public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/ckermit] epel8: Remove the 'rpmbuild -bp' directory from git, come on
@ 2026-09-18 13:57 David Cantrell
0 siblings, 0 replies; only message in thread
From: David Cantrell @ 2026-09-18 13:57 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/ckermit
Branch : epel8
Commit : 3abe589b4ed4c354ea3bfcf775796b18004cd08b
Author : David Cantrell <dcantrell@burdell.org>
Date : 2025-01-22T14:26:20-05:00
Stats : +0/-410593 in 81 file(s)
URL : https://src.fedoraproject.org/rpms/ckermit/c/3abe589b4ed4c354ea3bfcf775796b18004cd08b?branch=epel8
Log:
Remove the 'rpmbuild -bp' directory from git, come on
---
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/COPYING.TXT b/ckermit-9.0.302-build/ckermit-9.0.302/COPYING.TXT
deleted file mode 100644
index 200f236..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/COPYING.TXT
+++ /dev/null
@@ -1,31 +0,0 @@
-THE C-KERMIT 9.0 LICENSE
-
-Fri Jun 24 14:43:35 2011
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
- + Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- + Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
- + Neither the name of Columbia University nor the names of any
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/README.fedora b/ckermit-9.0.302-build/ckermit-9.0.302/README.fedora
deleted file mode 100644
index bfa41ac..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/README.fedora
+++ /dev/null
@@ -1,22 +0,0 @@
-If unprivileged users attempt to access a serial port, e.g.
-/dev/ttyS<n> or /dev/ttyUSB<n>, they will normally get an error
-message such as:
-
- Sorry, write access to UUCP lockfile directory denied.
-
-This message is actually due to permissions on the device, not the
-lockfile directory.
-
-If it is desired to allow specific unprivileged users to use ckermit
-to access serial ports, add those users to the "dialout" group. One
-way to accomplish this is using a command line such as:
-
- sudo usermod -a -G dialout <username>
-
-This will apply to future logins by that user.
-
-If you want to make the serial ports accessible to all users without
-adding them to the dialout group (not recommended), you can change the
-permissions of the serial device to 666, e.g.,
-
- sudo chmod 666 /dev/ttyS<n>
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ck_crp.c b/ckermit-9.0.302-build/ckermit-9.0.302/ck_crp.c
deleted file mode 100644
index 593d0b4..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ck_crp.c
+++ /dev/null
@@ -1,5622 +0,0 @@
-char *ckcrpv = "Encryption Engine, 9.0.117, 19 Mar 2010";
-/*
- C K _ C R P . C - Cryptography for C-Kermit"
-
- Copyright (C) 1998, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Author:
- Jeffrey E Altman (jaltman@secure-endpoints.com)
- Secure Endpoints Inc., New York City
-*/
-
-#define CK_CRP_C
-#ifdef CK_DES
-#ifdef CK_SSL
-#ifndef LIBDES
-#define LIBDES
-#endif /* LIBDES */
-#endif /* CK_SSL */
-#endif /* CK_DES */
-
-#ifdef CRYPT_DLL
-#define CK_AUTHENTICATION
-#define CK_ENCRYPTION
-#define CK_DES
-#define CK_CAST
-#ifndef LIBDES
-#define LIBDES
-#endif /* LIBDES */
-
-#define TELCMDS /* to define name array */
-#define TELOPTS /* to define name array */
-#define ENCRYPT_NAMES
-#endif /* CRYPT_DLL */
-
-#include "ckcsym.h"
-#include "ckcdeb.h"
-#include "ckcnet.h"
-
-#ifdef DEBUG
-#undef DEBUG
-#endif /* DEBUG */
-
-#ifdef CK_AUTHENTICATION
-#ifdef CK_ENCRYPTION
-#define ENCRYPTION
-#ifdef CK_DES
-#define DES_ENCRYPTION
-#endif /* CK_DES */
-#ifdef CK_CAST
-#define CAST_ENCRYPTION
-#endif /* CK_CAST */
-#ifdef COMMENT
-#define CAST_EXPORT_ENCRYPTION
-#endif /* COMMENT */
-#endif /* CK_ENCRYPTION */
-#endif /* CK_AUTHENTICATION */
-
-#ifdef CK_ENCRYPTION
-
-#include "ckucmd.h" /* For struct keytab definition */
-#include "ckuath.h"
-#include "ckuat2.h"
-#ifdef MIT_CURRENT
-#include <krb5.h>
-#endif /* MIT_CURRENT */
-
-#include <stdlib.h>
-#include <string.h>
-#ifdef OS2
-#include <stdarg.h>
-#ifdef OS2ONLY
-#include <os2.h>
-#endif /* OS2ONLY */
-#include "ckosyn.h"
-#else /* OS2 */
-static char * tmpstring = NULL;
-#endif /* OS2 */
-
-#ifndef CAST_OR_EXPORT
-#ifdef CAST_ENCRYPTION
-#define CAST_OR_EXPORT
-#endif /* CAST_ENCRYPTION */
-#ifdef CAST_EXPORT_ENCRYPTION
-#define CAST_OR_EXPORT
-#endif /* CAST_EXPORT_ENCRYPTION */
-#endif /* CAST_OR_EXPORT */
-
-#ifdef MACOSX
-#undef LIBDES
-#endif /* MACOSX */
-
-#ifdef CRYPT_DLL
-int cmd_quoting = 0;
-
-#ifndef TELOPT_MACRO
-int
-telopt_index(opt) int opt; {
- if ( opt >= 0 && opt <= TELOPT_SEND_URL )
- return(opt);
- else if ( opt >= TELOPT_PRAGMA_LOGON && opt <= TELOPT_PRAGMA_HEARTBEAT )
- return(opt-89);
- else
- return(NTELOPTS);
-}
-
-int
-telopt_ok(opt) int opt; {
- return((opt >= TELOPT_BINARY && opt <= TELOPT_SEND_URL) ||
- (opt >= TELOPT_PRAGMA_LOGON && opt <= TELOPT_PRAGMA_HEARTBEAT));
-}
-
-CHAR *
-telopt(opt) int opt; {
- if ( telopt_ok(opt) )
- return(telopts[telopt_index(opt)]);
- else
- return("UNKNOWN");
-}
-#endif /* TELOPT_MACRO */
-
-static int (*p_ttol)(char *,int)=NULL;
-static int (*p_dodebug)(int,char *,char *,CK_OFF_T)=NULL;
-static int (*p_dohexdump)(char *,char *,int)=NULL;
-static void (*p_tn_debug)(char *)=NULL;
-static int (*p_vscrnprintf)(char *, ...)=NULL;
-static void * p_k5_context=NULL;
-static unsigned long (*p_reqtelmutex)(unsigned long)=NULL;
-static unsigned long (*p_reltelmutex)(void)=NULL;
-
-unsigned long
-RequestTelnetMutex(unsigned long x)
-{
- if ( p_reqtelmutex )
- return p_reqtelmutex(x);
- return 0;
-}
-
-unsigned long
-ReleaseTelnetMutex(void)
-{
- if ( p_reltelmutex )
- return p_reltelmutex();
- return 0;
-}
-
-int
-ttol(char * s, int n)
-{
- if ( p_ttol )
- return(p_ttol(s,n));
- else
- return(-1);
-}
-
-int
-dodebug(int flag, char * s1, char * s2, CK_OFF_T n)
-{
- if ( p_dodebug )
- return(p_dodebug(flag,s1,s2,n));
- else
- return(-1);
-}
-
-int
-dohexdump( char * s1, char * s2, int n )
-{
- if ( p_dohexdump )
- p_dohexdump(s1,s2,n);
- return(0);
-}
-
-void
-tn_debug( char * s )
-{
- if ( p_tn_debug )
- p_tn_debug(s);
-}
-
-static char myprtfstr[4096];
-int
-Vscrnprintf(const char * format, ...) {
- int i, len, rc=0;
- char *cp;
- va_list ap;
-
- va_start(ap, format);
-#ifdef NT
- rc = _vsnprintf(myprtfstr, sizeof(myprtfstr)-1, format, ap);
-#else /* NT */
- rc = vsprintf(myprtfstr, format, ap);
-#endif /* NT */
- va_end(ap);
-
- if ( p_vscrnprintf )
- return(p_vscrnprintf(myprtfstr));
- else
- return(-1);
-}
-
-int
-#ifdef CK_ANSIC
-tn_hex(CHAR * buf, int buflen, CHAR * data, int datalen)
-#else /* CK_ANSIC */
-tn_hex(buf, buflen, data, datalen)
- CHAR * buf;
- int buflen;
- CHAR * data;
- int datalen;
-#endif /* CK_ANSIC */
-{
- int i = 0, j = 0, k = 0;
- CHAR tmp[8];
-#ifdef COMMENT
- int was_hex = 1;
-
- for (k=0; k < datalen; k++) {
- if (data[k] < 32 || data[k] >= 127) {
- sprintf(tmp,"%s%02X ",was_hex?"":"\" ",data[k]);
- was_hex = 1;
- } else {
- sprintf(tmp,"%s%c",was_hex?"\"":"",data[k]);
- was_hex = 0;
- }
- ckstrncat(buf,tmp,buflen);
- }
- if (!was_hex)
- ckstrncat(buf,"\" ",buflen);
-#else /* COMMENT */
- if (datalen <= 0 || data == NULL)
- return(0);
-
- for (i = 0; i < datalen; i++) {
- ckstrncat(buf,"\r\n ",buflen);
- for (j = 0 ; (j < 16); j++) {
- if ((i + j) < datalen)
- sprintf(tmp,
- "%s%02x ",
- (j == 8 ? "| " : ""),
- (CHAR) data[i + j]
- );
- else
- sprintf(tmp,
- "%s ",
- (j == 8 ? "| " : "")
- );
- ckstrncat(buf,tmp,buflen);
- }
- ckstrncat(buf," ",buflen);
- for (k = 0; (k < 16) && ((i + k) < datalen); k++) {
- sprintf(tmp,
- "%s%c",
- (k == 8 ? " " : ""),
- isprint(data[i + k]) ? data[i + k] : '.'
- );
- ckstrncat(buf,tmp,buflen);
- }
- i += j - 1;
- } /* end for */
- ckstrncat(buf,"\r\n ",buflen);
-#endif /* COMMENT */
- return(strlen(buf));
-}
-
-#ifdef COMMENT
-#define ttol dll_ttol
-#define dodebug dll_dodebug
-#define dohexdump dll_dohexdump
-#define tn_debug dll_tn_debug
-#define Vscrnprintf dll_vscrnprintf
-#endif /* COMMENT */
-
-char tn_msg[TN_MSG_LEN], hexbuf[TN_MSG_LEN]; /* from ckcnet.c */
-int deblog=1, debses=1, tn_deb=1;
-#else /* CRYPT_DLL */
-extern char tn_msg[], hexbuf[]; /* from ckcnet.c */
-extern int deblog, debses, tn_deb;
-#ifdef MIT_CURRENT
-extern krb5_context k5_context;
-#endif /* MIT_CURRENT */
-#endif /* CRYPT_DLL */
-
-#ifdef LIBDES
-#ifdef MACOSX
-#define des_new_random_key ck_des_new_random_key
-#define des_set_random_generator_seed ck_des_set_random_generator_seed
-#define des_key_sched ck_des_key_sched
-#define des_ecb_encrypt ck_des_ecb_encrypt
-#define des_string_to_key ck_des_string_to_key
-#define des_fixup_key_parity ck_des_fixup_key_parity
-#endif /* MACOSX */
-#ifndef UNIX
-#define des_new_random_key des_random_key
-#define des_set_random_generator_seed des_random_seed
-#endif /* UNIX */
-#define des_fixup_key_parity des_set_odd_parity
-#ifdef OPENSSL_097
-#define OPENSSL_ENABLE_OLD_DES_SUPPORT
-#include <openssl/des.h>
-#endif /* OPENSSL_097 */
-#else /* LIBDES */
-#ifdef UNIX
-#define des_set_random_generator_seed(x) des_init_random_number_generator(x)
-#endif /* UNIX */
-#ifdef OS2
-#define des_new_random_key ck_des_new_random_key
-#define des_set_random_generator_seed ck_des_set_random_generator_seed
-#define des_key_sched ck_des_key_sched
-#define des_ecb_encrypt ck_des_ecb_encrypt
-#define des_string_to_key ck_des_string_to_key
-#define des_fixup_key_parity ck_des_fixup_key_parity
-#endif /* OS2 */
-#endif /* LIBDES */
-
-#ifdef CK_DES
-/* This code comes from Eric Young's libdes package and is not part */
-/* of the standard MIT DES library that is part of Kerberos. However, */
-/* it is extremely useful. So we add it here. */
-
-
-/* Weak and semi week keys as take from
- * %A D.W. Davies
- * %A W.L. Price
- * %T Security for Computer Networks
- * %I John Wiley & Sons
- * %D 1984
- * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
- * (and actual cblock values).
- */
-#define NUM_WEAK_KEY 16
-static Block weak_keys[NUM_WEAK_KEY]={
- /* weak keys */
- {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
- {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
- {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
- {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
- /* semi-weak keys */
- {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
- {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
- {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
- {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
- {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
- {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
- {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
- {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
- {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
- {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
- {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
- {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
-
-int
-ck_des_is_weak_key(key)
-Block key;
-{
- int i;
-
- for (i=0; i<NUM_WEAK_KEY; i++) {
- /* Added == 0 to comparision, I obviously don't run
- * this section very often :-(, thanks to
- * engineering@MorningStar.Com for the fix
- * eay 93/06/29
- * Another problem, I was comparing only the first 4
- * bytes, 97/03/18 */
- if (memcmp(weak_keys[i],key,sizeof(Block)) == 0)
- return(1);
- }
- return(0);
-}
-
-#ifdef UNIX
-#ifdef LIBDES
-#ifndef MACOSX
-/* These functions are not part of Eric Young's DES library */
-/* _unix_time_gmt_unixsec */
-/* _des_set_random_generator_seed */
-/* _des_fixup_key_parity (added in 0.9.5) */
-/* _des_new_random_key */
-#include <sys/time.h>
-
-unsigned long
-unix_time_gmt_unixsec (usecptr)
- unsigned long *usecptr;
-{
- struct timeval now;
-
- (void) gettimeofday (&now, (struct timezone *)0);
- if (usecptr)
- *usecptr = now.tv_usec;
- return now.tv_sec;
-}
-
-void
-des_set_random_generator_seed(Block B)
-{
- des_random_seed(B);
- return;
-}
-
-#ifdef COMMENT
-/* added to openssl in 0.9.5 */
-void
-des_fixup_key_parity(Block B)
-{
- des_set_odd_parity(B);
- return;
-}
-#endif /* COMMENT */
-int
-des_new_random_key(Block B)
-{
- int rc=0;
- /* WARNING:
- This might need to have the "rc = " removed because this
- is VOID in later, and maybe even all, versions.
- */
- rc = des_random_key(B);
- return(rc);
-}
-
-#endif /* MACOSX */
-#endif /* LIBDES */
-#endif /* UNIX */
-#endif /* CK_DES */
-
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* based on @(#)encrypt.c 8.1 (Berkeley) 6/4/93 */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#include <stdio.h>
-
-/*
- * These function pointers point to the current routines
- * for encrypting and decrypting data.
- */
-/* NOTE: These next two might need to have the "static " removed */
-
-static VOID (*encrypt_output) P((unsigned char *, int));
-static int (*decrypt_input) P((int));
-
-#ifdef DEBUG
-static int encrypt_debug_mode = 1;
-static int encrypt_verbose = 1;
-#else
-static int encrypt_verbose = 1;
-static int encrypt_debug_mode = 0;
-#endif
-
-static char dbgbuf [16384];
-
-static int decrypt_mode = 0;
-static int encrypt_mode = 0;
-static int autoencrypt = 1;
-static int autodecrypt = 1;
-static int havesessionkey = 0;
-
-static kstream EncryptKSGlobalHack = NULL;
-static int EncryptType = ENCTYPE_ANY;
-
-#define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0)
-
-static long i_support_encrypt =
- typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64);
-static long i_support_decrypt =
- typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64);
-static long i_wont_support_encrypt = 0;
-static long i_wont_support_decrypt = 0;
-#define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt)
-#define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt)
-
-static long remote_supports_encrypt = 0;
-static long remote_supports_decrypt = 0;
-
-/* Make sure that this list is in order of algorithm strength */
-/* as it determines the search order for selecting specific */
-/* encryption choices. All CFB modes must come before OFB modes. */
-static Encryptions encryptions[] = {
-#ifdef DES_ENCRYPTION
- { "DES3_CFB64",
- ENCTYPE_DES3_CFB64,
- des3_cfb64_encrypt,
- des3_cfb64_decrypt,
- des3_cfb64_init,
- des3_cfb64_start,
- des3_cfb64_is,
- des3_cfb64_reply,
- des3_cfb64_session,
- des3_cfb64_keyid,
- NULL },
-#endif /* DES_ENCRYPTION */
-#ifdef CAST_ENCRYPTION
-#ifndef CAST_EXPORT_ENCRYPTION
- { "CAST128_CFB64", ENCTYPE_CAST128_CFB64,
- cast_cfb64_encrypt,
- cast_cfb64_decrypt,
- cast_cfb64_init,
- cast_cfb64_start,
- cast_cfb64_is,
- cast_cfb64_reply,
- cast_cfb64_session,
- cast_cfb64_keyid,
- NULL },
-#endif
-#endif
-#ifdef DES_ENCRYPTION
- { "DES_CFB64",
- ENCTYPE_DES_CFB64,
- cfb64_encrypt,
- cfb64_decrypt,
- cfb64_init,
- cfb64_start,
- cfb64_is,
- cfb64_reply,
- cfb64_session,
- cfb64_keyid,
- NULL },
-#endif /* DES_ENCRYPTION */
-#if defined (CAST_EXPORT_ENCRYPTION) || defined(CAST_ENCRYPTION)
- { "CAST5_40_CFB64", ENCTYPE_CAST5_40_CFB64,
- castexp_cfb64_encrypt,
- castexp_cfb64_decrypt,
- castexp_cfb64_init,
- castexp_cfb64_start,
- castexp_cfb64_is,
- castexp_cfb64_reply,
- castexp_cfb64_session,
- castexp_cfb64_keyid,
- NULL },
-#endif /* CAST_ENCRYPTION */
-#ifdef DES_ENCRYPTION
- { "DES3_OFB64",
- ENCTYPE_DES3_OFB64,
- des3_ofb64_encrypt,
- des3_ofb64_decrypt,
- des3_ofb64_init,
- des3_ofb64_start,
- des3_ofb64_is,
- des3_ofb64_reply,
- des3_ofb64_session,
- des3_ofb64_keyid,
- NULL },
-#endif /* DES_ENCRYPTION */
-#ifdef CAST_ENCRYPTION
-#ifndef CAST_EXPORT_ENCRYPTION
- { "CAST128_OFB64", ENCTYPE_CAST128_OFB64,
- cast_ofb64_encrypt,
- cast_ofb64_decrypt,
- cast_ofb64_init,
- cast_ofb64_start,
- cast_ofb64_is,
- cast_ofb64_reply,
- cast_ofb64_session,
- cast_ofb64_keyid,
- NULL },
-#endif
-#endif
-#ifdef DES_ENCRYPTION
- { "DES_OFB64",
- ENCTYPE_DES_OFB64,
- ofb64_encrypt,
- ofb64_decrypt,
- ofb64_init,
- ofb64_start,
- ofb64_is,
- ofb64_reply,
- ofb64_session,
- ofb64_keyid,
- NULL },
-#endif /* DES_ENCRYPTION */
-#if defined (CAST_EXPORT_ENCRYPTION) || defined(CAST_ENCRYPTION)
- { "CAST5_40_OFB64", ENCTYPE_CAST5_40_OFB64,
- castexp_ofb64_encrypt,
- castexp_ofb64_decrypt,
- castexp_ofb64_init,
- castexp_ofb64_start,
- castexp_ofb64_is,
- castexp_ofb64_reply,
- castexp_ofb64_session,
- castexp_ofb64_keyid,
- NULL },
-#endif /* CAST_ENCRYPTION */
- { 0,0,0,0,0,0,0,0,0,0,0 }
-};
-
-int
-get_crypt_table( struct keytab ** pTable, int * pN )
-{
- int i=0,n=0;
-
- if ( *pTable )
- {
- for ( i=0 ; i < *pN ; i++ )
- free( (*pTable)[i].kwd ) ;
- free ( *pTable ) ;
- }
- *pTable = NULL;
- *pN = 0;
-
- /* How many encryption types do we have? */
- while ( encryptions[n].name )
- n++;
-
- if ( n )
- {
- *pTable = malloc( sizeof(struct keytab) * (n+2) ) ;
- if ( !(*pTable) )
- return(0);
-
-#ifdef OS2
- (*pTable)[0].kwd =strdup("automatic");
-#else /* OS2 */
- makestr(&tmpstring,"automatic");
- (*pTable)[0].kwd = tmpstring;
- tmpstring = NULL;
-#endif /* OS2 */
- (*pTable)[0].kwval = ENCTYPE_ANY;
- (*pTable)[0].flgs = 0;
-#ifdef OS2
- (*pTable)[1].kwd =strdup("none");
-#else /* OS2 */
- makestr(&tmpstring,"none");
- (*pTable)[1].kwd = tmpstring;
- tmpstring = NULL;
-#endif /* OS2 */
- (*pTable)[1].kwval = 999;
- (*pTable)[1].flgs = 0;
- (*pN) = 2;
-
- for ( i=0 ; i < n ; i++ ) {
- char * newstr = NULL, * p;
- int newval = encryptions[i].type;
- int j = 0, len = 0;
-
-#ifdef OS2
- newstr = strdup(encryptions[i].name);
- strlwr(newstr);
-#else /* OS2 */
- makestr(&tmpstring,encryptions[i].name);
- newstr = tmpstring;
- tmpstring = NULL;
- for (p = newstr; *p; p++) if (isupper(*p)) *p = tolower(*p);
-#endif /* OS2 */
-
- for (j = 0; j < (*pN); j++) {
- int tempval = 0;
- char * tempstr = NULL;
-
- if ( strcmp( (*pTable)[j].kwd, newstr ) > 0 )
- {
- tempval = (*pTable)[j].kwval;
- tempstr = (*pTable)[j].kwd;
- (*pTable)[j].kwd = newstr ;
- (*pTable)[j].kwval = newval;
- newval = tempval;
- newstr = tempstr;
- (*pTable)[j].flgs = 0;
- }
- }
- (*pTable)[*pN].kwd = newstr ;
- (*pTable)[*pN].kwval = newval;
- (*pTable)[*pN].flgs = 0 ;
- (*pN)++ ;
- }
- } else {
- *pTable = malloc( sizeof(struct keytab) * 2 ) ;
- if ( !(*pTable) )
- return(0);
-
-#ifdef OS2
- (*pTable)[0].kwd =strdup("automatic");
-#else /* OS2 */
- makestr(&tmpstring,"automatic");
- (*pTable)[0].kwd = tmpstring;
- tmpstring = NULL;
-#endif /* OS2 */
- (*pTable)[0].kwval = ENCTYPE_ANY;
- (*pTable)[0].flgs = 0;
-#ifdef OS2
- (*pTable)[1].kwd =strdup("none");
-#else /* OS2 */
- makestr(&tmpstring,"none");
- (*pTable)[1].kwd = tmpstring;
- tmpstring = NULL;
-#endif /* OS2 */
- (*pTable)[1].kwval = 999;
- (*pTable)[1].flgs = 0;
- (*pN) = 2;
- }
- return(*pN);
-}
-
-static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPTION,
- ENCRYPT_SUPPORT };
-static unsigned char str_suplen = 0;
-static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPTION };
-static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPTION, 0, IAC, SE };
-
-_PROTOTYP(int encrypt_request_end, (VOID));
-_PROTOTYP(int encrypt_request_start, (VOID));
-_PROTOTYP(int encrypt_enc_keyid, (unsigned char *, int));
-_PROTOTYP(int encrypt_dec_keyid, (unsigned char *, int));
-_PROTOTYP(int encrypt_support, (unsigned char *, int));
-_PROTOTYP(int encrypt_start, (unsigned char *, int));
-_PROTOTYP(int encrypt_end, (VOID));
-
-_PROTOTYP(int encrypt_ks_stream,(struct kstream_data_block *, /* output */
- struct kstream_data_block *)); /* input */
-
-_PROTOTYP(int decrypt_ks_stream,(struct kstream_data_block *, /* output */
- struct kstream_data_block *)); /* input */
-
-int
-#ifdef CK_ANSIC
-encrypt_ks_stream(struct kstream_data_block *i,
- struct kstream_data_block *o)
-#else
-encrypt_ks_stream(i,o)
- struct kstream_data_block *i; struct kstream_data_block *o;
-#endif
-{
- /*
- * this is really quite bogus, since it does an in-place encryption...
- */
- if (encrypt_output) {
- encrypt_output(i->ptr, i->length);
- return 1;
- }
- return 0;
-}
-
-
-int
-#ifdef CK_ANSIC
-decrypt_ks_stream(struct kstream_data_block *i,
- struct kstream_data_block *o)
-#else
-decrypt_ks_stream(i,o)
- struct kstream_data_block *i; struct kstream_data_block *o;
-#endif
-{
- unsigned int len;
- /*
- * this is really quite bogus, since it does an in-place decryption...
- */
- if (decrypt_input) {
- for (len = 0 ; len < i->length ; len++)
- ((unsigned char *)i->ptr)[len]
- = decrypt_input(((unsigned char *)i->ptr)[len]);
- return 1;
- }
- return 0;
-}
-
-int
-#ifdef CK_ANSIC
-decrypt_ks_hack(unsigned char *buf, int cnt)
-#else
-decrypt_ks_hack(buf,cnt) unsigned char *buf; int cnt;
-#endif
-{
- int len;
- /*
- * this is really quite bogus, since it does an in-place decryption...
- */
- for (len = 0 ; len < cnt ; len++)
- buf[len] = decrypt_input(buf[len]);
-
-#ifdef DEBUG
- ckhexdump("decrypt ks hack", buf, cnt);
-#endif
- return 1;
-}
-
-
-/*
- * parsedat[0] == the suboption we might be negotiating,
- */
-int
-#ifdef CK_ANSIC
-encrypt_parse(unsigned char *parsedat, int end_sub)
-#else
-encrypt_parse(parsedat,end_sub) unsigned char *parsedat; int end_sub;
-#endif
-{
- int rc = 0;
-
- switch(parsedat[1]) {
- case ENCRYPT_START:
- rc = encrypt_start(parsedat + 2, end_sub - 2);
- break;
- case ENCRYPT_END:
- rc = encrypt_end();
- break;
- case ENCRYPT_SUPPORT:
- rc = encrypt_support(parsedat + 2, end_sub - 2);
- break;
- case ENCRYPT_REQSTART:
- rc = encrypt_request_start();
- break;
- case ENCRYPT_REQEND:
- /*
- * We can always send an REQEND so that we cannot
- * get stuck encrypting. We should only get this
- * if we have been able to get in the correct mode
- * anyhow.
- */
- rc = encrypt_request_end();
- break;
- case ENCRYPT_IS:
- rc = encrypt_is(parsedat + 2, end_sub - 2);
- break;
- case ENCRYPT_REPLY:
- rc = encrypt_reply(parsedat + 2, end_sub - 2);
- break;
- case ENCRYPT_ENC_KEYID:
- rc = encrypt_enc_keyid(parsedat + 2, end_sub - 2);
- break;
- case ENCRYPT_DEC_KEYID:
- rc = encrypt_dec_keyid(parsedat + 2, end_sub - 2);
- break;
- default:
- rc = -1;
- break;
- }
- return(rc);
-}
-
-/* XXX */
-Encryptions *
-#ifdef CK_ANSIC
-findencryption(int type)
-#else
-findencryption(type) int type;
-#endif
-{
- Encryptions *ep = encryptions;
-
- if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & typemask(type)))
- return(0);
- while (ep->type && ep->type != type)
- ++ep;
- return(ep->type ? ep : 0);
-}
-
-Encryptions *
-#ifdef CK_ANSIC
-finddecryption(int type)
-#else
-finddecryption(type) int type;
-#endif
-{
- Encryptions *ep = encryptions;
-
- if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & typemask(type)))
- return(0);
- while (ep->type && ep->type != type)
- ++ep;
- return(ep->type ? ep : 0);
-}
-
-#define MAXKEYLEN 64
-
-static struct key_info {
- unsigned char keyid[MAXKEYLEN];
- int keylen;
- int dir;
- int *modep;
- Encryptions *(*getcrypt)();
-} ki[2] = {
- { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption },
- { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption },
-};
-
-VOID
-#ifdef CK_ANSIC
-encrypt_init(kstream iks, int type)
-#else
-encrypt_init(iks, type) kstream iks; int type;
-#endif
-{
- Encryptions *ep = encryptions;
-
- i_support_encrypt = i_support_decrypt = 0;
- remote_supports_encrypt = remote_supports_decrypt = 0;
- i_wont_support_encrypt = i_wont_support_decrypt = 0;
- encrypt_mode = 0;
- decrypt_mode = 0;
- encrypt_output = NULL;
- decrypt_input = NULL;
- ki[0].keylen = 0;
- memset(ki[0].keyid,0,MAXKEYLEN);
- ki[1].keylen = 0;
- memset(ki[1].keyid,0,MAXKEYLEN);
- havesessionkey = 0;
- autoencrypt = 1;
- autodecrypt = 1;
-
- EncryptKSGlobalHack = iks;
- EncryptType = type;
-
- str_send[0] = IAC;
- str_send[1] = SB;
- str_send[2] = TELOPT_ENCRYPTION;
- str_send[3] = ENCRYPT_SUPPORT;
- str_suplen = 4;
-
- while (ep->type) {
- if ( EncryptType == ENCTYPE_ANY ||
- EncryptType == ep->type ) {
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>I will support %s\n",
- ENCTYPE_NAME(ep->type)); /* safe */
- debug(F110,"encrypt_init",dbgbuf,0);
- }
-#endif
- i_support_encrypt |= typemask(ep->type);
- i_support_decrypt |= typemask(ep->type);
- if ((i_wont_support_decrypt & typemask(ep->type)) == 0)
- if ((str_send[str_suplen++] = ep->type) == IAC)
- str_send[str_suplen++] = IAC;
- }
- if (ep->init)
- (*ep->init)(0);
- ++ep;
- }
- str_send[str_suplen++] = IAC;
- str_send[str_suplen++] = SE;
-}
-
-VOID
-#ifdef CK_ANSIC
-encrypt_send_support(VOID)
-#else
-encrypt_send_support()
-#endif
-{
- Encryptions *ep = encryptions;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return;
-#endif /* CK_SSL */
-
- str_send[0] = IAC;
- str_send[1] = SB;
- str_send[2] = TELOPT_ENCRYPTION;
- str_send[3] = ENCRYPT_SUPPORT;
- str_suplen = 4;
-
- while (ep->type) {
- if ( EncryptType == ENCTYPE_ANY ||
- EncryptType == ep->type ) {
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>I will support %s\n",
- ENCTYPE_NAME(ep->type)); /* safe */
- debug(F110,"encrypt_send_support",dbgbuf,0);
- }
-#endif
- if ((i_wont_support_decrypt & typemask(ep->type)) == 0)
- if ((str_send[str_suplen++] = ep->type) == IAC)
- str_send[str_suplen++] = IAC;
- }
- ++ep;
- }
- str_send[str_suplen++] = IAC;
- str_send[str_suplen++] = SE;
-
- /*
- * If the user has requested that decryption start
- * immediatly, then send a "REQUEST START" before
- * we negotiate the type.
- */
- if (autodecrypt)
- encrypt_send_request_start();
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,"TELNET SENT SB %s SUPPORT ",
- TELOPT(TELOPT_ENCRYPTION)); /* safe */
- for ( i=4;i<str_suplen-2;i++ ) {
- if ( str_send[i] == IAC ) {
- ckstrncat(tn_msg,"IAC ",TN_MSG_LEN);
- i++;
- }
- ckstrncat(tn_msg,ENCTYPE_NAME(str_send[i]),TN_MSG_LEN);
- ckstrncat(tn_msg," ",TN_MSG_LEN);
- }
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(str_send, str_suplen);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
-
- str_suplen = 0;
-}
-
-/*
- * Called when ENCRYPT SUPPORT is received.
- */
-int
-#ifdef CK_ANSIC
-encrypt_support(unsigned char *_typelist, int _cnt)
-#else
-encrypt_support(_typelist, _cnt) unsigned char * _typelist; int _cnt;
-#endif
-{
- register int type, use_type = 0;
- unsigned char * typelist = _typelist;
- int cnt = _cnt;
- Encryptions *ep;
-
- debug(F111,"encrypt_support","cnt",cnt);
-
- /*
- * Forget anything the other side has previously told us.
- */
- remote_supports_decrypt = 0;
-
- while (cnt-- > 0) {
- debug(F101,"XXX cnt","",cnt);
- type = *typelist++;
- debug(F101,"XXX type","",type);
- debug(F101,"XXX ENCTYPE_ANY","",ENCTYPE_ANY);
- if ( EncryptType == ENCTYPE_ANY ||
- EncryptType == type ) {
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>Remote supports %s (%d)\n",
- ENCTYPE_NAME(type), type); /* safe */
- debug(F110,"encrypt_support",dbgbuf,0);
- }
-#endif
- if ((type < ENCTYPE_CNT) &&
- (I_SUPPORT_ENCRYPT & typemask(type))) {
- remote_supports_decrypt |= typemask(type);
- if (use_type == 0)
- use_type = type;
- }
- }
- }
- debug(F101,"XXX use_type","",use_type);
- if (use_type) {
- ep = findencryption(use_type);
- if (!ep) {
- debug(F111,"encrypt_support","findencryption == NULL",use_type);
- return(-1);
- }
- debug(F100,"XXX ep not NULL","",0);
- type = ep->start ? (*ep->start)(DIR_ENCRYPT, 0) : 0;
- debug(F101,"XXX new type","",type);
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>(*ep->start)() %s returned %d (%s)\n",
- ENCTYPE_NAME(use_type), type,
- ENCRYPT_NAME(type)); /* safe */
- debug(F110,"encrypt_support",dbgbuf,0);
- }
-#endif
- if (type < 0) {
- debug(F111,"encrypt_support","type < 0",type);
- return(-1);
- }
- encrypt_mode = use_type;
- if (type == 0)
- encrypt_start_output(use_type);
- debug(F111,"encrypt_support","success",type);
- return(0);
- }
- debug(F111,"encrypt_support","failed",use_type);
- return(-1);
-}
-
-int
-#ifdef CK_ANSIC
-encrypt_is(unsigned char *data, int cnt)
-#else
-encrypt_is(data, cnt) unsigned char *data; int cnt;
-#endif /* CK_ANSIC */
-{
- Encryptions *ep;
- register int type, ret;
-
- if (--cnt < 0)
- return(-1);
- type = *data++;
- if (type < ENCTYPE_CNT)
- remote_supports_encrypt |= typemask(type);
- if (!(ep = finddecryption(type))) {
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>encrypt_is: "
- "Can't find type %s (%d) for initial negotiation\n",
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type); /* safe */
- debug(F110,"encrypt_is",dbgbuf,0);
- }
-#endif
- return(-1);
- }
- if (!ep->is) {
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>encrypt_is: "
- "No initial negotiation needed for type %s (%d)\n",
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type); /* safe */
- debug(F110,"encrypt_is",dbgbuf,0);
- }
-#endif
- ret = 0;
- } else {
- ret = (*ep->is)(data, cnt);
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, "encrypt_is: "
- "(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt,
- (ret < 0) ? "FAIL " :
- (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); /* safe */
- debug(F110,"encrypt_is",dbgbuf,0);
- }
-#endif
- }
- if (ret < 0) {
- autodecrypt = 0;
- return(-1);
- } else {
- decrypt_mode = type;
- if (ret == 0 && autodecrypt) {
- encrypt_send_request_start();
- }
- }
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-encrypt_reply(unsigned char *data, int cnt)
-#else
-encrypt_reply(data, cnt) unsigned char *data; int cnt;
-#endif
-{
- Encryptions *ep;
- register int ret, type;
-
- if (--cnt < 0)
- return(-1);
- type = *data++;
- if (!(ep = findencryption(type))) {
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf,
- ">>>Can't find type %s (%d) for initial negotiation\n",
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type); /* safe */
- debug(F110,"encrypt_reply",dbgbuf,0);
- }
-#endif
- return(-1);
- }
- if (!ep->reply) {
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>No initial negotiation needed for type %s (%d)\n",
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type); /* safe */
- debug(F110,"encrypt_reply",dbgbuf,0);
- }
-#endif
- ret = 0;
- } else {
- ret = (*ep->reply)(data, cnt);
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, "(*ep->reply)(%x, %d) returned %s(%d)\n",
- data, cnt,
- (ret < 0) ? "FAIL " :
- (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); /* safe */
- debug(F110,"encrypt_reply",dbgbuf,0);
- }
-#endif
- }
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>encrypt_reply returned %d\n", ret); /* safe */
- debug(F110,"encrypt_reply",dbgbuf,0);
- }
-#endif
- if (ret < 0) {
- autoencrypt = 0;
- return(-1);
- } else {
- encrypt_mode = type;
- if (ret == 0 && autoencrypt)
- encrypt_start_output(type);
- }
- return(0);
-}
-
-/*
- * Called when a ENCRYPT START command is received.
- */
-int
-#ifdef CK_ANSIC
-encrypt_start(unsigned char *data, int cnt)
-#else
-encrypt_start(data, cnt) unsigned char *data; int cnt;
-#endif
-{
- Encryptions *ep;
-
- if (!decrypt_mode) {
- /*
- * Something is wrong. We should not get a START
- * command without having already picked our
- * decryption scheme. Send a REQUEST-END to
- * attempt to clear the channel...
- */
- encrypt_send_request_end();
- printf("Authentication error!\n%s\n",
- "Warning, Cannot decrypt input stream!!!");
- return(-1);
- }
-
- if (ep = finddecryption(decrypt_mode)) {
- if ( decrypt_input != ep->input ) {
- decrypt_input = ep->input;
- EncryptKSGlobalHack->decrypt = decrypt_ks_stream;
- EncryptKSGlobalHack->decrypt_type = ep->type;
-
- if (encrypt_verbose) {
- sprintf(dbgbuf, "Input is now decrypted with type %s",
- ENCTYPE_NAME(decrypt_mode)); /* safe */
- debug(F110,"encrypt_start",dbgbuf,0);
- printf("%s\n",dbgbuf);
- }
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>Start to decrypt input with type %s",
- ENCTYPE_NAME(decrypt_mode)); /* safe */
- debug(F110,"ck_crp",dbgbuf,0);
- }
-#endif
- }
- } else {
- char buf[1024];
- sprintf(buf, "Warning, Cannot decrypt type %s (%d)!!!",
- ENCTYPE_NAME_OK(decrypt_mode)
- ? ENCTYPE_NAME(decrypt_mode) : "(unknown)",
- decrypt_mode); /* safe */
- printf("Authentication error!\n%s\n",buf);
- encrypt_send_request_end();
- return(-1);
- }
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-encrypt_dont_support(int type)
-#else
-encrypt_dont_support(type) int type;
-#endif
-{
- i_wont_support_encrypt |= typemask(type);
- i_wont_support_decrypt |= typemask(type);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-encrypt_session_key(Session_Key *key, int server)
-#else
-encrypt_session_key(key, server) Session_Key *key; int server;
-#endif
-{
- Encryptions *ep = encryptions;
-
- if (havesessionkey)
- return(0);
-
- havesessionkey = 1;
-
- while (ep->type) {
- debug(F111,"encrypt_session_key",ep->name,ep->type);
- if (ep->session) {
- if ((*ep->session)(key, server) < 0) {
- i_wont_support_encrypt |= typemask(ep->type);
- i_wont_support_decrypt |= typemask(ep->type);
- }
- }
- ++ep;
- }
- debug(F111,"encrypt_session_key (done)",ep->name,ep->type);
- return(0);
-}
-
-/*
- * Called when ENCRYPT END is received.
- */
-int
-#ifdef CK_ANSIC
-encrypt_end(VOID)
-#else
-encrypt_end()
-#endif
-{
- decrypt_input = NULL;
- EncryptKSGlobalHack->decrypt = NULL;
- EncryptKSGlobalHack->decrypt_type = ENCTYPE_ANY;
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>Input is back to clear text"); /* safe */
- debug(F110,"encrypt_end",dbgbuf,0);
- }
-#endif
- if (encrypt_verbose) {
- sprintf(dbgbuf, "Input is now clear text"); /* safe */
- debug(F110,"encrypt_end",dbgbuf,0);
- printf("%s\n",dbgbuf);
- }
- return(0);
-}
-
-/*
- * Called when ENCRYPT REQUEST-END is received.
- */
-int
-#ifdef CK_ANSIC
-encrypt_request_end(VOID)
-#else
-encrypt_request_end()
-#endif
-{
- encrypt_send_end();
- return(0);
-}
-
-/*
- * Called when ENCRYPT REQUEST-START is received. If we receive
- * this before a type is picked, then that indicates that the
- * other side wants us to start encrypting data as soon as we
- * can.
- */
-int
-#ifdef CK_ANSIC
-encrypt_request_start(VOID)
-#else
-encrypt_request_start()
-#endif
-{
- if (encrypt_mode != 0)
- encrypt_start_output(encrypt_mode);
- return(0);
-}
-
-static unsigned char str_keyid[(MAXKEYLEN*2)+5] = {
- IAC, SB, TELOPT_ENCRYPTION
-};
-_PROTOTYP(int encrypt_keyid,(struct key_info *,unsigned char *,int));
-
-int
-#ifdef CK_ANSIC
-encrypt_enc_keyid(unsigned char *keyid, int len)
-#else
-encrypt_enc_keyid(keyid, len) unsigned char *keyid; int len;
-#endif
-{
- return(encrypt_keyid(&ki[1], keyid, len));
-}
-
-int
-#ifdef CK_ANSIC
-encrypt_dec_keyid(unsigned char *keyid, int len)
-#else
-encrypt_dec_keyid(keyid, len) unsigned char *keyid; int len;
-#endif /* CK_ANSIC */
-{
- return(encrypt_keyid(&ki[0], keyid, len));
-}
-
-int
-#ifdef CK_ANSIC
-encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len)
-#else
-encrypt_keyid(kp, keyid, len)
- struct key_info *kp; unsigned char *keyid; int len;
-#endif
-{
- Encryptions *ep;
- int dir = kp->dir;
- register int ret = 0;
-
- if (!(ep = (*kp->getcrypt)(*kp->modep))) {
- if (len == 0)
- return(-1);
- kp->keylen = 0;
- } else if (len == 0 || len > MAXKEYLEN) {
- /*
- * Empty option or Key too long, indicates a failure.
- */
- if (kp->keylen == 0)
- return(-1);
- kp->keylen = 0;
- if (ep->keyid)
- (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
-
- } else if ((len != kp->keylen) || (memcmp(keyid, kp->keyid, len) != 0)) {
- /*
- * Length or contents are different
- */
- kp->keylen = len;
- memcpy(kp->keyid, keyid, len); /* length < MAXKEYLEN */
- if (ep->keyid)
- (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
- } else {
- if (ep->keyid)
- ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen);
- if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt)
- encrypt_start_output(*kp->modep);
- return(0);
- }
-
- encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-encrypt_send_keyid(int dir, unsigned char *keyid, int keylen, int saveit)
-#else
-encrypt_send_keyid(dir, keyid, keylen, saveit)
- int dir; unsigned char *keyid; int keylen; int saveit;
-#endif
-{
- unsigned char *strp;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return(0);
-#endif /* CK_SSL */
-
- str_keyid[3] = (dir == DIR_ENCRYPT)
- ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID;
- if (saveit && keylen <= MAXKEYLEN) {
- struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1];
- memcpy(kp->keyid, keyid, keylen);
- kp->keylen = keylen;
- }
-
- for (strp = &str_keyid[4]; keylen > 0; --keylen) {
- if ((*strp++ = *keyid++) == IAC)
- *strp++ = IAC;
- }
- *strp++ = IAC;
- *strp++ = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,"TELNET SENT SB %s %s ",
- TELOPT(TELOPT_ENCRYPTION),
- (dir == DIR_ENCRYPT) ? "ENC-KEYID" : "DEC-KEYID"); /* safe */
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_keyid[4],strp-str_keyid-2-4);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(str_keyid, strp - str_keyid);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- return(0);
-}
-
-VOID
-#ifdef CK_ANSIC
-encrypt_auto(int on)
-#else
-encrypt_auto(on) int on;
-#endif
-{
- if (on < 0)
- autoencrypt ^= 1;
- else
- autoencrypt = on ? 1 : 0;
-}
-
-VOID
-#ifdef CK_ANSIC
-decrypt_auto(int on)
-#else
-decrypt_auto(on) int on;
-#endif
-{
- if (on < 0)
- autodecrypt ^= 1;
- else
- autodecrypt = on ? 1 : 0;
-}
-
-VOID
-#ifdef CK_ANSIC
-encrypt_start_output(int type)
-#else
-encrypt_start_output(type) int type;
-#endif
-{
- Encryptions *ep;
- register unsigned char *p;
- register int i;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return;
-#endif /* CK_SSL */
-
- if (!(ep = findencryption(type))) {
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>Can't encrypt with type %s (%d)\n",
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type); /* safe */
- debug(F110,"encrypt_start_output",dbgbuf,0);
- }
-#endif
- return;
- }
- if (ep->start) {
- i = (*ep->start)(DIR_ENCRYPT, 0);
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>Encrypt start: %s (%d) %s\n",
- (i < 0) ? "failed" :
- "initial negotiation in progress",
- i, ENCTYPE_NAME(type)); /* safe */
- debug(F110,"encrypt_start_output",dbgbuf,0);
- }
-#endif
- if (i)
- return;
- }
-
- if ( encrypt_output != ep->output ) {
- p = str_start;
- *p++ = IAC;
- *p++ = SB;
- *p++ = TELOPT_ENCRYPTION;
- *p++ = ENCRYPT_START;
- for (i = 0; i < ki[0].keylen; ++i) {
- if (( *p++ = ki[0].keyid[i]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,"TELNET SENT SB %s START ",
- TELOPT(TELOPT_ENCRYPTION)); /* safe */
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_start[4],p-str_start-2-4);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(str_start, p - str_start);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
-
- /*
- * If we are already encrypting in some mode, then
- * encrypt the ring (which includes our request) in
- * the old mode, mark it all as "clear text" and then
- * switch to the new mode.
- */
- encrypt_output = ep->output;
- EncryptKSGlobalHack->encrypt = encrypt_ks_stream;
- EncryptKSGlobalHack->encrypt_type = type;
- encrypt_mode = type;
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>Started to encrypt output with type %s",
- ENCTYPE_NAME(type)); /* safe */
- debug(F110,"encrypt_start_output",dbgbuf,0);
- }
-#endif
- if (encrypt_verbose) {
- sprintf(dbgbuf, "Output is now encrypted with type %s",
- ENCTYPE_NAME(type)); /* safe */
- debug(F110,"encrypt_start_output",dbgbuf,0);
- printf("%s\n",dbgbuf);
- }
- }
-}
-
-VOID
-#ifdef CK_ANSIC
-encrypt_send_end(VOID)
-#else
-encrypt_send_end()
-#endif
-{
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return;
-#endif /* CK_SSL */
-
- if (!encrypt_output)
- return;
-
- str_end[0] = IAC;
- str_end[1] = SB;
- str_end[2] = TELOPT_ENCRYPTION;
- str_end[3] = ENCRYPT_END;
- str_end[4] = IAC;
- str_end[5] = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,"TELNET SENT SB %s END IAC SE",
- TELOPT(TELOPT_ENCRYPTION)); /* safe */
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(str_end, sizeof(str_end));
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
-
- encrypt_output = 0;
- EncryptKSGlobalHack->encrypt = NULL;
- EncryptKSGlobalHack->encrypt_type = ENCTYPE_ANY;
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>Output is back to clear text"); /* safe */
- debug(F110,"encrypt_send_end",dbgbuf,0);
- }
-#endif
- if (encrypt_verbose) {
- sprintf(dbgbuf, "Output is now clear text"); /* safe */
- debug(F110,"encrypt_send_end",dbgbuf,0);
- printf("%s\n",dbgbuf);
- }
-}
-
-VOID
-#ifdef CK_ANSIC
-encrypt_send_request_start(VOID)
-#else
-encrypt_send_request_start()
-#endif
-{
- register unsigned char *p;
- register int i;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return;
-#endif /* CK_SSL */
-
- p = str_start;
- *p++ = IAC;
- *p++ = SB;
- *p++ = TELOPT_ENCRYPTION;
- *p++ = ENCRYPT_REQSTART;
- for (i = 0; i < ki[1].keylen; ++i) {
- if (( *p++ = ki[1].keyid[i]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,"TELNET SENT SB %s REQUEST-START ",
- TELOPT(TELOPT_ENCRYPTION)); /* safe */
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_start[4],p-str_start-2-4);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(str_start, p - str_start);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
-
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>Request input to be encrypted\n"); /* safe */
- debug(F110,"encrypt_send_request_start",dbgbuf,0);
- }
-}
-
-VOID
-#ifdef CK_ANSIC
-encrypt_send_request_end(VOID)
-#else
-encrypt_send_request_end()
-#endif
-{
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return;
-#endif /* CK_SSL */
-
- str_end[0] = IAC;
- str_end[1] = SB;
- str_end[2] = TELOPT_ENCRYPTION;
- str_end[3] = ENCRYPT_REQEND;
- str_end[4] = IAC;
- str_end[5] = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,"TELNET SENT SB %s REQEND IAC SE",
- TELOPT(TELOPT_ENCRYPTION)); /* safe */
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(str_end, sizeof(str_end));
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
-
- if (encrypt_debug_mode) {
- sprintf(dbgbuf, ">>>Request input to be clear text\n"); /* safe */
- debug(F110,"encrypt_send_request_end",dbgbuf,0);
- }
-}
-
-int
-#ifdef CK_ANSIC
-encrypt_is_encrypting(VOID)
-#else
-encrypt_is_encrypting()
-#endif
-{
- if (encrypt_output)
- return 1;
- return 0;
-}
-
-int
-#ifdef CK_ANSIC
-encrypt_is_decrypting(VOID)
-#else
-encrypt_is_decrypting()
-#endif
-{
- if (decrypt_input)
- return 1;
- return 0;
-}
-
-#ifdef DEBUG
-void
-encrypt_debug(mode)
- int mode;
-{
- encrypt_debug_mode = mode;
-}
-#endif
-
-#ifdef CK_DES
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* based on @(#)enc_des.c 8.1 (Berkeley) 6/4/93 */
-
-#define CFB 0
-#define OFB 1
-
-#define NO_SEND_IV 1
-#define NO_RECV_IV 2
-#define NO_KEYID 4
-#define IN_PROGRESS (NO_SEND_IV|NO_RECV_IV|NO_KEYID)
-#define SUCCESS 0
-#define xFAILED -1
-
-Schedule test_sched;
-
-struct des_stinfo {
- Block str_output;
- Block str_feed;
- Block str_iv;
- Block str_ikey;
-#ifdef MIT_CURRENT
- unsigned char str_keybytes[8];
- krb5_keyblock str_key;
-#else /* MIT_CURRENT */
- Schedule str_sched;
- int str_index;
-#endif /* MIT_CURRENT */
- int str_flagshift;
-};
-
-struct des_fb {
-#ifndef MIT_CURRENT
- Block krbdes_key;
- Schedule krbdes_sched;
-#endif /* MIT_CURRENT */
- Block temp_feed;
- unsigned char fb_feed[64];
- int need_start;
- int state[2];
- int keyid[2];
- int once;
-#ifdef MIT_CURRENT
- int validkey;
-#endif /* MIT_CURRENT */
- struct des_stinfo streams[2];
-};
-static struct des_fb des_fb[2];
-
-struct des3_stinfo {
- Block str_output;
- Block str_feed;
- Block str_iv;
- Block str_ikey[3];
- Schedule str_sched[3];
- int str_index;
- int str_flagshift;
-};
-
-struct des3_fb {
-#ifndef MIT_CURRENT
- Block krbdes_key[3];
- Schedule krbdes_sched[3];
-#endif /* MIT_CURRENT */
- Block temp_feed;
- unsigned char fb_feed[64];
- int need_start;
- int state[2];
- int keyid[2];
- int once;
-#ifdef MIT_CURRENT
- int validkey;
-#endif /* MIT_CURRENT */
- struct des3_stinfo streams[2];
-};
-static struct des3_fb des3_fb[2];
-
-struct keyidlist {
- char *keyid;
- int keyidlen;
- char *key;
- int keylen;
- int flags;
-} keyidlist [] = {
- { "\0", 1, 0, 0, 0 }, /* default key of zero */
- { 0, 0, 0, 0, 0 }
-};
-
-#define KEYFLAG_MASK 03
-
-#define KEYFLAG_NOINIT 00
-#define KEYFLAG_INIT 01
-#define KEYFLAG_OK 02
-#define KEYFLAG_BAD 03
-
-#define KEYFLAG_SHIFT 2
-
-#define SHIFT_VAL(a,b) (KEYFLAG_SHIFT*((a)+((b)*2)))
-
-#define FB64_IV 1
-#define FB64_IV_OK 2
-#define FB64_IV_BAD 3
-#define FB64_CHALLENGE 4
-#define FB64_RESPONSE 5
-
-void fb64_stream_iv P((Block, struct des_stinfo *));
-void fb64_init P((struct des_fb *));
-static int fb64_start P((struct des_fb *, int, int));
-int fb64_is P((unsigned char *, int, struct des_fb *));
-int fb64_reply P((unsigned char *, int, struct des_fb *));
-static int fb64_session P((Session_Key *, int, struct des_fb *));
-void fb64_stream_key P((Block, struct des_stinfo *));
-int fb64_keyid P((int, unsigned char *, int *, struct des_fb *));
-
-#ifdef MIT_CURRENT
-static void
-#ifdef CK_ANSIC
-ecb_encrypt(struct des_stinfo *stp, Block in, Block out)
-#else /* CKANSIC */
-ecb_encrypt(stp, in, out)
- struct des_stinfo *stp;
- Block in;
- Block out;
-#endif /* CK_ANSIC */
-{
- krb5_error_code code;
- krb5_data din;
- krb5_enc_data dout;
-
- din.length = 8;
- din.data = in;
-
- dout.ciphertext.length = 8;
- dout.ciphertext.data = out;
- dout.enctype = ENCTYPE_UNKNOWN;
-
-#ifdef CRYPT_DLL
- code = krb5_c_encrypt(*p_k5_context, &stp->str_key, 0, 0,
- &din, &dout);
-#else /* CRYPT_DLL */
- code = krb5_c_encrypt(k5_context, &stp->str_key, 0, 0,
- &din, &dout);
-#endif /* CRYPT_DLL */
- /* XXX I'm not sure what to do if this fails */
- if (code)
- com_err("libtelnet", code, "encrypting stream data");
-}
-#endif /* MIT_CURRENT */
-
-void
-cfb64_init(server)
- int server;
-{
- fb64_init(&des_fb[CFB]);
- des_fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64;
- des_fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB);
- des_fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB);
-}
-
-void
-ofb64_init(server)
- int server;
-{
- fb64_init(&des_fb[OFB]);
- des_fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64;
- des_fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB);
- des_fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB);
-}
-
-void
-fb64_init(fbp)
- register struct des_fb *fbp;
-{
- memset((void *)fbp, 0, sizeof(*fbp));
- fbp->state[0] = fbp->state[1] = xFAILED;
- fbp->fb_feed[0] = IAC;
- fbp->fb_feed[1] = SB;
- fbp->fb_feed[2] = TELOPT_ENCRYPTION;
- fbp->fb_feed[3] = ENCRYPT_IS;
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- * 2: Not yet. Other things (like getting the key from
- * Kerberos) have to happen before we can continue.
- */
-int
-cfb64_start(dir, server)
- int dir;
- int server;
-{
- return(fb64_start(&des_fb[CFB], dir, server));
-}
-int
-ofb64_start(dir, server)
- int dir;
- int server;
-{
- return(fb64_start(&des_fb[OFB], dir, server));
-}
-
-static int
-fb64_start(fbp, dir, server)
- struct des_fb *fbp;
- int dir;
- int server;
-{
- int x;
- unsigned char *p;
- register int state;
-
- switch (dir) {
- case DIR_DECRYPT:
- /*
- * This is simply a request to have the other side
- * start output (our input). He will negotiate an
- * IV so we need not look for it.
- */
- state = fbp->state[dir-1];
- if (state == xFAILED)
- state = IN_PROGRESS;
- break;
-
- case DIR_ENCRYPT:
- state = fbp->state[dir-1];
- if (state == xFAILED)
- state = IN_PROGRESS;
- else if ((state & NO_SEND_IV) == 0)
- break;
-
-#ifdef MIT_CURRENT
- if (!fbp->validkey) {
- fbp->need_start = 1;
- break;
- }
-#else /* MIT_CURRENT */
- if (!VALIDKEY(fbp->krbdes_key)) {
- fbp->need_start = 1;
- break;
- }
-#endif /* MIT_CURRENT */
- state &= ~NO_SEND_IV;
- state |= NO_RECV_IV;
- /*
- * Create a random feed and send it over.
- */
-#ifdef MIT_CURRENT
- {
- krb5_data d;
- krb5_error_code code;
-
- d.data = fbp->temp_feed;
- d.length = sizeof(fbp->temp_feed);
-
-#ifdef CRYPT_DLL
- if (code = krb5_c_random_make_octets(*p_k5_context,&d))
- return(xFAILED);
-#else /* CRYPT_DLL */
- if (code = krb5_c_random_make_octets(k5_context,&d))
- return(xFAILED);
-#endif /* CRYPT_DLL */
- }
-
-#else /* MIT_CURRENT */
- des_new_random_key(fbp->temp_feed);
- des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
- fbp->krbdes_sched, 1);
-#endif /* MIT_CURRENT */
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_IS;
- p++;
- *p++ = FB64_IV;
- for (x = 0; x < sizeof(Block); ++x) {
- if (( *p++ = fbp->temp_feed[x]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,
- "TELNET SENT SB %s IS %s FB64_IV ",
- TELOPT(fbp->fb_feed[2]),
- enctype_names[fbp->fb_feed[4]]); /* safe */
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],
- (p-fbp->fb_feed)-2-6);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(fbp->fb_feed, p - fbp->fb_feed);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- break;
- default:
- return(xFAILED);
- }
- return(fbp->state[dir-1] = state);
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- */
-int
-cfb64_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(fb64_is(data, cnt, &des_fb[CFB]));
-}
-
-int
-ofb64_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(fb64_is(data, cnt, &des_fb[OFB]));
-}
-
-int
-fb64_is(data, cnt, fbp)
- unsigned char *data;
- int cnt;
- struct des_fb *fbp;
-{
- unsigned char *p;
- register int state = fbp->state[DIR_DECRYPT-1];
-
- if (cnt-- < 1)
- goto failure;
-
-#ifdef CK_SSL
- if (!TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
-#endif /* CK_SSL */
- switch (*data++) {
- case FB64_IV:
- if (cnt != sizeof(Block)) {
-#ifdef DEBUG
- if (encrypt_debug_mode)
- printf("CFB64: initial vector failed on size\r\n");
-#endif
- state = xFAILED;
- goto failure;
- }
-
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- printf("CFB64: initial vector received\r\n");
- printf("Initializing Decrypt stream\r\n");
- }
-#endif
- fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]);
-
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_REPLY;
- p++;
- *p++ = FB64_IV_OK;
- *p++ = IAC;
- *p++ = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,
- "TELNET SENT SB %s REPLY %s FB64_IV_OK ",
- TELOPT(fbp->fb_feed[2]),
- enctype_names[fbp->fb_feed[4]]); /* safe */
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],
- (p-fbp->fb_feed)-2-6);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(fbp->fb_feed, p - fbp->fb_feed);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- state = IN_PROGRESS;
- break;
-
- default:
-#if 0
- if (encrypt_debug_mode) {
- printf("Unknown option type: %d\r\n", *(data-1));
- printf("\r\n");
- }
-#endif
- /* FALL THROUGH */
- failure:
- /*
- * We failed. Send an FB64_IV_BAD option
- * to the other side so it will know that
- * things failed.
- */
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_REPLY;
- p++;
- *p++ = FB64_IV_BAD;
- *p++ = IAC;
- *p++ = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,
- "TELNET SENT SB %s REPLY %s FB64_IV_BAD ",
- TELOPT(fbp->fb_feed[2]),
- enctype_names[fbp->fb_feed[4]]); /* safe */
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],
- (p-fbp->fb_feed)-2-6);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(fbp->fb_feed, p - fbp->fb_feed);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- break;
- }
- return(fbp->state[DIR_DECRYPT-1] = state);
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- */
-int
-cfb64_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(fb64_reply(data, cnt, &des_fb[CFB]));
-}
-int
-ofb64_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(fb64_reply(data, cnt, &des_fb[OFB]));
-}
-
-
-int
-fb64_reply(data, cnt, fbp)
- unsigned char *data;
- int cnt;
- struct des_fb *fbp;
-{
- register int state = fbp->state[DIR_ENCRYPT-1];
-
- if (cnt-- < 1)
- goto failure;
-
- switch (*data++) {
- case FB64_IV_OK:
- fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
- if (state == xFAILED)
- state = IN_PROGRESS;
- state &= ~NO_RECV_IV;
- encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1);
- break;
-
- case FB64_IV_BAD:
- memset(fbp->temp_feed, 0, sizeof(Block));
- fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
- state = xFAILED;
- break;
-
- default:
-#if 0
- if (encrypt_debug_mode) {
- printf("Unknown option type: %d\r\n", data[-1]);
- printf("\r\n");
- }
-#endif
- /* FALL THROUGH */
- failure:
- state = xFAILED;
- break;
- }
- return(fbp->state[DIR_ENCRYPT-1] = state);
-}
-
-int
-cfb64_session(key, server)
- Session_Key *key;
- int server;
-{
- return(fb64_session(key, server, &des_fb[CFB]));
-}
-
-int
-ofb64_session(key, server)
- Session_Key *key;
- int server;
-{
- return(fb64_session(key, server, &des_fb[OFB]));
-}
-
-static int
-fb64_session(key, server, fbp)
- Session_Key *key;
- int server;
- struct des_fb *fbp;
-{
- int rc=0;
- int use2keys;
- struct des_stinfo * s_stream;
- struct des_stinfo * c_stream;
-
- if(server) {
- s_stream = &fbp->streams[DIR_ENCRYPT-1];
- c_stream = &fbp->streams[DIR_DECRYPT-1];
- }
- else {
- s_stream = &fbp->streams[DIR_DECRYPT-1];
- c_stream = &fbp->streams[DIR_ENCRYPT-1];
- }
-
- if (!key || key->length < sizeof(Block)) {
- CHAR buf[80];
- sprintf((char *)buf,"Can't set DES session key (%d < %d)",
- key ? key->length : 0, sizeof(Block)); /* safe */
-#ifdef DEBUG
- if (encrypt_debug_mode)
- printf("%s\r\n",buf);
-#endif
- debug(F110,"fb64_session",buf,0);
- return(-1);
- }
- use2keys = (key->type == SK_DES ||
- key->length < 2 * sizeof(Block)) ? 0 : 1;
-#ifdef MIT_CURRENT
- if(use2keys) {
- memcpy((void *) fbp->keybytes,
- (void *) (key->data + sizeof(Block)), sizeof(Block));
- des_fixup_key_parity(fbp->);
- fb64_stream_key(fbp->krbdes_key, s_stream);
- }
-
- memcpy((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block));
- if (key->type != SK_DES)
- des_fixup_key_parity(fbp->krbdes_key);
-
- if(!use2keys)
- fb64_stream_key(fbp->krbdes_key, s_stream);
- fb64_stream_key(fbp->krbdes_key, c_stream);
- fbp->validkey = 1;
-
- fb64_stream_key(key->data, &fbp->streams[DIR_ENCRYPT-1]);
- fb64_stream_key(key->data, &fbp->streams[DIR_DECRYPT-1]);
-#else /* MIT_CURRENT */
- if(use2keys) {
- memcpy((void *) fbp->krbdes_key,
- (void *) (key->data + sizeof(Block)), sizeof(Block));
- des_fixup_key_parity(fbp->krbdes_key);
- fb64_stream_key(fbp->krbdes_key, s_stream);
- }
-
- memcpy((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block));
- if (key->type != SK_DES)
- des_fixup_key_parity(fbp->krbdes_key);
-
- if(!use2keys)
- fb64_stream_key(fbp->krbdes_key, s_stream);
- fb64_stream_key(fbp->krbdes_key, c_stream);
-
- if (fbp->once == 0) {
- des_set_random_generator_seed(fbp->krbdes_key);
- fbp->once = 1;
- }
-
- memset(fbp->krbdes_sched,0,sizeof(Schedule));
- ckhexdump("fb64_session_key",fbp->krbdes_key,8);
-
- rc = des_key_sched(fbp->krbdes_key, fbp->krbdes_sched);
- if ( rc == -1 ) {
- printf("?Invalid DES key specified for encryption\n");
- debug(F110,"fb64_session_key",
- "invalid DES Key specified for encryption",0);
- } else if ( rc == -2 ) {
- printf("?Weak DES key specified for encryption\n");
- debug(F110,"fb64_session_key",
- "weak DES Key specified for encryption",0);
- } else if ( rc != 0 ) {
- printf("?Key Schedule not created by encryption\n");
- debug(F110,"fb64_session_key",
- "Key Schedule not created by encryption",0);
- }
-
- ckhexdump("fb64_session_key schedule",fbp->krbdes_sched,8*16);
-#endif /* MIT_CURRENT */
- /*
- * Now look to see if krbdes_start() was was waiting for
- * the key to show up. If so, go ahead an call it now
- * that we have the key.
- */
- if (fbp->need_start) {
- fbp->need_start = 0;
- fb64_start(fbp, DIR_ENCRYPT, server);
- }
- return(0);
-}
-
-/*
- * We only accept a keyid of 0. If we get a keyid of
- * 0, then mark the state as SUCCESS.
- */
-int
-cfb64_keyid(dir, kp, lenp)
- int dir, *lenp;
- unsigned char *kp;
-{
- return(fb64_keyid(dir, kp, lenp, &des_fb[CFB]));
-}
-
-int
-ofb64_keyid(dir, kp, lenp)
- int dir, *lenp;
- unsigned char *kp;
-{
- return(fb64_keyid(dir, kp, lenp, &des_fb[OFB]));
-}
-
-int
-fb64_keyid(dir, kp, lenp, fbp)
- int dir, *lenp;
- unsigned char *kp;
- struct des_fb *fbp;
-{
- register int state = fbp->state[dir-1];
-
- if (*lenp != 1 || (*kp != '\0')) {
- *lenp = 0;
- return(state);
- }
-
- if (state == xFAILED)
- state = IN_PROGRESS;
-
- state &= ~NO_KEYID;
-
- return(fbp->state[dir-1] = state);
-}
-
-#if 0
-void
-fb64_printsub(data, cnt, buf, buflen, type)
- unsigned char *data, *buf, *type;
- int cnt, buflen;
-{
- char lbuf[64];
- register int i;
- char *cp;
-
- buf[buflen-1] = '\0'; /* make sure it's NULL terminated */
- buflen -= 1;
-
- switch(data[2]) {
- case FB64_IV:
- sprintf(lbuf, "%s_IV", type);
- cp = lbuf;
- goto common;
-
- case FB64_IV_OK:
- sprintf(lbuf, "%s_IV_OK", type);
- cp = lbuf;
- goto common;
-
- case FB64_IV_BAD:
- sprintf(lbuf, "%s_IV_BAD", type);
- cp = lbuf;
- goto common;
-
- case FB64_CHALLENGE:
- sprintf(lbuf, "%s_CHALLENGE", type);
- cp = lbuf;
- goto common;
-
- case FB64_RESPONSE:
- sprintf(lbuf, "%s_RESPONSE", type);
- cp = lbuf;
- goto common;
-
- default:
- sprintf(lbuf, " %d (unknown)", data[2]);
- cp = lbuf;
- common:
- for (; (buflen > 0) && (*buf = *cp++); buf++)
- buflen--;
- for (i = 3; i < cnt; i++) {
- sprintf(lbuf, " %d", data[i]);
- for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++)
- buflen--;
- }
- break;
- }
-}
-
-void
-cfb64_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt, buflen;
-{
- fb64_printsub(data, cnt, buf, buflen, "CFB64");
-}
-
-void
-ofb64_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt, buflen;
-{
- fb64_printsub(data, cnt, buf, buflen, "OFB64");
-}
-#endif
-
-void
-fb64_stream_iv(seed, stp)
- Block seed;
- register struct des_stinfo *stp;
-{
- int rc=0;
-
- memcpy(stp->str_iv, seed, sizeof(Block));
- memcpy(stp->str_output, seed, sizeof(Block));
-
- memset(stp->str_sched,0,sizeof(Schedule));
-
- ckhexdump("fb64_stream_iv",stp->str_ikey,8);
-
-#ifndef MIT_CURRENT
- rc = des_key_sched(stp->str_ikey, stp->str_sched);
- if ( rc == -1 ) {
- printf("?Invalid DES key specified for encryption\r\n");
- debug(F110,"fb64_stream_iv",
- "invalid DES Key specified for encryption",0);
- } else if ( rc == -2 ) {
- printf("?Weak DES key specified for encryption\r\n");
- debug(F110,"fb64_stream_iv",
- "weak DES Key specified for encryption",0);
- } else if ( rc != 0 ) {
- printf("?Key Schedule not created by encryption\r\n");
- debug(F110,"fb64_stream_iv",
- "Key Schedule not created by encryption",0);
- }
- ckhexdump("fb64_stream_iv schedule",stp->str_sched,8*16);
-#endif /* MIT_CURRENT */
-
- stp->str_index = sizeof(Block);
-}
-
-void
-fb64_stream_key(key, stp)
- Block key;
- register struct des_stinfo *stp;
-{
- int rc = 0;
-
-#ifdef MIT_CURRENT
- memcpy(stp->str_keybytes, key, sizeof(Block));
- stp->str_key.length = 8;
- stp->str_key.contents = stp->str_keybytes;
- /* the original version of this code uses des ecb mode, but
- it only ever does one block at a time. cbc with a zero iv
- is identical */
- stp->str_key.enctype = ENCTYPE_DES_CBC_RAW;
-#else /* MIT_CURRENT */
- memcpy(stp->str_ikey, key, sizeof(Block));
-
- memset(stp->str_sched,0,sizeof(Schedule));
-
- ckhexdump("fb64_stream_key",key,8);
-
- rc = des_key_sched(key, stp->str_sched);
- if ( rc == -1 ) {
- printf("?Invalid DES key specified for encryption\r\n");
- debug(F110,"fb64_stream_key",
- "invalid DES Key specified for encryption",0);
- } else if ( rc == -2 ) {
- printf("?Weak DES key specified for encryption\r\n");
- debug(F110,"fb64_stream_key",
- "weak DES Key specified for encryption",0);
- } else if ( rc != 0 ) {
- printf("?Key Schedule not created by encryption\r\n");
- debug(F110,"fb64_stream_key",
- "Key Schedule not created by encryption",0);
- }
- ckhexdump("fb64_stream_key schedule",stp->str_sched,8*16);
-#endif /* MIT_CURRENT */
-
- memcpy(stp->str_output, stp->str_iv, sizeof(Block));
-
- stp->str_index = sizeof(Block);
-}
-
-/*
- * DES 64 bit Cipher Feedback
- *
- * key --->+-----+
- * +->| DES |--+
- * | +-----+ |
- * | v
- * INPUT --(--------->(+)+---> DATA
- * | |
- * +-------------+
- *
- *
- * Given:
- * iV: Initial vector, 64 bits (8 bytes) long.
- * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
- * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
- *
- * V0 = DES(iV, key)
- * On = Dn ^ Vn
- * V(n+1) = DES(On, key)
- */
-
-void
-cfb64_encrypt(s, c)
- register unsigned char *s;
- int c;
-{
- register struct des_stinfo *stp = &des_fb[CFB].streams[DIR_ENCRYPT-1];
- register int index;
-
- index = stp->str_index;
- while (c-- > 0) {
- if (index == sizeof(Block)) {
- Block b;
-#ifdef MIT_CURRENT
- ecb_encrypt(stp, stp->str_output, b);
-#else /* MIT_CURRENT */
- des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1);
-#endif /* MIT_CURRENT */
- memcpy(stp->str_feed,b,sizeof(Block));
- index = 0;
- }
-
- /* On encryption, we store (feed ^ data) which is cypher */
- *s = stp->str_output[index] = (stp->str_feed[index] ^ *s);
- s++;
- index++;
- }
- stp->str_index = index;
-}
-
-int
-cfb64_decrypt(data)
- int data;
-{
- register struct des_stinfo *stp = &des_fb[CFB].streams[DIR_DECRYPT-1];
- int index;
-
- if (data == -1) {
- /*
- * Back up one byte. It is assumed that we will
- * never back up more than one byte. If we do, this
- * may or may not work.
- */
- if (stp->str_index)
- --stp->str_index;
- return(0);
- }
-
- index = stp->str_index++;
- if (index == sizeof(Block)) {
- Block b;
-#ifdef MIT_CURRENT
- ecb_encrypt(stp, stp->str_output, b);
-#else /* MIT_CURRENT */
- des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1);
-#endif /* MIT_CURRENT */
- memcpy(stp->str_feed, b, sizeof(Block));
- stp->str_index = 1; /* Next time will be 1 */
- index = 0; /* But now use 0 */
- }
-
- /* On decryption we store (data) which is cypher. */
- stp->str_output[index] = data;
- return(data ^ stp->str_feed[index]);
-}
-
-/*
- * DES 64 bit Output Feedback
- *
- * key --->+-----+
- * +->| DES |--+
- * | +-----+ |
- * +-----------+
- * v
- * INPUT -------->(+) ----> DATA
- *
- * Given:
- * iV: Initial vector, 64 bits (8 bytes) long.
- * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
- * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
- *
- * V0 = DES(iV, key)
- * V(n+1) = DES(Vn, key)
- * On = Dn ^ Vn
- */
-void
-ofb64_encrypt(s, c)
- register unsigned char *s;
- int c;
-{
- register struct des_stinfo *stp = &des_fb[OFB].streams[DIR_ENCRYPT-1];
- register int index;
-
- index = stp->str_index;
- while (c-- > 0) {
- if (index == sizeof(Block)) {
- Block b;
-#ifdef MIT_CURRENT
- ecb_encrypt(stp, stp->str_feed, b);
-#else /* MIT_CURRENT */
- des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1);
-#endif /* MIT_CURRENT */
- memcpy(stp->str_feed,b,sizeof(Block));
- index = 0;
- }
- *s++ ^= stp->str_feed[index];
- index++;
- }
- stp->str_index = index;
-}
-
-int
-ofb64_decrypt(data)
- int data;
-{
- register struct des_stinfo *stp = &des_fb[OFB].streams[DIR_DECRYPT-1];
- int index;
-
- if (data == -1) {
- /*
- * Back up one byte. It is assumed that we will
- * never back up more than one byte. If we do, this
- * may or may not work.
- */
- if (stp->str_index)
- --stp->str_index;
- return(0);
- }
-
- index = stp->str_index++;
- if (index == sizeof(Block)) {
- Block b;
-#ifdef MIT_CURRENT
- ecb_encrypt(stp, stp->str_feed, b);
-#else /* MIT_CURRENT */
- des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1);
-#endif /* MIT_CURRENT */
- memcpy(stp->str_feed, b, sizeof(Block));
- stp->str_index = 1; /* Next time will be 1 */
- index = 0; /* But now use 0 */
- }
-
- return(data ^ stp->str_feed[index]);
-}
-
-
-void des3_fb64_stream_iv P((Block, struct des3_stinfo *));
-void des3_fb64_init P((struct des3_fb *));
-static int des3_fb64_start P((struct des3_fb *, int, int));
-int des3_fb64_is P((unsigned char *, int, struct des3_fb *));
-int des3_fb64_reply P((unsigned char *, int, struct des3_fb *));
-static int des3_fb64_session P((Session_Key *, int, struct des3_fb *));
-void des3_fb64_stream_key P((Block *, struct des3_stinfo *));
-int des3_fb64_keyid P((int, unsigned char *, int *, struct des3_fb *));
-
-void
-des3_cfb64_init(server)
- int server;
-{
- des3_fb64_init(&des3_fb[CFB]);
- des3_fb[CFB].fb_feed[4] = ENCTYPE_DES3_CFB64;
- des3_fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB);
- des3_fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB);
-}
-
-void
-des3_ofb64_init(server)
- int server;
-{
- des3_fb64_init(&des3_fb[OFB]);
- des3_fb[OFB].fb_feed[4] = ENCTYPE_DES3_OFB64;
- des3_fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB);
- des3_fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB);
-}
-
-void
-des3_fb64_init(fbp)
- register struct des3_fb *fbp;
-{
- memset((void *)fbp, 0, sizeof(*fbp));
- fbp->state[0] = fbp->state[1] = xFAILED;
- fbp->fb_feed[0] = IAC;
- fbp->fb_feed[1] = SB;
- fbp->fb_feed[2] = TELOPT_ENCRYPTION;
- fbp->fb_feed[3] = ENCRYPT_IS;
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- * 2: Not yet. Other things (like getting the key from
- * Kerberos) have to happen before we can continue.
- */
-int
-des3_cfb64_start(dir, server)
- int dir;
- int server;
-{
- return(des3_fb64_start(&des3_fb[CFB], dir, server));
-}
-int
-des3_ofb64_start(dir, server)
- int dir;
- int server;
-{
- return(des3_fb64_start(&des3_fb[OFB], dir, server));
-}
-
-static int
-des3_fb64_start(fbp, dir, server)
- struct des3_fb *fbp;
- int dir;
- int server;
-{
- int x;
- unsigned char *p;
- register int state;
-
- switch (dir) {
- case DIR_DECRYPT:
- /*
- * This is simply a request to have the other side
- * start output (our input). He will negotiate an
- * IV so we need not look for it.
- */
- state = fbp->state[dir-1];
- if (state == xFAILED)
- state = IN_PROGRESS;
- break;
-
- case DIR_ENCRYPT:
- state = fbp->state[dir-1];
- if (state == xFAILED)
- state = IN_PROGRESS;
- else if ((state & NO_SEND_IV) == 0)
- break;
-
- if (!VALIDKEY(fbp->krbdes_key[0]) ||
- !VALIDKEY(fbp->krbdes_key[1]) ||
- !VALIDKEY(fbp->krbdes_key[2]) ) {
- fbp->need_start = 1;
- break;
- }
- state &= ~NO_SEND_IV;
- state |= NO_RECV_IV;
- /*
- * Create a random feed and send it over.
- */
- des_new_random_key(fbp->temp_feed);
-#ifdef LIBDES
- des_ecb3_encrypt(fbp->temp_feed, fbp->temp_feed,
- fbp->krbdes_sched[0],
- fbp->krbdes_sched[1],
- fbp->krbdes_sched[2],
- 1);
-#else /* LIBDES */
- des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
- fbp->krbdes_sched[0], 1);
- des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
- fbp->krbdes_sched[1], 0);
- des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
- fbp->krbdes_sched[2], 1);
-#endif /* LIBDES */
-
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_IS;
- p++;
- *p++ = FB64_IV;
- for (x = 0; x < sizeof(Block); ++x) {
- if (( *p++ = fbp->temp_feed[x]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,
- "TELNET SENT SB %s IS %s FB64_IV ",
- TELOPT(fbp->fb_feed[2]),
- enctype_names[fbp->fb_feed[4]]); /* safe */
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],
- (p-fbp->fb_feed)-2-6);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(fbp->fb_feed, p - fbp->fb_feed);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- break;
- default:
- return(xFAILED);
- }
- return(fbp->state[dir-1] = state);
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- */
-int
-des3_cfb64_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(des3_fb64_is(data, cnt, &des3_fb[CFB]));
-}
-
-int
-des3_ofb64_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(des3_fb64_is(data, cnt, &des3_fb[OFB]));
-}
-
-int
-des3_fb64_is(data, cnt, fbp)
- unsigned char *data;
- int cnt;
- struct des3_fb *fbp;
-{
- unsigned char *p;
- register int state = fbp->state[DIR_DECRYPT-1];
-
- if (cnt-- < 1)
- goto failure;
-
-#ifdef CK_SSL
- if (!TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
-#endif /* CK_SSL */
- switch (*data++) {
- case FB64_IV:
- if (cnt != sizeof(Block)) {
-#ifdef DEBUG
- if (encrypt_debug_mode)
- printf("DES3_FB64: initial vector failed on size\r\n");
-#endif
- state = xFAILED;
- goto failure;
- }
-
-#ifdef DEBUG
- if (encrypt_debug_mode) {
- printf("DES3_FB64: initial vector received\r\n");
- printf("Initializing Decrypt stream\r\n");
- }
-#endif
- des3_fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]);
-
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_REPLY;
- p++;
- *p++ = FB64_IV_OK;
- *p++ = IAC;
- *p++ = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,
- "TELNET SENT SB %s REPLY %s FB64_IV_OK ",
- TELOPT(fbp->fb_feed[2]),
- enctype_names[fbp->fb_feed[4]]); /* safe */
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],
- (p-fbp->fb_feed)-2-6);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(fbp->fb_feed, p - fbp->fb_feed);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- state = IN_PROGRESS;
- break;
-
- default:
-#if 0
- if (encrypt_debug_mode) {
- printf("Unknown option type: %d\r\n", *(data-1));
- printf("\r\n");
- }
-#endif
- /* FALL THROUGH */
- failure:
- /*
- * We failed. Send an FB64_IV_BAD option
- * to the other side so it will know that
- * things failed.
- */
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_REPLY;
- p++;
- *p++ = FB64_IV_BAD;
- *p++ = IAC;
- *p++ = SE;
-
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,
- "TELNET SENT SB %s REPLY %s FB64_IV_BAD ",
- TELOPT(fbp->fb_feed[2]),
- enctype_names[fbp->fb_feed[4]]); /* safe */
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],
- (p-fbp->fb_feed)-2-6);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol(fbp->fb_feed, p - fbp->fb_feed);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- break;
- }
- return(fbp->state[DIR_DECRYPT-1] = state);
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- */
-int
-des3_cfb64_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(des3_fb64_reply(data, cnt, &des3_fb[CFB]));
-}
-int
-des3_ofb64_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(des3_fb64_reply(data, cnt, &des3_fb[OFB]));
-}
-
-
-int
-des3_fb64_reply(data, cnt, fbp)
- unsigned char *data;
- int cnt;
- struct des3_fb *fbp;
-{
- register int state = fbp->state[DIR_ENCRYPT-1];
-
- if (cnt-- < 1)
- goto failure;
-
- switch (*data++) {
- case FB64_IV_OK:
- des3_fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
- if (state == xFAILED)
- state = IN_PROGRESS;
- state &= ~NO_RECV_IV;
- encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1);
- break;
-
- case FB64_IV_BAD:
- memset(fbp->temp_feed, 0, sizeof(Block));
- des3_fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
- state = xFAILED;
- break;
-
- default:
-#if 0
- if (encrypt_debug_mode) {
- printf("Unknown option type: %d\r\n", data[-1]);
- printf("\r\n");
- }
-#endif
- /* FALL THROUGH */
- failure:
- state = xFAILED;
- break;
- }
- return(fbp->state[DIR_ENCRYPT-1] = state);
-}
-
-int
-des3_cfb64_session(key, server)
- Session_Key *key;
- int server;
-{
- return(des3_fb64_session(key, server, &des3_fb[CFB]));
-}
-
-int
-des3_ofb64_session(key, server)
- Session_Key *key;
- int server;
-{
- return(des3_fb64_session(key, server, &des3_fb[OFB]));
-}
-
-static int
-des3_fb64_session(key, server, fbp)
- Session_Key *key;
- int server;
- struct des3_fb *fbp;
-{
- int rc=0,i=0;
- int keys2use=0;
- struct des3_stinfo * s_stream;
- struct des3_stinfo * c_stream;
-
- if(server) {
- s_stream = &fbp->streams[DIR_ENCRYPT-1];
- c_stream = &fbp->streams[DIR_DECRYPT-1];
- }
- else {
- s_stream = &fbp->streams[DIR_DECRYPT-1];
- c_stream = &fbp->streams[DIR_ENCRYPT-1];
- }
-
- keys2use = key->length / sizeof(Block);
- if (!key || (key->type == SK_DES) || (keys2use < 2)) {
- CHAR buf[80];
- sprintf((char *)buf,"Can't set 3DES session key (%d < %d)",
- key ? key->length : 0, 2 * (int)sizeof(Block)); /* safe */
-#ifdef DEBUG
- if (encrypt_debug_mode)
- printf("%s\r\n",buf);
-#endif
- debug(F110,"des3_fb64_session",buf,0);
- return(-1);
- }
-
- debug(F111,"des3_fb64_session","keys2use",keys2use);
- /* Compute the first set of keys / key order */
- switch ( keys2use ) {
- case 2:
- memcpy((void *)fbp->krbdes_key[0], (void *)key->data, sizeof(Block));
- memcpy((void *) fbp->krbdes_key[1],(void *)(key->data + sizeof(Block)),
- sizeof(Block));
- memcpy((void *)fbp->krbdes_key[2], (void *)key->data, sizeof(Block));
- break;
- case 3:
- default:
- memcpy((void *)fbp->krbdes_key[0], (void *)key->data, sizeof(Block));
- memcpy((void *) fbp->krbdes_key[1],(void *)(key->data + sizeof(Block)),
- sizeof(Block));
- memcpy((void *) fbp->krbdes_key[2],
- (void *) (key->data + 2*sizeof(Block)), sizeof(Block));
- break;
- }
- ckhexdump("des3_session_key key->data",key->data,sizeof(Block));
- ckhexdump("des3_session_key fbp->krbdes_key[0]",
- fbp->krbdes_key[0],
- sizeof(Block)
- );
- if (fbp->once == 0) {
- des_set_random_generator_seed(fbp->krbdes_key[0]);
- fbp->once = 1;
- }
-
- for ( i=0;i<3;i++ )
- des_fixup_key_parity(fbp->krbdes_key[i]);
- des3_fb64_stream_key(fbp->krbdes_key, s_stream);
-
-
- /* Compute the second set of keys / key order */
- switch ( keys2use ) {
- case 2:
- memcpy((void *) fbp->krbdes_key[0],(void *)(key->data + sizeof(Block)),
- sizeof(Block));
- memcpy((void *)fbp->krbdes_key[1], (void *)key->data, sizeof(Block));
- memcpy((void *) fbp->krbdes_key[2],(void *)(key->data + sizeof(Block)),
- sizeof(Block));
- break;
- case 3:
- memcpy((void *) fbp->krbdes_key[0],(void *)(key->data + sizeof(Block)),
- sizeof(Block));
- memcpy((void *) fbp->krbdes_key[1],
- (void *) (key->data + 2*sizeof(Block)), sizeof(Block));
- memcpy((void *)fbp->krbdes_key[2], (void *)key->data, sizeof(Block));
- break;
- case 4:
- memcpy((void *) fbp->krbdes_key[0],(void *)(key->data + sizeof(Block)),
- sizeof(Block));
- memcpy((void *) fbp->krbdes_key[1],
- (void *) (key->data + 3*sizeof(Block)), sizeof(Block));
- memcpy((void *)fbp->krbdes_key[2], (void *)key->data, sizeof(Block));
- break;
- case 5:
- memcpy((void *) fbp->krbdes_key[0],(void *)(key->data + sizeof(Block)),
- sizeof(Block));
- memcpy((void *) fbp->krbdes_key[1],
- (void *) (key->data + 3*sizeof(Block)), sizeof(Block));
- memcpy((void *)fbp->krbdes_key[2],
- (void *)(key->data + 4*sizeof(Block)), sizeof(Block));
- break;
- case 6:
- memcpy((void *) fbp->krbdes_key[0],
- (void *) (key->data + 3*sizeof(Block)), sizeof(Block));
- memcpy((void *)fbp->krbdes_key[1],
- (void *)(key->data + 4*sizeof(Block)), sizeof(Block));
- memcpy((void *) fbp->krbdes_key[2],
- (void *) (key->data + 5 *sizeof(Block)), sizeof(Block));
- break;
- }
-
- for ( i=0;i<3;i++ )
- des_fixup_key_parity(fbp->krbdes_key[i]);
- des3_fb64_stream_key(fbp->krbdes_key, c_stream);
-
- /* now use the second set of keys to build the default Key Schedule */
- /* which is used for generating the IV. */
- for ( i=0;i<3;i++ ) {
- memset(fbp->krbdes_sched[i],0,sizeof(Schedule));
-
- rc = des_key_sched(fbp->krbdes_key[i], fbp->krbdes_sched[i]);
- if ( rc == -1 ) {
- printf("?Invalid DES key specified for encryption [DES3,%s]\r\n",
- server?"server":"client");
- debug(F110,"des3_fb64_stream_iv",
- "invalid DES Key specified for encryption",0);
- } else if ( rc == -2 ) {
- printf("?Weak DES key specified for encryption\r\n");
- debug(F110,"des3_fb64_stream_iv",
- "weak DES Key specified for encryption",0);
- } else if ( rc != 0 ) {
- printf("?Key Schedule not created by encryption\r\n");
- debug(F110,"des3_fb64_stream_iv",
- "Key Schedule not created by encryption",0);
- }
- ckhexdump("des3_fb64_session_key schedule",fbp->krbdes_sched[i],8*16);
- }
- /*
- * Now look to see if krbdes_start() was was waiting for
- * the key to show up. If so, go ahead an call it now
- * that we have the key.
- */
- if (fbp->need_start) {
- fbp->need_start = 0;
- des3_fb64_start(fbp, DIR_ENCRYPT, server);
- }
- return(0);
-}
-
-/*
- * We only accept a keyid of 0. If we get a keyid of
- * 0, then mark the state as SUCCESS.
- */
-int
-des3_cfb64_keyid(dir, kp, lenp)
- int dir, *lenp;
- unsigned char *kp;
-{
- return(des3_fb64_keyid(dir, kp, lenp, &des3_fb[CFB]));
-}
-
-int
-des3_ofb64_keyid(dir, kp, lenp)
- int dir, *lenp;
- unsigned char *kp;
-{
- return(des3_fb64_keyid(dir, kp, lenp, &des3_fb[OFB]));
-}
-
-int
-des3_fb64_keyid(dir, kp, lenp, fbp)
- int dir, *lenp;
- unsigned char *kp;
- struct des3_fb *fbp;
-{
- register int state = fbp->state[dir-1];
-
- if (*lenp != 1 || (*kp != '\0')) {
- *lenp = 0;
- return(state);
- }
-
- if (state == xFAILED)
- state = IN_PROGRESS;
-
- state &= ~NO_KEYID;
-
- return(fbp->state[dir-1] = state);
-}
-
-#if 0
-void
-des3_fb64_printsub(data, cnt, buf, buflen, type)
- unsigned char *data, *buf, *type;
- int cnt, buflen;
-{
- char lbuf[64];
- register int i;
- char *cp;
-
- buf[buflen-1] = '\0'; /* make sure it's NULL terminated */
- buflen -= 1;
-
- switch(data[2]) {
- case FB64_IV:
- sprintf(lbuf, "%s_IV", type);
- cp = lbuf;
- goto common;
-
- case FB64_IV_OK:
- sprintf(lbuf, "%s_IV_OK", type);
- cp = lbuf;
- goto common;
-
- case FB64_IV_BAD:
- sprintf(lbuf, "%s_IV_BAD", type);
- cp = lbuf;
- goto common;
-
- case FB64_CHALLENGE:
- sprintf(lbuf, "%s_CHALLENGE", type);
- cp = lbuf;
- goto common;
-
- case FB64_RESPONSE:
- sprintf(lbuf, "%s_RESPONSE", type);
- cp = lbuf;
- goto common;
-
- default:
- sprintf(lbuf, " %d (unknown)", data[2]);
- cp = lbuf;
- common:
- for (; (buflen > 0) && (*buf = *cp++); buf++)
- buflen--;
- for (i = 3; i < cnt; i++) {
- sprintf(lbuf, " %d", data[i]);
- for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++)
- buflen--;
- }
- break;
- }
-}
-
-void
-des3_cfb64_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt, buflen;
-{
- des3_fb64_printsub(data, cnt, buf, buflen, "CFB64");
-}
-
-void
-des3_ofb64_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt, buflen;
-{
- des3_fb64_printsub(data, cnt, buf, buflen, "OFB64");
-}
-#endif
-
-void
-des3_fb64_stream_iv(seed, stp)
- Block seed;
- register struct des3_stinfo *stp;
-{
- int rc=0, i = 0;;
-
- memcpy(stp->str_iv, seed, sizeof(Block));
- memcpy(stp->str_output, seed, sizeof(Block));
- for ( i=0;i<3;i++ ) {
- memset(stp->str_sched[i],0,sizeof(Schedule));
-
- ckhexdump("des3_fb64_stream_iv",stp->str_ikey[i],8);
-
- rc = des_key_sched(stp->str_ikey[i], stp->str_sched[i]);
- if ( rc == -1 ) {
- printf("?Invalid DES key specified for encryption [DES3 iv]\r\n");
- debug(F110,"des3_fb64_stream_iv",
- "invalid DES Key specified for encryption",0);
- } else if ( rc == -2 ) {
- printf("?Weak DES key specified for encryption\r\n");
- debug(F110,"des3_fb64_stream_iv",
- "weak DES Key specified for encryption",0);
- } else if ( rc != 0 ) {
- printf("?Key Schedule not created by encryption\r\n");
- debug(F110,"des3_fb64_stream_iv",
- "Key Schedule not created by encryption",0);
- }
- ckhexdump("des3_fb64_stream_iv schedule",stp->str_sched[i],8*16);
- }
- stp->str_index = sizeof(Block);
-}
-
-void
-des3_fb64_stream_key(key, stp)
- Block * key;
- register struct des3_stinfo *stp;
-{
- int rc = 0, i = 0;
-
- for ( i=0;i<3;i++ ) {
- memcpy(stp->str_ikey[i], key[i], sizeof(Block));
-
- memset(stp->str_sched[i],0,sizeof(Schedule));
-
- ckhexdump("des3_fb64_stream_key",key[i],8);
-
- rc = des_key_sched(key[i], stp->str_sched[i]);
- if ( rc == -1 ) {
- printf("?Invalid DES key specified for encryption [DES3 key]\r\n");
- debug(F110,"des3_fb64_stream_key",
- "invalid DES Key specified for encryption",0);
- } else if ( rc == -2 ) {
- printf("?Weak DES key specified for encryption\r\n");
- debug(F110,"des3_fb64_stream_key",
- "weak DES Key specified for encryption",0);
- } else if ( rc != 0 ) {
- printf("?Key Schedule not created by encryption\r\n");
- debug(F110,"des3_fb64_stream_key",
- "Key Schedule not created by encryption",0);
- }
- ckhexdump("des3_fb64_stream_key schedule",stp->str_sched[i],8*16);
- }
-
- memcpy(stp->str_output, stp->str_iv, sizeof(Block));
- stp->str_index = sizeof(Block);
-}
-
-/*
- * DES3 64 bit Cipher Feedback
- *
- * key1 key2 key3
- * | | |
- * v v v
- * +-------+ +-------+ +-------+
- * +->| DES-e |->| DES-d |->| DES-e |-- +
- * | +-------+ +-------+ +-------+ |
- * | v
- * INPUT --(-------------------------------->(+)+---> DATA
- * | |
- * +------------------------------------+
- *
- *
- * Given:
- * iV: Initial vector, 64 bits (8 bytes) long.
- * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
- * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
- *
- * V0 = DES-e(DES-d(DES-e(iV, key1),key2),key3)
- * On = Dn ^ Vn
- * V(n+1) = DES-e(DES-d(DES-e(On, key1),key2),key3)
- */
-
-void
-des3_cfb64_encrypt(s, c)
- register unsigned char *s;
- int c;
-{
- register struct des3_stinfo *stp = &des3_fb[CFB].streams[DIR_ENCRYPT-1];
- register int index;
-
- index = stp->str_index;
- while (c-- > 0) {
- if (index == sizeof(Block)) {
- Block b;
-#ifdef LIBDES
- des_ecb3_encrypt(stp->str_output, b, stp->str_sched[0],
- stp->str_sched[1], stp->str_sched[2], 1);
-#else /* LIBDES */
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[0], 1);
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[1], 0);
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[2], 1);
-#endif /* LIBDES */
- memcpy(stp->str_feed,b,sizeof(Block));
- index = 0;
- }
-
- /* On encryption, we store (feed ^ data) which is cypher */
- *s = stp->str_output[index] = (stp->str_feed[index] ^ *s);
- s++;
- index++;
- }
- stp->str_index = index;
-}
-
-int
-des3_cfb64_decrypt(data)
- int data;
-{
- register struct des3_stinfo *stp = &des3_fb[CFB].streams[DIR_DECRYPT-1];
- int index;
-
- if (data == -1) {
- /*
- * Back up one byte. It is assumed that we will
- * never back up more than one byte. If we do, this
- * may or may not work.
- */
- if (stp->str_index)
- --stp->str_index;
- return(0);
- }
-
- index = stp->str_index++;
- if (index == sizeof(Block)) {
- Block b;
-#ifdef LIBDES
- des_ecb3_encrypt(stp->str_output, b, stp->str_sched[0],
- stp->str_sched[1], stp->str_sched[2], 1);
-#else /* LIBDES */
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[0], 1);
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[1], 0);
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[2], 1);
-#endif /* LIBDES */
- memcpy(stp->str_feed, b, sizeof(Block));
- stp->str_index = 1; /* Next time will be 1 */
- index = 0; /* But now use 0 */
- }
-
- /* On decryption we store (data) which is cypher. */
- stp->str_output[index] = data;
- return(data ^ stp->str_feed[index]);
-}
-
-/*
- * DES3 64 bit Output Feedback
- *
- *
- * key1 key2 key3
- * | | |
- * v v v
- * +-------+ +-------+ +-------+
- * +->| DES-e |->| DES-d |->| DES-e |-- +
- * | +-------+ +-------+ +-------+ |
- * +------------------------------------+
- * v
- * INPUT ------------------------------------->(+) ----> DATA
- *
- * Given:
- * iV: Initial vector, 64 bits (8 bytes) long.
- * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
- * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
- *
- * V0 = DES-e(DES-d(DES-e(iV, key1),key2),key3)
- * V(n+1) = DES-e(DES-d(DES-e(Vn, key1),key2),key3)
- * On = Dn ^ Vn
- */
-void
-des3_ofb64_encrypt(s, c)
- register unsigned char *s;
- int c;
-{
- register struct des3_stinfo *stp = &des3_fb[OFB].streams[DIR_ENCRYPT-1];
- register int index;
-
- index = stp->str_index;
- while (c-- > 0) {
- if (index == sizeof(Block)) {
- Block b;
-#ifdef LIBDES
- des_ecb3_encrypt(stp->str_feed, b, stp->str_sched[0],
- stp->str_sched[1], stp->str_sched[2], 1);
-#else /* LIBDES */
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[0], 1);
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[1], 0);
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[2], 1);
-#endif /* LIBDES */
- memcpy(stp->str_feed,b,sizeof(Block));
- index = 0;
- }
- *s++ ^= stp->str_feed[index];
- index++;
- }
- stp->str_index = index;
-}
-
-int
-des3_ofb64_decrypt(data)
- int data;
-{
- register struct des3_stinfo *stp = &des3_fb[OFB].streams[DIR_DECRYPT-1];
- int index;
-
- if (data == -1) {
- /*
- * Back up one byte. It is assumed that we will
- * never back up more than one byte. If we do, this
- * may or may not work.
- */
- if (stp->str_index)
- --stp->str_index;
- return(0);
- }
-
- index = stp->str_index++;
- if (index == sizeof(Block)) {
- Block b;
-#ifdef LIBDES
- des_ecb3_encrypt(stp->str_feed, b, stp->str_sched[0],
- stp->str_sched[1], stp->str_sched[2], 1);
-#else /* LIBDES */
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[0], 1);
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[1], 0);
- des_ecb_encrypt(stp->str_output, b,
- stp->str_sched[2], 1);
-#endif /* LIBDES */
- memcpy(stp->str_feed, b, sizeof(Block));
- stp->str_index = 1; /* Next time will be 1 */
- index = 0; /* But now use 0 */
- }
-
- return(data ^ stp->str_feed[index]);
-}
-#endif /* CK_DES */
-
-#ifdef CK_CAST
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 1997 Stanford University
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdio.h>
-#ifdef __STDC__
-#include <stdlib.h>
-#endif
-
-/*
- * cast.h
- * Author: Tom Wu
- *
- * Type and function declarations for CAST.
- */
-
-#ifndef _CAST_H_
-#define _CAST_H_
-
-#ifndef P
-#ifdef __STDC__
-#define P(x) x
-#else
-#define P(x) ()
-#endif /* __STDC__ */
-#endif /* P */
-
-#ifndef LITTLE_ENDIAN
-#ifndef BIG_ENDIAN
-#ifndef WORDS_BIGENDIAN
-#define LITTLE_ENDIAN 1
-#endif /* WORDS_BIGENDIAN */
-#endif /* BIG_ENDIAN */
-#endif /* LITTLE_ENDIAN */
-
-typedef unsigned int uint32; /* Must be 32 bits */
-typedef uint32 * uint32p;
-typedef unsigned char uint8;
-typedef uint8 * uint8p;
-
-typedef struct {
- struct CastSubkeyPair {
- uint32 Km;
- uint32 Kr;
- } K[16];
- int ksize;
-} CastKeySched;
-
-/*
- * cast*_key_sched(schedule, key)
- *
- * Initializes the CAST key schedule "schedule" according to the given key.
- * The different setup routines accept different length keys:
- *
- * ck_cast5_40_key_sched: 40-bit/5-byte (12 round) keys
- * ck_cast5_64_key_sched: 64-bit/8-byte (12 round) keys
- * ck_cast5_80_key_sched: 80-bit/10-byte (12 round) keys
- * ck_cast128_key_sched: 128-bit/16-byte (16 round) keys
- */
-
-extern void ck_cast5_40_key_sched P((CastKeySched *, uint8 *));
-extern void ck_cast5_64_key_sched P((CastKeySched *, uint8 *));
-extern void ck_cast5_80_key_sched P((CastKeySched *, uint8 *));
-extern void ck_cast128_key_sched P((CastKeySched *, uint8 *));
-
-/*
- * ck_cast_ecb_encrypt(output, input, schedule, mode)
- * ck_cast_ecb_crypt(data, schedule, mode)
- *
- * Encrypts the 64-bit "input" according to the CAST key schedule
- * "schedule" and places the result in "output". If "mode" is 0,
- * ck_cast_ecb_encrypt will encrypt, otherwise it will decrypt.
- * "Output" and "input" can point to the same memory, in which case
- * en/decryption will be performed in place.
- *
- * ck_cast_ecb_crypt accepts input in the form of an array of two
- * 32-bit words and performs encryption/decryption in place.
- */
-
-extern void ck_cast_ecb_encrypt P((uint8 *, uint8 *, CastKeySched *, int));
-extern void ck_cast_ecb_crypt P((uint32 *, CastKeySched *, int));
-
-#endif /* CAST_H */
-
-extern encrypt_debug_mode;
-
-#define CFB_40 0
-#define OFB_40 1
-#ifdef CAST_EXPORT_ENCRYPTION
-#define FB_CNT 2
-#else
-#define CFB_128 2
-#define OFB_128 3
-#define FB_CNT 4
-#endif
-
-#define NO_SEND_IV 1
-#define NO_RECV_IV 2
-#define NO_KEYID 4
-#define IN_PROGRESS (NO_SEND_IV|NO_RECV_IV|NO_KEYID)
-#define SUCCESS 0
-#define cFAILED -1
-
-
-struct cast_fb {
- Block temp_feed;
- unsigned char fb_feed[64];
- int key_isset;
- int need_start;
- int state[2];
- struct cast_stinfo {
- Block str_output;
- Block str_feed;
- Block str_iv;
- CastKeySched str_sched;
- int str_index;
- } streams[2];
-};
-
-static struct cast_fb cast_fb[FB_CNT];
-
-#define FB64_IV 1
-#define FB64_IV_OK 2
-#define FB64_IV_BAD 3
-
-
-static void cast_fb64_stream_iv P((Block, struct cast_stinfo *));
-static void cast_fb64_init P((struct cast_fb *));
-static int cast_fb64_start P((struct cast_fb *, int, int));
-static int cast_fb64_is P((unsigned char *, int, struct cast_fb *));
-static int cast_fb64_reply P((unsigned char *, int, struct cast_fb *));
-static int cast_fb64_session P((Session_Key *, int, struct cast_fb *, int));
-static void cast_fb64_stream_key P((Block, struct cast_stinfo *, int));
-static int cast_fb64_keyid P((int, unsigned char *, int *, struct cast_fb *));
-static void _cast_cfb64_encrypt P((unsigned char *,int, struct cast_stinfo *));
-static int _cast_cfb64_decrypt P((int, struct cast_stinfo *));
-static void _cast_ofb64_encrypt P((unsigned char *,int, struct cast_stinfo *));
-static int _cast_ofb64_decrypt P((int, struct cast_stinfo *));
-
-#ifndef CAST_EXPORT_ENCRYPTION
-void
-cast_cfb64_init(server)
- int server;
-{
- cast_fb64_init(&cast_fb[CFB_128]);
- cast_fb[CFB_128].fb_feed[4] = ENCTYPE_CAST128_CFB64;
-}
-
-void
-cast_ofb64_init(server)
- int server;
-{
- cast_fb64_init(&cast_fb[OFB_128]);
- cast_fb[OFB_128].fb_feed[4] = ENCTYPE_CAST128_OFB64;
-}
-#endif
-
-void
-castexp_cfb64_init(server)
- int server;
-{
- cast_fb64_init(&cast_fb[CFB_40]);
- cast_fb[CFB_40].fb_feed[4] = ENCTYPE_CAST5_40_CFB64;
-}
-
-void
-castexp_ofb64_init(server)
- int server;
-{
- cast_fb64_init(&cast_fb[OFB_40]);
- cast_fb[OFB_40].fb_feed[4] = ENCTYPE_CAST5_40_OFB64;
-}
-
-static void
-cast_fb64_init(fbp)
- register struct cast_fb *fbp;
-{
- memset((void *)fbp, 0, sizeof(*fbp));
- fbp->key_isset = 0;
- fbp->state[0] = fbp->state[1] = cFAILED;
- fbp->fb_feed[0] = IAC;
- fbp->fb_feed[1] = SB;
- fbp->fb_feed[2] = TELOPT_ENCRYPTION;
- fbp->fb_feed[3] = ENCRYPT_IS;
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- * 2: Not yet. Other things (like getting the key from
- * Kerberos) have to happen before we can continue.
- */
-#ifndef CAST_EXPORT_ENCRYPTION
-int
-cast_cfb64_start(dir, server)
- int dir;
- int server;
-{
- return(cast_fb64_start(&cast_fb[CFB_128], dir, server));
-}
-
-int
-cast_ofb64_start(dir, server)
- int dir;
- int server;
-{
- return(cast_fb64_start(&cast_fb[OFB_128], dir, server));
-}
-#endif
-
-int
-castexp_cfb64_start(dir, server)
- int dir;
- int server;
-{
- return(cast_fb64_start(&cast_fb[CFB_40], dir, server));
-}
-
-int
-castexp_ofb64_start(dir, server)
- int dir;
- int server;
-{
- return(cast_fb64_start(&cast_fb[OFB_40], dir, server));
-}
-
-static int
-cast_fb64_start(fbp, dir, server)
- struct cast_fb *fbp;
- int dir;
- int server;
-{
- Block b;
- int x;
- unsigned char *p;
- register int state;
-
- switch (dir) {
- case DIR_DECRYPT:
- /*
- * This is simply a request to have the other side
- * start output (our input). He will negotiate an
- * IV so we need not look for it.
- */
- state = fbp->state[dir-1];
- if (state == cFAILED)
- state = IN_PROGRESS;
- break;
-
- case DIR_ENCRYPT:
- state = fbp->state[dir-1];
- if (state == cFAILED)
- state = IN_PROGRESS;
- else if ((state & NO_SEND_IV) == 0)
- break;
-
- if (!fbp->key_isset) {
- fbp->need_start = 1;
- break;
- }
- state &= ~NO_SEND_IV;
- state |= NO_RECV_IV;
-#ifdef DEBUG
- if (encrypt_debug_mode)
- printf("Creating new feed\r\n");
-#endif
- /*
- * Create a random feed and send it over.
- */
- ck_cast_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
- &fbp->streams[dir-1].str_sched, 0);
-
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_IS;
- p++;
- *p++ = FB64_IV;
- for (x = 0; x < sizeof(Block); ++x) {
- if ((*p++ = fbp->temp_feed[x]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
-
- ttol(fbp->fb_feed, p - fbp->fb_feed);
- break;
- default:
- return(cFAILED);
- }
- return(fbp->state[dir-1] = state);
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- */
-#ifndef CAST_EXPORT_ENCRYPTION
-int
-cast_cfb64_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(cast_fb64_is(data, cnt, &cast_fb[CFB_128]));
-}
-
-int
-cast_ofb64_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(cast_fb64_is(data, cnt, &cast_fb[OFB_128]));
-}
-#endif
-
-int
-castexp_cfb64_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(cast_fb64_is(data, cnt, &cast_fb[CFB_40]));
-}
-
-int
-castexp_ofb64_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(cast_fb64_is(data, cnt, &cast_fb[OFB_40]));
-}
-
-static int
-cast_fb64_is(data, cnt, fbp)
- unsigned char *data;
- int cnt;
- struct cast_fb *fbp;
-{
- int x;
- unsigned char *p;
- Block b;
- register int state = fbp->state[DIR_DECRYPT-1];
-
- if (cnt-- < 1)
- goto failure;
-
-#ifdef CK_SSL
- if (!TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
-#endif /* CK_SSL */
- switch (*data++) {
- case FB64_IV:
- if (cnt != sizeof(Block)) {
-#ifdef DEBUG
- if (encrypt_debug_mode)
- printf("FB64: initial vector failed on size\r\n");
-#endif
- state = cFAILED;
- goto failure;
- }
-#ifdef DEBUG
- if (encrypt_debug_mode)
- printf("FB64: initial vector received\r\n");
-
- if (encrypt_debug_mode)
- printf("Initializing Decrypt stream\r\n");
-#endif
- cast_fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]);
-
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_REPLY;
- p++;
- *p++ = FB64_IV_OK;
- *p++ = IAC;
- *p++ = SE;
-
- ttol(fbp->fb_feed, p - fbp->fb_feed);
- state = IN_PROGRESS;
- break;
-
- default:
- /* unknown option type */
- /* FALL THROUGH */
- failure:
- /*
- * We failed. Send an FB64_IV_BAD option
- * to the other side so it will know that
- * things failed.
- */
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_REPLY;
- p++;
- *p++ = FB64_IV_BAD;
- *p++ = IAC;
- *p++ = SE;
-
- ttol(fbp->fb_feed, p - fbp->fb_feed);
- break;
- }
- return(fbp->state[DIR_DECRYPT-1] = state);
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- */
-#ifndef CAST_EXPORT_ENCRYPTION
-int
-cast_cfb64_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(cast_fb64_reply(data, cnt, &cast_fb[CFB_128]));
-}
-
-int
-cast_ofb64_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(cast_fb64_reply(data, cnt, &cast_fb[OFB_128]));
-}
-#endif
-
-int
-castexp_cfb64_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(cast_fb64_reply(data, cnt, &cast_fb[CFB_40]));
-}
-
-int
-castexp_ofb64_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(cast_fb64_reply(data, cnt, &cast_fb[OFB_40]));
-}
-
-static int
-cast_fb64_reply(data, cnt, fbp)
- unsigned char *data;
- int cnt;
- struct cast_fb *fbp;
-{
- int x;
- unsigned char *p;
- Block b;
- register int state = fbp->state[DIR_ENCRYPT-1];
-
- if (cnt-- < 1)
- goto failure;
-
- switch (*data++) {
- case FB64_IV_OK:
- cast_fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
- if (state == cFAILED)
- state = IN_PROGRESS;
- state &= ~NO_RECV_IV;
- encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1);
- break;
-
- case FB64_IV_BAD:
- memset(fbp->temp_feed, 0, sizeof(Block));
- cast_fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
- state = cFAILED;
- break;
-
- default:
-#if 0
- if (encrypt_debug_mode) {
- printf("Unknown option type: %d\r\n", data[-1]);
- printd(data, cnt);
- printf("\r\n");
- }
-#endif
- /* FALL THROUGH */
- failure:
- state = cFAILED;
- break;
- }
- return(fbp->state[DIR_ENCRYPT-1] = state);
-}
-
-#ifndef CAST_EXPORT_ENCRYPTION
-int
-cast_cfb64_session(key, server)
- Session_Key *key;
- int server;
-{
- return(cast_fb64_session(key, server, &cast_fb[CFB_128], 1));
-}
-
-int
-cast_ofb64_session(key, server)
- Session_Key *key;
- int server;
-{
- return(cast_fb64_session(key, server, &cast_fb[OFB_128], 1));
-}
-#endif
-
-int
-castexp_cfb64_session(key, server)
- Session_Key *key;
- int server;
-{
- return(cast_fb64_session(key, server, &cast_fb[CFB_40], 0));
-}
-
-int
-castexp_ofb64_session(key, server)
- Session_Key *key;
- int server;
-{
- return(cast_fb64_session(key, server, &cast_fb[OFB_40], 0));
-}
-
-#define CAST128_KEYLEN 16 /* 128 bits */
-#define CAST5_40_KEYLEN 5 /* 40 bits */
-
-static int
-cast_fb64_session(key, server, fbp, fs)
- Session_Key *key;
- int server;
- struct cast_fb *fbp;
- int fs;
-{
- int klen;
- unsigned char * kptr;
-
- if(fs)
- klen = CAST128_KEYLEN;
- else
- klen = CAST5_40_KEYLEN;
-
- if (!key || key->length < klen) {
- CHAR buf[80];
- sprintf((char *)buf,"Can't set CAST session key (%d < %d)",
- key ? key->length : 0, klen); /* safe */
-#ifdef DEBUG
- if (encrypt_debug_mode)
- printf("%s\r\n",buf);
-#endif
- debug(F110,"cast_fb64_session",buf,0);
- return(cFAILED);
- }
- if(key->length < 2 * klen)
- kptr = key->data;
- else
- kptr = key->data + klen;
-
- if(server) {
- cast_fb64_stream_key(kptr, &fbp->streams[DIR_ENCRYPT-1], fs);
- cast_fb64_stream_key(key->data, &fbp->streams[DIR_DECRYPT-1], fs);
- }
- else {
- cast_fb64_stream_key(kptr, &fbp->streams[DIR_DECRYPT-1], fs);
- cast_fb64_stream_key(key->data, &fbp->streams[DIR_ENCRYPT-1], fs);
- }
-
- /* Stuff leftovers into the feed */
- if(key->length >= 2 * klen + sizeof(Block))
- memcpy(fbp->temp_feed, key->data + 2 * klen, sizeof(Block));
- else {
-#ifdef COMMENT
- /* This is a better way of erasing the password */
- /* but we do not want to link in libsrp */
- t_random(fbp->temp_feed, sizeof(Block));
-#else
- memset(fbp->temp_feed, 0, sizeof(Block));
-#endif
- }
-
- fbp->key_isset = 1;
- /*
- * Now look to see if cast_fb64_start() was was waiting for
- * the key to show up. If so, go ahead an call it now
- * that we have the key.
- */
- if (fbp->need_start) {
- fbp->need_start = 0;
- cast_fb64_start(fbp, DIR_ENCRYPT, server);
- }
- return(0);
-}
-
-/*
- * We only accept a keyid of 0. If we get a keyid of
- * 0, then mark the state as SUCCESS.
- */
-#ifndef CAST_EXPORT_ENCRYPTION
-int
-cast_cfb64_keyid(dir, kp, lenp)
- int dir, *lenp;
- unsigned char *kp;
-{
- return(cast_fb64_keyid(dir, kp, lenp, &cast_fb[CFB_128]));
-}
-
-int
-cast_ofb64_keyid(dir, kp, lenp)
- int dir, *lenp;
- unsigned char *kp;
-{
- return(cast_fb64_keyid(dir, kp, lenp, &cast_fb[OFB_128]));
-}
-#endif
-
-int
-castexp_cfb64_keyid(dir, kp, lenp)
- int dir, *lenp;
- unsigned char *kp;
-{
- return(cast_fb64_keyid(dir, kp, lenp, &cast_fb[CFB_40]));
-}
-
-int
-castexp_ofb64_keyid(dir, kp, lenp)
- int dir, *lenp;
- unsigned char *kp;
-{
- return(cast_fb64_keyid(dir, kp, lenp, &cast_fb[OFB_40]));
-}
-
-static int
-cast_fb64_keyid(dir, kp, lenp, fbp)
- int dir, *lenp;
- unsigned char *kp;
- struct cast_fb *fbp;
-{
- register int state = fbp->state[dir-1];
-
- if (*lenp != 1 || (*kp != '\0')) {
- *lenp = 0;
- return(state);
- }
-
- if (state == cFAILED)
- state = IN_PROGRESS;
-
- state &= ~NO_KEYID;
-
- return(fbp->state[dir-1] = state);
-}
-
-static void
-cast_fb64_printsub(data, cnt, buf, buflen, type)
- unsigned char *data, *buf, *type;
- int cnt, buflen;
-{
- char lbuf[64];
- register int i;
- char *cp;
-
- buf[buflen-1] = '\0'; /* make sure it's NULL terminated */
- buflen -= 1;
-
- switch(data[2]) {
- case FB64_IV:
- sprintf(lbuf, "%s_IV", type);
- cp = lbuf;
- goto common;
-
- case FB64_IV_OK:
- sprintf(lbuf, "%s_IV_OK", type);
- cp = lbuf;
- goto common;
-
- case FB64_IV_BAD:
- sprintf(lbuf, "%s_IV_BAD", type);
- cp = lbuf;
- goto common;
-
- default:
- sprintf(lbuf, " %d (unknown)", data[2]);
- cp = lbuf;
- common:
- for (; (buflen > 0) && (*buf = *cp++); buf++)
- buflen--;
- for (i = 3; i < cnt; i++) {
- sprintf(lbuf, " %d", data[i]);
- for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++)
- buflen--;
- }
- break;
- }
-}
-
-void
-cast_cfb64_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt, buflen;
-{
- cast_fb64_printsub(data, cnt, buf, buflen, "CFB64");
-}
-
-void
-cast_ofb64_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt, buflen;
-{
- cast_fb64_printsub(data, cnt, buf, buflen, "OFB64");
-}
-
-static void
-cast_fb64_stream_iv(seed, stp)
- Block seed;
- register struct cast_stinfo *stp;
-{
- memcpy((void *)stp->str_iv, (void *)seed, sizeof(Block));
- memcpy((void *)stp->str_output, (void *)seed, sizeof(Block));
-
- stp->str_index = sizeof(Block);
-}
-
-static void
-cast_fb64_stream_key(key, stp, fs)
- unsigned char * key;
- register struct cast_stinfo *stp;
- int fs;
-{
-#ifndef CAST_EXPORT_ENCRYPTION
- if(fs)
- ck_cast128_key_sched(&stp->str_sched, key);
- else
-#endif
- ck_cast5_40_key_sched(&stp->str_sched, key);
-
- memcpy((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block));
-
- stp->str_index = sizeof(Block);
-}
-
-/*
- * CAST 64 bit Cipher Feedback
- *
- * key --->+------+
- * +->| CAST |--+
- * | +------+ |
- * | v
- * INPUT --(---------->(+)+---> DATA
- * | |
- * +--------------+
- *
- *
- * Given:
- * iV: Initial vector, 64 bits (8 bytes) long.
- * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
- * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
- *
- * V0 = CAST(iV, key)
- * On = Dn ^ Vn
- * V(n+1) = CAST(On, key)
- */
-#ifndef CAST_EXPORT_ENCRYPTION
-void
-cast_cfb64_encrypt(s, c)
- register unsigned char *s;
- int c;
-{
- _cast_cfb64_encrypt(s, c, &cast_fb[CFB_128].streams[DIR_ENCRYPT-1]);
-}
-#endif
-
-void
-castexp_cfb64_encrypt(s, c)
- register unsigned char *s;
- int c;
-{
- _cast_cfb64_encrypt(s, c, &cast_fb[CFB_40].streams[DIR_ENCRYPT-1]);
-}
-
-static void
-_cast_cfb64_encrypt(s, c, stp)
- register unsigned char *s;
- int c;
- register struct cast_stinfo *stp;
-{
- register int index;
-
- index = stp->str_index;
- while (c-- > 0) {
- if (index == sizeof(Block)) {
- Block b;
- ck_cast_ecb_encrypt(b, stp->str_output, &stp->str_sched, 0);
- memcpy((void *)stp->str_feed, (void *)b, sizeof(Block));
- index = 0;
- }
-
- /* On encryption, we store (feed ^ data) which is cypher */
- *s = stp->str_output[index] = (stp->str_feed[index] ^ *s);
- s++;
- index++;
- }
- stp->str_index = index;
-}
-
-#ifndef CAST_EXPORT_ENCRYPTION
-int
-cast_cfb64_decrypt(data)
- int data;
-{
- return _cast_cfb64_decrypt(data, &cast_fb[CFB_128].streams[DIR_DECRYPT-1]);
-}
-#endif
-
-int
-castexp_cfb64_decrypt(data)
- int data;
-{
- return _cast_cfb64_decrypt(data, &cast_fb[CFB_40].streams[DIR_DECRYPT-1]);
-}
-
-static int
-_cast_cfb64_decrypt(data, stp)
- int data;
- register struct cast_stinfo *stp;
-{
- int index;
-
- if (data == -1) {
- /*
- * Back up one byte. It is assumed that we will
- * never back up more than one byte. If we do, this
- * may or may not work.
- */
- if (stp->str_index)
- --stp->str_index;
- return(0);
- }
-
- index = stp->str_index++;
- if (index == sizeof(Block)) {
- Block b;
- ck_cast_ecb_encrypt(b, stp->str_output, &stp->str_sched, 0);
- memcpy((void *)stp->str_feed, (void *)b, sizeof(Block));
- stp->str_index = 1; /* Next time will be 1 */
- index = 0; /* But now use 0 */
- }
-
- /* On decryption we store (data) which is cypher. */
- stp->str_output[index] = data;
- return(data ^ stp->str_feed[index]);
-}
-
-/*
- * CAST 64 bit Output Feedback
- *
- * key --->+------+
- * +->| CAST |--+
- * | +------+ |
- * +------------+
- * v
- * INPUT --------->(+) ----> DATA
- *
- * Given:
- * iV: Initial vector, 64 bits (8 bytes) long.
- * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
- * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
- *
- * V0 = CAST(iV, key)
- * V(n+1) = CAST(Vn, key)
- * On = Dn ^ Vn
- */
-#ifndef CAST_EXPORT_ENCRYPTION
-void
-cast_ofb64_encrypt(s, c)
- register unsigned char *s;
- int c;
-{
- _cast_ofb64_encrypt(s, c, &cast_fb[OFB_128].streams[DIR_ENCRYPT-1]);
-}
-#endif
-
-void
-castexp_ofb64_encrypt(s, c)
- register unsigned char *s;
- int c;
-{
- _cast_ofb64_encrypt(s, c, &cast_fb[OFB_40].streams[DIR_ENCRYPT-1]);
-}
-
-static void
-_cast_ofb64_encrypt(s, c, stp)
- register unsigned char *s;
- int c;
- register struct cast_stinfo *stp;
-{
- register int index;
-
- index = stp->str_index;
- while (c-- > 0) {
- if (index == sizeof(Block)) {
- Block b;
- ck_cast_ecb_encrypt(b, stp->str_feed, &stp->str_sched, 0);
- memcpy((void *)stp->str_feed, (void *)b, sizeof(Block));
- index = 0;
- }
- *s++ ^= stp->str_feed[index];
- index++;
- }
- stp->str_index = index;
-}
-
-#ifndef CAST_EXPORT_ENCRYPTION
-int
-cast_ofb64_decrypt(data)
- int data;
-{
- return _cast_ofb64_decrypt(data, &cast_fb[OFB_128].streams[DIR_DECRYPT-1]);
-}
-#endif
-
-int
-castexp_ofb64_decrypt(data)
- int data;
-{
- return _cast_ofb64_decrypt(data, &cast_fb[OFB_40].streams[DIR_DECRYPT-1]);
-}
-
-static int
-_cast_ofb64_decrypt(data, stp)
- int data;
- register struct cast_stinfo *stp;
-{
- int index;
-
- if (data == -1) {
- /*
- * Back up one byte. It is assumed that we will
- * never back up more than one byte. If we do, this
- * may or may not work.
- */
- if (stp->str_index)
- --stp->str_index;
- return(0);
- }
-
- index = stp->str_index++;
- if (index == sizeof(Block)) {
- Block b;
- ck_cast_ecb_encrypt(b, stp->str_feed, &stp->str_sched, 0);
- memcpy((void *)stp->str_feed, (void *)b, sizeof(Block));
- stp->str_index = 1; /* Next time will be 1 */
- index = 0; /* But now use 0 */
- }
-
- return(data ^ stp->str_feed[index]);
-}
-
-/*
- * Copyright (c) 1997 Stanford University
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * cast.c
- * Author: Tom Wu
- *
- * An implementation of the CAST-128 encryption algorithm, as
- * specified in RFC 2144.
- */
-
-/* The first four S-boxes are for encryption/decryption */
-
-static uint32 S1[] = {
- 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3,
- 0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,
- 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, 0x28683b6f, 0xc07fd059,
- 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
- 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b,
- 0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de,
- 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, 0xb82cbaef, 0xd751d159,
- 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
- 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f,
- 0xb48ee411, 0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,
- 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, 0x882240f2, 0x0c6e4f38,
- 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
- 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493,
- 0xe63d37e0, 0x2a54f6b3, 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a,
- 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb,
- 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
- 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14,
- 0xa0bebc3c, 0x54623779, 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6,
- 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, 0x81383f05, 0x6963c5c8,
- 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
- 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495,
- 0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e,
- 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, 0x6b54bfab, 0x2b0b1426,
- 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
- 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98,
- 0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f,
- 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,0x7b5a41f0, 0xd37cfbad,
- 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
- 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464,
- 0x5ad328d8, 0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,
- 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,0x3f04442f, 0x6188b153,
- 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
- 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274,
- 0xdd24cb9e, 0x7e1c54bd, 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755,
- 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,0x580304f0, 0xca042cf1,
- 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
- 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1,
- 0xd5ea50f1, 0x85a92872, 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79,
- 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,0x474d6ad7, 0x7c0c5e5c,
- 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
- 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff,
- 0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d,
- 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
-};
-
-static uint32 S2[] = {
- 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a,
- 0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba,
- 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, 0xa0b52f7b, 0x59e83605,
- 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
- 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b,
- 0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4,
- 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, 0xe113c85b, 0xacc40083,
- 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
- 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f,
- 0x361e3084, 0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d,
- 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094, 0x2537a95e,
- 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
- 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366,
- 0x721d9bfd, 0xa58684bb, 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4,
- 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064,
- 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
- 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6,
- 0x83ca6b94, 0x2d6ed23b, 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709,
- 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364,
- 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
- 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b,
- 0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9,
- 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, 0xee41e729, 0x6e1d2d7c,
- 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
- 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741,
- 0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab,
- 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, 0xcdf0b680, 0x17844d3b,
- 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
- 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa,
- 0xef8579cc, 0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8,
- 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c, 0x80823028,
- 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
- 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6,
- 0x273be979, 0xb0ffeaa6, 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b,
- 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1,
- 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
- 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb,
- 0x145892f5, 0x91584f7f, 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea,
- 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d,
- 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
- 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e,
- 0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef,
- 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
-};
-
-static uint32 S3[] = {
- 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b,
- 0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae,
- 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, 0x11107d9f, 0x07647db9,
- 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
- 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd,
- 0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e,
- 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, 0xa8c01db7, 0x579fc264,
- 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
- 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e,
- 0xc5884a28, 0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f,
- 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0, 0x1651192e,
- 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
- 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790,
- 0x796fb449, 0x8252dc15, 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504,
- 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e,
- 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
- 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8,
- 0x96bbb682, 0x93b4b148, 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d,
- 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240,
- 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
- 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c,
- 0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15,
- 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, 0x68cc7bfb, 0xd90f2788,
- 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
- 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa,
- 0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392,
- 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, 0x285ba1c8, 0x3c62f44f,
- 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
- 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae,
- 0x12deca4d, 0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67,
- 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437, 0xec00c9a9,
- 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
- 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888,
- 0xa2e53f55, 0xb9e6d4bc, 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d,
- 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2,
- 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
- 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2,
- 0xf1ac2571, 0xcc8239c2, 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce,
- 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d,
- 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
- 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00,
- 0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5,
- 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
-};
-
-static uint32 S4[] = {
- 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57,
- 0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120,
- 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, 0x28147f5f, 0x4fa2b8cd,
- 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
- 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe,
- 0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701,
- 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, 0xce84ffdf, 0xf5718801,
- 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
- 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1,
- 0x72500e03, 0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,
- 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805, 0x7f3d5ce3,
- 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
- 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c,
- 0x18f8931e, 0x281658e6, 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c,
- 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16,
- 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
- 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7,
- 0x0ce5c2ec, 0x4db4bba6, 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327,
- 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002,
- 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
- 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7,
- 0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031,
- 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, 0x026a4ceb, 0x52437eff,
- 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
- 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035,
- 0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69,
- 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, 0x63315c21, 0x5e0a72ec,
- 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
- 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e,
- 0xcfcbd12f, 0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3,
- 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532, 0x58fd7eb6,
- 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
- 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f,
- 0xaf9eb3db, 0x29c9ed2a, 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091,
- 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6,
- 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
- 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2,
- 0xf3e0eb5b, 0xd6cc9876, 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367,
- 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda,
- 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
- 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6,
- 0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e,
- 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
-};
-
-/* Encrypt/decrypt one 64-bit block of data */
-
-void
-ck_cast_ecb_encrypt(out, in, sched, mode)
- uint8p out;
- uint8p in;
- CastKeySched * sched;
- int mode; /* zero means encrypt */
-{
- uint32 t[2];
-
-#ifdef LITTLE_ENDIAN
- t[0] = (in[0] << 24) | (in[1] << 16) | (in[2] << 8) | in[3];
- t[1] = (in[4] << 24) | (in[5] << 16) | (in[6] << 8) | in[7];
-#else
- t[0] = *(uint32p) in;
- t[1] = *(uint32p) (in + 4);
-#endif
-
- ck_cast_ecb_crypt(t, sched, mode);
-
-#ifdef LITTLE_ENDIAN
- out[0] = (t[0] >> 24) & 0xff;
- out[1] = (t[0] >> 16) & 0xff;
- out[2] = (t[0] >> 8) & 0xff;
- out[3] = t[0] & 0xff;
- out[4] = (t[1] >> 24) & 0xff;
- out[5] = (t[1] >> 16) & 0xff;
- out[6] = (t[1] >> 8) & 0xff;
- out[7] = t[1] & 0xff;
-#else
- *(uint32p) out = t[0];
- *(uint32p) (out + 4) = t[1];
-#endif
-}
-
-void
-ck_cast_ecb_crypt(data, sched, mode)
- uint32p data;
- CastKeySched * sched;
- int mode;
-{
- register uint32 L, R, temp;
- register struct CastSubkeyPair * kp;
- register uint8p Ia, Ib, Ic, Id;
- uint32 I;
-
-#ifdef LITTLE_ENDIAN
- Id = (uint8p) &I;
- Ic = Id + 1;
- Ib = Ic + 1;
- Ia = Ib + 1;
-#else
- Ia = (uint8p) &I;
- Ib = Ia + 1;
- Ic = Ib + 1;
- Id = Ic + 1;
-#endif
-
- L = data[0];
- R = data[1];
-
-#define type0(left,right) \
- temp = kp->Km + right;\
- I = (temp << kp->Kr) | (temp >> (32 - kp->Kr));\
- left ^= ((S1[*Ia] ^ S2[*Ib]) - S3[*Ic]) + S4[*Id];
-
-#define type1(left,right) \
- temp = kp->Km ^ right;\
- I = (temp << kp->Kr) | (temp >> (32 - kp->Kr));\
- left ^= ((S1[*Ia] - S2[*Ib]) + S3[*Ic]) ^ S4[*Id];
-
-#define type2(left,right) \
- temp = kp->Km - right;\
- I = (temp << kp->Kr) | (temp >> (32 - kp->Kr));\
- left ^= ((S1[*Ia] + S2[*Ib]) ^ S3[*Ic]) - S4[*Id];
-
- if(mode) {
-#ifndef CAST_EXPORT_ENCRYPTION
- if(sched->ksize > 10) {
- kp = &sched->K[15];
- type0(L, R); --kp;
- type2(R, L); --kp;
- type1(L, R); --kp;
- type0(R, L); --kp;
- }
- else
-#endif
- kp = &sched->K[11];
- type2(L, R); --kp;
- type1(R, L); --kp;
- type0(L, R); --kp;
- type2(R, L); --kp;
- type1(L, R); --kp;
- type0(R, L); --kp;
- type2(L, R); --kp;
- type1(R, L); --kp;
- type0(L, R); --kp;
- type2(R, L); --kp;
- type1(L, R); --kp;
- type0(R, L);
- }
- else {
- kp = &sched->K[0];
- type0(L, R); ++kp;
- type1(R, L); ++kp;
- type2(L, R); ++kp;
- type0(R, L); ++kp;
- type1(L, R); ++kp;
- type2(R, L); ++kp;
- type0(L, R); ++kp;
- type1(R, L); ++kp;
- type2(L, R); ++kp;
- type0(R, L); ++kp;
- type1(L, R); ++kp;
- type2(R, L); ++kp;
-#ifndef CAST_EXPORT_ENCRYPTION
- if(sched->ksize > 10) {
- type0(L, R); ++kp;
- type1(R, L); ++kp;
- type2(L, R); ++kp;
- type0(R, L);
- }
-#endif
- }
-
- data[0] = R;
- data[1] = L;
-}
-
-/* The last four S-boxes are for key schedule setup */
-
-static uint32 S5[] = {
- 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5,
- 0x44dd9d44, 0x1731167f, 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00,
- 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, 0xe6a2e77f, 0xf0c720cd,
- 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
- 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb,
- 0x8dba1cfe, 0x41a99b02, 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725,
- 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, 0xf2f3f763, 0x68af8040,
- 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
- 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2,
- 0x2261be02, 0xd642a0c9, 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec,
- 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, 0x5c1ff900, 0xfe38d399,
- 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
- 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966,
- 0xdfdd55bc, 0x29de0655, 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468,
- 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, 0xbcf3f0aa, 0x87ac36e9,
- 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
- 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616,
- 0xf24766e3, 0x8eca36c1, 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4,
- 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, 0x26e46695, 0xb7566419,
- 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
- 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9,
- 0x68cb3e47, 0x086c010f, 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6,
- 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, 0x0ab378d5, 0xd951fb0c,
- 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
- 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715,
- 0x646c6bd7, 0x44904db3, 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6,
- 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, 0x76f0ae02, 0x083be84d,
- 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
- 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba,
- 0x9cad9010, 0xaf462ba2, 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487,
- 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, 0x445f7382, 0x175683f4,
- 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
- 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c,
- 0x1ad2fff3, 0x8c25404e, 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78,
- 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, 0x44094f85, 0x3f481d87,
- 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
- 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110,
- 0x1b5ad7a8, 0xf61ed5ad, 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58,
- 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, 0x5ce96c28, 0xe176eda3,
- 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
- 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d,
- 0x34010718, 0xbb30cab8, 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55,
- 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
-};
-
-static uint32 S6[] = {
- 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4,
- 0xeced5cbc, 0x325553ac, 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9,
- 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, 0x33f14961, 0xc01937bd,
- 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
- 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f,
- 0xa888614a, 0x2900af98, 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c,
- 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, 0xfd41197e, 0x9305a6b0,
- 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
- 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941,
- 0x2c0e636a, 0xba7dd9cd, 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d,
- 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, 0x284caf89, 0xaa928223,
- 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
- 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6,
- 0x9a69a02f, 0x68818a54, 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a,
- 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, 0x53bddb65, 0xe76ffbe7,
- 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
- 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89,
- 0xfd339fed, 0xb87834bf, 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be,
- 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, 0x4ec75b95, 0x24f2c3c0,
- 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
- 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4,
- 0xe9a9d848, 0xf3160289, 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853,
- 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, 0x36f73523, 0x4cfb6e87,
- 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
- 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585,
- 0xdc049441, 0xc8098f9b, 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751,
- 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, 0xbf32679d, 0xd45b5b75,
- 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
- 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283,
- 0x3cc2acfb, 0x3fc06976, 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459,
- 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, 0x3007cd3e, 0x74719eef,
- 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
- 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0,
- 0xbc60b42a, 0x953498da, 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb,
- 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, 0xe8816f4a, 0x3814f200,
- 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
- 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf,
- 0x3a479c3a, 0x5302da25, 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b,
- 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, 0xb81a928a, 0x60ed5869,
- 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
- 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb,
- 0xb0e93524, 0xbebb8fbd, 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454,
- 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
-};
-
-static uint32 S7[] = {
- 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912,
- 0xde6008a1, 0x2028da1f, 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82,
- 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, 0xa05fbcf6, 0xcd4181e9,
- 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
- 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4,
- 0x1286becf, 0xb6eacb19, 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9,
- 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, 0x107789be, 0xb3b2e9ce,
- 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
- 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7,
- 0xd0d854c0, 0xcb3a6c88, 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e,
- 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, 0x0a961288, 0xe1a5c06e,
- 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
- 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9,
- 0xc6e6fa14, 0xbae8584a, 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b,
- 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, 0x92544a8b, 0x009b4fc3,
- 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
- 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c,
- 0x16746233, 0x3c034c28, 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802,
- 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, 0x0c4fb99a, 0xbb325778,
- 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
- 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be,
- 0xbe8b9d2d, 0x7979fb06, 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858,
- 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, 0xf28ebfb0, 0xf5b9c310,
- 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
- 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476,
- 0x488dcf25, 0x36c9d566, 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df,
- 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, 0xf22b017d, 0xa4173f70,
- 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
- 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a,
- 0x058745b9, 0x3453dc1e, 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07,
- 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, 0x66626c1c, 0x7154c24c,
- 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
- 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e,
- 0xe4f2dfa6, 0x693ed285, 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378,
- 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, 0xc79f022f, 0x3c997e7e,
- 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
- 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301,
- 0xcfd2a87f, 0x60aeb767, 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2,
- 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, 0x97fd61a9, 0xea7759f4,
- 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
- 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021,
- 0xc3c0bdae, 0x4958c24c, 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada,
- 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
-};
-
-static uint32 S8[] = {
- 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b,
- 0x0e241600, 0x052ce8b5, 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174,
- 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, 0xde9adeb1, 0x0a0cc32c,
- 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
- 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7,
- 0x72df191b, 0x7580330d, 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164,
- 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, 0x12a8ddec, 0xfdaa335d,
- 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
- 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8,
- 0x57e8726e, 0x647a78fc, 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6,
- 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, 0xbbd35049, 0x2998df04,
- 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
- 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38,
- 0x424f7618, 0x35856039, 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8,
- 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, 0x7170c608, 0x2d5e3354,
- 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
- 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160,
- 0x7895cda5, 0x859c15a5, 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab,
- 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, 0x835ffcb8, 0x6df4c1f2,
- 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
- 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98,
- 0x7cd16efc, 0x1436876c, 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441,
- 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, 0xa842eedf, 0xfdba60b4,
- 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
- 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5,
- 0xbae7dfdc, 0x42cbda70, 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c,
- 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, 0x77853b53, 0x37effcb5,
- 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
- 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b,
- 0xc4248289, 0xacf3ebc3, 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4,
- 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, 0xe87b40e4, 0xe98ea084,
- 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
- 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a,
- 0xe0779695, 0xf9c17a8f, 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf,
- 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, 0x11403092, 0x00da6d77,
- 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
- 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f,
- 0xdf09822b, 0xbd691a6c, 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819,
- 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, 0x5938fa0f, 0x42399ef3,
- 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
- 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1,
- 0xa466bb1e, 0xf8da0a82, 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d,
- 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
-};
-
-/* Initialize a key schedule from a 128-bit key */
-
-static void
-cast_key_sched(sched, key)
- CastKeySched * sched;
- uint8p key;
-{
- uint8p x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xA, xB, xC, xD, xE, xF;
- uint8p z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, zA, zB, zC, zD, zE, zF;
- uint32 X03, X47, X8B, XCF, Z03, Z47, Z8B, ZCF;
-
-#ifdef LITTLE_ENDIAN
- x3 = (uint8p) &X03; x2 = x3 + 1; x1 = x2 + 1; x0 = x1 + 1;
- x7 = (uint8p) &X47; x6 = x7 + 1; x5 = x6 + 1; x4 = x5 + 1;
- xB = (uint8p) &X8B; xA = xB + 1; x9 = xA + 1; x8 = x9 + 1;
- xF = (uint8p) &XCF; xE = xF + 1; xD = xE + 1; xC = xD + 1;
- z3 = (uint8p) &Z03; z2 = z3 + 1; z1 = z2 + 1; z0 = z1 + 1;
- z7 = (uint8p) &Z47; z6 = z7 + 1; z5 = z6 + 1; z4 = z5 + 1;
- zB = (uint8p) &Z8B; zA = zB + 1; z9 = zA + 1; z8 = z9 + 1;
- zF = (uint8p) &ZCF; zE = zF + 1; zD = zE + 1; zC = zD + 1;
-#else
- x0 = (uint8p) &X03; x1 = x0 + 1; x2 = x1 + 1; x3 = x2 + 1;
- x4 = (uint8p) &X47; x5 = x4 + 1; x6 = x5 + 1; x7 = x6 + 1;
- x8 = (uint8p) &X8B; x9 = x8 + 1; xA = x9 + 1; xB = xA + 1;
- xC = (uint8p) &XCF; xD = xC + 1; xE = xD + 1; xF = xE + 1;
- z0 = (uint8p) &Z03; z1 = z0 + 1; z2 = z1 + 1; z3 = z2 + 1;
- z4 = (uint8p) &Z47; z5 = z4 + 1; z6 = z5 + 1; z7 = z6 + 1;
- z8 = (uint8p) &Z8B; z9 = z8 + 1; zA = z9 + 1; zB = zA + 1;
- zC = (uint8p) &ZCF; zD = zC + 1; zE = zD + 1; zF = zE + 1;
-#endif
-
-#ifdef LITTLE_ENDIAN
- *x0 = key[0];
- *x1 = key[1];
- *x2 = key[2];
- *x3 = key[3];
- *x4 = key[4];
- *x5 = key[5];
- *x6 = key[6];
- *x7 = key[7];
- *x8 = key[8];
- *x9 = key[9];
- *xA = key[10];
- *xB = key[11];
- *xC = key[12];
- *xD = key[13];
- *xE = key[14];
- *xF = key[15];
-#else
- X03 = *(uint32p) key;
- X47 = *(uint32p) (key + 4);
- X8B = *(uint32p) (key + 8);
- XCF = *(uint32p) (key + 12);
-#endif
-
- /* First half of key schedule */
-
- Z03 = X03 ^ S5[*xD] ^ S6[*xF] ^ S7[*xC] ^ S8[*xE] ^ S7[*x8];
- Z47 = X8B ^ S5[*z0] ^ S6[*z2] ^ S7[*z1] ^ S8[*z3] ^ S8[*xA];
- Z8B = XCF ^ S5[*z7] ^ S6[*z6] ^ S7[*z5] ^ S8[*z4] ^ S5[*x9];
- ZCF = X47 ^ S5[*zA] ^ S6[*z9] ^ S7[*zB] ^ S8[*z8] ^ S6[*xB];
-
- sched->K[0].Km = S5[*z8] ^ S6[*z9] ^ S7[*z7] ^ S8[*z6] ^ S5[*z2];
- sched->K[1].Km = S5[*zA] ^ S6[*zB] ^ S7[*z5] ^ S8[*z4] ^ S6[*z6];
- sched->K[2].Km = S5[*zC] ^ S6[*zD] ^ S7[*z3] ^ S8[*z2] ^ S7[*z9];
- sched->K[3].Km = S5[*zE] ^ S6[*zF] ^ S7[*z1] ^ S8[*z0] ^ S8[*zC];
-
- X03 = Z8B ^ S5[*z5] ^ S6[*z7] ^ S7[*z4] ^ S8[*z6] ^ S7[*z0];
- X47 = Z03 ^ S5[*x0] ^ S6[*x2] ^ S7[*x1] ^ S8[*x3] ^ S8[*z2];
- X8B = Z47 ^ S5[*x7] ^ S6[*x6] ^ S7[*x5] ^ S8[*x4] ^ S5[*z1];
- XCF = ZCF ^ S5[*xA] ^ S6[*x9] ^ S7[*xB] ^ S8[*x8] ^ S6[*z3];
-
- sched->K[4].Km = S5[*x3] ^ S6[*x2] ^ S7[*xC] ^ S8[*xD] ^ S5[*x8];
- sched->K[5].Km = S5[*x1] ^ S6[*x0] ^ S7[*xE] ^ S8[*xF] ^ S6[*xD];
- sched->K[6].Km = S5[*x7] ^ S6[*x6] ^ S7[*x8] ^ S8[*x9] ^ S7[*x3];
- sched->K[7].Km = S5[*x5] ^ S6[*x4] ^ S7[*xA] ^ S8[*xB] ^ S8[*x7];
-
- Z03 = X03 ^ S5[*xD] ^ S6[*xF] ^ S7[*xC] ^ S8[*xE] ^ S7[*x8];
- Z47 = X8B ^ S5[*z0] ^ S6[*z2] ^ S7[*z1] ^ S8[*z3] ^ S8[*xA];
- Z8B = XCF ^ S5[*z7] ^ S6[*z6] ^ S7[*z5] ^ S8[*z4] ^ S5[*x9];
- ZCF = X47 ^ S5[*zA] ^ S6[*z9] ^ S7[*zB] ^ S8[*z8] ^ S6[*xB];
-
- sched->K[8].Km = S5[*z3] ^ S6[*z2] ^ S7[*zC] ^ S8[*zD] ^ S5[*z9];
- sched->K[9].Km = S5[*z1] ^ S6[*z0] ^ S7[*zE] ^ S8[*zF] ^ S6[*zC];
- sched->K[10].Km = S5[*z7] ^ S6[*z6] ^ S7[*z8] ^ S8[*z9] ^ S7[*z2];
- sched->K[11].Km = S5[*z5] ^ S6[*z4] ^ S7[*zA] ^ S8[*zB] ^ S8[*z6];
-
- X03 = Z8B ^ S5[*z5] ^ S6[*z7] ^ S7[*z4] ^ S8[*z6] ^ S7[*z0];
- X47 = Z03 ^ S5[*x0] ^ S6[*x2] ^ S7[*x1] ^ S8[*x3] ^ S8[*z2];
- X8B = Z47 ^ S5[*x7] ^ S6[*x6] ^ S7[*x5] ^ S8[*x4] ^ S5[*z1];
- XCF = ZCF ^ S5[*xA] ^ S6[*x9] ^ S7[*xB] ^ S8[*x8] ^ S6[*z3];
-
- sched->K[12].Km = S5[*x8] ^ S6[*x9] ^ S7[*x7] ^ S8[*x6] ^ S5[*x3];
- sched->K[13].Km = S5[*xA] ^ S6[*xB] ^ S7[*x5] ^ S8[*x4] ^ S6[*x7];
- sched->K[14].Km = S5[*xC] ^ S6[*xD] ^ S7[*x3] ^ S8[*x2] ^ S7[*x8];
- sched->K[15].Km = S5[*xE] ^ S6[*xF] ^ S7[*x1] ^ S8[*x0] ^ S8[*xD];
-
- /* Second half of key schedule - just like first half */
-
- Z03 = X03 ^ S5[*xD] ^ S6[*xF] ^ S7[*xC] ^ S8[*xE] ^ S7[*x8];
- Z47 = X8B ^ S5[*z0] ^ S6[*z2] ^ S7[*z1] ^ S8[*z3] ^ S8[*xA];
- Z8B = XCF ^ S5[*z7] ^ S6[*z6] ^ S7[*z5] ^ S8[*z4] ^ S5[*x9];
- ZCF = X47 ^ S5[*zA] ^ S6[*z9] ^ S7[*zB] ^ S8[*z8] ^ S6[*xB];
-
- sched->K[0].Kr = (S5[*z8] ^ S6[*z9] ^ S7[*z7] ^ S8[*z6] ^ S5[*z2]) & 0x1f;
- sched->K[1].Kr = (S5[*zA] ^ S6[*zB] ^ S7[*z5] ^ S8[*z4] ^ S6[*z6]) & 0x1f;
- sched->K[2].Kr = (S5[*zC] ^ S6[*zD] ^ S7[*z3] ^ S8[*z2] ^ S7[*z9]) & 0x1f;
- sched->K[3].Kr = (S5[*zE] ^ S6[*zF] ^ S7[*z1] ^ S8[*z0] ^ S8[*zC]) & 0x1f;
-
- X03 = Z8B ^ S5[*z5] ^ S6[*z7] ^ S7[*z4] ^ S8[*z6] ^ S7[*z0];
- X47 = Z03 ^ S5[*x0] ^ S6[*x2] ^ S7[*x1] ^ S8[*x3] ^ S8[*z2];
- X8B = Z47 ^ S5[*x7] ^ S6[*x6] ^ S7[*x5] ^ S8[*x4] ^ S5[*z1];
- XCF = ZCF ^ S5[*xA] ^ S6[*x9] ^ S7[*xB] ^ S8[*x8] ^ S6[*z3];
-
- sched->K[4].Kr = (S5[*x3] ^ S6[*x2] ^ S7[*xC] ^ S8[*xD] ^ S5[*x8]) & 0x1f;
- sched->K[5].Kr = (S5[*x1] ^ S6[*x0] ^ S7[*xE] ^ S8[*xF] ^ S6[*xD]) & 0x1f;
- sched->K[6].Kr = (S5[*x7] ^ S6[*x6] ^ S7[*x8] ^ S8[*x9] ^ S7[*x3]) & 0x1f;
- sched->K[7].Kr = (S5[*x5] ^ S6[*x4] ^ S7[*xA] ^ S8[*xB] ^ S8[*x7]) & 0x1f;
-
- Z03 = X03 ^ S5[*xD] ^ S6[*xF] ^ S7[*xC] ^ S8[*xE] ^ S7[*x8];
- Z47 = X8B ^ S5[*z0] ^ S6[*z2] ^ S7[*z1] ^ S8[*z3] ^ S8[*xA];
- Z8B = XCF ^ S5[*z7] ^ S6[*z6] ^ S7[*z5] ^ S8[*z4] ^ S5[*x9];
- ZCF = X47 ^ S5[*zA] ^ S6[*z9] ^ S7[*zB] ^ S8[*z8] ^ S6[*xB];
-
- sched->K[8].Kr = (S5[*z3] ^ S6[*z2] ^ S7[*zC] ^ S8[*zD] ^ S5[*z9]) & 0x1f;
- sched->K[9].Kr = (S5[*z1] ^ S6[*z0] ^ S7[*zE] ^ S8[*zF] ^ S6[*zC]) & 0x1f;
- sched->K[10].Kr = (S5[*z7] ^ S6[*z6] ^ S7[*z8] ^ S8[*z9] ^ S7[*z2]) & 0x1f;
- sched->K[11].Kr = (S5[*z5] ^ S6[*z4] ^ S7[*zA] ^ S8[*zB] ^ S8[*z6]) & 0x1f;
-
- X03 = Z8B ^ S5[*z5] ^ S6[*z7] ^ S7[*z4] ^ S8[*z6] ^ S7[*z0];
- X47 = Z03 ^ S5[*x0] ^ S6[*x2] ^ S7[*x1] ^ S8[*x3] ^ S8[*z2];
- X8B = Z47 ^ S5[*x7] ^ S6[*x6] ^ S7[*x5] ^ S8[*x4] ^ S5[*z1];
- XCF = ZCF ^ S5[*xA] ^ S6[*x9] ^ S7[*xB] ^ S8[*x8] ^ S6[*z3];
-
- sched->K[12].Kr = (S5[*x8] ^ S6[*x9] ^ S7[*x7] ^ S8[*x6] ^ S5[*x3]) & 0x1f;
- sched->K[13].Kr = (S5[*xA] ^ S6[*xB] ^ S7[*x5] ^ S8[*x4] ^ S6[*x7]) & 0x1f;
- sched->K[14].Kr = (S5[*xC] ^ S6[*xD] ^ S7[*x3] ^ S8[*x2] ^ S7[*x8]) & 0x1f;
- sched->K[15].Kr = (S5[*xE] ^ S6[*xF] ^ S7[*x1] ^ S8[*x0] ^ S8[*xD]) & 0x1f;
-}
-
-/* Initialize with a full-strength 128-bit key */
-
-#ifndef CAST_EXPORT_ENCRYPTION
-void
-ck_cast128_key_sched(sched, key)
- CastKeySched * sched;
- uint8 * key;
-{
- sched->ksize = 16;
- cast_key_sched(sched, key);
-}
-#endif
-
-/* Handle reduced-keysize variants */
-
-static void
-cast5_key_sched(sched, key, sz)
- CastKeySched * sched;
- uint8 * key;
- int sz;
-{
- uint8 buf[16];
-
- sched->ksize = sz;
- memset(buf, 0, sizeof(buf));
- memcpy(buf, key, sz);
- cast_key_sched(sched, buf);
-}
-
-/* 40, 64, and 80-bit keys - all use 12 rounds */
-
-void
-ck_cast5_40_key_sched(sched, key)
- CastKeySched * sched;
- uint8 * key;
-{
- cast5_key_sched(sched, key, 5);
-}
-
-#ifndef CAST_EXPORT_ENCRYPTION
-void
-ck_cast5_64_key_sched(sched, key)
- CastKeySched * sched;
- uint8 * key;
-{
- cast5_key_sched(sched, key, 8);
-}
-
-void
-ck_cast5_80_key_sched(sched, key)
- CastKeySched * sched;
- uint8 * key;
-{
- cast5_key_sched(sched, key, 10);
-}
-#endif /* CAST_EXPORT_ENCRYPTION */
-#endif /* CK_CAST */
-
-#ifdef CRYPT_DLL
-static char *
-ck_crypt_dll_version()
-{
- return(ckcrpv);
-}
-
-int
-crypt_dll_init( struct _crypt_dll_init * init )
-{
-#ifdef LIBDES
- extern int des_check_key;
- extern void libdes_dll_init(struct _crypt_dll_init *);
- des_check_key = 1;
-#endif /* LIBDES */
-
- if ( init->version >= 1 ) {
- p_ttol = init->p_ttol;
- p_dodebug = init->p_dodebug;
- p_dohexdump = init->p_dohexdump;
- p_tn_debug = init->p_tn_debug;
- p_vscrnprintf = init->p_vscrnprintf;
- if ( init->version == 1 )
- return(1);
- }
- if ( init->version >= 2 ) {
- /* This is a k5_context but we don't want to include krb5.h */
- p_k5_context = (void *) init->p_k5_context;
- if ( init->version == 2 )
- return(1);
- }
- if ( init->version >= 3 ) {
- init->p_install_funcs("encrypt_parse",encrypt_parse);
- init->p_install_funcs("encrypt_init",encrypt_init);
- init->p_install_funcs("encrypt_session_key",encrypt_session_key);
- init->p_install_funcs("encrypt_send_request_start",
- encrypt_send_request_start
- );
- init->p_install_funcs("encrypt_request_start",encrypt_request_start);
- init->p_install_funcs("encrypt_send_request_end",
- encrypt_send_request_end
- );
- init->p_install_funcs("encrypt_request_end",encrypt_request_end);
- init->p_install_funcs("encrypt_send_end",encrypt_send_end);
- init->p_install_funcs("encrypt_send_support",encrypt_send_support);
- init->p_install_funcs("encrypt_is_encrypting",encrypt_is_encrypting);
- init->p_install_funcs("encrypt_is_decrypting",encrypt_is_decrypting);
- init->p_install_funcs("get_crypt_table",get_crypt_table);
- init->p_install_funcs("des_is_weak_key",ck_des_is_weak_key);
- libdes_dll_init(init);
- if (init->version == 3)
- return(1);
- }
- if ( init->version >= 4 ) {
- init->p_install_funcs("crypt_dll_version",ck_crypt_dll_version);
- if (init->version == 4)
- return(1);
- }
-
- if ( init->version >= 5 ) {
- p_reqtelmutex = init->p_reqtelmutex;
- p_reltelmutex = init->p_reltelmutex;
- if (init->version == 5)
- return(1);
- }
-
- if ( init->version >= 6 ) {
- init->p_install_funcs("encrypt_dont_support",encrypt_dont_support);
- if ( init->version == 6 )
- return(1);
- /* when adding new versions; migrate the next two lines */
- init->version = 6;
- return(1);
- }
- return(0);
-}
-
-#undef malloc
-#undef realloc
-#undef free
-#undef strdup
-
-static void
-fatal(char *msg) {
- if (!msg) msg = "";
-
- printf(msg);
- exit(1); /* Exit indicating failure */
-}
-
-void *
-kmalloc(size_t size)
-{
- void *ptr;
-
- if (size == 0) {
- fatal("kmalloc: zero size");
- }
- ptr = malloc(size);
- if (ptr == NULL) {
- fatal("kmalloc: out of memory");
- }
- return ptr;
-}
-
-void *
-krealloc(void *ptr, size_t new_size)
-{
- void *new_ptr;
-
- if (new_size == 0) {
- fatal("krealloc: zero size");
- }
- if (ptr == NULL)
- new_ptr = malloc(new_size);
- else
- new_ptr = realloc(ptr, new_size);
- if (new_ptr == NULL) {
- fatal("krealloc: out of memory");
- }
- return new_ptr;
-}
-
-void
-kfree(void *ptr)
-{
- if (ptr == NULL) {
- printf("kfree: NULL pointer given as argument");
- return;
- }
- free(ptr);
-}
-
-char *
-kstrdup(const char *str)
-{
- size_t len;
- char *cp;
-
- if (str == NULL) {
- fatal("kstrdup: NULL pointer given as argument");
- }
- len = strlen(str) + 1;
- cp = kmalloc(len);
- if (cp)
- memcpy(cp, str, len);
- return cp;
-}
-#endif /* CRYPT_DLL */
-#endif /* CK_ENCRYPTION */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ck_des.c b/ckermit-9.0.302-build/ckermit-9.0.302/ck_des.c
deleted file mode 100644
index c534652..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ck_des.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- C K _ D E S . C - libDES interface for Kermit 95"
-
- Copyright (C) 1998, 2001, Trustees of Columbia University in the City of New
- York. The C-Kermit software may not be, in whole or in part, licensed or
- sold for profit as a software product itself, nor may it be included in or
- distributed with commercial products or otherwise distributed by commercial
- concerns to their clients or customers without written permission of the
- Office of Kermit Development and Distribution, Columbia University. This
- copyright notice must not be removed, altered, or obscured.
-
- Author:
- Jeffrey E Altman (jaltman@secure-endpoints.com)
-*/
-
-/*
- This file contains wrappers so that the following functions will be imported
- into the k95crypt.dll/k2crypt.dll files in such a form that they can be
- re-exported to k95.exe/k2.exe. This subset of the DES library is needed to
- provide DES based Kerberos authentication.
-*/
-
-
-#ifdef LIBDES
-/* The following is specific to my installation, but since I'm the only one */
-/* that uses this file ... */
-#include "ckcdeb.h"
-#include "ckuath.h"
-#define CK_DES_C
-#include "ckuat2.h"
-#ifdef NT
-#ifdef _M_ALPHA
-#include <c:\srp\des\des.h>
-#else
-#include <c:\src\srp\des\des.h>
-#endif
-#else
-#include <c:\srp\des\des.h>
-#endif
-
-int
-libdes_random_key(des_cblock B)
-{
- des_random_key(B);
- return(0);
-}
-
-void
-libdes_random_seed(des_cblock B)
-{
- des_random_seed(B);
-}
-
-void
-libdes_key_sched(des_cblock * B, des_key_schedule S)
-{
- des_key_sched(B,S);
-}
-
-void
-libdes_ecb_encrypt(des_cblock * B1, des_cblock * B2, des_key_schedule S, int n)
-{
- des_ecb_encrypt(B1,B2,S,n);
-}
-
-int
-libdes_string_to_key(char * s, des_cblock * B)
-{
- des_string_to_key(s,B);
- return(0);
-}
-
-void
-libdes_fixup_key_parity(des_cblock * B)
-{
- des_set_odd_parity(B);
-}
-
-void
-libdes_pcbc_encrypt(des_cblock *input, des_cblock *output, long length,
- des_key_schedule schedule, des_cblock *ivec, int enc)
-{
- des_pcbc_encrypt(input,output,length,schedule,ivec,enc);
-}
-
-void
-libdes_dll_init(struct _crypt_dll_init * init)
-{
- init->p_install_funcs("libdes_random_key",libdes_random_key);
- init->p_install_funcs("libdes_random_seed",libdes_random_seed);
- init->p_install_funcs("libdes_key_sched",libdes_key_sched);
- init->p_install_funcs("libdes_ecb_encrypt",libdes_ecb_encrypt);
- init->p_install_funcs("libdes_string_to_key",libdes_string_to_key);
- init->p_install_funcs("libdes_fixup_key_parity",libdes_fixup_key_parity);
- init->p_install_funcs("libdes_pcbc_encrypt",libdes_pcbc_encrypt);
-
-}
-#endif /* LIBDES */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ck_ssl.c b/ckermit-9.0.302-build/ckermit-9.0.302/ck_ssl.c
deleted file mode 100644
index 428fb7c..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ck_ssl.c
+++ /dev/null
@@ -1,4358 +0,0 @@
-char *cksslv = "SSL/TLS support, 9.0.227, 04 Aug 2010";
-/*
- C K _ S S L . C -- OpenSSL Interface for C-Kermit
-
- Copyright (C) 1985, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Author: Jeffrey E Altman (jaltman@secure-endpoints.com)
- Secure Endpoints Inc., New York City
-
- Provides:
-
- . Telnet Auth SSL option compatible with Tim Hudson's hack.
- . Telnet START_TLS option
- . Configuration of certificate and key files
- . Certificate verification and revocation list checks
- . Client certificate to user id routine
-
- Note: This code is written to be compatible with OpenSSL 0.9.6[abcdefgh]
- and 0.9.7 beta 5 (and, presumably, later).
- It will also compile with version 0.9.5 although that is discouraged
- due to security weaknesses in that release.
-*/
-
-#include "ckcsym.h"
-#include "ckcdeb.h"
-
-#ifdef CK_SSL
-#include "ckcnet.h"
-#include "ckuath.h"
-
-#include <stdlib.h>
-#include <string.h>
-#ifdef UNIX
-#include <netinet/in.h>
-#ifndef FREEBSD4
-#include <arpa/inet.h>
-#endif /* FREEBSD4 */
-#endif /* UNIX */
-
-#ifdef DEC_TCPIP
-#include <time.h>
-#include <inet.h>
-#endif /* DEC_TCPIP */
-
-#ifdef OS2
-extern char exedir[];
-#ifdef NT
-char * GetAppData(int);
-#endif
-#endif /* OS2 */
-
-extern int quiet; /* fdc - Mon Nov 28 11:44:15 2005 */
-
-static int ssl_installed = 1;
-#endif /* CK_SSL */
-int
-ck_ssh_is_installed()
-{
-#ifdef SSHBUILTIN
-#ifdef SSLDLL
-#ifdef NT
- extern HINSTANCE hCRYPTO;
-#else /* NT */
- extern HMODULE hCRYPTO;
-#endif /* NT */
- debug(F111,"ck_ssh_is_installed","hCRYPTO",hCRYPTO);
- return(ssl_installed && (hCRYPTO != NULL));
-#else /* SSLDLL */
- return(ssl_installed);
-#endif /* SSLDLL */
-#else
- return 0;
-#endif
-}
-
-int
-#ifdef CK_ANSIC
-ck_ssleay_is_installed(void)
-#else
-ck_ssleay_is_installed()
-#endif
-{
-#ifdef CK_SSL
-#ifdef SSLDLL
-#ifdef NT
- extern HINSTANCE hSSL, hCRYPTO;
-#else /* NT */
- extern HMODULE hSSL, hCRYPTO;
-#endif /* NT */
- debug(F111,"ck_ssleay_is_installed","hSSL",hSSL);
- debug(F111,"ck_ssleay_is_installed","hCRYPTO",hCRYPTO);
- return(ssl_installed && (hSSL != NULL) && (hCRYPTO != NULL));
-#else /* SSLDLL */
- return(ssl_installed);
-#endif /* SSLDLL */
-#else /* CK_SSL */
- return(0);
-#endif /* CK_SSL */
-}
-
-#ifdef CK_SSL
-#include "ckcker.h"
-#include "ckucmd.h" /* For struct keytab */
-#include "ckctel.h"
-#include "ck_ssl.h"
-#ifdef UNIX
-#include <pwd.h> /* Password file for home directory */
-#endif /* UNIX */
-#ifdef OS2
-#include <process.h>
-#endif /* OS2 */
-#ifdef OS2ONLY
-#include "ckotcp.h"
-#endif /* OS2ONLY */
-
-#ifdef SSLDLL
-int ssl_finished_messages = 0;
-#else /* SSLDLL */
-#ifdef OPENSSL_VERSION_NUMBER
-int ssl_finished_messages = (OPENSSL_VERSION_NUMBER >= 0x0090581fL);
-#else
-!ERROR This module requires OpenSSL 0.9.5a or higher
-#endif /* OPENSSL_VERSION_NUMBER */
-#endif /* SSLDLL */
-
-static int auth_ssl_valid = 0;
-static char *auth_ssl_name = 0; /* this holds the oneline name */
-char ssl_err[SSL_ERR_BFSZ]="";
-
-BIO *bio_err=NULL;
-X509_STORE *crl_store = NULL;
-
-#ifndef NOFTP
-#ifndef SYSFTP
-SSL *ssl_ftp_con = NULL;
-SSL_CTX *ssl_ftp_ctx = NULL;
-SSL *ssl_ftp_data_con = NULL;
-int ssl_ftp_active_flag = 0;
-int ssl_ftp_data_active_flag = 0;
-#endif /* SYSFTP */
-#endif /* NOFTP */
-
-#ifndef NOHTTP
-SSL *tls_http_con = NULL;
-SSL_CTX *tls_http_ctx = NULL;
-int tls_http_active_flag = 0;
-int ssl_http_initialized = 0;
-#endif /* NOHTTP */
-
-SSL_CTX *ssl_ctx = NULL;
-SSL *ssl_con = NULL;
-int ssl_debug_flag = 0;
-int ssl_verbose_flag = 0;
-int ssl_only_flag = 0;
-int ssl_raw_flag = 0;
-int ssl_active_flag = 0;
-int ssl_verify_flag = SSL_VERIFY_PEER;
-int ssl_certsok_flag = 0;
-char *ssl_rsa_cert_file = NULL;
-char *ssl_rsa_cert_chain_file = NULL;
-char *ssl_rsa_key_file = NULL;
-char *ssl_dsa_cert_file = NULL;
-char *ssl_dsa_cert_chain_file = NULL;
-char *ssl_dh_key_file = NULL;
-char *ssl_crl_file = NULL;
-char *ssl_crl_dir = NULL;
-char *ssl_verify_file = NULL;
-char *ssl_verify_dir = NULL;
-char *ssl_dh_param_file = NULL;
-char *ssl_cipher_list = NULL;
-char *ssl_rnd_file = NULL;
-
-SSL_CTX *tls_ctx = NULL;
-SSL *tls_con = NULL;
-int tls_only_flag = 0;
-int tls_raw_flag = 0;
-int tls_active_flag = 0;
-
-int ssl_initialized = 0;
-int ssl_verify_depth = -1; /* used to track depth in verify routines */
-
-/* compile this set to 1 to negotiate SSL/TLS but not actually start it */
-int ssl_dummy_flag=0;
-
-extern int inserver;
-extern int debses;
-extern int accept_complete;
-extern char szHostName[], szUserNameRequested[], szUserNameAuthenticated[];
-
-_PROTOTYP(int X509_to_user,(X509 *, char *, int));
-
-static int verbosity = 0; /* Message control */
-static VOID
-setverbosity() {
- verbosity = ssl_verbose_flag;
- if (quiet) verbosity = 0;
-}
-
-int
-#ifdef CK_ANSIC
-ssl_server_verify_callback(int ok, X509_STORE_CTX * ctx)
-#else /* CK_ANSIC */
-ssl_server_verify_callback(ok, ctx)
-int ok;
-X509_STORE_CTX *ctx;
-#endif /* CK_ANSIC */
-{
- static char *saved_subject=NULL;
- char *subject=NULL, *issuer=NULL;
- int depth,error;
- X509 *xs = NULL;
-
- if ( ssl_certsok_flag )
- return(1);
-
- setverbosity();
-
- error=X509_STORE_CTX_get_error(ctx);
- depth=X509_STORE_CTX_get_error_depth(ctx);
- xs=X509_STORE_CTX_get_current_cert(ctx);
-
- if (depth==0) {
- /* clear things */
- if (saved_subject!=NULL) {
- free(saved_subject);
- saved_subject=NULL;
- }
- if (auth_ssl_name!=NULL) {
- free(auth_ssl_name);
- auth_ssl_name=NULL;
- }
- }
-
-
- if (ssl_debug_flag && !inserver) {
- printf("ssl:server_verify_callback:depth=%d ok=%d err=%d-%s\r\n",
- depth,ok,error,X509_verify_cert_error_string(error));
- }
-
- /* first thing is to have a meaningful name for the current
- * certificate that is being verified ... and if we cannot
- * determine that then something is seriously wrong!
- */
- makestr(&subject,
- (char *)X509_NAME_oneline(X509_get_subject_name(xs),NULL,0));
- makestr(&issuer,
- (char *)X509_NAME_oneline(X509_get_issuer_name(xs),NULL,0));
- if (!subject || !subject[0] || !issuer || !issuer[0]) {
- ok = 0;
- goto return_time;
- }
-
- if (verbosity && !inserver && depth != ssl_verify_depth) {
- printf("[%d] Certificate Subject:\r\n%s\r\n",depth,subject);
- printf("[%d] Certificate Issuer:\r\n%s\r\n",depth,issuer);
- ssl_verify_depth = depth;
- }
-
- /* make sure that the certificate that has been presented */
- /* has not been revoked (if we have been given a CRL. */
- ok = ssl_verify_crl(ok, ctx);
-
- /* if we have any form of error in secure mode we reject the connection */
- if (error!=X509_V_OK) {
- if (inserver) {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- cksyslog(SYSLG_LI, 0,
- "X.509 Certificate verify failure",
- (char *) subject,
- (char *)X509_verify_cert_error_string(error)
- );
- }
-#endif /* CKSYSLOG */
-
- } else {
- if ( ssl_verify_flag &
- (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
- printf("Error: ");
- else
- printf("Warning: ");
- switch (error) {
- case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- printf("Certificate is self signed.\r\n");
- break;
- case X509_V_ERR_CERT_HAS_EXPIRED:
- printf("Certificate has expired.\r\n");
- break;
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
- printf(
- "Certificate issuer's certificate isn't available locally.\r\n");
- break;
- case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
- printf("Unable to verify leaf signature.\r\n");
- break;
- case X509_V_ERR_CERT_REVOKED:
- printf("Certificate revoked.\r\n");
- break;
- default:
- printf("Error %d while verifying certificate.\r\n",
- ctx->error);
- break;
- }
- }
- ok = !(ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
- } else {
- /* if we got all the way to the top of the tree then
- * we *can* use this certificate for a username to
- * match ... in all other cases we must not!
- */
- auth_ssl_name = saved_subject;
- saved_subject = NULL;
- }
-
- return_time:
-
- /* save the name if at least the first level is okay */
- if (depth == 0 && ok)
- makestr(&saved_subject,subject);
-
- /* clean up things */
- if (subject!=NULL)
- free(subject);
- if (issuer!=NULL)
- free(issuer);
-
- return ok;
-}
-
-int
-#ifdef CK_ANSIC
-ssl_client_verify_callback(int ok, X509_STORE_CTX * ctx)
-#else
-ssl_client_verify_callback(ok, ctx)
-int ok;
-X509_STORE_CTX *ctx;
-#endif
-{
- char subject[256]="", issuer[256]="";
- int depth, error, len;
- X509 *xs;
-
- setverbosity();
-
- xs=X509_STORE_CTX_get_current_cert(ctx);
- error=X509_STORE_CTX_get_error(ctx);
- depth=X509_STORE_CTX_get_error_depth(ctx);
-
- if ( ssl_debug_flag )
- printf("ssl:client_verify_callback:depth=%d ok=%d err=%d-%s\r\n",
- depth,ok,error,X509_verify_cert_error_string(error));
-
- if ( ssl_certsok_flag ) {
- ok = 1;
- }
-
- /* first thing is to have a meaningful name for the current
- * certificate that is being verified ... and if we cannot
- * determine that then something is seriously wrong!
- */
-#ifdef XN_FLAG_SEP_MULTILINE
- X509_NAME_print_ex(bio_err,X509_get_subject_name(xs),4,
- XN_FLAG_SEP_MULTILINE);
- len = BIO_read(bio_err,subject,256);
- subject[len < 256 ? len : 255] = '\0';
- if (!subject[0]) {
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- uq_ok("X.509 Subject Name unavailable", ssl_err, 1, NULL, 0);
- ok=0;
- goto return_time;
- }
-
- X509_NAME_print_ex(bio_err,X509_get_issuer_name(xs),4,
- XN_FLAG_SEP_MULTILINE);
- len = BIO_read(bio_err,issuer,256);
- issuer[len < 256 ? len : 255] = '\0';
- if (!issuer[0]) {
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- uq_ok("X.509 Issuer Name unavailable", ssl_err, 1, NULL, 0);
- ok=0;
- goto return_time;
- }
-#else /* XN_FLAG_SEP_MULTILINE */
- X509_NAME_oneline(X509_get_subject_name(xs),subject,256);
- if (!subject[0]) {
- int len;
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- uq_ok("X.509 Subject Name unavailable", ssl_err, 1, NULL, 0);
- ok=0;
- goto return_time;
- }
-
- X509_NAME_oneline(X509_get_issuer_name(xs),issuer,256);
- if (!issuer[0]) {
- int len;
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- uq_ok("X.509 Issuer Name unavailable", ssl_err, 1, NULL, 0);
- ok=0;
- goto return_time;
- }
-#endif /* XN_FLAG_SEP_MULTILINE */
-
- if (verbosity && depth != ssl_verify_depth) {
- printf("[%d] Certificate Subject:\r\n%s\r\n",depth,subject);
- printf("[%d] Certificate Issuer:\r\n%s\r\n",depth,issuer);
- ssl_verify_depth = depth;
- }
-
- ok = ssl_verify_crl(ok, ctx);
-
- if ( !ok ) {
- char prefix[1024];
- /* if the server is using a self signed certificate then
- * we need to decide if that is good enough for us to
- * accept ...
- */
-
- switch ( error ) {
- case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: {
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- /* make 100% sure that in secure more we drop the
- * connection if the server does not have a
- * real certificate!
- */
- ckmakxmsg(prefix,1024,
- "Error: Server has a self-signed certificate\n",
- "[",ckitoa(depth),"] Certificate Subject=\n",subject,
- "\n[",ckitoa(depth),"] Certificate Issuer=\n",issuer,
- NULL,NULL,NULL);
-
- uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
-
- /* sometimes it is really handy to be able to debug things
- * and still get a connection!
- */
- if (ssl_debug_flag) {
- printf("SSL: debug -> ignoring cert required!\r\n");
- ok=1;
- } else {
- ok=0;
- }
- goto return_time;
- } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
- ckmakxmsg(prefix,1024,
- "Warning: Server has a self-signed certificate\n",
- "[",ckitoa(depth),"] Certificate Subject=\n",subject,
- "\n[",ckitoa(depth),"] Certificate Issuer=\n",issuer,
- NULL,NULL,NULL);
-
- ok = uq_ok(prefix,
- "Continue? (Y/N) ",
- 3, NULL, 0);
- if ( ok < 0 )
- ok = 0;
- goto return_time;
- }
- }
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- /* make 100% sure that in secure more we drop the
- * connection if the server does not have a
- * real certificate!
- */
- ckmakxmsg(prefix,1024,
- "Error: ",
- (char *)X509_verify_cert_error_string(error),
- "\nCertificate Issuer=\n",issuer,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
-
- /* sometimes it is really handy to be able to debug things
- * and still get a connection!
- */
- if (ssl_debug_flag) {
- printf("SSL: debug -> ignoring cert required!\r\n");
- ok=1;
- } else {
- ok=0;
- }
- goto return_time;
- } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
- ckmakxmsg(prefix,1024,
- "Warning: ",
- (char *)X509_verify_cert_error_string(error),
- "\nCertificate Issuer=\n",issuer,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
- goto return_time;
- }
- break;
- case X509_V_ERR_CERT_NOT_YET_VALID:
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- int len;
- /* make 100% sure that in secure more we drop the
- * connection if the server does not have a
- * real certificate!
- */
- ASN1_TIME_print(bio_err,X509_get_notBefore(xs));
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- ckmakxmsg(prefix,1024,
- "Error: ",
- (char *)X509_verify_cert_error_string(error),
- "\nCertificate Subject=\n",subject,
- "\nnotBefore=",ssl_err,
- NULL,NULL,NULL,NULL,NULL,NULL);
- uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
- /* sometimes it is really handy to be able to debug things
- * and still get a connection!
- */
- if (ssl_debug_flag) {
- printf("SSL: debug -> ignoring cert required!\r\n");
- ok=1;
- } else {
- ok=0;
- }
- goto return_time;
- } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
- int len;
- ASN1_TIME_print(bio_err,X509_get_notBefore(xs));
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- ckmakxmsg(prefix,1024,
- "Warning: ",
- (char *)X509_verify_cert_error_string(error),
- "\nCertificate Subject=\n",subject,
- "\n notBefore=",ssl_err,
- NULL,NULL,NULL,NULL,NULL,NULL);
- ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
- }
- break;
- case X509_V_ERR_CERT_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- int len;
- /* make 100% sure that in secure more we drop the
- * connection if the server does not have a
- * real certificate!
- */
- ASN1_TIME_print(bio_err,X509_get_notAfter(xs));
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
-
- ckmakxmsg(prefix,1024,
- "Error: ",
- (char *)X509_verify_cert_error_string(error),
- "\nCertificate Subject=\n",subject,
- "\n notAfter=",ssl_err,
- NULL,NULL,NULL,NULL,NULL,NULL);
- uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
-
- /* sometimes it is really handy to be able to debug things
- * and still get a connection!
- */
- if (ssl_debug_flag) {
- printf("SSL: debug -> ignoring cert required!\r\n");
- ok=1;
- } else {
- ok=0;
- }
- goto return_time;
- } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
- int len;
- ASN1_TIME_print(bio_err,X509_get_notAfter(xs));
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- ckmakxmsg(prefix,1024,
- "Warning: ",
- (char *)X509_verify_cert_error_string(error),
- "\nCertificate Subject=\n",subject,
- "\n notAfter=",ssl_err,
- NULL,NULL,NULL,NULL,NULL,NULL);
- ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
- }
- break;
- case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
- /*
- * When an SSL server sends its certificates to the client there
- * are two" conventions": one is to send the complete certificate
- * chain and the other is to send the whole chain apart from the
- * root.
- *
- * You don't usually need the root because the root is normally
- * stored and trusted locally.
- *
- * So if you get the whole chain it will complain about the self
- * signed certificate whereas if the root is missing it says it
- * can't find the issuer certificate.
- */
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- /* make 100% sure that in secure more we drop the
- * connection if the server does not have a
- * real certificate!
- */
- ckmakxmsg(prefix,1024,
- "Error: ",
- (char *)X509_verify_cert_error_string(error),
- "\nCertificate Issuer=\n",issuer,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
- /* sometimes it is really handy to be able to debug things
- * and still get a connection!
- */
- if (ssl_debug_flag) {
- printf("SSL: debug -> ignoring cert required!\r\n");
- ok=1;
- } else {
- ok=0;
- }
- goto return_time;
- } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
- ckmakxmsg(prefix,1024,
- "Warning: ",
- (char *)X509_verify_cert_error_string(error),
- "\nCertificate Issuer=\n",issuer,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
-#ifdef NT
- if (ok) {
- /* if the user decides to accept the certificate
- * offer to store it for future connections in
- * the user's private store
- */
- ok = uq_ok(
- "Do you wish to store the certificate to verify future connections?",
- "Continue (Y/N)", 3, NULL, 0);
- if (ok)
- ck_X509_save_cert_to_user_store(xs);
- }
-#endif /* NT */
- }
- break;
- case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
- case X509_V_ERR_UNABLE_TO_GET_CRL:
- case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
- case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
- case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
- case X509_V_ERR_CERT_SIGNATURE_FAILURE:
- case X509_V_ERR_CRL_SIGNATURE_FAILURE:
- case X509_V_ERR_CRL_NOT_YET_VALID:
- case X509_V_ERR_CRL_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
- case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
- case X509_V_ERR_OUT_OF_MEM:
- case X509_V_ERR_CERT_CHAIN_TOO_LONG:
- case X509_V_ERR_CERT_REVOKED:
- case X509_V_ERR_APPLICATION_VERIFICATION:
- default:
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- /* make 100% sure that in secure mode we drop the
- * connection if the server does not have a
- * real certificate!
- */
- ckmakxmsg(prefix,1024,
- "Error: ",
- (char *)X509_verify_cert_error_string(error),
- "\nCertificate Subject=\n",subject,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
-
- /* sometimes it is really handy to be able to debug things
- * and still get a connection!
- */
- if (ssl_debug_flag) {
- printf("SSL: debug -> ignoring cert required!\r\n");
- ok=1;
- } else {
- ok=0;
- }
- goto return_time;
- } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
- ckmakxmsg(prefix,1024,
- "Warning: ",
- (char *)X509_verify_cert_error_string(error),
- "\nCertificate Subject=\n",subject,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
- }
- break;
- }
- }
-
- return_time:
- if ( ssl_debug_flag )
- printf("ssl:client_verify_callback => ok: %d\r\n",ok);
- return ok;
-}
-
-VOID
-#ifdef CK_ANSIC
-ssl_client_info_callback(const SSL *s, int where, int ret)
-#else
-ssl_client_info_callback(s,where,ret)
-const SSL *s;
-int where;
-int ret;
-#endif /* CK_ANSIC */
-{
- if (inserver || !ssl_debug_flag)
- return;
-
- setverbosity();
-
- switch ( where ) {
- case SSL_CB_CONNECT_LOOP:
- printf("SSL_connect:%s %s\r\n",
- SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
- break;
- case SSL_CB_CONNECT_EXIT:
- if (ret == 0) {
- printf("SSL_connect:failed in %s %s\r\n",
- SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
- } else if (ret < 0) {
- printf("SSL_connect:error in %s %s\r\n",
- SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
- }
- break;
- case SSL_CB_ACCEPT_LOOP:
- printf("SSL_accept:%s %s\r\n",
- SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
- break;
- case SSL_CB_ACCEPT_EXIT:
- if (ret == 0) {
- printf("SSL_accept:failed in %s %s\r\n",
- SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
- } else if (ret < 0) {
- printf("SSL_accept:error in %s %s\r\n",
- SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
- }
- break;
- case SSL_CB_READ_ALERT:
- printf("SSL_read_alert\r\n");
- break;
- case SSL_CB_WRITE_ALERT:
- printf("SSL_write_alert\r\n");
- break;
- case SSL_CB_HANDSHAKE_START:
- printf("SSL_handshake:%s %s\r\n",
- SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
- break;
- case SSL_CB_HANDSHAKE_DONE:
- printf("SSL_handshake:%s %s\r\n",
- SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
- break;
- }
-}
-
-#ifdef USE_CERT_CB
-/* Return 1, client cert is available */
-/* Return 0, no client cert is available */
-/* Return -1, callback must be called again. SSL_want_x509_lookup() == 1 */
-int
-#ifdef CK_ANSIC
-ssl_client_cert_callback(SSL * s, X509 ** x509, EVP_PKEY ** pkey)
-#else /* CK_ANSIC */
-ssl_client_cert_callback(s, x509, pkey)
- SSL * s;
- X509 ** x509;
- EVP_PKEY ** pkey;
-#endif /* CK_ANSIC */
-{
- setverbosity();
-
- if ( ssl_debug_flag ) {
- const char * cipher_list=SSL_get_cipher(s);
- printf("ssl_client_cert_callback called (%s)\r\n",
- cipher_list?cipher_list:"UNKNOWN");
- }
-#ifdef COMMENT
- if ( s == tls_con ) {
- if (tls_load_certs(tls_cts,tls_con,0)) {
- *x509 = SSL_get_certificate(s);
- *pkey = SSL_get_privatekey(s);
- return(1);
- }
- } else if ( s == ssl_con ) {
- if (tls_load_certs(ssl_ctx,ssl_con,0)) {
- *x509 = SSL_get_certificate(s);
- *pkey = SSL_get_privatekey(s);
- return(1);
- }
- }
- return(0);
-#else /* COMMENT */
- return(0);
-#endif /* COMMENT */
-}
-#endif /* USE_CERT_CB */
-
-#ifndef MS_CALLBACK
-#define MS_CALLBACK
-#endif /* MS_CALLBACK */
-
-static RSA MS_CALLBACK *
-#ifdef CK_ANSIC
-tmp_rsa_cb(SSL * s, int export, int keylength)
-#else /* CK_ANSIC */
-tmp_rsa_cb(s,export,keylength)
-SSL *s;
-int export;
-int keylength;
-#endif /* CK_ANSIC */
-{
- static RSA *rsa_tmp=NULL;
-
-#ifndef NO_RSA
- if (rsa_tmp == NULL)
- {
- if (ssl_debug_flag)
- printf("Generating temporary (%d bit) RSA key...\r\n",keylength);
-
- rsa_tmp=RSA_generate_key(keylength,RSA_F4,NULL,NULL);
-
- if (ssl_debug_flag)
- printf("\r\n");
- }
-#else /* NO_RSA */
- if (ssl_debug_flag)
- printf("Unable to generate temporary RSA key...\r\n");
-#endif
- return(rsa_tmp);
-}
-
-
-#ifndef NO_DH
-static unsigned char dh512_p[]={
- 0xE9,0x4E,0x3A,0x64,0xFA,0x65,0x5F,0xA6,0x44,0xC7,0xFC,0xF1,
- 0x16,0x8B,0x11,0x11,0x7A,0xF0,0xB2,0x49,0x80,0x56,0xA3,0xF8,
- 0x0F,0x7D,0x01,0x68,0x5D,0xF6,0x8A,0xEA,0x8C,0xDD,0x01,0xDC,
- 0x43,0x18,0xE0,0xC4,0x89,0x80,0xE6,0x2D,0x44,0x77,0x45,0xFD,
- 0xBA,0xFC,0x43,0x35,0x12,0xC0,0xED,0x32,0xD3,0x16,0xEF,0x51,
- 0x09,0x44,0xA2,0xDB,
-};
-static unsigned char dh512_g[]={
- 0x05,
-};
-
-static unsigned char dh768_p[]={
- 0x8B,0x2A,0x8C,0x6C,0x0F,0x87,0xC7,0x34,0xEE,0x2E,0xFB,0x60,
- 0x94,0xB3,0xBF,0x95,0xBA,0x84,0x74,0x86,0xEA,0xE0,0xA4,0x33,
- 0xE0,0x8F,0x7C,0x79,0x5C,0x62,0xE2,0x91,0xC5,0x6D,0x68,0xB9,
- 0x6C,0x5E,0x4E,0x94,0x0C,0x8E,0x56,0x8E,0xEB,0x98,0x7C,0x6E,
- 0x0E,0xF2,0xD5,0xAA,0x22,0x27,0x3F,0x0F,0xAF,0x10,0xB5,0x0B,
- 0x16,0xCC,0x05,0x27,0xBB,0x58,0x6D,0x61,0x4B,0x2B,0xAB,0xDC,
- 0x6A,0x15,0xBC,0x36,0x75,0x4D,0xEC,0xAB,0xFA,0xB6,0xE1,0xB1,
- 0x13,0x70,0xD8,0x77,0xCD,0x5E,0x51,0x77,0x81,0x0D,0x77,0x43,
-};
-static unsigned char dh768_g[]={
- 0x05,
-};
-
-static unsigned char dh1024_p[]={
- 0xA4,0x75,0xCF,0x35,0x00,0xAF,0x3C,0x17,0xCE,0xB0,0xD0,0x52,
- 0x43,0xA0,0x0E,0xFA,0xA2,0xC9,0xBE,0x0B,0x76,0x7A,0xD9,0x2E,
- 0xF4,0x97,0xAC,0x02,0x24,0x69,0xF6,0x36,0x4F,0xAB,0xCC,0x43,
- 0xC1,0x74,0xFF,0xA3,0xD4,0x04,0x0F,0x11,0x2B,0x6D,0x8C,0x47,
- 0xC9,0xCF,0x40,0x93,0x9B,0x7D,0x1E,0x52,0x85,0xB2,0x17,0x55,
- 0x9C,0xF2,0x41,0x02,0x2A,0x9D,0x5F,0x24,0x22,0xC6,0x04,0xC4,
- 0xAB,0x92,0x6D,0xC7,0xC8,0xF3,0x41,0x58,0x6C,0x86,0xFD,0xB8,
- 0x0F,0x2D,0xDD,0xBF,0xA8,0x40,0x0C,0x58,0xC8,0xF2,0x3F,0x18,
- 0xEF,0xF1,0x93,0x3E,0xBA,0x16,0x41,0xBE,0x32,0x6C,0xC5,0x63,
- 0xFF,0x8A,0x02,0x3D,0xAC,0xD5,0x5A,0x49,0x64,0x34,0x14,0x2E,
- 0xFB,0x2E,0xE7,0x39,0x1A,0x0F,0x3C,0x33,
-};
-static unsigned char dh1024_g[]={
- 0x05,
-};
-
-static unsigned char dh1536_p[]={
- 0xA3,0x2B,0x75,0x0E,0x7B,0x31,0x82,0xCA,0xF2,0xFC,0xF3,0x3D,
- 0xCE,0x5F,0xCD,0x5B,0x95,0xF6,0x2F,0xA4,0x5D,0x08,0x26,0xD2,
- 0x5F,0xC0,0x3F,0xC5,0xD8,0xA2,0xFE,0x83,0x26,0xBC,0xEB,0x7D,
- 0xF0,0x4E,0xD2,0xA6,0xBB,0x3C,0x88,0x63,0xCE,0x98,0xDE,0x08,
- 0xE2,0xE1,0xAF,0xE2,0x38,0xA8,0xFA,0x68,0x76,0x8D,0xBF,0xDF,
- 0xBB,0x30,0x15,0xFE,0xBD,0x22,0xCC,0x03,0x4E,0x5E,0x33,0xA3,
- 0x6D,0xD6,0x68,0x12,0x97,0x17,0x4B,0xB5,0x84,0x5F,0x5F,0xA3,
- 0x5C,0x2F,0xA4,0x10,0xC1,0xAD,0xBF,0xAC,0x30,0xCA,0x47,0x64,
- 0x63,0xFE,0xEE,0xEE,0xA1,0x64,0x73,0x70,0xAA,0xF9,0xFE,0xC6,
- 0xAD,0x5E,0xF6,0xF3,0x9C,0xDF,0x34,0x53,0x34,0x72,0xA6,0xA4,
- 0xBB,0x81,0x5A,0x43,0x41,0xFD,0x41,0x05,0x5B,0x77,0x7B,0x84,
- 0x03,0xFA,0x8A,0xFA,0xF7,0x8E,0x0F,0xCB,0x51,0xA2,0xB8,0x45,
- 0xFF,0x59,0x42,0xEF,0xCF,0xF6,0x25,0x37,0xE2,0x6D,0xFF,0x69,
- 0x11,0xF5,0x77,0x59,0x79,0x1C,0x5F,0x05,0xFC,0x7A,0x65,0x81,
- 0x03,0x4A,0x78,0xC6,0xE9,0x48,0x73,0xF6,0x10,0xBC,0x99,0x1C,
- 0xEE,0x44,0x2F,0x8B,0x70,0xCA,0xA8,0xB6,0x02,0x83,0x3E,0x0B,
-};
-static unsigned char dh1536_g[]={
- 0x05,
-};
-
-static unsigned char dh2048_p[]={
- 0xFA,0x4E,0xE4,0x3B,0xFA,0xC1,0x87,0xDD,0xE7,0xC6,0x8B,0xE6,
- 0x13,0x85,0xBC,0x9B,0x2B,0x8B,0x5B,0x46,0xBB,0x8B,0x86,0x6D,
- 0xD7,0xB6,0xD5,0x49,0xC5,0x54,0xF2,0x3E,0xD2,0x39,0x64,0x9B,
- 0x0E,0x33,0x39,0x8F,0xFA,0xFA,0xD9,0x78,0xED,0x34,0x82,0x29,
- 0x37,0x58,0x4D,0x5D,0x40,0xCB,0x69,0xE3,0x8A,0x9F,0x17,0x0C,
- 0x01,0x23,0x6B,0x05,0x01,0xAF,0x33,0xDE,0xDF,0x1A,0xBB,0x7B,
- 0x6A,0x9F,0xD8,0xED,0x8D,0x5E,0x44,0x19,0x5B,0xE0,0xB6,0x23,
- 0xF9,0x7A,0x96,0x6E,0x94,0x33,0x31,0x49,0xBA,0x84,0xD5,0x12,
- 0xD7,0x6D,0xDC,0x35,0x54,0x64,0xA3,0xD8,0x04,0x26,0xC5,0xAF,
- 0x7F,0xE3,0xFE,0x6F,0xBE,0xD5,0x17,0x72,0x4B,0xA6,0xD0,0xA7,
- 0x5F,0x18,0xF5,0xF0,0x2D,0x11,0x9A,0xF6,0xD5,0x3B,0x6C,0x61,
- 0x3C,0x6F,0x8E,0x09,0x4F,0x2C,0xE1,0x26,0x06,0x51,0xB3,0x19,
- 0x85,0x85,0x13,0xF9,0xC2,0x6E,0x80,0x28,0x9E,0x8A,0xA0,0x01,
- 0x46,0xD1,0x85,0x44,0x8C,0xE6,0xEE,0x7E,0x1E,0x17,0x3D,0xBA,
- 0x54,0xFF,0xE8,0x0E,0xDD,0x51,0xF3,0x74,0x7F,0x0D,0x0B,0xAB,
- 0xCA,0x84,0x8D,0x24,0x5D,0x56,0xD4,0x47,0x02,0xFC,0x93,0x9F,
- 0xAE,0x9B,0x5C,0xDB,0x63,0xEB,0x65,0x01,0x38,0xC2,0x7B,0x30,
- 0x1E,0x17,0x1C,0x75,0xF5,0x16,0x3B,0x4F,0x5F,0x41,0x32,0xB5,
- 0xFF,0x9E,0x61,0xFD,0xD2,0x62,0x6E,0xFD,0x8A,0x28,0x93,0x59,
- 0x2D,0x70,0x14,0x4D,0xE1,0x86,0xD5,0x90,0xB4,0xDF,0x72,0x71,
- 0xE0,0xB4,0xD0,0xD6,0x82,0x3A,0x4A,0x04,0x58,0x32,0x0B,0xD3,
- 0x51,0x13,0x32,0x63,
-};
-static unsigned char dh2048_g[]={
- 0x02,
-};
-
-static DH *
-get_dh512()
-{
- DH *dh=NULL;
-
- if ((dh=DH_new()) == NULL)
- return(NULL);
- dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
- dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- return(NULL);
- return(dh);
-}
-
-static DH *
-get_dh768()
-{
- DH *dh=NULL;
-
- if ((dh=DH_new()) == NULL)
- return(NULL);
- dh->p=BN_bin2bn(dh768_p,sizeof(dh768_p),NULL);
- dh->g=BN_bin2bn(dh768_g,sizeof(dh768_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- return(NULL);
- return(dh);
-}
-
-static DH *
-get_dh1024()
-{
- DH *dh=NULL;
-
- if ((dh=DH_new()) == NULL)
- return(NULL);
- dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
- dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- return(NULL);
- return(dh);
-}
-
-static DH *
-get_dh1536()
-{
- DH *dh=NULL;
-
- if ((dh=DH_new()) == NULL)
- return(NULL);
- dh->p=BN_bin2bn(dh1536_p,sizeof(dh1536_p),NULL);
- dh->g=BN_bin2bn(dh1536_g,sizeof(dh1536_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- return(NULL);
- return(dh);
-}
-
-static DH *
-get_dh2048()
-{
- DH *dh=NULL;
-
- if ((dh=DH_new()) == NULL)
- return(NULL);
- dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
- dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- return(NULL);
- return(dh);
-}
-#endif /* NO_DH */
-
-static DH MS_CALLBACK *
-#ifdef CK_ANSIC
-tmp_dh_cb(SSL * s, int export, int keylength)
-#else /* CK_ANSIC */
-tmp_dh_cb(s,export,keylength)
-SSL *s;
-int export;
-int keylength;
-#endif /* CK_ANSIC */
-{
- static DH *dh_tmp=NULL;
- BIO *bio=NULL;
-
-#ifndef NO_DH
- if (dh_tmp == NULL)
- {
- if (ssl_dh_param_file &&
- (bio=BIO_new_file(ssl_dh_param_file,"r")) != NULL)
- dh_tmp=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
- if (bio != NULL)
- BIO_free(bio);
-
- if ( dh_tmp == NULL ) {
- if ( keylength < 768 )
- dh_tmp = get_dh512();
- else if ( keylength < 1024 )
- dh_tmp = get_dh768();
- else if ( keylength < 1536 )
- dh_tmp = get_dh1024();
- else if ( keylength < 2048 )
- dh_tmp = get_dh1536();
- else
- dh_tmp = get_dh2048();
- }
- }
-#else /* NO_DH */
- if (ssl_debug_flag)
- printf("DH not supported...\r\n");
-#endif /* NO_DH */
- return(dh_tmp);
-}
-
-static void
-ssl_display_comp(SSL * ssl)
-{
- if ( quiet ) /* fdc - Mon Nov 28 11:44:15 2005 */
- return;
-
- if ( !ck_ssleay_is_installed() )
- return;
-
- if (ssl == NULL)
- return;
-
- if (ssl->expand == NULL || ssl->expand->meth == NULL)
- printf("Compression: None\r\n");
- else {
- printf("Compression: %s\r\n",ssl->expand->meth->name);
- }
-}
-
-int
-#ifdef CK_ANSIC
-ssl_display_connect_details(SSL * ssl_con, int server, int verbose)
-#else /* CK_ANSIC */
-ssl_display_connect_details(ssl_con,server,verbose)
-SSL *ssl_con;
-int server;
-int verbose;
-#endif /* CK_ANSIC */
-{
- X509 *peer;
- SSL_CIPHER * cipher;
- const char *cipher_list;
- char buf[512]="";
-
- if ( quiet ) /* fdc - Mon Nov 28 11:44:15 2005 */
- return(0);
-
- if ( !ck_ssleay_is_installed() )
- return(0);
-
- if ( inserver && !tn_deb )
- return(0);
-
- /* the cipher list *can* be NULL ... useless but it happens! */
- cipher = SSL_get_current_cipher(ssl_con);
- cipher_list = SSL_CIPHER_get_name(cipher);
- SSL_CIPHER_description(cipher,buf,sizeof(buf));
- if (cipher_list==NULL)
- cipher_list="<NULL>";
- printf("[TLS - %s",buf);
- ssl_display_comp(ssl_con);
-
- if ( server ) {
- cipher_list=SSL_get_shared_ciphers(ssl_con,buf,512);
- if (cipher_list==NULL)
- cipher_list="<NULL>";
- printf("[TLS - shared ciphers=%s]\r\n",
- cipher_list);
- }
- if ( server || tn_deb ) {
- peer=SSL_get_peer_certificate(ssl_con);
- if (peer != NULL) {
- X509_NAME_oneline(X509_get_subject_name(peer),buf,512);
- printf("[TLS - subject=%s]\r\n",buf);
- X509_NAME_oneline(X509_get_issuer_name(peer),buf,512);
- printf("[TLS - issuer=%s]\r\n",buf);
- /* X509_free(peer); */
- } else if (!tls_is_krb5(0)) {
- if ( !sstelnet && !tcp_incoming ) {
- printf("[TLS - No certificate provided.]\r\n");
- printf(
- "[TLS - The identity of the host could not be verified.]\r\n");
- }
- }
- }
- return(0);
-}
-
-/*
- * Use SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *, void * userdata)
- * to set the value of the userdata. We are going to use it to store the
- * prompt.
- */
-
-int
-#ifdef CK_ANSIC
-ssl_passwd_callback(char *buf, int len, int rwflag, VOID * userdata)
-#else /* CK_ANSIC */
-ssl_passwd_callback(buf,len,rwflag,userdata)
- char * buf; int len; int rwflag; VOID *userdata;
-#endif /* CK_ANSIC */
-{
- extern char pwbuf[];
- extern int pwflg, pwcrypt;
- int ok;
- char *prompt=NULL;
-
- if ( pwbuf[0] && pwflg ) {
- int n;
- n = ckstrncpy(buf,pwbuf,len);
-#ifdef OS2
- if ( pwcrypt )
- ck_encrypt((char *)buf);
-#endif /* OS2 */
- return(n);
- }
-
- if ( userdata == NULL )
- prompt="Enter certificate passphrase: ";
- else
- prompt=(char*)userdata;
- ok = uq_txt(NULL,prompt,2,NULL,buf,len,NULL,DEFAULT_UQ_TIMEOUT);
- return(ok > 0 ? strlen(buf) : 0);
-}
-
-
-/* Attempts to load certificate data into the TLS context structures */
-/* Returns 1 on success; 0 on failure */
-int
-tls_load_certs(SSL_CTX * ctx, SSL * con, int server)
-{
- int rc = 1;
-
- if ( !ck_ssleay_is_installed() )
- return(0);
-
- debug(F110,"tls_load_certs","SSL_CTX",0);
- debug(F110,"tls_load_certs","SSL",0);
- debug(F110,"tls_load_certs","server",0);
-
- if ( con ) {
- if (ssl_rsa_cert_file) {
- if ( ssl_debug_flag )
- printf("Loading RSA certificate into SSL\r\n");
-
- rc = SSL_use_certificate_file(con, ssl_rsa_cert_file,
- X509_FILETYPE_PEM);
- if (!rc)
- {
- if ( !quiet || ssl_debug_flag )
- printf("Error loading certificate from %s\r\n",
- ssl_rsa_cert_file);
- } else {
- if (!ssl_rsa_key_file || !ssl_rsa_key_file[0])
- makestr(&ssl_rsa_key_file,ssl_rsa_cert_file);
-
- rc = SSL_use_PrivateKey_file(con, ssl_rsa_key_file,
- X509_FILETYPE_PEM);
- if (!rc)
- rc = SSL_use_PrivateKey_file(con, ssl_rsa_cert_file,
- X509_FILETYPE_PEM);
- if (!rc)
- {
- if ( !quiet || ssl_debug_flag )
- printf("Error loading key from %s\r\n",
- ssl_rsa_key_file);
- } else {
- rc = SSL_check_private_key(con);
- if (!rc)
- {
- if ( ssl_debug_flag )
- printf(
- "Private key does not match the certificate public key\r\n");
- }
- }
- }
- }
-
- if (ssl_dsa_cert_file) {
- if ( ssl_debug_flag )
- printf("Loading DSA certificate into SSL\r\n");
-
- rc = SSL_use_certificate_file(con, ssl_dsa_cert_file,
- X509_FILETYPE_PEM);
- if (!rc)
- {
- if ( ssl_debug_flag ) {
- printf("Error loading certificate from %s\r\n",
- ssl_dsa_cert_file);
- }
- } else {
- if (!ssl_dh_key_file || !ssl_dh_key_file[0])
- makestr(&ssl_dh_key_file,ssl_dsa_cert_file);
- rc = SSL_use_PrivateKey_file(con, ssl_dh_key_file,
- X509_FILETYPE_PEM);
- if (!rc)
- rc = SSL_use_PrivateKey_file(con, ssl_dsa_cert_file,
- X509_FILETYPE_PEM);
- if (!rc)
- {
- if ( !quiet || ssl_debug_flag ) {
- printf("Error loading key from %s\r\n",
- ssl_dh_key_file);
- }
- } else {
- rc = SSL_check_private_key(con);
- if (!rc)
- {
- if ( ssl_debug_flag )
- printf(
- "Private key does not match the certificate public key\n");
- }
- }
- }
- }
- } else {
- if (ssl_rsa_cert_file) {
- if ( ssl_debug_flag )
- printf("Loading RSA certificate into SSL\r\n");
-
- rc = SSL_CTX_use_certificate_file(ctx, ssl_rsa_cert_file,
- X509_FILETYPE_PEM);
- if (!rc)
- {
- if ( !quiet || ssl_debug_flag )
- printf("Error loading certificate from %s\r\n",
- ssl_rsa_cert_file);
- } else {
- if (!ssl_rsa_key_file || !ssl_rsa_key_file[0])
- makestr(&ssl_rsa_key_file,ssl_rsa_cert_file);
-
- rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_rsa_key_file,
- X509_FILETYPE_PEM);
- if (!rc)
- rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_rsa_cert_file,
- X509_FILETYPE_PEM);
- if (!rc) {
- if ( ssl_debug_flag )
- printf("Error loading key from %s\r\n",ssl_rsa_key_file);
- } else {
- rc = SSL_CTX_check_private_key(ctx);
- if (!rc) {
- if ( ssl_debug_flag )
- printf(
- "Private key does not match the certificate public key\r\n");
- }
- }
- }
- }
- if (ssl_dsa_cert_file) {
- if ( ssl_debug_flag )
- printf("Loading DSA certificate into SSL\r\n");
-
- rc = SSL_CTX_use_certificate_file(ctx, ssl_dsa_cert_file,
- X509_FILETYPE_PEM);
- if (!rc) {
- if ( ssl_debug_flag ) {
- printf("Error loading certificate from %s\r\n",
- ssl_dsa_cert_file);
- }
- } else {
- if (!ssl_dh_key_file || !ssl_dh_key_file[0])
- makestr(&ssl_dh_key_file,ssl_dsa_cert_file);
- rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_dh_key_file,
- X509_FILETYPE_PEM);
- if (!rc)
- rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_dsa_cert_file,
- X509_FILETYPE_PEM);
- if (!rc) {
- if ( ssl_debug_flag )
- printf("Error loading key from %s\r\n",ssl_dh_key_file);
- } else {
- rc = SSL_CTX_check_private_key(ctx);
- if (!rc) {
- if ( ssl_debug_flag )
- printf(
- "Private key does not match the certificate public key\n");
- }
- }
- }
- }
- }
-
- if (ssl_rsa_cert_chain_file && server) {
- int skip1st = 0;
- if (ssl_debug_flag)
- printf("Loading RSA Certificate Chain into SSL\r\n");
- if (!ckstrcmp(ssl_rsa_cert_chain_file,ssl_rsa_cert_file,-1,
-#ifdef OS2
- 0
-#else
- 1
-#endif /* OS2 */
- ))
- skip1st = 1;
- rc = SSL_CTX_use_certificate_chain_file(ctx,ssl_rsa_cert_chain_file);
- if (!rc && ssl_debug_flag)
- printf("Error loading RSA Certificate Chain into SSL\r\n");
- }
- if (ssl_dsa_cert_chain_file && server) {
- int skip1st = 0;
- if (ssl_debug_flag)
- printf("Loading DSA Certificate Chain into SSL\r\n");
- if (!ckstrcmp(ssl_dsa_cert_chain_file,ssl_dsa_cert_file,-1,
-#ifdef OS2
- 0
-#else
- 1
-#endif /* OS2 */
- ))
- skip1st = 1;
- rc = SSL_CTX_use_certificate_chain_file(ctx,ssl_dsa_cert_chain_file);
- if (!rc && ssl_debug_flag)
- printf("Error loading DSA Certificate Chain into SSL\r\n");
- }
- return(rc);
-}
-
-VOID
-#ifdef CK_ANSIC
-ssl_once_init(void)
-#else
-ssl_once_init()
-#endif /* CK_ANSIC */
-{
- COMP_METHOD * cm;
- char * s;
-
- if ( !ck_ssleay_is_installed() )
- return;
-/*
- OpenSSL does not provide for ABI compatibility between releases prior
- to version 1.0.0. If the version does not match, it is not safe to
- assume that any function you call takes the same parameters or does
- the same thing with them. Removing this test prior to the OpenSSL 1.0.0
- release will result in an increase in unexplained or incorrect behaviors.
- The test should be revised once OpenSSL 1.0.0 is released and we see what
- its claims are as to ABI compatibility.
-*/
- debug(F111,"Kermit built for OpenSSL",OPENSSL_VERSION_TEXT,SSLEAY_VERSION_NUMBER);
-#ifndef OS2ONLY
- debug(F111,"OpenSSL Library",SSLeay_version(SSLEAY_VERSION),
- SSLeay());
- debug(F110,"OpenSSL Library",SSLeay_version(SSLEAY_BUILT_ON),0);
- debug(F110,"OpenSSL Library",SSLeay_version(SSLEAY_CFLAGS),0);
- debug(F110,"OpenSSL Library",SSLeay_version(SSLEAY_PLATFORM),0);
-
- /* The following test is suggested by Richard Levitte */
- if (((OPENSSL_VERSION_NUMBER ^ SSLeay()) & 0xffffff0f)
-#ifdef OS2
- || ckstrcmp(OPENSSL_VERSION_TEXT,(char *)SSLeay_version(SSLEAY_VERSION),-1,1)
-#endif /* OS2 */
- ) {
- ssl_installed = 0;
- debug(F111,"OpenSSL Version does not match. Built with",
- SSLeay_version(SSLEAY_VERSION),SSLEAY_VERSION_NUMBER);
- printf("?OpenSSL libraries do not match required version:\r\n");
- printf(" . C-Kermit built with %s\r\n",OPENSSL_VERSION_TEXT);
- printf(" . Version found %s\r\n",SSLeay_version(SSLEAY_VERSION));
- printf(" OpenSSL versions prior to 1.0.0 must be the same.\r\n");
-
- s = "R";
-#ifdef SOLARIS
- printf(" Set CD_LIBRARY_PATH for %s.\r\n",OPENSSL_VERSION_TEXT);
- s = " Or r";
-#endif /* SOLARIS */
-
-#ifdef HPUX
- printf(" Set SHLIB_PATH for %s.\r\n",OPENSSL_VERSION_TEXT);
- s = " Or r";
-#endif /* HPUX */
-
-#ifdef AIX
- printf(" Set LIBPATH for %s.\r\n",OPENSSL_VERSION_TEXT);
- s = " Or r";
-#endif /* AIX */
-
-#ifdef LINUX
- printf(" Set LD_LIBRARY_PATH for %s.\r\n",OPENSSL_VERSION_TEXT);
- s = " Or r";
-#endif /* LINUX */
-
- printf(" %sebuild C-Kermit from source on this computer to make \
-versions agree.\r\n",s);
-
-#ifdef KTARGET
- {
- char * s;
- s = KTARGET;
- if (!s) s = "";
- if (!*s) s = "(unknown)";
- printf(" C-Kermit makefile target: %s\r\n",s);
- }
-#endif /* KTARGET */
- printf(" Or if that is what you did then try to find out why\r\n");
- printf(" the program loader (image activator) is choosing a\r\n");
- printf(" different OpenSSL library than the one specified in \
-the build.\r\n\r\n");
- printf(" All SSL/TLS features disabled.\r\n\r\n");
- bleep(BP_FAIL);
-#ifdef SSLDLL
- ck_ssl_unloaddll();
- ck_crypto_unloaddll();
-#endif /* SSLDLL */
- return;
- }
-#endif /* OS2ONLY */
-
- /* init things so we will get meaningful error messages
- * rather than numbers
- */
- SSL_load_error_strings();
-
-#ifdef SSHBUILTIN
- OPENSSL_add_all_algorithms_noconf();
-#else
- /* SSL_library_init() only loads those ciphers needs for SSL */
- /* These happen to be a similar set to those required for SSH */
- /* but they are not a complete set of ciphers provided by the */
- /* crypto library. */
- SSL_library_init();
-#endif /* SSHBUILTIN */
-
-#ifdef ZLIB
- cm = COMP_zlib();
- if (cm != NULL && cm->type != NID_undef) {
- SSL_COMP_add_compression_method(0xe0, cm); /* EAY's ZLIB ID */
- }
-#endif /* ZLIB */
- cm = COMP_rle();
- if (cm != NULL && cm->type != NID_undef)
- SSL_COMP_add_compression_method(0xe1, cm); /* EAY's RLE ID */
-
- /* Ensure the Random number generator has enough entropy */
- if ( !RAND_status() ) {
- char buffer[256]="";
- char randombytes[256];
- int rc1 = -1, rc2 = 1; /* assume failure and success */
-
- debug(F110,"ssl_once_init","!RAND_status()",0);
-
- if ( ssl_rnd_file == NULL ) {
- debug(F110,"ssl_rnd_file","ssl_rnd_file is NULL",0);
- RAND_file_name(buffer,256);
- if ( buffer[0] )
- makestr(&ssl_rnd_file, buffer);
- else
- makestr(&ssl_rnd_file,".rnd");
- }
- debug(F110,"ssl_rnd_file",ssl_rnd_file,0);
-
- rc1 = RAND_egd(ssl_rnd_file);
- debug(F111,"ssl_once_init","RAND_egd()",rc1);
- if ( rc1 <= 0 ) {
- rc2 = RAND_load_file(ssl_rnd_file, -1);
- debug(F111,"ssl_once_init","RAND_load_file()",rc1);
- }
-
- if ( rc1 <= 0 && !rc2 )
- {
- time_t t = time(NULL);
- int tlen = sizeof(time_t);
- int pid = getpid();
- int plen = sizeof(int);
- int n;
-#ifndef RAND_MAX
-#define RAND_MAX 0x7FFF
-#endif
- debug(F110,"ssl_once_init","calling RAND_seed()",0);
-
- RAND_seed((unsigned char *)&t, tlen);
- RAND_seed((unsigned char *)&pid, plen);
-
- srand((unsigned int)t);
- sprintf(buffer, "%.0f", (((double)(rand()%RAND_MAX)/RAND_MAX)*
- (sizeof(randombytes)-128-1)));
- n = (atoi(buffer)+1)%(sizeof(randombytes)-128-1);
- RAND_seed(randombytes, 128);
- }
-
- if ( !RAND_status() ) {
- debug(F110,"ssl_once_init","Unable to initialize PRNG",0);
- printf(" Unable to load 'random state'\n");
- printf(" SSL and TLS are unavailble.\n");
- printf(" Use SET AUTH SSL RANDOM-FILE <file> command to provide random data.\n");
- printf(" Specified file will be overwritten with new random data after use.\n");
- return;
- }
-
- if ( ssl_rnd_file ) {
- int rc = RAND_write_file(ssl_rnd_file);
- debug(F111,"ssl_once_init","RAND_write_file()",rc);
- }
- }
-
-#ifdef NT
- // Initialize additional OID types for use when saving certs to a file
- OBJ_create("2.99999.3","SET.ex3","SET x509v3 extension 3");
-#endif /* NT */
-
- /* make sure we have somewhere we can log errors to */
- bio_err=BIO_new(BIO_s_mem());
-
- debug(F100,"ssl_once_init() complete","",0);
-}
-
-int
-#ifdef CK_ANSIC
-ssl_tn_init(int mode)
-#else
-ssl_tn_init(mode) int mode;
-#endif /* CK_ANSIC */
-{
-#ifdef KRB5
- extern char * k5_keytab;
- extern char * krb5_d_srv;
-#endif /* KRB5 */
- static int last_ssl_mode = -1;
- SSL * ssl_conx=NULL, * tls_conx=NULL;
-
- ssl_initialized = 0;
-
- if ( !ck_ssleay_is_installed() )
- return(0);
-
- debug(F111,"ssl_tn_init","mode",mode);
-
- if (ssl_debug_flag)
- printf("SSL_DEBUG_FLAG on\r\n");
-
- if (last_ssl_mode != mode) {
- if (ssl_ctx) {
- SSL_CTX_free(ssl_ctx);
- ssl_ctx = NULL;
- }
- if (tls_ctx) {
- SSL_CTX_free(tls_ctx);
- tls_ctx = NULL;
- }
- }
-
- if ( (last_ssl_mode != mode) || !ssl_ctx || !tls_ctx ) {
- if ( mode == SSL_CLIENT ) {
- ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
- /* This can fail because we do not have RSA available */
- if ( !ssl_ctx ) {
- debug(F110,"ssl_tn_init","SSLv23_client_method failed",0);
- ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
- }
- if ( !ssl_ctx ) {
- debug(F110,"ssl_tn_init","SSLv3_client_method failed",0);
- last_ssl_mode = -1;
- return(0);
- }
-#ifndef COMMENT
- tls_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_client_method());
-#else /* COMMENT */
- tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
- /* This can fail because we do not have RSA available */
- if ( !tls_ctx ) {
- debug(F110,"ssl_tn_init","SSLv23_client_method failed",0);
- tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
- }
-#endif /* COMMENT */
- if ( !tls_ctx ) {
- debug(F110,"ssl_tn_init","TLSv1_client_method failed",0);
- last_ssl_mode = -1;
- return(0);
- }
-#ifdef USE_CERT_CB
- SSL_CTX_set_client_cert_cb(ssl_ctx,ssl_client_cert_callback);
- SSL_CTX_set_client_cert_cb(tls_ctx,ssl_client_cert_callback);
-#endif /* USE_CERT_CB */
- } else if (mode == SSL_SERVER) {
- /* We are a server */
- ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_server_method());
- /* This can fail because we do not have RSA available */
- if ( !ssl_ctx ) {
- debug(F110,"ssl_tn_init","SSLv23_server_method failed",0);
- ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_server_method());
- }
- if ( !ssl_ctx ) {
- debug(F110,"ssl_tn_init","SSLv3_server_method failed",0);
- last_ssl_mode = -1;
- return(0);
- }
-#ifdef COMMENT
- tls_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_server_method());
-#else /* COMMENT */
- tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_server_method());
- /* This can fail because we do not have RSA available */
- if ( !tls_ctx ) {
- debug(F110,"ssl_tn_init","SSLv23_server_method failed",0);
- tls_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_server_method());
- }
-#endif /* COMMENT */
- if ( !tls_ctx ) {
- debug(F110,"ssl_tn_init","TLSv1_server_method failed",0);
- last_ssl_mode = -1;
- return(0);
- }
- } else /* Unknown mode */
- return(0);
-
- if ( !inserver ) {
- SSL_CTX_set_default_passwd_cb(ssl_ctx,
- (pem_password_cb *)ssl_passwd_callback);
- SSL_CTX_set_default_passwd_cb(tls_ctx,
- (pem_password_cb *)ssl_passwd_callback);
- }
-
- /* for SSL switch on all the interoperability and bug
- * workarounds so that we will communicate with people
- * that cannot read poorly written specs :-)
- * for TLS be sure to prevent use of SSLv2
- */
- SSL_CTX_set_options(ssl_ctx,SSL_OP_ALL|SSL_OP_NO_SSLv2);
- SSL_CTX_set_options(tls_ctx,
- SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA);
-
- SSL_CTX_set_info_callback(ssl_ctx,ssl_client_info_callback);
- SSL_CTX_set_info_callback(tls_ctx,ssl_client_info_callback);
-
-#ifndef COMMENT
- /* Set the proper caching mode */
- if ( mode == SSL_SERVER ) {
- SSL_CTX_set_session_cache_mode(ssl_ctx,SSL_SESS_CACHE_SERVER);
- SSL_CTX_set_session_cache_mode(tls_ctx,SSL_SESS_CACHE_SERVER);
- } else {
- SSL_CTX_set_session_cache_mode(ssl_ctx,SSL_SESS_CACHE_CLIENT);
- SSL_CTX_set_session_cache_mode(tls_ctx,SSL_SESS_CACHE_CLIENT);
- }
- SSL_CTX_set_session_id_context(ssl_ctx,(CHAR *)"1",1);
- SSL_CTX_set_session_id_context(tls_ctx,(CHAR *)"2",1);
-#else /* COMMENT */
- SSL_CTX_set_session_cache_mode(ssl_ctx,SSL_SESS_CACHE_OFF);
- SSL_CTX_set_session_cache_mode(tls_ctx,SSL_SESS_CACHE_OFF);
-#endif /* COMMENT */
- }
-
- /* The server uses defaults for the certificate files. */
- /* The client does not. */
- if (mode == SSL_SERVER) {
- char cert_filepath[1024];
- const char * defdir = NULL;
- DH * dh = NULL;
-
- defdir = getenv("SSL_CERT_DIR");
- if ( !defdir ) {
-#ifdef OS2
- defdir = exedir;
-#else /* OS2 */
- defdir = X509_get_default_cert_dir();
-#endif /* OS2 */
- debug(F110,"ssl_tn_init - setting default directory to",defdir,0);
- }
- if ( !defdir )
- defdir = "";
-
- if (!ssl_rsa_cert_file) {
- /* we need to know the fullpath to the location of the
- * certificate that we will be running with as we cannot
- * be sure of the cwd when we are launched
- */
- sprintf(cert_filepath,"%s/%s",defdir,"telnetd-rsa.pem");
- if (zchki(cert_filepath) > 0)
- makestr(&ssl_rsa_cert_file,cert_filepath);
- }
- if (ssl_rsa_cert_file && !ssl_rsa_key_file) {
- /* we need to know the fullpath to the location of the
- * certificate that we will be running with as we cannot
- * be sure of the cwd when we are launched
- */
- sprintf(cert_filepath,"%s/%s",defdir,"telnetd-rsa-key.pem");
- if (zchki(cert_filepath) > 0)
- makestr(&ssl_rsa_key_file,cert_filepath);
- }
- if (!ssl_dsa_cert_file) {
- /* we need to know the fullpath to the location of the
- * certificate that we will be running with as we cannot
- * be sure of the cwd when we are launched
- */
- sprintf(cert_filepath,"%s/%s",defdir,"telnetd-dsa.pem");
- if (zchki(cert_filepath) > 0)
- makestr(&ssl_dsa_cert_file,cert_filepath);
- }
- if (ssl_dsa_cert_file && !ssl_dh_key_file) {
- /* we need to know the fullpath to the location of the
- * certificate that we will be running with as we cannot
- * be sure of the cwd when we are launched
- */
- sprintf(cert_filepath,"%s/%s",defdir,"telnetd-dsa-key.pem");
- if (zchki(cert_filepath) > 0)
- makestr(&ssl_dh_key_file,cert_filepath);
- }
- if (!ssl_crl_dir) {
- /* we need to know the fullpath to the location of the
- * certificate that we will be running with as we cannot
- * be sure of the cwd when we are launched
- */
- sprintf(cert_filepath,"%s/crl",defdir);
- if (zchki(cert_filepath) > 0)
- makestr(&ssl_crl_dir,cert_filepath);
- }
-
- if (ssl_only_flag && !tls_load_certs(ssl_ctx,ssl_con,1)) {
- debug(F110,"ssl_tn_init","Unable to load SSL certs",0);
- last_ssl_mode = -1;
- return(0);
- }
- if (tls_only_flag && !tls_load_certs(tls_ctx,tls_con,1)) {
- debug(F110,"ssl_tn_init","Unable to load TLS certs",0);
- last_ssl_mode = -1;
- return(0);
- }
-
- if ( (last_ssl_mode != mode) || !ssl_ctx || !tls_ctx ) {
- /* we may require a temp 512 bit RSA key because of the
- * wonderful way export things work ... if so we generate
- * one now!
- */
-
- SSL_CTX_set_tmp_rsa_callback(ssl_ctx, tmp_rsa_cb);
- SSL_CTX_set_tmp_dh_callback( ssl_ctx, tmp_dh_cb);
- SSL_CTX_set_tmp_rsa_callback(tls_ctx, tmp_rsa_cb);
- SSL_CTX_set_tmp_dh_callback( tls_ctx, tmp_dh_cb);
-
- dh = tmp_dh_cb(NULL,0,512);
- SSL_CTX_set_tmp_dh(ssl_ctx,dh);
- SSL_CTX_set_tmp_dh(tls_ctx,dh);
-
- /* The following code is only called if we are using a
- * certificate with an RSA public key and where the
- * certificate has a key length less than 512 bits or is
- * marked for signing only. This is so we can support
- * the greatest legal privacy level with exportable clients.
- */
-
- if (SSL_CTX_need_tmp_RSA(ssl_ctx) ||
- SSL_CTX_need_tmp_RSA(tls_ctx))
- {
- RSA *rsa;
-
- if ( ssl_debug_flag )
- printf("Generating temp (512 bit) RSA key ...\r\n");
- rsa=RSA_generate_key(512,RSA_F4,NULL,NULL);
- if ( ssl_debug_flag )
- printf("Generation of temp (512 bit) RSA key done\r\n");
-
- if (SSL_CTX_need_tmp_RSA(ssl_ctx)) {
- if (!SSL_CTX_set_tmp_rsa(ssl_ctx,rsa)) {
- if ( ssl_debug_flag )
- printf(
- "Failed to assign generated temp RSA key to SSL!\r\n");
- }
- }
- if (SSL_CTX_need_tmp_RSA(tls_ctx)) {
- if (!SSL_CTX_set_tmp_rsa(tls_ctx,rsa)) {
- if ( ssl_debug_flag )
- printf(
- "Failed to assign generated temp RSA key to TLS!\r\n");
- }
- }
- RSA_free(rsa);
- if ( ssl_debug_flag )
- printf("Assigned temp (512 bit) RSA key\r\n");
- }
- }
- }
-
- /* make sure we will find certificates in the standard
- * location ... otherwise we don't look anywhere for
- * these things which is going to make client certificate
- * exchange rather useless :-)
- * In OS2, default values for ssl_verify_file and ssl_verify_path.
- */
-
-#ifdef OS2
-#ifdef NT
- {
- /* The defaults in the SSL crypto library are not appropriate for OS/2 */
- char path[CKMAXPATH];
-
- ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
- if (isdir(path) &&
- SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1) {
- debug(F110,"ssl_tn_init certificate verify dir",path,0);
- if (ssl_debug_flag)
- printf(" Certificate Verification Directory: %s\r\n",path);
- SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
- }
- ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/certs",NULL,NULL);
- if (isdir(path) &&
- SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1) {
- debug(F110,"ssl_tn_init certificate verify dir",path,0);
- if (ssl_debug_flag)
- printf(" Certificate Verification Directory: %s\r\n",path);
- SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
- }
- ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/certs",NULL,NULL);
- if (isdir(path) &&
- SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1) {
- debug(F110,"ssl_tn_init certificate verify dir",path,0);
- if (ssl_debug_flag)
- printf(" Certificate Verification Directory: %s\r\n",path);
- SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
- }
- ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
- if (zchki(path) > 0 &&
- SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
- debug(F110,"ssl_tn_init certificate verify file",path,0);
- if (ssl_debug_flag)
- printf(" Certificate Verification File: %s\r\n",path);
- SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
- }
- ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_certs.pem",NULL,NULL);
- if (zchki(path) > 0 &&
- SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
- debug(F110,"ssl_tn_init certificate verify file",path,0);
- if (ssl_debug_flag)
- printf(" Certificate Verification File: %s\r\n",path);
- SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
- }
- ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_certs.pem",NULL,NULL);
- if (zchki(path) > 0 &&
- SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
- debug(F110,"ssl_tn_init certificate verify file",path,0);
- if (ssl_debug_flag)
- printf(" Certificate Verification File: %s\r\n",path);
- SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
- }
- }
-#else /* NT */
- {
- /* The defaults in the SSL crypto library are not appropriate for OS/2 */
- char path[CKMAXPATH];
-
- ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
- if (isdir(path) &&
- SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1) {
- debug(F110,"ssl_tn_init certificate verify dir",path,0);
- if (ssl_debug_flag)
- printf(" Certificate Verification Directory: %s\r\n",path);
- SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
- }
- ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
- if (zchki(path) > 0 &&
- SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
- debug(F110,"ssl_tn_init certificate verify file",path,0);
- if (ssl_debug_flag)
- printf(" Certificate Verification File: %s\r\n",path);
- SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
- }
- }
-#endif /* NT */
-#else /* OS2 */
- SSL_CTX_set_default_verify_paths(ssl_ctx);
- SSL_CTX_set_default_verify_paths(tls_ctx);
-#endif /* OS2 */
-
- if (ssl_verify_file) {
- if (zchki(ssl_verify_file) > 0 &&
- SSL_CTX_load_verify_locations(tls_ctx,ssl_verify_file,NULL) == 1) {
- debug(F110,"ssl_tn_init certificate verify file",ssl_verify_file,0);
- if (ssl_debug_flag)
- printf(" Certificate Verification File: %s\r\n",ssl_verify_file);
- SSL_CTX_load_verify_locations(ssl_ctx,ssl_verify_file,NULL);
- }
- }
- if (ssl_verify_dir && isdir(ssl_verify_dir)) {
- if (SSL_CTX_load_verify_locations(tls_ctx,NULL,ssl_verify_dir) == 1) {
- debug(F110,"ssl_tn_init certificate verify dir",ssl_verify_dir,0);
- if (ssl_debug_flag)
- printf(" Certificate Verification Directory: %s\r\n",ssl_verify_dir);
- SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssl_verify_dir);
- }
- }
- if (mode == SSL_SERVER) {
- SSL_CTX_set_verify(ssl_ctx,
- ssl_verify_flag?ssl_verify_flag|SSL_VERIFY_CLIENT_ONCE:0,
- ssl_server_verify_callback);
- SSL_CTX_set_verify(tls_ctx,
- ssl_verify_flag?ssl_verify_flag|SSL_VERIFY_CLIENT_ONCE:0,
- ssl_server_verify_callback);
- } else {
- SSL_CTX_set_verify(ssl_ctx,ssl_verify_flag,
- ssl_client_verify_callback);
- SSL_CTX_set_verify(tls_ctx,ssl_verify_flag,
- ssl_client_verify_callback);
- }
-
- /* Free the existing CRL Store */
- if (crl_store) {
- X509_STORE_free(crl_store);
- crl_store = NULL;
- }
-
- /* set up the new CRL Store */
- crl_store = X509_STORE_new();
- if (crl_store) {
-#ifdef OS2
- char path[CKMAXPATH];
-
- ckmakmsg(path,CKMAXPATH,exedir,"crls",NULL,NULL);
- if (isdir(path) &&
- X509_STORE_load_locations(crl_store,NULL,path) == 1) {
- debug(F110,"ssl_tn_init crl dir",path,0);
- if (ssl_debug_flag)
- printf(" CRL Directory: %s\r\n",path);
- }
-#ifdef NT
- ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/crls",NULL,NULL);
- if (isdir(path) &&
- X509_STORE_load_locations(crl_store,NULL,path) == 1) {
- debug(F110,"ssl_tn_init crl dir",path,0);
- if (ssl_debug_flag)
- printf(" CRL Directory: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/crls",NULL,NULL);
- if (isdir(path) &&
- X509_STORE_load_locations(crl_store,NULL,path) == 1) {
- debug(F110,"ssl_tn_init crl dir",path,0);
- if (ssl_debug_flag)
- printf(" CRL Directory: %s\r\n",path);
- }
-#endif /* NT */
-
- ckmakmsg(path,CKMAXPATH,exedir,"ca_crls.pem",NULL,NULL);
- if (zchki(path) > 0 &&
- X509_STORE_load_locations(crl_store,path,NULL) == 1) {
- debug(F110,"ssl_tn_init crl file",path,0);
- if (ssl_debug_flag)
- printf(" CRL File: %s\r\n",path);
- }
-#ifdef NT
- ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_crls.pem",NULL,NULL);
- if (zchki(path) > 0 &&
- X509_STORE_load_locations(crl_store,path,NULL) == 1) {
- debug(F110,"ssl_tn_init crl file",path,0);
- if (ssl_debug_flag)
- printf(" CRL File: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_crls.pem",NULL,NULL);
- if (zchki(path) > 0 &&
- X509_STORE_load_locations(crl_store,path,NULL) == 1) {
- debug(F110,"ssl_tn_init crl file",path,0);
- if (ssl_debug_flag)
- printf(" CRL File: %s\r\n",path);
- }
-#endif /* NT */
-#endif /* OS2 */
-
- if (ssl_crl_file || ssl_crl_dir) {
- if (ssl_crl_file && zchki(ssl_crl_file) > 0 &&
- X509_STORE_load_locations(crl_store,ssl_crl_file,NULL) == 1) {
- debug(F110,"ssl_tn_init crl file",ssl_crl_file,0);
- if (ssl_debug_flag)
- printf(" CRL File: %s\r\n",ssl_crl_file);
- }
- if (ssl_crl_dir && isdir(ssl_crl_dir) &&
- X509_STORE_load_locations(crl_store,NULL,ssl_crl_dir) == 1) {
- debug(F110,"ssl_tn_init crl dir",ssl_crl_dir,0);
- if (ssl_debug_flag)
- printf(" CRL Directory: %s\r\n",ssl_crl_dir);
- }
- }
-#ifndef OS2
- else {
- X509_STORE_set_default_paths(crl_store);
- }
-#endif /* OS2 */
- }
-
-#ifndef COMMENT
- ssl_conx = ssl_con;
- ssl_con=(SSL *)SSL_new(ssl_ctx);
- if ( !ssl_con ) {
- debug(F110,"ssl_tn_init","SSL_new(ssl_con) failed",0);
- last_ssl_mode = -1;
- ssl_con = ssl_conx;
- return(0);
- }
- if (ssl_conx) {
- if ( mode == SSL_CLIENT ) {
- SSL_set_session(ssl_con, SSL_get_session(ssl_conx));
- }
-#ifdef SSL_KRB5
- if (ssl_conx->kssl_ctx) {
- kssl_ctx_free(ssl_conx->kssl_ctx);
- ssl_conx->kssl_ctx = NULL;
- }
-#endif /* SSL_KRB5 */
- SSL_free(ssl_conx);
- ssl_conx = NULL;
- }
- tls_conx = tls_con;
- tls_con=(SSL *)SSL_new(tls_ctx);
- if ( !tls_con ) {
- debug(F110,"ssl_tn_init","SSL_new(tls_con) failed",0);
- last_ssl_mode = -1;
- tls_con = tls_conx;
- return(0);
- }
- if (tls_conx) {
- if ( mode == SSL_CLIENT )
- SSL_set_session(tls_con, SSL_get_session(tls_conx));
-#ifdef SSL_KRB5
- if (tls_conx->kssl_ctx) {
- kssl_ctx_free(tls_conx->kssl_ctx);
- tls_conx->kssl_ctx = NULL;
- }
-#endif /* SSL_KRB5 */
- SSL_free(tls_conx);
- tls_conx = NULL;
- }
-#else /* COMMENT */
- /* I don't know why this does not work to reuse the connection. */
- if ( ssl_con ) {
- SSL_clear(ssl_con);
- SSL_set_session(ssl_con,NULL);
- SSL_set_accept_state(ssl_con) ;
- } else {
- ssl_con=(SSL *)SSL_new(ssl_ctx);
- if (!ssl_con) {
- debug(F110,"ssl_tn_init","SSL_new(ssl_ctx) failed",0);
- last_ssl_mode = -1;
- ssl_con = ssl_conx;
- return(0);
- }
- }
-
- if ( tls_con ) {
- SSL_clear(tls_con);
- SSL_set_session(tls_con,NULL);
- SSL_set_accept_state(tls_con) ;
- } else {
- tls_con=(SSL *)SSL_new(tls_ctx);
- if ( !tls_con ) {
- debug(F110,"ssl_tn_init","SSL_new(tls_ctx) failed",0);
- last_ssl_mode = -1;
- tls_con = tls_conx;
- return(0);
- }
- }
-#endif /* COMMENT */
-
-#ifdef SSL_KRB5
-#ifndef KRB5_SERVICE_NAME
-#define KRB5_SERVICE_NAME "host"
-#endif
-
- if (ssl_con->kssl_ctx == NULL)
- ssl_con->kssl_ctx = kssl_ctx_new();
- if (tls_con->kssl_ctx == NULL)
- tls_con->kssl_ctx = kssl_ctx_new();
- if (mode == SSL_SERVER) {
- if (ssl_con->kssl_ctx != NULL)
- kssl_ctx_setstring(ssl_con->kssl_ctx, KSSL_KEYTAB, k5_keytab);
- if (tls_con->kssl_ctx != NULL)
- kssl_ctx_setstring(tls_con->kssl_ctx, KSSL_KEYTAB, k5_keytab);
- } else {
- if (ssl_con->kssl_ctx != NULL)
- kssl_ctx_setstring(ssl_con->kssl_ctx, KSSL_SERVER, szHostName);
- if (tls_con->kssl_ctx != NULL)
- kssl_ctx_setstring(tls_con->kssl_ctx, KSSL_SERVER, szHostName);
- }
- kssl_ctx_setstring(ssl_con->kssl_ctx, KSSL_SERVICE,
- krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME);
- kssl_ctx_setstring(tls_con->kssl_ctx, KSSL_SERVICE,
- krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME);
-#endif /* SSL_KRB5 */
-
- if (ssl_cipher_list) {
- SSL_set_cipher_list(ssl_con,ssl_cipher_list);
- SSL_set_cipher_list(tls_con,ssl_cipher_list);
- } else {
- char * p;
- if (p = getenv("SSL_CIPHER")) {
- SSL_set_cipher_list(ssl_con,p);
- SSL_set_cipher_list(tls_con,p);
- } else {
- SSL_set_cipher_list(ssl_con,DEFAULT_CIPHER_LIST);
- SSL_set_cipher_list(tls_con,DEFAULT_CIPHER_LIST);
- }
- }
-
- ssl_verify_depth = -1;
-
- if ( ssl_debug_flag )
- printf("SSL/TLS init done!\r\n");
-
- ssl_initialized = 1;
- last_ssl_mode = mode;
- debug(F110,"ssl_tn_init","done",0);
- return(1);
-}
-
-#ifndef NOHTTP
-int
-#ifdef CK_ANSIC
-ssl_http_init(char * hostname)
-#else
-ssl_http_init(hostname) char * hostname;
-#endif /* CK_ANSIC */
-{
-#ifdef KRB5
- extern char * k5_keytab;
- extern char * krb5_d_srv;
-#endif /* KRB5 */
- SSL * tls_conx=NULL;
-
- ssl_http_initialized = 0;
-
- if ( !ck_ssleay_is_installed() )
- return(0);
- debug(F110,"ssl_http_init",hostname,0);
-
- if (ssl_debug_flag)
- printf("SSL_DEBUG_FLAG on\r\n");
-
- if (!tls_http_ctx ) {
-#ifdef COMMENT
- /* too many web servers still do not support TLSv1 */
- tls_http_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_client_method());
-#else /* COMMENT */
- tls_http_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
- /* This can fail because we do not have RSA available */
- if ( !tls_http_ctx ) {
- debug(F110,"ssl_http_init","SSLv23_client_method failed",0);
- tls_http_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
- }
-#endif /* COMMENT */
- if ( !tls_http_ctx ) {
- debug(F110,"ssl_http_init","TLSv1_client_method failed",0);
- return(0);
- }
-#ifdef USE_CERT_CB
- SSL_CTX_set_client_cert_cb(tls_http_ctx,ssl_client_cert_callback);
-#endif /* USE_CERT_CB */
- }
-
- SSL_CTX_set_default_passwd_cb(tls_http_ctx,
- (pem_password_cb *)ssl_passwd_callback);
-
- /* for SSL switch on all the interoperability and bug
- * workarounds so that we will communicate with people
- * that cannot read poorly written specs :-)
- * for TLS be sure to prevent use of SSLv2
- */
- SSL_CTX_set_options(tls_http_ctx,
- SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA);
-
- SSL_CTX_set_info_callback(tls_http_ctx,ssl_client_info_callback);
-
-#ifndef COMMENT
- SSL_CTX_set_session_cache_mode(tls_http_ctx,SSL_SESS_CACHE_CLIENT);
- SSL_CTX_set_session_id_context(tls_http_ctx,(CHAR *)"3",1);
-#else /* COMMENT */
- SSL_CTX_set_session_cache_mode(tls_http_ctx,SSL_SESS_CACHE_OFF);
-#endif /* COMMENT */
-
- /* make sure we will find certificates in the standard
- * location ... otherwise we don't look anywhere for
- * these things which is going to make client certificate
- * exchange rather useless :-)
- */
-
-#ifdef OS2
-#ifdef NT
- {
- /* The defaults in the SSL crypto library are not appropriate for OS/2 */
- char path[CKMAXPATH];
-
- ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0) {
- debug(F110,"ssl_http_init unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0) {
- debug(F110,"ssl_http_init unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0) {
- debug(F110,"ssl_http_init unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
- debug(F110,"ssl_http_init unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
- debug(F110,"ssl_http_init unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
- debug(F110,"ssl_http_init unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
- }
-#else /* NT */
- {
- /* The defaults in the SSL crypto library are not appropriate for OS/2 */
- char path[CKMAXPATH];
-
- ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0) {
- debug(F110,"ssl_http_init unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
- debug(F110,"ssl_http_init unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
- }
-#endif /* NT */
-#else /* OS2 */
- SSL_CTX_set_default_verify_paths(tls_http_ctx);
-#endif /* OS2 */
-
- if (ssl_verify_file &&
- SSL_CTX_load_verify_locations(tls_http_ctx,ssl_verify_file,NULL) == 0) {
- debug(F110,"ssl_http_init unable to load ssl_verify_file",ssl_verify_file,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",ssl_verify_file);
- }
- if (ssl_verify_dir &&
- SSL_CTX_load_verify_locations(tls_http_ctx,NULL,ssl_verify_dir) == 0) {
- debug(F110,"ssl_http_init unable to load ssl_verify_dir",ssl_verify_dir,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",ssl_verify_dir);
- }
-
- SSL_CTX_set_verify(tls_http_ctx,ssl_verify_flag,
- ssl_client_verify_callback);
-
- /* Free the existing CRL Store */
- if (crl_store) {
- X509_STORE_free(crl_store);
- crl_store = NULL;
- }
-
- /* set up the new CRL Store */
- crl_store = X509_STORE_new();
- if (crl_store) {
-#ifdef OS2
- char path[CKMAXPATH];
-
- ckmakmsg(path,CKMAXPATH,exedir,"crls",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
- debug(F110,"ssl_http_init unable to load dir",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",path);
- }
-#ifdef NT
- ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/crls",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
- debug(F110,"ssl_http_init unable to load dir",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/crls",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
- debug(F110,"ssl_http_init unable to load dir",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",path);
- }
-#endif /* NT */
-
- ckmakmsg(path,CKMAXPATH,exedir,"ca_crls.pem",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
- debug(F110,"ssl_http_init unable to load file",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",path);
- }
-#ifdef NT
- ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_crls.pem",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
- debug(F110,"ssl_http_init unable to load file",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_crls.pem",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
- debug(F110,"ssl_http_init unable to load file",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",path);
- }
-#endif /* NT */
-#endif /* OS2 */
-
- if (ssl_crl_file || ssl_crl_dir) {
- if (ssl_crl_file &&
- X509_STORE_load_locations(crl_store,ssl_crl_file,NULL) == 0) {
- debug(F110,"ssl_http_init unable to load ssl_crl_file",ssl_crl_file,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",ssl_crl_file);
- }
- if (ssl_crl_dir &&
- X509_STORE_load_locations(crl_store,NULL,ssl_crl_dir) == 0) {
- debug(F110,"ssl_http_init unable to load ssl_crl_dir",ssl_crl_dir,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",ssl_crl_dir);
- }
- } else {
- X509_STORE_set_default_paths(crl_store);
- }
- }
-
-#ifndef COMMENT
- tls_conx = tls_http_con;
- tls_http_con=(SSL *)SSL_new(tls_http_ctx);
- if ( !tls_http_con ) {
- debug(F110,"ssl_http_init","SSL_new(tls_http_con) failed",0);
- tls_http_con = tls_conx;
- return(0);
- }
- if (tls_conx) {
- SSL_set_session(tls_http_con, SSL_get_session(tls_conx));
-#ifdef SSL_KRB5
- if (tls_conx->kssl_ctx) {
- kssl_ctx_free(tls_conx->kssl_ctx);
- tls_conx->kssl_ctx = NULL;
- }
-#endif /* SSL_KRB5 */
- SSL_free(tls_conx);
- tls_conx = NULL;
- }
-#else /* COMMENT */
- /* I don't know why this does not work to reuse the connection. */
- if ( tls_http_con ) {
- SSL_clear(tls_http_con);
- SSL_set_session(tls_http_con,NULL);
- SSL_set_accept_state(tls_http_con) ;
- } else {
- tls_http_con=(SSL *)SSL_new(tls_http_ctx);
- if ( !tls_http_con ) {
- debug(F110,"ssl_http_init","SSL_new(tls_http_ctx) failed",0);
- tls_http_con = tls_conx;
- return(0);
- }
- }
-#endif /* COMMENT */
-
-#ifdef SSL_KRB5
-#ifndef KRB5_SERVICE_NAME
-#define KRB5_SERVICE_NAME "host"
-#endif
-
- if (tls_http_con->kssl_ctx == NULL)
- tls_http_con->kssl_ctx = kssl_ctx_new();
- if (tls_http_con->kssl_ctx != NULL)
- kssl_ctx_setstring(tls_http_con->kssl_ctx, KSSL_SERVER, hostname);
-
- kssl_ctx_setstring(tls_http_con->kssl_ctx, KSSL_SERVICE,
- krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME);
-#endif /* SSL_KRB5 */
-
- if (ssl_cipher_list)
- SSL_set_cipher_list(tls_http_con,ssl_cipher_list);
- else {
- char * p;
- if (p = getenv("SSL_CIPHER")) {
- SSL_set_cipher_list(tls_http_con,p);
- } else {
- SSL_set_cipher_list(tls_http_con,DEFAULT_CIPHER_LIST);
- }
- }
-
- ssl_verify_depth = -1;
-
- if ( ssl_debug_flag )
- printf("SSL/TLS init done!\r\n");
-
- ssl_http_initialized = 1;
- return(1);
-}
-#endif /* NOHTTP */
-
-char *
-ssl_get_dNSName(ssl) SSL * ssl;
-{
- static char *dns = NULL;
- X509 *server_cert = NULL;
- int i;
- X509_EXTENSION *ext = NULL;
- STACK_OF(GENERAL_NAME) *ialt = NULL;
- GENERAL_NAME *gen = NULL;
-
- if ( dns ) {
- free(dns);
- dns = NULL;
- }
-
- if (server_cert = SSL_get_peer_certificate(ssl)) {
- if ((i = X509_get_ext_by_NID(server_cert, NID_subject_alt_name, -1))<0)
- return NULL;
- if (!(ext = X509_get_ext(server_cert, i)))
- return NULL;
- X509V3_add_standard_extensions();
- if (!(ialt = X509V3_EXT_d2i(ext)))
- return NULL;
- for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
- gen = sk_GENERAL_NAME_value(ialt, i);
- if (gen->type == GEN_DNS) {
- if (!gen->d.ia5 || !gen->d.ia5->length)
- break;
- if (strlen((char *)gen->d.ia5->data) != gen->d.ia5->length) {
- /* Ignoring IA5String containing null character */
- continue;
- }
- dns = malloc(gen->d.ia5->length + 1);
- if (dns) {
- memcpy(dns, gen->d.ia5->data, gen->d.ia5->length);
- dns[gen->d.ia5->length] = 0;
- }
- break;
- }
- }
- X509V3_EXT_cleanup();
- }
-cleanup:
- if (ialt) sk_GENERAL_NAME_free(ialt);
- if (server_cert) X509_free(server_cert);
- return dns;
-}
-
-char *
-ssl_get_commonName(ssl) SSL * ssl; {
- static char name[256];
- int name_text_len;
- int err;
- X509 *server_cert;
-
- name_text_len = 0;
- if (server_cert = SSL_get_peer_certificate(ssl)) {
- name_text_len =
- X509_NAME_get_text_by_NID(X509_get_subject_name(server_cert),
- NID_commonName, name, sizeof(name));
- X509_free(server_cert);
- }
- if (name_text_len <= 0) {
- /* Common Name was empty or not retrieved */
- err = 0;
- } else if (strlen(name) != name_text_len) {
- /* Ignoring Common Name containing null character */
- err = 0;
- } else {
- err = 1;
- }
- if (err > 0)
- return name;
- else
- return NULL;
-}
-
-char *
-ssl_get_issuer_name(ssl) SSL * ssl;
-{
- static char name[256];
- X509 *server_cert;
-
- name[0] = '\0';
- if (server_cert = SSL_get_peer_certificate(ssl)) {
- X509_NAME_oneline(X509_get_issuer_name(server_cert),name,sizeof(name));
- X509_free(server_cert);
- return name;
- }
- else {
-#ifdef COMMENT
- fprintf(stderr, "Warning: No certificate from server!\r\n");
-#endif /* COMMENT */
- return NULL;
- }
-}
-
-char *
-ssl_get_subject_name(ssl) SSL * ssl;
-{
- static char name[256];
- X509 *server_cert;
-
- name[0] = '\0';
- if (server_cert = SSL_get_peer_certificate(ssl)) {
- X509_NAME_oneline(X509_get_subject_name(server_cert),name,sizeof(name));
- X509_free(server_cert);
- return name;
- }
- else
- return NULL;
-}
-
-#ifdef COMMENT
-#ifdef CK_SSL
- && !(ck_ssleay_is_installed() &&
- (tls_active_flag || ssl_active_flag) &&
- ssl_anonymous_cipher(tls_active_flag?tls_con:ssl_con))
-#endif /* CK_SSL */
-
-int
-ssl_anonymous_cipher(ssl) SSL * ssl;
-{
- X509 * cert;
-
- if (sstelnet)
- cert = SSL_get_certificate(ssl);
- else
- cert = SSL_get_peer_certificate(ssl);
-
- if ( cert ) {
- X509_free(cert);
- return 0;
- }
- return 1;
-}
-#endif /* COMMENT */
-
-/*
- This one is (very much!) based on work by
- Ralf S. Engelschall <rse@engelschall.com>.
- Comments by Ralf.
-*/
-int
-ssl_verify_crl(int ok, X509_STORE_CTX *ctx)
-{
- X509_OBJECT obj;
- X509_NAME *subject = NULL;
- X509_NAME *issuer = NULL;
- X509 *xs = NULL;
- X509_CRL *crl = NULL;
- X509_REVOKED *revoked = NULL;
- X509_STORE_CTX * store_ctx = NULL;
- long serial;
- BIO *bio = NULL;
- int i, n, rc;
- char *cp;
- char *cp2;
-
- /*
- * Unless a revocation store for CRLs was created we
- * cannot do any CRL-based verification, of course.
- */
- if (!crl_store)
- return ok;
-
- store_ctx = X509_STORE_CTX_new();
- if ( !store_ctx )
- return(ok);
-
- /*
- * Determine certificate ingredients in advance
- */
- xs = X509_STORE_CTX_get_current_cert(ctx);
- subject = X509_get_subject_name(xs);
- issuer = X509_get_issuer_name(xs);
-
- /*
- * OpenSSL provides the general mechanism to deal with CRLs but does not
- * use them automatically when verifying certificates, so we do it
- * explicitly here. We will check the CRL for the currently checked
- * certificate, if there is such a CRL in the store.
- *
- * We come through this procedure for each certificate in the certificate
- * chain, starting with the root-CA's certificate. At each step we've to
- * both verify the signature on the CRL (to make sure it's a valid CRL)
- * and it's revocation list (to make sure the current certificate isn't
- * revoked). But because to check the signature on the CRL we need the
- * public key of the issuing CA certificate (which was already processed
- * one round before), we've a little problem. But we can both solve it and
- * at the same time optimize the processing by using the following
- * verification scheme (idea and code snippets borrowed from the GLOBUS
- * project):
- *
- * 1. We'll check the signature of a CRL in each step when we find a CRL
- * through the _subject_ name of the current certificate. This CRL
- * itself will be needed the first time in the next round, of course.
- * But we do the signature processing one round before this where the
- * public key of the CA is available.
- *
- * 2. We'll check the revocation list of a CRL in each step when
- * we find a CRL through the _issuer_ name of the current certificate.
- * This CRLs signature was then already verified one round before.
- *
- * This verification scheme allows a CA to revoke its own certificate as
- * well, of course.
- */
-
- /*
- * Try to retrieve a CRL corresponding to the _subject_ of
- * the current certificate in order to verify it's integrity.
- */
- memset((char *)&obj, 0, sizeof(obj));
- X509_STORE_CTX_init(store_ctx, crl_store, NULL, NULL);
- rc = X509_STORE_get_by_subject(store_ctx, X509_LU_CRL, subject, &obj);
- X509_STORE_CTX_cleanup(store_ctx);
- crl = obj.data.crl;
- if (rc > 0 && crl != NULL) {
- /*
- * Verify the signature on this CRL
- */
- if (X509_CRL_verify(crl, X509_get_pubkey(xs)) <= 0) {
- fprintf(stderr, "Invalid signature on CRL!\n");
- X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE);
- X509_OBJECT_free_contents(&obj);
- X509_STORE_CTX_free(store_ctx);
- return 0;
- }
-
- /*
- * Check date of CRL to make sure it's not expired
- */
- i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl));
- if (i == 0) {
- fprintf(stderr, "Found CRL has invalid nextUpdate field.\n");
- X509_STORE_CTX_set_error(ctx,
- X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
- X509_OBJECT_free_contents(&obj);
- X509_STORE_CTX_free(store_ctx);
- return 0;
- }
- if (i < 0) {
- fprintf(stderr,
-"Found CRL is expired - revoking all certificates until you get updated CRL.\n"
- );
- X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED);
- X509_OBJECT_free_contents(&obj);
- X509_STORE_CTX_free(store_ctx);
- return 0;
- }
- X509_OBJECT_free_contents(&obj);
- }
-
- /*
- * Try to retrieve a CRL corresponding to the _issuer_ of
- * the current certificate in order to check for revocation.
- */
- memset((char *)&obj, 0, sizeof(obj));
- X509_STORE_CTX_init(store_ctx, crl_store, NULL, NULL);
- rc = X509_STORE_get_by_subject(store_ctx, X509_LU_CRL, issuer, &obj);
- X509_STORE_CTX_free(store_ctx); /* calls X509_STORE_CTX_cleanup() */
- crl = obj.data.crl;
- if (rc > 0 && crl != NULL) {
- /*
- * Check if the current certificate is revoked by this CRL
- */
- n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
- for (i = 0; i < n; i++) {
- revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
- if (ASN1_INTEGER_cmp(revoked->serialNumber,
- X509_get_serialNumber(xs)) == 0) {
-
- serial = ASN1_INTEGER_get(revoked->serialNumber);
- cp = X509_NAME_oneline(issuer, NULL, 0);
- free(cp);
-
- X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
- X509_OBJECT_free_contents(&obj);
- return 0;
- }
- }
- X509_OBJECT_free_contents(&obj);
- }
- return ok;
-}
-
-char *
-tls_userid_from_client_cert(ssl) SSL * ssl;
-{
- static char cn[256];
- static char *r = cn;
- int err;
- X509 *client_cert;
-
- if (client_cert = SSL_get_peer_certificate(ssl)) {
- /* call the custom function */
- err = X509_to_user(client_cert, cn, sizeof(cn));
- X509_free(client_cert);
- if (err)
- return r = NULL;
- else
- return r;
- }
- else
- return r = NULL;
-}
-
-unsigned char **
-tls_get_SAN_objs(SSL * ssl, int type)
-/* returns NULL or an array of malloc'ed objects of type `type' from the server's
- * subjectAltName, remember to free() them all!
- */
-{
-#define NUM_SAN_OBJS 64
- static unsigned char *objs[NUM_SAN_OBJS];
- unsigned char **rv = NULL;
- X509 *server_cert = NULL;
- int i, j;
- X509_EXTENSION *ext = NULL;
- STACK_OF(GENERAL_NAME) *ialt = NULL;
- GENERAL_NAME *gen = NULL;
-
- memset(objs, 0, sizeof(objs));
- if (server_cert = SSL_get_peer_certificate(ssl)) {
- if ((i = X509_get_ext_by_NID(server_cert, NID_subject_alt_name, -1)) < 0)
- goto eject;
- if (!(ext = X509_get_ext(server_cert, i)))
- goto eject;
- X509V3_add_standard_extensions();
- if (!(ialt = X509V3_EXT_d2i(ext)))
- goto eject;
- rv = objs;
- for (i = 0, j = 0; i < sk_GENERAL_NAME_num(ialt) && j < NUM_SAN_OBJS - 2; i++) {
- gen = sk_GENERAL_NAME_value(ialt, i);
- /* The use of V_ASN1_CONTEXT_SPECIFIC is because OpenSSL 0.9.6 defined its
- * types | V_ASN1_CONTEXT_SPECIFIC. 0.9.7 does not. In case, we are built
- * with one and linked to the other we use this hack.
- */
- if ((gen->type | V_ASN1_CONTEXT_SPECIFIC) == (type | V_ASN1_CONTEXT_SPECIFIC)) {
- if (!gen->d.ia5 || !gen->d.ia5->length)
- break;
- if (strlen((char *)gen->d.ia5->data) != gen->d.ia5->length) {
- /* Ignoring IA5String containing null character */
- continue;
- }
- objs[j] = malloc(gen->d.ia5->length + 1);
- if (objs[j]) {
- memcpy(objs[j], gen->d.ia5->data, gen->d.ia5->length);
- objs[j][gen->d.ia5->length] = 0;
- j++;
- }
- }
- }
- X509V3_EXT_cleanup();
- }
-eject:
- if (ialt) sk_GENERAL_NAME_free(ialt);
- if (server_cert) X509_free(server_cert);
- return rv;
-}
-
-
-static int
-dNSName_cmp(const char *host, const char *dNSName)
-{
- int c1 = 1, c2 = 1, num_comp, rv = -1;
- char *p, *p1, *p2, *host_copy=NULL, *dNSName_copy=NULL;
-
- /* first we count the number of domain name components in both parameters.
- * they should be equal many, or it's not a match
- */
- p = (char *) host;
- while (p = strstr(p, ".")) {
- c1++;
- p++;
- }
- p = (char *) dNSName;
- while (p = strstr(p, ".")) {
- c2++;
- p++;
- }
- if (c1 != c2)
- return -1;
- num_comp = c1;
-
- makestr(&host_copy,host);
- makestr(&dNSName_copy,dNSName);
- if (host_copy == NULL || dNSName_copy == NULL)
- goto eject;
- /* make substrings by replacing '.' with '\0' */
- p = dNSName_copy;
- while (p = strstr(p, ".")) {
- *p = '\0';
- p++;
- }
- p = host_copy;
- while (p = strstr(p, ".")) {
- *p = '\0';
- p++;
- }
-
- /* compare each component */
- p1 = host_copy;
- p2 = dNSName_copy;
- for (; num_comp; num_comp--) {
- if (!ckmatch(p2, p1,0,1))
- /* failed match */
- goto eject;
- p1 += strlen(p1) + 1;
- p2 += strlen(p2) + 1;
- }
- /* match ok */
- rv = 0;
-
- eject:
- if (dNSName_copy) free(dNSName_copy);
- if (host_copy) free(host_copy);
- return rv;
-}
-
-
-
-static int
-show_hostname_warning(char *s1, char *s2)
-{
- char prefix[1024];
- int ok = 1;
- setverbosity();
- ckmakxmsg(prefix,1024,
- "Warning: Hostname (\"", s1,
- "\") does not match server's certificate (\"", s2, "\")",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- if (ssl_verify_flag)
- ok = uq_ok(prefix,
- "Continue? (Y/N) ",
- 3, NULL, 0);
- else if (verbosity)
- printf(prefix);
- return(ok);
-}
-
-#ifndef OSF50
-#ifndef HPUX10
-#ifndef HPUX1100
-#ifndef SCO_OSR505
-#ifndef OpenBSD
-#ifndef FREEBSD4
-#ifndef NETBSD15
-#ifndef LINUX
-#ifndef AIX41
-#ifndef UW7
-#ifndef IRIX65
-#ifndef SOLARIS9
-#ifndef SOLARIS8
-#ifndef SOLARIS7
-#ifndef MACOSX
-#ifdef DEC_TCPIP
-#define inet_aton INET_ATON
-#endif /* DEC_TCPIP */
-
-#ifndef NO_DCL_INET_ATON
-static int
-inet_aton(char * ipaddress, struct in_addr * ia) {
- struct stringarray * q;
- union {
- unsigned long l;
- unsigned char b[4];
- } dummy;
-
- q = cksplit(1,0,ipaddress,".","0123456789abcdefACDEF",8,0,0);
- if (q->a_size == 4) {
- dummy.b[0] = atoi(q->a_head[1]);
- dummy.b[1] = atoi(q->a_head[2]);
- dummy.b[2] = atoi(q->a_head[3]);
- dummy.b[3] = atoi(q->a_head[4]);
- ia->s_addr = dummy.l;
- return(ia->s_addr != 0);
- }
- return(0);
-}
-#endif /* NO_DCL_INET_ATON */
-
-#endif /* MACOSX */
-#endif /* SOLARIS7 */
-#endif /* SOLARIS8 */
-#endif /* SOLARIS9 */
-#endif /* IRIX65 */
-#endif /* UW7 */
-#endif /* AIX41 */
-#endif /* LINUX */
-#endif /* NETBSD15 */
-#endif /* FREEBSD4 */
-#endif /* OpenBSD */
-#endif /* SCO_OSR505 */
-#endif /* HPUX1100 */
-#endif /* HPUX10 */
-#endif /* OSF50 */
-
-int
-ssl_check_server_name(SSL * ssl, char * hostname)
-/* returns 0 if hostname and server's cert matches, else -1 */
-{
- char * commonName;
- unsigned char ** dNSName;
- unsigned char ** ipAddress;
- struct in_addr ia;
- int rv;
-
- setverbosity();
- if (verbosity && !inserver) {
- if (dNSName = tls_get_SAN_objs(ssl,GEN_DNS)) {
- int i = 0;
- for (i = 0; dNSName[i]; i++) {
- printf("Certificate[0] altSubjectName DNS=%s\r\n",dNSName[i]);
- free(dNSName[i]);
- }
- }
- if (ipAddress = tls_get_SAN_objs(ssl,GEN_IPADD)) {
- int i = 0;
- char *server_ip;
- struct in_addr ia;
-
- for (i = 0; ipAddress[i]; i++) {
- if (ipAddress[i]) {
- ia.s_addr = *(unsigned long *)ipAddress[i];
- server_ip = inet_ntoa(ia);
- printf("Certificate[0] altSubjectName IPAddr=%s\r\n",server_ip);
- }
- free(ipAddress[i]);
- }
- /* ipAddress points to a static - don't free */
- }
- if (dNSName = tls_get_SAN_objs(ssl,GEN_EMAIL)) {
- int i = 0;
- for (i = 0; dNSName[i]; i++) {
- printf("Certificate[0] altSubjectName Email=%s\r\n",dNSName[i]);
- free(dNSName[i]);
- }
- }
- if (dNSName = tls_get_SAN_objs(ssl,GEN_URI)) {
- int i = 0;
- for (i = 0; dNSName[i]; i++) {
- printf("Certificate[0] altSubjectName URI=%s\r\n",dNSName[i]);
- free(dNSName[i]);
- }
- }
- if (dNSName = tls_get_SAN_objs(ssl,GEN_OTHERNAME)) {
- int i = 0;
- for (i = 0; dNSName[i]; i++) {
- printf("Certificate[0] altSubjectName Other=%s\r\n",dNSName[i]);
- free(dNSName[i]);
- }
- }
- }
-
- /* first we check if `hostname' is in fact an ip address */
- if (inet_aton(hostname, &ia)) {
- ipAddress = tls_get_SAN_objs(ssl,GEN_IPADD);
- if (ipAddress) {
- int i = 0;
- char *server_ip = "UNKNOWN";
-
- for (i = 0; ipAddress[i]; i++)
- if (*(unsigned long *)ipAddress[i] == ia.s_addr)
- return 0;
-
- if (ipAddress[i - 1]) {
- ia.s_addr = *(unsigned long *)ipAddress[i - 1];
- server_ip = inet_ntoa(ia);
- }
- rv = show_hostname_warning(hostname, server_ip) ? 0 : -1;
- for (i = 0; ipAddress[i]; i++)
- free(ipAddress[i]);
- } else {
- rv = show_hostname_warning(hostname, "NO IP IN CERT") ? 0 : -1;
- }
- return(rv);
- }
-
- /* look for dNSName(s) in subjectAltName in the server's certificate */
- dNSName = tls_get_SAN_objs(ssl,GEN_DNS);
- if (dNSName) {
- int i = 0;
- for (i = 0; dNSName[i]; i++) {
- if (!dNSName_cmp(hostname,(char *)dNSName[i]))
- return 0;
- }
- rv = show_hostname_warning(hostname,
- (char *)((dNSName[i - 1] == NULL) ?
- (char *)"UNKNOWN" : (char *)dNSName[i - 1]))
- ? 0 : -1;
- for (i = 0; dNSName[i]; i++)
- free(dNSName[i]);
- return rv;
- } else if ((commonName = ssl_get_commonName(ssl))) {
- /* so the server didn't have any dNSName's, check the commonName */
- if (!dNSName_cmp(hostname, commonName))
- return 0;
- else
- return (show_hostname_warning(hostname, commonName) ? 0 : -1);
- }
- return -1;
-}
-
-/* Is 'user' authorized to access the system without a login */
-int
-tls_is_user_valid(SSL * ssl, const char *user)
-{
- X509 *client_cert;
- int r = 0;
-
- if ( !ssl || !user || !user[0] )
- return(0);
-
- if (!(client_cert = SSL_get_peer_certificate(ssl)))
- return 0;
-
- /* Use user supplied function */
- r = X509_userok(client_cert,user);
-
- X509_free(client_cert);
- return r;
-}
-
-int
-tls_is_anon(int x)
-{
- char buf[128];
- SSL_CIPHER * cipher;
- SSL * ssl = NULL;
-
- switch ( x ) {
-#ifndef NOFTP
-#ifndef SYSFTP
- case 1: /* ftp command */
- if ( ssl_ftp_active_flag )
- ssl = ssl_ftp_con;
- else
- return(0);
- break;
- case 2: /* ftp data */
- if ( ssl_ftp_data_active_flag )
- ssl = ssl_ftp_data_con;
- else
- return(0);
- break;
-#endif /* SYSFTP */
-#endif /* NOFTP */
- default:
- if (tls_active_flag)
- ssl = tls_con;
- else if (ssl_active_flag)
- ssl = ssl_con;
- else
- return(0);
- }
-
- cipher = SSL_get_current_cipher(ssl);
- if (SSL_CIPHER_description(cipher,buf,sizeof(buf))) {
- if (ckindex("Au=None",buf,0,0,0) != 0)
- return(1); /* anonymous */
- return(0); /* known */
- } else {
- /* could not get cipher description. Assume anonymous */
- return(1);
- }
-}
-
-int
-tls_is_krb5(int x)
-{
- char buf[128];
- SSL_CIPHER * cipher;
- SSL * ssl = NULL;
-
- switch ( x ) {
-#ifndef NOFTP
-#ifndef SYSFTP
- case 1: /* ftp command */
- if ( ssl_ftp_active_flag )
- ssl = ssl_ftp_con;
- else
- return(0);
- break;
- case 2: /* ftp data */
- if ( ssl_ftp_data_active_flag )
- ssl = ssl_ftp_data_con;
- else
- return(0);
- break;
-#endif /* SYSFTP */
-#endif /* NOFTP */
-#ifndef NOHTTP
- case 3:
- if ( tls_http_active_flag )
- ssl = tls_http_con;
- break;
-#endif /* NOHTTP */
- default:
- if (tls_active_flag)
- ssl = tls_con;
- else if (ssl_active_flag)
- ssl = ssl_con;
- else
- return(0);
- }
-
- cipher = SSL_get_current_cipher(ssl);
- if (cipher && SSL_CIPHER_description(cipher,buf,sizeof(buf))) {
- if (ckindex("Au=KRB5",buf,0,0,0) != 0)
- return(1); /* krb5 */
- }
- return(0); /* not */
-}
-
-int
-ssl_get_client_finished(char *buf, int count)
-{
-#ifdef NO_GET_FINISHED
- return(0);
-#else
- if (sstelnet || tcp_incoming) {
- return(SSL_get_peer_finished(ssl_active_flag?ssl_con:tls_con,
- buf,count));
- } else {
- return(SSL_get_finished(ssl_active_flag?ssl_con:tls_con,
- buf,count));
- }
-#endif /* NO_GET_FINISHED */
-}
-
-int
-ssl_get_server_finished(char *buf, int count)
-{
-#ifdef NO_GET_FINISHED
- return(0);
-#else
- if (sstelnet || tcp_incoming) {
- return(SSL_get_finished(ssl_active_flag?ssl_con:tls_con,
- buf,count));
- } else {
- return(SSL_get_peer_finished(ssl_active_flag?ssl_con:tls_con,
- buf,count));
- }
-#endif /* NO_GET_FINISHED */
-}
-
-
-#ifdef CK_AUTHENTICATION
-int
-#ifdef CK_ANSIC
-ssl_reply(int how, unsigned char *data, int cnt)
-#else
-ssl_reply(how,data,cnt) int how; unsigned char *data; int cnt;
-#endif
-{
- char * str=NULL;
-
- setverbosity();
- data += 4; /* Point to status byte */
- cnt -= 4;
-
- if(cnt-- < 1) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- switch(*data++) {
- case SSL_ACCEPT:
- if (tn_deb || debses)
- tn_debug("[SSL - handshake starting]");
- else if ( verbosity )
- printf("[SSL - handshake starting]\r\n");
- debug(F110,"ssl_reply","[SSL - handshake starting]",0);
-
- /* right ... now we drop into the SSL library */
- if (!ssl_only_flag) {
- if (ssl_dummy_flag) {
- if (tn_deb || debses)
- tn_debug("[SSL - Dummy Connected]");
- else if ( verbosity ) {
- printf("[SSL - Dummy Connected]\r\n");
- }
- debug(F110,"ssl_reply","[SSL - Dummy Connected]",0);
- auth_finished(AUTH_UNKNOWN);
- accept_complete = 1;
- return AUTH_SUCCESS;
- }
-
- if (SSL_connect(ssl_con) <= 0) {
- int len;
- if (tn_deb || debses) {
- tn_debug("[SSL - FAILED]");
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- printf(ssl_err);
- } else if ( verbosity ) {
- printf("[SSL - FAILED]\r\n");
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- printf(ssl_err);
- }
- debug(F110,"ssl_reply","[SSL - FAILED]",0);
- auth_finished(AUTH_REJECT);
- ttclos(0);
- return AUTH_FAILURE;
- } else {
- if (tn_deb || debses)
- tn_debug("[SSL - OK]");
- else if ( verbosity ) {
- printf("[SSL - OK]\r\n");
- }
- debug(F110,"ssl_reply","[SSL - OK]",0);
-
- ssl_active_flag = 1;
- ssl_display_connect_details(ssl_con,0,verbosity);
- }
- }
- auth_finished(AUTH_UNKNOWN);
- accept_complete = 1;
- break;
-
- case SSL_REJECT:
- if (tn_deb || debses) {
- tn_debug(
- "[SSL - failed to switch on SSL - trying plaintext login]");
- } else if ( verbosity ) {
- printf("[SSL - failed to switch on SSL]\r\n");
- printf("Trying plaintext login:\r\n");
- }
- debug(F110,"ssl_reply","[SSL - failed to switch on SSL]",0);
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
-
- default:
- return AUTH_FAILURE;
- }
- return AUTH_SUCCESS;
-}
-
-int
-#ifdef CK_ANSIC
-ssl_is(unsigned char *data, int cnt)
-#else
-ssl_is(data,cnt) unsigned char *data; int cnt;
-#endif
-{
- if ((cnt -= 4) < 1)
- return AUTH_FAILURE;
-
- setverbosity();
- data += 4;
- switch(*data++) {
- case SSL_START:
- /* server starts the SSL stuff now ... */
- if (!ssl_only_flag) {
- if ( !tls_load_certs(ssl_ctx,ssl_con,1) ) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- if (tn_deb || debses)
- tn_debug("[SSL - handshake starting]");
- else if ( verbosity )
- printf("[SSL - handshake starting]\r\n");
- debug(F110,"ssl_is","[SSL - handshake starting]",0);
-
- SendSSLAuthSB(SSL_ACCEPT, (void *)0, 0);
-
- auth_ssl_valid = 1;
-
- if (ssl_dummy_flag) {
- if (tn_deb || debses)
- tn_debug("[SSL - Dummy Connected]");
- else if ( verbosity ) {
- printf("[SSL - Dummy Connected]\r\n");
- }
- debug(F110,"ssl_is","[SSL - Dummy Connected]",0);
- accept_complete = 1;
- auth_finished(AUTH_UNKNOWN);
- return AUTH_SUCCESS;
- }
-
- if (SSL_accept(ssl_con) <= 0) {
- char errbuf[1024];
-
- sprintf(errbuf,"[SSL - SSL_accept error: %s",
- ERR_error_string(ERR_get_error(),NULL));
-
- if (tn_deb || debses)
- tn_debug(errbuf);
- else if ( ssl_debug_flag )
- printf("%s\r\n",errbuf);
- else if ( verbosity )
- printf("[SSL - SSL_accept error]\r\n");
-
- debug(F110,"ssl_is",errbuf,0);
-
- auth_finished(AUTH_REJECT);
- ttclos(0);
- return AUTH_FAILURE;
- }
-
- if (tn_deb || debses)
- tn_debug("[SSL - OK]");
- else if ( verbosity ) {
- printf("[SSL - OK]\r\n");
- }
- debug(F110,"ssl_is","[SSL - OK]",0);
- ssl_active_flag = 1;
- ssl_display_connect_details(ssl_con,1,verbosity);
-
- /* now check to see that we got exactly what we
- * wanted from the caller ... if a certificate is
- * required then we make 100% sure that we were
- * given one during the handshake (as it is an optional
- * part of SSL)
- */
-
-#ifdef SSL_KRB5
- if ( tls_is_krb5(0) ) {
- if (ssl_con->kssl_ctx->client_princ)
- debug(F110,"ssl_is KRB5",ssl_con->kssl_ctx->client_princ,0);
- } else
-#endif /* SSL_KRB5 */
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- X509 * peer = SSL_get_peer_certificate(ssl_con);
- if (peer == NULL) {
- if (tn_deb || debses)
- tn_debug("[SSL - peer check failed]");
- else if (ssl_debug_flag)
- printf("[SSL - peer check failed]\r\n");
- debug(F110,"ssl_is","[SSL - peer check failed]",0);
-
- /* LOGGING REQUIRED HERE! */
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
- }
- auth_finished(AUTH_UNKNOWN);
- accept_complete = 1;
- }
- break;
-
- default:
- SendSSLAuthSB(SSL_REJECT, (void *) "Unknown option received", -1);
- if (tn_deb || debses)
- tn_debug("[SSL - Unknown option received]");
- else
- printf("Unknown SSL option %d\r\n", data[-1]);
- debug(F111,"ssl_is","[SSL - Unknown option received]",data[-1]);
- auth_ssl_valid = 0;
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
- return AUTH_SUCCESS;
-}
-
-#endif /* CK_AUTHENTICATION */
-
-int
-ck_tn_tls_negotiate(VOID)
-{
- X509 * peer = NULL;
- char str[256], *uid=NULL;
- extern int sstelnet;
-
- if ( !ck_ssleay_is_installed() )
- return(-1);
-
- setverbosity();
- if (sstelnet) {
- /* server starts the TLS stuff now ... */
- if (!tls_only_flag) {
- if ( !tls_load_certs(tls_ctx,tls_con,1) ) {
- auth_finished(AUTH_REJECT);
- return -1;
- }
-
- if (tn_deb || debses)
- tn_debug("[TLS - handshake starting]");
- else if ( verbosity )
- printf("[TLS - handshake starting]\r\n");
- debug(F110,"ck_tn_tls_negotiate","[TLS - handshake starting]",0);
-
- if (ssl_dummy_flag) {
- if (tn_deb || debses)
- tn_debug("[TLS - Dummy Connected]");
- else if ( verbosity ) {
- printf("[TLS - Dummy Connected]\r\n");
- }
- debug(F110,"ck_tn_tls_negotiate","[TLS - Dummy Connected]",0);
- accept_complete = 1;
- auth_finished(AUTH_REJECT);
- return 0;
- }
-
- if (SSL_accept(tls_con) <= 0) {
- char errbuf[1024];
-
- sprintf(errbuf,"[TLS - SSL_accept error: %s",
- ERR_error_string(ERR_get_error(),NULL));
-
- if (tn_deb || debses)
- tn_debug(errbuf);
- else if ( ssl_debug_flag )
- printf("%s\r\n",errbuf);
- else if ( verbosity )
- printf("[TLS - SSL_accept error]\r\n");
-
- debug(F110,"ck_tn_tls_negotiate",errbuf,0);
- auth_finished(AUTH_REJECT);
- return -1;
- }
-
- if (tn_deb || debses)
- tn_debug("[TLS - OK]");
- else if ( verbosity ) {
- printf("[TLS - OK]\r\n");
- }
-
- debug(F110,"ck_tn_tls_negotiate","[TLS - OK]",0);
- tls_active_flag = 1;
- ssl_display_connect_details(tls_con,1,verbosity);
-
-
-#ifdef SSL_KRB5
- if ( tls_is_krb5(0) ) {
- if (tls_con->kssl_ctx->client_princ) {
- char *p;
- ckstrncpy(szUserNameAuthenticated,
- tls_con->kssl_ctx->client_princ,
- UIDBUFLEN);
- ckstrncpy(szUserNameRequested,
- tls_con->kssl_ctx->client_princ,
- UIDBUFLEN);
- for ( p = szUserNameRequested; *p ; p++ ) {
- if ( *p == '@' || *p == '/' ) {
- *p = '\0';
- break;
- }
- }
- } else {
- szUserNameRequested[0] = '\0';
- szUserNameAuthenticated[0] = '\0';
- }
-#ifdef CK_LOGIN
- if (zvuser(szUserNameRequested))
- auth_finished(AUTH_VALID);
- else
-#endif /* CK_LOGIN */
- auth_finished(AUTH_USER);
- } else
-#endif /* SSL_KRB5 */
- {
- /* now check to see that we got exactly what we
- * wanted from the caller ... if a certificate is
- * required then we make 100% sure that we were
- * given one during the handshake (as it is an optional
- * part of TLS)
- */
- peer=SSL_get_peer_certificate(tls_con);
- if (peer == NULL) {
- debug(F100,"SSL_get_peer_certificate() == NULL","",0);
- auth_finished(AUTH_REJECT);
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- if (tn_deb || debses)
- tn_debug("[TLS - peer check failed]");
- else if (ssl_debug_flag) {
- printf("[TLS - peer check failed]\r\n");
- }
- debug(F110,
- "ck_tn_tls_negotiate",
- "[TLS - peer check failed]",
- 0
- );
- /* LOGGING REQUIRED HERE! */
- return -1;
- }
- } else {
- debug(F100,"SSL_get_peer_certificate() != NULL","",0);
- X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
- NID_commonName,str,
- 256
- );
- if ( verbosity )
- printf("[TLS - commonName=%s]\r\n",str);
-
- X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
-#ifndef NID_x500UniqueIdentifier
- NID_uniqueIdentifier,
-#else
- NID_x500UniqueIdentifier,
-#endif
- str,
- 256
- );
- if ( verbosity )
- printf("[TLS - uniqueIdentifier=%s]\r\n",str);
-
- /* Try to determine user name */
- uid = tls_userid_from_client_cert(tls_con);
- if ( uid ) {
- /* This code is very questionable.
- * How should it behave?
- * The client has presented a certificate that
- * contains a username. We have validated the
- * certificate but we do not automatically
- * log the user in unless there is a .tlslogin
- * file.
- */
-
- ckstrncpy(szUserNameRequested,uid,UIDBUFLEN);
-#ifdef CK_LOGIN
- if (zvuser(uid))
- auth_finished(AUTH_VALID);
- else
-#endif /* CK_LOGIN */
- auth_finished(AUTH_USER);
- }
- else {
- szUserNameRequested[0] = '\0';
- auth_finished(AUTH_REJECT);
- }
- }
- }
- }
- } else {
- char * str=NULL;
-
- if (tn_deb || debses)
- tn_debug("[TLS - handshake starting]");
- else if ( verbosity )
- printf("[TLS - handshake starting]\r\n");
- debug(F110,"ck_tn_tls_negotiate","[TLS - handshake starting]",0);
-
- /* right ... now we drop into the SSL library */
- if (!tls_only_flag) {
- char *subject=NULL, *issuer=NULL, *commonName=NULL, *dNSName=NULL;
-
- if (ssl_dummy_flag) {
- if (tn_deb || debses)
- tn_debug("[TLS - Dummy Connected]");
- else if ( verbosity ) {
- printf("[TLS - Dummy Connected]\r\n");
- }
- debug(F110,"ck_tn_tls_negotiate","[TLS - Dummy Connected]",0);
- auth_finished(AUTH_REJECT);
- accept_complete = 1;
- return 0;
- }
-
-#ifndef USE_CERT_CB
- if (!tls_load_certs(tls_ctx,tls_con,0))
- return(-1);
-#endif /* USE_CERT_CB */
- if (SSL_connect(tls_con) <= 0) {
- int len;
- if (tn_deb || debses) {
- tn_debug("[TLS - FAILED]");
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- printf(ssl_err);
- } else if ( verbosity ) {
- printf("[TLS - FAILED]\r\n");
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- printf(ssl_err);
- }
- debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
- auth_finished(AUTH_REJECT);
- return -1;
- }
-
- tls_active_flag = 1;
- if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER)
- && !tls_is_krb5(0)) {
- char prmpt[1024];
- subject = ssl_get_subject_name(tls_con);
-
- if (!subject) {
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
- {
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
- auth_finished(AUTH_REJECT);
- return -1;
- } else {
- int ok;
- ok = uq_ok("Warning: Server didn't provide a certificate",
- "Continue? (Y/N)", 3, NULL, 0);
- if (!ok) {
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,
- "ck_tn_tls_negotiate","[TLS - FAILED]",0);
- auth_finished(AUTH_REJECT);
- return -1;
- }
- }
- } else if (ssl_check_server_name(tls_con, szHostName)) {
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,
- "ck_tn_tls_negotiate","[TLS - FAILED]",0);
- auth_finished(AUTH_REJECT);
- return -1;
- }
- }
-
- if ( ssl_debug_flag && ssl_finished_messages) {
- char msg[32];
- int i, len=32;
- extern char tn_msg[], hexbuf[];
-
- tn_msg[0] = '\0';
- len = ssl_get_client_finished(msg,len);
- if ( len > 0 ) {
- for ( i=0;i<len;i++ ) {
- sprintf(hexbuf,"%02X ",msg[i]);
- ckstrncat(tn_msg,hexbuf,TN_MSG_LEN);
- }
- printf("TLS client finished: %s\r\n",tn_msg);
- }
- tn_msg[0] = '\0';
- len = ssl_get_server_finished(msg,len);
- if ( len > 0 ) {
- for ( i=0;i<len;i++ ) {
- sprintf(hexbuf,"%02X ",msg[i]);
- ckstrncat(tn_msg,hexbuf,TN_MSG_LEN);
- }
- printf("TLS server finished: %s\r\n",tn_msg);
- }
- }
-
- if (tn_deb || debses)
- tn_debug("[TLS - OK]");
- else if ( verbosity )
- printf("[TLS - OK]\r\n");
- debug(F110,"ck_tn_tls_negotiate","[TLS - OK]",0);
-
- ssl_display_connect_details(tls_con,0,verbosity);
- }
- auth_finished(AUTH_REJECT);
- }
- accept_complete = 1;
- auth_ssl_valid = 1;
- return(0);
-}
-
-int
-ck_ssl_incoming(fd) int fd;
-{
- /* if we are not running in debug then any error
- * stuff from SSL debug *must* not go down
- * the socket (which 0,1,2 are all pointing to by
- * default)
- */
-
- int timo = 2000;
-
- setverbosity();
- if ( !ck_ssleay_is_installed() )
- return(-1);
-
- /* do the SSL stuff now ... before we play with pty's */
- SSL_set_fd(ssl_con,fd);
- SSL_set_fd(tls_con,fd);
-
- if (tls_only_flag) {
- if (tn_deb || debses)
- tn_debug("[TLS - handshake starting]");
- else if ( verbosity )
- printf("[TLS - handshake starting]\r\n");
- debug(F110,"ck_ssl_incoming","[TLS - handshake starting]",0);
-
- /* hmm ... only when running talking to things like
- * https servers should we hit this code and then
- * we really don't care *who* we talk to :-)
- */
- if (SSL_accept(tls_con) <= 0) {
- char errbuf[1024];
-
- sprintf(errbuf,"[TLS - SSL_accept error: %s",
- ERR_error_string(ERR_get_error(),NULL));
-
- if (tn_deb || debses)
- tn_debug(errbuf);
- else if ( ssl_debug_flag )
- printf("%s\r\n",errbuf);
- else if ( verbosity )
- printf("[TLS - SSL_accept error]\r\n");
-
- debug(F110,"ck_ssl_incoming",errbuf,0);
- return(-1);
- } else {
- if (tn_deb || debses)
- tn_debug("[TLS - OK]");
- else if ( verbosity )
- printf("[TLS - OK]\r\n");
- debug(F110,"ck_ssl_incoming","[TLS - OK]",0);
- tls_active_flag = 1;
- }
- } else if (ssl_only_flag) {
- if (tn_deb || debses)
- tn_debug("[SSL - handshake starting]");
- else if ( verbosity )
- printf("[SSL - handshake starting]\r\n");
- debug(F110,"ck_ssl_incoming","[SSL - handshake starting]",0);
-
- /* hmm ... only when running talking to things like
- * https servers should we hit this code and then
- * we really don't care *who* we talk to :-)
- */
- if (SSL_accept(ssl_con) <= 0) {
- char errbuf[1024];
-
- sprintf(errbuf,"[SSL - SSL_accept error: %s",
- ERR_error_string(ERR_get_error(),NULL));
-
- if (tn_deb || debses)
- tn_debug(errbuf);
- else if ( ssl_debug_flag )
- printf("%s\r\n",errbuf);
- else if ( verbosity )
- printf("[SSL - SSL_accept error]\r\n");
-
- debug(F110,"ck_ssl_incoming",errbuf,0);
- return(-1);
- } else {
- if (tn_deb || debses)
- tn_debug("[SSL - OK]");
- else if ( verbosity )
- printf("[SSL - OK]\r\n");
- debug(F110,"ssl_is","[SSL - OK]",0);
- ssl_active_flag = 1;
- }
- }
- if (ssl_active_flag || tls_active_flag) {
- X509 *peer;
- char str[256], *uid=NULL;
-
- /* now check to see that we got exactly what we
- * wanted from the caller ... if a certificate is
- * required then we make 100% sure that we were
- * given on during the handshake (as it is an optional
- * part of SSL and TLS)
- */
-
- if ( tls_active_flag ) {
- peer=SSL_get_peer_certificate(tls_con);
- } else if ( ssl_active_flag ) {
- peer=SSL_get_peer_certificate(ssl_con);
- }
-
- if (peer == NULL) {
- debug(F100,"SSL_get_peer_certificate() == NULL","",0);
- auth_finished(AUTH_REJECT);
-
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- if (tn_deb || debses)
- tn_debug("[SSL/TLS - peer check failed]");
- else if (ssl_debug_flag) {
- printf("[SSL/TLS - peer check failed]\r\n");
- }
- debug(F110,
- "ck_tn_tls_negotiate",
- "[SSL/TLS - peer check failed]",
- 0
- );
- /* LOGGING REQUIRED HERE! */
- return -1;
- }
-
- } else {
- debug(F100,"SSL_get_peer_certificate() != NULL","",0);
- X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
- NID_commonName,str,
- 256
- );
- printf("[TLS - commonName=%s]\r\n",str);
-
- X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
-#ifndef NID_x500UniqueIdentifier
- NID_uniqueIdentifier,
-#else
- NID_x500UniqueIdentifier,
-#endif
- str,256
- );
- printf("[TLS - uniqueIdentifier=%s]\r\n",str);
-
- /* Try to determine user name */
- uid = tls_userid_from_client_cert(tls_con);
- if ( uid ) {
- /* This code is very questionable.
- * How should it behave?
- * The client has presented a certificate that
- * contains a username. We have validated the
- * certificate but we do not automatically
- * log the user in unless there is a .tlslogin
- * file.
- */
-
- ckstrncpy(szUserNameRequested,uid,UIDBUFLEN);
-#ifdef CK_LOGIN
- if (zvuser(uid))
- auth_finished(AUTH_VALID);
- else
-#endif /* CK_LOGIN */
- auth_finished(AUTH_USER);
- }
- else {
- szUserNameRequested[0] = '\0';
- auth_finished(AUTH_REJECT);
- }
- }
- }
- return(0); /* success */
-}
-
-int
-ck_ssl_outgoing(fd) int fd;
-{
- int timo = 2000;
-
- setverbosity();
- if ( !ck_ssleay_is_installed() )
- return(-1);
-
- /* bind in the network descriptor */
- SSL_set_fd(ssl_con,fd);
- SSL_set_fd(tls_con,fd);
-
- /* If we are doing raw TLS then start it now ... */
- if (tls_only_flag) {
-#ifndef USE_CERT_CB
- if (!tls_load_certs(tls_ctx,tls_con,0)) {
- debug(F110,"ck_ssl_outgoing","tls_load_certs() failed",0);
- return(-1);
- }
-#endif /* USE_CERT_CB */
- if (tn_deb || debses)
- tn_debug("[TLS - handshake starting]");
- else if (verbosity)
- printf("[TLS - handshake starting]\r\n");
- debug(F110,"ck_ssl_outgoing","[TLS - handshake starting]",0);
- if (SSL_connect(tls_con) <= 0) {
- char errbuf[1024];
-
- sprintf(errbuf,"[TLS - SSL_connect error: %s",
- ERR_error_string(ERR_get_error(),NULL));
-
- if (tn_deb || debses)
- tn_debug(errbuf);
- else if ( ssl_debug_flag )
- printf("%s\r\n",errbuf);
-
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,"ck_ssl_outgoing","[TLS - FAILED]",0);
- netclos();
- return(-1);
- } else {
- tls_active_flag = 1;
- if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER) &&
- !tls_is_krb5(0) ) {
- char *subject = ssl_get_subject_name(tls_con);
-
- if (!subject) {
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
- {
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
-
- auth_finished(AUTH_REJECT);
- return -1;
- } else {
- char prmpt[1024];
- int ok;
- ok = uq_ok("Warning: Server didn't provide a certificate",
- "Continue? (Y/N)", 3, NULL, 0);
- if (!ok) {
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,
- "ck_tn_tls_negotiate","[TLS - FAILED]",0);
- auth_finished(AUTH_REJECT);
- return -1;
- }
- }
- } else if (ssl_check_server_name(tls_con, szHostName)) {
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,
- "ck_tn_tls_negotiate","[TLS - FAILED]",0);
- auth_finished(AUTH_REJECT);
- return -1;
- }
- }
- if (tn_deb || debses)
- tn_debug("[TLS - OK]");
- else if (!quiet)
- printf("[TLS - OK]\r\n");
- debug(F110,"ck_ssl_outgoing","[TLS - OK]",0);
- ssl_display_connect_details(tls_con,0,verbosity);
- }
- }
- /* if we are doing raw SSL then start it now ... */
- else if (ssl_only_flag) {
-#ifndef USE_CERT_CB
- if (!tls_load_certs(ssl_ctx,ssl_con,0))
- return(-1);
-#endif /* USE_CERT_CB */
- if (tn_deb || debses)
- tn_debug("[SSL - handshake starting]");
- else if ( verbosity )
- printf("[SSL - handshake starting]\r\n");
- debug(F110,"ck_ssl_outgoing","[SSL - handshake starting]",0);
- if (SSL_connect(ssl_con) <= 0) {
- if ( ssl_debug_flag ) {
- char errbuf[1024];
-
- sprintf(errbuf,"[SSL - SSL_connect error: %s",
- ERR_error_string(ERR_get_error(),NULL));
- printf("%s\r\n",errbuf);
- }
- if (tn_deb || debses)
- tn_debug("[SSL - FAILED]");
- else if ( verbosity )
- printf("[SSL - FAILED]\r\n");
- debug(F110,"ck_ssl_outgoing","[SSL - FAILED]",0);
- return(-1);
- } else {
- ssl_active_flag = 1;
-
- if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER) &&
- !tls_is_krb5(0)) {
- char *subject = ssl_get_subject_name(ssl_con);
-
- if (!subject) {
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
- {
- if (tn_deb || debses)
- tn_debug("[SSL - FAILED]");
- else if ( verbosity )
- printf("[SSL - FAILED]\r\n");
- debug(F110,"ck_tn_tls_negotiate","[SSL - FAILED]",0);
-
- auth_finished(AUTH_REJECT);
- return -1;
- } else {
- char prmpt[1024];
- int ok;
- ok = uq_ok("Warning: Server didn't provide a certificate",
- "Continue? (Y/N)", 3, NULL, 0);
- if (!ok) {
- if (tn_deb || debses)
- tn_debug("[SSL - FAILED]");
- else if ( verbosity )
- printf("[SSL - FAILED]\r\n");
- debug(F110,
- "ck_tn_tls_negotiate","[SSL - FAILED]",0);
- auth_finished(AUTH_REJECT);
- return -1;
- }
- }
- } else if (ssl_check_server_name(ssl_con, szHostName)) {
- if (tn_deb || debses)
- tn_debug("[SSL - FAILED]");
- else if ( verbosity )
- printf("[SSL - FAILED]\r\n");
- debug(F110, "ck_tn_tls_negotiate","[SSL - FAILED]",0);
- auth_finished(AUTH_REJECT);
- return -1;
- }
- }
- if (tn_deb || debses)
- tn_debug("[SSL - OK]");
- else if (!quiet)
- printf("[SSL - OK]\r\n");
- debug(F110,"ck_ssl_outgoing","[SSL - OK]",0);
- ssl_display_connect_details(ssl_con,0,verbosity);
- }
- }
- return(0); /* success */
-}
-
-#ifndef NOHTTP
-int
-ck_ssl_http_client(fd, hostname) int fd; char * hostname;
-{
- int timo = 2000;
-
- if ( !ck_ssleay_is_installed() )
- return(-1);
-
- setverbosity();
-
- /* bind in the network descriptor */
- SSL_set_fd(tls_http_con,fd);
-
- /* If we are doing raw TLS then start it now ... */
- if (1) {
-#ifndef USE_CERT_CB
- if (!tls_load_certs(tls_http_ctx,tls_http_con,0)) {
- debug(F110,"ck_ssl_http_client","tls_load_certs() failed",0);
- return(-1);
- }
-#endif /* USE_CERT_CB */
- if (tn_deb || debses)
- tn_debug("[TLS - handshake starting]");
- else if (verbosity)
- printf("[TLS - handshake starting]\r\n");
- debug(F110,"ck_ssl_outgoing","[TLS - handshake starting]",0);
- if (SSL_connect(tls_http_con) <= 0) {
- char errbuf[1024];
-
- sprintf(errbuf,"[TLS - SSL_connect error: %s",
- ERR_error_string(ERR_get_error(),NULL));
-
- if (tn_deb || debses)
- tn_debug(errbuf);
- else if ( ssl_debug_flag )
- printf("%s\r\n",errbuf);
-
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,"ck_ssl_http_client","[TLS - FAILED]",0);
- http_close();
- return(-1);
- } else {
- tls_http_active_flag = 1;
- if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER) &&
- !tls_is_krb5(3) ) {
- char *subject = ssl_get_subject_name(tls_http_con);
-
- if (!subject) {
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
- {
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
- return -1;
- } else {
- char prmpt[1024];
- int ok;
- ok = uq_ok("Warning: Server didn't provide a certificate",
- "Continue? (Y/N)", 3, NULL, 0);
- if (!ok) {
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,
- "ck_tn_tls_negotiate","[TLS - FAILED]",0);
- return -1;
- }
- }
- } else if (ssl_check_server_name(tls_http_con, hostname)) {
- if (tn_deb || debses)
- tn_debug("[TLS - FAILED]");
- else if ( verbosity )
- printf("[TLS - FAILED]\r\n");
- debug(F110,
- "ck_tn_tls_negotiate","[TLS - FAILED]",0);
- return -1;
- }
- }
-
- printf("[TLS - OK]\r\n");
- if (tn_deb || debses)
- tn_debug("[TLS - OK]");
- debug(F110,"ck_ssl_outgoing","[TLS - OK]",0);
- ssl_display_connect_details(tls_http_con,0,verbosity);
- }
- }
- return(0); /* success */
-}
-#endif /* NOHTTP */
-int
-ck_ssl_renegotiate_ciphers()
-{
-
- if ( !ck_ssleay_is_installed() )
- return(0);
-
- if ( !sstelnet )
- return(0);
-
- if ( ssl_active_flag )
- return SSL_renegotiate(ssl_con);
- else if ( tls_active_flag )
- return SSL_renegotiate(tls_con);
- return(0);
-}
-
-#ifdef NT
-int
-ck_X509_save_cert_to_user_store(X509 *cert)
-{
-#ifdef X509V3_EXT_DUMP_UNKNOWN
- char path[CKMAXPATH];
- char hash[16];
- char * GetAppData(int);
- BIO * out=NULL;
-
- if ( cert == NULL )
- return(0);
-
- sprintf(hash,"%08lx",X509_subject_name_hash(cert));
- ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/certs/",
- hash,".0");
-
-
- out=BIO_new(BIO_s_file());
- if (out == NULL)
- {
- ERR_print_errors(bio_err);
- return(0);
- }
- if (BIO_write_filename(out,path) <= 0) {
- perror(path);
- return(0);
- }
-
- X509_print_ex(out, cert, XN_FLAG_SEP_MULTILINE, X509V3_EXT_DUMP_UNKNOWN);
- if (!PEM_write_bio_X509(out,cert)) {
- BIO_printf(bio_err,"unable to write certificate\n");
- ERR_print_errors(bio_err);
- BIO_free_all(out);
- return(0);
- }
- BIO_free_all(out);
- return(1);
-#else /* X509V3_EXT_DUMP_UNKNOWN */
- return(0);
-#endif /* X509V3_EXT_DUMP_UNKNOWN */
-}
-#endif /* NT */
-
-#ifndef OS2
-/* The following function should be replaced by institution specific */
-/* code that will convert an X509 cert structure to a userid for the */
-/* purposes of client to host login. The example code included */
-/* simply returns the UID field of the Subject if it exists. */
-
-/* X509_to_user() returns 0 if valid userid in 'userid', else -1 */
-int
-X509_to_user(X509 *peer_cert, char *userid, int len)
-{
-#ifdef X509_UID_TO_USER
- /* BEGIN EXAMPLE */
- int err;
-
- if (!(peer_cert && userid) || len <= 0)
- return -1;
-
- userid[0] = '\0';
- debug(F110,"X509_to_user() subject",
- X509_NAME_oneline(X509_get_subject_name(peer_cert),NULL,0),0);
-
- /* userid is in cert subject /UID */
- err = X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
-#ifndef NID_x500UniqueIdentifier
- NID_uniqueIdentifier,
-#else
- NID_x500UniqueIdentifier,
-#endif
- userid, len);
-
- debug(F111,"X509_to_user() userid",userid,err);
- if (err > 0)
- return 0;
-
- /* END EXAMPLE */
-#else /* X509_UID_TO_USER */
-#ifdef X509_SUBJECT_ALT_NAME_TO_USER
- /* BEGIN EXAMPLE */
- int i;
- X509_EXTENSION *ext = NULL;
- STACK_OF(GENERAL_NAME) *ialt = NULL;
- GENERAL_NAME *gen = NULL;
- char email[256];
-
- if (!(peer_cert && userid) || len <= 0)
- return -1;
-
- userid[0] = '\0';
- email[0] = '\0';
- debug(F110,"X509_to_user() subject",
- X509_NAME_oneline(X509_get_subject_name(peer_cert),NULL,0),0);
-
- if ((i = X509_get_ext_by_NID(peer_cert, NID_subject_alt_name, -1))<0)
- return -1;
- if (!(ext = X509_get_ext(peer_cert, i)))
- return -1;
- X509V3_add_standard_extensions();
- if (!(ialt = X509V3_EXT_d2i(ext)))
- return -1;
- for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
- gen = sk_GENERAL_NAME_value(ialt, i);
- if (gen->type == GEN_DNS) {
- if (!gen->d.ia5 || !gen->d.ia5->length)
- break;
- if (strlen(gen->d.ia5->data) != gen->d.ia5->length) {
- /* Ignoring IA5String containing null character */
- continue;
- }
- if ( gen->d.ia5->length + 1 > sizeof(email) ) {
- goto cleanup;
- }
- memcpy(email, gen->d.ia5->data, gen->d.ia5->length);
- email[gen->d.ia5->length] = 0;
- break;
- }
- }
- cleanup:
- X509V3_EXT_cleanup();
- if (ialt)
- sk_GENERAL_NAME_free(ialt);
-
- debug(F110,"X509_to_user() email",email,0);
-
- if ( email[0] ) {
- char * domain = NULL;
-
- /* Find domain */
- for ( i=0 ; email[i] ; i++ ) {
- if ( email[i] == '@' ) {
- email[i] = '\0';
- domain = &email[i+1];
- break;
- }
- }
-
- if ( domain ) {
- /* XXX - Put code to Verify domain here */
-
- if ( /* domain is okay */ 1 )
- ckstrncpy(userid,email,len);
- }
- }
-
- return(userid[0] ? 0 : -1);
- /* END EXAMPLE */
-#endif /* X509_SUBJECT_ALT_NAME_TO_USER */
-#endif /* X509_UID_TO_USER */
- return -1;
-}
-
-/* The following function should be replaced by institution specific */
-/* code that will determine whether or not the combination of the */
-/* provided X509 certificate and username is valid for automatic */
-/* login. Whereas X509_to_user() is used to provide authentication */
-/* of the user, the X509_userok() function is used to provide */
-/* authorization. The certificate passed into X509_userok() does */
-/* need to map to a userid; nor would the userid it would map to */
-/* need to match the userid provided to the function. There are */
-/* numerous circumstances in which it is beneficial to have the ability */
-/* for multiple users to gain access to a common account such as */
-/* 'root' on Unix; or a class account on a web server. In Unix we */
-/* implement this capability with the ~userid/.tlslogin file which */
-/* a list of X509 certificates which may be used to access the */
-/* account 'userid'. */
-
-/* X509_to_user() returns 0 if access is denied; 1 is access is permitted */
-int
-X509_userok(X509 * peer_cert, const char * userid)
-{
-#ifndef VMS
- /* check if clients cert is in "user"'s ~/.tlslogin file */
- char buf[512];
- int r = 0;
- FILE *fp;
- struct passwd *pwd;
- X509 *file_cert;
-
- if ( peer_cert == NULL )
- return(0);
-
- if (!(pwd = getpwnam(userid)))
- return 0;
- if (strlen(pwd->pw_dir) > 500)
- return(0);
- sprintf(buf, "%s/.tlslogin", pwd->pw_dir);
-
- if (!(fp = fopen(buf, "r")))
- return 0;
- while (!r && (file_cert = PEM_read_X509(fp, NULL, NULL, NULL))) {
- if (!ASN1_STRING_cmp(peer_cert->signature, file_cert->signature))
- r = 1;
- X509_free(file_cert);
- }
- fclose(fp);
- return(r);
-#else /* VMS */
- /* Need to implement an appropriate function for VMS */
- return(0);
-#endif /* VMS */
-}
-#endif /* OS2 */
-#endif /* CK_SSL */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ck_ssl.h b/ckermit-9.0.302-build/ckermit-9.0.302/ck_ssl.h
deleted file mode 100644
index 97b6544..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ck_ssl.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- C K _ S S L . H -- OpenSSL Interface Header for C-Kermit
-
- Copyright (C) 1985, 2005,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Author: Jeffrey E Altman (jaltman@secure-endpoints.com)
- Secure Endpoints Inc., New York City
-*/
-
-#ifdef CK_SSL
-#ifndef CK_ANSIC
-#define NOPROTO
-#endif /* CK_ANSIC */
-
-#ifdef COMMENT /* Not for C-Kermit 7.1 */
-#ifdef KRB5
-#ifndef NOSSLK5
-#ifndef SSL_KRB5
-#define SSL_KRB5
-#endif /* SSL_KRB5 */
-#endif /* NOSSLK5 */
-#endif /* KRB5 */
-#endif /* COMMENT */
-
-#ifdef OS2
-#ifndef ZLIB
-#define ZLIB
-#endif /* ZLIB */
-#endif /* OS2 */
-
-#ifdef ZLIB
-#include <openssl/comp.h>
-#endif /* ZLIB */
-/* We place the following to avoid loading openssl/mdc2.h since it
- * relies on the OpenSSL des.h. Since we do not need the MDC2
- * definitions there is no reason to have it included by openssl/evp.h
- */
-#define OPENSSL_NO_MDC2
-#ifdef OPENSSL_100
-#define OPENSSL_098
-#endif /* OPENSSL_100 */
-#ifdef OPENSSL_098
-#define OPENSSL_097
-#endif /* OPENSSL_098 */
-#ifdef CK_DES
-#include <openssl/des.h>
-#endif /* CK_DES */
-#include <openssl/ssl.h>
-#include <openssl/x509v3.h>
-#include <openssl/rand.h>
-#include <openssl/x509_vfy.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/bn.h>
-#include <openssl/blowfish.h>
-#include <openssl/dh.h>
-#include <openssl/rc4.h>
-#include <openssl/cast.h>
-#include <openssl/dsa.h>
-#include <openssl/rsa.h>
-#include <openssl/md5.h>
-#include <openssl/sha.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#ifdef SSL_KRB5
-#include <openssl/kssl.h>
-#endif /* SSL_KRB5 */
-
-extern BIO *bio_err;
-extern SSL *ssl_con;
-extern SSL_CTX *ssl_ctx;
-extern int ssl_debug_flag;
-extern int ssl_only_flag;
-extern int ssl_active_flag;
-extern int ssl_verify_flag;
-extern int ssl_verbose_flag;
-extern int ssl_certsok_flag;
-extern int ssl_dummy_flag;
-extern int ssl_verify_depth;
-
-extern char *ssl_rsa_cert_file;
-extern char *ssl_rsa_cert_chain_file;
-extern char *ssl_rsa_key_file;
-extern char *ssl_dsa_cert_file;
-extern char *ssl_dsa_cert_chain_file;
-extern char *ssl_dh_key_file;
-extern char *ssl_cipher_list;
-extern char *ssl_crl_file;
-extern char *ssl_crl_dir;
-extern char *ssl_verify_file;
-extern char *ssl_verify_dir;
-extern char *ssl_dh_param_file;
-extern char *ssl_rnd_file;
-
-extern SSL_CTX *tls_ctx;
-extern SSL *tls_con;
-extern int tls_only_flag;
-extern int tls_active_flag;
-extern int x509_cert_valid;
-extern X509_STORE *crl_store;
-
-extern int ssl_raw_flag;
-extern int tls_raw_flag;
-
-#ifndef NOHTTP
-extern SSL_CTX *tls_http_ctx;
-extern SSL *tls_http_con;
-extern int tls_http_active_flag;
-#endif /* NOHTTP */
-
-extern int ssl_initialized;
-
-_PROTOTYP(VOID ssl_once_init,(void));
-_PROTOTYP(int ssl_tn_init,(int));
-_PROTOTYP(int ssl_http_init,(char *));
-_PROTOTYP(int ck_ssl_http_client,(int,char *));
-_PROTOTYP(int ssl_display_connect_details,(SSL *,int,int));
-_PROTOTYP(int ssl_server_verify_callback,(int, X509_STORE_CTX *));
-_PROTOTYP(int ssl_client_verify_callback,(int, X509_STORE_CTX *));
-_PROTOTYP(int ssl_reply,(int, unsigned char *, int));
-_PROTOTYP(int ssl_is,(unsigned char *, int));
-_PROTOTYP(int ck_ssl_incoming,(int));
-_PROTOTYP(int ck_ssl_outgoing,(int));
-_PROTOTYP(int tls_is_user_valid,(SSL *, const char *));
-_PROTOTYP(char * ssl_get_dnsName,(SSL *));
-_PROTOTYP(char * ssl_get_commonName,(SSL *));
-_PROTOTYP(char * ssl_get_issuer_name,(SSL *));
-_PROTOTYP(char * ssl_get_subject_name,(SSL *));
-_PROTOTYP(int ssl_get_client_finished,(char *, int));
-_PROTOTYP(int ssl_get_server_finished,(char *, int));
-_PROTOTYP(int ssl_passwd_callback,(char *, int, int, VOID *));
-_PROTOTYP(VOID ssl_client_info_callback,(const SSL *,int, int));
-_PROTOTYP(int ssl_anonymous_cipher,(SSL * ssl));
-_PROTOTYP(int tls_load_certs,(SSL_CTX * ctx, SSL * con, int server));
-_PROTOTYP(int ssl_verify_crl,(int, X509_STORE_CTX *));
-_PROTOTYP(int tls_is_krb5,(int));
-_PROTOTYP(int X509_userok,(X509 *,const char *));
-_PROTOTYP(int ck_X509_save_cert_to_user_store,(X509 *));
-/* SMS 2007/02/15 */
-_PROTOTYP(int ssl_check_server_name,(SSL * ssl, char * hostname));
-#ifdef OS2
-#include "ckosslc.h"
-#include "ckossl.h"
-#endif /* OS2 */
-
-#define SSL_CLIENT 0
-#define SSL_SERVER 1
-#define SSL_HTTP 2
-
-#define SSL_ERR_BFSZ 4096
-
-#ifdef SSL_KRB5
-#define DEFAULT_CIPHER_LIST "HIGH:MEDIUM:LOW:+KRB5:+ADH:+EXP"
-#else
-#define DEFAULT_CIPHER_LIST "HIGH:MEDIUM:LOW:+ADH:+EXP"
-#endif /* SSL_KRB5 */
-#endif /* CK_SSL */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckaaaa.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckaaaa.txt
deleted file mode 100644
index 335ec7d..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckaaaa.txt
+++ /dev/null
@@ -1,380 +0,0 @@
-ckaaaa.txt July 2011
-
- C-KERMIT VERSION 9.0.301
- OVERVIEW OF FILES
-
- Communications software for UNIX and (Open)VMS.
-
- And in former versions also for:
- Stratus VOS, AOS/VS, QNX,
- Plan 9, OS-9, Apollo Aegis, and the Commodore Amiga.
- The Apple Macintosh, the Atari ST.
-
- The Kermit Project - Columbia University
-
- http://kermit.columbia.edu/ - kermit@columbia.edu
-
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
- BRIEFLY: C-Kermit 9.0 has the OPEN SOURCE 3-clause MODIFIED BSD LICENSE.
-
-
-DOCUMENTATION
-
- C-Kermit is documented in the book "Using C-Kermit", Second Edition, by
- Frank da Cruz and Christine M. Gianone, Digital Press, ISBN 1-55558-164-1,
- supplemented by Web-based updates for C-Kermit 7.0, 8.0, and 9.0.
-
-PLATFORMS
- Security
- Name Included Last Updated
-
- Unix Yes 9.0.300 30 Jun 2011
- (Open)VMS Yes 9.0.300 30 Jun 2011
- Windows (K95) Yes 8.0.208 14 Mar 2003 (K95 2.1)
- OS/2 (K95) Yes 8.0.208 14 Mar 2003 (K95 2.1)
- DG AOS/VS No 7.0.196 1 Jan 2000
- Stratus VOS No 7.0.196 1 Jan 2000
- Bell Plan 9 No 7.0.196 1 Jan 2000
- Microware OS-9 No 7.0.196 1 Jan 2000
- Commodore Amiga No 7.0.196 1 Jan 2000
- Macintosh No 5A(190) 16 Aug 1994 (Mac Kermit 0.991)
- Atari ST No 5A(189) 30 Jun 1993
-
-QUICK START FOR FTP USERS
-
- If you have a Web browser, go to:
-
- http://www.columbia.edu/kermit/ckermit.html
-
- And take it from there. Otherwise...
-
- The definitive FTP source for Kermit software is kermit.columbia.edu.
- Kermit software obtained from other FTP sites is not necessarily complete
- or up to date, and may have been modified.
-
-C-Kermit for UNIX computers that have a C compiler and 'make' program:
-
- Directory kermit/archives, binary mode, file cku211.tar.Z or cku211.tar.gz
-
- This is a compressed tar archive of UNIX C-Kermit source code, makefile, and
- other files. It unpacks into its current directory, so download it into a
- fresh directory. Transfer in binary mode, uncompress (or gunzip), untar (tar
- xvf cku211.tar), and then give the appropriate "make" command to build for
- your UNIX system; read the comments in the makefile and ckuins.txt for
- further info.
-
-C-Kermit for VMS:
-
- If you have VMS UNZIP, get the file kermit/archives/ckv211.zip in binary
- mode, unzip -aa, and build with CKVKER.COM (@ckvker.com). Read the comments
- at the top of CKVKER.COM for details.
-
-Others: In the kermit/f or kermit/test directories under the appropriate
-prefixes, explained below.
-
-
-INSTALLATION
-
-Installation procedures depend on the operating system. Please read the
-CK?INS.TXT, if any, file for your operating system (?=U for UNIX, V for VMS,
-etc). Please note the naming and placement for the initialization files:
-
- CKERMIT.INI
- .kermrc in the user's home directory (UNIX).
- CKERMIT.INI in the user's home directory (other OS's).
-
-
- CKERMOD.INI
- .mykermrc in the user's home directory (UNIX).
- CKERMOD.INI elsewhere.
-
- DIALING DIRECTORIES
- Dialing directory files can be system-wide, per-group, or per-user, or
- any combination. For example, there can be a corporate wide directory
- shared by all users, a supplemental directory for each division or
- department, and a personal directory for each user. Simply be sure the
- dialing directory files are identified a SET DIAL DIRECTORY command in
- the user's (or the system-wide) C-Kermit initialization file, or in the
- environment variable (logical name, symbol) K_DIAL_DIRECTORY. (The
- standard initialization file looks by default in the user's home or login
- directory.) When installing C-Kermit on multiuser platforms from which
- users will dial out, you can also set environment variables for area
- code, country code, and the various dialing prefixes as described on page
- 478 of "Using C-Kermit" (second edition), so users don't have to worry
- about defining these items themselves. Network directories and service
- directories can also be set up in a similar manner.
-
- DOCUMENTATION
- In UNIX, the general C-Kermit man page (or one of the versions tailored
- for a specific platform, like HP-UX or Solaris) should be installed in
- the appropriate place. In VMS, the VMS help topic (CKVKER.HLP) should
- be installed as described in CKVINS.TXT. Plain-text documentation such
- as CKERMIT2.TXT should be put in whatever place people are accustomed
- to looking.
-
-FILES AND FILE NAMING CONVENTIONS
-
-C-Kermit is a family of Kermit programs for many different computer systems.
-The program shares a common set of system-independent file transfer protocol
-modules, written in the C language. System-dependent operations are collected
-into system-specific modules for each system.
-
-C-Kermit file names all start with the letters "CK", followed by a single
-letter indicating the subgroup. When referring to these files in the UNIX,
-AOS/VS, or VOS environments, use lowercase letters, rather than the uppercase
-letters shown here. Subgroups:
-
- _: Security/Authentication/Encryption code, possibly regulated by law
- a: General descriptive material and documentation
- b: BOO file encoders and decoders (obsolete)
- c: All platforms with C compilers
- d: Data General AOS/VS
- e: Reserved for "ckermit" files, like CKERMIT.INI, CKERMIT80.TXT
- f: (reserved)
- g: (reserved)
- h: (reserved)
- i: Commodore Amiga (Intuition)
- j: (unused)
- k: (unused)
- l: Stratus VOS
- m: Macintosh with Mac OS
- n: Microsoft Windows NT
- o: OS/2 and/or Microsoft Windows 95/98/ME/NT/2000/XP/...
- p: Bell Labs Plan 9
- q: (reserved)
- r: DEC PDP-11 with RSTS/E (reserved)
- s: Atari ST GEMDOS (last supported in version 5A(189))
- t: DEC PDP-11 with RT-11 (reserved)
- u: UNIX or environments with UNIX-like C libraries
- v: VMS and OpenVMS
- w: Wart (Lex-like preprocessor, used with all systems)
- x: (reserved)
- y: (reserved)
- z: (reserved)
- 0-3: (reserved)
- 4: IBM AS/400 (reserved but probably never will be used)
- 5-8: (reserved)
- 9: Microware OS-9
-
-Examples:
-
- ckaaaa.txt - This file
- ckufio.c - File i/o for UNIX
- ckstio.c - Communications i/o for the Atari ST
- makefile - makefile for building UNIX C-Kermit
- ckpker.mk - makefile for building Plan 9 C-Kermit
- ckvker.com - build procedure for VMS C-Kermit
-
-IMPORTANT FILES (use lowercase names on UNIX, VOS, or AOS/VS):
-
- ckaaaa.txt - This file (overview of the C-Kermit files).
- For system-specific distributions, this will normally
- be replaced by a system-specific READ.ME file.
-
- ckermit70.txt - Updates: Supplement to "Using C-Kermit", 2nd Ed, for 7.0.
- ckermit80.txt - Updates: Supplement to "Using C-Kermit", 2nd Ed, for 8.0.
- ckututor.txt - C-Kermit Tutorial for Unix (plain text)
- ckcbwr.txt - "Beware file" (limitations, known bugs, hints), general.
- ckermit.ini - Standard initialization file (rename to .kermrc in UNIX, OS-9)
- ckermod.ini - Sample customization file (rename to .mykermrc in UNIX, OS-9)
-
-The following can be found at the Kermit FTP site:
-
- ckermit.kdd - Sample dialing directory file (rename to .kdd in UNIX, OS-9)
- ckermit.knd - Sample dialing directory file (rename to .knd in UNIX, OS-9)
- ckermit.ksd - Sample services directory file (rename to .ksd in UNIX, OS-9)
- ckedemo.ksc - Demonstration macros from "Using C-Kermit"
- ckepage.ksc - Ditto
- ckevt.ksc - Ditto
-
-UNIX-specific files:
-
- ckuins.txt - UNIX-specific installation instructions.
- ckubwr.txt - UNIX-specific beware file.
- ckuker.nr - "man page" for UNIX.
-
-VMS-specific files:
-
- ckvins.txt - VMS-specific installation instructions.
- ckvbwr.txt - VMS-specific beware file
- ckvker.hlp - VMS C-Kermit HELP topic (needs updating).
-
-DG AOS/VS-specific files:
-
- ckdins.txt - Data General AOS/VS C-Kermit installation instructions
- ckdbwr.txt - AOS/VS "beware" file
- ckd*.cli - Procedures for building AOS/VS C-Kermit
-
-The following files are of interest mainly to programmers and historians
-(find them at the Kermit ftp site in the kermit/f directory):
-
- ckcker.ann - Release announcements.
- ckccfg.txt - Configuration information (feature selection), general.
- ckcplm.txt - Program logic manual (for programmers).
- ckc300.txt - Program update history for edit 212-300 (C-Kermit 9.0).
- ckc211.txt - Program update history for edit 201-211.
- ckc200.txt - Program update history for edit 198-200 (big)
- ckc197.txt - Program update history for edit 195-197 (big)
- ckc190.txt - Program update history for edits 189-190 (big).
- ckc188.txt - Program update history, edits 179-188 (big).
- ckc178.txt - Program edit history, 5A edits through 178 (very big).
- ckcv4f.txt - Program edit history, version 4F.
- ckcv4e.txt - Program edit history, version 4E.
-
-BINARIES
-
-If you have FTP access to kermit.columbia.edu (also known as
-kermit.cc.columbia.edu, ftp.cc.columbia.edu), you can also retrieve various
-C-Kermit binaries from the directory kermit/bin/ck*.*, or more conveniently
-from the web page:
-
- http://www.columbia.edu/kermit/ck80binaries.html
-
-Test versions would be in kermit/test/bin/ck*.*. Be sure to transfer these
-files in binary mode. The READ.ME file in that directory explains what's
-what.
-
-SOURCE FILES
-
-The source files for the UNIX version (all UNIX versions) are available in
-kermit/archives/ckuNNN.tar.Z, approximately 1MB in size. Transfer this file
-in binary mode. This is a compressed tar archive. There is also a gzip'd
-version, cku211.tar.gz. To get the binary tar archive:
-
- mkdir kermit (at shell prompt, make a Kermit directory)
- cd kermit (make it your current directory)
-
- ftp kermit.columbia.edu (make an ftp connection)
- user: anonymous (log in as user "anonymous", lower case!)
- password: (use your email id as a password)
- cd kermit/archives (go to the archives directory)
- type binary (specify binary file transfer)
- get cku300.tar.Z (get the tar archive) (or get cku192.tar.gz)
- bye (disconnect and exit from ftp)
-
- uncompress cku300.tar.Z (at the shell prompt, uncompress the archive)
- tar xvf cku300.tar (extract the files from the tar archive)
- make xxx (build C-Kermit for your system)
-
-(where "xxx" is the makefile entry appropriate for your system.)
-
-All C-Kermit source and other text files are also kept separately in the
-kermit/f directory. The files necessary to build a particular implementation
-of C-Kermit are listed in the appropriate makefile or equivalent:
-
- UNIX: makefile (or rename ckuker.mak to makefile)
- 2.11 BSD: ckubs2.mak (rename to makefile), ckustr.sed
- Plan 9: ckpker.mk (rename to mkfile)
- Macintosh: ckmker.mak (rename to kermit.make, use MPW C 3.2)
- VMS: CKVKER.COM (DCL) (and optionally also CKVKER.MMS)
- or CKVOLD.COM (for VMS 4.x)
- Amiga: CKIKER.MAK (Aztec C) or CKISAS.MAK (SAS C)
- Atari ST: CKSKER.MAK
- OS-9: ck9ker.mak or ck9ker.gcc
- AOS/VS: ckdmak.cli, ckdcc.cli, ckdlnk.cli
-Stratus VOS: cklmak.cm
-
-Minimal source files for building selected versions (these patterns get all
-the files you need, and in some cases maybe a few extra):
-
- UNIX: ck[cuw]*.[cwh] (including QNX, Plan 9, and BeBox)
- UNIX: ck[cuw_]*.[cwh] (Unix with security modules)
- VMS: ck[cuwv]*.[cwh] VMS
- VMS: ck[cuwv_]*.[cwh] VMS with SSL/TLS
- Mac: ck[cuwm]*.[cwhr] Old Mac OS, not Mac OS X, which is UNIX.
- AOS/VS: ck[cuwd]*.[cwh]
- VOS: ck[cwhl]*.[cwh]
- Amiga: ck[cuwi]*.[cwh]
- Atari: ck[cuws]*.[cwh]
- OS-9: ck[cuw9]*.[cwha]
-
-Finally, here is a more detailed description of the C-Kermit file naming
-conventions. A C-Kermit filename has the form:
-
- CK<system><what>.<type>
-
-where:
-
-<system> is described earlier in this file;
-
-<type> is the file type (use lowercase on UNIX, VOS, or AOS/VS):
-
- c: C language source
- h: Header file for C language source
- w: Wart preprocessor source, converted by Wart (or Lex) to a C program
- r: Macintosh resource file (8-bit text)
- a: Assembler source
-
- txt: Plain text.
- nr: Nroff/Troff text formatter source for UNIX "man page"
- mss: Scribe text formatter source
- ps: Typeset material to be printed on a PostScript printer
- pdf: An Adobe PDF file
- hlp: A VMS Help topic
-
- ini: Initialization file
- ksc: A Kermit Script to be executed by the TAKE command
- kdd: A Kermit Dialing Directory
- knd: A Kermit Network Directory
- ksd: A Kermit Services Directory
-
- mak: A Makefile or other build procedure (often needs renaming)
- com: (VMS only) a DCL command procedure
- cli: (AOS/VS only) a command procedure
- cmd: (OS/2 only) a Rexx command procedure
-
- boo: "boo"-encoded executable program, decode with CKBUNB program.
- hex: "hex"-encoded executable program, decode with CKVDEH program (VMS only).
- hqx: BinHex'd Macintosh Kermit program, decode with BinHex version 4.0.
- uue: A uuencoded binary file, decode with uudecode or (DG only) CKDECO.
-
- def: An OS/2 linker definitions file.
- sh: A UNIX shell script.
- sed: A UNIX sed (editor) script.
- str: A file of character strings extracted from C-Kermit (BSD 2.1x only).
-
-<what> is mnemonic (up to 3 characters) for what's in the file:
-
-NOTE: After C-Kermit 6.0, text filetypes such as .DOC and .HLP were changed
-to .TXT to avoid confusion in Windows-based Web browsers, which would
-otherwise mistake them for Microsoft Word or Windows Help documents.
-
- aaa: A "read-me" file, like this one
- ins: Installation instructions or procedures
- bwr: "Beware" file -- things to watch out for, hints and tips
- plm: Program Logic Manual
- ker: General C-Kermit definitions, information, documentation
-
- nnn: Digits: C-Kermit edit number (e.g. cku300.tar.gz)
- cmd: Command parsing
- con: CONNECT command
- cns: CONNECT command (UNIX only - version that uses select(), not fork())
- deb: Debug/Transaction Log formats, Typedefs
- dia: Modem/Dialer control
- fio: System-dependent File I/O
- fns: Protocol support functions
- fn2: More protocol support functions (and FN3, ...)
- lib: Common library routines module
- mai: Main program
- net: Network i/o module
- pro: Protocol
- scr: SCRIPT command
- tel: Telnet protocol module
- tio: System-dependent communications i/o & control and interrupt handing
- sig: Signal handling module
- usr: Interactive/script user interface
- us2: More user interface (mainly help text)
- us3: Still more user interface (and USR4, USR5, USR6, USR7)
- usx: Common user interface functions
- usy: Command-line parsing
- xla: Character set translation module
- uni: Unicode support
- pty: Pseudoterminal support
- mdb: Malloc-debugging module (not included in real builds)
- str: Strings module (only for 2.xBSD)
-
-(End of ckaaaa.txt)
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckc302.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckc302.txt
deleted file mode 100644
index 13a661a..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckc302.txt
+++ /dev/null
@@ -1,7881 +0,0 @@
-C-KERMIT 9.0 CHANGE LOG (Changes since 8.0.207 / K95 2.1.3 January 2003)
-
- Chronological order.
- Go to the bottom to find the newest edits.
-
- F. da Cruz, The Kermit Project, Columbia University, NYC.
- Last update: 28 June 2011.
-
-FTP USER, FTP ACCOUNT, plus the various prompts and switches for FTP username,
-password, and account all neglected to strip quotes, and in most cases quotes
-are necessary to specify a username that contains spaces. ckcftp.c,
-15 Jan 2003.
-
-FTP MPUT f1 f2 f3... gets a parse error if any of the fn's do not match an
-existing file. This is bad for scripts. In doftpput(), cmfdb() looks for
-keywords (switches) or CMIFI. When it hits CMIFI, it exits from the initial
-parse loop and then does additional cmifi()s in a loop until done. The most
-obvious fix is to parse each field with cmfdb(CMIFI,CMFLD), i.e. fall back to
-CMFLD if CMIFI doesn't match anything. Then if CMFLD was used, we don't add
-the filespec to the list. This is a rather big change but it seems to work.
-No error messages or failures happen for non-matching fields, but an error
-message is printed (and the MPUT command fails) if none of the fields match
-any files. This fix got in too late for 2.1.3; workaround: use C-Shell
-like wildcard list (ftp mput "{*.abc,foo.*}"). ckcftp.c, 16 Jan 2003.
-
-GREP did not pass its pattern through the expander, thus variables could
-not be used for patterns. This must have been an oversight -- I can't find
-anything in my notes about it. Fixed in dogrep(): ckuus6.c, 24 Jan 2003.
-
-New makefile target for HP-UX 11.xx with OpenSSL from Tapani Tarvainen.
-makefile, 31 Jan 2003.
-
-From Jeff:
- . Avoid core dump when dereferencing tnc_get_signature(): ckuus4.c.
- . Bump version numbers to 8.0.208, 2.1.4: ckcmai.c.
-
-Added /NOLOGIN to FTP [OPEN]. ckcftp.c, 10 Feb 2003.
-
-Don't dump core if FTP DEBUG is ON and FTP OPEN does not include a service.
-openftp(): ckcftp.c, 10 Feb 2003.
-
-HELP PATTERN text incorrectly identified commands and functions with
-floating and anchored patterns. The corrected lists are:
-Floating: GREP, TYPE /MATCH:, /EXCEPT: patterns, \farraylook(),
-Anchored: IF MATCH, file-matching wildcards, \fsearch(), \frsearch()
-ckuus2.c, 10 Feb 2003.
-
-INPUT n \fpattern(xxx) did not work for case-independent comparisons.
-Fixed in doinput(): ckuus4.c, 10 Feb 2003.
-
-It seems \fpattern() didn't work with MINPUT at all. There was no code to
-handle \fpattern() in the MINPUT parse loop, so it never worked. The code
-had to be totally rewritten to use cmfld() in a loop, rather than cmtxt()
-and then cksplit(). Furthermore, whenever any of the fields was an
-\fjoin(), this had to be split. ckuusr.c, 10 Feb 2003.
-
-Macro replacement via \m() and \fdefinition() does not work as advertised
-(i.e. case sensitively) for associative array elements; e.g. \m(xxx<abc>) is
-treated the same as \m(xxx<ABC>), contrary to section 7.10.10 of the C-Kermit
-7.0 update notes, and to the fact that the two really do exist separately.
-Fixed by adding a static function isaarray(s) which succeeds if s is an
-associative array reference and fails otherwise, and then having \m()
-and \fdef() call mxxlook() (case-sensitive lookup) if isaarray(), otherwise
-(as before) mxlook()). ckuus4.c, 11 Feb 2003.
-
-Fixed FTP OPEN to allow the /USER switch to override SET FTP AUTOLOGIN OFF,
-just as /NOLOGIN overrides SET FTP AUTOLOGIN ON. ckcftp.c, 11 Feb 2003.
-
-In K95, "set key \1234 \27H" (any SET KEY command in which the first char of
-the definition was backslash, and the ONLY character after the backslash
-quantity was an uppercase letter, that letter would be lowercased). Diagnosis:
-xlookup() poking its argument (see notes from July 2000). Jeff sent a fix.
-ckucmd.c, 15 Feb 2003.
-
-Ran my S-Expression torture test to make sure Sexps still worked. They do,
-except the bitwise & and | operators were broken, e.g. (& 7 2) and (| 1 2 4)
-get "Invalid operand" errors. Jeff's code had added an early failure return
-from the lookup loop when when a single-byte keyword matched a keyword that
-started with the same byte but was more than one byte long. So "&" would hit
-"&&" and fail instead of continuing its search (xlookup tables aren't sorted
-so there can be no early return). Fixed in xlookup(): ckucmd.c, 16 Feb 2003.
-
-Got rid of "krbmit" target from makefile. It's still there, but we don't
-use it any more. All secure targets now use "xermit", and produce a binary
-called wermit, just like the regular ones do (except the old ckucon.c ones).
-Non-secure targets, since they don't define any of the security symbols,
-wind up compiling and linking to (mostly) empty security modules. makefile,
-15 Feb 2003.
-
-Added \fcvtdate(xxx,3) to format its result in MDTM format (yyyymmddhhmmss,
-all numeric, no spaces or punctuation). Of course these numeric strings
-are too big to be 32-bit numbers and are useless for arithmetic, but they're
-useful for lexical comparison, etc. ckuus[24].c, 16 Feb 2003.
-
-The following FTP commands did not set FAILURE when they failed: RMDIR,
-CD, CDUP, Fixed in the corresponding doftpblah() routines. ckcftp.c,
-16 Feb 2003.
-
-RENAME would sometimes not print an error message when it failed, e.g. in K95
-when the destination file already existed. ckuus6.c, 17 Feb 2003.
-
-Fixed COPY error messages, which did not come out in standard format when
-/LIST was not included. ckuus6.c, 17 Feb 2003.
-
-Fixed #ifdefs in ck_crp.c to allow nonsecure builds on old platforms like
-System V/68 R3. 19 Feb 2003.
-
-Similar treatment for ck_ssl.c. 20 Feb 2003.
-
-From Jeff, 21 Feb 2003:
- . AIX53 and AIX52 symbols for ckcdeb.h, makefile.
- . New gcc targets for various AIX 4.x/5.x versions: makefile.
- . Copyright date updates: ck_crp.c, ck_ssl.c.
- . ENABLE/DISABLE QUERY broken because keyword table out of order: ckuusr.c.
- . Fixed the use of HTTP proxies for HTTP [RE]OPEN for Unix: ckcnet.c.
-
-Also for K95 only: Allow file transfer when K95 is invoked on the remote end
-of a connection to a Pragma Systems Terminal Server connection; automatically
-SET EXIT HANGUP OFF when invoked with open port handle ("k95 -l nnnn").
-
-"cd a*" failed even when "a*" matched only one directory. Fixed in cmifi():
-ckucmd.c, 21 Feb 2003.
-
-In the Unix version, replace "extern int errno;" with "#include <errno.h>"
-if __GLIBC__ is defined, since glibc now defines a thread-specific errno.
-ckcdeb.h, 26 Feb 2003.
-
-Added #ifdefs to skip compilation of ckuath.c in nonsecure builds. Tested
-by building both secure and regular versions in Linux. ckuath.c, 26 Feb 2003.
-
-Ran the build-in-84-different-configurations script on Linux to make sure it
-still builds with all different combinations of feature selection options.
-All OK. 26 Feb 2003.
-
-Built on VMS. Needed to add a prototype for mxxlook*() to ckuusr.h; built
-OK otherwise. 26 Feb 2003.
-
-From Jeff: More #ifdef shuffling for nonsecure builds: ckuath.c, ck_ssl.c,
-27 Feb 2003.
-
-Added code to ensure \v(download) ends in a directory separator in Unix,
-Windows, and OS/2. ckuus7.c, 27 Feb 2003.
-
-Added code to K95 zfnqfp() to tack on directory separator when returning
-a directory name. ckofio.c, 27 Feb 2003.
-
-Somehow an old copy of ckuath.c popped to replace the new one. Put the new
-one back. 28 Feb 2003.
-
-From Jeff: Fix typo in my K95 zfnqfp() code from yesterday; fixes for handling
-UNCs uniformly, no matter which way their slashes are leaning. ckofio.c,
-28 Feb 2003.
-
-At Jeff Mezei's suggestion, separate text and binary mode open sequences
-for VMS session log. ckvfio.c, 28 Feb 2003.
-
-Added freebsd48 target for FreeBSD 4.8. makefile, 1 Mar 2003.
-
-Changed Mac OS X entries to include -DUSE_STRERROR. makefile, 2 Mar 2003.
-
-Fixed GETOK /GUI to evaluate its text argument. ckuus6.c, 3 Mar 2003.
-
-Jeff fixed the K95 Dialer QUICK dialog to (a) allow templates, and (b) have
-a Save-As option. 3 Mar 2003.
-
-Jeff fixed a problem with the Xmodem-CRC checksum being crunched whenever
-there was a retransmission. 7 Mar 2003.
-
-Added target/banner for Tru64 5.1B. makefile, ckuver.h, 5 Mar 2003.
-
-In Unix, the zcopy() routine (used by the COPY command) reset the user's umask
-to 0 for the remainder of the Kermit process lifetime. The bug was in
-ckufio.c 8.0.194, 24 Oct 2002, and is fixed in ckufio.c 8.0.195, 6 Mar 2003.
-Of course this happened after building 155 C-Kermit 8.0.208 binaries. (But
-before officially releasing 8.0.208.)
-
-In the VMS version, changed:
-
- while ((n--) && xx_inc(2) > -1) ;
-to:
- while ((n--) && xx_inc(2) >= 0) ;
-
-to suppress the "...is being compared with a relational operator to a constant
-whose value is not greater than zero" warning. ckvtio.c, 7 Mar 2002.
-
-Added a debug call to dologend in hopes of catching overzealous Locus
-switching, which seems to happen only in K95. ckuus3.c, 7 Mar 2002.
-
-Rebuilt binaries for some of the more current Unix releases: AIX 4.3.3-5.1,
-Solaris 7-9 , Red Hat 7.0-8.0, Slackware 8.1, Freebsd 4.7-4.8, NetBSD 1.6,
-OpenBSD 3.2, Unixware 7.1.3, Open Unix 8, OSR5.0.6a, etc. A Unix binary with
-COPY umask fix shows a 6 Mar 2003 date for "UNIX File support" in SHOW
-VERSIONS; a binary without the fix shows 24 Oct 2002.
-
-C-Kermit 8.0.208 dated 14 March 2003 released on 10 March 2003.
-
----8.0.208---
-
-From Jeff 13 Mar 2003:
- . Updated SSL module allows importation of tickets from host.
- . freebsd50+openssl target: makefile.
- . FTP PUT /PERMISSIONS error message for K95: ckcftp.c.
-
-Fixed MINPUT to strip quotes or braces from around targets (this was broken
-on Feb 10th). Thanks to Jason Heskett for discovering and reporting this
-(killer) bug. ckuusr.c, 14 Mar 2003.
-
-Changed version number to 209 Dev.00. ckcmai.c, 14 Mar 2003.
-
-While debugging the alphapage script, I found that the command "minput 8 \6\13
-\21\13 \13\27\4\13 \30\13" gets "?Not confirmed" in 8.0.208 and 8.0.209, but
-not in 206 and earlier. This problem too was introduced on Feb 10th by
-changing MINPUT parsing from cmtxt() followed by cksplit() to cmfld() in a
-loop. cmfld() uses setatm() to return its result and of course setatm()
-breaks on \13. Changing setatm() not to do this would break everything else.
-But cmfld() has no arguments that let us tell it to do anything different in
-this case. Changing the API would be a disaster. The only solution is to add
-an "MINPUT ACTIVE" (minputactive) global variable that tells cmfld() to tell
-setatm() not to break on CR. Now MINPUT with braced targets containing CR
-and/or LF works in 209, 206, and 201 (but not 208). ckucmd.c, ckuusr.c,
-ckuus5.c, 15 Mar 2003.
-
-MINPUT n \fjoin(&a) works OK if all the members of \&a[] are text strings, but
-if they are strings of control chars (as above), they don't get separated by
-the spaces. For example in:
-
- dcl \&a[] = "\4\5" "\6\7" xxx
- minput 10 \fjoin(&a)
-
-MINPUT gets two targets: "aaa" and "\4\5 \6\7 xxx". The bug was in the
-cksplit() call in the \fjoin() case of MINPUT: it needed to specify an
-include set consisting of all the control characters except NUL. ckuusr.c,
-16 Mar 2003.
-
-But there's still a problem:
-
- dcl \&a[] = "\4\5\13\10" "\6\7" "xxx"
-
-creates an array whose first member is "^D^E (one doublequote included). But
-if braces are used instead, there's no problem. Same deal as MINPUT: cmfld()
-breaks on CR or LF, thus the end quote is lost. If I set minputactive for
-DECLARE initializers too, that fixes it. Is there any reason not to do this?
-Can't think of any (famous last words)... ckuusr.c, 16 Mar 2003.
-
-Since it has multiple applications, changed the flag's name from minputactive
-to keepallchars. ckucmd.c, ckuus[r5].c, 16 Mar 2003.
-
-\v(exedir) wasn't being set correctly (it included the program name as well
-as the directory). Fixed in getexedir(): ckuus4.c, 16 Mar 2003.
-
-SET CARRIER-WATCH <Esc> "auto matic" (spurious space in supplied keyword).
-Cosmetic only; it still worked. Fixed in setdcd(): ckuus3.c, 16 Mar 2003.
-
-"directory a b c" listed too many files -- all files whose names END WITH a,
-b, or c, rather than the files whose names WERE a, b, or c. Diagnosis: The
-filespec is changed into a pattern: {a,b,c}, which is the correct form. It is
-passed to nzxpand(), which goes through the directory getting filenames and
-sending each one to ckmatch() with the given pattern. ckmatch() receives the
-correct pattern but then prepends a "*" -- that's not right. It's not just
-in filename matching either. The following succeeds when it shouldn't:
-
- if match xxxxc {{a,b,c}} <command>
-
-Changing ckmatch() to not prepend the "*" to each segment fixes the command
-above but breaks lots of others. Running through the "match" torture-test
-script shows the problem occurs only when the {a,b,c} list is the entire
-pattern, and not embedded within a larger pattern. Testing for this case
-fixed the problem. ckmatch(): ckclib.c, 16 Mar 2003.
-
-Fixed FTP MODTIME to not print anything if QUIET ON. ckcftp.c, 16 Mar 2003.
-
-Picked up a new ckuath.c from Jeff, not sure what the changes are. 16 Mar 2003.
-
-Did a few regular and secure builds to make sure I didn't wreck anything.
-
-Changed version number to 209 (final). ckcmai.c, 16 Mar 2003.
-
-Jason Heskett found another bug: if you define a macro FOO inside the
-definition of another macro BAR, and FOO's definition includes an odd number
-of doublequotes (such as 1), FOO's definition absorbs the rest of BAR's
-definition. Example:
-
- def TEST {
- .foo = {X"}
- sho mac foo
- }
- do test
- sho mac foo
-
-Results in:
-
- foo = {X"}, sho mac foo
-
-Diagnosis: the TEST definition becomes:
-
- def TEST .foo = {X"}, sho mac foo
-
-and the macro reader is erroneously treating the doublequote as an open
-quote, and then automatically closes the quote at the end of the definition.
-The error is that a doublequote should be significant only at the beginning of
-a field. But the macro reader isn't a command parser; it doesn't know what
-a field is -- it's just looking for commas and skipping over quoted ones.
-First we have to fix an oversight: SET COMMAND DOUBLEQUOTING OFF should have
-worked here, but it wasn't tested in this case. Fixed in getncm(): ckuus5.c,
-17 Mar 2003.
-
-There are only certain cases where it makes sense to treat doublequotes as
-significant:
-
- . An open quote must be at the beginning or preceded by a space.
- . A close quote is only at the end or else followed by a space.
-
-This too was fixed in getncm(): ckuus5.c, 17 Mar 2003.
-
-A fix from Jeff SSL/TLS FTP data decoding. ckcftp.c, 18 Mar 2003.
-
-Tried building C-Kermit on a Cray Y-MP with UNICOS 9.0. "int suspend",
-declared in ckcmai.c and used in many modules, conflicts with:
-
- unistd.h:extern int suspend __((int _Category, int _Id));
-
-The "=Dsuspend=xsuspend" trick doesn't work for this; there is no way around
-the conflict other than to rename the variable: ckcmai.c, ckutio.c,
-ckuus[35xy].c. 26 Mar 2003. VMS and K95 not affected.
-
-OK that gets us past ckcmai.c... Then in ckutio.c I had to add a new #ifdef
-around the LFDEVNO setting, because the Cray didn't have mkdev.h. Could not
-find a Cray-specific manifest symbol, so I made a new makefile target (cray9)
-that sets this symbol. Having done this I have no idea what kind of lockfile
-would be created, but I also doubt if anybody dials out from a Cray. The
-binary should run a C90, J90, or Y-MP. makefile, 26 Mar 2003.
-
-Added a target for SCO OSR5.0.7. makefile, ckuver.h, 30 Mar 2003.
-
-Changed since 208:
-makefile ckuver.h ckcmai.c ckclib.c ckcftp.c ckucmd.c ckuus*.c ckutio.c.
-
----8.0.209---
-
-From Mark Sapiro, a fix for the March 17th doublequote fix, getncm(): ckuus5.c,
-4 Apr 2003.
-
-From Jeff, 29 Apr 2003:
- . Corrected target for HP-UX 11.00 + OpenSSL: makefile,
- . Do not allow WILL AUTH before WONT START_TLS: ckctel.h ckctel.c
- . Add hooks for SFTP and SET/SHOW SFTP: ckcdeb.h ckuusr.h ckuusr.c ckuus3.c
- . Add SKERMIT ckuusr.h ckuusr.c
- . Add ADM-5 terminal emulation: ckuus7.c, ckuus5.c
- . Uncomment and update HELP SET SSH V2 AUTO-REKEY: ckuus2.c
- . Enable IF TERMINAL-MACRO and IF STARTED-FROM-DIALER for C-Kermit: ckuus6.c
- . Fix conflicting NOSCROLL keyword definition: ckuusr.h
- . Set ttname when I_AM_SSH: ckuusy.c
- . Add extended arg parsing for SSH, Rlogin, Telnet: ckuusy.c, ckuus4.c
- . Security updates: ckuath.c, ck_ssl.c
- . Change K95 version number to 2.2.0: ckcmai.c
- . Save K95 term i/o state before executing keyboard macro: ckuus4.c
- . Add tests for SSH Subsystem active during INPUT/OUTPUT/CONNECT: ckuus[45].c
- . Enable K95 SET SSH V2 AUTO-REKEY: ckuus3.c
-
-SFTP and SET SFTP subcommands are implemented up to the case statements.
-
-Files of mine that Jeff hadn't picked up:
- ckuver.h ckcftp.c ckutio.c ckuusx.c (just minor changes for last build-all)
-
-On 4 Jan 2003, SET RECEIVE MOVE-TO was changed to convert is argument to an
-absolute path, which made it impossible to specify a relative path, then
-move to different directories and have it apply relatively to each directory.
-Changed this as follows:
-
- . Parser uses cmtxt() rather than cmdir() so it won't fail at parse time.
- . If path is absolute, we fail at parse time if directory doesn't exist.
- . In reof() we run the the path through xxstring (again, in case deferred
- evaluation of variables is desired) and then, if not null, use it.
- . If the directory doesn't exist, rename() fails and reof() returns -4,
- resulting in a protocol error (this is not a change). We do NOT create
- the directory on the fly.
-
-I also fixed SET SEND/RECEIVE RENAME-TO to parse with cmtxt() rather than
-cmdir(), since it's parsing a text template, not a directory name, e.g.
-"set receive rename-to file-\v(time)-v(date)-\v(pid)". This was totally
-broken, since when I don't know. We don't call xxstring() in this parse, so
-evaluation is always deferred -- I'd better not change this. ckuus7.c,
-ckcfns.c, 1 May 2003.
-
-From Jeff, Sat May 3 14:15:23 2003:
- . Pick up the right isascii definition for K95: ckctel.c
- . malloc... ckuath.c (new safe malloc routines for K95)
- . Add author listing: ckuus5.c
- . SSH Heartbeat support (K95 only): ckuus[23].c
- . Prescan --height and --width to avoid window resizing at startup: ckuusy.c
- . Add checks for fatal() or doexit() called from sysinit(): ckuusx.c
- . Move some K95-specific definitions to ckoker.h: ckcdeb.h
- . Add support for ON_CD macro in zchdir(): ckufio.c
- . Add a command to let FTP client authenticate with SSLv2: ckcftp.c
- . Fix parsing of FTP file facts like "UNIX.mode": ckcftp.c
-
-ON_CD will need some explaining (to be done). It's implemented for Unix,
-VMS, WIndows, and OS/2.
-
-The FTP file facts fix came from first exposure to the new OpenBSD FTP
-server: ftp://ftp7.usa.openbsd.org/pub/os/OpenBSD/3.3/i386/
-The period in "UNIX.mode" caused an erroneous word break, adding junk to
-the filename.
-
-About the malloc changes, Jeff says "K95 is not behaving well in low memory
-environments. I'm not sure that C-Kermit does much better. The program does
-not crash but it certainly does not behave the way the user expects it to.
-I'm beginning to think that any malloc() error should be treated as fatal."
-
-Not visible in these changes because it's in K95-specific modules: Jeff made
-SET ATTRIBUTES OFF and SET ATTRIBUTES DATE OFF apply to XYZMODEM transfers.
-
-From Jeff, 11 May 2003:
- . Add support for SSH Keepalive to relevant SET command (K95): ckuus3.c
- . Reduce max overlapped i/o requests from 30 to 7 (K95): ckuus7.c
- . Don't call sysinit() in fatal(): ckuusx.c.
- . Some new conditionalizations for SSL module: ck_ssl.c
-
-The doublequote-parsing fixes from March and April broke the SWITCH statement,
-which is implemented by internally defining, then executing, a macro. If I
-drop back to the old dumb handling of doublequotes, everything is fixed except
-the problem of March 17th. But can we really expect getncm() to pre-guess
-what the parser is going to do? getncm()'s only job is to find command
-boundaries, which are represented by commas. Commas, however, is needed IN
-commands too. We take a comma literally if it is quoted with \, or is inside
-a matched pair of braces, parens, or doublequotes. It is not unreasonable to
-require a doublequote in a macro definition to be prefixed by \ when it is to
-be taken literally. The proper response to Jason Heskett's complaint of March
-17th should have been to leave the code alone and recommand an appropriate
-form of quoting:
-
- def TEST {
- .foo = {X\"}
- sho mac foo
- }
-
-And this is what I have done. Another reason for sticking with the old method
-is that it's explainable. The "improved" method, even if it worked, would be
-be impossible to explain. Btw, in testing this I noticed that the switch-test
-script made 8.0.201 dump core. Today's version is fine. The problem with
-quoted strings inside of IF {...} clauses and FOR and WHILE loops is fixed
-too. Perhaps "unbroken" would be a better word. ckuus5.c, 11 May 2003.
-
-Vace discovered that FTP MGET /EXCEPT:{... (with an unterminated /EXCEPT list)
-could crash Kermit. Fixed in ckcftp.c, 11 May 2003.
-
-CONTINUE should not affect SUCCESS/FAILURE status. ckuusr.c, 11 May 2003.
-
-Fixed an oversight that goes back 15 years. While \{123} is allowed for
-decimal codes, \x{12} and \o{123} were never handled. ckucmd.c, 11 May 2003.
-
-Added support for Red Hat <baudboy.h> and /usr/sbin/lockdev. Supposedly this
-allows Kermit to be installed without setuid or setgid bits and still be able
-to lock and use the serial device. Compiles and starts, but not tested.
-ckcdeb.h, makefile, ckutio.c, ckuus5.c, 16 May 2003.
-
-From Jeff: FTP ASCII send data to host when FTP /SSL was in use was broken.
-ftp_dpl is set to Clear when FTP /SSL is in use. This was causing the data to
-be written to the socket with send() instead of the OpenSSL routines.
-ckcftp.c, ckuath.c, 21 May 2003.
-
-From Jeff: Stuff for Kerberos 524: ckcdeb.h. Fixes for FTP; "FTP ASCII send
-data did not properly compute the end of line translations. On Unix (and
-similar platforms) the end of line was correct for no character sets but
-incorrect when character sets were specified. On Windows/OS2, the end of line
-was correct when character sets were specified and incorrect when they were
-not. On MAC, both were broken. Also, FTP Send Byte counts were incorrect
-when character sets were specified." ckcftp.c. 17 Jun 2003.
-
-From Jeff: fixes to HTTP /AGENT: and /USER: switch action: ckcnet.c ckuus3.c
-ck_crp.c ckcftp.c ckuus2.c ckuusy.c ckuusr.c ckcnet.h, 21 Jun 2003.
-
-From Jeff: Fix SET DIALER BACKSPACE so it can override a previous SET KEY
-(e.g. from INI file): ckuus7.c. Some SSL/TLS updates: ck_ssl.c. HTTP support
-for VMS and other VMS improvements (e.g. a way to not have to hardwire the
-C-Kermit version number into the build script) from Martin Vorlaender:
-ckcnet.h, ckuus[r3].c, ckcdeb.h, ckvtio.c, ckcnet.c, ckvker.com. Built on
-Solaris (gcc/ansi) and SunOS (cc/k&r). The new VMS script tests the VMS
-version and includes HTTP support only for VMS 6.2 or later. 2 Jul 2003.
-
-Tried to build on our last VMS system but it seems to be dead. Looks like a
-head crash (makes really loud noises, boot says DKA0 not recognized) (fooey, I
-just paid good money to renew the VMS license). Tried building at another
-site with:
-
- Process Software MultiNet V4.3 Rev A-X,
- Compaq AlphaServer ES40, OpenVMS AXP V7.3
- Compaq C V6.4-008 on OpenVMS Alpha V7.3
-
-Had to make a few corrections to ckvker.com. But still, compilation of
-ckcnet.c bombs, indicating that the SELECT definition somehow got lost
-somewhere since the 209 release (i.e. no SELECT type is defined so it falls
-thru to "SELECT is required for this code"). But I don't see anything in
-ckcdeb.h or ckcnet.[ch] that would explain this. Not ckvker.com either
-(putting the old one back gives the same result). OK, I give up, maybe it's
-just that I haven't tried building it on MultiNet recently. What about UCX?
-Aha, builds fine there except for warnings about mlook, dodo, and parser in
-ckvfio.c (because of ON_CD) -- I suppose I have #include <ckucmd.h>... (done)
-Anyhow it builds OK and the HTTP code is active and almost works (HTTP OPEN
-works; HTTP GET seems to succeed but creates an empty file every time). Tried
-building under MultiNet at another installation; same bad result.
-
-OK so why won't it build for MultiNet? Comparing ckcnet.c with the 209
-version, not a single #ifdef or #include is changed. Tried building with
-p3="NOHTTP" -- builds OK, aha. Where's the problem? Not ckcnet.h...
-Not ckcdeb.h... OK I give up, will revisit this next time I get time to
-do anything with the code.
-
-Later Jeff said "Martin did not implement VMS networking for the HTTP code.
-All he did was activate the #define HTTP which happens to work because his
-connections are using SSL/TLS connections. http_inc(), http_tol(), etc have
-no support for VMS networking regardless of whether it is UCX or MULTINET.
-The vast majority of HTTP connections are not secured by SSL/TLS. It makes no
-sense to support HTTP on VMS until someone is willing to either do the work or
-pay have the work done to implement VMS networking in that code base." So the
-fix is to not enable HTTP for VMS after all. Removed the CKHTTP definition
-for VMS from ckcdeb.h, 6 Jul 2003.
-
-Fixed ckvfio.c to #include <ckuusr.h> (instead of <ckucmd.h>) to pick up
-missing prototypes. 6 Jul 2003.
-
-From Arthur Marsh: solaris2xg+openssl+zlib+srp+pam+shadow and the corresponding
-Solaris 7 target. makefile, 6 Jul 2003.
-
-Remove duplicate #includes for <sys/stat.h>, <errno.h>, and <ctype.h> from
-ckcftp.c. 6 Jul 2003.
-
-Add -DUSE_MEMCPY to Motorola SV/68 targets because of shuffled #includes in
-ckcftp.c. 8 Jul 2003.
-
-From Jeff: Fix problems mixing SSL and SRP without Kerberos. Plus a few minor
-#define comment changes and a reshuffling of #defines in ckcdeb.h to allow me
-to build on X86 Windows without Kerberos. ckcdeb.h, ck_crp.c, ckuath.c,
-10 Jul 2003.
-
-From Jeff: updated ckuat2.h and ckuath.c, 29 Jul 2003.
-
-Mats Peterson noticed that a very small Latin-1 file would be incorrectly
-identified as UCS-2 by scanfile(). Fixed in ckuusx.c, 29 Jul 2003.
-
-Fixed ACCESS macro definition to account for the fact that FIND is now a
-built-in command. ckermit.ini, 30 Jul 2003.
-
-From Jeff: Fix for typo in urlparse() (svc/hos): ckuusy.c, 18 Aug 2003.
-
-From Jeff: Redhat9 makefile targets (needed for for OpenSSL 0.9.7):
-makefile, 19 Aug 2003.
-
-GREP /NOLIST and /COUNT did too much magic, with some undesirable fallout:
-"GREP /NOLIST /COUNT:x args" printed "file:count" for each file. "GREP
-/COUNT:x /NOLIST args" did not print "file:count", but neither did it set the
-count variable. Removed the magic. Also one of the GREP switches,
-/LINENUMBERS, was out of order. Fixed in ckuus6.c, 20 Aug 2003.
-
-From Jeff: "Reorganizing code to enable building with different subsets of
-options; a few typos corrected as well." ckcdeb.h, ckuver.h (for RH9),
-ckcnet.c, ckuus7.c, ckuus3.c: 24 Aug 2003.
-
-Scanfile misidentified a big PDF file as text because the first 800K of it
-*was* text (most other PDF files were correctly tagged as binary). Fixed
-by adding a check for the PDF signature at the beginning of the file.
-scanfile(): ckuusx.c, 25 Aug 2003.
-
-Ditto for PostScript files, but conservatively. Signature at beginning of
-file must begin with "%!PS-Ado". If it's just "%!" (or something nonstandard
-like "%%Creator: Windows PSCRIPT") we do a regular scan. Also added "*.ps"
-to all binary filename patterns. ckuusx.c, 4 Sep 2003.
-
-Ditto (but within #ifndef NOPCLSCAN) for PCL (<ESC>E) and PJL (<ESC>%) files,
-but no binpatterns (note: ".PCL" is the extension for TOPS-20 EXEC scripts).
-ckuusx.c, 4 Sep 2003.
-
-Added comments about OpenSSL 0.9.7 to all linux+openssl targets.
-makefile, 4 Sep 2003.
-
-From Jeff: Added - #define ALLOW_KRB_3DES_ENCRYPT. When this symbol is defined
-at compilation Kermit will allow non-DES session keys to be used during Telnet
-Auth. These session keys can then be used for Telnet Encrypt. The reason
-this is not compiled on by default is that the MIT Kerberos Telnet does not
-follow the RFC for constructing keys for ENCRYPT DES when the keys are longer
-than 8 bytes in length. ckuath.c, ckuus5.c, 4 Sep 2003.
-
-"ftp mget a b c" succeeded if one or more of the files did not exist, even
-with "set ftp error-action proceed". This is because the server's NLST file
-list does not include any files that don't exist, so the client never even
-tries to get them. Fortunately, the way the code is structured, this one was
-easy to fix. ckcftp.c, 14 Sep 2003.
-
-From Jeff: Corrected code in ckcnet.c to ensure that Reverse DNS Lookups are
-not performed if tcp_rdns is OFF. Fixed ck_krb5_getrealm() to actually return
-the realm of the credentials cache and not the default realm specified in the
-krb5.conf file. Previously krb5_cc_get_principal() was not being called.
-Fixed ck_krb5_is_tgt_valid() to test the TGT in the current ccache and not the
-TGT constructed from the default realm. ckcnet.c, ckuath.c, 14 Sep 2003.
-
-Marco Bernardi noticed that IF DIRECTORY could produce a false positive if
-the argument directory had previously been referenced but then removed. This
-is because of the clever isdir() cache that was added to speed up recursion
-through big directory trees. Changed IF DIRECTORY to make a second check
-(definitive but more expensive) if isdir() succeeds, and changed the
-directory-deleting routine, ckmkdir(), to flush the directory cache (UNIX
-only -- this also should be done in K95 but it's not critical). This was
-done by adding a routine, clrdircache() to ckufio.c, which sets prevstat
-to -1 and prevpath[0] to NUL. ckcfn3.c, ckuus6.c, ckufio.c, 18 Sep 2003.
-
-Marco reported the second fix still didn't work for him (even though it did
-for me). Rather than try to figure out why, I concluded that the directory
-cache is just not safe: a directory found a second ago might have been deleted
-or renamed not only by Kermit but by some other process. Why did I add this
-in the first place? The log says:
-
- Some debug logs showed that isdir() is often called twice in a row on the
- same file. Rather than try to sort out clients, I added a 1-element cache
- to Unix isdir(). ckufio.c, 24 Apr 2000.
-
-Experimentation with DIR and DIR /RECURSIVE does not show this happening at
-all. So I #ifdef'd out the directory cache (see #ifdef ISDIRCACHE in ckufio.c;
-ISDIRCACHE is not defined) and backed off the previous changes: ckufio.c,
-ckcfn3.c, ckuus6.c, 28 Sep 2003.
-
-From Jeff: Replace the compile time ALLOW_KRB_3DES_ENCRYPT with a run-time
-command SET TELNET BUG AUTH-KRB5-DES which defaults to ON: ckctel.[ch],
-ckuus[234].c, ck_crp.c, ckuath.c. 4 Oct 2003.
-
-Allow DIAL RETRIES to be any positive number, and catch negative ones.
-Also added code to check for atoi() errors (e.g. truncation). At least on
-some platforms (e.g. Solaris) atoi() is supposed to set errno, but it
-doesn't. ckuus3.c, ckucmd.c, 4 Oct 2003.
-
-Added /DEFAULT: to ASK-class commands (ASK, ASKQ, GETOK):
-
- . For popups: no way to send defaults to popup_readtext() or popup_readpass().
- . For GUI ASK[Q], pass default to gui_txt_dialog().
- . For GUI GETOK, convert "yes" "ok" or "no" default to number for uq_ok().
- . For Text GETOK, add default to cmkey().
- . For Text ASK[Q], add default to cmtxt().
- . For GETC, GETKEY, and READ: no changes.
-
-GETOK, ASK, and ASKQ with /TIMEOUT: no longer fail when the timer goes off
-if a /DEFAULT was supplied. The GUI functions (uq_blah) don't seem to
-support timeouts. Only the text version has been tested. ckuus[26].c,
-4 Oct 2003.
-
-From Jeff: add /DEFAULT: for popups. ckuus6.c. 6 Oct 2003.
-
-Change SET DIAL INTERVAL to be like SET DIAL RETRIES. ckuus[34].c, 6 Oct 2003.
-
-Added target for HP-UX 10/11 + OpenSSL built with gcc, from Chris Cheney.
-Makefile, 12 Oct 2003.
-
-From Jeff, 6 Nov 2003:
- . #ifdef adjustments: ckcftp.c, ckcdeb.h
- . Fix spurious consumption of first byte(s) on Telnet connection: ckctel.c
- . Another HP PJL test for scanfile: ckuusx.c.
- . K95: Recognize DG4xx protected fields in DG2xx emulation: ckuus7.c.
- . Add SSLeay version display to SHOW AUTH command: ckuus7.c
- . Improved SET MOUSE CLEAR help text: ckuus2.c.
- . Improved Kverbs help text: ckuus2.c (+ new IBM-3151 Kverbs).
- . Some changes to ck_ssl.c, ckuath.c.
-
-From PeterE, 10 Nov 2003:
- . Improved HP-UX 10/11 makefile targets for OpenSSL.
- . #ifdef fix for OpenSSL on HP-UX: ck_ssl.c.
-
-Another new makefile from PeterE with improved and integrated HP-UX targets.
-12 Nov 2003.
-
-A couple fixes to the solaris9g+krb5+krb4+openssl+shadow+pam+zlib target
-from Jeff. Added a solaris9g+openssl+shadow+pam+zlib target. makefile,
-21 Nov 2003.
-
-From Jeff, 30 Nov 2003:
- . Fix SEND /MOVE-TO: ckuusr.c.
- . Fix K95 SET TITLE to allow quotes/braces around text: ckuus7.c.
- . Improved "set term autodownload ?" response: ckuus5.c.
- . Fix SHOW FEATURES to specify the protocol for encryption: ckuus5.c
- . Make {SEND, RECEIVE} {MOVE-TO, RENAME-TO} work for XYZMODEM (K95 only).
-
-From Jeff: 7 Jan 2004:
- . At one point Frank started to add a timer parameter to the
- uq_txt() function but he only did it for the non-ANSI
- compilers. I added it for the ANSI compilers, fixed the
- prototypes and provided a default value easily changed
- DEFAULT_UQ_TIMEOUT: ckcker.h, ckuus[36].c, ck_ssl.c, ckcftp.c, ckuath.c.
- . Fixed SET TERMINAL DEBUG ON (typo in variable name): ckuus7.c.
- . Fixed BEEP INFORMATION; previously it made no sound, now uses
- MB_ICONQUESTION. ckuusx.c.
-
-From Ian Beckwith <ian@nessie.mcc.ac.uk> (Debianization), 7 Jan 2004:
- . Search dir/ckermit for docs, as well as dir/kermit in cmdini(): ckuus5.c.
- . New linux+krb5+krb4+openssl+shadow+pam target (kitchen sink minus SRP,
- which Debian does not distribute): makefile.
- ? Mangles the DESTDIR support in makefile to install into a staging area:
- makefile (I didn't take this one yet).
-
-Updated copyright notices for 2004, all modules. 7 Jan 2004.
-
-Added INPUT /NOMATCH, allowing INPUT to be used for a fixed amount of time
-without attempting to match any text or patterns, so it's no longer
-necessary to "input 600 STRING_THAT_WILL_NEVER_COME". If /NOMATCH is
-included, INPUT succeeds if the timeout expires, with \v(instatus) = 1
-(meaning "timed out"); fails upon interruption or i/o error. ckuusr.h,
-ckuus[r24].c, 7 Jan 2004.
-
-Added SET INPUT SCALE-FACTOR <float>. This scales all INPUT timeouts by the
-given factor, allowing time-sensitive scripts to be adjusted to changing
-conditions such as congested networks or different-speed modems without
-having to change each INPUT-class command. This affects only those timeouts
-that are given in seconds, not as wall-clock times. Although the scale
-factor can have a fractional part, the INPUT timeout is still an integer.
-Added this to SHOW INPUT, and added a \v(inscale) variable for it.
-ckuusr.h, ckuus[r257].c, 7 Jan 2004.
-
-undef \%a, \fverify(abc,\%a) returns 0, which makes it look as if \%a is a
-string composed of a's, b's, and/or c's, when in fact it contains nothing.
-Changed \fverify() to return -1 in this case. ckuus4.c, 12 Jan 2004.
-
-\fcode(xxx) returned an empty string if its argument string was empty. This
-makes it unsafe to use in arithmetic or boolean expressions. Changed it to
-return 0 if its argument was missing, null, or empty. ckuus4.c, 12 Jan 2004.
-
-Updated \verify() and \fcode() help text. ckuus2.c, 12 Jan 2004.
-
-While setting up IKSD, Ian Beckwith noticed that including the --initfile:
-option caused Kermit to start parsing its own Copyright string as if it were
-the command line, and eventually crash. I couldn't reproduce on Solaris /
-Sparc but I could in Linux / i386 (what Ian is using) -- a change from Jeff
-on 28 Apr 2003 set the command-line arg pointer to a literal empty string in
-prescan() about line 1740 of of ckuus4.c; the pointer is incremented next
-time thru the loop, resulting in random memory being referenced. Fixed by
-setting the pointer to NULL instead of "". ckuus4.c, 12 Jan 2004.
-
-declare \&a[999999999999999] would dump core on some platforms. atoi()
-or whatever would truncate the dimension to maxint. When we add 1 to the
-result, we get a negative number, which is used as an index, loop test, etc.
-Fixed both dodcl() and dclarray() to check for (n+1 < 0). ckuus[r5].c,
-12 Jan 2004.
-
-Unix zchki() would fail on /dev/tty, which is unreasonable. This prevented
-FOPEN /READ from reading from the terminal. zchki() already allowed for
-/dev/null, so I added /dev/tty to the list of specials. Ditto for FOPEN
-/WRITE and zchko(). ckufio.c 13 Jan 2004.
-
-Added untabify() routine to ckclib.[ch], 13 Jan 2004.
-Added FREAD /TRIM and /UNTABIFY. ckuus[27].c, 13 Jan 2004.
-Added \funtabify(). ckuusr.h, ckuus[24].c, 13 Jan 2004.
-
-Dat Nguyen noticed that (setq u 'p') followed by (u) dumped core. This was
-caused by an over-clever optimization that skipped mallocs for short
-literals, but then went on later to try to free one that hadn't been
-malloc'd. Fixed in dosexp(): ckuus3.c, 14 Jan 2004.
-
-Catch another copyright date. ckuus5.c, 14 Jan 2004.
-
-Fixed SWITCH to work even when SET COMMAND DOUBLEQUOTE OFF (from Mark
-Sapiro). ckuus5.c, 15 Jan 2004.
-
-Changed version to 8.0.211 so scripts can test for recently added features.
-ckcmai.c, 15 Jan 2004.
-
-Fixed a glitch in K95 "help set port". ckuus2.c, 20 Jan 2004.
-
-Fix from Jeff: Connections to a TLS-aware protocol which require a reconnect
-upon certificate verification failure could not reconnect if the connection
-was initiated from the command line or via a URL. ckctel.c ckcmai.c
-ckuusr.c ckuus7.c ckuusy.c, 20 Jan 2004.
-
-From Alex Lewin: makefile target and #ifdef for Mac OS X 10.3 (Panther):
-makefile, ckcnet.c, 7 Feb 2004.
-
-Added KFLAGS to sco32v507 targets to make PTY and SSH commands work. The
-same flags could probably also be added to earlier OSR5 targets but they
-have not been tested there. makefile, 7 Feb 2004.
-
-Checked a complaint that "LOCAL &a" did not make array \&a[] local. Indeed
-it did not, and can not. You have to use the full syntax in the LOCAL
-command, "LOCAL \&a[]", or else it doesn't know it's not a macro named &a.
-7 Feb 2004.
-
-Fixed some confusion in creating IKSD database file and temp-file names.
-I was calling zfnqfp() without remembering that the path member of the
-returned struct included the filename, so to get just the directory name,
-I needed to strip the filename from the right. ckuusy.c, 2 Mar 2004.
-
-New ckuath.c, ck_ssl.c from Jeff. 2 Mar 2004.
-
-Updated Jeff's affiliation in VERSION command text. ckuusr.c, 2 Mar 2004.
-
-Designation changed from Dev.00 to Beta.01. ckcmai.c, 2 Mar 2004.
-
-Fixed zrename() syslogging -- it had success and failure reversed.
-Beta.02: ckufio.c, 4 Mar 2004.
-
-Problem: when accessing IKSD via a kermit:// or iksd:// URL, and a user ID
-is given but no password, doxarg() set the password to "" instead of leaving
-it NULL, but all the tests in dourl() are for NULL. Fixed in doxarg():
-ckuusy.c, 5 Mar 2004.
-
-The logic in dourl() about which macro to construct (login and connect,
-login and get directory listing, or login and fetch a file) was a bit off,
-so all three cases were not handled. ckcmai.c, 5 Mar 2004.
-
-Trial Beta builds:
- . HP-UX B.11.11 PA-RISC
- . HP-UX B.11.23 IA64
- . Tru64 4.0G Alpha
- . Tru64 5.1B Alpha
- . Debian 3.0 i386
- . Red Hat ES 2.1 i386
- . Slackware 9.1 i386
- . VMS 7.3-1 Alpha + UCX 5.3
- . VMS 7.3-1 Alpha no TCP/IP
- . VMS 7.3 Alpha MultiNet 4.3 A-X
- . SCO UnixWare 7.1.4 i386
- . SCO OSR5.0.7 i386
- . Solaris 9 Sparc
-
-Fixed compiler warning in doxarg() caused by typo (NULL instead of NUL) in
-the 5 March doxarg() edit. ckuusy.c, 9 Mar 2004.
-
-IKSD (kermit://) command-line URLs did not work right if the client had
-already preauthenticated with Kerberos or somesuch because they tried to log
-in again with REMOTE LOGIN. The macros constructed in doxarg() needed to
-check \v(authstate) before attempting REMOTE LOGIN. ckcmai.c, 10 Mar 2004.
-
-Added ckuker.nr to x.sh (ckdaily upload) and updated ckuker.nr with current
-version number and dates. 10 Mar 2004.
-
-Replaced hardwired references to /usr/local in makefile with $(prefix)
-(which defaults to /usr/local, but can be overridden on the command line),
-suggested by Nelson Beebe for use with Configure. 10 Mar 2004.
-
-From Nelson Beebe: In the Kermit makefile in the install target commands,
-line 981 reads:
-
- cp $(BINARY) $(DESTDIR)$(BINDIR)/kermit || exit 1;\
-
-Could you please add this line before it:
-
- rm -f $(DESTDIR)$(BINDIR)/kermit;\
-
-Some sites (mine included) keep multiple versions of software around,
-with hard links between $(prefix)/progname and $(prefix)/progname-x.y.z.
-Failure to remove the $(prefix)/progname at "make install" time then
-replaces the old $(prefix)/progname-x.y.z with the new one, destroying
-an old version that the site wanted to be preserved. makefile, 10 Mar 2004.
-
-Minor syntax and typo fixes (mostly prototypes): ckcdeb.h, ckcfns.c,
-ckclib.c, ckufio.c, ckuusr.h, ckuusx.c, 10 Mar 2004. (I still have a few
-more to do.)
-
-Added CC=$(CC) CC2=$(CC2) to many (but not all) makefile targets that
-reference other makefile targets. On some platforms (notably AIX, Solaris,
-SunOS) there are specific targets for different compilers, so I skipped
-those. makefile, 10 Mar 2004.
-
-Added error checking to kermit:// URL macros, so they don't plow ahead
-after the connection is closed. ckcmai.c, 11 Mar 2004.
-
-Added FreeBSD 4.9 and 5.1 targets (only the herald is affected).
-makefile, ckuver.h, 11 Mar 2004.
-
-Added "LIBS=-lcrypt" to bsd44 targets since nowadays crypt is almost always
-unbundled from libc. Also added explanatory notes. makefile, 11 Mar 2004.
-
-Changed MANDIR to default to $(manroot)/man/man1, and manroot to default
-to $(prefix). More adding of CC=$(CC) clauses: {Free,Net,Open}BSD, 4.4BSD.
-makefile, 11 Mar 2004.
-
-Miscellaneous cleanups: ckuusx.c, ckcnet.c, ckufio.c, 11 Mar 2004.
-
-Corrected the check in the linux target to see if /usr/include/crypt.h
-exists, and if so to define HAVE_CRYPT_H, which is used in ckcdeb.h to
-#include <crypt.h> to get the prototype for crypt() and prevent bogus
-conversions on its return type on 64-bit platforms (the previous test wasn't
-quite right and the resulting symbol wasn't spelled right). makefile,
-12 Mar 2004.
-
-From Jeff, 14 Mar 2004:
- . Initialize localuidbuf[] in tn_snenv(): ckctel.c.
- . Remove remote-mode checks in hupok() for K95G only (why?): ckuus3.c.
- . Add help text for new K95-only TYPE /GUI switches: ckuus2.c.
- . TYPE /GUI parsing, ...: ckuusr.c.
- . TYPE /GUI action, dotype(): ckuus6.c
- . Change Jeff's affiliation: most modules.
-
-20 Mar 2004: Looked into adding long file support, i.e. handling files more
-than 2GB (or 4GB) long. Discovered very quickly this would be a major
-project. Each platform has a different API, or environment, or transition
-plan, or whatever -- a nightmare to handle in portable code. At the very
-least we'll need to convert a lot of Kermit variables from long or unsigned
-long to some new Kermit type, which in turn is #defined or typedef'd
-appropriately for each platform (to off_t or size_t or whatever). Then we
-have to worry about the details of open() vs fopen(); printf() formats (%lld
-vs %Ld vs %"PRId64"...), platforms like HP-UX where you might have to use
-different APIs for different file systems on the same computer, etc. We'll
-need to confront this soon, but let's get a good stable 8.0.211 release out
-first! Meanwhile, for future reference, here are a few articles:
-
-General: http://freshmeat.net/articles/view/709/
-Linux: http://www.ece.utexas.edu/~luo/linux_lfs.html
-HP-UX: http://devrsrc1.external.hp.com/STK/partner/lg_files.pdf
-Solaris: http://wwws.sun.com/software/whitepapers/wp-largefiles/largefiles.pdf
-
-Looked into FTP timeouts. It appears I can just call empty() (which is
-nothing more than a front end for select()) with the desired timeout before
-any kind of network read. If it returns <= 0, we have a timeout. This is
-not quite the same as using alarm() / signal() around a recv() (which could
-get stuck) but alarm() / signal() are not not used in the FTP module and are
-not naturally portable to Windows, but select() is already in use in the FTP
-module for both Unix and Windows. This form of timeout could be used
-portably for both command response and data reads. What about writes to the
-command or data socket? They can get stuck for hours and hours without
-returning too, but the select() approach won't help here -- we need the
-actual send() or recv() to time out, or be wrapped in an alarm()/signal()
-kind of mechanism. But if we can do that for sends, we can also do it for
-receives. Better check with Jeff before I start programming anything.
-20 Mar 2004.
-
-Later: Decided to postpone the above two projects (ditto IPv6) until after
-8.0.211 is released because both will have major impacts on portability.
-Grumble: all i/o APIs should have been designed from the beginning with a
-timeout parameter. To this day, hardly any have this feature.
-
-3-4 Apr 2004: More 8.0.211 Beta.02+ test builds:
-
- . FreeBSD 3.3
- . FreeBSD 4.4
- . Linux Debian 2.1
- . Linux RH 6.1
- . Linux RH 7.1
- . Linux RH 7.2
- . Linux RH 9 (with 84 different combinations of feature selection)
- . Linux SuSE 6.4
- . Linux SuSE 7.0
- . NetBSD 1.4.1
- . NetBSD 1.5.2
- . OpenBSD 2.5
- . OpenBSD 3.0
- . QNX 4.25
- . SCO UnixWare 2.1.3
- . SCO UnixWare 7.1.4
- . SCO OpenServer 5.0.7
- . SCO XENIX 2.3.4 (no TCP)
-
-Changes needed: None.
-
-Problem: SCO XENIX 2.3.4 network build failed in the FTP module with
-header-file syntax and conflicting-definitions trouble. I'm not going to
-try to fix it; 8.0.209 built OK with FTP, so we'll just keep that one
-available.
-
-Got access to VMS 8.1 on IA64. Building the nonet version of C-Kermit
-required minor modifications to ckvvms.h, ckv[ft]io.c, and ckvcon.c, to
-account for a third architecture. Also to SHOW FEATURES in ckuus5.c. Once
-that was done, the UCX 5.5 version built OK too. Starts OK, makes Telnet
-connection OK, sends files. Has some obvious glitches though -- "stat"
-after a file transfer reports 0 elapsed time (in fact it was 00:09:48) and
-1219174400 cps (when in fact it was 10364). This doesn't happen on the
-Alpha. Btw, the IA64 binary is twice as big as the Alpha one. Changed
-to Beta.03. 5 Apr 2004.
-
-Fixed the ckdaily script to include the makefile and man page in the Zip
-file (they were not included because the Zip file was intended mainly for
-VMS users, but some Unix users prefer Zip to tar.gz). 6 Apr 2004.
-
-Traced problems in VMS/IA64 statistics report to rftimer()/gftimer() in
-ckvtio.c, which use sys$ and lib$ calls to figure elapsed time. These work
-on VAX and Alpha but not IA64. Sent a report to the chief engineer of the
-IA64 VMS port; he says it's probably a bug in VMS 8.1 (which is not a real
-release); he'll make sure it's fixed in 8.2. As an experiment, tried
-swapping in the Unix versions of these routines (which call gettimeofday()
-etc). They seem work just fine (it hung a couple times but I think that's
-because the underlying system hung too; trying it later on a new connection,
-it was fine; however I noticed a BIG discrepancy in throughput between
-sending and receiving). Moved definitions for VMS64BIT and VMSI64 to
-ckcdeb.h so all modules can use them and added them to the SHOW FEATURES
-display. Added VMSV80 definition to build procedure. Beta.03+. ckcdeb.h,
-ckcuus5.c, ckcvvms.h, ckvtio.c, ckvker.com, 6 Apr 2004.
-
-While doing the build-all, I noticed the VMS version did not build with
-Multinet or older UCX versions, always with the same errors -- undeclared
-variables, undefined symbols, all TCP/IP related. This didn't happen a
-couple weeks ago... Somehow the order of #includes was messed up --
-ckuusr.h depended on symbols that are defined in ckcnet.h, but ckcnet.h
-was being included after ckuusr.h... this was compounded by two missing
-commas in ckvker.com. 11 Apr 2004.
-
-Removed Beta designation, released as 8.0.211, 10 Apr 2004.
-
-I had somehow lost the edit to ckutio.c that changed the UUCP lockfile for
-Mac OS X from /var/spool/uucp to /var/spool/lock. So I slipped it in and
-re-uploaded version 8.0.211. You can tell the difference because SHOW
-VERSIONS has 17 Apr 2004 for the Communications I/O module. Also the 10.3
-executable now has a designer banner: "Mac OS X 10.3". makefile, ckuver.h,
-ckutio.c, ckuus[45].c, 17 Apr 2004.
-
----8.0.211---
-
-Removed "wermit" from "make clean" (how did it get there?). makefile.
-
-From Jeff, applied 10 May 2004.
- . Rearrange #ifdefs that define OS/2-only features. ckcdeb.h.
- . Fix two strncat()s that should have been ckstrncat()s. ckuus7.c.
- . Fix two strncat()s that should have been ckstrncat()s. ckuus4.c.
- . Fix one strncat(). ckcfns.c.
- . SET FTP CHAR ON used backwards byte order when output to screen. ckcfns.c.
- . Fix two strncat()s. ckuus3.c.
- . Add SET NETWORK TYPE NAMED-PIPE for K95. ckuus3.c.
- . Add "No active connections" message to hupok(). ckuus3.c.
- . Fix many strncat()s. ckcnet.c.
- . Fix some strncat()s. ckcftp.c
- . Make FTP port unsigned short for 16383 < port < 65536. ckcftp.c.
- . Improvements to FTP USER command. ckcftp.c.
- . Fix FEAT parsing to allow for various forms of whitespace. ckcftp.c.
-
-S-Expression (AND FOO BAR) would not short-circuit if FOO's value was 0,
-even though short-circuiting code has been there since Day 1. Similarly for
-(OR BAR FOO). Turns out the first operand was a special case that bypassed
-the short-circuit check. Fixed in dosexp(): ckuus3.c, 10 May 2004.
-
-Red Hat 7.3 (and maybe others) <baudboy.h> referenced open() without first
-ensuring it was declared. The declaration is in <fcntl.h>, which is after
-<baudboy.h> in ckutio.c series of #includes. Made a special case for this.
-ckutio.c (see comments), 10 May 2004.
-
-If the local Kermit's parity is set to SPACE and then a file arrives via
-autodownload, automatic parity detection improperly switches it to NONE.
-Fixed in rpack() by switching parity automatically only if parchk() returns
-> 0 (rather than > -1), since NONE and SPACE are indistinguishable. A
-bigger problem still remains: autodownload does not work at all if the
-sender is using actual parity bits (even, odd, or mark) and the receiver's
-parity is NONE. ckcfn2.c, 10 May 2004.
-
-When a DIAL MACRO is defined and the phone number is comprised of more than
-one "word" (i.e. contains spaces), the dial macro loses the second and
-subsequent words after the first call. Fixed in xdial() by inserting quotes
-around phone number before passing it to xdial(). ckuus6.c, 10 May 2004.
-
-DIAL MACRO fix was not right; the quotes were kept as part of the phone
-number and sent to the modem. dodo() pokes its argument to separate the
-macro argument string into its component arguments. xdial() is called
-repeatedly on the same string, so after the first time, a NUL has been
-deposited after the first word of the telephone number. The fix is to have
-xdial() create a pokeable copy of its argument string before calling
-dodo(dial-macro,args...). It might seem odd that dodo pokes its argument,
-but making copies would be would be prohibitive in space and time.
-ckuus6.c, 23 May 2004.
-
-FTP CD did not strip braces or quotes from around its argument. Fixed in
-doftprmt(): ckcftp.c, 23 May 2004.
-
-Added client side of REMOTE MESSAGE/RMESSAGE/RMSG: ckuus[r27].c, 23 May 2004.
-
-Server side of REMOTE MESSAGE: ckcpro.w, 23 May 2004.
-
-From Dave Sneddon: an updated CKVKER.COM containing a fix where the
-COMPAQ_SSL symbol was not defined but later referenced which generated an
-undefined symbol error. ckvker.com, 5 Jan 2005.
-
-From Andy Tanenbaum (28 May 2005):
- . Fix an errant prototype in ckcker.h and ckucmd.h - () instead of (void).
- . Add support for MINIX 3.0. makefile, ckutio.c, ckufio.c, ckuver.h.
-
-Fixed messed-up sndhlp() call which apparently had been jiggered to
-compensate for the bad prototype which has now been fixed, ckcpro.w,
-12 Jun 2005.
-
-From Jeff (12 June 2005):
- . Security updates. ck_ssl.c, ck_crp.c, ckuath.c.
- . Fix bug in K95 SET PRINTER CHARACTER-SET. ckuus3.c.
- . Add printer character-set to K95 SHOW PRINTER display. ckuus5,c
- . Add SET MSKERMIT FILE-RENAMING to K95. ckuus7.c, ckuusr.h.
- . Add help for K95 SET MSKERMIT. ckuus2.c.
- . Add SET GUI CLOSE to K95. ckuusr.h, ckuus2.c, ckuus3.c
- . Add help text for K95 SET GUI MENUBAR and TOOLBAR. ckuus2.c.
- . Add --noclose command-line option for K95. ckuusy.c
- . Add PAM support for Mac OS X. ckufio.c.
- . Add GSSAPI support for Mac OS X. ckcftp.c.
- . Pick up more URL options. ckcker.h, ckuusy.c.
- . Fix bug in delta-time calculation across year boundary. ckucmd.c.
- . Add Secure Endpoints to copyright notices. ckcmai.c.
- . Fix FTP HELP to override unverbose setting. ckcftp.c.
- . Fix assorted minor typos.
-
-From Matthias Kurz: automatic herald generation for NetBSD 2.0 and later,
-"make netbsd2". ckuver.h, makefile, 12 Jun 2005.
-
-Added SET TERMINAL LF-DISPLAY, like CR-DISPLAY but for linefeed rather than
-carriage return. ckuusr.h, ckuus[257x].c, 12 Jun 2005.
-
-Made a command-line option --unbuffered to do what the -DNONOSETBUF
-compile-time option does, i.e. force unbuffered console i/o. Unix only.
-ckuusr.h, ckuusy.c, ckutio.c, 12 Jun 2005.
-
-Fixed getiact() (which displays TERM IDLE-ACTION setting) to display
-space as \{32}. ckuus7.c, 12 Jun 2005.
-
-Added LMV as a synonym for LRENAME, which is itself a synonym for LOCAL
-RENAME. ckuusr.c, 12 Jun 2005.
-
-Put HELP SET TERMINAL DG-UNIX-MODE text where it belonged. ckuus2.c,
-12 Jun 2005.
-
-Added IF LINK (Unix only) to test if a filename is a symlink. Uses the most
-simpleminded possible method, calls readlink() to see if it succeeds or fails.
-No other method is dependable across different Unixes. This code should be
-portable because I already use readlink() elsewhere within exactly the same
-#ifdefs. ckufio.c, ckuus2.c, ckuus6.c, 12 Jun 2005.
-
-Fixed a bug in which \fdir() wouldn't work when its argument was the nonwild
-name of a directory file. zxpand(): ckufio.c, 12 Jun 2005.
-
-Made \fdirectory() a synonym for \fdirectories(). Made \fdir() an
-acceptable abbreviation for these, even though it clashes with \fdirname(),
-which still works as before. ckuus4.c, 12 Jun 2005.
-
-Added the long-needed \flopx() function, to return rightmost pieces of
-strings, such as file extensions. \fstripx() and \flopx() are the
-orthogonal functions we need to pick filenames apart from the right:
-\stripx(foo.tar.gz) = foo.tar; flopx(foo.tar.gz) = gz. ckuusr.h, ckuusr.c,
-ckuus2.c, 12 Jun 2005.
-
-Removed reference to defunct fax number, ckcmai.c, 12 Jun 2005.
-
-Added -DHAVE_PTMX to linux+krb5+openssl+zlib+shadow+pam. From Timothy Folks.
-makefile, 12 Jun 2005.
-
-Built on Solaris 9 and NetBSD 2.0.
-
-From Jeff: New build target for Mac OS X 10.3 with Kerberos 5 and SSL.
-makefile, 14 Jun 2005.
-
-Fixed error in ckuver.h NetBSD #ifdefs. 15 Jun 2005.
-
-Fixed SET TERMINAL IDLE-ACTION OUTPUT to work as documented, namely if the
-output string is empty, to send a NUL. Previously there was no way to make
-it send a NUL. ckuus7.c, 15 Jun 2005.
-
-Suppose (in Unix, for example) a filename contains wildcard characters, such
-as {abc}.txt. When referring to such a file (e.g. in a SEND command), these
-characters can be quoted, e.g. \{abc\}.txt. But if the file list has been
-obtained programmatically, e.g. stored in an array, there is no way, short
-of tedious, complicated, and error-prone string processing, to reference the
-file. For this we need a way to disable wildcard processing. I added { ON,
-OFF } choices for the SET WILD and SHOW FILE commands: ckuusr.h, ckuus[234].c.
-{ ON, OFF } turns wildcarding off and on without affecting the { KERMIT,
-SHELL } agent choice; it does this by setting a new and separate global
-variable, wildena. Added semantics to ckufio.c. Crude but effective. It
-might have been more Unixlike to add Yet Another form of quoting but we
-have enough of that already (later maybe I'll add a \function() for this).
-Needs to be propagated to Windows and VMS. 15 Jun 2005.
-
-Improved and fixed typos in HELP WILDCARD and HELP PATTERN. ckuus2.c,
-15 Jun 2005.
-
-The GREP command, and probably anything else that uses ckmatch() for pattern
-matching, failed on patterns like */[0-3]*.html. The [a-b] handler, when
-failing to match at the current position, neglected to back up the pattern
-and try again on the remainder of the string. I also fixed another case, in
-which matching a literal string a*b?c against the pattern a[*?]*[?*]c caused
-ckmatch() to recurse until it blew up. ckclib.c, 16 Jun 2005.
-
-Added builds and designer banner for Solaris 10. makefile, ckuver.h,
-27 Jun 2005.
-
-Defined CKHTTP for NetBSD, the HTTP code builds and works fine there.
-ckcdeb.h, 2 Jul 2005.
-
-Added #ifndef OSF40..#endif around definition of inet_aton() in ck_ssl()
-to allow building in Tru64. Added tru64-51b+openssl to makefile.
-15 Jul 2005.
-
-HTTP GET would fail if the URL contained any metacharacters, no matter how
-much you quoted them. Although it uses cmfld() to parse the (partial) URL,
-it then uses cmofi() to get the output filename, which by default is the
-"filename" from the URL, which might be something like "rankem.asp?id=1639".
-cmofi() refuses to accept unquoted metacharacters in "filenames" and that's
-what happens in this case if the output filename is not specified. Worked
-around this by disabling wildcard processing around HTTP GET using the new
-"wildena" variable from June 15th. ckuusr.c, 18 Jul 2005.
-
-Fixed the June 16th fix to the pattern matcher. I fixed a real problem, but
-I made an unrelated optimization that introduced new ones. ckclib.c,
-18 Jul 2005.
-
-Added missing help text for \fb64encode() and \fb64decode(). ckuus2.c,
-18 Jul 2005.
-
-Changed SET WILD OFF help text to warn that this setting prevents the
-creation of backup files (later I'll have to see if something more useful
-can be done about this). ckuus2.c, 18 Jul 2005.
-
-Built OK on Mac OS X 10.4.2 using macosx103 target (but with some
-"signedness" warnings in ckcnet.c and ckcftp.c). Built on Unixware 7.1.4
-with uw7 target. 27-28 Jul 2005.
-
-Added -DCKHTTP to Mac OS X 10.3-.4 KFLAGS. Makefile, 4 Aug 2005.
-
-Built on BSDI 4.3.1. Added -DCKHTTP.
-
-Compact substring notation extended to accept not only start:length but also
-start-end notation. Thus \s(foo[12:18]) means the substring of foo starting
-at position 12 of length 18, and tne new \s(foo[12-18]) means the substring
-of foo starting at position 12 and ending with position 18. Ditto for
-\:(\%a), etc. ckuus4.c, 9 Aug 2005.
-
-See correspondence with Mark Sapiro, Nov 2003 and Sep 2004, about certain
-variations on IF syntax having been broken by the introduction of "immediate
-macros" circa 1999. It seems the problem -- variables not being expanded --
-always occurs in the ELSE part when (a) the IF condition is false; (b) the
-ELSE command is "standalone", i.e. expressed as a separate command after the
-IF command (original C-Kermit 5A syntax), and (c) its command list is a block.
-This would suggest the problem is in the XXELS parser.
-
-Going back to 1999, I find this:
- Fixed a problem Jim Whitby noticed with quoting in ELSE statements. This
- problem was introduced when I unified IF and XIF, and occurs only when
- ELSE begins on a line, followed by a { command list } rather than a single
- command. The solution (gross) was to make a special version of pushcmd()
- (called pushqcmd()) for this situation, which doubles backslashes while
- copying, BUT ONLY IF it's a command list (i.e. starts with "{"); otherwise
- we break lots of other stuff. Result passes Jim's test and still passes
- ckedemo.ksc and iftest.ksc. ckucmd.c, ckuus6.c, 27 Sep 99.
-
-I undid this change and it made no difference to all the other IF
-constructions (in fact, it fixed an unrelated one that was broken, so now
-iftest scores 54 out of 54, instead of 53). However, it does not fix the
-ELSE problem; in fact it pushes it all the way in the other direction:
-
- The opposite occurs any time you try to execute an immediate macro inside a
- macro or any other { block }: not only is the variable evaluated, it is
- evaluated into nothing. It looks like this happens only in immediate
- macros, i.e. *commands* that start with '{'. So maybe we really have two
- isolated problems, that can each be fixed.
-
-The situation is illustrated by this simple script:
-
- def xx {
- if false { echo \%1, echo \%2 }
- else { echo \%3, echo \%4 }
- }
- xx one two three four
-
-With pushqcmd() it echoes the variable names literally; with pushcmd() it
-echoes empty lines. Since ELSE, when its argument is a block, dispatches
-to the immediate-macro handler, it seems we have unified the two problems,
-so fixing one should fix the other.
-
-The problem is that we define a new temporary macro and then call dodo() to
-execute it. But if the definition contains macro arguments, we have added a
-new level of macro invocation, thus wiping out the current level of args.
-The cure is to expand the variables in the immediate macro in the current
-context, before executing it. This means simply changing the cmtxt() call
-that reads the immediate macro to specify xxsting as its processing
-function, rather than NULL, which is used for real macros to defer their
-argument evaluation until after the macro entered. ckuusr.c, 11 Aug 2005.
-
-Added a new makefile target, macosx10.4, for Mac OS X 10.4. This one uses
-an undocumented trick to get the otherwise unavailable-except-by-clicking
-Mac OS X version number (in this case 10.4.2) and stuff it into the HERALD
-string. makefile, 11 Aug 2005.
-
-Built OK on Solaris 9, Solaris 10 (with a few implicit declaration warnings
-in ckuusx.c), Mac OS X 10.4.2 (with some warnings in ckcnet.c and ckcftp.c),
-Mac OS X 10.3.9 (also using the macos10.4 entry, which gets the right
-version number, and gets no warnings at all), RH Enterprise Linux AS4 on AMD
-x86_64, Tru64 Unix 4.0F, SCO UnixWare 7.1.4
-
-For docs and/or scriptlib: Unix C-Kermit can be a stdin/out filter. The
-trick is to use the ASK, ASKQ, or GETC command for input, specifying no
-prompt, and ECHO or XECHO for output, e.g.:
-
-while true {
- ask line
- if fail exit 0
- echo \freverse(\m(line))
-}
-exit 0
-
-FOPEN didn't do anything with the channel number if the open failed, so any
-subsequent command that tried to reference it would get a parse error it was
-undefined or non-numeric, not very helpful. Changed FOPEN to set the
-channel number to -1 if the file can't be opened. Now subsequent operations
-on the channel fail with "Channel -1: File not open". I also added two
-magic channel numbers: -8 means that any FILE command (besides OPEN and
-STATUS) on that channel is a noop that succeeds silently; -9 is a noop that
-fails silently. So now it's possible to simply set a channel number to one
-of these values to disable i/o to certain file without getting lots of error
-messages. dofile(): ckuus7.c, 12 Aug 2005.
-
-Added automatic herald construction for UnixWare 7. makefile, 12 Aug 2005.
-
-Unix isdir() never allowed for arguments that started with tilde, so gave
-incorrect results for ~/tmp/ or ~fdc. The problem was mainly invisible
-since most commands that parsed file or directory names used cmifi(), cmdir(),
-etc, which did the conversions themselves. But IF DIRECTORY was an exception,
-since its operand had to be treated as just text, and then tested after it
-was parsed. ckufio.c, 13 Aug 2005.
-
-Fixed the following:
-"ckuusx.c", line 8959: warning: implicit function declaration: ckgetpeer
-"ckufio.c", line 1869: warning: implicit function declaration: ttwait
-"ckufio.c", line 2941: warning: implicit function declaration: mlook
-"ckufio.c", line 2943: warning: implicit function declaration: dodo
-"ckufio.c", line 2944: warning: implicit function declaration: parser
-"ckcftp.c", line 2625: warning: implicit function declaration: delta2sec
-"ckcftp.c", line 4071: warning: no explicit type given for parameter: prm
-"ckcftp.c", line 8389: warning: no explicit type given for parameter: brief
-ckuusx.c, ckufio.c, ckcftp.c, ckucmd.h. 13 Aug 2005.
-
-Unbuffered stdout code has never worked because the setbuf(stdout,NULL) call
-has to occur before the stdout has been used. The reason it's needed is
-that some Kermit code writes to stderr (which is unbuffered) and other code
-writes to stdout, and therefore typescripts can come out jumbled. Robert
-Simmons <robertls@nortel.com> provided the needed clue when he insisted it
-worked only when executed at the very beginning of main(). So I moved the
-code to that spot. But since now we also want to make unbuffered a runtime
-(command-line) option, I had to do a clunky by-hand pre-prescan inline in
-main() to look thru argv[], even before prescan() was called. ckcmai.c,
-ckutio.c, ckuusy.c, 13 Aug 2005. (Now that this works, it might be a good
-idea to remove all use of stderr from Kermit.)
-
-Managed, after some finagling, to build a 64-bit version on Solaris 10 at
-Utah Math with Sun cc. (Can't make any gcc builds at all, 32- or 64-bit,
-they all blow up in <sys/siginfo.h>.) New target: solaris10_64. makefile,
-15 Aug 2005.
-
-The 64-bit Solaris 10 version compiles and links OK and transfers files in
-remote mode. It can make FTP connections and use them, but Telnet connections
-always fail with "network unreachable". This is with all default libs and
-include files. Nelson has a separate set in /usr/local, which he references
-explicitly in all his 64-bit builds, but using these makes no difference.
-Some data type is wrong in ckcnet.c. But telnet works fine in 64-bit Linux
-and Tru64 builds. Debug logs trace the difference to netopen() (of course),
-the spot where we test the results of inet_addr(), which is already marked
-suspicious for 64-bit builds. It seems that inet_addr() is of type in_addr_t,
-which in turn is u_int32, i.e. an unsigned 32-bit int. Yet the man page says
-that failure is indicated by returning -1. I guess this doesn't matter in
-32-bit builds, but in the 64-bit world, the test for failure didn't work
-right. I made a Solaris-specific workaround, and checked that it works in
-both 32-bit and 64-builds. I really hate typedefs. ckcnet.c, 15 Aug 2005.
-
-Changed the plain-text version (as opposed to the popup or GUI version - the
-GUI version, at least, already does this) of ASKQ to echo keystrokes
-asterisks rather than simply not echo anything, so it's easier to see what
-you're doing, the effects of editing, etc. Experimental; for now, there's
-no way to disable this. Not sure if there needs to be. Anyway, to get this
-working required a fair amount of cleaning up of gtword(), which was echoing
-different ways in different places. ckuus6.c, ckucmd.c, 15 Aug 2005.
-
-Added a solaris9_64 target for building a 64-bit version on Solaris 9 with
-Sun cc. Verified, using the DIR command and \fsize() function on a 4.4GB
-file, that the Solaris 64-bit version of Kermit gets the size correctly, and
-that it can copy such a file (thus its fopen/fread/fwrite/fclose interface
-works right). Initiated a large-file transfer between here and Utah over
-SSH and verified that it puts the correct file size in the A packet when
-sending; the right quantities are shown on the file transfer display (file
-size CPS, percent done, etc). But even at 5Mb/sec, it takes a good while to
-transfer 4.4GB, more than 2 hours (not streaming; 30 window slots, 4K
-packets, maybe it would go faster with streaming)... After an hour or so,
-it filled up the partition and gave up (gracefully) before it reached the
-2GB frontier (drained its pending packets, closed the partial file).
-Restarted at 12:54, this time with streaming and 8K packets (the speed
-wasn't significantly different). This time it transferred 95% of the file
-(4187660288 bytes) before failing because the disk filled up. Went to Utah
-and started a transfer between two Solaris 10/Sparc hosts; this goes about 8
-times faster. The transfer completed successfully after 17m41s. All fields
-in the f.t. display looked right the whole time. Then I verified various
-other 64-bit combinations transferring the same 4.4GB file:
-
- To................
- From Sol Amd i64 Tru
- Sol OK OK OK OK Sol = Solaris 10 / Sparc
- Amd OK Amd = AMD x86_64 RH Enterprise Linux AS4
- i64 OK i64 = Intel IA64, RH 2.1AS
- Tru Tru = Tru64 Unix 4.0F Alpha
-
-(The other combinations are difficult to test for logistical reasons.)
-
-Tried sending the same long file with Kermit's FTP client. It chugged along
-for a while until I stopped it; it would have taken hours to complete.
-There is no indication that it wouldn't have worked, assuming the FTP server
-could also handle long files, which who knows. Anyway, Kermit showed all
-the right data on the display screen. 17 Aug 2005.
-
-On AMD x86_64 and IA64 native 64-bit Linux builds, the pty routines did not
-work at all. ptsname() dumped core. If I commented out ptsname(), then the
-next thing dumped core. The same code works on the other 64-bit builds.
-Poking around, I see that this version of Linux has an openpty() function,
-which I could try using instead of the current API -- grantpty(), etc. Then
-I see that openpty() is already coded into Kermit's pty module,
-conditionalized under HAVE_OPENPTY, which has never before been defined for
-any build. I added a test to the makefile linux target (look for the
-openpty() prototype in <pty.h>, if found define HAVE_OPENPTY as a CFLAG and
-also add -lutil to LNKFLAGS). Works fine on the problem builds, and also
-on previously working 32-bit builds. makefile, 17 Aug 2005.
-
-Fixed a bug in the ASKQ echo asterisks code, which made the VMS version of
-C-Kermit always echo asterisks. Turns out that some code in the main parse
-loop to reset command-specific flags was in the wrong place, which had other
-effects too, for example ASKQ temporarily turns off debug logging as a
-security measure, but the code to turn it back on was skipped in most cases.
-Some other side effects related to the DIRECTORY and CD commands might have
-been possible but I haven't seen them. ckuus[56].c, 23 Aug 2005.
-
-Problem reported when sending a file to VMS when the name in the F packet
-starts with a device specification and does not include a directory field,
-and PATHNAMES are RELATIVE. Example: dsk:foo.bar becomes f_oo.bar. The
-code assumes that if there is a device field, it is followed by a directory
-field, and it inserts a dot after the '[', which in this case is not there.
-Later the dot becomes '_' because of the only-one-dot rule. Solution: only
-insert the dot if there really is an opening bracket. nzrtol(): ckvfio.c,
-23 Aug 2005.
-
-A report on the newsgroup complains that C-Kermit and K95 servers were
-sending REMOTE DIR listings with only #J line terminators, rather than #M#J.
-Yet all the other REMOTE xxx responses arrived with #M#J. snddir() was
-neglecting to switch to text mode. ckcfns.c, 26 Aug 2005.
-
-Back to long files. What happens if 32-bit Kermit is sent a long file?
-It gets an A-packet that looks like this:
-
- ^A_"A."U1""B8#120050815 18:28:03!'42920641*4395073536,#775-!7@ )CP
-
-The 32-bit receiver reacts like so:
-
- gattr length[4395073536]=100106240
-
-the first number being the string from the A-packet, the second being the
-value of the long int it was converted to by atol(). Clearly not equal in
-this case. When this happens Kermit should reject the file instead of
-accepting it and then getting a horrible error a long time later. Added
-code to gattr() to convert the result of atol() back to a string and compare
-it with the original string; if they're not equal, reject the file on the
-assumption that the only reason this could happen is overflow. Also some
-other code in case the sender sends the only LENGTHK attribute. Now files
-whose lengths are too big for a long int are rejected right away, provided
-the sender sends the length in an A packet ahead of the file itself. If
-this new code should ever cause a problem, it can be bypassed with SET
-ATTRIBUTE LENGTH OFF. ckcfn3.c, 26 Aug 2005.
-
-As I recall from when I was testing this a few weeks ago, when the too-big
-length is not caught at A-packet time, the transfer fails more or less
-gracefully when the first attempt is made to write past the limit. I went
-to doublecheck this by sending a big file from the 64-bit Solaris10 version
-to a 32-bit Mac OS X version that does not have today's code. The Mac
-thinks the incoming file is 2GB long when it's really 4GB+. But in this
-case, something new happens! Although the percent done and transfer rate go
-negative, the file keeps coming. It would seem that Mac OS X lets us create
-long files without using any special APIs. The transfer runs to completion.
-Mac OS X Kermit says SUCCESS (but gets the byte count and cps wrong, of
-course). But then a STATUS command says FAILURE. The file was, however,
-transferred successfully; it is exactly the same length and compares byte
-for byte with the original. This tells me that in the Mac OS X version --
-and how many others like it??? -- today's rejection code should not be
-enabled. Meanwhile I put today's new code in #ifndef NOCHECKOVERFLOW..#endif,
-and defined this symbol in the Mac OS X 10.4 target. Over time, I'll have
-to find out what other platforms have this characteristic. And of course
-I'll also have to do something about file-transfer display, statistics, and
-status. makefile, ckcfn3.c, 26 Aug 2005.
-
-From now on I'm going to bump the Dev.xx number each time I upload a new
-ckdaily. This one will be Dev.02. ckckmai.c, 26 Aug 2005.
-
-Got rid of all the extraneous FreeBSD 4 and 5 build targets. Now there's
-one (freebsd) for all FreeBSD 4.1 and later. makefile, 27 Aug 2005.
-
-Mac OS X 10.4 (Tiger) is a 64-bit OS. Building C-Kermit 0n 10.4.2 without
-any special switches stilll gives a 32-bit executable. Ditto building with
--mpowerpc64. Further investigation turned up a tip sheet on MySQL that says
-you have to include all of these: -mpowerpc64 -mcpu=G5 -mtune=G5 -arch
-ppc64. That did the trick. New makefile target: macosx10.4_64. But the
-10.4.2 system I tried did not have 64-bit [n]curses or resolv libs, so this
-build has no -DNOCURSES -DNO_DNS_SRV. makefile, 27 Aug 2005.
-
-Created a symbol CK_64BIT to indicate true 64-bit builds at compile time.
-Added 64-bit announcement to the startup herald and the VERSION text.
-ckcdeb.h, ckuus[r5].c, 27 Aug 2005.
-
-Added a built-in variable \v(bits) to indicate the size of the build
-(16, 32, 64, or whatever else sizeof() might report). ckuusr.h, ckuus4.c,
-27 Aug 2005.
-
-Got rid of all the warnings in 64-bit Mac OS X about args to getsockopt(),
-getsockname(), and getpeername(), and the comparisons on the return value
-of inet_addr(). ckcnet.[ch], 27 Aug 2005.
-
-Now to check the effects on other builds...
- Linux on AMD64: ok.
- Linux on IA64: ok.
- Linux on i386: ok.
- Mac OS X 10.3.9 32-bit: ok.
- Solaris 10 64-bit: ok.
- Solaris 9 32-bit: ok.
- Tru64 4.0F: ok.
- FreeBSD 4.11: ok.
- FreeBSD 5.4 ia64 (64-bit): ok.
- FreeBSD 5.4 i386 (32-bit): ok.
-
-The Tru64 5.1B build totally blew up because they have their own unique
-sockopt/etc length-argument data type (int!), so I had to roll back on using
-socklen_t for this in all 64-bit builds. Checked to make sure it still
-builds on Tru64 4.0F after this change (it does). ckcnet.h, 27 Aug 2005.
-
-The HP-UX 11i/ia64 build comes out to be 32-bit but thinks it's 64-bit.
-CK_64BIT is set because __ia64 is defined. So how do I actually make a
-64-bit HP-UX build? I tried adding +DD64 to CFLAGS, and this generates
-64-bit object files but linking fails to find the needed 64-bit libs
-(e.g. -lm). For now I added an exception for HPUX to the CK_64BIT
-definition section. ckcdeb.h, 27 Aug 2005.
-
-Took the time to verify my recollection about the "graceful failure" on a
-regular Pentium Linux system when receiving a too-big file... OK, it's not
-exactly graceful. It gets a "File size limit exceeded" error; the message
-is printed in the middle of the file-transfer display, apparently not by
-Kermit, and Kermit exits immediately. Looks like a trap... Yup. "File
-size limit exceeded" is SIGXFSZ (25). What happens if we set it to SIG_IGN?
-Just the right thing: The receiver gets "Error writing data" at 2147483647
-bytes, sends E-packet to sender with this message, and recovers with total
-grace (drains packet buffers, returns to prompt). ckutio.c, 27 Aug 2005.
-
-Backed off from rejecting a file because its announced size overflows a
-long. Now instead, I set the file size to -2 (a negative size means the
-size is unknown, but we have always used -1 for this; -2 means "unknown and
-probably too big"). In this case, the f-t display says:
-
- File Size: POSSIBLY EXCEEDS LOCAL FILE SIZE LIMIT
-
-then the user can interrupt it with X or whatever, or can let it run and
-see if maybe (as in the case of Mac OS X) it will be accepted anyway. This
-way, we skip all the bogus calculations of percent done, time remaining, etc.
-ckcfn3.c, ckuusx.c, 27 Aug 2005.
-
-Discovered that VMS C-Kermit on Alpha and IA64 is a 32-bit application;
-sizeof(long) == sizeof(char *) == 4. Tried adding /POINTER_SIZE=64 to VMS
-DECC builds on Alpha and IA64, but the results aren't great. Tons of
-warnings about pointer size mismatches between Kermit pointers and RMS ones,
-and the executable doesn't run. It appears that access to long files
-would require a lot of hacking, similar to what's needed for 32-bit Linux.
-
---- Dev.02: 27 Aug 2005 ---
-
-From Jeff, 28 Aug 2005.
- . Fix SSH GLOBAL-KNOWN-HOSTS-FILE / USER-KNOWN-HOSTS-FILE parsing, ckuus3.c.
- . Pick up K95STARTFLAGS from environment, ckuus4.c.
- . Fix some typos in command-line processing (-q), ckuus4.c.
- . Be sure to suppress herald if started with -q, ckuus7.c.
- . Fix ssh command-line switches, ckuusy.c.
-
-Eric Smutz complained that HTTP POST was adding an extraneous blank line,
-which prevented his application from successfully posting. RFC 2616 states
-(in Section 4.1):
-
- In the interest of robustness, servers SHOULD ignore any empty
- line(s) received where a Request-Line is expected. In other words, if
- the server is reading the protocol stream at the beginning of a
- message and receives a CRLF first, it should ignore the CRLF.
-
- Certain buggy HTTP/1.0 client implementations generate extra CRLF's
- after a POST request. To restate what is explicitly forbidden by the
- BNF, an HTTP/1.1 client MUST NOT preface or follow a request with an
- extra CRLF.
-
-This seems pretty clear. One section of code in http_post() (just above the
-postopen: label) was appending a CRLF to a buffer whose last already was
-terminated by CRLF, and then appended a second CRLF; thus two empty lines.
-I removed the second one. ckcnet.c, 28 Aug 2005.
-
-I looked into the 64-bitness of NetBSD, it seems to be like Linux and
-FreeBSD on 64-bit hardware, i.e. you just build it there and it works, at
-least on Alpha and AMD64, going back to NetBSD 1.4 or 1.5. But I don't have
-access to any of these for verification and documentation on the Web is
-scanty.
-
-Checked PeterE's complaint again of warnings in ckutio.c about parameter
-list of get[ug]id() and gete[ug]id(). When I "make hpux1100o" on HP-UX
-11.11 (PA-RISC), there are definitely no warnings. He says the same thing
-happens on 10.xx, but I don't have access to that any more. I also did
-"make hpux1100o" on HP-UX 11.23 (11i v2) (PA-RISC), also no warnings.
-(Except in both cases, a warning about a comment within a comment in
-/usr/include/sys/ptyio.h). On HP-UX 11i v2 on Itanium, however, there are
-TONS of warnings, mostly of the "variable set but never used" kind. Also
-"dollar sign used in identifier". Tracking this last one down, I see it's
-complaining about code that's in #ifdefs for other platforms, such as
-Apollo Aegis. Is "aegis" defined in HP-UX 11i v2/IA64? No! (It would show
-up in SHOW FEATURES if it was.) Some phase of the compiler is complaining
-about code that it should be skipping (and that, in fact, it *is* skipping
-it because the build is successful). It's as if cc is running lint for me
-but not telling lint which macros are defined and which are not.
-
-Verified that 64-bit linking fails in the same way for HP-UX 11i v2 on both
-IA64 and PA-RISC. Sent a query to HP.
-
-Compiling ckcnet.c and ckcftp.c got the familiar sockopt-related warnings on
-HP-UX 11i v2; turns out it is just like Tru64 Unix in using an int for the
-length argument. Added another special case and the warnings went away.
-ckcnet.h, 28 Aug 2005.
-
-Added some stuff to SHOW FEATURES to see what kinds of macros are exposed
-(e.g. INT_MAX, LONG_MAX, LLONG_MAX, etc) and also show sizeof(long long) and
-sizeof(off_t). Building this code all over the place will give me an idea
-of how widespread these data types are, and to what extent I can tell
-whether they are available from clues in the header files. (At first
-glance, it appears that I'm not picking up <limits.h>, but adding an
-#include for it is just asking for trouble.) No complaints about long long
-or off_t from Solaris 9 or recent Linuxes. ckuus5.c, 28 Aug 2005.
-
-Fixed a warning in HP-UX 10 and 11 stemming from some old-style prototypes
-in ckutio.c for get[re][gu]id(). ckutio.c, 29 Aug 2005.
-
-Updated minix3 target from Andy Tanenbaum. makefile, 29 Aug 2005.
-
-PeterE confirms that "long long" and off_t are available in all HP-UX 10 and
-11, and in HP-UX 9 on PA-RISC but not Motorola. 30 Aug 2005.
-
-Got 64-bit builds to work on HP-UX. According to my notes, John Bigg of HP
-said (in 1999) that HP-UX 10.30 and later require PA-RISC 1.1, and do not
-work on PA-RISC 1.0. But is PA 1.0 64-bit or what? Today, Alex McKale of
-HP said "The 64-bit binaries will work on all machines that have the same or
-later release of HP-UX (excluding PA-RISC 1.1 machines)". Still need
-clarification... Maybe it's that all IA64 builds can be 64-bit but I need
-dual builds for PA-RISC. Meanwhile I started transfer of a 4GB+ file from
-Solaris to HP-UX 11i but it exceeded some quota on the HP long before it
-approached the 2G point. It failed cleanly and up until then it was working
-fine (numbers, stats, etc). 30 Aug 2005.
-
-Support of large files in 32-bit builds began in 10.20. 64-bit application
-support began in 11.00, but not all machines that run 11.00 support 64 bits.
-About long files, see HP /usr/share/doc/lg_files.txt.
-
-PeterE found that certain patterns can still make Kermit loop; example:
-
- if match T01011-00856-21-632-073 *[abc] { echo GOOD } else { echo BAD }
- if match T01011-00856-21-632-073 *[a-z] { echo GOOD } else { echo BAD }
-
-The minimum offending pattern is * followed immediately by an [xxx]
-construction, followed by anything else, including nothing. Previous
-versions of Kermit handled this one correctly, without looping (but failed
-certain matches that should have succeeded). The new section of code I
-added on 15 June, upon failure to match, advances the string pointer and
-backs up the pattern to the previous pattern, and starts again
-(recursively). However, there needed to be a corresponding check at entry
-for an empty target string. ckmatch(): ckclib.c, 12 Sep 2005.
-
-PeterE discovered that "kermit -y filethatdoesnotexit" gives an erroneous
-error message that names the user's customization, rather than the name
-given on the command line. doinit(): ckuus5.c, 12 Sep 2005.
-
-FREAD does not get an error if it tries to read a record or file or piece of
-file that is too big for its buffer. In particular, FREAD /SIZE:xxx seems
-to succeed even if less than xxx was read. It should fail unless, perhaps,
-it successfully read up to the end of the file. Furthermore, if xxx is
-bigger than the file buffer size, it should complain. The buffer is
-line[LINBUFSIZ], 32K. The lack of failure was due to code in dofile() that
-adjusted the given size silently if it was greater than the buffer size,
-which I removed, and also added a check when parsing the /SIZE: switch.
-dofile(): ckuus7.c, 12 Sep 2005.
-
-That still didn't help with FREAD /SIZE:n returning less than n bytes, even
-when they were available. That's because the underlying routine, z_in(),
-didn't check fread()'s return code, which is the number of bytes read.
-If fread() has smaller buffers, it needs to be called in a loop. z_in():
-ckuus7.c, 12 Sep 2005.
-
-Flen() fails on strings of length 8192 or more. The limitation is in the
-callers of zzstring, which seem to be specifying an 8K buffer, in this case
-fneval(). The operable symbols are FNVALL (max length of value returned by
-a function) and MAXARGLEN (maximum length of an argument to a function). I
-changed both of these for BIGBUFOK builds to be CMDBL. Buffers can never be
-infinite, there has to be a limit. It's important to make everything work
-consistently within that limit, and to make something useful happen when the
-limit is exceeded. At this point, I can probably also increase the limits
-for modern 32-bit systems, and certainly for 64-bit ones. Also there's no
-point in worrying about 16-bit platforms any more; earlier C-Kermit versions
-can still be used on them if necessary. ckuusr.h, 12 Sep 2005.
-
-Special #ifdefs for finding resolv.h and nameser.h in MINIX3 from Andy
-Tanenbaum. ckcnet.c, 20 Sep 2005.
-
-PeterE noticed that ckmatch(), even though it works pretty well now, does a
-lot of extra and unnecessary recursion after determining the string and
-pattern do not match, at least when the pattern is of the form *[abc].
-After several false starts I was able reduce this effect to a minor level
-(but not eliminate it all together) by changing a while loop into a do loop.
-ckmatch(): ckclib.c, 15 Oct 2005.
-
-Added -DNOLONGLONG to HP-UX 8.00 and earlier builds, and to Motorola-based
-HP-UX 9.00 builds. This is simply to inhibit the test for whether "long
-long" is supported by the compiler, since when it isn't, the module
-containing the test won't compile. makefile, ckuus5.c, 16 Oct 2005.
-
-Making ASKQ always echo asterisks is a bad idea, because when it doesn't
-echo, it's the perfect way to read silently from stdin, e.g. in a CGI script
-(INPUT can also be used for this but it's not as straightforward). So I put
-the default for ASKQ back to no echoing, then gave ASKQ its own switch
-table, which is the same as for ASK with the addition of an /ECHO:x switch,
-which tells what character to echo. ckucmd.c, ckuus[26].c, 17 Oct 2005.
-
-Fixed a bug in FTP GET /COMMAND filename commandname; it always dumped core
-dereferencing a null string (the nonexistent local asname). ckcftp.c,
-17 Oct 2005.
-
-For docs: if you don't like the funny business that happens when you type
-an IF command at the prompt, use XIF instead and it won't happen. Also note
-that commands like "if xxx { echo blah } else { echo blah blah }" don't
-work when typed at the prompt; you have to use XIF for this.
-
-Back to ckmatch()... Under certain conditions (e.g. patterns like *[abc])
-failure to match would not stop the recursion because the string and pattern
-arguments are on the stack, as they must be, so there was no way for level
-n-1 to know that level n had detected a definitive nonmatch and that no
-further attempts at matching were required. The right way to handle this is
-to recode the whole thing as coroutines, the cheap way out is with a global
-static flag. Works perfectly, in the sense that the match.ksc test results
-are identical to what they were before and the extra backing up and
-recursion are eliminated. (The Oct 15th fix wasn't really a fix, it broke
-a couple of cases.) ckclib.c, 20 Oct 2005.
-
-ckuus7.c(2987): warning #267: the format string requires additional arguments
-(in PURGE command); fixed 20 Oct 2005.
-
-From Andy Tanenbaum, final changes for MINIX3: #ifdef out the inline
-definitions for gettimeofday() and readlink(). ckutio.c, 23 Oct 2005.
-
-From Jeff: struct gss_trials initializers changed from gss_mech_krb5 to
-ck_gss_mech_krb5. ckcftp.c, 23 Oct 2005.
-
-From Jeff: some improvements to K95 GUI SHOW TERMINAL. ckuus5.c, 23 Oct 2005.
-
-Found and corrected some misplaced #ifdefs in shofeat(), ckuus5.c, 23 Oct 2005.
-
---- Dev.03 ---
-
-Fixed a compiler warning in a debug() statement in zzstring() by adding
-parens. ckuus4.c, 24 Oct 2005.
-
-Added -DNOLONGLONG to sv68r3v6 target, makefile, 25 Oct 2005.
-
-New makefile targets for HP-UX from PeterE to handle the 'long long'
-situation. 26 Oct 2005.
-
-From Jeff: changes to support OpenSSL 0.9.8, ck_ssl.h. ckcasc.h has had
-short names defined for ASCII control characters for 20-some years but now
-they are causing conflicts, so EM becomes XEM (also for OpenSSL 0.9.8).
-Changed K95's default terminal type from VT320 to VT220 because VT320
-termcaps/terminfos are disappearing from Unix hosts: ckuus7.c. Reorganize
-the data-types section of SHOW FEATURES to add more macro tests for integral
-sizes and to provide for the proper printf formatting in order to allow the
-sizes to be output ("You are going to need to be careful because %llx is not
-supported on all platforms. On Windows, it is the same as %lx, 32 bits"):
-ckuus5.c, 26 Oct 2005.
-
-Defined NOLONGLONG ckcdeb.h for various old platforms where we know we are
-never going to need 64-bit ints (even if they support a long long datatype,
-chances are pretty slim they supported 64-bit file sizes). ckcdeb.h,
-26 Oct 2005.
-
-PeterE noticed that GOTO targets can only be 50 characters long. This was
-by design, a long time ago, on the assumption that nobody would make longer
-labels. But in SWITCH statements, case labels can be variables that expand
-to anything at all. If we chop them off at 50, we might execute the wrong
-case. Changed the maximum label size to be 8K, and added code to dogoto()
-to check when a label or target is too long and fail, to prevent spurious
-GOTO or SWITCH results. ckuusr.h, ckuus[r6].c, 26 Oct 2005.
-
-Testing revealed there was still a problem with SWITCH case labels that were
-variables that expanded into long strings. Turns out that I was being
-too clever when I decided that, if the SWITCH macro was n1 characters long
-and the case-label search target was n2 characters long, I only had to
-search the first n1-n2+1 characters of the macro definition. That was true
-before I allowed case labels to be variables, but not any more! Fixed in
-dogoto(): ckuus5.c, 26 Oct 2005.
-
---- Dev.04 ---
-
-Dev.04 didn't actually contain Jeff's data-type changes to shofeat(),
-I think I saved the wrong buffer in EMACS... Fixed now. 27 Oct 2005.
-
-PeterE corrected a typo in the HP-UX 7.00 makefile target. 27 Oct 2005.
-
-PeterE had been reporting problems stress-testing the new SWITCH code, but
-only on HP-UX 9, primarily stack overrun. Turns out to be the HP-UX 9
-optimizing compiler's fault. No optimization, no problems.
-
-PeterE found that even when dogoto() detects a string that is too long
-and fails, this does not stop SWITCH from producing a result, which can not
-possibly be trusted. Changed the part of dogoto() that handles this to
-not just fail, but also to exit the script immediately and return to top
-level. ckuus6.c, 28 Oct 2005.
-
-An idea popped into my head after having typed too many commands like "dir
-ck[cuw]*.[cwh]" to check the list of matching files, and then having to
-retype the same filespec in a SEND command: Why not unleash some unused
-control character such as Ctrl-K to spit out the most recently entered input
-filespec? It was easy, just a few lines in cmifi2() and gtword(), plus a
-couple declarations. To see all the changes, search for "lastfile" (all the
-new code is protected by #ifndef NOLASTFILE). ckucmd.c, 28 Oct 2005.
-
-I added a new variable \v(lastfilespec) that expands to the same last
-filespec, for use in scripts. ckuusr.h, ckuus4.c, 28 Oct 2005.
-
-The Unix version of C-Kermit failed to put anything in the session log if
-SET TERMINAL DEBUG ON. Rearranged the pertinent clause so logging happens
-independent of TERMINAL DEBUG. For now, since the user who noticed this
-wanted debug format to go into the session log, that's what I do. The
-alternative would be to just log the raw incoming stream as usual, or to add
-Yet Another SET Command to choose. ckucns.c, 11 Nov 2005.
-
-Fixed HELP INTRO text. ckuus2.c, 11 Nov 2005.
-
-Added NOLONGLONG for SV68. ckcdeb.h, 11 Nov 2005.
-
---- Dev.05 ---
-
-Added a debug() statement in FTP secure_getbyte() to see what's going on
-with Muhamad Taufiq Tajuddin's 205-byte-per-second FTP/SSL downloads.
-
---- Dev.06 ---
-
-Result: nothing, SSL_get_error() does not report any errors. Suggested
-testing SSL_read()'s return code, if 0 don't update the screen.
-
-Created a new data type CK_OFF_T in ckcdeb.h that will eventually resolve
-to whatever each platform uses for file sizes and offsets. ckcdeb.h,
-17 Nov 2005.
-
-Made a new library routine ckfstoa() that converts a file size or offset to
-a string. This is to solve the problem with having to use different
-printf() formats for different representations of file size (int, long, long
-long, off_t, signed, unsigned, etc). Replaced a few printf("%l",size) with
-printf("%s",ckfstoa(size)) with the expected results. This is just a start,
-the definitions will need adjustment for many platforms, variables need to
-be redeclared, and all the offending printf's (and printw's) will have to
-hunted down and converted. ckclib.[ch], ckuus4.c, 17 Nov 2005.
-
-Built a minimal version on Linux with:
-make linux "KFLAGS=-DNOLOCAL -DNOICP -DNOCSETS -DNODEBUG"
-Worked fine, result was 260K on i686. 21 Nov 2005.
-
-Discovered that Kermit's date parser, contrary to the documentation, failed
-to handle strings like "Wed, 13 Feb 2002 17:43:02 -0800 (PST)", which are
-commonly found in email. This was because of an overzealous and misguided
-check in the code; once removed, all was well. ckucmd.c, 26 Nov 2005.
-
-Added a new format code 4 to \fcvtdate() to emit asctime() format, used in
-BSD-format email message envelopes (i.e. the "From " line). shuffledate(),
-ckucmd.c, ckuus[24].c, 26 Nov 2005.
-
-Added a new function \femailaddress(). Given a From: or Sender: header line
-from an RFC2822-format email address, extracts and returns the actual email
-address, such as kermit@columbia.edu. ckuusr.h, ckuus[42].c, 26 Nov 2005.
-
-Using the new functions, I wrote a script to fetch mail from a POP3 server
-over a TLS connection. But the line-at-a-time input (needed for changing
-line terminators and byte-stuffing text lines that start with "From ") is
-slow, 17 sec to read 29 messages totaling 175K.
-
-Added INPUT /CLEAR so INPUT can be started with a clean buffer without
-requiring a separate CLEAR INPUT command. ckuusr.h, ckuus[r24].c,
-27 Nov 2005.
-
-One thing that INPUT was never able to do well was read and save the
-complete incoming data stream. That's because, while waiting for its
-target, the buffer might overflow wrap around. Yet there was never a way to
-tell it to stop when its buffer fills up and let me save it. I added a
-/NOWRAP switch that does this. If the buffer fills up before any other
-completion criterion is met, INPUT returns failure, but with \v(instatus)
-set to 6 (the next available instatus value). Thus a program that wants to
-read and save (say) an email message from a POP server, which could be any
-length at all, and which terminates with <CRLF>.<CRLF> could do this:
-
- set flag off
- while open connection {
- input /nowrap 10 \13\10.\13\10 # Wait for <CRLF>.<CRLF>
- if success {
- frwrite /string \%o {\freplace(\v(input),\13\10.\13\10,\13\10)}
- set flag on
- break
- } else if ( == \v(instatus) 6 || == \v(instatus) 1 ) {
- frwrite /string \%o {\v(input)}
- continue
- }
- break
- }
- if flag (handle success)
-
-Note carefully the braces around the FWRITE text; without them, trailing
-spaces would be lost.
-
-Previously the only way to INPUT an entire data stream without losing
-anything (assuming it was ordinary lines of text that were not "too long"),
-was line-by-line:
-
- while open connection {
- input /clear 10 \13\10
- if fail break
- if eq "\v(input)" "$ \13\10" break
- fwrite /string \%o {\freplace(\v(input),\13\10,\10)}
- }
-
-The new code is 3 times faster using the default INPUT buffer length of 4K.
-Raising it to 16K makes it 3.6 times faster (not worth it). Changing the
-POP3 script to use INPUT /NOWRAP makes it about twice as fast (it does more;
-it has to do all the byte-stuffing and unstuffing). 27 Nov 2005.
-
-Changed ssl_display_xxx() to just return if SET QUIET ON. Otherwise there
-is no way to suppress the messages. Also protected a previously unprotected
-printf("[SSL - OK]\r\n"); by if ( ssl_verbose_flag ). ck_ssl.c,
-28 Nov 2005.
-
-Discovered that FOPEN /APPEND doesn't work if the file doesn't exist. It
-uses cmiofi() which is a super-hokey front end to cmifi2(). I had code to
-call it but for some reason it was commented out, with a note to the effect
-it didn't work. I uncommented it but that didn't help much. So I wrote an
-entirely new cmiofi() that works exactly as it should, using chained FDBs,
-_CMIFI to _CMOFI (I think the original cmiofi() predated chained FDBs).
-ckuus7.c, ckucmd.c, 29 Nov 2005.
-
-Getting rid of the awful hacks required to call cmiofi() meant I also had to
-change the EDIT command, which is the only other place where it's used.
-Unfortunately now it's no longer possible to give EDIT without a filename
-(to just start an empty editor) but I doubt anyone will notice. ckuusr.c,
-29 Nov 2005.
-
-IF KERBANG didn't always work right. If a kerbang script TAKEs another
-kerbang script, the second one should have IF KERBANG false, but it didn't.
-Added a check for \v(cmdlevel) == 1. Now you can write a wrapper that runs
-a kerbang script in a loop, and the latter can use IF KERBANG to know
-whether to EXIT (if called at top level) or END (if called by another
-script, thus allowing -- in this case -- the loop to continue). ckuus6.c,
-29 Nov 2005.
-
-Changed \flop() and flopx() functions to take a third argument, a number
-signifying at which occurrence of the break character to lop, so:
-
- \flopx(sesame.cc.columbia.edu) = edu
- \flopx(sesame.cc.columbia.edu,,2) = columbia.edu
-
-ckuus[24].c, 1 Dec 2005.
-
-Built OK on VMS 7.2-1 with MultiNet 4.4. Built with and without OpenSSL on
-Linux OK, ditto Solaris 9. Built OK on RH Linux AS4 on X86_64 (64-bit);
-"show var fsize" (using new ckfstoa()) works OK there. Also Mac OS X 10.3.9
-(32-bit), Tru64 UNIX 4.0F (64-bit), HP-UX 11iv2 (64-bit) (picky new compiler
-spews out tons of useless warnings), FreeBSD 6.0 on ia64 (64-bit).
-
---- Dev.07 ---
-
-Changed "make netbsd" to be a synonym for "make netbsd2" because the
-original netbsd target was ancient. Renamed it to netbsd-old. makefile,
-3 Dec 2005.
-
-Updated INPUT and MINPUT help text. ckuus2.c, 3 Dec 2005.
-
-Discovered that on a SET PORT /SSL connection, Kermit treats incoming
-0xff data bytes (e.g. sent from the POP server) as IACs and goes into Telnet
-negotiations. Jeff says "You will need to implement NP_SSLRAW and NP_TLSRAW
-that do the same as NP_TCPRAW but negotiate SSL or TLS as appropriate."
-This was not as easy as it sounded, because apparently a lot of the Telnet
-code is used by SSL and TLS even when Telnet protocol is not being executed.
-I wound up doing this as follows: I added /SSL-RAW and /TLS-RAW to the
-switch table. Rather than disable Telnet, they do exactly what the /SSL and
-/TLS switches do, but also set a special flag. This flag is checked in only
-two place: netclos() (to prevent Kermit from sending TELNET LOGOUT when
-closing the connection), and tn_doop() (to prevent Kermit from reacting to
-incoming IACs; it makes tn_doop() return(3), which means "quoted IAC", which
-causes the caller to keep the IAC as data). ckcnet.h, ckctel.h, ckctel.c,
-ckuus7.c, 4 Dec 2005.
-
-The INPUT command did not account for tn_doop() returning 3. Fixed in
-doinput(), ckuus4.c, 4 Dec 2005.
-
-Added another debug() statement in FTP secure_getbyte() to see what's going on
-with Muhamad Taufiq Tajuddin's 205-byte-per-second FTP/SSL downloads, plus
-new code to test SSL_read()'s return code (byte count); if 0 don't update
-the screen. ckcftp.c, 4 Dec 2005.
-
---- Dev.08 ---
-
-Fixed a typo in the non-ANSIC definition of ckfstoa(). ckclib.c, 7 Dec 2005.
-
-Our Ctrl-C trap (the ON_CTRLC macro) wasn't working for kerbang files.
-Rearranged some code to make it work. ckcmai.c, 8 Dec 2005.
-
-Started converting code to use CK_OFF_T for file sizes and offsets, and
-all [s]printf's to replace "%ld" or whatever with "%s", and the size
-variable with a call to ckfstoa(). Since I haven't actually changed the
-definition of CK_OFF_T from what all the size variables were to begin
-with (i.e. long), it shouldn't do any harm. So far just ckcfn3.c
-10 Dec 2005.
-
-An updated HP-UX 9.xx makefile target from PeterE to fix a core dump that
-happens on that platform due to insufficient resources. 14 Dec 2005.
-
-Added debug() statements to http_blah() routines to tell whether the
-connection is "chunked". There seems to be a bad performance problem.
-ckcnet.c, 14 Dec 2005.
-
-PeterE complained about ugly DIRECTORY error message, ?No files match -
-"{blah}". The braces are used internally in case the user typed more than
-one filespec. I changed the error message to remove them. Ditto DELETE.
-ckuus6.c, 15 Dec 2005.
-
-The problem with HTTP downloads is that Kermit always does single-character
-read() or socket_read() calls (or the SSL equivalent); see http_inc(). I
-added buffering code for non-SSL connections only but it's gross because it
-has to swap ttyfd and httpfd before calling nettchk(). I tried making a
-nettchk() clone that accepts a file descriptor as an argument but it didn't
-work because too many other routines that are invoked directly or implicitly
-by nettchk() (such as in_chk()) are still hardwired to use ttyfd. HTTP GETs
-are now 20 times faster on the local network (the improvement is less
-dramatic over a clogged Internet). ckcnet.[ch], 15 Dec 2005.
-
---- Dev.09 ---
-
-HTTP file-descriptor swapping is not thread safe. Doing it right, of
-course, is a big deal, so for now I just don't define HTTP_BUFFERING for
-Windows. ckcnet.c, 15 Dec 2005.
-
-Noticed that HTTP not included in FreeBSD and OpenBSD builds. Fixed in
-ckcdeb.h, 22 Dec 2005.
-
-Fleshed out 32/64-bit data type definitions and changed struct zattr
-(file attribute structure) members length and lengthk to have the new
-CK_OFF_T type. Changed final arguments of debug() and tlog() to be the new
-LONGLONG type. ckcdeb.h, 22 Dec 2005.
-
-Changed ckfstoa() to return a signed number in string form, rather than an
-unsigned one. That's because off_t is signed (thank goodness). Added the
-inverse function, ckatofs() so we can convert file sizes and offsets back
-and forth between binary number and string. ckclib.c, 22 Dec 2005.
-
-Changed Attribute Packet reader to convert incoming file size attribute
-with ckatofs() rather than atol(). ckcfn3.c, 22 Dec 2005.
-
-Converted debug(), tlog(), ckscreen(), etc, to handle potentially "long long"
-arguments by making their "n" argument CK_OFF_T. ckuusx.c, ckcdeb.h,
-22 Dec 2005.
-
-Converted the rest of the source files to use CK_OFF_T for all file size
-and offset and byte-count related variables, and converted all references to
-these variables in printfs to go through ckfstoa(). Then I built it on
-Linux/i386 with:
-
- make linux "KFLAGS=-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
-
-which makes off_t be 64 bits and magically makes all the regular file APIs
-use 64-bit sizes and offsets without changing the API calls in the source
-code. It's going to be a lot of work to get through all the kinks but I was
-able to send a long file, do directory listings of long files, do
-\fsize(longfile), etc. When it sends a file, the length is shown correctly
-in the A packet. If the receiver does not support big numbers, it receives
-the file OK anyway, without showing the size, the thermometer, or percent
-done (and then will get an error when the file keeps coming after the 2G
-mark). Kermit 95 actually refuses long files for "Size", but only if the
-announced is less than 2^63 bytes. When today's Linux version receives a
-file, it shows the length correctly in the file-transfer display, as well as
-percent done, thermometer, etc. Also built this version on true 64-bit
-Linux, and it worked fine. Many files changed, 22 Dec 2005.
-
-For the record, this API is specified in X/Open's Single UNIX Specification
-Version 2, which is branded as UNIX 98. It is called Large File Support, or
-LFS, and was developed at the Large File Summit.
-
-It looks like the operative feature-test macro in glibc for transitional
-large file support is __USE_LARGEFILE64. So if this is defined, we can also
-supply _LARGEFILE_SOURCE and _FILE_OFFSET_BITS=64 automatically for 32-bit
-Linux builds. But there's a Catch-22, you don't know if this is defined
-until you read the header files, but you have to define _LARGEFILE_SOURCE
-and _FILE_OFFSET_BITS before you read the header files. Maybe it's good
-enough to grep through <features.h> for __USE_LARGEFILE64. makefile,
-23 Dec 2005.
-
-Checked this on true 64-bit Linux. The same symbols are defined in CFLAGS,
-but they do no harm; it builds without complaint and works fine. 24 Dec 2005.
-
-Built it on Red Hat Linux 6.1 from 1999. This picked up the long file
-support too. Guess 6.1 isn't old enough to not have it! Kermit seems to
-work OK on regular files but I don't have enough disk space to create a long
-file, and my bigfile.c program (which creates a long file containing only 1
-byte) doesn't work ("fseeko: invalid argument"). It looks like parts of
-this API were visible in Linux before they were actually working.
-24 Dec 2005.
-
-Converted all fseek() and ftell() to macros that expand to fseek() and ftell()
-or fseeko() and ftello() depending on whether _LARGEFILE_SOURCE is defined.
-ckufio.c, ckuus7.c, ckuusx.c, 24 Dec 2005.
-
-Made a CK_OFF_T version of cmnum(). It would be a very big deal to just
-change cmnum() to return a new type, so another idea is to rename cmnum() to
-something else, cmnumw(), change its result argument to CK_OFF_T, and then
-make a stub cmnum() to call it to get an int, then call cmnumw() explicitly
-any time we need a big number. ckucmd.c, 24 Dec 2005.
-
-Calling cmnumw() directly requires changes to each routine that uses it.
-The INCREMENT and DECREMENT commands, for example, required changes to
-doincr(), varval(), and incvar(), and all references to them. ckuusr.[ch],
-ckuus[56].c, 24 Dec 2005.
-
-Calling cmnumw() in chained FDBs required defining a new function code,
-_CMNUW, adding a new member to the OFDB struct for returning wide results,
-and adding a new case to cmfdb(). ckucmd.[ch], 24 Dec 2005.
-
-Changed FSEEK and FCOUNT to use the new chained FDB interface, now we can
-seek and look past 2GB. ckuus7.c, 24 Dec 2005.
-
-Next come switches, which store their results in a struct stringint. This
-struct was defined in each module where it was used (ckuus[r367].c, ckcftp.c).
-I moved the definition to ckuusr.h and added a wval member, which can be
-referenced by any switch-parsing code that calls cmnumw(). 24 Dec 2005.
-
-Changed SEND /CALIBRATE:n to allow big values of n. This makes it possible
-to test the protocol aspects of long-file transfer without actually having a
-long file handy. ckuusr.c, 24 Dec 2005.
-
-SEND /SMALLER-THAN:n, SEND /LARGER-THAN:n, and and SEND /START:n also now
-allow large values of n. ckuusr.c, 24 Dec 2005.
-
-Changed the algebraic expression evaluator to use wide values.
-ckuus5.c, 24 Dec 2005.
-
-Fixed ckfstoa() to handle the case when n is negative and (0 - n) is also
-negative, which happens for numbers 2^(n-1) or greater, where n is the
-number of bits in the word size we're dealing with, e.g. 64, in which case
-2^63 has its sign bit set so seems to be negative. In such cases, ckfstoa()
-returns "OVERFLOW" instead of a numeric string. We'll have to see how this
-plays out but I think it's better to cause a parse error and stop things
-dead than to return a spurious number. ckclib.c, 24 Dec 2005.
-
-Converted the S-Expression handler to use wide integers. ckuus3.c, 24 Dec 2005.
-
-Took all the LONGLONG stuff out of ckcdeb.h, we don't need it.
-
-All of these changes result in 64-bit arithmetic (more or less) on 32-bit
-Linux, as well as on true 64-bit platforms.
-
-Rebuilt today's code on Solaris 9 in the 32-bit and 64-bit worlds, on Red
-Hat 6.1, Red Hat AS4.2. I haven't bothered trying a 32/64 hybrid build for
-Solaris, since I can build a pure 64-bit version there. Quick tests show
-the large-number arithmetic works OK in all cases except, of course, on pure
-32-bit builds (unfortunately I can't find a running Linux system old enough
-to verify this for Linux, but it's true for other 32-bit platforms).
-24 Dec 2005.
-
-Tried building a hybrid version on Solaris 9 after all since the LFS API is
-ostensibly the same as for Linux:
-
- make solaris9 "KFLAGS=-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
-
-It built smoothly and the resulting binary is 2.5MB compared to 3.4MB for
-the 100% 64-bit version. Looks like a keeper. For now, added solaris9lfs
-and solaris10lfs entries to the makefile but if these work on PCs we can
-make these the regular entries for Solaris 9 and 10. 27 Dec 2005.
-
-Built on Mac OS X 10.4 with the regular target. It seems that in that case,
-off_t is 64 bits anyway. Noticed that a lot of stuff didn't work, like
-exponentiation in S-Expressions. Tried building it as above, which worked,
-and now CK_OFF_T is 64 bits instead of 32, but (^ 2 30) is still 2.0. In
-fact 2-to-the-any-power is 2.0. It seems that the Mac OS X version did not
-have FNFLOAT defined. It also seems that every test in dosexp() like:
-
- if (result != fpresult) fpflag++;
-
-should have been protected by #ifdef FNFLOAT..#endif /* FNFLOAT */ -- a
-double-ended break, as they say in the nuclear power industry. ckuus3.c,
-27 Dec 2005.
-
-Added GREP /EXCEPT:pattern. ckuus[26].c, 27 Dec 2005.
-
-Fixed a problem with uninitialized pv[].wval (switch-parsing parameter-value)
-members that showed up on certain platforms or with certain compilers. Now
-the Mac OS X 10.4 version works. ckuus[r367].c, ckcftp.c, 28 Dec 2005.
-
-Built on Unixware 7.1.1, a pure 32-bit build, seems fine. Rebuilt on Red
-Hat AS 4.2 just to make sure I didn't break anything, it's OK. No testing
-on HP-UX, etc, because HP testdrive file system is full, can't upload
-anything. 29 Dec 2005.
-
-Commented out the SHOW FEATURES section that displays constants like
-INT_MAX, CHAR_MAX, etc, because printing each value in the appropriate
-format is too tricky, and we don't need them anyway. ckuus5.c, 29 Dec 2005.
-
-Updated ckvfio.c to use CK_OFF_T for the relevant variables. Built and
-tested on VMS/Alpha 7.2: file transfer in remote mode; making a Telnet
-connection and then local-mode file transfer; S-Expressions, all OK. Also
-built a no-net version OK. 29 Dec 2005.
-
-Built and tested on Red Hat AS4 AMD X86_64, used it to upload new sources to
-FreeBSD 4.11. Built on FreeBSD 4.11/i386. Here's another one where off_t
-is 64 bits, even though long is 32 bits. But it seems to work ok, not sure
-why, when CK_OFF_T is 32 bits. There is no _LARGEFILE_SOURCE stuff in the
-header files. 29 Dec 2005.
-
-Built on Mac OS X 10.3.9 using the new macosx10.4 target to pick up LFS.
-Works fine.
-
-Built on Red Hat Linux 4WS on IA64 (64-bit). Now this one is odd, stat()
-fails on big files. It happens also if I use the "linuxnolfs" target, which
-does not define _USE_LARGEFILE or _FILE_OFFSET_BITS=64. DIRECTORY BIGFILE
-shows the size as -1, but if "log debug", it says "no files match", i.e.
-different behavior, observer effect. I hate when that happens.
-
-Let's see if that's an anomaly... Built on Tru64 Unix 4.0F (64-bit Alpha).
-It sees long files just fine. Rebuilt and checked on x86_64 again... fine.
-OK, let's not worry about IA64 yet.
-
-Another small fix to the HP-UX 9.0 target from PeterE. makefile, 29 Dec 2005.
-
----Dev.10---
-
-Code adjustments from Jeff, mainly to the SSL and TLS Raw mode code from
-several weeks ago, plus changing some data types in the security code to
-CK_OFF_T, plus a different data type for CK_OFF_T for K95 because Windows
-size_T isn't signed. This presumably will allow large-number arithmetic but
-it will not give large file access because that will require replacing all C
-library file i/o calls (esp. in ckofio.c) with native Windows APIs. Build
-on Solaris 9 with and without SSL and on Linux RH AS4.2 with and without
-SSL. ck_crp.c, ck_ssl.c, ck_ssl.h, ckcdeb.h, ckcftp.c, ckcmai.c, ckcnet.c,
-ckcnet.h, ckctel.c, ckuat2.h, ckuus4.c, ckuus7.c, ckuusr.c, 30 Dec 2005.
-
-It was reported that WRITE SESSION always returned a failure status, even
-when it succeeded. The problem was that Unix versions of zsout() and
-zsoutl(), for the session log only, were using write() and returning
-write()'s return code, which is different from what zsout() and zsoutl() are
-documented to return. Also plugged a couple potential holes in zsoutx()
-that I noticed while I was in the neighborhood. ckufio.c, 30 Dec 2005.
-
-Added FSEEK /FIND:pattern. This form of FSEEK accepts all the other
-switches and arguments and performs the desired seek. Then, if the seek was
-successful, it starts from that point and reads through the file, line by
-line, searching for the first line that contains the given string or matches
-the given (unanchored) pattern and, if found, sets the file pointer to the
-beginning of that line. Useful, e.g., for very long timestamped logs, where
-you want to start processing at a certain date or time; searching for a
-particular string is much faster than doing date comparisons on each line.
-ckuus[27].c, 30 Dec 2005.
-
-It was annoying me that FILE STATUS (FSTATUS) required a channel number to
-be given even if only one file was open, so I supplied the correct default
-in that case. ckuus7.c, 30 Dec 2005.
-
-INPUT /NOWRAP, added recently, is used for efficiently copying the INPUT
-stream intact, but it's not good for matching because if the INPUT target is
-broken between the end of the previous buffer and the beginning of the next
-one, the context is lost and the match does not occur. I thought of several
-ways around this, but they all involve saving a huge amount of context --
-old input buffers, the arrays of target strings and corresponding match
-positions, etc. The alternative is fairly simple but it's not transparent
-to the user. Here's what I did in a POP script:
-
- .eom := "\13\10.\13\10"
- set flag off # FLAG ON = success
- while ( open connection && not flag ) {
- .oldinput := \fright(\v(input),8) # Save tail of previous INPUT buffer
- input /clear /nowrap 4 \m(eom) # Get new INPUT buffer
- if success { # INPUT matched - good
- .s := {\freplace(\v(input),\m(eom),\13\10)}
- set flag on
- } else { # No match
- .s := \v(input) # Check if target crossed the border
- .oldinput := \m(oldinput)\fsubstr(\v(input),1,8)
- if \findex(\m(eom),\m(oldinput)) set flag on
- }
- ...
- }
-
-I think this will be easier to explain than any dangerous and grotesque
-magic I might put into doinput() itself. For now, added a few words about
-this to HELP INPUT. ckuus2.c, 30 Dec 2005.
-
-Back to the pattern matcher. Noticed that "IF MATCH index.html [a-hj-z]*"
-succeeded when it should have failed. In ckmatch(), the clist section
-needed one more clause: it can't float the pattern if an asterisk does not
-occur in the pattern before the clist. This change fixes the problem
-without breaking any other cases that weren't already broken, most of which
-involve slists, i.e. {string,string,string,...}. ckclib.c, 30 Dec 2005.
-
-Tried FSEEK /FIND: on a largish file (over 100,000 lines), using it to seek
-to a line near the end. It took 0.756 seconds, compared with Unix grep,
-which did the same thing in 0.151 sec. That's because C-Kermit is using
-ckmatch(). But if the search target is not a pattern, it should be a bit
-faster to use ckindex(). Yup, 0.554 sec, a 36% improvement. Can't expect
-to compete with grep, though; it's highly tuned for its single purpose.
-ckclib.[ch], ckuus7.c, 1 Jan 2006.
-
-Updated visible copyright dates to 2006: ckcmai.c, ckuus2.c, ckuus5.c,
-1 Jan 2006.
-
-Noticed that NetBSD 2.0.3 has 64-bit off_t, and that _LARGEFILE_SOURCE is
-mentioned in <stdio.h>. Tried building Kermit with _LARGEFILE_SOURCE added
-to CFLAGS, it's good. Added it to the netbsd target. makefile, 1 Jan 2006.
-
-Fixed typo, #ifdef CK_NOLONGLONG in ckuus5.c should have been #ifndef
-CK_LONGLONG (which, it turns out, we don't use anyway). 2 Jan 2005.
-
-Observed that FreeBSD 4.x has a 64-bit off_t, but does not use the
-_LARGEFILE_SOURCE convention. Reasoning that all versions of FreeBSD have
-off_t (I was able to check back to FreeBSD 3.3), I simply #define CK_OFF_T
-to be off_t in ckcdeb.h within #ifdef __FreeBSD__ .. #endif. Another one
-down. This can be done for any platform that is guaranteed to have off_t.
-Turns out FreeBSD 3.3 has 64-bit off_t too. 2 Jan 2005.
-
-OpenBSD, same as FreeBSD. Also, added OS-version-getting thing to makefile
-target for the program herald, as in the other BSDs. Built on OpenBSD 2.5
-from 1998, it has 64-bit off_t too. ckcdeb.h, makefile, 2 Jan 2005.
-
-Dumping the command stack every time there's an error is really too much.
-I added SET COMMAND ERROR-DISPLAY {0,1,2,3} to set the verbosity level of
-error messages. Only level 3 dumps the stack. ckuus[235].c, 2 Jan 2005.
-
-Built on HP-UX 11.11 with _LARGEFILE_SOURCE and _FILE_OFFSET_BITS=64. The
-result works fine as far as I can tell. It sees big files, it can open
-them, seek to positions past the 2^31 boundary. It can send large files.
-It can do large-number arithmetic (^ 2 62). The only problem is that during
-compilation, every single modules warns:
-
- cc: "/usr/include/sys/socket.h", line 504: warning 562: Redeclaration of
- "sendfile" with a different storage class specifier: "sendfile" will have
- internal linkage.
- cc: "/usr/include/sys/socket.h", line 505: warning 562: Redeclaration of
- "sendpath" with a different storage class specifier: "sendpath" will have
- internal linkage.
-
-These warnings should be perfectly harmless since they are not coming from
-C-Kermit code, nor does C-Kermit use either one of those functions. These
-warnings don't come out in HP-UX 11i v2, but on that one we get tons and tons
-of picky compiler warnings (variables set but not used, defined but not
-referenced, etc). A couple, however, turned out to be valid; one case of
-"expression has no effect", and two of "string format incompatible with
-data type" (I missed a couple file-size printfs).
-
-There were also numerous warnings about signedness mismatch or sign
-conversion of constants like IAC (0xff). Does the HP-UX Optimizing Compiler
-have a compiler flag to make all chars unsigned? Yes, +uc, but the man page
-says "Be careful when using this option. Your application may have problems
-interfacing with HP-UX system libraries and other libraries that do not use
-this option". Sigh, better not use it.
-
-After reviewing "HP-UX Large Files White Paper Version 1.4" and HP's
-"Writing Portable Code" documents, I added -D_LARGEFILE_SOURCE
--D_FILE_OFFSET_BITS=64 to the hpux1000 target, which is the basis for all
-HP-UX 10.00 and later builds. Large files are available in HP-UX 10.20 and
-later. 10.00 and 10.10 were not real releases, and anyway these flags
-should be harmless there unless the large-file implementation was only
-partly done. Built OK on both PA-RISC and IA64, optimized and plain.
-makefile, 4 Jan 2006.
-
-Built on FreeBSD 6.0 on IA64. All OK except I got a warning about the
-argument passed to time() in logwtmp() in ckufio.c. This section had
-already been partially fixed; thus I put the improved version into
-#ifdef CK_64BIT, which is our newly available symbol that should be
-automatically defined for any true 64-bit build. ckufio.c, 4 Jan 2006.
-
-Finally got around to testing Jeff's changes to SSL/TLS RAW mode from
-December 30th against our POP server. It didn't work, couldn't log in.
-Tried backing off the ckctel.c changes first; that allowed login and
-communication, but it did not suppress activation of Telnet protocol
-whenever a 0xff byte arrived. Backed off the rest of the changes and now
-all is OK again. ckctel.c, ckcnet.c, ckuus7.c, 9 Jan 2006.
-
-Built on NetBSD 1.4.1 (1999), found that it did not like the large file
-assumption -- fseeko() and ftello() do not exist; added a clause to the
-netbsd target to check for fseeko and not define _LARGEFILE_SOURCE if not
-found. Oddly enough, off_t is 64 bits anyway, but it doesn't look like the
-APIs are half-done. For example, stat() uses off_t (64 bits) for the file
-length, but fseek() uses long (32 bits) and there is no 64-bit analog.
-Anyway the new netbsd target works on both 1.4.1 and 1.5.2 (no large files)
-and on 2.0.3 (large files). makefile, 9 Jan 2006.
-
-Built on QNX-32 4.25, which has no large file support. Got a few strange
-compiler (WatCom) warnings, but it built and runs OK. Noticed that file
-transfers into QNX over a Telnet connection can't use streaming, but that's
-nothing new to this version; same thing happens with C-Kermit 7.0. 9 Jan 2006.
-
-Built on IRIX 6.5. I didn't bother with large files there because it does
-not support the _LARGEFILE_SOURCE interface; you have to change all the APIs
-at the source level from blah() to blah64(). Seems to work fine as a 32-bit
-app even though its off_t is 64 bits. Tried a pure 64-bit IRIX 6.5 build
-but it dies in ckcnet.c when it hits SOCKOPT_T and GSOCKNAME_T with "The
-identifier 'socklen_t' is undefined".
-
-Looks like I no longer have access to SCO OSR5.
-
-Made a pure 32-bit build on SCO UnixWare 7.1.4, all OK. Found that this
-version also supports LFS, added it to the uw7 target. makefile, 9 Jan 2006.
-
---- Dev.11 ---
-
-Evidently the HP-UX bundled (non-ANSI non-optimizing) compiler doesn't like
-long integers in switch expressions. Changed three examples of these in the
-S-expression code. ckuus3.c, 10 Jan 2006.
-
-A section of tstats() where GFTIMER isn't defined (e.g. on Motorola
-sv68r3v6) was garbled. Fixed in ckcfn2.c, 10 Jan 2006.
-
-A fix for setting 921600 bps on Linux from Paul Fulghum, Microgate Systems Ltd.
-ttgspd(): ckutio.c, 11 Jan 2006.
-
-Noticed that when I changed the compact substring notation code back on
-August 9th, I broke the ability to use arithmetic expressions within the
-brackets, which explains some rather odd behavior I saw with some of my
-scripts. Looking more deeply into this, I also see that all the parsers I
-have been using up to now for this, as well as for array bounds pairs, have
-been inadequate because they never allowed for nested constructions, such as
-a member of a bounds pair that itself was an array element, possibly with
-another array element as a subscript. I wrote a new routine for this,
-called boundspair(), which is like arraybounds() except it accepts an extra
-argument, an array of characters that can serve as bounds-pair delimiters,
-and it returns the pair separator that was encountered in another new
-argument. For the alternative substring notation for [startpos-endpos] I
-had to change the delimiter from '-' to '_' because '-' can be used in
-arithmetic but '_' is not a recognized operator. This is so I can parse,
-e.g. [a:b] or [a_b] in the same context, and then find out which form was
-used, e.g. \s(line[9:12]) or \s(line[9_12]); the first string is 4 bytes
-long, the second is 12. Everything seems to be OK now. \s(line[10]) gives
-everything starting at 10, but \s(line[10:0]) gives the null string. Bad
-syntax in the bounds pairs results in a null string; missing pieces of the
-bounds pair result in defaults that should be compatible with previous
-behavior. ckuus[45].c, ckuusr.h, 13 Jan 2005.
-
-Changed arraybounds() to call boundspair(). This was a rather drastic
-change, not strictly necessary, but I think I got all the kinks out.
-ckuus5.c, 13 Jan 2005.
-
-Changes from PeterE to the makefile for HP-UX 6 and 7, to accommodate bigger
-symbol tables, etc. 19 Jan 2005.
-
-Determined that SCO OSR5.0.6 (and earlier) do(es) not support large files.
-Don't know about 5.0.7. 30 Jan 2005.
-
-Created a new build target for SCO OSR6.0.0. Gets the exact 6.x.x version
-dynamically. Supports large files and big-number arithmetic via CK_OFF_T.
-The sockopt() family of functions changed the data types of some of their
-arguments since OSR5. It was already possible to define SOCKOPT_T and
-GSOCKNAME_T from the command line but I had to add code to also allow this
-for GPEERNAME_T too. ckcnet.c, makefile, 30 Jan 2005.
-
-Apparently, ever since C-Kermit 7.0 was released, it has never been possible
-to use a variable for the as-name in a RECEIVE command in Kermit 95. This
-is because evaluation of the as-name field was deferred until after we could
-check whether it might be a directory name (which, in Windows, could start
-with a backslash). This little bit of magic was not a good idea, magic
-hardly ever is. I changed the code to evaluate both as-name fields in the
-normal way. If they want to receive to a directory called "\%1", they'll
-just have to spell it differently. The workaround is to turn the whole
-command into a macro and evaluate it before executing it, e.g.:
-
- assign xx receive /as-name:\%1
- do xx
-
-ckuus6.c, 1 Feb 2006.
-
-Built OK on FreeBSD 6.1 on AMD64. Adjusted some copyrights and date stamps.
-ckcmai.c, makefile, 8 Feb 2006.
-
---- Dev.12 ---
-
-Fixed a signed/unsigned char warning in the new boundspair() calling code
-in the compact substring notation handler. ckuus4.c, 9 Feb 2006.
-
-Removed a spurious extra linux+openssl label from the makefile, added
-solaris10g_64 synonym. 9 Feb 2006.
-
-Satisfied myself that LFS is OK on Solaris 10 i386, and I'm going to assume
-it's also OK on Solaris 9. Made LFS standard for all Solaris 9 and 10
-builds (including the secure ones) except the explicitly 64-bit ones, and
-made the provisional solarisXXlfs targets into synonyms. makefile, 9 Feb 2006.
-
---- Dev.13 ---
-
-Further attempts at SSL/TLS message suppression when QUIET is ON.
-ck_ssl.c, 16 Feb 2006.
-
-From J.Scott Kasten: (quote...) I just uploaded a patch to /kermit/incoming.
-The file name is "jsk-patch-for-cku211.diff". I have also included the
-patch as ASCII text in this email below. This patch may be applied to the
-cku211.tar.gz source code via:
- cd cku211, patch -p1 <../jsk-patch-for-cku211.diff
-The patch adds 4 new build targets:
- netbsdwoc - a stripped no curses target for iksd used.
- netbsdse - security enhanced target with srp, ssl, and zlib.
- irix65gcc - build on SGI Irix 6.5 platform using gcc.
- irix65se - security enhanced target with srp, ssl, and zlib.
-The patch fixes one build target:
- irix64gcc - The "-s" option is not supported by gcc under Irix.
-I thank all of you in the Kermit Project for such a fine utility. I
-recently had to get a 16 MB file overseas across a spotty communications
-link to repair a computer remotely. Kermit was the only thing that could do
-the job, so I wanted to contribute these patches back to the mainstream to
-say thanks. This digitally signed email is a binding contract that
-officially assigns the rights to the source code patch (shown below) that I
-developed to the Kermit Project at Columbia University. (...end quote)
-ck_ssl.c, makefile, 23 Feb 2006.
-
-Changed the new NetBSD target names to be consistent with the conventions
-used in most other targets:
-
- netbsdwoc -> netbsdnc
- netbsdse -> netbsd+ssl+srp+zlib
- irix65se -> irix65+ssl+srp+zlib
-
-and removed old, now superfluous, NetBSD targets (old-netbsd, netbst15,
-netbst16), leaving synonym labels in their place. Also updated (crudely)
-the Linux target variations (curses instead of nocurses, no curses at all)
-to be (appropriately modified) copies of the current linux target. It would
-be nicer to combine them, but this gets the job done. makefile, 23 Feb 2006.
-
---- Dev.14 ---
-
-Fixed the HELP command when used with tokens like @, ^, #, and ;. The first
-two had been omitted from the table. The second two required a new path
-into the guts of the parser, since comments are normally stripped at a very
-low level. ckuus[r2].c, ckucmd.c, 24 Feb 2006.
-
-Built on AIX 5.1 ("make aix51") without incident. Then I tried:
-
- make aix51 "KFLAGS=-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
-
-This had no effect. I found the relevant document ath the IBM website. It
-says to use -D_LARGE_FILES instead. I added this to the AIX 4.2 target
-since (a) IBM says large files are supported by AIX 4.2 and later, and (b)
-all Kermit AIX targets past 4.2 use the 4.2 one. Plus a clause to make
-sure CK_OFF_T is defined appropriately. ckcdeb.h, makefile, 6 Mar 2006.
-
-Added a 32-bit aix51+openssl target. Builds OK, works fine (tested against
-our SSL POP server). Tried I tried adding -D_LARGE_FILES. It seems to work
-fine, so we'll keep it. Cleaned up the other aix5blah entries a bit also.
-makefile, 6 Mar 2006.
-
-Fixes from J. Scott Kasten to the IRIX 6.4 and 6.5 makefile targets. They
-were badly wrong. makefile, 6 Mar 2006.
-
-The reason Kermit was looping on directories in IRIX was a classic
-"double-ended break". The makefile targets failed to define DIRENT so
-Kermit was open/read on directories rather than opendir()/readdir(). But
-then it was also failing to account for the fact that read() would return -1
-on error. The makefile fix adds -DDIRENT, and the read() case in traverse()
-now properly terminates its loop on error. ckufio.c, 6 Mar 2006.
-
---- Dev.14 ---
-
-In response to a complaint that C-Kermit would not build on HP-UX 11 with
-OpenSSL, I tried it myself on both 11.11/PA-RISC and 11i v2/Itanium. It built
-OK on both but I had to add a new target (hpux1000o+openssl-nozlib) for no
-Zlib since these boxes did not have it installed. makefile, 9 Mar 2006.
-
-Added OpenSSL version number display to SHOW FEATURES. ckuus5.c, 9 Mar 2006.
-
-Gavin Graham noticed that FTP [M]GET /DELETE /MOVE-TO: was rejected with
-"?Sorry, /DELETE conflicts with /MOVE or /RENAME". This check belongs in the
-PUT code but not in the GET code. Commented it out and tested the result.
-The combination is now accepted but then Kermit refuses the incoming file as
-if it had been given a /SMALLER-THAN: or /LARGER-THAN: switch, which it didn't
-happen. Turns out there was one more place where I wasn't initializing the
-new "wide int" member of the switch-parsing pv[] struct. Once this was fixed,
-the /MOVE-TO part still didn't work. Turned out the /DELETE case was part of
-a long if-else-if-else- chain, which effectively made /DELETE and /MOVE-TO: or
-/RENAME-TO: mutually exclusive. Fixed this, now it works fine. ckcftp.c,
-13 Mar 2006.
-
-Got access to AIX 5.3, built there, all OK, including large files. 13 Mar 2006.
-
---- Dev.16 ---
-
-Patches from Mark Sapiro to suppress getsockopt() and getsockname() warnings
-in Mac OS X. ckcnet.[ch], 18 Mar 2006.
-
-In response to a complaint from Clarence Dold, tried "make redhat9" (which
-is the rather dated target that tried to include all forms of security) on
-RH Linux AS4.3, it failed miserably. I made a new makefile target, removing
-Kerberos IV and got a lot farther. But then in ckcftp.c, the following
-struct definition:
-
- struct {
- CONST gss_OID_desc * CONST * mech_type;
- char *service_name;
- } gss_trials[] = {
- { &ck_gss_mech_krb5, "ftp" },
- { &ck_gss_mech_krb5, "host" },
- };
-
-refers to a variable, ck_gss_mech_krb5, that is not defined anywhere. Up
-above, however, is a static definition for gss_mech_krb5, so I changed the
-struct definition to match. Next, in ckuath.c, the compiler could not find
-the com_err.h file. Turns out in Linux this is in a subdirectory, et, so we
-have to add a -I clause to the makefile target for this. Made a target for
-Linux+SSL only. Made a target for Linux+Krb5 only; this required moving an
-#ifdef in ckuus7.c to prevent an unguarded reference to SSLEAY_VERSION.
-New targets: linux+krb5+ssl, linux+krb5, linux+krb5. ckcftp.c, ckuus7.c,
-makefile, 27 Mar 2006.
-
-New targets of HP-UX 10/11 with OpenSSL from PeterE. makefile, 27 Mar 2006.
-
-Added large file/integer support to SHOW FEATURES. ckuus5.c, 27 Mar 2006.
-
-Built OK on Solaris 9 and 10 with gcc (someone was complaining that this
-didn't work, but that was 8.0.211).
-
-Started build on a Sun 3/80 mc68030 with NetBSD 2.0 and gcc 3.3.3. But it
-died with an assembler error in ckcfn2.c (compiler bug). 27 Mar 2006.
-
---- Dev.17 ---
-
-NebBSD 2.0 build completed by turning off optimization on ckcfn2.c
-("KFLAGS=-O0"). Result supports 64-bit ints and, presumably, large files.
-uname -p = "m68k", -m = "sun3". 29 Mar 2006.
-
-Corrected an omission in applying PeterE's updates to the HP-UX targets.
-makefile, 28 Mar 2006.
-
-solaris2xg+krb5+krb4+openssl+shadow:
-
-Tried resurrecting the solaris2xg+krb5+krb4+openssl+shadow target. It asks
-to link with libdes but there is no libdes. Removed -ldes from the target,
-now at least it builds and runs wart. The compilation blows up in ckcftp.c
-for missing header files:
-
- ckcftp.c:462: kerberosIV/krb.h: No such file or directory
- ckcftp.c:500: gssapi/gssapi_generic.h: No such file or directory
- ckcftp.c:501: gssapi/gssapi_krb5.h: No such file or directory
-
-Got a bit farther by adding appropriate -I's and -L's to KFLAGS but it still
-dies compiling (or linking?) ckcftp.c, but it doesn't say exactly why. OK,
-deferred.
-
-Added SET SEXPRESSION TRUNCATE-ALL-RESULTS { ON, OFF }. This can be used
-for force integer arithmetic in any kind of calculation that requires it,
-such as date calculations. This is a global setting, not on any kind of
-stack. Also, updated SHOW SEXP and added HELP SET SEXP which wasn't there
-before. ckuus[23].c, 30 Mar 2006.
-
-To make the RENAME command a bit more useful, need to add some switches.
-But it shares a switch table, qvswtab[], with some other commands. Broke
-this off into its own switch table. ckuus6.c, 17 Apr 2006.
-
-Added RENAME switch values that can be used in the same table with the DELETE
-switch values, which are shared by many commands. ckuusr.h, 17 Apr 2006.
-
-Discovered that the RENAME command could be entered without any arguments
-and it would still succeed. Fixed in dorenam(): ckuus6.c, 17 Apr 2006.
-
-Added parsing for RENAME /UPPER:option (to uppercase the file name(s)),
-/LOWER:option (to lowercase), and /REPLACE:{{s1}{s2}} (to do string
-replacement on the filename(s)), but not the semantics. When any of these
-switches is given, the target ("to") name is not parsed; they act on the
-source name. The /LOWER: switch takes keyword args to specify whether it
-should act only only files that have all UPPER case latters, or on ALL files
-(i.e., including files with mixed-case names); similarly for the /UPPER:
-switch. There is some creative parsing allowing these to be given with or
-without a colon and keyword argument, which works fine except if you include
-the colon but no argument, execute the command (which works fine), and then
-recall the command. I haven't yet decided about the interaction among these
-switches. Clearly if /UPPER is given after /LOWER, it overrides. But if
-/UPPER (or /LOWER) is given with /REPLACE, what should happen? ckuus6.c,
-17 Apr 2006.
-
-Filled in actions for RENAME /UPPER: and /LOWER: for the single file case,
-and tested all combinations of switch values and filename configurations.
-Once that was OK, moved the code out into a separate routine, renameone(),
-and then called it from both the single-file case and the multifile case.
-ckuus6.c, 19 Apr 2006.
-
-Added RENAME /SIMULATE. Filled in the code for string replacement, needs
-testing. ckuus6.c, 20 Apr 2006.
-
-Changed /REPLACE options to allow a negative number to specify an occurrence
-from the right, so -1 means the last occurrence, -2 means the next-to-last,
-etc. ckuus6.c, 24 Apr 2006.
-
-Added RENAME /COLLISION:{OVERWRITE,PROCEED,FAIL}. This is implemented but
-not tested. ckuus6.c, 24 Apr 2006.
-
-Worked on RENAME /COLLISION:FAIL. I decided it was less than useful to ...
-
-Added SET RENAME { COLLISION, LIST } to let user change default collision
-and listing actions. ckuusr.[ch], ckuus[36].c, 25 Apr 2006.
-
-Experimented with parsing for /CONVERT:cset1:cset2. The problem here is
-that there is no straightforward way for a switch to have multiple
-arguments. Or is there...? If I parse cset1 with cmswi() rather than
-cmkey(), it almost works; the only problem is that the character-set
-keywords don't have CM_ARG set, so they don't know to stop on, and ignore, a
-colon. If I make a copy of the table and set CM_ARG in the flags field for
-each keyword, it works fine: if I Tab in the first name, it fills itself
-out, supplies a colon, and waits for the second name. So in the code, the
-first time that RENAME /CONVERT is invoked, I put code to copy fcstab[] and
-set CM_ARG in each flags field. Works fine, and now we know how to make a
-switch that takes multiple arguments. ckuus6.c, 24 Apr 2006.
-
-I thought I had a function to convert the character set of a string but I
-don't, so actually implementing /CONVERT: will be difficult.
-
-Actually the parsing wasn't that easy either. It works OK interactively,
-but not in a TAKE file. To make a long story short, I had to change
-gtword() and cmkey2() to not require "/" at the beginning of a switch, and
-then to parse arguments-that-are-followed-by-other-arguments as if they were
-switches, so that they can end with colon rather than space. This might
-seem dangerous, but switches always have "/" at the beginning, so the check
-is superfluous. ckucmd.c, 26 Apr 2006.
-
-Back to /CONVERT... Once I was able to get the code to call cvtstring() I
-was able to debug it (at first it was skipping every second character). And
-now we have a general-purpose string-translating function we can call from
-anywhere. Requires that C-Kermit be built with Unicode support.
-ckuus6.c, 26 Apr 2006.
-
-Added SHOW RENAME. ckuusr.h, ckuus[r5].c, 26 Apr 2006.
-
-Conditionalized some Unix/Windows assumptions in renameone() so the code
-could work in VMS. ckuus6.c, 2 May 2006.
-
-Added RENAME /FIXSPACES to change all spaces in the filename(s) to
-underscore or any other character or string that is given. This is just a
-special case of RENAME /REPLACE:{{ }{x}} with easier syntax.
-ckuusr.h, ckuus6.c, 2 May 2006.
-
-Added an "all-but" control to the /REPLACE options:
-/REPLACE:{{.}{_}{~1}} means replace all but the first (this one works);
-/REPLACE:{{.}{_}{~-1}} means replace all but the last (this one not yet).
-ckuus6.c, 2 May 2006.
-
-Filled in the second one ("all but" the given occurrence). The algorithm is
-simply to reverse the three strings and then use the same code as we use in
-the left-right-case, and then unreverse the result. At first I used
-yystring() for this but yikes, what a bad design! So I made a better
-string-reversal routine, gnirts(), for this (luckily yystring() is only used
-in one place, for which its design is appropriate). ckuus6.c, 3-4 May 2006.
-
-Added code to handle the case where the file being renamed includes a path
-specification. In this case we separate the path, apply the renaming
-functions to the filename only, and then at the end rejoin the original
-filename with the path, and join the new name with same path or, if a
-destination directory was given, with that. ckuus6.c, 4 May 2006.
-
-Added HELP SET RENAME and updated HELP RENAME. ckuus2.c, 4 May 2006.
-
-"Tom Violin" (Tom Hansen) noticed that the first time you FOPEN a file,
-Kermit's memory consumption goes way up. In fact there's a warning to that
-effect in the code, where, upon first open, a potentially big array of
-potentially big structs is allocated. I rewrote the code to allocate each
-array member (struct ckz_file) as needed, i.e. when a file is opened, and to
-free it when the file is closed (or the open fails). This was actually
-quite a lot of work, which is why I didn't do it the first time around:
-every single "." had to be changed to "->". Every check for a valid
-channel first had to check if the channel's struct was allocated and every
-other reference to z_file[i]->anything had to be prechecked that z_file[i]
-was not a NULL pointer. Also I made some improvements to FILE STATUS, and I
-fixed FILE CLOSE to default the channel number if only one channel was open,
-as I did for FILE STATUS a while back. ckuus7.c, Cinco de mayo 2006.
-
-Ran my old BUILDS script that builds C-Kermit with about 100 different
-combinations of feature-selection switches. Fixed a few small glitches so
-now they all build OK (except can't do NOANSI builds any more on recent
-Linuxes because of varargs()). ckuus3.c, ckuus5.c, ckuus6.c, ckuus7.c,
-ckucmd.c, ckcfns.c, 6 May 2006.
-
-Fixed RENAME /LOWER and /UPPER, when given with no colon or argument, to
-default to ALL. ckuus6.c, 13 May 2006.
-
-Built on VMS 7.2-1, tested new RENAME command there; seems to be OK.
-13 May 2006.
-
---- Dev.18 ---
-
-I wanted to test large files against RESEND but I don't have access to any
-system that can run C-Kermit and that also has enough space for a large
-file. I created a "fake" large file on Linux (3G hole plus 1 byte), and
-sent it over a localhost connection, and interrupted it repeatedly and then
-initiated a RESEND at the sender. In each case, it picked up where it left
-off. But before the 2G boundary was crossed the disk filled up.
-Inconclusive. 14 May 2006.
-
-PeterE got a warning in the new FILE OPEN code when building in HP-UX 9.
-I added a cast, built on HP-UX 11, no more complaint. However there
-are warnings about internal vs external bindings of sendpath and sendfile
-in every module. Too bad, these are not Kermit tokens, it's a conflict in
-HP's header files. Marc Sapiro doesn't see them; probably it's something
-on the HP testdrive site. ckuus7.c, 17 May 2006.
-
-Fixed the tru64-51b+openssl target -- the terminating doublequote of KFLAGS
-was missing -- and also the osf target, which failed to import the LIBS
-definition from whatever other target invoked it. Now the SSL build goes OK
-on Tru64 5.1B. Replaced x.tar.z in the download areas without declaring a
-new Dev number. The new one has a makefile with today's date. Software
-engineering at its best! makefile, 18 May 2006.
-
-Scott Kasten noted that the estimated-time-remaining calculation would go
-bonkers on LFS systems when RESENDing a large file. It looks like the
-shocps() and shoetl() functions escaped the CK_OFF_T conversion. I made
-what seemed to be the right adjustments, and then was lucky enough to find a
-computer that had enough free disk space for me to send a large file,
-interrupt it several times, resend it, all seems to be OK. 28 May 2006.
-Later Scott verified these changes independently for Linux, but the problems
-in IRIX remain.
-
-Patches from Scott Kasten for large files on IRIX 6.5: ckcdeb.h, makefile,
-12 Jun 2006.
-
---- Dev.19 ---
-
-Added a new function for dealing with JPGs and GIFs:
-
-\fpicture(filename,&a)
- returns 0 if file not recognized or can't be opened;
- returns 1 if landscape, 2 if portrait or square.
- If array given, element 1 is width, element 2 is height.
-
-ckuusr.h, ckuus4.c, 19 Jun 2006.
-
-Scott Kasten reports that the FTP client can transfer large files OK, at
-least in Linux, but has trouble with recovery:
-
- . Kermit takes a very long time to start the transfer, sometimes over
- 30 minutes. Suspect the ftp server is counting the bytes in a long file?
- Or maybe it's a text-mode transfer and it's counting the lines? Probably
- in response to Kermit's SIZE command.
-
- . The size shown in the FT display is wrong by a random amount. And of
- course so are the progress bar, percent done, and time remaining.
-
- . The file, however, is transferred correctly. REGET works correctly too.
-
-I tried setting up a test scenario locally but our Solaris FTP server does
-not support large files:
-
- FTP SENT [SIZE BIGFILE]
- FTP RCVD [550 BIGFILE: not a plain file.]
- FTP SENT [PASV]
- FTP RCVD [227 Entering Passive Mode (128,59,48,24,246,37)]
- FTP SENT [RETR BIGFILE]
- FTP RCVD [550 BIGFILE: Value too large for defined data type.]
-
-Created the same 3GB on a Tru64 Unix system that allows FTP access. Made
-the connection from C-Kermit on Solaris (32-bit with LFS):
-
- 16:46:12.908 FTP SENT [SIZE BIGFILE]
- 16:46:12.947 FTP RCVD [213 3000000001]
-
-Note that it takes less than half a second to get the reply. Now I start
-the download and then interrupt it at about 2%:
-
- 16:46:12.979 FTP SENT [TYPE I]
- 16:46:13.174 FTP RCVD [200 Type set to I.]
- 16:46:13.226 FTP SENT [PASV]
- 16:46:13.262 FTP RCVD [227 Entering Passive Mode (15,170,178,171,11,37)]
- 16:46:13.299 FTP SENT [RETR BIGFILE]
- 16:46:13.337 FTP RCVD [150 Opening BINARY mode data connection for BIGFILE..]
- 16:47:24.895 FTP RCVD [426 Transfer aborted. Data connection closed.]
- 16:47:24.934 FTP RCVD [226 Abort successful]
- 16:47:24.991 FTP SENT [MDTM BIGFILE]
- 16:47:25.028 FTP RCVD [213 20060706204458]
-
-Now I do a REGET:
-
- 16:51:55.321 FTP SENT [PASV]
- 16:51:55.357 FTP RCVD [227 Entering Passive Mode (15,170,178,171,11,43)]
- 16:51:55.394 FTP SENT [REST 122736640]
- 16:51:55.430 FTP RCVD [350 Restarting at 122736640. Send STORE or RETRIEVE..]
- 16:51:55.431 FTP SENT [RETR BIGFILE]
- 16:51:55.469 FTP RCVD [150 Opening BINARY mode data connection for BIGFILE..]
-
-This worked perfectly, as far as I can tell; the FT display picked up in the
-right place; the thermometer, percent done, and estimated time remaining
-were the same as when we left off last time. I did the same thing several
-more times, everything was OK. It would have taken a really long time to
-let this run to completion, but I think this demonstrates that Scott's
-symptoms are server-dependent. No changes. 6 July 2006.
-
-Checked current code on VMS 8.2-1 on IA64 / UCX 5.5, builds fine.
-No changes. Updated listing at HP. 6 July 2006.
-
-Checked FTP GET of large file in ASCII mode against Tru64 FTP server. It
-was fine, and there was no delay in the server's response to our SIZE command
-(as there would be if it were scanning the entire file to count how many
-bytes would be required to send it in text mode). 7 Jul 2006.
-
-Tested FTP PUT big file against Tru64, OK. Ditto FTP RESEND big file:
-
- C-Kermit>resend BIGFILE
- PUT BIGFILE (binary) (3000000001 bytes)---> PASV
- 227 Entering Passive Mode (15,170,178,171,13,186)
- ---> SIZE BIGFILE
- 213 343211280
- ---> MDTM BIGFILE
- 213 20060707141243
- ---> APPE BIGFILE
- 150 Opening BINARY mode data connection for BIGFILE (128.59.59.56,45470).
-
-Made REPUT a synonym for RESEND. ckuusr.c, 7 Jul 2006.
-
-Added FTP REPUT and FTP RESEND since previously there was no FTP-prefixed
-command for recovering uploads, only the regular RESEND command, which might
-not have been obvious to people. ckcftp.c, 7 Jul 2006.
-
-Added help text for FTP RESEND and REPUT and amended RESEND help text.
-ckcftp.c, ckuus2.c, 7 Jul 2006.
-
-Changed name of \fpicture() to \fpictureinfo() and added help text. By the
-way, ImageMagick can do this too: identify -format "%w %h" dscf0520.jpg.
-The advantage of having it in Kermit is that not everybody has ImageMagick.
-ckuus[24].c, 7 Jul 2006.
-
-Changed the numeric comparisons = < > <= >= != to allow long integers by
-changing the data type to CK_OFF_T, etc. ckuus6.c, 7 Jul 2006.
-
-Noticed that \fkeywordvalue(foo=this is a string) only kept the first word.
-Fixed it to keep the whole definition. Also added \fkwvalue() as a briefer
-synonym. ckuus4.c, 7 Jul 2006
-
-Sometimes we want to check if a file's status before we've FOPEN'd it, in
-which case the channel variable is likely to be empty and \f_status(\%c)
-would get an error. Making the obvious change didn't fix this, however. It
-turns out that the function evaluator failed to adjust argn (argument count)
-when trailing arguments were empty, and argn was being used in this case,
-and probably others, to test whether an argument existed. I added code to
-adjust argn to reflect the number of arguments up to and including the
-rightmost non-empty one. ckuus4.c, 7 Jul 2006.
-
-Fixed \fstripb() to not dump core if second argument is missing.
-ckuus4.c, 7 Jul 2006.
-
-Discovered that it was not obvious what pattern to use to match strings
-enclosed in square brackets. "if match [abc] \[*\]" didn't work. Neither
-did various other tricks like NCRs for the brackets. However, "if match
-[abc] \\[*\\]" does work. Trying to fix this would no doubt break 100 other
-things, so let's call it a feature. 7 Jul 2006.
-
-Added \fgetpidinfo(n) to return info about a process ID; for now it simply
-returns 1 if the process is alive and 0 if not (or -1 if the argument is
-bad or missing or on any kind of error). ckuusr.h, ckuus[24].c, 7 Jul 2006.
-
-The "where-did-my-file-go" message seemed to be ending with a LF rather
-than CRLF, probably because the terminal modes had not yet been restored,
-leaving the next prompt hanging below it, rather than on the left margin,
-if C-Kermit exited immediately after the transfer. Fixed by changing
-all \n's to \r\n's in wheremsg(): ckcpro.w, 8 Jul 2006.
-
-Added \v(lastkwval) so we can retrieve programmatically the keyword most
-recently processed by \fkeywordval(). ckuusr.h, ckuus4.c, 9 Jul 2006.
-
---- Dev.20 ---
-
-Added #ifdef SV68, #include <unistd.h>, #endif because Unix System V/68 on
-Motorola choked on the SEEK_CUR reference without it. ckuus4.c, 10 Jul 2006.
-
-Make \fkeywordval(xxx) undefine xxx (i.e. when a keyword is given with no
-value). This way command-line keywords will always override preexisting
-default definitions, whether they have a value or not, which makes it easier
-to parse command lines like "foo=bar blah xx=yy". ckuus[24].c, 12 Jul 2006.
-
-On 29 Nov 2005 I changed IF KERBANG to solve a problem (see entry for that
-date), but introduced a new one; namely that you can't have (e.g.) a FATAL
-macro that uses IF KERBANG to decide whether to EXIT all the way or STOP
-back to the prompt. Changed it again, this time to require not that the
-command level be 1, but that the command *file* level be 0 (i.e. that we are
-in the top-level command file, irrespective of the command or macro level,
-but not in a subfile). ckuus6.c, 12 Jul 2006.
-
-It is unhelpful when Kermit gets a syntax error in the middle of a big
-compound statement block (e.g. FOR or WHILE loop) and dumps out the whole
-thing in an error message. I changed the two places where this can happen
-to call a new routine that, instead of dumping out the entire cmdbuf,
-checks its length first and if it's more than a line long, truncates it
-and adds an ellipsis. ckuus6.c, 12 Jul 2006.
-
-The new RENAME command didn't give very good error messages, e.g. if the
-filespec didn't match any files. Fixed in dorenam(): ckuus6.c, 12 Jul 2006.
-
-Fixed DIR /TOP to work if the /TOP:n argument was omitted, defaulting
-to 10. domydir(): ckuus6.c, 12 Jul 2006.
-
-Added DIR /COUNT:v to count the number of files that match the given
-criteria and store result in the variable v. ckuusr.h, ckuus[r26].c,
-24 Aug 2006.
-
-Added HDIRECTORY as an invisible synonym for DIR /SORT:SIZE /REVERSE.
-Can be used with other switches, of course, so (e.g.) HD /TOP shows the
-ten biggest files. ckuusr.h, ckuus[r26].c, 24 Aug 2006.
-
-DIR /FOLLOWLINKS and /NOFOLLOWLINKS always did the same thing; the switch
-was ignored, a symlink is always followed. Fixed in ckuus6.c, 24 Aug 2006.
-
-Added DIR /NOLINKS, which means don't show or count symlinks at all.
-ckuusr.h, ckuus[r26].c, 24 Aug 2006.
-
-Build on Solaris 9 and NetBSD 3.0, 24 Aug 2006.
-
-Added a missing definition for LOCK_DIR in the Linux HAVE_BAUDBOY case,
-suggested by Gerry Belanger. ckutio.c, 6 Oct 2006.
-
-Suggested by Jim Crapuchettes: \v(dialmessage) is the text string
-corresponding to \v(dialstatus). ckuusr.h, ckuus4.c, 6 Oct 2006.
-
-Soewono Effendi sent code for exit sequence to leave DTR on; this amounted
-to unsetting HPUCL in c_cflag. I did it a simpler way, hopefully portable
-to all Unixes, but who knows at this late date. The code is inside
-#ifndef CK_NOHUPCL..#endif in case it causes trouble. It is executed if
-SET EXIT HANGUP is OFF and a serial port was open at the time Kermit exits
-(or closes it explicitly). ttclos(): ckutio.c, 6 Oct 2006.
-
-Built on Solaris9/Sparc; FreeBSD 6.2/AMD64; NetBSD 3.0/i386; HP-UX 11i v2;
-SCO OSR6.00.
-
---- Dev.21 ---
-
-Added netbsd+openssl target to makefile. Built OK (NetBSD 3.0, OpenSSL
-0.9.7d) except with some warnings in ck_crp.c. Connects and logs in OK to a
-secure site. 10 Oct 2006.
-
-Added a debug statement to ftp_hookup() to record the TCP port that was used.
-ckcftp.c, 11 Oct 2006.
-
-Built with OpenSSL 0.9.7l on Solaris 9. Built with OpenSSL 0.9.8d on
-Solaris 9; connects and logs in to a secure site. 11 Oct 2006.
-
-The new RENAME command didn't work if both the source and destination names
-included directory segments, e.g. "rename /tmp/foo ~/bar" (see notes of
-4 May 2006). This was fixed in renameone() by a special case in which
-the second argument is given but it is a filename, not a directory name.
-ckuus6.c, 11 Oct 2006.
-
-Fixed unguarded reference to dialmsg[] for \fdialmessage(), noticed by
-Gerry Belanger. ckuus4.c, 12 Oct 2006.
-
-Added a TOUCH command that does what UNIX touch does: creates the file if it
-does not exist, updates the timestamp if it does. If a wildcard is given,
-it operates only on existing files. It shares the DIRECTORY command parser,
-so all the same file selection switches can be given. ckuusr.[ch],
-ckuus[26].c, 12 Oct 2006.
-
-PeterE noticed that if you FOPEN a file, do some seeks or reads, then FCLOSE
-it, then FOPEN it again (or open a different one), some of the old
-information is still there (e.g. current line number). This is an artifact
-of the changes of May 4th. Now the file closing and opening routines are a
-bit more careful about scrubbing and initializing the file info struct.
-ckuus7.c, 12 Oct 2006.
-
---- Dev.22 ---
-
-Built OK on Red Hat Linux AS4 with both "make linux" and "make linuxnc".
-15 Oct 2006.
-
-DIRECTORY /BRIEF ignored file selection switches and always listed all
-files. This was because of how I cleverly called filhelp() (the routine
-that lists matching files when ? is typed in a filename field) and, of
-course, filhelp() doesn't know anything about the DIRECTORY command's file
-selections. Changed filhelp() to accept all the args needed for passing
-along to fileselect(), renamed it to xfilhelp(), and made a filhelp() stub
-that chains to xfilhelp() with null selections. ckcker.h, ckucmd.[ch],
-ckuus6.c, 29 Nov 2006.
-
-SHOW CONNECTION for an SSH connection said the connection type was "NET"
-rather than "SSH". Fixed in dolognet(): ckuus3.c, 29 Nov 2006.
-
-SHOW CONNECTION didn't show the TCP port number. This command works by
-parsing the current connection log entry string, which doesn't have a field
-for this, but which sometimes shows the port number as part of the hostname
-(but more often not). Added code to dolognet() to log the TCP port number,
-if known. This involved adding a gettcpport() function to ckcnet.c.
-ckcnet.[ch], ckuus3.c, 29 Nov 2006.
-
-This was impossible: def \%1 upper, echo \f\%1(abc) -- i.e. to "compose" a
-function name. Fixed in zzstring(). But note that it's still not possible
-to do this: def \%1 \fupper, echo \%1(abc) -- because at the point where
-"\fupper" is encountered, which is automatically fed to fneval(), the
-argument list hasn't been read yet. ckuus4.c, 29 Nov 2006.
-
-The meaningless Lisp command (=) would cause Kermit to hang. Due to some
-idiosyncracy in the parser, it would see this as ((=) and would go into
-"wait for the closing paren" mode. There was already a hack in the code to
-compensate for this, but it didn't work. I fixed the hack but I don't
-understand the real problem. Anyway, comparing Kermit with real (Franz)
-Lisp I discovered that comparison operators do not require two arguments, as
-Kermit has been doing, although they do require at least one. I changed
-Kermit to not require two, so now all the comparison predicates behave
-exactly like Franz Lisp, including getting an error if there are no args).
-ckuus[r3].c, 29 Nov 2006.
-
-From to-do list: Make a way to inhibit pattern matching in SWITCH labels.
-It's already there; just quote the wildcard characters; the only trick is
-that for some reason (such as that SWITCH is really an internally defined
-macro), a double quote is needed:
-
- switch \%1 {
- :a\\*z, echo literally "a*z", break
- :abcxyz, echo literally "abcxyz", break
- :a*z, echo a...z, break
- :default, echo NO MATCH
- }
-
-In first case, the asterisk is taken literally; in the third it's a
-metacharacter and the label matches any string that starts with 'a' and
-ends with 'z'.
-
-Array initialization would quit early if any initializers were undefined,
-e.g. "decl \&a[] = \%a \%b \%c" would stop at the first element if \%b
-was not defined, even though \%c might be defined. Fixed in dodcl():
-ckuusr.c, 30 Nov 2006.
-
-DIR /ARRAY:a filespec, when the filespec does not match any files,
-terminates with the array undeclared. It would be better to return a
-declared but empty array (\&a[0] = 0). The code is already there to do
-that, but isn't working. And yet "declare \&a[0]" does indeed create a
-0-element array ("show array" shows a dimension of 0). Turns out there were
-two problems; one was the careless recycling of a local variable ("array"),
-resulting in failure to create \&a[] (but not any other array). Fixed in
-domydir(): ckuus6.c, 30 Nov 2006.
-
-The other problem was that dclarray(), when called with an array name and a
-dimension of zero, does two different things depending on whether the array
-already existed. There is still a fair amount of confusion about whether a
-dimension of 0 indicates an array with 1 element (as it should) or a
-nonexistent array. We call dclarray() with a size of 0 to undeclare an
-array but we also need to able able to declare an array with only element 0.
-I changed dclarray() to treat a negative dimension as a command to destroy
-the array, and 0 or positive as a command to create the array with the given
-dimension. ckuus[r56].c, 30 Nov 2006.
-
-Next problem: when chkarray() returns 0, this should not be interpreted to
-mean the array does not exist. Looks like the only place this happened was
-in \fcontents(); fixed in ckuus4.c, 30 Nov 2006.
-
-If we include file selectors with DIR /ARRAY:&a and some of the files that
-match the given filespec but don't fit the selectors, the array's dimension
-is bigger than its number of elements. Added code at the end of domydir()
-to resize the array so \fdim() returns the number of filenames in the array,
-and also made sure that element 0 contains that number too. ckuus6.c,
-30 Nov 2006.
-
-This would be a nice elegant way to loop over a bunch of files, if it worked:
-
- for \%i 1 \ffiles(*) 1 { rename \fnextfile() xxx_\flpad(\%i,3,0) }
-
-But in this loop, Kermit skips every other file (beginning with the first)
-and then runs out of files halfway through the loop. Why? Because in
-commands like RENAME and DELETE, the filename parser is in a chained FDB
-with the switch parser. First the switch parser, cmswi(), gets its hands on
-\fnextfile(), passing it through the evaluator and thus getting the first
-filename, which it then sees is not a switch, so now the field is parsed by
-the next parser in the chain, cmifi(), which causes \fnextfile() to be
-executed again. In fact, the FOR loop has nothing to do with; the same
-thing happens like this:
-
- void \ffiles(*)
- delete \fnextfile()
-
-This deletes not the first file, but the second one. Obviously users can be
-told not to refer to \fnextfile() in chained-fdb fields:
-
- for \%i 1 \ffiles(*) 1 { .f := \fnextfile(), delete \m(f) }
-
-but this is hardly intuitive. I had some clever ideas of how to make
-\fnextfile() work as expected in this context but it's way too much magic.
-Better to simply document that \fnextfile() is "deprecated" and the array
-format should be used:
-
- for \%i 1 \ffiles(*,&a) 1 { delete \&a[\%i] }
-
-The difference is, an array element doesn't change every time it's referred to!
-
-Added a /PRESERVE switch to the COPY command to preserve the timestamp and
-permissions of the file. I did this using the Kermit APIs so it should work
-for any version of C-Kermit or K95. ckuus[26].c, 30 Nov 2006.
-
-Added COPY /OVERWRITE:{ALWAYS,NEVER,OLDER,NEWER} to control name collisions
-when copying across directories. ckuus[26].c, 1 Dec 2006.
-
---- Dev.23 ---
-
-Fixed a bug in SET TELNET PROMPT-FOR-USERID, SET AUTH KERBEROS[45] PROMPT,
-and SET AUTH SRP PROMPT in which the user's string was compared with a
-literal (s == ""), reported by Pavol Rusnak. Worse, empty strings (if the
-test succeeded) were turned into null pointers, and then fed to strlen().
-Fixed in ckuus3.c, 5 Dec 2006.
-
-Added an optional 4th argument to \findex(), \frindex(), \fsearch(), and
-\frsearch(): the desired occurrence number of the searched-for string.
-\frsearch() was a bit tricky. ckuus[24].c, 7 Dec 2006.
-
-Added \fcount(s1,s2) to tell the number of occurrences of s1 in s2.
-ckuus[24].c, 8 Dec 2006.
-
-Added \ffunction(s1) to tell if a given built-in function is available.
-ckuus[24].c, 8 Dec 2006.
-
-Changed RENAME /COLLISION:PROCEED to be /COLLISION:SKIP, which is clearer.
-ckuus[26].c, 8 Dec 2006.
-
-For communication protocols: INPUT /COUNT:n to read exactly n characters
-without any matching. Can be used, for example, with CONTENT_LENGTH in CGI
-scripts; NUL characters are counted but not collected. ckuusr.[ch],
-ckuus4.c, 8 Dec 2006.
-
-There was a bad bug in the date-parsing routines; it's been there for years.
-If a date string includes a timezone, e.g. "Sat, 9 Dec 2006 19:26:23 EST",
-and converting to GMT changes the date, the variables for day, month, and
-year (which are used later) were not updated, and the final result was a day
-off. Fixed in cmcvtdate(): ckucmd.c, 10 Dec 2006.
-
-Built OK with SSL/TLS. Tested with the POP script, found that I broke INPUT
-when adding the /COUNT feature; there was a path through the code that could
-leave the "anychar" variable unset and therefore random. Fixed in
-doinput(). The POP script, which does not use /COUNT, works again and so
-does a new CGI script, which does use /COUNT. ckuus4.c, 10 Dec 2006.
-
-Supplied a missing comma in the help-text array for HELP SET TERMINAL, which
-resulted in bad formatting in K95 around SET SNI-FIRMWARE-VERSIONS.
-ckuus2.c, 10 Dec 2006.
-
-Made "help locus" a synonym for "help set locus". ckuusr.[ch], ckuus2.c,
-11 Dec 2006.
-
-This morning the Columbia FTP server was malfunctioning in a perfect way
-for me to implement and test an FTP timeout mechanism. The server would
-close the data connection after sending the file, but the client never saw
-the close and was stuck forever in a recv(). I added code to do a select()
-on the data connection prior to entering the recv(), with a timeout on the
-select() that the user can establish with SET FTP TIMEOUT. Built and tested
-on Solaris 9, clear-text FTP. Also built cleanly for FTPS and tested
-against a server that does not hang; I don't have access to an FTPS server
-that would tickle the timeout code. ckcftp.c, 11 Dec 2006.
-
---- Dev.24 ---
-
-Fixed a bug in the INPUT /COUNT: parser: the array of search strings was
-never initialized, which didn't matter before, but with /COUNT:, if the
-first element was not a NULL pointer, we'd treat it as a search string, and
-then if it happened to match something in the input stream, the operation
-would stop before the count was exhausted. Fixed by (a) initializing the
-array, and (b) ignoring any search strings if /COUNT: was given. ckuusr.c,
-13 Dec 2006.
-
-Removed a debug() statement from zsattr() that suddenly started making some
-version of gcc complain, reported by Gerry Belanger. ckufio.c, 13 Dec 2006.
-
---- Dev.25 ---
-
-Some casts for the 3 interior args of the new select() call in ckcftp.c
-for HP-UX 9. 14 Dec 2006.
-
-Changed \fkeywordvalue() to accept a string rather than a single word
-as its second argument, so that more than one separator could be specified,
-and to return -1 on error, 0 if it found nothing, 1 if given a keyword but
-no value, and 2 if there was a keyword and a value. dokwval(): ckuus[24].c,
-14 Dec 2006.
-
-Checked FTP timeout on command channel with FTP DIRECTORY of a big directory
-using a path into our ftp server that preserves the hanging behavior. The
-timeout was actually working, but the failure condition wasn't propagating
-back to the user, and there was no error message. Fixed in doftprecv2() and
-failftprecv2(): ckcftp.c, 15 Dec 2006.
-
-Added the obvious timeout checks for FTP uploads, but I have no way to test
-the code since our misbehaving FTP server does not hang when receiving
-files, only when sending them. But uploads work both with and without a
-timeout set, so at least no harm is done. ckcftp.c, 17 Dec 2006.
-
-When downloading with FILE DESTINATION NOWHERE (= /CALIBRATE), Kermit still
-checked the size of the incoming file and refused it if there wasn't enough
-free disk space, on platforms (such as VMS) where zchkspa()) actually works;
-reported by Bob Gezelter. ckcfn3.c, 18 Dec 2006.
-
-Built on Mac OS X 10.4.8 and NetBSD 3.1_RC3, all OK. 19 Dec 2006.
-
---- Dev.26 ---
-
-Built on VMS 7.3-2/Alpha. Had to squelch a couple compiler warnings by
-changing some ints in the new \fpictureinfo() code from unsigned to signed,
-and fix a typo in the prototype for the new gettcpport() function.
-ckcnet.h, ckuus4.c, 22 Dec 2006.
-
---- Dev.27 ---
-
-Parameterized pty routines and all references to them for file descriptor,
-rather than to use global ttyfd, thus allowing ptys to be created for
-different purposes. Tested on Solaris 9 and Mac OS X 10.4.8, with "set host
-/connect /pty emacs" (fine in both cases), and (more to the point) "set host
-/connect /pty kermit" -- here we make a connection from one Kermit process
-to another and transfer a file; works fine and wasn't especially slow either;
-a good sign. ckcdeb.h, ckutio.c, ckupty.c, 22 Dec 2006.
-
-Created a new version of ttruncmd() called ttyptycmd(), which works by
-calling do_pty() to get a pty to run the command on, and then in a loop,
-reads from the pty and writes to the net and reads from the net and writes
-to the pty, using select() to which of those it should do on each pass.
-First cut just uses single-byte reads and writes. Tested using Kermit
-itself as an external protocol. Works but slowly: 6000cps. Zmodem doesn't
-work at all. ckutio.c, 24 Dec 2006.
-
-Changed single-character read() and write() to buffered reads and writes,
-with ttxin() and ttol() used for network i/o. Using Kermit as the external
-protocol, this gives 450Kcps (about 1/3 normal on this connection).
-
-But now there's a problem: the loop doesn't know when to stop. How does it
-know when the process that is running on the pty has exited? With single
-character read()'s that are executed unconditionally when select() says the
-pty has data waiting, as in the first pass, I get EIO if there actually
-isn't any, and can exit the loop. But now, to avoid blocking, I call
-in_chk() to see how much data is waiting, and I don't try to read anything
-if it says nothing is waiting. If the process associated with the pty file
-descriptor has terminated, in_chk() would presumably get some kind of error,
-but it doesn't. I changed do_pty to return the pid of the fork where it
-execs its command so we can check the pid with kill(pid,0) when in_chk() of
-the pty says 0, but this doesn't help either; it seems like the process is
-not exiting, but of course it is.
-
-I could not find any legitimate way to test when the pty fork terminated.
-Select() always says the pty file descriptor was ready, no matter what.
-Select() never reports an exception on the pty file descriptor;
-in_chk(ptyfd) returns 0 and not an error. read(ptyfd,...) gets 0 but not an
-error. fcntl(ptyfd,...) doesn't get an error. Finally I tried
-write(ptyfd,c,0) and this indeed gets EIO (i/o error). With this, using
-Kermit as the external protocol works fine in Solaris but I tend to think
-this trick will not be very portable (it isn't). 24 Dec 2006.
-
-Made ttptycmd() use a more intelligent buffering scheme, fixed a few things
-about how I was setting up the select() call that should address some of
-yesterday's problems. Still doesn't work but it's progress. A: 25 Dec 2006.
-
-Debugging yesterday's code... Still, the error conditions are never set,
-we never detect when the pty closes. In Solaris, if select() says ptyfd is
-ready to read but in_chk() says there are no characters there, we can treat
-this as a loop-exit condition. But in NetBSD, in_chk() always says 0 when
-used on a pty (but works OK on a serial or net connection).
-
-Realized I could not use in_chk() on the pty because there is too much
-baggage with the communication path -- myread(), etc etc) -- so I replaced
-this with a simple ioctl(ptyfd,FIONREAD,&n). This works fine in Solaris but
-always returns 0 in NetBSD, despite what the man page says (i.e. that this
-function can be used on any file descriptor).
-
-OK, let's see.... select() does not return useful results. It says
-characters are waiting on ptyfd when they are not, and it never detects the
-closure of the pty..... Well of course not, because we are the ones who
-have to close it. Just because the process has stopped doesn't mean the pty
-is closed. So we're back to square one, how do we know when to close it?
-ckupty.c seems to keep the process ID in a global variable, pty_fork_pid
-(which is not the same as the pid now returned by do_pty(), which is
-useless, but I don't understand why). But it doesn't matter because when we
-kill(pty_fork_pid,0), we still get no error of any kind, even after we know
-the process has exited. I am completely flummoxed. select() lies, and even
-if it didn't, there is simply no completion criterion. In the loop,
-select() always says that the pty is ready to read. To be continued.
-26 Dec 2006.
-
-Back to Square One, single-byte reads and writes.
-
- . This works for both ripple and Kermit.
- . Doesn't work for Zmodem but we'll deal with that later.
- . In this case FD_ISSET(ptyfd) is still true after pty closes.
-
-But the ensuing read() gets EIO so we know the pty is gone. That means the
-same thing should happen in the buffered version, no? Yes; I went back to
-the buffered version and replaced all the other nonworking tests by a
-blocking read of 1 byte on the pty and this detects the termination. Now:
-
- . ripple works perfectly (of course it's only one-way).
- . Kermit fails
-
-Let's call the remote, forked, redirected, external Kermit A and its
-local partner B. A sends its S-packet, B receives it OK and Acks.
-A apparently does not receive the ACK in time, so sends the S again, but OK.
-followed immediately by the F. B Acks the F. A sends the A, B Acks it.
-But now A sends a piece of the previous F packet and the the first piece
-of a D packet.
-
-Clearly the buffering is messed up. Sure enough, there was an extraneous
-statement incrementing a read pointer in a write section. Removing that
-cleared up the problems with Kermit, now we can send and receive substantial
-files efficiently in remote mode. Zmodem seems to work too, except that at
-the beginning a bunch of "**B0800000000022d"'s are stuffed into Kermit's
-command buffer, so after the transfer we get some error messages.
-
-In local mode, over a Telnet connection, Kermit works fine. Zmodem works
-OK too except it doesn't finish right, so at the very end rz on the far end
-is still waiting for something; if I cancel out of it with ^X^X^X^X^X, it
-deletes the file. So there still is something wrong with the termination
-test.
-
-Also you don't see anything on your screen when running Kermit or Zmodem
-this way. That's to be expected, since they are using stdio for the
-transfer, so they can't also be displaying progress or other messages.
-
-Built this on NetBSD again... Seems to work this time, but has trouble
-finishing, like Zmodem. Hmmm, on closer examination, it turns out that
-since in_chk() always returns 0 on the ptyfd, we fall into our new
-single-byte read code, so it's really slow, like 10K cps on a connection
-where 1M is the norm. 27 Dec 2006.
-
-Switched the pty from buffer peeking (FIONREAD) and blocking reads to to
-nonblocking reads (O_NONBLOCK / O_NDELAY). Works just fine on NetBSD except
-now we no longer get EIO at the end when trying to read from the pty process
-that has exited. In fact, we're back to square one again. not ioctl(), not
-fcntl(), not select(), not even read() gets an i/o error after the pty
-process exits. But in NetBSD, we have to use nonblocking reads because ...
-Hmmmm, maybe switch the fd between blocking and nonblocking for the test...
-Nope, NetBSD seems to be hopeless (later, Ed Ravin confirmed that similar
-problems have been observed with other applications that try to do this).
-
-Switching to Linux, I see that yesterday's Solaris code (blocking reads)
-works exactly the same way on Linux.
-
-Tried today's O_NDELAY method on Solaris. It works perfectly. And then I
-moved this one to Linux and it works perfectly there too. Except in both
-cases we have the weird thing with Zmodem at the end, but I think that's
-because rz/sz don't use standard i/o. On NetBSD, it still hangs at the end.
-
-Turns out that testing the pid works in NetBSD, even though it didn't in
-Solaris. Turns out read() gets an i/o error in Solaris and Linux but not
-in NetBSD. So checking the read result first, and then checking the pid
-if read() got zero bytes catches all three. 28 Dec 2006.
-
-Now the question of return code. In the original ttruncmd() function, we do
-a fork() and a wait(). When the external protocol program finishes, wait()
-gives us its return code and we can pass it on through \v(pexitstat) as well
-ttruncmd's own return code. But ttptycmd() has to interact with the pty
-continuously, so it can't just sit back and wait() for it. Instead we have
-to detect when the process has exited and then call waitpid() on the fork
-pid, before shutting down the pty. Tested on Solaris using Kermit as the
-external protocol and then inducing failure, or letting it run to
-completion. FAILURE and SUCCESS set appropriately in each case. Tested
-with Zmodem too, works OK except for the aforementioned cosmetic glitch at
-the end. Tested on NetBSD, all OK.
-
-To make K5 connection to Panix from Spam:
-
- set telnet debug on
- authenticate K5 init /realm:PANIX.COM /password:xxxxx
- set host shell.panix.com 23 /k5login
-
-Good... Now I try to send a file from Spam to Panix over the K5 connection
-using Kermit itself as the external protocol. It fails. Inspection of the
-debug log on the far side shows that the S-Packet was received correctly,
-good! This means we are reading the clear-text S-Packet from the external
-Kermit program, and that ttol() is encrypting appropriately.
-
-The remote Kermit sends the Ack and goes to read the next packet: ttinl()
-calls myfillbuf() and:
-
- SVORPOSIX myfillbuf calling read()
- SVORPOSIX myfillbuf=0 <-- read returns 0
- SVORPOSIX myfillbuf ttcarr=2
- SVORPOSIX myfillbuf errno=0 <-- and reports no error
- HEXDUMP: mygetbuf read (-3 bytes)
- mygetbuf errno=0
- ttinl myread failure, n=-3
- ttinl myread errno=0
- ttinl non-EINTR -3[closing]
-
-This happens because myfillbuf() deliberately returns -3 when read() gets 0
-bytes. I don't understand why this happens but the real problem is yet to
-come. The local Kermit (the one that has made the secure connection and is
-running the external protocol through ttptycmd()) eventually figures out
-that the transfer failed and when we reconnect, we get total garbage -- the
-encryption either stopped happening, or got out of sync.
-
-Looking at the local debug log, ttol() is doing its job, converting the
-initial "kermit -r\13" from plaintext to cyphertext, as shown by the
-hexdumps. Then it enters ttptycmd()... Hmmmm, wait, how can it send the
-"kermit -r" before it starts the external protocol? Never mind, worry about
-that later... Anyway, ttptycmd() says:
-
- ttptycmd loop top have_pty=1
- ttptycmd loop top have_net=1
- ttptycmd FD_SET ptyfd in
- ttptycmd FD_SET ttyfd in
- ttptycmd nfds=5
- ttptycmd select=1
- ttptycmd FD_ISSET ttyfd in
- ...
- ttptycmd in_chk(ttyfd) n=11
- ttptycmd ttxin n=11
-
-ttxin() asks for 11 bytes, myfillbuf() gets 11 bytes, and hexdump() shows
-the cyphertext, there doesn't seem to be any decrypting going on. Hmmm, it
-looks like the regular code calls ttinc() in a loop, rather than ttxin().
-Maybe ttxin() doesn't have decryption hooks. No, that's not it, the code is
-there, but the Kermit packet reader does not use ttxin(), it uses ttinl().
-But of course we can't use that for external protocols because it's designed
-only to read Kermit packets. Substituting a loop of ttinc()s for the ttxin()
-call fixes things (and strangely enough, it seems to be faster). And now we
-have our first external protocol transfer over a secure connection (external
-Kermit program, Linux over Kerberos 5 to NetBSD). Zmodem worked too for a
-short file but "something happens" with longer ones. 29 Dec 2006.
-
-New makefile target for Linux with Kerberos 5, linux+krb5, that doesn't
-include anything extra from SSL or other security methods (but apparently it
-is still necessary to include -DOPENSSL_097 in order to get the right names
-for the DES routines?). Ditto netbsd+krb5 for NetBSD, except in this case
--DOPENSSL_097 is not necessary. makefile, 30 Dec 2006.
-
-Note to myself: On Panix:
-
- export LD_LIBRARY_PATH=/usr/local/kerblib
- make netbsd+krb5 "K5LIB=-L/usr/local/kerblib" "K5INC=-I/usr/local/include"
-
-Can't telnet-k5 from newly built Kermit on NetBSD; partway through the
-negotiations, just after "TELNET RCVD SB ENCRYPTION SUPPORT DES_CFB64
-DES_OFB64 IAC SE" it dumps core. The last two lines in debug.log after
-this are:
-
- tn_sb[len]=5
- encrypt_support[cnt]=2
-
-Rebuilding with -DOPENSSL_097 doesn't change anything. Ed Ravin said they
-have two different Kerberos installations, Heimdal and MIT; maybe some
-mixup between the two explains the problem (Jeff concurs). The core dump
-occurs in ck_crp: encrypt_support():
-
- debug(F100,"XXX ep not NULL","",0);
- type = ep->start ? (*ep->start)(DIR_ENCRYPT, 0) : 0; <-- Here
- debug(F101,"XXX new type","",type);
-
-Anyway, I can log in with Kerberos 5 to Panix OK from Columbia (sesame)
-using 8.0.201. So let's try to resurrect the Solaris version with everything:
-
- solaris9g+krb5+krb4+openssl+shadow+pam+zlib
-
-I hunted around to find where the current library and header file
-directories were... Last time I tried this (March 2006) it bombed, not
-finding libdes. Instead we have /opt/kerberos5125/lib/libdes425.a. Made a
-new cu-specific target that includes this; now we get farther; it blows up
-in ckcftp.c with tons of errors and warnings, which we can worry about
-later. Building again with -DNOFTP, it gets to ckuath.c (the first security
-module) and:
-
- ckuath.c:151:18: error: krb5.h: No such file or directory
- ckuath.c:152:21: error: profile.h: No such file or directory
- ckuath.c:153:21: error: com_err.h: No such file or directory
- ckuath.c:176:28: error: kerberosIV/krb.h: No such file or directory
- In file included from /opt/openssl-0.9.8d/include/openssl/des.h:101,
- from ckuath.c:219:
-
-Found krb5.h in /opt/kerberos5125/include/krb5.h, added a -I for this
-directory ... Now we get lots of warnings in ckuath.c, but it completes OK,
-then we wind up bombing out in ck_crp.c; I don't know why -- there are all
-the same warnings (related to argument passing to DES functions), but no
-errors. I have no clue.
-
-Tried to resurrect the solaris2x+krb4 target; this required changing -lkrb
-to -lkrb4 and -ldes to -ldes425. Lots of warnings in ckutio.c, ckcnet.c,
-ckctel.c, then it bombs out in ckcftp.c because it can't find krb.h. I
-found it, adjusted the -I flags, but now it bombs because krb.h itself
-#includes <kerberosIV/des.h>, which of course it can't find because the
-brackets mean it's looking in /usr/include/kerberosIV/, which, of course,
-the sys folks have removed. Giving up on Solaris again. Later, Jeff said
-"Solaris does not publicly export the krb5 libraries. You need to build
-the MIT Kerberos libraries separately and link to them." 30 December 2006.
-
-Changed copyright date to 2007. ckcmai.c, 1 Jan 2007.
-
-With Ed Ravin's help, successfully built C-Kermit with Kerberos 5 and
-OpenSSL (netbsd+krb5+openssl+zlib), but it does not make K5 connections; it
-gets hung up in the Telnet negotiations. 3 Jan 2007.
-
-Downloaded MIT Kerberos 5 v1.4.4 to Solaris 9, 54MB worth. This is just so
-I can build a Kerberized C-Kermit for testing ttyptycmd(). Ran the
-configure program, got a few warnings but it didn't fail (should it?) Did
-"make install", specifying a private directory but it failed immediately
-with "cannot stat libkrb5support.so.0.0: No such file or directory".
-OK, I tried. 3 Jan 2007.
-
-Made a new makefile target for Mac OS X, macosx10.4+krb5+ssl, ran it on Mac
-OS X 10.4.8. It bombs out in ckcftp.c with: ckcftp.c:551: error: static
-declaration of 'gss_mech_krb5' follows non-static declaration
-/usr/include/gssapi/gssapi_krb5.h:76: error: previous declaration of
-'gss_mech_krb5' was here". Ditto for gss_mech_krb5_old, gss_nt_krb5_name,
-and gss_nt_krb5_principal. Tried again with -DNOFTP. We get lots of
-warnings in the network modules, but they complete. But ck_ssl.c bombed
-with a conflict between its own declarations of encrypt_output and
-decrypt_input and the ones in ckuat2.h; removed the prototypes from the
-latter (as Jeff advised) it built OK and it works OK too. Built with FTP
-too, but with link-time warnings about the aforementioned gss_* symbols.
-#ifdef'd them out (gss_mech_krb5, gss_mech_krb5_old, gss_mech_name, and
-gss_mech_principal) for MACOSX, where these symbols are exported by the
-library. Now it all compiles and links OK, and runs OK too. 3 Jan 2007.
-
-Spent a day hunting around for a version of Zmodem that would build and
-execute on Mac OS X, finally found one. Now at last I could try a Zmodem
-external-protocol transfer over a secure connection. But phooey, C-Kermit's
-pty support didn't work on this box. Kermit finds master /dev/ptypa OK,
-then in ptyint_void_association() tries to open /dev/tty but gets ERRNO=6
-"device not configured" (which is apparently OK, because the same thing
-happens on other platforms where this works), then tries to open slave
-/dev/ttypa and gets ERRNO=13 "permission denied" because, indeed, I don't
-have r/w permission on the device. Left a message. 4 Jan 2007.
-
-Changed TRANSMIT /BINARY output buffer size from 252 to 508 to avoid
-TCP fragmentation. Need to add a SET command for this later.
-ckuus4.c, 5 Jan 2007.
-
-Found another Mac where the ptys weren't protected against me, make a K5
-connection and transferred a largish file with Zmodem with zero glitches,
-except it was kind of slow, 84K cps. Well, we're doing single-character
-reads on the net (ttinc()'s instead of ttxin()). Hmmm, but then I did it
-again and got 2.2Mcps. Success was reported, but it actually didn't work;
-it only sent the first quarter of the file.... Oh well, at least now we
-have a testbed. 5 Jan 2007.
-
-Tried again, saw that the file is actually transferred instantly but then
-we're not picking up the protocol at the end. Theory: after the transfer
-finishes, we come back to the prompt on the remote host, which means we have
-something to read from the net and write to the pty, but the pty has already
-exited. AFTER THE PTY IS GONE, WE DO NOT WANT TO READ FROM THE NET ANY
-MORE. Adding this test makes Kermit succeed right away when sending the
-same largish file, with a transfer rate of 4M cps, that's better. But the
-rz program on the far end is evidently not receiving the goodbye handshake
-from the receiver, because it sits there foreever in its *B09002402009418
-mode until I ^X^X^X^X^X out of it, at which point it deletes the file it
-already received, not very helpful. In the code, I read from the pty if the
-pty is open and there is room in the buffer. This means that when we get to
-the end, either there is no room in the buffer (unlikely) or the last bit
-sent by sz before exiting was cut off when the fork closed. Why do we get
-in this fix only with Zmodem and not with Kermit?
-
-In Mac OS X, after sz exits, we get ERRNO=5 if we try to write to the pty,
-but we still get no errors after that if we try to read from it. Still,
-prior to this we did more than 20 unproductive nonblocking reads from the
-pty (no error, no bytes) without incident; there did not seem to be anything
-waiting. In fact, the last thing we read from the pty were the text
-messages that are issued at the end of the transfer: "rz 3.73 1-30-03
-finished." After which it pauses a second and spits out a message about
-UNREGISTERED COPY.
-
-Figured out how to build lrzsz, in hopes that the previous problems were
-with rzsz and crzsz's fiddling with file descriptors, but I get the same
-behavior. Which is good, I guess, because if I can fix one, I fix them all.
-Or not... Testing lrz by itself (not under C-Kermit), I see that it doesn't
-work at all with Kermit's own Zmodem implementation.
-
-OK, here's one problem: at the end of the transfer, the Omen Zmodems print
-stuff like "Please read the license agreement", Kermit dutifully reads this
-from the pty and sends it to the host, the host shell says "Please: command
-not found", issues its prompt again, which Kermit reads, feeds to the pty,
-and apparently the pty echoes it, so we send it back to the host, and there
-ensues an infinite loop of getty babble until the pty closes. Now, there
-ought to be a way to make the external protocol shut up, like Kermit's
--q(uiet) flag, but these are unregistered versions so you can't shut up the
-messages. In fact, the transfer works, but the getty babble at the end
-ruins the experience. Now I'm beginning to wonder how any of these programs
-ever worked as external protocols. Hmmm, now that I try it, I see the
-same thing happens the old way, when using ttruncmd() rather than ttptycmd().
-
-Reading the crzsz documentation I see it says that messages come out on
-stderr. OK, that's progress. In ckupty.c I try redirecting 2 to /dev/null.
-Well good, this filters out the messages from csz, but we still get getty
-babble on the prompt. In the debug log, we read the last bunch of stuff
-from net, 618 bytes of Zmodem stuff... Now what happens?
-
-Zmodem on the remote exits, the host prints its prompt. Kermit, of course,
-reads the prompt from the net, now come to the bottom of the loop and we
-have 7 bytes to write to the pty, and no error condition, so we continue the
-loop. select() says that the pty is ready for writing. We write the 7
-bytes and and get no error. Loop again, this time select() says the pty has
-data waiting. Sure enough we get the prompt back, and send it to the net,
-and thus begins the getty babble. There are two causes for this:
-
- 1. crzsz does not exit immediately; it sleeps for 10 seconds after
- printing its nag message.
-
- 2. During this interval the pty seems to be echoing what is sent to it.
- csz is not echoing; I checked. Anyway, removing the pause doesn't
- seem to make a difference.
-
-ttptycmd() needs to:
-
- . TELL the pty module to redirect stderr to /dev/null
- . SET PTY TO NOECHO (master or slave?)
-
-Tried setting the pty to noecho:
-
- termbuf.c_lflag &= ~(ECHO|ECHOE|ECHOK);
-
-and this seemed to stop the getty babble. After the file transfer, I read
-back the prompt from the host shell, I write the prompt bytes to the pty;
-there is no error. And now select() simply hangs forever (or times out if
-a timeout is set). The question here is: why didn't writing to the pty
-produce an error? And, because we never detect the pty has exited, we can't
-set a good return code. 5 Jan 2007.
-
-Moved pty fork testing to a separate routine, pty_get_status(), and
-added a call to it from the place where we time out, in case the fork
-terminated; then we can get and return its status. 6 Jan 2007.
-
-Added calls to pty_get_status() to every place where we suspect a pty error,
-tried again with lrzsz, crzsz, and regular rzsz. All three work, but in
-each case waitpid() indicates that the sz program gave exit code 1 (failure).
-ckutio.c, 7 Jan 2007.
-
-Changing the subject... On my test system, every time I execute ttptycmd(),
-I get "permission denied" on /dev/ttyp3. Then I run it again and get to
-ttyp4 which is OK. I wanted to skip past any pty for which I lack
-permission and try the next without raising an error. Added debugging code:
-
- 16:25:23.524 pty_getpty() pty master open error[/dev/ptyp0]=5
- 16:25:23.524 pty_getpty() pty master open error[/dev/ptyp1]=5
- 16:25:23.524 pty_getpty() pty master open error[/dev/ptyp2]=5
- 16:25:23.524 pty_getpty() found pty master[/dev/ptyp3]
- 16:25:23.524 pty_getpty() slavebuf [2][/dev/ttyp3]
-
-So it already was skipping past open errors; ttyp3 was opened successfully.
-The problem is that ptyp3 is rw-rw-rw-, but the corresponding master,
-ttyp3, is rw--r----. It seems the code assumes that if the master can be
-opened, then so can the corresponding slave. Unfortunately, the code is
-not structured to allow us to skip ahead to the next master if the slave
-can't be opened. 7 Jan 2007.
-
-Spent a couple hours trying to rearrange the code in the pty module to skip
-past inaccessible slaves but it was a rabbit hole, not worth it, backed off.
-8 Jan 2008.
-
-Tried an upload over a secure connection using lsz. Unexpectedly, this time
-it worked; not only was the file (about 0.5MB) transferred correctly, but
-Kermit detected the fork's termination and got the pid's exit status, and,
-for the first time, correctly reported a successful transfer. I have no
-idea why this works today and not yesterday. More tests; it works most of
-the time. It works with csz and with regular sz too.
-
-(days later...)
-
-ckucns.c seems to do the right thing; it recognize the ZSTART string,
-activates the Zmodem-Receive APC, and returns. doconect() sees the APC and
-begins to execute it. The RECEIVE command results in a call to the GET
-command parser, doxget() (IS THAT RIGHT?), then comes a ttflui(), which
-throws away a bunch of stuff. Finally we get to ttptycmd(), we get a pty
-and run lrz in it, select() says stuff is waiting from the pty, but read
-returns 0, errno 0. Skipping the ttflui() in doxget() if the protocol was
-not Kermit didn't seem to make difference. ckuus6.c, 8 Jan 2007.
-
-The problem is that in this case, reads from the pty never get anything (no
-data, no error), write always gets an error. It's as if the pty was not
-being set up right, or we're using the wrong file descriptor. And if we
-skip the autodownload? Same thing.
-
-OK, putting downloads aside for a moment, let's get uploads working as well
-as possible. At this point we have the odd situation (at least in this
-configuration) that the upload succeeds, but now for some reason we are
-unable to read the exit status from the process, even though this was
-working before, so ttptycmd() returns 0 (failure), yet Kermit reports
-success.
-
-Well, it turns out that kill(pty_fork_pid,0) was gumming up the works.
-If we use only waitpid() all is well, I think. waitpid() with WNOHANG
-returns -1 with status -1 errno 0 if the pid has not exited, and it returns
-the pid and status > -1 if the process has exited. Fixed pty_get_status()
-to do it this way. ckutio.c, 7 Jan 2007.
-
-Let's move this from Mac OS to NetBSD and see how it works. Well, the file
-transfer was just fine, but then I used some sexps to calculate the elapsed
-time and transfer rate, and Kermit hung in dosexp(). Fine, ignoring that...
-The debug log shows that ttptycmd() gets the pty OK, master and slave, the
-i/o goes smoothly, and waitpid() does its job perfectly. Solaris, same
-deal; ttruncmd() goes smoothly, but then the sexps afterward get "Arithmetic
-exception". Turns out there was a BAD bug in dosexp() that allowed an
-integer division by 0 to occur under certain circumstances; it's always been
-there. Fixed in dosexp(): ckuus3.c, 8 Jan 2007.
-
-After noticing a few problems running the pop.ksc script in production over
-the past year, rewrote \femailaddress() to be more reliable and a lot
-simpler. ckuus4.c, 9 Jan 2007.
-
-Back to ttptycmd()... When we left off, we could send but not receive. Set
-up a test case using Kermit as the external protocol for receiving a short
-file. If I SET STREAMING OFF and use short packets, it actually does work,
-so it's not a complete failure to function, but apparently a lack of flow
-control for the pty. Began by completing the parameterization of the pty
-module, so it can be called for interactive use (fc 0) or for running
-protocols (1). Confirmed that everything works at least as well as before
-(e.g. "set host /pty emacs" vs external protocols). ckcdeb.h, ckutio.c,
-ckupty.c, 9 Jan 2007.
-
-Found in HP-UX "man 7 pty" a description of ioctl(fd,TIOCTTY,fc) which is
-exactly what we want: fc 0 turns off all termio processing and guarantees an
-uninterrupted, unmolested, flow-controlled stream of bytes in both
-directions. This function also exists in Linux, but not in Solaris, NetBSD,
-or Mac OS X (TIOCNOTTY is not what we want, it does something else entirely).
-
-Another possibility is TIOCREMOTE, which "causes input to the pseudoterminal
-to be flow controlled and not input edited, regardless of the terminal
-mode". This one exists in at least HPUX, NetBSD, Solaris, and Mac OS X.
-
-Solaris: builds OK, but at runtime we get ENOTTY ("Inappropriate ioctl for
-device"). By the time this happens, it's hard to tell from the code whether
-the fd we're using is for the master or the slave; TIOCREMOTE can be used
-only on the master. Close inspection shows that I am indeed doing that;
-ptyfd as seen by ttptycmd() is truly the master, i.e. the /dev/ptyXX device,
-not the /dev/ttyXX device (the slave fd can't be seen at all, as it exists
-only in a separate fork). OK, so now we know that TIOCREMOTE can't be used
-on Solaris.
-
-NetBSD: Somehow, whether as a result of today's fiddling or the phase of the
-moon, the code in pty_open_slave() that tries to open /dev/tty started
-failing on NetBSD ("Device not configured"). Changing it to be run only if
-fc == 0 (which doesn't seem to hurt anything), once again I get ENOTTY on
-the TIOCREMOTE ioctl. Zmodem works but Kermit totally fails (the fork exits
-immediately with an exit code of 0, even though it didn't do anything).
-
-Mac OS X: Exactly the same sequence and results as NetBSD.
-
-Linux: It did not execute the new ioctl at all; apparently the TIOC symbols
-are hidden or not exported or something.
-
-Where we stand:
- . Downloads don't work
- . Uploads got slow again
- . Kermit doesn't work at all as an external protocol
-
-Actually if I take the debugging out it goes fast, but it doesn't finish.
-
-All today's work on ttptycmd() looks like a dead end. To roll back to
-yesterday:
-
- cp ckutio.c-20070108 ckutio.c
- cp ckupty.c-20070108 ckupty.c
- cp ckupty.h-20070108 ckupty.h
-
-or to continue with today's:
-
- cp ckutio.c-20070109 ckutio.c
- cp ckupty.c-20070109 ckupty.c
- cp ckupty.h-20070109 ckupty.h
-
-Comparing Monday's and Tuesday's pty-related code, the differences are:
- 1. Passing of function code to and among pty modules.
- 2. Skipping the TIOCSCTTY ioctl and the open("/dev/tty") test.
- 3. Attempting to put pty in TIOCTTY or TIOCREMOTE mode.
-
-Commenting out 2 and 3 should put us back where we were on Monday if the
-parameterization was done right. And with this, on Solaris, downloading
-with Kermit external protocol works but slowly, 8K cps, with or without
-debugging. Debug log does not show any obvious bottlenecks; select() takes
-anywhere between no time at all and 0.1 seconds to return. If I increase
-the pty-net buffer size from 1K to 4K, the rate goes up to 55K cps. If I
-make it 8K I get 136K cps. With 16K I get 346K cps. 32K: 395K cps -- this
-last one isn't worth the doubling. But at 24K I get 490K cps, sometimes
-twice that. Let's stick with 24K for now. Downloading with Zmodem (rzsz)
-works at the same rate, but now we're back to seeing the getty babble
-(Several "**B0800000000022d") at the end. 10 Jan 2007.
-
-Moving to Mac OS X, everything works the same as on Solaris, except I don't
-get the Zmodem getty babble there, not even with Omen rzsz. Tested sends
-in both remote and local mode, the latter over a secure Kerberos 5 Telnet
-connection, using C-Kermit, rzsz, lrzsz, and crzsz, all good. 10 Jan 2007.
-
-Now we're back where we were yesterday morning, but with better throughput.
-The big issue then was receiving files. But yikes, now it works! Not only
-that, I got a transfer rate of 2.1M cps. That's using Kermit protocol,
-streaming, and big (4K) packets. Which didn't work before. Not a fluke
-either, I uploaded bigger and bigger files up to 6MB, they all went
-smoothly, at rates between 1 and 2 MBps. 10 Jan 2007.
-
-Not so great in Zmodem land, however. If I start the external-protocol
-receiver on the far end, escape back and start a Zmodem send... nothing.
-If I leave the remote C-Kermit at its prompt (where it supposed to recognize
-the Zmodem start string), still nothing. On the other hand, if I do it
-with a script instead of by hand:
-
- def xx output take blah\13, send /proto:zmodem \%1
-
-it works, at least intermittently. But that's in remote mode. We won't be
-using this in remote mode. In local mode, where we have a secure connection
-to another computer, it seems we can read from the pty and write to the net,
-but we time out waiting to read from the net; nothing arrives. Well, we
-know that i/o works both ways, so there is some kind of screwup with the
-Zmodem protocol start itself. Increasing the (still hardwired timeout) from
-5 to 22sec and driving the whole process with a script so as to avoid
-autodownload as well as manual dexterity effects... It just sits there
-forever, way longer than 22 sec. ^C'ing out, I see that sz was indeed
-started on the far end and the protocol was executing. But it looks like
-the receiver (the one running under ttptycmd()) is getting trashed packets,
-because (a) it seems to be sending the same thing over and over again, and
-(b) sometimes it waits as long as 10 seconds before anything arrives from
-the remote. Maybe I was too impatient; I interrupted it after 4 minutes but
-it seems to have been making some progress. Whenever there was data
-available to read from the net, it was always 65 bytes, and it was not
-actually the same data over and over. This is using lrz as the external
-protocol. crz gets a bit farther. In this case we read up to 24K at a
-gulp, but the amount varies a lot. It looks like we took in about 1.2MB of
-Zmodem protocol data, but were only able to output the first 20K of the
-file. Clearly there were lots of errors. In the end, the crz exits with
-status 1 (failure).
-
-Anyway it looks like we're back at needing to find a way to accomplish
-something like TIOCREMOTE on the pty, which is where we came in. 10 Jan 2007.
-
-Without any way to make the pty transparent and flow controlled, it would
-seem to make sense to write to the pty in smaller chunks than we do to the
-net. I left the read-from-pty-write-to-net buffer at 24K and changed the
-read-from-net-write-to-pty buffer to 48 bytes.
-
-Upload using lsz worked but took about 3 minutes. Actually it didn't work.
-On the local end it seemed to work, but the file did not appear on the
-remote end. Tried this several times, each time with different results,
-adding more debugging each time. The problem this time was that the pty
-read could get EWOULDBLOCK. Changed the code to not treat this as an error,
-now Zmodem uploads are solid again except I never got EWOULDBLOCK again
-either, even though I repeated the same upload about 1000 times (with
-throughput of over 2MBps even with debugging on), so the test for it has
-not been exercised.
-
-OK, uploads still work. Back to downloading... The very first pty read
-gets 0 bytes, followed by the fork test that shows that it exited with
-exit status 2.
-
-Next we try starting sz with some different options on the far end:
-
- -q: quiet (no messages):
- for some reason this gets totally stuck.
- it looks as if this option is misdocumented;
- sz seems to be sending the letter C (as in Xmodem 1K or whatever)
-
- -e: escape (all control chars):
- first attempt to read pty finds the process gone with exit status 2.
-
- -k: send 1k blocks:
- this one didn't stop immediately. It reads 48 bytes from net, writes
- 48 to the pty with no error. Then reads 21 bytes from the pty, writes
- them to the net OK. Then reads 48 bytes from net, writes them to pty OK,
- reads 21 from pty, writes to net OK, etc etc... It appears to have
- worked but (final read from pty returned 0, fork test showed lrz exited
- with status 0), but only 754 bytes were received from the net when the
- file is 420K...
-
-Well this only goes to show that the faster we shove stuff into the pty, the
-worse it gets. Zmodem downloads won't work unless we can make the pty
-transparent and flow-controlled. So to summarize today's developments:
-
- . separated in/out buffer sizes
- . handled EWOULDBLOCK
- . found out that sz options don't help much
-
-11 Jan 2007.
-
-Next day. This has got to be the most delicate code ever, it's like
-Whack-A-Mole, fix A and B pops up. Even without touching it, something that
-worked perfectly a 2:00 doesn't work at all an hour later. Maybe I could
-have used pipes instead of ptys, but pipes have problems of their own.
-There has to be a way to do this. The telnet server, the SSH server, etc --
-they all run on ptys, and we can upload files to them with Kermit. Why?
-Because Kermit puts its terminal into all the right modes using the
-time-honored methods of ttpkt() and ttvt(). Perhaps all we need is a copy
-of ttpkt() that operates on the pty.
-
-On that theory, let's go back to Kermit as the external protocol.
-It's important to suppress all messages and displays. With that,
-uploads work fine, no hitches.
-
-Downloads: We fail right away. The debug log shows the Kermit program that
-we are starting in the pty says:
-
- "" - Invalid command-line option, type "kermit -h" for help.
-
-But of course we are not giving it an invalid command-line option.
-Switching to gkermit for the external protocol, now we see that no matter
-command-line options we use, we read 0d 0d 0a from the pty and then the
-next time we go to read from the pty we get 0 bytes and waitpid() says the
-program has exited with status 1.
-
-Why should downloading be different from uploading? ttptycmd has no idea,
-it does everything the same. The only difference would seem to be which
-side sends first, but even that tends to get washed out by each program's
-startup messages.
-
-Downloading with Kermit worked 2 days ago, what's different now? The buffer
-sizes. Putting the net-to-pty back up to 24K (from 48 bytes)... Now it
-works again.
-
-Conclusion: Kermit conditions the pty correctly, Zmodem does not. Therefore
-ttruncmd() must duplicate what ttpkt() does.
-
-Or not. Because rz works fine on ssh/telnet ptys too. But not on our pty.
-lrz exits immediately with status code 2 = 01000 but there are no clues in
-the lrz.c source code, I don't even see this exit status set anywhere.
-Unredirecting stderr, I see that the error is "lrz: garbage on command line".
-
-Why do both Kermit and Zmodem sometimes think they are receiving an invalid
-command line? If I could capture the garbage...
-
-Side trip #1: ("pty.log",O_WRONLY) gives "no such file or directory".
-Changed this to ("pty.log",O_CREAT,0644) and now it doesn't get an error,
-and it creates the file, but not with 0644 permissions, and with nothing
-written in it. How come nothing works?
-
-Fine, the debug log shows that ttptycmd() receives the correct string
-(e.g. "lrz -v"). It passes it to do_pty() correctly, and do_pty() passes it
-to exec_cmd(), which runs cksplit() on it, coming up (in this case) with
-"lrz" and "-v", which is right, and then:
-
- args = q->a_head + 1;
- execvp(args[0],args);
-
-execvp() wants the args array to have a null element at the end. cksplit()
-does indeed do that, or at least the code is there. Added code to exec_cmd()
-to verify the argument list and that it is null-terminated. So far it is.
-
-Anyway, we have traffic between the Zmodem partners, but no joy.
-Commenting out the bit that redirects stderr, now I can see it on my screen
-in real time:
-
- lrz waiting to receive.Retry 0: Bad CRC
- Retry 0: Got ERROR
- Retry 0: TIMEOUT
- Retry 0: TIMEOUT
- Retry 0: TIMEOUT
- Retry 0: TIMEOUT
-
-etc etc, forever. Trying sz -e on the far end, I get:
-
- Retry 0: Bad CRC
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- ...
- Retry 0: Got ERROR
- Retry 0: Bad CRC
- Retry 0: Got ERROR
- Retry 0: Got ERROR
- lrz: xxufio.c removed.
-
-So apparently it's not a matter of escaping. Trying some other stuff, I
-caught the command-line problem in the act:
-
- lrz: garbage on commandline
- Try `lrz --help' for more information.
-
-Debug log shows:
-
- cksplit result[lrz]=1
- cksplit result[-v]=2
- exec_cmd arg[lrz]=0
- exec_cmd arg[-v]=1
- exec_cmd arg[]=2
-
-An empty string at the end instead of a null pointer. I really do not see
-any way that could happen, but rather than dig into cksplit() again after
-all these years I added a test for this in exec_cmd(), which, of course
-after adding it, never encountered this behavior again.
-
-Fiddled with pty buffer size again. Made it 512 bytes instead of 24K.
-Zmodem downloads are the same (Rety 0: TIMEOUT, over and over). But I don't
-see what the problem is -- every time we receive n bytes from the net, we
-write n bytes successfully to the pty and there are no errors. But it also
-looks like the remote sender is sending the file header over and over
-because it's not receiving an acknowledgment. If we're not losing data,
-then maybe it's a transparency problem.
-
-Tried uncommenting the TIOCblah stuff I commented out before. Now instead
-of only timeouts I get:
-
- lrz waiting to receive.Retry 0: Bad CRC
- Retry 0: Got ERROR
- Retry 0: Bad CRC
- Retry 0: Got ERROR
- Retry 0: Bad CRC
- Retry 0: Got ERROR
- Retry 0: TIMEOUT
-
-which is odd because the TIOCREMOTE ioctl failed with errno 14, EFAULT,
-bad address, which should indicate it had no effect. We're still receiving
-data from the remote in tiny chunks (from 12 to 65 bytes), apparently the
-same stuff (file header), and writing them to the pty successfully but
-nothing...
-
-Looked at cloning ttpkt() for the pty, but these stupid routines use global
-tty mode structs so it's not going to be easy.
-
-Well, we got exactly nowhere today, but I think I'll leave stderr as it is
-so users will see some feedback; no reason not to.
-
-WHY DO KERMIT DOWNLOADS WORK AND ZMODEM NOT?
-
-Is it 8-bit transparency? Up til now I've been testing with text files.
-If I try to download a binary what happens? Fails after 99 seconds. Packet
-log from the far end shows that as soon as the first packet containing 8-bit
-data is sent, everything stops. At least I got one of these:
-
- 17:23:56.475 exec_cmd arg[gkermit]=0
- 17:23:56.475 exec_cmd arg[-qr]=1
- 17:23:56.475 exec_cmd arg[]=2
- 17:23:56.475 exec_cmd SUBSTITUTING NULL=2 <-- the code I just added
-
-Doing this again shows the same thing on the near end. All the 7-bit-only
-packets are sent and acknowledged OK. Three 8-bit data packets arrive and
-nothing else happens after that. This is with G-Kermit.
-
-The same thing happens with C-Kermit receiving. But if I change C-Kermit's
-.kermrc to turn off streaming and use a short packet length:
-
-The transfer works, even though it's sending 8-bit bytes. So the problem is
-not 8-bit data after all, per se. Facts:
-
- . Kermit can receive streaming transfers of 7-bit files.
- . Kermit can not receive streaming transfers of 8-bit files.
- . Kermit can receive nonstreaming transfers of 8-bit files with short packets.
- . Kermit can receive nonstreaming transfers of 8-bit files with 1K packets.
- . Kermit can receive nonstreaming transfers of 8-bit files with 4K packets.
-
-So it's the combination of streaming and 8-bit data? 12 Jan 2007.
-
-As a test I made a new routine pty_make_raw() that does cfmakeraw() (a
-nonportable "POSIX-like" function known to be used on ptys in applications
-that do approximately what we're attempting). Results:
-
- Solaris: errno 25 - inappropriate ioctl for device.
-
-This happens even when we try to get the terminal modes with tcgetattr(),
-which is completely nuts. We pass it the file descriptor of the pty master,
-which is supposed to work. But in Mac OS X, there are no errors. But
-downloads still don't work; lots of errors but the pattern is different.
-Using a very small buffer:
-
- Retry 0: Bad CRC
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Got TIMEOUT
- Retry 0: TIMEOUT
- Retry 0: Bad CRC
- Retry 0: Bad CRC
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: TIMEOUT
- Retry 0: Got ERROR
- Retry 0: TIMEOUT
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Bad CRC
-
-Using a bigger buffer:
-
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- (several screensful)
-
-Various other combinations... Nothing seems to work.
-
-Insight: telnetd does exactly what we want to do, sort of.
-But it uses TIOCPKT, so every time it reads from pty, it receives
-one control byte and then the data bytes, which would complicate our
-buffering scheme considerably. Anyway the TIOCPKT ioctl() fails on
-Mac OS X with 14 "Bad address".
-
-Also see: snoopserver.c (found in Google). It seems to do things in a
-slightly different way -- it sets stdout to raw and then dups it to the
-slave side of the pty?
-
-Maybe it's a mistake to use the ckupty.c routines. They are designed for
-creating and accessing an interactive session. Maybe just copy one of the
-other programs.
-
-18 Jan 2007. Tried going back to blocking rather than nonblocking reads
-to see if it would make a difference, after all the other changes. Nope.
-OK, let's look at some of these other programs...
-
-snoopserver.c. I don't know exactly what this is or where it's from or what
-platform it runs on and there are no comments to speak of, but it does
-approximately what ttptycmd() does. To get a pty it uses openpty():
-
- if (openpty(&pty, &tty, NULL, NULL, NULL) == -1)
-
-then creates a fork. In the fork, it closes the pty (master) and
-manipulates the modes of the tty (slave), dups tty to be stdio, and then
-doex execv() on the command. Meanwhile the upper fork closes the tty
-(slave), gets the attributes of stdin, using atexit() to have them
-automatically restored on exit. Then it sets stdin to raw mode and enters
-the select() loop on stdin, the pty master, and the net. It uses regular
-blocking reads. It does not use TIOCPKT or anything like it.
-
-openpty() is supported on: Linux, Mac OS X, NetBSD, FreeBSD, ...
-openpty() is NOT supported on: Solaris, HP-UX, ...
-
- 1. Try copying the pty code, but keep everything else the same.
-
-I did this; it compiles and starts OK, upper fork (ttptycmd) debug log shows
-no errors, but nothing happens. Logs show that the Kermit program that is
-started in the subfork seems to die as soon as it reaches eof on its init
-file. The good news, at least, is that select() doesn't report report that
-the pty is ready to be read. Clearly the file descriptors aren't being
-assigned as expected, or as before.
-
-In ckupty.c getptyslave() dup2's the slave fd to 0 and 1. The new code
-does exactly the same thing. Debug log makes it look like the forked kermit
-is not receiving its command line. But now I'm not even sure that the
-forked kermit started at all. ps from another terminal doesn't show it.
-
-19 Jan 2007: Noticed that in snoopserver, the select() calls use standard
-input and output file descriptors, rather than the pty master. Made that
-change... In doing that I had to look at every file descriptor in every
-line of code and discovered a couple mistakes, fixed them, put back the
-original code but with the fixes, tried it, but no change; can upload OK but
-still can't download with Zmodem without lots of errors and ultimate
-failure. Going back to the alternative version and trying to get the the
-file descriptors sorted out, now it appears that the external Kermit program
-never even starts in the lower fork. After a bit more fiddling I sort that
-out, but now when the lower Kermit program goes to open "/dev/tty" it gets
-errno 6 "Device not configured". Forcing it to use stdio with "-l 0", it
-gets past this and actually sends its first packet. But the Kermit on top
-reads nothing from the pty.
-
-Next, I change the pty fd from STDIN_FILENO and STDOUT_FILENO to slavefd.
-No difference. Next I comment out the dup2() calls. This time I get some
-action. The transfer starts, but only one packet comes. Log shows that
-the lower Kermit sends its S packet. The upper Kermit receives the ACK
-but the lower Kermit never gets it. The write to the pty succeeds, no
-error. Different combinations give different results. If write to master
-and read from the slave, I get packets in both directions but tons of
-errors.... This happens only if I comment out the dup2()'s.
-
-25 Jan 2007: After leaving it sit for a while, and realizing that what I'm
-trying to do has to be possible because so much other software does the same
-thing (e.g. Telnet servers), I put things back to how they were originally
--- the upper fork (Kermit) uses the master and the lower fork the slave.
-The upper fork puts the master in raw mode, the lower fork puts the slave in
-raw mode. The lower fork dup2's the slave fd to stdin/out. Send file in
-remote mode using external Kermit: works OK but select() times out at the
-end. This means that the self-contained pty code in ttptycmd() is sorted
-out -- all the file descriptors go to the right place, etc, and now we can
-use this routine as a testbed, rather than the original ckupty.c-based one.
-
-But send with lsz, csz, and regular rz: Nothing happens, times out after 0
-bytes of i/o. Once again, Kermit works, Zmodem doesn't. The reason for
-running Zmodem in a pty is so its i/o will work as it does on a terminal,
-no matter how it may fiddle the file descriptors. So why don't we see a
-single byte come out?
-
-Commenting out pty_make_raw(), I get a successful Zmodem send using lsz.
-csz manages to get the filename across, but then gets stuck. regular sz, on
-the other hand, works perfectly. Testing csz by itself (not under Kermit),
-I see it fails in exactly the same way ("Got phony ZEOF", etc). OK, forget
-crzsz.
-
-OK, let's move to local mode over a Kerberized Telnet connection...
-Uploading (sending) with external Kermit protocol... works.
-Downloading (receiving) with external Kermit protocol... works.
-Uploading with sz... works.
-Downloading with lrz... Gets tons of errors and fails.
-
-Running pty_make_raw() on the slave but not on the master: no difference.
-Running pty_make_raw() on the master but not on the slave: no difference.
-
-Back where we started... Either:
-
- . Zmodem is overdriving the pty, no matter what modes we put it in.
- . It's a transparency problem.
-
-Theoretically we should be able to test these by using different sz switches:
- -q: quiet (should always use this)
- -e: escape all control characters
- -B n: Buffer n bytes (rather than whole file)
- -L n: Packet length
- -l n: Frame length (>= packet length)
- -w n: Window size
- -4: 4K blocksize (doesn't help)
-
--q by itself doesn't help.
--q -e, this one worked but still got about 100 errors and was very slow.
--q -e -l 200 -L 100, failed fast and bad.
--q -e -w 1. Failed quickly.
--q -e -w 1 -B 100. Eventually failed.
--q -w 1, Eventually failed.
--q -l 1024, this gets much more errors, definitely need -e.
--q -e -l 1024, got pretty far before failing.
--q -e -w 1 -l 1024, also got pretty far before failing.
--q -e, this one got farthest of all, about 48K, before getting errors.
-
-In the latter combinations that work somewhat better, we always get up to
-16K, or 32K, or 48K, before the errors start coming out and piling up.
-Sometimes the errors are recoverable and we receive as much as 300K
-successfully before giving up.
-
-Now that we have data flowing pretty well (but not well enough), tried
-reinstating pty_make_raw(), but it hurt more than helped.
-
-As a sanity check, I tried transferring from the same host over the same
-kind of connection (Kerberized Telnet) directly to K95's built-in Zmodem
-protocol, and that worked fine. So the problem is definitely in the pty.
-Or more precisely, where Kermit writes incoming net data to the pty master.
-
-26 Jan 2007: Tried changing the size of the net-to-pty buffer from 24K to
-1K. Result: total failure. Set both buffers to 1K. Still total failure.
-Set both to 4K: now we get about 45K of data, then failure. Put them both
-back to 24K, still fails totally -- the same code that worked pretty well
-yesterday. Actually, no downloads work, not even Kermit, not even of
-text files.
-
-27 Jan 2007: Since I have not been able to find a way to make ptys work for
-this, I made a third copy of this routine, this time using pipes instead of
-ptys. The disadvantage here is that if the external protocol does not use
-stdio, the pipes won't work, but one thing a time...
-
-Inferior Kermit starts in lower fork, but when it tries to send its first
-packet it gets errno=9 EBADF, Bad File Descriptor. Substituting G-Kermit as
-the external protocol, which is simpler, reveals that the problem is that
-the external protocol gets errors when it tries to manipulate the its stdio
-file descriptors with ioctls, etc; these are not valid for a pipe. The pipe
-mechanism itself works. If I take out the test for ttpkt() failing in
-gkermit, the file transfer works OK. Trying Zmodem... Sending works OK;
-receiving works a lot better than with ptys (it got 360K into the file
-before failing). Making the buffers smaller, doesn't help.
-
-I'm starting to wonder if the problem might be in my buffering code, rather
-than in the pty or pipe interface... Try making a version that does
-single-character reads and writes.
-
-This one reads the first packet from the lower Kermit and sends it. It is
-recognized by the other Kermit, which sends an ACK. We see the ^A of the
-ACK, but then select() times out on the next character -- OF COURSE: because
-at a lower level, it has already been read. We have to check the myread
-buffer, and then call select() only if it's empty. Making this change:
-
- . SEND with G-Kermit works (but very slowly).
- . SEND with lsz works but gets a lot of errors, eventually succeeds.
-
-Let's work our way back... With the same changes to the buffered pipe version:
-
- . SEND with G-Kermit/streaming works (fast).
- . SEND with lsz works too (fast), but we get gubbish at the end.
- . RECEIVE with Kermit fails because "/dev/tty is not a terminal device".
- . RECEIVE with rsz... lots of errors ("garbage count exceeded") but succeeded.
-
-But maybe now we're seeing pipe artifacts, so going back one more step to
-the version that gets its own pty and starts its own fork:
-
- . SEND with G-Kermit/Streaming works (fast) but select() times out at the end.
-
-Another breakthrough: Moved the write pieces to below the read pieces. This
-is what was preventing the buffer reset code from working -- with the writes
-done before the reads, we never catch up and can never reset the buffers.
-
- . SEND with G-Kermit/streaming works (fast) (but there's a pause at the end)
- . SEND with lsz works (fast) (but there's a pause at the end)
- . RECEIVE with rsz... lots of errors ("garbage count exceeded") and fails.
- . RECEIVE with Kermit -- nothing happens (it thinks it succeeded), then we
- reconnect, terminal sees S packet and goes into autodownload
-
-From the log it looks like ttpkt() fails in the lower Kermit. Switching
-this with the hacked G-Kermit... it gets "transmission error on reliable
-link". Tried again with real Kermit below, this time with "-l 0" and not
-streaming. This was actually working, but slowly, I don't see any NAKs in
-the packet log, but then select() timed out.
-
-28 Jan 2007: Restored both the calls to pty_make_raw():
-
- . SEND with C-Kermit streaming works, but slow (54Kcps)
- . Ditto, but with debugging off -- hangs forever.
- . Ditto, but using G-Kermit instead of C-Kermit -- also hangs forever.
-
-Backed off on calling pty_make_raw(). Same thing.
-Reduced size of net-to-pty buffer. Same thing.
-
-15 Feb 2007... Decided to give up on this and publish it as is, in hopes
-that somebody with more experience with ptys can make it work, because I'm
-just going in circles. So today I just have to get the code into shape so
-people could choose among the three alternative routines. The second one,
-yttyptycmd(), is the one that uses openpty(), which is not portable, so it
-can be enabled only for Mac OS X, NetBSD, FreeBSD, and Linux, or by also
-defining HAVE_OPENPTY at compile time. Anyway, if you build Kermit in the
-normal way, you get the regular behavior -- ttruncmd() is used to execute
-external protocols. If you build it with -DXTTPTYCMD, you get the first
-version of ttptycmd(); with -DYTTPTYCMD the second, and with -DZTTPTYCMD the
-third.
-
-(Then some interruptions, then...)
-
-From Jeff, fix hostname comparison in X.509 certificate checking to work
-right in the case of names that contain no periods. dNSName_cmp(): cl_ssl.c,
-21 Feb 2007.
-
-John Dunlap noticed some strange behavior when transferring files between
-home base and the EM-APEX oceanographic floats via satellite... long story,
-but every so often the transfer would get stuck for a long time, and it
-happened only when C-Kermit was sending a file and received two or more
-packets (Ack or Nak) back to back from the float. Years ago I added some
-lookahead code to ttinl() to clear the input buffer of any interpacket junk
-so that, in the windowing case, we wouldn't be tricked next time around into
-thinking a packet was waiting to be read when there wasn't. The code, which
-has been there for a while, was a bit fractured; luckily, it would be
-executed only when the debug log was active so it didn't have much effect.
-The problem was that if the SOP came immediately after the EOP, it could be
-missed because the loop read the next character before checking the current
-one. Fixed by rearranging the loop. Also I changed it so it would execute
-in all cases, not only when the debug log was active. Also, cleaned up a
-bunch of confusing #ifdefs and removed some chunks that had been commented
-out for years, decades maybe. ttinl(): ckutio.c, 21-22 Feb 2007.
-
-Added NOW keyword info to HELP DATE, plus a tip about how to convert to UTC;
-suggested by Arthur Marsh. ckuus2.c, 22 Feb 2007.
-
-When an FTP client sends NLST to the server and no matching files are found,
-the server is supposed to respond with an error message on the control
-channel and nothing on the data channel. However it seems that at least one
-server sends the error message back on the data channel, as if it were a
-filename ("/bin/ls: blah: No such file or directory"), and on the control
-channel there is no error indication ("226 ASCII Transfer complete"). At
-this point remote_files() has a listfile and, if a match pattern was given,
-it looks through list to see if any of the lines match the given filename,
-e.g. "blah". This makes FTP CHECK give false positives. The problem
-(diagnosed by Jeff) is that the match pattern was not given in this case, so
-it takes some random default action, resulting in the spurious success
-return. Fixed by using the user's string as the pattern. Not tested,
-however, since I don't have access to a server that behaves this way.
-ckcftp.c, 22 Feb 2007.
-
-If an external-protocol file transfer fails, don't print Kermit-specific
-hints. ckuus5.c, 22 Feb 2007.
-
-One more time with ttinl(). Got rid of the "csave" junk, which never could
-have worked (which is no doubt why it was in a debugging section). The
-problem was that saving the beginning of the next packet locally did not
-synchronize with the buffer clearing (ttflui()) done at a higher level,
-between calls to ttinl(). So now, the lookahead code, if it finds the
-beginning an as-yet unread packet, puts it back at the head of the input
-queue. This way, if the protocol engine clears the input buffer, it will
-get the whole packet, not just the part after the SOH. ckutio.c, 24 Feb 2007.
-
-From Steven M Schweda, Saint Paul, MN: adaptation of large file support to
-VMS (it was already possible to transfer large files in VMS C-Kermit but the
-file-transfer display and statistics were wrong). And a minimal adaptation
-of the FTP client to VMS -- no RMS, no special VMS file stuff, Stream_LF and
-binary files only, developed and tested only with UCX. SSL/TLS is
-supported. The source-code changes are minimal; most have nothing to do
-with VMS, but with header files, prototypes, and data types (e.g. ftp_port
-int rather than short, various signed/unsigned conflicts) to shut up
-compiler warnings. Some of these could be dangerous in terms of
-portability; I've marked them with /* SMS 2007/02/15 */. ckcfns.c,
-ckcnet.h, ck_ssl.h, ckuus3.c, ckuus4.c, ckvfio.c, ckcftp.c, ckvker.mms
-(which was rewritten to actually reflect the source module dependencies),
-ckvker.com (also heavily modified). ckvker.com (the "makefile" for VMS
-C-Kermit) now includes "F" and "I" option flags for the large File and
-Internal ftp features, plus better handling of Vax/Alpha/IA64 distinction.
-26 Feb 2007.
-
-Changed NetBSD targets to include -DHAVE_OPENPTY and -lutil, so they
-can use openpty(). makefile, 26 Feb 2007.
-
-Built on Solaris without and with SSL OK.
-Built on NetBSD with Kerberos 5, OK.
-Built on Mac OS X 10.4, regular version, OK.
-Built on Mac OS X 10.4 with SSL and Kerberos 5, OK.
-
-On VMS 7.2-1/Alpha with MultiNet 4.4A-X...
-
-'CC' 'CCOPT' KSP:ckuus3
-%DCL-W-TKNOVF, command element is too long - shorten
- \CKUUS4.OBJ "'CC' 'CCOPT' KSP:ckuus4" "KSP:ckuus4.c KSP:ckcsym.h KSP:ckcdeb.h
- KSP:ckclib.h" "KSP:ckcasc.h KSP:ckcker.h KSP:ckcnet.h KSP:ckvioc.h"
-"KSP:ckctel.h KSP:ckuusr.h KSP:ckucmd.h KSP:ckuver.h" "KSP:ckcxla.h
- KSP:ckuxla.h KSP:ckcuni.h KSP:ckuath.h"
-
-The new rule for ckuus4.c was too long. I removed one file from the
-dependency list (ckcxla.h, which will probably never change again) and that
-made it OK. Built Nonet and Net versions OK, but this is without the new
-stuff.
-
-"make f" (large-file support) on VMS 7.2-1...
-'CC' 'CCOPT' KSP:ckuus4
- if (CKFSEEK(fp,(CK_OFF_T)j,SEEK_CUR) != 0) {
-........................^
-%CC-I-IMPLICITFUNC, In this statement, the identifier "fseeko" is implicitly
-declared as a function.
-
-Ditto for ftello and fseeko in various other places, and then fseeko and
-ftello come up up undefined at link time.
-
-The rule for ckcftp in "make i" (Internal FTP support) had the same problem.
-I removed ckcxla.h from its dependency list too, but "utime" comes up
-undeclared at compile time and undefined at link time.
-
-Verdict: neither one of the two new features can be used in VMS 7.2 or
-earlier, but the code still builds OK if you don't ask for them.
-
-VMS 8.3 on IA64... Can't build anything:
-%MMS-F-BADTARG, Specified target (WERMIT) does not exist in description file
-
-27 Feb 2007: Changed CKVKER.COM to keep all its dependencies but use a
-shorter logical name (Steven M Schweda). The problem on VMS 8.3 is that MMS
-now supports case-sensitive file systems, and so it can't find anything.
-Workaround: bypass MMS (include "m" in P1). With this, "@ckvker.com ifm"
-builds OK on HP Testdrive, but I can't test the new features since outbound
-connections are not allowed there. As for fseeko(), ftello(), and utime(),
-they simply are not available prior to VMS 7.3. It would probably be a good
-idea to test for this in CKVKER.COM, but actually it is possible to install
-newer C's and CRTLs on older VMS versions, so don't stand in their way.
-
-28 Feb 2007: With additional changes from SMS, and then some further
-adjustments, I was able to build the FTP version on VMS 7.2-1. First I
-tested it with GET of a binary file, but it transferred it in text mode.
-After a few more attempts with PUT and GET, it crashed with "floating/decimal
-divide by zero" in ckscreen, ckuusx.c line 27859. Of course, that's the
-listing line, not the source line, and I don't have a listing.
-
-To get a listing, I deleted CKUUSX.OBJ and then did:
-
- $ make i "" "" "/LIST"
-
-Surprisingly, it recompiled everything.
-
-Anyway, the divide by zero happened in a section of code where the divisor
-was not checked, but it was a section of code we should not have been
-executing at all, since the file-transfer display was fullscreen, and this
-was in the "brief" section. Anyway, I added the needed check. Again, it
-recompiles everything. Maybe there's no MMS on grumpy -- right, there isn't.
-
-ANYWAY... Try to GET a binary file like this:
-
- binary
- ---> TYPE I
- 200 Type set to I.
- get gkermit
- ---> TYPE A
- 200 Type set to A.
- ---> SIZE gkermit
- 550 gkermit: file too large for SIZE.
- GET gkermit (text) (-1 bytes)---> TYPE A
-
-Anyway... "get /binary gkermit" downloads it, seemingly correctly (the byte
-count is right).
-
-But "put /binary gkermit.;1" results in a 0-length GKERMIT file being sent.
-Here's the debug log:
-
-FTP PUT gnfile[DISK$MSA4:[C.FDC.NET]gkermit.;1]=1
-ftp putfile flg[DISK$MSA4:[C.FDC.NET]gkermit.;1]=0
-zltor fncnv[DISK$MSA4:[C.FDC.NET]gkermit.;1]=-1
-FTP PUT nzltor[GKERMIT]
-zfnqfp 1[DISK$MSA4:[C.FDC.NET]gkermit.;1]=675
-zfnqfp 2[DISK$MSA4:[C.FDC.NET]GKERMIT.;1]=31
-zfnqfp 3[DISK$MSA4:[C.FDC.NET]GKERMIT.;1]=31
-zrelnam result 2[gkermit.;1]
-ftp sendrequest restart[DISK$MSA4:[C.FDC.NET]gkermit.;1]=0
-openi name[DISK$MSA4:[C.FDC.NET]gkermit.;1]
-openi sndsrc=-1
-openi file number=2
-zopeni[DISK$MSA4:[C.FDC.NET]gkermit.;1]=2
-zopeni fp=0
-chkfn=2
-chkfn return=0
-zopeni fixed file format - using blk I/O
-zopeni binary flag at open=1
-zopeni ifile_bmode=1
-zopeni binary=1
-zopeni RMS operations completed ok
-openi zopeni 1[DISK$MSA4:[C.FDC.NET]gkermit.;1]=1
-ftpcmd cmd[PASV]
-FTP SENT [PASV]
-FTP RCVD [227 Entering Passive Mode (166,84,1,2,233,216)]
-initconn connect ok
-FTP SENT [STOR GKERMIT]
-FTP RCVD [150 Opening BINARY mode data connection for 'GKERMIT'.]
-doftpsend2 ftpcode[STOR]=150
-
- Here is where the file is supposed to be read and sent but there is nothing
- in the log between the "doftpsend2 ftpcode" line and the following line.
-
-rftimer status=1
-gftimer status 1=1
-gftimer status 2=1409025
-gftimer status 3=1409025
-gftimer s[0.000000]
-zclose n=2
-chkfn=2
-chkfn return=1
-zclose ZIFILE RMS operations completed ok
-ftp getreply lcs=0
-ftp getreply rcs=-1
-ftp getreply fc=0
-FTP RCVD [226 Transfer complete.]
-ftp getreply[226 Transfer complete.]=2
-doftpsend2 ok=0
-
-Everything is OK up until we go to send the file, then it behaves as if we
-got EOF immediately and so closes the data connection, and reports success;
-an empty copy of the file is left on the far end.
-
-Starting over with a text file.... PUT LOGIN.COM gets another divide by
-zero. But it happened in the code I just fixed, which is impossible. Swell.
-I recompiled everything and this time the upload worked, and downloading it
-again worked too.
-
-But a binary file still can't be uploaded. Trying to upload a text file
-after doing this seems to succeed (reports the right number of bytes sent)
-but nothing appears on the far side.
-
-SUMMARY:
-
- To download a text file: GET /ASCII blah.txt (/ASCII is optional)
- To download a binary file: GET /BINARY blah.bin (/BINARY is required)
- To upload a text file: PUT blah.txt (/ASCII switch not needed)
- To upload a binary file: PUT /BINARY blah.bin (doesn't work)
-
-Problems:
- . Why doesn't BINARY "stick"?
- . Why don't binary uploads work?
-
-The culprit seems to be the VMS version of zxin(). In the FTP module,
-zxin() is called only when sending binary files. In VMS, zxin() is just
-a front end for C-Library fread(). It probably needs to do just do
-zminchar() in a loop, like binary mode does, but calling zzout instead
-of xxout. Or something like that. FINISH THIS TOMORROW (debug on grumpy).
-
-2 Mar 2007: New logs from John Dunlap.
-
-ema-1636-log-0175.dbg: C-Kermit uploads a short file. It receives an Ack for
-the Z packet it just sent, tailgated by the beginning of a Nak for the next
-packet. When the second SOH is encountered, it is put back in the myread
-queue. Then the protocol engine, to which we return the Ack, says, "I have
-the packet I wanted so I'm clearing the buffer", and away go the first two
-bytes of the Nak from the myread buffer. Then, having just received the Ack
-of our Z packet, we send our B, and go to read the reply. in_chk finds 0 in
-the myread buffer (which we just cleared) and 6 waiting to be read from the
-comms channel, which it does, obtaining the remaining 6 bytes of the Nak,
-which it properly discards. (The reason this is proper is that, having
-already received the Ack for the last packet it sent, no Ack or Nak that
-arrives subsequently -- in the non-windowing case -- could possibly affect
-what it does next.) Since it hasn't yet found a good packet, it keeps
-reading, and now it finds the Ack to the B, as soon as it showed up. This
-is how it's supposed to work. No time was lost because of anything that
-C-Kermit did.
-
-ema-1636-log-0174.dbg: C-Kermit uploads a short file. It sends Data packet
-#3 and receives the Ack followed immediately by the first 3 bytes of a Nak
-for packet 4. When it gets to the SOH of the second packet, it pushes it
-back in the queue. Again, input() flushes the input buffer (myread queue
-and device buffer). C-Kermit detects EOF on the file it is sending, and
-sends the Z packet. Then it reads the remaining bytes of the Nak,
-which it discards, and then it finds the Ack for Z which comes in 23 seconds
-later, sends the B, gets a Nak for the B, sends the B again, gets the Ack
-for the B 4 seconds later, and done. Again, it's working right and losing
-no time.
-
-The question remains: what would happen if the protocol engine did not clear
-the buffer? Would ttinl() retrieve all packets in sequence even when they
-come back to back? To test this, I had C-Kermit send a file using 30 window
-slots and observed the stream of Acks in the reverse direction:
-
- HEXDUMP: mygetbuf read (16 bytes)
- 01 25 23 59 2f 52 39 0d | 01 25 24 59 2b 26 31 0d .%#Y/R9. .%$Y+&1.
- ttinl lookahead my_count=9
- ttinl lookahead removed=^M
- ttinl lookahead pushback SOP=^A
- HEXDUMP: ttinl got (7 bytes)
- 01 25 23 59 2f 52 39 | .%#Y/R9
- RECEIVE BUFFERS:
- buffer inuse address length data type seq flag retries
- 0 1 29212 9667 0 Y 3 0
- [\x01%#Y]
- ...
- in_chk my_count=8
- ...
- ttinl lookahead my_count=1
- ttinl lookahead removed=^M
- HEXDUMP: ttinl got (7 bytes)
- 01 25 24 59 2b 26 31 | .%$Y+&1
- RECEIVE BUFFERS:
- buffer inuse address length data type seq flag retries
- 0 1 29212 9667 0 Y 4 0
- [\x01%$Y]
-
-Here we can see that the pushed-back SOH was properly retrieved next time
-around, and the tailgating Ack was not lost. This scenario repeats itself
-212 times in the log, and there are no screwups.
-
-Back to VMS FTP... The problem with sending binary files is that zxin()
-uses C-Library fopen()/fread() instead of RMS, so it can't access the input
-file, which was opened by zopeni(), which is totally RMS-ified in VMS
-C-Kermit. For VMS only, I replaced the zxin() loop by a zminchar() loop
-like the one used in text mode, except without the character set or
-record-format conversion. Tested by PUT /BINARY of some binary files, which
-worked fine. ckcftp.c, 2 Mar 2007.
-
-Next problem... VMS C-Kermit ftp client sending binary files in text mode.
-Variation 1: We just send the file. zopeni() is supposed to detect that
-it's a binary file and automatically set the mode. And it does:
-
- zopeni fixed file format - using blk I/O
- zopeni binary flag at open=0
- zopeni ifile_bmode=1
- zopeni binary=0
- zopeni autoswitch from TEXT to BINARY
- zopeni RMS operations completed ok
-
-but then in gnfile():
-
- if (!server || (server && ((whatru & WMI_FLAG) == 0)))
- binary = gnf_binary; /* Restore prevailing transfer mode */
-
-Well, since VMS sets text/binary mode automatically when sending files,
-this code can (and should) be skipped in VMS. gnfile(): ckcfns.c, 2 Mar 2007.
-
-Variation 2: BINARY or SET FILE TYPE BINARY doesn't force binary mode. But
-SET FTP TYPE BINARY does. But BINARY does indeed call doftptyp() so what's
-the problem? We do indeed set ftp_typ to 1 but it gets reset somewhere
-before we call zopeni(). But then zopeni() puts it back to 1. Tracing
-through a transfer, it looks like all of this works right, it's only that
-the file transfer display says TEXT when the transfer is really in binary
-mode. This is because screen() is called before openi(). I wonder if we
-can call scrft() from the ftp module... No, that would be too easy. OK,
-sendrequest calls openi() and sets the file mode; putfile() calls
-screen(SCR_FN), which prints the transfer mode. But putfile calls
-sendrequest() after it puts up the screen that says the file type. So it
-looks like sendrequest() has to call screen(SCR_FN) again if it changes the
-file type. OK, that did it. ckuusx.c, ckcftp.c, 2 Mar 2007.
-
-The BINARY and TEXT (ASCII) commands do not inhibit automatic type switching
-in VMS. They don't in Unix either. They never have. Should they? I think
-so, otherwise what good are they? Plus we want the Kermit FTP client to
-behave like the others. I added code for this but it doesn't work, due to
-the layers and layers of text/binary detection and switching and
-if-this-but-then-if-that... Anyway, no harm done. The normal rule is:
-when you PUT a file, Kermit figures out on a per-file basis whether to use
-text or binary mode unless you include a /TEXT (/ASCII) or /BINARY switch
-in the PUT (or MPUT) command. ckuus[r3].c, ckcftp.c, 2 Mar 2007.
-
-Wed Mar 7 16:21:13 2007 WROTE SHORT TEST PROGRAM for ttruncmd (the openpty
-version) on Mac OS X. On dulce: ~/kermit/ttpty.c / ttpty.sh. It starts the
-external protocol in the lower fork. The command to run is a command-line
-argument. Sending and receiving files with Kermit works OK. But again, the
-standalone program totally fails when I use sz or lsz as the external
-protocol. So it looks like we can rule out any environmental effects of
-running the code inside C-Kermit.
-
-Mon Mar 12 16:52:20 2007: Put some effort into making ttpty.c more useful;
-added a debug log. Found that for some reason, at least on Mac OS X,
-select() always timed out at the the end. I added a SIGCHLD alarm and that
-seems to handle the fork exit condition very nicely. Now we can send (say)
-a 3MB file at good speed on Ethernet (1Mcps) considering the debugging, etc,
-and it terminates instantly. But when sending a file into ttptycmd (with
-"gkermit -r"), things go wrong at the end -- the Z packet is never
-acknowledged. This is reproducible. Maybe this is a good lead.... The log
-shows that select() timed out, even though the gkermit fork had not yet
-exited (or finished). It looks like gkermit sent the Ack, ttpty.c read it
-from the pty and sent it out the net:
-
- 0003: read pty=8 <-- read Ack from pty
- 0003: loop top have_pty=1
- 0003: loop top have_net=1
- 0003: FD_SET pty_in
- 0003: FD_SET ttyfd in
- 0003: FD_SET ttyfd out=8
- 0003: nfds=5
- 0003: select=1
- 0003: FD_ISSET ttyfd out
- 0003: write net=8 <-- send ack to net
- 0003: loop top have_pty=1
- 0003: loop top have_net=1
- 0003: FD_SET pty_in
- 0003: FD_SET ttyfd in
- 0003: nfds=5
- 0009: select=0
- 0009: select timeout - have_pty=1
-
-But Ack never arrived. This is a streaming transfer. But nope, streaming
-is not the problem. If I disable streaming ("gkermit -Sr"), we hang in in
-the middle of sending the data. If I use small packets, we don't hang:
-1000 is OK, 2000 is not. In fact, the cutoff is 1024. OK, TBC...
-
-Wed 14 Mar 2007: Receiving a file thru ttpty "gkermit -e 1200 -Srd"
-produces a debug log that shows that gkermit gets a lot of EAGAIN errors
-when it tries to read from its stdin. In fact, it takes 6 tries (read()
-calls) to read the S packet (27 bytes). Then when the first data packet
-arrives (1200 bytes), read() never returns even one single byte. The
-timeout interval is 15 seconds and it times out repeatedly. Added a
-primitive hex dump to the ttpty debug log for each read/write (showing only
-the first 24 characters and the last character, so it fits on one line).
-Tried uploading a file. The S, F, and A packets (short) are received and
-Ack'd OK, but then ttpty select() times out, never receiving even one byte
-from the D packet. Clearly, when the pty driver receives a burst of > 1K
-bytes, stops working. As before, if I limit the packets to < 1K, it works
-fine.
-
-Can I send an 8-bit binary file? Nope. ttpty reads the binary data just
-fine from the net and writes it exactly as it was received to the pty, but
-the first time we write an 8-bit byte, we never hear back from the PTY
-again. But the log shows that when the initial 7-bit packets from the pty,
-it looks like the PTY is not in rawmode, because these packets end with ^J
-rather than ^M. Calling pty_make_raw() on the masterfd and slavefd
-explicitly, however, doesn't change anything. It doesn't matter if I do
-this in the lower fork or the upper fork. So maybe it's the actual
-semantics of pty_make_raw() that are wrong.
-
-Thu 15 Mar 2007: Went thru all the terminal mode flags in Mac OS X; didn't
-help. Changed hex dump to show whole packet. Put hex dump routine in a
-private copy of G-Kermit. Tried to transfer an 8-bit file, logging both
-ttpty and gkermit. Compared what ttpty received on stdin with what it sent
-to the pty (same) and what was received by G-Kermit (same). Then I realized
-that my little test program was not putting its controlling terminal into
-raw mode; when I did that, I could upload binary files (streaming, 2MB/sec).
-And with Zmodem too (with rz; lrz doesn't work for some reason). Looking
-back at the original in ckutio.c, I see that ttptycmd() never called
-ttpkt(). Maybe that was the trouble all along. (Yup, but maybe not the
-whole trouble.)
-
-Moving back to C-Kermit and the original ttptycmd() routine, adding the call
-to ttpkt(), and stripping out a lot of cruft, and moving the pty_make_raw()
-code to ckupty.c, Kermit uploads and downloads (streaming) work fine in
-Solaris. Zmodem sends a file, but then the transfer hangs at the very end,
-as if the signoff protocol were lost. This happens on Solaris. If I move
-back to Mac OS X, everything works just fine. Then, making a Kerberized
-connection from the Mac to NetBSD, I can send files from the Mac with both
-Zmodem and Kermit. Receiving... Kermit OK. Zmodem... Nope. "rz:
-Persistent CRC or other ERROR" (and created a 265MB debug.log!)
-
-Fri 16 Mar 2007: ttptycmd() was for sending files with Zmodem across
-encrypted connections. But it occurred to me that it's necessary for
-clear-text connections too; e.g. Telnet, where 0xff has to be doubled. Of
-course Zmodem doesn't do that itself, so there's no way Zmodem external
-protocol could work when executed over a Telnet connection, and in fact
-it doesn't. I wonder why I ever thought it did.
-
-Wed 21 Mar 2007: Back to where we left off a week ago. Trying C-Kermit's
-ttptycmd() on the Mac again, in remote mode:
-
- . G-Kermit send txt (kst): OK 832Kcps
- . G-Kermit recv txt (kr): OK 425Kcps
- . G-Kermit send bin (ksb): OK 1000Kcps
- . G-Kermit recv bin (kr): OK 188Kcps
-
-And Zmodem:
-
- . sz txt (zst): OK 563Kcps
- . sz bin (zsb): OK 714Kcps
- . rz txt (zr): OK 863Kcps
- . rz bin (zr): OK 198Kcps
-
-So in remote mode, everything works. Now let's try a clear-text Telnet
-connection...
-
- . G-Kermit send txt (kst): OK 841Kcps
- . G-Kermit recv txt (krt): OK 391Kcps
- . G-Kermit send bin (ksb): OK 811Kcps
- . G-Kermit recv bin (krb): OK 171Kcps
-
-And Zmodem over the same clear-text telnet connection:
-
- . sz txt (zst): OK 91Kcps (*)
-
-Kermit is sending sz messages like "sz 3.73 1-30-03 finished." to the
-host, which tries to execute them, after the transfer is finished.
-Of course "sz" is a command, but:
-
- sz: cannot open 3.73: No such file or directory
- sz: cannot open 1-30-03: No such file or directory
- sz: cannot open finished.: No such file or directory
-
-Did I lose that code that dis-redirects stderr when I went back to using the
-pty code from the ckupty module? No, it's there and it's being executed.
-Apparently the copy of sz I have is writing its "finished" message to stdout
-because "sz blah 2> /dev/null" does not suppress it. Starting again with
-lsz instead of sz:
-
- . sz txt (lzst): OK 413Kcps
- . sz bin (lzsb): OK FAILED (*)
- . rz txt (lzrt): OK
- . rz bin (lzrb): OK
-
-(*) Sigh. Using lsz, we get "garbage count exceeded" errors and eventual
-failure. But using regular sz, we get the extraneous message that starts
-sz on the far tend, and the resulting getty babble.
-
-But even without changing the code, it will work one minute, and then fail
-consistently the next. For example, I was able to send files with sz
-successfully over and over, but with the getty babble at the end. Then,
-after trying lsz and then going back to sz, every attempt at sending a file
-quits with "Got ZCAN". The difference has to be that Kermit always does at
-least some minimal encoding of C0/C1 control characters such NUL and DEL and
-IAC, and I doubt that Zmodem does.
-
-http://zssh.sourceforge.net/ says:
-
- If file transfer is initiated but never completes (ie a line like :
-
- Bytes Sent: 0/ 513 BPS:0 ETA 00:00 Retry 0: Got ZCAN
-
- can be seen, but transfer never completes), chances are the pty/tty on one
- of the systems are not 8-bit clean. (Linux is 8-bit clean, NetBSD is not).
- Using the -e (escape) option of rz should solve this problem.
-
-It doesn't, at least not with lrz. And yes, the receiving end happens to be
-NetBSD. But it looks like the zssh people have been down this road too.
-
-But with rz and sz, it worked. Once. Twice. Three times. But of course,
-with the getty babble at the end. This can be taken care of by doing:
-
- rz -eq ; cat > foo
-
-which puts "sz 3.73 1-30-03 finished" and any other messages in foo (but you
-have to type ^D to finish the cat). Using this method I was also able to
-send an 8K binary file that contained a test pattern of all 256 possible byte
-values. Then I tried a 3MB binary executable. All OK. So here we go again:
-
- . sz txt (zst): OK
- . sz bin (zsb): OK
- . rz txt (zrt):
- . rz bin (zrb):
-
-Downloading fails about halfway through a fairly large file. I tried an
-even bigger file, guaranteed to be 100% ASCII; same thing -- halfway
-through: "rz: Persistent CRC or other ERROR". But it worked with a smaller
-version of the same file (82K versus 2MB). Tried again with the bigger
-version, it failed in exactly the same way at exactly the same spot: byte
-number 1048320. But this is just ASCII text so it can't be a transparency
-problem. Substituting another plain ASCII file of the same size but totally
-different contents, it doesn't fail (2.36MB). Back to the previous file, it
-fails again, but in a different spot (832960). So it's not totally
-deterministic.
-
-To round things out, I tried downloading the binary test-pattern file; it's
-only 8K. This failed.
-
- -4, --try-4k go up to 4K blocksize
- -B, --bufsize N buffer N bytes (N==auto: buffer whole file)
- -e, --escape escape all control characters (Z)
- -E, --rename force receiver to rename files it already has
- -L, --packetlen N limit subpacket length to N bytes (Z)
- -l, --framelen N limit frame length to N bytes (l>=L) (Z)
-
-Tried again with "sz -L 256 -B 256 -4aeq". Doesn't change anything.
-
-NOTE: Mac OS X rz 3.73 1-30-03 does not support -e.
-NetBSD rz 0.12.20 does support -e.
-
-Thu 22 Mar 2007: It occurs to me that ttpkt() might still be a problem;
-maybe it's the network connection and not the pty that is not transparent
-enough. To test this theory I did "stty raw ; stty -a" and then copied all
-of the flag values into ttpkt in the BSD44ORPOSIX section:
-
- . rz txt (zrt): OK (2.36MB file, worked 2 out of 3 times)
- . rz bin (zrb): "rz: Persistent CRC or other ERROR"
-
-A little more fiddling with the flags and I got the 8K binary test pattern
-to SEEM to download OK (in the sense that rz gave a 0 return code) but the
-file itself was truncated, always at 224. If I changed the test pattern
-file to not include any bytes with value 224 (0xe0) or 255 (0xff), the
-download worked. So we have a transparency problem somewhere. The debug
-log shows that all byte values are being received from the network correctly
-so the problem has to occur when we try to feed them to the pty.
-
-But no amount of twiddling with the termios flags seems to let these
-characters pass through. Of course, since they are not in the C0 or C1
-control range, "sz -e" doesn't quote them (which it does by prefixing with
-Ctrl-X and then adding 0x40 to the byte value so (e.g.) NUL becomes ^X@.
-Note that 255 does not cause problems because it coincides with the IAC
-character; the remote Telnet server doubles outbound IACs, and Kermit's
-ttinc() undoubles them automatically (as the log shows).
-
-Trying to send a different file (a C-Kermit binary) shows that 255 is the
-real killer; the file is truncated where the first one appears (at about
-6K), even though some 224's precede it. Going back to the remote-mode test,
-I see the same thing happens with the binary test-pattern file, if I send it
-from K95 direct to rz-under-C-Kermit-in-remote-mode. So it has nothing to
-do with C-Kermit having a network connection. Yet if I send the same file
-direct from K95 to rz, it goes OK and the result is not truncated, so it's
-not Zmodem either. The data arrives to C-Kermit intact, so the failure is
-definitely in writing it to the rz process through the slave and master ptys.
-
-BUT if I send the same file from K95 to rz-under-ttpty, that works. What's
-the difference? Suppose I just transplant ttpty literally into C-Kermit...
-It makes no difference. When receiving the test-pattern, it truncates it
-in exactly the same place.
-
-Well, all this is on Mac OS X. What if I move it to a different platform?
-OK, building on Solaris and following the exact same procedure, ttptycmd()
-doesn't even use the network connection. I think that's because rzsz on
-Solaris is hardwired to use the controlling terminal and can't be
-redirected, even in a pty?
-
-Moved to NetBSD.
-
- . sz txt (zst): Failed ("Got ZCAN")
- . sz bin (zsb):
- . rz txt (zrt): OK
- . rz bin (zrb):
-
-Well, this is a big mess. Sending doesn't work (or sometimes it does but
-reports that it didn't). Receiving... well, actually it's the same thing;
-the file is completely transferred but then the final protocol handshake is
-lost. The local C-Kermit returns to its prompt, but rz is still running:
-
- Retry 0: Got TIMEOUT
- Retry 0: TIMEOUT
- Retry 0: Got TIMEOUT
- Retry 0: TIMEOUT
- Retry 0: Got TIMEOUT
- Retry 0: TIMEOUT
- Retry 0: Got TIMEOUT
- Retry 0: TIMEOUT
- Retry 0: Got TIMEOUT
- Retry 0: TIMEOUT
- Retry 0: Got TIMEOUT
-
-I don't see how that is even possible. Even after I exit from Kermit the
-messages keep coming, even though ps doesn't show the rz process anywhere.
-Looking at the code, I see a place where end_pty() was still commented out
-from the ttpty.c episode, I uncommented it. But still:
-
- . sz txt (zst): Fails ("Got ZCAN")
- . sz bin (zsb): Fails instantly (but with no diagnostic)
- . rz txt (zrt): OK
- . rz bin (zrb): Fails with tons of "Bad CRC", "Garbage Count exceeded"
-
-Conclusion for the day: I think this is hopeless. Even if I can get it to
-work somewhere, the results depend on the exact Zmodem software, how it uses
-stdin/out vs stderr versus getting its own nonredirectable file descriptor,
-versus the Zmodem version on the other end and which options are available
-on each, versus the pty and select() quirks on each platform, and on and on.
-It will be so hard to explain and to set up that nobody would ever use it.
-It would be better to just implement Zmodem internally.
-
-Fri 23 Mar 2007: Went back to the small test program, ttpty.c. Tried
-setting both the master and the slave pty to rawmode, even though I have
-never seen any other software that did this. I had it receive the binary
-test pattern file; it worked. I made a bigger test-pattern file, 3MB,
-containing single, double, and triple copies of each byte in byte order and
-in random order, this one was accepted too.
-
-So it would seem that the ckupty.c module is something to avoid after all.
-It's full of stuff I don't understand and probably should not undo. So
-changing C-Kermit's ttptycmd() to manage its own pty again, using openpty()
-(which is not portable), I got it all to work in remote mode: Kermit
-text/binary up/down and Zmodem text/binary up/down. But in local mode on
-the client side of a Telnet connection...
-
- zst: OK, but we still get the getty babble at the end that starts sz.
- zsb: OK, ditto. This is with the 3MB test-pattern file.
- zrt: Not OK -- "Persistent CRC or other ERROR"
- zrb: Not OK -- got the cutoff at 224 again "Persistent CRC or other ERROR"
-
-It's close. But actually this was still with USE_CKUPTY_C defined. When I
-undefined it, it was back to being totally broken. Start over. (Check the
-new cfmakeraw() code.)
-
-Tue 27 Mar 2007: Starting over. Back to ttpty.c. Let's verify, VERY
-CAREFULLY, that it really does work, using the most stressful of the four
-tests: sending the big (3.2768MB) binary test pattern from K95 into rz
-through ttpty, logging everything. ttpty definitely receives the big file
-smoothly with no errors or hiccups when I have it set to use the master side
-of the pty for i/o. The application program (Zmodem in this case) runs on
-the slave, and the network and/or control program communicates with the
-master. This implies that Zmodem controls the terminal modes of the slave,
-and ttpty should be concerned with those of the master. Doing it this way
-in ttpty confirms this.
-
-Fine. But if I tell ttpty to SEND a file with sz, nothing happens. Ditto
-with lsz. Select times out waiting for input from the pty. But if I
-manually tell K95 to RECEIVE /PROTOCOL:ZMODEM it works OK. Somehow sz's
-initial B000000 string is being swallowed somewhere, and it's waiting for
-a reply from the receiver. sigh... But "ttpty gkermit -s filename" works
-fine. What's the difference? It has nothing to do with stdout vs stderr;
-sz is not writing to stderr at all. Is it some timing thing between the
-forks? Aha. It's that I change the modes of the pty master in one fork
-while sz is already starting in the other fork.
-
-OK, good, now for the first time we have Kermit and Zmodem both able to
-upload and download a large worst-case binary test-pattern file... in
-remote mode. Now taking today's lessons and fitting them back into
-C-Kermit so I can try it local mode...
-
-Using G-Kermit as the external protocol, first in remote mode... All good:
-text/binary up/down. The "halting problem" is solved by SIGCHLD, which
-catches fork termination instantly and lets ttptycmd() know there is no more
-pty. Zmodem:
-
- zst: OK
- zsb: OK
- zrt: OK
- zrb: OK
-
-That's a first. Next, repeat in local mode, in which C-Kermit is the client
-and has made a Telnet connection to another host over a secure (Kerberos V)
-connection:
-
- kst: OK zst: ...
- ksb: OK
- krt: OK
- krb: OK
-
-It seems we can never end a day on a high note. Somehow I seem to have
-broken regular internal Kermit protocol transfers over encrypted connections
--- the en/decryption engine loses sync. But they still work OK over a
-clear-text Telnet connection.
-
-Today's code in ~/80/dulce.tar (27 Mar 2007).
-
-Added makefile target solaris10g+openssl. Gathered all the standard CFLAGS
-for Solaris into cdcdeb.h so they don't have to be included in every single
-makefile target for Solaris. On local Solaris 10 host OpenSSL is in
-/opt/openssl-0.9.8e/. Tried the new makefile target, works OK. Also made
-solaris10+openssl for Sun CC, but couldn't test it because I can't find any
-Solaris 10 host that has Sun CC. Built with gcc at another site that has
-OpenSSL 0.9.8f-dev, all OK. ckcdeb.h, makefile, 24 Jun 2007.
-
-It occurs to me that Kermit transfers on secure connections might have been
-broken by the changes I made back in February to ttinl() for John Dunlap.
-Here, for the first time, we invoke myunrd() to push a byte back into the
-input queue, and there is also some funny business with "csave", which
-changed, and which an old comment notes that it has to be treated specially
-when encrypting. So it could be that the broken Kermit transfer has nothing
-to do with the work on external protocols, and that putting back the
-previous ttinl() will fix it. But now I can't seem to make a Kerberized
-connection from Panix to Panix, even though I can make one from Columbia to
-Panix. This means I have to build a Kerberized binary from the current
-source code on either Solaris or Mac OS X. Trying Solaris
-first... [~/solaris9k5/mk5.sh] This didn't work the first time due to
-undefined krb5_init_ets, which is referenced if MIT_CURRENT is not defined
-(it should be for Kerberos 5 1.05 and later and we have 1.42 here), tried
-again with -DMIT_CURRENT=1... Nope, that one totally blew up in ck_crp.c.
-Later, Jeff says krb5_init_ets is a no-op in Kerberos 1.4.x and later,
-so I added an #ifdef (NO_KRB5_INIT_ETS) for skipping it; now it builds and
-runs OK. ckuath.c, makefile, 9 Jul 2007.
-
-Meanwhile, using C-Kermit on Mac OS X, which makes the Kerberized connection
-just fine, but still has the problem transferring files over it. Packet log
-shows:
-
- s-00-01-^A9 Sz/ @-#Y3~Z! z0___F"U1@A^M
- r-00-01-^A9 Y~/ @-#Y3~^>J)0___J"U1@I
- s-01-01-^A(!Fx.x)(V^M
- r-xx-08-<timeout>
- S-01-08-^A(!Fx.x)(V^M
- r-xx-08-<timeout>
- S-01-08-^A(!Fx.x)(V^M
- r-xx-16-<timeout>
-
-Note that S packet is sent, received, and Ack'd OK. The F packet is sent but
-is never Ack'd. Tried this several times and noticed that it's just
-receiving that is screwed up, not sending. After ^C'ing out of the
-transfer, I can still type commands, and they are executed on the far end,
-but the results coming back are gibberish. Mon Jul 9 16:08:22 2007 (come
-back to this later... substitute Dev.27 ttinl for current one and see if
-the problem goes away, and if so, conditionalize the new code for clear-text
-connections).
-
-Built C-Kermit with Kerberos 5 on Solaris with a version of ckutio.c that
-uses the old ttinl() and transferred a file OK over a Kerberized connection.
-So now it's just a matter of reconciling the old and new ttinl. The easiest
-way to do this is to have new ttinl() chain to old ttinl() if the connection
-is encrypted, which is what I did and it works fine. At some point the two
-versions of ttinl() should be reconciled. ckutio.c, 12 Aug 2007.
-
-There was a function, islink(), used in only one place (ckuus6.c) that had
-the same name as a commonly used scalar variable, and it was missing a
-prototype. Changed its name to isalink() and added the prototype (Unix
-only), ckuus6.c, ckufio.c, ckcdeb.h. 12 Aug 2007.
-
-Revisiting the ASCII and BINARY top-level commands, which are supposed to
-be like in other FTP clients, but don't seem to have any effect. I added a
-new routine to the FTP module, doftpglobaltype(), that sets the global,
-sticky, permanent transfer mode (ASCII or BINARY) (TENEX could be added to
-if anybody asks). These commands (now that they work) are different from
-SET FTP TYPE { ASCII, BINARY }, which set the *default* transfer mode when
-automatic switching fails for a given file. ckuusr.c, ckcftp.c, 12 Aug 2007.
- (notify: Matt <mlist@cmcflex.com>)
-
-Even though the code hasn't changed, suddenly we're getting:
-
- "ckuusx.c", line 5682: warning: implicit function declaration: tgetent
- "ckuusx.c", line 6183: warning: implicit function declaration: tgetstr
- "ckuusx.c", line 6262: warning: implicit function declaration: tputs
- "ckuusx.c", line 6266: warning: implicit function declaration: tgoto
-
-in ckuusx.c on Solaris 9. <curses.h> is still in /usr/include, dated 2002.
-A quick search shows the missing functions are hiding in <term.h>, which
-until now was included only in Linux. Added a USE_TERM_H clause. No, that
-doesn't help, the prototypes are not selected at compile time; there are
-#ifdefs in that file that skip over these prototypes. I had to put them in
-the code under #ifdef BUG999..#endif (I could have used a longer name like
-#ifdef ADD_PROTOTYPES_FOR_CURSES_FUNCTIONS, but that would not be portable).
-ckuusx.c, 12 Aug 2007.
-
-Also:
-
- "ckuusx.c", line 9232: warning: implicit function declaration: creat
-
-This is called in the IKSD database code, used for getting a lockfile.
-creat() is a Unixism in code that is supposed to be portable. But IKSD only
-runs on Unix and Windows, so I assume the Windows C library has a creat()
-function. Anyway, suddenly the Solaris header files seem to have blocked
-whatever path previously existed to the creat() prototype (which is in
-<fcntl.h>), so I added an #include in the appropriate spot. ckuusx.c,
-12 Aug 2007.
-
-Kermit functions for converting the number base -- \fradix(), \fhexify(),
-\unfhexify() -- did not work with big numbers; ckradix() was missed in the
-CK_OFF_T conversion. Fixed in ckclib.c, 12 Aug 2007.
-
-Updated the help text for ASCII, BINARY, and SET FTP TYPE to clarify the
-semantics. ckuus2.c, ckcftp.c, 12 Aug 2007.
-
-Error messages were printed upon failure to open any of the four log file,
-even with SET QUIET ON. Fixed in ckuus4.c, 12 Aug 2007.
-
-Built OK on NetBSD 1.3_RC3. Tried to build secure version but the libraries
-had disappeared. 13 Aug 2007.
-
-Built OK on Mac OS X 10.4.9. Tried the secure version, macosx10.4+krb5+ssl.
-Here we get the usual pile of "pointer targets in passing argument 1 of
-(function name) differ in signedness", regarding security functions, but it
-built OK. 13 Aug 2007.
-
-Reconciling the two ttinl's... On encrypted connections myread() returns
-encrypted bytes; ttinl() has to decrypt them; it wasn't doing this in the
-lookahead section so I fixed it. The new code works on both encrypted and
-clear-text connections. I removed the chaining to oldttinl(), and
-oldttinl() itself. ckutio.c, 13 Aug 2007.
-
- (Wouldn't it make more sense and be more efficient and less confusing
- for myfillbuf() to do the decrypting?)
-
-When C-Kermit uses Zmodem as an external protocol, it doesn't seem to scan
-files before sending them to set text or binary mode appropriately. It's
-that external protocols bypass Kermit's whole "get next file" mechanism; the
-(possibly wild) filespec is simply passed to the external protocol program.
-Changing this would be a very big deal. But if only one file is being sent
-(the filespec is not wild) it's easy enough to check. I added this to the
-external protocols section of the protocol module. It can be overridden in
-any of the regular ways (/TEXT or /BINARY switch on SEND command, SET
-PATTERNS OFF, SET TRANSFER MODE MANUAL, etc). ckcpro.w, 13 Aug 2007.
-
-[FTP SEND /RECURSIVE]
-Peter Crowley reported a problem with FTP recursive uploads getting the
-directory tree wrong when the previous pathname was a left substring of the
-new pathname (e.g. foo/bar/ and foo/bar2/). The logic did not handle this
-case and created the bar2 directory as a subdirectory of bar, rather than as
-a parallel directory. Fixed in syncdir() and tested with various edge cases.
-ckcftp.c 14 Aug 2007.
-
- notify <peter.crowley@alumni.utexas.net>
-
-Added CD messages to FTP BRIEF display to track the ups and downs of
-recursive uploads. ckcftp.c, 14 Aug 2007.
-
-The OUTPUT command gave a misleading error message ("Connection to xxx not
-open") when used on a serial port that was, indeed, open but was not
-presenting the Carrier signal, when CARRIER-WATCH was not OFF. Added a new
-message for this, and some others. ckuus5.c, 14 Aug 2007.
-
-Sending from the command line, e.g. kermit -s foo, did not give an
-informative error message if the file could not be found or opened. Fixed
-in ckuusy.c, 14 Aug 2007.
-
-OK, back to ttptycmd.... It seems that back on March 27th, I got everything
-working but I thought that there was still something wrong with it because
-an unrelated problem so I put it aside. The version of ttpty.c from that
-date worked OK, and it looks like I updated ckutio.c from it, but that
-version of ckutio.c was put aside. Since then I have been working on the
-ckutio.c version that was NOT put aside and so now I have to reconcile the
-two:
-
- ~/80/ttypty/20070327/ckutio.c
- ~/80/ckutio.c
-
-As a first cut I did this simply by replacing the contents of the #ifdef
-CK_REDIR section of the latter with that of the former. Of course in
-Solaris this comes up with openpty() implicitly declared at compile time and
-unresolved at link time. So the first task is to get HAVE_OPENPTY defined
-for platforms that have it and have the others use the ttruncmd(). For
-starters I put an #ifdef block in ckcdeb.h that defines HAVE_OPENPTY for
-Linux, FreeBSD, NetBSD, OpenBSD, and Mac OS X. Ones that don't have
-openpty() include AIX, HP-UX, and Solaris. Others like SCO I don't know but
-I doubt it. The real solution is to get the ckupty.c module to work but one
-thing at a time... This version is supposed work with secure builds on the
-openpty() platforms, and on the others like Solaris, if an external protocol
-is attempted on a secure (encrypted) connection, an error message is
-printed and the command fails. ckutio.c, 14 Aug 2007.
-
-How to test? Apparently I did all my testing on Panix before, and that's
-where all my Zmodem builds are, but now when I build a Kerberized version
-(which works if I do it on the right pool host), it won't make a local
-connection, and there is no other place I can connect to that has a
-Kerberized Telnet server. I can, however, connect to Panix from here, using
-the same code, but on Mac OS X...
-
-Slight detour: Got access to AIX again (5.3.0.0). Picky compiler, some
-things needed fixing.... Also it says "1506-507 (W) No licenses available.
-Contact your program supplier to add additional users. Compilation will
-proceed shortly" and of course it goes kind of slow. For some reason, I
-can't do streaming transfers into AIX over a local network (to its SSH
-server), but windowed transfers are OK. Anyway, noting that we've been
-using the same basic makefile target since AIX 4.2, changing nothing but the
-version herald, I made a new target, simply "aix", that picks up the AIX
-version automatically and sets the herald from it. Ditto for aix+openssl,
-but on this host requires setting SSLINC and SSLLIB to /opt/ssl/include and
-/opt/ssl/lib. Also the make program here was extremely sensitive to spacing
-so I had to make some minor edits to get the link step to work for the SSL
-version. ckuusy.c, makefile, 14-15 Aug 2007.
-
-Got rid of the special Panix secure NetBSD target, replaced it with a
-regular one, which is invoked in the normal way by defining K5INC and K5LIB
-to point to to where the stuff is hidden. Cleaned up and modernized the
-comments in the makefile a bit. makefile 15 Aug 2007.
-
-Changed some data types and added some casts to ckctel.c to do away with
-tons of "pointer targets in passing argument 1 of 'xxx' differ in signedness"
-warnings. 15 Aug 2007.
-
-Set up Mac OS X as the testbed for ttptycmd(), with Panix as the remote
-partner over a Kerberos 5 connection. The first test is to send a 300K
-text file with gkermit as the external protocol. It worked fine, and the
-debug log showed all the right components were active (namely encryption and
-ttptycmd) [kermit/zmodem send/receive text/binary]:
-
- Kermit Zmodem
- kst OK zst OK
- ksb OK zsb OK
- krt OK zrt OK
- krb OK zrb Failed "rz: Persistent CRC or other ERROR"
-
-We've seen this before. The problem is 0xff, Telnet IAC, as I proved to
-myself by constructing a 3MB file that contained every byte but 0xff in every
-mixture and order and transferring it successfully over the same connection.
-Presumably the Telnet server is doubling IACs, whereas of course rz is not
-undoubling, thus the CRC error. This is progress. 15 Aug 2007.
-
-Log shows that indeed every IAC in the source file arrives doubled. Adding
-code to remove the first IAC of every adjacent pair, a small test file with
-different-length runs of IACs transfers OK. The 3MB all.bin file does not.
-
-Starting over... I can receive a big text file with Zmodem OK. The 3.2MB
-binary test pattern that contains no IACs failed after 1.8MB, but the part
-that it transferred was OK. A second try, almost the whole thing arrived,
-it stopped just 584 bytes short of the end. Could be that file size is a
-separate problem. Making a new copy exactly 1MB long... Well, that's
-interesting, this one too stopped just short of the end. And again, the
-same thing. When connecting back to the host, the last Zmodem packet can
-be seen on the screen; it's as if the local Zmodem exited before reading
-the last packet... But OK, if I change the options on the remote sz
-sender to use small blocks, etc, then it works.
-
-Now, changing from the 1MB no-IAC-binary test pattern, to the 1MB all-values
-test pattern, we fail after 81K. But the part that was transferred is
-correct. Second try, same thing, but 57K. Third: 40K. Each time, upon
-connecting back, the session is completely dead.
-
-IF I HAVE TO undouble IACs for incoming files, don't I have to double them
-going out? To send a block to net we just call ttol(), but ttol() doesn't
-do any doubling (because Kermit protocol always quotes 0xff). To see what
-happens, I changed the ttol() call to ttoc() in a loop that doubles IACs. I
-tested this by sending the full 3.2MB test pattern, which worked fine.
-
-For receiving, it's slow but it works OK with files that don't contain IACs
-(my concern was that IACs might appear in outbound files or in Zmodem
-protocol messages). It receives the 1MB no-IAC test pattern, so there are
-no problems with protocol or timing. But the full test pattern always gets
-cut off, but at different points, as before, with the remote session dead.
-Changing the Zmodem receiver from rz to lrz on the local end (since the
-sender on the remote end is lsz) does not change the behavior.
-
-Anyway, I went back and replaced the byte loop with something more
-efficient, and it goes about 20 times faster. But this doesn't help either,
-it only makes it fail faster. But aha, what if a doubled IAC is broken
-across successive pty reads -- we have to make the "previous character"
-memory persistent. Well, that was a good insight, but it still didn't fix
-it. The log shows the IAC handling code is working fine.
-
-What does sz say? Capturing its stderr to a file... "Retry 1: Got ZCAN".
-Next time: "Retry 1: Got TIMEOUT". Next time: Got ZCAN.
-
-Trying different Zmodem options... apparently I don't need to use short
-blocks. But I do need to use -e, probably because of Telnet NVT treatment
-of carriage return; without -e, there is a "persistent CRC error". -O
-disables timeouts, but this makes no difference.
-
-OK, we still have two Big Problems:
-
- 1. When a long file has no IACs, the final < 1K of the file is not received.
- 2. When a long file has IACs, the transfer generally stops very early.
-
-Problem 1: the transfer consistently fails less than 1K from the end of the
-file. Upon CONNECT back to the host, a big Zmodem packet is sitting there
-waiting to be read, which means ttptycmd()'s copy of rz is terminating
-early. Can we catch it in the debug log? Doing this takes forever and
-writes a GB to the disk... And then the problem doesn't happen. Also, I
-can receive a HUGE text file almost instantly with no errors at all.
-
-Switching to lrz on the receiving end, now I see the error messages, about
-300 lines like this:
-
- Retry 0: Garbage count exceeded
- Bytes received: 872352/1000000 BPS:85464 ETA 00:01 Retry 0: Bad CRC
- Bytes received: 892448/1000000 BPS:86690 ETA 00:01 Retry 0: Bad CRC
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Retry 0: Got ERROR
- Bytes received: 898336/1000000 BPS:84293 ETA 00:01 Retry 0: Bad CRC
- Retry 0: Garbage count exceeded
- Retry 0: Garbage count exceeded
- Bytes received: 900384/1000000 BPS:83751 ETA 00:01 Bad escape sequence
- 2fRe
- try 0: Bad data subpacket
- Bytes received: 941472/1000000 BPS:86191 ETA 00:00 Retry 0: Bad CRC
- Retry 0: Garbage count exceeded
-
-Even when it succeeds, it gets these. But if I receive a text file, no
-matter how big, no errors or retries or timeouts at all. So it appears that
-there is only one problem: a big-time lack of transparency regarding 8-bit
-and/or control characters. The odd thing is, it's not that the characters
-can't get through -- they all can -- but they seem to cause transitory
-blockages. 16 Aug 2007.
-
-Cleaned up the remaining pointer signedness warnings in ckutio.c, but this
-was a mistake, it broke Kerberos connections completely. Undid the changes.
-ckutio.c, 17 Aug 2007.
-
-Changed all return() in the fork()==0 section of ttptycmd() to exit().
-ckutio.c, 17 Aug 2007.
-
-Tried explicitly setting the slave pty to rawmode. Makes no difference.
-Tried using the Mac OS X (curses) raw() function, and also system("stty
-raw"); still no difference. Tried doing all of these in different
-combinations and orders. I found one combination that cuts the errors about
-in half, and the transfer of the no-IAC test pattern almost always succeeds
-(but it's slow). Anyway, it doesn't help much with the test pattern that
-contains IACs. Well, the code is more solid than it was before but
-functionally we have not advanced much if we can't download a binary file
-with Zmodem! On the other hand, we can upload them, and we can transfer
-text files in both directions, which is an improvement over the previous
-situation, in which the entire session would hang due to loss of
-synchronization of the encryption stream.
-
-Tried adding -funsigned-char to CFLAGS of Mac OS X target. It does not
-make the "signedness" warnings go away and it doesn't change the runtime
-symptoms.
-
-I tried a simpler version of pty_make_raw(), the one from Serg Iakovlev, but
-it was a total failure. That's encouraging though, because it indicates
-that pty_make_raw() is the right place to be working.
-
-Then I made pty_make_raw() set or unset every single terminal flag
-explicitly. This made no difference, but didn't hurt anything either.
-
-Then I made pty_make_raw() explicitly set all the c_cc[] characters to 0
-(but left c_cc[VMIN] as 1). This made no difference either.
-
-I checked pty_make_raw() against ttpkt() and the only difference I found in
-the terminal flags is that ttpkt() sets IGNPAR thinking it means "ignore
-parity errors" when really it means "discard any character that has a parity
-error" (at least according to Iakovlev) -- exactly the opposite. But I
-tried it both ways, no difference. 17 Aug 2007.
-
-I noticed that even Zmodem text receives can fail. They don't get any
-errors, they just get cut off shortly before the end. (But usually they
-succeed, and fast too, like 500K cps).
-
-What if I don't call pty_make_raw() at all on the slave pty?
-
-zrt: EESSSSSSSS: 80% good (E = stopped just before end but no other errors)
-
-zrb no-IAC test pattern, short blocks:
- 1. S/5 (success with 5 screens of errors.
- 2. S/7
- 3. S/7
- 4. S/6
- 5. E/7 (failed just before end)
- 6. S/7
- 7. S/6
- 8. S/6
- 9. S/6
-10. S/4
-
-So, lots of errors, but it recovered 90% of the time.
-Next, same thing, but without requesting short blocks:
-
- 1. E/5
- 2. S/5
- 3. E/4
- 4. S/5
- 5. S/5
- 6. S/5
- 7. X/0 (hard failure right away: "Got ZCAN"
- 8. S/5
- 9. S/5
-10. S/5
-
-So it doesn't look like short blocks make that much difference. Now what if
-I turn off prefixing? Bad CRC, fails immediately every time. Putting back
-pty_make_raw(slave), it still fails hard.
-
-Tried a new strategy with pty_make_raw(): rather than modify existing flags,
-I set all flags to 0, and then turn on only those few that we need like CS8.
-Now we get only 2.5 screens of errors instead 4-7 and the transfer rate is
-higher for binary files (all of the previous ones were under 100K CPS, while
-for text files it was 400-500K CPS):
-
- 1. S/2 195669 CPS
- 2. S/2 194720
- 3. E/3
- 4. S/2 192550
- 5. S/3 192325
- 6. S/3 145066
- 7. S/2 200689
- 8. S/3 188948
- 9. S/2 209461
-10. S/3 181991
-
-I noticed that there was no TIOCSTTY ioctl in the pty/fork setup sequence,
-which is recommended somewhere, so I tried that and it was a disaster; the
-entire session hung. I took it back out. 18 Aug 2007.
-
-Tried some transfers over a clear-text (not encrypted) connection with the
-same results: smooth, fast transfer of a big text file (400K cps); rocky but
-successful transfer of the no-IAC binary pattern file (135K cps). Switching
-back to ttruncmd(), the same binary file is received at 1.5M cps, and the
-no-IAC binary file totally fails after too many "Bad CRC"s; and we already
-know that any file that contains IACs will fail. One might say that
-ttptycmd() is better in every respect than ttruncmd() except in speed
-(when it works).
-
-Let's see if ttyptycmd still works in remote mode (to local K95):
- . sz / text works, but slowly.
- . lsz / text works but some weird errors are reported.
- . lsz / binary / no IAC doesn't work at all (CRC-32 mismatch for a header;
- Unexpected control character ignored: 13, etc).
- . sz / binary / no IAC works OK but slow.
- . sz / binary / full test pattern with IAC works OK but slow.
- . Sending text into rz fails completely.
-
-What about ttruncmd() in remote mode?
- . send /text works, fast.
- . send /binary works, fast.
- . receive /text works, not so fast but not bad.
- . receive /binary works, not so fast but not bad.
-
-So we use ttruncmd() for remote mode, and we use it for local mode
-serial-port and modem connections, and we use ttptycmd() on network
-connections because (a) they might be encrypted, and (b) even if they are
-not, they use some protocol that we have to handle, e.g. Telnet, Rlogin.
-19 Aug 2007.
-
-Discovered that Sending binary files no longer works. Text is OK, binary
-transfers don't even start. This happens on both encrypted and clear-text
-connections. ttptycmd() is being used in both cases. But oddly enough,
-receiving binary still works as before. What did I break, and when?
-Oh, it was just the script, when I changed it from using sz to lsz. Putting
-it back to sz makes it work, even with the full 3.2MB binary pattern with
-IACs.
-
-I backed off the changes I made to ckctel.c to suppress some warnings, in
-view of the fact that similar changes to ckutio.c broke things so badly.
-19 Aug 2007.
-
-If sz is not given the -e flag, it sends control characters bare, except ^P,
-^Q, ^S, and ^X. ^X is the control prefix, so ^A is sent ^X followed by A.
-With -e, all C0 control chars are prefixed, but with ^X, which is, of
-course, a control character. Interestingly, the C1 analogs of ^P, ^Q, ^S
-(but not ^X and, unfortunately, not IAC) are also prefixed. -e makes no
-difference for 8-bit characters.
-
-If we have a Telnet connection and the server is in ASCII (NVT) mode, CR is
-always followed by LF or NUL. Well, it seems the server is putting us
-(Kermit) in binary mode in this case, but staying in ASCII mode itself.
-Added code to handle NVT byte stuffing and unstuffing in each direction
-independently, according to the TRANSMIT_BINARY state in that direction. I
-made a file containing just the bytes 0-31 and 127 and 128-159 and 255 (66
-bytes all together) and sending it from the host to C-Kermit, the local log
-shows that every control character was received correctly and all TELNET
-conversions were done right -- NUL removed after CR (and only after CR); IAC
-removed after IAC (and only after an IAC meant as a quote). For the first
-time, I can receive the 1MB all-values test pattern, but there are still
-tons of (correctable) CRC errors, so the transfer rate is really awful, like
-about 5% of what we get with a text file (25Kcps instead of 500).
-
-Further experimentation shows that the fundamental transparency problem is
-fixed; we can receive short files (say, 1K or less) containing absolutely
-any byte values in any combination with no errors at all. But once the file
-size reaches (say) 10K, we get CRC errors, like one every 2 or 3K of data.
-These are not deterministic. In successive transfers of the same file, they
-come in different spots. It's tempting to blame pty buffer overruns, but
-then text files would show the same behavior. When a binary file size
-exceeds, say, 1MB, the chances of successful completion go way down,
-independent of whether my external protocol is rz or lrz. I like lrz better
-because the error reports come out on the screen as the transfer is going
-on. Trying to download a real-world binary file -- a 2.2MB C-Kermit
-executable -- I get 4500 error messages but the transfer eventually succeeds,
-with an effective throughput of 21Kcps.
-
-Actually it turns out that "sz -a somebigtextfile" (2.2MB) also gets a lot
-of CRC errors. The -e flag (escape all control characters) makes the same
-big text file transfer with few or no errors. It's not sure-fire.
-Sometimes no errors, sometimes one or two, and sometimes a fatal error that
-kills the transfer.
-
-With binary files... a 32K binary file seems to make it every time. 40K
-fails about 50% of the time. 48K fails 60% and every time it fails, it has
-created a partial file of exactly 32K (32768 bytes). 96K fails 9 out of 10
-times, when it fails, the partial file is always 0 bytes, or 32768, or
-65536, but that just means that rz's file output buffer is 32K.
-
-Why, then, do binary files cause trouble if it is not a solid transparency
-problem? If a certain file can get through once, why can't it get through
-every time? When a character arrives at the pty, the pty driver probably
-takes a different path through its code, checking the terminal flags that
-would affect that character. I tried making Kermit's network read buffers
-very small but, surprisingly, this made things worse. I also tried making
-them very much bigger, which didn't help either. 24K still seems to be the
-right size.
-
-So, is it that some characters take longer to process than others? So long
-that data is lost due to lack of flow control between TCP and the pty? One
-way to test this theory is to slow Zmodem down. I tried "-l 32" which,
-according to the man page, tells sz to "wait for the receiver to acknowledge
-correct data every N (32 <= N <= 1024) characters. This may be used to
-avoid network over-run when XOFF flow control is lacking." Makes no
-difference. I also tried the -w (Window) switch, ditto. In fact there are
-all sorts of options to set the "window size", "packet length", "block
-size", and "frame length", but with no explanation of what these mean or how
-they are related. If I crank everything down to minimum value:
-
- lsz q -L 32 -l 32 -w 1
-
-I get 50% success with the 96K file instead of 10%. Adding -e, oddly
-enough, made it worse. I also tried setting the environment variable
-ZNULLS to different numbers like 512, no help there either.
-
-I tried making the read-from-net-write-to-pty buffer small (1K) but leaving
-the pty-to-net one big. This improves chances of success, but it's
-intolerably slow (3Kcps when the connection is capable of 500K).
-
-I also changed the write-to-pty operation from a single write() call of
-possibly many K characters to a byte loop, one write() per byte. Same
-result: success (but still about 300 recoverable errors), throughput 3Kcps.
-20 Aug 2007.
-
-With ttptycmd() configured to write to the pty in a byte loop, it is
-possible to delay each write. Adding a 10msec delay per character results
-in a transfer that runs at about 20 cps and (for the 96K test file) would
-take about 80 minutes to complete. And yet it still gets just as many
-errors. So it's not a matter of timing either. The errors come, on
-average, every file 388 bytes, but not at regular intervals.
-
-I tried the TIOCREMOTE ioctl on the pty master, as discussed somewhat
-obliquely in the Mac OS X "man pty" page; "This mode causes input to the
-pseudo terminal to be flow controlled and not input edited (regardless of
-the terminal mode)" -- sounds like just the ticket but it made no
-difference. Actually, looking at a man page on another OS (Solaris), it
-says this is only for lines of text, EOLs are supplied, so that would mess
-up the protocol. So remember: don't use this.
-
-Tried without O_NDELAY; the behavior was the same but the speed was much
-slower.
-
-Tried switching back to the ckupty.c routines on Mac OS X and found that it
-works now the same as with openpty(), except that I seem to get more getty
-babble at the end. But this means I can run some tests on Solaris. I moved
-the entire test environment from Mac OS X 10.4.9 to Solaris 9. But it
-doesn't work at all.
-
-Trying to figure out the ckupty.c modules again.
- . do_pty() calls pty_getpty() which returns in arg1 the fd of the pty master.
- . Then it creates a pipe as a way to tell when the child dies
- . Then it creates a fork:
- - The parent does a blocking read from the pipe
- - The child calls getptyslave() to get the pty slave
- and writes one byte to the pipe
- and then execs the command it's supposed to run
-Note that the file descriptor of the slave is known only to the lower fork.
-Therefore the lower fork is the one that has to set all the tty modes, etc.
-I took care of all that but the ckupty.c method doesn't work at all on
-Solaris. But it works "fine" on Mac OS X (the 32K all-bytes test file
-transfers instantly with no errors, but the 96K one errors out).
-
-The problem on Solaris is that pty_make_raw() fails on the masterfd (but not
-on the slavefd) with errno 25 "ioctl inappropriate for device". It doesn't
-matter whether I do it in ckupty.c or ckutio.c. I found a web page on
-kde.org that says Solaris does not allow tcget/setattr() on a pty master.
-But the Sun "knowledge base" is not open to the public. Well, presumably
-changes made to the slave are reflected in the master (comments in Solaris
-telnetd seem to confirm this...) Let's come back to Solaris later.
-
-Moving to a Linux with lrzsz installed... Built a Kerberos 5 version with
-USE_CKUPTY_C. Like on Mac OS X, it transfers short files OK and chokes on
-longer ones. Switched to openpty(), it behaves the same. So the problems
-on Mac OS X are evidently not OS-specific, which is good I guess, since that
-means finding the way around them will apply to more than one platform.
-21 Aug 2007.
-
-Look into TIOCSCTTY again. On System V based OS's, opening a pty acquires a
-controlling terminal automatically. On BSD-based OS's, no; you have to use
-the TIOCSCTTY on the slave file descriptor to give it one. I'm not sure why
-a controlling terminal would be needed, except that without one, the virtual
-device "/dev/tty" does not exist for the process that runs on the pty, and
-maybe the application that runs there (e.g. rzsz) checks for it. On the
-downside, having a controlling terminal opens the process up to terminal
-interrupts like SIGINT and SIGQUIT. Until now I have not been using this
-ioctl(). Results (in Linux):
-
- With TIOCSCTTY: 96K all-bytes test: 11 screens of errors, then success
- Without TIOCSCTTY: exactly the same.
-
-Tried the same thing with TIOCNOTTY instead of TIOCSCTTY, with exactly the
-same results (no effect whatsoever).
-
-There has to be a way to make this work, because Zmodem works through
-telnetd, which basically the same thing as ttptycmd(): a relay between the
-network and a pty. ttptycmd() is like telnetd backwards. Modern telnetds
-are not much help; they don't access ptys or the network directly, they go
-through "mux" devices so I can't see what they're doing to get transparency
-and flow control. An old BSD telnetd uses packet mode but that would be a
-big deal...
-
-I tried ignoring various signals like SIGTTOU and SITSTP, since some Telnet
-clients do this. No effect, no difference. Anyway, in Linux the transfers
-almost always finish OK despite the many errors. There is just some trick
-I'm missing to make the pty accept a stream of arbitrary bytes without
-hiccuping.
-
-What about Solaris, which uses ckupty.c? In streams-based OS's, where line
-disciplines and whatnot are pushed on top of the pty, it looks like the pty
-module saves the file descriptor of the "bare" slave pty (as 'spty') before
-pushing things onto it, and then later uses spty rather than the regular
-slave pty file descriptor when getting/setting terminal modes. I'm not sure
-what this is all about but it's definitely SysVish... It happens if
-STREAMSPTY is defined, but I noticed that STREAMSPTY is never defined
-anywhere. I tried defining it so we take an entirely different path through
-the code. It made absolutely no difference.
-
-Then I noticed that HAVE_STREAMS is not defined for Solaris either. Tried
-defining it, but the session didn't work at all, no i/o. Removing the
-HAVE_STREAMS definition but keeping the STREAMSPTY defined, I rebuilt and
-tried "set host /connect /pty emacs". I got an EMACS screen but could not
-type anything into it, which means that STREAMSPTY should not be defined
-either. Removed the definition and "set host /pty" works again. So what's
-the problem with ttptycmd()?
-
-In fact, ttptycmd() works on Solaris with Kermit as the external protocol,
-but not with Zmodem, not even with text files. So again, there is no
-fundamental problem with the code or the logic, it's Just A Matter Of
-Transparency to control and/or 8-bit characters -- some trick I don't know
-about.
-
-Looking at the Solaris debug log... I see that ckupty.c is calling
-init_termbuf() to set the tty modes of the master, not the slave, and
-set_termbuf() to set them, but you can't do that in Solaris, error 25. This
-is in getptyslave(). Shouldn't getptyslave() be setting the tty modes of
-the slave, not the master? I changed it to do this, but like all other
-changes, it made no difference. I checked to make sure that after the change,
-"set host /pty /connect emacs" still worked and it did.
-
-And then what... I had some code to redirect stderr in ckupty.c that was
-not being executing due to a typo. When I fixed the typo, poof, Zmodem
-binary transfers started working, or working as well as they work in Linux
-and Mac OS X. It turns out that if I don't redirect stderr, sz and rz
-just don't work. But lsz and lrz do. But if I do redirect it, I don't see
-the progress messages from lsz/lrz. 22 Aug 2007.
-
-Built on HP-UX 11i v3 (B.11.31 U ia64) with optimizing compiler, got tons of
-picky warnings, but it finished and linked and runs OK. Many of the
-warnings were like this:
-
- "ckucns.c", line 1606: warning #2068-D: integer conversion resulted in a
- change of sign: tnopt[0] = (CHAR) IAC;
-
-IAC is defined as 255 in ckctel.h. If I define it as 0xff, I don't get the
-warnings. I changed the definitions of all the Telnet commands to be in hex
-notation rather than decimal. If cuts way down on the HP-UX warnings and
-doesn't seem to cause problems elsewhere. ckctel.h, 23 Aug 2007.
-
-Now it looks like Solaris is working but then it hangs at the end. It
-appears as if the ckupty.c module is blocking SIGCHLD. Debug log shows that
-when the transfer is complete, we received IAC DM (Telnet Data Mark) after
-sz's last gasp and before the shell prompt is printed. But calling
-tn_doop() in this case is a mistake because we are reading the number of
-bytes that we know are available in a counted loop, but tn_doop() would
-consume an unknown number of bytes and we would never know when to exit the
-loop. Anyway, C-Kermit doesn't do anything with DM. Skipping over
-tn_doop() (and not writing out the Telnet command bytes) fixes the hanging
-condition at the end, even though SIGCHLD is never raised. ckutio.c,
-23 Aug 2007.
-
-Some tests, Solaris to NetBSD over K5.
-zst sends ascii.txt, a 2.36MB ascii text file (Kcps / Errors).
-zrt receives the same file:
-
- zst 587/0 526/0 542/0 434/0 423/0
- zrt 827/0 800/0 847/0 FAIL 610/0
-
-So text is good. Binary not so good. Here we transfer the 1MB all-bytes
-pattern file. zrb receives it successfully, but with 1248 errors, at only
-15Kcps. Sending the same file out always fails:
-
- Begin 20070823 16:32:07: SEND BINARY all2.bin [sz]
- Sending: all2.bin
- Bytes Sent: 5600/1000000 BPS:12446 ETA 01:19 FAILURE
- End 20070823 16:32:13
- Elapsed time: 6.617992999999842
- cps = 151103.2121067556
- lsz: caught signal 1; exiting
-
-Decided to move to Linux but found that something is screwed up in Linux
-C-Kermit with tilde expansion:
-
- send ~/testfiles/all.bin
-
-doesn't expand at all (but it did yesterday!). The problem was in the
-ancient, ancient realuid/setuid handling code; real_uid() no longer works in
-Linux. I worked around this in whoami() by setting ruid to getuid() if
-real_uid() returned a negative number. Maybe dangerous, worry about it
-later. ckufio.c, 23 Aug 2007.
-
-ANYWAY... after fixing that, I tested zsb on Linux, and it's broken there
-too, using openpty(), so it's nothing to do with ckupty.c. After sending
-the first Zmodem data packet, it just hangs, nothing comes back. In text
-mode it gets farther, but then the same thing happens. Captured stderr from
-rz on the far end:
-
- Bytes received: 608/1000000 BPS:21137 ETA 00:47 Retry 0: Bad CRC
- Bytes received: 864/1000000 BPS:23540 ETA 00:42 Retry 0: Bad CRC
- Bytes received: 1120/1000000 BPS:25003 ETA 00:39 Retry 0: Bad CRC
- Bytes received: 5696/1000000 BPS:56988 ETA 00:17 Retry 0: Bad CRC
- Bytes received: 9120/1000000 BPS:62227 ETA 00:15 Retry 0: Bad CRC
- Bytes received: 9376/1000000 BPS:60766 ETA 00:16 Retry 0: Bad CRC
- Bytes received: 9632/1000000 BPS:60361 ETA 00:16 Retry 0: Got TIMEOUT
- Retry 0: Sender Canceled
- Retry 0: Got ZCAN
-
-The local sz, however, doesn't give any error message. ZCAN means: "other
-end canceled session by sending 5 ^X's" (or user typed them). What actually
-happens is that ttptycmd()'s select() times out waiting for something from
-the Zmodem partner and ttptycmd() itself kills the sz fork with SIGHUP.
-When lsz receives SIGHUP it sends the ZCAN. So the real problem is that
-after some point we're not receiving anything.
-
-I changed the timeout from 4 seconds to 30 seconds and now I see it just
-stops for long periods of time and then resumes. The lrz log on the
-receiving end shows tons of timouts, CRC errors, and other errors. The
-local log shows that lsz wound up sending ZCAN (2 x (10 x ^H, 10 x ^X)).
-
-Moving on to another problem... Turns out Ctrl-C (SIGINT) is working right
-after all. Since I'm using my test scripts like kerbang scripts, Ctrl-C
-exits through trap(), as it should, closing the connection and cleaning up.
-If I start Kermit and tell it to TAKE the script, then Ctrl-C brings me back
-to the prompt with the connection still open (as it should). However, until
-now I haven't done anything about the fork or the ptys. Added code to
-trap() to kill the fork and close the master pty. ckuusx.c, 24 Aug 2007.
-
-Added code to try to break the deadlock. If select() times out, but we have
-stuff to write either to the pty or the net, try to do it anyway, even
-though select() did not say we could. But this doesn't help because when
-select() times out we don't have anything to write. The problem is that
-after receiving that last packet from the remote rz, the local lsz doesn't
-seem to do anything, as if the lower fork wasn't running (and to confirm
-this hypothesis, sometimes I noticed that when I Ctrl-C'd out of this, the
-transfer would take off again).
-
-Backing up and testing with gkermit rather than zmodem:
-
- kst ripple.txt [824K] OK
- kst ascii.txt [1359K] OK
- krt ripple.txt -- FAILED
-
-It seems that we can't handle streaming. If I set up krt to disable
-streaming on receipt, it works OK.
-
- krt ripple.txt [824K] OK
- krb all2.bin [1000K] OK
-
-So here we have no trouble sending but big trouble receiving unless we
-disable streaming. Whereas with Zmodem we have trouble receiving.
-
-But this wasn't happening before, what changed? Using C-Kermit on the far
-end to receive the file with debug log on, I see that it is sending 4K data
-packet after 4K data packet, with the local gkermit silent, as expected.
-About midway through the transfer, the local Kermit sends an error packet
-"Transmission error on reliable link". Looking at G-Kermit's debug log...
-It receives the first five 4K data packets OK, but gets a CRC error on the
-fifth one, and sends the Error packet. So it has received a stream of
-20-some thousand bytes OK and then messes up. That number sounds a lot like
-ttptycmd()'s buffer size. I changed the buffer sizes to be different:
-
- Read from pty and write to net: 4K
- Read from net and write to pty: 1K
-
-This time it received the first 4K packet and failed on the second one.
-Then I increased the buffers to 98K each, expecting to receive lots more
-packets successfully but it bombed out on the 5th one. But that's good, it
-confirms there's no logic error in the buffer management. Just to make
-sure, though, let's set the buffer size smaller than the packet size and
-disable streaming. In this case we get 4 good data packets and a CRC error
-on the 5th one and so we request retransmission, and the next 8 times it
-arrives it gets a different CRC error, but the 9th copy is OK. Then the
-next packet comes and it gets a CRC error every time. And this is nothing
-but plain ASCII text.
-
-Switching to remote mode:
-
- REMOTE=1 kk kst
-
-(after tricking myself because it was using ttruncmd() for this...) I see
-that nothing works at all. What did I break? 24 Aug 2007.
-
-Fixed ttptycmd() to restore console modes after a remote-mode transfer.
-ckutio.c, 25 Aug 2007.
-
-Noticed that error codes like ESRCH are not available in all modules.
-That's because of some complicated in #ifdefs in ckcdeb.h that wind up not
-always #including <errno.h>. But I notice that ckutio.c includes it
-unconditionally with no ill effects, and so does ckvfio.c. Does any version
-of Unix at all not have <errno.h>? Added a catch-all clause to ckcdeb.h to
-#include <errno.h> (in UNIX only) if, after the other clauses, ESRCH was
-still not defined. ckcdeb.h, 25 Aug 2007.
-
-Now back to debugging ttptycmd()... Remote-mode transfers with ttptycmd()
-were broken in two places, maybe as long as 2 weeks ago (this would have
-affected non-network transfers too, which I can't test any more).
-The logic was missing in a couple places for the non-network and/or
-non-Telnet and/or non-encrypting connections (if statements with no else
-parts). Fixed in ckutio.c, 25 Aug 2007.
-
-Testing remote mode:
-
- kst OK zst OK
- ksb OK zsb OK
- krt OK zrt OK
- krb OK zrb OK
-
-Functionally it all works but there are hitches with Zmodem as always.
-When sending to K95:
-
- . If I send with lsz, there are hundreds of "Subpacket too long" errors,
- and the transfer is very slow, but it succeeds.
-
- . If I send with the 1994 Omen version of sz, transmission is instantaneous
- and without errors, but then it hangs at the end.
-
- . If I bypass C-Kermit and send direct from lsz or sz, both work fine.
-
-So clearly the ptys are getting in the way. The hanging at the end would be
-caused by the sz process closing before its last output reached the master
-pty. It would need to do some form of flushing and/or pausing at the end
-but there's nothing I can do about that; these programs were not designed to
-be used in this way. Anyway, it only seems to happen with files longer than
-100K.
-
-For local mode, testing in Solaris over our Kerberos 5 connection again:
-
- gkermit lrzsz
- kst OK zst FAIL
- ksb OK zsb FAIL
- krt OK zrt OK but with errors
- krb OK zrb FAIL
-
-If I use Omen rzsz as the external protocol (e.g. with zst), it blocks
-redirection and it sends the file to my terminal, rather than over the
-connection. This would probably be because it finds out the device name of
-the job's controlling terminal and opens it, to prevent redirection. This
-is hard to prevent in Solaris because there is no TIOCSTTY ioctl().
-Supposedly the same thing is accomplished by closing and reopening the slave
-pty after doing setsid(). I added code to do this, but it made no
-difference. (If I use lsz instead of sz, it is indeed redirected, but jams
-up after about 15K.) ckupty.c, 27 Aug 2007.
-
-On Mac OS X with sz 3.73 1-30-03, however, the redirection works, so I
-assume it would also work in Linux, FreeBSD, NetBSD, etc, too. Doing the
-full test suite on Mac OS X:
-
- gkermit lrzsz rzsz
- kst OK zst FAIL (1) OK
- ksb OK zsb FAIL (2) OK
- krt OK zrt OK (3) OK for 100K file, fails for longer.
- krb OK zrb FAIL (4) OK (1MB all-bytes test pattern)
-
-(1) 64K file OK every time; 100K file fails every time.
-(2) 10K file fails every time.
-(3) Succeeds with 800K file but gets a few recoverable errors.
-(4) Succeeds with 48K binary file with some errors, fails with longer ones.
-
-So actually it looks pretty good, it's just that lrzsz messes up. When
-sending with lsz if I include -L 512 it sends the 100K test file with no
-errors, but still chokes on longer ones.
-
-Testing on Mac OS X again, but this time over a clear-text Telnet connection:
-
- gkermit lrzsz rzsz
- kst OK zst FAIL(1) OK
- ksb OK zsb FAIL(2) OK
- krt OK zrt OK(3) OK
- krb OK zrb FAIL(4) OK
-
-(1) Almost worked, finished 777K out of 824K without errors.
-(2) Got tons of errors, failed in first 30K out of 1000K.
-(3) OK for 100K file but fails for larger.
-(4) OK for 48K binary fail but fails for larger.
-
-Maybe see if we can do without the OPENPTY part.
-
-TOMORROW -- just clean up the code, add some SET / SHOW / HELP commands,
-document it, and move on.
-
-Note: In K95, SET WINDOW sets the Zmodem packet length, 32 - 1024, multiple
-of 64.
-
-SEE ~/80/external.txt
-
-Changed ftp port from int to unsigned int. ckcftp.c, 30 Aug 2007.
-
-Tried again to build KRB4/KRB5/SSL/TLS version for Solaris 9. Had to update
-the build procedure again, of course, because of new file and directory
-names, but ran into problems anyway because the
-cu-solaris9g+krb5+krb4+openssl+shadow+pam+zlib target was calling another
-target that did not know about the hardwired pathnames. Integrated the two
-targets and tried building again. It actually compiled ok (but with lots of
-warnings from the security modules), but failed at link time with
-krb5_init_ets not found; fixed that with an #ifdef NO_KRB5_INIT_ETS, now it
-builds OK but without the ftp client. Tried building it WITH the FTP and
-that was OK too, no changes needed except to the build procedure. 12 Feb
-2008, that is: C-Kermit 8.0.212 : 20080212.
-
-Tried to build with -DCK_SRP and -lsrp but:
-
- hash_supported ckcftp.o
- hash_getdescbyname ckcftp.o
- hash_getdescbyid ckcftp.o
- cipher_getdescbyname ckcftp.o
- krypto_delete ckcftp.o
- krypto_new ckcftp.o
- cipher_supported ckcftp.o
- krypto_msg_priv ckcftp.o
- krypto_msg_safe ckcftp.o
- hash_getlist ckcftp.o
- cipher_getlist ckcftp.o
- cipher_getdescbyid ckcftp.o
-
-Sent mail to Tom Wu and backed off for now. makefile, 14 Feb 2008.
-(Tom Wu never answered; seems like SRP is defunct.)
-
-The ".blah = xxx" form of variable assignment only worked for variables
-names of length 22 or less, noticed and fixed by Wolfram Sang. ckucmd.c,
-5 Mar 2008.
-
-In "set host /pty ssh ..." connections, the INPUT command suddenly stopped
-working. This is in Solaris 9. It happens with all 8.0.* versions of
-C-Kermit, so it's nothing to do with ttptycmd(). Added some debug()
-statements but they don't show anything. Turns out there wasn't a problem
-after all. Wed Mar 26 16:04:53 2008
-
-Changed cmifi() to not print "?No files match" (or whatever) if SET QUIET ON.
-ckucmd.c, 26 Mar 2008.
-
-Added \v(remoteip) for the IP address of the host we're connected to,
-and \v(inmessage) for INPUT status messages corresponding to \v(instatus).
-ckuusr.h, ckcmai.c, ckuus[24].c, 26 Mar 2008.
-
-Made \fkeywordval() strip braces/quotes from the right-hand side so we can
-handle things like:
-
- password="stringwithspaceatend "
-
-ckuus4.c, 6 Aug 2008.
-
-Added invisible PUTENV command for UNIX only. Value should not be enclosed
-in doublequotes. Requires lge \v(buildid) 20080826. ckuusr.[ch], 26 Aug 2008.
-
-Added SET VARIABLE-EVALUATION { RECURSIVE, SIMPLE }. This is highly
-experimental, but also highly desirable if it works out. SIMPLE inhibits
-the default recursive method of evaluating \%x and \&x[] variables, which
-is, quite frankly, nuts and makes programming in Kermit at best
-counterintuitive. I made an exception in the case of array subscripts,
-because changing how they are evaluated could break a lot of scripts, and
-anyway there should never be any harm in evaluating them recursively because
-their final value is always (or should be) numeric, not some string that
-might contain backslashes. The SET VAR setting is on the stack, just like
-SET QUIET (it follows the quiet/xquiet code in ckuus[356].c), so macros or
-command files that change it can't break the script that invokes them.
-Added \frecurse() to force recursive evaluation of a \%x or \&x[] variable
-regardless of the VARIABLE-EVALUATION setting. Added \v(vareval) to allow
-programmatic setting to current setting. Tested on Solaris 9 but should be
-totally portable. ckuusr.[ch], ckuus[356].c, 11 Sep 2008.
-
-From G�nter Knauf: 64-bit builds were failing on SuSE Linux because
-libresolv and libcrypt were in lib64 rather than lib; updated the tests in
-the linux makefile target to find them. makefile, 12 Jan 2009.
-
-Tried building on Red Hat Enterprise Linux Server release 5.3 64-bit.
-There is no curses or ncurses. "make linuxnc" compiled OK but collapsed at
-link time looking for crypt(), res_search(), and dn_expand(). Turned out
-the linuxnc (and linuxc) targets needed the same treatment as the Linux one
-for 64-bit Linuxes. makefile, 3 Mar 2009.
-
-Consolidated the linux targets so we no longer need three separate ones for
-curses, ncurses, and no curses. "make linux" works ok on computers with and
-without (n)curses. "make linux+ssl", ditto. "linux+krb5+ssl builds OK but
-needs -DNO_KRB5_INIT_ETS". Makefile, 3 Mar 2009.
-
-Fixed copyright date announced in herald, ckuus5.c, 3 Mar 2009.
-
-Patch from Seth Theriault to avoid deprecation warning for utmp references
-in ckufio.c in Mac OS X 10.5 (later, this became a consolidated makefile
-target that works automatically for at least Mac OS X 10.3.9 through
-10.5.6). makefile, ckufio.c, 28 April 2009.
-
-zshcmd() (the function used by RUN and ! to run external commands) was not
-falling back as expected in Linux RHEL4/5 if SHELL was not defined in the
-environment. Also in all Unix versions, there was no indication if a RUN/!
-command failed (other than the return code) because the specified shell
-didn't exist or was not executable (e.g. the SHELL environment variable was
-misdefined). Now it prints the name of the offending shell and the reason
-it couldn't be executed (Not found, Permission denied, etc). ckufio.c,
-28 April 2009.
-
-There is no easy way to get the last field of string; for example, the
-extension from a filename, which might have any number of fields. In
-general we want to be able to get "word number n" counting from the right;
-\fword() lacks this ability. Now if you give it a negative word number,
-that says to count from the right; for example \fword(one two three four
-five, -2) returns "four". ckclib.c, ckuusr.c, 14 May 2009.
-
-Fixed a typo in the aix51+openssl (SSLLIBS should have been SSLLIB).
-From Jason Lehr. makefile, 27 May 2009.
-
-Updated the linux+openssl+zlib+shadow+pam target to chain to the new main
-Linux target. A bunch of other ones remain un-updated. makefile, 12 Jun 2009.
-
-Updates to the new Mac OS X 10.5 target from Seth Theriault (which is
-supposed to work on all Mac OS 10-point-anything) to avoid warnings
-that came up on on Mac OS 10.4.11/Intel. Once this one is proven we should
-be able to remove/consolidate lots of other ones. makefile, 12 Jun 2009.
-
-C-Kermit disables SSL with the message "?OpenSSL libraries do not match
-required version." if the version of OpenSSL that Kermit was built with is
-not exactly the same as the version that is loaded dynamically at runtime.
-This is actually the proper behavior, since APIs are not guaranteed not to
-change between OpenSSL versions prior to 1.0.0. Made the error message more
-informative. ck_ssl.c, 26 Aug 2009, and again 28 Aug 2009.
-
-AIX 6.1 is out, it is really just a new name for AIX 5.4. Added makefile
-targets, plus for the first I made AIX 4.2 and later figure out its version
-number in the makefile target so we don't have to keep adding new -DAIXnn
-sections to the code, and also get its hardware name (e.g. "powerpc") from
-uname at make time, rather than hardwiring "rs6000" as I did before.
-Consolidated all AIX 4.2 and later targets so now just "make aix" or "make
-aix+ssl" can be used. Except not the gcc ones as they have some quirks so
-I'd rather not disturb them. Tested this on AIX 5.3.
-makefile, 28 Aug 2009.
-
-From Kinjal Shah, a correction to the Linux makefile entry that allows it
-find the 64-bit curses or ncurses library. makefile, 29 Aug 2009.
-
-Renamed aix4[23]: to oldaix4[23]: in makefile to fix the warning messages
-I didn't notice before. I didn't want to remove them because they have
-some special things that might still be needed, if anybody still has these
-AIX versions. makefile, 29 Aug 2009.
-
-Built on RHEL 5.3 64-bit, regular and with OpenSSL 0.9.8e. 31 Aug 2009.
-
-Built on NetBSD 5.0.1/i386, regular and with OpenSSL 0.9.9-dev, 1 Sep 2009.
-
-Changed SSL message to mention LD_LIBRARY_PATH (Solaris), SHLIB_PATH (HP-UX),
-LIBPATH (AIX), or LD_LIBRARY_PATH (Linux). ck_ssl.c, 3 Sep 2009
-
-Noticed that "make linux+openssl" fails to include -lutil a link time, which
-it needs for openpty(). That's because this target is obsolete. I renamed
-it to be oldlinux+openssl and added linux+openssl as a synonym for
-linux+ssl. makefile, 3 Sep 2009.
-
-Tested linux+openssl+zlib+shadow+pam, it's OK. Also linux+krb5. Also
-linux+krb5+ssl. makefile, 3 Sep 2009.
-
-Tried building on Solaris 9 with OpenSSL 0.9.8k with
-solaris9g+openssl+shadow+pam+zlib, it failed like so:
-
- ck_ssl.c:2875: error: conflicting types for 'inet_aton'
- /usr/include/arpa/inet.h:52: previous declaration of 'inet_aton' was here
- make[2]: [ck_ssl.o] Error 1
- make[2]: Leaving directory hmt/sirius1/prv0/kd/fdc/solaris9ssl'
- make[1]: [solaris2xg+openssl+zlib+pam+shadow] Error 2
- make[1]: Leaving directory hmt/sirius1/prv0/kd/fdc/solaris9ssl'
- make: [solaris9g+openssl+shadow+pam+zlib] Error 2
-
-The problem was caused by including an inet_aton() function ck_ssl.c for
-the benefit of platforms that don't have one in their libraries. This is
-defeated by including NO_DCL_INET_ATON in KFLAGS. I added this, but then
-I thought it would be a good idea to automatically sense the OpenSSL
-version so we can automatically set OPENSSL_097 or OPENSSL_098 rather than
-bombing out, so I added code to do that too, and also to set the Solaris
-version number: 9, 10, or 11. The new entry is solaris9g+openssl.
-ckcdeb.h, makefile, 3 Sep 2009.
-
-Fixed a complaint in ckufio.c about implicit declaration of initgroups.
-ckufio.c, 4 Sep 2009.
-
-Built on Solaris 10 with gcc and Sun CC using new solaris{9,10,11} target
-that is like the new solaris{9,10,11}g one but without the gccisms.
-makefile, 4 Sep 2009.
-
-Changed solaris{9,10,11}g+ssl target to set only the SSL-specific things and
-then chain to the main solaris{9,10,11}g target. Tested OK on Solaris 9 and
-10. makefile, 4 Sep 2009.
-
-Created solaris{9,10,11}+ssl target that is exactly like the
-solaris{9,10,11}g+ssl except it chains to the solaris{9,10,11} target
-instead of the solaris{9,10,11}g one. That is, it builds an SSL version of
-C-Kermit using Sun CC rather than gcc. makefile, 4 Sep 2009.
-
-Tried building on HP-UX 10.20, bundled (non-ANSI) compiler ("make
-hpux1000"). This failed until I:
-
- . Moved a struct initialization out of setextern(), ckuus3.c.
- . Removed an ANSIism from the declaration of sigchld_handler() in ckutio.c
- . Added a cast to strcmp() in zvuser(), ckufio.c.
-
-Builds OK now. Built OK with "hpux1000o" (the ANSI compiler) too.
-And with "hpux1000gcc". Couldn't test "hpux1000o+openssl". 21 Sep 2009.
-
-The Sony Playstation 2 and 3 are 64-bit PowerPC platforms that can run Linux
-if it is installed as an "other OS" on its hard disk; and the Linux kernel
-since 2.6.21 supports the PS3 without any patching required. Pawel Rogocz
-reported that "make linuxppc" (one of the old targets that has not yet been
-integrated into the main "linux" target) compiles OK on 2.6.29-ydl61.3
-(Yellow Dog Linux release 6.2 'Pyxis'), but fails at link time because
-'openpty' isn't found, because -lutil was not included, because that part
-was added only to the main linux target. I asked him to try "make linux"
-and he sent back a transcript in which there were thousands of errors from
-the curses code ckuusx.c. Later I tried it myself and it built without a
-hitch. My theory is that between then and now, a missing piece of the
-ncurses library (/usr/include/ncursesw) was installed. 21 Sep 2009.
-
-HP-UX 9.05 on PA-RISC 9000/712 building with hpux0900 (bundled compiler):
- . ckutio.c compilation failed with PENDIN and FLUSHO not defined in
- pty_make_raw(). I dummied definitions for them to handle this situation
- on this or any other platform where it might crop up.
- ckutio.c, 24 Sep 2009.
- . Ditto for the PTY module, + IMAXBEL. ckupty.c, 24 Sep 2009.
- . References to endusershell() were fatal in the bundled compiler. Changed
- the hpux0900 target to define NODCLENDUSERSHELL, and put a special case
- in ckufio.c to not put a cast in front of the call if NODCLENDUSERSHELL
- is defined. Now it builds and links OK. makefile, ckufio.c, 24 Sep 2009.
-
-HP-UX 9.05 on PA-RISC 9000/712 building with hpux0900o (optimizing compiler):
- . Warnings in ckutio.c at line 14860 about arguments to select (pointers
- are not assignment-compatible). "man select" says arguments are ints.
- Defining INTSELECT fixes these warnings but results in fatal errors later
- around line 14881 and others in the area involving FD_SET. This was too
- involved so I put it back as it was. 24 Sep 2009.
-
-Built OK on Solaris 10 with Sun CC. A couple warnings about implicit
-function declarations for curses routines because apparently they aren't
-declared in curses.h. Tuff. 25 Sep 2009.
-
-Tried building on Solaris 10 with Sun CC and OpenSSL 0.9.8k, and this
-uncovered various loose ends in the solaris9+openssl target, which I fixed.
-makefile, 25 Sep 2005.
-
-Fixed four typos in printfs in ck_ssl.c, \% instead of just %. 25 Sep 2009.
-
-Squelched 20-some complaints about a character array being referred to
-directly instead of by a pointer, plus several other similar nits to get rid
-of all the compilation warnings on Solaris 10 with Sun C 5.8 Patch 121015-06
-2007/10/03. ckctel.c, ckctel.h, 25 Sep 2009.
-
-Built the result on the same Solaris 10 system with gcc 4.2.4 using the
-new solari10g+openssl target, working out a few kinks here too.
-makefile, 25 Sep 2009.
-
-Made consolidated Solaris 9/10/11 64-bit targets for gcc, solaris9g64,
-solaris10g64, solaris11g64, tested on Solaris 10 Sparc. makefile, 25 Sep 2009.
-
-Made consolidated Solaris 9/10/11 64-bit targets for Sun cc: solaris9_64,
-solaris10_64, solaris11_64. These simply set a couple flags and chain to
-the main solaris9 target. makefile, 25 Sep 2009.
-
-Removed a bunch of old superfluous Solaris 9 and 10 targets: oldsolaris9,
-oldsolaris9lfs, solaris9g64 solaris9g_64, oldsolaris10 old solaris10lfs,
-oldsolaris10+openssl, oldsolaris10g+openssl, solaris10_64, oldsolaris10g,
-solaris10g_64, solaris10g64. There are still plenty more to prune but it's
-a start. makefile, 25 Sep 2009.
-
-Added or fixed some missing prototypes in ckctel.h:
-fwdx_send_xauth_to_xserver(), fwdx_parse_displayname. 25 Sep 2009.
-
-Improved the instructions for building secure versions in the makefile,
-using this example:
-
- make solaris9+openssl "SSLINC=-I/opt/openssl-0.9.8k/include" \
- "SSLLIB=-L/opt/openssl-0.9.8k/lib"
-
-makefile, http://kermit.columbia.edu/security.html, 25 Sep 2009.
-
-Built on HP-UX 11.11, 26 Sep 2009:
- . make hpux1100 (ok)
- . make hpux1100gcc (ok)
- . make hpux1100o (gets a lot of warnings about sendpath and sendfile,
- because they are also declared in <sys/socket.h>, but builds OK)
- . make hpux1000gcc+openssl \
- SSLINC=-I/opt/openssl/include SSLLIB=-L/opt/openssl/lib
-
-Note: sendpath and sendfile are not Kermit symbols. The warnings are coming
-from socket.h: 'Redeclaration of "sendfile" with a different storage class
-specifier'. This is nothing new; see notes of 2-4 Jan 2005.
-
-From Peter Eichhorn:
- . Update to makefile to make current code build OK on HP-UX 8.00.
- . Changes to format of some hints to make them more copy-and-pastable.
-makefile, ckuu5.c, 28 Sep 2009.
-
-From Peter Eichhorn: Changes to HP-UX 7.0 target to increase the switch table
-stack size, which was overflowing. makefile, 30 Sep 2009
-
-HP-UX 6.5 (1989), "make hpux0650tcpc"... (8:19...) Needed to not include
-arpa/inet.h (which doesn't exist) and not use host address lists (add
--DNOHADDRLIST), which gets us past ckcnet.c, but in ckcftp.c we bomb out on
-FD_SETSIZE undefined. Somehow we worked around this in ckcnet.c. Patched
-in a definition in ckcftp.c, and also added -DINTSELECT to compiler flags.
-Compiles ok, bombs at link time on bcopy, bzero, FD_ZERO, FD_SET, FD_ISSET.
-Now it compiles and links OK but dumps core when started. Added
--DNOCKGETFQHOST, rebuilt from scratch (takes 35 minutes). It starts OK, but
-it dumps core when given a "telnet xxx" command, where xxx is a hostname.
-However, it works OK if an IP address is used: "telnet 123.45.6.78". It
-took all day to track this down, but now it's fixed (see the #ifdef HPUX6
-sections of ckcnet.c). So now (for the first time, I think) we have both
-telnet and ftp in HP-UX 6.x, if anyone cares. ckcnet.[ch], ckcftp.c,
-makefile, 2 Oct 2009.
-
-Changed default SET TERMINAL TYPE type for K95 from vt320 to vt220. This is
-because Unix OS's such as Solaris have dropped vt320 as a terminal type.
-settrmtyp(), ckuus7.c, 5 Oct 2009.
-
-I moved the PUTENV command code, which was inline, to a function, doputenv().
-ckuus[r7].c, ckuusr.h, 5 Oct 2009.
-
-Changed the UNIX version of SET TERMINAL TYPE to take a value and then do
-the equivalent of "export TERM=value" by calling doputenv(). This sets
-\$(TERM) correctly and passes its value along to inferior processes.
-However, to make this take effect within Kermit itself (for the fullscreen
-file transfer display and for the SCREEN command, Ctrl-L, etc) I also had to
-reinitialize the curses database, which is tricky because normally if you
-feed it an unknown terminal name, it just exits. ckuus7.c, 5 Oct 2009.
-
-Changed the little-known and little-used RESET command (which closes all
-open files) to also put command echoing back to normal in case it got
-messed up somehow (as in HP-UX 6.5, upon returning from PUSH).
-ckuusx.c, 5 Oct 2009.
-
-For Unix, increased string buffer sizes for wildcard expansion for all
-platforms that have BIGBUFOK defined from 500000 (0.5M) to 10000000 (10M)
-bytes, and for 64-bit builds to 2000000000 (2G) bytes. No point making
-it bigger than that because malloc's argument is a size_t, which is an int.
-ckufio.c, 5 Oct 2009.
-
-Built on Mac OS X 10.4.11, required one minor adjustment to the makefile
-(-DNODCLINITGROUPS). This was using the macosx10.5 target, which is
-supposed to be universal like the linux and netbsd targets, but not yet
-proven. Also built a 64-bit version (-mpowerpc64 -mcpu=G5 -mtune=G5
--arch ppc64); it compiles and links OK but won't start: "Bad CPU Type
-in executable". Fix later... makefile, 5 Oct 2009.
-
-Changes from Seth Theriault to suppress signed vs unsigned char warnings in
-Mac OS 10.5.8 from gcc4, and a new makefile target for Mac OS X (presumably
-10.3.9 or later) + Kerberos 5 and OpenSSL. ckutio.c, ckuath.c, ckctel.c,
-ckcnet.c, ckcftp.c, ck_crp.c, makefile, 6 Oct 2009.
-
- Later I had to back out of these, because although it made for a
- clean build, in the resulting executable SSL connections didn't work.
-
-Tue Oct 6 17:23:27 2009
-FTP address resolution is broken, but ftp_hookup() hasn't changed.
-So... (see the #ifdef HPUX6 sections of ckcnet.c) (I did, and I rolled
-back some of the changes from the other day, but it made no difference.)
-Putting back the ckcftp.c from a few weeks ago makes no difference.
-Putting back the ckcnet.c from a few weeks ago makes no difference.
-
-Added patches from Seth Theriault so macosx10.5+krb5+openssl would build
-on Mac OS X 10.3.9. makefile, ckcftp.c, 7 Oct 2009.
-
-Built today's code on Linux RHEL4, NetBSD 5.0.1, Solaris 9, and Mac OS X
-10.4.11, both with and without SSL. The NetBSD system has OpenSSL 0.9.9-dev.
-7 Oct 2009.
-
-In Mac OS X 10.6, the following symbols are unresolved at link time:
-_des_key_sched, _des_new_random_key, _des_ecb_encrypt,
-_des_init_random_number_generator, _des_fixup_key_parity. This is
-with OpenSSL 0.9.8k. But it doesn't happen on other platforms that
-have 0.9.8k.
-
-Added SET SESSION-LOG NULL-TERMINATED-TEXT. This is for the benefit of a
-speech synthesizer that will speak a line of text only after receiving a
-NUL character. A more general solution would be to define a filter or
-whatever, but who has time. ckuus[23x].c, 7 Oct 2009.
-
-Consolidated Mac OS X targets, and removed experimental 64-bit ones, because
-they never could work in 10.5 and earlier because 64-bit libs are missing,
-and 10.6 and later are 64-bit automatically. makefile, 8 Oct 2009.
-
-Built on Mac OS X 10.6.1. It came out automatically as a 64-bit build
-because __LP64__ is defined somewhere that I can't find. But this explains
-why the 0.9.8k on 10.6 comes up with missing symbols when the 0.9.8k lib
-10.5 (or on Solaris or on Linux) does not: it's a different library: "Mach-O
-64-bit dynamically linked shared library x86_64", rather than "Mach-O
-dynamically linked shared library ppc". Probably the 64-bit version has
-some things #ifdef'd out. Added -m32 to the CFLAGS and LNKFLAGS for the
-macosx+krb5+openssl targets, and it built OK one time. But then the errors
-came back. makefile, 8 Oct 2009.
-
-Updated C-Kermit installation for Mac OS X in ckuwr.html on the website.
-8 Oct 2009.
-
-Tried some things to get around the problem with OpenSSL in Mac OS X 10.6,
-to no avail. Asked Jeff. He said, "MacOS X no longer includes DES anywhere
-on the system. Not for SSL, not for Kerberos, not for anything. This will
-increasingly become the situation on new operating systems. Windows 7 and
-2008 R2 will also ship with no DES." Sure enough, the Mac OS X Server
-Upgrading and Migrating document for 10.6 says, "Mac OS X Server v10.6 does
-not support single DES encryption. It supports AES 128 and 256 encryption
-types. However, during a migration or upgrade from v10.4 to v10.6, servers
-that were Kerberized by the v10.5 Open Directory server will not use the AES
-128 or 256 encryption types. To use the AES 128 or 256 encryption types you
-must re-Kerberize all servers." 12 Oct 2009.
-
-DES and 3DES encryption can be excluding removing the -DCK_DES flag. I
-removed this one and -DLIBDES (and -m32) and this makes a working 64-bit
-version. Then I added code to the macosx+krb5+openssl target to use these
-flags if the Mac OS X version was 10.5 or less and leave them out for 10.6
-or later. Tested on 10.4.11 and 10.6.1. A better way to do it might have
-been "nm -gj libssl.dylib | grep des_", but that gives the same results on
-10.4 and 10.6. Also, 10.6 still has /usr/include/ssl/des.h.
-makefile, 13 Oct 2009.
-
-Next issue:
- In file included from ckutio.c:15674:
- /usr/lib/gcc/i386-redhat-linux/3.4.6/include/varargs.h:4:2: #error "GCC no
- longer implements <varargs.h>."
- /usr/lib/gcc/i386-redhat-linux/3.4.6/include/varargs.h:5:2: #error "Revise
- your code to use <stdarg.h>."
-
-The problem occurs when trying to force a non-ANSIC build with GCC.
-Changing the source file to include <stdarg.h> instead of <varargs.h>
-doesn't help because evidently <stdarg.h> requires an ANSI C compiler.
-Nothing can be done about this. 13 Oct 2009.
-
-Next issue: Can't compile ckcftp.c with -DNOCSETS or -DNOSPL; some
-#ifdef/#endif doesn't match up. Sigh, this is the hardest kind of thing to
-debug. There's 17,622 lines of code in this module and no tool that I know
-of.... Wait, I wrote one. But it shows all the #if/#ifdef/#ifndef's and
-#endifs matching up just fine. Backing off to ckcftp.c of a few days ago
-(before char / unsigned char casts were added), I see that it builds OK, so
-I backed off to that one, but put back the special case #ifdef for MACOSX103
-declaring CONST gss_OID_desc, and it builds OK (the other stuff was purely
-cosmetic, when will I learn?). ckcftp.c, 13 Oct 2009.
-
-Protected cvtstring() and related functions with #ifdef NOCSETS..#endif,
-and ditto for the character-set conversion code in dorename().
-ckuus6.c, 13 Oct 2009.
-
-Fixed an #endif /* TNCODE */ that was a line too low in ttptycmd(),
-causing -DNONET builds to fail. ckutio.c, 13 Oct 2009.
-
-There was a reference to doputenv() that wasn't guarded by #ifndef NOPUTENV,
-fixed in ckuus7.c, 13 Oct 2009.
-
-Moved doputenv() and settermtyp() out of an #ifdef NOLOCAL section because
-these are useful even when not making connections. ckuus7.c, 13 Oct 2009.
-
-Moved havelfs declaration outside of #ifdef NOXFER because it was also used
-for other things. ckcmai.c, 13 Oct 2009.
-
-COPY /PRESERVE depended on code from the Kermit protocol module, which
-is omitted in -DNOXFER builds. Disabled COPY /PRESERVE in -DNOXFER
-builds. ckuus6.c, 14 Oct 2009.
-
-SHOW PROTOCOL code for external protocols had to be #ifdef'd out for
--DNOPUSH builds. ckuus4.c, 14 Oct 2009.
-
-There was some confusion between "No XYZMODEM" and "No external protocols";
-cleared up in ckuus3.c, 14 Oct 2009.
-
-After all that, 86 different combinations of feature selections built OK on
-Linux. And the Kerberized version (K5) works OK on Linux for Telnet and FTP.
-14 Oct 2009.
-
-Changed version number to 9.0. All modules, 16 Oct 2009.
-
-Need to make LOG SESSION log to a tty. Right now "log session
-/dev/ttyKeySerial1" says "Write permission denied" even though the device is
-crw-rw-rw-. This happens in zchko(), which is called by cmofi(). The
-problem is that /dev/ is not writeable. I added a Unix-only clause that
-attempts to open the file for write access using open(), in order to get a
-file descriptor, which then can be passed to isatty() to check if it's a
-tty, and if so, to allow access. And then close it. I tested this on Mac
-OS X as follows:
-
- log session /dev/ttyKeySerial1
- telnet somehost
-
-The Mac's serial port was connected to the serial port of another computer
-where Kermit displayed the incoming characters in CONNECT mode. Glitches:
-
- 1. The port has to be set up as desired in advance, outside of Kermit.
- 2. log session /dev/ttyKeySerial1 will hang if any required modem signals
- are not present when the port is opened.
- 3. Bypasses lockfile mechanism - so we do this only if -DNOUUCP.
-
-For (2), I tried setting O_NDELAY / O_NONBLOCK, and this allowed zchko() to
-continue, but then it freezes in the subsequent fopen(). So I changed
-zopeno() to also check if the device is a serial port, and if so, to open()
-it with O_NDELAY / O_NONBLOCK, and then convert the file descriptor into a
-file pointer with fdopen().
-
-Now for the speaking device that needs lines to be terminated by NUL...
-
- set session-log binary <-- need to put these in SHOW LOG
- set session-log null-padded (and in HELP SET LOG)
- set line /dev/ttyKeySerial1
-
-This part works.
-
-This feature is enabled only for -DNOUUCP builds because serial ports aren't
-like other Unix files; we would have to create a lockfile, but we can't do
-that... actually, ttlock() takes a name as an argument, but ttunlck() does
-not, so there would be no way to remove the lock. Anyway, there is only one
-API for configuring the port (speed, flow control, etc) and it only works
-with the SET LINE device, not any random file. To fix this would require
-massive redesign and changes. ckuus[23].c, ckufio.c, 19-20 Oct 2009.
-
-I made -DNOUUCP the default for Mac OS X, since everybody winds up building
-it that way anyhow. To undo this, do "make macosx KFLAGS=-UNOUUCP".
-makefile, 21 Oct 2009.
-
-Changed SET SESSION-LOG TEXT to strip out ANSI escape sequences;
-previously there wasn't that much difference between TEXT and BINARY logs.
-It's still not perfect; for example it doesn't delete characters that the
-user erased. (Made sure this still builds with -DNOESCSEQ.)
-ckucns.c, 22 Oct 2009.
-
-Changed SHOW LOG to show the SET SESSION-LOG settings, as well as
-SET DEBUG, which was not shown before. ckuus5.c, 22 Oct 2009.
-
-If a series of PUTENV commands is given, each new one undoes the previous
-one, so only the last definition is seen by the new fork (or by Kermit
-itself). Turns out you can't feed automatic variables to putenv(); they
-have to be static, so to allow for multiple PUTENV commands Kermit has to
-maintain an array of static strings. ckuus7.c, 6 Nov 2009.
-
-From Seth Theriault, a better way for the makefile to determine the
-Mac OS X version number; there's a program for this, sw_ver. makefile,
-6 Nov 2009.
-
-Peter Eichhorn reported that file-transfer failure hints were not coming
-out since Dev.27. The only change I made since then was to skip them if
-the file-transfer protocol was not Kermit. I was using the wrong variable
-in the tests, 'proto' instead of 'protocol'. ckuus5.c, 6 Nov 2009.
-
-Changed Mac OS X targets to correctly extract the Mac OS major version
-from uname -r in order to choose correctly between utmp and utmpx; this
-wasn't working in 10.6.1. makefile, 6 Nov 2009.
-
-Fix from Seth T. for an oversight in the previous edit. Also add
-MACOSX103 to "show features" display. makefile, ckuus5.c, 10 Nov 2009.
-
-Added REJECT as a synonym for DISCARD in SET FILE COLLISION; it's more
-intuitive and more accurate. ckuus[27].c, 15 Nov 2009.
-
-\fsplit() and \fword() always break on 8-bit characters unless you explicitly
-put every single 8-bit value into the include set, e.g. (for a TSV file):
-
- undef include
- for \%i 128 255 1 {
- if == \%i 9 continue
- .include := \m(include)\fchar(\%i)
- }
- .\%n := \fsplit(\m(line),&a,\9,\m(include))
-
-I changed cksplit() to treat all 8-bit bytes 128-255 as non-break characters
-by default. It might have made more sense to do this for 160-255 (since
-128-159 are traditionally C1 control characters) but thanks to Microsoft
-tradition is out the window. To treat one or more 8-bit characters as break
-characters, put them in the break set. This might break some scripts, but I
-doubt it because this flaw was so awful that if anyone had come up against
-they would have let me know. ckclib.c, 16 Nov 2009.
-
-Changed the netbsd target to set -funsigned-char, since cc on NetBSD is
-actually gcc. makefile, 16 Nov 2009.
-
-Changed macosx targets to get the CPU type from the HOSTTYPE environment
-variable. Also added getenv("HOSTTYPE") as a last-resort method to set the
-\v(cpu) variable at runtime (maybe it should be the first resort?)...
-ckuus4.c, makefile, 16 Nov 2009.
-
-Made sure the solaris9_64 and solaris10 targets still work. 16 Nov 2009.
-
-Made sure the current source package builds OK on HP-UX 10.20... Got a lot
-of "warning 6062: Optdriver: Exceeding compiler resource limits in xxx; some
-optimizations skipped. Use +Onolimit if override desired" but it builds OK.
-Tested long file transfer; works OK. 17 Nov 2009.
-
-Built on FreeBSD 7.2 with and without OpenSSL, all OK. 17 Nov 2009.
-
-Built on NetBSD 5.0.1 with and without OpenSSL, all OK, but netbsd+krb5
-fails with "can't find -lgssapi_krb5"; worked around this with
-"K5LIB=-L/usr/local/kerblib" (where the lib actually is on this host) but
-then it failed with "ckcftp.c:13868: error: 'gss_nt_service_name' undeclared".
-17 Nov 2009.
-
-I found a VMS 6.2 system... Takes a loooong time to build there. In
-ckuusy.c, DEC C didn't like the prototypes and declarations of dorlgarg()
-and dotnarg() as static so I made them not static. But that didn't help,
-now it fails at the very end, saying the final #ifdef is an invalid
-statement. It looks like an #ifdef mismatch that affects only VMS. I ran
-my #ifdef matcher, it turned up nothing. I substituted a copy of ckuusy.c
-from 2007, it comes up with the same errors. Then I substituted the copy
-from 8.0.211 from 2004, and this one compiled OK and, miraculously, the
-whole mess even linked OK and runs OK. The Alpha binary is 2.84MB. Now I
-have 4500 lines of code to compare.... I went through the two files line by
-line and I can't see a single thing wrong. I gave up and tried building the
-TCP/IP version. It builds fine except for ckuusy.c, with the utterly
-useless error message:
-
- #endif /* NOCMDL */
- ...................^
- %CC-E-BADSTMT, Invalid statement.
-
-Indicating the last line in the file. Just for the heck of it, I put
-another line after that one:
-
- /* This is a test */
-
-and got:
-
- /* This is a test */
- ....................^
- %CC-E-BADSTMT, Invalid statement.
-
-So it is not objecting to anything in the file. Trying the old LISP trick,
-I put an extraneous closing bracket after that. Success! Honestly, I don't
-see anything wrong with file. It's DEC C V5.3-006. I suspect a C bug.
-I'll leave it like this for now until I get access to some other VMS
-versions. Another clue is that when building the network version I get a
-horrible warning I never saw before from a module that hasn't been touched
-in a very long time (ckvrtl.c). Also, in the network version, I note that
-the FTP code is not compiled in. We have to try this again with some
-command-line switches, but it'll do for now. ckuusy.c, 18 Nov 2009.
-
----C-Kermit 9.0 Alpha.01---
-
-From Steven Schweda (SMS), the real solution for the VMS closing brace
-problem, it wasn't a DECC bug, it was a me bug. ckuusy.c, 20 Nov 2009.
-
-Rediscovered the new VMS build options: f for Long Files, i for Internal
-FTP. "make mnf" doesn't work on VMS 6.2, it looks like the VMS definition
-for CK_OFF_T got lost. Same thing with "make mfi". Come back to this later.
-
-From Gerry Belanger, a fix to INPUT /COUNT:n. ckuus4.c, 26 Nov 2009.
-
-Added \fsqueeze(s), returns string s with leading and trailing whitespace
-removed, Tabs converted to Spaces, and multiple spaces converted to single
-spaces. For now, ASCII only, no options. ckuusr.h, ckuus[24].c, 27 Nov 2009.
-
-I wrote a Kermit script to read a big file of addresses on Solaris 9,
-\fsqueeze()ing each line. After about 14000 lines, there was a malloc
-failure in getnct() (the command-file reader). There's nothing wrong with
-\fsqueeze(), the failure is on a deeper level, because the same thing
-happens if I use \fupper() (which is structurally identical to \fsqueeze())
-in the same script. The problem is not in getnct() either, because every
-malloc() is freed (I checked). On the other hand, the same script (with
-\fupper() instead of \fsqueeze() completes OK in C-Kermit 8.0.201. If I
-remove the function call (\fsqueeze() or \fupper()) from the script, it also
-runs OK in 9.0. This seems to point the finger at fnevel(), which contains
-countless malloc's and free's. But comparing fneval() between 8.0.211 and
-9.0, I don't see any difference that would explain this behavior -- nothing
-at all that involves malloc(), makstr(), or free(). Nor any pertinent
-change in the caller (zzstring) of fneval(). 27 Nov 3009.
-
-Another problem is that when this happens, the error is not caught (e.g. by
-the IF FAIL statement after the command that contains the function call);
-instead, C-Kermit returns immediately to its prompt. 27 Nov 2009.
-
-It could simply be that some of the buffers we allocate are much bigger now.
-But again, I don't see much difference between 8.0.211 and 9.0; we were
-already allocating 32K command-related buffers (malloc() takes a size_t, and
-size_t is an int almost everywhere). I built the same source on NetBSD and
-ran the same script (with \fqueeze()), and it worked fine. Let's worry
-about this later, if it comes up. 27 Nov 2009.
-
-Built OK on Silicon Graphics IRIX 6.5 R10000; regular build OK, SSL and
-Kerberos builds failed. 30 Nov 3009.
-
-Tried to build on Digital Unix 4.0F but it blew up in ckutio.c, apparently
-not recognizing any of the terminal struct symbols from termios.h. Tried
-again with gcc, same thing. Tried explicitly #including <sys/termios.h>
-within #ifdef TRU64, same thing. What could have changed? 30 Nov 2009.
-
-Built OK on Linux RHEL5.4/Itanium-2, make linux. The secure build
-required "FLAGS=-DNO_KRB5_INIT_ETS" and built OK. 30 Nov 2009.
-
-Built OK on Digital Unix 4.0F using "make osf" instead of "make tru64-40f".
-I don't know why the specific target doesn't work, but it's not worth
-chasing down. 2 Dec 2009.
-
-Built OK on MirBSD 10, despite a lot of gratuitous compiler warnings. Built
-OK on MirBSD 10, OpenBSD 4.5, and Fedora 10. 3 Dec 2009.
-
-(Various other successful Unix builds in these weeks...)
-
-Built on VMS 7.2 and 8.3 with and without TCP/IP, no problems. 11 Jan 2010.
-
-Built on VMS 8.3 with "make fi" to include the FTP client and long-file
-support (mid Jan 2010).
-
-Built on VMS 8.3 with UXC 5.6 and HP SSL 1.3, which is OpenSSL 0.9.7e.
-It compiled and linked OK but when I tried to make an FTP SSL connection
-it crashed in SSL$LIBSSL_SHR, which is called from ssl_auth(), after having
-had TLS accepted as an authentication type, but before actually
-authenticating. In Unix:
-
- 19. ftp open ftp.somecompany.com /user:pge.com/test_quota /password:xxxxxx
-Connected to ftp.somecompany.com.
-220-Somecompany FTP v6.0 for WinSock ready...
-220 Welcome to the online storage FTP server. Please check the main web
-site for system announcements and AUP. (O)
----> AUTH TLS
-234 AUTH command OK. Initializing SSL connection.
-TLS accepted as authentication type
-SSL DEBUG ACTIVE
-=>START SSL/TLS connect on COMMAND
-
-In VMS:
-
- 19. ftp open ftp.somecompany.com /user:pge.com/test_quota /password:xxxxxx
-Connected to ftp.somecompany.com.
-220 Somecompany FTP v6.0 for WinSock ready...
----> AUTH TLS
-234 AUTH command OK. Initializing SSL connection.
-TLS accepted as authentication type
-SSL DEBUG ACTIVE
-%SYSTEM-F-ACCVIO, access violation, reason mask=04, virtual
-address=FFFFFFFF8001A120, PC=000000000068B118, PS=0000001B
-
-Note: The Unix version received the second 220 response, the VMS version did
-not. That's odd, it's the same code... 25 Jan 2010.
-
-Added some essential details to the HELP FSEEK text. ckuus2.c, 25 Jan 2010.
-
-Discovered that the result returned by \fsearch() is totally unreliable.
-This is probably too hard to fix.
-
-FSEEK did not pay attention to SET CASE, searches were always case sensitive.
-Fixed in ckuus7.c, 26 Jan 2010.
-
-FSEEK failed to find anything if the search pattern was matched in the first
-line of the file. Fixed in ckuus7.c, 26 Jan 2010.
-
-\fword() and \fsplit().... Another change, but not backwards-incompatible.
-One may now put the word ALL (just like that, all uppercase) as the include
-set (4th argument) to indicate that there will be no break characters other
-than those explicitly given in the break set, e.g. \fsplit(\m(xx),&a,:,ALL)
-breaks a line only on a colon (:), nothing else. The original rules for
-cksplit() were more than a little counterintuitive: the default break set is
-all non alphanums, and the default include set is all alphanums, so if you
-wanted to parse (say) a CSV file, breaking only on comma, you had to think
-of all the characters you wanted to keep. This way you just say ALL.
-ckclib.c, 26 Jan 2010.
-
-Speaking of CSV files... How can you put comma as a function argument when
-comma is the function-argument separator? Use one of these forms:
-
- \fsplit(\m(xx),&a,",",ALL)
- \fsplit(\m(xx),&a,{,},ALL)
- \fsplit(\m(xx),&a,\44,ALL)
- \fsplit(\m(xx),&a,\fchar(44),ALL)
-
-From John Dunlap, U. of Washington Applied Physics Lab: 'When "stty -a <
-/dev/ttyS0 | grep crtscts" shows "crtscts" (not "-crtscts") and when using a
-three wire serial interface and when asking kermit to not use flow control
-(set flow none) then "ckutio.c1" (see attachments) fails while "ckutio.c"
-works. The result of "diff -u ckutio.c1 ckutio.c" is attached as "diffs"'.
-ckutio.c, 26 Jan 2010.
-
-Changed the year from 2009 to 2010 in the modules I worked on today and in
-the heralds, etc. ckckmai.c, ckuus5.c, ckutio.c, ckclib.c, ckuus7.c,
-26 Jan 2010.
-
-Built on Linux Fedora Core 3, regular and with OpenSSL 0.9.7a. Built on
-Ubuntu 9.4 OK, but SSL and Kerberos builds failed due to not finding libs
-and/or header files. I'm sure this could be fixed... 27 Jan 2010.
-
-Added SSL, KRB4, and KRB5 to the startup herald for versions that were
-built with SSL, Kerberos 4, or Kerberos 5. Built OK on Fedora 3 with
-linux+krb5+ssl and new banner shows correctly. ckuus5.c, 27 Jan 2010.
-
-Set NO_KRB5_INIT_ETS by default in ckuath.h since krb5_init_ets() is a no-op
-in Kerberos 1.4.x and later and in some installations it can't be found,
-which clobbers the build. ckuath.h, 27 Jan 2010.
-
-Adapted to MINIX 3 1.5, the first version that has virtual memory according
-to Andy T, who should know. On earlier versions (e.g. MINIX 3 1.2) any
-attempt to build C-Kermit causes the compiler to crash. Now the compiler
-doesn't crash but it spews out countless warnings about old-fashioned
-function declarations that I don't get anywhere else. The real problems
-came in ckutio.c where numerous symbols were undefined at compile time and
-the POSIX function tcgetpgrp() was not found at link time, even though there
-is a prototype for it in the MINIX header files, and there is no alternative
-(since POSIX doesn't let us use ioctl()). Also note that there is some
-confusion over the compile-time symbols MINIX, MINIX2, MINIX3, and MINIX315.
-You would expect MINIX to mean "any version of MINIX" but in some parts of
-ckutio.c it means MINIX 1.0. I sincerely doubt that C-Kermit 9.0 can be
-built on any version of Minix before 3.1.5 so I removed the confusion and
-made MINIX mean "any Minix". It builds on 3.1.5 OK now, except for the FTP
-client. This can probably be fixed but... Modules changed: ckcdeb.h,
-ckuver.h, ckcmai.c, ckuus5.c, ckutio.c, 1 Feb 2010.
-
-Later.. Andy says MINIX does not support job control, so no program is ever
-in the background. That settles that! 1 Feb 2010.
-
-Built OK on Minix, Linux, Mac OS X, Solaris 9, NetBSD 5.0.1... 1 Feb 2010.
-
----C-Kermit 9.0 Alpha.02---
-
-From Christian Corti at Uni-Stuttgart.de: fixes to allow building on SunOS
-4.1, which once was my main development platform but which is long-gone from
-here. ckupty.c, ckutio.c, 9 Feb 2010. (He says it is also necessary to
-comment out the "struct winsize" and "struct ttysize" in sys/ioctl.h;
-otherwise there will be a conflict with sys/ttycom.h (included by termios.h)
-which also declares these structs. But you need both includes.')
-
-From John Dunlap, a fix for Kermit protocol fixed packet-timeout interval
-going to a unexpected value (missing else clause in two places).
-ckcfn2.c, 9 Feb 2010.
-
-Added an aixg target to build on AIX with gcc when gcc is not installed as
-cc, and also added CC=$(CC) CC2=$(CC) clauses to the aix and aix+ssl
-targets. Wow, AIX really loses bigtime when receiving files through its ssh
-server. Streaming can't be used, sliding windows recover from errors but
-there are tons of them using the default 4K packets; 500 works much better.
-Built with IBM cc and gcc, and also tested (successfully) the new aix+ibmssl
-target, in which the OpenSSL headers and libs are in a standard place.
-makefile, 9 Feb 2010.
-
-In ckupty.h, make the #include <sys/ioctl.h> be #ifndef SUNOS41.
-From Christian Corti. 10 Feb 2010.
-
-Built on VMS E8.4. 12 Feb 2010.
-
-Tried to build on a real VAX-11/785 but the machine seems to be seriously
-wedged. 12-15 Feb 2010.
-
-Added note to CKVKER.COM to the effect the the 'f' option has no effect
-on VAX architecture. 15 Feb 2010.
-
-Moved the #include "ckvrtl.h" in the FTP module to below the include for
-utime.h, because building the VMS version with the 'i' option (meaning
-"include internal ftp client") results in "struct utimbuf tp" erroring out
-because struct utimbuf is not defined yet (at least in some version of VMS
-with some version of C). From Rob Brown, ckcftp.c, 20 Feb 2010.
-
-From Martin Vorlaender: new code in VMS C-Kermit build procedure to detect
-OpenSSL version automatically. ckvker.com, 22 Feb 2010.
-
-Added code to INPUT command to strip ANSI escape sequences. It's activated
-by SET SESSION-LOG TEXT. ckuusr.h: added prototype for chkaes();
-ckucon.c, ckucns.c: made inesc[] and oldesc[] global instead of static;
-ckuus4.c: doinput() code for skipping escape sequences. 1 Mar 2010.
-
-Peter Eichhorn complained that if you make an ssh connection with Kermit,
-then log out from the ssh host, and then use a "connect" command to
-make a new connection to the same host (which you can do with Telnet),
-Kermit says (e.g.):
-
- DNS Lookup... Can't get address for ssh -e none somehostname
- Sorry, can't open ssh -e none somehostname: Error 0
-
-I added code to detect and handle this case and it seems to work OK, even
-though it's kind of a hack. ckuusr.[ch], ckuus7.c, 1 Mar 2010.
-
-There has never been a clean way to put debugging messages (ECHO commands)
-in a script which are executed only if debugging is desired and ignored
-otherwise. You'd have to set a random variable and test it, or define a
-macro or whatever. To make this more straightforward, I added SET DEBUG
-MESSAGE ON/OFF/STDERR, and added a new MESSAGE (syn: MSG) command for printing
-debugging messages to stdout if SET DEBUG MESSAGE is ON or to stderr if SET
-DEBUG MESSAGE is STDERR. ckcmai.c, ckuus[r23].c, 12 Mar 2010.
-
-Also for debugging and error messages, I added \v(lastcommmand) so that
-the command that failed can be included in an IF FAIL or DEBUG error message.
-This works even for commands that have syntax errors.
-ckuusr.h, ckuus5.c, ckucmd.c, 12 Mar 2010.
-
-From SMS for VMS: 'Added/documented P3 options INTSELECT, OLDFIB, OLDIP.
-Disabled (commented out) automatic definition of NOSETTIME for VMS before
-V7.2 (vms_ver .lts. "VMS_V72").' ckcdeb.h, ckcftp.c, ckcnet.c, ckuus[2567].c,
-ckvfio.c, ckvker.com, ckvrtl.[ch], 15 Mar 2010.
-
-Exposed inesc[] and oldesc[] for VMS, so new INPUT command escape-sequence
-stripping can work (really, chkaes() and related global variables should be
-moved out of ck[uvd]con.c/ckucns.c and into a common module; do that later).
-ckuusr.h, ckvcon.c, 15 Mar 2010.
-
-Built OK on Solaris9, Mac OS X 10.4.11, RHEL4 (32-bit), RHEL5 (64-bit),
-AIX 5.3, SCO OpenServr 6.0.0... 15 Mar 2010.
-
-Not so good on VMS, turns out I made a typo in one of the VMS updates
-(#ifndef OLDIP instead of #ifdef...). ckcnet.c, 16 Mar 2010.
-
-More from SMS for VMS, 16 Mar 2010:
- . Set MAXPATH correctly for VMS, ckcdeb.h.
- . NAM -> NAML, QIO replaces system( "SET PROTECTION"), bugfixes in
- cvtdir() and nzltor(), ... (See comments): ckvfio.c, new ckvrms.h.
- (The RMS code in ckvfio.c was almost totally rewritten)
- . Moved "NAMX$*" (and related) macros to ckvrms.h, and renamed to
- "NAMX_*" (and similar "$" -> "_"), moved "FIB_*" macros from ckvrtl.c.
-
-These changes are mainly to accommodate the ODS5 file system, which has
-longer and mixed-case filenames, and also to execute certain commands
-(e.g. for setting file protection, deleting directories) directly instead
-of using a system() command.
-
-Built OK on VMS 8.3 (with and without network support). 16 Mar 2010.
-
-Failed to build on VMS 6.2. 16 Mar 2010.
-
-FreeBSD 8.0 <libutil.h> has a hexdump() prototype that conflicts with the
-hexdump macro defined in ckcdeb.h. Since the same thing is likely to happen
-elsewhere, I changed the Kermit macro to ckhexdump as well all references to
-it: ckcdeb.h, ckcftp.c, ckcnet.c, ckctel.c, ckuath.c, ckutio.c, 16 Mar 2010.
-
-Built OK on Digital Unix Tru-64 4.0E using "make osf", 16 Mar 2010.
-
-Tried again to build Digital Unix Tru64 4.0E using "make tru64-40e", but
-something prevents it from picking up the termios symbols and it blows up in
-ckutio.c, whereas this used to work in earlier C-Kermit versions. This is
-the only Tru64 system I still have access to, so I can't tell if it's a
-local peculiarity or what. Note that POSIX is not defined for this build.
-But if I define it, I get into trouble with "struct timeval". Tried again
-with "KFLAGS=-DPOSIX -DNOTIMEVAL" but that doesn't help. Tried "make
-dec-osf" and that worked OK but oddly enough it makes a Kermit with less
-features than "make osf". 16 Mar 2010.
-
-To go with MESSAGE and SET DEBUG MESSAGE, I added IF DEBUG, which is true
-if SET DEBUG MESSAGE is not OFF and false otherwise. ckuusr.h, ckuus6.c,
-16 Mar 2010.
-
-From SMS: Corrections to my merging of SMS's changes, ckcftp.c, ckvrtl.h.
-Builds OK on VMS 6.2 now. Also did an SSL build on VMS 8.3 with OpenSSL
-m0.9.7e and "OPENSSL_DISABLE_OLD_DES_SUPPORT" was included in P3
-automatically by Martin V's addition to ckvker.com. 17 Mar 2010.
-
-From SMS: #include <types.h> earlier for VMS in ckcdeb.h to pick up off_t
-before it is referenced. This allows C-Kermit to compile on VMS/Alpha 6.2
-but linking fails on fseeko() and ftello() (and yet, a functional executable
-is created, and FSEEK works right). Builds the same way with no problems at
-all on VMS 8.3 / Alpha. In this case we get the full 64-bit arithmetic...
-Well, 62 bits:
-
- ATLAS::C-Kermit>( ^ 2 63)
- 9223372036854775000.0
- ATLAS::C-Kermit>( ^ 2 62)
- 4611686018427387904
-
-whereas on VMS 6.2 we get integers only up to (^ 2 30). 17 Mar 2010.
-
-Changed the VMS build procedure to enable large file support automatically
-for non-VAX and VMS 7.3 or greater. No reason not to include this feature.
-Changed the sense of the F option to DISABLE large file support in the
-unlikely case that C-Kermit is being built on a suitable platform but the
-C library is older than VMS73_ACRTL-V0200, in which case fseeko() and
-ftello() will come up missing at link time. ckvker.com, 18 Mar 2010.
-
-Changed VMS build procedure to include the FTP client in any network build
-by default. Changed the sense of the I option to exclude the FTP client,
-in case anybody would want to do that. ckvker.com, 18 Mar 2010.
-
-From SMS: updated dependencies in CKVKER.COM, fix the "don't reinclude me"
-clause in CKVRTL.H. 19 Mar 2010.
-
-Built OK on VMS 6.2 and 8.3 with and without networking. Large file support
-included automatically in VMS 8.3 FTP client included automatically in both
-network builds. 19 Mar 2010.
-
-Changed hexdump() to ckhexdump() in ck_crp.c, which I missed before.
-19 Mar 2010.
-
----C-Kermit 9.0 Alpha.03---
-
-In HP-UX with the bundled-non ANSI compiler, we get warnings about functions
-such as endusershell(), which are declared void in the header files. But in
-non-ANSI builds we defind VOID to be int rather than void, so our prototypes
-are wrong. I checked that HP-UX 9, 10, and 11 all have void datatype and
-changed the definition of VOID to void in those cases. ckcdeb.h, 29 Mar 2010.
-
-Fixed a typo in a debug() statement in cksplit() that was causing some
-warnings. ckclib.c, 29 Mar 2010.
-
-Ditto in tls_load_certs(). ck_ssl.c, 29 Mar 2010.
-
-"make hpux1000o+ssl" files with:
-/usr/ccs/bin/ld: Unsatisfied symbols:
- __umoddi3 (code)
- __udivdi3 (code)
- __eprintf (code)
-
-It appears that OpenSSL (0.9.7c in this case) requires -lgcc.
-And indeed hpux1000gcc+ssl builds fine. 29 Mar 2010.
-
-There are various warnings in the SSL code in ckutio.c, ckcftp.c, and
-ckcnet.c about pointers not being assignment compatible, but I have learned
-from experience not to try to fix these (see notes from 6 Oct 2009).
-29 Mar 2010.
-
-connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)): In FTP,
-this doesn't work on RHEL5 / Mac OX X 6.1/2 64-bit. But the connect() in
-Telnet works. On Mac OS X 6.2 I tried changing the socket() call to be like
-the one in ckcnet.c for Telnet, but it made no difference. On a RHEL5.4
-system on i386, FTP works fine, so it's not the Red Hat version. On Digital
-Unix 4.0E 64-bit, same thing:
-
- 11:23:10.722 ftp_hookup[kermit.columbia.edu]=21
- 11:23:10.722 ftp hookup A[kermit.columbia.edu]
- 11:23:10.722 ftp hookup C[kermit.columbia.edu]
- 11:23:10.722 ftp hookup socket=4
- 11:23:10.722 ftp hookup HADDRLIST
- 11:23:10.723 ftp hookup connect failed=13
- 11:23:10.723 ftp hookup bad
-
-13 = Permission denied:
-
- [EACCESS] Search permission is denied for a component of the path prefix;
- or write access to the named socket is denied.
-
-On Gentoo Linux, also on Alpha, the errno is 51: Network is unreachable.
-Clearly some data type in the sockets structs is out of whack.
-
-The third connect() argument is "address length". The address is a
-struct sockaddr. About the third argument, RHEL5 "man connect" says:
-
- The third argument of connect() is in reality an int (and this is what
- 4.x BSD and libc4 and libc5 have). Some POSIX confusion resulted in
- the present socklen_t, also used by glibc. See also accept(2).
-
-Building on RHEL5 on x86_64, where size_t is 8 and socklen_t is 4, I get a
-warning:
-
- ckcftp.c: In function 'ftp_hookup':
- ckcftp.c:14667: warning:
- comparison is always true due to limited range of data
-
-Referring to:
-
- if (hisctladdr.sin_addr.s_addr != (unsigned long) -1)
-
-This seems to be the problem; if I remove the (unsigned long) cast (in two
-places), the problem goes away. Actually what I should be comparing it with
-is INADDR_NONE, which is defined appropriately in some header file, e.g. as
-0xffffffff. Also I define it explicitly as -1 if it is not defined in any
-header file (as is the case in Solaris 9). Tested OK on 64-bit RHEL5,
-32-bit RHEL5, Digital Unix 4.0E 64-bit, Solaris 9 32-bit, Mac OS X 10.4.11
-32-bit, Mac OS X 10.6.3 64-bit, AIX 5.3, Gentoo Linux 2.6.31 on Alpha
-64-bit, NetBSD 5.0.1 32-bit.... ckcftp.c, 29 Mar 2010.
-
----C-Kermit 9.0 Alpha.04---
-
-Yesterday's VOID redefinition caused problems for HP-UX in ckuusx.c, in the
-curses section where VOID is undef'd and not used to avoid a conflict with
-curses.h. As a workaround I defined a new macro CKVOID with the same
-definition as VOID and used it in the offending section of ckuusx. The real
-solution is to replace all references to VOID with CKVOID (since VOID is
-increasingly likely to cause conflicts), but a mass search and replace is
-not without risks. ckcdeb.h, ckuusx.c, 30 Mar 2010.
-
-Changed VOID and CKVOID definition to be 'void' for all HP-UX (verified by
-PeterE back to HP-UX 6.5, 1989). Still need to check this on HP-UX 5.21;
-if that's an exception it can be done in the makefile. ckcdeb.h, 30 Mar 2010.
-
-The change I made to allow CONNECT to reestablish a previous SSH connection
-prevented a new SSH connection to a different host to be made. Fixed in
-ckuus7.c, 30 Mar 2010.
-
-Fixed mistaken extern declarations of krb4_errno and krb5_errno as strings
-in nvlook(); they are ints. Built OK on Mac OS X 10.6.3. ckuus4.c, 30 Mar 2010.
-
-A fix to Trusted HP-UX makefile target from PeterE, to account for the
-equivalence of +openssl and +ssl as target suffixes. 30 Mar 2010.
-
-Added a new function \fcvtcsets(string,cset1,cset1) that converts a string
-from one character set to another. The csets are File Character-Set names.
-ckuus4.c, 31 Mar 2010.
-
-Added a new function \fdecodehex(string,prefix) that decodes a string
-containing prefixed hex bytes. Default prefix is %%, but any prefix of
-one of two chars (such as % or 0x) can be specified. ckuusr.h, ckclib.h,
-ckclib.c, ckuusr.c, 31 Mar 2010.
-
-Richard Nolde reports that Kermit can't find -lpam on Fedora 12 because it's
-in /lib rather than /usr/lib. RHEL5 has symlinks, FC12 should too. Added a
-note to the makefile. 1 Apr 2010.
-
-Build on Solaris 11 for the first time. Had to adjust ckuver.h to get the
-version herald right. This was on a box that reported its architecture as
-i86pc. 1 Apr 2010.
-
-Added MIME character-set names as invisible synonyms in the file and
-terminal character-set tables, fcstab[] and tcstab[]. Note that not all the
-character sets known to Kermit are registered in MIME. But at least now
-MIME-registered character sets can be referred to by their MIME names, e.g.
-ISO-8859-1, ISO646-ES, IBM437, WINDOWS-1252. These are not listed if you
-type ? in a field that is parsing them, unless you type a letter first,
-e.g. "i?" lists ISO- and IBM set names. Later maybe I'll make parallel
-tables, or keyword attribute bit that says whether a name is MIME or not.
-The real benefit of this change is that now Kermit can take its
-character-set names from external sources like email headers or web logs.
-ckuxla.c, 1 Apr 2010.
-
-Changed the IF command to accept a bare macro name its condition. This will
-parse and execute correctly if the macro is defined and if it has a numeric
-value, or if it is not defined, in which case it evaluates to 0 (FALSE). If
-it is defined but has a non-numeric value, a parse error occurs. ckuus6.c,
-2 Apr 2010.
-
-Added \fstringtype() function. Given a string argument, it tells whether
-the string is 7bit, 8bit, utf8, binary, etc. ckuusr.h, ckuus[4x].c,
-2 Apr 2010.
-
-Did a few builds to make sure there were no booboos. Solaris 9, NetBSD
-5.01, Linux RHEL4, HP-UX 10.20 (non-ANSI compiler and ANSI optimizing
-compiler), Mac OS X 10.4.11, SCO OSR 6.00. 5 Apr 2010.
-
----C-Kermit 9.0 Alpha.05---
-
-Increased maximum variable name length from 4K to 16K. Verified that
-too-long names are caught and recovered from correctly. ckuusr.h, 6 Apr 2010.
-
-Implemented a new \fsplit() option for parsing CSV files, which turns out to
-be a little complicated, because the separator is not just a comma, but a
-comma and all its surrounding spaces. Also there are special quoting rules
-for fields with embedded commas and fields with embedded quotes. ckclib.c,
-7 Apr 2010.
-
----C-Kermit 9.0 Alpha.06---
-
-VMS changes from SMS. They build OK, Kermit file transfers are still OK,
-but FTP text-mode GETs always hang on the 10th 8K network read. Couldn't
-get a debug log this time. ckcmai.c, ckvfio.c, ckvrms.h, ckvker.com.
-8 Apr 2010.
-
-Changing VNAML from 4K to 16K broke the build on HP-UX 9. Put it back to
-4K. 9 Apr 2010.
-
-John Dunlap, running days-long stress tests between E-Kermit and C-Kermit,
-found a bug in the packet-reading and -decoding code: If a NAK packet
-arrives with its length field corrupted to indicate a bigger size, and there
-are enough bytes following in the pipeline, ttinl() will return a too-long
-packet (if there are not enough bytes waiting to be read, then ttinl() will
-properly time out). In the bad case rpack() trusts the packet length, uses
-it as the basis for computation of the block-check length, which is then
-used to access memory that might not be there, causing (at least on John's
-Linux system) a segmentation fault. John added the normal clause to check
-the result of the block-check calculation, and I changed ttinl() to always
-break on the eol character (normally carriage return), since this can never
-appear in a packet, even if we "set control unprefix all". Also added a
-check to ttinl() to protect against length fields corrupted into illegal
-values. ckcfn2.c, ckutio.c, 13 Apr 2010.
-
-From Lewis McCarthy:
- Based on code inspection, C-Kermit appears to have an SSL-related security
- vulnerability analogous to that identified as CVE-2009-3767 (see e.g.
- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3767).
-
- I'm attaching a patch for this issue relative to the revision of ck_ssl.c
- obtained from a copy of http://www.columbia.edu/kermit/ftp/test/tar/x.zip
- downloaded on 2010/07/30, which I believe is the latest.
-
- When this flaw was first widely publicized at last year's Black Hat
- conference, it was claimed that some public certificate authorities had
- indeed issued certificates that could be used to exploit this class of
- vulnerability. As far as I know they have not revealed specifically which
- public CA(s) had been found issuing such certificates.
- Some references: http://www.mseclab.com/?p=180
- http://www.theregister.co.uk/2009/07/30/universal_ssl_certificate/
-
-Patches added to ck_ssl.c, 4 Aug 2010.
-
-Peter Eichhorn reported that "RENAME ../x ." didn't work. This is a side
-effect of the changes of 2006 to the RENAME command, there was a little
-confusion in the renameone() routine; fixed in ckuus6.c, 4 Aug 2010.
-
-If only one file is FOPEN'd, FCLOSE given with no arguments would close it.
-Turns out to be a bad idea. Example: program with an input and output file,
-try to close the output file before it is opened by just typing FCLOSE; this
-can mess up the input file. For safety FCLOSE has to require a channel
-number or ALL. ckuus7.c, 4 Aug 2010.
-
-Added \fstrcmp(s1,s2,case,start,length), which has the advantage over IF
-EQU,LGT,LLT that case sensitivity can be specified as a function arg, and
-also substrings can be specified. ckuusr.h, ckuus[24].c, 5 Aug 2010.
-
-The CSV feature of Alpha.06 had a subtle flaw, namely that if the last item
-in a comma separated list was enclosed within doublequotes with a trailing
-space after the closing doublequote, a spurious empty final element would be
-created in the result array. Fixed in cksplit(), ckclib.c, 5 Aug 2010.
-
----Alpha.07---
-
-The CSV feature of \fsplit() splits a comma-separated list into an array.
-To turn the array back into a comma separated list, \fjoin(&a,\44,1) almost
-works, except for elements contain literal doublequotes, such as:
-
- Mohammad "The Greatest" Ali
-
-This calls for making a symbolic CSV argument for \fjoin() like the one that
-was made for \fsplit(): \fjoin(&a,CSV). Also \fjoin(&a,TSV) for
-Tab-separated list. Thus if Kermit reads a record in CSV format, splits it
-into an array, and then joins the array back into a CSV record, the result
-will be equivalent to the original, according to the CSV definition. It
-might not be identical, because if the result had extraneous spaces before
-or after the separating commas, these are discarded, but that does not
-affect the elements themselves. Furthermore it is now possible to convert
-a comma-separated list into a tab-separated list, and vice versa (which is
-not a simple matter of changing commas to tabs or vice versa). ckuus4.c,
-12 Aug 2010.
-
-From Joop Boonen 26 Juli 2010: "Added HAVE_LOCKDEV as openSuSE >= 11.3 uses
-lockdev but not baudboy. They use ttylock directly. The program code has
-been added so the the program works without a problem." makefile, ckcdeb.h,
-ckutio.c, ckuus5.c, 23 Aug 2010.
-
----Alpha.08---
-
-From Gary Mills at the U of Manitoba: convert Solaris version from BSD ptys
-to streams ptys because there are only 48 BSD-style ptys and he was running
-out. No code changes needed, the only change necessary was to add the
-following flags to the makefile target:
-
- -DHAVE_STREAMS -DHAVE_GRANTPT -DHAVE_PTSNAME
- -DPUSH_PTEM -DPUSH_LDTERM -DPUSH_TTCOMPAT
-
-makefile, ckcmai.c, 21 Sep 2010.
-
-Testing this in Solaris 9 I see that the DES library disappeared. Added
-code to the solaris9 targets (also used by Solaris 10 and 11) to check for
-this. makefile, 21 Sep 2010.
-
-The Solaris target checked the OpenSSL version automatically to set the
-right flag, the Linux target didn't. Put the OpenSSL-version testing code
-in the Linux target too. makefile, 21 Sep 2010.
-
-A couple minor changes to the tru64-51b makefile targets from Steven Schweda
-but there still are some problems with the Tru64 Unix builds.
-makefile, 21 Sep 2010.
-
----Alpha.09---
-
-\fcontents(\&a[3]) got an error if the array was declared but its dimension
-was less than 3, which is bad when dealing with (say) an array created
-dynamically by \fsplit(), which might or might not have a third element.
-In case it doesn't -- i.e. in case we are referring to an out of range
-element of any array that is declared -- we should just return a null
-string, as we do with other types of variables that are not defined.
-For that matter, ditto even if the array is not declared; what useful
-purpose is served by throwing an error in this case?
-ckuus4.c, 30 Dec 2010.
-
-cksplit() treats \ as a quoting character. If the source string contains
-backslashes, they are swallowed (or, if doubled, one is kept). That's not
-good for parsing external data, such as lines read from files, where there
-are no quoting rules. This came up when parsing CSV files; as a workaround,
-I made \fsplit() treat backslash as an ordinary character for CSV and TSV
-splitting (a better solution might be yet another argument that specifies
-a quote character). ckclib.c, 30 Dec 2010.
-
-Began converting C-Kermit to Open Source with the Simplified 3-Clause BSD
-license. Updated the text for the INTRO, LICENSE, NEWS, and SUPPORT
-commands. Fixed things so the copyright year to be displayed is defined in
-one place (ck_cryear in ckcmai.c), rather than hardwired into text strings
-all over the place. COPYING.TXT, ckcmai.c, ckuus[256].c, 2 Jun 2011.
-
-When I added MIME synonyms for Kermit character-set names, I left a bogus
-entry in the tables ("windows-1251") that was in the wrong place
-alphabetically, thus preventing most references to file character-set names
-from working right. Removed the bogus entry. ckuxla.c, 2 Jun 2011.
-
-Most combinations work OK, but not translating Cyrillic text from UTF-8
-to Latin/Cyrillic, and probably the same would be true for any case of
-converting from UTF-8 or UCS-2 to anything else. The problem was in
-xgnbyte(), which converts the input stream from the specified character to
-UCS2; it needed to make a special case for when the input file was already
-Unicode. Believe it or not, this problem occurred at least as far back as
-8.0.201 (9.5 years ago) and nobody noticed. So if the fix isn't perfect
-probably nobody will notice that either. ckcfns.c, 3 Jun 2011.
-
-The SET BLOCK CHECK command did not parse all the items in its keyword
-list. Fixed in ckuus3.c, 3 Jun 2011.
-
-For EM-APEX ocean floats project, where buoys in stormy waters have to
-transmit data through an earth satellite using non-error-correcting modems,
-John Dunlap ran exhaustive stress tests of Kermit protocol transfers through
-a simulated connection that injected errors and delays and identified a
-weakness in Kermit protocol when it is used under extremely bad conditions:
-If a data byte of the S packet (or its Ack) is corrupted and the 1-byte
-checksum is also corrupted in such a way that that the checksum matches the
-corrupted data, the two Kermit programs will disagree as to the negotiated
-parameters. For example, if file Sender's RPT field is changed from '~' to
-'^', the receiver will decode the packet incorrectly. Ditto for most of the
-other parameters. The result is that a corrupted file is received but
-reported correct. John suggested a new mode of operation in which the Type
-3 block check is used for all packets. Such a mode can not be negotiated
-because the negotiation packet itself is assumed by all Kermit programs to
-have a 1-byte checksum. Added SET BLOCK-CHECK 5 to the parser (with
-invisible synonym FORCE-3". ckuus3.c, 3 Jun 2011.
-
-Added supporting code for SET BLOCK 5: ckcfn[23].c, ckcpro.w, ckcmai.c,
-ckuus3.c, 3 Jun 2011.
-
-Added code to skip the heuristic that S and I packets always have block
-check type 1. File transfer OK between two C-Kermits with SET BLOCK 5.
-rpack(): ckcfn2.c, 5 Jun 2011.
-
-Made the file receiver put "5" in the block-check-type in its ACK to the
-S-Packet. spar(): ckcfns.c, 5 Jun 2011.
-
-Now the question is: Can we make the file receiver automatically and safely
-recognize a three-byte block check on an incoming S or I packet? It's
-tricky because the block check field is not self-identified, it's just the
-last "n" characters of string indicated by the length field, so correct
-decoding of the packet depends on stateful knowledge of "n". How about this:
-rpack() already knows what type of packet it is, so if it's an S or I packet
-and the 8th byte of the data field is "5" and last 3 bytes, when interpreted
-as the CRC, match the packet contents, then we accept the packet and switch
-to BLOCK 5 mode.
-
-On the other hand, if the "5" was put there by corruption, the CRC should
-catch the error. In that case we NAK the packet and presumably get a
-different version back. There would be no reason to try to re-read the same
-packet with a different block check, because the "5" could not possibly be
-there legitimately unless it had a 3-byte CRC. To be clear, this is
-cheating. We read the packet contents before we know the packet is correct,
-then we check that it *is* correct. I made the 4-line change to rpack()
-and it works OK in the absence of transmission errors. ckcfn2.c, 3 Jun 2011.
-
-So the various combinations should work as desired:
-
- . Sender and receiver both support and are told to SET BLOCK 5 ("SB5").
- . Sender SB5, but receiver doesn't support it (errors out).
- . Sender SB5, receiver supports it but wasn't told (auto-recognizes it).
- . Receiver SB5 but sender no (errors out).
-
-Note in the last case, the receiver should NOT automatically fall back to
-standard behavior because if the user said SET BLOCK 5 that means every
-packet MUST be protected by CRC to prevent the I/S packets from being
-corrupted.
-
-Installed new HELP SET BLOCK-CHECK text. ckuus2.c, 5 Jun 2011.
-
-Autodownload didn't work when the S or I packet had a 3-byte block check
-because kstart() checked it for a 1-byte checksum. Fixed in kstart(),
-ckcfn2.c, 6 Jun 2011. However, older Kermit versions and programs that
-claim to do "autodownload" will never recognize this type of packet. No
-big deal since even if they did, the transfer would fail anyway.
-
-Added 'FORCE 3' to E-Kermit, called it EK 1.7. The option is "-b 5". Works
-OK for sending and receiving, both with and without the new option. Also
-works with "-b 5" if you send an S packet to it with '5' in the BCT field.
-Changes were minimal, I have them all in ek17.diff.
-
-I could probably also make a new G-Kermit in about 10 minutes, but who cares
-about G-Kermit... We already have two useful Kermit programs that
-interoperate with the new protocol. 6 Jun 2011.
-
-Replaced the very inadequate help texts for functions \fword() and
-\fsplit() with new ones. ckuus2.c, 6 Jun 2011.
-
-There were a couple reports of file corruption that I was saving for later.
-Now that now is later I dug up the messages, files, and logs and it turns
-out that nobody had reported a reproducible case of Kermit corrupting a
-file. There have been non-reproducible cases though, almost certainly due
-to corruption of the S or I packet or its ACK, which is why we now have SET
-BLOCK 5. Even with BLOCK CHECK 5, there is no guarantee that the same thing
-won't happen, it is just far less likely. Even if we added a 32-bit CRC or
-even 64-bit one, there would still be a small chance it could happen.
-
-7 Jun 2011:
-
-Corrected various #ifdefs (or lack of them) when building C-Kermit with
-different combinations of feature-selection options such as NOCSETS, NOICP,
-NOLOCAL, NOSPL, NOUNICODE, etc. ckcfns.c ckcmai.c ckcxla.h ckuus2.c
-ckuus4.c ckuus5.c ckuus6.c ckuusr.c, 7 Jun 2011. After running the script
-that does all these builds (84 of them) I ran it again to make sure that
-none of the changes broke builds that succeeded before the changes were made.
-
-Built OK on Solaris9 ("make solaris9")
-Ditto with Krb5 and OpenSSL 0.9.8q ("make solaris9g+openssl+shadow+pam+zlib")
-
-Built OK on Mac OS X 10.4.11 ("make macosx").
-Also "make macosx+krb5+openssl.
-
-Built OK on Linux RHEL4 ("make linux").
-Built OK on Linux RHEL4 with OpenSSL 0.9.7a ("make linux+ssl").
-Built OK on Linux RHEL5 ("make linux").
-
-"make linux+ssl" fails on RHEL5 because of DES, even though the target
-tests for the presence or absence of the DES libraries. In this case the
-libraries are there but they lack the functions des_ecb3_encrypt,
-des_random_seed, and des_set_odd_parity. The build succeeds as:
-
- make linux+ssl KFLAGS=-UCK_SSL
-
-Since DES is now considered harmful, Jeff Altman suggests that all OpenSSL
-builds, even for old versions, should omit it ("If you are building with
-openssl and no kerberos or srp, just disable DES. Disabling DES will impact
-telnet and rlogin but it won't matter if you have no ability to negotiate a
-session key").
-
-From Ian Beckwith, patches for Debian Linux:
- . Change all '-' to '\(hy' in man page (new pedantry): ckuker.nr.
- . Make IKSD authentication (using PAM) ask for a password when an invalid
- username has been given, to avoid disclosing which account names are valid:
- ckufio.c, ckuus7.c.
- . Fix spelling errors: ckcftp.c, ckuus2.c, ckuker.nr, ckcpro.w, ckuusr.h.
- . Patch makefile to support install to a staging area with DESTDIR.
- . Some other patches (mainly for typos) were for plain-text documentation
- files that were generated from Web pages; I updated the web pages.
-
-A big corporate C-Kermit user has an application where a local C-Kermit
-makes a connection to a remote one, uploads some files, and then if the
-server has any new patch files for the local, it sends the patches and
-does a REMOTE HOST command to run the patch program. This stopped working
-in C-Kermit 6.0 or 7.0 when I put a check to prevent it, because "it makes
-no sense to send REMOTE commands to the local end, because the results are
-sent back to the remote to be displayed on its screen but it has no screen".
-That may be true, but if the user needs to control the local from the
-remote, they should be able to. I removed the checks. This doesn't solve
-the problem of where the output goes; ideally it would go to the local
-screen but I don't see any elegant and simple way to make that change.
-However the output redirectors can still be used with the REMOTE command
-so the results can be captured to a remote file, which could then be sent.
-ckuus7.c, 7 Jun 2011.
-
-Changed SET VARIABLE-EVALUATION to SET COMMAND VARIABLE-EVALUATION, but left
-the former version available. ckuusr.c, 9 Jun 2011.
-
-Documented the SET COMMAND VARIABLE-EVALUATION command, which I added in
-2008. ck90.html, 9 Jun 2011.
-
-Renamed all old Mac OS X makefile targets to have the prefix "old" to avoid
-confusing them with the current targets, and made macosx10 a synonym for
-macosx, so those who used previous makefiles will get a current target
-without having to know the new name. makefile, 9 Jun 2011.
-
-Added XMESSAGE, which is to MESSAGE as XECHO is ECHO: prints the text
-without a line terminator, so it can be continued by subsequent [X]MESSAGE
-commands. ckuusr.[ch], 9 Jun 2011.
-
-Back to "make linux+ssl" on RHEL5... I took the coward's way out and added
-code to the makefile target to check whether the build worked (somebody let
-me know if there is a better way to check), and if not to give a message
-suggesting they "make clean ; make linux+ssl KFLAGS=-UCK_DES". makefile,
-9 Jun 2011.
-
-Noticed that \frecurse() would dump core if called with no arguments.
-Fixed in ckuus4.c, 9 Jun 2011.
-
-Added \q() as an alternative to the more verbose \fliteral() for quoting
-strings that contain characters (like \) that would otherwise be significant
-to Kermit. It's more efficient because it isn't a function call, and 'q'
-is an intuitive letter to mean 'quote'. It also works better than
-\fliteral() because functions treat commas and braces specially. ckuus4.c,
-10 Jun 2011.
-
-Built OK on VMS 8.3 on Alpha, no net. DEC C caught a couple glitches in the
-new code that gcc didn't catch, which I fixed. ckuus[25].c, 10 Jun 2011.
-
-Built OK on VMS 8.3 on Alpha with Multinet 5.3. The SSL build failed but
-I'm not going to worry about it. 10 Jun 2011.
-
-Built OK on NetBSD 5.1. 10 Jun 2011.
-
-Tried to resurrect my old "build-all" machine, an IBM Netfinity 3500 from
-1997 with 20-some mountable bootable hard disks with lots of 1990s OS's on
-them. No dice. I can see the BIOS but not the hard disks. The
-configuration is still correct because it tries to boot from the mountable
-hard disk, but it fails (I tried six different ones).
-
-Tried to resurrect my old Siemens Nixdorf RM 200 MIPS machine. Booted OK,
-headless even, but makes a hellish high-pitched whine, like a dentist drill.
-It's pretty slow too. "make sinix542" (for SINIX 5.4.2) bombed at link
-time on no rdchk(). Fixed by #including <sys/filio.h>. ckutio.c, 10 Jun 2011.
-
-Tried to resurrect my old SCO Xenix 2.3.4 machine, also headless. Amazingly
-it still works; it can't use a monitor but I can Telnet to it. Had to tweak
-some #ifdefs but I got a no-net version built successfully. According to my
-notes, it hasn't been possible to build with TCP/IP since C-Kermit 8.0,
-but how many people ever had SCO Xenix 2.3.4 with TCP/IP anyway? Anyway we
-still have the binaries for C-Kermit 7.0. ckuus4.c, 10 Jun 2011.
-
-Built OK on AIX 5.3. Built OK on Solaris 10. 11 Jun 2011.
-
-Tried harder to revive the build-all machine, now it sort of works, but not
-all of the bootable OS's work. Built C-Kermit 9.0 OK on OpenBSD 3.0. Built
-OK on QNX 4.25 but had to #ifdef references to IXANY in ckutio.c and ckupty.
-Built OK on NetBSD 1.5.1 (2000). Tried "make netbsd+ssl" on this one, it's
-OpenSSL 0.9.5a 1 Apr 2000, but it bombs out in ckuath.c, no big deal.
-Another problem in NetBSD 1.5.2 is that even though off_t is 8, CK_OFF_T
-is 4. Worth noting but not worth fixing unless someone else notices.
-13 Jun 2011.
-
-SuSE 7.0... boots OK but telnet server doesn't work. Can telnet out but
-it's too flaky, connection drops if I try to transfer a file.
-
-OpenBSD 2.5 [1999] OK. Red Hat 7.1 OK. Red Hat 7.1 with OpenSSL 0.9.6
-not OK, same error as with 0.9.5a:
-
-ckuath.c
-In file included from ck_ssl.h:48,
- from ckuath.c:225:
-/usr/include/openssl/des.h:77: warning: redefinition of `Block'
-ckuat2.h:86: warning: `Block' previously declared here
-/usr/include/openssl/des.h:83: redefinition of `struct des_ks_struct'
-/usr/include/openssl/des.h:91: warning: redefinition of `Schedule'
-ckuat2.h:90: warning: `Schedule' previously declared here
-
-So it appears that OpenSSL support is broken for pre-0.9.7. Tried
-building it again with -UCK_SSL (since the errors are originating from
-from des.h)... But it still failed exactly the same way. I found
-#includes for des.h in ckuath.c and and ck_ssl.h and #ifdef'd them out,
-but it still fails:
-
-In file included from /usr/include/openssl/evp.h:89,
- from /usr/include/openssl/x509.h:67,
- from /usr/include/openssl/ssl.h:69,
- from ck_ssl.h:51,
- from ckuath.c:227:
-/usr/include/openssl/des.h:77: warning: redefinition of `Block'
-ckuat2.h:86: warning: `Block' previously declared here
-/usr/include/openssl/des.h:83: redefinition of `struct des_ks_struct'
-/usr/include/openssl/des.h:91: warning: redefinition of `Schedule'
-ckuat2.h:90: warning: `Schedule' previously declared here
-
-Built OK on Debian 2.1. 13 Jun 2011.
-
-On FreeBSD 4.4, it blows up with:
-ckufio.c: In function vpass':
-ckufio.c:8201: conflicting types for 'initgroups'
-/usr/include/unistd.h:154: previous declaration of 'initgroups'
-ckufio.c:8201: warning: extern declaration of 'initgroups' doesn't match global
-one. Fixed by defining NODCLINITGROUPS for FreeBSD in ckufio.c. It might not
-be the right fix, but I don't have a lot of other FreeBSD versions to
-compare with. Anyway now it builds OK on 4.4, and also on FreeBSD 3.3.
-ckufio.c, 13 Jun 2011.
-
-Tried to build on SCO Open Server 5.0.7 but it fails at link time because
-it can't find rdchk(). But it's supposed to be there! Come back to this
-later...
-
-Red Hat 6.1 i386 32/64 linux 2332545
-Red Hat 7.1 i386 32/64 linux 2368528
-Red Hat EL4 i386 32/74 linux 2363067
-Red Hat EL5.6 i386 64 linux 2371279
-Solaris9 sparc 32/64 solaris9 2849896
-Solaris9+ssl sparc 32/64 solaris9 5021764
-Solaris10 sparc 32/64 solaris10 2855776
-QNX i386 32 qnx32 2012323
-NetBSD 1.5.1 i386 32/64 netbsd 2198055
-NetBSD 5.1 i386 32/64 netbsd 2159863
-OpenBSD 2.5 i386 32/64 openbsd 2236036
-Mac OS X 10.6.7 x86_64 64 macosx 2.7M
-Mac OS X 10.4.11 ppc 32/64 macosx 2496304
-Debian 2.1 i386 32/64 linux 2213221
-FreeBSD 4.4 i386 32/64 freebsd 2291333
-FreeBSD 3.3 i386 32/64 freebsd 2147370
-SINIX 5.42 mips 32 sinix542 3319325 (1995)
-SCO Unixware 2.1.3 i386 32 uw213 2242176
-SCO OSR6.0.0 i386 32/64 sco_osr600 2368300
-
-More builds, 14 June 2011:
-
-VMS 6.2 alpha 32 make mn 2556928 No TCP/IP
-VMS 6.2 alpha 32 make m 3112960 UCX 4.0
-Solaris 11 i386 32/64 solaris11 2823860
-Solaris 11 i386 32/64 solaris11+ssl 2993660 OpenSSL 0.9.8l
-NetBSD 5.1 i386 32/64 netbsd+krb5 2307855 Kerberos 5
-Linux Slackware 12.1.0 i386 32/65 linux 2175754
-Linux Fedora 14 i386 32/64 linux 2256514
-Linux Fedora 14 i386 32/64 linux+ssl ....... OpenSSL 1.0.0d
-Linux Fedora 14 i386 32/64 linux+krb 2449614 (*)
-
-(*) make linux+krb5 "LIBS=$LIBS /lib/libk5crypto.so.3 /lib/libcom_err.so.2"
-
-Noticed that netbsd+ssl build on NetBSD 5.1 said "NetBSD 1.5" in its banner.
-Fixed by replacing the old hardwired target with the new "subroutinized"
-target a'la linux+ssl and adapting it to NetBSD. makefile, 15 Jun 2011.
-
-Same deal for Kerberos 5, make a new netbsd+krb5 target and it builds ok,
-at least once one figures out where the Kerberos headers and libs are.
-makefile, 15 Jun 2011.
-
-Same deal for the netbsdnc target, now it simply defined NOCURSES and
-chains to the main netbsd target. makefile, 15 Jun 2011.
-
-Tried to build with Kerberos 5 on Solaris, fails because the DES library
-no longer exists. This one is beyond me, sorry.
-
-Made new targets for MirBSD, mirbsd and mirbsd+ssl, makefile 15 Jun 2011.
-
-In OpenSUSE 11.2 with OpenSSL 0.9.8r we bomb on undefined references from
-various DES library routines. Builds OK without DES.
-
-Various linux+krb5 builds fail because can't find -lgssapi_krb5
-
-SSL builds with OpenSSL < 0.9.7 fail even though there is code to support
-the older SSL.
-
-Fixed some printf %ld vs int instances in the sizeofs section of SHOW FEATURES.
-ckuus5.c, 15 Jun 2011.
-
-Fixed the new linux+ssl target to actually use the SSLINC and SSLLIBS
-definitions, oops. makefile, 15 Jun 2011.
-
-15 June 2011 builds (Beta.01):
-
-AIX 5.3 ppc 32/64 aix+ssl 3283846 OpenSSL 0.9.8m
-NetBSD 5.1 i386 32/64 netbsd 2159863
-NetBSD 5.1 i386 32/64 netbsd+ssl 2350274 OpenSSL 0.9.9-dev
-NetBSD 5.1 i386 32/64 netbsd+krb5 2349627 MIT Krb5 1.6.3
-FreeBSD 8.2 i386 32/64 freebsd 2298414
-FreeBSD 8.2 i386 32/64 freebsd+ssl 2448961 OpenSSL 0.9.8q
-OpenBSD 4.7 i386 32/64 openbsd 2266132
-OpenBSD 4.7 i386 32/64 openbsd+ssl 2409263 OpenSSL 0.9.8k
-MirBSD 10 i386 32/64 mirbsd 2216601
-MirBSD 10 i386 32/64 mirbsd+ssl 2358318 OpenSSL 0.9.8r
-OpenSuse 11.2 x86_64 64 linux 2348468
-OpenSuse 11.2 x86_64 64 linux+ssl (*) 2546540 OpenSSL 0.9.8r
-RHEL 5.6 ia64 64 linux 4390687
-RHEL 5.6 ia64 64 linux+ssl (*) 4775007 OpenSSL 0.9.8e
-Ubuntu 9.10 i386 32/64 linux 2275523
-Ubuntu 9.10 i386 32/64 linux+ssl 2466708 OpenSSL 0.9.8r
-Gentoo 1.12.13 ppc 32/64 linux 2386597
-Gentoo 1.12.13 ppc64 64 linux 2749015
-Gentoo 1.12.13 ppc64 64 linux+ssl 3002150 OpenSSL 0.9.8r
-Gentoo 1.12.13 sparc 32/64 linux 2478382
-Gentoo 1.12.13 sparc 32/64 linux+ssl 2690499 OpenSSL 0.9.8r
-Solaris 9 sparc 32/64 solaris9 2849896
-Solaris 10 i386 32/64 solaris10 2837620
-IRIX 6.5 R10000 32/64 irix65 2869704
-
-* and KFLAGS=-UCK_DES
-
-Tried building on NetBSD 5.1 with Heimdal Kerberos using:
-
-make netbsd+krb5 \
- "KFLAGS=-DHEIMDAL" \
- "K5INC=-I/usr/include" \
- "K5LIB=-L/usr/lib"
-
-It found all its headers OK, but it blew up in ckuath.c. Small wonder,
-ckccfg.html says:
-
-HEIMDAL
- Should be defined if Kerberos V support is provided by HEIMDAL. Support
- for this option is not complete in C-Kermit 8.0. Anyone interested in
- working on this should contact kermit-support.
-
-'krb5-config --version' gives the MIT Kerberos 5 version number.
-
-Make a new netbsd+krb5+ssl target based on the combination of the new
-netbsd+ssl and netbsd+krb5 targets. There were lots of warnings in the
-compilation but no errors, but it produced an executable that starts and
-does normal things but I have no idea if the SSL or Kerberos functions work.
-makefile, 16 Jun 2011.
-
-Changed the cu-solaris9-krb5 target to test for the presence of DES because
-DES isn't there, to see if this would allow a Kerberos build to proceed.
-And it worked, amazing. At least the build completed, I have no way to test
-the Kerberos part. makefile, 16 Jun 2011.
-
-Updated the solaris9+ssl target to do the DES testing. makefile, 16 Jun 2011.
-
-Updated cu-solaris+krb5 target to test whether the GSSAPI library is called
-libgassapi or libgassapi_krb5. makefile, 16 Jun 2011.
-
-Added lots of tests to the Linux Kerberos 5 entries, linux+krb5 and
-linux+krb5+ssl, because some have libk5crypto and some don't; some have
-libcom_err and some don't; and some have libgssapi_krb5 (e.g. RHEL5,
-OpenSuse 11.2) whereas others have libgssapi (Gentoo).
-
-16 June 2011 builds (Beta.01):
-
-NetBSD 5.1 i386 32/64 netbsd+krb5+ssl 2451757 OpenSSL 0.9.9 MIT Krb5 1.6.3
-Solaris 9 sparc 32/64 solaris9+krb5 2543036 MIT Kerberos 5 1.7.1
-Solaris 9 sparc 32/64 solaris9+ssl 5021544 OpenSSL 0.9.8q (gcc)
-Gentoo... ppc 32/64 linux 2386597
-Gentoo... ppc 32/64 linux+ssl 2593561 OpenSSL 0.9.8r
-Gentoo... ppc64 64 linux 2749015
-Gentoo... ppc64 64 linux+ssl 3002150 OpenSSL 0.9.8r
-RHEL5 x86_64 64 linux+krb5 (*) 2563878 MIT Kerberos 5 1.6.1
-RHEL5 x86_64 64 linux+krb5+ssl(*) 2563878 MIT Kerberos 5 1.6.1
-Fedora 14 i386 32/64 linux+krb5+ssl 2539891 MIT Krb5 + OpenSSL 0.9.8r
-
-* KFLAGS=-UCK_DES
-
---- C-Kermit 9.0.299 Beta.01 ---
-
-sizeof() can return a long or an int, so neither printf("%d",sizeof(blah));
-or printf("%ld",sizeof(blah)); can be used everywhere. Changed the
-"sizeofs" section of SHOW FEATURES in the dumbest (and therefore most
-portable) way to squelch the warnings. ckuus5.c, 17 Jun 2011.
-
-From John Dunlap: "Watching the server screen led me to offer a cosmetic
-patch for ckuusx.c. I noticed that the server screen said it was
-"RESENDING" when it really wasn't. The attached patch emits blanks to
-insure that old labels are completely erased." ckuusx.c, 17 Jun 2011.
-
-Nelson Beebe found two places where I had SSLLIBS in the makefile instead of
-SSLLIB. makefile, 18 Jun 2011.
-
-More important he knew how to force gcc to load the right header files for
-OpenSSL 1.0.0d (by using '-isystem' rather than '-I'). Previously it was
-using the 0.9.8r header files but linking with the 1.0.0d libraries. This
-is not in the sources or makefile; it's done when giving the 'make' command:
-
- export PATH=/usr/bin:$PATH
- export SSLINC=-isystem/usr/include
- export "SSLLIB=-L/usr/lib -Wl,-rpath,/usr/lib"
- make linux+ssl
-
-Folded the previous linux+openssl+zlib+shadow+pam and linux+openssl+shadow
-targets into linux+ssl. Checked the linuxso (scripting only) target, builds
-OK, 600K. Made new subroutinized linux+krb5+krb4 target but can't find
-anyplace to test it. Made new subroutinized linux+shadow+pam target, works
-fine on RHEL4. Revised comments and lists again. makefile, 18 Jun 2011.
-
-For the pluggable-disk OS's that boot OK but lack a working network, I
-rigged up a serial connection using a DB9-FF null modem cable, and then a
-DB9-MF modem cable to make it reach. I don't see any modem signals on
-either end, but the data goes through OK. COM1 on the desktop PC,
-/dev/ttyS1 or whatever on Lab. Since there are no modem signals, can't use
-RTS/CTS. At 57600bps with Xon/Xoff, 500-byte packets and sliding windows,
-transfers work OK at about 5000cps using 5 window slots; takes 8 minutes to
-transfer the gzipped C-Kermit tarball. Kermit to the rescue. 19 Jun 2011.
-
-Transferred the tarball over serial ports to SCO OSR5.0.5 at 38.4Kbps, the
-highest speed supported, 12 minutes, no errors, 3300cps. Unpack, make
-sco32v505udk, OK. Also built the TCP/IP version and it almost made an
-outbound connection, but only once (not a Kermit problem but something with
-the TCP/IP stack). 19 Jun 2011.
-
-Ditto for Solaris 2.6/i386, except 57.6Kbps, 4K-byte packets, no problem.
-Solaris 8/i386, ditto. 19 Jun 2011.
-
-SCO OpenServer 5.0.5 i386 32 sco32v505udk 1940964 No TCP/IP
-SCO OpenServer 5.0.5 i386 32 sco32v505udknet 2314668 With TCP/IP
-Sun Solaris 2.6 i386 32 solaris26g 4661368
-Sun Solaris 8 i386 32 solaris8g 4675432
-
-When using compact substring notation, \s(xx[4]) returns the whole string
-xx starting at position 4, but \s(xx[4:]) returns an empty string. Fixed
-the latter to be like the former. ckuus5.c, 20 Jun 2010.
-
-Really it would have been nicer if \s(xx[4]) returned a single character,
-the 4th character of xx, but it's too late now. Added another "separator"
-character '.' (period) for that: \s(xx[4.]) is the 4th character of xx.
-ckuus4.c, 20 Jun 2010.
-
-Back to SCO OSR5.0.7... This failed before because 'rdchk' came up unknown
-at link time, unlike all previous OSR5's, that used rdchk() in place of the
-FIONREAD ioctl. Added #ifdefs to make a special case for 5.0.7. I'm not
-sure this is the best way, but this is the minimal change to get it to work.
-If anybody cares, maybe the same can be done for previous OSR5 releases.
-ckutio.c, 20 Jun 2010 (search for SCO_OSR507).
-
-SCO OpenServer 5.0.7 i386 32 sco32v507 1895724 No TCP/IP
-SCO OpenServer 5.0.7 i386 32 sco32v507net 2246792 With TCP/IP
-
-Checked current code on RHEL4, found that my GSSAPI-lib finding makefile
-target didn't look in enough places; added some more. makefile, 21 Jun 2011.
-
-Got reports back on HPUX from Peter Eichhorn, almost all good on HP-UX 7, 8,
-9, 10, and 11. 21-22 Jun 2011.
-
-Got access to Debian 5.0 and 7-to-be ("Wheezy/Sid"). Regular 'make linux' is
-OK in Debian 5, but in 7 can't find crypt, res_search, or dn_expand; had
-to add more library search clauses to 'make linux'. makefile, 21 Jun 2011.
-
-In Debian 7.0, libk5crypto could not be found without adding another clause
-to 'make linux+krb5'. That done, the SSL build (1.0.0d) was OK, as well as
-the krb5+ssl one. makefile, 21 Jun 2011.
-
-I found a Linux box that had both Kerberos 4 and 5 installed and tried 'make
-linux+krb5+krb4', which failed because of missing DES functions. Tried
-'make linux+krb5+krb4 KFLAGS=-UCK_DES', but that fails too, even though it
-doesn't fail for Kerberos 5 alone, so probably some Krb4 code is making
-unguarded calls to the DES routines. What is really needed is a way to
-completely strip all DES references from any given build, code and makefile,
-a big deal. 21 Jun 2011.
-
-Fixed some typos in COPYING.TXT (noticed by Ian Beckwith). 24 Jun 2011.
-
-Got access to perhaps the last living 4.3BSD VAX system. It doesn't have
-SEEK_CUR so I had to #ifdef out the \fpicture() function. Aside from that,
-no problems. ckuus4.c, 24 Jun 2011.
-
-I had been wanting the S-Expression (ROUND x) to allow a second argument n,
-which, if given, tells where the rounding should occur. If n is positive,
-the number is rounded to n decimal places. If zero, it is rounded to the
-nearest integet. If positive, the number is rounded to the nearest power of
-10; e.g. -2 means "to the nearest hundred". If ROUND is used as before,
-with one argument, it works as before. ckclib.c, ckuus3.c, 25 Jun 2011.
-
-From Arthur Marsh, a few more directories to test for libresolv in Linux.
-makefile, 26 Jun 2011.
-
-From Martin Vorlaender, a fix for the VMS file-transfer display and
-statistics, a place where a file length wasn't being cast to CK_OFF_T
-in zchki(). ckvfio.c, 28 Jun 2011.
-
-Updated version to 9.0.300 and removed the Beta designation.
-ckcmai.c, makefile, 28 Jun 2011.
-
-Removed solaris9_64 target from makefile. It builds but it doesn't work
-at all. 30 Jun 2011.
-
---- C-Kermit 9.0.300 ---
-
-On Solaris 10 and 11, DNS lookups don't work. It seems these Solaris
-versions have INADDRX and INADDRX_NONE defined, thus triggering the code in
-ckcnet.c, ckucns.c, and ckcftp.c #ifdef'd on these symbols, but that code
-doesn't work in this case. This happens building with gcc as well as with
-Sun cc. Put #ifdefs in ckcnet.h to undefine these symbols (if they are
-defined after including all the header files) for Solaris. I didn't bother
-trying to differentiate the Solaris versions because the symbols are not
-defined in Solaris 9 or earlier, and they should not be used in Solaris 10
-or 11. ckcnet.h, 6 July 2011.
-
-From SMS: To avoid the %CC-W-PTRMISMATCH1 complaints from ck_ssl.c, add
-two (harmless) type casts at lines 2460 and 2773, 6 July 2011.
-
-Built and tested on Solaris 9, Solaris 10, and RHEL5. 6 July 2011.
-
---- C-Kermit 9.0.301 Beta.01 ---
-
-Updated version text and date. ckcmai.c, makefile, 11 July 2011.
-
---- C-Kermit 9.0.301 ---
-
-After the initial release I made some small changes that affect only HP-UX
-5.x: added -DVOID=void and -DCKVOID=void to the hpux0500 makefile targets,
-and put #ifdefs around #include <errno.h>, which (in the WinTCP case) didn't
-protect itself against multiple inclusion (which is happening in other
-header files, not in Kermit). makefile, ckucmd.c, ckucon.c, ckutio.c,
-ckufio.c, ckcnet.c, ckcftp.c, 14 July 2011.
-
-In the new copyright notice, copied from the BSD license template,
-one instance of "the <ORGANIZATION>" was not replaced by "Columbia
-University". Fixed in ckcmai.c, 19 July 2011.
-
-Added another search term for lk5crypto in the linux+krb5 targets.
-makefile, 20 July 2011.
-
-Added and successfully used a new solaris9+krb5+ssl target.
-makefile, 8 Aug 2011.
-
-FreeBSD 9 switched from utmp to utmpx, which broke compilation of Kermit on
-that version. Furthermore, the UUCP lockfile convensions changed in FreeBSD
-8, which did not prevent C-Kermit from compiling, but any attempt to lock a
-terminal or pty device would fail. Thanks to Alexey Dokuchaev "danfe" for
-finding and patching the problems. I undid the patches and fixed the code
-so it didn't need to be patched, except for some declarations in the
-ck_crp.c module, which I felt had better not be changed without thoroughly
-testing the changes on dozens of different platforms, which I don't have
-time to do (in any case, it builds OK on FreeBSD 9 without the patch). In
-particular I made completely new makefile targets for FreeBSD 4.0 and later,
-which automatically detect FreeBSD 8 and FreeBSD 9 to enable the appropriate
-feature tests in the code, for a regular build and a build with OpenSSL.
-These changes should affect only FreeBSD. ckutio.c, ckufio.c, ck_crp.c,
-ckuus5.c, makefile, 20 Aug 2011.
-
-Changed the version to 9.0.302, ckcmai.c, 20 Aug 2011.
-
-Fixed freebsd+ssl and netbsd+ssl, netbsd+krb5, and netbsd+krb5+ssl targets
-to have CC=$(CC) instead of CC=gcc; ditto for CC2, and adjusted line breaks
-in freebsd and freebsd+ssl targets. makefile, 21 Aug 2011.
-
---- 9.0.302 ---
-
----------------------------------
-***************************
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcasc.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckcasc.h
deleted file mode 100644
index 68cd2f7..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcasc.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- File CKCASC.H
- Mnemonics for ASCII control characters (and Space) for use with C-Kermit.
-*/
-/*
- Author: Frank da Cruz (fdc@columbia.edu).
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#ifndef CKCASC_H
-#define CKCASC_H
-
-#define NUL '\0' /* Null Ctrl-@*/
-#define SOH 1 /* Start of header Ctrl-A */
-#define STX 2 /* Ctrl-B */
-#define ETX 3 /* Ctrl-C */
-#define EOT 4 /* Ctrl-D */
-#define ENQ 5 /* ENQ Ctrl-E */
-#define ACK 6 /* Ctrl-F */
-#define BEL 7 /* Bell (Beep) Ctrl-G */
-#define BS 8 /* Backspace Ctrl-H */
-#define HT 9 /* Horizontal Tab Ctrl-I */
-#define LF 10 /* Linefeed Ctrl-J */
-#define VT 11 /* Vertical Tab Ctrl-K */
-#define NL '\n' /* Newline */
-#define FF 12 /* Formfeed Ctrl-L */
-#define CR 13 /* Carriage Return Ctrl-M */
-#define SO 14 /* Shift Out Ctrl-N */
-#define SI 15 /* Shift In Ctrl-O */
-#define DLE 16 /* Datalink Escape Ctrl-P */
-#define XON 17 /* XON Ctrl-Q */
-#define DC1 17
-#define DC2 18 /* Ctrl-R */
-#define XOFF 19 /* XOFF Ctrl-S */
-#define DC3 19
-#define DC4 20 /* Ctrl-T */
-#define NAK 21 /* Ctrl-U */
-#define SYN 22 /* SYN, Ctrl-V */
-#define ETB 23 /* Ctrl-W */
-#define CAN 24 /* CAN, Ctrl-X */
-#define XEM 25 /* Ctrl-Y (was EM but conflicts with OpenSSL) */
-#define SUB 26 /* SUB Ctrl-Z */
-#define ESC 27 /* Escape Ctrl-[ */
-#define XFS 28 /* Field Separator, Ctrl-Backslash */
-#define XGS 29 /* Group Separator, Ctrl-Rightbracket */
-#define XRS 30 /* Record Separator, Ctrl-Circumflex */
-#define US 31 /* Unit Separator, Ctrl-Underscore */
-#define SP 32 /* Space */
-#define DEL 127 /* Delete (Rubout) */
-#define RUB 127 /* Delete (Rubout) */
-
-#ifdef OS2
-/*
- These are needed in OS/2, so let's not cause any unnecessary conflicts.
-*/
-#define _CSI 0233 /* 8-bit Control Sequence Introducer */
-#define _SS2 0216 /* 8-bit Single Shift 2 */
-#define _SS3 0217 /* 8-bit Single Shift 3 */
-#define _DCS 0220 /* 8-bit Device Control String Introducer */
-#define _ST8 0234 /* 8-bit String Terminator */
-#define _OSC 0235 /* 8-bit Operating System Command */
-#define _PM8 0236 /* 8-bit Privacy Message */
-#define _APC 0237 /* 8-bit Application Program Command */
-#endif /* OS2 */
-#endif /* CKCASC_H */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcbwr.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckcbwr.txt
deleted file mode 100644
index 533c946..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcbwr.txt
+++ /dev/null
@@ -1,1514 +0,0 @@
-
- [1]The Columbia Crown The Kermit Project | Columbia University
- 612 West 115th Street, New York NY 10025 USA o [2]kermit@columbia.edu
- ...since 1981
- [3]Home [4]Kermit 95 [5]C-Kermit [6]Scripts [7]Current [8]New [9]FAQ
- [10]Support
-
- As of: C-Kermit 9.0.300, 30 June 2011
- This page last updated: Tue Jun 28 08:54:30 2011 (New York USA Time)
-
- IF YOU ARE READING A PLAIN-TEXT version of this document, it is a
- plain-text dump of a Web page. You can visit the original (and
- possibly more up-to-date) Web page here:
-
- [11]http://www.columbia.edu/kermit/ckcbwr.html
-
- This document contains platform-independent C-Kermit hints and tips.
- Also see the platform-specific C-Kermit hints and tips document for
- your platform, for example:
-
- [12]http://www.columbia.edu/kermit/ckubwr.html
-
- for Unix. This document also applies to [13]Kermit 95 for Windows,
- which is based on C-Kermit.
-
- [ [14]C-Kermit ] [ [15]TUTORIAL ]
-
-CONTENTS
-
- 0. [16]PATCHES
- 1. [17]INCOMPATIBLE CHANGES
- 2. [18]THE C-KERMIT COMMAND PARSER
- 3. [19]MULTIPLE SESSIONS
- 4. [20]NETWORK CONNECTIONS
- 5. [21]MODEMS AND DIALING
- 6. [22]DIALING HINTS AND TIPS
- 7. [23]TERMINAL SERVERS
- 8. [24]TERMINAL EMULATION
- 9. [25]KEY MAPPING
- 10. [26]FILE TRANSFER
- 11. [27]SCRIPT PROGRAMMING
-
-0. PATCHES
-
- [ [28]Top ] [ [29]Contents ] [ [30]Next ]
-
- Source-level patches for C-Kermit 8.0.211:
-
- (None)
-
-1. INCOMPATIBLE CHANGES
-
- [ [31]Top ] [ [32]Contents ] [ [33]Next ]
-
- These are not necessarily exhaustive lists.
-
-1.1. C-Kermit 6.0
-
- C-Kermit 6.0 was released 6 September 1996 and is completely documented
- in [34]Using C-Kermit, 2nd Edition. The following incompatible changes
- were made in C-Kermit 6.0:
-
- * Unless you tell C-Kermit otherwise, if a serial or network
- connection seems to be open, and you attempt to EXIT or to open a
- new connection, C-Kermit warns you that an active connection
- appears to be open and asks you if you really want to close it. If
- you do not want these warnings, add SET EXIT WARNING OFF to your
- customization file or script, or give this command at the prompt.
- * The default for SET { SEND, RECEIVE } PATHNAMES was changed from ON
- to OFF, to prevent unexpected creation of directories and
- depositing of incoming files in places you might not know to look.
- * The default for SET FILE INCOMPLETE was changed from DISCARD to
- KEEP to allow for file transfer recovery.
- * The default file-transfer block-check is now 3, rather than 1. If
- the other Kermit does not support this, the two will drop back to
- type 1 automatically unless the other Kermit fails to follow the
- protocol specification.
- * The default flow-control is now "auto" ("do the right thing for
- each type of connection"), not Xon/Xoff.
- * Backslash (\) is no longer a command continuation character. Only -
- (hyphen, dash) may be used for this in C-Kermit 6.0 and later.
- * Negative INPUT timeout now results in infinite wait, rather than 1
- second.
-
-1.2. C-Kermit 7.0
-
- C-Kermit 7.0 was released 1 January 2000. Its new features are
- documented in the C-Kermit 7.0 Supplement,
- [35]http://www.columbia.edu/kermit/ckermit2.html. The following
- incompatible changes were made in C-Kermit 7.0:
- * The "multiline GET" command is gone. Now use either of the
- following forms instead:
- get remote-name local-name
- get /as-name:local-name remote-name
-
- If either name contains spaces, enclose it in braces (or, in
- C-Kermit 8.0, doublequotes).
- * To include multiple file specifications in a GET command, you must
- now use MGET rather than GET:
- mget file1 file2 file3 ...
-
- * C-Kermit 7.0 and later use FAST Kermit protocol settings by
- default. This includes "unprefixing" of certain control characters.
- Because of this, file transfers that worked with previous releases
- might not work in the new release especially against a
- non-Kermit-Project Kermit protocol implementation (but it is more
- likely that they will work, and much faster). If a transfer fails,
- you'll get a context-sensitive hint suggesting possible causes and
- cures. Usually SET PREFIXING ALL does the trick.
- * By default C-Kermit 7.0 and later send files in text or binary mode
- by looking at each file to see which is the appropriate mode. To
- restore the previous behavior, put SET TRANSFER MODE MANUAL and the
- desired SET FILE TYPE (TEXT or BINARY) in your C-Kermit
- initialization file.
- * The RESEND and REGET commands automatically switch to binary mode;
- previously if RESEND or REGET were attempted when FILE TYPE was
- TEXT, these commands would fail immediately, with a message telling
- you they work only when the FILE TYPE is BINARY. Now they simply do
- this for you.
- * SET PREFIXING CAUTIOUS and MINIMAL now both prefix linefeed (10 and
- 138) in case rlogin, ssh, or cu are "in the middle", since
- otherwise <LF>~ might appear in Kermit packets, and this would
- cause rlogin, ssh, or cu to disconnect, suspend,escape back, or
- otherwise wreck the file transfer. Xon and Xoff are now always
- prefixed too, even when Xon/Xoff flow control is not in effect,
- since unprefixing them has proven dangerous on TCP/IP connections.
- * In UNIX, VMS, Windows, and OS/2, the DIRECTORY command is built
- into C-Kermit itself rather than implemented by running an external
- command or program. The built-in command might not behave the way
- the platform-specific external one did, but many options are
- available for customization. Of course the underlying
- platform-specific command can still be accessed with "!", "@", or
- "RUN" wherever the installation does not forbid. In UNIX, the "ls"
- command can be accessed directly as "ls" in C-Kermit.
- * SEND ? prints a list of switches rather than a list of filenames.
- If you want to see a list of filenames, use a (system-dependent)
- construction such as SEND ./? (for UNIX, Windows, or OS/2), SEND
- []? (VMS), etc.
- * In UNIX, OS-9, and Kermit 95, the wildcard characters in previous
- versions were * and ?. In C-Kermit 7.0 they are *, ?, [, ], {, and
- }, with dash used inside []'s to denote ranges and comma used
- inside {} to separate list elements. If you need to include any of
- these characters literally in a filename, precede each one with
- backslash (\).
- * SET QUIET { ON, OFF } is now on the command stack, just like SET
- INPUT CASE, SET COUNT, SET MACRO ERROR, etc, as described on p.458
- of [36]Using C-Kermit, 2nd Edition. This allows any macro or
- command file to SET QUIET ON or OFF without worrying about saving
- and restoring the global QUIET value. For example, this lets you
- write a script that tries SET LINE on lots of devices until it
- finds one free without spewing out loads of error messages, and
- also without disturbing the global QUIET setting, whatever it was.
- * Because of the new "." operator (which introduces assignments),
- macros whose names begin with "." can not be invoked "by name".
- However, they still can be invoked with DO or \fexecute().
- * The syntax of the EVALUATE command has changed. To restore the
- previous syntax, use SET EVALUATE OLD.
- * The \v(directory) variable now includes the trailing directory
- separator; in previous releases it did not. This is to allow
- constructions such as:
- cd \v(dir)data.tmp
-
- to work across platforms that might have different directory
- notation, such as UNIX, Windows, and VMS.
- * Prior to C-Kermit 7.0, the FLOW-CONTROL setting was global and
- sticky. In C-Kermit 7.0, there is an array of default flow-control
- values for each kind of connection, that are applied automatically
- at SET LINE/PORT/HOST time. Thus a SET FLOW command given before
- SET LINE/PORT/HOST is likely to be undone. Therefore SET FLOW can
- be guaranteed to have the desired effect only if given after the
- SET LINE/PORT/HOST command.
- * Character-set translation works differently in the TRANSMIT command
- when (a) the file character-set is not the same as the local end of
- the terminal character-set, or (b) when the terminal character-set
- is TRANSPARENT.
-
-1.3. C-Kermit 8.0
-
- The following incompatible changes were made in C-Kermit 8.0:
- * C-Kermit now accepts doublequotes in most contexts where you
- previously had to use braces to group multiple words into a single
- field, or to force inclusion of leading or trailing blanks. This
- might cause problems in contexts where you wanted the doublequote
- characters to be taken literally. Consult [37]Section 5 of the
- [38]C-Kermit 8.0 Update Notes for further information.
- * Using the SET HOST command to make HTTP connections is no longer
- supported. Instead, use the new [39]HTTP OPEN command.
-
-1.4. C-Kermit 9.0
-
- The [40]\fsplit() function is incredibly handy, it can do almost
- anything, up to and including parsing a LISP program (the underlying
- code is the basis of the [41]S-Expression interpreter). But did you
- ever try to use it to parse (say) a Tab-Separated-List (TSV file) or
- Comma-Separated-List (CSV)? It works as expected as long as the data
- contains only 7-bit characters. But if your data contains (say) Spanish
- or German or Russian text written in an 8-bit character set such as ISO
- 8859-1, every 8-bit character (any value 128-255) is treated as a break
- character. This is fixed in C-Kermit 9.0 by treating all 8-bit bytes as
- "include" characters rather than break characters, a total reversal of
- past behavior. I don't think it will affect anyone though, because if
- this had happened to anyone, I would have heard about it!
-
- Since most standard 8-bit character sets have control characters in
- positions 128-160, it might have made sense to keep 128-160 in the
- break set, but with the proliferation of Microsoft Windows code pages,
- there is no telling which 8-bit character is likely to be some kind of
- text, e.g. "smart quotes" or East European or Turkish accented letters.
-
-2. THE C-KERMIT COMMAND PARSER
-
- [ [42]Top ] [ [43]Contents ] [ [44]Next ] [ [45]Previous ]
-
- Various command-related limits are shown in the following table, in
- which the sample values are for a "large memory model" build of
- C-Kermit, typical for modern platforms (Linux, Solaris, AIX, VMS, etc).
- You can see the values for your version of Kermit by giving the SHOW
- FEATURES command. The maximum length for a Kermit command (CMDBL) also
- determines the maximum length for a macro definition, since DEFINE is
- itself a command. The maximum length for a variable name is between 256
- and 4096 characters, depending on the platform; for array declarations
- and references, that includes the subscript.
-
- Item Symbol Sample
- Value Definition
- Number of characters in a command CMDBL 32763 ckucmd.h
- Number of chars in a field of a command ATMBL 10238 ckucmd.h
- Nesting level for command files MAXTAKE 54 ckuusr.h
- Nesting level for macros MACLEVEL 128 ckuusr.h
- Nesting level for FOR / WHILE loops FORDEPTH 32 ckuusr.h
- Number of macros MAC_MAX 16384 ckuusr.h
- Size of INPUT buffer INPBUFSIZ 4096 ckuusr.h
- Maximum files to match a wildcard MAXWLD 102400 ckcdeb.h
- Filespecs in MSEND command MSENDMAX 1024 ckuusr.h
- Length for GOTO target label LBLSIZ 50 ckuusr.h
- \fexecute() recursion depth limit CMDDEP 64 ckucmd.h
-
- If you need to define a macro that is longer than CMDBL, you can break
- the macro up into sub-macros or rewrite the macro as a command file. In
- a pinch you can also redefine CMDBL and recompile C-Kermit. All of
- these numbers represent tradeoffs: the bigger the number, the more
- "powerful" Kermit in the corresponding area, but also the bigger the
- program image and possibly disk footprint, and the longer it takes to
- load and initialize.
-
- In the interactive command parser:
-
- * EMACS- or VI-style command line editing is not supported.
- * Editing keys are hardwired (Ctrl-U, Ctrl-W, etc).
-
- If you interrupt C-Kermit before it has issued its first prompt, it
- will exit. This means that you cannot interrupt execution of the
- initialization file, or of an "application file" (file whose name is
- given as the first command-line argument), or of an alternative
- initialization file ("-y filename"), and get to the prompt. There is,
- however, one exception to this rule: you *can* interrupt commands --
- including TAKE commands -- given in the '-C "command list"'
- command-line argument and -- if there were no action commands among the
- command-line arguments -- you will be returned to the C-Kermit prompt.
- So, for example, if you want to start C-Kermit in such a way that it
- executes a command file before issuing its first prompt, and you also
- want to be able to interrupt the command file and get to the prompt,
- include a TAKE command for the desired command in the -C argument, for
- example:
-
- kermit -C "take dial.scr"
-
- At the command prompt, if you use the backslash (\) prefix to enter a
- control character, space, or question mark into a command literally,
- the backslash disappears and is replaced by the quoted character. If it
- was a control character, it is shown as a circumflex (^). This allows
- editing (backspace, delete, Ctrl-W) to work correctly even for control
- characters.
-
- Priot to C-Kermit 8.0, the only way to include a comma literally in a
- macro definition -- as opposed to having it separate commands within
- the definition -- is to enter its ASCII value (44) in backslash
- notation, e.g.:
-
- DEFINE ROWS RUN MODE CO80\{44}\%1
-
- In C-Kermit 8.0 you can use constructions like this:
-
- DEFINE ROWS RUN MODE "CO80,\%1"
-
- If you quote special characters in a filename (e.g. in the SEND
- command), filename completion may seem to work incorrectly. For
- example, if you have a file whose name is a*b (the name really contains
- an asterisk), and you type "send a\\*<ESC>", the "b" does not appear,
- nor will Ctrl-R redisplay the completed name correctly. But internally
- the file name is recognized anyway.
-
- Question-mark help does not work during execution of an ASKQ command.
- The question marks are simply accepted as text.
-
- In OUTPUT commands only, \B sends a BREAK signal, \L sends a Long BREAK
- signal, and \N sends a NUL (ASCII 0). BREAK and Long BREAK are special
- signals, not characters, and NUL is a character that normally cannot be
- included in a C string, since it is the C string terminator. If you
- really want to output a backslash followed by a B, an L, or an N (as is
- needed to configure certain modems, etc), double the backslash, e.g.
- "output \\B". In C-Kermit 7.0 or later, you can disarm and re-arm the
- special OUTPUT-command escapes (\B, \L, and \N) with SET OUTPUT
- SPECIAL-ESCAPES { OFF, ON }.
-
- When using the command-line processor ("kermit -l /dev/tty00 -b 19200",
- etc), note that in some cases the order of the command-line options
- makes a difference, contrary to the expectation that order of
- command-line options should not matter. For example, the -b option must
- be given after the -l option if it is to affect the device specified in
- the -l option.
-
-3. MULTIPLE SESSIONS
-
- [ [46]Top ] [ [47]Contents ] [ [48]Next ] [ [49]Previous ]
-
- C-Kermit 7.0 and earlier do not support multiple sessions. When you SET
- LINE (or SET PORT, same thing) to a new device, or SET HOST to a new
- host, the previous SET LINE device or network host connection is
- closed, resulting in hangup of the modem or termination of the network
- connection. In windowing environments like HP-VUE, NeXTSTEP, Windows,
- OS/2, etc, you can run separate copies of Kermit in different windows
- to achieve multiple sessions.
-
- To achieve multiple sessions through a single serial port (e.g. when
- dialing up), you can install SLIP or PPP on your computer and then use
- C-Kermit's TCP/IP support over the SLIP or PPP connection, assuming you
- also have TCP/IP networking installed on your computer.
-
- C-Kermit 8.0 has the same restriction on SET LINE and SET HOST
- sessions: only one regular session (dialout, Telnet, etc) can be open
- at a time. However, version 8.0 adds two new kinds of sessions: FTP and
- HTTP; one or both of these can be open at the same as a regular
- session.
-
-4. NETWORK CONNECTIONS
-
- [ [50]Top ] [ [51]Contents ] [ [52]Next ] [ [53]Previous ]
-
-FTP Client Bugs
-
- The Unix C-Kermit 8.0.206 FTP client had the following bugs at the time
- most of the 8.0.206 binaries were built for the C-Kermit 8.0 CDROM:
-
- 1. FTP MGET fails when directory segments contain wildcards, as in
- "ftp mget */data/*.dat". Work around by doing a separate MGET for
- each source directory.
- 2. FTP MGET can fail or produce random side effects if you have a
- TMPDIR or CK_TMP environment variable definition in effect, or a
- SET TEMP-DIRECTORY value, longer than 7 characters. Work around by
- giving a SET TEMP-DIRECTORY command with a short value, such as
- "/tmp".
-
- These two bugs are fixed in the source code that is included on the
- CDROM, and also in Kermit 95 2.1.1. You can tell if a C-Kermit 8.0.206
- binary has these fixes by typing SHOW VERSION; if it says "FTP Client,
- 8.0.200, 24 Oct 2002" it has the fixes; if the edit number is less that
- 200, it doesn't, in which case can build a new binary from the source
- code (or contact us and we'll try to get get one for you).
-
-Making TCP/IP Connections Can Take a Long Time
-
- The most frequently asked question in many newsgroups is "Why does it
- take such a long time to make a Telnet connection to (or from) my
- (e.g.) Linux PC?" (this applies to Kermit as well as to regular Telnet
- clients):
-
- 1. Most Telnet servers perform reverse DNS lookups on the client for
- security and/or logging reasons. If the Telnet client's host cannot
- be found by the server's local DNS server, the DNS request goes out
- to the Internet at large, and this can take quite some time. The
- solution to this problem is to make sure that both client and host
- are registered in DNS.
- 2. C-Kermit itself performs reverse DNS lookups unless you tell it not
- to. This is to allow C-Kermit to let you know which host it is
- actually connected to in case you have made a connection to a "host
- pool" (multihomed host). You can disable C-Kermit's reverse DNS
- lookup with SET TCP REVERSE-DNS-LOOKUP OFF.
- 3. C-Kermit 7.0 and later strictly enforce Telnet protocol rules. One
- such rule is that certain negotiations must be responded to. If
- C-Kermit sends a such a negotiation and the host does not respond,
- C-Kermit waits a long time for the reply (in case the network is
- congested or the host is slow), but eventually will time out. To
- eliminate the waits (and therefore risk possible protocol
- mismatches -- or worse -- between Telnet client and server), tell
- C-Kermit to SET TELNET WAIT OFF (or include the /NOWAIT switch with
- the TELNET command).
-
-The Rlogin Client
-
- In multiuser operating systems such as UNIX and VMS, TCP/IP Rlogin
- connections are available only to privileged users, since "login" is a
- privileged socket. Assuming you are allowed to use it in the first
- place, it is likely to behave differently depending on what type of
- host you are rlogging in to, due to technical reasons having to do with
- conflicting interpretations of RFC793 (Out-Of-Band Data) and Rlogin
- (RFC1122)... "Specifically, the TCP urgent pointer in BSD points to the
- byte after the urgent data byte, and an RFC-compliant TCP urgent
- pointer points to the urgent data byte. As a result, if an application
- sends urgent data from a BSD-compatible implementation to an
- [54]RFC-1122 compatible implementation then the receiver will read the
- wrong urgent data byte (it will read the byte located after the correct
- byte in the data stream as the urgent data byte)." Rlogin requires the
- use of OOB data while Telnet does not. Therefore, it is possible for
- Telnet to work between all systems while BSD and System V TCP/IP
- implementations are almost always a bad mix.
-
-The Telnet Client
-
- On a TCP/IP TELNET connection, you should normally have PARITY set to
- NONE and (except in VMS C-Kermit) FLOW-CONTROL also set to NONE. If
- file transfer does not work with these settings (for example, because
- the remote TELNET server only gives a 7-bit data path), use SET PARITY
- SPACE. Do not use SET PARITY MARK, EVEN, or ODD on a TELNET connection
- -- it interferes with TELNET protocol.
-
- If echoing does not work right after connecting to a network host or
- after dialing through a TCP/IP modem server, it probably means that the
- TELNET server on the far end of the connection is executing the TELNET
- protocol incorrectly. After initially connecting and discovering
- incorrect echoing (characters are echoed twice, or not at all), escape
- back, give the appropriate SET DUPLEX command (FULL or HALF), and then
- CONNECT again. For a consistently misbehaving connection, you can
- automate this process in a macro or TAKE file.
-
- TELNET sessions are treated just like serial communications sessions as
- far as "terminal bytesize" and "command bytesize" are concerned. If you
- need to view and/or enter 8-bit characters during a TELNET session, you
- must tell C-Kermit to SET TERMINAL BYTESIZE 8, SET COMMAND BYTESIZE 8,
- and SET PARITY NONE.
-
- If you SET TELNET DEBUG ON prior to making a connection, protocol
- negotiations will be displayed on your screen. You can also capture
- them in the debug log (along with everything else) and then extract
- them easily, since all Telnet negotiations lines begin with (uppercase)
- "TELNET".
-
-The SSH Client
-
- C-Kermit does not have its own built-in SSH client; instead, in the
- Unix tradition, uses the external SSH client to do the SSH part, and
- Kermit does its thing on top -- file transfer, scripting, etc. Under
- certain circumstances that have not yet been identified, it sometimes
- happens that after making an SSH connection from C-Kermit, logging out
- from the remote host, and popping back to the local C-Kermit program,
- subsequent SSH commands file with a message like "Network type not
- supported". Starting a new copy of C-Kermit is the workaround.
-
-5. MODEMS AND DIALING
-
- [ [55]Top ] [ [56]Contents ] [ [57]Next ] [ [58]Previous ]
-
- External modems are recommended because:
-
- * They don't need any special drivers.
- * They are less likely to interfere with normal operation of your
- computer.
- * You can use the lights and speaker to troubleshoot dialing.
- * You can share them among all types of computers.
- * You can easily turn them off and on when power-cycling seems
- warranted.
- * They are more likely to have manuals.
-
- Modems can be used by C-Kermit only when they are visible as or through
- a regular serial port device. Certain modems can not be used in this
- normal way on many kinds of computers: Winmodems, RPI modems,
- Controllerless modems, the IBM Mwave, etc; all of these require special
- drivers that perform some, most, or all of the modem's functions in
- software. Such drivers are generally NOT available in UNIX or other
- non-Windows (or non-OS/2, in the case of the Mwave) platforms.
-
- In order to dial a modem, C-Kermit must know the modem's repertoire of
- commands and responses. Each modem make and model is likely to have a
- different repertoire. Since Kermit has no way of knowing which kind of
- modem will be dialed, normally you have to tell it with a SET MODEM
- TYPE command, e.g.:
-
- set modem type usrobotics
- set line /dev/cua0
- set speed 57600
- dial 7654321
-
- In the early days, there was a wide variety of modems and command
- languages. Nowadays, almost every modem uses the Hayes AT command set
- (but with some differences in the details) and its startup
- configuration includes error correction, data compression, and hardware
- (RTS/CTS) flow control. As long as C-Kermit is capable of hardware flow
- control (as it is on many, but not all, the platforms where it runs,
- since some operating systems don't support it), the modem can be dialed
- immediately, without lengthy configuration dialogs, and in fact this is
- what SET MODEM TYPE GENERIC-HIGH-SPEED does. In C-Kermit 8.0,
- GENERIC-HIGH-SPEED has become the default modem type, so now it is
- usually possible to SET LINE, SET SPEED, and DIAL without having to
- identify your modem. If this doesn't work, of course, then you might
- have to fall back to the traditional method: Give a SET MODEM TYPE for
- a specific modem first, then SET LINE, SET SPEED, and DIAL.
-
- An important change in C-Kermit 6.0 is that when you give a SET MODEM
- TYPE command to tell Kermit what kind of modem you have, Kermit also
- sets a number of other modem-related parameters automatically from its
- internal modem database. Thus, the order in which you give
- modem-related commands is significant, whereas in prior releases they
- could be given in any order.
-
- In particular, MODEM SPEED-MATCHING is set according to whether the
- modem is known to be capable of speed buffering. SET MODEM TYPE
- HAYES-2400 automatically turns SPEED-MATCHING ON, because when the
- Hayes 2400 reports a particular speed in its CONNECT message, that
- means its interface speed has changed to that speed, and C-Kermit's
- must change accordingly if it is to continue communicating. This might
- cause some confusion if you use "set modem type hayes" for dialing a
- more advanced type of modem.
-
- The new default for flow control is "auto", meaning "do the right thing
- for each type of connection". So (for example) if your version of
- C-Kermit supports SET FLOW RTS/CTS and your modem also supports
- RTS/CTS, then Kermit automatically sets its flow control to RTS/CTS and
- set modem's flow control to RTS/CTS too before attempting to use the
- modem.
-
- For these reasons, don't assume that "set modem type hayes" should be
- used for all modems that uses the Hayes AT command set. "set modem type
- hayes" really does mean Hayes 1200 or 2400, which in turn means no
- hardware flow control, and no speed buffering. This choice will rarely
- work with a modern high-speed modem.
-
-6. DIALING HINTS AND TIPS
-
- [ [59]Top ] [ [60]Contents ] [ [61]Next ] [ [62]Previous ]
-
- If you have a high-speed, error-correcting, data-compressing,
- speed-buffering modem, you should fix the modem's interface speed as
- high as possible, preferably (at least) four times higher than its
- maximum connection (modulation) speed to allow compression to work at
- full advantage. In this type of setup, you must also have an effective
- means of flow control enabled between C-Kermit and the modem,
- preferably hardware (RTS/CTS) flow control. On platforms that do not
- support hardware flow control, it is usually possible to select
- software flow control (Xon/Xoff), and C-Kermit will do its best to set
- the modem for local Xon/Xoff flow control too (but then, of course,
- Ctrl-S and Ctrl-Q characters can not be transmitted on the connection).
-
- If you are having trouble dialing your modem, SET DIAL DISPLAY ON to
- watch the dialing interactions between C-Kermit and your modem. Consult
- Chapters 3-4 of [63]Using C-Kermit (2nd Ed) for modem-dialing
- troubleshooting instructions. The following sections offer some
- additional hints and tips.
-
-6.1. Syntax
-
- If you want to dial a number that starts with #, you'll need to quote
- the "#" character (as \# or \{35}), since it is also a comment
- introducer:
-
- C-Kermit>dial #98765421-1-212-5551212 ; Looks like a comment
- ?You must specify a number to dial
- C-Kermit>dial \#98765421-1-212-5551212 ; Works OK
- C-Kermit>dial =#98765421-1-212-5551212 ; This works too
-
- When using a dialing directory, remember what happens if a name is not
- found:
-
- C-Kermit>dial xyzcorp
- Lookup: "xyzcorp" - not found - dialing as given
-
- This normally does no harm, but some modems might behave strangely when
- given dial strings that contain certain letters. For example, a certain
- German modem treats any dial string that contains the letter "s" as a
- command to fetch a number from its internal list, and replies OK to the
- ATD command, which is normally not a valid response except for partial
- dialing. To avoid this situation, use:
-
- lookup xyzcorp
- if success dial
-
-6.2. The Carrier Signal
-
- Remember: In many C-Kermit implementations (depending on the underlying
- operating system -- mostly Windows, OS/2, and System-V-based UNIX
- versions, and in C-Kermit 7.0, also VMS), you can't CONNECT to a modem
- and type the modem's dialing command (like "ATDT7654321") manually,
- unless you first tell C-Kermit to:
-
- SET CARRIER-WATCH OFF
-
- This is because (in these implementations), the CONNECT command
- requires the modem's Carrier Detect (CD) signal to be on, but the CD
- signal doesn't come on until after dialing is complete. This
- requirement is what allows C-Kermit to pop back to its prompt
- automatically when the connection is hung up. See the description of
- SET CARRIER-WATCH in "Using C-Kermit".
-
- Similarly, if your dialed connection drops when CARRIER-WATCH is set to
- AUTO or ON, you can't CONNECT back to the (now disconnected) screen to
- see what might have happened unless you first SET CARRIER-WATCH OFF.
- But sometimes not even SET CARRIER-WATCH OFF will help in this
- situation: certain platforms (for example Unixware 2.1), once carrier
- drops, won't let the application do i/o with the device any more. In
- that case, if you want to use the device again, you have to CLOSE it
- and OPEN it again. Or you can have Kermit do this for you automatically
- by telling it to SET CLOSE-ON-DISCONNECT ON.
-
-6.3. Dialing and Flow Control
-
- Don't SET FLOW RTS/CTS if your modem is turned off, or if it is not
- presenting the CTS signal. Otherwise, the serial device driver can get
- stuck waiting for this signal to appear.
-
- Most modern modems support RTS/CTS (if they support any hardware flow
- control at all), but some computers use different RS-232 circuits for
- the same purposes, e.g. DTR and CD, or DTR and CTS. In such cases, you
- might be able to make your computer work with your modem by
- appropriately cross-wiring the circuits in the cable connector, for
- example the computer's DTR to the modem's RTS, and modem's CD to the
- computer's CTS. HOWEVER, C-Kermit does not know you have done this. So
- if you have (say) SET FLOW DTR/CD, C-Kermit will make no attempt to
- tell the modem to use RTS/CTS. You probably did this yourself when you
- configured the modem.
-
-6.4. The Dial Timeout
-
- If it takes your call longer to be completed than the timeout interval
- that C-Kermit calculates, you can use the SET DIAL TIMEOUT command to
- override C-Kermit's value. But beware: the modem has its own timeout
- for completing the call. If it is a Hayes-like modem, C-Kermit adjusts
- the modem's value too by setting register S7. But the maximum value for
- S7 might be smaller than the time you need! In that case, C-Kermit sets
- S7 to 0, 255, or other (modem-specific) value to signify "no timeout".
- If Kermit attempts to set register S7 to a value higher than your
- modem's maximum, the modem will say "ERROR" and you will get a "Failure
- to initialize modem" error. In that case, use SET DIAL TIMEOUT to
- override C-Kermit's calculation of the timeout value with the highest
- value that is legal for your modem, e.g. 60.
-
-6.5. Escape Sequence Guard Time
-
- A "TIES" (Time-Independent Escape Sequence) modem does not require any
- guard time around its escape sequence. The following text:
-
- +++ATH0
-
- if sent through a TIES modem, for example because you were uploading
- this file through it, could pop the modem back into command mode and
- make it hang up the connection. Later versions of the Telebit T1600 and
- T3000 (version LA3.01E firmware and later), and all WorldBlazers, use
- TIES.
-
- Although the probability of "+++" appearing in a Kermit packet is
- markedly lower than with most other protocols (see the [64]File
- Transfer section below), it can still happen under certain
- circumstances. It can also happen when using C-Kermit's TRANSMIT
- command. If you are using a Telebit TIES modem, you can change the
- modem's escape sequence to an otherwise little-used control character
- such as Ctrl-_ (Control-Underscore):
-
- AT S2=31
-
- A sequence of three consecutive Ctrl-_ characters will not appear in a
- Kermit packet unless you go to extraordinary lengths to defeat more
- than a few of Kermit's built-in safety mechanisms. And if you do this,
- then you should also turn off the modem's escape-sequence recognition
- altogether:
-
- AT S48=0 S2=255
-
- But when escape sequence recognition is turned off, "modem hangup"
- (<pause>+++<pause>ATH0<CR>) will not work, so you should also SET MODEM
- HANGUP RS232-SIGNAL (rather then MODEM-COMMAND).
-
-6.6. Adaptive Dialing
-
- Some modems have a feature called adaptive dialing. When they are told
- to dial a number using Tone dialing, they check to make sure that
- dialtone has gone away after dialing the first digit. If it has not,
- the modem assumes the phone line does not accept Tone dialing and so
- switches to Pulse. When dialing out from a PBX, there is almost always
- a secondary dialtone. Typically you take the phone off-hook, get the
- PBX dialtone, dial "9" to get an outside line, and then get the phone
- company's dialtone. In a situation like this, you need to tell the
- modem to expect the secondary dialtone. On Hayes and compatible modems,
- this is done by putting a "W" in the dial string at the appropriate
- place. For example, to dial 9 for an outside line, and then 7654321,
- use ATDT9W7654321:
-
- SET PBX-OUTSIDE-PREFIX 9W
-
- (replace "9" with whatever your PBX's outside-line prefix is).
-
-6.7. The Busy Signal
-
- Some phone companies are eliminating the busy signal. Instead, they
- issue a voice message such as "press 1 to automatically redial until
- the number answers, or...". Obviously this is a disaster for modem
- calls. If your service has this feature, there's nothing Kermit can do
- about it. Your modem will respond with NO CARRIER (after a long time)
- rather than BUSY (immediately), and Kermit will declare the call a
- failure, rather than trying to redial the same number.
-
-6.8. Hanging Up
-
- There are two ways to hang up a modem: by turning off the serial port's
- DTR signal (SET MODEM HANGUP-METHOD RS232-SIGNAL) or sending the modem
- its escape sequence followed by its hangup command (SET MODEM
- HANGUP-METHOD MODEM-COMMAND). If one doesn't work, try the other. If
- the automatic hangup performed at the beginning of a DIAL command
- causes trouble, then SET DIAL HANGUP OFF.
-
- The HANGUP command has no effect when C-Kermit is in remote mode. This
- is on purpose. If C-Kermit could hang up its own controlling terminal,
- this would (a) most likely leave behind zombie processes, and (b) pose
- a security risk.
-
- If you DIAL a modem, disconnect, then SET HOST or TELNET, and then
- HANGUP, Kermit sends the modem's hangup command, such as "+++ATHO".
- There is no good way to avoid this, because this case can't reliably be
- distinguished from the case in which the user does SET HOST
- terminal-server, SET MODEM TYPE name, DIAL. In both cases we have a
- valid modem type selected and we have a network connection. If you want
- to DIAL and then later make a regular network connection, you will have
- to SET MODEM TYPE NONE or SET DIAL HANGUP OFF to avoid this phenomenon.
-
-7. TERMINAL SERVERS
-
- [ [65]Top ] [ [66]Contents ] [ [67]Next ] [ [68]Previous ]
-
- Watch out for terminal server's escape character -- usually a control
- character such as Ctrl-Circumflex (Ctrl-^). Don't unprefix it in
- Kermit!
-
- Ciscos -- must often be told to "terminal download"... Cisco ASM models
- don't have hardware flow control in both directions.
-
- Many terminal servers only give you a 7-bit connection, so if you can't
- make it 8-bit, tell Kermit to "set parity space".
-
- The following story, regarding trouble transferring 8-bit files through
- a reverse terminal server, was contributed by an Annex terminal server
- user:
-
- Using C-Kermit on an HP 9000 712/80 running the HP-UX 10.00
- operating system. The HP was connected to a Xylogics Annex
- MICRO-ELS-UX R7.1 8 port terminal server via ethernet. On the second
- port of the terminal server is an AT&T Paradyne 3810 modem, which is
- connected to a telephone line. There is a program which runs on the
- HP to establish a Telnet connection between a serial line on the
- Annex and a character special file on the HP (/dev file). This is an
- Annex specific program called rtelnet (reverse telnet) and is
- provided with the terminal server software. The rtelnet utility runs
- on top of the pseudo-terminal facility provided by UNIX. It creates
- host-originated connections to devices attached ot Annex serial
- ports. There are several command line arguments to be specified with
- this program: the IP address of the terminal server, the number of
- the port to attach to, and the name of the pseudo-device to create.
- In addition to these there are options to tell rtelnet how to
- operate on the connect: -b requests negotiation for Telnet binary
- mode, -d turns on socket-leve debugging, -f enables "connect on the
- fly" mode, -r removes the device-name if it already exists, etc. The
- most important of these to be specified when using 8 data bits and
- no parity, as we found out, was the -t option. This creates a
- transparent TCP connection to the terminal server. Again, what we
- assumed to be happening was that the rtelnet program encountered a
- character sequence special to itself and then "eating" those kermit
- packets. I think this is all of the information I can give you on
- the configuration, short of the values associated with the port on
- the terminal server.
-
- How to DIAL from a TCP/IP reverse terminal server (modem server):
-
- 1. (only if necessary) SET TELNET ECHO REMOTE
- 2. SET HOST terminal-server-ip-name-or-address [ port ]
- 3. SET MODEM TYPE modem-type
- 4. (only if necessary) SET DIAL HANGUP OFF
- 5. (for troubleshooting) SET DIAL DISPLAY ON
- 6. DIAL phone-number
-
- The order is important: SET HOST before SET MODEM TYPE. Since this is a
- Telnet connection, serial-port related commands such as SET SPEED, SET
- STOP-BITS, HANGUP (when MODEM HANGUP-METHOD is RS232), etc, have no
- effect. However, in C-Kermit 8.0, if the modem server supports
- [69]RFC-2217 Telnet Com-Port Control protocol, these commands do indeed
- take effect at the server's serial port.
-
-8. TERMINAL EMULATION
-
- [ [70]Top ] [ [71]Contents ] [ [72]Next ] [ [73]Previous ]
-
- Except for the Windows, OS/2, and Macintosh versions, C-Kermit does not
- emulate any kind of terminal. Rather, it acts as a "semitransparent
- pipe", passing the characters you type during a CONNECT session to the
- remote host, and sending the characters received from the remote host
- to your screen. Whatever is controlling your keyboard and screen
- provides the specific terminal emulation: a real terminal, a PC running
- a terminal emulator, etc, or (in the case of a self-contained
- workstation) your console driver, a terminal window, xterm, etc.
-
- Kermit is semitransparent rather than fully transparent in the
- following ways:
-
- * During a TELNET ("set host") session, C-Kermit itself executes the
- TELNET protocol and performs TELNET negotiations. (But it does not
- perform TN3270 protocol or any other type of 3270 terminal
- emulation.)
- * If you have changed your keyboard mapping using SET KEY, C-Kermit
- replaces the characters you type with the characters or strings
- they are mapped to.
- * If you SET your TERMINAL CHARACTER-SET to anything but TRANSPARENT,
- C-Kermit translates your keystrokes (after applying any SET KEY
- definitions) before transmitting them, and translates received
- characters before showing them on your screen.
- * If your remote and/or local TERMINAL CHARACTER-SET is an ISO 646
- 7-bit national character set, such as German, French, Italian,
- Swedish, etc, or Short KOI used for Cyrillic, C-Kermit's CONNECT
- command automatically skips over ANSI escape sequences to avoid
- translating their characters. Only ANSI/ISO standard
- (VT100/200/300-like) 7-bit escape sequence formats are supported
- for this purpose, no proprietary schemes like H-P, Televideo,
- Tektronix, etc.
- * If your version of C-Kermit includes SET TERMINAL APC command, then
- C-Kermit's CONNECT command will handle APC escape sequences if
- TERMINAL APC is not set to OFF (which is the default).
-
- You can make C-Kermit fully transparent by starting it with the -0
- (dash zero) command-line option.
-
- If you are running C-Kermit under a console driver, or in a terminal
- window, that emulates the VT100, and use C-Kermit to log in to a VMS
- system, the console driver or terminal window (not Kermit) is supposed
- to reply to the "what are you?" query (ESC Z) from the VAX. If it
- doesn't, and you can't make it do so, then you can (a) live with the
- "unknown terminal" problem; (b) tell VMS to SET TERMINAL/DEVICE=VT100;
- (c) program a key using SET KEY to send the appropriate sequence and
- then punch the key at the right time; or (d) use the VMSLOGIN macro
- that is defined in CKERMIT.INI to do this for you automatically.
-
- SET SESSION-LOG { TEXT, BINARY }, which is effective in UNIX and AOS/VS
- but not other C-Kermit versions, removes CR, DEL, NUL, XON, and XOFF
- characters (Using C-Kermit neglects to mention that XON and XOFF are
- removed). The TEXT-mode setting is ineffective during SCRIPT command
- execution, as well as on X.25 connections.
-
-9. KEY MAPPING
-
- [ [74]Top ] [ [75]Contents ] [ [76]Next ] [ [77]Previous ]
-
- Except in the terminal-emulating versions, C-Kermit's key mapping
- facilities are limited to normal "ASCII" keys, and cannot be used with
- function keys, arrow keys, arcane key combinations, etc. Since C-Kermit
- runs on such a wide variety of hardware platforms (including, for
- example, more than 360 different UNIX platforms), it is not possible
- for C-Kermit to support every conceivable keyboard under every release
- of every UNIX (or VMS, or ...) product on every different kind of
- computer possibly under all manner of different console drivers, even
- if it had the means to do so.
-
- In technical terms, C-Kermit uses the read() function to read
- keystrokes, and read() returns a single byte (value 0 through 255).
- C-Kermit's SET KEY function applies to these single-byte codes.
- "Extended function" keys, such as F-keys, arrow keys, etc, usually
- return either a 2-byte "scan code" or else a character string (such as
- an escape sequence like "<ESC> O p"). In both cases, C-Kermit has no
- way to tell the difference between such multibyte key values, and the
- corresponding series of single-byte key values. This could only be done
- by accessing the keyboard at a much lower level in a highly
- platform-dependent manner, probably requiring tens of thousands of
- lines of code to support even a sampling of the most popular
- workstation / OS combinations.
-
- However, most workstation console drivers (terminal emulation windows,
- etc) include their own key-mapping facility. For example in AIX, the
- AIXterm program (in whose window you would run C-Kermit) allows
- rebinding of the F1-F12 keys to arbitrary strings. The same is true of
- Xterm and DECterm windows, etc. Consult the technical documentation for
- your workstation or emulator. See sample Xterm (Xmodmap) mappings in
- the [78]Unix C-Kermit Hints and Tips document.
-
- The SET KEY command (except in Kermit 95) does not allow a key
- definition to be (or contain) the NUL (\0) character.
-
-10. FILE TRANSFER
-
- [ [79]Top ] [ [80]Contents ] [ [81]Next ] [ [82]Previous ]
-
- C-Kermit 7.0 is the first release of C-Kermit to use fast (rather than
- robust and therefore slow) protocol defaults: long packets, sliding
- windows, control-character unprefixing, and streaming where possible.
- This makes most transfers (partner willing) dramatically faster "out of
- the box" but might break some combinations that worked before. If
- transfers with C-Kermit 7.0 or later fail where transfers worked with
- earlier C-Kermit versions, try the following (one at a time, in this
- order):
-
- 1. SET PREFIXING ALL: Disables control-character unprefixing.
- 2. SET STREAMING OFF: Disables streaming.
- 3. CAUTIOUS: Selects medium but cautious protocol settings.
- 4. ROBUST: this command reverts to the most conservative protocol
- settings.
-
- Execution of multiple file transfers by C-Kermit from a command file
- when in remote mode might exhibit long delays between each transfer. To
- avoid this, just include the command "SET DELAY 0" in your command file
- before any of the file-transfer commands.
-
- File transfer failures can occur for all sorts of reasons, most of them
- listed in Chapter 10 of [83]Using C-Kermit. The following sections
- touch on some that aren't.
-
- The [84]C-Kermit 7.0 Release Notes document SEND /COMMAND as taking an
- argument, but it doesn't. Instead of SEND /COMMAND:{some command}, use:
-
-SEND /COMMAND [ other switches such as /AS-NAME: ] command [ arguments... ]
-
-10.1. Laptops
-
- Watch out for laptops and their assorted power-saver features; for
- example, a built-in modem's "auto timeout delay" hanging up the
- connection in the middle of a file transfer. Most modems, even if they
- have this feature, do not have it enabled by default. But if you
- experience otherwise inexplicable disconnections in the midst of your
- Kermit sessions, check the modem manual for such things as "idle
- timeout", "auto timeout", etc, and add the command to disable this
- feature to Kermit's init string for this modem.
-
-10.2. NFS
-
- If uploading a large file to an NFS-mounted disk fails (or is painfully
- slow), try uploading it to a local disk (e.g. /tmp on Unix) and then
- copying to the NFS disk later.
-
-10.3. Modems
-
- If you are dialing out and find that downloads work but uploads don't,
- try again with a lower serial-port speed. Case in point: dialing out on
- a certain PC from Linux at 115200 bps using a USR Courier 56K
- "V.Everything" external modem and RTS/CTS flow control. Downloads
- worked flawlessly, uploads stopped dead after the first few packets
- were sent. The modem lights showed constant retraining (ARQ light
- blinks slowly), and the CTS light was off 95% of the time, allowing
- nothing to get through. Reducing the serial port speed to 57600 bps
- made the problems go away. Evidently the PC in question has a very fast
- serial port, since dialing the same modem with a different PC at 115200
- bps works without incident.
-
-10.4. TCP/IP Connections
-
- If you have trouble transferring files over a TCP/IP connection, tell
- Kermit to SET PARITY SPACE and try again. If that doesn't work, also
- try a shorter packet length or smaller window size (to compensate for
- certain well-known broken Telnet servers), and/or SET RELIABLE OFF.
-
-10.5. Multihop Connections
-
- If you have a multihop connection, with the interior nodes in CONNECT
- mode (Kermit, Telnet, Rlogin, or any other), you can expect (a) file
- transfer to be slower, and (b) the connection to be less transparent
- (to control characters, perhaps to the 8th bit) than a more direct
- connection. C-Kermit 7.0 and later have a "-0" (dash-zero) command-line
- option to make it 100% transparent in cases where it is to be used in
- the middle.
-
-10.6. Recovery
-
- The recovery feature (RESEND command) that was added in version 5A(190)
- works only for binary-mode transfers. In order for this feature to be
- useful at all, the default for SET FILE INCOMPLETE was changed from
- DISCARD to KEEP. Otherwise an interrupted transfer would leave no
- partial file behind unless you had remembered to change the default.
- But now you have to pay closer attention to Kermit's messages to know
- whether a transfer succeeded or failed -- previously, if it failed, the
- file would not show up on the receiving end at all; in 5A(190) and
- later, you'll get a partial file which could easily be mistaken for the
- complete file unless you change the default back to DISCARD or read the
- screen messages, or keep a transaction log.
-
-10.7. Filename Collisions
-
- SET FILE COLLISION BACKUP is the default. This means:
-
- * If you send the same file lots of times, there will be many backup
- files. There is no automatic mechanism within Kermit to delete
- them, no notion of a "version retention count", etc, but you can
- use the PURGE command to clean them up.
- * If a file arrives that has the same name as a directory, the file
- transfer fails because Kermit will not rename a directory. Send the
- file with another name, or use SET FILE COLLISION RENAME.
- * If the directory lacks write permission, the file transfer fails
- even if you have write access to the file that is being backed up;
- in that case, switch to SET FILE COLLISION OVERWRITE or APPEND, or
- send to a different directory.
-
- SET FILE COLLISION UPDATE depends on the date/time stamp in the
- attribute packet. However, this is recorded in local time, not
- Universal Time (GMT), and there is no indication of time zone. The time
- is expressed to the precision of 1 second, but some file systems do not
- record with this precision -- for example, MS-DOS records the file
- date/time only to the nearest 2 seconds. This might cause update
- operations to send more files than necessary.
-
- (This paragraph does NOT apply to UNIX, where, as of C-Kermit 7.0,
- C-Kermit pipes incoming mail and print material directly the mail or
- print program): When C-Kermit is receiving files from another Kermit
- program that has been given the MAIL or REMOTE PRINT command, C-Kermit
- follows the current filename collision action. This can be
- disconcerting if the action was (for example) BACKUP, because the
- existing file will be renamed, and the new file will be mailed (or
- printed) and then deleted. Kermit cannot temporarily change to RENAME
- because the file collision action occurs when the filename packet is
- received, and the PRINT or MAIL disposition only comes later, in the
- Attribute packet.
-
- Watch out for SET FILE COLLISION RENAME, especially when used in
- conjunction with recovery. Recall that this option (which is NOT the
- default) renames the incoming file if a file already exists with the
- same name (the default is to rename the previously existing file, and
- store the incoming file with its own name). It is strongly recommended
- that you do not use SET FILE COLLISION RENAME if you ever intend to use
- the recovery feature:
-
- * When the file is first received by C-Kermit, its name is changed if
- another file already has the same name. When you RESEND the same
- file after a failure, C-Kermit will probably try to append the
- re-sent portion to the wrong file.
- * Assuming that you get RESEND to work with FILE COLLISION RENAME,
- C-Kermit, when receiving the remainder of the file during a RESEND
- operation, will report back the wrong name. Nothing can be done
- about this because the name is reported back before the receiving
- Kermit program finds out that it is a recovery operation.
-
- Also watch out for DISABLE DELETE, since this implicitly sets FILE
- COLLISION to RENAME. And note tht DELETE is DISABLEd automatically any
- time you Kermit is in local mode (i.e. it makes a connection). Also
- note that for purposes of DISABLE and ENABLE, "set host *" connections
- do not count as local mode even though, strictly speaking, they are.
-
-10.8. DOS Pathnames
-
- When referring to foreign MS-DOS, Windows, Atari ST, OS/2, or other
- file specifications that contain backslash characters in a C-Kermit
- command, you might have to double each backslash, for example:
-
- C-Kermit>get c:\\directory\\foo.txt
-
- This is because backslash is used in C-Kermit commands for introducing
- special character codes, variables, functions, etc.
-
-10.9. Cancellation
-
- If attempting to cancel local-mode file reception at a very early stage
- (i.e. before data packets are exchanged) with X or Z does not work, use
- E or Ctrl-C instead, or wait until the first data packets are sent.
-
- If you cancel a transfer that is underway using X or Z, and a lot of
- window slots are in use, it might take a while for the cancellation to
- take effect, especially if you do this on the receiving end; that's
- because a lot of packets might already be on their way to you. In that
- case, just be patient and let Kermit "drain" them.
-
- If C-Kermit is sending a file, remote-mode packet-mode breakout (three
- consecutive Ctrl-C's by default) is not effective until after C-Kermit
- sends its first packet. If C-Kermit is receiving a file or is in server
- mode, it is effective right away. In the former case, the SET DELAY
- value determines the earliest time at which you can break out of packet
- mode.
-
-10.10. Partner Peculiarities
-
- When one or both partners is on an SCO operating system such as OSR5,
- you might issue the command:
-
-mapchan -n
-
- to disable character-set conversion by the terminal driver. Similarly
- for AIX:
-
-setmaps -t NOMAP
-
- When using C-Kermit to transfer files with the HP48SX calculator, you
- must SET FLOW NONE. The HP48SX does not support flow control, and
- evidently also becomes confused if you attempt to use it. You might
- also need to use SET SEND PAUSE 100 (or other number). For greater
- detail about transferring files the HP-48, see:
-
- [85]http://www.columbia.edu/kermit/hp48.html
-
- Some communication programs have errors in their implementation of
- Kermit attribute packets. If you get an error message from your
- communication program like "Attribute error", tell C-Kermit to SET
- ATTRIBUTES OFF. Better yet, switch to a real Kermit program.
-
- Some communication software claims to implement Kermit sliding windows,
- but does so incorrectly. If sliding window transfers fail, set
- C-Kermit's window size to the smallest one that works, for example, SET
- WINDOW 1.
-
- For lots more detail about how to cope with defective Kermit partners,
- see:
-
- * [86]Coping with Faulty Kermit Implementations (C-Kermit 7.0 and
- later).
- * [87]Coping with Broken Kermit Partners (C-Kermit 8.0 and later).
-
- The UNIX version of C-Kermit discards carriage returns when receiving
- files in text mode. Thus, "bare" carriage returns (sometimes used to
- achieve overstriking) are lost.
-
-11. SCRIPT PROGRAMMING
-
- [ [88]Top ] [ [89]Contents ] [ [90]Previous ]
-
-11.1. Comments Versus the SCRIPT Command
-
- Remember that ";" and "#" introduce comments when (a) they are the
- first character on the line, or (b) they are preceded by at least one
- blank or tab within a line. Thus constructions like:
-
- INPUT 5 ;
- SCRIPT ~0 #--#--#
-
- must be coded using backslash notation to keep the data from being
- ignored:
-
- INPUT 5 \59 ; 59 is the decimal ASCII code for ";"
- SCRIPT ~0 \35--#--# ; 43 is the decimal ASCII code for "#"
-
- or, more simply:
-
- INPUT 5 \; ; Just quote the semicolon
- SCRIPT ~0 \#--#--# ; Just quote the "#"
-
-11.2. Alphabetic Case and the INPUT Command
-
- INPUT and MINPUT caseless string comparisons do not work for non-ASCII
- (international) characters. Workaround: SET INPUT CASE OBSERVE. Even
- then, the "lexically less than" and "lexically greater than" operations
- (IF LLT, IF LGT) probably won't work as expected. The same is true for
- the case-conversion functions \Flower() and \Fupper(). C-Kermit does
- not know the collating sequence for different character sets and
- languages. (On the other hand, it might work depending on such items as
- how Kermit was linked, whether your operating supports "locales", etc)
-
-11.3. NUL (0) Characters in C-Kermit Commands
-
- You can't include a NUL character (\0) in C-Kermit command text without
- terminating the character string in which it appears. For example:
-
- echo In these brackets [\0] is a NUL
-
- will echo "In these brackets [". This applies to ECHO, INPUT, OUTPUT,
- and all other commands (but you can represent NUL by "\N" in an OUTPUT
- string). This is because C-language strings are terminated internally
- by the NUL character, and it allows all of C-Kermit's string comparison
- and manipulation functions to work in the normal "C" way.
-
- To illustrate:
-
- INPUT 5 \0
-
- is equivalent to:
-
- INPUT 5
-
- and:
-
- INPUT 5 ABC\0DEF
-
- is equivalent to:
-
- INPUT 5 ABC
-
- INPUT operations discard and ignore NUL characters that arrive from the
- communication device, meaning that they do not figure into matching
- operations (e.g. A<NUL>B matches AB); they are not deposited in the
- INPUT buffer (\v(input)); and they are not counted in \v(incount), with
- two exceptions:
-
- 1. An arriving NUL character restarts the INPUT SILENCE timer.
- 2. An arriving NUL character terminates the INPUT command with the
- SUCCESS condition if the INPUT command was given an empty search
- string. In this case \v(incount) is set to 1.
-
- Also, the \v(inchar) variable is null (completely empty) if the last
- INPUT character was NUL. That is, there is no way to tell only by
- looking at \v(inchar) the difference between a NUL that was INPUT and
- no INPUT at all. If the INPUT command succeeded but \v(inchar) is
- empty, then a NUL character was input. Also, \v(incount) will be set to
- 1.
-
- Here's a sample script fragment to read characters, possibly including
- NUL, from the communication connection and write them to a file:
-
- while true {
- input 1 ; read one byte
- if fail break ; timed out or connection closed
- fwrite /char \%c \v(inchar) ; record the byte
- }
-
- This works because when \v(inchar) is NUL, that's equivalent to FWRITE
- /CHAR having no text argument at all, in which case it writes a NUL
- character.
-
- \v(incount) and \v(inchar) are NOT affected by the CLEAR command.
-
-11.4. \ffiles() and \fnextfile() Peculiarities
-
- The following script program:
-
- for \%i 1 \ffiles(oofa.*) 1 {
- send \fnextfile()
- }
-
- did not work as expected in C-Kermit 6.0 and earlier but does work in
- C-Kermit 7.0 and later.
-
-11.5. Commands That Have Only Local Effect
-
- Certain settings are local to each command level, meaning that
- subordinate command levels (macros or command files) can change them
- without affecting their values at higher command levels. When a new
- command level is invoked, the value is inherited from the previous
- level. These settings are:
-
- CASE
- COUNT and \v(count)
- INPUT CASE
- INPUT TIMEOUT
- MACRO ERROR
- QUIET
- TAKE ERROR
-
- This arrangement allows CASE, TIMEOUT, and ERROR settings, which are
- used to control automatic exit from a command file or macro upon error,
- to be automatically restored when the command file or macro exits.
-
- The COUNT variable follows this rule too, which permits nested SET
- COUNT / IF COUNT loops, as in this example in which the inner loop
- counts down from the current COUNT value of the outer loop (try it):
-
- DEFINE INNER WHILE COUNT { WRITE SCREEN { Inner:}, SHOW COUNT }
- SET COUNT 5
- WHILE COUNT { WRITE SCREEN Outer:, SHOW COUNT, DO INNER }
-
- Keep in mind that an inferior command level cannot manipulate the COUNT
- value held by a higher level. For example:
-
- DEFINE OOFA SHOW COUNT, IF COUNT GOTO LOOP
- SET COUNT 5
- :LOOP
- OOFA
- ECHO Done
-
- results in an infinite loop; the COUNT value remains at 5 because it is
- never decremented at the same level at which it was set.
-
-11.6. Literal Braces in Function Calls
-
- Since braces are used in function calls to indicate grouping, there is
- no way to pass literal braces to the function itself. Solution: Define
- a variable containing the string that has braces. Example:
-
- define \%a ab{cd
- echo \fsubstring(\%a)
- ab{cd
-
- If the string is to start with a leading brace and end with a closing
- brace, then double braces must appear around the string (which itself
- is enclosed in braces):
-
- define \%a {{{foo}}}
- echo \fsubstring(\%a)
- {foo}
-
- This also works for any other kind of string:
-
- define \%a {{ab{cd}}
- echo \fsubstring(\%a)
- ab{cd
-
-11.7. Defining Variables on the C-Kermit Command Line
-
- To define variables on the C-Kermit command line, use the -C
- command-line option with one or more DEFINE or ASSIGN commands. Note
- that the C-Kermit command line must cope with the quoting rules of your
- shell. Examples:
-
- kermit -C "define \\%a foo, define phonenumber 7654321"
-
- In this case we follow UNIX quoting rules by doubling the backslash.
- Once C-Kermit starts, the \%a and \m(phonenumber) variables are defined
- as indicated and can be used in the normal way.
-
- In DOS or Windows or OS/2 the command would be:
-
- kermit -C "define \%%a foo, define phonenumber 7654321"
-
- Here we need to double the percent sign rather than the backslash
- because of DOS shell quoting rules.
-
-11.8. Per-Character Echo Check with the OUTPUT Command
-
- Sometimes the OUTPUT command must be used to send commands or data to a
- device in "echoplex" mode, meaning that characters must be sent one at
- a time, and the next character can not be sent until the echo from the
- previous one has been received. For example, a certain PBX might have
- this characteristic. Let's say a Kermit script is used to program the
- PBX. If characters are sent too fast, they can be lost. It would seem
- that the command:
-
- SET OUTPUT PACING milliseconds
-
- could be used to take care of this, but the pacing interval is constant
- and must be set large enough to allow even the slowest echo to finish.
- If the script is large (an actual example is 14,000 lines long), this
- can cause it to take hours longer than it needs to.
-
- Here is a macro you can use to OUTPUT a string in an Echoplex
- environment:
-
- define XOUTPUT {
- local \%c \%i
- set output pacing 0
- for \%i 1 \flen(\%*) 1 {
- asg \%c \fsubstr(\%*,\%i,1)
- output \%c
- input 2 \%c
- }
- }
-
- C-Kermit 7.0 or later is required.
-
- It sends one character at a time and then waits up to 2 seconds for the
- character to be echoed back, but continues to the next character as
- soon as the echo appears, so no time is wasted. You can add an IF FAIL
- clause after the INPUT in case you want to do something special about
- failure to detect an echo within the timeout period. Obviously you can
- also change the 2-second limit, and adjust the script in any other
- desired way.
-
-11.9. Scripted File Transfer
-
- Sometimes a user complains that when she makes a connection by hand,
- logs in, and transfers a file, there are no problems, but when she
- scripts the the exact same sequence, the file transfer always fails
- after a few packets. Here's a scenario where this can happen:
-
- 1. Upon logging in to the remote computer, it sends a "What Are You?"
- escape sequence.
- 2. When you log in interactively, your terminal emulator sends the
- response. This is invisible to you; you don't know it's happening.
- 3. When you script the login, and begin a file transfer immediately
- upon logging in, the host still sends the "What Are You?" sequence.
- Kermit's INPUT ECHO setting is ON by default, so the escape
- sequence passes through to the terminal, and the terminal sends its
- response. But by this time Kermit has already started the file
- transfer.
- 4. By default, the local Kermit program examines the keyboard for
- interruption characters between every packet. The "What Are You"
- response is sitting in the keyboard buffer. Eventually Kermit will
- read a character such as "c" that is a valid interruption
- character, and the file transfer stops with "User canceled".
-
- The right way to handle this situation is to have your look for the
- "What Are You?" sequence and send the response itself, as described in
- Using C-Kermit, pp.429-431. Or you can work around it by telling the
- local Kermit to "set input echo off" and/or "set transfer interruption
- off".
-
-11.10. Hexadecimal arithmetic...
-
- C-Kermit can do both integer and floating-point arithmetic, in both
- ordinary algebraic notation and in Lisp S-Expression notation. All
- arithmetic operators and functions operate only on decimal numbers. It
- is possible, however, to write scripts that operate on hexadecimal
- numbers. This is done by converting them to decimal prior to any
- arithmetic operations, and then converting them back to hexadecimal for
- display. Example:
-
-; EVALUATE is a command that evaluates an arithmetic expression.
-; See HELP EVALUATE for details. This is just for demonstration.
-; Arithmetic expressions can be used in any context where a number
-; can be used. Also, the special notation:
-;
-; .\%a ::= expression
-;
-; evaluations the expression and assigns the result to the variable.
-;
-.\%a := fffe ; Set variable to hex value
-set eval old ; See HELP EVAL
-eval \fhex2n(\%a) ; Show value of variable
-eval \fhex2n(\%a) + 1 ; Show value of expression
-eval \fhex2n(\%a) + 2 ; Show value of expression
-.\%x ::= \fhex2n(\%a) + 1 ; Assign value of expression to variable
-echo \fn2hex(\%x) ; Display variable's value in hex
-.\%x ::= \fhex2n(\%a) + 2 : Ditto
-echo \fn2hex(\%x)
-.\%x ::= \fhex2n(\%a) | \fhex2n(ffff) ; Similarly for logical OR
-echo \fn2hex(\%x)
-.\%x ::= \fhex2n(\%a) & \fhex2n(ffff) ; and logical AND
-echo \fn2hex(\%x)
-
- By the way, you might be tempted to use Kermit's \xnn notation to plug
- hex numbers into arithmetic expressions but this doesn't work. That
- notation is strictly for bytes (hex representation of character
- values), not for numbers.
-
-11.11. Other...
-
- Escape sequences (or any strings that contain control characters) can't
- be used as labels, GOTO targets, or SWITCH cases.
-
- [ [91]Top ] [ [92]Contents ] [ [93]C-Kermit Home ] [ [94]C-Kermit 8.0
- Overview ] [ [95]Kermit Home ]
- __________________________________________________________________
-
- C-Kermit 8.0 Unix Hints and Tips / [96]The Kermit Project /
- [97]kermit@columbia.edu / 30 June 2011
-
-References
-
- 1. http://www.columbia.edu/
- 2. mailto:kermit@columbia.edu
- 3. http://www.columbia.edu/kermit/index.html
- 4. http://www.columbia.edu/kermit/k95.html
- 5. http://www.columbia.edu/kermit/ckermit.html
- 6. http://www.columbia.edu/kermit/ckscripts.html
- 7. http://www.columbia.edu/kermit/current.html
- 8. http://www.columbia.edu/kermit/whatsnew.html
- 9. http://www.columbia.edu/kermit/faq.html
- 10. http://www.columbia.edu/kermit/support.html
- 11. http://www.columbia.edu/kermit/ckcbwr.html
- 12. http://www.columbia.edu/kermit/ckubwr.html
- 13. http://www.columbia.edu/kermit/k95.html
- 14. http://www.columbia.edu/kermit/ckermit.html
- 15. http://www.columbia.edu/kermit/ckututor.html
- 16. http://www.columbia.edu/kermit/ckcbwr.html#x0
- 17. http://www.columbia.edu/kermit/ckcbwr.html#x1
- 18. http://www.columbia.edu/kermit/ckcbwr.html#x2
- 19. http://www.columbia.edu/kermit/ckcbwr.html#x3
- 20. http://www.columbia.edu/kermit/ckcbwr.html#x4
- 21. http://www.columbia.edu/kermit/ckcbwr.html#x5
- 22. http://www.columbia.edu/kermit/ckcbwr.html#x6
- 23. http://www.columbia.edu/kermit/ckcbwr.html#x7
- 24. http://www.columbia.edu/kermit/ckcbwr.html#x8
- 25. http://www.columbia.edu/kermit/ckcbwr.html#x9
- 26. http://www.columbia.edu/kermit/ckcbwr.html#x10
- 27. http://www.columbia.edu/kermit/ckcbwr.html#x11
- 28. http://www.columbia.edu/kermit/ckcbwr.html#top
- 29. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 30. http://www.columbia.edu/kermit/ckcbwr.html#x2
- 31. http://www.columbia.edu/kermit/ckcbwr.html#top
- 32. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 33. http://www.columbia.edu/kermit/ckcbwr.html#x2
- 34. http://www.columbia.edu/kermit/ck60manual.html
- 35. http://www.columbia.edu/kermit/ckermit2.html
- 36. http://www.columbia.edu/kermit/ck60manual.html
- 37. http://www.columbia.edu/kermit/ckermit80.html#x5
- 38. http://www.columbia.edu/kermit/ckermit80.html
- 39. http://www.columbia.edu/kermit/ckermit80.html#x2.2
- 40. http://www.columbia.edu/kermit/ckermit80.html#x8.7.2
- 41. http://www.columbia.edu/kermit/ckermit80.html#x9
- 42. http://www.columbia.edu/kermit/ckcbwr.html#top
- 43. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 44. http://www.columbia.edu/kermit/ckcbwr.html#x3
- 45. http://www.columbia.edu/kermit/ckcbwr.html#x1
- 46. http://www.columbia.edu/kermit/ckcbwr.html#top
- 47. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 48. http://www.columbia.edu/kermit/ckcbwr.html#x4
- 49. http://www.columbia.edu/kermit/ckcbwr.html#x2
- 50. http://www.columbia.edu/kermit/ckcbwr.html#top
- 51. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 52. http://www.columbia.edu/kermit/ckcbwr.html#x5
- 53. http://www.columbia.edu/kermit/ckcbwr.html#x3
- 54. ftp://ftp.isi.edu/in-notes/rfc1122.txt
- 55. http://www.columbia.edu/kermit/ckcbwr.html#top
- 56. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 57. http://www.columbia.edu/kermit/ckcbwr.html#x6
- 58. http://www.columbia.edu/kermit/ckcbwr.html#x4
- 59. http://www.columbia.edu/kermit/ckcbwr.html#top
- 60. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 61. http://www.columbia.edu/kermit/ckcbwr.html#x7
- 62. http://www.columbia.edu/kermit/ckcbwr.html#x5
- 63. http://www.columbia.edu/kermit/ck60manual.html
- 64. http://www.columbia.edu/kermit/ckcbwr.html#x10
- 65. http://www.columbia.edu/kermit/ckcbwr.html#top
- 66. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 67. http://www.columbia.edu/kermit/ckcbwr.html#x8
- 68. http://www.columbia.edu/kermit/ckcbwr.html#x6
- 69. ftp://ftp.isi.edu/in-notes/rfc2217.txt
- 70. http://www.columbia.edu/kermit/ckcbwr.html#top
- 71. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 72. http://www.columbia.edu/kermit/ckcbwr.html#x9
- 73. http://www.columbia.edu/kermit/ckcbwr.html#x7
- 74. http://www.columbia.edu/kermit/ckcbwr.html#top
- 75. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 76. http://www.columbia.edu/kermit/ckcbwr.html#x10
- 77. http://www.columbia.edu/kermit/ckcbwr.html#x8
- 78. http://www.columbia.edu/kermit/ckubwr.html
- 79. http://www.columbia.edu/kermit/ckcbwr.html#top
- 80. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 81. http://www.columbia.edu/kermit/ckcbwr.html#x11
- 82. http://www.columbia.edu/kermit/ckcbwr.html#x9
- 83. http://www.columbia.edu/kermit/ck60manual.html
- 84. http://www.columbia.edu/kermit/ckermi70.htm
- 85. http://www.columbia.edu/kermit/hp48.html
- 86. http://www.columbia.edu/kermit/ckermit70.html#x4.22
- 87. http://www.columbia.edu/kermit/ckermit80.html#x15
- 88. http://www.columbia.edu/kermit/ckcbwr.html#top
- 89. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 90. http://www.columbia.edu/kermit/ckcbwr.html#x10
- 91. http://www.columbia.edu/kermit/ckcbwr.html#top
- 92. http://www.columbia.edu/kermit/ckcbwr.html#contents
- 93. http://www.columbia.edu/kermit/ckermit.html
- 94. http://www.columbia.edu/kermit/ck80.html
- 95. http://www.columbia.edu/kermit/index.html
- 96. http://www.columbia.edu/kermit/index.html
- 97. mailto:kermit@columbia.edu
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckccfg.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckccfg.txt
deleted file mode 100644
index 0185c3d..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckccfg.txt
+++ /dev/null
@@ -1,1738 +0,0 @@
-
- [1]The Columbia Crown The Kermit Project | Columbia University
- 612 West 115th Street, New York NY 10025 USA o [2]kermit@columbia.edu
- ...since 1981
- [3]Home [4]Kermit 95 [5]C-Kermit [6]Scripts [7]Current [8]New [9]FAQ
- [10]Support
-
-C-Kermit Configuration Options
-
- As of: C-Kermit 9.0.300, 30 June 2011
- This page last updated: Fri Jul 1 15:48:21 2011 (New York USA Time)
-
- IF YOU ARE READING A PLAIN-TEXT version of this document, note that
- this file is a plain-text dump of a Web page. You can visit the
- original (and possibly more up-to-date) Web page here:
-
- [11]http://www.columbia.edu/kermit/ckccfg.html
-
- [ [12]C-Kermit Home ] [ [13]Kermit Home ]
-
- CONTENTS
-
- 1. [14]FILE TRANSFER
- 2. [15]SERIAL COMMUNICATION SPEEDS
- 3. [16]FULLSCREEN FILE TRANSFER DISPLAY
- 4. [17]CHARACTER SETS
- 5. [18]APC EXECUTION
- 6. [19]PROGRAM SIZE
- 7. [20]MODEM DIALING
- 8. [21]NETWORK SUPPORT
- 9. [22]EXCEPTION HANDLING
- 10. [23]SECURITY FEATURES
- 11. [24]ENABLING SELECT()
- 12. [25]I/O REDIRECTION
- 13. [26]FLOATING-POINT NUMBERS, TIMERS, AND ARITHMETIC
- 14. [27]SPECIAL CONFIGURATIONS
- I. [28]SUMMARY OF COMPILE-TIME OPTIONS
-
- OVERVIEW
-
- This document describes configuration options for C-Kermit (5A and
- later). The major topics covered include program size (and how to
- reduce it), how to include or exclude particular features, notes on
- serial-port, modem, and network support, and a list of C-Kermit's
- compile-time options.
-
- For details about your particular operating system, also see the
- system-specific installation instructions file, such as the
- [29]C-Kermit Installation Instructions for Unix.
-
- [ [30]C-Kermit Home ] [ [31]Kermit Home ]
-
- 1. FILE TRANSFER
-
- [ [32]Top ] [ [33]Contents ] [ [34]Next ] [ [35]Previous ]
-
- Prior to version 7.0, C-Kermit was always built with the most
- conservative Kermit file-transfer protocol defaults on every platform:
- no control-character prefixing, 94-byte packets, and a window size of
- 1.
-
- Starting in version 7.0, fast settings are the default. To override
- these at compile time, include:
-
- -DNOFAST
-
- in the C compiler CFLAGS. Even with the fast defaults, C-Kermit
- automatically drops down to whatever window and packet sizes requested
- by the other Kermit, if these are smaller, when sending files (except
- for control-character unprefixing, which is not negotiated, and which
- is now set to CAUTIOUS rather than NONE at startup). C-Kermit's
- settings prevail when it is receiving.
-
- [ [36]C-Kermit Home ] [ [37]Kermit Home ]
-
- 2. SERIAL COMMUNICATION SPEEDS
-
- [ [38]Top ] [ [39]Contents ] [ [40]Next ] [ [41]Previous ]
-
- As of 6 September 1997, a new simplified mechanism for obtaining the
- list of legal serial interface speeds is in place:
-
- * If the symbol TTSPDLIST is defined, the system-dependent routine
- ttspdlist() is called at program initialization to obtain the list.
- * This symbol should be defined only for C-Kermit implementations
- that have implemented the ttspdlist() function, typically in the
- ck?tio.c module. See [42]ckutio.c for an example.
- * TTSPDLIST is automatically defined in [43]ckcdeb.h for UNIX. Add
- the appropriate #ifdefs for other platforms when the corresponding
- ttspdlist() functions are filled in.
- * If TTSPDLIST is (or normally would be) defined, the old code
- (described below) can still be selected by defining NOTTSPDLIST.
-
- The ttspdlist() function can obtain the speeds in any way that works.
- For example, based simply on #ifdef Bnnnn..#endif (in UNIX). Although
- it might be better to actually check each speed against the currently
- selected hardware interface before allowing it in the array, there is
- usually no passive and/or reliable and safe way to do this, and so it's
- better to let some speeds into the array that might not work, than it
- is to erroneously exclude others. Speeds that don't work are caught
- when the SET SPEED command is actually given.
-
- Note that this scheme does not necessarily rule out split speed
- operation, but effectively it does in C-Kermit as presently constituted
- since there are no commands to set input and output speed separately
- (except the special case "set speed 75/1200").
-
- Note that some platforms, notably AIX 4.2 and 4.3, implement high
- serial speeds transparently to the application, e.g. by mapping 50 bps
- to 57600 bps, and so on.
-
- That's the whole deal. When TTSPDLIST is not defined, the following
- applies:
-
- Speeds are defined in two places: the SET SPEED keyword list in the
- command parser (as of this writing, in the [44]ckuus3.c source file),
- and in the system- dependent communications i/o module, ck?tio.c,
- functions ttsspd() (set speed) and ttgspd() (get speed). The following
- speeds are assumed to be available in all versions:
-
- 0, 110, 300, 600, 1200, 2400, 4800, 9600
-
- If one or more of these speeds is not supported by your system, you'll
- need to change the source code (this has never happened so far). Other
- speeds that are not common to all systems have Kermit-specific symbols:
-
- Symbol Symbol
- Speed (bps) to enable to disable
- 50 BPS_50 NOB_50
- 75 BPS_75 NOB_75
- 75/1200 BPS_7512 NOB_7512
- 134.5 BPS_134 NOB_134
- 150 BPS_150 NOB_150
- 200 BPS_200 NOB_200
- 1800 BPS_1800 NOB_1800
- 3600 BPS_3600 NOB_3600
- 7200 BPS_7200 NOB_7200
- 14400 BPS_14K NOB_14K
- 19200 BPS_19K NOB_19K
- 28800 BPS_28K NOB_28K
- 38400 BPS_38K NOB_38K
- 57600 BPS_57K NOB_57K
- 76800 BPS_76K NOB_76K
- 115200 BPS_115K NOB_155K
- 230400 BPS_230K NOB_230K
- 460800 BPS_460K NOB_460K
- 921600 BPS_921K NOB_921K
-
- The [45]ckcdeb.h header file contains default speed configurations for
- the many systems that C-Kermit supports. You can override these
- defaults by (a) editing ckcdeb.h, or (b) defining the appropriate
- enabling and/or disabling symbols on the CC command line, for example:
-
- -DBPS_14400 -DNOB_115200
-
- or the "make" command line, e.g.:
-
- make blah "KFLAGS=-DBPS_14400 -DNOB_115200"
-
- Note: some speeds have no symbols defined for them, because they have
- never been needed: 12.5bps, 45.5bps, 20000bps, etc. These can easily be
- added if required (but they will work only if the OS supports them).
-
- IMPORTANT: Adding one of these flags at compile time does not
- necessarily mean that you will be able to use that speed. A particular
- speed is usable only if your underlying operating system supports it.
- In particular, it needs to be defined in the appropriate system header
- file (e.g. in UNIX, cd to /usr/include and grep for B9600 in *.h and
- sys/*.h to find the header file that contains the definitions for the
- supported speeds), and supported by the serial device driver, and of
- course by the physical device itself.
-
- ALSO IMPORTANT: The list of available speeds is independent of how they
- are set. The many UNIXes, for example, offer a wide variety of APIs
- that are BSD-based, SYSV-based, POSIX-based, and purely made up. See
- the ttsspd(), ttgspd(), and ttspdlist() routines in [46]ckutio.c for
- illustrations.
-
- The latest entries in this horserace are the tcgetspeed() and
- ttsetspeed() routines found in UnixWare 7. Unlike other methods, they
- accept the entire range of integers (longs really) as speed values,
- rather than certain codes, and return an error if the number is not, in
- fact, a legal speed for the device/driver in question. In this case,
- there is no way to build a list of legal speeds at compile time, since
- no Bnnnn symbols are defined (except for "deprecated, legacy"
- interfaces like ioctl()) and so the legal speed list must be enumerated
- in the code -- see ttspdlist() in [47]ckutio.c.
-
- [ [48]C-Kermit Home ] [ [49]Kermit Home ]
-
- 3. FULLSCREEN FILE TRANSFER DISPLAY
-
- [ [50]Top ] [ [51]Contents ] [ [52]Next ] [ [53]Previous ]
-
- New to edit 180 is support for an MS-DOS-Kermit-like local-mode full
- screen file transfer display, accomplished using the curses library, or
- something equivalent (for example, the Screen Manager on DEC VMS). To
- enable this feature, include the following in your CFLAGS:
-
- -DCK_CURSES
-
- and then change your build procedure (if necessary) to include the
- necessary libraries. For example, in Unix these are usually "curses" or
- "ncurses" (and more recently, "ncursesw" and "slang"), perhaps also
- "termcap", "termlib", or "tinfo":
-
- "LIBS= -lcurses -ltermcap"
- "LIBS= -lcurses -ltermlib"
- "LIBS= -lncurses"
- "LIBS= -ltermlib"
- "LIBS= -ltinfo"
-
- "man curses" for further information, and search through the Unix
- [54]makefile for "CK_CURSES" to see many examples, and also see the
- relevant sections of the [55]Unix C-Kermit Installation Instructions,
- particularly Sections [56]4 and [57]9.2.
-
- There might still be a complication. Some implementations of curses
- reserve the right to alter the buffering on the output file without
- restoring it afterwards, which can leave Kermit's command processing in
- a mess when the prompt comes back after a fullscreen file transfer
- display. The typical symptom is that characters you type at the prompt
- after a local-mode file transfer (i.e. after seeing the curses
- file-transfer display) do not echo until you press the Return (Enter)
- key. If this happens to you, try adding
-
- -DCK_NEWTERM
-
- to your makefile target (see comments in screenc() in [58]ckuusx.c for
- an explanation).
-
- If that doesn't fix the problem, then use a bigger hammer and replace
- -DCK_NEWTERM with:
-
- -DNONOSETBUF
-
- which tells Kermit to force stdout to be unbuffered so CBREAK mode can
- work.
-
- In SCO Xenix and SCO UNIX, there are two separate curses libraries, one
- based on termcap and the other based on terminfo. The default library,
- usually terminfo, is established when the development system is
- installed. To manually select terminfo (at compile time):
-
- compile -DM_TERMINFO and link -ltinfo
-
- and to manually select termcap:
-
- compile -DM_TERMCAP and link -ltcap -ltermlib
-
- <curses.h> looks at M_TERMINFO and M_TERMCAP to decide which header
- files to use. /usr/lib/libcurses.a is a link to either libtinfo.a or
- libtcap.a. The C-Kermit compilation options must agree with the version
- of the curses library that is actually installed.
-
- NOTE: If you are doing an ANSI-C compilation and you get compile time
- warnings like the following:
-
- Warning: function not declared in ckuusx.c: wmove, printw, wclrtoeol,
- wclear, wrefresh, endwin, etc...
-
- it means that your <curses.h> file does not contain prototypes for
- these functions. The warnings should be harmless.
-
- New to edit 190 is the ability to refresh a messed-up full-screen
- display, e.g. after receiving a broadcast message. This depends on the
- curses package including the wrefresh() and clearok() functions and the
- curscr variable. If your version has these, or has code to simulate
- them, then add:
-
- -DCK_WREFRESH
-
- The curses and termcap libraries add considerable size to the program
- image (e.g. about 20K on a SUN-4, 40K on a 386). On some small systems,
- such as the AT&T 6300 PLUS, curses can push Kermit over the edge...
- even though it compiles, loads, and runs correctly, its increased size
- apparently makes it swap constantly, slowing it down to a crawl, even
- when the curses display is not in use. Some new makefile targets have
- been added to take care of this (e.g. sys3upcshcc), but similar tricks
- might be necessary in other cases too.
-
- On the curses file-transfer display, just below the "thermometer", is a
- running display of the transfer rate, as a flat quotient of file
- characters per elapsed seconds so far. You can change this to an
- average that gives greater weight to recent history (0.25 *
- instantaneous cps + 0.75 * historical cps) by adding -DCPS_WEIGHTED to
- your CFLAGS (sorry folks, this one is not worth a SET command). You can
- choose a second type of weighted average in which the weighting smooths
- out progressively as the transfer progresses by adding -DCPS_VINCE to
- -DCPS_WEIGHTED.
-
- An alternative to curses is also available at compile time, but should
- be selected if your version of Kermit is to be run in local mode only
- in an ANSI terminal environment, for example on a desktop workstation
- that has an ANSI console driver. To select this option in place of
- curses, define the symbol MYCURSES:
-
- -DMYCURSES
-
- instead of CK_CURSES. The MYCURSES option uses built-in ANSI (VT100)
- escape sequences, and depends upon your terminal or console driver to
- interpret them correctly.
-
- In some C-Kermit builds, we replace printf() via #define printf...
- However, this can cause conflicts with the [n]curses header files.
- Various hacks are required to get around this -- see [59]ckutio.c,
- [60]ckufio.c, [61]ckuusx.c, [62]ckucmd.c, etc.
-
- [ [63]C-Kermit Home ] [ [64]Kermit Home ]
-
- 4. CHARACTER SETS
-
- [ [65]Top ] [ [66]Contents ] [ [67]Next ] [ [68]Previous ]
-
- Since version 5A, C-Kermit has included support for conversion of
- character sets for Western European languages (i.e. languages that
- originated in Western Europe, but are now also spoken in the Western
- Hemisphere and other parts of the world), via ISO 8859-1 Latin Alphabet
- 1, for Eastern European languages (ISO Latin-2), Hebrew (and Yiddish),
- Greek, and Cyrillic-alphabet languages (ISO Latin/Cyrillic). Many file
- (local) character sets are supported: ISO 646 7-bit national sets, IBM
- code pages, Apple, DEC, DG, NeXT, etc.
-
- To build Kermit with no character-set translation at all, include
- -DNOCSETS in the CFLAGS. To build with no Latin-2, add -DNOLATIN2. To
- build with no Cyrillic, add -DNOCYRIL. To omit Hebrew, add -DNOHEBREW.
- If -DNOCSETS is *not* included, you'll always get LATIN1. To build with
- no KANJI include -DNOKANJI. There is presently no way to include
- Latin-2, Cyrillic, Hebrew, or Kanji without also including Latin-1.
-
- [69]Unicode support was added in C-Kermit 7.0, and it adds a fair
- amount of tables and code (and this is only a "Level 1" implementation
- -- a higher level would also require building in the entire Unicode
- database). On a PC with RH 5.2 Linux, building C-Kermit 7.0, we get the
- following sizes:
-
- NOCSETS NOUNICODE NOKANJI Before After
- [ ] [ ] [ ] 1329014 (Full)
- [ ] [ ] [ X ] 1325686 (Unicode but no Kanji)
- [ ] [ X ] [ ] 1158837 (All charsets except Unicode)
- [ X ] [ x ] [ x ] 1090845 (NOCSETS implies the other two)
-
- Note, by the way, that NOKANJI without NOUNICODE only removes the
- non-Unicode Kanji sets (Shift-JIS, EUC-JP, JIS-7, etc). Kanji is still
- representable in UCS-2 and UTF-8.
-
- [ [70]C-Kermit Home ] [ [71]Kermit Home ]
-
- 5. APC EXECUTION
-
- [ [72]Top ] [ [73]Contents ] [ [74]Next ] [ [75]Previous ]
-
- The Kermit CONNECT and INPUT commands are coded to execute Application
- Program Command escape sequences from the host:
-
- <ESC>_<text><ESC>\
-
- where <text> is a C-Kermit command, or a list of C-Kermit commands
- separated by commas, up to about 1K in length.
-
- To date, this feature has been included in the OS/2, Windows, VMS,
- OS-9, and Unix versions, for which the symbol:
-
- CK_APC
-
- is defined automatically in [76]ckuusr.h. For OS/2, APC is enabled at
- runtime by default, for UNIX it is disabled. It is controlled by the
- SET TERMINAL APC command. Configuring APC capability into a version
- that gets it by default (because CK_APC is defined in [77]ckuusr.h) can
- be overridden by including:
-
- -DNOAPC
-
- on the CC command line.
-
- C-Kermit's autodownload feature depends on the APC feature, so
- deconfiguring APC also disables autodownload (it doesn't use APC escape
- sequences, but uses the APC switching mechanism internally).
-
- [ [78]C-Kermit Home ] [ [79]Kermit Home ]
-
- 6. PROGRAM SIZE
-
- [ [80]Top ] [ [81]Contents ] [ [82]Next ] [ [83]Previous ]
-
- SECTION CONTENTS
-
- 6.1. [84]Feature Selection
- 6.2. [85]Changing Buffer Sizes
- 6.3. [86]Other Size-Related Items
- 6.4. [87]Space/Time Tradeoffs
-
- (Also see [88]Section 4)
-
- Each release of C-Kermit is larger than the last. On some computers
- (usually old ones) the size of the program prevents it from being
- successfully linked and loaded. On some others (also usually old ones),
- it occupies so much memory that it is constantly swapping or paging. In
- such cases, you can reduce C-Kermit's size in various ways, outlined in
- this section. The following options can cut down on the program's size
- at compile time by removing features or changing the size of storage
- areas.
-
- If you are reading this section because all you want is a small, fast,
- quick-to-load Kermit file-transfer application for the remote end of
- your connection, and the remote end is Unix based, take a look at
- G-Kermit:
-
- [89]http://www.columbia.edu/kermit/gkermit.html
-
- 6.1. Feature Selection
-
- Features can be added or removed by defining symbols on the CC (C
- compiler) command line. "-D" is the normal CC directive to define a
- symbol so, for example, "-DNODEBUG" defines the symbol NODEBUG. Some C
- compilers might use different syntax, e.g. "-d NODEBUG" or
- "/DEFINE=NODEBUG". For C compilers that do not accept command-line
- definitions, you can put the corresponding #define statements in the
- file ckcsym.h, for example:
-
- #define NODEBUG
-
- The following table shows the savings achieved when building C-Kermit
- 8.0 (Beta.04) with selected feature-deselection switches on an
- Intel-based PC with Red Hat Linux 7.0 and gcc 2.96. The sizes are for
- non-security builds. The fully configured non-security build is 2127408
- bytes.
-
- Option Size Savings Effect
- NOICP 545330 74.4% No Interactive Command Parser (command-line only)
- NOLOCAL 1539994 27.6% No making connections.
- NOXFER 1551108 27.1% No file transfer.
- IKSDONLY 1566608 26.4% Internet Kermit Server only.
- NOCSETS 1750097 17.7% No character-set conversion.
- NOSPL 1800293 15.4% No Script Programming Language.
- NONET 1808575 15.0% No making network connections.
- NOUNICODE 1834426 13.8% No Unicode character-set conversion.
- NOHELP 1837877 13.6% No built-in help text.
- NODEBUG 1891669 11.1% No debug log.
- NOFRILLS 1918966 9.8% No "frills".
- NOFTP 1972496 7.3% No FTP client.
- NODIAL 1984488 6.7% No automatic modem dialing.
- NOPUSH 2070184 2.7% No shell access, running external programs, etc.
- NOIKSD 2074129 2.5% No Internet Kermit Server capability.
- NOHTTP 2082610 2.1% No HTTP client.
- NOFLOAT 2091332 1.7% No floating-point arithmetic.
- NOCHANNELIO 2095978 1.5% No FOPEN/FREAD/FWRITE/FCLOSE, etc.
- MINIDIAL 2098035 1.4% No built-in support for many kinds of modems.
- NOSERVER 2098987 1.3% No server mode.
- NOSEXP 2105898 1.0% No S-Expressions.
- NOPTY 2117743 0.5% No pseudoterminal support.
- NORLOGIN 2121089 0.3% No RLOGIN connections.
- NOOLDMODEMS 2124038 0.2% No built-in support for old kinds of modems.
- NOSSH 2125696 0.1% No SSH command.
-
- And here are a few combinations
-
- Options Size Savings Effect
- NODEBUG NOICP NOCSETS NOLOCAL 281641 86.7% No debug log, parser,
- character sets, or making connections.
- NOICP NOCSETS NOLOCAL 376468 82.3% No parser, character sets, or making
- connections.
- NOICP NOCSETS NONET 427510 79.9% No parser, character sets, or network
- connections.
- NOSPL NOCSETS 1423784 33.1% No script language, or character sets.
-
- -DNOFRILLS removes various command synonyms; the following top-level
- commands: CLEAR, DELETE, DISABLE, ENABLE, GETOK, MAIL, RENAME, TYPE,
- WHO; and the following REMOTE commands: KERMIT, LOGIN, LOGOUT, PRINT,
- TYPE, WHO.
-
- 6.2. Changing Buffer Sizes
-
- Most modern computers have so much memory that (a) there is no need to
- scrimp and save, and (b) C-Kermit, even when fully configured, is
- relatively small by today's standards.
-
- Two major factors affect Kermit's size: feature selection and buffer
- sizes. Buffer sizes affect such things as the maximum length for a
- Kermit packet, the maximum length for a command, for a macro, for the
- name of a macro, etc. Big buffer sizes are used when the following
- symbol is defined:
-
- BIGBUFOK
-
- as it is by default for most modern platforms (Linux, AIX 4 and 5,
- HP-UX 10 and 11, Solaris, etc) in [90]ckuusr.h. If your build does not
- get big buffers automatically (SHOW FEATURES tells you), you can
- include them by rebuilding with BIGBUFOK defined; e.g. in Unix:
-
- make xxxx KFLAGS=-DBIGBUFOK
-
- where xxxx is the makefile target. On the other hand, if you want to
- build without big buffers when they normally would be selected, use:
-
- make xxxx KFLAGS=-DNOBIGBUF
-
- There are options to control Kermit's packet buffer allocations. The
- following symbols are defined in [91]ckcker.h in such a way that you
- can override them by redefining them in CFLAGS:
-
- -DMAXSP=xxxx - Maximum send-packet length.
- -DMAXRP=xxxx - Maximum receive-packet length.
- -DSBSIZ=xxxx - Total allocation for send-packet buffers.
- -DRBSIZ=xxxx - Total allocation for receive-packet buffers.
-
- The defaults depend on the platform.
-
- Using dynamic allocation (-DDYNAMIC) reduces storage requirements for
- the executable program on disk, and allows more and bigger packets at
- runtime. This has proven safe over the years, and now most builds (e.g.
- all Unix, VMS, Windows, and OS/2 ones) use dynamic memory allocation by
- default. If it causes trouble, however, then omit the -DDYNAMIC option
- from CFLAGS, or add -DNODYNAMIC.
-
- 6.3. Other Size-Related Items
-
- To make Kermit compile and load successfully, you might have to change
- your build procedure to:
-
- a. Request a larger ("large" or "huge") compilation / code-generation
- model. This is needed for 16-bit PC-based UNIX versions (most or
- all of which fail to build C-Kermit 7.0 and later anyway). This is
- typically done with a -M and/or -F switch (see your cc manual or
- man page for details).
- b. Some development systems support overlays. If the program is too
- big to be built as is, check your loader manual ("man ld") to see
- if an overlay feature is available. See the 2.10/2.11 BSD example
- in the UNIX makefile. (Actually, as of version 7.0, C-Kermit is too
- big to build, period, even with overlays, on 2.xx BSD).
- c. Similarly, some small and/or segment-based architectures support
- "code mapping", which is similar to overlays (PDP11-based VENIX
- 1.0, circa 1984, was an example). See the linker documentation on
- the affected platform.
-
- It is also possible to reduce the size of the executable program file
- in several other ways:
-
- a. Include the -O (optimize) compiler switch if it isn't already
- included in your "make" entry (and if it works!). If your compiler
- supports higher levels of optimization (e.g. -O2 or higher number,
- -Onolimit (HP-UX), etc), try them; the greater the level of
- optimization, the longer the compilation and more likely the
- compiler will run out of memory. The latter eventuality, some
- compilers also provide command-line options to allocate more memory
- for the optimizer, like "-Olimit number" in Ultrix.
- b. If your platform supports shared libraries, change the make entry
- to take advantage of this feature. The way to do this is, of
- course, platform dependent; see the NeXT makefile target for an
- example. some platforms (like Solaris) do it automatically and give
- you no choice. But watch out: executables linked with shared
- libraries are less portable than statically linked executables.
- c. Strip the program image after building ("man strip" for further
- info), or add -s to the LNKFLAGS (UNIX only). This strips the
- program of its symbol table and relocation information.
- d. Move character strings into a separate file. See the 2.11 BSD
- target for an example.
-
- 6.4. Space/Time Tradeoffs
-
- There are more than 6000 debug() statements in the program. If you want
- to save both space (program size) and time (program execution time),
- include -DNODEBUG in the compilation. If you want to include debugging
- for tracking down problems, omit -DNODEBUG from the make entry. But
- when you include debugging, you have two choices for how it's done. One
- definition defines debug() to be a function call; this is cheap in
- space but expensive in execution. The other defines debug as "if
- (deblog)" and then the function call, to omit the function call
- overhead when the debug log is not active. But this adds a lot of space
- to the program. Both methods work, take your choice; IFDEBUG is
- preferred if memory is not a constraint but the computer is likely to
- be slow. The first method is the default, i.e. if nothing is done to
- the CFLAGS or in [92]ckcdeb.h (but in some cases, e.g. VMS, it is). To
- select the second method, include -DIFDEBUG in the compilation (and
- don't include -DNODEBUG).
-
- [ [93]C-Kermit Home ] [ [94]Kermit Home ]
-
- 7. MODEM DIALING
-
- [ [95]Top ] [ [96]Contents ] [ [97]Next ] [ [98]Previous ]
-
- -DNODIAL removes automatic modem dialing completely, including the
- entire [99]ckudia.c module, plus all commands that refer to dialing in
- the various ckuus*.c modules.
-
- -DMINIDIAL leaves the DIAL and related commands (SET/SHOW MODEM,
- SET/SHOW DIAL) intact, but removes support for all types of modems
- except CCITT, Hayes, Unknown, User-defined, Generic-high-speed, and
- None (= Direct). The MINIDIAL option cuts the size of the dial module
- approximately in half. Use this option if you have only Hayes or CCITT
- modems and don't want to carry the baggage for the other types.
-
- A compromise between full dialer support and MINIDIAL is obtained by
- removing support for "old" modems -- all the strange non-Hayes
- compatible 1200 and 2400 bps modems that C-Kermit has been carrying
- around since 1985 or so. To remove support for these modems, add
- -DNOOLDMODEMS to CFLAGS at compilation time.
-
- Finally, if you keep support for old modems, you will notice that their
- names appear on the "set modem ?" menu. That's because their names are,
- by default, "visible". But the list is confusing to the younger
- generation, who have only heard of modems from the V.32bis-and-later
- era. If you want to be able to use old modems, but don't want their
- names cluttering up menus, add this to CFLAGS:
-
- -DM_OLD=1
-
- [ [100]C-Kermit Home ] [ [101]Kermit Home ]
-
- 8. NETWORK SUPPORT
-
- [ [102]Top ] [ [103]Contents ] [ [104]Next ] [ [105]Previous ]
-
- SECTION CONTENTS
-
- 8.1. [106]TCP/IP
- 8.2. [107]X.25
- 8.3. [108]Other Networks
-
- C-Kermit supports not only serial-port and modem connections, but also
- TCP/IP and X.25 network connections. Some versions support other
- network types too like DECnet, LAT, NETBIOS, etc. If you define the
- following symbol:
-
- NONET
-
- then all network support is compiled away.
-
- 8.1. TCP/IP
-
- SUBSECTION CONTENTS
-
- 8.1.1. [109]Firewalls
- 8.1.2. [110]Compilation and Linking Problems
- 8.1.3. [111]Enabling Host Address Lists
- 8.1.4. [112]Enabling Telnet NAWS
- 8.1.5. [113]Enabling Incoming TCP/IP Connections
- 8.1.6. [114]Disabling SET TCP Options
-
- C-Kermit's TCP/IP features require the Berkeley sockets library or
- equivalent, generally available on any Unix system, as well as in
- Windows 9x/NT, OS/2, VMS, AOS/VS, VOS, etc. The TCP/IP support includes
- built-in TELNET, FTP, and HTTP protocol. To select TCP/IP support,
- include -DTCPSOCKET in your makefile target's CFLAGS, or (in VMS) the
- appropriate variant (e.g. -DWOLLONGONG, -DMULTINET, -DEXCELAN,
- -DWINTCP, etc).
-
- The VMS and/or early Unix third-party TCP/IP products are often
- incompatible with each other, and sometimes with different versions of
- themselves. For example, Wollongong reportedly put header files in
- different directories for different UNIX versions:
-
- * in.h can be in either /usr/include/sys or /user/include/netinet.
- * telnet.h can be in either /usr/include/arpa or
- /user/include/netinet.
- * inet.h can be in either /usr/include/arpa or /user/include/sys.
-
- In cases like this, use the -I cc command-line option when possible;
- otherwise it's better to make links in the file system than it is to
- hack up the C-Kermit source code. Suppose, for example, Kermit is
- looking for telnet.h in /usr/include/arpa, but on your computer it is
- in /usr/include/netinet. Do this (as root, or get the system
- administrator to do it):
-
- cd /usr/include/arpa
- ln /usr/include/netinet/telnet.h telnet.h
-
- ("man ln" for details about links.)
-
- The network support for TCP/IP and X.25 is in the source files
- [115]ckcnet.h, [116]ckctel.c, [117]ckctel.c, [118]ckctel.h,
- [119]ckcftp.c, with miscellaneous SHOW commands, etc, in the various
- ckuus*.c modules, plus code in the ck*con.c or ckucns.c (CONNECT
- command) and several other modules to detect TELNET negotiations, etc.
-
- Within the TCPSOCKET code, some socket-level controls are included if
- TCPSOCKET is defined in the C-Kermit CFLAGS and SOL_SOCKET is defined
- in in the system's TCP-related header files, such as <sys/socket.h>.
- These are:
-
- SET TCP KEEPALIVE
- SET TCP LINGER
- SET TCP RECVBUF
- SET TCP SENDBUF
-
- In addition, if TCP_NODELAY is defined, the following command is also
- enabled:
-
- SET TCP NODELAY (Nagle algorithm)
-
- See the [120]C-Kermit user documentation for descriptions of these
- commands.
-
- 8.1.1. Firewalls
-
- There exist various types of firewalls, set up to separate users of an
- internal TCP/IP network ("Intranet") from the great wide Internet, but
- then to let selected users or services get through after all.
-
- One firewall method is called SOCKS, in which a proxy server allows
- users inside a firewall to access the outside world, based on a
- permission list generally stored in a file. SOCKS is enabled in one of
- two ways. First, the standard sockets library is modified to handle the
- firewall, and then all the client applications are relinked (if
- necessary, i.e. if the libraries are not dynamically loaded) with the
- modified sockets library. The APIs are all the same, so the
- applications do not need to be recoded or recompiled.
-
- In the other method, the applications must be modified to call
- replacement routines, such as Raccept() instead of accept(), Rbind()
- instead of bind(), etc, and then linked with a separate SOCKS library.
- This second method is accomplished (for SOCKS4) in C-Kermit by
- including -DCK_SOCKS in your CFLAGS, and also adding:
-
- -lsocks
-
- to LIBS, or replacing -lsockets with -lsocks (depending on whether the
- socks library also includes all the sockets entry points).
-
- For SOCKS5, use -DCK_SOCKS5.
-
- Explicit firewall support can, in general, not be a standard feature or
- a feature that is selected at runtime, because the SOCKS library tends
- to be different at each site -- local modifications abound.
-
- The ideal situation occurs when firewalls are supported by the first
- method, using dynamically linked sockets-replacement libraries; in this
- case, all your TCP/IP client applications negotiate the firewall
- transparently.
-
- 8.1.2. Compilation and Linking Problems
-
- If you get a compilation error in [121]ckcnet.c, with a complaint like
- "incompatible types in assignment", it probably has something to do
- with the data type your system uses for the inet_addr() function, which
- is declared (usually) in <arpa/inet.h>. Kermit uses "unsigned long"
- unless the symbol INADDRX is defined, in which case "struct inaddr" is
- used instead. Try adding -DINADDRX to CFLAGS in your make entry, and if
- that fixes the problem, please send a report to kermit@columbia.edu.
-
- Compilation errors might also have to do with the data type used for
- getsockopt() and setsockopt() option-length field. This is normally an
- int, but sometimes it's a short, a long, or an unsigned any of those,
- or a size_t. To fix the compilation problem, add -DSOCKOPT_T=xxx to the
- CFLAGS in your makefile target, where xxx is the appropriate type (use
- "man getsockopt" or grep through your system/network header files to
- find the needed type).
-
- 8.1.3. Enabling Host Address Lists
-
- When you give Kermit an IP host name, it calls the socket routine
- gethostbyname() to resolve it. gethostbyname() returns a hostent
- struct, which might or might not not include a list of addresses; if it
- does, then if the first one fails, Kermit can try the second one, and
- so on. However, this will only work if the symbol "h_addr" is a macro
- defined as "h_addr_list[0]", usually in netdb.h. If it is, then you can
- activate this feature by defining the following symbol in CFLAGS:
-
- HADDRLIST
-
- 8.1.4. Enabling Telnet NAWS
-
- The Telnet Negotiation About Window Size (NAWS) option requires the
- ability to find out the terminal screen's dimensions. E.g. in Unix, we
- need something like ioctl(0, TIOCGWINSZ, ...). If your version of
- Kermit was built with NAWS capability, SHOW VERSIONS includes CK_NAWS
- among the compiler options. If it doesn't, you can add it by defining
- CK_NAWS at compile time. Then, if the compiler or linker complain about
- undefined or missing symbols, or there is no complaint but SHOW
- TERMINAL fails to show reasonable "Rows =, Columns =" values, then take
- a look at (or write) the appropriate ttgwsiz() routine. On the other
- hand, if CK_NAWS is defined by default for your system (in
- [122]ckcnet.h), but causes trouble, you can override this definition by
- including the -DNONAWS switch on your CC command line, thus disabling
- the NAWS feature.
-
- This appears to be needed at least on the AT&T 3B2, where in
- [123]ckutio.c, the routine ttgwsiz() finds that the TIOCGWINSZ symbol
- is defined but lacks definitions for the corresponding winsize struct
- and its members ws_col and ws_row.
-
- The UNIX version of C-Kermit also traps SIGWINCH, so it can send a NAWS
- to the Telnet server any time the local console terminal window size
- changes, e.g. when you stretch it with a mouse. The SIGWINCH-trapping
- code is enabled if SIGWINCH is defined (i.e. in signal.h). If this code
- should cause problems, you can disable it without disabling the NAWS
- feature altogether, by defining NOSIGWINCH at compile time.
-
- 8.1.5. Enabling Incoming TCP/IP Connections
-
- This feature lets you "set host * port" and wait for an incoming
- connection on the given port. This feature is enabled automatically at
- compile if TCPSOCKET is defined and SELECT is also defined. But watch
- out, simply defining SELECT on the cc command line does not guarantee
- successful compilation or linking (see [124]Section 11).
-
- If you want to disable incoming TCP/IP connections, then build C-Kermit
- with:
-
- -DNOLISTEN
-
- 8.1.6. Disabling SET TCP Options
-
- The main reason for this is because of header file / prototype
- conflicts at compile time regarding get- / setsockopt(). If you can't
- fix them (without breaking other builds), add the following in CFLAGS:
-
- -DNOTCPOPTS
-
- 8.2. X.25
-
- X.25 support requires (a) a Sun, (b) the SunLink product (libraries and
- header files), and (c) an X.25 connection into your Sun. Similarly (in
- C-Kermit 7.0 or later) Stratus VOS and IBM AIX.
-
- In UNIX, special makefile targets sunos4x25 and sunos41x25 (for SUNOS
- 4.0 and 4.1, respectively), or aix41x25, are provided to build in this
- feature, but they only work if conditions (a)-(c) are met. To request
- this feature, include -DSUNX25 (or -DIBMX25) in CFLAGS.
-
- SUNX25 (or -DIBMX25) and TCPSOCKET can be freely mixed and matched, and
- selected by the user at runtime with the SET NETWORK TYPE command or
- SET HOST switches.
-
- 8.3. Other Networks
-
- Support for other networking methods -- NETBIOS, LAT, Named Pipes, etc
- -- is included in ck*net.h and ck*net.c for implementations (such as
- Windows or OS/2) where these methods are supported.
-
- Provision is made in the organization of the modules, header files,
- commands, etc, for addition of new network types such as DECnet, X.25
- for other systems (HP-UX, VMS, etc), and so on. Send email to
- [125]kermit@columbia.edu if you are willing and able to work on such a
- project.
-
- [ [126]C-Kermit Home ] [ [127]Kermit Home ]
-
- 9. EXCEPTION HANDLING
-
- [ [128]Top ] [ [129]Contents ] [ [130]Next ] [ [131]Previous ]
-
- The C language setjmp/longjmp mechanism is used for handling
- exceptions. The jump buffer is of type jmp_buf, which almost everywhere
- is typedef'd as an array, in which case you should have no trouble
- compiling the exception-handling code. However, if you are building
- C-Kermit in/for an environment where jmp_buf is something other than an
- array (e.g. a struct), then you'll have to define the following symbol:
-
- JBNOTARRAY
-
- [ [132]C-Kermit Home ] [ [133]Kermit Home ]
-
- 10. SECURITY FEATURES
-
- [ [134]Top ] [ [135]Contents ] [ [136]Next ] [ [137]Previous ]
-
- Security, in the sense of secure authentication and strong encryption,
- can be built into versionf of C-Kermit for which the appropriate
- libraries and header files are available (Kerberos IV, Kerberos V,
- OpenSSL, SRP), as explained in great detail in the Kermit Security
- Reference
- . The following symbols govern C-Kermit's security features at build
- time:
-
- NO_AUTHENTICATION
- Means do not configure any TELNET AUTHENTICATION support. It
- implies NO_ENCRYPTION and undefines any of the auth and encrypt
- types. It does not undefine CK_SSL even though builds with
- CK_SSL cannot succeed without CK_AUTHENTICATION. (This will be
- supported in a future release. It will be needed to allow
- C-Kermit to be built only as an FTP client.)
-
- NO_KERBEROS
- Means do not compile in any KERBEROS support when
- CK_AUTHENTICATION has been defined.
-
- NO_SRP
- Do not compile in any SRP support when CK_AUTHENTICATION has
- been defined.
-
- NO_SSL
- Do not compile in any SSL/TLS support
-
- NO_ENCRYPTION
- Do not compile in any Telnet encryption support. It does not
- affect the use of SSL/TLS
-
- NOSSH
- Do not compile in any SSH support whether internal or external
-
- CK_AUTHENTICATION
- Telnet AUTHENTICATION support. (Also, required if SSL/TLS
- support is desired.) On most platforms this does not autodefine
- any authentication mechanisms such as Kerberos V, Kerberos IV,
- SRP, ... Those need to be defined separately.
-
- CK_KERBEROS
- Defined automatically when KRB4, KRB5, or KRB524 are defined.
- Implies that some version of Kerberos is in use.
-
- KRB4
- Should be defined when Kerberos IV support is desired.
-
- KRB5
- Should be defined when Kerberos V support is desired.
-
- KRB524
- Should be defined if both Kerberos V and Kerberos IV are used
- and the Kerberos IV support is provided by the MIT Kerberos IV
- compatibility library in the current Kerberos 5 distribution.
-
- KRB5_U2U
- Should be defined if KRB5 is defined and Kerberos 5 User to User
- mode is desired.
-
- HEIMDAL
- Should be defined if Kerberos V support is provided by HEIMDAL.
- Support for this option is not complete in C-Kermit 8.0. Anyone
- interested in working on this should contact kermit-support.
-
- CK_SRP
- Should be defined if SRP support is desired.
-
- CK_ENCRYPTION
- Should be defined if TELNET ENCRYPTION option support is
- desired. This option does not define any particular encryption
- types. That should be done by defining CK_DES or CK_CAST.
-
- CK_DES
- Should be defined if either DES or 3DES Telnet Encryption option
- support is desired.
-
- LIBDES
- If CK_DES is defined and DES support is being provided by either
- Eric Young's libdes.a or OpenSSL 0.9.6x or earlier, this option
- must be defined. If it is not defined, it will be assumed that
- DES support is provided by the MIT Kerberos IV libraries.
-
- CK_CAST
- Should be defined if CAST Telnet Encryption option support is
- desired
-
- CK_SSL
- Should be defined if SSL/TLS support (OpenSSL) is desired.
-
- SSL_KRB5
- If KRB5 is defined, and OpenSSL is built to support the Kerberos
- 5 ciphers, then you should define SSL_KRB5
-
- NOSSLKRB5
- If you are using OpenSSL 0.9.7 or higher and do not wish to
- build with support for Kerberos 5 TLS ciphers, this option must
- be defined.
-
- ZLIB
- If you are using OpenSSL 0.9.6 or higher and it has been
- compiled with support for ZLIB compression, this option should
- be defined to enable Kermit to properly enable the use of
- compression.
-
- SSHCMD
- Defined for C-Kermit to enable the use of external SSH clients
- from the Kermit command language
-
- SSHBUILTIN
- Defined for Kermit implementations that have integrated SSH
- support. Currently only Windows.
-
- ANYSSH
- Defined if either SSHCMD or SSHBUILTIN are defined.
-
- CK_SNDLOC
- Telnet Send Location support.
-
- NOSNDLOC
- Do not include Telnet Send Location support.
-
- CK_XDISPLOC
- Telnet X-Display Location support. Determines if the X-Display
- location information is sent to the Telnet server either via
- Telnet XDISPLOC or NEW-ENV options.
-
- NOXDISPLOC
- Do not include Telnet X-Display Location support.
-
- CK_FORWARD_X
- Telnet Forward X Windows Session Data option. Used to protect
- the privacy and integrity of X Windows Sessions when secure
- telnet sessions are in use.
-
- NOFORWARDX
- Do not include Telnet Forward X Windows Session Data option.
-
- Besides the strong forms of security listed above, C-Kermit also
- embodies various internal security features, including:
-
- NOPUSH
- Compiling with the NOPUSH symbol defined removes all the "shell
- escape" features from the program, including the PUSH, RUN, and
- SPAWN commands, the "!" and "@" command prefixes, OPEN !READ,
- OPEN !WRITE, job control (including the SUSPEND command), the
- REDIRECT command, shell/DCL escape from CONNECT mode, as well as
- the server's execution of REMOTE HOST commands (and, of course,
- the ENABLE HOST command). Add NODISPO to also prevent acceptance
- of incoming MAIL or REMOTE PRINT files. For UNIX, also be sure
- to read [138]Section 11 of the [139]Unix C-Kermit Installation
- Instructions. about set[ug]id configuration. Additional
- restrictions can be enforced when in server mode; read about the
- DISABLE command in the user manual.
-
- NOCCTRAP
- Compiling with NOCCTRAP prevents the trapping of SIGINT by
- Kermit. Thus if the user generates a SIGINT signal (e.g. by
- typing the system's interrupt character), Kermit will exit
- immediately, rather than returning to its prompt.
-
- NOPUSH and NOCCTRAP together allow Kermit to be run from restricted
- shells, preventing access to system functions.
-
- [ [140]C-Kermit Home ] [ [141]Kermit Home ]
-
- 11. ENABLING SELECT()
-
- [ [142]Top ] [ [143]Contents ] [ [144]Next ] [ [145]Previous ]
-
- Kermit works best if it can do nonblocking reads, nondestructive input
- buffer checking, and millisecond sleeps. All of these functions can be
- accomplished by the select() function, which, unfortunately, is not
- universally available. Furthermore, select() is required if incoming
- TCP/IP connections are to be supported.
-
- select() was introduced with Berkeley UNIX, rejected by AT&T for System
- V, but is gradually creeping in to all UNIX versions (and other
- operating systems too) by virtue of its presence in the sockets
- library, which is needed for TCP/IP. AT&T SVID for System V R4 includes
- select(), but that does not mean that all SVR4 implementations have it.
-
- Furthermore, even when select() is available, it might work only on
- socket file descriptors, but not on others like serial ports, pipes,
- etc. For example, in AOS/VS and BeOS, it works only with file
- descriptors that were created by socket() and opened by connect() or
- accept().
-
- Other alternatives include poll() and rdchk(). Only one of these three
- functions should be included. The following symbols govern this:
-
- SELECT Use select() (BSD, or systems with sockets libraries)
- CK_POLL Use poll() (System V)
- RDCHK Use rdchk() (SCO XENIX and UNIX)
-
- If your system supports the select() function, but your version of
- C-Kermit does not, try adding:
-
- -DSELECT
-
- to the CFLAGS, and removing -DRDCHK or -DCK_POLL if it is there. If you
- get compilation errors, some adjustments to ck*tio.c and/or ck*net.c
- might be needed; search for SELECT (uppercase) in these files (note
- that there are several variations on the calling conventions for
- select()).
-
- Various macros and data types need to be defined in order to use
- select(). Usually these are picked up from <types.h> or <sys/types.h>.
- But on some systems, they are in <sys/select.h>. In that case, add the
- following:
-
- -DSELECT_H
-
- to the CFLAGS to tell C-Kermit to #include <sys/select.h>. A good
- indication that you need to do this would be if you get compile-time
- complaints about "fd_set" or "FD_SET" not being declared or defined.
-
- In UNIX, the use of select() vs fork() in the CONNECT command is
- independent of the above considerations, and is governed by choosing a
- particular makefile target.
-
- As of C-Kermit 7.0, select() is also the preferred control mechanism
- for the CONNECT command. Unfortunately, the structures used by the
- original UNIX CONNECT command, based on fork(), and those used by
- select(), are so different, it was not practical to implement them both
- in one module. So the select()-based CONNECT command module for UNIX is
- [146]ckucns.c, and the fork-based one remains [147]ckucon.c. To choose
- the fork-based one, which is more portable (but slower and more
- fragile), use "wermit" as the make target. To choose the select-based
- one, use "xermit". Only do this if you can verify that the CONNECT
- command works on serial connections and PIPE connections as well as TCP
- connections.
-
- The select()-based Unix CONNECT module, ckucns.c, must be used if
- encryption is to be done, since the fork() version (ckucon.c) loses
- its ability to share vital state information between the two forks.
- Also note that the select() version is superior in many other ways
- too. For example, it recovers better from exterior killing, forced
- disconnections, etc, plus it goes faster.
-
- SHOW VERSIONS tells whether the CONNECT module uses fork() or select().
-
- C-Kermit 8.0 adds learned script capability, which depends on select().
- All the "wermit" based targets (as opposed to "xermit") had NOLEARN
- added to them. Whenever changing a target over from wermit to xermit,
- also remember to remove NOLEARN.
-
- [ [148]C-Kermit Home ] [ [149]Kermit Home ]
-
- 12. I/O REDIRECTION
-
- [ [150]Top ] [ [151]Contents ] [ [152]Next ] [ [153]Previous ]
-
- The REDIRECT command allows a local program to be run with its i/o
- redirected over the communications connection. Your version of C-Kermit
- has a REDIRECT command if it was built with the following CFLAG:
-
- -DCK_REDIR
-
- This, in turn, is possible only if the underlying API is there. In the
- case of UNIX this is just the wait() system call, so all UNIX versions
- get this feature as of 6.0.192 (earlier versions needed a <sys/wait.h>
- header file defining the symbols WIFEXITED and WEXITSTATUS).
-
- As of version 7.0, file transfer can be done using pipes and filters.
- To enable this feature, #define PIPESEND (and fill in the code). To
- disable on systems where it is normally enabled, define NOPIPESEND.
- This feature is, of course, also disabled by building with NOPUSH (or
- giving the "nopush" command at runtime).
-
- C-Kermit 7.0 also adds the PIPE and SET HOST /COMMAND commands, which
- provide another form of redirection. This feature is selected with
- -DNETCMD. CK_RDIR must also be defined, since the same mechanisms are
- used internally.
-
- [ [154]C-Kermit Home ] [ [155]Kermit Home ]
-
- 13. FLOATING-POINT NUMBERS, TIMERS, AND ARITHMETIC
-
- [ [156]Top ] [ [157]Contents ] [ [158]Next ] [ [159]Previous ]
-
- Floating-point support was added in C-Kermit 7.0.
-
- Floating-point numbers are enabled internally, at least for use in
- high-precision file-transfer timers and statistics, unless the
- following symbol is defined at compile time:
-
- -DNOFLOAT
-
- This might be necessary on old PCs that do not have built-in
- floating-point hardware.
-
- When NOFLOAT is not defined, the following symbol tells which
- floating-point type to use:
-
- -DCKFLOAT=xxxx
-
- The value is either "double" (normal for 32- and 16-bit architectures)
- or "float" (normal for 64-bit architectures).
-
- C-Kermit can be configured to use high-precision file-transfer timers
- for more accurate statistics. This feature is enabled with:
-
- -DGFTIMER
-
- and disabled with:
-
- -DNOGFTIMER
-
- If you try to build with -DGFTIMER but you get compilation errors,
- either fix them (and send email to kermit@columbia.edu telling what you
- did), or else give up and use -DNOGFTIMER (or -DNOFLOAT) instead. Hint:
- depending on your machine architecture, you might have better luck
- using double than float as the data type for floating-point numbers, or
- vice versa. Look in [160]ckcdeb.h for the CKFLOAT definition.
-
- Floating-point arithmetic is also supported in the script programming
- language. First via the \fpp...() functions, such as \fppadd(), which
- adds two floating-point numbers, second in S-Expressions. Addition,
- subtraction, multiplication, and division are always available. But
- other functions such as logs, raising to powers, sines and cosines,
- etc, require the C Math library. To include user-level floating-point
- math you must put:
-
- -DFNFLOAT
-
- and in Unix you must link with the Math library:
-
- LIBS=".... -lm"
-
- In K95 and VMS, FNFLOAT is defined automatically if CKFLOAT is defined.
- In Unix, however, FNFLOAT must be added to each makefile target
- individually, because of the special linking instructions that must
- also be added to each target.
-
- Note: S-Expressions require FNFLOAT.
-
- [ [161]C-Kermit Home ] [ [162]Kermit Home ]
-
- 14. SPECIAL CONFIGURATIONS
-
- [ [163]Top ] [ [164]Contents ] [ [165]Previous ]
-
- As of C-Kermit 7.0, if you build C-Kermit normally, but with -DNOICP
- (No Interactive Command Parser), you get a program capable of making
- serial connections (but not dialing) and network connections (if
- TCPSOCKET or other network option included), and can also transfer
- files using Kermit protocol, but only via autodownload/upload.
- Furthermore, if you call the executable "telnet", it will act like
- Telnet -- using the command-line options. However, in this case there
- is nothing to escape back to, so if you type Ctrl-\c, it just prints a
- message to this effect.
-
- You can also build C-Kermit with -DNOXFER, meaning omit all the
- file-transfer features. This leaves you with a scriptable
- communications program that is considerably smaller than the full
- C-Kermit.
-
- [ [166]C-Kermit Home ] [ [167]Kermit Home ]
-
- APPENDIX I: SUMMARY OF COMPILE-TIME OPTIONS
-
- [ [168]Top ] [ [169]Contents ]
-
- These are the symbols that can be specified on the cc command line,
- listed alphabetically. Others are used internally, including those
- taken from header files, those defined by the compiler itself, and
- those inferred from the ones given below. Kermit's SHOW VERSIONS
- command attempts to display most of these. See [170]ckcdeb.h and
- [171]ckcnet.h for inference rules. For example SVR3 implies ATTSV,
- MULTINET implies TCPSOCKET, and so on.
-
- Here is the complete list of the Kermit-specific compile-time switches:
-
- ACUCNTRL Select BSD 4.3-style acucntrl() bidirectional tty control.
- aegis Build for Apollo Aegis (predefined on Apollo systems).
- AIX370 Build for IBM AIX/370 for IBM mainframes.
- AIXESA Build for IBM AIX/ESA for IBM mainframes.
- AIXPS2 Build for IBM AIX 3.0 for PS/2 series (never formally released).
- AIXRS Build for IBM AIX 3.x on RS/6000.
- AIX41 Build for IBM AIX 4.x on RS/6000.
- AMIGA Build for Commodore Amiga with Intuition OS.
- ATT6300 Build for AT&T 6300 PLUS.
- ATT7300 Build for AT&T 7300 UNIX PC (3B1).
- ATTSV Build for AT&T System III or V UNIX.
- AUX Build for Apple A/UX for the Macintosh.
- BIGBUFOK OK to use big buffers - "memory is not a problem"
- BPS_xxxx Enable SET SPEED xxxx
- BSD29 Build for BSD 2.9 or 2.10.
- BSD4 Build for BSD 4.2.
- BSD41 Build for BSD 4.1.
- BSD43 Build for BSD 4.3.
- BSD44 Build for BSD 4.4.
- C70 Build for BBN C/70.
- CIE Build for CIE Systems 680/20.
- CKCONINTB4CB Work around prompt-disappears after escape back from
- CONNECT.
- CKLEARN Build with support for learned scripts.
- CKLOGDIAL Enable connection log.
- CKMAXPATH Maximum length for a fully qualified filename.
- CKREGEX (misnomer) Include [...] or {xxx,xxx,xxx} matching in
- ckmatch().
- CKSYSLOG Enable syslogging.
- CK_ANSIC Enable ANSI C constructs - prototypes, etc.
- CK_ANSILIBS Use header files for ANSI C libraries.
- CK_APC Enable APC execution by CONNECT module.
- CK_CURSES Enable fullscreen file transfer display.
- CK_DSYSINI Use system-wide init file, with name supplied by Kermit.
- CK_DTRCD DTR/CD flow control is available.
- CK_FAST Build with fast Kermit protocol defaults.
- CK_FORK_SIG UNIX only: signal() number for CONNECT module forks.
- CK_IFRO IF REMOTE command is available (and can run in remote mode).
- CK_INI_A System-wide init file takes precedence over user's.
- CK_INI_B User's init file takes precedence over the system-wide one.
- CK_LABELED Include support for SET FILE TYPE LABELED.
- CK_LBRK This version can send Long BREAK.
- CK_LINGER Add code to turn of TCP socket "linger" parameter.
- CK_MKDIR This version has a zmkdir() command to create directories.
- CK_NAWS Include TELNET Negotiate About Window Size support.
- CK_NEWTERM Use newterm() rather than initscr() to initialize curses.
- CK_PAM Include PAM authentication (might also require -lpam).
- CK_PCT_BAR Fullscreen file transfer display should include
- "thermometer".
- CK_POLL System-V or POSIX based UNIX has poll() function.
- CK_POSIX_SIG Use POSIX signal handing: sigjmp_buf, sigsetjmp,
- siglongjmp.
- CK_READ0 read(fd,&x,0) can be used to test TCP/IP connections.
- CK_REDIR Enable the REDIRECT command.
- CK_RESEND Include the RESEND command (needs zfseek() + append).
- CK_RTSCTS RTS/CTS flow control is available.
- CK_SHADOW Include support for shadow passwords (e.g. for IKSD
- authentication).
- CK_SOCKBUF Enable TCP socket-buffer-size-increasing code.
- CK_SOCKS UNIX only: Build with socks library rather than regular
- sockets
- CK_SOCKS5 UNIX only: Build with socks 5 lib rather than regular sockets
- CK_SPEED Enable control-character unprefixing.
- CK_SYSINI="xxxxx" Quoted string to be used as system-wide init file
- name.
- CK_TIMERS Build with support for dynamically calculated packet
- timeouts.
- CK_TMPDIR This version of Kermit has an isdir() function.
- CK_TTYFD Defined on systems where the communications connection file
- descriptor (ttyfd) can be passed to other processes as a command-line
- argument via \v(ttyfd).
- CK_URL Parse URLs as well as hostnames, etc.
- CK_XONXOFF Xon/Xoff flow control available.
- CK_XYZ Include support for XYZMODEM protocols.
- CK_WREFRESH Curses package includes wrefresh(),clearok() for screen
- refresh.
- CKFLOAT=type Floating-point data type, "double" or "float".
- CKTYP_H=xxx Force include of xxx as <types.h> file.
- CLSOPN When hanging up a tty device, also close and reopen it.
- CMDDEP Maximum recursion depth for self-referential user-defined fn's.
- COHERENT Build for Mark Williams Coherent UNIX
- CONGSPD Define if this version has congspd() routine in ck?tio.c
- datageneral Build for Data General AOS/VS or AOS/VS II
- DCLPOPEN popen() is available but needs to be declared
- DEC_TCPIP Build with support for DEC TCP/IP (UCX) for (Open)VMS
- DGUX430 Build for DG/UX 4.30
- DGUX540 Build for DG/UX 5.40
- DEFPAR=x Default parity, 0, 'e', 'o', 'm', or 's'.
- DFTTY=xxx Default communications device name.
- DIRENT UNIX directory structure to be taken from <dirent.h>.
- DIRPWDRP Prompt for password in REMOTE CWD command.
- DTILDE Include UNIX ~ notation for username/home-directory
- DYNAMIC Allocate file transfer packet buffers dynamically with malloc.
- ENCORE Build for Encore Multimax computers.
- EXCELAN Build with excelan TCP/IP.
- FNFLOAT Include floating-point math functions (logs, sin, cos, exp,
- etc)
- FT18 Build for Fortune For:Pro 1.8.
- FT21 Build for Fortune For:Pro 2.1.
- GEMDOS Build for Atari ST GEMDOS.
- GFTIMER Use high-precision floating-point file-transfer timers.
- GID_T=xxx Group IDs are of type xxx (usually int, short, or gid_t).
- HADDRLIST If gethostbyname() hostent struct contains a list of
- addresses.
- HDBUUCP Build with support for Honey DanBer UUCP.
- HPUX Build for Hewlett Packard HP-UX.
- HPUX9 Build for Hewlett Packard HP-UX 9.x.
- HPUX10 Build for Hewlett Packard HP-UX 10.x.
- HWPARITY Define if this version can SET PARITY HARDWARE { EVEN, ODD...}
- I386IX Build for Interactive System V R3.
- IFDEBUG Add IF stmts "if (deblog)" before "debug()" calls.
- INADDRX TCP/IP inet_addr() type is struct inaddr, not unsigned long.
- INTERLAN Build with support for Racal/Interlan TCP/IP.
- ISDIRBUG System defs of S_ISDIR and S_ISREG have bug, define ourselves.
- ISIII Build for Interactive System III.
- IX370 Build for IBM IX/370.
- KANJI Build with Kanji character-set translation support.
- LCKDIR UUCP lock directory is /usr/spool/uucp/LCK/.
- LFDEVNO UUCP lockfile name uses device numbers, as in SVR4.
- LINUXFSSTND For Linux, use FSSTND UUCP lockfile conventions (default).
- LOCK_DIR=xxx UUCP lock directory is xxx (quoted string).
- LOCKF Use lockf() (in addition to lockfiles) on serial lines
- LONGFN BSD long filenames supported using <dir.h> and opendir().
- LYNXOS Build for Lynx OS 2.2 or later (POSIX-based).
- MAC Build for Apple Macintosh with Mac OS.
- MATCHDOT Make wildcards match filenames that start with period (.)
- MAXRP=number Maximum receive-packet length.
- MAXSP=number Maximum send-packet length.
- MDEBUG Malloc-debugging requested.
- MINIDIAL Minimum modem dialer support: CCITT, Hayes, Unknown, and None.
- MINIX Build for MINIX.
- MIPS Build for MIPS workstation.
- MULTINET Build with support for TGV MultiNet TCP/IP (VAX/VMS).
- M_UNIX Defined by SCO.
- NAP The nap() is available (conflicts with SELECT and USLEEP)
- NAPHACK The nap() call is available but only as syscall(3112,...)
- NDIR BSD long filenames supported using <ndir.h> and opendir().
- NDGPWNAM Don't declare getpwnam().
- NDSYSERRLIST Don't declare sys_errlist[].
- NEEDSELECTDEFS select() is available but we need to define FD_blah
- ourselves.
- NETCMD Build with support for SET HOST /COMMAND and PIPE commands.
- NEXT Build for NeXT Mach 1.x or 2.x or 3.0, 3.1, or 3.2.
- NEXT33 Build for NeXT Mach 3.3.
- NOANSI Disable ANSI C function prototyping.
- NOAPC Do not include CK_APC code.
- NOARROWKEYS Exclude code to parse ANSI arrow-key sequences.
- NOB_xxxx Disable SET SPEED xxxx
- NOBIGBUF Override BIGBUFOK when it is the default
- NOBRKC Don't try to refer to t_brkc or t_eof tchars structure members.
- NOCKFQHOSTNAME Exclude code to get fully qualified hostname in case it
- causes core dumps.
- NOCCTRAP Disable Control-C (SIGINT) trapping.
- NOCKSPEED Disable control-prefix removal feature (SET CONTROL).
- NOCKTIMERS Build without support for dynamic timers.
- NOCKXYZ Overrides CK_XYZ.
- NOCKREGEX Do not include [...] or {xxx,xxx,xxx} matching in ckmatch().
- NOCMDL Build with no command-line option processing.
- NOCOTFMC No Close(Open()) To Force Mode Change (UNIX version).
- NOCSETS Build with no support for character set translation.
- NOCYRIL Build with no support for Cyrillic character set translation.
- NOCYRILLIC Ditto.
- NODEBUG Build with no debug logging capability.
- NODIAL Build with no DIAL or SET DIAL commands.
- NODISPO Build to always refuse incoming MAIL or REMOTE PRINT files.
- DNODISPLAY Build with no file-transfer display.
- NOESCSEQ Build with no support for ANSI escape sequence recognition.
- NOFAST Do not make FAST Kermit protocol settings the default.
- NOFDZERO Do not use file descriptor 0 for remote-mode file transfer.
- NOFILEH Do not #include <sys/file.h>.
- NOFLOAT Don't include any floating-point data types or operations.
- NOFRILLS Build with "no frills" (this should be phased out...)
- NOFTRUNCATE Include this on UNIXes that don't have ftruncate().
- NOGETUSERSHELL Include this on UNIXes that don't have getusershell().
- NOGFTIMER Don't use high-precision floating-point file-transfer timers.
- NOHEBREW Build with no support for Hebrew character sets.
- NOHELP Build with no built-in help.
- NOIKSD Build with IKSD support excluded.
- NOINITGROUPS Include this on UNIXes that don't have initgroups().
- NOICP Build with no interactive command parser.
- NOJC Build with no support for job control (suspend).
- NOKANJI Build with no support for Japanese Kanji character sets.
- NOKVERBS Build with no support for keyboard verbs (\Kverbs).
- NOLATIN2 Build with no ISO Latin-2 character-set translation support.
- NOLEARN Build with no support for learned scripts.
- NOLINKBITS Use of S_ISLNK and _IFLNK untrustworthy; use readlink()
- instead.
- NOLOCAL Build without any local-mode features: No Making Connections.
- NOLOGDIAL Disable connection log.
- NOLOGIN Build without IKSD (network login) support.
- NOLSTAT Not OK to use lstat().
- NOMDMHUP Build without "modem-specific hangup" (e.g. ATH0) feature.
- NOMHHOST Exclude the multihomed-host TCP/IP code (if compilation
- errors)
- NOMINPUT Build without MINPUT command.
- NOMSEND Build with no MSEND command.
- NONAWS Do not include TELNET Negotiate About Window Size support.
- NONET Do not include any network support.
- NONOSETBUF (See NOSETBUF)
- NOPARSEN Build without automatic parity detection.
- NOPIPESEND Disable file transfer using pipes and filters.
- NOPOLL Override CK_POLL definition.
- NOPOPEN The popen() library call is not available.
- NOPURGE Build with no PURGE command.
- NOPUSH Build with no escapes to operating system.
- NOREALPATH In UNIX, realpath() function is not available.
- NORECALL Disable the command-recall feature.
- NOREDIRECT Disable REDIRECT command.
- NORENAME Don't use rename() system call, use link()/unlink() (UNIX).
- NORESEND Build with no RESEND command.
- NORETRY Build with no command-retry feature.
- NOSCRIPT Build with no SCRIPT command.
- NOSELECT Don't try to use select().
- NOSERVER Build with no SERVER mode and no server-related commands.
- NOSETBUF Don't make console writes unbuffered.
- NONOSETBUF DO make console writes unbuffered.
- NOSETREU setreuid() and/or setregid() not available.
- NOSHOW Build with no SHOW command (not recommended!).
- NOSIGWINCH Disable SIGWINCH signal trapping.
- NOSPL Build with no script programming language.
- NOSTAT Don't call stat() from mainline code.
- NOSYMLINK Include this for UNIXes that don't have readlink().
- NOSYSIOCTLH Do not #include <sys/ioctl.h>.
- NOSYSTIMEH Co not include <sys/time.h>.
- NOSYSLOG Disable syslogging code.
- NOTCPOPTS Build with no SET TCP options or underlying support.
- NOTLOG Build with no support for transaction logging.
- NOTM_ISDST Struct tm has no tm_isdst member.
- NOUNICODE Build with no support for Unicode character-set translation.
- NOURL Don't parse URLs
- NOUUCP Build with no UUCP lockfile support (dangerous!).
- NOWARN Make EXIT WARNING be OFF by default (otherwise it's ON).
- NOWREFRESH Override built-in definition of CK_WREFRESH (q.v.).
- NOXFER Build with no Kermit or other file-transfer protocols.
- NOXMIT Build with no TRANSMIT command.
- NOXPRINT Disables transparent print code.
- OLDMSG Use old "entering server mode" message (see [172]ckcmai.c).
- OLINUXHISPEED Build in old Linux hi-serial-speed code (for Linux <=
- 1.0).
- OPENBSD Build for OpenBSD.
- OS2 Build for OS/2.
- OSF Build for OSF/1.
- OSFPC Build for OSF/1 on a PC.
- OSF32 Digital UNIX 3.2 or later.
- OSF40 Build for Digital UNIX 4.0.
- OSF50 Build for Digital UNIX 5.0.
- OSK Build for OS-9.
- OXOS Build for Olivetti X/OS 2.3.
- PCIX Build for PC/IX
- PID_T=xxx Type for pids is xxx (normally int or pid_t).
- POSIX Build for POSIX: use POSIX header files, functions, etc.
- _POSIX_SOURCE Disable non-POSIX features.
- PROVX1 Build for Venix 1.0 on DEC Professional 3xx.
- PTX Build for Dynix/PTX
- PWID_T=xxx getpwid() type is xxx.
- RBSIZ=xxx Define overall size of receive-packet buffer (with DYNAMIC).
- RDCHK rdchk() system call is available.
- RENAME rename() system call is available (UNIX).
- RTAIX Build for AIX 2.2.1 on IBM RT PC.
- RTU Build for Masscomp / Concurrent RTU.
- SAVEDUID BSD or other non-AT&T UNIX has saved-setuid feature.
- SBSIZ=xxx Define overall size of send-packet buffer (use with DYNAMIC).
- SDIRENT Directory structure specified in <sys/dirent.h>.
- SELECT select() function available (conflicts with RDCHK and CK_POLL)
- SELECT_H Include <sys/select.h> for select()-related definitions.
- SETEUID BSD 4.4-style seteXid() functions available.
- SIG_V Type for signal() is void. Used to override normal assumption.
- SIG_I Type for signal() is int. Used to override normal assumption.
- SOCKOPT_T Override default data type for get/setsockopt() option
- length.
- SOLARIS Build for Solaris.
- SOLARIS25 Build for Solaris 2.5 or later.
- SONYNEWS Build for Sony NEWS-OS.
- STERMIOX <sys/termiox.h> is available.
- STRATUS Build for Stratus VOS.
- STRATUSX25 Include Stratus VOS X.25 support.
- SUN4S5 Build for SUNOS 4.x in the System V R3 environment.
- SUNOS4 Build for SUNOS 4.0 in the BSD environment.
- SUNOS41 Build for SUNOS 4.1 in the BSD environment.
- SUNX25 Build with support for SunLink X.25.
- SVR3 Build for AT&T System V Release 3.
- SVR3JC Allow job control support on System V Release 3 UNIX versions.
- SVR4 Build for AT&T System V Release 4.
- SW_ACC_ID UNIX only -- swap real & effective ids around access() calls.
- sxaE50 Build for PFU Compact A Series SX/A TISP.
- SYSLOGLEVEL=n Force syslogging at given level.
- SYSTIMEH Include <sys/time.h>.
- SYSUTIMEH Include <sys/utime.h> for setting file dates (88OPEN)
- TCPSOCKET Build with support for TCP/IP via Berkeley sockets library.
- TERMIOX <termiox.h> header file is available (mostly SVR4).
- TNCODE Include TELNET-specific code.
- TOWER1 Build for NCR Tower 1632 with OS 1.02.
- TRS16 Build for Tandy 16/6000.
- UID_T=xxx Type for uids is xxx (normally int or uid_t).
- UNIX Must be defined for all UNIX versions.
- UNIX351M AT&T UNIX 3.51m on the AT&T 7300 UNIX PC.
- USE_ARROWKEYS Include code to parse ANSI arrow-key sequences.
- USE_LSTAT OK to use lstat().
- USE_MEMCPY Define this if memcpy()/memset()/memmove() available.
- USE_STRERROR Define this if strerror() is available.
- USLEEP usleep() system call available (conflicts with NAP & SELECT).
- UTEK Build for Tektronix workstations with UTEK OS.
- UTIMEH Include <utime.h> for setting file dates (SVR4, POSIX)
- UTS24 Build for Amdahl UTS 2.4.
- V7 Build for Version 7 UNIX.
- VMS Build for VAX/VMS.
- VOID=xxx VOID type for functions (int or void).
- VXVE Build for CDC VX/VE 5.2.1.
- WAIT_T=xxx Type of argument passed to wait().
- WINTCP Build with Wollongong VAX/VMS TCP/IP (implies TCPSOCKET)
- WOLLONGONG Build with Wollongong UNIX TCP/IP (implies TCPSOCKET)
- XENIX Build for Xenix (SCO, Tandy, others).
- XNDIR Support for BSD long filenames via <sys/ndir.h>.
- XYZ_INTERNAL Support for XYZMODEM protocols is internal, not external.
- ZFCDAT Define this if zfcdat() function is available in Kermit.
- ZILOG Build for Zilog ZEUS.
- ZJDATE Has zjdate() function that converts date to Julian format.
- XPRINT Transparent print code included in CONNECT module.
-
- [ [173]Top ] [ [174]Contents ] [ [175]C-Kermit Home ] [ [176]Kermit
- Home ]
- __________________________________________________________________
-
-
- C-Kermit Configuration Options / [177]The Kermit Project /
- [178]kermit@columbia.edu / 30 June 2011
-
-References
-
- 1. http://www.columbia.edu/
- 2. mailto:kermit@columbia.edu
- 3. http://www.columbia.edu/kermit/index.html
- 4. http://www.columbia.edu/kermit/k95.html
- 5. http://www.columbia.edu/kermit/ckermit.html
- 6. http://www.columbia.edu/kermit/ckscripts.html
- 7. http://www.columbia.edu/kermit/current.html
- 8. http://www.columbia.edu/kermit/whatsnew.html
- 9. http://www.columbia.edu/kermit/faq.html
- 10. http://www.columbia.edu/kermit/support.html
- 11. http://www.columbia.edu/kermit/ckccfg.html
- 12. http://www.columbia.edu/kermit/ckermit.html
- 13. http://www.columbia.edu/kermit/index.html
- 14. http://www.columbia.edu/kermit/ckccfg.html#x1
- 15. http://www.columbia.edu/kermit/ckccfg.html#x2
- 16. http://www.columbia.edu/kermit/ckccfg.html#x3
- 17. http://www.columbia.edu/kermit/ckccfg.html#x4
- 18. http://www.columbia.edu/kermit/ckccfg.html#x5
- 19. http://www.columbia.edu/kermit/ckccfg.html#x6
- 20. http://www.columbia.edu/kermit/ckccfg.html#x7
- 21. http://www.columbia.edu/kermit/ckccfg.html#x8
- 22. http://www.columbia.edu/kermit/ckccfg.html#x9
- 23. http://www.columbia.edu/kermit/ckccfg.html#x10
- 24. http://www.columbia.edu/kermit/ckccfg.html#x11
- 25. http://www.columbia.edu/kermit/ckccfg.html#x12
- 26. http://www.columbia.edu/kermit/ckccfg.html#x13
- 27. http://www.columbia.edu/kermit/ckccfg.html#x14
- 28. http://www.columbia.edu/kermit/ckccfg.html#xa1
- 29. http://www.columbia.edu/kermit/ckuins.html
- 30. http://www.columbia.edu/kermit/ckermit.html
- 31. http://www.columbia.edu/kermit/index.html
- 32. http://www.columbia.edu/kermit/ckccfg.html#top
- 33. http://www.columbia.edu/kermit/ckccfg.html#contents
- 34. http://www.columbia.edu/kermit/ckccfg.html#x2
- 35. http://www.columbia.edu/kermit/ckccfg.html#x0
- 36. http://www.columbia.edu/kermit/ckermit.html
- 37. http://www.columbia.edu/kermit/index.html
- 38. http://www.columbia.edu/kermit/ckccfg.html#top
- 39. http://www.columbia.edu/kermit/ckccfg.html#contents
- 40. http://www.columbia.edu/kermit/ckccfg.html#x3
- 41. http://www.columbia.edu/kermit/ckccfg.html#x1
- 42. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 43. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h
- 44. ftp://kermit.columbia.edu/kermit/c-kermit/ckuus3.c
- 45. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h
- 46. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 47. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 48. http://www.columbia.edu/kermit/ckermit.html
- 49. http://www.columbia.edu/kermit/index.html
- 50. http://www.columbia.edu/kermit/ckccfg.html#top
- 51. http://www.columbia.edu/kermit/ckccfg.html#contents
- 52. http://www.columbia.edu/kermit/ckccfg.html#x4
- 53. http://www.columbia.edu/kermit/ckccfg.html#x2
- 54. ftp://kermit.columbia.edu/kermit/c-kermit/makefile
- 55. http://www.columbia.edu/kermit/ckuins.html
- 56. http://www.columbia.edu/kermit/ckuins.html#x4
- 57. http://www.columbia.edu/kermit/ckuins.html#x9.2
- 58. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusx.c
- 59. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 60. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 61. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusx.c
- 62. ftp://kermit.columbia.edu/kermit/c-kermit/ckucmd.c
- 63. http://www.columbia.edu/kermit/ckermit.html
- 64. http://www.columbia.edu/kermit/index.html
- 65. http://www.columbia.edu/kermit/ckccfg.html#top
- 66. http://www.columbia.edu/kermit/ckccfg.html#contents
- 67. http://www.columbia.edu/kermit/ckccfg.html#x5
- 68. http://www.columbia.edu/kermit/ckccfg.html#x3
- 69. http://www.columbia.edu/kermit/unicode.html
- 70. http://www.columbia.edu/kermit/ckermit.html
- 71. http://www.columbia.edu/kermit/index.html
- 72. http://www.columbia.edu/kermit/ckccfg.html#top
- 73. http://www.columbia.edu/kermit/ckccfg.html#contents
- 74. http://www.columbia.edu/kermit/ckccfg.html#x6
- 75. http://www.columbia.edu/kermit/ckccfg.html#x4
- 76. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusr.h
- 77. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusr.h
- 78. http://www.columbia.edu/kermit/ckermit.html
- 79. http://www.columbia.edu/kermit/index.html
- 80. http://www.columbia.edu/kermit/ckccfg.html#top
- 81. http://www.columbia.edu/kermit/ckccfg.html#contents
- 82. http://www.columbia.edu/kermit/ckccfg.html#x7
- 83. http://www.columbia.edu/kermit/ckccfg.html#x5
- 84. http://www.columbia.edu/kermit/ckccfg.html#x6.1
- 85. http://www.columbia.edu/kermit/ckccfg.html#x6.2
- 86. http://www.columbia.edu/kermit/ckccfg.html#x6.3
- 87. http://www.columbia.edu/kermit/ckccfg.html#x6.4
- 88. http://www.columbia.edu/kermit/ckccfg.html#x4
- 89. http://www.columbia.edu/kermit/gkermit.html
- 90. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusr.h
- 91. ftp://kermit.columbia.edu/kermit/c-kermit/ckcker.h
- 92. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h
- 93. http://www.columbia.edu/kermit/ckermit.html
- 94. http://www.columbia.edu/kermit/index.html
- 95. http://www.columbia.edu/kermit/ckccfg.html#top
- 96. http://www.columbia.edu/kermit/ckccfg.html#contents
- 97. http://www.columbia.edu/kermit/ckccfg.html#x8
- 98. http://www.columbia.edu/kermit/ckccfg.html#x6
- 99. ftp://kermit.columbia.edu/kermit/c-kermit/ckudia.c
- 100. http://www.columbia.edu/kermit/ckermit.html
- 101. http://www.columbia.edu/kermit/index.html
- 102. http://www.columbia.edu/kermit/ckccfg.html#top
- 103. http://www.columbia.edu/kermit/ckccfg.html#contents
- 104. http://www.columbia.edu/kermit/ckccfg.html#x9
- 105. http://www.columbia.edu/kermit/ckccfg.html#x7
- 106. http://www.columbia.edu/kermit/ckccfg.html#x8.1
- 107. http://www.columbia.edu/kermit/ckccfg.html#x8.2
- 108. http://www.columbia.edu/kermit/ckccfg.html#x8.3
- 109. http://www.columbia.edu/kermit/ckccfg.html#x8.1.1
- 110. http://www.columbia.edu/kermit/ckccfg.html#x8.1.2
- 111. http://www.columbia.edu/kermit/ckccfg.html#x8.1.3
- 112. http://www.columbia.edu/kermit/ckccfg.html#x8.1.4
- 113. http://www.columbia.edu/kermit/ckccfg.html#x8.1.5
- 114. http://www.columbia.edu/kermit/ckccfg.html#x8.1.6
- 115. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.h
- 116. ftp://kermit.columbia.edu/kermit/c-kermit/ckctel.c
- 117. ftp://kermit.columbia.edu/kermit/c-kermit/ckctel.c
- 118. ftp://kermit.columbia.edu/kermit/c-kermit/ckctel.h
- 119. ftp://kermit.columbia.edu/kermit/c-kermit/ckcftp.c
- 120. http://www.columbia.edu/kermit/ckermit.html
- 121. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.c
- 122. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.h
- 123. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 124. http://www.columbia.edu/kermit/ckccfg.html#x11
- 125. mailto:kermit@columbia.edu
- 126. http://www.columbia.edu/kermit/ckermit.html
- 127. http://www.columbia.edu/kermit/index.html
- 128. http://www.columbia.edu/kermit/ckccfg.html#top
- 129. http://www.columbia.edu/kermit/ckccfg.html#contents
- 130. http://www.columbia.edu/kermit/ckccfg.html#x10
- 131. http://www.columbia.edu/kermit/ckccfg.html#x8
- 132. http://www.columbia.edu/kermit/ckermit.html
- 133. http://www.columbia.edu/kermit/index.html
- 134. http://www.columbia.edu/kermit/ckccfg.html#top
- 135. http://www.columbia.edu/kermit/ckccfg.html#contents
- 136. http://www.columbia.edu/kermit/ckccfg.html#x11
- 137. http://www.columbia.edu/kermit/ckccfg.html#x9
- 138. http://www.columbia.edu/kermit/ckuins.html#x11
- 139. http://www.columbia.edu/kermit/ckuins.html
- 140. http://www.columbia.edu/kermit/ckermit.html
- 141. http://www.columbia.edu/kermit/index.html
- 142. http://www.columbia.edu/kermit/ckccfg.html#top
- 143. http://www.columbia.edu/kermit/ckccfg.html#contents
- 144. http://www.columbia.edu/kermit/ckccfg.html#x12
- 145. http://www.columbia.edu/kermit/ckccfg.html#x10
- 146. ftp://kermit.columbia.edu/kermit/c-kermit/ckucns.c
- 147. ftp://kermit.columbia.edu/kermit/c-kermit/ckucon.c
- 148. http://www.columbia.edu/kermit/ckermit.html
- 149. http://www.columbia.edu/kermit/index.html
- 150. http://www.columbia.edu/kermit/ckccfg.html#top
- 151. http://www.columbia.edu/kermit/ckccfg.html#contents
- 152. http://www.columbia.edu/kermit/ckccfg.html#x13
- 153. http://www.columbia.edu/kermit/ckccfg.html#x11
- 154. http://www.columbia.edu/kermit/ckermit.html
- 155. http://www.columbia.edu/kermit/index.html
- 156. http://www.columbia.edu/kermit/ckccfg.html#top
- 157. http://www.columbia.edu/kermit/ckccfg.html#contents
- 158. http://www.columbia.edu/kermit/ckccfg.html#x14
- 159. http://www.columbia.edu/kermit/ckccfg.html#x12
- 160. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h
- 161. http://www.columbia.edu/kermit/ckermit.html
- 162. http://www.columbia.edu/kermit/index.html
- 163. http://www.columbia.edu/kermit/ckccfg.html#top
- 164. http://www.columbia.edu/kermit/ckccfg.html#contents
- 165. http://www.columbia.edu/kermit/ckccfg.html#x13
- 166. http://www.columbia.edu/kermit/ckermit.html
- 167. http://www.columbia.edu/kermit/index.html
- 168. http://www.columbia.edu/kermit/ckccfg.html#top
- 169. http://www.columbia.edu/kermit/ckccfg.html#contents
- 170. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h
- 171. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.h
- 172. ftp://kermit.columbia.edu/kermit/c-kermit/ckcmai.c
- 173. http://www.columbia.edu/kermit/ckccfg.html#top
- 174. http://www.columbia.edu/kermit/ckccfg.html#contents
- 175. http://www.columbia.edu/kermit/ckermit.html
- 176. http://www.columbia.edu/kermit/index.html
- 177. http://www.columbia.edu/kermit/index.html
- 178. mailto:kermit@columbia.edu
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcdeb.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckcdeb.h
deleted file mode 100644
index 34ff008..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcdeb.h
+++ /dev/null
@@ -1,6607 +0,0 @@
-/* C K C D E B . H */
-
-/*
-Mon Aug 23 09:22:05 2010
-
- NOTE TO CONTRIBUTORS: This file, and all the other C-Kermit files, must be
- compatible with C preprocessors that support only #ifdef, #else, #endif,
- #define, and #undef. Please do not use #if, logical operators, or other
- later-model preprocessor features in any of the portable C-Kermit modules.
- You can, of course, use these constructions in platform-specific modules
- when you know they are supported.
-*/
-
-/*
- This file is included by all C-Kermit modules, including the modules
- that aren't specific to Kermit (like the command parser and the ck?tio and
- ck?fio modules). It should be included BEFORE any other C-Kermit header
- files. It specifies format codes for debug(), tlog(), and similar
- functions, and includes any necessary definitions to be used by all C-Kermit
- modules, and also includes some feature selection compile-time switches, and
- also system- or compiler-dependent definitions, plus #includes and prototypes
- required by all C-Kermit modules.
-*/
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- Etymology: The name of this file means "C-Kermit Common-C-Language Debugging
- Header", because originally it contained only the formats (F000-F111) for
- the debug() and tlog() functions. Since then it has grown to include all
- material required by all other C-Kermit modules, including the non-Kermit
- specific ones. In other words, this is the one header file that is
- guaranteed to be included by all C-Kermit source modules.
-*/
-
-#ifndef CKCDEB_H /* Don't include me more than once. */
-#define CKCDEB_H
-
-#ifdef OS2
-#include "ckoker.h"
-#else /* OS2 */
-/* Unsigned numbers */
-
-#ifndef USHORT
-#define USHORT unsigned short
-#endif /* USHORT */
-
-#ifndef UINT
-#define UINT unsigned int
-#endif /* UINT */
-
-#ifndef ULONG
-#define ULONG unsigned long
-#endif /* ULONG */
-#endif /* OS2 */
-
-#ifdef MACOSX10 /* Mac OS X 1.0 */
-#ifndef MACOSX /* implies Mac OS X */
-#define MACOSX
-#endif /* MACOSX */
-#endif /* MACOSX10 */
-
-#ifdef MACOSX /* Mac OS X */
-#ifndef BSD44 /* implies 4.4 BSD */
-#define BSD44
-#endif /* BSD44 */
-#endif /* MACOSX */
-
-#ifdef SCO_OSR505 /* SCO 3.2v5.0.5 */
-#ifndef SCO_OSR504 /* implies SCO 3.2v5.0.4 */
-#define SCO_OSR504
-#endif /* SCO_OSR504 */
-#endif /* SCO_OSR505 */
-
-#ifdef SCO_OSR504 /* SCO 3.2v5.0.4 */
-#ifndef CK_SCOV5 /* implies SCO 3.2v5.0 */
-#define CK_SCOV5
-#endif /* CK_SCOV5 */
-#include <sys/types.h> /* To sidestep header-file mess */
-#endif /* SCO_OSR504 */
-
-#ifdef CK_SCOV5
-#ifndef ANYSCO
-#define ANYSCO
-#endif /* ANYSCO */
-#endif /* CK_SCOV5 */
-
-#ifdef UNIXWARE
-#ifndef ANYSCO
-#define ANYSCO
-#endif /* ANYSCO */
-#endif /* UNIXWARE */
-
-#ifndef MINIX /* Minix versions */
-#ifdef MINIX315
-#define MINIX
-#else
-#ifdef MINIX3
-#define MINIX
-#else
-#ifdef MINIX2
-#define MINIX
-#endif /* MINIX2 */
-#endif /* MINIX3 */
-#endif /* MINIX315 */
-#endif /* MINIX */
-
-#ifdef CK_SCO32V4 /* SCO 3.2v4 */
-#ifndef ANYSCO
-#define ANYSCO
-#endif /* ANYSCO */
-#ifndef XENIX
-#define XENIX
-#endif /* XENIX */
-#ifndef SVR3
-#define SVR3
-#endif /* SVR3 */
-#ifndef DIRENT
-#define DIRENT
-#endif /* DIRENT */
-#ifndef RENAME
-#define RENAME
-#endif /* RENAME */
-#ifndef SVR3JC
-#define SVR3JC
-#endif /* SVR3JC */
-#ifndef CK_RTSCTS
-#define CK_RTSCTS
-#endif /* CK_RTSCTS */
-#ifndef PID_T
-#define PID_T pid_t
-#endif /* PID_T */
-#ifndef PWID_T
-#define PWID_T int
-#endif /* PWID_T */
-#endif /* CK_SCO32V4 */
-
-#ifdef NOICP /* If no command parser */
-#ifndef NOSPL /* Then no script language either */
-#define NOSPL
-#endif /* NOSPL */
-#ifndef NOCSETS /* Or characer sets */
-#define NOCSETS
-#endif /* NOCSETS */
-#ifndef NOFTP /* Or FTP client */
-#define NOFTP
-#endif /* NOFTP */
-#endif /* NOICP */
-
-/* Built-in makefile entries */
-
-#ifdef SOLARIS11 /* Solaris 11 implies 10 */
-#ifndef SOLARIS10
-#define SOLARIS10
-#endif /* SOLARIS10 */
-#endif /* SOLARIS11 */
-
-#ifdef SOLARIS10 /* Solaris 10 implies 9 */
-#ifndef SOLARIS9
-#define SOLARIS9
-#endif /* SOLARIS9 */
-#endif /* SOLARIS10 */
-
-#ifdef SOLARIS9 /* Solaris 9 implies 8 */
-#ifndef SOLARIS8
-#define SOLARIS8
-#endif /* SOLARIS8 */
-#endif /* SOLARIS9 */
-
-#ifdef SOLARIS8 /* Solaris 8 implies 7 */
-#ifndef SOLARIS7
-#define SOLARIS7
-#endif /* SOLARIS7 */
-#endif /* SOLARIS8 */
-
-#ifdef SOLARIS7 /* Solaris 7 implies 2.6 */
-#ifndef SOLARIS26
-#define SOLARIS26
-#endif /* SOLARIS26 */
-#endif /* SOLARIS7 */
-
-#ifdef SOLARIS26 /* Solaris 2.6 implies 2.5 */
-#ifndef SOLARIS25
-#define SOLARIS25
-#endif /* SOLARIS25 */
-#endif /* SOLARIS26 */
-
-#ifdef SOLARIS25 /* Solaris 2.5 implies Solaris */
-#ifndef SOLARIS
-#define SOLARIS
-#endif /* SOLARIS */
-#ifndef POSIX /* And POSIX */
-#define POSIX
-#endif /* POSIX */
-#ifndef CK_WREFRESH /* And this (curses) */
-#define CK_WREFRESH
-#endif /* CK_WREFRESH */
-#endif /* SOLARIS25 */
-
-#ifdef SOLARIS24 /* Solaris 2.4 implies Solaris */
-#ifndef SOLARIS
-#define SOLARIS
-#endif /* SOLARIS */
-#endif /* SOLARIS24 */
-
-#ifdef SOLARIS /* Solaris gets "POSIX" RTS/CTS API */
-#ifdef POSIX
-#ifndef POSIX_CRTSCTS
-#define POSIX_CRTSCTS
-#endif /* POSIX_CRTSCTS */
-#endif /* POSIX */
-#ifndef SVR4
-#define SVR4
-#endif /* SVR4 */
-#ifndef STERMIOX
-#define STERMIOX
-#endif /* STERMIOX */
-#ifndef SELECT
-#define SELECT
-#endif /* SELECT */
-#ifndef FNFLOAT
-#define FNFLOAT
-#endif /* FNFLOAT */
-#ifndef DIRENT
-#define DIRENT
-#endif /* DIRENT */
-#ifndef BIGBUFOK
-#define BIGBUFOK
-#endif /* BIGBUFOK */
-#ifndef CK_NEWTERM
-#define CK_NEWTERM
-#endif /* CK_NEWTERM */
-#endif /* SOLARIS */
-
-#ifdef SUN4S5 /* Sun-4 System V environment */
-#ifndef SVR3 /* implies System V R3 or later */
-#define SVR3
-#endif /* SVR3 */
-#endif /* SUN4S5 */
-#ifdef SUNOS41 /* SUNOS41 implies SUNOS4 */
-#ifndef SUNOS4
-#define SUNOS4
-#endif /* SUNOS4 */
-#endif /* SUNOS41 */
-
-#ifdef SUN4S5 /* Sun-4 System V environment */
-#ifndef SVR3 /* implies System V R3 or later */
-#define SVR3
-#endif /* SVR3 */
-#endif /* SUN4S5 */
-
-#ifdef SUNOS41 /* SUNOS41 implies SUNOS4 */
-#ifndef SUNOS4
-#define SUNOS4
-#endif /* SUNOS4 */
-#endif /* SUNOS41 */
-
-#ifdef SUNOS4 /* Built-in SUNOS4 makefile entry */
-#ifndef UNIX
-#define UNIX
-#endif /* UNIX */
-#ifndef BSD4
-#define BSD4
-#endif /* BSD4 */
-#ifndef NOSETBUF
-#define NOSETBUF
-#endif /* NOSETBUF */
-#ifndef DIRENT
-#define DIRENT
-#endif /* DIRENT */
-#ifndef NONET
-#ifndef TCPSOCKET
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#endif /* NONET */
-#ifndef SAVEDUID
-#define SAVEDUID
-#endif /* SAVEDUID */
-#ifndef DYNAMIC
-#define DYNAMIC
-#endif /* DYNAMIC */
-#endif /* SUNOS4 */
-
-#ifdef SOLARIS /* Built in makefile entry */
-#ifndef NOSETBUF /* for Solaris 2.x */
-#define NOSETBUF
-#endif /* NOSETBUF */
-#ifndef NOCURSES
-#ifndef CK_CURSES
-#define CK_CURSES
-#endif /* CK_CURSES */
-#endif /* NOCURSES */
-#ifndef CK_NEWTERM
-#define CK_NEWTERM
-#endif /* CK_NEWTERM */
-#ifndef DIRENT
-#define DIRENT
-#endif /* DIRENT */
-#ifndef NONET
-#ifndef TCPSOCKET
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#endif /* NONET */
-#ifndef UNIX
-#define UNIX
-#endif /* UNIX */
-#ifndef SVR4
-#define SVR4
-#endif /* SVR4 */
-#ifndef HADDRLIST
-#define HADDRLIST
-#endif /* HADDRLIST */
-#ifndef STERMIOX
-#define STERMIOX
-#endif /* STERMIOX */
-#ifndef SELECT
-#define SELECT
-#endif /* SELECT */
-#ifndef DYNAMIC
-#define DYNAMIC
-#endif /* DYNAMIC */
-#ifndef NOUUCP
-#ifndef HDBUUCP
-#define HDBUUCP
-#endif /* HDBUUCP */
-#endif /* NOUUCP */
-#endif /* SOLARIS */
-
-/* Features that can be eliminated from a no-file-transfer version */
-
-#ifdef NOXFER
-#ifndef NOFTP
-#define NOFTP
-#endif /* NOFTP */
-#ifndef OS2
-#ifndef NOCURSES /* Fullscreen file-transfer display */
-#define NOCURSES
-#endif /* NOCURSES */
-#endif /* OS2 */
-#ifndef NOCKXYZ /* XYZMODEM support */
-#define NOCKXYZ
-#endif /* NOCKXYZ */
-#ifndef NOCKSPEED /* Ctrl-char unprefixing */
-#define NOCKSPEED
-#endif /* NOCKSPEED */
-#ifndef NOSERVER /* Server mode */
-#define NOSERVER
-#endif /* NOSERVER */
-#ifndef NOCKTIMERS /* Dynamic packet timers */
-#define NOCKTIMERS
-#endif /* NOCKTIMERS */
-#ifndef NOPATTERNS /* File-type patterns */
-#define NOPATTERNS
-#endif /* NOPATTERNS */
-#ifndef NOSTREAMING /* Streaming */
-#define NOSTREAMING
-#endif /* NOSTREAMING */
-#ifndef NOIKSD /* Internet Kermit Service */
-#define NOIKSD
-#endif /* NOIKSD */
-#ifndef NOPIPESEND /* Sending from pipes */
-#define NOPIPESEND
-#endif /* NOPIPESEND */
-#ifndef NOAUTODL /* Autodownload */
-#define NOAUTODL
-#endif /* NOAUTODL */
-#ifndef NOMSEND /* MSEND */
-#define NOMSEND
-#endif /* NOMSEND */
-#ifndef NOTLOG /* Transaction logging */
-#define NOTLOG
-#endif /* NOTLOG */
-#ifndef NOCKXXCHAR /* Packet character doubling */
-#define NOCKXXCHAR
-#endif /* NOCKXXCHAR */
-#endif /* NOXFER */
-
-#ifdef NOICP /* No Interactive Command Parser */
-#ifndef NODIAL /* Implies No DIAL command */
-#define NODIAL
-#endif /* NODIAL */
-#ifndef NOCKXYZ /* and no external protocols */
-#define NOCKXYZ
-#endif /* NOCKXYZ */
-#endif /* NOICP */
-
-#ifndef NOIKSD
-#ifdef IKSDONLY
-#ifndef IKSD
-#define IKSD
-#endif /* IKSD */
-#ifndef NOLOCAL
-#define NOLOCAL
-#endif /* NOLOCAL */
-#ifndef NOPUSH
-#define NOPUSH
-#endif /* NOPUSH */
-#ifndef TNCODE
-#define TNCODE
-#endif /* TNCODE */
-#ifndef TCPSOCKET
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#ifndef NETCONN
-#define NETCONN
-#endif /* NETCONN */
-#ifdef SUNX25
-#undef SUNX25
-#endif /* SUNX25 */
-#ifdef IBMX25
-#undef IBMX25
-#endif /* IBMX25 */
-#ifdef STRATUSX25
-#undef STRATUSX25
-#endif /* STRATUSX25 */
-#ifdef CK_NETBIOS
-#undef CK_NETBIOS
-#endif /* CK_NETBIOS */
-#ifdef SUPERLAT
-#undef SUPERLAT
-#endif /* SUPERLAT */
-#ifdef NPIPE
-#undef NPIPE
-#endif /* NPIPE */
-#ifdef NETFILE
-#undef NETFILE
-#endif /* NETFILE */
-#ifdef NETCMD
-#undef NETCMD
-#endif /* NETCMD */
-#ifdef NETPTY
-#undef NETPTY
-#endif /* NETPTY */
-#ifdef RLOGCODE
-#undef RLOGCODE
-#endif /* RLOGCODE */
-#ifdef NETDLL
-#undef NETDLL
-#endif /* NETDLL */
-#ifndef NOSSH
-#undef NOSSH
-#endif /* NOSSH */
-#ifndef NOFORWARDX
-#define NOFORWARDX
-#endif /* NOFORWARDX */
-#ifndef NOBROWSER
-#define NOBROWSER
-#endif /* NOBROWSER */
-#ifndef NOHTTP
-#define NOHTTP
-#endif /* NOHTTP */
-#ifndef NOFTP
-#define NOFTP
-#endif /* NOFTP */
-#ifndef NO_COMPORT
-#define NO_COMPORT
-#endif /* NO_COMPORT */
-#endif /* IKSDONLY */
-#endif /* NOIKSD */
-
-/* Features that can be eliminated from a remote-only version */
-
-#ifdef NOLOCAL
-#ifndef NOFTP
-#define NOFTP
-#endif /* NOFTP */
-#ifndef NOHTTP
-#define NOHTTP
-#endif /* NOHTTP */
-#ifndef NOSSH
-#define NOSSH
-#endif /* NOSSH */
-#ifndef NOTERM
-#define NOTERM
-#endif /* NOTERM */
-#ifndef NOCURSES /* Fullscreen file-transfer display */
-#define NOCURSES
-#endif /* NOCURSES */
-#ifndef NODIAL
-#define NODIAL
-#endif /* NODIAL */
-#ifndef NOSCRIPT
-#define NOSCRIPT
-#endif /* NOSCRIPT */
-#ifndef NOSETKEY
-#define NOSETKEY
-#endif /* NOSETKEY */
-#ifndef NOKVERBS
-#define NOKVERBS
-#endif /* NOKVERBS */
-#ifndef NOXMIT
-#define NOXMIT
-#endif /* NOXMIT */
-#ifdef CK_CURSES
-#undef CK_CURSES
-#endif /* CK_CURSES */
-#ifndef IKSDONLY
-#ifndef NOAPC
-#define NOAPC
-#endif /* NOAPC */
-#ifndef NONET
-#define NONET
-#endif /* NONET */
-#endif /* IKSDONLY */
-#endif /* NOLOCAL */
-
-#ifdef NONET
-#ifdef NETCONN
-#undef NETCONN
-#endif /* NETCONN */
-#ifdef TCPSOCKET
-#undef TCPSOCKET
-#endif /* TCPSOCKET */
-#ifndef NOTCPOPTS
-#define NOTCPOPTS
-#endif /* NOTCPOPTS */
-#ifdef SUNX25
-#undef SUNX25
-#endif /* SUNX25 */
-#ifdef IBMX25
-#undef IBMX25
-#endif /* IBMX25 */
-#ifdef STRATUSX25
-#undef STRATUSX25
-#endif /* STRATUSX25 */
-#ifdef CK_NETBIOS
-#undef CK_NETBIOS
-#endif /* CK_NETBIOS */
-#ifdef SUPERLAT
-#undef SUPERLAT
-#endif /* SUPERLAT */
-#ifdef NPIPE
-#undef NPIPE
-#endif /* NPIPE */
-#ifdef NETFILE
-#undef NETFILE
-#endif /* NETFILE */
-#ifdef NETCMD
-#undef NETCMD
-#endif /* NETCMD */
-#ifdef NETPTY
-#undef NETPTY
-#endif /* NETPTY */
-#ifdef RLOGCODE
-#undef RLOGCODE
-#endif /* RLOGCODE */
-#ifdef NETDLL
-#undef NETDLL
-#endif /* NETDLL */
-#ifndef NOSSH
-#define NOSSH
-#endif /* NOSSH */
-#ifndef NOFTP
-#define NOFTP
-#endif /* NOFTP */
-#ifndef NOHTTP
-#define NOHTTP
-#endif /* NOHTTP */
-#ifndef NOBROWSER
-#define NOBROWSER
-#endif /* NOBROWSER */
-#ifndef NOFORWARDX
-#define NOFORWARDX
-#endif /* NOFORWARDX */
-#endif /* NONET */
-
-#ifdef IKSDONLY
-#ifdef SUNX25
-#undef SUNX25
-#endif /* SUNX25 */
-#ifdef IBMX25
-#undef IBMX25
-#endif /* IBMX25 */
-#ifdef STRATUSX25
-#undef STRATUSX25
-#endif /* STRATUSX25 */
-#ifdef CK_NETBIOS
-#undef CK_NETBIOS
-#endif /* CK_NETBIOS */
-#ifdef SUPERLAT
-#undef SUPERLAT
-#endif /* SUPERLAT */
-#ifdef NPIPE
-#undef NPIPE
-#endif /* NPIPE */
-#ifdef NETFILE
-#undef NETFILE
-#endif /* NETFILE */
-#ifdef NETCMD
-#undef NETCMD
-#endif /* NETCMD */
-#ifdef NETPTY
-#undef NETPTY
-#endif /* NETPTY */
-#ifdef RLOGCODE
-#undef RLOGCODE
-#endif /* RLOGCODE */
-#ifdef NETDLL
-#undef NETDLL
-#endif /* NETDLL */
-#ifndef NOSSH
-#define NOSSH
-#endif /* NOSSH */
-#ifndef NOHTTP
-#define NOHTTP
-#endif /* NOHTTP */
-#ifndef NOBROWSER
-#define NOBROWSER
-#endif /* NOBROWSER */
-#endif /* IKSDONLY */
-/*
- Note that none of the above precludes TNCODE, which can be defined in
- the absence of TCPSOCKET, etc, to enable server-side Telnet negotation.
-*/
-#ifndef TNCODE /* This is for the benefit of */
-#ifdef TCPSOCKET /* modules that might need TNCODE */
-#define TNCODE /* not all of ckcnet.h... */
-#endif /* TCPSOCKET */
-#endif /* TNCODE */
-
-#ifndef NETCONN
-#ifdef TCPSOCKET
-#define NETCONN
-#endif /* TCPSOCKET */
-#endif /* NETCONN */
-
-#ifndef DEFPAR /* Default parity */
-#define DEFPAR 0 /* Must be here because it is used */
-#endif /* DEFPAR */ /* by all classes of modules */
-
-#ifdef NT
-#ifndef OS2ORWIN32
-#define OS2ORWIN32
-#endif /* OS2ORWIN32 */
-#ifndef OS2
-#define WIN32ONLY
-#endif /* OS2 */
-#endif /* NT */
-
-#ifdef OS2 /* For OS/2 debugging */
-#ifndef OS2ORWIN32
-#define OS2ORWIN32
-#endif /* OS2ORWIN32 */
-#ifdef NT
-#define NOCRYPT
-#include <windows.h>
-#define NTSIG
-#else /* NT */
-#define OS2ONLY
-#include <os2def.h>
-#endif /* NT */
-#ifndef OS2ORUNIX
-#define OS2ORUNIX
-#endif /* OS2ORUNIX */
-#ifndef OS2ORVMS
-#define OS2ORVMS
-#endif /* OS2ORVMS */
-#endif /* OS2 */
-
-#include <stdio.h> /* Begin by including this. */
-#include <ctype.h> /* and this. */
-
-#ifdef VMS
-#include <types.h> /* Ensure off_t. */
-#include "ckvrms.h" /* Get NAMDEF NAMX_C_MAXRSS. */
-#endif /* def VMS */
-
-/* System-type compilation switches */
-
-#ifdef FT21 /* Fortune For:Pro 2.1 implies 1.8 */
-#ifndef FT18
-#define FT18
-#endif /* FT18 */
-#endif /* FT21 */
-
-#ifdef __bsdi__
-#ifndef BSDI
-#define BSDI
-#endif /* BSDI */
-#endif /* __bsdi__ */
-
-#ifdef AIXPS2 /* AIXPS2 implies AIX370 */
-#ifndef AIX370
-#define AIX370
-#endif /* AIX370 */
-#endif /* AIXPS2 */
-
-#ifdef AIX370 /* AIX PS/2 or 370 implies BSD4 */
-#ifndef BSD4
-#define BSD4
-#endif /* BSD4 */
-#endif /* AIX370 */
-
-#ifdef AIXESA /* AIX/ESA implies BSD4.4 */
-#ifndef BSD44
-#define BSD44
-#endif /* BSD44 */
-#endif /* AIXESA */
-
-#ifdef AIX53 /* AIX53 implies AIX52 */
-#ifndef AIX52
-#define AIX52
-#endif /* AIX52 */
-#endif /* AIX53 */
-
-#ifdef AIX52 /* AIX52 implies AIX51 */
-#ifndef AIX51
-#define AIX51
-#endif /* AIX51 */
-#endif /* AIX52 */
-
-#ifdef AIX51 /* AIX51 implies AIX50 */
-#ifndef AIX50
-#define AIX50
-#endif /* AIX50 */
-#endif /* AIX51 */
-
-#ifdef AIX50 /* AIX50 implies AIX45 */
-#ifndef AIX45
-#define AIX45
-#endif /* AIX45 */
-#endif /* AIX50 */
-
-#ifdef AIX45 /* AIX45 implies AIX44 */
-#ifndef AIX44
-#define AIX44
-#endif /* AIX44 */
-#endif /* AIX45 */
-
-#ifdef AIX44 /* AIX44 implies AIX43 */
-#ifndef AIX43
-#define AIX43
-#endif /* AIX43 */
-#endif /* AIX44 */
-
-#ifdef AIX43 /* AIX43 implies AIX42 */
-#ifndef AIX42
-#define AIX42
-#endif /* AIX42 */
-#endif /* AIX43 */
-
-#ifdef AIX42 /* AIX42 implies AIX41 */
-#ifndef AIX41
-#define AIX41
-#endif /* AIX41 */
-#endif /* AIX42 */
-
-#ifdef SV68R3V6 /* System V/68 R32V6 implies SVR3 */
-#ifndef SVR3
-#define SVR3
-#endif /* SVR3 */
-#endif /* SV68R3V6 */
-
-#ifdef SV88R32 /* System V/88 R32 implies SVR3 */
-#ifndef SVR3
-#define SVR3
-#endif /* SVR3 */
-#endif /* SV88R32 */
-
-#ifdef DGUX540 /* DG UX 5.40 implies Sys V R 4 */
-#ifndef SVR4
-#define SVR4
-#endif /* SVR4 */
-#endif /* DGUX540 */
-
-#ifndef DGUX
-#ifdef DGUX540 /* DG/UX 5.40 implies DGUX */
-#define DGUX
-#else
-#ifdef DGUX430 /* So does DG/UX 4.30 */
-#define DGUX
-#endif /* DGUX430 */
-#endif /* DGUX540 */
-#endif /* DGUX */
-
-#ifdef IRIX65 /* IRIX 6.5 implies IRIX 6.4 */
-#ifndef IRIX64
-#define IRIX64
-#endif /* IRIX64 */
-#endif /* IRIX65 */
-
-#ifdef IRIX64 /* IRIX 6.4 implies IRIX 6.2 */
-#ifndef BSD44ORPOSIX
-#define BSD44ORPOSIX /* for ckutio's benefit */
-#endif /* BSD44ORPOSIX */
-#ifndef IRIX62
-#define IRIX62
-#endif /* IRIX62 */
-#endif /* IRIX64 */
-
-#ifdef IRIX62 /* IRIX 6.2 implies IRIX 6.0 */
-#ifndef IRIX60
-#define IRIX60
-#endif /* IRIX60 */
-#endif /* IRIX62 */
-
-#ifdef IRIX60 /* IRIX 6.0 implies IRIX 5.1 */
-#ifndef IRIX51
-#define IRIX51
-#endif /* IRIX51 */
-#ifndef IRIX52 /* And IRIX 5.2 (for hwfc) */
-#define IRIX52
-#endif /* IRIX52 */
-#endif /* IRIX60 */
-
-#ifndef IRIX /* IRIX 4.0 or greater implies IRIX */
-#ifdef IRIX64
-#define IRIX
-#else
-#ifdef IRIX62
-#define IRIX
-#else
-#ifdef IRIX60
-#define IRIX
-#else
-#ifdef IRIX51
-#define IRIX
-#else
-#ifdef IRIX40
-#define IRIX
-#endif /* IRIX40 */
-#endif /* IRIX51 */
-#endif /* IRIX60 */
-#endif /* IRIX62 */
-#endif /* IRIX64 */
-#endif /* IRIX */
-
-#ifdef MIPS /* MIPS System V environment */
-#ifndef SVR3 /* implies System V R3 or later */
-#define SVR3
-#endif /* SVR3 */
-#endif /* MIPS */
-
-#ifdef HPUX9 /* HP-UX 9.x */
-#ifndef SVR3
-#define SVR3
-#endif /* SVR3 */
-#ifndef HPUX
-#define HPUX
-#endif /* HPUX */
-#ifndef HPUX9PLUS
-#define HPUX9PLUS
-#endif /* HPUX9PLUS */
-#endif /* HPUX9 */
-
-#ifdef HPUX10 /* HP-UX 10.x */
-#ifndef HPUX1010 /* If anything higher is defined */
-#ifdef HPUX1020 /* define HPUX1010 too. */
-#define HPUX1010
-#endif /* HPUX1020 */
-#ifdef HPUX1030
-#define HPUX1010
-#endif /* HPUX1030 */
-#endif /* HPUX1010 */
-
-#ifdef HPUX1100 /* HP-UX 11.00 implies 10.10 */
-#ifndef HPUX1010
-#define HPUX1010
-#endif /* HPUX1010 */
-#endif /* HPUX1100 */
-
-#ifndef SVR4
-#define SVR4
-#endif /* SVR4 */
-#ifndef HPUX
-#define HPUX
-#endif /* HPUX */
-#ifndef HPUX9PLUS
-#define HPUX9PLUS
-#endif /* HPUX9PLUS */
-#endif /* HPUX10 */
-
-#ifdef QNX /* QNX Software Systems Inc */
-#ifndef POSIX /* QNX 4.0 or later is POSIX */
-#define POSIX
-#endif /* POSIX */
-#ifndef __386__ /* Comes in 16-bit and 32-bit */
-#define __16BIT__
-#define CK_QNX16
-#else
-#define __32BIT__
-#define CK_QNX32
-#endif /* __386__ */
-#endif /* QNX */
-
-/*
- 4.4BSD is a mixture of System V R4, POSIX, and 4.3BSD.
-*/
-#ifdef BSD44 /* 4.4 BSD */
-#ifndef SVR4 /* BSD44 implies SVR4 */
-#define SVR4
-#endif /* SVR4 */
-#ifndef NOSETBUF /* NOSETBUF is safe */
-#define NOSETBUF
-#endif /* NOSETBUF */
-#ifndef DIRENT /* Uses <dirent.h> */
-#define DIRENT
-#endif /* DIRENT */
-#endif /* BSD44 */
-
-#ifdef OPENBSD /* OpenBSD might or might not */
-#ifndef __OpenBSD__ /* have this defined... */
-#define __OpenBSD__
-#endif /* __OpenBSD__ */
-#endif /* OPENBSD */
-
-#ifdef SVR3 /* SVR3 implies ATTSV */
-#ifndef ATTSV
-#define ATTSV
-#endif /* ATTSV */
-#endif /* SVR3 */
-
-#ifdef SVR4 /* SVR4 implies ATTSV */
-#ifndef ATTSV
-#define ATTSV
-#endif /* ATTSV */
-#ifndef SVR3 /* ...as well as SVR3 */
-#define SVR3
-#endif /* SVR3 */
-#endif /* SVR4 */
-
-#ifdef OXOS
-#ifndef ATTSV
-#define ATTSV /* OXOS implies ATTSV */
-#endif /* ! ATTSV */
-#define SW_ACC_ID /* access() wants privs on */
-#define kill priv_kill /* kill() wants privs on */
-#ifndef NOSETBUF
-#define NOSETBUF /* NOSETBUF is safe */
-#endif /* ! NOSETBUF */
-#endif /* OXOS */
-
-#ifdef UTSV /* UTSV implies ATTSV */
-#ifndef ATTSV
-#define ATTSV
-#endif /* ATTSV */
-#endif /* UTSV */
-
-#ifdef XENIX /* XENIX implies ATTSV */
-#ifndef ATTSV
-#define ATTSV
-#endif /* ATTSV */
-#endif /* XENIX */
-
-#ifdef AUX /* AUX implies ATTSV */
-#ifndef ATTSV
-#define ATTSV
-#endif /* ATTSV */
-#endif /* AUX */
-
-#ifdef ATT7300 /* ATT7300 implies ATTSV */
-#ifndef ATTSV
-#define ATTSV
-#endif /* ATTSV */
-#endif /* ATT7300 */
-
-#ifdef ATT6300 /* ATT6300 implies ATTSV */
-#ifndef ATTSV
-#define ATTSV
-#endif /* ATTSV */
-#endif /* ATT6300 */
-
-#ifdef HPUX /* HPUX implies ATTSV */
-#ifndef ATTSV
-#define ATTSV
-#endif /* ATTSV */
-#endif /* HPUX */
-
-#ifdef ISIII /* ISIII implies ATTSV */
-#ifndef ATTSV
-#define ATTSV
-#endif /* ATTSV */
-#endif /* ISIII */
-
-#ifdef NEXT33 /* NEXT33 implies NEXT */
-#ifndef NEXT
-#define NEXT
-#endif /* NEXT */
-#endif /* NEXT33 */
-
-#ifdef NEXT /* NEXT implies BSD4 */
-#ifndef BSD4
-#define BSD4
-#endif /* BSD4 */
-#endif /* NEXT */
-
-#ifdef BSD41 /* BSD41 implies BSD4 */
-#ifndef BSD4
-#define BSD4
-#endif /* BSD4 */
-#endif /* BSD41 */
-
-#ifdef BSD43 /* BSD43 implies BSD4 */
-#ifndef BSD4
-#define BSD4
-#endif /* BSD4 */
-#endif /* BSD43 */
-
-#ifdef BSD4 /* BSD4 implies ANYBSD */
-#ifndef ANYBSD
-#define ANYBSD
-#endif /* ANYBSD */
-#endif /* BSD4 */
-
-#ifdef BSD29 /* BSD29 implies ANYBSD */
-#ifndef ANYBSD
-#define ANYBSD
-#endif /* ANYBSD */
-#endif /* BSD29 */
-
-#ifdef ATTSV /* ATTSV implies UNIX */
-#ifndef UNIX
-#define UNIX
-#endif /* UNIX */
-#endif /* ATTSV */
-
-#ifdef ANYBSD /* ANYBSD implies UNIX */
-#ifndef UNIX
-#define UNIX
-#endif /* UNIX */
-#endif /* ANYBSD */
-
-#ifdef POSIX /* POSIX implies UNIX */
-#ifndef UNIX
-#define UNIX
-#endif /* UNIX */
-#ifndef DIRENT /* and DIRENT, i.e. <dirent.h> */
-#ifndef SDIRENT
-#define DIRENT
-#endif /* SDIRENT */
-#endif /* DIRENT */
-#ifndef NOFILEH /* POSIX doesn't use <sys/file.h> */
-#define NOFILEH
-#endif /* NOFILEH */
-#endif /* POSIX */
-
-#ifdef V7
-#ifndef UNIX
-#define UNIX
-#endif /* UNIX */
-#endif /* V7 */
-
-#ifdef COHERENT
-#ifndef UNIX
-#define UNIX
-#endif /* UNIX */
-#ifdef COMMENT
-#ifndef NOCURSES
-#define NOCURSES
-#endif /* NOCURSES */
-#endif /* COMMENT */
-#endif /* COHERENT */
-
-#ifdef MINIX
-#ifndef UNIX
-#define UNIX
-#endif /* UNIX */
-#endif /* MINIX */
-/*
- The symbol SVORPOSIX is defined for both AT&T and POSIX compilations
- to make it easier to select items that System V and POSIX have in common,
- but which BSD, V7, etc, do not have.
-*/
-#ifdef ATTSV
-#ifndef SVORPOSIX
-#define SVORPOSIX
-#endif /* SVORPOSIX */
-#endif /* ATTSV */
-
-#ifdef POSIX
-#ifndef SVORPOSIX
-#define SVORPOSIX
-#endif /* SVORPOSIX */
-#endif /* POSIX */
-
-/*
- The symbol SVR4ORPOSIX is defined for both AT&T System V R4 and POSIX
- compilations to make it easier to select items that System V R4 and POSIX
- have in common, but which BSD, V7, and System V R3 and earlier, etc, do
- not have.
-*/
-#ifdef POSIX
-#ifndef SVR4ORPOSIX
-#define SVR4ORPOSIX
-#endif /* SVR4ORPOSIX */
-#endif /* POSIX */
-#ifdef SVR4
-#ifndef SVR4ORPOSIX
-#define SVR4ORPOSIX
-#endif /* SVR4ORPOSIX */
-#endif /* SVR4 */
-
-/*
- The symbol BSD44ORPOSIX is defined for both 4.4BSD and POSIX compilations
- to make it easier to select items that 4.4BSD and POSIX have in common,
- but which System V, BSD, V7, etc, do not have.
-*/
-#ifdef BSD44
-#ifndef BSD44ORPOSIX
-#define BSD44ORPOSIX
-#endif /* BSD44ORPOSIX */
-#endif /* BSD44 */
-
-#ifdef POSIX
-#ifndef BSD44ORPOSIX
-#define BSD44ORPOSIX
-#endif /* BSD44ORPOSIX */
-#endif /* POSIX */
-
-#ifdef UNIX /* For items common to OS/2 and UNIX */
-#ifndef OS2ORUNIX
-#define OS2ORUNIX
-#endif /* OS2ORUNIX */
-#endif /* UNIX */
-
-#ifdef UNIX /* For items common to VMS and UNIX */
-#define VMSORUNIX
-#else
-#ifdef VMS
-#define VMSORUNIX
-#ifndef OS2ORVMS
-#define OS2ORVMS
-#endif /* OS2ORVMS */
-#endif /* VMS */
-#endif /* UNIX */
-
-#ifndef UNIXOROSK /* UNIX or OS-9 (or OS-9000) */
-#ifdef UNIX
-#define UNIXOROSK
-#else
-#ifdef OSK
-#define UNIXOROSK
-#endif /* OSK */
-#endif /* UNIX */
-#endif /* UNIXOROSK */
-
-#ifndef OSKORUNIX
-#ifdef UNIXOROSK
-#define OSKORUNIX
-#endif /* UNIXOROSK */
-#endif /* OSKORUNIX */
-
-#ifdef OS2
-#define CK_ANSIC /* OS/2 supports ANSIC and more extensions */
-#endif /* OS2 */
-
-#ifdef OSF50 /* Newer OSF/1 versions imply older ones */
-#ifndef OSF40
-#define OSF40
-#endif /* OSF40 */
-#endif /* OSF50 */
-
-#ifdef OSF40
-#ifndef OSF32
-#define OSF32
-#endif /* OSF32 */
-#endif /* OSF40 */
-
-#ifdef OSF32
-#ifndef OSF30
-#define OSF30
-#endif /* OSF30 */
-#endif /* OSF32 */
-
-#ifdef OSF30
-#ifndef OSF20
-#define OSF20
-#endif /* OSF20 */
-#endif /* OSF30 */
-
-#ifdef OSF20
-#ifndef OSF10
-#define OSF10
-#endif /* OSF10 */
-#endif /* OSF20 */
-
-#ifdef __DECC /* For DEC Alpha VMS or OSF/1 */
-#ifndef CK_ANSIC
-#define CK_ANSIC /* Even with /stand=vaxc, need ansi */
-#endif /* CKANSIC */
-#ifndef SIG_V
-#define SIG_V /* and signal type is VOID */
-#endif /* SIG_V */
-#ifndef CK_ANSILIBS
-#define CK_ANSILIBS /* (Martin Zinser, Feb 1995) */
-#endif /* CK_ANSILIBS */
-#ifndef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 1
-#endif /* _POSIX_C_SOURCE */
-#endif /* __DECC */
-
-#ifdef VMS
-#ifdef __ia64 /* VMS on Itanium */
-#ifndef VMSI64
-#define VMSI64
-#endif /* VMSI64 */
-#endif /* __ia64 */
-#ifndef VMS64BIT /* 64-bit VMS on Itanium or Alpha */
-#ifdef __ia64
-#define VMS64BIT
-#else
-#ifdef __ALPHA
-#define VMS64BIT
-#endif /* __ia64 */
-#endif /* __ALPHA */
-#endif /* VMS64BIT */
-#endif /* VMS */
-
-#ifdef apollo /* May be ANSI-C, check further */
-#ifdef __STDCPP__
-#define CK_ANSIC /* Yes, this is real ANSI-C */
-#define SIG_V
-#else
-#define NOANSI /* Nope, not ANSI */
-#undef __STDC__ /* Even though it say it is! */
-#define SIG_I
-#endif /* __STDCPP__ */
-#endif /* apollo */
-
-#ifdef POSIX /* -DPOSIX on cc command line */
-#ifndef _POSIX_SOURCE /* Implies _POSIX_SOURCE */
-#define _POSIX_SOURCE
-#endif /* _POSIX_SOURCE */
-#endif /* POSIX */
-
-/*
- ANSI C? That is, do we have function prototypes, new-style
- function declarations, and parameter type checking and coercion?
-*/
-#ifdef MAC /* MPW C is ANSI */
-#ifndef NOANSI
-#ifndef CK_ANSIC
-#define CK_ANSIC
-#endif /* CK_ANSIC */
-#endif /* NOANSI */
-#endif /* MAC */
-
-#ifdef STRATUS /* Stratus VOS */
-#ifndef CK_ANSIC
-#define CK_ANSIC
-#endif /* CK_ANSIC */
-#ifndef NOSTAT
-#define NOSTAT
-#endif /* NOSTAT */
-#endif /* STRATUS */
-
-#ifndef NOANSI
-#ifdef __STDC__ /* __STDC__ means ANSI C */
-#ifndef CK_ANSIC
-#define CK_ANSIC
-#endif /* CK_ANSIC */
-#endif /* __STDC__ */
-#endif /* NOANSI */
-/*
- _PROTOTYP() is used for forward declarations of functions so we can have
- parameter and return value type checking if the compiler offers it.
- __STDC__ should be defined by the compiler only if function prototypes are
- allowed. Otherwise, we get old-style forward declarations. Our own private
- CK_ANSIC symbol tells whether we use ANSI C prototypes. To force use of
- ANSI prototypes, include -DCK_ANSIC on the cc command line. To disable the
- use of ANSI prototypes, include -DNOANSI.
-*/
-#ifdef CK_ANSIC
-#define _PROTOTYP( func, parms ) func parms
-#else /* Not ANSI C */
-#define _PROTOTYP( func, parms ) func()
-#endif /* CK_ANSIC */
-
-#ifndef OS2
-#ifdef NOLOGIN /* NOLOGIN implies NOIKSD */
-#ifndef NOIKSD
-#define NOIKSD
-#endif /* NOIKSD */
-#endif /* NOLOGIN */
-#endif /* OS2 */
-
-#ifdef NOIKSD /* Internet Kermit Service Daemon */
-#ifndef OS2
-#ifndef NOPRINTFSUBST
-#define NOPRINTFSUBST
-#endif /* NOPRINTFSUBST */
-#endif /* OS2 */
-#ifndef NOLOGIN
-#define NOLOGIN
-#endif /* NOLOGIN */
-#ifndef NOSYSLOG
-#define NOSYSLOG
-#endif /* NOSYSLOG */
-#ifndef NOWTMP
-#define NOWTMP
-#endif /* NOWTMP */
-#else
-#ifndef IKSD
-#ifdef OS2ORUNIX /* Platforms where IKSD is supported */
-#define IKSD
-#endif /* OS2ORUNIX */
-#endif /* IKSD */
-#endif /* NOIKSD */
-
-#ifdef IKSD /* IKSD options... */
-#ifndef IKSDCONF /* IKSD configuration file */
-#ifdef UNIX
-#define IKSDCONF "/etc/iksd.conf"
-#else
-#ifdef OS2
-#define IKSDCONF "iksd.ksc"
-#endif /* OS2 */
-#endif /* UNIX */
-#endif /* IKSDCONF */
-#ifndef NOIKSDB
-#ifndef IKSDB /* IKSD database */
-#ifdef UNIX
-#define IKSDB
-#define IK_LCKTRIES 16 /* How many times to try to get lock */
-#define IK_LCKSLEEP 1 /* How long to sleep between tries */
-#define IK_LOCKFILE "iksd.lck" /* Database lockfilename */
-#define IK_DBASEDIR "/var/log/" /* Database directory */
-#define IK_DBASEFIL "iksd.db" /* Database filename */
-#else /* UNIX */
-#ifdef OS2
-#define IKSDB
-#ifndef NOFTRUNCATE /* ftruncate() not available */
-#define NOFTRUNCATE
-#endif /* NOFTRUNCATE */
-#define IK_LCKTRIES 16 /* How many times to try to get lock */
-#define IK_LCKSLEEP 1 /* How long to sleep between tries */
-#define IK_LOCKFILE "iksd.lck" /* DB lockfilename (in systemroot) */
-#define IK_DBASEFIL "iksd.db" /* Database filename */
-#endif /* OS2 */
-#endif /* UNIX */
-#endif /* IKSDB */
-#endif /* NOIKSDB */
-#endif /* IKSD */
-/*
- Substitutes for printf() and friends used in IKS to compensate for
- lack of a terminal driver, mainly to supply CR after LF.
-*/
-#ifndef NOPRINTFSUBST
-#ifdef MAC
-/*
- * The MAC doesn't use standard stdio routines.
- */
-#undef getchar
-#define getchar() mac_getchar()
-#undef putchar
-#define putchar(c) mac_putchar(c)
-#define printf mac_printf
-#define perror mac_perror
-#define puts mac_puts
-extern int mac_putchar (int c);
-extern int mac_puts (const char *string);
-extern int mac_printf(const char *, ...);
-extern int mac_getchar (void);
-#endif /* MAC */
-
-#ifdef OS2
-#define printf Vscrnprintf
-#define fprintf Vscrnfprintf
-extern int Vscrnprintf(const char *, ...);
-extern int Vscrnprintw(const char *, ...);
-extern int Vscrnfprintf(FILE *, const char *, ...);
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) Vscrnprintf("%c",x)
-#define perror(x) Vscrnperror(x)
-#endif /* OS2 */
-
-#ifndef CKWART_C
-#ifdef UNIX
-#ifndef pdp11
-#ifndef CKXPRINTF
-#define CKXPRINTF
-#endif /* CKXPRINTF */
-#endif /* pdp11 */
-#endif /* UNIX */
-#endif /* CKWART_C */
-#endif /* NOPRINTFSUBST */
-
-#ifdef CKXPRINTF
-#define printf ckxprintf
-#define fprintf ckxfprintf
-#ifdef CK_ANSIC
-_PROTOTYP(int ckxprintf,(const char *, ...));
-#ifdef NEXT
-_PROTOTYP(void ckxperror,(const char *));
-#else
-#ifdef CK_SCOV5
-_PROTOTYP(void ckxperror,(const char *));
-#else
-_PROTOTYP(int ckxperror,(const char *));
-#endif /* CK_SCOV5 */
-#endif /* NEXT */
-_PROTOTYP(int ckxfprintf,(FILE *, const char *, ...));
-#endif /* CK_ANSIC */
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) ckxprintf("%c",x)
-#ifdef putc
-#undef putc
-#endif /* putc */
-#define putc(a,b) ckxfprintf(b,"%c",a)
-#define perror(x) ckxperror(x)
-#endif /* CKXPRINTF */
-
-/*
- Altos-specific items: 486, 586, 986 models...
-*/
-#ifdef A986
-#define M_VOID
-#define void int
-#define CHAR char
-#define SIG_I
-#endif /* A986 */
-
-/* Signal handling */
-
-#ifdef QNX
-#ifndef CK_POSIX_SIG
-#define CK_POSIX_SIG
-#endif /* CK_POSIX_SIG */
-#endif /* QNX */
-
-/*
- void type, normally available only in ANSI compilers.
- The HP-UX exception (for its "bundled" non-ANSI C compiler)
- is known to be valid back to HP-UX 6.5.
- Adjustments might be needed for earlier HP-UX versions.
-*/
-#ifndef VOID /* Used throughout all C-Kermit */
-#ifdef CK_ANSIC /* modules... */
-#define VOID void
-#else
-#ifdef HPUX
-#define VOID void
-#else
-#define VOID int
-#endif /* HPUX */
-#endif /* CK_ANSIC */
-#endif /* VOID */
-/*
- Exactly the same as VOID but for use in contexts where the VOID symbol
- conflicts some header-file definition. This is needed for the section
- of ckuusx.c that provides C-Kermit's curses interface, roughly the
- second half of ckuusx.c.
-*/
-#ifndef CKVOID
-#ifdef CK_ANSIC
-#define CKVOID void
-#else
-#ifdef HPUX
-#define CKVOID void
-#else
-#define CKVOID int
-#endif /* HPUX */
-#endif /* CK_ANSIC */
-#endif /* CKVOID */
-
-/* Const type */
-
-#ifndef CONST
-#ifdef OSK
-#ifdef _UCC
-#define CONST const
-#else
-#define CONST
-#endif /* _UCC */
-#else /* !OSK */
-#ifdef CK_SCO32V4
-#define CONST
-#else
-#ifdef CK_ANSIC
-#define CONST const
-#else
-#define CONST
-#endif /* CK_ANSIC */
-#endif /* CK_SCO32V4 */
-#endif /* OSK */
-#endif /* CONST */
-
-/* Signal type */
-
-#ifndef SIG_V /* signal() type, if not def'd yet */
-#ifndef SIG_I
-#ifdef OS2
-#define SIG_V
-#else
-#ifdef POSIX
-#define SIG_V
-#else
-#ifdef SVR3 /* System V R3 and later */
-#define SIG_V
-#else
-#ifdef SUNOS4 /* SUNOS V 4.0 and later */
-#ifndef sun386
-#define SIG_V
-#else
-#define SIG_I
-#endif /* sun386 */
-#else
-#ifdef NEXT /* NeXT */
-#define SIG_V
-#else
-#ifdef AIX370
-#include <signal.h>
-#define SIG_V
-#define SIGTYP __SIGVOID /* AIX370 */
-#else
-#ifdef STRATUS /* Stratus VOS */
-#define SIG_V
-#else
-#ifdef MAC
-#define SIGTYP long
-#define SIG_I
-#ifndef MPW33
-#define SIG_IGN 0
-#endif /* MPW33 */
-#define SIGALRM 1
-#ifndef MPW33
-#define SIGINT 2
-#endif /* MPW33 */
-#else /* Everything else */
-#define SIG_I
-#endif /* MAC */
-#endif /* STRATUS */
-#endif /* AIX370 */
-#endif /* NEXT */
-#endif /* SUNOS4 */
-#endif /* SVR3 */
-#endif /* POSIX */
-#endif /* OS2 */
-#endif /* SIG_I */
-#endif /* SIG_V */
-
-#ifdef SIG_I
-#define SIGRETURN return(0)
-#ifndef SIGTYP
-#define SIGTYP int
-#endif /* SIGTYP */
-#endif /* SIG_I */
-
-#ifdef SIG_V
-#define SIGRETURN return
-#ifndef SIGTYP
-#define SIGTYP void
-#endif /* SIGTYP */
-#endif /* SIG_V */
-
-#ifdef NT
-#ifndef SIGTYP
-#define SIGTYP void
-#endif /* SIGTYP */
-#endif /* NT */
-
-#ifndef SIGTYP
-#define SIGTYP int
-#endif /* SIGTYP */
-
-#ifndef SIGRETURN
-#define SIGRETURN return(0)
-#endif /* SIGRETURN */
-
-#ifdef CKNTSIG
-/* This does not work, so don't use it. */
-#define signal ckntsignal
-SIGTYP (*ckntsignal(int type, SIGTYP (*)(int)))(int);
-#endif /* CKNTSIG */
-
-/* We want all characters to be unsigned if the compiler supports it */
-
-#ifdef KUI
-#ifdef CHAR
-#undef CHAR
-#endif /* CHAR */
-#define CHAR unsigned char
-#else
-#ifdef PROVX1
-typedef char CHAR;
-/* typedef long LONG; */
-typedef int void;
-#else
-#ifdef MINIX
-typedef unsigned char CHAR;
-#else
-#ifdef V7
-typedef char CHAR;
-#else
-#ifdef C70
-typedef char CHAR;
-/* typedef long LONG; */
-#else
-#ifdef BSD29
-typedef char CHAR;
-/* typedef long LONG; */
-#else
-#ifdef datageneral
-#define CHAR unsigned char /* 3.22 compiler */
-#else
-#ifdef HPUX
-#define CHAR unsigned char
-#else
-#ifdef OS2
-#ifdef NT
-#define CHAR unsigned char
-#else /* NT */
-#ifdef CHAR
-#undef CHAR
-#endif /* CHAR */
-typedef unsigned char CHAR;
-#endif /* NT */
-#else /* OS2 */
-#ifdef VMS
-typedef unsigned char CHAR;
-#else
-#ifdef CHAR
-#undef CHAR
-#endif /* CHAR */
-typedef unsigned char CHAR;
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* HPUX */
-#endif /* datageneral */
-#endif /* BSD29 */
-#endif /* C70 */
-#endif /* V7 */
-#endif /* MINIX */
-#endif /* PROVX1 */
-#endif /* KUI */
-
-union ck_short { /* Mainly for Unicode */
- USHORT x_short;
- CHAR x_char[2];
-};
-
-#ifdef MAC /* Macintosh file routines */
-#ifndef CKWART_C /* But not in "wart"... */
-#ifdef feof
-#undef feof
-#endif /* feof */
-#define feof mac_feof
-#define rewind mac_rewind
-#define fgets mac_fgets
-#define fopen mac_fopen
-#define fclose mac_fclose
-int mac_feof();
-void mac_rewind();
-char *mac_fgets();
-FILE *mac_fopen();
-int mac_fclose();
-#endif /* CKCPRO_W */
-#endif /* MAC */
-/*
- Systems whose mainline modules have access to the communication-line
- file descriptor, ttyfd.
-*/
-#ifndef CK_TTYFD
-#ifdef UNIX
-#define CK_TTYFD
-#else
-#ifdef OS2
-#define CK_TTYFD
-#else
-#ifdef VMS
-#define CK_TTYFD
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIX */
-#endif /* CK_TTYFD */
-
-/* Systems where we can get our own process ID */
-
-#ifndef CK_PID
-#ifdef UNIX
-#define CK_PID
-#endif /* UNIX */
-#ifdef OS2
-#define CK_PID
-#endif /* OS2 */
-#ifdef VMS
-#define CK_PID
-#endif /* VMS */
-#endif /* CK_PID */
-
-/* Systems that support the Microsoft Telephony API (TAPI) */
-
-#ifndef NODIAL
-#ifndef CK_TAPI
-#ifdef NT
-#define CK_TAPI
-#endif /* NT */
-#endif /* CK_TAPI */
-#endif /* NODIAL */
-
-#ifndef NONZXPAND
-#ifndef NZXPAND
-#ifdef OS2ORUNIX
-#define NZXPAND
-#else
-#ifdef VMS
-#define NZXPAND
-#else
-#ifdef datageneral
-#define NZXPAND
-#else
-#ifdef OSK
-#define NZXPAND
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* OS2ORUNIX */
-#endif /* NZXPAND */
-#else
-#ifdef NZXPAND
-#undef NZXPAND
-#endif /* NZXPAND */
-#endif /* NONZXPAND */
-
-/* nzxpand() option flags */
-
-#define ZX_FILONLY 1 /* Match only regular files */
-#define ZX_DIRONLY 2 /* Match only directories */
-#define ZX_RECURSE 4 /* Descend through directory tree */
-#define ZX_MATCHDOT 8 /* Match "dot files" */
-#define ZX_NOBACKUP 16 /* Don't match "backup files" */
-#define ZX_NOLINKS 32 /* Don't follow symlinks */
-
-#ifndef NZXPAND
-#define nzxpand(a,b) zxpand(a)
-#endif /* NZXPAND */
-
-#ifndef NOZXREWIND
-#ifndef ZXREWIND /* Platforms that have zxrewind() */
-#ifdef OS2ORUNIX
-#define ZXREWIND
-#else
-#ifdef VMS
-#define ZXREWIND
-#else
-#ifdef datageneral
-#define ZXREWIND
-#else
-#ifdef OSK
-#define ZXREWIND
-#else
-#ifdef STRATUS
-#define ZXREWIND
-#endif /* STRATUS */
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* OS2ORUNIX */
-#endif /* ZXREWIND */
-#else
-#ifdef ZXREWIND
-#undef ZXREWIND
-#endif /* ZXREWIND */
-#endif /* NOZXREWIND */
-
-/* Temporary-directory-for-RECEIVE feature ... */
-/* This says whether we have the isdir() function defined. */
-
-#ifdef UNIX /* UNIX has it */
-#ifndef CK_TMPDIR
-#ifndef pdp11
-#define CK_TMPDIR
-#define TMPDIRLEN 256
-#endif /* pdp11 */
-#endif /* CK_TMPDIR */
-#endif /* UNIX */
-
-#ifdef VMS /* VMS too */
-#ifndef CK_TMPDIR
-#define CK_TMPDIR
-#define TMPDIRLEN 256
-#endif /* CK_TMPDIR */
-#endif /* VMS */
-
-#ifdef OS2 /* OS two too */
-#ifndef CK_TMPDIR
-#define CK_TMPDIR
-#define TMPDIRLEN 129
-#endif /* CK_TMPDIR */
-#endif /* OS2 */
-
-#ifdef STRATUS /* Stratus VOS too. */
-#ifndef CK_TMPDIR
-#define CK_TMPDIR
-#define TMPDIRLEN 256
-#endif /* CK_TMPDIR */
-#endif /* STRATUS */
-
-#ifdef OSK /* OS-9 too */
-#ifndef CK_TMPDIR
-#define CK_TMPDIR
-#define TMPDIRLEN 256
-#endif /* CK_TMPDIR */
-#endif /* OSK */
-
-#ifdef datageneral /* AOS/VS too */
-#ifndef CK_TMPDIR
-#define CK_TMPDIR
-#define TMPDIRLEN 256
-#endif /* CK_TMPDIR */
-#endif /* datageneral */
-
-#ifdef CK_TMPDIR /* Needs command parser */
-#ifdef NOICP
-#undef CK_TMPDIR
-#endif /* NOICP */
-#endif /* CK_TMPDIR */
-
-/* Whether to include <sys/time.h> */
-
-#ifndef NOTIMEH /* <time.h> */
-#ifndef TIMEH
-#define TIMEH
-#endif /* TIMEH */
-#endif /* NOTIMEH */
-
-#ifndef NOSYSTIMEH /* <sys/time.h> */
-#ifndef SYSTIMEH
-#ifdef UNIX /* UNIX */
-#ifdef SVORPOSIX /* System V or POSIX... */
-#ifdef M_UNIX
-#define SYSTIMEH
-#else
-#ifdef SCO_32V4
-#define SYSTIMEH
-#else
-#ifdef OXOS
-#define SYSTIMEH
-#else
-#ifdef BSD44
-#define SYSTIMEH
-#else
-#ifdef __linux__
-#define SYSTIMEH
-#else
-#ifdef AIXRS
-#ifndef AIX41
-#define SYSTIMEH
-#endif /* AIX41 */
-#else
-#ifdef IRIX60
-#define SYSTIMEH
-#else
-#ifdef I386IX
-#define SYSTIMEH
-#else
-#ifdef SV68R3V6
-#define SYSTIMEH
-#endif /* SV68R3V6 */
-#endif /* I386IX */
-#endif /* IRIX60 */
-#endif /* AIXRS */
-#endif /* __linux__ */
-#endif /* BSD44 */
-#endif /* OXOS */
-#endif /* SCO_32V4 */
-#endif /* M_UNIX */
-
-#else /* Not SVORPOSIX */
-
-#ifndef BELLV10 /* All but these... */
-#ifndef PROVX1
-#ifndef V7
-#ifndef BSD41
-#ifndef COHERENT
-#define SYSTIMEH
-#endif /* COHERENT */
-#endif /* BSD41 */
-#endif /* V7 */
-#endif /* PROVX1 */
-#endif /* BELLV10 */
-#endif /* SVORPOSIX */
-#endif /* UNIX */
-#endif /* SYSTIMEH */
-#endif /* NOSYSTIMEH */
-
-#ifndef NOSYSTIMEBH /* <sys/timeb.h> */
-#ifndef SYSTIMEBH
-#ifdef OSF
-#define SYSTIMEBH
-#else
-#ifdef COHERENT
-#define SYSTIMEBH
-#else
-#ifdef BSD41
-#define SYSTIMEBH
-#else
-#ifdef BSD29
-#define SYSTIMEBH
-#else
-#ifdef TOWER1
-#define SYSTIMEBH
-#else
-#ifdef FT21
-#define SYSTIMEBH
-#else
-#ifdef BELLV10
-#define SYSTIMEBH
-#endif /* BELLV10 */
-#endif /* FT21 */
-#endif /* TOWER1 */
-#endif /* BSD29 */
-#endif /* BSD41 */
-#endif /* COHERENT */
-#endif /* OSF */
-#endif /* SYSTIMEBH */
-#endif /* NOSYSTIMEBH */
-
-/*
- Debug and transaction logging is included automatically unless you define
- NODEBUG or NOTLOG. Do this if you want to save the space and overhead.
- (Note, in version 4F these definitions changed from "{}" to the null string
- to avoid problems with semicolons after braces, as in: "if (x) tlog(this);
- else tlog(that);"
-*/
-#ifndef NODEBUG
-#ifndef DEBUG
-#define DEBUG
-#endif /* DEBUG */
-#else
-#ifdef DEBUG
-#undef DEBUG
-#endif /* DEBUG */
-#endif /* NODEBUG */
-
-#ifdef NOTLOG
-#ifdef TLOG
-#undef TLOG
-#endif /* TLOG */
-#else /* NOTLOG */
-#ifndef TLOG
-#define TLOG
-#endif /* TLOG */
-#endif /* NOTLOG */
-
-/* debug() macro style selection. */
-
-#ifdef VMS
-#ifndef IFDEBUG
-#define IFDEBUG
-#endif /* IFDEBUG */
-#endif /* VMS */
-
-#ifdef MAC
-#ifndef IFDEBUG
-#define IFDEBUG
-#endif /* IFDEBUG */
-#endif /* MAC */
-
-#ifdef OS2
-#ifndef IFDEBUG
-#define IFDEBUG
-#endif /* IFDEBUG */
-#endif /* OS2 */
-
-#ifdef OXOS /* tst is faster than jsr */
-#ifndef IFDEBUG
-#define IFDEBUG
-#endif /* IFDEBUG */
-#endif /* OXOS */
-
-#ifndef CKCMAI
-extern int deblog;
-extern int debok;
-extern int debxlen;
-extern int matchdot;
-extern int tt_bell;
-#endif /* CKCMAI */
-
-#ifdef OS2
-_PROTOTYP( void bleep, (short) );
-#else /* OS2 */
-#define bleep(x) if(tt_bell)putchar('\07')
-#endif /* OS2 */
-
-#ifndef BEOSORBEBOX
-#ifdef BEBOX /* This was used only for DR7 */
-#define BEOSORBEBOX
-#else
-#ifdef BEOS /* This is used for BeOS 4.x */
-#define BEOSORBEBOX
-#endif /* BEOS */
-#endif /* BEBOX */
-#endif /* BEOSORBEBOX */
-
-#ifdef NOICP
-#ifdef TLOG
-#undef TLOG
-#endif /* TLOG */
-#endif /* NOICP */
-
-/* Formats for debug() and tlog() */
-
-#define F000 0
-#define F001 1
-#define F010 2
-#define F011 3
-#define F100 4
-#define F101 5
-#define F110 6
-#define F111 7
-
-#ifdef __linux__
-#ifndef LINUX
-#define LINUX
-#endif /* LINUX */
-#endif /* __linux__ */
-
-/* Platforms where small size is needed */
-
-#ifdef pdp11
-#define CK_SMALL
-#endif /* pdp11 */
-
-/* Can we use realpath()? */
-
-#ifndef NOREALPATH
-#ifdef pdp11
-#define NOREALPATH
-#endif /* pdp11 */
-#endif /* NOREALPATH */
-
-#ifndef NOREALPATH
-#ifdef UNIX
-#ifdef HPUX5
-#define NOREALPATH
-#else
-#ifdef HPUX6
-#define NOREALPATH
-#else
-#ifdef HPUX7
-#define NOREALPATH
-#else
-#ifdef HPUX8
-#define NOREALPATH
-#else
-#ifdef SV68R3V6
-#define NOREALPATH
-#else
-#ifdef XENIX
-#define NOREALPATH
-#else
-#ifdef CK_SCO32V4
-#define NOREALPATH
-#else
-#ifdef CK_SCOV5
-#define NOREALPATH
-#else
-#ifdef OSF32
-#define NOREALPATH
-#else
-#ifdef OSF30
-#define NOREALPATH
-#else
-#ifdef ultrix
-#define NOREALPATH
-#else
-#ifdef COHERENT
-#define NOREALPATH
-#endif /* COHERENT */
-#endif /* ultrix */
-#endif /* OSF30 */
-#endif /* OSF32 */
-#endif /* CK_SCOV5 */
-#endif /* CK_SCO32V4 */
-#endif /* XENIX */
-#endif /* SV68R3V6 */
-#endif /* HPUX8 */
-#endif /* HPUX7 */
-#endif /* HPUX6 */
-#endif /* HPUX5 */
-#endif /* NOREALPATH */
-
-#ifndef NOREALPATH
-#ifndef CKREALPATH
-#define CKREALPATH
-#endif /* NOREALPATH */
-#endif /* CKREALPATH */
-#endif /* UNIX */
-
-#ifdef CKREALPATH
-#ifdef OS2ORUNIX
-#ifndef CKROOT
-#define CKROOT
-#endif /* CKROOT */
-#endif /* OS2ORUNIX */
-#endif /* CKREALPATH */
-
-/* CKSYMLINK should be set only if we can use readlink() */
-
-#ifdef UNIX
-#ifndef NOSYMLINK
-#ifndef CKSYMLINK
-#define CKSYMLINK
-#endif /* NOSYMLINK */
-#endif /* CKSYMLINK */
-#endif /* UNIX */
-
-/* Platforms where we can use lstat() instead of stat() (for symlinks) */
-/* This should be set only if both lstat() and readlink() are available */
-
-#ifndef NOLSTAT
-#ifndef NOSYMLINK
-#ifndef USE_LSTAT
-#ifdef UNIX
-#ifdef CKSYMLINK
-#ifdef SVR4 /* SVR4 has lstat() */
-#define USE_LSTAT
-#else
-#ifdef BSD42 /* 4.2BSD and 4.3BSD have it */
-#define USE_LSTAT /* This should include old HPUXs */
-#else
-#ifdef BSD44 /* 4.4BSD has it */
-#define USE_LSTAT
-#else
-#ifdef LINUX /* LINUX has it */
-#define USE_LSTAT
-#else
-#ifdef SUNOS4 /* SunOS has it */
-#define USE_LSTAT
-#endif /* SUNOS4 */
-#endif /* LINUX */
-#endif /* BSD44 */
-#endif /* BSD42 */
-#endif /* SVR4 */
-#endif /* CKSYMLINK */
-#endif /* UNIX */
-#endif /* USE_LSTAT */
-#endif /* NOSYMLINK */
-#endif /* NOLSTAT */
-
-#ifdef NOLSTAT
-#ifdef USE_LSTAT
-#undef USE_LSTAT
-#endif /* USE_LSTAT */
-#endif /* NOLSTAT */
-
-#ifndef NOTTYLOCK /* UNIX systems that have ttylock() */
-#ifndef USETTYLOCK
-#ifdef AIXRS /* AIX 3.1 and later */
-#define USETTYLOCK
-#else
-#ifdef USE_UU_LOCK /* FreeBSD or other with uu_lock() */
-#define USETTYLOCK
-#else
-/*
- Prior to 8.0.299 Alpha.08 this was HAVE_BAUDBOY which was added for
- Red Hat 7.2 in May 2003 but which is no longer supported in Debian and
- OpenSuse (at least).
-*/
-#ifdef HAVE_LOCKDEV
-#define USETTYLOCK
-#endif /* HAVE_LOCKDEV */
-#endif /* USE_UU_LOCK */
-#endif /* AIXRS */
-#endif /* USETTYLOCK */
-#endif /* NOTTYLOCK */
-
-#ifndef NO_OPENPTY /* Can use openpty() */
-#ifndef HAVE_OPENPTY
-#ifdef __linux__
-#define HAVE_OPENPTY
-#else
-#ifdef __FreeBSD__
-#define HAVE_OPENPTY
-#else
-#ifdef __OpenBSD__
-#define HAVE_OPENPTY
-#else
-#ifdef __NetBSD__
-#define HAVE_OPENPTY
-#else
-#ifdef MACOSX10
-#define HAVE_OPENPTY
-#endif /* MACOSX10 */
-#endif /* __NetBSD__ */
-#endif /* __OpenBSD__ */
-#endif /* __FreeBSD__ */
-#endif /* __linux__ */
-#endif /* HAVE_OPENPTY */
-#endif /* NO_OPENPTY */
-
-/* Kermit feature selection */
-
-#ifndef NOSPL
-#ifndef NOCHANNELIO /* Channel-based file i/o package */
-#ifndef CKCHANNELIO
-#ifdef UNIX
-#define CKCHANNELIO
-#else
-#ifdef OS2
-#define CKCHANNELIO
-#else
-#ifdef VMS
-#define CKCHANNELIO
-#else
-#ifdef STRATUS
-#define CKCHANNELIO
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIX */
-#endif /* CKCHANNELIO */
-#endif /* NOCHANNELIO */
-#endif /* NOSPL */
-
-#ifndef NOCKEXEC /* EXEC command */
-#ifndef NOPUSH
-#ifndef CKEXEC
-#ifdef UNIX /* UNIX can do it */
-#define CKEXEC
-#endif /* UNIX */
-#endif /* CKEXEC */
-#endif /* NOPUSH */
-#endif /* NOCKEXEC */
-
-#ifndef NOFAST /* Fast Kermit protocol by default */
-#ifndef CK_FAST
-#ifdef UNIX
-#define CK_FAST
-#else
-#ifdef VMS
-#define CK_FAST
-#else
-#ifdef OS2
-#define CK_FAST
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* CK_FAST */
-#endif /* NOFAST */
-
-#ifdef UNIX /* Transparent print */
-#ifndef NOXPRINT
-#ifndef XPRINT
-#define XPRINT
-#endif /* XPRINT */
-#endif /* NOXPRINT */
-#endif /* UNIX */
-
-#ifndef NOHWPARITY /* Hardware parity */
-#ifndef HWPARITY
-#ifdef SVORPOSIX /* System V or POSIX can have it */
-#define HWPARITY
-#else
-#ifdef SUNOS41 /* SunOS 4.1 can have it */
-#define HWPARITY
-#else
-#ifdef OS2 /* K95 can have it */
-#define HWPARITY
-#endif /* OS2 */
-#endif /* SUNOS41 */
-#endif /* SVORPOSIX */
-#endif /* HWPARITY */
-#endif /* NOHWPARITY */
-
-#ifndef NOSTOPBITS /* Stop-bit selection */
-#ifndef STOPBITS
-#ifdef OS2ORUNIX
-/* In Unix really this should only be if CSTOPB is defined. */
-/* But we don't know that yet. */
-#define STOPBITS
-#else
-#ifdef TN_COMPORT
-#define STOPBITS
-#endif /* TN_COMPORT */
-#endif /* OS2ORUNIX */
-#endif /* STOPBITS */
-#endif /* NOSTOPBITS */
-
-#ifdef UNIX
-#ifndef NETCMD /* Can SET NETWORK TYPE COMMAND */
-#define NETCMD
-#endif /* NETCMD */
-#endif /* UNIX */
-
-/* Pty support, nonportable, available on a case-by-case basis */
-
-#ifndef NOPTY
-#ifdef NEXT /* NeXTSTEP (tested on 3.1)*/
-#define NETPTY
-#else
-#ifdef CK_SCOV5 /* SCO OSR5 (tested on 5.0.5)*/
-#define NETPTY
-#else
-#ifdef QNX /* QNX (tested on 4.25) */
-#define NETPTY
-#else
-#ifdef SINIX /* Sinix (tested on 5.42) */
-#define NETPTY
-#else
-#ifdef DGUX540 /* DG/UX 5.4++ (tested on 5.4R4.11) */
-#define NETPTY
-#else
-#ifdef OSF32 /* Digital Unix 3.2 */
-#define NETPTY
-#else
-#ifdef OSF40 /* Digital Unix 4.0 / Tru64 */
-#define NETPTY
-#else
-#ifdef IRIX60 /* IRIX 6.0 (not earlier) */
-#define NETPTY
-#else
-#ifdef HPUX10 /* HPUX 10.00 or later */
-#define NETPTY
-#ifndef HAVE_PTYTRAP
-#define HAVE_PTYTRAP
-#endif /* HAVE_PTYTRAP */
-#else
-#ifdef HPUX9 /* HPUX 9.00 (not earlier) */
-#define NETPTY
-#ifndef HAVE_PTYTRAP
-#define HAVE_PTYTRAP
-#endif /* HAVE_PTYTRAP */
-#else
-#ifdef BSD44 /* BSD44, {Net,Free,Open}BSD */
-#define NETPTY
-#else
-#ifdef BSDI /* BSDI/OS (tested in 4) */
-#define NETPTY
-#else
-#ifdef SOLARIS /* Solaris (tested in 2.5) */
-#define NETPTY
-#else
-#ifdef UW7 /* Unixware 7 */
-#define NETPTY
-#else
-#ifdef SUNOS41 /* SunOS (tested in 4.1.3) */
-#define NETPTY
-#else
-#ifdef AIX41 /* AIX 4.1 and later */
-#define NETPTY
-#else
-#ifdef LINUX /* Linux */
-#define NETPTY
-#endif /* LINUX */
-#endif /* AIX41 */
-#endif /* SUNOS41 */
-#endif /* UW7 */
-#endif /* SOLARIS */
-#endif /* BSDI */
-#endif /* BSD44 */
-#endif /* HPUX9 */
-#endif /* HPUX10 */
-#endif /* IRIX60 */
-#endif /* OSF40 */
-#endif /* OSF32 */
-#endif /* DGUX540 */
-#endif /* SINIX */
-#endif /* QNX */
-#endif /* CK_SCOV5 */
-#endif /* NEXT */
-
-#else /* NOPTY */
-
-#ifdef NETPTY
-#undef NETPTY
-#endif /* NETPTY */
-#endif /* NOPTY */
-
-#ifdef NETPTY /* NETCMD required for NETPTY */
-#ifndef NETCMD
-#define NETCMD
-#endif /* NETCMD */
-#endif /* NETPTY */
-
-#ifndef CK_UTSNAME /* Can we call uname()? */
-#ifdef VMS
-#define CK_UTSNAME
-#else
-#ifdef OS2
-#define CK_UTSNAME
-#else
-#ifdef POSIX /* It's in POSIX.1 */
-#define CK_UTSNAME
-#else
-#ifdef SUNOS41 /* It's in SunOS 4.1 */
-#define CK_UTSNAME
-#else
-#ifdef AIXRS /* It's in AIX */
-#define CK_UTSNAME
-#else
-#ifdef SVR4 /* It's in SVR4 (but not SVR3) */
-#define CK_UTSNAME
-#else
-#ifdef HPUX /* It's in HP-UX 5.00 and later */
-#define CK_UTSNAME
-#else
-#ifdef OSF /* It's in OSF/1 / Digital UNIX */
-#define CK_UTSNAME
-#else
-#ifdef CK_SCOV5
-#define CK_UTSNAME
-#endif /* CK_SCOV5 */
-#endif /* OSF */
-#endif /* HPUX */
-#endif /* SVR4 */
-#endif /* AIXRS */
-#endif /* SUNOS41 */
-#endif /* POSIX */
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* CK_UTSNAME */
-
-/* This section for anything that might use floating-point */
-
-/* If the following causes trouble use -DFLOAT=float on the command line */
-
-#ifdef NOSPL
-#ifdef FNFLOAT
-#undef FNFLOAT
-#endif /* FNFLOAT */
-#ifdef CKFLOAT
-#undef CKFLOAT
-#endif /* CKFLOAT */
-#endif /* NOSPL */
-
-#ifndef NOFLOAT
-
-#ifndef CKFLOAT
-#ifdef __alpha
-/* Don't use double on 64-bit platforms -- bad things happen */
-#define CKFLOAT float
-#define CKFLOAT_S "float"
-#else
-#define CKFLOAT double
-#define CKFLOAT_S "double"
-#endif /* __alpha */
-#endif /* CKFLOAT */
-
-#ifndef NOGFTIMER /* Floating-point timers */
-#ifndef GFTIMER
-#ifdef UNIX /* For UNIX */
-#define GFTIMER
-#endif /* UNIX */
-#ifdef VMS /* VMS */
-#ifndef OLD_VMS /* 5.0 and later */
-#define GFTIMER
-#endif /* OLD_VMS */
-#endif /* VMS */
-#ifdef OS2 /* And K95 */
-#define GFTIMER
-#endif /* OS2 */
-#ifdef STRATUS /* And Stratus VOS */
-#define GFTIMER
-#endif /* STRATUS */
-#endif /* GFTIMER */
-#endif /* NOGFTIMER */
-
-#ifndef NOSPL
-#ifndef FNFLOAT /* Floating-point math functions */
-#ifdef VMS /* defined by default in VMS */
-#define FNFLOAT
-#else
-#ifdef OS2 /* and K95 */
-#define FNFLOAT
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* FNFLOAT */
-#endif /* NOSPL */
-
-#else /* NOFLOAT is defined */
-
-#ifdef CKFLOAT
-#undef CKFLOAT
-#endif /* CKFLOAT */
-
-#ifdef GFTIMER
-#undef GFTIMER
-#endif /* GFTIMER */
-
-#ifdef FNFLOAT
-#undef FNFLOAT
-#endif /* FNFLOAT */
-
-#endif /* NOFLOAT */
-
-#ifdef GFTIMER /* Fraction of second to use when */
-#ifndef GFMINTIME /* elapsed time is <= 0 */
-#define GFMINTIME 0.005
-#endif /* GFMINTIME */
-#endif /* GFTIMER */
-
-#ifndef CKCMAI
-extern long ztmsec, ztusec; /* Fraction of sec of current time */
-#endif /* CKCMAI */
-
-#ifndef NOUNPREFIXZERO /* Allow unprefixing of NUL (0) */
-#ifndef UNPREFIXZERO /* in file-transfer packets */
-#define UNPREFIXZERO
-#endif /* UNPREFIXZERO */
-#endif /* NOUNPREFIXZERO */
-
-#ifdef CK_SMALL
-#define NOCAL /* Calibrate */
-#endif /* CK_SMALL */
-
-#ifndef NOPATTERNS /* Filetype matching patterns */
-#ifndef PATTERNS
-#ifndef VMS
-#ifndef CK_SMALL
-#define PATTERNS
-#endif /* CK_SMALL */
-#endif /* VMS */
-#endif /* PATTERNS */
-#endif /* NOPATTERNS */
-
-#ifndef NOCAL
-#ifndef CALIBRATE
-#define CALIBRATE
-#endif /* CALIBRATE */
-#else
-#ifdef CALIBRATE
-#undef CALIBRATE
-#endif /* CALIBRATE */
-#endif /* NOCAL */
-
-#ifndef NORECURSE /* Recursive directory traversal */
-#ifndef RECURSIVE
-#ifdef VMS
-#define RECURSIVE
-#else
-#ifdef OS2ORUNIX
-#ifndef CK_SMALL
-#define RECURSIVE
-#endif /* CK_SMALL */
-#else
-#ifdef STRATUS
-#define RECURSIVE
-#else
-#ifdef OSK
-#define RECURSIVE
-#endif /* OSK */
-#endif /* STRATUS */
-#endif /* OS2ORUNIX */
-#endif /* VMS */
-#endif /* RECURSIVE */
-#endif /* NORECURSE */
-
-#ifndef CK_SMALL /* Enable file-transfer tuning code */
-#ifndef CKTUNING /* in which more code is added */
-#ifndef NOTUNING /* to avoid function calls, etc */
-#define CKTUNING
-#endif /* NOTUNING */
-#endif /* CKTUNING */
-#endif /* CK_SMALL */
-
-#ifndef NOURL /* Parse URLs in SET HOST, etc */
-#define CK_URL
-#define NO_FTP_AUTH /* No auth "ftp" / "anonymous" */
-#endif /* NOURL */
-
-#ifndef NOTRIGGER
-#ifndef CK_TRIGGER /* Trigger string to exit CONNECT */
-#ifdef OS2ORUNIX /* OK for UNIX and K95 */
-#define CK_TRIGGER
-#else
-#ifdef VMS /* and VMS */
-#define CK_TRIGGER
-#else
-#ifdef datageneral /* and AOS/VS */
-#define CK_TRIGGER
-#endif /* datageneral */
-#endif /* OS2ORUNIX */
-#endif /* VMS */
-#endif /* CK_TRIGGER */
-#endif /* NOTRIGGER */
-
-#ifdef CK_TRIGGER
-#define TRIGGERS 8 /* How many triggers allowed */
-#endif /* CK_TRIGGER */
-
-#ifndef XLIMITS /* CONNECT limits */
-#ifdef OS2
-#define XLIMITS
-#endif /* OS2 */
-#endif /* XLIMITS */
-
-#ifdef NOFRILLS
-#ifndef NOBROWSER
-#define NOBROWSER
-#endif /* NOBROWSER */
-#ifndef NOFTP
-#define NOFTP
-#endif /* NOFTP */
-#endif /* NOFRILLS */
-
-#ifndef NOHTTP /* HTTP features need... */
-#ifdef NOICP /* an interactive command parser */
-#define NOHTTP
-#endif /* NOICP */
-#ifndef VMS
-#ifndef OS2ORUNIX /* K95 or UNIX (because of */
-#define NOHTTP /* time functions, time_t, etc) */
-#endif /* OS2ORUNIX */
-#endif /* VMS */
-#endif /* NOHTTP */
-
-
-#ifndef NONET
-#ifdef TCPSOCKET
-
-/* The HTTP code is not very portable, so it must be asked for with -DCKHTTP */
-
-#ifndef NOHTTP
-#ifndef CKHTTP
-#ifdef SUNOS4 /* We can use it in SunOS */
-#define CKHTTP
-#endif /* SUNOS4 */
-#ifdef SOLARIS /* And in Solaris */
-#define CKHTTP
-#endif /* SOLARIS */
-#ifdef LINUX /* And Linux */
-#define CKHTTP
-#endif /* LINUX */
-#ifdef HPUX10 /* And HP-UX 10 and above */
-#define CKHTTP
-#endif /* HPUX10 */
-#ifdef OS2 /* And in K-95 */
-#define CKHTTP
-#endif /* OS2 */
-#ifdef AIX41 /* In AIX 4.1 and higher */
-#define CKHTTP
-#endif /* AIX41 */
-#ifdef UNIXWARE /* In Unixware 2.1 and higher */
-#define CKHTTP /* and probably also in 1.x and 2.0 */
-#endif /* UNIXWARE */
-#ifdef CK_SCOV5
-#define CKHTTP
-#endif /* CK_SCOV5 */
-#ifdef OSF /* And in OSF Digital UNIX/True 64 */
-#define CKHTTP
-#endif /* OSF */
-#ifdef ultrix /* And in Ultrix Mips */
-#ifdef mips
-#define CKHTTP
-#endif /* mips */
-#endif /* ultrix */
-#ifdef __NetBSD__ /* NetBSD */
-#define CKHTTP
-#endif /* __NetBSD__ */
-#ifdef __FreeBSD__
-#define CKHTTP
-#endif /* __FreeBSD__ */
-#ifdef __OpenBSD__
-#define CKHTTP
-#endif /* __OpenBSD__ */
-/* Add more here... */
-#endif /* CKHTTP */
-#ifndef CKHTTP /* If CKHTTP not defined yet */
-#define NOHTTP /* then define NOHTTP */
-#endif /* CKHTTP */
-#endif /* NOHTTP */
-
-#ifdef NETCONN /* Special "network" types... */
-#ifndef NOLOCAL
-#ifdef OS2
-#ifndef NETFILE
-#define NETFILE
-#endif /* NETFILE */
-#ifndef NOPUSH
-#ifndef NETCMD
-#define NETCMD
-#endif /* NETCMD */
-#endif /* NOPUSH */
-#ifdef NT
-#ifndef NETDLL
-#define NETDLL
-#endif /* NETDLL */
-#endif /* NT */
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#endif /* NETCONN */
-
-#ifndef NOFTP
-#ifndef SYSFTP
-#ifndef NEWFTP
-#ifdef OS2ORUNIX
-#define NEWFTP
-#endif /* OS2ORUNIX */
-#endif /* NEWFTP */
-#endif /* SYSFTP */
-#endif /* NOFTP */
-
-#ifndef NOFTP
-#ifdef NEWFTP
-#ifdef SYSFTP
-#undef SYSFTP
-#endif /* SYSFTP */
-#else /* NEWFTP */
-#ifndef SYSFTP
-#define SYSFTP
-#endif /* SYSFTP */
-#endif /* NEWFTP */
-#else /* NOFTP */
-#ifdef NEWFTP
-#undef NEWFTP
-#endif /* NEWFTP */
-#ifdef SYSFTP
-#undef SYSFTP
-#endif /* SYSFTP */
-#endif /* NOFTP */
-
-#ifndef NOBROWSER
-#ifdef UNIX
-#ifndef BROWSER
-#ifndef NOPUSH
-#define BROWSER
-#endif /* NOPUSH */
-#endif /* BROWSER */
-#endif /* UNIX */
-#ifdef OS2
-#ifndef BROWSER
-#ifndef NOPUSH
-#define BROWSER
-#endif /* NOPUSH */
-#endif /* BROWSER */
-#endif /* OS2 */
-#else
-#ifdef BROWSER
-#undef BROWSER
-#endif /* BROWSER */
-#endif /* NOBROWSER */
-
-#else /* TCPSOCKET */
-#ifndef NOHTTP /* HTTP requires TCPSOCKET */
-#define NOHTTP
-#endif /* NOHTTP */
-#endif /* TCPSOCKET */
-#endif /* NONET */
-
-#ifdef TCPSOCKET
-#ifndef NOCKGETFQHOST
-#ifdef __ia64__
-#define NOCKGETFQHOST
-#else /* __ia64__ */
-#ifdef SV68
-#define NOCKGETFQHOST
-#else
-#ifdef HPUXPRE65
-#define NOCKGETFQHOST
-#endif /* HPUXPRE65 */
-#endif /* SV68 */
-#endif /* __ia64 */
-#endif /* NOCKGETFQHOST */
-/*
- Regarding System V/68 (SV68) (from Gerry Belanger, Oct 2002):
-
- 1) The gethostbyname() appears to return the actual host IP
- address in the hostent struct, instead of the expected pointer
- to the address. Hence the bogus address in the bcopy/memcopy.
- This is despite the header agreeing with our expectations.
-
- 2) the expected argument swap between bcopy and memcopy
- did not happen. What grief this might cause, I know not.
-*/
-#endif /* TCPSOCKET */
-
-#ifdef TCPSOCKET
-#ifdef OS2ONLY
-#ifndef NOSOCKS
-#define NOSOCKS
-#endif /* NOSOCKS */
-#endif /* OS2ONLY */
-#ifdef NOSOCKS
-#ifdef CK_SOCKS
-#undef CK_SOCKS
-#endif /* CK_SOCKS */
-#ifdef CK_SOCKS5
-#undef CK_SOCKS5
-#endif /* CK_SOCKS5 */
-#else /* NOSOCKS */
-#ifdef NT
-#ifndef CK_SOCKS
-#define CK_SOCKS
-#endif /* CK_SOCKS */
-#endif /* NT */
-#ifdef CK_SOCKS5 /* CK_SOCKS5 implies CK_SOCKS */
-#ifndef CK_SOCKS
-#define CK_SOCKS
-#endif /* CK_SOCKS */
-#endif /* CK_SOCKS5 */
-#endif /* NOSOCKS */
-#endif /* TCPSOCKET */
-
-#ifdef TNCODE
-#ifndef CK_AUTHENTICATION
-#ifdef OS2
-#ifdef _M_PPC
-#define NO_KERBEROS
-#define NO_SRP
-#else /* _M_PPC */
-#ifndef NO_SSL
-#define CK_SSL
-#define SSLDLL
-#endif /* NO_SSL */
-#endif /* _M_PPC */
-#ifndef NO_KERBEROS
-#define CK_KERBEROS
-#define KRB4
-#define KRB5
-#define KRB524
-#define KRB524_CONV
-#ifdef NT
-#ifndef _M_PPC
-#ifndef _M_ALPHA
-#ifndef NO_SSL_KRB5
-#define SSL_KRB5
-#endif /* NO_SSL_KRB5 */
-#endif /* _M_ALPHA */
-#endif /* _M_PPC */
-#endif /* NT */
-#endif /* NO_KERBEROS */
-#ifndef NO_SRP
-#define CK_SRP
-#endif /* NO_SRP */
-#define CK_AUTHENTICATION
-#endif /* OS2 */
-#endif /* CK_AUTHENTICATION */
-
-#ifdef CK_AUTHENTICATION /* Encryption must have Auth */
-#ifndef CK_ENCRYPTION
-#ifndef NO_ENCRYPTION
-#ifdef OS2
-#define CK_ENCRYPTION
-#define CK_DES
-#define CK_CAST
-#endif /* OS2 */
-#endif /* NO_ENCRYPTION */
-#endif /* CK_ENCRYPTION */
-#endif /* CK_AUTHENTICATION */
-
-#ifdef NO_AUTHENTICATION /* Allow authentication to be */
-#ifdef CK_AUTHENTICATION /* disabled in NT and OS/2 */
-#undef CK_AUTHENTICATION
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_KERBEROS
-#undef CK_KERBEROS
-#endif /* CK_KERBEROS */
-#ifdef CK_SRP
-#undef CK_SRP
-#endif /* CK_SRP */
-#ifdef CK_ENCRYPTION
-#undef CK_ENCRYPTION
-#endif /* CK_ENCRYPTION */
-#endif /* NO_AUTHENTICATION */
-
-#ifdef NO_ENCRYPTION /* Allow encryption to be */
-#ifdef CK_ENCRYPTION /* disabled in NT and OS/2 */
-#undef CK_ENCRYPTION
-#endif /* CK_ENCRYPTION */
-#endif /* NO_ENCRYPTION */
-
-#ifdef CK_KERBEROS /* Disable funcs not yet supported with Heimdal */
-#ifdef KRB5
-#ifndef HEIMDAL
-#define KRB5_U2U
-#endif /* HEIMDAL */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-/*
- SSH section. NOSSH disables any form of SSH support.
- If NOSSH is not defined (or implied by NONET, NOLOCAL, etc)
- then SSHBUILTIN is defined for K95 and SSHCMD is defined for UNIX.
- Then, if either SSHBUILTIN or SSHCMD is defined, ANYSSH is also defined.
-*/
-
-#ifndef NOSSH
-#ifndef NO_SSL
-#ifdef OS2ONLY
-#define NOSSH
-#endif /* OS2ONLY */
-#ifdef NT
-#ifndef CK_SSL
-#define NOSSH
-#endif /* CK_SSL */
-#endif /* NT */
-#else /* NO_SSL */
-#define NOSSH
-#endif /* NO_SSL */
-#endif /* NOSSH */
-
-#ifdef NOSSH /* NOSSH */
-#ifdef SSHBUILTIN /* undefines any SSH selctors */
-#undef SSHBUILTIN
-#endif /* SSHBUILTIN */
-#ifdef SFTP_BUILTIN
-#undef SFTP_BUILTIN
-#endif /* SFTP_BUILTIN */
-#ifdef SSHCMD
-#undef SSHCMD
-#endif /* SSHCMD */
-#ifdef ANYSSH
-#undef ANYSSH
-#endif /* ANYSSH */
-#else /* Not NOSSH */
-#ifndef NOLOCAL
-#ifdef OS2
-#ifndef SSHBUILTIN
-#define SSHBUILTIN
-#endif /* SSHBUILTIN */
-#else /* Not OS2 */
-#ifdef UNIX
-#ifndef SSHCMD
-#ifdef NETPTY
-#ifndef NOPUSH
-#define SSHCMD
-#endif /* NOPUSH */
-#endif /* NETPTY */
-#endif /* SSHCMD */
-#endif /* UNIX */
-#endif /* OS2 */
-#ifndef ANYSSH
-#ifdef SSHBUILTIN
-#define ANYSSH
-#ifdef SSHCMD
-#undef SSHCMD
-#endif /* SSHCMD */
-#else /* SSHBUILTIN */
-#ifdef SSHCMD
-#define ANYSSH
-#endif /* SSHCMD */
-#endif /* SSHBUILTIN */
-#endif /* ANYSSH */
-#endif /* NOLOCAL */
-#endif /* NOSSH */
-
-/* This is in case #ifdef SSH is used anywhere in the K95 modules */
-
-#ifdef OS2
-#ifdef SSHBUILTIN
-#ifndef SSH
-#define SSH
-#endif /* SSH */
-#endif /* SSHBUILTIN */
-#endif /* OS2 */
-
-#ifdef CK_AUTHENTICATION
-#define CK_SECURITY
-#else
-#ifdef CK_SSL
-#define CK_AUTHENTICATION
-#define CK_SECURITY
-#endif /* CK_SSL */
-#endif /* CK_AUTHENTICATION */
-
-/* Environment stuff */
-
-#ifndef OS2ORUNIX
-#ifndef NOPUTENV
-#define NOPUTENV
-#endif /* NOPUTENV */
-#endif /* OS2ORUNIX */
-
-#ifndef CK_ENVIRONMENT
-#ifdef OS2
-#define CK_ENVIRONMENT
-#else
-#ifdef UNIX
-#define CK_ENVIRONMENT
-#else
-#ifdef STRATUS
-#define CK_ENVIRONMENT
-#else
-#ifdef VMS
-#define CK_ENVIRONMENT
-#endif /* VMS */
-#endif /* STRATUS */
-#endif /* UNIX */
-#endif /* OS2 */
-#endif /* CK_ENVIRONMENT */
-#ifndef NOSNDLOC /* RFC 779 SEND LOCATION */
-#ifndef CK_SNDLOC
-#define CK_SNDLOC
-#endif /* CK_SNDLOC */
-#endif /* NOSNDLOC */
-#ifndef NOXDISPLOC /* RFC 1096 XDISPLOC */
-#ifndef CK_XDISPLOC
-#define CK_XDISPLOC
-#endif /* CK_XDISPLOC */
-#endif /* NOXDISPLOC */
-#ifndef NOFORWARDX
-#ifndef NOPUTENV
-#ifndef NOSELECT
-#ifndef CK_FORWARD_X
-#ifdef CK_AUTHENTICATION
-#ifndef OS2ONLY
-#define CK_FORWARD_X
-#endif /* OS2ONLY */
-#endif /* CK_AUTHENTICATION */
-#endif /* CK_FORWARD_X */
-#endif /* NOSELECT */
-#endif /* NOPUTENV */
-#endif /* NOFORWARDX */
-#ifndef NO_COMPORT
-#ifdef TCPSOCKET
-#ifndef TN_COMPORT
-#define TN_COMPORT
-#endif /* TN_COMPORT */
-#endif /* TCPSOCKET */
-#endif /* NO_COMPORT */
-#endif /* TNCODE */
-
-#ifndef NOXFER
-#ifndef NOCTRLZ /* Allow SET FILE EOF CTRL-Z */
-#ifndef CK_CTRLZ
-#ifdef OS2ORUNIX
-#define CK_CTRLZ
-#endif /* OS2ORUNIX */
-#endif /* CK_CTRLZ */
-#endif /* NOCTRLZ */
-#endif /* NOXFER */
-
-#ifndef NOPERMS /* File permissions in A packets */
-#ifndef CK_PERMS
-#ifdef UNIX
-#define CK_PERMS
-#else
-#ifdef VMS
-#define CK_PERMS
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* CK_PERMS */
-#endif /* NOPERMS */
-#ifdef CK_PERMS
-#define CK_PERMLEN 24 /* Max length of sys-dependent perms */
-#endif /* CK_PERMS */
-
-#ifdef UNIX /* NOSETBUF for everybody */
-#ifndef NOSETBUF
-#ifndef USE_SETBUF /* This is the escape clause */
-#define NOSETBUF
-#endif /* USE_SETBUF */
-#endif /* NOSETBUF */
-#endif /* UNIX */
-
-#ifndef USE_STRERROR /* Whether to use strerror() */
-#ifdef pdp11
-#define USE_STRERROR
-#endif /* pdp11 */
-#endif /* USE_STRERROR */
-
-#ifdef VMS /* Features for all VMS builds */
-#ifndef NOJC
-#define NOJC
-#endif /* NOJC */
-#ifndef NOSETBUF
-#define NOSETBUF
-#endif /* NOSETBUF */
-#ifndef DYNAMIC
-#define DYNAMIC
-#endif /* DYNAMIC */
-#ifndef NOCURSES
-#ifndef CK_CURSES
-#define CK_CURSES
-#endif /* CK_CURSES */
-#endif /* NOCURSES */
-#endif /* VMS */
-
-#ifndef NOCKTIMERS /* Dynamic timeouts */
-#ifndef CK_TIMERS
-#define CK_TIMERS
-#endif /* CK_TIMERS */
-#endif /* NOCKTIMERS */
-
-#define CK_SPEED /* Control-prefix removal */
-#ifdef NOCKSPEED
-#undef CK_SPEED
-#endif /* NOCKSPEED */
-
-#ifndef NOCKXXCHAR
-#ifndef CKXXCHAR
-#ifdef UNIX
-#define CKXXCHAR
-#else
-#ifdef OS2
-#define CKXXCHAR
-#endif /* OS2 */
-#endif /* UNIX */
-#endif /* CKXXCHAR */
-#endif /* NOCKXXCHAR */
-
-#ifdef MAC /* For Macintosh, no escape */
-#define NOPUSH /* to operating system */
-#endif /* MAC */
-
-/* Systems where we can call zmkdir() to create directories. */
-
-#ifndef CK_MKDIR
-#ifndef NOMKDIR
-
-#ifdef UNIX
-#ifndef pdp11
-#define CK_MKDIR
-#endif /* pdp11 */
-#endif /* UNIX */
-
-#ifdef OS2
-#define CK_MKDIR
-#endif /* OS2 */
-
-#ifdef VMS
-#define CK_MKDIR
-#endif /* VMS */
-
-#ifdef STRATUS
-#define CK_MKDIR
-#endif /* STRATUS */
-
-#ifdef OSK
-#define CK_MKDIR
-#endif /* OSK */
-
-#ifdef datageneral
-#define CK_MKDIR
-#endif /* datageneral */
-
-#endif /* CK_MKDIR */
-#endif /* NOMKDIR */
-
-#ifdef NOMKDIR /* Allow for command-line override */
-#ifdef CK_MKDIR
-#undef CK_MKDIR
-#endif /* CK_MKDIR */
-#endif /* NOMKDIR */
-
-/* Systems for which we can enable the REDIRECT command automatically */
-/* As of 6.0.193, it should work for all UNIX... */
-
-#ifndef NOREDIRECT
-#ifndef CK_REDIR
-#ifdef UNIX
-#define CK_REDIR
-#endif /* UNIX */
-#ifdef OS2 /* As well as OS/2 and friends... */
-#define CK_REDIR
-#endif /* OS2 */
-#endif /* CK_REDIR */
-#endif /* NOREDIRECT */
-
-#ifdef NOPUSH /* But... REDIRECT command is not */
-#ifdef CK_REDIR /* allowed if NOPUSH is defined. */
-#undef CK_REDIR
-#endif /* CK_REDIR */
-#ifdef NETCMD /* Nor is SET NET COMMAND */
-#undef NETCMD
-#endif /* NETCMD */
-#ifdef NETPTY
-#undef NETPTY
-#endif /* NETPTY */
-#endif /* NOPUSH */
-
-#ifndef PEXITSTAT /* \v(pexitstat) variable defined */
-#ifdef OS2ORUNIX
-#define PEXITSTAT
-#else
-#ifdef VMS
-#define PEXITSTAT
-#endif /* VMS */
-#endif /* OS2ORUNIX */
-#endif /* PEXITSTAT */
-
-/* The following allows automatic enabling of REDIRECT to be overridden... */
-
-#ifdef NOREDIRECT
-#ifdef NETCMD
-#undef NETCMD
-#endif /* NETCMD */
-#ifdef NETPTY
-#undef NETPTY
-#endif /* NETPTY */
-#ifdef CK_REDIR
-#undef CK_REDIR
-#endif /* CK_REDIR */
-#endif /* NOREDIRECT */
-
-#ifdef NONETCMD
-#ifdef NETCMD
-#undef NETCMD
-#endif /* NETCMD */
-#ifdef NETPTY
-#undef NETPTY
-#endif /* NETPTY */
-#endif /* NONETCMD */
-
-#ifdef CK_REDIR
-_PROTOTYP( int ttruncmd, (char *) );
-#endif /* CK_REDIR */
-
-/* Use built-in DIRECTORY command */
-
-#ifndef NOMYDIR
-#ifndef DOMYDIR
-#ifdef UNIXOROSK
-#define DOMYDIR
-#else
-#ifdef OS2
-#define DOMYDIR
-#else
-#ifdef VMS
-#define DOMYDIR
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIXOROSK */
-#endif /* DOMYDIR */
-#endif /* NOMYDIR */
-
-/* Sending from and receiving to commands/pipes */
-
-#ifndef PIPESEND
-#ifdef UNIX
-#define PIPESEND
-#endif /* UNIX */
-#ifdef OS2
-#define PIPESEND
-#endif /* OS2 */
-#endif /* PIPESEND */
-
-#ifdef PIPESEND
-#ifdef NOPIPESEND
-#undef PIPESEND
-#endif /* NOPIPESEND */
-#ifdef NOPUSH
-#undef PIPESEND
-#endif /* NOPUSH */
-#endif /* PIPESEND */
-
-#ifdef NOPUSH
-#ifdef BROWSER
-#undef BROWSER
-#endif /* BROWSER */
-#endif /* NOPUSH */
-
-/* Versions where we support the RESEND command */
-
-#ifndef NOXFER
-#ifndef NORESEND
-#ifndef CK_RESEND
-#ifdef UNIX
-#ifndef pdp11
-#define CK_RESEND
-#endif /* pdp11 */
-#endif /* UNIX */
-
-#ifdef VMS
-#define CK_RESEND
-#endif /* VMS */
-
-#ifdef OS2
-#define CK_RESEND
-#endif /* OS2 */
-
-#ifdef AMIGA
-#define CK_RESEND
-#endif /* AMIGA */
-
-#ifdef datageneral
-#define CK_RESEND
-#endif /* datageneral */
-
-#ifdef STRATUS
-#define CK_RESEND
-#endif /* STRATUS */
-
-#ifdef OSK
-#define CK_RESEND
-#endif /* OSK */
-
-#endif /* CK_RESEND */
-#endif /* NORESEND */
-#endif /* NOXFER */
-
-/* Systems implementing "Doomsday Kermit" protocol ... */
-
-#ifndef DOOMSDAY
-#ifdef UNIX
-#define DOOMSDAY
-#else
-#ifdef VMS
-#define DOOMSDAY
-#else
-#ifdef OS2
-#define DOOMSDAY
-#else
-#ifdef STRATUS
-#define DOOMSDAY
-#endif /* STRATUS */
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* DOOMSDAY */
-
-/* Systems where we want the Thermometer to be used for fullscreen */
-
-#ifdef OS2
-#ifndef CK_PCT_BAR
-#define CK_PCT_BAR
-#endif /* CK_PCT_BAR */
-#endif /* OS2 */
-
-/* Systems where we have a REXX command */
-
-#ifdef OS2
-#ifdef __32BIT__
-#ifndef NOREXX
-#define CK_REXX
-#endif /* NOREXX */
-#endif /* __32BIT__ */
-#endif /* OS2 */
-
-/* Platforms that have a ZCHKPID function */
-
-#ifdef OS2ORUNIX
-#define ZCHKPID
-#endif /* OS2ORUNIX */
-
-#ifndef ZCHKPID
-/* If we can't check pids then we have treat all pids as active & valid. */
-#define zchkpid(x) 1
-#endif /* ZCHKPID */
-
-/* Systems that have a ZRENAME function */
-
-#define ZRENAME /* They all do */
-
-/* Systems that have a ZCOPY function */
-
-#ifndef ZCOPY
-#ifdef VMS
-#define ZCOPY
-#else
-#ifdef OS2
-#define ZCOPY
-#else
-#ifdef UNIX
-#define ZCOPY
-#else
-#ifdef STRATUS
-#define ZCOPY
-#endif /* STRATUS */
-#endif /* UNIX */
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* ZCOPY */
-
-/* Systems that have ttgwsiz() (they all should but they don't) */
-
-#ifndef NOTTGWSIZ
-#ifndef CK_TTGWSIZ
-#ifdef UNIX
-#define CK_TTGWSIZ
-#else
-#ifdef VMS
-#define CK_TTGWSIZ
-#else
-#ifdef OS2
-#define CK_TTGWSIZ
-#else
-#ifdef OSK
-#define CK_TTGWSIZ
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* CK_TTGWSIZ */
-#endif /* NOTTGWSIZ */
-
-#ifdef NOTTGWSIZ
-#ifdef CK_TTGWSIZ
-#undef CK_TTGWSIZ
-#endif /* CK_TTGWSIZ */
-#endif /* NOTTGWSIZ */
-
-#ifdef OS2
-/* OS/2 C-Kermit features not available in 16-bit version... */
-
-#ifdef OS2ONLY
-#ifndef __32BIT__
-#ifndef NOLOCAL
-#ifdef PCFONTS /* PC Font support */
-#undef PCFONTS
-#endif /* PCFONTS */
-#ifdef NPIPE /* Named Pipes communication */
-#undef NPIPE
-#endif /* NPIPE */
-#ifdef CK_NETBIOS /* NETBIOS communication */
-#undef CK_NETBIOS
-#endif /* CK_NETBIOS */
-#ifdef OS2MOUSE /* Mouse */
-#undef OS2MOUSE
-#endif /* OS2MOUSE */
-#ifdef OS2PM /* Presentation Manager */
-#undef OS2PM
-#endif /* OS2PM */
-#endif /* NOLOCAL */
-#ifdef CK_REXX /* Rexx */
-#undef CK_REXX
-#endif /* CK_REXX */
-#endif /* __32BIT__ */
-#endif /* OS2ONLY */
-
-/* OS/2 C-Kermit features not available in Windows NT version... */
-
-#ifdef NT
-#ifdef PCFONTS /* PC Font support */
-#undef PCFONTS
-#endif /* PCFONTS */
-#ifdef OS2PM /* Presentation Manager */
-#undef OS2PM
-#endif /* OS2PM */
-#ifdef CK_REXX /* Rexx */
-#undef CK_REXX
-#endif /* CK_REXX */
-#endif /* NT */
-#endif /* OS2 */
-
-/*
- Systems that have select().
- This is used for both msleep() and for read-buffer checking in in_chk().
-*/
-#define CK_SLEEPINT 250 /* milliseconds - set this to something that
- divides evenly into 1000 */
-#ifndef SELECT
-#ifndef NOSELECT
-#ifdef __linux__
-#define SELECT
-#else
-#ifdef SUNOS4
-#define SELECT
-#else
-#ifdef NEXT
-#define SELECT
-#else
-#ifdef RTAIX
-#define SELECT
-#else
-#ifdef HPUX
-/*
- Not really. I think it's only in HP-UX 7.0 and later, except it's also
- in earlier versions that have TCP/IP installed. Override this default
- in particular HP-UX makefile entries by adding -DNOSELECT, as in (e.g.)
- the HP-UX 6.5 ones.
-*/
-#define SELECT
-#else
-#ifdef AIXRS
-#define SELECT
-#else
-#ifdef BSD44
-#define SELECT
-#else
-#ifdef BSD4
-#define SELECT
-#else
-#ifdef OXOS
-#define SELECT
-#else
-#ifdef OS2
-#define SELECT
-#else
-#ifdef BEBOX
-#define SELECT
-#endif /* BEBOX */
-#endif /* OS2 */
-#endif /* OXOS */
-#endif /* BSD4 */
-#endif /* BSD44 */
-#endif /* AIXRS */
-#endif /* HPUX */
-#endif /* RTAIX */
-#endif /* NEXT */
-#endif /* __linux__ */
-#endif /* SUNOS4 */
-#endif /* NOSELECT */
-#endif /* SELECT */
-
-/*
- The following section moved here from ckcnet.h in 6.1 because select()
- is now used for non-networking purposes.
-*/
-
-/* On HP-9000/500 HP-UX 5.21 this stuff is not defined in any header file */
-
-#ifdef hp9000s500
-#ifndef NEEDSELECTDEFS
-#define NEEDSELECTDEFS
-#endif /* NEEDSELECTDEFS */
-#endif /* hp9000s500 */
-
-#ifdef NEEDSELECTDEFS
-typedef long fd_mask;
-#ifndef NBBY
-#define NBBY 8
-#endif /* NBBY */
-#ifndef FD_SETSIZE
-#define FD_SETSIZE 32
-#endif /* FD_SETSIZE */
-#ifndef NFDBITS
-#define NFDBITS (sizeof(fd_mask) * NBBY)
-#endif /* NFDBITS */
-#ifndef howmany
-#define howmany(x,y) (((x)+((y)-1))/(y))
-#endif /* howmany */
-typedef struct fd_set {
- fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
-} fd_set;
-#ifndef FD_SET
-#define FD_SET(n,p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
-#endif /* FD_SET */
-#ifndef FD_CLR
-#define FD_CLR(n,p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
-#endif /* FD_CLR */
-#ifndef FD_ISSET
-#define FD_ISSET(n,p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
-#endif /* FD_ISSET */
-#ifndef FD_COPY
-#define FD_COPY(f,t) (bcopy(f,t,sizeof(*(f)))
-#endif /* FD_COPY */
-#ifndef FD_ZERO
-#define FD_ZERO(p) bzero((char *)(p),sizeof(*(p)))
-#endif /* FD_ZERO */
-#endif /* NEEDSELECTDEFS */
-
-/*
- CK_NEED_SIG is defined if the system cannot check the console to
- to see if characters are waiting. This is used during local-mode file
- transfer to interrupt the transfer, refresh the screen display, etc.
- If CK_NEED_SIG is defined, then file-transfer interruption characters
- have to be preceded a special character, e.g. the SIGQUIT character.
- CK_NEED_SIG should be defined if the conchk() function is not operational.
-*/
-#ifdef NOPOLL /* For overriding CK_POLL definition */
-#ifdef CK_POLL
-#undef CK_POLL
-#endif /* CK_POLL */
-#endif /* NOPOLL */
-
-#ifndef CK_POLL /* If we don't have poll() */
-#ifndef RDCHK /* And we don't have rdchk() */
-#ifndef SELECT /* And we don't have select() */
-#ifdef ATTSV
-#ifndef aegis
-#ifndef datageneral
-#ifndef OXOS
-#define CK_NEED_SIG
-#endif /* OXOS */
-#endif /* datageneral */
-#endif /* aegis */
-#endif /* ATTSV */
-#ifdef POSIX
-#ifndef CK_NEED_SIG
-#define CK_NEED_SIG
-#endif /* CK_NEED_SIG */
-#endif /* POSIX */
-#endif /* SELECT */
-#endif /* RDCHK */
-#endif /* CK_POLL */
-
-#ifdef HPUX /* HP-UX has select() */
-#ifdef CK_NEED_SIG
-#undef CK_NEED_SIG
-#endif /* CK_NEED_SIG */
-#endif /* HPUX */
-
-#ifdef AIXRS /* AIX has select() */
-#ifdef CK_NEED_SIG
-#undef CK_NEED_SIG
-#endif /* CK_NEED_SIG */
-#endif /* AIXRS */
-
-#ifdef BSD44 /* 4.4BSD has FIONREAD */
-#ifdef CK_NEED_SIG
-#undef CK_NEED_SIG
-#endif /* CK_NEED_SIG */
-#endif /* BSD44 */
-
-#ifdef QNX /* QNX has FIONREAD and select() */
-#ifdef CK_NEED_SIG
-#undef CK_NEED_SIG
-#endif /* CK_NEED_SIG */
-#endif /* QNX */
-
-#ifdef COHERENT
-#ifndef NOTIMEZONE
-#define NOTIMEZONE
-#endif /* NOTIMEZONE */
-#endif /* COHERENT */
-
-#ifdef UNIX
-#ifndef HAVE_TZ /* Can we use struct timezone? */
-#ifndef NOTIMEZONE
-#ifdef PTX
-#define NOTIMEZONE
-#else
-#ifndef SELECT
-#ifdef COHERENT
-#define NOTIMEZONE
-#else
-#ifdef BELLV10
-#define NOTIMEZONE
-#endif /* BELLV10 */
-#endif /* COHERENT */
-#endif /* SELECT */
-#endif /* PTX */
-#endif /* NOTIMEZONE */
-#endif /* HAVE_TZ */
-#ifndef NOTIMEVAL /* Can we use struct timeval? */
-#ifndef HAVE_TV
-#define HAVE_TV
-#endif /* HAVE_TV */
-#endif /* NOTIMEVAL */
-#ifndef NOTIMEZONE
-#ifndef HAVE_TZ
-#define HAVE_TZ
-#endif /* HAVE_TZ */
-#endif /* NOTIMEZONE */
-#endif /* UNIX */
-
-#ifdef SCO32
-#ifdef HAVE_TV
-#undef HAVE_TV
-#endif /* HAVE_TV */
-#ifdef HAVE_TZ
-#undef HAVE_TZ
-#endif /* HAVE_TZ */
-#ifndef NOTIMEVAL
-#define NOTIMEVAL
-#endif /* NOTIMEVAL */
-#ifndef NOTIMEZONE
-#define NOTIMEZONE
-#endif /* NOTIMEZONE */
-#endif /* SCO32 */
-
-#ifdef ATT7300
-#ifdef HAVE_TV
-#undef HAVE_TV
-#endif /* HAVE_TV */
-#ifdef HAVE_TZ
-#undef HAVE_TZ
-#endif /* HAVE_TZ */
-#ifndef NOTIMEVAL
-#define NOTIMEVAL
-#endif /* NOTIMEVAL */
-#ifndef NOTIMEZONE
-#define NOTIMEZONE
-#endif /* NOTIMEZONE */
-#endif /* ATT7300 */
-
-/*
- Automatic parity detection.
- This actually implies a lot more now: length-driven packet reading,
- "Doomsday Kermit" IBM Mainframe file transfer through 3270 data streams, etc.
-*/
-#ifdef UNIX /* For Unix */
-#ifndef NOPARSEN
-#define PARSENSE
-#endif /* NOPARSEN */
-#endif /* UNIX */
-
-#ifdef VMS /* ... and VMS */
-#ifndef NOPARSEN
-#define PARSENSE
-#endif /* NOPARSEN */
-#ifdef __GNUC__
-#define VMSGCC
-#endif /* __GNUC__ */
-#endif /* VMS */
-
-#ifdef MAC /* and Macintosh */
-#ifndef NOPARSEN
-#define PARSENSE
-#endif /* NOPARSEN */
-#endif /* MAC */
-
-#ifdef STRATUS /* and Stratus VOS */
-#ifndef NOPARSEN
-#define PARSENSE
-#endif /* NOPARSEN */
-#endif /* STRATUS */
-
-#ifdef OS2 /* and OS/2, finally */
-#ifndef NOPARSEN
-#define PARSENSE
-#endif /* NOPARSEN */
-#endif /* OS2 */
-
-#ifndef NODYNAMIC /* DYNAMIC is default for UNIX */
-#ifndef DYNAMIC /* as of C-Kermit 7.0 */
-#ifdef UNIX
-#define DYNAMIC
-#endif /* UNIX */
-#endif /* DYNAMIC */
-#endif /* NODYNAMIC */
-
-#ifdef DYNAMIC /* If DYNAMIC is defined */
-#define DCMDBUF /* then also define this. */
-#endif /* DYNAMIC */
-
-#ifndef CK_LBRK /* Can send Long BREAK */
-
-#ifdef UNIX /* (everybody but OS-9) */
-#define CK_LBRK
-#endif /* UNIX */
-#ifdef VMS
-#define CK_LBRK
-#endif /* VMS */
-#ifdef datageneral
-#define CK_LBRK
-#endif /* datageneral */
-#ifdef GEMDOS
-#define CK_LBRK
-#endif /* GEMDOS */
-#ifdef OS2
-#define CK_LBRK
-#endif /* OS2 */
-#ifdef AMIGA
-#define CK_LBRK
-#endif /* AMIGA */
-#ifdef STRATUS
-#define CK_LBRK
-#endif /* STRATUS */
-
-#endif /* CK_LBRK */
-
-/* Carrier treatment */
-/* These are defined here because they are shared by the system dependent */
-/* and the system independent modules. */
-
-#define CAR_OFF 0 /* Off: ignore carrier always. */
-#define CAR_ON 1 /* On: heed carrier always, except during DIAL. */
-#define CAR_AUT 2 /* Auto: heed carrier, but only if line is declared */
- /* to be a modem line, and only during CONNECT. */
-
-/* And more generically (for use with any ON/OFF/AUTO feature) */
-#define CK_OFF 0
-#define CK_ON 1
-#define CK_AUTO 2
-
-#ifndef NOLOCAL
-/*
- Serial interface speeds available.
-
- As of C-Kermit 6.1 there is a new method to get the supported
- speeds, which obviates the need for all the craziness below. At runtime,
- just call the new ttspdlist() routine to get a list of supported speeds.
- Then the user interface module can build a keyword table or menu from it.
-*/
-#ifndef TTSPDLIST
-#ifdef UNIX /* For now, only for UNIX */
-#ifndef OLINUXHISPEED /* But not systems with hacks for */
-#ifndef MINIX /* high speeds, like 110 = 115200 */
-#define TTSPDLIST
-#endif /* MINIX */
-#endif /* OLINUXHISPEED */
-#else
-#ifdef VMS
-#define TTSPDLIST /* VMS gets it too */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* TTSPDLIST */
-
-#ifndef NODIAL /* Hangup by modem command */
-#ifndef NOMDMHUP
-#ifndef MDMHUP
-#define MDMHUP
-#endif /* MDMHUP */
-#endif /* NOMDMHUP */
-#endif /* NODIAL */
-
-#ifdef NOSPL
-#ifndef NOLOGDIAL /* Connection log needs mjd(), etc. */
-#define NOLOGDIAL
-#endif /* NOLOGDIAL */
-#endif /* NOSPL */
-
-#ifdef pdp11
-#define NOLOGDIAL
-#endif /* pdp11 */
-
-#ifndef NOLOGDIAL /* Connection log */
-#ifndef CXLOGFILE
-#define CXLOGFILE "CX.LOG" /* Default connection log file name */
-#endif /* CXLOGFILE */
-#ifndef CKLOGDIAL
-#ifndef CK_SMALL
-#define CKLOGDIAL
-#define CXLOGBUFL 1024 /* Connection log record buffer size */
-#endif /* CK_SMALL */
-#endif /* NOLOGDIAL */
-#endif /* CKLOGDIAL */
-
-#endif /* NOLOCAL */
-
-#ifdef NOTTSPDLIST /* Except if NOTTSPDLIST is defined */
-#ifdef TTSPDLIST
-#undef TTSPDLIST
-#endif /* TTSPDLIST */
-#endif /* NOTTSPDLIST */
-
-#ifdef TTSPDLIST
-
-_PROTOTYP( long * ttspdlist, (void) );
-
-#else /* TTSPDLIST not defined */
-/*
- We must use a long and convoluted series of #ifdefs that have to be kept in
- sync with the code in the ck?tio.c module.
-
- We assume that everybody supports: 0, 110, 300, 600, 1200, 2400, 4800, and
- 9600 bps. Symbols for other speeds are defined here. You can also add
- definitions on the CC command lines. These definitions affect the SET SPEED
- keyword table, and are not necessarily usable in the system-dependent
- speed-setting code in the ck?tio.c modules, which depends on system-specific
- symbols like (in UNIX) B19200. In other words, just defining it doesn't
- mean it'll work -- you also have to supply the supporting code in ttsspd()
- and ttgspd() in ck?tio.c.
-
- The symbols have the form BPS_xxxx, where xxxx is the speed in bits per
- second, or (for bps values larger than 9999) thousands of bps followed by K.
- The total symbol length should be 8 characters or less. Some values are
- enabled automatically below. You can disable a particular value by defining
- NOB_xxxx on the CC command line.
-
-*/
-
-#ifndef NOB_50
-#define BPS_50 /* 50 bps */
-#endif
-
-#ifndef NOB_75
-#define BPS_75 /* 75 bps */
-#endif
-
-#ifndef NOB7512
-#ifdef ANYBSD
-#define BPS_7512 /* 75/1200 Split Speed */
-#endif /* ANYBSD */
-#endif /* NOB7512 */
-
-#ifndef NOB134
-#ifdef SOLARIS25
-#define BPS_134
-#else
-#undef BPS_134 /* 134.5 bps (IBM 2741) */
-#endif /* BPS_134 */
-#endif /* NOB134 */
-
-#ifndef NOB_150
-#define BPS_150 /* 150 bps */
-#endif
-
-#ifndef NOB_200
-#define BPS_200 /* 200 bps */
-#endif
-
-#ifndef NOB_1800
-#ifdef MAC
-#define BPS_1800 /* 1800 bps */
-#else
-#ifdef SOLARIS25
-#define BPS_1800
-#endif
-#endif
-#endif
-
-#ifndef NOB_3600
-#ifndef SOLARIS25
-#define BPS_3600 /* 3600 bps */
-#endif
-#endif
-
-#ifndef NOB_7200
-#ifndef SOLARIS25
-#define BPS_7200 /* 7200 bps */
-#endif /* SOLARIS25 */
-#endif
-
-#ifndef NOB_14K
-#ifdef BSD44
-#define BPS_14K /* 14400 bps */
-#else
-#ifdef OS2
-#define BPS_14K
-#else
-#ifdef NEXT
-#define BPS_14K
-#else
-#ifdef MAC
-#define BPS_14K
-#else
-#ifdef AMIGA
-#define BPS_14K
-#endif /* AMIGA */
-#endif /* MAC */
-#endif /* NEXT */
-#endif /* OS2 */
-#endif /* BSD44 */
-#endif /* NOB_14K */
-
-#ifndef NOB_19K
-#define BPS_19K /* 19200 bps */
-#endif
-
-#ifndef NOB_28K
-#ifdef BSD44
-#define BPS_28K
-#else
-#ifdef OS2
-#define BPS_28K
-#else
-#ifdef NEXT
-#define BPS_28K /* 28800 bps */
-#else
-#ifdef MAC
-#define BPS_28K /* 28800 bps */
-#endif /* MAC */
-#endif /* NEXT */
-#endif /* OS2 */
-#endif /* BSD44 */
-#endif /* NOB_28K */
-
-#ifndef NOB_38K
-#define BPS_38K /* 38400 bps */
-#endif
-
-#ifndef NOB_57K
-#ifdef Plan9
-#define BPS_57K
-#else
-#ifdef SOLARIS25
-#define BPS_57K
-#else
-#ifdef VMS
-#define BPS_57K /* 57600 bps */
-#else
-#ifdef OS2
-#define BPS_57K
-#else
-#ifdef __linux__
-#define BPS_57K
-#else
-#ifdef HPUX
-#define BPS_57K
-#else
-#ifdef NEXT
-#define BPS_57K
-#else
-#ifdef __386BSD__
-#define BPS_57K
-#else
-#ifdef __FreeBSD__
-#define BPS_57K
-#else
-#ifdef __NetBSD__
-#define BPS_57K
-#else
-#ifdef MAC
-#define BPS_57K
-#else
-#ifdef QNX
-#define BPS_57K
-#else
-#ifdef BEOSORBEBOX
-#define BPS_57K
-#else
-#ifdef IRIX62
-#define BPS_57K
-#else
-#ifdef SCO_OSR504
-#define BPS_57K
-#else
-#ifdef BSDI2
-#define BPS_57K
-#endif /* BSDI2 */
-#endif /* SCO_OSR504 */
-#endif /* IRIX62 */
-#endif /* BEOSORBEBOX */
-#endif /* QNX */
-#endif /* MAC */
-#endif /* __NetBSD__ */
-#endif /* __FreeBSD__ */
-#endif /* __386BSD__ */
-#endif /* NEXT */
-#endif /* HPUX */
-#endif /* __linux__ */
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* SOLARIS25 */
-#endif /* Plan9 */
-#endif /* NOB_57K */
-
-#ifndef NOB_76K
-#ifdef BSDI2
-#define BPS_76K
-#endif /* BSDI2 */
-#ifdef Plan9
-#define BPS_76K
-#endif /* Plan9 */
-#ifdef SOLARIS25
-#define BPS_76K
-#endif /* SOLARIS25 */
-#ifdef VMS
-#define BPS_76K /* 76800 bps */
-#endif /* VMS */
-#ifdef OS2
-#ifdef __32BIT__
-#define BPS_76K
-#endif /* __32BIT__ */
-#endif /* OS2 */
-#ifdef QNX
-#define BPS_76K
-#endif /* QNX */
-#ifdef IRIX62
-#define BPS_76K
-#endif /* IRIX62 */
-#ifdef SCO_OSR504
-#define BPS_76K
-#endif /* SCO_OSR504 */
-#endif /* NOB_76K */
-
-#ifndef NOB_115K
-#ifdef BSDI2
-#define BPS_115K
-#endif /* BSDI2 */
-#ifdef Plan9
-#define BPS_115K
-#endif /* Plan9 */
-#ifdef SOLARIS25
-#define BPS_115K
-#endif /* SOLARIS25 */
-#ifdef VMS
-#define BPS_115K /* 115200 bps */
-#else
-#ifdef QNX
-#define BPS_115K
-#else
-#ifdef HPUX
-#define BPS_115K
-#else
-#ifdef __linux__
-#define BPS_115K
-#else
-#ifdef __386BSD__
-#define BPS_115K
-#else
-#ifdef __FreeBSD__
-#define BPS_115K
-#else
-#ifdef __NetBSD__
-#define BPS_115K
-#else
-#ifdef OS2
-#ifdef __32BIT__
-#define BPS_115K
-#endif /* __32BIT__ */
-#else
-#ifdef BEOSORBEBOX
-#define BPS_115K
-#else
-#ifdef IRIX62
-#define BPS_115K
-#else
-#ifdef SCO_OSR504
-#define BPS_115K
-#endif /* SCO_OSR504 */
-#endif /* IRIX62 */
-#endif /* BEOSORBEBOX */
-#endif /* OS2 */
-#endif /* __NetBSD__ */
-#endif /* __FreeBSD__ */
-#endif /* __386BSD__ */
-#endif /* __linux__ */
-#endif /* HPUX */
-#endif /* QNX */
-#endif /* VMS */
-#endif /* NOB_115K */
-
-#ifndef NOB_230K /* 230400 bps */
-#ifdef BSDI2
-#define BPS_230K
-#else
-#ifdef SCO_OSR504
-#define BPS_230K
-#else
-#ifdef __linux__
-#define BPS_230K
-#else
-#ifdef SOLARIS25
-#define BPS_230K
-#else
-#ifdef OS2
-#ifdef __32BIT__
-#define BPS_230K
-#endif /* __32BIT__ */
-#else
-#undef BPS_230K
-#endif /* OS2 */
-#endif /* SOLARIS25 */
-#endif /* __linux__ */
-#endif /* SCO_OSR504 */
-#endif /* BSDI2 */
-#endif /* NOB_230K */
-
-#ifndef NOB_460K /* 460800 bps */
-#ifdef SCO_OSR504
-#define BPS_460K
-#else
-#ifdef __linux__
-#define BPS_460K
-#else
-#ifdef OS2
-#ifdef __32BIT__
-#define BPS_460K
-#endif /* __32BIT__ */
-#else
-#undef BPS_460K
-#endif /* __linux__ */
-#endif /* SCO_OSR504 */
-#endif /* OS2 */
-#endif /* NOB_460K */
-
-#ifndef NOB_921K /* 921600 bps */
-#ifdef SCO_OSR504
-#define BPS_921K
-#endif /* SCO_OSR504 */
-#endif /* NOB_921K */
-
-#ifdef BPS_921K /* Maximum speed defined */
-#define MAX_SPD 921600L
-#else
-#ifdef BPS_460K
-#define MAX_SPD 460800L
-#else
-#ifdef BPS_230K
-#define MAX_SPD 230400L
-#else
-#ifdef BPS_115K
-#define MAX_SPD 115200L
-#else
-#ifdef BPS_76K
-#define MAX_SPD 76800L
-#else
-#ifdef BPS_57K
-#define MAX_SPD 57600L
-#else
-#ifdef BPS_38K
-#define MAX_SPD 38400L
-#else
-#ifdef BPS_28K
-#define MAX_SPD 28800L
-#else
-#ifdef BPS_19K
-#define MAX_SPD 19200L
-#else
-#ifdef BPS_14K
-#define MAX_SPD 14400L
-#else
-#define MAX_SPD 9600L
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif /* TTSPDLIST */
-
-#ifndef CONGSPD /* Systems that can call congspd() */
-#ifdef UNIX
-#define CONGSPD
-#endif /* UNIX */
-#ifdef VMS
-#define CONGSPD
-#endif /* VMS */
-#ifdef STRATUS
-#define CONGSPD
-#endif /* STRATUS */
-#endif /* CONGSPD */
-
-/* Types of flow control available */
-
-#define CK_XONXOFF /* Everybody can do this, right? */
-
-#ifdef AMIGA /* Commodore Amiga */
-#define CK_RTSCTS /* has RTS/CTS */
-#endif /* AMIGA */
-
-#ifdef SUN4S5 /* SunOS in System V environment */
-#define CK_RTSCTS
-#else /* SunOS 4.0/4.1 in BSD environment */
-#ifdef SUNOS4 /* SunOS 4.0+later supports RTS/CTS */
-#ifdef SUNOS41 /* Easy in 4.1 and later */
-#define CK_RTSCTS
-#else /* Harder in 4.0 */
-#ifndef __GNUC__ /* (see tthflow() in ckutio.c) */
-#ifndef GNUC
-#define CK_RTSCTS /* Only if not using GNU gcc */
-#endif /* __GNUC__ */
-#endif /* GNUC */
-#endif /* SUNOS41 */
-#endif /* SUNOS4 */
-#endif /* SUN4S5 */
-
-#ifdef BSD44 /* And in 4.4 BSD, including BSDI */
-#define CK_RTSCTS
-#endif /* BSD44 */
-
-#ifdef TERMIOX /* Sys V R4 <termiox.h> */
-#ifndef CK_RTSCTS
-#define CK_RTSCTS
-#endif /* CK_RTSCTS */
-#ifndef CK_DTRCD
-#define CK_DTRCD
-#endif /* CK_DTRCD */
-#else
-#ifdef STERMIOX /* Sys V R4 <sys/termiox.h> */
-#ifndef CK_RTSCTS
-#define CK_RTSCTS
-#endif /* CK_RTSCTS */
-#ifndef CK_DTRCD
-#define CK_DTRCD
-#endif /* CK_DTRCD */
-#endif /* STERMIOX */
-#endif /* TERMIOX */
-
-#ifdef OXOS /* Olivetti X/OS R2 struct termios */
-#define CK_RTSCTS /* Ditto. */
-#define CK_DTRCD
-#endif /* OXOS */
-
-#ifdef AIXRS /* RS/6000 with AIX 3.x */
-#define CK_RTSCTS /* Has its own peculiar method... */
-#endif /* AIXRS */
-
-#ifdef __linux__ /* Linux */
-#define CK_RTSCTS
-#endif /* __linux__ */
-/*
- Hardware flow control is not defined in POSIX.1. Nevertheless, a certain
- style API for hardware flow control, using tcsetattr() and the CRTSCTS
- bit(s), seems to be gaining currency on POSIX-based UNIX systems. The
- following code defines the symbol POSIX_CRTSCTS for such systems.
-*/
-#ifdef CK_RTSCTS
-#ifdef __bsdi__ /* BSDI, a.k.a. BSD/386 */
-#define POSIX_CRTSCTS
-#endif /* __bsdi__ */
-#ifdef __linux__ /* Linux */
-#define POSIX_CRTSCTS
-#endif /* __linux__ */
-#ifdef __NetBSD__ /* NetBSD */
-#define POSIX_CRTSCTS
-#endif /* __NetBSD__ */
-#ifdef __OpenBSD__
-#define POSIX_CRTSCTS
-#endif /* __OpenBSD__ */
-#ifdef BEOSORBEBOX /* BeBOX */
-#define POSIX_CRTSCTS
-/* BEBOX defines CRTSFL as (CTSFLOW & RTSFLOW) */
-#define CRTSCTS CRTSFL
-#endif /* BEOSORBEBOX */
-#ifdef IRIX52 /* IRIX 5.2 and later */
-#define POSIX_CRTSCTS
-#define CRTSCTS CNEW_RTSCTS /* See <sys/termios.h> */
-#endif /* IRIX52 */
-#endif /* CK_RTSCTS */
-
-/* Implementations that have implemented the ttsetflow() function. */
-
-#ifndef CK_TTSETFLOW
-#ifdef UNIX
-#define CK_TTSETFLOW
-#endif /* UNIX */
-#ifdef OS2
-#define CK_TTSETFLOW
-#endif /* OS2 */
-#endif /* CK_TTSETFLOW */
-
-#ifdef CK_TTSETFLOW
-_PROTOTYP( int ttsetflow, (int) );
-#endif /* CK_TTSETFLOW */
-/*
- Systems where we can expand tilde at the beginning of file or directory names
-*/
-#ifdef POSIX
-#ifndef DTILDE
-#define DTILDE
-#endif /* DTILDE */
-#endif /* POSIX */
-#ifdef BSD4
-#ifndef DTILDE
-#define DTILDE
-#endif /* DTILDE */
-#endif /* BSD4 */
-#ifdef ATTSV
-#ifndef DTILDE
-#define DTILDE
-#endif /* DTILDE */
-#endif /* ATTSV */
-#ifdef OSK
-#ifndef DTILDE
-#define DTILDE
-#endif /* DTILDE */
-#endif /* OSK */
-#ifdef HPUX /* I don't know why this is */
-#ifndef DTILDE /* necessary, since -DHPUX */
-#define DTILDE /* automatically defines ATTSV */
-#endif /* DTILDE */ /* (see above) ... */
-#endif /* HPUX */
-
-/*
- This is mainly for the benefit of ckufio.c (UNIX and OS/2 file support).
- Systems that have an atomic rename() function, so we don't have to use
- link() and unlink().
-*/
-#ifdef POSIX
-#ifndef RENAME
-#define RENAME
-#endif /* RENAME */
-#endif /* POSIX */
-
-#ifdef OS2
-#ifndef RENAME
-#define RENAME
-#endif /* RENAME */
-#endif /* OS2 */
-
-#ifdef SUNOS41
-#ifndef RENAME
-#define RENAME
-#endif /* RENAME */
-#endif /* SUNOS41 */
-
-#ifdef SVR4
-#ifndef RENAME
-#define RENAME
-#endif /* RENAME */
-#endif /* SVR4 */
-
-#ifdef AIXRS
-#ifndef RENAME
-#define RENAME
-#endif /* RENAME */
-#endif /* AIXRS */
-
-#ifdef BSD44
-#ifndef RENAME
-#define RENAME
-#endif /* RENAME */
-#endif /* BSD44 */
-
-#ifdef NORENAME /* Allow for compile-time override */
-#ifdef RENAME
-#undef RENAME
-#endif /* RENAME */
-#endif /* NORENAME */
-
-#ifdef STRATUS /* Stratus VOS */
-#ifndef RENAME
-#define RENAME
-#endif /* RENAME */
-#endif /* STRATUS */
-
-/* Line delimiter for text files */
-
-/*
- If the system uses a single character for text file line delimitation,
- define NLCHAR to the value of that character. For text files, that
- character will be converted to CRLF upon output, and CRLF will be converted
- to that character on input during text-mode (default) packet operations.
-*/
-#ifdef MAC /* Macintosh */
-#define NLCHAR 015
-#else
-#ifdef OSK /* OS-9/68K */
-#define NLCHAR 015
-#else /* All Unix-like systems */
-#define NLCHAR 012
-#endif /* OSK */
-#endif /* MAC */
-
-/*
- At this point, if there's a system that uses ordinary CRLF line
- delimitation AND the C compiler actually returns both the CR and
- the LF when doing input from a file, then #undef NLCHAR.
-*/
-#ifdef OS2 /* OS/2 */
-#undef NLCHAR
-#endif /* OS2 */
-
-#ifdef GEMDOS /* Atari ST */
-#undef NLCHAR
-#endif /* GEMDOS */
-
-/*
- VMS file formats are so complicated we need to do all the conversion
- work in the CKVFIO module, so we tell the rest of C-Kermit not to fiddle
- with the bytes.
-*/
-
-#ifdef vms
-#undef NLCHAR
-#endif /* vms */
-
-/* The device name of a job's controlling terminal */
-/* Special for VMS, same for all Unixes (?), not used by Macintosh */
-
-#ifdef BEOS
-#define CTTNAM dftty
-#else
-#ifdef vms
-#define CTTNAM "SYS$INPUT:" /* (4 Jan 2002) Was TT: */
-#else
-#ifdef datageneral
-#define CTTNAM "@output"
-#else
-#ifdef OSK
-extern char myttystr[];
-#define CTTNAM myttystr
-#else
-#ifdef OS2
-#define CTTNAM "con"
-#else
-#ifdef UNIX
-#define CTTNAM "/dev/tty"
-#else
-#ifdef GEMDOS
-#define CTTNAM "aux:"
-#else
-#ifdef STRATUS
-extern char myttystr[];
-#define CTTNAM myttystr
-#else /* Anyone else... */
-#define CTTNAM "stdout" /* This is a kludge used by Mac */
-#endif /* STRATUS */
-#endif /* GEMDOS */
-#endif /* UNIX */
-#endif /* OS2 */
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* vms */
-#endif /* BEOS */
-
-#ifndef HAVECTTNAM
-#ifdef UNIX
-#define HAVECTTNAM
-#else
-#ifdef VMS
-#define HAVECTTNAM
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* HAVECTTNAM */
-
-#ifndef ZFCDAT /* zfcdat() function available? */
-#ifdef UNIX
-#define ZFCDAT
-#else
-#ifdef STRATUS
-#define ZFCDAT
-#else
-#ifdef GEMDOS
-#define ZFCDAT
-#else
-#ifdef AMIGA
-#define ZFCDAT
-#else
-#ifdef OS2
-#define ZFCDAT
-#else
-#ifdef datageneral
-#define ZFCDAT
-#else
-#ifdef VMS
-#define ZFCDAT
-#endif /* VMS */
-#endif /* datageneral */
-#endif /* OS2 */
-#endif /* AMIGA */
-#endif /* GEMDOS */
-#endif /* STRATUS */
-#endif /* UNIX */
-#endif /* ZFCDAT */
-
-#ifdef SUNS4S5
-#define tolower _tolower
-#define toupper _toupper
-#endif /* SUNS4S5 */
-
-/* Error number */
-
-#ifdef _CRAY
-#ifdef _CRAYCOM /* Cray Computer Corp. */
-extern int errno;
-#else /* _CRAYCOM */
-#include <errno.h> /* Cray Research UNICOS defines */
- /* errno as a function. */
-#endif /* _CRAYCOM */ /* OK for UNICOS 6.1 and 7.0. */
-#else /* _CRAY */
-#ifdef STRATUS /* Stratus VOS */
-#include <errno.h>
-#else /* not STRATUS */
-#ifndef VMS
-#ifndef OS2
-#ifdef __GLIBC__
-/*
- "glibc uses threads, kermit uses glibc; errno access is in Thread Local
- Storage (TLS) from glibc-3.2.2. ...a thread specific errno is being run in
- thread local storage relative to the %gs segment register, so some means to
- revector gets/puts needs to be done." - Jeff Johnson, Red Hat, Feb 2003.
-*/
-#include <errno.h>
-#else
-/*
- The following declaration would cause problems for VMS and OS/2, in which
- errno is an "extern volatile int noshare"... NOTE: by now (2007) the
- following is an anachronism and should be the execption rather than the
- rule.
-*/
-extern int errno;
-#endif /* __GLIBC__ */
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* STRATUS */
-#endif /* _CRAY */
-
-#ifdef UNIX /* Catch-all so we can have */
-#ifndef ESRCH /* access to error mnemonics */
-#include <errno.h> /* in all modules - 2007/08/25 */
-#endif /* ESRCH */
-#endif /* UNIX */
-
-#ifdef pdp11 /* Try to make some space on PDP-11 */
-#ifndef NODIAL
-#define NODIAL
-#endif /* NODIAL */
-#ifndef NOCURSES
-#define NOCURSES
-#endif /* NOCURSES */
-#ifndef NOBIGBUF
-#define NOBIGBUF
-#endif /* NOBIGBUF */
-#endif /* pdp11 */
-
-#ifndef NOBIGBUF
-#ifndef BIGBUFOK /* Platforms with lots of memory */
-
-#ifdef QNX /* QNX */
-#ifndef QNX16 /* But not 16-bit versions */
-#define BIGBUFOK
-#endif /* QNX16 */
-#endif /* QNX */
-
-#ifdef BSD44
-#define BIGBUFOK
-#endif /* BSD44 */
-
-#ifdef STRATUS /* Stratus VOS */
-#define BIGBUFOK
-#endif /* STRATUS */
-
-#ifdef sparc /* SPARC processors */
-#define BIGBUFOK
-#endif /* sparc */
-
-#ifdef mips /* MIPS processors */
-#define BIGBUFOK
-#endif /* mips */
-
-#ifdef HPUX9 /* HP-UX 9.x */
-#define BIGBUFOK
-#endif /* HPUX9 */
-
-#ifdef HPUX10 /* HP-UX 10.0 PA-RISC */
-#define BIGBUFOK
-#endif /* HPUX10 */
-
-#ifdef NEXT /* NeXTSTEP */
-#ifdef mc68000 /* on NEXT platforms... */
-#define BIGBUFOK
-#endif /* mc68000 */
-#endif /* NEXT */
-
-#ifdef LINUX /* Linux in 1998 should be OK */
-#ifndef BIGBUFOK
-#define BIGBUFOK
-#endif /* BIGBUFOK */
-#endif /* LINUX */
-
-#ifdef OS2 /* 32-bit OS/2 2.x and above */
-#ifdef __32BIT__
-#define BIGBUFOK
-#endif /* __32BIT__ */
-#ifdef NT
-#define BIGBUFOK
-#endif /* NT */
-#endif /* OS2 */
-
-#ifdef Plan9 /* Plan 9 is OK */
-#define BIGBUFOK
-#endif /* Plan9 */
-
-#ifdef VMS /* Any VMS is OK */
-#ifndef BIGBUFOK
-#define BIGBUFOK
-#endif /* BIGBUFOK */
-#endif /* VMS */
-
-#ifdef __alpha /* DEC 64-bit Alpha, e.g. OSF/1 */
-#ifndef BIGBUFOK /* Might already be defined for VMS */
-#define BIGBUFOK
-#endif /* BIGBUFOK */
-#endif /* __alpha */
-
-#ifdef sgi /* SGI with IRIX 4.0 or later */
-#ifndef BIGBUFOK
-#define BIGBUFOK
-#endif /* BIGBUFOK */
-#endif /* sgi */
-
-#ifdef AIXRS /* AIX on RISC */
-#define BIGBUFOK
-#endif /* AIXRS */
-
-#ifdef CK_SCOV5 /* SCO OSR5 */
-#ifndef BIGBUFOK
-#define BIGBUFOK
-#endif /* BIGBUFOK */
-#endif /* CK_SCOV5 */
-
-#ifdef SOLARIS /* Solaris x86 */
-#ifndef BIGBUFOK
-#define BIGBUFOK
-#endif /* BIGBUFOK */
-#endif /* SOLARIS */
-
-#endif /* BIGBUFOK */
-#endif /* NOBIGBUF */
-
-#ifdef CK_SMALL
-#ifdef BIGBUFOK
-#undef BIGBUFOK
-#endif /* BIGBUFOK */
-#endif /* CK_SMALL */
-
-/* If "memory is no problem" then this improves performance */
-
-#ifdef DEBUG
-#ifdef BIGBUFOK
-#ifndef IFDEBUG
-#define IFDEBUG
-#endif /* IFDEBUG */
-#endif /* BIGBUFOK */
-#endif /* DEBUG */
-
-/* File System Defaults */
-
-#ifndef UIDBUFLEN /* Length of User ID */
-#ifdef OS2
-#define UIDBUFLEN 256
-#else /* OS2 */
-#ifdef BIGBUFOK
-#define UIDBUFLEN 256
-#else
-#define UIDBUFLEN 64
-#endif /* BIGBUFOK */
-#endif /* OS2 */
-#endif /* UIDBUFLEN */
-
-#ifdef UNIX
-#ifdef PROVX1
-#define MAXWLD 50
-#else
-#ifdef pdp11
-#define MAXWLD 50
-#else
-#ifdef BIGBUFOK
-#define MAXWLD 102400
-#else
-#define MAXWLD 1024
-#endif /* BIGBUFOK */
-#endif /* pdp11 */
-#endif /* PROVX1 */
-#else
-#ifdef VMS
-#define MAXWLD 102400 /* Maximum wildcard filenames */
-#else
-#ifdef datageneral
-#define MAXWLD 500
-#else
-#ifdef STRATUS
-#define MAXWLD 5000
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* UNIX */
-
-#ifdef VMS
-#define DBLKSIZ 512
-#define DLRECL 512
-#else
-#define DBLKSIZ 0
-#define DLRECL 0
-#endif /* VMS */
-
-/* Communication device / network host name length */
-
-#ifdef BIGBUFOK
-#define TTNAMLEN 512
-#else
-#ifdef MAC
-#define TTNAMLEN 256
-#else
-#ifndef CK_SMALL
-#define TTNAMLEN 128
-#else
-#define TTNAMLEN 80
-#endif /* CK_SMALL */
-#endif /* MAC */
-#endif /* BIGBUFOK */
-
-/* Program return codes for DECUS C and UNIX (VMS uses UNIX codes) */
-
-#ifdef decus
-#define GOOD_EXIT IO_NORMAL
-#define BAD_EXIT IO_ERROR
-#else
-#define GOOD_EXIT 0
-#define BAD_EXIT 1
-#endif /* decus */
-
-/* Special hack for Fortune, which doesn't have <sys/file.h>... */
-
-#ifdef FT18
-#define FREAD 0x01
-#define FWRITE 0x10
-#endif /* FT18 */
-
-/* Special hack for OS-9/68k */
-#ifdef OSK
-#ifndef _UCC
-#define SIGALRM 30 /* May always cancel I/O */
-#endif /* _UCC */
-#define SIGARB 1234 /* Arbitrary for I/O */
-SIGTYP (*signal())();
-#endif /* OSK */
-
-#ifdef MINIX
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(c) (putc(c,stdout)!=EOF)&&fflush(stdout)
-#endif /* MINIX */
-
-#ifdef datageneral /* Data General AOS/VS */
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(c) conoc(c)
-#endif /* datageneral */
-
-/* Escape/quote character used by the command parser */
-
-#define CMDQ '\\'
-
-/* Symbols for RS-232 modem signals */
-
-#define KM_FG 1 /* Frame ground */
-#define KM_TXD 2 /* Transmit */
-#define KM_RXD 3 /* Receive */
-#define KM_RTS 4 /* Request to Send */
-#define KM_CTS 5 /* Clear to Send */
-#define KM_DSR 6 /* Data Set Ready */
-#define KM_SG 7 /* Signal ground */
-#define KM_DCD 8 /* Carrier Detect */
-#define KM_DTR 20 /* Data Terminal Ready */
-#define KM_RI 22 /* Ring Indication */
-
-/* Bit mask values for modem signals */
-
-#define BM_CTS 0001 /* Clear to send (From DCE) */
-#define BM_DSR 0002 /* Dataset ready (From DCE) */
-#define BM_DCD 0004 /* Carrier (From DCE) */
-#define BM_RNG 0010 /* Ring Indicator (From DCE) */
-#define BM_DTR 0020 /* Data Terminal Ready (From DTE) */
-#define BM_RTS 0040 /* Request to Send (From DTE) */
-
-/* Codes for full duplex flow control */
-
-#define FLO_NONE 0 /* None */
-#define FLO_XONX 1 /* Xon/Xoff (soft) */
-#define FLO_RTSC 2 /* RTS/CTS (hard) */
-#define FLO_DTRC 3 /* DTR/CD (hard) */
-#define FLO_ETXA 4 /* ETX/ACK (soft) */
-#define FLO_STRG 5 /* String-based (soft) */
-#define FLO_DIAL 6 /* DIALing kludge */
-#define FLO_DIAX 7 /* Cancel dialing kludge */
-#define FLO_DTRT 8 /* DTR/CTS (hard) */
-#define FLO_KEEP 9 /* Keep, i.e. don't touch or change */
-#define FLO_AUTO 10 /* Figure out automatically */
-
-/* Types of connections */
-
-#define CXT_REMOTE 0 /* Remote mode - no connection */
-#define CXT_DIRECT 1 /* Direct serial connection */
-#define CXT_MODEM 2 /* Modem dialout */
-#define CXT_TCPIP 3 /* TCP/IP - Telnet, Rlogin, etc */
-#define CXT_X25 4 /* X.25 peer-to-peer */
-#define CXT_DECNET 5 /* DECnet (CTERM, etc) */
-#define CXT_LAT 6 /* LAT */
-#define CXT_NETBIOS 7 /* NETBIOS */
-#define CXT_NPIPE 8 /* Named Pipe */
-#define CXT_PIPE 9 /* Pipe, Command, PTY, DLL, etc */
-#define CXT_SSH 10 /* SSH */
-#define CXT_MAX 10 /* Highest connection type */
-
-/* Autodownload Detection Options */
-
-#define ADL_PACK 0 /* Auto-Download detect packet */
-#define ADL_STR 1 /* Auto-Download detect string */
-
-/* And finally... */
-
-#ifdef COMMENT /* Make sure this is NOT defined! */
-#undef COMMENT
-#endif /* COMMENT */
-
-/* zstr zattr filinfo were here (moved to top for DECC 5 Jun 2000) */
-
-#ifndef ZFNQFP /* Versions that have zfnqfp() */
-#ifdef UNIX
-#define ZFNQFP
-#else
-#ifdef VMS
-#define ZFNQFP
-#else
-#ifdef OS2
-#define ZFNQFP
-#else
-#ifdef datageneral
-#define ZFNQFP
-#else
-#ifdef STRATUS
-#define ZFNQFP
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* UNIX */
-struct zfnfp {
- int len; /* Length of full pathname */
- char * fpath; /* Pointer to full pathname */
- char * fname; /* Pointer to name part */
-};
-#endif /* ZFNQFP */
-
-/* Systems that support FILE TYPE LABELED */
-
-#ifdef VMS
-#define CK_LABELED
-#else
-#ifdef OS2
-#ifdef __32BIT__
-#ifndef NT
-#define CK_LABELED
-#endif /* NT */
-#endif /* __32BIT__ */
-#endif /* OS2 */
-#endif /* VMS */
-
-/* LABELED FILE options bitmask */
-
-#ifdef VMS /* For VMS */
-#define LBL_NAM 1 /* Ignore incoming name if set */
-#define LBL_PTH 2 /* Use complete path if set */
-#define LBL_ACL 4 /* Preserve ACLs if set */
-#define LBL_BCK 8 /* Preserve backup date if set */
-#define LBL_OWN 16 /* Preserve ownership if set */
-
-#else
-
-#ifdef OS2 /* Ditto for OS/2 */
-#define LBL_NOR 0x0000 /* Normal file */
-#define LBL_ARC 0x0020 /* Archive */
-#define LBL_DIR 0x0010 /* Directory */
-#define LBL_HID 0x0002 /* Hidden file */
-#define LBL_RO 0x0001 /* Read only file */
-#define LBL_SYS 0x0004 /* System file */
-#define LBL_EXT 0x0040 /* Extended */
-#endif /* OS2 */
-#endif /* VMS */
-
-/*
- Data types. First the header file for data types so we can pick up the
- types used for pids, uids, and gids. Override this section by putting
- -DCKTYP_H=xxx on the command line to specify the header file where your
- system defines these types.
-*/
-#ifndef STRATUS
-#ifdef __ALPHA
-#ifdef MULTINET
-#define CK_TGV_AXP
-#endif /* MULTINET */
-#endif /* __ALPHA */
-
-#ifdef CK_TGV_AXP /* Alpha, VMS, MultiNet */
-/*
- Starting in DECC 5.0, <stdlib.h> no longer includes <types.h>.
- But before that an elaborate workaround is required, which results in
- including <types.h> sometimes but not others, evidently depending on whether
- <types.h> protects itself against multiple inclusion, which in turn probably
- differentiates between DECC <types.h> and TGV <types.h>. Unfortunately I
- don't remember the details. (fdc, 25 Oct 96)
-*/
-#ifdef COMMENT
-/*
- Previously the test here was for DEC version prior to 4.0, but since the
- test involved an "#if" statement, it was not portable and broke some non-VMS
- builds. In any case, condition was never satisfied, so the result of
- commenting this section out is the same as the previous "#if" condition.
-*/
-#ifndef __TYPES_LOADED
-#define __TYPES_LOADED /* Work around bug in .h files */
-#endif /* __TYPES_LOADED */
-#endif /* COMMENT */
-#include <sys/types.h>
-#ifdef IF_DOT_H
-#ifndef MULTINET
-#include <if.h> /* Needed to put up u_int typedef */
-#endif /* MULTINET */
-#else /* IF_DOT_H */
-#ifdef NEEDUINT
-typedef unsigned int u_int;
-#endif /* NEEDUINT */
-#endif /* IF_DOT_H */
-#else /* !CK_TGV_AXP */
-#ifdef OSK /* OS-9 */
-#include <types.h>
-#else /* General case, not OS-9 */
-#ifndef CKTYP_H
-#ifndef VMS
-#ifndef MAC
-#ifndef AMIGA
-#define CKTYP_H <sys/types.h>
-#endif /* AMIGA */
-#endif /* MAC */
-#endif /* VMS */
-#endif /* CKTYP_H */
-
-#ifdef GEMDOS
-#undef CKTYP_H
-#include <types.h>
-#endif /* GEMDOS */
-
-#ifdef OS2
-#undef CKTYP_H
-#include <sys/types.h>
-#endif /* OS2 */
-
-#ifdef CKTYP_H /* Include it. */
-#ifdef COHERENT /* Except for COHERENT */
-#include <unistd.h>
-#include <sys/types.h>
-#else
-#ifdef datageneral /* AOS/VS */
-#include <sys/types.h>
-#else /* All others */
-#ifdef __bsdi__ /* BSDI */
-#ifdef POSIX
-#undef _POSIX_SOURCE
-#endif /* POSIX */
-#endif /* __bsdi__ */
-#include CKTYP_H
-#ifdef __bsdi__
-#ifdef POSIX
-#define _POSIX_SOURCE
-#endif /* POSIX */
-#endif /* __bsdi__ */
-#endif /* datageneral */
-#endif /* COHERENT */
-#endif /* CKTYP_H */
-
-#endif /* OSK */
-#endif /* CK_TGV_AXP */
-#endif /* STRATUS */ /* End of types.h section */
-
-/*
- File lengths and offsets. This section is expected to grow as we
- support long files on 32-bit platforms. We want this data type to be
- signed because so many functions return either a file size or a negative
- value to indicate an error.
-*/
-#ifndef CK_OFF_T
-#ifdef OS2
-#ifdef NT
-#define CK_OFF_T __int64
-#else
-#define CK_OFF_T long
-#endif /* NT */
-#endif /* OS2 */
-#endif /* CK_OFF_T */
-
-/* FreeBSD and OpenBSD set off_t to the appropriate size unconditionally */
-
-#ifndef CK_OFF_T
-#ifdef __FreeBSD__
-#define CK_OFF_T off_t
-#else
-#ifdef __OpenBSD__
-#define CK_OFF_T off_t
-#endif /* __OpenBSD__ */
-#endif /* __FreeBSD__ */
-#endif /* CK_OFF_T */
-
-/* 32-bit platforms that support long files thru "transitional interface" */
-/* These include Linux, Solaris, NetBSD... */
-
-#ifdef AIXRS
-#ifdef _LARGE_FILES
-#ifndef CK_OFF_T
-#define CK_OFF_T off_t
-#endif /* CK_OFF_T */
-#endif /* _LARGE_FILES */
-#endif /* AIXRS */
-
-#ifdef _LARGEFILE_SOURCE
-#ifndef CK_OFF_T
-#define CK_OFF_T off_t
-#endif /* CK_OFF_T */
-#ifdef IRIX
-#define CKFSEEK(a,b,c) fseek64(a,b,c)
-#define CKFTELL(a) ftell64(a)
-#else /* IRIX */
-#define CKFSEEK(a,b,c) fseeko(a,b,c)
-#define CKFTELL(a) ftello(a)
-#endif /* IRIX */
-#else /* Not _LARGEFILE_SOURCE */
-#define CKFSEEK(a,b,c) fseek(a,b,c)
-#define CKFTELL(a) ftell(a)
-/* See below the next section for the catch-all case */
-#endif /* _LARGEFILE_SOURCE */
-
-/* 32-bit or 64-bit platforms */
-
-/* CK_64BIT is a compile-time symbol indicating a true 64-bit build */
-/* meaning that longs and pointers are 64 bits */
-
-#ifndef VMS /* VMS Alpha and IA64 are 32-bit! */
-#ifndef CK_64BIT
-#ifdef _LP64 /* Solaris */
-#define CK_64BIT
-#else
-#ifdef __LP64__ /* MacOS X 10.4 (or _LP64,__ppc64__) */
-#define CK_64BIT
-#else
-#ifdef __arch64__ /* gcc alpha, sparc */
-#define CK_64BIT
-#else
-#ifdef __alpha /* Alpha decc (or __ALPHA) */
-#define CK_64BIT
-#else
-#ifdef __amd64 /* AMD x86_64 (or __x86_64) */
-#define CK_64BIT
-#else
-#ifdef __ia64 /* Intel IA64 */
-#ifndef HPUX
-#define CK_64BIT
-#endif /* HPUX */
-#endif /* __ia64 */
-#endif /* __amd64 */
-#endif /* __alpha */
-#endif /* __arch64__ */
-#endif /* __LP64__ */
-#endif /* _LP64 */
-#endif /* CK_64BIT */
-#endif /* VMS */
-
-#ifndef CK_OFF_T
-#ifdef CK_64BIT
-#define CK_OFF_T off_t /* This has to be signed */
-#else /* CK_64BIT */
-#define CK_OFF_T long /* Signed */
-#endif /* CK_64BIT */
-#endif /* CK_OFF_T */
-
-#ifndef TLOG
-#define tlog(a,b,c,d)
-#else
-#ifndef CKCMAI
-/* Debugging included. Declare debug log flag in main program only. */
-extern int tralog, tlogfmt;
-#endif /* CKCMAI */
-_PROTOTYP(VOID dotlog,(int, char *, char *, CK_OFF_T));
-#define tlog(a,b,c,d) if (tralog && tlogfmt) dotlog(a,b,c,(CK_OFF_T)d)
-_PROTOTYP(VOID doxlog,(int, char *, CK_OFF_T, int, int, char *));
-#endif /* TLOG */
-
-#ifndef DEBUG
-/* Compile all the debug() statements away. Saves a lot of space and time. */
-#define debug(a,b,c,d)
-#define ckhexdump(a,b,c)
-/* Now define the debug() macro. */
-#else /* DEBUG */
-_PROTOTYP(int dodebug,(int,char *,char *,CK_OFF_T));
-_PROTOTYP(int dohexdump,(CHAR *,CHAR *,int));
-#ifdef IFDEBUG
-/* Use this form to avoid function calls: */
-#ifdef COMMENT
-#define debug(a,b,c,d) if (deblog) dodebug(a,b,(char *)(c),(CK_OFF_T)(d))
-#define ckhexdump(a,b,c) if (deblog) dohexdump((CHAR *)(a),(CHAR *)(b),c)
-#else
-#ifdef CK_ANSIC
-#define debug(a,b,c,d) \
-((void)(deblog?dodebug(a,b,(char *)(c),(CK_OFF_T)(d)):0))
-#define ckhexdump(a,b,c) \
-((void)(deblog?dohexdump((CHAR *)(a),(CHAR *)(b),c):0))
-#else
-#define debug(a,b,c,d) (deblog?dodebug(a,b,(char *)(c),(CK_OFF_T)(d)):0)
-#define ckhexdump(a,b,c) (deblog?dohexdump((CHAR *)(a),(CHAR *)(b),c):0)
-#endif /* CK_ANSIC */
-#endif /* COMMENT */
-#else /* IFDEBUG */
-/* Use this form to save space: */
-#define debug(a,b,c,d) dodebug(a,b,(char *)(c),(CK_OFF_T)(d))
-#define ckhexdump(a,b,c) dohexdump((CHAR *)(a),(CHAR *)(b),c)
-#endif /* IFDEBUG */
-#endif /* DEBUG */
-
-
-/* Structure definitions for Kermit file attributes */
-/* All strings come as pointer and length combinations */
-/* Empty string (or for numeric variables, -1) = unused attribute. */
-
-struct zstr { /* string format */
- int len; /* length */
- char *val; /* value */
-};
-
-struct zattr { /* Kermit File Attribute structure */
- CK_OFF_T lengthk; /* (!) file length in K */
- struct zstr type; /* (") file type (text or binary) */
- struct zstr date; /* (#) file creation date yyyymmdd[ hh:mm[:ss]] */
- struct zstr creator; /* ($) file creator id */
- struct zstr account; /* (%) file account */
- struct zstr area; /* (&) area (e.g. directory) for file */
- struct zstr password; /* (') password for area */
- long blksize; /* (() file blocksize */
- struct zstr xaccess; /* ()) file access: new, supersede, append, warn */
- struct zstr encoding; /* (*) encoding (transfer syntax) */
- struct zstr disp; /* (+) disposition (mail, message, print, etc) */
- struct zstr lprotect; /* (,) protection (local syntax) */
- struct zstr gprotect; /* (-) protection (generic syntax) */
- struct zstr systemid; /* (.) ID for system of origin */
- struct zstr recfm; /* (/) record format */
- struct zstr sysparam; /* (0) system-dependent parameter string */
- CK_OFF_T length; /* (1) exact length on system of origin */
- struct zstr charset; /* (2) transfer syntax character set */
-#ifdef OS2
- struct zstr longname; /* OS/2 longname if applicable */
-#endif /* OS2 */
- struct zstr reply; /* This goes last, used for attribute reply */
-};
-
-/* Kermit file information structure */
-
-struct filinfo {
- int bs; /* Blocksize */
- int cs; /* Character set */
- long rl; /* Record length */
- int org; /* Organization */
- int fmt; /* Record format */
- int cc; /* Carriage control */
- int typ; /* Type (text/binary) */
- int dsp; /* Disposition */
- char *os_specific; /* OS-specific attributes */
-#ifdef OS2
- unsigned long int lblopts; /* LABELED FILE options bitmask */
-#else
- int lblopts;
-#endif /* OS2 */
-};
-
-
-/*
- Data type for pids. If your system uses a different type, put something
- like -DPID_T=pid_t on command line, or override here.
-*/
-#ifndef PID_T
-#define PID_T int
-#endif /* PID_T */
-/*
- Data types for uids and gids. Same deal as for pids.
- Wouldn't be nice if there was a preprocessor test to find out if a
- typedef existed?
-*/
-#ifdef VMS
-/* Not used in VMS so who cares */
-#define UID_T int
-#define GID_T int
-#endif /* VMS */
-
-#ifdef POSIX
-/* Or would it be better (or worse?) to use _POSIX_SOURCE here? */
-#ifndef UID_T
-#define UID_T uid_t
-#endif /* UID_T */
-#ifndef GID_T
-#define GID_T gid_t
-#endif /* GID_T */
-#else /* Not POSIX */
-#ifdef SVR4
-/* SVR4 and later have uid_t and gid_t. */
-/* SVR3 and earlier use int, or unsigned short, or.... */
-#ifndef UID_T
-#define UID_T uid_t
-#endif /* UID_T */
-#ifndef GID_T
-#define GID_T gid_t
-#endif /* GID_T */
-#else /* Not SVR4 */
-#ifdef BSD43
-#ifndef UID_T
-#define UID_T uid_t
-#endif /* UID_T */
-#ifndef GID_T
-#define GID_T gid_t
-#endif /* GID_T */
-#else /* Not BSD43 */
-/* Default these to int for older UNIX versions */
-#ifndef UID_T
-#define UID_T int
-#endif /* UID_T */
-#ifndef GID_T
-#define GID_T int
-#endif /* GID_T */
-#endif /* BSD43 */
-#endif /* SVR4 */
-#endif /* POSIX */
-
-/*
- getpwuid() arg type, which is not necessarily the same as UID_T,
- e.g. in SCO UNIX SVR3, it's int.
-*/
-#ifndef PWID_T
-#define PWID_T UID_T
-#endif /* PWID_T */
-
-#ifdef CK_REDIR
-#ifdef NEXT
-#define MACHWAIT
-#else
-#ifdef MACH
-#define MACHWAIT
-#endif /* MACH */
-#endif /* NEXT */
-
-#ifdef MACHWAIT /* WAIT_T argument for wait() */
-#include <sys/wait.h>
-#define CK_WAIT_H
-typedef union wait WAIT_T;
-#else
-#ifdef POSIX
-#ifdef OSF
-/* OSF wait.h defines BSD wait if _BSD is defined so hide _BSD from wait.h */
-#ifdef _BSD
-#define CK_OSF_BSD
-#undef _BSD
-#endif /* _BSD */
-#endif /* OSF */
-#include <sys/wait.h>
-#define CK_WAIT_H
-#ifndef WAIT_T
-typedef int WAIT_T;
-#endif /* WAIT_T */
-#ifdef CK_OSF_BSD /* OSF/1: Restore _BSD definition */
-#define _BSD
-#undef CK_OSF_BSD
-#endif /* CK_OSF_BSD */
-#else /* !POSIX */
-typedef int WAIT_T;
-#endif /* POSIX */
-#endif /* MACHWAIT */
-#else
-typedef int WAIT_T;
-#endif /* CK_REDIR */
-
-/* Assorted other blah_t's handled here... */
-
-#ifndef SIZE_T
-#define SIZE_T size_t
-#endif /* SIZE_T */
-
-/* Forward declarations of system-dependent functions callable from all */
-/* C-Kermit modules. */
-
-/* File-related functions from system-dependent file i/o module */
-
-#ifndef CKVFIO_C
-/* For some reason, this does not agree with DEC C */
-_PROTOTYP( int zkself, (void) );
-#endif /* CKVFIO_C */
-_PROTOTYP( int zopeni, (int, char *) );
-_PROTOTYP( int zopeno, (int, char *, struct zattr *, struct filinfo *) );
-_PROTOTYP( int zclose, (int) );
-#ifndef MAC
-_PROTOTYP( int zchin, (int, int *) );
-#endif /* MAC */
-_PROTOTYP( int zxin, (int, char *, int) );
-_PROTOTYP( int zsinl, (int, char *, int) );
-_PROTOTYP( int zinfill, (void) );
-_PROTOTYP( int zsout, (int, char*) );
-_PROTOTYP( int zsoutl, (int, char*) );
-_PROTOTYP( int zsoutx, (int, char*, int) );
-_PROTOTYP( int zchout, (int, char) );
-_PROTOTYP( int zoutdump, (void) );
-_PROTOTYP( int zsyscmd, (char *) );
-_PROTOTYP( int zshcmd, (char *) );
-#ifdef UNIX
-_PROTOTYP( int zsetfil, (int, int) );
-_PROTOTYP( int zchkpid, (unsigned long) );
-#endif /* UNIX */
-#ifdef CKEXEC
-_PROTOTYP( VOID z_exec, (char *, char **, int) );
-#endif /* CKEXEC */
-_PROTOTYP( int chkfn, (int) );
-_PROTOTYP( CK_OFF_T zchki, (char *) );
-#ifdef VMSORUNIX
-_PROTOTYP( CK_OFF_T zgetfs, (char *) );
-#else
-#ifdef OS2
-_PROTOTYP( CK_OFF_T zgetfs, (char *) );
-#else
-#define zgetfs(a) zchki(a)
-#endif /* OS2 */
-#endif /* VMSORUNIX */
-_PROTOTYP( int iswild, (char *) );
-_PROTOTYP( int isdir, (char *) );
-_PROTOTYP( int zchko, (char *) );
-_PROTOTYP( int zdelet, (char *) );
-_PROTOTYP( VOID zrtol, (char *,char *) );
-_PROTOTYP( VOID zltor, (char *,char *) );
-_PROTOTYP( VOID zstrip, (char *,char **) );
-#ifdef VMS
-_PROTOTYP( char * zrelname, (char *, char *) );
-#endif /* VMS */
-_PROTOTYP( int zchdir, (char *) );
-_PROTOTYP( char * zhome, (void) );
-_PROTOTYP( char * zgtdir, (void) );
-_PROTOTYP( int zxcmd, (int, char *) );
-#ifndef MAC
-_PROTOTYP( int zclosf, (int) );
-#endif /* MAC */
-#ifdef NZXPAND
-_PROTOTYP( int nzxpand, (char *, int) );
-#else /* NZXPAND */
-_PROTOTYP( int zxpand, (char *) );
-#endif /* NZXPAND */
-_PROTOTYP( int znext, (char *) );
-#ifdef ZXREWIND
-_PROTOTYP( int zxrewind, (void) );
-#endif /* ZXREWIND */
-_PROTOTYP( int zchkspa, (char *, CK_OFF_T) );
-_PROTOTYP( VOID znewn, (char *, char **) );
-_PROTOTYP( int zrename, (char *, char *) );
-_PROTOTYP( int zcopy, (char *, char *) );
-_PROTOTYP( int zsattr, (struct zattr *) );
-_PROTOTYP( int zfree, (char *) );
-_PROTOTYP( char * zfcdat, (char *) );
-_PROTOTYP( int zstime, (char *, struct zattr *, int) );
-#ifdef CK_PERMS
-_PROTOTYP( char * zgperm, (char *) );
-_PROTOTYP( char * ziperm, (char *) );
-#endif /* CK_PERMS */
-_PROTOTYP( int zmail, (char *, char *) );
-_PROTOTYP( int zprint, (char *, char *) );
-_PROTOTYP( char * tilde_expand, (char *) );
-_PROTOTYP( int zmkdir, (char *) ) ;
-_PROTOTYP( int zfseek, (CK_OFF_T) ) ;
-#ifdef ZFNQFP
-_PROTOTYP( struct zfnfp * zfnqfp, (char *, int, char * ) ) ;
-#else
-#define zfnqfp(a,b,c) ckstrncpy(c,a,b)
-#endif /* ZFNQFP */
-_PROTOTYP( int zvuser, (char *) ) ;
-_PROTOTYP( int zvpass, (char *) ) ;
-_PROTOTYP( VOID zvlogout, (void) ) ;
-#ifdef OS2
-_PROTOTYP( int os2setlongname, ( char * fn, char * ln ) ) ;
-_PROTOTYP( int os2getlongname, ( char * fn, char ** ln ) ) ;
-_PROTOTYP( int os2rexx, ( char *, char *, int ) ) ;
-_PROTOTYP( int os2rexxfile, ( char *, char *, char *, int) ) ;
-_PROTOTYP( int os2geteas, (char *) ) ;
-_PROTOTYP( int os2seteas, (char *) ) ;
-_PROTOTYP( char * get_os2_vers, (void) ) ;
-_PROTOTYP( int do_label_send, (char *) ) ;
-_PROTOTYP( int do_label_recv, (void) ) ;
-#ifdef OS2MOUSE
-_PROTOTYP( unsigned long os2_mouseon, (void) );
-_PROTOTYP( unsigned long os2_mousehide, (void) );
-_PROTOTYP( unsigned long os2_mouseshow, (void) );
-_PROTOTYP( unsigned long os2_mouseoff, (void) );
-_PROTOTYP( void os2_mouseevt, (void *) );
-_PROTOTYP( int mousebuttoncount, (void));
-#endif /* OS2MOUSE */
-#endif /* OS2 */
-
-/* Functions from system-dependent terminal i/o module */
-
-_PROTOTYP( int ttopen, (char *, int *, int, int) ); /* tty functions */
-#ifndef MAC
-_PROTOTYP( int ttclos, (int) );
-#endif /* MAC */
-_PROTOTYP( int tthang, (void) );
-_PROTOTYP( int ttres, (void) );
-_PROTOTYP( int ttpkt, (long, int, int) );
-#ifndef MAC
-_PROTOTYP( int ttvt, (long, int) );
-#endif /* MAC */
-_PROTOTYP( int ttsspd, (int) );
-_PROTOTYP( long ttgspd, (void) );
-_PROTOTYP( int ttflui, (void) );
-_PROTOTYP( int ttfluo, (void) );
-_PROTOTYP( int ttpushback, (CHAR *, int) );
-_PROTOTYP( int ttpeek, (void) );
-_PROTOTYP( int ttgwsiz, (void) );
-_PROTOTYP( int ttchk, (void) );
-_PROTOTYP( int ttxin, (int, CHAR *) );
-_PROTOTYP( int ttxout, (CHAR *, int) );
-_PROTOTYP( int ttol, (CHAR *, int) );
-_PROTOTYP( int ttoc, (char) );
-_PROTOTYP( int ttinc, (int) );
-_PROTOTYP( int ttscarr, (int) );
-_PROTOTYP( int ttgmdm, (void) );
-_PROTOTYP( int ttsndb, (void) );
-_PROTOTYP( int ttsndlb, (void) );
-#ifdef UNIX
-_PROTOTYP( char * ttglckdir, (void) );
-#endif /* UNIX */
-#ifdef PARSENSE
-#ifdef UNIX
-_PROTOTYP( int ttinl, (CHAR *, int, int, CHAR, CHAR, int) );
-#else
-#ifdef VMS
-_PROTOTYP( int ttinl, (CHAR *, int, int, CHAR, CHAR, int) );
-#else
-#ifdef STRATUS
-_PROTOTYP( int ttinl, (CHAR *, int, int, CHAR, CHAR, int) );
-#else
-#ifdef OS2
-_PROTOTYP( int ttinl, (CHAR *, int, int, CHAR, CHAR, int) );
-#else
-#ifdef OSK
-_PROTOTYP( int ttinl, (CHAR *, int, int, CHAR, CHAR, int) );
-#else
-_PROTOTYP( int ttinl, (CHAR *, int, int, CHAR, CHAR) );
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* UNIX */
-#else /* ! PARSENSE */
-_PROTOTYP( int ttinl, (CHAR *, int, int, CHAR) );
-#endif /* PARSENSE */
-
-/* XYZMODEM support */
-
-/*
- CK_XYZ enables the various commands and data structures.
- XYZ_INTERNAL means these protocols are built-in; if not defined,
- then they are external. XYZ_DLL is used to indicate a separate
- loadable library containing the XYZmodem protocol code.
-*/
-#ifdef pdp11 /* No room for this in PDP-11 */
-#define NOCKXYZ
-#endif /* pdp11 */
-
-#ifndef NOCKXYZ /* Alternative protocols */
-#ifndef CK_XYZ
-#ifdef UNIX
-#define CK_XYZ
-#else
-#ifdef OS2
-#define CK_XYZ
-#ifndef NOXYZDLL
-#define XYZ_INTERNAL /* Internal and DLL */
-#define XYZ_DLL
-#endif /* NOXYZDLL */
-#endif /* OS2 */
-#endif /* UNIX */
-#endif /* CK_XYZ */
-#endif /* NOCKXYZ */
-
-#ifdef XYZ_INTERNAL /* This ensures that XYZ_INTERNAL */
-#ifndef CK_XYZ /* is defined only if CK_XYZ is too */
-#undef XYZ_INTERNAL
-#endif /* CK_XYZ */
-#endif /* XYZ_INTERNAL */
-#ifdef XYZ_DLL /* This ensures XYZ_DLL is defined */
-#ifndef XYZ_INTERNAL /* only if XYZ_INTERNAL is too */
-#undef XYZ_DLL
-#endif /* XYZ_INTERNAL */
-#endif /* XYZ_DLL */
-
-/* Console functions */
-
-_PROTOTYP( int congm, (void) );
-#ifdef COMMENT
-_PROTOTYP( VOID conint, (SIGTYP (*)(int, int), SIGTYP (*)(int, int)) );
-#else
-_PROTOTYP( VOID conint, (SIGTYP (*)(int), SIGTYP (*)(int)) );
-#endif /* COMMENT */
-_PROTOTYP( VOID connoi, (void) );
-_PROTOTYP( int concb, (char) );
-#ifdef CONGSPD
-_PROTOTYP( long congspd, (void) );
-#endif /* CONGSPD */
-_PROTOTYP( int conbin, (char) );
-_PROTOTYP( int conres, (void) );
-_PROTOTYP( int conoc, (char) );
-_PROTOTYP( int conxo, (int, char *) );
-_PROTOTYP( int conol, (char *) );
-_PROTOTYP( int conola, (char *[]) );
-_PROTOTYP( int conoll, (char *) );
-_PROTOTYP( int conchk, (void) );
-_PROTOTYP( int coninc, (int) );
-_PROTOTYP( char * conkbg, (void) );
-_PROTOTYP( int psuspend, (int) );
-_PROTOTYP( int priv_ini, (void) );
-_PROTOTYP( int priv_on, (void) );
-_PROTOTYP( int priv_off, (void) );
-_PROTOTYP( int priv_can, (void) );
-_PROTOTYP( int priv_chk, (void) );
-_PROTOTYP( int priv_opn, (char *, int) );
-
-_PROTOTYP( int sysinit, (void) ); /* Misc Kermit functions */
-_PROTOTYP( int syscleanup, (void) );
-_PROTOTYP( int msleep, (int) );
-_PROTOTYP( VOID rtimer, (void) );
-_PROTOTYP( int gtimer, (void) );
-#ifdef GFTIMER
-_PROTOTYP( VOID rftimer, (void) );
-_PROTOTYP( CKFLOAT gftimer, (void) );
-#endif /* GFTIMER */
-_PROTOTYP( VOID ttimoff, (void) );
-_PROTOTYP( VOID ztime, (char **) );
-_PROTOTYP( int parchk, (CHAR *, CHAR, int) );
-_PROTOTYP( VOID doexit, (int, int) );
-_PROTOTYP( int askmore, (void) );
-_PROTOTYP( VOID fatal, (char *) );
-_PROTOTYP( VOID fatal2, (char *, char *) );
-#ifdef VMS
-_PROTOTYP( int ck_cancio, (void) );
-#endif /* VMS */
-
-/* Key mapping support */
-
-#ifdef NOICP
-#ifndef NOSETKEY
-#define NOSETKEY
-#endif /* NOSETKEY */
-#endif /* NOICP */
-
-#ifdef MAC
-#ifndef NOSETKEY
-#define NOSETKEY
-#endif /* NOSETKEY */
-#endif /* MAC */
-
-_PROTOTYP( int congks, (int) );
-#ifdef OS2
-/* OS2 requires these definitions even if SET KEY is not being supported */
-#define KMSIZE 8916
-typedef ULONG KEY;
-typedef CHAR *MACRO;
-extern int wideresult;
-#else /* Not OS2 */
-#ifndef NOSETKEY
-/*
- Catch-all for systems where we don't know how to read keyboard scan
- codes > 255.
-*/
-#define KMSIZE 256
-/* Note: CHAR (i.e. unsigned char) is very important here. */
-typedef CHAR KEY;
-typedef CHAR * MACRO;
-#define congks coninc
-#endif /* NOSETKEY */
-#endif /* OS2 */
-
-#ifndef OS2
-#ifndef NOKVERBS /* No \Kverbs unless... */
-#define NOKVERBS
-#endif /* NOKVERBS */
-#endif /* OS2 */
-
-#ifndef NOKVERBS
-#ifdef OS2
-/*
- Note: this value chosen to be bigger than PC BIOS key modifier bits,
- but still fit in 16 bits without affecting sign.
-
- As of K95 1.1.5, this no longer fits in 16 bits, good thing we are 32 bit.
-*/
-#define F_MACRO 0x2000 /* Bit indicating a macro indice */
-#define IS_MACRO(x) (x & F_MACRO)
-#define F_KVERB 0x4000 /* Bit indicating a keyboard verb */
-#define IS_KVERB(x) (x & F_KVERB) /* Test this bit */
-#endif /* OS2 */
-#endif /* NOKVERBS */
-
-#define F_ESC 0x8000 /* Bit indicating ESC char combination */
-#define IS_ESC(x) (x & F_ESC)
-#define F_CSI 0x10000 /* Bit indicating CSI char combination */
-#define IS_CSI(x) (x & F_CSI)
-
-#ifdef NOSPL /* This might be overkill.. */
-#ifndef NOKVERBS /* Not all \Kverbs require */
-#define NOKVERBS /* the script programming language. */
-#endif /* NOKVERBS */
-#ifndef NOTAKEARGS
-#define NOTAKEARGS
-#endif /* NOTAKEARGS */
-#endif /* NOSPL */
-
-/*
- Function prototypes for system and library functions.
-*/
-#ifdef _POSIX_SOURCE
-#ifndef VMS
-#ifndef MAC
-#define CK_ANSILIBS
-#endif /* MAC */
-#endif /* VMS */
-#endif /* _POSIX_SOURCE */
-
-#ifdef NEXT
-#define CK_ANSILIBS
-#endif /* NEXT */
-
-#ifdef SVR4
-#define CK_ANSILIBS
-#endif /* SVR4 */
-
-#ifdef STRATUS /* Stratus VOS uses ANSI libraries */
-#define CK_ANSILIBS
-#endif /* STRATUS */
-
-#ifdef OS2
-#define CK_ANSILIBS
-#ifndef NOCURSES
-#define MYCURSES
-#endif /* NOCURSES */
-#define CK_RTSCTS
-#ifdef __IBMC__
-#define S_IFMT 0xF000
-#define timezone _timezone
-#endif /* __IBMC__ */
-#include <fcntl.h>
-#include <io.h>
-#ifdef __EMX__
-#ifndef __32BIT__
-#define __32BIT__
-#endif /* __32BIT__ */
-#include <sys/timeb.h>
-#else /* __EMX__ */
-#include <direct.h>
-#undef SIGALRM
-#ifndef SIGUSR1
-#define SIGUSR1 7
-#endif /* SIGUSR1 */
-#define SIGALRM SIGUSR1
-_PROTOTYP( unsigned alarm, (unsigned) );
-_PROTOTYP( unsigned sleep, (unsigned) );
-#endif /* __EMX__ */
-_PROTOTYP( unsigned long zdskspace, (int) );
-_PROTOTYP( int zchdsk, (int) );
-_PROTOTYP( int conincraw, (int) );
-_PROTOTYP( int ttiscom, (int f) );
-_PROTOTYP( int IsFileNameValid, (char *) );
-_PROTOTYP( void ChangeNameForFAT, (char *) );
-_PROTOTYP( char *GetLoadPath, (void) );
-#endif /* OS2 */
-
-/* Fullscreen file transfer display items... */
-
-#ifndef NOCURSES
-#ifdef CK_NCURSES /* CK_NCURSES implies CK_CURSES */
-#ifndef CK_CURSES
-#define CK_CURSES
-#endif /* CK_CURSES */
-#endif /* CK_NCURSES */
-
-#ifdef MYCURSES /* MYCURSES implies CK_CURSES */
-#ifndef CK_CURSES
-#define CK_CURSES
-#endif /* CK_CURSES */
-#endif /* MYCURSES */
-#endif /* NOCURSES */
-
-#ifdef NOCURSES
-#ifdef CK_CURSES
-#undef CK_CURSES
-#endif /* CK_CURSES */
-#ifndef NODISPLAY
-#define NODISPLAY
-#endif /* NODISPLAY */
-#endif /* NOCURSES */
-
-#ifdef CK_CURSES
-/*
- The CK_WREFRESH symbol is defined if the curses library provides
- clearok() and wrefresh() functions, which are used in repainting
- the screen.
-*/
-#ifdef NOWREFRESH /* Override CK_WREFRESH */
-
-#ifdef CK_WREFRESH /* If this is defined, */
-#undef CK_WREFRESH /* undefine it. */
-#endif /* CK_WREFRESH */
-
-#else /* !NOWREFRESH */ /* No override... */
-
-#ifndef CK_WREFRESH /* If CK_WREFRESH not defined */
-/*
- Automatically define it for systems known to have it ...
-*/
-#ifdef VMS /* DEC (Open)VMS has it */
-#define CK_WREFRESH
-#else
-#ifdef ultrix /* DEC ULTRIX has it */
-#else
-#ifdef SVR3 /* System V has it */
-#define CK_WREFRESH
-#else
-#ifdef BSD44 /* 4.4 BSD has it */
-#define CK_WREFRESH
-#else
-#ifdef NEXT /* Define it for NeXTSTEP */
-#define CK_WREFRESH
-#else
-#ifdef SUNOS4 /* SunOS 4.x... */
-#define CK_WREFRESH
-#else
-#ifdef SOLARIS25 /* Solaris 2.5 and later */
-#define CK_WREFRESH
-#else
-#ifdef AIXRS /* RS/6000 AIX ... */
-#define CK_WREFRESH
-#else
-#ifdef RTAIX /* RT PC AIX ... */
-#define CK_WREFRESH
-#else
-#ifdef OSF /* DEC OSF/1 ... */
-#define CK_WREFRESH
-
-/* Add more here, or just define CK_WREFRESH on the CC command line... */
-
-#endif /* OSF */
-#endif /* RTAIX */
-#endif /* AIXRS */
-#endif /* SOLARIS25 */
-#endif /* SUNOS4 */
-#endif /* NEXT */
-#endif /* BSD44 */
-#endif /* SVR3 */
-#endif /* ultrix */
-#endif /* VMS */
-
-#else /* CK_WREFRESH is defined */
-
-/* This is within an ifdef CK_CURSES block. The following is not needed */
-
-#ifndef CK_CURSES /* CK_WREFRESH implies CK_CURSES */
-#define CK_CURSES
-#endif /* CK_CURSES */
-
-#endif /* CK_WREFRESH */
-#endif /* NOWREFRESH */
-
-#ifndef TRMBUFL
-#ifdef BIGBUFOK
-#define TRMBUFL 16384
-#else
-#ifdef DYNAMIC
-#define TRMBUFL 8192
-#else
-#define TRMBUFL 1024
-#endif /* BIGBUFOK */
-#endif /* DYNAMIC */
-#endif /* TRMBUFL */
-#endif /* CK_CURSES */
-
-/*
- Whether to use ckmatch() in all its glory for C-Shell-like patterns.
- If CKREGEX is NOT defined, all but * and ? matching are removed from
- ckmatch(). NOTE: Defining CKREGEX does not necessarily mean that ckmatch()
- regexes are used for filename matching. That depends on whether zxpand()
- in ck?fio.c calls ckmatch(). NOTE 2: REGEX is a misnomer -- these are not
- regular expressions in the computer-science sense (in which, e.g. "a*b"
- matches 0 or more 'a' characters followed by 'b') but patterns (in which
- "a*b" matches 'a' followed by 0 or more non-b characters, followed by b).
-*/
-#ifndef NOCKREGEX
-#ifndef CKREGEX
-#define CKREGEX
-#endif /* CKREGEX */
-#endif /* NOCKREGEX */
-
-/* Learned-script feature */
-
-#ifndef NOLEARN
-#ifdef NOSPL
-#define NOLEARN
-#else
-#ifdef NOLOCAL
-#define NOLEARN
-#endif /* NOLOCAL */
-#endif /* NOSPL */
-#endif /* NOLEARN */
-
-#ifdef NOLEARN
-#ifdef CKLEARN
-#undef CKLEARN
-#endif /* CKLEARN */
-#else /* !NOLEARN */
-#ifndef CKLEARN
-#ifdef OS2ORUNIX
-/* In UNIX this can work only with ckucns.c builds */
-#define CKLEARN
-#else
-#ifdef VMS
-#define CKLEARN
-#endif /* VMS */
-#endif /* OS2ORUNIX */
-#endif /* CKLEARN */
-#endif /* NOLEARN */
-
-#ifdef CKLEARN
-#ifndef LEARNBUFSIZ
-#define LEARNBUFSIZ 128
-#endif /* LEARNBUFSIZ */
-#endif /* CKLEARN */
-
-#ifndef IKSDONLY
-#ifndef CKTIDLE /* Pseudo-keepalive in CONNECT */
-#ifdef OS2 /* In K95 */
-#define CKTIDLE
-#else
-#ifdef UNIX /* In UNIX but only ckucns versions */
-#ifndef NOLEARN
-#ifndef NOSELECT
-#define CKTIDLE
-#endif /* NOSELECT */
-#endif /* NOLEARN */
-#endif /* UNIX */
-#endif /* OS2 */
-#endif /* CKTIDLE */
-#endif /* IKSDONLY */
-
-#ifdef CK_ANSILIBS
-/*
- String library functions.
- For ANSI C, get prototypes from <string.h>.
- Otherwise, skip the prototypes.
-*/
-#include <string.h>
-
-/*
- Prototypes for other commonly used library functions, such as
- malloc, free, getenv, atol, atoi, and exit. Otherwise, no prototypes.
-*/
-#include <stdlib.h>
-#ifdef DIAB /* DIAB DS90 */
-/* #include <commonC.h> */
-#include <sys/wait.h>
-#define CK_WAIT_H
-#ifdef COMMENT
-extern void exit(int status);
-extern void _exit(int status);
-extern int uname(struct utsname *name);
-#endif /* COMMENT */
-extern int chmod(char *path, int mode);
-extern int ioctl(int fildes, int request, ...);
-extern int rdchk(int ttyfd);
-extern int nap(int m);
-#ifdef COMMENT
-extern int getppid(void);
-#endif /* COMMENT */
-extern int _filbuf(FILE *stream);
-extern int _flsbuf(char c,FILE *stream);
-#endif /* DIAB */
-
-/*
- Prototypes for UNIX functions like access, alarm, chdir, sleep, fork,
- and pause. Otherwise, no prototypes.
-*/
-#ifdef VMS
-#include <signal.h> /* SMS: sleep() for old (V4.0-000) DEC C. */
-#include <unixio.h>
-#include <unixlib.h> /* SMS: getpid() for old (V4.0-000) DEC C. */
-#endif /* VMS */
-
-#ifdef NEXT
-#ifndef NEXT33
-#include <libc.h>
-#endif /* NEXT33 */
-#else /* NoT NeXT */
-#ifndef AMIGA
-#ifndef OS2
-#ifdef STRATUS
-#include <c_utilities.h>
-#else /* !STRATUS */
-#ifndef OSKXXC
-#include <unistd.h>
-#endif /* OSKXXC */
-#ifdef HAVE_CRYPT_H
-#include <crypt.h>
-#endif /* HAVE_CRYPT_H */
-#endif /* STRATUS */
-#endif /* OS2 */
-#endif /* AMIGA */
-#endif /* NEXT */
-
-#else /* Not ANSI libs... */
-
-#ifdef MAC
-#include <String.h>
-#include <StdLib.h>
-#endif /* MAC */
-
-#ifdef HPUX
-#ifndef HPUXPRE65
-#include <unistd.h>
-#endif /* HPUXPRE65 */
-#endif /* HPUX */
-
-#ifdef SUNOS41
-#include <unistd.h>
-#include <stdlib.h>
-#else
-#ifndef MAC
-/*
- It is essential that these are declared correctly!
- Which is not always easy. Take malloc() for instance ...
-*/
-#ifdef PYRAMID
-#ifdef SVR4
-#ifdef __STDC__
-#define SIZE_T_MALLOC
-#endif /* __STDC__ */
-#endif /* SVR4 */
-#endif /* PYRAMID */
-/*
- Maybe some other environments need the same treatment for malloc.
- If so, define SIZE_T_MALLOC for them here or in compiler CFLAGS.
-*/
-#ifdef SIZE_T_MALLOC
-_PROTOTYP( void * malloc, (size_t) );
-#else
-_PROTOTYP( char * malloc, (unsigned int) );
-#endif /* SIZE_T_MALLOC */
-
-_PROTOTYP( char * getenv, (char *) );
-_PROTOTYP( long atol, (char *) );
-#endif /* !MAC */
-#endif /* SUNOS41 */
-#endif /* CK_ANSILIBS */
-
-/*
- <sys/param.h> generally picks up NULL, MAXPATHLEN, and MAXNAMLEN
- and seems to present on all Unixes going back at least to SCO Xenix
- with the exception(s) noted.
-*/
-#ifndef NO_PARAM_H /* 2001-11-03 */
-#ifndef UNIX /* Non-Unixes don't have it */
-#define NO_PARAM_H
-#else
-#ifdef TRS16 /* Tandy Xenix doesn't have it */
-#define NO_PARAM_H
-#endif /* TRS16 */
-#endif /* UNIX */
-#endif /* NO_PARAM_H */
-
-#ifndef NO_PARAM_H
-#ifndef INCL_PARAM_H
-#define INCL_PARAM_H
-#endif /* INCL_PARAM_H */
-#include <sys/param.h>
-#endif /* NO_PARAM_H */
-
-#ifndef NULL /* In case NULL is still not defined */
-#define NULL 0L
-/* or #define NULL 0 */
-/* or #define NULL ((char *) 0) */
-/* or #define NULL ((void *) 0) */
-#endif /* NULL */
-
-/* Macro to differentiate "" from NULL (to avoid comparisons with literals) */
-
-#ifndef isemptystring
-#define isemptystring(s) ((s?(*s?0:1):0))
-#endif /* isemptystring */
-
-/* Maximum length for a fully qualified filename, not counting \0 at end. */
-/*
- This is a rough cut, and errs on the side of being too big. We don't
- want to pull in hundreds of header files looking for many and varied
- symbols, for fear of introducing unnecessary conflicts.
-*/
-#ifndef CKMAXPATH
-#ifdef VMS /* VMS may have bad (small, ODS2) */
-#define CKMAXPATH NAMX_C_MAXRSS /* PATH_MAX, so use NAMX_C_MAXRSS. */
-#else /* def VMS */
-#ifdef MAXPATHLEN /* (it probably isn't) */
-#define CKMAXPATH MAXPATHLEN
-#else
-#ifdef PATH_MAX /* POSIX */
-#define CKMAXPATH PATH_MAX
-#else /* def PATH_MAX */
-#ifdef MAC
-#define CKMAXPATH 63
-#else /* def MAC */
-#ifdef pdp11
-#define CKMAXPATH 255
-#else /* def pdp11 */
-#ifdef UNIX /* Even though some are way less... */
-#define CKMAXPATH 1024
-#else /* def UNIX */
-#ifdef STRATUS
-#define CKMAXPATH 256 /* == $MXPL from PARU.H */
-#else /* def STRATUS */
-#ifdef datageneral
-#define CKMAXPATH 256 /* == $MXPL from PARU.H */
-#else /* def datageneral */
-#define CKMAXPATH 255
-#endif /* def STRATUS [else] */
-#endif /* def datageneral [else] */
-#endif /* def UNIX [else] */
-#endif /* def pdp11 [else] */
-#endif /* def MAC [else] */
-#endif /* def PATH_MAX [else] */
-#endif /* def MAXPATHLEN [else] */
-#endif /* def VMS [else] */
-#endif /* ndef CKMAXPATH */
-
-/* Maximum length for the name of a tty device */
-
-#ifndef DEVNAMLEN
-#define DEVNAMLEN CKMAXPATH
-#endif /* DEVNAMLEN */
-
-/* Directory (path segment) separator */
-/* Not fully general - Tricky for VMS, Amiga, ... */
-
-#ifndef DIRSEP
-#ifdef UNIX
-#define DIRSEP '/'
-#define ISDIRSEP(c) ((c)=='/')
-#else
-#ifdef OS2
-#define DIRSEP '/'
-#define ISDIRSEP(c) ((c)=='/'||(c)=='\\')
-#else
-#ifdef datageneral
-#define DIRSEP ':'
-#define ISDIRSEP(c) (((c)==':')||((c)=='^')||((c)=='='))
-#else
-#ifdef STRATUS
-#define DIRSEP '>'
-#define ISDIRSEP(c) ((c)=='>')
-#else
-#ifdef VMS
-#define DIRSEP ']' /* (not really) */
-#define ISDIRSEP(c) ((c)==']'||(c)==':')
-#else
-#ifdef MAC
-#define DIRSEP ':'
-#define ISDIRSEP(c) ((c)==':')
-#else
-#ifdef AMIGA
-#define DIRSEP '/'
-#define ISDIRSEP(c) ((c)=='/'||(c)==':')
-#else
-#ifdef GEMDOS
-#define DIRSEP '\\'
-#define ISDIRSEP(c) ((c)=='\\'||(c)==':')
-#else
-#define DIRSEP '/'
-#define ISDIRSEP(c) ((c)=='/')
-#endif /* GEMDOS */
-#endif /* AMIGA */
-#endif /* MAC */
-#endif /* VMS */
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* OS2 */
-#endif /* UNIX */
-#endif /* DIRSEP */
-
-/* FILE package parameters */
-
-#ifdef pdp11
-#define NOCHANNELIO
-#else
-
-#ifndef CKMAXOPEN
-#ifdef QNX
-#define CKMAXOPEN 390
-#else
-#ifdef VMS
-#define CKMAXOPEN 64
-#else
-#ifdef OPEN_MAX
-#define CKMAXOPEN OPEN_MAX
-#else
-#ifdef FOPEN_MAX
-#define CKMAXOPEN FOPEN_MAX
-#else
-#define CKMAXOPEN 64
-#endif /* FOPEN_MAX */
-#endif /* OPEN_MAX */
-#endif /* VMS */
-#endif /* QNX */
-#endif /* CKMAXOPEN */
-
-/* Maximum channels for FOPEN = CKMAXOPEN minus logs, stdio, etc */
-
-#ifndef Z_MINCHAN
-#define Z_MINCHAN 16
-#endif /* Z_MINCHAN */
-
-#ifndef Z_MAXCHAN
-#define Z_MAXCHAN (CKMAXOPEN-ZNFILS-5)
-#endif /* Z_MAXCHAN */
-#endif /* pdp11 */
-
-/* New-format nzltor() and nzrtol() functions that handle pathnames */
-
-#ifndef NZLTOR
-#ifdef UNIX
-#define NZLTOR
-#else
-#ifdef VMS
-#define NZLTOR
-#else
-#ifdef OS2
-#define NZLTOR
-#else
-#ifdef STRATUS
-#define NZLTOR
-#endif /* STRATUS */
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* NZLTOR */
-
-#ifdef NZLTOR
-_PROTOTYP( VOID nzltor, (char *, char *, int, int, int) );
-_PROTOTYP( VOID nzrtol, (char *, char *, int, int, int) );
-#endif /* NZLTOR */
-
-/* Implementations with a zrmdir() function */
-
-#ifndef ZRMDIR
-#ifdef OS2
-#define ZRMDIR
-#else /* OS2 */
-#ifdef UNIX
-#define ZRMDIR
-#else
-#ifdef VMS
-#define ZRMDIR
-#else /* VMS */
-#ifdef STRATUS
-#define ZRMDIR
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* OS2 */
-#endif /* ZRMDIR */
-
-#ifdef ZRMDIR
-_PROTOTYP( int zrmdir, (char *) );
-#endif /* ZRMDIR */
-
-#ifndef FILECASE
-#ifdef UNIXOROSK
-#define FILECASE 1
-#else
-#define FILECASE 0
-#endif /* UNIXOROSK */
-#ifndef CKCMAI
-extern int filecase;
-#endif /* CKCMAI */
-#endif /* FILECASE */
-
-/* Funny names for library functions department... */
-
-#ifdef ZILOG
-#define setjmp setret
-#define longjmp longret
-#define jmp_buf ret_buf
-#define getcwd curdir
-#endif /* ZILOG */
-
-#ifdef STRATUS
-/* The C-runtime conflicts with things we do in Stratus VOS ckltio.c ... */
-#define printf vosprtf
-_PROTOTYP( int vosprtf, (char *fmt, ...) );
-#define perror(txt) printf("%s\n", txt)
-/* char_varying is a string type from PL/I that VOS uses extensively */
-#define CV char_varying
-#endif /* STRATUS */
-
-#ifdef NT
-extern int OSVer;
-#define isWin95() (OSVer==VER_PLATFORM_WIN32_WINDOWS)
-#else
-#define isWin95() (0)
-#endif /* NT */
-
-#ifndef BPRINT
-#ifdef OS2
-#define BPRINT
-#endif /* OS2 */
-#endif /* BPRINT */
-
-#ifndef SESLIMIT
-#ifdef OS2
-#define SESLIMIT
-#endif /* OS2 */
-#endif /* SESLIMIT */
-
-#ifndef NOTERM
-#ifndef PCTERM
-#ifdef NT
-#define PCTERM
-#endif /* NT */
-#endif /* PCTERM */
-#endif /* NOTERM */
-
-#ifdef BEOSORBEBOX
-#define query ckquery
-#endif /* BEOSORBEBOX */
-
-#ifndef PTYORPIPE /* NETCMD and/or NETPTY defined */
-#ifdef NETCMD
-#define PTYORPIPE
-#else
-#ifdef NETPTY
-#define PTYORPIPE
-#endif /* NETPTY */
-#endif /* NETCMD */
-#endif /* PTYORPIPE */
-
-/* mktemp() and mkstemp() */
-
-#ifndef NOMKTEMP
-#ifndef MKTEMP
-#ifdef OS2ORUNIX
-#define MKTEMP
-#endif /* OS2ORUNIX */
-#endif /* MKTEMP */
-
-#ifdef MKTEMP
-#ifndef NOMKSTEMP
-#ifndef MKSTEMP
-#ifdef BSD44
-#define MKSTEMP
-#else
-#ifdef __linux__
-#define MKSTEMP
-#endif /* __linux__ */
-#endif /* BSD44 */
-#endif /* MKSTEMP */
-#endif /* NOMKSTEMP */
-#endif /* MKTEMP */
-#endif /* NOMKTEMP */
-
-/* Platforms that have memcpy() -- only after all headers included */
-
-#ifndef USE_MEMCPY
-#ifdef VMS
-#define USE_MEMCPY
-#else
-#ifdef NEXT
-#define USE_MEMCPY
-#else
-#ifdef OS2
-#define USE_MEMCPY
-#else
-#ifdef __linux__
-#define USE_MEMCPY
-#else
-#ifdef SOLARIS
-#define USE_MEMCPY
-#else
-#ifdef SUNOS4
-#define USE_MEMCPY
-#else
-#ifdef AIXRS
-#define USE_MEMCPY
-#else
-#ifdef HPUX
-#define USE_MEMCPY
-#else
-#ifdef POSIX
-#define USE_MEMCPY
-#else
-#ifdef SVR4
-#define USE_MEMCPY
-#else
-#ifdef OSF
-#define USE_MEMCPY
-#else
-#ifdef datageneral
-#define USE_MEMCPY
-#else
-#ifdef STRATUS
-#define USE_MEMCPY
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* OSF */
-#endif /* SVR4 */
-#endif /* POSIX */
-#endif /* HPUX */
-#endif /* AIXRS */
-#endif /* SUNOS4 */
-#endif /* SOLARIS */
-#endif /* __linux__ */
-#endif /* OS2 */
-#endif /* NEXT */
-#endif /* VMS */
-#endif /* USE_MEMCPY */
-
-#ifndef USE_MEMCPY
-#define memcpy(a,b,c) ckmemcpy((a),(b),(c))
-#else
-#ifdef CK_SCO32V4
-/* Because the prototype isn't picked up in the normal header files */
-_PROTOTYP( void *memcpy, (void *, const void *, size_t));
-#endif /* CK_SCO32V4 */
-#endif /* USE_MEMCPY */
-
-/* User authentication for IKS -- So far K95 and UNIX only */
-
-#ifdef NOICP
-#ifndef NOLOGIN
-#define NOLOGIN
-#endif /* NOLOGIN */
-#endif /* NOICP */
-
-#ifndef NOLOGIN
-#ifdef OS2ORUNIX
-#ifndef CK_LOGIN
-#define CK_LOGIN
-#ifndef NOSHADOW
-#ifdef CK_SCOV5
-#define CK_SHADOW
-#endif /* CK_SCOV5 */
-#endif /* NOSHADOW */
-#endif /* CK_LOGIN */
-#ifdef NT
-#define NTCREATETOKEN
-#endif /* NT */
-#endif /* OS2ORUNIX */
-#else /* NOLOGIN */
-#ifdef CK_LOGIN
-#undef CK_LOGIN
-#endif /* CK_LOGIN */
-#endif /* NOLOGIN */
-
-#ifdef OS2
-#define CKSPINNER
-#endif /* OS2 */
-
-#ifdef CK_LOGIN /* Telnet protocol required */
-#ifndef TNCODE /* for login to IKSD. */
-#define TNCODE
-#endif /* TNCODE */
-#endif /* CK_LOGIN */
-
-#ifdef CK_AUTHENTICATION
-#ifdef NOSENDUID
-#undef NOSENDUID
-#endif /* NOSENDUID */
-#endif /* CK_AUTHENTICATION */
-
-#ifdef TNCODE /* Should TELNET send user ID? */
-#ifndef NOSENDUID
-#ifndef CKSENDUID
-#define CKSENDUID
-#endif /* CKSENDUID */
-#endif /* NOSENDUID */
-#endif /* TNCODE */
-
-/* UNIX platforms that don't have getusershell() */
-
-#ifdef UNIX
-#ifndef NOGETUSERSHELL
-#ifdef IRIX
-#define NOGETUSERSHELL
-#else
-#ifdef PTX
-#define NOGETUSERSHELL
-#else
-#ifdef AIXRS
-#define NOGETUSERSHELL
-#else
-#ifdef SINIX
-#define NOGETUSERSHELL
-#else
-#ifdef UNIXWARE
-#define NOGETUSERSHELL
-#else
-#ifdef COHERENT
-#define NOGETUSERSHELL
-#endif /* COHERENT */
-#endif /* UNIXWARE */
-#endif /* SINIX */
-#endif /* AIXRS */
-#endif /* PTX */
-#endif /* IRIX */
-#endif /* NOGETUSERSHELL */
-#endif /* UNIX */
-
-#ifdef CK_LOGIN
-#ifdef NT
-#ifndef NOSYSLOG
-#ifndef CKSYSLOG
-#define CKSYSLOG
-#endif /* CKSYSLOG */
-#endif /* NOSYSLOG */
-#endif /* NT */
-#ifdef UNIX
-#ifndef NOSYSLOG
-#ifndef CKSYSLOG
-#define CKSYSLOG
-#endif /* CKSYSLOG */
-#endif /* NOSYSLOG */
-#ifndef NOWTMP
-#ifndef CKWTMP
-#define CKWTMP
-#endif /* CKWTMP */
-#endif /* NOWTMP */
-#ifndef NOGETUSERSHELL
-#ifndef GETUSERSHELL
-#define GETUSERSHELL
-#endif /* GETUSERSHELL */
-#endif /* NOGETUSERSHELL */
-#endif /* UNIX */
-_PROTOTYP( int ckxlogin, (CHAR *, CHAR *, CHAR *, int));
-_PROTOTYP( int ckxlogout, (VOID));
-#endif /* CK_LOGIN */
-
-#ifndef NOZLOCALTIME /* zlocaltime() available. */
-#ifdef OS2ORUNIX
-#define ZLOCALTIME
-_PROTOTYP( char * zlocaltime, (char *) );
-#endif /* OS2ORUNIX */
-#endif /* NOZLOCALTIME */
-
-#ifdef CKSYSLOG /* Syslogging levels */
-#define SYSLG_NO 0 /* No logging */
-#define SYSLG_LI 1 /* Login/out */
-#define SYSLG_DI 2 /* Dialing out */
-#define SYSLG_AC 3 /* Making any kind of connection */
-#define SYSLG_PR 4 /* Protocol Operations */
-#define SYSLG_FC 5 /* File creation */
-#define SYSLG_FA 6 /* File reading */
-#define SYSLG_CM 7 /* Top-level commands */
-#define SYSLG_CX 8 /* All commands */
-#define SYSLG_DB 9 /* Debug */
-#define SYSLGMAX 9 /* Highest level */
-#define SYSLG_DF SYSLG_FA /* Default level */
-/* Logging function */
-_PROTOTYP(VOID cksyslog,(int, int, char *, char *, char *));
-#endif /* CKSYSLOG */
-#ifndef CKCMAI
-extern int ckxlogging, ckxsyslog, ikdbopen;
-#endif /* CKCMAI */
-
-#ifndef CK_KEYTAB
-#define CK_KEYTAB
-/* Keyword Table Template */
-
-/* Note: formerly defined in ckucmd.h but now more widely used */
-
-struct keytab { /* Keyword table */
- char *kwd; /* Pointer to keyword string */
- int kwval; /* Associated value */
- int flgs; /* Flags (as defined above) */
-};
-#endif /* CK_KEYTAB */
-
-#ifdef UNIX
-_PROTOTYP( int isalink, (char *));
-#endif /* UNIX */
-
-#ifdef NETPTY
-_PROTOTYP( int do_pty, (int *, char *, int));
-_PROTOTYP( VOID end_pty, (void));
-#endif /* NETPTY */
-
-#ifdef CKROOT
-_PROTOTYP( int zsetroot, (char *) );
-_PROTOTYP( char * zgetroot, (void) );
-_PROTOTYP( int zinroot, (char *) );
-#endif /* CKROOT */
-
-/* Local Echo Buffer prototypes */
-_PROTOTYP( VOID le_init, (void) );
-_PROTOTYP( VOID le_clean, (void));
-_PROTOTYP( int le_inbuf, (void));
-_PROTOTYP( int le_putstr, (CHAR *));
-_PROTOTYP( int le_puts, (CHAR *, int));
-_PROTOTYP( int le_putchar, (CHAR));
-_PROTOTYP( int le_getchar, (CHAR *));
-
-/* #ifndef NOHTTP */
-#ifndef NOCMDATE2TM
-#ifndef CMDATE2TM
-#ifdef OS2ORUNIX
-#define CMDATE2TM
-#endif /* OS2ORUNIX */
-#ifdef VMS
-#define CMDATE2TM
-#endif /* VMS */
-#endif /* CMDATE2TM */
-#endif /* NOCMDATE2TM */
-
-#ifdef CMDATE2TM
-_PROTOTYP( struct tm * cmdate2tm, (char *,int));
-#endif /* CMDATE2TM */
-/* #endif */ /* NOHTTP */
-
-#ifndef NOSETTIME /* This would be set in CFLAGS */
-#ifdef SVR4ORPOSIX /* Defined in IEEE 1003.1-1996 */
-#ifndef UTIMEH /* and in SVID for SVR4 */
-#define UTIMEH
-#endif /* UTIMEH */
-#else /* SVR4ORPOSIX */
-#ifdef OSF /* Verified by Lucas Hart */
-#ifndef UTIMEH
-#define UTIMEH
-#endif /* UTIMEH */
-#else /* OSF */
-#ifdef SUNOS41 /* Verified by Lucas Hart */
-#ifndef UTIMEH
-#define UTIMEH
-#endif /* UTIMEH */
-#else /* SUNOS41 */
-#ifdef OS2
-#ifndef SYSUTIMEH
-#define SYSUTIMEH
-#endif /* SYSUTIMEH */
-#else /* OS2 */
-#ifdef VMS
-#ifndef UTIMEH
-#define UTIMEH
-#endif /* UTIMEH */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* SUNOS41 */
-#endif /* OSF */
-#endif /* SVR4ORPOSIX */
-#endif /* NOSETTIME */
-
-#ifdef NEWFTP
-_PROTOTYP( int ftpisconnected, (void));
-_PROTOTYP( int ftpisloggedin, (void));
-_PROTOTYP( int ftpissecure, (void));
-#endif /* NEWFTP */
-
-_PROTOTYP( int readpass, (char *, char *, int));
-_PROTOTYP( int readtext, (char *, char *, int));
-
-#ifdef OS2
-_PROTOTYP(int ck_auth_loaddll, (VOID));
-_PROTOTYP(int ck_auth_unloaddll, (VOID));
-#endif /* OS2 */
-
-#ifdef NT
-_PROTOTYP(DWORD ckGetLongPathname,(LPCSTR lpFileName,
- LPSTR lpBuffer, DWORD cchBuffer));
-#endif /* NT */
-
-
-#include "ckclib.h"
-
-/* End of ckcdeb.h */
-#endif /* CKCDEB_H */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcfn2.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckcfn2.c
deleted file mode 100644
index 5fa0507..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcfn2.c
+++ /dev/null
@@ -1,3350 +0,0 @@
-/* C K C F N 2 -- System-independent Kermit protocol support functions... */
-
-/* ...Part 2 (continued from ckcfns.c) */
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-/*
- Note -- if you change this file, please amend the version number and date at
- the top of ckcfns.c accordingly.
-*/
-
-#include "ckcsym.h" /* Compilation options */
-#include "ckcdeb.h" /* Debugging and other symbols */
-#include "ckcasc.h" /* ASCII symbols */
-#include "ckcker.h" /* Kermit symbols */
-#include "ckcxla.h" /* Translation */
-#include "ckcnet.h" /* IKS and VMS #define TCPSOCKET */
-#ifdef TCPSOCKET /* For TELNET business in spack() */
-extern int tn_nlm, ttnproto, tn_b_nlm;
-#endif /* TCPSOCKET */
-
-extern int parity, network, local, interrupted, fatalio, wasclosed;
-
-int kstartactive = 0; /* Flag for kstart() in a packet */
-
-static CHAR p_tbl[] = { /* Even parity table for dopar(). */
- (CHAR) '\000', /* ANSI C casts '\ooo' constants */
- (CHAR) '\201', /* to signed char, so we have to */
- (CHAR) '\202', /* cast back to unsigned char... */
- (CHAR) '\003',
- (CHAR) '\204',
- (CHAR) '\005',
- (CHAR) '\006',
- (CHAR) '\207',
- (CHAR) '\210',
- (CHAR) '\011',
- (CHAR) '\012',
- (CHAR) '\213',
- (CHAR) '\014',
- (CHAR) '\215',
- (CHAR) '\216',
- (CHAR) '\017',
- (CHAR) '\220',
- (CHAR) '\021',
- (CHAR) '\022',
- (CHAR) '\223',
- (CHAR) '\024',
- (CHAR) '\225',
- (CHAR) '\226',
- (CHAR) '\027',
- (CHAR) '\030',
- (CHAR) '\231',
- (CHAR) '\232',
- (CHAR) '\033',
- (CHAR) '\234',
- (CHAR) '\035',
- (CHAR) '\036',
- (CHAR) '\237',
- (CHAR) '\240',
- (CHAR) '\041',
- (CHAR) '\042',
- (CHAR) '\243',
- (CHAR) '\044',
- (CHAR) '\245',
- (CHAR) '\246',
- (CHAR) '\047',
- (CHAR) '\050',
- (CHAR) '\251',
- (CHAR) '\252',
- (CHAR) '\053',
- (CHAR) '\254',
- (CHAR) '\055',
- (CHAR) '\056',
- (CHAR) '\257',
- (CHAR) '\060',
- (CHAR) '\261',
- (CHAR) '\262',
- (CHAR) '\063',
- (CHAR) '\264',
- (CHAR) '\065',
- (CHAR) '\066',
- (CHAR) '\267',
- (CHAR) '\270',
- (CHAR) '\071',
- (CHAR) '\072',
- (CHAR) '\273',
- (CHAR) '\074',
- (CHAR) '\275',
- (CHAR) '\276',
- (CHAR) '\077',
- (CHAR) '\300',
- (CHAR) '\101',
- (CHAR) '\102',
- (CHAR) '\303',
- (CHAR) '\104',
- (CHAR) '\305',
- (CHAR) '\306',
- (CHAR) '\107',
- (CHAR) '\110',
- (CHAR) '\311',
- (CHAR) '\312',
- (CHAR) '\113',
- (CHAR) '\314',
- (CHAR) '\115',
- (CHAR) '\116',
- (CHAR) '\317',
- (CHAR) '\120',
- (CHAR) '\321',
- (CHAR) '\322',
- (CHAR) '\123',
- (CHAR) '\324',
- (CHAR) '\125',
- (CHAR) '\126',
- (CHAR) '\327',
- (CHAR) '\330',
- (CHAR) '\131',
- (CHAR) '\132',
- (CHAR) '\333',
- (CHAR) '\134',
- (CHAR) '\335',
- (CHAR) '\336',
- (CHAR) '\137',
- (CHAR) '\140',
- (CHAR) '\341',
- (CHAR) '\342',
- (CHAR) '\143',
- (CHAR) '\344',
- (CHAR) '\145',
- (CHAR) '\146',
- (CHAR) '\347',
- (CHAR) '\350',
- (CHAR) '\151',
- (CHAR) '\152',
- (CHAR) '\353',
- (CHAR) '\154',
- (CHAR) '\355',
- (CHAR) '\356',
- (CHAR) '\157',
- (CHAR) '\360',
- (CHAR) '\161',
- (CHAR) '\162',
- (CHAR) '\363',
- (CHAR) '\164',
- (CHAR) '\365',
- (CHAR) '\366',
- (CHAR) '\167',
- (CHAR) '\170',
- (CHAR) '\371',
- (CHAR) '\372',
- (CHAR) '\173',
- (CHAR) '\374',
- (CHAR) '\175',
- (CHAR) '\176',
- (CHAR) '\377'
-};
-
-/* D O P A R -- Add an appropriate parity bit to a character */
-
-CHAR
-#ifdef CK_ANSIC
-dopar(register CHAR ch)
-#else
-dopar(ch) register CHAR ch;
-#endif /* CK_ANSIC */
- {
- register unsigned int a;
- if (!parity
-#ifdef TCPSOCKET
- || (network && (ttnproto == NP_TELNET) && (TELOPT_ME(TELOPT_BINARY)))
-#ifndef NOXFER
- || (!local && sstelnet) /* TELNET BINARY MODE */
-#endif /* NOXFER */
-#endif /* TCPSOCKET */
- ) return((CHAR) (ch & 255)); else a = ch & 127;
- switch (parity) {
- case 'e': return(p_tbl[a]); /* Even */
- case 'm': return((CHAR) (a | 128)); /* Mark */
- case 'o': return((CHAR) (p_tbl[a] ^ 128)); /* Odd */
- case 's': return((CHAR) a); /* Space */
- default: return((CHAR) a); /* Something illegal */
- }
-}
-
-#ifndef NOXFER /* Rest of this file... */
-
-#define NEWDPL /* New dynamic packet length method */
-
-#ifdef VMS
-extern int batch;
-#else
-extern int backgrd;
-#endif /* VMS */
-
-#ifdef DYNAMIC
-extern struct pktinfo *s_pkt; /* array of pktinfo structures */
-extern struct pktinfo *r_pkt; /* array of pktinfo structures */
-#else
-extern struct pktinfo s_pkt[]; /* array of pktinfo structures */
-extern struct pktinfo r_pkt[]; /* array of pktinfo structures */
-#endif /* DYNAMIC */
-
-extern int sseqtbl[], rseqtbl[], sbufuse[], sacktbl[], wslots, winlo, wslotn,
- sbufnum, rbufnum, pktpaus, reliable;
-
-#ifdef STREAMING
-static int dontsend = 0;
-extern int streaming;
-#endif /* STREAMING */
-
-extern int ttprty; /* from ck*tio.c */
-extern int autopar;
-
-extern int spsiz, spmax, rpsiz, timint, timef, npad, bestlen, maxsend;
-extern int rpt, rptq, rptflg, capas, spsizf, en_fin, tsecs, flow;
-extern int pktnum, sndtyp, rcvtyp, bctr, bctu, bctf, bctl, rsn, rln, maxtry;
-extern int size, osize, maxsize, spktl, rpktl, nfils, stdouf, fsecs;
-extern int turn, turnch, displa, pktlog, seslog, xflg, mypadn;
-extern int hcflg, server, cxseen, czseen, discard, slostart;
-extern int nakstate, quiet, success, xitsta, what, filestatus;
-extern int spackets, rpackets, timeouts, retrans, crunched, urpsiz;
-extern int carrier, fdispla, srvidl;
-
-#ifdef GFTIMER
-extern CKFLOAT fptsecs, fpfsecs, fpxfsecs;
-#endif /* GFTIMER */
-
-extern long filcnt, filrej, speed, filcps, tfcps;
-extern CK_OFF_T ffc, flci, flco, tlci, tlco, tfc;
-
-extern char *cmarg, filnam[];
-
-extern CHAR padch, mypadc, eol, seol, ctlq, sstate;
-extern CHAR *recpkt, *data, myinit[];
-extern CHAR *srvptr, stchr, mystch, *rdatap;
-extern CHAR padbuf[];
-extern CHAR * epktmsg;
-extern int epktrcvd, epktsent;
-
-#ifdef OS2 /* AUTODOWNLOAD parameters */
-extern int adl_kmode, adl_zmode; /* Match Packet to signal download */
-extern char * adl_kstr; /* KERMIT Download String */
-extern char * adl_zstr; /* ZMODEM Download String */
-#endif /* OS2 */
-
-#ifdef CK_AUTODL
-CHAR ksbuf[96] = { NUL, NUL }; /* Autodownload "Kermit Start" buf */
-#endif /* CK_AUTODL */
-
-int numerrs = 0; /* Number of packet errors so far */
-int rcvtimo = 0; /* Timeout for receiving a packet */
-int idletmo = 0; /* Flag for idle timeout */
-
-long filcps = 0L; /* CPS most recent file transferred */
-long tfcps = 0L; /* CPS most recent transaction */
-long xfsecs = 0L; /* Elapsed time for most recent file */
-#ifdef GFTIMER
-CKFLOAT fpxfsecs = 0.0; /* Ditto, but floating point */
-#endif /* GFTIMER */
-
-#ifdef CK_TIMERS
-int rrttbl[64], srttbl[64]; /* Packet timestamp tables */
-extern int rttflg;
-#define RTT_SCALE 1000
-long
- rttsamples, /* Round trip time samples */
- rttdelay, /* RTT delay */
- pktintvl, /* Interpacket arrival time */
- rttvariance, /* RTT variance */
- rttstddev; /* RTT standard deviation */
-#endif /* CK_TIMERS */
-
-/* CRC generation tables */
-
-long crcta[16] = { 0L, 010201L, 020402L, 030603L, 041004L,
- 051205L, 061406L, 071607L, 0102010L, 0112211L, 0122412L, 0132613L, 0143014L,
- 0153215L, 0163416L, 0173617L
-};
-
-long crctb[16] = { 0L, 010611L, 021422L, 031233L, 043044L,
- 053655L, 062466L, 072277L, 0106110L, 0116701L, 0127532L, 0137323L, 0145154L,
- 0155745L, 0164576L, 0174367L
-};
-
-#ifdef CK_TIMERS
-/*
- Round-trip timer calculations adapted from Tim Kientzle's article,
- "Improving Kermit Performance", Dr Dobb's Journal, February 1996.
-*/
-
-
-/* R T T I N I T -- Initialize timers at start of transaction */
-
-VOID
-rttinit() { /* Initialize round-trip timing */
- int i;
-
- if (timint == 0)
- return;
-
- rttsamples = 0L; /* Samples (packets) */
- rttvariance = 0L; /* Variance in delay */
- rttdelay = (long) timint * RTT_SCALE; /* Delay */
- pktintvl = (long) timint * RTT_SCALE; /* Delay */
- rttstddev = (long) timint * RTT_SCALE; /* Standard deviation of delay */
-
- /* Tables of timestamps indexed by packet sequence number */
-
- for (i = 0; i < 64; i++) {
- rrttbl[i] = -1; /* Time each packet was received */
- srttbl[i] = -1; /* Time each packet was sent */
- }
- rcvtimo = timint; /* Initial timeout is what user said */
-}
-
-/* G E T R T T -- Get packet round trip time */
-/*
- Call with nakstate == 0 if file sender, nonzero if receiver,
- and n == packet sequence number of the packet we just received.
-
- Returns:
- -1 on failure with rcvtimo set to timint (what the user said), or:
- 0 on success with rcvtimo set to dynamically calculated value:
- 1 <= rcvtimo <= timint * 3.
-*/
-int
-getrtt(nakstate, n) int nakstate, n; {
- extern int mintime, maxtime;
- static int prevz = 0, prevr = 0;
- int x, y, yy, z = 0, zz = 0; /* How long did it take to get here? */
-
- rcvtimo = timint; /* Default timeout is what user said */
-
- if (timint == 0) /* We're not timing out. */
- return(0);
-
- if (!rttflg) /* Not supposed to be doing this? */
- return(-1); /* So don't */
-
- if (!RTT_SCALE) /* Paranoia... */
- return(-1);
-
- /* rtimer() (reset timer) is not called until 1st data packet */
-#ifdef GFTIMER
- /* rftimer(); */
-#endif /* GFTIMER */
- /* S (F [ A ] D* Z)* B */
-
- /* NOTE: we calculate both the round-trip time AND the packet */
- /* arrival rate. We don't use the RTT for anything, we just display it. */
- /* Timeouts are based on the packet arrival rate. */
-
- if (spackets > 3) { /* Don't start till 4th packet */
- if (nakstate) { /* File receiver */
- x = rrttbl[n]; /* Time when I got packet n */
- y = rrttbl[n > 0 ? n - 1 : 63]; /* Time when I got packet n-1 */
- yy = srttbl[n > 0 ? n - 1 : 63]; /* Time when I sent ACK(n-1) */
- if (x > -1 && y > -1) { /* Be careful */
- z = x - y; /* Packet rate */
- zz = x - yy; /* Round trip time */
- z++; /* So sender & receiver differ */
- debug(F101,"RTT RECV","",z);
- } else { /* This shouldn't happen */
- debug(F101,"RTT RECV ERROR spackets","",spackets);
- debug(F101,"RTT RECV ERROR sequence","",n);
- return(-1);
- }
- } else { /* File sender */
- x = rrttbl[n]; /* Time when I got ACK(n) */
- y = rrttbl[n > 0 ? n - 1 : 63]; /* Time when I got packet n-1 */
- yy = srttbl[n]; /* Time when I sent n */
- if (x > -1 && y > -1) {
- z = x - y; /* Packet rate */
- zz = x - yy; /* Round trip time */
- debug(F101,"RTT SEND","",z);
- } else {
- debug(F100,"RTT SEND ERROR","",0);
- return(-1);
- }
- }
- if (z < 1) /* For fast connections */
- z = RTT_SCALE / 2; /* Convert to scale... */
- else
- z *= RTT_SCALE;
- debug(F101,"RTT z scaled","",z);
-
- if (zz < 1) /* For fast connections */
- zz = RTT_SCALE / 2; /* Convert to scale... */
- else
- zz *= RTT_SCALE;
-
- rttdelay = zz; /* Round trip time of this packet */
-#ifdef COMMENT
-/*
- This was used in C-Kermit 7.0 (and 6.0?) but not only is it overkill,
- it also can produce ridiculously long timeouts under certain conditions.
- Replaced in 8.0 by a far simpler and more aggressive strategy.
-*/
- if (rttsamples++ == 0L) { /* First sample */
- pktintvl = z;
- } else { /* Subsequent samples */
- long oldavg = pktintvl;
- long rttdiffsq;
-
- if (rttsamples > 30) /* Use real average for first 30 */
- rttsamples = 30; /* then decaying average. */
-
- /* Average delay, difference squared, variance, std deviation */
-
- pktintvl += (z - pktintvl) / rttsamples;
- rttdiffsq = (z - oldavg) * (z - oldavg);
- rttvariance += (rttdiffsq - rttvariance) / rttsamples;
- debug(F101,"RTT stddev1","",rttstddev);
- if (rttstddev < 1L) /* It can be zero, in which case */
- rttstddev = RTT_SCALE / 3; /* set it to something small... */
- rttstddev = (rttstddev + rttvariance / rttstddev) / 2;
- }
- debug(F101,"RTT stddev2","",rttstddev);
- debug(F101,"RTT delay ","",pktintvl);
- rcvtimo = (pktintvl + (3L * rttstddev)) / RTT_SCALE + 1;
- if (rpackets < 32) /* Allow for slow start */
- rcvtimo += rcvtimo + 2;
- else if (rpackets < 64)
- rcvtimo += rcvtimo / 2 + 1;
- /* On a reliable link, don't try too hard to time out. */
- /* Especially on fast local network connections. */
- if (server && what == W_NOTHING) /* Server command wait */
- rcvtimo = rcvtimo; /* == srvtim */
- else if (reliable == SET_ON && rcvtimo > 0) /* Reliable */
- rcvtimo = rcvtimo +15; /* and not server command wait */
- else /* Not reliable or server cmd wait */
- rcvtimo = rcvtimo;
- if (rcvtimo < mintime) /* Lower bound */
- rcvtimo = mintime;
- if (maxtime > 0) { /* User specified an upper bound */
- if (rcvtimo > maxtime)
- rcvtimo = maxtime;
- } else if (maxtime == 0) { /* User didn't specify */
- if (rcvtimo > timint * 6)
- rcvtimo = timint * 6;
- }
-#else /* COMMENT */
-#ifdef CKFLOAT
- {
- CKFLOAT x;
- x = (CKFLOAT)(prevz + z + z) / 3.0;
- rcvtimo = (int)((((CKFLOAT)x * 2.66) / RTT_SCALE) + 0.5);
- debug(F101,"RTT rcvtimo (float)","",rcvtimo);
- }
-#else
- rcvtimo = (prevz + z + z) / RTT_SCALE;
- debug(F101,"RTT rcvtimo (int)","",rcvtimo);
-#endif /* CKFLOAT */
-#endif /* COMMENT */
-
- zz = (rttdelay + 500) / 1000;
- if (rcvtimo > (zz * 3))
- rcvtimo = zz * 3;
-
- if (rcvtimo < 1)
- rcvtimo = 1;
- if (mintime > 0) {
- if (rcvtimo < mintime) /* Lower bound */
- rcvtimo = mintime;
- }
- if (maxtime > 0) { /* Upper bound */
- if (rcvtimo > maxtime)
- rcvtimo = maxtime;
- }
- if (rcvtimo == (prevr - 1))
- rcvtimo++;
-
- debug(F101,"RTT final rcvtimo","",rcvtimo);
- }
- prevz = z;
- prevr = rcvtimo;
- return(0);
-}
-#endif /* CK_TIMERS */
-
-/* I N P U T -- Attempt to read packet number 'pktnum'. */
-
-/*
- This is the function that feeds input to Kermit's finite state machine,
- in the form of a character in the range 32-126, normally a packet type
- (uppercase letter) or pseudo-packet-type (lowercase letter).
-
- If a special start state is in effect, that state is returned as if it were
- the type of an incoming packet.
-*/
-int
-input() {
- int type = 0, acktype; /* Received packet type */
- int x, y, k; /* Workers */
- int z, pi, nf; /* Worker, packet index, NAK flag */
- int nak2ack = 0;
-
- debug(F000,"input sstate","",sstate);
- debug(F101,"input nakstate","",nakstate);
- debug(F000,"input sndtyp","",sndtyp);
- debug(F101,"input xitsta","",xitsta);
- debug(F101,"input what","",what);
-
- while (1) { /* Big loop... */
-/*
- It is ttchk()'s responsibility to tell us if the connection is broken,
- and to do so instantly and nondestructively -- no blocking, etc, that would
- slow down file transfer.
-*/
- if (ttchk() < 0) {
- debug(F100,"input CONNECTION BROKEN","",0);
- fatalio = 1;
- return('q');
- }
- if (sstate != 0) { /* If a start state is in effect, */
- type = sstate; /* return it like a packet type, */
- sstate = 0; /* and then nullify it. */
- numerrs = 0; /* (PWP) no errors so far */
- return(type);
- }
- if (nakstate) { /* This section for file receiver. */
- if (wslots > 1) { /* If we're doing windows, */
- x = rseqtbl[winlo]; /* see if desired packet already in. */
- debug(F101,"input winlo","",winlo);
- debug(F101,"input rseqtbl[winlo]","",rseqtbl[winlo]);
- if (x > -1) { /* Already there? */
- if (r_pkt[x].pk_seq == winlo) { /* (double check) */
- rsn = winlo; /* Yes, return its info */
- debug(F101,"input return pre-stashed packet","",rsn);
- dumprbuf();
- rdatap = r_pkt[x].pk_adr; /* like rpack would do. */
- rln = (int)strlen((char *) rdatap);
- type = r_pkt[x].pk_typ;
- break;
- }
- }
- }
- type = rpack(); /* Try to read a packet. */
- debug(F101,"input rpack","",type);
-
- while (type == 'e') { /* Handle echoes */
- debug(F101,"input echo discarded","",type);
- type = rpack();
- }
-#ifdef DEBUG
- if (deblog) {
- if (type == 'D')
- debug(F011,"input type D=",(char *)rdatap,39);
- else
- debug(F000,"input type",(char *)rdatap,type);
- }
-#endif /* DEBUG */
-#ifndef OLDCHKINT
- if (type == 'z') {
- epktrcvd = 1;
- errpkt((CHAR *)"User cancelled.");
- type = 'E';
- break;
- }
-#endif /* OLDCHKINT */
- if (type < -1) {
- char * s;
- s = (type == -2) ?
- "FAILED - Interrupted" :
- "FAILED - Connection lost";
-
- xxscreen(SCR_PT,'q',0L,s);
- dologend();
- return('q'); /* Ctrl-C or connection lost */
- }
- if (type < 0) { /* Receive window full */
- /* Another thing to do here would be to delete */
- /* the highest packet and NAK winlo. But that */
- /* shouldn't be necessary since the other Kermit */
- /* should not have sent a packet outside the window. */
-#ifdef COMMENT
- char foo[256];
- ckmakxmsg(foo,256,"Receive window full (rpack): wslots=",
- ckitoa(wslots)," winlo=",ckitoa(winlo)," pktnum=",
- ckitoa(pktnum), NULL,NULL,NULL,NULL,NULL,NULL);
- errpkt((CHAR *)foo);
- debug(F100,foo,"",0);
-#else
- errpkt((CHAR *)"Receive window full");
- debug(F101,"rpack receive window full","",0);
- debug(F101," wslots","",wslots);
- debug(F101," winlo","",winlo);
- debug(F101," pktnum","",pktnum);
-#endif
- dumprbuf();
- type = 'E';
- break;
- }
- dumprbuf();
-
-#ifdef OLDCHKINT
- if (chkint() < 0) { /* Check for console interrupts. */
- errpkt((CHAR *)"User cancelled."); /* (old way) */
- type = 'E';
- break;
- }
-#endif /* OLDCHKINT */
-
-#ifdef STREAMING
- if (streaming) { /* Streaming */
- if (type == 'Q' || type == 'T') { /* Errors are fatal. */
- crunched++; /* For statistics */
- errpkt((CHAR *)"Transmission error on reliable link.");
- type = 'E';
- }
- }
-#endif /* STREAMING */
- if (type == 'E') {
- debug(F101,"input got E, nakstate","",nakstate);
- break; /* Error packet */
- }
- if (type == 'Q') { /* Crunched packet. */
- crunched++;
- numerrs++;
-/*
- Packet arrived damaged. It was most likely the packet we were expecting
- next, so we send a NAK for that packet. Prior to 5A(189), we always
- NAK'd winlo here, but that was bad because if two (or more) different
- packets were damaged, we would keep NAKing the first one and never NAK the
- other ones, which could result in a lengthy series of timeouts. Now we
- NAK the oldest as-yet-unNAK'd missing packet.
-*/
-#ifdef CK_TIMERS
- rcvtimo++; /* Stretch the timeout a little */
-#endif /* CK_TIMERS */
- z = (winlo + wslots) % 64; /* Search from winlo to z */
- debug(F101,"ZZZ crunched z","",z);
- nf = 0; /* NAK flag not set yet */
- for (x = winlo; x != z; x = (x + 1) % 64) {
- debug(F101,"ZZZ x","",x);
- if (rseqtbl[x] > -1) /* Have I received packet x? */
- continue; /* Yes, go on. */
- debug(F101,"ZZZ x not recd yet","",x);
- pi = sseqtbl[x]; /* No, have I NAK'd it yet? */
- if (pi < 0 || s_pkt[pi].pk_rtr == 0) {
- debug(F101,"ZZZ x not NAK'd yet","",x);
- nack(x); /* No, NAK it now. */
- nf = 1; /* Flag that I did. */
- break;
- }
- }
- if (!nf) { /* If we didn't NAK anything above, */
- debug(F101,"ZZZ NAKing winlo","",winlo);
- if (nack(winlo) < 0) { /* we have to NAK winlo (again) */
- errpkt((CHAR *)"Too many retries."); /* Too many */
- type = 'E';
- break;
- }
- }
- continue;
- }
-
- if (type == 'T') { /* Timeout */
-#ifndef OS2
- /* K95 does this its own way */
- if (server && srvidl) {
- idletmo = 1;
- debug(F101,"SERVER IDLE TIMEOUT","",srvidl);
- return('q');
- }
-#endif /* OS2 */
-#ifdef CK_TIMERS
- rcvtimo++; /* Stretch the timeout a little */
-#endif /* CK_TIMERS */
- timeouts++;
- debug(F101,"input receive-state timeout, winlo","",winlo);
- /* NAK only the packet at window-low */
- debug(F101,"input sending NAK for winlo","",winlo);
- x = ttchk();
- if (x > 0) /* Don't give up if there is still */
- continue; /* something to read. */
- else if (x < 0) {
- dologend();
- fatalio = 1;
- return('q'); /* Connection Lost */
- }
- if (nack(winlo) < 0) {
- debug(F101,"input sent too many naks","",winlo);
- errpkt((CHAR *)"Too many retries.");
- type = 'E';
- break;
- } else continue;
- }
- if (rsn == winlo) { /* Got the packet we want, done. */
-#ifdef CK_TIMERS
- if (rttflg && timint) /* Dynamic round trip timers? */
- getrtt(nakstate, rsn); /* yes, do it. */
- else /* JHD 20100208 */
- rcvtimo = timint; /* JHD 20100208 */
-#endif /* CK_TIMERS */
- debug(F101,"input rsn=winlo","",rsn);
- break;
- }
-
- /* Got a packet out of order. */
-
- debug(F101,"input out of sequence, rsn","",rsn);
- k = rseqtbl[rsn]; /* Get window slot of this packet. */
- debug(F101,"input rseqtbl[rsn]","",k);
- if (k < 0) {
- debug(F101,"input recv can't find index for rcvd pkt","",rsn);
- /* Was "Internal error 21" */
- /* This should not happen */
- errpkt((CHAR *)"Sliding windows protocol error.");
- type = 'E';
- break;
- }
- y = chkwin(rsn,winlo,wslots); /* See what window it's in. */
- debug(F101,"input recv chkwin","",y);
- if (y == 1) { /* From previous window. */
-#ifdef STREAMING
- if (!streaming) /* NO RESEND IF STREAMING! */
-#endif /* STREAMING */
- resend(rsn); /* Resend the ACK (might have data) */
- freerpkt(rsn); /* Get rid of received packet */
- continue; /* Back to wait for another packet */
- } else { /* In this window or out of range */
- if (y < 0) /* If out of range entirely, */
- freerpkt(rsn); /* release its buffer */
-
-#ifdef STREAMING
- if (streaming) { /* Streaming (this shouldn't happen) */
- errpkt((CHAR *)"Sequence error on reliable link.");
- type = 'E';
- break;
- }
-#endif /* STREAMING */
-
-/* If our receive window is full, NAK window-low */
-
- if (rbufnum < 1) { /* Receive window full? */
- if (nack(winlo) < 0) { /* No choice, must NAK winlo. */
- errpkt((CHAR *)"Too many retries."); /* Too many */
- type = 'E';
- break;
- } else continue;
- }
-/*
- Receive window not full. This is a packet in the current window but it is
- not the desired packet at winlo. So therefore there are gaps before this
- packet. So we find the "lowest" unNAK'd missing packet, if any, between
- winlo and this one, and NAK it. If there are no as-yet-unNAK'd missing
- packets in the window, then we send nothing and go wait for another packet.
- In theory, this could result in a timeout, but in practice it is likely that
- the already-NAK'd missing packets are already on their way. Note, we do not
- NAK ahead of ourselves, as that only creates unnecessary retransmissions.
-*/
- for (x = winlo; x != rsn; x = (x + 1) % 64) {
- if (rseqtbl[x] > -1) /* Have I received packet x? */
- continue; /* Yes, check next sequence number. */
- pi = sseqtbl[x]; /* No, have I NAK'd it yet? */
- if (pi < 0 || s_pkt[pi].pk_rtr == 0) {
- nack(x); /* No, NAK it now. */
- break;
- }
- }
- }
-/*!!!*/
- } else { /* Otherwise file sender... */
-
-#ifdef STREAMING
- if (streaming && sndtyp == 'D') {
- debug(F101,"STREAMING input streaming","",streaming);
- debug(F000,"STREAMING input sndtyp","",sndtyp);
- rsn = winlo;
- type = 'Y'; /* Pretend we got an ACK */
- }
-#endif /* STREAMING */
- if (!nak2ack) { /* NAK(n+1) = ACK(n) */
- if (wslots > 1) { /* Packet at winlo already ACK'd? */
- if (sacktbl[winlo]) { /* If so, */
- sacktbl[winlo] = 0; /* Turn off the ACK'd flag */
- winlo = (winlo + 1) % 64; /* Rotate the window */
- type = 'Y'; /* And return ACK */
- debug(F101,
- "input send returning pre-stashed ACK","",
- winlo-1);
- break;
- }
- }
-#ifdef STREAMING
- if (!(streaming && sndtyp == 'D')) { /* Not streaming | data */
- type = rpack(); /* Try to read an acknowledgement */
- } else { /* Streaming and in Data phase */
- type = 'Y'; /* Assume all is normal */
- if (chkint() < 0) /* Check for console interrupts. */
- type = 'z';
- else if (ttchk() > 4 + bctu) /* Check for return traffic */
- type = rpack();
- debug(F000,"input streaming type","",type);
- }
-#endif /* STREAMING */
- debug(F111,"input send",(char *) rdatap,(int) type);
- while (type == 'e') { /* Handle echoes */
- debug(F000,"echo discarded","",type);
- type = rpack();
- }
-#ifndef OLDCHKINT
- if (type == 'z') {
- epktrcvd = 1;
- errpkt((CHAR *)"User cancelled.");
- type = 'E';
- break;
- }
-#endif /* OLDCHKINT */
- if (type < -1) {
- xxscreen(SCR_PT,'q',0L,
- ((char *)((type == -2) ?
- "Interrupted" :
- "Connection lost"))
- );
- if (type != -2)
- dologend();
- return('q'); /* Ctrl-C or connection lost */
- }
- if (type == -1) {
-#ifdef COMMENT
- char foo[256];
- ckmakxmsg(foo,256,
- "Receive window full (error 18): wslots=",
- ckitoa(wslots),
- " winlo=",ckitoa(winlo)," pktnum=",
- ckitoa(pktnum), NULL,NULL,NULL,NULL,NULL,NULL);
- errpkt((CHAR *)foo);
- debug(F100,foo,"",0);
-#else
- errpkt((CHAR *)"Receive window full"); /* was "internal */
- debug(F101," wslots","",wslots); /* error 18" */
- debug(F101," winlo","",winlo);
- debug(F101," pktnum","",pktnum);
-#endif /* COMMENT */
- dumprbuf();
- type = 'E';
- break;
- }
- dumprbuf(); /* Debugging */
-
-#ifdef OLDCHKINT
- if (chkint() < 0) { /* Check for console interrupts. */
- errpkt((CHAR *)"User cancelled.");
- return(type = 'E');
- }
-#endif /* OLDCHKINT */
-
- /* Got a packet */
-
-#ifdef STREAMING
- if (streaming) { /* Streaming */
- if (type == 'Q' || type == 'T') { /* Errors are fatal. */
- crunched++; /* For statistics */
- errpkt((CHAR *)"Transmission error on reliable link.");
- type = 'E';
- }
- }
-#endif /* STREAMING */
- if (type == 'E') {
- debug(F101,"input send got E, nakstate","",nakstate);
- break; /* Error packet */
- }
- if (type == 'Q') { /* Crunched packet */
- crunched++; /* For statistics */
- numerrs++; /* For packet resizing */
- x = resend(winlo); /* Resend window-low */
- if (x < 0) {
- type = 'E';
- errpkt((CHAR *)"Too many retries");
- break;
- }
- continue;
- }
- if (type == 'T') { /* Timeout waiting for ACKs. */
- timeouts++; /* Count it */
- numerrs++; /* Count an error too */
- debug(F101,"input send state timeout, winlo","",winlo);
-
- /* Retransmit the oldest un-ACK'd packet. */
-
- debug(F101,"input send resending winlo","",winlo);
- if (resend(winlo) < 0) { /* Check retries */
- debug(F101,"input send too many resends","",maxtry);
- errpkt((CHAR *)"Too many retries");
- return(type = 'E');
- }
-#ifdef NEWDPL
- /* Reduce prevailing packet length */
- x = sseqtbl[winlo]; /* Get length of packet we want ACKd */
- if (x > -1) { /* Only if we have a valid index */
- if (s_pkt[x].pk_typ == 'D') { /* only for D packets */
- spsiz = (s_pkt[x].pk_len + 8) >> 1; /* halve it */
- if (spsiz < 20) spsiz = 20; /* within reason */
- debug(F101,"input T cut packet length","",spsiz);
- }
- }
-#endif /* NEWDPL */
- continue;
- }
- }
- /* Got an actual normal packet */
-
- nak2ack = 0; /* Unset this flag. */
- y = chkwin(rsn,winlo,wslots); /* Is it in the window? */
- debug(F101,"input send rsn","",rsn);
- debug(F101,"input send winlo","",winlo);
- debug(F101,"input send chkwin","",y);
-
- if (type == 'Y') { /* Got an ACK */
- if (y == 0) { /* In current window */
- if (spackets < 4) /* Error counter doesn't count */
- numerrs = 0; /* until data phase. */
- sacktbl[rsn]++; /* Mark the packet as ACK'd */
- x = sseqtbl[rsn]; /* Get ACK'd packet's buffer index */
- debug(F101,"bestlen ack x","",x);
-#ifdef NEWDPL
- if (x > -1) {
- acktype = s_pkt[x].pk_typ; /* Get type */
- debug(F000,"bestlen ack type","",acktype);
-
- if (acktype == 'D') { /* Adjust data packet length */
- if (spsiz > bestlen) {
- bestlen = spsiz;
- debug(F101,"bestlen B","",bestlen);
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"bestlen retry","",s_pkt[x].pk_rtr);
- debug(F101,"bestlen len","",s_pkt[x].pk_len);
- debug(F101,"bestlen spackets","",spackets);
- }
-#endif /* DEBUG */
- /* Set new best length */
- if (s_pkt[x].pk_rtr == 0 &&
- s_pkt[x].pk_len + 8 > bestlen) {
- bestlen = s_pkt[x].pk_len + 8;
- if (bestlen > spmax)
- bestlen = spmax;
- debug(F101,"bestlen A","",bestlen);
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"bestlen wslots","",wslots);
- debug(F101,"bestlen maxsend","",maxsend);
- }
-#endif /* DEBUG */
- /* Slow start */
- if (slostart &&
- (maxsend <= spmax) &&
- (rpackets < 11) &&
- (numerrs == 0)) {
- spsiz = spsiz << 1;
- debug(F101,"bestlen spsiz A","",spsiz);
-
- /* Creep up to best length */
- } else if ((spackets > 5) &&
- (spsiz < bestlen - 8)) {
- spsiz += (bestlen - spsiz) / 3;
- debug(F101,"bestlen spsiz B","",spsiz);
-
- /* Push the envelope */
- } else if ((spackets % (wslots + 1) == 0) &&
- (spackets > 6) &&
- (bestlen < spmax - 8) &&
- (spsiz < spmax)) {
- spsiz += (spmax - bestlen) / 3;
- debug(F101,"bestlen spsiz C","",spsiz);
- }
- /* But not too far */
- if (spsiz > spmax) {
- spsiz = spmax;
- debug(F101,"bestlen spsiz D","",spsiz);
- }
- }
- }
-#endif /* NEWDPL */
-
-#ifdef CK_TIMERS
- if (rttflg && timint) /* If doing dynamic timers */
- getrtt(nakstate, rsn); /* call routine to set it. */
- else /* JHD 20100208 */
- rcvtimo = timint; /* JHD 20100208 */
-#endif /* CK_TIMERS */
-/*
- NOTE: The following statement frees the buffer of the ACK we just got.
- But the upper layers still need the data, like if it's the ACK to an I,
- S, F, D, Z, or just about any kind of packet. So for now, freerbuf()
- deallocates the buffer, but does not erase the data or destroy the pointer
- to it. There's no other single place where these receive buffers can be
- correctly freed (?) ...
-*/
- freerpkt(rsn); /* Free the ACK's buffer */
- freesbuf(rsn); /* *** Free the sent packet's buffer */
- if (rsn == winlo) { /* Got the one we want */
- sacktbl[winlo] = 0;
- winlo = (winlo + 1) % 64;
- debug(F101,"input send rotated send window","",winlo);
- break; /* Return the ACK */
- } else {
- debug(F101,"input send mark pkt","",rsn);
- continue; /* Otherwise go read another packet */
- }
- } else if (y == 1 && wslots < 2) { /* (190) ACK for previous */
- numerrs++; /* == NAK for current, count error */
- debug(F101,"input send ACK for previous","",rsn);
- freerpkt(rsn); /* Free NAK's buffer */
- x = resend(winlo); /* Resend current packet */
- if (x < 0) {
- type = 'E';
- errpkt((CHAR *)"Too many retries");
- break;
- } else continue; /* Resend ok, go read another packet */
- } else { /* Other cases, just ignore */
- debug(F101,"input send ACK out of window","",rsn);
- freerpkt(rsn);
- continue;
- }
- }
- if (type == 'N') { /* NAK */
- numerrs++; /* Count an error */
-#ifdef STREAMING
- if (streaming) { /* Streaming */
- errpkt((CHAR *)"NAK received on reliable link.");
- type = 'E';
- break;
- }
-#endif /* STREAMING */
-
- debug(F101,"input send NAK","",rsn);
-#ifdef NEWDPL
- /* Reduce prevailing packet length */
- x = sseqtbl[rsn]; /* Length of packet that was NAK'd */
- if (x > -1) { /* If it's a Data packet we've sent */
- if (s_pkt[x].pk_typ == 'D') {
- spsiz = (s_pkt[x].pk_len + 8) >> 1; /* Halve length */
-#ifdef COMMENT
- /* This might be a good idea -- haven't tried it ... */
- if (bestlen > 0 && spsiz > bestlen)
- spsiz = bestlen;
-#endif /* COMMENT */
- if (spsiz < 20) spsiz = 20;
- debug(F101,"input N cut packet length","",spsiz);
- }
- }
-#endif /* NEWDPL */
- freerpkt(rsn); /* Free buffer where NAK lies. */
- if (y == 0) { /* In current window */
- debug(F100," in window","",0);
- k = sseqtbl[rsn]; /* Get pointer to NAK'd packet. */
- if (k < 0 || (k > -1 && s_pkt[k].pk_typ == ' ')) {
- x = resend(winlo); /* Packet we haven't sent yet. */
- } else {
- x = resend(rsn); /* Resend requested packet. */
- }
- if (x < 0) { /* Resend error is fatal. */
- type = 'E';
- errpkt((CHAR *)"Too many retries");
- break;
- } else continue; /* Resend ok, go read another packet */
- } else if ((rsn == (pktnum + 1) % 64)) { /* NAK for next pkt */
- if (wslots > 1) {
- debug( F101,"NAK for next packet, windowing","",rsn);
- x = resend(winlo); /* Resend window-low */
- if (x < 0) {
- type = 'E';
- errpkt((CHAR *)"Too many retries");
- break;
- }
- continue; /* Go back and read another pkt */
- }
- debug(F101,"NAK for next packet, no windowing","",rsn);
- x = (rsn == 0) ? 63 : rsn - 1;
- if (x == 0 && (sndtyp == 'S' || sndtyp == 'I')) {
- resend(0); /* ACK for S or I packet missing */
- continue; /* so resend the S or I */
- }
- rsn = x; /* Else, treat NAK(n+1) as ACK(n) */
- nak2ack = 1; /* Go back and process the ACK */
- continue;
- } else if (y > 0) { /* NAK for pkt we can't resend */
- debug(F101," NAK out of window","",rsn); /* bad... */
- type = 'E';
- errpkt((CHAR *)"NAK out of window");
- break;
- } else continue; /* Ignore other NAKs */
- } /* End of file-sender NAK handler */
-
- if (rsn == winlo) { /* Not ACK, NAK, timeout, etc. */
- debug(F000,"input send unexpected type","",type);
- break;
- }
- } /* End of file-sender section */
- } /* End of input() while() loop */
-/*
- When the window size is 1 and we have the packet we want, there can not
- possibly be anything waiting for us on the connection that is useful to us.
- However, there might be redundant copies of a packet we already got, which
- would cause needless cycles of repeated packets. Therefore we flush the
- communications input buffer now to try to get rid of undesired and unneeded
- packets that we have not read yet.
-
- Actually, the first sentence above is not entirely true: there could be an
- Error packet waiting to be read. Flushing an E packet is bad because it
- will not be resent, and we'll go into a cycle of timing out and
- retransmitting up to the retry limit. - fdc 2007/03/02
-*/
- if (wslotn == 1 /* (not wslots!) */
-#ifdef STREAMING
- && !streaming /* But not when streaming */
-#endif /* STREAMING */
- ) {
- debug(F100,"input about to flush","",0);
- ttflui(); /* Got what we want, clear input buffer. */
- }
-#ifndef NEWDPL
- if (!nakstate) /* When sending */
- rcalcpsz(); /* recalculate size every packet */
-#endif /* NEWDPL */
- if (type == 'E')
- xitsta |= (what ? what : 1); /* Remember what failed. */
- debug(F101,"input winlo","",winlo);
- debug(F101,"input rsn","",rsn);
- debug(F000,"input returning type","",type);
- return(rcvtyp = type); /* Success, return packet type. */
-}
-
-#ifdef PARSENSE
-/* P A R C H K -- Check if Kermit packet has parity */
-
-/*
- Call with s = pointer to packet, start = packet start character, n = length.
- Returns 0 if packet has no parity, -1 on error, or, if packet has parity:
- 'e' for even, 'o' for odd, 'm' for mark. Space parity cannot be sensed.
- So a return value of 0 really means either space or none.
- Returns -2 if parity has already been checked during this protocol operation.
-*/
-int
-#ifdef CK_ANSIC
-parchk(CHAR *s, CHAR start, int n)
-#else
-parchk(s,start,n) CHAR *s, start; int n;
-#endif /* CK_ANSIC */
-/* parchk */ {
- CHAR s0, s1, s2, s3;
-
- debug(F101,"parchk n","",n);
- debug(F101,"parchk start","",start);
-
- s0 = s[0] & 0x7f; /* Mark field (usually Ctrl-A) */
-
- if (s0 != start || n < 5) return(-1); /* Not a valid packet */
-
-/* Look at packet control fields, which never have 8th bit set */
-/* First check for no parity, most common case. */
-
- if (((s[0] | s[1] | s[2] | s[3]) & 0x80) == 0)
- return(0); /* No parity or space parity */
-
-/* Check for mark parity */
-
- if (((s[0] & s[1] & s[2] & s[3]) & 0x80) == 0x80)
- return('m'); /* Mark parity */
-
-/* Packet has some kind of parity */
-/* Make 7-bit copies of control fields */
-
- s1 = s[1] & 0x7f; /* LEN */
- s2 = s[2] & 0x7f; /* SEQ */
- s3 = s[3] & 0x7f; /* TYPE */
-
-/* Check for even parity */
-
- if ((s[0] == p_tbl[s0]) &&
- (s[1] == p_tbl[s1]) &&
- (s[2] == p_tbl[s2]) &&
- (s[3] == p_tbl[s3]))
- return('e');
-
-/* Check for odd parity */
-
- if ((s[0] != p_tbl[s0]) &&
- (s[1] != p_tbl[s1]) &&
- (s[2] != p_tbl[s2]) &&
- (s[3] != p_tbl[s3]))
- return('o');
-
-/* Otherwise it's probably line noise. Let checksum calculation catch it. */
-
- return(-1);
-}
-#endif /* PARSENSE */
-\f
-/*
- Check to make sure timeout intervals are long enough to allow maximum
- length packets to get through before the timer goes off. If not, the
- timeout interval is adjusted upwards.
-
- This routine is called at the beginning of a transaction, before we
- know anything about the delay characteristics of the line. It works
- only for serial communication devices; it trusts the speed reported by
- the operating system.
-
- Call with a timout interval. Returns it, adjusted if necessary.
-*/
-int
-chktimo(timo,flag) int timo, flag; {
- long cps, z; int x, y;
-#ifdef STREAMING
- debug(F101,"chktimo streaming","",streaming);
- if (streaming)
- return(0);
-#endif /* STREAMING */
-
- debug(F101,"chktimo timo","",timo); /* Timeout before adjustment */
- debug(F101,"chktimo flag","",flag);
-
- if (flag) /* Don't change timeout if user */
- return(timo); /* gave SET SEND TIMEOUT command. */
- debug(F101,"chktimo spmax","",spmax);
- debug(F101,"chktimo urpsiz","",urpsiz);
-
- if (!network) { /* On serial connections... */
- speed = ttgspd(); /* Get current speed. */
- if (speed > 0L) {
- cps = speed / 10L; /* Convert to chars per second */
- if (cps > 0L) {
- long plen; /* Maximum of send and rcv pkt size */
- z = cps * (long) timo; /* Chars per timeout interval */
- z -= z / 10L; /* Less 10 percent */
- plen = spmax;
- if (urpsiz > spmax) plen = urpsiz;
- debug(F101,"chktimo plen","",plen);
- if (z < plen) { /* Compare with packet size */
- x = (int) ((long) plen / cps); /* Adjust if necessary */
- y = x / 10; /* Add 10 percent for safety */
- if (y < 2) y = 2; /* Or 2 seconds, whichever is more */
- x += y;
- if (x > timo) /* If this is greater than current */
- timo = x; /* timeout, change the timeout */
- debug(F101,"chktimo new timo","",timo);
- }
- }
- }
- }
- return(timo);
-}
-\f
-/* S P A C K -- Construct and send a packet */
-
-/*
- spack() sends a packet of the given type, sequence number n, with len data
- characters pointed to by d, in either a regular or extended- length packet,
- depending on len. Returns the number of bytes actually sent, or else -1
- upon failure. Uses global npad, padch, mystch, bctu, data. Leaves packet
- fully built and null-terminated for later retransmission by resend().
- Updates global sndpktl (send-packet length).
-
- NOTE: The global pointer "data" is assumed to point into the 7th position
- of a character array (presumably in packet buffer for the current packet).
- It was used by getpkt() to build the packet data field. spack() fills in
- the header to the left of the data pointer (the data pointer is defined
- in getsbuf() in ckcfn3.c). If the address "d" is the same as "data", then
- the packet's data field has been built "in place" and need not be copied.
-*/
-int
-#ifdef CK_ANSIC
-spack(char pkttyp, int n, int len, CHAR *d)
-#else
-spack(pkttyp,n,len,d) char pkttyp; int n, len; CHAR *d;
-#endif /* CK_ANSIC */
-/* spack */ {
- register int i;
- int ix, j, k, x, lp, longpkt, copy, loglen;
-
-#ifdef GFTIMER
- CKFLOAT t1 = 0.0, t2 = 0.0;
-#endif /* GFTIMER */
-
- register CHAR *cp, *mydata;
- unsigned crc;
-
- copy = (d != data); /* Flag whether data must be copied */
-
-#ifdef DEBUG
- if (deblog) { /* Save lots of function calls! */
- debug(F101,"spack n","",n);
-#ifdef COMMENT
- if (pkttyp != 'D') { /* Data packets would be too long */
- debug(F111,"spack data",data,data);
- debug(F111,"spack d",d,d);
- }
-#endif /* COMMENT */
- debug(F101,"spack len","",len);
- debug(F101,"spack copy","",copy);
- }
-#endif /* DEBUG */
-
- longpkt = (len + bctl + 2) > 94; /* Decide whether it's a long packet */
- mydata = data - 7 + (longpkt ? 0 : 3); /* Starting position of header */
- k = sseqtbl[n]; /* Packet structure info for pkt n */
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) { /* Save 2 more function calls... */
- debug(F101,"spack mydata","",mydata);
- debug(F101,"spack sseqtbl[n]","",k);
- if (k < 0) {
-#ifdef STREAMING
- if (!streaming)
-#endif /* STREAMING */
- debug(F101,"spack sending packet out of window","",n);
- }
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- if (k > -1) {
- s_pkt[k].pk_adr = mydata; /* Remember address of packet. */
- s_pkt[k].pk_seq = n; /* Record sequence number */
- s_pkt[k].pk_typ = pkttyp; /* Record packet type */
- }
- spktl = 0; /* Initialize length of this packet */
- i = 0; /* and position in packet. */
-
-/* Now fill the packet */
-
- mydata[i++] = mystch; /* MARK */
- lp = i++; /* Position of LEN, fill in later */
-
- mydata[i++] = tochar(n); /* SEQ field */
- mydata[i++] = pkttyp; /* TYPE field */
- j = len + bctl; /* Length of data + block check */
- if (longpkt) { /* Long packet? */
- int x; /* Yes, work around SCO Xenix/286 */
-#ifdef CKTUNING
- unsigned int chk;
-#endif /* CKTUNING */
- x = j / 95; /* compiler bug... */
- mydata[lp] = tochar(0); /* Set LEN to zero */
- mydata[i++] = tochar(x); /* Extended length, high byte */
- mydata[i++] = tochar(j % 95); /* Extended length, low byte */
-#ifdef CKTUNING
- /* Header checksum - skip the function calls and loops */
- chk = (unsigned) mydata[lp] +
- (unsigned) mydata[lp+1] +
- (unsigned) mydata[lp+2] +
- (unsigned) mydata[lp+3] +
- (unsigned) mydata[lp+4] ;
- mydata[i++] = tochar((CHAR) ((((chk & 0300) >> 6) + chk) & 077));
-#else
- mydata[i] = '\0'; /* Terminate for header checksum */
- mydata[i++] = tochar(chk1(mydata+lp,5));
-#endif /* CKTUNING */
- } else mydata[lp] = tochar(j+2); /* Normal LEN */
-/*
- When sending a file, the data is already in the right place. If it weren't,
- it might make sense to optimize this section by using memcpy or bcopy
- (neither of which are portable), but only if our packets were rather long.
- When receiving, we're only sending ACKs so it doesn't matter. So count the
- following loop as a sleeping dog.
-*/
- if (copy) /* Data field built in place? */
- for ( ; len--; i++) mydata[i] = *d++; /* No, must copy. */
- else /* Otherwise, */
- i += len; /* Just skip past data field. */
- mydata[i] = '\0'; /* Null-terminate for checksum calc. */
-
- switch (bctu) { /* Block check */
- case 1: /* 1 = 6-bit chksum */
- ix = i - lp; /* Avoid "order of operation" error */
- mydata[i++] = tochar(chk1(mydata+lp,ix));
- break;
- case 2: /* 2 = 12-bit chksum */
- j = chk2(mydata+lp,i-lp);
- mydata[i++] = (unsigned)tochar((j >> 6) & 077);
- mydata[i++] = (unsigned)tochar(j & 077);
- break;
- case 3: /* 3 = 16-bit CRC */
- crc = chk3(mydata+lp,i-lp);
- mydata[i++] = (unsigned)tochar(((crc & 0170000)) >> 12);
- mydata[i++] = (unsigned)tochar((crc >> 6) & 077);
- mydata[i++] = (unsigned)tochar(crc & 077);
- break;
- case 4: /* 2 = 12-bit chksum, blank-free */
- j = chk2(mydata+lp,i-lp);
- mydata[i++] =
- (unsigned)(tochar((unsigned)(((j >> 6) & 077) + 1)));
- mydata[i++] = (unsigned)(tochar((unsigned)((j & 077) + 1)));
- break;
- }
- loglen = i;
- mydata[i++] = seol; /* End of line (packet terminator) */
-#ifdef TCPSOCKET
-/*
- If TELNET connection and packet terminator is carriage return,
- we must stuff either LF or NUL, according to SET TELNET NEWLINE-MODE
- (tn_nlm), to meet the TELNET NVT specification, unless user said RAW.
-
- If NEWLINE-MODE is set to LF instead of CR, we still send CR-NUL
- on a NVT connection and CR on a binary connection.
-*/
- if (
-#ifdef STREAMING
- !dontsend &&
-#endif /* STREAMING */
- ((network && ttnproto == NP_TELNET) || (!local && sstelnet))
- && seol == CR) {
- switch (TELOPT_ME(TELOPT_BINARY) ? tn_b_nlm : tn_nlm) {
- case TNL_CR: /* NVT or BINARY */
- break;
- case TNL_CRNUL:
- mydata[i++] = NUL;
- break;
- case TNL_CRLF:
- mydata[i++] = LF;
- break;
- }
- }
-#endif /* TCPSOCKET */
- mydata[i] = '\0'; /* Terminate string */
- if (
-#ifdef STREAMING
- !dontsend &&
-#endif /* STREAMING */
- pktlog
- ) /* Save a function call! */
- logpkt('s',n,mydata,loglen); /* Log the packet */
-
- /* (PWP) add the parity quickly at the end */
- if (parity) {
- switch (parity) {
- case 'e': /* Even */
- for (cp = &mydata[i-1]; cp >= mydata; cp--)
- *cp = p_tbl[*cp];
- break;
- case 'm': /* Mark */
- for (cp = &mydata[i-1]; cp >= mydata; cp--)
- *cp |= 128;
- break;
- case 'o': /* Odd */
- for (cp = &mydata[i-1]; cp >= mydata; cp--)
- *cp = p_tbl[*cp] ^ 128;
- break;
- case 's': /* Space */
- for (cp = &mydata[i-1]; cp >= mydata; cp--)
- *cp &= 127;
- break;
- }
- }
- if (pktpaus) msleep(pktpaus); /* Pause if requested */
- x = 0;
-
- if (npad) {
-#ifdef STREAMING
- if (dontsend)
- x = 0;
- else
-#endif /* STREAMING */
- x = ttol(padbuf,npad); /* Send any padding */
- }
- if (x > -1) {
-#ifdef CK_TIMERS
- if (timint > 0) {
- if (pkttyp == 'N')
- srttbl[n > 0 ? n-1 : 63] = gtimer();
- else
- srttbl[n] = gtimer();
- }
-#endif /* CK_TIMERS */
- spktl = i; /* Remember packet length */
- if (k > -1)
- s_pkt[k].pk_len = spktl; /* also in packet info structure */
-
-#ifdef DEBUG
-#ifdef GFTIMER
-/*
- This code shows (in the debug log) how long it takes write() to execute.
- Sometimes on a congested TCP connection, it can surprise you -- 90 seconds
- or more...
-*/
- if (
-#ifdef STREAMING
- !dontsend &&
-#endif /* STREAMING */
- deblog
- )
- t1 = gftimer();
-#endif /* GFTIMER */
-#endif /* DEBUG */
-
-#ifdef STREAMING
- if (dontsend) {
- debug(F000,"STREAMING spack skipping","",pkttyp);
- x = 0;
- } else
-#endif /* STREAMING */
- x = ttol(mydata,spktl); /* Send the packet */
- }
-#ifdef STREAMING
- if (!dontsend) {
-#endif /* STREAMING */
- debug(F101,"spack spktl","",spktl);
- debug(F101,"spack ttol returns","",x);
- if (x < 0) { /* Failed. */
- if (local && x < -1) {
- xxscreen(SCR_ST,ST_ERR,0L,"FAILED: Connection lost");
- /* We can't send an E packet because the connection is lost. */
- epktsent = 1; /* So pretend we sent one. */
- fatalio = 1; /* Remember we got a fatal i/o error */
- dologend();
- ckstrncpy((char *)epktmsg,"Connection lost",PKTMSGLEN);
- }
- return(x);
- }
- if (spktl > maxsend) /* Keep track of longest packet sent */
- maxsend = spktl;
-#ifdef DEBUG
-#ifdef GFTIMER
- if (deblog) { /* Log elapsed time for write() */
- t2 = gftimer();
- debug(F101,"spack ttol msec","",(long)((t2-t1)*1000.0));
- }
-#endif /* GFTIMER */
-#endif /* DEBUG */
-#ifdef STREAMING
- }
-#endif /* STREAMING */
-
- sndtyp = pkttyp; /* Remember packet type for echos */
-#ifdef STREAMING
- if (!dontsend) { /* If really sent, */
- spackets++; /* count it. */
- flco += spktl; /* Count the characters */
- tlco += spktl; /* for statistics... */
-#ifdef DEBUG
- if (deblog) { /* Save two function calls! */
- dumpsbuf(); /* Dump send buffers to debug log */
- debug(F111,"spack calling screen, mydata=",mydata,n);
- }
-#endif /* DEBUG */
- }
-#endif /* STREAMING */
- if (local) {
- int x = 0;
- if (fdispla != XYFD_N) x = 1;
- if ((fdispla == XYFD_B) && (pkttyp == 'D' || pkttyp == 'Y')) x = 0;
- if (x)
- xxscreen(SCR_PT,pkttyp,(long)n,(char *)mydata); /* Update screen */
- }
- return(spktl); /* Return length */
-}
-
-/* C H K 1 -- Compute a type-1 Kermit 6-bit checksum. */
-
-int
-chk1(pkt,len) register CHAR *pkt; register int len; {
- register unsigned int chk;
-#ifdef CKTUNING
-#ifdef COMMENT
- register unsigned int m; /* Avoid function call */
- m = (parity) ? 0177 : 0377;
- for (chk = 0; len-- > 0; pkt++)
- chk += *pkt & m;
-#else
- chk = 0;
- while (len-- > 0) chk += (unsigned) *pkt++;
-#endif /* COMMENT */
-#else
- chk = chk2(pkt,len);
-#endif /* CKTUNING */
- chk = (((chk & 0300) >> 6) + chk) & 077;
- debug(F101,"chk1","",chk);
- return((int) chk);
-}
-
-/* C H K 2 -- Compute the numeric sum of all the bytes in the packet. */
-
-unsigned int
-chk2(pkt,len) register CHAR *pkt; register int len; {
- register long chk;
-#ifdef COMMENT
- register unsigned int m;
- m = (parity) ? 0177 : 0377;
- for (chk = 0; len-- > 0; pkt++)
- chk += *pkt & m;
-#else
- /* Parity has already been stripped */
- chk = 0L;
- while (len-- > 0) chk += (unsigned) *pkt++;
-#endif /* COMMENT */
- debug(F101,"chk2","",(unsigned int) (chk & 07777));
- return((unsigned int) (chk & 07777));
-}
-
-/* C H K 3 -- Compute a type-3 Kermit block check. */
-/*
- Calculate the 16-bit CRC-CCITT of a null-terminated string using a lookup
- table. Assumes the argument string contains no embedded nulls.
-*/
-#ifdef COMMENT
-unsigned int
-chk3(pkt,parity,len) register CHAR *pkt; int parity; register int len; {
- register long c, crc;
- register unsigned int m;
- m = (parity) ? 0177 : 0377;
- for (crc = 0; len-- > 0; pkt++) {
- c = crc ^ (long)(*pkt & m);
- crc = (crc >> 8) ^ (crcta[(c & 0xF0) >> 4] ^ crctb[c & 0x0F]);
- }
- return((unsigned int) (crc & 0xFFFF));
-}
-#else
-unsigned int
-chk3(pkt,len) register CHAR *pkt; register int len; {
- register long c, crc;
- for (crc = 0; len-- > 0; pkt++) {
- c = crc ^ (long)(*pkt);
- crc = (crc >> 8) ^ (crcta[(c & 0xF0) >> 4] ^ crctb[c & 0x0F]);
- }
- debug(F101,"chk3","",(unsigned int) (crc & 0xFFFF));
- return((unsigned int) (crc & 0xFFFF));
-}
-#endif /* COMMENT */
-
-/* N X T P K T -- Next Packet */
-/*
- Get packet number of next packet to send and allocate a buffer for it.
- Returns:
- 0 on success, with global pktnum set to the packet number;
- -1 on failure to allocate buffer (fatal);
- -2 if resulting packet number is outside the current window.
-*/
-int
-nxtpkt() { /* Called by file sender */
- int j, n, x;
-
- debug(F101,"nxtpkt pktnum","",pktnum);
- debug(F101,"nxtpkt winlo ","",winlo);
- n = (pktnum + 1) % 64; /* Increment packet number mod 64 */
- debug(F101,"nxtpkt n","",n);
-#ifdef STREAMING
- if (!streaming) {
- x = chkwin(n,winlo,wslots); /* Don't exceed window boundary */
- debug(F101,"nxtpkt chkwin","",x);
- if (x)
- return(-2);
- j = getsbuf(n); /* Get a buffer for packet n */
- if (j < 0) {
- debug(F101,"nxtpkt getsbuf failure","",j);
- return(-1);
- }
- }
-#endif /* STREAMING */
- pktnum = n;
- return(0);
-}
-
-/* Functions for sending ACKs and NAKs */
-
-/* Note, we should only ACK the packet at window-low (winlo) */
-/* However, if an old packet arrives again (e.g. because the ACK we sent */
-/* earlier was lost), we ACK it again. */
-
-int
-ack() { /* Acknowledge the current packet. */
- return(ackns(winlo,(CHAR *)""));
-}
-
-#ifdef STREAMING
-int
-fastack() { /* Acknowledge packet n */
- int j, k, n, x;
- n = winlo;
-
- k = rseqtbl[n]; /* First find received packet n. */
- debug(F101,"STREAMING fastack k","",k);
- freesbuf(n); /* Free current send-buffer, if any */
- if ((j = getsbuf(n)) < 0) {
- /* This can happen if we have to re-ACK an old packet that has */
- /* already left the window. It does no harm. */
- debug(F101,"STREAMING fastack can't getsbuf","",n);
- }
- dontsend = 1;
- x = spack('Y',n,0,(CHAR *)""); /* Now send it (but not really) */
- dontsend = 0;
- if (x < 0) return(x);
- debug(F101,"STREAMING fastack x","",x);
- if (k > -1)
- freerbuf(k); /* don't need it any more */
- if (j > -1)
- freesbuf(j); /* and don't need to keep ACK either */
- winlo = (winlo + 1) % 64;
- return(0);
-}
-#endif /* STREAMING */
-
-int
-ackns(n,s) int n; CHAR *s; { /* Acknowledge packet n */
- int j, k, x;
- debug(F111,"ackns",s,n);
-
- k = rseqtbl[n]; /* First find received packet n. */
- debug(F101,"ackns k","",k);
- freesbuf(n); /* Free current send-buffer, if any */
- if ((j = getsbuf(n)) < 0) {
- /* This can happen if we have to re-ACK an old packet that has */
- /* already left the window. It does no harm. */
- debug(F101,"ackns can't getsbuf","",n);
- }
- x = spack('Y',n,(int)strlen((char *)s),s); /* Now send it. */
- if (x < 0) return(x);
- debug(F101,"ackns winlo","",winlo);
- debug(F101,"ackns n","",n);
- if (n == winlo) { /* If we're acking winlo */
- if (k > -1)
- freerbuf(k); /* don't need it any more */
- if (j > -1)
- freesbuf(j); /* and don't need to keep ACK either */
- winlo = (winlo + 1) % 64;
- }
- return(0);
-}
-
-int
-ackn(n) int n; { /* Send ACK for packet number n */
- return(ackns(n,(CHAR *)""));
-}
-
-int
-ack1(s) CHAR *s; { /* Send an ACK with data. */
- if (!s) s = (CHAR *)"";
- debug(F110,"ack1",(char *)s,0);
- return(ackns(winlo,s));
-}
-
-/* N A C K -- Send a Negative ACKnowledgment. */
-/*
- Call with the packet number, n, to be NAK'd.
- Returns -1 if that packet has been NAK'd too many times, otherwise 0.
- Btw, it is not right to return 0 under error conditions. This is
- done because the -1 code is used for cancelling the file transfer.
- More work is needed here.
-*/
-int
-nack(n) int n; {
- int i, x;
-
- if (n < 0 || n > 63) {
- debug(F101,"nack bad pkt num","",n);
- return(0);
- } else debug(F101,"nack","",n);
- if ((i = sseqtbl[n]) < 0) { /* If necessary */
- if (getsbuf(n) < 0) { /* get a buffer for this NAK */
- debug(F101,"nack can't getsbuf","",n);
- return(0);
- } else i = sseqtbl[n]; /* New slot number */
- }
- if (maxtry > 0 && s_pkt[i].pk_rtr++ > maxtry) /* How many? */
- return(-1); /* Too many... */
-
-/* Note, don't free this buffer. Eventually an ACK will come, and that */
-/* will set it free. If not, well, it's back to ground zero anyway... */
-
- x = spack('N',n,0,(CHAR *) ""); /* NAKs never have data. */
- return(x);
-}
-
-#ifndef NEWDPL /* This routine no longer used */
-/*
- * (PWP) recalculate the optimal packet length in the face of errors.
- * This is a modified version of the algorithm by John Chandler in Kermit/370,
- * see "Dynamic Packet Size Control", Kermit News, V2 #1, June 1988.
- *
- * This implementation minimizes the total overhead equation, which is
- *
- * Total chars = file_chars + (header_len * num_packs)
- * + (errors * (header_len + packet_len))
- *
- * Differentiate with respect to number of chars, solve for packet_len, get:
- *
- * packet_len = sqrt (file_chars * header_len / errors)
- */
-
-/*
- (FDC) New super-simple algorithm. If there was an error in the most recent
- packet exchange, cut the send-packet size in half, down to a minimum of 20.
- If there was no error, increase the size by 5/4, up to the maximum negotiated
- length. Seems to be much more responsive than previous algorithm, which took
- forever to recover the original packet length, and it also went crazy under
- certain conditions.
-
- Here's another idea for packet length resizing that keeps a history of the
- last n packets. Push a 1 into the left end of an n-bit shift register if the
- current packet is good, otherwise push a zero. The current n-bit value, w, of
- this register is a weighted sum of the noise hits for the last n packets, with
- the most recent weighing the most. The current packet length is some function
- of w and the negotiated packet length, like:
-
- (2^n - w) / (2^n) * (negotiated length)
-
- If the present resizing method causes problems, think about this one a little
- more.
-*/
-VOID
-rcalcpsz() {
-
-#ifdef COMMENT
-/* Old way */
- register long x, q;
- if (numerrs == 0) return; /* bounds check just in case */
-
- /* overhead on a data packet is npad+5+bctr, plus 3 if extended packet */
- /* an ACK is 5+bctr */
-
- /* first set x = per packet overhead */
- if (wslots > 1) /* Sliding windows */
- x = (long) (npad+5+bctr); /* packet only, don't count ack */
- else /* Stop-n-wait */
- x = (long) (npad+5+3+bctr+5+bctr); /* count packet and ack. */
-
- /* then set x = packet length ** 2 */
- x = x * ( ffc / (CK_OFF_T) numerrs); /* careful of overflow */
-
- /* calculate the long integer sqrt(x) quickly */
- q = 500;
- q = (q + x/q) >> 1;
- q = (q + x/q) >> 1;
- q = (q + x/q) >> 1;
- q = (q + x/q) >> 1; /* should converge in about 4 steps */
- if ((q > 94) && (q < 130)) /* break-even point for long packets */
- q = 94;
- if (q > spmax) q = spmax; /* maximum bounds */
- if (q < 10) q = 10; /* minimum bounds */
- spsiz = q; /* set new send packet size */
- debug(F101,"rcalcpsiz","",q);
-#else
-/* New way */
- debug(F101,"rcalcpsiz numerrs","",numerrs);
- debug(F101,"rcalcpsiz spsiz","",spsiz);
- if (spackets < 3) {
- numerrs = 0;
- return;
- }
- if (numerrs)
- spsiz = spsiz / 2;
- else
- spsiz = (spsiz / 4) * 5;
- if (spsiz < 20) spsiz = 20;
- if (spsiz > spmax) spsiz = spmax;
- debug(F101,"rcalcpsiz new spsiz","",spsiz);
- numerrs = 0;
-#endif /* COMMENT */
-}
-#endif /* NEWDPL */
-
-/* R E S E N D -- Retransmit packet n. */
-
-/*
- Returns 0 or positive on success (the number of retries for packet n).
- On failure, returns a negative number, and an error message is placed
- in recpkt.
-*/
-int
-resend(n) int n; { /* Send packet n again. */
- int j, k, x;
-#ifdef GFTIMER
- CKFLOAT t1 = 0.0, t2 = 0.0;
-#endif /* GFTIMER */
-
- debug(F101,"resend seq","",n);
-
- k = chkwin(n,winlo,wslots); /* See if packet in current window */
- j = -1; /* Assume it's lost */
- if (k == 0) j = sseqtbl[n]; /* See if we still have a copy of it */
- if (k != 0 || j < 0) { /* If not.... */
- if (nakstate && k == 1) {
-/*
- Packet n is in the previous window and we are the file receiver.
- We already sent the ACK and deallocated its buffer so we can't just
- retransmit the ACK. Rather than give up, we try some tricks...
-*/
- if (n == 0 && spackets < 63 && myinit[0]) { /* ACK to Send-Init */
-/*
- If the packet number is 0, and we're at the beginning of a protocol
- operation (spackets < 63), then we have to resend the ACK to an I or S
- packet, complete with parameters in the data field. So we take a chance and
- send a copy of the parameters in an ACK packet with block check type 1.
- (Or 3 if SET BLOCK 5.)
-*/
- if (bctf) { /* Force Type 3 on all packets? */
- x = spack('Y',0,(int)strlen((char *)myinit),(CHAR *)myinit);
- if (x < 0) return(x);
- logpkt('#',n,(CHAR *)"<reconstructed>",0); /* Log it */
- } else { /* Regular Kermit protocol */
- int bctlsav; /* Temporary storage */
- int bctusav;
- bctlsav = bctl; /* Save current block check length */
- bctusav = bctu; /* and type */
- bctu = bctl = 1; /* Set block check to 1 */
- x = spack('Y',0,(int)strlen((char *)myinit),(CHAR *)myinit);
- if (x < 0) return(x);
- logpkt('#',n,(CHAR *)"<reconstructed>",0); /* Log it */
- bctu = bctusav; /* Restore block check type */
- bctl = bctlsav; /* and length */
- }
- } else { /* Not the first packet */
-/*
- It's not the first packet of the protocol operation. It's some other packet
- that we have already ACK'd and forgotten about. So we take a chance and
- send an empty ACK using the current block-check type. Usually this will
- work out OK (like when acking Data packets), and no great harm will be done
- if it was some other kind of packet (F, etc). If we are requesting an
- interruption of the file transfer, the flags are still set, so we'll catch
- up on the next packet.
-*/
- x = spack('Y',n,0,(CHAR *) "");
- if (x < 0) return(x);
- }
- retrans++;
- xxscreen(SCR_PT,'%',(long)pktnum,"Retransmission");
- return(0);
- } else {
-/*
- Packet number is not in current or previous window. We seem to hit this
- code occasionally at the beginning of a transaction, for apparently no good
- reason. Let's just log it for debugging, send nothing, and try to proceed
- with the protocol rather than killing it.
-*/
- debug(F101,"resend PKT NOT IN WINDOW","",n);
- debug(F101,"resend k","",k);
- return(0);
- }
- }
-
-/* OK, it's in the window and it's not lost. */
-
- debug(F101,"resend pktinfo index","",k);
-
- if (maxtry > 0 && s_pkt[j].pk_rtr++ > maxtry) { /* Over retry limit */
- xitsta |= what;
- return(-1);
- }
- debug(F101,"resend retry","",s_pkt[j].pk_rtr); /* OK so far */
- dumpsbuf(); /* (debugging) */
- if (s_pkt[j].pk_typ == ' ') { /* Incompletely formed packet */
- if (nakstate) { /* (This shouldn't happen any more) */
- nack(n);
- retrans++;
- xxscreen(SCR_PT,'%',(long)pktnum,"(resend)");
- return(s_pkt[j].pk_rtr);
- } else { /* No packet to resend! */
-#ifdef COMMENT
-/*
- This happened (once) while sending a file with 2 window slots and typing
- X to the sender to cancel the file. But since we're cancelling anyway,
- there's no need to give a scary message.
-*/
- sprintf((char *)epktmsg,
- "resend logic error: NPS, n=%d, j=%d.",n,j);
- return(-2);
-#else
-/* Just ignore it. */
- return(0);
-#endif /* COMMENT */
- }
- }
-#ifdef DEBUG
-#ifdef GFTIMER
- if (deblog) t1 = gftimer();
-#endif /* GFTIMER */
-#endif /* DEBUG */
-
- /* Everything ok, send the packet */
-#ifdef CK_TIMERS
- if (timint > 0)
- srttbl[n] = gtimer(); /* Update the timer */
-#endif /* CK_TIMERS */
- x = ttol(s_pkt[j].pk_adr,s_pkt[j].pk_len);
-
-#ifdef DEBUG
-#ifdef GFTIMER
- if (deblog) {
- t2 = gftimer();
- debug(F101,"resend ttol msec","",(long)((t2-t1)*1000.0));
- }
-#endif /* GFTIMER */
-#endif /* DEBUG */
- debug(F101,"resend ttol returns","",x);
-
- retrans++; /* Count a retransmission */
- xxscreen(SCR_PT,'%',(long)pktnum,"(resend)"); /* Tell user about resend */
- logpkt('S',n,s_pkt[j].pk_adr, s_pkt[j].pk_len); /* Log the resent packet */
- return(s_pkt[j].pk_rtr); /* Return the number of retries. */
-}
-
-/* E R R P K T -- Send an Error Packet */
-
-int
-errpkt(reason) CHAR *reason; { /* ...containing the reason given */
- extern int rtimo, state, justone;
- int x, y;
- czseen = 1; /* Also cancels batch */
- state = 0; /* Reset protocol state */
- debug(F110,"errpkt",reason,0);
- tlog(F110,"Protocol Error:",(char *)reason,0L);
- xxscreen(SCR_EM,0,0L,reason);
- encstr(reason);
- x = spack('E',pktnum,size,data);
- ckstrncpy((char *)epktmsg,(char *)reason,PKTMSGLEN);
- y = quiet; quiet = 1; epktsent = 1; /* Close files silently. */
- clsif(); clsof(1);
- quiet = y;
-/*
- I just sent an E-packet. I'm in local mode, I was receiving a file,
- I'm not a server, and sliding windows are in use. Therefore, there are
- likely to be a bunch of packets already "in the pipe" on their way to me
- by the time the remote sender gets the E-packet. So the next time I
- CONNECT or try to start another protocol operation, I am likely to become
- terribly confused by torrents of incoming material. To prevent this,
- the following code soaks up packets from the connection until there is an
- error or timeout, without wasting too much time waiting.
-
- Exactly the same problem occurs when I am in remote mode or if I am
- in server mode with the justone flag set. In remote mode not only
- does the packet data potentially get echo'd back to the sender which
- is confusing to the user in CONNECT mode, but it also may result in the
- host performing bizarre actions such as suspending the process if ^Z is
- unprefixed, etc.
-
- Furthermore, thousands of packets bytes in the data stream prevent the
- client from being able to process Telnet Kermit Option negotiations
- properly.
-*/
-#ifdef STREAMING
- /* Because streaming sets the timeout to 0... */
- if (streaming) {
- timint = rcvtimo = rtimo;
- streaming = 0;
- }
-#endif /* STREAMING */
- if (what & W_RECV &&
- (!server || (server && justone)) &&
- (wslots > 1
-#ifdef STREAMING
- || streaming
-#endif /* STREAMING */
- )) {
-#ifdef GFTIMER
- CKFLOAT oldsec, sec = (CKFLOAT) 0.0;
-#else
- int oldsec, sec = 0;
-#endif /* GFTIMER */
- debug(F101,"errpkt draining","",wslots);
- xxscreen(SCR_ST,ST_MSG,0l,"Draining incoming packets, wait...");
- while (x > -1) { /* Don't bother if no connection */
- oldsec = sec;
-#ifdef GFTIMER
- sec = gftimer();
- if (oldsec != (CKFLOAT) 0.0)
- timint = rcvtimo = (int) (sec - oldsec + 0.5);
-#else
- sec = gtimer();
- if (oldsec != 0)
- timint = rcvtimo = sec - oldsec + 1;
-#endif /* GFTIMER */
- if (timint < 1)
- timint = rcvtimo = 1;
- msleep(50); /* Allow a bit of slop */
- x = rpack(); /* Read a packet */
- if (x == 'T' || x == 'z') /* Timed out means we're done */
- break;
- xxscreen(SCR_PT,x,rsn,""); /* Let user know */
- }
- xxscreen(SCR_ST,ST_MSG,0l,"Drain complete.");
- }
- if ((x = (what & W_KERMIT)))
- xitsta |= x; /* Remember what failed. */
- success = 0;
- return(y);
-}
-
-/* scmd() -- Send a packet of the given type */
-
-int
-#ifdef CK_ANSIC
-scmd(char t, CHAR *dat)
-#else
-scmd(t,dat) char t; CHAR *dat;
-#endif /* CK_ANSIC */
-/* scmd */ {
- int x;
- extern char * srimsg;
- debug(F000,"scmd",dat,t);
- if (encstr(dat) < 0) { /* Encode the command string */
- srimsg = "String too long";
- return(-1);
- }
- x = spack(t,pktnum,size,data);
- debug(F101,"scmd spack","",x);
- return(x);
-}
-
-/* Compose and Send GET packet */
-
-struct opktparm { /* O-Packet item list */
- CHAR * opktitem;
- struct opktparm * opktnext;
-};
-
-struct opktparm * opkthead = NULL; /* Linked list of O-packet fields */
-int opktcnt = 0; /* O-Packet counter */
-char * srimsg = NULL; /* GET-Packet error message */
-
-/* S O P K T -- Send O-Packet */
-/*
- Sends one O-Packet each time called, using first-fit method of filling
- the packet from linked list of parameters pointed to by opkthead.
- To be called repeatedly until list is empty or there is an error.
- Returns:
- -1 on failure.
- 0 on success and no more fields left to send.
- 1 on success but with more fields left to be sent.
-*/
-
-int
-sopkt() {
- int n = 0; /* Field number in this packet */
- int rc = 0; /* Return code */
- int len = 0; /* Data field length */
- char c = NUL;
- struct opktparm * o = NULL;
- struct opktparm * t = NULL;
- struct opktparm * prev = NULL;
- CHAR * dsave = data;
- int x, ssave = spsiz;
-
- srimsg = NULL; /* Error message */
- o = opkthead; /* Point to head of list */
- if (!o) { /* Oops, no list... */
- srimsg = "GET Packet Internal Error 1";
- debug(F100,"sopkt NULL list","",0);
- return(-1);
- }
- while (o) { /* Go thru linked list... */
- c = *(o->opktitem); /* Parameter code */
- debug(F000,"sopkt",o->opktitem,c);
- x = encstr((CHAR *)o->opktitem);
- debug(F111,"sopkt encstr",dsave,x);
- if (x < 0) { /* Encode this item */
- if (n == 0) { /* Failure, first field in packet */
- debug(F100,"sopkt overflow","",0);
- spsiz = ssave; /* Restore these */
- data = dsave;
- o = opkthead; /* Free linked list */
- while (o) {
- if (o->opktitem) free(o->opktitem);
- t = o->opktnext;
- free((char *)o);
- o = t;
- }
- opkthead = NULL;
- srimsg = "GET Packet Too Long for Server";
- return(-1); /* Fail */
- } else { /* Not first field in packet */
- debug(F110,"sopkt leftover",o->opktitem,0);
- prev = o; /* Make this one the new previous */
- o = o->opktnext; /* Get next */
- c = NUL; /* So we know we're not done */
- *data = NUL; /* Erase any partial encoding */
- continue; /* We can try this one again later */
- }
- }
- n++; /* Encoding was successful */
- debug(F111,"sopkt field",data,x);
- len += x; /* Total data field length */
- data += x; /* Set up for next field... */
- spsiz -= x;
- free(o->opktitem); /* Free item just encoded */
- if (o == opkthead) { /* If head */
- opkthead = o->opktnext; /* Move head to next */
- free((char *)o); /* Free this list node */
- o = opkthead;
- } else { /* If not head */
- o = o->opktnext; /* Get next */
- prev->opktnext = o; /* Link previous to next */
- }
- if (c == '@') /* Loop exit */
- break;
- if (!o && !opkthead) { /* Set up End Of Parameters Field */
- o = (struct opktparm *)malloc(sizeof(struct opktparm));
- if (o) {
- opkthead = o;
- if (!(o->opktitem = (CHAR *)malloc(3))) {
- free((char *)o);
- srimsg = "GET Packet Internal Error 8";
- return(-1);
- }
- ckstrncpy((char *)(o->opktitem), "@ ", 3);
- debug(F111,"sopkt o->opktitem",o->opktitem,
- strlen((char *)(o->opktitem)));
- o->opktnext = NULL;
- }
- }
- }
- data = dsave; /* Restore globals */
- spsiz = ssave;
- debug(F110,"sopkt data",data,0);
- debug(F101,"sopkt opktcnt","",opktcnt);
- if (opktcnt++ > 0) {
- if (nxtpkt() < 0) { /* Get next packet number and buffer */
- srimsg = "GET Packet Internal Error 9";
- return(-1);
- }
- }
- debug(F101,"sopkt pktnum","",pktnum);
- rc = spack((char)'O',pktnum,len,data); /* Send O-Packet */
- debug(F101,"sopkt spack","",rc);
- if (rc < 0) /* Failed */
- srimsg = "Send Packet Failure"; /* Set message */
- else /* Succeeded */
- rc = (c == '@') ? 0 : 1; /* 1 = come back for more, 0 = done */
- debug(F101,"sopkt rc","",rc);
- return(rc);
-}
-
-/* S R I N I T -- Send GET packet */
-/*
- Sends the appropriate GET-Class packet.
- Returns:
- -1 on error
- 0 if packet sent successfully and we can move on to the next state
- 1 if an O-packet was sent OK but more O packets still need to be sent.
-*/
-int
-srinit(reget, retrieve, opkt) int reget, retrieve, opkt; {
- int x = 0, left = 0;
- extern int oopts, omode;
- CHAR * p = NULL;
-#ifdef RECURSIVE
- extern int recursive;
- debug(F101,"srinit recursive","",recursive);
-#endif /* RECURSIVE */
- debug(F101,"srinit reget","",reget);
- debug(F101,"srinit retrieve","",retrieve);
- debug(F101,"srinit opkt","",opkt);
- debug(F101,"srinit oopts","",oopts);
- debug(F101,"srinit omode","",omode);
- debug(F110,"srinit cmarg",cmarg,0);
- srimsg = NULL;
-
- opktcnt = 0;
- if (!cmarg) cmarg = "";
- if (!*cmarg) {
- srimsg = "GET with no filename";
- debug(F100,"srinit null cmarg","",0);
- return(-1);
- }
- if (opkt) { /* Extended GET is totally different */
- char buf[16];
- struct opktparm * o = NULL;
- struct opktparm * prev = NULL;
-
- buf[0] = NUL;
-
- /* Build O-Packet fields and send (perhaps first) O-Packet */
-
- if (oopts > -1) { /* Write Option flags */
- o = (struct opktparm *)malloc(sizeof(struct opktparm));
- if (!o) {
- srimsg = "GET Packet Internal Error 2";
- debug(F100,"srinit malloc fail O1","",0);
- return(-1);
- }
- sprintf(buf,"Ox%d",oopts); /* safe */
- x = (int) strlen(buf+2);
- buf[1] = tochar(x);
- o->opktitem = (CHAR *)malloc(x + 3);
- if (!o->opktitem) {
- srimsg = "GET Packet Internal Error 3";
- debug(F100,"srinit malloc fail O2","",0);
- return(-1);
- }
- ckstrncpy((char *)(o->opktitem),buf,x+3);
- o->opktnext = NULL;
- if (!opkthead)
- opkthead = o;
- prev = o;
- }
- if (omode > -1) { /* If Xfer Mode specified, write it */
- o = (struct opktparm *)malloc(sizeof(struct opktparm));
- if (!o) {
- srimsg = "GET Packet Internal Error 4";
- debug(F100,"srinit malloc fail M1","",0);
- return(-1);
- }
- sprintf(buf,"Mx%d",omode); /* safe */
- x = (int) strlen(buf+2);
- buf[1] = tochar(x);
- o->opktitem = (CHAR *)malloc(x + 3);
- if (!o->opktitem) {
- srimsg = "GET Packet Internal Error 5";
- debug(F100,"srinit malloc fail O2","",0);
- return(-1);
- }
- ckstrncpy((char *)(o->opktitem),buf,x+3);
- o->opktnext = NULL;
- if (!opkthead)
- opkthead = o;
- else
- prev->opktnext = o;
- prev = o;
- }
-
- /* Same deal for oname and opath eventually but not needed now... */
-
- x = strlen(cmarg); /* Now do filename */
- if (x > spsiz - 4) {
- srimsg = "GET Packet Too Long for Server";
- return(-1);
- }
- o = (struct opktparm *)malloc(sizeof(struct opktparm));
- if (!o) {
- srimsg = "GET Packet Internal Error 6";
- debug(F100,"srinit malloc fail F1","",0);
- return(-1);
- }
- left = x + 6;
- o->opktitem = (CHAR *)malloc(left + 1);
- if (!o->opktitem) {
- srimsg = "GET Packet Internal Error 7";
- debug(F100,"srinit malloc fail F2","",0);
- return(-1);
- }
- p = o->opktitem;
- *p++ = 'F';
- left--;
- if (x > 94) { /* Too long for normal length */
- *p++ = SYN; /* Escape length with Ctrl-V */
- *p++ = tochar(x / 95);
- *p++ = tochar(x % 95);
- left -= 3;
- } else { /* Normal encoding for 94 or less */
- *p++ = tochar(x);
- left--;
- }
- ckstrncpy((char *)p,cmarg,left); /* Copy the filename */
- o->opktnext = NULL;
- if (!opkthead)
- opkthead = o;
- else
- prev->opktnext = o;
- prev = o;
-
- /* End of Parameters */
-
- prev->opktnext = NULL; /* End of list. */
- return(sopkt());
- }
-
- /* Not Extended GET */
-
- if (encstr((CHAR *)cmarg) < 0) { /* Encode the filename. */
- srimsg = "GET Packet Too Long for Server";
- return(-1);
- }
- if (retrieve) { /* Send the packet. */
-#ifdef RECURSIVE
- if (recursive)
- x = spack((char)'W',pktnum,size,data); /* GET /DELETE /RECURSIVE */
- else
-#endif /* RECURSIVE */
- x = spack((char)'H',pktnum,size,data); /* GET /DELETE */
- }
-#ifdef RECURSIVE
- else if (recursive)
- x = spack((char)'V',pktnum,size,data); /* GET /RECURSIVE */
-#endif /* RECURSIVE */
- else
- x = spack((char)(reget ? 'J' : 'R'),pktnum,size,data); /* GET */
- if (x < 0)
- srimsg = "Send Packet Failure";
- return(x < 0 ? x : 0);
-}
-
-
-/* K S T A R T -- Checks for a Kermit packet while in terminal mode. */
-
-/* (or command mode...) */
-
-#ifdef CK_AUTODL
-int
-#ifdef CK_ANSIC
-kstart(CHAR ch)
-#else
-kstart(ch) CHAR ch;
-#endif /* CK_ANSIC */
-/* kstart */ {
- static CHAR * p = NULL;
-
-#ifdef OS2
- static CHAR * pk = NULL;
-#endif /* OS2 */
- ch &= 0177; /* Strip 8th bit */
-
- /* Because we're in cooked mode at the command prompt... */
-
- if (ch == LF) {
- debug(F110,"kstart","ch == LF",0);
- if ((what == W_COMMAND || what == W_INIT || what == W_NOTHING)) {
- if (eol == CR) {
- ch = eol;
- debug(F110,"kstart","ch = CR",0);
- }
- }
- }
-
-#ifdef OS2
- if (adl_kmode == ADL_STR) {
- if (!ch)
- return(0);
- if (!pk)
- pk = adl_kstr;
-
- if (ch == *pk) {
- pk++;
- if (*pk == '\0') {
- pk = adl_kstr;
- debug(F100, "kstart Kermit Start String","",0);
- return(PROTO_K + 1);
- }
- } else
- pk = adl_kstr;
- }
-#endif /* OS2 */
-
- if (ch == stchr) { /* Start of packet */
- kstartactive = 1;
- p = ksbuf;
- *p = ch;
- debug(F101,"kstart SOP","",ch);
- } else if (ch == eol) { /* End of packet */
- kstartactive = 0;
- if (p) {
- debug(F101,"kstart EOL","",ch);
- p++;
- if (p - ksbuf < 94 ) {
- int rc = 0;
- *p++ = ch;
- *p = NUL;
- rc = chkspkt((char *)ksbuf);
- debug(F111,"kstart EOP chkspkt", ksbuf, rc);
- p = NULL;
- if (!rc) return(0);
- if (rc == 2) rc = -1;
- debug(F111,"kstart ksbuf",ksbuf,rc);
- return(rc);
- } else {
- debug(F110,"kstart","p - ksbuf >= 94",0);
- p = NULL;
- }
- }
- } else if (p) {
- if (ch < SP)
- kstartactive = 0;
- p++;
- if (p - ksbuf < 94) {
- *p = ch;
- } else {
- p = NULL;
- debug(F110,"kstart","p - ksbuf >= 94",0);
- }
- }
- return(0);
-}
-
-#ifdef CK_XYZ
-
-/* Z S T A R T -- Checks for a ZMODEM packet while in terminal mode. */
-
-int
-#ifdef CK_ANSIC
-zstart(CHAR ch)
-#else
-zstart(ch) CHAR ch;
-#endif /* CK_ANSIC */
-/* zstart */ {
- static CHAR * matchstr = (CHAR *) "\030B00";
- /* "rz\r**\030B00000000000000\r\033J\021"; */
- static CHAR * p = NULL;
- extern int inserver;
-
- if (inserver)
- return(0);
-
- if (!ch)
- return(0);
- if (!p) {
-#ifdef OS2
- p = adl_zmode == ADL_PACK ? matchstr : adl_zstr;
-#else
- p = matchstr;
-#endif /* OS2 */
- }
- if (ch == *p) {
- p++;
- if (*p == '\0') {
-#ifdef OS2
- if (adl_zmode == ADL_PACK) {
- p = matchstr;
- debug(F100, "zstart Zmodem SOP","",0);
- } else {
- p = adl_zstr;
- debug(F100, "zstart Zmodem Start String","",0);
- }
-#else
- p = matchstr;
- debug(F100, "zstart Zmodem SOP","",0);
-#endif /* OS2 */
- return(PROTO_Z + 1);
- }
- } else {
-#ifdef OS2
- p = adl_zmode == ADL_PACK ? matchstr : adl_zstr;
-#else
- p = matchstr;
-#endif /* OS2 */
- }
- return(0);
-}
-#endif /* CK_XYZ */
-
-#ifndef NOICP
-#ifdef CK_APC
-/* A U T O D O W N */
-
-#ifdef CK_ANSIC
-VOID
-autodown(int ch)
-#else
-VOID
-autodown(ch) int ch;
-#endif /* CK_ANSIC */
-/* autodown */ {
-
-/* The Kermit and Zmodem Auto-download calls go here */
-
- extern int justone; /* From protocol module */
- extern int debses, protocol, apcactive, autodl, inautodl;
-#ifdef DCMDBUF
- extern char *apcbuf;
-#else
- extern char apcbuf[];
-#endif /* DCMDBUF */
-#ifdef OS2
- extern int apclength, term_io;
-#endif /* OS2 */
- int k = 0;
-
- if ((autodl || inautodl
-#ifdef IKS_OPTION
- || TELOPT_SB(TELOPT_KERMIT).kermit.me_start
-#endif /* IKS_OPTION */
- ) && !debses) {
-#ifdef CK_XYZ
-#ifdef XYZ_INTERNAL
- extern int p_avail;
-#else
- int p_avail = 1;
-#endif /* XYZ_INTERNAL */
- if (p_avail && zstart((CHAR) ch)) {
- debug(F100, "Zmodem download","",0);
-#ifdef OS2
-#ifndef NOTERM
- apc_command(APC_LOCAL,"receive /protocol:zmodem");
-#endif /* NOTERM */
-#else /* OS2 */
- ckstrncpy(apcbuf,"receive /protocol:zmodem",APCBUFLEN);
- apcactive = APC_LOCAL;
-#endif /* OS2 */
- return;
- }
-#endif /* CK_XYZ */
-
- /* First try... */
- k = kstart((CHAR) ch);
- if (
-#ifdef NOSERVER
- k > 0
-#else /* NOSERVER */
- k
-#endif /* NOSERVER */
- ) { /* We saw a valid S or I packet */
- if (k < 0) { /* Stuff RECEIVE into APC buffer */
- justone = 1;
- switch (protocol) {
-#ifdef CK_XYZ
- case PROTO_G:
- ckstrncpy(apcbuf,
- "set proto kermit, server, set protocol g",
- APCBUFLEN
- );
- break;
- case PROTO_X:
- ckstrncpy(apcbuf,
- "set proto kermit,server,set proto xmodem",
- APCBUFLEN
- );
- break;
- case PROTO_XC:
- ckstrncpy(apcbuf,
- "set proto kermit,server,set proto xmodem-crc",
- APCBUFLEN
- );
- break;
- case PROTO_Y:
- ckstrncpy(apcbuf,
- "set proto kermit,server, set protocol y",
- APCBUFLEN
- );
- break;
- case PROTO_Z:
- ckstrncpy(apcbuf,
- "set proto kermit,server,set proto zmodem",
- APCBUFLEN
- );
- break;
-#endif /* CK_XYZ */
- case PROTO_K:
- ckstrncpy(apcbuf,"server",APCBUFLEN);
- break;
- }
- } else {
- justone = 0;
- ckstrncpy(apcbuf,"receive /protocol:kermit",APCBUFLEN);
- }
-#ifdef OS2
-#ifndef NOTERM
- apc_command(APC_LOCAL,apcbuf);
-#endif /* NOTERM */
-#else /* OS2 */
- ckstrncpy(apcbuf,"receive /protocol:zmodem",APCBUFLEN);
- apcactive = APC_LOCAL;
-#endif /* OS2 */
- return;
- }
- }
-}
-#endif /* CK_APC */
-#endif /* NOICP */
-
-/* C H K S P K T -- Check if buf contains a valid S or I packet */
-
-int
-chkspkt(packet) char *packet; {
- int i;
- int buflen;
- int len = -1;
- CHAR chk;
- char type = 0;
- char *s = NULL;
- char *buf = NULL;
- char tmpbuf[100]; /* Longest S/I packet is about 30 */
-
- if (!packet) return(0);
- buflen = ckstrncpy(tmpbuf,packet,100); /* Make a pokeable copy */
- if (buflen < 5) return(0); /* Too short */
- if (buflen > 100) return(0); /* Too long to be an S or I packet */
- s = buf = tmpbuf; /* Point to beginning of copy */
-
- if (*s++ != stchr) return(0); /* SOH */
- len = xunchar(*s++); /* Length */
- if (len < 0) return(0);
- if (*s++ != SP) return(0); /* Sequence number */
- type = *s++; /* Type */
- if (type != 'S' && type != 'I')
- return(0);
- if (buflen < len + 2) return(0);
- s += (len - 3); /* Position of checksum */
- chk = (CHAR) (*s); /* Checksum */
- *s = NUL; /* Temporarily null-terminate data field */
- if (xunchar(chk) != chk1((CHAR *)(buf+1),buflen-2)) { /* Check it */
- /*
- In C-Kermit 9.0 and later, an S or I packet can have a
- Type 3 Block check ("help set block-check" for details).
- */
- unsigned crc; /* Failed... Try Type 3 block check */
- *s = chk; /* Replace last byte */
- s -= 2; /* Back up two bytes */
- crc = (xunchar(s[0]) << 12) /* Convert 3 bytes to numeric CRC */
- | (xunchar(s[1]) << 6)
- | (xunchar(s[2]));
- chk = (CHAR)(*s); /* Copy 1st byte of 3-byte CRC */
- *s = NUL; /* Null-terminate data field */
- if (crc != chk3((CHAR *)(buf+1),strlen(buf+1)))
- return(0);
- }
- return(type == 'S' ? 1 : 2);
-}
-#endif /* CK_AUTODL */
-
-/* R P A C K -- Read a Packet */
-
-/*
- rpack reads a packet and returns the packet type, or else Q if the
- packet was invalid, or T if a timeout occurred. Upon successful return,
- sets the values of global rsn (received sequence number), rln (received
- data length), and rdatap (pointer to null-terminated data field), and
- returns the packet type. NOTE: This is an inner-loop function so must be
- efficient. Protect function calls by if-tests where possible, e.g.
- "if (pktlog) logpkt(...);".
-*/
-int
-rpack() {
- register int i, j, x, lp; /* Local variables */
-#ifdef CKTUNING
- unsigned int chk;
-#endif /* CKTUNING */
- int k, type, chklen;
- unsigned crc;
- CHAR pbc[5]; /* Packet block check */
- CHAR *sohp; /* Pointer to SOH */
- CHAR e; /* Packet end character */
-
-#ifdef GFTIMER
- CKFLOAT t1 = 0.0, t2 = 0.0;
-#endif /* GFTIMER */
-
- debug(F101,"rpack pktnum","",pktnum);
-
-#ifndef OLDCHKINT
- if (chkint() < 0) /* Check for console interrupts. */
- return('z');
-#endif /* OLDCHKINT */
-
- k = getrbuf(); /* Get a new packet input buffer. */
- debug(F101,"rpack getrbuf","",k);
- if (k < 0) { /* Return like this if none free. */
- return(-1);
- }
- recpkt = r_pkt[k].bf_adr;
- *recpkt = '\0'; /* Clear receive buffer. */
- sohp = recpkt; /* Initialize pointers to it. */
- rdatap = recpkt;
- rsn = rln = -1; /* In case of failure. */
- e = (turn) ? turnch : eol; /* Use any handshake char for eol */
-
-/* Try to get a "line". */
-
-#ifdef CK_AUTODL
- debug(F110,"rpack ksbuf",ksbuf,0);
- if (ksbuf[0]) { /* Kermit packet already */
- int x; /* collected for us in CONNECT mode */
- CHAR *s1 = recpkt, *s2 = ksbuf;
- j = 0;
- while (*s2) { /* Copy and get length */
- *s1++ = *s2++; /* No point optimizing this since */
- j++; /* it's never more than ~20 chars */
- }
- *s1 = NUL;
-#ifdef PARSENSE
- x = parchk(recpkt, stchr, j); /* Check parity */
- debug(F000,"autodownload parity","",parity);
- debug(F000,"autodownload parchk","",x);
- if (x > 0 && parity != x) {
- autopar = 1;
- parity = x;
- }
-#endif /* PARSENSE */
- ksbuf[0] = NUL; /* Don't do this next time! */
-
- } else { /* Normally go read a packet */
-#endif /* CK_AUTODL */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"rpack timint","",timint);
- debug(F101,"rpack rcvtimo","",rcvtimo);
-#ifdef STREAMING
- debug(F101,"rpack streaming","",streaming);
-#endif /* STREAMING */
-#ifdef GFTIMER
- /* Measure how long it takes to read a packet */
- t1 = gftimer();
-#endif /* GFTIMER */
- }
-#endif /* DEBUG */
-
-/* JUST IN CASE (otherwise this could clobber streaming) */
-
- if ((timint == 0
-#ifdef STREAMING
- || streaming
-#endif /* STREAMING */
- ) && (rcvtimo != 0)) {
- debug(F101,"rpack timint 0 || streaming but rcvtimo","",rcvtimo);
- rcvtimo = 0;
- }
-
-#ifdef PARSENSE
-#ifdef UNIX
-/*
- So far the final turn argument is only for ck[uvdl]tio.c. Should be added
- to the others too. (turn == handshake character.)
-*/
- j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);
-#else
-#ifdef VMS
- j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);
-#else
-#ifdef datageneral
- j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);
-#else
-#ifdef STRATUS
- j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);
-#else
-#ifdef OS2
- j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);
-#else
-#ifdef OSK
- j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);
-#else
- j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr);
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* UNIX */
- if (parity != 0 && parity != 's' && ttprty != 0) {
- if (parity != ttprty) autopar = 1;
- parity = ttprty;
- }
-#else /* !PARSENSE */
- j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e);
-#endif /* PARSENSE */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"rpack ttinl len","",j);
-#ifdef GFTIMER
- t2 = gftimer();
- debug(F101,"rpack ttinl msec","",(long)((t2-t1)*1000.0));
-#endif /* GFTIMER */
- }
-#endif /* DEBUG */
-
-#ifdef STREAMING
- if (streaming && sndtyp == 'D' && j == 0)
- return('Y');
-#endif /* STREAMING */
-
- if (j < 0) {
- /* -1 == timeout, -2 == ^C, -3 == connection lost or fatal i/o */
- debug(F101,"rpack: ttinl fails","",j); /* Otherwise, */
- freerbuf(k); /* Free this buffer */
- if (j < -1) { /* Bail out if ^C^C typed. */
- if (j == -2) {
- interrupted = 1;
- debug(F101,"rpack ^C server","",server);
- debug(F101,"rpack ^C en_fin","",en_fin);
- } else if (j == -3) {
- fatalio = 1;
- debug(F101,"rpack fatalio","",en_fin);
- }
- return(j);
- }
- if (nakstate) /* j == -1 is a read timeout */
- xxscreen(SCR_PT,'T',(long)winlo,"");
- else
- xxscreen(SCR_PT,'T',(long)pktnum,"");
- logpkt('r',-1,(CHAR *)"<timeout>",0);
- if (flow == 1) ttoc(XON); /* In case of Xoff blockage. */
- return('T');
- }
-#ifdef CK_AUTODL
- }
-#endif /* CK_AUTODL */
-
- rpktl = j;
- tlci += j; /* All OK, Count the characters. */
- flci += j;
-
-/* Find start of packet */
-
-#ifndef PARSENSE
- for (i = 0; (recpkt[i] != stchr) && (i < j); i++)
- sohp++; /* Find mark */
- if (i++ >= j) { /* Didn't find it. */
- logpkt('r',-1,"<timeout>",0);
- freerbuf(k);
- return('T');
- }
-#else
- i = 1; /* ttinl does this for us */
-#endif /* PARSENSE */
-
- rpackets++; /* Count received packet. */
- lp = i; /* Remember LEN position. */
- if ((j = xunchar(recpkt[i++])) == 0) { /* Get packet length. */
- if ((j = lp+5) > MAXRP) { /* Long packet */
- return('Q'); /* Too long */
- }
-
-#ifdef CKTUNING
- /* Save some function-call and loop overhead... */
-#ifdef COMMENT
- /* ttinl() already removed parity */
- if (parity)
-#endif /* COMMENT */
- chk = (unsigned) ((unsigned) recpkt[i-1] +
- (unsigned) recpkt[i] +
- (unsigned) recpkt[i+1] +
- (unsigned) recpkt[i+2] +
- (unsigned) recpkt[i+3]
- );
-#ifdef COMMENT
- else
- chk = (unsigned) ((unsigned) (recpkt[i-1] & 077) +
- (unsigned) (recpkt[i] & 077) +
- (unsigned) (recpkt[i+1] & 077) +
- (unsigned) (recpkt[i+2] & 077) +
- (unsigned) (recpkt[i+3] & 077)
- );
-#endif /* COMMENT */
- if (xunchar(recpkt[j]) != ((((chk & 0300) >> 6) + chk) & 077))
-#else
- x = recpkt[j]; /* Header checksum. */
- recpkt[j] = '\0'; /* Calculate & compare. */
- if (xunchar(x) != chk1(recpkt+lp,5))
-#endif /* CKTUNING */
- {
- freerbuf(k);
- logpkt('r',-1,(CHAR *)"<crunched:hdr>",0);
- xxscreen(SCR_PT,'%',(long)pktnum,"Bad packet header");
- return('Q');
- }
-#ifndef CKTUNING
- recpkt[j] = x; /* Checksum ok, put it back. */
-#endif /* CKTUNING */
- rln = xunchar(recpkt[j-2]) * 95 + xunchar(recpkt[j-1]) - bctl;
- j = 3; /* Data offset. */
- } else if (j < 3) {
- debug(F101,"rpack packet length less than 3","",j);
- freerbuf(k);
- logpkt('r',-1,(CHAR *)"<crunched:len>",0);
- xxscreen(SCR_PT,'%',(long)pktnum,"Bad packet length");
- return('Q');
- } else {
- rln = j - bctl - 2; /* Regular packet */
- j = 0; /* No extended header */
- }
- rsn = xunchar(recpkt[i++]); /* Sequence number */
- if (pktlog) /* Save a function call! */
- logpkt('r',rsn,sohp,rln+bctl+j+4);
- if (rsn < 0 || rsn > 63) {
- debug(F101,"rpack bad sequence number","",rsn);
- freerbuf(k);
- if (pktlog)
- logpkt('r',rsn,(CHAR *)"<crunched:seq>",0);
- xxscreen(SCR_PT,'%',(long)pktnum,"Bad sequence number");
- return('Q');
- }
-/*
- If this packet has the same type as the packet just sent, assume it is
- an echo and ignore it. Don't even bother with the block check calculation:
- even if the packet is corrupted, we don't want to NAK an echoed packet.
- Nor must we NAK an ACK or NAK.
-*/
- type = recpkt[i++]; /* Get packet's TYPE field */
- if (type == sndtyp || (nakstate && (type == 'N' /* || type == 'Y' */ ))) {
- debug(F000,"rpack echo","",type); /* If it's an echo */
- freerbuf(k); /* Free this buffer */
- logpkt('#',rsn,(CHAR *)"<echo:ignored>",0);
- return('e'); /* Return special (lowercase) code */
- }
-/*
- Separate the data from the block check, accounting for the case where
- a packet was retransmitted after the block check switched. The "Type 3
- Forced" business is new to C-Kermit 9.0.
-*/
- if (bctf) { /* Type 3 forced on all packets */
- bctl = chklen = 3;
- } else if ((type == 'I' || type == 'S')) { /* Otherwise... */
- if (recpkt[11] == '5') { /* Sender is forcing Type 3 */
- bctf = 1; /* So we will too */
- bctl = chklen = 3;
- debug(F100,"RECOGNIZE BLOCK CHECK TYPE 5","",0);
- } else { /* Normal case */
- /* I & S packets always have type 1 */
- chklen = 1;
- rln = rln + bctl - 1;
- }
- } else if (type == 'N') { /* A NAK packet never has data */
- chklen = xunchar(recpkt[lp]) - 2;
- if (chklen < 1 || chklen > 3) { /* JHD 13 Apr 2010 */
- debug(F101,"rpack bad nak chklen","",chklen);
- freerbuf(k);
- logpkt('r',-1,(CHAR *)"<crunched:chklen>",0);
- xxscreen(SCR_PT,'%',(long)pktnum,"(bad nak)");
- return('Q');
- }
- rln = rln + bctl - chklen;
- } else chklen = bctl;
-#ifdef DEBUG
- if (deblog) { /* Save 2 function calls */
- debug(F101,"rpack bctl","",bctl);
- debug(F101,"rpack chklen","",chklen);
- }
-#endif /* DEBUG */
- i += j; /* Buffer index of DATA field */
- rdatap = recpkt+i; /* Pointer to DATA field */
- if ((j = rln + i) > r_pkt[k].bf_len) { /* Make sure it fits */
- debug(F101,"packet too long","",j);
- freerbuf(k);
- logpkt('r',rsn,(CHAR *)"<overflow>",0);
- return('Q');
- }
- for (x = 0; x < chklen; x++) /* Copy the block check */
- pbc[x] = recpkt[j+x]; /* 3 bytes at most. */
- pbc[x] = '\0'; /* Null-terminate block check string */
- recpkt[j] = '\0'; /* and the packet Data field. */
-
- if (chklen == 2 && bctu == 4) { /* Adjust for Blank-Free-2 */
- chklen = 4; /* (chklen is now a misnomer...) */
- debug(F100,"rpack block check B","",0);
- }
- switch (chklen) { /* Check the block check */
- case 1: /* Type 1, 6-bit checksum */
- if (xunchar(*pbc) != chk1(recpkt+lp,j-lp)) {
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"checked chars",recpkt+lp,0);
- debug(F101,"block check (1)","",(int) xunchar(*pbc));
- debug(F101,"should be (1)","",chk1(recpkt+lp,j-lp));
- }
-#endif /* DEBUG */
- freerbuf(k);
- logpkt('r',-1,(CHAR *)"<crunched:chk1>",0);
- xxscreen(SCR_PT,'%',(long)pktnum,"Checksum error");
- return('Q');
- }
- break;
- case 2: /* Type 2, 12-bit checksum */
- x = xunchar(*pbc) << 6 | xunchar(pbc[1]);
- if (x != chk2(recpkt+lp,j-lp)) { /* No match */
- if (type == 'E') { /* Allow E packets to have type 1 */
- recpkt[j++] = pbc[0];
- recpkt[j] = '\0';
- if (xunchar(pbc[1]) == chk1(recpkt+lp,j-lp))
- break;
- else
- recpkt[--j] = '\0';
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"checked chars",recpkt+lp,0);
- debug(F101,"block check (2)","", x);
- debug(F101,"should be (2)","", (int) chk2(recpkt+lp,j-lp));
- }
-#endif /* DEBUG */
- freerbuf(k);
- logpkt('r',-1,(CHAR *)"<crunched:chk2>",0);
- xxscreen(SCR_PT,'%',(long)pktnum,"Checksum error");
- return('Q');
- }
- break;
- case 3: /* Type 3, 16-bit CRC */
- crc = (xunchar(pbc[0]) << 12)
- | (xunchar(pbc[1]) << 6)
- | (xunchar(pbc[2]));
- if (crc != chk3(recpkt+lp,j-lp)) {
- if (type == 'E') { /* Allow E packets to have type 1 */
- recpkt[j++] = pbc[0];
- recpkt[j++] = pbc[1];
- recpkt[j] = '\0';
- if (xunchar(pbc[2]) == chk1(recpkt+lp,j-lp))
- break;
- else { j -=2; recpkt[j] = '\0'; }
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"checked chars",recpkt+lp,0);
- debug(F101,"block check (3)","",crc);
- debug(F101,"should be (3)","",(int) chk3(recpkt+lp,j-lp));
- }
-#endif /* DEBUG */
- freerbuf(k);
- logpkt('r',-1,(CHAR *)"<crunched:chk3>",0);
- xxscreen(SCR_PT,'%',(long)pktnum,"CRC error");
- return('Q');
- }
- break;
- case 4: /* Type 4 = Type 2, no blanks. */
- x = (unsigned)((xunchar(*pbc) - 1) << 6) |
- (unsigned)(xunchar(pbc[1]) - 1);
- if (x != chk2(recpkt+lp,j-lp)) {
- if (type == 'E') { /* Allow E packets to have type 1 */
- recpkt[j++] = pbc[0];
- recpkt[j] = '\0';
- if (xunchar(pbc[1]) == chk1(recpkt+lp,j-lp))
- break;
- else
- recpkt[--j] = '\0';
- }
- debug(F101,"bad type B block check","",x);
- freerbuf(k);
- logpkt('r',-1,(CHAR *)"<crunched:chkb>",0);
- xxscreen(SCR_PT,'%',(long)pktnum,"Checksum error");
- return('Q');
- }
- break;
- default: /* Shouldn't happen... */
- freerbuf(k);
- logpkt('r',-1,(CHAR *)"<crunched:chkx>",0);
- xxscreen(SCR_PT,'%',(long)pktnum,"(crunched)");
- return('Q');
- }
- debug(F101,"rpack block check OK","",rsn);
-
-/* Now we can believe the sequence number, and other fields. */
-/* Here we violate strict principles of layering, etc, and look at the */
-/* packet sequence number. If there's already a packet with the same */
-/* number in the window, we remove this one so that the window will not */
-/* fill up. */
-
- if ((x = rseqtbl[rsn]) != -1) { /* Already a packet with this number */
- retrans++; /* Count it for statistics */
- debug(F101,"rpack got dup","",rsn);
- logpkt('r',rsn,(CHAR *)"<duplicate>",0);
- freerbuf(x); /* Free old buffer, keep new packet. */
- r_pkt[k].pk_rtr++; /* Count this as a retransmission. */
- }
-
-/* New packet, not seen before, enter it into the receive window. */
-
-#ifdef CK_TIMERS
- if (timint > 0)
- rrttbl[rsn] = gtimer(); /* Timestamp */
-#endif /* CK_TIMERS */
-
- rseqtbl[rsn] = k; /* Make back pointer */
- r_pkt[k].pk_seq = rsn; /* Record in packet info structure */
- r_pkt[k].pk_typ = type; /* Sequence, type,... */
- r_pkt[k].pk_adr = rdatap; /* pointer to data buffer */
- if (local) { /* Save a function call! */
- int x = 0;
- if (fdispla != XYFD_N) x = 1;
- if (fdispla == XYFD_B && (type == 'D' || sndtyp == 'D')) x = 0;
- if (x) /* Update screen */
- xxscreen(SCR_PT,(char)type,(long)rsn,(char *)sohp);
- }
- return(type); /* Return packet type */
-}
-
-/* L O G P K T -- Log packet number n, pointed to by s. */
-
-/* c = 's' (send) or 'r' (receive) */
-
-VOID
-#ifdef CK_ANSIC
-logpkt(char c,int n, CHAR *s, int len)
-#else
-logpkt(c,n,s,len) char c; int n; CHAR *s; int len;
-#endif /* CK_ANSIC */
-/* logpkt */ {
- char plog[20];
- if (!s) s = (CHAR *)"";
- if (pktlog) if (chkfn(ZPFILE) > 0) {
- if (n < 0) /* Construct entry header */
- sprintf(plog,"%c-xx-%02d-",c,(gtimer()%60)); /* safe */
- else
- sprintf(plog,"%c-%02d-%02d-",c,n,(gtimer()%60)); /* safe */
- if (zsoutx(ZPFILE,plog,(int)strlen(plog)) < 0) {
- pktlog = 0;
- return;
- } else {
- if (len == 0)
- len = strlen((char *)s);
- if (len > 0) {
- char * p; /* Make SOP printable */
- int x; /* so we can look at logs without */
- p = dbchr(*s); /* triggering autodownload. */
- x = strlen(dbchr(*s));
- if (*s < 32 || (*s > 127 && *s < 160)) {
- if (zsoutx(ZPFILE,p,x) < 0) {
- pktlog = 0;
- return;
- } else {
- len--;
- s++;
- }
- }
- }
- if (zsoutx(ZPFILE,(char *)s,len) < 0) {
- pktlog = 0;
- return;
- } else if (zsoutx(ZPFILE,
-#ifdef UNIX
- "\n", 1
-#else
-#ifdef datageneral
- "\n", 1
-#else
-#ifdef OSK
- "\r", 1
-#else
-#ifdef MAC
- "\r", 1
-#else
- "\015\012", 2
-#endif /* MAC */
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* UNIX */
- ) < 0) {
- pktlog = 0;
- }
- }
- }
-}
-
-/* T S T A T S -- Record statistics in transaction log */
-
-VOID
-tstats() {
- char *tp = NULL;
-#ifdef GFTIMER
- CKFLOAT xx; /* Elapsed time divisor */
-#endif /* GFTIMER */
-
- debug(F101,"tstats xfsecs","",xfsecs);
- debug(F101,"tstats filcnt","",filcnt);
- if (filcnt == 1) { /* Get timing for statistics */
- tsecs = xfsecs; /* Single file, we already have it */
-#ifdef GFTIMER
- debug(F101,"tstats fpxfsecs","",(int)fpxfsecs);
- fptsecs = fpxfsecs;
-#endif /* GFTIMER */
- } else { /* Multiple files */
- tsecs = gtimer(); /* Get current time */
-#ifdef GFTIMER
- fptsecs = gftimer();
-#endif /* GFTIMER */
- }
-#ifdef GFTIMER
- if (fptsecs <= GFMINTIME) /* Calculate CPS */
- fptsecs = (CKFLOAT) GFMINTIME;
- debug(F101,"tstats fptsecs","",(int)fptsecs);
- xx = (CKFLOAT) tfc / fptsecs;
- if (sizeof(long) <= 4) { /* doesn't account for 16-bit longs */
- if (xx > 2147483647.0)
- tfcps = 2147483647L; /* 31 bits */
- else
- tfcps = (long) xx;
- } else
- tfcps = (long) xx;
-#else
- if (tsecs < 2L)
- tsecs = 1L;
- debug(F101,"tstats tsecs","",tsecs);
- tfcps = tfc / tsecs;
-#endif /* GFTIMER */
-
- ztime(&tp); /* Get time stamp */
- tlog(F100,"","",0L); /* Leave a blank line */
- tlog(F110,"Transaction complete",tp,0L); /* Record it */
-
- if (filcnt < 1) return; /* If no files, done. */
-
-/* If multiple files, record character totals for all files */
-
- if (filcnt > 1) {
- tlog(F101," files transferred ","",filcnt - filrej);
- tlog(F101," total file characters ","",tfc);
- tlog(F101," communication line in ","",tlci);
- tlog(F101," communication line out ","",tlco);
- }
-
-/* Record timing info for one or more files */
-
-#ifdef GFTIMER
- if (filcnt - filrej == 1) {
- tlog(F101," elapsed time (seconds) ","",(long) fpxfsecs);
- tlog(F101," effective data rate ","",filcps);
- } else {
- tlog(F101," elapsed time (seconds) ","",(long) fptsecs);
- tlog(F101," effective data rate ","",(long) xx);
- }
-#else
- tlog(F101," elapsed time (seconds) ","",tsecs);
- if (tsecs > 0)
- tlog(F101," effective data rate ","",(tfc / tsecs));
-#endif /* GFTIMER */
-
- tlog(F100,"","",0L); /* Leave a blank line */
-}
-
-/* F S T A T S -- Record file statistics in transaction log */
-
-VOID
-fcps() {
-#ifdef GFTIMER
- double xx;
- fpxfsecs = gftimer() - fpfsecs;
- if (fpxfsecs <= GFMINTIME)
- fpxfsecs = (CKFLOAT) GFMINTIME;
- xx = (CKFLOAT) ffc / fpxfsecs;
- if (sizeof(long) <= 4) {
- if (xx > 2147483647.0)
- tfcps = 2147483647L; /* 31 bits */
- else
- filcps = (long) xx;
- } else
- filcps = (long) xx;
- if (sizeof(int) >= 4)
- xfsecs = (int) fpxfsecs;
- else if (fpxfsecs < 32768.0)
- xfsecs = (int) fpxfsecs;
- else
- xfsecs = 32767;
-#else /* GFTIMER */
- xfsecs = gtimer() - fsecs;
- if (xfsecs < 1L) xfsecs = 1L;
- filcps = ffc / xfsecs;
-#endif /* GFTIMER */
-}
-
-VOID
-fstats() {
- tfc += ffc;
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"fstats tfc","",tfc);
- debug(F101,"fstats what","",what);
- debug(F110,"fstats epktmsg",epktmsg,0);
- }
-#endif /* DEBUG */
-#ifdef TLOG
- if (!discard && !cxseen && !czseen && what != W_NOTHING && !*epktmsg)
- tlog(F101," complete, size","",ffc);
-#endif /* TLOG */
-}
-
-#endif /* NOXFER */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcfn3.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckcfn3.c
deleted file mode 100644
index 2d58a56..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcfn3.c
+++ /dev/null
@@ -1,2606 +0,0 @@
-/* C K C F N 3 -- Packet buffer management for C-Kermit */
-
-/* (plus assorted functions tacked on at the end) */
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-/*
- Note -- if you change this file, please amend the version number and date at
- the top of ckcfns.c accordingly.
-*/
-
-#include "ckcsym.h"
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckcxla.h"
-
-/* C K M K D I R -- Create a directory */
-/*
- Call with:
- int fc = 0 to create, nonzero to remove, a directory.
- char * s = pointer to name of directory to create or remove.
- char ** r = address of pointer to return name or message.
- int m = 1 to print error messages, 0 to be silent.
- int cvt = 1 means convert s from standard format to local format;
- 0 means use s as is.
- Returns:
- 0 on success (directory was created or removed).
- -1 when attempt to create the directory failed.
- -2 on internal error (e.g. no code for creating directories).
- On success, the name is pointed to by p.
- On failure, the reason is pointed to by p.
-*/
-#ifdef CK_MKDIR
-static char ckmkdbuf[CKMAXPATH+1];
-#else
-#ifdef datageneral
-static char ckmkdbuf[CKMAXPATH+1];
-#endif /* datageneral */
-#endif /* CK_MKDIR */
-
-#ifdef CK_MKDIR
-int
-ckmkdir(fc,s,r,m,cvt) int fc; char * s; char ** r; int m; int cvt; {
- int x, rc = -2;
- char tmpbuf[CKMAXPATH+1];
- char buf2[CKMAXPATH+1];
- if (!s) s = "";
- debug(F110,"ckmkdir 1 fc",s,fc);
- if (!*s) {
- ckmakmsg(ckmkdbuf,
- CKMAXPATH+1,
- (fc == 0) ? "mkdir" : "rmdir",
- ": no name given",
- NULL,
- NULL
- );
- *r = ckmkdbuf;
- return(-2);
- }
-#ifdef datageneral
-/* Come back and make this nicer later if anybody notices */
- if (fc == 0) { /* mkdir */
- rc = createdir(s,0);
- } else { /* rmdir */
- /* AOS/VS rmdir() is a no-op. */
- ckmakmsg(tmpbuf,CKMAXPATH+1,"delete ",s,NULL,NULL);
- debug(F110,"ckmkdir 2",tmpbuf,0);
- rc = system(tmpbuf);
- }
- *r = NULL;
-#else /* not datageneral */
-
-/* First make sure the name has an acceptable directory-name format */
-
-#ifdef VMS
- {
- char *p = s;
- int lb = 0, rb = 0, sl = 0;
- while (*p) {
- if (*p == '[' || *p == '<') lb++; /* Count brackets */
- else if (*p == ']' || *p == '>') rb++;
- else if (*p == '/') sl++; /* and slashes */
- p++;
- }
- if (lb != 1 && rb != 1 && sl == 0 && p > s && *(p-1) != ':') {
- /* Probably just a word - convert to VMS format */
- ckmakmsg(buf2,
- CKMAXPATH+1,
- "[",
- (*s == '.') ? "" : ".",
- s,
- "]"
- );
- s = buf2;
- } else if (lb == 0 && rb == 0 && sl != 0 && p > s && *(p-1) != ':') {
- int flag = 0;
- /* Seems to be in UNIX format */
- x = strlen(s);
- if (x > 0 && s[x-1] != '/')
- flag = 1;
- ckmakmsg(buf2,CKMAXPATH+1,s,flag ? "/" : "",NULL,NULL);
- s = buf2;
- }
- if (s == buf2) {
- ckstrncpy(tmpbuf,s,CKMAXPATH+1);
- s = tmpbuf;
- }
- debug(F110,"ckmkdir 2+VMS",s,0);
- }
-#else
-#ifdef UNIXOROSK
-#ifdef DTILDE
- s = tilde_expand(s);
-#endif /* DTILDE */
- ckstrncpy(tmpbuf,s,CKMAXPATH+1);
- s = tmpbuf;
- x = strlen(s);
- if (x > 0 && s[x-1] != '/') { /* Must end in "/" for zmkdir() */
- s[x] = '/';
- s[x+1] = NUL;
- debug(F110,"ckmkdir 2+UNIXOROSK",s,0);
- }
-#else /* UNIXOROSK */
-#ifdef OS2
- ckstrncpy(tmpbuf,s,CKMAXPATH+1);
- s = tmpbuf;
- x = strlen(s);
- if (fc == 0 && x > 0 && s[x-1] != '/') { /* Must end in "/" for zmkdir() */
- s[x] = '/';
- s[x+1] = NUL;
- debug(F110,"ckmkdir 2+OS2",s,0);
- }
-#endif /* OS2 */
-#endif /* UNIXOROSK */
-#endif /* VMS */
-#ifdef NZLTOR
- /* Server is calling us, so convert to local format if necessary */
- if (cvt) {
- nzrtol(s,(char *)buf2,1,PATH_ABS,CKMAXPATH);
- s = buf2;
- debug(F110,"ckmkdir 3",s,0);
- }
-#endif /* NZLTOR */
- debug(F110,"ckmkdir 4",s,0);
- if (fc == 0) { /* Making */
-#ifdef CK_MKDIR
- rc = zmkdir(s);
-#else
-#ifdef NT
- rc = _mkdir(s);
-#else
- rc = mkdir(s,0777);
-#endif /* NT */
-#endif /* CK_MKDIR */
- } else { /* Removing */
-#ifdef ZRMDIR
- rc = zrmdir(s);
-#else
-#ifdef NT
- rc = _rmdir(s);
-#else
-#ifdef OSK
- rc = -2;
-#else
- rc = rmdir(s);
-#endif /* OSK */
-#endif /* NT */
-#endif /* ZRMDIR */
- }
-#endif /* datageneral */
- debug(F101,"ckmkdir rc","",rc);
- if (rc == -2) {
- ckmakmsg(ckmkdbuf,
- CKMAXPATH,
- "Directory ",
- (fc == 0) ? "creation" : "removal",
- "not implemented in this version of C-Kermit",
- NULL
- );
- *r = ckmkdbuf;
- if (m) printf("%s\n",*r);
- } else if (rc < 0) {
- if (m) perror(s);
- ckmakmsg(ckmkdbuf,CKMAXPATH,s,": ",ck_errstr(),NULL);
- *r = ckmkdbuf;
- } else if (fc == 0 && zfnqfp(s,CKMAXPATH,ckmkdbuf)) {
- *r = ckmkdbuf;
- } else if (fc != 0) {
- ckmakmsg(ckmkdbuf,CKMAXPATH,s,": removed",NULL,NULL);
- *r = ckmkdbuf;
- }
- return(rc);
-}
-#endif /* CK_MKDIR */
-
-#ifndef NOXFER /* Rest of this file... */
-
-#ifndef NODISPO
-#ifdef pdp11
-#define NODISPO
-#endif /* pdpd11 */
-#endif /* NODISPO */
-
-extern int pipesend;
-#ifdef PIPESEND
-extern char ** sndfilter;
-#endif /* PIPESEND */
-
-extern int unkcs, wmax, wcur, discard, bctu, bctl, local, fdispla, what,
- sendmode, opnerr, dest, epktrcvd, epktsent, filestatus, eofmethod, dispos,
- fncnv, fnrpath;
-
-extern char * ofn2;
-extern char * rfspec, * sfspec, * prfspec, * psfspec, * rrfspec, * prrfspec;
-extern char ofn1[];
-extern int ofn1x;
-extern char * ofperms;
-
-#ifdef VMS
-extern int batch;
-#else
-extern int backgrd;
-#endif /* VMS */
-
-extern int xflg, remfile, remappd;
-extern CHAR *data;
-extern char filnam[];
-#ifndef NOFRILLS
-extern int rprintf, rmailf; /* REMOTE MAIL, PRINT */
-char optbuf[OPTBUFLEN]; /* Options for MAIL or REMOTE PRINT */
-#endif /* NOFRILLS */
-extern int wslots;
-extern int fblksiz, frecl, forg, frecfm, fncact, fncsav, fcctrl, lf_opts;
-extern CHAR * srvcmd;
-extern int srvcmdlen;
-
-extern int binary, spsiz;
-extern int pktnum, cxseen, czseen, nfils, stdinf;
-extern int memstr, stdouf, keep, sndsrc, hcflg;
-extern int server, en_cwd, en_mai, en_pri;
-
-/* Attributes in/out enabled flags */
-
-extern int
- atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
- attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
-
-#ifdef CK_PERMS
-extern int atlpri, atlpro, atgpri, atgpro;
-#endif /* CK_PERMS */
-
-#ifdef STRATUS
-extern int atfrmi, atfrmo, atcrei, atcreo, atacti, atacto;
-#endif /* STRATUS */
-
-#ifdef datageneral
-extern int quiet;
-#endif /* datageneral */
-
-extern long filcnt;
-extern CK_OFF_T fsize, ffc, tfc, sendstart, calibrate;
-CK_OFF_T rs_len;
-
-#ifndef NOCSETS
-_PROTOTYP (VOID setxlate, (void));
-extern int tcharset, fcharset;
-extern int ntcsets, xlatype, xfrxla;
-extern struct csinfo tcsinfo[], fcsinfo[];
-#endif /* NOCSETS */
-
-/* Variables global to Kermit that are defined in this module */
-
-#ifdef CKXXCHAR /* DOUBLE / IGNORE char table */
-int dblflag = 0;
-int ignflag = 0;
-short dblt[256] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-};
-#endif /* CKXXCHAR */
-
-int winlo; /* packet number at low window edge */
-
-int sbufnum; /* number of free buffers */
-int dum001 = 1234; /* protection... */
-int sbufuse[MAXWS]; /* buffer in-use flag */
-int dum003 = 1111;
-int rbufnum; /* number of free buffers */
-int dum002 = 4321; /* more protection */
-int rbufuse[MAXWS]; /* buffer in-use flag */
-int sseqtbl[64]; /* sequence # to buffer # table */
-int rseqtbl[64]; /* sequence # to buffer # table */
-int sacktbl[64]; /* sequence # ack table */
-
-int o_isopen = 0, i_isopen = 0; /* Input & output files are open */
-
-#ifdef DYNAMIC
-struct pktinfo *s_pkt = NULL; /* array of pktinfo structures */
-struct pktinfo *r_pkt = NULL; /* array of pktinfo structures */
-#else
-struct pktinfo s_pkt[MAXWS]; /* array of pktinfo structures */
-struct pktinfo r_pkt[MAXWS]; /* array of pktinfo structures */
-#endif /* DYNAMIC */
-
-#ifdef DEBUG
-char xbuf[200]; /* For debug logging */
-#endif /* DEBUG */
-
-#ifdef DYNAMIC
-CHAR *bigsbuf = NULL, *bigrbuf = NULL;
-#else
-char bigsbt[8]; /* Protection (shouldn't need this). */
- /* BUT DON'T REMOVE IT! */
-CHAR bigsbuf[SBSIZ + 5]; /* Send-packet buffer area */
-char bigrbt[8]; /* Safety padding */
-CHAR bigrbuf[RBSIZ + 5]; /* Receive-packet area */
-#endif
-int bigsbsiz = SBSIZ; /* Sizes of big send & rcv buffers. */
-int bigrbsiz = RBSIZ;
-
-#ifdef VMS
-int zchkpath(char *s);
-#endif /* VMS */
-
-/* FUNCTIONS */
-
-VOID
-dofast() {
- long maxbufsiz = RBSIZ; /* Configuration parameters */
- int maxpktsiz = MAXSP;
- extern int spsizf, /* For bug in IRIX Telnet server */
- rpsiz, urpsiz, spsizr, spmax, wslotr;
- extern struct ck_p ptab[];
-
- if (maxpktsiz < 40) /* Long packet length */
- maxpktsiz = 40;
- else if (maxpktsiz > 4000)
- maxpktsiz = 4000;
- wslotr = maxbufsiz / maxpktsiz;
- if (wslotr > MAXWS) /* Window slots */
- wslotr = MAXWS;
- if (wslotr > 30)
- wslotr = 30;
- else if (wslotr < 1)
- wslotr = 1;
- urpsiz = adjpkl(maxpktsiz,wslotr,maxbufsiz);
- ptab[PROTO_K].rpktlen = urpsiz;
- rpsiz = (urpsiz > 94) ? 94 : urpsiz; /* Max non-long packet length */
- debug(F111,"dofast","uprsiz",urpsiz);
-#ifdef IRIX
-#ifndef IRIX65
- /* IRIX Telnet server chops off writes longer than 4K */
- spsiz = spmax = spsizr = urpsiz;
- debug(F101,"doarg Q IRIX spsiz","",spsiz);
- spsizf = 1;
-#endif /* IRIX65 */
-#endif /* IRIX */
-#ifdef CK_SPEED
- setprefix(PX_CAU); /* Cautious unprefixing */
-#endif /* CK_SPEED */
-}
-
-
-/* For sanity, use "i" for buffer slots, "n" for packet numbers. */
-
-/* I N I B U F S */
-
-/*
- Allocates the big send and receive buffers.
- Call with size for big send buffer (s) and receive buffer (r).
- These sizes can be different.
- Attempts to allocate buffers of the requested size, but if it can't,
- it will allocate smaller ones.
- Sets global variables bigsbsiz and bigrbsiz to the actual sizes,
- and bigsbuf and bigrbuf pointing to the actual buffers.
- Designed to be called more than once.
- Returns 0 on success, -1 on failure.
-*/
-
-CHAR *bigbufp = NULL;
-
-int
-inibufs(s,r) int s, r; {
-#ifdef DYNAMIC
- unsigned
- int size;
-#ifdef OS2
- unsigned /* Don't you wish everybody had unsigned long... */
-#endif /* OS2 */
- long z;
- int x;
-
- debug(F101,"inibufs s","",s);
- debug(F101,"inibufs r","",r);
-
- if (s < 80 || r < 80) return(-1); /* Validate arguments. */
-
- if (!s_pkt) { /* Allocate packet info structures */
- if (!(s_pkt = (struct pktinfo *) malloc(sizeof(struct pktinfo)*MAXWS)))
- fatal("ini_pkts: no memory for s_pkt");
- }
- for (x = 0; x < MAXWS; x++)
- s_pkt[x].pk_adr = NULL; /* Initialize addresses */
-
- if (!r_pkt) {
- if (!(r_pkt = (struct pktinfo *) malloc(sizeof(struct pktinfo)*MAXWS)))
- fatal("ini_pkts: no memory for s_pkt");
- }
- for (x = 0; x < MAXWS; x++)
- r_pkt[x].pk_adr = NULL; /* Initialize addresses */
-
- if (!srvcmd) { /* Allocate srvcmd buffer */
- srvcmd = (CHAR *) malloc(r + 100);
- if (!srvcmd) return(-1);
- srvcmdlen = r + 99;
- *srvcmd = NUL;
- }
- if (bigbufp) { /* Free previous buffers, if any. */
- free(bigbufp);
- bigbufp = NULL;
- }
- size = s + r + 40; /* Combined requested size + padding */
- z = (unsigned) s + (unsigned) r + 40;
- debug(F101,"inibufs size 1","",size);
- debug(F101,"inibufs size z","",z);
- if ((long) size != z) {
- debug(F100,"inibufs overflow","",0);
- size = 65535;
- }
-
- /* Try to get the space. If malloc fails, try to get a little less. */
- /* (Obviously, this algorithm can be refined.) */
-
- while (!(bigbufp = (CHAR *) malloc(size))) {
- debug(F101,"inibufs bigbuf malloc failed","",size);
- size = (size * 2) / 3; /* Failed, cut size by 1/3. */
- if (size < 200) /* Try again until too small. */
- return(-1);
- }
- debug(F101,"inibufs size 2","",size); /* OK, we got some space. */
-
-/*
- Now divide the allocated space between the send and receive buffers in the
- requested proportion. The natural formula would be (s / (s + r)) * size
- (for the send buffer), but that doesn't work with integer arithmetic and we
- can't use floating point because some machines don't have it. This can be
- rearranged as (s * size) / (s + r). But (s * size) can be VERY large, too
- large for 32 bits. So let's do it this way. This arithmetic works for
- buffer sizes up to about 5,000,000.
-*/
-#define FACTOR 20L
- z = ( (long) s * FACTOR ) / ( (long) s + (long) r );
- x = ( z * ( (long) size / FACTOR ) );
- if (x < 0) return(-1); /* Catch overflow */
-
- bigsbsiz = x - 5; /* Size of send buffer */
- bigsbuf = bigbufp; /* Address of send buffer */
- debug(F101,"inibufs bigsbsiz","",bigsbsiz);
-
- bigrbsiz = size - x - 5; /* Size of receive buffer */
- bigrbuf = bigbufp + x; /* Addresss of receive buffer */
- debug(F101,"inibufs bigrbsiz","",bigrbsiz);
-
- return(0); /* Success */
-#else /* No dynamic allocation */
- bigsbsiz = SBSIZ; /* Just use the symbols */
- bigrbsiz = RBSIZ; /* ... */
- return(0); /* Success. */
-#endif /* DYNAMIC */
-}
-
-
-/* M A K E B U F -- Makes and clears a new buffers. */
-
-/* Call with: */
-/* slots: number of buffer slots to make, 1 to 32 */
-/* bufsiz: size of the big buffer */
-/* buf: address of the big buffer */
-/* xx: pointer to array of pktinfo structures for these buffers */
-
-/* Subdivides the big buffer into "slots" buffers. */
-
-/* Returns: */
-/* -1 if too many or too few slots requested, */
-/* -2 if slots would be too small. */
-/* n (positive) on success = size of one buffer. */
-/* with pktinfo structure initialized for this set of buffers. */
-
-int
-makebuf(slots,bufsiz,buf,xx)
-/* makebuf */ int slots, bufsiz; CHAR buf[]; struct pktinfo *xx; {
-
- CHAR *a;
- int i, size;
-
- debug(F101,"makebuf","",slots);
- debug(F101,"makebuf bufsiz","",bufsiz);
- debug(F101,"makebuf MAXWS","",MAXWS);
-
- if (slots > MAXWS || slots < 1) return(-1);
- if (bufsiz < slots * 10 ) return(-2);
-
- size = bufsiz / slots; /* Divide up the big buffer. */
- a = buf; /* Address of first piece. */
-
- for (i = 0; i < slots; i++) {
- struct pktinfo *x = &xx[i];
- x->bf_adr = a; /* Address of this buffer */
- x->bf_len = size; /* Length of this buffer */
- x->pk_len = 0; /* Length of data field */
- x->pk_typ = ' '; /* packet type */
- x->pk_seq = -1; /* packet sequence number */
- x->pk_rtr = 0; /* retransmissions */
- *a = '\0'; /* Clear the buffer */
- a += size; /* Position to next buffer slot */
- }
- return(size);
-}
-
-/* M A K S B U F -- Makes the send-packet buffer */
-
-int
-mksbuf(slots) int slots; {
- int i, x;
- sbufnum = 0;
- if ((x = makebuf(slots,bigsbsiz,bigsbuf,s_pkt)) < 0) {
- debug(F101,"mksbuf makebuf return","",x);
- return(x);
- }
- debug(F101,"mksbuf makebuf return","",x);
- for (i = 0; i < 64; i++) { /* Initialize sequence-number- */
- sseqtbl[i] = -1; /* to-buffer-number table. */
- sacktbl[i] = 0;
- }
- for (i = 0; i < MAXWS; i++)
- sbufuse[i] = 0; /* Mark each buffer as free */
- sbufnum = slots;
- wcur = 0;
- return(x);
-}
-
-/* M A K R B U F -- Makes the receive-packet buffer */
-
-int
-mkrbuf(slots) int slots; {
- int i, x;
- rbufnum = 0;
- if ((x = makebuf(slots,bigrbsiz,bigrbuf,r_pkt)) < 0) {
- debug(F101,"mkrbuf makebuf return","",x);
- return(x);
- }
- debug(F101,"mkrbuf makebuf return","",x);
- for (i = 0; i < 64; i++) { /* Initialize sequence-number- */
- rseqtbl[i] = -1; /* to-buffer-number table. */
- }
- for (i = 0; i < MAXWS; i++)
- rbufuse[i] = 0; /* Mark each buffer as free */
- rbufnum = slots;
- wcur = 0;
- return(x);
-}
-
-/* W I N D O W -- Resize the window to n */
-
-int
-window(n) int n; {
- debug(F101,"window","",n);
- if (n < 1 || n > MAXWS) return(-1);
- if (mksbuf(n) < 0) return(-1);
- if (mkrbuf(n) < 0) return(-1);
- wslots = n;
-#ifdef DEBUG
- if (deblog) dumpsbuf();
- if (deblog) dumprbuf();
-#endif /* DEBUG */
- return(0);
-}
-
-/* G E T S B U F -- Allocate a send-buffer. */
-
-/* Call with packet sequence number to allocate buffer for. */
-/* Returns: */
-/* -4 if argument is invalid (negative, or greater than 63) */
-/* -3 if buffers were thought to be available but really weren't (bug!) */
-/* -2 if the number of free buffers is negative (bug!) */
-/* -1 if no free buffers. */
-/* 0 or positive, packet sequence number, with buffer allocated for it. */
-
-int
-getsbuf(n) int n; { /* Allocate a send-buffer */
- int i;
- CHAR * p = NULL;
- if (n < 0 || n > 63) {
- debug(F101,"getsbuf bad arg","",n);
- return(-4); /* Bad argument */
- }
- debug(F101,"getsbuf packet","",n);
- /* debug(F101,"getsbuf, sbufnum","",sbufnum); */
- if (sbufnum == 0) return(-1); /* No free buffers. */
- if (sbufnum < 0) return(-2); /* Shouldn't happen. */
- for (i = 0; i < wslots; i++) /* Find the first one not in use. */
- if (sbufuse[i] == 0) { /* Got one? */
- sbufuse[i] = 1; /* Mark it as in use. */
- sbufnum--; /* One less free buffer. */
- *s_pkt[i].bf_adr = '\0'; /* Zero the buffer data field */
- s_pkt[i].pk_seq = n; /* Put in the sequence number */
- sseqtbl[n] = i; /* Back pointer from sequence number */
- sacktbl[n] = 0; /* ACK flag */
- s_pkt[i].pk_len = 0; /* Data field length now zero. */
- s_pkt[i].pk_typ = ' '; /* Blank the packet type too. */
- s_pkt[i].pk_rtr = 0; /* Zero the retransmission count */
- p = s_pkt[i].bf_adr + 7; /* Set global "data" address. */
- debug(F101,"getsbuf p","",0);
- data = p;
- if (!data) {
- debug(F100,"getsbuf data == NULL","",0);
- return(-3);
- }
- if ((what & (W_SEND|W_REMO)) && (++wcur > wmax))
- wmax = wcur; /* For statistics. */
- /* debug(F101,"getsbuf wcur","",wcur); */
- return(n); /* Return its index. */
- }
- sbufnum = 0; /* Didn't find one. */
- return(-3); /* Shouldn't happen! */
-}
-
-int
-getrbuf() { /* Allocate a receive buffer */
- int i;
-#ifdef COMMENT
- /* This code is pretty stable by now... */
- /* Looks like we might need this after all */
- debug(F101,"getrbuf rbufnum","",rbufnum);
- debug(F101,"getrbuf wslots","",wslots);
- debug(F101,"getrbuf dum002","",dum002);
- debug(F101,"getrbuf dum003","",dum003);
-#endif /* COMMENT */
- if (rbufnum == 0) return(-1); /* No free buffers. */
- if (rbufnum < 0) return(-2); /* Shouldn't happen. */
- for (i = 0; i < wslots; i++) /* Find the first one not in use. */
- if (rbufuse[i] == 0) { /* Got one? */
- rbufuse[i] = 1; /* Mark it as in use. */
- *r_pkt[i].bf_adr = '\0'; /* Zero the buffer data field */
- rbufnum--; /* One less free buffer. */
- debug(F101,"getrbuf new rbufnum","",rbufnum);
- if ((what & W_RECV) && (++wcur > wmax))
- wmax = wcur; /* For statistics. */
- /* debug(F101,"getrbuf wcur","",wcur); */
- return(i); /* Return its index. */
- }
- /* debug(F101,"getrbuf foulup","",i); */
- rbufnum = 0; /* Didn't find one. */
- return(-3); /* Shouldn't happen! */
-}
-
-/* F R E E S B U F -- Free send-buffer for given packet sequence number */
-
-/* Returns: */
-/* 1 upon success */
-/* -1 if specified buffer does not exist */
-
-int
-freesbuf(n) int n; { /* Release send-buffer for packet n. */
- int i;
-
- debug(F101,"freesbuf","",n);
- if (n < 0 || n > 63) /* No such packet. */
- return(-1);
- i = sseqtbl[n]; /* Get the window slot number. */
- if (i > -1 && i <= wslots) {
- sseqtbl[n] = -1; /* If valid, remove from seqtbl */
- sbufnum++; /* and count one more free buffer */
- sbufuse[i] = 0; /* and mark it as free, */
- if (what & (W_SEND|W_REMO)) /* decrement active slots */
- wcur--; /* for statistics and display. */
- } else {
- debug(F101," sseqtbl[n]","",sseqtbl[n]);
- return(-1);
- }
-
-/* The following is done only so dumped buffers will look right. */
-
- if (1) {
- *s_pkt[i].bf_adr = '\0'; /* Zero the buffer data field */
- s_pkt[i].pk_seq = -1; /* Invalidate the sequence number */
- s_pkt[i].pk_len = 0; /* Data field length now zero. */
- s_pkt[i].pk_typ = ' '; /* Blank the packet type too. */
- s_pkt[i].pk_rtr = 0; /* And the retries field. */
- }
- return(1);
-}
-
-int
-freerbuf(i) int i; { /* Release receive-buffer slot "i". */
- int n;
-
-/* NOTE !! Currently, this function frees the indicated buffer, but */
-/* does NOT erase the data. The program counts on this. Will find a */
-/* better way later.... */
-
- /* debug(F101,"freerbuf, slot","",i); */
- if (i < 0 || i >= wslots) { /* No such slot. */
- debug(F101,"freerbuf no such slot","",i);
- return(-1);
- }
- n = r_pkt[i].pk_seq; /* Get the packet sequence number */
- debug(F101,"freerbuf packet","",n);
- if (n > -1 && n < 64) /* If valid, remove from seqtbl */
- rseqtbl[n] = -1;
- if (rbufuse[i] != 0) { /* If really allocated, */
- rbufuse[i] = 0; /* mark it as free, */
- rbufnum++; /* and count one more free buffer. */
- if (what & W_RECV) /* Keep track of current slots */
- wcur--; /* for statistics and display */
- debug(F101,"freerbuf rbufnum","",rbufnum);
- }
-
-/* The following is done only so dumped buffers will look right. */
-
- if (1) {
- /* *r_pkt[i].bf_adr = '\0'; */ /* Zero the buffer data field */
- r_pkt[i].pk_seq = -1; /* And from packet list */
- r_pkt[i].pk_len = 0; /* Data field length now zero. */
- r_pkt[i].pk_typ = ' '; /* Blank the packet type too. */
- r_pkt[i].pk_rtr = 0; /* And the retries field. */
- }
- return(1);
-}
-
-/* This is like freerbuf, except it's called with a packet sequence number */
-/* rather than a packet buffer index. */
-
-VOID
-freerpkt(seq) int seq; {
- int k;
- debug(F101,"freerpkt seq","",seq);
- k = rseqtbl[seq];
- /* debug(F101,"freerpkt k","",k); */
- if (k > -1) {
- k = freerbuf(k);
- /* debug(F101,"freerpkt freerbuf","",k); */
- }
-}
-
-
-/* C H K W I N -- Check if packet n is in window. */
-
-/* Returns: */
-/* 0 if it is in the current window, */
-/* +1 if it would have been in previous window (e.g. if ack was lost), */
-/* -1 if it is outside any window (protocol error), */
-/* -2 if either of the argument packet numbers is out of range. */
-
-/* Call with packet number to check (n), lowest packet number in window */
-/* (bottom), and number of slots in window (slots). */
-
-int
-chkwin(n,bottom,slots) int n, bottom, slots; {
- int top, prev;
-
- debug(F101,"chkwin packet","",n);
- debug(F101,"chkwin winlo","",bottom);
- debug(F101,"chkwin slots","",slots);
-
-/* First do the easy and common cases, where the windows are not split. */
-
- if (n < 0 || n > 63 || bottom < 0 || bottom > 63)
- return(-2);
-
- if (n == bottom) return(0); /* In a perfect world... */
-
- top = bottom + slots; /* Calculate window top. */
- if (top < 64 && n < top && n >= bottom)
- return(0); /* In current window. */
-
- prev = bottom - slots; /* Bottom of previous window. */
- if (prev > -1 && n < bottom && n > prev)
- return(1); /* In previous. */
-
-/* Now consider the case where the current window is split. */
-
- if (top > 63) { /* Wraparound... */
- top -= 64; /* Get modulo-64 sequence number */
- if (n < top || n >= bottom) {
- return(0); /* In current window. */
- } else { /* Not in current window. */
- if (n < bottom && n >= prev) /* Previous window can't be split. */
- return(1); /* In previous window. */
- else
- return(-1); /* Not in previous window. */
- }
- }
-
-/* Now the case where current window not split, but previous window is. */
-
- if (prev < 0) { /* Is previous window split? */
- prev += 64; /* Yes. */
- if (n < bottom || n >= prev)
- return(1); /* In previous window. */
- } else { /* Previous window not split. */
- if (n < bottom && n >= prev)
- return(1); /* In previous window. */
- }
-
-/* It's not in the current window, and not in the previous window... */
-
- return(-1); /* So it's not in any window. */
-}
-
-int
-dumpsbuf() { /* Dump send-buffers */
-#ifdef DEBUG
- int j, x, z; /* to debug log. */
-
- if (! deblog) return(0);
- x = zsoutl(ZDFILE,"SEND BUFFERS:");
- if (x < 0) {
- deblog = 0;
- return(0);
- }
- x=zsoutl(ZDFILE,"buffer inuse address length data type seq flag retries");
- if (x < 0) {
- deblog = 0;
- return(0);
- }
- for (j = 0; j < wslots; j++) {
- if (!sbufuse[j])
- continue;
- z = ((unsigned long)(s_pkt[j].bf_adr)) & 0xffff;
-
- sprintf(xbuf, /* safe (200) */
- "%4d%6d%10d%5d%6d%4c%5d%6d\n",
- j,
- sbufuse[j],
- /* Avoid warnings when addresses are bigger than ints */
- z,
- s_pkt[j].bf_len,
- s_pkt[j].pk_len,
- s_pkt[j].pk_typ,
- s_pkt[j].pk_seq,
- s_pkt[j].pk_rtr
- );
- if (zsout(ZDFILE,xbuf) < 0) {
- deblog = 0;
- return(0);
- }
- if (s_pkt[j].pk_adr) {
- x = (int)strlen((char *) s_pkt[j].pk_adr);
- if (x)
- sprintf(xbuf, /* safe (checked) */
- "[%.72s%s]\n",s_pkt[j].pk_adr, x > 72 ? "..." : "");
- else
- sprintf(xbuf,"[(empty string)]\n"); /* safe (200) */
- } else {
- sprintf(xbuf,"[(null pointer)]\n"); /* safe (200) */
- }
- if (zsout(ZDFILE,xbuf) < 0) {
- deblog = 0;
- return(0);
- }
- }
- sprintf(xbuf,"free: %d, winlo: %d\n", sbufnum, winlo); /* safe (200) */
- if (zsout(ZDFILE,xbuf) < 0) {
- deblog = 0;
- return(0);
- }
-#endif /* DEBUG */
- return(0);
-}
-int
-dumprbuf() { /* Dump receive-buffers */
-#ifdef DEBUG
- int j, x, z;
- if (! deblog) return(0);
- if (zsoutl(ZDFILE,"RECEIVE BUFFERS:") < 0) {
- deblog = 0;
- return(0);
- }
- x=zsoutl(ZDFILE,"buffer inuse address length data type seq flag retries");
- if (x < 0) {
- deblog = 0;
- return(0);
- }
- for ( j = 0; j < wslots; j++ ) {
- if (!rbufuse[j])
- continue;
- z = ((unsigned long)(r_pkt[j].bf_adr)) & 0xffff;
- sprintf(xbuf, /* 200, safe */
- "%4d%6d%10d%5d%6d%4c%5d%6d\n",
- j,
- rbufuse[j],
- /* Avoid warnings when addresses are bigger than ints */
- z,
- r_pkt[j].bf_len,
- r_pkt[j].pk_len,
- r_pkt[j].pk_typ,
- r_pkt[j].pk_seq,
- r_pkt[j].pk_rtr
- );
- if (zsout(ZDFILE,xbuf) < 0) {
- deblog = 0;
- return(0);
- }
- x = (int)strlen((char *)r_pkt[j].bf_adr);
- sprintf(xbuf, /* safe (checked) */
- "[%.72s%s]\n",r_pkt[j].bf_adr, x > 72 ? "..." : "");
- if (zsout(ZDFILE,xbuf) < 0) {
- deblog = 0;
- return(0);
- }
- }
- sprintf(xbuf,"free: %d, winlo: %d\n", rbufnum, winlo); /* safe (200) */
- if (zsout(ZDFILE,xbuf) < 0) {
- deblog = 0;
- return(0);
- }
-#endif /* DEBUG */
- return(0);
-}
-
-/* S A T T R -- Send an Attribute Packet */
-
-/*
- Sends attribute packet(s) for the current file. If the info will not
- fit into one packet, it can be called repeatedly until all the fields
- that will fit are sent.
-
- Call with:
- xp == 0 if we're sending a real file (F packet), or:
- xp != 0 for screen data (X packet).
- And:
- flag == 1 for first A packet
- flag == 0 for subsequent A packets.
- Returns:
- 1 or greater if an A packet was sent, or:
- 0 if an S-packet was not sent because there was no data to send or
- there was no data left that was short enough to send, or:
- -1 on any kind of error.
-*/
-
-/* (don't) #define TSOFORMAT */
-/* which was only for making C-Kermit send TSO-Kermit-like A packets */
-/* to try to track down a problem somebody reported... */
-
-int
-sattr(xp, flag) int xp, flag; { /* Send Attributes */
-
- static int max; /* Maximum length for Attributes */
- static short done[95]; /* Field-complete array */
- static struct zattr x; /* File attribute struct */
- static char xdate[24];
-
- extern char * cksysid;
-
- /* Some extra flags are used because the "done" array is sparse */
-
- int i, j, rc, aln, left = 0, numset = 0, xbin = 0; /* Workers */
- int notafile = 0;
- char *tp, c;
-
- notafile = sndarray || pipesend ||
-#ifdef PIPESEND
- sndfilter ||
-#endif /* PIPESEND */
- calibrate;
-
- debug(F101,"sattr flag","",flag);
- if (!flag) /* No more attributes to send */
- if (done[xunchar('@')])
- return(0);
-
- /* Initialize Attribute mechanism */
-
- if (flag) { /* First time here for this file? */
- initattr(&x); /* Blank out all the fields. */
- for (j = 0; j < 95; j++) /* Init array of completed fields */
- done[j] = 0;
- max = maxdata(); /* Get maximum data field length */
- if (notafile || xp == 1) { /* Is it not a real file? */
- extern char * zzndate();
- char * p;
- int i;
-#ifdef CALIBRATE
- if (calibrate) { /* Calibration run... */
- x.lengthk = calibrate / 1024L; /* We know the length */
- x.length = calibrate;
- }
-#endif /* CALIBRATE */
- x.systemid.val = cksysid; /* System ID */
- x.systemid.len = (int)strlen(cksysid);
- ckstrncpy(xdate,zzndate(),24);
- xdate[8] = SP;
- ztime(&p);
- for (i = 11; i < 19; i++) /* copy hh:mm:ss */
- xdate[i - 2] = p[i]; /* to xdate */
- xdate[17] = NUL; /* terminate */
- x.date.val = xdate;
- x.date.len = 17;
- debug(F111,"sattr notafile date",x.date.val,x.date.len);
- } else { /* Real file */
- rc = zsattr(&x); /* Get attributes for this file */
- debug(F101,"sattr zsattr","",rc);
- if (rc < 0) /* Can't get 'em so don't send 'em */
- return(0);
- debug(F101,"sattr init max","",max);
- }
- }
- if (nxtpkt() < 0) /* Got 'em, get next packet number */
- return(-1); /* Bad news if we can't */
-
- i = 0; /* Init data field character number */
-
- /* Do each attribute using first-fit method, marking as we go */
- /* This is rather long and repititious - could be done more cleverly */
-
- if (atsido && !done[xunchar(c = '.')]) { /* System type */
- if (max - i >= x.systemid.len + 2) { /* Enough space ? */
- data[i++] = c; /* Yes, add parameter */
- data[i++] = tochar(x.systemid.len); /* Add length */
- for (j = 0; j < x.systemid.len; j++) /* Add data */
- data[i++] = x.systemid.val[j];
- numset++; /* Count that we did at least one */
- done[xunchar(c)] = 1; /* Mark this attribute as done */
- } else /* No */
- left++; /* so mark this one left to do */
- }
-#ifdef STRATUS
- if (atcreo && !done[xunchar(c = '$')]) { /* Creator */
- if (max - i >= x.creator.len + 2) { /* Enough space ? */
- data[i++] = c;
- data[i++] = tochar(x.creator.len);
- for (j = 0; j < x.creator.len; j++)
- data[i++] = x.creator.val[j];
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
- }
- if (atacto && !done[xunchar(c = '%')]) { /* File account */
- if (max - i >= x.account.len + 2) {
- data[i++] = c;
- data[i++] = tochar(x.account.len);
- for (j = 0; j < x.account.len; j++)
- data[i++] = x.account.val[j];
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
- }
- if (atfrmo && !done[xunchar(c = '/')]) { /* Packet data format */
- if (max - i >= x.recfm.len + 2) {
- data[i++] = c;
- data[i++] = tochar(x.recfm.len); /* Copy from attr structure */
- for (j = 0; j < x.recfm.len; j++)
- data[i++] = x.recfm.val[j];
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
- }
-#endif /* STRATUS */
-
- xbin = /* Is the transfer in binary mode? */
-#ifdef VMS
- binary == XYFT_I || binary == XYFT_L || /* IMAGE or LABELED */
- !strncmp(x.recfm.val,"F",1) /* or RECFM=Fxxxxxx */
-#else
- binary /* User said SET FILE TYPE BINARY */
-#endif /* VMS */
- ;
-
- if (attypo && !done[xunchar(c = '"')]) { /* File type */
- if (max - i >= 5) { /* Max length for this field */
- data[i++] = c;
- if (xbin) { /* Binary */
- data[i++] = tochar(2); /* Two characters */
- data[i++] = 'B'; /* B for Binary */
- data[i++] = '8'; /* 8-bit bytes (note assumption...) */
-#ifdef CK_LABELED
- if (binary != XYFT_L
-#ifdef VMS
- && binary != XYFT_I
-#endif /* VMS */
- )
- binary = XYFT_B;
-#endif /* CK_LABELED */
- } else { /* Text */
-#ifdef TSOFORMAT
- data[i++] = tochar(1); /* One character */
- data[i++] = 'A'; /* A = (extended) ASCII with CRLFs */
-#else
- data[i++] = tochar(3); /* Three characters */
- data[i++] = 'A'; /* A = (extended) ASCII with CRLFs */
- data[i++] = 'M'; /* M for carriage return */
- data[i++] = 'J'; /* J for linefeed */
-#endif /* TSOFORMAT */
-
-#ifdef VMS
- binary = XYFT_T; /* We automatically detected text */
-#endif /* VMS */
- }
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
- }
-
-#ifdef TSOFORMAT
- if (attypo && !xbin && !done[xunchar(c = '/')]) { /* Record format */
- if (max - i >= 5) {
- data[i++] = c;
- data[i++] = tochar(3); /* Three characters */
- data[i++] = 'A'; /* A = variable with CRLFs */
- data[i++] = 'M'; /* M for carriage return */
- data[i++] = 'J'; /* J for linefeed */
- }
- }
-#endif /* TSOFORMAT */
-
- if (attypo && !xbin && !done[xunchar(c = '*')]) { /* Text encoding */
-#ifdef NOCSETS
- if (max - i >= 3) {
- data[i++] = c;
- data[i++] = tochar(1); /* Length of value is 1 */
- data[i++] = 'A'; /* A for ASCII */
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
-#else
- if (tcharset == TC_TRANSP || !xfrxla) { /* Transfer character set */
- if (max - i >= 3) {
- data[i++] = c; /* Encoding */
- data[i++] = tochar(1); /* Length of value is 1 */
- data[i++] = 'A'; /* A for ASCII (i.e. text) */
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
- } else {
- tp = tcsinfo[tcharset].designator;
- if (!tp) tp = "";
- aln = strlen(tp);
- if (aln > 0) {
- if (max - i >= aln + 2) {
- data[i++] = c; /* Encoding */
- data[i++] = tochar(aln+1); /* Length of designator. */
- data[i++] = 'C'; /* Text in specified charset. */
- for (j = 0; j < aln; j++) /* Copy designator */
- data[i++] = *tp++; /* Example: *&I6/100 */
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
- } else
- done[xunchar(c)] = 1;
- }
-#endif /* NOCSETS */
- }
- if (atdato && !done[xunchar(c = '#')] && /* Creation date, if any */
- (aln = x.date.len) > 0) {
- if (max - i >= aln + 2) {
- data[i++] = c;
- data[i++] = tochar(aln);
- for (j = 0; j < aln; j++)
- data[i++] = x.date.val[j];
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
- }
- /* File length in K */
- if (atleno && !done[xunchar(c = '!')] && x.lengthk > (CK_OFF_T)-1) {
-#ifdef COMMENT
- sprintf((char *) &data[i+2],"%ld",x.lengthk); /* safe */
-#else
- ckstrncpy((char *)&data[i+2],ckfstoa(x.lengthk),32);
-#endif /* COMMENT */
- aln = (int)strlen((char *)(data+i+2));
- if (max - i >= aln + 2) {
- data[i] = c;
- data[i+1] = tochar(aln);
- i += aln + 2;
- numset++;
- done[xunchar(c)] = 1;
- } else {
- data[i] = NUL;
- left++;
- }
- }
- /* File length in bytes */
- if (atleno && !done[xunchar(c = '1')] && x.length > (CK_OFF_T)-1) {
-#ifdef COMMENT
- sprintf((char *) &data[i+2],"%ld",x.length); /* safe */
-#else
- ckstrncpy((char *)&data[i+2],ckfstoa(x.length),32);
-#endif /* COMMENT */
- aln = (int)strlen((char *)(data+i+2));
- if (max - i >= aln + 2) {
- data[i] = c;
- data[i+1] = tochar(aln);
- i += aln + 2;
- numset++;
- done[xunchar(c)] = 1;
- } else {
- data[i] = NUL;
- left++;
- }
- }
-#ifdef CK_PERMS
- if (atlpro && !done[xunchar(c = ',')] && /* Local protection */
- (aln = x.lprotect.len) > 0 && !notafile && xp == 0) {
- if (max - i >= aln + 2) {
- data[i++] = c;
- data[i++] = tochar(aln);
- for (j = 0; j < aln; j++)
- data[i++] = x.lprotect.val[j];
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
- }
- if (atgpro && !done[xunchar(c = '-')] && /* Generic protection */
- (aln = x.gprotect.len) > 0 && !notafile && xp == 0) {
- if (max - i >= aln + 2) {
- data[i++] = c;
- data[i++] = tochar(aln);
- for (j = 0; j < aln; j++)
- data[i++] = x.gprotect.val[j];
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
- }
-#endif /* CK_PERMS */
- if (atblko && fblksiz && !done[xunchar(c = '(')] &&
- !notafile && xp == 0) { /* Blocksize */
- sprintf((char *) &data[i+2],"%d",fblksiz); /* safe */
- aln = (int)strlen((char *)(data+i+2));
- if (max - i >= aln + 2) {
- data[i] = c;
- data[i+1] = tochar(aln);
- i += aln + 2;
- numset++;
- done[xunchar(c)] = 1;
- } else {
- data[i] = NUL;
- left++;
- }
- }
-#ifndef NOFRILLS
- if ((rprintf || rmailf) && atdiso && /* MAIL, or REMOTE PRINT? */
- !done[xunchar(c = '+')]) {
- aln = (int) strlen(optbuf) + 1; /* Options, if any */
- if (max - i >= aln + 2) {
- data[i++] = c; /* Disposition */
- data[i++] = tochar(aln); /* Options, if any */
- if (rprintf)
- data[i++] = 'P'; /* P for Print */
- else
- data[i++] = 'M'; /* M for Mail */
- for (j = 0; optbuf[j]; j++) /* Copy any options */
- data[i++] = optbuf[j];
- numset++;
- done[xunchar(c)] = 1;
- } else {
- data[i] = NUL;
- left++;
- }
- }
-#endif /* NOFRILLS */
-#ifdef CK_RESEND
- if (sendmode == SM_RESEND && !done[xunchar(c = '+')]) {
- if (max - i >= 3) {
- data[i++] = c; /* Disposition */
- data[i++] = tochar(1);
- data[i++] = 'R'; /* is RESEND */
- numset++;
- done[xunchar(c)] = 1;
- } else
- left++;
- }
-#endif /* CK_RESEND */
-
- /* End of Attributes -- to be sent only after sending all others */
-
- debug(F111,"sattr","@",i);
- debug(F101,"sattr numset","",numset);
- debug(F101,"sattr left","",left);
-
- if ((left == 0 || numset == 0) && !done[xunchar(c = '@')]) {
- if (max - i >= 3) {
- data[i++] = c; /* End of Attributes */
- data[i++] = SP; /* Length 0 */
- data[i] = NUL; /* Make sure it's null-terminated */
- numset++;
- done[xunchar(c)] = 1;
- }
- }
-
- /* Finished - send the packet off if we have anything in it */
-
- if (numset) {
- data[i] = NUL; /* Terminate last good field */
- debug(F111,"sattr sending",data,left);
- aln = (int)strlen((char *)data); /* Get overall length of attributes */
- return(spack('A',pktnum,aln,data)); /* Send it */
- } else
- return(0);
-}
-
-static char *refused = "";
-
-static char *reason[] = {
- "size", "type", "date", "creator", "account", "area", "password",
- "blocksize", "access", "encoding", "disposition", "protection",
- "protection", "origin", "format",
- "sys-dependent", /* 0 */
- "size", /* 1 */
- "2", /* 2 */
- "3", /* 3 */
- "4", /* 4 */
- "5", /* 5 */
- "6", /* 6 */
- "7", /* 7 */
- "8", /* 8 */
- "9", /* 9 */
- ":", /* : */
- ";", /* ; */
- "<", /* < */
- "=", /* = */
- ">", /* > */
- "name", /* ? */
- "@"
-};
-static int nreason = sizeof(reason) / sizeof(char *);
-int rejection = -1;
-
-char *
-getreason(s) char *s; { /* Decode attribute refusal reason */
- char c, *p;
- if (rejection == 1) /* Kludge for SET FIL COLL DISCARD */
- return("name"); /* when other Kermit doesn't... */
- p = s;
- if (*p++ != 'N') return(""); /* Should start with N */
- else if ((c = *p) > SP) { /* get reason, */
- rejection = c; /* remember it, */
- c -= '!'; /* get offset */
- p = ((unsigned int) ((CHAR) c) <= (unsigned int) nreason) ?
- reason[c] :
- "unknown";
- }
- return(p);
-}
-
-int
-rsattr(s) CHAR *s; { /* Read response to attribute packet */
- debug(F111,"rsattr",s,*s);
- if (*s == 'N') { /* If it's 'N' followed by anything, */
- refused = getreason((char *)s); /* they are refusing, get reason. */
- debug(F110,"rsattr refused",refused,0);
- tlog(F110," refused:",refused,0L);
- return(-1);
- }
-#ifdef CK_RESEND
- if (sendmode == SM_RESEND && *s == '1') { /* RESEND length */
- int n; CK_OFF_T z; CHAR *p;
- p = s + 1;
- n = xunchar(*p++);
- debug(F101,"rsattr RESEND n","",n);
- z = (CK_OFF_T)0;
- while (n-- > 0) /* We assume the format is good. */
- z = (CK_OFF_T)10 * z + (CK_OFF_T)(*p++ - '0');
- debug(F101,"rsattr RESEND z","",z);
- if (z > (CK_OFF_T)0) sendstart = z;
- debug(F101,"rsattr RESEND sendstart","",sendstart);
- if (sendstart > (CK_OFF_T)0)
- if (zfseek(sendstart) < 0) /* Input file is already open. */
- return(0);
-#ifdef CK_CURSES
- if (fdispla == XYFD_C)
- xxscreen(SCR_FS,0,fsize,""); /* Refresh file transfer display */
-#endif /* CK_CURSES */
- }
-#endif /* CK_RESEND */
- refused = "";
- return(0);
-}
-
-/*
- Get attributes from incoming A packet. Returns:
- 0 on success, file is to be accepted
- -1 on failure, file is to be refused
-*/
-int
-gattr(s, yy) CHAR *s; struct zattr *yy; { /* Read incoming attribute packet */
- char c, d;
- char *ff;
- int aln, i, overflow = 0;
-
-#ifndef NOCSETS
- extern int r_cset, axcset[];
-#endif /* NOCSETS */
-
-#define ABUFL 40 /* Temporary buffer for conversions */
- char abuf[ABUFL+1];
-#define RFBUFL 10 /* Record-format buffer */
- static char rfbuf[RFBUFL+1];
-#define FTBUFL 10 /* File type buffer */
- static char ftbuf[FTBUFL+1];
-#define DTBUFL 40 /* File creation date */
- static char dtbuf[DTBUFL+1];
-#define TSBUFL 10 /* Transfer syntax */
- static char tsbuf[TSBUFL+1];
-#define IDBUFL 10 /* System ID */
- static char idbuf[IDBUFL+1];
-#ifndef DYNAMIC
-#define DSBUFL 100 /* Disposition */
- static char dsbuf[DSBUFL+1];
-#define SPBUFL 512 /* System-dependent parameters */
- static char spbuf[SPBUFL+1];
-#else
-#define DSBUFL 100 /* Disposition */
- static char *dsbuf = NULL;
-#define SPBUFL 512 /* System-dependent parameters */
- static char *spbuf = NULL;
-#endif /* DYNAMIC */
-#define RPBUFL 20 /* Attribute reply */
- static char rpbuf[RPBUFL+1];
-
-#ifdef CK_PERMS
- static char lprmbuf[CK_PERMLEN+1];
- static char gprmbuf[2];
-#endif /* CK_PERMS */
-
- char *rp; /* Pointer to reply buffer */
- int retcode; /* Return code */
-
- d = SP; /* Initialize disposition */
- ff = filnam; /* Filename returned by rcvfil */
- if (fncact == XYFX_R && ofn1x && ofn1[0]) /* But watch out for FC=RENAME */
- ff = ofn1; /* because we haven't renamed it yet */
-
-/* Fill in the attributes we have received */
-
- rp = rpbuf; /* Initialize reply buffer */
- *rp++ = 'N'; /* for negative reply. */
- *rp = NUL;
- retcode = 0; /* Initialize return code. */
-
- if (dest == DEST_P) { /* SET DESTINATION PRINTER */
-#ifdef DYNAMIC
- if (!dsbuf)
- if ((dsbuf = malloc(DSBUFL+1)) == NULL)
- fatal("gtattr: no memory for dsbuf");
-#endif /* DYNAMIC */
- dsbuf[0] = 'P';
- dsbuf[1] = '\0';
- yy->disp.val = dsbuf;
- yy->disp.len = 1;
- }
- while (c = *s++) { /* Get attribute tag */
- aln = xunchar(*s++); /* Length of attribute string */
- switch (c) {
-#ifdef COMMENT /* This case combined with '1' below */
- case '!': /* File length in K */
- for (i = 0; (i < aln) && (i < ABUFL); i++) /* Copy it */
- abuf[i] = *s++;
- abuf[i] = '\0'; /* Terminate with null */
- if (i < aln) s += (aln - i); /* If field was too long for buffer */
- yy->lengthk = ckatofs(abuf); /* Convert to number */
- break;
-#endif /* COMMENT */
-
- case '/': /* Record format */
- rfbuf[1] = NUL;
- rfbuf[2] = NUL;
- for (i = 0; (i < aln) && (i < RFBUFL); i++) /* Copy it */
- rfbuf[i] = *s++;
- rfbuf[i] = NUL; /* Terminate with null */
- yy->recfm.val = rfbuf; /* Pointer to string */
- yy->recfm.len = i; /* Length of string */
- if ((rfbuf[0] != 'A') ||
- (rfbuf[1] && rfbuf[1] != 'M') ||
- (rfbuf[2] && rfbuf[2] != 'J')) {
- debug(F110,"gattr bad recfm",rfbuf,0);
- *rp++ = c;
- retcode = -1;
- }
- break;
-
- case '"': /* File type (text, binary, ...) */
- for (i = 0; (i < aln) && (i < FTBUFL); i++)
- ftbuf[i] = *s++; /* Copy it into a static string */
- ftbuf[i] = '\0';
- if (i < aln) s += (aln - i);
- /* TYPE attribute is enabled? */
- if (attypi) {
- yy->type.val = ftbuf; /* Pointer to string */
- yy->type.len = i; /* Length of string */
- debug(F111,"gattr file type", ftbuf, i);
- debug(F101,"gattr binary 1","",binary);
- /* Unknown type? */
- if ((*ftbuf != 'A' && *ftbuf != 'B' && *ftbuf != 'I')
-#ifdef CK_LABELED
-/* ... Or our FILE TYPE is LABELED and the incoming file is text... */
- || (binary == XYFT_L && *ftbuf == 'A' && !xflg)
-#endif /* CK_LABELED */
- ) {
- retcode = -1; /* Reject the file */
- *rp++ = c;
- if (!opnerr) tlog(F100," refused: type","",0);
- break;
- }
-/*
- The following code moved here from opena() so we set binary mode
- as soon as requested by the attribute packet. That way when the first
- data packet comes, the mode of transfer can be displayed correctly
- before opena() is called.
-*/
- if (yy->type.val[0] == 'A') { /* Check received attributes. */
-#ifdef VMS
- if (binary != XYFT_I) /* VMS IMAGE overrides this */
-#endif /* VMS */
- binary = XYFT_T; /* Set current type to Text. */
- debug(F101,"gattr binary 2","",binary);
- } else if (yy->type.val[0] == 'B') {
-#ifdef CK_LABELED
- if (binary != XYFT_L
-#ifdef VMS
- && binary != XYFT_U /* VMS special case */
-#endif /* VMS */
- )
-#endif /* CK_LABELED */
-#ifdef MAC
- if (binary != XYFT_M) /* If not MacBinary... */
-#endif /* MAC */
- binary = XYFT_B;
- debug(F101,"gattr binary 3","",binary);
- }
- }
- break;
-
- case '#': /* File creation date */
- for (i = 0; (i < aln) && (i < DTBUFL); i++)
- dtbuf[i] = *s++; /* Copy it into a static string */
- if (i < aln) s += (aln - i);
- dtbuf[i] = '\0';
- if (atdati && !xflg) { /* Real file and dates enabled */
- yy->date.val = dtbuf; /* Pointer to string */
- yy->date.len = i; /* Length of string */
- if (fncact == XYFX_U) { /* Receiving in update mode? */
- if (zstime(ff,yy,1) > 0) { /* Compare dates */
- *rp++ = c; /* Discard if older, reason = date. */
- if (!opnerr) tlog(F100," refused: date","",0);
- retcode = -1; /* Rejection notice. */
- }
- }
- }
- break;
-
- case '(': /* File Block Size */
- for (i = 0; (i < aln) && (i < ABUFL); i++) /* Copy it */
- abuf[i] = *s++;
- abuf[i] = '\0'; /* Terminate with null */
- if (i < aln) s += (aln - i);
- if (atblki)
- yy->blksize = atol(abuf); /* Convert to number */
- break;
-
- case '*': /* Encoding (transfer syntax) */
- for (i = 0; (i < aln) && (i < TSBUFL); i++)
- tsbuf[i] = *s++; /* Copy it into a static string */
- if (i < aln) s += (aln - i);
- tsbuf[i] = '\0';
-#ifndef NOCSETS
- xlatype = XLA_NONE; /* Assume no translation */
-#endif /* NOCSETS */
- if (atenci) {
- char * ss;
- yy->encoding.val = tsbuf; /* Pointer to string */
- yy->encoding.len = i; /* Length of string */
- debug(F101,"gattr encoding",tsbuf,i);
- ss = tsbuf+1;
- switch (*tsbuf) {
-#ifndef NOCSETS
- case 'A': /* Normal, nothing special */
- tcharset = TC_TRANSP; /* Transparent chars untranslated */
- debug(F110,"gattr sets tcharset TC_TRANSP","A",0);
- break;
- case 'C': /* Specified character set */
- if (!xfrxla) { /* But translation disabled */
- tcharset = TC_TRANSP;
- debug(F110,"gattr sets tcharset TC_TRANSP","C",0);
- break;
- }
-#ifdef UNICODE
- if (!strcmp("I196",ss)) /* Treat I196 (UTF-8 no level) */
- ss = "I190"; /* as I190 (UTF-8 Level 1) */
-#endif /* UNICODE */
- if (!strcmp("I6/204",ss)) /* Treat "Latin-1 + Euro" */
- ss = "I6/100"; /* as I6/100 (regular Latin-1) */
- for (i = 0; i < ntcsets; i++) {
- if (!strcmp(tcsinfo[i].designator,ss))
- break;
- }
- debug(F101,"gattr xfer charset lookup","",i);
- if (i == ntcsets) { /* If unknown character set, */
- debug(F110,"gattr: xfer charset unknown",ss,0);
- if (!unkcs) { /* and SET UNKNOWN DISCARD, */
- retcode = -1; /* reject the file. */
- *rp++ = c;
- if (!opnerr)
- tlog(F100," refused: character set","",0);
- }
- } else {
- tcharset = tcsinfo[i].code; /* it's known, use it */
- debug(F101,"gattr switch tcharset","",tcharset);
- debug(F101,"gattr fcharset","",fcharset);
- if (r_cset == XMODE_A) { /* Automatic switching? */
- if (tcharset > -1 && tcharset <= MAXTCSETS) {
- int x;
- x = axcset[tcharset];
- if (x > 0 && x <= MAXFCSETS) {
- fcharset = x;
- debug(F101,"gattr switch fcharset","",x);
- }
- }
- }
- /* Set up translation type and function */
- setxlatype(tcharset,fcharset);
- }
- break;
-#endif /* NOCSETS */
- default: /* Something else. */
- debug(F110,"gattr unk encoding attribute",tsbuf,0);
- if (!unkcs) { /* If SET UNK DISC */
- retcode = -1;
- *rp++ = c;
- if (!opnerr) tlog(F100," refused: encoding","",0);
- }
- break;
- }
- }
- break;
-
- case '+': /* Disposition */
-#ifdef DYNAMIC
- if (!dsbuf)
- if ((dsbuf = malloc(DSBUFL+1)) == NULL)
- fatal("gtattr: no memory for dsbuf");
-#endif /* DYNAMIC */
- for (i = 0; (i < aln) && (i < DSBUFL); i++)
- dsbuf[i] = *s++; /* Copy it into a separate string */
- dsbuf[i] = '\0';
- if (i < aln) s += (aln - i);
- rs_len = (CK_OFF_T)0;
- if (atdisi) { /* We are doing this attribute */
- /* Copy it into the attribute structure */
- yy->disp.val = dsbuf; /* Pointer to string */
- yy->disp.len = i; /* Length of string */
- d = *dsbuf;
-#ifndef NODISPO
-/*
- Define NODISPO to disable receipt of mail or print files and of RESEND.
-*/
- if (
-#ifndef datageneral /* MAIL supported only for */
-#ifndef OS2 /* UNIX, VMS, and OS-9 */
-#ifndef MAC
-#ifndef GEMDOS
-#ifndef AMIGA
- d != 'M' && /* MAIL */
-#endif /* AMIGA */
-#endif /* GEMDOS */
-#endif /* MAC */
-#endif /* OS/2 */
-#endif /* datageneral */
-#ifdef CK_RESEND
- d != 'R' && /* RESEND */
-#endif /* CK_RESEND */
- d != 'P') { /* PRINT */
- retcode = -1; /* Unknown/unsupported disposition */
- *rp++ = c;
- if (!opnerr) tlog(F101," refused: bad disposition","",d);
- }
- dispos = d;
- debug(F000,"gattr dispos","",dispos);
- switch (d) {
-#ifndef NOFRILLS
- case 'M':
- if (!en_mai) {
- retcode = -1;
- *rp++ = c;
- if (!opnerr) tlog(F100," refused: mail disabled","",0);
- dispos = 0;
- }
- break;
-#endif /* NOFRILLS */
- case 'P':
- if (!en_pri) {
- retcode = -1;
- *rp++ = c;
- if (!opnerr)
- tlog(F100," refused: print disabled","",0);
- dispos = 0;
- }
- break;
-
- case 'R':
- dispos = 0;
-#ifdef CK_RESEND
- rs_len = zgetfs(ff); /* Get length of file */
- debug(F111,"gattr RESEND",ff,rs_len);
-#ifdef VMS
- rs_len &= (long) -512; /* Ensure block boundary if VMS */
- rs_len -= 512; /* In case last block not complete */
- debug(F111,"gattr rs_len",ff,rs_len);
-#endif /* VMS */
-#ifdef COMMENT
- if (rs_len < 0L) /* Local file doesn't exist */
- rs_len = 0L;
-#endif /* COMMENT */
-/*
- Another possibility here (or later, really) would be to check if the two
- file lengths are the same, and if so, keep the prevailing collision action
- as is (note: rs_len == length of existing file; yy->length == fsize ==
- length of incoming file). This could be complicated, though, since
- (a) we might not have received the length attribute yet, and in fact it
- might even be in a subsequent A-packet, yet (b) we have to accept or reject
- the Recover attribute now. So better to leave as-is. Anyway, it's probably
- more useful this way.
-*/
- if (rs_len > (CK_OFF_T)0) {
- fncsav = fncact; /* Save collision action */
- fncact = XYFX_A; /* Switch to APPEND */
- }
-#else
- retcode = -1; /* This shouldn't happen */
- *rp++ = c; /* 'cause it wasn't negotiated. */
- if (!opnerr) tlog(F100," refused: resend","",0);
-#endif /* CK_RESEND */
- }
-#else /* NODISPO */
- retcode = -1;
- *rp++ = c;
- if (!opnerr) tlog(F100," refused: NODISPO","",0);
-#endif /* NODISPO */
- }
- break;
-
- case '.': /* Sender's system ID */
- for (i = 0; (i < aln) && (i < IDBUFL); i++)
- idbuf[i] = *s++; /* Copy it into a static string */
- idbuf[i] = '\0';
- if (i < aln) s += (aln - i);
- if (atsidi) {
- yy->systemid.val = idbuf; /* Pointer to string */
- yy->systemid.len = i; /* Length of string */
- }
- break;
-
- case '0': /* System-dependent parameters */
-#ifdef DYNAMIC
- if (!spbuf && !(spbuf = malloc(SPBUFL)))
- fatal("gattr: no memory for spbuf");
-#endif /* DYNAMIC */
- for (i = 0; (i < aln) && (i < SPBUFL); i++)
- spbuf[i] = *s++; /* Copy it into a static string */
- spbuf[i] = '\0';
- if (i < aln) s += (aln - i);
- if (atsysi) {
- yy->sysparam.val = spbuf; /* Pointer to string */
- yy->sysparam.len = i; /* Length of string */
- }
- break;
-
- case '!': /* File length in K */
- case '1': { /* File length in bytes */
- char * l2;
- CK_OFF_T xlen;
- for (i = 0; (i < aln) && (i < ABUFL); i++) /* Copy it */
- abuf[i] = *s++;
- abuf[i] = '\0'; /* Terminate with null */
- if (i < aln) s += (aln - i);
- if (rdigits(abuf)) { /* Make sure string is all digits */
- xlen = ckatofs(abuf); /* Convert to number */
- l2 = ckfstoa(xlen); /* Convert number back to string */
- if (c == '1')
- debug(F111,"gattr length",abuf,xlen);
- else
- debug(F111,"gattr lengthk",abuf,xlen);
- if (ckstrcmp(abuf,l2,-1,1)) { /* This is how we check... */
- xlen = (CK_OFF_T)-2; /* -2 = unk, possibly too long */
- overflow++;
- debug(F111,"gattr overflow",
- (c == '1') ? "length" : "lengthk",
- xlen);
- }
- if (c == '1') {
- yy->length = xlen;
- debug(F101,"gattr length","",xlen);
- } else {
- yy->lengthk = xlen;
- debug(F101,"gattr lengthk","",xlen);
- }
- }
- /* If the length field is not numeric accept the file */
- /* anyway but with an unknown length */
- break;
- }
-
-#ifdef CK_PERMS
- case ',': /* System-dependent protection code */
- for (i = 0; (i < aln) && (i < CK_PERMLEN); i++)
- lprmbuf[i] = *s++; /* Just copy it - decode later */
- lprmbuf[i] = '\0'; /* Terminate with null */
- if (i < aln) s += (aln - i);
- if (atlpri) {
- yy->lprotect.val = (char *)lprmbuf;
- yy->lprotect.len = i;
- } else
- lprmbuf[0] = NUL;
- break;
-
- case '-': /* Generic "world" protection code */
- gprmbuf[0] = NUL; /* Just 1 byte by definition */
- for (i = 0; i < aln; i++) /* But allow for more... */
- if (i == 0) gprmbuf[0] = *s++;
- gprmbuf[1] = NUL;
- if (atgpri) {
- yy->gprotect.val = (char *)gprmbuf;
- yy->gprotect.len = gprmbuf[0] ? 1 : 0;
- } else
- gprmbuf[0] = NUL;
- break;
-#endif /* CK_PERMS */
-
- default: /* Unknown attribute */
- s += aln; /* Just skip past it */
- break;
- }
- }
-
- /* Check space now, because we also need to know the file type */
- /* in case zchkspa() differentiates text and binary (VMS version does) */
-
- if (atleni && !calibrate) { /* Length attribute enabled? */
- if (yy->length > (CK_OFF_T)-1) { /* Length-in-bytes attribute rec'd? */
- if (!zchkspa(ff,(yy->length))) { /* Check space */
- retcode = -1; /* Not enuf */
- *rp++ = '1';
- if (!opnerr) tlog(F100," refused: length bytes","",0);
- }
- } else if (yy->lengthk > (CK_OFF_T)-1) { /* Length in K received? */
- long xlen;
- xlen = yy->lengthk * 1024;
- if (!zchkspa(ff,xlen)) {
- retcode = -1; /* Check space */
- *rp++ = '!';
- if (!opnerr) tlog(F100," refused: length K","",0);
- }
- }
- }
- if (retcode > -1L) { /* Remember the file size */
- if (yy->length > (CK_OFF_T)-1) {
- fsize = yy->length;
- } else if (yy->lengthk > (CK_OFF_T)-1 && !overflow) {
- fsize = yy->lengthk * 1024L;
- } else fsize = yy->length; /* (e.g. -2L) */
- }
-
-#ifdef DEBUG
- if (deblog) {
-#ifdef COMMENT
- sprintf(abuf,"%ld",fsize); /* safe */
-#else
- ckstrncpy(abuf,ckfstoa(fsize),ABUFL);
-#endif /* COMMENT */
-debug(F110,"gattr fsize",abuf,0);
- }
-#endif /* DEBUG */
-
- if (retcode == 0) rp = rpbuf; /* Null reply string if accepted */
- *rp = '\0'; /* End of reply string */
-
-#ifdef CK_RESEND
- if (d == 'R') { /* Receiving a RESEND? */
- debug(F101,"gattr RESEND","",retcode);
- /* We ignore retcodes because this overrides */
- if (binary != XYFT_B) { /* Reject if not binary */
- retcode = -1; /* in case type field came */
- ckstrncpy(rpbuf,"N+",RPBUFL); /* after the disposition field */
- debug(F111,"gattr RESEND not binary",rpbuf,binary);
- } else { /* Binary mode */
- retcode = 0; /* Accept the file */
- discard = 0; /* If SET FILE COLLISION DISCARD */
-#ifdef COMMENT
- sprintf(rpbuf+2,"%ld",rs_len); /* Reply with length of file */
-#else
- ckstrncpy(rpbuf+2,ckfstoa(rs_len),RPBUFL-2);
-#endif /* COMMENT */
- rpbuf[0] = '1'; /* '1' means Length in Bytes */
- rpbuf[1] = tochar((int)strlen(rpbuf+2)); /* Length of length */
- debug(F111,"gattr RESEND OK",rpbuf,retcode);
- }
- }
-#endif /* CK_RESEND */
- if (retcode == 0 && discard != 0) { /* Do we still have a discard flag? */
- ckstrncpy(rpbuf,"N?",RPBUFL); /* Yes, must be filename collision */
- retcode = -1; /* "?" = name (reply-only code) */
- }
- yy->reply.val = rpbuf; /* Add it to attribute structure */
- yy->reply.len = (int)strlen(rpbuf);
- if (retcode < 0) { /* If we are rejecting */
- discard = 1; /* remember to discard the file */
- rejection = rpbuf[1]; /* and use the first reason given. */
- if (fncsav != -1) {
- fncact = fncsav;
- fncsav = -1;
- }
- }
- debug(F111,"gattr return",rpbuf,retcode);
- return(retcode);
-}
-
-/* I N I T A T T R -- Initialize file attribute structure */
-
-int
-initattr(yy) struct zattr *yy; {
- yy->lengthk = yy->length = (CK_OFF_T)-1;
- yy->type.val = "";
- yy->type.len = 0;
- yy->date.val = "";
- yy->date.len = 0;
- yy->encoding.val = "";
- yy->encoding.len = 0;
- yy->disp.val = "";
- yy->disp.len = 0;
- yy->systemid.val = "";
- yy->systemid.len = 0;
- yy->sysparam.val = "";
- yy->sysparam.len = 0;
- yy->creator.val = "";
- yy->creator.len = 0;
- yy->account.val = "";
- yy->account.len = 0;
- yy->area.val = "";
- yy->area.len = 0;
- yy->password.val = "";
- yy->password.len = 0;
- yy->blksize = -1L;
- yy->xaccess.val = "";
- yy->xaccess.len = 0;
-#ifdef CK_PERMS
- if (!ofperms) ofperms = "";
- debug(F110,"initattr ofperms",ofperms,0);
- yy->lprotect.val = ofperms;
- yy->lprotect.len = 0 - strlen(ofperms); /* <-- NOTE! */
- /*
- A negative length indicates that we have a permissions string but it has
- been inherited from a previously existing file rather than picked up
- from an incoming A-packet.
- */
-#else
- yy->lprotect.val = "";
- yy->lprotect.len = 0;
-#endif /* CK_PERMS */
- yy->gprotect.val = "";
- yy->gprotect.len = 0;
- yy->recfm.val = "";
- yy->recfm.len = 0;
- yy->reply.val = "";
- yy->reply.len = 0;
-#ifdef OS2
- yy->longname.len = 0 ;
- yy->longname.val = "" ;
-#endif /* OS2 */
- return(0);
-}
-
-/* A D E B U -- Write attribute packet info to debug log */
-
-int
-adebu(f,zz) char *f; struct zattr *zz; {
-#ifdef DEBUG
- if (deblog == 0) return(0);
- debug(F110,"Attributes for incoming file ",f,0);
- debug(F101," length in K","",(int) zz->lengthk);
- debug(F111," file type",zz->type.val,zz->type.len);
- debug(F111," creation date",zz->date.val,zz->date.len);
- debug(F111," creator",zz->creator.val,zz->creator.len);
- debug(F111," account",zz->account.val,zz->account.len);
- debug(F111," area",zz->area.val,zz->area.len);
- debug(F111," password",zz->password.val,zz->password.len);
- debug(F101," blksize","",(int) zz->blksize);
- debug(F111," access",zz->xaccess.val,zz->xaccess.len);
- debug(F111," encoding",zz->encoding.val,zz->encoding.len);
- debug(F111," disposition",zz->disp.val,zz->disp.len);
- debug(F111," lprotection",zz->lprotect.val,zz->lprotect.len);
- debug(F111," gprotection",zz->gprotect.val,zz->gprotect.len);
- debug(F111," systemid",zz->systemid.val,zz->systemid.len);
- debug(F111," recfm",zz->recfm.val,zz->recfm.len);
- debug(F111," sysparam",zz->sysparam.val,zz->sysparam.len);
- debug(F101," length","",(int) zz->length);
- debug(F110," reply",zz->reply.val,0);
-#endif /* DEBUG */
- return(0);
-}
-
-/* O P E N A -- Open a file, with attributes. */
-/*
- This function tries to open a new file to put the arriving data in. The
- filename is the one in the srvcmd buffer. File collision actions are:
- OVERWRITE (the existing file is overwritten), RENAME (the new file is
- renamed), BACKUP (the existing file is renamed), DISCARD (the new file is
- refused), UPDATE (the incoming file replaces the existing file only if the
- incoming file has a newer creation date).
-
- Returns 0 on failure, nonzero on success.
-*/
-extern char *rf_err;
-
-int
-opena(f,zz) char *f; struct zattr *zz; {
- int x, dispos = 0;
- static struct filinfo fcb; /* Must be static! */
-
- debug(F110,"opena f",f,0);
- debug(F101,"opena discard","",discard);
-
- adebu(f,zz); /* Write attributes to debug log */
-
- ffc = (CK_OFF_T)0; /* Init file-character counter */
-
-#ifdef PIPESEND
- if (pipesend) /* Receiving to a pipe - easy. */
- return(openo(f,zz,&fcb)); /* Just open the pipe. */
-#endif /* PIPESEND */
-
- /* Receiving to a file - set up file control structure */
-
- fcb.bs = fblksiz; /* Blocksize */
-#ifndef NOCSETS
- fcb.cs = fcharset; /* Character set */
-#else
- fcb.cs = 0; /* Character set */
-#endif /* NOCSETS */
- fcb.rl = frecl; /* Record Length */
- fcb.fmt = frecfm; /* Record Format */
- fcb.org = forg; /* Organization */
- fcb.cc = fcctrl; /* Carriage control */
- fcb.typ = binary; /* Type */
- debug(F101,"opena xflg","",xflg);
- debug(F101,"opena remfile","",remfile);
- debug(F101,"opena remappd","",remappd);
- if (xflg && remfile && remappd) /* REMOTE output redirected with >> */
- fcb.dsp = XYFZ_A;
- else
- fcb.dsp = (fncact == XYFX_A) ? XYFZ_A : XYFZ_N; /* Disposition */
- debug(F101,"opena disp","",fcb.dsp);
- fcb.os_specific = ""; /* OS-specific info */
-#ifdef CK_LABELED
- fcb.lblopts = lf_opts; /* Labeled file options */
-#else
- fcb.lblopts = 0;
-#endif /* CK_LABELED */
-
- if (zz->disp.len > 0) { /* Incoming file has a disposition? */
- debug(F111,"open disposition",zz->disp.val,zz->disp.len);
- dispos = (int) (*(zz->disp.val));
- }
- if (!dispos && xflg && remfile && remappd) /* REMOTE redirect append ? */
- dispos = fcb.dsp;
-
- debug(F101,"opena dispos","",dispos);
-
- if (!dispos) { /* No special disposition? */
- if (fncact == XYFX_B && ofn1x && ofn2) { /* File collision = BACKUP? */
- if (zrename(ofn1,ofn2) < 0) { /* Rename existing file. */
- debug(F110,"opena rename fails",ofn1,0);
- rf_err = "Can't create backup file";
- return(0);
- } else debug(F110,"opena rename ok",ofn2,0);
- }
- } else if (dispos == 'R') { /* Receiving a RESEND */
- debug(F101,"opena remote len","",zz->length);
- debug(F101,"opena local len","",rs_len);
-#ifdef COMMENT
- if (fncact == XYFX_R) /* and file collision = RENAME */
- if (ofn1x)
-#endif /* COMMENT */
- if (ofn1[0])
- f = ofn1; /* use original name. */
- if (fncact == XYFX_R) /* if file collision is RENAME */
- ckstrncpy(filnam,ofn1,CKMAXPATH+1); /* restore the real name */
- xxscreen(SCR_AN,0,0L,f); /* update name on screen */
- if (zz->length == rs_len) /* Local and remote lengths equal? */
- return(-17); /* Secret code */
- }
- debug(F111,"opena [file]=mode: ",f,fcb.dsp);
- if (x = openo(f,zz,&fcb)) { /* Try to open the file. */
-#ifdef pdp11
- tlog(F110," local name:",f,0L); /* OK, open, record local name. */
- makestr(&prfspec,f); /* New preliminary name */
-#else
-#ifndef ZFNQFP
- tlog(F110," local name:",f,0L);
- makestr(&prfspec,f);
-#else
- { /* Log full local pathname */
- char *p = NULL, *q = f;
- if ((p = malloc(CKMAXPATH+1)))
- if (zfnqfp(filnam, CKMAXPATH, p))
- q = p;
- tlog(F110," local name:",q,0L);
- makestr(&prfspec,q);
- if (p) free(p);
- }
-#endif /* ZFNQFP */
-#endif /* pdp11 */
-
- if (binary) { /* Log file mode in transaction log */
- tlog(F101," mode: binary","",(long) binary);
- } else { /* If text mode, check character set */
- tlog(F100," mode: text","",0L);
-#ifndef NOCSETS
- if (xfrxla) {
- if (fcharset > -1 && fcharset <= MAXFCSETS)
- tlog(F110," file character-set:",fcsinfo[fcharset].name,0L);
- if (tcharset > -1 && tcharset <= MAXTCSETS)
- tlog(F110," xfer character-set:",tcsinfo[tcharset].name,0L);
- } else {
- tlog(F110," character-set:","transparent",0L);
- }
-#endif /* NOCSETS */
- debug(F111,"opena charset",zz->encoding.val,zz->encoding.len);
- }
- debug(F101,"opena binary","",binary);
-
-#ifdef COMMENT
- if (fsize >= 0)
-#endif /* COMMENT */
- xxscreen(SCR_FS,0,fsize,"");
-
-#ifdef datageneral
-/*
- Need to turn on multi-tasking console interrupt task here, since multiple
- files may be received (huh?) ...
-*/
- if ((local) && (!quiet)) /* Only do this if local & not quiet */
- consta_mt(); /* Start the async read task */
-#endif /* datageneral */
-
- } else { /* Did not open file OK. */
-
- rf_err = ck_errstr(); /* Get system error message */
- if (*rf_err)
- xxscreen(SCR_EM,0,0l,rf_err);
- else
- xxscreen(SCR_EM,0,0l,"Can't open output file");
- tlog(F110,"Failure to open",f,0L);
- tlog(F110,"Error:",rf_err,0L);
- debug(F110,"opena error",rf_err,0);
- }
- return(x); /* Pass on return code from openo */
-}
-
-/* O P E N C -- Open a command (in place of a file) for output */
-
-int
-openc(n,s) int n; char * s; {
- int x;
-#ifndef NOPUSH
- x = zxcmd(n,s);
-#else
- x = 0;
-#endif /* NOPUSH */
- debug(F111,"openc zxcmd",s,x);
- o_isopen = (x > 0) ? 1 : 0;
- return(x);
-}
-
-/* C A N N E D -- Check if current file transfer cancelled */
-
-int
-canned(buf) CHAR *buf; {
- extern int interrupted;
- if (*buf == 'X') cxseen = 1;
- if (*buf == 'Z') czseen = 1;
- if (czseen || cxseen)
- interrupted = 1;
- debug(F101,"canned: cxseen","",cxseen);
- debug(F101," czseen","",czseen);
- return((czseen || cxseen) ? 1 : 0);
-}
-
-
-/* O P E N I -- Open an existing file for input */
-
-int
-openi(name) char *name; {
-#ifndef NOSERVER
- extern int fromgetpath;
-#endif /* NOSERVER */
- int x, filno;
- char *name2;
- extern CHAR *epktmsg;
-
- epktmsg[0] = NUL; /* Initialize error message */
- if (memstr || sndarray) { /* Just return if "file" is memory. */
- i_isopen = 1;
- return(1);
- }
- debug(F110,"openi name",name,0);
- debug(F101,"openi sndsrc","",sndsrc);
-
- filno = (sndsrc == 0) ? ZSTDIO : ZIFILE; /* ... */
- debug(F101,"openi file number","",filno);
-
-#ifndef NOSERVER
- /* If I'm a server and CWD is disabled and name is not from GET-PATH... */
-
- if (server && !en_cwd && !fromgetpath) {
- zstrip(name,&name2);
- if ( /* ... check if pathname included. */
-#ifdef VMS
- zchkpath(name)
-#else
- strcmp(name,name2)
-#endif /* VMS */
- ) {
- tlog(F110,name,"access denied",0L);
- debug(F110,"openi CD disabled",name,0);
- ckstrncpy((char *)epktmsg,"Access denied",PKTMSGLEN);
- return(0);
- } else name = name2;
- }
-#endif /* NOSERVER */
-
-#ifdef PIPESEND
- debug(F101,"openi pipesend","",pipesend);
- if (pipesend) {
- int x;
-#ifndef NOPUSH
- x = zxcmd(ZIFILE,name);
-#else
- x = 0;
-#endif /* NOPUSH */
- i_isopen = (x > 0) ? 1 : 0;
- if (!i_isopen)
- ckstrncpy((char *)epktmsg,"Command or pipe failure",PKTMSGLEN);
- debug(F111,"openi pipesend zxcmd",name,x);
- return(i_isopen);
- }
-#endif /* PIPESEND */
-
-#ifdef CALIBRATE
- if (calibrate) {
- i_isopen = 1;
- return(1);
- }
-#endif /* CALIBRATE */
-
- x = zopeni(filno,name); /* Otherwise, try to open it. */
- debug(F111,"openi zopeni 1",name,x);
- if (x) {
- i_isopen = 1;
- return(1);
- } else { /* If not found, */
- char xname[CKMAXPATH]; /* convert the name */
-#ifdef NZLTOR
- nzrtol(name,xname,fncnv,fnrpath,CKMAXPATH);
-#else
- zrtol(name,xname); /* to local form and then */
-#endif /* NZLTOR */
- x = zopeni(filno,xname); /* try opening it again. */
- debug(F111,"openi zopeni 2",xname,x);
- if (x) {
- i_isopen = 1;
- return(1); /* It worked. */
- } else {
- char * s;
- s = ck_errstr();
- if (s) if (!s) s = NULL;
- if (!s) s = "Can't open file";
- ckstrncpy((char *)epktmsg,s,PKTMSGLEN);
- tlog(F110,xname,s,0L);
- debug(F110,"openi failed",xname,0);
- debug(F110,"openi message",s,0);
- i_isopen = 0;
- return(0);
- }
- }
-}
-
-/* O P E N O -- Open a new file for output. */
-
-int
-openo(name,zz,fcb) char *name; struct zattr *zz; struct filinfo *fcb; {
- char *name2;
-#ifdef DTILDE
- char *dirp;
-#endif /* DTILDE */
-
- int channel, x;
-
- if (stdouf) { /* Receiving to stdout? */
- x = zopeno(ZSTDIO,"",zz,NULL);
- o_isopen = (x > 0);
- debug(F101,"openo stdouf zopeno","",x);
- return(x);
- }
- debug(F110,"openo: name",name,0);
-
- if (cxseen || czseen || discard) { /* If interrupted, get out before */
- debug(F100," open cancelled","",0); /* destroying existing file. */
- return(1); /* Pretend to succeed. */
- }
- channel = ZOFILE; /* SET DESTINATION DISK or PRINTER */
-
-#ifdef PIPESEND
- debug(F101,"openo pipesend","",pipesend);
- if (pipesend) {
- int x;
-#ifndef NOPUSH
- x = zxcmd(ZOFILE,(char *)srvcmd);
-#else
- x = 0;
-#endif /* NOPUSH */
- o_isopen = x > 0;
- debug(F101,"openo zxcmd","",x);
- return(x);
- }
-#endif /* PIPESEND */
-
- if (dest == DEST_S) { /* SET DEST SCREEN... */
- channel = ZCTERM;
- fcb = NULL;
- }
-#ifdef DTILDE
- if (*name == '~') {
- dirp = tilde_expand(name);
- if (*dirp) ckstrncpy(name,dirp,CKMAXPATH+1);
- }
-#endif /* DTILDE */
- if (server && !en_cwd) { /* If running as server */
- zstrip(name,&name2); /* and CWD is disabled, */
- if (strcmp(name,name2)) { /* check if pathname was included. */
- tlog(F110,name,"authorization failure",0L);
- debug(F110,"openo CD disabled",name,0);
- return(0);
- } else name = name2;
- }
- if (zopeno(channel,name,zz,fcb) <= 0) { /* Try to open the file */
- o_isopen = 0;
- debug(F110,"openo failed",name,0);
- /* tlog(F110,"Failure to open",name,0L); */
- return(0);
- } else {
- o_isopen = 1;
- debug(F110,"openo ok, name",name,0);
- return(1);
- }
-}
-
-/* O P E N T -- Open the terminal for output, in place of a file */
-
-int
-opent(zz) struct zattr *zz; {
- int x;
- ffc = tfc = (CK_OFF_T)0;
- x = zopeno(ZCTERM,"",zz,NULL);
- debug(F101,"opent zopeno","",x);
- if (x >= 0) {
- o_isopen = 1;
- binary = XYFT_T;
- } else
- return(0);
- return(x);
-}
-
-/* O P E N X -- Open nothing (incoming file to be accepted but ignored) */
-
-int
-ckopenx(zz) struct zattr *zz; {
- ffc = tfc = (CK_OFF_T)0; /* Reset counters */
- o_isopen = 1;
- debug(F101,"ckopenx fsize","",fsize);
- xxscreen(SCR_FS,0,fsize,""); /* Let screen display know the size */
- return(1);
-}
-
-/* C L S I F -- Close the current input file. */
-
-int
-clsif() {
- extern int xferstat, success;
- int x = 0;
-
- fcps(); /* Calculate CPS quickly */
-
-#ifdef datageneral
- if ((local) && (!quiet)) /* Only do this if local & not quiet */
- if (nfils < 1) /* More files to send ... leave it on! */
- connoi_mt();
-#endif /* datageneral */
-
- debug(F101,"clsif i_isopen","",i_isopen);
- if (i_isopen) { /* If input file is open... */
- if (memstr) { /* If input was memory string, */
- memstr = 0; /* indicate no more. */
- } else {
- x = zclose(ZIFILE); /* else close input file. */
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"clsif zclose","",x);
- debug(F101,"clsif success","",success);
- debug(F101,"clsif xferstat","",xferstat);
- debug(F101,"clsif fsize","",fsize);
- debug(F101,"clsif ffc","",ffc);
- debug(F101,"clsif cxseen","",cxseen);
- debug(F101,"clsif czseen","",czseen);
- debug(F101,"clsif discard","",czseen);
- }
-#endif /* DEBUG */
- if ((cxseen || czseen) && !epktsent) { /* If interrupted */
- xxscreen(SCR_ST,ST_INT,0l,""); /* say so */
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,psfspec,fsize,binary,1,"Interrupted");
-#endif /* TLOG */
- } else if (discard && !epktsent) { /* If I'm refusing */
- xxscreen(SCR_ST,ST_REFU,0l,refused); /* say why */
-#ifdef TLOG
- if (tralog && !tlogfmt) {
- char buf[128];
- ckmakmsg(buf,128,"Refused: ",refused,NULL,NULL);
- doxlog(what,psfspec,fsize,binary,1,buf);
- }
-#endif /* TLOG */
- } else if (!epktrcvd && !epktsent && !cxseen && !czseen) {
- CK_OFF_T zz;
- zz = ffc;
-#ifdef CK_RESEND
- if (sendmode == SM_RESEND || sendmode == SM_PSEND)
- zz += sendstart;
-#endif /* CK_RESEND */
- debug(F101,"clsif fstats","",zz);
- fstats(); /* Update statistics */
- if ( /* Was the whole file sent? */
-#ifdef VMS
- 0 /* Not a reliable check in VMS */
-#else
-#ifdef STRATUS
- 0 /* Probably not for VOS either */
-#else
- zz < fsize
-#ifdef CK_CTRLZ
- && ((eofmethod != XYEOF_Z && !binary) || binary)
-#endif /* CK_CTRLZ */
-#endif /* STRATUS */
-#endif /* VMS */
- ) {
- xxscreen(SCR_ST,ST_INT,0l,"");
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,psfspec,fsize,binary,1,"Incomplete");
-#endif /* TLOG */
- } else {
-#ifdef COMMENT
- /* Not yet -- we don't have confirmation from the receiver */
- xxscreen(SCR_ST,ST_OK,0l,"");
-#endif /* COMMENT */
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,psfspec,fsize,binary,0,"");
-#endif /* TLOG */
- }
- }
- }
- i_isopen = 0;
- hcflg = 0; /* Reset flags */
- sendstart = (CK_OFF_T)0; /* Don't do this again! */
-#ifdef COMMENT
-/*
- This prevents a subsequent call to clsof() from deleting the file
- when given the discard flag.
-*/
- *filnam = '\0'; /* and current file name */
-#endif /* COMMENT */
- return(x);
-}
-
-
-/* C L S O F -- Close an output file. */
-
-/* Call with disp != 0 if file is to be discarded. */
-/* Returns -1 upon failure to close, 0 or greater on success. */
-
-int
-clsof(disp) int disp; {
- int x = 0;
- extern int success;
-
- fcps(); /* Calculate CPS quickly */
-
- debug(F101,"clsof disp","",disp);
- debug(F101,"clsof cxseen","",cxseen);
- debug(F101,"clsof success","",success);
-
- debug(F101,"clsof o_isopen","",o_isopen);
- if (fncsav != -1) { /* Saved file collision action... */
- fncact = fncsav; /* Restore it. */
- fncsav = -1; /* Unsave it. */
- }
-#ifdef datageneral
- if ((local) && (!quiet)) /* Only do this if local & not quiet */
- connoi_mt();
-#endif /* datageneral */
- if (o_isopen && !calibrate) {
- if ((x = zclose(ZOFILE)) < 0) { /* Try to close the file */
- tlog(F100,"Failure to close",filnam,0L);
- xxscreen(SCR_ST,ST_ERR,0l,"Can't close file");
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,prfspec,fsize,binary,1,"Can't close file");
-#endif /* TLOG */
- } else if (disp) { /* Interrupted or refused */
- if (keep == 0 || /* If not keeping incomplete files */
- (keep == SET_AUTO && binary == XYFT_T)
- ) {
- if (*filnam && (what & W_RECV)) /* AND we're receiving */
- zdelet(filnam); /* ONLY THEN, delete it */
- if (what & W_KERMIT) {
- debug(F100,"clsof incomplete discarded","",0);
- tlog(F100," incomplete: discarded","",0L);
- if (!epktrcvd && !epktsent) {
- xxscreen(SCR_ST,ST_DISC,0l,"");
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,prfspec,fsize,binary,1,"Discarded");
-#endif /* TLOG */
- }
- }
- } else { /* Keep incomplete copy */
- debug(F100,"clsof fstats 1","",0);
- fstats();
- if (!discard) { /* Unless discarding for other reason... */
- if (what & W_KERMIT) {
- debug(F100,"closf incomplete kept","",0);
- tlog(F100," incomplete: kept","",0L);
- }
- }
- if (what & W_KERMIT) {
- if (!epktrcvd && !epktsent) {
- xxscreen(SCR_ST,ST_INC,0l,"");
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,prfspec,fsize,binary,1,"Incomplete");
-#endif /* TLOG */
- }
- }
- }
- }
- }
- if (o_isopen && x > -1 && !disp) {
- debug(F110,"clsof OK",rfspec,0);
- makestr(&rfspec,prfspec);
- makestr(&rrfspec,prrfspec);
- fstats();
- if (!epktrcvd && !epktsent && !cxseen && !czseen) {
- xxscreen(SCR_ST,ST_OK,0L,"");
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,rfspec,fsize,binary,0,"");
-#endif /* TLOG */
- }
- }
- rs_len = (CK_OFF_T)0;
- o_isopen = 0; /* The file is not open any more. */
- cxseen = 0; /* Reset per-file interruption flag */
- return(x); /* Send back zclose() return code. */
-}
-
-#ifdef SUNOS4S5
-tolower(c) char c; { return((c)-'A'+'a'); }
-toupper(c) char c; { return((c)-'a'+'A'); }
-#endif /* SUNOS4S5 */
-#endif /* NOXFER */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcfns.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckcfns.c
deleted file mode 100644
index 0f2bd86..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcfns.c
+++ /dev/null
@@ -1,7165 +0,0 @@
-char *fnsv = "C-Kermit functions, 9.0.233, 3 Jun 2011";
-
-char *nm[] = { "Disabled", "Local only", "Remote only", "Enabled" };
-
-/* C K C F N S -- System-independent Kermit protocol support functions. */
-
-/* ...Part 1 (others moved to ckcfn2,3 to make this module smaller) */
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-/*
- System-dependent primitives defined in:
-
- ck?tio.c -- terminal (communications) i/o
- cx?fio.c -- file i/o, directory structure
-*/
-#include "ckcsym.h" /* Needed for Stratus VOS */
-#include "ckcasc.h" /* ASCII symbols */
-#include "ckcdeb.h" /* Debug formats, typedefs, etc. */
-#include "ckcker.h" /* Symbol definitions for Kermit */
-#include "ckcxla.h" /* Character set symbols */
-#include "ckcnet.h" /* VMS definition of TCPSOCKET */
-#ifdef OS2
-#ifdef OS2ONLY
-#include <os2.h>
-#endif /* OS2ONLY */
-#include "ckocon.h"
-#endif /* OS2 */
-
-int docrc = 0; /* Accumulate CRC for \v(crc16) */
-long crc16 = 0L; /* File CRC = \v(crc16) */
-int gnferror = 0; /* gnfile() failure reason */
-
-extern CHAR feol;
-extern int byteorder, xflg, what, fmask, cxseen, czseen, nscanfile, sysindex;
-extern int xcmdsrc, dispos, matchfifo;
-extern int inserver;
-
-extern int nolinks;
-#ifdef VMSORUNIX
-extern int zgfs_dir;
-#ifdef CKSYMLINK
-extern int zgfs_link;
-#endif /* CKSYMLINK */
-#endif /* VMSORUNIX */
-
-#ifndef NOXFER
-
-#ifndef NOICP
-#ifndef NOSPL
-extern char * clcmds;
-extern int haveurl;
-#ifdef CK_APC
-extern int apcactive, adl_ask;
-#endif /* CK_APC */
-#endif /* NOSPL */
-#endif /* NOICP */
-
-extern int remfile;
-
-/* (move these prototypes to the appropriate .h files...) */
-
-#ifdef COMMENT
-/* Not used */
-#ifdef VMS
-_PROTOTYP( int getvnum, (char *) );
-#endif /* VMS */
-#endif /* COMMENT */
-
-_PROTOTYP( static int bgetpkt, (int) );
-#ifndef NOCSETS
-_PROTOTYP( int lookup, (struct keytab[], char *, int, int *) );
-#endif /* NOCSETS */
-#ifndef NOSPL
-_PROTOTYP( int zzstring, (char *, char **, int *) );
-#endif /* NOSPL */
-
-#ifdef OS2
-#include <io.h>
-#ifdef OS2ONLY
-#include <os2.h>
-#endif /* OS2ONLY */
-#endif /* OS2 */
-
-#ifdef VMS
-#include <errno.h>
-#endif /* VMS */
-
-/* Externals from ckcmai.c */
-
-extern int srvcdmsg, srvidl, idletmo;
-extern char * cdmsgfile[];
-extern int spsiz, spmax, rpsiz, timint, srvtim, rtimo, npad, ebq, ebqflg,
- rpt, rptq, rptflg, capas, keep, fncact, pkttim, autopar, spsizr, xitsta;
-extern int pktnum, bctr, bctu, bctf, bctl, clfils, sbufnum, protocol,
- size, osize, spktl, nfils, ckwarn, timef, spsizf, sndtyp, rcvtyp, success;
-extern int parity, turn, network, whatru, fsecs, justone, slostart,
- ckdelay, displa, mypadn, moving, recursive, nettype;
-extern long filcnt;
-extern CK_OFF_T
- tfc, fsize, sendstart, rs_len, flci, flco, tlci, tlco, calibrate;
-extern long filrej, oldcps, cps, peakcps, ccu, ccp, filestatus;
-extern int fblksiz, frecl, frecfm, forg, fcctrl, fdispla, skipbup;
-extern int spackets, rpackets, timeouts, retrans, crunched, wmax, wcur;
-extern int hcflg, binary, fncnv, b_save, f_save, server;
-extern int nakstate, discard, rejection, local, xfermode, interrupted;
-extern int rq, rqf, sq, wslots, wslotn, wslotr, winlo, urpsiz, rln;
-extern int fnspath, fnrpath, eofmethod, diractive, whatru2, wearealike;
-extern int atcapr, atcapb, atcapu;
-extern int lpcapr, lpcapb, lpcapu;
-extern int swcapr, swcapb, swcapu;
-extern int lscapr, lscapb, lscapu;
-extern int rscapr, rscapb, rscapu;
-extern int rptena, rptmin;
-extern int sseqtbl[];
-extern int numerrs, nzxopts;
-extern long rptn;
-extern int maxtry;
-extern int stdouf;
-extern int sendmode;
-extern int carrier, ttprty;
-extern int g_fnrpath;
-#ifdef TCPSOCKET
-extern int ttnproto;
-#endif /* TCPSOCKET */
-
-#ifndef NOSPL
-extern int sndxin, sndxhi, sndxlo;
-#endif /* NOSPL */
-
-extern int g_binary, g_fncnv;
-
-#ifdef GFTIMER
-extern CKFLOAT fpfsecs;
-#endif /* GFTIMER */
-
-#ifdef OS2
-extern struct zattr iattr;
-#endif /* OS2 */
-
-#ifdef PIPESEND
-extern int usepipes;
-#endif /* PIPESEND */
-extern int pipesend;
-
-#ifdef STREAMING
-extern int streamrq, streaming, streamed, streamok;
-#endif /* STREAMING */
-extern int reliable, clearrq, cleared, urclear;
-
-extern int
- atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
- attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
-
-extern int bigsbsiz, bigrbsiz;
-extern char *versio;
-extern char *filefile;
-extern char whoareu[], * cksysid;
-
-#ifndef NOSERVER
-extern int ngetpath;
-extern char * getpath[];
-extern int fromgetpath;
-#endif /* NOSERVER */
-
-#ifdef CK_LOGIN
-extern int isguest;
-#endif /* CK_LOGIN */
-
-extern int srvcmdlen;
-extern CHAR *srvcmd, * epktmsg;
-extern CHAR padch, mypadc, eol, seol, ctlq, myctlq, sstate, myrptq;
-extern CHAR *data, padbuf[], stchr, mystch;
-extern CHAR *srvptr;
-extern CHAR *rdatap;
-extern char *cmarg, *cmarg2, **cmlist, filnam[], ofilnam[];
-extern char *rfspec, *prfspec, *rrfspec, *prrfspec, *sfspec, *psfspec, *rfspec;
-extern char fspec[];
-extern int fspeclen;
-
-#ifndef NOMSEND
-extern struct filelist * filehead, * filenext;
-extern int addlist;
-#endif /* NOMSEND */
-
-_PROTOTYP( int lslook, (unsigned int b) ); /* Locking Shift Lookahead */
-_PROTOTYP( int szeof, (CHAR *s) );
-_PROTOTYP( VOID fnlist, (void) );
-#endif /* NOXFER */
-
-extern CK_OFF_T ffc;
-
-/* Character set Translation */
-
-#ifndef NOCSETS
-extern int tcharset, fcharset, dcset7, dcset8;
-extern int fcs_save, tcs_save;
-extern int ntcsets, xlatype, cseqtab[];
-extern struct csinfo tcsinfo[], fcsinfo[];
-extern int r_cset, s_cset, afcset[];
-#ifdef UNICODE
-extern int ucsorder, fileorder;
-#endif /* UNICODE */
-
-_PROTOTYP( CHAR ident, (CHAR) ); /* Identity translation function */
-
-/* Arrays of and pointers to character translation functions */
-
-#ifdef CK_ANSIC
-extern CHAR (*rx)(CHAR); /* Pointer to input character translation function */
-extern CHAR (*sx)(CHAR); /* Pointer to output character translation function */
-extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* Byte-to-Byte Send */
-extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* Byte-to-Byte Recv */
-#ifdef UNICODE
-extern int (*xut)(USHORT); /* Translation function UCS to TCS */
-extern int (*xuf)(USHORT); /* Translation function UCS to FCS */
-extern USHORT (*xtu)(CHAR); /* Translation function TCS to UCS */
-extern USHORT (*xfu)(CHAR); /* Translation function FCS to UCS */
-#endif /* UNICODE */
-
-#else /* The same declarations again for non-ANSI comilers... */
-
-extern CHAR (*rx)();
-extern CHAR (*sx)();
-extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])();
-extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])();
-#ifdef UNICODE
-extern int (*xut)();
-extern int (*xuf)();
-extern USHORT (*xtu)();
-extern USHORT (*xfu)();
-#endif /* UNICODE */
-#endif /* CK_ANSIC */
-#endif /* NOCSETS */
-
-/* (PWP) external def. of things used in buffered file input and output */
-
-#ifdef DYNAMIC
-extern char *zinbuffer, *zoutbuffer;
-#else
-extern char zinbuffer[], zoutbuffer[];
-#endif /* DYNAMIC */
-extern char *zinptr, *zoutptr;
-extern int zincnt, zoutcnt, zobufsize, xfrxla;
-
-extern long crcta[], crctb[]; /* CRC-16 generation tables */
-extern int rseqtbl[]; /* Rec'd-packet sequence # table */
-
-#ifndef NOXFER
-
-/* Criteria used by gnfile()... */
-
-char sndafter[19] = { NUL, NUL };
-char sndbefore[19] = { NUL, NUL };
-char sndnafter[19] = { NUL, NUL };
-char sndnbefore[19] = { NUL, NUL };
-char *sndexcept[NSNDEXCEPT] = { NULL, NULL };
-char *rcvexcept[NSNDEXCEPT] = { NULL, NULL };
-CK_OFF_T sndsmaller = (CK_OFF_T)-1;
-CK_OFF_T sndlarger = (CK_OFF_T)-1;
-
-/* Variables defined in this module but shared by other modules. */
-
-int xfrbel = 1;
-char * ofperms = ""; /* Output file permissions */
-int autopath = 0; /* SET RECEIVE PATHNAMES AUTO flag */
-
-#ifdef CALIBRATE
-#define CAL_O 3
-#define CAL_M 253
-
-int cal_j = 0;
-
-CHAR
-cal_a[] = {
- 16, 45, 98, 3, 52, 41, 14, 7, 76,165,122, 11,104, 77,166, 15,
-160, 93, 18, 19,112, 85, 54, 23,232,213, 90, 27, 12, 81,126, 31,
- 4,205, 34, 35,144, 73,110, 39, 28,133,218, 43,156, 65,102, 47,
- 84, 61, 50, 51,208,117, 86, 55, 8,245, 74, 59, 44,125,222, 63,
- 80, 1,162, 67,116,105,206, 71,120, 9,250, 75, 88, 97, 6, 79,
-100,221, 82, 83, 36, 89, 94, 87, 40, 21,106, 91,236,145,150, 95,
-228, 33,130, 99,148,137,198,103,108,169, 42,107,184,129, 78,111,
- 0, 49,114,115, 32,121,254,119,172, 57,138,123,152,177, 22,127,
-240,193, 2,131,176, 5, 38,135,204,229, 10,139,200,161,174,143,
-128, 17,146,147, 68,153, 30,151, 72,217,170,155, 24,209, 62,159,
- 64,225,194,163,244,201, 70,167,216,197,234,171,188,109,230,175,
-212,113,178,179,132,185,190,183,136,249,202,187, 92,241,118,191,
- 48,237, 66,195, 96,233,142,199,248, 37, 58,203, 60, 13,134,207,
- 20, 29,210,211,164,149,182,215,220, 25, 26,219,124,157,246,223,
-180,141,226,227,192,101,238,231, 56, 69,154,235,252,173, 46,239,
-224,253,242,243,196, 53,214,247,168,181,186,251,140,189,158,255
-};
-#endif /* CALIBRATE */
-
-char * rf_err = "Error receiving file"; /* rcvfil() error message */
-
-#ifdef CK_SPEED
-short ctlp[256] = { /* Control-Prefix table */
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* C0 */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* G0 */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* DEL */
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* C1 */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* G1 */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 /* 255 */
-};
-#endif /* CK_SPEED */
-
-int sndsrc; /* Flag for where to get names of files to send: */
- /* -1: znext() function */
- /* 0: stdin */
- /* >0: list in cmlist or other list */
- /* -9: calibrate */
-
-int memstr; /* Flag for input from memory string */
-int funcstr; /* Flag for input from function */
-int bestlen = 0;
-int maxsend = 0;
-
-int gnf_binary = 0; /* Prevailing xfer mode for gnfile */
-
-#ifdef pdp11
-#define MYINITLEN 32
-#else
-#define MYINITLEN 100
-#endif /* pdp11 */
-CHAR myinit[MYINITLEN]; /* Copy of my Send-Init data */
-
-/* Variables local to this module */
-
-#ifdef TLOG
-#ifndef XYZ_INTERNAL
-static
-#endif /* XYZ_INTERNAL */
-char *fncnam[] = {
- "rename", "replace", "backup", "append", "discard", "ask",
- "update", "dates-differ", ""
-};
-#endif /* TLOG */
-
-static char *memptr; /* Pointer for memory strings */
-
-#ifdef VMS
-extern int batch;
-#else
-extern int backgrd;
-#endif /* VMS */
-
-#ifdef CK_CTRLZ
-static int lastchar = 0;
-#endif /* CK_CTRLZ */
-
-#ifdef CK_ANSIC
-static int (*funcptr)(void); /* Pointer for function strings */
-#else
-static int (*funcptr)();
-#endif /* CK_ANSIC */
-
-#ifdef pdp11
-#define CMDSTRL 50
-static char cmdstr[50]; /* System command string. */
-#else
-#ifdef BIGBUFOK
-#define CMDSTRL 1024
-#else
-#define CMDSTRL 256
-#endif /* BIGBUFOK */
-static char cmdstr[CMDSTRL+1];
-#endif /* pdp11 */
-
-static int drain; /* For draining stacked-up ACKs. */
-
-static int first; /* Flag for first char from input */
-static CHAR t; /* Current character */
-#ifdef COMMENT
-static CHAR next; /* Next character */
-#endif /* COMMENT */
-
-static int ebqsent = 0; /* 8th-bit prefix bid that I sent */
-static int lsstate = 0; /* Locking shift state */
-static int lsquote = 0; /* Locking shift quote */
-
-extern int quiet;
-
-/* E N C S T R -- Encode a string from memory. */
-
-/*
- Call this instead of getpkt() if source is a string, rather than a file.
- Note: Character set translation is never done in this case.
-*/
-
-#ifdef COMMENT
-#define ENCBUFL 200
-#ifndef pdp11
-CHAR encbuf[ENCBUFL];
-#else
-/* This is gross, but the pdp11 root segment is out of space */
-/* Will allocate it in ckuusr.c. */
-extern CHAR encbuf[];
-#endif /* pdp11 */
-#endif /* COMMENT */
-
-/*
- Encode packet data from a string in memory rather than from a file.
- Returns the length of the encoded string on success, -1 if the string
- could not be completely encoded into the currently negotiated data
- field length.
-*/
-int
-#ifdef CK_ANSIC
-encstr(CHAR *s)
-#else /* CK_ANSIC */
-encstr(s) CHAR* s;
-#endif /* CK_ANSIC */
-{
-/*
- Recoded 30 Jul 94 to use the regular data buffer and the negotiated
- maximum packet size. Previously we were limited to the length of encbuf[].
- Also, to return a failure code if the entire encoded string would not fit.
- Modified 14 Jul 98 to return length of encoded string.
-*/
- int m, rc, slen; char *p;
- if (!data) { /* Watch out for null pointers. */
- debug(F100,"SERIOUS ERROR: encstr data == NULL","",0);
- return(-1);
- }
- if (!s) s = (CHAR *)""; /* Ditto. */
- slen = strlen((char *)s); /* Length of source string. */
- debug(F111,"encstr",s,slen);
- rc = 0; /* Return code. */
- m = memstr; p = memptr; /* Save these. */
- memptr = (char *)s; /* Point to the string. */
- /* debug(F101,"encstr memptr 1","",memptr); */
- memstr = 1; /* Flag memory string as source. */
- first = 1; /* Initialize character lookahead. */
- *data = NUL; /* In case s is empty */
- debug(F101,"encstr spsiz","",spsiz);
- rc = getpkt(spsiz,0); /* Fill a packet from the string. */
- debug(F101,"encstr getpkt rc","",rc);
- if (rc > -1 && memptr < (char *)(s + slen)) { /* Means we didn't encode */
- rc = -1; /* the whole string. */
- debug(F101,"encstr string too big","",size);
- }
- debug(F101,"encstr getpkt rc","",rc);
- memstr = m; /* Restore memory string flag */
- memptr = p; /* and pointer */
- first = 1; /* Put this back as we found it. */
- return(rc);
-}
-
-/* Output functions passed to 'decode': */
-
-int /* Put character in server command buffer */
-#ifdef CK_ANSIC
-putsrv(char c)
-#else
-putsrv(c) register char c;
-#endif /* CK_ANSIC */
-/* putsrv */ {
- *srvptr++ = c;
- *srvptr = '\0'; /* Make sure buffer is null-terminated */
- return(0);
-}
-
-int /* Output character to console. */
-#ifdef CK_ANSIC
-puttrm(char c)
-#else
-puttrm(c) register char c;
-#endif /* CK_ANSIC */
-/* puttrm */ {
- extern int rcdactive;
-#ifndef NOSPL
- extern char * qbufp; /* If REMOTE QUERY active, */
- extern int query, qbufn; /* also store response in */
- if (query && qbufn++ < 1024) { /* query buffer. */
- *qbufp++ = c;
- *qbufp = NUL;
- }
- if (!query || !xcmdsrc)
-#endif /* NOSPL */
-/*
- This routine is used (among other things) for printing the server's answer
- to a REMOTE command. But REMOTE CD is special because it isn't really
- asking for an answer from the server. Thus some people want to suppress
- the confirmation message (e.g. when the server sends back the actual path
- of the directory CD'd to), and expect to be able to do this with SET QUIET
- ON. But they would not want SET QUIET ON to suppress the other server
- replies, which are pointless without their answers. Thus the "rcdactive"
- flag (REMOTE CD command is active). Thu Oct 10 16:38:21 2002
-*/
- if (!(quiet && rcdactive)) /* gross, yuk */
- conoc(c);
- return(0);
-}
-#endif /* NOXFER */
-
-int /* Output char to file. */
-#ifdef CK_ANSIC
-putmfil(char c) /* Just like putfil but to ZMFILE */
-#else /* rather than ZOFILE... */
-putmfil(c) register char c;
-#endif /* CK_ANSIC */
-/* putmfil */ {
- debug(F000,"putfil","",c);
- if (zchout(ZMFILE, (char) (c & fmask)) < 0) {
- czseen = 1;
- debug(F101,"putfil zchout write error, setting czseen","",1);
- return(-1);
- }
- return(0);
-}
-
-int /* Output char to nowhere. */
-#ifdef CK_ANSIC
-putnowhere(char c)
-#else
-putnowhere(c) register char c;
-#endif /* CK_ANSIC */
-/* putnowhere */ {
- return(0);
-}
-
-
-int /* Output char to file. */
-#ifdef CK_ANSIC
-putfil(char c)
-#else
-putfil(c) register char c;
-#endif /* CK_ANSIC */
-/* putfil */ {
- debug(F000,"putfil","",c);
- if (zchout(ZOFILE, (char) (c & fmask)) < 0) {
- czseen = 1; /* If write error... */
- debug(F101,"putfil zchout write error, setting czseen","",1);
- return(-1);
- }
- return(0);
-}
-
-/*
- The following function is a wrapper for putfil(). The only reason for its
- existence is to be passed as a function pointer to decode(), which treats
- putfil() itself specially -- bypassing it and using an internal macro
- instead to speed things up. Use zputfil() instead of putfil() in cases where
- we do not want this to happen, e.g. when we need to send output to the file
- with a mixture of zchout() and zsout()/zsoutl() calls (as is the case with
- incoming short-form REMOTE command replies redirected to a file), which would
- otherwise result in data written to the file out of order.
-*/
-int
-#ifdef CK_ANSIC
-zputfil(char c)
-#else
-zputfil(c) register char c;
-#endif /* CK_ANSIC */
-/* zputfil */ {
- return(putfil(c));
-}
-
-#ifndef NOXFER
-
-/* D E C O D E -- Kermit packet decoding procedure */
-
-/*
- Call with string to be decoded and an output function.
- Returns 0 on success, -1 on failure (e.g. disk full).
-
- This is the "inner loop" when receiving files, and must be coded as
- efficiently as possible. Note some potential problems: if a packet
- is badly formed, having a prefixed sequence ending prematurely, this
- function, as coded, could read past the end of the packet. This has
- never happened, thus the additional (time-consuming) tests have not
- been added.
-*/
-
-static CHAR *xdbuf; /* Global version of decode()'s buffer pointer */
- /* for use by translation functions. */
-
-/* Function for pushing a character onto decode()'s input stream. */
-
-VOID
-#ifdef CK_ANSIC
-zdstuff(CHAR c)
-#else
-zdstuff(c) CHAR c;
-#endif /* CK_ANSIC */
-/* zdstuff */ {
- xdbuf--; /* Back up the pointer. */
- *xdbuf = c; /* Stuff the character. */
-}
-
-#ifdef CKTUNING
-/*
- Trimmed-down packet decoder for binary-mode no-parity transfers.
- decode() is the full version.
-*/
-int
-#ifdef CK_ANSIC
-bdecode(CHAR *buf, int (*fn)(char))
-#else
-bdecode(buf,fn) register CHAR *buf; register int (*fn)();
-#endif /* CK_ANSIC */
-/* bdecode */ {
- register unsigned int a, a7; /* Various copies of current char */
- int ccpflg; /* For Ctrl-unprefixing stats */
- int t; /* Int version of character */
- int len;
- long z; /* For CRC calculation */
- CHAR c; /* Current character */
-
- if (!binary || parity || fn != putfil) /* JUST IN CASE */
- return(decode(buf,fn,1));
- debug(F100,"BDECODE","",0);
-
- xdbuf = buf; /* Global copy of source pointer. */
-
- len = rln; /* Number of bytes in data field */
- while (len > 0) {
- a = *xdbuf++ & 0xff; /* Get next character */
- len--;
- rpt = 0; /* Initialize repeat count. */
- if (a == rptq && rptflg) { /* Got a repeat prefix? */
- rpt = xunchar(*xdbuf++ & 0xFF); /* Yes, get the repeat count, */
- rptn += rpt;
- a = *xdbuf++ & 0xFF; /* and get the prefixed character. */
- len -= 2;
- }
- ccpflg = 0; /* Control prefix flag. */
- if (a == ctlq) { /* If control prefix, */
- a = *xdbuf++ & 0xFF; /* get its operand */
- len--;
- a7 = a & 0x7F; /* and its low 7 bits. */
- if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') { /* Controllify */
- a = ctl(a); /* if in control range. */
- a7 = a & 0x7F;
- ccpflg = 1; /* Note that we did this */
- ccp++; /* Count for stats */
- }
- } else a7 = a & 0x7f; /* Not control quote */
- if (a7 < 32 || a7 == 127) /* A bare control character? */
- if (!ccpflg) ccu++; /* Count it */
- if (!rpt) rpt = 1;
- for (; rpt > 0; rpt--) { /* Output the char RPT times */
-#ifdef CALIBRATE
- if (calibrate) {
- ffc++;
- continue;
- }
-#endif /* CALIBRATE */
-#ifdef OS2
- if (xflg && !remfile) { /* Write to virtual screen */
- char _a;
- _a = a & fmask;
- t = conoc(_a);
- if (t < 1)
- t = -1;
- } else
-#endif /* OS2 */
- t = zmchout(a & fmask); /* zmchout is a macro */
- if (t < 0) {
- debug(F101,"bdecode write error - errno","",errno);
- return(-1);
- }
- ffc++; /* Count the character */
- if (docrc && !remfile) { /* Update file CRC */
- c = a; /* Force conversion to unsigned char */
- z = crc16 ^ (long)c;
- crc16 = (crc16 >> 8) ^
- (crcta[(z & 0xF0) >> 4] ^ crctb[z & 0x0F]);
- }
- }
-#ifdef CK_CTRLZ
- lastchar = a;
-#endif /* CK_CTRLZ */
- }
- return(0);
-}
-#endif /* CKTUNING */
-#endif /* NOXFER */
-
-/* P N B Y T E -- Output next byte to file or other destination */
-
-static CK_OFF_T offc = 0L;
-
-static int
-#ifdef CK_ANSIC
-pnbyte(CHAR c, int (*fn)(char))
-#else
-pnbyte(c,fn) CHAR c; int (*fn)();
-#endif /* CK_ANSIC */
-/* pnbyte */ {
- int rc;
- long z;
-
-#ifdef OS2
-#ifndef NOXFER
- if (xflg && !remfile) { /* Write to virtual screen */
- char _a;
- _a = c & fmask;
- rc = conoc(_a);
- if (rc < 1)
- return(-1);
- } else
-#endif /* NOXFER */
-#endif /* OS2 */
- {
- if (fn == putfil) { /* Execute output function */
- rc = zmchout(c); /* to-file macro (fast) */
- } else if (!fn) {
- rc = putchar(c); /* to-screen macro (fast) */
- } else {
- rc = (*fn)(c); /* function call (not as fast) */
- }
- if (rc < 0)
- return(rc);
- }
-/*
- Both xgnbyte() and xpnbyte() increment ffc (the file byte counter).
- During file transfer, only one of these functions is called. However,
- the TRANSLATE command is likely to call them both. offc, therefore,
- contains the output byte count, necessary for handling the UCS-2 BOM.
- NOTE: It might be safe to just test for W_SEND, FTP or not.
-*/
- if ((what & (W_FTP|W_SEND)) != (W_FTP|W_SEND)) {
- offc++; /* Count the byte */
- ffc++; /* Count the byte */
- }
-#ifndef NOXFER
- if (docrc && !xflg && !remfile) { /* Update file CRC */
- z = crc16 ^ (long)c;
- crc16 = (crc16 >> 8) ^
- (crcta[(z & 0xF0) >> 4] ^ crctb[z & 0x0F]);
- }
-#endif /* NOXFER */
- return(1);
-}
-
-/*
- X P N B Y T E -- Translate and put next byte to file.
-
- Only for Unicode. Call with next untranslated byte from incoming
- byte stream, which can be in any Transfer Character Set: UCS-2, UTF-8,
- Latin-1, Latin-Hebrew, etc. Translates to the file character set and
- writes bytes to the output file. Call with character to translate
- as an int, plus the transfer character set (to translate from) and the
- file character set (to translate to), or -1,0,0 to reset the UCS-2 byte
- number (which should be done at the beginning of a file). If the transfer
- (source) character-set is UCS-2, bytes MUST arrive in Big-Endian order.
- Returns:
- -1: On error
- 0: Nothing to write (mid-sequence)
- >0: Number of bytes written.
-*/
-#ifdef KANJI
-static int jstate = 0, jx = 0; /* For outputting JIS-7 */
-static char jbuf[16] = { NUL, NUL };
-#endif /* KANJI */
-
-int
-#ifdef CK_ANSIC
-xpnbyte(int a, int tcs, int fcs, int (*fn)(char))
-#else
-xpnbyte(a,tcs,fcs,fn) int a, tcs, fcs; int (*fn)();
-#endif /* CK_ANSIC */
-/* xpnbyte */ {
-#ifdef UNICODE
- extern int ucsbom; /* Byte order */
-#endif /* UNICODE */
- /* CHAR c; */ /* Unsigned char worker */
- static union ck_short uc, eu, sj; /* UCS-2, EUC, and Shift-JIS workers */
- USHORT ch; /* ditto... */
- USHORT * us = NULL; /* ditto... */
- int c7, rc, haveuc = 0; /* Return code and UCS-2 flag */
- int utferror = 0; /* UTF-8 error */
- static int bn = 0; /* UCS-2 byte number */
- int swapping = 0; /* Swapping UCS bytes to output? */
- /* swapping must be 0 or 1 */
- if (a == -1 && (tcs | fcs) == 0) { /* Reset in case previous run */
- bn = 0; /* left bn at 1... */
- offc = (CK_OFF_T)0;
- debug(F101,"xpnbyte RESET","",bn);
- return(0);
- }
- debug(F001,"xpnbyte a","",a);
-
-#ifdef UNICODE
-
-/*
- byteorder = hardware byte order of this machine.
- ucsorder = override by SET FILE UCS BYTE-ORDER command.
- fileorder = byte order of UCS-2 input file detected from BOM.
- swapping applies only when output charset is UCS-2.
-*/
- if (ucsorder != 1 && ucsorder != 0) /* Also just in case... */
- ucsorder = byteorder;
- if ((byteorder && !ucsorder) || (!byteorder && fileorder))
- swapping = 1; /* Swapping bytes to output */
-
-#ifdef COMMENT
- debug(F101,"xpnbyte ucsorder","",ucsorder);
- debug(F101,"xpnbyte swapping","",swapping);
-#endif /* COMMENT */
-
- if (tcs == TC_UTF8) { /* 'a' is from a UTF-8 stream */
- ch = a;
- if (fcs == TC_UTF8) /* Output is UTF-8 too */
- return(pnbyte(ch,fn)); /* so just copy. */
- rc = utf8_to_ucs2(ch,&us); /* Otherwise convert to UCS-2 */
- if (rc == 0) { /* Done with this sequence */
- uc.x_short = *us; /* We have a Unicode */
- haveuc = 1;
- } else if (rc < 0) { /* Error */
- debug(F101,"xpnbyte UTF-8 conversion error","",rc);
- haveuc = 1; /* Replace by U+FFFD */
- uc.x_short = *us;
- utferror = 1;
- } else /* Sequence incomplete */
- return(0);
- } else if (tcs == TC_UCS2) { /* 'a' is UCS-2 */
- /* Here we have incoming UCS-2 in guaranteed Big Endian order */
- /* so we must exchange bytes if local machine is Little Endian. */
- switch (bn) { /* Which byte? */
- case 0: /* High... */
- uc.x_char[byteorder] = (unsigned)a & 0xff;
- bn++;
- return(0); /* Wait for next */
- case 1: /* Low... */
- uc.x_char[1-byteorder] = (unsigned)a & 0xff;
- bn = 0; /* Done with sequence */
- haveuc = 1; /* Have a Unicode */
- }
- } else
-#endif /* UNICODE */
-
-#ifdef KANJI /* Whether UNICODE is defined or not */
- if (tcs == TC_JEUC) { /* Incoming Japanese EUC */
- int bad = 0;
- static int kanji = 0; /* Flags set in case 0 for case 1 */
- static int kana = 0;
- switch (bn) { /* Byte number */
- case 0: /* Byte 0 */
- eu.x_short = 0;
- if ((a & 0x80) == 0) {
- sj.x_short = (unsigned)a & 0xff; /* Single byte */
- kanji = kana = 0;
- } else { /* Double byte */
- c7 = a & 0x7f;
- if (c7 > 0x20 && c7 < 0x7f) { /* Kanji */
- eu.x_char[byteorder] = (CHAR) a; /* Store first byte */
- bn++; /* Set up for second byte */
- kanji = 1;
- kana = 0;
- return(0);
- } else if (a == 0x8e) { /* SS2 -- Katakana prefix */
- eu.x_char[byteorder] = (CHAR) a; /* Save it */
- bn++;
- kana = 1;
- kanji = 0;
- return(0);
- } else {
- bad++;
- }
- }
- break;
- case 1: /* Byte 1 */
- bn = 0;
- if (kanji) {
- eu.x_char[1-byteorder] = (CHAR) a;
- sj.x_short = eu_to_sj(eu.x_short);
- break;
- } else if (kana) {
- sj.x_short = (CHAR) (a | 0x80);
- break;
- } else { /* (shouldn't happen) */
- bad++;
- }
- }
- /* Come here with one Shift-JIS character */
-
-#ifdef UNICODE
- if (bad) {
- uc.x_short = 0xfffd;
- } else {
- uc.x_short = sj_to_un(sj.x_short); /* Convert to Unicode */
- }
- haveuc = 1;
-#endif /* UNICODE */
- } else
-#endif /* KANJI */
-
-#ifdef UNICODE
- uc.x_short = (unsigned)a & 0xff; /* Latin-1 or whatever... */
-
- /* Come here with uc = the character to be translated. */
- /* If (haveuc) it's UCS-2 in native order, otherwise it's a byte. */
-
- debug(F101,"xpnbyte haveuc","",haveuc);
-
- if (haveuc) { /* If we have a Unicode... */
- debug(F001,"xpnbyte uc.x_short","[A]",uc.x_short);
- debug(F101,"xpnbyte feol","",feol);
- if (what & W_XFER) { /* If transferring a file */
- if (feol && uc.x_short == CR) { /* handle eol conversion. */
- return(0);
- } else if (feol && uc.x_short == LF) {
- uc.x_short = feol;
- }
- }
- debug(F001,"xpnbyte uc.x_short","[B]",uc.x_short);
- if (fcs == FC_UCS2) { /* And FCS is UCS-2 */
- /* Write out the bytes in the appropriate byte order */
- int count = 0;
-#ifndef IKSDONLY
-#ifdef OS2
- extern int k95stdout,wherex[],wherey[];
- extern unsigned char colorcmd;
- union {
- USHORT ucs2;
- UCHAR bytes[2];
- } output;
-#endif /* OS2 */
-#endif /* IKSDONLY */
- if (!offc && ucsbom) { /* Beginning of file? */
-
-#ifndef IKSDONLY
-#ifdef OS2
- if (fn == NULL && !k95stdout && !inserver) {
- offc++;
-#ifdef COMMENT
- /* Don't print the BOM to the display */
- output.bytes[0] = (!ucsorder ? 0xff : 0xfe);
- output.bytes[1] = (!ucsorder ? 0xfe : 0xff);
-
- VscrnWrtUCS2StrAtt(VCMD,
- &output.ucs2,
- 1,
- wherey[VCMD],
- wherex[VCMD],
- &colorcmd
- );
-#endif /* COMMENT */
- } else
-#endif /* OS2 */
-#endif /* IKSDONLY */
- {
- if ((rc = pnbyte((ucsorder ? 0xff : 0xfe),fn)) < 0)
- return(rc); /* BOM */
- if ((rc = pnbyte((ucsorder ? 0xfe : 0xff),fn)) < 0)
- return(rc);
- }
- count += 2;
- }
- if (utferror) {
-#ifndef IKSDONLY
-#ifdef OS2
- if (fn == NULL && !k95stdout && !inserver) {
- offc++;
- output.bytes[0] = (!ucsorder ? 0xfd : 0xff);
- output.bytes[1] = (!ucsorder ? 0xff : 0xfd);
-
- VscrnWrtUCS2StrAtt(VCMD,
- &output.ucs2,
- 1,
- wherey[VCMD],
- wherex[VCMD],
- &colorcmd
- );
- } else
-#endif /* OS2 */
-#endif /* IKSDONLY */
- {
- if ((rc = pnbyte((ucsorder ? 0xfd : 0xff),fn)) < 0)
- return(rc);
- if ((rc = pnbyte((ucsorder ? 0xff : 0xfd),fn)) < 0)
- return(rc);
- }
- count += 2;
- }
-#ifndef IKSDONLY
-#ifdef OS2
- if (fn == NULL && !k95stdout && !inserver) {
- offc++;
- output.bytes[0] = uc.x_char[swapping];
- output.bytes[1] = uc.x_char[1-swapping];
-
- VscrnWrtUCS2StrAtt(VCMD,
- &output.ucs2,
- 1,
- wherey[VCMD],
- wherex[VCMD],
- &colorcmd
- );
- } else
-#endif /* OS2 */
-#endif /* IKSDONLY */
- {
- if ((rc = pnbyte(uc.x_char[swapping],fn)) < 0)
- return(rc);
- if ((rc = pnbyte(uc.x_char[1-swapping],fn)) < 0)
- return(rc);
- }
- count += 2;
- return(count);
- } else if (fcs == FC_UTF8) { /* Convert to UTF-8 */
- CHAR * buf = NULL;
- int i, count;
- if (utferror) {
- if ((rc = pnbyte((ucsorder ? 0xbd : 0xff),fn)) < 0)
- return(rc);
- if ((rc = pnbyte((ucsorder ? 0xff : 0xbd),fn)) < 0)
- return(rc);
- }
- if ((count = ucs2_to_utf8(uc.x_short,&buf)) < 1)
- return(-1);
- debug(F011,"xpnbyte buf",buf,count);
- for (i = 0; i < count; i++)
- if ((rc = pnbyte(buf[i],fn)) < 0)
- return(rc);
- if (utferror)
- count += 2;
- return(count);
- } else { /* Translate UCS-2 to byte */
- if (uc.x_short == 0x2028 || uc.x_short == 0x2029) {
- if (utferror)
- pnbyte(UNK,fn);
- if (feol)
- return(pnbyte((CHAR)feol,fn));
- if ((rc = pnbyte((CHAR)CR,fn)) < 0)
- return(rc);
- if ((rc = pnbyte((CHAR)LF,fn)) < 0)
- return(rc);
- else
- return(utferror ? 3 : 2);
- } else if (xuf) { /* UCS-to-FCS function */
- int x = 0;
- if (utferror)
- pnbyte(UNK,fn);
- if ((rc = (*xuf)(uc.x_short)) < 0) /* These can fail... */
- ch = UNK;
- else
- ch = (unsigned)((unsigned)rc & 0xffff);
- x = pnbyte(ch,fn);
- if (x < 0)
- return(x);
- else if (utferror)
- x++;
- return(x);
-#ifdef KANJI
-
-/* Also see the non-Unicode Kanji section further down in this function. */
-
- } else if (fcsinfo[fcs].alphabet == AL_JAPAN) {
-
- /* Translate UCS-2 to Japanese set */
- debug(F001,"xpnbyte uc","",uc.x_short);
- sj.x_short = un_to_sj(uc.x_short); /* First to Shift-JIS */
- debug(F001,"xpnbyte sj","",sj.x_short);
-
- switch (fcs) { /* File character set */
- case FC_SHJIS: /* Shift-JIS -- just output it */
- if (sj.x_char[byteorder]) /* But not high byte if zero */
- if ((rc = pnbyte((CHAR)sj.x_char[byteorder],fn)) < 0)
- return(rc);
- if ((rc = pnbyte((CHAR)sj.x_char[1-byteorder],fn)) < 0)
- return(rc);
- return(2);
- case FC_JEUC: /* EUC-JP */
- eu.x_short = sj_to_eu(sj.x_short); /* Shift-JIS to EUC */
- debug(F001,"xpnbyte eu","",eu.x_short);
- if (eu.x_short == 0xffff) { /* Bad */
- if ((rc = pnbyte(UNK,fn)) < 0)
- return(rc);
- return(1);
- } else { /* Good */
- int count = 0; /* Write high byte if not zero */
- if (eu.x_char[byteorder]) {
- if ((rc=pnbyte((CHAR)eu.x_char[byteorder],fn)) < 0)
- return(rc);
- count++;
- }
- /* Always write low byte */
- if ((rc = pnbyte((CHAR)eu.x_char[1-byteorder],fn)) < 0)
- return(rc);
- count++;
- return(count);
- }
- break;
-
- case FC_JIS7: /* JIS-7 */
- case FC_JDEC: /* DEC Kanji */
- eu.x_short = sj_to_eu(sj.x_short); /* Shift-JIS to EUC */
- if (eu.x_short == 0xffff) { /* Bad */
- debug(F001,"xpnbyte bad eu","",eu.x_short);
- if ((rc = pnbyte(UNK,fn)) < 0)
- return(rc);
- return(1);
- } else { /* Good */
- int i;
- /* Use another name - 'a' hides parameter */
- /* It's OK as is but causes compiler warnings */
- char a = eu.x_char[1-byteorder]; /* Low byte */
- debug(F001,"xpnbyte eu","",eu.x_short);
- if (eu.x_char[byteorder] == 0) { /* Roman */
- switch (jstate) {
- case 1: /* Current state is Katakana */
- jbuf[0] = 0x0f; /* SI */
- jbuf[1] = a;
- jx = 2;
- break;
- case 2: /* Current state is Kanji */
- jbuf[0] = 0x1b; /* ESC */
- jbuf[1] = 0x28; /* ( */
- jbuf[2] = 0x4a; /* J */
- jbuf[3] = a;
- jx = 4;
- break;
- default: /* Current state is Roman */
- jbuf[0] = a;
- jx = 1;
- break;
- }
- jstate = 0; /* New state is Roman */
- } else if (eu.x_char[byteorder] == 0x8e) { /* Kana */
- jx = 0;
- switch (jstate) {
- case 2: /* from Kanji */
- jbuf[jx++] = 0x1b; /* ESC */
- jbuf[jx++] = 0x28; /* ( */
- jbuf[jx++] = 0x4a; /* J */
- case 0: /* from Roman */
- jbuf[jx++] = 0x0e; /* SO */
- default: /* State is already Kana*/
- jbuf[jx++] = (a & 0x7f); /* and the char */
- break;
- }
- jstate = 1; /* New state is Katakana */
- } else { /* Kanji */
- jx = 0;
- switch (jstate) {
- case 1: /* Current state is Katakana */
- jbuf[jx++] = 0x0f; /* SI */
- case 0: /* Current state is Roman */
- jbuf[jx++] = 0x1b; /* ESC */
- jbuf[jx++] = 0x24; /* $ */
- jbuf[jx++] = 0x42; /* B */
- default: /* Current state is already Kanji */
- jbuf[jx++] = eu.x_char[byteorder] & 0x7f;
- jbuf[jx++] = eu.x_char[1-byteorder] & 0x7f;
- break;
- }
- jstate = 2; /* Set state to Kanji */
- }
- for (i = 0; i < jx; i++) /* Output the result */
- if ((rc = pnbyte(jbuf[i],fn)) < 0)
- return(rc);
- return(jx); /* Return its length */
- }
- }
-#endif /* KANJI */
- } else { /* No translation function */
- int count = 0;
- if (utferror) {
- if ((rc = pnbyte((ucsorder ? 0xfd : 0xff),fn)) < 0)
- return(rc);
- if ((rc = pnbyte((ucsorder ? 0xff : 0xfd),fn)) < 0)
- return(rc);
- count += 2;
- }
- if ((rc = pnbyte(uc.x_char[swapping],fn)) < 0)
- return(rc);
- if ((rc = pnbyte(uc.x_char[1-swapping],fn)) < 0)
- return(rc);
- count += 2;
- return(count);
- }
- }
- } else { /* Byte to Unicode */
- if (xtu) { /* TCS-to-UCS function */
- if (((tcsinfo[tcs].size > 128) && (uc.x_short & 0x80)) ||
- tcsinfo[tcs].size <= 128)
- uc.x_short = (*xtu)(uc.x_short);
- }
- if (fcs == FC_UCS2) { /* And FCS is UCS-2 */
- /* Write out the bytes in the appropriate byte order */
- if (!offc && ucsbom) { /* Beginning of file? */
- if ((rc = pnbyte((ucsorder ? 0xff : 0xfe),fn)) < 0) /* BOM */
- return(rc);
- if ((rc = pnbyte((ucsorder ? 0xfe : 0xff),fn)) < 0)
- return(rc);
- }
- if ((rc = pnbyte(uc.x_char[swapping],fn)) < 0)
- return(rc);
- if ((rc = pnbyte(uc.x_char[1-swapping],fn)) < 0)
- return(rc);
- return(2);
- } else if (fcs == FC_UTF8) { /* Convert to UTF-8 */
- CHAR * buf = NULL;
- int i, count;
- if ((count = ucs2_to_utf8(uc.x_short,&buf)) < 1)
- return(-1);
- for (i = 0; i < count; i++)
- if ((rc = pnbyte(buf[i],fn)) < 0)
- return(rc);
- return(count);
- } else {
- debug(F100,"xpnbyte impossible combination","",0);
- return(-1);
- }
- }
-#else
-#ifdef KANJI
-/*
- This almost, but not quite, duplicates the Kanji section above.
- There is no doubt a way to combine the sections more elegantly,
- but probably only at the expense of additional execution overhead.
- As matters stand, be careful to reflect any changes in this section
- to the other Kanji section above.
-*/
- if (tcs == TC_JEUC) { /* Incoming Japanese EUC */
- int count = 0;
- switch (fcs) { /* File character set */
- case FC_SHJIS: /* Shift-JIS -- just output it */
- if (sj.x_char[byteorder]) /* But not high byte if zero */
- if ((rc = pnbyte((CHAR)sj.x_char[byteorder],fn)) < 0)
- return(rc);
- count++;
- if ((rc = pnbyte((CHAR)sj.x_char[1-byteorder],fn)) < 0)
- return(rc);
- count++;
- return(count);
- case FC_JEUC: /* EUC-JP */
- eu.x_short = sj_to_eu(sj.x_short); /* Shift-JIS to EUC */
- debug(F001,"xpnbyte FC_JEUC eu","",eu.x_short);
- if (eu.x_short == 0xffff) { /* Bad */
- if ((rc = pnbyte(UNK,fn)) < 0)
- return(rc);
- return(1);
- } else { /* Good */
- int count = 0; /* Write high byte if not zero */
- if (eu.x_char[byteorder]) {
- if ((rc = pnbyte((CHAR)eu.x_char[byteorder],fn)) < 0)
- return(rc);
- count++;
- }
- /* Always write low byte */
- if ((rc = pnbyte((CHAR)eu.x_char[1-byteorder],fn)) < 0)
- return(rc);
- count++;
- return(count);
- }
- break;
-
- case FC_JIS7: /* JIS-7 */
- case FC_JDEC: /* DEC Kanji */
- eu.x_short = sj_to_eu(sj.x_short); /* Shift-JIS to EUC */
- if (eu.x_short == 0xffff) { /* Bad */
- debug(F001,"xpnbyte FC_JIS7 bad eu","",eu.x_short);
- if ((rc = pnbyte(UNK,fn)) < 0)
- return(rc);
- return(1);
- } else { /* Good */
- int i;
- char a = eu.x_char[1-byteorder]; /* Low byte */
- debug(F001,"xpnbyte FC_JIS7 eu","",eu.x_short);
- if (eu.x_char[byteorder] == 0) { /* Roman */
- switch (jstate) {
- case 1: /* Current state is Katakana */
- jbuf[0] = 0x0f; /* SI */
- jbuf[1] = a;
- jx = 2;
- break;
- case 2: /* Current state is Kanji */
- jbuf[0] = 0x1b; /* ESC */
- jbuf[1] = 0x28; /* ( */
- jbuf[2] = 0x4a; /* J */
- jbuf[3] = a;
- jx = 4;
- break;
- default: /* Current state is Roman */
- jbuf[0] = a;
- jx = 1;
- break;
- }
- jstate = 0; /* New state is Roman */
- } else if (eu.x_char[byteorder] == 0x8e) { /* Kana */
- jx = 0;
- switch (jstate) {
- case 2: /* from Kanji */
- jbuf[jx++] = 0x1b; /* ESC */
- jbuf[jx++] = 0x28; /* ( */
- jbuf[jx++] = 0x4a; /* J */
- case 0: /* from Roman */
- jbuf[jx++] = 0x0e; /* SO */
- default: /* State is already Kana*/
- jbuf[jx++] = (a & 0x7f); /* and the char */
- break;
- }
- jstate = 1; /* New state is Katakana */
- } else { /* Kanji */
- jx = 0;
- switch (jstate) {
- case 1: /* Current state is Katakana */
- jbuf[jx++] = 0x0f; /* SI */
- case 0: /* Current state is Roman */
- jbuf[jx++] = 0x1b; /* ESC */
- jbuf[jx++] = 0x24; /* $ */
- jbuf[jx++] = 0x42; /* B */
- default: /* Current state is already Kanji */
- jbuf[jx++] = eu.x_char[byteorder] & 0x7f;
- jbuf[jx++] = eu.x_char[1-byteorder] & 0x7f;
- break;
- }
- jstate = 2; /* Set state to Kanji */
- }
- for (i = 0; i < jx; i++) /* Output the result */
- if ((rc = pnbyte(jbuf[i],fn)) < 0)
- return(rc);
- return(jx); /* Return its length */
- }
- default:
- if (sj.x_short < 0x80)
- return(sj.x_short);
- else
- return('?');
- }
- }
-#endif /* KANJI */
-#endif /* UNICODE */
- debug(F100,"xpnbyte BAD FALLTHRU","",0);
- return(-1);
-}
-
-#ifndef NOXFER
-
-/* D E C O D E -- Kermit Data-packet decoder */
-
-int
-#ifdef CK_ANSIC
-decode(CHAR *buf, int (*fn)(char), int xlate)
-#else
-decode(buf,fn,xlate) register CHAR *buf; register int (*fn)(); int xlate;
-#endif /* CK_ANSIC */
-/* decode */ {
- register unsigned int a, a7, a8, b8; /* Various copies of current char */
- int t; /* Int version of character */
- int ssflg; /* Character was single-shifted */
- int ccpflg; /* For Ctrl-unprefixing stats */
- int len;
- long z;
- CHAR c;
-/*
- Catch the case in which we are asked to decode into a file that is not open,
- for example, if the user interrupted the transfer, but the other Kermit
- keeps sending.
-*/
- if ((cxseen || czseen || discard) && (fn == putfil))
- return(0);
-
-#ifdef COMMENT
-#ifdef CKTUNING
- if (binary && !parity)
- return(bdecode(buf,fn));
-#endif /* CKTUNING */
-#endif /* COMMENT */
- debug(F100,"DECODE","",0);
-
- xdbuf = buf; /* Make global copy of pointer. */
- rpt = 0; /* Initialize repeat count. */
-
- len = rln; /* Number of bytes in data field */
- while (len > 0) { /* Loop for each byte */
- a = *xdbuf++ & 0xff; /* Get next character */
- len--;
- if (a == rptq && rptflg) { /* Got a repeat prefix? */
- rpt = xunchar(*xdbuf++ & 0xFF); /* Yes, get the repeat count, */
- rptn += rpt;
- a = *xdbuf++ & 0xFF; /* and get the prefixed character. */
- len -= 2;
- }
- b8 = lsstate ? 0200 : 0; /* 8th-bit value from SHIFT-STATE */
- if (ebqflg && a == ebq) { /* Have 8th-bit prefix? */
- b8 ^= 0200; /* Yes, invert the 8th bit's value, */
- ssflg = 1; /* remember we did this, */
- a = *xdbuf++ & 0xFF; /* and get the prefixed character. */
- len--;
- } else ssflg = 0;
- ccpflg = 0;
- if (a == ctlq) { /* If control prefix, */
- a = *xdbuf++ & 0xFF; /* get its operand */
- len--;
- a7 = a & 0x7F; /* and its low 7 bits. */
- if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') { /* Controllify */
- a = ctl(a); /* if in control range. */
- a7 = a & 0x7F;
- ccpflg = 1; /* Note that we did this */
- ccp++; /* Count for stats */
- }
- } else a7 = a & 0x7f; /* Not control quote */
- if (a7 < 32 || a7 == 127) { /* Control character? */
- if (!ccpflg) ccu++; /* A bare one, count it */
- if (lscapu) { /* If doing locking shifts... */
- if (lsstate) /* If SHIFTED */
- a8 = (a & ~b8) & 0xFF; /* Invert meaning of 8th bit */
- else /* otherwise */
- a8 = a | b8; /* OR in 8th bit */
- /* If we're not in a quoted sequence */
- if (!lsquote && (!lsstate || !ssflg)) {
- if (a8 == DLE) { /* Check for DLE quote */
- lsquote = 1; /* prefixed by single shift! */
- continue;
- } else if (a8 == SO) { /* Check for Shift-Out */
- lsstate = 1; /* SHIFT-STATE = SHIFTED */
- continue;
- } else if (a8 == SI) { /* or Shift-In */
- lsstate = 0; /* SHIFT-STATE = UNSHIFTED */
- continue;
- }
- } else lsquote = 0;
- }
- }
- a |= b8; /* OR in the 8th bit */
- if (rpt == 0) rpt = 1; /* If no repeats, then one */
-#ifndef NOCSETS
- if (!binary) { /* If in text mode, */
- if (tcharset != TC_UCS2) {
- if (feol && a == CR) /* Convert CRLF to newline char */
- continue;
- if (feol && a == LF)
- a = feol;
- }
- if (xlatype == XLA_BYTE) /* Byte-for-byte - do it now */
- if (xlate && rx) a = (*rx)((CHAR) a);
- }
-#endif /* NOCSETS */
- /* (PWP) Decoding speedup via buffered output and a macro... */
- if (fn == putfil) {
- for (; rpt > 0; rpt--) { /* Output the char RPT times */
-#ifdef CALIBRATE
- if (calibrate) {
- ffc++;
- continue;
- }
-#endif /* CALIBRATE */
-
-/* Note: The Unicode and Kanji sections can probably be combined now; */
-/* the Unicode method (xpnbyte()) covers Kanji too. */
-
-#ifdef UNICODE
- if (!binary && xlatype == XLA_UNICODE)
- t = xpnbyte((unsigned)((unsigned)a & 0xff),
- tcharset,
- fcharset,
- fn
- );
- else
-#endif /* UNICODE */
-#ifdef KANJI
- if (!binary && tcharset == TC_JEUC &&
- fcharset != FC_JEUC) { /* Translating from J-EUC */
- if (!ffc) xkanjf();
- if (xkanji(a,fn) < 0) /* to something else? */
- return(-1);
- else t = 1;
- } else
-#endif /* KANJI */
- {
-#ifdef OS2
- if (xflg && !remfile) { /* Write to virtual screen */
- char _a;
- _a = a & fmask;
- t = conoc(_a);
- if (t < 1)
- t = -1;
- } else
-#endif /* OS2 */
- t = zmchout(a & fmask); /* zmchout is a macro */
- }
- if (t < 0) {
- debug(F101,"decode write errno","",errno);
- return(-1);
- }
-#ifdef UNICODE
- if (xlatype != XLA_UNICODE || binary) {
- ffc++; /* Count the character */
- if (docrc && !xflg && !remfile) { /* Update file CRC */
- c = a; /* Force conversion to unsigned char */
- z = crc16 ^ (long)c;
- crc16 = (crc16 >> 8) ^
- (crcta[(z & 0xF0) >> 4] ^ crctb[z & 0x0F]);
- }
- }
-#endif /* UNICODE */
- }
- } else { /* Output to something else. */
- a &= fmask; /* Apply file mask */
- for (; rpt > 0; rpt--) { /* Output the char RPT times */
-#ifdef CALIBRATE
- if (calibrate) {
- ffc++;
- continue;
- }
-#endif /* CALIBRATE */
- if ((*fn)((char) a) < 0) return(-1); /* Send to output func. */
- }
- }
-#ifdef CK_CTRLZ
- lastchar = a;
-#endif /* CK_CTRLZ */
- }
- return(0);
-}
-
-/* G E T P K T -- Fill a packet data field */
-
-/*
- Gets characters from the current source -- file or memory string.
- Encodes the data into the packet, filling the packet optimally.
- Set first = 1 when calling for the first time on a given input stream
- (string or file).
-
- Call with:
- bufmax -- current send-packet size
- xlate -- flag: 0 to skip character-set translation, 1 to translate
-
- Uses global variables:
- t -- current character.
- first -- flag: 1 to start up, 0 for input in progress, -1 for EOF.
- next -- next character (not used any more).
- data -- pointer to the packet data buffer.
- size -- number of characters in the data buffer.
- memstr - flag that input is coming from a memory string instead of a file.
- memptr - pointer to string in memory.
- (*sx)() character set translation function
-
- Returns:
- The size as value of the function, and also sets global "size",
- and fills (and null-terminates) the global data array.
- Returns:
- 0 on EOF.
- -1 on fatal (internal) error.
- -3 on timeout (e.g. when reading data from a pipe).
-
- Rewritten by Paul W. Placeway (PWP) of Ohio State University, March 1989.
- Incorporates old getchx() and encode() inline to reduce function calls,
- uses buffered input for much-improved efficiency, and clears up some
- confusion with line termination (CRLF vs LF vs CR).
-
- Rewritten again by Frank da Cruz to incorporate locking shift mechanism,
- May 1991. And again in 1998 for efficiency, etc, with a separate
- bgetpkt() split out for binary-mode no-parity transfers.
-*/
-
-/*
- Note: Separate Kanji support dates from circa 1991 and now (1999) can most
- likely be combined with the the Unicode support: the xgnbyte()/xpnbyte()
- mechanism works for both Unicode and Kanji.
-*/
-#ifdef KANJI
-int
-kgetf(
-#ifdef CK_ANSIC
- VOID
-#endif /* CK_ANSIC */
- ) {
- if (funcstr)
- return((*funcptr)());
- else
- return(zminchar());
-}
-
-int
-kgetm(
-#ifdef CK_ANSIC
- VOID
-#endif /* CK_ANSIC */
- ) {
- int x;
- if ((x = *memptr++)) return(x);
- else return(-1);
-}
-#endif /* KANJI */
-
-/*
- Lookahead function to decide whether locking shift is worth it. Looks at
- the next four input characters to see if all of their 8th bits match the
- argument. Call with 0 or 0200. Returns 1 on match, 0 if they don't match.
- If we don't happen to have at least 4 more characters waiting in the input
- buffer, returns 1. Note that zinptr points two characters ahead of the
- current character because of repeat-count lookahead.
-*/
-int
-lslook(b) unsigned int b; { /* Locking Shift Lookahead */
- int i;
- if (zincnt < 3) /* If not enough chars in buffer, */
- return(1); /* force shift-state switch. */
- b &= 0200; /* Force argument to proper form. */
- for (i = -1; i < 3; i++) /* Look at next 5 characters to */
- if (((*(zinptr+i)) & 0200) != b) /* see if all their 8th bits match. */
- return(0); /* They don't. */
- return(1); /* They do. */
-}
-
-/* Routine to compute maximum data length for packet to be filled */
-
-int
-maxdata() { /* Get maximum data length */
- int n, len;
- debug(F101,"maxdata spsiz 1","",spsiz);
- if (spsiz < 0) /* How could this happen? */
- spsiz = DSPSIZ;
- debug(F101,"maxdata spsiz 2","",spsiz);
- n = spsiz - 5; /* Space for Data and Checksum */
- if (n > 92 && n < 96) n = 92; /* "Short" Long packets don't pay */
- if (n > 92 && lpcapu == 0) /* If long packets needed, */
- n = 92; /* make sure they've been negotiated */
- len = n - bctl; /* Space for data */
- if (n > 92) len -= 3; /* Long packet needs header chksum */
- debug(F101,"maxdata len 1","",len);
- if (len < 0) len = 10;
- debug(F101,"maxdata len 2","",len);
- return(len);
-}
-
-static CHAR leftover[9] = { '\0','\0','\0','\0','\0','\0','\0','\0','\0' };
-static int nleft = 0;
-
-#ifdef CKTUNING
-/*
- When CKTUNING is defined we use this special trimmed-down version of getpkt
- to speed up binary-mode no-parity transfers. When CKTUNING is not defined,
- or for text-mode or parity transfers, we use the regular getpkt() function.
- Call just like getpkt() but test first for transfer mode and parity. NOTE:
- This routine is only to be called when sending a real file -- not for
- filenames, server responses, etc, because it only reads from the input file.
- See getpkt() for more detailed commentary.
-*/
-static int
-bgetpkt(bufmax) int bufmax; {
- register CHAR rt = t, rnext;
- register CHAR *dp, *odp, *p1, *p2;
- register int x = 0, a7;
-
- CHAR xxrc, xxcq; /* Pieces of prefixed sequence */
-
- long z; /* A long worker (for CRC) */
-
- if (!binary || parity || memstr) /* JUST IN CASE caller didn't test */
- return(getpkt(bufmax,!binary));
-
- if (!data) {
- debug(F100,"SERIOUS ERROR: bgetpkt data == NULL","",0);
- return(-1);
- }
- dp = data; /* Point to packet data buffer */
- size = 0; /* And initialize its size */
- bufmax = maxdata(); /* Get maximum data length */
-
-#ifdef DEBUG
- if (deblog)
- debug(F101,"bgetpkt bufmax","",bufmax);
-#endif /* DEBUG */
-
- if (first == 1) { /* If first character of this file.. */
- ffc = (CK_OFF_T)0; /* reset file character counter */
-#ifdef COMMENT
-/* Moved to below */
- first = 0; /* Next character won't be first */
-#endif /* COMMENT */
- *leftover = '\0'; /* Discard any interrupted leftovers */
- nleft = 0;
-
- /* Get first character of file into rt, watching out for null file */
-
-#ifdef CALIBRATE
- if (calibrate) {
-#ifdef NORANDOM
- rt = 17;
-#else
- rt = cal_a[rand() & 0xff];
-#endif /* NORANDOM */
- first = 0;
- } else
-#endif /* CALIBRATE */
-
- if ((x = zminchar()) < 0) { /* EOF or error */
- if (x == -3) { /* Timeout. */
- size = (dp - data);
- debug(F101,"bgetpkt timeout size","",size);
- return((size == 0) ? x : size);
- }
- first = -1;
- size = 0;
- if (x == -2) { /* Error */
- debug(F100,"bgetpkt: input error","",0);
- cxseen = 1; /* Interrupt the file transfer */
- } else {
- debug(F100,"bgetpkt empty file","",0);
- }
- return(0);
- }
- first = 0; /* Next char will not be the first */
- ffc++; /* Count a file character */
- rt = (CHAR) x; /* Convert int to char */
- if (docrc && (what & W_SEND)) { /* Accumulate file crc */
- z = crc16 ^ (long)rt;
- crc16 = (crc16 >> 8) ^
- (crcta[(z & 0xF0) >> 4] ^ crctb[z & 0x0F]);
- }
- rt &= fmask; /* Apply SET FILE BYTESIZE mask */
-
- } else if (first == -1 && nleft == 0) { /* EOF from last time */
-
- return(size = 0);
- }
-/*
- Here we handle characters that were encoded for the last packet but
- did not fit, and so were saved in the "leftover" array.
-*/
- if (nleft) {
- for (p1 = leftover; nleft > 0; nleft--) /* Copy leftovers */
- *dp++ = *p1++;
- *leftover = '\0'; /* Delete leftovers */
- nleft = 0;
- }
- if (first == -1) /* Handle EOF */
- return(size = (dp - data));
-
-/* Now fill up the rest of the packet. */
-
- rpt = 0; /* Initialize character repeat count */
-
- while (first > -1) { /* Until EOF... */
-#ifdef CALIBRATE
- if (calibrate) { /* We generate our own "file" */
- if (ffc >= calibrate) { /* EOF */
- first = -1;
- ffc--;
- } else { /* Generate next character */
- if (cal_j > CAL_M * ffc)
- cal_j = cal_a[ffc & 0xff];
- x = (unsigned)cal_a[(cal_j & 0xff)];
- if (x == rt) x ^= 2;
- }
- ffc++;
- cal_j += (unsigned int)(ffc + CAL_O);
- } else
-#endif /* CALIBRATE */
- if ((x = zminchar()) < 0) { /* Check for EOF */
- if (x == -3) { /* Timeout. */
- t = rt;
- size = (dp-data);
- debug(F101,"bgetpkt timeout size","",size);
- return((size == 0) ? x : size);
- }
- first = -1; /* Flag eof for next time. */
- if (x == -2) cxseen = 1; /* If error, cancel this file. */
- } else {
- ffc++; /* Count the character */
- if (docrc && (what & W_SEND)) { /* Accumulate file crc */
- z = crc16 ^ (long)((CHAR)x & 0xff);
- crc16 = (crc16 >> 8) ^
- (crcta[(z & 0xF0) >> 4] ^ crctb[z & 0x0F]);
- }
- }
- rnext = (CHAR) (x & fmask); /* Apply file mask */
-/*
- At this point, the character we just read is in rnext,
- and the character we are about to encode into the packet is in rt.
-*/
- odp = dp; /* Remember where we started. */
- xxrc = xxcq = NUL; /* Clear these. */
-/*
- Now encode the character according to the options that are in effect:
- ctlp[]: whether this control character needs prefixing.
- rptflg: repeat counts enabled.
- Other options don't apply in this routine.
-*/
- if (rptflg && (rt == rnext) && (first == 0)) { /* Got a run... */
- if (++rpt < 94) { /* Below max, just count */
- continue; /* go back and get another */
- } else if (rpt == 94) { /* Reached max, must dump */
- xxrc = (CHAR) tochar(rpt); /* Put the repeat count here */
- rptn += rpt; /* Accumulate it for statistics */
- rpt = 0; /* And reset it */
- }
- } else if (rpt > 0) { /* End of run */
- xxrc = (CHAR)tochar(++rpt); /* The count */
- rptn += rpt; /* For stats */
- rpt = 0; /* Reset repeat count */
- }
- a7 = rt & 0177; /* Get low 7 bits of character */
- if (
-#ifdef CK_SPEED
- ctlp[(unsigned)(rt & 0xff)] /* Lop off any "sign" extension */
-#else
- (a7 < SP) || (a7 == DEL)
-#endif /* CK_SPEED */
- ) { /* Do control prefixing if necessary */
- xxcq = myctlq; /* The prefix */
- ccp++; /* Count it */
- rt = (CHAR) ctl(rt); /* Uncontrollify the character */
- }
-#ifdef CK_SPEED
- else if ((a7 < SP) || (a7 == DEL)) /* Count an unprefixed one */
- ccu++;
-#endif /* CK_SPEED */
-
- if (a7 == myctlq) /* Always prefix the control prefix */
- xxcq = myctlq;
-
- if ((rptflg) && (a7 == rptq)) /* If it's the repeat prefix, */
- xxcq = myctlq; /* prefix it if doing repeat counts */
-
-/* Now construct the prefixed sequence */
-
- if (xxrc) { /* Repeat count */
-#ifdef COMMENT
- if (xxrc == (CHAR) '"' && !xxcq) { /* 2 in a row & not prefixed */
- *dp++ = rt; /* So just do this */
- } else { /* More than two or prefixed */
- *dp++ = (CHAR) rptq; *dp++ = xxrc; /* Emit repeat sequence */
- }
-#else /* CHECK THIS */
- if (xxrc == (CHAR) '"' && !xxcq) { /* 2 in a row & not prefixed */
- if (dp == data) {
- *dp++ = rt; /* So just do this */
- } else if (*(dp-1) == rt) {
- *dp++ = (CHAR) rptq;
- *dp++ = xxrc; /* Emit repeat sequence */
- } else {
- *dp++ = rt; /* So just do this */
- }
- } else { /* More than two or prefixed */
- *dp++ = (CHAR) rptq;
- *dp++ = xxrc; /* Emit repeat sequence */
- }
-#endif /* COMMENT */
- }
- if (xxcq) { *dp++ = myctlq; } /* Control prefix */
- *dp++ = rt; /* Finally, the character itself */
- rt = rnext; /* Next character is now current. */
-
-/* Done encoding the character. Now take care of packet buffer overflow. */
-
- size = dp - data; /* How many bytes we put in buffer. */
- if (size >= bufmax) { /* If too big, save some for next. */
- *dp = '\0'; /* Mark the end. */
- if (size > bufmax) { /* if packet is overfull */
- /* Copy the part that doesn't fit into the leftover buffer, */
- /* taking care not to split a prefixed sequence. */
- int i;
- nleft = dp - odp;
- p1 = leftover;
- p2 = odp;
- for (i = 0; i < nleft; i++)
- *p1++ = *p2++;
- size = odp - data; /* Return truncated packet. */
- *odp = '\0'; /* Mark the new end */
- }
- t = rt; /* Save for next time */
- return(size);
- }
- } /* Otherwise, keep filling. */
- size = dp - data; /* End of file */
- *dp = '\0'; /* Mark the end of the data. */
- return(size); /* Return partially filled last packet. */
-}
-#endif /* CKTUNING */
-
-VOID
-dofilcrc(c) int c; { /* Accumulate file crc */
- long z;
- z = crc16 ^ (long)c;
- crc16 = (crc16 >> 8) ^
- (crcta[(z & 0xF0) >> 4] ^ crctb[z & 0x0F]);
-}
-
-/* For SENDing from an array... */
-
-int
-agnbyte() { /* Get next byte from array */
-#ifndef NOSPL
- char c;
- static int save = 0; /* For CRLF */
- static char ** ap = NULL; /* Array pointer */
- static char * p = NULL; /* Character pointer */
- static int i = 0, n = 0; /* Array index and limit */
- extern int a_dim[]; /* Array dimension */
-
- if (!ap) { /* First time thru */
- ap = sndarray; /* Set up array pointers */
- if (!ap || (i = sndxlo) > a_dim[sndxin]) {
- sndarray = NULL;
- ap = NULL;
- return(-1);
- }
- p = ap[i]; /* Point to first element in range */
- n = sndxhi; /* Index of last element in range */
- if (sndxhi > a_dim[sndxin]) /* Adjust if necessary */
- n = a_dim[sndxin];
- }
- if (save) { /* If anything saved */
- c = save; /* unsave it */
- save = 0; /* and return it */
- return(c & 0xff);
- }
- if (i > n) { /* No more elements */
- sndarray = NULL;
- ap = NULL;
- return(-1);
- }
- if (!p) /* Source pointer is NULL */
- c = NUL; /* this means an empty line */
- else /* Source pointer not NULL */
- c = *p++; /* Next char */
- if (!c) { /* Char is empty? */
- if (!binary) { /* Text: end of line. */
- if (feol) { /* Supply NL */
- c = feol;
- } else { /* or CRLF */
- save = LF;
- c = CR;
- }
- p = ap[++i];
- return(c & 0xff);
- }
- while (i++ < n) { /* Binary - get next element */
- p = ap[i];
- if (!p) /* Empty line? */
- continue; /* Ignore it and get another */
- c = *p++; /* Get next char */
- if (!c) /* Emtpy char? */
- continue; /* Ignore it and get another */
- return(c & 0xff); /* Not empty - return it */
- }
- sndarray = NULL;
- ap = NULL;
- return(-1); /* Done */
- }
- return(c & 0xff); /* Char is not empty */
-#else
- sndarray = NULL;
- return(-1);
-#endif /* NOSPL */
-}
-#endif /* NOXFER */
-
-#ifndef NOCSETS
-static CHAR xlabuf[32] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-static int xlacount = 0;
-static int xlaptr = 0;
-/* static USHORT lastucs2 = 0; */
-
-/*
- X G N B Y T E -- Get next translated byte from the input file.
-
- Returns the next byte that is to be put into the packet, already translated.
- This isolates getpkt() from having to know anything about translation,
- single- vs multibyte character sets, one-to-many vs many-to-one, etc, but it
- has rather high overhead, so don't call it unless you know translation is
- needed to or from Unicode, Japanese, or other multibyte character set.
-
- Call with:
- fcs: File character set (source, file we are reading from)
- tcs: Target character set (use an FC_xxx code, not a TC_xxx code)
- Returns:
- >= 0: A translated byte suitable for writing.
- < 0: Fatal error (such as EOF on input source).
- As of Sat Sep 7 18:37:41 2002:
- When the output character-set is UCS-2, bytes are ALWAYS returned in
- big-endian order (previously they could also be returned in LE order
- under certain conditions, which was just way too confusing).
-*/
-int
-#ifdef CK_ANSIC
-xgnbyte(int tcs, int fcs, int (*fn)(void))
-#else /* CK_ANSIC */
-xgnbyte(tcs,fcs,fn) int tcs, fcs, (*fn)();
-#endif /* CK_ANSIC */
-/* xgnbyte */ {
- _PROTOTYP( int (*xx), (USHORT) ) = NULL;
- int haveuc = 0; /* Flag for have Unicode character */
-#ifdef KANJI
- int havesj = 0; /* Have Shift-JIS character */
- int haveeu = 0; /* Have EUC-JP character */
-#endif /* KANJI */
- int rc = -1, x = 0, flag = 0;
- int utferror = 0;
- int eolflag = 0;
- unsigned int xc, thischar;
- static int swapping = 0;
- CHAR rt;
- /* USHORT ch; */
-#ifdef UNICODE
- union ck_short uc;
-#endif /* UNICODE */
-#ifdef KANJI
- union ck_short sj, eu; /* Shift-JIS character */
-#endif /* KANJI */
-
-#ifdef KANJI
- sj.x_short = 0;
-#endif /* KANJI */
-
-#ifdef DEBUG
- if (deblog && !ffc) {
- debug(F101,"xgnbyte initial swap","",swapping);
- }
-#endif /* DEBUG */
-
- if (xlacount-- > 0) { /* We already have some */
- x = xlabuf[xlaptr++];
- debug(F001,"xgnbyte from buf","",x);
- return(x);
- }
- if (xlatype != XLA_NONE) { /* Not not translating... */
- haveuc = 0;
-#ifdef UNICODE
- if (fcs == FC_UCS2) { /* UCS-2: Read two bytes */
- if (!ffc) /* Beginning of file? */
- swapping = 0; /* Reset byte-swapping flag */
- uc.x_short = 0;
- bomskip:
- x = fn ? (*fn)() : zminchar(); /* Get first byte */
- debug(F001,"zminchar swapping","",swapping);
- debug(F001,"zminchar C0","",x);
- flag = 1; /* Remember we called zminchar() */
- if (x > -1) { /* Didn't fail */
- ffc++; /* Count a file byte */
- uc.x_char[swapping] = x & 0xff;
-#ifndef NOXFER
- if (docrc && (what & W_SEND))
- dofilcrc(x);
-#endif /* NOXFER */
- x = fn ? (*fn)() : zminchar(); /* Get second byte */
- if (x > -1) { /* If didn't fail */
- debug(F001,"zminchar C1","",x);
- ffc++; /* count another file byte */
- uc.x_char[1-swapping] = x & 0xff;
- haveuc = 1; /* And remember we have Unicode */
-#ifndef NOXFER
- if (docrc && (what & W_SEND))
- dofilcrc(x);
-#endif /* NOXFER */
- if (ffc == (CK_OFF_T)2) { /* Second char of file */
- debug(F001,"xgnbyte 1st UCS2","",uc.x_short);
- debug(F111,"xgnbyte fileorder","A",fileorder);
- if (fileorder < 0) /* Byte order of this file */
- fileorder = ucsorder; /* Default is ucsorder */
- if (fileorder > 1)
- fileorder = 1;
- debug(F111,"xgnbyte fileorder","B",fileorder);
- if (uc.x_short == (USHORT)0xfeff) {
- swapping = 0;
- debug(F101,
- "xgnbyte UCS2 goodbom swap","",swapping);
- fileorder = byteorder; /* Note: NOT 0 */
- goto bomskip;
- } else if (uc.x_short == (USHORT)0xfffe) {
- swapping = 1;
- debug(F101,
- "xgnbyte UCS2 badbom swap","",swapping);
- fileorder = (1 - byteorder); /* Note: NOT 1 */
- goto bomskip;
- } else if ((byteorder && !fileorder) || /* No BOM */
- (!byteorder && fileorder > 0)) {
- /* fileorder might have been set by scanfile() */
- CHAR c;
- c = uc.x_char[0];
- uc.x_char[0] = uc.x_char[1];
- uc.x_char[1] = c;
- swapping = 1;
- debug(F111,"xgnbyte UCS2 noBOM swap","A",swapping);
- } else {
- swapping = 0;
- debug(F111,"xgnbyte UCS2 noBOM swap","B",swapping);
- }
- debug(F111,"xgnbyte fileorder","C",fileorder);
- }
- } else
- return(x);
- } else
- return(x);
- debug(F001,"xgnbyte UCS2","",uc.x_short);
-
- } else if (fcs == FC_UTF8) { /* File is UTF-8 */
- CHAR ch = 0; /* Data types needed for API... */
- USHORT * us = NULL;
- uc.x_short = 0;
- flag = 1; /* We (will) have called zminchar() */
- /* Read source bytes */
- while ((x = fn ? (*fn)() : zminchar()) > -1) {
- ffc++; /* Got a byte - count it */
-#ifndef NOXFER
- if (docrc && (what & W_SEND))
- dofilcrc(x);
-#endif /* NOXFER */
- ch = x;
- rc = utf8_to_ucs2(ch,&us); /* Convert to UCS-2 */
- if (rc == 0) { /* Done */
- uc.x_short = *us;
- haveuc = 1;
- break;
- } else if (rc < 0) { /* Error */
- utferror = 1;
- debug(F101,"xgnbyte UTF-8 input error","",rc);
- haveuc = 1;
- uc.x_short = *us;
- break;
- }
- }
- if (x < 0)
- return(x);
- debug(F001,"xgnbyte UTF8->UCS2","",uc.x_short);
- }
-#endif /* UNICODE */
-
-#ifdef KANJI
-#ifdef UNICODE
- else
-#endif /* UNICODE */
- if (fcsinfo[fcs].alphabet == AL_JAPAN) { /* Japanese source file */
- int c7, x, y;
- if (fcs == FC_JIS7) { /* If file charset is JIS-7 */
- if (!ffc) /* If first byte of file */
- j7init(); /* Initialize JIS-7 parser */
- x = getj7(); /* Get a JIS-7 byte */
- } else /* Otherwise */
- x = fn ? (*fn)() : zminchar(); /* Just get byte */
- if (x < 0) { /* Propogate EOF or error */
- debug(F100,"XGNBYTE EOF","",0);
- return(x);
- }
- debug(F001,"XGNBYTE x","",x);
- ffc++; /* Count */
-#ifndef NOXFER
- if (docrc && (what & W_SEND)) dofilcrc(x); /* Do CRC */
-#endif /* NOXFER */
- switch (fcs) { /* What next depends on charset */
- case FC_SHJIS: /* Shift-JIS */
- if ((x <= 0x80) || /* Any 7-bit char... */
- (x >= 0xa0 && x <= 0xdf)) { /* or halfwidth Katakana */
- sj.x_short = (USHORT) x; /* we read one byte. */
- } else { /* Anything else */
- if ((y = fn ? (*fn)() : zminchar()) < 0) /* get another */
- return(y);
-#ifndef NOXFER
- if (docrc && (what & W_SEND)) dofilcrc(y);
-#endif /* NOXFER */
- ffc++;
- sj.x_char[byteorder] = (CHAR) x;
- sj.x_char[1-byteorder] = (CHAR) y;
- }
- break;
-
- case FC_JIS7: /* JIS-7 */
- case FC_JDEC: /* DEC Kanji */
- case FC_JEUC: /* EUC-JP */
- if ((x & 0x80) == 0) { /* Convert to Shift-JIS */
- sj.x_short = (USHORT) x; /* C0 or G0: one byte */
- eu.x_short = (USHORT) x;
- haveeu = 1;
- } else {
- c7 = x & 0x7f;
- if (c7 > 0x20 && c7 < 0x7f) { /* Kanji: two bytes */
- if ((y = (fcs == FC_JEUC) ?
- (fn ? (*fn)() : zminchar()) :
- getj7() /* ^^^ */
- ) < 0)
- return(y);
- ffc++;
-#ifndef NOXFER
- if (docrc && (what & W_SEND)) dofilcrc(y);
-#endif /* NOXFER */
- eu.x_char[byteorder] = (CHAR) x;
- eu.x_char[1-byteorder] = (CHAR) y;
- sj.x_short = eu_to_sj(eu.x_short);
- haveeu = 1;
- } else if (x == 0x8e) { /* SS2 Katakana prefix: 2 bytes */
- if ((y = (fcs == FC_JIS7) ?
- getj7() : /* ^^^ */
- (fn ? (*fn)() : zminchar())
- ) < 0)
- return(y);
- ffc++;
-#ifndef NOXFER
- if (docrc && (what & W_SEND)) dofilcrc(y);
-#endif /* NOXFER */
- sj.x_short = y | 0x80;
- debug(F001,"XGNBYTE KANA SJ","",sj.x_short);
- } else {
- /* Something that translates to U+FFFD */
- sj.x_short = UNKSJIS;
- }
- }
- break;
- }
- havesj = 1; /* Have Shift-JIS */
-#ifdef UNICODE
- uc.x_short = sj_to_un(sj.x_short); /* Translate to UCS-2 */
- haveuc = 1; /* Have Unicode */
-#endif /* UNICODE */
- flag = 1; /* Have a char */
- }
-#endif /* KANJI */
- }
- if (!flag) { /* If no character was read yet... */
- if ((x = (fn ? (*fn)() : zminchar())) > -1) /* read one now */
- ffc++;
- debug(F101,"xgnbyte zminchar 1","",x);
- if (x < 0)
- return(x);
- haveuc = 0;
- }
-#ifdef UNICODE
- if (haveuc) {
- thischar = uc.x_short;
- /* lastucs2 = uc.x_short; */
- } else
-#endif /* UNICODE */
- thischar = x;
- debug(F001,"xgnbyte thischar",haveuc ? "[UNICODE]" : "[other]",thischar);
-
-#ifdef CK_CTRLZ /* SET EOF CTRLZ */
- if (eofmethod == XYEOF_Z && !binary && thischar == 26) {
- debug(F100,"xgnbyte EOF on Ctrl-Z 1","",0);
- return(-1);
- }
-#endif /* CK_CTRLZ */
-
-#ifdef UNICODE
- if (!haveuc) /* If not Unicode... */
-#endif /* UNICODE */
- x &= fmask; /* Apply SET FILE BYTESIZE mask */
-
- switch (xlatype) { /* Translation type... */
-#ifdef UNICODE
- case XLA_UNICODE: { /* Unicode is involved */
- xc = 0;
-/*
- Here we must choose the appropriate translation function. If we are being
- called by getpkt() (i.e. when transferring a file), we are translating from
- Unicode to the Transfer Character Set and therefore must use the function
- pointed to by xut. Otherwise, e.g. during TRANSLATE, CONNECT, TRANSMIT, etc,
- we are translating from Unicode to the File Character Set and so must call
- the function pointed to by xuf. There might be a cleaner way to set this
- up but I don't think so. For example, setxlatype() might have been called
- too soon and so might not have known whether it was a file transfer or a
- local operation.
-*/
-/*
- (Many years later...) In testing this code I noticed that TRANSLATE'ing
- Russian text from UTF-8 to ISO Latin/Cyrillic produced all question marks.
- Rereading the previous paragraph it seems to me we are (I am) overloading
- this function with responsibilites, satisfying the needs of file transfer
- (local file charset -> transfer charset for outbound packet) and local file
- conversion. In the case of TRANSLATE, we call (xgnbyte(), xpnbyte()) in a
- loop, expecting the xgnbyte() will feed UCS2 to xpnbyte(). But the
- following code does what xpnbyte() is going to do, returning (in this case)
- an ISO Latin/Cyrillic byte stream, which xpnbyte() believes to be UCS2, and
- comes up with nonsense. Not wanting to rip the whole thing apart and start
- over, I made the following change that should do no harm, upon observing
- that if the input character set is UTF-8 or UCS-2, then when we get here it
- has already been converted to UCS2, so if we are not transferring a file, we
- don't need to do anything else except put the bytes in the right place to be
- returned, which is done further along.
-*/
-#ifdef COMMENT
- /* Previous code */
- xx = (what & W_SEND) ? xut : xuf;
-#else
- /* New code 2011-06-03 */
- if (what & W_SEND) {
- xx = xut;
- } else {
- if (fcs == FC_UCS2 || fcs == FC_UTF8)
- xx = NULL;
- else
- xx = xuf;
- }
-#endif /* COMMENT */
-
- eolflag = 0;
- if (haveuc) { /* File is Unicode */
- /* See Unicode TR13, "Converting to Other Character Sets" */
- if (uc.x_short == 0x2028 || /* Line Separator? */
- uc.x_short == 0x2029 || /* Paragraph Separator */
- (feol && (uc.x_short == (USHORT)feol))
- ) {
- debug(F001,"xgnbyte uc eol","",uc.x_short);
- rc = 0;
- eolflag = 1; /* Don't translate and handle later */
- }
- if (xx && !eolflag) { /* UCS-to-TCS function (UCS->byte) */
- rc = (*xx)(uc.x_short); /* These can fail... */
- debug(F101,"xgnbyte xx rc","",rc);
- if (rc < 0) /* If it can't be translated */
- uc.x_short = UNK; /* Put unknown-character symbol */
- else
- uc.x_short = (unsigned)((unsigned)rc & 0xffff);
- debug(F101,"xgnbyte xx uc","",uc.x_short);
- }
-#ifdef KANJI
- if (tcs == FC_JEUC) { /* Translating to EUC-JP */
- USHORT sj = 0;
- union ck_short eu;
- debug(F001,"xgnbyte UCS->EUC UCS","",uc.x_short);
- if (!havesj) /* If we don't already have it */
- sj = un_to_sj(uc.x_short); /* convert to Shift-JIS */
- eu.x_short = sj_to_eu(sj);
- debug(F001,"xgnbyte UCS->EUC EUC","",eu.x_short);
- xlaptr = 0;
- xlacount = 0;
- if (eolflag) {
- if (what & W_SEND) {
- xlabuf[xlacount++] = LF;
- return(CR);
- } else {
- return(feol);
- }
- }
- if (eu.x_char[byteorder]) { /* Two bytes */
- rc = eu.x_char[byteorder];
- xlabuf[xlacount++] = eu.x_char[1-byteorder];
- debug(F001,"xgnbyte UCS->EUC xlabuf[0]","",xlabuf[0]);
- } else { /* One byte */
- rc = eu.x_char[1-byteorder];
- }
- debug(F101,"xgnbyte UCS->EUC xlacount","",xlacount);
- debug(F001,"xgnbyte UCS->EUC rc","",rc);
- return(rc);
- } else
-#endif /* KANJI */
- if (tcs != FC_UCS2 && tcs != FC_UTF8) {
- if (uc.x_short & 0xff00) { /* Decoding error */
- debug(F001,"xgnbyte decoding error","",uc.x_short);
- return(-2);
- } else
- return((unsigned int)(uc.x_short & 0xff));
- }
- xc = uc.x_short;
-
- } else { /* File is not Unicode */
- USHORT ch;
- /* Translate from single FCS byte to UCS-2 */
-/*
- This is a bit nonobvious... The blah_u() (Blah-to-Unicode) routines are
- called only with pieces of character sets, in the ISO 2022 sense. So,
- for example, if ch is a Latin-1 character, we call the translation
- routine only if it is in the right half; if it's in the left half, it
- isn't translated, and in fact will give the wrong result if sent to the
- translation function. That's because those functions were designed for
- use with the ISO 2022 G0..G3 sets, not for file transfer. On the other
- hand, if it's a 7-bit character set, we *do* call the translation
- function. (To put it another way, the left half of any 8-bit character
- set is ASCII and therefore doesn't need to be translated but 7-bit sets
- such as ISO 646 German do need translation).
-*/
- ch = (unsigned)(thischar & 0xff);
- if (((fcsinfo[fcs].size > 128) && (ch & 0x80)) ||
- fcsinfo[fcs].size <= 128) {
- if (xfu) { /* FCS-to-UCS function */
- ch = (*xfu)(ch);
- }
- }
- xc = ch;
- }
- /* At this point we have a UCS-2 character in native format */
- /* (Big Endian or Little Endian) in xc, which is an unsigned int. */
-
- debug(F001,"xgnbyte xc","",xc);
-
- if (tcs == FC_UTF8) { /* Now convert to UTF-8 */
- USHORT c; /* NOTE: this is FC_UTF8 on purpose! */
- CHAR * buf = NULL;
- int i, k = 0, x;
-
- xlaptr = 0;
- if (utferror) {
- xlabuf[k++] = 0xff;
- xlabuf[k++] = 0xbd;
- }
- if (eolflag) { /* We detected EOL in source file */
- if (what & W_SEND) { /* Convert to CRLF */
- xlabuf[k++] = LF;
- xlacount = k;
- return((unsigned int)CR);
-#ifdef COMMENT
- } else { /* Or to local line-end */
- xlacount = k;
- return((unsigned int)feol);
-#endif /* COMMENT */
- }
- }
- c = xc;
- if ((x = ucs2_to_utf8(c,&buf)) < 1) {
- debug(F101,"xgnbyte ucs2_to_utf8 error","",c);
- return(-2);
- }
- debug(F101,"xgnbyte UTF8 buf[0]","",buf[0]);
- for (i = 1; i < x; i++) {
- xlabuf[k+i-1] = buf[i];
- debug(F111,"xgnbyte UTF8 xlabuf",ckitoa(i-1),buf[i]);
- }
- xlaptr = 0;
- xlacount = x - 1;
- debug(F101,"xgnbyte UTF8 xlacount","",xlacount);
- return((unsigned int)buf[0]);
- } else { /* Or keep it as UCS-2 */
- int k = 0;
- CHAR c;
- xlaptr = 0;
- if (utferror) {
- xlabuf[k++] = 0xff;
- xlabuf[k++] = 0xfd;
- debug(F101,"xgnbyte error","",k);
- }
- if (eolflag) { /* We detected EOL in source file */
- if (what & W_SEND) { /* Convert to CRLF */
- xlabuf[k++] = CR;
- xlabuf[k++] = NUL;
- xlabuf[k++] = LF;
- xlacount = k;
- debug(F101,"xgnbyte send CRLF","",k);
- return(0); /* Return NUL */
- } else { /* Or to local line-end */
-#ifdef COMMENT
- /* This bypasses byte swapping that we might need */
- xlabuf[k++] = (CHAR)feol;
- xlacount = k;
- debug(F101,"xgnbyte send feol","",k);
- return(0); /* Return NUL */
-#else
- xc = (CHAR)feol;
-#endif /* COMMENT */
- }
- }
- /* In which order should we return the bytes? */
-#ifdef COMMENT
- if ( (what & W_SEND) || (what & W_FTP) || (fileorder == 0)) {
-#endif /* COMMENT */
- /* ALWAYS RETURN IN BIG ENDIAN ORDER... 7 Sep 2002 */
- /* xgnbyte() is almost always used to feed xpnbyte() */
- /* which requires bytes in BE order. In cases where */
- /* xgnbyte is used in isolation, the caller can swap */
- /* bytes itself afterwards. */
- xlabuf[k++] = (xc >> 8) & 0xff; /* Big Endian */
- xlabuf[k++] = xc & 0xff;
- debug(F001,"xgnbyte->UCS2BE",
- ckitox((int)xlabuf[0]),xlabuf[1]);
-#ifdef COMMENT
- } else { /* Little Endian */
- xlabuf[k++] = xc & 0xff;
- xlabuf[k++] = (xc >> 8) & 0xff;
- debug(F001,"xgnbyte->UCS2LE",
- ckitox((int)xlabuf[0]),xlabuf[1]);
- }
-#endif /* COMMENT */
- c = xlabuf[0];
- xlaptr = 1;
- xlacount = k-1;
- debug(F101,"xgnbyte c","",c);
- debug(F101,"xgnbyte xlaptr","",xlaptr);
- debug(F011,"xgnbyte xlabuf",xlabuf,xlacount);
- return((unsigned int)c);
- }
- }
-#endif /* UNICODE */
- case XLA_NONE:
- return((fn ? (*fn)() : zminchar()));
- case XLA_BYTE: /* Byte-for-Byte translation */
- rt = x;
- if (sx)
- rt = (*sx)(rt);
-#ifdef UNICODE
- if (utferror) {
- xlaptr = 0;
- xlacount = 1;
- xlabuf[0] = rt;
- return(UNK);
- } else
-#endif /* UNICODE */
- return((unsigned int)rt);
-
-#ifdef KANJI
- case XLA_JAPAN: /* Come here with Shift-JIS */
- if (tcs == FC_JEUC) { /* It better be... */
- xlaptr = 0;
- xlacount = 0;
- if (!havesj) {
- printf("BAD BAD\n");
- return(-2);
- }
- if (!haveeu) /* We might already have EUC too */
- eu.x_short = sj_to_eu(sj.x_short);
- if (eu.x_char[byteorder]) {
- xlabuf[xlacount++] = eu.x_char[1-byteorder];
- return(eu.x_char[byteorder]);
- } else {
- return(eu.x_char[1-byteorder]);
- }
- break;
- }
-#endif /* KANJI */
-
- default:
- debug(F101,"xgnbyte bad xlatype","",xlatype);
- return(-2);
- }
-#ifdef COMMENT
-/*
- If there is a return() statement here, some compilers complain
- about "statement not reached". If there is no return() statement,
- other compilers complain that "Non-void function should return a value".
- There is no path through this function that falls through to here.
-*/
- debug(F100,"xgnbyte switch failure","",0);
- return(-2);
-#endif /* COMMENT */
-}
-#endif /* NOCSETS */
-
-#ifndef NOXFER
-
-/* G E T P K T -- Fill a packet data field from the indicated source. */
-
-/*
- Parameters:
- bufmax: Maximum length of entire packet.
- xlate: Flag for whether to translate charsets when in text mode.
- Returns: Number of characters written to packet data field, 0 or more,
- Or -1 on failure (internal error),
- or -3 on timeout (e.g. when reading from a pipe).
-
- This is the full version allowing for parity and text-mode conversions;
- i.e. it works in all cases. Also see bgetpkt(), a special lean/mean/fast
- packet encoder that works only for binary-mode no-parity transfers.
-*/
-static int uflag = 0;
-
-int
-getpkt(bufmax,xlate) int bufmax, xlate; { /* Fill one packet buffer */
- register CHAR rt = t, rnext = NUL; /* Register shadows of the globals */
- register CHAR *dp, *odp, *odp2, *p1, *p2; /* pointers... */
- register int x; /* Loop index. */
- register int a7; /* Low 7 bits of character */
-
- CHAR xxls, xxdl, xxrc, xxss, xxcq; /* Pieces of prefixed sequence */
-
- if (binary) xlate = 0; /* We don't translate if binary */
-
- if (!data) {
- debug(F100,"SERIOUS ERROR: getpkt data == NULL","",0);
- return(-1);
- }
- dp = data; /* Point to packet data buffer */
- size = 0; /* And initialize its size */
-/*
- Assume bufmax is the receiver's total receive-packet buffer length.
- Our whole packet has to fit into it, so we adjust the data field length.
- We also decide optimally whether it is better to use a short-format or
- long-format packet when we're near the borderline.
-*/
- bufmax = maxdata(); /* Get maximum data length */
-
- if (first == 1) { /* If first character of this file.. */
-#ifdef UNICODE
- /* Special end-of-line handling for Unicode */
- if (tcharset == TC_UCS2 || tcharset == TC_UTF8)
- uflag = 1;
-#endif /* UNICODE */
- debug(F101,"getpkt first uflag","",uflag);
- debug(F101,"getpkt first rt","",rt);
- if (!memstr && !funcstr) /* and real file... */
- ffc = (CK_OFF_T)0; /* reset file character counter */
-#ifdef COMMENT
- /* Moved to below... */
- first = 0; /* Next character won't be first */
-#endif /* COMMENT */
- *leftover = '\0'; /* Discard any interrupted leftovers */
- nleft = 0;
-#ifndef NOCSETS
- setxlatype(tcharset,fcharset); /* Set up charset translations */
-#endif /* NOCSETS */
-
- /* Get first character of file into rt, watching out for null file */
-
-#ifdef CALIBRATE
- if (calibrate && !memstr) {
-#ifdef NORANDOM
- x = rt = 53;
-#else
- x = rt = cal_a[rand() & 0xff];
-#endif /* NORANDOM */
- first = 0;
- ffc++;
- } else
-#endif /* CALIBRATE */
-#ifdef KANJI
- if (xlate && tcharset == TC_JEUC) { /* Kanji text */
- x = zkanjf();
- if ((x = zkanji(memstr ? kgetm : kgetf)) < 0) {
- first = -1;
- size = 0;
- if (x == -2) {
- debug(F100,"getpkt zkanji: input error","",0);
- cxseen = 1;
- } else debug(F100,"getpkt zkanji: empty string/file","",0);
- return(0);
- }
- rt = x;
- first = 0;
- if (!memstr) {
- ffc++;
- if (docrc && (what & W_SEND)) /* Accumulate file crc */
- dofilcrc((int)rt);
- }
- } else { /* Not Kanji text */
-#endif /* KANJI */
- if (memstr) { /* Reading data from memory string */
- /* This will not be Unicode */
- if ((rt = *memptr++) == '\0') { /* end of string ==> EOF */
- first = -1;
- size = 0;
- debug(F100,"getpkt: empty string","",0);
- return(0);
- }
- first = 0;
- } else if (funcstr) { /* Reading data from a function */
- /* This will not be Unicode */
- if ((x = (*funcptr)()) < 0) { /* End of input */
- first = -1;
- size = 0; /* Empty */
- return(0);
- }
- ffc++; /* Count a file character */
- rt = (CHAR) x; /* Convert int to char */
- first = 0;
- debug(F000,"getpkt funcstr","",rt);
-
- } else { /* Reading data from a file */
-#ifndef NOCSETS
- if (xlate && !binary) { /* Could be Unicode */
- if (xlatype == XLA_UNICODE) {
- /* Get next translated byte */
- x = xgnbyte(cseqtab[tcharset],fcharset,NULL);
- debug(F101,"getpkt xgnbyte","",x);
- } else { /* Not Unicode */
- x = zminchar(); /* Get next byte, translate below */
- debug(F101,"getpkt zminchar A","",x);
- }
- } else { /* Just get next byte */
-#endif /* NOCSETS */
- x = zminchar();
- debug(F101,"getpkt zminchar B","",x);
-#ifndef NOCSETS
- }
-#endif /* NOCSETS */
- if (x < 0) { /* End of file or input error */
- if (x == -3) { /* Timeout. */
- size = (dp-data);
- debug(F101,"getpkt timeout size","",size);
- return((size == 0) ? x : size);
- }
- first = -1;
- size = 0;
- if (x == -2) { /* Error */
- debug(F100,"getpkt: input error","",0);
- cxseen = 1; /* Interrupt the file transfer */
- } else {
- debug(F100,"getpkt empty file","",0);
- }
- return(0);
- }
- first = 0; /* Next character won't be first */
- rt = (CHAR) x; /* Convert int to char */
-#ifndef NOCSETS
- if (xlatype != XLA_UNICODE || binary) {
- ffc++;
- if (sx)
- rt = (*sx)(rt);
- if (docrc && (what & W_SEND))
- dofilcrc(x);
- }
-#endif /* NOCSETS */
-#ifdef DEBUG
- if (deblog)
- debug(F101,"getpkt 1st char","",rt);
-#endif /* DEBUG */
- if (/* !haveuc && */ docrc && (what & W_SEND)) /* File CRC */
- dofilcrc(x);
- }
-#ifdef KANJI
- }
-#endif /* KANJI */
- /* PWP: handling of feol is done later (in the while loop)... */
-
- } else if ((first == -1) && (nleft == 0)) { /* EOF from last time */
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"getpkt eof crc16","",crc16);
- debug(F101,"getpkt eof ffc","",ffc);
- }
-#endif /* DEBUG */
- return(size = 0);
- }
-/*
- Here we handle characters that were encoded for the last packet but
- did not fit, and so were saved in the "leftover" array.
-*/
- debug(F101,"getpkt nleft","",nleft);
- if (nleft) {
- for (p1 = leftover; nleft > 0; nleft--) /* Copy leftovers */
- *dp++ = *p1++;
- *leftover = '\0'; /* Delete leftovers */
- nleft = 0;
- }
- if (first == -1) /* Handle EOF */
- return(size = (dp - data));
-
-/* Now fill up the rest of the packet. */
-
- rpt = 0; /* Initialize character repeat count */
-
- while (first > -1) { /* Until EOF... */
-#ifdef CALIBRATE
- if (calibrate && !memstr) { /* We generate our own "file" */
- if (ffc >= calibrate) { /* EOF */
- first = -1;
- ffc--;
- } else { /* Generate next character */
- if (cal_j > CAL_M * ffc)
- cal_j = cal_a[ffc & 0xff];
- x = (unsigned)cal_a[(cal_j & 0xff)];
- if (x == rt) x ^= 2;
- }
- cal_j += (unsigned int)(ffc + CAL_O);
- ffc++;
- } else
-#endif /* CALIBRATE */
-#ifdef KANJI
- if (xlate && tcharset == TC_JEUC) {
- if ((x = zkanji(memstr ? kgetm : kgetf)) < 0) {
- first = -1;
- if (x == -2) cxseen = 1;
- } else if (!memstr) ffc++;
- rnext = (CHAR) (x & fmask);
- } else {
-#endif /* KANJI */
- if (memstr) { /* Get next char from memory string */
- if ((x = *memptr++) == '\0') /* End of string means EOF */
- first = -1; /* Flag EOF for next time. */
- rnext = (CHAR) (x & fmask); /* Apply file mask */
- } else if (funcstr) { /* Get next char from function */
- if ((x = (*funcptr)()) < 0) /* End of string means EOF */
- first = -1; /* Flag EOF for next time. */
- rnext = (CHAR) (x & fmask); /* Apply file mask */
- } else { /* From file... */
-#ifndef NOCSETS
- if (xlate && !binary) { /* Could be Unicode */
- if (xlatype == XLA_UNICODE) {
- /* Get next translated byte */
- x = xgnbyte(cseqtab[tcharset],fcharset,NULL);
- } else { /* Not Unicode */
- x = zminchar(); /* Get next byte, translate below */
- /* debug(F101,"xgnbyte B zminchar","",x); */
- }
- } else { /* Just get next byte */
-#endif /* NOCSETS */
- x = zminchar();
- /* debug(F101,"xgnbyte C zminchar","",x); */
-#ifndef NOCSETS
- }
-#endif /* NOCSETS */
- if (x < 0) { /* Check for EOF */
- if (x == -3) { /* Timeout reading from pipe */
- t = rt;
- size = (dp-data);
- debug(F101,"getpkt timeout size","",size);
- return((size == 0) ? x : size);
- }
- first = -1; /* Flag eof for next time. */
- if (x == -2) cxseen = 1; /* If error, cancel this file. */
- }
- rnext = (CHAR) (x & fmask); /* Apply file mask */
-#ifndef NOCSETS
- if (xlatype != XLA_UNICODE) {
-#endif /* NOCSETS */
- ffc++;
-#ifndef NOCSETS
- if (sx)
- rt = (*sx)(rt);
-#endif /* NOCSETS */
- if (docrc && (what & W_SEND))
- dofilcrc(x);
-
-#ifndef NOCSETS
- }
-#endif /* NOCSETS */
- }
-#ifdef KANJI
- }
-#endif /* KANJI */
-/*
- At this point, the character we just read is in rnext,
- and the character we are about to encode into the packet is in rt.
-*/
- odp = dp; /* Remember where we started. */
- xxls = xxdl = xxrc = xxss = xxcq = NUL; /* Clear these. */
-/*
- Now encode the character according to the options that are in effect:
- ctlp[]: whether this control character needs prefixing.
- binary: text or binary mode.
- rptflg: repeat counts enabled.
- ebqflg: 8th-bit prefixing enabled.
- lscapu: locking shifts enabled.
-*/
- if (rptflg) { /* Repeat processing is on? */
- if (!uflag &&
- /*
- * If the next char is really CRLF, then we cannot
- * be doing a repeat (unless CR,CR,LF which becomes
- * "~ <n-1> CR CR LF", which is OK but not most efficient).
- * I just plain don't worry about this case. The actual
- * conversion from NL to CRLF is done after the rptflg if...
- */
- (!feol || binary || (feol && (rnext != feol))) &&
- (rt == rnext) && (first == 0)) { /* Got a run... */
- if (++rpt < 94) { /* Below max, just count */
- continue; /* go back and get another */
- } else if (rpt == 94) { /* Reached max, must dump */
- xxrc = (CHAR) tochar(rpt); /* Put the repeat count here */
- rptn += rpt; /* Accumulate it for statistics */
- rpt = 0; /* And reset it */
- }
- } else if (rpt > 1) { /* More than two */
- xxrc = (CHAR) tochar(++rpt); /* and count. */
- rptn += rpt;
- rpt = 0; /* Reset repeat counter. */
- }
- /*
- If (rpt == 1) we must encode exactly two characters.
- This is done later, after the first character is encoded.
- */
- }
- /* If it's the newline character... */
- if (!uflag && !binary && feol && (rt == feol)) {
- if (lscapu && lsstate) { /* If SHIFT-STATE is SHIFTED */
- if (ebqflg) { /* If single shifts enabled, */
- *dp++ = (CHAR) ebq; /* insert a single shift. */
- } else { /* Otherwise must shift in. */
- *dp++ = myctlq; /* Insert shift-out code */
- *dp++ = 'O';
- lsstate = 0; /* Change shift state */
- }
- }
-#ifdef CK_SPEED
- if (ctlp[CR]) {
- *dp++ = myctlq; /* Insert carriage return directly */
- *dp++ = 'M';
- ccp++;
- } else {
- *dp++ = CR; /* Perhaps literally */
- ccu++;
- }
-#else /* !CK_SPEED */
- *dp++ = myctlq; /* Insert carriage return directly */
- *dp++ = 'M';
- ccp++;
-#endif /* CK_SPEED */
- rt = LF; /* Now make next char be linefeed. */
- }
-/*
- Now handle the 8th bit of the file character. If we have an 8-bit
- connection, we preserve the 8th bit. If we have a 7-bit connection,
- we employ either single or locking shifts (if they are enabled).
-*/
- a7 = rt & 0177; /* Get low 7 bits of character */
- if (rt & 0200) { /* 8-bit character? */
- if (lscapu) { /* Locking shifts enabled? */
- if (!lsstate) { /* Not currently shifted? */
- x = lslook(0200); /* Look ahead */
- if (x != 0 || ebqflg == 0) { /* Locking shift decision */
- xxls = 'N'; /* Need locking shift-out */
- lsstate = 1; /* and change to shifted state */
- } else if (ebqflg) { /* Not worth it */
- xxss = (CHAR) ebq; /* Use single shift */
- }
- }
- rt = (CHAR) a7; /* Replace character by 7-bit value */
- } else if (ebqflg) { /* 8th bit prefixing is on? */
- xxss = (CHAR) ebq; /* Insert single shift */
- rt = (CHAR) a7; /* Replace character by 7-bit value */
- }
-/*
- In case we have a 7-bit connection and this is an 8-bit character, AND
- neither locking shifts nor single shifts are enabled, then the character's
- 8th bit will be destroyed in transmission, and a block check error will
- occur.
-*/
- } else if (lscapu) { /* 7-bit character */
-
- if (lsstate) { /* Comes while shifted out? */
- x = lslook(0); /* Yes, look ahead */
- if (x || ebqflg == 0) { /* Time to shift in. */
- xxls = 'O'; /* Set shift-in code */
- lsstate = 0; /* Exit shifted state */
- } else if (ebqflg) { /* Not worth it, stay shifted out */
- xxss = (CHAR) ebq; /* Insert single shift */
- }
- }
- }
- /* If data character is significant to locking shift protocol... */
- if (lscapu && (a7 == SO || a7 == SI || a7 == DLE))
- xxdl = 'P'; /* Insert datalink escape */
-
- if (
-#ifdef CK_SPEED
- /*
- Thwart YET ANOTHER unwanted, unneeded, and unloved sign
- extension. This one was particularly nasty because it prevented
- 255 (Telnet IAC) from being prefixed on some platforms -- e.g.
- VMS with VAX C -- but not others, thus causing file transfers to
- fail on Telnet connections by sending bare IACs. Not to mention
- the stray memory reference. Signed chars are a BAD idea.
- */
- ctlp[(unsigned)(rt & 0xff)] /* Lop off any "sign" extension */
-#else
- (a7 < SP) || (a7 == DEL)
-#endif /* CK_SPEED */
- ) { /* Do control prefixing if necessary */
- xxcq = myctlq; /* The prefix */
- ccp++; /* Count it */
- rt = (CHAR) ctl(rt); /* Uncontrollify the character */
- }
-#ifdef CK_SPEED
- else if ((a7 < SP) || (a7 == DEL)) /* Count an unprefixed one */
- ccu++;
-#endif /* CK_SPEED */
-
- if (a7 == myctlq) /* Always prefix the control prefix */
- xxcq = myctlq;
-
- if ((rptflg) && (a7 == rptq)) /* If it's the repeat prefix, */
- xxcq = myctlq; /* prefix it if doing repeat counts */
-
- if ((ebqflg) && (a7 == ebq)) /* Prefix the 8th-bit prefix */
- xxcq = myctlq; /* if doing 8th-bit prefixes */
-
-/* Now construct the entire sequence */
-
- if (xxls) { *dp++ = myctlq; *dp++ = xxls; } /* Locking shift */
- odp2 = dp; /* (Save this place) */
- if (xxdl) { *dp++ = myctlq; *dp++ = xxdl; } /* Datalink escape */
- if (xxrc) { *dp++ = (CHAR) rptq; *dp++ = xxrc; } /* Repeat count */
- if (xxss) { *dp++ = (CHAR) ebq; } /* Single shift */
- if (xxcq) { *dp++ = myctlq; } /* Control prefix */
- *dp++ = rt; /* Finally, the character itself */
-
- if (rpt == 1) { /* Exactly two copies? */
- rpt = 0;
- p2 = dp; /* Save place temporarily */
- for (p1 = odp2; p1 < p2; p1++) /* Copy the old chars over again */
- *dp++ = *p1;
- if ((p2-data) <= bufmax) odp = p2; /* Check packet bounds */
- if ((p2-data) < bufmax) odp = p2; /* Check packet bounds */
- }
- rt = rnext; /* Next character is now current. */
-
-/* Done encoding the character. Now take care of packet buffer overflow. */
-
- if ((dp-data) >= bufmax) { /* If too big, save some for next. */
-
- debug(F000,"getpkt EOP","",rt);
-
- size = (dp-data); /* Calculate the size. */
- *dp = '\0'; /* Mark the end. */
- if (memstr) { /* No leftovers for memory strings */
- if (rt) /* Char we didn't encode yet */
- memptr--; /* (for encstr()) */
- return(size);
- }
- if ((dp-data) > bufmax) { /* if packet is overfull */
- /* copy the part that doesn't fit into the leftover buffer, */
- /* taking care not to split a prefixed sequence. */
- int i;
- nleft = dp - odp;
- for (i = 0, p1 = leftover, p2 = odp; i < nleft; i++) {
- *p1++ = *p2++;
- if (memstr) memptr--; /* (for encstr) */
- }
- debug(F111,"getpkt leftover",leftover,size);
- debug(F101,"getpkt osize","",(odp-data));
- size = (odp-data); /* Return truncated packet. */
- *odp = '\0'; /* Mark the new end */
- }
- t = rt; /* Save for next time */
- return(size);
- }
- } /* Otherwise, keep filling. */
- size = (dp-data); /* End of file */
- *dp = '\0'; /* Mark the end of the data. */
- debug(F111,"getpkt eof/eot",data,size); /* Fell thru before packet full, */
- return(size); /* return partially filled last packet. */
-}
-
-/* T I N I T -- Initialize a transaction */
-
-int epktrcvd = 0, epktsent = 0;
-
-/*
- Call with 1 to reset everything before S/I/Y negotiation, or 0 to
- reset only the things that are not set in the S/I/Y negotiation.
- Returns -1 on failure (e.g. to create packet buffers), 0 on success.
-*/
-int
-tinit(flag) int flag; {
- int x;
-#ifdef CK_TIMERS
- extern int rttflg;
-#endif /* CK_TIMERS */
- extern int rcvtimo;
- extern int fatalio;
-
- debug(F101,"tinit flag","",flag);
-
- *epktmsg = NUL;
- epktrcvd = 0;
- epktsent = 0;
- ofperms = "";
- diractive = 0; /* DIR / REMOTE DIR not active */
- interrupted = 0; /* Not interrupted */
- fatalio = 0; /* No fatal i/o error */
- if (server) {
- moving = 0;
- pipesend = 0; /* This takes care of multiple GETs sent to a server. */
- }
- bestlen = 0; /* For packet length optimization */
- maxsend = 0; /* Biggest data field we can send */
-#ifdef STREAMING
- streamok = 0; /* Streaming negotiated */
- streaming = 0; /* Streaming being done now */
-#endif /* STREAMING */
-
- binary = b_save; /* ... */
- gnf_binary = binary; /* Per-file transfer mode */
- retrans = 0; /* Packet retransmission count */
- sndtyp = 0; /* No previous packet */
- xflg = 0; /* Reset x-packet flag */
- memstr = 0; /* Reset memory-string flag */
- memptr = NULL; /* and buffer pointer */
- funcstr = 0; /* Reset "read from function" flag */
- funcptr = NULL; /* and function pointer */
- autopar = 0; /* Automatic parity detection flag */
-
- /* This stuff is only for BEFORE S/I/Y negotiation, not after */
-
- if (flag) {
- if (bctf) { /* Force Block Check 3 on all packets */
- bctu = bctl = 3; /* Set block check type to 3 */
- } else {
- bctu = bctl = 1; /* Reset block check type to 1 */
- }
- myinit[0] = '\0'; /* Haven't sent init string yet */
- rqf = -1; /* Reset 8th-bit-quote request flag */
- ebq = MYEBQ; /* Reset 8th-bit quoting stuff */
- ebqflg = 0; /* 8th bit quoting not enabled */
- ebqsent = 0; /* No 8th-bit prefix bid sent yet */
- sq = 'Y'; /* 8th-bit prefix bid I usually send */
- spsiz = spsizr; /* Initial send-packet size */
- debug(F101,"tinit spsiz","",spsiz);
- wslots = 1; /* One window slot */
- wslotn = 1; /* No window negotiated yet */
- justone = 0; /* (should this be zero'd here?) */
- whoareu[0] = NUL; /* Partner's system type */
- sysindex = -1;
- wearealike = 0;
- what = W_INIT; /* Doing nothing so far... */
- }
- fncnv = f_save; /* Back to what user last said */
- pktnum = 0; /* Initial packet number to send */
- cxseen = czseen = discard = 0; /* Reset interrupt flags */
- *filnam = '\0'; /* Clear file name */
- spktl = 0; /* And its length */
- nakstate = 0; /* Assume we're not in a NAK state */
- numerrs = 0; /* Transmission error counter */
- idletmo = 0; /* No idle timeout yet */
- if (server) { /* If acting as server, */
- if (srvidl > 0) /* If an idle timeout is given */
- timint = srvidl;
- else
- timint = srvtim; /* use server timeout interval. */
- } else { /* Otherwise */
- timint = chktimo(rtimo,timef); /* and use local timeout value */
- }
- debug(F101,"tinit timint","",timint);
-
-#ifdef CK_TIMERS
- if (rttflg && timint > 0) /* Using round-trip timers? */
- rttinit();
- else
-#endif /* CK_TIMERS */
- rcvtimo = timint;
-
- winlo = 0; /* Packet 0 is at window-low */
- debug(F101,"tinit winlo","",winlo);
- x = mksbuf(1); /* Make a 1-slot send-packet buffer */
- if (x < 0) return(x);
- x = getsbuf(0); /* Allocate first send-buffer. */
- debug(F101,"tinit getsbuf","",x);
- if (x < 0) return(x);
- dumpsbuf();
- x = mkrbuf(wslots); /* & a 1-slot receive-packet buffer. */
- if (x < 0) return(x);
- lsstate = 0; /* Initialize locking shift state */
- if (autopath) { /* SET RECEIVE PATHNAMES AUTO fixup */
- fnrpath = PATH_AUTO;
- autopath = 0;
- }
- return(0);
-}
-
-VOID
-pktinit() { /* Initialize packet sequence */
- pktnum = 0; /* number & window low. */
- winlo = 0;
- debug(F101,"pktinit winlo","",winlo);
-}
-
-/* R I N I T -- Respond to S or I packet */
-
-VOID
-rinit(d) CHAR *d; {
- char *tp = NULL;
- ztime(&tp);
- tlog(F110,"Transaction begins",tp,0L); /* Make transaction log entry */
- tlog(F110,"Global file mode:", binary ? "binary" : "text", 0L);
- tlog(F110,"Collision action:", fncnam[fncact],0);
- tlog(F100,"","",0);
- debug(F101,"rinit fncact","",fncact);
- filcnt = filrej = 0; /* Init file counters */
- spar(d);
- ack1(rpar());
-#ifdef datageneral
- if ((local) && (!quiet)) /* Only do this if local & not quiet */
- consta_mt(); /* Start the asynch read task */
-#endif /* datageneral */
-}
-
-
-/* R E S E T C -- Reset per-transaction character counters */
-
-VOID
-resetc() {
- rptn = 0; /* Repeat counts */
- fsecs = flci = flco = (CK_OFF_T)0; /* File chars in and out */
-#ifdef GFTIMER
- fpfsecs = 0.0;
-#endif /* GFTIMER */
- tfc = tlci = tlco = (CK_OFF_T)0; /* Total file, line chars in & out */
- ccu = ccp = 0L; /* Control-char statistics */
-#ifdef COMMENT
- fsize = (CK_OFF_T)-1; /* File size */
-#else
- if (!(what & W_SEND))
- fsize = (CK_OFF_T)-1;
- debug(F101,"resetc fsize","",fsize);
-#endif /* COMMENT */
- timeouts = retrans = 0; /* Timeouts, retransmissions */
- spackets = rpackets = 0; /* Packet counts out & in */
- crunched = 0; /* Crunched packets */
- wcur = 0; /* Current window size */
- wmax = 0; /* Maximum window size used */
- peakcps = 0; /* Peak chars per second */
-}
-
-/* S I N I T -- Get & verify first file name, then send Send-Init packet */
-/*
- Returns:
- 1 if send operation begins successfully
- 0 if send operation fails
-*/
-#ifdef DYNAMIC
-char *cmargbuf = NULL;
-#else
-char cmargbuf[CKMAXPATH+1];
-#endif /* DYNAMIC */
-char *cmargp[2];
-
-VOID
-fnlist() {
- if (!calibrate)
- sndsrc = (nfils < 0) ? -1 : nfils; /* Source for filenames */
-#ifdef DYNAMIC
- if (!cmargbuf && !(cmargbuf = malloc(CKMAXPATH+1)))
- fatal("fnlist: no memory for cmargbuf");
-#endif /* DYNAMIC */
- cmargbuf[0] = NUL; /* Initialize name buffer */
-
- debug(F101,"fnlist nfils","",nfils);
- debug(F110,"fnlist cmarg",cmarg,0);
- debug(F110,"fnlist cmarg2",cmarg2,0);
- if (!cmarg2) cmarg2 = "";
- if (nfils == 0) { /* Sending from stdin or memory. */
- if ((cmarg2 != NULL) && (*cmarg2)) {
- cmarg = cmarg2; /* If F packet, "as-name" is used */
- cmarg2 = ""; /* if provided */
- } else
- cmarg = "stdin"; /* otherwise just use "stdin" */
- ckstrncpy(cmargbuf,cmarg,CKMAXPATH+1);
- cmargp[0] = cmargbuf;
- cmargp[1] = "";
- cmlist = cmargp;
- nfils = 1;
- }
-}
-
-int
-sinit() {
- int x; /* Worker int */
- char *tp, *xp, *m; /* Worker string pointers */
-
- filcnt = filrej = 0; /* Initialize file counters */
-
- fnlist();
-
- xp = "";
- if (nfils < 0) {
-#ifdef PIPESEND
- if (usepipes && protocol == PROTO_K && *cmarg == '!') {
- pipesend = 1;
- cmarg++;
- }
-#endif /* PIPESEND */
- xp = cmarg;
- } else {
-#ifndef NOMSEND
- if (addlist)
- xp = filehead->fl_name;
- else
-#endif /* NOMSEND */
- if (filefile)
- xp = filefile;
- else if (calibrate)
- xp = "Calibration";
- else
- xp = *cmlist;
- }
- debug(F110,"sinit xp",xp,0);
- x = gnfile(); /* Get first filename. */
- debug(F111,"sinit gnfile",ckitoa(gnferror),x);
- if (x == 0) x = gnferror; /* If none, get error reason */
- m = NULL; /* Error message pointer */
- debug(F101,"sinit gnfil","",x);
- switch (x) {
- case -6: m = "No files meet selection criteria"; break;
- case -5: m = "Too many files match wildcard"; break;
- case -4: m = "Cancelled"; break;
- case -3: m = "Read access denied"; break;
- case -2: m = "File is not readable"; break;
-#ifdef COMMENT
- case -1: m = iswild(filnam) ? "No files match" : "File not found";
- break;
- case 0: m = "No filespec given!"; break;
-#else
- case 0:
- case -1: m = iswild(filnam) ? "No files match" : "File not found";
- break;
-#endif /* COMMENT */
- default:
- break;
- }
- debug(F101,"sinit nfils","",nfils);
- debug(F110,"sinit filnam",filnam,0);
- if (x < 1) { /* Didn't get a file. */
- debug(F111,"sinit msg",m,x);
- if (server) { /* Doing GET command */
- errpkt((CHAR *)m); /* so send Error packet. */
- } else if (!local) { /* Doing SEND command */
- interrupted = 1; /* (To suppress hint) */
- printf("?%s\r\n",m);
- } else {
- xxscreen(SCR_EM,0,0l,m); /* so print message. */
- }
- tlog(F110,xp,m,0L); /* Make transaction log entry. */
- freerbuf(rseqtbl[0]); /* Free the buffer the GET came in. */
- return(0); /* Return failure code */
- }
- if (!local && !server && ckdelay > 0) /* OS-9 sleep(0) == infinite */
- sleep(ckdelay); /* Delay if requested */
-#ifdef datageneral
- if ((local) && (!quiet)) /* Only do this if local & not quiet */
- consta_mt(); /* Start the async read task */
-#endif /* datageneral */
- freerbuf(rseqtbl[0]); /* Free the buffer the GET came in. */
- sipkt('S'); /* Send the Send-Init packet. */
- ztime(&tp); /* Get current date/time */
- tlog(F110,"Transaction begins",tp,0L); /* Make transaction log entry */
- tlog(F110,"Global file mode:", binary ? "binary" : "text", 0L);
- tlog(F100,"","",0);
- debug(F111,"sinit ok",filnam,0);
- return(1);
-}
-
-int
-#ifdef CK_ANSIC
-sipkt(char c) /* Send S or I packet. */
-#else
-sipkt(c) char c;
-#endif
-/* sipkt */ {
- CHAR *rp; int k, x;
- extern int sendipkts;
- debug(F101,"sipkt pktnum","",pktnum); /* (better be 0...) */
- ttflui(); /* Flush pending input. */
- /*
- If this is an I packet and SET SEND I-PACKETS is OFF, don't send it;
- set sstate to 'Y' which makes the next input() call return 'Y' as if we
- had received an ACK to the I packet we didn't send. This is to work
- around buggy Kermit servers that can't handle I packets.
- */
- if ((sendipkts == 0) && (c == 'I')) { /* I packet but don't send I pkts? */
- sstate = 'Y'; /* Yikes! */
- return(0); /* (see input()..)*/
- }
- k = sseqtbl[pktnum]; /* Find slot for this packet */
- if (k < 0) { /* No slot? */
- k = getsbuf(winlo = pktnum); /* Make one. */
- debug(F101,"sipkt getsbuf","",k);
- }
- rp = rpar(); /* Get protocol parameters. */
- if (!rp) rp = (CHAR *)"";
- x = spack(c,pktnum,(int)strlen((char *)rp),rp); /* Send them. */
- return(x);
-}
-
-/* X S I N I T -- Retransmit S-packet */
-/*
- For use in the GET-SEND sequence, when we start to send, but receive another
- copy of the GET command because the receiver didn't get our S packet.
- This retransmits the S packet and frees the receive buffer for the ACK.
- This special case is necessary because packet number zero is being re-used.
-*/
-VOID
-xsinit() {
- int k;
- k = rseqtbl[0];
- debug(F101,"xsinit k","",k);
- if (k > -1)
- freerbuf(k);
- resend(0);
-}
-
-/* R C V F I L -- Receive a file */
-
-/*
- Incoming filename is in data field of F packet.
- This function decodes it into the srvcmd buffer, substituting an
- alternate "as-name", if one was given.
- Then it does any requested transformations (like converting to
- lowercase), and finally if a file of the same name already exists,
- takes the desired collision action.
- Returns:
- 1 on success.
- 0 on failure.
-*/
-char ofn1[CKMAXPATH+4]; /* Buffer for output file name */
-char * ofn2; /* Pointer to backup file name */
-int ofn1x; /* Flag output file already exists */
-CK_OFF_T ofn1len = (CK_OFF_T)0;
-int opnerr; /* Flag for open error */
-
-int /* Returns success ? 1 : 0 */
-rcvfil(n) char *n; {
- extern int en_cwd;
- int i, skipthis;
- char * n2;
- char * dispo;
-#ifdef OS2ONLY
- char *zs, *longname, *newlongname, *pn; /* OS/2 long name items */
-#endif /* OS2ONLY */
-#ifdef DTILDE
- char *dirp;
-#endif /* DTILDE */
- int dirflg, x, y;
-#ifdef PIPESEND
- extern char * rcvfilter;
-#endif /* PIPESEND */
-#ifdef CALIBRATE
- extern int dest;
- CK_OFF_T csave;
- csave = calibrate; /* So we can decode filename */
- calibrate = (CK_OFF_T)0;
-#endif /* CALIBRATE */
-
- ofperms = ""; /* Reset old-file permissions */
- opnerr = 0; /* No open error (yet) */
- ofn2 = NULL; /* No new name (yet) */
- lsstate = 0; /* Cancel locking-shift state */
- srvptr = srvcmd; /* Decode file name from packet. */
-
-#ifdef UNICODE
- xpnbyte(-1,0,0,NULL); /* Reset UCS-2 byte counter. */
-#endif /* UNICODE */
-
- debug(F110,"rcvfil rdatap",rdatap,0);
- decode(rdatap,putsrv,0); /* Don't xlate charsets. */
-#ifdef CALIBRATE
- calibrate = csave;
- if (dest == DEST_N) {
- calibrate = 1;
- cmarg2 = "CALIBRATE";
- }
-#endif /* CALIBRATE */
- if (*srvcmd == '\0') /* Watch out for null F packet. */
- ckstrncpy((char *)srvcmd,"NONAME",srvcmdlen);
- makestr(&prrfspec,(char *)srvcmd); /* New preliminary filename */
-#ifdef DTILDE
- if (*srvcmd == '~') {
- dirp = tilde_expand((char *)srvcmd); /* Expand tilde, if any. */
- if (*dirp != '\0')
- ckstrncpy((char *)srvcmd,dirp,srvcmdlen);
- }
-#else
-#ifdef OS2
- if (isalpha(*srvcmd) && srvcmd[1] == ':' && srvcmd[2] == '\0')
- ckstrncat((char *)srvcmd,"NONAME",srvcmdlen);
-#endif /* OS2 */
-#endif /* DTILDE */
-
-#ifndef NOICP
-#ifndef NOSPL
-/* File dialog when downloading... */
- if (
-#ifdef CK_APC
- (apcactive == APC_LOCAL && adl_ask) || /* Autodownload with ASK */
-#endif /* CK_APC */
- (clcmds && haveurl) /* Or "kermit:" or "iksd:" URL */
- ) {
- int x;
- char fnbuf[CKMAXPATH+1]; /* Result buffer */
- char * preface;
-
- if (clcmds && haveurl)
- preface = "\r\nIncoming file from Kermit server...\r\n\
-Please confirm output file specification or supply an alternative:";
- else
- preface = "\r\nIncoming file from remote Kermit...\r\n\
-Please confirm output file specification or supply an alternative:";
-
- x = uq_file(preface, /* Preface */
- NULL, /* Prompt (let uq_file() built it) */
- 3, /* Output file */
- NULL, /* Help text */
- (char *)srvcmd, /* Default */
- fnbuf, /* Result buffer */
- CKMAXPATH+1 /* Size of result buffer */
- );
- if (x < 1) { /* Refused */
- rf_err = "Refused by user";
- return(0);
- }
- ckstrncpy((char *)srvcmd,fnbuf,CKMAXPATH+1);
- if (isabsolute((char *)srvcmd)) { /* User gave an absolute path */
- g_fnrpath = fnrpath; /* Save current RECEIVE PATHNAMES */
- fnrpath = PATH_ABS; /* switch to ABSOLUTE */
- }
- }
-#endif /* NOSPL */
-#endif /* NOICP */
-
- if (!ENABLED(en_cwd)) { /* CD is disabled */
- zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
- if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
- rf_err = "Access denied";
- return(0);
- }
- }
-#ifdef COMMENT
- /* Wrong place for this -- handle cmarg2 first -- see below... */
-
- if (zchko((char *)srvcmd) < 0) { /* Precheck for write access */
- debug(F110,"rcvfil access denied",srvcmd,0);
- rf_err = "Write access denied";
- discard = opnerr = 1;
- return(0);
- }
- xxscreen(SCR_FN,0,0l,(char *)srvcmd); /* Put it on screen if local */
- debug(F110,"rcvfil srvcmd 1",srvcmd,0);
- tlog(F110,"Receiving",(char *)srvcmd,0L); /* Transaction log entry */
-#endif /* COMMENT */
-
- skipthis = 0; /* This file in our exception list? */
- for (i = 0; i < NSNDEXCEPT; i++) {
- if (!rcvexcept[i]) {
- break;
- }
- if (ckmatch(rcvexcept[i],(char *)srvcmd,filecase,1)) {
- skipthis = 1;
- break;
- }
- }
-
-#ifdef DEBUG
- if (deblog && skipthis) {
- debug(F111,"rcvfil rcvexcept",rcvexcept[i],i);
- debug(F110,"rcvfil skipping",srvcmd,0);
- }
-#endif /* DEBUG */
-
- if (skipthis) { /* Skipping this file */
- discard = 1;
- rejection = 1;
- rf_err = "Exception list";
- debug(F101,"rcvfil discard","",discard);
- tlog(F100," refused: exception list","",0);
- return(1);
- }
-
- /* File is not in exception list */
-
- if (!cmarg2) /* No core dumps please */
- cmarg2 = "";
- debug(F110,"rcvfil cmarg2",cmarg2,0);
-
- if (*cmarg2) { /* Check for alternate name */
-#ifndef NOSPL
- int y; char *s; /* Pass it thru the evaluator */
- extern int cmd_quoting;
- if (cmd_quoting) {
- y = MAXRP;
- ckstrncpy(ofn1,(char *)srvcmd,CKMAXPATH+1); /* for \v(filename) */
- s = (char *)srvcmd;
- zzstring(cmarg2,&s,&y);
- } else
- *srvcmd = NUL;
- if (!*srvcmd) /* If we got something */
-#endif /* NOSPL */
- ckstrncpy((char *)srvcmd,cmarg2,srvcmdlen);
- }
- debug(F110,"rcvfil srvcmd 2",srvcmd,0);
-
-#ifdef PIPESEND
- /* If it starts with "bang", it's a pipe, not a file. */
- if (usepipes && protocol == PROTO_K && *srvcmd == '!' && !rcvfilter) {
- CHAR *s;
- s = srvcmd+1; /* srvcmd[] is not a pointer. */
- while (*s) { /* So we have to slide the contents */
- *(s-1) = *s; /* over 1 space to the left. */
- s++;
- }
- *(s-1) = NUL;
- pipesend = 1;
- }
-#endif /* PIPESEND */
-
-#ifdef COMMENT
-/*
- This is commented out because we need to know whether the name we are
- using was specified by the local user as an override, or came from the
- incoming packet. In the former case, we don't do stuff to it (like
- strip the pathname) that we might do to it in the latter.
-*/
- cmarg2 = ""; /* Done with alternate name */
-#endif /* COMMENT */
-
- if ((int)strlen((char *)srvcmd) > CKMAXPATH) /* Watch out for overflow */
- *(srvcmd + CKMAXPATH - 1) = NUL;
-
- /* At this point, srvcmd[] contains the incoming filename or as-name. */
- /* So NOW we check for write access. */
-
- if (zchko((char *)srvcmd) < 0) { /* Precheck for write access */
- debug(F110,"rcvfil access denied",srvcmd,0);
- rf_err = "Write access denied";
- discard = opnerr = 1;
- return(0);
- }
- xxscreen(SCR_FN,0,0l,(char *)srvcmd); /* Put it on screen if local */
- debug(F110,"rcvfil srvcmd 1",srvcmd,0);
- tlog(F110,"Receiving",(char *)srvcmd,0L); /* Transaction log entry */
-
-#ifdef CK_LABELED
-#ifdef VMS
-/*
- If we have an as-name, this overrides the internal name if we are doing
- a labeled-mode transfer.
-*/
- if (*cmarg2) {
- extern int lf_opts;
- lf_opts &= ~LBL_NAM;
- }
-#endif /* VMS */
-#endif /* CK_LABELED */
-
- debug(F111,"rcvfil pipesend",srvcmd,pipesend);
-
-#ifdef PIPESEND
- /* Skip all the filename manipulation and collision actions */
- if (pipesend) {
- dirflg = 0;
- ofn1[0] = '!';
- ckstrncpy(&ofn1[1],(char *)srvcmd,CKMAXPATH+1);
- ckstrncpy(n,ofn1,CKMAXPATH+1);
- ckstrncpy(fspec,ofn1,CKMAXPATH+1);
- makestr(&prfspec,fspec); /* New preliminary filename */
- debug(F110,"rcvfil pipesend",ofn1,0);
- goto rcvfilx;
- }
-#endif /* PIPESEND */
-/*
- This is to avoid passing email subjects through nzrtol().
- We haven't yet received the A packet so we don't yet know it's e-mail,
- so in fact we go ahead and convert it anyway, but later we get the
- original back from ofilnam[].
-*/
- dispos = 0;
- ckstrncpy(ofilnam,(char *)srvcmd,CKMAXPATH+1);
-
-#ifdef NZLTOR
- if (*cmarg2)
- ckstrncpy((char *)ofn1,(char *)srvcmd,CKMAXPATH+1);
- else
- nzrtol((char *)srvcmd, /* Filename from packet */
- (char *)ofn1, /* Where to put result */
- fncnv, /* Filename conversion */
- fnrpath, /* Pathname handling */
- CKMAXPATH /* Size of result buffer */
- );
-#else
- debug(F101,"rcvfil fnrpath","",fnrpath); /* Handle pathnames */
- if (fnrpath == PATH_OFF && !*cmarg2) { /* RECEIVE PATHNAMES OFF? */
- char *t; /* Yes. */
- zstrip((char *)srvcmd,&t); /* If there is a pathname, strip it */
- debug(F110,"rcvfil PATH_OFF zstrip",t,0);
- if (!t) /* Be sure we didn't strip too much */
- sprintf(ofn1,"FILE%02ld",filcnt);
- else if (*t == '\0')
- sprintf(ofn1,"FILE%02ld",filcnt);
- else
- ckstrncpy(ofn1,t,CKMAXPATH+1);
- ckstrncpy((char *)srvcmd,ofn1,srvcmdlen); /* Now copy it back. */
- }
-/*
- SET RECEIVE PATHNAMES RELATIVE...
- The following doesn't belong here but doing it right would require
- defining and implementing a new file routine for all ck?fio.c modules.
- So for now...
-*/
-#ifdef UNIXOROSK
- else if (fnrpath == PATH_REL && !*cmarg2) {
- if (isabsolute((char *)srvcmd)) {
- ofn1[0] = '.';
- ckstrncpy(&of1n[1],(char *)srvcmd,CKMAXPATH+1);
- ckstrncpy((char *)srvcmd,ofn1,srvcmdlen);
- debug(F110,"rcvfil PATH_REL",ofn1,0);
- }
- }
-#else
-#ifdef OS2
- else if (fnrpath == PATH_REL && !*cmarg2) {
- if (isabsolute((char *)srvcmd)) {
- char *p = (char *)srvcmd;
- if (isalpha(*p) && *(p+1) == ':')
- p += 2;
- if (*p == '\\' || *p == '/')
- p++;
- ckstrncpy(ofn1,p,CKMAXPATH+1);
- ckstrncpy((char *)srvcmd,ofn1,srvcmdlen);
- debug(F110,"rcvfil OS2 PATH_REL",ofn1,0);
- }
- }
-#endif /* OS2 */
-#endif /* UNIXOROSK */
-
- /* Now srvcmd contains incoming filename with path possibly stripped */
-
- if (fncnv) /* FILE NAMES CONVERTED? */
- zrtol((char *)srvcmd,(char *)ofn1); /* Yes, convert to local form */
- else
- ckstrncpy(ofn1,(char *)srvcmd,CKMAXPATH+1); /* No, copy literally. */
-#endif /* NZLTOR */
-
-#ifdef PIPESEND
- if (rcvfilter) {
- char * p = NULL, * q;
- int nn = MAXRP;
- pipesend = 1;
- debug(F110,"rcvfil rcvfilter ",rcvfilter,0);
-#ifndef NOSPL
- if ((p = (char *) malloc(nn + 1))) {
- q = p;
-#ifdef COMMENT
- /* We have already processed srvcmd and placed it into ofn1 */
- ckstrncpy(ofn1,(char *)srvcmd,CKMAXPATH+1); /* For \v(filename) */
-#endif /* COMMENT */
- debug(F110,"rcvfile pipesend filter",rcvfilter,0);
- zzstring(rcvfilter,&p,&nn);
- debug(F111,"rcvfil pipename",q,nn);
- if (nn <= 0) {
- printf(
- "?Sorry, receive filter + filename too long, %d max.\n",
- CKMAXPATH
- );
- rf_err = "Name too long";
- free(q);
- return(0);
- }
- ckstrncpy((char *)srvcmd,q,MAXRP);
- free(q);
- }
-#endif /* NOSPL */
- }
-#endif /* PIPESEND */
-
- /* Now the incoming filename, possibly converted, is in ofn1[]. */
-
-#ifdef OS2
- /* Don't refuse the file just because the name is illegal. */
- if (!IsFileNameValid(ofn1)) { /* Name is OK for OS/2? */
-#ifdef OS2ONLY
- char *zs = NULL;
- zstrip(ofn1, &zs); /* Not valid, strip unconditionally */
- if (zs) {
- if (iattr.longname.len && /* Free previous longname, if any */
- iattr.longname.val)
- free(iattr.longname.val);
- iattr.longname.len = strlen(zs); /* Store in attribute structure */
- iattr.longname.val = (char *) malloc(iattr.longname.len + 1);
- if (iattr.longname.val) /* Remember this (illegal) name */
- strcpy(iattr.longname.val, zs); /* safe */
- }
-#endif /* OS2ONLY */
- debug(F110,"rcvfil: invalid file name",ofn1,0);
- ChangeNameForFAT(ofn1); /* Change to an acceptable name */
- debug(F110,"rcvfil: FAT file name",ofn1,0);
-
- } else { /* Name is OK. */
-
- debug(F110,"rcvfil: valid file name",ofn1,0);
-#ifdef OS2ONLY
- if (iattr.longname.len &&
- iattr.longname.val) /* Free previous longname, if any */
- free(iattr.longname.val);
- iattr.longname.len = 0;
- iattr.longname.val = NULL; /* This file doesn't need a longname */
-#endif /* OS2ONLY */
- }
-#endif /* OS2 */
- debug(F110,"rcvfil as",ofn1,0);
-
-/* Filename collision action section. */
-
- dirflg = /* Is it a directory name? */
-#ifdef CK_TMPDIR
- isdir(ofn1)
-#else
- 0
-#endif /* CK_TMPDIR */
- ;
- debug(F101,"rcvfil dirflg","",dirflg);
- ofn1len = zchki(ofn1); /* File already exists? */
- debug(F111,"rcvfil ofn1len",ofn1,ofn1len);
- ofn1x = (ofn1len != (CK_OFF_T)-1);
-
- if ( (
-#ifdef UNIX
- strcmp(ofn1,"/dev/null") && /* It's not the null device? */
-#else
-#ifdef OSK
- strcmp(ofn1,"/nil") &&
-#endif /* OSK */
-#endif /* UNIX */
- !stdouf ) && /* Not copying to standard output? */
- ofn1x || /* File of same name exists? */
- dirflg ) { /* Or file is a directory? */
- debug(F111,"rcvfil exists",ofn1,fncact);
-#ifdef CK_PERMS
- ofperms = zgperm((char *)ofn1); /* Get old file's permissions */
- debug(F110,"rcvfil perms",ofperms,0);
-#endif /* CK_PERMS */
-
- debug(F101,"rcvfil fncact","",fncact);
- switch (fncact) { /* Yes, do what user said. */
- case XYFX_A: /* Append */
- ofperms = "";
- debug(F100,"rcvfil append","",0);
- if (dirflg) {
- rf_err = "Can't append to a directory";
- tlog(F100," error - can't append to directory","",0);
- discard = opnerr = 1;
- return(0);
- }
- tlog(F110," appending to",ofn1,0);
- break;
-#ifdef COMMENT
- case XYFX_Q: /* Query (Ask) */
- break; /* not implemented */
-#endif /* COMMENT */
- case XYFX_B: /* Backup (rename old file) */
- if (dirflg) {
- rf_err = "Can't rename existing directory";
- tlog(F100," error - can't rename directory","",0);
- discard = opnerr = 1;
- return(0);
- }
- znewn(ofn1,&ofn2); /* Get new unique name */
- tlog(F110," backup:",ofn2,0);
- debug(F110,"rcvfil backup ofn1",ofn1,0);
- debug(F110,"rcvfil backup ofn2",ofn2,0);
-#ifdef CK_LABELED
-#ifdef OS2ONLY
-/*
- In case this is a FAT file system, we can't change only the FAT name, we
- also have to change the longname from the extended attributes block.
- Otherwise, we'll have many files with the same longname and if we copy them
- to an HPFS volume, only one will survive.
-*/
- if (os2getlongname(ofn1, &longname) > -1) {
- if (strlen(longname)) {
- char tmp[10];
- extern int ck_znewn;
- sprintf(tmp,".~%d~",ck_znewn);
- newlongname =
- (char *) malloc(strlen(longname) + strlen(tmp) + 1);
- if (newlongname) {
- strcpy(newlongname, longname); /* safe (prechecked) */
- strcat(newlongname, tmp); /* safe (prechecked) */
- os2setlongname(ofn1, newlongname);
- free(newlongname);
- newlongname = NULL;
- }
- }
- } else debug(F100,"rcvfil os2getlongname failed","",0);
-#endif /* OS2ONLY */
-#endif /* CK_LABELED */
-
-#ifdef COMMENT
- /* Do this later, in opena()... */
- if (zrename(ofn1,ofn2) < 0) {
- rf_err = "Can't transform filename";
- debug(F110,"rcvfil rename fails",ofn1,0);
- discard = opnerr = 1;
- return(0);
- }
-#endif /* COMMENT */
- break;
-
- case XYFX_D: /* Discard (refuse new file) */
- ofperms = "";
- discard = 1;
- rejection = 1; /* Horrible hack: reason = name */
- debug(F101,"rcvfil discard","",discard);
- tlog(F100," refused: name","",0);
- break;
-
- case XYFX_R: /* Rename incoming file */
- znewn(ofn1,&ofn2); /* Make new name for it */
-#ifdef OS2ONLY
- if (iattr.longname.len) {
- char tmp[10];
- extern int ck_znewn;
- sprintf(tmp,".~%d~",ck_znewn);
- newlongname =
- (char *) malloc(iattr.longname.len + strlen(tmp) + 1);
- if (newlongname) {
- strcpy(newlongname, iattr.longname.val); /* safe */
- strcat(newlongname, tmp); /* safe */
- debug(F110,
- "Rename Incoming: newlongname",newlongname,0);
- if (iattr.longname.len &&
- iattr.longname.val)
- free(iattr.longname.val);
- iattr.longname.len = strlen(newlongname);
- iattr.longname.val = newlongname;
- /* free(newlongname) here ? */
- }
- }
-#endif /* OS2ONLY */
- break;
- case XYFX_X: /* Replace old file */
- debug(F100,"rcvfil overwrite","",0);
- if (dirflg) {
- rf_err = "Can't overwrite existing directory";
- tlog(F100," error - can't overwrite directory","",0);
- discard = opnerr = 1;
-#ifdef COMMENT
- return(0);
-#else
- break;
-#endif /* COMMENT */
- }
- tlog(F110,"overwriting",ofn1,0);
- break;
- case XYFX_U: /* Refuse if older */
- debug(F110,"rcvfil update",ofn1,0);
- if (dirflg) {
- rf_err = "File has same name as existing directory";
- tlog(F110," error - directory exists:",ofn1,0);
- discard = opnerr = 1;
-#ifdef COMMENT
- /* Don't send an error packet, just refuse the file */
- return(0);
-#endif /* COMMENT */
- }
- break; /* Not here, we don't have */
- /* the attribute packet yet. */
- default:
- ofperms = "";
- debug(F101,"rcvfil bad collision action","",fncact);
- break;
- }
- }
- debug(F110,"rcvfil ofn1",ofn1,0);
- debug(F110,"rcvfil ofn2",ofn2,0);
- debug(F110,"rcvfil ofperms",ofperms,0);
- if (fncact == XYFX_R && ofn1x && ofn2) { /* Renaming incoming file? */
- xxscreen(SCR_AN,0,0l,ofn2); /* Display renamed name */
- ckstrncpy(n, ofn2, CKMAXPATH+1); /* Return it */
- } else { /* No */
- xxscreen(SCR_AN,0,0l,ofn1); /* Display regular name */
- ckstrncpy(n, ofn1, CKMAXPATH+1); /* and return it. */
- }
-
-#ifdef CK_MKDIR
-/* Create directory(s) if necessary. */
- if (!discard && fnrpath != PATH_OFF) { /* RECEIVE PATHAMES ON? */
- int x;
- debug(F110,"rcvfil calling zmkdir",ofn1,0); /* Yes */
- if ((x = zmkdir(ofn1)) < 0) {
- debug(F100,"zmkdir fails","",0);
- tlog(F110," error - directory creation failure:",ofn1,0);
- rf_err = "Directory creation failure.";
- discard = 1;
- return(0);
- }
-#ifdef TLOG
- else if (x > 0)
- tlog(F110," path created:",ofn1,0);
-#endif /* TLOG */
- }
-#else
- debug(F110,"rcvfil CK_MKDIR not defined",ofn1,0);
-#endif /* CK_MKDIR */
-
- if (calibrate)
- ckstrncpy(fspec,ofn1,CKMAXPATH+1);
- else
- zfnqfp(ofn1,fspeclen,fspec);
- debug(F110,"rcvfil fspec",fspec,0);
-
-#ifdef COMMENT
- /* See comments with VMS zfnqfp()... */
-#ifdef VMS
- /* zfnqfp() does not return the version number */
- if (!calibrate) {
- int x, v;
- x = strlen(ofn1);
- if (x > 0) {
- if (ofn1[x-1] == ';') {
- v = getvnum(ofn1);
- ckstrncpy(&ofn1[x],ckitoa(v),CKMAXPATH-x);
- }
- }
- }
-#endif /* VMS */
-#endif /* COMMENT */
- fspec[fspeclen] = NUL;
- makestr(&prfspec,fspec); /* New preliminary filename */
-
-#ifdef PIPESEND
- rcvfilx:
-#endif /* PIPESEND */
-
- debug(F110,"rcvfilx: n",n,0);
- debug(F110,"rcvfilx: ofn1",ofn1,0);
- ffc = (CK_OFF_T)0; /* Init per-file counters */
- cps = oldcps = 0L;
- rs_len = (CK_OFF_T)0;
- rejection = -1;
- fsecs = gtimer(); /* Time this file started */
-#ifdef GFTIMER
- fpfsecs = gftimer();
- debug(F101,"rcvfil fpfsecs","",fpfsecs);
-#endif /* GFTIMER */
- filcnt++;
- intmsg(filcnt);
- return(1); /* Successful return */
-}
-
-
-/* R E O F -- Receive End Of File packet for incoming file */
-
-/*
- Closes the received file.
- Returns:
- 0 on success.
- -1 if file could not be closed.
- 2 if disposition was mail, mail was sent, but temp file not deleted.
- 3 if disposition was print, file was printed, but not deleted.
- -2 if disposition was mail and mail could not be sent
- -3 if disposition was print and file could not be printed
- -4 if MOVE-TO: failed
- -5 if RENAME-TO: failed
-*/
-int
-reof(f,yy) char *f; struct zattr *yy; {
- extern char * rcv_move, * rcv_rename;
- extern int o_isopen;
- int rc = 0; /* Return code */
- char *p;
- char c;
-
- debug(F111,"reof fncact",f,fncact);
- debug(F101,"reof discard","",discard);
- success = 1; /* Assume status is OK */
- lsstate = 0; /* Cancel locking-shift state */
- if (discard) { /* Handle attribute refusals, etc. */
- debug(F101,"reof discarding","",0);
- success = 0; /* Status = failed. */
- if (rejection == '#' || /* Unless rejection reason is */
- rejection == 1 || /* date or name (SET FILE COLLISION */
- rejection == '?') /* UPDATE or DISCARD) */
- success = 1;
- debug(F101,"reof success","",success);
- filrej++; /* Count this rejection. */
- discard = 0; /* We never opened the file, */
- return(0); /* so we don't close it. */
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"reof cxseen","",cxseen);
- debug(F101,"reof czseen","",czseen);
- debug(F110,"reof rdatap",rdatap,0);
- }
-#endif /* DEBUG */
-
- if (cxseen == 0) /* Got cancel directive? */
- cxseen = (*rdatap == 'D');
- if (cxseen || czseen) /* (for hints) */
- interrupted = 1;
- success = (cxseen || czseen) ? 0 : 1; /* Set SUCCESS flag appropriately */
- if (!success) /* "Uncount" this file */
- filrej++;
- debug(F101,"reof o_isopen","",o_isopen);
-
- if (o_isopen) { /* If an output file was open... */
-
-#ifdef CK_CTRLZ
- if (success) {
- debug(F101,"reof lastchar","",lastchar);
- if (!binary && eofmethod == XYEOF_Z && lastchar != 26 &&
- (!xflg || (xflg && remfile)))
- pnbyte((char)26,putfil);
- }
-#endif /* CK_CTRLZ */
-
- rc = clsof(cxseen || czseen); /* Close the file (resets cxseen) */
- debug(F101,"reof closf","",rc);
- if (rc < 0) { /* If failure to close, FAIL */
- if (success) filrej++;
- success = 0;
- }
- if (!calibrate) {
- /* Set file modification date and/or permissions */
- if (success)
- zstime(f,yy,0);
-#ifdef OS2ONLY
-#ifdef CK_LABELED
- if (success && yy->longname.len)
- os2setlongname(f, yy->longname.val);
-#endif /* CK_LABELED */
-#endif /* OS2ONLY */
- }
- if (success == 0) { /* And program return code */
- xitsta |= W_RECV;
- } else if (success == 1) { /* File rec'd successfully */
- makestr(&rrfspec,prrfspec); /* Record it for wheremsg */
- makestr(&rfspec,prfspec);
- }
-
-/* Handle dispositions from attribute packet... */
-
- c = NUL;
-#ifndef NOFRILLS
- if (!calibrate && yy->disp.len != 0) {
- p = yy->disp.val;
- c = *p++;
-#ifndef UNIX
-/*
- See ckcpro.w. In UNIX we don't use temp files any more -- we pipe the
- stuff right into mail or lpr.
-*/
- if (c == 'M') { /* Mail to user. */
- rc = zmail(p,filnam); /* Do the system's mail command */
- if (rc < 0) success = 0; /* Remember status */
- tlog(F110,"mailed",filnam,0L);
- tlog(F110," to",p,0L);
- zdelet(filnam); /* Delete the file */
- } else if (c == 'P') { /* Print the file. */
- rc = zprint(p,filnam); /* Do the system's print command */
- if (rc < 0) success = 0; /* Remember status */
- tlog(F110,"printed",filnam,0L);
- tlog(F110," with options",p,0L);
-#ifndef VMS
-#ifndef STRATUS
- /* spooler deletes file after print complete in VOS & VMS */
- if (zdelet(filnam) && rc == 0) rc = 3; /* Delete the file */
-#endif /* STRATUS */
-#endif /* VMS */
- }
-#endif /* UNIX */
- }
-#endif /* NOFRILLS */
-
- if (success &&
- !pipesend &&
- !calibrate && c != 'M' && c != 'P') {
- if (rcv_move) { /* If /MOVE-TO was given... */
- char * p = rcv_move;
-#ifdef COMMENT
-/* No need for this - it's a directory name */
- char tmpbuf[CKMAXPATH+1];
- extern int cmd_quoting; /* for \v(filename) */
- if (cmd_quoting) { /* But only if cmd_quoting is on */
- int n;
- n = CKMAXPATH;
- p = tmpbuf;
- debug(F111,"reof /move-to",rcv_move,0);
- zzstring(rcv_move,&p,&n);
- p = tmpbuf;
- }
-#endif /* COMMENT */
-/*
- Here we could create the directory if it didn't exist (and it was relative)
- but there would have to be a user-settable option to say whether to do this.
-*/
- rc = zrename(filnam,p);
- debug(F111,"reof MOVE zrename",rcv_move,rc);
- if (rc > -1) {
- tlog(F110," moving received file to",rcv_move,0);
- } else {
- rc = -4;
- tlog(F110," FAILED to move received file to",rcv_move,0);
- }
- } else if (rcv_rename) { /* Or /RENAME-TO: */
- char *s = rcv_rename; /* This is the renaming string */
-#ifndef NOSPL
- char tmpnam[CKMAXPATH+16];
- extern int cmd_quoting; /* for \v(filename) */
- if (cmd_quoting) { /* But only if cmd_quoting is on */
- int n; /* Pass it thru the evaluator */
- n = CKMAXPATH;
- s = (char *)tmpnam;
- zzstring(rcv_rename,&s,&n);
- s = (char *)tmpnam;
- }
-#endif /* NOSPL */
- if (s) if (*s) {
- rc = zrename(filnam,s);
- debug(F111,"reof RENAME zrename",s,rc);
- if (rc > -1) {
- tlog(F110," renaming received file to",s,0);
- } else {
- rc = -5;
- tlog(F110," FAILED to rename received file to",s,0);
- }
- }
- }
- }
- }
- debug(F101,"reof success","",success);
- debug(F101,"reof returns","",rc);
-
- filnam[0] = NUL; /* Erase the filename */
- return(rc);
-}
-
-/* R E O T -- Receive End Of Transaction */
-
-VOID
-reot() {
- cxseen = czseen = discard = 0; /* Reset interruption flags */
- tstats(); /* Finalize transfer statistics */
-}
-
-/* S F I L E -- Send File header or teXt header packet */
-
-/*
- Call with x nonzero for X packet, zero for F packet.
- If X == 0, filename to send is in filnam[], and if cmarg2 is not null
- or empty, the file should be sent under this name rather than filnam[].
- If sndfilter not NULL, it is the name of a send filter.
- Returns 1 on success, 0 on failure.
-*/
-int
-sfile(x) int x; {
-#ifdef pdp11
-#define PKTNL 64
-#else
-#define PKTNL 256
-#endif /* pdp11 */
- char pktnam[PKTNL+1]; /* Local copy of name */
- char *s;
- int rc;
- int notafile = 0;
- extern int filepeek;
-#ifdef PIPESEND
- extern char * sndfilter;
-
- if (sndfilter) {
- pipesend = 1;
- debug(F110,"sfile send filter ",sndfilter,0);
- }
-#endif /* PIPESEND */
-
- notafile = calibrate || sndarray || pipesend || x;
- debug(F101,"sfile x","",x);
- debug(F101,"sfile notafile","",notafile);
-
-#ifndef NOCSETS
- if (tcs_save > -1) { /* Character sets */
- tcharset = tcs_save;
- tcs_save = -1;
- debug(F101,"sfile restored tcharset","",tcharset);
- }
- if (fcs_save > -1) {
- fcharset = fcs_save;
- fcs_save = -1;
- debug(F101,"sfile restored fcharset","",fcharset);
- }
- setxlatype(tcharset,fcharset); /* Translation type */
-#endif /* NOCSETS */
-
- /* cmarg2 or filnam (with that precedence) have the file's name */
-
- lsstate = 0; /* Cancel locking-shift state */
-#ifdef COMMENT
- /* Do this after making sure we can open the file */
- if (nxtpkt() < 0) return(0); /* Bump packet number, get buffer */
-#endif /* COMMENT */
- pktnam[0] = NUL; /* Buffer for name we will send */
- if (x == 0) { /* F-Packet setup */
- if (!cmarg2) cmarg2 = "";
-#ifdef DEBUG
- if (deblog) {
- /* debug(F111,"sfile cmarg2",cmarg2,cmarg2); */
- debug(F101,"sfile binary 1","",binary);
- debug(F101,"sfile wearealike","",wearealike);
- debug(F101,"sfile xfermode","",xfermode);
- debug(F101,"sfile filepeek","",filepeek);
-#ifndef NOCSETS
- debug(F101,"sfile s_cset","",s_cset);
- debug(F101,"sfile tcharset","",tcharset);
- debug(F101,"sfile xfrxla","",xfrxla);
-#endif /* NOCSETS */
- }
-#endif /* DEBUG */
- if (xfermode == XMODE_A /* TRANSFER MODE AUTOMATIC */
-#ifndef NOMSEND
- && !addlist /* And not working from a SEND-LIST */
-#endif /* NOMSEND */
- ) {
- /* Other Kermit is on a like system and no charset translation */
- if (wearealike
-#ifndef NOCSETS
- && (tcharset == TC_TRANSP || xfrxla == 0)
-#endif /* NOCSETS */
- ) {
-#ifdef VMS
- if (binary != XYFT_I)
-#endif /* VMS */
-#ifdef CK_LABELED
- if (binary != XYFT_L)
-#endif /* CK_LABELED */
- binary = XYFT_B; /* Send all files in binary mode */
- }
-
- /* Otherwise select transfer mode based on file info */
-
- else if (!notafile /* but not if sending from pipe */
-#ifdef CK_LABELED
- && binary != XYFT_L /* and not if FILE TYPE LABELED */
-#endif /* CK_LABELED */
-#ifdef VMS
- && binary != XYFT_I /* or FILE TYPE IMAGE */
-#endif /* VMS */
- ) {
-#ifdef UNICODE
- fileorder = -1; /* File byte order */
-#endif /* UNICODE */
- if (filepeek && !notafile) { /* Real file, FILE SCAN is ON */
- int k, x;
- k = scanfile(filnam,&x,nscanfile); /* Scan the file */
- debug(F101,"sfile scanfile","",k);
- switch (k) {
- case FT_TEXT: /* Unspecified text */
- debug(F100,"sfile scanfile text","",0);
- binary = XYFT_T; /* SET FILE TYPE TEXT */
- break;
-#ifndef NOCSETS
- case FT_7BIT: /* 7-bit text */
- binary = XYFT_T; /* SET FILE TYPE TEXT */
- /* If SEND CHARSET-SELECTION AUTO */
- /* and SET TRANSFER TRANSLATION is ON */
- debug(F100,"sfile scanfile text7","",0);
- if (s_cset == XMODE_A && xfrxla) {
- if (fcsinfo[fcharset].size != 128) {
- fcs_save = fcharset; /* Current FCS not 7bit */
- fcharset = dcset7; /* Use default 7bit set */
- debug(F101,"sfile scanfile 7 fcharset",
- "",fcharset);
- }
- /* And also switch to appropriate TCS */
- if (afcset[fcharset] > -1 &&
- afcset[fcharset] <= MAXTCSETS) {
- tcs_save = tcharset;
- tcharset = afcset[fcharset];
- debug(F101,"sfile scanfile 7 tcharset","",
- tcharset);
- }
- setxlatype(tcharset,fcharset);
- }
- break;
-
- case FT_8BIT: /* 8-bit text */
- binary = XYFT_T; /* SET FILE TYPE TEXT */
- /* If SEND CHARSET-SELEC AUTO */
- /* and SET TRANSFER TRANSLATION is ON */
- debug(F100,"sfile scanfile text8","",0);
- if (s_cset == XMODE_A && xfrxla) {
- if (fcsinfo[fcharset].size != 256) {
- fcs_save = fcharset; /* Current FCS not 8bit */
- fcharset = dcset8; /* Use default 8bit set */
- debug(F101,"sfile scanfile 8 fcharset",
- "",fcharset);
- }
- /* Switch to corresponding transfer charset */
- if (afcset[fcharset] > -1 &&
- afcset[fcharset] <= MAXTCSETS) {
- tcs_save = tcharset;
- tcharset = afcset[fcharset];
- debug(F101,"sfile scanfile 8 tcharset","",
- tcharset);
- }
- setxlatype(tcharset,fcharset);
- }
- break;
-#ifdef UNICODE
- case FT_UTF8: /* UTF-8 text */
- case FT_UCS2: /* UCS-2 text */
- debug(F101,"sfile scanfile Unicode","",k);
- binary = XYFT_T;
- /* If SEND CHARSET-SELEC AUTO */
- /* and SET TRANSFER TRANSLATION is ON */
- if (s_cset == XMODE_A && xfrxla) {
- fcs_save = fcharset;
- tcs_save = tcharset;
- fcharset = (k == FT_UCS2) ? FC_UCS2 : FC_UTF8;
- if (k == FT_UCS2 && x > -1)
- fileorder = x;
- }
- /* Switch to associated transfer charset if any */
- if (afcset[fcharset] > -1 &&
- afcset[fcharset] <= MAXTCSETS)
- tcharset = afcset[fcharset];
- if (tcharset == TC_TRANSP) /* If none */
- tcharset = TC_UTF8; /* use UTF-8 */
- setxlatype(tcharset,fcharset);
- debug(F101,"sfile Unicode tcharset","",tcharset);
- break;
-#endif /* UNICODE */
-#endif /* NOCSETS */
- case FT_BIN:
- debug(F101,"sfile scanfile binary","",k);
- binary = XYFT_B;
- break;
- /* Default: Don't change anything */
- }
- }
- }
- debug(F101,"sfile binary 2","",binary);
- debug(F101,"sfile sendmode","",sendmode);
- }
- if (*cmarg2) { /* If we have a send-as name... */
- int y; char *s;
-#ifndef NOSPL /* and a script programming language */
- extern int cmd_quoting;
- if (cmd_quoting) { /* and it's not turned off */
- y = PKTNL; /* pass as-name thru the evaluator */
- s = pktnam;
- zzstring(cmarg2,&s,&y);
-#ifdef COMMENT
-/* This ruins macros like BSEND */
- if (!pktnam[0]) /* and make sure result is not empty */
- sprintf(pktnam,"FILE%02ld",filcnt);
-#endif /* COMMENT */
- } else
-#endif /* NOSPL */
- ckstrncpy(pktnam,cmarg2,PKTNL); /* copy it literally, */
-
- debug(F110,"sfile pktnam",pktnam,0);
-#ifdef COMMENT
-/* We don't do this any more because now we have filename templates */
- cmarg2 = ""; /* and blank it out for next time. */
-#endif /* COMMENT */
- }
- if (!*pktnam) { /* No as-name... */
-#ifdef NZLTOR
- int xfncnv, xpath;
- debug(F101,"sfile fnspath","",fnspath);
- debug(F101,"sfile fncnv","",fncnv);
- xfncnv = fncnv;
- xpath = fnspath;
- if (notafile) { /* If not an actual file */
- xfncnv = 0; /* Don't convert name */
- xpath = PATH_OFF; /* Leave path off */
- } else if (xfncnv &&
- (!strcmp(whoareu,"U1") || !strcmp(whoareu,"UN"))
- ) {
- /* Less-strict conversion if partner is UNIX or Win32 */
- xfncnv = -1;
- }
- debug(F101,"sfile xpath","",xpath);
- debug(F101,"sfile xfncnv","",xfncnv);
- nzltor(filnam,pktnam,xfncnv,xpath,PKTNL);
-
-#else /* Not NZLTOR */
-
- debug(F101,"sfile fnspath","",fnspath);
- if (fnspath == PATH_OFF /* Stripping path names? */
- && (!notafile) /* (of actual files) */
- ) {
- char *t; /* Yes. */
- zstrip(filnam,&t); /* Strip off the path. */
- debug(F110,"sfile zstrip",t,0);
- if (!t) t = "UNKNOWN"; /* Be cautious... */
- else if (*t == '\0')
- t = "UNKNOWN";
- ckstrncpy(pktnam,t,PKTNL); /* Copy stripped name literally. */
- } else if (fnspath == PATH_ABS && !notafile) {
- /* Converting to absolute form */
- zfnqfp(filnam,PKTNL,pktnam);
- } else
- ckstrncpy(pktnam,filnam,PKTNL);
-
- /* pktnam[] has the packet name, filnam[] has the original name. */
- /* But we still need to convert pktnam if FILE NAMES CONVERTED. */
-
- debug(F101,"sfile fncnv","",fncnv);
- if (fncnv && !notafile) { /* If converting names of files */
- zltor(pktnam,(char *)srvcmd); /* convert it to common form, */
- ckstrncpy(pktnam,(char *)srvcmd,PKTNL);
- *srvcmd = NUL;
- }
-#endif /* NZLTOR */
- }
- if (!*pktnam) /* Failsafe... */
- sprintf(pktnam,"FILE%02ld",filcnt);
- debug(F110,"sfile filnam 1",filnam,0);
- debug(F110,"sfile pktnam 1",pktnam,0);
-#ifdef PIPESEND
-/* If we have a send filter, substitute the current filename into it */
-
- if (sndfilter) {
- char * p = NULL, * q;
- int n = CKMAXPATH;
-#ifndef NOSPL
- if ((p = (char *) malloc(n + 1))) {
- q = p;
- debug(F110,"sfile pipesend filter",sndfilter,0);
- zzstring(sndfilter,&p,&n);
- debug(F111,"sfile pipename",q,n);
- if (n <= 0) {
- printf(
- "?Sorry, send filter + filename too long, %d max.\n",
- CKMAXPATH
- );
- free(q);
- return(0);
- }
- ckstrncpy(filnam,q,CKMAXPATH+1);
- free(q);
- }
-#endif /* NOSPL */
- }
-#endif /* PIPESEND */
-
- debug(F110,"sfile filnam 2",filnam,0); /* Log debugging info */
- debug(F110,"sfile pktnam 2",pktnam,0);
- if (openi(filnam) == 0) /* Try to open the input file */
- return(0);
-
-#ifdef CK_RESEND
-/*
- The following check is done after openi() is called, since openi() itself
- can change the transfer mode (as in VMS).
-*/
- if ((binary == XYFT_T
-#ifdef VMS
- || binary == XYFT_L
-#endif /* VMS */
- ) && sendmode == SM_RESEND) {
- /* Trying to RESEND/REGET a file first sent in TEXT mode. */
- debug(F111,"sfile error - Recover vs Text",filnam,binary);
- /* Set appropriate error messages and make log entries here */
-#ifdef VMS
- if (binary == XYFT_L)
- ckmakmsg((char *)epktmsg,
- PKTMSGLEN,
- "Recovery attempted in LABELED mode: ",
- filnam,
- NULL,
- NULL
- );
- else
-#endif /* VMS */
- ckmakmsg((char *)epktmsg,
- PKTMSGLEN,
- "Recovery attempted in TEXT mode: ",
- filnam,
- NULL,
- NULL
- );
- return(0);
- }
- if (sendmode == SM_PSEND) /* PSENDing? */
- if (sendstart > (CK_OFF_T)0) /* Starting position */
- if (zfseek(sendstart) < 0) /* seek to it... */
- return(0);
-#endif /* CK_RESEND */
- s = pktnam; /* Name for packet data field */
-#ifdef OS2
- /* Never send a disk letter. */
- if (isalpha(*s) && (*(s+1) == ':'))
- s += 2;
-#endif /* OS2 */
-
- } else { /* X-packet setup, not F-packet. */
- binary = XYFT_T; /* Text always */
- debug(F110,"sfile X packet",cmdstr,0); /* Log debugging info */
- s = cmdstr; /* Name for data field */
- }
-
- /* Now s points to the string that goes in the packet data field. */
-
- debug(F101,"sfile binary","",binary); /* Log debugging info */
- encstr((CHAR *)s); /* Encode the name. */
- /* Send the F or X packet */
- /* If the encoded string did not fit into the packet, it was truncated. */
-
- if (nxtpkt() < 0) return(0); /* Bump packet number, get buffer */
-
- rc = spack((char) (x ? 'X' : 'F'), pktnum, size, data);
- if (rc < 0)
- return(rc);
-
-#ifndef NOCSETS
- setxlatype(tcharset,fcharset); /* Set up charset translations */
-#endif /* NOCSETS */
-
- if (x == 0) { /* Display for F packet */
- if (displa) { /* Screen */
- xxscreen(SCR_FN,'F',(long)pktnum,filnam);
- xxscreen(SCR_AN,0,0L,pktnam);
- xxscreen(SCR_FS,0,calibrate ? calibrate : fsize,"");
- }
-#ifdef pdp11
- tlog(F110,"Sending",filnam,0L); /* Transaction log entry */
- makestr(&psfspec,filnam); /* New filename */
-#else
-#ifndef ZFNQFP
- tlog(F110,"Sending",filnam,0L);
- makestr(&psfspec,filnam); /* New filename */
-#else
- if (notafile) { /* If not a file log simple name */
- tlog(F110,"Sending", filnam, 0L);
- } else { /* Log fully qualified filename */
-#ifdef COMMENT
- /* This section generates bad code in SCO 3.2v5.0.5's cc */
- char *p = NULL, *q = filnam;
- debug(F101,"sfile CKMAXPATH","",CKMAXPATH);
- if ((p = malloc(CKMAXPATH+1))) {
- debug(F111,"sfile calling zfnqfp",filnam,strlen(filnam));
- if (zfnqfp(filnam, CKMAXPATH, p)) {
- debug(F111,"sfile zfnqfp ok",p,strlen(p));
- q = p;
- }
- }
-#else
- char tmpbuf[CKMAXPATH+1];
- char *p = tmpbuf, *q = filnam;
- if (zfnqfp(filnam, CKMAXPATH, p))
- q = p;
-#endif /* COMMENT */
- debug(F111,"sfile q",q,strlen(q));
- tlog(F110,"Sending",q,0L);
- makestr(&psfspec,q); /* New preliminary filename */
-#ifdef COMMENT
- if (p) free(p);
-#endif /* COMMENT */
- }
-#endif /* ZFNQFP */
-#endif /* pdp11 */
- tlog(F110," as",pktnam,0L);
- if (binary) { /* Log file mode in transaction log */
- tlog(F101," mode: binary","",(long) binary);
- } else { /* If text mode, check character set */
- tlog(F100," mode: text","",0L);
-#ifndef NOCSETS
- if (tcharset == TC_TRANSP || xfrxla == 0) {
- tlog(F110," character set","transparent",0L);
- } else {
- tlog(F110," xfer character set",tcsinfo[tcharset].name,0L);
- tlog(F110," file character set",fcsinfo[fcharset].name,0L);
- }
-#endif /* NOCSETS */
- }
- } else { /* Display for X-packet */
-
- xxscreen(SCR_XD,'X',(long)pktnum,cmdstr); /* Screen */
- tlog(F110,"Sending from:",cmdstr,0L); /* Transaction log */
- }
- intmsg(++filcnt); /* Count file, give interrupt msg */
- first = 1; /* Init file character lookahead. */
- ffc = (CK_OFF_T)0; /* Init file character counter. */
- cps = oldcps = 0L; /* Init cps statistics */
- rejection = -1;
- fsecs = gtimer(); /* Time this file started */
-#ifdef GFTIMER
- fpfsecs = gftimer();
- debug(F101,"SFILE fpfsecs","",fpfsecs);
-#endif /* GFTIMER */
- debug(F101,"SFILE fsecs","",fsecs);
- return(1);
-}
-
-/* S D A T A -- Send a data packet */
-
-/*
- Returns -1 if no data to send (end of file), -2 if connection is broken.
- If there is data, a data packet is sent, and sdata() returns 1.
-
- In the streaming case, the window is regarded as infinite and we keep
- sending data packets until EOF or there appears to be a Kermit packet on the
- reverse channel. When not streaming and the window size is greater than 1,
- we keep sending data packets until window is full or characters start to
- appear from the other Kermit.
-
- In the windowing or streaming case, when there is no more data left to send
- (or when sending has been interrupted), sdata() does nothing and returns 0
- each time it is called until the acknowledgement sequence number catches up
- to the last data packet that was sent.
-*/
-int
-sdata() {
- int i, x, len;
- char * s;
-
- debug(F101,"sdata entry, first","",first);
- debug(F101,"sdata drain","",drain);
-/*
- The "drain" flag is used with window size > 1. It means we have sent
- our last data packet. If called and drain is not zero, then we return
- 0 as if we had sent an empty data packet, until all data packets have
- been ACK'd, then then we can finally return -1 indicating EOF, so that
- the protocol can switch to seof state. This is a kludge, but at least
- it's localized...
-*/
- if (first == 1) drain = 0; /* Start of file, init drain flag. */
-
- if (drain) { /* If draining... */
- debug(F101,"sdata draining, winlo","",winlo);
- if (winlo == pktnum) /* If all data packets are ACK'd */
- return(-1); /* return EOF indication */
- else /* otherwise */
- return(0); /* pretend we sent a data packet. */
- }
- debug(F101,"sdata sbufnum","",sbufnum);
- for (i = sbufnum;
- i > 0
-#ifdef STREAMING
- || streaming
-#endif /* STREAMING */
- ;
- i--) {
- if (i < 0)
- break;
- debug(F101,"sdata countdown","",i);
-#ifdef STREAMING
- if (streaming) {
- pktnum = (pktnum + 1) % 64;
- winlo = pktnum;
- debug(F101,"sdata streaming pktnum","",pktnum);
- } else {
-#endif /* STREAMING */
- x = nxtpkt(); /* Get next pkt number and buffer */
- debug(F101,"sdata nxtpkt pktnum","",pktnum);
- if (x < 0) return(0);
-#ifdef STREAMING
- }
-#endif /* STREAMING */
- debug(F101,"sdata packet","",pktnum);
- if (chkint() < 0) /* Especially important if streaming */
- return(-9);
- if (cxseen || czseen) { /* If interrupted, done. */
- if (wslots > 1) {
- drain = 1;
- debug(F100,"sdata cx/zseen windowing","",0);
- return(0);
- } else {
- debug(F100,"sdata cx/zseen nonwindowing","",0);
- return(-1);
- }
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"sdata spsiz","",spsiz);
- debug(F101,"sdata binary","",binary);
- debug(F101,"sdata parity","",parity);
- }
-#endif /* DEBUG */
-#ifdef CKTUNING
- if (binary && !parity && !memstr && !funcstr)
- len = bgetpkt(spsiz);
- else
- len = getpkt(spsiz,1);
-#else
- len = getpkt(spsiz,1);
-#endif /* CKTUNING */
- s = (char *)data;
- if (len == -3) { /* Timed out (e.g.reading from pipe) */
- s = ""; /* Send an empty data packet. */
- len = 0;
- } else if (len == 0) { /* Done if no data. */
- if (pktnum == winlo)
- return(-1);
- drain = 1; /* But can't return -1 until all */
- debug(F101,"sdata eof, drain","",drain);
- return(0); /* ACKs are drained. */
- }
- debug(F101,"sdata pktnum","",pktnum);
- debug(F101,"sdata len","",len);
- debug(F011,"sdata data",data,52);
-
- x = spack('D',pktnum,len,(CHAR *)s); /* Send the data packet. */
- debug(F101,"sdata spack","",x);
- if (x < 0) { /* Error */
- ttchk(); /* See if connection is still there */
- return(-2);
- }
-#ifdef STREAMING
- if (streaming) /* What an ACK would do. */
- winlo = pktnum;
-#endif /* STREAMING */
- x = ttchk(); /* Peek at input buffer. */
- debug(F101,"sdata ttchk","",x); /* ACKs waiting, maybe? */
- if (x < 0) /* Or connection broken? */
- return(-2);
-/*
- Here we check to see if any ACKs or NAKs have arrived, in which case we
- break out of the D-packet-sending loop and return to the state switcher
- to process them. This is what makes our windows slide instead of lurch.
-*/
- if (
-#ifdef GEMDOS
-/*
- In the Atari ST version, ttchk() can only return 0 or 1. But note: x will
- probably always be > 0, since the as-yet-unread packet terminator from the
- last packet is probably still in the buffer, so sliding windows will
- probably never happen when the Atari ST is the file sender. The alternative
- is to say "if (0)", in which case the ST will always send a window full of
- packets before reading any ACKs or NAKs.
-*/
- x > 0
-
-#else /* !GEMDOS */
-/*
- In most other versions, ttchk() returns the actual count.
- It can't be a Kermit packet if it's less than five bytes long.
-*/
- x > 4 + bctu
-
-#endif /* GEMDOS */
- )
- return(1); /* Yes, stop sending data packets */
- } /* and go try to read the ACKs. */
- return(1);
-}
-
-
-/* S E O F -- Send an End-Of-File packet */
-
-/* Call with a string pointer to character to put in the data field, */
-/* or else a null pointer or "" for no data. */
-
-/*
- There are two "send-eof" functions. seof() is used to send the normal eof
- packet at the end of a file's data (even if the file has no data), or when
- a file transfer is interrupted. sxeof() is used to send an EOF packet that
- occurs because of attribute refusal or interruption prior to entering data
- state. The difference is purely a matter of buffer allocation and packet
- sequence number management. Both functions act as "front ends" to the
- common send-eof function, szeof().
-*/
-
-/* Code common to both seof() and sxeof() */
-
-int
-szeof(s) CHAR *s; {
- int x;
- lsstate = 0; /* Cancel locking-shift state */
- if (!s) s = (CHAR *)"";
- debug(F111,"szeof",s,pktnum);
- if (*s) {
- x = spack('Z',pktnum,1,s);
- xitsta |= W_SEND;
-#ifdef COMMENT
- tlog(F100," *** interrupted, sending discard request","",0L);
-#endif /* COMMENT */
- filrej++;
- } else {
- x = spack('Z',pktnum,0,(CHAR *)"");
- }
- if (x < 0)
- return(x);
-
-#ifdef COMMENT
- /* No, too soon */
- discard = 0; /* Turn off per-file discard flag */
-#endif /* COMMENT */
-
-/* If we were sending from a pipe, we're not any more... */
- pipesend = 0;
- return(0);
-}
-
-int
-seof(x) int x; {
- char * s;
-/*
- ckcpro.w, before calling seof(), sets window size back to 1 and then calls
- window(), which clears out the old buffers. This is OK because the final
- data packet for the file has been ACK'd. However, sdata() has already
- called nxtpkt(), which set the new value of pktnum which seof() will use.
- So all we need to do here is is allocate a new send-buffer.
-*/
- s = x ? "D" : "";
- debug(F111,"seof",s,pktnum);
- if (getsbuf(pktnum) < 0) { /* Get a buffer for packet n */
- debug(F101,"seof can't get s-buffer","",pktnum);
- return(-1);
- }
- return(szeof((CHAR *)s));
-}
-
-/*
- Version of seof() to be called when sdata() has not been called before. The
- difference is that this version calls nxtpkt() to allocate a send-buffer and
- get the next packet number.
-*/
-int
-sxeof(x) int x; {
- char * s;
- s = x ? "D" : "";
- if (nxtpkt() < 0) /* Get next pkt number and buffer */
- debug(F101,"sxeof nxtpkt fails","",pktnum);
- else
- debug(F101,"sxeof packet","",pktnum);
- return(szeof((CHAR *)s));
-}
-
-/* S E O T -- Send an End-Of-Transaction packet */
-
-int
-seot() {
- int x;
- x = nxtpkt();
- debug(F101,"seot nxtpkt","",x);
- if (x < 0) return(-1); /* Bump packet number, get buffer */
- x = spack('B',pktnum,0,(CHAR *)""); /* Send the EOT packet */
- if (x < 0)
- return(x);
- cxseen = czseen = discard = 0; /* Reset interruption flags */
- tstats(); /* Log timing info */
- return(0);
-}
-
-
-/* R P A R -- Fill the data array with my send-init parameters */
-
-int q8flag = 0;
-
-CHAR dada[32]; /* Use this instead of data[]. */
- /* To avoid some kind of wierd */
- /* addressing foulup in spack()... */
- /* (which might be fixed now...) */
-
-CHAR *
-rpar() {
- char *p;
- int i, x, max;
- extern int sprmlen;
-
- max = maxdata(); /* Biggest data field I can send */
- debug(F101, "rpar max 1","",max);
- debug(F101, "rpar sprmlen","",sprmlen);
- if (sprmlen > 1 && sprmlen < max) /* User override */
- max = sprmlen;
- debug(F101, "rpar max 2","",max);
-
- if (rpsiz > MAXPACK) /* Biggest normal packet I want. */
- dada[0] = (char) tochar(MAXPACK); /* If > 94, use 94, but specify */
- else /* extended packet length below... */
- dada[0] = (char) tochar(rpsiz); /* else use what the user said. */
- dada[1] = (char) tochar(chktimo(pkttim,0)); /* When to time me out */
- dada[2] = (char) tochar(mypadn); /* How much padding I need (none) */
- dada[3] = (char) ctl(mypadc); /* Padding character I want */
- dada[4] = (char) tochar(eol); /* End-Of-Line character I want */
- dada[5] = myctlq; /* Control-Quote character I send */
-
- if (max < 6) { dada[6] = NUL; rqf = 0; ebq = sq = NUL; return(dada); }
-
- switch (rqf) { /* 8th-bit prefix (single-shift) */
- case -1: /* I'm opening the bids */
- case 1: /* Other Kermit already bid 'Y' */
- if (parity) ebq = sq = MYEBQ; /* So I reply with '&' if parity */
- break; /* otherwise with 'Y'. */
- case 2: /* Other Kermit sent a valid prefix */
- if (q8flag)
- sq = ebq; /* Fall through on purpose */
- case 0: /* Other Kermit bid nothing */
- break; /* So I reply with 'Y'. */
- }
- debug(F000,"rpar 8bq sq","",sq);
- debug(F000,"rpar 8bq ebq","",ebq);
- if (lscapu == 2) /* LOCKING-SHIFT FORCED */
- dada[6] = 'N'; /* requires no single-shift */
- else /* otherwise send prefix or 'Y' */
- dada[6] = (char) sq;
- ebqsent = dada[6]; /* And remember what I really sent */
-
- if (max < 7) { dada[7] = NUL; bctr = 1; return(dada); }
-
- dada[7] = (char) (bctr == 4) ? 'B' : bctr + '0'; /* Block check type */
-
- if (max < 8) { dada[8] = NUL; rptflg = 0; return(dada); }
-
- if (rptena) {
- if (rptflg) /* Run length encoding */
- dada[8] = (char) rptq; /* If receiving, agree */
- else /* by replying with same character. */
- dada[8] = (char) (rptq = myrptq); /* When sending use this. */
- } else dada[8] = SP; /* Not enabled, put a space here. */
-
- /* CAPAS mask */
-
- if (max < 9) {
- dada[9] = NUL;
- atcapr = 0;
- lpcapr = 0;
- swcapr = 0;
- rscapr = 0;
- return(dada);
- }
- dada[9] = (char) tochar((lscapr ? lscapb : 0) | /* Locking shifts */
- (atcapr ? atcapb : 0) | /* Attribute packets */
- (lpcapr ? lpcapb : 0) | /* Long packets */
- (swcapr ? swcapb : 0) | /* Sliding windows */
- (rscapr ? rscapb : 0)); /* RESEND */
- if (max < 10) { wslotr = 1; return(dada); }
- dada[10] = (char) tochar(swcapr ? wslotr : 1); /* CAPAS+1 = Window size */
-
- if (max < 12) { rpsiz = 80; return(dada); }
- if (urpsiz > 94)
- rpsiz = urpsiz - 1; /* Long packets ... */
- dada[11] = (char) tochar(rpsiz / 95); /* Long packet size, big part */
- dada[12] = (char) tochar(rpsiz % 95); /* Long packet size, little part */
-
- if (max < 16) return(dada);
- dada[13] = '0'; /* CAPAS+4 = WONT CHKPNT */
- dada[14] = '_'; /* CAPAS+5 = CHKINT (reserved) */
- dada[15] = '_'; /* CAPAS+6 = CHKINT (reserved) */
- dada[16] = '_'; /* CAPAS+7 = CHKINT (reserved) */
- if (max < 17) return(dada);
-#ifndef WHATAMI
- dada[17] = ' ';
-#else
- x = 0;
- if (server) x |= WMI_SERVE; /* Whether I am a server */
- if (binary) x |= WMI_FMODE; /* My file transfer mode is ... */
- if (fncnv) x |= WMI_FNAME; /* My filename conversion is ... */
-#ifdef STREAMING
- if (streamrq == SET_ON)
- x |= WMI_STREAM;
- else if (streamrq == SET_AUTO && reliable == SET_ON)
- x |= WMI_STREAM;
- /*
- Always offer to stream when in remote mode and STREAMING is AUTO
- and RELIABLE is not OFF (i.e. is ON or AUTO).
- */
- else if (!local && streamrq == SET_AUTO && reliable != SET_OFF)
- x |= WMI_STREAM;
-#endif /* STREAMING */
-#ifdef TCPSOCKET
- if (clearrq == SET_ON)
- x |= WMI_CLEAR;
- else if (clearrq == SET_AUTO && /* SET CLEAR-CHANNEL AUTO */
- ((network && nettype == NET_TCPB /* TCP/IP */
-#ifdef RLOGCODE
- && ttnproto != NP_RLOGIN/* Rlogin is not clear */
- && !(ttnproto >= NP_K4LOGIN && ttnproto <= NP_EK5LOGIN)
-#endif /* RLOGCODE */
- )
-#ifdef SSHBUILTIN
- || (network && nettype == NET_SSH)
-#endif /* SSHBUILTIN */
-#ifdef IKSD
- || inserver /* We are IKSD */
-#endif /* IKSD */
- ))
- x |= WMI_CLEAR;
-#endif /* TCPSOCKET */
- x |= WMI_FLAG;
- dada[17] = (char) tochar(x);
-#endif /* WHATAMI */
- i = 18; /* Position of next field */
- p = cksysid; /* WHOAMI (my system ID) */
- x = strlen(p);
- if (max - i < x + 1) return(dada);
- if (x > 0) {
- dada[i++] = (char) tochar(x);
- while (*p)
- dada[i++] = *p++;
- }
-
- if (max < i+1) return(dada);
-#ifndef WHATAMI /* WHATAMI2 */
- dada[i++] = ' ';
-#else
- debug(F101,"rpar xfermode","",xfermode);
- x = WMI2_FLAG; /* Is-Valid flag */
- if (xfermode != XMODE_A) /* If TRANSFER MODE is MANUAL */
- x |= WMI2_XMODE; /* set the XFERMODE bit */
- if (recursive > 0) /* If this is a recursive transfer */
- x |= WMI2_RECU; /* set the RECURSIVE bit */
- dada[i++] = tochar(x);
- debug(F101,"rpar whatami2","",x);
-#endif /* WHATAMI */
-
- dada[i] = '\0'; /* Terminate the init string */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"rpar",dada,0);
- rdebu(dada,(int)strlen((char *)dada));
- }
-#endif /* DEBUG */
- ckstrncpy((char *)myinit,(char *)dada,MYINITLEN);
- return(dada); /* Return pointer to string. */
-}
-
-int
-spar(s) CHAR *s; { /* Set parameters */
- int x, y, lpsiz, biggest;
- extern int rprmlen, lastspmax;
- extern struct sysdata sysidlist[];
-
- whatru = 0;
- whoareu[0] = NUL;
-#ifdef STREAMING
- streamok = 0;
- streaming = 0;
-#endif /* STREAMING */
- biggest = rln;
-
- debug(F101, "spar biggest 1","",biggest);
- debug(F101, "spar rprmlen","",rprmlen);
- if (rprmlen > 1 && rprmlen < biggest)
- biggest = rprmlen;
- debug(F101, "rpar biggest 2","",biggest);
- debug(F110,"spar packet",s,0);
-
- s--; /* Line up with field numbers. */
-
-/* Limit on size of outbound packets */
- x = (biggest >= 1) ? xunchar(s[1]) : 80;
- lpsiz = spsizr; /* Remember what they SET. */
- if (spsizf) { /* SET-command override? */
- if (x < spsizr) spsiz = x; /* Ignore LEN unless smaller */
- } else { /* otherwise */
- spsiz = (x < 10) ? 80 : x; /* believe them if reasonable */
- }
- spmax = spsiz; /* Remember maximum size */
-
-/* Timeout on inbound packets */
- if (timef) {
- timint = rtimo; /* SET SEND TIMEOUT value overrides */
- } else { /* Otherwise use requested value, */
- x = (biggest >= 2) ? xunchar(s[2]) : rtimo; /* if it is legal. */
- timint = (x < 0) ? rtimo : x;
- }
- timint = chktimo(timint,timef); /* Adjust if necessary */
-
-/* Outbound Padding */
- npad = 0; padch = '\0';
- if (biggest >= 3) {
- npad = xunchar(s[3]);
- if (biggest >= 4) padch = (CHAR) ctl(s[4]); else padch = 0;
- }
- if (npad) {
- int i;
- for (i = 0; i < npad; i++) padbuf[i] = dopar(padch);
- }
-
-/* Outbound Packet Terminator */
- seol = (CHAR) (biggest >= 5) ? xunchar(s[5]) : CR;
- if ((seol < 1) || (seol > 31)) seol = CR;
-
-/* Control prefix that the other Kermit is sending */
- x = (biggest >= 6) ? s[6] : '#';
- ctlq = (CHAR) (((x > 32 && x < 63) || (x > 95 && x < 127)) ? x : '#');
-
-/* 8th-bit prefix */
-/*
- NOTE: Maybe this could be simplified using rcvtyp.
- If rcvtyp == 'Y' then we're reading the ACK,
- otherwise we're reading the other Kermit's initial bid.
- But his horrendous code has been working OK for years, so...
-*/
- rq = (biggest >= 7) ? s[7] : 0;
- if (rq == 'Y') rqf = 1;
- else if ((rq > 32 && rq < 63) || (rq > 95 && rq < 127)) rqf = 2;
- else rqf = 0;
- debug(F000,"spar 8bq rq","",rq);
- debug(F000,"spar 8bq sq","",sq);
- debug(F000,"spar 8bq ebq","",ebq);
- debug(F101,"spar 8bq rqf","",rqf);
- switch (rqf) {
- case 0: /* Field is missing from packet. */
- ebqflg = 0; /* So no 8th-bit prefixing. */
- break;
- case 1: /* Other Kermit sent 'Y' = Will Do. */
- /*
- When I am the file receiver, ebqsent is 0 because I didn't send a
- negotiation yet. If my parity is set to anything other than NONE,
- either because my user SET PARITY or because I detected parity bits
- on this packet, I reply with '&', otherwise 'Y'.
-
- When I am the file sender, ebqsent is what I just sent in rpar(),
- which can be 'Y', 'N', or '&'. If I sent '&', then this 'Y' means
- the other Kermit agrees to do 8th-bit prefixing.
-
- If I sent 'Y' or 'N', but then detected parity on the ACK packet
- that came back, then it's too late: there is no longer any way for
- me to tell the other Kermit that I want to do 8th-bit prefixing, so
- I must not do it, and in that case, if there is any 8-bit data in
- the file to be transferred, the transfer will fail because of block
- check errors.
-
- The following clause covers all of these situations:
- */
- if (parity && (ebqsent == 0 || ebqsent == '&')) {
- ebqflg = 1;
- ebq = MYEBQ;
- }
- break;
- case 2: /* Other Kermit sent a valid prefix */
- ebqflg = (ebq == sq || sq == 'Y');
- if (ebqflg) {
- ebq = rq;
- debug(F101,"spar setting parity to space","",ebq);
- if (!parity) parity = ttprty = 's';
- }
- }
- if (lscapu == 2) { /* But no single-shifts if LOCKING-SHIFT FORCED */
- ebqflg = 0;
- ebq = 'N';
- }
-
-/* Block check */
- x = 1;
- if (biggest >= 8) {
- if (s[8] == 'B') x = 4;
- else x = s[8] - '0';
- if ((x < 1) || (x > 5)) x = 1; /* "5" 20110605 */
- }
- bctr = x;
-
-/* Repeat prefix */
-
- rptflg = 0; /* Assume no repeat-counts */
- if (biggest >= 9) { /* Is there a repeat-count field? */
- char t; /* Yes. */
- t = s[9]; /* Get its contents. */
-/*
- If I'm sending files, then I'm reading these parameters from an ACK, and so
- this character must agree with what I sent.
-*/
- if (rptena) { /* If enabled ... */
- if ((char) rcvtyp == 'Y') { /* Sending files, reading ACK. */
- if (t == myrptq) rptflg = 1;
- } else { /* I'm receiving files */
- if ((t > 32 && t < 63) || (t > 95 && t < 127)) {
- rptflg = 1;
- rptq = t;
- }
- }
- } else rptflg = 0;
- }
-
-/* Capabilities */
-
- atcapu = lpcapu = swcapu = rscapu = 0; /* Assume none of these. */
- if (lscapu != 2) lscapu = 0; /* Assume no LS unless forced. */
- y = 11; /* Position of next field, if any */
- if (biggest >= 10) {
- x = xunchar(s[10]);
- debug(F101,"spar capas","",x);
- atcapu = (x & atcapb) && atcapr; /* Attributes */
- lpcapu = (x & lpcapb) && lpcapr; /* Long packets */
- swcapu = (x & swcapb) && swcapr; /* Sliding windows */
- rscapu = (x & rscapb) && rscapr; /* RESEND */
- debug(F101,"spar lscapu","",lscapu);
- debug(F101,"spar lscapr","",lscapr);
- debug(F101,"spar ebqflg","",ebqflg);
- if (lscapu != 2) lscapu = ((x & lscapb) && lscapr && ebqflg) ? 1 : 0;
- debug(F101,"spar swcapr","",swcapr);
- debug(F101,"spar swcapu","",swcapu);
- debug(F101,"spar lscapu","",lscapu);
- for (y = 10; (xunchar(s[y]) & 1) && (biggest >= y); y++);
- debug(F101,"spar y","",y);
- }
-
-/* Long Packets */
- debug(F101,"spar lpcapu","",lpcapu);
- if (lpcapu) {
- if (biggest > y+1) {
- x = xunchar(s[y+2]) * 95 + xunchar(s[y+3]);
- debug(F101,"spar lp len","",x);
- if (spsizf) { /* If overriding negotiations */
- spsiz = (x < lpsiz) ? x : lpsiz; /* do this, */
- } else { /* otherwise */
- spsiz = (x > MAXSP) ? MAXSP : x; /* do this. */
- }
- if (spsiz < 10) spsiz = 80; /* Be defensive... */
- }
- }
- /* (PWP) save current send packet size for optimal packet size calcs */
- spmax = spsiz; /* Maximum negotiated length */
- lastspmax = spsiz; /* For stats */
- if (slostart && spsiz > 499) /* Slow start length */
- spsiz = 244;
- debug(F101,"spar slow-start spsiz","",spsiz);
- debug(F101,"spar lp spmax","",spmax);
- timint = chktimo(timint,timef); /* Recalculate the packet timeout */
-
-/* Sliding Windows... */
-
- if (swcapr) { /* Only if requested... */
- if (biggest > y) { /* See what other Kermit says */
- x = xunchar(s[y+1]);
- debug(F101,"spar window","",x);
- wslotn = (x > MAXWS) ? MAXWS : x;
-/*
- wslotn = negotiated size (from other Kermit's S or I packet).
- wslotr = requested window size (from this Kermit's SET WINDOW command).
-*/
- if (wslotn > wslotr) /* Use the smaller of the two */
- wslotn = wslotr;
- if (wslotn < 1) /* Watch out for bad negotiation */
- wslotn = 1;
- if (wslotn > 1) {
- swcapu = 1; /* We do windows... */
- if (wslotn > maxtry) /* Retry limit must be greater */
- maxtry = wslotn + 1; /* than window size. */
- }
- debug(F101,"spar window after adjustment","",x);
- } else { /* No window size specified. */
- wslotn = 1; /* We don't do windows... */
- debug(F101,"spar window","",x);
- swcapu = 0;
- debug(F101,"spar no windows","",wslotn);
- }
- }
-
-/* Now recalculate packet length based on number of windows. */
-/* The nogotiated number of window slots will be allocated, */
-/* and the maximum packet length will be reduced if necessary, */
-/* so that a windowful of packets can fit in the big buffer. */
-
- if (wslotn > 1) { /* Shrink to fit... */
- x = adjpkl(spmax,wslotn,bigsbsiz);
- if (x < spmax) {
- spmax = x;
- lastspmax = spsiz;
- if (slostart && spsiz > 499) spsiz = 244; /* Slow start again */
- debug(F101,"spar sending, redefine spmax","",spmax);
- }
- }
-#ifdef WHATAMI
- debug(F101,"spar biggest","",biggest);
- if (biggest > y+7) { /* Get WHATAMI info if any */
- whatru = xunchar(s[y+8]);
- debug(F101,"spar whatru","",whatru);
- }
- if (whatru & WMI_FLAG) { /* Only valid if this bit is set */
-#ifdef STREAMING
- if (whatru & WMI_STREAM) {
- if (streamrq == SET_ON ||
- (streamrq == SET_AUTO &&
- (reliable == SET_ON || (reliable == SET_AUTO && !local)
-#ifdef TN_COMPORT
- && !istncomport()
-#endif /* TN_COMPORT */
-#ifdef IKSD
- || inserver
-#endif /* IKSD */
- ))) {
- streamok = 1; /* Streaming negotiated */
- slostart = 0; /* Undo slow-start machinations */
- spsiz = lastspmax;
- }
- }
- streamed = streamok;
- debug(F101,"spar streamok","",streamok);
- debug(F101,"spar clearrq","",clearrq);
- if (clearrq == SET_ON ||
- (clearrq == SET_AUTO &&
- ((network && nettype == NET_TCPB
-#ifdef RLOGCODE
- && ttnproto != NP_RLOGIN/* Rlogin is not clear */
- && !(ttnproto >= NP_K4LOGIN && ttnproto <= NP_EK5LOGIN)
-#endif /* RLOGCODE */
-#ifdef TN_COMPORT
- && !istncomport()
-#endif /* TN_COMPORT */
- )
-#ifdef SSHBUILTIN
- || (network && nettype == NET_SSH)
-#endif /* SSHBUILTIN */
-#ifdef IKSD
- || inserver
-#endif /* IKSD */
- )))
- urclear = (whatru & WMI_CLEAR);
- debug(F101,"spar urclear","",urclear);
-#ifdef CK_SPEED
- if (urclear)
- setprefix(PX_NON);
-#endif /* CK_SPEED */
- cleared = urclear;
-#endif /* STREAMING */
- }
-#endif /* WHATAMI */
-
- if (biggest > y+8) { /* Get WHOAREYOU info if any */
- int x, z;
- x = xunchar(s[y+9]); /* Length of it */
- z = y;
- y += (9 + x);
- debug(F101,"spar sysindex x","",x);
- debug(F101,"spar sysindex y","",y);
- debug(F101,"spar sysindex biggest","",biggest);
-
- if (x > 0 && x < 16 && biggest >= y) {
- strncpy(whoareu,(char *)s+z+10,x); /* Other Kermit's system ID */
- debug(F111,"spar whoareyou",whoareu,whoareu[0]);
- if (whoareu[0]) { /* Got one? */
- sysindex = getsysix((char *)whoareu);
- debug(F101,"spar sysindex",whoareu,sysindex);
- }
- }
- } else
- goto xspar;
-
-#ifdef WHATAMI
- y++; /* Advance pointer */
- if (biggest >= y) {
- whatru2 = xunchar(s[y]); /* Next field is WHATAMI2 */
- debug(F101,"spar whatru2","",whatru2);
- if (whatru2 & WMI2_FLAG) { /* Valid only if this bit is set */
- if (server) { /* Server obeys client's xfer mode */
- xfermode = (whatru2 & WMI2_XMODE) ? XMODE_M : XMODE_A;
- debug(F101,"spar whatru2 xfermode","",xfermode);
- }
- if (whatru2 & WMI2_RECU) { /* RECURSIVE transfer */
- if (fnrpath == PATH_AUTO) { /* If REC PATH AUTO */
- fnrpath = PATH_REL; /* Set it to RELATIVE */
- autopath = 1; /* and remember we did this */
- }
- }
- }
- }
-#endif /* WHATAMI */
-
- xspar:
- if (sysindex > -1) {
- char * p;
- p = sysidlist[sysindex].sid_name;
- tlog(F110,"Remote system type: ",p,0L);
- if (sysindex > 0) { /* If partnet's system type known */
- whoarewe(); /* see if we are a match. */
-#ifdef CK_SPEED
-/* Never unprefix XON and XOFF when sending to VMS */
- debug(F111,"proto whoareu",whoareu,sysindex);
- if (!strcmp((char *)whoareu,"D7")) {
- debug(F111,"proto special VMS prefixing","",0);
- ctlp[XON] = ctlp[XOFF] = 1;
- ctlp[XON+128] = ctlp[XOFF+128] = 1;
- ctlp[3] = 1; /* Ctrl-C might be dangerous too */
- ctlp[14] = ctlp[15] = 1; /* And SO/SI */
- ctlp[24] = ctlp[25] = 1; /* And ^X/^Y */
- ctlp[141] = 1; /* And CR+128 */
- }
-#endif /* CK_SPEED */
- }
- }
-
-/* Record parameters in debug log */
-#ifdef DEBUG
- if (deblog) sdebu(biggest);
-#endif /* DEBUG */
- numerrs = 0; /* Start counting errors here. */
- return(0);
-}
-
-/* G N F I L E -- Get name of next file to send */
-/*
- Expects global sndsrc to be:
- -9: if we are generating a file internally for calibration.
- -1: next filename to be obtained by calling znext().
- 0: no next file name
- 1: (or greater) next filename to be obtained from **cmlist,
- or if addlist != 0, from the "filehead" linked list,
- or if filefile pointer not null from that file (which is already open).
- Returns:
- 1, with name of next file in filnam.
- 0, no more files, with filnam set to empty string.
- -1, file not found
- -2, file is not readable (but then we just skip to the next one if any)
- -3, read access denied
- -4, cancelled
- -5, too many files match wildcard
- -6, no files selected
- NOTE:
- If gnfile() returns 0, then the global variable gnferror should be checked
- to find out the most recent gnfile() error, and use that instead of the
- return code (for reasons to hard to explain).
-*/
-int
-gnfile() {
- int i = 0, x = 0;
- CK_OFF_T filesize = 0;
- int dodirstoo = 0;
- int retcode = 0;
-
- char fullname[CKMAXPATH+1];
-
- dodirstoo = ((what & (W_FTP|W_SEND)) == (W_FTP|W_SEND)) && recursive;
-
- debug(F101,"gnfile sndsrc","",sndsrc);
- debug(F101,"gnfile filcnt","",filcnt);
- debug(F101,"gnfile what","",what);
- debug(F101,"gnfile recursive","",recursive);
- debug(F101,"gnfile dodirstoo","",dodirstoo);
- gnferror = 0;
- fsize = (CK_OFF_T)-1; /* Initialize file size */
- fullname[0] = NUL;
-
-#ifdef VMS
- /*
- In VMS, zopeni() sets binary 0/1 automatically from the file
- attributes. Don't undo it here.
- */
- debug(F101,"gnfile VMS binary","",binary);
-#else /* VMS */
- if (!(what & W_REMO) && (xfermode == XMODE_A)
-#ifndef NOMSEND
- && !addlist
-#endif /* NOMSEND */
- ) {
- extern int stdinf;
- if (!stdinf) /* Not if sending from stdin */
-#ifdef WHATAMI
- /* We don't do this in server mode because it undoes WHATAMI */
- if (!server || (server && ((whatru & WMI_FLAG) == 0)))
-#endif /* WHATAMI */
- binary = gnf_binary; /* Restore prevailing transfer mode */
- debug(F101,"gnfile binary = gnf_binary","",gnf_binary);
- }
-#endif /* VMS */
-
-#ifdef PIPESEND
- debug(F101,"gnfile pipesend","",pipesend);
- if (pipesend) { /* First one */
- if (filcnt == 0) {
- ckstrncpy(filnam,cmarg,CKMAXPATH+1);
- return(1);
- } else { /* There's only one... */
- *filnam = NUL;
- pipesend = 0;
- return(0);
- }
- }
-#endif /* PIPESEND */
-
-#ifdef CALIBRATE
- if (sndsrc == -9) {
- debug(F100,"gnfile calibrate","",0);
- ckstrncpy(filnam,"CALIBRATION",CKMAXPATH);
- nfils = 0;
- cal_j = 0;
- fsize = calibrate;
- sndsrc = 0; /* For next time */
- nfils = 0;
- return(1);
- }
-#endif /* CALIBRATE */
-
-#ifndef NOSPL
- if (sndarray) { /* Sending from an array */
- extern char sndxnam[]; /* Pseudo filename */
- debug(F100,"gnfile array","",0);
- nfils = 0;
- fsize = (CK_OFF_T)-1; /* Size unknown */
- sndsrc = 0;
- ckstrncpy(filnam,sndxnam,CKMAXPATH);
- return(1);
- }
-#endif /* NOSPL */
-
- if (sndsrc == 0) { /* It's not really a file */
- if (nfils > 0) { /* It's a pipe, or stdin */
- ckstrncpy(filnam,*cmlist,CKMAXPATH+1); /* Copy its "name" */
- nfils = 0; /* There is no next file */
- return(1); /* OK this time */
- } else return(0); /* but not next time */
- }
-
-/* If file group interruption (C-Z) occurred, fail. */
-
- if (czseen) {
- tlog(F100,"Transaction cancelled","",0L);
- debug(F100,"gnfile czseen","",0);
- return(-4);
- }
-
-/* Loop through file list till we find a readable, sendable file */
-
- filesize = (CK_OFF_T)-1; /* Loop exit (file size) variable */
- while (filesize < 0) { /* Keep trying till we get one... */
- retcode = 0;
- if (sndsrc > 0) { /* File list in cmlist or file */
- if (filefile) { /* Reading list from file... */
- if (zsinl(ZMFILE,filnam,CKMAXPATH) < 0) { /* Read a line */
- zclose(ZMFILE); /* Failed */
- debug(F110,"gnfile filefile EOF",filefile,0);
- makestr(&filefile,NULL);
- return(0);
- }
- debug(F110,"gnfile filefile filnam",filnam,0);
- }
- debug(F101,"gnfile nfils","",nfils);
- if (nfils-- > 0 || filefile) { /* Still some left? */
-#ifndef NOMSEND
- if (addlist) {
- if (filenext && filenext->fl_name) {
- ckstrncpy(filnam,filenext->fl_name,CKMAXPATH+1);
- cmarg2 =
- filenext->fl_alias ?
- filenext->fl_alias :
- "";
- binary = filenext->fl_mode;
- } else {
- printf("?Internal error expanding ADD list\n");
- return(-5);
- }
- filenext = filenext->fl_next;
- debug(F111,"gnfile addlist filnam",filnam,nfils);
- } else if (sndsrc > 0 && !filefile) {
-#endif /* NOMSEND */
- ckstrncpy(filnam,*cmlist++,CKMAXPATH+1);
- debug(F111,"gnfile cmlist filnam",filnam,nfils);
-#ifndef NOMSEND
- }
-#endif /* NOMSEND */
- i = 0;
-#ifndef NOSERVER
- debug(F101,"gnfile ngetpath","",ngetpath);
-#endif /* NOSERVER */
-nextinpath:
-#ifndef NOSERVER
- fromgetpath = 0;
- if (server && !isabsolute(filnam) && (ngetpath > i)) {
- ckstrncpy(fullname,getpath[i],CKMAXPATH+1);
- ckstrncat(fullname,filnam,CKMAXPATH);
- debug(F111,"gnfile getpath",fullname,i);
- fromgetpath = 1;
- i++;
- } else {
- i = ngetpath + 1;
-#else
- i = 1; /* ? */
-#endif /* NOSERVER */
- ckstrncpy(fullname,filnam,CKMAXPATH+1);
- debug(F110,"gnfile absolute",fullname,0);
-#ifndef NOSERVER
- }
-#endif /* NOSERVER */
- if (iswild(fullname)
-#ifdef RECURSIVE
- || recursive > 0 || !strcmp(fullname,".")
-#endif /* RECURSIVE */
- ) { /* It looks wild... */
- /* First check if a file with this name exists */
- debug(F110,"gnfile wild",fullname,0);
- if (zchki(fullname) >= 0) {
- /*
- Here we have a file whose name actually
- contains wildcard characters.
- */
- goto gotnam;
- }
-#ifdef COMMENT
- nzxopts = ZX_FILONLY; /* (was 0: 25 Jul 2001 fdc) */
-#else
- nzxopts = recursive ? 0 : ZX_FILONLY; /* 30 Jul 2001 */
-#endif /* COMMENT */
- if (nolinks) nzxopts |= ZX_NOLINKS; /* (26 Jul 2001 fdc) */
-#ifdef UNIXOROSK
- if (matchdot) nzxopts |= ZX_MATCHDOT;
-#endif /* UNIXOROSK */
- if (recursive) nzxopts |= ZX_RECURSE;
- x = nzxpand(fullname,nzxopts); /* Expand wildcards */
- debug(F101,"gnfile nzxpand","",x);
- if (x == 1) {
- int xx;
- xx = znext(fullname);
- debug(F111,"gnfile znext A",fullname,xx);
- goto gotnam;
- }
- if (x == 0) { /* None match */
-#ifndef NOSERVER
- if (server && ngetpath > i)
- goto nextinpath;
-#endif /* NOSERVER */
- retcode = -1;
- debug(F101,"gnfile gnferror A","",gnferror);
- gnferror = -1;
- continue;
- }
- if (x < 0) { /* Too many to expand */
- debug(F101,"gnfile gnferror B","",gnferror);
- gnferror = -5;
- return(-5);
- }
- sndsrc = -1; /* Change send-source to znext() */
- }
- } else { /* We're out of files. */
- debug(F111,"gnfile done",ckitoa(gnferror),nfils);
- *filnam = '\0';
- return(0);
- }
- }
-
-/* Otherwise, step to next element of internal wildcard expansion list. */
-
- if (sndsrc == -1) {
- int xx = 0;
- while (1) {
- debug(F111,"gnfile znext X",filnam,xx);
- xx = znext(filnam);
- debug(F111,"gnfile znext B",filnam,xx);
- if (!filnam[0])
- break;
- if (dodirstoo) {
- debug(F111,"gnfile FTP MPUT /RECURSIVE",filnam,xx);
- break;
- }
- if (!isdir(filnam))
- break;
- }
- debug(F111,"gnfile znext C",filnam,x);
- if (!filnam[0]) { /* If no more, */
- sndsrc = 1; /* go back to previous list */
- debug(F101,"gnfile setting sndsrc back","",sndsrc);
- continue;
- } else
- ckstrncpy(fullname,filnam,CKMAXPATH+1);
- }
-
-/* Get here with a filename. */
-
-gotnam:
- debug(F110,"gnfile fullname",fullname,0);
- if (fullname[0]) {
-#ifdef DTILDE
- char * dirp = "";
- if (fullname[0] == '~') {
- dirp = tilde_expand((char *)fullname);
- if (*dirp) ckstrncpy(fullname,dirp,CKMAXPATH+1);
- }
-#endif /* DTILDE */
- filesize = zchki(fullname); /* Check if file readable */
- debug(F111,"gnfile zchki",fullname,filesize);
- retcode = filesize; /* Possible return code */
- if (filesize == (CK_OFF_T)-2 && dodirstoo) {
- filesize = 0;
- }
- if (filesize < 0) {
- gnferror = (int)filesize;
- debug(F101,"gnfile gnferror C","",gnferror);
- }
- if (filesize == (CK_OFF_T)-1) { /* If not found */
- debug(F100,"gnfile -1","",0);
-#ifndef NOSERVER
- if (server && ngetpath > i)
- goto nextinpath;
-#endif /* NOSERVER */
- debug(F110,"gnfile skipping:",fullname,0);
- tlog(F110,fullname,": open failure - skipped",0);
- xxscreen(SCR_FN,0,0l,fullname);
- xxscreen(SCR_ST,ST_SKIP,SKP_ACC,fullname);
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,fullname,fsize,binary,1,"Skipped");
-#endif /* TLOG */
- continue;
- } else if (filesize < 0) {
- if (filesize == (CK_OFF_T)-3) { /* Exists but not readable */
- debug(F100,"gnfile -3","",0);
- filrej++; /* Count this one as not sent */
- tlog(F110,"Read access denied",fullname,0); /* Log this */
- xxscreen(SCR_FN,0,0l,fullname);
- xxscreen(SCR_ST,ST_SKIP,SKP_ACC,fullname); /* Display it */
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,fullname,fsize,binary,1,"Skipped");
-#endif /* TLOG */
- }
- continue;
- } else {
- int xx;
- fsize = filesize;
-/* +++ */
- debug(F111,"gnfile sndsmaller",ckfstoa(sndsmaller),sndsmaller);
- debug(F111,"gnfile sndlarger",ckfstoa(sndlarger),sndlarger);
- debug(F111,"gnfile (CK_OFF_T)-1",ckfstoa((CK_OFF_T)-1),(CK_OFF_T)-1);
-
- xx = fileselect(fullname,
- sndafter, sndbefore,
- sndnafter,sndnbefore,
- sndsmaller,sndlarger,
- skipbup,
- NSNDEXCEPT,sndexcept);
- debug(F111,"gnfile fileselect",fullname,xx);
- if (!xx) {
- filesize = (CK_OFF_T)-1;
- gnferror = -6;
- debug(F101,"gnfile gnferror D","",gnferror);
- continue;
- }
- ckstrncpy(filnam,fullname,CKMAXPATH+1);
- return(1);
- }
-#ifdef COMMENT
- /* This can't be right! */
- } else { /* sndsrc is 0... */
- if (!fileselect(fullname,
- sndafter, sndbefore,
- sndnafter,sndnbefore,
- sndsmaller,sndlarger,
- skipbup,
- NSNDEXCEPT,sndexcept)) {
- gnferror = -6;
- debug(F111,"gnfile fileselect",fullname,gnferror);
- filesize = (CK_OFF_T)-1;
- continue;
- }
- ckstrncpy(filnam,fullname,CKMAXPATH+1);
- return(1);
-#endif /* COMMENT */
- }
- }
- debug(F101,"gnfile result","",retcode);
- *filnam = '\0';
- return(0);
-}
-
-/*
- The following bunch of routines feed internally generated data to the server
- to send to the client in response to REMOTE commands like DIRECTORY, DELETE,
- and so on. We have to write these lines in the format appropriate to our
- platform, so they can be converted to generic (CRLF) text format by the
- packetizer.
-*/
-#ifdef UNIX
-char * endline = "\12";
-#else
-#ifdef datageneral
-char * endline = "\12";
-#else
-#ifdef MAC
-char * endline = "\15";
-#else
-#ifdef OSK
-char * endline = "\15";
-#else
-char * endline = "\15\12";
-#endif /* OSK */
-#endif /* MAC */
-#endif /* datageneral */
-#endif /* UNIX */
-
-#ifdef MAC
-#define FNCBUFL 256
-#else
-#ifdef CKSYMLINK
-#define FNCBUFL (CKMAXPATH + CKMAXPATH + 64)
-#else
-#define FNCBUFL (CKMAXPATH + 64)
-#endif /* CKSYMLINK */
-#endif /* MAC */
-
-/* NB: The minimum FNCBUFL is 255 */
-
-static CHAR funcbuf[FNCBUFL];
-static int funcnxt = 0;
-static int funclen = 0;
-static int nxpnd = -1;
-static long ndirs = 0;
-static long nfiles = 0;
-static CK_OFF_T nbytes = 0;
-
-int
-sndstring(p) char * p; {
-#ifndef NOSERVER
- nfils = 0; /* No files, no lists. */
- xflg = 1; /* Flag we must send X packet. */
- ckstrncpy(cmdstr,versio,CMDSTRL); /* Data for X packet. */
- first = 1; /* Init getchx lookahead */
- memstr = 1; /* Just set the flag. */
- memptr = p; /* And the pointer. */
- binary = XYFT_T; /* Text mode for this. */
- return(sinit());
-#else
- return(0);
-#endif /* NOSERVER */
-}
-
-/* S N D H L P -- Routine to send builtin help */
-
-static int srvhlpnum = 0;
-
-#ifdef IKSD
-static char *nmx[] = { "Disabled", "Disabled", "Enabled", "Enabled" };
-#endif /* IKSD */
-
-static char *
-xnm(x) int x; {
-#ifdef IKSD
- if (inserver)
- return(nmx[x]);
- else
-#endif /* IKSD */
- return(nm[x]);
-}
-
-static int
-nxthlp(
-#ifdef CK_ANSIC
- void
-#endif /* CK_ANSIC */
- ) {
- int x = 0;
- extern int
- en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai,
- en_pri, en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who,
- /* en_ret, */ en_mkd, en_rmd, en_asg, en_que, en_xit, x_login, x_logged,
- xfinish;
- extern char * ckxsys;
-
- if (funcnxt < funclen)
- return (funcbuf[funcnxt++]);
-
- switch (srvhlpnum++) {
- case 0:
- x = ckstrncpy((char *)funcbuf,
- "Client Command Status Description\n",
- FNCBUFL
- );
- if (x_login && !x_logged) {
- x += ckstrncat((char *)funcbuf,
- " REMOTE LOGIN required\n",
- FNCBUFL
- );
- }
- if (FNCBUFL - x > 74)
- sprintf((char *)(funcbuf+x)," GET %-14s%s\n",
- xnm(en_get),
- "Transfer file(s) from server to client."
- );
- break;
-
-/* NOTE: The minimum funcbuf[] size is 255; all of the following are safe. */
-
- case 1:
- sprintf((char *)funcbuf," SEND %-14s%s\n",
- xnm(en_sen),
- "Transfer file(s) from client to server."
- );
- break;
-
- case 2:
- sprintf((char *)funcbuf," MAIL %-14s%s\n",
- xnm(inserver ? 0 : en_mai),
- "Send file(s) as e-mail."
- );
- break;
-
- case 3:
-#ifndef NOSPL
- sprintf((char *)funcbuf," REMOTE ASSIGN %-14s%s\n",
- xnm(en_asg),
- "Assign value to server variable or macro."
- );
-#else
- sprintf((char *)funcbuf," REMOTE ASSIGN not configured\n");
-#endif /* NOSPL */
-
- break;
- case 4:
- sprintf((char *)funcbuf," REMOTE CD %-14s%s\n",
- xnm(en_cwd),
- "Change server's directory."
- );
- break;
-
- case 5:
-#ifdef ZCOPY
- sprintf((char *)funcbuf," REMOTE COPY %-14s%s\n",
- xnm(en_cpy),
- "Copy a file on the server."
- );
-#else
- sprintf((char *)funcbuf," REMOTE COPY not configured\n");
-#endif /* ZCOPY */
-
- break;
- case 6:
- sprintf((char *)funcbuf," REMOTE DELETE %-14s%s\n",
- xnm(en_del),
- "Delete a file on the server."
- );
- break;
-
- case 7:
- sprintf((char *)funcbuf," REMOTE DIRECTORY %-14s%s\n",
- xnm(en_dir),
- "List files on the server."
- );
- break;
-
- case 8:
- sprintf((char *)funcbuf," REMOTE EXIT %-14s%s\n",
- xnm(en_xit),
- "Exit from Kermit server program."
- );
- break;
-
- case 9:
- sprintf((char *)funcbuf," REMOTE HOST %-14s%s\n",
- xnm(inserver ? 0 : en_hos),
-#ifdef datageneral
- "Execute a CLI command on the server."
-#else
-#ifdef VMS
- "Execute a DCL command on the server."
-#else
- "Execute a shell command on the server."
-#endif /* VMS */
-#endif /* datageneral */
- );
- break;
-
- case 10:
- sprintf((char *)funcbuf," REMOTE PRINT %-14s%s\n",
- xnm(inserver ? 0 : en_pri),
- "Send a file to the server for printing."
- );
- break;
-
- case 11:
-#ifndef NOSPL
- sprintf((char *)funcbuf," REMOTE QUERY %-14s%s\n",
- xnm(en_que),
- "Get value of server variable or macro."
- );
-
-#else
- sprintf((char *)funcbuf," REMOTE QUERY not configured\n");
-#endif /* NOSPL */
-
- break;
- case 12:
- sprintf((char *)funcbuf," REMOTE MKDIR %-14s%s\n",
- xnm(en_mkd),
- "Create a directory on the server."
- );
- break;
-
- case 13:
- sprintf((char *)funcbuf," REMOTE RMDIR %-14s%s\n",
- xnm(en_rmd),
- "Remove a directory on the server."
- );
- break;
-
- case 14:
- sprintf((char *)funcbuf," REMOTE RENAME %-14s%s\n",
- xnm(en_ren),
- "Rename a file on the server."
- );
- break;
-
- case 15:
- sprintf((char *)funcbuf," REMOTE SET %-14s%s\n",
- xnm(en_set),
- "Set a parameter on the server"
- );
- break;
-
- case 16:
- sprintf((char *)funcbuf," REMOTE SPACE %-14s%s\n",
- xnm(en_spa),
- "Inquire about disk space on the server."
- );
- break;
-
- case 17:
- sprintf((char *)funcbuf," REMOTE TYPE %-14s%s\n",
- xnm(en_typ),
- "Display a server file on your screen."
- );
- break;
-
- case 18:
- sprintf((char *)funcbuf," REMOTE WHO %-14s%s\n",
- xnm(inserver ? 0 : en_who),
- "List who is logged in to the server."
- );
- break;
-
- case 19:
- sprintf((char *)funcbuf," FINISH %-14s%s\n",
- xnm(en_fin),
- xfinish ?
- "Exit from Kermit server program." :
- "Return the server to its command prompt."
- );
- break;
-
- case 20:
- sprintf((char *)funcbuf," BYE %-14s%s\n\n",
- xnm(en_bye),
- "Log the server out and disconnect."
- );
- break;
-
- default:
- return(-1);
- }
- funcnxt = 0;
- funclen = strlen((char *)funcbuf);
- return(funcbuf[funcnxt++]);
-}
-
-int
-sndhlp() {
-#ifndef NOSERVER
- extern char * ckxsys;
-
- first = 1; /* Init getchx lookahead */
- nfils = 0; /* No files, no lists. */
- xflg = 1; /* Flag we must send X packet. */
- ckstrncpy(cmdstr,"REMOTE HELP",CMDSTRL); /* Data for X packet. */
- sprintf((char *)funcbuf, "C-Kermit %s,%s\n\n", versio, ckxsys);
- funclen = strlen((char *)funcbuf);
-#ifdef IKSD
- if (inserver) {
- sprintf((char *)(funcbuf+funclen),
- "Internet Kermit Service (EXPERIMENTAL)\n\n");
- funclen = strlen((char *)funcbuf);
- }
-#endif /* IKSD */
- funcnxt = 0;
- funcptr = nxthlp;
- funcstr = 1;
- srvhlpnum = 0;
- binary = XYFT_T; /* Text mode for this. */
- return(sinit());
-#else
- return(0);
-#endif /* NOSERVER */
-}
-
-/*
- Returns the next available character,
- -1 if no more data.
-*/
-static int
-nxttype(
-#ifdef CK_ANSIC
- void
-#endif /* CK_ANSIC */
- ) {
- int c;
- if (zchin(ZIFILE,&c) < 0) {
- zclose(ZIFILE);
- return(-1);
- } else {
- return((unsigned)c);
- }
-}
-
-/* S N D T Y P -- TYPE a file to remote client */
-
-int
-sndtype(file) char * file; {
-#ifndef NOSERVER
- char name[CKMAXPATH+1];
-
-#ifdef OS2
- char * p = NULL;
-
- if (*file) {
- ckstrncpy(name, file, CKMAXPATH+1);
- /* change / to \. */
- p = name;
- while (*p) { /* Change them back to \ */
- if (*p == '/') *p = '\\';
- p++;
- }
- } else
- return(0);
-#else
- ckstrncpy(name, file, CKMAXPATH+1);
-#endif /* OS2 */
-
- funcnxt = 0;
- funclen = strlen((char *)funcbuf);
- if (zchki(name) == -2) {
- /* Found a directory */
- return(0);
- }
- if (!zopeni(ZIFILE,name))
- return(0);
-
- nfils = 0; /* No files, no lists. */
- xflg = 1; /* Flag we must send X packet. */
- ckstrncpy(cmdstr,"type",CMDSTRL); /* Data for X packet. */
- first = 1; /* Init getchx lookahead */
- funcstr = 1; /* Just set the flag. */
- funcptr = nxttype; /* And the pointer. */
- binary = XYFT_T; /* Text mode for this */
- return(sinit());
-#else
- return(0);
-#endif /* NOSERVER */
-}
-
-/*
- N X T D I R -- Provide data for senddir()
-
- Returns the next available character or -1 if no more data.
-*/
-#ifndef NOICP
-/* Directory listing parameters set by the user interface, if any. */
-extern int dir_head, dir_dots, dir_back;
-#endif /* NOICP */
-static int sd_hdg, sd_bkp, sd_dot; /* Local listing parameters */
-
-static int
-nxtdir(
-#ifdef CK_ANSIC
- void
-#endif /* CK_ANSIC */
- ) {
- char name[CKMAXPATH+1], dbuf[24], *p = NULL;
- char *dstr = NULL, * lnk = "";
- CHAR c, * linebuf = funcbuf;
-#ifdef OSK
- /* Work around bugs in OSK compiler */
- char *dirtag = "directories";
- char *filetag = "files";
- char *bytetag = "bytes";
-#endif /* OSK */
- CK_OFF_T len = 0;
- int x, itsadir = 0, gotone = 0;
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"nxtdir funcnxt","",funcnxt);
- debug(F101,"nxtdir funclen","",funclen);
- debug(F110,"nxtdir funcbuf",funcbuf+funcnxt,0);
- }
-#endif /* DEBUG */
- if (funcnxt < funclen) { /* Return next character from buffer */
- c = funcbuf[funcnxt++];
- debug(F000,"nxtdir return 1","",(unsigned)(c & 0xff));
- return((unsigned)(c & 0xff));
- }
- while (nxpnd > 0) { /* Buffer needs refill */
- nxpnd--;
- znext(name); /* Get next filename */
- if (!name[0]) { /* None left - done */
- nxpnd = 0;
- return(nxtdir());
- }
- if (sd_bkp) { /* Showing backup files? */
- gotone = 1; /* Yes, no need to check. */
- break;
- }
- x = ckmatch( /* No - see if this is one */
-#ifdef CKREGEX
- "*.~[0-9]*~" /* Not perfect but close enough. */
-#else
- "*.~*~" /* Less close. */
-#endif /* CKREGEX */
- ,name,filecase,1);
- debug(F111,"nxtdir ckmatch",name,x);
- if (x) {
- continue; /* It's a backup file - skip it */
- } else {
- gotone = 1; /* It's not, break from loop. */
- break;
- }
- }
- if (gotone) {
- len = zgetfs(name); /* Get file size */
- debug(F111,"nxtdir zgetfs",name,len);
-#ifdef VMSORUNIX
- itsadir = zgfs_dir; /* See if it's a directory */
-#else
- itsadir = (len == -2 || isdir(name));
-#endif /* VMSORUNIX */
- dstr = zfcdat(name);
- debug(F111,"nxtdir zcfdat",dstr,0);
- if (!dstr)
- dstr = "0000-00-00 00:00:00";
- if (!*dstr) {
- dstr = "0000-00-00 00:00:00";
- } else {
- dbuf[0] = dstr[0];
- dbuf[1] = dstr[1];
- dbuf[2] = dstr[2];
- dbuf[3] = dstr[3];
- dbuf[4] = '-';
- dbuf[5] = dstr[4];
- dbuf[6] = dstr[5];
- dbuf[7] = '-';
- dbuf[8] = dstr[6];
- dbuf[9] = dstr[7];
- strcpy(dbuf+10,dstr+8);
- dstr = dbuf;
- }
-#ifdef CK_PERMS
-#ifdef VMSORUNIX
- p = ziperm(name); /* Get permissions */
-#else
- p = zgperm(name);
-#endif /* VMSORUNIX */
-#else
- p = NULL;
-#endif /* CK_PERMS */
- debug(F110,"domydir perms",p,0);
-
-#ifdef VMS
- /* Make name relative */
- ckstrncpy(name,zrelname(name,zgtdir()),CKMAXPATH+1);
-#endif /* VMS */
-
- if (itsadir) {
- ndirs++;
- } else {
- nfiles++;
- nbytes += len;
- }
- lnk = "";
-#ifdef UNIX
-#ifdef CKSYMLINK
- if (zgfs_link) {
- extern char linkname[];
- lnk = linkname;
- }
- debug(F111,"nxtdir linkname",lnk,zgfs_link);
-#endif /* CKSYMLINK */
-#endif /* UNIX */
-
-/*
- The following sprintf's are safe; linebuf is a pointer to funcbuf,
- which is 64 bytes larger than CKMAXPATH (or double CKMAXPATH when
- symlinks are possible). 64 allows for the fixed-field portions of
- the file listing line: permissions, size, and date. CKMAXPATH allows
- for the longest possible pathname.
-*/
- if (itsadir && len < 0) { /* Directory */
-#ifdef VMS
- sprintf((char *)linebuf,
- "%-22s%-10s %s %s\n",p,"<DIR>",dstr,name);
-#else
- if (p)
- sprintf((char *)linebuf,
- "%10s%-10s %s %s\n",p,"<DIR>",dstr,name);
- else
- sprintf((char *)linebuf,
- "%-10s %s %s\n", "<DIR>", dstr, name);
-#endif /* VMS */
- } else { /* Regular file */
-#ifdef VMS
- sprintf((char *)linebuf,
- "%-22s%10s %s %s\n", p, ckfstoa(len), dstr, name);
-#else
- if (p)
- sprintf((char *)linebuf,
- "%10s%10s %s %s%s%s\n",
- p, ckfstoa(len), dstr, name,
- *lnk ? " -> " : "",
- lnk
- );
- else
- sprintf((char *)linebuf,
- "%10s %s %s%s%s\n",
- ckfstoa(len), dstr, name,
- *lnk ? " -> " : "",
- lnk
- );
-#endif /* VMS */
- }
- funcnxt = 0;
- funclen = strlen((char *)funcbuf);
- } else if (sd_hdg && nxpnd == 0) { /* Done, send summary */
- char *blankline = ""; /* At beginning of summary */
-/*
- The idea is to prevent (a) unnecessary multiple blanklines, and (b)
- prompt-stomping. Preventing (b) is practically impossible, because it
- depends on the client so for now always include that final CRLF.
-*/
- if (!ndirs || !nbytes || !nfiles)
- blankline = endline;
-#ifdef OSK
-/* Workaround bugs in OS-9 compiler... */
- if (ndirs == 1)
- dirtag = "directory";
- if (nfiles == 1)
- filetag = "file";
- if (nbytes == (CK_OFF_T)1)
- bytetag = "byte";
- sprintf((char *)funcbuf,
- "%sSummary: %ld %s, %ld %s, %s %s%s",
- blankline,
- ndirs,
- dirtag,
- nfiles,
- filetag,
- ckfstoa(nbytes),
- bytetag,
- endline);
-#else
- sprintf((char *)funcbuf,
- "%sSummary: %ld director%s, %ld file%s, %s byte%s%s",
- blankline,
- ndirs,
- (ndirs == 1) ? "y" : "ies",
- nfiles,
- (nfiles == 1) ? "" : "s",
- ckfstoa(nbytes),
- (nbytes == (CK_OFF_T)1) ? "" : "s",
- endline
- );
-#endif /* OSK */
- nxpnd--;
- funcnxt = 0;
- funclen = strlen((char *)funcbuf);
- } else {
- funcbuf[0] = '\0';
- funcnxt = 0;
- funclen = 0;
- }
- debug(F101,"nxtdir funclen","",funclen);
-
- if (funcnxt < funclen) { /* If we have data to send... */
- c = funcbuf[funcnxt++];
- debug(F000,"nxtdir return 2","",(unsigned)(c & 0xff));
- return((unsigned)(c & 0xff));
- } else
- return(-1); /* Nothing left, done. */
-}
-
-/* S N D D I R -- send directory listing */
-
-int
-snddir(spec) char * spec; {
-#ifndef NOSERVER
- char * p = NULL, name[CKMAXPATH+1];
- int t = 0, rc = 0;
- char fnbuf[CKMAXPATH+1];
-
- debug(F111,"snddir matchdot",spec,matchdot);
-
-#ifndef NOICP
- debug(F111,"snddir dir_dots",spec,dir_dots);
- sd_hdg = dir_head > 0; /* Import listing parameters if any */
- sd_bkp = dir_back > 0;
- if (dir_dots > -1)
- sd_dot = dir_dots;
- else
- sd_dot = matchdot;
-#else
- sd_hdg = 1; /* Or use hardwired defaults */
- sd_bkp = 1;
- sd_dot = matchdot;
-#endif /* NOICP */
-
- if (!spec) spec = "";
- debug(F111,"snddir sd_dot",spec,sd_dot);
- if (*spec) {
-#ifdef COMMENT
- zfnqfp(spec,CKMAXPATH,name);
- debug(F110,"snddir zfnqfp",name,0);
-#else
- ckstrncpy(name,spec,CKMAXPATH+1);
- debug(F110,"snddir name",name,0);
-#endif /* COMMENT */
- } else {
-#ifdef OS2
- strcpy(name, "*");
-#else
-#ifdef UNIXOROSK
- strcpy(name, "./*");
-#else
-#ifdef VMS
- strcpy(name, "*.*");
-#else
-#ifdef datageneral
- strcpy(name, "+");
-#else
- debug(F101,"snddir quit (no filespec)","",0);
- return(0);
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* OS2 */
- }
- debug(F110,"snddir name 1",name,0);
- ndirs = 0L;
- nfiles = 0L;
- nbytes = (CK_OFF_T)0;
-
- if (zfnqfp(name,CKMAXPATH,fnbuf))
-
- debug(F110,"snddir name 2",name,0);
- p = name + strlen(name); /* Move it to end of list */
-
- /* sprintf safe because funcbuf size >= max path len + 64 */
-
- if (sd_hdg) {
- sprintf((char *)funcbuf,"Listing files: %s%s%s",fnbuf,endline,endline);
- funcnxt = 0;
- funclen = strlen((char *)funcbuf);
- }
- diractive = 1;
-
-#ifdef OS2
- if (zchki(name) == -2) { /* Found a directory */
- p--;
- if (*p == '\\' || *p == '/')
- ckstrncat(name, "*", CKMAXPATH);
- else if (*p == ':')
- ckstrncat(name, ".", CKMAXPATH);
- else
- ckstrncat(name, "\\*", CKMAXPATH);
- debug(F110,"snddir directory",name,0);
- }
-#else
- if (!iswild(name) && isdir(name)) {
- char * s = name;
- p--;
-#ifdef UNIXOROSK
- if (*p == '/') /* So append wildcard to it */
- ckstrncat(s, "*", CKMAXPATH);
- else
- ckstrncat(s, "/*", CKMAXPATH);
-#else
-#ifdef VMS
- if (*p == ']' || *p == '>' || *p == ':')
- ckstrncat(s, "*.*", CKMAXPATH);
-#else
-#ifdef datageneral
- if (*p == ':')
- ckstrncat(s, "+", CKMAXPATH);
- else
- ckstrncat(s, ":+", CKMAXPATH);
-#else
-#ifdef VOS
- if (*p == '>')
- ckstrncat(s, "*", CKMAXPATH);
- else
- ckstrncat(s, ">*", CKMAXPATH);
-#endif /* VOS */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* UNIXOROSK */
- debug(F110,"snddir directory",name,0);
- }
-#endif /* OS2 */
-
- nzxopts = 0;
-#ifdef UNIX
- {
- extern char ** mtchs;
- debug(F111,"snddir sd_dot",spec,sd_dot);
- if (sd_dot > 0)
- nzxopts |= ZX_MATCHDOT;
- if (recursive)
- nzxopts |= ZX_RECURSE;
- debug(F111,"snddir nzxopts",spec,nzxopts);
- nxpnd = nzxpand(name,nzxopts); /* Get the array of names */
- sh_sort(mtchs,NULL,nxpnd,0,0,1); /* Sort the array */
- }
-#else
- if (recursive) nzxopts |= ZX_RECURSE;
- nxpnd = nzxpand(name,nzxopts);
-#endif /* UNIX */
-
- debug(F101,"snddir nzxpand nxpnd","",nxpnd);
- if (nxpnd < 1)
- return(-1);
- nfils = 0; /* No files, no lists. */
- xflg = 1; /* Flag we must send X packet. */
- if ((int)strlen(name) < CMDSTRL - 11) /* Data for X packet. */
- sprintf(cmdstr,"DIRECTORY %s",name); /* safe */
- else
- ckstrncpy(cmdstr,"DIRECTORY",CMDSTRL);
- first = 1; /* Init getchx lookahead */
- funcstr = 1; /* Just set the flag. */
- funcptr = nxtdir; /* And the pointer. */
- binary = XYFT_T; /* Text mode for this */
- rc = sinit(); /* 26 Aug 2005 */
- debug(F111,"snddir","sinit()",rc);
- return(rc);
-#else
- return(0);
-#endif /* NOSERVER */
-}
-
-/* N X T D E L -- provide data for delete */
-
-/* Returns the next available character or -1 if no more data */
-
-static int
-nxtdel(
-#ifdef CK_ANSIC
- void
-#endif /* CK_ANSIC */
- ) {
- char name[257], *p = NULL;
- int len = 0;
-
- if (funcnxt < funclen)
- return ((unsigned)funcbuf[funcnxt++]);
-
- if (nxpnd > 0) {
- nxpnd--;
- znext(name);
- if (!name[0]) {
- nxpnd = 0;
- return(nxtdel());
- }
- len = zchki(name);
-
- /* Find just the name of the file */
-
- for (p = name + strlen(name); p != name && *p != '/' ; p--) ;
- if (*p == '/') p++;
-
- /* sprintf's safe because size of funcbuf >= 64 + maxpathlen */
-
- if (len > -1L) {
- if (zdelet(name)) {
- sprintf((char *)funcbuf," %10s: %s%s","skipping",p,endline);
- } else {
- nfiles++;
- nbytes += len;
- sprintf((char *)funcbuf," %10s: %s%s","deleted",p,endline);
- }
- } else
- sprintf((char *)funcbuf," directory: %s%s", p, endline);
- funcnxt = 0;
- funclen = strlen((char *)funcbuf);
- } else
-
- /* If done processing the expanded entries send a summary statement */
-
- if (nxpnd == 0) {
- sprintf((char *)funcbuf,
- "%s%ld file%s deleted, %s byte%s freed%s",
- endline,
- nfiles,
- (nfiles == 1) ? "" : "s",
- ckfstoa(nbytes),
- (nbytes == (CK_OFF_T)1) ? "" : "s",
- endline
- );
- nxpnd--;
- funcnxt = 0;
- funclen = strlen((char *)funcbuf);
- } else {
- funcbuf[0] = '\0';
- funcnxt = 0;
- funclen = 0;
- }
-
- /* If we have data to send */
-
- if (funcnxt < funclen)
- return ((unsigned)funcbuf[funcnxt++]); /* Return a character */
- else
- return(-1); /* No more input */
-}
-
-/* S N D D E L -- Send delete message */
-
-int
-snddel(spec) char * spec; {
-#ifndef NOSERVER
- char name[CKMAXPATH+1];
-#ifdef OS2
- char * p = NULL;
-#endif /* #ifdef OS2 */
-
- if (!*spec)
- return(0);
-
- ckstrncpy(name, spec, CKMAXPATH+1);
-
-#ifdef OS2
- /* change / to \. */
- p = name;
- while (*p) { /* Change them back to \ */
- if (*p == '/') *p = '\\';
- p++;
- }
-#endif /* OS2 */
-
- nfiles = 0L;
- nbytes = (CK_OFF_T)0;
- sprintf((char *)funcbuf,"Deleting \"%s\"%s",name,endline);
- funcnxt = 0;
- funclen = strlen((char *)funcbuf);
-
- nzxopts = ZX_FILONLY; /* Files only */
-#ifdef UNIXOROSK
- if (matchdot) nzxopts |= ZX_MATCHDOT;
-#endif /* UNIXOROSK */
-#ifdef COMMENT
- /* Recursive deleting not supported yet */
- if (recursive) nzxopts |= ZX_RECURSE;
-#endif /* COMMENT */
- nxpnd = nzxpand(name,nzxopts);
- if (nxpnd < 1)
- return(-1);
- nfils = 0; /* No files, no lists. */
- xflg = 1; /* Flag we must send X packet. */
- ckstrncpy(cmdstr,"REMOTE DELETE",CMDSTRL); /* Data for X packet. */
- first = 1; /* Init getchx lookahead */
- funcstr = 1; /* Just set the flag. */
- funcptr = nxtdel; /* And the pointer. */
- binary = XYFT_T; /* Use text mode for this, */
- return(sinit());
-#else
- return(0);
-#endif /* NOSERVER */
-}
-
-#ifdef OS2
-/* S N D S P A C E -- send disk space message */
-int
-sndspace(drive) int drive; {
-#ifndef NOSERVER
- static char spctext[64];
- unsigned long space;
-
- if (drive) {
- space = zdskspace(drive - 'A' + 1);
- if (space > 0 && space < 1024)
- sprintf(spctext,
- " Drive %c: unknown%s",
- drive,
- endline
- );
- else
- sprintf(spctext,
- " Drive %c: %ldK free%s",
- drive,
- space / 1024L,
- endline
- );
- } else {
- space = zdskspace(0);
- if (space > 0 && space < 1024)
- sprintf(spctext, " Free space: unknown%s", endline);
- else
- sprintf(spctext, " Free space: %ldK%s", space / 1024L, endline);
- }
- nfils = 0; /* No files, no lists. */
- xflg = 1; /* Flag we must send X packet. */
- ckstrncpy(cmdstr,"free space",CMDSTRL); /* Data for X packet. */
- first = 1; /* Init getchx lookahead */
- memstr = 1; /* Just set the flag. */
- memptr = spctext; /* And the pointer. */
- binary = XYFT_T; /* Text mode for this. */
- return(sinit());
-#else
- return(0);
-#endif /* NOSERVER */
-}
-
-/* S N D W H O -- send who message */
-int
-sndwho(who) char * who; {
-#ifndef NOSERVER
- nfils = 0; /* No files, no lists. */
- xflg = 1; /* Flag we must send X packet. */
- ckstrncpy(cmdstr,"who",CMDSTRL); /* Data for X packet. */
- first = 1; /* Init getchx lookahead */
- memstr = 1; /* Just set the flag. */
-#ifdef NT
- memptr = "\15\12K95 SERVER\15\12"; /* And the pointer. */
-#else
- memptr = "\15\12K/2 SERVER\15\12";
-#endif /* NT */
- binary = XYFT_T; /* Use text mode */
- return(sinit());
-#else
- return(0);
-#endif /* NOSERVER */
-}
-#endif /* OS2 */
-
-/* C W D -- Change server's working directory */
-
-/*
- String passed has first byte as length of directory name, rest of string
- is name. Returns:
- 0 on failure.
- 1 on success after sending short-form response (ACK with name).
- 2 on success if a CD Message file is to be sent.
-*/
-int
-cwd(vdir) char *vdir; {
- char *cdd, *dirp;
-
- vdir[xunchar(*vdir) + 1] = '\0'; /* Terminate string with a null */
- dirp = vdir+1;
- tlog(F110,"Directory requested: ",dirp,0L);
- if (zchdir(dirp)) { /* Try to change */
- cdd = zgtdir(); /* Get new working directory. */
- debug(F110,"cwd",cdd,0);
- if (srvcdmsg) { /* Send orientation file? */
- int i;
- for (i = 0; i < 8; i++) {
- if (zchki(cdmsgfile[i]) > -1) {
- xxscreen(SCR_CD,0,0l,cdd);
- tlog(F110,"Changed directory to",cdd,0L);
- return(2);
- }
- }
- }
- encstr((CHAR *)cdd); /* Send short-form reply */
- ack1(data); /* containing directory name. */
- xxscreen(SCR_CD,0,0l,cdd);
- tlog(F110,"Changed directory to",cdd,0L);
- return(1);
- } else {
- debug(F110,"cwd failed",dirp,0);
- tlog(F110,"Failed to change directory to",dirp,0L);
- return(0);
- }
-}
-
-
-/* S Y S C M D -- Do a system command */
-
-/* Command string is formed by concatenating the two arguments. */
-
-int
-syscmd(prefix,suffix) char *prefix, *suffix; {
- extern int i_isopen;
-#ifndef NOPUSH
- char *cp;
-
- i_isopen = 0;
- if (!prefix)
- return(0);
- if (!*prefix)
- return(0);
- for (cp = cmdstr; *prefix != '\0'; (*cp++ = *prefix++));
- while ((*cp++ = *suffix++))
-#ifdef OS2
- /* This takes away more than we gain in convenience
- if (*(cp-1) == '/') *(cp-1) = '\\' */
-#endif /* OS2 */
- ; /* Copy suffix */
-
- debug(F110,"syscmd",cmdstr,0);
-
- if (zxcmd(ZIFILE,cmdstr) > 0) {
- debug(F110,"syscmd zxcmd ok",cmdstr,0);
- nfils = sndsrc = 0; /* Flag that input is from stdin */
- xflg = hcflg = 1; /* And special flags for pipe */
- binary = XYFT_T; /* Go to text mode */
- i_isopen = 1;
- return (sinit()); /* Send S packet */
- } else {
- debug(F100,"syscmd zxcmd failed",cmdstr,0);
- i_isopen = 0;
- return(0);
- }
-#else
- debug(F100,"syscmd zxcmd NOPUSH",cmdstr,0);
- i_isopen = 0;
- return(0);
-#endif /* NOPUSH */
-}
-
-/* R E M S E T -- Remote Set */
-/* Called by server to set variables as commanded in REMOTE SET packets. */
-/* Returns 1 on success, 0 on failure. */
-
-int
-remset(s) char *s; {
- extern int c_save, en_del;
- int len, i, x, y;
- char *p;
-
- len = xunchar(*s++); /* Length of first field */
- p = s + len; /* Pointer to second length field */
- *p++ = '\0'; /* Zero out second length field */
- x = atoi(s); /* Value of first field */
- debug(F111,"remset",s,x);
- debug(F110,"remset",p,0);
- switch (x) { /* Do the right thing */
- case 132: /* Attributes (all, in) */
- atcapr = atoi(p);
- return(1);
- case 133: /* File length attributes */
- case 233: /* IN/OUT combined */
- case 148: /* Both kinds of lengths */
- case 248:
- atleni = atleno = atoi(p);
- return(1);
- case 134: /* File Type (text/binary) */
- case 234:
- attypi = attypo = atoi(p);
- return(1);
- case 135: /* File creation date */
- case 235:
- atdati = atdato = atoi(p);
- return(1);
- case 139: /* File Blocksize */
- case 239:
- atblki = atblko = atoi(p);
- return(1);
- case 141: /* Encoding / Character Set */
- case 241:
- atenci = atenco = atoi(p);
- return(1);
- case 142: /* Disposition */
- case 242:
- atdisi = atdiso = atoi(p);
- return(1);
- case 145: /* System ID */
- case 245:
- atsidi = atsido = atoi(p);
- return(1);
- case 147: /* System-Dependent Info */
- case 247:
- atsysi = atsyso = atoi(p);
- return(1);
- case 232: /* Attributes (all, out) */
- atcapr = atoi(p);
- return(1);
- case 300: /* File type (text, binary) */
- binary = atoi(p);
- b_save = binary;
-#ifndef NOICP
- g_binary = -1;
-#endif /* NOICP */
- return(1);
- case 301: /* File name conversion */
- fncnv = 1 - atoi(p); /* (oops) */
- f_save = fncnv;
-#ifndef NOICP
- g_fncnv = -1;
-#endif /* NOICP */
- return(1);
- case 302: /* File name collision */
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest) /* May not be changed by guest */
- return(0);
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- x = atoi(p);
- if (!ENABLED(en_del) && (x == XYFX_X || x == XYFX_U))
- return(0);
- if (x == XYFX_R) ckwarn = 1; /* Rename */
- if (x == XYFX_X) ckwarn = 0; /* Replace */
- fncact = x;
- return(1);
- case 310: /* Incomplete File Disposition */
- keep = atoi(p); /* Keep, Discard, Auto */
- return(1);
- case 311: /* Blocksize */
- fblksiz = atoi(p);
- return(1);
- case 312: /* Record Length */
- frecl = atoi(p);
- return(1);
- case 313: /* Record format */
- frecfm = atoi(p);
- return(1);
- case 314: /* File organization */
- forg = atoi(p);
- return(1);
- case 315: /* File carriage control */
- fcctrl = atoi(p);
- return(1);
- case 330: /* Match dotfiles */
-#ifndef NOICP
- dir_dots = -1; /* This undoes DIR /DOT option */
-#endif /* NOICP */
- matchdot = atoi(p);
- return(1);
- case 331: /* Match FIFOs */
- matchfifo = atoi(p);
- return(1);
- case 400: /* Block check */
- y = atoi(p);
- if (y < 5 && y > 0) {
- bctr = y;
- c_save = -1;
- return(1);
- } else if (*p == 'B') {
- bctr = 4;
- c_save = -1;
- return(1);
- } else if (*p == '5') {
- bctr = 3;
- c_save = -1;
- return(1);
- }
- return(0);
- case 401: /* Receive packet-length */
- rpsiz = urpsiz = atoi(p);
- if (urpsiz > MAXRP) urpsiz = MAXRP; /* Max long-packet length */
- if (rpsiz > 94) rpsiz = 94; /* Max short-packet length */
- urpsiz = adjpkl(urpsiz,wslots,bigrbsiz);
- return(1);
- case 402: /* Receive timeout */
- y = atoi(p); /* Client is telling us */
- if (y > -1 && y < 999) { /* the timeout that it wants */
- pkttim = chktimo(y,timef); /* us to tell it to use. */
- return(1);
- } else return(0);
- case 403: /* Retry limit */
- y = atoi(p);
- if (y > -1 && y < 95) {
- maxtry = y;
- return(1);
- } else return(0);
- case 404: /* Server timeout */
- y = atoi(p);
- if (y < 0) return(0);
- srvtim = y;
- return(1);
-
-#ifndef NOCSETS
- case 405: { /* Transfer character set */
- extern int s_cset, axcset[];
- int i;
- for (i = 0; i < ntcsets; i++) {
- if (!strcmp(tcsinfo[i].designator,p)) break;
- }
- debug(F101,"remset tcharset lookup","",i);
- if (i == ntcsets) return(0);
- tcharset = tcsinfo[i].code; /* If known, use it */
- debug(F101,"remset tcharset","",tcharset);
- if (s_cset == XMODE_A)
- if (axcset[tcharset] > -1 && axcset[tcharset] > MAXFCSETS)
- fcharset = axcset[tcharset]; /* Auto-pick file charset */
- debug(F101,"remset tcharset fcharset","",fcharset);
- setxlatype(tcharset,fcharset); /* Set up charset translations */
- debug(F101,"remset xlatype","",xlatype);
- debug(F101,"remset tcharset after setxlatype","",tcharset);
- tcs_save = -1;
- return(1);
- }
- case 320: { /* File character set */
- extern struct keytab fcstab[];
- extern int nfilc, s_cset, r_cset;
- x = lookup(fcstab,p,nfilc,&y);
- debug(F111,"RSET FILE CHAR name",p,x);
- if (x < 0)
- return(0);
- s_cset = XMODE_M; /* No automatic charset switching */
- r_cset = XMODE_M;
- fcharset = x; /* Set file charset */
- setxlatype(tcharset,fcharset); /* and translation type */
- fcs_save = -1;
- return(1);
- }
-#endif /* NOCSETS */
-
- case 406: /* Window slots */
- y = atoi(p);
- if (y == 0) y = 1;
- if (y < 1 || y > MAXWS) return(0);
- wslotr = y;
- swcapr = 1;
- urpsiz = adjpkl(urpsiz,wslotr,bigrbsiz);
- return(1);
-
- case 410: /* Transfer mode */
- y = atoi(p); /* 0 = automatic, nonzero = manual */
- if (y != 0) y = 1;
- xfermode = y;
- debug(F101,"REMOTE SET xfermode","",xfermode);
- return(1);
-
- case 420: /* SERVER CD-MESSAGE { ON, OFF } */
- y = atoi(p); /* 0 = automatic, nonzero = manual */
- srvcdmsg = y;
- return(1);
-
- default: /* Anything else... */
- return(0);
- }
-}
-
-/* Adjust packet length based on number of window slots and buffer size */
-
-int
-adjpkl(pktlen,slots,bufsiz) int pktlen, slots, bufsiz; {
- if (protocol != PROTO_K) return(pktlen);
- debug(F101,"adjpkl len","",pktlen);
- debug(F101,"adjpkl slots","",slots);
- debug(F101,"adjpkl bufsiz","",bufsiz);
- if (((pktlen + 6) * slots) > bufsiz)
- pktlen = (bufsiz / slots) - 6;
- debug(F101,"adjpkl new len","",pktlen);
- return(pktlen);
-}
-
-/* Set transfer mode and file naming based on comparison of system types */
-
-
-VOID
-whoarewe() {
-#ifndef NOICP
- extern int g_xfermode;
-#endif /* NOICP */
-
- wearealike = 0;
-
- debug(F101,"whoarewe xfermode","",xfermode);
-#ifndef NOICP
- debug(F101,"whoarewe g_xfermode","",g_xfermode);
-#endif /* NOICP */
- if (whoareu[0]) { /* If we know partner's system type */
- char * p = (char *)whoareu;
- debug(F110,"whoarewe remote sysid",whoareu,0);
- if (!strcmp(p,cksysid)) /* Other system same as us */
- wearealike = 1;
-
-#ifdef UNIX
- else if (!strcmp(p,"L3")) /* UNIX is sort of like AmigaDOS */
- wearealike = 1; /* (same directory separator) */
- else if (!strcmp(p,"N3")) /* UNIX like Aegis */
- wearealike = 1;
-#else
-#ifdef AMIGA
-/* Like UNIX, but case distinctions are ignored and can begin with device:. */
- else if (!strcmp(p,"U1")) /* Amiga is sort of like UNIX */
- wearealike = 1;
- else if (!strcmp(p,"N3")) /* Amiga is sort of like Aegis */
- wearealike = 1;
-#else
-#ifdef OS2 /* (Includes Windows 95/NT) */
-
- /* DOS, GEMDOS, Windows 3.x, Windows 95, Windows NT */
- /* All "the same" for FAT partitions but all bets off otherwise */
- /* so this part needs some refinement ... */
-
- else if (!strcmp(p,"U8")) /* MS-DOS */
- wearealike = 1;
- else if (!strcmp(p,"UO")) /* OS/2 */
- wearealike = 1;
- else if (!strcmp(p,"UN")) /* Windows NT or 95 */
- wearealike = 1;
- else if (!strcmp(p,"K2")) /* GEMDOS */
- wearealike = 1;
-#else
-#ifdef GEMDOS
- else if (!strcmp(p,"U8"))
- wearealike = 1;
- else if (!strcmp(p,"UO"))
- wearealike = 1;
- else if (!strcmp(p,"UN"))
- wearealike = 1;
- else if (!strcmp(p,"K2"))
- wearealike = 1;
-#endif /* GEMDOS */
-#endif /* OS2 */
-#endif /* AMIGA */
-#endif /* UNIX */
-
- /* Get here with wearealike == 1 if system types match */
-
- debug(F101,"whoarewe wearealike","",wearealike);
- if (!wearealike) /* Not alike */
- return;
-
- fncnv = XYFN_L; /* Alike, so literal filenames */
- debug(F101,"whoarewe setting fncnv","",fncnv);
-
- if (xfermode == XMODE_A) { /* Current xfer mode is auto */
-#ifdef VMS
- binary = XYFT_L; /* For VMS-to-VMS, use labeled */
-#else
-#ifdef OS2
- /* OS/2 but not Windows */
- if (!strcmp(cksysid,"UO") && !strcmp((char *)whoareu,"UO"))
- binary = XYFT_L; /* For OS/2-to-OS/2, use labeled */
-#else
- binary = XYFT_B; /* For all others use binary */
-#endif /* OS2 */
-#endif /* VMS */
- gnf_binary = binary; /* Prevailing type for gnfile() */
- debug(F101,"whoarewe setting binary","",binary);
- }
- }
-}
-#endif /* NOXFER */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcftp.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckcftp.c
deleted file mode 100644
index 66c7940..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcftp.c
+++ /dev/null
@@ -1,17654 +0,0 @@
-#define FTP_TIMEOUT
-
-/* C K C F T P -- FTP Client for C-Kermit */
-
-char *ckftpv = "FTP Client, 9.0.260, 14 Jul 2011";
-
-/*
- Authors:
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University.
-
- Copyright (C) 2000, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Portions of conditionally included code Copyright Regents of the
- University of California and The Stanford SRP Authentication Project;
- see notices below.
-*/
-
-/*
- Pending...
-
- . Implement recursive NLST downloads by trying to CD to each filename.
- If it works, it's a directory; if not, it's a file -- GET it. But
- that won't work with servers like wu-ftpd that don't send directory
- names. Recursion with MLSD is done.
-
- . Make syslog entries for session? Files?
-
- . Messages are printed to stdout and stderr in random fashion. We should
- either print everything to stdout, or else be systematic about when
- to use stderr.
-
- . Implement mail (MAIL, MLFL, MSOM, etc) if any servers support it.
-
- . Adapt to VMS. Big job because of its record-oriented file system.
- RMS programmer required. There are probably also some VMS TCP/IP
- product-specific wrinkles, e.g. attribute preservation in VMS-to-VMS
- transfers using special options for Multinet or other FTP servers
- (find out about STRU VMS).
-*/
-
-/*
- Quick FTP command reference:
-
- RFC765 (1980) and earlier:
- MODE S(tream), B(lock), C(ompressed)
- STRU F(ILE), R(ECORD), P(AGE)
- TYPE A(SCII) <format>, E(BCDIC) <format>, I(MAGE), L(OCAL) <bytesize>
- PORT - Port
- PASV - Passive mode
- USER - User
- PASS - Password
- ACCT - Account
- CWD - Change Working Directory
- REIN - Logout but not disconnect
- QUIT - Bye
- RETR - Retreive
- STOR - Store
- APPE - Append
- ALLO - Allocate
- REST - Restart
- RNFR - Rename from
- RNTO - Rename to
- ABOR - Cancel
- DELE - Delete
- LIST - Directory
- NLST - Name List
- SITE - Site parameters or commands
- STAT - Status
- HELP - Help
- NOOP - Noop
-
- RFC959 (1985):
- CDUP - Change to Parent Directory
- SMNT - Structure Mount
- STOU - Store Unique
- RMD - Remove Directory
- MKD - Make Directory
- PWD - Print Directory
- SYST - System
-
- RFC2389 (1998):
- FEAT - List Features (done)
- OPTS - Send options (done)
-
- RFC2640 (1999):
- LANG - Specify language for messages (not done)
-
- Pending (Internet Drafts):
- SIZE - File size (done)
- MDTM - File modification date-time (done)
- MLST - File name and attribute list (single file) (not done)
- MLSD - File list with attributes (multiple files) (done)
- MAIL, MLFL, MSOM - mail delivery (not done)
-
- Alphabetical syntax list:
- ABOR <CRLF>
- ACCT <SP> <account-information> <CRLF>
- ALLO <SP> <decimal-integer> [<SP> R <SP> <decimal-integer>] <CRLF>
- APPE <SP> <pathname> <CRLF>
- CDUP <CRLF>
- CWD <SP> <pathname> <CRLF>
- DELE <SP> <pathname> <CRLF>
- FEAT <CRLF>
- HELP [<SP> <string>] <CRLF>
- LANG [<SP> <language-tag> ] <CRLF>
- LIST [<SP> <pathname>] <CRLF>
- MKD <SP> <pathname> <CRLF>
- MLSD [<SP> <pathname>] <CRLF>
- MLST [<SP> <pathname>] <CRLF>
- MODE <SP> <mode-code> <CRLF>
- NLST [<SP> <pathname-or-wildcard>] <CRLF>
- NOOP <CRLF>
- OPTS <SP> <commandname> [ <SP> <command-options> ] <CRLF>
- PASS <SP> <password> <CRLF>
- PASV <CRLF>
- PORT <SP> <host-port> <CRLF>
- PWD <CRLF>
- QUIT <CRLF>
- REIN <CRLF>
- REST <SP> <marker> <CRLF>
- RETR <SP> <pathname> <CRLF>
- RMD <SP> <pathname> <CRLF>
- RNFR <SP> <pathname> <CRLF>
- RNTO <SP> <pathname> <CRLF>
- SITE <SP> <string> <CRLF>
- SIZE <SP> <pathname> <CRLF>
- SMNT <SP> <pathname> <CRLF>
- STAT [<SP> <pathname>] <CRLF>
- STOR <SP> <pathname> <CRLF>
- STOU <CRLF>
- STRU <SP> <structure-code> <CRLF>
- SYST <CRLF>
- TYPE <SP> <type-code> <CRLF>
- USER <SP> <username> <CRLF>
-*/
-#include "ckcsym.h" /* Standard includes */
-#include "ckcdeb.h"
-
-#ifndef NOFTP /* NOFTP = no FTP */
-#ifndef SYSFTP /* SYSFTP = use external ftp client */
-#ifdef TCPSOCKET /* Build only if TCP/IP included */
-#define CKCFTP_C
-
-/* Note: much of the following duplicates what was done in ckcdeb.h */
-/* but let's not mess with it unless it causes trouble. */
-
-#ifdef CK_ANSIC
-#include <stdarg.h>
-#else /* CK_ANSIC */
-#include <varargs.h>
-#endif /* CK_ANSIC */
-#include <signal.h>
-#ifdef OS2
-#ifdef OS2ONLY
-#include <os2.h>
-#endif /* OS2ONLY */
-#include "ckowin.h"
-#include "ckocon.h"
-#endif /* OS2 */
-#ifndef ZILOG
-#ifdef NT
-#include <setjmpex.h>
-#ifdef NTSIG
-extern int TlsIndex;
-#endif /* NTSIG */
-#else /* NT */
-#include <setjmp.h>
-#endif /* NT */
-#else
-#include <setret.h>
-#endif /* ZILOG */
-#include "ckcsig.h"
-#ifdef VMS
-/* 2010-03-09 SMS. VAX C needs help to find "sys". It's easier not to try. */
-#include <stat.h>
-#else /* def VMS */
-#include <sys/stat.h>
-#endif /* def VMS [else] */
-#include <ctype.h>
-
-#ifndef HPUXPRE65
-#include <errno.h> /* Error number symbols */
-#else
-#ifndef ERRNO_INCLUDED
-#include <errno.h> /* Error number symbols */
-#endif /* ERRNO_INCLUDED */
-#endif /* HPUXPRE65 */
-
-#ifndef NOTIMEH
-#include <time.h>
-#endif /* NOTIMEH */
-#ifndef EPIPE
-#define EPIPE 32 /* Broken pipe error */
-#endif /* EPIPE */
-
-/* Kermit includes */
-
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckucmd.h"
-#include "ckuusr.h"
-#include "ckcnet.h" /* Includes ckctel.h */
-#include "ckctel.h" /* (then why include it again?) */
-#include "ckcxla.h"
-
-#ifdef CK_SSL
-#include "ckuath.h" /* SMS 2007/02/15 */
-#endif /* def CK_SSL */
-
-/*
- How to get the struct timeval definition so we can call select(). The
- xxTIMEH symbols are defined in ckcdeb.h, overridden in various makefile
- targets. The problem is: maybe we have already included some header file
- that defined struct timeval, and maybe we didn't. If we did, we don't want
- to include another header file that defines it again or the compilation will
- fail. If we didn't, we have to include the header file where it's defined.
- But in some cases even that won't work because of strict POSIX constraints
- or somesuch, or because this introduces other conflicts (e.g. struct tm
- multiply defined), in which case we have to define it ourselves, but this
- can work only if we didn't already encounter a definition.
-*/
-#ifndef DCLTIMEVAL
-#ifdef SV68R3V6
-#define DCLTIMEVAL
-#else
-#ifdef SCO234
-#define DCLTIMEVAL
-#endif /* SCO234 */
-#endif /* SV68R3V6 */
-#endif /* DCLTIMEVAL */
-
-#ifdef DCLTIMEVAL
-/* Also maybe in some places the elements must be unsigned... */
-struct timeval {
- long tv_sec;
- long tv_usec;
-};
-#ifdef COMMENT
-/* Currently we don't use this... */
-struct timezone {
- int tz_minuteswest;
- int tz_dsttime;
-};
-#endif /* COMMENT */
-#else /* !DCLTIMEVAL */
-#ifndef NOSYSTIMEH
-#ifdef SYSTIMEH
-#include <sys/time.h>
-#endif /* SYSTIMEH */
-#endif /* NOSYSTIMEH */
-#ifndef NOSYSTIMEBH
-#ifdef SYSTIMEBH
-#include <sys/timeb.h>
-#endif /* SYSTIMEBH */
-#endif /* NOSYSTIMEBH */
-#endif /* DCLTIMEVAL */
-
-/* 2010-03-09 SMS. VAX C needs help to find "sys". It's easier not to try. */
-#ifdef VMS
-#include <types.h>
-#else /* def VMS */
-#include <sys/types.h>
-#endif /* def VMS [else] */
-#include <stdio.h>
-#include <string.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif /* HAVE_STDLIB_H */
-
-#ifndef NOSETTIME
-#ifdef COMMENT
-/* This section moved to ckcdeb.h */
-#ifdef POSIX
-#define UTIMEH
-#else
-#ifdef HPUX9
-#define UTIMEH
-#else
-#ifdef OS2
-#define SYSUTIMEH
-#endif /* OS2 */
-#endif /* HPUX9 */
-#endif /* POSIX */
-#endif /* COMMENT */
-
-#ifdef VMS /* SMS 2007/02/15 */
-#include "ckvrtl.h" /* for utime() */
-#else /* def VMS */
-#ifdef SYSUTIMEH
-#include <sys/utime.h>
-#else
-#ifdef UTIMEH
-#include <utime.h>
-#define SYSUTIMEH
-#endif /* UTIMEH */
-#endif /* SYSUTIMEH */
-#endif /* def VMS */
-#endif /* NOSETTIME */
-
-#ifndef SCO_OSR504
-#ifdef SELECT_H
-#include <sys/select.h>
-#endif /* SELECT_H */
-#endif /* SCO_OSR504 */
-
-#ifndef INADDR_NONE /* 2010-03-29 */
-#define INADDR_NONE -1
-#endif /* INADDR_NONE */
-
-/* select() dialects... */
-
-#ifdef UNIX
-#define BSDSELECT /* BSD select() syntax/semantics */
-#ifndef FD_SETSIZE
-#define FD_SETSIZE 128
-#endif /* FD_SETSIZE */
-#ifdef HPUX6 /* For HP-UX 6.5 circa 1989 */
-typedef long fd_mask;
-#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
-#ifndef howmany
-#define howmany(x, y) (((x)+((y)-1))/(y))
-#endif /* howmany */
-#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
-#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
-#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
-#define FD_COPY(f, t) bcopy(f, t, sizeof(*(f)))
-#define FD_ZERO(p) bzero(p, sizeof(*(p)))
-#endif /* HPUX6 */
-
-#else
-#ifdef OS2 /* OS/2 or Win32 */
-#ifdef NT
-#define BSDSELECT
-#else /* NT */
-#define IBMSELECT
-#endif /* NT */
-#endif /* OS2 */
-#endif /* UNIX */
-
-#ifdef VMS
-#define BSDSELECT /* SMS 2007/02/15 */
-#endif /* def VMS */
-
-/* Other select() peculiarities */
-
-#ifdef HPUX
-#ifndef HPUX10 /* HP-UX 9.xx and earlier */
-#ifndef HPUX1100
-/* The three interior args to select() are (int *) rather than (fd_set *) */
-#ifndef INTSELECT
-#define INTSELECT
-#endif /* INTSELECT */
-#endif /* HPUX1100 */
-#endif /* HPUX10 */
-#endif /* HPUX */
-
-#ifdef CK_SOCKS /* SOCKS Internet relay package */
-#ifdef CK_SOCKS5 /* SOCKS 5 */
-#define accept SOCKSaccept
-#define bind SOCKSbind
-#define connect SOCKSconnect
-#define getsockname SOCKSgetsockname
-#define listen SOCKSlisten
-#else /* Not SOCKS 5 */
-#define accept Raccept
-#define bind Rbind
-#define connect Rconnect
-#define getsockname Rgetsockname
-#define listen Rlisten
-#endif /* CK_SOCKS5 */
-#endif /* CK_SOCKS */
-
-#ifndef NOHTTP
-extern char * tcp_http_proxy; /* Name[:port] of http proxy server */
-extern int tcp_http_proxy_errno;
-extern char * tcp_http_proxy_user;
-extern char * tcp_http_proxy_pwd;
-extern char * tcp_http_proxy_agent;
-#define HTTPCPYL 1024
-static char proxyhost[HTTPCPYL];
-#endif /* NOHTTP */
-int ssl_ftp_proxy = 0; /* FTP over SSL/TLS Proxy Server */
-
-/* Feature selection */
-
-#ifndef USE_SHUTDOWN
-/*
- We don't use shutdown() because (a) we always call it just before close()
- so it's redundant and unnecessary, and (b) it introduces a long pause on
- some platforms like SV/68 R3.
-*/
-/* #define USE_SHUTDOWN */
-#endif /* USE_SHUTDOWN */
-
-#ifndef NORESEND
-#ifndef NORESTART /* Restart / recover */
-#ifndef FTP_RESTART
-#define FTP_RESTART
-#endif /* FTP_RESTART */
-#endif /* NORESTART */
-#endif /* NORESEND */
-
-#ifndef NOUPDATE /* Update mode */
-#ifndef DOUPDATE
-#define DOUPDATE
-#endif /* DOUPDATE */
-#endif /* NOUPDATE */
-
-#ifndef UNICODE /* Unicode required */
-#ifndef NOCSETS /* for charset translation */
-#define NOCSETS
-#endif /* NOCSETS */
-#endif /* UNICODE */
-
-#ifndef OS2
-#ifndef HAVE_MSECS /* Millisecond timer */
-#ifdef UNIX
-#ifdef GFTIMER
-#define HAVE_MSECS
-#endif /* GFTIMER */
-#endif /* UNIX */
-#endif /* HAVE_MSECS */
-#endif /* OS2 */
-
-#ifdef PIPESEND /* PUT from pipe */
-#ifndef PUTPIPE
-#define PUTPIPE
-#endif /* PUTPIPE */
-#endif /* PIPESEND */
-
-#ifndef NOSPL /* PUT from array */
-#ifndef PUTARRAY
-#define PUTARRAY
-#endif /* PUTARRAY */
-#endif /* NOSPL */
-
-/* Security... */
-
-#ifdef CK_SRP
-#define FTP_SRP
-#endif /* CK_SRP */
-
-#ifdef CK_KERBEROS
-#ifdef KRB4
-/*
- There is a conflict between the Key Schedule formats used internally
- within the standalone MIT KRB4 library and that used by Eric Young
- in OpenSSL and his standalone DES library. Therefore, KRB4 FTP AUTH
- cannot be supported when either of those two packages are used.
-*/
-#ifdef KRB524
-#define FTP_KRB4
-#else /* KRB524 */
-#ifndef CK_SSL
-#ifndef LIBDES
-#define FTP_KRB4
-#endif /* LIBDES */
-#endif /* CK_SSL */
-#endif /* KRB524 */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifndef HEIMDAL
-#ifndef NOFTP_GSSAPI /* 299 */
-#define FTP_GSSAPI
-#endif /* NOFTP_GSSAPI */
-#endif /* HEIMDAL */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-/* FTP_SECURITY is defined if any of the above is selected */
-#ifndef FTP_SECURITY
-#ifdef FTP_GSSAPI
-#define FTP_SECURITY
-#else
-#ifdef FTP_KRB4
-#define FTP_SECURITY
-#else
-#ifdef FTP_SRP
-#define FTP_SECURITY
-#else
-#ifdef CK_SSL
-#define FTP_SECURITY
-#endif /* CK_SSL */
-#endif /* FTP_SRP */
-#endif /* FTP_KRB4 */
-#endif /* FTP_GSSAPI */
-#endif /* FTP_SECURITY */
-
-#ifdef CK_DES
-#ifdef CK_SSL
-#ifndef LIBDES
-#define LIBDES
-#endif /* LIBDES */
-#endif /* CK_SSL */
-#endif /* CK_DES */
-
-#ifdef CRYPT_DLL
-#ifndef LIBDES
-#define LIBDES
-#endif /* LIBDES */
-#endif /* CRYPT_DLL */
-
-#ifdef FTP_KRB4
-#define des_cblock Block
-#define des_key_schedule Schedule
-#ifdef KRB524
-#ifdef NT
-#define _WINDOWS
-#endif /* NT */
-#include "kerberosIV/krb.h"
-#else /* KRB524 */
-#ifdef SOLARIS
-#ifndef sun
-/* For some reason lost in history the Makefile Solaris targets have -Usun */
-#define sun
-#endif /* sun */
-#endif /* SOLARIS */
-#include "krb.h"
-#define krb_get_err_text_entry krb_get_err_text
-#endif /* KRB524 */
-#endif /* FTP_KRB4 */
-
-#ifdef CK_SSL
-#ifdef FTP_KRB4
-#ifndef HEADER_DES_H
-#define HEADER_DES_H
-#endif /* HEADER_DES_H */
-#endif /* FTP_KRB4 */
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-
-#ifdef FTP_SRP
-#ifdef HAVE_PWD_H
-#include "pwd.h"
-#endif /* HAVE_PWD_H */
-#include "t_pwd.h"
-#include "t_client.h"
-#include "krypto.h"
-#endif /* FTP_SRP */
-
-#ifdef FTP_GSSAPI
-#include <gssapi/gssapi.h>
-/*
- Need to include the krb5 file, because we're doing manual fallback
- from the v2 mech to the v1 mech. Once there's real negotiation,
- we can be generic again.
-*/
-#include <gssapi/gssapi_generic.h>
-#include <gssapi/gssapi_krb5.h>
-static gss_ctx_id_t gcontext;
-
-#ifdef MACOSX
-/** exported constants defined in gssapi_krb5{,_nx}.h **/
-
-/* these are bogus, but will compile */
-
-/*
- * The OID of the draft krb5 mechanism, assigned by IETF, is:
- * iso(1) org(3) dod(5) internet(1) security(5)
- * kerberosv5(2) = 1.3.5.1.5.2
- * The OID of the krb5_name type is:
- * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
- * krb5(2) krb5_name(1) = 1.2.840.113554.1.2.2.1
- * The OID of the krb5_principal type is:
- * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
- * krb5(2) krb5_principal(2) = 1.2.840.113554.1.2.2.2
- * The OID of the proposed standard krb5 mechanism is:
- * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
- * krb5(2) = 1.2.840.113554.1.2.2
- * The OID of the proposed standard krb5 v2 mechanism is:
- * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
- * krb5v2(3) = 1.2.840.113554.1.2.3
- *
- */
-
-/*
- * Encoding rules: The first two values are encoded in one byte as 40
- * * value1 + value2. Subsequent values are encoded base 128, most
- * significant digit first, with the high bit (\200) set on all octets
- * except the last in each value's encoding.
- */
-
-static CONST gss_OID_desc
-ck_krb5_gss_oid_array[] = {
- /* this is the official, rfc-specified OID */
- {9, "\052\206\110\206\367\022\001\002\002"},
- /* this is the unofficial, wrong OID */
- {5, "\053\005\001\005\002"},
- /* this is the v2 assigned OID */
- {9, "\052\206\110\206\367\022\001\002\003"},
- /* these two are name type OID's */
- {10, "\052\206\110\206\367\022\001\002\002\001"},
- {10, "\052\206\110\206\367\022\001\002\002\002"},
- { 0, 0 }
-};
-
-static
-CONST gss_OID_desc * CONST gss_mech_krb5_v2 = ck_krb5_gss_oid_array+2;
-
-#ifdef MACOSX103
-static
-CONST gss_OID_desc * CONST gss_mech_krb5 = ck_krb5_gss_oid_array+0;
-#endif /* MACOSX103 */
-
-#ifndef MACOSX
-static
-CONST gss_OID_desc * CONST gss_mech_krb5 = ck_krb5_gss_oid_array+0;
-static
-CONST gss_OID_desc * CONST gss_mech_krb5_old = ck_krb5_gss_oid_array+1;
-static
-CONST gss_OID_desc * CONST gss_nt_krb5_name = ck_krb5_gss_oid_array+3;
-static
-CONST gss_OID_desc * CONST gss_nt_krb5_principal = ck_krb5_gss_oid_array+4;
-#endif /* MACOSX */
-
-/*
- * See krb5/gssapi_krb5.c for a description of the algorithm for
- * encoding an object identifier.
- */
-
-/*
- * The OID of user_name is:
- * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
- * generic(1) user_name(1) = 1.2.840.113554.1.2.1.1
- * machine_uid_name:
- * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
- * generic(1) machine_uid_name(2) = 1.2.840.113554.1.2.1.2
- * string_uid_name:
- * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
- * generic(1) string_uid_name(3) = 1.2.840.113554.1.2.1.3
- * service_name:
- * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
- * generic(1) service_name(4) = 1.2.840.113554.1.2.1.4
- * exported_name:
- * 1(iso), 3(org), 6(dod), 1(internet), 5(security), 6(nametypes),
- * 4(gss-api-exported-name)
- * host_based_service_name (v2):
- * iso (1) org (3), dod (6), internet (1), security (5), nametypes(6),
- * gss-host-based-services(2)
- */
-
-static gss_OID_desc ck_oids[] = {
- {10, "\052\206\110\206\367\022\001\002\001\001"},
- {10, "\052\206\110\206\367\022\001\002\001\002"},
- {10, "\052\206\110\206\367\022\001\002\001\003"},
- {10, "\052\206\110\206\367\022\001\002\001\004"},
- { 6, "\053\006\001\005\006\004"},
- { 6, "\053\006\001\005\006\002"},
-};
-
-static gss_OID ck_gss_nt_user_name = ck_oids+0;
-static gss_OID ck_gss_nt_machine_uid_name = ck_oids+1;
-static gss_OID ck_gss_nt_string_uid_name = ck_oids+2;
-static gss_OID ck_gss_nt_service_name = ck_oids+3;
-static gss_OID ck_gss_nt_exported_name = ck_oids+4;
-static gss_OID ck_gss_nt_service_name_v2 = ck_oids+5;
-#endif /* MACOSX */
-#endif /* FTP_GSSAPI */
-
-#ifdef OS2
-#ifdef FTP_SRP
-#define MAP_KRYPTO
-#ifdef SRPDLL
-#define MAP_SRP
-#endif /* SRPDLL */
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
-#define MAP_KRB4
-#ifdef CK_ENCRYPTION
-#define MAP_DES
-#endif /* CK_ENCRYPTION */
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
-#define MAP_GSSAPI
-#define GSS_OIDS
-#endif /* FTP_GSSAPI */
-#include "ckoath.h"
-
-extern int k95stdout, wherex[], wherey[];
-extern unsigned char colorcmd;
-#endif /* OS2 */
-
-#ifdef FTP_KRB4
-static char ftp_realm[REALM_SZ + 1];
-static KTEXT_ST ftp_tkt;
-#ifdef OS2
-static LEASH_CREDENTIALS ftp_cred;
-#else /* OS2 */
-static CREDENTIALS ftp_cred;
-#endif /* OS2 */
-static MSG_DAT ftp_msg_data;
-static des_key_schedule ftp_sched;
-static int foo[4] = {99,99,99,99};
-#endif /* FTP_KRB4 */
-
-/* getreply() function codes */
-
-#define GRF_AUTH 1 /* Reply to AUTH command */
-#define GRF_FEAT 2 /* Reply to FEAT command */
-
-/* Operational definitions */
-
-#define DEF_VBM 0 /* Default verbose mode */
-/* #define SETVBM */ /* (see getreply) */
-
-#define URL_ONEFILE /* GET, not MGET, for FTP URL */
-
-#define FTP_BUFSIZ 10240 /* Max size for FTP cmds & replies */
-#define SRVNAMLEN 32 /* Max length for server type name */
-#define PWDSIZ 256
-#define PASSBUFSIZ 256
-#define PROMPTSIZ 256
-
-#ifndef MGETMAX /* Max operands for MGET command */
-#define MGETMAX 1000
-#endif /* MGETMAX */
-
-#ifdef FTP_SRP
-#define FUDGE_FACTOR 100
-#endif /* FTP_SRP */
-
-/*
- Amount of growth from cleartext to ciphertext. krb_mk_priv adds this
- number bytes. Must be defined for each auth type.
- GSSAPI appears to add 52 bytes, but I'm not sure it is a constant--hartmans
- 3DES requires 56 bytes. Lets use 96 just to be sure.
-*/
-#ifdef FTP_GSSAPI
-#ifndef FUDGE_FACTOR
-#define FUDGE_FACTOR 96
-#endif /* FUDGE_FACTOR */
-#endif /* FTP_GSSAPI */
-
-#ifdef FTP_KRB4
-#ifndef FUDGE_FACTOR
-#define FUDGE_FACTOR 32
-#endif /* FUDGE_FACTOR */
-#endif /* FTP_KRB4 */
-
-#ifndef FUDGE_FACTOR /* In case no auth types define it */
-#define FUDGE_FACTOR 0
-#endif /* FUDGE_FACTOR */
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif /* MAXHOSTNAMELEN */
-#define MAX_DNS_NAMELEN (15*(MAXHOSTNAMELEN + 1)+1)
-
-/* Fascist compiler toadying */
-
-#ifndef SENDARG2TYPE
-#ifdef COMMENT /* Might be needed here and there */
-#define SENDARG2TYPE const char *
-#else
-#define SENDARG2TYPE char *
-#endif /* COMMENT */
-#endif /* SENDARG2TYPE */
-
-/* Common text messages */
-
-static char *nocx = "?No FTP control connection\n";
-
-static char *fncnam[] = {
- "rename", "overwrite", "backup", "append", "discard", "ask", "update",
- "dates-differ", ""
-};
-
-/* Macro definitions */
-
-/* Used to speed up text-mode PUTs */
-#define zzout(fd,c) \
-((fd<0)?(-1):((nout>=ucbufsiz)?(zzsend(fd,c)):(ucbuf[nout++]=c)))
-
-#define CHECKCONN() if(!connected){printf(nocx);return(-9);}
-
-/* Externals */
-
-#ifdef CK_URL
-extern struct urldata g_url;
-#endif /* CK_URL */
-
-#ifdef DYNAMIC
-extern char *zinbuffer, *zoutbuffer; /* Regular Kermit file i/o */
-#else
-extern char zinbuffer[], zoutbuffer[];
-#endif /* DYNAMIC */
-extern char *zinptr, *zoutptr;
-extern int zincnt, zoutcnt, zobufsize, fncact;
-
-#ifdef CK_TMPDIR
-extern int f_tmpdir; /* Directory changed temporarily */
-extern char savdir[]; /* For saving current directory */
-extern char * dldir;
-#endif /* CK_TMPDIR */
-
-extern char * rfspec, * sfspec, * srfspec, * rrfspec; /* For WHERE command */
-
-extern xx_strp xxstring;
-extern struct keytab onoff[], txtbin[], rpathtab[];
-extern int nrpathtab, xfiletype, patterns, gnferror, moving, what, pktnum;
-extern int success, nfils, sndsrc, quiet, nopush, recursive, inserver, binary;
-extern int filepeek, nscanfile, fsecs, xferstat, xfermode, lastxfer, tsecs;
-extern int backgrd, spackets, rpackets, spktl, rpktl, xaskmore, cmd_rows;
-extern int nolinks, msgflg, keep;
-extern CK_OFF_T fsize, ffc, tfc, sendstart, sndsmaller, sndlarger, rs_len;
-extern long filcnt, xfsecs, tfcps, cps, oldcps;
-
-#ifdef FTP_TIMEOUT
-int ftp_timed_out = 0;
-long ftp_timeout = 0;
-#endif /* FTP_TIMEOUT */
-
-#ifdef GFTIMER
-extern CKFLOAT fptsecs, fpfsecs, fpxfsecs;
-#else
-extern long xfsecs;
-#endif /* GFTIMER */
-
-extern char filnam[], * filefile, myhost[];
-extern char * snd_move, * rcv_move, * snd_rename, * rcv_rename;
-extern int g_skipbup, skipbup, sendmode;
-extern int g_displa, fdispla, displa;
-
-#ifdef LOCUS
-extern int locus, autolocus;
-#endif /* LOCUS */
-
-#ifndef NOCSETS
-extern int nfilc, dcset7, dcset8, fileorder;
-extern struct csinfo fcsinfo[];
-extern struct keytab fcstab[];
-extern int fcharset;
-#endif /* NOCSETS */
-
-extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */
-extern char sndnbefore[], sndnafter[], *rcvexcept[];
-extern CHAR feol;
-
-extern char * remdest;
-extern int remfile, remappd, rempipe;
-
-#ifndef NOSPL
-extern int cmd_quoting;
-#ifdef PUTARRAY
-extern int sndxlo, sndxhi, sndxin;
-extern char sndxnam[];
-extern char **a_ptr[]; /* Array pointers */
-extern int a_dim[]; /* Array dimensions */
-#endif /* PUTARRAY */
-#endif /* NOSPL */
-
-#ifndef NOMSEND /* MPUT and ADD SEND-LIST lists */
-extern char *msfiles[];
-extern int filesinlist;
-extern struct filelist * filehead;
-extern struct filelist * filetail;
-extern struct filelist * filenext;
-extern int addlist;
-extern char fspec[]; /* Most recent filespec */
-extern int fspeclen; /* Length of fspec[] buffer */
-#endif /* NOMSEND */
-
-extern int pipesend;
-#ifdef PIPESEND
-extern char * sndfilter, * rcvfilter;
-#endif /* PIPESEND */
-
-#ifdef CKROOT
-extern int ckrooterr;
-#endif /* CKROOT */
-
-#ifdef KRB4
-extern int krb4_autoget;
-_PROTOTYP(char * ck_krb4_realmofhost,(char *));
-#endif /* KRB4 */
-
-#ifdef KRB5
-extern int krb5_autoget;
-extern int krb5_d_no_addresses;
-_PROTOTYP(char * ck_krb5_realmofhost,(char *));
-#endif /* KRB5 */
-
-#ifdef DCMDBUF
-extern char *atmbuf; /* Atom buffer (malloc'd) */
-extern char *cmdbuf; /* Command buffer (malloc'd) */
-extern char *line; /* Big string buffer #1 */
-extern char *tmpbuf; /* Big string buffer #2 */
-#else
-extern char atmbuf[]; /* The same, but static */
-extern char cmdbuf[];
-extern char line[];
-extern char tmpbuf[];
-#endif /* DCMDBUF */
-
-extern char * cmarg, * cmarg2, ** cmlist; /* For setting up file lists */
-
-/* Public variables declared here */
-
-#ifdef NOXFER
-int ftpget = 1; /* GET/PUT/REMOTE orientation FTP */
-#else
-int ftpget = 2; /* GET/PUT/REMOTE orientation AUTO */
-#endif /* NOXFER */
-int ftpcode = -1; /* Last FTP response code */
-int ftp_cmdlin = 0; /* FTP invoked from command line */
-int ftp_fai = 0; /* FTP failure count */
-int ftp_deb = 0; /* FTP debugging */
-int ftp_dis = -1; /* FTP display style */
-int ftp_log = 1; /* FTP Auto-login */
-int sav_log = -1;
-int ftp_action = 0; /* FTP action from command line */
-int ftp_dates = 1; /* Set file dates from server */
-int ftp_xfermode = XMODE_A; /* FTP-specific transfer mode */
-
-char ftp_reply_str[FTP_BUFSIZ] = ""; /* Last line of previous reply */
-char ftp_srvtyp[SRVNAMLEN] = { NUL, NUL }; /* Server's system type */
-char ftp_user_host[MAX_DNS_NAMELEN]= ""; /* FTP hostname specified by user */
-char * ftp_host = NULL; /* FTP hostname */
-char * ftp_logname = NULL; /* FTP username */
-char * ftp_rdir = NULL; /* Remote directory from cmdline */
-char * ftp_apw = NULL; /* Anonymous password */
-
-/* Definitions and typedefs needed for prototypes */
-
-#define sig_t my_sig_t
-#define sigtype SIGTYP
-typedef sigtype (*sig_t)();
-
-/* Static global variables */
-
-static char ftpsndbuf[FTP_BUFSIZ+64];
-
-static char * fts_sto = NULL;
-
-static int ftpsndret = 0;
-static struct _ftpsnd {
- sig_t oldintr, oldintp;
- int reply;
- int incs,
- outcs;
- char * cmd, * local, * remote;
- int bytes;
- int restart;
- int xlate;
- char * lmode;
-} ftpsnd;
-
-/*
- This is just a first stab -- these strings should match how the
- corresponding FTP servers identify themselves.
-*/
-#ifdef UNIX
-static char * myostype = "UNIX";
-#else
-#ifdef VMS
-/* not yet... */
-static char * myostype = "VMS";
-#else
-#ifdef OS2
-#ifdef NT
-static char * myostype = "WIN32";
-#else
-static char * myostype = "OS/2";
-#endif /* NT */
-#else
-static char * myostype = "UNSUPPORTED";
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* UNIX */
-
-static int noinit = 0; /* Don't send REST, STRU, MODE */
-static int alike = 0; /* Client/server like platforms */
-static int local = 1; /* Shadows Kermit global 'local' */
-static int dout = -1; /* Data connection file descriptor */
-static int dpyactive = 0; /* Data transfer is active */
-static int globaldin = -1; /* Data connection f.d. */
-static int out2screen = 0; /* GET output is to screen */
-static int forcetype = 0; /* Force text or binary mode */
-static int cancelfile = 0; /* File canceled */
-static int cancelgroup = 0; /* Group canceled */
-static int anonymous = 0; /* Logging in as anonymous */
-static int loggedin = 0; /* Logged in (or not) */
-static int puterror = 0; /* What to do on PUT error */
-static int geterror = 0; /* What to do on GET error */
-static int rfrc = 0; /* remote_files() return code */
-static int okrestart = 0; /* Server understands REST */
-static int printlines = 0; /* getreply()should print data lines */
-static int haveurl = 0; /* Invoked by command-line FTP URL */
-static int mdtmok = 1; /* Server supports MDTM */
-static int sizeok = 1;
-static int featok = 1;
-static int mlstok = 1;
-static int stouarg = 1;
-static int typesent = 0;
-static int havesigint = 0;
-static long havetype = 0;
-static CK_OFF_T havesize = (CK_OFF_T)-1;
-static char * havemdtm = NULL;
-static int mgetmethod = 0; /* NLST or MLSD */
-static int mgetforced = 0;
-
-static int i, /* j, k, */ x, y, z; /* Volatile temporaries */
-static int c0, c1; /* Temp variables for characters */
-
-static char putpath[CKMAXPATH+1] = { NUL, NUL };
-static char asnambuf[CKMAXPATH+1] = { NUL, NUL };
-
-#define RFNBUFSIZ 4096 /* Remote filename buffer size */
-
-static unsigned int maxbuf = 0, actualbuf = 0;
-static CHAR *ucbuf = NULL;
-static int ucbufsiz = 0;
-static unsigned int nout = 0; /* Number of chars in ucbuf */
-
-static jmp_buf recvcancel;
-static jmp_buf sendcancel;
-static jmp_buf ptcancel;
-static jmp_buf jcancel;
-static int ptabflg = 0;
-
-/* Protection level symbols */
-
-#define FPL_CLR 1 /* Clear */
-#define FPL_SAF 2 /* Safe */
-#define FPL_PRV 3 /* Private */
-#define FPL_CON 4 /* Confidential */
-
-/* Symbols for file types returned by MLST/MLSD */
-
-#define FTYP_FILE 1 /* Regular file */
-#define FTYP_DIR 2 /* Directory */
-#define FTYP_CDIR 3 /* Current directory */
-#define FTYP_PDIR 4 /* Parent directory */
-
-/* File type symbols keyed to the file-type symbols from ckcker.h */
-
-#define FTT_ASC XYFT_T /* ASCII (text) */
-#define FTT_BIN XYFT_B /* Binary (image) */
-#define FTT_TEN XYFT_X /* TENEX (TOPS-20) */
-
-/* Server feature table - sfttab[0] > 0 means server supports FEAT and OPTS */
-
-static int sfttab[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-
-#define SFT_AUTH 1 /* FTP server feature codes */
-#define SFT_LANG 2
-#define SFT_MDTM 3
-#define SFT_MLST 4
-#define SFT_PBSZ 5
-#define SFT_PROT 6
-#define SFT_REST 7
-#define SFT_SIZE 8
-#define SFT_TVFS 9
-#define SFT_UTF8 10
-
-#define CNV_AUTO 2 /* FTP filename conversion */
-#define CNV_CNV 1
-#define CNV_LIT 0
-
-/* SET FTP values */
-
-static int /* SET FTP values... */
- ftp_aut = 1, /* Auto-authentication */
-#ifdef FTP_SECURITY
- ftp_cry = 1, /* Auto-encryption */
- ftp_cfw = 0, /* Credential forwarding */
-#endif /* FTP_SECURITY */
- ftp_cpl = FPL_CLR, /* Command protection level */
- ftp_dpl = FPL_CLR, /* Data protection level */
-#ifdef FTP_PROXY
- ftp_prx = 0, /* Use proxy */
-#endif /* FTP_PROXY */
- sav_psv = -1, /* For saving passive mode */
- ftp_psv = 1, /* Passive mode */
- ftp_spc = 1, /* Send port commands */
- ftp_typ = FTT_ASC, /* Type */
- get_auto = 1, /* Automatic type switching for GET */
- tenex = 0, /* Type is Tenex */
- ftp_usn = 0, /* Unique server names */
- ftp_prm = 0, /* Permissions */
- ftp_cnv = CNV_AUTO, /* Filename conversion (2 = auto) */
- ftp_vbm = DEF_VBM, /* Verbose mode */
- ftp_vbx = DEF_VBM, /* Sticky version of same */
- ftp_err = 0, /* Error action */
- ftp_fnc = -1; /* Filename collision action */
-
-#ifdef CK_SSL
-static int ftp_bug_use_ssl_v2 = 0; /* use SSLv2 for AUTH SSL */
-#endif /* CK_SSL */
-
-static int
-#ifdef NOCSETS
- ftp_csr = -1, /* Remote (server) character set */
-#else
- ftp_csr = FC_UTF8,
-#endif /* NOCSETS */
- ftp_xla = 0; /* Character-set translation on/off */
-int
- ftp_csx = -1, /* Remote charset currently in use */
- ftp_csl = -1; /* Local charset currently in use */
-
-static int g_ftp_typ = FTT_ASC; /* For saving and restoring ftp_typ */
-
-char * ftp_nml = NULL; /* /NAMELIST */
-char * ftp_tmp = NULL; /* Temporary string */
-static char * ftp_acc = NULL; /* Account string */
-static char * auth_type = NULL; /* Authentication type */
-static char * srv_renam = NULL; /* Server-rename string */
-FILE * fp_nml = NULL; /* Namelist file pointer */
-
-static int csocket = -1; /* Control socket */
-static int connected = 0; /* Connected to FTP server */
-/* static unsigned short ftp_port = 0; */ /* FTP port */
-/* static int ftp_port = 0; */ /* SMS 2007/02/15 */
-static int ftp_port = 0; /* fdc 2007/08/30 */
-#ifdef FTPHOST
-static int hostcmd = 0; /* Has HOST command been sent */
-#endif /* FTPHOST */
-static int form, mode, stru, bytesize, curtype = FTT_ASC;
-static char bytename[8];
-
-/* For parsing replies to FTP server command */
-static char *reply_parse, reply_buf[FTP_BUFSIZ], *reply_ptr;
-
-#ifdef FTP_PROXY
-static int proxy, unix_proxy
-#endif /* FTP_PROXY */
-
-static char pasv[64]; /* Passive-mode port */
-static int passivemode = 0;
-static int sendport = 0;
-static int servertype = 0; /* FTP server's OS type */
-
-static int testing = 0;
-static char ftpcmdbuf[FTP_BUFSIZ];
-
-/* Macro definitions */
-
-#define UC(b) ckitoa(((int)b)&0xff)
-#define nz(x) ((x) == 0 ? 1 : (x))
-
-/* Command tables and definitions */
-
-#define FTP_ACC 1 /* FTP command keyword codes */
-#define FTP_APP 2
-#define FTP_CWD 3
-#define FTP_CHM 4
-#define FTP_CLS 5
-#define FTP_DEL 6
-#define FTP_DIR 7
-#define FTP_GET 8
-#define FTP_IDL 9
-#define FTP_MDE 10
-#define FTP_MDI 11
-#define FTP_MGE 12
-#define FTP_MKD 13
-#define FTP_MOD 14
-#define FTP_MPU 15
-#define FTP_OPN 16
-#define FTP_PUT 17
-#define FTP_PWD 18
-#define FTP_RGE 19
-#define FTP_REN 20
-#define FTP_RES 21
-#define FTP_HLP 22
-#define FTP_RMD 23
-#define FTP_STA 24
-#define FTP_SIT 25
-#define FTP_SIZ 26
-#define FTP_SYS 27
-#define FTP_UMA 28
-#define FTP_GUP 29
-#define FTP_USR 30
-#define FTP_QUO 31
-#define FTP_TYP 32
-#define FTP_FEA 33
-#define FTP_OPT 34
-#define FTP_CHK 35
-#define FTP_VDI 36
-#define FTP_ENA 37
-#define FTP_DIS 38
-#define FTP_REP 39
-
-struct keytab gprtab[] = { /* GET-PUT-REMOTE keywords */
- { "auto", 2, 0 },
- { "ftp", 1, 0 },
- { "kermit", 0, 0 }
-};
-
-static struct keytab qorp[] = { /* QUIT or PROCEED keywords */
- { "proceed", 0, 0 }, /* 0 = proceed */
- { "quit", 1, 0 } /* 1 = quit */
-};
-
-static struct keytab ftpcmdtab[] = { /* FTP command table */
- { "account", FTP_ACC, 0 },
- { "append", FTP_APP, 0 },
- { "bye", FTP_CLS, 0 },
- { "cd", FTP_CWD, 0 },
- { "cdup", FTP_GUP, 0 },
- { "check", FTP_CHK, 0 },
- { "chmod", FTP_CHM, 0 },
- { "close", FTP_CLS, 0 },
- { "cwd", FTP_CWD, CM_INV },
- { "delete", FTP_MDE, 0 },
- { "directory", FTP_DIR, 0 },
- { "disable", FTP_DIS, 0 },
- { "enable", FTP_ENA, 0 },
- { "features", FTP_FEA, 0 },
- { "get", FTP_GET, 0 },
- { "help", FTP_HLP, 0 },
- { "idle", FTP_IDL, 0 },
- { "login", FTP_USR, CM_INV },
- { "mdelete", FTP_MDE, CM_INV },
- { "mget", FTP_MGE, 0 },
- { "mkdir", FTP_MKD, 0 },
- { "modtime", FTP_MOD, 0 },
- { "mput", FTP_MPU, 0 },
- { "open", FTP_OPN, 0 },
- { "opt", FTP_OPT, CM_INV|CM_ABR },
- { "opts", FTP_OPT, CM_INV },
- { "options", FTP_OPT, 0 },
- { "put", FTP_PUT, 0 },
- { "pwd", FTP_PWD, 0 },
- { "quit", FTP_CLS, CM_INV },
- { "quote", FTP_QUO, 0 },
- { "reget", FTP_RGE, 0 },
- { "rename", FTP_REN, 0 },
- { "reput", FTP_REP, 0 },
- { "resend", FTP_REP, CM_INV },
- { "reset", FTP_RES, 0 },
- { "rmdir", FTP_RMD, 0 },
- { "send", FTP_PUT, CM_INV },
- { "site", FTP_SIT, 0 },
- { "size", FTP_SIZ, 0 },
- { "status", FTP_STA, 0 },
- { "system", FTP_SYS, 0 },
- { "type", FTP_TYP, 0 },
- { "umask", FTP_UMA, 0 },
- { "up", FTP_GUP, CM_INV },
- { "user", FTP_USR, 0 },
- { "vdirectory",FTP_VDI, 0 },
- { "", 0, 0 }
-};
-static int nftpcmd = (sizeof(ftpcmdtab) / sizeof(struct keytab)) - 1;
-
-#define OPN_ANO 1 /* FTP OPEN switch codes */
-#define OPN_PSW 2
-#define OPN_USR 3
-#define OPN_ACC 4
-#define OPN_ACT 5
-#define OPN_PSV 6
-#define OPN_TLS 7
-#define OPN_NIN 8
-#define OPN_NOL 9
-
-#ifdef FTP_SECURITY
-#ifdef CK_SSL
-#define USETLSTAB
-static struct keytab tlstab[] = { /* FTP SSL/TLS switches */
- { "/ssl", OPN_TLS, 0 },
- { "/tls", OPN_TLS, 0 },
- { "", 0, 0 }
-};
-static int ntlstab = (sizeof(tlstab) / sizeof(struct keytab)) - 1;
-#endif /* CK_SSL */
-#endif /* FTP_SECURITY */
-
-static struct keytab ftpswitab[] = { /* FTP command switches */
- { "/account", OPN_ACC, CM_ARG },
- { "/active", OPN_ACT, 0 },
- { "/anonymous", OPN_ANO, 0 },
- { "/noinit", OPN_NIN, 0 },
- { "/nologin", OPN_NOL, 0 },
- { "/passive", OPN_PSV, 0 },
- { "/password", OPN_PSW, CM_ARG },
- { "/user", OPN_USR, CM_ARG },
- { "", 0, 0 }
-};
-static int nftpswi = (sizeof(ftpswitab) / sizeof(struct keytab)) - 1;
-
-/* FTP { ENABLE, DISABLE } items */
-
-#define ENA_FEAT 1
-#define ENA_MDTM 2
-#define ENA_MLST 3
-#define ENA_SIZE 4
-#define ENA_AUTH 5
-
-static struct keytab ftpenatab[] = {
- { "AUTH", ENA_AUTH, 0 },
- { "FEAT", ENA_FEAT, 0 },
- { "MDTM", ENA_MDTM, 0 },
- { "ML", ENA_MLST, CM_INV|CM_ABR },
- { "MLS", ENA_MLST, CM_INV|CM_ABR },
- { "MLSD", ENA_MLST, CM_INV },
- { "MLST", ENA_MLST, 0 },
- { "SIZE", ENA_SIZE, 0 },
- { "", 0, 0 }
-};
-static int nftpena = (sizeof(ftpenatab) / sizeof(struct keytab)) - 1;
-
-/* SET FTP command keyword indices */
-
-#define FTS_AUT 1 /* Autoauthentication */
-#define FTS_CRY 2 /* Encryption */
-#define FTS_LOG 3 /* Autologin */
-#define FTS_CPL 4 /* Command protection level */
-#define FTS_CFW 5 /* Credentials forwarding */
-#define FTS_DPL 6 /* Data protection level */
-#define FTS_DBG 7 /* Debugging */
-#define FTS_PSV 8 /* Passive mode */
-#define FTS_SPC 9 /* Send port commands */
-#define FTS_TYP 10 /* (file) Type */
-#define FTS_USN 11 /* Unique server names (for files) */
-#define FTS_VBM 12 /* Verbose mode */
-#define FTS_ATP 13 /* Authentication type */
-#define FTS_CNV 14 /* Filename conversion */
-#define FTS_TST 15 /* Test (progress) messages */
-#define FTS_PRM 16 /* (file) Permissions */
-#define FTS_XLA 17 /* Charset translation */
-#define FTS_CSR 18 /* Server charset */
-#define FTS_ERR 19 /* Error action */
-#define FTS_FNC 20 /* Collision */
-#define FTS_SRP 21 /* SRP options */
-#define FTS_GFT 22 /* GET automatic file-type switching */
-#define FTS_DAT 23 /* Set file dates */
-#define FTS_STO 24 /* Server time offset */
-#define FTS_APW 25 /* Anonymous password */
-#define FTS_DIS 26 /* File-transfer display style */
-#define FTS_BUG 27 /* Bug(s) */
-#define FTS_TMO 28 /* Timeout */
-
-/* FTP BUGS */
-
-#define FTB_SV2 1 /* use SSLv2 */
-
-static struct keytab ftpbugtab[] = {
- { "use-ssl-v2", FTB_SV2, 0 }
-};
-static int nftpbug = (sizeof(ftpbugtab) / sizeof(struct keytab));
-
-/* FTP PUT options (mutually exclusive, not a bitmask) */
-
-#define PUT_UPD 1 /* Update */
-#define PUT_RES 2 /* Restart */
-#define PUT_SIM 4 /* Simulation */
-#define PUT_DIF 8 /* Dates Differ */
-
-static struct keytab ftpcolxtab[] = { /* SET FTP COLLISION options */
-#ifndef MAC
- { "append", XYFX_A, 0 }, /* append to old file */
-#endif /* MAC */
-#ifdef COMMENT
- { "ask", XYFX_Q, 0 }, /* ask what to do (not implemented) */
-#endif
- { "backup", XYFX_B, 0 }, /* rename old file */
-#ifndef MAC
- { "dates-differ", XYFX_M, 0 }, /* accept if dates differ */
- { "discard", XYFX_D, 0 }, /* don't accept new file */
- { "no-supersede", XYFX_D, CM_INV }, /* ditto (MSK compatibility) */
-#endif /* MAC */
- { "overwrite", XYFX_X, 0 }, /* overwrite the old file */
- { "rename", XYFX_R, 0 }, /* rename the incoming file */
-#ifndef MAC /* This crashes Mac Kermit. */
- { "update", XYFX_U, 0 }, /* replace if newer */
-#endif /* MAC */
- { "", 0, 0 }
-};
-static int nftpcolx = (sizeof(ftpcolxtab) / sizeof(struct keytab)) - 1;
-
-
-#ifdef FTP_SECURITY
-/* FTP authentication options */
-
-#define FTA_AUTO 0 /* Auto */
-#define FTA_SRP 1 /* SRP */
-#define FTA_GK5 2 /* Kerberos 5 */
-#define FTA_K4 3 /* Kerberos 4 */
-#define FTA_SSL 4 /* SSL */
-#define FTA_TLS 5 /* TLS */
-
-/* FTP authentication types */
-
-#define FTPATYPS 8
-static int ftp_auth_type[FTPATYPS] = {
-#ifdef FTP_GSSAPI
- FTA_GK5, /* GSSAPI Kerberos 5 */
-#endif /* FTP_GK5 */
-#ifdef FTP_SRP
- FTA_SRP, /* SRP */
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- FTA_K4, /* Kerberos 4 */
-#endif /* FTP_KRB4 */
-#ifdef CK_SSL
- FTA_TLS, /* TLS */
- FTA_SSL, /* SSL */
-#endif /* CK_SSL */
- 0
-};
-
-static struct keytab ftpauth[] = { /* SET FTP AUTHTYPE cmd table */
- { "automatic", FTA_AUTO, CM_INV },
-#ifdef FTP_GSSAPI
- { "gssapi-krb5", FTA_GK5, 0 },
-#endif /* FTP_GSSAPI */
-#ifdef FTP_KRB4
- { "k4", FTA_K4, CM_INV },
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- { "k5", FTA_GK5, CM_INV },
-#endif /* FTP_GSSAPI */
-#ifdef FTP_KRB4
- { "kerberos4", FTA_K4, 0 },
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- { "kerberos5", FTA_GK5, CM_INV },
-#endif /* FTP_GSSAPI */
-#ifdef FTP_KRB4
- { "kerberos_iv",FTA_K4, CM_INV },
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- { "kerberos_v", FTA_GK5, CM_INV },
-#endif /* FTP_GSSAPI */
-#ifdef FTP_KRB4
- { "krb4", FTA_K4, CM_INV },
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- { "krb5", FTA_GK5, CM_INV },
-#endif /* FTP_GSSAPI */
-#ifdef FTP_SRP
- { "srp", FTA_SRP, 0 },
-#endif /* FTP_SRP */
-#ifdef CK_SSL
- { "ssl", FTA_SSL, 0 },
- { "tls", FTA_TLS, 0 },
-#endif /* CK_SSL */
- { "", 0, 0 }
-};
-static int nftpauth = (sizeof(ftpauth) / sizeof(struct keytab)) - 1;
-
-#ifdef FTP_SRP
-#define SRP_CIPHER 1
-#define SRP_HASH 2
-static struct keytab ftpsrp[] = { /* SET FTP SRP command table */
- { "cipher", SRP_CIPHER, 0 },
- { "hash", SRP_HASH, 0 },
- { "", 0, 0 }
-};
-static int nftpsrp = (sizeof(ftpsrp) / sizeof(struct keytab)) - 1;
-#endif /* FTP_SRP */
-#endif /* FTP_SECURITY */
-
-static struct keytab ftpset[] = { /* SET FTP commmand table */
- { "anonymous-password", FTS_APW, 0 },
-#ifdef FTP_SECURITY
- { "authtype", FTS_ATP, 0 },
- { "autoauthentication", FTS_AUT, 0 },
- { "autoencryption", FTS_CRY, 0 },
-#endif /* FTP_SECURITY */
- { "autologin", FTS_LOG, 0 },
- { "bug", FTS_BUG, 0 },
-#ifndef NOCSETS
- { "character-set-translation",FTS_XLA, 0 },
-#endif /* NOCSETS */
- { "collision", FTS_FNC, 0 },
-#ifdef FTP_SECURITY
- { "command-protection-level", FTS_CPL, 0 },
- { "cpl", FTS_CPL, CM_INV },
- { "credential-forwarding", FTS_CFW, 0 },
- { "da", FTS_DAT, CM_INV|CM_ABR },
- { "data-protection-level", FTS_DPL, 0 },
-#endif /* FTP_SECURITY */
- { "dates", FTS_DAT, 0 },
- { "debug", FTS_DBG, 0 },
- { "display", FTS_DIS, 0 },
-#ifdef FTP_SECURITY
- { "dpl", FTS_DPL, CM_INV },
-#endif /* FTP_SECURITY */
- { "error-action", FTS_ERR, 0 },
- { "filenames", FTS_CNV, 0 },
- { "get-filetype-switching", FTS_GFT, 0 },
- { "passive-mode", FTS_PSV, 0 },
- { "pasv", FTS_PSV, CM_INV },
- { "permissions", FTS_PRM, 0 },
- { "progress-messages", FTS_TST, 0 },
- { "send-port-commands", FTS_SPC, 0 },
-#ifndef NOCSETS
- { "server-character-set", FTS_CSR, 0 },
-#endif /* NOCSETS */
- { "server-time-offset", FTS_STO, 0 },
-#ifdef FTP_SRP
- { "srp", FTS_SRP, 0 },
-#else
- { "srp", FTS_SRP, CM_INV },
-#endif /* FTP_SRP */
-#ifdef FTP_TIMEOUT
- { "timeout", FTS_TMO, 0 },
-#endif /* FTP_TIMEOUT */
- { "type", FTS_TYP, 0 },
- { "unique-server-names", FTS_USN, 0 },
- { "verbose-mode", FTS_VBM, 0 },
- { "", 0, 0 }
-};
-static int nftpset = (sizeof(ftpset) / sizeof(struct keytab)) - 1;
-
-/*
- GET and PUT switches are approximately the same as Kermit GET and SEND,
- and use the same SND_xxx definitions, but hijack a couple for FTP use.
- Don't just make up new ones, since the number of SND_xxx options must be
- known in advance for the switch-parsing arrays.
-*/
-#define SND_USN SND_PRO /* /UNIQUE instead of /PROTOCOL */
-#define SND_PRM SND_PIP /* /PERMISSIONS instead of /PIPES */
-#define SND_TEN SND_CAL /* /TENEX instead of /CALIBRATE */
-
-static struct keytab putswi[] = { /* FTP PUT switch table */
- { "/after", SND_AFT, CM_ARG },
-#ifdef PUTARRAY
- { "/array", SND_ARR, CM_ARG },
-#endif /* PUTARRAY */
- { "/as", SND_ASN, CM_ARG|CM_INV|CM_ABR },
- { "/as-name", SND_ASN, CM_ARG },
- { "/ascii", SND_TXT, CM_INV },
- { "/b", SND_BIN, CM_INV|CM_ABR },
- { "/before", SND_BEF, CM_ARG },
- { "/binary", SND_BIN, 0 },
-#ifdef PUTPIPE
- { "/command", SND_CMD, CM_PSH },
-#endif /* PUTPIPE */
-#ifdef COMMENT
-/* This works but it's dangerous */
-#ifdef DOUPDATE
- { "/dates-differ", SND_DIF, CM_INV },
-#endif /* DOUPDATE */
-#endif /* COMMENT */
- { "/delete", SND_DEL, 0 },
-#ifdef UNIXOROSK
- { "/dotfiles", SND_DOT, 0 },
-#endif /* UNIXOROSK */
- { "/error-action", SND_ERR, CM_ARG },
- { "/except", SND_EXC, CM_ARG },
- { "/filenames", SND_NAM, CM_ARG },
-#ifdef PIPESEND
-#ifndef NOSPL
- { "/filter", SND_FLT, CM_ARG|CM_PSH },
-#endif /* NOSPL */
-#endif /* PIPESEND */
-#ifdef CKSYMLINK
- { "/followlinks", SND_LNK, 0 },
-#endif /* CKSYMLINK */
-#ifdef VMS
- { "/image", SND_IMG, 0 },
-#else
- { "/image", SND_BIN, CM_INV },
-#endif /* VMS */
- { "/larger-than", SND_LAR, CM_ARG },
- { "/listfile", SND_FIL, CM_ARG },
-#ifndef NOCSETS
- { "/local-character-set", SND_CSL, CM_ARG },
-#endif /* NOCSETS */
-#ifdef CK_TMPDIR
- { "/move-to", SND_MOV, CM_ARG },
-#endif /* CK_TMPDIR */
- { "/nobackupfiles", SND_NOB, 0 },
-#ifdef UNIXOROSK
- { "/nodotfiles", SND_NOD, 0 },
-#endif /* UNIXOROSK */
-#ifdef CKSYMLINK
- { "/nofollowlinks", SND_NLK, 0 },
-#endif /* CKSYMLINK */
-
- { "/not-after", SND_NAF, CM_ARG },
- { "/not-before", SND_NBE, CM_ARG },
-#ifdef UNIX
- { "/permissions", SND_PRM, CM_ARG },
-#else
- { "/permissions", SND_PRM, CM_ARG|CM_INV },
-#endif /* UNIX */
- { "/quiet", SND_SHH, 0 },
-#ifdef FTP_RESTART
- { "/recover", SND_RES, 0 },
-#endif /* FTP_RESTART */
-#ifdef RECURSIVE
- { "/recursive", SND_REC, 0 },
-#endif /* RECURSIVE */
- { "/rename-to", SND_REN, CM_ARG },
-#ifdef FTP_RESTART
- { "/restart", SND_RES, CM_INV },
-#endif /* FTP_RESTART */
-#ifndef NOCSETS
- { "/server-character-set", SND_CSR, CM_ARG },
-#endif /* NOCSETS */
- { "/server-rename-to", SND_SRN, CM_ARG },
- { "/simulate", SND_SIM, 0 },
- { "/since", SND_AFT, CM_INV|CM_ARG },
- { "/smaller-than", SND_SMA, CM_ARG },
-#ifdef COMMENT
- { "/starting-at", SND_STA, CM_ARG },
-#endif /* COMMENT */
-#ifdef RECURSIVE
- { "/subdirectories", SND_REC, CM_INV },
-#endif /* RECURSIVE */
- { "/tenex", SND_TEN, 0 },
- { "/text", SND_TXT, 0 },
-#ifndef NOCSETS
- { "/transparent", SND_XPA, 0 },
-#endif /* NOCSETS */
- { "/type", SND_TYP, CM_ARG },
-#ifdef DOUPDATE
- { "/update", SND_UPD, 0 },
-#endif /* DOUPDATE */
- { "/unique-server-names", SND_USN, 0 },
- { "", 0, 0 }
-};
-static int nputswi = (sizeof(putswi) / sizeof(struct keytab)) - 1;
-
-static struct keytab getswi[] = { /* FTP [M]GET switch table */
- { "/after", SND_AFT, CM_INV },
- { "/as", SND_ASN, CM_ARG|CM_INV|CM_ABR },
- { "/as-name", SND_ASN, CM_ARG },
- { "/ascii", SND_TXT, CM_INV },
- { "/before", SND_BEF, CM_INV },
- { "/binary", SND_BIN, 0 },
- { "/collision", SND_COL, CM_ARG },
-#ifdef PUTPIPE
- { "/command", SND_CMD, CM_PSH },
-#endif /* PUTPIPE */
- { "/delete", SND_DEL, 0 },
- { "/error-action", SND_ERR, CM_ARG },
- { "/except", SND_EXC, CM_ARG },
- { "/filenames", SND_NAM, CM_ARG },
-#ifdef PIPESEND
-#ifndef NOSPL
- { "/filter", SND_FLT, CM_ARG|CM_PSH },
-#endif /* NOSPL */
-#endif /* PIPESEND */
-#ifdef VMS
- { "/image", SND_IMG, 0 },
-#else
- { "/image", SND_BIN, CM_INV },
-#endif /* VMS */
- { "/larger-than", SND_LAR, CM_ARG },
- { "/listfile", SND_FIL, CM_ARG },
-#ifndef NOCSETS
- { "/local-character-set", SND_CSL, CM_ARG },
-#endif /* NOCSETS */
- { "/match", SND_PAT, CM_ARG },
- { "/ml", SND_MLS, CM_INV|CM_ABR },
- { "/mls", SND_MLS, CM_INV|CM_ABR },
- { "/mlsd", SND_MLS, 0 },
- { "/mlst", SND_MLS, CM_INV },
-#ifdef CK_TMPDIR
- { "/move-to", SND_MOV, CM_ARG },
-#endif /* CK_TMPDIR */
- { "/namelist", SND_NML, CM_ARG },
- { "/nlst", SND_NLS, 0 },
- { "/nobackupfiles", SND_NOB, 0 },
- { "/nodotfiles", SND_NOD, 0 },
-#ifdef DOUPDATE
- { "/dates-differ", SND_DIF, CM_INV },
-#endif /* DOUPDATE */
- { "/not-after", SND_NAF, CM_INV },
- { "/not-before", SND_NBE, CM_INV },
- { "/permissions", SND_PRM, CM_INV },
- { "/quiet", SND_SHH, 0 },
-#ifdef FTP_RESTART
- { "/recover", SND_RES, 0 },
-#endif /* FTP_RESTART */
-#ifdef RECURSIVE
- { "/recursive", SND_REC, 0 },
-#endif /* RECURSIVE */
- { "/rename-to", SND_REN, CM_ARG },
-#ifdef FTP_RESTART
- { "/restart", SND_RES, CM_INV },
-#endif /* FTP_RESTART */
-#ifndef NOCSETS
- { "/server-character-set", SND_CSR, CM_ARG },
-#endif /* NOCSETS */
- { "/server-rename-to", SND_SRN, CM_ARG },
- { "/smaller-than", SND_SMA, CM_ARG },
-#ifdef RECURSIVE
- { "/subdirectories", SND_REC, CM_INV },
-#endif /* RECURSIVE */
- { "/text", SND_TXT, 0 },
- { "/tenex", SND_TEN, 0 },
-#ifndef NOCSETS
- { "/transparent", SND_XPA, 0 },
-#endif /* NOCSETS */
- { "/to-screen", SND_MAI, 0 },
-#ifdef DOUPDATE
- { "/update", SND_UPD, CM_INV },
-#endif /* DOUPDATE */
- { "", 0, 0 }
-};
-static int ngetswi = (sizeof(getswi) / sizeof(struct keytab)) - 1;
-
-static struct keytab delswi[] = { /* FTP [M]DELETE switch table */
- { "/error-action", SND_ERR, CM_ARG },
- { "/except", SND_EXC, CM_ARG },
- { "/filenames", SND_NAM, CM_ARG },
- { "/larger-than", SND_LAR, CM_ARG },
- { "/nobackupfiles", SND_NOB, 0 },
-#ifdef UNIXOROSK
- { "/nodotfiles", SND_NOD, 0 },
-#endif /* UNIXOROSK */
- { "/quiet", SND_SHH, 0 },
-#ifdef RECURSIVE
- { "/recursive", SND_REC, 0 },
-#endif /* RECURSIVE */
- { "/smaller-than", SND_SMA, CM_ARG },
-#ifdef RECURSIVE
- { "/subdirectories", SND_REC, CM_INV },
-#endif /* RECURSIVE */
- { "", 0, 0 }
-};
-static int ndelswi = (sizeof(delswi) / sizeof(struct keytab)) - 1;
-
-static struct keytab fntab[] = { /* Filename conversion keyword table */
- { "automatic", 2, CNV_AUTO },
- { "converted", 1, CNV_CNV },
- { "literal", 0, CNV_LIT }
-};
-static int nfntab = (sizeof(fntab) / sizeof(struct keytab));
-
-static struct keytab ftptyp[] = { /* SET FTP TYPE table */
- { "ascii", FTT_ASC, 0 },
- { "binary", FTT_BIN, 0 },
- { "tenex", FTT_TEN, 0 },
- { "text", FTT_ASC, CM_INV },
- { "", 0, 0 }
-};
-static int nftptyp = (sizeof(ftptyp) / sizeof(struct keytab)) - 1;
-
-#ifdef FTP_SECURITY
-static struct keytab ftppro[] = { /* SET FTP PROTECTION-LEVEL table */
- { "clear", FPL_CLR, 0 },
- { "confidential", FPL_CON, 0 },
- { "private", FPL_PRV, 0 },
- { "safe", FPL_SAF, 0 },
- { "", 0, 0 }
-};
-static int nftppro = (sizeof(ftppro) / sizeof(struct keytab)) - 1;
-#endif /* FTP_SECURITY */
-
-/* Definitions for FTP from RFC765. */
-
-/* Reply codes */
-
-#define REPLY_PRELIM 1 /* Positive preliminary */
-#define REPLY_COMPLETE 2 /* Positive completion */
-#define REPLY_CONTINUE 3 /* Positive intermediate */
-#define REPLY_TRANSIENT 4 /* Transient negative completion */
-#define REPLY_ERROR 5 /* Permanent negative completion */
-#define REPLY_SECURE 6 /* Security encoded message */
-
-/* Form codes and names */
-
-#define FORM_N 1 /* Non-print */
-#define FORM_T 2 /* Telnet format effectors */
-#define FORM_C 3 /* Carriage control (ASA) */
-
-/* Structure codes and names */
-
-#define STRU_F 1 /* File (no record structure) */
-#define STRU_R 2 /* Record structure */
-#define STRU_P 3 /* Page structure */
-
-/* Mode types and names */
-
-#define MODE_S 1 /* Stream */
-#define MODE_B 2 /* Block */
-#define MODE_C 3 /* Compressed */
-
-/* Protection levels and names */
-
-#define PROT_C 1 /* Clear */
-#define PROT_S 2 /* Safe */
-#define PROT_P 3 /* Private */
-#define PROT_E 4 /* Confidential */
-
-#ifdef COMMENT /* Not used */
-#ifdef FTP_NAMES
-char *strunames[] = {"0", "File", "Record", "Page" };
-char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" };
-char *modenames[] = {"0", "Stream", "Block", "Compressed" };
-char *levelnames[] = {"0", "Clear", "Safe", "Private", "Confidential" };
-#endif /* FTP_NAMES */
-
-/* Record Tokens */
-
-#define REC_ESC '\377' /* Record-mode Escape */
-#define REC_EOR '\001' /* Record-mode End-of-Record */
-#define REC_EOF '\002' /* Record-mode End-of-File */
-
-/* Block Header */
-
-#define BLK_EOR 0x80 /* Block is End-of-Record */
-#define BLK_EOF 0x40 /* Block is End-of-File */
-#define BLK_REPLY_ERRORS 0x20 /* Block might have errors */
-#define BLK_RESTART 0x10 /* Block is Restart Marker */
-#define BLK_BYTECOUNT 2 /* Bytes in this block */
-#endif /* COMMENT */
-
-#define RADIX_ENCODE 0 /* radix_encode() function codes */
-#define RADIX_DECODE 1
-
-/*
- The default setpbsz() value in the Unix FTP client is 1<<20 (1MB). This
- results in a serious performance degradation due to the increased number
- of page faults and the inability to overlap encrypt/decrypt, file i/o, and
- network i/o. So instead we set the value to 1<<13 (8K), about half the size
- of the typical TCP window. Maybe we should add a command to allow the value
- to be changed.
-*/
-#define DEFAULT_PBSZ 1<<13
-
-/* Prototypes */
-
-_PROTOTYP(int remtxt, (char **) );
-_PROTOTYP(char * gskreason, (int) );
-_PROTOTYP(static int ftpclose,(void));
-_PROTOTYP(static int zzsend, (int, CHAR));
-_PROTOTYP(static int getreply,(int,int,int,int,int));
-_PROTOTYP(static int radix_encode,(CHAR[], CHAR[], int, int *, int));
-_PROTOTYP(static int setpbsz,(unsigned int));
-_PROTOTYP(static int recvrequest,(char *,char *,char *,char *,
- int,int,char *,int,int,int));
-_PROTOTYP(static int ftpcmd,(char *,char *,int,int,int));
-_PROTOTYP(static int fts_cpl,(int));
-_PROTOTYP(static int fts_dpl,(int));
-#ifdef FTP_SECURITY
-_PROTOTYP(static int ftp_auth, (void));
-#endif /* FTP_SECURITY */
-_PROTOTYP(static int ftp_user, (char *, char *, char *));
-_PROTOTYP(static int ftp_login, (char *));
-_PROTOTYP(static int ftp_reset, (void));
-_PROTOTYP(static int ftp_rename, (char *, char *));
-_PROTOTYP(static int ftp_umask, (char *));
-_PROTOTYP(static int secure_flush, (int));
-#ifdef COMMENT
-_PROTOTYP(static int secure_putc, (char, int));
-#endif /* COMMENT */
-_PROTOTYP(static int secure_write, (int, CHAR *, unsigned int));
-_PROTOTYP(static int scommand, (char *));
-_PROTOTYP(static int secure_putbuf, (int, CHAR *, unsigned int));
-_PROTOTYP(static int secure_getc, (int, int));
-_PROTOTYP(static int secure_getbyte, (int, int));
-_PROTOTYP(static int secure_read, (int, char *, int));
-_PROTOTYP(static int initconn, (void));
-_PROTOTYP(static int dataconn, (char *));
-_PROTOTYP(static int setprotbuf,(unsigned int));
-_PROTOTYP(static int sendrequest, (char *, char *, char *, int,int,int,int));
-
-_PROTOTYP(static char * radix_error,(int));
-_PROTOTYP(static char * ftp_hookup,(char *, int, int));
-_PROTOTYP(static CHAR * remote_files, (int, CHAR *, CHAR *, int));
-
-_PROTOTYP(static VOID mlsreset, (void));
-_PROTOTYP(static VOID secure_error, (char *fmt, ...));
-_PROTOTYP(static VOID lostpeer, (void));
-_PROTOTYP(static VOID cancel_remote, (int));
-_PROTOTYP(static VOID changetype, (int, int));
-
-_PROTOTYP(static sigtype cmdcancel, (int));
-
-#ifdef FTP_SRP
-_PROTOTYP(static int srp_reset, ());
-_PROTOTYP(static int srp_ftp_auth, (char *,char *,char *));
-_PROTOTYP(static int srp_put, (CHAR *, CHAR **, int, int *));
-_PROTOTYP(static int srp_get, (CHAR **, CHAR **, int *, int *));
-_PROTOTYP(static int srp_encode, (int, CHAR *, CHAR *, unsigned int));
-_PROTOTYP(static int srp_decode, (int, CHAR *, CHAR *, unsigned int));
-_PROTOTYP(static int srp_selcipher, (char *));
-_PROTOTYP(static int srp_selhash, (char *));
-#endif /* FTP_SRP */
-
-#ifdef FTP_GSSAPI
-_PROTOTYP(static void user_gss_error,(OM_uint32, OM_uint32,char *));
-#endif /* FTP_GSSAPI */
-
-/* D O F T P A R G -- Do an FTP command-line argument. */
-
-#ifdef FTP_SECURITY
-#ifndef NOICP
-#define FT_NOGSS 1
-#define FT_NOK4 2
-#define FT_NOSRP 3
-#define FT_NOSSL 4
-#define FT_NOTLS 5
-#define FT_CERTFI 6
-#define FT_OKCERT 7
-#define FT_DEBUG 8
-#define FT_KEY 9
-#define FT_SECURE 10
-#define FT_VERIFY 11
-
-static struct keytab ftpztab[] = {
- { "!gss", FT_NOGSS, 0 },
- { "!krb4", FT_NOK4, 0 },
- { "!srp", FT_NOSRP, 0 },
- { "!ssl", FT_NOSSL, 0 },
- { "!tls", FT_NOTLS, 0 },
- { "cert", FT_CERTFI, CM_ARG },
- { "certsok", FT_OKCERT, 0 },
- { "debug", FT_DEBUG, 0 },
- { "key", FT_KEY, CM_ARG },
- { "nogss", FT_NOGSS, 0 },
- { "nokrb4", FT_NOK4, 0 },
- { "nosrp", FT_NOSRP, 0 },
- { "nossl", FT_NOSSL, 0 },
- { "notls", FT_NOTLS, 0 },
-#ifdef COMMENT
- { "secure", FT_SECURE, 0 },
-#endif /* COMMENT */
- { "verify", FT_VERIFY, CM_ARG },
- { "", 0, 0 }
-};
-static int nftpztab = sizeof(ftpztab) / sizeof(struct keytab) - 1;
-
-/*
- The following cipher and hash tables should be replaced with
- dynamicly created versions based upon the linked library.
-*/
-#define SRP_BLOWFISH_ECB 1
-#define SRP_BLOWFISH_CBC 2
-#define SRP_BLOWFISH_CFB64 3
-#define SRP_BLOWFISH_OFB64 4
-#define SRP_CAST5_ECB 5
-#define SRP_CAST5_CBC 6
-#define SRP_CAST5_CFB64 7
-#define SRP_CAST5_OFB64 8
-#define SRP_DES_ECB 9
-#define SRP_DES_CBC 10
-#define SRP_DES_CFB64 11
-#define SRP_DES_OFB64 12
-#define SRP_DES3_ECB 13
-#define SRP_DES3_CBC 14
-#define SRP_DES3_CFB64 15
-#define SRP_DES3_OFB64 16
-
-static struct keytab ciphertab[] = {
- { "blowfish_ecb", SRP_BLOWFISH_ECB, 0 },
- { "blowfish_cbc", SRP_BLOWFISH_CBC, 0 },
- { "blowfish_cfb64", SRP_BLOWFISH_CFB64, 0 },
- { "blowfish_ofb64", SRP_BLOWFISH_OFB64, 0 },
- { "cast5_ecb", SRP_CAST5_ECB, 0 },
- { "cast5_cbc", SRP_CAST5_CBC, 0 },
- { "cast5_cfb64", SRP_CAST5_CFB64, 0 },
- { "cast5_ofb64", SRP_CAST5_OFB64, 0 },
- { "des_ecb", SRP_DES_ECB, 0 },
- { "des_cbc", SRP_DES_CBC, 0 },
- { "des_cfb64", SRP_DES_CFB64, 0 },
- { "des_ofb64", SRP_DES_OFB64, 0 },
- { "des3_ecb", SRP_DES3_ECB, 0 },
- { "des3_cbc", SRP_DES3_CBC, 0 },
- { "des3_cfb64", SRP_DES3_CFB64, 0 },
- { "des3_ofb64", SRP_DES3_OFB64, 0 },
- { "none", 0, 0 },
- { "", 0, 0 }
-};
-static int nciphertab = sizeof(ciphertab) / sizeof(struct keytab) - 1;
-
-#define SRP_MD5 1
-#define SRP_SHA 2
-static struct keytab hashtab[] = {
- { "md5", SRP_MD5, 0 },
- { "none", 0, 0 },
- { "sha", SRP_SHA, 0 },
- { "", 0, 0 }
-};
-static int nhashtab = sizeof(hashtab) / sizeof(struct keytab) - 1;
-#endif /* NOICP */
-#endif /* FTP_SECURITY */
-
-static char *
-strval(s1,s2) char * s1, * s2; {
- if (!s1) s1 = "";
- if (!s2) s2 = "";
- return(*s1 ? s1 : (*s2 ? s2 : "(none)"));
-}
-
-#ifndef NOCSETS
-static char * rfnptr = NULL;
-static int rfnlen = 0;
-static char rfnbuf[RFNBUFSIZ]; /* Remote filename translate buffer */
-static char * xgnbp = NULL;
-
-static int
-strgetc() { /* Helper function for xgnbyte() */
- int c;
- if (!xgnbp)
- return(-1);
- if (!*xgnbp)
- return(-1);
- c = (unsigned) *xgnbp++;
- return(((unsigned) c) & 0xff);
-}
-
-static int /* Helper function for xpnbyte() */
-#ifdef CK_ANSIC
-strputc(char c)
-#else
-strputc(c) char c;
-#endif /* CK_ANSIC */
-{
- rfnlen = rfnptr - rfnbuf;
- if (rfnlen >= (RFNBUFSIZ - 1))
- return(-1);
- *rfnptr++ = c;
- *rfnptr = NUL;
- return(0);
-}
-
-static int
-#ifdef CK_ANSIC
-xprintc(char c)
-#else
-xprintc(c) char c;
-#endif /* CK_ANSIC */
-{
- printf("%c",c);
- return(0);
-}
-
-static VOID
-bytswap(c0,c1) int * c0, * c1; {
- int t;
- t = *c0;
- *c0 = *c1;
- *c1 = t;
-}
-#endif /* NOCSETS */
-
-#ifdef CKLOGDIAL
-char ftplogbuf[CXLOGBUFL] = { NUL, NUL }; /* Connection Log */
-int ftplogactive = 0;
-long ftplogprev = 0L;
-
-VOID
-ftplogend() {
- extern int dialog;
- extern char diafil[];
- long d1, d2, t1, t2;
- char buf[32], * p;
-
- debug(F111,"ftp cx log active",ckitoa(dialog),ftplogactive);
- debug(F110,"ftp cx log buf",ftplogbuf,0);
-
- if (!ftplogactive || !ftplogbuf[0]) /* No active record */
- return;
-
- ftplogactive = 0; /* Record is not active */
-
- d1 = mjd((char *)ftplogbuf); /* Get start date of this session */
- ckstrncpy(buf,ckdate(),31); /* Get current date */
- d2 = mjd(buf); /* Convert them to mjds */
- p = ftplogbuf; /* Get start time */
- p[11] = NUL;
- p[14] = NUL; /* Convert to seconds */
- t1 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
- p[11] = ':';
- p[14] = ':';
- p = buf; /* Get end time */
- p[11] = NUL;
- p[14] = NUL;
- t2 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
- t2 = ((d2 - d1) * 86400L) + (t2 - t1); /* Compute elapsed time */
- if (t2 > -1L) {
- ftplogprev = t2;
- p = hhmmss(t2);
- ckstrncat(ftplogbuf,"E=",CXLOGBUFL); /* Append to log record */
- ckstrncat(ftplogbuf,p,CXLOGBUFL);
- } else
- ftplogprev = 0L;
- debug(F101,"ftp cx log dialog","",dialog);
- if (dialog) { /* If logging */
- int x;
- x = diaopn(diafil,1,1); /* Open log in append mode */
- if (x > 0) {
- debug(F101,"ftp cx log open","",x);
- x = zsoutl(ZDIFIL,ftplogbuf); /* Write the record */
- debug(F101,"ftp cx log write","",x);
- x = zclose(ZDIFIL); /* Close the log */
- debug(F101,"ftp cx log close","",x);
- }
- }
-}
-
-VOID
-dologftp() {
- ftplogend(); /* Previous session not closed out? */
- ftplogprev = 0L;
- ftplogactive = 1; /* Record is active */
-
- ckmakxmsg(ftplogbuf,CXLOGBUFL,
- ckdate()," ",strval(ftp_logname,NULL)," ",ckgetpid(),
- " T=FTP N=", strval(ftp_host,NULL)," H=",myhost,
- " P=", ckitoa(ftp_port)," "); /* SMS 2007/02/15 */
- debug(F110,"ftp cx log begin",ftplogbuf,0);
-}
-#endif /* CKLOGDIAL */
-
-static char * dummy[2] = { NULL, NULL };
-
-static struct keytab modetab[] = {
- { "active", 0, 0 },
- { "passive", 1, 0 }
-};
-
-#ifndef NOCMDL
-int /* Called from ckuusy.c */
-#ifdef CK_ANSIC
-doftparg(char c)
-#else
-doftparg(c) char c;
-#endif /* CK_ANSIC */
-/* doftparg */ {
- int x, z;
- char *xp;
- extern char **xargv, *xarg0;
- extern int xargc, stayflg, haveftpuid;
- extern char uidbuf[];
-
- xp = *xargv+1; /* Pointer for bundled args */
- while (c) {
- if (ckstrchr("MuDPkcHzm",c)) { /* Options that take arguments */
- if (*(xp+1)) {
- fatal("?Invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- fatal("?Required argument missing");
- }
- }
- switch (c) { /* Big switch on arg */
- case 'h': /* help */
- printf("C-Kermit's FTP client command-line personality. Usage:\n");
- printf(" %s [ options ] host [ port ] [-pg files ]\n\n",xarg0);
- printf("Options:\n");
- printf(" -h = help (this message)\n");
- printf(" -m mode = \"passive\" (default) or \"active\"\n");
- printf(" -u name = username for autologin (or -M)\n");
- printf(" -P password = password for autologin (RISKY)\n");
- printf(" -A = autologin anonymously\n");
- printf(" -D directory = cd after autologin\n");
- printf(" -b = force binary mode\n");
- printf(" -a = force text (\"ascii\") mode (or -T)\n");
- printf(" -d = debug (double to add timestamps)\n");
- printf(" -n = no autologin\n");
- printf(" -v = verbose (default)\n");
- printf(" -q = quiet\n");
- printf(" -S = Stay (issue command prompt when done)\n");
- printf(" -Y = do not execute Kermit init file\n");
- printf(" -p files = files to put after autologin (or -s)\n");
- printf(" -g files = files to get after autologin\n");
- printf(" -R = recursive (for use with -p)\n");
-
-#ifdef FTP_SECURITY
- printf("\nSecurity options:\n");
- printf(" -k realm = Kerberos 4 realm\n");
- printf(" -f = Kerboros 5 credentials forwarding\n");
- printf(" -x = autoencryption mode\n");
- printf(" -c cipher = SRP cipher type\n");
- printf(" -H hash = SRP encryption hash\n");
- printf(" -z option = Security options\n");
-#endif /* FTP_SECURITY */
-
- printf("\n-p or -g, if given, should be last. Example:\n");
- printf(" ftp -A kermit.columbia.edu -D kermit -ag TESTFILE\n");
-
- doexit(GOOD_EXIT,-1);
- break;
-
- case 'R': /* Recursive */
- recursive = 1;
- break;
-
- case 'd': /* Debug */
-#ifdef DEBUG
- if (deblog) {
- extern int debtim;
- debtim = 1;
- } else {
- deblog = debopn("debug.log",0);
- debok = 1;
- }
-#endif /* DEBUG */
- /* fall thru on purpose */
-
- case 't': /* Trace */
- ftp_deb++;
- break;
-
- case 'n': /* No autologin */
- ftp_log = 0;
- break;
-
- case 'i': /* No prompt */
- case 'v': /* Verbose */
- break; /* (ignored) */
-
- case 'q': /* Quiet */
- quiet = 1;
- break;
-
- case 'S': /* Stay */
- stayflg = 1;
- break;
-
- case 'M':
- case 'u': /* My User Name */
- if ((int)strlen(*xargv) > 63) {
- fatal("username too long");
- }
- ckstrncpy(uidbuf,*xargv,UIDBUFLEN);
- haveftpuid = 1;
- break;
-
- case 'A':
- ckstrncpy(uidbuf,"anonymous",UIDBUFLEN);
- haveftpuid = 1;
- break;
-
- case 'T': /* Text */
- case 'a': /* "ascii" */
- case 'b': /* Binary */
- binary = (c == 'b') ? FTT_BIN : FTT_ASC;
- ftp_xfermode = XMODE_M;
- filepeek = 0;
- patterns = 0;
- break;
-
- case 'g': /* Get */
- case 'p': /* Put */
- case 's': { /* Send (= Put) */
- int havefiles, rc;
- if (ftp_action) {
- fatal("Only one FTP action at a time please");
- }
- if (*(xp+1)) {
- fatal("invalid argument bundling after -s");
- }
- nfils = 0; /* Initialize file counter */
- havefiles = 0; /* Assume nothing to send */
- cmlist = xargv + 1; /* Remember this pointer */
-
- while (++xargv, --xargc > 0) { /* Traverse the list */
- if (c == 'g') {
- havefiles++;
- nfils++;
- continue;
- }
-#ifdef RECURSIVE
- if (!strcmp(*xargv,".")) {
- havefiles = 1;
- nfils++;
- recursive = 1;
- } else
-#endif /* RECURSIVE */
- if ((rc = zchki(*xargv)) > -1 || (rc == -2)) {
- if (rc != -2)
- havefiles = 1;
- nfils++;
- } else if (iswild(*xargv) && nzxpand(*xargv,0) > 0) {
- havefiles = 1;
- nfils++;
- }
- }
- xargc++, xargv--; /* Adjust argv/argc */
- if (!havefiles) {
- if (c == 'g') {
- fatal("No files to put");
- } else {
- fatal("No files to get");
- }
- }
- ftp_action = c;
- break;
- }
- case 'D': /* Directory */
- makestr(&ftp_rdir,*xargv);
- break;
-
- case 'm': /* Mode (Active/Passive */
- ftp_psv = lookup(modetab,*xargv,2,NULL);
- if (ftp_psv < 0) fatal("Invalid mode");
- break;
-
- case 'P':
- makestr(&ftp_tmp,*xargv); /* You-Know-What */
- break;
-
- case 'Y': /* No initialization file */
- break; /* (already done in prescan) */
-
-#ifdef CK_URL
- case 'U': { /* URL */
- /* These are set by urlparse() - any not set are NULL */
- if (g_url.hos) {
-/*
- Kermit has accepted host:port notation since many years before URLs were
- invented. Unfortunately, URLs conflict with this notation. Thus "ftp
- host:449" looks like a URL and results in service = host and host = 449.
- Here we try to catch this situation transparently to the user.
-*/
- if (ckstrcmp(g_url.svc,"ftp",-1,0)
-#ifdef CK_SSL
- && ckstrcmp(g_url.svc,"ftps",-1,0)
-#endif /* CK_SSL */
- ) {
- if (!g_url.usr &&
- !g_url.psw &&
- !g_url.por &&
- !g_url.pth) {
- g_url.por = g_url.hos;
- g_url.hos = g_url.svc;
- g_url.svc = "ftp";
- } else {
- ckmakmsg(tmpbuf,TMPBUFSIZ,"Non-FTP URL: service=",
- g_url.svc," host=",g_url.hos);
- fatal(tmpbuf);
- }
- }
- makestr(&ftp_host,g_url.hos);
- if (g_url.usr) {
- haveftpuid = 1;
- ckstrncpy(uidbuf,g_url.usr,UIDBUFLEN);
- makestr(&ftp_logname,uidbuf);
- }
- if (g_url.psw) {
- makestr(&ftp_tmp,g_url.psw);
- }
- if (g_url.pth) {
- if (!g_url.usr) {
- haveftpuid = 1;
- ckstrncpy(uidbuf,"anonymous",UIDBUFLEN);
- makestr(&ftp_logname,uidbuf);
- }
- if (ftp_action) {
- fatal("Only one FTP action at a time please");
- }
- if (!stayflg)
- quiet = 1;
- nfils = 1;
- dummy[0] = g_url.pth;
- cmlist = dummy;
- ftp_action = 'g';
- }
- xp = NULL;
- haveurl = 1;
- }
- break;
- }
-#endif /* CK_URL */
-
-#ifdef FTP_SECURITY
- case 'k': { /* K4 Realm */
-#ifdef FTP_KRB4
- ckstrncpy(ftp_realm,*xargv, REALM_SZ);
-#endif /* FTP_KRB4 */
- if (ftp_deb) printf("K4 Realm = [%s]\n",*xargv);
- break;
- }
- case 'f': {
-#ifdef FTP_GSSAPI
- ftp_cfw = 1;
- if (ftp_deb) printf("K5 Credentials Forwarding\n");
-#else /* FTP_GSSAPI */
- printf("K5 Credentials Forwarding not supported\n");
-#endif /* FTP_GSSAPI */
- break;
- }
- case 'x': {
- ftp_cry = 1;
- if (ftp_deb) printf("Autoencryption\n");
- break;
- }
- case 'c': { /* Cipher */
-#ifdef FTP_SRP
- if (!srp_selcipher(*xargv)) {
- if (ftp_deb) printf("SRP cipher type: \"%s\"\n",*xargv);
- } else
- printf("?Invalid SRP cipher type: \"%s\"\n",*xargv);
-#else /* FTP_SRP */
- printf("?SRP not supported\n");
-#endif /* FTP_SRP */
- break;
- }
- case 'H': {
-#ifdef FTP_SRP
- if (!srp_selhash(*xargv)) {
- if (ftp_deb) printf("SRP hash type: \"%s\"\n",*xargv);
- } else
- printf("?Invalid SRP hash type: \"%s\"\n",*xargv);
-#else /* FTP_SRP */
- printf("?SRP not supported\n");
-#endif /* FTP_SRP */
- break;
- }
- case 'z': {
- /* *xargv contains a value of the form tag=value */
- /* we need to lookup the tag and save the value */
- char * p = NULL, * q = NULL;
- makestr(&p,*xargv);
- y = ckindex("=",p,0,0,1);
- if (y > 0)
- p[y-1] = '\0';
- x = lookup(ftpztab,p,nftpztab,&z);
- if (x < 0) {
- printf("?Invalid security option: \"%s\"\n",p);
- } else {
- if (ftp_deb)
- printf("Security option: \"%s",p);
- if (ftpztab[z].flgs & CM_ARG) {
- if (y <= 0)
- fatal("?Missing required value");
- q = &p[y];
- if (!*q)
- fatal("?Missing required value");
- if (ftp_deb)
- printf("=%s\"",q);
- }
- switch (ftpztab[z].kwval) { /* -z options w/args */
- case FT_NOGSS:
-#ifdef FTP_GSSAPI
- for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) {
- if (ftp_auth_type[z] == FTA_GK5) {
- for (y = z;
- y < (FTPATYPS-1) && ftp_auth_type[y];
- y++
- )
- ftp_auth_type[y] = ftp_auth_type[y+1];
- ftp_auth_type[FTPATYPS-1] = 0;
- break;
- }
- }
-#endif /* FTP_GSSAPI */
- break;
- case FT_NOK4:
-#ifdef FTP_KRB4
- for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) {
- if (ftp_auth_type[z] == FTA_K4) {
- for (y = z;
- y < (FTPATYPS-1) && ftp_auth_type[y];
- y++
- )
- ftp_auth_type[y] = ftp_auth_type[y+1];
- ftp_auth_type[FTPATYPS-1] = 0;
- break;
- }
- }
-#endif /* FTP_KRB4 */
- break;
- case FT_NOSRP:
-#ifdef FTP_SRP
- for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) {
- if (ftp_auth_type[z] == FTA_SRP) {
- for (y = z;
- y < (FTPATYPS-1) && ftp_auth_type[y];
- y++
- )
- ftp_auth_type[y] = ftp_auth_type[y+1];
- ftp_auth_type[FTPATYPS-1] = 0;
- break;
- }
- }
-#endif /* FTP_SRP */
- break;
- case FT_NOSSL:
-#ifdef CK_SSL
- for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) {
- if (ftp_auth_type[z] == FTA_SSL) {
- for (y = z;
- y < (FTPATYPS-1) && ftp_auth_type[y];
- y++
- )
- ftp_auth_type[y] = ftp_auth_type[y+1];
- ftp_auth_type[FTPATYPS-1] = 0;
- break;
- }
- }
-#endif /* CK_SSL */
- break;
- case FT_NOTLS:
-#ifdef CK_SSL
- for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) {
- if (ftp_auth_type[z] == FTA_TLS) {
- for (y = z;
- y < (FTPATYPS-1) && ftp_auth_type[y];
- y++
- )
- ftp_auth_type[y] = ftp_auth_type[y+1];
- ftp_auth_type[FTPATYPS-1] = 0;
- break;
- }
- }
-#endif /* CK_SSL */
- break;
- case FT_CERTFI:
-#ifdef CK_SSL
- makestr(&ssl_rsa_cert_file,q);
-#endif /* CK_SSL */
- break;
- case FT_OKCERT:
-#ifdef CK_SSL
- ssl_certsok_flag = 1;
-#endif /* CK_SSL */
- break;
- case FT_DEBUG:
-#ifdef DEBUG
- if (deblog) {
- extern int debtim;
- debtim = 1;
- } else {
- deblog = debopn("debug.log",0);
- }
-#endif /* DEBUG */
- break;
- case FT_KEY:
-#ifdef CK_SSL
- makestr(&ssl_rsa_key_file,q);
-#endif /* CK_SSL */
- break;
- case FT_SECURE:
- /* no equivalent */
- break;
- case FT_VERIFY:
-#ifdef CK_SSL
- if (!rdigits(q))
- printf("?Bad number: %s\n",q);
- ssl_verify_flag = atoi(q);
-#endif /* CK_SSL */
- break;
- }
- }
- if (ftp_deb) printf("\"\n");
- free(p);
- break;
- }
-#endif /* FTP_SECURITY */
-
- default:
- fatal2(*xargv,
- "unknown command-line option, type \"ftp -h\" for help"
- );
- }
- if (!xp) break;
- c = *++xp; /* See if options are bundled */
- }
- return(0);
-}
-#endif /* NOCMDL */
-
-int
-ftpisconnected() {
- return(connected);
-}
-
-int
-ftpisloggedin() {
- return(connected ? loggedin : 0);
-}
-
-int
-ftpissecure() {
- return((ftp_dpl == FPL_CLR && !ssl_ftp_proxy) ? 0 : 1);
-}
-
-static VOID
-ftscreen(n, c, z, s) int n; char c; CK_OFF_T z; char * s; {
- if (displa && fdispla && !backgrd && !quiet && !out2screen) {
- if (!dpyactive) {
- ckscreen(SCR_PT,'S',(CK_OFF_T)0,"");
- dpyactive = 1;
- }
- ckscreen(n,c,z,s);
- }
-}
-
-#ifndef OS2
-/* g m s t i m e r -- Millisecond timer */
-
-long
-gmstimer() {
-#ifdef HAVE_MSECS
- /* For those versions of ztime() that also set global ztmsec. */
- char *p = NULL;
- long z;
- ztime(&p);
- if (!p) return(0L);
- if (!*p) return(0L);
- z = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
- return(z * 1000 + ztmsec);
-#else
- return((long)time(NULL) * 1000L);
-#endif /* HAVE_MSECS */
-}
-#endif /* OS2 */
-
-/* d o s e t f t p -- The SET FTP command */
-
-int
-dosetftp() {
- int cx;
- if ((cx = cmkey(ftpset,nftpset,"","",xxstring)) < 0) /* Set what? */
- return(cx);
- switch (cx) {
-
- case FTS_FNC: /* Filename collision action */
- if ((x = cmkey(ftpcolxtab,nftpcolx,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ftp_fnc = x;
- return(1);
-
- case FTS_CNV: /* Filename conversion */
- if ((x = cmkey(fntab,nfntab,"","automatic",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ftp_cnv = x;
- return(1);
-
- case FTS_DBG: /* Debug messages */
- return(seton(&ftp_deb));
-
- case FTS_LOG: /* Auto-login */
- return(seton(&ftp_log));
-
- case FTS_PSV: /* Passive mode */
- return(dosetftppsv());
-
- case FTS_SPC: /* Send port commands */
- x = seton(&ftp_spc);
- if (x > 0) sendport = ftp_spc;
- return(x);
-
- case FTS_TYP: /* Type */
- if ((x = cmkey(ftptyp,nftptyp,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- ftp_typ = x;
- g_ftp_typ = x;
- tenex = (ftp_typ == FTT_TEN);
- return(1);
-
- case FTS_USN: /* Unique server names */
- return(seton(&ftp_usn));
-
- case FTS_VBM: /* Verbose mode */
- if ((x = seton(&ftp_vbm)) < 0) /* Per-command copy */
- return(x);
- ftp_vbx = ftp_vbm; /* Global sticky copy */
- return(x);
-
- case FTS_TST: /* "if (testing)" messages */
- return(seton(&testing));
-
- case FTS_PRM: /* Send permissions */
- return(setonaut(&ftp_prm));
-
- case FTS_AUT: /* Auto-authentication */
- return(seton(&ftp_aut));
-
- case FTS_ERR: /* Error action */
- if ((x = cmkey(qorp,2,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ftp_err = x;
- return(success = 1);
-
-#ifndef NOCSETS
- case FTS_XLA: /* Translation */
- return(seton(&ftp_xla));
-
- case FTS_CSR: /* Server charset */
- if ((x = cmkey(fcstab,nfilc,"character-set","utf8",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ftp_csr = x;
- ftp_xla = 1; /* Also enable translation */
- return(success = 1);
-#endif /* NOCSETS */
-
- case FTS_GFT:
- return(seton(&get_auto)); /* GET-filetype-switching */
-
- case FTS_DAT:
- return(seton(&ftp_dates)); /* Set file dates */
-
-#ifdef FTP_TIMEOUT
- case FTS_TMO: /* Timeout */
- if ((x = cmnum("Number of seconds","0",10,&z,xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ftp_timeout = z;
- return(success = 1);
-#endif /* FTP_TIMEOUT */
-
- case FTS_STO: { /* Server time offset */
- char * s, * p = NULL;
- long k;
- if ((x = cmfld("[+-]hh[:mm[:ss]]","+0",&s,xxstring)) < 0)
- return(x);
- if (!strcmp(s,"+0")) {
- s = NULL;
- } else if ((x = delta2sec(s,&k)) < 0) { /* Check format */
- printf("?Invalid time offset\n");
- return(-9);
- }
- makestr(&p,s); /* Make a safe copy the string */
- if ((x = cmcfm()) < 0) { /* Get confirmation */
- if (p)
- makestr(&p,NULL);
- return(x);
- }
- fts_sto = p; /* Confirmed - set the string. */
- return(success = 1);
- }
- case FTS_APW: {
- char * s;
- if ((x = cmtxt("Text", "", &s, xxstring)) < 0)
- return(x);
- makestr(&ftp_apw, *s ? s : NULL);
- return(success = 1);
- }
-
- case FTS_BUG: {
- if ((x = cmkey(ftpbugtab,nftpbug,"","",xxstring)) < 0)
- return(x);
- switch (x) {
-#ifdef CK_SSL
- case FTB_SV2:
- return seton(&ftp_bug_use_ssl_v2);
-#endif /* CK_SSL */
- default:
- return(-2);
- }
- }
-
-#ifdef FTP_SECURITY
- case FTS_CRY: /* Auto-encryption */
- return(seton(&ftp_cry));
-
- case FTS_CFW: /* Credential-forwarding */
- return(seton(&ftp_cfw));
-
- case FTS_CPL: /* Command protection level */
- if ((x = cmkey(ftppro,nftppro,"","",xxstring)) < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
- success = fts_cpl(x);
- return(success);
-
- case FTS_DPL: /* Data protection level */
- if ((x = cmkey(ftppro,nftppro,"","",xxstring)) < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
- success = fts_dpl(x);
- return(success);
-
- case FTS_ATP: { /* FTP Auth Type */
- int i, j, atypes[8];
-
- for (i = 0; i < 8; i++) {
- if ((y = cmkey(ftpauth,nftpauth,"",
- (i == 0) ? "automatic" : "",
- xxstring)) < 0) {
- if (y == -3)
- break;
- return(y);
- }
- if (i > 0 && (y == FTA_AUTO)) {
- printf("?Choice may only be used in first position.\r\n");
- return(-9);
- }
- for (j = 0; j < i; j++) {
- if (atypes[j] == y) {
- printf("\r\n?Choice has already been used.\r\n");
- return(-9);
- }
- }
- atypes[i] = y;
- if (y == FTA_AUTO) {
- i++;
- break;
- }
- }
- if (i < 8)
- atypes[i] = 0;
- if ((z = cmcfm()) < 0)
- return(z);
- if (atypes[0] == FTA_AUTO) {
- i = 0;
-#ifdef FTP_GSSAPI
- ftp_auth_type[i++] = FTA_GK5;
-#endif /* FTP_GSSAPI */
-#ifdef FTP_SRP
- ftp_auth_type[i++] = FTA_SRP;
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- ftp_auth_type[i++] = FTA_K4;
-#endif /* FTP_KRB4 */
-#ifdef CK_SSL
- ftp_auth_type[i++] = FTA_TLS;
- ftp_auth_type[i++] = FTA_SSL;
-#endif /* CK_SSL */
- ftp_auth_type[i] = 0;
- } else {
- for (i = 0; i < 8; i++)
- ftp_auth_type[i] = atypes[i];
- }
- return(success = 1);
- }
-
- case FTS_SRP:
-#ifdef FTP_SRP
- if ((x = cmkey(ftpsrp,nftpsrp,"","",xxstring)) < 0)
- return(x);
- switch (x) {
- case SRP_CIPHER:
- if ((x = cmkey(ciphertab,nciphertab,"","",xxstring)) < 0)
- return(x);
- if ((z = cmcfm()) < 0)
- return(z);
- success = !srp_selcipher(ciphertab[x].kwd);
- return(success);
- case SRP_HASH:
- if ((x = cmkey(hashtab,nhashtab,"","",xxstring)) < 0)
- return(x);
- if ((z = cmcfm()) < 0)
- return(z);
- success = !srp_selhash(hashtab[x].kwd);
- return(success = 1);
- default:
- if ((z = cmcfm()) < 0)
- return(z);
- return(-2);
- }
-#else /* FTP_SRP */
- if ((z = cmcfm()) < 0)
- return(z);
- return(-2);
-#endif /* FTP_SRP */
-#endif /* FTP_SECURITY */
-
- case FTS_DIS:
- doxdis(2); /* 2 == ftp */
- return(success = 1);
-
- default:
- return(-2);
- }
-}
-
-int
-ftpbye() {
- int x;
- if (!connected)
- return(1);
- if (testing)
- printf(" ftp closing %s...\n",ftp_host);
- x = ftpclose();
- return((x > -1) ? 1 : 0);
-}
-
-/* o p e n f t p -- Parse FTP hostname & port and open */
-
-static int
-openftp(s,opn_tls) char * s; int opn_tls; {
- char c, * p, * hostname = NULL, *hostsave = NULL, * service = NULL;
- int i, n, havehost = 0, getval = 0, rc = -9, opn_psv = -1, nologin = 0;
- int haveuser = 0;
- struct FDB sw, fl, cm;
- extern int nnetdir; /* Network services directory */
- extern int nhcount; /* Lookup result */
- extern char *nh_p[]; /* Network directory entry pointers */
- extern char *nh_p2[]; /* Network directory entry nettype */
-
- if (!s) return(-2);
- if (!*s) return(-2);
-
- makestr(&hostname,s);
- hostsave = hostname;
- makestr(&ftp_logname,NULL);
- anonymous = 0;
- noinit = 0;
-
- debug(F110,"ftp open",hostname,0);
-
- if (sav_psv > -1) { /* Restore prevailing active/passive */
- ftp_psv = sav_psv; /* selection in case it was */
- sav_psv = -1; /* temporarily overriden by a switch */
- }
- if (sav_log > -1) { /* Ditto for autologin */
- ftp_log = sav_log;
- sav_log = -1;
- }
- cmfdbi(&sw, /* Switches */
- _CMKEY,
- "Service name or port;\n or switch",
- "", /* default */
- "", /* addtl string data */
- nftpswi, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: none */
- xxstring, /* Processing function */
- ftpswitab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* A host name or address */
- _CMFLD, /* fcode */
- "", /* help */
- "xYzBoo", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* Command confirmation */
- _CMCFM,
- "",
- "",
- "",
- 0,
- 0,
- NULL,
- NULL,
- NULL
- );
-
- for (n = 0;; n++) {
- rc = cmfdb(&sw); /* Parse a service name or a switch */
- if (rc < 0)
- goto xopenftp;
-
- if (cmresult.fcode == _CMCFM) { /* Done? */
- break;
- } else if (cmresult.fcode == _CMFLD) { /* Port */
- if (ckstrcmp("xYzBoo",cmresult.sresult,-1,1))
- makestr(&service,cmresult.sresult);
- else
- makestr(&service,opn_tls?"ftps":"ftp");
- } else if (cmresult.fcode == _CMKEY) { /* Have a switch */
- c = cmgbrk(); /* get break character */
- getval = (c == ':' || c == '=');
- rc = -9;
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- goto xopenftp;
- }
- if (!getval && (cmresult.kflags & CM_ARG)) {
- printf("?This switch requires an argument\n");
- goto xopenftp;
- }
- switch (cmresult.nresult) { /* Switch */
- case OPN_ANO: /* /ANONYMOUS */
- anonymous++;
- nologin = 0;
- break;
- case OPN_NIN: /* /NOINIT */
- noinit++;
- break;
- case OPN_NOL: /* /NOLOGIN */
- nologin++;
- anonymous = 0;
- makestr(&ftp_logname,NULL);
- break;
- case OPN_PSW: /* /PASSWORD */
- if (!anonymous) /* Don't log real passwords */
- debok = 0;
- rc = cmfld("Password for FTP server","",&p,xxstring);
- if (rc == -3) {
- makestr(&ftp_tmp,NULL);
- } else if (rc < 0) {
- goto xopenftp;
- } else {
- makestr(&ftp_tmp,brstrip(p));
- nologin = 0;
- }
- break;
- case OPN_USR: /* /USER */
- rc = cmfld("Username for FTP server","",&p,xxstring);
- if (rc == -3) {
- makestr(&ftp_logname,NULL);
- } else if (rc < 0) {
- goto xopenftp;
- } else {
- nologin = 0;
- anonymous = 0;
- haveuser = 1;
- makestr(&ftp_logname,brstrip(p));
- }
- break;
- case OPN_ACC:
- rc = cmfld("Account for FTP server","",&p,xxstring);
- if (rc == -3) {
- makestr(&ftp_acc,NULL);
- } else if (rc < 0) {
- goto xopenftp;
- } else {
- makestr(&ftp_acc,brstrip(p));
- }
- break;
- case OPN_ACT:
- opn_psv = 0;
- break;
- case OPN_PSV:
- opn_psv = 1;
- break;
- case OPN_TLS:
- opn_tls = 1;
- break;
- default:
- break;
- }
- }
- if (n == 0) { /* After first time through */
- cmfdbi(&sw, /* accept only switches */
- _CMKEY,
- "\nCarriage return to confirm to command, or switch",
- "",
- "",
- nftpswi,
- 4,
- xxstring,
- ftpswitab,
- &cm
- );
- }
- }
-#ifdef COMMENT
- debug(F100,"ftp openftp while exit","",0);
- rc = cmcfm();
- debug(F101,"ftp openftp cmcfm rc","",rc);
- if (rc < 0)
- goto xopenftp;
-#endif /* COMMENT */
-
- if (opn_psv > -1) { /* /PASSIVE or /ACTIVE switch given */
- sav_psv = ftp_psv;
- ftp_psv = opn_psv;
- }
- if (nologin || haveuser) { /* /NOLOGIN or /USER switch given */
- sav_log = ftp_log;
- ftp_log = haveuser ? 1 : 0;
- }
- if (*hostname == '=') { /* Bypass directory lookup */
- hostname++; /* if hostname starts with '=' */
- havehost++;
- } else if (isdigit(*hostname)) { /* or if it starts with a digit */
- havehost++;
- }
- if (!service)
- makestr(&service,opn_tls?"ftps":"ftp");
-
-#ifndef NODIAL
- if (!havehost && nnetdir > 0) { /* If there is a networks directory */
- lunet(hostname); /* Look up the name */
- debug(F111,"ftp openftp lunet",hostname,nhcount);
- if (nhcount == 0) {
- if (testing)
- printf(" ftp open trying \"%s %s\"...\n",hostname,service);
- success = ftpopen(hostname,service,opn_tls);
- debug(F101,"ftp openftp A ftpopen success","",success);
- rc = success;
- } else {
- int found = 0;
- for (i = 0; i < nhcount; i++) {
- if (nh_p2[i]) /* If network type specified */
- if (ckstrcmp(nh_p2[i],"tcp/ip",strlen(nh_p2[i]),0))
- continue;
- found++;
- makestr(&hostname,nh_p[i]);
- debug(F111,"ftpopen lunet substitution",hostname,i);
- if (testing)
- printf(" ftp open trying \"%s %s\"...\n",hostname,service);
- success = ftpopen(hostname,service,opn_tls);
- debug(F101,"ftp openftp B ftpopen success","",success);
- rc = success;
- if (success)
- break;
- }
- if (!found) { /* E.g. if no network types match */
- if (testing)
- printf(" ftp open trying \"%s %s\"...\n",hostname,service);
- success = ftpopen(hostname,service,opn_tls);
- debug(F101,"ftp openftp C ftpopen success","",success);
- rc = success;
- }
- }
- } else {
-#endif /* NODIAL */
- if (testing)
- printf(" ftp open trying \"%s %s\"...\n",hostname,service);
- success = ftpopen(hostname,service,opn_tls);
- debug(F111,"ftp openftp D ftpopen success",hostname,success);
- debug(F111,"ftp openftp D ftpopen connected",hostname,connected);
- rc = success;
-#ifndef NODIAL
- }
-#endif /* NODIAL */
-
- xopenftp:
- debug(F101,"ftp openftp xopenftp rc","",rc);
- if (hostsave) free(hostsave);
- if (service) free(service);
- if (rc < 0 && ftp_logname) {
- free(ftp_logname);
- ftp_logname = NULL;
- }
- if (ftp_tmp) {
- free(ftp_tmp);
- ftp_tmp = NULL;
- }
- return(rc);
-}
-
-VOID /* 12 Aug 2007 */
-doftpglobaltype(x) int x; {
- ftp_xfermode = XMODE_M; /* Set manual FTP transfer mode */
- ftp_typ = x; /* Used by top-level BINARY and */
- g_ftp_typ = x; /* ASCII commands. */
- get_auto = 0;
- forcetype = 1;
-}
-
-int
-doftpacct() {
- int x;
- char * s;
- if ((x = cmtxt("Remote account", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- makestr(&ftp_acc,brstrip(s));
- if (testing)
- printf(" ftp account: \"%s\"\n",ftp_acc);
- success = (ftpcmd("ACCT",ftp_acc,-1,-1,ftp_vbm) == REPLY_COMPLETE);
- return(success);
-}
-
-int
-doftpusr() { /* Log in as USER */
- extern char uidbuf[];
- extern char pwbuf[];
- extern int pwflg, pwcrypt;
- int x;
- char *s, * acct = "";
-
- debok = 0; /* Don't log */
-
- if ((x = cmfld("Remote username or ID",uidbuf,&s,xxstring)) < 0)
- return(x);
- ckstrncpy(line,brstrip(s),LINBUFSIZ); /* brstrip: 15 Jan 2003 */
- if ((x = cmfld("Remote password","",&s,xxstring)) < 0) {
- if (x == -3) { /* no input */
- if ( pwbuf[0] && pwflg ) {
- ckstrncpy(tmpbuf,(char *)pwbuf,TMPBUFSIZ);
-#ifdef OS2
- if ( pwcrypt )
- ck_encrypt((char *)tmpbuf);
-#endif /* OS2 */
- }
- } else {
- return(x);
- }
- } else {
- ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
- }
- if ((x = cmtxt("Remote account\n or Enter or CR to confirm the command",
- "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- if (*s) {
- x = strlen(tmpbuf);
- if (x > 0) {
- acct = &tmpbuf[x+2];
- ckstrncpy(acct,brstrip(s),TMPBUFSIZ - x - 2);
- }
- }
- if (testing)
- printf(" ftp user \"%s\" password \"%s\"...\n",line,tmpbuf);
- success = ftp_user(line,tmpbuf,acct);
-#ifdef CKLOGDIAL
- dologftp();
-#endif /* CKLOGDIAL */
- return(success);
-}
-
-/* DO (various FTP commands)... */
-
-int
-doftptyp(type) int type; { /* TYPE */
- CHECKCONN();
- ftp_typ = type;
- changetype(ftp_typ,ftp_vbm);
- debug(F101,"doftptyp changed type","",type);
- return(1);
-}
-
-static int
-doftpxmkd(s,vbm) char * s; int vbm; { /* MKDIR action */
- int lcs = -1, rcs = -1;
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
- debug(F110,"ftp doftpmkd",s,0);
- if (ftpcmd("MKD",s,lcs,rcs,vbm) == REPLY_COMPLETE)
- return(success = 1);
- if (ftpcode == 500 || ftpcode == 502) {
- if (!quiet)
- printf("MKD command not recognized, trying XMKD\n");
- if (ftpcmd("XMKD",s,lcs,rcs,vbm) == REPLY_COMPLETE)
- return(success = 1);
- }
- return(success = 0);
-}
-
-static int
-doftpmkd() { /* MKDIR parse */
- int x;
- char * s;
- if ((x = cmtxt("Remote directory name", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp mkdir \"%s\"...\n",line);
- return(success = doftpxmkd(line,-1));
-}
-
-static int
-doftprmd() { /* RMDIR */
- int x, lcs = -1, rcs = -1;
- char * s;
- if ((x = cmtxt("Remote directory", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp rmdir \"%s\"...\n",line);
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
- if (ftpcmd("RMD",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE)
- return(success = 1);
- if (ftpcode == 500 || ftpcode == 502) {
- if (!quiet)
- printf("RMD command not recognized, trying XMKD\n");
- success = (ftpcmd("XRMD",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE);
- } else
- success = 0;
- return(success);
-}
-
-static int
-doftpren() { /* RENAME */
- int x;
- char * s;
- if ((x = cmfld("Remote filename","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmfld("New name for remote file","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((x = cmcfm()) < 0)
- return(x);
- CHECKCONN();
- if (testing)
- printf(" ftp rename \"%s\" (to) \"%s\"...\n",line,tmpbuf);
- success = ftp_rename(line,tmpbuf);
- return(success);
-}
-
-int
-doftpres() { /* RESET (log out without close) */
- int x;
- if ((x = cmcfm()) < 0)
- return(x);
- CHECKCONN();
- if (testing)
- printf(" ftp reset...\n");
- return(success = ftp_reset());
-}
-
-static int
-doftpxhlp() { /* HELP */
- int x;
- char * s;
- if ((x = cmtxt("Command name", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp help \"%s\"...\n",line);
- /* No need to translate -- all FTP commands are ASCII */
- return(success = (ftpcmd("HELP",line,0,0,1) == REPLY_COMPLETE));
-}
-
-static int
-doftpdir(cx) int cx; { /* [V]DIRECTORY */
- int x, lcs = 0, rcs = 0, xlate = 0;
- char * p, * s, * m = "";
- if (cx == FTP_VDI) {
- switch (servertype) {
- case SYS_VMS:
- case SYS_DOS:
- case SYS_TOPS10:
- case SYS_TOPS20:
- m = "*.*";
- break;
- default:
- m = "*";
- }
- }
- if ((x = cmtxt("Remote filespec",m,&s,xxstring)) < 0)
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
-#ifdef NOCSETS
- xlate = 0;
-#else
- xlate = ftp_xla;
-#endif /* NOCSETS */
- line[0] = NUL;
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- CHECKCONN();
-
-#ifndef NOCSETS
- if (xlate) { /* SET FTP CHARACTER-SET-TRANSLATION */
- lcs = ftp_csl; /* Local charset */
- if (lcs < 0) lcs = fcharset;
- if (lcs < 0) xlate = 0;
- }
- if (xlate) { /* Still ON? */
- rcs = ftp_csx; /* Remote (Server) charset */
- if (rcs < 0) rcs = ftp_csr;
- if (rcs < 0) xlate = 0;
- }
-#endif /* NOCSETS */
-
- if (testing) {
- p = s;
- if (!p) p = "";
- if (*p)
- printf("Directory of files %s at %s:\n", line, ftp_host);
- else
- printf("Directory of files at %s:\n", ftp_host);
- }
- debug(F111,"doftpdir",s,cx);
-
- if (cx == FTP_DIR) {
- /* Translation of line[] is done inside recvrequest() */
- /* when it calls ftpcmd(). */
- return(success =
- (recvrequest("LIST","-",s,"wb",0,0,NULL,xlate,lcs,rcs) == 0));
- }
- success = 1; /* VDIR - one file at a time... */
- p = (char *)remote_files(1,(CHAR *)s,NULL,0); /* Get the file list */
- cancelgroup = 0;
- if (!ftp_vbm && !quiet)
- printlines = 1;
- while (p && !cancelfile && !cancelgroup) { /* STAT one file */
- if (ftpcmd("STAT",p,lcs,rcs,ftp_vbm) < 0) {
- success = 0;
- break;
- }
- p = (char *)remote_files(0,NULL,NULL,0); /* Get next file */
- debug(F110,"ftp vdir file",s,0);
- }
- return(success);
-}
-
-static int
-doftppwd() { /* PWD */
- int x, lcs = -1, rcs = -1;
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
- if ((x = cmcfm()) < 0)
- return(x);
- CHECKCONN();
- if (ftpcmd("PWD",NULL,lcs,rcs,1) == REPLY_COMPLETE) {
- success = 1;
- } else if (ftpcode == 500 || ftpcode == 502) {
- if (ftp_deb)
- printf("PWD command not recognized, trying XPWD\n");
- success = (ftpcmd("XPWD",NULL,lcs,rcs,1) == REPLY_COMPLETE);
- }
- return(success);
-}
-
-static int
-doftpcwd(s,vbm) char * s; int vbm; { /* CD (CWD) */
- int lcs = -1, rcs = -1;
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
-
- debug(F110,"ftp doftpcwd",s,0);
- if (ftpcmd("CWD",s,lcs,rcs,vbm) == REPLY_COMPLETE)
- return(success = 1);
- if (ftpcode == 500 || ftpcode == 502) {
- if (!quiet)
- printf("CWD command not recognized, trying XCWD\n");
- if (ftpcmd("XCWD",s,lcs,rcs,vbm) == REPLY_COMPLETE)
- return(success = 1);
- }
- return(success = 0);
-}
-
-static int
-doftpcdup() { /* CDUP */
- debug(F100,"ftp doftpcdup","",0);
- if (ftpcmd("CDUP",NULL,0,0,1) == REPLY_COMPLETE)
- return(success = 1);
- if (ftpcode == 500 || ftpcode == 502) {
- if (!quiet)
- printf("CDUP command not recognized, trying XCUP\n");
- if (ftpcmd("XCUP",NULL,0,0,1) == REPLY_COMPLETE)
- return(success = 1);
- }
- return(success = 0);
-}
-
-/* s y n c d i r -- Synchronizes client & server directories */
-
-/*
- Call with:
- local = pointer to pathname of local file to be sent.
- sim = 1 for simulation, 0 for real uploading.
- Returns 0 on failure, 1 on success.
-
- The 'local' argument is relative to the initial directory of the MPUT,
- i.e. the root of the tree being uploaded. If the directory of the
- argument file is different from the directory of the previous file
- (which is stored in global putpath[]), this routine does the appropriate
- CWDs, CDUPs, and/or MKDIRs to position the FTP server in the same place.
-*/
-static int cdlevel = 0, cdsimlvl = 0; /* Tree-level trackers */
-
-static int
-syncdir(local,sim) char * local; int sim; {
- char buf[CKMAXPATH+1];
- char tmp[CKMAXPATH+1];
- char msgbuf[CKMAXPATH+64];
- char c, * p = local, * s = buf, * q = buf, * psep, * ssep;
- int i, k = 0, done = 0, itsadir = 0, saveq;
-
- debug(F110,"ftp syncdir local (new)",local,0);
- debug(F110,"ftp syncdir putpath (old)",putpath,0);
-
- itsadir = isdir(local); /* Is the local file a directory? */
- saveq = quiet;
-
- while ((*s = *p)) { /* Copy the argument filename */
- if (++k == CKMAXPATH) /* so we can poke it. */
- return(-1);
- if (*s == '/') /* Pointer to rightmost dirsep */
- q = s;
- s++;
- p++;
- }
- if (!itsadir) /* If it's a regular file */
- *q = NUL; /* keep just the path part */
-
- debug(F110,"ftp syncdir buf",buf,0);
- if (!strcmp(buf,putpath)) { /* Same path as previous file? */
- if (itsadir) { /* This file is a directory? */
- if (doftpcwd(local,0)) { /* Try to CD to it */
- doftpcdup(); /* Worked - CD back up */
- } else if (sim) { /* Simulating... */
- if (fdispla == XYFD_B) {
- printf("WOULD CREATE DIRECTORY %s\n",local);
- } else if (fdispla) {
- ckmakmsg(msgbuf,CKMAXPATH,
- "WOULD CREATE DIRECTORY",local,NULL,NULL);
- ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,msgbuf);
- }
- /* See note above */
- return(0);
- } else if (!doftpxmkd(local,0)) { /* Can't CD - try to create */
- return(0);
- } else { /* Remote directory created OK */
- if (fdispla == XYFD_B) {
- printf("CREATED DIRECTORY %s\n",local);
- } else if (fdispla) {
- ckmakmsg(msgbuf,CKMAXPATH+64,
- "CREATED DIRECTORY ",local,NULL,NULL);
- ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,msgbuf);
- }
- }
- }
- debug(F110,"ftp syncdir no change",buf,0);
- return(1); /* Yes, done. */
- }
- ckstrncpy(tmp,buf,CKMAXPATH+1); /* Make a safe (pre-poked) copy */
- debug(F110,"ftp syncdir new path",buf,0); /* for later (see end) */
-
- p = buf; /* New */
- s = putpath; /* Old */
-
- debug(F110,"ftp syncdir A (old) s",s,0); /* Previous */
- debug(F110,"ftp syncdir A (new) p",p,0); /* New */
-
- psep = buf;
- ssep = putpath;
- while (*p != NUL && *s != NUL && *p == *s) {
- if (*p == '/') { psep = p+1; ssep = s+1; }
- p++,s++;
- }
- /*
- psep and ssep point to the first path segment that differs.
- We have to do as many CDUPs as there are path segments in ssep.
- then we have to do as many MKDs and CWDs as there are segments in psep.
- */
- s = ssep;
- p = psep;
-
- debug(F110,"ftp syncdir B (old) s",s,0); /* Previous */
- debug(F110,"ftp syncdir B (new) p",p,0); /* New */
-
- /* p and s now point to the leftmost spot where the paths differ */
-
- if (*s) { /* We have to back up */
- k = 1; /* How many levels counting this one */
- while ((c = *s++)) { /* Count dirseps remaining in prev */
- if (c == '/' && *s)
- k++;
- }
- debug(F101,"ftp syncdir levels up","",k);
-
- for (i = 1; i <= k; i++) { /* Do that many CDUPs */
- debug(F111,"ftp syncdir CDUP A",p,i);
- if (fdispla == XYFD_B)
- printf(" CDUP\n");
- if (sim && cdsimlvl) {
- cdsimlvl--;
- } else {
- if (!doftpcdup()) {
- quiet = saveq;
- return(0);
- }
- }
- cdlevel--;
- }
- if (!*p) /* If we don't have to go down */
- goto xcwd; /* we're done. */
- }
-#ifdef COMMENT
- while (p > buf && *p && *p != '/') /* If in middle of segment */
- p--; /* back up to beginning */
- if (*p == '/') /* and terminate there */
- p++;
-#endif /* COMMENT */
-
- debug(F110,"ftp syncdir NEW PATH",p,0);
-
- s = p; /* Point to start of new down path. */
- while (1) { /* Loop through characters. */
- if (*s == '/' || !*s) { /* Have a segment. */
- if (!*s) /* If end of string, */
- done++; /* after this segment we're done. */
- else
- *s = NUL; /* NUL out the separator. */
- if (*p) { /* If segment is not empty */
- debug(F110,"ftp syncdir down segment",p,0);
- if (!doftpcwd(p,0)) { /* Try to CD to it */
- if (sim) {
- if (fdispla == XYFD_B) {
- printf(" WOULD CREATE DIRECTORY %s\n",local);
- } else if (fdispla) {
- ckmakmsg(msgbuf,CKMAXPATH,
- "WOULD CREATE DIRECTORY",
- local,NULL,NULL);
- ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,msgbuf);
- }
- cdsimlvl++;
- } else {
- if (!doftpxmkd(p,0)) { /* Can't CD - try to create */
- debug(F110,"ftp syncdir mkdir failed",p,0);
-/*
- Suppose we are executing SEND /RECURSIVE. Locally we have a directory
- FOO but the remote has a regular file with the same name. We can't CD
- to it, can't MKDIR it either. There's no way out but to fail and let
- the user handle the problem.
-*/
- quiet = saveq;
- return(0);
- }
- debug(F110,"ftp syncdir mkdir OK",p,0);
- if (fdispla == XYFD_B) {
- printf(" CREATED DIRECTORY %s\n",p);
- } else if (fdispla) {
- ckmakmsg(msgbuf,CKMAXPATH,
- "CREATED DIRECTORY ",p,NULL,NULL);
- ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,msgbuf);
- }
- if (!doftpcwd(p,0)) { /* Try again to CD */
- debug(F110,"ftp syncdir CD failed",p,0);
- quiet = saveq;
- return(0);
- }
- if (fdispla == XYFD_B) printf(" CWD %s\n",p);
- debug(F110,"ftp syncdir CD OK",p,0);
- }
- }
- cdlevel++;
- }
- if (done) /* Quit if no next segment */
- break;
- p = s+1; /* Point to next segment */
- }
- s++; /* Point to next source char */
- }
-
- xcwd:
- ckstrncpy(putpath,tmp,CKMAXPATH+1); /* All OK - make this the new path */
- quiet = saveq;
- return(1);
-}
-
-#ifdef DOUPDATE
-#ifdef DEBUG
-static VOID
-dbtime(s,xx) char * s; struct tm * xx; { /* Write struct tm to debug log */
- if (deblog) {
- debug(F111,"ftp year ",s,xx->tm_year);
- debug(F111,"ftp month",s,xx->tm_mon);
- debug(F111,"ftp day ",s,xx->tm_mday);
- debug(F111,"ftp hour ",s,xx->tm_hour);
- debug(F111,"ftp min ",s,xx->tm_min);
- debug(F111,"ftp sec ",s,xx->tm_sec);
- }
-}
-#endif /* DEBUG */
-
-/* t m c o m p a r e -- Compare two struct tm's */
-
-/* Like strcmp() but for struct tm's */
-/* Returns -1 if xx < yy, 0 if they are equal, 1 if xx > yy */
-
-static int
-tmcompare(xx,yy) struct tm * xx, * yy; {
-
- if (xx->tm_year < yy->tm_year) /* First year less than second */
- return(-1);
- if (xx->tm_year > yy->tm_year) /* First year greater than second */
- return(1);
-
- /* Years are equal so compare months */
-
- if (xx->tm_mon < yy->tm_mon) /* And so on... */
- return(-1);
- if (xx->tm_mon > yy->tm_mon)
- return(1);
-
- if (xx->tm_mday < yy->tm_mday)
- return(-1);
- if (xx->tm_mday > yy->tm_mday)
- return(1);
-
- if (xx->tm_hour < yy->tm_hour)
- return(-1);
- if (xx->tm_hour > yy->tm_hour)
- return(1);
-
- if (xx->tm_min < yy->tm_min)
- return(-1);
- if (xx->tm_min > yy->tm_min)
- return(1);
-
- if (xx->tm_sec < yy->tm_sec)
- return(-1);
- if (xx->tm_sec > yy->tm_sec)
- return(1);
-
- return(0);
-}
-#endif /* DOUPDATE */
-
-#ifndef HAVE_TIMEGM /* For platforms that do not have timegm() */
-static CONST int MONTHDAYS[] = { /* Number of days in each month. */
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-/* Macro for whether a given year is a leap year. */
-#define ISLEAP(year) \
-(((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
-#endif /* HAVE_TIMEGM */
-
-/* m k u t i m e -- Like mktime() but argument is already UTC */
-
-static time_t
-#ifdef CK_ANSIC
-mkutime(struct tm * tm)
-#else
-mkutime(tm) struct tm * tm;
-#endif /* CK_ANSIC */
-/* mkutime */ {
-#ifdef HAVE_TIMEGM
- return(timegm(tm)); /* Have system service, use it. */
-#else
-/*
- Contributed by Russ Allbery (rra@stanford.edu), used by permission.
- Given a struct tm representing a calendar time in UTC, convert it to
- seconds since epoch. Returns (time_t) -1 if the time is not
- convertable. Note that this function does not canonicalize the provided
- struct tm, nor does it allow out-of-range values or years before 1970.
- Result should be identical with timegm().
-*/
- time_t result = 0;
- int i;
- /*
- We do allow some ill-formed dates, but we don't do anything special
- with them and our callers really shouldn't pass them to us. Do
- explicitly disallow the ones that would cause invalid array accesses
- or other algorithm problems.
- */
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"mkutime tm_mon","",tm->tm_mon);
- debug(F101,"mkutime tm_year","",tm->tm_year);
- }
-#endif /* DEBUG */
- if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 70)
- return((time_t) -1);
-
- /* Convert to time_t. */
- for (i = 1970; i < tm->tm_year + 1900; i++)
- result += 365 + ISLEAP(i);
- for (i = 0; i < tm->tm_mon; i++)
- result += MONTHDAYS[i];
- if (tm->tm_mon > 1 && ISLEAP(tm->tm_year + 1900))
- result++;
- result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
- result = 60 * result + tm->tm_min;
- result = 60 * result + tm->tm_sec;
- debug(F101,"mkutime result","",result);
- return(result);
-#endif /* HAVE_TIMEGM */
-}
-
-
-/*
- s e t m o d t i m e -- Set file modification time.
-
- f = char * filename;
- t = time_t date/time to set (Secs since 19700101 0:00:00 UTC, NOT local)
-
- UNIX-specific; isolates mainline code from hideous #ifdefs.
- Returns:
- 0 on success,
- -1 on error.
-
-*/
-static int
-#ifdef CK_ANSIC
-setmodtime(char * f, time_t t)
-#else
-setmodtime(f,t) char * f; time_t t;
-#endif /* CK_ANSIC */
-/* setmodtime */ {
-#ifdef NT
- struct _stat sb;
-#else /* NT */
- struct stat sb;
-#endif /* NT */
- int x, rc = 0;
-#ifdef BSD44
- struct timeval tp[2];
-#else /* def BSD44 */
-#ifdef V7
- struct utimbuf {
- time_t timep[2];
- } tp;
-#else /* def V7 */
-#ifdef SYSUTIMEH
-#ifdef NT
- struct _utimbuf tp;
-#else /* NT */
- struct utimbuf tp;
-#endif /* NT */
-#else /* def SYSUTIMEH */
-#ifdef VMS
- struct utimbuf tp;
-#define SYSUTIMEH /* Our utimbuf matches this one. */
-#else /* def VMS */
- struct utimbuf {
- time_t atime;
- time_t mtime;
- } tp;
-#endif /* def VMS [else] */
-#endif /* def SYSUTIMEH [else] */
-#endif /* def V7 [else] */
-#endif /* def BSD44 [else] */
-
- if (stat(f,&sb) < 0) {
- debug(F111,"setmodtime stat failure",f,errno);
- return(-1);
- }
-#ifdef BSD44
- tp[0].tv_sec = sb.st_atime; /* Access time first */
- tp[1].tv_sec = t; /* Update time second */
- debug(F111,"setmodtime BSD44",f,t);
-#else
-#ifdef V7
- tp.timep[0] = t; /* Set modif. time to creation date */
- tp.timep[1] = sb.st_atime; /* Don't change the access time */
- debug(F111,"setmodtime V7",f,t);
-#else
-#ifdef SYSUTIMEH
- tp.modtime = t; /* Set modif. time to creation date */
- tp.actime = sb.st_atime; /* Don't change the access time */
- debug(F111,"setmodtime SYSUTIMEH",f,t);
-#else
- tp.mtime = t; /* Set modif. time to creation date */
- tp.atime = sb.st_atime; /* Don't change the access time */
- debug(F111,"setmodtime (other)",f,t);
-#endif /* SYSUTIMEH */
-#endif /* V7 */
-#endif /* BSD44 */
-
- /* Try to set the file date */
-
-#ifdef BSD44
- x = utimes(f,tp);
- debug(F111,"setmodtime utimes()","BSD44",x);
-#else
-#ifdef IRIX65
- {
- /*
- The following produces the nonsensical warning:
- Argument of type "const struct utimbuf *" is incompatible with
- parameter of type "const struct utimbuf *". If you can make it
- go away, be my guest.
- */
- const struct utimbuf * t2 = &tp;
- x = utime(f,t2);
- }
-#else
- x = utime(f,&tp);
- debug(F111,"setmodtime utime()","other",x);
-#endif /* IRIX65 */
-#endif /* BSD44 */
- if (x)
- rc = -1;
-
- debug(F101,"setmodtime result","",rc);
- return(rc);
-}
-
-
-/*
- c h k m o d t i m e -- Check/Set file modification time.
-
- fc = function code:
- 0 = Check; returns:
- -1 on error,
- 0 if local older than remote,
- 1 if modtimes are equal,
- 2 if local newer than remote.
- 1 = Set (local file's modtime from remote's); returns:
- -1 on error,
- 0 on success.
-*/
-static int
-chkmodtime(local,remote,fc) char * local, * remote; int fc; {
-#ifdef NT
- struct _stat statbuf;
-#else /* NT */
- struct stat statbuf;
-#endif /* NT */
- struct tm * tmlocal = NULL;
- struct tm tmremote;
- int rc = 0, havedate = 0, lcs = -1, rcs = -1, flag = 0;
- char * s, timebuf[64];
-
- debug(F111,"chkmodtime",local,mdtmok);
- if (!mdtmok) /* Server supports MDTM? */
- return(-1); /* No don't bother. */
-
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
-
- if (fc == 0) {
- rc = stat(local,&statbuf);
- if (rc == 0) { /* Get local file's mod time */
- /* Convert to struct tm */
- tmlocal = gmtime((time_t *)&statbuf.st_mtime);
-#ifdef DEBUG
- if (tmlocal) {
- dbtime(local,tmlocal);
- }
-#endif /* DEBUG */
- }
- }
- /* Get remote file's mod time as yyyymmddhhmmss */
-
- if (havemdtm) { /* Already got it from MLSD? */
- s = havemdtm;
- flag++;
- } else if (ftpcmd("MDTM",remote,lcs,rcs,0) == REPLY_COMPLETE) {
- char c;
- bzero((char *)&tmremote, sizeof(struct tm));
- s = ftp_reply_str;
- while ((c = *s++)) { /* Skip past response code */
- if (c == SP) {
- flag++;
- break;
- }
- }
- }
- if (flag) {
- debug(F111,"ftp chkmodtime string",s,flag);
- if (fts_sto) { /* User gave server time offset? */
- char * p;
- debug(F110,"ftp chkmodtime offset",fts_sto,0);
- ckmakmsg(timebuf,64,s," ",fts_sto,NULL); /* Build delta time */
- if ((p = cmcvtdate(timebuf,1))) { /* Apply delta time */
- ckstrncpy(timebuf,p,64); /* Convert to MDTM format */
- timebuf[8] = timebuf[9]; /* h */
- timebuf[9] = timebuf[10]; /* h */
- timebuf[10] = timebuf[12]; /* m */
- timebuf[11] = timebuf[13]; /* m */
- timebuf[12] = timebuf[12]; /* s */
- timebuf[13] = timebuf[13]; /* s */
- timebuf[14] = NUL;
- s = timebuf;
- debug(F110,"ftp chkmodtime adjust",s,0);
- }
- }
- if (flag) { /* Convert to struct tm */
- char * pat;
- int y2kbug = 0; /* Seen in Kerberos 4 FTP servers */
- if (!ckstrcmp(s,"191",3,0)) {
- pat = "%05d%02d%02d%02d%02d%02d";
- y2kbug++;
- debug(F110,"ftp chkmodtime Y2K BUG detected",s,0);
- } else {
- pat = "%04d%02d%02d%02d%02d%02d";
- }
- if (sscanf(s, /* Parse into struct tm */
- pat,
- &(tmremote.tm_year),
- &(tmremote.tm_mon),
- &(tmremote.tm_mday),
- &(tmremote.tm_hour),
- &(tmremote.tm_min),
- &(tmremote.tm_sec)
- ) == 6) {
- tmremote.tm_year -= (y2kbug ? 19000 : 1900);
- debug(F101,"ftp chkmodtime year","",tmremote.tm_year);
- tmremote.tm_mon--;
-
-#ifdef DEBUG
- debug(F100,"SERVER TIME FOLLOWS:","",0);
- dbtime(remote,&tmremote);
-#endif /* DEBUG */
-
- if (havedate > -1)
- havedate = 1;
- }
- }
- } else { /* Failed */
- debug(F101,"ftp chkmodtime ftpcode","",ftpcode);
- if (ftpcode == 500 || /* Command unrecognized */
- ftpcode == 502 || /* Command not implemented */
- ftpcode == 202) /* Command superfluous */
- mdtmok = 0; /* Don't ask this server again */
- return(-1);
- }
- if (fc == 0) { /* Compare */
- if (havedate == 1) { /* Only if we have both file dates */
- /*
- Compare with local file's time. We don't use
- clock time (time_t) here in case of signed/unsigned
- confusion, etc.
- */
- int xx;
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- dbtime("LOCAL",tmlocal);
- dbtime("REMOT",&tmremote);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- xx = tmcompare(tmlocal,&tmremote);
- debug(F101,"chkmodtime tmcompare","",xx);
- return(xx + 1);
- }
- } else if (ftp_dates) { /* Set */
- /*
- Here we must convert struct tm to time_t
- without applying timezone conversion, for which
- there is no portable API. The method is hidden
- in mkutime(), defined above.
- */
- time_t utc;
- utc = mkutime(&tmremote);
- debug(F111,"ftp chkmodtime mkutime",remote,utc);
- if (utc != (time_t)-1)
- return(setmodtime(local,utc));
- }
- return(-1);
-}
-
-/* getfile() returns: -1 on error, 0 if file received, 1 if file skipped */
-
-static int
-getfile(remote,local,recover,append,pipename,xlate,fcs,rcs)
- char * local, * remote, * pipename; int recover, append, xlate, fcs, rcs;
-/* getfile */ {
- int rc = -1;
- ULONG t0, t1;
-
-#ifdef GFTIMER
- CKFLOAT sec;
-#else
- int sec = 0;
-#endif /* GFTIMER */
- char fullname[CKMAXPATH+1];
-
- debug(F110,"ftp getfile remote A",remote,0);
- debug(F110,"ftp getfile local A",local,0);
- debug(F110,"ftp getfile pipename",pipename,0);
- if (!remote) remote = "";
-
-#ifdef PATTERNS
- /* Automatic type switching? */
- if (ftp_xfermode == XMODE_A && patterns && get_auto && !forcetype) {
- int x;
- x = matchname(remote,0,servertype);
- debug(F111,"ftp getfile matchname",remote,x);
- switch (x) {
- case 0: ftp_typ = FTT_ASC; break;
- case 1: ftp_typ = tenex ? FTT_TEN : FTT_BIN; break;
- default: if (g_ftp_typ > -1) ftp_typ = g_ftp_typ;
- }
- changetype(ftp_typ,ftp_vbm);
- binary = ftp_typ; /* For file-transfer display */
- }
-#endif /* PATTERNS */
-
-#ifndef NOCSETS
- ftp_csx = -1; /* For file-transfer display */
- ftp_csl = -1; /* ... */
-
- if (rcs > -1) /* -1 means no translation */
- if (ftp_typ == FTT_ASC) /* File type is "ascii"? */
- if (fcs < 0) /* File charset not forced? */
- fcs = fcharset; /* use prevailing FILE CHARACTER-SET */
- if (fcs > -1 && rcs > -1) { /* Set up translation functions */
- debug(F110,"ftp getfile","initxlate",0);
- initxlate(rcs,fcs); /* NB: opposite order of PUT */
- ftp_csx = rcs;
- ftp_csl = fcs;
- } else
- xlate = 0;
-#endif /* NOCSETS */
-
- if (!local) local = "";
- if (!pipename && !*local)
- local = remote;
-
- out2screen = !strcmp(local,"-");
-
- fullname[0] = NUL;
- if (pipename) {
- ckstrncpy(fullname,pipename,CKMAXPATH+1);
- } else {
- zfnqfp(local,CKMAXPATH,fullname);
- if (!fullname[0])
- ckstrncpy(fullname,local,CKMAXPATH+1);
- }
- if (!out2screen && displa && fdispla) { /* Screen */
- ftscreen(SCR_FN,'F',(CK_OFF_T)pktnum,remote);
- ftscreen(SCR_AN,0,(CK_OFF_T)0,fullname);
- ftscreen(SCR_FS,0,fsize,"");
- }
- tlog(F110,ftp_typ ? "ftp get BINARY:" : "ftp get TEXT:", remote, 0);
- tlog(F110," as",fullname,0);
- debug(F111,"ftp getfile size",remote,fsize);
- debug(F111,"ftp getfile local",local,out2screen);
-
- ckstrncpy(filnam, pipename ? remote : local, CKMAXPATH);
-
- t0 = gmstimer(); /* Start time */
- debug(F111,"ftp getfile t0",remote,t0); /* ^^^ */
- rc = recvrequest("RETR",
- local,
- remote,
- append ? "ab" : "wb",
- 0,
- recover,
- pipename,
- xlate,
- fcs,
- rcs
- );
- t1 = gmstimer(); /* End time */
- debug(F111,"ftp getfile t1",remote,t1);
- debug(F111,"ftp getfile sec",remote,(t1-t0)/1000);
-#ifdef GFTIMER
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- fpxfsecs = sec; /* (for doxlog()) */
-#else
- sec = (t1 - t0) / 1000;
- xfsecs = (int)sec;
-#endif /* GFTIMER */
-
-#ifdef FTP_TIMEOUT
- if (ftp_timed_out)
- rc = -4;
-#endif /* FTP_TIMEOUT */
-
- debug(F111,"ftp recvrequest rc",remote,rc);
- if (cancelfile || cancelgroup) {
- debug(F111,"ftp get canceled",ckitoa(cancelfile),cancelgroup);
- ftscreen(SCR_ST,ST_INT,(CK_OFF_T)0,"");
- } else if (rc > 0) {
- debug(F111,"ftp get skipped",ckitoa(cancelfile),cancelgroup);
- ftscreen(SCR_ST,ST_SKIP,(CK_OFF_T)0,cmarg);
- } else if (rc < 0) {
- switch (ftpcode) {
- case -4: /* Network error */
- case -2: /* File error */
- ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,ck_errstr());
- break;
- case -3:
- ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,
- "Failure to make data connection");
- break;
- case -1: /* (should be covered above) */
- ftscreen(SCR_ST,ST_INT,(CK_OFF_T)0,"");
- break;
- default:
- ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,&ftp_reply_str[4]);
- }
- } else { /* Tudo bem */
- ftscreen(SCR_PT,'Z',(CK_OFF_T)0,"");
- if (rc == 0) {
- ftscreen(SCR_ST,ST_OK,(CK_OFF_T)0,""); /* For screen */
- makestr(&rrfspec,remote); /* For WHERE command */
- makestr(&rfspec,fullname);
- }
- }
- if (rc > -1) {
- if (ftp_dates) /* If FTP DATES ON... */
- if (!pipename && !out2screen) /* and it's a real file */
- if (rc < 1 && rc != -3) /* and it wasn't skipped */
- if (connected) /* and we still have a connection */
- if (zchki(local) > -1) { /* and the file wasn't discarded */
- chkmodtime(local,remote,1); /* set local file date */
- debug(F110,"ftp get set date",local,0);
- }
- filcnt++; /* Used by \v(filenum) */
- }
-#ifdef TLOG
- if (tralog) {
- if (rc > 0) {
- tlog(F100," recovery skipped","",0);
- } else if (rc == 0) {
- tlog(F101," complete, size", "", fsize);
- } else if (cancelfile) {
- tlog(F100," canceled by user","",0);
-#ifdef FTP_TIMEOUT
- } else if (ftp_timed_out) {
- tlog(F100," timed out","",0);
-#endif /* FTP_TIMEOUT */
- } else {
- tlog(F110," failed:",ftp_reply_str,0);
- }
- if (!tlogfmt)
- doxlog(what,local,fsize,ftp_typ,rc,"");
- }
-#endif /* TLOG */
- return(rc);
-}
-
-/* putfile() returns: -1 on error, >0 if file not selected, 0 on success. */
-/* Positive return value is Skip Reason, SKP_xxx, from ckcker.h. */
-
-static int
-putfile(cx,
- local,remote,force,moving,mvto,rnto,srvrn,x_cnv,x_usn,xft,prm,fcs,rcs,flg)
- char * local, * remote, * mvto, *rnto, *srvrn;
- int cx, force, moving, x_cnv, x_usn, xft, fcs, rcs, flg, prm;
-
-/* putfile */ {
-
- char asname[CKMAXPATH+1];
- char fullname[CKMAXPATH+1];
- int k = -1, x = 0, y = 0, o = -1, rc = 0, nc = 0;
- int xlate = 0, restart = 0, mt = -1;
- char * s = NULL, * cmd = NULL;
- ULONG t0 = 0, t1 = 0; /* Times for stats */
- int ofcs = 0, orcs = 0;
-
-#ifdef GFTIMER
- CKFLOAT sec = 0.0;
-#else
- int sec = 0;
-#endif /* GFTIMER */
- debug(F111,"ftp putfile flg",local,flg);
- debug(F110,"ftp putfile srv_renam",srvrn,0);
- debug(F101,"ftp putfile fcs","",fcs);
- debug(F101,"ftp putfile rcs","",rcs);
-
- ofcs = fcs; /* Save charset args */
- orcs = rcs;
-
- sendstart = (CK_OFF_T)0;
- restart = flg & PUT_RES;
- if (!remote)
- remote = "";
-
- /* FTP protocol command to send to server */
- cmd = (cx == FTP_APP) ? "APPE" : (x_usn ? "STOU" : "STOR");
-
- if (x_cnv == SET_AUTO) { /* Name conversion is auto */
- if (alike) { /* If server & client are alike */
- nc = 0; /* no conversion */
- } else { /* If they are different */
- if (servertype == SYS_UNIX || servertype == SYS_WIN32)
- nc = -1; /* only minimal conversions needed */
- else /* otherwise */
- nc = 1; /* full conversion */
- }
- } else /* Not auto - do what user said */
- nc = x_cnv;
-
- /* If Transfer Mode is Automatic, determine file type */
- if (ftp_xfermode == XMODE_A && filepeek && !pipesend) {
- if (isdir(local)) { /* If it's a directory */
- k = FT_BIN; /* skip the file scan */
- } else {
- debug(F110,"FTP PUT calling scanfile",local,0);
- k = scanfile(local,&o,nscanfile); /* Scan the file */
- }
- debug(F111,"FTP PUT scanfile",local,k);
- if (k > -1 && !forcetype) {
- ftp_typ = (k == FT_BIN) ? 1 : 0;
- if (xft > -1 && ftp_typ != xft) {
- if (flg & PUT_SIM)
- tlog(F110,"ftp put SKIP (Type):", local, 0);
- return(SKP_TYP);
- }
- if (ftp_typ == 1 && tenex) /* User said TENEX? */
- ftp_typ = FTT_TEN;
- }
- }
-#ifndef NOCSETS
- ftp_csx = -1; /* For file-transfer display */
- ftp_csl = -1; /* ... */
-
- if (rcs > -1) { /* -1 means no translation */
- if (ftp_typ == 0) { /* File type is "ascii"? */
- if (fcs < 0) { /* File charset not forced? */
- if (k < 0) { /* If we didn't scan */
- fcs = fcharset; /* use prevailing FILE CHARACTER-SET */
- } else { /* If we did scan, use scan result */
- switch (k) {
- case FT_TEXT: /* Unknown text */
- fcs = fcharset;
- break;
- case FT_7BIT: /* 7-bit text */
- fcs = dcset7;
- break;
- case FT_8BIT: /* 8-bit text */
- fcs = dcset8;
- break;
- case FT_UTF8: /* UTF-8 */
- fcs = FC_UTF8;
- break;
- case FT_UCS2: /* UCS-2 */
- fcs = FC_UCS2;
- if (o > -1) /* Input file byte order */
- fileorder = o;
- break;
- default:
- rcs = -1;
- }
- }
- }
- }
- }
- if (fcs > -1 && rcs > -1) { /* Set up translation functions */
- debug(F110,"ftp putfile","initxlate",0);
- initxlate(fcs,rcs);
- debug(F111,"ftp putfile rcs",fcsinfo[rcs].keyword,rcs);
- xlate = 1;
- ftp_csx = rcs;
- ftp_csl = fcs;
- }
-#endif /* NOCSETS */
-
- binary = ftp_typ; /* For file-transfer display */
- asname[0] = NUL;
-
- if (recursive) { /* If sending recursively, */
- if (!syncdir(local,flg & PUT_SIM)) /* synchronize directories. */
- return(-1); /* Don't PUT if it fails. */
- else if (isdir(local)) /* It's a directory */
- return(0); /* Don't send it! */
- }
- if (*remote) { /* If an as-name template was given */
-#ifndef NOSPL
- if (cmd_quoting) { /* and COMMAND QUOTING is ON */
- y = CKMAXPATH; /* evaluate it for this file */
- s = asname;
- zzstring(remote,&s,&y);
- } else
-#endif /* NOSPL */
- ckstrncpy(asname,remote,CKMAXPATH); /* (or take it literally) */
- } else { /* No as-name */
- nzltor(local,asname,nc,0,CKMAXPATH); /* use local name strip path */
- debug(F110,"FTP PUT nzltor",asname,0);
- }
- /* Preliminary messages and log entries */
-
- fullname[0] = NUL;
- zfnqfp(local,CKMAXPATH,fullname);
- if (!fullname[0]) ckstrncpy(fullname,local,CKMAXPATH+1);
- fullname[CKMAXPATH] = NUL;
-
- if (displa && fdispla) { /* Screen */
- ftscreen(SCR_FN,'F',(CK_OFF_T)pktnum,local);
- ftscreen(SCR_AN,0,(CK_OFF_T)0,asname);
- ftscreen(SCR_FS,0,fsize,"");
- }
-#ifdef DOUPDATE
- if (flg & (PUT_UPD|PUT_DIF)) { /* Date-checking modes... */
- mt = chkmodtime(fullname,asname,0);
- debug(F111,"ftp putfile chkmodtime",asname,mt);
- if (mt == 0 && ((flg & PUT_DIF) == 0)) { /* Local is older */
- tlog(F110,"ftp put /update SKIP (Older modtime): ",fullname,0);
- /* Skip this one */
- ftscreen(SCR_ST,ST_SKIP,(CK_OFF_T)SKP_DAT,fullname);
- filcnt++;
- return(SKP_DAT);
- } else if (mt == 1) { /* Times are equal */
- tlog(F110,"ftp put /update SKIP (Equal modtime): ",fullname,0);
- ftscreen(SCR_ST,ST_SKIP,(CK_OFF_T)SKP_EQU,fullname); /* Skip it */
- filcnt++;
- return(SKP_DAT);
- }
- /* Local file is newer */
- tlog(F110,ftp_typ ? "ftp put /update BINARY:" :
- "ftp put /update TEXT:", fullname, 0);
- } else if (flg & PUT_RES) {
- tlog(F110,ftp_typ ? "ftp put /recover BINARY:" :
- "ftp put /recover TEXT:", fullname, 0);
- } else {
- tlog(F110,ftp_typ ? "ftp put BINARY:" : "ftp put TEXT:", fullname, 0);
- }
-#else
- tlog(F110,ftp_typ ? "ftp put BINARY:" : "ftp put TEXT:", fullname, 0);
-#endif /* DOUPDATE */
- tlog(F110," as",asname,0);
-
-#ifndef NOCSETS
- if (xlate) {
- debug(F111,"ftp putfile fcs",fcsinfo[fcs].keyword,fcs);
- tlog(F110," file character set:",fcsinfo[fcs].keyword,0);
- tlog(F110," server character set:",fcsinfo[rcs].keyword,0);
- } else if (!ftp_typ) {
- tlog(F110," character sets:","no conversion",0);
- fcs = ofcs; /* Binary file but we still must */
- rcs = orcs; /* translate its name */
- }
-#endif /* NOCSETS */
-
- /* PUT THE FILE */
-
- t0 = gmstimer(); /* Start time */
- if (flg & PUT_SIM) { /* rc > 0 is a skip reason code */
- if (flg & (PUT_UPD|PUT_DIF)) { /* (see SKP_xxx in ckcker.h) */
- rc = (mt < 0) ? /* Update mode... */
- SKP_XNX : /* Remote file doesn't exist */
- SKP_XUP; /* Remote file is older */
- } else {
- rc = SKP_SIM; /* "Would be sent", period. */
- }
- } else {
- rc = sendrequest(cmd,local,asname,xlate,fcs,rcs,restart);
- }
- t1 = gmstimer(); /* End time */
- filcnt++; /* File number */
-
-#ifdef GFTIMER
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- fpxfsecs = sec; /* (for doxlog()) */
-#else
- sec = (t1 - t0) / 1000;
- xfsecs = (int)sec;
-#endif /* GFTIMER */
-
- debug(F111,"ftp sendrequest rc",local,rc);
-
- if (cancelfile || cancelgroup) {
- debug(F111,"ftp put canceled",ckitoa(cancelfile),cancelgroup);
- ftscreen(SCR_ST,ST_INT,(CK_OFF_T)0,"");
- } else if (rc > 0) {
- debug(F101,"ftp put skipped",local,rc);
- ftscreen(SCR_ST,ST_SKIP,(CK_OFF_T)rc,fullname);
- } else if (rc < 0) {
- debug(F111,"ftp put error",local,ftpcode);
- ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,&ftp_reply_str[4]);
- } else {
- debug(F111,"ftp put not canceled",ckitoa(displa),fdispla);
- ftscreen(SCR_PT,'Z',(CK_OFF_T)0,"");
- debug(F111,"ftp put ST_OK",local,rc);
- ftscreen(SCR_ST,ST_OK,(CK_OFF_T)0,"");
- debug(F110,"ftp put old sfspec",sfspec,0);
- makestr(&sfspec,fullname); /* For WHERE command */
- debug(F110,"ftp put new sfspec",sfspec,0);
- debug(F110,"ftp put old srfspec",srfspec,0);
- makestr(&srfspec,asname);
- debug(F110,"ftp put new srfspec",srfspec,0);
- }
-
- /* Final log entries */
-
-#ifdef TLOG
- if (tralog) {
- if (rc > 0) {
- if (rc == SKP_XNX)
- tlog(F100," /simulate: WOULD BE SENT:","no remote file",0);
- else if (rc == SKP_XUP)
- tlog(F100," /simulate: WOULD BE SENT:","remote file older",0);
- else if (rc == SKP_SIM)
- tlog(F100," /simulate: WOULD BE SENT","",0);
- else
- tlog(F110," skipped:",gskreason(rc),0);
- } else if (rc == 0) {
- tlog(F101," complete, size", "", fsize);
- } else if (cancelfile) {
- tlog(F100," canceled by user","",0);
- } else {
- tlog(F110," failed:",ftp_reply_str,0);
- }
- if (!tlogfmt)
- doxlog(what,local,fsize,ftp_typ,rc,"");
- }
-#endif /* TLOG */
-
- if (rc < 0) /* PUT did not succeed */
- return(-1); /* so done. */
-
- if (flg & PUT_SIM) /* Simulating, skip the rest. */
- return(SKP_SIM);
-
-#ifdef UNIX
- /* Set permissions too? */
-
- if (prm) { /* Change permissions? */
- s = zgperm(local); /* Get perms of local file */
- if (!s) s = "";
- x = strlen(s);
- if (x > 3) s += (x - 3);
- if (rdigits(s)) {
- ckmakmsg(ftpcmdbuf,FTP_BUFSIZ,s," ",asname,NULL);
- x =
- ftpcmd("SITE CHMOD",ftpcmdbuf,fcs,rcs,ftp_vbm) == REPLY_COMPLETE;
- tlog(F110, x ? " chmod" : " chmod failed",
- s,
- 0
- );
- if (!x)
- return(-1);
- }
- }
-#endif /* UNIX */
-
- /* Disposition of source file */
-
- if (moving) {
- x = zdelet(local);
- tlog(F110, (x > -1) ?
- " deleted" : " failed to delete",
- local,
- 0
- );
- if (x < 0)
- return(-1);
- } else if (mvto) {
- x = zrename(local,mvto);
- tlog(F110, (x > -1) ?
- " moved source to" : " failed to move source to",
- mvto,
- 0
- );
- if (x < 0)
- return(-1);
- /* ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,mvto); */
-
- } else if (rnto) {
- char * s = rnto;
-#ifndef NOSPL
- int y; /* Pass it thru the evaluator */
- extern int cmd_quoting; /* for \v(filename) */
- if (cmd_quoting) { /* But only if cmd_quoting is on */
- y = CKMAXPATH;
- s = (char *)asname;
- zzstring(rnto,&s,&y);
- s = (char *)asname;
- }
-#endif /* NOSPL */
- if (s) if (*s) {
- int x;
- x = zrename(local,s);
- tlog(F110, (x > -1) ?
- " renamed source file to" :
- " failed to rename source file to",
- s,
- 0
- );
- if (x < 0)
- return(-1);
- /* ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,s); */
- }
- }
-
- /* Disposition of destination file */
-
- if (srvrn) { /* /SERVER-RENAME: */
- char * s = srvrn;
-#ifndef NOSPL
- int y; /* Pass it thru the evaluator */
- extern int cmd_quoting; /* for \v(filename) */
- debug(F111,"ftp putfile srvrn",s,1);
-
- if (cmd_quoting) { /* But only if cmd_quoting is on */
- y = CKMAXPATH;
- s = (char *)fullname; /* We can recycle this buffer now */
- zzstring(srvrn,&s,&y);
- s = (char *)fullname;
- }
-#endif /* NOSPL */
- debug(F111,"ftp putfile srvrn",s,2);
- if (s) if (*s) {
- int x;
- x = ftp_rename(asname,s);
- debug(F111,"ftp putfile ftp_rename",asname,x);
- tlog(F110, (x > 0) ?
- " renamed destination file to" :
- " failed to rename destination file to",
- s,
- 0
- );
- if (x < 1)
- return(-1);
- }
- }
- return(0);
-}
-
-/* xxout must only be used for ASCII transfers */
-static int
-#ifdef CK_ANSIC
-xxout(char c)
-#else
-xxout(c) char c;
-#endif /* CK_ANSIC */
-{
-#ifndef OS2
-#ifndef VMS
-#ifndef MAC
-#ifndef OSK
- /* For Unix, DG, Stratus, Amiga, Gemdos, other */
- if (c == '\012') {
- if (zzout(dout,(CHAR)'\015') < 0)
- return(-1);
- ftpsnd.bytes++;
- }
-#else /* OSK */
- if (c == '\015') {
- c = '\012';
- if (zzout(dout,(CHAR)'\015') < 0)
- return(-1);
- ftpsnd.bytes++;
- }
-#endif /* OSK */
-#else /* MAC */
- if (c == '\015') {
- c = '\012';
- if (zzout(dout,(CHAR)'\015') < 0)
- return(-1);
- ftpsnd.bytes++;
- }
-#endif /* MAC */
-#endif /* VMS */
-#endif /* OS2 */
- if (zzout(dout,(CHAR)c) < 0)
- return(-1);
- ftpsnd.bytes++;
- return(0);
-}
-
-static int
-#ifdef CK_ANSIC
-scrnout(char c)
-#else
-scrnout(c) char c;
-#endif /* CK_ANSIC */
-{
- return(putchar(c));
-}
-
-static int
-#ifdef CK_ANSIC
-pipeout(char c)
-#else
-pipeout(c) char c;
-#endif /* CK_ANSIC */
-{
- return(zmchout(c));
-}
-
-static int
-ispathsep(c) int c; {
- switch (servertype) {
- case SYS_VMS:
- case SYS_TOPS10:
- case SYS_TOPS20:
- return(((c == ']') || (c == '>') || (c == ':')) ? 1 : 0);
- case SYS_OS2:
- case SYS_WIN32:
- case SYS_DOS:
- return(((c == '\\') || (c == '/') || (c == ':')) ? 1 : 0);
- case SYS_VOS:
- return((c == '>') ? 1 : 0);
- default:
- return((c == '/') ? 1 : 0);
- }
-}
-
-static int
-iscanceled() {
-#ifdef CK_CURSES
- extern int ck_repaint();
-#endif /* CK_CURSES */
- int x, rc = 0;
- char c = 0;
- if (cancelfile)
- return(1);
- x = conchk(); /* Any chars waiting at console? */
- if (x-- > 0) { /* Yes... */
- c = coninc(5); /* Get one */
- switch (c) {
- case 032: /* Ctrl-X or X */
- case 'z':
- case 'Z': cancelgroup++; /* fall thru on purpose */
- case 030: /* Ctrl-Z or Z */
- case 'x':
- case 'X': cancelfile++; rc++; break;
-#ifdef CK_CURSES
- case 'L':
- case 'l':
- case 014: /* Ctrl-L or L or Ctrl-W */
- case 027:
- ck_repaint(); /* Refresh screen */
-#endif /* CK_CURSES */
- }
- }
- while (x-- > 0) /* Soak up any rest */
- c = coninc(1);
- return(rc);
-}
-
-#ifdef FTP_TIMEOUT
-/* fc = 0 for read; 1 for write */
-static int
-check_data_connection(fd,fc) int fd, fc; {
- int x;
- struct timeval tv;
- fd_set in, out, err;
-
- if (ftp_timeout < 1L)
- return(0);
-
- FD_ZERO(&in);
- FD_ZERO(&out);
- FD_ZERO(&err);
- FD_SET(fd,fc ? &out : &in);
- tv.tv_sec = ftp_timeout; /* Time limit */
- tv.tv_usec = 0L;
-
-#ifdef INTSELECT
- x = select(FD_SETSIZE,(int *)&in,(int *)&out,(int *)&err,&tv);
-#else
- x = select(FD_SETSIZE,&in,&out,&err,&tv);
-#endif /* INTSELECT */
-
- if (x == 0) {
-#ifdef EWOULDBLOCK
- errno = EWOULDBLOCK;
-#else
-#ifdef EAGAIN
- errno = EAGAIN;
-#else
- errno = 11;
-#endif /* EAGAIN */
-#endif /* EWOULDBLOCK */
- debug(F100,"ftp check_data_connection TIMOUT","",0);
- return(-3);
- }
- return(0);
-}
-#endif /* FTP_TIMEOUT */
-
-/* zzsend - used by buffered output macros. */
-
-static int
-#ifdef CK_ANSIC
-zzsend(int fd, CHAR c)
-#else
-zzsend(fd,c) int fd; CHAR c;
-#endif /* CK_ANSIC */
-{
- int rc;
-
- debug(F101,"zzsend ucbufsiz","",ucbufsiz);
- debug(F101,"zzsend nout","",nout);
- debug(F111,"zzsend","secure?",ftpissecure());
-
- if (iscanceled()) /* Check for cancellation */
- return(-9);
-
-#ifdef FTP_TIMEOUT
- ftp_timed_out = 0;
- if (check_data_connection(fd,1) < 0) {
- ftp_timed_out = 1;
- return(-3);
- }
-#endif /* FTP_TIMEOUT */
-
- rc = (!ftpissecure()) ?
- send(fd, (SENDARG2TYPE)ucbuf, nout, 0) :
- secure_putbuf(fd, ucbuf, nout);
- ucbuf[nout] = NUL;
- nout = 0;
- ucbuf[nout++] = c;
- spackets++;
- pktnum++;
- if (rc > -1 && fdispla != XYFD_B) {
- spktl = nout;
- ftscreen(SCR_PT,'D',(CK_OFF_T)spackets,NULL);
- }
- return(rc);
-}
-
-/* c m d l i n p u t -- Command-line PUT */
-
-int
-cmdlinput(stay) int stay; {
- int x, rc = 0, done = 0, good = 0, status = 0;
- ULONG t0, t1; /* Times for stats */
-#ifdef GFTIMER
- CKFLOAT sec;
-#else
- int sec = 0;
-#endif /* GFTIMER */
-
- if (quiet) { /* -q really means quiet */
- displa = 0;
- fdispla = 0;
- } else {
- displa = 1;
- fdispla = XYFD_B;
- }
- testing = 0;
- out2screen = 0;
- dpyactive = 0;
- what = W_FTP|W_SEND;
-
-#ifndef NOSPL
- cmd_quoting = 0;
-#endif /* NOSPL */
- sndsrc = nfils;
-
- t0 = gmstimer(); /* Record starting time */
-
- while (!done && !cancelgroup) { /* Loop for all files */
-
- cancelfile = 0;
- x = gnfile(); /* Get next file from list(s) */
- if (x == 0) /* (see gnfile() comments...) */
- x = gnferror;
-
- switch (x) {
- case 1: /* File to send */
- rc = putfile(FTP_PUT, /* Function (PUT, APPEND) */
- filnam, /* Local file to send */
- filnam, /* Remote name for file */
- forcetype, /* Text/binary mode forced */
- 0, /* Not moving */
- NULL, /* No move-to */
- NULL, /* No rename-to */
- NULL, /* No server-rename */
- ftp_cnv, /* Filename conversion */
- 0, /* Unique-server-names */
- -1, /* All file types */
- 0, /* No permissions */
- -1, /* No character sets */
- -1, /* No character sets */
- 0 /* No update or restart */
- );
- if (rc > -1) {
- good++;
- status = 1;
- }
- if (cancelfile) {
- continue; /* Or break? */
- }
- if (rc < 0) {
- ftp_fai++;
- }
- continue; /* Or break? */
-
- case 0: /* No more files, done */
- done++;
- continue;
-
- case -2:
- case -1:
- printf("?%s: file not found - \"%s\"\n",
- puterror ? "Fatal" : "Warning",
- filnam
- );
- continue; /* or break? */
- case -3:
- printf("?Warning access denied - \"%s\"\n", filnam);
- continue; /* or break? */
- case -5:
- printf("?Too many files match\n");
- done++;
- break;
- case -6:
- if (good < 1)
- printf("?No files selected\n");
- done++;
- break;
- default:
- printf("?getnextfile() - unknown failure\n");
- done++;
- }
- }
- if (status > 0) {
- if (cancelgroup)
- status = 0;
- else if (cancelfile && good < 1)
- status = 0;
- }
- success = status;
- x = success;
- if (x > -1) {
- lastxfer = W_FTP|W_SEND;
- xferstat = success;
- }
- t1 = gmstimer(); /* End time */
-#ifdef GFTIMER
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- if (!sec) sec = 0.001;
- fptsecs = sec;
-#else
- sec = (t1 - t0) / 1000;
- if (!sec) sec = 1;
-#endif /* GFTIMER */
- tfcps = (long) (tfc / sec);
- tsecs = (int)sec;
- lastxfer = W_FTP|W_SEND;
- xferstat = success;
- if (dpyactive)
- ftscreen(status > 0 ? SCR_TC : SCR_CW, 0, (CK_OFF_T)0, "");
- if (!stay)
- doexit(success ? GOOD_EXIT : BAD_EXIT, -1);
- return(success);
-}
-
-
-/* d o f t p p u t -- Parse and execute PUT, MPUT, and APPEND */
-
-int
-#ifdef CK_ANSIC
-doftpput(int cx, int who) /* who == 1 for ftp, 0 for kermit */
-#else
-doftpput(cx,who) int cx, who;
-#endif /* CK_ANSIC */
-{
- struct FDB sf, fl, sw, cm;
- int n, rc, confirmed = 0, wild = 0, getval = 0, mput = 0, done = 0;
- int x_cnv = 0, x_usn = 0, x_prm = 0, putflags = 0, status = 0, good = 0;
- char * s, * s2;
-
- int x_csl, x_csr = -1; /* Local and remote charsets */
- int x_xla = 0;
- int x_recurse = 0;
- char c, * p; /* Workers */
-#ifdef PUTARRAY
- int range[2]; /* Array range */
- char ** ap = NULL; /* Array pointer */
- int arrayx = -1; /* Array index */
-#endif /* PUTARRAY */
- ULONG t0 = 0L, t1 = 0L; /* Times for stats */
-#ifdef GFTIMER
- CKFLOAT sec;
-#else
- int sec = 0;
-#endif /* GFTIMER */
-
- struct stringint pv[SND_MAX+1]; /* Temporary array for switch values */
- success = 0; /* Assume failure */
- forcetype = 0; /* No /TEXT or /BINARY given yet */
- out2screen = 0; /* Not outputting file to screen */
- putflags = 0; /* PUT options */
- x_cnv = ftp_cnv; /* Filename conversion */
- x_usn = ftp_usn; /* Unique server names */
- x_prm = ftp_prm; /* Permissions */
- if (x_prm == SET_AUTO) /* Permissions AUTO */
- x_prm = alike;
-
-#ifndef NOCSETS
- x_csr = ftp_csr; /* Inherit global server charset */
- x_csl = ftp_csl;
- if (x_csl < 0)
- x_csl = fcharset;
- x_xla = ftp_xla;
-#endif /* NOCSETS */
-
- makestr(&filefile,NULL); /* No filename list file yet. */
- makestr(&srv_renam,NULL); /* Clear /SERVER-RENAME: */
- makestr(&snd_rename,NULL); /* PUT /RENAME */
- makestr(&snd_move,NULL); /* PUT /MOVE */
- putpath[0] = NUL; /* Initialize for syncdir(). */
- puterror = ftp_err; /* Inherit global error action. */
- what = W_SEND|W_FTP; /* What we're doing (sending w/FTP) */
- asnambuf[0] = NUL; /* Clear as-name buffer */
-
- if (g_ftp_typ > -1) { /* Restore TYPE if saved */
- ftp_typ = g_ftp_typ;
- /* g_ftp_typ = -1; */
- }
- for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */
- pv[i].sval = NULL; /* to null pointers */
- pv[i].ival = -1; /* and -1 int values */
- pv[i].wval = (CK_OFF_T)-1; /* and -1 wide values */
- }
- if (who == 0) { /* Called with unprefixed command */
- switch (cx) {
- case XXRSEN: pv[SND_RES].ival = 1; break;
- case XXCSEN: pv[SND_CMD].ival = 1; break;
- case XXMOVE: pv[SND_DEL].ival = 1; break;
- case XXMMOVE: pv[SND_DEL].ival = 1; /* fall thru */
- case XXMSE: mput++; break;
- }
- } else {
- if (cx == FTP_REP)
- pv[SND_RES].ival = 1;
- if (cx == FTP_MPU)
- mput++;
- }
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Filename, or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nputswi, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- putswi, /* Keyword table */
- &sf /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* 3rd FDB - local filespec */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* 4th FDB - Confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
-
- again:
- cmfdbi(&sf, /* 2nd FDB - file to send */
- _CMIFI, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- /* 0 = parse files, 1 = parse files or dirs, 2 = skip symlinks */
- nolinks | x_recurse, /* addtl numeric data 1 */
- 0, /* dirflg 0 means "not dirs only" */
- xxstring,
- NULL,
-#ifdef COMMENT
- mput ? &cm : &fl
-#else
- &fl
-#endif /* COMMENT */
- );
-
- while (1) { /* Parse zero or more switches */
- x = cmfdb(&sw); /* Parse something */
- debug(F101,"ftp put cmfdb A","",x);
- debug(F101,"ftp put fcode A","",cmresult.fcode);
- if (x < 0) /* Error */
- goto xputx; /* or reparse needed */
- if (cmresult.fcode != _CMKEY) /* Break out of loop if not a switch */
- break;
- c = cmgbrk(); /* Get break character */
- getval = (c == ':' || c == '='); /* to see how they ended the switch */
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- x = -9;
- goto xputx;
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- x = -9;
- goto xputx;
- }
- n = cmresult.nresult; /* Numeric result = switch value */
- debug(F101,"ftp put switch","",n);
-
- switch (n) { /* Process the switch */
- case SND_AFT: /* Send /AFTER:date-time */
- case SND_BEF: /* Send /BEFORE:date-time */
- case SND_NAF: /* Send /NOT-AFTER:date-time */
- case SND_NBE: /* Send /NOT-BEFORE:date-time */
- if (!getval) break;
- if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) {
- if (x == -3) {
- printf("?Date-time required\n");
- x = -9;
- }
- goto xputx;
- }
- pv[n].ival = 1;
- makestr(&(pv[n].sval),s);
- break;
-
- case SND_ASN: /* /AS-NAME: */
- debug(F101,"ftp put /as-name getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Name to send under","",&s,NULL)) < 0) {
- if (x == -3) {
- printf("?name required\n");
- x = -9;
- }
- goto xputx;
- }
- makestr(&(pv[n].sval),brstrip(s));
- debug(F110,"ftp put /as-name 1",pv[n].sval,0);
- if (pv[n].sval) pv[n].ival = 1;
- break;
-
-#ifdef PUTARRAY
- case SND_ARR: /* /ARRAY */
- if (!getval) break;
- ap = NULL;
- if ((x = cmfld("Array name (a single letter will do)",
- "",
- &s,
- NULL
- )) < 0) {
- if (x == -3)
- break;
- else
- return(x);
- }
- if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
- printf("?Bad array: %s\n",s);
- return(-9);
- }
- if (!(ap = a_ptr[x])) {
- printf("?No such array: %s\n",s);
- return(-9);
- }
- pv[n].ival = 1;
- pv[SND_CMD].ival = 0; /* Undo any conflicting ones... */
- pv[SND_RES].ival = 0;
- pv[SND_FIL].ival = 0;
- arrayx = x;
- break;
-#endif /* PUTARRAY */
-
- case SND_BIN: /* /BINARY */
- case SND_TXT: /* /TEXT or /ASCII */
- case SND_TEN: /* /TENEX */
- pv[SND_BIN].ival = 0;
- pv[SND_TXT].ival = 0;
- pv[SND_TEN].ival = 0;
- pv[n].ival = 1;
- break;
-
-#ifdef PUTPIPE
- case SND_CMD: /* These take no args */
- if (nopush) {
- printf("?Sorry, system command access is disabled\n");
- x = -9;
- goto xputx;
- }
-#ifdef PIPESEND
- else if (sndfilter) {
- printf("?Sorry, no PUT /COMMAND when SEND FILTER selected\n");
- x = -9;
- goto xputx;
- }
-#endif /* PIPESEND */
- sw.hlpmsg = "Command, or switch"; /* Change help message */
- pv[n].ival = 1; /* Just set the flag */
- pv[SND_ARR].ival = 0;
- break;
-#endif /* PUTPIPE */
-
-#ifdef CKSYMLINK
- case SND_LNK:
- nolinks = 0;
- goto again; /* Because CMIFI params changed... */
- case SND_NLK:
- nolinks = 2;
- goto again;
-#endif /* CKSYMLINK */
-
-#ifdef FTP_RESTART
- case SND_RES: /* /RECOVER (resend) */
- pv[SND_ARR].ival = 0; /* fall thru on purpose... */
-#endif /* FTP_RESTART */
-
- case SND_NOB:
- case SND_DEL: /* /DELETE */
- case SND_SHH: /* /QUIET */
- case SND_UPD: /* /UPDATE */
- case SND_SIM: /* /UPDATE */
- case SND_USN: /* /UNIQUE */
- pv[n].ival = 1; /* Just set the flag */
- break;
-
- case SND_REC: /* /RECURSIVE */
- recursive = 2; /* Must be set before cmifi() */
- x_recurse = 1;
- goto again; /* Because CMIFI params changed... */
- break;
-
-#ifdef UNIXOROSK
- case SND_DOT: /* /DOTFILES */
- matchdot = 1;
- break;
- case SND_NOD: /* /NODOTFILES */
- matchdot = 0;
- break;
-#endif /* UNIXOROSK */
-
- case SND_ERR: /* /ERROR-ACTION */
- if ((x = cmkey(qorp,2,"","",xxstring)) < 0)
- goto xputx;
- pv[n].ival = x;
- break;
-
- case SND_EXC: /* Excludes */
- if (!getval) break;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Pattern required\n");
- x = -9;
- }
- goto xputx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- if (pv[n].sval)
- pv[n].ival = 1;
- break;
-
- case SND_PRM: /* /PERMISSIONS */
- if (!getval)
- x = 1;
- else if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
- goto xputx;
- pv[SND_PRM].ival = x;
- break;
-
-#ifdef PIPESEND
- case SND_FLT: /* /FILTER */
- debug(F101,"ftp put /filter getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
- if (x == -3)
- s = "";
- else
- goto xputx;
- }
- if (*s) s = brstrip(s);
- y = strlen(s);
- for (x = 0; x < y; x++) { /* Make sure they included "\v(...)" */
- if (s[x] != '\\') continue;
- if (s[x+1] == 'v') break;
- }
- if (x == y) {
- printf(
- "?Filter must contain a replacement variable for filename.\n"
- );
- x = -9;
- goto xputx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- if (pv[n].sval)
- pv[n].ival = 1;
- break;
-#endif /* PIPESEND */
-
- case SND_NAM: /* /FILENAMES */
- if (!getval) break;
- if ((x = cmkey(fntab,nfntab,"","automatic",xxstring)) < 0)
- goto xputx;
- debug(F101,"ftp put /filenames","",x);
- pv[n].ival = x;
- break;
-
- case SND_SMA: /* Smaller / larger than */
- case SND_LAR: {
- CK_OFF_T y;
- if (!getval) break;
- if ((x = cmnumw("Size in bytes","0",10,&y,xxstring)) < 0)
- goto xputx;
- pv[n].wval = y;
- break;
- }
- case SND_FIL: /* Name of file containing filenames */
- if (!getval) break;
- if ((x = cmifi("Name of file containing list of filenames",
- "",&s,&y,xxstring)) < 0) {
- if (x == -3) {
- printf("?Filename required\n");
- x = -9;
- }
- goto xputx;
- } else if (y && iswild(s)) {
- printf("?Wildcards not allowed\n");
- x = -9;
- goto xputx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- if (pv[n].sval) {
- pv[n].ival = 1;
- pv[SND_ARR].ival = 0;
- } else {
- pv[n].ival = 0;
- }
- mput = 0;
- break;
-
- case SND_MOV: /* MOVE after */
- case SND_REN: /* RENAME after */
- case SND_SRN: { /* SERVER-RENAME after */
- char * m = "";
- switch (n) {
- case SND_MOV:
- m = "device and/or directory for source file after sending";
- break;
- case SND_REN:
- m = "new name for source file after sending";
- break;
- case SND_SRN:
- m = "new name for destination file after sending";
- break;
- }
- if (!getval) break;
- if ((x = cmfld(m, "", &s, n == SND_MOV ? xxstring : NULL)) < 0) {
- if (x == -3) {
- printf("%s\n", n == SND_MOV ?
- "?Destination required" :
- "?New name required"
- );
- x = -9;
- }
- goto xputx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s ? brstrip(s) : NULL);
- pv[n].ival = (pv[n].sval) ? 1 : 0;
- break;
- }
- case SND_STA: /* Starting position (= PSEND) */
- if (!getval) break;
- if ((x = cmnum("0-based position","0",10,&y,xxstring)) < 0)
- goto xputx;
- pv[n].ival = y;
- break;
-
- case SND_TYP: /* /TYPE */
- if (!getval) break;
- if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0)
- goto xputx;
- pv[n].ival = (x == 2) ? -1 : x;
- break;
-
-#ifndef NOCSETS
- case SND_CSL: /* Local character set */
- case SND_CSR: /* Remote (server) charset */
- if ((x = cmkey(fcstab,nfilc,"","",xxstring)) < 0) {
- return((x == -3) ? -2 : x);
- }
- if (n == SND_CSL)
- x_csl = x;
- else
- x_csr = x;
- x_xla = 1; /* Overrides global OFF setting */
- break;
-
- case SND_XPA: /* Transparent */
- x_xla = 0;
- x_csr = -1;
- x_csl = -1;
- break;
-#endif /* NOCSETS */
- }
- }
-#ifdef PIPESEND
- if (pv[SND_RES].ival > 0) { /* /RECOVER */
- if (sndfilter || pv[SND_FLT].ival > 0) {
- printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n");
- x = -9;
- goto xputx;
- }
- if (sfttab[0] > 0 && sfttab[SFT_REST] == 0)
- printf("WARNING: Server says it doesn't support REST.\n");
- }
-#endif /* PIPESEND */
-
- cmarg = "";
- cmarg2 = asnambuf;
- line[0] = NUL;
- s = line;
- wild = 0;
-
- switch (cmresult.fcode) { /* How did we get out of switch loop */
- case _CMIFI: /* Input filename */
- if (pv[SND_FIL].ival > 0) {
- printf("?You may not give a PUT filespec and a /LISTFILE\n");
- x = -9;
- goto xputx;
- }
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
- if (pv[SND_ARR].ival > 0)
- ckstrncpy(asnambuf,line,CKMAXPATH);
- else
- wild = cmresult.nresult; /* Wild flag */
- debug(F111,"ftp put wild",line,wild);
- if (!wild && !recursive && !mput)
- nolinks = 0;
- break;
- case _CMFLD: /* Field */
- /* Only allowed with /COMMAND and /ARRAY */
- if (pv[SND_FIL].ival > 0) {
- printf("?You may not give a PUT filespec and a /LISTFILE\n");
- x = -9;
- goto xputx;
- }
- /* For MPUT it's OK to have filespecs that don't match any files */
- if (mput)
- break;
- if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off limits: %s\n",cmresult.sresult);
- else
-#endif /* CKROOT */
- printf("?%s - \"%s\"\n",
- iswild(cmresult.sresult) ?
- "No files match" : "File not found",
- cmresult.sresult
- );
- x = -9;
- goto xputx;
- }
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- if (pv[SND_ARR].ival > 0)
- ckstrncpy(asnambuf,line,CKMAXPATH);
- break;
- case _CMCFM: /* Confirmation */
- confirmed = 1;
- break;
- default:
- printf("?Unexpected function code: %d\n",cmresult.fcode);
- x = -9;
- goto xputx;
- }
- debug(F110,"ftp put string",s,0);
- debug(F101,"ftp put confirmed","",confirmed);
-
- /* Save and change protocol and transfer mode */
- /* Global values are restored in main parse loop */
-
- g_displa = fdispla;
- if (ftp_dis > -1)
- fdispla = ftp_dis;
- g_skipbup = skipbup;
-
- if (pv[SND_NOB].ival > -1) { /* /NOBACKUP (skip backup file) */
- g_skipbup = skipbup;
- skipbup = 1;
- }
- if (pv[SND_TYP].ival > -1) { /* /TYPE */
- xfiletype = pv[SND_TYP].ival;
- if (xfiletype == 2)
- xfiletype = -1;
- }
- if (pv[SND_BIN].ival > 0) { /* /BINARY really means binary... */
- forcetype = 1; /* So skip file scan */
- ftp_typ = FTT_BIN; /* Set binary */
- } else if (pv[SND_TXT].ival > 0) { /* Similarly for /TEXT... */
- forcetype = 1;
- ftp_typ = FTT_ASC;
- } else if (pv[SND_TEN].ival > 0) { /* and /TENEX*/
- forcetype = 1;
- ftp_typ = FTT_TEN;
- } else if (ftp_cmdlin && ftp_xfermode == XMODE_M) {
- forcetype = 1;
- ftp_typ = binary;
- g_ftp_typ = binary;
- }
-
-#ifdef PIPESEND
- if (pv[SND_CMD].ival > 0) { /* /COMMAND - strip any braces */
- debug(F110,"PUT /COMMAND before stripping",s,0);
- s = brstrip(s);
- debug(F110,"PUT /COMMAND after stripping",s,0);
- if (!*s) {
- printf("?Sorry, a command to send from is required\n");
- x = -9;
- goto xputx;
- }
- cmarg = s;
- }
-#endif /* PIPESEND */
-
-/* Set up /MOVE and /RENAME */
-
- if (pv[SND_DEL].ival > 0 &&
- (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
- printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
- x = -9;
- goto xputx;
- }
-#ifdef CK_TMPDIR
- if (pv[SND_MOV].ival > 0) {
- int len;
- char * p = pv[SND_MOV].sval;
- len = strlen(p);
- if (!isdir(p)) { /* Check directory */
-#ifdef CK_MKDIR
- char * s = NULL;
- s = (char *)malloc(len + 4);
- if (s) {
- strcpy(s,p); /* safe */
-#ifdef datageneral
- if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
-#else
- if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
-#endif /* datageneral */
- s[len++] = 'X';
- s[len] = NUL;
-#ifdef NOMKDIR
- x = -1;
-#else
- x = zmkdir(s);
-#endif /* NOMKDIR */
- free(s);
- if (x < 0) {
- printf("?Can't create \"%s\"\n",p);
- x = -9;
- goto xputx;
- }
- }
-#else
- printf("?Directory \"%s\" not found\n",p);
- x = -9;
- goto xputx;
-#endif /* CK_MKDIR */
- }
- makestr(&snd_move,p);
- }
-#endif /* CK_TMPDIR */
-
- if (pv[SND_REN].ival > 0) { /* /RENAME */
- char * p = pv[SND_REN].sval;
- if (!p) p = "";
- if (!*p) {
- printf("?New name required for /RENAME\n");
- x = -9;
- goto xputx;
- }
- p = brstrip(p);
-#ifndef NOSPL
- /* If name given is wild, rename string must contain variables */
- if (wild) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(p,&s,&x);
- if (!strcmp(tmpbuf,p)) {
- printf(
- "?/RENAME for file group must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xputx;
- }
- }
-#endif /* NOSPL */
- makestr(&snd_rename,p);
- debug(F110,"FTP snd_rename",snd_rename,0);
- }
- if (pv[SND_SRN].ival > 0) { /* /SERVER-RENAME */
- char * p = pv[SND_SRN].sval;
- if (!p) p = "";
- if (!*p) {
- printf("?New name required for /SERVER-RENAME\n");
- x = -9;
- goto xputx;
- }
- p = brstrip(p);
-#ifndef NOSPL
- if (wild) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(p,&s,&x);
- if (!strcmp(tmpbuf,p)) {
- printf(
-"?/SERVER-RENAME for file group must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xputx;
- }
- }
-#endif /* NOSPL */
- makestr(&srv_renam,p);
- debug(F110,"ftp put srv_renam",srv_renam,0);
- }
- if (!confirmed) { /* CR not typed yet, get more fields */
- char * lp;
- if (mput) { /* MPUT or MMOVE */
- nfils = 0; /* We already have the first one */
-#ifndef NOMSEND
- if (cmresult.fcode == _CMIFI) {
- /* First filespec is valid */
- msfiles[nfils++] = line; /* Store pointer */
- lp = line + (int)strlen(line) + 1; /* Point past it */
- debug(F111,"ftp put mput",msfiles[nfils-1],nfils-1);
- } else {
- /* First filespec matches no files */
- debug(F110,"ftp put mput skipping first filespec",
- cmresult.sresult,
- 0
- );
- lp = line;
- }
- /* Parse a filespec, a "field", or confirmation */
-
- cmfdbi(&sf, /* 1st FDB - file to send */
- _CMIFI, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nolinks | x_recurse, /* addtl numeric data 1 */
- 0, /* dirflg 0 means "not dirs only" */
- xxstring,
- NULL,
- &fl
- );
- cmfdbi(&fl, /* 2nd FDB - local filespec */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* 3rd FDB - Confirmation */
- _CMCFM, /* fcode */
- "",
- "",
- "",
- 0,
- 0,
- NULL,
- NULL,
- NULL
- );
-
- while (!confirmed) { /* Get more filenames */
- x = cmfdb(&sf); /* Parse something */
- debug(F101,"ftp put cmfdb B","",x);
- debug(F101,"ftp put fcode B","",cmresult.fcode);
- if (x < 0) /* Error */
- goto xputx; /* or reparse needed */
- switch (cmresult.fcode) {
- case _CMCFM: /* End of command */
- confirmed++;
- if (nfils < 1) {
- debug(F100,"ftp put mput no files match","",0);
- printf("?No files match MPUT list\n");
- x = -9;
- goto xputx;
- }
- break;
- case _CMFLD: /* No match */
- debug(F110,"ftp put mput skipping",cmresult.sresult,0);
- continue;
- case _CMIFI: /* Good match */
- s = cmresult.sresult;
- msfiles[nfils++] = lp; /* Got one, count, point to it, */
- p = lp; /* remember pointer, */
- while ((*lp++ = *s++)) /* and copy it into buffer */
- if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
- printf("?MPUT list too long\n");
- line[0] = NUL;
- x = -9;
- goto xputx;
- }
- debug(F111,"ftp put mput adding",msfiles[nfils-1],nfils-1);
- if (nfils == 1) /* Take care of \v(filespec) */
- fspec[0] = NUL;
-#ifdef ZFNQFP
- zfnqfp(p,TMPBUFSIZ,tmpbuf);
- p = tmpbuf;
-#endif /* ZFNQFP */
- if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
- strcat(fspec,p); /* safe */
- strcat(fspec," "); /* safe */
- } else {
-#ifdef COMMENT
- printf("WARNING - \\v(filespec) buffer overflow\n");
-#else
- debug(F101,"doxput filespec buffer overflow","",0);
-#endif /* COMMENT */
- }
- }
- }
-#endif /* NOMSEND */
- } else { /* Regular PUT */
- nfils = -1;
- if ((x = cmtxt(wild ?
-"\nOptional as-name template containing replacement variables \
-like \\v(filename)" :
- "Optional name to send it with",
- "",&p,NULL)) < 0)
- goto xputx;
-
- if (p) if (!*p) p = NULL;
- p = brstrip(p);
-
- if (p && *p) {
- makestr(&(pv[SND_ASN].sval),p);
- if (pv[SND_ASN].sval)
- pv[SND_ASN].ival = 1;
- debug(F110,"ftp put /as-name 2",pv[SND_ASN].sval,0);
- }
- }
- }
- /* Set cmarg2 from as-name, however we got it. */
-
- CHECKCONN();
- if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !asnambuf[0]) {
- char * p;
- p = brstrip(pv[SND_ASN].sval);
- ckstrncpy(asnambuf,p,CKMAXPATH+1);
- }
- debug(F110,"ftp put asnambuf",asnambuf,0);
-
- if (pv[SND_FIL].ival > 0) {
- if (confirmed) {
- if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
- debug(F110,"ftp put can't open",pv[SND_FIL].sval,0);
- printf("?Failure to open %s\n",pv[SND_FIL].sval);
- x = -9;
- goto xputx;
- }
- makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */
- debug(F110,"ftp PUT /LISTFILE opened",filefile,0);
- wild = 1;
- }
- }
- if (confirmed && !line[0] && !filefile) {
-#ifndef NOMSEND
- if (filehead) { /* OK if we have a SEND-LIST */
- nfils = filesinlist;
- sndsrc = nfils; /* Like MSEND */
- addlist = 1; /* But using a different list... */
- filenext = filehead;
- goto doput;
- }
-#endif /* NOMSEND */
- printf("?Filename required but not given\n");
- x = -9;
- goto xputx;
- }
-#ifndef NOMSEND
- addlist = 0; /* Don't use SEND-LIST. */
-#endif /* NOMSEND */
-
- if (mput) { /* MPUT (rather than PUT) */
-#ifndef NOMSEND
- cmlist = msfiles; /* List of filespecs */
- sndsrc = nfils; /* rather filespec and as-name */
-#endif /* NOMSEND */
- pipesend = 0;
- } else if (filefile) { /* File contains list of filenames */
- s = "";
- cmarg = "";
- line[0] = NUL;
- nfils = 1;
- sndsrc = 1;
-
- } else if (pv[SND_ARR].ival < 1 && pv[SND_CMD].ival < 1) {
-
- /* Not MSEND, MMOVE, /LIST, or /ARRAY */
- nfils = sndsrc = -1;
- if (!wild) {
- if (zchki(s) < 0) {
- printf("?Read access denied - \"%s\"\n", s);
- x = -9;
- goto xputx;
- }
- }
- if (s != line) /* We might already have done this. */
- ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */
-#ifdef DEBUG
- else
- debug(F110,"doxput line=s",line,0);
-#endif /* DEBUG */
- cmarg = line; /* File to send */
- }
-#ifndef NOMSEND
- zfnqfp(cmarg,fspeclen,fspec); /* Get full name */
-#endif /* NOMSEND */
-
- if (!mput) { /* For all but MPUT... */
-#ifdef PIPESEND
- if (pv[SND_CMD].ival > 0) /* /COMMAND sets pipesend flag */
- pipesend = 1;
- debug(F101,"ftp put /COMMAND pipesend","",pipesend);
- if (pipesend && filefile) {
- printf("?Invalid switch combination\n");
- x = -9;
- goto xputx;
- }
-#endif /* PIPESEND */
-
-#ifndef NOSPL
- /* If as-name given and filespec is wild, as-name must contain variables */
- if ((wild || mput) && asnambuf[0]) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(asnambuf,&s,&x);
- if (!strcmp(tmpbuf,asnambuf)) {
- printf(
- "?As-name for file group must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xputx;
- }
- }
-#endif /* NOSPL */
- }
-
- doput:
-
- if (pv[SND_SHH].ival > 0) { /* SEND /QUIET... */
- fdispla = 0;
- debug(F101,"ftp put display","",fdispla);
- } else {
- displa = 1;
- if (ftp_deb)
- fdispla = XYFD_B;
- }
-
-#ifdef PUTARRAY /* SEND /ARRAY... */
- if (pv[SND_ARR].ival > 0) {
- if (!ap) { x = -2; goto xputx; } /* (shouldn't happen) */
- if (range[0] == -1) /* If low end of range not specified */
- range[0] = 1; /* default to 1 */
- if (range[1] == -1) /* If high not specified */
- range[1] = a_dim[arrayx]; /* default to size of array */
- if ((range[0] < 0) || /* Check range */
- (range[0] > a_dim[arrayx]) ||
- (range[1] < range[0]) ||
- (range[1] > a_dim[arrayx])) {
- printf("?Bad array range - [%d:%d]\n",range[0],range[1]);
- x = -9;
- goto xputx;
- }
- sndarray = ap; /* Array pointer */
- sndxin = arrayx; /* Array index */
- sndxlo = range[0]; /* Array range */
- sndxhi = range[1];
- sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE);
- if (!asnambuf[0])
- ckstrncpy(asnambuf,sndxnam,CKMAXPATH);
- cmarg = "";
- }
-#endif /* PUTARRAY */
-
- moving = 0;
-
- if (pv[SND_ARR].ival < 1) { /* File selection & disposition... */
- if (pv[SND_DEL].ival > 0) /* /DELETE was specified */
- moving = 1;
- if (pv[SND_AFT].ival > 0) /* Copy SEND criteria */
- ckstrncpy(sndafter,pv[SND_AFT].sval,19);
- if (pv[SND_BEF].ival > 0)
- ckstrncpy(sndbefore,pv[SND_BEF].sval,19);
- if (pv[SND_NAF].ival > 0)
- ckstrncpy(sndnafter,pv[SND_NAF].sval,19);
- if (pv[SND_NBE].ival > 0)
- ckstrncpy(sndnbefore,pv[SND_NBE].sval,19);
- if (pv[SND_EXC].ival > 0)
- makelist(pv[SND_EXC].sval,sndexcept,NSNDEXCEPT);
- if (pv[SND_SMA].ival > -1)
- sndsmaller = pv[SND_SMA].wval;
- if (pv[SND_LAR].ival > -1)
- sndlarger = pv[SND_LAR].wval;
- if (pv[SND_NAM].ival > -1)
- x_cnv = pv[SND_NAM].ival;
- if (pv[SND_USN].ival > -1)
- x_usn = pv[SND_USN].ival;
- if (pv[SND_ERR].ival > -1)
- puterror = pv[SND_ERR].ival;
-
-#ifdef DOUPDATE
- if (pv[SND_UPD].ival > 0) {
- if (x_usn) {
- printf("?Conflicting switches: /UPDATE /UNIQUE\n");
- x = -9;
- goto xputx;
- }
- putflags |= PUT_UPD;
- ftp_dates |= 2;
- }
-#ifdef COMMENT
- /* This works but it's useless, maybe dangerous */
- if (pv[SND_DIF].ival > 0) {
- if (x_usn) {
- printf("?Conflicting switches: /DATES-DIFFER /UNIQUE\n");
- x = -9;
- goto xputx;
- }
- putflags |= PUT_DIF;
- ftp_dates |= 2;
- }
-#endif /* COMMENT */
-#endif /* DOUPDATE */
-
- if (pv[SND_SIM].ival > 0)
- putflags |= PUT_SIM;
-
- if (pv[SND_PRM].ival > -1) {
-#ifdef UNIX
- if (x_usn) {
- printf("?Conflicting switches: /PERMISSIONS /UNIQUE\n");
- x = -9;
- goto xputx;
- }
- x_prm = pv[SND_PRM].ival;
-#else /* UNIX */
- printf("?/PERMISSIONS switch is not supported\n");
-#endif /* UNIX */
- }
-#ifdef FTP_RESTART
- if (pv[SND_RES].ival > 0) {
- if (!sizeok) {
- printf("?PUT /RESTART can't be used because SIZE disabled.\n");
- x = -9;
- goto xputx;
- }
- if (x_usn || putflags) {
- printf("?Conflicting switches: /RECOVER %s\n",
- x_usn && putflags ? "/UNIQUE /UPDATE" :
- (x_usn ? "/UNIQUE" : "/UPDATE")
- );
- x = -9;
- goto xputx;
- }
-#ifndef NOCSETS
- if (x_xla &&
- (x_csl == FC_UCS2 ||
- x_csl == FC_UTF8 ||
- x_csr == FC_UCS2 ||
- x_csr == FC_UTF8)) {
- printf("?/RECOVER can not be used with Unicode translation\n");
- x = -9;
- goto xputx;
- }
-#endif /* NOCSETS */
- putflags = PUT_RES;
- }
-#endif /* FTP_RESTART */
- }
- debug(F101,"ftp PUT restart","",putflags & PUT_RES);
- debug(F101,"ftp PUT update","",putflags & PUT_UPD);
-
-#ifdef PIPESEND
- if (pv[SND_FLT].ival > 0) { /* Have SEND FILTER? */
- if (!pv[SND_FLT].sval) {
- sndfilter = NULL;
- } else {
- sndfilter = (char *) malloc((int) strlen(pv[SND_FLT].sval) + 1);
- if (sndfilter) strcpy(sndfilter,pv[SND_FLT].sval); /* safe */
- }
- debug(F110,"ftp put /FILTER", sndfilter, 0);
- }
- if (sndfilter || pipesend) /* No /UPDATE or /RESTART */
- if (putflags) /* with pipes or filters */
- putflags = 0;
-#endif /* PIPESEND */
-
- tfc = (CK_OFF_T)0; /* Initialize stats and counters */
- filcnt = 0;
- pktnum = 0;
- spackets = 0L;
-
- if (wild) /* (is this necessary?) */
- cx = FTP_MPU;
-
- t0 = gmstimer(); /* Record starting time */
-
- done = 0; /* Loop control */
- cancelgroup = 0;
-
- cdlevel = 0;
- cdsimlvl = 0;
- while (!done && !cancelgroup) { /* Loop for all files */
- /* or until canceled. */
-#ifdef FTP_PROXY
- /*
- If we are using a proxy, we don't use the local file list;
- instead we use the list on the remote machine which we want
- sent to someone else, and we use remglob() to get the names.
- But in that case we shouldn't even be executing this routine;
- see ftp_mput().
- */
-#endif /* FTP_PROXY */
-
- cancelfile = 0;
- x = gnfile(); /* Get next file from list(s) */
-
- if (x == 0) /* (see gnfile() comments...) */
- x = gnferror;
- debug(F111,"FTP PUT gnfile",filnam,x);
- debug(F111,"FTP PUT binary",filnam,binary);
-
- switch (x) {
- case 1: /* File to send */
- s2 = asnambuf;
-#ifndef NOSPL
- if (asnambuf[0]) { /* As-name */
- int n; char *p; /* to be evaluated... */
- n = TMPBUFSIZ;
- p = tmpbuf;
- zzstring(asnambuf,&p,&n);
- s2 = tmpbuf;
- debug(F110,"ftp put asname",s2,0);
- }
-#endif /* NOSPL */
- rc = putfile(cx, /* Function (PUT, APPEND) */
- filnam, s2, /* Name to send, as-name */
- forcetype, moving, /* Parameters from switches... */
- snd_move, snd_rename, srv_renam,
- x_cnv, x_usn, xfiletype, x_prm,
-#ifndef NOCSETS
- x_csl, (!x_xla ? -1 : x_csr),
-#else
- -1, -1,
-#endif /* NOCSETS */
- putflags
- );
- debug(F111,"ftp put putfile rc",filnam,rc);
- debug(F111,"ftp put putfile cancelfile",filnam,cancelfile);
- debug(F111,"ftp put putfile cancelgroup",filnam,cancelgroup);
- if (rc > -1) {
- good++;
- status = 1;
- }
- if (cancelfile)
- continue;
- if (rc < 0) {
- ftp_fai++;
- if (puterror) {
- status = 0;
- printf("?Fatal upload error: %s\n",filnam);
- done++;
- }
- }
- continue;
- case 0: /* No more files, done */
- done++;
- continue;
- case -1:
- printf("?%s: file not found - \"%s\"\n",
- puterror ? "Fatal" : "Warning",
- filnam
- );
- if (puterror) {
- status = 0;
- done++;
- break;
- }
- continue;
- case -2:
- if (puterror) {
- printf("?Fatal: file not found - \"%s\"\n", filnam);
- status = 0;
- done++;
- break;
- }
- continue; /* Not readable, keep going */
- case -3:
- if (puterror) {
- printf("?Fatal: Read access denied - \"%s\"\n", filnam);
- status = 0;
- done++;
- break;
- }
- printf("?Warning access denied - \"%s\"\n", filnam);
- continue;
-#ifdef COMMENT
- case -4: /* Canceled */
- done++;
- break;
-#endif /* COMMENT */
- case -5:
- printf("?Too many files match\n");
- done++;
- break;
- case -6:
- if (good < 1)
- printf("?No files selected\n");
- done++;
- break;
- default:
- printf("?getnextfile() - unknown failure\n");
- done++;
- }
- }
- if (cdlevel > 0) {
- while (cdlevel--) {
- if (cdsimlvl) {
- cdsimlvl--;
- } else if (!doftpcdup())
- break;
- }
- }
- if (status > 0) {
- if (cancelgroup)
- status = 0;
- else if (cancelfile && good < 1)
- status = 0;
- }
- success = status;
- x = success;
-
- xputx:
- if (x > -1) {
-#ifdef GFTIMER
- t1 = gmstimer(); /* End time */
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- if (!sec) sec = 0.001;
- fptsecs = sec;
-#else
- sec = (t1 - t0) / 1000;
- if (!sec) sec = 1;
-#endif /* GFTIMER */
- tfcps = (long) (tfc / sec);
- tsecs = (int)sec;
- lastxfer = W_FTP|W_SEND;
- xferstat = success;
- if (dpyactive)
- ftscreen(status > 0 ? SCR_TC : SCR_CW, 0, (CK_OFF_T)0, "");
- }
- for (i = 0; i <= SND_MAX; i++) { /* Free malloc'd memory */
- if (pv[i].sval)
- free(pv[i].sval);
- }
- ftreset(); /* Undo switch effects */
- dpyactive = 0;
- return(x);
-}
-
-
-static char ** mgetlist = NULL; /* For MGET */
-static int mgetn = 0, mgetx = 0;
-static char xtmpbuf[4096];
-
-/*
- c m d l i n g e t
-
- Get files specified by -g command-line option.
- File list is set up in cmlist[] by ckuusy.c; nfils is length of list.
-*/
-int
-cmdlinget(stay) int stay; {
- int i, x, rc = 0, done = 0, good = 0, status = 0, append = 0;
- int lcs = -1, rcs = -1, xlate = 0;
- int first = 1;
- int mget = 1;
- int nc;
- char * s, * s2, * s3;
- ULONG t0, t1; /* Times for stats */
-#ifdef GFTIMER
- CKFLOAT sec;
-#else
- int sec = 0;
-#endif /* GFTIMER */
-
- if (quiet) { /* -q really means quiet */
- displa = 0;
- fdispla = 0;
- } else {
- displa = 1;
- fdispla = XYFD_B;
- }
- testing = 0;
- dpyactive = 0;
- out2screen = 0;
- what = W_FTP|W_RECV;
- mgetmethod = 0;
- mgetforced = 0;
-
- havetype = 0;
- havesize = (CK_OFF_T)-1;
- makestr(&havemdtm,NULL);
-
- if (ftp_fnc < 0)
- ftp_fnc = fncact;
-
-#ifndef NOSPL
- cmd_quoting = 0;
-#endif /* NOSPL */
- debug(F101,"ftp cmdlinget nfils","",nfils);
-
- if (ftp_cnv == CNV_AUTO) { /* Name conversion is auto */
- if (alike) { /* If server & client are alike */
- nc = 0; /* no conversion */
- } else { /* If they are different */
- if (servertype == SYS_UNIX || servertype == SYS_WIN32)
- nc = -1; /* only minimal conversions needed */
- else /* otherwise */
- nc = 1; /* full conversion */
- }
- } else /* Not auto - do what user said */
- nc = ftp_cnv;
-
- if (nfils < 1)
- doexit(BAD_EXIT,-1);
-
- t0 = gmstimer(); /* Starting time for this batch */
-
-#ifndef NOCSETS
- if (xlate) { /* SET FTP CHARACTER-SET-TRANSLATION */
- lcs = ftp_csl; /* Local charset */
- if (lcs < 0) lcs = fcharset;
- if (lcs < 0) xlate = 0;
- }
- if (xlate) { /* Still ON? */
- rcs = ftp_csx; /* Remote (Server) charset */
- if (rcs < 0) rcs = ftp_csr;
- if (rcs < 0) xlate = 0;
- }
-#endif /* NOCSETS */
- /*
- If we have only one file and it is a directory, then we ask for a
- listing of its contents, rather than retrieving the directory file
- itself. This is what (e.g.) Netscape does.
- */
- if (nfils == 1) {
- if (doftpcwd((char *)cmlist[mgetx],-1)) {
- /* If we can CD to it, it must be a directory */
- if (recursive) {
- cmlist[mgetx] = "*";
- } else {
- status =
- (recvrequest("LIST","-","","wb",0,0,NULL,xlate,lcs,rcs)==0);
- done = 1;
- }
- }
- }
-/*
- The following is to work around UNIX servers which, when given a command
- like "NLST path/blah" (not wild) returns the basename without the path.
-*/
- if (!done && servertype == SYS_UNIX && nfils == 1) {
- mget = iswild(cmlist[mgetx]);
- }
- if (!mget && !done) { /* Invoked by command-line FTP URL */
- if (ftp_deb)
- printf("DOING GET...\n");
- done++;
- cancelfile = 0; /* This file not canceled yet */
- s = cmlist[mgetx];
- rc = 0; /* Initial return code */
- fsize = (CK_OFF_T)-1;
- if (sizeok) {
- x = ftpcmd("SIZE",s,lcs,rcs,ftp_vbm); /* Get remote file's size */
- if (x == REPLY_COMPLETE)
- fsize = ckatofs(&ftp_reply_str[4]);
- }
- ckstrncpy(filnam,s,CKMAXPATH); /* For \v(filename) */
- debug(F111,"ftp cmdlinget filnam",filnam,fsize);
-
- nzrtol(s,tmpbuf,nc,0,CKMAXPATH); /* Strip path and maybe convert */
- s2 = tmpbuf;
-
- /* If local file already exists, take collision action */
-
- if (zchki(s2) > -1) {
- switch (ftp_fnc) {
- case XYFX_A: /* Append */
- append = 1;
- break;
- case XYFX_R: /* Rename */
- case XYFX_B: { /* Backup */
- char * p = NULL;
- int x = -1;
- znewn(s2,&p); /* Make unique name */
- debug(F110,"ftp cmdlinget znewn",p,0);
- if (ftp_fnc == XYFX_B) { /* Backup existing file */
- x = zrename(s2,p);
- debug(F111,"ftp cmdlinget backup zrename",p,x);
- } else { /* Rename incoming file */
- x = ckstrncpy(tmpbuf,p,CKMAXPATH+1);
- s2 = tmpbuf;
- debug(F111,"ftp cmdlinget rename incoming",p,x);
- }
- if (x < 0) {
- printf("?Backup/Rename failed\n");
- return(success = 0);
- }
- break;
- }
- case XYFX_D: /* Discard */
- ftscreen(SCR_FN,'F',(CK_OFF_T)0,s);
- ftscreen(SCR_ST,ST_SKIP,(CK_OFF_T)SKP_NAM,s);
- tlog(F100," refused: name","",0);
- debug(F110,"ftp cmdlinget skip name",s2,0);
- goto xclget;
-
- case XYFX_X: /* Overwrite */
- case XYFX_U: /* Update (already handled above) */
- case XYFX_M: /* ditto */
- break;
- }
- }
- rc = getfile(s, /* Remote name */
- s2, /* Local name */
- 0, /* Recover/Restart */
- append, /* Append */
- NULL, /* Pipename */
- 0, /* Translate charsets */
- -1, /* File charset (none) */
- -1 /* Server charset (none) */
- );
- debug(F111,"ftp cmdlinget rc",s,rc);
- debug(F111,"ftp cmdlinget cancelfile",s,cancelfile);
- debug(F111,"ftp cmdlinget cancelgroup",s,cancelgroup);
-
- if (rc < 0 && haveurl && s[0] == '/') /* URL failed - try again */
- rc = getfile(&s[1], /* Remote name without leading '/' */
- s2, /* Local name */
- 0, /* Recover/Restart */
- append, /* Append */
- NULL, /* Pipename */
- 0, /* Translate charsets */
- -1, /* File charset (none) */
- -1 /* Server charset (none) */
- );
- if (rc > -1) {
- good++;
- status = 1;
- }
- if (cancelfile)
- goto xclget;
- if (rc < 0) {
- ftp_fai++;
-#ifdef FTP_TIMEOUT
- if (ftp_timed_out)
- status = 0;
-#endif /* FTP_TIMEOUT */
- if (geterror) {
- status = 0;
- done++;
- }
- }
- }
- if (ftp_deb && !done)
- printf("DOING MGET...\n");
- while (!done && !cancelgroup) {
- cancelfile = 0; /* This file not canceled yet */
- s = (char *)remote_files(first,(CHAR *)cmlist[mgetx],NULL,0);
- if (!s) s = "";
- if (!*s) {
- first = 1;
- mgetx++;
- if (mgetx < nfils)
- s = (char *)remote_files(first,(CHAR *)cmlist[mgetx],NULL,0);
- else
- s = NULL;
- debug(F111,"ftp cmdlinget remote_files B",s,0);
- if (!s) {
- done = 1;
- break;
- }
- }
- /*
- The semantics of NLST are ill-defined. Suppose we have just sent
- NLST /path/[a-z]*. Most servers send back names like /path/foo,
- /path/bar, etc. But some send back only foo and bar, and subsequent
- RETR commands based on the pathless names are not going to work.
- */
- if (servertype == SYS_UNIX && !ckstrchr(s,'/')) {
- if ((s3 = ckstrrchr(cmlist[mgetx],'/'))) {
- int len, left = 4096;
- char * tmp = xtmpbuf;
- len = s3 - cmlist[mgetx] + 1;
- ckstrncpy(tmp,cmlist[mgetx],left);
- tmp += len;
- left -= len;
- ckstrncpy(tmp,s,left);
- s = xtmpbuf;
- debug(F111,"ftp cmdlinget remote_files X",s,0);
- }
- }
- first = 0; /* Not first any more */
-
- debug(F111,"ftp cmdlinget havetype",s,havetype);
- if (havetype > 0 && havetype != FTYP_FILE) { /* Server says not file */
- debug(F110,"ftp cmdlinget not-a-file",s,0);
- continue;
- }
- rc = 0; /* Initial return code */
- if (havesize > (CK_OFF_T)-1) { /* Already have file size? */
- fsize = havesize;
- } else { /* No - must ask server */
- /*
- Prior to sending the NLST command we necessarily put the
- server into ASCII mode. We must now put it back into the
- the requested mode so the upcoming SIZE command returns
- right kind of size; this is especially important for
- GET /RECOVER; otherwise the server returns the "ASCII" size
- of the file, rather than its true size.
- */
- changetype(ftp_typ,0); /* Change to requested type */
- fsize = (CK_OFF_T)-1;
- if (sizeok) {
- x = ftpcmd("SIZE",s,lcs,rcs,ftp_vbm);
- if (x == REPLY_COMPLETE)
- fsize = ckatofs(&ftp_reply_str[4]);
- }
- }
- ckstrncpy(filnam,s,CKMAXPATH); /* For \v(filename) */
- debug(F111,"ftp cmdlinget filnam",filnam,fsize);
-
- nzrtol(s,tmpbuf,nc,0,CKMAXPATH); /* Strip path and maybe convert */
- s2 = tmpbuf;
-
- /* If local file already exists, take collision action */
-
- if (zchki(s2) > -1) {
- switch (ftp_fnc) {
- case XYFX_A: /* Append */
- append = 1;
- break;
- case XYFX_R: /* Rename */
- case XYFX_B: { /* Backup */
- char * p = NULL;
- int x = -1;
- znewn(s2,&p); /* Make unique name */
- debug(F110,"ftp cmdlinget znewn",p,0);
- if (ftp_fnc == XYFX_B) { /* Backup existing file */
- x = zrename(s2,p);
- debug(F111,"ftp cmdlinget backup zrename",p,x);
- } else { /* Rename incoming file */
- x = ckstrncpy(tmpbuf,p,CKMAXPATH+1);
- s2 = tmpbuf;
- debug(F111,"ftp cmdlinget rename incoming",p,x);
- }
- if (x < 0) {
- printf("?Backup/Rename failed\n");
- return(success = 0);
- }
- break;
- }
- case XYFX_D: /* Discard */
- ftscreen(SCR_FN,'F',(CK_OFF_T)0,s);
- ftscreen(SCR_ST,ST_SKIP,(CK_OFF_T)SKP_NAM,s);
- tlog(F100," refused: name","",0);
- debug(F110,"ftp cmdlinget skip name",s2,0);
- continue;
- case XYFX_X: /* Overwrite */
- case XYFX_U: /* Update (already handled above) */
- case XYFX_M: /* ditto */
- break;
- }
- }
- /* ^^^ ADD CHARSET STUFF HERE ^^^ */
- rc = getfile(s, /* Remote name */
- s2, /* Local name */
- 0, /* Recover/Restart */
- append, /* Append */
- NULL, /* Pipename */
- 0, /* Translate charsets */
- -1, /* File charset (none) */
- -1 /* Server charset (none) */
- );
- debug(F111,"ftp cmdlinget rc",s,rc);
- debug(F111,"ftp cmdlinget cancelfile",s,cancelfile);
- debug(F111,"ftp cmdlinget cancelgroup",s,cancelgroup);
-
- if (rc > -1) {
- good++;
- status = 1;
- }
- if (cancelfile)
- continue;
- if (rc < 0) {
- ftp_fai++;
-#ifdef FTP_TIMEOUT
- if (ftp_timed_out)
- status = 0;
-#endif /* FTP_TIMEOUT */
- if (geterror) {
- status = 0;
- done++;
- }
- }
- }
-
- xclget:
- if (cancelgroup)
- mlsreset();
- if (status > 0) {
- if (cancelgroup)
- status = 0;
- else if (cancelfile && good < 1)
- status = 0;
- }
- success = status;
-
-#ifdef GFTIMER
- t1 = gmstimer(); /* End time */
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- if (!sec) sec = 0.001;
- fptsecs = sec;
-#else
- sec = (t1 - t0) / 1000;
- if (!sec) sec = 1;
-#endif /* GFTIMER */
-
- tfcps = (long) (tfc / sec);
- tsecs = (int)sec;
- lastxfer = W_FTP|W_RECV;
- xferstat = success;
- if (dpyactive)
- ftscreen(status > 0 ? SCR_TC : SCR_CW, 0, (CK_OFF_T)0, "");
- if (!stay)
- doexit(success ? GOOD_EXIT : BAD_EXIT, -1);
- return(success);
-}
-
-/* d o f t p g e t -- Parse and execute GET, MGET, MDELETE, ... */
-
-/*
- Note: if we wanted to implement /AFTER:, /BEFORE:, etc, we could use
- zstrdat() to convert to UTC-based time_t. But it doesn't make sense from
- the user-interface perspective, since the server's directory listings show
- its own local times and since we don't know what timezone it's in, there's
- no way to reconcile our local times with the server's.
-*/
-int
-doftpget(cx,who) int cx, who; { /* who == 1 for ftp, 0 for kermit */
- struct FDB fl, sw, cm;
- int i, n, rc, getval = 0, mget = 0, done = 0, pipesave = 0;
- int x_cnv = 0, x_prm = 0, restart = 0, status = 0, good = 0;
- int x_fnc = 0, first = 0, skipthis = 0, append = 0, selected = 0;
- int renaming = 0, mdel = 0, listfile = 0, updating = 0, getone = 0;
- int moving = 0, deleting = 0, toscreen = 0, haspath = 0;
- int gotsize = 0;
- int matchdot = 0;
- CK_OFF_T getlarger = (CK_OFF_T)-1;
- CK_OFF_T getsmaller = (CK_OFF_T)-1;
- char * msg, * s, * s2, * nam, * pipename = NULL, * pn = NULL;
- char * src = "", * local = "";
- char * pat = "";
-
- int x_csl = -1, x_csr = -1; /* Local and remote charsets */
- int x_xla = 0;
- char c; /* Worker char */
- ULONG t0 = 0L, t1; /* Times for stats */
-#ifdef GFTIMER
- CKFLOAT sec;
-#else
- int sec = 0;
-#endif /* GFTIMER */
-
- struct stringint pv[SND_MAX+1]; /* Temporary array for switch values */
-
- success = 0; /* Assume failure */
- forcetype = 0; /* No /TEXT or /BINARY given yet */
- restart = 0; /* No restart yet */
- out2screen = 0; /* No TO-SCREEN switch given yet */
- mgetmethod = 0; /* No NLST or MLSD switch yet */
- mgetforced = 0;
-
- g_displa = fdispla;
- if (ftp_dis > -1)
- fdispla = ftp_dis;
-
- x_cnv = ftp_cnv; /* Filename conversion */
- if (x_cnv == CNV_AUTO) { /* Name conversion is auto */
- if (alike) { /* If server & client are alike */
- x_cnv = 0; /* no conversion */
- } else { /* If they are different */
- if (servertype == SYS_UNIX || servertype == SYS_WIN32)
- x_cnv = -1; /* only minimal conversions needed */
- else /* otherwise */
- x_cnv = 1; /* full conversion */
- }
- } else /* Not auto - do what user said */
- x_cnv = ftp_cnv;
-
- x_prm = ftp_prm; /* Permissions */
- if (x_prm == SET_AUTO) /* Permissions AUTO */
- x_prm = alike;
-
-#ifndef NOCSETS
- x_csr = ftp_csr; /* Inherit global server charset */
- x_csl = ftp_csl; /* Inherit global local charset */
- if (x_csl < 0) /* If none, use current */
- x_csl = fcharset; /* file character-set. */
- x_xla = ftp_xla; /* Translation On/Off */
-#endif /* NOCSETS */
-
- geterror = ftp_err; /* Inherit global error action. */
- asnambuf[0] = NUL; /* No as-name yet. */
- pipesave = pipesend;
- pipesend = 0;
-
- havetype = 0;
- havesize = (CK_OFF_T)-1;
- makestr(&havemdtm,NULL);
-
- if (g_ftp_typ > -1) { /* Restore TYPE if saved */
- ftp_typ = g_ftp_typ;
- /* g_ftp_typ = -1; */
- }
- for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */
- pv[i].sval = NULL; /* to null pointers */
- pv[i].ival = -1; /* and -1 int values */
- pv[i].wval = (CK_OFF_T)-1; /* and -1 wide values */
- }
- zclose(ZMFILE); /* In case it was left open */
-
- x_fnc = ftp_fnc > -1 ? ftp_fnc : fncact; /* Filename collision action */
-
- if (fp_nml) { /* Reset /NAMELIST */
- if (fp_nml != stdout)
- fclose(fp_nml);
- fp_nml = NULL;
- }
- makestr(&ftp_nml,NULL);
-
- /* Initialize list of remote filespecs */
-
- if (!mgetlist) {
- mgetlist = (char **)malloc(MGETMAX * sizeof(char *));
- if (!mgetlist) {
- printf("?Memory allocation failure - MGET list\n");
- return(-9);
- }
- for (i = 0; i < MGETMAX; i++)
- mgetlist[i] = NULL;
- }
- mgetn = 0; /* Number of mget arguments */
- mgetx = 0; /* Current arg */
-
- if (who == 0) { /* Called with unprefixed command */
- if (cx == XXGET || cx == XXREGET || cx == XXRETR)
- getone++;
- switch (cx) {
- case XXREGET: pv[SND_RES].ival = 1; break;
- case XXRETR: pv[SND_DEL].ival = 1; break;
- case XXGET:
- case XXMGET: mget++; break;
- }
- } else { /* FTP command */
- if (cx == FTP_GET || cx == FTP_RGE)
- getone++;
- switch (cx) {
- case FTP_DEL: /* (fall thru on purpose) */
- case FTP_MDE: mdel++; /* (ditto) */
- case FTP_GET: /* (ditto) */
- case FTP_MGE: mget++; break;
- case FTP_RGE: pv[SND_RES].ival = 1; break;
- }
- }
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Remote filename;\n or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- mdel ? ndelswi : ngetswi, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- mdel ? delswi : getswi, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* 2nd FDB - remote filename */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* 3rd FDB - Confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
-
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse something */
- debug(F101,"ftp get cmfdb","",x);
- if (x < 0) /* Error */
- goto xgetx; /* or reparse needed */
- if (cmresult.fcode != _CMKEY) /* Break out of loop if not a switch */
- break;
- c = cmgbrk(); /* Get break character */
- getval = (c == ':' || c == '='); /* to see how they ended the switch */
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- x = -9;
- goto xgetx;
- }
- n = cmresult.nresult; /* Numeric result = switch value */
- debug(F101,"ftp get switch","",n);
-
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- x = -9;
- goto xgetx;
- }
- switch (n) { /* Process the switch */
- case SND_ASN: /* /AS-NAME: */
- debug(F101,"ftp get /as-name getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Name to store it under","",&s,NULL)) < 0) {
- if (x == -3) {
- printf("?name required\n");
- x = -9;
- }
- goto xgetx;
- }
- s = brstrip(s);
- if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- pv[n].ival = 1;
- break;
-
- case SND_BIN: /* /BINARY */
- case SND_TXT: /* /TEXT or /ASCII */
- case SND_TEN: /* /TENEX */
- pv[SND_BIN].ival = 0;
- pv[SND_TXT].ival = 0;
- pv[SND_TEN].ival = 0;
- pv[n].ival = 1;
- break;
-
-#ifdef PUTPIPE
- case SND_CMD: /* These take no args */
- if (nopush) {
- printf("?Sorry, system command access is disabled\n");
- x = -9;
- goto xgetx;
- }
-#ifdef PIPESEND
- else if (rcvfilter) {
- printf("?Sorry, no PUT /COMMAND when SEND FILTER selected\n");
- x = -9;
- goto xgetx;
- }
-#endif /* PIPESEND */
- sw.hlpmsg = "Command, or switch"; /* Change help message */
- pv[n].ival = 1; /* Just set the flag */
- pv[SND_ARR].ival = 0;
- break;
-#endif /* PUTPIPE */
-
- case SND_SHH: /* /QUIET */
- case SND_RES: /* /RECOVER (reget) */
- case SND_NOB: /* /NOBACKUPFILES */
- case SND_DEL: /* /DELETE */
- case SND_UPD: /* /UPDATE */
- case SND_USN: /* /UNIQUE */
- case SND_NOD: /* /NODOTFILES */
- case SND_REC: /* /RECOVER */
- case SND_MAI: /* /TO-SCREEN */
- pv[n].ival = 1; /* Just set the flag */
- break;
-
- case SND_DIF: /* /DATES-DIFFER */
- pv[SND_COL].ival = XYFX_M; /* Now it's a collision option */
- pv[n].ival = 1;
- break;
-
- case SND_COL: /* /COLLISION: */
- if ((x = cmkey(ftpcolxtab,nftpcolx,"","",xxstring)) < 0)
- goto xgetx;
- if (x == XYFX_M)
- pv[SND_DIF].ival = 1; /* (phase this out) */
- pv[n].ival = x; /* this should be sufficient */
- break;
-
- case SND_ERR: /* /ERROR-ACTION */
- if ((x = cmkey(qorp,2,"","",xxstring)) < 0)
- goto xgetx;
- pv[n].ival = x;
- break;
-
- case SND_EXC: /* Exception list */
- if (!getval) break;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Pattern required\n");
- x = -9;
- }
- goto xgetx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- if (pv[n].sval)
- pv[n].ival = 1;
- break;
-
-#ifdef PIPESEND
- case SND_FLT:
- debug(F101,"ftp get /filter getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
- if (x == -3)
- s = "";
- else
- goto xgetx;
- }
- s = brstrip(s);
- if (pv[SND_MAI].ival < 1) {
- y = strlen(s);
- /* Make sure they included "\v(...)" */
- for (x = 0; x < y; x++) {
- if (s[x] != '\\') continue;
- if (s[x+1] == 'v') break;
- }
- if (x == y) {
- printf(
- "?Filter must contain a replacement variable for filename.\n"
- );
- x = -9;
- goto xgetx;
- }
- }
- if (*s) {
- pv[n].ival = 1;
- makestr(&(pv[n].sval),s);
- } else {
- pv[n].ival = 0;
- makestr(&(pv[n].sval),NULL);
- }
- break;
-#endif /* PIPESEND */
-
- case SND_NAM:
- if (!getval) break;
- if ((x = cmkey(fntab,nfntab,"","automatic",xxstring)) < 0)
- goto xgetx;
- debug(F101,"ftp get /filenames","",x);
- pv[n].ival = x;
- break;
-
- case SND_SMA: /* Smaller / larger than */
- case SND_LAR: {
- CK_OFF_T y;
- if (!getval) break;
- if ((x = cmnumw("Size in bytes","0",10,&y,xxstring)) < 0)
- goto xgetx;
- pv[n].wval = y;
- break;
- }
- case SND_FIL: /* Name of file containing filnames */
- if (!getval) break;
- if ((x = cmifi("Name of file containing list of filenames",
- "",&s,&y,xxstring)) < 0) {
- if (x == -3) {
- printf("?Filename required\n");
- x = -9;
- }
- goto xgetx;
- } else if (y && iswild(s)) {
- printf("?Wildcards not allowed BBB\n");
- x = -9;
- goto xgetx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- if (pv[n].sval)
- pv[n].ival = 1;
- break;
-
- case SND_MOV: /* MOVE after */
- case SND_REN: /* RENAME after */
- case SND_SRN: { /* SERVER-RENAME */
- char * m = "";
- switch (n) {
- case SND_MOV:
- m =
- "Device and/or directory for incoming file after reception";
- break;
- case SND_REN:
- m = "New name for incoming file after reception";
- break;
- case SND_SRN:
- m = "New name for source file on server after reception";
- break;
- }
- if (!getval) break;
- if ((x = cmfld(m, "", &s, n == SND_MOV ? xxstring : NULL)) < 0) {
- if (x == -3) {
- printf("%s\n", n == SND_MOV ?
- "?Destination required" :
- "?New name required"
- );
- x = -9;
- }
- goto xgetx;
- }
- makestr(&(pv[n].sval),*s ? brstrip(s) : NULL);
- pv[n].ival = (pv[n].sval) ? 1 : 0;
- break;
- }
-#ifndef NOCSETS
- case SND_CSL: /* Local character set */
- case SND_CSR: /* Remote (server) charset */
- if ((x = cmkey(fcstab,nfilc,"","",xxstring)) < 0)
- return((x == -3) ? -2 : x);
- if (n == SND_CSL)
- x_csl = x;
- else
- x_csr = x;
- x_xla = 1; /* Overrides global OFF setting */
- break;
-
- case SND_XPA: /* Transparent */
- x_xla = 0;
- x_csr = -1;
- x_csl = -1;
- break;
-#endif /* NOCSETS */
-
- case SND_NML:
- if ((x = cmofi("Local filename","-",&s,xxstring)) < 0)
- goto xgetx;
- makestr(&ftp_nml,s);
- break;
-
- case SND_PAT: /* /PATTERN: */
- if (!getval) break;
- if ((x = cmfld("Pattern","*", &s, xxstring)) < 0)
- goto xgetx;
- makestr(&(pv[n].sval),*s ? brstrip(s) : NULL);
- pv[n].ival = (pv[n].sval) ? 1 : 0;
- break;
-
- case SND_NLS: /* /NLST */
- pv[n].ival = 1; /* Use NLST */
- pv[SND_MLS].ival = 0; /* Don't use MLSD */
- break;
-
- case SND_MLS: /* /MLSD */
- pv[n].ival = 1; /* Use MLSD */
- pv[SND_NLS].ival = 0; /* Don't use NLST */
- break;
-
- default: /* /AFTER, /PERMISSIONS, etc... */
- printf("?Sorry, \"%s\" works only with [M]PUT\n",atmbuf);
- x = -9;
- goto xgetx;
- }
- }
- line[0] = NUL;
- cmarg = line;
- cmarg2 = asnambuf;
- s = line;
-/*
- For GET, we want to parse an optional as-name, like with PUT.
- For MGET, we must parse a list of names, and then send NLST or MLSD
- commands for each name separately.
-*/
- switch (cmresult.fcode) { /* How did we get out of switch loop */
- case _CMFLD: /* Field */
- if (!getone) {
- s = brstrip(cmresult.sresult);
- makestr(&(mgetlist[mgetn++]),s);
- while ((x = cmfld("Remote filename","",&s,xxstring)) != -3) {
- if (x < 0)
- goto xgetx;
- makestr(&(mgetlist[mgetn++]),brstrip(s));
- if (mgetn >= MGETMAX) {
- printf("?Too many items in MGET list\n");
- goto xgetx;
- }
- }
- if ((x = cmcfm()) < 0)
- goto xgetx;
- } else {
- s = brstrip(cmresult.sresult);
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmfld("Name to store it under","",&s,xxstring)) < 0)
- if (x != -3)
- goto xgetx;
- s = brstrip(s);
- ckstrncpy(asnambuf,s,CKMAXPATH+1);
- if ((x = cmcfm()) < 0)
- goto xgetx;
- }
- break;
- case _CMCFM: /* Confirmation */
- break;
- default:
- printf("?Unexpected function code: %d\n",cmresult.fcode);
- x = -9;
- goto xgetx;
- }
- if (pv[SND_REC].ival > 0) /* /RECURSIVE */
- recursive = 2;
-
- if (pv[SND_BIN].ival > 0) { /* /BINARY really means binary... */
- forcetype = 1; /* So skip the name-pattern match */
- ftp_typ = XYFT_B; /* Set binary */
- } else if (pv[SND_TXT].ival > 0) { /* Similarly for /TEXT... */
- forcetype = 1;
- ftp_typ = XYFT_T;
- } else if (pv[SND_TEN].ival > 0) { /* and /TENEX*/
- forcetype = 1;
- ftp_typ = FTT_TEN;
- } else if (ftp_cmdlin && ftp_xfermode == XMODE_M) {
- forcetype = 1;
- ftp_typ = binary;
- g_ftp_typ = binary;
- }
- if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !asnambuf[0]) {
- char * p;
- p = brstrip(pv[SND_ASN].sval); /* As-name */
- ckstrncpy(asnambuf,p,CKMAXPATH+1);
- }
- debug(F110,"ftp get asnambuf",asnambuf,0);
-
-#ifdef PIPESEND
- if (pv[SND_CMD].ival > 0) { /* /COMMAND - strip any braces */
- char * p;
- p = asnambuf;
- debug(F110,"GET /COMMAND before stripping",p,0);
- p = brstrip(p);
- debug(F110,"GET /COMMAND after stripping",p,0);
- if (!*p) {
- printf("?Sorry, a command to write to is required\n");
- x = -9;
- goto xgetx;
- }
- pipename = p;
- pipesend = 1;
- }
-#endif /* PIPESEND */
-
-/* Set up /MOVE and /RENAME */
-
-#ifdef COMMENT
- /* Conflict exists only for PUT - removed 13 Mar 2006 - fdc */
- if (pv[SND_DEL].ival > 0 &&
- (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
- printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
- x = -9;
- goto xgetx;
- }
-#endif /* COMMENT */
-#ifdef CK_TMPDIR
- if (pv[SND_MOV].ival > 0 && pv[SND_MOV].sval) {
- int len;
- char * p = pv[SND_MOV].sval;
- len = strlen(p);
- if (!isdir(p)) { /* Check directory */
-#ifdef CK_MKDIR
- char * s = NULL;
- s = (char *)malloc(len + 4);
- if (s) {
- strcpy(s,p); /* safe */
-#ifdef datageneral
- if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
-#else
- if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
-#endif /* datageneral */
- s[len++] = 'X';
- s[len] = NUL;
-#ifdef NOMKDIR
- x = -1;
-#else
- x = zmkdir(s);
-#endif /* NOMKDIR */
- free(s);
- if (x < 0) {
- printf("?Can't create \"%s\"\n",p);
- x = -9;
- goto xgetx;
- }
- }
-#else
- printf("?Directory \"%s\" not found\n",p);
- x = -9;
- goto xgetx;
-#endif /* CK_MKDIR */
- }
- makestr(&rcv_move,p);
- moving = 1;
- }
-#endif /* CK_TMPDIR */
-
- if (pv[SND_REN].ival > 0) { /* /RENAME */
- char * p = pv[SND_REN].sval;
- if (!p) p = "";
- if (!*p) {
- printf("?New name required for /RENAME\n");
- x = -9;
- goto xgetx;
- }
- p = brstrip(p);
-#ifndef NOSPL
- /* If name given is wild, rename string must contain variables */
- if (mget && !getone) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(p,&s,&x);
- if (!strcmp(tmpbuf,p)) {
- printf(
- "?/RENAME for file group must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xgetx;
- }
- }
-#endif /* NOSPL */
- renaming = 1;
- makestr(&rcv_rename,p);
- debug(F110,"FTP rcv_rename",rcv_rename,0);
- }
- if (!cmarg[0] && mgetn == 0 && getone && pv[SND_FIL].ival < 1) {
- printf("?Filename required but not given\n");
- x = -9;
- goto xgetx;
- } else if ((cmarg[0] || mgetn > 0) && pv[SND_FIL].ival > 0) {
- printf("?You can't give both /LISTFILE and a remote filename\n");
- x = -9;
- goto xgetx;
- }
- CHECKCONN(); /* Check connection */
-
- if (pv[SND_COL].ival > -1)
- x_fnc = pv[SND_COL].ival;
-
-#ifndef NOSPL
- /* If as-name given for MGET, as-name must contain variables */
- if (mget && !getone && asnambuf[0] && x_fnc != XYFX_A) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(asnambuf,&s,&x);
- if (!strcmp(tmpbuf,asnambuf)) {
- printf(
- "?As-name for MGET must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xgetx;
- }
- }
-#endif /* NOSPL */
-
-/* doget: */
-
- if (pv[SND_SHH].ival > 0 || ftp_nml) { /* GET /QUIET... */
- fdispla = 0;
- } else {
- displa = 1;
- if (mdel || ftp_deb)
- fdispla = XYFD_B;
- }
- deleting = 0;
- if (pv[SND_DEL].ival > 0) /* /DELETE was specified */
- deleting = 1;
- if (pv[SND_EXC].ival > 0)
- makelist(pv[SND_EXC].sval,rcvexcept,NSNDEXCEPT);
- if (pv[SND_SMA].wval > -1)
- getsmaller = pv[SND_SMA].wval;
- if (pv[SND_LAR].wval > -1)
- getlarger = pv[SND_LAR].wval;
- if (pv[SND_NAM].ival > -1)
- x_cnv = pv[SND_NAM].ival;
- if (pv[SND_ERR].ival > -1)
- geterror = pv[SND_ERR].ival;
- if (pv[SND_MAI].ival > -1)
- toscreen = 1;
-
- if (pv[SND_NLS].ival > 0) { /* Force NLST or MLSD? */
- mgetmethod = SND_NLS;
- mgetforced = 1;
- } else if (pv[SND_MLS].ival > 0) {
- mgetmethod = SND_MLS;
- mgetforced = 1;
- }
-
-#ifdef FTP_RESTART
- if (pv[SND_RES].ival > 0) {
- if (!ftp_typ) {
- printf("?Sorry, GET /RECOVER requires binary mode\n");
- x = -9;
- goto xgetx;
-#ifdef COMMENT
- /* Not true - the fact that the initial REST fails does not mean */
- /* it will fail here. */
- } else if (!okrestart) {
- printf("WARNING: Server might not support restart...\n");
-#endif /* COMMENT */
- }
- restart = 1;
- }
-#endif /* FTP_RESTART */
-
-#ifdef PIPESEND
- if (pv[SND_FLT].ival > 0) { /* Have SEND FILTER? */
- if (pipesend) {
- printf("?Switch conflict: /FILTER and /COMMAND\n");
- x = -9;
- goto xgetx;
- }
- makestr(&rcvfilter,pv[SND_FLT].sval);
- debug(F110,"ftp get /FILTER", rcvfilter, 0);
- }
- if (rcvfilter || pipesend) { /* /RESTART */
-#ifdef FTP_RESTART
- if (restart) { /* with pipes or filters */
- printf("?Switch conflict: /FILTER or /COMMAND and /RECOVER\n");
- x = -9;
- goto xgetx;
- }
-#endif /* FTP_RESTART */
- if (pv[SND_UPD].ival > 0 || x_fnc == XYFX_M || x_fnc == XYFX_U) {
- printf(
- "?Switch conflict: /FILTER or /COMMAND and Date Checking\n");
- x = -9;
- goto xgetx;
- }
- }
-#endif /* PIPESEND */
-
- tfc = (CK_OFF_T)0; /* Initialize stats and counters */
- filcnt = 0;
- pktnum = 0;
- rpackets = 0L;
-
- if (pv[SND_FIL].ival > 0) {
- if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
- debug(F111,"ftp get can't open listfile",pv[SND_FIL].sval,errno);
- printf("?Failure to open listfile - \"%s\"\n",pv[SND_FIL].sval);
- x = -9;
- goto xgetx;
- }
- if (zsinl(ZMFILE,tmpbuf,CKMAXPATH) < 0) { /* Read a line */
- zclose(ZMFILE); /* Failed */
- debug(F110,"ftp get listfile EOF",pv[SND_FIL].sval,0);
- printf("?Empty listfile - \"%s\"\n",pv[SND_FIL].sval);
- x = -9;
- goto xgetx;
- }
- listfile = 1;
- debug(F110,"ftp get listfile first",tmpbuf,0);
- makestr(&(mgetlist[0]),tmpbuf);
- }
- t0 = gmstimer(); /* Record starting time */
-
- updating = 0; /* Checking dates? */
- if (pv[SND_UPD].ival > 0 || (!mdel && x_fnc == XYFX_U))
- updating = 1;
- if (pv[SND_DIF].ival > 0 || x_fnc == XYFX_M)
- updating = 2;
- if (updating) /* These switches force FTP DATES ON */
- ftp_dates |= 2;
-
- what = mdel ? W_FTP|W_FT_DELE : W_RECV|W_FTP; /* What we're doing */
-
- cancelgroup = 0; /* Group not canceled yet */
- if (!(ftp_xfermode == XMODE_A && patterns && get_auto && !forcetype))
- changetype(ftp_typ,0); /* Change to requested type */
- binary = ftp_typ; /* For file-transfer display */
- first = 1; /* For MGET list */
- done = 0; /* Loop control */
-
-#ifdef CK_TMPDIR
- if (dldir && !f_tmpdir) { /* If they have a download directory */
- if ((s = zgtdir())) { /* Get current directory */
- if (zchdir(dldir)) { /* Change to download directory */
- ckstrncpy(savdir,s,TMPDIRLEN);
- f_tmpdir = 1; /* Remember that we did this */
- }
- }
- }
-#endif /* CK_TMPDIR */
-
- if (ftp_nml) { /* /NAMELIST */
- debug(F110,"ftp GET ftp_nml",ftp_nml,0);
- if (ftp_nml[0] == '-' && ftp_nml[1] == 0)
- fp_nml = stdout;
- else
- fp_nml = fopen(ftp_nml, "wb");
- if (!fp_nml) {
- printf("?%s: %s\n",ftp_nml,ck_errstr());
- goto xgetx;
- }
- }
- while (!done && !cancelgroup) { /* Loop for all files */
- /* or until canceled. */
-#ifdef FTP_PROXY
- /* do something here if proxy */
-#endif /* FTP_PROXY */
-
- rs_len = (CK_OFF_T)0; /* REGET position */
- cancelfile = 0; /* This file not canceled yet */
- haspath = 0; /* Recalculate this each time thru */
-
- if (getone) { /* GET */
- char * p;
- s = line;
- src = line; /* Server name */
- done = 1;
- debug(F111,"ftp get file",s,0);
- } else if (mget) { /* MGET */
- src = mgetlist[mgetx];
- debug(F111,"ftp mget remote_files A",src,first);
- s = (char *)remote_files(first,
- (CHAR *)mgetlist[mgetx],
- (CHAR *)pv[SND_PAT].sval,
- 0
- );
- debug(F110,"ftp mget remote_files B",s,0);
- if (!s) s = "";
- if (!*s) {
- first = 1;
- if (listfile) { /* Names from listfile */
- again:
- tmpbuf[0] = NUL;
- while (!tmpbuf[0]) {
- if (zsinl(ZMFILE,tmpbuf,CKMAXPATH) < 0) {
- zclose(ZMFILE);
- debug(F110,"ftp get listfile EOF",
- pv[SND_FIL].sval,0);
- makestr(&(mgetlist[0]),NULL);
- s = NULL;
- done = 1;
- break;
- }
- }
- if (done)
- continue;
-
- makestr(&(mgetlist[0]),tmpbuf);
- debug(F110,"ftp get listfile next",tmpbuf,0);
- s = (char *)remote_files(first,
- (CHAR *)mgetlist[0],
- (CHAR *)pv[SND_PAT].sval,
- 0
- );
- debug(F110,"ftp mget remote_files C",s,0);
- if (!s) {
- ftscreen(SCR_FN,'F',(CK_OFF_T)0,s);
- ftscreen(SCR_ST,ST_MSG,(CK_OFF_T)0,"File not found");
- tlog(F110,"ftp get file not found:",s,0);
- goto again;
- }
- } else { /* Names from command line */
- mgetx++;
- if (mgetx < mgetn)
- s = (char *)remote_files(first,
- (CHAR *)mgetlist[mgetx],
- (CHAR *)pv[SND_PAT].sval,
- 0
- );
- else
- s = NULL;
- if (!s) mgetx++;
- debug(F111,"ftp mget remote_files D",s,mgetx);
- }
- if (!s) {
- if (!first || mgetx >= mgetn) {
- done = 1;
- break;
- } else if (geterror) {
- status = 0;
- done = 1;
- break;
- } else {
- continue;
- }
- }
- }
- }
- debug(F111,"ftp mget remote_files E",s,0);
- /*
- The semantics of NLST are ill-defined. Suppose we have just sent
- NLST /path/[a-z]*. Most servers send back names like /path/foo,
- /path/bar, etc. But some send back only foo and bar, and subsequent
- RETR commands based on the pathless names are not going to work.
- */
- if (servertype == SYS_UNIX && !ckstrchr(s,'/')) {
- char * s3;
- if ((s3 = ckstrrchr(mgetlist[mgetx],'/'))) {
- int len, left = 4096;
- char * tmp = xtmpbuf;
- len = s3 - mgetlist[mgetx] + 1;
- ckstrncpy(tmp,mgetlist[mgetx],left);
- tmp += len;
- left -= len;
- ckstrncpy(tmp,s,left);
- s = xtmpbuf;
- debug(F111,"ftp mget remote_files F",s,0);
- }
- }
- first = 0;
- skipthis = 0; /* File selection... */
- msg = "";
- nam = s; /* Filename (without path) */
- rc = 0; /* Initial return code */
- s2 = "";
-
- if (!getone && !skipthis) { /* For MGET and MDELETE... */
- char c, * p = s;
- int srvpath = 0;
- int usrpath = 0;
- int i, k = 0;
-
- debug(F111,"ftp mget havetype",s,havetype);
- if (havetype > 0 && havetype != FTYP_FILE) {
- /* Server says it's not file... */
- debug(F110,"ftp mget not-a-file",s,0);
- continue;
- }
-/*
- Explanation: Some ftp servers (such as wu-ftpd) return a recursive list.
- But if the client did not ask for a recursive list, we have to ignore any
- server files that include a pathname that extends beyond any path that
- was included in the user's request.
-
- User's filespec is blah or path/blah (or other non-UNIX syntax). We need to
- get the user's path segment. Then, for each incoming file, if it begins
- with the same path segment, we must strip it (point past it).
-*/
- src = mgetlist[mgetx]; /* In case it moved! */
- if (src) {
- for (i = 0; src[i]; i++) { /* Find rightmost path separator */
- if (ispathsep(src[i])) /* in user's pathname */
- k = i + 1;
- }
- } else {
- src = "";
- }
- usrpath = k; /* User path segment length */
- debug(F111,"ftp get usrpath",src,usrpath);
-
- p = s; /* Server filename */
- while ((c = *p++)) { /* Look for path in server filename */
- if (ispathsep(c)) {
- /* haspath++; */
- nam = p; /* Pathless name (for ckmatch) */
- srvpath = p - s; /* Server path segment length */
- }
- }
- debug(F111,"ftp get srvpath",s,srvpath);
-
- if (usrpath == 0) {
-/*
- Here we handle the case where the user said "mget foo" where foo is a
- directory name, and the server is sending back names like "foo/file1",
- "foo/file2", etc. This is a nasty trick but it's necessary because the
- user can't compensate by typing "mget foo/" because then the server is
- likely to send back "foo//file1, foo//file2" etc, and we still won't
- get a match...
-*/
- int srclen = 0, srvlen = 0;
- if (src) srclen = strlen(src);
- if (s) srvlen = strlen(s);
- if (src && (srvlen > srclen)) {
- if (!strncmp(src,s,srclen) && ispathsep(s[srclen])) {
- char * tmpsrc = NULL;
- tmpsrc = (char *)malloc(srclen + 2);
- strncpy(tmpsrc,src,srclen);
- tmpsrc[srclen] = s[srclen];
- tmpsrc[srclen+1] = NUL;
- free(mgetlist[mgetx]);
- mgetlist[mgetx] = tmpsrc;
- tmpsrc = NULL;
- src = mgetlist[mgetx];
- usrpath = srclen+1;
- }
- }
- }
-/*
- If as-name not given and server filename includes path that matches
- the pathname from the user's file specification, we must trim the common
- path prefix from the server's name when constructing the local name.
-*/
- if (src && /* Wed Sep 25 17:27:48 2002 */
- !asnambuf[0] &&
- !recursive && /* Thu Sep 19 16:11:59 2002 */
- (srvpath > 0) &&
- !strncmp(src,s,usrpath)) {
- s2 = s + usrpath; /* Local name skips past remote path */
- }
-#ifdef COMMENT
- /* This doesn't work if the path prefix contains wildcards! */
- haspath = (srvpath > usrpath);
-#else
- { /* Count path segments instead */
- int x1 = 0, x2 = 0;
- char *p;
- for (p = s; *p; p++)
- if (ispathsep(*p)) x1++;
- for (p = src; *p; p++) {
- if (ispathsep(*p)) x2++;
- }
- haspath = recursive ? x1 || x2 : x1 > x2;
- debug(F111,"ftp get server path segments",s,x1);
- debug(F111,"ftp get user path segments",src,x2);
- }
-
-#endif /* COMMENT */
- debug(F111,"ftp get haspath",s+usrpath,haspath);
-
- if (haspath) { /* Server file has path segments? */
- if (!recursive) { /* [M]GET /RECURSIVE? */
-/*
- We did not ask for a recursive listing, but the server is sending us one
- anyway (as wu-ftpd is wont to do). We get here if the current filename
- includes a path segment beyond any path segment we asked for in our
- non-recursive [M]GET command. We MUST skip this file.
-*/
- debug(F111,"ftp get skipping because of path",s,0);
- continue;
- }
- }
- } else if (getone && !skipthis) { /* GET (not MGET) */
- char * p = nam;
- while ((c = *p++)) { /* Handle path in local name */
- if (ispathsep(c)) {
- if (recursive) { /* If recursive, keep it */
- haspath = 1;
- break;
- } else { /* Otherwise lose it. */
- nam = p;
- }
- }
- }
- s2 = nam;
- }
- if (!*nam) /* Name without path */
- nam = s;
-
- if (!skipthis && pv[SND_NOD].ival > 0) { /* /NODOTFILES */
- if (nam[0] == '.')
- continue;
- }
- if (!skipthis && rcvexcept[0]) { /* /EXCEPT: list */
- int xx;
- for (i = 0; i < NSNDEXCEPT; i++) {
- if (!rcvexcept[i]) {
- break;
- }
- xx = ckmatch(rcvexcept[i], nam, servertype == SYS_UNIX, 1);
- debug(F111,"ftp mget /except match",rcvexcept[i],xx);
- if (xx) {
- tlog(F100," refused: exception list","",0);
- msg = "Refused: Exception List";
- skipthis++;
- break;
- }
- }
- }
- if (!skipthis && pv[SND_NOB].ival > 0) { /* /NOBACKUPFILES */
- if (ckmatch(
-#ifdef CKREGEX
- "*.~[0-9]*~"
-#else
- "*.~*~"
-#endif /* CKREGEX */
- ,nam,0,1) > 0)
- continue;
- }
- if (!x_xla) { /* If translation is off */
- x_csl = -2; /* unset the charsets */
- x_csr = -2;
- }
- ckstrncpy(filnam,s,CKMAXPATH); /* For \v(filename) */
- if (!*s2) /* Local name */
- s2 = asnambuf; /* As-name */
-
- if (!*s2) /* Sat Nov 16 19:19:39 2002 */
- s2 = recursive ? s : nam; /* Fri Jan 10 13:15:19 2003 */
-
- debug(F110,"ftp get filnam ",s,0);
- debug(F110,"ftp get asname A",s2,0);
-
- /* Receiving to real file */
- if (!pipesend &&
-#ifdef PIPESEND
- !rcvfilter &&
-#endif /* PIPESEND */
- !toscreen) {
-#ifndef NOSPL
- /* Do this here so we can decide whether to skip */
- if (cmd_quoting && !skipthis && asnambuf[0]) {
- int n; char *p;
- n = TMPBUFSIZ;
- p = tmpbuf;
- zzstring(asnambuf,&p,&n);
- s2 = tmpbuf;
- debug(F111,"ftp get asname B",s2,updating);
- }
-#endif /* NOSPL */
-
- local = *s2 ? s2 : s;
-
- if (!skipthis && x_fnc == XYFX_D) { /* File Collision = Discard */
- CK_OFF_T x;
- x = zchki(local);
- debug(F111,"ftp get DISCARD zchki",local,x);
- if (x > -1) {
- skipthis++;
- debug(F110,"ftp get skip name",local,0);
- tlog(F100," refused: name","",0);
- msg = "Refused: Name";
- }
- }
-
-#ifdef DOUPDATE
- if (!skipthis && updating) { /* If updating and not yet skipping */
- if (zchki(local) > -1) {
- x = chkmodtime(local,s,0);
-#ifdef DEBUG
- if (deblog) {
- if (updating == 2)
- debug(F111,"ftp get /dates-diff chkmodtime",local,x);
- else
- debug(F111,"ftp get /update chkmodtime",local,x);
- }
-#endif /* DEBUG */
- if ((updating == 1 && x > 0) || /* /UPDATE */
- (updating == 2 && x == 1)) { /* /DATES-DIFFER */
- skipthis++;
- tlog(F100," refused: date","",0);
- msg = "Refused: Date";
- debug(F110,"ftp get skip date",local,0);
- }
- }
- }
-#endif /* DOUPDATE */
- }
- /* Initialize file size to -1 in case server doesn't understand */
- /* SIZE command, so xxscreen() will know we don't know the size */
-
- fsize = (CK_OFF_T)-1;
-
- /* Ask for size now only if we need it for selection */
- /* because if you're going thru a list 100,000 files to select */
- /* a small subset, 100,000 SIZE commands can take hours... */
-
- gotsize = 0;
- if (!mdel && !skipthis && /* Don't need size for DELE... */
- (getsmaller >= (CK_OFF_T)0 || getlarger >= (CK_OFF_T)0)) {
- if (havesize >= (CK_OFF_T)0) { /* Already have file size? */
- fsize = havesize;
- gotsize = 1;
- } else { /* No - must ask server */
- /*
- Prior to sending the NLST command we necessarily put the
- server into ASCII mode. We must now put it back into the
- the requested mode so the upcoming SIZE command returns
- right kind of size; this is especially important for
- GET /RECOVER; otherwise the server returns the "ASCII" size
- of the file, rather than its true size.
- */
- changetype(ftp_typ,0); /* Change to requested type */
- fsize = (CK_OFF_T)-1;
- if (sizeok) {
- x = ftpcmd("SIZE",s,x_csl,x_csr,ftp_vbm);
- if (x == REPLY_COMPLETE) {
- fsize = ckatofs(&ftp_reply_str[4]);
- gotsize = 1;
- }
- }
- }
- if (gotsize) {
- if (getsmaller >= (CK_OFF_T)0 && fsize >= getsmaller)
- skipthis++;
- if (getlarger >= (CK_OFF_T)0 && fsize <= getlarger)
- skipthis++;
- if (skipthis) {
- debug(F111,"ftp get skip size",s,fsize);
- tlog(F100," refused: size","",0);
- msg = "Refused: Size";
- }
-#ifdef COMMENT
- } else if (getone) {
- /* SIZE can fail for many reasons. Does the file exist? */
- x = ftpcmd("NLST",s,x_csl,x_csr,ftp_vbm);
- if (x != REPLY_COMPLETE) {
- printf(">>> FILE NOT FOUND: %s\n",s);
- break;
- }
-#endif /* COMMENT */
- }
- }
- if (skipthis) { /* Skipping this file? */
- ftscreen(SCR_FN,'F',(CK_OFF_T)0,s);
- if (msg)
- ftscreen(SCR_ST,ST_ERR,(CK_OFF_T)0,msg);
- else
- ftscreen(SCR_ST,ST_SKIP,(CK_OFF_T)0,s);
- continue;
- }
- if (fp_nml) { /* /NAMELIST only - no transfer */
- fprintf(fp_nml,"%s\n",s);
- continue;
- }
- if (recursive && haspath && !pipesend
-#ifdef PIPESEND
- && !rcvfilter
-#endif /* PIPESEND */
- ) {
- int x;
-
-#ifdef NOMKDIR
- x = -1;
-#else
- x = zmkdir(s); /* Try to make the directory */
-#endif /* NOMKDIR */
-
- if (x < 0) {
- rc = -1; /* Failure is fatal */
- if (geterror) {
- status = 0;
- ftscreen(SCR_EM,0,(CK_OFF_T)0,
- "Directory creation failure");
- break;
- }
- }
- }
-
- /* Not skipping */
-
- selected++; /* Count this file as selected */
- pn = NULL;
-
- if (!gotsize && !mdel) { /* Didn't get size yet */
- if (havesize > (CK_OFF_T)-1) { /* Already have file size? */
- fsize = havesize;
- gotsize = 1;
- } else { /* No - must ask server */
- fsize = (CK_OFF_T)-1;
- if (sizeok) {
- x = ftpcmd("SIZE",s,x_csl,x_csr,ftp_vbm);
- if (x == REPLY_COMPLETE) {
- fsize = ckatofs(&ftp_reply_str[4]);
- gotsize = 1;
- }
- }
- }
- }
- if (mdel) { /* [M]DELETE */
- if (displa && !ftp_vbm)
- printf(" %s...",s);
- rc =
- (ftpcmd("DELE",s,x_csl,x_csr,ftp_vbm) == REPLY_COMPLETE) ? 1 : -1;
- if (rc > -1) {
- tlog(F110,"ftp mdelete",s,0);
- if (displa && !ftp_vbm)
- printf("OK\n");
- } else {
- tlog(F110,"ftp mdelete failed:",s,0);
- if (displa)
- printf("Failed\n");
- }
-#ifndef NOSPL
-#ifdef PIPESEND
- } else if (rcvfilter) { /* [M]GET with filter */
- int n; char * p;
- n = CKMAXPATH;
- p = tmpbuf; /* Safe - no asname with filter */
- zzstring(rcvfilter,&p,&n);
- if (n > -1)
- pn = tmpbuf;
- debug(F111,"ftp get rcvfilter",pn,n);
-#endif /* PIPESEND */
-#endif /* NOSPL */
- if (toscreen) s2 = "-";
- } else if (pipesend) { /* [M]GET /COMMAND */
- int n; char * p;
- n = CKMAXPATH;
- p = tmpbuf; /* Safe - no asname with filter */
- zzstring(pipename,&p,&n);
- if (n > -1)
- pn = tmpbuf;
- debug(F111,"ftp get pipename",pipename,n);
- if (toscreen) s2 = "-";
- } else { /* [M]GET with no pipes or filters */
- debug(F111,"ftp get s2 A",s2,x_cnv);
- if (toscreen) {
- s2 = "-"; /* (hokey convention for stdout) */
- } else if (!*s2) { /* No asname? */
- if (x_cnv) { /* If converting */
- nzrtol(s,tmpbuf,x_cnv,1,CKMAXPATH); /* convert */
- s2 = tmpbuf;
- debug(F110,"ftp get nzrtol",s2,0);
- } else /* otherwise */
- s2 = s; /* use incoming file's name */
- }
- debug(F110,"ftp get s2 B",s2,0);
-
- /* If local file already exists, take collision action */
-
- if (!pipesend &&
-#ifdef PIPESEND
- !rcvfilter &&
-#endif /* PIPESEND */
- !toscreen) {
- CK_OFF_T x;
- x = zchki(s2);
- debug(F111,"ftp get zchki",s2,x);
- debug(F111,"ftp get x_fnc",s2,x_fnc);
-
- if (x > (CK_OFF_T)-1 && !restart) {
- int x = -1;
- char * newname = NULL;
-
- switch (x_fnc) {
- case XYFX_A: /* Append */
- append = 1;
- break;
- case XYFX_R: /* Rename */
- case XYFX_B: /* Backup */
- znewn(s2,&newname); /* Make unique name */
- debug(F110,"ftp get znewn",newname,0);
- if (x_fnc == XYFX_B) { /* Backup existing file */
- x = zrename(s2,newname);
- debug(F111,"ftp get backup zrename",newname,x);
- } else { /* Rename incoming file */
- x = ckstrncpy(tmpbuf,newname,CKMAXPATH+1);
- s2 = tmpbuf;
- debug(F111,"ftp get rename incoming",newname,x);
- }
- if (x < 0) {
- ftscreen(SCR_EM,0,(CK_OFF_T)0,
- "Backup/Rename failed");
- x = 0;
- goto xgetx;
- }
- break;
- case XYFX_D: /* Discard (already handled above) */
- case XYFX_U: /* Update (ditto) */
- case XYFX_M: /* Update (ditto) */
- case XYFX_X: /* Overwrite */
- break;
- }
- }
- }
- }
- if (!mdel) {
-#ifdef PIPESEND
- debug(F111,"ftp get pn",pn,rcvfilter ? 1 : 0);
-#endif /* PIPESEND */
- if (pipesend && !toscreen)
- s2 = NULL;
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"ftp get x_xla","",x_xla);
- debug(F101,"ftp get x_csl","",x_csl);
- debug(F101,"ftp get x_csr","",x_csr);
- debug(F101,"ftp get append","",append);
- }
-#endif /* DEBUG */
-
- rc = getfile(s,s2,restart,append,pn,x_xla,x_csl,x_csr);
-
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"ftp get rc",s,rc);
- debug(F111,"ftp get ftp_timed_out",s,ftp_timed_out);
- debug(F111,"ftp get cancelfile",s,cancelfile);
- debug(F111,"ftp get cancelgroup",s,cancelgroup);
- debug(F111,"ftp get renaming",s,renaming);
- debug(F111,"ftp get moving",s,moving);
- }
-#endif /* DEBUG */
- }
- if (rc > -1) {
- good++;
- status = 1;
- if (!cancelfile) {
- if (deleting) { /* GET /DELETE (source file) */
- rc =
- (ftpcmd("DELE",s,x_csl,x_csr,ftp_vbm) == REPLY_COMPLETE)
- ? 1 : -1;
- tlog(F110, (rc > -1) ?
- " deleted" : " failed to delete", s, 0);
- }
- if (renaming && rcv_rename && !toscreen) {
- char *p; /* Rename downloaded file */
-#ifndef NOSPL
- char tmpbuf[CKMAXPATH+1];
- int n;
- n = CKMAXPATH;
- p = tmpbuf;
- debug(F111,"ftp get /rename",rcv_rename,0);
- zzstring(rcv_rename,&p,&n);
- debug(F111,"ftp get /rename",rcv_rename,0);
- p = tmpbuf;
-#else
- p = rcv_rename;
-#endif /* NOSPL */
- rc = (zrename(s2,p) < 0) ? -1 : 1;
- debug(F111,"doftpget /RENAME zrename",p,rc);
- tlog(F110, (rc > -1) ?
- " renamed to" :
- " failed to rename to",
- p,
- 0
- );
- } else if (moving && rcv_move && !toscreen) {
- char *p; /* Move downloaded file */
-#ifndef NOSPL
- char tmpbuf[CKMAXPATH+1];
- int n;
- n = TMPBUFSIZ;
- p = tmpbuf;
- debug(F111,"ftp get /move-to",rcv_move,0);
- zzstring(rcv_move,&p,&n);
- p = tmpbuf;
-#else
- p = rcv_move;
-#endif /* NOSPL */
- debug(F111,"ftp get /move-to",p,0);
- rc = (zrename(s2,p) < 0) ? -1 : 1;
- debug(F111,"doftpget /MOVE zrename",p,rc);
- tlog(F110, (rc > -1) ?
- " moved to" : " failed to move to", p, 0);
- }
- if (pv[SND_SRN].ival > 0 && pv[SND_SRN].sval) {
- char * s = pv[SND_SRN].sval;
- char * srvrn = pv[SND_SRN].sval;
- char tmpbuf[CKMAXPATH+1];
-#ifndef NOSPL
- int y; /* Pass it thru the evaluator */
- extern int cmd_quoting; /* for \v(filename) */
- debug(F111,"ftp get srv_renam",s,1);
-
- if (cmd_quoting) {
- y = CKMAXPATH;
- s = (char *)tmpbuf;
- zzstring(srvrn,&s,&y);
- s = (char *)tmpbuf;
- }
-#endif /* NOSPL */
- debug(F111,"ftp get srv_renam",s,1);
- if (s) if (*s) {
- int x;
- x = ftp_rename(s2,s);
- debug(F111,"ftp get ftp_rename",s2,x);
- tlog(F110, (x > 0) ?
- " renamed source file to" :
- " failed to rename source file to",
- s,
- 0
- );
- if (x < 1)
- return(-1);
- }
- }
- }
- }
- if (cancelfile)
- continue;
- if (rc < 0) {
- ftp_fai++;
-#ifdef FTP_TIMEOUT
- debug(F101,"ftp get ftp_timed_out","",ftp_timed_out);
- if (ftp_timed_out) {
- status = 0;
- ftscreen(SCR_EM,0,(CK_OFF_T)0,"GET timed out");
- }
-#endif /* FTP_TIMEOUT */
- if (geterror) {
- status = 0;
- ftscreen(SCR_EM,0,(CK_OFF_T)0,"Fatal download error");
- done++;
- }
- }
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"ftp get status","",status);
- debug(F101,"ftp get cancelgroup","",cancelgroup);
- debug(F101,"ftp get cancelfile","",cancelfile);
- debug(F101,"ftp get selected","",selected);
- debug(F101,"ftp get good","",good);
- }
-#endif /* DEBUG */
-
- if (selected == 0) { /* No files met selection criteria */
- status = 1; /* which is a kind of success. */
- } else if (status > 0) { /* Some files were selected */
- if (cancelgroup) /* but MGET was canceled */
- status = 0; /* so MGET failed */
- else if (cancelfile && good < 1) /* If file was canceled */
- status = 0; /* MGET failed if it got no files */
- }
- success = status;
- x = success;
- debug(F101,"ftp get success","",success);
-
- xgetx:
- pipesend = pipesave; /* Restore global pipe selection */
- if (fp_nml) { /* Close /NAMELIST */
- if (fp_nml != stdout)
- fclose(fp_nml);
- fp_nml = NULL;
- }
- if (
-#ifdef COMMENT
- x > -1
-#else
- success
-#endif /* COMMENT */
- ) { /* Download successful */
-#ifdef GFTIMER
- t1 = gmstimer(); /* End time */
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- if (!sec) sec = 0.001;
- fptsecs = sec;
-#else
- sec = (t1 - t0) / 1000;
- if (!sec) sec = 1;
-#endif /* GFTIMER */
- tfcps = (long) (tfc / sec);
- tsecs = (int)sec;
- lastxfer = W_FTP|W_RECV;
- xferstat = success;
- }
- if (dpyactive)
- ftscreen(success > 0 ? SCR_TC : SCR_CW, 0, (CK_OFF_T)0, "");
-#ifdef CK_TMPDIR
- if (f_tmpdir) { /* If we changed to download dir */
- zchdir((char *) savdir); /* Go back where we came from */
- f_tmpdir = 0;
- }
-#endif /* CK_TMPDIR */
-
- for (i = 0; i <= SND_MAX; i++) { /* Free malloc'd memory */
- if (pv[i].sval)
- free(pv[i].sval);
- }
- for (i = 0; i < mgetn; i++) /* MGET list too */
- makestr(&(mgetlist[i]),NULL);
-
- if (cancelgroup) /* Clear temp-file stack */
- mlsreset();
-
- ftreset(); /* Undo switch effects */
- dpyactive = 0;
- return(x);
-}
-
-static struct keytab ftprmt[] = {
- { "cd", XZCWD, 0 },
- { "cdup", XZCDU, 0 },
- { "cwd", XZCWD, CM_INV },
- { "delete", XZDEL, 0 },
- { "directory", XZDIR, 0 },
- { "exit", XZXIT, 0 },
- { "help", XZHLP, 0 },
- { "login", XZLGI, 0 },
- { "logout", XZLGO, 0 },
- { "mkdir", XZMKD, 0 },
- { "pwd", XZPWD, 0 },
- { "rename", XZREN, 0 },
- { "rmdir", XZRMD, 0 },
- { "type", XZTYP, 0 },
- { "", 0, 0 }
-};
-static int nftprmt = (sizeof(ftprmt) / sizeof(struct keytab)) - 1;
-
-int
-doftpsite() { /* Send a SITE command */
- int reply;
- char * s;
- int lcs = -1, rcs = -1;
- int save_vbm = ftp_vbm;
-
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
- if ((x = cmtxt("Command", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing) printf(" ftp site \"%s\"...\n",line);
- if (!ftp_vbm)
- ftp_vbm = !ckstrcmp("HELP",line,4,0);
- if ((reply = ftpcmd("SITE",line,lcs,rcs,ftp_vbm)) == REPLY_PRELIM) {
- do {
- reply = getreply(0,lcs,rcs,ftp_vbm,0);
- } while (reply == REPLY_PRELIM);
- }
- ftp_vbm = save_vbm;
- return(success = (reply == REPLY_COMPLETE));
-}
-
-
-int
-dosetftppsv() { /* Passive mode */
- x = seton(&ftp_psv);
- if (x > 0) passivemode = ftp_psv;
- return(x);
-}
-
-/* d o f t p r m t -- Parse and execute REMOTE commands */
-
-int
-doftprmt(cx,who) int cx, who; { /* who == 1 for ftp, 0 for kermit */
- /* cx == 0 means REMOTE */
- /* cx != 0 is a XZxxx value */
- char * s;
-
- if (who != 0)
- return(0);
-
- if (cx == 0) {
- if ((x = cmkey(ftprmt,nftprmt,"","",xxstring)) < 0)
- return(x);
- cx = x;
- }
- switch (cx) {
- case XZCDU: /* CDUP */
- if ((x = cmcfm()) < 0) return(x);
- return(doftpcdup());
-
- case XZCWD: /* RCD */
- if ((x = cmtxt("Remote directory", "", &s, xxstring)) < 0)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- s = brstrip(line);
- return(doftpcwd(s,1));
- case XZPWD: /* RPWD */
- return(doftppwd());
- case XZDEL: /* RDEL */
- return(doftpget(FTP_MDE,1));
- case XZDIR: /* RDIR */
- return(doftpdir(FTP_DIR));
- case XZHLP: /* RHELP */
- return(doftpxhlp());
- case XZMKD: /* RMKDIR */
- return(doftpmkd());
- case XZREN: /* RRENAME */
- return(doftpren());
- case XZRMD: /* RRMDIR */
- return(doftprmd());
- case XZLGO: /* LOGOUT */
- return(doftpres());
- case XZXIT: /* EXIT */
- return(ftpbye());
- }
- printf("?Not usable with FTP - \"%s\"\n", atmbuf);
- return(-9);
-}
-
-int
-doxftp() { /* Command parser for built-in FTP */
- int cx, n;
- struct FDB kw, fl;
- char * s;
- int usetls = 0;
- int lcs = -1, rcs = -1;
-
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
-
- if (inserver) /* FTP not allowed in IKSD. */
- return(-2);
-
- if (g_ftp_typ > -1) { /* Restore TYPE if saved */
- ftp_typ = g_ftp_typ;
- /* g_ftp_typ = -1; */
- }
-#ifdef COMMENT
-/*
- We'll set the collision action locally in doftpget() based on whether
- ftp_fnc was ever set to a value. if not, we'll use the fncact value.
-*/
- if (ftp_fnc < 0) /* Inherit global collision action */
- ftp_fnc = fncact; /* if none specified for FTP */
-#endif /* COMMENT */
-
- /* Restore global verbose mode */
- if (ftp_deb)
- ftp_vbm = 1;
- else if (quiet)
- ftp_vbm = 0;
- else
- ftp_vbm = ftp_vbx;
-
- ftp_dates &= 1; /* Undo any previous /UPDATE switch */
-
- dpyactive = 0; /* Reset global transfer-active flag */
- printlines = 0; /* Reset printlines */
-
- if (fp_nml) { /* Reset /NAMELIST */
- if (fp_nml != stdout)
- fclose(fp_nml);
- fp_nml = NULL;
- }
- makestr(&ftp_nml,NULL);
-
- cmfdbi(&kw, /* First FDB - commands */
- _CMKEY, /* fcode */
- "Hostname; or FTP command", /* help */
- "", /* default */
- "", /* addtl string data */
- nftpcmd, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: none */
- xxstring, /* Processing function */
- ftpcmdtab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* A host name or address */
- _CMFLD, /* fcode */
- "Hostname or address", /* help */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- x = cmfdb(&kw); /* Parse a hostname or a keyword */
- if (x == -3) {
- printf("?ftp what? \"help ftp\" for hints\n");
- return(-9);
- }
- if (x < 0)
- return(x);
- if (cmresult.fcode == _CMFLD) { /* If hostname */
- return(openftp(cmresult.sresult,0)); /* go open the connection */
- } else {
- cx = cmresult.nresult;
- }
- switch (cx) {
- case FTP_ACC: /* ACCOUNT */
- if ((x = cmtxt("Remote account", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- makestr(&ftp_acc,s);
- if (testing)
- printf(" ftp account: \"%s\"\n",ftp_acc);
- success = (ftpcmd("ACCT",ftp_acc,-1,-1,ftp_vbm) == REPLY_COMPLETE);
- return(success);
-
- case FTP_GUP: /* Go UP */
- if ((x = cmcfm()) < 0) return(x);
- CHECKCONN();
- if (testing) printf(" ftp cd: \"(up)\"\n");
- return(success = doftpcdup());
-
- case FTP_CWD: /* CD */
- if ((x = cmtxt("Remote directory", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp cd: \"%s\"\n", line);
- return(success = doftpcwd(line,1));
-
- case FTP_CHM: /* CHMOD */
- if ((x = cmfld("Permissions or protection code","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((x = cmtxt("Remote filename", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckmakmsg(ftpcmdbuf,FTP_BUFSIZ,tmpbuf," ",s,NULL);
- if (testing)
- printf(" ftp chmod: %s\n",ftpcmdbuf);
- success =
- (ftpcmd("SITE CHMOD",ftpcmdbuf,lcs,rcs,ftp_vbm) == REPLY_COMPLETE);
- return(success);
-
- case FTP_CLS: /* CLOSE FTP connection */
- if ((y = cmcfm()) < 0)
- return(y);
- CHECKCONN();
- if (testing)
- printf(" ftp closing...\n");
- ftpclose();
- return(success = 1);
-
- case FTP_DIR: /* DIRECTORY of remote files */
- case FTP_VDI:
- return(doftpdir(cx));
-
- case FTP_GET: /* GET a remote file */
- case FTP_RGE: /* REGET */
- case FTP_MGE: /* MGET */
- case FTP_MDE: /* MDELETE */
- return(doftpget(cx,1));
-
- case FTP_IDL: /* IDLE */
- if ((x = cmnum("Number of seconds","-1",10,&z,xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- CHECKCONN();
- if (z < 0) { /* Display idle timeout */
- if (testing)
- printf(" ftp query idle timeout...\n");
- success = (ftpcmd("SITE IDLE",NULL,0,0,1) == REPLY_COMPLETE);
- } else { /* Set idle timeout */
- if (testing)
- printf(" ftp idle timeout set: %d...\n",z);
- success =
- (ftpcmd("SITE IDLE",ckitoa(z),0,0,1) == REPLY_COMPLETE);
- }
- return(success);
-
- case FTP_MKD: /* MKDIR */
- return(doftpmkd());
-
- case FTP_MOD: /* MODTIME */
- if ((x = cmtxt("Remote filename", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp modtime \"%s\"...\n",line);
- success = 0;
- if (ftpcmd("MDTM",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE) {
- success = 1;
- mdtmok = 1;
- if (!quiet) {
- int flag = 0;
- char c, * s;
- struct tm tmremote;
-
- bzero((char *)&tmremote, sizeof(struct tm));
- s = ftp_reply_str;
- while ((c = *s++)) {
- if (c == SP) {
- flag++;
- break;
- }
- }
- if (flag) {
- if (sscanf(s, "%04d%02d%02d%02d%02d%02d",
- &tmremote.tm_year,
- &tmremote.tm_mon,
- &tmremote.tm_mday,
- &tmremote.tm_hour,
- &tmremote.tm_min,
- &tmremote.tm_sec
- ) == 6) {
- printf(" %s %04d-%02d-%02d %02d:%02d:%02d GMT\n",
- line,
- tmremote.tm_year,
- tmremote.tm_mon,
- tmremote.tm_mday,
- tmremote.tm_hour,
- tmremote.tm_min,
- tmremote.tm_sec
- );
- } else {
- success = 0;
- }
- }
- }
- }
- return(success);
-
- case FTP_OPN: /* OPEN connection */
-#ifdef COMMENT
- x = cmfld("IP hostname or address","",&s,xxstring);
- if (x < 0) {
- success = 0;
- return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- return(openftp(s,0));
-#else
- { /* OPEN connection */
- char name[TTNAMLEN+1], *p;
- extern int network;
- extern char ttname[];
- if (network) /* If we have a current connection */
- ckstrncpy(name,ttname,LINBUFSIZ); /* get the host name */
- else
- *name = '\0'; /* as default host */
- for (p = name; *p; p++) /* Remove ":service" from end. */
- if (*p == ':') { *p = '\0'; break; }
-#ifndef USETLSTAB
- x = cmfld("IP hostname or address",name,&s,xxstring);
-#else
- cmfdbi(&kw, /* First FDB - commands */
- _CMKEY, /* fcode */
- "Hostname or switch", /* help */
- "", /* default */
- "", /* addtl string data */
- ntlstab, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: none */
- xxstring, /* Processing function */
- tlstab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* A host name or address */
- _CMFLD, /* fcode */
- "Hostname or address", /* help */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
-
- for (n = 0;; n++) {
- x = cmfdb(&kw); /* Parse a hostname or a keyword */
- if (x == -3) {
- printf("?ftp open what? \"help ftp\" for hints\n");
- return(-9);
- }
- if (x < 0)
- break;
- if (cmresult.fcode == _CMFLD) { /* Hostname */
- s = cmresult.sresult;
- break;
- } else if (cmresult.nresult == OPN_TLS) {
- usetls = 1;
- }
- }
-#endif /* USETLSTAB */
- if (x < 0) {
- success = 0;
- return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- return(openftp(s,usetls));
- }
-#endif /* COMMENT */
-
- case FTP_PUT: /* PUT */
- case FTP_MPU: /* MPUT */
- case FTP_APP: /* APPEND */
- case FTP_REP: /* REPUT */
- return(doftpput(cx,1));
-
- case FTP_PWD: /* PWD */
- x = doftppwd();
- if (x > -1) success = x;
- return(x);
-
- case FTP_REN: /* RENAME */
- return(doftpren());
-
- case FTP_RES: /* RESET */
- return(doftpres());
-
- case FTP_HLP: /* (remote) HELP */
- return(doftpxhlp());
-
- case FTP_RMD: /* RMDIR */
- return(doftprmd());
-
- case FTP_STA: /* STATUS */
- if ((x = cmtxt("Command", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing) printf(" ftp status \"%s\"...\n",line);
- success = (ftpcmd("STAT",line,lcs,rcs,1) == REPLY_COMPLETE);
- return(success);
-
- case FTP_SIT: { /* SITE */
- return(doftpsite());
- }
-
- case FTP_SIZ: /* (ask for) SIZE */
- if ((x = cmtxt("Remote filename", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp size \"%s\"...\n",line);
- success = (ftpcmd("SIZE",line,lcs,rcs,1) == REPLY_COMPLETE);
- if (success)
- sizeok = 1;
- return(success);
-
- case FTP_SYS: /* Ask for server's SYSTEM type */
- if ((x = cmcfm()) < 0) return(x);
- CHECKCONN();
- if (testing)
- printf(" ftp system...\n");
- success = (ftpcmd("SYST",NULL,0,0,1) == REPLY_COMPLETE);
- return(success);
-
- case FTP_UMA: /* Set/query UMASK */
- if ((x = cmfld("Umask to set or nothing to query","",&s,xxstring)) < 0)
- if (x != -3)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((x = cmcfm()) < 0) return(x);
- CHECKCONN();
- if (testing) {
- if (tmpbuf[0])
- printf(" ftp umask \"%s\"...\n",tmpbuf);
- else
- printf(" ftp query umask...\n");
- }
- success = ftp_umask(tmpbuf);
- return(success);
-
- case FTP_USR:
- return(doftpusr());
-
- case FTP_QUO:
- if ((x = cmtxt("FTP protocol command", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- success = (ftpcmd(s,NULL,0,0,ftp_vbm) == REPLY_COMPLETE);
- return(success);
-
- case FTP_TYP: /* Type */
- if ((x = cmkey(ftptyp,nftptyp,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- CHECKCONN();
- ftp_typ = x;
- g_ftp_typ = x;
- tenex = (ftp_typ == FTT_TEN);
- changetype(ftp_typ,ftp_vbm);
- return(1);
-
- case FTP_CHK: /* Check if remote file(s) exist(s) */
- if ((x = cmtxt("remote filename", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- success = remote_files(1,(CHAR *)s,(CHAR *)s,0) ? 1 : 0;
- return(success);
-
- case FTP_FEA: /* RFC2389 */
- if ((y = cmcfm()) < 0)
- return(y);
- CHECKCONN();
- success = (ftpcmd("FEAT",NULL,0,0,1) == REPLY_COMPLETE);
- if (success) {
- if (sfttab[0] > 0) {
- ftp_aut = sfttab[SFT_AUTH];
- sizeok = sfttab[SFT_SIZE];
- mdtmok = sfttab[SFT_MDTM];
- mlstok = sfttab[SFT_MLST];
- }
- }
- return(success);
-
- case FTP_OPT: /* RFC2389 */
- /* Perhaps this should be a keyword list... */
- if ((x = cmfld("FTP command","",&s,xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmtxt("Options for this command", "", &s, xxstring)) < 0)
- return(x);
- success = (ftpcmd("OPTS",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE);
- return(success);
-
- case FTP_ENA: /* FTP ENABLE */
- case FTP_DIS: /* FTP DISABLE */
- if ((x = cmkey(ftpenatab,nftpena,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- switch (x) {
- case ENA_AUTH: /* OK to use autoauthentication */
- ftp_aut = (cx == FTP_ENA) ? 1 : 0;
- sfttab[SFT_AUTH] = ftp_aut;
- break;
- case ENA_FEAT: /* OK to send FEAT command */
- featok = (cx == FTP_ENA) ? 1 : 0;
- break;
- case ENA_MLST: /* OK to use MLST/MLSD */
- mlstok = (cx == FTP_ENA) ? 1 : 0;
- sfttab[SFT_MLST] = mlstok;
- break;
- case ENA_MDTM: /* OK to use MDTM */
- mdtmok = (cx == FTP_ENA) ? 1 : 0;
- sfttab[SFT_MDTM] = mdtmok;
- break;
- case ENA_SIZE: /* OK to use SIZE */
- sizeok = (cx == FTP_ENA) ? 1 : 0;
- sfttab[SFT_SIZE] = sizeok;
- break;
- }
- return(success = 1);
- }
- return(-2);
-}
-
-#ifndef NOSHOW
-static char *
-shopl(x) int x; {
- switch (x) {
- case FPL_CLR: return("clear");
- case FPL_PRV: return("private");
- case FPL_SAF: return("safe");
- case 0: return("(not set)");
- default: return("(unknown)");
- }
-}
-
-int
-shoftp(brief) int brief; {
- char * s = "?";
- int n, x;
-
- if (g_ftp_typ > -1) { /* Restore TYPE if saved */
- ftp_typ = g_ftp_typ;
- /* g_ftp_typ = -1; */
- }
- printf("\n");
- printf("FTP connection: %s\n",connected ?
- ftp_host :
- "(none)"
- );
- n = 2;
- if (connected) {
- n++;
- printf("FTP server type: %s\n",
- ftp_srvtyp[0] ? ftp_srvtyp : "(unknown)");
- }
- if (loggedin)
- printf("Logged in as: %s\n",
- strval(ftp_logname,"(unknown)"));
- else
- printf("Not logged in\n");
- n++;
- if (brief) return(0);
-
- printf("\nSET FTP values:\n\n");
- n += 3;
-
- printf(" ftp anonymous-password: %s\n",
- ftp_apw ? ftp_apw : "(default)"
- );
- printf(" ftp auto-login: %s\n",showoff(ftp_log));
- printf(" ftp auto-authentication: %s\n",showoff(ftp_aut));
- switch (ftp_typ) {
- case FTT_ASC: s = "text"; break;
- case FTT_BIN: s = "binary"; break;
- case FTT_TEN: s = "tenex"; break;
- }
-#ifdef FTP_TIMEOUT
- printf(" ftp timeout: %ld\n",ftp_timeout);
-#endif /* FTP_TIMEOUT */
- printf(" ftp type: %s\n",s);
- printf(" ftp get-filetype-switching: %s\n",showoff(get_auto));
- printf(" ftp dates: %s\n",showoff(ftp_dates));
- printf(" ftp error-action: %s\n",ftp_err ? "quit":"proceed");
- printf(" ftp filenames: %s\n",
- ftp_cnv == CNV_AUTO ? "auto" : (ftp_cnv ? "converted" : "literal")
- );
- printf(" ftp debug %s\n",showoff(ftp_deb));
-
- printf(" ftp passive-mode: %s\n",showoff(ftp_psv));
- printf(" ftp permissions: %s\n",showooa(ftp_prm));
- printf(" ftp verbose-mode: %s\n",showoff(ftp_vbx));
- printf(" ftp send-port-commands: %s\n",showoff(ftp_psv));
- printf(" ftp unique-server-names: %s\n",showoff(ftp_usn));
-#ifdef COMMENT
- /* See note in doxftp() */
- if (ftp_fnc < 0)
- ftp_fnc = fncact;
-#endif /* COMMENT */
- printf(" ftp collision: %s\n",
- fncnam[ftp_fnc > -1 ? ftp_fnc : fncact]);
- printf(" ftp server-time-offset: %s\n",
- fts_sto ? fts_sto : "(none)");
- n += 15;
-
-#ifndef NOCSETS
- printf(" ftp character-set-translation: %s\n",showoff(ftp_xla));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-
- printf(" ftp server-character-set: %s\n",fcsinfo[ftp_csr].keyword);
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-
- printf(" file character-set: %s\n",fcsinfo[fcharset].keyword);
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-#endif /* NOCSETS */
-
- x = ftp_dis;
- if (x < 0)
- x = fdispla;
- switch (x) {
- case XYFD_N: s = "none"; break;
- case XYFD_R: s = "serial"; break;
- case XYFD_C: s = "fullscreen"; break;
- case XYFD_S: s = "crt"; break;
- case XYFD_B: s = "brief"; break;
- }
- printf(" ftp display: %s\n",s);
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-
- if (mlstok || featok || mdtmok || sizeok || ftp_aut) {
- printf(" enabled: ");
- if (ftp_aut) printf(" AUTH");
- if (featok) printf(" FEAT");
- if (mdtmok) printf(" MDTM");
- if (mlstok) printf(" MLST");
- if (sizeok) printf(" SIZE");
- printf("\n");
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- }
- if (!mlstok || !featok || !mdtmok || !sizeok || !ftp_aut) {
- printf(" disabled: ");
- if (!ftp_aut) printf(" AUTH");
- if (!featok) printf(" FEAT");
- if (!mdtmok) printf(" MDTM");
- if (!mlstok) printf(" MLST");
- if (!sizeok) printf(" SIZE");
- printf("\n");
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- }
- switch (ftpget) {
- case 0: s = "kermit"; break;
- case 1: s = "ftp"; break;
- case 2: s = "auto"; break;
- default: s = "?";
- }
- printf(" get-put-remote: %s\n",s);
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-
- printf("\n");
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-
-#ifdef FTP_SECURITY
- printf("Available security methods: ");
-#ifdef FTP_GSSAPI
- printf("GSSAPI ");
-#endif /* FTP_GSSAPI */
-#ifdef FTP_KRB4
- printf("Kerberos4 ");
-#endif /* FTP_KRB4 */
-#ifdef FTP_SRP
- printf("SRP ");
-#endif /* FTP_SRP */
-#ifdef FTP_SSL
- printf("SSL ");
-#endif /* FTP_SSL */
-
- n++;
- printf("\n\n");
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp authtype: %s\n",strval(auth_type,NULL));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp auto-encryption: %s\n",showoff(ftp_cry));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp credential-forwarding: %s\n",showoff(ftp_cfw));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp command-protection-level: %s\n",shopl(ftp_cpl));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp data-protection-level: %s\n",shopl(ftp_dpl));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp secure proxy: %s\n",shopl(ssl_ftp_proxy));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-#else
- printf("Available security methods: (none)\n");
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-#endif /* FTP_SECURITY */
-
- if (n <= cmd_rows - 3)
- printf("\n");
- return(0);
-}
-#endif /* NOSHOW */
-
-#ifndef NOHELP
-/* FTP HELP text strings */
-
-static char * fhs_ftp[] = {
- "Syntax: FTP subcommand [ operands ]",
- " Makes an FTP connection, or sends a command to the FTP server.",
- " To see a list of available FTP subcommands, type \"ftp ?\".",
- " and then use HELP FTP xxx to get help about subcommand xxx.",
- " Also see HELP SET FTP, HELP SET GET-PUT-REMOTE, and HELP FIREWALL.",
- ""
-};
-
-static char * fhs_acc[] = { /* ACCOUNT */
- "Syntax: FTP ACCOUNT text",
- " Sends an account designator to an FTP server that needs one.",
- " Most FTP servers do not use accounts; some use them for other",
- " other purposes, such as disk-access passwords.",
- ""
-};
-static char * fhs_app[] = { /* APPEND */
- "Syntax: FTP APPEND filname",
- " Equivalent to [ FTP ] PUT /APPEND. See HELP FTP PUT.",
- ""
-};
-static char * fhs_cls[] = { /* BYE, CLOSE */
- "Syntax: [ FTP ] BYE",
- " Logs out from the FTP server and closes the FTP connection.",
- " Also see HELP SET GET-PUT-REMOTE. Synonym: [ FTP ] CLOSE.",
- ""
-};
-static char * fhs_cwd[] = { /* CD, CWD */
- "Syntax: [ FTP ] CD directory",
- " Asks the FTP server to change to the given directory.",
- " Also see HELP SET GET-PUT-REMOTE. Synonyms: [ FTP ] CWD, RCD, RCWD.",
- ""
-};
-static char * fhs_gup[] = { /* CDUP, UP */
- "Syntax: FTP CDUP",
- " Asks the FTP server to change to the parent directory of its current",
- " directory. Also see HELP SET GET-PUT-REMOTE. Synonym: FTP UP.",
- ""
-};
-static char * fhs_chm[] = { /* CHMOD */
- "Syntax: FTP CHMOD filename permissions",
- " Asks the FTP server to change the permissions, protection, or mode of",
- " the given file. The given permissions must be in the syntax of the",
- " the server's file system, e.g. an octal number for UNIX. Also see",
- " FTP PUT /PERMISSIONS",
- ""
-};
-static char * fhs_mde[] = { /* DELETE */
- "Syntax: FTP DELETE [ switches ] filespec",
- " Asks the FTP server to delete the given file or files.",
- " Synonym: MDELETE (Kermit makes no distinction between single and",
- " multiple file deletion). Optional switches:",
- " ",
- " /ERROR-ACTION:{PROCEED,QUIT}",
- " /EXCEPT:pattern",
- " /FILENAMES:{AUTO,CONVERTED,LITERAL}",
- " /LARGER-THAN:number",
-#ifdef UNIXOROSK
- " /NODOTFILES",
-#endif /* UNIXOROSK */
- " /QUIET",
-#ifdef RECURSIVE
- " /RECURSIVE (depends on server)",
- " /SUBDIRECTORIES",
-#endif /* RECURSIVE */
- " /SMALLER-THAN:number",
- ""
-};
-static char * fhs_dir[] = { /* DIRECTORY */
- "Syntax: FTP DIRECTORY [ filespec ]",
- " Asks the server to send a directory listing of the files that match",
- " the given filespec, or if none is given, all the files in its current",
- " directory. The filespec, including any wildcards, must be in the",
- " syntax of the server's file system. Also see HELP SET GET-PUT-REMOTE.",
- " Synonym: RDIRECTORY.",
- ""
-};
-static char * fhs_vdi[] = { /* VDIRECTORY */
- "Syntax: FTP VDIRECTORY [ filespec ]",
- " Asks the server to send a directory listing of the files that match",
- " the given filespec, or if none is given, all the files in its current",
- " directory. VDIRECTORY is needed for getting verbose directory",
- " listings from certain FTP servers, such as on TOPS-20. Try it if",
- " FTP DIRECTORY lists only filenames without details.",
- ""
-};
-static char * fhs_fea[] = { /* FEATURES */
- "Syntax: FTP FEATURES",
- " Asks the FTP server to list its special features. Most FTP servers",
- " do not recognize this command.",
- ""
-};
-static char * fhs_mge[] = { /* MGET */
- "Syntax: [ FTP ] MGET [ options ] filespec [ filespec [ filespec ... ] ]",
- " Download a single file or multiple files. Asks the FTP server to send",
- " the given file or files. Also see FTP GET. Optional switches:",
- " ",
- " /AS-NAME:text",
- " Name under which to store incoming file.",
- " Pattern required for for multiple files.",
- " /BINARY", /* /IMAGE */
- " Force binary mode. Synonym: /IMAGE.",
- " /COLLISION:{BACKUP,RENAME,UPDATE,DISCARD,APPEND,OVERWRITE}",
- " What to do if an incoming file has the same name as an existing file.",
-
-#ifdef PUTPIPE
- " /COMMAND",
- " Specifies that the as-name is a command to which the incoming file",
- " is to be piped as standard input.",
-#endif /* PUTPIPE */
-
-#ifdef DOUPDATE
- " /DATES-DIFFER",
- " Download only those files whose modification date-times differ from",
- " those of the corresponding local files, or that do not already",
- " exist on the local computer.",
-#endif /* DOUPDATE */
-
- " /DELETE",
- " Specifies that each file is to be deleted from the server after,",
- " and only if, it is successfully downloaded.",
- " /ERROR-ACTION:{PROCEED,QUIT}",
- " When downloading a group of files, what to do upon failure to",
- " transfer a file: quit or proceed to the next one.",
- " /EXCEPT:pattern",
- " Exception list: don't download any files that match this pattern.",
- " See HELP WILDCARD for pattern syntax.",
- " /FILENAMES:{AUTOMATIC,CONVERTED,LITERAL}",
- " Whether to convert incoming filenames to local syntax.",
-#ifdef PIPESEND
-#ifndef NOSPL
- " /FILTER:command",
- " Pass incoming files through the given command.",
-#endif /* NOSPL */
-#endif /* PIPESEND */
- " /LARGER-THAN:number",
- " Only download files that are larger than the given number of bytes.",
- " /LISTFILE:filename",
- " Obtain the list of files to download from the given file.",
-#ifndef NOCSETS
- " /LOCAL-CHARACTER-SET:name",
- " When downloading in text mode and character-set conversion is",
- " desired, this specifies the target set.",
-#endif /* NOCSETS */
- " /MATCH:pattern",
- " Specifies a pattern to be used to select filenames locally from the",
- " server's list.",
- " /MLSD",
- " Forces sending of MLSD (rather than NLST) to get the file list.",
-#ifdef CK_TMPDIR
- " /MOVE-TO:directory",
- " Each file that is downloaded is to be moved to the given local",
- " directory immediately after, and only if, it has been received",
- " successfully.",
-#endif /* CK_TMPDIR */
- " /NAMELIST:filename",
- " Instead of downloading the files, stores the list of files that",
- " would be downloaded in the given local file, one filename per line.",
- " /NLST",
- " Forces sending of NLST (rather than MLSD) to get the file list.",
- " /NOBACKUPFILES",
- " Don't download any files whose names end with .~<number>~.",
- " /NODOTFILES",
- " Don't download any files whose names begin with period (.).",
- " /QUIET",
- " Suppress the file-transfer display.",
-#ifdef FTP_RESTART
- " /RECOVER", /* /RESTART */
- " Resume a download that was previously interrupted from the point of",
- " failure. Works only in binary mode. Not supported by all servers.",
- " Synonym: /RESTART.",
-#endif /* FTP_RESTART */
-#ifdef RECURSIVE
- " /RECURSIVE", /* /SUBDIRECTORIES */
- " Create subdirectories automatically if the server sends files",
- " recursively and includes pathnames (most don't).",
-#endif /* RECURSIVE */
- " /RENAME-TO:text",
- " Each file that is downloaded is to be renamed as indicated just,",
- " after, and only if, it has arrived successfully.",
-#ifndef NOCSETS
- " /SERVER-CHARACTER-SET:name",
- " When downloading in text mode and character-set conversion is desired"
-, " this specifies the original file's character set on the server.",
-#endif /* NOCSETS */
- " /SERVER-RENAME:text",
- " Each server source file is to be renamed on the server as indicated",
- " immediately after, but only if, it has arrived successfully.",
- " /SMALLER-THAN:number",
- " Download only those files smaller than the given number of bytes.",
- " /TEXT", /* /ASCII */
- " Force text mode. Synonym: /ASCII.",
- " /TENEX",
- " Force TENEX (TOPS-20) mode (see HELP SET FTP TYPE).",
-#ifndef NOCSETS
- " /TRANSPARENT",
- " When downloading in text mode, do not convert chracter-sets.",
-#endif /* NOCSETS */
- " /TO-SCREEN",
- " The downloaded file is to be displayed on the screen.",
-#ifdef DOUPDATE
- " /UPDATE",
- " Equivalent to /COLLISION:UPDATE. Download only those files that are",
- " newer than than their local counterparts, or that do not exist on",
- " the local computer.",
-#endif /* DOUPDATE */
- ""
-};
-static char * fhs_hlp[] = { /* HELP */
- "Syntax: FTP HELP [ command [ subcommand... ] ]",
- " Asks the FTP server for help about the given command. First use",
- " FTP HELP by itself to get a list of commands, then use HELP FTP xxx",
- " to get help for command \"xxx\". Synonyms: REMOTE HELP, RHELP.",
- ""
-};
-static char * fhs_idl[] = { /* IDLE */
- "Syntax: FTP IDLE [ number ]",
- " If given without a number, this asks the FTP server to tell its",
- " current idle-time limit. If given with a number, it asks the server",
- " to change its idle-time limit to the given number of seconds.",
- ""
-};
-static char * fhs_usr[] = { /* USER, LOGIN */
- "Syntax: FTP USER username [ password [ account ] ]",
- " Log in to the FTP server. To be used when connected but not yet",
- " logged in, e.g. when SET FTP AUTOLOGIN is OFF or autologin failed.",
- " If you omit the password, and one is required by the server, you are",
- " prompted for it. If you omit the account, no account is sent.",
- " Synonym: FTP LOGIN.",
- ""
-};
-static char * fhs_get[] = { /* GET */
- "Syntax: [ FTP ] GET [ options ] filename [ as-name ]",
- " Download a single file. Asks the FTP server to send the given file.",
- " The optional as-name is the name to store it under when it arrives;",
- " if omitted, the file is stored with the name it arrived with, as",
- " modified according to the FTP FILENAMES setting or /FILENAMES: switch",
- " value. Aside from the file list and as-name, syntax and options are",
- " the same as for FTP MGET, which is used for downloading multiple files."
-, ""
-};
-static char * fhs_mkd[] = { /* MKDIR */
- "Syntax: FTP MKDIR directory",
- " Asks the FTP server to create a directory with the given name,",
- " which must be in the syntax of the server's file system. Synonyms:",
- " REMOTE MKDIR, RMKDIR.",
- ""
-};
-static char * fhs_mod[] = { /* MODTIME */
- "Syntax: FTP MODTIME filename",
- " Asks the FTP server to send the modification time of the given file,",
- " to be displayed on the screen. The date-time format is all numeric:",
- " yyyymmddhhmmssxxx... (where xxx... is 0 or more digits indicating",
- " fractions of seconds).",
- ""
-};
-static char * fhs_mpu[] = { /* MPUT */
- "Syntax: [ FTP ] MPUT [ switches ] filespec [ filespec [ filespec ... ] ]",
- " Uploads files. Sends the given file or files to the FTP server.",
- " Also see FTP PUT. Optional switches are:",
- " ",
- " /AFTER:date-time",
- " Uploads only those files newer than the given date-time.",
- " HELP DATE for info about date-time formats. Synonym: /SINCE.",
-#ifdef PUTARRAY
- " /ARRAY:array-designator",
- " Tells Kermit to upload the contents of the given array, rather than",
- " a file.",
-#endif /* PUTARRAY */
- " /AS-NAME:text",
- " Name under which to send files.",
- " Pattern required for for multiple files.",
- " /BEFORE:date-time",
- " Upload only those files older than the given date-time.",
- " /BINARY",
- " Force binary mode. Synonym: /IMAGE.",
-#ifdef PUTPIPE
- " /COMMAND",
- " Specifies that the filespec is a command whose standard output is",
- " to be sent.",
-#endif /* PUTPIPE */
-
-#ifdef COMMENT
-#ifdef DOUPDATE
- " /DATES-DIFFER",
- " Upload only those files whose modification date-times differ from",
- " those on the server, or that don't exist on the server at all.",
-#endif /* DOUPDATE */
-#endif /* COMMENT */
-
- " /DELETE",
- " Specifies that each source file is to be deleted after, and only if,",
- " it is successfully uploaded.",
- " /DOTFILES",
- " Include files whose names begin with period (.).",
- " /ERROR-ACTION:{PROCEED,QUIT}",
- " When uploading a group of files, what to do upon failure to",
- " transfer a file: quit or proceed to the next one.",
- " /EXCEPT:pattern",
- " Exception list: don't upload any files that match this pattern.",
- " See HELP WILDCARD for pattern syntax.",
- " /FILENAMES:{AUTOMATIC,CONVERTED,LITERAL}",
- " Whether to convert outbound filenames to common syntax.",
-#ifdef PIPESEND
-#ifndef NOSPL
- " /FILTER:command",
- " Pass outbound files through the given command.",
-#endif /* NOSPL */
-#endif /* PIPESEND */
-#ifdef CKSYMLINK
- " /FOLLOWINKS",
- " Send files that are pointed to by symbolic links.",
- " /NOFOLLOWINKS",
- " Skip over symbolic links (default).",
-#endif /* CKSYMLINK */
- " /LARGER-THAN:number",
- " Only upload files that are larger than the given number of bytes.",
- " /LISTFILE:filename",
- " Obtain the list of files to upload from the given file.",
-#ifndef NOCSETS
- " /LOCAL-CHARACTER-SET:name",
- " When uploading in text mode and character-set conversion is",
- " desired, this specifies the source-file character set.",
-#endif /* NOCSETS */
-#ifdef CK_TMPDIR
- " /MOVE-TO:directory",
- " Each source file that is uploaded is to be moved to the given local",
- " directory when, and only if, the transfer is successful.",
-#endif /* CK_TMPDIR */
- " /NOBACKUPFILES",
- " Don't upload any files whose names end with .~<number>~.",
-#ifdef UNIXOROSK
- " /NODOTFILES",
- " Don't upload any files whose names begin with period (.).",
-#endif /* UNIXOROSK */
- " /NOT-AFTER:date-time",
- " Upload only files that are not newer than the given date-time",
- " /NOT-BEFORE:date-time",
- " Upload only files that are not older than the given date-time",
-#ifdef UNIX
- " /PERMISSIONS",
- " Ask the server to set the permissions of each file it receives",
- " according to the source file's permissions.",
-#endif /* UNIX */
- " /QUIET",
- " Suppress the file-transfer display.",
-#ifdef FTP_RESTART
- " /RECOVER",
- " Resume an upload that was previously interrupted from the point of",
- " failure. Synonym: /RESTART.",
-#endif /* FTP_RESTART */
-#ifdef RECURSIVE
- " /RECURSIVE",
- " Send files from the given directory and all the directories beneath",
- " it. Synonym: /SUBDIRECTORIES.",
-#endif /* RECURSIVE */
- " /RENAME-TO:text",
- " Each source file that is uploaded is to be renamed on the local",
- " local computer as indicated when and only if, the transfer completes",
- " successfully.",
-#ifndef NOCSETS
- " /SERVER-CHARACTER-SET:name",
- " When uploading in text mode and character-set conversion is desired,",
- " this specifies the character set to which the file should be",
- " converted for storage on the server.",
-#endif /* NOCSETS */
- " /SERVER-RENAME:text",
- " Each file that is uploaded is to be renamed as indicated on the",
- " server after, and only if, if arrives successfully.",
- " /SIMULATE",
- " Show which files would be sent without actually sending them.",
- " /SMALLER-THAN:number",
- " Upload only those files smaller than the given number of bytes.",
- " /TEXT",
- " Force text mode. Synonym: /ASCII.",
- " /TENEX",
- " Force TENEX (TOPS-20) mode (see HELP SET FTP TYPE).",
-#ifndef NOCSETS
- " /TRANSPARENT",
- " When uploading in text mode, do not convert chracter-sets.",
-#endif /* NOCSETS */
- " /TYPE:{TEXT,BINARY}",
- " Upload only files of the given type.",
-#ifdef DOUPDATE
- " /UPDATE",
- " If a file of the same name exists on the server, upload only if",
- " the local file is newer.",
-#endif /* DOUPDATE */
- " /UNIQUE-SERVER-NAMES",
- " Ask the server to compute new names for any incoming file that has",
- " the same name as an existing file.",
- ""
-};
-static char * fhs_opn[] = { /* OPEN */
-#ifdef CK_SSL
- "Syntax: FTP [ OPEN ] [ { /SSL, /TLS } ] hostname [ port ] [ switches ]",
- " Opens a connection to the FTP server on the given host. The default",
- " TCP port is 21 (990 if SSL/TLS is used), but a different port number",
- " can be supplied if necessary. Optional switches are:",
-#else /* CK_SSL */
- "Syntax: FTP [ OPEN ] hostname [ port ] [ switches ]",
- " Opens a connection to the FTP server on the given host. The default",
- " TCP port is 21, but a different port number can be supplied if",
- " necessary. Optional switches are:",
-#endif /* CK_SSL */
- " ",
- " /ANONYMOUS",
- " Logs you in anonymously.",
- " /USER:text",
- " Supplies the given text as your username.",
- " /PASSWORD:text",
- " Supplies the given text as your password. If you include a username",
- " but omit this switch and the server requires a password, you are",
- " prompted for it.",
- " /ACCOUNT:text",
- " Supplies the given text as your account, if required by the server.",
- " /ACTIVE",
- " Forces an active (rather than passive) connection.",
- " /PASSIVE",
- " Forces a passive (rather than active) connection.",
- " /NOINIT",
- " Inhibits sending initial REST, STRU, and MODE commands, which are",
- " well-known standard commands, but to which some servers react badly.",
- " /NOLOGIN",
- " Inhibits autologin for this connection only.",
- ""
-};
-static char * fhs_opt[] = { /* OPTS, OPTIONS */
- "Syntax: FTP OPTIONS",
- " Asks the FTP server to list its current options. Advanced, new,",
- " not supported by most FTP servers.",
- ""
-};
-static char * fhs_put[] = { /* PUT, SEND */
- "Syntax: [ FTP ] PUT [ switches ] filespec [ as-name ]",
- " Like FTP MPUT, but only one filespec is allowed, and if it is followed",
- " by an additional field, this is interpreted as the name under which",
- " to send the file or files. See HELP FTP MPUT.",
- ""
-};
-static char * fhs_reput[] = { /* REPUT, RESEND */
- "Syntax: [ FTP ] REPUT [ switches ] filespec [ as-name ]",
- " Synonym for FTP PUT /RECOVER. Recovers an interrupted binary-mode",
- " upload from the point of failure if the FTP server supports recovery.",
- " Synonym: [ FTP ] RESEND. For details see HELP FTP MPUT.",
- ""
-};
-static char * fhs_pwd[] = { /* PWD */
- "Syntax: FTP PWD",
- " Asks the FTP server to reveal its current working directory.",
- " Synonyms: REMOTE PWD, RPWD.",
- ""
-};
-static char * fhs_quo[] = { /* QUOTE */
- "Syntax: FTP QUOTE text",
- " Sends an FTP protocol command to the FTP server. Use this command",
- " for sending commands that Kermit might not support.",
- ""
-};
-static char * fhs_rge[] = { /* REGET */
- "Syntax: FTP REGET",
- " Synonym for FTP GET /RECOVER.",
- ""
-};
-static char * fhs_ren[] = { /* RENAME */
- "Syntax: FTP RENAME name1 name1",
- " Asks the FTP server to change the name of the file whose name is name1",
- " and which resides in the FTP server's file system, to name2. Works",
- " only for single files; wildcards are not accepted.",
- ""
-};
-static char * fhs_res[] = { /* RESET */
- "Syntax: FTP RESET",
- " Asks the server to log out your session, terminating your access",
- " rights, without closing the connection.",
- ""
-};
-static char * fhs_rmd[] = { /* RMDIR */
- "Syntax: FTP RMDIR directory",
- " Asks the FTP server to remove the directory whose name is given.",
- " This usually requires the directory to be empty. Synonyms: REMOTE",
- " RMDIR, RRMDIR.",
- ""
-};
-static char * fhs_sit[] = { /* SITE */
- "Syntax: FTP SITE text",
- " Sends a site-specific command to the FTP server.",
- ""
-};
-static char * fhs_siz[] = { /* SIZE */
- "Syntax: FTP SIZE filename",
- " Asks the FTP server to send a numeric string representing the size",
- " of the given file.",
- ""
-};
-static char * fhs_sta[] = { /* STATUS */
- "Syntax: FTP STATUS [ filename ]",
- " Asks the FTP server to report its status. If a filename is given,",
- " the FTP server should report details about the file.",
- ""
-};
-static char * fhs_sys[] = { /* SYSTEM */
- "Syntax: FTP SYSTEM",
- " Asks the FTP server to report its operating system type.",
- ""
-};
-static char * fhs_typ[] = { /* TYPE */
- "Syntax: FTP TYPE { TEXT, BINARY, TENEX }",
- " Puts the client and server in the indicated transfer mode.",
- " ASCII is a synonym for TEXT. TENEX is used only for uploading 8-bit",
- " binary files to a 36-bit platforms such as TENEX or TOPS-20 and/or",
- " downloading files from TENEX or TOPS-20 that have been uploaded in",
- " TENEX mode.",
- ""
-};
-static char * fhs_uma[] = { /* UMASK */
- "Syntax: FTP UMASK number",
- " Asks the FTP server to set its file creation mode mask. Applies",
- " only (or mainly) to UNIX-based FTP servers.",
- ""
-};
-static char * fhs_chk[] = { /* CHECK */
- "Syntax: FTP CHECK remote-filespec",
- " Asks the FTP server if the given file or files exist. If the",
- " remote-filespec contains wildcards, this command fails if no server",
- " files match, and succeeds if at least one file matches. If the",
- " remote-filespec does not contain wildcards, this command succeeds if",
- " the given file exists and fails if it does not.",
- ""
-};
-static char * fhs_ena[] = { /* ENABLE */
- "Syntax: FTP ENABLE { AUTH, FEAT, MDTM, MLST, SIZE }",
- " Enables the use of the given FTP protocol command in case it has been",
- " disabled (but this is no guarantee that the FTP server understands it)."
-,
- " Use SHOW FTP to see which of these commands is enabled and disabled.",
- " Also see FTP DISABLE.",
- ""
-};
-static char * fhs_dis[] = { /* DISABLE */
- "Syntax: FTP DISABLE { AUTH, FEAT, MDTM, MLST, SIZE }",
- " Disables the use of the given FTP protocol command.",
- " Also see FTP ENABLE.",
- ""
-};
-
-#endif /* NOHELP */
-
-int
-doftphlp() {
- int cx;
- if ((cx = cmkey(ftpcmdtab,nftpcmd,"","",xxstring)) < 0)
- if (cx != -3)
- return(cx);
- if ((x = cmcfm()) < 0)
- return(x);
-
-#ifdef NOHELP
- printf("Sorry, no help available\n");
-#else
- switch (cx) {
- case -3:
- return(hmsga(fhs_ftp));
- case FTP_ACC: /* ACCOUNT */
- return(hmsga(fhs_acc));
- case FTP_APP: /* APPEND */
- return(hmsga(fhs_app));
- case FTP_CLS: /* BYE, CLOSE */
- return(hmsga(fhs_cls));
- case FTP_CWD: /* CD, CWD */
- return(hmsga(fhs_cwd));
- case FTP_GUP: /* CDUP, UP */
- return(hmsga(fhs_gup));
- case FTP_CHM: /* CHMOD */
- return(hmsga(fhs_chm));
- case FTP_MDE: /* DELETE, MDELETE */
- return(hmsga(fhs_mde));
- case FTP_DIR: /* DIRECTORY */
- return(hmsga(fhs_dir));
- case FTP_VDI: /* VDIRECTORY */
- return(hmsga(fhs_vdi));
- case FTP_FEA: /* FEATURES */
- return(hmsga(fhs_fea));
- case FTP_GET: /* GET */
- return(hmsga(fhs_get));
- case FTP_HLP: /* HELP */
- return(hmsga(fhs_hlp));
- case FTP_IDL: /* IDLE */
- return(hmsga(fhs_idl));
- case FTP_USR: /* USER, LOGIN */
- return(hmsga(fhs_usr));
- case FTP_MGE: /* MGET */
- return(hmsga(fhs_mge));
- case FTP_MKD: /* MKDIR */
- return(hmsga(fhs_mkd));
- case FTP_MOD: /* MODTIME */
- return(hmsga(fhs_mod));
- case FTP_MPU: /* MPUT */
- return(hmsga(fhs_mpu));
- case FTP_OPN: /* OPEN */
- return(hmsga(fhs_opn));
- case FTP_OPT: /* OPTS, OPTIONS */
- return(hmsga(fhs_opt));
- case FTP_PUT: /* PUT, SEND */
- return(hmsga(fhs_put));
- case FTP_REP: /* REPUT, RESEND */
- return(hmsga(fhs_reput));
- case FTP_PWD: /* PWD */
- return(hmsga(fhs_pwd));
- case FTP_QUO: /* QUOTE */
- return(hmsga(fhs_quo));
- case FTP_RGE: /* REGET */
- return(hmsga(fhs_rge));
- case FTP_REN: /* RENAME */
- return(hmsga(fhs_ren));
- case FTP_RES: /* RESET */
- return(hmsga(fhs_res));
- case FTP_RMD: /* RMDIR */
- return(hmsga(fhs_rmd));
- case FTP_SIT: /* SITE */
- return(hmsga(fhs_sit));
- case FTP_SIZ: /* SIZE */
- return(hmsga(fhs_siz));
- case FTP_STA: /* STATUS */
- return(hmsga(fhs_sta));
- case FTP_SYS: /* SYSTEM */
- return(hmsga(fhs_sys));
- case FTP_TYP: /* TYPE */
- return(hmsga(fhs_typ));
- case FTP_UMA: /* UMASK */
- return(hmsga(fhs_uma));
- case FTP_CHK: /* CHECK */
- return(hmsga(fhs_chk));
- case FTP_ENA:
- return(hmsga(fhs_ena));
- case FTP_DIS:
- return(hmsga(fhs_dis));
- default:
- printf("Sorry, help available for this command.\n");
- break;
- }
-#endif /* NOHELP */
- return(success = 0);
-}
-
-int
-dosetftphlp() {
- int cx;
- if ((cx = cmkey(ftpset,nftpset,"","",xxstring)) < 0)
- if (cx != -3)
- return(cx);
- if (cx != -3)
- ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
- if ((x = cmcfm()) < 0)
- return(x);
-
-#ifdef NOHELP
- printf("Sorry, no help available\n");
-#else
- switch (cx) {
- case -3:
- printf("\nSyntax: SET FTP parameter value\n");
- printf(" Type \"help set ftp ?\" for a list of parameters.\n");
- printf(" Type \"help set ftp xxx\" for information about setting\n");
- printf(" parameter xxx. Type \"show ftp\" for current values.\n\n");
- return(0);
-
- case FTS_BUG:
- printf("\nSyntax: SET FTP BUG <name> {ON, OFF}\n");
- printf(
- " Activates a workaround for the named bug in the FTP server.\n");
- printf(" Type SET FTP BUG ? for a list of names.\n");
- printf(" For each bug, the default is OFF\n\n");
- return(0);
-
-#ifdef FTP_SECURITY
- case FTS_ATP: /* "authtype" */
- printf("\nSyntax: SET FTP AUTHTYPE list\n");
- printf(" Specifies an ordered list of authentication methods to be\n"
- );
- printf(" when FTP AUTOAUTHENTICATION is ON. The default list is:\n");
- printf(" GSSAPI-KRB5, SRP, KERBEROS_V4, TLS, SSL.\n\n");
- return(0);
-
- case FTS_AUT: /* "autoauthentication" */
- printf("\nSyntax:SET FTP AUTOAUTHENTICATION { ON, OFF }\n");
- printf(" Tells whether authentication should be negotiated by the\n");
- printf(" FTP OPEN command. Default is ON.\n\n");
- break;
-
- case FTS_CRY: /* "autoencryption" */
- printf("\nSET FTP AUTOENCRYPTION { ON, OFF }\n");
- printf(" Tells whether encryption (privacy) should be negotiated\n");
- printf(" by the FTP OPEN command. Default is ON.\n\n");
- break;
-#endif /* FTP_SECURITY */
-
- case FTS_LOG: /* "autologin" */
- printf("\nSET FTP AUTOLOGIN { ON, OFF }\n");
- printf(" Tells Kermit whether to try to log you in automatically\n");
- printf(" as part of the connection process.\n\n");
- break;
-
- case FTS_DIS:
- printf("\nSET FTP DISPLAY { BRIEF, FULLSCREEN, CRT, ... }\n");
- printf(" Chooses the file-transfer display style for FTP.\n");
- printf(" Like SET TRANSFER DISPLAY but applies only to FTP.\n\n");
- break;
-
-#ifndef NOCSETS
- case FTS_XLA: /* "character-set-translation" */
- printf("\nSET FTP CHARACTER-SET-TRANSLATION { ON, OFF }\n");
- printf(" Whether to translate character sets when transferring\n");
- printf(" text files with FTP. OFF by default.\n\n");
- break;
-
-#endif /* NOCSETS */
- case FTS_FNC: /* "collision" */
- printf("\n");
- printf(
-"Syntax: SET FTP COLLISION { BACKUP,RENAME,UPDATE,DISCARD,APPEND,OVERWRITE }\n"
- );
- printf(" Tells what do when an incoming file has the same name as\n");
- printf(" an existing file when downloading with FTP.\n\n");
- break;
-
-#ifdef FTP_SECURITY
- case FTS_CPL: /* "command-protection-level" */
- printf("\n");
- printf(
-"Syntax: SET FTP COMMAND-PROTECTION-LEVEL { CLEAR,CONFIDENTIAL,PRIVATE,SAFE }"
- );
- printf("\n");
- printf(
-" Tells what level of protection is applied to the FTP command channel.\n\n");
- break;
- case FTS_CFW: /* "credential-forwarding" */
- printf("\nSyntax: SET FTP CREDENTIAL-FORWARDING { ON, OFF }\n");
- printf(" Tells whether end-user credentials are to be forwarded\n");
- printf(" to the server if supported by the authentication method\n");
- printf(" (GSSAPI-KRB5 only).\n\n");
- break;
- case FTS_DPL: /* "data-protection-level" */
- printf("\n");
- printf(
-"Syntax: SET FTP DATA-PROTECTION-LEVEL { CLEAR,CONFIDENTIAL,PRIVATE,SAFE }"
- );
- printf("\n");
- printf(
-" Tells what level of protection is applied to the FTP data channel.\n\n");
- break;
-#endif /* FTP_SECURITY */
-
- case FTS_DBG: /* "debug" */
- printf("\nSyntax: SET FTP DEBUG { ON, OFF }\n");
- printf(" Whether to print FTP protocol messages.\n\n");
- return(0);
-
- case FTS_ERR: /* "error-action" */
- printf("\nSyntax: SET FTP ERROR-ACTION { QUIT, PROCEED }\n");
- printf(" What to do when an error occurs when transferring a group\n")
- ;
- printf(" of files: quit and fail, or proceed to the next file.\n\n");
- return(0);
-
- case FTS_CNV: /* "filenames" */
- printf("\nSyntax: SET FTP FILENAMES { AUTO, CONVERTED, LITERAL }\n");
- printf(" What to do with filenames: convert them, take and use them\n"
- );
- printf(" literally; or choose what to do automatically based on the\n"
- );
- printf(" OS type of the server. The default is AUTO.\n\n");
- return(0);
-
- case FTS_PSV: /* "passive-mode" */
- printf("\nSyntax: SET FTP PASSIVE-MODE { ON, OFF }\n");
- printf(" Whether to use passive mode, which helps to get through\n");
- printf(" firewalls. ON by default.\n\n");
- return(0);
-
- case FTS_PRM: /* "permissions" */
- printf("\nSyntax: SET FTP PERMISSIONS { AUTO, ON, OFF }\n");
- printf(" Whether to try to send file permissions when uploading.\n");
- printf(" OFF by default. AUTO means only if client and server\n");
- printf(" have the same OS type.\n\n");
- return(0);
-
- case FTS_TST: /* "progress-messages" */
- printf("\nSyntax: SET FTP PROGRESS-MESSAGES { ON, OFF }\n");
- printf(" Whether Kermit should print locally-generated feedback\n");
- printf(" messages for each non-file-transfer command.");
- printf(" ON by default.\n\n");
- return(0);
-
- case FTS_SPC: /* "send-port-commands" */
- printf("\nSyntax: SET FTP SEND-PORT-COMMANDS { ON, OFF }\n");
- printf(" Whether Kermit should send a new PORT command for each");
- printf(" task.\n\n");
- return(0);
-
-#ifndef NOCSETS
- case FTS_CSR: /* "server-character-set" */
- printf("\nSyntax: SET FTP SERVER-CHARACTER-SET name\n");
- printf(" The name of the character set used for text files on the\n");
- printf(" server. Enter a name of '?' for a menu.\n\n");
- return(0);
-#endif /* NOCSETS */
-
- case FTS_STO: /* "server-time-offset */
- printf(
-"\nSyntax: SET FTP SERVER-TIME-OFFSET +hh[:mm[:ss]] or -hh[:mm[:ss]]\n");
- printf(
-" Specifies an offset to apply to the server's file timestamps.\n");
- printf(
-" Use this to correct for misconfigured server time or timezone.\n");
- printf(
-" Format: must begin with + or - sign. Hours must be given; minutes\n");
- printf(
-" and seconds are optional: +4 = +4:00 = +4:00:00 (add 4 hours).\n\n");
- return(0);
-
- case FTS_TYP: /* "type" */
- printf("\nSyntax: SET FTP TYPE { TEXT, BINARY, TENEX }\n");
- printf(" Establishes the default transfer mode.\n");
- printf(" TENEX is used for uploading 8-bit binary files to 36-bit\n");
- printf(" platforms such as TENEX and TOPS-20 and for downloading\n");
- printf(" them again. ASCII is a synonym for TEXT. Normally each\n");
- printf(" file's type is determined automatically from its contents\n"
- );
- printf(" or its name; SET FTP TYPE does not prevent that, it only\n");
- printf(" tells which mode to use when the type can't be determined\n"
- );
- printf(" automatically. To completely disable automatic transfer-\n"
- );
- printf(" mode switching and force either text or binary mode, give\n"
- );
- printf(" the top-level command ASCII or BINARY, as in traditional\n");
- printf(" FTP clients.\n\n");
- return(0);
-
-#ifdef FTP_TIMEOUT
- case FTS_TMO:
- printf("\nSyntax: SET FTP TIMEOUT number-of-seconds\n");
- printf(" Establishes a timeout for FTP transfers.\n");
- printf(" The timeout applies per network read or write on the data\n");
- printf(" connection, not to the whole transfer. By default the\n");
- printf(" timeout value is 0, meaning no timeout. Use a positive\n");
- printf(" number to escape gracefully from hung data connections or\n");
- printf(" directory listings.\n\n");
- return(0);
-#endif /* FTP_TIMEOUT */
-
-#ifdef PATTERNS
- case FTS_GFT:
- printf("\nSyntax: SET FTP GET-FILETYPE-SWITCHING { ON, OFF }\n");
- printf(" Tells whether GET and MGET should automatically switch\n");
- printf(" the appropriate file type, TEXT, BINARY, or TENEX, by\n");
- printf(" matching the name of each incoming file with its list of\n");
- printf(" FILE TEXT-PATTERNS and FILE BINARY-PATTERNS. ON by\n");
- printf(" default. SHOW PATTERNS displays the current pattern\n");
- printf(" list. HELP SET FILE to see how to change it.\n");
- break;
-#endif /* PATTERNS */
-
- case FTS_USN: /* "unique-server-names" */
- printf("\nSyntax: SET FTP UNIQUE-SERVER-NAMES { ON, OFF }\n");
- printf(" Tells whether to ask the server to create unique names\n");
- printf(" for any uploaded file that has the same name as an\n");
- printf(" existing file. Default is OFF.\n\n");
- return(0);
-
- case FTS_VBM: /* "verbose-mode" */
- printf("\nSyntax: SET FTP VERBOSE-MODE { ON, OFF }\n");
- printf(" Whether to display all responses from the FTP server.\n");
- printf(" OFF by default.\n\n");
- return(0);
-
- case FTS_DAT:
- printf("\nSyntax: SET FTP DATES { ON, OFF }\n");
- printf(" Whether to set date of incoming files from the file date\n");
- printf(" on the server. ON by default. Note: there is no way to\n")
- ;
- printf(" set the date on files uploaded to the server. Also note\n");
- printf(" that not all servers support this feature.\n\n");
- return(0);
-
- case FTS_APW:
- printf("\nSyntax: SET FTP ANONYMOUS-PASSWORD [ text ]\n");
- printf(" Password to supply automatically on anonymous FTP\n");
- printf(" connections instead of the default user@host.\n");
- printf(" Omit optional text to restore default.\n\n");
- return(0);
-
- default:
- printf("Sorry, help not available for \"set ftp %s\"\n",tmpbuf);
- }
-#endif /* NOHELP */
- return(0);
-}
-
-#ifndef L_SET
-#define L_SET 0
-#endif /* L_SET */
-#ifndef L_INCR
-#define L_INCR 1
-#endif /* L_INCR */
-
-#ifdef FTP_SRP
-char srp_user[BUFSIZ]; /* where is BUFSIZ defined? */
-char *srp_pass;
-char *srp_acct;
-#endif /* FTP_SRP */
-
-static int kerror; /* Needed for all auth types */
-
-static struct sockaddr_in hisctladdr;
-static struct sockaddr_in hisdataaddr;
-static struct sockaddr_in data_addr;
-static int data = -1;
-static int ptflag = 0;
-static struct sockaddr_in myctladdr;
-
-#ifdef COMMENT
-#ifndef OS2
-UID_T getuid();
-#endif /* OS2 */
-#endif /* COMMENT */
-
-
-static int cpend = 0; /* No pending replies */
-
-#ifdef CK_SSL
-extern SSL *ssl_ftp_con;
-extern SSL_CTX *ssl_ftp_ctx;
-extern SSL *ssl_ftp_data_con;
-extern int ssl_ftp_active_flag;
-extern int ssl_ftp_data_active_flag;
-#endif /* CK_SSL */
-
-/* f t p c m d -- Send a command to the FTP server */
-/*
- Call with:
- char * cmd: The command to send.
- char * arg: The argument (e.g. a filename).
- int lcs: The local character set index.
- int rcs: The remote (server) character set index.
- int vbm: Verbose mode:
- 0 = force verbosity off
- >0 = force verbosity on
-
- If arg is given (not NULL or empty) and lcs != rcs and both are > -1,
- and neither lcs or rcs is UCS-2, the arg is translated from the local
- character set to the remote one before sending the result to the server.
-
- Returns:
- 0 on failure with ftpcode = -1
- >= 0 on success (getreply() result) with ftpcode = 0.
-*/
-static char xcmdbuf[RFNBUFSIZ];
-
-static int
-ftpcmd(cmd,arg,lcs,rcs,vbm) char * cmd, * arg; int lcs, rcs, vbm; {
- char * s = NULL;
- int r = 0, x = 0, fc = 0, len = 0, cmdlen = 0, q = -1;
- sig_t oldintr;
-
- if (ftp_deb) /* DEBUG */
- vbm = 1;
- else if (quiet || dpyactive) /* QUIET or File Transfer Active */
- vbm = 0;
- else if (vbm < 0) /* VERBOSE */
- vbm = ftp_vbm;
-
- cancelfile = 0;
- if (!cmd) cmd = "";
- if (!arg) arg = "";
- cmdlen = (int)strlen(cmd);
- len = cmdlen + (int)strlen(arg) + 1;
-
- if (ftp_deb /* && !dpyactive */ ) {
-#ifdef FTP_PROXY
- if (ftp_prx) printf("%s ", ftp_host);
-#endif /* FTP_PROXY */
- printf("---> ");
- if (!anonymous && strcmp("PASS",cmd) == 0)
- printf("PASS XXXX");
- else
- printf("%s %s",cmd,arg);
- printf("\n");
- }
- /* bzero(xcmdbuf,RFNBUFSIZ); */
- ckmakmsg(xcmdbuf,RFNBUFSIZ, cmd, *arg ? " " : "", arg, NULL);
-
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"ftpcmd cmd",cmd,0);
- debug(F110,"ftpcmd arg",arg,0);
- debug(F101,"ftpcmd lcs","",lcs);
- debug(F101,"ftpcmd rcs","",rcs);
- }
-#endif /* DEBUG */
-
- if (csocket == -1) {
- perror("No control connection for command");
- ftpcode = -1;
- return(0);
- }
- havesigint = 0;
- oldintr = signal(SIGINT, cmdcancel);
-
-#ifndef NOCSETS
- if (*arg && /* If an arg was given */
- lcs > -1 && /* and a local charset */
- rcs > -1 && /* and a remote charset */
- lcs != rcs && /* and the two are not the same */
- lcs != FC_UCS2 && /* and neither one is UCS-2 */
- rcs != FC_UCS2 /* ... */
- ) {
- initxlate(lcs,rcs); /* Translate arg from lcs to rcs */
- xgnbp = arg; /* Global pointer to input string */
- rfnptr = rfnbuf; /* Global pointer to output buffer */
-
- while (1) {
- if ((c0 = xgnbyte(FC_UCS2,lcs,strgetc)) < 0) break;
- if (xpnbyte(c0,TC_UCS2,rcs,strputc) < 0) break;
- }
- /*
- We have to copy here instead of translating directly into
- xcmdbuf[] so strputc() can check length. Alternatively we could
- write yet another xpnbyte() output function.
- */
- if ((int)strlen(rfnbuf) > (RFNBUFSIZ - (cmdlen+1))) {
- printf("?FTP command too long: %s + arg\n",cmd);
- ftpcode = -1;
- return(0);
- }
- x = ckstrncpy(&xcmdbuf[cmdlen+1], rfnbuf, RFNBUFSIZ - (cmdlen+1));
- }
-#endif /* NOCSETS */
-
- s = xcmdbuf; /* Command to send to server */
-
-#ifdef DEBUG
- if (deblog) { /* Log it */
- if (!anonymous && !ckstrcmp(s,"PASS ",5,0)) {
- /* But don't log passwords */
- debug(F110,"FTP SENT ","PASS XXXX",0);
- } else {
- debug(F110,"FTP SENT ",s,0);
- }
- }
-#endif /* DEBUG */
-
-#ifdef CK_ENCRYPTION
- again:
-#endif /* CK_ENCRYPTION */
- if (scommand(s) == 0) { /* Send it. */
- signal(SIGINT, oldintr);
- return(0);
- }
- cpend = 1;
- x = !strcmp(cmd,"QUIT"); /* Is it the QUIT command? */
- if (x) /* In case we're interrupted */
- connected = 0; /* while waiting for the reply... */
-
- fc = 0; /* Function code for getreply() */
- if (!strncmp(cmd,"AUTH ",5) /* Must parse AUTH reply */
-#ifdef FTPHOST
- && strncmp(cmd, "HOST ",5)
-#endif /* FTPHOST */
- ) {
- fc = GRF_AUTH;
- } else if (!ckstrcmp(cmd,"FEAT",-1,0)) { /* Must parse FEAT reply */
- fc = GRF_FEAT; /* But FEAT not widely understood */
- if (!ftp_deb) /* So suppress error messages */
- vbm = 9;
- }
- r = getreply(x, /* Expect connection to close */
- lcs,rcs, /* Charsets */
- vbm, /* Verbosity */
- fc /* Function code */
- );
- if (q > -1)
- quiet = q;
-
-#ifdef CK_ENCRYPTION
- if (ftpcode == 533 && ftp_cpl == FPL_PRV) {
- fprintf(stderr,
- "ENC command not supported at server; retrying under MIC...\n");
- ftp_cpl = FPL_SAF;
- goto again;
- }
-#endif /* CK_ENCRYPTION */
-#ifdef COMMENT
- if (cancelfile && oldintr != SIG_IGN)
- (*oldintr)(SIGINT);
-#endif /* COMMENT */
- signal(SIGINT, oldintr);
- return(r);
-}
-
-static VOID
-lostpeer() {
- debug(F100,"lostpeer","",0);
- if (connected) {
- if (csocket != -1) {
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- SSL_shutdown(ssl_ftp_con);
- SSL_free(ssl_ftp_con);
- ssl_ftp_proxy = 0;
- ssl_ftp_active_flag = 0;
- ssl_ftp_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(csocket, 1+1);
-#endif /* USE_SHUTDOWN */
- close(csocket);
-#endif /* TCPIPLIB */
- csocket = -1;
- }
- if (data != -1) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = -1;
- }
- connected = 0;
- anonymous = 0;
- loggedin = 0;
- auth_type = NULL;
- ftp_cpl = ftp_dpl = FPL_CLR;
-#ifdef CKLOGDIAL
- ftplogend();
-#endif /* CKLOGDIAL */
-
-#ifdef LOCUS
- if (autolocus) /* Auotomatic locus switching... */
- setlocus(1,1); /* Switch locus to local. */
-#endif /* LOCUS */
-#ifdef OS2
- DialerSend(OPT_KERMIT_HANGUP, 0);
-#endif /* OS2 */
- }
-#ifdef FTP_PROXY
- pswitch(1);
- if (connected) {
- if (csocket != -1) {
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(csocket, 1+1);
-#endif /* USE_SHUTDOWN */
- close(csocket);
-#endif /* TCPIPLIB */
- csocket = -1;
- }
- connected = 0;
- anonymous = 0;
- loggedin = 0;
- auth_type = NULL;
- ftp_cpl = ftp_dpl = FPL_CLR;
- }
- proxflag = 0;
- pswitch(0);
-#endif /* FTP_PROXY */
-}
-
-int
-ftpisopen() {
- return(connected);
-}
-
-static int
-ftpclose() {
- extern int quitting;
- if (!connected)
- return(0);
- ftp_xfermode = xfermode;
- if (!ftp_vbm && !quiet)
- printlines = 1;
- ftpcmd("QUIT",NULL,0,0,ftp_vbm);
- if (csocket) {
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- SSL_shutdown(ssl_ftp_con);
- SSL_free(ssl_ftp_con);
- ssl_ftp_proxy = 0;
- ssl_ftp_active_flag = 0;
- ssl_ftp_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(csocket, 1+1);
-#endif /* USE_SHUTDOWN */
- close(csocket);
-#endif /* TCPIPLIB */
- }
- csocket = -1;
- connected = 0;
- anonymous = 0;
- loggedin = 0;
- mdtmok = 1;
- sizeok = 1;
- featok = 1;
- stouarg = 1;
- typesent = 0;
- data = -1;
- globaldin = -1;
-#ifdef FTP_PROXY
- if (!proxy)
- macnum = 0;
-#endif /* FTP_PROXY */
- auth_type = NULL;
- ftp_dpl = FPL_CLR;
-#ifdef CKLOGDIAL
- ftplogend();
-#endif /* CKLOGDIAL */
-#ifdef LOCUS
- /* Unprefixed file management commands are executed locally */
- if (autolocus && !ftp_cmdlin && !quitting) {
- setlocus(1,1);
- }
-#endif /* LOCUS */
-#ifdef OS2
- DialerSend(OPT_KERMIT_HANGUP, 0);
-#endif /* OS2 */
- return(0);
-}
-
-int
-ftpopen(remote, service, use_tls) char * remote, * service; int use_tls; {
- char * host;
-
- if (connected) {
- printf("?Already connected to %s, use FTP CLOSE first.\n", ftp_host);
- ftpcode = -1;
- return(0);
- }
-#ifdef FTPHOST
- hostcmd = 0;
-#endif /* FTPHOST */
- alike = 0;
- ftp_srvtyp[0] = NUL;
- if (!service) service = "";
- if (!*service) service = use_tls ? "ftps" : "ftp";
-
- if (!isdigit(service[0])) {
- struct servent *destsp;
- destsp = getservbyname(service, "tcp");
- if (!destsp) {
- if (!ckstrcmp(service,"ftp",-1,0)) {
- ftp_port = 21;
- } else if (!ckstrcmp(service,"ftps",-1,0)) {
- ftp_port = 990;
- } else {
- printf("?Bad port name - \"%s\"\n", service);
- ftpcode = -1;
- return(0);
- }
- } else {
- ftp_port = destsp->s_port;
- ftp_port = ntohs((unsigned short)ftp_port); /* SMS 2007/02/15 */
- }
- } else
- ftp_port = atoi(service);
- if (ftp_port <= 0) {
- printf("?Bad port name - \"%s\"\n", service);
- ftpcode = -1;
- return(0);
- }
- host = ftp_hookup(remote, ftp_port, use_tls);
- if (host) {
- ckstrncpy(ftp_user_host,remote,MAX_DNS_NAMELEN);
- connected = 1; /* Set FTP defaults */
- ftp_cpl = ftp_dpl = FPL_CLR;
- curtype = FTT_ASC; /* Server uses ASCII mode */
- form = FORM_N;
- mode = MODE_S;
- stru = STRU_F;
- strcpy(bytename, "8");
- bytesize = 8;
-
-#ifdef FTP_SECURITY
- if (ftp_aut) {
- if (ftp_auth()) {
- if (ftp_cry
-#ifdef OS2
- && ck_crypt_is_installed()
-#endif /* OS2 */
- ) {
- if (!quiet)
- printf("FTP Command channel is Private (encrypted)\n");
- ftp_cpl = FPL_PRV;
- if (setpbsz(DEFAULT_PBSZ) < 0) {
- /* a failure here is most likely caused by a mixup */
- /* in the session key used by client and server */
- printf("?Protection buffer size negotiation failed\n");
- return(0);
- }
- if (ftpcmd("PROT P",NULL,0,0,ftp_vbm) == REPLY_COMPLETE) {
- if (!quiet)
- printf("FTP Data channel is Private (encrypted)\n");
- ftp_dpl = FPL_PRV;
- } else
- printf("?Unable to enable encryption on data channel\n");
- } else {
- ftp_cpl = FPL_SAF;
- }
- }
- if (!connected)
- goto fail;
- }
-#endif /* FTP_SECURITY */
- if (ftp_log) /* ^^^ */
- ftp_login(remote);
-
- if (!connected)
- goto fail;
-
- ftp_xfermode = xfermode;
-
-#ifdef CKLOGDIAL
- dologftp();
-#endif /* CKLOGDIAL */
-#ifdef OS2
- DialerSend(OPT_KERMIT_CONNECT, 0);
-#endif /* OS2 */
- passivemode = ftp_psv;
- sendport = ftp_spc;
- mdtmok = 1;
- sizeok = 1;
- stouarg = 1;
- typesent = 0;
-
- if (ucbuf == NULL) {
- actualbuf = DEFAULT_PBSZ;
- while (actualbuf && (ucbuf = (CHAR *)malloc(actualbuf)) == NULL)
- actualbuf >>= 2;
- }
- if (!maxbuf)
- ucbufsiz = actualbuf - FUDGE_FACTOR;
- debug(F101,"ftpopen ucbufsiz","",ucbufsiz);
- return(1);
- }
- fail:
- printf("?Can't FTP connect to %s:%s\n",remote,service);
- ftpcode = -1;
- return(0);
-}
-
-#ifdef CK_SSL
-int
-ssl_auth() {
- int i;
- char* p;
-
- if (ssl_debug_flag) {
- fprintf(stderr,"SSL DEBUG ACTIVE\n");
- fflush(stderr);
- /* for the moment I want the output on screen */
- }
- if (ssl_ftp_data_con != NULL) {
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_con = NULL;
- }
- if (ssl_ftp_con != NULL) {
- SSL_free(ssl_ftp_con);
- ssl_ftp_con=NULL;
- }
- if (ssl_ftp_ctx != NULL) {
- SSL_CTX_free(ssl_ftp_ctx);
- ssl_ftp_ctx = NULL;
- }
-
- /* The SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
- * was added to OpenSSL 0.9.6e and 0.9.7. It does not exist in previous
- * versions
- */
-#ifndef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
-#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0L
-#endif
- if (auth_type && !strcmp(auth_type,"TLS")) {
- ssl_ftp_ctx=SSL_CTX_new(SSLv3_client_method());
- if (!ssl_ftp_ctx)
- return(0);
- SSL_CTX_set_options(ssl_ftp_ctx,
- SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA
- );
- } else {
- ssl_ftp_ctx = SSL_CTX_new(ftp_bug_use_ssl_v2 ? SSLv23_client_method() :
- SSLv3_client_method());
- if (!ssl_ftp_ctx)
- return(0);
- SSL_CTX_set_options(ssl_ftp_ctx,
- (ftp_bug_use_ssl_v2 ? 0 : SSL_OP_NO_SSLv2)|
- SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA
- );
- }
- SSL_CTX_set_default_passwd_cb(ssl_ftp_ctx,
- (pem_password_cb *)ssl_passwd_callback);
- SSL_CTX_set_info_callback(ssl_ftp_ctx,ssl_client_info_callback);
- SSL_CTX_set_session_cache_mode(ssl_ftp_ctx,SSL_SESS_CACHE_CLIENT);
-
-#ifdef OS2
-#ifdef NT
- /* The defaults in the SSL crypto library are not appropriate for OS/2 */
- {
- char path[CKMAXPATH];
- extern char exedir[];
-
- ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,
- (char *)GetAppData(1),"kermit 95/certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,
- (char *)GetAppData(0),"kermit 95/certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,(char *)GetAppData(1),
- "kermit 95/ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,(char *)GetAppData(0),
- "kermit 95/ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
- }
-#else /* NT */
- /* The defaults in the SSL crypto library are not appropriate for OS/2 */
- {
-
- char path[CKMAXPATH];
- extern char exedir[];
-
- ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
- }
-#endif /* NT */
-#else /* OS2 */
- SSL_CTX_set_default_verify_paths(ssl_ftp_ctx);
-#endif /* OS2 */
-
- if (ssl_verify_file &&
- SSL_CTX_load_verify_locations(ssl_ftp_ctx,ssl_verify_file,NULL) == 0) {
- debug(F110,
- "ftp ssl auth unable to load ssl_verify_file",
- ssl_verify_file,
- 0
- );
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",ssl_verify_file);
- }
- if (ssl_verify_dir &&
- SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,ssl_verify_dir) == 0) {
- debug(F110,
- "ftp ssl auth unable to load ssl_verify_dir",
- ssl_verify_dir,
- 0
- );
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",ssl_verify_dir);
- }
-
- /* set up the new CRL Store */
- crl_store = (X509_STORE *)X509_STORE_new();
- if (crl_store) {
-#ifdef OS2
- char path[CKMAXPATH];
- extern char exedir[];
-
- ckmakmsg(path,CKMAXPATH,exedir,"crls",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
- debug(F110,"ftp ssl auth unable to load dir",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",path);
- }
-#ifdef NT
- ckmakmsg(path,CKMAXPATH,
- (char *)GetAppData(1),"kermit 95/crls",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
- debug(F110,"ftp ssl auth unable to load dir",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,
- (char *)GetAppData(0),"kermit 95/crls",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
- debug(F110,"ftp ssl auth unable to load dir",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",path);
- }
-#endif /* NT */
-
- ckmakmsg(path,CKMAXPATH,exedir,"ca_crls.pem",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
- debug(F110,"ftp ssl auth unable to load file",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",path);
- }
-#ifdef NT
- ckmakmsg(path,CKMAXPATH,(char *)GetAppData(1),
- "kermit 95/ca_crls.pem",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
- debug(F110,"ftp ssl auth unable to load file",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,(char *)GetAppData(0),
- "kermit 95/ca_crls.pem",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
- debug(F110,"ftp ssl auth unable to load file",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",path);
- }
-#endif /* NT */
-#endif /* OS2 */
-
- if (ssl_crl_file || ssl_crl_dir) {
- if (ssl_crl_file &&
- X509_STORE_load_locations(crl_store,ssl_crl_file,NULL) == 0) {
- debug(F110,
- "ftp ssl auth unable to load ssl_crl_file",
- ssl_crl_file,
- 0
- );
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",ssl_crl_file);
- }
- if (ssl_crl_dir &&
- X509_STORE_load_locations(crl_store,NULL,ssl_crl_dir) == 0) {
- debug(F110,
- "ftp ssl auth unable to load ssl_crl_dir",
- ssl_crl_dir,
- 0
- );
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",ssl_crl_dir);
- }
- } else {
- X509_STORE_set_default_paths(crl_store);
- }
- }
- SSL_CTX_set_verify(ssl_ftp_ctx,ssl_verify_flag,
- ssl_client_verify_callback);
- ssl_verify_depth = -1;
- ssl_ftp_con=(SSL *)SSL_new(ssl_ftp_ctx);
- tls_load_certs(ssl_ftp_ctx,ssl_ftp_con,0);
- SSL_set_fd(ssl_ftp_con,csocket);
- SSL_set_verify(ssl_ftp_con,ssl_verify_flag,NULL);
- if (ssl_cipher_list) {
- SSL_set_cipher_list(ssl_ftp_con,ssl_cipher_list);
- } else {
- char * p;
- if (p = getenv("SSL_CIPHER")) {
- SSL_set_cipher_list(ssl_ftp_con,p);
- } else {
- SSL_set_cipher_list(ssl_ftp_con,DEFAULT_CIPHER_LIST);
- }
- }
- if (ssl_debug_flag) {
- fprintf(stderr,"=>START SSL/TLS connect on COMMAND\n");
- fflush(stderr);
- }
- if (SSL_connect(ssl_ftp_con) <= 0) {
- static char errbuf[1024];
- ckmakmsg(errbuf,1024,"ftp: SSL/TLS connect COMMAND error: ",
- ERR_error_string(ERR_get_error(),NULL),NULL,NULL);
- fprintf(stderr,"%s\n", errbuf);
- fflush(stderr);
- ssl_ftp_active_flag=0;
- SSL_free(ssl_ftp_con);
- ssl_ftp_con = NULL;
- } else {
- ssl_ftp_active_flag = 1;
-
- if (!ssl_certsok_flag && !tls_is_krb5(1)) {
- char *subject = ssl_get_subject_name(ssl_ftp_con);
-
- if (!subject) {
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- debug(F110,"ssl_auth","[SSL - FAILED]",0);
- return(ssl_ftp_active_flag = 0);
- } else {
- if (uq_ok("Warning: Server didn't provide a certificate\n",
- "Continue? (Y/N)",3,NULL,0) <= 0) {
- debug(F110, "ssl_auth","[SSL - FAILED]",0);
- return(ssl_ftp_active_flag = 0);
- }
- }
- } else if (ssl_check_server_name(ssl_ftp_con, ftp_user_host)) {
- debug(F110,"ssl_auth","[SSL - FAILED]",0);
- return(ssl_ftp_active_flag = 0);
- }
- }
- debug(F110,"ssl_auth","[SSL - OK]",0);
- ssl_display_connect_details(ssl_ftp_con,0,ssl_verbose_flag);
- }
- if (ssl_debug_flag) {
- fprintf(stderr,"=>DONE SSL/TLS connect on COMMAND\n");
- fflush(stderr);
- }
- return(ssl_ftp_active_flag);
-}
-#endif /* CK_SSL */
-
-static sigtype
-cmdcancel(sig) int sig; {
-#ifdef OS2
- /* In Unix we "chain" to trap(), which prints this */
- printf("^C...\n");
-#endif /* OS2 */
- debug(F100,"ftp cmdcancel caught SIGINT ","",0);
- fflush(stdout);
- secure_getc(0,1); /* Initialize net input buffers */
- cancelfile++;
- cancelgroup++;
- mlsreset();
-#ifndef OS2
-#ifdef FTP_PROXY
- if (ptflag) /* proxy... */
- longjmp(ptcancel,1);
-#endif /* FTP_PROXY */
- debug(F100,"ftp cmdcancel chain to trap()...","",0);
- trap(SIGINT);
- /* NOTREACHED */
- debug(F100,"ftp cmdcancel return from trap()...","",0);
-#else
- debug(F100,"ftp cmdcancel PostCtrlCSem()...","",0);
- PostCtrlCSem();
-#endif /* OS2 */
-}
-
-static int
-#ifdef CK_ANSIC
-scommand(char * s) /* Was secure_command() */
-#else
-scommand(s) char * s;
-#endif /* CK_ANSIC */
-{
- int length = 0, len2;
- char in[FTP_BUFSIZ], out[FTP_BUFSIZ];
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- int error, rc;
- length = strlen(s) + 2;
- length = ckmakmsg(out,FTP_BUFSIZ,s,"\r\n",NULL,NULL);
- rc = SSL_write(ssl_ftp_con,out,length);
- error = SSL_get_error(ssl_ftp_con,rc);
- switch (error) {
- case SSL_ERROR_NONE:
- return(1);
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
-#ifdef NT
- {
- int gle = GetLastError();
- }
-#endif /* NT */
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- lostpeer();
- }
- return(0);
- }
-#endif /* CK_SSL */
-
- if (auth_type && ftp_cpl != FPL_CLR) {
-#ifdef FTP_SRP
- if (ck_srp_is_installed() && (strcmp(auth_type,"SRP") == 0))
- if ((length = srp_encode(ftp_cpl == FPL_PRV,
- (CHAR *)s,
- (CHAR *)out,
- strlen(s))) < 0) {
- fprintf(stderr, "SRP failed to encode message\n");
- return(0);
- }
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- if (ck_krb4_is_installed() &&
- (strcmp(auth_type, "KERBEROS_V4") == 0)) {
- if (ftp_cpl == FPL_PRV) {
- length =
- krb_mk_priv((CHAR *)s, (CHAR *)out,
- strlen(s), ftp_sched,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &myctladdr, &hisctladdr);
- } else {
- length =
- krb_mk_safe((CHAR *)s,
- (CHAR *)out,
- strlen(s),
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &myctladdr, &hisctladdr);
- }
- if (length == -1) {
- fprintf(stderr, "krb_mk_%s failed for KERBEROS_V4\n",
- ftp_cpl == FPL_PRV ? "priv" : "safe");
- return(0);
- }
- }
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- /* Scommand (based on level) */
- if (ck_gssapi_is_installed() && (strcmp(auth_type, "GSSAPI") == 0)) {
- gss_buffer_desc in_buf, out_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
- in_buf.value = s;
- in_buf.length = strlen(s) + 1;
- maj_stat = gss_seal(&min_stat, gcontext,
- (ftp_cpl==FPL_PRV), /* private */
- GSS_C_QOP_DEFAULT,
- &in_buf, &conf_state,
- &out_buf);
- if (maj_stat != GSS_S_COMPLETE) { /* Generally need to deal */
- user_gss_error(maj_stat, min_stat,
- (ftp_cpl==FPL_PRV)?
- "gss_seal ENC didn't complete":
- "gss_seal MIC didn't complete");
- } else if ((ftp_cpl == FPL_PRV) && !conf_state) {
- fprintf(stderr, "GSSAPI didn't encrypt message");
- } else {
- if (ftp_deb)
- fprintf(stderr, "sealed (%s) %d bytes\n",
- ftp_cpl==FPL_PRV?"ENC":"MIC",
- out_buf.length);
- memcpy(out, out_buf.value,
- length=out_buf.length);
- gss_release_buffer(&min_stat, &out_buf);
- }
- }
-#endif /* FTP_GSSAPI */
- /* Other auth types go here ... */
-
- len2 = FTP_BUFSIZ;
- if ((kerror = radix_encode((CHAR *)out, (CHAR *)in,
- length, &len2, RADIX_ENCODE))
- ) {
- fprintf(stderr,"Couldn't base 64 encode command (%s)\n",
- radix_error(kerror));
- return(0);
- }
- if (ftp_deb)
- fprintf(stderr, "scommand(%s)\nencoding %d bytes\n", s, length);
- len2 = ckmakmsg(out,
- FTP_BUFSIZ,
- ftp_cpl == FPL_PRV ? "ENC " : "MIC ",
- in,
- "\r\n",
- NULL
- );
- send(csocket,(SENDARG2TYPE)out,len2,0);
- } else {
- char out[FTP_BUFSIZ];
- int len = ckmakmsg(out,FTP_BUFSIZ,s,"\r\n",NULL,NULL);
- send(csocket,(SENDARG2TYPE)out,len,0);
- }
- return(1);
-}
-
-static int
-mygetc() {
- static char inbuf[4096];
- static int bp = 0, ep = 0;
- int rc;
-
- if (bp == ep) {
- bp = ep = 0;
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- int error;
- rc = SSL_read(ssl_ftp_con,inbuf,4096);
- error = SSL_get_error(ssl_ftp_con,rc);
- switch (error) {
- case SSL_ERROR_NONE:
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(0);
- case SSL_ERROR_SYSCALL:
- if (rc == 0) { /* EOF */
- break;
- } else {
-#ifdef NT
- int gle = GetLastError();
-#endif /* NT */
- break;
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- break;
- }
- } else
-#endif /* CK_SSL */
- rc = recv(csocket,(char *)inbuf,4096,0);
- if (rc <= 0)
- return(EOF);
- ep = rc;
- }
- return(inbuf[bp++]);
-}
-
-/* x l a t e c -- Translate a character */
-/*
- Call with:
- fc = Function code: 0 = translate, 1 = initialize.
- c = Character (as int).
- incs = Index of charset to translate from.
- outcs = Index of charset to translate to.
-
- Returns:
- 0: OK
- -1: Error
-*/
-static int
-xlatec(fc,c,incs,outcs) int fc, c, incs, outcs; {
-#ifdef NOCSETS
- return(c);
-#else
- static char buf[128];
- static int cx;
- int c0, c1;
-
- if (fc == 1) { /* Initialize */
- cx = 0; /* Catch-up buffer write index */
- xgnbp = buf; /* Catch-up buffer read pointer */
- buf[0] = NUL; /* Buffer is empty */
- return(0);
- }
- if (cx >= 127) { /* Catch-up buffer full */
- debug(F100,"xlatec overflow","",0); /* (shouldn't happen) */
- printf("?Translation buffer overflow\n");
- return(-1);
- }
- /* Add char to buffer. */
- /* The buffer won't grow unless incs is a multibyte set, e.g. UTF-8. */
-
- debug(F000,"xlatec buf",ckitoa(cx),c);
- buf[cx++] = c;
- buf[cx] = NUL;
-
- while ((c0 = xgnbyte(FC_UCS2,incs,strgetc)) > -1) {
- if (xpnbyte(c0,TC_UCS2,outcs,NULL) < 0) /* (NULL was xprintc) */
- return(-1);
- }
- /* If we're caught up, reinitialize the buffer */
- return((cx == (xgnbp - buf)) ? xlatec(1,0,0,0) : 0);
-#endif /* NOCSETS */
-}
-
-
-/* p a r s e f e a t */
-
-/* Note: for convenience we align keyword values with table indices */
-/* If you need to insert a new keyword, adjust the SFT_xxx definitions */
-
-static struct keytab feattab[] = {
- { "$$$$", 0, 0 }, /* Dummy for sfttab[0] */
- { "AUTH", SFT_AUTH, 0 },
- { "LANG", SFT_LANG, 0 },
- { "MDTM", SFT_MDTM, 0 },
- { "MLST", SFT_MLST, 0 },
- { "PBSZ", SFT_PBSZ, 0 },
- { "PROT", SFT_PROT, 0 },
- { "REST", SFT_REST, 0 },
- { "SIZE", SFT_SIZE, 0 },
- { "TVFS", SFT_TVFS, 0 },
- { "UTF8", SFT_UTF8, 0 }
-};
-static int nfeattab = (sizeof(feattab) / sizeof(struct keytab));
-
-#define FACT_CSET 1
-#define FACT_CREA 2
-#define FACT_LANG 3
-#define FACT_MTYP 4
-#define FACT_MDTM 5
-#define FACT_PERM 6
-#define FACT_SIZE 7
-#define FACT_TYPE 8
-#define FACT_UNIQ 9
-
-static struct keytab facttab[] = {
- { "CHARSET", FACT_CSET, 0 },
- { "CREATE", FACT_CREA, 0 },
- { "LANG", FACT_LANG, 0 },
- { "MEDIA-TYPE", FACT_MTYP, 0 },
- { "MODIFY", FACT_MDTM, 0 },
- { "PERM", FACT_PERM, 0 },
- { "SIZE", FACT_SIZE, 0 },
- { "TYPE", FACT_TYPE, 0 },
- { "UNIQUE", FACT_UNIQ, 0 }
-};
-static int nfacttab = (sizeof(facttab) / sizeof(struct keytab));
-
-static struct keytab ftyptab[] = {
- { "CDIR", FTYP_CDIR, 0 },
- { "DIR", FTYP_DIR, 0 },
- { "FILE", FTYP_FILE, 0 },
- { "PDIR", FTYP_PDIR, 0 }
-};
-static int nftyptab = (sizeof(ftyptab) / sizeof(struct keytab));
-
-static VOID
-parsefeat(s) char * s; { /* Parse a FEATURE response */
- char kwbuf[8];
- int i, x;
- if (!s) return;
- if (!*s) return;
- while (*s < '!')
- s++;
- for (i = 0; i < 4; i++) {
- if (s[i] < '!')
- break;
- kwbuf[i] = s[i];
- }
- if (s[i] && s[i] != SP && s[i] != CR && s[i] != LF)
- return;
- kwbuf[i] = NUL;
- /* xlookup requires a full (but case independent) match */
- i = xlookup(feattab,kwbuf,nfeattab,&x);
- debug(F111,"ftp parsefeat",s,i);
- if (i < 0 || i > 15)
- return;
-
- switch (i) {
- case SFT_MDTM: /* Controlled by ENABLE/DISABLE */
- sfttab[i] = mdtmok;
- if (mdtmok) sfttab[0]++;
- break;
- case SFT_MLST: /* ditto */
- sfttab[i] = mlstok;
- if (mlstok) sfttab[0]++;
- break;
- case SFT_SIZE: /* ditto */
- sfttab[i] = sizeok;
- if (sizeok) sfttab[0]++;
- break;
- case SFT_AUTH: /* ditto */
- sfttab[i] = ftp_aut;
- if (ftp_aut) sfttab[0]++;
- break;
- default: /* Others */
- sfttab[0]++;
- sfttab[i]++;
- }
-}
-
-static char *
-parsefacts(s) char * s; { /* Parse MLS[DT] File Facts */
- char * p;
- int i, j, x;
- if (!s) return(NULL);
- if (!*s) return(NULL);
-
- /* Maybe we should make a copy of s so we can poke it... */
-
- while ((p = ckstrchr(s,'='))) {
- *p = NUL; /* s points to fact */
- i = xlookup(facttab,s,nfacttab,&x);
- debug(F111,"ftp parsefact fact",s,i);
- *p = '=';
- s = p+1; /* Now s points to arg */
- p = ckstrchr(s,';');
- if (!p)
- p = ckstrchr(s,SP);
- if (!p) {
- debug(F110,"ftp parsefact end-of-val search fail",s,0);
- break;
- }
- *p = NUL;
- debug(F110,"ftp parsefact valu",s,0);
- switch (i) {
- case FACT_CSET: /* Ignore these for now */
- case FACT_CREA:
- case FACT_LANG:
- case FACT_PERM:
- case FACT_MTYP:
- case FACT_UNIQ:
- break;
- case FACT_MDTM: /* Modtime */
- makestr(&havemdtm,s);
- debug(F110,"ftp parsefact mdtm",havemdtm,0);
- break;
- case FACT_SIZE: /* Size */
- havesize = ckatofs(s);
- debug(F101,"ftp parsefact size","",havesize);
- break;
- case FACT_TYPE: /* Type */
- j = xlookup(ftyptab,s,nftyptab,NULL);
- debug(F111,"ftp parsefact type",s,j);
- havetype = (j < 1) ? 0 : j;
- break;
- }
- *p = ';';
- s = p+1; /* s points next fact or name */
- }
- while (*s == SP) /* Skip past spaces. */
- s++;
- if (!*s) /* Make sure we still have a name */
- s = NULL;
- debug(F110,"ftp parsefact name",s,0);
- return(s);
-}
-
-/* g e t r e p l y -- (to an FTP command sent to server) */
-
-/* vbm = 1 (verbose); 0 (quiet except for error messages); 9 (super quiet) */
-
-static int
-getreply(expecteof,lcs,rcs,vbm,fc) int expecteof, lcs, rcs, vbm, fc; {
- /* lcs, rcs, vbm parameters as in ftpcmd() */
- register int i, c, n;
- register int dig;
- register char *cp;
- int xlate = 0;
- int count = 0;
- int auth = 0;
- int originalcode = 0, continuation = 0;
- sig_t oldintr;
- int pflag = 0;
- char *pt = pasv;
- char ibuf[FTP_BUFSIZ], obuf[FTP_BUFSIZ]; /* (these are pretty big...) */
- int safe = 0;
- int xquiet = 0;
-
- auth = (fc == GRF_AUTH);
-
-#ifndef NOCSETS
- debug(F101,"ftp getreply lcs","",lcs);
- debug(F101,"ftp getreply rcs","",rcs);
- if (lcs > -1 && rcs > -1 && lcs != rcs) {
- xlate = 1;
- initxlate(rcs,lcs);
- xlatec(1,0,rcs,lcs);
- }
-#endif /* NOCSETS */
- debug(F101,"ftp getreply fc","",fc);
-
- if (quiet)
- xquiet = 1;
- if (vbm == 9) {
- xquiet = 1;
- vbm = 0;
- }
- if (ftp_deb) /* DEBUG */
- vbm = 1;
- else if (quiet || dpyactive) /* QUIET or File Transfer Active */
- vbm = 0;
- else if (vbm < 0) /* VERBOSE */
- vbm = ftp_vbm;
-
- ibuf[0] = '\0';
- if (reply_parse)
- reply_ptr = reply_buf;
- havesigint = 0;
- oldintr = signal(SIGINT, cmdcancel);
- for (count = 0;; count++) {
- obuf[0] = '\0';
- dig = n = ftpcode = i = 0;
- cp = ftp_reply_str;
- while ((c = ibuf[0] ? ibuf[i++] : mygetc()) != '\n') {
- if (c == IAC) { /* Handle telnet commands */
- switch (c = mygetc()) {
- case WILL:
- case WONT:
- c = mygetc();
- obuf[0] = IAC;
- obuf[1] = DONT;
- obuf[2] = c;
- obuf[3] = NUL;
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- int error, rc;
- rc = SSL_write(ssl_ftp_con,obuf,3);
- error = SSL_get_error(ssl_ftp_con,rc);
- switch (error) {
- case SSL_ERROR_NONE:
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(0);
- case SSL_ERROR_SYSCALL:
- if (rc == 0) { /* EOF */
- break;
- } else {
-#ifdef NT
- int gle = GetLastError();
-#endif /* NT */
- break;
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- break;
- }
- } else
-#endif /* CK_SSL */
- send(csocket,(SENDARG2TYPE)obuf,3,0);
- break;
- case DO:
- case DONT:
- c = mygetc();
- obuf[0] = IAC;
- obuf[1] = WONT;
- obuf[2] = c;
- obuf[3] = NUL;
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- int error, rc;
- rc = SSL_write(ssl_ftp_con,obuf,3);
- error = SSL_get_error(ssl_ftp_con,rc);
- switch (error) {
- case SSL_ERROR_NONE:
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- signal(SIGINT,oldintr);
- return(0);
- case SSL_ERROR_SYSCALL:
- if (rc == 0) { /* EOF */
- break;
- } else {
-#ifdef NT
- int gle = GetLastError();
-#endif /* NT */
- break;
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- break;
- }
- } else
-#endif /* CK_SSL */
- send(csocket,(SENDARG2TYPE)obuf,3,0);
- break;
- default:
- break;
- }
- continue;
- }
- dig++;
- if (c == EOF) {
- if (expecteof) {
- signal(SIGINT,oldintr);
- ftpcode = 221;
- debug(F101,"ftp getreply EOF","",ftpcode);
- return(0);
- }
- lostpeer();
- if (!xquiet) {
- if (ftp_deb)
- printf("421 ");
- printf(
- "Service not available, connection closed by server\n");
- fflush(stdout);
- }
- signal(SIGINT,oldintr);
- ftpcode = 421;
- debug(F101,"ftp getreply EOF","",ftpcode);
- return(4);
- }
- if (n == 0) { /* First digit */
- n = c; /* Save it */
- }
- if (auth_type &&
-#ifdef CK_SSL
- !ssl_ftp_active_flag &&
-#endif /* CK_SSL */
- !ibuf[0] && (n == '6' || continuation)) {
- if (c != '\r' && dig > 4)
- obuf[i++] = c;
- } else {
- if (auth_type &&
-#ifdef CK_SSL
- !ssl_ftp_active_flag &&
-#endif /* CK_SSL */
- !ibuf[0] && dig == 1 && vbm)
- printf("Unauthenticated reply received from server:\n");
- if (reply_parse) {
- *reply_ptr++ = c;
- *reply_ptr = NUL;
- }
- if ((!dpyactive || ftp_deb) && /* Don't mess up xfer display */
- ftp_cmdlin < 2) {
- if ((c != '\r') &&
- (ftp_deb || ((vbm || (!auth && n == '5')) &&
- (dig > 4 || ( dig <= 4 && !isdigit(c) && ftpcode == 0
- )))))
- {
-#ifdef FTP_PROXY
- if (ftp_prx && (dig == 1 || (dig == 5 && vbm == 0)))
- printf("%s:",ftp_host);
-#endif /* FTP_PROXY */
-
- if (!xquiet) {
-#ifdef NOCSETS
- printf("%c",c);
-#else
- if (xlate) {
- xlatec(0,c,rcs,lcs);
- } else {
- printf("%c",c);
- }
-#endif /* NOCSETS */
- }
- }
- }
- }
- if (auth_type &&
-#ifdef CK_SSL
- !ssl_ftp_active_flag &&
-#endif /* CK_SSL */
- !ibuf[0] && n != '6')
- continue;
- if (dig < 4 && isdigit(c))
- ftpcode = ftpcode * 10 + (c - '0');
- if (!pflag && ftpcode == 227)
- pflag = 1;
- if (dig > 4 && pflag == 1 && isdigit(c))
- pflag = 2;
- if (pflag == 2) {
- if (c != '\r' && c != ')')
- *pt++ = c;
- else {
- *pt = '\0';
- pflag = 3;
- }
- }
- if (dig == 4 && c == '-' && n != '6') {
- if (continuation)
- ftpcode = 0;
- continuation++;
- }
- if (cp < &ftp_reply_str[FTP_BUFSIZ - 1]) {
- *cp++ = c;
- *cp = NUL;
- }
- }
- if (deblog ||
-#ifdef COMMENT
-/*
- Sometimes we need to print the server reply. printlines is nonzero for any
- command where the results are sent back on the control connection rather
- than the data connection, e.g. STAT. In the TOPS-20 case, each file line
- has ftpcode 213. But if you do this with a UNIX server, it sends "213-Start
- STAT", <line with ftpcode == 0>, "213-End" or somesuch. So when printlines
- is nonzero, we want the 213 lines from TOPS-20 and we DON'T want the 213
- lines from UNIX. Further experimentation needed with other servers. Of
- course RFC959 is mute as to the format of the server reply.
-
- 'printlines' is also true for PWD and BYE.
-*/
- (printlines && ((ftpcode == 0) || (servertype == SYS_TOPS20)))
-#else
-/* No, we can't be that clever -- it breaks other things like RPWD... */
- (printlines &&
- (ftpcode != 631 && ftpcode != 632 && ftpcode != 633))
-#endif /* COMMENT */
- ) {
- char * q = cp;
- char *r = ftp_reply_str;
- *q-- = NUL; /* NUL-terminate */
- while (*q < '!' && q > r) /* Strip CR, etc */
- *q-- = NUL;
- if (!ftp_deb && printlines) { /* If printing */
- if (ftpcode != 0) /* strip ftpcode if any */
- r += 4;
-#ifdef NOCSETS
- printf("%s\n",r); /* and print */
-#else
- if (!xlate) {
- printf("%s\n",r);
- } else { /* Translating */
- xgnbp = r; /* Set up strgetc() */
- while ((c0 = xgnbyte(FC_UCS2,rcs,strgetc)) > -1) {
- if (xpnbyte(c0,TC_UCS2,lcs,NULL) < 0) { /* (xprintc) */
- signal(SIGINT,oldintr);
- return(-1);
- }
- }
- printf("\n");
- }
-#endif /* NOCSETS */
- }
- }
- debug(F110,"FTP RCVD ",ftp_reply_str,0);
-
- if (fc == GRF_FEAT) { /* Parsing FEAT command response? */
- if (count == 0 && n == '2') {
- int i; /* (Re)-init server FEATure table */
- debug(F100,"ftp getreply clearing feature table","",0);
- for (i = 0; i < 16; i++)
- sfttab[i] = 0;
- } else {
- parsefeat((char *)ftp_reply_str);
- }
- }
- if (auth_type &&
-#ifdef CK_SSL
- !ssl_ftp_active_flag &&
-#endif /* CK_SSL */
- !ibuf[0] && n != '6') {
- signal(SIGINT,oldintr);
- return(getreply(expecteof,lcs,rcs,vbm,auth));
- }
- ibuf[0] = obuf[i] = '\0';
- if (ftpcode && n == '6')
- if (ftpcode != 631 && ftpcode != 632 && ftpcode != 633) {
- printf("Unknown reply: %d %s\n", ftpcode, obuf);
- n = '5';
- } else safe = (ftpcode == 631);
- if (obuf[0] /* if there is a string to decode */
-#ifdef CK_SSL
- && !ssl_ftp_active_flag /* and not SSL/TLS */
-#endif /* CK_SSL */
- ) {
- if (!auth_type) {
- printf("Cannot decode reply:\n%d %s\n", ftpcode, obuf);
- n = '5';
- }
-#ifndef CK_ENCRYPTION
- else if (ftpcode == 632) {
- printf("Cannot decrypt %d reply: %s\n", ftpcode, obuf);
- n = '5';
- }
-#endif /* CK_ENCRYPTION */
-#ifdef NOCONFIDENTIAL
- else if (ftpcode == 633) {
- printf("Cannot decrypt %d reply: %s\n", ftpcode, obuf);
- n = '5';
- }
-#endif /* NOCONFIDENTIAL */
- else {
- int len = FTP_BUFSIZ;
- if ((kerror = radix_encode((CHAR *)obuf,
- (CHAR *)ibuf,
- 0,
- &len,
- RADIX_DECODE))
- ) {
- printf("Can't decode base 64 reply %d (%s)\n\"%s\"\n",
- ftpcode, radix_error(kerror), obuf);
- n = '5';
- }
-#ifdef FTP_SRP
- else if (strcmp(auth_type, "SRP") == 0) {
- int outlen;
- outlen = srp_decode(!safe, (CHAR *)ibuf,
- (CHAR *) ibuf, len);
- if (outlen < 0) {
- printf("Warning: %d reply %s!\n",
- ftpcode, safe ? "modified" : "garbled");
- n = '5';
- } else {
- ckstrncpy(&ibuf[outlen], "\r\n",FTP_BUFSIZ-outlen);
- if (ftp_deb)
- printf("%c:", safe ? 'S' : 'P');
- continue;
- }
- }
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- else if (strcmp(auth_type, "KERBEROS_V4") == 0) {
- if (safe) {
- kerror = krb_rd_safe((CHAR *)ibuf, len,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &hisctladdr,
- &myctladdr,
- &ftp_msg_data
- );
- } else {
- kerror = krb_rd_priv((CHAR *)ibuf, len,
- ftp_sched,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &hisctladdr,
- &myctladdr,
- &ftp_msg_data
- );
- }
- if (kerror != KSUCCESS) {
- printf("%d reply %s! (krb_rd_%s: %s)\n", ftpcode,
- safe ? "modified" : "garbled",
- safe ? "safe" : "priv",
- krb_get_err_text(kerror));
- n = '5';
- } else if (ftp_msg_data.app_length >= FTP_BUFSIZ - 3) {
- kerror = KFAILURE;
- n = '5';
- printf("reply data too large for buffer\n");
- } else {
- if (ftp_deb)
- printf("%c:", safe ? 'S' : 'P');
- memcpy(ibuf,ftp_msg_data.app_data,
- ftp_msg_data.app_length);
- ckstrncpy(&ibuf[ftp_msg_data.app_length], "\r\n",
- FTP_BUFSIZ - ftp_msg_data.app_length);
- continue;
- }
- }
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- else if (strcmp(auth_type, "GSSAPI") == 0) {
- gss_buffer_desc xmit_buf, msg_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
- xmit_buf.value = ibuf;
- xmit_buf.length = len;
- /* decrypt/verify the message */
- conf_state = safe;
- maj_stat = gss_unseal(&min_stat, gcontext,
- &xmit_buf, &msg_buf,
- &conf_state, NULL);
- if (maj_stat != GSS_S_COMPLETE) {
- user_gss_error(maj_stat, min_stat,
- "failed unsealing reply");
- n = '5';
- } else {
- memcpy(ibuf, msg_buf.value, msg_buf.length);
- ckstrncpy(&ibuf[msg_buf.length], "\r\n",
- FTP_BUFSIZ-msg_buf.length);
- gss_release_buffer(&min_stat,&msg_buf);
- if (ftp_deb)
- printf("%c:", safe ? 'S' : 'P');
- continue;
- }
- }
-#endif /* FTP_GSSAPI */
- /* Other auth types go here... */
- }
- } else if ((!dpyactive || ftp_deb) && ftp_cmdlin < 2 &&
- !xquiet && (vbm || (!auth && (n == '4' || n == '5')))) {
-#ifdef NOCSETS
- printf("%c",c);
-#else
- if (xlate) {
- xlatec(0,c,rcs,lcs);
- } else {
- printf("%c",c);
- }
-#endif /* NOCSETS */
- fflush (stdout);
- }
- if (continuation && ftpcode != originalcode) {
- if (originalcode == 0)
- originalcode = ftpcode;
- continue;
- }
- *cp = '\0';
- if (n != '1')
- cpend = 0;
- signal(SIGINT,oldintr);
- if (ftpcode == 421 || originalcode == 421) {
- lostpeer();
- if (!xquiet && !ftp_deb)
- printf("%s\n",reply_buf);
- }
- if ((cancelfile != 0) &&
-#ifndef ULTRIX3
- /* Ultrix 3.0 cc objects violently to this clause */
- (oldintr != cmdcancel) &&
-#endif /* ULTRIX3 */
- (oldintr != SIG_IGN)) {
- if (oldintr)
- (*oldintr)(SIGINT);
- }
- if (reply_parse) {
- *reply_ptr = '\0';
- if ((reply_ptr = ckstrstr(reply_buf, reply_parse))) {
- reply_parse = reply_ptr + strlen(reply_parse);
- if ((reply_ptr = ckstrpbrk(reply_parse, " \r")))
- *reply_ptr = '\0';
- } else
- reply_parse = reply_ptr;
- }
- while (*cp < '!' && cp > ftp_reply_str) /* Remove trailing junk */
- *cp-- = NUL;
- debug(F111,"ftp getreply",ftp_reply_str,n - '0');
- return(n - '0');
- } /* for (;;) */
-}
-
-#ifdef BSDSELECT
-static int
-#ifdef CK_ANSIC
-empty(fd_set * mask, int sec)
-#else
-empty(mask, sec) fd_set * mask; int sec;
-#endif /* CK_ANSIC */
-{
- struct timeval t;
- t.tv_sec = (long) sec;
- t.tv_usec = 0L;
- debug(F100,"ftp empty calling select...","",0);
-#ifdef INTSELECT
- x = select(32, (int *)mask, NULL, NULL, &t);
-#else
- x = select(32, mask, (fd_set *) 0, (fd_set *) 0, &t);
-#endif /* INTSELECT */
- debug(F101,"ftp empty select","",x);
- return(x);
-}
-#else /* BSDSELECT */
-#ifdef IBMSELECT
-static int
-empty(mask, cnt, sec) int * mask, sec;
- int cnt;
-{
- return(select(mask,cnt,0,0,sec*1000));
-}
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
-
-static sigtype
-cancelsend(sig) int sig; {
- havesigint++;
- cancelgroup++;
- cancelfile = 0;
- printf(" Canceled...\n");
- secure_getc(0,1); /* Initialize net input buffers */
- debug(F100,"ftp cancelsend caught SIGINT ","",0);
- fflush(stdout);
-#ifndef OS2
- longjmp(sendcancel, 1);
-#else
- PostCtrlCSem();
-#endif /* OS2 */
-}
-
-static VOID
-#ifdef CK_ANSIC
-secure_error(char *fmt, ...)
-#else
-/* VARARGS1 */
-secure_error(fmt, p1, p2, p3, p4, p5)
- char *fmt; int p1, p2, p3, p4, p5;
-#endif /* CK_ANSIC */
-{
-#ifdef CK_ANSIC
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-#else
- fprintf(stderr, fmt, p1, p2, p3, p4, p5);
-#endif
- fprintf(stderr, "\n");
-}
-
-/*
- * Internal form of settype; changes current type in use with server
- * without changing our notion of the type for data transfers.
- * Used to change to and from ascii for listings.
- */
-static VOID
-changetype(newtype, show) int newtype, show; {
- int rc;
- char * s;
-
- if ((newtype == curtype) && typesent++)
- return;
- switch (newtype) {
- case FTT_ASC:
- s = "A";
- break;
- case FTT_BIN:
- s = "I";
- break;
- case FTT_TEN:
- s = "L 8";
- break;
- default:
- s = "I";
- break;
- }
- rc = ftpcmd("TYPE",s,-1,-1,show);
- if (rc == REPLY_COMPLETE)
- curtype = newtype;
-}
-
-/* PUT a file. Returns -1 on error, 0 on success, 1 if file skipped */
-
-static VOID
-#ifdef CK_ANSIC
-doftpsend(void * threadinfo)
-#else
-doftpsend(threadinfo) VOID * threadinfo;
-#endif
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "doftpsend called with threadinfo block","", 0);
- } else debug(F100, "doftpsend - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- if (initconn()) {
-#ifndef NOHTTP
- int y = -1;
- /* debug(F101,"doftpsend","tcp_http_proxy",tcp_http_proxy); */
-
- /* If the connection failed and we are using an HTTP Proxy
- * and the reason for the failure was an authentication
- * error, then we need to give the user to ability to
- * enter a username and password, just like a browser.
- *
- * I tried to do all of this within the netopen() call
- * but it is much too much work.
- */
- while (y != 0 && tcp_http_proxy != NULL ) {
-
- if (tcp_http_proxy_errno == 401 ||
- tcp_http_proxy_errno == 407 ) {
- char uid[UIDBUFLEN];
- char pwd[PWDSIZ];
- struct txtbox tb[2];
- int ok;
-
- tb[0].t_buf = uid;
- tb[0].t_len = UIDBUFLEN;
- tb[0].t_lbl = "Proxy Userid: ";
- tb[0].t_dflt = NULL;
- tb[0].t_echo = 1;
- tb[1].t_buf = pwd;
- tb[1].t_len = 256;
- tb[1].t_lbl = "Proxy Passphrase: ";
- tb[1].t_dflt = NULL;
- tb[1].t_echo = 2;
-
- ok = uq_mtxt("Proxy Server Authentication Required\n",
- NULL, 2, tb);
- if (ok && uid[0]) {
- char * proxy_user, * proxy_pwd;
-
- proxy_user = tcp_http_proxy_user;
- proxy_pwd = tcp_http_proxy_pwd;
-
- tcp_http_proxy_user = uid;
- tcp_http_proxy_pwd = pwd;
-
- y = initconn();
-
- debug(F101,"doftpsend","initconn",y);
- memset(pwd,0,PWDSIZ);
- tcp_http_proxy_user = proxy_user;
- tcp_http_proxy_pwd = proxy_pwd;
- } else
- break;
- } else
- break;
- }
-
- if ( y != 0 ) {
-#endif /* NOHTTP */
- signal(SIGINT, ftpsnd.oldintr);
-#ifdef SIGPIPE
- if (ftpsnd.oldintp)
- signal(SIGPIPE, ftpsnd.oldintp);
-#endif /* SIGPIPE */
- ftpcode = -1;
- zclose(ZIFILE);
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
-#ifndef NOHTTP
- }
-#endif /* NOHTTP */
- }
- ftpsndret = 0;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
-}
-
-static VOID
-#ifdef CK_ANSIC
-failftpsend(void * threadinfo)
-#else
-failftpsend(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- while (cpend) {
- ftpsnd.reply = getreply(0,ftpsnd.incs,ftpsnd.outcs,ftp_vbm,0);
- debug(F111,"ftp sendrequest getreply","null command",ftpsnd.reply);
- }
- if (data >= 0) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = -1;
- }
- if (ftpsnd.oldintr)
- signal(SIGINT,ftpsnd.oldintr);
-#ifdef SIGPIPE
- if (ftpsnd.oldintp)
- signal(SIGPIPE,ftpsnd.oldintp);
-#endif /* SIGPIPE */
- ftpcode = -1;
-#ifndef OS2
- /* TEST ME IN K95 */
- if (havesigint) {
- havesigint = 0;
- debug(F100,"ftp failftpsend chain to trap()...","",0);
- if (ftpsnd.oldintr != SIG_IGN)
- (*ftpsnd.oldintr)(SIGINT);
- /* NOTREACHED (I hope!) */
- debug(F100,"ftp failftpsend return from trap()...","",0);
- }
-#endif /* OS2 */
-}
-
-static VOID
-#ifdef CK_ANSIC
-failftpsend2(void * threadinfo)
-#else
-failftpsend2(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- debug(F101,"ftp sendrequest canceled","",ftpsnd.bytes);
- tfc += ffc;
-#ifdef GFTIMER
- fpfsecs = gftimer();
-#endif /* GFTIMER */
- zclose(ZIFILE);
-#ifdef PIPESEND
- if (sndfilter)
- pipesend = 0;
-#endif /* PIPESEND */
- signal(SIGINT, ftpsnd.oldintr);
-#ifdef SIGPIPE
- if (ftpsnd.oldintp)
- signal(SIGPIPE, ftpsnd.oldintp);
-#endif /* SIGPIPE */
- if (!cpend) {
- ftpcode = -1;
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (data >= 0) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = -1;
- }
- if (dout) {
-#ifdef TCPIPLIB
- socket_close(dout);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(dout, 1+1);
-#endif /* USE_SHUTDOWN */
- close(dout);
-#endif /* TCPIPLIB */
- }
- ftpsnd.reply = getreply(0,ftpsnd.incs,ftpsnd.outcs,ftp_vbm,0);
- ftpcode = -1;
- ftpsndret = -1;
-
-#ifndef OS2
- /* TEST ME IN K95 */
- if (havesigint) {
- havesigint = 0;
- debug(F100,"ftp failftpsend2 chain to trap()...","",0);
- if (ftpsnd.oldintr != SIG_IGN)
- (*ftpsnd.oldintr)(SIGINT);
- /* NOTREACHED (I hope!) */
- debug(F100,"ftp failftpsend2 return from trap()...","",0);
- }
-#endif /* OS2 */
-}
-
-static VOID
-#ifdef CK_ANSIC
-doftpsend2(void * threadinfo)
-#else
-doftpsend2(threadinfo) VOID * threadinfo;
-#endif
-{
- register int c, d = 0;
- int n, t, x, notafile, unique = 0;
- char *buf, *bufp;
-
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "doftpsend2 called with threadinfo block","", 0);
- } else debug(F100, "doftpsend2 - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- buf = ftpsndbuf; /* (not on stack) */
-
- unique = strcmp(ftpsnd.cmd,"STOU") ? 0 : 1;
- notafile = sndarray || pipesend;
-
-#ifdef FTP_RESTART
- if (ftpsnd.restart && ((curtype == FTT_BIN) || (alike > 0))) {
- char * p;
- changetype(FTT_BIN,0); /* Change to binary */
-
- /* Ask for remote file's size */
- x = ftpcmd("SIZE",ftpsnd.remote,ftpsnd.incs,ftpsnd.outcs,ftp_vbm);
-
- if (x == REPLY_COMPLETE) { /* Have ftpsnd.reply */
- p = &ftp_reply_str[4]; /* Parse it */
- while (isdigit(*p)) {
- sendstart = sendstart * 10 + (int)(*p - '0');
- p++;
- }
- if (*p && *p != CR) { /* Bad number */
- debug(F110,"doftpsend2 bad size",ftp_reply_str,0);
- sendstart = (CK_OFF_T)0;
- } else if (sendstart > fsize) { /* Remote file bigger than local */
- debug(F110,"doftpsend2 big size",ckfstoa(fsize),sendstart);
- sendstart = (CK_OFF_T)0;
- }
- /* Local is newer */
- debug(F111,"doftpsend2 size",ftpsnd.remote,sendstart);
- if (chkmodtime(ftpsnd.local,ftpsnd.remote,0) == 2) {
- debug(F110,"doftpsend2 date mismatch",ftp_reply_str,0);
- sendstart = (CK_OFF_T)0; /* Send the whole file */
- }
- }
- changetype(ftp_typ,0); /* Change back to appropriate type */
- if (sendstart > (CK_OFF_T)0) { /* Still restarting? */
- if (sendstart == fsize) { /* Same size - no need to send */
- debug(F111,"doftpsend2 /restart SKIP",
- ckfstoa(fsize),sendstart);
- zclose(ZIFILE);
- ftpsndret = SKP_RES;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- errno = 0; /* Restart needed, seek to the spot */
- if (zfseek((long)sendstart) < 0) {
- debug(F111,"doftpsend2 zfseek fails",
- ftpsnd.local,sendstart);
- fprintf(stderr, "FSEEK: %s: %s\n", ftpsnd.local, ck_errstr());
- sendstart = 0;
- zclose(ZIFILE);
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
-#ifdef COMMENT
- debug(F111,"doftpsend2 zfseek ok",ftpsnd.local,sendstart);
- x = ftpcmd("REST",ckltoa(sendstart),-1,-1,ftp_vbm);
- if (x != REPLY_CONTINUE) {
- sendstart = 0;
- zclose(ZIFILE);
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- } else {
- ftpsnd.cmd = "STOR";
- }
-#else
- sendmode = SM_RESEND;
- ftpsnd.cmd = "APPE";
-#endif /* COMMENT */
- /* sendstart = (CK_OFF_T)0; */
- }
- }
-#endif /* FTP_RESTART */
-
- if (unique && !stouarg) /* If we know STOU accepts no arg */
- ftpsnd.remote = NULL; /* don't include one. */
-
- x = ftpcmd(ftpsnd.cmd, ftpsnd.remote, ftpsnd.incs, ftpsnd.outcs, ftp_vbm);
- debug(F111,"doftpsend2 ftpcode",ftpsnd.cmd,ftpcode);
- debug(F101,"doftpsend2 ftpcmd","",x);
-
- if (x != REPLY_PRELIM && unique) {
- /*
- RFC959 says STOU does not take an argument. But every FTP server
- I've encountered but one accepts the arg and constructs the unique
- name from it, which is better than making up a totally random name
- for the file, which is what RFC959 calls for. Especially because
- there is no way for the client to find out the name chosen by the
- server. So we try STOU with the argument first, which works with
- most servers, and if it fails we retry it without the arg, for
- the benefit of the one picky server that is not "liberal in what
- it accepts" UNLESS the first STOU got a 502 code ("not implemented")
- which means STOU is not accepted, period.
- */
- if ((x == 5) && stouarg && (ftpcode != 502)) {
- x = ftpcmd(ftpsnd.cmd,NULL,ftpsnd.incs,ftpsnd.outcs,ftp_vbm);
- if (x == REPLY_PRELIM) /* If accepted */
- stouarg = 0; /* flag no STOU arg for this server */
- }
- }
- if (x != REPLY_PRELIM) {
- signal(SIGINT, ftpsnd.oldintr);
-#ifdef SIGPIPE
- if (ftpsnd.oldintp)
- signal(SIGPIPE, ftpsnd.oldintp);
-#endif /* SIGPIPE */
- debug(F101,"doftpsend2 not REPLY_PRELIM","",x);
- zclose(ZIFILE);
-#ifdef PIPESEND
- if (sndfilter)
- pipesend = 0;
-#endif /* PIPESEND */
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- debug(F100,"doftpsend2 getting data connection...","",0);
- dout = dataconn(ftpsnd.lmode); /* Get data connection */
- debug(F101,"doftpsend2 dataconn","",dout);
- if (dout == -1) {
- failftpsend2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- /* Initialize per-file stats */
- ffc = (CK_OFF_T)0; /* Character counter */
- cps = oldcps = 0L; /* Thruput */
- n = 0;
-#ifdef GFTIMER
- rftimer(); /* reset f.p. timer */
-#endif /* GFTIMER */
-
-#ifdef SIGPIPE
- ftpsnd.oldintp = signal(SIGPIPE, SIG_IGN);
-#endif /* SIGPIPE */
- debug(F101,"doftpsend2 curtype","",curtype);
- switch (curtype) {
- case FTT_BIN: /* Binary mode */
- case FTT_TEN:
- errno = d = 0;
-#ifdef VMS
- /*
- This is because VMS zxin() is C-Library fread()
- but the file was opened with zopeni(), which is RMS.
- */
- while (((c = zminchar()) > -1) && !cancelfile) {
- ffc++;
- if (zzout(dout,c) < 0)
- break;
- }
-#else /* VMS */
- while ((n = zxin(ZIFILE,buf,FTP_BUFSIZ - 1)) > 0 && !cancelfile) {
- ftpsnd.bytes += n;
- ffc += n;
- debug(F111,"doftpsend2 zxin",ckltoa(n),ffc);
- ckhexdump("doftpsend2 zxin",buf,16);
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- for (bufp = buf; n > 0; n -= d, bufp += d) {
- if ((d = SSL_write(ssl_ftp_data_con, bufp, n)) <= 0)
- break;
- spackets++;
- pktnum++;
- if (fdispla != XYFD_B) {
- spktl = d;
- ftscreen(SCR_PT,'D',(CK_OFF_T)spackets,NULL);
- }
- }
- } else {
-#endif /* CK_SSL */
- for (bufp = buf; n > 0; n -= d, bufp += d) {
- if (((d = secure_write(dout, (CHAR *)bufp, n)) <= 0)
- || iscanceled())
- break;
- spackets++;
- pktnum++;
- if (fdispla != XYFD_B) {
- spktl = d;
- ftscreen(SCR_PT,'D',(CK_OFF_T)spackets,NULL);
- }
- }
-#ifdef CK_SSL
- }
-#endif /* CK_SSL */
- if (d <= 0)
- break;
- }
-#endif /* VMS */
-
- debug(F111,"doftpsend2 XX zxin",ckltoa(n),ffc);
- if (n < 0)
- fprintf(stderr, "local: %s: %s\n", ftpsnd.local, ck_errstr());
- if (d < 0 || (d = secure_flush(dout)) < 0) {
- if (d == -1 && errno && errno != EPIPE)
- perror("netout");
- ftpsnd.bytes = -1;
- }
- break;
-
- case FTT_ASC: /* Text mode */
-#ifndef NOCSETS
- if (ftpsnd.xlate) { /* With translation */
- initxlate(ftpsnd.incs,ftpsnd.outcs);
- while (!cancelfile) {
- if ((c0 = xgnbyte(FC_UCS2,ftpsnd.incs,NULL)) < 0) break;
- if ((x = xpnbyte(c0,TC_UCS2,ftpsnd.outcs,xxout)) < 0) break;
- }
- } else {
-#endif /* NOCSETS */
- /* Text mode, no translation */
- while (((c = zminchar()) > -1) && !cancelfile) {
- ffc++;
- if (xxout(c) < 0)
- break;
- }
- d = 0;
-#ifndef NOCSETS
- }
-#endif /* NOCSETS */
- if (dout == -1 || (d = secure_flush(dout)) < 0) {
- if (d == -1 && errno && errno != EPIPE)
- perror("netout");
- ftpsnd.bytes = -1;
- }
- break;
- }
- tfc += ffc; /* Total file chars */
-#ifdef GFTIMER
- fpfsecs = gftimer();
-#endif /* GFTIMER */
- zclose(ZIFILE); /* Close input file */
-#ifdef PIPESEND
- if (sndfilter) /* Undo this (it's per file) */
- pipesend = 0;
-#endif /* PIPESEND */
-
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-
-#ifdef TCPIPLIB
- socket_close(dout); /* Close data connection */
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(dout, 1+1);
-#endif /* USE_SHUTDOWN */
- close(dout);
-#endif /* TCPIPLIB */
- ftpsnd.reply = getreply(0,ftpsnd.incs,ftpsnd.outcs,ftp_vbm,0);
- signal(SIGINT, ftpsnd.oldintr); /* Put back interrupts */
-#ifdef SIGPIPE
- if (ftpsnd.oldintp)
- signal(SIGPIPE, ftpsnd.oldintp);
-#endif /* SIGPIPE */
- if (ftpsnd.reply == REPLY_TRANSIENT || ftpsnd.reply == REPLY_ERROR) {
- debug(F101,"doftpsend2 ftpsnd.reply","",ftpsnd.reply);
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- } else if (cancelfile) {
- debug(F101,"doftpsend2 canceled","",ftpsnd.bytes);
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- debug(F101,"doftpsend2 ok","",ftpsnd.bytes);
- ftpsndret = 0;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
-}
-
-static int
-sendrequest(cmd, local, remote, xlate, incs, outcs, restart)
- char *cmd, *local, *remote; int xlate, incs, outcs, restart;
-{
- if (!remote) remote = ""; /* Check args */
- if (!*remote) remote = local;
- if (!local) local = "";
- if (!*local) return(-1);
- if (!cmd) cmd = "";
- if (!*cmd) cmd = "STOR";
-
- debug(F111,"ftp sendrequest restart",local,restart);
-
- nout = 0; /* Init output buffer count */
- ftpsnd.bytes = 0; /* File input byte count */
- dout = -1;
-
-#ifdef FTP_PROXY
- if (proxy) {
- proxtrans(cmd, local, remote, !strcmp(cmd,"STOU"));
- return(0);
- }
-#endif /* FTP_PROXY */
-
- changetype(ftp_typ,0); /* Change type for this file */
-
- ftpsnd.oldintr = NULL; /* Set up interrupt handler */
- ftpsnd.oldintp = NULL;
- ftpsnd.restart = restart;
- ftpsnd.xlate = xlate;
- ftpsnd.lmode = "wb";
-
-#ifdef PIPESEND /* Use Kermit API for file i/o... */
- if (sndfilter) {
- char * p = NULL, * q;
-#ifndef NOSPL
- int n = CKMAXPATH;
- if (cmd_quoting && (p = (char *) malloc(n + 1))) {
- q = p;
- debug(F110,"sendrequest pipesend filter",sndfilter,0);
- zzstring(sndfilter,&p,&n);
- debug(F111,"sendrequest pipename",q,n);
- if (n <= 0) {
- printf("?Sorry, send filter + filename too long, %d max.\n",
- CKMAXPATH
- );
- free(q);
- return(-1);
- }
- ckstrncpy(filnam,q,CKMAXPATH+1);
- free(q);
- local = filnam;
- }
-#endif /* NOSPL */
- }
-
- if (sndfilter) /* If sending thru a filter */
- pipesend = 1; /* set this for open and i/o */
-#endif /* PIPESEND */
-
-#ifdef VMS
- debug(F101,"XXX before openi binary","",binary);
- debug(F101,"XXX before openi ftp_typ","",ftp_typ);
-#endif /* VMS */
-
- if (openi(local) == 0) /* Try to open the input file */
- return(-1);
-
-#ifdef VMS
- debug(F101,"XXX after openi binary","",binary);
- debug(F101,"XXX after openi ftp_typ","",ftp_typ);
- if (!forcetype) {
- if (binary != ftp_typ) { /* VMS zopeni() sets binary */
- debug(F101,"XXX changing type","",binary);
- doftptyp(binary);
- debug(F101,"XXX after doftptyp","",ftp_typ);
-
- /* **** */
- if (displa && fdispla) { /* Update file type display */
- ftscreen(SCR_FN,'F',(CK_OFF_T)0,local);
- }
- }
- }
-#endif /* VMS */
- ftpsndret = 0;
- ftpsnd.incs = incs;
- ftpsnd.outcs = outcs;
- ftpsnd.cmd = cmd;
- ftpsnd.local = local;
- ftpsnd.remote = remote;
- ftpsnd.oldintr = signal(SIGINT, cancelsend);
- havesigint = 0;
-
- if (cc_execute(ckjaddr(sendcancel), doftpsend, failftpsend) < 0)
- return(-1);
- if (ftpsndret < 0)
- return(-1);
- if (cc_execute(ckjaddr(sendcancel), doftpsend2, failftpsend2) < 0)
- return(-1);
-
- return(ftpsndret);
-}
-
-static sigtype
-cancelrecv(sig) int sig; {
- havesigint++;
- cancelfile = 0;
- cancelgroup++;
- secure_getc(0,1); /* Initialize net input buffers */
- printf(" Canceling...\n");
- debug(F100,"ftp cancelrecv caught SIGINT","",0);
- fflush(stdout);
- if (fp_nml) {
- if (fp_nml != stdout)
- fclose(fp_nml);
- fp_nml = NULL;
- }
-#ifndef OS2
- longjmp(recvcancel, 1);
-#else
- PostCtrlCSem();
-#endif /* OS2 */
-}
-
-/* Argumentless front-end for secure_getc() */
-
-static int
-netgetc() {
- return(secure_getc(globaldin,0));
-}
-
-/* Returns -1 on failure, 0 on success, 1 if file skipped */
-
-/*
- Sets ftpcode < 0 on failure if failure reason is not server reply code:
- -1: interrupted by user.
- -2: error opening or writing output file (reason in errno).
- -3: failure to make data connection.
- -4: network read error (reason in errno).
-*/
-
-struct xx_ftprecv {
- int reply;
- int fcs;
- int rcs;
- int recover;
- int xlate;
- int din;
- int is_retr;
- sig_t oldintr, oldintp;
- char * cmd;
- char * local;
- char * remote;
- char * lmode;
- char * pipename;
- int tcrflag;
- CK_OFF_T localsize;
-};
-static struct xx_ftprecv ftprecv;
-
-static int ftprecvret = 0;
-
-static VOID
-#ifdef CK_ANSIC
-failftprecv(VOID * threadinfo)
-#else
-failftprecv(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- while (cpend) {
- ftprecv.reply = getreply(0,ftprecv.fcs,ftprecv.rcs,ftp_vbm,0);
- }
- if (data >= 0) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = -1;
- }
- if (ftprecv.oldintr)
- signal(SIGINT, ftprecv.oldintr);
- ftpcode = -1;
- ftprecvret = -1;
-
-#ifndef OS2
- /* TEST ME IN K95 */
- if (havesigint) {
- havesigint = 0;
- debug(F100,"ftp failftprecv chain to trap()...","",0);
- if (ftprecv.oldintr != SIG_IGN)
- (*ftprecv.oldintr)(SIGINT);
- /* NOTREACHED (I hope!) */
- debug(F100,"ftp failftprecv return from trap()...","",0);
- }
-#endif /* OS2 */
- return;
-}
-
-static VOID
-#ifdef CK_ANSIC
-doftprecv(VOID * threadinfo)
-#else
-doftprecv(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
-#ifndef COMMENT
- if (!out2screen && !ftprecv.pipename) {
- int x;
- char * local;
- local = ftprecv.local;
- x = zchko(local);
- if (x < 0) {
- if ((!dpyactive || ftp_deb))
- fprintf(stderr,
- "Temporary file %s: %s\n", ftprecv.local, ck_errstr());
- signal(SIGINT, ftprecv.oldintr);
- ftpcode = -2;
- ftprecvret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- }
-#endif /* COMMENT */
- changetype((!ftprecv.is_retr) ? FTT_ASC : ftp_typ, 0);
- if (initconn()) { /* Initialize the data connection */
- signal(SIGINT, ftprecv.oldintr);
- ftpcode = -1;
- ftprecvret = -3;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- secure_getc(0,1); /* Initialize net input buffers */
- ftprecvret = 0;
-
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
-}
-
-static VOID
-#ifdef CK_ANSIC
-failftprecv2(VOID * threadinfo)
-#else
-failftprecv2(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- /* Cancel using RFC959 recommended IP,SYNC sequence */
-
- debug(F100,"ftp recvrequest CANCEL","",0);
-#ifdef GFTIMER
- fpfsecs = gftimer();
-#endif /* GFTIMER */
-#ifdef SIGPIPE
- if (ftprecv.oldintp)
- signal(SIGPIPE, ftprecv.oldintr);
-#endif /* SIGPIPE */
- signal(SIGINT, SIG_IGN);
- if (!cpend) {
- ftpcode = -1;
- signal(SIGINT, ftprecv.oldintr);
- ftprecvret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- cancel_remote(ftprecv.din);
-
-#ifdef FTP_TIMEOUT
- if (ftp_timed_out && out2screen && !quiet)
- printf("\n?Timed out.\n");
-#endif /* FTP_TIMEOUT */
-
- if (ftpcode > -1)
- ftpcode = -1;
- if (data >= 0) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = -1;
- }
- if (!out2screen) {
- int x = 0;
- debug(F111,"ftp failrecv2 zclose",ftprecv.local,keep);
- zclose(ZOFILE);
- switch (keep) { /* which is... */
- case SET_AUTO: /* AUTO */
- if (curtype == FTT_ASC) /* Delete file if TYPE A. */
- x = 1;
- break;
- case SET_OFF: /* DISCARD */
- x = 1; /* Delete file, period. */
- break;
- default: /* KEEP */
- break;
- }
- if (x) {
- x = zdelet(ftprecv.local);
- debug(F111,"ftp failrecv2 delete incomplete",ftprecv.local,x);
- }
- }
- if (ftprecv.din) {
-#ifdef TCPIPLIB
- socket_close(ftprecv.din);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(ftprecv.din, 1+1);
-#endif /* USE_SHUTDOWN */
- close(ftprecv.din);
-#endif /* TCPIPLIB */
- }
- signal(SIGINT, ftprecv.oldintr);
- ftprecvret = -1;
-
- if (havesigint) {
- havesigint = 0;
- debug(F100,"FTP failftprecv2 chain to trap()...","",0);
-#ifdef OS2
- debug(F100,"FTP failftprecv2 PostCtrlCSem()...","",0);
- PostCtrlCSem();
-#else /* OS2 */
- if (ftprecv.oldintr != SIG_IGN)
- (*ftprecv.oldintr)(SIGINT);
- /* NOTREACHED (I hope!) */
- debug(F100,"ftp failftprecv2 return from trap()...","",0);
-#endif /* OS2 */
- }
-}
-
-static VOID
-#ifdef CK_ANSIC
-doftprecv2(VOID * threadinfo)
-#else
-doftprecv2(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
- register int c, d;
- CK_OFF_T bytes = (CK_OFF_T)0;
- int bare_lfs = 0;
- int blksize = 0;
- ULONG start = 0L, stop;
- char * p;
- static char * rcvbuf = NULL;
- static int rcvbufsiz = 0;
-#ifdef CK_URL
- char newname[CKMAXPATH+1]; /* For file dialog */
-#endif /* CK_URL */
- extern int adl_ask;
-
-#ifdef FTP_TIMEOUT
- ftp_timed_out = 0;
-#endif /* FTP_TIMEOUT */
-
- ftprecv.din = -1;
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- if (ftprecv.recover) { /* Initiate recovery */
- x = ftpcmd("REST",ckfstoa(ftprecv.localsize),-1,-1,ftp_vbm);
- debug(F111,"ftp reply","REST",x);
- if (x == REPLY_CONTINUE) {
- ftprecv.lmode = "ab";
- rs_len = ftprecv.localsize;
- } else {
- ftprecv.recover = 0;
- }
- }
- /* IMPORTANT: No FTP commands can come between REST and RETR! */
-
- debug(F111,"ftp recvrequest recover E",ftprecv.remote,ftprecv.recover);
-
- /* Send the command and get reply */
- debug(F110,"ftp recvrequest cmd",ftprecv.cmd,0);
- debug(F110,"ftp recvrequest remote",ftprecv.remote,0);
-
- if (ftpcmd(ftprecv.cmd,ftprecv.remote,ftprecv.fcs,ftprecv.rcs,ftp_vbm)
- != REPLY_PRELIM) {
- signal(SIGINT, ftprecv.oldintr); /* Bad reply, fail. */
- ftprecvret = -1; /* ftpcode is set by ftpcmd() */
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- ftprecv.din = dataconn("r"); /* Good reply, open data connection */
- globaldin = ftprecv.din; /* Global copy of file descriptor */
- if (ftprecv.din == -1) { /* Check for failure */
- ftpcode = -3; /* Code for no data connection */
- ftprecvret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
-#ifdef CK_URL
- /* In K95 GUI put up a file box */
- if (haveurl && g_url.pth && adl_ask ) { /* Downloading from a URL */
- int x;
- char * preface =
-"\r\nIncoming file from FTP server...\r\n\
-Please confirm output file specification or supply an alternative:";
-
- x = uq_file(preface, /* K95 GUI: Put up file box. */
- NULL,
- 4,
- NULL,
- ftprecv.local ? ftprecv.local : ftprecv.remote,
- newname,
- CKMAXPATH+1
- );
- if (x > 0) {
- ftprecv.local = newname; /* Substitute user's file name */
- if (x == 2) /* And append if user said to */
- ftprecv.lmode = "ab";
- }
- }
-#endif /* CK_URL */
- x = 1; /* Output file open OK? */
- if (ftprecv.pipename) { /* Command */
- x = zxcmd(ZOFILE,ftprecv.pipename);
- debug(F111,"ftp recvrequest zxcmd",ftprecv.pipename,x);
- } else if (!out2screen) { /* File */
- struct filinfo xx;
- xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
- xx.typ = 0; xx.os_specific = NUL; xx.lblopts = 0;
- /* Append or New */
- xx.dsp = !strcmp(ftprecv.lmode,"ab") ? XYFZ_A : XYFZ_N;
- x = zopeno(ZOFILE,ftprecv.local,NULL,&xx);
- debug(F111,"ftp recvrequest zopeno",ftprecv.local,x);
- }
- if (x < 1) { /* Failure to open output file */
- if ((!dpyactive || ftp_deb))
- fprintf(stderr, "local(2): %s: %s\n", ftprecv.local, ck_errstr());
- ftprecvret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- blksize = FTP_BUFSIZ; /* Allocate input buffer */
-
- debug(F101,"ftp recvrequest blksize","",blksize);
- debug(F101,"ftp recvrequest rcvbufsiz","",rcvbufsiz);
-
- if (rcvbufsiz < blksize) { /* if necessary */
- if (rcvbuf) {
- free(rcvbuf);
- rcvbuf = NULL;
- }
- rcvbuf = (char *)malloc((unsigned)blksize);
- if (!rcvbuf) {
- debug(F100,"ftp get rcvbuf malloc failed","",0);
- ftpcode = -2;
-#ifdef ENOMEM
- errno = ENOMEM;
-#endif /* ENOMEM */
- if ((!dpyactive || ftp_deb))
- perror("malloc");
- rcvbufsiz = 0;
- ftprecvret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- debug(F101,"ftp get rcvbuf malloc ok","",blksize);
- rcvbufsiz = blksize;
- }
- debug(F111,"ftp get rcvbufsiz",ftprecv.local,rcvbufsiz);
-
- ffc = (CK_OFF_T)0; /* Character counter */
- cps = oldcps = 0L; /* Thruput */
- start = gmstimer(); /* Start time (msecs) */
-#ifdef GFTIMER
- rftimer(); /* Start time (float) */
-#endif /* GFTIMER */
-
- debug(F111,"ftp get type",ftprecv.local,curtype);
- debug(F101,"ftp recvrequest ftp_dpl","",ftp_dpl);
- switch (curtype) {
- case FTT_BIN: /* Binary mode */
- case FTT_TEN: /* TENEX mode */
- d = 0;
- while (1) {
- errno = 0;
- c = secure_read(ftprecv.din, rcvbuf, rcvbufsiz);
- if (cancelfile) {
- failftprecv2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (c < 1)
- break;
-#ifdef printf /* (What if it isn't?) */
- if (out2screen && !ftprecv.pipename) {
- int i;
- for (i = 0; i < c; i++)
- printf("%c",rcvbuf[i]);
- } else
-#endif /* printf */
- {
- register int i;
- i = 0;
- errno = 0;
- while (i < c) {
- if (zmchout(rcvbuf[i++]) < 0) {
- d = i;
- break;
- }
- }
- }
- bytes += c;
- ffc += c;
- }
-#ifdef FTP_TIMEOUT
- if (c == -3) {
- debug(F100,"ftp recvrequest timeout","",0);
- bytes = (CK_OFF_T)-1;
- ftp_timed_out = 1;
- ftpcode = -3;
- } else
-#endif /* FTP_TIMEOUT */
- if (c < 0) {
- debug(F111,"ftp recvrequest errno",ckitoa(c),errno);
- if (c == -1 && errno != EPIPE)
- if ((!dpyactive || ftp_deb))
- perror("netin");
- bytes = (CK_OFF_T)-1;
- ftpcode = -4;
- }
- if (d < c) {
- ftpcode = -2;
- if ((!dpyactive || ftp_deb)) {
- char * p;
- p = ftprecv.local ? ftprecv.local : ftprecv.pipename;
- if (d < 0)
- fprintf(stderr,
- "local(3): %s: %s\n", ftprecv.local, ck_errstr());
- else
- fprintf(stderr,
- "%s: short write\n", ftprecv.local);
- }
- }
- break;
-
- case FTT_ASC: /* Text mode */
- debug(F101,"ftp recvrequest TYPE A xlate","",ftprecv.xlate);
-#ifndef NOCSETS
- if (ftprecv.xlate) {
- int t;
-#ifdef CK_ANSIC
- int (*fn)(char);
-#else
- int (*fn)();
-#endif /* CK_ANSIC */
- debug(F110,"ftp recvrequest (data)","initxlate",0);
- initxlate(ftprecv.rcs,ftprecv.fcs); /* (From,To) */
- if (ftprecv.pipename) {
- fn = pipeout;
- debug(F110,"ftp recvrequest ASCII","pipeout",0);
- } else {
- fn = out2screen ? scrnout : putfil;
- debug(F110,"ftp recvrequest ASCII",
- out2screen ? "scrnout" : "putfil",0);
- }
- while (1) {
- /* Get byte from net */
- c0 = xgnbyte(FC_UCS2,ftprecv.rcs,netgetc);
- if (cancelfile) {
- failftprecv2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (c0 < 0)
- break;
- /* Second byte from net */
- c1 = xgnbyte(FC_UCS2,ftprecv.rcs,netgetc);
- if (cancelfile) {
- failftprecv2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (c1 < 0)
- break;
-#ifdef COMMENT
- /* K95: Check whether we need this */
- if (fileorder > 0) /* Little Endian */
- bytswap(&c0,&c1); /* swap bytes*/
-#endif /* COMMENT */
-
-#ifdef OS2
- if ( out2screen && /* we're translating to UCS-2 */
- !k95stdout && !inserver) /* for the real screen... */
- {
- union {
- USHORT ucs2;
- UCHAR bytes[2];
- } output;
-
- output.bytes[0] = c1;
- output.bytes[1] = c0;
-
- VscrnWrtUCS2StrAtt(VCMD,
- &output.ucs2,
- 1,
- wherey[VCMD],
- wherex[VCMD],
- &colorcmd
- );
-
- } else
-#endif /* OS2 */
- {
- if ((x = xpnbyte(c0,TC_UCS2,ftprecv.fcs,fn)) < 0) break;
- if ((x = xpnbyte(c1,TC_UCS2,ftprecv.fcs,fn)) < 0) break;
- }
- }
- } else {
-#endif /* NOCSETS */
- while (1) {
- c = secure_getc(ftprecv.din,0);
- if (cancelfile
-#ifdef FTP_TIMEOUT
- || ftp_timed_out
-#endif /* FTP_TIMEOUT */
- ) {
- failftprecv2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (c < 0 || c == EOF)
- break;
-#ifdef UNIX
- /* Record format conversion for Unix */
- /* SKIP THIS FOR WINDOWS! */
- if (c == '\n')
- bare_lfs++;
- while (c == '\r') {
- bytes++;
- if ((c = secure_getc(ftprecv.din,0)) != '\n' ||
- ftprecv.tcrflag) {
- if (cancelfile) {
- failftprecv2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (c < 0 || c == EOF)
- goto break2;
- if (c == '\0') {
- bytes++;
- goto contin2;
- }
- }
- }
- if (c < 0)
- break;
-#endif /* UNX */
-
- if (out2screen && !ftprecv.pipename)
-#ifdef printf
- printf("%c",(char)c);
-#else
- putchar((char)c);
-#endif /* printf */
- else
- if ((d = zmchout(c)) < 0)
- break;
- bytes++;
- ffc++;
- contin2:
- ;
- }
- break2:
- if (bare_lfs && (!dpyactive || ftp_deb)) {
- printf("WARNING! %d bare linefeeds received in ASCII mode\n",
- bare_lfs);
- printf("File might not have transferred correctly.\n");
- }
- if (ftprecv.din == -1) {
- bytes = (CK_OFF_T)-1;
- }
- if (c == -2)
- bytes = (CK_OFF_T)-1;
- break;
-#ifndef NOCSETS
- }
-#endif /* NOCSETS */
- }
- if (ftprecv.pipename || !out2screen) {
- zclose(ZOFILE); /* Close the file */
- debug(F111,"doftprecv2 zclose ftpcode",ftprecv.local,ftpcode);
- if (ftpcode < 0) { /* If download failed */
- int x = 0;
- switch (keep) { /* which is... */
- case SET_AUTO: /* AUTO */
- if (curtype == FTT_ASC) /* Delete file if TYPE A. */
- x = 1;
- break;
- case SET_OFF: /* DISCARD */
- x = 1; /* Delete file, period. */
- break;
- default: /* KEEP */
- break;
- }
- if (x) {
- x = zdelet(ftprecv.local);
- debug(F111,"ftp get delete incomplete",ftprecv.local,x);
- }
- }
- }
- signal(SIGINT, ftprecv.oldintr);
-#ifdef SIGPIPE
- if (ftprecv.oldintp)
- signal(SIGPIPE, ftprecv.oldintp);
-#endif /* SIGPIPE */
- stop = gmstimer();
-#ifdef GFTIMER
- fpfsecs = gftimer();
-#endif /* GFTIMER */
- tfc += ffc;
-
-#ifdef TCPIPLIB
- socket_close(ftprecv.din);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(ftprecv.din, 1+1);
-#endif /* USE_SHUTDOWN */
- close(ftprecv.din);
-#endif /* TCPIPLIB */
- ftprecv.reply = getreply(0,ftprecv.fcs,ftprecv.rcs,ftp_vbm,0);
- ftprecvret = ((ftpcode < 0 || ftprecv.reply == REPLY_TRANSIENT ||
- ftprecv.reply == REPLY_ERROR) ? -1 : 0);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
-}
-
-static int
-recvrequest(cmd, local, remote, lmode, printnames, recover, pipename,
- xlate, fcs, rcs)
- char *cmd, *local, *remote, *lmode, *pipename;
- int printnames, recover, xlate, fcs, rcs;
-{
-#ifdef NT
- struct _stat stbuf;
-#else /* NT */
- struct stat stbuf;
-#endif /* NT */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"ftp recvrequest cmd",cmd,recover);
- debug(F110,"ftp recvrequest local ",local,0);
- debug(F111,"ftp recvrequest remote",remote,ftp_typ);
- debug(F110,"ftp recvrequest pipename ",pipename,0);
- debug(F101,"ftp recvrequest xlate","",xlate);
- debug(F101,"ftp recvrequest fcs","",fcs);
- debug(F101,"ftp recvrequest rcs","",rcs);
- }
-#endif /* DEBUG */
-
- ftprecv.localsize = (CK_OFF_T)0;
-
- if (remfile) { /* See remcfm(), remtxt() */
- if (rempipe) {
- pipename = remdest;
- } else {
- local = remdest;
- if (remappd) lmode = "ab";
- }
- }
- out2screen = 0;
- if (!cmd) cmd = ""; /* Core dump prevention */
- if (!remote) remote = "";
- if (!lmode) lmode = "";
-
- if (pipename) { /* No recovery for pipes. */
- recover = 0;
- if (!local)
- local = pipename;
- } else {
- if (!local) /* Output to screen? */
- local = "-";
- out2screen = !strcmp(local,"-");
- }
- debug(F101,"ftp recvrequest out2screen","",out2screen);
-
-#ifdef OS2
- if ( ftp_xla && out2screen && !k95stdout && !inserver )
- fcs = FC_UCS2;
-#endif /* OS2 */
-
- if (out2screen) /* No recovery to screen */
- recover = 0;
- if (!ftp_typ) /* No recovery in text mode */
- recover = 0;
- ftprecv.is_retr = (strcmp(cmd, "RETR") == 0);
-
- if (!ftprecv.is_retr) /* No recovery except for RETRieve */
- recover = 0;
-
-#ifdef COMMENT
- if (!out2screen && !pipename && ftprecv.is_retr) { /* To real file */
- if (recursive && ckstrchr(local,'/')) {
-
- }
- }
-#endif /* COMMENT */
-
- ftprecv.localsize = (CK_OFF_T)0; /* Local file size */
- rs_len = (CK_OFF_T)0; /* Recovery point */
-
- debug(F101,"ftp recvrequest recover","",recover);
- if (recover) { /* Recovering... */
- if (stat(local, &stbuf) < 0) { /* Can't stat local file */
- debug(F101,"ftp recvrequest recover stat failed","",errno);
- recover = 0; /* So cancel recovery */
- } else { /* Have local file info */
- ftprecv.localsize = stbuf.st_size; /* Get size */
- /* Remote file smaller than local */
- if (fsize < ftprecv.localsize) {
- debug(F101,"ftp recvrequest recover remote smaller","",fsize);
- recover = 0; /* Recovery can't work */
- } else if (fsize == ftprecv.localsize) { /* Sizes are equal */
- debug(F111,"ftp recvrequest recover equal size",
- remote,ftprecv.localsize);
- return(1);
- }
-#ifdef COMMENT
-/*
- The problem here is that the original partial file never got its date
- set, either because FTP DATES was OFF, or because the partial file was
- downloaded by some other program that doesn't set local file dates, or
- because Kermit only sets the file's date when the download was complete
- and successful. In all these cases, the local file has a later time
- than the remote.
-*/
- if (recover) { /* Remote is bigger */
- x = chkmodtime(local,remote,0); /* Check file dates */
- debug(F111,"ftp recvrequest chkmodtime",remote,x);
- if (x != 1) /* Dates must be equal! */
- recover = 0; /* If not, get whole file */
- }
-#endif /* COMMENT */
- }
- debug(F111,"ftp recvrequest recover",remote,recover);
- }
-
-#ifdef FTP_PROXY
- if (proxy && ftprecv.is_retr)
- return(proxtrans(cmd, local ? local : remote, remote));
-#endif /* FTP_PROXY */
-
- ftprecv.tcrflag = (feol != CR) && ftprecv.is_retr;
-
- ftprecv.reply = 0;
- ftprecv.fcs = fcs;
- ftprecv.rcs = rcs;
- ftprecv.recover = recover;
- ftprecv.xlate = xlate;
- ftprecv.cmd = cmd;
- ftprecv.local = local;
- ftprecv.remote = remote;
- ftprecv.lmode = lmode;
- ftprecv.pipename = pipename;
- ftprecv.oldintp = NULL;
- ftpcode = 0;
-
- havesigint = 0;
- ftprecv.oldintr = signal(SIGINT, cancelrecv);
- if (cc_execute(ckjaddr(recvcancel), doftprecv, failftprecv) < 0)
- return -1;
-
-#ifdef FTP_TIMEOUT
- debug(F111,"ftp recvrequest ftprecvret",remote,ftprecvret);
- debug(F111,"ftp recvrequest ftp_timed_out",remote,ftp_timed_out);
- if (ftp_timed_out)
- ftprecvret = -1;
-#endif /* FTP_TIMEOUT */
-
- if (ftprecvret < 0)
- return -1;
-
- if (cc_execute(ckjaddr(recvcancel), doftprecv2, failftprecv2) < 0)
- return -1;
- return ftprecvret;
-}
-
-/*
- * Need to start a listen on the data channel before we send the command,
- * otherwise the server's connect may fail.
- */
-static int
-initconn() {
- register char *p, *a;
- int result, tmpno = 0;
- int on = 1;
- GSOCKNAME_T len;
-
-#ifndef NO_PASSIVE_MODE
- int a1,a2,a3,a4,p1,p2;
-
- if (passivemode) {
- data = socket(AF_INET, SOCK_STREAM, 0);
- globaldin = data;
- if (data < 0) {
- perror("ftp: socket");
- return(-1);
- }
- if (ftpcmd("PASV",NULL,0,0,ftp_vbm) != REPLY_COMPLETE) {
- printf("Passive mode refused\n");
- passivemode = 0;
- return(initconn());
- }
-/*
- Now we have a string of comma-separated one-byte unsigned integer values,
- The first four are the an IP address. The fifth is the MSB of the port
- number, the sixth is the LSB. From that we can make a sockaddr_in.
-*/
- if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",&a1,&a2,&a3,&a4,&p1,&p2) != 6) {
- printf("Passive mode address scan failure\n");
- return(-1);
- };
-#ifndef NOHTTP
- if (tcp_http_proxy) {
-#ifdef OS2
- char * agent = "Kermit 95"; /* Default user agent */
-#else
- char * agent = "C-Kermit";
-#endif /* OS2 */
- register struct hostent *hp = 0;
- struct servent *destsp;
- char host[512], *p, *q;
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- int tos;
-#endif /* IPTOS_THROUGHPUT */
-#endif /* IP_TOS */
- int s;
-#ifdef DEBUG
- extern int debtim;
- int xdebtim;
- xdebtim = debtim;
- debtim = 1;
-#endif /* DEBUG */
-
- ckmakxmsg(proxyhost,HTTPCPYL,ckuitoa(a1),".",ckuitoa(a2),
- ".",ckuitoa(a3),".",ckuitoa(a4),":",ckuitoa((p1<<8)|p2),
- NULL,NULL,NULL
- );
- memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
- for (p = tcp_http_proxy, q=host; *p != '\0' && *p != ':'; p++, q++)
- *q = *p;
- *q = '\0';
-
- hisctladdr.sin_addr.s_addr = inet_addr(host);
- if (hisctladdr.sin_addr.s_addr != INADDR_NONE) /* 2010-03-29 */
- {
- debug(F110,"initconn A",host,0);
- hisctladdr.sin_family = AF_INET;
- } else {
- debug(F110,"initconn B",host,0);
- hp = gethostbyname(host);
-#ifdef HADDRLIST
- hp = ck_copyhostent(hp); /* make safe copy that won't change */
-#endif /* HADDRLIST */
- if (hp == NULL) {
- fprintf(stderr, "ftp: %s: Unknown host\n", host);
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(0);
- }
- hisctladdr.sin_family = hp->h_addrtype;
-#ifdef HADDRLIST
- memcpy((char *)&hisctladdr.sin_addr, hp->h_addr_list[0],
- sizeof(hisctladdr.sin_addr));
-#else /* HADDRLIST */
- memcpy((char *)&hisctladdr.sin_addr, hp->h_addr,
- sizeof(hisctladdr.sin_addr));
-#endif /* HADDRLIST */
- }
- data = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- debug(F101,"initconn socket","",data);
- if (data < 0) {
- perror("ftp: socket");
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(0);
- }
- if (*p == ':')
- p++;
- else
- p = "http";
-
- destsp = getservbyname(p,"tcp");
- if (destsp)
- hisctladdr.sin_port = destsp->s_port;
- else if (p)
- hisctladdr.sin_port = htons(atoi(p));
- else
- hisctladdr.sin_port = htons(80);
- errno = 0;
-#ifdef HADDRLIST
- debug(F100,"initconn HADDRLIST","",0);
- while
-#else
- debug(F100,"initconn no HADDRLIST","",0);
- if
-#endif /* HADDRLIST */
- (connect(data, (struct sockaddr *)&hisctladdr,
- sizeof (hisctladdr)) < 0) {
- debug(F101,"initconn connect failed","",errno);
-#ifdef HADDRLIST
- if (hp && hp->h_addr_list[1]) {
- int oerrno = errno;
-
- fprintf(stderr,
- "ftp: connect to address %s: ",
- inet_ntoa(hisctladdr.sin_addr)
- );
- errno = oerrno;
- perror((char *)0);
- hp->h_addr_list++;
- memcpy((char *)&hisctladdr.sin_addr,
- hp->h_addr_list[0],
- sizeof(hisctladdr.sin_addr));
- fprintf(stdout, "Trying %s...\n",
- inet_ntoa(hisctladdr.sin_addr));
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
- close(data);
-#endif /* TCPIPLIB */
- data = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- if (data < 0) {
- perror("ftp: socket");
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(0);
- }
- continue;
- }
-#endif /* HADDRLIST */
- perror("ftp: connect");
- ftpcode = -1;
- goto bad;
- }
- if (http_connect(data,
- tcp_http_proxy_agent ?
- tcp_http_proxy_agent :
- agent,
- NULL,
- tcp_http_proxy_user,
- tcp_http_proxy_pwd,
- 0,
- proxyhost
- ) < 0) {
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
- close(data);
-#endif /* TCPIPLIB */
- perror("ftp: connect");
- ftpcode = -1;
- goto bad;
- }
- } else
-#endif /* NOHTTP */
- {
- data_addr.sin_family = AF_INET;
- data_addr.sin_addr.s_addr = htonl((a1<<24)|(a2<<16)|(a3<<8)|a4);
- data_addr.sin_port = htons((p1<<8)|p2);
-
- if (connect(data,
- (struct sockaddr *)&data_addr,
- sizeof(data_addr)) < 0
- ) {
- perror("ftp: connect");
- return(-1);
- }
- }
- debug(F100,"initconn connect ok","",0);
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- on = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
- perror("ftp: setsockopt TOS (ignored)");
-#endif /* IPTOS_THROUGHPUT */
-#endif /* IP_TOS */
- memcpy(&hisdataaddr,&data_addr,sizeof(struct sockaddr_in));
- return(0);
- }
-#endif /* NO_PASSIVE_MODE */
-
- noport:
- memcpy(&data_addr,&myctladdr,sizeof(struct sockaddr_in));
- if (sendport)
- data_addr.sin_port = 0; /* let system pick one */
- if (data != -1) {
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- }
- data = socket(AF_INET, SOCK_STREAM, 0);
- globaldin = data;
- if (data < 0) {
- perror("ftp: socket");
- if (tmpno)
- sendport = 1;
- return(-1);
- }
- if (!sendport) {
- if (setsockopt(data,
- SOL_SOCKET,
- SO_REUSEADDR,
- (char *)&on,
- sizeof (on)
- ) < 0
- ) {
- perror("ftp: setsockopt (reuse address)");
- goto bad;
- }
- }
- if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
- perror("ftp: bind");
- goto bad;
- }
- len = sizeof (data_addr);
- if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
- perror("ftp: getsockname");
- goto bad;
- }
- if (listen(data, 1) < 0) {
- perror("ftp: listen");
- goto bad;
- }
- if (sendport) {
- a = (char *)&data_addr.sin_addr;
- p = (char *)&data_addr.sin_port;
- ckmakxmsg(ftpcmdbuf,FTP_BUFSIZ,"PORT ",
- UC(a[0]),",",UC(a[1]),",", UC(a[2]),",", UC(a[3]),",",
- UC(p[0]),",", UC(p[1]));
- result = ftpcmd(ftpcmdbuf,NULL,0,0,ftp_vbm);
- if (result == REPLY_ERROR && sendport) {
- sendport = 0;
- tmpno = 1;
- goto noport;
- }
- return(result != REPLY_COMPLETE);
- }
- if (tmpno)
- sendport = 1;
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- on = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
- perror("ftp: setsockopt TOS (ignored)");
-#endif
-#endif
- return(0);
- bad:
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- if (tmpno)
- sendport = 1;
- return(-1);
-}
-
-#ifdef CK_SSL
-static int
-ssl_dataconn() {
- if (ssl_ftp_data_con!=NULL) { /* Do SSL */
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_con=NULL;
- }
- ssl_ftp_data_con=(SSL *)SSL_new(ssl_ftp_ctx);
-
- SSL_set_fd(ssl_ftp_data_con,data);
- SSL_set_verify(ssl_ftp_data_con,ssl_verify_flag,NULL);
-
- SSL_copy_session_id(ssl_ftp_data_con,ssl_ftp_con);
-
- if (ssl_debug_flag) {
- fprintf(stderr,"=>START SSL connect on DATA\n");
- fflush(stderr);
- }
- if (SSL_connect(ssl_ftp_data_con) <= 0) {
- static char errbuf[1024];
- ckmakmsg(errbuf,1024,"ftp: SSL_connect DATA error: ",
- ERR_error_string(ERR_get_error(),NULL),NULL,NULL);
- fprintf(stderr,"%s\n", errbuf);
- fflush(stderr);
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- } else {
- ssl_ftp_data_active_flag=1;
-
- if (!ssl_certsok_flag && !tls_is_krb5(2)) {
- char *subject = ssl_get_subject_name(ssl_ftp_data_con);
-
- if (!subject) {
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- debug(F110,"dataconn","[SSL _- FAILED]",0);
-
- ssl_ftp_data_active_flag = 0;
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- } else {
- if (!out2screen && displa && fdispla) {
- ftscreen(SCR_TC,0,(CK_OFF_T)0,"Display canceled");
- /* fdispla = XYFD_B; */
- }
-
- if (uq_ok(
- "Warning: Server didn't provide a certificate on data connection\n",
- "Continue with file transfer? (Y/N)",
- 3,NULL,0) <= 0) {
- debug(F110, "dataconn","[SSL - FAILED]",0);
- ssl_ftp_data_active_flag = 0;
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- }
- }
- } else {
- if (!out2screen && displa && fdispla == XYFD_C) {
- ftscreen(SCR_TC,0,(CK_OFF_T)0,"Display canceled");
- /* fdispla = XYFD_B; */
- }
-
- if (ssl_check_server_name(ssl_ftp_data_con,ftp_user_host)) {
- debug(F110,"dataconn","[SSL - FAILED]",0);
- ssl_ftp_data_active_flag = 0;
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- }
- }
- }
- debug(F110,"dataconn","[SSL - OK]",0);
-#ifdef COMMENT
- /* This messes up the full screen file transfer display */
- ssl_display_connect_details(ssl_ftp_con,0,ssl_verbose_flag);
-#endif /* COMMENT */
- }
- if (ssl_debug_flag) {
- fprintf(stderr,"=>DONE SSL connect on DATA\n");
- fflush(stderr);
- }
- return(data);
-}
-#endif /* CK_SSL */
-
-static int
-dataconn(lmode) char *lmode; {
- int s;
-#ifdef IP_TOS
- int tos;
-#endif /* IP_TOS */
-#ifdef UCX50
- static u_int fromlen;
-#else
- static SOCKOPT_T fromlen;
-#endif /* UCX50 */
-
- fromlen = sizeof(hisdataaddr);
-
-#ifndef NO_PASSIVE_MODE
- if (passivemode) {
-#ifdef CK_SSL
- ssl_ftp_data_active_flag=0;
- if (ssl_ftp_active_flag &&
- (ssl_ftp_proxy || ftp_dpl == FPL_PRV))
- return(ssl_dataconn());
-#endif /* CK_SSL */
- return(data);
- }
-#endif /* NO_PASSIVE_MODE */
-
- s = accept(data, (struct sockaddr *) &hisdataaddr, &fromlen);
- if (s < 0) {
- perror("ftp: accept");
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- }
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = s;
- globaldin = data;
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- tos = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
- perror("ftp: setsockopt TOS (ignored)");
-#endif /* IPTOS_THROUGHPUT */
-#endif /* IP_TOS */
-
-#ifdef CK_SSL
- ssl_ftp_data_active_flag=0;
- if (ssl_ftp_active_flag &&
- (ssl_ftp_proxy || ftp_dpl == FPL_PRV))
- return(ssl_dataconn());
-#endif /* CK_SSL */
- return(data);
-}
-
-#ifdef FTP_PROXY
-static sigtype
-pscancel(sig) int sig; {
- cancelfile++;
-}
-
-static VOID
-pswitch(flag) int flag; {
- extern int proxy;
- sig_t oldintr;
- static struct comvars {
- int connect;
- char name[MAXHOSTNAMELEN];
- struct sockaddr_in mctl;
- struct sockaddr_in hctl;
- FILE *in;
- FILE *out;
- int tpe;
- int curtpe;
- int cpnd;
- int sunqe;
- int runqe;
- int mcse;
- int ntflg;
- char nti[17];
- char nto[17];
- int mapflg;
- char mi[CKMAXPATH];
- char mo[CKMAXPATH];
- char *authtype;
- int clvl;
- int dlvl;
-#ifdef FTP_KRB4
- des_cblock session;
- des_key_schedule ftp_sched;
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- gss_ctx_id_t gcontext;
-#endif /* GSSAPI */
- } proxstruct, tmpstruct;
- struct comvars *ip, *op;
-
- cancelfile = 0;
- oldintr = signal(SIGINT, pscancel);
- if (flag) {
- if (proxy)
- return;
- ip = &tmpstruct;
- op = &proxstruct;
- proxy++;
- } else {
- if (!proxy)
- return;
- ip = &proxstruct;
- op = &tmpstruct;
- proxy = 0;
- }
- ip->connect = connected;
- connected = op->connect;
- if (ftp_host) {
- strncpy(ip->name, ftp_host, MAXHOSTNAMELEN - 1);
- ip->name[MAXHOSTNAMELEN - 1] = '\0';
- ip->name[strlen(ip->name)] = '\0';
- } else
- ip->name[0] = 0;
- ftp_host = op->name;
- ip->hctl = hisctladdr;
- hisctladdr = op->hctl;
- ip->mctl = myctladdr;
- myctladdr = op->mctl;
- ip->in = csocket;
- csocket = op->in;
- ip->out = csocket;
- csocket = op->out;
- ip->tpe = ftp_typ;
- ftp_typ = op->tpe;
- ip->curtpe = curtype;
- curtype = op->curtpe;
- ip->cpnd = cpend;
- cpend = op->cpnd;
- ip->sunqe = ftp_usn;
- ftp_usn = op->sunqe;
- ip->mcse = mcase;
- mcase = op->mcse;
- ip->ntflg = ntflag;
- ntflag = op->ntflg;
- strncpy(ip->nti, ntin, 16);
- (ip->nti)[strlen(ip->nti)] = '\0';
- strcpy(ntin, op->nti);
- strncpy(ip->nto, ntout, 16);
- (ip->nto)[strlen(ip->nto)] = '\0';
- strcpy(ntout, op->nto);
- ip->mapflg = mapflag;
- mapflag = op->mapflg;
- strncpy(ip->mi, mapin, CKMAXPATH - 1);
- (ip->mi)[strlen(ip->mi)] = '\0';
- strcpy(mapin, op->mi);
- strncpy(ip->mo, mapout, CKMAXPATH - 1);
- (ip->mo)[strlen(ip->mo)] = '\0';
- strcpy(mapout, op->mo);
- ip->authtype = auth_type;
- auth_type = op->authtype;
- ip->clvl = ftp_cpl;
- ftp_cpl = op->clvl;
- ip->dlvl = ftp_dpl;
- ftp_dpl = op->dlvl;
- if (!ftp_cpl)
- ftp_cpl = FPL_CLR;
- if (!ftp_dpl)
- ftp_dpl = FPL_CLR;
-#ifdef FTP_KRB4
- memcpy(ip->session, ftp_cred.session, sizeof(ftp_cred.session));
- memcpy(ftp_cred.session, op->session, sizeof(ftp_cred.session));
- memcpy(ip->schedule, ftp_sched, sizeof(ftp_sched));
- memcpy(ftp_sched, op->schedule, sizeof(ftp_sched));
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- ip->gcontext = gcontext;
- gcontext = op->gcontext;
-#endif /* GSSAPI */
- signal(SIGINT, oldintr);
- if (cancelfile) {
- cancelfile = 0;
- debug(F101,"pswitch cancelfile B","",cancelfile);
- (*oldintr)(SIGINT);
- }
-}
-
-static sigtype
-cancelpt(sig) int sig; {
- printf("\n");
- fflush(stdout);
- ptabflg++;
- cancelfile = 0;
-#ifndef OS2
- longjmp(ptcancel, 1);
-#else
- PostCtrlCSem();
-#endif /* OS2 */
-}
-
-void
-proxtrans(cmd, local, remote, unique) char *cmd, *local, *remote; int unique; {
- sig_t oldintr;
- int secndflag = 0, prox_type, nfnd;
- char *cmd2;
-#ifdef BSDSELECT
- fd_set mask;
-#endif /* BSDSELECT */
- sigtype cancelpt();
-
- if (strcmp(cmd, "RETR"))
- cmd2 = "RETR";
- else
- cmd2 = unique ? "STOU" : "STOR";
- if ((prox_type = type) == 0) {
- if (servertype == SYS_UNIX && unix_proxy)
- prox_type = FTT_BIN;
- else
- prox_type = FTT_ASC;
- }
- if (curtype != prox_type)
- changetype(prox_type, 1);
- if (ftpcmd("PASV",NULL,0,0,ftp_vbm) != REPLY_COMPLETE) {
- printf("Proxy server does not support third party transfers.\n");
- return;
- }
- pswitch(0);
- if (!connected) {
- printf("No primary connection\n");
- pswitch(1);
- ftpcode = -1;
- return;
- }
- if (curtype != prox_type)
- changetype(prox_type, 1);
-
- if (ftpcmd("PORT",pasv,-1,-1,ftp_vbm) != REPLY_COMPLETE) {
- pswitch(1);
- return;
- }
-
- /* Replace with calls to cc_execute() */
- if (setjmp(ptcancel))
- goto cancel;
- oldintr = signal(SIGINT, cancelpt);
- if (ftpcmd(cmd,remote,-1,-1,ftp_vbm) != PRELIM) {
- signal(SIGINT, oldintr);
- pswitch(1);
- return;
- }
- sleep(2000);
- pswitch(1);
- secndflag++;
- if (ftpcmd(cmd2,local,-1,-1,ftp_vbm) != PRELIM)
- goto cancel;
- ptflag++;
- getreply(0,-1,-1,ftp_vbm,0);
- pswitch(0);
- getreply(0,-1,-1,ftp_vbm,0);
- signal(SIGINT, oldintr);
- pswitch(1);
- ptflag = 0;
- return;
-
- cancel:
- signal(SIGINT, SIG_IGN);
- ptflag = 0;
- if (strcmp(cmd, "RETR") && !proxy)
- pswitch(1);
- else if (!strcmp(cmd, "RETR") && proxy)
- pswitch(0);
- if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */
- if (ftpcmd(cmd2,local,-1,-1,ftp_vbm) != PRELIM) {
- pswitch(0);
- if (cpend)
- cancel_remote(0);
- }
- pswitch(1);
- if (ptabflg)
- ftpcode = -1;
- signal(SIGINT, oldintr);
- return;
- }
- if (cpend)
- cancel_remote(0);
- pswitch(!proxy);
- if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */
- if (ftpcmd(cmd2,local,-1,-1,ftp_vbm) != PRELIM) {
- pswitch(0);
- if (cpend)
- cancel_remote(0);
- pswitch(1);
- if (ptabflg)
- ftpcode = -1;
- signal(SIGINT, oldintr);
- return;
- }
- }
- if (cpend)
- cancel_remote(0);
- pswitch(!proxy);
- if (cpend) {
-#ifdef BSDSELECT
- FD_ZERO(&mask);
- FD_SET(csocket, &mask);
- if ((nfnd = empty(&mask, 10)) <= 0) {
- if (nfnd < 0) {
- perror("cancel");
- }
- if (ptabflg)
- ftpcode = -1;
- lostpeer();
- }
-#else /* BSDSELECT */
-#ifdef IBMSELECT
- if ((nfnd = empty(&csocket, 1, 10)) <= 0) {
- if (nfnd < 0) {
- perror("cancel");
- }
- if (ptabflg)
- ftpcode = -1;
- lostpeer();
- }
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
- getreply(0,-1,-1,ftp_vbm,0);
- getreply(0,-1,-1,ftp_vbm,0);
- }
- if (proxy)
- pswitch(0);
- pswitch(1);
- if (ptabflg)
- ftpcode = -1;
- signal(SIGINT, oldintr);
-}
-#endif /* FTP_PROXY */
-
-#ifdef FTP_SECURITY
-#ifdef FTP_GSSAPI
-
-#ifdef COMMENT
-/* ck_gss_mech_krb5 is not declared anywhere */
-struct {
- CONST gss_OID_desc * CONST * mech_type;
- char *service_name;
-} gss_trials[] = {
- { &ck_gss_mech_krb5, "ftp" },
- { &ck_gss_mech_krb5, "host" },
-};
-#else
-/* This matches what is declared above */
-struct {
- CONST gss_OID_desc * CONST * mech_type;
- char *service_name;
-} gss_trials[] = {
- { &gss_mech_krb5, "ftp" },
- { &gss_mech_krb5, "host" },
-};
-#endif /* COMMENT */
-
-
-int n_gss_trials = sizeof(gss_trials)/sizeof(gss_trials[0]);
-#endif /* FTP_GSSAPI */
-
-static int
-ftp_auth() {
- extern int setsafe();
- int j = 0, n;
-#ifdef FTP_KRB4
- char *service, inst[INST_SZ];
- ULONG cksum;
- ULONG checksum = (ULONG) getpid();
- CHAR out_buf[FTP_BUFSIZ];
- int i;
-#else /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- CHAR out_buf[FTP_BUFSIZ];
- int i;
-#endif /* FTP_GSSAPI */
-#endif /* FTP_KRB4 */
-
- if (ssl_ftp_proxy) /* Do not allow AUTH over SSL proxy */
- return(0);
-
- if (auth_type)
- return(1); /* auth already succeeded */
-
- /* Try each auth type as specified by the end user */
- for (j = 0; j < 8 && ftp_auth_type[j] != 0; j++) {
-#ifdef FTP_GSSAPI
- if (ftp_auth_type[j] == FTA_GK5 && ck_gssapi_is_installed()) {
- n = ftpcmd("AUTH GSSAPI",NULL,0,0,ftp_vbm);
- if (n == REPLY_CONTINUE) {
- OM_uint32 maj_stat, min_stat;
- gss_name_t target_name;
- gss_buffer_desc send_tok, recv_tok, *token_ptr;
- char stbuf[FTP_BUFSIZ];
- int comcode, trial;
- struct gss_channel_bindings_struct chan;
- char * realm = NULL;
- char tgt[256];
-
- chan.initiator_addrtype = GSS_C_AF_INET; /* OM_uint32 */
- chan.initiator_address.length = 4;
- chan.initiator_address.value = &myctladdr.sin_addr.s_addr;
- chan.acceptor_addrtype = GSS_C_AF_INET; /* OM_uint32 */
- chan.acceptor_address.length = 4;
- chan.acceptor_address.value = &hisctladdr.sin_addr.s_addr;
- chan.application_data.length = 0;
- chan.application_data.value = 0;
-
- if (!quiet)
- printf("GSSAPI accepted as authentication type\n");
-
- realm = ck_krb5_realmofhost(ftp_user_host);
- if (realm) {
- ckmakmsg(tgt,sizeof(tgt),"krbtgt/",realm,"@",realm);
- debug(F110,"ftp_auth(GSSAPI) TGT",tgt,0);
- if ( krb5_autoget &&
- !((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
- (ck_krb5_is_tgt_valid() > 0)) )
- ck_krb5_autoget_TGT(realm);
- }
-
- /* Blob from gss-client */
- for (trial = 0; trial < n_gss_trials; trial++) {
- /* ftp@hostname first, the host@hostname */
- /* the V5 GSSAPI binding canonicalizes this for us... */
- ckmakmsg(stbuf,FTP_BUFSIZ,
- gss_trials[trial].service_name,
- "@",
- ftp_user_host,
- NULL
- );
- if (ftp_deb)
- fprintf(stderr,
- "Authenticating to <%s>...\n", stbuf);
- send_tok.value = stbuf;
- send_tok.length = strlen(stbuf);
- maj_stat = gss_import_name(&min_stat, &send_tok,
- gss_nt_service_name,
- &target_name
- );
- if (maj_stat != GSS_S_COMPLETE) {
- user_gss_error(maj_stat, min_stat, "parsing name");
- secure_error("name parsed <%s>\n", stbuf);
- continue;
- }
- token_ptr = GSS_C_NO_BUFFER;
- gcontext = GSS_C_NO_CONTEXT; /* structure copy */
-
- do {
- if (ftp_deb)
- fprintf(stderr, "calling gss_init_sec_context\n");
- maj_stat =
- gss_init_sec_context(&min_stat,
- GSS_C_NO_CREDENTIAL,
- &gcontext,
- target_name,
- (gss_OID) *
- gss_trials[trial].mech_type,
- GSS_C_MUTUAL_FLAG |
- GSS_C_REPLAY_FLAG |
- (ftp_cfw ?
- GSS_C_DELEG_FLAG : 0),
- 0,
- /* channel bindings */
- (krb5_d_no_addresses ?
- GSS_C_NO_CHANNEL_BINDINGS :
- &chan),
- token_ptr,
- NULL, /* ignore mech type */
- &send_tok,
- NULL, /* ignore ret_flags */
- NULL
- ); /* ignore time_rec */
-
- if (maj_stat != GSS_S_COMPLETE &&
- maj_stat != GSS_S_CONTINUE_NEEDED) {
- if (trial == n_gss_trials-1)
- user_gss_error(maj_stat,
- min_stat,
- "initializing context"
- );
- gss_release_name(&min_stat, &target_name);
- /* maybe we missed on the service name */
- goto outer_loop;
- }
- if (send_tok.length != 0) {
- int len;
- reply_parse = "ADAT="; /* for ftpcmd() later */
- len = FTP_BUFSIZ;
- kerror =
- radix_encode(send_tok.value,
- out_buf,
- send_tok.length,
- &len,
- RADIX_ENCODE
- );
- if (kerror) {
- fprintf(stderr,
- "Base 64 encoding failed: %s\n",
- radix_error(kerror)
- );
- goto gss_complete_loop;
- }
- comcode = ftpcmd("ADAT",out_buf,-1,-1,0);
- if (comcode != REPLY_COMPLETE
- && comcode != REPLY_CONTINUE /* (335) */
- ) {
- if (trial == n_gss_trials-1) {
- fprintf(stderr, "GSSAPI ADAT failed\n");
- /* force out of loop */
- maj_stat = GSS_S_FAILURE;
- }
- /*
- Backoff to the v1 gssapi is still possible.
- Send a new AUTH command. If that fails,
- terminate the loop.
- */
- if (ftpcmd("AUTH GSSAPI",NULL,0,0,ftp_vbm)
- != REPLY_CONTINUE) {
- fprintf(stderr,
- "GSSAPI ADAT failed, AUTH restart failed\n");
- /* force out of loop */
- maj_stat = GSS_S_FAILURE;
- }
- goto outer_loop;
- }
- if (!reply_parse) {
- fprintf(stderr,
- "No authentication data received from server\n");
- if (maj_stat == GSS_S_COMPLETE) {
- fprintf(stderr,
- "...but no more was needed\n");
- goto gss_complete_loop;
- } else {
- user_gss_error(maj_stat,
- min_stat,
- "no reply, huh?"
- );
- goto gss_complete_loop;
- }
- }
- len = FTP_BUFSIZ;
- kerror = radix_encode(reply_parse,out_buf,i,&len,
- RADIX_DECODE);
- if (kerror) {
- fprintf(stderr,
- "Base 64 decoding failed: %s\n",
- radix_error(kerror));
- goto gss_complete_loop;
- }
-
- /* everything worked */
- token_ptr = &recv_tok;
- recv_tok.value = out_buf;
- recv_tok.length = len;
- continue;
-
- /* get out of loop clean */
- gss_complete_loop:
- trial = n_gss_trials-1;
- gss_release_buffer(&min_stat, &send_tok);
- gss_release_name(&min_stat, &target_name);
- goto outer_loop;
- }
- } while (maj_stat == GSS_S_CONTINUE_NEEDED);
-
- outer_loop:
- if (maj_stat == GSS_S_COMPLETE)
- break;
- }
- if (maj_stat == GSS_S_COMPLETE) {
- printf("GSSAPI authentication succeeded\n");
- reply_parse = NULL;
- auth_type = "GSSAPI";
- return(1);
- } else {
- fprintf(stderr, "GSSAPI authentication failed\n");
- reply_parse = NULL;
- }
- } else {
- if (ftp_deb)
- fprintf(stderr, "GSSAPI rejected as an authentication type\n");
- if (ftpcode == 500 || ftpcode == 502)
- return(0);
- }
- }
-#endif /* FTP_GSSAPI */
-#ifdef FTP_SRP
- if (ftp_auth_type[j] == FTA_SRP && ck_srp_is_installed()) {
- if (srp_ftp_auth(ftp_user_host,NULL,NULL))
- return(1);
- else if (ftpcode == 500 || ftpcode == 502)
- return(0);
- }
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- if (ftp_auth_type[j] == FTA_K4 && ck_krb4_is_installed()) {
- n = ftpcmd("AUTH KERBEROS_V4",NULL,0,0,ftp_vbm);
- if (n == REPLY_CONTINUE) {
- char tgt[4*REALM_SZ+1];
- int rc;
-
- if (!quiet)
- printf("KERBEROS_V4 accepted as authentication type\n");
- ckstrncpy(inst, (char *) krb_get_phost(ftp_user_host),INST_SZ);
- ckstrncpy(ftp_realm,
- (char *)ck_krb4_realmofhost(ftp_user_host),
- REALM_SZ
- );
-
- ckmakmsg(tgt,sizeof(tgt),"krbtgt.",ftp_realm,"@",ftp_realm);
- rc = ck_krb4_tkt_isvalid(tgt);
-
- if (rc <= 0 && krb4_autoget)
- ck_krb4_autoget_TGT(ftp_realm);
-
- service = "ftp";
- kerror = krb_mk_req(&ftp_tkt,service,inst,ftp_realm,checksum);
- if (kerror == KDC_PR_UNKNOWN) {
- service = "rcmd";
- kerror = krb_mk_req(&ftp_tkt,
- service,
- inst,
- ftp_realm,
- checksum
- );
- }
- if (kerror)
- fprintf(stderr, "Kerberos V4 krb_mk_req failed: %s\n",
- krb_get_err_text(kerror));
- if (!kerror) {
- kerror = krb_get_cred(service, inst, ftp_realm,&ftp_cred);
- if (kerror)
- fprintf(stderr, "Kerberos V4 krb_get_cred failed: %s\n",
- krb_get_err_text(kerror));
- }
- if (!kerror) {
- int rc;
- rc = des_key_sched(ftp_cred.session, ftp_sched);
- if (rc == -1) {
- printf("?Invalid DES key specified in credentials\r\n");
- debug(F110,"ftp_auth",
- "invalid DES Key specified in credentials",0);
- } else if ( rc == -2 ) {
- printf("?Weak DES key specified in credentials\r\n");
- debug(F110,"ftp_auth",
- "weak DES Key specified in credentials",0);
- } else if ( rc != 0 ) {
- printf("?DES Key Schedule not set by credentials\r\n");
- debug(F110,"ftp_auth",
- "DES Key Schedule not set by credentials",0);
- }
- reply_parse = "ADAT=";
- i = FTP_BUFSIZ;
- kerror = radix_encode(ftp_tkt.dat, out_buf, ftp_tkt.length,
- &i, RADIX_ENCODE);
- if (kerror) {
- fprintf(stderr, "Base 64 encoding failed: %s\n",
- radix_error(kerror));
- goto krb4_err;
- }
- if (i > FTP_BUFSIZ - 6)
- printf("?ADAT data too long\n");
- if (ftpcmd("ADAT",out_buf,-1,-1,0) !=
- REPLY_COMPLETE) {
- fprintf(stderr, "Kerberos V4 authentication failed\n");
- goto krb4_err;
- }
- if (!reply_parse) {
- fprintf(stderr,
- "No authentication data received from server\n");
- goto krb4_err;
- }
- i = sizeof(out_buf);
- kerror =
- radix_encode(reply_parse, out_buf, 0, &i, RADIX_DECODE);
- if (kerror) {
- fprintf(stderr, "Base 64 decoding failed: %s\n",
- radix_error(kerror));
- goto krb4_err;
- }
- kerror = krb_rd_safe(out_buf, i,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &hisctladdr,
- &myctladdr,
- &ftp_msg_data
- );
- if (kerror) {
- fprintf(stderr, "Kerberos V4 krb_rd_safe failed: %s\n",
- krb_get_err_text(kerror));
- goto krb4_err;
- }
-
- /* fetch the (modified) checksum */
- memcpy(&cksum, ftp_msg_data.app_data, sizeof(cksum));
- if (ntohl(cksum) == checksum + 1) {
- if (ftp_vbm)
- printf("Kerberos V4 authentication succeeded\n");
- reply_parse = NULL;
- auth_type = "KERBEROS_V4";
- return(1);
- } else
- fprintf(stderr,
- "Kerberos V4 mutual authentication failed\n");
- krb4_err:
- reply_parse = NULL;
- }
- } else {
- if (ftp_deb)
- fprintf(stderr,
- "KERBEROS_V4 rejected as an authentication type\n");
- if (ftpcode == 500 || ftpcode == 502)
- return(0);
- }
- }
-#endif /* FTP_KRB4 */
-#ifdef CK_SSL
- if (ftp_auth_type[j] == FTA_TLS && ck_ssleay_is_installed()) {
-#ifdef FTPHOST
- if (!hostcmd) {
- ftpcmd("HOST",ftp_user_host,0,0,0);
- hostcmd = 1;
- }
-#endif /* FTPHOST */
- n = ftpcmd("AUTH TLS",NULL,0,0,ftp_vbm);
- if (n != REPLY_COMPLETE)
- n = ftpcmd("AUTH TLS-P",NULL,0,0,ftp_vbm);
- if (n == REPLY_COMPLETE) {
- if (!quiet)
- printf("TLS accepted as authentication type\n");
-
- auth_type = "TLS";
- ssl_auth();
- if (ssl_ftp_active_flag ) {
- ftp_dpl = FPL_CLR;
- ftp_cpl = FPL_PRV;
- return(1);
- } else {
- fprintf(stderr,"TLS authentication failed\n");
- auth_type = NULL;
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(csocket, 1+1);
-#endif /* USE_SHUTDOWN */
- close(csocket);
-#endif /* TCPIPLIB */
- csocket = -1;
- if (ftp_hookup(ftp_user_host,ftp_port,0) == NULL)
- return(0);
- }
- } else {
- if (ftp_deb)
- fprintf(stderr,"TLS rejected as an authentication type\n");
- if (ftpcode == 500 || ftpcode == 502)
- return(0);
- }
- }
- if (ftp_auth_type[j] == FTA_SSL && ck_ssleay_is_installed()) {
-#ifdef FTPHOST
- if (!hostcmd) {
- ftpcmd("HOST",ftp_user_host,0,0,0);
- hostcmd = 1;
- }
-#endif /* FTPHOST */
- n = ftpcmd("AUTH SSL",NULL,0,0,ftp_vbm);
- if (n == REPLY_CONTINUE || n == REPLY_COMPLETE) {
- if (!quiet)
- printf("SSL accepted as authentication type\n");
- auth_type = "SSL";
- ssl_auth();
- if (ssl_ftp_active_flag) {
- ftp_dpl = FPL_PRV;
- ftp_cpl = FPL_PRV;
- setprotbuf(1<<20);
- return(1);
- } else {
- fprintf(stderr,"SSL authentication failed\n");
- auth_type = NULL;
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(csocket, 1+1);
-#endif /* USE_SHUTDOWN */
- close(csocket);
-#endif /* TCPIPLIB */
- csocket = -1;
- if (ftp_hookup(ftp_user_host,ftp_port,0) == NULL)
- return(0);
- }
- } else {
- if (ftp_deb)
- fprintf(stderr, "SSL rejected as an authentication type\n");
- if (ftpcode == 500 || ftpcode == 502)
- return(0);
- }
- }
-#endif /* CK_SSL */
- /* Other auth types go here ... */
- } /* for (j;;) */
- return(0);
-}
-#endif /* FTP_SECURITY */
-
-static int
-#ifdef CK_ANSIC
-setprotbuf(unsigned int size)
-#else
-setprotbuf(size) unsigned int size;
-#endif /* CK_ANSIC */
-/* setprotbuf */ {
- if (ucbuf)
- free(ucbuf);
- ucbuf = NULL;
- ucbufsiz = 0;
- actualbuf = size;
- while ((ucbuf = (CHAR *)malloc(actualbuf)) == NULL) {
- if (actualbuf)
- actualbuf /= 2;
- else
- return(0);
- }
- ucbufsiz = actualbuf - FUDGE_FACTOR;
- debug(F101,"setprotbuf ucbufsiz","",ucbufsiz);
- if (ucbufsiz < 128) {
- printf("WARNING: tiny ucbufsiz: %d\n",ucbufsiz);
- } else if (ucbufsiz < 0) {
- printf("ERROR: ucbuf allocation failure\n");
- return(-1);
- }
- maxbuf = actualbuf;
- return(1);
-}
-
-static int
-#ifdef CK_ANSIC
-setpbsz(unsigned int size)
-#else
-setpbsz(size) unsigned int size;
-#endif /* CK_ANSIC */
-/* setpbsz */ {
- if (!setprotbuf(size)) {
- perror("?Error while trying to malloc PROT buffer:");
-#ifdef FTP_SRP
- srp_reset();
-#endif /* FTP_SRP */
- ftpclose();
- return(-1);
- }
- reply_parse = "PBSZ=";
- ckmakmsg(ftpcmdbuf,FTP_BUFSIZ,"PBSZ ",
-#ifdef CK_SSL
- ssl_ftp_active_flag ? "0" :
-#endif /* CK_SSL */
- ckuitoa(actualbuf),NULL,NULL);
- if (ftpcmd(ftpcmdbuf,NULL,0,0,0) != REPLY_COMPLETE) {
- if (connected) {
- printf("?Unable to negotiate PROT buffer size with FTP server\n");
- ftpclose();
- }
- return(-1);
- }
- if (reply_parse) {
- if ((maxbuf = (unsigned int) atol(reply_parse)) > actualbuf)
- maxbuf = actualbuf;
- } else
- maxbuf = actualbuf;
- ucbufsiz = maxbuf - FUDGE_FACTOR;
- debug(F101,"setpbsz ucbufsiz","",ucbufsiz);
- reply_parse = NULL;
- return(0);
-}
-
-static VOID
-cancel_remote(din) int din; {
- CHAR buf[FTP_BUFSIZ];
- int x, nfnd;
-#ifdef BSDSELECT
- fd_set mask;
-#endif /* BSDSELECT */
-#ifdef IBMSELECT
- int fds[2], fdcnt = 0;
-#endif /* IBMSELECT */
-#ifdef DEBUG
- extern int debtim;
- int xdebtim;
- xdebtim = debtim;
- debtim = 1;
-#endif /* DEBUG */
- debug(F100,"ftp cancel_remote entry","",0);
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- /*
- * Send Telnet IP, Telnet DM but do so inline and within the
- * TLS channel
- */
- int count, error;
-
- buf[0] = IAC;
- buf[1] = TN_IP;
- buf[2] = IAC;
- buf[3] = TN_DM;
- buf[4] = NUL;
-
- count = SSL_write(ssl_ftp_con, buf, 4);
- debug(F111,"ftp cancel_remote","SSL_write(IAC IP IAC DM)",count);
- error = SSL_get_error(ssl_ftp_con,count);
- debug(F111,"ftp cancel_remote","SSL_get_error()",error);
- switch (error) {
- case SSL_ERROR_NONE:
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
-#ifdef NT
- {
- int gle = GetLastError();
- }
-#endif /* NT */
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- lostpeer();
- return;
- }
- } else
-#endif /* CK_SSL */
- {
- /*
- * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
- * after urgent byte rather than before as is protocol now.
- */
- buf[0] = IAC;
- buf[1] = TN_IP;
- buf[2] = IAC;
- buf[3] = NUL;
- if ((x = send(csocket, (SENDARG2TYPE)buf, 3, MSG_OOB)) != 3)
- perror("cancel");
- debug(F101,"ftp cancel_remote send 1","",x);
- buf[0] = TN_DM;
- x = send(csocket,(SENDARG2TYPE)buf,1,0);
- debug(F101,"ftp cancel_remote send 2","",x);
- }
- x = scommand("ABOR");
- debug(F101,"ftp cancel_remote scommand","",x);
-#ifdef BSDSELECT
- FD_ZERO(&mask);
- FD_SET(csocket, &mask);
- if (din) {
- FD_SET(din, &mask);
- }
- nfnd = empty(&mask, 10);
- debug(F101,"ftp cancel_remote empty","",nfnd);
- if ((nfnd) <= 0) {
- if (nfnd < 0) {
- perror("cancel");
- }
-#ifdef FTP_PROXY
- if (ptabflg)
- ftpcode = -1;
-#endif /* FTP_PROXY */
- lostpeer();
- }
- debug(F110,"ftp cancel_remote","D",0);
- if (din && FD_ISSET(din, &mask)) {
- /* Security: No threat associated with this read. */
- /* But you can't simply read the TLS data stream */
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- int count, error;
- while ((count = SSL_read(ssl_ftp_data_con, buf, FTP_BUFSIZ)) > 0)
- /* LOOP */ ;
- } else
-#endif /* CK_SSL */
- {
- while (recv(din, (SENDARG2TYPE)buf, FTP_BUFSIZ,0) > 0)
- /* LOOP */ ;
- }
- }
- debug(F110,"ftp cancel_remote","E",0);
-#else /* BSDSELECT */
-#ifdef IBMSELECT
- fds[0] = csocket;
- fdcnt++;
- if (din) {
- fds[1] = din;
- fdcnt++;
- }
- nfnd = empty(fds, fdcnt, 10);
- debug(F101,"ftp cancel_remote empty","",nfnd);
- if ((nfnd) <= 0) {
- if (nfnd < 0) {
- perror("cancel");
- }
-#ifdef FTP_PROXY
- if (ptabflg)
- ftpcode = -1;
-#endif /* FTP_PROXY */
- lostpeer();
- }
- debug(F110,"ftp cancel_remote","D",0);
- if (din && select(&din, 1,0,0,1) ) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- int count, error;
- while ((count = SSL_read(ssl_ftp_data_con, buf, FTP_BUFSIZ)) > 0)
- /* LOOP */ ;
- } else
-#endif /* CK_SSL */
- {
- while (recv(din, (SENDARG2TYPE)buf, FTP_BUFSIZ,0) > 0)
- /* LOOP */ ;
- }
- }
- debug(F110,"ftp cancel_remote","E",0);
-#else /* IBMSELECT */
- Some form of select is required.
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
- if (getreply(0,-1,-1,ftp_vbm,0) == REPLY_ERROR && ftpcode == 552) {
- debug(F110,"ftp cancel_remote","F",0);
- /* 552 needed for NIC style cancel */
- getreply(0,-1,-1,ftp_vbm,0);
- debug(F110,"ftp cancel_remote","G",0);
- }
- debug(F110,"ftp cancel_remote","H",0);
- getreply(0,-1,-1,ftp_vbm,0);
- debug(F110,"ftp cancel_remote","I",0);
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
-}
-
-static int
-fts_dpl(x) int x; {
- if (!auth_type
-#ifdef OS2
- || !ck_crypt_is_installed()
-#endif /* OS2 */
- ) {
- switch ( x ) {
- case FPL_PRV:
- printf("?Cannot set protection level to PRIVATE\n");
- return(0);
- case FPL_SAF:
- printf("?Cannot set protection level to SAFE\n");
- return(0);
- }
- ftp_dpl = x;
- return(1);
- }
-
-#ifdef CK_SSL
- if (x == FPL_SAF &&
- (!strcmp(auth_type,"SSL") || !strcmp(auth_type,"TLS"))) {
- printf("Cannot set protection level to safe\n");
- return(0);
- }
-#endif /* CK_SSL */
- /* Start with a PBSZ of 1 meg */
- if (x != FPL_CLR) {
- if (setpbsz(DEFAULT_PBSZ) < 0)
- return(0);
- }
- y = ftpcmd(x == FPL_CLR ? "PROT C" :
- (x == FPL_SAF ? "PROT S" : "PROT P"), NULL, 0, 0,ftp_vbm);
- if (y == REPLY_COMPLETE) {
- ftp_dpl = x;
- return(1);
- }
- return(0);
-}
-
-static int
-fts_cpl(x) int x; {
- if (!auth_type
-#ifdef OS2
- || !ck_crypt_is_installed()
-#endif /* OS2 */
- ) {
- switch ( x ) {
- case FPL_PRV:
- printf("?Cannot set protection level to PRIVATE\n");
- return(0);
- case FPL_SAF:
- printf("?Cannot set protection level to SAFE\n");
- return(0);
- }
- ftp_cpl = x;
- return(1);
- }
- if (x == FPL_CLR) {
- y = ftpcmd("CCC",NULL,0,0,ftp_vbm);
- if (y == REPLY_COMPLETE) {
- ftp_cpl = x;
- return(1);
- }
- return(0);
- }
- ftp_cpl = x;
- return(1);
-}
-
-#ifdef FTP_GSSAPI
-static VOID
-user_gss_error(maj_stat, min_stat, s)
- OM_uint32 maj_stat, min_stat;
- char *s;
-{
- /* a lot of work just to report the error */
- OM_uint32 gmaj_stat, gmin_stat, msg_ctx;
- gss_buffer_desc msg;
- msg_ctx = 0;
- while (!msg_ctx) {
- gmaj_stat = gss_display_status(&gmin_stat, maj_stat,
- GSS_C_GSS_CODE,
- GSS_C_NULL_OID,
- &msg_ctx,
- &msg
- );
- if ((gmaj_stat == GSS_S_COMPLETE)||
- (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
- fprintf(stderr, "GSSAPI error major: %s\n",
- (char*)msg.value);
- gss_release_buffer(&gmin_stat, &msg);
- }
- if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
- break;
- }
- msg_ctx = 0;
- while (!msg_ctx) {
- gmaj_stat = gss_display_status(&gmin_stat, min_stat,
- GSS_C_MECH_CODE,
- GSS_C_NULL_OID,
- &msg_ctx,
- &msg
- );
- if ((gmaj_stat == GSS_S_COMPLETE)||
- (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
- fprintf(stderr, "GSSAPI error minor: %s\n", (char*)msg.value);
- gss_release_buffer(&gmin_stat, &msg);
- }
- if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
- break;
- }
- fprintf(stderr, "GSSAPI error: %s\n", s);
-}
-#endif /* FTP_GSSAPI */
-
-#ifndef NOMHHOST
-#ifdef datageneral
-#define NOMHHOST
-#else
-#ifdef HPUX5WINTCP
-#define NOMHHOST
-#endif /* HPUX5WINTCP */
-#endif /* datageneral */
-#endif /* NOMHHOST */
-
-#ifdef INADDRX
-static struct in_addr inaddrx;
-#endif /* INADDRX */
-
-static char *
-ftp_hookup(host, port, tls) char * host; int port; int tls; {
- register struct hostent *hp = 0;
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- int tos;
-#endif /* IPTOS_THROUGHPUT */
-#endif /* IP_TOS */
- int s;
- GSOCKNAME_T len;
- static char hostnamebuf[MAXHOSTNAMELEN];
- char hostname[MAXHOSTNAMELEN] /* , *p, *q */ ;
- int cport;
-#ifdef DEBUG
- extern int debtim;
- int xdebtim;
- xdebtim = debtim;
- debtim = 1;
-#endif /* DEBUG */
-
- debug(F111,"ftp_hookup",host,port);
-
-#ifndef NOHTTP
- if (tcp_http_proxy) {
- struct servent *destsp;
- char *p, *q;
-
- ckmakmsg(proxyhost,HTTPCPYL,host,":",ckuitoa(port),NULL);
- for (p = tcp_http_proxy, q = hostname;
- *p != '\0' && *p != ':';
- p++, q++
- )
- *q = *p;
- *q = '\0';
-
- if (*p == ':')
- p++;
- else
- p = "http";
-
- destsp = getservbyname(p,"tcp");
- if (destsp)
- cport = ntohs(destsp->s_port);
- else if (p) {
- cport = atoi(p);
- } else
- cport = 80;
- } else
-#endif /* NOHTTP */
- {
- ckstrncpy(hostname,host,MAXHOSTNAMELEN);
- cport = port;
- }
- memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
- hisctladdr.sin_addr.s_addr = inet_addr(host);
- if (hisctladdr.sin_addr.s_addr != INADDR_NONE) /* 2010-03-29 */
- {
- debug(F110,"ftp hookup A",hostname,0);
- hisctladdr.sin_family = AF_INET;
- ckstrncpy(hostnamebuf, hostname, MAXHOSTNAMELEN);
- } else {
- debug(F110,"ftp hookup B",hostname,0);
- hp = gethostbyname(hostname);
-#ifdef HADDRLIST
- hp = ck_copyhostent(hp); /* make safe copy that won't change */
-#endif /* HADDRLIST */
- if (hp == NULL) {
- fprintf(stderr, "ftp: %s: Unknown host\n", host);
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return((char *) 0);
- }
- hisctladdr.sin_family = hp->h_addrtype;
-#ifdef HADDRLIST
- memcpy((char *)&hisctladdr.sin_addr, hp->h_addr_list[0],
- sizeof(hisctladdr.sin_addr));
-#else /* HADDRLIST */
- memcpy((char *)&hisctladdr.sin_addr, hp->h_addr,
- sizeof(hisctladdr.sin_addr));
-#endif /* HADDRLIST */
- ckstrncpy(hostnamebuf, hp->h_name, MAXHOSTNAMELEN);
- }
- debug(F110,"ftp hookup C",hostnamebuf,0);
- ftp_host = hostnamebuf;
- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- debug(F101,"ftp hookup socket","",s);
- if (s < 0) {
- perror("ftp: socket");
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(0);
- }
- hisctladdr.sin_port = htons(cport);
- errno = 0;
-
-#ifdef COMMENT
- printf("hisctladdr=%d\n",sizeof(hisctladdr));
- printf("hisctladdr.sin_addr=%d\n",sizeof(hisctladdr.sin_addr));
- printf("sockaddr_in=%d\n",sizeof(struct sockaddr_in));
- printf("hisctladdr.sin_addr.s_addr=%d\n",sizeof(hisctladdr.sin_addr.s_addr));
-#endif /* COMMENT */
-
-#ifdef HADDRLIST
- debug(F100,"ftp hookup HADDRLIST","",0);
- while
-#else
- debug(F100,"ftp hookup no HADDRLIST","",0);
- if
-#endif /* HADDRLIST */
- (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
- debug(F101,"ftp hookup connect failed","",errno);
-#ifdef HADDRLIST
- if (hp && hp->h_addr_list[1]) {
- int oerrno = errno;
-
- fprintf(stderr, "ftp: connect to address %s: ",
- inet_ntoa(hisctladdr.sin_addr));
- errno = oerrno;
- perror((char *) 0);
- hp->h_addr_list++;
- memcpy((char *)&hisctladdr.sin_addr,
- hp->h_addr_list[0],
- sizeof(hisctladdr.sin_addr));
- fprintf(stdout, "Trying %s...\n",
- inet_ntoa(hisctladdr.sin_addr));
-#ifdef TCPIPLIB
- socket_close(s);
-#else /* TCPIPLIB */
- close(s);
-#endif /* TCPIPLIB */
- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- if (s < 0) {
- perror("ftp: socket");
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(0);
- }
- continue;
- }
-#endif /* HADDRLIST */
- perror("ftp: connect");
- ftpcode = -1;
- goto bad;
- }
- debug(F100,"ftp hookup connect ok","",0);
-
- len = sizeof (myctladdr);
- errno = 0;
- if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
- debug(F101,"ftp hookup getsockname failed","",errno);
- perror("ftp: getsockname");
- ftpcode = -1;
- goto bad;
- }
- debug(F100,"ftp hookup getsockname ok","",0);
-
-#ifndef NOHTTP
- if (tcp_http_proxy) {
-#ifdef OS2
- char * agent = "Kermit 95"; /* Default user agent */
-#else
- char * agent = "C-Kermit";
-#endif /* OS2 */
-
- if (http_connect(s,agent,NULL,
- tcp_http_proxy_user,
- tcp_http_proxy_pwd,
- 0,
- proxyhost
- ) < 0) {
- char * foo = NULL;
-#ifdef TCPIPLIB
- socket_close(s);
-#else /* TCPIPLIB */
- close(s);
-#endif /* TCPIPLIB */
-
- while (foo == NULL && tcp_http_proxy != NULL ) {
-
- if (tcp_http_proxy_errno == 401 ||
- tcp_http_proxy_errno == 407 ) {
- char uid[UIDBUFLEN];
- char pwd[PWDSIZ];
- struct txtbox tb[2];
- int ok;
-
- tb[0].t_buf = uid;
- tb[0].t_len = UIDBUFLEN;
- tb[0].t_lbl = "Proxy Userid: ";
- tb[0].t_dflt = NULL;
- tb[0].t_echo = 1;
- tb[1].t_buf = pwd;
- tb[1].t_len = 256;
- tb[1].t_lbl = "Proxy Passphrase: ";
- tb[1].t_dflt = NULL;
- tb[1].t_echo = 2;
-
- ok = uq_mtxt("Proxy Server Authentication Required\n",
- NULL, 2, tb);
-
- if (ok && uid[0]) {
- char * proxy_user, * proxy_pwd;
-
- proxy_user = tcp_http_proxy_user;
- proxy_pwd = tcp_http_proxy_pwd;
-
- tcp_http_proxy_user = uid;
- tcp_http_proxy_pwd = pwd;
-
- foo = ftp_hookup(host, port, 0);
-
- debug(F110,"ftp_hookup()",foo,0);
- memset(pwd,0,PWDSIZ);
- tcp_http_proxy_user = proxy_user;
- tcp_http_proxy_pwd = proxy_pwd;
- } else
- break;
- } else
- break;
- }
- if (foo != NULL)
- return(foo);
- perror("ftp: connect");
- ftpcode = -1;
- goto bad;
- }
- ckstrncpy(hostnamebuf, proxyhost, MAXHOSTNAMELEN);
- }
-#endif /* NOHTTP */
-
- csocket = s;
-
-#ifdef CK_SSL
- if (tls) {
- /* FTP over SSL
- * If the connection is over an SSL proxy then the
- * auth_type will be NULL. However, I'm not sure
- * whether we should protect the data channel in
- * that case or not.
- */
-
- debug(F100,"ftp hookup use_tls","",0);
- if (!ssl_auth()) {
- debug(F100,"ftp hookup ssl_auth failed","",0);
- auth_type = NULL;
- ftpcode = -1;
- csocket = -1;
- goto bad;
- }
- ssl_ftp_proxy = 1;
- }
-#endif /* CK_SSL */
-
-#ifdef IP_TOS
-#ifdef IPTOS_LOWDELAY
- tos = IPTOS_LOWDELAY;
- if (setsockopt(csocket, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
- perror("ftp: setsockopt TOS (ignored)");
-#endif
-#endif
- if (!quiet)
- printf("Connected to %s.\n", host);
-
- /* Read greeting from server */
- if (getreply(0,ftp_csl,ftp_csr,ftp_vbm,0) > 2) {
- debug(F100,"ftp hookup bad reply","",0);
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
- close(csocket);
-#endif /* TCPIPLIB */
- ftpcode = -1;
- goto bad;
- }
-#ifdef SO_OOBINLINE
- {
- int on = 1;
- errno = 0;
- if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on,
- sizeof(on)) < 0) {
- perror("ftp: setsockopt");
- debug(F101,"ftp hookup setsockopt failed","",errno);
- }
-#ifdef DEBUG
- else
- debug(F100,"ftp hookup setsockopt ok","",0);
-#endif /* DEBUG */
- }
-#endif /* SO_OOBINLINE */
-
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(ftp_host);
-
- bad:
- debug(F100,"ftp hookup bad","",0);
-#ifdef TCPIPLIB
- socket_close(s);
-#else /* TCPIPLIB */
- close(s);
-#endif /* TCPIPLIB */
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- csocket = -1;
- return((char *)0);
-}
-
-static VOID
-ftp_init() {
- int i, n;
-
- /* The purpose of the initial REST 0 is not clear, but other FTP */
- /* clients do it. In any case, failure of this command is not a */
- /* reliable indication that the server does not support Restart. */
-
- okrestart = 0;
- if (!noinit) {
- n = ftpcmd("REST 0",NULL,0,0,0);
- if (n == REPLY_COMPLETE)
- okrestart = 1;
-#ifdef COMMENT
- else if (ftp_deb)
- printf("WARNING: Unable to restore file pointer.\n");
-#endif /* COMMENT */
- }
- n = ftpcmd("SYST",NULL,0,0,0); /* Get server system type */
- if (n == REPLY_COMPLETE) {
- register char *cp, c = NUL;
- cp = ckstrchr(ftp_reply_str+4,' '); /* Get first word of reply */
- if (cp == NULL)
- cp = ckstrchr(ftp_reply_str+4,'\r');
- if (cp) {
- if (cp[-1] == '.')
- cp--;
- c = *cp; /* Save this char */
- *cp = '\0'; /* Replace it with NUL */
- }
- if (!quiet)
- printf("Remote system type is %s.\n",ftp_reply_str+4);
- ckstrncpy(ftp_srvtyp,ftp_reply_str+4,SRVNAMLEN);
- if (cp) /* Put back saved char */
- *cp = c;
- }
- alike = !ckstrcmp(ftp_srvtyp,myostype,-1,0);
-
- if (!ckstrcmp(ftp_srvtyp,"UNIX",-1,0)) servertype = SYS_UNIX;
- else if (!ckstrcmp(ftp_srvtyp,"WIN32",-1,0)) servertype = SYS_WIN32;
- else if (!ckstrcmp(ftp_srvtyp,"OS/2",-1,0)) servertype = SYS_WIN32;
- else if (!ckstrcmp(ftp_srvtyp,"VMS",-1,0)) servertype = SYS_VMS;
- else if (!ckstrcmp(ftp_srvtyp,"DOS",-1,0)) servertype = SYS_DOS;
- else if (!ckstrcmp(ftp_srvtyp,"TOPS20",-1,0)) servertype = SYS_TOPS20;
- else if (!ckstrcmp(ftp_srvtyp,"TOPS10",-1,0)) servertype = SYS_TOPS10;
-
-#ifdef FTP_PROXY
- unix_proxy = 0;
- if (servertype == SYS_UNIX && proxy) unix_proxy = 1;
-#endif /* FTP_PROXY */
-
- if (ftp_cmdlin && ftp_xfermode == XMODE_M)
- ftp_typ = binary; /* Type given on command line */
- else /* Otherwise set it automatically */
- ftp_typ = alike ? FTT_BIN : FTT_ASC;
- changetype(ftp_typ,0); /* Change to this type */
- g_ftp_typ = ftp_typ; /* Make it the global type */
- if (!quiet)
- printf("Default transfer mode is %s\n",
- ftp_typ ? "BINARY" : "TEXT (\"ASCII\")"
- );
- for (i = 0; i < 16; i++) /* Init server FEATure table */
- sfttab[i] = 0;
- if (!noinit) {
- n = ftpcmd("MODE S",NULL,0,0,0); /* We always send in Stream mode */
-#ifdef COMMENT
- if (n != REPLY_COMPLETE)
- printf("WARNING: Server does not accept MODE S(TREAM)\n");
-#endif /* COMMENT */
- n = ftpcmd("STRU F",NULL,0,0,0); /* STRU File (not Record or Page) */
-#ifdef COMMENT
- if (n != REPLY_COMPLETE)
- printf("WARNING: Server does not accept STRU F(ILE)\n");
-#endif /* COMMENT */
- if (featok) {
- n = ftpcmd("FEAT",NULL,0,0,0); /* Ask server about features */
- if (n == REPLY_COMPLETE) {
- debug(F101,"ftp_init FEAT","",sfttab[0]);
- if (deblog || ftp_deb) {
- int i;
- for (i = 1; i < 16 && i < nfeattab; i++) {
- debug(F111,"ftp_init FEAT",feattab[i].kwd,sfttab[i]);
- if (ftp_deb)
- printf(" Server %s %s\n",
- sfttab[i] ? "supports" : "does not support",
- feattab[i].kwd
- );
- }
- /* Deal with disabled MLST opts here if necessary */
- /* But why would it be? */
- }
- }
- }
- }
-}
-
-static int
-ftp_login(host) char * host; { /* (also called from ckuusy.c) */
- static char ftppass[PASSBUFSIZ]="";
- char tmp[PASSBUFSIZ];
- char *user = NULL, *pass = NULL, *acct = NULL;
- int n, aflag = 0;
- extern char uidbuf[];
- extern char pwbuf[];
- extern int pwflg, pwcrypt;
-
- debug(F111,"ftp_login",ftp_logname,ftp_log);
-
- if (!ckstrcmp(ftp_logname,"anonymous",-1,0))
- anonymous = 1;
- if (!ckstrcmp(ftp_logname,"ftp",-1,0))
- anonymous = 1;
-
-#ifdef FTP_SRP
- if (auth_type && !strcmp(auth_type, "SRP")) {
- user = srp_user;
- pass = srp_pass;
- acct = srp_acct;
- } else
-#endif /* FTP_SRP */
- if (anonymous) {
- user = "anonymous";
- if (ftp_tmp) { /* They gave a password */
- pass = ftp_tmp;
- } else if (ftp_apw) { /* SET FTP ANONYMOUS-PASSWORD */
- pass = ftp_apw;
- } else { /* Supply user@host */
- ckmakmsg(tmp,PASSBUFSIZ,whoami(),"@",myhost,NULL);
- pass = tmp;
- }
- debug(F110,"ftp anonymous",pass,0);
- } else {
-#ifdef USE_RUSERPASS
- if (ruserpass(host, &user, &pass, &acct) < 0) {
- ftpcode = -1;
- return(0);
- }
-#endif /* USE_RUSERPASS */
- if (ftp_logname) {
- user = ftp_logname;
- pass = ftp_tmp;
- } else if (uidbuf[0] && (ftp_tmp || pwbuf[0] && pwflg)) {
- user = uidbuf;
- if (ftp_tmp) {
- pass = ftp_tmp;
- } else if (pwbuf[0] && pwflg) {
- ckstrncpy(ftppass,pwbuf,PASSBUFSIZ);
-#ifdef OS2
- if ( pwcrypt )
- ck_encrypt((char *)ftppass);
-#endif /* OS2 */
- pass = ftppass;
- }
- }
- acct = ftp_acc;
- while (user == NULL) {
- char *myname, prompt[PROMPTSIZ];
- int ok;
-
- myname = whoami();
- if (myname)
- ckmakxmsg(prompt,PROMPTSIZ," Name (",host,":",myname,"): ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- else
- ckmakmsg(prompt,PROMPTSIZ," Name (",host,"): ",NULL);
- tmp[0] = '\0';
-
- ok = uq_txt(NULL,prompt,1,NULL,tmp,PASSBUFSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (!ok || *tmp == '\0')
- user = myname;
- else
- user = brstrip(tmp);
- }
- }
- n = ftpcmd("USER",user,-1,-1,ftp_vbm);
- if (n == REPLY_COMPLETE) {
- /* determine if we need to send a dummy password */
- if (ftpcmd("PWD",NULL,0,0,0) != REPLY_COMPLETE)
- ftpcmd("PASS dummy",NULL,0,0,1);
- } else if (n == REPLY_CONTINUE) {
-#ifdef CK_ENCRYPTION
- int oldftp_cpl;
-#endif /* CK_ENCRYPTION */
-
- if (pass == NULL) {
- int ok;
- setint();
- ok = uq_txt(NULL," Password: ",2,NULL,ftppass,PASSBUFSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (ok)
- pass = brstrip(ftppass);
- }
-
-#ifdef CK_ENCRYPTION
- oldftp_cpl = ftp_cpl;
- ftp_cpl = FPL_PRV;
-#endif /* CK_ENCRYPTION */
- n = ftpcmd("PASS",pass,-1,-1,1);
- if (!anonymous && pass) {
- char * p = pass;
- while (*p++) *(p-1) = NUL;
- makestr(&ftp_tmp,NULL);
- }
-#ifdef CK_ENCRYPTION
- /* level may have changed */
- if (ftp_cpl == FPL_PRV)
- ftp_cpl = oldftp_cpl;
-#endif /* CK_ENCRYPTION */
- }
- if (n == REPLY_CONTINUE) {
- aflag++;
- if (acct == NULL) {
- static char ftpacct[80];
- int ok;
- setint();
- ok = uq_txt(NULL," Account: ",2,NULL,ftpacct,80,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (ok)
- acct = brstrip(ftpacct);
- }
- n = ftpcmd("ACCT",acct,-1,-1,ftp_vbm);
- }
- if (n != REPLY_COMPLETE) {
- fprintf(stderr, "FTP login failed.\n");
- if (haveurl)
- doexit(BAD_EXIT,-1);
- return(0);
- }
- if (!aflag && acct != NULL) {
- ftpcmd("ACCT",acct,-1,-1,ftp_vbm);
- }
- makestr(&ftp_logname,user);
- loggedin = 1;
-#ifdef LOCUS
- /* Unprefixed file management commands go to server */
- if (autolocus && !ftp_cmdlin) {
- setlocus(0,1);
- }
-#endif /* LOCUS */
- ftp_init();
-
- if (anonymous && !quiet) {
- printf(" Logged in as anonymous (%s)\n",pass);
- memset(pass, 0, strlen(pass));
- }
- if (ftp_rdir) {
- if (doftpcwd(ftp_rdir,-1) < 1)
- doexit(BAD_EXIT,-1);
- }
-
-#ifdef FTP_PROXY
- if (proxy)
- return(1);
-#endif /* FTP_PROXY */
- return(1);
-}
-
-static int
-ftp_reset() {
- int rc;
-#ifdef BSDSELECT
- int nfnd = 1;
- fd_set mask;
- FD_ZERO(&mask);
- while (nfnd > 0) {
- FD_SET(csocket, &mask);
- if ((nfnd = empty(&mask,0)) < 0) {
- perror("reset");
- ftpcode = -1;
- lostpeer();
- return(0);
- } else if (nfnd) {
- getreply(0,-1,-1,ftp_vbm,0);
- }
- }
-#else /* BSDSELECT */
-#ifdef IBMSELECT
- int nfnd = 1;
- while (nfnd > 0) {
- if ((nfnd = empty(&csocket,1,0)) < 0) {
- perror("reset");
- ftpcode = -1;
- lostpeer();
- return(0);
- } else if (nfnd) {
- getreply(0,-1,-1,ftp_vbm,0);
- }
- }
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
- rc = (ftpcmd("REIN",NULL,0,0,ftp_vbm) == REPLY_COMPLETE);
- if (rc > 0)
- loggedin = 0;
- return(rc);
-}
-
-static int
-ftp_rename(from, to) char * from, * to; {
- int lcs = -1, rcs = -1;
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
- if (ftpcmd("RNFR",from,lcs,rcs,ftp_vbm) == REPLY_CONTINUE) {
- return(ftpcmd("RNTO",to,lcs,rcs,ftp_vbm) == REPLY_COMPLETE);
- }
- return(0); /* Failure */
-}
-
-static int
-ftp_umask(mask) char * mask; {
- int rc;
- rc = (ftpcmd("SITE UMASK",mask,-1,-1,1) == REPLY_COMPLETE);
- return(rc);
-}
-
-static int
-ftp_user(user,pass,acct) char * user, * pass, * acct; {
- int n = 0, aflag = 0;
- char pwd[PWDSIZ];
-
- if (!auth_type && ftp_aut) {
-#ifdef FTP_SRP
- if (ck_srp_is_installed()) {
- if (srp_ftp_auth( NULL, user, pass)) {
- makestr(&pass,srp_pass);
- }
- }
-#endif /* FTP_SRP */
- }
- n = ftpcmd("USER",user,-1,-1,ftp_vbm);
- if (n == REPLY_COMPLETE)
- n = ftpcmd("PASS dummy",NULL,0,0,1);
- else if (n == REPLY_CONTINUE) {
-#ifdef CK_ENCRYPTION
- int oldftp_cpl;
-#endif /* CK_ENCRYPTION */
- if (pass == NULL || !pass[0]) {
- int ok;
- pwd[0] = '\0';
- setint();
- ok = uq_txt(NULL," Password: ",2,NULL,pwd,PWDSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (ok)
- pass = brstrip(pwd);
- }
-
-#ifdef CK_ENCRYPTION
- if ((oldftp_cpl = ftp_cpl) == PROT_S)
- ftp_cpl = PROT_P;
-#endif /* CK_ENCRYPTION */
- n = ftpcmd("PASS",pass,-1,-1,1);
- memset(pass, 0, strlen(pass));
-#ifdef CK_ENCRYPTION
- /* level may have changed */
- if (ftp_cpl == PROT_P)
- ftp_cpl = oldftp_cpl;
-#endif /* CK_ENCRYPTION */
- }
- if (n == REPLY_CONTINUE) {
- if (acct == NULL || !acct[0]) {
- int ok;
- pwd[0] = '\0';
- setint();
- ok = uq_txt(NULL," Account: ",2,NULL,pwd,PWDSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (ok)
- acct = pwd;
- }
- n = ftpcmd("ACCT",acct,-1,-1,ftp_vbm);
- aflag++;
- }
- if (n != REPLY_COMPLETE) {
- printf("Login failed.\n");
- return(0);
- }
- if (!aflag && acct != NULL && acct[0]) {
- n = ftpcmd("ACCT",acct,-1,-1,ftp_vbm);
- }
- if (n == REPLY_COMPLETE) {
- makestr(&ftp_logname,user);
- loggedin = 1;
- ftp_init();
- return(1);
- }
- return(0);
-}
-
-char *
-ftp_authtype() {
- if (!connected)
- return("NULL");
- return(auth_type ? auth_type : "NULL");
-}
-
-char *
-ftp_cpl_mode() {
- switch (ftp_cpl) {
- case FPL_CLR:
- return("clear");
- case FPL_SAF:
- return("safe");
- case FPL_PRV:
- return("private");
- case FPL_CON:
- return("confidential");
- default:
- return("(error)");
- }
-}
-
-char *
-ftp_dpl_mode() {
- switch (ftp_dpl) {
- case FPL_CLR:
- return("clear");
- case FPL_SAF:
- return("safe");
- case FPL_PRV:
- return("private");
- case FPL_CON:
- return("confidential");
- default:
- return("(error)");
- }
-}
-
-
-/* remote_files() */
-/*
- Returns next remote filename on success;
- NULL on error or no more files with global rfrc set to:
- -1: Bad argument
- -2: Server error response to NLST, e.g. file not found
- -3: No more files
- -9: Internal error
-*/
-#define FTPNAMBUFLEN CKMAXPATH+1024
-
-/* Check: ckmaxfiles CKMAXOPEN */
-
-#define MLSDEPTH 128 /* Stack of open temp files */
-static int mlsdepth = 0; /* Temp file stack depth */
-static FILE * tmpfilptr[MLSDEPTH+1] = { NULL, NULL }; /* Temp file pointers */
-static char * tmpfilnam[MLSDEPTH+1] = { NULL, NULL }; /* Temp file names */
-
-static VOID
-mlsreset() { /* Reset MGET temp-file stack */
- int i;
- for (i = 0; i <= mlsdepth; i++) {
- if (tmpfilptr[i]) {
- fclose(tmpfilptr[i]);
- tmpfilptr[i] = NULL;
- if (tmpfilnam[i]) {
-#ifdef OS2
- unlink(tmpfilnam[i]);
-#endif /* OS2 */
- free(tmpfilnam[i]);
- }
- }
- }
- mlsdepth = 0;
-}
-
-static CHAR *
-#ifdef CK_ANSIC
-remote_files(int new_query, CHAR * arg, CHAR * pattern, int proxy_switch)
-#else /* CK_ANSIC */
-remote_files(new_query, arg, pattern, proxy_switch)
- int new_query;
- CHAR * arg; /* That we send to the server */
- CHAR * pattern; /* That we use locally */
- int proxy_switch;
-#endif /* CK_ANSIC */
-/* remote_files */ {
- static CHAR buf[FTPNAMBUFLEN];
- CHAR *cp, *whicharg;
- char * cdto = NULL;
- char * p;
- int i, x, forced = 0;
- int lcs = 0, rcs = 0, xlate = 0;
-
- debug(F101,"ftp remote_files new_query","",new_query);
- debug(F110,"ftp remote_files arg",arg,0);
- debug(F110,"ftp remote_files pattern",pattern,0);
-
- rfrc = -1;
- if (pattern) /* Treat empty pattern same as NULL */
- if (!*pattern)
- pattern = NULL;
- if (arg) /* Ditto for arg */
- if (!*arg)
- arg = NULL;
-
- again:
-
- if (new_query) {
- if (tmpfilptr[mlsdepth]) {
- fclose(tmpfilptr[mlsdepth]);
- tmpfilptr[mlsdepth] = NULL;
-#ifdef OS2
- if (!ftp_deb && !deblog)
- unlink(tmpfilnam[mlsdepth]);
-#endif /* OS2 */
- }
- }
- if (tmpfilptr[mlsdepth] == NULL) {
- extern char * tempdir;
- char * p;
- debug(F110,"ftp remote_files tempdir",tempdir,0);
- if (tempdir) {
- p = tempdir;
- } else {
-#ifdef OS2
-#ifdef NT
- p = getenv("K95TMP");
-#else
- p = getenv("K2TMP");
-#endif /* NT */
- if (!p)
-#endif /* OS2 */
- p = getenv("CK_TMP");
- if (!p)
- p = getenv("TMPDIR");
- if (!p) p = getenv("TEMP");
- if (!p) p = getenv("TMP");
-#ifdef OS2ORUNIX
- if (p) {
- int len = strlen(p);
- if (p[len-1] != '/'
-#ifdef OS2
- && p[len-1] != '\\'
-#endif /* OS2 */
- ) {
- static char foo[CKMAXPATH];
- ckstrncpy(foo,p,CKMAXPATH);
- ckstrncat(foo,"/",CKMAXPATH);
- p = foo;
- }
- } else
-#else /* OS2ORUNIX */
- if (!p)
-#endif /* OS2ORUNIX */
-#ifdef UNIX /* Systems that have a standard */
- p = "/tmp/"; /* temporary directory... */
-#else
-#ifdef datageneral
- p = ":TMP:";
-#else
- p = "";
-#endif /* datageneral */
-#endif /* UNIX */
- }
- debug(F110,"ftp remote_files p",p,0);
-
- /* Get temp file */
-
- if ((tmpfilnam[mlsdepth] = (char *)malloc(CKMAXPATH+1))) {
- ckmakmsg((char *)tmpfilnam[mlsdepth],
- CKMAXPATH+1,p,"ckXXXXXX",NULL,NULL);
- } else {
- printf("?Malloc failure: remote_files()\n");
- return(NULL);
- }
-
-#ifdef NT
- {
- char * tmpfil = mktemp((char *)tmpfilnam[mlsdepth]);
- if ( tmpfil )
- ckstrncpy(tmpfilnam[mlsdepth],tmpfil,CKMAXPATH+1);
- }
-#else /* NT */
-#ifdef MKTEMP
-#ifdef MKSTEMP
- x = mkstemp((char *)tmpfilnam[mlsdepth]);
- if (x > -1) close(x); /* We just want the name. */
-#else
- mktemp((char *)tmpfilnam[mlsdepth]);
-#endif /* MKSTEMP */
- /* if no mktmpnam() the name will just be "ckXXXXXX"... */
-#endif /* MKTEMP */
-#endif /* NT */
-
- debug(F111,"ftp remote_files tmpfilnam[mlsdepth]",
- tmpfilnam[mlsdepth],mlsdepth);
-
-#ifdef FTP_PROXY
- if (proxy_switch) {
- pswitch(!proxy);
- }
-#endif /* FTP_PROXY */
-
- debug(F101,"ftp remote_files ftp_xla","",ftp_xla);
- debug(F101,"ftp remote_files ftp_csl","",ftp_csl);
- debug(F101,"ftp remote_files ftp_csr","",ftp_csr);
-
-#ifndef NOCSETS
- xlate = ftp_xla; /* SET FTP CHARACTER-SET-TRANSLATION */
- if (xlate) { /* ON? */
- lcs = ftp_csl; /* Local charset */
- if (lcs < 0) lcs = fcharset;
- if (lcs < 0) xlate = 0;
- }
- if (xlate) { /* Still ON? */
- rcs = ftp_csx; /* Remote (Server) charset */
- if (rcs < 0) rcs = ftp_csr;
- if (rcs < 0) xlate = 0;
- }
-#endif /* NOCSETS */
-
- forced = mgetforced; /* MGET method forced? */
- if (!forced || !mgetmethod) /* Not forced... */
- mgetmethod = (sfttab[0] && sfttab[SFT_MLST]) ? /* so pick one */
- SND_MLS :
- SND_NLS;
-/*
- User's Command: Result:
- mget /nlst NLST (NULL)
- mget /nlst foo NLST foo
- mget /nlst *.txt NLST *.txt
- mget /nlst /match:*.txt NLST (NULL)
- mget /nlst /match:*.txt foo NLST foo
- mget /mlsd MLSD (NULL)
- mget /mlsd foo MLSD foo
- mget /mlsd *.txt MLSD (NULL)
- mget /mlsd /match:*.txt MLSD (NULL)
- mget /mlsd /match:*.txt foo MLSD foo
-*/
- x = -1;
- while (x < 0) {
- if (pattern) { /* Don't simplify this! */
- whicharg = arg;
- } else if (mgetmethod == SND_MLS) {
- if (arg)
- whicharg = iswild((char *)arg) ? NULL : arg;
- else
- whicharg = NULL;
- } else {
- whicharg = arg;
- }
- debug(F110,"ftp remote_files mgetmethod",
- mgetmethod == SND_MLS ? "MLSD" : "NLST", 0);
- debug(F110,"ftp remote_files whicharg",whicharg,0);
-
- x = recvrequest((mgetmethod == SND_MLS) ? "MLSD" : "NLST",
- (char *)tmpfilnam[mlsdepth],
- (char *)whicharg,
- "wb",
- 0,
- 0,
- NULL,
- xlate,
- lcs,
- rcs
- );
- if (x < 0) { /* Chosen method wasn't accepted */
- if (forced) {
- if (ftpcode > 500 && ftpcode < 505 && !quiet)
- printf("?%s: Not supported by server\n",
- mgetmethod == SND_MLS ? "MLSD" : "NLST"
- );
- rfrc = -2; /* Fail */
- return(NULL);
- }
- /* Not forced - if MLSD failed, try NLST */
- if (mgetmethod == SND_MLS) { /* Server lied about MLST */
- sfttab[SFT_MLST] = 0; /* So disable it */
- mlstok = 0; /* and */
- mgetmethod = SND_NLS; /* try NLST */
- continue;
- }
- rfrc = -2;
- return(NULL);
- }
- }
-#ifdef FTP_PROXY
- if (proxy_switch) {
- pswitch(!proxy);
- }
-#endif /* FTP_PROXY */
- tmpfilptr[mlsdepth] = fopen((char *)tmpfilnam[mlsdepth], "r");
-#ifndef OS2
- if (tmpfilptr[mlsdepth]) {
- if (!ftp_deb && !deblog)
- unlink(tmpfilnam[mlsdepth]);
- }
-#endif /* OS2 */
- notemp:
- if (!tmpfilptr[mlsdepth]) {
- debug(F110,"ftp remote_files open fail",tmpfilnam[mlsdepth],0);
- if ((!dpyactive || ftp_deb))
- printf("?Can't find list of remote files, oops\n");
- rfrc = -9;
- return(NULL);
- }
- if (ftp_deb)
- printf("LISTFILE: %s\n",tmpfilnam[mlsdepth]);
- }
- buf[0] = NUL;
- buf[FTPNAMBUFLEN-1] = NUL;
- buf[FTPNAMBUFLEN-2] = NUL;
-
- /* We have to redo all this because the first time was only for */
- /* for getting the file list, now it's for getting each file */
-
- if (arg && mgetmethod == SND_MLS) { /* MLSD */
- if (!pattern && iswild((char *)arg)) {
- pattern = arg; /* Wild arg is really a pattern */
- if (pattern)
- if (!*pattern)
- pattern = NULL;
- arg = NULL; /* and not an arg */
- }
- if (new_query) { /* Initial query? */
- cdto = (char *)arg; /* (nonwild) arg given? */
- if (cdto)
- if (!*cdto)
- cdto = NULL;
- if (cdto) /* If so, then CD to it */
- doftpcwd(cdto,0);
- }
- }
- new_query = 0;
-
- if (fgets((char *)buf, FTPNAMBUFLEN, tmpfilptr[mlsdepth]) == NULL) {
- fclose(tmpfilptr[mlsdepth]);
- tmpfilptr[mlsdepth] = NULL;
-
-#ifdef OS2
- if (!ftp_deb && !deblog)
- unlink(tmpfilnam[mlsdepth]);
-#endif /* OS2 */
- if (ftp_deb && !deblog) {
- printf("(Temporary file %s NOT deleted)\n",
- (char *)tmpfilnam[mlsdepth]);
- }
- if (mlsdepth <= 0) { /* EOF at depth 0 */
- rfrc = -3; /* means we're done */
- return(NULL);
- }
- printf("POPPING(%d)...\n",mlsdepth-1);
- if (tmpfilnam[mlsdepth]) free(tmpfilnam[mlsdepth]);
- mlsdepth--;
- doftpcdup();
- zchdir(".."); /* <-- Not portable */
- goto again;
- }
- if (buf[FTPNAMBUFLEN-1]) {
- printf("?BUFFER OVERFLOW -- FTP NLST or MLSD string longer than %d\n",
- FTPNAMBUFLEN
- );
- debug(F101,"remote_files buffer overrun","",FTPNAMBUFLEN);
- return(NULL);
- }
- /* debug(F110,"ftp remote_files buf 1",buf,0); */
- if ((cp = (CHAR *)ckstrchr((char *)buf,'\n')) != NULL)
- *cp = '\0';
- if ((cp = (CHAR *)ckstrchr((char *)buf,'\r')) != NULL)
- *cp = '\0';
- debug(F110,"ftp remote_files buf",buf,0);
- rfrc = 0;
-
- if (ftp_deb)
- printf("[%s]\n",(char *)buf);
-
- havesize = (CK_OFF_T)-1; /* Initialize file facts... */
- havetype = 0;
- makestr(&havemdtm,NULL);
- p = (char *)buf;
-
- if (mgetmethod == SND_NLS) { /* NLST... */
- if (pattern) {
- if (!ckmatch((char *)pattern,p,(servertype == SYS_UNIX),1))
- goto again;
- }
- } else { /* MLSD... */
- p = parsefacts((char *)buf);
- switch (havetype) {
- case FTYP_FILE: /* File: Get it if it matches */
- if (pattern) {
- if (!ckmatch((char *)pattern,p,(servertype == SYS_UNIX),1))
- goto again;
- }
- break;
- case FTYP_CDIR: /* Current directory */
- case FTYP_PDIR: /* Parent directory */
- goto again; /* Skip */
- case FTYP_DIR: /* (Sub)Directory */
- if (!recursive) /* If not /RECURSIVE */
- goto again; /* Skip */
- if (mlsdepth < MLSDEPTH) {
- char * p2 = NULL;
- mlsdepth++;
- printf("RECURSING [%s](%d)...\n",p,mlsdepth);
- if (doftpcwd(p,0) > 0) {
- int x;
- if (!ckstrchr(p,'/')) {
- /* zmkdir() needs dirsep */
- if ((p2 = (char *)malloc((int)strlen(p) + 2))) {
- strcpy(p2,p); /* SAFE */
- strcat(p2,"/"); /* SAFE */
- p = p2;
- }
- }
-#ifdef NOMKDIR
- x = -1;
-#else
- x = zmkdir(p);
-#endif /* NOMKDIR */
- if (x > -1) {
- zchdir(p);
- p = (char *)remote_files(1,arg,pattern,0);
- if (p2) free(p2);
- } else {
- printf("?mkdir failed: [%s] Depth=%d\n",
- p,
- mlsdepth
- );
- mlsreset();
- if (p2) free(p2);
- return(NULL);
- }
- } else {
- printf("?CWD failed: [%s] Depth=%d\n",p,mlsdepth);
- mlsreset();
- return(NULL);
- }
- } else {
- printf("MAX DIRECTORY STACK DEPTH EXCEEDED: %d\n",
- mlsdepth
- );
- mlsreset();
- return(NULL);
- }
- }
- }
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"remote_files havesize","",havesize);
- debug(F101,"remote_files havetype","",havetype);
- debug(F110,"remote_files havemdtm",havemdtm,0);
- debug(F110,"remote_files name",p,0);
- }
-#endif /* DEBUG */
- return((CHAR *)p);
-}
-
-/* N O T P O R T A B L E !!! */
-
-#if (SIZEOF_SHORT == 4)
-typedef unsigned short ftp_uint32;
-typedef short ftp_int32;
-#else
-#if (SIZEOF_INT == 4)
-typedef unsigned int ftp_uint32;
-typedef int ftp_int32;
-#else
-#if (SIZEOF_LONG == 4)
-typedef ULONG ftp_uint32;
-typedef long ftp_int32;
-#endif
-#endif
-#endif
-
-/* Perhaps use these in general, certainly use them for GSSAPI */
-
-#ifndef looping_write
-#define ftp_int32 int
-#define ftp_uint32 unsigned int
-static int
-looping_write(fd, buf, len)
- int fd;
- register CONST char *buf;
- int len;
-{
- int cc;
- register int wrlen = len;
- do {
- cc = send(fd, (SENDARG2TYPE)buf, wrlen, 0);
- if (cc < 0) {
- if (errno == EINTR)
- continue;
- return(cc);
- } else {
- buf += cc;
- wrlen -= cc;
- }
- } while (wrlen > 0);
- return(len);
-}
-#endif
-#ifndef looping_read
-static int
-looping_read(fd, buf, len)
- int fd;
- register char *buf;
- register int len;
-{
- int cc, len2 = 0;
-
- do {
- cc = recv(fd, (char *)buf, len,0);
- if (cc < 0) {
- if (errno == EINTR)
- continue;
- return(cc); /* errno is already set */
- } else if (cc == 0) {
- return(len2);
- } else {
- buf += cc;
- len2 += cc;
- len -= cc;
- }
- } while (len > 0);
- return(len2);
-}
-#endif /* looping_read */
-
-#define ERR -2
-
-#ifdef COMMENT
-static
-secure_putbyte(fd, c) int fd; CHAR c; {
- int ret;
-
- ucbuf[nout++] = c;
- if (nout == (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR) {
- nout = 0;
- if (!ftpissecure())
- ret = send(fd, (SENDARG2TYPE)ucbuf,
- (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR, 0);
- else
- ret = secure_putbuf(fd,
- ucbuf,
- (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR
- );
- return(ret?ret:c);
- }
- return(c);
-}
-#endif /* COMMENT */
-
-/* returns:
- * 0 on success
- * -1 on error (errno set)
- * -2 on security error
- */
-static int
-secure_flush(fd) int fd; {
- int rc = 0;
- int len = 0;
-
- if (nout > 0) {
- len = nout;
- if (!ftpissecure()) {
- rc = send(fd, (SENDARG2TYPE)ucbuf, nout, 0);
- nout = 0;
- goto xflush;
- } else {
- rc = secure_putbuf(fd, ucbuf, nout);
- if (rc)
- goto xflush;
- }
- }
- rc = (!ftpissecure()) ? 0 : secure_putbuf(fd, (CHAR *)"", nout = 0);
-
- xflush:
- if (rc > -1 && len > 0 && fdispla != XYFD_B) {
- spackets++;
- spktl = len;
- ftscreen(SCR_PT,'D',(CK_OFF_T)spackets,NULL);
- }
- return(rc);
-}
-
-#ifdef COMMENT /* (not used) */
-/* returns:
- * c>=0 on success
- * -1 on error
- * -2 on security error
- */
-static int
-#ifdef CK_ANSIC
-secure_putc(char c, int fd)
-#else
-secure_putc(c, fd) char c; int fd;
-#endif /* CK_ANSIC */
-/* secure_putc */ {
- return(secure_putbyte(fd, (CHAR) c));
-}
-#endif /* COMMENT */
-
-/* returns:
- * nbyte on success
- * -1 on error (errno set)
- * -2 on security error
- */
-static int
-#ifdef CK_ANSIC
-secure_write(int fd, CHAR * buf, unsigned int nbyte)
-#else
-secure_write(fd, buf, nbyte)
- int fd;
- CHAR * buf;
- unsigned int nbyte;
-#endif /* CK_ANSIC */
-{
- int ret;
-
-#ifdef FTP_TIMEOUT
- ftp_timed_out = 0;
- if (check_data_connection(fd,1) < 0) {
- ftp_timed_out = 1;
- return(-3);
- }
-#endif /* FTP_TIMEOUT */
-
- if (!ftpissecure()) {
- if (nout > 0) {
- if ((ret = send(fd, (SENDARG2TYPE)ucbuf, nout, 0)) < 0)
- return(ret);
- nout = 0;
- }
- return(send(fd,(SENDARG2TYPE)buf,nbyte,0));
- } else {
- int ucbuflen = (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR;
- int bsent = 0;
-
- while (bsent < nbyte) {
- int b2cp = ((nbyte - bsent) > (ucbuflen - nout) ?
- (ucbuflen - nout) : (nbyte - bsent));
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"secure_write ucbuflen","",ucbuflen);
- debug(F101,"secure_write ucbufsiz","",ucbufsiz);
- debug(F101,"secure_write bsent","",bsent);
- debug(F101,"secure_write b2cp","",b2cp);
- }
-#endif /* DEBUG */
- memcpy(&ucbuf[nout],&buf[bsent],b2cp);
- nout += b2cp;
- bsent += b2cp;
-
- if (nout == ucbuflen) {
- nout = 0;
- ret = secure_putbuf(fd, ucbuf, ucbuflen);
- if (ret < 0)
- return(ret);
- }
- }
- return(bsent);
- }
-}
-
-/* returns:
- * 0 on success
- * -1 on error (errno set)
- * -2 on security error
- */
-static int
-#ifdef CK_ANSIC
-secure_putbuf(int fd, CHAR * buf, unsigned int nbyte)
-#else
-secure_putbuf(fd, buf, nbyte) int fd; CHAR * buf; unsigned int nbyte;
-#endif /* CK_ANSIC */
-{
- static char *outbuf = NULL; /* output ciphertext */
-#ifdef FTP_SECURITY
- static unsigned int bufsize = 0; /* size of outbuf */
-#endif /* FTP_SECURITY */
- ftp_int32 length = 0;
- ftp_uint32 net_len = 0;
-
- /* Other auth types go here ... */
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- int count, error;
-
- /* there is no need to send an empty buffer when using SSL/TLS */
- if ( nbyte == 0 )
- return(0);
-
- count = SSL_write(ssl_ftp_data_con, buf, nbyte);
- error = SSL_get_error(ssl_ftp_data_con,count);
- switch (error) {
- case SSL_ERROR_NONE:
- return(0);
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
-#ifdef NT
- {
- int gle = GetLastError();
- if (gle == 0)
- return(0);
- debug(F111,"secure_putbuf","SSL_ERROR_SYSCALL",gle);
- }
-#endif /* NT */
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- }
- return(-1);
- }
-#endif /* CK_SSL */
-
-#ifdef FTP_SRP
- if (ck_srp_is_installed() && (strcmp(auth_type, "SRP") == 0)) {
- if (bufsize < nbyte + FUDGE_FACTOR) {
- if (outbuf?
- (outbuf = realloc(outbuf, (unsigned) (nbyte + FUDGE_FACTOR))):
- (outbuf = malloc((unsigned) (nbyte + FUDGE_FACTOR)))) {
- bufsize = nbyte + FUDGE_FACTOR;
- } else {
- bufsize = 0;
- secure_error("%s (in malloc of PROT buffer)", ck_errstr());
- return(ERR);
- }
- }
- if ((length =
- srp_encode(ftp_dpl == FPL_PRV,
- (CHAR *) buf,
- (CHAR *) outbuf,
- nbyte
- )
- ) < 0) {
- secure_error ("srp_encode failed");
- return ERR;
- }
- }
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- if (ck_krb4_is_installed() && (strcmp(auth_type, "KERBEROS_V4") == 0)) {
- struct sockaddr_in myaddr, hisaddr;
- GSOCKNAME_T len;
- len = sizeof(myaddr);
- if (getsockname(fd, (struct sockaddr*)&myaddr, &len) < 0) {
- secure_error("secure_putbuf: getsockname failed");
- return(ERR);
- }
- len = sizeof(hisaddr);
- if (getpeername(fd, (struct sockaddr*)&hisaddr, &len) < 0) {
- secure_error("secure_putbuf: getpeername failed");
- return(ERR);
- }
- if (bufsize < nbyte + FUDGE_FACTOR) {
- if (outbuf ?
- (outbuf = realloc(outbuf, (unsigned) (nbyte + FUDGE_FACTOR))):
- (outbuf = malloc((unsigned) (nbyte + FUDGE_FACTOR)))) {
- bufsize = nbyte + FUDGE_FACTOR;
- } else {
- bufsize = 0;
- secure_error("%s (in malloc of PROT buffer)", ck_errstr());
- return(ERR);
- }
- }
- if (ftp_dpl == FPL_PRV) {
- length = krb_mk_priv(buf, (CHAR *) outbuf, nbyte,
- ftp_sched,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &myaddr,
- &hisaddr
- );
- } else {
- length = krb_mk_safe(buf, (CHAR *) outbuf, nbyte,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &myaddr,
- &hisaddr
- );
- }
- if (length == -1) {
- secure_error("krb_mk_%s failed for KERBEROS_V4",
- ftp_dpl == FPL_PRV ? "priv" : "safe");
- return(ERR);
- }
- }
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- if (ck_gssapi_is_installed() && (strcmp(auth_type, "GSSAPI") == 0)) {
- gss_buffer_desc in_buf, out_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
-
- in_buf.value = buf;
- in_buf.length = nbyte;
- maj_stat = gss_seal(&min_stat, gcontext,
- (ftp_dpl == FPL_PRV), /* confidential */
- GSS_C_QOP_DEFAULT,
- &in_buf,
- &conf_state,
- &out_buf
- );
- if (maj_stat != GSS_S_COMPLETE) {
- /* generally need to deal */
- /* ie. should loop, but for now just fail */
- user_gss_error(maj_stat, min_stat,
- ftp_dpl == FPL_PRV?
- "GSSAPI seal failed":
- "GSSAPI sign failed");
- return(ERR);
- }
- if (bufsize < out_buf.length) {
- if (outbuf ?
- (outbuf = realloc(outbuf, (unsigned) out_buf.length)):
- (outbuf = malloc((unsigned) out_buf.length))) {
- bufsize = out_buf.length;
- } else {
- bufsize = 0;
- secure_error("%s (in malloc of PROT buffer)",
- ck_errstr());
- return(ERR);
- }
- }
- memcpy(outbuf, out_buf.value, length=out_buf.length);
- gss_release_buffer(&min_stat, &out_buf);
- }
-#endif /* FTP_GSSAPI */
- net_len = htonl((ULONG) length);
- if (looping_write(fd, (char *)&net_len, 4) == -1)
- return(-1);
- if (looping_write(fd, outbuf, length) != length)
- return(-1);
- return(0);
-}
-
-
-/* fc = 0 means to get a byte; nonzero means to initialize buffer pointers */
-
-static int
-secure_getbyte(fd,fc) int fd,fc; {
- /* number of chars in ucbuf, pointer into ucbuf */
- static unsigned int nin = 0, bufp = 0;
- int kerror;
- ftp_uint32 length;
-
- if (fc) {
- nin = bufp = 0;
- ucbuf[0] = NUL;
- return(0);
- }
- if (nin == 0) {
- if (iscanceled())
- return(-9);
-
-#ifdef FTP_TIMEOUT
- if (check_data_connection(fd,0) < 0)
- return(-3);
-#endif /* FTP_TIMEOUT */
-
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- int count, error;
- count = SSL_read(ssl_ftp_data_con, ucbuf, ucbufsiz);
- error = SSL_get_error(ssl_ftp_data_con,count);
-#ifdef DEBUG
- if (error != SSL_ERROR_NONE)
- debug(F101,"ftp secure_getbyte error","",error);
- if (count == 0)
- debug(F101,"ftp secure_getbyte count","",count);
-#endif /* DEBUG */
- switch (error) {
- case SSL_ERROR_NONE:
- if (count > 0) {
- nin = bufp = count;
- rpackets++;
- pktnum++;
- if (fdispla != XYFD_B) {
- rpktl = count;
- ftscreen(SCR_PT,'D',(CK_OFF_T)rpackets,NULL);
- }
- break;
- }
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
-#ifdef NT
- {
- int gle = GetLastError();
- }
-#endif /* NT */
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- nin = bufp = count = 0;
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- break;
- }
- } else
-#endif /* CK_SSL */
- {
- kerror = looping_read(fd, (char *)&length, sizeof(length));
- if (kerror != sizeof(length)) {
- secure_error("Couldn't read PROT buffer length: %d/%s",
- kerror,
- kerror == -1 ? ck_errstr()
- : "premature EOF"
- );
- return(ERR);
- }
- debug(F101,"secure_getbyte length","",length);
- debug(F101,"secure_getbyte ntohl(length)","",ntohl(length));
-
- length = (ULONG) ntohl(length);
- if (length > maxbuf) {
- secure_error("Length (%d) of PROT buffer > PBSZ=%u",
- length,
- maxbuf
- );
- return(ERR);
- }
- if ((kerror = looping_read(fd, ucbuf, length)) != length) {
- secure_error("Couldn't read %u byte PROT buffer: %s",
- length,
- kerror == -1 ? ck_errstr() : "premature EOF"
- );
- return(ERR);
- }
-
- /* Other auth types go here ... */
-#ifdef FTP_SRP
- if (strcmp(auth_type, "SRP") == 0) {
- if ((nin = bufp = srp_decode (ftp_dpl == FPL_PRV,
- (CHAR *) ucbuf,
- ucbuf,
- length
- )
- ) == -1) {
- secure_error ("srp_encode failed" );
- return ERR;
- }
- }
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- if (strcmp(auth_type, "KERBEROS_V4") == 0) {
- struct sockaddr_in myaddr, hisaddr;
- GSOCKNAME_T len;
- len = sizeof(myaddr);
- if (getsockname(fd, (struct sockaddr*)&myaddr, &len) < 0) {
- secure_error("secure_putbuf: getsockname failed");
- return(ERR);
- }
- len = sizeof(hisaddr);
- if (getpeername(fd, (struct sockaddr*)&hisaddr, &len) < 0) {
- secure_error("secure_putbuf: getpeername failed");
- return(ERR);
- }
- if (ftp_dpl) {
- kerror = krb_rd_priv(ucbuf, length, ftp_sched,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &hisaddr, &myaddr, &ftp_msg_data);
- } else {
- kerror = krb_rd_safe(ucbuf, length,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &hisaddr, &myaddr, &ftp_msg_data);
- }
- if (kerror) {
- secure_error("krb_rd_%s failed for KERBEROS_V4 (%s)",
- ftp_dpl == FPL_PRV ? "priv" : "safe",
- krb_get_err_text(kerror));
- return(ERR);
- }
- memcpy(ucbuf,ftp_msg_data.app_data,ftp_msg_data.app_length);
- nin = bufp = ftp_msg_data.app_length;
- }
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- if (strcmp(auth_type, "GSSAPI") == 0) {
- gss_buffer_desc xmit_buf, msg_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
-
- xmit_buf.value = ucbuf;
- xmit_buf.length = length;
- conf_state = (ftp_dpl == FPL_PRV);
- /* decrypt/verify the message */
- maj_stat = gss_unseal(&min_stat, gcontext, &xmit_buf,
- &msg_buf, &conf_state, NULL);
- if (maj_stat != GSS_S_COMPLETE) {
- user_gss_error(maj_stat, min_stat,
- (ftp_dpl == FPL_PRV)?
- "failed unsealing ENC message":
- "failed unsealing MIC message");
- return ERR;
- }
- memcpy(ucbuf, msg_buf.value, nin = bufp = msg_buf.length);
- gss_release_buffer(&min_stat, &msg_buf);
- }
-#endif /* FTP_GSSAPI */
- /* Other auth types go here ... */
-
- /* Update file transfer display */
- rpackets++;
- pktnum++;
- if (fdispla != XYFD_B) {
- rpktl = nin;
- ftscreen(SCR_PT,'D',(CK_OFF_T)rpackets,NULL);
- }
- }
- }
- if (nin == 0)
- return(EOF);
- else
- return(ucbuf[bufp - nin--]);
-}
-
-/* secure_getc(fd,fc)
- * Call with:
- * fd = file descriptor for connection.
- * fc = 0 to get a character, fc != 0 to initialize buffer pointers.
- * Returns:
- * c>=0 on success (character value)
- * -1 on EOF
- * -2 on security error
- * -3 on timeout (if built with FTP_TIMEOUT defined)
- */
-static int
-secure_getc(fd,fc) int fd,fc; { /* file descriptor, function code */
-
- if (!ftpissecure()) {
- static unsigned int nin = 0, bufp = 0;
- if (fc) {
- nin = bufp = 0;
- ucbuf[0] = NUL;
- return(0);
- }
- if (nin == 0) {
- if (iscanceled())
- return(-9);
-
-#ifdef FTP_TIMEOUT
- if (check_data_connection(fd,0) < 0) {
- debug(F100,"secure_getc TIMEOUT","",0);
- nin = bufp = 0;
- ftp_timed_out = 1;
- return(-3);
- }
-#endif /* FTP_TIMEOUT */
-
- nin = bufp = recv(fd,(char *)ucbuf,actualbuf,0);
- if ((nin == 0) || (nin == (unsigned int)-1)) {
- debug(F111,"secure_getc recv errno",ckitoa(nin),errno);
- debug(F101,"secure_getc returns EOF","",EOF);
- nin = bufp = 0;
- return(EOF);
- }
- debug(F101,"ftp secure_getc recv","",nin);
- ckhexdump("ftp secure_getc recv",ucbuf,16);
- rpackets++;
- pktnum++;
- if (fdispla != XYFD_B) {
- rpktl = nin;
- ftscreen(SCR_PT,'D',(CK_OFF_T)rpackets,NULL);
- }
- }
- return(ucbuf[bufp - nin--]);
- } else
- return(secure_getbyte(fd,fc));
-}
-
-/* returns:
- * n>0 on success (n == # of bytes read)
- * 0 on EOF
- * -1 on error (errno set), only for FPL_CLR
- * -2 on security error
- */
-static int
-secure_read(fd, buf, nbyte) int fd; char *buf; int nbyte; {
- static int c = 0;
- int i;
-
- debug(F101,"secure_read bytes requested","",nbyte);
- if (c == EOF)
- return(c = 0);
- for (i = 0; nbyte > 0; nbyte--) {
- c = secure_getc(fd,0);
- switch (c) {
- case -9: /* Canceled from keyboard */
- debug(F101,"ftp secure_read interrupted","",c);
- return(0);
- case ERR:
- debug(F101,"ftp secure_read error","",c);
- return(c);
- case EOF:
- debug(F101,"ftp secure_read EOF","",c);
- if (!i)
- c = 0;
- return(i);
-#ifdef FTP_TIMEOUT
- case -3:
- debug(F101,"ftp secure_read timeout","",c);
- return(c);
-#endif /* FTP_TIMEOUT */
- default:
- buf[i++] = c;
- }
- }
- return(i);
-}
-
-#ifdef USE_RUSERPASS
-/* BEGIN_RUSERPASS
- *
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ruserpass.c 5.3 (Berkeley) 3/1/91";
-#endif /* not lint */
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-char * renvlook();
-static FILE * cfile;
-
-#define DEFAULT 1
-#define LOGIN 2
-#define PASSWD 3
-#define ACCOUNT 4
-#define MACDEF 5
-#define ID 10
-#define MACH 11
-
-static char tokval[100];
-
-static struct toktab {
- char *tokstr;
- int tval;
-} toktab[]= {
- "default", DEFAULT,
- "login", LOGIN,
- "password", PASSWD,
- "passwd", PASSWD,
- "account", ACCOUNT,
- "machine", MACH,
- "macdef", MACDEF,
- 0, 0
-};
-
-static int
-token() {
- char *cp;
- int c;
- struct toktab *t;
-
- if (feof(cfile))
- return(0);
- while ((c = getc(cfile)) != EOF &&
- (c == '\n' || c == '\t' || c == ' ' || c == ','))
- continue;
- if (c == EOF)
- return(0);
- cp = tokval;
- if (c == '"') {
- while ((c = getc(cfile)) != EOF && c != '"') {
- if (c == '\\')
- c = getc(cfile);
- *cp++ = c;
- }
- } else {
- *cp++ = c;
- while ((c = getc(cfile)) != EOF
- && c != '\n' && c != '\t' && c != ' ' && c != ',') {
- if (c == '\\')
- c = getc(cfile);
- *cp++ = c;
- }
- }
- *cp = 0;
- if (tokval[0] == 0)
- return(0);
- for (t = toktab; t->tokstr; t++)
- if (!strcmp(t->tokstr, tokval))
- return(t->tval);
- return(ID);
-}
-
-ruserpass(host, aname, apass, aacct)
- char *host, **aname, **apass, **aacct;
-{
- char *hdir, buf[FTP_BUFSIZ], *tmp;
- char myname[MAXHOSTNAMELEN], *mydomain;
- int t, i, c, usedefault = 0;
-#ifdef NT
- struct _stat stb;
-#else /* NT */
- struct stat stb;
-#endif /* NT */
-
- hdir = getenv("HOME");
- if (hdir == NULL)
- hdir = ".";
- ckmakmsg(buf,FTP_BUFSIZ,hdir,"/.netrc",NULL,NULL);
- cfile = fopen(buf, "r");
- if (cfile == NULL) {
- if (errno != ENOENT)
- perror(buf);
- return(0);
- }
- if (gethostname(myname, MAXHOSTNAMELEN) < 0)
- myname[0] = '\0';
- if ((mydomain = ckstrchr(myname, '.')) == NULL)
- mydomain = "";
-
- next:
- while ((t = token())) switch(t) {
-
- case DEFAULT:
- usedefault = 1;
- /* FALL THROUGH */
-
- case MACH:
- if (!usedefault) {
- if (token() != ID)
- continue;
- /*
- * Allow match either for user's input host name
- * or official hostname. Also allow match of
- * incompletely-specified host in local domain.
- */
- if (ckstrcmp(host, tokval,-1,1) == 0)
- goto match;
- if (ckstrcmp(ftp_host, tokval,-1,0) == 0)
- goto match;
- if ((tmp = ckstrchr(ftp_host, '.')) != NULL &&
- ckstrcmp(tmp, mydomain,-1,1) == 0 &&
- ckstrcmp(ftp_host, tokval, tmp-ftp_host,0) == 0 &&
- tokval[tmp - ftp_host] == '\0')
- goto match;
- if ((tmp = ckstrchr(host, '.')) != NULL &&
- ckstrcmp(tmp, mydomain,-1,1) == 0 &&
- ckstrcmp(host, tokval, tmp - host, 0) == 0 &&
- tokval[tmp - host] == '\0')
- goto match;
- continue;
- }
-
- match:
- while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
-
- case LOGIN:
- if (token())
- if (*aname == 0) {
- *aname = malloc((unsigned) strlen(tokval) + 1);
- strcpy(*aname, tokval); /* safe */
- } else {
- if (strcmp(*aname, tokval))
- goto next;
- }
- break;
- case PASSWD:
- if (strcmp(*aname, "anonymous") &&
- fstat(fileno(cfile), &stb) >= 0 &&
- (stb.st_mode & 077) != 0) {
- fprintf(stderr, "Error - .netrc file not correct mode.\n");
- fprintf(stderr, "Remove password or correct mode.\n");
- goto bad;
- }
- if (token() && *apass == 0) {
- *apass = malloc((unsigned) strlen(tokval) + 1);
- strcpy(*apass, tokval); /* safe */
- }
- break;
- case ACCOUNT:
- if (fstat(fileno(cfile), &stb) >= 0
- && (stb.st_mode & 077) != 0) {
- fprintf(stderr, "Error - .netrc file not correct mode.\n");
- fprintf(stderr, "Remove account or correct mode.\n");
- goto bad;
- }
- if (token() && *aacct == 0) {
- *aacct = malloc((unsigned) strlen(tokval) + 1);
- strcpy(*aacct, tokval); /* safe */
- }
- break;
-
- default:
- fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
- break;
- }
- goto done;
- }
-
- done:
- fclose(cfile);
- return(0);
-
- bad:
- fclose(cfile);
- return(-1);
-}
-#endif /* USE_RUSERPASS */
-
-static char *radixN =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-static char pad = '=';
-
-static int
-radix_encode(inbuf, outbuf, inlen, outlen, decode)
- CHAR inbuf[], outbuf[];
- int inlen, *outlen, decode;
-{
- int i, j, D = 0;
- char *p;
- CHAR c = NUL;
-
- if (decode) {
- for (i = 0, j = 0; inbuf[i] && inbuf[i] != pad; i++) {
- if ((p = ckstrchr(radixN, inbuf[i])) == NULL)
- return(1);
- D = p - radixN;
- switch (i&3) {
- case 0:
- outbuf[j] = D<<2;
- break;
- case 1:
- outbuf[j++] |= D>>4;
- outbuf[j] = (D&15)<<4;
- break;
- case 2:
- outbuf[j++] |= D>>2;
- outbuf[j] = (D&3)<<6;
- break;
- case 3:
- outbuf[j++] |= D;
- }
- if (j == *outlen)
- return(4);
- }
- switch (i&3) {
- case 1: return(3);
- case 2: if (D&15) return(3);
- if (strcmp((char *)&inbuf[i], "==")) return(2);
- break;
- case 3: if (D&3) return(3);
- if (strcmp((char *)&inbuf[i], "=")) return(2);
- }
- *outlen = j;
- } else {
- for (i = 0, j = 0; i < inlen; i++) {
- switch (i%3) {
- case 0:
- outbuf[j++] = radixN[inbuf[i]>>2];
- c = (inbuf[i]&3)<<4;
- break;
- case 1:
- outbuf[j++] = radixN[c|inbuf[i]>>4];
- c = (inbuf[i]&15)<<2;
- break;
- case 2:
- outbuf[j++] = radixN[c|inbuf[i]>>6];
- outbuf[j++] = radixN[inbuf[i]&63];
- c = 0;
- }
- if (j == *outlen)
- return(4);
- }
- if (i%3) outbuf[j++] = radixN[c];
- switch (i%3) {
- case 1: outbuf[j++] = pad;
- case 2: outbuf[j++] = pad;
- }
- outbuf[*outlen = j] = '\0';
- }
- return(0);
-}
-
-static char *
-radix_error(e) int e;
-{
- switch (e) {
- case 0: return("Success");
- case 1: return("Bad character in encoding");
- case 2: return("Encoding not properly padded");
- case 3: return("Decoded # of bits not a multiple of 8");
- case 4: return("Output buffer too small");
- default: return("Unknown error");
- }
-}
-/* END_RUSERPASS */
-
-#ifdef FTP_SRP
-/*---------------------------------------------------------------------------+
- | |
- | Package: srpftp |
- | Author: Eugene Jhong |
- | |
- +---------------------------------------------------------------------------*/
-
-/*
- * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following conditions apply:
- *
- * 1. Any software that incorporates the SRP authentication technology
- * must display the following acknowlegment:
- * "This product uses the 'Secure Remote Password' cryptographic
- * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
- *
- * 2. Any software that incorporates all or part of the SRP distribution
- * itself must also display the following acknowledgment:
- * "This product includes software developed by Tom Wu and Eugene
- * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
- *
- * 3. Redistributions in source or binary form must retain an intact copy
- * of this copyright notice and list of conditions.
- */
-
-#define SRP_PROT_VERSION 1
-
-#ifdef CK_ENCRYPTION
-#define SRP_DEFAULT_CIPHER CIPHER_ID_CAST5_CBC
-#else
-#define SRP_DEFAULT_CIPHER CIPHER_ID_NONE
-#endif /* CK_ENCRYPTION */
-
-#define SRP_DEFAULT_HASH HASH_ID_SHA
-
-CHAR srp_pref_cipher = CIPHER_ID_DES3_ECB;
-CHAR srp_pref_hash = HASH_ID_SHA;
-
-static struct t_client *tc = NULL;
-static CHAR *skey = NULL;
-static krypto_context *incrypt = NULL;
-static krypto_context *outcrypt = NULL;
-
-typedef unsigned int srp_uint32;
-
-/*--------------------------------------------------------------+
- | srp_selcipher: select cipher |
- +--------------------------------------------------------------*/
-static int
-srp_selcipher (cname) char *cname; {
- cipher_desc *cd;
-
- if (!(cd = cipher_getdescbyname (cname))) {
- int i;
- CHAR *list = cipher_getlist ();
-
- fprintf (stderr, "ftp: supported ciphers:\n\n");
- for (i = 0; i < strlen (list); i++)
- fprintf (stderr, " %s\n", (cipher_getdescbyid(list[i]))->name);
- fprintf (stderr, "\n");
- return -1;
- }
- srp_pref_cipher = cd->id;
- return 0;
-}
-
-/*--------------------------------------------------------------+
- | srp_selhash: select hash |
- +--------------------------------------------------------------*/
-static int
-srp_selhash (hname) char *hname; {
- hash_desc *hd;
-
- if (!(hd = hash_getdescbyname (hname))) {
- int i;
- CHAR *list = hash_getlist ();
-
- fprintf (stderr, "ftp: supported hash functions:\n\n");
- for (i = 0; i < strlen (list); i++)
- fprintf (stderr, " %s\n", (hash_getdescbyid(list[i]))->name);
- fprintf (stderr, "\n");
- return -1;
- }
- srp_pref_hash = hd->id;
- return 0;
-}
-
-/*--------------------------------------------------------------+
- | srp_userpass: get username and password |
- +--------------------------------------------------------------*/
-static int
-srp_userpass (host) char *host; {
- char tmp[BUFSIZ], prompt[PROMPTSIZ];
- char *user;
-
- user = NULL;
-#ifdef USE_RUSERPASS
- ruserpass (host, &user, &srp_pass, &srp_acct);
-#endif /* USE_RUSERPASS */
-
- while (user == NULL) {
- char *myname;
- int ok;
-
- myname = whoami();
- if (!myname) myname = "";
- if (myname[0])
- ckmakxmsg(prompt,PROMPTSIZ," Name (",host,":",myname,"): ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- else
- ckmakmsg(prompt,PROMPTSIZ," Name (",host,"): ",NULL);
- tmp[0] = '\0';
- ok = uq_txt(NULL,prompt,1,NULL,tmp,BUFSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (!ok || *tmp == '\0')
- user = myname;
- else
- user = brstrip(tmp);
- }
- ckstrncpy (srp_user, user,BUFSIZ);
- return(0);
-}
-
-/*--------------------------------------------------------------+
- | srp_reset: reset srp information |
- +--------------------------------------------------------------*/
-static int
-srp_reset () {
- if (tc) { t_clientclose (tc); tc = NULL; }
- if (incrypt) { krypto_delete (incrypt); incrypt = NULL; }
- if (outcrypt) { krypto_delete (outcrypt); outcrypt = NULL; }
- return(0);
-}
-
-/*--------------------------------------------------------------+
- | srp_ftp_auth: perform srp authentication |
- +--------------------------------------------------------------*/
-static int
-srp_ftp_auth(host, user, pass)
- char *host;
- char *user;
- char *pass;
-{
- struct t_num *wp;
- struct t_num N;
- struct t_num g;
- struct t_num s;
- struct t_num yp;
- CHAR buf[FTP_BUFSIZ];
- CHAR tmp[FTP_BUFSIZ];
- CHAR *bp, *cp;
- int n, e, clen, blen, len, i;
- CHAR cid = 0;
- CHAR hid = 0;
-
- srp_pass = srp_acct = 0;
-
- n = ftpcmd("AUTH SRP",NULL,0,0,ftp_vbm);
- if (n != REPLY_CONTINUE) {
- if (ftp_deb)
- fprintf(stderr, "SRP rejected as an authentication type\n");
- return(0);
- } else { /* Send protocol version */
- CHAR vers[4];
- memset (vers, 0, 4);
- vers[3] = SRP_PROT_VERSION;
- if (!quiet)
- printf ("SRP accepted as authentication type.\n");
- bp = tmp; blen = 0;
- srp_put (vers, &bp, 4, &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
- }
- if (n == REPLY_CONTINUE) { /* Get protocol version */
- bp = buf;
- if (!reply_parse)
- goto data_error;
- blen = FTP_BUFSIZ;
- if (e = radix_encode(reply_parse, bp, 0, &blen, RADIX_DECODE))
- goto decode_error;
- if (srp_get (&bp, &cp, &blen, &clen) != 4)
- goto data_error;
-
- if (host) { /* Get username/password if needed */
- srp_userpass (host);
- } else {
- ckstrncpy (srp_user, user, BUFSIZ);
- srp_pass = pass;
- }
- bp = tmp; blen = 0; /* Send username */
- srp_put (srp_user, &bp, strlen (srp_user), &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
- }
- if (n == REPLY_CONTINUE) { /* Get N, g and s */
- bp = buf;
- if (!reply_parse)
- goto data_error;
- blen = FTP_BUFSIZ;
- if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE))
- goto decode_error;
- if (srp_get (&bp, &(N.data), &blen, &(N.len)) < 0)
- goto data_error;
- if (srp_get (&bp, &(g.data), &blen, &(g.len)) < 0)
- goto data_error;
- if (srp_get (&bp, &(s.data), &blen, &(s.len)) < 0)
- goto data_error;
- if ((tc = t_clientopen (srp_user, &N, &g, &s)) == NULL) {
- fprintf (stderr, "Unable to open SRP client structure.\n");
- goto bad;
- }
- wp = t_clientgenexp (tc); /* Send wp */
- bp = tmp; blen = 0;
- srp_put (wp->data, &bp, wp->len, &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
- }
- if (n == REPLY_CONTINUE) { /* Get yp */
- bp = buf;
- if (!reply_parse)
- goto data_error;
- blen = FTP_BUFSIZ;
- if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE))
- goto decode_error;
- if (srp_get (&bp, &(yp.data), &blen, &(yp.len)) < 0)
- goto data_error;
- if (!srp_pass) {
- static char ftppass[PASSBUFSIZ];
- int ok;
- setint();
- ok = uq_txt(NULL," SRP Password: ",2,NULL,ftppass,PASSBUFSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (ok)
- srp_pass = brstrip(ftppass);
- }
- t_clientpasswd (tc, srp_pass);
- memset (srp_pass, 0, strlen (srp_pass));
- skey = t_clientgetkey (tc, &yp); /* Send response */
- bp = tmp; blen = 0;
- srp_put (t_clientresponse (tc), &bp, 20, &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
- }
- if (n == REPLY_CONTINUE) { /* Get response */
- bp = buf;
- if (!reply_parse)
- goto data_error;
- blen = FTP_BUFSIZ;
- if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE))
- goto encode_error;
- if (srp_get (&bp, &cp, &blen, &clen) != 20)
- goto data_error;
- if (t_clientverify (tc, cp)) {
- fprintf (stderr, "WARNING: bad response to client challenge.\n");
- goto bad;
- }
- bp = tmp; blen = 0; /* Send nothing */
- srp_put ("\0", &bp, 1, &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
- }
- if (n == REPLY_CONTINUE) { /* Get cipher & hash lists, seqnum */
- CHAR seqnum[4];
- CHAR *clist;
- CHAR *hlist;
- CHAR *p1;
- int clist_len, hlist_len;
- bp = buf;
- if (!reply_parse)
- goto data_error;
- blen = FTP_BUFSIZ;
- if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE))
- goto encode_error;
- if (srp_get (&bp, &clist, &blen, &clist_len) < 0)
- goto data_error;
- if (srp_get (&bp, &hlist, &blen, &hlist_len) < 0)
- goto data_error;
- if (srp_get (&bp, &cp, &blen, &clen) != 4)
- goto data_error;
- memcpy (seqnum, cp, 4);
- if (cipher_supported (clist, srp_pref_cipher)) /* Choose cipher */
- cid = srp_pref_cipher;
- if (!cid && cipher_supported (clist, SRP_DEFAULT_CIPHER))
- cid = SRP_DEFAULT_CIPHER;
- if (!cid) {
- CHAR *loclist = cipher_getlist ();
- for (i = 0; i < strlen (loclist); i++)
- if (cipher_supported (clist, loclist[i])) {
- cid = loclist[i];
- break;
- }
- }
- if (!cid) {
- fprintf (stderr, "Unable to agree on cipher.\n");
- goto bad;
- }
- /* Choose hash */
-
- if (srp_pref_hash && hash_supported (hlist, srp_pref_hash))
- hid = srp_pref_hash;
-
- if (!hid && hash_supported (hlist, SRP_DEFAULT_HASH))
- hid = SRP_DEFAULT_HASH;
-
- if (!hid) {
- CHAR *loclist = hash_getlist ();
- for (i = 0; i < strlen (loclist); i++)
- if (hash_supported (hlist, loclist[i])) {
- hid = loclist[i];
- break;
- }
- }
- if (!hid) {
- fprintf (stderr, "Unable to agree on hash.\n");
- goto bad;
- }
- /* Set incrypt */
-
- if (!(incrypt = krypto_new (cid, hid, skey, 20, NULL, 0, seqnum,
- KRYPTO_DECODE)))
- goto bad;
-
- /* Generate random number for outkey and outseqnum */
-
- t_random (seqnum, 4);
-
- /* Send cid, hid, outkey, outseqnum */
-
- bp = tmp; blen = 0;
- srp_put (&cid, &bp, 1, &blen);
- srp_put (&hid, &bp, 1, &blen);
- srp_put (seqnum, &bp, 4, &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
-
- /* Set outcrypt */
-
- if (!(outcrypt = krypto_new (cid, hid, skey+20, 20, NULL, 0, seqnum,
- KRYPTO_ENCODE)))
- goto bad;
-
- t_clientclose (tc);
- tc = NULL;
- }
- if (n != REPLY_COMPLETE)
- goto bad;
-
- if (ftp_vbm) {
- if (ftp_deb)
- printf("\n");
- printf ("SRP authentication succeeded.\n");
- printf ("Using cipher %s and hash function %s.\n",
- (cipher_getdescbyid(cid))->name,
- (hash_getdescbyid(hid))->name
- );
- }
- reply_parse = NULL;
- auth_type = "SRP";
- return(1);
-
- encode_error:
- fprintf (stderr, "Base 64 encoding failed: %s.\n", radix_error (e));
- goto bad;
-
- decode_error:
- fprintf (stderr, "Base 64 decoding failed: %s.\n", radix_error (e));
- goto bad;
-
- data_error:
- fprintf (stderr, "Unable to unmarshal authentication data.\n");
- goto bad;
-
- bad:
- fprintf (stderr, "SRP authentication failed, trying regular login.\n");
- reply_parse = NULL;
- return(0);
-}
-
-/*--------------------------------------------------------------+
- | srp_put: put item to send buffer |
- +--------------------------------------------------------------*/
-static int
-srp_put (in, out, inlen, outlen)
- CHAR *in;
- CHAR **out;
- int inlen;
- int *outlen;
-{
- srp_uint32 net_len;
-
- net_len = htonl (inlen);
- memcpy (*out, &net_len, 4);
-
- *out += 4; *outlen += 4;
-
- memcpy (*out, in, inlen);
-
- *out += inlen; *outlen += inlen;
- return(0);
-}
-
-/*--------------------------------------------------------------+
- | srp_get: get item from receive buffer |
- +--------------------------------------------------------------*/
-static int
-srp_get (in, out, inlen, outlen)
- CHAR **in;
- CHAR **out;
- int *inlen;
- int *outlen;
-{
- srp_uint32 net_len;
-
- if (*inlen < 4) return -1;
-
- memcpy (&net_len, *in, 4); *inlen -= 4; *in += 4;
- *outlen = ntohl (net_len);
-
- if (*inlen < *outlen) return -1;
-
- *out = *in; *inlen -= *outlen; *in += *outlen;
-
- return *outlen;
-}
-
-/*--------------------------------------------------------------+
- | srp_encode: encode control message |
- +--------------------------------------------------------------*/
-static int
-srp_encode (private, in, out, len)
- int private;
- CHAR *in;
- CHAR *out;
- unsigned len;
-{
- if (private)
- return krypto_msg_priv (outcrypt, in, out, len);
- else
- return krypto_msg_safe (outcrypt, in, out, len);
-}
-
-/*--------------------------------------------------------------+
- | srp_decode: decode control message |
- +--------------------------------------------------------------*/
-static int
-srp_decode (private, in, out, len)
- int private;
- CHAR *in;
- CHAR *out;
- unsigned len;
-{
- if (private)
- return krypto_msg_priv (incrypt, in, out, len);
- else
- return krypto_msg_safe (incrypt, in, out, len);
-}
-
-#endif /* FTP_SRP */
-
-
-
-#ifdef NOT_USED
-/*
- The following code is from the Unix FTP client. Be sure to
- make sure that the functionality is not lost. Especially
- the Proxy stuff even though we have not yet implemented it.
-*/
-
-/* Send multiple files */
-
-static int
-ftp_mput(argc, argv) int argc; char **argv; {
- register int i;
- sig_t oldintr;
- int ointer;
- char *tp;
- sigtype mcancel();
-
- if (argc < 2 && !another(&argc, &argv, "local-files")) {
- printf("usage: %s local-files\n", argv[0]);
- ftpcode = -1;
- return;
- }
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT, mcancel);
-
- /* Replace with calls to cc_execute() */
- setjmp(jcancel);
-#ifdef FTP_PROXY
- if (proxy) {
- char *cp, *tp2, tmpbuf[CKMAXPATH];
-
- while ((cp = remglob(argv,0)) != NULL) {
- if (*cp == 0) {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- tp = cp;
- if (mcase) {
- while (*tp && !islower(*tp)) {
- tp++;
- }
- if (!*tp) {
- tp = cp;
- tp2 = tmpbuf;
- while ((*tp2 = *tp) != 0) {
- if (isupper(*tp2)) {
- *tp2 = 'a' + *tp2 - 'A';
- }
- tp++;
- tp2++;
- }
- }
- tp = tmpbuf;
- }
- if (ntflag) {
- tp = dotrans(tp);
- }
- if (mapflag) {
- tp = domap(tp);
- }
- sendrequest((sunique) ? "STOU" : "STOR", cp, tp, 0, -1, -1, 0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mput")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- signal(SIGINT, oldintr);
- mflag = 0;
- return;
- }
-#endif /* FTP_PROXY */
- for (i = 1; i < argc; i++) {
- register char **cpp, **gargs;
-
- if (mflag && confirm(argv[0], argv[i])) {
- tp = argv[i];
- sendrequest((ftp_usn) ? "STOU" : "STOR", argv[i], tp, 0,-1,-1, 0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mput")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- continue;
-
- gargs = ftpglob(argv[i]);
- if (globerr != NULL) {
- printf("%s\n", globerr);
- if (gargs) {
- blkfree(gargs);
- free((char *)gargs);
- }
- continue;
- }
- for (cpp = gargs; cpp && *cpp != NULL; cpp++) {
- if (mflag && confirm(argv[0], *cpp)) {
- tp = *cpp;
- sendrequest((sunique) ? "STOU":"STOR", *cpp, tp, 0, -1, -1, 0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mput")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- if (gargs != NULL) {
- blkfree(gargs);
- free((char *)gargs);
- }
- }
- signal(SIGINT, oldintr);
- mflag = 0;
-}
-
-/* Get multiple files */
-
-static int
-ftp_mget(argc, argv) int argc; char **argv; {
- int rc = -1;
- sig_t oldintr;
- int ointer;
- char *cp, *tp, *tp2, tmpbuf[CKMAXPATH];
- sigtype mcancel();
-
- if (argc < 2 && !another(&argc, &argv, "remote-files")) {
- printf("usage: %s remote-files\n", argv[0]);
- ftpcode = -1;
- return(-1);
- }
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT,mcancel);
- /* Replace with calls to cc_execute() */
- setjmp(jcancel);
- while ((cp = remglob(argv,proxy)) != NULL) {
- if (*cp == '\0') {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- tp = cp;
- if (mcase) {
- while (*tp && !islower(*tp)) {
- tp++;
- }
- if (!*tp) {
- tp = cp;
- tp2 = tmpbuf;
- while ((*tp2 = *tp) != 0) {
- if (isupper(*tp2)) {
- *tp2 = 'a' + *tp2 - 'A';
- }
- tp++;
- tp2++;
- }
- }
- tp = tmpbuf;
- }
- rc = (recvrequest("RETR", tp, cp, "wb",
- tp != cp || !interactive) == 0,0,NULL,0,0,0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mget")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- signal(SIGINT,oldintr);
- mflag = 0;
- return(rc);
-}
-
-/* Delete multiple files */
-
-static int
-mdelete(argc, argv) int argc; char **argv; {
- sig_t oldintr;
- int ointer;
- char *cp;
- sigtype mcancel();
-
- if (argc < 2 && !another(&argc, &argv, "remote-files")) {
- printf("usage: %s remote-files\n", argv[0]);
- ftpcode = -1;
- return(-1);
- }
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT, mcancel);
- /* Replace with calls to cc_execute() */
- setjmp(jcancel);
- while ((cp = remglob(argv,0)) != NULL) {
- if (*cp == '\0') {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- rc = (ftpcmd("DELE",cp,-1,-1,ftp_vbm) == REPLY_COMPLETE);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with", "mdelete")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- signal(SIGINT, oldintr);
- mflag = 0;
- return(rc);
-}
-
-/* Get a directory listing of multiple remote files */
-
-static int
-mls(argc, argv) int argc; char **argv; {
- sig_t oldintr;
- int ointer, i;
- char *cmd, mode[1], *dest;
- sigtype mcancel();
- int rc = -1;
-
- if (argc < 2 && !another(&argc, &argv, "remote-files"))
- goto usage;
- if (argc < 3 && !another(&argc, &argv, "local-file")) {
- usage:
- printf("usage: %s remote-files local-file\n", argv[0]);
- ftpcode = -1;
- return(-1);
- }
- dest = argv[argc - 1];
- argv[argc - 1] = NULL;
- if (strcmp(dest, "-") && *dest != '|')
- if (!globulize(&dest) ||
- !confirm("output to local-file:", dest)) {
- ftpcode = -1;
- return(-1);
- }
- cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT, mcancel);
- /* Replace with calls to cc_execute() */
- setjmp(jcancel);
- for (i = 1; mflag && i < argc-1; ++i) {
- *mode = (i == 1) ? 'w' : 'a';
- rc = recvrequest(cmd, dest, argv[i], mode, 0,0,NULL,0,0,0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with", argv[0])) {
- mflag ++;
- }
- interactive = ointer;
- }
- }
- signal(SIGINT, oldintr);
- mflag = 0;
- return(rc);
-}
-
-static char *
-remglob(argv,doswitch) char *argv[]; int doswitch; {
- char temp[16];
- static char buf[CKMAXPATH];
- static FILE *ftemp = NULL;
- static char **args;
- int oldhash;
- char *cp, *mode;
-
- if (!mflag) {
- if (!doglob) {
- args = NULL;
- } else {
- if (ftemp) {
- (void) fclose(ftemp);
- ftemp = NULL;
- }
- }
- return(NULL);
- }
- if (!doglob) {
- if (args == NULL)
- args = argv;
- if ((cp = *++args) == NULL)
- args = NULL;
- return(cp);
- }
- if (ftemp == NULL) {
- (void) strcpy(temp, _PATH_TMP);
-#ifdef MKTEMP
-#ifndef MKSTEMP
- (void) mktemp(temp);
-#endif /* MKSTEMP */
-#endif /* MKTEMP */
- verbose = 0;
- oldhash = hash, hash = 0;
-#ifdef FTP_PROXY
- if (doswitch) {
- pswitch(!proxy);
- }
-#endif /* FTP_PROXY */
- for (mode = "wb"; *++argv != NULL; mode = "ab")
- recvrequest ("NLST", temp, *argv, mode, 0);
-#ifdef FTP_PROXY
- if (doswitch) {
- pswitch(!proxy);
- }
-#endif /* FTP_PROXY */
- hash = oldhash;
- ftemp = fopen(temp, "r");
- unlink(temp);
- if (ftemp == NULL && (!dpyactive || ftp_deb)) {
- printf("Can't find list of remote files, oops\n");
- return(NULL);
- }
- }
- if (fgets(buf, CKMAXPATH, ftemp) == NULL) {
- fclose(ftemp), ftemp = NULL;
- return(NULL);
- }
- if ((cp = ckstrchr(buf,'\n')) != NULL)
- *cp = '\0';
- return(buf);
-}
-#endif /* NOT_USED */
-#endif /* TCPSOCKET (top of file) */
-#endif /* SYSFTP (top of file) */
-#endif /* NOFTP (top of file) */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcker.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckcker.h
deleted file mode 100644
index 890f666..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcker.h
+++ /dev/null
@@ -1,1425 +0,0 @@
-/* ckcker.h -- Symbol and macro definitions for C-Kermit */
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-#ifndef CKCKER_H
-#define CKCKER_H
-
-#define I_AM_KERMIT 0 /* Personalities */
-#define I_AM_TELNET 1
-#define I_AM_RLOGIN 2
-#define I_AM_IKSD 3
-#define I_AM_FTP 4
-#define I_AM_HTTP 5
-#define I_AM_SSHSUB 6
-#define I_AM_SSH 7
-
-#ifndef NOSTREAMING
-#ifndef STREAMING
-#define STREAMING
-#endif /* STREAMING */
-#endif /* NOSTREAMING */
-/*
- If NEWDEFAULTS is defined then:
- - RECEIVE PACKET-LENGTH is 4095 rather than 90
- - WINDOW is 30 rather than 1
- - BLOCK-CHECK is 3 rather than 1
- - FILE TYPE is BINARY rather than TEXT
-*/
-#ifdef BIGBUFOK /* (was OS2) */
-#ifndef NEWDEFAULTS
-#define NEWDEFAULTS
-#endif /* NEWDEFAULTS */
-#endif /* BIGBUFOK */
-
-#ifdef NOICP /* No Interactive Command Parser */
-#ifndef NOSPL /* implies... */
-#define NOSPL /* No Script Programming Language */
-#endif /* NOSPL */
-#ifndef NOCSETS /* No character-set translation */
-#define NOCSETS /* because the only way to set it up */
-#endif /* NOCSETS */ /* is with interactive commands */
-#endif /* NOICP */
-
-#ifdef pdp11 /* There is a maximum number of */
-#ifndef NOCKSPEED /* of -D's allowed on the CC */
-#define NOCKSPEED /* command line, so some of them */
-#endif /* NOCKSPEED */ /* have to go here... */
-#ifndef NOREDIRECT
-#define NOREDIRECT
-#endif /* NOREDIRECT */
-#ifdef WHATAMI
-#undef WHATAMI
-#endif /* WHATAMI */
-#endif /* pdp11 */
-
-#ifdef UIDBUFLEN
-#define LOGINLEN UIDBUFLEN
-#else
-#define LOGINLEN 32 /* Length of server login field */
-#endif /* UIDBUFLEN */
-
-/* Bell values */
-
-#define XYB_NONE 0 /* No bell */
-#define XYB_AUD 1 /* Audible bell */
-#define XYB_VIS 2 /* Visible bell */
-#define XYB_BEEP 0 /* Audible Beep */
-#define XYB_SYS 4 /* Audible System Sounds */
-
-/* File status bits */
-
-#define FS_OK 1 /* File transferred OK */
-#define FS_REFU 2 /* File was refused */
-#define FS_DISC 4 /* File was discarded */
-#define FS_INTR 8 /* Transfer was interrupted by user */
-#define FS_ERR 16 /* Fatal error during transfer */
-
-/* Control-character (un)prefixing options */
-
-#define PX_ALL 0 /* Prefix all control chars */
-#define PX_CAU 1 /* Unprefix cautiously */
-#define PX_WIL 2 /* Unprefix with wild abandon */
-#define PX_NON 3 /* Unprefix all (= prefix none) */
-
-/* Destination codes */
-
-#define DEST_D 0 /* DISK */
-#define DEST_S 1 /* SCREEN */
-#define DEST_P 2 /* PRINTER */
-#define DEST_N 3 /* NOWHERE (calibration run) */
-
-/* File transfer protocols */
-
-#define PROTO_K 0 /* Kermit */
-#ifdef CK_XYZ
-#define PROTO_X 1 /* XMODEM */
-#define PROTO_XC 2 /* XMODEM-CRC */
-#define PROTO_Y 3 /* YMODEM */
-#define PROTO_G 4 /* YMODEM-g */
-#define PROTO_Z 5 /* ZMODEM */
-#define PROTO_O 6 /* OTHER */
-#define NPROTOS 7 /* How many */
-#else
-#define NPROTOS 1 /* How many */
-#endif /* CK_XYZ */
-
-struct ck_p { /* C-Kermit Protocol info structure */
- char * p_name; /* Protocol name */
- int rpktlen; /* Packet length - receive */
- int spktlen; /* Packet length - send */
- int spktflg; /* ... */
- int winsize; /* Window size */
- int prefix; /* Control-char prefixing options */
- int fnca; /* Filename collision action */
- int fncn; /* Filename conversion */
- int fnsp; /* Send filename path stripping */
- int fnrp; /* Receive filename path stripping */
- char * h_b_init; /* Host receive initiation string - text */
- char * h_t_init; /* Host receive initiation string - binary */
- char * h_x_init; /* Host server string */
- char * p_b_scmd; /* SEND cmd for external protocol - text */
- char * p_t_scmd; /* SEND cmd for external protocol - binary */
- char * p_b_rcmd; /* RECV cmd for external protocol - text */
- char * p_t_rcmd; /* RECV cmd for external protocol - binary */
-};
-
-struct filelist { /* Send-file list element */
- char * fl_name; /* Filename */
- int fl_mode; /* Transfer mode */
- char * fl_alias; /* Name to send the file under */
- struct filelist * fl_next; /* Pointer to next element */
-};
-
-/* Kermit system IDs and associated properties... */
-
-struct sysdata {
- char *sid_code; /* Kermit system ID code */
- char *sid_name; /* Descriptive name */
- short sid_unixlike; /* Tree-structured directory with separators */
- char sid_dirsep; /* Directory separator character if unixlike */
- short sid_dev; /* Can start with dev: */
- short sid_case; /* Bit mapped: 1 = case matters, 2 = case preserved */
- short sid_recfm; /* Text record separator */
-/*
- 0 = unknown or nonstream
- 1 = cr
- 2 = lf
- 3 = crlf
-*/
-};
-
-struct ssh_pf { /* SSH port forwarding */
- int p1; /* port to be forwarded */
- char * host; /* host */
- int p2; /* port */
-};
-
-#define SET_ON 1 /* General values for settings that can be ON */
-#define SET_OFF 0 /* OFF, */
-#define SET_AUTO 2 /* or AUTO */
-
-#define PATH_OFF 0 /* Pathnames off (to be stripped) */
-#define PATH_REL 1 /* Pathnames on, left relative if possible */
-#define PATH_ABS 2 /* Pathnames absolute always */
-#define PATH_AUTO 4 /* Pathnames handled automatically */
-
-/* GET Options */
-
-#define GOPT_DEL 1 /* Delete source file */
-#define GOPT_REC 2 /* Recursive */
-#define GOPT_RES 4 /* Recover (Resend) */
-#define GOPT_CMD 8 /* Filename is a Command */
-
-/* GET Transfer Modes */
-
-#define GMOD_TXT 0 /* Text */
-#define GMOD_BIN 1 /* Binary */
-#define GMOD_AUT 2 /* Auto */
-#define GMOD_LBL 3 /* Labeled */
-
-/* GET Filename Options */
-
-#define GNAM_LIT 0 /* Literal */
-#define GNAM_CNV 1 /* Converted */
-
-/* GET Pathname Options */
-
-#define GPTH_OFF 0 /* Pathnames Off */
-#define GPTH_REL 1 /* Pathnames Relative */
-#define GPTH_ABX 2 /* Pathnames Absolute */
-
-#ifndef NOSPL
-/*
- The IF REMOTE-ONLY command is available only in versions
- that actually can be used in remote mode, and only if we have
- an interactive command parser.
-*/
-#define CK_IFRO
-#ifdef MAC
-#undef CK_IFRO
-#else
-#ifdef GEMDOS
-#undef CK_IFRO
-#endif /* GEMDOS */
-#endif /* MAC */
-#endif /* NOSPL */
-
-/* Systems whose CONNECT modules can execute Application Program Commands */
-
-#ifdef NOSPL /* Script programming language */
-#ifdef CK_APC /* is required for APC. */
-#undef CK_APC
-#endif /* CK_APC */
-#ifndef NOAPC
-#define NOAPC
-#endif /* NOAPC */
-#ifndef NOAUTODL
-#define NOAUTODL
-#endif /* NOAUTODL */
-#endif /* NOSPL */
-
-#ifndef NOAPC /* Unless they said NO APC */
-#ifndef CK_APC /* And they didn't already define it */
-#ifdef OS2 /* OS/2 gets it */
-#define CK_APC
-#endif /* OS2 */
-#ifdef UNIX /* UNIX gets it */
-#define CK_APC
-#endif /* UNIX */
-#ifdef VMS /* VMS too */
-#define CK_APC
-#endif /* VMS */
-#endif /* CK_APC */
-#endif /* NOAPC */
-
-#ifdef CK_APC /* APC buffer length */
-#ifndef APCBUFLEN /* Should be no bigger than */
-#ifdef NOSPL /* command buffer length */
-#define APCBUFLEN 608 /* (see ckucmd.h) but we can't */
-#else /* reference ckucmd.h symbols here */
-#define APCBUFLEN 4096
-#endif /* NOSPL */
-#endif /* APCBUFLEN */
-#define APC_OFF 0 /* APC OFF (disabled) */
-#define APC_ON 1 /* APC ON (enabled for non-dangerous commands) */
-#define APC_UNCH 2 /* APC UNCHECKED (enabled for ALL commands) bitmask */
-#define APC_NOINP 4 /* APC (enabled with no input allowed - bitmask) */
-#define APC_INACTIVE 0 /* APC not in use */
-#define APC_REMOTE 1 /* APC in use from Remote */
-#define APC_LOCAL 2 /* APC being used from within Kermit */
-#ifndef NOAUTODL
-#ifndef CK_AUTODL /* Autodownload */
-#ifdef OS2
-#define CK_AUTODL
-#else
-#ifdef UNIX
-#define CK_AUTODL
-#else
-#ifdef VMS
-#define CK_AUTODL
-#else
-#ifdef CK_AUTODL
-#undef CK_AUTODL
-#endif /* CK_AUTODL */
-#endif /* NOAUTODL */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* OS2 */
-#endif /* CK_AUTODL */
-
-#else /* CK_APC not defined */
-
-#ifdef NOICP
-#ifdef UNIX
-#ifndef CK_AUTODL
-#define CK_AUTODL
-#endif /* CK_AUTODL */
-#endif /* UNIX */
-#else /* Not NOICP... */
-#ifdef CK_AUTODL
-#undef CK_AUTODL
-#endif /* CK_AUTODL */
-#endif /* NOICP */
-#endif /* CK_APC */
-
-#ifdef NOAUTODL
-#ifdef CK_AUTODL
-#undef CK_AUTODL
-#endif /* CK_AUTODL */
-#endif /* NOAUTODL */
-
-/* Codes for what we are doing now - bit mask values */
-
-#define W_NOTHING 0 /* Nothing */
-#define W_INIT 1 /* Initializing protocol */
-#define W_SEND 2 /* SENDing or MAILing */
-#define W_RECV 4 /* RECEIVEing or GETting */
-#define W_REMO 8 /* Doing a REMOTE command */
-#define W_CONNECT 16 /* CONNECT mode */
-#define W_COMMAND 32 /* Command mode */
-#define W_DIALING 64 /* Dialing a modem */
-#define W_FTP 128 /* FTP */
-#define W_FT_DELE 64 /* FTP MDELETE */
-#define W_KERMIT (W_INIT|W_SEND|W_RECV|W_REMO) /* Kermit protocol */
-#define W_XFER (W_INIT|W_SEND|W_RECV|W_REMO|W_FTP) /* File xfer any protocol */
-
-#ifndef NOWHATAMI
-#ifndef WHATAMI
-#define WHATAMI
-#endif /* WHATAMI */
-#endif /* NOWHATAMI */
-
-#ifdef WHATAMI /* Bit mask positions for WHATAMI */
-#define WMI_SERVE 1 /* Server mode */
-#define WMI_FMODE 2 /* File transfer mode */
-#define WMI_FNAME 4 /* File name conversion */
-#define WMI_STREAM 8 /* I have a reliable transport */
-#define WMI_CLEAR 16 /* I have a clear channel */
-#define WMI_FLAG 32 /* Flag that WHATAMI field is valid */
-/* WHATAMI2 bits... */
-#define WMI2_XMODE 1 /* Transfer mode auto(0)/manual(1) */
-#define WMI2_RECU 2 /* Transfer is recursive */
-#define WMI2_FLAG 32 /* Flag that WHATAMI2 field is valid */
-#endif /* WHATAMI */
-
-/* Terminal types */
-#define VT100 0 /* Also for VT52 mode */
-#define TEKTRONIX 1
-
-/* Normal packet and window size */
-
-#define MAXPACK 94 /* Maximum unextended packet size */
- /* Can't be more than 94. */
-#ifdef pdp11 /* Maximum sliding window slots */
-#define MAXWS 8
-#else
-#define MAXWS 32 /* Can't be more than 32. */
-#endif /* pdp11 */
-
-/* Maximum long packet size for sending packets */
-/* Override these from cc command line via -DMAXSP=nnn */
-
-#ifdef IRIX /* Irix 6.4 and earlier has */
-#ifndef MAXSP /* Telnet server bug */
-#ifdef IRIX65
-#define MAXSP 9024
-#else
-#define MAXSP 4000
-#endif /* IRIX65 */
-#endif /* MAXSP */
-#endif /* IRIX */
-
-#ifdef DYNAMIC
-#ifndef MAXSP
-#define MAXSP 9024
-#endif /* MAXSP */
-#else /* not DYNAMIC */
-#ifndef MAXSP
-#ifdef pdp11
-#define MAXSP 1024
-#else
-#define MAXSP 2048
-#endif /* pdp11 */
-#endif /* MAXSP */
-#endif /* DYNAMIC */
-
-/* Maximum long packet size for receiving packets */
-/* Override these from cc command line via -DMAXRP=nnn */
-
-#ifdef DYNAMIC
-#ifndef MAXRP
-#define MAXRP 9024
-#endif /* MAXRP */
-#else /* not DYNAMIC */
-#ifndef MAXRP
-#ifdef pdp11
-#define MAXRP 1024
-#else
-#define MAXRP 2048
-#endif /* pdp11 */
-#endif /* MAXRP */
-#endif /* DYNAMIC */
-/*
- Default sizes for windowed packet buffers.
- Override these from cc command line via -DSBSIZ=nnn, -DRBSIZ=nnn.
- Or just -DBIGBUFOK.
-*/
-#ifndef MAXGETPATH /* Maximum number of directories */
-#ifdef BIGBUFOK /* for GET path... */
-#define MAXGETPATH 128
-#else
-#define MAXGETPATH 16
-#endif /* BIGBUFOK */
-#endif /* MAXGETPATH */
-
-#ifndef NOSPL /* Query buffer length */
-#ifdef OS2
-#define QBUFL 4095
-#else
-#ifdef BIGBUFOK
-#define QBUFL 4095
-#else
-#define QBUFL 1023
-#endif /* BIGBUFOK */
-#endif /* OS2 */
-#endif /* NOSPL */
-
-#ifdef DYNAMIC
-#ifndef SBSIZ
-#ifdef BIGBUFOK /* If big buffers are safe... */
-#define SBSIZ 290000 /* Allow for 10 x 9024 or 20 x 4096 */
-#else /* Otherwise... */
-#ifdef pdp11
-#define SBSIZ 3020
-#else
-#define SBSIZ 9050 /* Allow for 3 x 3000, etc. */
-#endif /* pdp11 */
-#endif /* BIGBUFOK */
-#endif /* SBSIZ */
-
-#ifndef RBSIZ
-#ifdef BIGBUFOK
-#define RBSIZ 290000
-#else
-#ifdef pdp11
-#define RBSIZ 3020
-#else
-#define RBSIZ 9050
-#endif /* pdp11 */
-#endif /* BIGBUFOK */
-#endif /* RBSIZ */
-#else /* not DYNAMIC */
-#ifdef pdp11
-#define SBSIZ 3020
-#define RBSIZ 3020
-#else
-#ifndef SBSIZ
-#define SBSIZ (MAXSP * (MAXWS + 1))
-#endif /* SBSIZ */
-#ifndef RBSIZ
-#define RBSIZ (MAXRP * (MAXWS + 1))
-#endif /* RBSIZ */
-#endif /* pdp11 */
-#endif /* DYNAMIC */
-
-#ifdef BIGBUFOK
-#define PKTMSGLEN 1023
-#else
-#define PKTMSGLEN 80
-#endif /* BIGBUFOK */
-
-/* Kermit parameters and defaults */
-
-#define CTLQ '#' /* Control char prefix I will use */
-#define MYEBQ '&' /* 8th-Bit prefix char I will use */
-#define MYRPTQ '~' /* Repeat count prefix I will use */
-
-#define MAXTRY 10 /* Times to retry a packet */
-#define MYPADN 0 /* How many padding chars I need */
-#define MYPADC '\0' /* Which padding character I need */
-
-#define DMYTIM 8 /* Initial timeout interval to use. */
-#define URTIME 15 /* Timeout interval to use on me. */
-#define DSRVTIM 0 /* Default server cmd wait timeout. */
-
-#define DEFTRN 0 /* Default line turnaround handshake */
-
-#define MYEOL CR /* Incoming packet terminator. */
-
-#ifdef NEWDEFAULTS
-#define DRPSIZ 4095 /* Default incoming packet size. */
-#define DFWSIZ 30 /* Default window size */
-#define DFBCT 3 /* Default block-check type */
-#else
-#define DRPSIZ 90 /* Default incoming packet size. */
-#define DFWSIZ 1 /* Default window size */
-#define DFBCT 3 /* Default block-check type */
-#endif /* NEWDEFAULTS */
-
-/* The HP-UX 5 and 6 Telnet servers can only swallow 513 bytes at once */
-
-#ifdef HPUX5
-#ifdef DRPSIZ
-#undef DRPSIZ
-#endif /* DRPSIZ */
-#define DRPSIZ 500
-#else
-#ifdef HPUX6
-#ifdef DRPSIZ
-#undef DRPSIZ
-#endif /* DRPSIZ */
-#define DRPSIZ 500
-#endif /* HPUX6 */
-#endif /* HPUX5 */
-
-#define DSPSIZ 90 /* Default outbound packet size. */
-#define DDELAY 1 /* Default delay. */
-#define DSPEED 9600 /* Default line speed. */
-
-#ifdef OS2 /* Default CONNECT-mode */
-#define DFESC 29 /* escape character */
-#else
-#ifdef NEXT /* Ctrl-] for PC and NeXT */
-#define DFESC 29
-#else
-#ifdef GEMDOS /* And Atari ST */
-#define DFESC 29
-#else
-#define DFESC 28 /* Ctrl-backslash for others */
-#endif /* GEMDOS */
-#endif /* NEXT */
-#endif /* OS2 */
-
-#ifdef NOPUSH /* NOPUSH implies NOJC */
-#ifndef NOJC /* (no job control) */
-#define NOJC
-#endif /* NOJC */
-#endif /* NOPUSH */
-
-#ifdef UNIX /* Default for SET SUSPEND */
-#ifdef NOJC /* UNIX but job control disabled */
-#define DFSUSP 0
-#else /* UNIX, job control enabled. */
-#define DFSUSP 1
-#endif /* NOJC */
-#else
-#define DFSUSP 0
-#endif /* UNIX */
-
-#ifndef DFCDMSG
-#ifdef UNIXOROSK
-#define DFCDMSG "{{./.readme}{README.TXT}{READ.ME}}"
-#else
-#define DFCDMSG "{{README.TXT}{READ.ME}}"
-#endif /* UNIXOROSK */
-#endif /* DFCDMSG */
-
-#define NSNDEXCEPT 64 /* Max patterns for /EXCEPT: list */
-
-/* Files */
-
-#define ZCTERM 0 /* Console terminal */
-#define ZSTDIO 1 /* Standard input/output */
-#define ZIFILE 2 /* Current input file (SEND, etc) (in) */
-#define ZOFILE 3 /* Current output file (RECEIVE, GET) (out) */
-#define ZDFILE 4 /* Current debugging log file (out) */
-#define ZTFILE 5 /* Current transaction log file (out) */
-#define ZPFILE 6 /* Current packet log file (out) */
-#define ZSFILE 7 /* Current session log file (out) */
-#define ZSYSFN 8 /* Input/Output from a system function */
-#define ZRFILE 9 /* Local file for READ (in) */
-#define ZWFILE 10 /* Local file for WRITE (out) */
-#define ZMFILE 11 /* Miscellaneous file, e.g. for XLATE */
-#define ZDIFIL 12 /* DIAL log */
-#define ZNFILS 13 /* How many defined file numbers */
-
-#ifdef CKCHANNELIO
-
-/* File modes */
-
-#define FM_REA 1 /* Read */
-#define FM_WRI 2 /* Write */
-#define FM_APP 4 /* Append */
-#define FM_RWA 7 /* Read/Write/Append mask */
-#define FM_BIN 8 /* Binary */
-#define FM_RWB 15 /* Read/Write/Append/Binary mask */
-#define FM_CMD 16 /* Command */
-#define FM_EOF 64 /* (status) At EOF */
-
-/* File errors */
-
-#define FX_NER 0 /* No error */
-#define FX_SYS -1 /* System error */
-#define FX_EOF -2 /* End of file */
-#define FX_NOP -3 /* Channel not open */
-#define FX_CHN -4 /* Channel out of range */
-#define FX_RNG -5 /* Argument range error */
-#define FX_FNF -6 /* File not found */
-#define FX_BFN -7 /* Bad or missing filename */
-#define FX_NMF -8 /* No more files */
-#define FX_FOP -9 /* Forbidden operation */
-#define FX_ACC -10 /* Access denied */
-#define FX_BOM -11 /* Bad combination of open modes */
-#define FX_OFL -12 /* Buffer overflow */
-#define FX_LNU -13 /* Current line number unknown */
-#define FX_ROO -14 /* Set Root violation */
-#define FX_NYI -99 /* Feature not implemented yet */
-#define FX_UNK -999 /* Unknown error */
-
-_PROTOTYP( int z_open, (char *, int) );
-_PROTOTYP( int z_close, (int) );
-_PROTOTYP( int z_out, (int, char *, int, int) );
-_PROTOTYP( int z_in, (int, char *, int, int, int) );
-_PROTOTYP( int z_flush, (int) );
-_PROTOTYP( int z_seek, (int, CK_OFF_T) );
-_PROTOTYP( int z_line, (int, CK_OFF_T) );
-_PROTOTYP( int z_getmode, (int) );
-_PROTOTYP( int z_getfnum, (int) );
-_PROTOTYP( CK_OFF_T z_getpos, (int) );
-_PROTOTYP( CK_OFF_T z_getline, (int) );
-_PROTOTYP( CK_OFF_T z_count, (int, int) );
-_PROTOTYP( char * z_getname, (int) );
-_PROTOTYP( char * ckferror, (int) );
-#endif /* CKCHANNELIO */
-
-_PROTOTYP( int scanfile, (char *, int *, int) );
-_PROTOTYP( int scanstring, (char *) );
-
-/* Buffered file i/o ... */
-#ifdef OS2 /* K-95 */
-#define INBUFSIZE 32768
-#define OBUFSIZE 32768
-#else
-#ifdef pdp11
-#define INBUFSIZE 512
-#define OBUFSIZE 512
-#else
-/* In VMS, allow for longest possible RMS record */
-#ifdef VMS
-#define INBUFSIZE 32768 /* File input buffer size */
-#define OBUFSIZE 32768 /* File output buffer size */
-#else /* Not VMS */
-#ifdef STRATUS
-#ifdef DYNAMIC
-#define INBUFSIZE 32767 /* File input buffer size */
-#define OBUFSIZE 32767 /* File output buffer size */
-#else /* STRATUS, not DYNAMIC */
-#define INBUFSIZE 4096 /* File input buffer size */
-#define OBUFSIZE 4096 /* File output buffer size */
-#endif /* DYNAMIC */
-#else /* not STRATUS */
-#ifdef BIGBUFOK /* Systems where memory is */
-#define INBUFSIZE 32768 /* not a problem... */
-#define OBUFSIZE 32768
-#else /* Not BIGBUFOK */
-#define INBUFSIZE 1024
-#define OBUFSIZE 1024
-#endif /* BIGBUFOK */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* pdp11 */
-#endif /* OS2 */
-
-/* File-transfer character in/out macros for buffered i/o */
-
-/* Get the next file byte */
-#ifndef CKCMAI
-#ifndef NOXFER
-extern char ** sndarray;
-#endif /* NOXFER */
-#endif /* CKCMAI */
-#ifdef NOSPL
-#define zminchar() (((--zincnt)>=0) ? ((int)(*zinptr++) & 0377) : zinfill())
-#else
-#ifdef NOXFER
-#define zminchar() (((--zincnt)>=0) ? ((int)(*zinptr++) & 0377) : zinfill())
-#else
-#define zminchar() \
-(sndarray?agnbyte():(((--zincnt)>=0) ? ((int)(*zinptr++) & 0377) : zinfill()))
-#endif /* NOXFER */
-#endif /* NOSPL */
-
-/* Stuff a character into the input buffer */
-#define zmstuff(c) zinptr--, *zinptr = c, zincnt++
-
-/* Put a character to a file */
-#define zmchout(c) \
-((*zoutptr++=(char)(c)),(((++zoutcnt)>=zobufsize)?zoutdump():0))
-
-/* Screen functions */
-
-#define XYFD_N 0 /* File transfer display: None, Off */
-#define XYFD_R 1 /* Regular, Dots */
-#define XYFD_C 2 /* Cursor-positioning (e.g. curses) */
-#define XYFD_S 3 /* CRT Screen */
-#define XYFD_B 4 /* Brief */
-#define XYFD_G 5 /* GUI */
-
-#ifdef NODISPLAY
-#define xxscreen(a,b,c,d)
-#define ckscreen(a,b,c,d)
-#else
-_PROTOTYP( VOID ckscreen, (int, char, CK_OFF_T, char *) );
-#ifdef VMS
-#define xxscreen(a,b,c,d) \
-if (local && fdispla != XYFD_N) \
-ckscreen((int)a,(char)b,(CK_OFF_T)c,(char *)d)
-#else
-#define xxscreen(a,b,c,d) \
-if (local && !backgrd && fdispla != XYFD_N) \
-ckscreen((int)a,(char)b,(CK_OFF_T)c,(char *)d)
-#endif /* VMS */
-#endif /* NODISPLAY */
-
-#define SCR_FN 1 /* filename */
-#define SCR_AN 2 /* as-name */
-#define SCR_FS 3 /* file-size */
-#define SCR_XD 4 /* x-packet data */
-#define SCR_ST 5 /* File status: */
-#define ST_OK 0 /* Transferred OK */
-#define ST_DISC 1 /* Discarded */
-#define ST_INT 2 /* Interrupted */
-#define ST_SKIP 3 /* Skipped */
-#define ST_ERR 4 /* Fatal Error */
-#define ST_REFU 5 /* Refused (use Attribute codes for reason) */
-#define ST_INC 6 /* Incompletely received */
-#define ST_MSG 7 /* Informational message */
-#define ST_SIM 8 /* Transfer simulated (e.g. would be sent) */
-#define SCR_PN 6 /* packet number */
-#define SCR_PT 7 /* packet type or pseudotype */
-#define SCR_TC 8 /* transaction complete */
-#define SCR_EM 9 /* error message */
-#define SCR_WM 10 /* warning message */
-#define SCR_TU 11 /* arbitrary undelimited text */
-#define SCR_TN 12 /* arbitrary new text, delimited at beginning */
-#define SCR_TZ 13 /* arbitrary text, delimited at end */
-#define SCR_QE 14 /* quantity equals (e.g. "foo: 7") */
-#define SCR_CW 15 /* close screen window */
-#define SCR_CD 16 /* display current directory */
-#define SCR_MS 17 /* message from client */
-
-/* Skip reasons */
-
-#define SKP_DAT 1 /* Date-Time (Older) */
-#define SKP_EQU 2 /* Date-Time (Equal) */
-#define SKP_TYP 3 /* Type */
-#define SKP_SIZ 4 /* Size */
-#define SKP_NAM 5 /* Name collision */
-#define SKP_EXL 6 /* Exception list */
-#define SKP_DOT 7 /* Dot file */
-#define SKP_BKU 8 /* Backup file */
-#define SKP_RES 9 /* Recovery not needed */
-#define SKP_ACC 10 /* Access denied */
-#define SKP_NRF 11 /* Not a regular file */
-#define SKP_SIM 12 /* Simulation (WOULD BE SENT) */
-#define SKP_XUP 13 /* Simulation: Would be sent because remote file older */
-#define SKP_XNX 14 /* Simulation: ditto, because remote file does not exist */
-
-/* Macros */
-
-#ifndef CKCMAI
-extern int tcp_incoming; /* Used by ENABLE macro */
-#endif /* CKCMAI */
-
-#ifndef TCPSOCKET
-/*
- ENABLED tells whether a server-side service is enabled.
- 0 = disabled, 1 = local, 2 = remote.
- A "set host *" connection is technically local but logically remote
-*/
-#define ENABLED(x) ((local && (x & 1)) || (!local && (x & 2)))
-#else
-#define ENABLED(x) (((local && !tcp_incoming) && (x & 1)) || \
-((!local || tcp_incoming) && (x&2)))
-#endif /* TCPSOCKET */
-
-/* These are from the book */
-
-#define tochar(ch) (((ch) + SP ) & 0xFF ) /* Number to character */
-#define xunchar(ch) (((ch) - SP ) & 0xFF ) /* Character to number */
-#define ctl(ch) (((ch) ^ 64 ) & 0xFF ) /* Control/Uncontrol toggle */
-#define unpar(ch) (((ch) & 127) & 0xFF ) /* Clear parity bit */
-
-#ifndef NOLOCAL /* CONNECT return status codes */
-
-/* Users will see the numbers so they can't be changed */
-/* Numbers >= 100 indicate connection loss */
-
-#define CSX_NONE 0 /* No CONNECT yet so no status */
-#define CSX_ESCAPE 1 /* User Escaped back */
-#define CSX_TRIGGER 2 /* Trigger was encountered */
-#define CSX_IKSD 3 /* IKSD autosynchronization */
-#define CSX_APC 4 /* Application Program Command */
-#define CSX_IDLE 5 /* Idle limit exceeded */
-#define CSX_TN_ERR 6 /* Telnet Error */
-#define CSX_MACRO 7 /* Macro bound to keystroke */
-#define CSX_TIME 8 /* Time Limit exceeded */
-#define CSX_INTERNAL 100 /* Internal error */
-#define CSX_CARRIER 101 /* Carrier required but not detected */
-#define CSX_IOERROR 102 /* I/O error on connection */
-#define CSX_HOSTDISC 103 /* Disconnected by host */
-#define CSX_USERDISC 104 /* Disconnected by user */
-#define CSX_SESSION 105 /* Session Limit exceeded */
-#define CSX_TN_POL 106 /* Rejected due to Telnet Policy */
-#define CSX_KILL_SIG 107 /* Received Kill Signal */
-
-/* SET TERMINAL IDLE-ACTION values */
-
-#define IDLE_RET 0 /* Return to prompt */
-#define IDLE_EXIT 1 /* Exit from Kermit */
-#define IDLE_HANG 2 /* Hangup the connection */
-#define IDLE_OUT 3 /* OUTPUT a string */
-#define IDLE_TNOP 4 /* TELNET NOP */
-#define IDLE_TAYT 5 /* TELNET AYT */
-#endif /* NOLOCAL */
-
-/* Modem and dialing definitions */
-
-#ifndef NODIAL
-
-/* Modem capabilities (bit values) */
-#define CKD_AT 1 /* Hayes AT commands and responses */
-#define CKD_V25 2 /* V.25bis commands and responses */
-#define CKD_SB 4 /* Speed buffering */
-#define CKD_EC 8 /* Error correction */
-#define CKD_DC 16 /* Data compression */
-#define CKD_HW 32 /* Hardware flow control */
-#define CKD_SW 64 /* (Local) software flow control */
-#define CKD_KS 128 /* Kermit spoofing */
-#define CKD_TB 256 /* Made by Telebit */
-#define CKD_ID 512 /* Has Caller ID */
-
-/* DIAL command result codes */
-#define DIA_UNK -1 /* No DIAL command given yet */
-#define DIA_OK 0 /* DIAL succeeded */
-#define DIA_NOMO 1 /* Modem type not specified */
-#define DIA_NOLI 2 /* Communication line not spec'd */
-#define DIA_OPEN 3 /* Line can't be opened */
-#define DIA_NOSP 4 /* Speed not specified */
-#define DIA_HANG 5 /* Hangup failure */
-#define DIA_IE 6 /* Internal error (malloc, etc) */
-#define DIA_IO 7 /* I/O error */
-#define DIA_TIMO 8 /* Dial timeout expired */
-#define DIA_INTR 9 /* Dialing interrupted by user */
-#define DIA_NRDY 10 /* Modem not ready */
-#define DIA_PART 11 /* Partial dial command OK */
-#define DIA_DIR 12 /* Dialing directory error */
-#define DIA_HUP 13 /* Modem was hung up OK */
-#define DIA_NRSP 19 /* No response from modem */
-#define DIA_ERR 20 /* Modem command error */
-#define DIA_NOIN 21 /* Failure to initialize modem */
-#define DIA_BUSY 22 /* Phone busy */
-#define DIA_NOCA 23 /* No carrier */
-#define DIA_NODT 24 /* No dialtone */
-#define DIA_RING 25 /* Ring, incoming call */
-#define DIA_NOAN 26 /* No answer */
-#define DIA_DISC 27 /* Disconnected */
-#define DIA_VOIC 28 /* Answered by voice */
-#define DIA_NOAC 29 /* Access denied, forbidden call */
-#define DIA_BLCK 30 /* Blacklisted */
-#define DIA_DELA 31 /* Delayed */
-#define DIA_FAX 32 /* Fax */
-#define DIA_DIGI 33 /* Digital Line */
-#define DIA_TAPI 34 /* TAPI dialing failure */
-#define DIA_UERR 98 /* Unknown error */
-#define DIA_UNSP 99 /* Unspecified failure detected by modem */
-
-#define MDMINF struct mdminf
-
-MDMINF { /* Structure for modem-specific information */
-
- char * name; /* Descriptive name */
- char * pulse; /* Command to force pulse dialing */
- char * tone; /* Command to force tone dialing */
- int dial_time; /* Time modem allows for dialing (secs) */
- char * pause_chars; /* Character(s) to tell modem to pause */
- int pause_time; /* Time associated with pause chars (secs) */
- char * wake_str; /* String to wakeup modem & put in cmd mode */
- int wake_rate; /* Delay between wake_str characters (msecs) */
- char * wake_prompt; /* String prompt after wake_str */
- char * dmode_str; /* String to put modem in dialing mode */
- char * dmode_prompt; /* String prompt for dialing mode */
- char * dial_str; /* Dialing string, with "%s" for number */
- int dial_rate; /* Interchar delay to modem (msec) */
- int esc_time; /* Escape sequence guard time (msec) */
- int esc_char; /* Escape character */
- char * hup_str; /* Hangup string */
- char * hwfc_str; /* Hardware flow control string */
- char * swfc_str; /* Software flow control string */
- char * nofc_str; /* No flow control string */
- char * ec_on_str; /* Error correction on string */
- char * ec_off_str; /* Error correction off string */
- char * dc_on_str; /* Data compression on string */
- char * dc_off_str; /* Data compression off string */
- char * aa_on_str; /* Autoanswer on string */
- char * aa_off_str; /* Autoanswer off string */
- char * sb_on_str; /* Speed buffering on string */
- char * sb_off_str; /* Speed buffering off string */
- char * sp_on_str; /* Speaker on string */
- char * sp_off_str; /* Speaker off string */
- char * vol1_str; /* Volume low string */
- char * vol2_str; /* Volume med string */
- char * vol3_str; /* Volume high string */
- char * ignoredt; /* Ignore dialtone string */
- char * ini2; /* Last-minute init string */
- long max_speed; /* Maximum interface speed */
- long capas; /* Capability bits */
- /* function to read modem's response string to a non-dialing command */
- _PROTOTYP( int (*ok_fn), (int,int) );
-};
-#endif /* NODIAL */
-
-/* Symbols for File Attributes */
-
-#define AT_XALL 0 /* All of them */
-#define AT_ALLY 1 /* All of them on (Yes) */
-#define AT_ALLN 2 /* All of them off (no) */
-#define AT_LENK 3 /* Length in K */
-#define AT_FTYP 4 /* File Type */
-#define AT_DATE 5 /* Creation date */
-#define AT_CREA 6 /* Creator */
-#define AT_ACCT 7 /* Account */
-#define AT_AREA 8 /* Area */
-#define AT_PSWD 9 /* Password for area */
-#define AT_BLKS 10 /* Blocksize */
-#define AT_ACCE 11 /* Access */
-#define AT_ENCO 12 /* Encoding */
-#define AT_DISP 13 /* Disposition */
-#define AT_LPRO 14 /* Local Protection */
-#define AT_GPRO 15 /* Generic Protection */
-#define AT_SYSI 16 /* System ID */
-#define AT_RECF 17 /* Record Format */
-#define AT_SYSP 18 /* System-Dependent Parameters */
-#define AT_LENB 19 /* Length in Bytes */
-#define AT_EOA 20 /* End of Attributes */
-
-/* Kermit packet information structure */
-
-struct pktinfo { /* Packet information structure */
- CHAR *bf_adr; /* buffer address */
- int bf_len; /* buffer length */
- CHAR *pk_adr; /* Packet address within buffer */
- int pk_len; /* length of data within buffer */
- int pk_typ; /* packet type */
- int pk_seq; /* packet sequence number */
- int pk_rtr; /* retransmission count */
-};
-
-/* Send Modes (indicating which type of SEND command was used) */
-
-#define SM_SEND 0
-#define SM_MSEND 1
-#define SM_RESEND 2
-#define SM_PSEND 3
-#define SM_MAIL 4
-#define SM_PRINT 5
-
-#define OPTBUFLEN 256
-
-/* File-related symbols and structures */
-/* Used by SET FILE command but also by protocol and i/o modules */
-
-#define XMODE_A 0 /* Transfer mode Automatic */
-#define XMODE_M 1 /* Transfer mode Manual */
-
-#define XYFILN 0 /* Naming */
-#define XYFN_L 0 /* Literal */
-#define XYFN_C 1 /* Converted */
-#define XYFILT 1 /* Type */
-#define XYFT_T 0 /* Text */
-#define XYFT_B 1 /* Binary */
-#define XYFT_I 2 /* Image or Block (VMS) */
-#define XYFT_L 3 /* Labeled (tagged binary) (VMS or OS/2) */
-#define XYFT_U 4 /* Binary Undefined (VMS) */
-#define XYFT_M 5 /* MacBinary (Macintosh) */
-#define XYFT_X 6 /* TENEX (FTP TYPE L 8) */
-#define XYFT_D 99 /* Debug (for session logs) */
-#define XYFILW 2 /* Warning */
-#define XYFILD 3 /* Display */
-#define XYFILC 4 /* Character set */
-#define XYFILF 5 /* Record Format */
-#define XYFF_S 0 /* Stream */
-#define XYFF_V 1 /* Variable */
-#define XYFF_VB 2 /* Variable with RCW's */
-#define XYFF_F 3 /* Fixed length */
-#define XYFF_U 4 /* Undefined */
-#define XYFILR 6 /* Record length */
-#define XYFILO 7 /* Organization */
-#define XYFO_S 0 /* Sequential */
-#define XYFO_I 1 /* Indexed */
-#define XYFO_R 2 /* Relative */
-#define XYFILP 8 /* Printer carriage control */
-#define XYFP_N 0 /* Newline (imbedded control characters) */
-#define XYFP_F 1 /* FORTRAN (space, 1, +, etc, in column 1 */
-#define XYFP_P 2 /* Special printer carriage controls */
-#define XYFP_X 4 /* None */
-#define XYFILX 9 /* Collision Action */
-#define XYFX_A 3 /* Append */
-#define XYFX_Q 5 /* Ask */
-#define XYFX_B 2 /* Backup */
-#define XYFX_D 4 /* Discard */
-#define XYFX_R 0 /* Rename */
-#define XYFX_X 1 /* Replace */
-#define XYFX_U 6 /* Update */
-#define XYFX_M 7 /* Modtimes differ */
-#define XYFILB 10 /* Blocksize */
-#define XYFILZ 11 /* Disposition */
-#define XYFZ_N 0 /* New, Create */
-#define XYFZ_A 1 /* New, append if file exists, else create */
-#define XYFZ_O 2 /* Old, file must exist */
-#define XYFILS 12 /* File Byte Size */
-#define XYFILL 13 /* File Label (VMS) */
-#define XYFILI 14 /* File Incomplete */
-#define XYFILQ 15 /* File path action (strip or not) */
-#define XYFILG 16 /* File download directory */
-#define XYFILA 17 /* Line terminator for local text files */
-#define XYFA_L 012 /* LF (as in UNIX) */
-#define XYFA_C 015 /* CR (as in OS-9 or Mac OS) */
-#define XYFA_2 000 /* CRLF -- Note: this must be defined as 0 */
-#define XYFILY 18 /* Destination */
-#define XYFILV 19 /* EOF Detection Method */
-#define XYEOF_L 0 /* File length */
-#define XYEOF_Z 1 /* Ctrl-Z in file */
-#define XYFILH 20 /* OUTPUT parameters - buffered, blocking, etc */
-#define XYFIBP 21 /* BINARY-PATTERN */
-#define XYFITP 22 /* TEXT-PATTERN */
-#define XYFIPA 23 /* PATTERNS ON/OFF */
-#define XYFILU 24 /* UCS ... */
-#define XYF_PRM 25 /* PERMISSIONS, PROTECTION */
-#define XYF_INSP 26 /* INSPECTION (SCAN) */
-#define XYF_DFLT 27 /* DEFAULT (character sets) */
-#define XYF_SSPA 28 /* STRINGSPACE */
-#define XYF_LSIZ 29 /* LISTSIZE */
-
-/* File Type (return code) definitions and corresponding name strings */
-
-#define FT_7BIT 0 /* 7-bit text */
-#define FT_8BIT 1 /* 8-bit text */
-#define FT_UTF8 2 /* UTF8 */
-#define FT_UCS2 3 /* UCS2 */
-#define FT_TEXT 4 /* Unknown text */
-#define FT_BIN 5 /* Binary */
-#define SCANFILEBUF 49152 /* Size of file scan (48K) */
-
-/* Connection closed reasons */
-
-#define WC_REMO 0 /* Closed by remote */
-#define WC_CLOS 1 /* Closed from our end */
-#define WC_TELOPT 2 /* Telnet negotiation failure */
-
-#ifdef BIGBUFOK
-#define FTPATTERNS 256
-#else
-#define FTPATTERNS 64
-#endif /* BIGBUFOK */
-
-#define SYS_UNK 0 /* Selected server system types */
-#define SYS_UNIX 1
-#define SYS_WIN32 2
-#define SYS_VMS 3
-#define SYS_OS2 4
-#define SYS_DOS 5
-#define SYS_TOPS10 6
-#define SYS_TOPS20 7
-#define SYS_VOS 8
-#define SYS_DG 9
-#define SYS_OSK 10
-#define SYS_MAX 11
-
-#ifdef CK_SMALL
-#define PWBUFL 63
-#else
-#define PWBUFL 255
-#endif /* CK_SMALL */
-
-#ifdef OS2
-struct tt_info_rec { /* Terminal emulation info */
- char *x_name;
- char *x_aliases[4];
- char *x_id;
-};
-#endif /* OS2 */
-
-/* BEEP TYPES */
-#define BP_BEL 0 /* Terminal bell */
-#define BP_NOTE 1 /* Info */
-#define BP_WARN 2 /* Warning */
-#define BP_FAIL 3 /* Error */
-
-#ifndef NOIKSD
-#ifdef IKSDB /* IKSD Database definitions */
-
-/* Field values */
-
-#define DBF_INUSE 1 /* Flag bits... In use */
-#define DBF_USER 2 /* Real user (versus anonymous) */
-#define DBF_LOGGED 4 /* Logged in (versus not) */
-
-/* Data Definitions... */
-
-/* Numeric fields, hex, right justified, 0-filled on left */
-
-#define db_FLAGS 0 /* Field 0: Flags */
-#define DB_FLAGS 0 /* Offset: 0 */
-#define dB_FLAGS 4 /* Length: 4 (hex digits) */
-
-#define db_ATYPE 1 /* Field 1: Authentication type */
-#define DB_ATYPE 4 /* 4 hex digits */
-#define dB_ATYPE 4
-
-#define db_AMODE 2 /* Field 2: Authentication mode */
-#define DB_AMODE 8 /* 4 hex digits */
-#define dB_AMODE 4
-
-#define db_STATE 3 /* Field 3: State - 4 hex digits*/
-#define DB_STATE 12 /* 4 hex digits */
-#define dB_STATE 4
-
-#define db_MYPID 4 /* Field 4: My PID */
-#define DB_MYPID 16 /* 16 hex digits left padded with 0 */
-#define dB_MYPID 16
-
-#define db_SADDR 5 /* Field 5: Server (my) IP address */
-#define DB_SADDR 32 /* 16 hex digits left padded with 0 */
-#define dB_SADDR 16
-
-#define db_CADDR 6 /* Field 6: Client IP address */
-#define DB_CADDR 48 /* 16 hex digits left padded with 0 */
-#define dB_CADDR 16
-
-/* Date-time fields (17 right-adjusted in 18 for Y10K readiness) */
-
-#define db_START 7 /* Field 7: Session start date-time */
-#define DB_START 65 /* 64 is leading space for Y10K */
-#define dB_START 17
-
-#define db_LASTU 8 /* Field 8: Last lastu date-time */
-#define DB_LASTU 83 /* 82 is leading space for Y10K */
-#define dB_LASTU 17
-
-#define db_ULEN 9 /* Field 9: Length of Username */
-#define DB_ULEN 100 /* 4 hex digits */
-#define dB_ULEN 4
-
-#define db_DLEN 10 /* Field 10: Length of Directory */
-#define DB_DLEN 104 /* 4 hex digits */
-#define dB_DLEN 4
-
-#define db_ILEN 11 /* Field 11: Length of Info */
-#define DB_ILEN 108 /* 4 hex digits */
-#define dB_ILEN 4
-
-#define db_PAD1 12 /* Field 12: (Reserved) */
-#define DB_PAD1 112 /* filled with spaces */
-#define dB_PAD1 912
-
-/* String fields, all right-padded with blanks */
-
-#define db_USER 13 /* Field 13: Username */
-#define DB_USER 1024 /* right-padded with spaces */
-#define dB_USER 1024
-
-#define db_DIR 14 /* Field 14: Current directory */
-#define DB_DIR 2048 /* right-padded with spaces */
-#define dB_DIR 1024
-
-#define db_INFO 15 /* Field 15: State-specific info */
-#define DB_INFO 3072 /* right-padded with spaces */
-#define dB_INFO 1024
-
-#define DB_RECL 4096 /* Database record length */
-
-/* Offset, length, and type of each field thru its db_XXX symbol */
-
-#define DBT_HEX 1 /* Hexadecimal number */
-#define DBT_STR 2 /* String */
-#define DBT_DAT 3 /* Date-Time yyyymmdd hh:mm:ss */
-#define DBT_UND 9 /* Undefined and blank */
-
-struct iksdbfld {
- int off; /* Position (offset) */
- int len; /* Length (bytes) */
- int typ; /* Data type */
-};
-_PROTOTYP(int dbinit, (void));
-_PROTOTYP(int initslot, (int));
-_PROTOTYP(int getslot, (void));
-_PROTOTYP(int freeslot, (int));
-_PROTOTYP(int updslot, (int));
-_PROTOTYP(int slotstate, (int, char *, char *, char *));
-_PROTOTYP(int slotdir, (char *, char *));
-#endif /* IKSDB */
-#endif /* NOIKSD */
-
-/* ANSI forward declarations for protocol-related functions. */
-
-_PROTOTYP( int input, (void) );
-_PROTOTYP( int inibufs, (int, int) );
-_PROTOTYP( int makebuf, (int, int, CHAR [], struct pktinfo *) );
-_PROTOTYP( int mksbuf, (int) );
-_PROTOTYP( int mkrbuf, (int) );
-_PROTOTYP( int spack, (char, int, int, CHAR *) );
-_PROTOTYP( VOID proto, (void) );
-_PROTOTYP( int rpack, (void) );
-_PROTOTYP( int ack, (void) );
-_PROTOTYP( int nack, (int) );
-_PROTOTYP( int ackn, (int) );
-_PROTOTYP( int ack1, (CHAR *) );
-_PROTOTYP( int ackns, (int, CHAR *) );
-#ifdef STREAMING
-_PROTOTYP( int fastack, (void) );
-#endif /* STREAMING */
-_PROTOTYP( int resend, (int) );
-_PROTOTYP( int errpkt, (CHAR *) );
-_PROTOTYP( VOID logpkt, (char, int, CHAR *, int) );
-_PROTOTYP( CHAR dopar, (CHAR) );
-_PROTOTYP( int chk1, (CHAR *, int) );
-_PROTOTYP( unsigned int chk2, (CHAR *, int) );
-_PROTOTYP( unsigned int chk3, (CHAR *, int) );
-_PROTOTYP( int sipkt, (char) );
-_PROTOTYP( int sopkt, (void) );
-_PROTOTYP( int sinit, (void) );
-_PROTOTYP( VOID rinit, (CHAR *) );
-_PROTOTYP( int spar, (CHAR *) );
-_PROTOTYP( int rcvfil, (char *) );
-_PROTOTYP( CHAR * rpar, (void) );
-_PROTOTYP( int gnfile, (void) );
-_PROTOTYP( int getsbuf, (int) );
-_PROTOTYP( int getrbuf, (void) );
-_PROTOTYP( int freesbuf, (int) );
-_PROTOTYP( int freerbuf, (int) );
-_PROTOTYP( int dumpsbuf, (void) );
-_PROTOTYP( int dumprbuf, (void) );
-_PROTOTYP( VOID freerpkt, (int) );
-_PROTOTYP( int chkwin, (int, int, int) );
-_PROTOTYP( int rsattr, (CHAR *) );
-_PROTOTYP( char *getreason, (char *) );
-_PROTOTYP( int scmd, (char, CHAR *) );
-_PROTOTYP( int encstr, (CHAR *) );
-_PROTOTYP( int decode, (CHAR *, int (*)(char), int) );
-_PROTOTYP( int bdecode, (CHAR *, int (*)(char)) );
-_PROTOTYP( int fnparse, (char *) );
-_PROTOTYP( int syscmd, (char *, char *) );
-_PROTOTYP( int cwd, (char *) );
-_PROTOTYP( int remset, (char *) );
-_PROTOTYP( int initattr, (struct zattr *) );
-_PROTOTYP( int gattr, (CHAR *, struct zattr *) );
-_PROTOTYP( int adebu, (char *, struct zattr *) );
-_PROTOTYP( int canned, (CHAR *) );
-_PROTOTYP( int opent, (struct zattr *) );
-_PROTOTYP( int ckopenx, (struct zattr *) );
-_PROTOTYP( int opena, (char *, struct zattr *) );
-_PROTOTYP( int openi, (char *) );
-_PROTOTYP( int openo, (char *, struct zattr *, struct filinfo *) );
-_PROTOTYP( int openc, (int, char *) );
-_PROTOTYP( int reof, (char *, struct zattr *) );
-_PROTOTYP( VOID reot, (void) );
-_PROTOTYP( int sfile, (int) );
-_PROTOTYP( int sattr, (int, int) );
-_PROTOTYP( int sdata, (void) );
-_PROTOTYP( int seof, (int) );
-_PROTOTYP( int sxeof, (int) );
-_PROTOTYP( int seot, (void) );
-_PROTOTYP( int window, (int) );
-_PROTOTYP( int clsif, (void) );
-_PROTOTYP( int clsof, (int) );
-_PROTOTYP( CHAR setgen, (char, char *, char *, char *) );
-_PROTOTYP( int getpkt, (int, int) );
-_PROTOTYP( int maxdata, (void) );
-_PROTOTYP( int putsrv, (char) );
-_PROTOTYP( int puttrm, (char) );
-_PROTOTYP( int putque, (char) );
-_PROTOTYP( int putfil, (char) );
-_PROTOTYP( int putmfil, (char) );
-_PROTOTYP( int zputfil, (char) );
-_PROTOTYP( VOID zdstuff, (CHAR) );
-_PROTOTYP( int tinit, (int) );
-_PROTOTYP( VOID pktinit, (void) );
-_PROTOTYP( VOID resetc, (void) );
-_PROTOTYP( VOID xsinit, (void) );
-_PROTOTYP( int adjpkl, (int,int,int) );
-_PROTOTYP( int chktimo, (int,int) );
-_PROTOTYP( int nxtpkt, (void) );
-_PROTOTYP( VOID rcalcpsz, (void) );
-_PROTOTYP( int srinit, (int, int, int) );
-_PROTOTYP( VOID tstats, (void) );
-_PROTOTYP( VOID fstats, (void) );
-_PROTOTYP( VOID intmsg, (long) );
-_PROTOTYP( VOID ermsg, (char *) );
-_PROTOTYP( int chkint, (void) );
-_PROTOTYP( VOID sdebu, (int) );
-_PROTOTYP( VOID rdebu, (CHAR *, int) );
-_PROTOTYP( char * dbchr, ( int ) );
-#ifdef COMMENT
-_PROTOTYP( SIGTYP stptrap, (int, int) );
-_PROTOTYP( SIGTYP trap, (int, int) );
-#else
-_PROTOTYP( SIGTYP stptrap, (int) );
-_PROTOTYP( SIGTYP trap, (int) );
-#endif /* COMMENT */
-_PROTOTYP( char * ck_errstr, (void) );
-#ifndef NOXFER
-_PROTOTYP( int agnbyte, (void) );
-#endif /* NOXFER */
-_PROTOTYP( int xgnbyte, (int, int, int (*)(void)) );
-_PROTOTYP( int xpnbyte, (int, int, int, int (*)(char)) );
-
-/* User interface functions needed by main program, etc. */
-
-_PROTOTYP( int doconect, (int,int) );
-_PROTOTYP( VOID setflow, (void) );
-_PROTOTYP( VOID prescan, (int) );
-_PROTOTYP( VOID setint, (void) );
-_PROTOTYP( VOID doinit, (void) );
-_PROTOTYP( VOID dofast, (void) );
-_PROTOTYP( VOID cmdini, (void) );
-_PROTOTYP( int dotake, (char *) );
-_PROTOTYP( int cmdlin, (void) );
-#ifdef OS2
-_PROTOTYP( int conect, (int) );
-#else /* OS2 */
-_PROTOTYP( int conect, (void) );
-#endif /* OS2 */
-_PROTOTYP( int ckcgetc, (int) );
-_PROTOTYP( int ckcputc, (int) );
-_PROTOTYP (int mdmhup, (void) );
-_PROTOTYP( VOID herald, (void) );
-_PROTOTYP( VOID fixcmd, (void) );
-_PROTOTYP( int doarg, (char) );
-_PROTOTYP( int doxarg, (char **, int) );
-_PROTOTYP( VOID usage, (void) );
-_PROTOTYP( VOID doclean, (int) );
-_PROTOTYP( int sndhlp, (void) );
-_PROTOTYP( int sndstring, (char *) );
-_PROTOTYP( VOID ckhost, (char *, int) );
-_PROTOTYP( int gettcs, (int, int) );
-_PROTOTYP( VOID getdialenv, (void) );
-_PROTOTYP( VOID setprefix, (int) );
-_PROTOTYP(VOID initproto,(int,char *,char *,char *,char *,char *,char*,char*));
-_PROTOTYP( VOID initpat, (void) );
-_PROTOTYP( VOID initcsets, (void) );
-_PROTOTYP( char * getsysid, (char *) );
-_PROTOTYP( int getsysix, (char *) );
-#ifdef CK_TIMERS
-_PROTOTYP( VOID rttinit, (void) );
-_PROTOTYP( int getrtt, (int, int) );
-#endif /* CK_TIMERS */
-
-_PROTOTYP( int is_a_tty, (int) );
-_PROTOTYP( int snddir, (char *) );
-_PROTOTYP( int snddel, (char *) );
-_PROTOTYP( int sndtype, (char *) );
-_PROTOTYP( int dooutput, (char *, int) );
-_PROTOTYP( int isabsolute, (char *) );
-_PROTOTYP( VOID whoarewe, (void) );
-_PROTOTYP( int ckmkdir, (int, char *, char **, int, int) );
-_PROTOTYP( int autoexitchk, (CHAR) );
-_PROTOTYP( VOID fcps, (void) );
-#ifdef OS2
-_PROTOTYP( VOID logchar, (unsigned short) );
-#else /* OS2 */
-_PROTOTYP( VOID logchar, (char) );
-#endif /* OS2 */
-_PROTOTYP( VOID logstr, (char *, int) );
-
-_PROTOTYP( VOID dologend, (void) );
-#ifdef NOLOCAL
-#define dologshow()
-#else
-_PROTOTYP( long dologshow, (int) );
-#endif /* NOLOCAL */
-
-#ifdef NODISPLAY
-#define fxdinit(a)
-#else
-_PROTOTYP( VOID fxdinit, (int) );
-#endif /* NODISPLAY */
-
-_PROTOTYP( int fileselect, (char *,
- char *, char *, char *, char *,
- CK_OFF_T, CK_OFF_T,
- int, int,
- char **) );
-_PROTOTYP( char * whoami, (void) );
-_PROTOTYP( int shoesc, (int) );
-
-#ifdef CK_APC
-_PROTOTYP( int chkspkt, (char *) );
-_PROTOTYP( int kstart, (CHAR) );
-_PROTOTYP( VOID autodown, (int));
-#ifdef CK_XYZ
-_PROTOTYP( int zstart, (CHAR) );
-#endif /* CK_XYZ */
-#ifdef OS2
-_PROTOTYP(void apc_command, (int, char*));
-#endif /* OS2 */
-#endif /* CK_APC */
-
-/* User Query data structures and functions */
-
-struct txtbox {
- char * t_buf; /* Destination buffer address */
- int t_len; /* Destination buffer length */
- char * t_lbl; /* Label for this field */
- char * t_dflt; /* Default response for this field */
- int t_echo; /* 0 = no, 1 = yes, 2 = asterisks */
-};
-
-#define DEFAULT_UQ_TIMEOUT 0
-_PROTOTYP(int uq_ok, (char *,char *,int,char **,int) );
-_PROTOTYP(int uq_txt, (char *,char *,int,char **,char *,int,char *,int));
-_PROTOTYP(int uq_mtxt, (char *,char **,int,struct txtbox[]) );
-_PROTOTYP(int uq_file, (char *,char *,int,char **,char *,char *,int));
-
-#ifdef CK_URL
-struct urlopt {
- char * nam;
- char * val;
-};
-#define MAX_URL_OPTS 16
-struct urldata {
- char * sav; /* The URL itself */
- char * svc; /* Service */
- char * usr; /* User */
- char * psw; /* Password */
- char * hos; /* Host */
- char * por; /* Port */
- char * pth; /* Path */
- int nopts; /* number of options */
- struct urlopt opt[MAX_URL_OPTS]; /* options */
-};
-_PROTOTYP(int urlparse, (char *, struct urldata *));
-#endif /* CK_URL */
-
-#endif /* CKCKER_H */
-
-/* End of ckcker.h */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckclib.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckclib.c
deleted file mode 100644
index 51b9f06..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckclib.c
+++ /dev/null
@@ -1,3319 +0,0 @@
-char * cklibv = "C-Kermit library, 9.0.052, 29 Jun 2011";
-
-#define CKCLIB_C
-
-/* C K C L I B . C -- C-Kermit Library routines. */
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1999, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- General-purpose, system/platform/compiler-independent routines for use
- by all modules. Many are replacements for commonly used C library
- functions that are not found on every platform, and/or that lack needed
- functionality (e.g. caseless string search/compare) or safety features.
-
- ckstrncpy() - Similar to strncpy() but different (see comments).
- ckstrncat() - Similar to strncat() but different (see comments).
- chartostr() - Converts a char to a string (self or ctrl char name).
- ckstrchr() - Portable strchr().
- ckstrpbrk() - Portable strpbrk().
- cklower() - Lowercase a string (in place).
- ckupper() - Uppercase a string (in place).
- ckindex() - Left or right index.
- ckstrstr() - Portable strstr().
- ckitoa() - Converts int to string.
- ckuitoa() - Converts unsigned int to string.
- ckltoa() - Converts long to string.
- ckultoa() - Converts unsigned long to string.
- ckfstoa() - Converts off_t-type integer (long or long long) to string.
- ckatofs() - Converts a numeric string to an off_t-type integer.
- ckctoa() - Converts char to string.
- ckmakmsg() - Constructs a message from 4 source strings.
- ckmakxmsg() - Constructs a message from 12 source strings.
- ckmatch() - Pattern matching.
- ckmemcpy() - Portable memcpy().
- ckrchar() - Rightmost character of a string.
- ckstrcmp() - Possibly caseless string comparison.
- ckstrpre() - Caseless string prefix comparison.
- sh_sort() - Sorts an array of strings, many options.
- brstrip() - Strips enclosing braces (and doublequotes).
- makelist() - Splits "{{item}{item}...}" into an array.
- makestr() - Careful malloc() front end.
- xmakestr() - ditto (see comments).
- ckradix() - Convert number radix (2-36).
- b8tob64() - Convert data to base 64.
- b64tob8() - Convert base 64 to data.
- chknum() - Checks if string is a (possibly signed) integer.
- rdigits() - Checks if string is composed only of decimal digits.
- isfloat() - Checks if string is a valid floating-point number.
- ckround() - Rounds a floating-point number to desired precision.
- parnam() - Returns parity name string.
- hhmmss() - Converts seconds to hh:mm:ss string.
- lset() - Write fixed-length field left-adjusted into a record.
- rset() - Write fixed-length field right-adjusted into a record.
- ulongtohex() - Converts an unsigned long to a hex string.
- hextoulong() - Converts a hex string to an unsigned long.
- cksplit() - Splits a string into an array of words.
- ispattern() - Tells if argument string is a pattern.
-
- Prototypes are in ckclib.h.
-
- Note: This module should not contain any extern declarations.
-*/
-#include "ckcsym.h"
-#include "ckcdeb.h"
-#include "ckcasc.h"
-
-/* Public variables */
-
-int dblquo = 1; /* Nonzero if doublequotes can be used for grouping */
-
-char *
-ccntab[] = { /* Names of ASCII (C0) control characters 0-31 */
- "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
- "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
- "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
- "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
-};
-
-char *
-c1tab[] = { /* Names of ISO 6429 (C1) control characters 0-32 */
- "XXX", "XXX", "BPH", "NBH", "IND", "NEL", "SSA", "ESA",
- "HTS", "HTJ", "VTS", "PLD", "PLU", "RI", "SS2", "SS3",
- "DCS", "PU1", "PU2", "STS", "CCH", "MW", "SPA", "EPA",
- "SOS", "XXX", "SCI", "CSI", "ST", "OSC", "PM", "APC", "NBS"
-};
-
-#define RXRESULT 127
-static char rxdigits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-static char rxresult[RXRESULT+1];
-
-/* C K S T R N C P Y */
-
-/*
- Copies a NUL-terminated string into a buffer whose total length is given,
- ensuring that the result is NUL-terminated even if it has to be truncated.
-
- Call with:
- dest = pointer to destination buffer
- src = pointer to source string
- len = length of destination buffer (the actual length, not one less).
-
- Returns:
- int, The number of bytes copied, 0 or more.
-
- NOTE: This is NOT a replacement for strncpy():
- . strncpy() does not require its source string to be NUL-terminated.
- . strncpy() does not necessarily NUL-terminate its result.
- . strncpy() right-pads dest with NULs if it is longer than src.
- . strncpy() treats the length argument as the number of bytes to copy.
- . ckstrncpy() treats the length argument as the size of the dest buffer.
- . ckstrncpy() doesn't dump core if given NULL string pointers.
- . ckstrncpy() returns a number.
-
- Use ckstrncpy() when you want to:
- . Copy an entire string into a buffer without overrun.
- . Get the length of the string back.
-
- Use strncpy() when you want to:
- . Copy a piece of a string.
-*/
-int
-#ifdef CK_ANSIC
-ckstrncpy(char * dest, const char * src, int len)
-#else
-ckstrncpy(dest,src,len) char * dest, * src; int len;
-#endif /* CK_ANSIC */
-{
- int i;
- if (len < 1 || !src || !dest) { /* Nothing or nowhere to copy */
- if (dest) *dest = NUL;
- return(0);
- }
-#ifndef NOCKSTRNCPY
- for (i = 0; src[i] && (i < len-1); i++) /* Args OK, copy */
- dest[i] = src[i];
- dest[i] = NUL;
-#else
- i = strlen(src);
- if (i > len) i = len;
- strncpy(dest,src,i);
- dest[len] = NUL;
-#endif /* NOCKSTRNCPY */
- return(i);
-}
-
-/* C K S T R N C A T */
-
-/*
- Appends a NUL-terminated string to a buffer whose total length is given,
- ensuring that the result is NUL-terminated even if it had to be truncated.
-
- Call with:
- dest = pointer to destination buffer containing a null-terminated string
- src = pointer to null-terminated source string
- len = length of destination buffer (the actual length, not one less).
-
- Returns:
- int, The number of bytes copied, 0 or more.
-*/
-int
-#ifdef CK_ANSIC
-ckstrncat(char * dest, const char * src, int len)
-#else
-ckstrncat(dest,src,len) char * dest, * src; int len;
-#endif /* CK_ANSIC */
-{
- register int i, j;
-#ifdef NOCKSTRNCPY
- register char * s1, * s2;
-#endif /* NOCKSTRNCPY */
- if (len < 1 || !src || !dest) { /* Nothing or nowhere to copy */
- if (dest) *dest = NUL;
- return(0);
- }
-#ifndef NOCKSTRNCPY
- /* Args OK, copy */
- for (i = 0, j = strlen(dest); src[i] && (i < len-j-1); i++)
- dest[i+j] = src[i];
- dest[i+j] = NUL;
-#else
- j = 0;
- s1 = dest;
- while (*s1++) j++; /* j = strlen(dest); */
- s1--; /* (back up over NUL) */
-
- i = 0;
- s2 = (char *)src;
- while (*s2++) i++; /* i = strlen(src); */
-
- if (i > (len-j))
- i = len - j;
- if (i <= 0)
- return(0);
-
-#ifdef COMMENT
- strncpy(&dest[j],src,i);
-#else
- j = i; /* This should be a bit faster... */
- s2 = (char *)src; /* depends on strcpy implementation; */
- while ((*s1++ = *s2++) && j--) /* at least it shouldn't be slower. */
- ;
- dest[len-1] = NUL; /* In case of early exit. */
-#endif /* COMMENT */
-
-#endif /* NOCKSTRNCPY */
- return(i);
-}
-
-/* C K M A K M S G */
-
-/*
- Constructs a message from up to 4 pieces with length checking.
- Result is always NUL terminated. Call with:
- buf: Pointer to buffer for constructing message.
- len: Length of buffer.
- s1-s4: String pointers (can be NULL).
- Returns:
- 0: Nothing was copied.
- n: (positive number) n bytes copied, all args copied successfully.
- -n: n bytes were copied, destination buffer not big enough for all.
- Also see:
- ckmakxmsg() -- accepts 12 string args.
- ckitoa(), ckltoa(), ckctoa(), ckitox(), etc.
- Use ckmak[x]msg() plus ck?to?() as a safe replacement for sprintf().
-*/
-int
-#ifdef CK_ANSIC
-ckmakmsg(char * buf, int len, char *s1, char *s2, char *s3, char *s4)
-#else /* CK_ANSIC */
-ckmakmsg(buf,len,s1,s2,s3,s4) char *buf, *s1, *s2, *s3, *s4; int len;
-#endif /* CK_ANSIC */
-{
- int i, n = 0, m = 0;
- char *s;
- char *p, *a[4];
-
- if (!buf) return(n); /* No destination */
- if (len < 1) return(n); /* No size */
-
- s = buf; /* Point to destination */
- a[0] = s1; a[1] = s2; a[2] = s3; a[3] = s4; /* Array of source strings */
- for (i = 0; i < 4; i++) { /* Loop thru array */
- p = a[i]; /* Point to this element */
- if (p) { /* If pointer not null */
- n = ckstrncpy(s,p,len); /* Copy safely */
- m += n; /* Accumulate total */
- if (p[n]) /* Didn't get whole thing? */
- return(-m); /* return indicating buffer full */
- len -= n; /* Deduct from space left */
- s += n; /* Otherwise advance dest pointer */
- }
- }
- return(m); /* Return total bytes copied */
-}
-
-
-/* C K M A K X M S G */
-
-/* Exactly like ckmakmsg(), but accepts 12 string arguments. */
-
-int
-#ifdef CK_ANSIC
-ckmakxmsg(char * buf, int len,
- char *s1, char *s2, char *s3, char *s4, char *s5, char *s6,
- char *s7, char *s8, char *s9, char *s10, char *s11, char *s12)
-#else /* CK_ANSIC */
-ckmakxmsg(buf,len,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12)
- char *buf, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11, *s12;
- int len;
-#endif /* CK_ANSIC */
-{
- int i, n = 0, m = 0;
- char *s;
- char *p, *a[12];
-
-
- if (!buf) return(n); /* No destination */
- if (len < 1) return(n); /* No size */
-
- s = buf; /* Point to destination */
- a[0] = s1; a[1] = s2; a[2] = s3; a[3] = s4; /* Source-string array */
- a[4] = s5; a[5] = s6; a[6] = s7; a[7] = s8;
- a[8] = s9; a[9] = s10; a[10] = s11; a[11] = s12;
- for (i = 0; i < 12; i++) { /* Loop thru array */
- p = a[i]; /* Point to this element */
- if (p) { /* If pointer not null */
- n = ckstrncpy(s,p,len); /* Copy safely */
- m += n; /* Accumulate total */
- if (p[n]) /* Didn't get whole thing? */
- return(-m); /* return indicating buffer full */
- len -= n; /* Deduct from space left */
- s += n; /* Otherwise advance dest pointer */
- }
- }
- return(m); /* Return total bytes copied */
-}
-
-/* C H A R T O S T R */
-
-/* Converts a character to a string, interpreting controls. */
-
-char *
-chartostr(x) int x; { /* Call with char x */
- static char buf[2]; /* Returns string pointer. */
- if (x < 32)
- return(ccntab[x]);
- if (x == 127)
- return("DEL");
- if (x > 127 && x < 161)
- return(c1tab[x - 128]);
- if (x == 0xAD)
- return("SHY");
- buf[1] = NUL;
- buf[0] = (unsigned)(x & 0xff);
- return((char *)buf);
-}
-
-/* C K R C H A R */
-
-/* Returns the rightmost character of the given null-terminated string */
-
-int
-ckrchar(s) char * s; {
- register CHAR c = '\0', *p;
- p = (CHAR *)s;
- if (!p) p = (CHAR *)""; /* Null pointer == empty string */
- if (!*p) return(0);
- while (*p) /* Crawl to end of string */
- c = *p++;
- return((unsigned)(c & 0xff)); /* Return final character */
-}
-
-/* C K S T R C H R */
-
-/* Replacement for strchr(), which is not universal. */
-/* Call with:
- s = pointer to string to look in.
- c = character to look for.
- Returns:
- NULL if c not found in s or upon any kind of error, or:
- pointer to first occurrence of c in s, searching from left to right.
-*/
-char *
-#ifdef CK_ANSIC
-ckstrchr(char * s, char c)
-#else
-ckstrchr(s,c) char *s, c;
-#endif /* CK_ANSIC */
-/* ckstrchr */ {
- if (!s)
- return(NULL);
- while (*s && *s != c)
- s++;
- return((*s == c) ? s : NULL);
-}
-
-/* C K S T R R C H R */
-
-/* Replacement for strrchr(), which is not universal. */
-/* Call with:
- s = pointer to string to look in.
- c = character to look for.
- Returns:
- NULL if c not found in s or upon any kind of error, or:
- pointer to first occurrence of c in s, searching from right to left.
-*/
-char *
-#ifdef CK_ANSIC
-ckstrrchr(char * s, char c)
-#else
-ckstrrchr(s,c) char *s, c;
-#endif /* CK_ANSIC */
-/* ckstrchr */ {
- char * s2 = NULL;
- if (!s)
- return(NULL);
- while (*s) {
- if (*s == c)
- s2 = s;
- s++;
- }
- return(s2);
-}
-
-
-/* C K S T R P B R K -- Portable replacement for strpbrk() */
-
-/* Returns pointer to first char in s1 that is also in s2, or NULL */
-
-char *
-ckstrpbrk(s1, s2) char * s1, * s2; {
- char c1, c2, * s3;
- if (!s1 || !s2) return(NULL);
- if (!*s1 || !*s2) return(NULL);
- while ((c1 = *s1++)) {
- s3 = s2;
- while ((c2 = *s3++)) {
- if (c2 == c1)
- return(s1-1);
- }
- }
- return(NULL);
-}
-
-/* C K L O W E R -- Lowercase a string IN PLACE */
-
-/* Returns the length of the string */
-
-int
-cklower(s) char *s; {
- int n = 0;
- if (!s) return(0);
- while (*s) {
- if (isupper(*s)) *s = (char) tolower(*s);
- s++, n++;
- }
- return(n);
-}
-
-/* C K U P P E R -- Uppercase a string IN PLACE */
-
-/* Returns the length of the string */
-
-int
-ckupper(s) char *s; {
- int n = 0;
- if (!s) return(0);
- while (*s) {
- if (islower(*s)) *s = (char) toupper(*s);
- s++, n++;
- }
- return(n);
-}
-
-/* C K L T O A -- Long to string -- FOR DISCIPLINED USE ONLY */
-
-#define NUMBUF 1024
-static char numbuf[NUMBUF+32] = { NUL, NUL };
-static int numbp = 0;
-/*
- ckltoa() and ckitoa() are like atol() and atoi() in the reverse direction,
- returning a pointer to the string representation of the given number without
- the caller having to worry about allocating or defining a buffer first.
- They manage their own internal buffer, so successive calls return different
- pointers. However, to keep memory consumption from growing without bound,
- the buffer recycles itself. So after several hundred calls (depending on
- the size of the numbers), some of the earlier pointers might well find
- themselves referencing something different. Moral: You can't win in C.
- Therefore, these routines are intended mainly for generating numeric strings
- for short-term use, e.g. for passing numbers in string form as parameters to
- functions. For long-term use, the result must be copied to a safe place.
-*/
-char *
-#ifdef CK_ANSIC
-ckltoa(long n)
-#else
-ckltoa(n) long n;
-#endif /* CK_ANSIC */
-/* ckltoa */ {
- char buf[32]; /* Internal working buffer */
- char * p, * s, * q;
- int k, x, len = 0, sign = 0;
- if (n < 0L) { /* Sign */
- n = 0L - n;
- sign = 1;
- }
- buf[31] = NUL;
- for (k = 30; k > 0; k--) { /* Convert number to string */
- x = n % 10L;
- buf[k] = x + '0';
- n = n / 10L;
- if (!n)
- break;
- }
- if (sign) buf[--k] = '-'; /* Add sign if necessary */
- len = 31 - k;
- if (len + numbp > NUMBUF)
- numbp = 0;
- p = numbuf + numbp;
- q = p;
- s = buf + k;
- while ((*p++ = *s++)) ; /* Copy */
- *p++ = NUL;
- numbp += len+1;
- return(q); /* Return pointer */
-}
-
-/* C K U L T O A -- Unsigned long to string */
-
-char *
-#ifdef CK_ANSIC
-ckultoa(unsigned long n)
-#else
-ckultoa(n) unsigned long n;
-#endif /* CK_ANSIC */
-/* ckultoa */ {
- char buf[32]; /* Internal working buffer */
- char * p, * s, * q;
- int k, x, len = 0;
- buf[31] = NUL;
- for (k = 30; k > 0; k--) { /* Convert number to string */
- x = n % 10L;
- buf[k] = x + '0';
- n = n / 10L;
- if (!n)
- break;
- }
- len = 31 - k;
- if (len + numbp > NUMBUF)
- numbp = 0;
- p = numbuf + numbp;
- q = p;
- s = buf + k;
- while ((*p++ = *s++)) ; /* Copy */
- numbp += len+1;
- return(q); /* Return pointer */
-}
-
-char *
-#ifdef CK_ANSIC
-ckltox(long n) /* Long int to "0x.." hex string */
-#else
-ckltox(n) long n;
-#endif /* CK_ANSIC */
-/* ckltox */ {
- char buf[32]; /* Internal working buffer */
- char *p, *q, *s, *bp = buf + 2;
- int k;
- buf[0] = '0';
- buf[1] = 'x';
- sprintf(bp, "%lx", n);
- k = strlen(bp);
- if (k&1) {
- sprintf(bp, "0%lx", n);
- k++;
- }
- k += 2; /* "0x" */
- if (numbp + k >= NUMBUF)
- numbp = 0;
- p = numbuf + numbp;
- q = p;
- s = buf;
- while ((*p++ = *s++)) ; /* Copy */
- *p++ = NUL;
- numbp += k+1;
- return(q); /* Return pointer */
-}
-
-
-/* C K F S T O A -- File Size (or offset) to string */
-
-/* This is just like ckltoa() except for the data type of the argument. */
-/* It's mainly for printing file sizes without having to know their data */
-/* type, so we don't have to hardware "%ld" or "%lld" into printf()s. */
-/* Works for 32 or 64 bits, according to CK_OFF_T definition. */
-
-char *
-#ifdef CK_ANSIC
-ckfstoa(CK_OFF_T n)
-#else
-ckfstoa(n) CK_OFF_T n;
-#endif /* CK_ANSIC */
-/* ckfstoa */ {
- char buf[32]; /* Internal working buffer */
- char * p, * s, * q;
- int k, x, len = 0, sign = 0;
-
- if (n < (CK_OFF_T)0) { /* Sign */
- n = (CK_OFF_T)0 - n;
- sign = 1;
- }
- buf[31] = NUL; /* 2^63-1 is about 20 decimal digits */
- for (k = 30; k > 0; k--) { /* Convert number to string */
- x = n % (CK_OFF_T)10;
- if (x < 0) {
- /* x += 10; */
- ckstrncpy(&buf[23],"OVERFLOW",32);
- sign = 0;
- k = 23;
- break;
- }
- buf[k] = x + '0';
- n = n / (CK_OFF_T)10;
- if (!n)
- break;
- }
- if (sign) buf[--k] = '-'; /* Add sign if necessary */
- len = 31 - k;
- if (len + numbp > NUMBUF)
- numbp = 0;
- p = numbuf + numbp;
- q = p;
- s = buf + k;
- while ((*p++ = *s++)) ; /* Copy */
- *p++ = NUL;
- numbp += len+1;
- return(q); /* Return pointer */
-}
-
-/* C K A T O F S -- String to File Size (or offset) */
-
-/* This is the inverse of ckfstoa(), a replacement for atol() that works */
-/* for either 32-bit or 64-bit arguments, according to CK_OFF_T definition. */
-/* Like atol(), there is no error indication. */
-
-CK_OFF_T
-#ifdef CK_ANSIC
-ckatofs(char * s)
-#else
-ckatofs(s) char * s;
-#endif /* CK_ANSIC */
-/* ckatofs */ {
- CK_OFF_T result = (CK_OFF_T)0;
- int minus = 0;
- while (*s && (*s == SP || *s == HT)) s++;
- if (*s == '+') s++;
- if (*s == '-') {
- minus = 1;
- s++;
- }
- while (isdigit(*s)) {
- result = (result * (CK_OFF_T)10) + (CK_OFF_T)(*s - '0');
- s++;
- }
- return(minus ? -result : result);
-}
-
-/* C K I T O A -- Int to string -- FOR DISCIPLINED USE ONLY */
-
-char *
-ckitoa(n) int n; { /* See comments with ckltoa(). */
- long nn;
- nn = n;
- return(ckltoa(nn));
-}
-
-
-char * /* Unsigned int to string */
-ckuitoa(n) unsigned int n; {
- unsigned long nn;
- nn = n;
- return(ckultoa(nn));
-}
-
-char *
-ckitox(n) int n; { /* Int to hex */
- long nn;
- nn = n;
- return(ckltox(nn));
-}
-
-char *
-#ifdef CK_ANSIC
-ckctoa(char c) /* Char to string */
-#else
-ckctoa(c) char c;
-#endif
-/* ckctoa */ {
- static char buf[32];
- static int current = 0;
- if (current >= 30)
- current = 0;
- buf[current++] = c;
- buf[current++] = '\0';
- return((char *)(buf + current - 2));
-}
-
-char *
-#ifdef CK_ANSIC
-ckctox(CHAR c, int flag) /* Unsigned char to hex */
-#else
-ckctox(c, flag) CHAR c; int flag;
-#endif
-/* ckctox */ {
- static char buf[48];
- static int current = 0;
- int x;
- char h;
- if (current > 45)
- current = 0;
- x = (c >> 4) & 0x0f;
- h = rxdigits[x];
- if (!flag && isupper(rxdigits[x]))
- h = tolower(rxdigits[x]);
- buf[current++] = h;
- x = c & 0x0f;
- h = rxdigits[x];
- if (!flag && isupper(rxdigits[x]))
- h = tolower(rxdigits[x]);
- buf[current++] = h;
- buf[current++] = '\0';
- return((char *)(buf + current - 3));
-}
-
-/* C K I N D E X -- C-Kermit's index function */
-/*
- We can't depend on C libraries to have one, so here is our own.
- Call with:
- s1 - String to look for.
- s2 - String to look in.
- t - Offset from right or left of s2, 0 based; -1 for rightmost char in s2.
- r - 0 for left-to-right search, non-0 for right-to-left.
- icase 0 for case independence, non-0 if alphabetic case matters.
- Returns 0 if string not found, otherwise a 1-based result.
- Also returns 0 on any kind of error, e.g. junk parameters.
-*/
-int
-ckindex(s1,s2,t,r,icase) char *s1, *s2; int t, r, icase; {
- int len1 = 0, len2 = 0, i, j, x, ot = t; /* ot = original t */
- char * s;
-
- if (!s1 || !s2) return(0);
- s = s1;
- while (*s++) len1++; /* length of string to look for */
- s = s2;
- while (*s++) len2++; /* length of string to look in */
- s = s2;
- if (t < 0) t = len2 - 1;
-
- j = len2 - len1; /* length difference */
-
- if (j < 0 || (r == 0 && t > j)) /* search string is longer */
- return(0);
- if (r == 0) { /* Index */
- s = s2 + t; /* Point to beginning of target */
- for (i = 0; i <= (j - t); i++) { /* Now compare */
- x = ckstrcmp(s1,s++,len1,icase);
- if (!x)
- return(i+1+t);
- }
- } else { /* Reverse Index */
- i = len2 - len1; /* Where to start looking */
- if (ot > 0) /* Figure in offset if any */
- i -= t;
- for (j = i; j > -1; j--) {
- if (!ckstrcmp(s1,&s2[j],len1,icase))
- return(j+1);
- }
- }
- return(0);
-}
-
-/* C K S T R S T R -- Portable replacement for strstr() */
-
-/* Returns pointer to first occurrence of s1 in s2, or NULL */
-
-char *
-ckstrstr(s1, s2) char * s1, * s2; {
- int k;
- k = ckindex(s2,s1,0,0,1);
- return((k < 1) ? NULL : &s1[k-1]);
-}
-
-
-/* B R S T R I P -- Strip enclosing braces from arg string, in place. */
-/*
- Call with:
- Pointer to string that can be poked.
- Returns:
- Pointer to string without enclosing braces.
- If original string was not braced, this is the arg pointer;
- otherwise it is 1 + the arg pointer, with the matching closing
- brace zero'd out. If the string starts with a brace but does
- not end with a matching brace, the original pointer to the original
- string is returned. If the arg pointer is NULL, a pointer to an
- empty string is returned.
-*/
-#ifdef COMMENT
-
-/* This is the original version, handling only braces */
-
-char *
-brstrip(p) char *p; {
- if (!p) return("");
- if (*p == '{') {
- int x;
- x = (int)strlen(p) - 1;
- if (p[x] == '}') {
- p[x] = NUL;
- p++;
- }
- }
- return(p);
-}
-
-#else
-/* New version handles braces and doublequotes */
-/* WARNING: this function writes into its argument, it always has. */
-
-char *
-brstrip(p) char *p; {
- if (!p) return("");
- if (*p == '{' || (*p == '"' && dblquo)) {
- int x;
- x = (int)strlen(p) - 1;
- if (x > 0) {
- if ((*p == '{' && p[x] == '}') ||
- (*p == '"' && p[x] == '"')) {
- if (x > 0 && p[x-1] != CMDQ) {
- p[x] = NUL;
- p++;
- }
- }
- }
- }
- return(p);
-}
-#endif /* COMMENT */
-
-#ifdef COMMENT
-
-/* Even newer experimental version -- breaks many things */
-
-char *
-fnstrip(p) char *p; {
- int i, j, k, n, len;
- extern int cmd_quoting; /* Bad - no externs allowed! */
-
- if (!p)
- return("");
-
- if (*p == '{') {
- len = strlen(p);
- n = 0;
-
- for (j = 0; j < len; j++ ) {
- if (p[j] == '{' &&
- (!cmd_quoting || j == 0 || p[j-1] != CMDQ)) {
- for (n = 1, i = j+1; i < len; i++ ) {
- if (p[i] == '{' && (!cmd_quoting || p[i-1] != CMDQ))
- n++;
- else if (p[i] == '}' && (!cmd_quoting || p[i-1] != CMDQ)) {
- if (--n == 0) {
- for (k = j; k < i - 1; k++)
- p[k] = p[k+1];
- for (; i < len; i++ )
- p[i-1] = p[i+1];
- len -= 2;
- j = i - 1;
- }
- }
- }
- }
- }
- if (n == 1) { /* Implied right brace at end of field */
- for (k = j; k < len; k++)
- p[k] = p[k+1];
- len -= 1;
- }
- } else if (*p == '"') {
- len = strlen(p);
- n = 0;
-
- for (j = 0; j < len; j++) {
- if (p[j] == '"' &&
- (!cmd_quoting || j == 0 || p[j-1] != CMDQ)) {
- n++;
-
- for (i = j + 1; i < len; i++) {
- if (p[i] == '"' && (!cmd_quoting || p[i-1] != CMDQ)) {
- n--;
-
- for (k = j; k < i - 1; k++)
- p[k] = p[k+1];
- for (; i < len; i++)
- p[i-1] = p[i+1];
- len -= 2;
- j = i - 1;
- }
- }
- }
- }
- if (n == 1) { /* Implied double quote at end of field */
- for (k = j; k < len; k++ )
- p[k] = p[k+1];
- len -= 1;
- }
- }
- return(p);
-}
-#endif /* COMMENT */
-
-#ifdef COMMENT
-/*
- Not used -- Note: these not only write into their arg, but write past
- past the end.
-*/
-char *
-brace(fn) char *fn; {
- int spaces = 0;
- char * p, ch, ch2;
- for (p = fn; *p; p++) {
- if (*p == SP) {
- spaces = 1;
- break;
- }
- }
- if (spaces) {
- p = fn;
- ch = *p;
- *p = '{';
- p++;
-
- while (*p) {
- ch2 = *p;
- *p = ch;
- ch = ch2;
- p++;
- }
- *p = ch;
- p++;
- *p = '}';
- p++;
- *p = '\0';
- }
- return(fn);
-}
-#endif /* COMMENT */
-
-/* d q u o t e -- Puts doublequotes around arg in place. */
-/*
- Call with:
- Pointer to buffer and its total length and flag = 0 to use
- doublequotes, 1 to use braces.
- Returns:
- Number: length of result.
-*/
-int
-dquote(fn, len, flag) char *fn; int len; int flag; {
- int spaces = 0, k = 0;
- char * p, ch, ch2;
- if (!fn)
- return(0);
-
- k = strlen(fn);
- for (p = fn; *p; p++) {
- if (*p == SP) {
- spaces = 1;
- break;
- }
- }
- if (spaces) {
- if (k + 2 >= len)
- return(k);
- p = fn;
- ch = *p;
- *p = flag ? '{' : '"';
- p++;
-
- while (*p) {
- ch2 = *p;
- *p = ch;
- ch = ch2;
- p++;
- }
- *p = ch;
- p++;
- *p = flag ? '}' : '"';
- p++;
- *p = '\0';
- }
- return(k+2);
-}
-
-
-/* U N T A B I F Y --- Untabify s1 into s2, assuming tabs every 8 space */
-
-int
-untabify(s1,s2,max) char * s1, * s2; int max; {
- int i, j, k, x, z;
- x = strlen(s1);
- for (i = 0, k = 0; k < x; k++) {
- if (s1[k] != '\t') {
- if (i >= max-1) {
- s2[max-1] = '\0';
- return(-1);
- }
- s2[i++] = s1[k];
- continue;
- }
- z = 8 - i%8;
- if (z == 0) z = 8;
- for (j = 0; j < z && i < max; j++)
- s2[i++] = ' ';
- }
- s2[i] = '\0';
- return(0);
-}
-
-
-/* M A K E L I S T --- Breaks {{s1}{s2}..{sn}} into an array of strings */
-/*
- Call with:
- s = pointer to string to break up.
- list = array of string pointers.
- len = number of elements in array.
- NOTE: The array must be preinitialized to all NULL pointers.
- If any array element is not NULL, it is assumed to have been malloc'd
- and is therefore freed. Do NOT call this function with an uninitialized
- array, or with an array that has had any static elements assigned to it.
-*/
-VOID
-makelist(s,list,len) char * s; char *list[]; int len; {
- int i, n, q, bc = 0;
- char *p = NULL, *s2 = NULL;
- debug(F110,"makelist s",s,0);
- if (!s) { /* Check for null or empty string */
- list[0] = NULL;
- return;
- }
- n = strlen(s);
- if (n == 0) {
- list[0] = NULL;
- return;
- }
- if ((s2 = (char *)malloc(n+1))) { /* Safe copy for poking */
- strcpy(s2,s); /* (no need for ckstrncpy here) */
- s = s2;
- }
- s = brstrip(s); /* Strip braces */
- n = strlen(s); /* Get length */
- if (*s != '{') { /* Outer braces only */
- if ((p = (char *)malloc(n+1))) { /* So just one pattern */
- strcpy(p,s); /* (no need for ckstrncpy here) */
- if (list[0])
- free(list[0]);
- list[0] = p;
- }
- if (s2) free(s2);
- return;
- }
- q = 0; /* Inner ones too */
- i = 0; /* so a list of patterns. */
- n = 0;
- while (*s && i < len) {
- if (*s == CMDQ) { /* Quote... */
- q = 1;
- s++;
- n++;
- continue;
- }
- if (*s == '{' && !q) { /* Opening brace */
- if (bc++ == 0) { /* Beginning of a group */
- p = ++s;
- n = 0;
- } else { /* It's a brace inside the group */
- n++;
- s++;
- }
- continue;
- } else if (*s == '}' && !q) { /* Closing brace */
- if (--bc == 0) { /* End of a group */
- *s++ = NUL;
- debug(F111,"makelist element",p,i);
- if (list[i])
- free(list[i]);
- if ((list[i] = (char *)malloc(n+1))) {
- ckstrncpy(list[i],p,n+1); /* Note: n+1 */
- i++;
- }
- while (*s == SP) s++;
- p = s;
- n = 0;
- continue;
- } else { /* Within a group */
- n++;
- s++;
- }
- } else { /* Regular character */
- q = 0;
- s++;
- n++;
- }
- }
- if (*p && i < len) { /* Last one */
- if (list[i])
- free(list[i]);
- if ((list[i] = (char *)malloc(n+1))) {
- ckstrncpy(list[i],p,n+1);
- debug(F111,"makelist last element",p,i);
- }
- }
- i++; /* Clear out the rest of the list */
- for ( ; i < len; i++) {
- if (list[i])
- free (list[i]);
- list[i] = NULL;
- }
- if (s2) free(s2);
-}
-
-/*
- M A K E S T R -- Creates a dynamically allocated string.
-
- Makes a new copy of string s and sets pointer p to its address.
- Handles degenerate cases, like when buffers overlap or are the same,
- one or both arguments are NULL, etc.
-
- The source string is assumed to be NUL-terminated. Therefore it can not
- be a UCS-2 string or arbitrary binary data.
-
- The target pointer must be either NULL or else a pointer to a previously
- malloc'ed buffer. If not, expect a core dump or segmentation fault.
-
- Note: The caller can tell whether this routine failed as follows:
-
- malloc(&p,q);
- if (q & !p) { makestr() failed };
-
- Really this routine should have returned a length, but since it doesn't
- we set the global variable makestrlen to the length of the result string.
-*/
-int makestrlen = 0;
-
-VOID
-#ifdef CK_ANSIC
-makestr(char **p, const char *s)
-#else
-makestr(p,s) char **p, *s;
-#endif
-/* makestr */ {
- int x = 0;
- char *q = NULL;
-#ifdef CK_ANSIC
- register const char * s2;
-#else
- register char * s2;
-#endif /* CK_ANSIC */
- register char * q2;
-
- if (*p == s) /* The two pointers are the same. */
- return; /* Don't do anything. */
-
- if (!s) { /* New definition is null? */
- if (*p) /* Free old storage. */
- free(*p);
- *p = NULL; /* Return null pointer. */
- makestrlen = 0;
- return;
- }
- s2 = s; /* Maybe new string will fit */
-
-#ifdef COMMENT
-/*
- This is a fairly big win, allowing us to skip the malloc() and free if the
- destination string already exists and is not shorter than the source string.
- But it doesn't allow for possible overlap of source and destination.
-*/
- if (*p) { /* into old storage... */
- char * p2 = *p;
- char c;
- while (c = *p2) {
- if (!(*p2++ = *s2++))
- break;
- x++;
- }
- makestrlen = x;
- if (c) return;
- }
-#endif /* COMMENT */
-
-/* Didn't fit */
-
- x = 0;
- while (*s2++) x++; /* Get (rest of) length of s. */
-
- if (x >= 0) { /* Get length, even of empty string. */
- q = malloc(x+1); /* Get and point to temp storage. */
- if (q) {
- makestrlen = x; /* Remember length for stats */
- s2 = s; /* Point back to beginning of source */
- q2 = q; /* Copy dest pointer to increment... */
- while ((*q2++ = *s2++)) ; /* Instead of calling strcpy(). */
-/*
- Note: HP flexelint says that the above loop can result in creation (++) and
- access (*) of out-of-bounds pointers. I really don't see it.
-*/
- }
-#ifdef DEBUG
- else { /* This would be a really bad error */
- char tmp[24]; /* So get a good record of it. */
- if (x > 23) {
- ckstrncpy(tmp,s,20);
- strcpy(tmp+20,"...");
- tmp[23] = NUL;
- } else {
- strcpy(tmp,s); /* We already checked the length */
- }
- debug(F110,"MAKESTR MALLOC FAILURE ",tmp,0);
- }
-#endif /* DEBUG */
- } else
- q = NULL; /* Length of string is zero */
-
- if (*p) /* Now free the original storage. */
- free(*p);
- *p = q;
-}
-
-/* X M A K E S T R -- Non-destructive makestr() if s is NULL. */
-
-VOID
-#ifdef CK_ANSIC
-xmakestr(char **p, const char *s)
-#else
-xmakestr(p,s) char **p, *s;
-#endif
-/* xmakestr */ {
- if (s) makestr(p,s);
-}
-
-#ifndef USE_MEMCPY
-/* C K M E M C P Y -- Portable (but slow) memcpy() */
-
-/* Copies n bytes from s to p, allowing for overlap. */
-/* For use when real memcpy() not available. */
-
-VOID
-ckmemcpy(p,s,n) char *p, *s; int n; {
- char * q = NULL;
- register int i;
- int x;
-
- if (!s || !p || n <= 0 || p == s) /* Verify args */
- return;
- x = p - s; /* Check for overlap */
- if (x < 0)
- x = 0 - x;
- if (x < n) { /* They overlap */
- q = p;
- if (!(p = (char *)malloc(n))) /* So use a temporary buffer */
- return;
- }
- for (i = 0; i < n; i++) /* Copy n bytes */
- p[i] = s[i];
- if (q) { /* If we used a temporary buffer */
- for (i = 0; i < n; i++) /* copy from it to destination */
- q[i] = p[i];
- if (p) free(p); /* and free the temporary buffer */
- }
-}
-#endif /* USE_MEMCPY */
-
-
-/* C K S T R C M P -- String comparison with case-matters selection */
-/*
- Call with pointers to the two strings, s1 and s2, a length, n,
- and c == 0 for caseless comparison, nonzero for case matters.
- Call with n == -1 to compare without a length limit.
- Compares up to n characters of the two strings and returns:
- 1 if s1 > s2
- 0 if s1 = s2
- -1 if s1 < s2
- Note: case handling is only as good as isupper() and tolower().
-*/
-int
-ckstrcmp(s1,s2,n,c) char *s1, *s2; register int n, c; {
- register CHAR t1, t2;
- if (n == 0) return(0);
- if (!s1) s1 = ""; /* Watch out for null pointers. */
- if (!s2) s2 = "";
- if (!*s1) return(*s2 ? -1 : 0);
- if (!*s2) return(1);
- while (n--) {
- t1 = (CHAR) *s1++; /* Get next character from each. */
- t2 = (CHAR) *s2++;
- if (!t1) return(t2 ? -1 : 0);
- if (!t2) return(1);
- if (!c) { /* If case doesn't matter */
- if (isupper(t1)) t1 = tolower(t1); /* Convert case. */
- if (isupper(t2)) t2 = tolower(t2);
- }
- if (t1 < t2) return(-1); /* s1 < s2 */
- if (t1 > t2) return(1); /* s1 > s2 */
- }
- return(0); /* They're equal */
-}
-
-/* C K S T R P R E -- Caseless string prefix comparison */
-
-/* Returns position of the first char in the 2 strings that doesn't match */
-
-int
-ckstrpre(s1,s2) char *s1, *s2; {
- CHAR t1, t2;
- int n = 0;
- if (!s1) s1 = "";
- if (!s2) s2 = "";
- while (1) {
- t1 = (CHAR) *s1++;
- t2 = (CHAR) *s2++;
- if (!t1 || !t2) return(n);
- if (isupper(t1)) t1 = tolower(t1);
- if (isupper(t2)) t2 = tolower(t2);
- if (t1 != t2)
- return(n);
- n++;
- }
-}
-
-#define GLOBBING
-
-/* C K M A T C H -- Match a string against a pattern */
-/*
- Call with:
- pattern to be matched.
- string to look for the pattern in.
- icase is 1 if case-sensitive, 0 otherwise.
- opts is a bitmask:
- Bit 0 (=1):
- 1 = Match strings starting with '.'
- 0 = Don't match them (used with UNIX filenames).
- Bit 1 (=2):
- 1 = File globbing (dirseps are fences);
- 0 = Dirseps are not fences.
- Bit 2 (=4):
- 1 = Allow ^ and $ anchors at beginning and end of pattern.
- 0 = Don't allow them (normal case for filename matching).
- Bit 3 (and beyond): Undefined.
- Works only with NUL-terminated strings.
- Pattern may contain any number of ? and/or *.
- If CKREGEX is defined, also [abc], [a-z], and/or {string,string,...}.
- (Note: REGEX is a misnomer, see below.)
-
- Returns:
- 0 if string does not match pattern,
- >= 1, the 1-based position in the string where the match was found.
-
- To be done:
- Find a way to identify the piece of the string that matched the pattern,
- as in Snobol "LINE (PAT . RESULT)". This is now partially done by
- setting matchpos and matchend (except matchend needs some tuning). But
- these are useless unless a copy of the string is kept, or a copy of the
- matching part is made. But that would be too costly in performance --
- this routine has to be fast because it's used for wildcard expansion.
-
- Note:
- Patterns are not the same as regular expressions, in which '*' means
- 0 or more repetitions of the preceding item. For example "a*b" as a
- pattern matches any string that starts with 'a' and ends with 'b'; as a
- regular expression it matches any string of zero or more a's followed by
- one b. Regular expressions are especially useful in matching strings of
- (say) digits, or letters, e.g. "[0-9]*" matches any string of digits.
- So far, Kermit doesn't do this.
-*/
-static char * mypat = NULL; /* For rewriting pattern */
-static int matchpos = 0;
-int matchend = 0;
-static int matchdepth = 0;
-static int stringpos = 0;
-static char * ostring = NULL;
-
-#define MATCHRETURN(x,y) { rc=y; where=x; goto xckmatch; }
-static char * lastpat = NULL;
-
-static int xxflag = 0; /* Global bailout flag for ckmatch() */
-
-int
-ispattern(s) char * s; {
- int quote = 0, sbflag = 0, sb = 0, cbflag = 0, cb = 0;
-
- char c = 0;
- if (*s == '^') return(1);
- while ((c = *s++)) {
- if (quote) {
- quote = 0;
- continue;
- }
- if (c == '\\') {
- quote = 1;
- continue;
- }
- if (c == '*') return(1);
- if (c == '?') return(1);
- /* Unquoted brackets or braces must match */
- if (c == '[') { sbflag++; sb++; continue; }
- if (c == ']') { sb--; continue; }
- if (c == '{') { cbflag++; cb++; continue; }
- if (c == '}') { cb--; continue; }
- if (!*s && c == '$') return(1);
- }
- return(sbflag || cbflag);
-}
-
-int
-ckmatch(pattern, string, icase, opts) char *pattern,*string; int icase, opts; {
- int q = 0, i = 0, k = -1, x, flag = 0;
- int rc = 0; /* Return code */
- int havestar = 0;
- int where = -1;
- CHAR cp; /* Current character from pattern */
- CHAR cs; /* Current character from string */
- char * patstart; /* Start of pattern */
- int plen, dot, globbing, xstar = 0;
- int bronly = 0; /* Whole pattern is {a,b,c,...} */
-
- debug(F111,"CKMATCH ENTRY pat opt",pattern,opts);
- debug(F111,"CKMATCH ENTRY str dep",string,matchdepth);
- /* debug(F101,"CKMATCH ENTRY icase","",icase); */
-
- globbing = opts & 2;
-
- if (!string) string = "";
- if (!pattern) pattern = "";
-
- if (!*pattern) { /* Empty pattern matches anything */
- matchdepth++; /* (it wasn't incremented yet) */
- MATCHRETURN(0,1);
- } else if (!*string) {
- MATCHRETURN(0,0);
- }
- patstart = pattern; /* Remember beginning of pattern */
-
- if (matchdepth == 0) { /* Top-level call? */
- xxflag = 0;
- stringpos = 0; /* Reset indices etc. */
- matchpos = 0;
- matchend = 0;
- ostring = string;
- lastpat = pattern;
- if (*pattern == '{') /* Entire pattern is {a,b.c} */
- bronly = 1; /* Maybe */
- dot = (opts & 1) || /* Match leading dot (if file) */
- ((opts & 2) == 0) || /* always if not file */
- (pattern[0] == '.'); /* or if pattern starts with '.' */
-
- plen = strlen(pattern); /* Length of pattern */
-/* This would be used in calculating length of matching segment */
- if (plen > 0) /* User's pattern ends with '*' */
- if (pattern[plen - 1] == '*')
- xstar = 1;
- if (pattern[0] == '*') { /* User's pattern starts with '*' */
- matchpos = 1;
- debug(F111,"CKMATCH 1",string, matchpos);
- }
- if (opts & 4) { /* ^..$ allowed (top level only) */
- /* Rewrite pattern to account for ^..$ anchoring... */
-
- if (mypat) free(mypat); /* Get space for "*pattern*" */
- mypat = (char *)malloc(plen + 4);
- if (mypat) { /* Got space? */
- char * s = pattern, * p = mypat; /* Set working pointers */
- if (*s == '^') { /* First source char is ^ */
- s++; /* so skip past it */
- } else if (*s != '*') { /* otherwise */
- *p++ = '*'; /* prepend '*' to pattern */
- }
- while (*s) { /* Copy rest of pattern */
- if (!*(s+1)) { /* Final pattern character? */
- if (*s != '$') { /* If it's not '$' */
- *p++ = *s; /* Copy it into the pattern */
- if (*s++ != '*') /* And if it's also not '*' */
- *p++ = '*'; /* append '*'. */
- }
- break; /* Done */
- } else /* Not final character */
- *p++ = *s++; /* Just copy it */
- }
- *p = NUL; /* Terminate the new pattern */
- pattern = mypat; /* Make the switch */
- }
- debug(F110,"CKMATCH INIT pat",pattern,0);
- }
- }
- matchdepth++; /* Now increment call depth */
-
-#ifdef UNIX
- if (!dot) { /* For UNIX file globbing */
- if (*string == '.' && *pattern != '.' && !matchdot) {
- if (
-#ifdef CKREGEX
- *pattern != '{' && *pattern != '['
-#else
- 1
-#endif /* CKREGEX */
- ) {
- debug(F110,"ckmatch skip",string,0);
- MATCHRETURN(1,0);
- }
- }
- }
-#endif /* UNIX */
- while (1) {
- k++;
- cp = *pattern; /* Character from pattern */
- cs = *string; /* Character from string */
-
-#ifdef COMMENT
- debug(F000,"CKMATCH pat cp",pattern,cp);
- debug(F000,"CKMATCH str cs",string,cs);
-#endif /* COMMENT */
-
- if (!cs) { /* End of string - done. */
- x = (!cp || (cp == '*' && !*(pattern+1))) ? 1 : 0;
- if (x) {
- if (!matchpos) {
- matchpos = stringpos;
- debug(F111,"CKMATCH A",string, matchpos);
- }
- matchend = stringpos;
- MATCHRETURN(2,matchpos);
- }
- debug(F111,"CKMATCH ZERO d",string, matchpos);
- matchpos = 0;
- MATCHRETURN(16,matchpos);
- }
- if (!icase) { /* If ignoring case */
- if (isupper(cp)) /* convert both to lowercase. */
- cp = tolower(cp);
- if (isupper(cs))
- cs = tolower(cs);
- }
- if (q) { /* This character was quoted */
- debug(F000,"CKMATCH QUOTED",pattern,cp);
- q = 0; /* Turn off quote flag */
-
- if (cs == cp) { /* Compare directly */
- if (!matchpos) { /* Matches */
- matchpos = stringpos;
- debug(F111,"CKMATCH \\ new match",string, matchpos);
- }
- pattern++;
- } else { /* Doesn't match */
- pattern = lastpat; /* Back up the pattern */
- matchpos = 0;
- debug(F111,"CKMATCH \\ no match",pattern, matchpos);
- }
- string++;
- stringpos++;
- continue;
- }
- if (cp == CMDQ && !q) { /* Quote in pattern */
- debug(F000,"CKMATCH QUOTE",pattern,cp);
- q = 1; /* Set flag */
- pattern++; /* Advance to next pattern character */
- continue; /* and continue. */
- }
- if (cs && cp == '?') { /* '?' matches any char */
- if (!matchpos) {
- matchpos = stringpos;
- debug(F111,"CKMATCH D",string, matchpos);
- }
- debug(F110,"CKMATCH ? pat",pattern,0);
- debug(F110,"CKMATCH ? str",string,0);
- pattern++;
- string++;
- stringpos++;
- continue;
-#ifdef CKREGEX
- } else if (cp == '[') { /* Have bracket */
- int q = 0; /* My own private q */
- char * psave = NULL; /* and backup pointer */
- CHAR clist[256]; /* Character list from brackets */
- CHAR c, c1, c2;
-
- for (i = 0; i < 256; i++) /* memset() etc not portable */
- clist[i] = NUL;
- psave = ++pattern; /* Where pattern starts */
- debug(F111,"CKMATCH [] ",pattern-1, matchpos);
- for (flag = 0; !flag; pattern++) { /* Loop thru pattern */
- c = (CHAR)*pattern; /* Current char */
- debug(F000,">>> pattern char","",c);
- if (q) { /* Quote within brackets */
- q = 0;
- clist[c] = 1;
- continue;
- }
- if (!icase) /* Case conversion */
- if (isupper(c))
- c = tolower(c);
- switch (c) { /* Handle unquoted character */
- case NUL: /* End of string */
- MATCHRETURN(4,0); /* No matching ']' so fail */
- case CMDQ: /* Next char is quoted */
- q = 1; /* Set flag */
- continue; /* and continue. */
- case '-': /* A range is specified */
- c1 = (pattern > psave) ? (CHAR)*(pattern-1) : NUL;
- c2 = (CHAR)*(pattern+1); /* IGNORE OUT-OF-BOUNDS WARNING */
- if (c2 == ']') c2 = NUL; /* (it can't happen) */
- if (c1 == NUL) c1 = c2;
- for (c = c1; c <= c2; c++) {
- clist[c] = 1;
- if (!icase) {
- if (islower(c)) {
- clist[toupper(c)] = 1;
- } else if (isupper(c)) {
- clist[tolower(c)] = 1;
- }
- }
- }
- continue;
- case ']': /* End of bracketed sequence */
- flag = 1; /* Done with FOR loop */
- break; /* Compare what we have */
- default: /* Just a char */
- clist[c] = 1; /* Record it */
- if (!icase) {
- if (islower(c)) {
- clist[toupper(c)] = 1;
- } else if (isupper(c)) {
- clist[tolower(c)] = 1;
- }
- }
- continue;
- }
- }
- debug(F000,">>> cs","",cs);
- debug(F101,">>> clist[cs]","",clist[cs]);
- debug(F000,">>> string",string,*string);
-
- if (!clist[(unsigned)cs]) { /* No match? */
- if (!*string) { /* This clause 16 Jun 2005 */
- MATCHRETURN(5,0); /* Nope, done. */
- }
-/*
- We need to fail here if the [clist] is not allowed to float.
- The [clist] is not allowed to float if it is not preceded
- by an asterisk, right? 30 Dec 2005.
-*/
- if (!havestar) {
- MATCHRETURN(500,0);
- }
- string++; /* From here to end added 2005/6/15 */
- stringpos++;
- pattern = lastpat; /* Back up pattern */
- k = ckmatch(pattern,string,icase,opts);
- if (xxflag) MATCHRETURN(0,0);
- if (!matchpos && k > 0)
- matchpos = stringpos;
- MATCHRETURN(5, (*string) ? matchpos : 0);
- }
- if (!matchpos) {
- matchpos = stringpos;
- debug(F111,"CKMATCH [] match",string, matchpos);
- }
- string++; /* Yes, advance string pointer */
- stringpos++;
- continue; /* and go on. */
- } else if (cp == '{') { /* Braces enclosing list of strings */
- char * p, * s, * s2, * buf = NULL;
- int n, bc = 0;
- int len = 0;
- debug(F111,"CKMATCH {} ",string, matchpos);
- for (p = pattern++; *p; p++) {
- if (*p == '{') bc++;
- if (*p == '}') bc--;
- if (bc < 1) break;
- }
- if (bc != 0) { /* Braces don't match */
- MATCHRETURN(6,0); /* Fail */
- } else { /* Braces do match */
- int q = 0, done = 0;
- len = *p ? strlen(p+1) : 0; /* Length of rest of pattern */
- if (len)
- bronly = 0;
- if (bronly && (matchdepth != 1))
- bronly = 0;
- n = p - pattern; /* Size of list in braces */
- if ((buf = (char *)malloc(n+1))) { /* Copy so we can poke it */
- char * tp = NULL;
- int k, sofar;
- ckstrncpy(buf,pattern,n+1);
- sofar = string - ostring - matchpos + 1;
- if (sofar < 0) sofar = 0;
- debug(F111,"CKMATCH .. string",string,sofar);
- debug(F111,"CKMATCH .. ostring",ostring,sofar);
- n = 0;
- for (s = s2 = buf; 1; s++) { /* Loop through segments */
- n++;
- if (q) { /* This char is quoted */
- q = 0;
- if (!*s)
- done = 1;
- continue;
- }
- if (*s == CMDQ && !q) { /* Quote next char */
- q = 1;
- continue;
- }
- if (!*s || *s == ',') { /* End of this segment */
- int tplen = 0;
- if (!*s) /* If end of buffer */
- done = 1; /* then end of last segment */
- *s = NUL; /* Overwrite comma with NUL */
- debug(F111,"CKMATCH {} segment",s2,done);
- tplen = n + len + sofar + 2;
- if (!*s2) { /* Empty segment, no advancement */
- k = 0;
- } else if ((tp = (char *)malloc(tplen))) {
- int savpos, opts2;
- char * pp;
- pp = matchpos > 0 ?
- &ostring[matchpos-1] :
- ostring;
- if (bronly) {
- if (matchpos > 0)
- ckstrncpy(tp,pp,sofar+1);
- else
- ckstrncpy(tp,pp,sofar);
- } else {
- tp[0] = '*';
- tp[1] = NUL;
- if (matchpos > 0)
- ckstrncpy(&tp[1],pp,sofar+1);
- else
- ckstrncpy(&tp[1],pp,sofar);
- }
- ckstrncat(tp,s2,tplen); /* Current segment */
- ckstrncat(tp,p+1,tplen); /* rest of pattern */
-
- debug(F101,"CKMATCH {} matchpos","",matchpos);
- savpos = matchpos;
- matchpos = 0;
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"CKMATCH {} tp",tp,matchpos);
- debug(F111,"CKMATCH {} string",
- string,matchpos);
- debug(F111,"CKMATCH {} ostring",
- ostring,savpos);
- }
-#endif /* DEBUG */
- /* If segment starts with dot */
- /* then set matchdot option.. */
- opts2 = opts;
- if (*s2 == '.') opts2 |= 1;
- debug(F111,"CKMATCH {} recursing",s2,opts2);
- k = ckmatch(tp,
- (string > ostring) ?
- &ostring[savpos-1] : string,
- icase,opts2);
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"CKMATCH {} k","",k);
- debug(F101,"CKMATCH {} savpos","",savpos);
- }
-#endif /* DEBUG */
- free(tp);
- tp = NULL;
- if (xxflag) MATCHRETURN(0,0);
- if (k == 0) {
- matchpos = savpos;
- }
- if (k > 0) { /* If it matched we're done */
- MATCHRETURN(7,k);
- }
- } else { /* Malloc failure */
- MATCHRETURN(14,0);
- }
- if (k) { /* Successful comparison */
- if (!matchpos) {
- matchpos = stringpos;
- debug(F111,"CKMATCH {} match",
- string, matchpos);
- }
- string += n-1; /* Advance pointers */
- pattern = p+1;
- break;
- }
- if (done) /* If no more segments */
- break; /* break out of segment loop. */
- s2 = s+1; /* Otherwise, on to next segment */
- n = 0;
- }
- }
- free(buf);
- }
- }
-#endif /* CKREGEX */
- } else if (cp == '*') { /* Pattern char is asterisk */
- char * psave;
- char * p, * s = NULL; /* meaning match anything */
- int k, n, q = 0;
- havestar++; /* The rest can float */
- while (*pattern == '*') /* Collapse successive asterisks */
- pattern++;
- psave = pattern; /* First non-asterisk after asterisk */
- lastpat = pattern - 1; /* Ditto, global */
- debug(F111,"CKMATCH * ",string,matchpos);
- for (n = 0, p = psave; *p; p++,n++) { /* Find next meta char */
- if (!q) {
- if (*p == '?' || *p == '*' || *p == CMDQ
-#ifdef CKREGEX
- || *p == '[' || *p == '{'
-#endif /* CKREGEX */
- )
- break;
-#ifdef GLOBBING
- if (globbing
-#ifdef UNIXOROSK
- && *p == '/'
-#else
-#ifdef VMS
- && (*p == '.' || *p == ']' ||
- *p == '<' || *p == '>' ||
- *p == ':' || *p == ';')
-#else
-#ifdef datageneral
- && *p == ':'
-#else
-#ifdef STRATUS
- && *p == '>'
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* UNIXOROSK */
- )
- break;
-#endif /* GLOBBING */
- }
- }
- debug(F111,"CKMATCH * n string",string,n);
- debug(F111,"CKMATCH * n pattrn",pattern,n);
- debug(F111,"CKMATCH * n p",p,n);
- if (n > 0) { /* Literal string to match */
- s = (char *)malloc(n+1);
- if (s) {
- ckstrncpy(s,psave,n+1); /* Copy cuz no poking original */
- if (*p) {
- k = ckindex(s,string,0,0,icase); /* 1-based index() */
- debug(F110,"CKMATCH * Index() string",string,0);
- debug(F110,"CKMATCH * Index() pattrn",s,0);
- debug(F101,"CKMATCH * Index() result","",k);
- } else { /* String is right-anchored */
- k = ckindex(s,string,-1,1,icase); /* rindex() */
- debug(F111,"CKMATCH * Rindex()",string,k);
- debug(F110,"CKMATCH * Rindex() pattrn",s,0);
- debug(F101,"CKMATCH * Rindex() result","",k);
- }
- free(s);
- if (k < 1) {
- MATCHRETURN(8,0);
- }
- debug(F111,"CKMATCH * stringpos matchpos",
- ckitoa(stringpos), matchpos);
- if (!matchpos) {
- matchpos = string - ostring + k;
- debug(F111,"CKMATCH * new match ", string, matchpos);
- }
- string += k + n - 1;
- stringpos += k + n - 1;
- pattern += n;
- debug(F111,"CKMATCH * new string", string, stringpos);
- debug(F110,"CKMATCH * new pattrn", pattern, 0);
- continue;
- }
- } else if (!*p) { /* Asterisk at end matches the rest */
- if (!globbing) { /* (if not filename globbing) */
- if (!matchpos) {
- matchpos = stringpos;
- debug(F111,"CKMATCH *$ ",string, matchpos);
- }
- matchend = stringpos;
- MATCHRETURN(9,matchpos);
- }
-#ifdef GLOBBING
- while (*string) {
- if (globbing /* Filespec so don't cross fields */
-#ifdef OS2
- && *string == '/' || *string == '\\' ||
- *string == ':'
-#else
-#ifdef UNIXOROSK
- && *string == '/'
-#else
-#ifdef VMS
- && (*string == '.' || *string == ']' ||
- *string == '<' || *string == '>' ||
- *string == ':' || *string == ';')
-#else
-#ifdef datageneral
- && *string == ':'
-#else
-#ifdef STRATUS
- && *string == '>'
-#else
- && *string == '/' /* (catch-all) */
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* UNIXOROSK */
-#endif /* OS2 */
- ) {
- matchend = stringpos;
- MATCHRETURN(10,0);
- }
- if (!matchpos) {
- matchpos = stringpos;
- debug(F111,"CKMATCH *$ match",string, matchpos);
- }
- string++;
- stringpos++;
- }
-#endif /* GLOBBING */
- if (!matchpos) {
- matchpos = stringpos;
- debug(F111,"CKMATCH ** match",string, matchpos);
- }
- matchend = stringpos;
- MATCHRETURN(11,matchpos);
-
- } else { /* A meta char follows asterisk */
- if (!*string)
- MATCHRETURN(17, matchpos = 0);
-#ifdef COMMENT
- /* This is more elegant but it doesn't work. */
- p--;
- string++;
- stringpos++;
- k = ckmatch(p,string,icase,opts);
-#else
- while (*string && ((k = ckmatch(p,string,icase,opts)) < 1)) {
- if (xxflag) MATCHRETURN(0,0);
- string++;
- stringpos++;
- }
- if (!*string && k < 1) {
-/*
- Definitely no match so we set a global flag to inibit further backing up
- and retrying by previous incarnations, since they don't see that the string
- and/or pattern, which are on the stack, have been exhausted at this level.
-*/
- xxflag++;
- debug(F111,"CKMATCH DEFINITELY NO MATCH",p,k);
- MATCHRETURN(91,0);
- }
-#endif /* COMMENT */
- debug(F111,"CKMATCH *<meta> k",string, k);
- if (!matchpos && k > 0) {
- matchpos = stringpos;
- debug(F111,"CKMATCH *<meta> matchpos",string, matchpos);
- }
- MATCHRETURN(12, (*string) ? matchpos : 0);
- }
- } else if (cs == cp) {
- pattern++;
- string++;
- stringpos++;
- if (!matchpos) {
- matchpos = stringpos;
- debug(F111,"CKMATCH cs=cp",string, matchpos);
- }
- continue;
- } else {
- MATCHRETURN(13,0);
- }
- }
- xckmatch:
- {
-#ifdef DEBUG
- char msgbuf[256];
-#endif /* DEBUG */
- if (matchdepth > 0)
- matchdepth--;
- matchpos = rc;
-#ifdef DEBUG
- ckmakxmsg(msgbuf,256,
- "CKMATCH RETURN[",
- ckitoa(where),
- "] matchpos=",
- ckitoa(matchpos),
- " matchdepth=",
- ckitoa(matchdepth),
- " pat=",pattern,
- " string=",string,NULL,NULL
- );
- debug(F110,msgbuf,string,0);
-#endif /* DEBUG */
- return(rc);
- }
-}
-
-
-#ifdef CKFLOAT
-/* I S F L O A T -- Verify that arg represents a floating-point number */
-
-/*
- Portable replacement for atof(), strtod(), scanf(), etc.
-
- Call with:
- s = pointer to string
- flag == 0 means entire string must be a (floating-pointing) number.
- flag != 0 means to terminate scan on first character that is not legal.
-
- Returns:
- 1 if result is a legal number;
- 2 if result has a fractional part;
- 0 if not or if string empty.
-
- Side effect:
- Sets global floatval to floating-point value if successful.
-
- Number need not contain a decimal point -- integer is subcase of float.
- Scientific notation not supported.
-*/
-CKFLOAT floatval = 0.0; /* For returning value */
-
-int
-isfloat(s,flag) char *s; int flag; {
- int state = 0;
- int sign = 0;
- char c;
- CKFLOAT d = 0.0, f = 0.0;
-
- if (!s) return(0);
- if (!*s) return(0);
-
- while (isspace(*s)) s++;
-
- if (*s == '-') { /* Handle optional sign */
- sign = 1;
- s++;
- } else if (*s == '+')
- s++;
- while ((c = *s++)) { /* Handle numeric part */
- switch (state) {
- case 0: /* Mantissa... */
- if (isdigit(c)) {
- f = f * 10.0 + (CKFLOAT)(c - '0');
- continue;
- } else if (c == '.') {
- state = 1;
- d = 1.0;
- continue;
- }
- if (flag) /* Not digit or period */
- goto done; /* break if flag != 0 */
- return(0); /* otherwise fail. */
- case 1: /* Fraction... */
- if (isdigit(c)) {
- d *= 10.0;
- f += (CKFLOAT)(c - '0') / d;
- continue;
- }
- default:
- if (flag) /* Illegal character */
- goto done; /* Break */
- return(0); /* or fail, depending on flag */
- }
- }
- done:
- if (sign) f = 0.0 - f; /* Apply sign to result */
- floatval = f; /* Set result */
- return(d ? 2 : 1); /* Succeed */
-}
-
-/*
- c k r o u n d -- Rounds a floating point number or an integer.
-
- fpnum:
- Floating-point number to round.
- places:
- Positive...To how many decimal places.
- Zero.......Round to integer.
- Negative...-1 = nearest ten, -2 = nearest 100, -3 = nearest thousand, etc.
- obuf
- Output buffer for string result if desired.
- obuflen
- Length of output buffer.
- Returns:
- Result as CKFLOAT (which is not going to be as exact as the string result)
- And the exact result in the string output buffer, if one was specified.
-*/
-CKFLOAT
-#ifdef CK_ANSIC
-ckround(CKFLOAT fpnum, int places, char *obuf, int obuflen)
-#else
-ckround(fpnum,places,obuf,obuflen)
- CKFLOAT fpnum; int places, obuflen; char *obuf;
-#endif /* CK_ANSIC */
-/* ckround */ {
- char *s, *s2, *d;
- int i, p, len, x, n, digits;
- int carry = 0;
- int minus = 0;
- char buf[200];
- char * number;
- CKFLOAT value;
- extern int fp_digits;
-
- sprintf(buf,"%200.100f",fpnum); /* Make string version to work with */
- number = (char *) buf; /* Make pointer to it */
-
- p = places; /* Precision */
- d = (char *)0; /* Pointer to decimal or string end */
-
- s = number; /* Fix number... */
- while (*s == ' ' || *s == '\011') s++; /* Strip leading whitespace */
- if (*s == '+') s++; /* Skip leading plus sign*/
- number = s; /* Start of number */
- if (*s == '-') { minus++; number++; s++; } /* Remember if negative */
-
- s = number; /* Don't allow false precision */
- n = 0;
- while (*s && *s != '.') s++, n++; /* Find decimal */
-
- if (p + n > fp_digits) /* Too many digits */
- p = fp_digits - n; /* Don't ask for bogus precision */
- if (p < 0) p = 0; /* But don't ask for less than zero */
- if (n > fp_digits) /* Integer part has too many digits */
- *s = 0; /* but we can't truncate it */
- else /* Magnitude is OK */
- number[fp_digits+1] = 0; /* Truncate fractional part. */
-
- len = (int)strlen(number); /* Length of non-bogus number */
- d = s; /* Pointer to decimal point */
- if (p > 0) { /* Rounding the fractional part */
- if (n + p < len) { /* If it's not already shorter */
- if (*s == '.') s++; /* Skip past decimal */
- s += p; /* Go to desired spot */
- if (*s > '4' && *s <= '9') /* Check value of digit */
- carry = 1;
- *s = 0; /* And end the string */
- s--; /* Point to last digit */
- }
- } else if (p == 0) { /* Rounding to integer */
- if (*s == '.') {
- *s = 0; /* erase the decimal point */
- if (*(s+1)) { /* and there is a factional part */
- if (*(s+1) > '4' && *(s+1) <= '9') /* Check for carry */
- carry = 1;
- }
- s--; /* Point to last digit */
- }
- } else { /* Rounding the integer part */
- if (s + p > number) { /* as in "the nearest hundred" */
- s += p; /* Go left to desired digit */
- *d = 0; /* Discard fraction */
- carry = 0;
- if (*s > '4') /* Check first digit of fraction */
- carry = 1; /* and set carry flag */
- s2 = s;
- while (s2 < d) /* Fill in the rest with zeros */
- *s2++ = '0';
- s--; /* Point to last digit */
- }
- }
- if (carry) { /* Handle carry, if any */
- while (s >= number) {
- if (*s == '.') { /* Skip backwards over decimal */
- s--;
- continue;
- }
- *s += 1; /* Add 1 to current digit */
- carry = 0;
- if (*s <= '9') /* If result is 9 or less */
- break; /* we're done */
- *s = '0'; /* Otherwise put 0 */
- carry = 1; /* carry the 1 */
- s--; /* and back up to next digit */
- }
- }
-#ifdef __alpha
- sscanf(number,"%f",&value); /* Convert back to floating point */
-#else
- sscanf(number,"%lf",&value); /* Convert back to floating point */
-#endif
- if (obuf) strncpy(obuf,number,obuflen); /* Set string result */
- return(value); /* Return floating-point result */
-}
-
-#endif /* CKFLOAT */
-
-/* Sorting routines... */
-
-/* S H _ S O R T -- Shell sort -- sorts string array s in place. */
-
-/*
- Highly defensive and relatively quick.
- Uses shell sort algorithm.
-
- Args:
- s = pointer to array of strings.
- p = pointer to a second array to sort in parallel s, or NULL for none.
- n = number of elements in s.
- k = position of key.
- r = ascending lexical order if zero, reverse lexical order if nonzero.
- c = 0 for case independence, 1 for case matters, 2 for numeric.
-
- If k is past the right end of a string, the string is considered empty
- for comparison purposes.
-
- Hint:
- To sort a piece of an array, call with s pointing to the first element
- and n the number of elements to sort.
-
- Return value:
- None. Always succeeds, unless any of s[0]..s[n-1] are bad pointers,
- in which case memory violations are possible, but C offers no defense
- against this, so no way to gracefully return an error code.
-*/
-VOID
-sh_sort(s,p,n,k,r,c) char **s, **p; int n, k, r, c; {
- int m, i, j, x;
- char *t, *t1, *t2, *u = NULL;
-#ifdef CKFLOAT
- CKFLOAT f1, f2;
-#else
- long n1, n2;
-#endif /* CKFLOAT */
-
- if (!s) return; /* Nothing to sort? */
- if (n < 2) return; /* Not enough elements to sort? */
- if (k < 0) k = 0; /* Key */
-
- m = n; /* Initial group size is whole array */
- while (1) {
- m = m / 2; /* Divide group size in half */
- if (m < 1) /* Small as can be, so done */
- break;
- for (j = 0; j < n-m; j++) { /* Sort each group */
- t = t2 = s[j+m]; /* Compare this one... */
- if (!t) /* But if it's NULL */
- t2 = ""; /* make it the empty string */
- if (p) /* Handle parallel array, if any */
- u = p[j+m];
- if (k > 0 && *t2) {
- if ((int)strlen(t2) < k) /* If key too big */
- t2 = ""; /* make key the empty string */
- else /* Key is in string */
- t2 = t + k; /* so point to key position */
- }
- for (i = j; i >= 0; i -= m) { /* Loop thru comparands s[i..]*/
- t1 = s[i];
- if (!t1) /* Same deal */
- t1 = "";
- if (k > 0 && *t1) {
- if ((int)strlen(t1) < k)
- t1 = "";
- else
- t1 = s[i]+k;
- }
- if (c == 2) { /* Numeric comparison */
- x = 0;
-#ifdef CKFLOAT
- f2 = 0.0;
- f1 = 0.0;
- if (isfloat(t1,1)) {
- f1 = floatval;
- if (isfloat(t2,1))
- f2 = floatval;
- else
- f1 = 0.0;
- }
- if (f2 < f1)
- x = 1;
- else
- x = -1;
-#else
- n2 = 0L;
- n1 = 0L;
- if (rdigits(t1)) {
- n1 = atol(t1);
- if (rdigits(t2))
- n2 = atol(t2);
- else
- n1 = 0L;
- }
- if (n2 < n1)
- x = 1;
- else
- x = -1;
-#endif /* CKFLOAT */
- } else {
- x = ckstrcmp(t1,t2,-1,c); /* Compare */
- }
- if (r == 0 && x < 0)
- break;
- if (r != 0 && x > 0)
- break;
- s[i+m] = s[i];
- if (p) p[i+m] = p[i];
- }
- s[i+m] = t;
- if (p) p[i+m] = u;
- }
- }
-}
-
-
-/* C K R A D I X -- Radix converter */
-/*
- Call with:
- s: a number in string format.
- in: int, specifying the radix of s, 2-36.
- out: int, specifying the radix to convert to, 2-36.
- Returns:
- NULL on error (illegal radix, illegal number, etc.).
- "-1" on overflow (number too big for unsigned long).
- Otherwise: Pointer to result.
-*/
-char *
-ckradix(s,in,out) char * s; int in, out; {
- char c, *r = rxresult;
- int d, minus = 0;
-#ifdef COMMENT
- unsigned long zz = 0L;
- long z = 0L;
-#else
- /*
- To get 64 bits on 32-bit hardware we use off_t, but there
- is no unsigned version of off_t, so we lose the ability to
- detect overflow.
- */
- CK_OFF_T zz = (CK_OFF_T)0;
- CK_OFF_T z = (CK_OFF_T)0;
-#endif /* COMMENT */
-
- if (in < 2 || in > 36) /* Verify legal input radix */
- return(NULL);
- if (out < 2 || out > 36) /* and output radix. */
- return(NULL);
- if (*s == '+') { /* Get sign if any */
- s++;
- } else if (*s == '-') {
- minus++;
- s++;
- }
- while (*s == SP || *s == '0') /* Trim leading blanks or 0's */
- s++;
-/*
- For detecting overflow, we use a signed copy of the unsigned long
- accumulator. If it goes negative, we know we'll overflow NEXT time
- through the loop.
-*/
- for (; *s; s++) { /* Convert from input radix to */
- c = *s; /* unsigned long */
- if (islower(c)) c = toupper(c);
- if (c >= '0' && c <= '9')
- d = c - '0';
- else if (c >= 'A' && c <= 'Z')
- d = c - 'A' + 10;
- else
- return(NULL);
- if (d >= in) /* Check for illegal digit */
- return(NULL);
- zz = zz * in + d;
- if (z < 0L) /* Clever(?) overflow detector */
- return("-1");
- z = zz;
- }
- if (!zz) return("0");
- r = &rxresult[RXRESULT]; /* Convert from unsigned long */
- *r-- = NUL; /* to output radix. */
- while (zz > 0 && r > rxresult) {
- d = zz % (unsigned)out;
- *r-- = rxdigits[d];
- zz = zz / (unsigned)out;
- }
- if (minus) *r-- = '-'; /* Replace original sign */
- return((char *)(r+1));
-}
-
-#ifndef NOB64
-/* Base-64 conversion routines */
-
-static char b64[] = { /* Encoding vector */
-#ifdef pdp11
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
-#else
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S',
- 'T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l',
- 'm','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4',
- '5','6','7','8','9','+','/','=','\0'
-#endif /* pdp11 */
-};
-static int b64tbl[] = { /* Decoding vector */
- -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
- -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
- -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
- -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-/*
- B 8 T O B 6 4 -- Converts 8-bit data to Base64 encoding.
-
- Call with:
- s = Pointer to 8-bit data;
- n = Number of source bytes to encode (SEE NOTE).
- If it's a null-terminated string, you can use -1 here.
- out = Address of output buffer.
- len = Length of output buffer (should > 4/3 longer than input).
-
- Returns:
- >= 0 if OK, number of bytes placed in output buffer,
- with the subsequent byte set to NUL if space permits.
- -1 on error (output buffer space exhausted).
-
- NOTE:
- If this function is to be called repeatedly, e.g. to encode a data
- stream a chunk at a time, the source length must be a multiple of 3
- in all calls but the final one to avoid the generation of extraneous
- pad characters that would throw the decoder out of sync. When encoding
- only a single string, this is not a consideration. No internal state
- is kept, so there is no reset function.
-*/
-int
-b8tob64(s,n,out,len) char * s,* out; int n, len; {
- int b3, b4, i, x = 0;
- unsigned int t;
-
- if (n < 0) n = strlen(s);
-
- for (i = 0; i < n; i += 3,x += 4) { /* Loop through source bytes */
- b3 = b4 = 0;
- t = (unsigned)((unsigned)((unsigned int)s[i] & 0xff) << 8);
- if (n - 1 > i) { /* Do we have another after this? */
- t |= (unsigned)(s[i+1] & 0xff); /* Yes, OR it in */
- b3 = 1; /* And remember */
- }
- t <<= 8; /* Move over */
- if (n - 2 > i) { /* Another one after that? */
- t |= (unsigned)(s[i+2] & 0xff); /* Yes, OR it in */
- b4 = 1; /* and remember */
- }
- if (x + 4 > len) /* Check output space */
- return(-1);
- out[x+3] = b64[b4 ? (t & 0x3f) : 64]; /* 64 = code for '=' */
- t >>= 6;
- out[x+2] = b64[b3 ? (t & 0x3f) : 64];
- t >>= 6;
- out[x+1] = b64[t & 0x3f];
- t >>= 6;
- out[x] = b64[t & 0x3f];
- }
- if (x < len) out[x] = NUL; /* Null-terminate the string */
- return(x);
-}
-
-
-/*
- B 6 4 T O B 8 -- Converts Base64 string to 8-bit data.
-
- Call with:
- s = pointer to Base64 string (whitespace ignored).
- n = length of string, or -1 if null terminated, or 0 to reset.
- out = address of output buffer.
- len = length of output buffer.
-
- Returns:
- >= 0 if OK, number of bytes placed in output buffer,
- with the subsequent byte set to NUL if space permits.
- < 0 on error:
- -1 = output buffer too small for input.
- -2 = input contains illegal characters.
- -3 = internal coding error.
-
- NOTE:
- Can be called repeatedly to decode a Base64 stream, one chunk at a
- time. However, if it is to be called for multiple streams in
- succession, its internal state must be reset at the beginning of
- the new stream.
-*/
-int
-b64tob8(s,n,out,len) char * s,* out; int n, len; { /* Decode */
- static int bits = 0;
- static unsigned int r = 0;
- int i, k = 0, x, t;
- unsigned char c;
-
- if (n == 0) { /* Reset state */
- bits = 0;
- r = 0;
- return(0);
- }
- x = (n < 0) ? strlen(s) : n; /* Source length */
-
- n = ((x + 3) / 4) * 3; /* Compute destination length */
- if (x > 0 && s[x-1] == '=') n--; /* Account for padding */
- if (x > 1 && s[x-2] == '=') n--;
- if (n > len) /* Destination not big enough */
- return(-1); /* Fail */
-
- for (i = 0; i < x; i++) { /* Loop thru source */
- c = (CHAR)s[i]; /* Next char */
- t = b64tbl[c]; /* Code for this char */
- if (t == -2) { /* Whitespace or Ctrl */
- n--; /* Ignore */
- continue;
- } else if (t == -1) { /* Illegal code */
- return(-2); /* Fail. */
- } else if (t > 63 || t < 0) /* Illegal value */
- return(-3); /* fail. */
- bits += 6; /* Count bits */
- r <<= 6; /* Make space */
- r |= (unsigned) t; /* OR in new code */
- if (bits >= 8) { /* Have a byte yet? */
- bits -= 8; /* Output it */
- c = (unsigned) ((r >> bits) & 0xff);
- out[k++] = c;
- }
- }
- if (k < len) out[k] = NUL; /* Null-terminate in case it's */
- return(k); /* a text string */
-}
-#endif /* NOB64 */
-
-/* C H K N U M -- See if argument string is an integer */
-
-/* Returns 1 if OK, zero if not OK */
-/* If OK, string should be acceptable to atoi() or atol() or ckatofs() */
-/* Allows leading space, sign */
-
-int
-chknum(s) char *s; { /* Check Numeric String */
- int x = 0; /* Flag for past leading space */
- int y = 0; /* Flag for digit seen */
- char c;
- debug(F110,"chknum",s,0);
- if (!s) return(0);
- if (!*s) return(0);
- while ((c = *s++)) { /* For each character in the string */
- switch (c) {
- case SP: /* Allow leading spaces */
- case HT:
- if (x == 0) continue;
- else return(0);
- case '+': /* Allow leading sign */
- case '-':
- if (x == 0) x = 1;
- else return(0);
- break;
- default: /* After that, only decimal digits */
- if (c >= '0' && c <= '9') {
- x = y = 1;
- continue;
- } else return(0);
- }
- }
- return(y);
-}
-
-
-/* R D I G I T S -- Verify that all characters in arg ARE DIGITS */
-
-/* Returns 1 if so, 0 if not or if string is empty */
-
-int
-rdigits(s) char *s; {
- if (!s) return(0);
- do {
- if (!isdigit(*s)) return(0);
- s++;
- } while (*s);
- return(1);
-}
-
-/* P A R N A M -- Return parity name */
-
-char *
-#ifdef CK_ANSIC
-parnam(char c)
-#else
-parnam(c) char c;
-#endif /* CK_ANSIC */
-/* parnam */ {
- switch (c) {
- case 'e': return("even");
- case 'o': return("odd");
- case 'm': return("mark");
- case 's': return("space");
- case 0: return("none");
- default: return("invalid");
- }
-}
-
-char * /* Convert seconds to hh:mm:ss */
-#ifdef CK_ANSIC
-hhmmss(long x)
-#else
-hhmmss(x) long x;
-#endif /* CK_ANSIC */
-/* hhmmss(x) */ {
- static char buf[10];
- long s, h, m;
- h = x / 3600L; /* Hours */
- x = x % 3600L;
- m = x / 60L; /* Minutes */
- s = x % 60L; /* Seconds */
- if (x > -1L)
- sprintf(buf,"%02ld:%02ld:%02ld",h,m,s);
- else
- buf[0] = NUL;
- return((char *)buf);
-}
-
-/* L S E T -- Set s into p, right padding to length n with char c; */
-/*
- s is a NUL-terminated string.
- If length(s) > n, only n bytes are moved.
- The result is NOT NUL terminated unless c == NUL and length(s) < n.
- The intended of this routine is for filling in fixed-length record fields.
-*/
-VOID
-lset(p,s,n,c) char *s; char *p; int n; int c; {
- int x;
-#ifndef USE_MEMCPY
- int i;
-#endif /* USE_MEMCPY */
- if (!s) s = "";
- x = strlen(s);
- if (x > n) x = n;
-#ifdef USE_MEMCPY
- memcpy(p,s,x);
- if (n > x)
- memset(p+x,c,n-x);
-#else
- for (i = 0; i < x; i++)
- *p++ = *s++;
- for (; i < n; i++)
- *p++ = c;
-#endif /* USE_MEMCPY */
-}
-
-/* R S E T -- Right-adjust s in p, left padding to length n with char c */
-
-VOID
-rset(p,s,n,c) char *s; char *p; int n; int c; {
- int x;
-#ifndef USE_MEMCPY
- int i;
-#endif /* USE_MEMCPY */
- if (!s) s = "";
- x = strlen(s);
- if (x > n) x = n;
-#ifdef USE_MEMCPY
- memset(p,c,n-x);
- memcpy(p+n-x,s,x);
-#else
- for (i = 0; i < (n - x); i++)
- *p++ = c;
- for (; i < n; i++)
- *p++ = *s++;
-#endif /* USE_MEMCPY */
-}
-
-/* U L O N G T O H E X -- Unsigned long to hex */
-
-/*
- Converts unsigned long arg to hex and returns string pointer to
- rightmost n hex digits left padded with 0's. Allows for longs
- up to 64 bits. Returns pointer to result.
-*/
-char *
-#ifdef CK_ANSIC
-ulongtohex( unsigned long z, int n )
-#else
-ulongtohex(z,n) unsigned long z; int n;
-#endif /* CK_ANSIC */
-/* ulongtohex */ {
- static char hexbuf[17];
- int i = 16, x, k = 0;
- hexbuf[16] = '\0';
- if (n > 16) n = 16;
- k = 2 * (sizeof(long));
- for (i = 0; i < n; i++) {
- if (i > k || z == 0) {
- hexbuf[15-i] = '0';
- } else {
- x = z & 0x0f;
- z = z >> 4;
- hexbuf[15-i] = x + ((x < 10) ? '0' : 0x37);
- }
- }
- return((char *)(&hexbuf[16-i]));
-}
-
-/* H E X T O U L O N G -- Hex string to unsigned long */
-
-/*
- Converts n chars from s from hex to unsigned long.
- Returns:
- 0L or positive, good result (0L is returned if arg is NULL or empty).
- -1L on error: non-hex arg or overflow.
-*/
-long
-hextoulong(s,n) char *s; int n; {
- char buf[64];
- unsigned long result = 0L;
- int d, count = 0;
- int flag = 0;
- if (!s) s = "";
- if (!*s) {
- return(0L);
- }
- if (n < 1)
- return(0L);
- if (n > 63) n = 63;
- strncpy(buf,s,n);
- buf[n] = '\0';
- s = buf;
- while (*s) {
- d = *s++;
- if ((d == '0' || d == ' ')) {
- if (!flag)
- continue;
- } else {
- flag = 1;
- }
- if (islower(d))
- d = toupper(d);
- if (d >= '0' && d <= '9') {
- d -= 0x30;
- } else if (d >= 'A' && d <= 'F') {
- d -= 0x37;
- } else {
- return(-1L);
- }
- if (++count > (sizeof(long) * 2))
- return(-1L);
- result = (result << 4) | (d & 0x0f);
- }
- return(result);
-}
-
-/*
- c k s p l i t -- Splits a string into words, or:
- extracts a given word from a string.
-
- Allows for grouping.
- Operates on a copy of the string; does not alter the original string.
- All strings NUL-terminated.
-
- Call with:
- fc = function code:
- 1 = split, 0 = word.
- n1 = desired word number if fc == 0.
- s1 = source string.
- s2 = break string (NULL to accept default = all non-alphanum).
- s3 = include string (NULL to accept default = all alphanum).
- n2 = grouping mask (OR desired ones together):
- 1 = doublequotes, 2 = braces, 4 = apostrophes,
- 8 = parens, 16 = brackets, 32 = angle brackets,
- -1 = 63 = all of these.
- n3 = group quote character, ASCII value, used and tested only for
- LISP quote, e.g. (a 'b c '(d e f)).
- n4 = 0 to collapse adjacent separators;
- nonzero not to collapse them.
-
- Returns:
- Pointer to struct stringarray, with size:
- -1 = memory allocation error.
- -2 = too many words in string.
- n = number of words (0 or more).
-
- With:
- wordarray = array of pointers to n words (n == 1 if fc == 0), 1-based.
- Each pointer is to a malloc'd string. This array is recycled upon each
- call; if you need to keep the strings, make copies of them. This routine
- must have control of allocation and deallocation.
-
- If a given character is included in the include list, it is not treated
- as a separator or as a grouping character.
-
- Groups may be nested only if they are formed with braces, parens, or
- brackets, but not with quotes or apostrophes since ASCII quotes have no
- intrinsic handedness. Group-start and end characters are treated as
- separators even in the absence of other separators, so a string such as
- "a{b}c" results in three words, not one.
-
- Sample call to split a string into an array:
- struct stringarray * q;
- q = cksplit(1,0,s1,s2,s3,-1,0);
- q->a_size = size (>=0) or failure code (<0)
- q->a_head = pointer to array (elements 0 thru q->asize - 1).
-
- Sample call to extract word n from a string:
- struct stringarray * q;
- q = cksplit(0,n,s1,s2,s3,-1,0);
- q->a_size = size (1) or failure code (<0)
- q->a_head = pointer to array (element 1 is the desired word).
-*/
-
-/* States */
-
-#define ST_BW 0 /* Between Words */
-#define ST_IW 1 /* In Word */
-#define ST_IG 2 /* Start Group */
-
-/* Character Classes (bitmap) */
-
-#define CL_SEP 1 /* Separator */
-#define CL_OPN 2 /* Group Open */
-#define CL_CLS 4 /* Group Close */
-#define CL_DAT 8 /* Data */
-#define CL_QUO 16 /* Group quote */
-
-#ifdef BIGBUFOK
-#ifndef MAXWORDS
-#define MAXWORDS 4096 /* Max number of words */
-#endif /* MAXWORDS */
-#ifndef NESTMAX
-#define NESTMAX 64 /* Maximum nesting level */
-#endif /* NESTMAX */
-#else
-#ifndef MAXWORDS
-#define MAXWORDS 128 /* Max number of words */
-#endif /* MAXWORDS */
-#ifndef NESTMAX
-#define NESTMAX 16 /* Maximum nesting level */
-#endif /* NESTMAX */
-#endif /* BIGBUFOK */
-
-/* static */ char ** wordarray = NULL; /* Result array of word pointers */
-
-static struct stringarray ck_sval = { /* Return value structure */
- NULL, /* Pointer to array */
- 0 /* Size */
-};
-static int * wordsize = NULL;
-
-static VOID
-setword(n,s,len) int n, len; char * s; {
- register char * p;
- register int i, k;
-
- if (!s) s = "";
-
- if (!wordarray) { /* Allocate result array (only once) */
- if (!(wordarray = (char **)malloc((MAXWORDS+1) * sizeof(char *))))
- return;
- if (!(wordsize = (int *)malloc((MAXWORDS+1) * sizeof(int))))
- return;
- for (i = 0; i <= MAXWORDS; i++) { /* Initialize result array */
- wordarray[i] = NULL;
- wordsize[i] = 0;
- }
- }
- if (wordsize[n] < len /* || !wordarray[n] */ ) {
- k = (len < 16) ? 16 : len + (len / 4);
- wordarray[n] = (char *) malloc(k+1);
- wordsize[n] = (wordarray[n]) ? k : 0;
- if (wordarray[n]) {
- p = wordarray[n];
- while ((*p++ = *s++) && k-- > 0) ;
- }
- } else if (len > 0) {
- k = wordsize[n]; /* (In case len arg is a lie) */
- p = wordarray[n];
- while ((*p++ = *s++) && k-- > 0) {
-#ifdef COMMENT
- if ((*(s-1) == CMDQ) && *s != CMDQ) {
- k++;
- p--;
- }
-#endif /* COMMENT */
- }
- } else if (wordarray[n]) {
- wordarray[n][0] = NUL;
- }
-}
-
-static char * splitbuf = NULL;
-static int nsplitbuf = 0;
-
-/* n4 = 1 to NOT collapse adjacent separators */
-
-
-struct stringarray *
-cksplit(fc,n1,s1,s2,s3,n2,n3,n4) int fc,n1,n2,n3,n4; char *s1, *s2, *s3; {
- int splitting = 0; /* What I was asked to do */
- int i, k, ko = 0, n, x, max = MAXWORDS; /* Workers */
- char * s = NULL, * ss, * p; /* Workers */
- char * sep = ""; /* Default break set */
- char * notsep = ""; /* Default include set */
- int grouping = 0; /* Grouping option */
- char * gr_opn = "\"{'([<"; /* Group open brackets */
- char * gr_cls = "\"}')]>"; /* Group close brackets */
- int gr_stk[NESTMAX]; /* Nesting bracket stack */
- int gr_lvl = 0; /* Nesting level */
- int wordnum = 0; /* Current word number */
- CHAR c = 'A'; /* Current char (dummy start value) */
- int class = 0; /* Current character class */
- int state = ST_BW; /* Current FSA state */
- int len = 0; /* Length of current word */
- int slen = 0; /* Length of s1 */
- int gquote = 0; /* Quoted group */
- int cquote = 0; /* Quoted character */
- int collapse = 1; /* Collapse adjacent separators */
- int all = 0; /* s3 == ALL */
- int csv = 0; /* s3 == CSV */
- int tsv = 0; /* s3 == TSV */
- int prevstate = -1;
-
- unsigned int hex80 = 128;
- unsigned int hexff = 255;
- CHAR notsepbuf[256];
-
- notsepbuf[0] = NUL; /* Keep set for "ALL" */
- if (n4) collapse = 0; /* Don't collapse */
-
- for (i = 0; i < NESTMAX; i++) /* Initialize nesting stack */
- gr_stk[i] = 0;
-
- setword(1,NULL,0);
- ck_sval.a_head = wordarray; /* Initialize return value struct */
- ck_sval.a_size = 0;
-
- if (!s1) s1 = ""; /* s1 = source string */
- if (!*s1) { /* If none, nothing to do */
- return(&ck_sval);
- }
- splitting = fc; /* Our job */
- if (splitting) { /* If splitting n = word count */
- n = 0; /* Initialize it */
- } else { /* Otherwise */
-#ifdef COMMENT
- if (n1 < 1) { /* If 0 (or less) */
- ck_sval.a_size = 0; /* nothing to do. */
- return(&ck_sval);
- }
-#else
- if (n1 == 0) { /* If 0 */
- ck_sval.a_size = 0; /* nothing to do. */
- return(&ck_sval);
- }
-#endif /* COMMENT */
- n = n1; /* n = desired word number. */
- }
- slen = 0; /* Get length of s1 */
- debug(F111,"cksplit",s1,n);
-
- p = s1;
-
-#ifdef COMMENT
- while (*p++) slen++; /* Make pokeable copy of s1 */
- if (!splitbuf || slen > nsplitbuf) { /* Allocate buffer if needed */
- int xx;
- if (splitbuf)
- free(splitbuf);
- xx = (slen < 255) ? 255 : xx + (xx / 4);
- debug(F101,"cksplit splitbuf","",xx);
- splitbuf = (char *)malloc(xx+1);
- if (!splitbuf) { /* Memory allocation failure... */
- ck_sval.a_size = -1;
- return(&ck_sval);
- }
- nsplitbuf = xx; /* Remember size of buffer */
- }
-#else
-/*
- The idea is to just copy the string into splitbuf (if it exists). This
- gives us both the copy and the length so we only need to grovel through the
- string once in most cases. Only when splitbuf doesn't exist or is too short
- do we re-malloc(), which should be very infrequent so who cares if we have
- to go through the string again in that case.
-*/
- p = s1;
- s = splitbuf;
- if (splitbuf) { /* Make pokeable copy of s1 */
- while ((*s++ = *p++) && (slen++ < nsplitbuf)) /* Try to copy */
- ;
- }
- if (!splitbuf || slen >= nsplitbuf) { /* Need to do more... */
- int xx;
- if (splitbuf) /* Free previous buf if any */
- free(splitbuf);
- while (*p++) slen++; /* Get (rest of) length */
- xx = (slen < 255) ? 255 : slen + (slen / 4); /* Size of new buffer */
- splitbuf = (char *)malloc(xx+1); /* Allocate it */
- if (!splitbuf) { /* Memory allocation failure... */
- ck_sval.a_size = -1;
- return(&ck_sval);
- }
- nsplitbuf = xx; /* Remember (new) buffer size */
- s = splitbuf;
- p = s1;
- while ((*s++ = *p++)) ;
- }
-
-#endif /* COMMENT */
- s = splitbuf;
- sep = s2; /* s2 = break set */
- if (!sep) sep = "";
- notsep = s3; /* s3 = include set */
- if (!notsep) {
- notsep = "";
- } else if ((all = !ckstrcmp(notsep,"ALL",3,1)) ||
- (csv = !ckstrcmp(notsep,"CSV",3,1)) ||
- (tsv = !ckstrcmp(notsep,"TSV",3,1))) {
- int i, flag; CHAR c;
- int n = 0;
- char * ss;
- if (!all && (csv || tsv)) {
- all = 1;
- collapse = 0;
- }
- if (csv || tsv) {
- all = 1;
- collapse = 0;
- }
- for (i = 1; i < 256; i++) {
- flag = 0;
- ss = sep;
- while (c = *ss++ && !flag) {
- if (c == i) flag++;
- }
- if (!flag) notsepbuf[n++] = c;
- }
- notsepbuf[n] = NUL;
- notsep = (char *)notsepbuf;
- debug(F110,"CKMATCH NOTSEPBUF ALL",notsep,0);
- }
- if (*s && csv) { /* For CSV skip leading whitespace */
- while (*s == SP || *s == HT)
- s++;
- c = *s;
- }
- if (n2 == 0 && csv) n2 = 1; /* CSV implies doublequote grouping */
- if (n2 < 0) n2 = 63; /* n2 = grouping mask */
- grouping = n2;
- p = ""; /* Pointer to current word */
- while (c) { /* Loop through string */
- c = *s;
- class = 0;
- if (!csv && !tsv) { /* fdc 2010-12-30 */
- /* In CSV and TSV splitting, backslash is not special */
- if (!cquote && c == CMDQ) { /* If CMDQ */
- cquote++; /* next one is quoted */
- goto nextc; /* go get it */
- }
-
- }
- if (cquote && c == CMDQ) { /* Quoted CMDQ is special */
- if (state != ST_BW) { /* because it can still separate */
- char * s2 = s-1;
- while (s2 > p) { *s2 = *(s2-1); s2--; }
- p++;
- }
- cquote = 0;
- }
- if (cquote) { /* Other quoted character */
- if (state != ST_BW) { /* can't separate or group */
- char * s2 = s-1;
- while (s2 > p) { *s2 = *(s2-1); s2--; }
- p++;
- }
- class = CL_DAT; /* so treat it as data */
- cquote = 0;
- x = 1;
- } else { /* Character is not quoted */
- if (!all && c < SP) { /* Get its class */
- x = 0; /* x == 0 means "is separator" */
- } else if (*sep) { /* Break set given */
- ss = sep;
- while (*ss && *ss != c) ss++; /* (instead of ckstrchr()) */
- x = (*ss != c);
- } else { /* Default break set is */
- x = ((c >= 'a' && c <= 'z') || /* all but alphanumerics */
- (c >= '0' && c <= '9') ||
- (c >= 'A' && c <= 'Z') ||
- ((unsigned int)c >= hex80 && (unsigned int)c <= hexff)
- );
- }
- if (x == 0 && *notsep && c) { /* Include set if given */
- ss = notsep;
- while (*ss && *ss != c) ss++; /* (instead of ckstrchr()) */
- x = (*ss == c);
- }
- if (c == n3 && grouping && state == ST_BW) { /* Group quote? */
- class = CL_QUO;
- } else {
- class = x ? CL_DAT : CL_SEP; /* Class = data or separator */
- }
- if (grouping) { /* Grouping? */
- int j; /* Look for group start */
- for (k = 0; k < 6; k++) { /* Group-start char? */
- j = 1 << k; /* Get its mask bit value */
- if (grouping & j) {
- if (c == gr_opn[k]) { /* Selected group opener? */
- ko = k;
- class |= CL_OPN;
- if (c == '"' || c == '\'') { /* These can also */
- class |= CL_CLS; /* be closers */
- break;
- }
- } else if (c == gr_cls[k]) { /* Group closer? */
- class |= CL_CLS;
- break;
- }
- }
- }
- }
- }
- debug(F000,"cksplit char",s,c);
- debug(F101,"cksplit state","",state);
- debug(F101,"cksplit class","",class);
-
- switch (state) { /* State switcher... */
- case ST_BW: /* BETWEENWORDS */
- if (class & CL_OPN) { /* Group opener */
- if (gr_lvl == 0 && !gquote) { /* If not in group */
- p = s; /* point to beginning of word */
- }
- gr_lvl++; /* Push closer on nesting stack */
- if (gr_lvl >= NESTMAX)
- goto xxsplit;
- gr_stk[gr_lvl] = gr_cls[ko];
- prevstate = state;
- state = ST_IG; /* Switch to INGROUP state */
- } else if (class & CL_DAT) { /* Data character */
- gr_lvl = 0; /* Clear group nesting stack */
- gr_stk[gr_lvl] = 0;
- len = 0;
- p = s; /* Point to beginning of word */
- if (gquote) { /* Adjust for quote */
- len++;
- p--;
- gquote = 0;
- }
- prevstate = state;
- state = ST_IW; /* Switch to INWORD state */
- } else if (class & CL_QUO) { /* Group quote */
- gquote = gr_lvl+1; /* Remember quoted level */
- p = s - 1;
- len = 1;
- }
- if (collapse)
- break;
-
- case ST_IW: /* INWORD (but not in a group) */
- if (class & CL_SEP) { /* Ends on any kind of separator */
- *s = NUL; /* Terminate this word */
- if (csv) { /* If comma-separated list */
- char * s2 = s; /* discard surrounding spaces */
- while (s2 > splitbuf) { /* first backwards... */
- s2--;
- if (*s2 == SP || *s2 == HT)
- *s2 = NUL;
- else
- break;
- }
- s2 = s+1; /* Then forwards... */
- while (*s2 && (*s2 == SP || *s2 == HT))
- *s2++;
- s = s2-1;
- }
- if (!csv || prevstate != ST_IG) {
- wordnum++; /* Count it */
- if (splitting || n < 0) { /* Dispose of it appropriately */
- if (wordnum > max) { /* Add to array if splitting */
- ck_sval.a_size = -2;
- return(&ck_sval);
- }
- /* This inelegant bit corrects an edge condition */
- if (csv && !*p && (!c || !*(s+1))) {
- wordnum--;
- } else {
- setword(wordnum,p,len);
- }
- } else if (wordnum == n) { /* Searching for word n */
- setword(1,p,len);
- ck_sval.a_size = 1;
- return(&ck_sval);
- }
- }
- prevstate = state;
- state = ST_BW; /* Switch to BETWEENWORDS state */
- len = 0;
- }
- break;
-
- case ST_IG: /* INGROUP */
- if (class & CL_CLS) { /* Have group closer? */
- if (csv) {
- if (*(s+1) == c) {
- char *s2 = s;
- while ((*s2 = *(s2+1))) s2++;
- s++;
- c = *s;
- }
- }
- if (c == gr_stk[gr_lvl]) { /* Does it match current opener? */
- gr_lvl--; /* Yes, pop stack */
- if (gr_lvl < 0) /* Don't pop it too much */
- gr_lvl = 0;
- if (gr_lvl == 0) { /* If at top of stack */
- if (gquote)
- s++;
- c = *s;
- *s = NUL; /* we have word. */
- wordnum++; /* Count and dispose of it. */
- len--;
- if (splitting || n < 0) {
- if (wordnum > max) {
- ck_sval.a_size = -2;
- return(&ck_sval);
- }
- setword(wordnum,p+1,len);
- } else if (wordnum == n) {
- setword(1,p+1,len);
- ck_sval.a_size = 1;
- return(&ck_sval);
- }
- prevstate = state;
- state = ST_BW; /* Switch to BETWEENWORDS state */
- len = 0;
- }
- if (gr_lvl < gquote)
- gquote = 0;
- }
- } else if (class & CL_OPN) { /* Have group opener */
- gr_lvl++; /* Push on nesting stack */
- if (gr_lvl >= NESTMAX) goto xxsplit;
- gr_stk[gr_lvl] = gr_cls[ko];
- }
- } /* switch */
-
- nextc:
- s++; /* Next char */
- if (state)
- len++;
- } /* while (c) */
-
- if (gr_lvl > 0) { /* In case of an unclosed group */
- if (splitting || n < 0) { /* make it the last word. */
- if (++wordnum > max) {
- ck_sval.a_size = -2;
- return(&ck_sval);
- }
- setword(wordnum,p+1,len);
- } else if (wordnum == n) { /* Counting from left */
- setword(1,p+1,len);
- ck_sval.a_size = 1;
- return(&ck_sval);
- } else if (n < 0 && (wordnum + n > -1)) { /* Counting from right */
- char * s = wordarray[wordnum + n + 1];
- if (!s) s = "";
- setword(1,s,strlen(s));
- ck_sval.a_size = 1;
- return(&ck_sval);
- }
- }
- if (!splitting) { /* Fword... */
- if (n < 0 && (wordnum + n > -1)) { /* Counting from right */
- char * s = wordarray[wordnum + n + 1];
- if (!s) s = "";
- setword(1,s,strlen(s));
- ck_sval.a_size = 1;
- return(&ck_sval);
- }
- setword(1,NULL,0); /* From left... */
- ck_sval.a_size = 0; /* but there weren't n words */
- return(&ck_sval);
- } else { /* Succeed otherwise */
- ck_sval.a_size = wordnum;
-/*
- Always put a null element at the end of the array. It does no harm in
- the normal case, and it's required if we're making an argv[] array to
- pass to execvp(). This element is not included in the count.
-*/
- if (wordnum < MAXWORDS)
- setword(wordnum+1,NULL,0);
- }
-#ifdef DEBUG
- if (deblog) {
- for (i = 1; i <= wordnum; i++)
- debug(F111,"cksplit result",wordarray[i],i);
- }
-#endif /* DEBUG */
- return(&ck_sval);
-
- xxsplit: /* Error return */
- ck_sval.a_size = -2;
- return(&ck_sval);
-}
-
-/*
- ckhexbytetoint() expects a string of two hex characters,
- returns the int equivalent or -1 on error.
-*/
-int
-#ifdef CK_ANSIC
-ckhexbytetoint( char * s )
-#else
-ckhexbytetoint(s) char * s;
-#endif /* CK_ANSIC */
-{
- int i, c[2];
- if (!s) return(-1);
- if ((int)strlen(s) != 2) return(-1);
- for (i = 0; i < 2; i++) {
- c[i] = *s++;
- if (!c[i]) return(-1);
- if (islower(c[i])) c[i] = toupper(c[i]);
- if (c[i] >= '0' && c[i] <= '9') {
- c[i] -= 0x30;
- } else if (c[i] >= 'A' && c[i] <= 'F') {
- c[i] -= 0x37;
- } else {
- return(-1);
- }
- }
- return(c[0] * 16 + c[1]);
-}
-
-
-/* End of ckclib.c */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckclib.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckclib.h
deleted file mode 100644
index af09c0e..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckclib.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ckclib.h -- C-Kermit library routine prototypes */
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 2002, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#ifndef CKCLIB_H
-#define CKCLIB_H
-
-struct stringarray {
- char ** a_head;
- int a_size;
-};
-
-#ifdef CK_ANSIC
-_PROTOTYP( int ckstrncpy, (char *, const char *, int) );
-_PROTOTYP( int ckstrncat, (char *, const char *, int) );
-#else
-_PROTOTYP( int ckstrncpy, (char *, char *, int) );
-_PROTOTYP( int ckstrncat, (char *, char *, int) );
-#endif /* CK_ANSIC */
-
-_PROTOTYP( int ckmakmsg, (char *, int, char *, char *, char *, char *) );
-_PROTOTYP( int ckmakxmsg, (char *, int,
- char *, char *, char *, char *, char *, char *,
- char *, char *, char *, char *, char *, char *) );
-
-_PROTOTYP( char * ckstrpbrk, (char *, char *) );
-_PROTOTYP( char * ckstrstr, (char *, char *) );
-_PROTOTYP( char * chartostr, (int) );
-_PROTOTYP( int cklower, (char *) );
-_PROTOTYP( int ckupper, (char *) );
-_PROTOTYP( int ckindex, (char *, char *, int, int, int) );
-_PROTOTYP( char * ckctoa, (char) );
-_PROTOTYP( char * ckctox, (CHAR, int) );
-_PROTOTYP( char * ckitoa, (int) );
-_PROTOTYP( char * ckuitoa, (unsigned int) );
-_PROTOTYP( char * ckltoa, (long) );
-_PROTOTYP( char * ckultoa, (unsigned long) );
-_PROTOTYP( char * ckfstoa, (CK_OFF_T) );
-_PROTOTYP( CK_OFF_T ckatofs, (char *) );
-_PROTOTYP( char * ckitox, (int) );
-_PROTOTYP( char * ckltox, (long) );
-_PROTOTYP( int ispattern, (char *) );
-_PROTOTYP( int ckmatch, (char *, char *, int, int ) );
-_PROTOTYP( VOID ckmemcpy, (char *, char *, int) );
-_PROTOTYP( char * ckstrchr, (char *, char) );
-_PROTOTYP( char * ckstrrchr, (char *, char) );
-_PROTOTYP( int ckrchar, (char *) );
-_PROTOTYP( int ckstrcmp, (char *, char *, int, int) );
-#define xxstrcmp(a,b,c) ckstrcmp(a,b,c,0)
-_PROTOTYP( int ckstrpre, (char *, char *) );
-_PROTOTYP( VOID sh_sort, (char **, char **, int, int, int, int) );
-_PROTOTYP( char * brstrip, (char *) );
-_PROTOTYP( char * fnstrip, (char *) );
-#ifdef COMMENT
-_PROTOTYP( char * brace, (char *) );
-#endif /* COMMENT */
-_PROTOTYP( int dquote, (char *, int, int) );
-_PROTOTYP( int untabify, (char *, char *, int) );
-_PROTOTYP( VOID makelist, (char *, char *[], int) );
-#ifndef CK_ANSIC
-_PROTOTYP( VOID makestr, (char **, char *) );
-_PROTOTYP( VOID xmakestr, (char **, char *) );
-#else /* CK_ANSIC */
-_PROTOTYP( VOID makestr, (char **, const char *) );
-_PROTOTYP( VOID xmakestr, (char **, const char *) );
-#endif /* CK_ANSIC */
-_PROTOTYP( int chknum, (char *) );
-_PROTOTYP( int rdigits, (char *) );
-_PROTOTYP( char * ckradix, (char *,int,int) );
-
-/* Base-64 conversion needed for script programming and HTTP */
-
-#ifndef NOB64
-_PROTOTYP( int b8tob64, (char *,int,char *,int));
-_PROTOTYP( int b64tob8, (char *,int,char *,int));
-#endif /* NOB64 */
-
-#ifdef CKFLOAT
-_PROTOTYP( int isfloat, (char *,int) );
-#ifndef CKCLIB_C
-#ifndef CKWART_C
-extern CKFLOAT floatval;
-#endif /* CKWART_C */
-#endif /* CKCLIB_C */
-#endif /* CKFLOAT */
-
-_PROTOTYP( char * parnam, (char) );
-_PROTOTYP( char *hhmmss, (long) );
-
-_PROTOTYP( VOID lset, (char *, char *, int, int) );
-_PROTOTYP( VOID rset, (char *, char *, int, int) );
-_PROTOTYP( char * ulongtohex, (unsigned long, int) );
-_PROTOTYP( long hextoulong, (char *, int) );
-_PROTOTYP( struct stringarray * cksplit, (int,int,
- char *,char *,char *,int,int,int) );
-
-_PROTOTYP( int ckhexbytetoint, (char *) );
-#endif /* CKCLIB_H */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcmai.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckcmai.c
deleted file mode 100644
index f65d0a0..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcmai.c
+++ /dev/null
@@ -1,3580 +0,0 @@
-#define EDITDATE "20 Aug 2011" /* Last edit date dd mmm yyyy */
-#define EDITNDATE "20110820" /* Keep them in sync */
-/* Sat Aug 20 17:20:17 2011 */
-
-/* ckcmai.c - Main program for C-Kermit plus some miscellaneous functions */
-
-/*
- ckcsym.h is used for for defining symbols that normally would be defined
- using -D or -d on the cc command line, for use with compilers that don't
- support this feature. Must come before any tests for preprocessor symbols.
-*/
-#include "ckcsym.h"
-/*
- Consolidated program C-Kermit version information for all platforms
- (but for UNIX also see ckuver.h). See makever() below for how they are used.
-*/
-#ifdef COMMENT /* Uncomment this for real K95 version */
-#ifndef OS2 /* OS2 actually means Kermit 95. */
-#ifndef BETATEST /* It's because Kermit 95 started */
-#define BETATEST /* out as C-Kermit for OS/2. */
-#endif /* BETATEST */
-#endif /* OS2 */
-#endif /* COMMENT */
-
-#ifdef BETATEST
-#ifdef OS2
-#ifdef __DATE__
-#define BETADATE
-#endif /* __DATE__ */
-#endif /* OS2 */
-#endif /* BETATEST */
-
-char * ck_cryear = "2011"; /* C-Kermit copyright year */
-
-#ifndef MAC /* MAC = Kermit for MAC OS 6, 7, ... */
-/*
- Note: initialize ck_s_test to "" if this is not a test version.
- Use (*ck_s_test != '\0') to decide whether to print test-related messages.
-*/
-
-#ifndef BETATEST
-#ifndef OS2 /* UNIX, VMS, etc... (i.e. C-Kermit) */
-char *ck_s_test = ""; /* "Dev","Alpha","Beta","RC", or "" */
-char *ck_s_tver = ""; /* Test version number or "" */
-#else /* OS2 */
-char *ck_s_test = ""; /* (i.e. K95) */
-char *ck_s_tver = "";
-#endif /* OS2 */
-#else
-char *ck_s_test = ""; /* Development */
-char *ck_s_tver = "";
-#endif /* BETATEST */
-#else /* MAC */
-char *ck_s_test = "Pre-Alpha"; /* Mac Kermit is always a test... */
-char *ck_s_tver = ""; /* (pre Mac OS X 10, that is!) */
-#endif /* MAC */
-
-#ifdef BETADATE /* Date of this version or edit */
-char *ck_s_date = __DATE__; /* Compilation date */
-#else
-char *ck_s_date = EDITDATE; /* See top */
-
-#endif /* BETADATE */
-char *buildid = EDITNDATE; /* See top */
-
-#ifdef UNIX
-static char sccsid[] = "@(#)C-Kermit 9.0.302";
-#endif /* UNIX */
-
-/*
- The C-Kermit Version number is major.minor.edit (integers).
- Major version always goes up.
- Minor version is historical, hasn't been used since C-Kermit 7.1.
- Edit is sequential, always goes up, but there can be gaps.
- For example there might be many edits between releases.
- If the major goes to 10, some version-number-based feature tests
- could fail. It might be better to use the minor version field
- for future releases.
-*/
-
-char *ck_s_ver = "9.0.302"; /* C-Kermit version string */
-long ck_l_ver = 900302L; /* C-Kermit version number */
-
-#ifdef OS2
-char *ck_s_xver = "3.0.0"; /* Product-specific version string */
-long ck_l_xver = 3000L; /* Product-specific version number */
-#else
-#ifdef MAC
-char *ck_s_xver = "0.995"; /* Product-specific version string */
-long ck_l_xver = 995L; /* Product-specific version number */
-#else
-char *ck_s_xver = ""; /* Don't touch these... */
-long ck_l_xver = 0L; /* they are computed at runtime */
-#endif /* MAC */
-#endif /* OS2 */
-
-#ifdef OS2
-#ifdef IKSDONLY
-#ifdef NT
-char *ck_s_name = "IKS-NT";
-#else /* NT */
-char *ck_s_name = "IKS-OS/2";
-#endif /* NT */
-#else /* IKSDONLY */
-char *ck_s_name = "Kermit 95"; /* Program name */
-#endif /* IKSDONLY */
-#else
-#ifdef MAC
-char *ck_s_name = "Mac Kermit";
-#else
-char *ck_s_name = "C-Kermit";
-#endif /* MAC */
-#endif /* OS2 */
-
-char *ck_s_who = ""; /* Where customized, "" = not. */
-char *ck_patch = ""; /* Patch info, if any. */
-
-#define CKVERLEN 128
-char versiox[CKVERLEN]; /* Version string buffer */
-char *versio = versiox; /* These are filled in at */
-long vernum, xvernum; /* runtime from above. */
-
-#define CKCMAI
-
-#include "ckcasc.h" /* ASCII character symbols */
-#include "ckcdeb.h" /* Debug & other symbols */
-
-char * myname = NULL; /* The name I am called by */
-#ifndef OS2
-char * exedir = NULL; /* Directory I was executed from */
-#endif /* OS2 */
-char * myhome = NULL; /* Home directory override */
-
-/* C K C M A I -- C-Kermit Main program */
-
-/*
- Author: Frank da Cruz (fdc@columbia.edu),
- Columbia University in the city of New York,
- Computer Center / Center for Computing Activities / Information Technology.
- I am no longer at Columbia U as of 1 July 2011, but the email address
- should still work. The Kermit website http://kermit.columbia.edu should
- still be available and under my control, as well as the Kermit FTP site,
- ftp://kermit.columbia.edu/kermit/.
-
-COPYRIGHT NOTICE:
-*/
-
-char *copyright[] = {
-
-#ifdef pdp11
-"Copyright (C) 1985, %s, Trustees of Columbia University, NYC.",
-"All rights reserved.",
-" ",
-#else
-"Copyright (C) 1985, %s,",
-" The Trustees of Columbia University in the City of New York.",
-" All rights reserved.",
-" ",
-"Redistribution and use in source and binary forms, with or without",
-"modification, are permitted provided that the following conditions",
-"are met:",
-" ",
-" + Redistributions of source code must retain the above copyright",
-" notice, this list of conditions and the following disclaimer.",
-" ",
-" + Redistributions in binary form must reproduce the above copyright",
-" notice, this list of conditions and the following disclaimer in",
-" the documentation and/or other materials provided with the",
-" distribution.",
-" ",
-" + Neither the name of Columbia University nor the names of its",
-" contributors may be used to endorse or promote products derived",
-" from this software without specific prior written permission.",
-" ",
-"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS",
-"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT",
-"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR",
-"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT",
-"HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,",
-"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT",
-"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,",
-"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY",
-"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT",
-"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE",
-"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
-#endif /* pdp11 */
-
-#ifdef OS2
-"Portions Copyright (C) 2002-2005, Secure Endpoints Inc, New York NY USA.",
-"Portions Copyright (C) 1995, Oy Online Solutions Ltd., Jyvaskyla, Finland.",
-#endif /* OS2 */
-
-#ifdef CK_AUTHENTICATION
-"Portions Copyright (C) 1990, Massachusetts Institute of Technology.",
-#ifdef CK_ENCRYPTION
-"Portions Copyright (C) 1991, 1993 Regents of the University of California.",
-"Portions Copyright (C) 1991, 1992, 1993, 1994, 1995 by AT&T.",
-"Portions Copyright (C) 1995, 1997, Eric Young <eay@cryptosoft.com>.",
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SRP
-"Portions Copyright (C) 1997, Stanford University.",
-#endif /* CK_SRP */
-#endif /* CK_AUTHENTICATION */
-
-#ifndef pdp11
-" ",
-"For further information, visit the Kermit Project website:",
-"http://www.columbia.edu/kermit/ .",
-#endif /* pdp11 */
-""};
-
-/* Windows IKSD copyright used to be separate */
-char *wiksdcpr = (char *) copyright;
-
-
-/*
-DOCUMENTATION:
-
- "Using C-Kermit" by Frank da Cruz and Christine M. Gianone,
- Digital Press / Butterworth-Heinemann, Woburn MA, USA.
- Second edition (1997), ISBN 1-55558-164-1.
- Order from Digital Press: +1 (800) 366-2665
- Or from Columbia University: +1 (212) 854-3703
-
-For Kermit 95, also:
-
- "Kermit 95" by Christine M. Gianone and Frank da Cruz,
- Manning Publications, Greenwich CT, USA (1998) - Online.
-
-ACKNOWLEDGMENTS:
-
- The Kermit file transfer protocol was developed at the Columbia University
- Center for Computing Activities (CUCCA), which was since renamed to Columbia
- University Academic Information Systems (AcIS) and after that Columbia
- University Information Technology (CUIT). Kermit is named after Kermit the
- Frog, star of the television series THE MUPPET SHOW; the name is used by
- permission of Henson Associates, Inc.
-
- Thanks to at least the following people for their contributions to this
- program over the years, and apologies to anyone who was inadvertantly
- omitted:
-
- Chris Adie, Edinburgh U, Scotland (OS/2)
- Robert Adsett, University of Waterloo, Canada
- Larry Afrin, Clemson U
- Russ Allbery, Stanford U
- Jeffrey Altman, Columbia University
- Greg Andrews, Telebit Corp
- Barry Archer, U of Missouri
- Robert Andersson, International Systems A/S, Oslo, Norway
- Chris Armstrong, Brookhaven National Lab (OS/2)
- William Bader, Software Consulting Services, Nazareth, PA
- Fuat Baran, Columbia U
- Stan Barber, Rice U
- Jim Barbour, U of Colorado
- Donn Baumgartner, Dell
- Ian Beckwith, Debian Project
- Nelson Beebe, U of Utah
- Gerry Belanger, Cognitronics
- Karl Berry, UMB
- Mark Berryman, SAIC
- Dean W Bettinger, SUNY
- Gary Bilkus
- Peter Binderup, Denmark
- David Bolen, Advanced Networks and Services, Inc.
- Joop Bonen
- Marc Boucher, U of Montreal
- Charles Brooks, EDN
- Bob Brown
- Mike Brown, Purdue U
- Rob Brown
- Jack Bryans, California State U at Long Beach
- Mark Buda, DEC (VMS)
- Fernando Cabral, Padrao iX, Brasilia
- Bjorn Carlsson, Stockholm University Computer Centre QZ, Sweden
- Bill Catchings, (formerly of) Columbia U
- Bob Cattani, Columbia U CS Dept
- Davide Cervone, Rochester U
- Seth Chaiklin, Denmark
- John Chandler, Harvard U / Smithsonian Astronomical Observatory
- Bernard Chen, UCLA
- Andrew A Chernov, RELCOM Team, Moscow
- John L Chmielewski, AT&T, Lisle, IL
- Howard Chu, U of Michigan
- Bill Coalson, McDonnell Douglas
- Bertie Coopersmith, London
- Christian Corti
- Chet Creider, U of Western Ontario
- Alan Crosswell, Columbia U
- Jeff Damens, (formerly of) Columbia U
- Mark Davies, Bath U, UK
- Sin-itirou Dezawa, Fujifilm, Japan
- Joe R. Doupnik, Utah State U
- Frank Dreano, Honeywell
- John Dunlap, U of Washington
- Alex Dupuy, SMART.COM
- David Dyck, John Fluke Mfg Co.
- Stefaan A. Eeckels, Eurokom, Luxembourg
- Nick Efthymiou
- Paul Eggert, Twin Sun, Inc., El Segundo, CA
- Bernie Eiben, DEC
- Peter Eichhorn, Assyst International
- Kristoffer Eriksson, Peridot Konsult AB, Oerebro, Sweden
- John R. Evans, IRS, Kansas City
- Glenn Everhart, RCA Labs
- Charlie Finan, Cray Research
- Herm Fischer, Encino, CA (extensive contributions to version 4.0)
- Carl Fongheiser, CWRU
- Mike Freeman, Bonneville Power Authority
- Carl Friedberg
- Marcello Frutig, Catholic University, Sao Paulo, Brazil (X.25 support)
- Hirofumi Fujii, Japan Nat'l Lab for High Energy Physics, Tokyo (Kanji)
- Chuck Fuller, Westinghouse Corporate Computer Services
- Andy Fyfe, Caltech
- Christine M. Gianone, Columbia U
- John Gilmore, UC Berkeley
- Madhusudan Giyyarpuram, HP
- Rainer Glaschick, Siemens AG, Paderborn
- William H. Glass
- German Goldszmidt, IBM
- Chuck Goodhart, NASA
- Alistair Gorman, New Zealand
- Richard Gration, ADFA, Australia
- Chris Green, Essex U, UK
- Alan Grieg, Dundee Tech, Scotland
- Yekta Gursel, MIT
- Jim Guyton, Rand Corp
- Michael Haertel
- Bruno Haible
- Bob Hain, UMN
- Marion Hakanson, ORST
- Richard Hamilton
- John Hamilston, Iowa State U
- Simon Hania, Netherlands
- Stan Hanks, Rice U.
- Ken Harrenstein, SRI
- Eugenia Harris, Data General (AOS/VS)
- David Harrison, Kingston Warren Corp
- Lucas Hart, Oregon State University
- James Harvey, Indiana/Purdue U (VMS)
- Rob Healey
- Chuck Hedrick, Rutgers U
- Ron Heiby, Technical Systems Division, Motorola Computer Group
- Steve Hemminger, Tektronix
- Christian Hemsing, RWTH Aachen, Germany (OS-9)
- Randolph Herber, US DOE,
- Andrew Herbert, Monash Univ, Australia
- Marcus Herbert, Germany
- Mike Hickey, ITI
- Dan Hildebrand, QNX Software Systems Inc, Kanata, ON (QNX)
- R E Hill
- Stephan Hoffman-Emden
- Sven Holmstrom, ABB Utilities AB, Sweden
- Bill Homer, Cray Research
- Ray Hunter, The Wollongong Group
- Randy Huntziger, National Library of Medicine
- Larry Jacobs, Transarc
- Steve Jenkins, Lancaster University, UK
- Dave Johnson, Gradient Technologies
- Mark B Johnson, Apple Computer
- Jyke Jokinen, Tampere University of Technology, Finland (QNX)
- Eric F Jones, AT&T
- Luke Jones, AT&T
- Peter Jones, U of Quebec Montreal
- Phil Julian, SAS Institute
- Peter Kabal, U of Quebec
- Mic Kaczmarczik, U of Texas at Austin
- Sergey Kartashoff, Inst. of Precise Mechanics & Computer Equipment, Moscow
- Howie Kaye, Columbia U
- Rob Kedoin, Linotype Co, Hauppauge, NY (OS/2)
- Phil Keegstra
- Mark Kennedy, IBM
- Terry Kennedy, St Peter's College, Jersey City, NJ (VMS and more)
- "Carlo Kid", Technical University of Delft, Netherlands
- Tim Kientzle
- Paul Kimoto, Cornell U
- Douglas Kingston, morgan.com
- Lawrence Kirby, Wiltshire, UK
- Tom Kloos, Sequent Computer Systems
- Guenter Knauf
- Jim Knutson, U of Texas at Austin
- John T. Kohl (BSDI)
- Scott Kramer, SRI International, Menlo Park, CA
- John Kraynack, US Postal Service
- David Kricker, Encore Computer
- Thomas Krueger, UWM
- Bo Kullmar, ABC Klubben, Stockholm, and Central Bank of Sweden, Kista
- R. Brad Kummer, AT&T Bell Labs, Atlanta, GA
- John Kunze, UC Berkeley
- David Lane, BSSI / BellSouth (Stratus VOS, X.25)
- Bob Larson, USC (OS-9)
- Bert Laverman, Groningen U, Netherlands
- Steve Layton
- David Lawyer, UC Irvine
- Jason Lehr
- David LeVine, National Semiconductor Corporation
- Daniel S. Lewart, UIUC
- S.O. Lidie, Lehigh U
- Tor Lillqvist, Helsinki U, Finland
- David-Michael Lincke, U of St Gallen, Switzerland
- Robert Lipe (for SCO makefile entries & advice)
- Dean Long
- Mike Long, Analog Devices, Norwood MA
- Kevin Lowey, U of Saskatchewan (OS/2)
- Andy Lowry, Columbia U
- James Lummel, Caprica Telecomputing Resources (QNX)
- Lewis McCarthy
- David MacKenzie, Environmental Defense Fund, U of Maryland
- John Mackin, University of Sidney, Australia
- Martin Maclaren, Bath U, UK
- Chris Maio, Columbia U CS Dept
- Montserrat Mane, HP, Grenoble, France
- Fulvio Marino, Olivetti, Ivrea, Italy
- Arthur Marsh, dircsa.org.au
- Peter Mauzey, Lucent Technologies
- Tye McQueen, Utah State U
- Ted Medin
- Hellmuth Michaelis, Hanseatischer Computerservice GmbH, Hamburg, Germany
- Leslie Mikesell, American Farm Bureau
- Todd Miller, Courtesan Consulting
- Gary Mills
- Martin Minow, DEC (VMS)
- Pawan Misra, Bellcore
- Ken Mizialko, IBM, Manassas, VA
- Wolfgang Moeller, DECUS Germany
- Ray Moody, Purdue U
- Bruce J Moore, Allen-Bradley Co, Highland Heights, OH (Atari ST)
- Steve Morley, Convex
- Peter Mossel, Columbia U
- Tony Movshon, NYU
- Lou Muccioli, Swanson Analysis Systems
- Dan Murphy
- Neal P. Murphy, Harsof Systems, Wonder Lake IL
- Gary Mussar
- John Nall, FSU
- Jack Nelson, U of Pittsburgh
- Jim Noble, Planning Research Corporation (Macintosh)
- Ian O'Brien, Bath U, UK
- Melissa O'Neill, SFU
- John Owens
- Thomas Pinkl, Health Business Systems Inc.
- Michael Pins, Iowa Computer Aided Engineering Network
- Andre' Pirard, University of Liege, Belgium
- Paul Placeway, Ohio State U
- Piet W. Plomp, ICCE, Groningen University, Netherlands
- Ken Poulton, HP Labs
- Manfred Prange, Oakland U
- Christopher Pratt, APV Baker, UK
- Frank Prindle, NADC
- Tony Querubin, U of Hawaii
- Jean-Pierre Radley
- Anton Rang
- Mike Rechtman
- Scott Ribe
- Alan Robiette, Oxford University, UK
- Michel Robitaille, U of Montreal (Mac)
- Huw Rogers, Schweizerische Kreditanstalt, Zuerich
- Nigel Roles, Cambridge, England
- Kai Uwe Rommel, Technische Universitaet Muenchen (OS/2)
- Larry Rosenman (Amiga)
- Jay Rouman, U of Michigan
- Jack Rouse, SAS Institute (Data General and/or Apollo)
- Stew Rubenstein, Harvard U (VMS)
- Gerhard Rueckle, FH Darmstadt, Fb. E/Automatisierungstechnik
- John Santos, EG&H
- Bill Schilit, Columbia U
- Ulli Schlueter, RWTH Aachen, Germany (OS-9, etc)
- Michael Schmidt, U of Paderborn, Germany
- Eric Schnoebelen, Convex
- Benn Schreiber, DEC
- Dan Schullman, DEC (modems, DIAL command, etc)
- John Schultz, 3M
- Steven Schultz, Contel (PDP-11)
- Steven Schweda
- APPP Scorer, Leeds Polytechnic, UK
- Gordon Scott, Micro Focus, Newbury UK
- Gisbert W. Selke, WIdO, Bonn, Germany
- Kijal Shah
- David Singer, IBM Almaden Research Labs
- David Sizeland, U of London Medical School
- Fridrik Skulason, Iceland
- Rick Sladkey (Linux)
- Dave Slate
- Bradley Smith, UCLA
- Fred Smith, Merk / Computrition
- Richard S Smith, Cal State
- Ryan Stanisfer, UNT
- Bertil Stenstroem, Stockholm University Computer Centre (QZ), Sweden
- James Sturdevant, CAP GEMENI AMERICA, Minneapolis
- Peter Svanberg, Royal Techn. HS, Sweden
- James R. Swenson, Accu-Weather, Inc.
- Ted T'so, MIT (Linux)
- Andy Tanenbaum, Vrije U, Amsterdam, Netherlands
- Seth Theriault, Columbia U
- Glen Thobe
- Markku Toijala, Helsinki U of Technology
- Teemu Torma, Helsinki U of Technology
- Linus Torvalds, Helsinki
- Rick Troxel, NIH
- Warren Tucker, Tridom Corp, Mountain Park, GA
- Dave Tweten, AMES-NAS
- G Uddeborg, Sweden
- Walter Underwood, Ford Aerospace
- Pieter Van Der Linden, Centre Mondial, Paris
- Ge van Geldorp, Netherlands
- Fred van Kempen, MINIX User Group, Voorhout, Netherlands
- Wayne Van Pelt, GE/CRD
- Mark Vasoll, Oklahoma State U (V7 UNIX)
- Konstantin Vinogradov, ICSTI, Moscow
- Paul Vixie, DEC
- Bernie Volz, Process Software
- Eduard Vopicka, Prague University of Economics, Czech Republic
- Martin Vorlaender
- Dimitri Vulis, CUNY
- Roger Wallace, Raytheon
- Stephen Walton, Calif State U, Northridge (Amiga)
- Jamie Watson, Adasoft, Switzerland (AIX)
- Rick Watson, U of Texas (Macintosh)
- Eric Weaver, Columbia U
- Scott Weikart (Association for Progressive Communications)
- Robert Weiner, Programming Plus, New York City
- Lauren Weinstein, Vortex Technlogy
- David Wexelblat, AT&T
- Clark Wierda, Illuminati Online
- Joachim Wiesel, U of Karlsruhe
- Lon Willett, U of Utah
- Michael Williams, UCLA
- Nate Williams, U of Montana
- David Wilson
- Joellen Windsor, U of Arizona
- Patrick Wolfe, Kuck & Associates, Inc.
- Gregg Wonderly, Oklahoma State U (V7 UNIX)
- Farrell Woods, Concurrent (formerly Masscomp)
- Dave Woolley, CAP Communication Systems, London
- Jack Woolley, SCT Corp
- Frank Wortner
- Ken Yap, formerly of U of Rochester
- John Zeeff, Ann Arbor, MI
-*/
-
-#include "ckcker.h" /* Kermit symbols */
-#include "ckcnet.h" /* Network symbols */
-
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-
-#ifndef NOSPL
-#include "ckuusr.h"
-#endif /* NOSPL */
-
-#ifdef OS2ONLY
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#endif /* OS2ONLY */
-
-#ifdef NT
-#include <windows.h>
-#include <tapi.h>
-#include "ckntap.h"
-#endif /* NT */
-
-#ifndef NOSERVER
-/* Text message definitions.. each should be 256 chars long, or less. */
-#ifdef MINIX
-char *srvtxt = "\r\n\
-Entering server mode.\r\n\0";
-#else
-#ifdef OLDMSG
-/*
- It seems there was a large installation that was using C-Kermit 5A(165)
- or thereabouts, which had deployed thousands of MS-DOS Kermit scripts in
- scattered locations that looked for strings in the old server message,
- which changed in 5A(183), August 1992.
-*/
-char *srvtxt = "\r\n\
-C-Kermit server starting. Return to your local machine by typing\r\n\
-its escape sequence for closing the connection, and issue further\r\n\
-commands from there. To shut down the C-Kermit server, issue the\r\n\
-FINISH or BYE command and then reconnect.\n\
-\r\n\0";
-#else
-#ifdef OSK
-char *srvtxt = "\r\012\
-Entering server mode. If your local Kermit software is menu driven, use\r\012\
-the menus to send commands to the server. Otherwise, enter the escape\r\012\
-sequence to return to your local Kermit prompt and issue commands from\r\012\
-there. Use SEND and GET for file transfer. Use REMOTE HELP for a list of\r\012\
-other available services. Use BYE or FINISH to end server mode.\r\012\0";
-#else /* UNIX, VMS, AOS/VS, and all others */
-char *srvtxt = "\r\n\
-Entering server mode. If your local Kermit software is menu driven, use\r\n\
-the menus to send commands to the server. Otherwise, enter the escape\r\n\
-sequence to return to your local Kermit prompt and issue commands from\r\n\
-there. Use SEND and GET for file transfer. Use REMOTE HELP for a list of\r\n\
-other available services. Use BYE or FINISH to end server mode.\r\n\0";
-#endif /* OSK */
-#endif /* OLDMSG */
-#endif /* MINIX */
-#else /* server mode disabled */
-char *srvtxt = "";
-#endif /* NOSERVER */
-
-int initflg = 0; /* sysinit() has executed... */
-int howcalled = I_AM_KERMIT; /* How I was called */
-int hmtopline = 0;
-int quitting = 0; /* I'm in the act of quitting */
-
-#ifdef IKSDCONF
-char * iksdconf = IKSDCONF; /* IKSD configuration file */
-int iksdcf = 0; /* Has IKSD c.f. been processed? */
-#endif /* IKSDCONF */
-
-int srvcdmsg = 0; /* [Server] CD message */
-char * cdmsgfile[8] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
-char * cdmsgstr = NULL;
-char * ckcdpath = NULL;
-
-#ifdef NLCHAR /* Text-file line terminator */
-CHAR feol = NLCHAR;
-#else
-CHAR feol = 0;
-#endif /* NLCHAR */
-
-int fblksiz = DBLKSIZ; /* File blocksize */
-int frecl = DLRECL; /* File record length */
-int frecfm = XYFF_S; /* File record format (default = stream) */
-int forg = XYFO_S; /* File organization (sequential) */
-int fcctrl = XYFP_N; /* File carriage control (ctrl chars) */
-int filecase = FILECASE; /* Case matters in filenames */
-int stathack = 1; /* Fast directory lookups by default */
-
-char uidbuf[UIDBUFLEN] = { NUL, NUL }; /* User ID buffer */
-int cfilef = 0; /* Application ("kerbang") file flag */
-char cmdfil[CKMAXPATH + 1] = { NUL, NUL }; /* Application file name */
-int haveurl = 0; /* URL given on command line */
-
-#ifndef NOXFER
-/* Multi-protocol support */
-
-struct ck_p ptab[NPROTOS] = { /* Initialize the Kermit part ... */
- { "Kermit",
- DRPSIZ, /* Receive packet size */
- DSPSIZ, /* Send packet size */
- 0, /* Send-packet-size-set flag */
- DFWSIZ, /* Window size */
-
-#ifdef NEWDEFAULTS
- PX_CAU, /* Control char unprefixing... */
-#else
- PX_ALL,
-#endif /* NEWDEFAULTS */
-
-#ifdef VMS /* Default filename collision action */
- XYFX_X, /* REPLACE for VAX/VMS */
-#else
- XYFX_B, /* BACKUP for everybody else */
-#endif /* VMS */
-
-#ifdef OS2 /* Flag for file name conversion */
- XYFN_L, /* Literal for OS2 */
-#else
- XYFN_C, /* Converted for others */
-#endif /* OS2 */
-
- PATH_OFF, /* Send pathnames OFF */
- PATH_AUTO, /* Receive pathnames AUTO */
- NULL, /* Host receive initiation string (binary) */
- NULL, /* Host receive initiation string (text) */
- NULL, /* Host server string */
- NULL, /* External protocol send command (binary) */
- NULL, /* External protocol send command (text) */
- NULL, /* External protocol receive command (bin) */
- NULL } /* External protocol receive command (txt) */
-#ifdef CK_XYZ
-,
-{"XMODEM", 128,128,-1,-1, 1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
-{"XMODEM-CRC",128,128,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
-{"YMODEM", -1, -1,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
-{"YMODEM-g", -1, -1,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
-{"ZMODEM", -1, -1,-1,-1,PX_WIL,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
-{"Other", -1, -1,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
-#endif /* CK_XYZ */
-};
-
-/* Declarations for Send-Init Parameters */
-
-int spsiz = DSPSIZ, /* Current packet size to send */
- spmax = DSPSIZ, /* Biggest packet size we can send */
- lastspmax = DSPSIZ, /* Send-packet size last used */
- spsizr = DSPSIZ, /* Send-packet size requested */
- spsizf = 0, /* Flag to override size negotiation */
- rpsiz = DRPSIZ, /* Biggest we want to receive */
- urpsiz = DRPSIZ, /* User-requested receive pkt size */
- maxrps = MAXRP, /* Maximum incoming long packet size */
- maxsps = MAXSP, /* Maximum outbound l.p. size */
- maxtry = MAXTRY, /* Maximum retries per packet */
- wslots = 1, /* Window size currently in use */
- wslotr = DFWSIZ, /* Window size from SET WINDOW */
- wslotn = 1, /* Window size negotiated in S-pkt */
- timeouts = 0, /* For statistics reporting */
- spackets = 0, /* ... */
- rpackets = 0, /* ... */
- retrans = 0, /* ... */
- crunched = 0, /* ... */
- wmax = 0, /* ... */
- wcur = 0, /* ... */
- srvidl = 0, /* Server idle timeout */
- srvdis = 1, /* Server file xfer display */
- srvtim = DSRVTIM, /* Server command wait timeout */
- srvping = 1, /* Server keepalive */
-/*
- timint is the timeout interval I use when waiting for a packet.
- pkttim is the SET RECEIVE TIMEOUT value, sent to the other Kermit.
- rtimo is the SET SEND TIMEOUT value. rtimo is the initial value of
- timint. timint is changed by the value in the incoming negotiation
- packet unless a SET SEND TIMEOUT command was given.
-*/
- timint = DMYTIM, /* Timeout interval I use */
- pkttim = URTIME, /* Timeout I want you to use */
- rtimo = DMYTIM, /* Normal packet wait timeout */
- timef = 0, /* Flag to override what you ask */
-#ifdef CK_TIMERS
- rttflg = 1, /* Use dynamic round-trip timers */
-#else
- rttflg = 0, /* Use fixed timer */
-#endif /* CK_TIMERS */
- mintime = 1, /* Minimum timeout */
- maxtime = 0, /* Maximum timeout */
-
- npad = MYPADN, /* How much padding to send */
- mypadn = MYPADN, /* How much padding to ask for */
- bctr = DFBCT, /* Block check type requested */
- bctu = 1, /* Block check type used */
- bctl = 1, /* Block check length */
- bctf = 0, /* Block check type 3 forced on all */
- c_save = -1, /* Block check saving and restoring */
- ss_save = -1, /* Slow-start saving and restoring */
- ebq = MYEBQ, /* 8th bit prefix */
- ebqflg = 0, /* 8th-bit quoting flag */
- rqf = -1, /* Flag used in 8bq negotiation */
- rq = 0, /* Received 8bq bid */
- sq = 'Y', /* Sent 8bq bid */
- rpt = 0, /* Repeat count */
- rptq = MYRPTQ, /* Repeat prefix */
- rptflg = 0, /* Repeat processing flag */
- rptena = 1, /* Repeat processing enabled */
- xfrcan = 1, /* Transfer cancellation enabled */
- xfrint = 1, /* Transfer interruption enabled */
- xfrchr = 3, /* Transfer cancel char = Ctrl-C */
- xfrnum = 3, /* Need three of them by default */
- g_xfrxla = -1;
- char * xfrmsg = NULL; /* Message for f.t. display screen */
-#endif /* NOXFER */
-
-#ifdef NOCSETS
-int xfrxla = 0; /* Character-set translation */
-#else
-int xfrxla = 1; /* enabled or disabled */
-#endif /* NOCSETS */
-
-int havelfs = 0; /* Large file support available */
-
-#ifndef NOXFER
-int epktflg = 0; /* E-PACKET command active */
-
-int capas = 9, /* Position of Capabilities */
- lpcapb = 2, /* Long Packet capability */
- lpcapr = 1, /* requested */
- lpcapu = 0, /* used */
- swcapb = 4, /* Sliding Window capability */
- swcapr = 1, /* requested (allowed) */
- swcapu = 0, /* used */
- atcapb = 8, /* Attribute capability */
- atcapr = 1, /* requested */
- atcapu = 0, /* used */
- rscapb = 16, /* RESEND capability */
- rscapr = 1, /* requested by default */
- rscapu = 0, /* used */
- lscapb = 32, /* Locking Shift capability */
- lscapr = 1, /* requested by default */
- lscapu = 0; /* used */
-
-/* Flags for whether to use particular attributes */
-
-int atenci = 1, /* Encoding in */
- atenco = 1, /* Encoding out */
- atdati = 1, /* Date in */
- atdato = 1, /* Date out */
- atdisi = 1, /* Disposition in/out */
- atdiso = 1,
- atleni = 1, /* Length in/out (both kinds) */
- atleno = 1,
- atblki = 1, /* Blocksize in/out */
- atblko = 1,
- attypi = 1, /* File type in/out */
- attypo = 1,
- atsidi = 1, /* System ID in/out */
- atsido = 1,
- atsysi = 1, /* System-dependent parameters in/out */
- atsyso = 1;
-
-int dispos = 0; /* Disposition */
-
-#ifdef CK_PERMS
-int atlpri = 1,
- atlpro = 1,
- atgpri = 1,
- atgpro = 1;
-#endif /* CK_PERMS */
-
-int atfrmi = 1, /* Record Format in/out */
- atfrmo = 1;
-
-#ifdef STRATUS
-int atcrei = 1, /* Creator ID in/out */
- atcreo = 1,
- atacti = 1, /* Account in/out */
- atacto = 1;
-#endif /* STRATUS */
-
-int sprmlen = -1; /* Send/Receive protocol parameter */
-int rprmlen = -1; /* string length limits */
-int sendipkts = 1; /* Send I packets */
-
-CHAR padch = MYPADC, /* Padding character to send */
- mypadc = MYPADC, /* Padding character to ask for */
- seol = MYEOL, /* End-Of-Line character to send */
- eol = MYEOL, /* End-Of-Line character to look for */
- ctlq = CTLQ, /* Control prefix in incoming data */
- myctlq = CTLQ, /* Outbound control character prefix */
- myrptq = MYRPTQ; /* Repeat prefix I want to use */
-
-int rptmin = 3; /* Repeat-count minimum */
-
-int usepipes = 0, /* Used for xfer to/from pipes */
- g_usepipes = -1;
-
-char * filefile = NULL; /* File containing list of filenames */
-/* CD message filename list */
-
-char whoareu[16] = { NUL, NUL }; /* System ID of other Kermit */
-int sysindex = -1; /* and index to its system ID struct */
-int myindex = -1;
-int wearealike = 0; /* 2 Kermits have compatible sysids */
-char * cksysid = /* My system ID */
-#ifdef UNIX
- "U1"
-#else
-#ifdef VMS
- "D7"
-#else
-#ifdef OSK
- "UD"
-#else
-#ifdef AMIGA
- "L3"
-#else
-#ifdef MAC
- "A3"
-#else
-#ifdef OS2
-#ifdef NT
- "UN"
-#else /* NT */
- "UO"
-#endif /* NT */
-#else /* OS2 */
-#ifdef datageneral
- "F3"
-#else
-#ifdef GEMDOS
- "K2"
-#else
-#ifdef STRATUS
- "MV"
-#else
- ""
-#endif /* STRATUS */
-#endif /* GEMDOS */
-#endif /* datageneral */
-#endif /* OS2 */
-#endif /* MAC */
-#endif /* AMIGA */
-#endif /* OSK */
-#endif /* VMS */
-#endif /* UNIX */
- ;
-
-int oopts = -1; /* O-Packet Options */
-int omode = -1; /* O-Packet Transfer Mode */
-int oname = -1; /* O-Packet Filename Options */
-int opath = -1; /* O-Packet Pathname Options */
-
-struct zattr iattr; /* Incoming file attributes */
-
-#ifdef VMS
-/* VMS labeled file default options - name only. */
-int lf_opts = LBL_NAM;
-#else
-#ifdef OS2
-/* OS/2 labeled file default options, all attributes but archived. */
-unsigned long int lf_opts = LBL_EXT|LBL_HID|LBL_RO|LBL_SYS;
-#else
-int lf_opts = 0;
-#endif /* OS2 */
-#endif /* VMS */
-
-/* Packet-related variables */
-
-int pktnum = 0, /* Current packet number */
- sndtyp = 0, /* Type of packet just sent */
- rcvtyp = 0, /* Type of packet just received */
- rsn, /* Received packet sequence number */
- rln, /* Received packet length */
- size, /* Current size of output pkt data */
- osize, /* Previous output packet data size */
- maxsize, /* Max size for building data field */
- spktl = 0, /* Length packet being sent */
- rpktl = 0, /* Length of packet just received */
- pktpaus = 0, /* Interpacket pause interval, msec */
- rprintf, /* REMOTE PRINT flag */
- rmailf, /* MAIL flag */
- xferstat = -1, /* Status of last transaction */
- filestatus = 0; /* Status of last file transfer */
-
-CHAR pktmsgbuf[PKTMSGLEN+1];
-CHAR *epktmsg = pktmsgbuf;
-
-#ifdef pdp11
-int srvcmdlen = MAXRP; /* srvcmd buffer length */
-#else
-#ifdef DYNAMIC
-int srvcmdlen = MAXRP;
-#else
-int srvcmdlen = 0;
-#endif /* DYNAMIC */
-#endif /* pdp11 */
-
-CHAR
-#ifdef pdp11
- srvcmdbuf[MAXRP+4],
- *srvcmd = srvcmdbuf,
-#else
-#ifdef DYNAMIC
- *srvcmd = (CHAR *)0, /* Where to decode server command */
-#else
- srvcmdbuf[MAXRP+4],
- *srvcmd = srvcmdbuf,
-#endif /* DYNAMIC */
-#endif /* pdp11 */
- padbuf[96], /* Buffer for send-padding */
- *recpkt,
- *rdatap, /* Pointer to received packet data */
- *data = (CHAR *)0, /* Pointer to send-packet data */
- *srvptr, /* Pointer to srvcmd */
- mystch = SOH, /* Outbound packet-start character */
- stchr = SOH; /* Incoming packet-start character */
-
-/* File-related variables */
-
-#ifndef NOMSEND /* Multiple SEND */
-struct filelist * filehead = NULL; /* SEND list */
-struct filelist * filetail = NULL;
-struct filelist * filenext = NULL;
-int addlist = 0;
-#endif /* NOMSEND */
-
-char filnam[CKMAXPATH + 1]; /* Name of current file. */
-char ofilnam[CKMAXPATH + 1]; /* Original name. */
-
-int pipesend = 0; /* Nonzero if sending from pipe */
-#ifdef PIPESEND
-char * sndfilter = NULL; /* Send and receive filters */
-char * rcvfilter = NULL;
-#endif /* PIPESEND */
-
-char ** sndarray = NULL; /* SEND /ARRAY pointer and range */
-#ifndef NOSPL
-int sndxlo = -1, sndxhi = -1, sndxin = -1;
-#endif /* NOSPL */
-#endif /* NOXFER */
-
-#ifndef NOSERVER
-int ngetpath = 0; /* GET search path */
-int fromgetpath = 0;
-char * getpath[MAXGETPATH];
-char * x_user = NULL; /* Server login information */
-char * x_passwd = NULL;
-char * x_acct = NULL;
-#endif /* NOSERVER */
-
-int x_login = 0; /* Login required */
-int x_logged = 0; /* User is logged in */
-
-extern int timelimit;
-
-#ifdef CK_LOGIN
-int logintimo = 300; /* Login timeout */
-char * userfile = NULL; /* Forbidden user file */
-#endif /* CK_LOGIN */
-#ifdef IKSD
-char * anonfile = NULL; /* Anonymous login init file */
-char * anonroot = NULL; /* Anonymous file-system root */
-int iks_timo = 300; /* 5 minutes idle timo */
-int iks_retry = 3; /* 3 attempts at login */
-#endif /* IKSD */
-
-#ifdef CKSYSLOG
-extern VOID zsyslog();
-extern int ckxlogging, ckxsyslog;
-#endif /* CKSYSLOG */
-
-CK_OFF_T fsize = (CK_OFF_T)0, /* Size of current file */
- sendstart = (CK_OFF_T)0, /* SEND start position */
- calibrate = (CK_OFF_T)0; /* Nonzero if calibration run */
-
-int nzxopts = 0; /* Options for nzxpand() */
-int nfils = 0; /* Number of files in file group */
-int wildena = 1; /* Wildcard expansion enabled */
-#ifdef UNIX
-int wildxpand = 0; /* Who expands wildcards, 0=Kermit.. */
-#else /* UNIX */
-#ifdef STRATUS
-int wildxpand = 1; /* 1=Shell. */
-#endif /* STRATUS */
-#endif /* UNIX */
-#ifdef UNIXOROSK
-int matchdot = 0; /* Whether to match dot files */
-#else
-int matchdot = 1;
-#endif /* UNIXOROSK */
-int matchfifo = 0; /* Whether to match FIFO "files" */
-int clfils = 0; /* Flag for command-line files */
-int stayflg = 0; /* Flag for "stay", i.e. "-S" */
-int xfinish = 0; /* Flag for FINISH = EXIT */
-long ztusec = -1L; /* Used with ztime() */
-long ztmsec = -1L; /* Ditto */
-
-/* Communication device / connection variables */
-
-char ttname[TTNAMLEN+1]; /* Name of communication device */
-
-#ifdef MAC
-int connected = 0; /* True if connected */
-int startconnected; /* initial state of connected */
-#endif /* MAC */
-
-long speed = -1L; /* Communication device speed */
-int wasclosed = 0; /* Connection was just closed */
-int whyclosed = WC_REMO; /* why it was closed */
-int qnxportlock = 0; /* QNX port locking on/off */
-
-#ifndef CLSONDISC
-#define CLSONDISC 0
-#endif /* CLSONDISC */
-
-int cxflow[CXT_MAX+1]; /* See initflow() */
-
-#ifndef NOSHOW
-char * floname[] = { /* Flow control names */
- "none", "xon/xoff", "rts/cts", "dtr/cd", "etx/ack", "string",
- "xxx1", "xxx2", "dtr/cts", "keep", "auto"
-};
-int nfloname = (sizeof(floname) / sizeof(char *));
-
-char * cxname[] = { /* Connection type names */
- "remote", "direct-serial", "modem", "tcp/ip", "x.25", "decnet",
- "lat", "netbios", "named-pipe", "ssh", "pipe"
-};
-int ncxname = (sizeof(cxname) / sizeof(char *));
-#endif /* NOSHOW */
-
-int parity = DEFPAR, /* Parity specified, 0,'e','o',etc */
- hwparity = 0, /* Hardware parity for serial port */
- stopbits = -1, /* Stop bits for serial port */
- clsondisc = CLSONDISC, /* Serial port close on disconnect */
- autopar = 0, /* Automatic parity change flag */
- sosi = 0, /* Shift-In/Out flag */
- flow = 0, /* Flow control (see initflow()) */
- autoflow = 1, /* Automatic flow control */
- turn = 0, /* Line turnaround handshake flag */
- turnch = XON, /* Line turnaround character */
- duplex = 0, /* Duplex, full by default */
- escape = DFESC, /* Escape character for connect */
- ckdelay = DDELAY, /* Initial delay before sending */
- tnlm = 0; /* Terminal newline mode */
-
-/* Networks for SET HOST */
-
-#ifdef BIGBUFOK
-#define MYHOSTL 1024
-#else
-#define MYHOSTL 100
-#endif /* BIGBUFOK */
-
-char myhost[MYHOSTL]; /* Local host name */
-int network = 0; /* Network vs serial connection */
-int inserver = 0; /* Running as an Internet server */
-int isguest = 0; /* User is anonymous */
-char * clienthost = NULL; /* Peer host name or address */
-int tcp_incoming = 0; /* Incoming TCP connection? */
-
-#ifdef NETCONN
-#ifdef TCPSOCKET
-int nettype = NET_TCPB; /* Default network type */
-#else
-#ifdef SUNX25
-int nettype = NET_SX25;
-#else
-#ifdef IBMX25
-int nettype = NET_IX25;
-#else
-#ifdef HPX25
-int nettype = NET_HX25;
-#else
-#ifdef STRATUSX25
-int nettype = NET_VX25;
-#else
-#ifdef DECNET
-int nettype = NET_DEC;
-#else
-#ifdef SUPERLAT
-int nettype = NET_SLAT;
-#else
-int nettype = NET_NONE;
-#endif /* SUPERLAT */
-#endif /* DECNET */
-#endif /* STRATUSX25 */
-#endif /* HPX25 */
-#endif /* IBMX25 */
-#endif /* SUNX25 */
-#endif /* TCPSOCKET */
-#else /* NETCONN */
-int nettype = NET_NONE;
-#endif /* NETCONN */
-
-#ifdef ANYX25
-int revcall = 0; /* X.25 reverse call not selected */
-int closgr = -1; /* X.25 closed user group */
-int cudata = 0; /* X.25 call user data not specified */
-char udata[MAXCUDATA]; /* X.25 call user data */
-
-#ifdef IBMX25
-/*
- I was unable to find any pre-defined MAX values for x25 addresses - the
- addresses that I've seen have been around 10-12 characters 32 is probably
- enough, 64 is hopefully safe for everyone.
-*/
- x25addr_t local_nua = {'\0'}; /* local x.25 address */
- x25addr_t remote_nua = {'\0'}; /* remote x.25 address */
- char x25name[32] = {'\0'}; /* x25 device name, sx25a0 or sx25a1 */
- char x25dev[64] = "/dev/x25pkt"; /* x25 device in /dev */
- int x25port = 0; /* port used for X.25 - AIX only */
-#endif /* IBMX25 */
-
-#ifndef IBMX25
-/*
- This condition is unrelated to the above IBMX25 condition.
- IBM X.25 doesn't have PAD support.
-*/
- CHAR padparms[MAXPADPARMS+1]; /* X.3 parameters */
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-/* Other items */
-
-int isinterrupted = 0; /* Used in exception handling */
-int what = W_INIT; /* What I am doing */
-int lastxfer = 0; /* Last transfer (send or receive) */
-
-extern int mdmtyp; /* Modem (/network) type */
-
-#ifdef NT
-extern int StartedFromDialer;
-#ifdef NTSIG
-extern int TlsIndex;
-#endif /* NTSIG */
-#ifdef NTASM
-unsigned long ESPToRestore; /* Ditto */
-#endif /* NTASM */
-#endif /* NT */
-
-#ifdef OS2PM
-int os2pm = 0; /* OS/2 Presentation Manager flag */
-#endif /* OS2PM */
-
-/* Terminal screen size, if known, -1 means unknown. */
-
-#ifdef OS2
-#include "ckocon.h"
-#ifdef KUI
-int tt_rows[VNUM] = {24,24,25,1}; /* Rows (height) */
-int tt_cols[VNUM] = {80,80,80,80}; /* Columns (width) */
-int cmd_rows = 24, cmd_cols = 80; /* Command/console screen dimensions */
-#else /* KUI */
-int tt_rows[VNUM] = {-1,24,25,1}; /* Rows (height) */
-int tt_cols[VNUM] = {-1,80,80,80}; /* Columns (width) */
-int cmd_rows = -1, cmd_cols = -1; /* Command/console screen dimensions */
-#endif /* KUI */
-int k95stdio = 0; /* Stdio threads */
-int tt_bell = XYB_AUD | XYB_SYS; /* BELL AUDIBLE (system sounds) */
-#else /* OS2 */
-int tt_rows = -1; /* Rows (height) */
-int tt_cols = -1; /* Columns (width) */
-int cmd_rows = 24, cmd_cols = 80; /* Command/console screen dimensions */
-int tt_bell = XYB_AUD; /* BELL ON */
-#endif /* OS2 */
-
-int tt_print = 0; /* Transparent print disabled */
-int tt_escape = 1; /* Escaping back is enabled */
-int tt_scroll = 1; /* Scrolling operations are enabled */
-
-int tn_exit = 0; /* Exit on disconnect */
-
-int exitonclose = 0; /* Exit on close */
-int exithangup = 1; /* Hangup on exit */
-int haveline = 0; /* SET LINE or SET HOST in effect */
-int tlevel = -1; /* Take-file command level */
-int hints = 1; /* Whether to give hints */
-
-#ifdef NOLOCAL
-int remonly = 1; /* Remote-mode-only advisory (-R) */
-int nolocal = 1; /* Remote-only strictly enforced */
-#else
-int remonly = 0;
-int nolocal = 0;
-int cx_status = 0; /* CONNECT return status */
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
-extern int cmdlvl; /* Command level */
-extern int maclvl; /* Macro invocation level */
-#endif /* NOSPL */
-
-int protocol = PROTO_K; /* File transfer protocol = Kermit */
-
-#ifdef NEWDEFAULTS
-int prefixing = PX_CAU;
-#else
-int prefixing = PX_ALL;
-#endif /* NEWDEFAULTS */
-
-extern short ctlp[]; /* Control-prefix table */
-
-int carrier = CAR_AUT; /* Pay attention to carrier signal */
-int cdtimo = 0; /* Carrier wait timeout */
-int xitsta = GOOD_EXIT; /* Program exit status */
-
-#ifdef VMS /* Default filename collision action */
-int fncact = XYFX_X; /* REPLACE for VMS */
-#else
-int fncact = XYFX_B; /* BACKUP for everybody else */
-#endif /* VMS */
-
-int fncsav = -1; /* For saving & restoring the above */
-int bgset = -1; /* BACKGROUND mode set explicitly */
-
-int cmdint = 1; /* Interrupts are allowed */
-#ifdef UNIX
-int xsuspend = DFSUSP; /* Whether SUSPEND command, etc, */
-#else /* is to be allowed. */
-int xsuspend = 0;
-#endif /* UNIX */
-
-/* Statistics variables */
-
-CK_OFF_T
- flci, /* Characters from line, current file */
- flco, /* Chars to line, current file */
- tlci, /* Chars from line in transaction */
- tlco, /* Chars to line in transaction */
- ffc, /* Chars to/from current file */
- tfc; /* Chars to/from files in transaction */
-
-long filcnt, /* Number of files in transaction */
- filrej, /* Number of files rejected in transaction */
- cps = 0L, /* Chars/sec last transfer */
- peakcps = 0L, /* Peak chars/sec last transfer */
- ccu, /* Control chars unprefixed in transaction */
- ccp, /* Control chars prefixed in transaction */
- rptn; /* Repeated characters compressed */
-
-int tsecs = 0; /* Seconds for transaction */
-int fsecs = 0; /* Per-file timer */
-
-#ifdef GFTIMER
-CKFLOAT
- fpfsecs = 0.0, /* Floating point per-file timer */
- fptsecs = 0.0; /* and per-transaction timer */
-#endif /* GFTIMER */
-
-/* Flags */
-
-int deblog = 0, /* Debug log is open */
- debok = 1, /* Debug log is not disabled */
- debxlen = 54, /* Default length for debug strings */
- debses = 0, /* Flag for DEBUG SESSION */
- debtim = 0, /* Include timestamp in debug log */
- debmsg = 0, /* Debug messages on/off */
- pktlog = 0, /* Flag for packet logging */
- seslog = 0, /* Session logging */
- dialog = 0, /* DIAL logging */
- tralog = 0, /* Transaction logging */
- tlogfmt = 1, /* Transaction log format (verbose) */
- tlogsep = (int)',', /* Transaction log field separator */
- displa = 0, /* File transfer display on/off */
- stdouf = 0, /* Flag for output to stdout */
- stdinf = 0, /* Flag for input from stdin */
- xflg = 0, /* Flag for X instead of F packet */
- hcflg = 0, /* Doing Host command */
- dest = DEST_D, /* Destination for packet data */
- zchkod = 0, /* zchko() should work for dirs too? */
- zchkid = 0, /* zchki() should work for dirs too? */
-
-/* If you change this, also see struct ptab above... */
-
-#ifdef OS2 /* Flag for file name conversion */
- fncnv = XYFN_L, /* Default is Literal in OS/2, */
- f_save = XYFN_L, /* (saved copy of same) */
-#else
- fncnv = XYFN_C, /* elsewhere Convert them */
- f_save = XYFN_C, /* (ditto) */
-#endif /* OS2 */
-
- fnspath = PATH_OFF, /* Send file path */
- fnrpath = PATH_AUTO, /* Receive file path */
- fackpath = 1, /* Send back path in ACK to F */
- binary = XYFT_B, /* Default file transfer mode */
- b_save = XYFT_B, /* Saved file mode */
- eofmethod = 0, /* EOF detection method (length) */
-
-#ifdef OS2
- cursor_save = -1, /* Cursor state */
-#endif /* OS2 */
-
- xfermode = XMODE_A, /* Transfer mode, manual or auto */
- xfiletype = -1, /* Transfer only text (or binary) */
- recursive = 0, /* Recursive directory traversal */
- nolinks = 2, /* Don't follow symbolic links */
- skipbup = 0, /* Skip backup files when sending */
- sendmode = SM_SEND, /* Which type of SEND operation */
- slostart = 1, /* Slow start (grow packet lengths) */
- cmask = 0377, /* CONNECT (terminal) byte mask */
- fmask = 0377, /* File byte mask */
- ckwarn = 0, /* Flag for file warning */
- quiet = 0, /* Be quiet during file transfer */
- local = 0, /* 1 = local mode, 0 = remote mode */
- cxtype = CXT_REMOTE, /* Connection type */
- server = 0, /* Flag for I Am Server */
- query = 0, /* Flag for Query active */
- justone = 0, /* Server should do Just One command */
- urserver = 0, /* Flag for You Are Server */
- bye_active = 0, /* Flag for BYE command active */
- diractive = 0, /* Flag for DIRECTORY command active */
- cdactive = 0, /* Flag for CD command active */
- cflg = 0, /* Connect before transaction */
- cnflg = 0, /* Connect after transaction */
- cxseen = 0, /* Flag for cancelling a file */
- czseen = 0, /* Flag for cancelling file group */
- fatalio = 0, /* Flag for fatal i/o error */
- discard = 0, /* Flag for file to be discarded */
- keep = SET_AUTO, /* Keep incomplete files = AUTO */
- unkcs = 1, /* Keep file w/unknown character set */
-#ifdef VMS
- filepeek = 0, /* Inspection of files */
-#else
-#ifdef datgeneral
- filepeek = 0,
-#else
- filepeek = 1,
-#endif /* datageneral */
-#endif /* VMS */
- nakstate = 0, /* In a state where we can send NAKs */
- dblchar = -1, /* Character to double when sending */
- moving = 0, /* MOVE = send, then delete */
- reliable = SET_AUTO, /* Nonzero if transport is reliable */
- xreliable = -1,
- setreliable = 0,
- urclear = 0, /* Nonzero for clear channel to you */
- clearrq = SET_AUTO, /* SET CLEARCHANEL value */
- cleared = 0,
- streaming = 0, /* Nonzero if streaming is active */
- streamok = 0, /* Nonzero if streaming negotiated */
- streamrq = SET_AUTO, /* SET STREAMING value */
- streamed = -1; /* Whether we streamed last time */
-
-char * snd_move = NULL; /* Move file after sending it */
-char * snd_rename = NULL; /* Rename file after sending it */
-char * rcv_move = NULL; /* Move file after receiving it */
-char * rcv_rename = NULL; /* Rename file after receiving it */
-
-char * g_snd_move = NULL;
-char * g_snd_rename = NULL;
-char * g_rcv_move = NULL;
-char * g_rcv_rename = NULL;
-
-#ifdef CK_TRIGGER
-char *tt_trigger[TRIGGERS] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
-CHAR *tt_trmatch[TRIGGERS] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
-char *triggerval = NULL;
-#endif /* CK_TRIGGER */
-
-int ckxlogging = 0; /* Flag for syslogging active */
-int ikdbopen = 0; /* Flag for IKSD database active */
-int dbinited = 0; /* Flag for IKSDB record init'd */
-#ifndef CKSYSLOG
-int ckxsyslog = 0; /* Logging level 0 */
-#else
-#ifdef SYSLOGLEVEL
-int ckxsyslog = SYSLOGLEVEL; /* Logging level specified */
-#else
-int ckxsyslog = SYSLG_DF; /* Default logging level */
-#endif /* SYSLOGLEVEL */
-#endif /* CKSYSLOG */
-
-#ifndef NOHELP
-#ifndef NOCMDL
-_PROTOTYP( VOID iniopthlp, (void) ); /* Command-line help initializer */
-#endif /* NOCMDL */
-#endif /* NOHELP */
-
-_PROTOTYP( VOID getexedir, (void) );
-_PROTOTYP( int putnothing, (char) );
-
-#ifdef IKSD
-_PROTOTYP( VOID doiksdinit, (void) );
-_PROTOTYP( VOID iksdinit, (void) );
-_PROTOTYP( VOID doiklog, (void) );
-_PROTOTYP( int dbinit, (void) );
-#endif /* IKSD */
-
-/* Variables passed from command parser to protocol module */
-
-#ifndef NOSPL
-#ifndef NOICP
-#ifdef CK_APC
-_PROTOTYP( VOID apconect, (void) );
-#endif /* CK_APC */
-#ifdef OS2
-extern int initvik;
-#endif /* OS2 */
-#endif /* NOICP */
-#endif /* NOSPL */
-char *clcmds = NULL; /* Pointer to command-line commands */
-
-#ifndef NOSETKEY
-extern KEY *keymap;
-extern MACRO *macrotab;
-#endif /* NOSETKEY */
-
-#ifndef NOPUSH
-int nopush = 0; /* PUSH enabled */
-#else
-int nopush = 1; /* PUSH disabled */
-#endif /* NOPUSH */
-
-CHAR sstate = (CHAR) 0; /* Starting state for automaton */
-CHAR zstate = (CHAR) 0; /* For remembering sstate */
-char * printername = NULL; /* NULL if printer not redirected */
-int printpipe = 0; /* For SET PRINTER */
-int noprinter = 0;
-
-#ifndef NOXFER
-char *cmarg = ""; /* Pointer to command data */
-char *cmarg2 = ""; /* Pointer to 2nd command data */
-char **cmlist; /* Pointer to file list in argv */
-
-#ifdef CK_AUTODL /* Autodownload */
-int autodl = 1; /* Enabled by default */
-#else
-int autodl = 0; /* (or if not implemented). */
-#endif /* CK_AUTODL */
-int adl_err = 1; /* 1 = stop on error */
-#ifdef KUI
-int adl_ask = 1; /* 1 = file dialog on autodownload */
-#else
-int adl_ask = 0; /* 0 = no file dialog */
-#endif /* KUI */
-#ifdef OS2 /* AUTODOWNLOAD parameters */
-int adl_kmode = ADL_PACK, /* Match Packet to signal download */
- adl_zmode = ADL_PACK;
-char * adl_kstr = NULL; /* KERMIT Download String */
-char * adl_zstr = NULL; /* ZMODEM Download String */
-#endif /* OS2 */
-
-int remfile = 0, rempipe = 0, remappd = 0; /* REMOTE output redirection */
-char * remdest = NULL;
-
-#ifndef NOSERVER
-/*
- Server services:
- 0 = disabled
- 1 = enabled in local mode
- 2 = enabled in remote mode
- 3 = enabled in both local and remote modes
- only as initial (default) values.
-*/
-int en_xit = 2; /* EXIT */
-int en_cwd = 3; /* CD/CWD */
-int en_cpy = 3; /* COPY */
-int en_del = 2; /* DELETE */
-int en_mkd = 3; /* MKDIR */
-int en_rmd = 2; /* RMDIR */
-int en_dir = 3; /* DIRECTORY */
-int en_fin = 3; /* FINISH */
-int en_get = 3; /* GET */
-#ifndef NOPUSH
-int en_hos = 2; /* HOST enabled */
-#else
-int en_hos = 0; /* HOST disabled */
-#endif /* NOPUSH */
-int en_ren = 3; /* RENAME */
-int en_sen = 3; /* SEND */
-int en_set = 3; /* SET */
-int en_spa = 3; /* SPACE */
-int en_typ = 3; /* TYPE */
-int en_who = 3; /* WHO */
-#ifdef datageneral
-/* Data General AOS/VS can't do this */
-int en_bye = 0; /* BYE */
-#else
-int en_bye = 2; /* PCs in local mode... */
-#endif /* datageneral */
-int en_asg = 3; /* ASSIGN */
-int en_que = 3; /* QUERY */
-int en_ret = 2; /* RETRIEVE */
-int en_mai = 3; /* MAIL */
-int en_pri = 3; /* PRINT */
-int en_ena = 3; /* ENABLE */
-#else
-int en_xit = 0, en_cwd = 0, en_cpy = 0, en_del = 0, en_mkd = 0, en_rmd = 0,
- en_dir = 0, en_fin = 0, en_get = 0, en_hos = 0, en_ren = 0, en_sen = 0,
- en_set = 0, en_spa = 0, en_typ = 0, en_who = 0, en_bye = 0, en_asg = 0,
- en_que = 0, en_ret = 0, en_mai = 0, en_pri = 0, en_ena = 0;
-#endif /* NOSERVER */
-#endif /* NOXFER */
-
-/* Miscellaneous */
-
-char **xargv; /* Global copies of argv */
-int xargc; /* and argc */
-int xargs; /* an immutable copy of argc */
-char *xarg0; /* and of argv[0] */
-char *pipedata; /* Pointer to -P (pipe) data */
-
-extern char *dftty; /* Default tty name from ck?tio.c */
-extern int dfloc; /* Default location: remote/local */
-extern int dfprty; /* Default parity */
-extern int dfflow; /* Default flow control */
-
-#ifdef TNCODE
-extern int tn_deb;
-#endif /* TNCODE */
-/*
- Buffered file input and output buffers. See getpkt() in ckcfns.c
- and zoutdump() in the system-dependent file i/o module (usually ck?fio.c).
-*/
-#ifndef DYNAMIC
-/* Now we allocate them dynamically, see getiobs() below. */
-char zinbuffer[INBUFSIZE], zoutbuffer[OBUFSIZE];
-#endif /* DYNAMIC */
-char *zinptr, *zoutptr;
-int zincnt, zoutcnt;
-int zobufsize = OBUFSIZE;
-int zofbuffer = 1;
-int zofblock = 1;
-
-#ifdef SESLIMIT
-int seslimit = 0;
-#endif /* SESLIMIT */
-
-#ifdef CK_AUTHENTICATION
-#include "ckuath.h"
-#endif /* CK_AUTHENTICATION */
-
-_PROTOTYP( int getiobs, (VOID) );
-
-/* M A I N -- C-Kermit main program */
-
-#include <signal.h>
-
-#ifndef VMS
-#include <time.h>
-#endif
-
-#ifndef NOCCTRAP
-#include <setjmp.h>
-#include "ckcsig.h"
-ckjmpbuf cmjbuf;
-#ifdef GEMDOS /* Special for Atari ST */
-cc_clean(); /* This can't be right? */
-#endif /* GEMDOS */
-#endif /* NOCCTRAP */
-
-#ifndef NOXFER
-/* Info associated with a system ID */
-
-struct sysdata sysidlist[] = { /* Add others as needed... */
- { "0", "anonymous", 0, NUL, 0, 0, 0 },
- { "A1", "Apple II", 0, NUL, 0, 0, 3 }, /* fix this */
- { "A3", "Macintosh", 1, ':', 0, 2, 1 },
- { "D7", "VMS", 0, ']', 1, 0, 0 },
- { "DA", "RSTS/E", 0, ']', 1, 0, 3 }, /* (i think...) */
- { "DB", "RT11", 0, NUL, 1, 0, 3 }, /* (maybe...) */
- { "F3", "AOS/VS", 1, ':', 0, 0, 2 },
- { "I1", "VM/CMS", 0, NUL, 0, 0, 0 },
- { "I2", "MVS/TSO", 0, NUL, 0, 0, 0 },
- { "I4", "MUSIC", 0, NUL, 0, 0, 0 },
- { "I7", "CICS", 0, NUL, 0, 0, 0 },
- { "I9", "MVS/ROSCOE", 0, NUL, 0, 0, 0 },
- { "K2", "Atari ST", 1, '\\', 1, 0, 3 },
- { "L3", "Amiga", 1, '/', 1, 0, 2 },
- { "MV", "Stratus VOS", 1, '>', 0, 1, 0 },
- { "N3", "Apollo Aegis", 1, '/', 0, 3, 2 },
- { "U1", "UNIX", 1, '/', 0, 3, 2 },
- { "U8", "MS-DOS", 1, '\\', 1, 0, 3 },
- { "UD", "OS-9", 1, '/', 0, 3, 2 },
- { "UN", "Windows-32", 1, '\\', 1, 2, 3 },
- { "UO", "OS/2", 1, '\\', 1, 2, 3 }
-};
-static int nxxsysids = (sizeof(sysidlist) / sizeof(struct sysdata));
-
-/* Given a Kermit system ID code, return the associated name string */
-/* and some properties of the filenames... */
-
-char *
-getsysid(s) char * s; { /* Get system-type name */
- int i;
- if (!s) return("");
- for (i = 0; i < nxxsysids; i++)
- if (!strcmp(sysidlist[i].sid_code,s))
- return(sysidlist[i].sid_name);
- return(s);
-}
-
-int
-getsysix(s) char *s; { /* Get system-type index */
- int i;
- if (!s) return(-1);
- for (i = 0; i < nxxsysids; i++)
- if (!strcmp(sysidlist[i].sid_code,s))
- return(i);
- return(-1);
-}
-#endif /* NOXFER */
-
-/* Tell if a pathname is absolute (versus relative) */
-/* This should be parceled out to each of the ck*fio.c modules... */
-/* VMS isabsolute() is now in ckvfio.c. */
-#ifndef VMS
-int
-isabsolute(path) char * path; {
- int rc = 0;
- int x;
- if (!path)
- return(0);
- if (!*path)
- return(0);
- x = (int) strlen(path);
- debug(F111,"isabsolute",path,x);
-#ifdef UNIX
- if (*path == '/'
-#ifdef DTILDE
- || *path == '~'
-#endif /* DTILDE */
- )
- rc = 1;
-#else /* def UNIX */
-#ifdef OS2
- if (*path == '/' || *path == '\\')
- rc = 1;
- else if (isalpha(*path) && x > 2)
- if (*(path+1) == ':' && (*(path +2) == '/' || *(path+2) == '\\'))
- rc = 1;
-#else /* def OS2 */
-#ifdef AMIGA
- if (*path == '/'
-#ifdef DTILDE
- || *path == '~'
-#endif /* DTILDE */
- )
- rc = 1;
-#else /* def AMIGA */
-#ifdef OSK
- if (*path == '/'
-#ifdef DTILDE
- || *path == '~'
-#endif /* DTILDE */
- )
- rc = 1;
-#else /* def OSK */
-#ifdef datageneral
- if (*path == ':')
- rc = 1;
-#else /* def datageneral */
-#ifdef MAC
- rc = 0; /* Fill in later... */
-#else /* def MAC */
-#ifdef STRATUS
- rc = 0; /* Fill in later... */
-#else /* def STRATUS */
-#ifdef GEMDOS
- if (*path == '/' || *path == '\\')
- rc = 1;
- else if (isalpha(*path) && x > 1)
- if (*(path+1) == ':')
- rc = 1;
-#endif /* GEMDOS */
-#endif /* STRATUS */
-#endif /* MAC */
-#endif /* datageneral */
-#endif /* OSK */
-#endif /* AMIGA */
-#endif /* OS2 */
-#endif /* UNIX */
- debug(F101,"isabsolute rc","",rc);
- return(rc);
-}
-#endif /* ndef VMS */
-
-/* See if I have direct access to the keyboard */
-
-int
-is_a_tty(n) int n; {
-#ifdef UNIX
- extern int ttfdflg;
- if (ttfdflg > 0)
- return(1);
-#endif /* UNIX */
-#ifdef KUI
- return 1;
-#else /* KUI */
-#ifdef NT
- if (isWin95())
- return(1);
- else
- return(_isatty(n));
-#else
-#ifdef IKSD
- if (inserver)
- return(1);
- else
-#endif /* IKSD */
- return(isatty(n));
-#endif /* NT */
-#endif /* KUI */
-}
-
-#ifndef NOXFER
-VOID
-initxlist() {
- extern char * sndexcept[], * rcvexcept[];
- int i;
- for (i = 0; i < NSNDEXCEPT; i++) {
- sndexcept[i] = NULL;
- rcvexcept[i] = NULL;
- }
-}
-#endif /* NOXFER */
-
-/* Initialize flow control table */
-
-VOID
-initflow() { /* Default values for flow control */
-#ifdef VMS /* for each kind of connection. */
- /* The VMS telnet terminal driver treats "none" as request to lose chars */
- cxflow[CXT_REMOTE] = FLO_XONX; /* Remote mode... */
-#else
-#ifdef HPUX
- /* Ditto for HP-UX */
- cxflow[CXT_REMOTE] = FLO_XONX; /* Remote mode... */
-#else
- /* The temptation is to make this one FLO_KEEP but don't!!! */
- /* It totally wrecks binary-file transfer when coming in via Telnet. */
- /* In UNIX at least... */
- cxflow[CXT_REMOTE] = FLO_NONE;
-#endif /* HPUX */
-#endif /* VMS */
-
-#ifdef VMS
- cxflow[CXT_DIRECT] = FLO_XONX; /* Direct serial connections... */
-#else
- cxflow[CXT_DIRECT] = FLO_NONE;
-#endif /* VMS */
-
-#ifdef CK_RTSCTS
- cxflow[CXT_MODEM] = FLO_RTSC; /* Modem connections... */
-#else
-#ifdef VMS
- cxflow[CXT_MODEM] = FLO_XONX;
-#else
- cxflow[CXT_MODEM] = FLO_NONE;
-#endif /* VMS */
-#endif /* CK_RTSCTS */
-
-#ifdef VMS
- cxflow[CXT_TCPIP] = FLO_XONX; /* TCP/IP connections... */
-#else
- cxflow[CXT_TCPIP] = FLO_NONE;
-#endif /* VMS */
-
- cxflow[CXT_SSH] = FLO_NONE;
- cxflow[CXT_X25] = FLO_NONE; /* Other kinds of networks... */
- cxflow[CXT_DECNET] = FLO_XONX;
- cxflow[CXT_LAT] = FLO_XONX;
- cxflow[CXT_NETBIOS] = FLO_NONE;
- cxflow[CXT_NPIPE] = FLO_NONE;
- cxflow[CXT_PIPE] = FLO_NONE;
- flow = cxflow[cxtype]; /* Initial flow setting. */
- debug(F101,"initflow","",flow);
-}
-
-#ifndef NOXFER
-/* Initialize file transfer protocols */
-
-VOID
-initproto(y, upbstr, uptstr, srvstr, sndbstr, sndtstr, rcvbstr, rcvtstr)
- int y;
- char * upbstr, * uptstr, * srvstr, * sndbstr, * sndtstr, * rcvbstr,
- * rcvtstr;
-/* initproto */ {
-
- if (upbstr) /* Convert null strings */
- if (!*upbstr) /* to null pointers */
- upbstr = NULL;
-
- if (uptstr) /* Convert null strings */
- if (!*uptstr) /* to null pointers */
- uptstr = NULL;
-
- if (sndbstr)
- if (!*sndbstr)
- sndbstr = NULL;
-
- if (sndtstr)
- if (!*sndtstr)
- sndtstr = NULL;
-
- if (rcvbstr)
- if (!*rcvbstr)
- rcvbstr = NULL;
-
- if (rcvtstr)
- if (!*rcvtstr)
- rcvtstr = NULL;
-
- if (srvstr)
- if (!*srvstr)
- srvstr = NULL;
-
- protocol = y; /* Set protocol */
-
- if (ptab[protocol].rpktlen > -1)
- urpsiz = ptab[protocol].rpktlen;
- if (ptab[protocol].spktflg > -1)
- spsizf = ptab[protocol].spktflg;
- if (ptab[protocol].spktlen > -1) {
- spsiz = ptab[protocol].spktlen;
- debug(F101,"initproto spsiz","",spsiz);
- if (spsizf) {
- spsizr = spmax = spsiz;
- debug(F101,"initproto spsizr","",spsizr);
- }
- }
- if (ptab[protocol].winsize > -1)
- wslotr = ptab[protocol].winsize;
- if (ptab[protocol].prefix > -1)
- prefixing = ptab[protocol].prefix;
- if (ptab[protocol].fnca > -1)
- fncact = ptab[protocol].fnca;
- if (ptab[protocol].fncn > -1)
- fncnv = ptab[protocol].fncn;
- if (ptab[protocol].fnsp > -1)
- fnspath = ptab[protocol].fnsp;
- if (ptab[protocol].fnrp > -1)
- fnrpath = ptab[protocol].fnrp;
-
- makestr(&(ptab[protocol].h_b_init),upbstr);
- makestr(&(ptab[protocol].h_t_init),uptstr);
- makestr(&(ptab[protocol].h_x_init),srvstr);
- makestr(&(ptab[protocol].p_b_scmd),sndbstr);
- makestr(&(ptab[protocol].p_t_scmd),sndtstr);
- makestr(&(ptab[protocol].p_b_rcmd),rcvbstr);
- makestr(&(ptab[protocol].p_t_rcmd),rcvtstr);
-}
-#endif /* NOXFER */
-
-#ifndef NOCMDL
-VOID
-#ifdef CK_ANSIC
-docmdline(void * threadinfo)
-#else /* CK_ANSIC */
-docmdline(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- setint();
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug( F100, "docmdline called with threadinfo block", "", 0 );
- } else
- debug( F100, "docmdline threadinfo is NULL","",0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef NT
-#ifdef IKSD
- if (inserver)
- setntcreds();
-#endif /* IKSD */
-#endif /* NT */
-#endif /* CK_LOGIN */
- proto(); /* Take any requested action, then */
- if (!quiet) /* put cursor back at left margin, */
- conoll("");
-#ifndef NOLOCAL
- if (cnflg) { /* Re-connect if requested */
- cnflg = 0;
- doconect(0,0);
- if (ttchk() < 0)
- dologend();
- }
-#endif /* NOLOCAL */
-
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
-}
-
-void
-ikslogin() {
- if (sstelnet
-#ifdef IKSD
- || inserver /* Internet server */
-#endif /* IKSD */
- ) {
- char *s;
- extern int fdispla; /* File-transfer display format */
- extern char * ikprompt; /* IKSD prompt */
-
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver) {
- x_login = 1; /* Login required */
- x_logged = 0; /* Not logged in yet */
- cmsetp(ikprompt); /* Set up IKSD's prompt */
-#ifndef NOSERVER
- en_mai = 0; /* MAIL is disabled */
- en_who = 0; /* REMOTE WHO is disabled */
- en_hos = 0; /* REMOTE HOST is disabled */
- en_pri = 0; /* PRINT is disabled */
-#endif /* NOSERVER */
- } else {
- x_login = 0; /* Login not required */
- x_logged = 1; /* Already logged in */
- }
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- nolocal = 1; /* SET LINE/HOST not allowed */
- fdispla = XYFD_N; /* No file-transfer display */
-#ifdef NETCONN
- clienthost = ckgetpeer(); /* Get client's hostname */
- debug(F110,"ikslogin clienthost",clienthost,0);
-#endif /* NETCONN */
- ztime(&s); /* Get current date and time */
-
-#ifdef CK_LOGIN
-#ifdef CK_AUTHENTICATION
- if (x_login) {
- x_logged = ck_tn_auth_valid(); /* Did Telnet Auth succeed? */
- debug(F111,"ikslogin","x_logged",x_logged);
-
-#ifdef NT
- /* On Windows 9x, we do not have the ability in */
- /* zvuser() at present to determine if the name */
- /* approved in a Kerberos principal is really a */
- /* an account in the Windows Access Control List */
- if (isWin95() && x_logged == AUTH_VALID
- && (ck_tn_authenticated() != AUTHTYPE_NTLM)
-#ifdef CK_SRP
- && (ck_tn_authenticated() != AUTHTYPE_SRP)
-#endif /* CK_SRP */
- ) {
- auth_finished(AUTH_USER);
- x_logged = AUTH_USER;
- printf("WARNING:\r\n");
- printf(
-" The Telnet authentication method used cannot provide for automated\r\n");
- printf(
-" login to Windows 95 or Windows 98. A password must be entered\r\n");
- printf(
-" locally to validate your userid. Telnet authentication (and encryption)\r\n"
- );
- printf(
-" can be used to validate the host (and protect the privacy of your password.)\
-\r\n"
- );
- }
-#endif /* NT */
-
- if (x_logged == AUTH_VALID) {
-#ifdef CK_SSL
- if ((ssl_active_flag || tls_active_flag) &&
- (!TELOPT_U(TELOPT_AUTHENTICATION) ||
- ck_tn_authenticated() == AUTHTYPE_NULL ||
- ck_tn_authenticated() == AUTHTYPE_AUTO)
- ) {
-#ifdef SSL_KRB5
- if (tls_is_krb5(0)) {
- printf("Authenticated using Kerberos 5\r\n");
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- extern char szUserNameAuthenticated[];
- cksyslog(SYSLG_LI, 1, "AUTH_VALID",
- "Kerberos 5",
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- } else
-#endif /* SSL_KRB5 */
- {
- printf("Authenticated using X.509 certificate\r\n");
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- extern char szUserNameAuthenticated[];
- cksyslog(SYSLG_LI, 1, "AUTH_VALID",
- "X.509 certificate",
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- }
- } else
-#endif /* CK_SSL */
- {
- printf("Authenticated using %s\r\n",
- AUTHTYPE_NAME(ck_tn_authenticated()));
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- extern char szUserNameAuthenticated[];
- cksyslog(SYSLG_LI, 1, "AUTH_VALID",
- AUTHTYPE_NAME(ck_tn_authenticated()),
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- }
- zvuser(uidbuf);
- if (zvpass("") == 0)
- x_logged = 0;
- } else if (x_logged == AUTH_USER && !strcmp(uidbuf,"anonymous")) {
- extern char szUserNameAuthenticated[];
- zvuser(uidbuf);
- debug(F110,"szUserNameAuthenticated",
- szUserNameAuthenticated,0);
- if (zvpass(szUserNameAuthenticated) == 0) {
- /* Anonymous login failed. Force a username prompt. */
- x_logged = 0;
- uidbuf[0] = '\0';
- } else {
-#ifdef CK_SSL
- if ((ssl_active_flag || tls_active_flag) &&
- (!TELOPT_U(TELOPT_AUTHENTICATION) ||
- ck_tn_authenticated() == AUTHTYPE_NULL ||
- ck_tn_authenticated() == AUTHTYPE_AUTO)) {
- printf("Authenticated using X.509 certificate\r\n");
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- extern char szUserNameAuthenticated[];
- cksyslog(SYSLG_LI, 1, "AUTH_USER",
- "X.509 certificate",
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- } else
-#endif /* CK_SSL */
- {
- printf("Authenticated using %s\r\n",
- AUTHTYPE_NAME(ck_tn_authenticated())
- );
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- cksyslog(SYSLG_LI, 1, "AUTH_USER",
- AUTHTYPE_NAME(ck_tn_authenticated()),
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- }
- }
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging &&
- x_logged == AUTH_USER) {
- extern char szUserNameAuthenticated[];
- cksyslog(SYSLG_LI, 1, "AUTH_USER",
- AUTHTYPE_NAME(ck_tn_authenticated()),
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- x_logged = 0;
- if (!strcmp("(unknown)",uidbuf)
-#ifdef NT
- || !stricmp("administrator",uidbuf)
-#ifdef UNIX
- || !strcmp("root",uidbuf)
-#else
-#ifdef Plan9
- || !strcmp("root",uidbuf)
-#else
-#ifdef OSK
- || !strcmp("root",uidbuf)
-#endif /* OSK */
-#endif /* Plan9 */
-#endif /* UNIX */
-#endif /* NT */
- )
- uidbuf[0] = '\0';
- }
- }
-#endif /* CK_AUTHENTICATION */
-#endif /* CK_LOGIN */
-
-#ifdef IKSD
- if (inserver)
- printf("\r\nInternet Kermit Service ready at %s%s\r\n",s,versio);
- else
-#endif /* IKSD */
- printf("\r\nC-Kermit ready at %s%s\r\n",s,versio);
- if (*myhost)
- printf("%s\r\n", myhost);
- printf("\r\n");
- }
-#ifdef CK_LOGIN
-#ifdef IKSD
- if (inserver) {
- int i;
- extern int arg_x; /* Flag for '-x' on command line */
-#ifndef NOSPL
- extern struct mtab *mactab; /* For ON_LOGIN macro. */
- extern int nmac;
-#endif /* NOSPL */
-
- debug(F110,"MAIN clienthost",clienthost,0);
- srvidl = timelimit = logintimo; /* For interactive login */
- rtimer(); /* Reset timer */
- for (i = 0; i < iks_retry && !x_logged; i++) { /* Count retries */
- if (gtimer() > logintimo)
- break;
-#ifdef TNCODE
- tn_wait("login loop");
- tn_push();
-#endif /* TNCODE */
- debug(F101,"MAIN LOGIN try","",i);
- what = W_NOTHING; /* Because proto() changes this */
-
-#ifdef IKS_OPTION
- debug(F111,"MAIN LOGIN",
- "TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start
- );
- /* Kermit server negotiated */
- if (TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- debug(F101,"IKSD starting in server mode","",0);
- arg_x = 1; /* Enter server mode */
- sstate = 'x';
-#ifdef IKSDPOPBACK
- justone = 1; /* Execute one command at a time. */
-#endif /* IKSDPOPBACK */
- proto(); /* Enter protocol if requested. */
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- if (x_logged) /* Logged in */
- break;
- } else { /* Not in client/server mode */
-#endif /* IKS_OPTION */
- debug(F101,"IKSD starting with Username prompt","",0);
- x_logged = ckxlogin((CHAR *)uidbuf,NULL,NULL,1);
- if (sstate) { /* Received a packet at prompt */
-#ifdef IKSDPOPBACK
- justone = 1; /* Go handle it */
-#endif /* IKSDPOPBACK */
- proto();
- }
- if (!x_logged) { /* In case we are at the prompt... */
- printf("Access denied.\n");
- uidbuf[0] = '\0'; /* Forget the name if we have one */
- }
-#ifdef IKS_OPTION
- }
-#endif /* IKS_OPTION */
- }
- srvidl = timelimit = iks_timo; /* Reset command timelimit */
- debug(F101,"MAIN LOGIN","",x_logged);
- if (!x_logged) { /* Logins failed. */
- if (TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
- errpkt((CHAR *)"Login Timeout");
- msleep(500);
- doexit(BAD_EXIT,0);
- }
- what = W_NOTHING; /* Stay in known state */
-#ifndef NOSERVER
- if (isguest) {
- en_pri = 0; /* No printing for anonymous users */
- en_mai = 0; /* No email for anonymous users */
- en_mkd = 0; /* Or directory creation */
- en_rmd = 0; /* Or directory removal */
- en_ena = 0; /* Or ENABLing DISABLEd items */
- }
-#endif /* NOSERVER */
-
-#ifndef NOSPL
-/*
- If a macro named "on_login" is defined, execute it. Also remove it from the
- macro table so the user cannot see what it does. Execute it as part of the
- iksd.conf file.
-*/
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- char * cmd = "on_login"; /* MSVC 2.x compiler error */
- k = mlook(mactab,cmd,nmac); /* Look up "on_login" */
- if (k >= 0) { /* If found, */
-#ifdef IKSDCONF
- int saved = iksdcf;
- iksdcf = 0;
-#endif /* IKSDCONF */
- if (dodo(k,"",0) > -1) /* set it up, */
- parser(1); /* execute it */
-#ifdef IKSDCONF
- iksdcf = saved;
-#endif /* IKSDCONF */
- delmac(cmd,1); /* and delete it */
- }
- }
-#endif /* NOSPL */
- } /* if (inserver) */
-#else /* CK_LOGIN */
- if (inserver)
- srvidl = timelimit = iks_timo; /* Set idle limits for IKS */
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-}
-
-VOID
-#ifdef CK_ANSIC
-failcmdline(void * foo)
-#else /* CK_ANSIC */
-failcmdline(foo) VOID * foo;
-#endif /* CK_ANSIC */
-{
-#ifdef GEMDOS
- cc_clean();
-#endif /* GEMDOS */
-#ifndef NOLOCAL
- if (cnflg) doconect(0,0); /* connect again if requested. */
- if (ttchk() < 0)
- dologend();
-#endif /* NOLOCAL */
-}
-#endif /* NOCMDL */
-
-#ifndef NOICP
-VOID
-#ifdef CK_ANSIC
-dotakeini(void * threadinfo) /* Execute init file. */
-#else /* CK_ANSIC */
-dotakeini(threadinfo) VOID * threadinfo; /* Execute init file. */
-#endif /* CK_ANSIC */
-/* dotakeini */ {
-#ifdef NTSIG
- setint();
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "dotakeini called with threadinfo block","", 0);
- } else
- debug(F100, "dotakeini - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef NT
-#ifdef IKSD
- if (inserver)
- setntcreds();
-#endif /* IKSD */
-#endif /* NT */
-#endif /* CK_LOGIN */
- cmdini(); /* Sets tlevel */
-
- debug(F111,"dotakeini","inserver",inserver);
- debug(F111,"dotakeini","sstelnet",sstelnet);
-
-#ifdef COMMENT
-/* Wrong place for this... */
-#ifndef NOXFER
-#ifdef CK_FAST
- dofast(); /* By now FAST defaults should be OK */
-#endif /* CK_FAST */
-#endif /* NOXFER */
-#endif /* COMMENT */
-
- doinit(); /* Now do the initialization file */
- debug(F101,"main executing init file","",tlevel);
- while (tlevel > -1) {
- sstate = (CHAR) parser(1); /* Execute one command at a time. */
- if (sstate) proto(); /* Enter protocol if requested. */
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- }
- debug(F101,"main exits init file","",tlevel);
-
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
-}
-
-VOID
-#ifdef CK_ANSIC
-failtakeini(void * threadinfo)
-#else /* CK_ANSIC */
-failtakeini(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* failtakeini */ {
-#ifdef GEMDOS
- cc_clean(); /* Atari: Clean up after ^C-trap. */
-#endif /* GEMDOS */
- fixcmd();
- if (!cfilef) {
- conoll("Interrupted during initialization or \
-command-line processing.");
- conoll("C-Kermit quitting...");
- }
- doexit(BAD_EXIT,-1); /* Exit with bad status. */
-}
-
-VOID
-#ifdef CK_ANSIC
-doicp(void * threadinfo)
-#else /* CK_ANSIC */
-doicp(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* doicp */ {
-#ifdef NTSIG
- setint();
- if (threadinfo) { /* Thread local storage... */
- if (!TlsSetValue(TlsIndex,threadinfo))
- debug(F101,"doicp TlsSetValue failed","",GetLastError());
- debug(F101, "doicp a threadinfo block - TlsIndex", "", TlsIndex);
- } else {
- debug(F100, "doicp received a null threadinfo", "", 0);
- }
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef NT
-#ifdef IKSD
- if (inserver)
- setntcreds();
-#endif /* IKSD */
-#endif /* NT */
-#endif /* CK_LOGIN */
-#ifdef MAC
- while (1) {
- extern char *lfiles; /* Fake pointer cast */
-
- if (connected) {
- debug(F100, "doicp: calling macparser", "", 0);
- sstate = newparser(1, 1, 0L);
-
- /* ignore null command state */
- if (sstate == 'n')
- sstate = '\0';
-
- if (sstate)
- proto();
- } else {
- /*
- * process take files the finder gave us.
- */
- if ((tlevel == -1) && lfiles)
- startlfile();
-
- debug(F100, "doicp: calling parser", "", 0);
- sstate = (CHAR) parser(0);
- if (sstate == 'c') /* if MAC connect */
- sstate = 0;
- if (sstate)
- proto();
- }
- }
-#else /* Not MAC */
-
-#ifndef NOSPL
-/*
- If interactive commands were given on the command line (using the
- -C "command, command, ..." option), assign them to a macro called
- "cl_commands", then execute the macro and leave it defined for
- subsequent re-execution if desired.
-*/
- if (clcmds) { /* Check for -C commands */
- int x;
- x = addmac("cl_commands",clcmds); /* Put macro in table */
- if (x > -1) { /* If successful, */
- dodo(x,NULL,CF_CMDL); /* set up for macro execution */
- while (maclvl > -1) { /* Loop getting macro commands. */
- sstate = (CHAR) parser(1);
- if (sstate) proto(); /* Enter protocol if requested. */
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- }
- }
- debug(F100,"doicp calling herald","",0);
- herald();
- }
-#endif /* NOSPL */
- while(1) { /* Loop getting commands. */
- sstate = (CHAR) parser(0);
- if (sstate) proto(); /* Enter protocol if requested. */
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- }
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
-#endif /* MAC */
-}
-
-VOID
-#ifdef CK_ANSIC
-failicp(void * threadinfo)
-#else /* CK_ANSIC */
-failicp(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef GEMDOS
- cc_clean();
-#endif /* GEMDOS */
- fixcmd(); /* Pop command stacks, etc. */
- clcmds = NULL;
- debug(F100,"ckcmai got interrupt","",0);
-}
-#endif /* NOICP */
-
-#ifndef NOICP
-VOID
-#ifdef CK_ANSIC
-docmdfile(void * threadinfo) /* Execute application file */
-#else /* CK_ANSIC */
-docmdfile(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* docmdfile */ {
-#ifdef NTSIG
- concb((char)escape);
- setint();
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
- debug(F110,"main cmdfil",cmdfil,0);
-#ifndef NOSPL
- addmac("\\%0",cmdfil);
-#endif /* NOSPL */
- dotake(cmdfil); /* Set up the command file */
- if (tlevel > -1) /* Remember we did this */
- cfilef = 1;
- while (tlevel > -1) { /* Execute it until it runs out. */
- sstate = parser(1); /* Loop getting commands. */
- if (sstate) proto(); /* Enter protocol if requested. */
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- }
-
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
-}
-
-VOID
-#ifdef CK_ANSIC
-failcmdfile(void * threadinfo)
-#else /* CK_ANSIC */
-failcmdfile(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* failcmdfile */ {
-#ifdef GEMDOS
- cc_clean(); /* Atari: Clean up after ^C-trap. */
-#endif /* GEMDOS */
- fixcmd();
- if (!cfilef) {
- conoll("Interrupted during initialization or \
-command-line processing.");
- conoll("C-Kermit quitting...");
- }
- doexit(BAD_EXIT,-1); /* Exit with bad status. */
-}
-#endif /* NOICP */
-
-#ifndef NOXFER
-VOID
-setprefix(z) int z; { /* Initial control-char prefixing */
-#ifdef CK_SPEED
- int i, val;
-
- prefixing = z;
- ptab[protocol].prefix = prefixing;
- debug(F101,"setprefix","",prefixing);
- switch (z) {
- case PX_ALL: /* All */
-#ifdef COMMENT
- /* Don't let Clear-Channel be dependent on prefixing */
- clearrq = 0; /* Turn off clearchannel, fall thru */
-#endif /* COMMENT */
- case PX_NON: /* None */
- val = (z == PX_ALL) ? 1 : 0;
- for (i =
-#ifdef UNPREFIXZERO
- 0
-#else
- 1
-#endif /* UNPREFIXZERO */
- ; i < 32; i++)
- ctlp[i] = val;
- for (i = 127; i < 160; i++) ctlp[i] = val;
- ctlp[(unsigned)255] = val;
- if (z == PX_NON) { /* These are never safe */
- if (network) { /* Assume network = telnet or rlogin */
- ctlp[CR] = 1; /* Prefix CR because of NVT rules */
- ctlp[XON] = ctlp[XOFF] = 1; /* Because of Telnet server */
- ctlp[127] = ctlp[255] = 1; /* Telnet IAC */
- ctlp[mystch] = ctlp[mystch+128] = 1; /* Kermit packet start */
- } else {
- ctlp[CR] = ctlp[255] = ctlp[mystch] = ctlp[mystch+128] = 1;
- if (flow == FLO_XONX) /* Xon/Xoff forces prefixing */
- ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
- }
- }
- break;
-
- case PX_CAU: /* Cautious or Minimal */
-#ifdef COMMENT
- /* Don't let CLEAR-CHANNEL be dependent on Prefixing */
- clearrq = 0; /* Turn off clearchannel */
-#endif /* COMMENT */
- case PX_WIL: /* Minimal ("wild") */
- ctlp[0] = 1; /* Does not include 0 */
- for (i = 1; i < 32; i++)
- ctlp[i] = 0;
- for (i = 127; i < 160; i++)
- ctlp[i] = 0;
- ctlp[mystch] = ctlp[mystch+128] = 1; /* Kermit start of packet */
- if (seol != 13)
- ctlp[seol] = ctlp[seol+128] = 1; /* Kermit end */
- ctlp[13] = ctlp[141] = 1; /* In case of TELNET (NVT rules) */
- ctlp[(unsigned)255] = 1; /* Ditto */
-
- /* ^D, ^J, ^M, or ^U followed by tilde trigger Rlogin escape */
-
- ctlp[4] = ctlp[4+128] = 1; /* In case of RLOGIN */
- ctlp[10] = ctlp[10+128] = 1; /* In case of RLOGIN */
- ctlp[21] = ctlp[21+128] = 1; /* In case of RLOGIN */
-
- if (flow == FLO_XONX || /* Xon/Xoff forces prefixing these */
- prefixing == PX_CAU || /* So does CAUTIOUS */
- network) /* Networks too... */
- ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
- if (prefixing == PX_CAU) { /* Cautious - add some more */
-#ifdef UNPREFIXZERO
- ctlp[0] = 1;
-#endif /* UNPREFIXZERO */
- ctlp[3] = ctlp[16] = 1; /* ^C, DLE */
- ctlp[14] = ctlp[15] = 1; /* SO/SI */
- ctlp[24] = ctlp[25] = 1; /* VMS might need these */
- ctlp[26] = ctlp[26+128] = 1; /* UNIX suspend */
- ctlp[28] = ctlp[29] = ctlp[30] = 1; /* Assorted esc chars */
- ctlp[131] = ctlp[141] = ctlp[144] = 1; /* and 8-bit versions */
- ctlp[(unsigned)255] = ctlp[156] = ctlp[157] = ctlp[158] = 1;
- }
- break;
- }
-#endif /* CK_SPEED */
-}
-#endif /* NOXFER */
-
-VOID
-makever() { /* Make version string from pieces */
- int x, y;
- char * s;
-#ifndef OS2
-#ifndef MAC
- ck_s_xver = ck_s_ver; /* Fill in C-Kermit version number */
- ck_l_xver = ck_l_ver; /* for UNIX, VMS, etc. */
-#endif /* MAC */
-#endif /* OS2 */
- x = strlen(ck_s_name);
- y = strlen(ck_s_xver);
- if (y + x + 1 < CKVERLEN) {
- ckmakmsg(versio,CKVERLEN,ck_s_name," ",ck_s_xver,NULL);
- } else {
- ckstrncpy(versio,"C-Kermit",CKVERLEN);
- return;
- }
- x += y + 1;
-
- s = " OPEN SOURCE:"; /* C-Kermit 9.0 and later */
- y = strlen(s);
- if (CKVERLEN < x + y + 1)
- return;
- ckstrncat(versio,s,CKVERLEN);
-
- x += y + 1;
- if (*ck_s_who) {
- y = strlen(ck_s_who);
- if (CKVERLEN < x + y + 1)
- return;
- ckstrncat(versio,"-",CKVERLEN);
- ckstrncat(versio,ck_s_who,CKVERLEN);
- }
- x += y + 1;
- y = strlen(ck_s_test);
- if (y > 0 && y + x + 1 < CKVERLEN) {
- ckstrncat(versio," ",CKVERLEN);
- ckstrncat(versio,ck_s_test,CKVERLEN);
- x += y + 1;
- y = strlen(ck_s_tver);
- if (y > 0 && y + x + 1 < CKVERLEN) {
- ckstrncat(versio,".",CKVERLEN);
- ckstrncat(versio,ck_s_tver,CKVERLEN);
- x += y + 1;
- }
- }
- y = strlen(ck_s_date);
- if (y > 0 && y + x + 2 < CKVERLEN) {
- ckstrncat(versio,", ",CKVERLEN);
- ckstrncat(versio,ck_s_date,CKVERLEN);
- }
- vernum = ck_l_ver;
- xvernum = ck_l_xver;
- debug(F110,"Kermit version",versio,0);
-}
-
-union ck_short shortbytes; /* For determining byte order */
-int byteorder = 0; /* 0 = Big Endian; 1 = Little Endian */
-int bigendian = 1;
-/* NOTE: MUST BE 0 or 1 - nothing else */
-
-#ifndef NOSPL
-#define SCRIPTLEN 10240
-#endif /* NOSPL */
-
-#ifdef NETCONN
-#ifndef NOCMDL
-#ifndef NOURL
-VOID
-dourl() {
- int rc = 0;
- char * port = NULL;
- extern int ttnproto;
- extern struct urldata g_url;
-
-#ifdef COMMENT
- /* NOTE: debug() doesn't work yet - must use printf's */
- printf("URL: %s\n",g_url.sav ? g_url.sav : "(none)");
- printf("Type: %s\n",g_url.svc ? g_url.svc : "(none)");
- printf("User: %s\n",g_url.usr ? g_url.usr : "(none)");
- printf("Pass: %s\n",g_url.psw ? g_url.psw : "(none)");
- printf("Host: %s\n",g_url.hos ? g_url.hos : "(none)");
-/* printf("Port: %s\n",g_url.por ? g_url.por : "(none)"); */
- printf("Path: %s\n",g_url.pth ? g_url.pth : "(none)");
-#endif /* COMMENT */
-
- if (!ckstrcmp(g_url.svc,"iksd",-1,0) ||
- !ckstrcmp(g_url.svc,"kermit",-1,0)) {
- extern char pwbuf[];
- extern int pwflg;
-#ifdef OS2
- extern int pwcrypt;
-#endif /* OS2 */
-
- if (!g_url.hos) {
- printf("?Incomplete IKSD URL\n");
- doexit(BAD_EXIT,1);
- }
- if (!g_url.usr)
- makestr(&g_url.usr,"anonymous");
- if (!g_url.psw) {
- char * tmpbuf = NULL;
- if (!(tmpbuf = (char *)malloc(1024)))
- fatal("dourl: out of memory");
- if (!ckstrcmp(g_url.usr,"anonymous",-1,0)) {
- ckmakmsg(tmpbuf,1024,uidbuf,"@",myhost,NULL);
- makestr(&g_url.psw,tmpbuf);
- } else {
- readpass(" Password:",tmpbuf,1024);
- makestr(&g_url.psw,tmpbuf);
- }
- free(tmpbuf);
- }
- port = "kermit";
- ttnproto = NP_TELNET;
- nettype = NET_TCPB;
- mdmtyp = -nettype;
- local = -1;
- ckstrncpy(uidbuf,g_url.usr,UIDBUFLEN);
- if (g_url.psw) {
- ckstrncpy(pwbuf,g_url.psw,PWBUFL);
- pwflg = 1;
-#ifdef OS2
- pwcrypt = 0;
-#endif /* OS2 */
- }
- ckmakmsg(ttname,
- TTNAMLEN,
- g_url.hos,
- ":",
- g_url.por ? g_url.por : port,
- NULL
- );
- rc = ttopen(ttname,&local,mdmtyp,0);
- if (rc > -1) {
- network = 1;
- exitonclose = 1;
-#ifdef CKLOGDIAL
- dolognet();
-#endif /* CKLOGDIAL */
- } else {
- printf("?Connection failed: %s\n",g_url.sav);
- doexit(BAD_EXIT,1);
- }
- /* Also need to check here for secure authentication already done */
-
-#ifdef NOSPL
- cflg = 1;
-#else
- {
- char * script = NULL;
- if (!(script = (char *)malloc(SCRIPTLEN)))
- fatal("dourl: out of memory");
- if (!g_url.pth) { /* Write the appropriate script */
- cflg = 1;
- ckmakxmsg(script,SCRIPTLEN,
- "if not eq {\\v(authstate)} {user} ",
- "if not eq {\\v(authstate)} {valid} { ",
- "remote login ", /* No path */
- g_url.usr, /* Just log in and CONNECT */
- " ",
- g_url.psw,
- ", if fail exit 1 {IKSD login failed} }",
- ", connect",
- NULL,NULL,NULL,NULL);
- /* printf("CLCMDS 1: %s\n",script); */
- } else {
- /* does the path specify a file or a directory? */
- int len = strlen(g_url.pth);
- if (ISDIRSEP(g_url.pth[len-1])) {
- ckmakxmsg(script,SCRIPTLEN, /* Directory name given */
- "if not eq {\\v(authstate)} {user} \
-if not eq {\\v(authstate)} {valid} { remote login ",
- g_url.usr,
- " ",
- g_url.psw,
- ", if fail exit 1 {IKSD login failed} }",
- ", set macro error on",
- ", set xfer displ brief",
- ", set xfer bell off",
- ", remote cd ",
- g_url.pth,
- ", lineout directory",
- ", connect"
- );
- /* printf("CLCMDS 2: %s\n",script); */
- } else {
- ckmakxmsg(script,SCRIPTLEN, /* Path given, try to GET */
- "if not eq {\\v(authstate)} {user} \
-if not eq {\\v(authstate)} {valid} { remote login ",
- g_url.usr,
- " ",
- g_url.psw,
- ", if fail exit 1 {IKSD login failed} }",
- ", set xfer displ brief",
- ", set xfer bell off",
- ", get ",
- g_url.pth,
- ", .rc := \\v(status)",
- ", if open connection bye",
- ", exit \\m(rc)"
- );
- /* printf("CLCMDS 2: %s\n",script); */
- }
- }
- clcmds = script; /* Make this our -C cmdline macro */
- /* printf("HAVEURL=%d\n",haveurl); */
- }
-#endif /* NOSPL */
- } else {
- if (ckstrcmp(g_url.svc,"telnet",-1,0) &&
-#ifdef SSHBUILTIN
- ckstrcmp(g_url.svc,"ssh",-1,0) &&
-#endif /* SSHBUILTIN */
- ckstrcmp(g_url.svc,"ftp",-1,0)) {
- printf("?Sorry, %s URLs not supported\n",
- g_url.svc ? g_url.svc : "");
- doexit(BAD_EXIT,1);
- }
- }
-}
-#endif /* NOCMDL */
-#endif /* NETCONN */
-#endif /* NOURL */
-
-/*
- main()...
-
- If you get complaints about "main: return type is not blah",
- define MAINTYPE on the CC command line, e.g. "CFLAGS=-DMAINTYPE=blah"
- (where "blah" is int, long, or whatever).
-
- If the complaint is "Attempt to return a value from a function of type void"
- then add -DMAINISVOID.
-*/
-#ifndef MAINTYPE
-#ifndef MAINISVOID
-#define MAINTYPE int
-#endif /* MAINISVOID */
-#endif /* MAINTYPE */
-
-#ifdef MAINISVOID
-#ifndef MAINTYPE
-#define MAINTYPE void
-#endif /* MAINTYPE */
-#endif /* MAINISVOID */
-
-#ifdef aegis
-/* On the Apollo, intercept main to insert a cleanup handler */
-int
-ckcmai(argc,argv) int argc; char **argv;
-#else
-#ifdef MAC /* Macintosh */
-int
-main (void)
-#else
-#ifdef __GNUC__ /* GCC compiler */
-int
-main(argc,argv) int argc; char **argv;
-#else
-#ifdef __DECC /* DEC Alpha with DEC C compiler */
-#ifdef __ALPHA
-int
-main(argc,argv) int argc; char **argv;
-#else /* DEC C compiler, not Alpha */
-#define MAINISVOID
-VOID
-main(argc,argv) int argc; char **argv;
-#endif /* __ALPHA */
-#else
-#ifdef STRATUS /* Stratus VOS */
-int
-main(argc,argv) int argc; char **argv;
-#else /* K-95 */
-#ifdef OS2
-#ifdef KUI
-#define MAINISVOID
-void
-Main( int argc, char ** argv )
-#else /* KUI */
-#define MAINISVOID
-VOID
-main(argc,argv) int argc; char **argv;
-#endif /* KUI */
-#else /* Not K95 */
-MAINTYPE /* All others... */
-main(argc,argv) int argc; char **argv;
-#endif /* OS2 */
-#endif /* STRATUS */
-#endif /* __DECC */
-#endif /* __GNUC__ */
-#endif /* MAC */
-#endif /* aegis */
-
-/* main */ {
-
- char *p;
-
-#ifndef NOSETKEY
- int i;
-#endif /* NOSETKEY */
-
-#ifdef datageneral
- short *pfha = 016000000036; /* Get around LANG_RT problem */
- *pfha = (short) 0; /* No user protection fault handler */
-#endif /* datageneral */
-
- int unbuf = 0; /* nonzero for unbuffered stdout */
-
-/* setbuf has to be called on the file descriptor before it is used */
-
-#ifdef UNIX
-#ifdef NONOSETBUF /* Unbuffered console i/o */
- unbuf++; /* as a compile-time option */
-#endif /* NONOSETBUF */
- if (!unbuf) { /* Or as a command-line selection */
- int i, n; /* We have to pre-pre-scan for */
- char * s; /* this one. */
- for (i = 1; i < argc; i++) {
- s = argv[i];
- if (!s) n = 0; else n = (int)strlen(s);
- if (n > 4) {
- if (!ckstrcmp("--unbuffered",s,n,0)) {
- unbuf++;
- break;
- }
- }
- }
- }
- if (unbuf)
- setbuf(stdout,NULL);
-#endif /* UNIX */
-
-/* Do some initialization */
-
-#ifdef VMS
-#ifdef __DECC
- /* Get some RMS default settings. */
- get_rms_defaults();
-#endif /* def __DECC */
-#endif /* def VMS */
-
-#ifndef MAC
- xargc = xargs = argc; /* Make global copies of argc */
- xargv = argv; /* ...and argv. */
- xarg0 = argv[0];
-#ifdef NT
- setOSVer();
-#endif /* NT */
- zstrip(argv[0],&p); /* Get name we were invoked with */
- makestr(&myname,p);
- if (!ckstrcmp(myname,"telnet",-1,0)) howcalled = I_AM_TELNET;
-#ifdef CK_KERBEROS
- else if (!ckstrcmp(myname,"ktelnet",-1,0)) howcalled = I_AM_TELNET;
-#endif /* CK_KERBEROS */
- else if (!ckstrcmp(myname,"rlogin",-1,0)) howcalled = I_AM_RLOGIN;
- else if (!ckstrcmp(myname,"iksd",-1,0)) howcalled = I_AM_IKSD;
-#ifdef NEWFTP
- else if (!ckstrcmp(myname,"ftp",-1,0)) howcalled = I_AM_FTP;
-#endif /* NEWFTP */
-#ifndef NOHTTP
- else if (!ckstrcmp(myname,"http",-1,0)) howcalled = I_AM_HTTP;
-#endif /* NOHTTP */
-#ifdef OS2
- else if (!ckstrcmp(myname,"telnet.exe",-1,0)) howcalled = I_AM_TELNET;
-#ifdef SSHBUILTIN
- else if (!ckstrcmp(myname,"ssh",-1,0)) howcalled = I_AM_SSH;
- else if (!ckstrcmp(myname,"ssh.exe",-1,0)) howcalled = I_AM_SSH;
-#endif /* SSHBUILTIN */
-#ifdef CK_KERBEROS
- else if (!ckstrcmp(myname,"ktelnet.exe",-1,0)) howcalled = I_AM_TELNET;
-#endif /* CK_KERBEROS */
- else if (!ckstrcmp(myname,"rlogin.exe",-1,0)) howcalled = I_AM_RLOGIN;
-#ifdef NT
- else if (!ckstrcmp(myname,"iksdnt",-1,0)) howcalled = I_AM_IKSD;
- else if (!ckstrcmp(myname,"iksdnt.exe",-1,0)) howcalled = I_AM_IKSD;
-#endif /* NT */
-#ifdef NEWFTP
- else if (!ckstrcmp(myname,"ftp.exe",-1,0)) howcalled = I_AM_FTP;
-#endif /* NEWFTP */
-#ifndef NOHTTP
- else if (!ckstrcmp(myname,"http.exe",-1,0)) howcalled = I_AM_HTTP;
-#endif /* NOHTTP */
-#endif /* OS2 */
- else if (!ckstrcmp(myname,"kermit-sshsub",-1,0)) howcalled = I_AM_SSHSUB;
-
-#ifndef NOICP
- cmdini(); /* Must come before prescan */
- debug(F100,"main cmdini() done","",0);
-#endif /* NOICP */
- prescan(0); /* Pre-Check for debugging, etc */
-#endif /* MAC */
- debug(F101,"MAIN feol","",feol);
- makever(); /* Put together version strings */
-#ifndef NOSETKEY /* Allocate & initialize the keymap */
- /* This code has been moved to before sysinit() for K95G */
- if (!(keymap = (KEY *) malloc(sizeof(KEY)*KMSIZE)))
- fatal("main: no memory for keymap");
- if (!(macrotab = (MACRO *) malloc(sizeof(MACRO)*KMSIZE)))
- fatal("main: no memory for macrotab");
- for (i = 0; i < KMSIZE; i++) {
- keymap[i] = (KEY) i;
- macrotab[i] = NULL;
- }
-#endif /* NOSETKEY */
-
- shortbytes.x_short = 0xABCD; /* Get Endianness */
- if (shortbytes.x_char[0] == 0xCD) { /* 0 = Big Endian */
- byteorder = 1; /* 1 = Little Endian */
- bigendian = 0; /* (for clarity in programming) */
- } else {
- byteorder = 0; /* Big Endian */
- bigendian = 1;
- }
- if (sizeof(CK_OFF_T) == 8) /* Large files and ints? */
- havelfs = 1;
-
- if (sysinit() < 0) /* System-dependent initialization. */
- fatal("Can't initialize!");
- else
- initflg = 1; /* Remember we did. */
- debug(F111,"ckcmai myname",myname,howcalled);
-
-#ifdef UNIX
- getexedir(); /* Compute exedir variable */
-#endif /* UNIX */
-
-#ifdef CKSYSLOG
-#ifdef SYSLOGLEVEL
-/*
- If built with -DSYSLOGLEVEL on cc command line, this means we always
- do syslogging at the indicated level.
-*/
- zsyslog(); /* Open syslog */
-#else /* SYSLOGLEVEL */
-#ifdef IKSD
- if (inserver)
- zsyslog(); /* Open syslog */
-#endif /* IKSD */
-#endif /* SYSLOGLEVEL */
-#endif /* CKSYSLOG */
-
-#ifdef CK_KERBEROS
- ini_kerb(); /* Initialize Kerberos data */
-#endif /* CK_KERBEROS */
-#ifdef CK_SSL
- ssl_once_init();
-#endif /* CK_SSL */
-#ifdef TNCODE
- tn_set_modes(); /* Init Telnet Option tables */
-#endif /* TNCODE */
-
-#ifdef CK_TTGWSIZ /* Initialize screen dimensions */
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
-#ifndef OS2
-#ifdef TCPSOCKET
-#ifdef CK_SOCKS
- SOCKSinit(argv[0]); /* Internet relay package... */
-#endif /* CK_SOCKS */
-#endif /* TCPSOCKET */
-#endif /* OS2 */
-
- initflow(); /* Initialize flow-control table */
-
-#ifndef NOICP
-#ifdef CKFLOAT
- initfloat(); /* Deduce floating-point precision */
-#endif /* CKFLOAT */
-#endif /* NOICP */
-
-#ifndef NOXFER
- initxlist(); /* Init exception lists */
-
-#ifdef CK_XYZ /* Initialize protocols... */
-
-#ifdef XYZ_INTERNAL /* XYZMODEM are internal ... */
-
-#ifdef COMMENT
- /* Can't do this for XMODEM because if filename contains a "C" etc... */
- initproto(PROTO_X, "rx %s","rx %s", NULL, NULL, NULL, NULL, NULL);
- initproto(PROTO_XC,"rc %s","rc %s", NULL, NULL, NULL, NULL, NULL);
-#else /* COMMENT */
- initproto(PROTO_X, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- initproto(PROTO_XC,NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-#endif /* COMMENT */
- initproto(PROTO_Y, "rb","rb", NULL, NULL, NULL, NULL, NULL);
- initproto(PROTO_G, "rb","rb", NULL, NULL, NULL, NULL, NULL);
- initproto(PROTO_Z, "rz","rz", NULL, NULL, NULL, NULL, NULL);
- initproto(PROTO_K,"kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL);
- /* Kermit Must be last */
-
-#else /* XYZMODEM are external protocols ... */
-
- /* s1 s2 s3 s4 s5 s6 s7 */
- initproto(PROTO_X, "rx %s","rx %s",NULL,"sx %s","sx -a %s","rx %s", "rx %s");
- initproto(PROTO_XC,"rc %s","rc %s",NULL,"sx %s","sx -a %s","rc %s", "rc %s");
- initproto(PROTO_Y, "rb", "rb", NULL,"sb %s","sb -a %s","rb", "rb" );
- initproto(PROTO_G, "rb", "rb", NULL,"sb %s","sb -a %s","rb", "rb" );
- initproto(PROTO_Z, "rz", "rz", NULL,"sz %s","sz -a %s","rz", "rz" );
- initproto(PROTO_K, "kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL);
- /* Kermit must be last */
-
-#endif /* XYZ_INTERNAL */
-
-#else /* No XYZMODEM support */
-
- initproto(PROTO_K,"kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL);
-
-#endif /* CK_XYZ */
-#endif /* NOXFER */
-
- connoi(); /* Console interrupts off */
-
-#ifndef NOXFER
-#ifdef OS2
- /* Initialize Kermit and Zmodem Auto-Download Strings */
- adl_kstr = strdup("KERMIT READY TO SEND...");
- adl_zstr = strdup("rz\r");
-#endif /* OS2 */
-
-#ifdef PATTERNS
- initpat(); /* Initialize filename patterns */
-#endif /* PATTERNS */
-#endif /* NOXFER */
-
-#ifndef NOCSETS
- initcsets(); /* Initialize character sets */
-#endif /* NOCSETS */
-
-#ifndef NOICP
-#ifdef DFCDMSG
- makestr(&cdmsgstr,DFCDMSG);
- makelist(cdmsgstr,cdmsgfile,8); /* Initialize CD message filenames */
-#endif /* DFCDMSG */
-#endif /* NOICP */
-
- sstate = 0; /* No default start state. */
-#ifdef DYNAMIC
- if (getiobs() < 0)
- fatal("Can't allocate i/o buffers!");
-#endif /* DYNAMIC */
-
-#ifndef NOSPL
-#ifndef NORANDOM
- {
- char stackdata[256];
- unsigned int c = 1234, n;
- /* try to make a random unsigned int to feed srand() */
-#ifndef VMS
- /* time.h and MultiNet do not get along */
- c = time(NULL);
-#endif /* VMS */
- c *= getpid();
- /* Referenced before set... DELIBERATELY */
- for (n = 0; n < sizeof(stackdata); n++) /* IGNORE WARNING */
- c += stackdata[n]; /* DELIBERATELY USED BEFORE SET */
- srand((unsigned int)c);
- }
-#endif /* NORANDOM */
-#endif /* NOSPL */
-
- ckhost(myhost,MYHOSTL); /* Name of local host */
- debug(F110,"main ckhost",myhost,0);
-#ifdef IKSD
- if (!inserver) {
-#endif /* IKSD */
- ckstrncpy(ttname,dftty,TTNAMLEN); /* Set up default tty name. */
- local = nolocal ? 0 : dfloc; /* And whether it's local or remote. */
- parity = dfprty; /* Set initial parity, */
-#ifndef NOXFER
- myindex = getsysix(cksysid); /* System index */
-#endif /* NOXFER */
- if (local) if (ttopen(ttname,&local,0,0) < 0) {
-#ifndef OS2
- conol("Can't open device: ");
- conoll(ttname);
-#endif /* OS2 */
- local = 0;
- ckstrncpy(ttname,CTTNAM,TTNAMLEN);
- }
- setflow(); /* Set appropriate flow control */
- speed = ttgspd(); /* Get transmission speed. */
-#ifdef IKSD
- }
-#endif /* IKSD */
-
-#ifdef ANYX25 /* All X.25 implementations */
-#ifndef IBMX25 /* except IBM have PAD support */
- initpad(); /* Initialize X.25 PAD */
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifndef NOXFER
- if (inibufs(SBSIZ,RBSIZ) < 0) /* Allocate packet buffers */
- fatal("Can't allocate packet buffers!");
-#ifndef NOCKSPEED
- setprefix(prefixing); /* Set up control char prefixing */
-#endif /* NOCKSPEED */
-#endif /* NOXFER */
-
-#ifndef NOICP
- if (sstelnet
-#ifdef IKSD
- || inserver
-#endif /* IKSD */
- ) {
- int on = 1, x = 0;
- extern int ckxech, ttnet, ttnproto, cmdmsk;
-#ifdef SO_SNDBUF
- extern int tcp_sendbuf;
-#endif
-#ifdef SO_RCVBUF
- extern int tcp_recvbuf;
-#endif
-#ifdef SO_KEEPALIVE
- extern int tcp_keepalive;
-#endif
-#ifdef SO_LINGER
- extern int tcp_linger, tcp_linger_tmo;
-#endif /* SO_LINGER */
-#ifdef SO_DONTROUTE
- extern int tcp_dontroute;
-#endif /* SO_DONTROUTE */
-#ifdef TCP_NODELAY
- extern int tcp_nodelay;
-#endif /* TCP_NODELAY */
-#ifdef IKSD
- extern int iklogopen;
-#endif /* IKSD */
- extern int ttmdm;
-
-#ifdef UNIX
- if (isatty(0))
- fatal("Internet Kermit Service cannot be started at a terminal.");
-#endif /* UNIX */
-
- reliable = xreliable = SET_ON; /* IKSD has reliable connection */
-#ifndef VMS
- flow = 0; /* No flow control needed */
-#endif /* VMS */
- bgset = 0; /* Not in background */
- nopush = 1; /* No external processes */
- parity = 0; /* 8 bits ... */
- cmdmsk = 0xff; /* all the way */
- cmask = 0xff;
-
-#ifdef IKSD
- if (inserver) { /* If IKSD */
- doiksdinit(); /* Execute IKSD configuration file */
- while (tlevel > -1)
- parser(1); /* (Ignore any file-xfer commands) */
- iksdcf = 1; /* IKSD c.f. has been processed */
- }
- if (!iklogopen) (VOID) doiklog(); /* Open Kermit-specific log */
-#endif /* IKSD */
-
-#ifdef UNIX
- setbuf(stdout,NULL); /* Don't buffer the output */
- ckstrncpy(ttname,"0",TTNAMLEN); /* not "/dev/tty"... */
-#endif /* UNIX */
- local = 0; /* We are in remote mode */
- ckxech = 1; /* We will echo */
-#ifdef OS2
- nettype = NET_TCPB; /* So ttopen() treats the connection */
- mdmtyp = -nettype; /* as a network */
-#endif /* OS2 */
- debug(F100,"main about to call ttopen() inserver","",0);
- if (ttopen(ttname,&local,mdmtyp,0) < 0) { /* Open comm channel */
- fatal("can't initialize i/o");
- }
-#ifdef OS2
- local = 0;
- network = 1; /* Does use networking code */
-#else /* OS2 */
- network = 0; /* Does not use networking code */
-#endif /* OS2 */
- ttmdm = -1; /* Does not use a modem */
- sstelnet = 1; /* Do server-side Telnet negotations */
- debug(F111,"MAIN","sstelnet",sstelnet);
- ttnet = NET_TCPB; /* Network type is TCP sockets */
- ttnproto = NP_TELNET; /* Netword protocol is Telnet */
-#ifdef IKSDB
- dbinit(); /* Initialize database record */
-#endif /* IKSDB */
-#ifndef OS2
-#ifdef CK_AUTHENTICATION
- /* Before initializating Telnet/Rlogin negotiations, init Kerberos */
- ck_auth_init(ckgetpeer(),"","",0);
-#endif /* CK_AUTHENTICATION */
-
-#ifdef NON_BLOCK_IO
- on = 1;
- x = socket_ioctl(0,FIONBIO,&on);
- debug(F101,"main FIONBIO","",x);
-#endif /* NON_BLOCK_IO */
-#ifdef SO_OOBINLINE
- on = 1;
- x = setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on));
- debug(F101,"main SO_OOBINLINE","",x);
-#endif /* SO_OOBINLINE */
-
-#ifndef NOTCPOPTS
-#ifndef datageneral
-#ifdef SOL_SOCKET
-#ifdef TCP_NODELAY
- no_delay(0,tcp_nodelay);
-#endif /* TCP_NODELAY */
-#ifdef SO_KEEPALIVE
- keepalive(0,tcp_keepalive);
-#endif /* SO_KEEPALIVE */
-#ifdef SO_LINGER
- ck_linger(0,tcp_linger, tcp_linger_tmo);
-#endif /* SO_LINGER */
-#ifdef SO_DONTROUTE
- dontroute(0,tcp_dontroute);
-#endif /* SO_DONTROUTE */
-#ifdef SO_SNDBUF
- sendbuf(0,tcp_sendbuf);
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
- recvbuf(0,tcp_recvbuf);
-#endif /* SO_RCVBUF */
-#endif /* SOL_SOCKET */
-#endif /* datageneral */
-#endif /* NOTCPOPTS */
-
-#ifdef CK_SSL
- if (ck_ssleay_is_installed()) {
- if (!ssl_tn_init(SSL_SERVER)) {
- if (bio_err != NULL) {
- BIO_printf(bio_err,"do_ssleay_init() failed\r\n");
- ERR_print_errors(bio_err);
- } else {
- fflush(stderr);
- fprintf(stderr,"do_ssleay_init() failed\r\n");
- ERR_print_errors_fp(stderr);
- }
- switch (ttnproto) {
- case NP_SSL:
- case NP_TLS:
- case NP_SSL_RAW:
- case NP_TLS_RAW:
- case NP_SSL_TELNET:
- case NP_TLS_TELNET:
- doexit(BAD_EXIT,1);
- }
- /* otherwise we will continue to accept the connection */
- /* without SSL or TLS support unless required. */
- if ( TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- } else {
- if ( ck_ssl_incoming(0) < 0 ) {
- doexit(BAD_EXIT,1);
- }
- }
- }
-#endif /* CK_SSL */
-
-#ifdef TNCODE
- tn_ini(); /* Start Telnet negotiation now */
-#endif /* TNCODE */
-#endif /* OS2 */
- }
- debug(F101,"main argc after prescan()","",argc);
-
- /* Now process any relevant environment variables */
-
-#ifndef NODIAL
- getdialenv(); /* Dialing */
-#ifdef NETCONN
- ndinit(); /* Initialize network directory info */
- getnetenv(); /* Network directories */
-#endif /* NETCONN */
-#endif /* NODIAL */
-
-#ifndef NOXFER
-#ifdef CK_FAST
- dofast(); /* By now FAST defaults should be OK */
-#endif /* CK_FAST */
-#endif /* NOXFER */
-
-#ifndef NOCMDL
- ikslogin(); /* IKSD Login and other stuff */
-#ifdef IKSD
-#ifdef NT
- if ( inserver )
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* NOCMDL */
-
- if (howcalled == I_AM_SSHSUB) {
- reliable = 1; /* We say the connection is reliable */
- xreliable = 1; /* And that we said it was */
- setreliable = 1; /* And pretend the "user" did too */
- xfinish = 1; /* For REMOTE HELP response */
- mdmtyp = 0; /* For ttopen() */
- ckstrncpy(ttname,"0",TTNAMLEN+1); /* Use file descriptor 0 */
- local = 0; /* And force remote mode */
- ttopen(ttname,&local,mdmtyp,0); /* Open the "connection" */
- sstate = 'x'; /* Initial state is Server */
- proto(); /* Enter protocol */
- doexit(GOOD_EXIT,xitsta); /* Exit when done */
- }
- debug(F111,"howcalled",myname,howcalled);
-
-#ifdef NOCCTRAP
- dotakeini(0);
-#else /* NOCCTRAP */
- debug(F100,"main about to cc_execute","",0);
- setint();
- cc_execute( ckjaddr(cmjbuf), dotakeini, failtakeini );
-#endif /* NOCCTRAP */
-
- debug(F111,"main 2 cfilef",cmdfil,cfilef);
- if (cmdfil[0]) { /* If we got one (see prescan())... */
-#ifdef NOCCTRAP
- docmdfile(0); /* execute it. */
-#else /* NOCCTRAP */
- setint();
- cc_execute( ckjaddr(cmjbuf), docmdfile, failcmdfile );
-#endif /* NOCCTRAP */
- }
-#ifndef OS2 /* Preserve name so we can delete it */
- *cmdfil = '\0'; /* Done, nullify the file name */
-#endif /* OS2 */
-#endif /* NOICP */
-
-#ifndef NOCMDL
-/* Look for a UNIX-style command line... */
-
- what = W_NOTHING;
-
- debug(F101,"main argc","",argc);
-#ifndef NOHELP
- iniopthlp(); /* Initialize cmdline arg help */
-#endif /* NOHELP */
- if (
-#ifdef COMMENT
- !cfilef &&
-#endif /* COMMENT */
- argc > 1) { /* Command line arguments? */
- sstate = (CHAR) cmdlin(); /* Yes, parse. */
-#ifdef NETCONN
-#ifndef NOURL
- if (haveurl) { /* Was a URL given? */
- dourl(); /* if so, do it. */
- }
-#endif /* NOURL */
-#endif /* NETCONN */
-#ifndef NOXFER
- zstate = sstate; /* Remember sstate around protocol */
- debug(F101,"main zstate","",zstate);
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
- if (cflg) { /* Connect first if requested */
- doconect(0,0);
- if (ttchk() < 0)
- dologend();
- cflg = 0;
- }
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
- if (sstate) {
-#ifndef NOLOCAL
- if (displa) concb((char)escape); /* (for console "interrupts") */
-#endif /* NOLOCAL */
-#ifdef NOCCTRAP
- docmdline(1);
-#else /* NOCCTRAP */
- setint();
- cc_execute( ckjaddr(cmjbuf), docmdline, failcmdline );
-#endif /* NOCCTRAP */
- }
-#endif /* NOXFER */
-
-#ifndef NOICP
-/*
- If a command-line action argument was given and -S ("stay") was not given,
- exit now.
-*/
- if ((cflg || cnflg || zstate) && !stayflg)
-#endif /* NOICP */
- doexit(GOOD_EXIT,xitsta); /* Exit with good status */
-
-#ifndef NOLOCAL
-#ifndef NOICP
- if (local) {
-#ifdef NETCONN
- if ((cflg || cnflg) && tn_exit && ttchk() < 0)
- doexit(GOOD_EXIT,xitsta); /* Exit with good status */
-#endif /* NETCONN */
- if (exitonclose && !network &&
- (carrier != CAR_OFF && (ttgmdm() & BM_DCD) == 0))
- doexit(GOOD_EXIT,xitsta); /* Exit with good status */
- if (exitonclose && network && ttchk() < 0)
- doexit(GOOD_EXIT,xitsta); /* Exit with good status */
- }
-#endif /* NOICP */
-#endif /* NOLOCAL */
- }
-#endif /* NOCMDL */
-
-#ifdef NOICP /* No interactive command parser */
-#ifndef NOCMDL
- else {
-
- /* Command-line-only version */
- fatal("?No command-line options given - type 'kermit -h' for help");
- }
-#else /* Neither one! */
- sstate = 'x';
- justone = 0;
- proto(); /* So go into server mode */
- doexit(GOOD_EXIT,xitsta); /* exit with good status */
-
-#endif /* NOCMDL */
-#else /* not NOICP */
-/*
- If no action requested on command line, or if -S ("stay") was included,
- enter the interactive command parser.
-*/
- if (!clcmds)
- herald(); /* Display program herald. */
-
-#ifdef NOCCTRAP
- debug(F100,"main NOCCTRAP setting interrupt trap","",0);
- setint(); /* Set up command interrupt traps */
- doicp(NULL);
-#else /* NOCCTRAP */
- while (1) {
- debug(F100,"main setting interrupt trap","",0);
- setint(); /* Set up command interrupt traps */
- if (!cc_execute(ckjaddr(cmjbuf), doicp, failicp))
- break;
- }
-#endif /* NOCCTRAP */
-#endif /* NOICP */
-#ifndef MAINISVOID
- return(1);
-#endif /* MAINISVOID */
-}
-
-#ifdef DYNAMIC
-/* Allocate file i/o buffers */
-
-char *zinbuffer = NULL, *zoutbuffer = NULL;
-
-int
-getiobs() {
- zinbuffer = (char *)malloc(INBUFSIZE);
- if (!zinbuffer) return(-1);
- zoutbuffer = (char *)malloc(zobufsize);
- debug(F101,"zoutbuffer malloc","",zobufsize);
- if (!zoutbuffer) return(-1);
- debug(F100,"getiobs ok","",0);
- return(0);
-}
-#endif /* DYNAMIC */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcmai.c.c99 b/ckermit-9.0.302-build/ckermit-9.0.302/ckcmai.c.c99
deleted file mode 100644
index a5640e5..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcmai.c.c99
+++ /dev/null
@@ -1,3576 +0,0 @@
-#define EDITDATE "20 Aug 2011" /* Last edit date dd mmm yyyy */
-#define EDITNDATE "20110820" /* Keep them in sync */
-/* Sat Aug 20 17:20:17 2011 */
-
-/* ckcmai.c - Main program for C-Kermit plus some miscellaneous functions */
-
-/*
- ckcsym.h is used for for defining symbols that normally would be defined
- using -D or -d on the cc command line, for use with compilers that don't
- support this feature. Must come before any tests for preprocessor symbols.
-*/
-#include "ckcsym.h"
-/*
- Consolidated program C-Kermit version information for all platforms
- (but for UNIX also see ckuver.h). See makever() below for how they are used.
-*/
-#ifdef COMMENT /* Uncomment this for real K95 version */
-#ifndef OS2 /* OS2 actually means Kermit 95. */
-#ifndef BETATEST /* It's because Kermit 95 started */
-#define BETATEST /* out as C-Kermit for OS/2. */
-#endif /* BETATEST */
-#endif /* OS2 */
-#endif /* COMMENT */
-
-#ifdef BETATEST
-#ifdef OS2
-#ifdef __DATE__
-#define BETADATE
-#endif /* __DATE__ */
-#endif /* OS2 */
-#endif /* BETATEST */
-
-char * ck_cryear = "2011"; /* C-Kermit copyright year */
-
-#ifndef MAC /* MAC = Kermit for MAC OS 6, 7, ... */
-/*
- Note: initialize ck_s_test to "" if this is not a test version.
- Use (*ck_s_test != '\0') to decide whether to print test-related messages.
-*/
-
-#ifndef BETATEST
-#ifndef OS2 /* UNIX, VMS, etc... (i.e. C-Kermit) */
-char *ck_s_test = ""; /* "Dev","Alpha","Beta","RC", or "" */
-char *ck_s_tver = ""; /* Test version number or "" */
-#else /* OS2 */
-char *ck_s_test = ""; /* (i.e. K95) */
-char *ck_s_tver = "";
-#endif /* OS2 */
-#else
-char *ck_s_test = ""; /* Development */
-char *ck_s_tver = "";
-#endif /* BETATEST */
-#else /* MAC */
-char *ck_s_test = "Pre-Alpha"; /* Mac Kermit is always a test... */
-char *ck_s_tver = ""; /* (pre Mac OS X 10, that is!) */
-#endif /* MAC */
-
-#ifdef BETADATE /* Date of this version or edit */
-char *ck_s_date = __DATE__; /* Compilation date */
-#else
-char *ck_s_date = EDITDATE; /* See top */
-
-#endif /* BETADATE */
-char *buildid = EDITNDATE; /* See top */
-
-#ifdef UNIX
-static char sccsid[] = "@(#)C-Kermit 9.0.302";
-#endif /* UNIX */
-
-/*
- The C-Kermit Version number is major.minor.edit (integers).
- Major version always goes up.
- Minor version is historical, hasn't been used since C-Kermit 7.1.
- Edit is sequential, always goes up, but there can be gaps.
- For example there might be many edits between releases.
- If the major goes to 10, some version-number-based feature tests
- could fail. It might be better to use the minor version field
- for future releases.
-*/
-
-char *ck_s_ver = "9.0.302"; /* C-Kermit version string */
-long ck_l_ver = 900302L; /* C-Kermit version number */
-
-#ifdef OS2
-char *ck_s_xver = "3.0.0"; /* Product-specific version string */
-long ck_l_xver = 3000L; /* Product-specific version number */
-#else
-#ifdef MAC
-char *ck_s_xver = "0.995"; /* Product-specific version string */
-long ck_l_xver = 995L; /* Product-specific version number */
-#else
-char *ck_s_xver = ""; /* Don't touch these... */
-long ck_l_xver = 0L; /* they are computed at runtime */
-#endif /* MAC */
-#endif /* OS2 */
-
-#ifdef OS2
-#ifdef IKSDONLY
-#ifdef NT
-char *ck_s_name = "IKS-NT";
-#else /* NT */
-char *ck_s_name = "IKS-OS/2";
-#endif /* NT */
-#else /* IKSDONLY */
-char *ck_s_name = "Kermit 95"; /* Program name */
-#endif /* IKSDONLY */
-#else
-#ifdef MAC
-char *ck_s_name = "Mac Kermit";
-#else
-char *ck_s_name = "C-Kermit";
-#endif /* MAC */
-#endif /* OS2 */
-
-char *ck_s_who = ""; /* Where customized, "" = not. */
-char *ck_patch = ""; /* Patch info, if any. */
-
-#define CKVERLEN 128
-char versiox[CKVERLEN]; /* Version string buffer */
-char *versio = versiox; /* These are filled in at */
-long vernum, xvernum; /* runtime from above. */
-
-#define CKCMAI
-
-#include "ckcasc.h" /* ASCII character symbols */
-#include "ckcdeb.h" /* Debug & other symbols */
-
-char * myname = NULL; /* The name I am called by */
-#ifndef OS2
-char * exedir = NULL; /* Directory I was executed from */
-#endif /* OS2 */
-char * myhome = NULL; /* Home directory override */
-
-/* C K C M A I -- C-Kermit Main program */
-
-/*
- Author: Frank da Cruz (fdc@columbia.edu),
- Columbia University in the city of New York,
- Computer Center / Center for Computing Activities / Information Technology.
- I am no longer at Columbia U as of 1 July 2011, but the email address
- should still work. The Kermit website http://kermit.columbia.edu should
- still be available and under my control, as well as the Kermit FTP site,
- ftp://kermit.columbia.edu/kermit/.
-
-COPYRIGHT NOTICE:
-*/
-
-char *copyright[] = {
-
-#ifdef pdp11
-"Copyright (C) 1985, %s, Trustees of Columbia University, NYC.",
-"All rights reserved.",
-" ",
-#else
-"Copyright (C) 1985, %s,",
-" The Trustees of Columbia University in the City of New York.",
-" All rights reserved.",
-" ",
-"Redistribution and use in source and binary forms, with or without",
-"modification, are permitted provided that the following conditions",
-"are met:",
-" ",
-" + Redistributions of source code must retain the above copyright",
-" notice, this list of conditions and the following disclaimer.",
-" ",
-" + Redistributions in binary form must reproduce the above copyright",
-" notice, this list of conditions and the following disclaimer in",
-" the documentation and/or other materials provided with the",
-" distribution.",
-" ",
-" + Neither the name of Columbia University nor the names of its",
-" contributors may be used to endorse or promote products derived",
-" from this software without specific prior written permission.",
-" ",
-"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS",
-"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT",
-"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR",
-"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT",
-"HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,",
-"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT",
-"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,",
-"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY",
-"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT",
-"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE",
-"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
-#endif /* pdp11 */
-
-#ifdef OS2
-"Portions Copyright (C) 2002-2005, Secure Endpoints Inc, New York NY USA.",
-"Portions Copyright (C) 1995, Oy Online Solutions Ltd., Jyvaskyla, Finland.",
-#endif /* OS2 */
-
-#ifdef CK_AUTHENTICATION
-"Portions Copyright (C) 1990, Massachusetts Institute of Technology.",
-#ifdef CK_ENCRYPTION
-"Portions Copyright (C) 1991, 1993 Regents of the University of California.",
-"Portions Copyright (C) 1991, 1992, 1993, 1994, 1995 by AT&T.",
-"Portions Copyright (C) 1995, 1997, Eric Young <eay@cryptosoft.com>.",
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SRP
-"Portions Copyright (C) 1997, Stanford University.",
-#endif /* CK_SRP */
-#endif /* CK_AUTHENTICATION */
-
-#ifndef pdp11
-" ",
-"For further information, visit the Kermit Project website:",
-"http://www.columbia.edu/kermit/ .",
-#endif /* pdp11 */
-""};
-
-/* Windows IKSD copyright used to be separate */
-char *wiksdcpr = (char *) copyright;
-
-
-/*
-DOCUMENTATION:
-
- "Using C-Kermit" by Frank da Cruz and Christine M. Gianone,
- Digital Press / Butterworth-Heinemann, Woburn MA, USA.
- Second edition (1997), ISBN 1-55558-164-1.
- Order from Digital Press: +1 (800) 366-2665
- Or from Columbia University: +1 (212) 854-3703
-
-For Kermit 95, also:
-
- "Kermit 95" by Christine M. Gianone and Frank da Cruz,
- Manning Publications, Greenwich CT, USA (1998) - Online.
-
-ACKNOWLEDGMENTS:
-
- The Kermit file transfer protocol was developed at the Columbia University
- Center for Computing Activities (CUCCA), which was since renamed to Columbia
- University Academic Information Systems (AcIS) and after that Columbia
- University Information Technology (CUIT). Kermit is named after Kermit the
- Frog, star of the television series THE MUPPET SHOW; the name is used by
- permission of Henson Associates, Inc.
-
- Thanks to at least the following people for their contributions to this
- program over the years, and apologies to anyone who was inadvertantly
- omitted:
-
- Chris Adie, Edinburgh U, Scotland (OS/2)
- Robert Adsett, University of Waterloo, Canada
- Larry Afrin, Clemson U
- Russ Allbery, Stanford U
- Jeffrey Altman, Columbia University
- Greg Andrews, Telebit Corp
- Barry Archer, U of Missouri
- Robert Andersson, International Systems A/S, Oslo, Norway
- Chris Armstrong, Brookhaven National Lab (OS/2)
- William Bader, Software Consulting Services, Nazareth, PA
- Fuat Baran, Columbia U
- Stan Barber, Rice U
- Jim Barbour, U of Colorado
- Donn Baumgartner, Dell
- Ian Beckwith, Debian Project
- Nelson Beebe, U of Utah
- Gerry Belanger, Cognitronics
- Karl Berry, UMB
- Mark Berryman, SAIC
- Dean W Bettinger, SUNY
- Gary Bilkus
- Peter Binderup, Denmark
- David Bolen, Advanced Networks and Services, Inc.
- Joop Bonen
- Marc Boucher, U of Montreal
- Charles Brooks, EDN
- Bob Brown
- Mike Brown, Purdue U
- Rob Brown
- Jack Bryans, California State U at Long Beach
- Mark Buda, DEC (VMS)
- Fernando Cabral, Padrao iX, Brasilia
- Bjorn Carlsson, Stockholm University Computer Centre QZ, Sweden
- Bill Catchings, (formerly of) Columbia U
- Bob Cattani, Columbia U CS Dept
- Davide Cervone, Rochester U
- Seth Chaiklin, Denmark
- John Chandler, Harvard U / Smithsonian Astronomical Observatory
- Bernard Chen, UCLA
- Andrew A Chernov, RELCOM Team, Moscow
- John L Chmielewski, AT&T, Lisle, IL
- Howard Chu, U of Michigan
- Bill Coalson, McDonnell Douglas
- Bertie Coopersmith, London
- Christian Corti
- Chet Creider, U of Western Ontario
- Alan Crosswell, Columbia U
- Jeff Damens, (formerly of) Columbia U
- Mark Davies, Bath U, UK
- Sin-itirou Dezawa, Fujifilm, Japan
- Joe R. Doupnik, Utah State U
- Frank Dreano, Honeywell
- John Dunlap, U of Washington
- Alex Dupuy, SMART.COM
- David Dyck, John Fluke Mfg Co.
- Stefaan A. Eeckels, Eurokom, Luxembourg
- Nick Efthymiou
- Paul Eggert, Twin Sun, Inc., El Segundo, CA
- Bernie Eiben, DEC
- Peter Eichhorn, Assyst International
- Kristoffer Eriksson, Peridot Konsult AB, Oerebro, Sweden
- John R. Evans, IRS, Kansas City
- Glenn Everhart, RCA Labs
- Charlie Finan, Cray Research
- Herm Fischer, Encino, CA (extensive contributions to version 4.0)
- Carl Fongheiser, CWRU
- Mike Freeman, Bonneville Power Authority
- Carl Friedberg
- Marcello Frutig, Catholic University, Sao Paulo, Brazil (X.25 support)
- Hirofumi Fujii, Japan Nat'l Lab for High Energy Physics, Tokyo (Kanji)
- Chuck Fuller, Westinghouse Corporate Computer Services
- Andy Fyfe, Caltech
- Christine M. Gianone, Columbia U
- John Gilmore, UC Berkeley
- Madhusudan Giyyarpuram, HP
- Rainer Glaschick, Siemens AG, Paderborn
- William H. Glass
- German Goldszmidt, IBM
- Chuck Goodhart, NASA
- Alistair Gorman, New Zealand
- Richard Gration, ADFA, Australia
- Chris Green, Essex U, UK
- Alan Grieg, Dundee Tech, Scotland
- Yekta Gursel, MIT
- Jim Guyton, Rand Corp
- Michael Haertel
- Bruno Haible
- Bob Hain, UMN
- Marion Hakanson, ORST
- Richard Hamilton
- John Hamilston, Iowa State U
- Simon Hania, Netherlands
- Stan Hanks, Rice U.
- Ken Harrenstein, SRI
- Eugenia Harris, Data General (AOS/VS)
- David Harrison, Kingston Warren Corp
- Lucas Hart, Oregon State University
- James Harvey, Indiana/Purdue U (VMS)
- Rob Healey
- Chuck Hedrick, Rutgers U
- Ron Heiby, Technical Systems Division, Motorola Computer Group
- Steve Hemminger, Tektronix
- Christian Hemsing, RWTH Aachen, Germany (OS-9)
- Randolph Herber, US DOE,
- Andrew Herbert, Monash Univ, Australia
- Marcus Herbert, Germany
- Mike Hickey, ITI
- Dan Hildebrand, QNX Software Systems Inc, Kanata, ON (QNX)
- R E Hill
- Stephan Hoffman-Emden
- Sven Holmstrom, ABB Utilities AB, Sweden
- Bill Homer, Cray Research
- Ray Hunter, The Wollongong Group
- Randy Huntziger, National Library of Medicine
- Larry Jacobs, Transarc
- Steve Jenkins, Lancaster University, UK
- Dave Johnson, Gradient Technologies
- Mark B Johnson, Apple Computer
- Jyke Jokinen, Tampere University of Technology, Finland (QNX)
- Eric F Jones, AT&T
- Luke Jones, AT&T
- Peter Jones, U of Quebec Montreal
- Phil Julian, SAS Institute
- Peter Kabal, U of Quebec
- Mic Kaczmarczik, U of Texas at Austin
- Sergey Kartashoff, Inst. of Precise Mechanics & Computer Equipment, Moscow
- Howie Kaye, Columbia U
- Rob Kedoin, Linotype Co, Hauppauge, NY (OS/2)
- Phil Keegstra
- Mark Kennedy, IBM
- Terry Kennedy, St Peter's College, Jersey City, NJ (VMS and more)
- "Carlo Kid", Technical University of Delft, Netherlands
- Tim Kientzle
- Paul Kimoto, Cornell U
- Douglas Kingston, morgan.com
- Lawrence Kirby, Wiltshire, UK
- Tom Kloos, Sequent Computer Systems
- Guenter Knauf
- Jim Knutson, U of Texas at Austin
- John T. Kohl (BSDI)
- Scott Kramer, SRI International, Menlo Park, CA
- John Kraynack, US Postal Service
- David Kricker, Encore Computer
- Thomas Krueger, UWM
- Bo Kullmar, ABC Klubben, Stockholm, and Central Bank of Sweden, Kista
- R. Brad Kummer, AT&T Bell Labs, Atlanta, GA
- John Kunze, UC Berkeley
- David Lane, BSSI / BellSouth (Stratus VOS, X.25)
- Bob Larson, USC (OS-9)
- Bert Laverman, Groningen U, Netherlands
- Steve Layton
- David Lawyer, UC Irvine
- Jason Lehr
- David LeVine, National Semiconductor Corporation
- Daniel S. Lewart, UIUC
- S.O. Lidie, Lehigh U
- Tor Lillqvist, Helsinki U, Finland
- David-Michael Lincke, U of St Gallen, Switzerland
- Robert Lipe (for SCO makefile entries & advice)
- Dean Long
- Mike Long, Analog Devices, Norwood MA
- Kevin Lowey, U of Saskatchewan (OS/2)
- Andy Lowry, Columbia U
- James Lummel, Caprica Telecomputing Resources (QNX)
- Lewis McCarthy
- David MacKenzie, Environmental Defense Fund, U of Maryland
- John Mackin, University of Sidney, Australia
- Martin Maclaren, Bath U, UK
- Chris Maio, Columbia U CS Dept
- Montserrat Mane, HP, Grenoble, France
- Fulvio Marino, Olivetti, Ivrea, Italy
- Arthur Marsh, dircsa.org.au
- Peter Mauzey, Lucent Technologies
- Tye McQueen, Utah State U
- Ted Medin
- Hellmuth Michaelis, Hanseatischer Computerservice GmbH, Hamburg, Germany
- Leslie Mikesell, American Farm Bureau
- Todd Miller, Courtesan Consulting
- Gary Mills
- Martin Minow, DEC (VMS)
- Pawan Misra, Bellcore
- Ken Mizialko, IBM, Manassas, VA
- Wolfgang Moeller, DECUS Germany
- Ray Moody, Purdue U
- Bruce J Moore, Allen-Bradley Co, Highland Heights, OH (Atari ST)
- Steve Morley, Convex
- Peter Mossel, Columbia U
- Tony Movshon, NYU
- Lou Muccioli, Swanson Analysis Systems
- Dan Murphy
- Neal P. Murphy, Harsof Systems, Wonder Lake IL
- Gary Mussar
- John Nall, FSU
- Jack Nelson, U of Pittsburgh
- Jim Noble, Planning Research Corporation (Macintosh)
- Ian O'Brien, Bath U, UK
- Melissa O'Neill, SFU
- John Owens
- Thomas Pinkl, Health Business Systems Inc.
- Michael Pins, Iowa Computer Aided Engineering Network
- Andre' Pirard, University of Liege, Belgium
- Paul Placeway, Ohio State U
- Piet W. Plomp, ICCE, Groningen University, Netherlands
- Ken Poulton, HP Labs
- Manfred Prange, Oakland U
- Christopher Pratt, APV Baker, UK
- Frank Prindle, NADC
- Tony Querubin, U of Hawaii
- Jean-Pierre Radley
- Anton Rang
- Mike Rechtman
- Scott Ribe
- Alan Robiette, Oxford University, UK
- Michel Robitaille, U of Montreal (Mac)
- Huw Rogers, Schweizerische Kreditanstalt, Zuerich
- Nigel Roles, Cambridge, England
- Kai Uwe Rommel, Technische Universitaet Muenchen (OS/2)
- Larry Rosenman (Amiga)
- Jay Rouman, U of Michigan
- Jack Rouse, SAS Institute (Data General and/or Apollo)
- Stew Rubenstein, Harvard U (VMS)
- Gerhard Rueckle, FH Darmstadt, Fb. E/Automatisierungstechnik
- John Santos, EG&H
- Bill Schilit, Columbia U
- Ulli Schlueter, RWTH Aachen, Germany (OS-9, etc)
- Michael Schmidt, U of Paderborn, Germany
- Eric Schnoebelen, Convex
- Benn Schreiber, DEC
- Dan Schullman, DEC (modems, DIAL command, etc)
- John Schultz, 3M
- Steven Schultz, Contel (PDP-11)
- Steven Schweda
- APPP Scorer, Leeds Polytechnic, UK
- Gordon Scott, Micro Focus, Newbury UK
- Gisbert W. Selke, WIdO, Bonn, Germany
- Kijal Shah
- David Singer, IBM Almaden Research Labs
- David Sizeland, U of London Medical School
- Fridrik Skulason, Iceland
- Rick Sladkey (Linux)
- Dave Slate
- Bradley Smith, UCLA
- Fred Smith, Merk / Computrition
- Richard S Smith, Cal State
- Ryan Stanisfer, UNT
- Bertil Stenstroem, Stockholm University Computer Centre (QZ), Sweden
- James Sturdevant, CAP GEMENI AMERICA, Minneapolis
- Peter Svanberg, Royal Techn. HS, Sweden
- James R. Swenson, Accu-Weather, Inc.
- Ted T'so, MIT (Linux)
- Andy Tanenbaum, Vrije U, Amsterdam, Netherlands
- Seth Theriault, Columbia U
- Glen Thobe
- Markku Toijala, Helsinki U of Technology
- Teemu Torma, Helsinki U of Technology
- Linus Torvalds, Helsinki
- Rick Troxel, NIH
- Warren Tucker, Tridom Corp, Mountain Park, GA
- Dave Tweten, AMES-NAS
- G Uddeborg, Sweden
- Walter Underwood, Ford Aerospace
- Pieter Van Der Linden, Centre Mondial, Paris
- Ge van Geldorp, Netherlands
- Fred van Kempen, MINIX User Group, Voorhout, Netherlands
- Wayne Van Pelt, GE/CRD
- Mark Vasoll, Oklahoma State U (V7 UNIX)
- Konstantin Vinogradov, ICSTI, Moscow
- Paul Vixie, DEC
- Bernie Volz, Process Software
- Eduard Vopicka, Prague University of Economics, Czech Republic
- Martin Vorlaender
- Dimitri Vulis, CUNY
- Roger Wallace, Raytheon
- Stephen Walton, Calif State U, Northridge (Amiga)
- Jamie Watson, Adasoft, Switzerland (AIX)
- Rick Watson, U of Texas (Macintosh)
- Eric Weaver, Columbia U
- Scott Weikart (Association for Progressive Communications)
- Robert Weiner, Programming Plus, New York City
- Lauren Weinstein, Vortex Technlogy
- David Wexelblat, AT&T
- Clark Wierda, Illuminati Online
- Joachim Wiesel, U of Karlsruhe
- Lon Willett, U of Utah
- Michael Williams, UCLA
- Nate Williams, U of Montana
- David Wilson
- Joellen Windsor, U of Arizona
- Patrick Wolfe, Kuck & Associates, Inc.
- Gregg Wonderly, Oklahoma State U (V7 UNIX)
- Farrell Woods, Concurrent (formerly Masscomp)
- Dave Woolley, CAP Communication Systems, London
- Jack Woolley, SCT Corp
- Frank Wortner
- Ken Yap, formerly of U of Rochester
- John Zeeff, Ann Arbor, MI
-*/
-
-#include "ckcker.h" /* Kermit symbols */
-#include "ckcnet.h" /* Network symbols */
-
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-
-#ifndef NOSPL
-#include "ckuusr.h"
-#endif /* NOSPL */
-
-#ifdef OS2ONLY
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#endif /* OS2ONLY */
-
-#ifdef NT
-#include <windows.h>
-#include <tapi.h>
-#include "ckntap.h"
-#endif /* NT */
-
-#ifndef NOSERVER
-/* Text message definitions.. each should be 256 chars long, or less. */
-#ifdef MINIX
-char *srvtxt = "\r\n\
-Entering server mode.\r\n\0";
-#else
-#ifdef OLDMSG
-/*
- It seems there was a large installation that was using C-Kermit 5A(165)
- or thereabouts, which had deployed thousands of MS-DOS Kermit scripts in
- scattered locations that looked for strings in the old server message,
- which changed in 5A(183), August 1992.
-*/
-char *srvtxt = "\r\n\
-C-Kermit server starting. Return to your local machine by typing\r\n\
-its escape sequence for closing the connection, and issue further\r\n\
-commands from there. To shut down the C-Kermit server, issue the\r\n\
-FINISH or BYE command and then reconnect.\n\
-\r\n\0";
-#else
-#ifdef OSK
-char *srvtxt = "\r\012\
-Entering server mode. If your local Kermit software is menu driven, use\r\012\
-the menus to send commands to the server. Otherwise, enter the escape\r\012\
-sequence to return to your local Kermit prompt and issue commands from\r\012\
-there. Use SEND and GET for file transfer. Use REMOTE HELP for a list of\r\012\
-other available services. Use BYE or FINISH to end server mode.\r\012\0";
-#else /* UNIX, VMS, AOS/VS, and all others */
-char *srvtxt = "\r\n\
-Entering server mode. If your local Kermit software is menu driven, use\r\n\
-the menus to send commands to the server. Otherwise, enter the escape\r\n\
-sequence to return to your local Kermit prompt and issue commands from\r\n\
-there. Use SEND and GET for file transfer. Use REMOTE HELP for a list of\r\n\
-other available services. Use BYE or FINISH to end server mode.\r\n\0";
-#endif /* OSK */
-#endif /* OLDMSG */
-#endif /* MINIX */
-#else /* server mode disabled */
-char *srvtxt = "";
-#endif /* NOSERVER */
-
-int initflg = 0; /* sysinit() has executed... */
-int howcalled = I_AM_KERMIT; /* How I was called */
-int hmtopline = 0;
-int quitting = 0; /* I'm in the act of quitting */
-
-#ifdef IKSDCONF
-char * iksdconf = IKSDCONF; /* IKSD configuration file */
-int iksdcf = 0; /* Has IKSD c.f. been processed? */
-#endif /* IKSDCONF */
-
-int srvcdmsg = 0; /* [Server] CD message */
-char * cdmsgfile[8] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
-char * cdmsgstr = NULL;
-char * ckcdpath = NULL;
-
-#ifdef NLCHAR /* Text-file line terminator */
-CHAR feol = NLCHAR;
-#else
-CHAR feol = 0;
-#endif /* NLCHAR */
-
-int fblksiz = DBLKSIZ; /* File blocksize */
-int frecl = DLRECL; /* File record length */
-int frecfm = XYFF_S; /* File record format (default = stream) */
-int forg = XYFO_S; /* File organization (sequential) */
-int fcctrl = XYFP_N; /* File carriage control (ctrl chars) */
-int filecase = FILECASE; /* Case matters in filenames */
-int stathack = 1; /* Fast directory lookups by default */
-
-char uidbuf[UIDBUFLEN] = { NUL, NUL }; /* User ID buffer */
-int cfilef = 0; /* Application ("kerbang") file flag */
-char cmdfil[CKMAXPATH + 1] = { NUL, NUL }; /* Application file name */
-int haveurl = 0; /* URL given on command line */
-
-#ifndef NOXFER
-/* Multi-protocol support */
-
-struct ck_p ptab[NPROTOS] = { /* Initialize the Kermit part ... */
- { "Kermit",
- DRPSIZ, /* Receive packet size */
- DSPSIZ, /* Send packet size */
- 0, /* Send-packet-size-set flag */
- DFWSIZ, /* Window size */
-
-#ifdef NEWDEFAULTS
- PX_CAU, /* Control char unprefixing... */
-#else
- PX_ALL,
-#endif /* NEWDEFAULTS */
-
-#ifdef VMS /* Default filename collision action */
- XYFX_X, /* REPLACE for VAX/VMS */
-#else
- XYFX_B, /* BACKUP for everybody else */
-#endif /* VMS */
-
-#ifdef OS2 /* Flag for file name conversion */
- XYFN_L, /* Literal for OS2 */
-#else
- XYFN_C, /* Converted for others */
-#endif /* OS2 */
-
- PATH_OFF, /* Send pathnames OFF */
- PATH_AUTO, /* Receive pathnames AUTO */
- NULL, /* Host receive initiation string (binary) */
- NULL, /* Host receive initiation string (text) */
- NULL, /* Host server string */
- NULL, /* External protocol send command (binary) */
- NULL, /* External protocol send command (text) */
- NULL, /* External protocol receive command (bin) */
- NULL } /* External protocol receive command (txt) */
-#ifdef CK_XYZ
-,
-{"XMODEM", 128,128,-1,-1, 1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
-{"XMODEM-CRC",128,128,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
-{"YMODEM", -1, -1,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
-{"YMODEM-g", -1, -1,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
-{"ZMODEM", -1, -1,-1,-1,PX_WIL,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
-{"Other", -1, -1,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
-#endif /* CK_XYZ */
-};
-
-/* Declarations for Send-Init Parameters */
-
-int spsiz = DSPSIZ, /* Current packet size to send */
- spmax = DSPSIZ, /* Biggest packet size we can send */
- lastspmax = DSPSIZ, /* Send-packet size last used */
- spsizr = DSPSIZ, /* Send-packet size requested */
- spsizf = 0, /* Flag to override size negotiation */
- rpsiz = DRPSIZ, /* Biggest we want to receive */
- urpsiz = DRPSIZ, /* User-requested receive pkt size */
- maxrps = MAXRP, /* Maximum incoming long packet size */
- maxsps = MAXSP, /* Maximum outbound l.p. size */
- maxtry = MAXTRY, /* Maximum retries per packet */
- wslots = 1, /* Window size currently in use */
- wslotr = DFWSIZ, /* Window size from SET WINDOW */
- wslotn = 1, /* Window size negotiated in S-pkt */
- timeouts = 0, /* For statistics reporting */
- spackets = 0, /* ... */
- rpackets = 0, /* ... */
- retrans = 0, /* ... */
- crunched = 0, /* ... */
- wmax = 0, /* ... */
- wcur = 0, /* ... */
- srvidl = 0, /* Server idle timeout */
- srvdis = 1, /* Server file xfer display */
- srvtim = DSRVTIM, /* Server command wait timeout */
- srvping = 1, /* Server keepalive */
-/*
- timint is the timeout interval I use when waiting for a packet.
- pkttim is the SET RECEIVE TIMEOUT value, sent to the other Kermit.
- rtimo is the SET SEND TIMEOUT value. rtimo is the initial value of
- timint. timint is changed by the value in the incoming negotiation
- packet unless a SET SEND TIMEOUT command was given.
-*/
- timint = DMYTIM, /* Timeout interval I use */
- pkttim = URTIME, /* Timeout I want you to use */
- rtimo = DMYTIM, /* Normal packet wait timeout */
- timef = 0, /* Flag to override what you ask */
-#ifdef CK_TIMERS
- rttflg = 1, /* Use dynamic round-trip timers */
-#else
- rttflg = 0, /* Use fixed timer */
-#endif /* CK_TIMERS */
- mintime = 1, /* Minimum timeout */
- maxtime = 0, /* Maximum timeout */
-
- npad = MYPADN, /* How much padding to send */
- mypadn = MYPADN, /* How much padding to ask for */
- bctr = DFBCT, /* Block check type requested */
- bctu = 1, /* Block check type used */
- bctl = 1, /* Block check length */
- bctf = 0, /* Block check type 3 forced on all */
- c_save = -1, /* Block check saving and restoring */
- ss_save = -1, /* Slow-start saving and restoring */
- ebq = MYEBQ, /* 8th bit prefix */
- ebqflg = 0, /* 8th-bit quoting flag */
- rqf = -1, /* Flag used in 8bq negotiation */
- rq = 0, /* Received 8bq bid */
- sq = 'Y', /* Sent 8bq bid */
- rpt = 0, /* Repeat count */
- rptq = MYRPTQ, /* Repeat prefix */
- rptflg = 0, /* Repeat processing flag */
- rptena = 1, /* Repeat processing enabled */
- xfrcan = 1, /* Transfer cancellation enabled */
- xfrint = 1, /* Transfer interruption enabled */
- xfrchr = 3, /* Transfer cancel char = Ctrl-C */
- xfrnum = 3, /* Need three of them by default */
- g_xfrxla = -1;
- char * xfrmsg = NULL; /* Message for f.t. display screen */
-#endif /* NOXFER */
-
-#ifdef NOCSETS
-int xfrxla = 0; /* Character-set translation */
-#else
-int xfrxla = 1; /* enabled or disabled */
-#endif /* NOCSETS */
-
-int havelfs = 0; /* Large file support available */
-
-#ifndef NOXFER
-int epktflg = 0; /* E-PACKET command active */
-
-int capas = 9, /* Position of Capabilities */
- lpcapb = 2, /* Long Packet capability */
- lpcapr = 1, /* requested */
- lpcapu = 0, /* used */
- swcapb = 4, /* Sliding Window capability */
- swcapr = 1, /* requested (allowed) */
- swcapu = 0, /* used */
- atcapb = 8, /* Attribute capability */
- atcapr = 1, /* requested */
- atcapu = 0, /* used */
- rscapb = 16, /* RESEND capability */
- rscapr = 1, /* requested by default */
- rscapu = 0, /* used */
- lscapb = 32, /* Locking Shift capability */
- lscapr = 1, /* requested by default */
- lscapu = 0; /* used */
-
-/* Flags for whether to use particular attributes */
-
-int atenci = 1, /* Encoding in */
- atenco = 1, /* Encoding out */
- atdati = 1, /* Date in */
- atdato = 1, /* Date out */
- atdisi = 1, /* Disposition in/out */
- atdiso = 1,
- atleni = 1, /* Length in/out (both kinds) */
- atleno = 1,
- atblki = 1, /* Blocksize in/out */
- atblko = 1,
- attypi = 1, /* File type in/out */
- attypo = 1,
- atsidi = 1, /* System ID in/out */
- atsido = 1,
- atsysi = 1, /* System-dependent parameters in/out */
- atsyso = 1;
-
-int dispos = 0; /* Disposition */
-
-#ifdef CK_PERMS
-int atlpri = 1,
- atlpro = 1,
- atgpri = 1,
- atgpro = 1;
-#endif /* CK_PERMS */
-
-int atfrmi = 1, /* Record Format in/out */
- atfrmo = 1;
-
-#ifdef STRATUS
-int atcrei = 1, /* Creator ID in/out */
- atcreo = 1,
- atacti = 1, /* Account in/out */
- atacto = 1;
-#endif /* STRATUS */
-
-int sprmlen = -1; /* Send/Receive protocol parameter */
-int rprmlen = -1; /* string length limits */
-int sendipkts = 1; /* Send I packets */
-
-CHAR padch = MYPADC, /* Padding character to send */
- mypadc = MYPADC, /* Padding character to ask for */
- seol = MYEOL, /* End-Of-Line character to send */
- eol = MYEOL, /* End-Of-Line character to look for */
- ctlq = CTLQ, /* Control prefix in incoming data */
- myctlq = CTLQ, /* Outbound control character prefix */
- myrptq = MYRPTQ; /* Repeat prefix I want to use */
-
-int rptmin = 3; /* Repeat-count minimum */
-
-int usepipes = 0, /* Used for xfer to/from pipes */
- g_usepipes = -1;
-
-char * filefile = NULL; /* File containing list of filenames */
-/* CD message filename list */
-
-char whoareu[16] = { NUL, NUL }; /* System ID of other Kermit */
-int sysindex = -1; /* and index to its system ID struct */
-int myindex = -1;
-int wearealike = 0; /* 2 Kermits have compatible sysids */
-char * cksysid = /* My system ID */
-#ifdef UNIX
- "U1"
-#else
-#ifdef VMS
- "D7"
-#else
-#ifdef OSK
- "UD"
-#else
-#ifdef AMIGA
- "L3"
-#else
-#ifdef MAC
- "A3"
-#else
-#ifdef OS2
-#ifdef NT
- "UN"
-#else /* NT */
- "UO"
-#endif /* NT */
-#else /* OS2 */
-#ifdef datageneral
- "F3"
-#else
-#ifdef GEMDOS
- "K2"
-#else
-#ifdef STRATUS
- "MV"
-#else
- ""
-#endif /* STRATUS */
-#endif /* GEMDOS */
-#endif /* datageneral */
-#endif /* OS2 */
-#endif /* MAC */
-#endif /* AMIGA */
-#endif /* OSK */
-#endif /* VMS */
-#endif /* UNIX */
- ;
-
-int oopts = -1; /* O-Packet Options */
-int omode = -1; /* O-Packet Transfer Mode */
-int oname = -1; /* O-Packet Filename Options */
-int opath = -1; /* O-Packet Pathname Options */
-
-struct zattr iattr; /* Incoming file attributes */
-
-#ifdef VMS
-/* VMS labeled file default options - name only. */
-int lf_opts = LBL_NAM;
-#else
-#ifdef OS2
-/* OS/2 labeled file default options, all attributes but archived. */
-unsigned long int lf_opts = LBL_EXT|LBL_HID|LBL_RO|LBL_SYS;
-#else
-int lf_opts = 0;
-#endif /* OS2 */
-#endif /* VMS */
-
-/* Packet-related variables */
-
-int pktnum = 0, /* Current packet number */
- sndtyp = 0, /* Type of packet just sent */
- rcvtyp = 0, /* Type of packet just received */
- rsn, /* Received packet sequence number */
- rln, /* Received packet length */
- size, /* Current size of output pkt data */
- osize, /* Previous output packet data size */
- maxsize, /* Max size for building data field */
- spktl = 0, /* Length packet being sent */
- rpktl = 0, /* Length of packet just received */
- pktpaus = 0, /* Interpacket pause interval, msec */
- rprintf, /* REMOTE PRINT flag */
- rmailf, /* MAIL flag */
- xferstat = -1, /* Status of last transaction */
- filestatus = 0; /* Status of last file transfer */
-
-CHAR pktmsgbuf[PKTMSGLEN+1];
-CHAR *epktmsg = pktmsgbuf;
-
-#ifdef pdp11
-int srvcmdlen = MAXRP; /* srvcmd buffer length */
-#else
-#ifdef DYNAMIC
-int srvcmdlen = MAXRP;
-#else
-int srvcmdlen = 0;
-#endif /* DYNAMIC */
-#endif /* pdp11 */
-
-CHAR
-#ifdef pdp11
- srvcmdbuf[MAXRP+4],
- *srvcmd = srvcmdbuf,
-#else
-#ifdef DYNAMIC
- *srvcmd = (CHAR *)0, /* Where to decode server command */
-#else
- srvcmdbuf[MAXRP+4],
- *srvcmd = srvcmdbuf,
-#endif /* DYNAMIC */
-#endif /* pdp11 */
- padbuf[96], /* Buffer for send-padding */
- *recpkt,
- *rdatap, /* Pointer to received packet data */
- *data = (CHAR *)0, /* Pointer to send-packet data */
- *srvptr, /* Pointer to srvcmd */
- mystch = SOH, /* Outbound packet-start character */
- stchr = SOH; /* Incoming packet-start character */
-
-/* File-related variables */
-
-#ifndef NOMSEND /* Multiple SEND */
-struct filelist * filehead = NULL; /* SEND list */
-struct filelist * filetail = NULL;
-struct filelist * filenext = NULL;
-int addlist = 0;
-#endif /* NOMSEND */
-
-char filnam[CKMAXPATH + 1]; /* Name of current file. */
-char ofilnam[CKMAXPATH + 1]; /* Original name. */
-
-int pipesend = 0; /* Nonzero if sending from pipe */
-#ifdef PIPESEND
-char * sndfilter = NULL; /* Send and receive filters */
-char * rcvfilter = NULL;
-#endif /* PIPESEND */
-
-char ** sndarray = NULL; /* SEND /ARRAY pointer and range */
-#ifndef NOSPL
-int sndxlo = -1, sndxhi = -1, sndxin = -1;
-#endif /* NOSPL */
-#endif /* NOXFER */
-
-#ifndef NOSERVER
-int ngetpath = 0; /* GET search path */
-int fromgetpath = 0;
-char * getpath[MAXGETPATH];
-char * x_user = NULL; /* Server login information */
-char * x_passwd = NULL;
-char * x_acct = NULL;
-#endif /* NOSERVER */
-
-int x_login = 0; /* Login required */
-int x_logged = 0; /* User is logged in */
-
-extern int timelimit;
-
-#ifdef CK_LOGIN
-int logintimo = 300; /* Login timeout */
-char * userfile = NULL; /* Forbidden user file */
-#endif /* CK_LOGIN */
-#ifdef IKSD
-char * anonfile = NULL; /* Anonymous login init file */
-char * anonroot = NULL; /* Anonymous file-system root */
-int iks_timo = 300; /* 5 minutes idle timo */
-int iks_retry = 3; /* 3 attempts at login */
-#endif /* IKSD */
-
-#ifdef CKSYSLOG
-extern VOID zsyslog();
-extern int ckxlogging, ckxsyslog;
-#endif /* CKSYSLOG */
-
-CK_OFF_T fsize = (CK_OFF_T)0, /* Size of current file */
- sendstart = (CK_OFF_T)0, /* SEND start position */
- calibrate = (CK_OFF_T)0; /* Nonzero if calibration run */
-
-int nzxopts = 0; /* Options for nzxpand() */
-int nfils = 0; /* Number of files in file group */
-int wildena = 1; /* Wildcard expansion enabled */
-#ifdef UNIX
-int wildxpand = 0; /* Who expands wildcards, 0=Kermit.. */
-#else /* UNIX */
-#ifdef STRATUS
-int wildxpand = 1; /* 1=Shell. */
-#endif /* STRATUS */
-#endif /* UNIX */
-#ifdef UNIXOROSK
-int matchdot = 0; /* Whether to match dot files */
-#else
-int matchdot = 1;
-#endif /* UNIXOROSK */
-int matchfifo = 0; /* Whether to match FIFO "files" */
-int clfils = 0; /* Flag for command-line files */
-int stayflg = 0; /* Flag for "stay", i.e. "-S" */
-int xfinish = 0; /* Flag for FINISH = EXIT */
-long ztusec = -1L; /* Used with ztime() */
-long ztmsec = -1L; /* Ditto */
-
-/* Communication device / connection variables */
-
-char ttname[TTNAMLEN+1]; /* Name of communication device */
-
-#ifdef MAC
-int connected = 0; /* True if connected */
-int startconnected; /* initial state of connected */
-#endif /* MAC */
-
-long speed = -1L; /* Communication device speed */
-int wasclosed = 0; /* Connection was just closed */
-int whyclosed = WC_REMO; /* why it was closed */
-int qnxportlock = 0; /* QNX port locking on/off */
-
-#ifndef CLSONDISC
-#define CLSONDISC 0
-#endif /* CLSONDISC */
-
-int cxflow[CXT_MAX+1]; /* See initflow() */
-
-#ifndef NOSHOW
-char * floname[] = { /* Flow control names */
- "none", "xon/xoff", "rts/cts", "dtr/cd", "etx/ack", "string",
- "xxx1", "xxx2", "dtr/cts", "keep", "auto"
-};
-int nfloname = (sizeof(floname) / sizeof(char *));
-
-char * cxname[] = { /* Connection type names */
- "remote", "direct-serial", "modem", "tcp/ip", "x.25", "decnet",
- "lat", "netbios", "named-pipe", "ssh", "pipe"
-};
-int ncxname = (sizeof(cxname) / sizeof(char *));
-#endif /* NOSHOW */
-
-int parity = DEFPAR, /* Parity specified, 0,'e','o',etc */
- hwparity = 0, /* Hardware parity for serial port */
- stopbits = -1, /* Stop bits for serial port */
- clsondisc = CLSONDISC, /* Serial port close on disconnect */
- autopar = 0, /* Automatic parity change flag */
- sosi = 0, /* Shift-In/Out flag */
- flow = 0, /* Flow control (see initflow()) */
- autoflow = 1, /* Automatic flow control */
- turn = 0, /* Line turnaround handshake flag */
- turnch = XON, /* Line turnaround character */
- duplex = 0, /* Duplex, full by default */
- escape = DFESC, /* Escape character for connect */
- ckdelay = DDELAY, /* Initial delay before sending */
- tnlm = 0; /* Terminal newline mode */
-
-/* Networks for SET HOST */
-
-#ifdef BIGBUFOK
-#define MYHOSTL 1024
-#else
-#define MYHOSTL 100
-#endif /* BIGBUFOK */
-
-char myhost[MYHOSTL]; /* Local host name */
-int network = 0; /* Network vs serial connection */
-int inserver = 0; /* Running as an Internet server */
-int isguest = 0; /* User is anonymous */
-char * clienthost = NULL; /* Peer host name or address */
-int tcp_incoming = 0; /* Incoming TCP connection? */
-
-#ifdef NETCONN
-#ifdef TCPSOCKET
-int nettype = NET_TCPB; /* Default network type */
-#else
-#ifdef SUNX25
-int nettype = NET_SX25;
-#else
-#ifdef IBMX25
-int nettype = NET_IX25;
-#else
-#ifdef HPX25
-int nettype = NET_HX25;
-#else
-#ifdef STRATUSX25
-int nettype = NET_VX25;
-#else
-#ifdef DECNET
-int nettype = NET_DEC;
-#else
-#ifdef SUPERLAT
-int nettype = NET_SLAT;
-#else
-int nettype = NET_NONE;
-#endif /* SUPERLAT */
-#endif /* DECNET */
-#endif /* STRATUSX25 */
-#endif /* HPX25 */
-#endif /* IBMX25 */
-#endif /* SUNX25 */
-#endif /* TCPSOCKET */
-#else /* NETCONN */
-int nettype = NET_NONE;
-#endif /* NETCONN */
-
-#ifdef ANYX25
-int revcall = 0; /* X.25 reverse call not selected */
-int closgr = -1; /* X.25 closed user group */
-int cudata = 0; /* X.25 call user data not specified */
-char udata[MAXCUDATA]; /* X.25 call user data */
-
-#ifdef IBMX25
-/*
- I was unable to find any pre-defined MAX values for x25 addresses - the
- addresses that I've seen have been around 10-12 characters 32 is probably
- enough, 64 is hopefully safe for everyone.
-*/
- x25addr_t local_nua = {'\0'}; /* local x.25 address */
- x25addr_t remote_nua = {'\0'}; /* remote x.25 address */
- char x25name[32] = {'\0'}; /* x25 device name, sx25a0 or sx25a1 */
- char x25dev[64] = "/dev/x25pkt"; /* x25 device in /dev */
- int x25port = 0; /* port used for X.25 - AIX only */
-#endif /* IBMX25 */
-
-#ifndef IBMX25
-/*
- This condition is unrelated to the above IBMX25 condition.
- IBM X.25 doesn't have PAD support.
-*/
- CHAR padparms[MAXPADPARMS+1]; /* X.3 parameters */
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-/* Other items */
-
-int isinterrupted = 0; /* Used in exception handling */
-int what = W_INIT; /* What I am doing */
-int lastxfer = 0; /* Last transfer (send or receive) */
-
-extern int mdmtyp; /* Modem (/network) type */
-
-#ifdef NT
-extern int StartedFromDialer;
-#ifdef NTSIG
-extern int TlsIndex;
-#endif /* NTSIG */
-#ifdef NTASM
-unsigned long ESPToRestore; /* Ditto */
-#endif /* NTASM */
-#endif /* NT */
-
-#ifdef OS2PM
-int os2pm = 0; /* OS/2 Presentation Manager flag */
-#endif /* OS2PM */
-
-/* Terminal screen size, if known, -1 means unknown. */
-
-#ifdef OS2
-#include "ckocon.h"
-#ifdef KUI
-int tt_rows[VNUM] = {24,24,25,1}; /* Rows (height) */
-int tt_cols[VNUM] = {80,80,80,80}; /* Columns (width) */
-int cmd_rows = 24, cmd_cols = 80; /* Command/console screen dimensions */
-#else /* KUI */
-int tt_rows[VNUM] = {-1,24,25,1}; /* Rows (height) */
-int tt_cols[VNUM] = {-1,80,80,80}; /* Columns (width) */
-int cmd_rows = -1, cmd_cols = -1; /* Command/console screen dimensions */
-#endif /* KUI */
-int k95stdio = 0; /* Stdio threads */
-int tt_bell = XYB_AUD | XYB_SYS; /* BELL AUDIBLE (system sounds) */
-#else /* OS2 */
-int tt_rows = -1; /* Rows (height) */
-int tt_cols = -1; /* Columns (width) */
-int cmd_rows = 24, cmd_cols = 80; /* Command/console screen dimensions */
-int tt_bell = XYB_AUD; /* BELL ON */
-#endif /* OS2 */
-
-int tt_print = 0; /* Transparent print disabled */
-int tt_escape = 1; /* Escaping back is enabled */
-int tt_scroll = 1; /* Scrolling operations are enabled */
-
-int tn_exit = 0; /* Exit on disconnect */
-
-int exitonclose = 0; /* Exit on close */
-int exithangup = 1; /* Hangup on exit */
-int haveline = 0; /* SET LINE or SET HOST in effect */
-int tlevel = -1; /* Take-file command level */
-int hints = 1; /* Whether to give hints */
-
-#ifdef NOLOCAL
-int remonly = 1; /* Remote-mode-only advisory (-R) */
-int nolocal = 1; /* Remote-only strictly enforced */
-#else
-int remonly = 0;
-int nolocal = 0;
-int cx_status = 0; /* CONNECT return status */
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
-extern int cmdlvl; /* Command level */
-extern int maclvl; /* Macro invocation level */
-#endif /* NOSPL */
-
-int protocol = PROTO_K; /* File transfer protocol = Kermit */
-
-#ifdef NEWDEFAULTS
-int prefixing = PX_CAU;
-#else
-int prefixing = PX_ALL;
-#endif /* NEWDEFAULTS */
-
-extern short ctlp[]; /* Control-prefix table */
-
-int carrier = CAR_AUT; /* Pay attention to carrier signal */
-int cdtimo = 0; /* Carrier wait timeout */
-int xitsta = GOOD_EXIT; /* Program exit status */
-
-#ifdef VMS /* Default filename collision action */
-int fncact = XYFX_X; /* REPLACE for VMS */
-#else
-int fncact = XYFX_B; /* BACKUP for everybody else */
-#endif /* VMS */
-
-int fncsav = -1; /* For saving & restoring the above */
-int bgset = -1; /* BACKGROUND mode set explicitly */
-
-int cmdint = 1; /* Interrupts are allowed */
-#ifdef UNIX
-int xsuspend = DFSUSP; /* Whether SUSPEND command, etc, */
-#else /* is to be allowed. */
-int xsuspend = 0;
-#endif /* UNIX */
-
-/* Statistics variables */
-
-CK_OFF_T
- flci, /* Characters from line, current file */
- flco, /* Chars to line, current file */
- tlci, /* Chars from line in transaction */
- tlco, /* Chars to line in transaction */
- ffc, /* Chars to/from current file */
- tfc; /* Chars to/from files in transaction */
-
-long filcnt, /* Number of files in transaction */
- filrej, /* Number of files rejected in transaction */
- cps = 0L, /* Chars/sec last transfer */
- peakcps = 0L, /* Peak chars/sec last transfer */
- ccu, /* Control chars unprefixed in transaction */
- ccp, /* Control chars prefixed in transaction */
- rptn; /* Repeated characters compressed */
-
-int tsecs = 0; /* Seconds for transaction */
-int fsecs = 0; /* Per-file timer */
-
-#ifdef GFTIMER
-CKFLOAT
- fpfsecs = 0.0, /* Floating point per-file timer */
- fptsecs = 0.0; /* and per-transaction timer */
-#endif /* GFTIMER */
-
-/* Flags */
-
-int deblog = 0, /* Debug log is open */
- debok = 1, /* Debug log is not disabled */
- debxlen = 54, /* Default length for debug strings */
- debses = 0, /* Flag for DEBUG SESSION */
- debtim = 0, /* Include timestamp in debug log */
- debmsg = 0, /* Debug messages on/off */
- pktlog = 0, /* Flag for packet logging */
- seslog = 0, /* Session logging */
- dialog = 0, /* DIAL logging */
- tralog = 0, /* Transaction logging */
- tlogfmt = 1, /* Transaction log format (verbose) */
- tlogsep = (int)',', /* Transaction log field separator */
- displa = 0, /* File transfer display on/off */
- stdouf = 0, /* Flag for output to stdout */
- stdinf = 0, /* Flag for input from stdin */
- xflg = 0, /* Flag for X instead of F packet */
- hcflg = 0, /* Doing Host command */
- dest = DEST_D, /* Destination for packet data */
- zchkod = 0, /* zchko() should work for dirs too? */
- zchkid = 0, /* zchki() should work for dirs too? */
-
-/* If you change this, also see struct ptab above... */
-
-#ifdef OS2 /* Flag for file name conversion */
- fncnv = XYFN_L, /* Default is Literal in OS/2, */
- f_save = XYFN_L, /* (saved copy of same) */
-#else
- fncnv = XYFN_C, /* elsewhere Convert them */
- f_save = XYFN_C, /* (ditto) */
-#endif /* OS2 */
-
- fnspath = PATH_OFF, /* Send file path */
- fnrpath = PATH_AUTO, /* Receive file path */
- fackpath = 1, /* Send back path in ACK to F */
- binary = XYFT_B, /* Default file transfer mode */
- b_save = XYFT_B, /* Saved file mode */
- eofmethod = 0, /* EOF detection method (length) */
-
-#ifdef OS2
- cursor_save = -1, /* Cursor state */
-#endif /* OS2 */
-
- xfermode = XMODE_A, /* Transfer mode, manual or auto */
- xfiletype = -1, /* Transfer only text (or binary) */
- recursive = 0, /* Recursive directory traversal */
- nolinks = 2, /* Don't follow symbolic links */
- skipbup = 0, /* Skip backup files when sending */
- sendmode = SM_SEND, /* Which type of SEND operation */
- slostart = 1, /* Slow start (grow packet lengths) */
- cmask = 0377, /* CONNECT (terminal) byte mask */
- fmask = 0377, /* File byte mask */
- ckwarn = 0, /* Flag for file warning */
- quiet = 0, /* Be quiet during file transfer */
- local = 0, /* 1 = local mode, 0 = remote mode */
- cxtype = CXT_REMOTE, /* Connection type */
- server = 0, /* Flag for I Am Server */
- query = 0, /* Flag for Query active */
- justone = 0, /* Server should do Just One command */
- urserver = 0, /* Flag for You Are Server */
- bye_active = 0, /* Flag for BYE command active */
- diractive = 0, /* Flag for DIRECTORY command active */
- cdactive = 0, /* Flag for CD command active */
- cflg = 0, /* Connect before transaction */
- cnflg = 0, /* Connect after transaction */
- cxseen = 0, /* Flag for cancelling a file */
- czseen = 0, /* Flag for cancelling file group */
- fatalio = 0, /* Flag for fatal i/o error */
- discard = 0, /* Flag for file to be discarded */
- keep = SET_AUTO, /* Keep incomplete files = AUTO */
- unkcs = 1, /* Keep file w/unknown character set */
-#ifdef VMS
- filepeek = 0, /* Inspection of files */
-#else
-#ifdef datgeneral
- filepeek = 0,
-#else
- filepeek = 1,
-#endif /* datageneral */
-#endif /* VMS */
- nakstate = 0, /* In a state where we can send NAKs */
- dblchar = -1, /* Character to double when sending */
- moving = 0, /* MOVE = send, then delete */
- reliable = SET_AUTO, /* Nonzero if transport is reliable */
- xreliable = -1,
- setreliable = 0,
- urclear = 0, /* Nonzero for clear channel to you */
- clearrq = SET_AUTO, /* SET CLEARCHANEL value */
- cleared = 0,
- streaming = 0, /* Nonzero if streaming is active */
- streamok = 0, /* Nonzero if streaming negotiated */
- streamrq = SET_AUTO, /* SET STREAMING value */
- streamed = -1; /* Whether we streamed last time */
-
-char * snd_move = NULL; /* Move file after sending it */
-char * snd_rename = NULL; /* Rename file after sending it */
-char * rcv_move = NULL; /* Move file after receiving it */
-char * rcv_rename = NULL; /* Rename file after receiving it */
-
-char * g_snd_move = NULL;
-char * g_snd_rename = NULL;
-char * g_rcv_move = NULL;
-char * g_rcv_rename = NULL;
-
-#ifdef CK_TRIGGER
-char *tt_trigger[TRIGGERS] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
-CHAR *tt_trmatch[TRIGGERS] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
-char *triggerval = NULL;
-#endif /* CK_TRIGGER */
-
-int ckxlogging = 0; /* Flag for syslogging active */
-int ikdbopen = 0; /* Flag for IKSD database active */
-int dbinited = 0; /* Flag for IKSDB record init'd */
-#ifndef CKSYSLOG
-int ckxsyslog = 0; /* Logging level 0 */
-#else
-#ifdef SYSLOGLEVEL
-int ckxsyslog = SYSLOGLEVEL; /* Logging level specified */
-#else
-int ckxsyslog = SYSLG_DF; /* Default logging level */
-#endif /* SYSLOGLEVEL */
-#endif /* CKSYSLOG */
-
-#ifndef NOHELP
-#ifndef NOCMDL
-_PROTOTYP( VOID iniopthlp, (void) ); /* Command-line help initializer */
-#endif /* NOCMDL */
-#endif /* NOHELP */
-
-_PROTOTYP( VOID getexedir, (void) );
-_PROTOTYP( int putnothing, (char) );
-
-#ifdef IKSD
-_PROTOTYP( VOID doiksdinit, (void) );
-_PROTOTYP( VOID iksdinit, (void) );
-_PROTOTYP( VOID doiklog, (void) );
-_PROTOTYP( int dbinit, (void) );
-#endif /* IKSD */
-
-/* Variables passed from command parser to protocol module */
-
-#ifndef NOSPL
-#ifndef NOICP
-#ifdef CK_APC
-_PROTOTYP( VOID apconect, (void) );
-#endif /* CK_APC */
-#ifdef OS2
-extern int initvik;
-#endif /* OS2 */
-#endif /* NOICP */
-#endif /* NOSPL */
-char *clcmds = NULL; /* Pointer to command-line commands */
-
-#ifndef NOSETKEY
-extern KEY *keymap;
-extern MACRO *macrotab;
-#endif /* NOSETKEY */
-
-#ifndef NOPUSH
-int nopush = 0; /* PUSH enabled */
-#else
-int nopush = 1; /* PUSH disabled */
-#endif /* NOPUSH */
-
-CHAR sstate = (CHAR) 0; /* Starting state for automaton */
-CHAR zstate = (CHAR) 0; /* For remembering sstate */
-char * printername = NULL; /* NULL if printer not redirected */
-int printpipe = 0; /* For SET PRINTER */
-int noprinter = 0;
-
-#ifndef NOXFER
-char *cmarg = ""; /* Pointer to command data */
-char *cmarg2 = ""; /* Pointer to 2nd command data */
-char **cmlist; /* Pointer to file list in argv */
-
-#ifdef CK_AUTODL /* Autodownload */
-int autodl = 1; /* Enabled by default */
-#else
-int autodl = 0; /* (or if not implemented). */
-#endif /* CK_AUTODL */
-int adl_err = 1; /* 1 = stop on error */
-#ifdef KUI
-int adl_ask = 1; /* 1 = file dialog on autodownload */
-#else
-int adl_ask = 0; /* 0 = no file dialog */
-#endif /* KUI */
-#ifdef OS2 /* AUTODOWNLOAD parameters */
-int adl_kmode = ADL_PACK, /* Match Packet to signal download */
- adl_zmode = ADL_PACK;
-char * adl_kstr = NULL; /* KERMIT Download String */
-char * adl_zstr = NULL; /* ZMODEM Download String */
-#endif /* OS2 */
-
-int remfile = 0, rempipe = 0, remappd = 0; /* REMOTE output redirection */
-char * remdest = NULL;
-
-#ifndef NOSERVER
-/*
- Server services:
- 0 = disabled
- 1 = enabled in local mode
- 2 = enabled in remote mode
- 3 = enabled in both local and remote modes
- only as initial (default) values.
-*/
-int en_xit = 2; /* EXIT */
-int en_cwd = 3; /* CD/CWD */
-int en_cpy = 3; /* COPY */
-int en_del = 2; /* DELETE */
-int en_mkd = 3; /* MKDIR */
-int en_rmd = 2; /* RMDIR */
-int en_dir = 3; /* DIRECTORY */
-int en_fin = 3; /* FINISH */
-int en_get = 3; /* GET */
-#ifndef NOPUSH
-int en_hos = 2; /* HOST enabled */
-#else
-int en_hos = 0; /* HOST disabled */
-#endif /* NOPUSH */
-int en_ren = 3; /* RENAME */
-int en_sen = 3; /* SEND */
-int en_set = 3; /* SET */
-int en_spa = 3; /* SPACE */
-int en_typ = 3; /* TYPE */
-int en_who = 3; /* WHO */
-#ifdef datageneral
-/* Data General AOS/VS can't do this */
-int en_bye = 0; /* BYE */
-#else
-int en_bye = 2; /* PCs in local mode... */
-#endif /* datageneral */
-int en_asg = 3; /* ASSIGN */
-int en_que = 3; /* QUERY */
-int en_ret = 2; /* RETRIEVE */
-int en_mai = 3; /* MAIL */
-int en_pri = 3; /* PRINT */
-int en_ena = 3; /* ENABLE */
-#else
-int en_xit = 0, en_cwd = 0, en_cpy = 0, en_del = 0, en_mkd = 0, en_rmd = 0,
- en_dir = 0, en_fin = 0, en_get = 0, en_hos = 0, en_ren = 0, en_sen = 0,
- en_set = 0, en_spa = 0, en_typ = 0, en_who = 0, en_bye = 0, en_asg = 0,
- en_que = 0, en_ret = 0, en_mai = 0, en_pri = 0, en_ena = 0;
-#endif /* NOSERVER */
-#endif /* NOXFER */
-
-/* Miscellaneous */
-
-char **xargv; /* Global copies of argv */
-int xargc; /* and argc */
-int xargs; /* an immutable copy of argc */
-char *xarg0; /* and of argv[0] */
-char *pipedata; /* Pointer to -P (pipe) data */
-
-extern char *dftty; /* Default tty name from ck?tio.c */
-extern int dfloc; /* Default location: remote/local */
-extern int dfprty; /* Default parity */
-extern int dfflow; /* Default flow control */
-
-#ifdef TNCODE
-extern int tn_deb;
-#endif /* TNCODE */
-/*
- Buffered file input and output buffers. See getpkt() in ckcfns.c
- and zoutdump() in the system-dependent file i/o module (usually ck?fio.c).
-*/
-#ifndef DYNAMIC
-/* Now we allocate them dynamically, see getiobs() below. */
-char zinbuffer[INBUFSIZE], zoutbuffer[OBUFSIZE];
-#endif /* DYNAMIC */
-char *zinptr, *zoutptr;
-int zincnt, zoutcnt;
-int zobufsize = OBUFSIZE;
-int zofbuffer = 1;
-int zofblock = 1;
-
-#ifdef SESLIMIT
-int seslimit = 0;
-#endif /* SESLIMIT */
-
-#ifdef CK_AUTHENTICATION
-#include "ckuath.h"
-#endif /* CK_AUTHENTICATION */
-
-_PROTOTYP( int getiobs, (VOID) );
-
-/* M A I N -- C-Kermit main program */
-
-#include <signal.h>
-
-#ifndef NOCCTRAP
-#include <setjmp.h>
-#include "ckcsig.h"
-ckjmpbuf cmjbuf;
-#ifdef GEMDOS /* Special for Atari ST */
-cc_clean(); /* This can't be right? */
-#endif /* GEMDOS */
-#endif /* NOCCTRAP */
-
-#ifndef NOXFER
-/* Info associated with a system ID */
-
-struct sysdata sysidlist[] = { /* Add others as needed... */
- { "0", "anonymous", 0, NUL, 0, 0, 0 },
- { "A1", "Apple II", 0, NUL, 0, 0, 3 }, /* fix this */
- { "A3", "Macintosh", 1, ':', 0, 2, 1 },
- { "D7", "VMS", 0, ']', 1, 0, 0 },
- { "DA", "RSTS/E", 0, ']', 1, 0, 3 }, /* (i think...) */
- { "DB", "RT11", 0, NUL, 1, 0, 3 }, /* (maybe...) */
- { "F3", "AOS/VS", 1, ':', 0, 0, 2 },
- { "I1", "VM/CMS", 0, NUL, 0, 0, 0 },
- { "I2", "MVS/TSO", 0, NUL, 0, 0, 0 },
- { "I4", "MUSIC", 0, NUL, 0, 0, 0 },
- { "I7", "CICS", 0, NUL, 0, 0, 0 },
- { "I9", "MVS/ROSCOE", 0, NUL, 0, 0, 0 },
- { "K2", "Atari ST", 1, '\\', 1, 0, 3 },
- { "L3", "Amiga", 1, '/', 1, 0, 2 },
- { "MV", "Stratus VOS", 1, '>', 0, 1, 0 },
- { "N3", "Apollo Aegis", 1, '/', 0, 3, 2 },
- { "U1", "UNIX", 1, '/', 0, 3, 2 },
- { "U8", "MS-DOS", 1, '\\', 1, 0, 3 },
- { "UD", "OS-9", 1, '/', 0, 3, 2 },
- { "UN", "Windows-32", 1, '\\', 1, 2, 3 },
- { "UO", "OS/2", 1, '\\', 1, 2, 3 }
-};
-static int nxxsysids = (sizeof(sysidlist) / sizeof(struct sysdata));
-
-/* Given a Kermit system ID code, return the associated name string */
-/* and some properties of the filenames... */
-
-char *
-getsysid(s) char * s; { /* Get system-type name */
- int i;
- if (!s) return("");
- for (i = 0; i < nxxsysids; i++)
- if (!strcmp(sysidlist[i].sid_code,s))
- return(sysidlist[i].sid_name);
- return(s);
-}
-
-int
-getsysix(s) char *s; { /* Get system-type index */
- int i;
- if (!s) return(-1);
- for (i = 0; i < nxxsysids; i++)
- if (!strcmp(sysidlist[i].sid_code,s))
- return(i);
- return(-1);
-}
-#endif /* NOXFER */
-
-/* Tell if a pathname is absolute (versus relative) */
-/* This should be parceled out to each of the ck*fio.c modules... */
-/* VMS isabsolute() is now in ckvfio.c. */
-#ifndef VMS
-int
-isabsolute(path) char * path; {
- int rc = 0;
- int x;
- if (!path)
- return(0);
- if (!*path)
- return(0);
- x = (int) strlen(path);
- debug(F111,"isabsolute",path,x);
-#ifdef UNIX
- if (*path == '/'
-#ifdef DTILDE
- || *path == '~'
-#endif /* DTILDE */
- )
- rc = 1;
-#else /* def UNIX */
-#ifdef OS2
- if (*path == '/' || *path == '\\')
- rc = 1;
- else if (isalpha(*path) && x > 2)
- if (*(path+1) == ':' && (*(path +2) == '/' || *(path+2) == '\\'))
- rc = 1;
-#else /* def OS2 */
-#ifdef AMIGA
- if (*path == '/'
-#ifdef DTILDE
- || *path == '~'
-#endif /* DTILDE */
- )
- rc = 1;
-#else /* def AMIGA */
-#ifdef OSK
- if (*path == '/'
-#ifdef DTILDE
- || *path == '~'
-#endif /* DTILDE */
- )
- rc = 1;
-#else /* def OSK */
-#ifdef datageneral
- if (*path == ':')
- rc = 1;
-#else /* def datageneral */
-#ifdef MAC
- rc = 0; /* Fill in later... */
-#else /* def MAC */
-#ifdef STRATUS
- rc = 0; /* Fill in later... */
-#else /* def STRATUS */
-#ifdef GEMDOS
- if (*path == '/' || *path == '\\')
- rc = 1;
- else if (isalpha(*path) && x > 1)
- if (*(path+1) == ':')
- rc = 1;
-#endif /* GEMDOS */
-#endif /* STRATUS */
-#endif /* MAC */
-#endif /* datageneral */
-#endif /* OSK */
-#endif /* AMIGA */
-#endif /* OS2 */
-#endif /* UNIX */
- debug(F101,"isabsolute rc","",rc);
- return(rc);
-}
-#endif /* ndef VMS */
-
-/* See if I have direct access to the keyboard */
-
-int
-is_a_tty(n) int n; {
-#ifdef UNIX
- extern int ttfdflg;
- if (ttfdflg > 0)
- return(1);
-#endif /* UNIX */
-#ifdef KUI
- return 1;
-#else /* KUI */
-#ifdef NT
- if (isWin95())
- return(1);
- else
- return(_isatty(n));
-#else
-#ifdef IKSD
- if (inserver)
- return(1);
- else
-#endif /* IKSD */
- return(isatty(n));
-#endif /* NT */
-#endif /* KUI */
-}
-
-#ifndef NOXFER
-VOID
-initxlist() {
- extern char * sndexcept[], * rcvexcept[];
- int i;
- for (i = 0; i < NSNDEXCEPT; i++) {
- sndexcept[i] = NULL;
- rcvexcept[i] = NULL;
- }
-}
-#endif /* NOXFER */
-
-/* Initialize flow control table */
-
-VOID
-initflow() { /* Default values for flow control */
-#ifdef VMS /* for each kind of connection. */
- /* The VMS telnet terminal driver treats "none" as request to lose chars */
- cxflow[CXT_REMOTE] = FLO_XONX; /* Remote mode... */
-#else
-#ifdef HPUX
- /* Ditto for HP-UX */
- cxflow[CXT_REMOTE] = FLO_XONX; /* Remote mode... */
-#else
- /* The temptation is to make this one FLO_KEEP but don't!!! */
- /* It totally wrecks binary-file transfer when coming in via Telnet. */
- /* In UNIX at least... */
- cxflow[CXT_REMOTE] = FLO_NONE;
-#endif /* HPUX */
-#endif /* VMS */
-
-#ifdef VMS
- cxflow[CXT_DIRECT] = FLO_XONX; /* Direct serial connections... */
-#else
- cxflow[CXT_DIRECT] = FLO_NONE;
-#endif /* VMS */
-
-#ifdef CK_RTSCTS
- cxflow[CXT_MODEM] = FLO_RTSC; /* Modem connections... */
-#else
-#ifdef VMS
- cxflow[CXT_MODEM] = FLO_XONX;
-#else
- cxflow[CXT_MODEM] = FLO_NONE;
-#endif /* VMS */
-#endif /* CK_RTSCTS */
-
-#ifdef VMS
- cxflow[CXT_TCPIP] = FLO_XONX; /* TCP/IP connections... */
-#else
- cxflow[CXT_TCPIP] = FLO_NONE;
-#endif /* VMS */
-
- cxflow[CXT_SSH] = FLO_NONE;
- cxflow[CXT_X25] = FLO_NONE; /* Other kinds of networks... */
- cxflow[CXT_DECNET] = FLO_XONX;
- cxflow[CXT_LAT] = FLO_XONX;
- cxflow[CXT_NETBIOS] = FLO_NONE;
- cxflow[CXT_NPIPE] = FLO_NONE;
- cxflow[CXT_PIPE] = FLO_NONE;
- flow = cxflow[cxtype]; /* Initial flow setting. */
- debug(F101,"initflow","",flow);
-}
-
-#ifndef NOXFER
-/* Initialize file transfer protocols */
-
-VOID
-initproto(y, upbstr, uptstr, srvstr, sndbstr, sndtstr, rcvbstr, rcvtstr)
- int y;
- char * upbstr, * uptstr, * srvstr, * sndbstr, * sndtstr, * rcvbstr,
- * rcvtstr;
-/* initproto */ {
-
- if (upbstr) /* Convert null strings */
- if (!*upbstr) /* to null pointers */
- upbstr = NULL;
-
- if (uptstr) /* Convert null strings */
- if (!*uptstr) /* to null pointers */
- uptstr = NULL;
-
- if (sndbstr)
- if (!*sndbstr)
- sndbstr = NULL;
-
- if (sndtstr)
- if (!*sndtstr)
- sndtstr = NULL;
-
- if (rcvbstr)
- if (!*rcvbstr)
- rcvbstr = NULL;
-
- if (rcvtstr)
- if (!*rcvtstr)
- rcvtstr = NULL;
-
- if (srvstr)
- if (!*srvstr)
- srvstr = NULL;
-
- protocol = y; /* Set protocol */
-
- if (ptab[protocol].rpktlen > -1)
- urpsiz = ptab[protocol].rpktlen;
- if (ptab[protocol].spktflg > -1)
- spsizf = ptab[protocol].spktflg;
- if (ptab[protocol].spktlen > -1) {
- spsiz = ptab[protocol].spktlen;
- debug(F101,"initproto spsiz","",spsiz);
- if (spsizf) {
- spsizr = spmax = spsiz;
- debug(F101,"initproto spsizr","",spsizr);
- }
- }
- if (ptab[protocol].winsize > -1)
- wslotr = ptab[protocol].winsize;
- if (ptab[protocol].prefix > -1)
- prefixing = ptab[protocol].prefix;
- if (ptab[protocol].fnca > -1)
- fncact = ptab[protocol].fnca;
- if (ptab[protocol].fncn > -1)
- fncnv = ptab[protocol].fncn;
- if (ptab[protocol].fnsp > -1)
- fnspath = ptab[protocol].fnsp;
- if (ptab[protocol].fnrp > -1)
- fnrpath = ptab[protocol].fnrp;
-
- makestr(&(ptab[protocol].h_b_init),upbstr);
- makestr(&(ptab[protocol].h_t_init),uptstr);
- makestr(&(ptab[protocol].h_x_init),srvstr);
- makestr(&(ptab[protocol].p_b_scmd),sndbstr);
- makestr(&(ptab[protocol].p_t_scmd),sndtstr);
- makestr(&(ptab[protocol].p_b_rcmd),rcvbstr);
- makestr(&(ptab[protocol].p_t_rcmd),rcvtstr);
-}
-#endif /* NOXFER */
-
-#ifndef NOCMDL
-VOID
-#ifdef CK_ANSIC
-docmdline(void * threadinfo)
-#else /* CK_ANSIC */
-docmdline(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- setint();
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug( F100, "docmdline called with threadinfo block", "", 0 );
- } else
- debug( F100, "docmdline threadinfo is NULL","",0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef NT
-#ifdef IKSD
- if (inserver)
- setntcreds();
-#endif /* IKSD */
-#endif /* NT */
-#endif /* CK_LOGIN */
- proto(); /* Take any requested action, then */
- if (!quiet) /* put cursor back at left margin, */
- conoll("");
-#ifndef NOLOCAL
- if (cnflg) { /* Re-connect if requested */
- cnflg = 0;
- doconect(0,0);
- if (ttchk() < 0)
- dologend();
- }
-#endif /* NOLOCAL */
-
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
-}
-
-void
-ikslogin() {
- if (sstelnet
-#ifdef IKSD
- || inserver /* Internet server */
-#endif /* IKSD */
- ) {
- char *s;
- extern int fdispla; /* File-transfer display format */
- extern char * ikprompt; /* IKSD prompt */
-
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver) {
- x_login = 1; /* Login required */
- x_logged = 0; /* Not logged in yet */
- cmsetp(ikprompt); /* Set up IKSD's prompt */
-#ifndef NOSERVER
- en_mai = 0; /* MAIL is disabled */
- en_who = 0; /* REMOTE WHO is disabled */
- en_hos = 0; /* REMOTE HOST is disabled */
- en_pri = 0; /* PRINT is disabled */
-#endif /* NOSERVER */
- } else {
- x_login = 0; /* Login not required */
- x_logged = 1; /* Already logged in */
- }
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- nolocal = 1; /* SET LINE/HOST not allowed */
- fdispla = XYFD_N; /* No file-transfer display */
-#ifdef NETCONN
- clienthost = ckgetpeer(); /* Get client's hostname */
- debug(F110,"ikslogin clienthost",clienthost,0);
-#endif /* NETCONN */
- ztime(&s); /* Get current date and time */
-
-#ifdef CK_LOGIN
-#ifdef CK_AUTHENTICATION
- if (x_login) {
- x_logged = ck_tn_auth_valid(); /* Did Telnet Auth succeed? */
- debug(F111,"ikslogin","x_logged",x_logged);
-
-#ifdef NT
- /* On Windows 9x, we do not have the ability in */
- /* zvuser() at present to determine if the name */
- /* approved in a Kerberos principal is really a */
- /* an account in the Windows Access Control List */
- if (isWin95() && x_logged == AUTH_VALID
- && (ck_tn_authenticated() != AUTHTYPE_NTLM)
-#ifdef CK_SRP
- && (ck_tn_authenticated() != AUTHTYPE_SRP)
-#endif /* CK_SRP */
- ) {
- auth_finished(AUTH_USER);
- x_logged = AUTH_USER;
- printf("WARNING:\r\n");
- printf(
-" The Telnet authentication method used cannot provide for automated\r\n");
- printf(
-" login to Windows 95 or Windows 98. A password must be entered\r\n");
- printf(
-" locally to validate your userid. Telnet authentication (and encryption)\r\n"
- );
- printf(
-" can be used to validate the host (and protect the privacy of your password.)\
-\r\n"
- );
- }
-#endif /* NT */
-
- if (x_logged == AUTH_VALID) {
-#ifdef CK_SSL
- if ((ssl_active_flag || tls_active_flag) &&
- (!TELOPT_U(TELOPT_AUTHENTICATION) ||
- ck_tn_authenticated() == AUTHTYPE_NULL ||
- ck_tn_authenticated() == AUTHTYPE_AUTO)
- ) {
-#ifdef SSL_KRB5
- if (tls_is_krb5(0)) {
- printf("Authenticated using Kerberos 5\r\n");
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- extern char szUserNameAuthenticated[];
- cksyslog(SYSLG_LI, 1, "AUTH_VALID",
- "Kerberos 5",
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- } else
-#endif /* SSL_KRB5 */
- {
- printf("Authenticated using X.509 certificate\r\n");
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- extern char szUserNameAuthenticated[];
- cksyslog(SYSLG_LI, 1, "AUTH_VALID",
- "X.509 certificate",
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- }
- } else
-#endif /* CK_SSL */
- {
- printf("Authenticated using %s\r\n",
- AUTHTYPE_NAME(ck_tn_authenticated()));
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- extern char szUserNameAuthenticated[];
- cksyslog(SYSLG_LI, 1, "AUTH_VALID",
- AUTHTYPE_NAME(ck_tn_authenticated()),
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- }
- zvuser(uidbuf);
- if (zvpass("") == 0)
- x_logged = 0;
- } else if (x_logged == AUTH_USER && !strcmp(uidbuf,"anonymous")) {
- extern char szUserNameAuthenticated[];
- zvuser(uidbuf);
- debug(F110,"szUserNameAuthenticated",
- szUserNameAuthenticated,0);
- if (zvpass(szUserNameAuthenticated) == 0) {
- /* Anonymous login failed. Force a username prompt. */
- x_logged = 0;
- uidbuf[0] = '\0';
- } else {
-#ifdef CK_SSL
- if ((ssl_active_flag || tls_active_flag) &&
- (!TELOPT_U(TELOPT_AUTHENTICATION) ||
- ck_tn_authenticated() == AUTHTYPE_NULL ||
- ck_tn_authenticated() == AUTHTYPE_AUTO)) {
- printf("Authenticated using X.509 certificate\r\n");
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- extern char szUserNameAuthenticated[];
- cksyslog(SYSLG_LI, 1, "AUTH_USER",
- "X.509 certificate",
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- } else
-#endif /* CK_SSL */
- {
- printf("Authenticated using %s\r\n",
- AUTHTYPE_NAME(ck_tn_authenticated())
- );
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- cksyslog(SYSLG_LI, 1, "AUTH_USER",
- AUTHTYPE_NAME(ck_tn_authenticated()),
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- }
- }
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging &&
- x_logged == AUTH_USER) {
- extern char szUserNameAuthenticated[];
- cksyslog(SYSLG_LI, 1, "AUTH_USER",
- AUTHTYPE_NAME(ck_tn_authenticated()),
- szUserNameAuthenticated
- );
- }
-#endif /* CKSYSLOG */
- x_logged = 0;
- if (!strcmp("(unknown)",uidbuf)
-#ifdef NT
- || !stricmp("administrator",uidbuf)
-#ifdef UNIX
- || !strcmp("root",uidbuf)
-#else
-#ifdef Plan9
- || !strcmp("root",uidbuf)
-#else
-#ifdef OSK
- || !strcmp("root",uidbuf)
-#endif /* OSK */
-#endif /* Plan9 */
-#endif /* UNIX */
-#endif /* NT */
- )
- uidbuf[0] = '\0';
- }
- }
-#endif /* CK_AUTHENTICATION */
-#endif /* CK_LOGIN */
-
-#ifdef IKSD
- if (inserver)
- printf("\r\nInternet Kermit Service ready at %s%s\r\n",s,versio);
- else
-#endif /* IKSD */
- printf("\r\nC-Kermit ready at %s%s\r\n",s,versio);
- if (*myhost)
- printf("%s\r\n", myhost);
- printf("\r\n");
- }
-#ifdef CK_LOGIN
-#ifdef IKSD
- if (inserver) {
- int i;
- extern int arg_x; /* Flag for '-x' on command line */
-#ifndef NOSPL
- extern struct mtab *mactab; /* For ON_LOGIN macro. */
- extern int nmac;
-#endif /* NOSPL */
-
- debug(F110,"MAIN clienthost",clienthost,0);
- srvidl = timelimit = logintimo; /* For interactive login */
- rtimer(); /* Reset timer */
- for (i = 0; i < iks_retry && !x_logged; i++) { /* Count retries */
- if (gtimer() > logintimo)
- break;
-#ifdef TNCODE
- tn_wait("login loop");
- tn_push();
-#endif /* TNCODE */
- debug(F101,"MAIN LOGIN try","",i);
- what = W_NOTHING; /* Because proto() changes this */
-
-#ifdef IKS_OPTION
- debug(F111,"MAIN LOGIN",
- "TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start
- );
- /* Kermit server negotiated */
- if (TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- debug(F101,"IKSD starting in server mode","",0);
- arg_x = 1; /* Enter server mode */
- sstate = 'x';
-#ifdef IKSDPOPBACK
- justone = 1; /* Execute one command at a time. */
-#endif /* IKSDPOPBACK */
- proto(); /* Enter protocol if requested. */
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- if (x_logged) /* Logged in */
- break;
- } else { /* Not in client/server mode */
-#endif /* IKS_OPTION */
- debug(F101,"IKSD starting with Username prompt","",0);
- x_logged = ckxlogin((CHAR *)uidbuf,NULL,NULL,1);
- if (sstate) { /* Received a packet at prompt */
-#ifdef IKSDPOPBACK
- justone = 1; /* Go handle it */
-#endif /* IKSDPOPBACK */
- proto();
- }
- if (!x_logged) { /* In case we are at the prompt... */
- printf("Access denied.\n");
- uidbuf[0] = '\0'; /* Forget the name if we have one */
- }
-#ifdef IKS_OPTION
- }
-#endif /* IKS_OPTION */
- }
- srvidl = timelimit = iks_timo; /* Reset command timelimit */
- debug(F101,"MAIN LOGIN","",x_logged);
- if (!x_logged) { /* Logins failed. */
- if (TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
- errpkt((CHAR *)"Login Timeout");
- msleep(500);
- doexit(BAD_EXIT,0);
- }
- what = W_NOTHING; /* Stay in known state */
-#ifndef NOSERVER
- if (isguest) {
- en_pri = 0; /* No printing for anonymous users */
- en_mai = 0; /* No email for anonymous users */
- en_mkd = 0; /* Or directory creation */
- en_rmd = 0; /* Or directory removal */
- en_ena = 0; /* Or ENABLing DISABLEd items */
- }
-#endif /* NOSERVER */
-
-#ifndef NOSPL
-/*
- If a macro named "on_login" is defined, execute it. Also remove it from the
- macro table so the user cannot see what it does. Execute it as part of the
- iksd.conf file.
-*/
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- char * cmd = "on_login"; /* MSVC 2.x compiler error */
- k = mlook(mactab,cmd,nmac); /* Look up "on_login" */
- if (k >= 0) { /* If found, */
-#ifdef IKSDCONF
- int saved = iksdcf;
- iksdcf = 0;
-#endif /* IKSDCONF */
- if (dodo(k,"",0) > -1) /* set it up, */
- parser(1); /* execute it */
-#ifdef IKSDCONF
- iksdcf = saved;
-#endif /* IKSDCONF */
- delmac(cmd,1); /* and delete it */
- }
- }
-#endif /* NOSPL */
- } /* if (inserver) */
-#else /* CK_LOGIN */
- if (inserver)
- srvidl = timelimit = iks_timo; /* Set idle limits for IKS */
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-}
-
-VOID
-#ifdef CK_ANSIC
-failcmdline(void * foo)
-#else /* CK_ANSIC */
-failcmdline(foo) VOID * foo;
-#endif /* CK_ANSIC */
-{
-#ifdef GEMDOS
- cc_clean();
-#endif /* GEMDOS */
-#ifndef NOLOCAL
- if (cnflg) doconect(0,0); /* connect again if requested. */
- if (ttchk() < 0)
- dologend();
-#endif /* NOLOCAL */
-}
-#endif /* NOCMDL */
-
-#ifndef NOICP
-VOID
-#ifdef CK_ANSIC
-dotakeini(void * threadinfo) /* Execute init file. */
-#else /* CK_ANSIC */
-dotakeini(threadinfo) VOID * threadinfo; /* Execute init file. */
-#endif /* CK_ANSIC */
-/* dotakeini */ {
-#ifdef NTSIG
- setint();
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "dotakeini called with threadinfo block","", 0);
- } else
- debug(F100, "dotakeini - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef NT
-#ifdef IKSD
- if (inserver)
- setntcreds();
-#endif /* IKSD */
-#endif /* NT */
-#endif /* CK_LOGIN */
- cmdini(); /* Sets tlevel */
-
- debug(F111,"dotakeini","inserver",inserver);
- debug(F111,"dotakeini","sstelnet",sstelnet);
-
-#ifdef COMMENT
-/* Wrong place for this... */
-#ifndef NOXFER
-#ifdef CK_FAST
- dofast(); /* By now FAST defaults should be OK */
-#endif /* CK_FAST */
-#endif /* NOXFER */
-#endif /* COMMENT */
-
- doinit(); /* Now do the initialization file */
- debug(F101,"main executing init file","",tlevel);
- while (tlevel > -1) {
- sstate = (CHAR) parser(1); /* Execute one command at a time. */
- if (sstate) proto(); /* Enter protocol if requested. */
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- }
- debug(F101,"main exits init file","",tlevel);
-
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
-}
-
-VOID
-#ifdef CK_ANSIC
-failtakeini(void * threadinfo)
-#else /* CK_ANSIC */
-failtakeini(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* failtakeini */ {
-#ifdef GEMDOS
- cc_clean(); /* Atari: Clean up after ^C-trap. */
-#endif /* GEMDOS */
- fixcmd();
- if (!cfilef) {
- conoll("Interrupted during initialization or \
-command-line processing.");
- conoll("C-Kermit quitting...");
- }
- doexit(BAD_EXIT,-1); /* Exit with bad status. */
-}
-
-VOID
-#ifdef CK_ANSIC
-doicp(void * threadinfo)
-#else /* CK_ANSIC */
-doicp(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* doicp */ {
-#ifdef NTSIG
- setint();
- if (threadinfo) { /* Thread local storage... */
- if (!TlsSetValue(TlsIndex,threadinfo))
- debug(F101,"doicp TlsSetValue failed","",GetLastError());
- debug(F101, "doicp a threadinfo block - TlsIndex", "", TlsIndex);
- } else {
- debug(F100, "doicp received a null threadinfo", "", 0);
- }
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef NT
-#ifdef IKSD
- if (inserver)
- setntcreds();
-#endif /* IKSD */
-#endif /* NT */
-#endif /* CK_LOGIN */
-#ifdef MAC
- while (1) {
- extern char *lfiles; /* Fake pointer cast */
-
- if (connected) {
- debug(F100, "doicp: calling macparser", "", 0);
- sstate = newparser(1, 1, 0L);
-
- /* ignore null command state */
- if (sstate == 'n')
- sstate = '\0';
-
- if (sstate)
- proto();
- } else {
- /*
- * process take files the finder gave us.
- */
- if ((tlevel == -1) && lfiles)
- startlfile();
-
- debug(F100, "doicp: calling parser", "", 0);
- sstate = (CHAR) parser(0);
- if (sstate == 'c') /* if MAC connect */
- sstate = 0;
- if (sstate)
- proto();
- }
- }
-#else /* Not MAC */
-
-#ifndef NOSPL
-/*
- If interactive commands were given on the command line (using the
- -C "command, command, ..." option), assign them to a macro called
- "cl_commands", then execute the macro and leave it defined for
- subsequent re-execution if desired.
-*/
- if (clcmds) { /* Check for -C commands */
- int x;
- x = addmac("cl_commands",clcmds); /* Put macro in table */
- if (x > -1) { /* If successful, */
- dodo(x,NULL,CF_CMDL); /* set up for macro execution */
- while (maclvl > -1) { /* Loop getting macro commands. */
- sstate = (CHAR) parser(1);
- if (sstate) proto(); /* Enter protocol if requested. */
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- }
- }
- debug(F100,"doicp calling herald","",0);
- herald();
- }
-#endif /* NOSPL */
- while(1) { /* Loop getting commands. */
- sstate = (CHAR) parser(0);
- if (sstate) proto(); /* Enter protocol if requested. */
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- }
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
-#endif /* MAC */
-}
-
-VOID
-#ifdef CK_ANSIC
-failicp(void * threadinfo)
-#else /* CK_ANSIC */
-failicp(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef GEMDOS
- cc_clean();
-#endif /* GEMDOS */
- fixcmd(); /* Pop command stacks, etc. */
- clcmds = NULL;
- debug(F100,"ckcmai got interrupt","",0);
-}
-#endif /* NOICP */
-
-#ifndef NOICP
-VOID
-#ifdef CK_ANSIC
-docmdfile(void * threadinfo) /* Execute application file */
-#else /* CK_ANSIC */
-docmdfile(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* docmdfile */ {
-#ifdef NTSIG
- concb((char)escape);
- setint();
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
- debug(F110,"main cmdfil",cmdfil,0);
-#ifndef NOSPL
- addmac("\\%0",cmdfil);
-#endif /* NOSPL */
- dotake(cmdfil); /* Set up the command file */
- if (tlevel > -1) /* Remember we did this */
- cfilef = 1;
- while (tlevel > -1) { /* Execute it until it runs out. */
- sstate = parser(1); /* Loop getting commands. */
- if (sstate) proto(); /* Enter protocol if requested. */
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- }
-
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
-}
-
-VOID
-#ifdef CK_ANSIC
-failcmdfile(void * threadinfo)
-#else /* CK_ANSIC */
-failcmdfile(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* failcmdfile */ {
-#ifdef GEMDOS
- cc_clean(); /* Atari: Clean up after ^C-trap. */
-#endif /* GEMDOS */
- fixcmd();
- if (!cfilef) {
- conoll("Interrupted during initialization or \
-command-line processing.");
- conoll("C-Kermit quitting...");
- }
- doexit(BAD_EXIT,-1); /* Exit with bad status. */
-}
-#endif /* NOICP */
-
-#ifndef NOXFER
-VOID
-setprefix(z) int z; { /* Initial control-char prefixing */
-#ifdef CK_SPEED
- int i, val;
-
- prefixing = z;
- ptab[protocol].prefix = prefixing;
- debug(F101,"setprefix","",prefixing);
- switch (z) {
- case PX_ALL: /* All */
-#ifdef COMMENT
- /* Don't let Clear-Channel be dependent on prefixing */
- clearrq = 0; /* Turn off clearchannel, fall thru */
-#endif /* COMMENT */
- case PX_NON: /* None */
- val = (z == PX_ALL) ? 1 : 0;
- for (i =
-#ifdef UNPREFIXZERO
- 0
-#else
- 1
-#endif /* UNPREFIXZERO */
- ; i < 32; i++)
- ctlp[i] = val;
- for (i = 127; i < 160; i++) ctlp[i] = val;
- ctlp[(unsigned)255] = val;
- if (z == PX_NON) { /* These are never safe */
- if (network) { /* Assume network = telnet or rlogin */
- ctlp[CR] = 1; /* Prefix CR because of NVT rules */
- ctlp[XON] = ctlp[XOFF] = 1; /* Because of Telnet server */
- ctlp[127] = ctlp[255] = 1; /* Telnet IAC */
- ctlp[mystch] = ctlp[mystch+128] = 1; /* Kermit packet start */
- } else {
- ctlp[CR] = ctlp[255] = ctlp[mystch] = ctlp[mystch+128] = 1;
- if (flow == FLO_XONX) /* Xon/Xoff forces prefixing */
- ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
- }
- }
- break;
-
- case PX_CAU: /* Cautious or Minimal */
-#ifdef COMMENT
- /* Don't let CLEAR-CHANNEL be dependent on Prefixing */
- clearrq = 0; /* Turn off clearchannel */
-#endif /* COMMENT */
- case PX_WIL: /* Minimal ("wild") */
- ctlp[0] = 1; /* Does not include 0 */
- for (i = 1; i < 32; i++)
- ctlp[i] = 0;
- for (i = 127; i < 160; i++)
- ctlp[i] = 0;
- ctlp[mystch] = ctlp[mystch+128] = 1; /* Kermit start of packet */
- if (seol != 13)
- ctlp[seol] = ctlp[seol+128] = 1; /* Kermit end */
- ctlp[13] = ctlp[141] = 1; /* In case of TELNET (NVT rules) */
- ctlp[(unsigned)255] = 1; /* Ditto */
-
- /* ^D, ^J, ^M, or ^U followed by tilde trigger Rlogin escape */
-
- ctlp[4] = ctlp[4+128] = 1; /* In case of RLOGIN */
- ctlp[10] = ctlp[10+128] = 1; /* In case of RLOGIN */
- ctlp[21] = ctlp[21+128] = 1; /* In case of RLOGIN */
-
- if (flow == FLO_XONX || /* Xon/Xoff forces prefixing these */
- prefixing == PX_CAU || /* So does CAUTIOUS */
- network) /* Networks too... */
- ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
- if (prefixing == PX_CAU) { /* Cautious - add some more */
-#ifdef UNPREFIXZERO
- ctlp[0] = 1;
-#endif /* UNPREFIXZERO */
- ctlp[3] = ctlp[16] = 1; /* ^C, DLE */
- ctlp[14] = ctlp[15] = 1; /* SO/SI */
- ctlp[24] = ctlp[25] = 1; /* VMS might need these */
- ctlp[26] = ctlp[26+128] = 1; /* UNIX suspend */
- ctlp[28] = ctlp[29] = ctlp[30] = 1; /* Assorted esc chars */
- ctlp[131] = ctlp[141] = ctlp[144] = 1; /* and 8-bit versions */
- ctlp[(unsigned)255] = ctlp[156] = ctlp[157] = ctlp[158] = 1;
- }
- break;
- }
-#endif /* CK_SPEED */
-}
-#endif /* NOXFER */
-
-VOID
-makever() { /* Make version string from pieces */
- int x, y;
- char * s;
-#ifndef OS2
-#ifndef MAC
- ck_s_xver = ck_s_ver; /* Fill in C-Kermit version number */
- ck_l_xver = ck_l_ver; /* for UNIX, VMS, etc. */
-#endif /* MAC */
-#endif /* OS2 */
- x = strlen(ck_s_name);
- y = strlen(ck_s_xver);
- if (y + x + 1 < CKVERLEN) {
- ckmakmsg(versio,CKVERLEN,ck_s_name," ",ck_s_xver,NULL);
- } else {
- ckstrncpy(versio,"C-Kermit",CKVERLEN);
- return;
- }
- x += y + 1;
-
- s = " OPEN SOURCE:"; /* C-Kermit 9.0 and later */
- y = strlen(s);
- if (CKVERLEN < x + y + 1)
- return;
- ckstrncat(versio,s,CKVERLEN);
-
- x += y + 1;
- if (*ck_s_who) {
- y = strlen(ck_s_who);
- if (CKVERLEN < x + y + 1)
- return;
- ckstrncat(versio,"-",CKVERLEN);
- ckstrncat(versio,ck_s_who,CKVERLEN);
- }
- x += y + 1;
- y = strlen(ck_s_test);
- if (y > 0 && y + x + 1 < CKVERLEN) {
- ckstrncat(versio," ",CKVERLEN);
- ckstrncat(versio,ck_s_test,CKVERLEN);
- x += y + 1;
- y = strlen(ck_s_tver);
- if (y > 0 && y + x + 1 < CKVERLEN) {
- ckstrncat(versio,".",CKVERLEN);
- ckstrncat(versio,ck_s_tver,CKVERLEN);
- x += y + 1;
- }
- }
- y = strlen(ck_s_date);
- if (y > 0 && y + x + 2 < CKVERLEN) {
- ckstrncat(versio,", ",CKVERLEN);
- ckstrncat(versio,ck_s_date,CKVERLEN);
- }
- vernum = ck_l_ver;
- xvernum = ck_l_xver;
- debug(F110,"Kermit version",versio,0);
-}
-
-union ck_short shortbytes; /* For determining byte order */
-int byteorder = 0; /* 0 = Big Endian; 1 = Little Endian */
-int bigendian = 1;
-/* NOTE: MUST BE 0 or 1 - nothing else */
-
-#ifndef NOSPL
-#define SCRIPTLEN 10240
-#endif /* NOSPL */
-
-#ifdef NETCONN
-#ifndef NOCMDL
-#ifndef NOURL
-VOID
-dourl() {
- int rc = 0;
- char * port = NULL;
- extern int ttnproto;
- extern struct urldata g_url;
-
-#ifdef COMMENT
- /* NOTE: debug() doesn't work yet - must use printf's */
- printf("URL: %s\n",g_url.sav ? g_url.sav : "(none)");
- printf("Type: %s\n",g_url.svc ? g_url.svc : "(none)");
- printf("User: %s\n",g_url.usr ? g_url.usr : "(none)");
- printf("Pass: %s\n",g_url.psw ? g_url.psw : "(none)");
- printf("Host: %s\n",g_url.hos ? g_url.hos : "(none)");
-/* printf("Port: %s\n",g_url.por ? g_url.por : "(none)"); */
- printf("Path: %s\n",g_url.pth ? g_url.pth : "(none)");
-#endif /* COMMENT */
-
- if (!ckstrcmp(g_url.svc,"iksd",-1,0) ||
- !ckstrcmp(g_url.svc,"kermit",-1,0)) {
- extern char pwbuf[];
- extern int pwflg;
-#ifdef OS2
- extern int pwcrypt;
-#endif /* OS2 */
-
- if (!g_url.hos) {
- printf("?Incomplete IKSD URL\n");
- doexit(BAD_EXIT,1);
- }
- if (!g_url.usr)
- makestr(&g_url.usr,"anonymous");
- if (!g_url.psw) {
- char * tmpbuf = NULL;
- if (!(tmpbuf = (char *)malloc(1024)))
- fatal("dourl: out of memory");
- if (!ckstrcmp(g_url.usr,"anonymous",-1,0)) {
- ckmakmsg(tmpbuf,1024,uidbuf,"@",myhost,NULL);
- makestr(&g_url.psw,tmpbuf);
- } else {
- readpass(" Password:",tmpbuf,1024);
- makestr(&g_url.psw,tmpbuf);
- }
- free(tmpbuf);
- }
- port = "kermit";
- ttnproto = NP_TELNET;
- nettype = NET_TCPB;
- mdmtyp = -nettype;
- local = -1;
- ckstrncpy(uidbuf,g_url.usr,UIDBUFLEN);
- if (g_url.psw) {
- ckstrncpy(pwbuf,g_url.psw,PWBUFL);
- pwflg = 1;
-#ifdef OS2
- pwcrypt = 0;
-#endif /* OS2 */
- }
- ckmakmsg(ttname,
- TTNAMLEN,
- g_url.hos,
- ":",
- g_url.por ? g_url.por : port,
- NULL
- );
- rc = ttopen(ttname,&local,mdmtyp,0);
- if (rc > -1) {
- network = 1;
- exitonclose = 1;
-#ifdef CKLOGDIAL
- dolognet();
-#endif /* CKLOGDIAL */
- } else {
- printf("?Connection failed: %s\n",g_url.sav);
- doexit(BAD_EXIT,1);
- }
- /* Also need to check here for secure authentication already done */
-
-#ifdef NOSPL
- cflg = 1;
-#else
- {
- char * script = NULL;
- if (!(script = (char *)malloc(SCRIPTLEN)))
- fatal("dourl: out of memory");
- if (!g_url.pth) { /* Write the appropriate script */
- cflg = 1;
- ckmakxmsg(script,SCRIPTLEN,
- "if not eq {\\v(authstate)} {user} ",
- "if not eq {\\v(authstate)} {valid} { ",
- "remote login ", /* No path */
- g_url.usr, /* Just log in and CONNECT */
- " ",
- g_url.psw,
- ", if fail exit 1 {IKSD login failed} }",
- ", connect",
- NULL,NULL,NULL,NULL);
- /* printf("CLCMDS 1: %s\n",script); */
- } else {
- /* does the path specify a file or a directory? */
- int len = strlen(g_url.pth);
- if (ISDIRSEP(g_url.pth[len-1])) {
- ckmakxmsg(script,SCRIPTLEN, /* Directory name given */
- "if not eq {\\v(authstate)} {user} \
-if not eq {\\v(authstate)} {valid} { remote login ",
- g_url.usr,
- " ",
- g_url.psw,
- ", if fail exit 1 {IKSD login failed} }",
- ", set macro error on",
- ", set xfer displ brief",
- ", set xfer bell off",
- ", remote cd ",
- g_url.pth,
- ", lineout directory",
- ", connect"
- );
- /* printf("CLCMDS 2: %s\n",script); */
- } else {
- ckmakxmsg(script,SCRIPTLEN, /* Path given, try to GET */
- "if not eq {\\v(authstate)} {user} \
-if not eq {\\v(authstate)} {valid} { remote login ",
- g_url.usr,
- " ",
- g_url.psw,
- ", if fail exit 1 {IKSD login failed} }",
- ", set xfer displ brief",
- ", set xfer bell off",
- ", get ",
- g_url.pth,
- ", .rc := \\v(status)",
- ", if open connection bye",
- ", exit \\m(rc)"
- );
- /* printf("CLCMDS 2: %s\n",script); */
- }
- }
- clcmds = script; /* Make this our -C cmdline macro */
- /* printf("HAVEURL=%d\n",haveurl); */
- }
-#endif /* NOSPL */
- } else {
- if (ckstrcmp(g_url.svc,"telnet",-1,0) &&
-#ifdef SSHBUILTIN
- ckstrcmp(g_url.svc,"ssh",-1,0) &&
-#endif /* SSHBUILTIN */
- ckstrcmp(g_url.svc,"ftp",-1,0)) {
- printf("?Sorry, %s URLs not supported\n",
- g_url.svc ? g_url.svc : "");
- doexit(BAD_EXIT,1);
- }
- }
-}
-#endif /* NOCMDL */
-#endif /* NETCONN */
-#endif /* NOURL */
-
-/*
- main()...
-
- If you get complaints about "main: return type is not blah",
- define MAINTYPE on the CC command line, e.g. "CFLAGS=-DMAINTYPE=blah"
- (where "blah" is int, long, or whatever).
-
- If the complaint is "Attempt to return a value from a function of type void"
- then add -DMAINISVOID.
-*/
-#ifndef MAINTYPE
-#ifndef MAINISVOID
-#define MAINTYPE int
-#endif /* MAINISVOID */
-#endif /* MAINTYPE */
-
-#ifdef MAINISVOID
-#ifndef MAINTYPE
-#define MAINTYPE void
-#endif /* MAINTYPE */
-#endif /* MAINISVOID */
-
-#ifdef aegis
-/* On the Apollo, intercept main to insert a cleanup handler */
-int
-ckcmai(argc,argv) int argc; char **argv;
-#else
-#ifdef MAC /* Macintosh */
-int
-main (void)
-#else
-#ifdef __GNUC__ /* GCC compiler */
-int
-main(argc,argv) int argc; char **argv;
-#else
-#ifdef __DECC /* DEC Alpha with DEC C compiler */
-#ifdef __ALPHA
-int
-main(argc,argv) int argc; char **argv;
-#else /* DEC C compiler, not Alpha */
-#define MAINISVOID
-VOID
-main(argc,argv) int argc; char **argv;
-#endif /* __ALPHA */
-#else
-#ifdef STRATUS /* Stratus VOS */
-int
-main(argc,argv) int argc; char **argv;
-#else /* K-95 */
-#ifdef OS2
-#ifdef KUI
-#define MAINISVOID
-void
-Main( int argc, char ** argv )
-#else /* KUI */
-#define MAINISVOID
-VOID
-main(argc,argv) int argc; char **argv;
-#endif /* KUI */
-#else /* Not K95 */
-MAINTYPE /* All others... */
-main(argc,argv) int argc; char **argv;
-#endif /* OS2 */
-#endif /* STRATUS */
-#endif /* __DECC */
-#endif /* __GNUC__ */
-#endif /* MAC */
-#endif /* aegis */
-
-/* main */ {
-
- char *p;
-
-#ifndef NOSETKEY
- int i;
-#endif /* NOSETKEY */
-
-#ifdef datageneral
- short *pfha = 016000000036; /* Get around LANG_RT problem */
- *pfha = (short) 0; /* No user protection fault handler */
-#endif /* datageneral */
-
- int unbuf = 0; /* nonzero for unbuffered stdout */
-
-/* setbuf has to be called on the file descriptor before it is used */
-
-#ifdef UNIX
-#ifdef NONOSETBUF /* Unbuffered console i/o */
- unbuf++; /* as a compile-time option */
-#endif /* NONOSETBUF */
- if (!unbuf) { /* Or as a command-line selection */
- int i, n; /* We have to pre-pre-scan for */
- char * s; /* this one. */
- for (i = 1; i < argc; i++) {
- s = argv[i];
- if (!s) n = 0; else n = (int)strlen(s);
- if (n > 4) {
- if (!ckstrcmp("--unbuffered",s,n,0)) {
- unbuf++;
- break;
- }
- }
- }
- }
- if (unbuf)
- setbuf(stdout,NULL);
-#endif /* UNIX */
-
-/* Do some initialization */
-
-#ifdef VMS
-#ifdef __DECC
- /* Get some RMS default settings. */
- get_rms_defaults();
-#endif /* def __DECC */
-#endif /* def VMS */
-
-#ifndef MAC
- xargc = xargs = argc; /* Make global copies of argc */
- xargv = argv; /* ...and argv. */
- xarg0 = argv[0];
-#ifdef NT
- setOSVer();
-#endif /* NT */
- zstrip(argv[0],&p); /* Get name we were invoked with */
- makestr(&myname,p);
- if (!ckstrcmp(myname,"telnet",-1,0)) howcalled = I_AM_TELNET;
-#ifdef CK_KERBEROS
- else if (!ckstrcmp(myname,"ktelnet",-1,0)) howcalled = I_AM_TELNET;
-#endif /* CK_KERBEROS */
- else if (!ckstrcmp(myname,"rlogin",-1,0)) howcalled = I_AM_RLOGIN;
- else if (!ckstrcmp(myname,"iksd",-1,0)) howcalled = I_AM_IKSD;
-#ifdef NEWFTP
- else if (!ckstrcmp(myname,"ftp",-1,0)) howcalled = I_AM_FTP;
-#endif /* NEWFTP */
-#ifndef NOHTTP
- else if (!ckstrcmp(myname,"http",-1,0)) howcalled = I_AM_HTTP;
-#endif /* NOHTTP */
-#ifdef OS2
- else if (!ckstrcmp(myname,"telnet.exe",-1,0)) howcalled = I_AM_TELNET;
-#ifdef SSHBUILTIN
- else if (!ckstrcmp(myname,"ssh",-1,0)) howcalled = I_AM_SSH;
- else if (!ckstrcmp(myname,"ssh.exe",-1,0)) howcalled = I_AM_SSH;
-#endif /* SSHBUILTIN */
-#ifdef CK_KERBEROS
- else if (!ckstrcmp(myname,"ktelnet.exe",-1,0)) howcalled = I_AM_TELNET;
-#endif /* CK_KERBEROS */
- else if (!ckstrcmp(myname,"rlogin.exe",-1,0)) howcalled = I_AM_RLOGIN;
-#ifdef NT
- else if (!ckstrcmp(myname,"iksdnt",-1,0)) howcalled = I_AM_IKSD;
- else if (!ckstrcmp(myname,"iksdnt.exe",-1,0)) howcalled = I_AM_IKSD;
-#endif /* NT */
-#ifdef NEWFTP
- else if (!ckstrcmp(myname,"ftp.exe",-1,0)) howcalled = I_AM_FTP;
-#endif /* NEWFTP */
-#ifndef NOHTTP
- else if (!ckstrcmp(myname,"http.exe",-1,0)) howcalled = I_AM_HTTP;
-#endif /* NOHTTP */
-#endif /* OS2 */
- else if (!ckstrcmp(myname,"kermit-sshsub",-1,0)) howcalled = I_AM_SSHSUB;
-
-#ifndef NOICP
- cmdini(); /* Must come before prescan */
- debug(F100,"main cmdini() done","",0);
-#endif /* NOICP */
- prescan(0); /* Pre-Check for debugging, etc */
-#endif /* MAC */
- debug(F101,"MAIN feol","",feol);
- makever(); /* Put together version strings */
-#ifndef NOSETKEY /* Allocate & initialize the keymap */
- /* This code has been moved to before sysinit() for K95G */
- if (!(keymap = (KEY *) malloc(sizeof(KEY)*KMSIZE)))
- fatal("main: no memory for keymap");
- if (!(macrotab = (MACRO *) malloc(sizeof(MACRO)*KMSIZE)))
- fatal("main: no memory for macrotab");
- for (i = 0; i < KMSIZE; i++) {
- keymap[i] = (KEY) i;
- macrotab[i] = NULL;
- }
-#endif /* NOSETKEY */
-
- shortbytes.x_short = 0xABCD; /* Get Endianness */
- if (shortbytes.x_char[0] == 0xCD) { /* 0 = Big Endian */
- byteorder = 1; /* 1 = Little Endian */
- bigendian = 0; /* (for clarity in programming) */
- } else {
- byteorder = 0; /* Big Endian */
- bigendian = 1;
- }
- if (sizeof(CK_OFF_T) == 8) /* Large files and ints? */
- havelfs = 1;
-
- if (sysinit() < 0) /* System-dependent initialization. */
- fatal("Can't initialize!");
- else
- initflg = 1; /* Remember we did. */
- debug(F111,"ckcmai myname",myname,howcalled);
-
-#ifdef UNIX
- getexedir(); /* Compute exedir variable */
-#endif /* UNIX */
-
-#ifdef CKSYSLOG
-#ifdef SYSLOGLEVEL
-/*
- If built with -DSYSLOGLEVEL on cc command line, this means we always
- do syslogging at the indicated level.
-*/
- zsyslog(); /* Open syslog */
-#else /* SYSLOGLEVEL */
-#ifdef IKSD
- if (inserver)
- zsyslog(); /* Open syslog */
-#endif /* IKSD */
-#endif /* SYSLOGLEVEL */
-#endif /* CKSYSLOG */
-
-#ifdef CK_KERBEROS
- ini_kerb(); /* Initialize Kerberos data */
-#endif /* CK_KERBEROS */
-#ifdef CK_SSL
- ssl_once_init();
-#endif /* CK_SSL */
-#ifdef TNCODE
- tn_set_modes(); /* Init Telnet Option tables */
-#endif /* TNCODE */
-
-#ifdef CK_TTGWSIZ /* Initialize screen dimensions */
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
-#ifndef OS2
-#ifdef TCPSOCKET
-#ifdef CK_SOCKS
- SOCKSinit(argv[0]); /* Internet relay package... */
-#endif /* CK_SOCKS */
-#endif /* TCPSOCKET */
-#endif /* OS2 */
-
- initflow(); /* Initialize flow-control table */
-
-#ifndef NOICP
-#ifdef CKFLOAT
- initfloat(); /* Deduce floating-point precision */
-#endif /* CKFLOAT */
-#endif /* NOICP */
-
-#ifndef NOXFER
- initxlist(); /* Init exception lists */
-
-#ifdef CK_XYZ /* Initialize protocols... */
-
-#ifdef XYZ_INTERNAL /* XYZMODEM are internal ... */
-
-#ifdef COMMENT
- /* Can't do this for XMODEM because if filename contains a "C" etc... */
- initproto(PROTO_X, "rx %s","rx %s", NULL, NULL, NULL, NULL, NULL);
- initproto(PROTO_XC,"rc %s","rc %s", NULL, NULL, NULL, NULL, NULL);
-#else /* COMMENT */
- initproto(PROTO_X, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- initproto(PROTO_XC,NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-#endif /* COMMENT */
- initproto(PROTO_Y, "rb","rb", NULL, NULL, NULL, NULL, NULL);
- initproto(PROTO_G, "rb","rb", NULL, NULL, NULL, NULL, NULL);
- initproto(PROTO_Z, "rz","rz", NULL, NULL, NULL, NULL, NULL);
- initproto(PROTO_K,"kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL);
- /* Kermit Must be last */
-
-#else /* XYZMODEM are external protocols ... */
-
- /* s1 s2 s3 s4 s5 s6 s7 */
- initproto(PROTO_X, "rx %s","rx %s",NULL,"sx %s","sx -a %s","rx %s", "rx %s");
- initproto(PROTO_XC,"rc %s","rc %s",NULL,"sx %s","sx -a %s","rc %s", "rc %s");
- initproto(PROTO_Y, "rb", "rb", NULL,"sb %s","sb -a %s","rb", "rb" );
- initproto(PROTO_G, "rb", "rb", NULL,"sb %s","sb -a %s","rb", "rb" );
- initproto(PROTO_Z, "rz", "rz", NULL,"sz %s","sz -a %s","rz", "rz" );
- initproto(PROTO_K, "kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL);
- /* Kermit must be last */
-
-#endif /* XYZ_INTERNAL */
-
-#else /* No XYZMODEM support */
-
- initproto(PROTO_K,"kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL);
-
-#endif /* CK_XYZ */
-#endif /* NOXFER */
-
- connoi(); /* Console interrupts off */
-
-#ifndef NOXFER
-#ifdef OS2
- /* Initialize Kermit and Zmodem Auto-Download Strings */
- adl_kstr = strdup("KERMIT READY TO SEND...");
- adl_zstr = strdup("rz\r");
-#endif /* OS2 */
-
-#ifdef PATTERNS
- initpat(); /* Initialize filename patterns */
-#endif /* PATTERNS */
-#endif /* NOXFER */
-
-#ifndef NOCSETS
- initcsets(); /* Initialize character sets */
-#endif /* NOCSETS */
-
-#ifndef NOICP
-#ifdef DFCDMSG
- makestr(&cdmsgstr,DFCDMSG);
- makelist(cdmsgstr,cdmsgfile,8); /* Initialize CD message filenames */
-#endif /* DFCDMSG */
-#endif /* NOICP */
-
- sstate = 0; /* No default start state. */
-#ifdef DYNAMIC
- if (getiobs() < 0)
- fatal("Can't allocate i/o buffers!");
-#endif /* DYNAMIC */
-
-#ifndef NOSPL
-#ifndef NORANDOM
- {
- char stackdata[256];
- unsigned int c = 1234, n;
- /* try to make a random unsigned int to feed srand() */
-#ifndef VMS
- /* time.h and MultiNet do not get along */
- c = time(NULL);
-#endif /* VMS */
- c *= getpid();
- /* Referenced before set... DELIBERATELY */
- for (n = 0; n < sizeof(stackdata); n++) /* IGNORE WARNING */
- c += stackdata[n]; /* DELIBERATELY USED BEFORE SET */
- srand((unsigned int)c);
- }
-#endif /* NORANDOM */
-#endif /* NOSPL */
-
- ckhost(myhost,MYHOSTL); /* Name of local host */
- debug(F110,"main ckhost",myhost,0);
-#ifdef IKSD
- if (!inserver) {
-#endif /* IKSD */
- ckstrncpy(ttname,dftty,TTNAMLEN); /* Set up default tty name. */
- local = nolocal ? 0 : dfloc; /* And whether it's local or remote. */
- parity = dfprty; /* Set initial parity, */
-#ifndef NOXFER
- myindex = getsysix(cksysid); /* System index */
-#endif /* NOXFER */
- if (local) if (ttopen(ttname,&local,0,0) < 0) {
-#ifndef OS2
- conol("Can't open device: ");
- conoll(ttname);
-#endif /* OS2 */
- local = 0;
- ckstrncpy(ttname,CTTNAM,TTNAMLEN);
- }
- setflow(); /* Set appropriate flow control */
- speed = ttgspd(); /* Get transmission speed. */
-#ifdef IKSD
- }
-#endif /* IKSD */
-
-#ifdef ANYX25 /* All X.25 implementations */
-#ifndef IBMX25 /* except IBM have PAD support */
- initpad(); /* Initialize X.25 PAD */
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifndef NOXFER
- if (inibufs(SBSIZ,RBSIZ) < 0) /* Allocate packet buffers */
- fatal("Can't allocate packet buffers!");
-#ifndef NOCKSPEED
- setprefix(prefixing); /* Set up control char prefixing */
-#endif /* NOCKSPEED */
-#endif /* NOXFER */
-
-#ifndef NOICP
- if (sstelnet
-#ifdef IKSD
- || inserver
-#endif /* IKSD */
- ) {
- int on = 1, x = 0;
- extern int ckxech, ttnet, ttnproto, cmdmsk;
-#ifdef SO_SNDBUF
- extern int tcp_sendbuf;
-#endif
-#ifdef SO_RCVBUF
- extern int tcp_recvbuf;
-#endif
-#ifdef SO_KEEPALIVE
- extern int tcp_keepalive;
-#endif
-#ifdef SO_LINGER
- extern int tcp_linger, tcp_linger_tmo;
-#endif /* SO_LINGER */
-#ifdef SO_DONTROUTE
- extern int tcp_dontroute;
-#endif /* SO_DONTROUTE */
-#ifdef TCP_NODELAY
- extern int tcp_nodelay;
-#endif /* TCP_NODELAY */
-#ifdef IKSD
- extern int iklogopen;
-#endif /* IKSD */
- extern int ttmdm;
-
-#ifdef UNIX
- if (isatty(0))
- fatal("Internet Kermit Service cannot be started at a terminal.");
-#endif /* UNIX */
-
- reliable = xreliable = SET_ON; /* IKSD has reliable connection */
-#ifndef VMS
- flow = 0; /* No flow control needed */
-#endif /* VMS */
- bgset = 0; /* Not in background */
- nopush = 1; /* No external processes */
- parity = 0; /* 8 bits ... */
- cmdmsk = 0xff; /* all the way */
- cmask = 0xff;
-
-#ifdef IKSD
- if (inserver) { /* If IKSD */
- doiksdinit(); /* Execute IKSD configuration file */
- while (tlevel > -1)
- parser(1); /* (Ignore any file-xfer commands) */
- iksdcf = 1; /* IKSD c.f. has been processed */
- }
- if (!iklogopen) (VOID) doiklog(); /* Open Kermit-specific log */
-#endif /* IKSD */
-
-#ifdef UNIX
- setbuf(stdout,NULL); /* Don't buffer the output */
- ckstrncpy(ttname,"0",TTNAMLEN); /* not "/dev/tty"... */
-#endif /* UNIX */
- local = 0; /* We are in remote mode */
- ckxech = 1; /* We will echo */
-#ifdef OS2
- nettype = NET_TCPB; /* So ttopen() treats the connection */
- mdmtyp = -nettype; /* as a network */
-#endif /* OS2 */
- debug(F100,"main about to call ttopen() inserver","",0);
- if (ttopen(ttname,&local,mdmtyp,0) < 0) { /* Open comm channel */
- fatal("can't initialize i/o");
- }
-#ifdef OS2
- local = 0;
- network = 1; /* Does use networking code */
-#else /* OS2 */
- network = 0; /* Does not use networking code */
-#endif /* OS2 */
- ttmdm = -1; /* Does not use a modem */
- sstelnet = 1; /* Do server-side Telnet negotations */
- debug(F111,"MAIN","sstelnet",sstelnet);
- ttnet = NET_TCPB; /* Network type is TCP sockets */
- ttnproto = NP_TELNET; /* Netword protocol is Telnet */
-#ifdef IKSDB
- dbinit(); /* Initialize database record */
-#endif /* IKSDB */
-#ifndef OS2
-#ifdef CK_AUTHENTICATION
- /* Before initializating Telnet/Rlogin negotiations, init Kerberos */
- ck_auth_init(ckgetpeer(),"","",0);
-#endif /* CK_AUTHENTICATION */
-
-#ifdef NON_BLOCK_IO
- on = 1;
- x = socket_ioctl(0,FIONBIO,&on);
- debug(F101,"main FIONBIO","",x);
-#endif /* NON_BLOCK_IO */
-#ifdef SO_OOBINLINE
- on = 1;
- x = setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on));
- debug(F101,"main SO_OOBINLINE","",x);
-#endif /* SO_OOBINLINE */
-
-#ifndef NOTCPOPTS
-#ifndef datageneral
-#ifdef SOL_SOCKET
-#ifdef TCP_NODELAY
- no_delay(0,tcp_nodelay);
-#endif /* TCP_NODELAY */
-#ifdef SO_KEEPALIVE
- keepalive(0,tcp_keepalive);
-#endif /* SO_KEEPALIVE */
-#ifdef SO_LINGER
- ck_linger(0,tcp_linger, tcp_linger_tmo);
-#endif /* SO_LINGER */
-#ifdef SO_DONTROUTE
- dontroute(0,tcp_dontroute);
-#endif /* SO_DONTROUTE */
-#ifdef SO_SNDBUF
- sendbuf(0,tcp_sendbuf);
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
- recvbuf(0,tcp_recvbuf);
-#endif /* SO_RCVBUF */
-#endif /* SOL_SOCKET */
-#endif /* datageneral */
-#endif /* NOTCPOPTS */
-
-#ifdef CK_SSL
- if (ck_ssleay_is_installed()) {
- if (!ssl_tn_init(SSL_SERVER)) {
- if (bio_err != NULL) {
- BIO_printf(bio_err,"do_ssleay_init() failed\r\n");
- ERR_print_errors(bio_err);
- } else {
- fflush(stderr);
- fprintf(stderr,"do_ssleay_init() failed\r\n");
- ERR_print_errors_fp(stderr);
- }
- switch (ttnproto) {
- case NP_SSL:
- case NP_TLS:
- case NP_SSL_RAW:
- case NP_TLS_RAW:
- case NP_SSL_TELNET:
- case NP_TLS_TELNET:
- doexit(BAD_EXIT,1);
- }
- /* otherwise we will continue to accept the connection */
- /* without SSL or TLS support unless required. */
- if ( TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- } else {
- if ( ck_ssl_incoming(0) < 0 ) {
- doexit(BAD_EXIT,1);
- }
- }
- }
-#endif /* CK_SSL */
-
-#ifdef TNCODE
- tn_ini(); /* Start Telnet negotiation now */
-#endif /* TNCODE */
-#endif /* OS2 */
- }
- debug(F101,"main argc after prescan()","",argc);
-
- /* Now process any relevant environment variables */
-
-#ifndef NODIAL
- getdialenv(); /* Dialing */
-#ifdef NETCONN
- ndinit(); /* Initialize network directory info */
- getnetenv(); /* Network directories */
-#endif /* NETCONN */
-#endif /* NODIAL */
-
-#ifndef NOXFER
-#ifdef CK_FAST
- dofast(); /* By now FAST defaults should be OK */
-#endif /* CK_FAST */
-#endif /* NOXFER */
-
-#ifndef NOCMDL
- ikslogin(); /* IKSD Login and other stuff */
-#ifdef IKSD
-#ifdef NT
- if ( inserver )
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* NOCMDL */
-
- if (howcalled == I_AM_SSHSUB) {
- reliable = 1; /* We say the connection is reliable */
- xreliable = 1; /* And that we said it was */
- setreliable = 1; /* And pretend the "user" did too */
- xfinish = 1; /* For REMOTE HELP response */
- mdmtyp = 0; /* For ttopen() */
- ckstrncpy(ttname,"0",TTNAMLEN+1); /* Use file descriptor 0 */
- local = 0; /* And force remote mode */
- ttopen(ttname,&local,mdmtyp,0); /* Open the "connection" */
- sstate = 'x'; /* Initial state is Server */
- proto(); /* Enter protocol */
- doexit(GOOD_EXIT,xitsta); /* Exit when done */
- }
- debug(F111,"howcalled",myname,howcalled);
-
-#ifdef NOCCTRAP
- dotakeini(0);
-#else /* NOCCTRAP */
- debug(F100,"main about to cc_execute","",0);
- setint();
- cc_execute( ckjaddr(cmjbuf), dotakeini, failtakeini );
-#endif /* NOCCTRAP */
-
- debug(F111,"main 2 cfilef",cmdfil,cfilef);
- if (cmdfil[0]) { /* If we got one (see prescan())... */
-#ifdef NOCCTRAP
- docmdfile(0); /* execute it. */
-#else /* NOCCTRAP */
- setint();
- cc_execute( ckjaddr(cmjbuf), docmdfile, failcmdfile );
-#endif /* NOCCTRAP */
- }
-#ifndef OS2 /* Preserve name so we can delete it */
- *cmdfil = '\0'; /* Done, nullify the file name */
-#endif /* OS2 */
-#endif /* NOICP */
-
-#ifndef NOCMDL
-/* Look for a UNIX-style command line... */
-
- what = W_NOTHING;
-
- debug(F101,"main argc","",argc);
-#ifndef NOHELP
- iniopthlp(); /* Initialize cmdline arg help */
-#endif /* NOHELP */
- if (
-#ifdef COMMENT
- !cfilef &&
-#endif /* COMMENT */
- argc > 1) { /* Command line arguments? */
- sstate = (CHAR) cmdlin(); /* Yes, parse. */
-#ifdef NETCONN
-#ifndef NOURL
- if (haveurl) { /* Was a URL given? */
- dourl(); /* if so, do it. */
- }
-#endif /* NOURL */
-#endif /* NETCONN */
-#ifndef NOXFER
- zstate = sstate; /* Remember sstate around protocol */
- debug(F101,"main zstate","",zstate);
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
- if (cflg) { /* Connect first if requested */
- doconect(0,0);
- if (ttchk() < 0)
- dologend();
- cflg = 0;
- }
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
- if (sstate) {
-#ifndef NOLOCAL
- if (displa) concb((char)escape); /* (for console "interrupts") */
-#endif /* NOLOCAL */
-#ifdef NOCCTRAP
- docmdline(1);
-#else /* NOCCTRAP */
- setint();
- cc_execute( ckjaddr(cmjbuf), docmdline, failcmdline );
-#endif /* NOCCTRAP */
- }
-#endif /* NOXFER */
-
-#ifndef NOICP
-/*
- If a command-line action argument was given and -S ("stay") was not given,
- exit now.
-*/
- if ((cflg || cnflg || zstate) && !stayflg)
-#endif /* NOICP */
- doexit(GOOD_EXIT,xitsta); /* Exit with good status */
-
-#ifndef NOLOCAL
-#ifndef NOICP
- if (local) {
-#ifdef NETCONN
- if ((cflg || cnflg) && tn_exit && ttchk() < 0)
- doexit(GOOD_EXIT,xitsta); /* Exit with good status */
-#endif /* NETCONN */
- if (exitonclose && !network &&
- (carrier != CAR_OFF && (ttgmdm() & BM_DCD) == 0))
- doexit(GOOD_EXIT,xitsta); /* Exit with good status */
- if (exitonclose && network && ttchk() < 0)
- doexit(GOOD_EXIT,xitsta); /* Exit with good status */
- }
-#endif /* NOICP */
-#endif /* NOLOCAL */
- }
-#endif /* NOCMDL */
-
-#ifdef NOICP /* No interactive command parser */
-#ifndef NOCMDL
- else {
-
- /* Command-line-only version */
- fatal("?No command-line options given - type 'kermit -h' for help");
- }
-#else /* Neither one! */
- sstate = 'x';
- justone = 0;
- proto(); /* So go into server mode */
- doexit(GOOD_EXIT,xitsta); /* exit with good status */
-
-#endif /* NOCMDL */
-#else /* not NOICP */
-/*
- If no action requested on command line, or if -S ("stay") was included,
- enter the interactive command parser.
-*/
- if (!clcmds)
- herald(); /* Display program herald. */
-
-#ifdef NOCCTRAP
- debug(F100,"main NOCCTRAP setting interrupt trap","",0);
- setint(); /* Set up command interrupt traps */
- doicp(NULL);
-#else /* NOCCTRAP */
- while (1) {
- debug(F100,"main setting interrupt trap","",0);
- setint(); /* Set up command interrupt traps */
- if (!cc_execute(ckjaddr(cmjbuf), doicp, failicp))
- break;
- }
-#endif /* NOCCTRAP */
-#endif /* NOICP */
-#ifndef MAINISVOID
- return(1);
-#endif /* MAINISVOID */
-}
-
-#ifdef DYNAMIC
-/* Allocate file i/o buffers */
-
-char *zinbuffer = NULL, *zoutbuffer = NULL;
-
-int
-getiobs() {
- zinbuffer = (char *)malloc(INBUFSIZE);
- if (!zinbuffer) return(-1);
- zoutbuffer = (char *)malloc(zobufsize);
- debug(F101,"zoutbuffer malloc","",zobufsize);
- if (!zoutbuffer) return(-1);
- debug(F100,"getiobs ok","",0);
- return(0);
-}
-#endif /* DYNAMIC */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcmdb.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckcmdb.c
deleted file mode 100644
index de5cebc..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcmdb.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- C K C M D B . C -- malloc debugger.
-*/
-
-/*
- Author: Howie Kaye, Columbia University Center for Computing Activities.
-
- Copyright (C) 1985, 1999,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-/* Use the real ones in this module! */
-#ifdef malloc
-#undef malloc
-#endif /* malloc */
-#ifdef calloc
-#undef calloc
-#endif /* calloc */
-#ifdef realloc
-#undef realloc
-#endif /* realloc */
-#ifdef free
-#undef free
-#endif /* free */
-
-#include "ckcsym.h"
-#include <stdio.h>
-#include "ckcdeb.h"
-
-#ifdef COHERENT
-_PROTOTYP ( FILE * fdopen, (int, char *) );
-#endif /* COHERENT */
-
-/*
- memdebug:
- variable to control memory debugging.
- if memdebug == 1, then action is always taken.
- if memdebug == 0, then no action is taken.
- if memdebug == -1, then the user is asked (works well with gdb).
-*/
-int memdebug = -1;
-int disabled = 0;
-int inited = 0;
-/*
- To use this package, compile your program with:
- -Dmalloc=dmalloc -Dfree=dfree =Dcalloc=dcalloc ... -DMDEBUG
- and then link it with ckcmdb.c.
-*/
-#ifdef MDEBUG
-
-#ifndef M_SIZE_T
-#ifdef NEXT
-#define M_SIZE_T size_t
-#else
-#ifdef SUNOS41
-#define M_SIZE_T unsigned
-#else
-#define M_SIZE_T int
-#endif /* SUNOS41 */
-#endif /* NEXT */
-#endif /* M_SIZE_T */
-
-#ifdef CK_ANSIC
-_PROTOTYP( void free, (void *) );
-_PROTOTYP( void * malloc, (size_t) );
-_PROTOTYP( void * realloc, (void *, size_t) );
-#else
-_PROTOTYP( VOID free, (char *) );
-_PROTOTYP( char * malloc, (M_SIZE_T) );
-_PROTOTYP( char * realloc, (char *, M_SIZE_T) );
-#endif /* NEXT */
-
-_PROTOTYP( VOID m_insert, (char *) );
-_PROTOTYP( int m_delete, (char *) );
-
-_PROTOTYP( char * dmalloc, (int) );
-_PROTOTYP( char * dcalloc, (int, int) );
-_PROTOTYP( char * drealloc, (char *, int) );
-
-_PROTOTYP( char *set_range_check, (char *, int) );
-_PROTOTYP( char *check_range, (char *) );
-_PROTOTYP( static char *maybe_check_range, (char *) );
-
-_PROTOTYP( static VOID maybe_quit, (char *) );
-_PROTOTYP( static int ask, (char *) );
-
-#ifndef min
-#define min(x,y) ((x) < (y) ? (x) : (y))
-#endif /* min */
-#define RANGE "ABCDEFGHIJKLMNOP"
-#define INTSIZE sizeof(int)
-#define LONGSIZE sizeof(long)
-#define RSIZE sizeof(RANGE)
-#define RFRONT min((RSIZE/2),LONGSIZE)
-#define RBACK min((RSIZE-RFRONT),LONGSIZE)
-
-char *
-dmalloc(size) int size; {
- char *cp;
-
- cp = malloc(size + RSIZE + INTSIZE);
- if (cp) {
- cp = set_range_check(cp, size);
- m_insert(cp);
- }
- return(cp);
-}
-
-char *
-dcalloc(nelem, elsize) int nelem, elsize; {
- char *cp;
-
- cp = dmalloc(nelem * elsize);
- if (cp)
- memset(cp, 0, nelem * elsize);
- return(cp);
-}
-
-char *
-drealloc(bp,size) char *bp; int size; {
- char *cp;
-
- if (bp == NULL) {
- maybe_quit("Freeing NULL pointer");
- } else {
- m_delete(bp);
- cp = check_range(bp);
- }
- cp = realloc(cp, size + RSIZE + INTSIZE);
- if (cp) {
- cp = set_range_check(cp, size);
- m_insert(cp);
- }
- return(cp);
-}
-
-VOID
-dfree(cp) char *cp; {
- if (cp == NULL)
- maybe_quit("Freeing NULL pointer");
- else {
- switch(m_delete(cp)) {
- case 0:
- cp = maybe_check_range(cp);
- break;
- case 1:
- cp = check_range(cp);
- break;
- case 2:
- break;
- }
- }
-#ifndef CK_ANSIC
- return(free(cp));
-#endif /* CK_ANSIC */
-}
-
-char *
-set_range_check(cp,size) char *cp; int size; {
- register int i;
- int tmp = size;
-
- for(i = 0; i < INTSIZE; i++) { /* set the size in the string */
- cp[i] = tmp & 0xff;
- tmp >>= 8;
- }
- cp += INTSIZE; /* skip the size */
-
- for(i = 0; i < RFRONT; i++) /* set the front of the range check */
- cp[i] = RANGE[i]; /* string */
-
- cp += RFRONT; /* skip the front range check */
-
- for(i = 0; i < RBACK; i++) /* set the back odf the range check */
- cp[i+size] = RANGE[i+RFRONT];
-
- return(cp);
-}
-
-/*
- Put calls to this routine in your code any place where you want to
- check whether you've copied too many characters into a malloc'd space.
-*/
-char *
-check_range(cp) char *cp; {
- register char *bp = cp - RFRONT - INTSIZE;
- char *xp = bp;
- register int i;
- int size = 0;
-
- for(i = 0 ; i < INTSIZE; i++) { /* get the size out of the string */
- size <<= 8;
- size |= bp[INTSIZE-i-1] & 0xff;
- }
- bp += INTSIZE;
-
- for(i = 0; i < RFRONT; i++) /* check front range check */
- if (bp[i] != RANGE[i]) {
- maybe_quit("leftside malloc buffer overrun");
- break;
- }
- bp += RFRONT; /* skip front range check */
-
- for(i = 0; i < RBACK; i++) /* check back range check */
- if (bp[i+size] != RANGE[i+RFRONT]) {
- maybe_quit("rightside malloc buffer overrun");
- break;
- }
- return(xp);
-}
-
-static char *
-maybe_check_range(cp) char *cp; {
- register char *bp = cp - RFRONT - INTSIZE;
- char *xp = bp;
- register int i;
- int size = 0;
-
- for(i = 0 ; i < INTSIZE; i++) { /* get the size out of the string */
- size <<= 8;
- size |= bp[INTSIZE-i-1] & 0xff;
- }
- bp += INTSIZE;
-
- for(i = 0; i < RFRONT; i++) /* check front range check */
- if (bp[i] != RANGE[i]) {
- return(cp);
- }
- bp += RFRONT; /* skip front range check */
-
- for(i = 0; i < RBACK; i++) /* check back range check */
- if (bp[i+size] != RANGE[i+RFRONT]) {
- fprintf(stderr,"rightside malloc buffer overrun\n");
- abort();
- break;
- }
- return(xp);
-}
-
-#define BUCKETS 10000
-char *m_used[BUCKETS];
-char *m_used2[BUCKETS];
-
-VOID
-m_insert(cp) register char *cp; {
- register int i;
-
- if (disabled)
- return;
-
- for(i = 0; i < BUCKETS; i++)
- if (m_used[i] == 0) {
- m_used[i] = cp;
- return;
- }
- disabled ++;
-}
-
-static VOID
-m_insert2(cp) register char *cp; {
- register int i;
-
- if (disabled)
- return;
- for(i = 0; i < BUCKETS; i++)
- if (m_used2[i] == 0) {
- m_used2[i] = cp;
- return;
- }
- disabled ++;
-}
-
-int
-m_delete(cp) register char *cp; {
- register int i;
-
- for(i = 0; i < BUCKETS; i++)
- if (m_used[i] == cp) {
- m_used[i] = 0;
- return(1);
- }
- for(i = 0; i < BUCKETS; i++)
- if (m_used2[i] == cp) {
- m_used2[i] = 0;
- return(2);
- }
- if (disabled)
- return(0);
-
- maybe_quit("Freeing unmalloc'ed pointer");
- return(0);
-}
-
-VOID
-m_init() {
- register int i;
-
- inited = 1;
- disabled = 0;
-#ifdef NEXT
- malloc_debug(2+4+8+16);
-#endif /* NEXT */
-
- for(i = 0; i < BUCKETS; i++)
- m_used[i] = 0;
-}
-
-VOID
-m_done() {
- register int i,j=0;
-
- if (disabled)
- return;
- for(i = 0; i < BUCKETS; i++)
- if (m_used[i] != 0) {
- if (memdebug) {
- if (j == 0)
- fprintf(stderr,"unfree'ed buffers, indices: ");
- fprintf(stderr,"%d, ", i);
- j++;
- }
- }
- if (j)
- fprintf(stderr,"\n");
- for(i = 0; i < BUCKETS; i++)
- if (m_used2[i] != 0) {
- if (memdebug) {
- if (j == 0)
- fprintf(stderr,"unfree'ed registered buffers, indices: ");
- fprintf(stderr,"%d, ", i);
- j++;
- }
- }
- if (j)
- fprintf(stderr,"\n");
- if (j)
- maybe_quit("Unfree'ed malloc buffers");
-}
-
-VOID
-m_checkranges() {
- int i;
-
- for ( i = 0; i < BUCKETS; i++)
- if (m_used[i])
- check_range(m_used[i]);
-}
-
-static VOID
-maybe_quit(str) char *str; {
- debug(F100,"mdebug maybe_quit","",0);
- if (memdebug == 0)
- return;
- fprintf(stderr,"%s\n",str);
- if (memdebug == 1)
- abort();
- if (memdebug == -1)
- if (ask("Quit? "))
- abort();
-}
-
-static int
-ask(str) char *str; {
- char buf[100];
- FILE *in;
- int fd;
-
- fd = dup(fileno(stdin));
- in = fdopen(fd, "r");
- while(1) {
- fprintf(stderr,str);
- fflush(stderr);
- if (fgets(buf, 99, in) == NULL) /* EOF? */
- return(0);
- if (buf[0] == 'n' || buf[0] == 'N') {
- fclose(in);
- return(0);
- }
- if (buf[0] == 'y' || buf[0] == 'Y') {
- fclose(in);
- return(1);
- }
- fprintf(stderr,"please answer y/n.\n");
- }
-}
-#endif /* MDEBUG */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcnet.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckcnet.c
deleted file mode 100644
index 2bb01a6..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcnet.c
+++ /dev/null
@@ -1,14447 +0,0 @@
-char *cknetv = "Network support, 9.0.297, 14 Jul 2011";
-
-/* C K C N E T -- Network support */
-
-/*
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- REMINDER: Any changes made to this file that other modules depend must
- also be made to cklnet.c (for VOS) until such time as cklnet.c and this
- module are merged back together.
-
- NOTE TO CONTRIBUTORS: This file, and all the other shared (ckc and cku)
- C-Kermit source files, must be compatible with C preprocessors that support
- only #ifdef, #else, #endif, #define, and #undef. Please do not use #if,
- logical operators, or other preprocessor features in this module. Also,
- don't use any ANSI C constructs except within #ifdef CK_ANSIC..#endif.
-
- Authors:
-
- Frank da Cruz (fdc@columbia.edu),
- Columbia University Academic Information Systems, New York City.
- Jeffrey E Altman (jaltman@secure-endpoints.com) -- Primary
- maintainer/developer since about 1996.
- netopen() routine for TCP/IP originally by Ken Yap, Rochester University
- (ken@cs.rochester.edu) (no longer at that address).
- Missing pieces for Excelan sockets library from William Bader.
- Telnet protocol by Frank da Cruz and Jeffrey Altman.
- Rlogin protocol by Jeffrey E Altman.
- SSL support adapted by Jeffrey E Altman from work done by
- Tim Hudson <tjh@cryptosoft.com> +61 7 32781581
- TLS support by Jeffrey E Altman.
- HTTP support by Jeffrey E Altman.
- TGV MultiNet code by Frank da Cruz.
- MultiNet code adapted to WIN/TCP by Ray Hunter of TWG.
- MultiNet code adapted to DEC TCP/IP by Lee Tibbert of DEC and Frank da Cruz.
- TCP/IP support adapted to IBM TCP/IP 1.2.1,2.0 for OS/2 by Kai Uwe Rommel.
- CMU-OpenVMS/IP modifications by Mike O'Malley, Digital (DEC).
- X.25 support by Marcello Frutig, Catholic University,
- Rio de Janeiro, Brazil (frutig@rnp.impa.br) with fixes from
- Stefaan Eeckels, Eurokom, Luxembourg.
- David Lane added support for Stratus VOS X.25 1996.
- Stephen Riehm added support for IBM AIX X.25 in April 1998.
- Other contributions as indicated in the code.
-*/
-#define CKCNET_C
-#include "ckcsym.h"
-#include "ckcdeb.h"
-#include "ckcker.h"
-#include "ckcasc.h"
-#ifdef I386IX /* Has to come before ckcnet.h in */
-#include <errno.h> /* this version, but after in others */
-#endif /* I386IX */
-#include "ckcnet.h" /* which includes ckctel.h */
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-
-#ifdef CK_DNS_SRV
-#ifdef OS2
-#ifdef NT
-#include <wshelper.h>
-#else /* NT */
-/* !Error OS/2 does not support DNS Service Records. */
-#endif /* NT */
-#else /* OS2 */
-#include <arpa/inet.h>
-#ifdef USE_NAMESER_COMPAT
-#include <arpa/nameser_compat.h>
-#endif /* USE_NAMESER_COMPAT */
-
-#ifdef MINIX3
-#include <net/gen/resolv.h>
-#include <net/gen/nameser.h>
-#else
-#include <arpa/nameser.h>
-#include <resolv.h>
-#endif /* MINIX 3 */
-
-#ifndef PS2AIX10
-#ifndef BSD4
-#ifndef I386IX
-#ifndef RTAIX
-#include <netdb.h>
-#endif /* RTAIX */
-#endif /* I386IX */
-#endif /* BSD4 */
-#endif /* PS2AIX10 */
-#endif /* OS2 */
-#ifndef T_SRV
-#define T_SRV 33
-#endif /* T_SRV */
-#ifndef T_TXT
-#define T_TXT 16
-#endif /* T_TXT */
-
-/* for old Unixes and friends ... */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif /* MAXHOSTNAMELEN */
-
-#define MAX_DNS_NAMELEN (15*(MAXHOSTNAMELEN + 1)+1)
-#endif /* CK_DNS_SRV */
-
-#ifdef NONET
-#ifdef TCPIPLIB
-#undef TCPIPLIB
-#endif /* TCPIPLIB */
-#endif /* NONET */
-
-#ifndef NOMHHOST
-#ifdef datageneral
-#define NOMHHOST
-#else
-#ifdef HPUX5WINTCP
-#define NOMHHOST
-#endif /* HPUX5WINTCP */
-#endif /* datageneral */
-#endif /* NOMHHOST */
-
-#ifdef INADDRX
- struct in_addr inaddrx;
-#endif /* INADDRX */
-
-int ttnet = NET_NONE; /* Network type */
-int ttnproto = NP_DEFAULT; /* Network virtual terminal protocol */
-
-/* 0 = don't lowercase username for Rlogin/Telnet protocol */
-/* nonzero = do lowercase it. Add a SET command if necessary... */
-#ifdef VMS
-int ck_lcname = 1;
-#else
-int ck_lcname = 0;
-#endif /* VMS */
-
-extern int /* External variables */
- duplex, debses, seslog, sessft, wasclosed,
- ttyfd, quiet, msgflg, what, nettype, ttmdm;
-#ifdef IKSD
-extern int inserver;
-#endif /* IKSD */
-
-char myipaddr[20] = { '\0' }; /* Global copy of my IP address */
-char hostipaddr[64] = { '\0' }; /* Global copy of remote IP address */
-
-#ifdef NETCONN
-/* Don't need any of this if there is no network support. */
-
-#ifndef OS2
-/* Current fd-swapping hack is not thread-safe */
-#define HTTP_BUFFERING
-#endif /* OS2 */
-
-#ifdef HTTP_BUFFERING
-#define HTTP_INBUFLEN 8192
-static char http_inbuf[HTTP_INBUFLEN];
-static int http_bufp = 0, http_count;
-#endif /* HTTP_BUFFERING */
-
-/*
- NETLEBUF is (must be) defined for those platforms that call this
- module to do network i/o (e.g. netinc(), nettchk(), etc) rather
- than doing it themselves (ttinc(), ttchk(), etc). In this case
- the Telnet local-echo buffers and routines are defined and referenced
- here, rather than in the ck?tio.c module.
-*/
-#ifdef NETLEBUF
-#define LEBUFSIZ 4096
-int ttpush = -1, le_data = 0; /* These are seen from outside */
-static CHAR le_buf[LEBUFSIZ]; /* These are used internally */
-static int le_start = 0, le_end = 0;
-int tt_push_inited = 0;
-#endif /* NETLEBUF */
-
-#ifdef CK_SOCKS /* SOCKS Internet relay package */
-#ifdef CK_SOCKS5 /* SOCKS 5 */
-#define accept SOCKSaccept
-#define bind SOCKSbind
-#define connect SOCKSconnect
-#define getsockname SOCKSgetsockname
-#define listen SOCKSlisten
-#else /* Not SOCKS 5 */
-#define accept Raccept
-#define bind Rbind
-#define connect Rconnect
-#define getsockname Rgetsockname
-#define listen Rlisten
-#endif /* CK_SOCKS5 */
-#endif /* CK_SOCKS */
-
-#ifdef DEC_TCPIP
-#include <time.h>
-#include <inet.h>
-#endif /* DEC_TCPIP */
-
-/* Also see ckcnet.h -- hmmm, why don't we always include inet.h? */
-
-#ifdef HPUX
-#ifndef HPUX7 /* HPUX 7.00 doesn't have it */
-#ifndef HPUX6 /* HPUX 6.00 doesn't have it */
-#include <arpa/inet.h> /* For inet_ntoa() prototype */
-#endif /* HPUX6 */
-#endif /* HPUX7 */
-#endif /* HPUX */
-
-#ifdef CMU_TCPIP
-#include <time.h>
-#endif /* CMU_TCPIP */
-
-#ifndef NODCLTIMEVAL
-#ifdef DCLTIMEVAL /* UnixWare 7 */
-struct timeval { /* And define these ourselves. */
- long tv_sec; /* (see comments in ckutio.c) */
- long tv_usec;
-};
-struct timezone {
- int tz_minuteswest;
- int tz_dsttime;
-};
-#endif /* DCLTIMEVAL */
-#endif /* NODCLTIMEVAL */
-
-#ifdef WINTCP
-
-#include <setjmp.h>
-#include <signal.h>
-#include <sys/time.h>
-/*
- The WIN/TCP code path is the same as that for MultiNet.
- Only the routine names have changed ...
-*/
-#define socket_read netread
-#define socket_ioctl ioctl
-#define socket_write netwrite
-#define socket_close netclose
-
-#ifdef OLD_TWG /* some routines have evolved */
- extern int vmserrno, uerrno;
-#define socket_errno uerrno
-#define socket_perror perror /* which uses errno, not uerrno! */
-#else
-#define socket_errno errno
-#define socket_perror win$perror
-#endif /* OLD_TWG */
-
-#else /* Not WINTCP */
-
-#ifdef OSF13
-#ifdef CK_ANSIC
-#ifdef _NO_PROTO
-#undef _NO_PROTO
-#endif /* _NO_PROTO */
-#endif /* CK_ANSIC */
-#endif /* OSF13 */
-
-#ifndef I386IX
-#ifndef HPUXPRE65
-#include <errno.h> /* Error number symbols */
-#else
-#ifndef ERRNO_INCLUDED
-#include <errno.h> /* Error number symbols */
-#endif /* ERRNO_INCLUDED */
-#endif /* HPUXPRE65 */
-#endif /* I386IX */
-
-#include <signal.h> /* Everybody needs this */
-
-#ifdef ZILOG /* Zilog has different name for this */
-#include <setret.h>
-#else
-#include <setjmp.h>
-#endif /* ZILOG */
-
-#endif /* WINTCP */
-
-#ifdef datageneral /* Data General AOS/VS */
-#include <:usr:include:vs_tcp_errno.h>
-#include <:usr:include:sys:vs_tcp_types.h>
-#ifdef SELECT
-/*
- NOTE: This can be compiled and linked OK with SELECT defined
- but it doesn't work at all. Anybody who cares and knows how
- to fix it, feel free.
-*/
-#include <:usr:include:sys:vs_tcp_time.h>
-#endif /* SELECT */
-#include <:usr:include:sys:socket.h>
-#include <:usr:include:netinet:in.h>
-#include <:usr:include:netdb.h>
-#endif /* datageneral */
-
-#ifndef socket_errno
-#define socket_errno errno
-#endif /* socket_errno */
-
-#ifdef TNCODE
-extern int tn_deb;
-#endif /* TNCODE */
-
-int tcp_rdns = /* Reverse DNS lookup */
-#ifdef DEC_TCPIP_OLD
- SET_OFF /* Doesn't seem to work in UCX */
-#else
- SET_AUTO
-#endif /* DEC_TCPIP */
- ;
-#ifdef CK_DNS_SRV
-int tcp_dns_srv = SET_OFF;
-#endif /* CK_DNS_SRV */
-
-_PROTOTYP( char * cmcvtdate, (char *, int) );
-
-#ifdef RLOGCODE
-_PROTOTYP( int rlog_ctrl, (CHAR *, int) );
-_PROTOTYP( static int rlog_oob, (CHAR *, int) );
-#ifndef TCPIPLIB
-_PROTOTYP( static SIGTYP rlogoobh, ( int ) );
-#endif /* TCPIPLIB */
-_PROTOTYP( static int rlog_ini, (CHAR *, int,
- struct sockaddr_in *,
- struct sockaddr_in *) );
-int rlog_mode = RL_COOKED;
-int rlog_stopped = 0;
-int rlog_inband = 0;
-#endif /* RLOGCODE */
-
-#ifndef NOICP
-extern int doconx; /* CONNECT-class command active */
-#endif /* NOICP */
-
-#ifdef IBMX25
-/* This variable should probably be generalised for true client/server
- * support - ie: the fd of the listening server, accepted calls should
- * be forked or at least handled via a second fd (for IBM's X.25 -
- * ttyfd always holds the active fd - ie the server becomes inactive
- * as long as a client is connected, and becomes active again when the
- * connection is closed)
- */
-int x25serverfd = 0; /* extern in ckcnet.h */
-int x25seqno = 0; /* Connection sequence number */
-int x25lastmsg = -1; /* A cheapskate's state table */
-
-#define X25_CLOSED 0 /* Default state: no connection, no STREAM */
-#define X25_SETUP 1 /* X.25 has been set up (no connection) */
-#define X25_CONNECTED 2 /* X.25 connection has been established */
-int x25_state = X25_CLOSED; /* Default state */
-#endif /* IBMX25 */
-
-#ifndef DEBUG
-#define deblog 0
-#endif /* DEBUG */
-
-#ifdef CK_NAWS /* Negotiate About Window Size */
-#ifdef RLOGCODE
-_PROTOTYP( int rlog_naws, (void) );
-#endif /* RLOGCODE */
-#endif /* CK_NAWS */
-
-#ifdef OS2 /* For terminal type name string */
-#include "ckuusr.h"
-#ifndef NT
-#include <os2.h>
-#undef COMMENT
-#endif /* NT */
-#include "ckocon.h"
-extern int tt_type, max_tt;
-extern struct tt_info_rec tt_info[];
-extern char ttname[];
-#else
-#ifdef CK_AUTHENTICATION
-#include "ckuusr.h"
-#endif /* CK_AUTHENTICATION */
-#endif /* OS2 */
-
-#ifdef NT
-extern int winsock_version;
-#endif /* NT */
-
-#ifdef CK_AUTHENTICATION
-#include "ckuath.h"
-#endif /* CK_AUTHENTICATION */
-
-#include "ckcsig.h"
-
-#ifndef OS2 /* For timeout longjumps */
-static ckjmpbuf njbuf;
-#endif /* OS2 */
-
-#define NAMECPYL 1024 /* Local copy of hostname */
-char namecopy[NAMECPYL]; /* Referenced by ckctel.c */
-char namecopy2[NAMECPYL]; /* Referenced by ckctel.c */
-#ifndef NOHTTP
-char http_host_port[NAMECPYL]; /* orig host/port necessary for http */
-char http_ip[20] = { '\0' }; /* ip address of host */
-char http_port = 0;
-int http_ssl = 0;
-char * http_agent = 0;
-int httpfd = -1; /* socket for http connections */
-int http_code = 0;
-#define HTTPBUFLEN 1024
-char http_reply_str[HTTPBUFLEN] = "";
-#endif /* NOHTTP */
-
-char ipaddr[20] = { '\0' }; /* Global copy of IP address */
-unsigned long myxipaddr = 0L; /* Ditto as a number */
-#endif /* NETCONN */
-
-char *tcp_address = NULL; /* Preferred IP Address */
-extern char uidbuf[]; /* User ID buffer */
-extern char pwbuf[]; /* Password buffer */
-
-#ifndef NOHTTP
-char * tcp_http_proxy = NULL; /* Name[:port] of http proxy server */
-int tcp_http_proxy_errno = 0;
-char * tcp_http_proxy_user = NULL;
-char * tcp_http_proxy_pwd = NULL;
-char * tcp_http_proxy_agent = NULL;
-#define HTTPCPYL 1024
-static char proxycopy[HTTPCPYL];
-#endif /* NOHTTP */
-
-#ifdef OS2
-extern int tt_rows[], tt_cols[];
-extern int tt_status[VNUM];
-#else /* OS2 */
-extern int tt_rows, tt_cols; /* Everybody has this */
-#endif /* OS2 */
-
-extern int cmd_cols, cmd_rows;
-
-#ifdef STREAMING /* Use blocking writes for streaming */
-extern int streaming;
-#endif /* STREAMING */
-
-#ifdef NT
-extern int WSASafeToCancel;
-int win95selectbug = 0; /* For TCP/IP stacks whose select() */
-/* always fails on write requests such as Cisco and Quarterdeck */
-#define stricmp _stricmp
-#endif /* NT */
-
-#ifndef NOTCPOPTS
-
-/* Skip all this if NOTCPOPTS specified. */
-
-#ifdef SOL_SOCKET
-
-#ifdef TCP_NODELAY
-int tcp_nodelay = 0; /* Nagle algorithm TCP_NODELAY */
-#endif /* TCP_NODELAY */
-
-#ifdef SO_DONTROUTE
-int tcp_dontroute = 0;
-#endif /* SO_DONTROUTE */
-
-#ifdef SO_LINGER
-int tcp_linger = 0; /* SO_LINGER */
-int tcp_linger_tmo = 0; /* SO_LINGER timeout */
-#endif /* SO_LINGER */
-
-#ifdef HPUX /* But the data structures */
-#ifndef HPUX8 /* needed for linger are not */
-#ifndef HPUX9 /* defined in HP-UX versions */
-#ifndef HPUX10 /* prior to 8.00. */
-#ifdef SO_LINGER
-#undef SO_LINGER
-#endif /* SO_LINGER */
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* HPUX8 */
-#endif /* HPUX */
-
-#ifndef SO_OOBINLINE /* Hopefully only HP-UX 7.0 */
-#define SO_OOBINLINE 0x0100
-#endif /* SO_OOBINLINE */
-
-#ifndef TCPSNDBUFSIZ
-#ifdef VMS
-#ifdef __alpha
-#define TCPSNDBUFSIZ 16384
-#endif /* __alpha */
-#endif /* VMS */
-#endif /* TCPSNDBUFSIZ */
-
-#ifndef TCPSNDBUFSIZ
-#define TCPSNDBUFSIZ -1
-#endif /* TCPSNDBUFSIZ */
-
-#ifdef SO_SNDBUF
-int tcp_sendbuf = TCPSNDBUFSIZ;
-#endif /* SO_SNDBUF */
-
-#ifdef SO_RCVBUF
-int tcp_recvbuf = -1;
-#endif /* SO_RCVBUF */
-
-#ifdef SO_KEEPALIVE
-int tcp_keepalive = 1;
-#endif /* SO_KEEPALIVE */
-
-#endif /* SOL_SOCKET */
-#endif /* NOTCPOPTS */
-
-#ifndef NETCONN
-/*
- Network support not defined.
- Dummy functions here in case #ifdef's forgotten elsewhere.
-*/
-int /* Open network connection */
-netopen(name, lcl, nett) char *name; int *lcl, nett; {
- return(-1);
-}
-int /* Close network connection */
-netclos() {
- return(-1);
-}
-int /* Check network input buffer */
-nettchk() {
- return(-1);
-}
-int /* Flush network input buffer */
-netflui() {
- return(-1);
-}
-int /* Send network BREAK */
-netbreak() {
- return(-1);
-}
-int /* Input character from network */
-netinc(timo) int timo; {
- return(-1);
-}
-int /* Output character to network */
-#ifdef CK_ANSIC
-nettoc(CHAR c)
-#else
-nettoc(c) CHAR c;
-#endif /* CK_ANSIC */
-/* nettoc */ {
- return(-1);
-}
-int
-nettol(s,n) CHAR *s; int n; {
- return(-1);
-}
-
-#else /* NETCONN is defined (much of this module...) */
-
-#ifdef NETLEBUF
-VOID
-le_init() { /* LocalEchoInit() */
- int i;
- for (i = 0; i < LEBUFSIZ; i++)
- le_buf[i] = '\0';
- le_start = 0;
- le_end = 0;
- le_data = 0;
- tt_push_inited = 1;
-}
-
-VOID
-le_clean() { /* LocalEchoCleanup() */
- le_init();
- return;
-}
-
-int
-le_inbuf() {
- int rc = 0;
- if (le_start != le_end) {
- rc = (le_end -
- le_start +
- LEBUFSIZ) % LEBUFSIZ;
- }
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-le_putchar(CHAR ch)
-#else
-le_putchar(ch) CHAR ch;
-#endif /* CK_ANSIC */
-/* le_putchar */ {
- if ((le_start - le_end + LEBUFSIZ)%LEBUFSIZ == 1) {
- debug(F110,"le_putchar","buffer is full",0);
- return(-1);
- }
- le_buf[le_end++] = ch;
- if (le_end == LEBUFSIZ)
- le_end = 0;
- le_data = 1;
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-le_puts(CHAR * s, int n)
-#else
-le_puts(s,n) CHAR * s; int n;
-#endif /* CK_ANSIC */
-/* le_puts */ {
- int rc = 0;
- int i = 0;
- CHAR * p = (CHAR *)"le_puts";
- ckhexdump(p,s,n);
- for (i = 0; i < n; i++)
- rc = le_putchar((char)s[i]);
- debug(F101,"le_puts","",rc);
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-le_putstr(CHAR * s)
-#else
-le_putstr(s) CHAR * s;
-#endif /* CK_ANSIC */
-/* le_puts */ {
- CHAR * p;
- int rc = 0;
- p = (CHAR *)"le_putstr";
- ckhexdump(p,s,(int)strlen((char *)s));
- for (p = s; *p && !rc; p++)
- rc = le_putchar(*p);
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-le_getchar(CHAR * pch)
-#else /* CK_ANSIC */
-le_getchar(pch) CHAR * pch;
-#endif /* CK_ANSIC */
-/* le_gatchar */ {
- int rc = 0;
- if (le_start != le_end) {
- *pch = le_buf[le_start];
- le_buf[le_start] = 0;
- le_start++;
-
- if (le_start == LEBUFSIZ)
- le_start = 0;
-
- if (le_start == le_end) {
- le_data = 0;
- }
- rc++;
- } else {
- *pch = 0;
- }
- return(rc);
-}
-#endif /* NETLEBUF */
-
-#ifdef VMS
-/*
- In edit 190, we moved tn_ini() to be called from within netopen().
- But tn_ini() calls ttol(), and ttol() checks to see if it's a net
- connection, but the flag for that isn't set until after netopen()
- is finished. Since, in this module, we are always doing network
- output anyway, we just call nettol() directly, instead of going thru
- ttol(). Only needed for VMS, since UNIX, AOS/VS, and VOS can handle
- net connections just like regular connections in ttol(), and OS/2
- has a special routine for this.
-*/
-#define ttol nettol
-#endif /* VMS */
-
-int tcpsrfd = -1;
-
-#ifdef CK_KERBEROS
-
-char * krb5_d_principal = NULL; /* Default principal */
-char * krb5_d_instance = NULL; /* Default instance */
-char * krb5_d_realm = NULL; /* Default realm */
-char * krb5_d_cc = NULL; /* Default credentials cache */
-char * krb5_d_srv = NULL; /* Default Service */
-int krb5_d_lifetime = 600; /* Default lifetime (10 hours) */
-int krb5_d_forwardable = 0; /* creds not forwardable */
-int krb5_d_proxiable = 0; /* creds not proxiable */
-int krb5_d_renewable = 0; /* creds not renewable (0 min) */
-int krb5_autoget = 1; /* Autoget TGTs */
-int krb5_autodel = 0; /* Auto delete TGTs */
-int krb5_d_getk4 = 0; /* K5 Kinit gets K4 TGTs */
-int krb5_checkaddrs = 1; /* Check TGT Addrs */
-int krb5_d_no_addresses = 0; /* Do not include IP Addresses */
-char * krb5_d_addrs[KRB5_NUM_OF_ADDRS+1]={NULL,NULL}; /* Addrs to include */
-int krb5_errno = 0; /* Last K5 errno */
-char * krb5_errmsg = NULL; /* Last K5 errmsg */
-char * k5_keytab = NULL;
-
-char * krb4_d_principal = NULL; /* Default principal */
-char * krb4_d_realm = NULL; /* Default realm */
-char * krb4_d_srv = NULL; /* Default Service */
-int krb4_d_lifetime = 600; /* Default lifetime (10 hours) */
-int krb4_d_preauth = 1; /* Use preauth requests */
-char * krb4_d_instance = NULL; /* Default instance */
-int krb4_autoget = 1; /* Autoget TGTs */
-int krb4_autodel = 0; /* Auto delete TGTs */
-int krb4_checkaddrs = 1; /* Check TGT Addrs */
-char * k4_keytab = NULL;
-
-int krb4_errno = 0; /* Last K4 errno */
-char * krb4_errmsg = NULL; /* Last K4 errmsg */
-
-struct krb_op_data krb_op = { /* Operational data structure */
- 0, NULL /* (version, cachefile) */
-};
-
-struct krb4_init_data krb4_init = { /* Kerberos 4 INIT data structure */
- 0, NULL, NULL, NULL, NULL
-};
-
-struct krb5_init_data krb5_init = { /* Kerberos 5 INIT data structure */
- 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0,
- { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
- 0
-};
-
-struct krb5_list_cred_data krb5_lc = { /* List Credentials data structure */
- 0, 0, 0
-};
-
-int krb_action = -1; /* Kerberos action to perform */
-
-#ifndef CK_AUTHENTICATION
-char *
-ck_krb4_getrealm() {
- return("");
-}
-char *
-ck_krb5_getrealm(cc) char * cc; {
- return("");
-}
-char *
-ck_krb4_getprincipal() {
- return("");
-}
-char *
-ck_krb5_getprincipal(cc) char * cc; {
- return("");
-}
-#endif /* CK_AUTHENTICATION */
-
-/* I N I _ K E R B -- Initialize Kerberos data */
-
-VOID
-ini_kerb() {
- int i;
-
- krb_action = -1; /* No action specified */
-
- krb_op.version = 0; /* Kerberos version (none) */
- krb_op.cache = NULL; /* Cache file (none) */
-
-/* Kerberos 5 */
-
- krb5_init.forwardable = krb5_d_forwardable; /* Init switch values... */
- krb5_init.proxiable = krb5_d_proxiable;
- krb5_init.lifetime = krb5_d_lifetime;
- krb5_init.renew = 0;
- krb5_init.renewable = krb5_d_renewable;
- krb5_init.validate = 0;
- krb5_init.no_addresses = krb5_d_no_addresses;
- krb5_init.getk4 = krb5_d_getk4;
- if (krb5_init.postdate) {
- free(krb5_init.postdate);
- krb5_init.postdate = NULL;
- }
- if (krb5_init.service) {
- free(krb5_init.service);
- krb5_init.service = NULL;
- }
- if (!krb5_d_cc || !krb5_d_cc[0]) { /* Set default cache */
- char * p;
- p = ck_krb5_get_cc_name();
- makestr(&krb5_d_cc,(p && p[0]) ? p : NULL);
- }
- if (!krb5_d_realm || !krb5_d_realm[0]) { /* Set default realm */
- char * p;
- p = ck_krb5_getrealm(krb5_d_cc);
- makestr(&krb5_d_realm,(p && p[0]) ? p : NULL);
- }
- makestr(&krb5_init.instance,krb5_d_instance);
- makestr(&krb5_init.realm,krb5_d_realm); /* Set realm from default */
- if (krb5_init.password) {
- memset(krb5_init.password,0xFF,strlen(krb5_init.password));
- free(krb5_init.password);
- krb5_init.password = NULL;
- }
- if (!krb5_d_principal) { /* Default principal */
- /* a Null principal indicates the user should be prompted */
- char * p = ck_krb5_getprincipal(krb5_d_cc);
- if (!p || !(*p))
- p = (char *)uidbuf; /* Principal = user */
- makestr(&krb5_d_principal,(p && p[0]) ? p : NULL);
- }
- makestr(&krb5_init.principal,krb5_d_principal);
- for (i = 0; i <= KRB5_NUM_OF_ADDRS; i++) {
- if (krb5_init.addrs[i])
- free(krb5_init.addrs[i]);
- krb5_init.addrs[i] = NULL;
- }
- for (i = 0; i <= KRB5_NUM_OF_ADDRS && krb5_d_addrs[i]; i++) {
- makestr(&krb5_init.addrs[i],krb5_d_addrs[i]);
- }
-
- /* Kerberos 4 */
-
- krb4_init.lifetime = krb4_d_lifetime;
- krb4_init.preauth = krb4_d_preauth;
- makestr(&krb4_init.instance,krb4_d_instance);
- if (!krb4_d_realm || !krb4_d_realm[0]) {/* Set default realm */
- char * p;
- p = ck_krb4_getrealm();
- makestr(&krb4_d_realm,(p && p[0]) ? p : NULL);
- }
- makestr(&krb4_init.realm,krb4_d_realm);
- if (krb4_init.password) {
- memset(krb4_init.password,0xFF,strlen(krb4_init.password));
- free(krb4_init.password);
- krb4_init.password = NULL;
- }
- if (!krb4_d_principal) { /* Default principal */
- /* a Null principal indicates the user should be prompted */
- char * p = ck_krb4_getprincipal();
- if (!p || !(*p))
- p = (char *)uidbuf; /* Principal = user */
- makestr(&(krb4_d_principal),(p && p[0]) ? p : NULL);
- }
- makestr(&(krb4_init.principal),krb4_d_principal);
-}
-
-/* D O A U T H -- AUTHENTICATE action routine */
-
-int
-doauth(cx) int cx; { /* AUTHENTICATE action routine */
- int rc = 0; /* Return code */
-
-#ifdef CK_AUTHENTICATION
-#ifdef OS2
- if (!ck_security_loaddll()) /* Load various DLLs */
- return(rc);
-#endif /* OS2 */
- if (krb_op.version == 4) { /* Version = 4 */
-#ifdef COMMENT
- sho_auth(AUTHTYPE_KERBEROS_V4);
-#endif /* COMMENT */
- if (!ck_krb4_is_installed()) {
- printf("?Kerberos 4 is not installed\n");
- return(0);
- }
- switch (krb_action) { /* Perform V4 functions */
- case KRB_A_IN: /* INIT */
- rc |= !(ck_krb4_initTGT(&krb_op,&krb4_init) < 0);
- break;
- case KRB_A_DE: /* DESTROY */
- rc |= !(ck_krb4_destroy(&krb_op) < 0);
- break;
- case KRB_A_LC: /* LIST-CREDENTIALS */
- rc |= !(ck_krb4_list_creds(&krb_op) < 0);
- break;
- }
- }
- if (krb_op.version == 5) { /* V5 functions */
-#ifdef COMMENT
- sho_auth(AUTHTYPE_KERBEROS_V5);
-#endif /* COMMENT */
- if (!ck_krb5_is_installed()) {
- printf("?Kerberos 5 is not installed\n");
- return(0);
- }
- switch (krb_action) {
- case KRB_A_IN: /* INIT */
- rc |= !(ck_krb5_initTGT(&krb_op,&krb5_init,
- krb5_init.getk4 ? &krb4_init : 0) < 0);
- break;
- case KRB_A_DE: /* DESTROY */
- rc |= !(ck_krb5_destroy(&krb_op) < 0);
- break;
- case KRB_A_LC: /* LIST-CREDENTIALS */
- if (krb_op.version == 0)
- printf("\n");
- rc |= !(ck_krb5_list_creds(&krb_op,&krb5_lc) < 0);
- break;
- }
- }
-#else
-#ifndef NOICP
-#ifndef NOSHOW
- rc = sho_auth(0); /* Show all */
-#endif /* NOSHOW */
-#endif /* NOICP */
-#endif /* CK_AUTHENTICATION */
- return(rc);
-}
-#endif /* CK_KERBEROS */
-
-#ifdef TCPSOCKET
-#ifndef OS2
-#ifndef NOLISTEN /* For incoming connections */
-
-#ifndef INADDR_ANY
-#define INADDR_ANY 0
-#endif /* INADDR_ANY */
-
-_PROTOTYP( int ttbufr, ( VOID ) );
-_PROTOTYP( int tcpsrv_open, (char *, int *, int, int ) );
-
-static unsigned short tcpsrv_port = 0;
-
-#endif /* NOLISTEN */
-#endif /* OS2 */
-
-static char svcbuf[80]; /* TCP service string */
-static int svcnum = 0; /* TCP port number */
-
-#endif /* TCPSOCKET */
-
-/*
- TCPIPLIB means use separate socket calls for i/o, while on UNIX the
- normal file system calls are used for TCP/IP sockets too.
- Means "DEC_TCPIP or MULTINET or WINTCP or OS2 or BEBOX" (see ckcnet.h),
-*/
-
-#ifdef TCPIPLIB
-
-/* For buffered network reads... */
-/*
- If the buffering code is written right, it shouldn't matter
- how long this buffer is.
-*/
-#ifdef OS2
-#ifdef NT
-#define TTIBUFL 64240 /* 44 * 1460 (MSS) */
-#else
-#define TTIBUFL 32120 /* 22 * 1460 (MSS) */
-#endif /* NT */
-#else /* OS2 */
-#define TTIBUFL 8191 /* Let's use 8K. */
-#endif /* OS2 */
-
-CHAR ttibuf[TTIBUFL+1];
-
-/*
- select() is used in preference to alarm()/signal(), but different systems
- use different forms of select()...
-*/
-#ifndef NOSELECT /* Option to override BSDSELECT */
-#ifdef BELLV10
-/*
- Note: Although BELLV10 does have TCP/IP support, and does use the unique
- form of select() that is evident in this module (and in ckutio.c), it does
- not have a sockets library and so we can't build Kermit TCP/IP support for
- it. For this, somebody would have to write TCP/IP streams code.
-*/
-#define BELLSELECT
-#ifndef FD_SETSIZE
-#define FD_SETSIZE 128
-#endif /* FD_SETSIZE */
-#else
-#ifdef WINTCP /* VMS with Wollongong WIN/TCP */
-#ifndef OLD_TWG /* TWG 3.2 has only select(read) */
-#define BSDSELECT
-#endif /* OLD_TWG */
-#else
-#ifdef CMU_TCPIP /* LIBCMU can do select */
-#define BSDSELECT
-#else
-#ifdef DEC_TCPIP
-#define BSDSELECT
-#else
-#ifdef OS2 /* OS/2 with TCP/IP */
-#ifdef NT
-#define BSDSELECT
-#else /* NT */
-#define IBMSELECT
-#endif /* NT */
-#endif /* OS2 */
-#endif /* DEC_TCPIP */
-#endif /* CMU_TCPIP */
-#endif /* WINTCP */
-#endif /* BELLV10 */
-#endif /* NOSELECT */
-/*
- Others (TGV, TCPware, ...) use alarm()/signal(). The BSDSELECT case does not
- compile at all; the IBMSELECT case compiles and links but crashes at runtime.
- NOTE: If any of these can be converted to select(), they should be for two
- reasons: (1) It's a lot faster; (2) certain sockets libraries do not like
- their socket_read() calls to be interrupted; subsequent socket_read()'s tend
- to fail with EBUSY. This happened in the UCX case before it was converted
- to use select().
-*/
-#ifndef OS2
-#ifndef VMS
-static /* These are used in CKVTIO.C */
-#endif /* VMS */ /* And in CKONET.C */
-#endif /* OS2 */
-int
- ttibp = 0,
- ttibn = 0;
-/*
- Read bytes from network into internal buffer ttibuf[].
- To be called when input buffer is empty, i.e. when ttibn == 0.
-
- Other network reading routines, like ttinc, ttinl, ttxin, should check the
- internal buffer first, and call this routine for a refill if necessary.
-
- Returns -1 on error, 0 if nothing happens. When data is read successfully,
- returns number of bytes read, and sets global ttibn to that number and
- ttibp (the buffer pointer) to zero.
-*/
-_PROTOTYP( int ttbufr, ( VOID ) );
-int
-ttbufr() { /* TT Buffer Read */
- int count;
-
- if (ttnet != NET_TCPB) /* First make sure current net is */
- return(-1); /* TCP/IP; if not, do nothing. */
-
-#ifdef OS2
- RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
-#endif /* OS2 */
-
- if (ttibn > 0) { /* Our internal buffer is not empty, */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(ttibn); /* so keep using it. */
- }
-
- if (ttyfd == -1) { /* No connection, error */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- }
-
- ttibp = 0; /* Else reset pointer to beginning */
-
-#ifdef WINTCP
- count = 512; /* This works for WIN/TCP */
-#else
-#ifdef DEC_TCPIP
- count = 512; /* UCX */
-#else
-#ifdef OS2
- count = TTIBUFL;
-#else /* Multinet, etc. */
- count = ttchk(); /* Check network input buffer, */
- if (ttibn > 0) { /* which can put a char there! */
- debug(F111,"ttbufr","ttchk() returns",count);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(ttibn);
- }
- if (count < 0) { /* Read error - connection closed */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- }
- else if (count > TTIBUFL) /* Too many to read */
- count = TTIBUFL;
- else if (count == 0) /* None, so force blocking read */
- count = 1;
-#endif /* OS2 */
-#endif /* DEC_TCPIP */
-#endif /* WINTCP */
- debug(F101,"ttbufr count 1","",count);
-
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error;
- ssl_read:
- if (ssl_active_flag)
- count = SSL_read(ssl_con, ttibuf, count);
- else
- count = SSL_read(tls_con, ttibuf, count);
- error = SSL_get_error(ssl_active_flag?ssl_con:tls_con,count);
- switch (error) {
- case SSL_ERROR_NONE:
- debug(F111,"ttbufr SSL_ERROR_NONE","count",count);
- if (count > 0) {
- ttibp = 0; /* Reset buffer pointer. */
- ttibn = count;
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(ttibn); /* Return buffer count. */
- } else if (count < 0) {
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- } else {
- netclos();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- }
- case SSL_ERROR_WANT_WRITE:
- debug(F100,"ttbufr SSL_ERROR_WANT_WRITE","",0);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- case SSL_ERROR_WANT_READ:
- debug(F100,"ttbufr SSL_ERROR_WANT_READ","",0);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- case SSL_ERROR_SYSCALL:
- if ( count == 0 ) { /* EOF */
- netclos();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- } else {
- int rc = -1;
-#ifdef NT
- int gle = GetLastError();
- debug(F111,"ttbufr SSL_ERROR_SYSCALL",
- "GetLastError()",gle);
- rc = os2socketerror(gle);
- if (rc == -1)
- rc = -2;
- else if ( rc == -2 )
- rc = -1;
-#endif /* NT */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(rc);
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- debug(F100,"ttbufr SSL_ERROR_WANT_X509_LOOKUP","",0);
- netclos();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- case SSL_ERROR_SSL:
- if (bio_err!=NULL) {
- int len;
- extern char ssl_err[];
- BIO_printf(bio_err,"ttbufr SSL_ERROR_SSL\n");
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- debug(F110,"ttbufr SSL_ERROR_SSL",ssl_err,0);
- if (ssl_debug_flag)
- printf(ssl_err);
- } else if (ssl_debug_flag) {
- debug(F100,"ttbufr SSL_ERROR_SSL","",0);
- fflush(stderr);
- fprintf(stderr,"ttbufr SSL_ERROR_SSL\n");
- ERR_print_errors_fp(stderr);
- }
-#ifdef COMMENT
- netclos();
-#endif /* COMMENT */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- case SSL_ERROR_ZERO_RETURN:
- debug(F100,"ttbufr SSL_ERROR_ZERO_RETURN","",0);
- netclos();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- default:
- debug(F100,"ttbufr SSL_ERROR_?????","",0);
- netclos();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- }
- }
-#endif /* CK_SSL */
-
-#ifdef COMMENT
-/*
- This is for nonblocking reads, which we don't do any more. This code didn't
- work anyway, in the sense that a broken connection was never sensed.
-*/
- if ((count = socket_read(ttyfd,&ttibuf[ttibp+ttibn],count)) < 1) {
- if (count == -1 && socket_errno == EWOULDBLOCK) {
- debug(F100,"ttbufr finds nothing","",0);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(0);
- } else {
- debug(F101,"ttbufr socket_read error","",socket_errno);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- }
-
- } else if (count == 0) {
- debug(F100,"ttbufr socket eof","",0);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- }
-#else /* COMMENT */
-
-/* This is for blocking reads */
-
-#ifndef VMS
-#ifdef SO_OOBINLINE
- {
- int outofband = 0;
-#ifdef BELLSELECT
- if (select(128, NULL, NULL, efds, 0) > 0 && FD_ISSET(ttyfd, efds))
- outofband = 1;
-#else
-#ifdef BSDSELECT
- fd_set efds;
- struct timeval tv;
- FD_ZERO(&efds);
- FD_SET(ttyfd, &efds);
- tv.tv_sec = tv.tv_usec = 0L;
- debug(F100,"Out-of-Band BSDSELECT","",0);
-#ifdef NT
- WSASafeToCancel = 1;
-#endif /* NT */
- if (select(FD_SETSIZE, NULL, NULL, &efds, &tv) > 0 &&
- FD_ISSET(ttyfd, &efds))
- outofband = 1;
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
-#else /* !BSDSELECT */
-#ifdef IBMSELECT
-/* Is used by OS/2 ... */
-/* ... and it came in handy! For our TCP/IP layer, it avoids all the fd_set */
-/* and timeval stuff since this is the only place where it is used. */
- int socket = ttyfd;
- debug(F100,"Out-of-Band IBMSELECT","",0);
- if ((select(&socket, 0, 0, 1, 0L) == 1) && (socket == ttyfd))
- outofband = 1;
-#else /* !IBMSELECT */
-/*
- If we can't use select(), then we use the regular alarm()/signal()
- timeout mechanism.
-*/
- debug(F101,"Out-of-Band data not supported","",0);
- outofband = 0;
-
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
-#endif /* BELLSELECT */
- if (outofband) {
- /* Get the Urgent Data */
- /* if OOBINLINE is disabled this should be only a single byte */
- /* MS Winsock has a bug in Windows 95. Extra bytes are delivered */
- /* That were never sent. */
-#ifdef OS2
- RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
-#endif /* OS2 */
- count = socket_recv(ttyfd,&ttibuf[ttibp+ttibn],count,MSG_OOB);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- if (count <= 0) {
- int s_errno = socket_errno;
- debug(F101, "ttbufr socket_recv MSG_OOB","",count);
- debug(F101, "ttbufr socket_errno","",s_errno);
-#ifdef OS2ONLY
- if (count < 0 && (s_errno == 0 || s_errno == 23)) {
- /* These appear in OS/2 - don't know why */
- /* ignore it and read as normal data */
- /* and break, then we will attempt to read */
- /* the port using normal read() techniques */
- debug(F100,"ttbufr handing as in-band data","",0);
- count = 1;
- } else {
- netclos(); /* *** *** */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- }
-#else /* OS2ONLY */
- netclos(); /* *** *** */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
-#endif /* OS2ONLY */
- } else { /* we got out-of-band data */
- ckhexdump("ttbufr out-of-band chars",&ttibuf[ttibp+ttibn],count);
-#ifdef BETADEBUG
- bleep(BP_NOTE);
-#endif /* BETADEBUG */
-#ifdef RLOGCODE /* blah */
- if (ttnproto == NP_RLOGIN ||
- ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN ||
- ((ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN) &&
- !rlog_inband)
- )
- {
- /*
- When urgent data is read with MSG_OOB and not OOBINLINE
- then urgent data and normal data are not mixed. So
- treat the entire buffer as urgent data.
- */
- rlog_oob(&ttibuf[ttibp+ttibn], count);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return ttbufr();
- } else
-#endif /* RLOGCODE */ /* blah */
-#ifdef COMMENT
- /*
- I haven't written this yet, nor do I know what it should do
- */
- if (ttnproto == NP_TELNET) {
- tn_oob();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return 0;
- } else
-#endif /* COMMENT */
- {
- /* For any protocols we don't have a special out-of-band */
- /* handler for, just put the bytes in the normal buffer */
- /* and return */
-
- ttibp += 0; /* Reset buffer pointer. */
- ttibn += count;
-#ifdef DEBUG
- /* Got some bytes. */
- debug(F101,"ttbufr count 2","",count);
- if (count > 0)
- ttibuf[ttibp+ttibn] = '\0';
- debug(F111,"ttbufr ttibuf",ttibuf,ttibp);
-#endif /* DEBUG */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(ttibn); /* Return buffer count. */
- }
- }
- }
- }
-#endif /* SO_OOBINLINE */
-#endif /* VMS */
-
- count = socket_read(ttyfd,&ttibuf[ttibp+ttibn],count);
- if (count <= 0) {
- int s_errno = socket_errno;
- debug(F101,"ttbufr socket_read","",count);
- debug(F101,"ttbufr socket_errno","",s_errno);
-#ifdef OS2
- if (count == 0 || os2socketerror(s_errno) < 0) {
- netclos();
- ReleaseTCPIPMutex();
- return(-2);
- }
- ReleaseTCPIPMutex();
- return(-1);
-#else /* OS2 */
- netclos(); /* *** *** */
- return(-2);
-#endif /* OS2 */
- }
-#endif /* COMMENT */ /* (blocking vs nonblock reads...) */
- else {
- ttibp = 0; /* Reset buffer pointer. */
- ttibn += count;
-#ifdef DEBUG
- debug(F101,"ttbufr count 2","",count); /* Got some bytes. */
- if (count > 0)
- ttibuf[ttibp+ttibn] = '\0';
- debug(F111,"ttbufr ttibuf",&ttibuf[ttibp],ttibn);
-#endif /* DEBUG */
-
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(ttibn); /* Return buffer count. */
- }
-}
-#endif /* TCPIPLIB */
-
-#ifndef IBMSELECT
-#ifndef BELLSELECT
-#ifndef BSDSELECT /* Non-TCPIPLIB case */
-#ifdef SELECT
-#define BSDSELECT
-#endif /* SELECT */
-#endif /* BSDSELECT */
-#endif /* BELLSELECT */
-#endif /* IBMSELECT */
-
-#define TELNET_PORT 23 /* Should do lookup, but it won't change */
-#define RLOGIN_PORT 513
-#define KERMIT_PORT 1649
-#define KLOGIN_PORT 543
-#define EKLOGIN_PORT 2105
-
-#ifndef NONET
-/*
- C-Kermit network open/close functions for BSD-sockets.
- Much of this code shared by SunLink X.25, which also uses the socket library.
-*/
-
-/* N E T O P N -- Open a network connection. */
-/*
- Call with:
- name of host (or host:service),
- lcl - local-mode flag to be set if this function succeeds,
- network type - value defined in ckunet.h.
-*/
-#ifdef TCPSOCKET
-struct hostent *
-#ifdef CK_ANSIC
-ck_copyhostent(struct hostent * h)
-#else /* CK_ANSIC */
-ck_copyhostent(h) struct hostent * h;
-#endif /* CK_ANSIC */
-{
- /*
- * The hostent structure is dynamic in nature.
- * struct hostent {
- * char * h_name;
- * char * * h_aliases;
- * short h_addrtype;
- * short h_length;
- * char * * h_addr_list;
- * #define h_addr h_addr_list[0]
- */
-#define HOSTENTCNT 5
- static struct hostent hosts[HOSTENTCNT] = {{NULL,NULL,0,0,NULL},
- {NULL,NULL,0,0,NULL},
- {NULL,NULL,0,0,NULL},
- {NULL,NULL,0,0,NULL},
- {NULL,NULL,0,0,NULL}};
- static int next = 0;
- int i,cnt;
- char ** pp;
-
- if ( h == NULL )
- return(NULL);
-
- if (next == HOSTENTCNT)
- next = 0;
-
- if ( hosts[next].h_name ) {
- free(hosts[next].h_name);
- hosts[next].h_name = NULL;
- }
- if ( hosts[next].h_aliases ) {
- pp = hosts[next].h_aliases;
- while ( *pp ) {
- free(*pp);
- pp++;
- }
- free(hosts[next].h_aliases);
- }
-#ifdef HADDRLIST
- if ( hosts[next].h_addr_list ) {
- pp = hosts[next].h_addr_list;
- while ( *pp ) {
- free(*pp);
- pp++;
- }
- free(hosts[next].h_addr_list);
- }
-#endif /* HADDRLIST */
-
- makestr(&hosts[next].h_name,h->h_name);
- if (h->h_aliases) {
- for ( cnt=0,pp=h->h_aliases; pp && *pp; pp++,cnt++) ;
- /* The following can give warnings in non-ANSI builds */
- hosts[next].h_aliases = (char **) malloc(sizeof(char *) * (cnt+1));
- for ( i=0; i<cnt; i++) {
- hosts[next].h_aliases[i] = NULL;
- makestr(&hosts[next].h_aliases[i],h->h_aliases[i]);
- }
- hosts[next].h_aliases[i] = NULL;
- } else
- hosts[next].h_aliases = NULL;
-
- hosts[next].h_addrtype = h->h_addrtype;
- hosts[next].h_length = h->h_length;
-
-#ifdef HADDRLIST
-#ifdef h_addr
- if (h->h_addr_list) {
- for ( cnt=0,pp=h->h_addr_list; pp && *pp; pp++,cnt++) ;
- /* The following can give warnings non-ANSI builds */
- hosts[next].h_addr_list = (char **) malloc(sizeof(char *) * (cnt+1));
- for ( i=0; i<cnt; i++) {
- hosts[next].h_addr_list[i] = malloc(h->h_length);
- bcopy(h->h_addr_list[i],hosts[next].h_addr_list[i],h->h_length);
- }
- hosts[next].h_addr_list[i] = NULL;
- } else
- hosts[next].h_addr_list = NULL;
-#else
- bcopy(h->h_addr, &hosts[next].h_addr, h->h_length);
-#endif /* h_addr */
-#else /* HADDRLIST */
- bcopy(h->h_addr, &hosts[next].h_addr, h->h_length);
-#endif /* HADDRLIST */
-
- return(&hosts[next++]);
-}
-
-#ifdef EXCELAN
-/*
- Most other BSD sockets implementations define these in header files
- and libraries.
-*/
-struct servent {
- unsigned short s_port;
-};
-
-struct hostent {
- short h_addrtype;
- struct in_addr h_addr;
- int h_length;
-};
-
-struct servent *
-getservbyname(service, connection) char *service,*connection; {
- static struct servent servrec;
- int port;
-
- port = 0;
- if (strcmp(service, "telnet") == 0) port = 23;
- else if (strcmp(service, "smtp") == 0) port = 25;
- else port = atoi(service);
-
- debug(F101,"getservbyname return port ","",port);
-
- if (port > 0) {
- servrec.s_port = htons(port);
- return(&servrec);
- }
- return((struct servent *) NULL);
-}
-
-struct hostent *
-gethostbyname(hostname) char *hostname; {
- return((struct hostent *) NULL);
-}
-
-unsigned long
-inet_addr(name) char *name; {
- unsigned long addr;
-
- addr = rhost(&name);
- debug(F111,"inet_addr ",name,(int)addr);
- return(addr);
-}
-
-char *
-inet_ntoa(in) struct in_addr in; {
- static char name[80];
- ckmakxmsg(name, ckuitoa(in.s_net),".",ckuitoa(in.s_host),".",
- ckuitoa(in.s_lh),".", ckuitoa(in.s_impno));
- return(name);
-}
-#else
-#ifdef DEC_TCPIP /* UCX */
-
-int ucx_port_bug = 0; /* Explained below */
-
-#ifdef OLDIP /* Very old VAXC or GCC */
-/*
- Note that my oldest VAX C (V3.1-051) does not need (or want) OLDIP,
- hence the "Very old" in the comment - SMS, 2010/03/15.
-*/
-#define getservbyname my_getservbyname
-
-#ifdef CK_ANSIC
-globalref int (*C$$GA_UCX_GETSERVBYNAME)();
-extern void C$$TRANSLATE();
-extern void C$$SOCK_TRANSLATE();
-#else
-globalref int (*C$$GA_UCX_GETSERVBYNAME)();
-extern VOID C$$TRANSLATE();
-extern VOID C$$SOCK_TRANSLATE();
-#endif /* CK_ANSIC */
-
-struct servent *
-my_getservbyname (service, proto) char *service, *proto; {
- static struct servent sent;
- struct iosb {
- union {
- unsigned long status;
- unsigned short st[2];
- } sb;
- unsigned long spare;
- } s;
- struct {
- struct iosb *s;
- char *serv;
- char *prot;
- } par;
- unsigned long e;
- char sbuf[30], pbuf[30];
- char *p;
-
- debug(F111,"UCX getservbyname",service,(int)C$$GA_UCX_GETSERVBYNAME);
-
- p = sbuf;
- ckstrncpy(p, service, 29);
- while (*p = toupper(*p), *p++) {}
- p = pbuf;
- ckstrncpy(p, proto, 29);
- while (*p = toupper(*p), *p++) {}
-
- par.s = &s;
-
- par.serv = "";
- par.prot = "";
- /* reset file pointer or something like that!?!? */
- e = (*C$$GA_UCX_GETSERVBYNAME)(&par, &sent, par.s);
- par.serv = sbuf;
- par.prot = pbuf; /* that is don't care */
- e = (*C$$GA_UCX_GETSERVBYNAME)(&par, &sent, par.s);
- if ((long)e == -1L)
- return NULL;
- if ((e & 1) == 0L) {
- C$$TRANSLATE(e);
- return NULL;
- }
- if ((s.sb.st[0] & 1) == 0) {
- C$$SOCK_TRANSLATE(&s.sb.st[0]);
- return NULL;
- }
-/*
- sent.s_port is supposed to be returned by UCX in network byte order.
- However, UCX 2.0 through 2.0C did not do this; 2.0D and later do it.
- But there is no way of knowing which UCX version, so we have a user-settable
- runtime variable. Note: UCX 2.0 was only for the VAX.
-*/
- debug(F101,"UCX getservbyname port","",sent.s_port);
- debug(F101,"UCX getservbyname ntohs(port)","",ntohs(sent.s_port));
- if (ucx_port_bug) {
- sent.s_port = htons(sent.s_port);
- debug(F100,"UCX-PORT-BUG ON: swapping bytes","",0);
- debug(F101,"UCX swapped port","",sent.s_port);
- debug(F101,"UCX swapped ntohs(port)","",ntohs(sent.s_port));
- }
- return &sent;
-}
-#endif /* def OLDIP */
-#endif /* DEC_TCPIP */
-#endif /* EXCELAN */
-
-int
-gettcpport() {
- return(svcnum);
-}
-
-#endif /* TCPSOCKET */
-
-#ifndef NOTCPOPTS
-#ifndef datageneral
-int
-ck_linger(sock, onoff, timo) int sock; int onoff; int timo; {
-/*
- The following, from William Bader, turns off the socket linger parameter,
- which makes a close() block until all data is sent. "I don't think that
- disabling linger can ever cause kermit to lose data, but you telnet to a
- flaky server (or to our modem server when the modem is in use), disabling
- linger prevents kermit from hanging on the close if you try to exit."
-
- Modified by Jeff Altman to be generally useful.
-*/
-#ifdef SOL_SOCKET
-#ifdef SO_LINGER
- struct linger set_linger_opt;
- struct linger get_linger_opt;
- SOCKOPT_T x;
-
-#ifdef IKSD
- if (!inserver)
-#endif /* IKSD */
- if (sock == -1 ||
- nettype != NET_TCPA && nettype != NET_TCPB &&
- nettype != NET_SSH || ttmdm >= 0) {
- tcp_linger = onoff;
- tcp_linger_tmo = timo;
- return(1);
- }
- x = sizeof(get_linger_opt);
- if (getsockopt(sock, SOL_SOCKET, SO_LINGER,
- (char *)&get_linger_opt, &x)) {
- debug(F111,"TCP ck_linger can't get SO_LINGER",ck_errstr(),errno);
- } else if (x != sizeof(get_linger_opt)) {
-#ifdef OS2
- struct _linger16 {
- short s_linger;
- short s_onoff;
- } get_linger_opt16, set_linger_opt16;
- if ( x == sizeof(get_linger_opt16) ) {
- debug(F111,"TCP setlinger warning: SO_LINGER","len is 16-bit",x);
- if (getsockopt(sock,
- SOL_SOCKET, SO_LINGER,
- (char *)&get_linger_opt16, &x)
- ) {
- debug(F111,
- "TCP ck_linger can't get SO_LINGER",ck_errstr(),errno);
- } else if (get_linger_opt16.s_onoff != onoff ||
- get_linger_opt16.s_linger != timo)
- {
- set_linger_opt16.s_onoff = onoff;
- set_linger_opt16.s_linger = timo;
- if (setsockopt(sock,
- SOL_SOCKET,
- SO_LINGER,
- (char *)&set_linger_opt16,
- sizeof(set_linger_opt16))
- ) {
- debug(F111,
- "TCP ck_linger can't set SO_LINGER",
- ck_errstr(),
- errno
- );
- tcp_linger = get_linger_opt16.s_onoff;
- tcp_linger_tmo = get_linger_opt16.s_linger;
- } else {
- debug(F101,
- "TCP ck_linger new SO_LINGER","",
- set_linger_opt16.s_onoff);
- tcp_linger = set_linger_opt16.s_onoff;
- tcp_linger_tmo = set_linger_opt16.s_linger;
- return 1;
- }
- } else {
- debug(F101,"TCP ck_linger SO_LINGER unchanged","",
- get_linger_opt16.s_onoff);
- tcp_linger = get_linger_opt16.s_onoff;
- tcp_linger_tmo = get_linger_opt16.s_linger;
- return 1;
- }
- return(0);
- }
-#endif /* OS2 */
- debug(F111,"TCP ck_linger error: SO_LINGER","len",x);
- debug(F111,"TCP ck_linger SO_LINGER",
- "expected len",sizeof(get_linger_opt));
- debug(F111,"TCP ck_linger SO_LINGER","linger_opt.l_onoff",
- get_linger_opt.l_onoff);
- debug(F111,"TCP linger SO_LINGER","linger_opt.l_linger",
- get_linger_opt.l_linger);
- } else if (get_linger_opt.l_onoff != onoff ||
- get_linger_opt.l_linger != timo) {
- set_linger_opt.l_onoff = onoff;
- set_linger_opt.l_linger = timo;
- if (setsockopt(sock,
- SOL_SOCKET,
- SO_LINGER,
- (char *)&set_linger_opt,
- sizeof(set_linger_opt))) {
- debug(F111,"TCP ck_linger can't set SO_LINGER",ck_errstr(),errno);
- tcp_linger = get_linger_opt.l_onoff;
- tcp_linger_tmo = get_linger_opt.l_linger;
- } else {
- debug(F101,
- "TCP ck_linger new SO_LINGER",
- "",
- set_linger_opt.l_onoff
- );
- tcp_linger = set_linger_opt.l_onoff;
- tcp_linger_tmo = set_linger_opt.l_linger;
- return 1;
- }
- } else {
- debug(F101,"TCP ck_linger SO_LINGER unchanged","",
- get_linger_opt.l_onoff);
- tcp_linger = get_linger_opt.l_onoff;
- tcp_linger_tmo = get_linger_opt.l_linger;
- return 1;
- }
-#else
- debug(F100,"TCP ck_linger SO_LINGER not defined","",0);
-#endif /* SO_LINGER */
-#else
- debug(F100,"TCP ck_linger SO_SOCKET not defined","",0);
-#endif /* SOL_SOCKET */
- return(0);
-}
-
-int
-sendbuf(sock,size) int sock; int size; {
-/*
- The following, from William Bader, allows changing of socket buffer sizes,
- in case that might affect performance.
-
- Modified by Jeff Altman to be generally useful.
-*/
-#ifdef SOL_SOCKET
-#ifdef SO_SNDBUF
- int i, j;
- SOCKOPT_T x;
-
-#ifdef IKSD
- if (!inserver)
-#endif /* IKSD */
- if (sock == -1 ||
- nettype != NET_TCPA && nettype != NET_TCPB && nettype != NET_SSH
- || ttmdm >= 0) {
- tcp_sendbuf = size;
- return 1;
- }
- x = sizeof(i);
- if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&i, &x)) {
- debug(F111,"TCP sendbuf can't get SO_SNDBUF",ck_errstr(),errno);
- } else if (x != sizeof(i)) {
-#ifdef OS2
- short i16,j16;
- if (x == sizeof(i16)) {
- debug(F111,"TCP sendbuf warning: SO_SNDBUF","len is 16-bit",x);
- if (getsockopt(sock,
- SOL_SOCKET, SO_SNDBUF,
- (char *)&i16, &x)
- ) {
- debug(F111,"TCP sendbuf can't get SO_SNDBUF",
- ck_errstr(),errno);
- } else if (size <= 0) {
- tcp_sendbuf = i16;
- debug(F101,"TCP sendbuf SO_SNDBUF retrieved","",i16);
- return 1;
- } else if (i16 != size) {
- j16 = size;
- if (setsockopt(sock,
- SOL_SOCKET,
- SO_SNDBUF,
- (char *)&j16,
- sizeof(j16))
- ) {
- debug(F111,"TCP sendbuf can't set SO_SNDBUF",
- ck_errstr(),errno);
- } else {
- debug(F101,"TCP sendbuf old SO_SNDBUF","",i16);
- debug(F101,"TCP sendbuf new SO_SNDBUF","",j16);
- tcp_sendbuf = size;
- return 1;
- }
- } else {
- debug(F101,"TCP sendbuf SO_SNDBUF unchanged","",i16);
- tcp_sendbuf = size;
- return 1;
- }
- return(0);
- }
-#endif /* OS2 */
- debug(F111,"TCP sendbuf error: SO_SNDBUF","len",x);
- debug(F111,"TCP sendbuf SO_SNDBUF","expected len",sizeof(i));
- debug(F111,"TCP sendbuf SO_SNDBUF","i",i);
- } else if (size <= 0) {
- tcp_sendbuf = i;
- debug(F101,"TCP sendbuf SO_SNDBUF retrieved","",i);
- return 1;
- } else if (i != size) {
- j = size;
- if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&j, sizeof(j))) {
- debug(F111,"TCP sendbuf can't set SO_SNDBUF",ck_errstr(),errno);
- tcp_sendbuf = i;
- } else {
- debug(F101,"TCP sendbuf old SO_SNDBUF","",i);
- debug(F101,"TCP sendbuf new SO_SNDBUF","",j);
- tcp_sendbuf = size;
- return 1;
- }
- } else {
- debug(F101,"TCP sendbuf SO_SNDBUF unchanged","",i);
- tcp_sendbuf = size;
- return 1;
- }
-#else
- debug(F100,"TCP sendbuf SO_SNDBUF not defined","",0);
-#endif /* SO_SNDBUF */
-#else
- debug(F100,"TCP sendbuf SO_SOCKET not defined","",0);
-#endif /* SOL_SOCKET */
- return(0);
-}
-
-int
-recvbuf(sock,size) int sock; int size; {
-/*
- The following, from William Bader, allows changing of socket buffer sizes,
- in case that might affect performance.
-
- Modified by Jeff Altman to be generally useful.
-*/
-#ifdef SOL_SOCKET
-#ifdef SO_RCVBUF
- int i, j;
- SOCKOPT_T x;
-
-#ifdef IKSD
- if (!inserver)
-#endif /* IKSD */
- if (sock == -1 ||
- nettype != NET_TCPA && nettype != NET_TCPB &&
- nettype != NET_SSH || ttmdm >= 0) {
- tcp_recvbuf = size;
- return(1);
- }
- x = sizeof(i);
- if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&i, &x)) {
- debug(F111,"TCP recvbuf can't get SO_RCVBUF",ck_errstr(),errno);
- } else if (x != sizeof(i)) {
-#ifdef OS2
- short i16,j16;
- if ( x == sizeof(i16) ) {
- debug(F111,"TCP recvbuf warning: SO_RCVBUF","len is 16-bit",x);
- if (getsockopt(sock,
- SOL_SOCKET, SO_RCVBUF,
- (char *)&i16, &x)
- ) {
- debug(F111,"TCP recvbuf can't get SO_RCVBUF",
- ck_errstr(),errno);
- } else if (size <= 0) {
- tcp_recvbuf = i16;
- debug(F101,"TCP recvbuf SO_RCVBUF retrieved","",i16);
- return 1;
- } else if (i16 != size) {
- j16 = size;
- if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&j16,
- sizeof(j16))) {
- debug(F111,"TCP recvbuf can' set SO_RCVBUF",
- ck_errstr(),errno);
- } else {
- debug(F101,"TCP recvbuf old SO_RCVBUF","",i16);
- debug(F101,"TCP recvbuf new SO_RCVBUF","",j16);
- tcp_recvbuf = size;
- return 1;
- }
- } else {
- debug(F101,"TCP recvbuf SO_RCVBUF unchanged","",i16);
- tcp_recvbuf = size;
- return 1;
- }
- return(0);
- }
-#endif /* OS2 */
- debug(F111,"TCP recvbuf error: SO_RCVBUF","len",x);
- debug(F111,"TCP recvbuf SO_RCVBUF","expected len",sizeof(i));
- debug(F111,"TCP recvbuf SO_RCVBUF","i",i);
- } else if (size <= 0) {
- tcp_recvbuf = i;
- debug(F101,"TCP recvbuf SO_RCVBUF retrieved","",i);
- return 1;
- } else if (i != size) {
- j = size;
- if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&j, sizeof(j))) {
- debug(F111,"TCP recvbuf can't set SO_RCVBUF",ck_errstr(),errno);
- tcp_recvbuf = i;
- } else {
- debug(F101,"TCP recvbuf old SO_RCVBUF","",i);
- debug(F101,"TCP recvbuf new SO_RCVBUF","",j);
- tcp_recvbuf = size;
- return 1;
- }
- } else {
- debug(F101,"TCP recvbuf SO_RCVBUF unchanged","",i);
- tcp_recvbuf = size;
- return 1;
- }
-#else
- debug(F100,"TCP recvbuf SO_RCVBUF not defined","",0);
-#endif /* SO_RCVBUF */
-#else
- debug(F100,"TCP recvbuf SO_SOCKET not defined","",0);
-#endif /* SOL_SOCKET */
- return 0;
-}
-
-int
-keepalive(sock,onoff) int sock; int onoff; {
-#ifdef SOL_SOCKET
-#ifdef SO_KEEPALIVE
- int get_keepalive_opt;
- int set_keepalive_opt;
- SOCKOPT_T x;
-
- debug(F111,"TCP keepalive","sock",sock);
- debug(F111,"TCP keepalive","nettype",nettype);
- debug(F111,"TCP keepalive","ttmdm",ttmdm);
-
-#ifdef IKSD
- if (!inserver)
-#endif /* IKSD */
- if (sock == -1 ||
- nettype != NET_TCPA && nettype != NET_TCPB && nettype != NET_SSH
- || ttmdm >= 0) {
- tcp_keepalive = onoff;
- return 1;
- }
- x = sizeof(get_keepalive_opt);
- if (getsockopt(sock,
- SOL_SOCKET, SO_KEEPALIVE, (char *)&get_keepalive_opt, &x)) {
- debug(F111,"TCP keepalive can't get SO_KEEPALIVE",ck_errstr(),errno);
- } else if (x != sizeof(get_keepalive_opt)) {
-#ifdef OS2
- short get_keepalive_opt16;
- short set_keepalive_opt16;
- if (x == sizeof(get_keepalive_opt16)) {
- debug(F111,"TCP keepalive warning: SO_KEEPALIVE",
- "len is 16-bit",x);
- if (getsockopt(sock,
- SOL_SOCKET, SO_KEEPALIVE,
- (char *)&get_keepalive_opt16, &x)
- ) {
- debug(F111,
- "TCP keepalive can't get SO_KEEPALIVE",
- ck_errstr(),
- errno
- );
- } else if (get_keepalive_opt16 != onoff) {
- set_keepalive_opt16 = onoff;
- if (setsockopt(sock,
- SOL_SOCKET,
- SO_KEEPALIVE,
- (char *)&set_keepalive_opt16,
- sizeof(set_keepalive_opt16))
- ) {
- debug(F111,
- "TCP keepalive can't clear SO_KEEPALIVE",
- ck_errstr(),
- errno
- );
- tcp_keepalive = get_keepalive_opt16;
- } else {
- debug(F101,
- "TCP keepalive new SO_KEEPALIVE","",
- set_keepalive_opt16);
- tcp_keepalive = set_keepalive_opt16;
- return 1;
- }
- } else {
- debug(F101,"TCP keepalive SO_KEEPALIVE unchanged","",
- get_keepalive_opt16);
- tcp_keepalive = onoff;
- return 1;
- }
- return(0);
- }
-#endif /* OS2 */
- debug(F111,"TCP keepalive error: SO_KEEPALIVE","len",x);
- debug(F111,
- "TCP keepalive SO_KEEPALIVE",
- "expected len",
- sizeof(get_keepalive_opt)
- );
- debug(F111,
- "TCP keepalive SO_KEEPALIVE",
- "keepalive_opt",
- get_keepalive_opt
- );
- } else if (get_keepalive_opt != onoff) {
- set_keepalive_opt = onoff;
- if (setsockopt(sock,
- SOL_SOCKET,
- SO_KEEPALIVE,
- (char *)&set_keepalive_opt,
- sizeof(set_keepalive_opt))
- ) {
- debug(F111,
- "TCP keepalive can't clear SO_KEEPALIVE",
- ck_errstr(),
- errno
- );
- tcp_keepalive = get_keepalive_opt;
- } else {
- debug(F101,
- "TCP keepalive new SO_KEEPALIVE",
- "",
- set_keepalive_opt
- );
- tcp_keepalive = onoff;
- return 1;
- }
- } else {
- debug(F101,"TCP keepalive SO_KEEPALIVE unchanged",
- "",
- get_keepalive_opt
- );
- tcp_keepalive = onoff;
- return 1;
- }
-#else
- debug(F100,"TCP keepalive SO_KEEPALIVE not defined","",0);
-#endif /* SO_KEEPALIVE */
-#else
- debug(F100,"TCP keepalive SO_SOCKET not defined","",0);
-#endif /* SOL_SOCKET */
- return(0);
-}
-
-int
-dontroute(sock,onoff) int sock; int onoff; {
-#ifdef SOL_SOCKET
-#ifdef SO_DONTROUTE
- int get_dontroute_opt;
- int set_dontroute_opt;
- SOCKOPT_T x;
-
-#ifdef IKSD
- if (!inserver)
-#endif /* IKSD */
- if (sock == -1 ||
- nettype != NET_TCPA && nettype != NET_TCPB && nettype != NET_SSH
- || ttmdm >= 0) {
- tcp_dontroute = onoff;
- return 1;
- }
- x = sizeof(get_dontroute_opt);
- if (getsockopt(sock,
- SOL_SOCKET, SO_DONTROUTE, (char *)&get_dontroute_opt, &x)) {
- debug(F111,"TCP dontroute can't get SO_DONTROUTE",ck_errstr(),errno);
- } else if (x != sizeof(get_dontroute_opt)) {
-#ifdef OS2
- short get_dontroute_opt16;
- short set_dontroute_opt16;
- if (x == sizeof(get_dontroute_opt16)) {
- debug(F111,"TCP dontroute warning: SO_DONTROUTE",
- "len is 16-bit",x);
- if (getsockopt(sock,
- SOL_SOCKET, SO_DONTROUTE,
- (char *)&get_dontroute_opt16, &x)
- ) {
- debug(F111,
- "TCP dontroute can't get SO_DONTROUTE",
- ck_errstr(),
- errno
- );
- } else if (get_dontroute_opt16 != onoff) {
- set_dontroute_opt16 = onoff;
- if (setsockopt(sock,
- SOL_SOCKET,
- SO_DONTROUTE,
- (char *)&set_dontroute_opt16,
- sizeof(set_dontroute_opt16))
- ) {
- debug(F111,
- "TCP dontroute can't clear SO_DONTROUTE",
- ck_errstr(),
- errno
- );
- tcp_dontroute = get_dontroute_opt16;
- } else {
- debug(F101,
- "TCP dontroute new SO_DONTROUTE","",
- set_dontroute_opt16);
- tcp_dontroute = set_dontroute_opt16;
- return 1;
- }
- } else {
- debug(F101,"TCP dontroute SO_DONTROUTE unchanged","",
- get_dontroute_opt16);
- tcp_dontroute = onoff;
- return 1;
- }
- return(0);
- }
-#endif /* OS2 */
- debug(F111,"TCP dontroute error: SO_DONTROUTE","len",x);
- debug(F111,
- "TCP dontroute SO_DONTROUTE",
- "expected len",
- sizeof(get_dontroute_opt)
- );
- debug(F111,
- "TCP dontroute SO_DONTROUTE",
- "dontroute_opt",
- get_dontroute_opt
- );
- } else if (get_dontroute_opt != onoff) {
- set_dontroute_opt = onoff;
- if (setsockopt(sock,
- SOL_SOCKET,
- SO_DONTROUTE,
- (char *)&set_dontroute_opt,
- sizeof(set_dontroute_opt))
- ) {
- debug(F111,
- "TCP dontroute can't clear SO_DONTROUTE",
- ck_errstr(),
- errno
- );
- tcp_dontroute = get_dontroute_opt;
- } else {
- debug(F101,
- "TCP dontroute new SO_DONTROUTE",
- "",
- set_dontroute_opt
- );
- tcp_dontroute = onoff;
- return 1;
- }
- } else {
- debug(F101,"TCP dontroute SO_DONTROUTE unchanged",
- "",
- get_dontroute_opt
- );
- tcp_dontroute = onoff;
- return 1;
- }
-#else
- debug(F100,"TCP dontroute SO_DONTROUTE not defined","",0);
-#endif /* SO_DONTROUTE */
-#else
- debug(F100,"TCP dontroute SO_SOCKET not defined","",0);
-#endif /* SOL_SOCKET */
- return(0);
-}
-
-int
-no_delay(sock,onoff) int sock; int onoff; {
-#ifdef SOL_SOCKET
-#ifdef TCP_NODELAY
- int get_nodelay_opt;
- int set_nodelay_opt;
- SOCKOPT_T x;
-
-#ifdef IKSD
- if (!inserver)
-#endif /* IKSD */
- if (sock == -1 ||
- nettype != NET_TCPA && nettype != NET_TCPB && nettype != NET_SSH
- || ttmdm >= 0) {
- tcp_nodelay = onoff;
- return(1);
- }
- x = sizeof(get_nodelay_opt);
- if (getsockopt(sock,IPPROTO_TCP,TCP_NODELAY,
- (char *)&get_nodelay_opt,&x)) {
- debug(F111,
- "TCP no_delay can't get TCP_NODELAY",
- ck_errstr(),
- errno);
- } else if (x != sizeof(get_nodelay_opt)) {
-#ifdef OS2
- short get_nodelay_opt16;
- short set_nodelay_opt16;
- if (x == sizeof(get_nodelay_opt16)) {
- debug(F111,"TCP no_delay warning: TCP_NODELAY","len is 16-bit",x);
- if (getsockopt(sock,
- IPPROTO_TCP, TCP_NODELAY,
- (char *)&get_nodelay_opt16, &x)
- ) {
- debug(F111,
- "TCP no_delay can't get TCP_NODELAY",
- ck_errstr(),
- errno);
- } else if (get_nodelay_opt16 != onoff) {
- set_nodelay_opt16 = onoff;
- if (setsockopt(sock,
- IPPROTO_TCP,
- TCP_NODELAY,
- (char *)&set_nodelay_opt16,
- sizeof(set_nodelay_opt16))
- ) {
- debug(F111,
- "TCP no_delay can't clear TCP_NODELAY",
- ck_errstr(),
- errno);
- tcp_nodelay = get_nodelay_opt16;
- } else {
- debug(F101,
- "TCP no_delay new TCP_NODELAY",
- "",
- set_nodelay_opt16);
- tcp_nodelay = onoff;
- return 1;
- }
- } else {
- debug(F101,"TCP no_delay TCP_NODELAY unchanged","",
- get_nodelay_opt16);
- tcp_nodelay = onoff;
- return 1;
- }
- return(0);
- }
-#endif /* OS2 */
- debug(F111,"TCP no_delay error: TCP_NODELAY","len",x);
- debug(F111,"TCP no_delay TCP_NODELAY","expected len",
- sizeof(get_nodelay_opt));
- debug(F111,"TCP no_delay TCP_NODELAY","nodelay_opt",get_nodelay_opt);
- } else if (get_nodelay_opt != onoff) {
- set_nodelay_opt = onoff;
- if (setsockopt(sock,
- IPPROTO_TCP,
- TCP_NODELAY,
- (char *)&set_nodelay_opt,
- sizeof(set_nodelay_opt))) {
- debug(F111,
- "TCP no_delay can't clear TCP_NODELAY",
- ck_errstr(),
- errno
- );
- tcp_nodelay = get_nodelay_opt;
- } else {
- debug(F101,"TCP no_delay new TCP_NODELAY","",set_nodelay_opt);
- tcp_nodelay = onoff;
- return 1;
- }
- } else {
- debug(F101,"TCP no_delay TCP_NODELAY unchanged","",get_nodelay_opt);
- tcp_nodelay = onoff;
- return(1);
- }
-#else
- debug(F100,"TCP no_delay TCP_NODELAY not defined","",0);
-#endif /* TCP_NODELAY */
-#else
- debug(F100,"TCP no_delay SO_SOCKET not defined","",0);
-#endif /* SOL_SOCKET */
- return 0;
-}
-#endif /* datageneral */
-#endif /* NOTCPOPTS */
-
-#ifdef SUNX25
-#ifndef X25_WR_FACILITY
-/* For Solaris 2.3 / SunLink 8.x - see comments in ckcnet.h */
-void
-bzero(s,n) char *s; int n; {
- memset(s,0,n);
-}
-#endif /* X25_WR_FACILITY */
-#endif /* SUNX25 */
-
-#ifdef TCPSOCKET
-#ifndef OS2
-#ifndef NOLISTEN
-
-#ifdef BSDSELECT
-#ifndef VMS
-#ifndef BELLV10
-#ifndef datageneral
-#ifdef hp9000s500 /* HP-9000/500 HP-U 5.21 */
-#include <time.h>
-#else
-
-/****** THIS SECTION ADDED BY STEVE RANCE - OS9 NETWORK SERVER
-* ------------------------------------------------------
-*
-* Due to OS9's Lack of a select() call, the following seems to be
-* enough to fool the rest of the code into compiling. The only
-* effect that I can see is using control L to refresh the status
-* display gets qued up until some network packets arrive.
-*
-* This solution is by no means elegant but works enough to be
-* a (the) solution.
-*
-* Also with the defines I had specified in my makefile I had to
-* have an #endif right at the end of the file when compiling.
-* I did not bother speding time to find out why.
-*
-* COPTS = -to=osk -d=OSK -d=TCPSOCKET -d=SELECT -d=VOID=void -d=SIG_V \
-* -d=DYNAMIC -d=PARSENSE -d=KANJI -d=MYCURSES -d=ZFCDAT \
-* -d=CK_APC -d=CK_REDIR -d=RENAME -d=CK_TTYFD -d=NOOLDMODEMS \
-* -d=CK_ANSIC -d=CK_XYZ -tp=68040d -l=netdb.l -l=socklib.l \
-* -l=termlib.l -l=math.l -l=sys_clib.l
-*
-* stever@ozemail.com.au
-*/
-
-#ifdef OSK
-#define BSDSELECT /* switch on BSD select code */
-#define FD_SETSIZE 32 /* Max # of paths in OS9 */
-#define FD_ZERO(p) ((*p)=0)
-#define FD_SET(n,b) ((*b)|=(1<<(n)))
-#define FD_ISSET(n,b) 1 /* always say data is ready */
-#define select(a,b,c,d,e) 1 /* always say 1 path has data */
-typedef int fd_set; /* keep BSD Code Happy */
-struct timeval {int tv_sec,tv_usec;}; /* keep BSD Code Happy */
-
-/****** END OF OS9 MODS FROM STEVE RANCE **************************/
-#endif /* OSK */
-
-#include <sys/time.h>
-#endif /* hp9000s500 */
-#endif /* datageneral */
-#endif /* BELLV10 */
-#endif /* VMS */
-#ifdef SELECT_H
-#include <sys/select.h>
-#endif /* SELECT_H */
-#endif /* BSDSELECT */
-
-#ifdef SELECT
-#ifdef CK_SCOV5
-#include <sys/select.h>
-#endif /* CK_SCOV5 */
-#endif /* SELECT */
-
-#ifdef NOTUSED
-/* T C P S O C K E T _ O P E N -- Open a preexisting socket number */
-
-int
-tcpsocket_open(name,lcl,nett,timo) char * name; int * lcl; int nett; int timo {
- int on = 1;
- static struct servent *service, servrec;
- static struct hostent *host;
- static struct sockaddr_in saddr;
- static
-#ifdef UCX50
- unsigned
-#endif /* UCX50 */
- int saddrlen;
-#ifdef BSDSELECT
- fd_set rfds;
- struct timeval tv;
-#else
-#ifdef BELLSELECT
- fd_set rfds;
-#else
- fd_set rfds;
- fd_set rfds;
- struct timeval {
- long tv_sec;
- long tv_usec;
- } tv;
-#endif /* BELLSELECT */
-#endif /* BSDSELECT */
-
- debug(F101,"tcpsocket_open nett","",nett);
- *ipaddr = '\0';
-
- if (nett != NET_TCPB)
- return(-1); /* BSD socket support */
-
- netclos(); /* Close any previous connection. */
- ckstrncpy(namecopy, name, NAMECPYL); /* Copy the hostname. */
-#ifdef COMMENT
- /* Jeff's version from 30 Dec 2005 doesn't inhibit Telnet */
- if (ttnproto != NP_TCPRAW &&
- ttnproto != NP_SSL_RAW &&
- ttnproto != NP_TLS_RAW)
- ttnproto = NP_NONE; /* No protocol selected yet. */
-#else
- /* fdc's version from 4 Dec 2005 works ok */
- if (ttnproto != NP_TCPRAW)
- ttnproto = NP_NONE; /* No protocol selected yet. */
-#endif /* COMMENT */
- debug(F110,"tcpsocket_open namecopy",namecopy,0);
-
- /* Assign the socket number to ttyfd and then fill in tcp structures */
- ttyfd = atoi(&name[1]);
- debug(F111,"tcpsocket_open","ttyfd",ttyfd);
-
-#ifndef NOTCPOPTS
-#ifdef SOL_SOCKET
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-
-#ifndef datageneral
-#ifdef TCP_NODELAY
- no_delay(ttyfd,tcp_nodelay);
-#endif /* TCP_NODELAY */
-#ifdef SO_KEEPALIVE
- keepalive(ttyfd,tcp_keepalive);
-#endif /* SO_KEEPALIVE */
-#ifdef SO_LINGER
- ck_linger(ttyfd,tcp_linger, tcp_linger_tmo);
-#endif /* SO_LINGER */
-#ifdef SO_SNDBUF
- sendbuf(ttyfd,tcp_sendbuf);
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
- recvbuf(ttyfd,tcp_recvbuf);
-#endif /* SO_RCVBUF */
-#endif /* datageneral */
-#endif /* SOL_SOCKET */
-#endif /* NOTCPOPTS */
-
-#ifdef NT_TCP_OVERLAPPED
- OverlappedWriteInit();
- OverlappedReadInit();
-#endif /* NT_TCP_OVERLAPPED */
-
-
- /* Get the name of the host we are connected to */
-
- saddrlen = sizeof(saddr);
- getpeername(ttyfd,(struct sockaddr *)&saddr,&saddrlen);
-
- ckstrncpy(ipaddr,(char *)inet_ntoa(saddr.sin_addr),20);
-
- if (tcp_rdns == SET_ON
-#ifdef CK_KERBEROS
- || tcp_rdns == SET_AUTO &&
- (ck_krb5_is_installed() || ck_krb4_is_installed())
-#endif /* CK_KERBEROS */
-#ifndef NOHTTP
- && (tcp_http_proxy == NULL)
-#endif /* NOHTTP */
-#ifdef CK_SSL
- && !(ssl_only_flag || tls_only_flag)
-#endif /* CK_SSL */
- ) { /* Reverse DNS */
- if (!quiet) {
- printf(" Reverse DNS Lookup... ");
- fflush(stdout);
- }
- host = gethostbyaddr((char *)&saddr.sin_addr,4,PF_INET);
- debug(F110,"tcpsocket_open gethostbyaddr",host ? "OK" : "FAILED",0);
- if (host) {
- host = ck_copyhostent(host);
- debug(F100,"tcpsocket_open gethostbyaddr != NULL","",0);
- if (!quiet) {
- printf("(OK)\n");
- fflush(stdout);
- }
- ckstrncpy(name, host->h_name, 80);
- ckstrncat(name, ":", 80);
- ckstrncat(name,ckuitoa(ntohs(saddr.sin_port)), 80);
- if (!quiet
-#ifndef NOICP
- && !doconx
-#endif /* NOICP */
- )
- printf("%s connected on port %d\n",
- host->h_name,
- ntohs(saddr.sin_port)
- );
- } else if (!quiet)
- printf("Failed\n");
- } else if (!quiet)
- printf("(OK)\n");
-
- if (tcp_rdns != SET_ON || !host) {
- ckstrncpy(name,ipaddr,80);
- ckstrncat(name,":",80);
- ckstrncat(name,ckuitoa(ntohs(saddr.sin_port)),80);
- if (!quiet
-#ifdef NOICP
- && !doconx
-#endif /* NOICP */
- )
- printf("%s connected on port %d\n",ipaddr,ntohs(saddr.sin_port));
- }
- if (!quiet) fflush(stdout);
- ttnet = nett; /* TCP/IP (sockets) network */
-
-#ifdef RLOGCODE
- if (ntohs(saddr.sin_port) == 513)
- ttnproto = NP_LOGIN;
- else
-#endif /* RLOGCODE */
- /* Assume the service is TELNET. */
-#ifdef COMMENT
- /* Jeff's code from 2005/12/30 */
- if (ttnproto != NP_TCP_RAW &&
- ttnproto != NP_SSL_RAW &&
- ttnproto != NP_TLS_RAW)
-#else
- /* fdc's code from 2005/12/04 */
- if (ttnproto != NP_TCPRAW)
-#endif /* COMMENT */
- ttnproto = NP_TELNET; /* Yes, set global flag. */
-#ifdef CK_SECURITY
- /* Before Initialization Telnet/Rlogin Negotiations Init Kerberos */
- ck_auth_init((tcp_rdns && host && host->h_name && host->h_name[0]) ?
- host->h_name : ipaddr,
- ipaddr,
- uidbuf,
- ttyfd
- );
-#endif /* CK_SECURITY */
- if (tn_ini() < 0) /* Start/Reset TELNET negotiations */
- if (ttchk() < 0) /* Did it fail due to connect loss? */
- return(-1);
-
- if (*lcl < 0) *lcl = 1; /* Local mode. */
-
- return(0); /* Done. */
-}
-#endif /* NOTUSED */
-
-/* T C P S R V _ O P E N -- Open a TCP/IP Server connection */
-/*
- Calling conventions same as ttopen(), except third argument is network
- type rather than modem type.
-*/
-int
-tcpsrv_open(name,lcl,nett,timo) char * name; int * lcl; int nett; int timo; {
- char *p;
- int i, x;
- SOCKOPT_T on = 1;
- int ready_to_accept = 0;
- static struct servent *service, *service2, servrec;
- static struct hostent *host;
- static struct sockaddr_in saddr;
- struct sockaddr_in l_addr;
- GSOCKNAME_T l_slen;
-#ifdef UCX50
- static u_int saddrlen;
-#else
- static SOCKOPT_T saddrlen;
-#endif /* UCX50 */
-
-#ifdef BSDSELECT
- fd_set rfds;
- struct timeval tv;
-#else
-#ifdef BELLSELCT
- fd_set rfds;
-#else
- fd_set rfds;
- struct timeval {
- long tv_sec;
- long tv_usec;
- } tv;
-#endif /* BELLSELECT */
-#endif /* BSDSELECT */
-#ifdef CK_SSL
- int ssl_failed = 0;
-#endif /* CK_SSL */
-
- debug(F101,"tcpsrv_open nett","",nett);
- *ipaddr = '\0';
-
- if (nett != NET_TCPB)
- return(-1); /* BSD socket support */
-
- netclos(); /* Close any previous connection. */
- ckstrncpy(namecopy, name, NAMECPYL); /* Copy the hostname. */
- /* Don't do this. */
-#ifdef COMMENT
- /* fdc */
- if (ttnproto != NP_TCPRAW)
- ttnproto = NP_NONE; /* No protocol selected yet. */
-#endif /* COMMENT */
-#ifdef COMMENT
- /* Jeff */
- if (ttnproto != NP_TCP_RAW &&
- ttnproto != NP_SSL_RAW &&
- ttnproto != NP_TLS_RAW)
- ttnproto = NP_NONE; /* No protocol selected yet. */
-#endif /* COMMENT */
- debug(F110,"tcpsrv_open namecopy",namecopy,0);
-
- p = namecopy; /* Was a service requested? */
- while (*p != '\0' && *p != ':')
- p++; /* Look for colon */
- if (*p == ':') { /* Have a colon */
- *p++ = '\0'; /* Get service name or number */
- } else { /* Otherwise use kermit */
- p = "kermit";
- }
- debug(F110,"tcpsrv_open service requested",p,0);
- if (isdigit(*p)) { /* Use socket number without lookup */
- service = &servrec;
- service->s_port = htons((unsigned short)atoi(p));
- } else { /* Otherwise lookup the service name */
- service = getservbyname(p, "tcp");
- }
- if (!service && !strcmp("kermit",p)) { /* Use Kermit service port */
- service = &servrec;
- service->s_port = htons(1649);
- }
-#ifdef RLOGCODE
- if (service && !strcmp("login",p) && service->s_port != htons(513)) {
- fprintf(stderr,
- " Warning: login service on port %d instead of port 513\n",
- ntohs(service->s_port));
- fprintf(stderr, " Edit SERVICES file if RLOGIN fails to connect.\n");
- debug(F101,"tcpsrv_open login on port","",ntohs(service->s_port));
- }
-#endif /* RLOGCODE */
- if (!service) {
- fprintf(stderr, "Cannot find port for service: %s\n", p);
- debug(F111,"tcpsrv_open can't get service",p,errno);
- errno = 0; /* rather than mislead */
- return(-1);
- }
-
- /* If we currently have a listen active but port has changed then close */
-
- debug(F101,"tcpsrv_open checking previous connection","",tcpsrfd);
- debug(F101,"tcpsrv_open previous tcpsrv_port","",tcpsrv_port);
- if (tcpsrfd != -1 &&
- tcpsrv_port != ntohs((unsigned short)service->s_port)) {
- debug(F100,"tcpsrv_open closing previous connection","",0);
-#ifdef TCPIPLIB
- socket_close(tcpsrfd);
-#else
- close(tcpsrfd);
-#endif /* TCPIPLIB */
- tcpsrfd = -1;
- }
- debug(F100,"tcpsrv_open tcpsrfd","",tcpsrfd);
- if (tcpsrfd == -1) {
-
- /* Set up socket structure and get host address */
-
- bzero((char *)&saddr, sizeof(saddr));
- debug(F100,"tcpsrv_open bzero ok","",0);
- saddr.sin_family = AF_INET;
- if (tcp_address) {
-#ifdef INADDRX
- inaddrx = inet_addr(tcp_address);
- saddr.sin_addr.s_addr = *(unsigned long *)&inaddrx;
-#else
- saddr.sin_addr.s_addr = inet_addr(tcp_address);
-#endif /* INADDRX */
- } else
- saddr.sin_addr.s_addr = INADDR_ANY;
-
- /* Get a file descriptor for the connection. */
-
- saddr.sin_port = service->s_port;
- ipaddr[0] = '\0';
-
- debug(F100,"tcpsrv_open calling socket","",0);
- if ((tcpsrfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("TCP socket error");
- debug(F101,"tcpsrv_open socket error","",errno);
- return (-1);
- }
- errno = 0;
-
- /* Specify the Port may be reused */
-
- debug(F100,"tcpsrv_open calling setsockopt","",0);
- x = setsockopt(tcpsrfd,
- SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof on);
- debug(F101,"tcpsrv_open setsockopt","",x);
-
- /* Now bind to the socket */
- printf("\nBinding socket to port %d ...\n",
- ntohs((unsigned short)service->s_port));
- if (bind(tcpsrfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
- i = errno; /* Save error code */
-#ifdef TCPIPLIB
- socket_close(tcpsrfd);
-#else /* TCPIPLIB */
- close(tcpsrfd);
-#endif /* TCPIPLIB */
- tcpsrfd = -1;
- tcpsrv_port = 0;
- ttyfd = -1;
- wasclosed = 1;
- errno = i; /* and report this error */
- debug(F101,"tcpsrv_open bind errno","",errno);
- printf("?Unable to bind to socket (errno = %d)\n",errno);
- return(-1);
- }
- debug(F100,"tcpsrv_open bind OK","",0);
- printf("Listening ...\n");
- if (listen(tcpsrfd, 15) < 0) {
- i = errno; /* Save error code */
-#ifdef TCPIPLIB
- socket_close(tcpsrfd);
-#else /* TCPIPLIB */
- close(tcpsrfd);
-#endif /* TCPIPLIB */
- tcpsrfd = -1;
- tcpsrv_port = 0;
- ttyfd = -1;
- wasclosed = 1;
- errno = i; /* And report this error */
- debug(F101,"tcpsrv_open listen errno","",errno);
- return(-1);
- }
- debug(F100,"tcpsrv_open listen OK","",0);
- tcpsrv_port = ntohs((unsigned short)service->s_port);
- }
-
-#ifdef CK_SSL
- if (ck_ssleay_is_installed()) {
- if (!ssl_tn_init(SSL_SERVER)) {
- ssl_failed = 1;
- if (bio_err!=NULL) {
- BIO_printf(bio_err,"do_ssleay_init() failed\n");
- ERR_print_errors(bio_err);
- } else {
- fflush(stderr);
- fprintf(stderr,"do_ssleay_init() failed\n");
- ERR_print_errors_fp(stderr);
- }
- if (tls_only_flag || ssl_only_flag) {
-#ifdef TCPIPLIB
- socket_close(ttyfd);
- socket_close(tcpsrfd);
-#else /* TCPIPLIB */
- close(ttyfd);
- close(tcpsrfd);
-#endif /* TCPIPLIB */
- ttyfd = -1;
- wasclosed = 1;
- tcpsrfd = -1;
- tcpsrv_port = 0;
- return(-1);
- }
- /* we will continue to accept the connection */
- /* without SSL or TLS support unless required. */
- if ( TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- }
- }
-#endif /* CK_SSL */
-
- printf("\nWaiting to Accept a TCP/IP connection on port %d ...\n",
- ntohs((unsigned short)service->s_port));
- saddrlen = sizeof(saddr);
-
-#ifdef BSDSELECT
- tv.tv_sec = tv.tv_usec = 0L;
- if (timo < 0)
- tv.tv_usec = (long) -timo * 10000L;
- else
- tv.tv_sec = timo;
- debug(F101,"tcpsrv_open BSDSELECT","",timo);
-#else
- debug(F101,"tcpsrv_open not BSDSELECT","",timo);
-#endif /* BSDSELECT */
-
- if (timo) {
- while (!ready_to_accept) {
-#ifdef BSDSELECT
- FD_ZERO(&rfds);
- FD_SET(tcpsrfd, &rfds);
- ready_to_accept =
- ((select(FD_SETSIZE,
-#ifdef HPUX
-#ifdef HPUX1010
- (fd_set *)
-#else
-
- (int *)
-#endif /* HPUX1010 */
-#else
-#ifdef __DECC
-#ifdef INTSELECT
- (int *)
-#else /* def INTSELECT */
- (fd_set *)
-#endif /* def INTSELECT [else] */
-#endif /* __DECC */
-#endif /* HPUX */
- &rfds, NULL, NULL, &tv) > 0) &&
- FD_ISSET(tcpsrfd, &rfds));
-#else /* BSDSELECT */
-#ifdef IBMSELECT
-#define ck_sleepint 250
- ready_to_accept =
- (select(&tcpsrfd, 1, 0, 0,
- timo < 0 ? -timo :
- (timo > 0 ? timo * 1000L : ck_sleepint)) == 1
- );
-#else
-#ifdef BELLSELECT
- FD_ZERO(rfds);
- FD_SET(tcpsrfd, rfds);
- ready_to_accept =
- ((select(128, rfds, NULL, NULL, timo < 0 ? -timo :
- (timo > 0 ? timo * 1000L)) > 0) &&
- FD_ISSET(tcpsrfd, rfds));
-#else
-/* Try this - what's the worst that can happen... */
-
- FD_ZERO(&rfds);
- FD_SET(tcpsrfd, &rfds);
- ready_to_accept =
- ((select(FD_SETSIZE,
- (fd_set *) &rfds, NULL, NULL, &tv) > 0) &&
- FD_ISSET(tcpsrfd, &rfds));
-
-#endif /* BELLSELECT */
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
- }
- }
- if (ready_to_accept || timo == 0) {
- if ((ttyfd = accept(tcpsrfd,
- (struct sockaddr *)&saddr,&saddrlen)) < 0) {
- i = errno; /* save error code */
-#ifdef TCPIPLIB
- socket_close(tcpsrfd);
-#else /* TCPIPLIB */
- close(tcpsrfd);
-#endif /* TCPIPLIB */
- ttyfd = -1;
- wasclosed = 1;
- tcpsrfd = -1;
- tcpsrv_port = 0;
- errno = i; /* and report this error */
- debug(F101,"tcpsrv_open accept errno","",errno);
- return(-1);
- }
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-
-#ifndef NOTCPOPTS
-#ifndef datageneral
-#ifdef SOL_SOCKET
-#ifdef TCP_NODELAY
- no_delay(ttyfd,tcp_nodelay);
- debug(F101,"tcpsrv_open no_delay","",tcp_nodelay);
-#endif /* TCP_NODELAY */
-#ifdef SO_KEEPALIVE
- keepalive(ttyfd,tcp_keepalive);
- debug(F101,"tcpsrv_open keepalive","",tcp_keepalive);
-#endif /* SO_KEEPALIVE */
-#ifdef SO_LINGER
- ck_linger(ttyfd,tcp_linger, tcp_linger_tmo);
- debug(F101,"tcpsrv_open linger","",tcp_linger_tmo);
-#endif /* SO_LINGER */
-#ifdef SO_SNDBUF
- sendbuf(ttyfd,tcp_sendbuf);
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
- recvbuf(ttyfd,tcp_recvbuf);
-#endif /* SO_RCVBUF */
-#endif /* SOL_SOCKET */
-#endif /* datageneral */
-#endif /* NOTCPOPTS */
-
- ttnet = nett; /* TCP/IP (sockets) network */
- tcp_incoming = 1; /* This is an incoming connection */
- sstelnet = 1; /* Do server-side Telnet protocol */
-
- /* See if the service is TELNET. */
- x = (unsigned short)service->s_port;
- service2 = getservbyname("telnet", "tcp");
- if (service2 && x == service2->s_port) {
-#ifdef COMMENT
- /* Jeff 2005/12/30 */
- if (ttnproto != NP_TCPRAW && /* Yes... */
- ttnproto != NP_SSL_RAW &&
- ttnproto != NP_TLS_RAW) /* and if raw port not requested */
-#else
- /* fdc 2005/12/04 */
- if (ttnproto != NP_TCPRAW) /* Yes and if raw port not requested */
-#endif /* */
- ttnproto = NP_TELNET; /* set protocol to TELNET. */
- }
- ckstrncpy(ipaddr,(char *)inet_ntoa(saddr.sin_addr),20);
- if (tcp_rdns) {
- if (!quiet) {
- printf(" Reverse DNS Lookup... ");
- fflush(stdout);
- }
- if (host = gethostbyaddr((char *)&saddr.sin_addr,4,PF_INET)) {
- host = ck_copyhostent(host);
- debug(F100,"tcpsrv_open gethostbyaddr != NULL","",0);
- if (!quiet) {
- printf("(OK)\n");
- fflush(stdout);
- }
- name[0] = '*';
- ckstrncpy(&name[1],host->h_name,78);
- ckstrncat(name,":",80-strlen(name));
- ckstrncat(name,p,80-strlen(name));
- if (!quiet
-#ifndef NOICP
- && !doconx
-#endif /* NOICP */
- )
- printf("%s connected on port %s\n",host->h_name,p);
- } else {
- if (!quiet) printf("Failed.\n");
- }
- } else if (!quiet) printf("(OK)\n");
-
- if (!tcp_rdns || !host) {
- ckstrncpy(name,ipaddr,80);
- ckstrncat(name,":",80);
- ckstrncat(name,ckuitoa(ntohs(saddr.sin_port)),80);
- if (!quiet
-#ifndef NOICP
- && !doconx
-#endif /* NOICP */
- )
- printf("%s connected on port %d\n",ipaddr,ntohs(saddr.sin_port));
- }
- if (!quiet) fflush(stdout);
-
-#ifdef CK_SECURITY
- /* Before Initialization Telnet/Rlogin Negotiations Init Kerberos */
- ck_auth_init((tcp_rdns && host && host->h_name && host->h_name[0]) ?
- (char *)host->h_name : ipaddr,
- ipaddr,
- uidbuf,
- ttyfd
- );
-#endif /* CK_SECURITY */
-
-#ifdef CK_SSL
- if (ck_ssleay_is_installed() && !ssl_failed) {
- if (ck_ssl_incoming(ttyfd) < 0) {
-#ifdef TCPIPLIB
- socket_close(ttyfd);
- socket_close(tcpsrfd);
-#else /* TCPIPLIB */
- close(ttyfd);
- close(tcpsrfd);
-#endif /* TCPIPLIB */
- ttyfd = -1;
- wasclosed = 1;
- tcpsrfd = -1;
- tcpsrv_port = 0;
- return(-1);
- }
- }
-#endif /* CK_SSL */
-
-#ifndef datageneral
- /* Find out our own IP address. */
- l_slen = sizeof(l_addr);
- bzero((char *)&l_addr, l_slen);
-#ifndef EXCELAN
- if (!getsockname(ttyfd, (struct sockaddr *)&l_addr, &l_slen)) {
- char * s = (char *)inet_ntoa(l_addr.sin_addr);
- ckstrncpy(myipaddr, s,20);
- debug(F110,"getsockname",myipaddr,0);
- }
-#endif /* EXCELAN */
-#endif /* datageneral */
-
- if (tn_ini() < 0) /* Start TELNET negotiations. */
- if (ttchk() < 0) { /* Disconnected? */
- i = errno; /* save error code */
-#ifdef TCPIPLIB
- socket_close(tcpsrfd);
-#else /* TCPIPLIB */
- close(tcpsrfd);
-#endif /* TCPIPLIB */
- ttyfd = -1;
- wasclosed = 1;
- tcpsrfd = -1;
- tcpsrv_port = 0;
- errno = i; /* and report this error */
- debug(F101,"tcpsrv_open accept errno","",errno);
- return(-1);
- }
- debug(F101,"tcpsrv_open service","",x);
- if (*lcl < 0) /* Set local mode. */
- *lcl = 1;
-
-#ifdef CK_KERBEROS
-#ifdef KRB5_U2U
- if ( ttnproto == NP_K5U2U ) {
- if (k5_user_to_user_server_auth() != 0) {
- i = errno; /* save error code */
-#ifdef TCPIPLIB
- socket_close(tcpsrfd);
-#else /* TCPIPLIB */
- close(tcpsrfd);
-#endif /* TCPIPLIB */
- ttyfd = -1;
- wasclosed = 1;
- tcpsrfd = -1;
- tcpsrv_port = 0;
- errno = i; /* and report this error */
- debug(F101,"tcpsrv_open accept errno","",errno);
- return(-1);
- }
- }
-#endif /* KRB5_U2U */
-#endif /* CK_KERBEROS */
- return(0); /* Done. */
- } else {
- i = errno; /* save error code */
-#ifdef TCPIPLIB
- socket_close(tcpsrfd);
-#else /* TCPIPLIB */
- close(tcpsrfd);
-#endif /* TCPIPLIB */
- ttyfd = -1;
- wasclosed = 1;
- tcpsrfd = -1;
- tcpsrv_port = 0;
- errno = i; /* and report this error */
- debug(F101,"tcpsrv_open accept errno","",errno);
- return(-1);
- }
-}
-#endif /* NOLISTEN */
-#endif /* OS2 */
-#endif /* TCPSOCKET */
-#endif /* NONET */
-
-#ifdef TCPSOCKET
-char *
-ckname2addr(name) char * name;
-{
-#ifdef HPUX5
- return("");
-#else
- struct hostent *host;
-
- if (name == NULL || *name == '\0')
- return("");
-
- host = gethostbyname(name);
- if ( host ) {
- host = ck_copyhostent(host);
- return(inet_ntoa(*((struct in_addr *) host->h_addr)));
- }
- return("");
-#endif /* HPUX5 */
-}
-
-char *
-ckaddr2name(addr) char * addr;
-{
-#ifdef HPUX5
- return("");
-#else
- struct hostent *host;
- struct in_addr sin_addr;
-
- if (addr == NULL || *addr == '\0')
- return("");
-
- sin_addr.s_addr = inet_addr(addr);
- host = gethostbyaddr((char *)&sin_addr,4,AF_INET);
- if (host) {
- host = ck_copyhostent(host);
- return((char *)host->h_name);
- }
- return("");
-#endif /* HPUX5 */
-}
-#endif /* TCPSOCKET */
-
-unsigned long peerxipaddr = 0L;
-
-char *
-ckgetpeer() {
-#ifdef TCPSOCKET
- static char namebuf[256];
- static struct hostent *host;
- static struct sockaddr_in saddr;
-#ifdef GPEERNAME_T
- static GPEERNAME_T saddrlen;
-#else
-#ifdef PTX
- static size_t saddrlen;
-#else
-#ifdef AIX42
- /* It's size_t in 4.2 but int in 4.1 and earlier. */
- /* Note: the 4.2 man page lies; believe socket.h. */
- static size_t saddrlen;
-#else
-#ifdef UNIXWARE
- static size_t saddrlen;
-#else /* UNIXWARE */
-#ifdef DEC_TCPIP
-/* 2010-03-08 SMS.
- * Coincidentally, the condition for integer arguments in select(),
- * which is actually "defined( _DECC_V4_SOURCE)", works for an integer
- * argument in getpeername(). Sadly, due to a lack of foresight,
- * "defined( _DECC_V4_SOURCE)" doesn't work with DEC C V4.0, so the
- * user-specified INTSELECT is used instead. Most likely, "size_t"
- * should be used instead of "unsigned int", but I'm a coward.
- */
-#ifdef INTSELECT
- static int saddrlen;
-#else /* def INTSELECT */
- static unsigned int saddrlen;
-#endif /* def INTSELECT [else] */
-#else
-#ifdef MACOSX10
- static unsigned int saddrlen;
-#else
-#ifdef CK_64BIT
- static socklen_t saddrlen;
-#else
- static int saddrlen;
-#endif /* CK_64BIT */
-#endif /* MACOSX10 */
-#endif /* DEC_TCPIP */
-#endif /* UNIXWARE */
-#endif /* AIX42 */
-#endif /* PTX */
-#endif /* GPEERNAME_T */
- saddrlen = sizeof(saddr);
- if (getpeername(ttyfd,(struct sockaddr *)&saddr,&saddrlen) < 0) {
- debug(F111,"ckgetpeer failure",ckitoa(ttyfd),errno);
- return(NULL);
- }
- host = gethostbyaddr((char *)&saddr.sin_addr,4,AF_INET);
- if (host) {
- host = ck_copyhostent(host);
- ckstrncpy(namebuf,(char *)host->h_name,80);
- } else {
- ckstrncpy(namebuf,(char *)inet_ntoa(saddr.sin_addr),80);
- }
- peerxipaddr = ntohl(saddr.sin_addr.s_addr);
- debug(F111,"ckgetpeer",namebuf,peerxipaddr);
- return(namebuf);
-#else
- return(NULL);
-#endif /* TCPSOCKET */
-}
-
-/* Get fully qualified IP hostname */
-
-#ifndef NONET
-char *
-#ifdef CK_ANSIC
-ckgetfqhostname(char * name)
-#else
-ckgetfqhostname(name) char * name;
-#endif /* CK_ANSIC */
-{
-#ifdef NOCKGETFQHOST
-
- return(name);
-
-#else /* If the following code dumps core, define NOCKGETFQHOST and rebuild. */
-
- static char namebuf[256];
- struct hostent *host=NULL;
- struct sockaddr_in r_addr;
- int i;
-
- debug(F110,"ckgetfqhn()",name,0);
-
- ckstrncpy(namebuf,name,256);
- namebuf[255] = '\0';
- i = ckindex(":",namebuf,0,0,0);
- if (i)
- namebuf[i-1] = '\0';
-
- bzero((char *)&r_addr, sizeof(r_addr));
-
- host = gethostbyname(namebuf);
- if (host) {
- host = ck_copyhostent(host);
- debug(F100,"ckgetfqhn() gethostbyname != NULL","",0);
- r_addr.sin_family = host->h_addrtype;
-#ifdef HADDRLIST
-#ifdef h_addr
- /* This is for trying multiple IP addresses - see <netdb.h> */
- if (!(host->h_addr_list))
- goto exit_func;
- bcopy(host->h_addr_list[0],
- (caddr_t)&r_addr.sin_addr,
- host->h_length
- );
-#else
- bcopy(host->h_addr, (caddr_t)&r_addr.sin_addr, host->h_length);
-#endif /* h_addr */
-#else /* HADDRLIST */
- bcopy(host->h_addr, (caddr_t)&r_addr.sin_addr, host->h_length);
-#endif /* HADDRLIST */
-#ifdef COMMENT
-#ifndef EXCELAN
- debug(F111,"BCOPY","host->h_addr",host->h_addr);
-#endif /* EXCELAN */
- debug(F111,"BCOPY"," (caddr_t)&r_addr.sin_addr",
- (caddr_t)&r_addr.sin_addr);
-#endif /* COMMENT */
- debug(F111,"BCOPY","host->h_length",host->h_length);
-
-#ifdef NT
- /* Windows 95/98 requires a 1 second wait between calls to Microsoft */
- /* provided DNS functions. Otherwise, the TTL of the DNS response */
- /* is ignored. */
- if (isWin95())
- sleep(1);
-#endif /* NT */
- host = gethostbyaddr((char *)&r_addr.sin_addr,4,PF_INET);
- if (host) {
- host = ck_copyhostent(host);
- debug(F100,"ckgetfqhn() gethostbyaddr != NULL","",0);
- ckstrncpy(namebuf, host->h_name, 256);
- }
- }
-
-#ifdef HADDRLIST
-#ifdef h_addr
- exit_func:
-#endif /* h_addr */
-#endif /* HADDRLIST */
-
- if (i > 0)
- ckstrncat(namebuf,&name[i-1],256-strlen(namebuf)-strlen(&name[i-1]));
- debug(F110,"ckgetfqhn()",namebuf,0);
- return(namebuf);
-#endif /* NOCKGETFQHOST */
-}
-
-VOID
-#ifdef CK_ANSIC
-setnproto(char * p)
-#else
-setnproto(p) char * p;
-#endif /* CK_ANSIC */
-{
- if (!isdigit(*p)) {
- if (!strcmp("kermit",p))
- ttnproto = NP_KERMIT;
- else if (!strcmp("telnet",p))
- ttnproto = NP_TELNET;
- else if (!strcmp("http",p))
- ttnproto = NP_TCPRAW;
-#ifdef RLOGCODE
- else if (!strcmp("login",p))
- ttnproto = NP_RLOGIN;
-#endif /* RLOGCODE */
-#ifdef CK_SSL
- /* Commonly used SSL ports (might not be in services file) */
- else if (!strcmp("https",p)) {
- ttnproto = NP_SSL_RAW;
- ssl_only_flag = 1;
- } else if (!strcmp("ssl-telnet",p)) {
- ttnproto = NP_TELNET;
- ssl_only_flag = 1;
- } else if (!strcmp("telnets",p)) {
- ttnproto = NP_TELNET;
- ssl_only_flag = 1;
- }
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef RLOGCODE
- else if (!strcmp("klogin",p)) {
- if (ck_krb5_is_installed())
- ttnproto = NP_K5LOGIN;
- else if (ck_krb4_is_installed())
- ttnproto = NP_K4LOGIN;
- else
- ttnproto = NP_RLOGIN;
- } else if (!strcmp("eklogin",p)) {
- if (ck_krb5_is_installed())
- ttnproto = NP_EK5LOGIN;
- else if (ck_krb4_is_installed())
- ttnproto = NP_EK4LOGIN;
- else
- ttnproto = NP_RLOGIN;
- }
-#endif /* RLOGCODE */
-#endif /* CK_KERBEROS */
- else
- ttnproto = NP_NONE;
- } else {
- switch (atoi(p)) {
- case 23: /* Telnet */
- ttnproto = NP_TELNET;
- break;
- case 513:
- ttnproto = NP_RLOGIN;
- break;
- case 1649:
- ttnproto = NP_KERMIT;
- break;
-#ifdef CK_SSL
- case 443:
-#ifdef COMMENT
- /* Jeff 2005/12/30 */
- ttnproto = NP_SSL_RAW;
-#else
- /* fdc 2005/12/04 */
- ttnproto = NP_SSL;
-#endif /* COMMENT */
- ssl_only_flag = 1;
- break;
- case 151:
- case 992:
- ttnproto = NP_TELNET;
- ssl_only_flag = 1;
- break;
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
- case 543:
- if (ck_krb5_is_installed())
- ttnproto = NP_K5LOGIN;
- else if (ck_krb4_is_installed())
- ttnproto = NP_K4LOGIN;
- else
- ttnproto = NP_RLOGIN;
- break;
- case 2105:
- if (ck_krb5_is_installed())
- ttnproto = NP_EK5LOGIN;
- else if (ck_krb4_is_installed())
- ttnproto = NP_EK4LOGIN;
- else
- ttnproto = NP_RLOGIN;
- break;
-#endif /* CK_KERBEROS */
- case 80: /* HTTP */
- ttnproto = NP_TCPRAW;
- break;
- default:
- ttnproto = NP_NONE;
- break;
- }
- }
-}
-
-/* ckgetservice() is used to determine the port number for a given */
-/* service taking into account the use of DNS SRV records. */
-
-static struct servent servrec;
-static struct servent *
-ckgetservice(hostname, servicename, ip, iplen)
- char *hostname; char * servicename; char * ip; int iplen;
-{
- struct servent * service = NULL;
-#ifdef CK_DNS_SRV
- struct sockaddr * dns_addrs = NULL;
- int dns_naddrs = 0;
-#endif /* CK_DNS_SRV */
-
- if (isdigit(*servicename)) { /* Use socket number without lookup */
- service = &servrec;
- service->s_port = htons((unsigned short)atoi(servicename));
- } else { /* Otherwise lookup the service name */
-#ifdef CK_DNS_SRV
- if (tcp_dns_srv && !quiet) {
- printf(" DNS SRV Lookup... ");
- fflush(stdout);
- }
- if (tcp_dns_srv &&
- locate_srv_dns(hostname,
- servicename,
- "tcp",
- &dns_addrs,
- &dns_naddrs
- )
- ) {
- /* Use the first one. Eventually we should cycle through all */
- /* the returned IP addresses and port numbers. */
- struct sockaddr_in *sin = NULL;
-#ifdef BETADEBUG
- int i;
- printf("\r\n");
- for ( i=0;i<dns_naddrs;i++ ) {
- sin = (struct sockaddr_in *) &dns_addrs[i];
- printf("dns_addrs[%d] = %s %d\r\n", i,
- (char *)inet_ntoa(sin->sin_addr),
- ntohs(sin->sin_port));
- }
-#endif /* BETADEBUG */
- sin = (struct sockaddr_in *) &dns_addrs[0];
- if ( ip && iplen > 0 )
- ckstrncpy(ip,(char *)inet_ntoa(sin->sin_addr),iplen);
- service = &servrec;
- service->s_port = sin->sin_port;
-
- free(dns_addrs);
- dns_addrs = NULL;
- dns_naddrs = 0;
- } else
-#endif /* CK_DNS_SRV */
- service = getservbyname(servicename, "tcp");
- }
- if (!service) {
- if (!ckstrcmp("kermit",servicename,-1,0)) { /* Kermit service port */
- service = &servrec;
- service->s_port = htons(1649);
- } else if (!ckstrcmp("telnet",servicename,-1,0)) { /* Telnet port */
- service = &servrec;
- service->s_port = htons(23);
- } else if (!ckstrcmp("http",servicename,-1,0)) {
- service = &servrec;
- service->s_port = htons(80);
- }
-#ifdef RLOGCODE
- else if (!ckstrcmp("login",servicename,-1,0)) {
- service = &servrec;
- service->s_port = htons(513);
- }
-#endif /* RLOGCODE */
-#ifdef CK_SSL
- /* Commonly used SSL ports (might not be in services file) */
- else if (!ckstrcmp("https",servicename,-1,0)) {
- service = &servrec;
- service->s_port = htons(443);
- } else if (!ckstrcmp("ssl-telnet",servicename,-1,0)) {
- service = &servrec;
- service->s_port = htons(151);
- } else if (!ckstrcmp("telnets",servicename,-1,0)) {
- service = &servrec;
- service->s_port = htons(992);
- }
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef RLOGCODE
- else if (!ckstrcmp("klogin",servicename,-1,0)) {
- service = &servrec;
- service->s_port = htons(543);
- } else if (!ckstrcmp("eklogin",servicename,-1,0)) {
- service = &servrec;
- service->s_port = htons(2105);
- }
-#endif /* RLOGCODE */
-#endif /* CK_KERBEROS */
- }
- return(service);
-}
-
-/* N E T O P E N -- Open a network connection */
-/*
- Calling conventions same as ttopen(), except third argument is network
- type rather than modem type. Designed to be called from within ttopen.
-*/
-
-#define XXNAMELEN 256
-static char xxname[XXNAMELEN];
-
-int
-netopen(name, lcl, nett) char *name; int *lcl, nett; {
- char *p;
- int i, x, rc_inet_addr = 0, dns = 0;
-#ifdef TCPSOCKET
- int isconnect = 0;
-#ifdef SO_OOBINLINE
- int on = 1;
-#endif /* SO_OOBINLINE */
- struct servent *service=NULL;
- struct hostent *host=NULL;
- struct sockaddr_in r_addr;
- struct sockaddr_in sin;
- struct sockaddr_in l_addr;
- GSOCKNAME_T l_slen;
-#ifdef EXCELAN
- struct sockaddr_in send_socket;
-#endif /* EXCELAN */
-
-#ifdef INADDRX
-/* inet_addr() is of type struct in_addr */
-#ifdef datageneral
- extern struct in_addr inet_addr();
-#else
-#ifdef HPUX5WINTCP
- extern struct in_addr inet_addr();
-#endif /* HPUX5WINTCP */
-#endif /* datageneral */
- struct in_addr iax;
-#else
-#ifdef INADDR_NONE
- struct in_addr iax;
-#else /* INADDR_NONE */
- long iax;
-#endif /* INADDR_NONE */
-#endif /* INADDRX */
-#endif /* TCPSOCKET */
-
-#ifdef COMMENT
-/* This causes big trouble */
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif /* INADDR_NONE */
-#endif /* COMMENT */
-
-#ifdef SUNX25 /* Code for SunLink X.25 support */
-#define X29PID 1 /* X.29 Protocol ID */
-_PROTOTYP(SIGTYP x25oobh, (int) );
- CONN_DB x25host;
-#ifndef X25_WR_FACILITY
- FACILITY x25facil;
-#else
- FACILITY_DB x25facil;
-#endif /* X25_WR_FACILITY */
- static int needh = 1;
- PID_T pid;
- extern int linkid, lcn, x25ver;
-#endif /* SUNX25 */
-#ifdef ANYX25
- extern int revcall, closgr, cudata;
- extern char udata[];
-#endif /* ANYX25 */
-
-#ifdef IBMX25 /* Variables for IBM X25 */
- extern int x25port; /* Logical port to use */
- extern x25addr_t local_nua; /* Local X.25 address */
- extern x25addr_t remote_nua; /* Remote X.25 address */
- extern char x25name[]; /* X25 device name (sx25a0) */
- extern char x25dev[]; /* X25 device file /dev/x25pkt */
- ulong bind_flags = 0; /* Flags for binding the X25 stream */
- ulong token = 0; /* Temporary return code */
-#endif /* IBMX25 */
-
- debug(F101,"netopen nett","",nett);
- *ipaddr = '\0'; /* Initialize IP address string */
-
-#ifdef SUNX25
- if (nett == NET_SX25) { /* If network type is X.25 */
- netclos(); /* Close any previous net connection */
- ttnproto = NP_NONE; /* No protocol selected yet */
-
- /* Set up host structure */
- bzero((char *)&x25host,sizeof(x25host));
- if ((x25host.hostlen = pkx121(name,x25host.host)) < 0) {
- fprintf (stderr,"Invalid X.121 host address %s\n",name);
- errno = 0;
- return (-1);
- }
- x25host.datalen = X29PIDLEN;
- x25host.data[0] = X29PID;
-
- /* Set call user data if specified */
- if (cudata) {
- ckstrncpy((char *)x25host.data+X29PIDLEN,udata,(int)strlen(udata));
- x25host.datalen += (int)strlen(udata);
- }
-
- /* Open SunLink X.25 socket */
- if (!quiet && *name) {
- printf(" Trying %s... ", name);
- fflush(stdout);
- }
- if ((ttyfd = socket(AF_X25, SOCK_STREAM, 0)) < 0) {
- debug(F101,"netopen socket error","",errno);
- perror ("X.25 socket error");
- return (-1);
- }
-
- /* Setting X.25 out-of-band data handler */
- pid = getpid();
- if (ioctl(ttyfd,SIOCSPGRP,&pid)) {
- perror("X.25 set process group id error");
- return(-1);
- }
- (VOID) signal(SIGURG,x25oobh);
-
- /* Set reverse charge call and closed user group if requested */
- bzero ((char *)&x25facil,sizeof(x25facil));
-
-#ifndef X25_WR_FACILITY
-/* New SunLink (7.0 or 8.0, not sure which)... */
- x25facil.type = T_REVERSE_CHARGE; /* Reverse Charge */
- x25facil.f_reverse_charge = revcall ? 1 : 0;
- if (ioctl(ttyfd,X25_SET_FACILITY,&x25facil) < 0) {
- perror ("Setting X.25 reverse charge");
- return (-1);
- }
- if (closgr > -1) { /* Closed User Group (Outgoing) */
- bzero ((char *)&x25facil,sizeof(x25facil));
- x25facil.type = T_CUG;
- x25facil.f_cug_req = CUG_REQ_ACS;
- x25facil.f_cug_index = closgr;
- if (ioctl(ttyfd,X25_SET_FACILITY,&x25facil) < 0) {
- perror ("Setting X.25 closed user group");
- return (-1);
- }
- }
-#else
-/* Old SunLink 6.0 (or 7.0?)... */
- if (revcall) x25facil.reverse_charge = revcall;
- if (closgr > -1) {
- x25facil.cug_req = 1;
- x25facil.cug_index = closgr;
- }
- if (ioctl(ttyfd,X25_WR_FACILITY,&x25facil) < 0) {
- perror ("Setting X.25 facilities");
- return (-1);
- }
-#endif /* X25_WR_FACILITY */
-
- /* Need X.25 header with bits Q and M */
- if (ioctl (ttyfd,X25_HEADER,&needh) < 0) {
- perror ("Setting X.25 header");
- return (-1);
- }
-
- /* Connects to remote host via SunLink X.25 */
- if (connect(ttyfd,(struct sockaddr *)&x25host,sizeof(x25host)) < 0) {
- i = errno;
- debug(F101,"netopen connect errno","",i);
- if (i) {
- perror("netopen x25 connect");
- x25diag();
- }
- (VOID) netclos();
- ttyfd = -1;
- wasclosed = 1;
- ttnproto = NP_NONE;
- errno = i;
- return (-1);
- }
-
- /* Get X.25 link identification used for the connection */
- if (ioctl(ttyfd,X25_GET_LINK,&linkid) < 0) {
- perror ("Getting X.25 link id");
- return (-1);
- }
-
- /* Get X.25 logical channel number used for the connection */
- if (ioctl(ttyfd,X25_RD_LCGN,&lcn) < 0) {
- perror ("Getting X.25 lcn");
- return (-1);
- }
-
- /* Get SunLink X.25 version */
- if (ioctl(ttyfd,X25_VERSION,&x25ver) < 0) {
- perror ("Getting SunLink X.25 version");
- return (-1);
- }
- ttnet = nett; /* Sunlink X.25 network */
- ttnproto = NP_X3; /* PAD X.3, X.28, X.29 protocol */
- if (lcl) if (*lcl < 0) *lcl = 1; /* Local mode */
- return(0);
- } else /* Note that SUNX25 support can coexist with TCP/IP support. */
-#endif /* SUNX25 */
-
-#ifdef IBMX25
- /* riehm */
- if (nett == NET_IX25) { /* IBM AIX X.25 */
- netclos(); /* Close any previous net connection */
- ttnproto = NP_NONE; /* No protocol selected yet */
-
- /* find out who we are - this is not so easy on AIX */
- /* riehm: need to write the code that finds this out
- * automatically, or at least allow it to be configured
- * somehow
- */
- if (!local_nua[0] && !x25local_nua(local_nua)) {
- return(-1);
- }
-
- /* Initialise the X25 API (once per process? once per connection?) */
-
- debug(F110, "Opening ", x25dev, 0 );
- /* set O_NDELAY to allow polling? */
- if ((ttyfd = open(x25dev, O_RDWR)) < 0) {
- perror ("X.25 device open error");
- debug(F101,"netopen: device open error","",errno);
- return (-1);
- }
-
- /* push the NPI onto the STREAM */
- if (ioctl(ttyfd,I_PUSH,"npi") < 0 ) {
- close(ttyfd);
- ttyfd = -1;
- wasclosed = 1;
- perror( "kermit: netopen(): couldn't push npi on the X25 stream" );
- debug(F101,"netopen: can't push npi on the X25 stream","",errno);
- return (-1);
- }
-
- /* set up server mode - bind the x25 port and wait for
- * incoming connections
- */
- if (name[0] == '*') { /* Server */
- /* set up a server - see the warning in x25bind() */
- bind_flags |= TOKEN_REQUEST;
-
- /* bind kermit to the local X25 address */
- token = x25bind(ttyfd,
- local_nua,
- udata,
- (int)strlen( udata ),
- 1,
- x25port,
- bind_flags
- );
- if (token < 0) {
- debug(F100,"netopen: couldn't bind to local X25 address","",0);
- netclos();
- return(-1);
- }
- /* Currently not connected to a remote host */
-
- remote_nua[0] = '\0';
-
- /* store the fd so that incoming calls can have their own fd
- * This is almost support for a true server (ie: a'la ftpd)
- * but we're not quite there yet.
- * used in netclos()
- */
- x25serverfd = ttyfd;
- /*
- * wait for an incoming call
- * this should happen in the "server" command and not in
- * the "set host *" command.
- */
- if ((ttyfd = x25getcall(ttyfd)) < 0) {
- netclos();
- return(-1);
- }
- } else { /* Client */
- /* Bind kermit to the local X25 address */
- token = x25bind(
- ttyfd,
- local_nua,
- (char *)NULL,
- 0,
- 0,
- x25port,
- bind_flags
- );
- if (token < 0) {
- debug(F100,"netopen: couldn't bind to local X25 address","",0);
- netclos();
- return(-1);
- }
-/* riehm: this should be done via the CONNECT command, not HOST! */
- {
- x25serverfd = 0;
- /* call the remote host */
- /* name == address of remote host as char* */
- if (x25call(ttyfd, name, udata) < 0 ) {
- debug(F100,
- "netopen: couldn't connect to remote X25 address",
- "", 0);
- netclos();
- return(-1);
- }
- strcpy(remote_nua, name);
- }
- }
- ttnet = nett; /* AIX X.25 network */
- if (lcl) if (*lcl < 0) *lcl = 1; /* Local mode */
- return(0);
-
- } else /* Note that IBMX25 support can coexist with TCP/IP support. */
-#endif /* IBMX25 */
-
-/* Add support for other networks here. */
-
- if (nett != NET_TCPB) return(-1); /* BSD socket support */
-
-#ifdef TCPSOCKET
- netclos(); /* Close any previous connection. */
- ckstrncpy(namecopy, name, NAMECPYL); /* Copy the hostname. */
- debug(F110,"netopen namecopy",namecopy,0);
-
-#ifndef NOLISTEN
- if (name[0] == '*')
- return(tcpsrv_open(name, lcl, nett, 0));
-#endif /* NOLISTEN */
-
- p = namecopy; /* Was a service requested? */
- while (*p != '\0' && *p != ':') p++; /* Look for colon */
- if (*p == ':') { /* Have a colon */
- debug(F110,"netopen name has colon",namecopy,0);
- *p++ = '\0'; /* Get service name or number */
-#ifdef CK_URL
- /*
- Here we have to check for various popular syntaxes:
- host:port (our original syntax)
- URL such as telnet:host or telnet://host/
- Or even telnet://user:password@host:port/path/
- Or a malformed URL such as generated by Netscape 4.0 like:
- telnet:telnet or telnet::host.
- */
-
- /*
- * REPLACE THIS CODE WITH urlparse() but not on the day of the
- * C-Kermit 8.0 RELEASE.
- */
-
- if (*p == ':') /* a second colon */
- *p++ = '\0'; /* get rid of that one too */
- while (*p == '/') *p++ = '\0'; /* and slashes */
- x = strlen(p); /* Length of remainder */
- if (p[x-1] == '/') /* If there is a trailing slash */
- p[x-1] = '\0'; /* remove it. */
- debug(F110,"netopen namecopy after stripping",namecopy,0);
- debug(F110,"netopen p after stripping",p,0);
- service = getservbyname(namecopy,"tcp");
- if (service ||
-#ifdef RLOGCODE
- !ckstrcmp("rlogin",namecopy,NAMECPYL,0) ||
-#endif /* RLOGCODE */
-#ifdef CK_SSL
- !ckstrcmp("telnets",namecopy,NAMECPYL,0) ||
-#endif /* CK_SSL */
- !ckstrcmp("iksd",namecopy,NAMECPYL,0)
- ) {
- char temphost[256], tempservice[80], temppath[256];
- char * q = p, *r = p, *w = p;
- int uidfound=0;
- extern char pwbuf[];
- extern int pwflg, pwcrypt;
-
- if (ttnproto == NP_DEFAULT)
- setnproto(namecopy);
-
- /* Check for userid and possibly password */
- while (*p != '\0' && *p != '@')
- p++; /* look for @ */
- if (*p == '@') {
- /* found username and perhaps password */
- debug(F110,"netopen namecopy found @","",0);
- *p = '\0';
- p++;
- while (*w != '\0' && *w != ':')
- w++;
- if (*w == ':')
- *w++ = '\0';
- /* r now points to username, save it and the password */
- debug(F110,"netopen namecopy username",r,0);
- debug(F110,"netopen namecopy password",w,0);
- uidfound=1;
- if ( strcmp(uidbuf,r) || *w )
- ckstrncpy(pwbuf,w,PWBUFL+1);
- ckstrncpy(uidbuf,r,UIDBUFLEN);
- pwflg = 1;
- pwcrypt = 0;
- q = p; /* Host after user and pwd */
- } else {
- p = q; /* No username or password */
- }
- /* Now we must look for the optional port. */
- debug(F110,"netopen x p",p,0);
- debug(F110,"netopen x q",q,0);
-
- /* Look for the port/service or a file/directory path */
- while (*p != '\0' && *p != ':' && *p != '/')
- p++;
- if (*p == ':') {
- debug(F110,"netopen found port",q,0);
- *p++ = '\0'; /* Found a port name or number */
- r = p;
-
- /* Look for the end of port/service or a file/directory path */
- while (*p != '\0' && *p != '/')
- p++;
- if (*p == '/')
- *p++ = '\0';
-
- debug(F110,"netopen port",r,0);
- ckstrncpy(tempservice,r,80);
- ckstrncpy(temphost,q,256);
- ckstrncpy(temppath,p,256);
- ckstrncpy(namecopy,temphost,NAMECPYL);
- debug(F110,"netopen tempservice",tempservice,0);
- debug(F110,"netopen temphost",temphost,0);
- debug(F110,"netopen temppath",temppath,0);
-
- /* move port/service to a buffer that won't go away */
- x = strlen(namecopy);
- p = namecopy + x + 1;
- ckstrncpy(p, tempservice, NAMECPYL - x);
- } else {
- /* Handle a path if we found one */
- if (*p == '/')
- *p++ = '\0';
- ckstrncpy(temppath,p,256);
-
- /* We didn't find another port, but if q is a service */
- /* then assume that namecopy is actually a host. */
- if (getservbyname(q,"tcp")) {
- p = q;
- } else {
-#ifdef RLOGCODE
- /* rlogin is not a valid service */
- if (!ckstrcmp("rlogin",namecopy,6,0)) {
- ckstrncpy(namecopy,"login",NAMECPYL);
- }
-#endif /* RLOGCODE */
- /* iksd is not a valid service */
- if (!ckstrcmp("iksd",namecopy,6,0)) {
- ckstrncpy(namecopy,"kermit",NAMECPYL);
- }
- /* Reconstruct namecopy */
- ckstrncpy(tempservice,namecopy,80);
- ckstrncpy(temphost,q,256);
- ckstrncpy(namecopy,temphost,NAMECPYL);
- debug(F110,"netopen tempservice",tempservice,0);
- debug(F110,"netopen temphost",temphost,0);
- debug(F110,"netopen temppath",temppath,0);
-
- /* move port/service to a buffer that won't go away */
- x = strlen(namecopy);
- p = namecopy + x + 1;
- ckstrncpy(p, tempservice, NAMECPYL - x - 1);
- }
- }
- debug(F110,"netopen URL result: host",namecopy,0);
- debug(F110,"netopen URL result: service",p,0);
- debug(F110,"netopen URL result: path",temppath,0);
-
-#ifdef IKS_GET
- /* If we have set a path specified, we need to try to GET it */
- /* But we have another problem, we have to login first. How */
- /* do we specify that a login must be done before the GET? */
- /* The user's name if specified is in 'userid' and the */
- /* password if any is in 'pwbuf'. */
- if ( temppath[0] ) {
- extern int action;
- extern char * cmarg;
-
- if ( !uidfound ) {
- /* If no userid was specified as part of the URL but
- * a path was specified, then we
- * set the user name to anonymous and the password
- * to the current userid.
- */
- ckstrncpy(pwbuf,uidbuf,PWBUFL);
- ckstrncat(pwbuf,"@",PWBUFL);
- pwflg = 1;
- pwcrypt = 0;
- ckstrncpy(uidbuf,"anonymous",UIDBUFLEN);
- }
-
- /*
- * If a file path was specified we perform the GET
- * operation and then terminate the connection.
- *
- * If a directory was given instead of a file, then
- * we should REMOTE CD to the directory and list its
- * contents. But how do we tell the difference?
- */
- makestr(&cmarg,temppath);
- action = 'r';
- }
-#endif /* IKS_GET */
- }
-#endif /* CK_URL */
- } else { /* Otherwise use telnet */
- p = "telnet";
- }
-/*
- By the time we get here, namecopy[] should hold the null-terminated
- hostname or address, and p should point to the service name or number.
-*/
- debug(F110,"netopen host",namecopy,0);
- debug(F110,"netopen service requested",p,0);
-
- /* Use the service port to set the default protocol type if necessary */
- if (ttnproto == NP_DEFAULT)
- setnproto(p);
-
- ckstrncpy(namecopy2,namecopy,NAMECPYL);
- service = ckgetservice(namecopy,p,namecopy,NAMECPYL);
- if (!service) {
- fprintf(stderr, "Can't find port for service %s\n", p);
-#ifdef TGVORWIN
- debug(F101,"netopen can't get service","",socket_errno);
-#else
- debug(F101,"netopen can't get service","",errno);
-#endif /* TGVORWIN */
- errno = 0; /* (rather than mislead) */
- return(-1);
- } else {
- if (!ckstrcmp(namecopy,namecopy2,-1,0))
- namecopy2[0] = '\0';
- ckstrncpy(svcbuf,ckuitoa(ntohs(service->s_port)),sizeof(svcbuf));
- debug(F110,"netopen service ok",svcbuf,0);
- }
-
-#ifdef RLOGCODE
- if (service && !strcmp("login",p) && service->s_port != htons(513)) {
- fprintf(stderr,
- " Warning: login service on port %d instead of port 513\n",
- ntohs(service->s_port)
- );
- fprintf(stderr, " Edit SERVICES file if RLOGIN fails to connect.\n");
- debug(F101,"tcpsrv_open login on port","",ntohs(service->s_port));
- }
-#endif /* RLOGCODE */
-
-#ifndef NOHTTP
- /* For HTTP connections we must preserve the original hostname and */
- /* service requested so we can include them in the Host header. */
- ckmakmsg(http_host_port,sizeof(http_host_port),namecopy,":",
- ckitoa(ntohs(service->s_port)),NULL);
-
- /* 'namecopy' contains the name of the host to which we want to connect */
- /* 'svcbuf' contains the service name */
- /* 'service->s_port' contains the port number in network byte order */
-
- /* If we are using an http proxy, we need to create a buffer containing */
- /* hostname:port-number */
- /* to pass to the http_connect() function. Then we need to replace */
- /* 'namecopy' with the name of the proxy server and the service->s_port */
- /* with the port number of the proxy (default port 80). */
-
- if ( tcp_http_proxy ) {
- ckmakmsg(proxycopy,sizeof(proxycopy),namecopy,":",
- ckuitoa(ntohs(service->s_port)),NULL);
- ckstrncpy(namecopy,tcp_http_proxy,NAMECPYL);
-
- p = namecopy; /* Was a service requested? */
- while (*p != '\0' && *p != ':') p++; /* Look for colon */
- if (*p == ':') { /* Have a colon */
- debug(F110,"netopen name has colon",namecopy,0);
- *p++ = '\0'; /* Get service name or number */
- } else {
- strcpy(++p,"http");
- }
-
- service = ckgetservice(namecopy,p,namecopy,NAMECPYL);
- if (!service) {
- fprintf(stderr, "Can't find port for service %s\n", p);
-#ifdef TGVORWIN
- debug(F101,"netopen can't get service for proxy","",socket_errno);
-#else
- debug(F101,"netopen can't get service for proxy","",errno);
-#endif /* TGVORWIN */
- errno = 0; /* (rather than mislead) */
- return(-1);
- }
- ckstrncpy(p,ckuitoa(ntohs(service->s_port)),NAMECPYL-(p-namecopy));
-
- }
-#endif /* NOHTTP */
-
- /* Set up socket structure and get host address */
-
- bzero((char *)&r_addr, sizeof(r_addr));
- debug(F100,"netopen bzero ok","",0);
-/*
- NOTE: Originally the inet_addr() check was #ifdef NT, but is enabled for
- all as of 20 Sep 97, to allow people to "set host" to a specific numeric IP
- address without going through the multihomed host sequence and winding up
- at a different place than the one requested.
-*/
-#ifdef INADDR_NONE
- debug(F101,"netopen INADDR_NONE defined","",INADDR_NONE);
-#else /* INADDR_NONE */
- debug(F100,"netopen INADDR_NONE not defined","",0);
-#endif /* INADDR_NONE */
-#ifdef INADDRX
- debug(F100,"netopen INADDRX defined","",0);
-#else /* INADDRX */
- debug(F100,"netopen INADDRX not defined","",0);
-#endif /* INADDRX */
-
-#ifndef NOMHHOST
-#ifdef INADDRX
- iax = inet_addr(namecopy);
- debug(F111,"netopen inet_addr",namecopy,iax.s_addr);
-#else /* INADDRX */
-#ifdef INADDR_NONE
- iax.s_addr = inet_addr(namecopy);
- debug(F111,"netopen inet_addr",namecopy,iax.s_addr);
-#else /* INADDR_NONE */
-#ifdef SOLARIS
- /* In Solaris inet_addr() is of type in_addr_t which is uint32_t */
- /* (unsigned) yet it returns -1 (signed) on failure. */
- /* It makes a difference in 64-bit builds. */
- rc_inet_addr = inet_addr(namecopy); /* Assign return code to an int */
- iax = (unsigned) rc_inet_addr; /* and from there to whatever.. */
-#else
-#ifndef datageneral
- iax = (unsigned int) inet_addr(namecopy);
-#else
- iax = -1L;
-#endif /* datageneral */
-#endif /* SOLARIS */
- debug(F111,"netopen rc_inet_addr",namecopy,rc_inet_addr);
- debug(F111,"netopen inet_addr",namecopy,iax);
-#endif /* INADDR_NONE */
-#endif /* INADDRX */
-
- dns = 0;
- if (
-/* This might give warnings on 64-bit platforms but they should be harmless */
-/* because INADDR_NONE should be all 1's anyway, thus the OR part is */
-/* probably superfluous -- not sure why it's even there, maybe it should be */
-/* removed. */
-#ifdef SOLARIS
- rc_inet_addr == -1
-#else
-#ifdef INADDR_NONE
- iax.s_addr == INADDR_NONE /* || iax.s_addr == (unsigned long) -1L */
-#else /* INADDR_NONE */
- iax < 0
-#endif /* INADDR_NONE */
-#endif /* SOLARIS */
- ) {
- if (!quiet) {
- printf(" DNS Lookup... ");
- fflush(stdout);
- }
- if ((host = gethostbyname(namecopy)) != NULL) {
- debug(F110,"netopen gethostbyname != NULL",namecopy,0);
- host = ck_copyhostent(host);
- dns = 1; /* Remember we performed dns lookup */
- r_addr.sin_family = host->h_addrtype;
- if (tcp_rdns && host->h_name && host->h_name[0]
-#ifndef NOHTTP
- && (tcp_http_proxy == NULL)
-#endif /* NOHTTP */
- ) {
-#ifdef COMMENT
- ckstrncpy(xxname,host->h_name,XXNAMELEN);
- debug(F110,"netopen xxname[1]",xxname,0);
- if ((XXNAMELEN - (int)strlen(name)) > ((int)strlen(svcbuf)+1)){
- ckstrncat(xxname,":",XXNAMELEN - (int)strlen(xxname));
- ckstrncat(xxname,svcbuf,XXNAMELEN - (int)strlen(xxname));
- debug(F110,"netopen xxname[2]",xxname,0);
- }
- name = (char *)xxname;
-#else
- ckstrncpy(name,host->h_name,80); /* Bad Bad Bad */
- if ( (80-strlen(name)) > (strlen(svcbuf)+1) ) {
- ckstrncat(name,":",80-strlen(name));
- ckstrncat(name,svcbuf,80-strlen(name));
- }
-#endif /* COMMENT */
- }
- debug(F110,"netopen name after lookup",name,0);
-
-#ifdef HADDRLIST
-#ifdef h_addr
- /* This is for trying multiple IP addresses - see <netdb.h> */
- if (!(host->h_addr_list))
- return(-1);
- bcopy(host->h_addr_list[0],
- (caddr_t)&r_addr.sin_addr,
- host->h_length
- );
-#else
- bcopy(host->h_addr, (caddr_t)&r_addr.sin_addr, host->h_length);
-#endif /* h_addr */
-#else /* HADDRLIST */
-#ifdef HPUX6
- r_addr.sin_addr.s_addr = (u_long)host->h_addr;
-#else /* HPUX6 */
- bcopy(host->h_addr, (caddr_t)&r_addr.sin_addr, host->h_length);
-#endif /* HPUX6 */
-#endif /* HADDRLIST */
-
-#ifndef HPUX6
- debug(F111,"BCOPY","host->h_length",host->h_length);
-#endif /* HPUX6 */
- }
- }
-#endif /* NOMHHOST */
-
- debug(F101,"netopen dns","",dns);
-
- if (!dns) {
-#ifdef INADDRX
-/* inet_addr() is of type struct in_addr */
- struct in_addr ina;
- unsigned long uu;
- debug(F100,"netopen gethostbyname == NULL: INADDRX","",0);
- ina = inet_addr(namecopy);
- uu = *(unsigned int *)&ina;
-#else /* Not INADDRX */
-/* inet_addr() is unsigned long */
- unsigned long uu;
- debug(F100,"netopen gethostbyname == NULL: Not INADDRX","",0);
- uu = inet_addr(namecopy);
-#endif /* INADDRX */
- debug(F101,"netopen uu","",uu);
- if (
-#ifdef INADDR_NONE
- !(uu == INADDR_NONE || uu == (unsigned int) -1L)
-#else /* INADDR_NONE */
- uu != ((unsigned long)-1)
-#endif /* INADDR_NONE */
- ) {
- r_addr.sin_addr.s_addr = uu;
- r_addr.sin_family = AF_INET;
- } else {
-#ifdef VMS
- fprintf(stdout, "\r\n"); /* complete any previous message */
-#endif /* VMS */
- fprintf(stderr, "Can't get address for %s\n", namecopy);
-#ifdef TGVORWIN
- debug(F101,"netopen can't get address","",socket_errno);
-#else
- debug(F101,"netopen can't get address","",errno);
-#endif /* TGVORWIN */
- errno = 0; /* Rather than mislead */
- return(-1);
- }
- }
-
- /* Get a file descriptor for the connection. */
-
- r_addr.sin_port = service->s_port;
- ckstrncpy(ipaddr,(char *)inet_ntoa(r_addr.sin_addr),20);
- debug(F110,"netopen trying",ipaddr,0);
- if (!quiet && *ipaddr) {
- printf(" Trying %s... ", ipaddr);
- fflush(stdout);
- }
-
- /* Loop to try additional IP addresses, if any. */
-
- do {
-#ifdef EXCELAN
- send_socket.sin_family = AF_INET;
- send_socket.sin_addr.s_addr = 0;
- send_socket.sin_port = 0;
- if ((ttyfd = socket(SOCK_STREAM, (struct sockproto *)0,
- &send_socket, SO_REUSEADDR)) < 0)
-#else /* EXCELAN */
-#ifdef NT
-#ifdef COMMENT_X
- /*
- Must make sure that all sockets are opened in
- Non-overlapped mode since we use the standard
- C RTL functions to read and write data.
- But it doesn't seem to work as planned.
- */
- {
- int optionValue = SO_SYNCHRONOUS_NONALERT;
- if (setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
- (char *) &optionValue, sizeof(optionValue))
- != NO_ERROR)
- return(-1);
- }
-#endif /* COMMENT */
-#endif /* NT */
-
- if ((ttyfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-#endif /* EXCELAN */
- {
-#ifdef EXCELAN
- experror("TCP socket error");
-#else
-#ifdef VMS
- fprintf(stdout, "\r\n"); /* complete any previous stdout */
-#endif /* VMS */
-#ifdef TGVORWIN
-#ifdef OLD_TWG
- errno = socket_errno;
-#endif /* OLD_TWG */
- socket_perror("TCP socket error");
- debug(F101,"netopen socket error","",socket_errno);
-#else
- perror("TCP socket error");
- debug(F101,"netopen socket error","",errno);
-#endif /* TGVORWIN */
-#endif /* EXCELAN */
- return (-1);
- }
- errno = 0;
-
-#ifdef RLOGCODE
- /* Not part of the RLOGIN RFC, but the BSD implementation */
- /* requires that the client port be a priviliged port (<1024) */
- /* on a Unix system this would require SuperUser permissions */
- /* thereby saying that the root of the Unix system has given */
- /* permission for this connection to be created */
- if (service->s_port == htons((unsigned short)RLOGIN_PORT)) {
- static unsigned short lport = 1024; /* max reserved port */
-#ifdef OS2
- int s_errno;
-#endif /* OS2 */
-
- lport--; /* Make sure we do not reuse a port */
- if (lport == 512)
- lport = 1023;
-
- sin.sin_family = AF_INET;
- if (tcp_address) {
-#ifdef INADDRX
- inaddrx = inet_addr(tcp_address);
- sin.sin_addr.s_addr = *(unsigned long *)&inaddrx;
-#else
- sin.sin_addr.s_addr = inet_addr(tcp_address);
-#endif /* INADDRX */
- } else
- sin.sin_addr.s_addr = INADDR_ANY;
- while (1) {
- sin.sin_port = htons(lport);
- if (bind(ttyfd, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
- break;
-#ifdef OS2
- s_errno = socket_errno;
- if (s_errno && /* OS2 bind fails with 0, if already in use */
-#ifdef NT
- s_errno != WSAEADDRINUSE
-#else
- s_errno != SOCEADDRINUSE &&
- s_errno != (SOCEADDRINUSE - SOCBASEERR)
-#endif /* NT */
- )
-#else /* OS2 */
-#ifdef TGVORWIN
- if (socket_errno != EADDRINUSE)
-#else
- if (errno != EADDRINUSE)
-#endif /* TGVORWIN */
-#endif /* OS2 */
- {
-#ifdef COMMENT
- printf("\nBind failed with errno %d for port %d.\n",
-#ifdef OS2
- s_errno
-#else
-#ifdef TGVORWIN
- socket_errno
-#else
- errno
-#endif /* TGVORWIN */
-#endif /* OS2 */
- , lport
- );
-#ifdef OS2
- debug(F101,"rlogin bind failed","",s_errno);
-#else
-#ifdef TGVORWIN
- debug(F101,"rlogin bind failed","",socket_errno);
-#ifdef OLD_TWG
- errno = socket_errno;
-#endif /* OLD_TWG */
- socket_perror("rlogin bind");
-#else
- debug(F101,"rlogin bind failed","",errno);
- perror("rlogin bind");
-#endif /* TGVORWIN */
-#endif /* OS2 */
-#else /* COMMENT */
-#ifdef OS2
- debug(F101,"rlogin bind s_errno","",s_errno);
- perror("rlogin bind");
-#else
-#ifdef VMS
- printf("\r\n"); /* complete any previous message */
-#endif /* VMS */
-#ifdef TGVORWIN
- debug(F101,"rlogin bind socket_errno","",socket_errno);
-#ifdef OLD_TWG
- errno = socket_errno;
-#endif /* OLD_TWG */
- socket_perror("rlogin bind");
-#else
- debug(F101,"rlogin bind errno","",errno);
- perror("rlogin bind");
-#endif /* TGVORWIN */
-#endif /* OS2 */
- debug(F101,"rlogin local port","",lport);
-#endif /* COMMENT */
- netclos();
- return -1;
- }
- lport--;
- if (lport == 512 /* lowest reserved port to use */ ) {
- printf("\nNo reserved ports available.\n");
- netclos();
- return -1;
- }
- }
- debug(F101,"rlogin lport","",lport);
- ttnproto = NP_RLOGIN;
- } else
-#endif /* RLOGCODE */
-
- /* If a specific TCP address on the local host is desired we */
- /* must bind it to the socket. */
-#ifndef datageneral
- if (tcp_address) {
- int s_errno;
-
- debug(F110,"netopen binding socket to",tcp_address,0);
- bzero((char *)&sin,sizeof(sin));
- sin.sin_family = AF_INET;
-#ifdef INADDRX
- inaddrx = inet_addr(tcp_address);
- sin.sin_addr.s_addr = *(unsigned long *)&inaddrx;
-#else
- sin.sin_addr.s_addr = inet_addr(tcp_address);
-#endif /* INADDRX */
- sin.sin_port = 0;
- if (bind(ttyfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- s_errno = socket_errno; /* Save error code */
-#ifdef TCPIPLIB
- socket_close(ttyfd);
-#else /* TCPIPLIB */
- close(ttyfd);
-#endif /* TCPIPLIB */
- ttyfd = -1;
- wasclosed = 1;
- errno = s_errno; /* and report this error */
- debug(F101,"netopen bind errno","",errno);
- return(-1);
- }
- }
-#endif /* datageneral */
-
-/* Now connect to the socket on the other end. */
-
-#ifdef EXCELAN
- if (connect(ttyfd, &r_addr) < 0)
-#else
-#ifdef NT
- WSASafeToCancel = 1;
-#endif /* NT */
- if (connect(ttyfd, (struct sockaddr *)&r_addr, sizeof(r_addr)) < 0)
-#endif /* EXCELAN */
- {
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
-#ifdef OS2
- i = socket_errno;
-#else /* OS2 */
-#ifdef TGVORWIN
- i = socket_errno;
-#else
- i = errno; /* Save error code */
-#endif /* TGVORWIN */
-#endif /* OS2 */
-#ifdef RLOGCODE
- if (
-#ifdef OS2
- i && /* OS2 bind fails with 0, if already in use */
-#ifdef NT
- i == WSAEADDRINUSE
-#else
- (i == SOCEADDRINUSE ||
- i == (SOCEADDRINUSE - SOCBASEERR))
-#endif /* NT */
-#else /* OS2 */
-#ifdef TGVORWIN
- socket_errno == EADDRINUSE
-#else
- errno == EADDRINUSE
-#endif /* TGVORWIN */
-#endif /* OS2 */
- && ttnproto == NP_RLOGIN) {
-#ifdef TCPIPLIB
- socket_close(ttyfd); /* Close it. */
-#else
- close(ttyfd);
-#endif /* TCPIPLIB */
- continue; /* Try a different lport */
- }
-#endif /* RLOGCODE */
-#ifdef HADDRLIST
-#ifdef h_addr
- if (host && host->h_addr_list && host->h_addr_list[1]) {
- perror("");
- host->h_addr_list++;
- bcopy(host->h_addr_list[0],
- (caddr_t)&r_addr.sin_addr,
- host->h_length);
-
- ckstrncpy(ipaddr,(char *)inet_ntoa(r_addr.sin_addr),20);
- debug(F110,"netopen h_addr_list",ipaddr,0);
- if (!quiet && *ipaddr) {
- printf(" Trying %s... ", ipaddr);
- fflush(stdout);
- }
-#ifdef TCPIPLIB
- socket_close(ttyfd); /* Close it. */
-#else
- close(ttyfd);
-#endif /* TCPIPLIB */
- continue;
- }
-#endif /* h_addr */
-#endif /* HADDRLIST */
- netclos();
- ttyfd = -1;
- wasclosed = 1;
- ttnproto = NP_NONE;
- errno = i; /* And report this error */
-#ifdef EXCELAN
- if (errno) experror("netopen connect");
-#else
-#ifdef TGVORWIN
- debug(F101,"netopen connect error","",socket_errno);
- /* if (errno) socket_perror("netopen connect"); */
-#ifdef OLD_TWG
- errno = socket_errno;
-#endif /* OLD_TWG */
- if (!quiet)
- socket_perror("netopen connect");
-#else /* TGVORWIN */
- debug(F101,"netopen connect errno","",errno);
-#ifdef VMS
- if (!quiet)
- perror("\r\nFailed");
-#else
- if (!quiet)
- perror("Failed");
-#endif /* VMS */
-#ifdef DEC_TCPIP
- if (!quiet)
- perror("netopen connect");
-#endif /* DEC_TCPIP */
-#ifdef CMU_TCPIP
- if (!quiet)
- perror("netopen connect");
-#endif /* CMU_TCPIP */
-#endif /* TGVORWIN */
-#endif /* EXCELAN */
- return(-1);
- }
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
- isconnect = 1;
- } while (!isconnect);
-
-#ifdef NON_BLOCK_IO
- on = 1;
- x = socket_ioctl(ttyfd,FIONBIO,&on);
- debug(F101,"netopen FIONBIO","",x);
-#endif /* NON_BLOCK_IO */
-
-#ifdef NT_TCP_OVERLAPPED
- OverlappedWriteInit();
- OverlappedReadInit();
-#endif /* NT_TCP_OVERLAPPED */
-
- ttnet = nett; /* TCP/IP (sockets) network */
-
-#ifndef NOHTTP
- /* We have succeeded in connecting to the HTTP PROXY. So now we */
- /* need to attempt to connect through the proxy to the actual host */
- /* If that is successful, we have to pretend that we made a direct */
- /* connection to the actual host. */
-
- if ( tcp_http_proxy ) {
-#ifdef OS2
- char * agent = "Kermit 95"; /* Default user agent */
-#else
- char * agent = "C-Kermit";
-#endif /* OS2 */
-
- if (http_connect(ttyfd,
- tcp_http_proxy_agent ? tcp_http_proxy_agent : agent,
- NULL,
- tcp_http_proxy_user,
- tcp_http_proxy_pwd,
- 0,
- proxycopy
- ) < 0) {
- netclos();
- return(-1);
- }
-
- ckstrncpy(namecopy,proxycopy,NAMECPYL);
- p = namecopy; /* Was a service requested? */
- while (*p != '\0' && *p != ':') p++; /* Look for colon */
- *p = '\0';
- }
-#endif /* NOHTTP */
-
- /* Jeff - Does this next block of code that set's the protocol */
- /* need to be here anymore? 5/10/2000 */
-
- /* There are certain magic port numbers that when used require */
- /* the use of specific protocols. Check this now before we */
- /* set the SO_OOBINLINE state or we might get it wrong. */
- x = ntohs((unsigned short)service->s_port);
- svcnum = x;
- /* See if the service is TELNET. */
- if (x == TELNET_PORT) {
- /* Yes, so if raw port not requested */
-#ifdef COMMENT
- /* Jeff 2005/12/30 */
- if (ttnproto != NP_TCPRAW && ttnproto != NP_SSL_RAW &&
- ttnproto != NP_TLS_RAW && ttnproto != NP_NONE)
-#else
- /* fdc 2005/12/04 */
- if (ttnproto != NP_TCPRAW && ttnproto != NP_NONE)
-#endif /* COMMENT */
- ttnproto = NP_TELNET; /* Select TELNET protocol. */
- }
-#ifdef RLOGCODE
- else if (x == RLOGIN_PORT) {
- ttnproto = NP_RLOGIN;
- }
-#ifdef CK_KERBEROS
- /* There is no good way to do this. If the user didn't tell */
- /* which one to use up front. We may guess wrong if the user */
- /* has both Kerberos versions installed and valid TGTs for each */
- else if (x == KLOGIN_PORT &&
- ttnproto != NP_K4LOGIN &&
- ttnproto != NP_K5LOGIN) {
- if (ck_krb5_is_installed() &&
- ck_krb5_is_tgt_valid())
- ttnproto = NP_K5LOGIN;
- else if (ck_krb4_is_installed() && ck_krb4_is_tgt_valid())
- ttnproto = NP_K4LOGIN;
- else
- ttnproto = NP_K4LOGIN;
- } else if (x == EKLOGIN_PORT &&
- ttnproto != NP_EK4LOGIN &&
- ttnproto != NP_EK5LOGIN) {
- if (ck_krb5_is_installed() && ck_krb5_is_tgt_valid())
- ttnproto = NP_EK5LOGIN;
- else if (ck_krb4_is_installed() && ck_krb4_is_tgt_valid())
- ttnproto = NP_EK4LOGIN;
- else
- ttnproto = NP_EK4LOGIN;
- }
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
-#ifdef IKS_OPTION
- else if (x == KERMIT_PORT) { /* IKS uses Telnet protocol */
- if (ttnproto == NP_NONE)
- ttnproto = NP_KERMIT;
- }
-#endif /* IKS_OPTION */
-
-#ifdef SO_OOBINLINE
-/*
- The symbol SO_OOBINLINE is not known to Ultrix 2.0.
- It means "leave out of band data inline". The normal value is 0x0100,
- but don't try this on systems where the symbol is undefined.
-*/
-/*
- Note from Jeff Altman: 12/13/95
- In implementing rlogin protocol I have come to the conclusion that it is
- a really bad idea to read out-of-band data inline.
- At least Windows and OS/2 does not handle this well.
- And if you need to know that data is out-of-band, then it becomes
- absolutely pointless.
-
- Therefore, at least on OS2 and Windows (NT) I have changed the value of
- on to 0, so that out-of-band data stays out-of-band.
-
- 12/18/95
- Actually, OOB data should be read inline when possible. Especially with
- protocols that don't care about the Urgent flag. This is true with Telnet.
- With Rlogin, you need to be able to catch OOB data. However, the best
- way to do this is to set a signal handler on SIGURG. This isn't possible
- on OS/2 and Windows. But it is in UNIX. We will also need OOB data for
- FTP so better create a general mechanism.
-
- The reason for making OOB data be inline is that the standard ttinc/ttoc
- calls can be used for reading that data on UNIX systems. If we didn't
- have the OOBINLINE option set then we would have to use recv(,MSG_OOB)
- to read it.
-*/
-#ifdef RLOGCODE
-#ifdef TCPIPLIB
- if (ttnproto == NP_RLOGIN
-#ifdef CK_KERBEROS
- || ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN
- || ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_KERBEROS */
- )
- on = 0;
-#else /* TCPIPLIB */
- if (ttnproto == NP_RLOGIN
-#ifdef CK_KERBEROS
- || ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN
- || ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_KERBEROS */
- ) {
- debug(F100,"Installing rlogoobh on SIGURG","",0);
- signal(SIGURG, rlogoobh);
- on = 0;
- } else {
- debug(F100,"Ignoring SIGURG","",0);
- signal(SIGURG, SIG_DFL);
- }
-#endif /* TCPIPLIB */
-#endif /* RLOGCODE */
-
-#ifdef datageneral
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef BSD43
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef OSF1
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef POSIX
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef MOTSV88R4
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef SOLARIS
-/*
- Maybe this applies to all SVR4 versions, but the other (else) way has been
- compiling and working fine on all the others, so best not to change it.
-*/
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef OSK
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef OS2
- {
- int rc;
- rc = setsockopt(ttyfd,
- SOL_SOCKET,
- SO_OOBINLINE,
- (char *) &on,
- sizeof on
- );
- debug(F111,"setsockopt SO_OOBINLINE",on ? "on" : "off" ,rc);
- }
-#else
-#ifdef VMS /* or, at least, VMS with gcc */
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef CLIX
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof on);
-#endif /* CLIX */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* OSK */
-#endif /* SOLARIS */
-#endif /* MOTSV88R4 */
-#endif /* POSIX */
-#endif /* BSD43 */
-#endif /* OSF1 */
-#endif /* datageneral */
-#endif /* SO_OOBINLINE */
-
-#ifndef NOTCPOPTS
-#ifndef datageneral
-#ifdef SOL_SOCKET
-#ifdef TCP_NODELAY
- no_delay(ttyfd,tcp_nodelay);
-#endif /* TCP_NODELAY */
-#ifdef SO_KEEPALIVE
- keepalive(ttyfd,tcp_keepalive);
-#endif /* SO_KEEPALIVE */
-#ifdef SO_LINGER
- ck_linger(ttyfd,tcp_linger, tcp_linger_tmo);
-#endif /* SO_LINGER */
-#ifdef SO_SNDBUF
- sendbuf(ttyfd,tcp_sendbuf);
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
- recvbuf(ttyfd,tcp_recvbuf);
-#endif /* SO_RCVBUF */
-#endif /* SOL_SOCKET */
-#endif /* datageneral */
-#endif /* NOTCPOPTS */
-
-#ifndef datageneral
- /* Find out our own IP address. */
- /* We need the l_addr structure for [E]KLOGIN. */
- l_slen = sizeof(l_addr);
- bzero((char *)&l_addr, l_slen);
-#ifndef EXCELAN
- if (!getsockname(ttyfd, (struct sockaddr *)&l_addr, &l_slen)) {
- char * s = (char *)inet_ntoa(l_addr.sin_addr);
- ckstrncpy(myipaddr, s, 20);
- debug(F110,"getsockname",myipaddr,0);
- }
-#endif /* EXCELAN */
-#endif /* datageneral */
-
-/*
- This is really only needed for Kerberos IV but is useful information in any
- case. If we connect to a name that is really a pool, we need to get the
- name of the machine we are actually connecting to for K4 to authenticate
- properly. This way we also update the names properly.
-
- However, it is a security hole when used with insecure DNS.
-
- Note: This does not work on Windows 95 or Windows NT 3.5x. This is because
- of the Microsoft implementation of gethostbyaddr() in both Winsock 1.1
- and Winsock 2.0 on those platforms. Their algorithm is:
-
- 1. Check the HOSTENT cache.
- 2. Check the HOSTS file at %SystemRoot%\System32\DRIVERS\ETC.
- 3. Do a DNS query if the DNS server is configured for name resolution.
- 4. Do an additional NetBIOS remote adapter status to an IP address for its
- NetBIOS name table. This step is specific only to the Windows NT version
- 3.51 implementation.
-
- The problem is the use of the HOSTENT cache. It means that gethostbyaddr()
- can not be used to resolve the real name of machine if it was originally
- accessed by an alias used to represent a cluster.
-*/
- if ((tcp_rdns && dns || tcp_rdns == SET_ON
-#ifdef CK_KERBEROS
- || tcp_rdns == SET_AUTO &&
- (ck_krb5_is_installed() || ck_krb4_is_installed())
-#endif /* CK_KERBEROS */
- )
-#ifndef NOHTTP
- && (tcp_http_proxy == NULL)
-#endif /* NOHTTP */
-#ifdef CK_SSL
- && !(ssl_only_flag || tls_only_flag)
-#endif /* CK_SSL */
- ) {
-#ifdef NT
- if (isWin95())
- sleep(1);
-#endif /* NT */
- if (!quiet) {
- printf(" Reverse DNS Lookup... ");
- fflush(stdout);
- }
- if (host = gethostbyaddr((char *)&r_addr.sin_addr,4,PF_INET)) {
- char * s;
- host = ck_copyhostent(host);
- debug(F100,"netopen gethostbyname != NULL","",0);
- if (!quiet) {
- printf("(OK)\n");
- fflush(stdout);
- }
- s = host->h_name;
- if (!s) { /* This can happen... */
- debug(F100,"netopen host->h_name is NULL","",0);
- s = "";
- }
- /* Something is wrong with inet_ntoa() on HPUX 10.xx */
- /* The compiler says "Integral value implicitly converted to */
- /* pointer in assignment." The prototype is right there */
- /* in <arpa/inet.h> so what's the problem? */
- /* Ditto in HP-UX 5.x, but not 8.x or 9.x... */
- if (!*s) { /* No name so substitute the address */
- debug(F100,"netopen host->h_name is empty","",0);
- s = inet_ntoa(r_addr.sin_addr); /* Convert address to string */
- if (!s) /* Trust No 1 */
- s = "";
- if (*s) { /* If it worked, use this string */
- ckstrncpy(ipaddr,s,20);
- }
- s = ipaddr; /* Otherwise stick with the IP */
- if (!*s) /* or failing that */
- s = namecopy; /* the name we were called with. */
- }
- if (*s) { /* Copying into our argument? */
- ckstrncpy(name,s,80); /* Bad Bad Bad */
- if ( (80-strlen(name)) > (strlen(svcbuf)+1) ) {
- ckstrncat(name,":",80-strlen(name));
- ckstrncat(name,svcbuf,80-strlen(name));
- }
- }
- if (!quiet && *s
-#ifndef NOICP
- && !doconx
-#endif /* NOICP */
- ) {
- printf(" %s connected on port %s\n",s,p);
-#ifdef BETADEBUG
- /* This is simply for testing the DNS entries */
- if (host->h_aliases) {
- char ** a = host->h_aliases;
- while (*a) {
- printf(" alias => %s\n",*a);
- a++;
- }
- }
-#endif /* BETADEBUG */
- }
- } else {
- if (!quiet) printf("Failed.\n");
- }
- } else if (!quiet) printf("(OK)\n");
- if (!quiet) fflush(stdout);
-
- /* This should already have been done but just in case */
- ckstrncpy(ipaddr,(char *)inet_ntoa(r_addr.sin_addr),20);
-
-#ifdef CK_SECURITY
-
- /* Before Initialization Telnet/Rlogin Negotiations Init Kerberos */
-#ifndef NOHTTP
- if (tcp_http_proxy) {
- for (i=strlen(proxycopy); i >= 0 ; i--)
- if ( proxycopy[i] == ':' )
- proxycopy[i] = '\0';
- }
-#endif /* NOHTTP */
- ck_auth_init(
-#ifndef NOHTTP
- tcp_http_proxy ? proxycopy :
-#endif /* NOHTTP */
- (tcp_rdns && host && host->h_name && host->h_name[0]) ?
- (char *)host->h_name : (namecopy2[0] ? namecopy2 :
- (namecopy[0] ? namecopy : ipaddr)),
- ipaddr,
- uidbuf,
- ttyfd
- );
-#endif /* CK_SECURITY */
-#ifdef CK_SSL
- if (ck_ssleay_is_installed()) {
- if (!ssl_tn_init(SSL_CLIENT)) {
- debug(F100,"netopen ssl_tn_init() failed","",0);
- if (bio_err!=NULL) {
- BIO_printf(bio_err,"ssl_tn_init() failed\n");
- ERR_print_errors(bio_err);
- } else {
- fflush(stderr);
- fprintf(stderr,"ssl_tn_init() failed\n");
- ERR_print_errors_fp(stderr);
- }
- if (tls_only_flag || ssl_only_flag) {
- debug(F100,"netopen ssl/tls required","",0);
- netclos();
- return(-1);
- }
-
- /* we will continue to accept the connection */
- /* without SSL or TLS support unless required. */
- if ( TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
- if ( TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) != TN_NG_MU )
- TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- } else if ( ck_ssl_outgoing(ttyfd) < 0 ) {
- debug(F100,"ck_ssl_outgoing() failed","",0);
- netclos();
- return(-1);
- }
- }
-#endif /* CK_SSL */
-
-#ifdef RLOGCODE
- if (ttnproto == NP_RLOGIN
-#ifdef CK_KERBEROS
- || ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN
- || ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_KERBEROS */
- ) { /* Similar deal for rlogin */
- if (rlog_ini(((tcp_rdns && host && host->h_name && host->h_name[0]) ?
- (CHAR *)host->h_name : (CHAR *)ipaddr),
- service->s_port,
- &l_addr,&r_addr
- ) < 0) {
- debug(F100,"rlogin initialization failed","",0);
- netclos();
- return(-1);
- }
- } else
-#endif /* RLOGCODE */
- if (tn_ini() < 0) { /* Start Telnet negotiations. */
- netclos();
- return(-1); /* Gone, so open failed. */
- }
- if (ttchk() < 0) {
- netclos();
- return(-1);
- }
-#ifdef CK_KERBEROS
-#ifdef KRB5_U2U
- if ( ttnproto == NP_K5U2U ) {
- if (k5_user_to_user_client_auth()) {
- netclos();
- return(-1);
- }
- }
-#endif /* KRB5_U2U */
-#endif /* CK_KERBEROS */
-
- debug(F101,"netopen service","",svcnum);
- debug(F110,"netopen name",name,0);
- debug(F110,"netopen ipaddr",ipaddr,0);
- ckstrncpy(hostipaddr,ipaddr,63);
-
- if (lcl) if (*lcl < 0) /* Local mode. */
- *lcl = 1;
-#endif /* TCPSOCKET */
- return(0); /* Done. */
-}
-
-/* N E T C L O S -- Close current network connection. */
-
-#ifndef NOLOCAL
-_PROTOTYP(VOID slrestor,(VOID));
-#ifdef CK_SSL
-int tls_norestore = 0;
-#endif /* CK_SSL */
-#endif /* NOLOCAL */
-
-int
-netclos() {
- static int close_in_progress = 0;
- int x = 0, y, z;
- debug(F101,"netclos","",ttyfd);
-
-#ifdef NETLEBUF
- if (!tt_push_inited)
- le_init();
-#endif /* NETLEBUF */
-
- if (ttyfd == -1) /* Was open? */
- return(0); /* Wasn't. */
-
- if (close_in_progress)
- return(0);
- close_in_progress = 1; /* Remember */
-
-#ifndef NOLOCAL
- /* This function call should not be here since this is a direct call */
- /* from an I/O routine to a user interface level function. However, */
- /* the reality is that we do not have pure interfaces. If we ever */
- /* decide to clean this up the UI level should assign this function */
- /* via a pointer assignment. - Jeff 9/10/1999 */
-#ifdef CK_SSL
- if (!tls_norestore)
-#endif /* CK_SSL */
- slrestor();
-#endif /* NOLOCAL */
-#ifdef OS2
- RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
-#else /* OS2 */
- if (ttyfd > -1) /* Was. */
-#endif /* OS2 */
- {
-#ifdef VMS
- y = 1; /* Turn on nonblocking reads */
- z = socket_ioctl(ttyfd,FIONBIO,&y);
- debug(F111,"netclos FIONBIO","on",z);
-#endif /* VMS */
-#ifdef TNCODE
- if (ttnproto == NP_TELNET) {
- if (!TELOPT_ME(TELOPT_LOGOUT)
-#ifdef COMMENT
-/* Jeff 2005/12/30 */
-#ifdef CK_SSL
- && !ssl_raw_flag && !tls_raw_flag
-#endif /* CK_SSL */
-#endif /* COMMENT */
- ) {
- /* Send LOGOUT option before close */
- if (tn_sopt(DO,TELOPT_LOGOUT) >= 0) {
- TELOPT_UNANSWERED_DO(TELOPT_LOGOUT) = 1;
- /* It would be nice to call tn_wait but we can't */
- }
- }
- tn_push(); /* Place any waiting data into input*/
- }
-#endif /* TNCODE */
-#ifdef CK_SSL
- if (ssl_active_flag) {
- if (ssl_debug_flag)
- BIO_printf(bio_err,"calling SSL_shutdown\n");
- SSL_shutdown(ssl_con);
- ssl_active_flag = 0;
- }
- if (tls_active_flag) {
- if (ssl_debug_flag)
- BIO_printf(bio_err,"calling SSL_shutdown\n");
- SSL_shutdown(tls_con);
- tls_active_flag = 0;
- }
-#endif /* CK_SSL */
-#ifdef VMS
- ck_cancio(); /* Cancel any outstanding reads. */
-#endif /* VMS */
-#ifdef TCPIPLIB
- x = socket_close(ttyfd); /* Close it. */
-#else
-#ifndef OS2
-#ifdef IBMX25
- if (ttnet == NET_IX25) {
- /* riehm: should send a disc_req - but only if link is still OK */
- x = x25clear();
- close(ttyfd);
- if (x25serverfd) {
- /* we were the passive client of a server, now we
- * go back to being the normal client.
- * I hope that kermit can cope with the logic that
- * there can still be a connection after netclos
- * has been called.
- */
- ttyfd = x25serverfd;
- x25serverfd = 0;
- /*
- * need to close the server connection too - because
- * all file descriptors connected to the NPI have the
- * same status.
- *
- * The problem is that any waiting connections get
- * lost, the client doesn't realise, and hangs.
- */
- netclos();
- }
- x25_state = X25_CLOSED; /* riehm: dead code? */
- } else
-#endif /* IBMX25 */
- x = close(ttyfd);
-#endif /* OS2 */
-#endif /* TCPIPLIB */
- }
- ttyfd = -1; /* Mark it as closed. */
- wasclosed = 1;
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
-#ifdef TNCODE
-#ifdef CK_FORWARD_X
- fwdx_close_all(); /* Shut down any Forward X sockets */
-#endif /* CK_FORWARD_X */
- tn_reset(); /* The Reset Telnet Option table. */
- debug(F100,"netclose setting tn_init = 0","",0);
- tn_init = 0; /* Remember about telnet protocol... */
- sstelnet = 0; /* Client-side Telnet */
-#endif /* TNCODE */
- *ipaddr = '\0'; /* Zero the IP address string */
- tcp_incoming = 0; /* No longer incoming */
- /* Don't reset ttnproto so that we can remember which protocol is in use */
-
-#ifdef TCPIPLIB
-/*
- Empty the internal buffers so they won't be used as invalid input on
- the next connect attempt (rlogin).
-*/
- ttibp = 0;
- ttibn = 0;
-#endif /* TCPIPLIB */
-#ifdef CK_KERBEROS
- /* If we are automatically destroying Kerberos credentials on Close */
- /* do it now. */
-#ifdef KRB4
- if (krb4_autodel == KRB_DEL_CL) {
- extern struct krb_op_data krb_op;
- krb_op.version = 4;
- krb_op.cache = NULL;
- ck_krb4_destroy(&krb_op);
- }
-#endif /* KRB4 */
-#ifdef KRB5
- if (krb5_autodel == KRB_DEL_CL) {
- extern struct krb_op_data krb_op;
- extern char * krb5_d_cc;
- krb_op.version = 5;
- krb_op.cache = krb5_d_cc;
- ck_krb5_destroy(&krb_op);
- }
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
- close_in_progress = 0; /* Remember we are done. */
- return(x);
-}
-
-#ifdef OS2
-int
-os2socketerror( int s_errno ) {
-#ifdef OS2ONLY
- if (s_errno > 0 && s_errno <= SOCBASEERR) {
- /* in OS/2, there is a problem with threading in that
- * the value of errno is not thread safe. It can be
- * set to a value from a previous library call and if
- * it was not cleared it will appear here. Only treat
- * valid socket error codes as errors in this function.
- */
- debug(F100,"os2socketerror errno.h","",0);
- socket_errno = 0;
- return(0);
- }
-#endif /* OS2ONLY */
-
- switch (s_errno) {
- case 0: /* NO ERROR */
- debug(F100,"os2socketerror NOERROR","",0);
- return(0);
-#ifdef NT
- case WSAECONNRESET:
-#else /* NT */
- case SOCECONNRESET:
- case SOCECONNRESET - SOCBASEERR:
-#endif /* NT */
- debug(F100,"os2socketerror ECONRESET","",0);
- tn_debug("ECONRESET");
- netclos(); /* *** *** */
- return(-1); /* Connection is broken. */
-#ifdef NT
- case WSAECONNABORTED:
-#else /* NT */
- case SOCECONNABORTED:
- case SOCECONNABORTED - SOCBASEERR:
-#endif /* NT */
- debug(F100,"os2socketerror ECONNABORTED","",0);
- tn_debug("ECONNABORTED");
- netclos(); /* *** *** */
- return(-1); /* Connection is broken. */
-#ifdef NT
- case WSAENETRESET:
-#else /* NT */
- case SOCENETRESET:
- case SOCENETRESET - SOCBASEERR:
-#endif /* NT */
- debug(F100,"os2socketerror ENETRESET","",0);
- tn_debug("ENETRESET");
- netclos(); /* *** *** */
- return(-1); /* Connection is broken. */
-#ifdef NT
- case WSAENOTCONN:
-#else /* NT */
- case SOCENOTCONN:
- case SOCENOTCONN - SOCBASEERR:
-#endif /* NT */
- debug(F100,"os2socketerror ENOTCONN","",0);
- tn_debug("ENOTCONN");
- netclos(); /* *** *** */
- return(-1); /* Connection is broken. */
-#ifdef NT
- case WSAESHUTDOWN:
- debug(F100,"os2socketerror ESHUTDOWN","",0);
- tn_debug("ESHUTDOWN");
- netclos(); /* *** *** */
- return(-1); /* Connection is broken. */
-#endif /* NT */
-#ifdef NT
- case WSAEWOULDBLOCK:
-#else
- case SOCEWOULDBLOCK:
- case SOCEWOULDBLOCK - SOCBASEERR:
-#endif /* NT */
- debug(F100,"os2socketerror EWOULDBLOCK","",0);
- return(0);
-#ifdef NT
- case ERROR_IO_INCOMPLETE:
- case ERROR_IO_PENDING:
- case ERROR_OPERATION_ABORTED:
- return(0);
-#endif /* NT */
- default:
- return(-2);
- }
- return(0);
-}
-#endif /* OS2 */
-
-/* N E T T C H K -- Check if network up, and how many bytes can be read */
-/*
- Returns number of bytes waiting, or -1 if connection has been dropped.
-*/
-int /* Check how many bytes are ready */
-nettchk() { /* for reading from network */
-#ifdef TCPIPLIB
- long count = 0;
- int x = 0, z;
- long y;
- char c;
- int rc;
-#ifdef NT
- extern int ionoblock; /* For Overlapped I/O */
-#endif /* NT */
-
- debug(F101,"nettchk entry ttibn","",ttibn);
- debug(F101,"nettchk entry ttibp","",ttibp);
-
-#ifdef NETLEBUF
- {
- int n = 0;
- if (ttpush >= 0)
- n++;
- n += le_inbuf();
- if (n > 0)
- return(n);
- }
-#endif /* NETLEBUF */
-
-#ifndef OS2
-#ifndef BEBOX
- socket_errno = 0; /* This is a function call in NT, and BeOS */
-#endif /* BEBOX */
-#endif /* OS2 */
-
- if (ttyfd == -1) {
- debug(F100,"nettchk socket is closed","",0);
- return(-1);
- }
-/*
- Note: this socket_ioctl() call does NOT return an error if the
- connection has been broken. (At least not in MultiNet.)
-*/
-#ifdef COMMENT
-/* Another trick that can be tried here is something like this: */
-
- if (ttnet == NET_TCPB) {
- char dummy;
- x = read(ttyfd,&dummy,0); /* Try to read nothing */
- if (x < 0) { /* "Connection reset by peer" */
- perror("TCP/IP"); /* or somesuch... */
- ttclos(0); /* Close our end too. */
- return(-1);
- }
- }
-#endif /* COMMENT */
-
-
-#ifdef CK_SSL
- if (ssl_active_flag) {
-#ifndef IKSDONLY
-#ifdef OS2
- if ( IsConnectMode() ) {
- debug(F101,"nettchk (ssl_active_flag) returns","",count);
- return(0);
- }
-#endif /* OS2 */
-#endif /* IKSDONLY */
- count = SSL_pending(ssl_con);
- if (count < 0) {
- debug(F111,"nettchk","SSL_pending error",count);
- netclos();
- return(-1);
- }
- if ( count > 0 )
- return(count); /* Don't perform a read */
- } else if (tls_active_flag) {
-#ifndef IKSDONLY
-#ifdef OS2
- if ( IsConnectMode() ) {
- debug(F101,"nettchk (tls_active_flag) returns","",count);
- return(0);
- }
-#endif /* OS2 */
-#endif /* IKSDONLY */
- count = SSL_pending(tls_con);
- if (count < 0) {
- debug(F111,"nettchk","TLS_pending error",count);
- netclos();
- return(-1);
- }
- if ( count > 0 )
- return(count); /* Don't perform a read */
- } else
-#endif /* CK_SSL */
-
- if (socket_ioctl(ttyfd,FIONREAD,
-#ifdef COMMENT
- /* Now we've changed the ioctl(..,..,x) prototype for DECC to (void *) */
-#ifdef __DECC
- /* NOTE: "&count" might need to be "(char *)&count" in some settings. */
- /* Cast needed for DECC 4.1 & later? */
- /* Maybe, but __DECC_VER only exists in 5.0 and later */
- (char *)
-#endif /* __DECC */
-#endif /* COMMENT */
- &count
- ) < 0) {
- debug(F101,"nettchk socket_ioctl error","",socket_errno);
- /* If the connection is gone, the connection is gone. */
- netclos();
-#ifdef NT_TCP_OVERLAPPED
- /* Is there anything in the overlapped I/O buffers? */
- count += OverlappedDataWaiting();
-#endif /* NT_TCP_OVERLAPPED */
- count += ttibn;
- return(count>0?count:-1);
- }
- debug(F101,"nettchk count","",count);
-#ifdef NT_TCP_OVERLAPPED
- /* Is there anything in the overlapped I/O buffers? */
- count += OverlappedDataWaiting();
- debug(F101,"nettchk count w/overlapped","",count);
-#endif /* NT_TCP_OVERLAPPED */
-
-#ifdef OS2
-#ifndef IKSDONLY
- if ( IsConnectMode() ) {
- debug(F101,"nettchk (FIONREAD) returns","",count);
- return(count);
- }
-#endif /* IKSDONLY */
-#endif /* OS2 */
-
-/* For the sake of efficiency, if there is still data in the ttibuf */
-/* do not go to the bother of checking to see of the connection is */
-/* still valid. The handle is still good, so just return the count */
-/* of the bytes that we already have left to process. */
-#ifdef OS2
- if ( count > 0 || ttibn > 0 ) {
- count+=ttibn;
- debug(F101,"nettchk (count+ttibn > 0) returns","",count);
- return(count);
- } else {
- RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
- if ( ttibn == 0 )
- ttibp = 0; /* reset for next read */
- }
-#else /* OS2 */
- if ( count > 0 || ttibn > 0 ) {
- debug(F101,"nettchk returns","",count+ttibn);
- return(count+ttibn);
- }
- ttibn = ttibp = 0;
-#endif /* OS2 */
-
-/*
- The following code works well in most settings, but messes things up in
- others, including CMU/Tek TCP/IP and UCX 2.0, where it somehow manages to
- make it impossible to ever make a new connection to the same host again with
- CONNECT, once it has been logged out from the first time. Not even if you
- HANGUP first, or SET HOST<CR>, or SET LINE<CR>. Reportedly, however, it
- does work OK in later releases of UCX. But there is no way we can
- accommodate both old and new -- we might have static linking or dynamic
- linking, etc etc. If we have static, I only have access to 2.0, where this
- doesn't work, etc etc blah blah.
-
- In the following lines, we define a symbol NOCOUNT for builds where we want
- to omit this code. By default, it is omitted for CMU/Tek. You can force
- omission of it for other combinations by defining NOCOUNT in CFLAGS. You
- can force inclusion of this code, even for CMU/Tek, by including NONOCOUNT
- in CFLAGS.
-*/
-#ifdef NONOCOUNT
-#ifdef NOCOUNT
-#undef NOCOUNT
-#endif /* NOCOUNT */
-#else
-#ifndef NOCOUNT
-#ifdef CMU_TCPIP
-#define NOCOUNT
-#endif /* CMU_TCPIP */
-#endif /* NOCOUNT */
-#endif /* NONOCOUNT */
-
-
- /* From this point forward we have a possible race condition in K95
- * due to its use of multiple threads. Therefore, we must ensure
- * that only one thread attempt to read/write from the socket at a
- * time. Otherwise, it is possible for a buffer to be overwritten.
- */
- /* we know now that count >= 0 and that ttibn == 0 */
-
- if (count == 0
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
- && ttnproto != NP_EK4LOGIN && ttnproto != NP_EK5LOGIN
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
- ) {
- int s_errno = 0;
-#ifndef NOCOUNT
-/*
- Here we need to tell the difference between a 0 count on an active
- connection, and a 0 count because the remote end of the socket broke the
- connection. There is no mechanism in TGV MultiNet (or WIN/TCP?) to query
- the status of the connection, so we have to do a read. -1 means there was
- no data available (socket_errno == EWOULDBLOCK), 0 means the connection is
- down. But if, by chance, we actually get a character, we have to put it
- where it won't be lost.
-*/
-#ifndef NON_BLOCK_IO
-#ifdef OS2
-#ifdef CK_SSL
- RequestSSLMutex(SEM_INDEFINITE_WAIT);
-#endif /* CK_SSL */
-#endif /* OS2 */
- y = 1; /* Turn on nonblocking reads */
- z = socket_ioctl(ttyfd,FIONBIO,&y);
- debug(F111,"nettchk FIONBIO","on",z);
-#ifdef OS2
-#ifdef CK_SSL
- ReleaseSSLMutex();
-#endif /* CK_SSL */
-#endif /* OS2 */
-#endif /* NON_BLOCK_IO */
-#ifdef NT_TCP_OVERLAPPED
- ionoblock = 1; /* For Overlapped I/O */
-#endif /* NT_TCP_OVERLAPPED */
-#ifdef CK_SSL
- if ( ssl_active_flag || tls_active_flag ) {
-#ifdef OS2
- ssl_read:
- x = SSL_read( ssl_active_flag?ssl_con:tls_con,
- &ttibuf[ttibp+ttibn],
- TTIBUFL-ttibp-ttibn );
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,x)) {
- case SSL_ERROR_NONE:
- debug(F111,"nettchk SSL_ERROR_NONE","x",x);
- break;
- case SSL_ERROR_WANT_WRITE:
- debug(F100,"nettchk SSL_ERROR_WANT_WRITE","",0);
- x = -1;
- break;
- case SSL_ERROR_WANT_READ:
- debug(F100,"nettchk SSL_ERROR_WANT_READ","",0);
- x = -1;
- break;
- case SSL_ERROR_SYSCALL:
- if ( x == 0 ) { /* EOF */
- netclos();
- rc = -1;
- goto nettchk_return;
- } else {
-#ifdef NT
- int gle = GetLastError();
-#endif /* NT */
-#ifndef NON_BLOCK_IO
-#ifdef OS2
-#ifdef CK_SSL
- RequestSSLMutex(SEM_INDEFINITE_WAIT);
-#endif /* CK_SSL */
-#endif /* OS2 */
- y = 0; /* Turn off nonblocking reads */
- z = socket_ioctl(ttyfd,FIONBIO,&y);
- debug(F111,"nettchk FIONBIO","off",z);
-#ifdef OS2
-#ifdef CK_SSL
- ReleaseSSLMutex();
-#endif /* CK_SSL */
-#endif /* OS2 */
-#endif /* NON_BLOCK_IO */
-#ifdef NT_TCP_OVERLAPPED
- ionoblock = 0; /* For Overlapped I/O */
-#endif /* NT_TCP_OVERLAPPED */
-#ifdef NT
- debug(F111,"nettchk SSL_ERROR_SYSCALL",
- "GetLastError()",gle);
- rc = os2socketerror(gle);
- if (rc == -1)
- rc = -2;
- else if ( rc == -2 )
- rc = -1;
- goto nettchk_return;
-#endif /* NT */
- break;
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- debug(F100,"nettchk SSL_ERROR_WANT_X509_LOOKUP","",0);
- break;
- case SSL_ERROR_SSL:
- if (bio_err!=NULL) {
- int len;
- extern char ssl_err[];
- BIO_printf(bio_err,"nettchk() SSL_ERROR_SSL\n");
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- debug(F110,"nettchk SSL_ERROR_SSL",ssl_err,0);
- if (ssl_debug_flag)
- printf(ssl_err);
- } else if (ssl_debug_flag) {
- debug(F100,"nettchk SSL_ERROR_SSL","",0);
- fflush(stderr);
- fprintf(stderr,"nettchk() SSL_ERROR_SSL\n");
- ERR_print_errors_fp(stderr);
- }
-#ifdef COMMENT
- netclos();
- rc = -1;
- goto nettchk_return;
-#else
- x = -1;
- break;
-#endif
- case SSL_ERROR_ZERO_RETURN:
- debug(F100,"nettchk SSL_ERROR_ZERO_RETURN","",0);
- netclos();
- rc = -1;
- goto nettchk_return;
- default:
- debug(F100,"nettchk SSL_ERROR_?????","",0);
- netclos();
- rc = -1;
- goto nettchk_return;
- }
-#else /* OS2 */
- /* Do not block */
- x = -1;
-#endif /* OS2 */
- } else
-#endif /* CK_SSL */
- {
-#ifdef OS2
- x = socket_read(ttyfd,&ttibuf[ttibp+ttibn],
- TTIBUFL-ttibp-ttibn); /* Returns -1 if no data */
-#else /* OS2 */
- x = socket_read(ttyfd,&c,1); /* Returns -1 if no data */
-#endif /* OS2 */
- }
- s_errno = socket_errno; /* socket_errno may be a function */
- debug(F101,"nettchk socket_read","",x);
-
-#ifndef NON_BLOCK_IO
-#ifdef OS2
-#ifdef CK_SSL
- RequestSSLMutex(SEM_INDEFINITE_WAIT);
-#endif /* CK_SSL */
-#endif /* OS2 */
- y = 0; /* Turn off nonblocking reads */
- z = socket_ioctl(ttyfd,FIONBIO,&y);
- debug(F111,"nettchk FIONBIO","off",z);
-#ifdef OS2
-#ifdef CK_SSL
- ReleaseSSLMutex();
-#endif /* CK_SSL */
-#endif /* OS2 */
-#endif /* NON_BLOCK_IO */
-#ifdef NT_TCP_OVERLAPPED
- ionoblock = 0; /* For Overlapped I/O */
-#endif /* NT_TCP_OVERLAPPED */
-
- if (x == -1) {
- debug(F101,"nettchk socket_read errno","",s_errno);
-#ifdef OS2
- if (os2socketerror(s_errno) < 0) {
- rc = -1;
- goto nettchk_return;
- }
-#endif /* OS2 */
- } else if (x == 0) {
- debug(F100,"nettchk connection closed","",0);
- netclos(); /* *** *** */
- rc = -1;
- goto nettchk_return;
- }
- if (x >= 1) { /* Oops, actually got a byte? */
-#ifdef OS2
- /* In OS/2 we read directly into ttibuf[] */
- ckhexdump("nettchk got real data",&ttibuf[ttibp+ttibn],x);
- ttibn += x;
-#else /* OS2 */
-#ifdef CK_SSL
- if ( ssl_active_flag || tls_active_flag ) {
- ckhexdump("nettchk got real data",&ttibuf[ttibp+ttibn],x);
- ttibn += x;
- } else
-#endif /* CK_SSL */
- {
- debug(F101,"nettchk socket_read char","",c);
- debug(F101,"nettchk ttibp","",ttibp);
- debug(F101,"nettchk ttibn","",ttibn);
-/*
- In the case of Overlapped I/O the character would have come from
- the beginning of the buffer, so put it back.
-*/
- if (ttibp > 0) {
- ttibp--;
- ttibuf[ttibp] = c;
- ttibn++;
- } else {
- ttibuf[ttibp+ttibn] = c;
- ttibn++;
- }
- }
-#endif /* OS2 */
- }
-#else /* NOCOUNT */
- if (ttnet == NET_TCPB) {
- char dummy;
- x = read(ttyfd,&dummy,0); /* Try to read nothing */
- if (x < 0) { /* "Connection reset by peer" */
- perror("TCP/IP"); /* or somesuch... */
- ttclos(0); /* Close our end too. */
- rc = -1;
- goto nettchk_return;
- }
- }
-#endif /* NOCOUNT */
- }
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN)
- count += krb4_des_avail(ttyfd);
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN)
- count += krb5_des_avail(ttyfd);
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U)
- count += krb5_u2u_avail(ttyfd);
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
- debug(F101,"nettchk returns","",count+ttibn);
- rc = count + ttibn;
-
- nettchk_return:
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(rc);
-
-#else /* Not TCPIPLIB */
-/*
- UNIX just uses ttchk(), in which the ioctl() calls on the file descriptor
- seem to work OK.
-*/
- return(ttchk());
-#endif /* TCPIPLIB */
-/*
- But what about X.25?
-*/
-}
-
-#ifndef OS2
-VOID
-nettout(i) int i; { /* Catch the alarm interrupts */
- debug(F100,"nettout caught timeout","",0);
- ttimoff();
- cklongjmp(njbuf, -1);
-}
-#endif /* !OS2 */
-
-#ifdef TCPIPLIB
-
-VOID
-#ifdef CK_ANSIC
-donetinc(void * threadinfo)
-#else /* CK_ANSIC */
-donetinc(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* donetinc */ {
-#ifdef NTSIG
- extern int TlsIndex;
- setint();
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- }
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef NT
-#ifdef IKSD
- if (inserver)
- setntcreds();
-#endif /* IKSD */
-#endif /* NT */
-#endif /* CK_LOGIN */
- while (1) {
- if (ttbufr() < 0) /* Keep trying to refill it. */
- break; /* Till we get an error. */
- if (ttibn > 0) /* Or we get a character. */
- break;
- }
-}
-#endif /* TCPIPLIB */
-
-VOID
-#ifdef CK_ANSIC
-failnetinc(void * threadinfo)
-#else /* CK_ANSIC */
-failnetinc(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* failnetinc */ {
- ; /* Nothing to do on an error */
-}
-
-/* N E T X I N -- Input block of characters from network */
-
-int
-netxin(n,buf) int n; CHAR * buf; {
- int len, i, j;
-#ifdef TCPIPLIB
- int rc;
-#endif /* TCPIPLIB */
-
- if (ttyfd == -1) {
- debug(F100,"netxin socket is closed","",0);
- return(-2);
- }
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- if ((len = krb4_des_read(ttyfd,buf,n)) < 0)
- return(-1);
- else
- return(len);
- }
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- if ((len = krb5_des_read(ttyfd,(char *)buf,n,0)) < 0)
- return(-1);
- else
- return(len);
- }
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- if ((len = krb5_u2u_read(ttyfd,(char *)buf,n)) < 0)
- return(-1);
- else
- return(len);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef TCPIPLIB
-#ifdef OS2
- RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
-#endif /* OS2 */
- if (ttibn == 0)
- if ((rc = ttbufr()) <= 0) {
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(rc);
- }
-
- if (ttibn <= n) {
- len = ttibn;
- memcpy(buf,&ttibuf[ttibp],len); /* safe */
- ttibp += len;
- ttibn = 0;
- } else {
- memcpy(buf,&ttibuf[ttibp],n); /* safe */
- ttibp += n;
- ttibn -= n;
- len = n;
- }
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
-#else /* TCPIPLIB */
- for (i = 0; i < n; i++) {
- if ((j = netinc(0)) < 0) {
- if (j < -1)
- return(j);
- else
- break;
- }
- buf[i] = j;
- }
- len = i;
-#endif /* TCPIPLIB */
-
-#ifdef COMMENT
-#ifdef CK_ENCRYPTION
- /* This would be great if it worked. But what if the buffer we read */
- /* contains a telnet negotiation that changes the state of the */
- /* encryption. If so, we would be either decrypting unencrypted text */
- /* or not decrypting encrypted text. So we must move this call to */
- /* all functions that call ttxin(). In OS2 that means os2_netxin() */
- /* where the Telnet Negotiations are handled. */
- if (u_encrypt)
- ck_tn_decrypt(buf,len);
-#endif /* CK_ENCRYPTION */
-#endif /* COMMENT */
-
- return(len);
-}
-
-/* N E T I N C -- Input character from network */
-
-#ifdef NETLEBUF
-#define LEBUF
-#endif /* NETLEBUF */
-#ifdef TTLEBUF
-#define LEBUF
-#endif /* TTLEBUF */
-#ifndef LEBUF
-#ifdef OS2
-#define LEBUF
-#endif /* OS2 */
-#endif /* LEBUF */
-
-int
-netinc(timo) int timo; {
-#ifdef TCPIPLIB
- int x; unsigned char c; /* The locals. */
-
-#ifdef NETLEBUF
- if (ttpush >= 0) {
- debug(F111,"netinc","ttpush",ttpush);
- c = ttpush;
- ttpush = -1;
- return(c);
- }
- if (le_data) {
- if (le_getchar((CHAR *)&c) > 0) {
- debug(F111,"netinc le_getchar","c",c);
- return(c);
- }
- }
-#endif /* NETLEBUF */
-
- if (ttyfd == -1) {
- debug(F100,"netinc socket is closed","",0);
- return(-2);
- }
-
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- if ((x = krb4_des_read(ttyfd,&c,1)) == 0)
- return(-1);
- else if (x < 0)
- return(-2);
- else
- return(c);
- }
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- if ((x = krb5_des_read(ttyfd,&c,1,0)) == 0)
- return(-1);
- else if (x < 0)
- return(-2);
- else
- return(c);
- }
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- if ((x = krb5_u2u_read(ttyfd,&c,1)) == 0)
- return(-1);
- else if (x < 0)
- return(-2);
- else
- return(c);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef OS2
- RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
-#endif /* OS2 */
- if (ttibn > 0) { /* Something in internal buffer? */
-#ifdef COMMENT
- debug(F100,"netinc char in buf","",0); /* Yes. */
-#endif /* COMMENT */
- x = 0; /* Success. */
- } else { /* Else must read from network. */
- x = -1; /* Assume failure. */
-#ifdef DEBUG
- debug(F101,"netinc goes to net, timo","",timo);
-#endif /* DEBUG */
-#ifdef CK_SSL
- /*
- * In the case of OpenSSL, it is possible that there is still
- * data waiting in the SSL session buffers that has not yet
- * been read by Kermit. If this is the case we must process
- * it without calling select() because select() will not return
- * with an indication that there is data to be read from the
- * socket. If there is no data pending in the SSL session
- * buffers then fall through to the select() code and wait for
- * some data to arrive.
- */
- if (ssl_active_flag) {
- x = SSL_pending(ssl_con);
- if (x < 0) {
- debug(F111,"netinc","SSL_pending error",x);
- netclos();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- } else if ( x > 0 ) {
- if ( ttbufr() >= 0 ) {
- x = netinc(timo);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(x);
- }
- }
- x = -1;
- } else if (tls_active_flag) {
- x = SSL_pending(tls_con);
- if (x < 0) {
- debug(F111,"netinc","TLS_pending error",x);
- netclos();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- } else if ( x > 0 ) {
- if ( ttbufr() >= 0 ) {
- x = netinc(timo);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(x);
- }
- }
- x = -1;
- }
-#endif /* CK_SSL */
-#ifndef LEBUF
- if (timo == 0) { /* Untimed case. */
- while (1) { /* Wait forever if necessary. */
- if (ttbufr() < 0) /* Refill buffer. */
- break; /* Error, fail. */
- if (ttibn > 0) { /* Success. */
- x = 0;
- break;
- }
- }
- } else /* Timed case... */
-#endif /* LEBUF */
- {
-#ifdef NT_TCP_OVERLAPPED
- /* This code is for use on NT when we are using */
- /* Overlapped I/O to handle reads. In the case */
- /* of outstanding reads select() doesn't work */
-
- if (WaitForOverlappedReadData(timo)) {
- while (1) {
- if (ttbufr() < 0) /* Keep trying to refill it. */
- break; /* Till we get an error. */
- if (ttibn > 0) { /* Or we get a character. */
- x = 0;
- break;
- }
- }
- }
-#else /* NT_TCP_OVERLAPPED */
-#ifdef BSDSELECT
- fd_set rfds;
- struct timeval tv;
- int timeout = timo < 0 ? -timo : 1000 * timo;
- debug(F101,"netinc BSDSELECT","",timo);
-
- for ( ; timeout >= 0; timeout -= (timo ? 100 : 0)) {
- int rc;
- debug(F111,"netinc","timeout",timeout);
- /* Don't move select() initialization out of the loop. */
- FD_ZERO(&rfds);
- FD_SET(ttyfd, &rfds);
- tv.tv_sec = tv.tv_usec = 0L;
- if (timo)
- tv.tv_usec = (long) 100000L;
- else
- tv.tv_sec = 30;
-#ifdef NT
- WSASafeToCancel = 1;
-#endif /* NT */
- rc = select(FD_SETSIZE,
-#ifdef __DECC
-#ifdef INTSELECT
- (int *)
-#else /* def INTSELECT */
- (fd_set *)
-#endif /* def INTSELECT [else] */
-#else /* def __DECC */
- (fd_set *)
-#endif /* def __DECC [else] */
- &rfds, NULL, NULL, &tv);
- if (rc < 0) {
- int s_errno = socket_errno;
- debug(F111,"netinc","select",rc);
- debug(F111,"netinc","socket_errno",s_errno);
- if (s_errno) {
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- }
- }
- debug(F111,"netinc","select",rc);
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
- if (!FD_ISSET(ttyfd, &rfds)) {
-#ifdef LEBUF
- if (le_inbuf() > 0) {
- timeout = -1;
- break;
- }
-#endif /* LEBUF */
- /* If waiting forever we have no way of knowing if the */
- /* socket closed so try writing a 0-length TCP packet */
- /* which should force an error if the socket is closed */
- if (!timo) {
- if ((rc = socket_write(ttyfd,"",0)) < 0) {
- int s_errno = socket_errno;
- debug(F101,"netinc socket_write error","",s_errno);
-#ifdef OS2
- if (os2socketerror(s_errno) < 0) {
- ReleaseTCPIPMutex();
- return(-2);
- }
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1); /* Call it an i/o error */
- }
- }
- continue;
- }
- while (1) {
- if (ttbufr() < 0) { /* Keep trying to refill it. */
- timeout = -1;
- break; /* Till we get an error. */
- }
- if (ttibn > 0) { /* Or we get a character. */
- x = 0;
- timeout = -1;
- break;
- }
- }
- }
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
-#else /* !BSDSELECT */
-#ifdef IBMSELECT
-/*
- Was used by OS/2, currently not used, but might come in handy some day...
- ... and it came in handy! For our TCP/IP layer, it avoids all the fd_set
- and timeval stuff since this is the only place where it is used.
-*/
- int socket = ttyfd;
- int timeout = timo < 0 ? -timo : 1000 * timo;
-
- debug(F101,"netinc IBMSELECT","",timo);
- for ( ; timeout >= 0; timeout -= (timo ? 100 : 0)) {
- if (select(&socket, 1, 0, 0, 100L) == 1) {
- while (1) {
- if (ttbufr() < 0) { /* Keep trying to refill it. */
- timeout = -1;
- break; /* Till we get an error. */
- }
- if (ttibn > 0) { /* Or we get a character. */
- x = 0;
- timeout = -1;
- break;
- }
- }
- }
-#ifdef LEBUF
- else if (le_inbuf() > 0) {
- timeout = -1;
- break;
- }
-#endif /* LEBUF */
- }
-#else /* !IBMSELECT */
-#ifdef WINSOCK
- /* Actually, under WinSock we have a better mechanism than select() */
- /* for setting timeouts (SO_RCVTIMEO, SO_SNDTIMEO) */
- SOCKET socket = ttyfd;
- debug(F101,"netinc NTSELECT","",timo);
- if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timo,
- sizeof(timo)) == NO_ERROR)
- while (1) {
- if (ttbufr() < 0) /* Keep trying to refill it. */
- break; /* Till we get an error. */
- if (ttibn > 0) { /* Or we get a character. */
- x = 0;
- break;
- }
- }
-#else /* WINSOCK */
-/*
- If we can't use select(), then we use the regular alarm()/signal()
- timeout mechanism.
-*/
- debug(F101,"netinc alarm","",timo);
- x = alrm_execute(ckjaddr(njbuf),timo,nettout,donetinc,failnetinc);
- ttimoff(); /* Timer off. */
-#endif /* WINSOCK */
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
-#endif /* NT_TCP_OVERLAPPED */
- }
- }
-
-#ifdef LEBUF
- if (le_inbuf() > 0) { /* If data was inserted into the */
- if (le_getchar((CHAR *)&c) > 0) {/* Local Echo buffer while the */
-#ifdef OS2 /* was taking place do not mix */
- ReleaseTCPIPMutex(); /* the le data with the net data */
-#endif /* OS2 */
- return(c);
- }
- }
-#endif /* LEBUF */
- if (x < 0) { /* Return -1 if we failed. */
- debug(F100,"netinc timed out","",0);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- } else { /* Otherwise */
- c = ttibuf[ttibp]; /* Return the first char in ttibuf[] */
- if (deblog) {
-#ifndef COMMENT
- debug(F101,"netinc returning","",c);
-#endif /* COMMENT */
- if (c == 0) {
- debug(F101,"netinc 0 ttibn","",ttibn);
- debug(F101,"netinc 0 ttibp","",ttibp);
-#ifdef BETADEBUG
- {
-#ifdef OS2
- extern int tt_type_mode;
- if ( !ISVTNT(tt_type_mode) )
-#endif /* OS2 */
- ckhexdump("netinc &ttbuf[ttibp]",&ttibuf[ttibp],ttibn);
- }
-#endif /* BETADEBUG */
- }
- }
- ttibp++;
- ttibn--;
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION))
- ck_tn_decrypt(&c,1);
-#endif /* CK_ENCRYPTION */
- return(c);
- }
-#else /* Not using TCPIPLIB */
- return(-1);
-#endif /* TCPIPLIB */
-}
-
-/* N E T T O L -- Output a string of bytes to the network */
-/*
- Call with s = pointer to string, n = length.
- Returns number of bytes actually written on success, or
- -1 on i/o error, -2 if called improperly.
-*/
-
-int
-nettol(s,n) CHAR *s; int n; {
-#ifdef TCPIPLIB
- int count = 0;
- int len = n;
- int try = 0;
-
- if (ttyfd == -1) {
- debug(F100,"nettol socket is closed","",0);
- return -1;
- }
- debug(F101,"nettol TCPIPLIB ttnet","",ttnet);
-#ifdef COMMENT
- ckhexdump("nettol",s,n);
-#endif /* COMMENT */
-
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- return(krb4_des_write(ttyfd,s,n));
- }
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- return(krb5_des_write(ttyfd,s,n,0));
- }
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- return(krb5_u2u_write(ttyfd,s,n));
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef CK_ENCRYPTION
- if (TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(s,n);
-#endif /* CK_ENCRYPTION */
-
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error, r;
- /* Write using SSL */
- ssl_retry:
- if (ssl_active_flag)
- r = SSL_write(ssl_con, s, len /* >1024?1024:len */);
- else
- r = SSL_write(tls_con, s, len /* >1024?1024:len */);
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,r)) {
- case SSL_ERROR_NONE:
- debug(F111,"nettol","SSL_write",r);
- if ( r == len )
- return(n);
- s += r;
- len -= r;
- goto ssl_retry;
- case SSL_ERROR_WANT_WRITE:
- debug(F100,"nettol SSL_ERROR_WANT_WRITE","",0);
- return(-1);
- case SSL_ERROR_WANT_READ:
- debug(F100,"nettol SSL_ERROR_WANT_READ","",0);
- return(-1);
- case SSL_ERROR_SYSCALL:
- if ( r == 0 ) { /* EOF */
- netclos();
- return(-2);
- } else {
- int rc = -1;
-#ifdef NT
- int gle = GetLastError();
- debug(F111,"nettol SSL_ERROR_SYSCALL",
- "GetLastError()",gle);
- rc = os2socketerror(gle);
- if (rc == -1)
- rc = -2;
- else if ( rc == -2 )
- rc = -1;
-#endif /* NT */
- return(rc);
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- debug(F100,"nettol SSL_ERROR_WANT_X509_LOOKUP","",0);
- netclos();
- return(-2);
- case SSL_ERROR_SSL:
- debug(F100,"nettol SSL_ERROR_SSL","",0);
- if (bio_err!=NULL) {
- int len;
- extern char ssl_err[];
- BIO_printf(bio_err,"nettol() SSL_ERROR_SSL\n");
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- debug(F110,"nettol SSL_ERROR_SSL",ssl_err,0);
- if (ssl_debug_flag)
- printf(ssl_err);
- } else if (ssl_debug_flag) {
- debug(F100,"nettol SSL_ERROR_SSL","",0);
- fflush(stderr);
- fprintf(stderr,"nettol() SSL_ERROR_SSL\n");
- ERR_print_errors_fp(stderr);
- }
-#ifdef COMMENT
- netclos();
- return(-2);
-#else
- return(-1);
-#endif
- case SSL_ERROR_ZERO_RETURN:
- debug(F100,"nettol SSL_ERROR_ZERO_RETURN","",0);
- netclos();
- return(-2);
- default:
- debug(F100,"nettol SSL_ERROR_?????","",0);
- netclos();
- return(-2);
- }
- }
-#endif /* CK_SSL */
-
- nettol_retry:
- try++; /* Increase the try counter */
-
- if (ttnet == NET_TCPB) {
-#ifdef BSDSELECT
- fd_set wfds;
- struct timeval tv;
-
- debug(F101,"nettol BSDSELECT","",0);
- tv.tv_usec = 0L;
- tv.tv_sec=30;
-#ifdef NT
- WSASafeToCancel = 1;
-#endif /* NT */
-#ifdef STREAMING
- do_select:
-#endif /* STREAMING */
- FD_ZERO(&wfds);
- FD_SET(ttyfd, &wfds);
- if (select(FD_SETSIZE, NULL,
-#ifdef __DECC
-#ifndef __DECC_VER
- (int *)
-#endif /* __DECC_VER */
-#endif /* __DECC */
- &wfds, NULL, &tv) < 0) {
- int s_errno = socket_errno;
- debug(F101,"nettol select failed","",s_errno);
-#ifdef BETADEBUG
- printf("nettol select failed: %d\n", s_errno);
-#endif /* BETADEBUG */
-#ifdef NT
- WSASafeToCancel = 0;
- if (!win95selectbug)
-#endif /* NT */
- return(-1);
- }
- if (!FD_ISSET(ttyfd, &wfds)) {
-#ifdef STREAMING
- if (streaming)
- goto do_select;
-#endif /* STREAMING */
- debug(F111,"nettol","!FD_ISSET",ttyfd);
-#ifdef NT
- WSASafeToCancel = 0;
- if (!win95selectbug)
-#endif /* NT */
- return(-1);
- }
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
-#else /* BSDSELECT */
-#ifdef IBMSELECT
- {
- int tries = 0;
- debug(F101,"nettol IBMSELECT","",0);
- while (select(&ttyfd, 0, 1, 0, 1000) != 1) {
- int count;
- if (tries++ >= 60) {
- /* if after 60 seconds we can't get permission to write */
- debug(F101,"nettol select failed","",socket_errno);
- return(-1);
- }
- if ((count = nettchk()) < 0) {
- debug(F111,"nettol","nettchk()",count);
- return(count);
- }
- }
- }
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
- if ((count = socket_write(ttyfd,s,n)) < 0) {
- int s_errno = socket_errno; /* maybe a function */
- debug(F101,"nettol socket_write error","",s_errno);
-#ifdef OS2
- if (os2socketerror(s_errno) < 0)
- return(-2);
-#endif /* OS2 */
- return(-1); /* Call it an i/o error */
- }
- if (count < n) {
- debug(F111,"nettol socket_write",s,count);
- if (try > 25) {
- /* don't try more than 25 times */
- debug(F100,"nettol tried more than 25 times","",0);
- return(-1);
- }
- if (count > 0) {
- s += count;
- n -= count;
- }
- debug(F111,"nettol retry",s,n);
- goto nettol_retry;
- } else {
- debug(F111,"nettol socket_write",s,count);
- return(len); /* success - return total length */
- }
- } else
- return(-2);
-#else
- debug(F100,"nettol TCPIPLIB not defined","",0);
- return(-2);
-#endif /* TCPIPLIB */
-}
-
-/* N E T T O C -- Output character to network */
-/*
- Call with character to be transmitted.
- Returns 0 if transmission was successful, or
- -1 upon i/o error, or -2 if called improperly.
-*/
-int
-#ifdef CK_ANSIC
-nettoc(CHAR c)
-#else
-nettoc(c) CHAR c;
-#endif /* CK_ANSIC */
-/* nettoc */ {
-#ifdef UNIX
- return(ttoc(c));
-#else
-#ifdef TCPIPLIB
- unsigned char cc;
- if (ttyfd == -1) {
- debug(F100,"nettoc socket is closed","",0);
- return -1;
- }
- cc = c;
- debug(F101,"nettoc cc","",cc);
-
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- return(krb4_des_write(ttyfd,&cc,1)==1?0:-1);
- }
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- return(krb5_des_write(ttyfd,&cc,1,0)==1?0:-1);
- }
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- return(krb5_u2u_write(ttyfd,&cc,1)==1?0:-1);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef CK_ENCRYPTION
- if ( TELOPT_ME(TELOPT_ENCRYPTION) )
- ck_tn_encrypt(&cc,1);
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int len, error;
- /* Write using SSL */
- ssl_retry:
- if (ssl_active_flag)
- len = SSL_write(ssl_con, &cc, 1);
- else
- len = SSL_write(tls_con, &cc, 1);
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,len)) {
- case SSL_ERROR_NONE:
- debug(F111,"nettoc","SSL_write",len);
- return(len == 1 ? 0 : -1);
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(-1);
- case SSL_ERROR_SYSCALL:
- if ( len == 0 ) { /* EOF */
- netclos();
- return(-2);
- } else {
- int rc = -1;
-#ifdef NT
- int gle = GetLastError();
- debug(F111,"nettoc SSL_ERROR_SYSCALL",
- "GetLastError()",gle);
- rc = os2socketerror(gle);
- if (rc == -1)
- rc = -2;
- else if ( rc == -2 )
- rc = -1;
-#endif /* NT */
- return(rc);
- }
- case SSL_ERROR_SSL:
- if (bio_err!=NULL) {
- int len;
- extern char ssl_err[];
- BIO_printf(bio_err,"nettoc() SSL_ERROR_SSL\n");
- ERR_print_errors(bio_err);
- len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
- ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
- debug(F110,"nettoc SSL_ERROR_SSL",ssl_err,0);
- if (ssl_debug_flag)
- printf(ssl_err);
- } else if (ssl_debug_flag) {
- debug(F100,"nettoc SSL_ERROR_SSL","",0);
- fflush(stderr);
- fprintf(stderr,"nettoc() SSL_ERROR_SSL\n");
- ERR_print_errors_fp(stderr);
- }
- return(-1);
- break;
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_ZERO_RETURN:
- default:
- netclos();
- return(-2);
- }
- }
-#endif /* CK_SSL */
- if (ttnet == NET_TCPB) {
-#ifdef BSDSELECT
- fd_set wfds;
- struct timeval tv;
-
- debug(F101,"nettoc BSDSELECT","",0);
- tv.tv_usec = 0L;
- tv.tv_sec = 30;
-
-#ifdef STREAMING
- do_select:
-#endif /* STREAMING */
-
- FD_ZERO(&wfds);
- FD_SET(ttyfd, &wfds);
- if (select(FD_SETSIZE, NULL,
-#ifdef __DECC
-#ifndef __DECC_VER
- (int *)
-#endif /* __DECC_VER */
-#endif /* __DECC */
- &wfds, NULL, &tv) < 0) {
- int s_errno = socket_errno;
- debug(F101,"nettoc select failed","",s_errno);
-#ifdef BETADEBUG
- printf("nettoc select failed: %d\n", s_errno);
-#endif /* BETADEBUG */
-#ifdef NT
- WSASafeToCancel = 0;
- if (!win95selectbug)
-#endif /* NT */
- return(-1);
- }
- if (!FD_ISSET(ttyfd, &wfds)) {
-#ifdef STREAMING
- if (streaming)
- goto do_select;
-#endif /* STREAMING */
- debug(F111,"nettoc","!FD_ISSET",ttyfd);
-#ifdef NT
- WSASafeToCancel = 0;
- if (!win95selectbug)
-#endif /* NT */
- return(-1);
- }
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
-#else /* BSDSELECT */
-#ifdef IBMSELECT
- {
- int tries = 0;
- while (select(&ttyfd, 0, 1, 0, 1000) != 1) {
- int count;
- if (tries++ >= 60) {
- /* if after 60 seconds we can't get permission to write */
- debug(F101,"nettoc select failed","",socket_errno);
- return(-1);
- }
- if ((count = nettchk()) < 0) {
- debug(F111,"nettoc","nettchk()",count);
- return(count);
- }
- }
- }
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
- if (socket_write(ttyfd,&cc,1) < 1) {
- int s_errno = socket_errno; /* maybe a function */
- debug(F101,"nettoc socket_write error","",s_errno);
-#ifdef OS2
- if (os2socketerror(s_errno) < 0)
- return(-2);
-#endif /* OS2 */
- return(-1);
- }
- debug(F101,"nettoc socket_write","", cc);
- return(0);
- } else return(-2);
-#else
- return(-2);
-#endif /* TCPIPLIB */
-#endif /* UNIX */
-}
-
-/* N E T F L U I -- Flush network input buffer */
-
-#ifdef TNCODE
-static int
-#ifdef CK_ANSIC
-netgetc(int timo) /* Input function to point to... */
-#else /* CK_ANSIC */
-netgetc(timo) int timo;
-#endif /* CK_ANSIC */
-{ /* ...in the tn_doop() call */
-#ifdef TCPIPLIB
- return netinc(timo);
-#else /* TCPIPLIB */
- return ttinc(timo);
-#endif /* TCPIPLIB */
-}
-#endif /* TNCODE */
-
-int
-netflui() {
- int n;
- int ch;
-#ifdef NETLEBUF
- ttpush = -1; /* Clear the peek-ahead char */
- while (le_data && (le_inbuf() > 0)) {
- CHAR ch = '\0';
- if (le_getchar(&ch) > 0) {
- debug(F101,"ttflui le_inbuf ch","",ch);
- }
- }
-#endif /* NETLEBUF */
-
-#ifdef TCPIPLIB
-#ifdef OS2
- RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
-#endif /* OS2 */
-#ifdef TNCODE
- if (ttnproto == NP_TELNET) {
- /* Netflui must process Telnet negotiations or get out of sync */
- if ((n = nettchk()) <= 0)
- goto exit_flui;
- while (n-- > 0) {
- ch = netinc(1);
- if (ch == IAC) {
- extern int duplex; /* this really shouldn't be here but ... */
- int tx = tn_doop((CHAR)(ch & 0xff),duplex,netgetc);
- if (tx == 1) duplex = 1;
- else if (tx == 2) duplex = 0;
- n = nettchk();
- }
- }
- } else
-#endif /* TNCODE */
- {
- ttibuf[ttibp+ttibn] = '\0';
- debug(F111,"netflui 1",ttibuf,ttibn);
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION)) {
- ck_tn_decrypt(&ttibuf[ttibp],ttibn);
- }
-#endif /* CK_ENCRYPTION */
- ttibn = ttibp = 0; /* Flush internal buffer *FIRST* */
- if (ttyfd < 1)
- goto exit_flui;
- if ((n = nettchk()) > 0) { /* Now see what's waiting on the net */
- if (n > TTIBUFL) n = TTIBUFL; /* and sponge it up */
- debug(F101,"netflui 2","",n); /* ... */
- n = socket_read(ttyfd,ttibuf,n); /* into our buffer */
- if (n >= 0) ttibuf[n] = '\0';
- debug(F111,"netflui 3",ttibuf,n);
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION)) {
- ck_tn_decrypt(&ttibuf[ttibp],n);
- }
-#endif /* CK_ENCRYPTION */
- ttibuf[0] = '\0';
- }
- }
-#else /* !TCPIPLIB */
- if (ttyfd < 1)
- goto exit_flui;
-#ifdef TNCODE
- if (ttnproto == NP_TELNET) {
- if ((n = ttchk()) <= 0)
- goto exit_flui;
- while (n-- >= 0) {
- /* Netflui must process Telnet negotiations or get out of sync */
- ch = ttinc(1);
- if (ch == IAC) {
- extern int duplex; /* this really shouldn't be here but ... */
- int tx = tn_doop((CHAR)(ch & 0xff),duplex,netgetc);
- if (tx == 1) duplex = 1;
- else if (tx == 2) duplex = 0;
- n = ttchk();
- }
- };
- } else
-#endif /* TNCODE */
- if ((n = ttchk()) > 0) {
- debug(F101,"netflui non-TCPIPLIB","",n);
- while ((n--) && ttinc(1) > -1) /* Don't worry, ttinc() is buffered */
- ; /* and it handles the decryption... */
- }
-#endif /* TCPIPLIB */
- exit_flui:
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(0);
-}
-
-#ifdef CK_KERBEROS
-/* The following two functions are required for encrypted rlogin */
-/* They are called with nettoc() or nettol() are transmitting */
-/* encrypted data. They call a function to encrypt the data */
-/* and that function needs to be able to write to/read from the */
-/* network in an unimpeded manner. Hence, these two simple fns. */
-int
-net_write(fd, buf, len)
- int fd;
- register const char *buf;
- int len;
-{
- int cc;
- register int wrlen = len;
- do {
-#ifdef TCPIPLIB
- cc = socket_write(fd, buf, wrlen);
-#else
- cc = write(fd,buf,wrlen);
-#endif /* TCPIPLIB */
- if (cc < 0) {
- int s_errno = socket_errno;
- debug(F101,"net_write error","",s_errno);
-#ifdef OS2
- if (os2socketerror(s_errno) < 0)
- return(-1);
- else
- continue;
-#else /* OS2 */
- if (errno == EINTR)
- continue;
- return(-1);
-#endif /* OS2 */
- }
- else {
- buf += cc;
- wrlen -= cc;
- }
- } while (wrlen > 0);
- return(len);
-}
-int
-net_read(fd, buf, len)
- int fd;
- register char *buf;
- register int len;
-{
- int cc, len2 = 0;
-
- do {
-#ifdef TCPIPLIB
- cc = socket_read(fd, buf, len);
-#else
- cc = read(fd,buf,len);
-#endif
- if (cc < 0) {
- int s_errno = socket_errno;
- debug(F101,"net_read error","",s_errno);
-#ifdef OS2
- if (os2socketerror(s_errno) < 0)
- return(-1);
-#endif /* OS2 */
- return(cc); /* errno is already set */
- }
- else if (cc == 0) {
- netclos();
- return(len2);
- } else {
- buf += cc;
- len2 += cc;
- len -= cc;
- }
- } while (len > 0);
- return(len2);
-}
-#endif /* CK_KERBEROS */
-#endif /* NONET */
-
-/* getlocalipaddr() attempts to resolve an IP Address for the local machine.
- * If the host is multi-homed it returns only one address.
- *
- * Two techniques are used.
- * (1) get the local host name and perform a DNS lookup, then take
- * the first entry;
- * (2) open a UDP socket, use it to connect to a fictitious host (it's OK,
- * no data is sent), then retrieve the local address from the socket.
- * Note: the second technique won't work on Microsoft systems. See
- * Article ID: Q129065 PRB: Getsockname() Returns IP Address 0.0.0.0 for UDP
- */
-
-/* Technique number one cannot work reliably if the machine is a laptop
- * and the hostname is associated with a physical adapter which is not
- * installed and a PPP connection is being used instead. This is because
- * the hostname DNS lookup will succeed for the physical adapter even though
- * it would be impossible to use it. In NT4 SP4, the gethostbyname()
- * when given the result of gethostname() returns not the real DNS entries
- * for that name+domain. Instead it returns all of the static and dynamic
- * IP addresses assigned to any physical or virtual adapter defined in the
- * system regardless of whether or not it is installed. The order of the
- * addresses is fixed according to the binding order in the NT registry.
- */
-
-/*
- * It appears that calling gethostbyname(NULL) is more reliable than
- * calling gethostbyname(gethostname()) on Windows. So on Windows we will
- * only call gethostbyname(NULL).
- */
-
-int
-getlocalipaddr() {
-#ifndef datageneral
- struct sockaddr_in l_sa;
- struct sockaddr_in r_sa;
- GSOCKNAME_T slen = sizeof(struct sockaddr_in);
- int sock;
- int rc;
- struct in_addr laddr;
-
- /* if still not resolved, then try second strategy */
- /* This second strategy does not work on Windows */
-
- debug(F100,"getlocalipaddr","",0);
- memset(&l_sa,0,slen);
- memset(&r_sa,0,slen);
-
- /* get a UDP socket */
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock != -1) {
- /* connect to arbirary port and address (NOT loopback) */
- r_sa.sin_family = AF_INET;
- r_sa.sin_port = htons(IPPORT_ECHO);
-
- /* The following is an "illegal conversion" in AOS/VS */
- /* (and who knows where else) */
-
-#ifdef INADDRX
- inaddrx = inet_addr("128.127.50.1");
- r_sa.sin_addr.s_addr = *(unsigned long *)&inaddrx;
-#else
- r_sa.sin_addr.s_addr = inet_addr("128.127.50.1");
-#endif /* INADDRX */
- rc = connect(sock, (struct sockaddr *) &r_sa, sizeof(struct sockaddr));
- if (!rc) { /* get local address */
- getsockname(sock,(struct sockaddr *)&l_sa,&slen);
-#ifdef TCPIPLIB
- socket_close(sock); /* We're done with the socket */
-#else
- close(sock);
-#endif /* TCPIPLIB */
- if (l_sa.sin_addr.s_addr != INADDR_ANY) {
- myxipaddr = ntohl(l_sa.sin_addr.s_addr);
- ckstrncpy(myipaddr,(char *)inet_ntoa(l_sa.sin_addr),20);
- debug(F110,"getlocalipaddr setting buf to",myipaddr,0);
- return(0);
- }
- }
- }
- return getlocalipaddrs(myipaddr,sizeof(myipaddr),0);
-#else /* datageneral */
- return(-1);
-#endif /* datageneral */
-}
-
-int
-getlocalipaddrs(buf,bufsz,index)
- char * buf;
- int bufsz;
- int index;
-/* getlocalipaddrs */ {
-#ifndef datageneral
- char localhost[256];
- struct hostent * host=NULL;
- struct sockaddr_in l_sa;
- struct sockaddr_in r_sa;
- GSOCKNAME_T slen = sizeof(struct sockaddr_in);
- int rc;
-#ifdef COMMENT
- int sock;
- char messageBuf[60];
- struct in_addr laddr;
-#endif /* COMMENT */
-
- debug(F100,"getlocalipaddrs","",0);
- memset(&l_sa,0,slen);
- memset(&r_sa,0,slen);
-
- /* init local address (to zero) */
- l_sa.sin_addr.s_addr = INADDR_ANY;
-
-#ifdef CKGHNLHOST
- rc = gethostname(localhost, 256);
- debug(F110,"getlocalipaddrs localhost",localhost,0);
-#else
- /* This doesn't work on some platforms, e.g. Solaris */
- rc = 0;
- localhost[0] = '\0';
-#ifdef NT
- if ( winsock_version < 20 ) {
- rc = gethostname(localhost, 256);
- debug(F110,"getlocalipaddrs localhost",localhost,0);
- }
-#endif /* NT */
-#endif /* CKGHNLHOST */
- if (!rc) {
- /* resolve host name for local address */
- debug(F110,"getlocalipaddrs","calling gethostbyname()",0);
- host = gethostbyname(localhost);
- /* debug(F111,"getlocalipaddrs","gethostbyname() returned",host); */
- if (host) {
-#ifdef HADDRLIST
- host = ck_copyhostent(host);
- if ( index < 0 || index > 63 || !host->h_addr_list[index] ) {
- buf[0] = '\0';
- return(-1);
- }
- l_sa.sin_addr.s_addr =
- *((unsigned long *) (host->h_addr_list[index]));
- ckstrncpy(buf,(char *)inet_ntoa(l_sa.sin_addr),20);
- debug(F110,"getlocalipaddrs setting buf to",buf,0);
-
-#ifdef COMMENT
- /* This is for reporting multiple IP Address */
- while (host->h_addr_list && host->h_addr_list[0]) {
- l_sa.sin_addr.s_addr =
- *((unsigned long *) (host->h_addr_list[0]));
- ckstrncpy(messageBuf,
- (char *)inet_ntoa(l_sa.sin_addr),60);
- if (tcp_address) {
- if (!strcmp(messageBuf,tcp_address))
- ckstrncpy(myipaddr,tcp_address,20);
- }
- debug(F110,"getlocalipaddrs ip address list", messageBuf, 0);
- host->h_addr_list++;
- }
-#endif /* COMMENT */
-#else /* HADDRLIST */
- if (index != 0) {
- buf[0] = '\0';
- return(-1);
- }
- l_sa.sin_addr.s_addr = *((unsigned long *) (host->h_addr));
- ckstrncpy(buf,(char *)inet_ntoa(l_sa.sin_addr),bufsz);
- debug(F110,"getlocalipaddrs setting buf to",buf,0);
-#endif /* HADDRLIST */
- return(0);
- } else debug(F110,
- "getlocalipaddrs: gethostbyname() failed",
- localhost,
- 0
- );
- }
-#endif /* datageneral */
- return(-1);
-}
-
-#ifdef RLOGCODE /* TCP/IP RLOGIN protocol support code */
-int
-rlog_naws() {
- struct rlog_naws {
- unsigned char id[4];
- unsigned short rows, cols, ypix, xpix;
- } nawsbuf;
-
- if (ttnet != NET_TCPB)
- return 0;
- if (ttnproto != NP_RLOGIN
-#ifdef CK_KERBEROS
- && ttnproto != NP_K4LOGIN
- && ttnproto != NP_EK4LOGIN
- && ttnproto != NP_K5LOGIN
- && ttnproto != NP_EK5LOGIN
-#endif /* CK_KERBEROS */
- )
- return 0;
- if (!TELOPT_ME(TELOPT_NAWS))
- return 0;
-
- debug(F100,"rlogin Window Size sent","",0);
-
- nawsbuf.id[0] = nawsbuf.id[1] = 0377;
- nawsbuf.id[2] = nawsbuf.id[3] = 's';
-#ifdef OS2
- nawsbuf.rows = htons((unsigned short) (VscrnGetHeight(VTERM)
- -(tt_status[VTERM]?1:0)));
- nawsbuf.cols = htons((unsigned short) VscrnGetWidth(VTERM));
-#else /* OS2 */
- nawsbuf.rows = htons((unsigned short) tt_rows);
- nawsbuf.cols = htons((unsigned short) tt_cols);
-#endif /* OS2 */
- nawsbuf.ypix = htons(0); /* y pixels */
-
- nawsbuf.xpix = htons(0); /* x pixels */
- if (ttol((CHAR *)(&nawsbuf), sizeof(nawsbuf)) < 0)
- return(-1);
- return(0);
-}
-
-#ifdef OS2ORUNIX
-#define RLOGOUTBUF
-#endif /* OS2 */
-static int
-#ifdef CK_ANSIC
-rlog_ini(CHAR * hostname, int port,
- struct sockaddr_in * l_addr, struct sockaddr_in * r_addr)
-#else /* CK_ANSIC */
-rlog_ini(hostname, port, l_addr, r_addr)
- CHAR * hostname;
- int port;
- struct sockaddr_in * l_addr;
- struct sockaddr_in * r_addr;
-#endif /* CK_ANSIC */
-/* rlog_ini */ {
-
-#ifdef RLOGOUTBUF
- char outbuf[512];
- int outbytes=0;
-#endif /* RLOGOUTBUF */
- int flag = 0;
-#define TERMLEN 16
-#define CONSPDLEN 16
- CHAR localuser[UIDBUFLEN+1];
- CHAR remoteuser[UIDBUFLEN+1];
- int userlen = 0;
- CHAR term_speed[TERMLEN+CONSPDLEN+1];
-#ifdef CONGSPD
- long conspd = -1L;
-#endif /* CONGSPD */
-#ifdef OS2
- extern int tt_type, max_tt;
- extern struct tt_info_rec tt_info[];
-#endif /* OS2 */
- int i, n;
-
- int rc = 0;
- tn_reset(); /* This call will reset all of the Telnet */
- /* options and then quit. We need to do */
- /* this since we use the Telnet options */
- /* to hold various state information */
- duplex = 0; /* Rlogin is always remote echo */
- rlog_inband = 0;
-
-#ifdef CK_TTGWSIZ
-/*
- But compute the values anyway before the first read since the out-
- of-band NAWS request would arrive before the first data byte (NULL).
-*/
-#ifdef OS2
- /* Console terminal screen rows and columns */
- debug(F101,"rlog_ini tt_rows 1","",VscrnGetHeight(VTERM)
- -(tt_status[VTERM]?1:0));
- debug(F101,"rlog_ini tt_cols 1","",VscrnGetWidth(VTERM));
- /* Not known yet */
- if (VscrnGetWidth(VTERM) < 0 ||
- VscrnGetHeight(VTERM)-(tt_status[VTERM]?1:0) < 0) {
- ttgwsiz(); /* Try to get screen dimensions */
- }
- debug(F101,
- "rlog_ini tt_rows 2",
- "",
- VscrnGetHeight(VTERM)-(tt_status[VTERM]?1:0)
- );
- debug(F101,"rlog_ini tt_cols 2","",VscrnGetWidth(VTERM));
-#else /* OS2 */
- debug(F101,"rlog_ini tt_rows 1","",tt_rows);
- debug(F101,"rlog_ini tt_cols 1","",tt_cols);
- if (tt_rows < 0 || tt_cols < 0) { /* Not known yet */
- ttgwsiz(); /* Try to find out */
- }
- debug(F101,"rlog_ini tt_rows 2","",tt_rows);
- debug(F101,"rlog_ini tt_cols 2","",tt_cols);
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
- ttflui(); /* Start by flushing the buffers */
-
- rlog_mode = RL_COOKED;
-
- /* Determine the user's local username ... */
-
- localuser[0] = '\0';
-#ifdef NT
- {
- char localuid[UIDBUFLEN+1];
- ckstrncpy((char *)localuser,(char *)GetLocalUser(),UIDBUFLEN);
- }
-
- if ( !localuser[0] )
-#endif /* NT */
- {
- char * user = getenv("USER");
- if (!user)
- user = "";
- userlen = strlen(user);
- debug(F111,"rlogin getenv(USER)",user,userlen);
- ckstrncpy((char *)localuser,user,UIDBUFLEN);
- debug(F110,"rlog_ini localuser 1",localuser,0);
- }
- if ( !localuser[0] )
- strcpy((char *)localuser,"unknown");
- else if (ck_lcname) {
- cklower((char *)localuser);
- debug(F110,"rlog_ini localuser 2",localuser,0);
- }
-
- /* And the username to login with */
- if (uidbuf[0]) {
- ckstrncpy((char *)remoteuser,uidbuf,UIDBUFLEN);
- debug(F110,"rlog_ini remoteuser 1",remoteuser,0);
- } else if (localuser[0]) {
- ckstrncpy((char *)remoteuser,(char *)localuser,UIDBUFLEN);
- debug(F110,"rlog_ini remoteuser 2",remoteuser,0);
- } else {
- remoteuser[0] = '\0';
- debug(F110,"rlog_ini remoteuser 3",remoteuser,0);
- }
- if (ck_lcname)
- cklower((char *)remoteuser);
- debug(F110,"rlog_ini remoteuser 4",remoteuser,0);
-
- /* The command to issue is the terminal type and speed */
- term_speed[0] = '\0';
- if (tn_term) { /* SET TELNET TERMINAL-TYPE value */
- if (*tn_term) { /* (if any) takes precedence. */
- ckstrncpy((char *)term_speed, tn_term, TERMLEN);
- flag = 1;
- }
- } else { /* Otherwise the local terminal type */
-#ifdef OS2
- /* In terminal-emulating versions, it's the SET TERM TYPE value */
- ckstrncpy(term_speed, (tt_type >= 0 && tt_type <= max_tt) ?
- tt_info[tt_type].x_name : "network", TERMLEN);
-#else
- /* In the others, we just look at the TERM environment variable */
- {
- char *p = getenv("TERM");
- if (p)
- ckstrncpy((char *)term_speed,p,TERMLEN);
- else
- term_speed[0] = '\0';
-#ifdef VMS
- for (p = (char *) term_speed; *p; p++) {
- if (*p == '-' && (!strcmp(p,"-80") || !strcmp(p,"-132")))
- break;
- else if (isupper(*p))
- *p = tolower(*p);
- }
- *p = '\0';
-#endif /* VMS */
- }
-#endif /* OS2 */
- }
- n = strlen((char *)term_speed);
- if (n > 0) { /* We have a terminal type */
- if (!flag) { /* If not user-specified */
- for (i = 0; i < n; i++) /* then lowercase it. */
- if (isupper(term_speed[i]))
- term_speed[i] = tolower(term_speed[i]);
- }
- debug(F110,"rlog_ini term_speed 1",term_speed,0);
-
-#ifdef CONGSPD
- /* conspd() is not yet defined in all ck*tio.c modules */
- conspd = congspd();
- if (conspd > 0L) {
- ckstrncat((char *)term_speed,"/",sizeof(term_speed));
- ckstrncat((char *)term_speed,ckltoa(conspd),sizeof(term_speed));
- } else
-#endif /* CONGSPD */
- ckstrncat((char *)term_speed,"/19200",sizeof(term_speed));
- debug(F110,"rlog_ini term_speed 2",term_speed,0);
- } else {
- term_speed[0] = '\0';
- debug(F110,"rlog_ini term_speed 3",term_speed,0);
- }
-
-#ifdef CK_KERBEROS
- if (ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN ||
- ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN) {
- int kver, encrypt, rc;
- switch (ttnproto) {
- case NP_K4LOGIN:
- kver = 4;
- encrypt = 0;
- break;
- case NP_EK4LOGIN:
- kver = 4;
- encrypt = 1;
- break;
- case NP_K5LOGIN:
- kver = 5;
- encrypt = 0;
- break;
- case NP_EK5LOGIN:
- kver = 5;
- encrypt = 1;
- break;
- default:
- kver = 0;
- encrypt = 0;
- }
- rc = ck_krb_rlogin(hostname, port,
- localuser, remoteuser, term_speed,
- l_addr, r_addr, kver, encrypt);
- if (!rc) { /* success */
- TELOPT_ME(TELOPT_NAWS) = 1;
- rc = rlog_naws();
- }
- return(rc);
- } else
-#endif /* CK_KERBEROS */
- if (ttnproto == NP_RLOGIN) {
-#ifdef RLOGOUTBUF
- /*
- * The rcmds start the connection with a series of init data:
- *
- * a port number upon which client is listening for stderr data
- * the user's name on the client machine
- * the user's name on the server machine
- * the terminal_type/speed or command to execute
- */
- outbuf[outbytes++] = 0;
- strcpy((char *)outbuf+outbytes,(char *)localuser);
- outbytes += strlen((char *)localuser) + 1;
- strcpy((char *)outbuf+outbytes,(char *)remoteuser);
- outbytes += strlen((char *)remoteuser) + 1;
- strcpy((char *)outbuf+outbytes,(char *)term_speed);
- outbytes += strlen((char *)term_speed) + 1;
- rc = ttol((CHAR *)outbuf,outbytes);
-#else /* RLOGOUTBUF */
- ttoc(0); /* Send an initial NUL as wake-up */
- /* Send each variable with the trailing NUL */
- rc = ttol(localuser,strlen((char *)localuser)+1);
- if (rc > 0)
- rc = ttol(remoteuser,strlen((char *)remoteuser)+1);
- if (rc > 0)
- rc = ttol(term_speed,strlen((char *)term_speed)+1);
-#endif /* RLOGOUTBUF */
-
- /* Now we are supposed to get back a single NUL as confirmation */
- errno = 0;
- rc = ttinc(60);
- debug(F101,"rlogin first ttinc","",rc);
- if (rc > 0) {
- debug(F101,"rlogin ttinc 1","",rc);
- printf(
- "Rlogin protocol error - 0x%x received instead of 0x00\n", rc);
- return(-1);
- } else if (rc < 0) {
- debug(F101,"rlogin ttinc errno","",errno);
- /* printf("Network error: %d\n", errno); */
- return(-1);
- }
- }
- return(0);
-}
-
-/* two control messages are defined:
-
- a double flag byte of 'o' indicates a one-byte message which is
- identical to what was once carried out of band.
-
- a double flag byte of 'q' indicates a zero-byte message. This
- message is interpreted as two \377 data bytes. This is just a
- quote rule so that binary data from the server does not confuse the
- client. */
-
-int
-rlog_ctrl(cp, n)
- unsigned char *cp;
- int n;
-{
- if ((n >= 5) && (cp[2] == 'o') && (cp[3] == 'o')) {
- if (rlog_oob(&cp[4],1))
- return(-5);
- return(5);
- } else if ((n >= 4) && (cp[2] == 'q') && (cp[3] == 'q')) {
- /* this is somewhat of a hack */
- cp[2] = '\377';
- cp[3] = '\377';
- return(2);
- }
- return(0);
-}
-
-static int
-rlog_oob(oobdata, count) CHAR * oobdata; int count; {
- int i;
- int flush = 0;
-
- debug(F111,"rlogin out_of_band","count",count);
-
- for (i = 0; i<count; i++) {
- debug(F101,"rlogin out_of_band","",oobdata[i]);
- if (oobdata[i] & 0x01)
- continue;
-
- if (oobdata[i] & 0x02) { /* Flush Buffered Data not yet displayed */
- debug(F101,"rlogin Flush Buffered Data command","",oobdata[i]);
-
- /* Only flush the data if in fact we are in a mode that won't */
- /* get out of sync. Ie, not when we are in protocol mode. */
- switch ( what ) {
- case W_NOTHING:
- case W_CONNECT:
- case W_COMMAND:
- if ( rlog_inband )
- flush = 1;
- else
- ttflui();
- break;
- }
- }
- if (oobdata[i] & 0x10) { /* Switch to RAW mode */
- debug(F101,"rlogin Raw Mode command","",oobdata[i]);
- rlog_mode = RL_RAW;
- }
-
- if (oobdata[i] & 0x20) { /* Switch to COOKED mode */
- debug(F101,"rlogin Cooked Mode command","",oobdata[i]);
- rlog_mode = RL_COOKED;
- }
- if (oobdata[i] & 0x80)
- { /* Send Window Size Info */
- debug(F101,"rlogin Window Size command","",oobdata[i]);
- /* Remember to send WS Info when Window Size changes */
- if ( !TELOPT_ME(TELOPT_NAWS) ) {
- TELOPT_ME(TELOPT_NAWS) = 1;
- rlog_naws();
- }
- }
- }
- return(flush);
-}
-#ifndef TCPIPLIB
-static SIGTYP
-rlogoobh(sig) int sig; {
-#ifdef SOLARIS
- char /* Or should it be char for all? */
-#else
- CHAR
-#endif /* SOLARIS */
- oobdata;
-
- /* int count = 0; */ /* (not used) */
-
- while (recv(ttyfd, &oobdata, 1, MSG_OOB) < 0) {
- /*
- * We need to do some special processing here.
- * Just in case the socket is blocked for input
- *
- */
- switch (errno) {
- case EWOULDBLOCK:
- break;
- default:
- return;
- }
- }
- debug(F101,"rlogin out_of_band","",oobdata);
- if (oobdata == 0x02) { /* Flush Buffered Data not yet displayed */
- debug(F101,"rlogin Flush Buffered Data command","",oobdata);
- netflui();
- }
- if (oobdata & 0x10) { /* Switch to raw mode */
- debug(F101,"rlogin Raw Mode command","",oobdata);
- rlog_mode = RL_RAW;
- }
- if (oobdata & 0x20) { /* Switch to cooked mode */
- debug(F101,"rlogin Cooked Mode command","",oobdata);
- rlog_mode = RL_COOKED;
- }
- if (oobdata & 0x80) { /* Send Window Size Info */
- debug(F101,"rlogin Window Size command","",oobdata);
- /* Remember to send WS Info when Window Size changes */
- if ( !TELOPT_ME(TELOPT_NAWS) ) {
- TELOPT_ME(TELOPT_NAWS) = 1;
- rlog_naws();
- }
- }
-}
-#endif /* TCPIPLIB */
-#endif /* RLOGCODE */
-
-/* Send network BREAK */
-/*
- Returns -1 on error, 0 if nothing happens, 1 if BREAK sent successfully.
-*/
-int
-netbreak() {
- CHAR buf[3];
- if (ttnet == NET_TCPB) {
- if (ttnproto == NP_TELNET) {
-#ifdef TNCODE
- buf[0] = (CHAR) IAC; buf[1] = (CHAR) BREAK; buf[2] = (CHAR) 0;
- if (
-#ifdef OS2
- nettol((char *) buf, 2)
-#else
- ttol(buf, 2)
-#endif /* OS2 */
- < 2)
- return(-1);
- if (tn_deb || debses || deblog) {
- extern char tn_msg[];
- ckmakmsg(tn_msg,TN_MSG_LEN,"TELNET SENT ",TELCMD(BREAK),
- NULL,NULL);
- debug(F101,tn_msg,"",BREAK);
- if (debses || tn_deb) tn_debug(tn_msg);
- }
- return(1);
-#else
- debug(F100,"netbreak no TNCODE","",0);
- return(0);
-#endif /* TNCODE */
- }
- /* Insert other TCP/IP protocols here */
- }
- /* Insert other networks here */
- return(0);
-}
-#endif /* NETCONN */
-
-
-#ifdef NETCONN
-#ifdef SUNX25
-/*
- SunLink X.25 support by Marcello Frutig, Catholic University,
- Rio de Janeiro, Brazil, 1990.
-*/
-
-/* PAD X.3, X.28 and X.29 support */
-
-static CHAR x29err[MAXPADPARMS+3] = { X29_ERROR, INVALID_PAD_PARM, '\0' };
-
-/* Initialize PAD */
-
-extern CHAR padparms[];
-
-VOID
-initpad() {
- padparms[PAD_BREAK_CHARACTER] = 0; /* Break character */
- padparms[PAD_ESCAPE] = 1; /* Escape permitted */
- padparms[PAD_ECHO] = 1; /* Kermit PAD does echo */
- padparms[PAD_DATA_FORWARD_CHAR] = 2; /* forward character CR */
- padparms[PAD_DATA_FORWARD_TIMEOUT] = 0; /* no timeout forward condition */
- padparms[PAD_FLOW_CONTROL_BY_PAD] = 0; /* not used */
- padparms[PAD_SUPPRESSION_OF_SIGNALS] = 1; /* allow PAD service signals */
- padparms[PAD_BREAK_ACTION] = 21; /* brk action: INT pk + brk ind*/
- padparms[PAD_SUPPRESSION_OF_DATA] = 0; /* no supression of user data */
- padparms[PAD_PADDING_AFTER_CR] = 0; /* no padding after CR */
- padparms[PAD_LINE_FOLDING] = 0; /* no line fold */
- padparms[PAD_LINE_SPEED] = 0; /* line speed - don't care */
- padparms[PAD_FLOW_CONTROL_BY_USER] = 0; /* flow cont of PAD - not used */
- padparms[PAD_LF_AFTER_CR] = 0; /* no LF insertion after CR */
- padparms[PAD_PADDING_AFTER_LF] = 0; /* no padding after LF */
- padparms[PAD_EDITING] = 1; /* can edit */
- padparms[PAD_CHAR_DELETE_CHAR] = 8; /* character delete character */
- padparms[PAD_BUFFER_DELETE_CHAR] = 21; /* buffer delete character */
- padparms[PAD_BUFFER_DISPLAY_CHAR] = 18; /* buffer display character */
-}
-
-/* Set PAD parameters */
-
-VOID
-setpad(s,n) CHAR *s; int n; {
- int i;
- CHAR *ps = s;
-
- if (n < 1) {
- initpad();
- } else {
- for (i = 0; i < n; i++) {
- if (*ps > MAXPADPARMS)
- x29err[i+2] = *ps;
- else
- padparms[*ps] = *(ps+1);
- ps += 2;
- }
- }
-}
-
-/* Read PAD parameters */
-
-VOID
-readpad(s,n,r) CHAR *s; int n; CHAR *r; {
- int i;
- CHAR *ps = s;
- CHAR *pr = r;
-
- *pr++ = X29_PARAMETER_INDICATION;
- if (n > 0) {
- for (i = 0; i < n; i++, ps++) {
- if (*ps > MAXPADPARMS) {
- x29err[i+2] = *ps++;
- } else {
- *pr++ = *ps;
- *pr++ = padparms[*ps++];
- }
- }
- } else {
- for (i = 1; i < MAXPADPARMS; i++) {
- *pr++ = i;
- *pr++ = padparms[i];
- }
- }
-}
-
-int
-qbitpkt(s,n) CHAR *s; int n; {
- CHAR *ps = s;
- int x29cmd = *ps;
- CHAR *psa = s+1;
- CHAR x29resp[(MAXPADPARMS*2)+1];
-
- switch (x29cmd) {
-
- case X29_SET_PARMS:
- setpad (ps+1,n/2);
- if ((int)strlen((char *)x29err) > 2) {
- ttol(x29err,(int)strlen((char *)x29err));
- x29err[2] = '\0';
- }
- return (-2);
- case X29_READ_PARMS:
- readpad (ps+1,n/2,x29resp);
- setqbit ();
- ttol(x29resp,(n>1)?(n+1):(2*MAXPADPARMS+1));
- if ((int)strlen((char *)x29err) > 2) {
- ttol(x29err,(int)strlen((char *)x29err));
- x29err[2] = '\0';
- }
- resetqbit();
- break;
- case X29_SET_AND_READ_PARMS:
- setpad (ps+1,n/2);
- readpad (ps+1,n/2,x29resp);
- setqbit();
- ttol(x29resp,(n>1)?(n+1):(2*MAXPADPARMS+1));
- if ((int)strlen((char *)x29err) > 2) {
- ttol (x29err,(int)strlen((char *)x29err));
- x29err [2] = '\0';
- }
- resetqbit();
- return (-2);
- case X29_INVITATION_TO_CLEAR:
- (VOID) x25clear();
- return (-1);
- case X29_INDICATION_OF_BREAK:
- break;
- }
- return (0);
-}
-
-/* PAD break action processor */
-
-VOID
-breakact() {
- extern char x25obuf[MAXOX25];
- extern int obufl;
- extern int active;
- extern unsigned char tosend;
- static CHAR indbrk[3] = {
- X29_INDICATION_OF_BREAK,
- PAD_SUPPRESSION_OF_DATA,
- 1
- };
- CHAR intudat, cause, diag;
-
- if (x25stat() < 0) return; /* Ignore if no virtual call established */
-
- if (padparms[PAD_BREAK_ACTION] != 0) /* Forward condition */
- if (ttol((CHAR *)x25obuf,obufl) < 0) {
- perror ("\r\nCan't send characters");
- active = 0;
- } else {
- bzero (x25obuf,sizeof(x25obuf));
- obufl = 0;
- tosend = 0;
- };
-
- switch (padparms[PAD_BREAK_ACTION]) {
-
- case 0 : break; /* do nothing */
- case 1 : /* send interrupt packet with interrupt user data field = 1 */
- intudat = 1;
- x25intr (intudat);
- break;
- case 2 : /* send reset packet with cause and diag = 0 */
- cause = diag = 0;
- x25reset (cause,diag);
- break;
- case 5 : /* send interrupt packet with interrupt user data field = 0 */
- intudat = 0;
- x25intr (intudat);
- setqbit ();
- /* send indication of break without a parameter field */
- ttoc(X29_INDICATION_OF_BREAK);
- resetqbit ();
- break;
- case 8 : active = 0; /* leave data transfer */
- conol ("\r\n");
- break;
- case 21: /* send interrupt packet with interrupt user data field = 0 */
- intudat = 0;
- x25intr (intudat);
- setpad (indbrk+1,2); /* set pad to discard input */
- setqbit ();
- /* send indication of break with parameter field */
- ttol (indbrk,sizeof(indbrk));
- resetqbit ();
- break;
- }
-}
-
-/* X.25 support functions */
-
-X25_CAUSE_DIAG diag;
-
-/*
- Convert a null-terminated string representing an X.121 address
- to a packed BCD form.
-*/
-int
-pkx121(str,bcd) char *str; CHAR *bcd; {
- int i, j;
- u_char c;
-
- i = j = 0;
- while (str[i]) {
- if (i >= 15 || str [i] < '0' || str [i] > '9')
- return (-1);
- c = str [i] - '0';
- if (i & 1)
- bcd [j++] |= c;
- else
- bcd [j] = c << 4;
- i++;
- }
- return (i);
-}
-
-/* Reads and prints X.25 diagnostic */
-
-int
-x25diag () {
- int i;
-
- bzero ((char *)&diag,sizeof(diag));
- if (ioctl(ttyfd,X25_RD_CAUSE_DIAG,&diag)) {
- perror ("Reading X.25 diagnostic");
- return(-1);
- }
- if (diag.datalen > 0) {
- printf ("X.25 Diagnostic :");
- for (i = 0; i < (int)diag.datalen; i++)
- printf(" %02h",diag.data[i])+
- printf ("\r\n");
- }
- return(0);
-}
-
-/* X.25 Out-of-Band Signal Handler */
-
-SIGTYP
-x25oobh(foo) int foo; {
- int oobtype;
- u_char oobdata;
- int t;
-
- (VOID) signal(SIGURG,x25oobh);
- do {
- if (ioctl(ttyfd,X25_OOB_TYPE,&oobtype)) {
- perror ("Getting signal type");
- return;
- }
- switch (oobtype) {
- case INT_DATA:
- if (recv(ttyfd,(char *)&oobdata,1,MSG_OOB) < 0) {
- perror ("Receiving X.25 interrupt data");
- return;
- }
- t = oobdata;
- printf ("\r\nInterrupt received, data = %d\r\n", t);
- break;
- case VC_RESET:
- printf ("\r\nVirtual circuit reset\r\n");
- x25diag ();
- break;
- case N_RESETS:
- printf ("\r\nReset timeout\r\n");
- break;
- case N_CLEARS:
- printf ("\r\nClear timeout\r\n");
- break;
- case MSG_TOO_LONG:
- printf ("\r\nMessage discarded, too long\r\n");
- break;
- default:
- if (oobtype) printf("\r\nUnknown oob type %d\r\n",oobtype);
- break;
- }
- } while (oobtype);
-}
-
-/* Send a X.25 interrupt packet */
-
-int
-#ifdef CK_ANSIC
-x25intr(char intr)
-#else
-x25intr(intr) char intr;
-#endif /* CK_ANSIC */
-/* x25intr */ {
- if (send(ttyfd,&intr,1,MSG_OOB) < 0) return(-1);
- debug(F100,"X.25 intr","",0);
- return(0);
-}
-
-/* Reset X.25 virtual circuit */
-int
-#ifdef CK_ANSIC
-x25reset(char cause, char diagn)
-#else
-x25reset(cause, diagn) char cause; char diagn;
-#endif /* CK_ANSIC */
-/* x25reset */ {
- bzero ((char *)&diag,sizeof(diag));
- diag.flags = 0;
- diag.datalen = 2;
- diag.data[0] = cause;
- diag.data[1] = diagn;
- if (ioctl(ttyfd,X25_WR_CAUSE_DIAG,&diag) < 0)
- return(-1);
- debug(F100,"X.25 reset","",0);
- return(0);
-}
-
-/* Clear X.25 virtual circuit */
-int
-x25clear() {
- int i;
- debug(F100,"X.25 clear","",0);
- bzero ((char *)&diag,sizeof(diag));
- diag.flags = (1 << DIAG_TYPE);
- diag.datalen = 2;
- diag.data[0] = 0;
- diag.data[1] = 0;
- ioctl (ttyfd,X25_WR_CAUSE_DIAG,&diag); /* Send Clear Request */
- return(ttclos(0)); /* Close socket */
-}
-
-/* X.25 status */
-int
-x25stat() {
- if (ttyfd == -1) return (-1);
- return(0);
-}
-
-/* Set Q_BIT on */
-VOID
-setqbit() {
- static int qbiton = 1 << Q_BIT;
- ioctl (ttyfd,X25_SEND_TYPE,&qbiton);
-}
-
-/* Set Q_BIT off */
-VOID
-resetqbit() {
- static int qbitoff = 0;
- ioctl (ttyfd,X25_SEND_TYPE,&qbitoff);
-}
-
-/* Read n characters from X.25 circuit into buf */
-
-int
-x25xin(n,buf) int n; CHAR *buf; {
- register int x, c;
- int qpkt;
-
- do {
- x = read(ttyfd,buf,n);
- if (buf[0] & (1 << Q_BIT)) { /* If Q_BIT packet, process it */
- /* If return -1 : invitation to clear; -2 : PAD changes */
- if ((c=qbitpkt(buf+1,x-2)) < 0) return(c);
- qpkt = 1;
- } else qpkt = 0;
- } while (qpkt);
-
-#ifdef COMMENT /* Disabled by Stephen Riehm 19.12.97 */
- /* BUG!
- * if buf[] is full, then this null lands in nirvana!
- * I was unable to find any code which needs a trailing null in buf[]
- */
- if (x > 0) buf[x] = '\0';
-#endif /* COMMENT */
- if (x < 1) x = -1;
- debug(F101,"x25xin x","",x);
-
- return(x);
-}
-
-#ifdef COMMENT /* NO LONGER NEEDED! */
-/* X.25 read a line */
-
-int
-#ifdef PARSENSE
-#ifdef CK_ANSIC
-x25inl(CHAR *dest, int max,int timo, CHAR eol, CHAR start)
-#else
-x25inl(dest,max,timo,eol,start) int max,timo; CHAR *dest, eol, start;
-#endif /* CK_ANSIC */
-#else /* not PARSENSE */
-#ifdef CK_ANSIC
-x25inl(CHAR *dest, int max,int timo, CHAR eol)
-#else
-x25inl(dest,max,timo,eol) int max,timo; CHAR *dest, eol;
-#endif /* __SDTC__ */
-#endif /*PARSENSE */
- /* x25inl */ {
- CHAR *pdest;
- int pktype, goteol, rest, n;
- int i, flag = 0;
- extern int ttprty, ttpflg;
- int ttpmsk;
-
- ttpmsk = (ttprty) ? 0177 : 0377; /* Set parity stripping mask */
-
- debug(F101,"x25inl max","",max);
- debug(F101,"x25inl eol","",eol);
- pdest = dest;
- rest = max;
- goteol = 0;
- do {
- n = read(ttyfd,pdest,rest);
- n--;
- pktype = *pdest & 0x7f;
- switch (pktype) {
- case 1 << Q_BIT:
- if (qbitpkt(pdest+1,--n) < 0) return(-2);
- break;
- default:
- if (flag == 0) { /* if not in packet, search start */
- for (i = 1; (i < n) &&
- !(flag = ((dest[i] & 0x7f) == start));
- i++);
- if (flag == 0) { /* not found, discard junk */
- debug(F101,"x25inl skipping","",n);
- continue;
- } else { /* found, discard junk before start */
- int k;
- n = n - i + 1;
- for (k = 1; k <= n; k++, i++) dest[k] = dest[i];
- }
- }
- for (i = 0; (i < n) && /* search for eol */
- !(goteol=(((*pdest = *(pdest+1)&ttpmsk)&0x7f)== eol));
- i++,pdest++);
- *pdest = '\0';
- rest -= n;
- }
- } while ((rest > 0) && (!goteol));
-
- if (goteol) {
- n = max - rest;
- debug (F111,"x25inl X.25 got",(char *) dest,n);
- if (timo) ttimoff();
- if (ttpflg++ == 0 && ttprty == 0) {
- if ((ttprty = parchk(dest,start,n)) > 0) {
- int j;
- debug(F101,"x25inl senses parity","",ttprty);
- debug(F110,"x25inl packet before",(char *)dest,0);
- ttpmsk = 0x7f;
- for (j = 0; j < n; j++)
- dest[j] &= 0x7f; /* Strip parity from packet */
- debug(F110,"x25inl packet after ",dest,0);
- } else {
- debug(F101,"parchk","",ttprty);
- if (ttprty < 0) { ttprty = 0; n = -1; }
- }
- }
- ttimoff();
- return(n);
- }
- ttimoff();
- return(-1);
-}
-#endif /* COMMENT */
-#endif /* SUNX25 */
-
-#ifdef IBMX25
-/*
- * IBM X25 support - using the NPI streams interface
- * written by Stephen Riehm, pc-plus, Munich Germany
- */
-
-/* riehm: missing functions / TODO list */
-
-/*
- x25intr() - Send an interrupt packet
-*/
-
-/* return an error message depending on packet type */
-char *
-x25err(n) int n; {
- static char buf[30];
- switch (n) {
- case NBADADDR: return "invalid address";
- case NBADOPT: return "invalid options";
- case NACCESS: return "no permission";
- case NNOADDR: return "unable to allocate address";
- case NOUTSTATE: return "invalid state";
- case NBADSEQ: return "invalid sequence number";
- case NSYSERR: return "system error";
- case NBADDATA: return "invalid data size";
- case NBADFLAG: return "invalid flag";
- case NNOTSUPPORT: return "unsupported primitive";
- case NBOUND: return "address in use";
- case NBADQOSPARAM: return "bad QOS parameters";
- case NBADQOSTYPE: return "bad QOS type";
- case NBADTOKEN: return "bad token value";
- case NNOPROTOID: return "protocol id could not be allocated";
- case NODDCUD: return "odd length call user data";
- default:
- ckmakmsg(buf,sizeof(buf),"Unknown NPI error ",ckitoa(n),NULL,NULL);
- return buf;
- }
-}
-
-/* turn a meaningless primitive number into a meaningful primitive name */
-char *
-x25prim(n) int n; {
- static char buf[30];
- switch(n) {
- case N_BIND_ACK: return "N_BIND_ACK";
- case N_BIND_REQ: return "N_BIND_REQ";
- case N_CONN_CON: return "N_CONN_CON";
- case N_CONN_IND: return "N_CONN_IND";
- case N_CONN_REQ: return "N_CONN_REQ";
- case N_CONN_RES: return "N_CONN_RES";
- case N_DATACK_IND: return "N_DATAACK_IND";
- case N_DATACK_REQ: return "N_DATAACK_REQ";
- case N_DATA_IND: return "N_DATA_IND";
- case N_DATA_REQ: return "N_DATA_REQ";
- case N_DISCON_IND: return "N_DISCON_IND";
- case N_DISCON_REQ: return "N_DISCON_REQ";
- case N_ERROR_ACK: return "N_ERROR_ACK";
- case N_EXDATA_IND: return "N_EXDATA_IND";
- case N_EXDATA_REQ: return "N_EXDATA_REQ";
- case N_INFO_ACK: return "N_INFO_ACK";
- case N_INFO_REQ: return "N_INFO_REQ";
- case N_OK_ACK: return "N_OK_ACK";
- case N_OPTMGMT_REQ: return "N_OPTMGMT_REQ";
- case N_RESET_CON: return "N_RESET_CON";
- case N_RESET_IND: return "N_RESET_IND";
- case N_RESET_REQ: return "N_RESET_REQ";
- case N_RESET_RES: return "N_RESET_RES";
- case N_UDERROR_IND: return "N_UDERROR_IND";
- case N_UNBIND_REQ: return "N_UNBIND_REQ";
- case N_UNITDATA_REQ: return "N_UNITDATA_REQ";
- case N_UNITDATA_IND: return "N_UNITDATA_IND";
- default:
- ckmakmsg(buf,sizeof(buf),"UNKNOWN (",ckitoa(n),")",NULL);
- return buf;
- }
-}
-
-/*****************************************************************************
- * Function: x25getmsg()
- * Description: get a STREAMS message, and check it for errors
- *
- * Parameters:
- * fd - file descriptor to x25 device (opened)
- * control - control buffer (pre-allocated)
- * ctl_size - size of control buffer
- * data - data buffer (pre-allocated)
- * data_size - size of data buffer
- * flags - flags for getmsg()
- * expected - expected Primitive type
- *
- * Return Value:
- * >= 0 OK (size of data returned)
- * -1 error
- *
- */
-int
-x25getmsg( fd, control, ctl_size, data, data_size, get_flags, expected )
- int fd; /* X25 device (opened) */
- N_npi_ctl_t *control; /* control buffer (pre-allocated) */
- int ctl_size; /* size of control buffer */
- N_npi_data_t *data; /* data buffer (pre-allocated) */
- int data_size; /* size of data buffer */
- int *get_flags; /* getmsg() flags */
- int expected; /* expected primitive type */
-/* x25getmsg */ {
- int rc = 0; /* return code */
- struct strbuf *get_ctl=NULL; /* getmsg control */
- struct strbuf *get_data=NULL; /* getmsg data */
- int more = 0; /* flag for more data etc */
- int file_status = -1; /* file async status */
- N_npi_ctl_t * result; /* pointer to simplify switch() */
- int packet_type = -1; /* unknown packet thus far */
-
-#ifdef TRACE
- printf( "TRACE: entering x25getmsg\n" );
-#endif /* TRACE */
-
- debug( F110, "x25getmsg waiting for packet ", x25prim( expected ), 0);
- /* prepare the control structures for getmsg */
- if (control) {
- if ((get_ctl = (struct strbuf*)malloc(sizeof(struct strbuf))) == NULL)
- {
- perror("kermit x25getmsg(): get_ctl malloc failed\n");
- debug( F100, "x25getmsg malloc failed for get_ctl\n", "", 0);
- return(-1);
- }
- /* allow getmsg to return an unexpected packet type (which may be
- * larger than the expected one)
- */
- get_ctl->maxlen = NPI_MAX_CTL;
- get_ctl->len = 0;
- get_ctl->buf = (char *)control;
- } else {
- printf(
- "kermit x25getmsg(): internal error. control buffer MUST be pre-allocated!\n"
- );
- debug(F100,"x25getmsg internal error. no buffer pre-allocated","",0);
- return( -1 );
- }
- if (data) {
- if ((get_data = (struct strbuf*)malloc(sizeof(struct strbuf))) == NULL)
- {
- perror("kermit x25getmsg(): get_data malloc failed\n");
- debug( F100, "x25getmsg malloc failed for get_data\n", "", 0);
- return(-1);
- }
- get_data->maxlen = (NPI_MAX_DATA < data_size ) ?
- NPI_MAX_DATA :
- data_size;
- get_data->len = 0;
- get_data->buf = (char *)data;
- }
-
- /* get an X.25 packet -
- * it may be any kind of packet, so check for special cases
- * it may be split into multiple parts - so loop if necessary
- */
- do {
-#ifdef DEBUG
- printf( "kermit: x25getmsg(): getting a message\n" );
-#endif /* DEBUG */
- errno = 0;
- if ((more = getmsg(fd, get_ctl, get_data, get_flags)) < 0) {
-#ifdef DEBUG
- printf( "kermit: x25getmsg(): getmsg returned an error\n" );
- perror( "getmsg error was" );
-#endif /* DEBUG */
- debug(F101, "x25getmsg getmsg returned an error\n", "", errno);
- if ((errno == EAGAIN) && (get_data && (get_data->len > 0)) ) {
- /* was in non-blocking mode, nothing to get, but we're
- * already waiting for the rest of the packet -
- * switch to blocking mode for the next read.
- * file_status used to reset file status before returning
- */
- if ((file_status = fcntl(fd, F_GETFL, 0)) < 0
- || fcntl(fd, F_SETFL, file_status & ~O_NDELAY) < 0)
- {
- perror("x25getmsg(): couldn't change x25 blocking mode");
- debug(F101,
- "x25getmsg fcntl returned an error\n", "", errno);
- /* netclos(); */
- rc = -1;
- break;
- } else {
- /* loop again into a blocking getmsg() */
- continue;
- }
- } else {
- /* no data to get in non-blocking mode - return empty handed */
- perror( "x25getmsg(): getmsg failed" );
- debug(F101,"x25getmsg getmsg returned an error\n", "", errno);
- rc = -1;
- break;
- }
- } else if (more & MORECTL) {
- /* panic - the control information was larger than the
- * maximum control buffer size!
- */
- /* riehm: close connection? */
-#ifdef DEBUG
- printf("x25getmsg(): received partial control packet - panic\n");
-#endif /* DEBUG */
- debug( F101, "x25getmsg getmsg bad control block\n", "", errno);
- rc = -1;
- break;
- }
-
- if (result = (N_npi_ctl_t *)control) {
- packet_type = result->bind_ack.PRIM_type;
- if (packet_type != N_OK_ACK) {
- x25lastmsg = packet_type;
- }
- }
-#ifdef DEBUG
- /* printf( "kermit: x25getmsg(): getting " ); */
- if (get_ctl->len > 0) {
- x25dump_prim(result);
- }
- debug(F110,
- "x25getmsg got packet ",
- x25prim( result->bind_ack.PRIM_type ),
- 0
- );
-#endif /* DEBUG */
-
- if (get_ctl->len >= (int)sizeof(result->bind_ack.PRIM_type)) {
- /* not as pretty as a switch(), but switch can't handle
- * runtime variable values :-(
- */
- if (packet_type == expected ) {
- /* got what we wanted, special case for DATA_IND
- * packets though */
- /* riehm: check Q-bit ? */
-#ifdef DEBUG
- printf("x25getmsg(): got expected packet\nrc is %d\n", rc);
-#endif /* DEBUG */
- if (packet_type == N_DATA_IND ) {
- /* data received. May be incomplete, even though
- * getmsg returned OK
- */
- if (result->data_ind.DATA_xfer_flags & N_MORE_DATA_FLAG)
- more |= MOREDATA;
- if (result->data_ind.DATA_xfer_flags & N_RC_FLAG)
- printf( "x25getmsg(): data packet wants ack\n" );
- }
- } else if( packet_type == N_DISCON_IND) {
- printf( "X25 diconnected\n" );
- /* riehm: need to acknowledge a disconnection? */
- x25clear();
- /* x25unbind( ttyfd ); */
- rc = -1;
- } else if( packet_type == N_ERROR_ACK) {
- errno = result->error_ack.UNIX_error;
- perror( "X25 error received" );
- rc = -1;
- } else {
- printf("x25getmsg(): failed %s\n", x25err(packet_type));
- rc = -1;
- }
- }
-#ifdef COMMENT
- else {
- /* Panic - no control data */
- printf( "kermit: x25getmsg(): no control data with packet\n" );
- rc = -1;
- }
-#endif /* COMMENT */
-
- if (get_data && (get_data->len >= 0)) {
- get_data->buf += get_data->len;
- get_data->maxlen -= get_data->len;
- }
- } while ((rc == 0)
- && (get_data && (get_data->maxlen > 0))
- && (more & MOREDATA)
- );
-
- /* return the file status to its original value, unless its still
- * set to -1, or one of the fcntl's failed */
- if ((file_status >= 0) && fcntl(fd, F_SETFL, file_status) < 0)
- rc = -1;
-
- /*
- * Verify that we received an expected primitive
- * there is apparantly an error case where the primitive is set
- * correctly, but there is not enough data in the control structure
- */
- if ((packet_type != expected) && (get_ctl->len >= ctl_size) ) {
- fprintf(stderr,
- "x25getmsg(): %s NOT received. Primitive received was %s\n",
- x25prim( expected ), x25prim( packet_type ));
- debug(F110, "x25getmsg got an unexpected packet ",
- x25prim(packet_type),
- 0
- );
- rc = -1;
- }
-
- if (rc == 0) {
- if (get_data && ( get_data->len >= 0)) {
- rc = get_data->len;
- }
- }
-
- if (get_ctl) { free(get_ctl); get_ctl = NULL; }
- if (get_data) { free(get_data); get_data = NULL; }
-
-#ifdef COMMENT
-#ifdef DEBUG
- printf( "kermit x25getmsg(): returning %d\n", rc );
-#endif /* DEBUG */
-#endif /* COMMENT */
- debug(F110, "x25getmsg returning packet ", x25prim( packet_type ), 0);
-
-#ifdef TRACE
- printf( "TRACE: leaving x25getmsg\n" );
-#endif /* TRACE */
- return(rc);
-}
-
-/*****************************************************************************
- * Function: x25putmsg()
- *
- * Description:
- * send a message to a X25 STREAM
- *
- * Parameters:
- * fd - file descriptor to x25 device (opened)
- * control - control buffer (pre-allocated)
- * data - data buffer (pre-allocated)
- * data_len - length of data to be transmitted
- * put_flags - flags for putmsg()
- *
- * Return Value:
- * >= 0 number of bytes transmitted
- * -1 error
- */
-int
-x25putmsg(fd, control, data, data_len, put_flags)
- int fd; /* X25 device (opened) */
- N_npi_ctl_t *control; /* control buffer (pre-allocated) */
- N_npi_data_t *data; /* data buffer (pre-allocated) */
- int data_len; /* length of data (not the size of
- the buffer) */
- int *put_flags; /* putmsg() flags */
-/* x25putmsg */ {
- int rc = 0; /* return code */
- ulong type; /* primitive type */
- struct strbuf *put_ctl = NULL; /* putmsg control */
- struct strbuf *put_data = NULL; /* putmsg data */
-
-#ifdef TRACE
- printf( "TRACE: entering x25putmsg\n" );
-#endif /* TRACE */
-
-#ifdef DEBUG
- printf( "kermit: x25putmsg(): putting " );
- x25dump_prim( control );
- printf( "\tdata:\t\t" );
- x25dump_data( data, 0, data_len );
- debug(F110,"x25putmsg: putting packet ",x25prim(control->PRIM_type),0);
-#endif /* DEBUG */
-
- if (control) {
- put_ctl = (struct strbuf *)malloc( sizeof( struct strbuf ) );
- if (put_ctl == NULL) {
- perror("kermit x25putmsg(): put_ctl malloc failed\n");
- return(-1);
- }
- put_ctl->maxlen = 0; /* unused by putmsg */
- put_ctl->len = NPI_MAX_CTL;
- put_ctl->buf = (char *)control;
- }
- if (data && ( data_len > 0)) {
- put_data = (struct strbuf *)malloc( sizeof( struct strbuf ) );
- if( put_data == NULL) {
- perror("kermit x25putmsg(): put_data malloc failed\n");
- return(-1);
- }
- put_data->maxlen = 0; /* unused by putmsg */
- put_data->len = data_len;
- put_data->buf = (char *)data;
- }
-
- errno = 0;
- rc = putmsg (fd, put_ctl, put_data, 0);
- if (rc < 0) {
- printf("x25putmsg(): couldn't put %s\n",x25prim(control->PRIM_type));
- perror("kermit: x25putmsg(): putmsg failed");
- return(-1);
- }
-
- /* riehm: this should perhaps be discounted! */
- x25lastmsg = control->PRIM_type;
-
-#ifdef COMMENT
-#ifdef DEBUG
- printf( "kermit debug: x25putmsg() returning %d\n", data_len );
-#endif /* DEBUG */
-#endif /* COMMENT */
- debug( F101, "x25putmsg block size put ", "", data_len);
-
-#ifdef TRACE
- printf( "TRACE: leaving x25putmsg\n" );
-#endif /* TRACE */
-
- return( data_len );
-}
-
-/*****************************************************************************
-* Function: x25bind
-* Description: The bind submitted to NPI provides the information required
-* by the packet layer for it to listen for suitable incoming
-* calls.
-*
-* WARNING:
-*
-* This routine needs to be called in a completely different manner for
-* the client and server side. When starting a client, the
-* num_waiting_calls and CUD information should all be set to 0! The
-* client's CUD must be inserted in the CONN_REQ data block.
-* When starting a server, the CUD must be set to a CUD pattern, and
-* the number of waiting calls should be set to a number other than 0.
-* (num waiting calls is the number of incomming calls which are to be
-* put on hold while the server is servicing another client.)
-*
-* Who invented this crap?
-*
-* Parameters:
-* fd - X25 device (opened)
-* addr - local address
-* cud - User Data (null terminated)
-* cud_len - User Data length
-* num_waiting_calls - number of outstanding calls allowed on this stream
-* line - logical port number (1)
-* flags - 0, DEFAULT_LISTENER or TOKEN_REQUEST
-*
-* Return Value:
-* if binding is successful, 0 is returned for a client, and a token is
-* returned for a server
-*
-* Return code: 0 if successful
-* -1 if unsuccessful
-*****************************************************************************/
-
-ulong
-x25bind(fd, addr, cud, cud_len, num_waiting_calls, line, bind_flags)
- int fd; /* X25 device (opened) */
- char * addr; /* local address */
- char * cud; /* Call User Data (null terminated) */
- int cud_len; /* User Data length */
- int num_waiting_calls; /* Outstanding calls allowed */
- int line; /* logical port number */
- ulong bind_flags; /* 0, DEFAULT_LISTENER or TOKEN_REQUEST */
-/* x25bind */ {
- ulong rc; /* return code */
- int get_flags; /* priority flag passed to getmsg */
- int put_flags = 0; /* output flags for putmsg, always 0 */
- ulong type; /* primitive type */
- N_bind_req_t *bind_req; /* pointer to N_BIND_REQ primitive */
- N_bind_ack_t *bind_ack; /* pointer to N_BIND_ACK primitive */
- char *addtl_info; /* pointer to info in addition to
- * the N_BIND_REQ primitive that is
- * passed in the control structure
- * to putmsg */
- int addr_len = 0; /* length of address string */
- ulong bind_req_t_size; /* for debugging only */
-
-#ifdef TRACE
- printf("TRACE: entering x25bind\n" );
-#endif /* TRACE */
-
-#ifdef DEBUG
- printf("TRACE: x25bind( %d, %s, %s, %d, %d )\n",
- fd, addr, cud, line, bind_flags
- );
-#endif /* DEBUG */
-
- /*
- * Allocate and zero out space to hold the control portion of the
- * message passed to putmsg. This will contain the N_BIND_REQ
- * primitive and any additional info required for that.
- *
- * Note: allocated space is the size of the union typedef
- * N_npi_ctl_t to allow the use fo the generic x25putmsg routine.
- */
- bind_req = (N_bind_req_t *) malloc(sizeof( N_npi_ctl_t));
- if (bind_req == NULL) {
- perror("kermit: x25bind(): bind_req malloc failed");
- debug(F100, "x25bind bind_req malloc failed", "", 0);
- return(-1);
- }
- bzero((char *)bind_req, sizeof(N_npi_ctl_t));
-
- /* Build the Bind Request Primitive */
- bind_req->PRIM_type = (ulong) N_BIND_REQ;
-
- /* Note that the address length is n+2 and NOT n. Two bytes MUST preceed
- * the actual address in an N_BIND_REQ. The first byte contains the
- * line number being used with this address, and the second byte is the
- * X.121 address prefix, which must be zero.
- */
- addr_len = strlen(addr);
- bind_req->ADDR_length = (ulong) (addr_len + 2);
- bind_req->ADDR_offset = (ulong)(sizeof(N_bind_req_t));
- bind_req->CONIND_number = (ulong)num_waiting_calls; /* server only */
- bind_req->BIND_flags = (ulong) bind_flags; /* 0 in client */
- bind_req->PROTOID_length = (ulong) cud_len; /* 0 in client */
- if (cud_len == 0) {
- bind_req->PROTOID_offset = (ulong) 0;
- } else {
- /* need to remember the trailing NULL in the address - not
- * counted in the address length
- */
- bind_req->PROTOID_offset
- = (ulong) (sizeof(N_bind_req_t) + bind_req->ADDR_length);
- }
-
- /*
- * Now fill in the additional information required with this primitive
- * (address and protocol information (Call User Data))
- */
- addtl_info = (char *) ((void *)bind_req + bind_req->ADDR_offset);
- /*
- * The bitwise "&" ensures that the line number is only one byte long
- */
- *addtl_info++ = (char) line & 0xff;
- *addtl_info++ = (char) 0; /* X.121 format */
- bcopy( addr, addtl_info, addr_len ); /* include trailing null */
- addtl_info += addr_len;
- if (cud_len > 0)
- bcopy( cud, addtl_info, cud_len );
- /*
- * Call putmsg() to put the bind request message on the stream
- */
- if (x25putmsg(fd,
- (N_npi_ctl_t*)bind_req,
- (N_npi_data_t *)NULL,
- 0,
- &put_flags
- ) < 0) {
- printf( "kermit: x25bind(): x25putmsg failed\n" );
- return(-1);
- }
-
- /*
- * Allocate and zero out space for the N_BIND_ACK primitive
- */
- bind_ack = (N_bind_ack_t *) malloc(sizeof(N_npi_ctl_t));
- if (bind_ack == NULL){
- perror("kermit: x25bind(): bind_ack malloc failed");
- return(-1);
- }
- bzero(bind_ack, sizeof(N_npi_ctl_t));
- /*
- * Initialize the control structure and flag variable sent to getmsg
- */
- get_flags=0;
-
- /* get the ACK for the bind */
-#ifdef DEBUG
- printf( "kermit: x25bind() trying to get a BIND_ACK\n" );
-#endif /* DEBUG */
- rc = (ulong)x25getmsg( fd, (N_npi_ctl_t*)bind_ack,
- (int)sizeof( N_bind_ack_t ), (N_npi_data_t*)NULL, 0, &get_flags,
- N_BIND_ACK );
-
- /* turn quantitive return code into a qualitative one */
- if (rc > 0) rc = 0;
-
- /* if all went well, get the token from the acknowledgement packet */
- if ((bind_flags & TOKEN_REQUEST ) && ( rc >= 0)) {
- rc = bind_ack->TOKEN_value;
- }
-
- /* free up the memory we allocated earlier */
- free(bind_req);
- free(bind_ack);
-
-#ifdef TRACE
- printf( "TRACE: leaving x25bind\n" );
-#endif /* TRACE */
-
- return( rc );
-}
-
-/*****************************************************************************
-* Function: x25call
-* Description: This routine builds and sends an N_CONN_REQ primitive, then
-* checks for an N_CONN_CON primitive in return.
-*
-* Parameters:
-* fd - file descriptor of stream
-* caddr - called address (remote address)
-*
-* Functions Referenced:
-* malloc()
-* bzero()
-* getmsg()
-* putmsg()
-*
-* Return code:
-* 0 - if successful
-* -1 if not successful
-*****************************************************************************/
-int
-x25call(fd, remote_nua, cud)
- int fd; /* X25 device (opened) */
- char * remote_nua; /* remote address to call */
- char * cud; /* call user data */
-/* x25call */ {
- int rc; /* return code */
- int flags; /* Connection flags */
- int get_flags; /* priority flags for getmsg */
- ulong type; /* primitive type */
- N_conn_req_t *connreq_ctl; /* pointer to N_CONN_REQ primitive */
- N_npi_data_t *connreq_data; /* pointer to N_CONN_REQ data (CUD) */
- int connreq_data_len; /* length of filled data buffer */
- N_conn_con_t *conncon_ctl; /* pointer to N_CONN_CON primitive */
- N_npi_data_t *conncon_data; /* pointer to any data associated with
- * the N_CONN_CON primitive */
- char *addtl_info; /* pointer to additional info needed
- * for N_CONN_REQ primitive */
- int addr_len; /* length of address */
-
-#ifdef TRACE
- printf( "TRACE: entering x25call\n" );
-#endif /* TRACE */
-
-#ifdef DEBUG
- printf( "x25call( %d, %s )\n", fd, remote_nua );
- printf( "connecting to %s on fd %d\n", remote_nua, fd );
-#endif /* DEBUG */
-
- /*
- * Allocate and zero out space for the N_CONN_REQ primitive
- * use the size of the generic NPI primitive control buffer
- */
- connreq_ctl = (N_conn_req_t *) malloc(sizeof(N_npi_ctl_t));
- if (connreq_ctl == NULL){
- perror("kermit: x25call(): connreq_ctl malloc failed");
- return(-1);
- }
- bzero(connreq_ctl,sizeof(N_npi_ctl_t));
- /*
- * Build the Connection Request Primitive
- */
- flags = 0;
- connreq_ctl->PRIM_type = (ulong) N_CONN_REQ;
-
- /* Note that the address length is nchai+1 and not n+2. The line number
- * is only passed with the address for the bind. The first byte of
- * the address for the N_CONN primitives contains the X.121
- * address prefix, which must be zero. The remaining bytes are the
- * address itself.
- */
- addr_len = strlen( remote_nua );
- connreq_ctl->DEST_length = (ulong) (addr_len + 1);
- connreq_ctl->DEST_offset = (ulong) sizeof(N_conn_req_t);
- /* connreq_ctl->CONN_flags = (ulong)EX_DATA_OPT | REC_CONF_OPT; */
- connreq_ctl->CONN_flags = (ulong) 0;
- connreq_ctl->QOS_length = (ulong) 0; /* unsupported in AIX 4.1 */
- connreq_ctl->QOS_offset = (ulong) 0; /* unsupported in AIX 4.1 */
-
- addtl_info = (char *) ((void*)connreq_ctl + connreq_ctl->DEST_offset);
- *addtl_info++ = (char) 0; /* X.121 format */
- bcopy( remote_nua, addtl_info, addr_len );
-
- /*
- * setup the data buffer for the connection request
- */
- connreq_data = (N_npi_data_t *) malloc(sizeof(N_npi_data_t));
- if (connreq_data == NULL){
- perror("kermit: x25call(): connreq_data malloc failed");
- return(-1);
- }
- bzero(connreq_data,sizeof(N_npi_data_t));
-
- /* facility selection needs to be put in the front of connreq_data */
- connreq_data_len = 0;
- connreq_data_len += x25facilities( (char *)connreq_data );
- if (cud && *cud) {
- bcopy(cud,
- (char *)((char *)connreq_data + connreq_data_len),
- strlen(cud)
- );
- connreq_data_len += strlen( cud );
- }
-
- /*
- * Call putmsg() to put the connection request message on the stream
- */
- rc = x25putmsg( fd, (N_npi_ctl_t*)connreq_ctl, connreq_data,
- connreq_data_len, &flags );
- if (rc < 0) {
- return(-1);
- }
-
- /*
- * Allocate and zero out space for the N_CONN_CON primitive
- */
- if ((conncon_ctl = (N_conn_con_t *) malloc(sizeof(N_npi_ctl_t))) == NULL) {
- perror("kermit: x25call(): conncon_ctl malloc failed");
- return(-1);
- }
- bzero(conncon_ctl, sizeof(N_npi_ctl_t));
-
- /*
- * Allocate and zero out space for any data associated with N_CONN_CON
- */
- if ( (conncon_data = (N_npi_data_t *) malloc(NPI_MAX_DATA)) == NULL) {
- perror("kermit: x25call(): conncon_data malloc failed");
- return(-1);
- }
- bzero(conncon_data, NPI_MAX_DATA);
-
- /* Initialize and build the structures for getmsg */
- get_flags=0;
-
- rc = x25getmsg( fd, (N_npi_ctl_t*)conncon_ctl, (int)sizeof( N_conn_con_t ),
- conncon_data, NPI_MAX_DATA, &get_flags, N_CONN_CON );
-
- /* turn quantitive return code into a qualitative one */
- if (rc > 0) rc = 0;
-
- /* Free the space that we no longer need */
- if (connreq_ctl) { free(connreq_ctl); connreq_ctl = NULL; }
- if (conncon_ctl) { free(conncon_ctl); conncon_ctl = NULL; }
- if (conncon_data) { free(conncon_data); conncon_data = NULL; }
-
-#ifdef TRACE
- printf( "TRACE: leaving x25call\n" );
-#endif /* TRACE */
-
- return(rc);
-}
-
-/*****************************************************************************
- * Function: x25getcall
- *
- * Description: This routine checks for an incomming call, verified
- * that it is a CONNIND (connection indication) message, and then
- * accepts the call and returns the file descriptor of the new stream
- *
- * Parameters:
- * fd - file descriptor of listening stream
- *
- * Return Codes:
- * callfd - file descriptor of connected incomming call.
- * - set to -1 if an error occured
- *
- *****************************************************************************/
-int
-x25getcall(fd) int fd; {
- int x25callfd; /* fd of incomming call */
- N_conn_ind_t *connind_ctl; /* connind controll buffer */
- N_npi_data_t *connind_data; /* connind data buffer */
- int get_flags; /* flags for getmsg */
- ulong flags; /* connection flags */
- int rc; /* return code */
-
- extern x25addr_t remote_nua; /* remote X.25 addr global var */
-
-#ifdef TRACE
- printf( "TRACE: entering x25getcall\n" );
-#endif /* TRACE */
-
- /* allocate space for connection indication buffers */
- if ((connind_ctl = (N_conn_ind_t *)malloc(sizeof(N_npi_ctl_t))) == NULL) {
- perror("kermit: x25getcall(): connind_ctl malloc failed");
- return (-1);
- }
- bzero(connind_ctl, sizeof(N_npi_ctl_t));
-
- if ((connind_data = (N_npi_data_t *)malloc(NPI_MAX_DATA)) == NULL) {
- perror("kermit: x25getcall(): connind_data malloc failed");
- return (-1);
- }
- bzero(connind_data, NPI_MAX_DATA);
-
- /* initialise control structures */
- get_flags = 0;
-
- /* call getmsg to check for a connection indication */
- if (x25getmsg(fd,
- (N_npi_ctl_t*)connind_ctl,
- (int)sizeof(N_conn_ind_t),
- connind_data,
- NPI_MAX_DATA,
- &get_flags,
- N_CONN_IND
- ) < 0) {
-#ifdef DEBUG
- printf( "x25getcall(): errno is: %d\n", errno );
-#endif /* DEBUG */
- perror ("x25getcall(): getmsg failed");
- return(-1);
- }
-
- /* a connection indication was received
- * - pull it to bits and answer the call
- */
- x25seqno = connind_ctl->SEQ_number;
- flags = connind_ctl->CONN_flags;
-#ifdef DEBUG
- printf( "setting remote_nua to a new value due to incomming call\n" );
-#endif /* DEBUG */
- /*
- * no guarantee that the address is null terminated, ensure that
- * after copying that it is (assumption: remote_nua is longer than
- * the address + 1)
- */
- bzero(remote_nua, sizeof(remote_nua));
- /* note: connind_ctl contains a x121 address, which has a null as
- * the FIRST character - strip it off!
- */
- ckstrncpy(remote_nua,
- (char*)((char*)connind_ctl + connind_ctl->SRC_offset + 1),
- connind_ctl->SRC_length - 1
- );
-#ifdef DEBUG
- printf( "remote_nua set to new value of %s\n", remote_nua );
-#endif /* DEBUG */
-
- /* errors handled by callee */
- x25callfd = x25accept(x25seqno, flags);
-
- /* free the malloc'd buffers */
- if (connind_ctl) { free(connind_ctl); connind_ctl = NULL; }
- if (connind_data) { free(connind_data); connind_data = NULL; }
-
-#ifdef TRACE
- printf( "TRACE: leaving x25getcall\n" );
-#endif /* TRACE */
-
- /* return the file descriptor (or error if < 0) */
- return( x25callfd );
-}
-
-/*****************************************************************************
- * Function: x25accept
- *
- * Description: accept an incomming call
- * This essentially means opening a new STREAM and sending
- * an acknowledge back to the caller.
- *
- * Parameters:
- * seqno - sequence number for acknowledgement
- * flags - flags passed to us by the caller
- *
- * Return Codes:
- * fd - file descriptor of new STREAM
- * set to -1 if an error occured
- *
- *****************************************************************************/
-int
-x25accept(seqno,flags)
- ulong seqno; /* connection sequence number */
- ulong flags; /* connection flags */
-/* x25accept */ {
- int x25callfd; /* fd for incomming call */
- int get_flags; /* priority flags for getmsg */
- int put_flags = 0; /* flags for putmsg, always 0 */
- int addr_len; /* length of local address */
- ulong token; /* connection token */
- N_conn_res_t *conn_res; /* N_CONN_RES primitive */
- N_ok_ack_t *ok_ack; /* N_OK_ACK primitive */
- char *addtl_info; /* temp pointer */
- int rc; /* temporary return code */
-
-/* global variables from ckcmai.c */
- extern int revcall, closgr, cudata;
- extern char udata[];
- extern x25addr_t local_nua; /* local X.25 address */
- extern char x25name[]; /* x25 device name (sx25a0) */
- extern char x25dev[]; /* x25 device file /dev/x25pkt */
- extern int x25port; /* logical port to use */
- ulong bind_flags = 0; /* flags for binding the X25 stream */
-
-#ifdef TRACE
- printf( "TRACE: entering x25accept\n" );
-#endif /* TRACE */
-
- /* open a new packet level stream */
- if ((x25callfd = open(x25dev, O_RDWR)) < 0) {
- perror ("kermit: x25accept(): X.25 device open error");
- debug(F101,"x25accept() device open error","",errno);
- return(-1);
- }
-
- /* push the NPI onto the STREAM */
- if (ioctl(x25callfd,I_PUSH,"npi") < 0) {
- perror( "kermit: x25accept(): couldn't push npi on the X25 stream" );
- debug(F101,"x25accept can't push npi on the X25 stream","",errno);
- return (-1);
- }
-
- /* bind kermit server to the local X25 address */
- /* taken from /usr/samples/sx25/npi/npiserver.c (AIX 4) */
- bind_flags |= TOKEN_REQUEST;
- token = x25bind(x25callfd,local_nua,(char *)NULL,0,0,x25port,bind_flags);
- if (token < 0) {
- printf( "kermit: x25accept(): couldn't bind to local X25 address\n" );
- netclos();
- return(-1);
- }
-
- /* allocate connection response primitive */
- if ((conn_res = (N_conn_res_t *)malloc( NPI_MAX_CTL )) == NULL) {
- perror("kermit: x25accept(): conn_res malloc failed");
- return (-1);
- }
- bzero((char *)conn_res, NPI_MAX_CTL);
-
- /* setup connection response primitive */
- addr_len = strlen( local_nua );
- conn_res->PRIM_type = (ulong)N_CONN_RES;
- conn_res->TOKEN_value = token;
- /* note address length is n+1 to accomodate the X.121 address prefix */
- conn_res->RES_length = (ulong)(addr_len + 1);
- conn_res->RES_offset = (ulong)sizeof( N_conn_res_t );
- conn_res->SEQ_number = seqno;
- conn_res->CONN_flags = 0;
- conn_res->QOS_length = 0; /* unsupported - must be 0 (!?) */
- conn_res->QOS_offset = 0;
-
- addtl_info = (char *)((char *)conn_res + conn_res->RES_offset);
- *addtl_info++ = (char)0; /* X.121 address prefix */
- bcopy( local_nua, addtl_info, addr_len );
-
- /*
- * send off the connect response
- */
- if (x25putmsg(x25callfd,
- (N_npi_ctl_t*)conn_res,
- (N_npi_data_t *)NULL,
- 0,
- &put_flags
- ) < 0 ) {
- perror("kermit: x25accept(): putmsg connect response failed");
- return(-1);
- }
-
- /*
- * Allocate and zero out space for the OK_ACK primitive
- */
- if ((ok_ack = (N_ok_ack_t *) malloc(sizeof(N_npi_ctl_t))) == NULL) {
- perror("kermit: x25call(): ok_ack malloc failed");
- return(-1);
- }
- bzero(ok_ack, sizeof(N_npi_ctl_t));
-
- /* Initialize and build the structures for getmsg */
- get_flags=0;
-
- rc = (int)x25getmsg(x25callfd,
- (N_npi_ctl_t*)ok_ack,
- (int)sizeof(N_ok_ack_t),
- (N_npi_data_t*)NULL,
- 0,
- &get_flags,
- N_OK_ACK
- );
- if (rc == 0) {
- /* sequence number is only for disconnecting when not connected !? */
- x25seqno = 0;
- }
-
- /* free up malloc'ed buffer space */
- if (conn_res) { free(conn_res); conn_res = NULL; }
- if (ok_ack) { free(ok_ack); ok_ack = NULL; }
-
-#ifdef TRACE
- printf( "TRACE: leaving x25accept\n" );
-#endif /* TRACE */
-
- return( ( rc >= 0 ) ? x25callfd : -1 );
-}
-
-/*****************************************************************************
- * Function: x25unbind
- *
- * Description: This subroutine builds and sends an unbind request and gets
- * the acknowledgement for it.
- *
- * Parameters:
- * fd - File descriptor of the stream
- *
- * Functions Referenced:
- * getmsg()
- * putmsg()
- * malloc()
- * bzero()
- *
- * Return code:
- * 0 - if successful
- * -1 - if not successful
- *****************************************************************************/
-int
-x25unbind(fd) int fd; { /* X25 device (opened) */
- int rc; /* return code */
- int flags; /* bind flags */
- int get_flags; /* priority flag for getmsg */
- ulong type; /* primitive type */
- N_unbind_req_t *unbind_req; /* pointer to N_UNBIND_REQ */
- N_ok_ack_t *ok_ack; /* pointer to N_OK_ACK */
-
-#ifdef TRACE
- printf( "TRACE: entering x25unbind\n" );
-#endif /* TRACE */
-
-#ifdef DEBUG
- /* printf( "x25unbind( %d )\n", fd ); */
-#endif /* DEBUG */
- debug(F101,"x25unbind closing x25 connection #","",fd);
-
- /* Allocate and zero out space to hold the N_UNBIND_REQ primitive */
- unbind_req = (N_unbind_req_t *) malloc(sizeof(N_npi_ctl_t));
- if (unbind_req == NULL) {
- perror("kermit: x25unbind(): unbind_req malloc failed");
- return(-1);
- }
- bzero(unbind_req, sizeof(N_npi_ctl_t));
-
- /*
- * Build the Unbind Request Primitive
- */
- flags = 0;
- unbind_req->PRIM_type = (ulong) N_UNBIND_REQ;
-
- /*
- * Call putmsg() to put the bind request message on the stream
- */
- if (x25putmsg(fd,
- (N_npi_ctl_t*)unbind_req,
- (N_npi_data_t *)NULL,
- 0,
- &flags
- ) < 0) {
- perror ("kermit: x25unbind(): putmsg failed");
- return(-1);
- }
-
- /* Allocate and Zero out space for the N_OK_ACK primitive */
- ok_ack = (N_ok_ack_t *) malloc(sizeof(N_npi_ctl_t));
- if (ok_ack == NULL) {
- perror("kermit x25unbind(): ok_ack malloc failed\n");
- return(-1);
- }
- bzero(ok_ack, sizeof(N_npi_ctl_t));
-
- /* Initialize and build the control structure for getmsg */
- get_flags=0;
-
- /* Call getmsg() to check for an acknowledgement */
- rc = x25getmsg(fd,
- (N_npi_ctl_t*)ok_ack,
- (int)sizeof(N_ok_ack_t),
- (N_npi_data_t*)NULL,
- 0,
- &get_flags,
- N_OK_ACK
- );
- if (rc < 0) {
- perror ("kermit: x25unbind: getmsg failed");
- return(-1);
- }
-
- /* Free up the space that we no longer need */
- if (unbind_req) { free(unbind_req); unbind_req = NULL; }
- if (ok_ack) { free(ok_ack); ok_ack = NULL; }
-
-#ifdef TRACE
- printf( "TRACE: leaving x25unbind\n" );
-#endif /* TRACE */
-
- return(0);
-}
-
-/*****************************************************************************
- * Function: x25xin
- *
- * Description:
- * Read n characters from X.25 circuit into buf (AIX only)
- *
- * Parameters:
- * data_buf_len maximum size of data buffer
- * data_buf pointer to pre-allocated buffer space
- *
- * Return Value:
- * the number of characters actually read
- */
-int
-x25xin(data_buf_len,data_buf) int data_buf_len; CHAR *data_buf; {
- struct strbuf getmsg_ctl; /* streams control structure */
- struct strbuf getmsg_data; /* streams data structure */
- int rc = 0; /* return code */
- int getmsg_flags; /* packet priority flags */
- char * ctl_buf; /* npi control buffer */
- N_npi_ctl_t * result; /* pointer to simplify switch() */
-
-#ifdef TRACE
- printf( "TRACE: entering x25xin\n" );
-#endif /* TRACE */
-
- /* ensure that no maximum's are overridden */
- data_buf_len = (NPI_MAX_DATA < data_buf_len) ? NPI_MAX_DATA : data_buf_len;
-
- /* allocate space for packet control info */
- if ((ctl_buf = (char *)malloc(NPI_MAX_CTL)) == NULL) {
- perror( "kermit: x25xin(): ctl_buf malloc" );
- return(-1);
- }
-#ifdef COMMENT
- /* riehm: need zeroed buffer for getmsg? */
- bzero( ctl_buf, NPI_MAX_CTL );
- /* clear data buffer */
- bzero( data_buf, data_buf_len );
-#endif /* COMMENT */
-
- getmsg_flags = 0; /* get the first packet available */
-
- rc = x25getmsg(ttyfd,
- ctl_buf,
- NPI_MAX_CTL,
- data_buf,
- data_buf_len,
- &getmsg_flags,
- N_DATA_IND
- );
-#ifdef COMMENT
-#ifdef DEBUG
- if (rc >= 0) {
- printf( "kermit: x25xin(): got " );
- x25dump_data( data_buf, 0, rc );
- } else {
- printf( "x25xin(): attempt to get data resulted in an error\n" );
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
-
- /* free buffers */
- if (ctl_buf) { free(ctl_buf); ctl_buf = NULL; }
-
-#ifdef TRACE
- printf( "TRACE: leaving x25xi\n" );
-#endif /* TRACE */
-
- return(rc);
-}
-
-/*****************************************************************************
- * Function: x25write
- *
- * Description:
- * write a block of characters to the X25 STREAM (AIX)
- *
- * Parameters:
- * fd file descriptor to write to
- * databuf buffer containing data to write
- * databufsize size of the buffer to write
- *
- * Return Value:
- * size the number of bytes actually transmitted
- */
-int
-x25write(fd, databuf, databufsize)
- int fd; /* X25 STREAMS file descriptor (ttyfd) */
- char *databuf; /* buffer to write */
- int databufsize; /* buffer size */
-/* x25write */ {
- N_data_req_t *data_req_ctl;
- int rc; /* return code (size transmitted) */
- int write_flags = 0; /* always 0 !? */
-
-#ifdef TRACE
- printf( "TRACE: entering x25write\n" );
-#endif /* TRACE */
-
- if ((data_req_ctl = (N_data_req_t *)malloc(NPI_MAX_CTL) ) == NULL) {
- perror( "kermit: x25write(): data_req_ctl malloc" );
- return(-1);
- }
- data_req_ctl->PRIM_type = N_DATA_REQ;
- data_req_ctl->DATA_xfer_flags = 0;
-
- /* riehm: possible extension
- * possibly need to think about splitting up the data buffer
- * into multiple parts if databufsize > NPI_MAX_DATA
- */
-
-#ifdef COMMENT
-#ifdef DEBUG
- printf( "kermit: x25write(): writing data to x25 stream\n" );
- printf( "\tdata:\t" );
- x25dump_data(databuf, 0, databufsize);
-#endif /* DEBUG */
-#endif /* COMMENT */
- rc = x25putmsg(fd,
- (N_npi_ctl_t*)data_req_ctl,
- (N_npi_data_t*)databuf,
- databufsize,
- &write_flags
- );
- if (data_req) { free(data_req_ctl); data_req = NULL; }
-
-#ifdef TRACE
- printf( "TRACE: leaving x25write\n" );
-#endif /* TRACE */
-
- return(rc);
-}
-
-/*****************************************************************************
- * Function: x25local_nua
- *
- * Description:
- * This routine is only interesting for IBM computers. In order
- * to set up a connection (see x25bind()) you need to know the
- * local NUA (x25 address). Unfortunately, you need all this code
- * to find that out, I just hope this works for everyone else!
- *
- * Parameters:
- * a pre-allocated character buffer, long enough to hold an X.25 address
- * and the tailing null.
- *
- * Return Value:
- * the length of the address string.
- * 0 = error
- */
-int
-x25local_nua(char *buf) {
- struct CuAt *response; /* structure to fill with info from ODM */
- CLASS_SYMBOL retClass; /* ODM class */
- char query[64]; /* odm database query */
- int rc = 0; /* return value (length of local NUA) */
- extern char x25name[]; /* x25 device name (sx25a0) */
-
-#ifdef TRACE
- printf( "TRACE: entering x25local_nua\n" );
-#endif /* TRACE */
-
- /* set up query string */
- if (x25name[0] == '\0') {
-#ifdef DEBUG
- printf( "kermit: x25local_nua(): No x25 device set, trying sx25a0\n" );
-#endif /* DEBUG */
- strcpy( x25name, "sx25a0" );
- }
- ckmakmsg(query, sizeof(query), "name like ",x25name,
- " and attribute like local_nua");
-
- /* initialise ODM database */
- odmerrno = 0;
- if (odm_initialize() == -1) {
- printf( "x25local_nua(): can't initialize ODM database");
- switch (odmerrno) {
- case ODMI_INVALID_PATH:
- printf( "invalid path\n" );
- break;
- case ODMI_MALLOC_ERR:
- printf( "malloc failed\n" );
- break;
- default:
- printf( "unknown error %d\nPlease call IBM\n", odmerrno );
- }
- return(rc);
- }
-
- /* open the CuAt class */
- retClass = odm_open_class(CuAt_CLASS);
- if (((int)retClass) == -1) {
- printf( "kermit: x25local_nua(): can't open CuAt class in odm. " );
- switch (odmerrno) {
- case ODMI_CLASS_DNE:
- printf( "CuAt class doesn't exist\n" );
- break;
- case ODMI_CLASS_PERMS:
- printf( "permission to CuAt class file denied\n" );
- break;
- case ODMI_MAGICNO_ERR:
- printf( "CuAt is an invalid ODM object class\n" );
- break;
- case ODMI_OPEN_ERR:
- printf( "cannot open CuAt class - and don't know why!\n" );
- break;
- case ODMI_INVALID_PATH:
- printf( "invalid path\n" );
- break;
- case ODMI_TOOMANYCLASSES:
- printf( "too many object classes have been opened\n" );
- break;
- default:
- printf( "unknown error %d\nPlease call IBM\n", odmerrno );
- }
- return(rc);
- }
-
-#ifdef DEBUG
- printf("retClass= %d\n", retClass);
-#endif /* DEBUG */
-
- response = (struct CuAt *)odm_get_first( retClass, query, NULL );
- if (((int)response) == -1) {
- printf( "kermit: x25local_nua(): odm query failed " );
- switch (odmerrno) {
- case ODMI_BAD_CRIT: /* Programming error */
- printf( "bad search criteria\n" );
- break;
- case ODMI_CLASS_DNE:
- printf( "CuAt class doesn't exist\n" );
- break;
- case ODMI_CLASS_PERMS:
- printf( "permission to CuAt class file denied\n" );
- break;
- case ODMI_INTERNAL_ERR:
- printf("odm internal error\nPlease contact your administrator\n" );
- break;
- case ODMI_INVALID_CLXN:
- printf("CuAt is invalid or inconsistent odm class collection\n");
- break;
- case ODMI_INVALID_PATH:
- printf( "invalid path\n" );
- break;
- case ODMI_MAGICNO_ERR:
- printf( "CuAt is an invalid ODM object class\n" );
- break;
- case ODMI_MALLOC_ERR:
- printf( "malloc failed\n" );
- break;
- case ODMI_OPEN_ERR:
- printf( "cannot open CuAt class - and don't know why!\n" );
- break;
- case ODMI_TOOMANYCLASSES:
- printf( "too many object classes have been opened\n" );
- break;
- default:
- printf( "unknown error %d\nPlease call IBM\n", odmerrno );
- }
- return(rc);
- }
-
- /* check for a meaningfull response */
- if (response != NULL) {
- if (response->value != NULL) {
- strcpy(buf, response->value);
- rc = strlen( buf );
-#ifdef DEBUG
-/*
- printf( "attribute name is: %s\n", (char *)response->attribute );
- printf( "I think my address is %s\n", (char*)response->value );
-*/
-#endif /* DEBUG */
- } else {
- printf( "kermit: x25local_nua(): couldn't find the local NUA\n" );
- }
- } else {
- switch (odmerrno) {
- case ODMI_BAD_CRIT:
- printf( "Error: ODMI_BAD_CRIT - bad criteria\n" );
- break;
- case ODMI_CLASS_DNE:
- printf( "Error: ODMI_CLASS_DNE - class doesn't exist\n" );
- break;
- case ODMI_CLASS_PERMS:
- printf( "Error: ODMI_CLASS_PERMS - class permissions\n" );
- break;
- case ODMI_INTERNAL_ERR:
- printf( "Error: ODMI_INTERNAL_ERR - panic\n" );
- break;
- case ODMI_INVALID_CLXN:
- printf( "Error: ODMI_INVALID_CLXN - invalid collection\n" );
- break;
- case ODMI_INVALID_PATH:
- printf( "Error: ODMI_INVALID_PATH - invalid path - what path?\n" );
- break;
- case ODMI_MAGICNO_ERR:
- printf( "Error: ODMI_MAGICNO_ERR - invalid object magic\n" );
- break;
- case ODMI_MALLOC_ERR:
- printf( "Error: ODMI_MALLOC_ERR - malloc failed\n" );
- break;
- case ODMI_OPEN_ERR:
- printf( "Error: ODMI_OPEN_ERR - cannot open class\n" );
- break;
- case ODMI_TOOMANYCLASSES:
- printf( "Error: ODMI_TOOMANYCLASSES - too many classes\n" );
- break;
- default:
- printf( "Unknown error!\n" );
- }
- return(rc);
- }
-
- /* close the database again */
- odm_close_class( retClass );
-
- /* forget about ODM all together */
- odm_terminate();
-
-#ifdef TRACE
- printf( "TRACE: leaving x25local_nua\n" );
-#endif /* TRACE */
-
- debug(F110, "x25local_nua local address is ", buf, 0);
- return(rc);
-}
-
-/*****************************************************************************
- * Function: x25facilities
- *
- * Description:
- * build up the facilities data packet for a connection request
- *
- * Parameters:
- * a pre-allocated char buffer, normally NPI_MAX_DATA big.
- *
- * Return Value:
- * the number of characters inserted into the buffer
- */
-int
-x25facilities(buffer) char *buffer; {
- extern int revcall;
- extern int closgr;
- char *p; /* temp pointer */
- char *start; /* temp pointer */
-
-#ifdef TRACE
- printf( "TRACE: entering x25facilities\n" );
-#endif /* TRACE */
-
- p = buffer + 1;
- start = p;
-
-#ifdef DEBUG
- printf( "kermit: x25facilities(): getting X25 facilities\n" );
-#endif /* DEBUG */
-
- if (revcall != 0) {
-#ifdef DEBUG
- printf("reverse charge: %d\n", revcall );
-#endif /* DEBUG */
- *++p = 0x01;
- *++p = revcall;
- }
- if (closgr > 0) {
-#ifdef DEBUG
- printf("closed user group: %d\n", closgr );
-#endif /* DEBUG */
- *++p = 0x03;
- *++p = closgr;
- }
-
-#ifdef DEBUG
- if (p == start) {
- printf( "no facilities\n" );
- }
-#endif /* DEBUG */
-
- /* set the size of the facilities buffer */
- *buffer = (char)( p - start ) & 0xff;
-
-#ifdef DEBUG
- printf( "kermit: x25facilities(): returning %d\n", (int)(p - buffer) );
-#endif /* DEBUG */
-
-#ifdef TRACE
- printf( "TRACE: leaving x25facilities\n" );
-#endif /* TRACE */
-
- /* return the size of the facilities with size byte */
- /* 1 == no facilities, 0 byte returned as facilities size */
- return( (int)(p - buffer) );
-}
-
-/*
- * reset the connection
- */
-int
-x25reset(cause, diagn) char cause; char diagn; {
- /* not implemented */
-
-#ifdef TRACE
- printf( "TRACE: entering x25reset\n" );
-#endif /* TRACE */
-
-#ifdef TRACE
- printf( "TRACE: leaving x25reset\n" );
-#endif /* TRACE */
-
- return(0);
-}
-
-/*
- * clear the x25 connection - ie: hang up
- */
-int
-x25clear() {
- int get_flags = 0; /* priority flag for getmsg */
- int put_flags = 0; /* send flags, always 0 */
- ulong type; /* primitive type */
- N_discon_req_t *discon_req; /* pointer to N_DISCON_REQ */
- N_discon_ind_t *discon_ind; /* pointer to N_DISCON_IND */
- N_npi_data_t *discon_data; /* pointer to N_DISCON_IND data */
- int rc = 0; /* return code */
-
-#ifdef TRACE
- printf( "TRACE: entering x25clear\n" );
-#endif /* TRACE */
-
-#ifdef DEBUG
- /* printf( "x25clear(): checking last msg: %s\n", x25prim(x25lastmsg)); */
-#endif /* DEBUG */
-
- /*
- * The following checks are used to ensure that we don't disconnect
- * or unbind twice - this seems to throw the NPI interface right out of
- * kilter.
- */
- switch(x25lastmsg) {
- case N_BIND_ACK:
- case N_CONN_CON:
- case N_CONN_REQ:
- case N_DATA_REQ:
- case N_DATA_IND:
- {
-#ifdef DEBUG
- /* printf("x25clear(): actively disconnecting\n"); */
-#endif /* DEBUG */
-
- discon_req = (N_discon_req_t *)malloc(NPI_MAX_CTL);
- if (discon_req == NULL) {
- perror("kermit x25clear(): discon_req malloc failed\n");
- /* fallthrough, try to unbind the NPI anyway */
- } else {
- discon_req->PRIM_type = N_DISCON_REQ;
- discon_req->DISCON_reason = 0; /* not used by AIX */
- discon_req->RES_length = 0;
- discon_req->RES_offset = (ulong)(sizeof(N_discon_req_t));
- discon_req->SEQ_number = x25seqno; /* global */
-
- if (x25putmsg(ttyfd,
- (N_npi_ctl_t*)discon_req,
- (N_npi_data_t*)NULL,
- 0,
- &put_flags
- ) < 0) {
- perror("x25putmsg failed in x25clear()");
- }
- discon_ind = (N_discon_ind_t *)malloc(NPI_MAX_CTL);
- discon_data = (N_npi_data_t *)malloc(NPI_MAX_DATA);
- if((discon_ind == NULL) || (discon_data == NULL)) {
- perror("x25clear(): discon_ind malloc failed\n");
- /* fallthrough, try to unbind the NPI anyway */
- } else {
- if(x25getmsg(ttyfd,
- (N_npi_ctl_t*)discon_ind,
- NPI_MAX_CTL,
- (N_npi_data_t*)discon_data,
- NPI_MAX_DATA,
- &get_flags,
- N_OK_ACK
- ) < 0 ) {
- perror("x25getmsg failed in x25clear()");
- /* fallthrough, try to unbind the NPI anyway */
- }
- }
- }
- break;
- }
- }
-
- if (x25lastmsg != N_UNBIND_REQ) {
- rc = x25unbind(ttyfd);
- }
-
-#ifdef TRACE
- printf( "TRACE: leaving x25clear\n" );
-#endif /* TRACE */
-
- return(rc);
-}
-
-#ifdef DEBUG
-/*
- * only for debugging
- *
- * turn the internal representation of a datablock into something
- * half-way readable. Because the length is known, we can print
- * the string including null's etc (important, because the first(!)
- * byte of an X121 address is a null! (X121 addr == 0 + X25 addr)
- */
-x25dump_data(char *addr, ulong offset, ulong length) {
- char *ptr = addr + offset;
- ulong i = length;
- /* allocate enough memory for all unprintable chars */
- char *buf = (char *)malloc( length * 4 );
- char *bptr = buf; /* pointer to current place in the print buffer */
-
- while (i > 0) {
- if (isprint(*ptr)) {
- *bptr++ = *ptr;
- } else {
- *bptr++ = '[';
- strcpy(bptr,ckctox(*ptr,1)); bptr += 2;
- *bptr++ = ']';
- }
- ptr++;
- i--;
- }
- if (length > 0) {
- *bptr = '\0';
- printf( "%s", buf );
- }
- printf( " (%d+%d)\n", offset, length );
-
- if (buf) { free(buf); buf = NULL; }
- return;
-}
-
-/*
- * only for debugging
- * print as much useful information about a packet as possible
- */
-x25dump_prim(primitive) N_npi_ctl_t *primitive; {
- printf("Primitive");
- switch (primitive->PRIM_type) {
- case N_BIND_ACK:
- printf( "\tN_BIND_ACK\n\taddress:\t" );
- x25dump_data( (char *)primitive,
- primitive->bind_ack.ADDR_offset,
- primitive->bind_ack.ADDR_length );
- printf( "\tproto id:\t" );
- x25dump_data( (char *)primitive,
- primitive->bind_ack.PROTOID_offset,
- primitive->bind_ack.PROTOID_length );
- printf( "\tconnind:\t%d\n\ttoken:\t\t%d\n",
- primitive->bind_ack.CONIND_number,
- primitive->bind_ack.TOKEN_value );
- break;
-
- case N_BIND_REQ:
- printf( "\tN_BIND_REQ\n\taddress:\t" );
- x25dump_data( (char *)primitive,
- primitive->bind_req.ADDR_offset,
- primitive->bind_req.ADDR_length );
- printf( "\tproto id:\t" );
- x25dump_data( (char *)primitive,
- primitive->bind_req.PROTOID_offset,
- primitive->bind_req.PROTOID_length );
- printf( "\tconnind:\t%d\n\tflags:\t\t%d\n",
- primitive->bind_req.CONIND_number,
- primitive->bind_req.BIND_flags );
- break;
-
- case N_CONN_CON:
- printf( "\tN_CONN_CON\n" );
- printf( "\tRES\t\t" );
- x25dump_data( (char *)primitive,
- primitive->conn_con.RES_offset,
- primitive->conn_con.RES_length );
- printf( "\tflags:\t%d\n", primitive->conn_con.CONN_flags );
- break;
-
- case N_CONN_IND:
- printf( "\tN_CONN_IND\n" );
- printf( "\tsource:\t\t" );
- x25dump_data( (char *)primitive,
- primitive->conn_ind.SRC_offset,
- primitive->conn_ind.SRC_length );
- printf( "\tdestination:\t" );
- x25dump_data( (char *)primitive,
- primitive->conn_ind.DEST_offset,
- primitive->conn_ind.DEST_length );
- printf( "\tSEQ_number:\t%d\n", primitive->conn_ind.SEQ_number );
- printf( "\tflags:\t%d\n", primitive->conn_ind.CONN_flags );
- break;
-
- case N_CONN_REQ:
- printf( "\tN_CONN_REQ\n\tdestination:\t" );
- x25dump_data( (char *)primitive,
- primitive->conn_req.DEST_offset,
- primitive->conn_req.DEST_length );
- printf( "\tflags:\t%d\n", primitive->conn_req.CONN_flags );
- break;
-
- case N_CONN_RES:
- printf( "\tN_CONN_RES\n" );
- printf( "\tTOKEN_value\t%d\n", primitive->conn_res.TOKEN_value );
- printf( "\tSEQ_number\t%d\n", primitive->conn_res.SEQ_number );
- printf( "\tCONN_flags\t%d\n", primitive->conn_res.CONN_flags );
- printf( "\tRES\t\t" );
- x25dump_data( (char *)primitive,
- primitive->conn_res.RES_offset,
- primitive->conn_res.RES_length );
- break;
-
- case N_DATACK_IND:
- printf( "\tN_DATACK_IND\n" );
- break;
-
- case N_DATACK_REQ:
- printf( "\tN_DATACK_REQ\n" );
- printf( "\tflags:\t%d\n", primitive->data_req.DATA_xfer_flags );
- break;
-
- case N_DATA_IND:
- printf( "\tN_DATA_IND\n" );
- printf( "\tflags:\t%d\n", primitive->data_ind.DATA_xfer_flags );
- break;
-
- case N_DATA_REQ:
- printf( "\tN_DATA_REQ\n" );
- break;
-
- case N_DISCON_IND:
- printf( "\tN_DISCON_IND\n" );
- printf( "\torigin:\t%d\n", primitive->discon_ind.DISCON_orig );
- printf( "\treason:\t\t%d\n", primitive->discon_ind.DISCON_reason );
- printf( "\tseq no:\t\t%d\n", primitive->discon_ind.SEQ_number );
- printf( "\tRES:\t" );
- x25dump_data( (char *)primitive,
- primitive->discon_ind.RES_offset,
- primitive->discon_ind.RES_length );
- break;
-
- case N_DISCON_REQ:
- printf( "\tN_DISCON_REQ\n" );
- printf( "\tDISCON_reason:\t%d\n",
- primitive->discon_req.DISCON_reason );
- printf( "\tRES:\t" );
- x25dump_data( (char *)primitive,
- primitive->discon_req.RES_offset,
- primitive->discon_req.RES_length );
- printf( "\tSEQ_number:\t%d\n", primitive->discon_req.SEQ_number );
- break;
-
- case N_ERROR_ACK:
- printf( "\tN_ERROR_ACK\n" );
- printf( "\tCaused by:\t%s\n",
- x25prim( primitive->error_ack.ERROR_prim ) );
- printf( "\tNPI error:\t%s\n",
- x25err( primitive->error_ack.NPI_error ));
- errno = primitive->error_ack.UNIX_error;
- perror( "\t" );
- break;
-
- case N_EXDATA_IND:
- printf( "\tN_EXDATA_ACK\n" );
- break;
-
- case N_EXDATA_REQ:
- printf( "\tN_EXDATA_REQ\n" );
- break;
-
- case N_INFO_ACK:
- printf( "\tN_INFO_ACK\n" );
- printf( "\tNSDU size:\t%d\n", primitive->info_ack.NSDU_size );
- printf( "\tENSDU size:\t%d\n", primitive->info_ack.ENSDU_size );
- printf( "\tCDATA size:\t%d\n", primitive->info_ack.CDATA_size );
- printf( "\tDDATA size:\t%d\n", primitive->info_ack.DDATA_size );
- printf( "\tADDR size:\t%d\n", primitive->info_ack.ADDR_size );
- printf( "\tNIDU size:\t%d\n", primitive->info_ack.NIDU_size );
- break;
-
- case N_INFO_REQ:
- printf( "\tN_INFO_REQ\n" );
- break;
-
- case N_OK_ACK:
- printf( "\tN_OK_ACK\n" );
- break;
-
- case N_OPTMGMT_REQ:
- printf( "\tN_OPTMGMT_REQ\n" );
- break;
-
- case N_RESET_CON:
- printf( "\tN_RESET_CON\n" );
- break;
-
- case N_RESET_IND:
- printf( "\tN_RESET_IND\n" );
- printf( "\treason:\t\t%d\n", primitive->reset_ind.RESET_reason );
- printf( "\torigin:\t\t%d\n", primitive->reset_ind.RESET_orig );
- break;
-
- case N_RESET_REQ:
- printf( "\tN_RESET_REQ\n" );
- printf( "\treason:\t\t%d\n", primitive->reset_req.RESET_reason );
- break;
-
- case N_RESET_RES:
- printf( "\tN_RESET_RES\n" );
- break;
-
- case N_UDERROR_IND:
- printf( "\tN_UDERROR_IND\n" );
- break;
-
- case N_UNBIND_REQ:
- printf( "\tN_UNBIND_REQ\n" );
- break;
-
- case N_UNITDATA_REQ:
- printf( "\tN_UNITDATA_REQ\n" );
- break;
-
- case N_UNITDATA_IND:
- printf( "\tN_UNITDATA_IND\n" );
- break;
-
- default:
- (void) printf( "Unknown NPI error %d", primitive->PRIM_type );
- return 0;
- }
-}
-#endif /* DEBUG */
-
-/* it looks like signal handling is not needed with streams! */
-/* x25oobh() - handle SIGURG signals - take from isode ? */
-
-#endif /* IBMX25 */
-
-#ifndef NOHTTP
-/*
- Which time.h files to include... See ckcdeb.h for defaults.
- Note that 0, 1, 2, or all 3 of these can be included according to
- the symbol definitions.
-*/
-#ifndef NOTIMEH
-#ifdef TIMEH
-#include <time.h>
-#endif /* TIMEH */
-#endif /* NOTIMEH */
-
-#ifndef NOSYSTIMEH
-#ifdef SYSTIMEH
-#include <sys/time.h>
-#endif /* SYSTIMEH */
-#endif /* NOSYSTIMEH */
-
-#ifndef NOSYSTIMEBH
-#ifdef SYSTIMEBH
-#include <sys/timeb.h>
-#endif /* SYSTIMEBH */
-#endif /* NOSYSTIMEBH */
-
-#ifndef TIMEH
-#ifndef SYSTIMEH
-#ifndef SYSTIMEBH
-#ifdef Plan9
-#include <sys/time.h>
-#else
-#ifdef AIX41
-#include <time.h>
-#else
-#ifdef SUNOS4
-#include <sys/time.h>
-#else
-#ifdef SYSTIMEH
-#include <sys/time.h>
-#else
-#ifdef POSIX
-#include <posix/time.h>
-#else
-#ifdef CLIX
-#include <sys/time.h>
-#else
-#ifdef OS2
-#include <time.h>
-#else
-#include <time.h>
-/* #include <utime.h> */
-#endif /* OS2 */
-#endif /* CLIX */
-#endif /* POSIX */
-#endif /* SYSTIMEH */
-#endif /* SUNOS4 */
-#endif /* AIX41 */
-#endif /* Plan9 */
-#endif
-#endif
-#endif
-
-#ifdef OS2
-#include <sys/utime.h>
-#ifdef NT
-#define utimbuf _utimbuf
-#endif /* NT */
-#define utime _utime
-#else
-#ifdef SYSUTIMEH /* <sys/utime.h> if requested, */
-#include <sys/utime.h> /* for extra fields required by */
-#else /* 88Open spec. */
-#ifdef UTIMEH /* or <utime.h> if requested */
-#include <utime.h> /* (SVR4, POSIX) */
-#define SYSUTIMEH /* Use this for both cases. */
-#endif /* UTIMEH */
-#endif /* SYSUTIMEH */
-#endif /* OS2 */
-
-#ifdef VMS /* SMS 2007/02/15 */
-#include "ckvrtl.h"
-#endif /* def VMS */
-
-#ifndef HTTP_VERSION
-#define HTTP_VERSION "HTTP/1.1"
-#endif /* HTTP_VERSION */
-
-#ifdef CMDATE2TM
-time_t
-#ifdef CK_ANSIC
-http_date(char * date)
-#else
-http_date(date) char * date;
-#endif /* CK_ANSIC */
-/* http_date */ {
- /* HTTP dates are of the form: "Sun, 06 Oct 1997 20:11:47 GMT" */
- /* There are two older formats which we are required to parse
- * that we currently do not:
- *
- * RFC 850: "Sunday, 06-Oct-97 20:11:47 GMT"
- * asctime(): "Sun Nov 6 20:11:47 1997"
- *
- * However, it is required that all dates be sent in the form we
- * do accept. The other two formats are for compatibility with
- * really old servers.
- */
- extern char cmdatebuf[18];
- struct tm t_tm;
- time_t t;
- char ldate[32];
- int j;
-
- j = ckindex(",",date,0,0,0);
- ckstrncpy(ldate,&date[j+1],25);
-
- { /*
- cmcvtate() date changed to return a string pointer.
- fdc, 12 Aug 2001.
- */
- char * dp;
- dp = (char *)cmcvtdate(ldate,0); /* Convert to normal form */
- if (!dp)
- return(0);
- t_tm = *cmdate2tm(dp,1);
- }
-/*
- From Lucas Hart, 5 Dec 2001:
- "On the systems to which I have access (SunOS 4.1.1, Solaris 8, and Tru64),
- setting tm_isdst to -1 maintains the correct timezone offsets, i.e., writes
- the specified (GMT) time if the buffer size is 21, or the contemporaneous
- localtime if the buffer size is 25. Perhaps tm_isdst should be set in
- cmdate2tm(), rather than only in http_date."
-*/
-#ifndef NOTM_ISDST /* For platforms where */
- t_tm.tm_isdst = -1; /* tm_isdst doesn't exist. */
-#endif /* NOTM_ISDST */
-
- t = mktime(&t_tm); /* NOT PORTABLE */
-
-#ifdef XX_TIMEZONE
- t -= _timezone;
-#endif /* XX_TIMEZONE */
-
- return(t);
-}
-#endif /* CMDATE2TM */
-
-char *
-http_now() {
- static char nowstr[32];
-#ifdef CMDATE2TM
- struct tm *gmt;
- time_t ltime; /* NOT PORTABLE */
-
- time(<ime);
-
- gmt = gmtime(<ime); /* PROBABLY NOT PORTABLE */
- strftime(nowstr,32,"%a, %d %b %Y %H:%M:%S GMT",gmt); /* NOT PORTABLE */
- /* not only is it not portable but it's locale-dependent */
-#else
-/*
- This is hopeless. First of all, it seems that HTTP wants Day and Month
- NAMES? In English? Whose idea was that? Even worse, the date/time must be
- expressed in Zulu (UTC (GMT)), and converting from local time to GMT is a
- nightmare. Every platform does it differently, if at all -- even if we
- restrict ourselves to UNIX. For example (quoting from recent C-Kermit edit
- history), "Fixed a longstanding bug in the BSDI version, in which incoming
- file dates were set in GMT rather than local time. It seems in 4.4BSD,
- localtime() does not return the local time, but rather Zero Meridian (Zulu)
- time (GMT), and must be adjusted by the tm_gmtoff value." Swell. For
- greater appreciation of the scope of the problem, just take a look at the
- time-related #ifdefs in ckutio.c. The only right way to do this is to add
- our own portable API for converting between local time and GMT/UTC/Zulu
- that shields us not only from UNIXisms like time_t and struct tm, but also
- the unbelievable amount of differences in time-related APIs -- e.g. is
- "timezone" an external variable or a function; which header file(s) do we
- include, etc etc etc. It's a major project.
-*/
- int x;
- x = cmcvtdate("",1);
-
-Evidently this code is not used -- if it is, it must be fixed to use
-new (aug 2001) cmcvtdate() calling conventions.
-
- if (x < 0)
- return("");
-/* yyyymmdd hh:mm:ss */
-/* 01234567890123456 */
- nowstr[0] = 'X'; /* 1st letter of day */
- nowstr[1] = 'x'; /* 2nd letter of day */
- nowstr[2] = 'x'; /* 3rd letter of day */
- nowstr[3] = ',';
- nowstr[4] = ' ';
- nowstr[5] = cmdate[6];
- nowstr[6] = cmdate[7];
- nowstr[7] = ' ';
- nowstr[8] = ' '; /* first letter of month */
- nowstr[9] = ' '; /* second letter of month */
- nowstr[10] = ' '; /* third letter of month */
- nowstr[11] = ' ';
- nowstr[12] = cmdate[0];
- nowstr[13] = cmdate[1];
- nowstr[14] = cmdate[2];
- nowstr[15] = cmdate[3];
- nowstr[16] = ' ';
- nowstr[17] = cmdate[9];
- nowstr[18] = cmdate[10];
- nowstr[19] = cmdate[11];
- nowstr[20] = cmdate[12];
- nowstr[21] = cmdate[13];
- nowstr[22] = cmdate[14];
- nowstr[23] = cmdate[15];
- nowstr[24] = cmdate[16];
- nowstr[25] = ' ';
- nowstr[26] = 'G';
- nowstr[27] = 'M';
- nowstr[28] = 'T';
- nowstr[29] = '\0';
-#endif /* CMDATE2TM */
- return(nowstr);
-}
-
-#ifndef OS2
-#ifndef CK_AUTHENTICATION
-/* from ckuusr.h, which this module normally doesn't include */
-_PROTOTYP( int dclarray, (char, int) );
-#endif /* CK_AUTHENTICATION */
-#endif /* OS2 */
-/*
- Assign http response pairs to given array.
- For best results, response pairs should contain no spaces.
-
- Call with:
- resp = pointer to response list.
- n = size of response list.
- array = array letter.
- Returns:
- 0 on failure.
- >= 1, size of array, on success.
-*/
-static int
-#ifdef CK_ANSIC
-http_mkarray(char ** resp, int n, char array)
-#else
-http_mkarray(resp, n, array) char ** resp; int n; char array;
-#endif /* CK_ANSIC */
-{
-#ifndef NOSPL
- int i, x;
- char ** ap;
- extern char ** a_ptr[];
- extern int a_dim[];
-
- if (!array || n <= 0)
- return(0);
- if ((x = dclarray(array,n)) < 0) {
- printf("?Array declaration failure\n");
- return(-9);
- }
- /* Note: argument array is 0-based but Kermit array is 1-based */
- ap = a_ptr[x];
- ap[0] = NULL; /* 0th element is empty */
- for (i = 1; i <= n; i++) {
- ap[i] = resp[i-1]; /* If resp elements were malloc'd */
- resp[i-1] = NULL;
- }
- a_dim[x] = n;
- return(n);
-#else
- return(0);
-#endif /* NOSPL */
-}
-
-#define HTTPHEADCNT 64
-int
-http_get_chunk_len()
-{
- int len = 0;
- int i = 0, j = -1;
- char buf[24];
- int ch;
-
- while ((ch = http_inc(0)) >= 0 && i < 24) {
- buf[i] = ch;
- if ( buf[i] == ';' ) /* Find chunk-extension (if any) */
- j = i;
- if ( buf[i] == 10 ) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- buf[i] = '\0';
- break;
- }
- i++;
- }
- if ( i < 24 ) { /* buf now contains len in Hex */
- len = hextoulong(buf, j == -1 ? i : j-1);
- }
-
- return(len);
-}
-
-int
-http_isconnected()
-{
- return(httpfd != -1);
-}
-
-char *
-http_host()
-{
- return(httpfd != -1 ? http_host_port : "");
-}
-
-char *
-http_security()
-{
- if ( httpfd == -1 )
- return("NULL");
-#ifdef CK_SSL
- if (tls_http_active_flag) {
- SSL_CIPHER * cipher;
- const char *cipher_list;
- static char buf[128];
- buf[0] = NUL;
- cipher = SSL_get_current_cipher(tls_http_con);
- cipher_list = SSL_CIPHER_get_name(cipher);
- SSL_CIPHER_description(cipher,buf,sizeof(buf));
- return(buf);
- }
-#endif /* CK_SSL */
- return("NULL");
-}
-
-int
-http_reopen()
-{
- int rc = 0;
- char * s = NULL; /* strdup is not portable */
- if ( tcp_http_proxy ) {
- char * p;
- makestr(&s,(char *)http_host_port);
- p = s;
- while (*p != '\0' && *p != ':') p++; /* Look for colon */
- if (*p == ':') { /* Have a colon */
- *p++ = '\0'; /* Get service name or number */
- } else {
- p="http";
- }
- rc = http_open(s,p,http_ssl,NULL,0,http_agent);
- } else {
- makestr(&s,(char *)http_ip);
- rc = http_open(s,ckuitoa(http_port),http_ssl,NULL,0,http_agent);
- }
- free(s);
- return(rc);
-}
-
-
-int
-#ifdef CK_ANSIC
-http_open(char * hostname, char * svcname, int use_ssl, char * rdns_name,
- int rdns_len, char * agent)
-#else /* CK_ANSIC */
-http_open(hostname, svcname, use_ssl, rdns_name, rdns_len, agent)
- char * hostname;
- char * svcname;
- int use_ssl;
- char * rdns_name;
- int rdns_len;
- char * agent;
-#endif /* CK_ANSIC */
-{
- char namecopy[NAMECPYL];
- char *p;
- int i, x, dns = 0;
-#ifdef TCPSOCKET
- int isconnect = 0;
-#ifdef SO_OOBINLINE
- int on = 1;
-#endif /* SO_OOBINLINE */
- struct servent *service=NULL;
- struct hostent *host=NULL;
- struct sockaddr_in r_addr;
- struct sockaddr_in sin;
- struct sockaddr_in l_addr;
- GSOCKNAME_T l_slen;
-#ifdef EXCELAN
- struct sockaddr_in send_socket;
-#endif /* EXCELAN */
-
-#ifdef INADDRX
-/* inet_addr() is of type struct in_addr */
-#ifdef datageneral
- extern struct in_addr inet_addr();
-#else
-#ifdef HPUX5WINTCP
- extern struct in_addr inet_addr();
-#endif /* HPUX5WINTCP */
-#endif /* datageneral */
- struct in_addr iax;
-#else
-#ifdef INADDR_NONE
- struct in_addr iax;
-#else /* INADDR_NONE */
- long iax;
-#endif /* INADDR_NONE */
-#endif /* INADDRX */
-
- if ( rdns_name == NULL || rdns_len < 0 )
- rdns_len = 0;
-
- *http_ip = '\0'; /* Initialize IP address string */
- namecopy[0] = '\0';
-
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"http_open hostname",hostname,0);
- debug(F110,"http_open svcname",svcname,0);
- }
-#endif /* DEBUG */
- if (!hostname) hostname = "";
- if (!svcname) svcname = "";
- if (!*hostname || !*svcname) return(-1);
-
-
- service = ckgetservice(hostname,svcname,http_ip,20);
-
- if (service == NULL) {
- if ( !quiet )
- printf("?Invalid service: %s\r\n",svcname);
- return(-1);
- }
-
- /* For HTTP connections we must preserve the original hostname and */
- /* service requested so we can include them in the Host header. */
- ckmakmsg(http_host_port,sizeof(http_host_port),hostname,":",
- ckuitoa(ntohs(service->s_port)),NULL);
- http_port = ntohs(service->s_port);
- http_ssl = use_ssl;
- debug(F111,"http_open",http_host_port,http_port);
-
- /* 'http_ip' contains the IP address to which we want to connect */
- /* 'svcnam' contains the service name */
- /* 'service->s_port' contains the port number in network byte order */
-
- /* If we are using an http proxy, we need to create a buffer containing */
- /* hostname:port-number */
- /* to pass to the http_connect() function. Then we need to replace */
- /* 'namecopy' with the name of the proxy server and the service->s_port */
- /* with the port number of the proxy (default port 80). */
-
- if ( tcp_http_proxy ) {
-
- ckmakmsg(proxycopy,sizeof(proxycopy),hostname,":",
- ckuitoa(ntohs(service->s_port)),NULL);
- ckstrncpy(namecopy,tcp_http_proxy,NAMECPYL);
-
- p = namecopy; /* Was a service requested? */
- while (*p != '\0' && *p != ':') p++; /* Look for colon */
- if (*p == ':') { /* Have a colon */
- debug(F110,"http_open name has colon",namecopy,0);
- *p++ = '\0'; /* Get service name or number */
- } else {
- strcpy(++p,"http");
- }
-
- service = ckgetservice(namecopy,p,http_ip,20);
- if (!service) {
- fprintf(stderr, "Can't find port for service %s\n", p);
-#ifdef TGVORWIN
- debug(F101,"http_open can't get service for proxy","",socket_errno);
-#else
- debug(F101,"http_open can't get service for proxy","",errno);
-#endif /* TGVORWIN */
- errno = 0; /* (rather than mislead) */
- return(-1);
- }
-
- /* copy the proxyname and remove the service if any so we can use
- * it as the hostname
- */
- ckstrncpy(namecopy,tcp_http_proxy,NAMECPYL);
- p = namecopy; /* Was a service requested? */
- while (*p != '\0' && *p != ':') p++; /* Look for colon */
- if (*p == ':') { /* Have a colon */
- *p = '\0'; /* terminate string */
- }
- hostname = namecopy; /* use proxy as hostname */
- }
-
- /* Set up socket structure and get host address */
- bzero((char *)&r_addr, sizeof(r_addr));
- debug(F100,"http_open bzero ok","",0);
-
-#ifdef INADDR_NONE
- debug(F101,"http_open INADDR_NONE defined","",INADDR_NONE);
-#else /* INADDR_NONE */
- debug(F100,"http_open INADDR_NONE not defined","",0);
-#endif /* INADDR_NONE */
-#ifdef INADDRX
- debug(F100,"http_open INADDRX defined","",0);
-#else /* INADDRX */
- debug(F100,"http_open INADDRX not defined","",0);
-#endif /* INADDRX */
-
-#ifndef NOMHHOST
-#ifdef INADDRX
- iax = inet_addr(http_ip[0]?http_ip:hostname);
- debug(F111,"http_open inet_addr",http_ip[0]?http_ip:hostname,iax.s_addr);
-#else /* INADDRX */
-#ifdef INADDR_NONE
- iax.s_addr = inet_addr(http_ip[0]?http_ip:hostname);
- debug(F111,"http_open inet_addr",http_ip[0]?http_ip:hostname,iax.s_addr);
-#else /* INADDR_NONE */
-#ifndef datageneral
- iax = (unsigned int) inet_addr(http_ip[0]?http_ip:hostname);
-#else
- iax = -1L;
-#endif /* datageneral */
- debug(F111,"http_open inet_addr",http_ip[0]?http_ip:hostname,iax);
-#endif /* INADDR_NONE */
-#endif /* INADDRX */
-
- dns = 0;
- if (
-#ifdef INADDR_NONE
-/* This might give warnings on 64-bit platforms but they should be harmless */
-/* because INADDR_NONE should be all 1's anyway, thus the OR part is */
-/* probably superfluous -- not sure why it's even there, maybe it should be */
-/* removed. */
- iax.s_addr == INADDR_NONE /* || iax.s_addr == (unsigned long) -1L */
-#else /* INADDR_NONE */
- iax == -1
-#endif /* INADDR_NONE */
- ) {
- if (!quiet) {
- printf(" DNS Lookup... ");
- fflush(stdout);
- }
- if ((host = gethostbyname(http_ip[0] ? http_ip : hostname)) != NULL) {
- debug(F100,"http_open gethostbyname != NULL","",0);
- host = ck_copyhostent(host);
- dns = 1; /* Remember we performed dns lookup */
- r_addr.sin_family = host->h_addrtype;
- if (tcp_rdns && host->h_name && host->h_name[0] && (rdns_len > 0)
- && (tcp_http_proxy == NULL)
- )
- ckmakmsg(rdns_name,rdns_len,host->h_name,":",svcname,NULL);
-
-#ifdef HADDRLIST
-#ifdef h_addr
- /* This is for trying multiple IP addresses - see <netdb.h> */
- if (!(host->h_addr_list))
- return(-1);
- bcopy(host->h_addr_list[0],
- (caddr_t)&r_addr.sin_addr,
- host->h_length
- );
-#else
- bcopy(host->h_addr, (caddr_t)&r_addr.sin_addr, host->h_length);
-#endif /* h_addr */
-#else /* HADDRLIST */
- bcopy(host->h_addr, (caddr_t)&r_addr.sin_addr, host->h_length);
-#endif /* HADDRLIST */
-#ifdef COMMENT
-#ifndef EXCELAN
- debug(F111,"BCOPY","host->h_addr",host->h_addr);
-#endif /* EXCELAN */
- debug(F111,"BCOPY"," (caddr_t)&r_addr.sin_addr",
- (caddr_t)&r_addr.sin_addr);
- debug(F111,"BCOPY"," r_addr.sin_addr.s_addr",
- r_addr.sin_addr.s_addr);
-#endif /* COMMENT */
- debug(F111,"BCOPY","host->h_length",host->h_length);
- }
- }
-#endif /* NOMHHOST */
-
- if (!dns) {
-#ifdef INADDRX
-/* inet_addr() is of type struct in_addr */
- struct in_addr ina;
- unsigned long uu;
- debug(F100,"http_open gethostbyname == NULL: INADDRX","",0);
- ina = inet_addr(http_ip[0]?http_ip:hostname);
- uu = *(unsigned int *)&ina;
-#else /* Not INADDRX */
-/* inet_addr() is unsigned long */
- unsigned long uu;
- debug(F100,"http_open gethostbyname == NULL: Not INADDRX","",0);
- uu = inet_addr(http_ip[0]?http_ip:hostname);
-#endif /* INADDRX */
- debug(F101,"http_open uu","",uu);
- if (
-#ifdef INADDR_NONE
- !(uu == INADDR_NONE || uu == (unsigned int) -1L)
-#else /* INADDR_NONE */
- uu != ((unsigned long)-1)
-#endif /* INADDR_NONE */
- ) {
- r_addr.sin_addr.s_addr = uu;
- r_addr.sin_family = AF_INET;
- } else {
-#ifdef VMS
- fprintf(stdout, "\r\n"); /* complete any previous message */
-#endif /* VMS */
- fprintf(stderr, "Can't get address for %s\n",
- http_ip[0]?http_ip:hostname);
-#ifdef TGVORWIN
- debug(F101,"http_open can't get address","",socket_errno);
-#else
- debug(F101,"http_open can't get address","",errno);
-#endif /* TGVORWIN */
- errno = 0; /* Rather than mislead */
- return(-1);
- }
- }
-
- /* Get a file descriptor for the connection. */
-
- r_addr.sin_port = service->s_port;
- ckstrncpy(http_ip,(char *)inet_ntoa(r_addr.sin_addr),20);
- debug(F110,"http_open trying",http_ip,0);
- if (!quiet && *http_ip) {
- printf(" Trying %s... ", http_ip);
- fflush(stdout);
- }
-
- /* Loop to try additional IP addresses, if any. */
-
- do {
-#ifdef EXCELAN
- send_socket.sin_family = AF_INET;
- send_socket.sin_addr.s_addr = 0;
- send_socket.sin_port = 0;
- if ((httpfd = socket(SOCK_STREAM, (struct sockproto *)0,
- &send_socket, SO_REUSEADDR)) < 0)
-#else /* EXCELAN */
- if ((httpfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-#endif /* EXCELAN */
- {
-#ifdef EXCELAN
- experror("TCP socket error");
-#else
-#ifdef TGVORWIN
-#ifdef OLD_TWG
- errno = socket_errno;
-#endif /* OLD_TWG */
- socket_perror("TCP socket error");
- debug(F101,"http_open socket error","",socket_errno);
-#else
- perror("TCP socket error");
- debug(F101,"http_open socket error","",errno);
-#endif /* TGVORWIN */
-#endif /* EXCELAN */
- return (-1);
- }
- errno = 0;
-
- /* If a specific TCP address on the local host is desired we */
- /* must bind it to the socket. */
-#ifndef datageneral
- if (tcp_address) {
- int s_errno;
-
- debug(F110,"http_open binding socket to",tcp_address,0);
- bzero((char *)&sin,sizeof(sin));
- sin.sin_family = AF_INET;
-#ifdef INADDRX
- inaddrx = inet_addr(tcp_address);
- sin.sin_addr.s_addr = *(unsigned long *)&inaddrx;
-#else
- sin.sin_addr.s_addr = inet_addr(tcp_address);
-#endif /* INADDRX */
- sin.sin_port = 0;
- if (bind(httpfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- s_errno = socket_errno; /* Save error code */
-#ifdef TCPIPLIB
- socket_close(httpfd);
-#else /* TCPIPLIB */
- close(httpfd);
-#endif /* TCPIPLIB */
- httpfd = -1;
- errno = s_errno; /* and report this error */
- debug(F101,"http_open bind errno","",errno);
- return(-1);
- }
- }
-#endif /* datageneral */
-
-/* Now connect to the socket on the other end. */
-
-#ifdef EXCELAN
- if (connect(httpfd, &r_addr) < 0)
-#else
-#ifdef NT
- WSASafeToCancel = 1;
-#endif /* NT */
- if (connect(httpfd, (struct sockaddr *)&r_addr, sizeof(r_addr)) < 0)
-#endif /* EXCELAN */
- {
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
-#ifdef OS2
- i = socket_errno;
-#else /* OS2 */
-#ifdef TGVORWIN
- i = socket_errno;
-#else
- i = errno; /* Save error code */
-#endif /* TGVORWIN */
-#endif /* OS2 */
-#ifdef HADDRLIST
-#ifdef h_addr
- if (host && host->h_addr_list && host->h_addr_list[1]) {
- perror("");
- host->h_addr_list++;
- bcopy(host->h_addr_list[0],
- (caddr_t)&r_addr.sin_addr,
- host->h_length);
-
- ckstrncpy(http_ip,(char *)inet_ntoa(r_addr.sin_addr),20);
- debug(F110,"http_open h_addr_list",http_ip,0);
- if (!quiet && *http_ip) {
- printf(" Trying %s... ", http_ip);
- fflush(stdout);
- }
-#ifdef TCPIPLIB
- socket_close(httpfd); /* Close it. */
-#else
- close(httpfd);
-#endif /* TCPIPLIB */
- continue;
- }
-#endif /* h_addr */
-#endif /* HADDRLIST */
- http_close();
- httpfd = -1;
- errno = i; /* And report this error */
-#ifdef EXCELAN
- if (errno) experror("http_open connect");
-#else
-#ifdef TGVORWIN
- debug(F101,"http_open connect error","",socket_errno);
- /* if (errno) socket_perror("http_open connect"); */
-#ifdef OLD_TWG
- errno = socket_errno;
-#endif /* OLD_TWG */
- if (!quiet)
- socket_perror("http_open connect");
-#else /* TGVORWIN */
- debug(F101,"http_open connect errno","",errno);
-#ifdef VMS
- if (!quiet)
- perror("\r\nFailed");
-#else
- if (!quiet)
- perror("Failed");
-#endif /* VMS */
-#ifdef DEC_TCPIP
- if (!quiet)
- perror("http_open connect");
-#endif /* DEC_TCPIP */
-#ifdef CMU_TCPIP
- if (!quiet)
- perror("http_open connect");
-#endif /* CMU_TCPIP */
-#endif /* TGVORWIN */
-#endif /* EXCELAN */
- return(-1);
- }
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
- isconnect = 1;
- } while (!isconnect);
-
-#ifdef NON_BLOCK_IO
- on = 1;
- x = socket_ioctl(httpfd,FIONBIO,&on);
- debug(F101,"http_open FIONBIO","",x);
-#endif /* NON_BLOCK_IO */
-
- /* We have succeeded in connecting to the HTTP PROXY. So now we */
- /* need to attempt to connect through the proxy to the actual host */
- /* If that is successful, we have to pretend that we made a direct */
- /* connection to the actual host. */
-
- if ( tcp_http_proxy ) {
-#ifdef OS2
- if (!agent)
- agent = "Kermit 95"; /* Default user agent */
-#else
- if (!agent)
- agent = "C-Kermit";
-#endif /* OS2 */
-
- if (http_connect(httpfd,
- tcp_http_proxy_agent ? tcp_http_proxy_agent : agent,
- NULL,
- tcp_http_proxy_user,
- tcp_http_proxy_pwd,
- 0,
- proxycopy
- ) < 0) {
- http_close();
- return(-1);
- }
- }
-
-#ifdef SO_OOBINLINE
- /* See note on SO_OOBINLINE in netopen() */
-#ifdef datageneral
- setsockopt(httpfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef BSD43
- setsockopt(httpfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef OSF1
- setsockopt(httpfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef POSIX
- setsockopt(httpfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef MOTSV88R4
- setsockopt(httpfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef SOLARIS
-/*
- Maybe this applies to all SVR4 versions, but the other (else) way has been
- compiling and working fine on all the others, so best not to change it.
-*/
- setsockopt(httpfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef OSK
- setsockopt(httpfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef OS2
- {
- int rc;
- rc = setsockopt(httpfd,
- SOL_SOCKET,
- SO_OOBINLINE,
- (char *) &on,
- sizeof on
- );
- debug(F111,"setsockopt SO_OOBINLINE",on ? "on" : "off" ,rc);
- }
-#else
-#ifdef VMS /* or, at least, VMS with gcc */
- setsockopt(httpfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
-#ifdef CLIX
- setsockopt(httpfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
-#else
- setsockopt(httpfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof on);
-#endif /* CLIX */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* OSK */
-#endif /* SOLARIS */
-#endif /* MOTSV88R4 */
-#endif /* POSIX */
-#endif /* BSD43 */
-#endif /* OSF1 */
-#endif /* datageneral */
-#endif /* SO_OOBINLINE */
-
-#ifndef NOTCPOPTS
-#ifndef datageneral
-#ifdef SOL_SOCKET
-#ifdef TCP_NODELAY
- no_delay(ttyfd,tcp_nodelay);
-#endif /* TCP_NODELAY */
-#ifdef SO_KEEPALIVE
- keepalive(ttyfd,tcp_keepalive);
-#endif /* SO_KEEPALIVE */
-#ifdef SO_LINGER
- ck_linger(ttyfd,tcp_linger, tcp_linger_tmo);
-#endif /* SO_LINGER */
-#ifdef SO_SNDBUF
- sendbuf(ttyfd,tcp_sendbuf);
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
- recvbuf(ttyfd,tcp_recvbuf);
-#endif /* SO_RCVBUF */
-#endif /* SOL_SOCKET */
-#endif /* datageneral */
-#endif /* NOTCPOPTS */
-
-#ifndef datageneral
- /* Find out our own IP address. */
- /* We need the l_addr structure for [E]KLOGIN. */
- l_slen = sizeof(l_addr);
- bzero((char *)&l_addr, l_slen);
-#ifndef EXCELAN
- if (!getsockname(httpfd, (struct sockaddr *)&l_addr, &l_slen)) {
- char * s = (char *)inet_ntoa(l_addr.sin_addr);
- ckstrncpy(myipaddr, s, 20);
- debug(F110,"getsockname",myipaddr,0);
- }
-#endif /* EXCELAN */
-#endif /* datageneral */
-
-/* See note in netopen() on Reverse DNS lookups */
- if (tcp_rdns == SET_ON) {
-#ifdef NT
- if (isWin95())
- sleep(1);
-#endif /* NT */
- if (!quiet) {
- printf(" Reverse DNS Lookup... ");
- fflush(stdout);
- }
- if (host = gethostbyaddr((char *)&r_addr.sin_addr,4,PF_INET)) {
- char * s;
- host = ck_copyhostent(host);
- debug(F100,"http_open gethostbyname != NULL","",0);
- if (!quiet) {
- printf("(OK)\n");
- fflush(stdout);
- }
- s = host->h_name;
- if (!s) { /* This can happen... */
- debug(F100,"http_open host->h_name is NULL","",0);
- s = "";
- }
- /* Something is wrong with inet_ntoa() on HPUX 10.xx */
- /* The compiler says "Integral value implicitly converted to */
- /* pointer in assignment." The prototype is right there */
- /* in <arpa/inet.h> so what's the problem? */
- /* Ditto in HP-UX 5.x, but not 8.x or 9.x... */
- if (!*s) { /* No name so substitute the address */
- debug(F100,"http_open host->h_name is empty","",0);
- s = inet_ntoa(r_addr.sin_addr); /* Convert address to string */
- if (!s) /* Trust No 1 */
- s = "";
- if (*s) { /* If it worked, use this string */
- ckstrncpy(http_ip,s,20);
- }
- s = http_ip; /* Otherwise stick with the IP */
- if (!*s) /* or failing that */
- s = http_host_port; /* the name we were called with. */
- }
- if (*s) /* return the rdns name */
- ckmakmsg(rdns_name,rdns_len,s,":",svcname,NULL);
-
- if (!quiet && *s
-#ifndef NOICP
- && !doconx
-#endif /* NOICP */
- ) {
- printf(" %s connected on port %s\n",s,
- ckuitoa(ntohs(service->s_port)));
-#ifdef BETADEBUG
- /* This is simply for testing the DNS entries */
- if (host->h_aliases) {
- char ** a = host->h_aliases;
- while (*a) {
- printf(" alias => %s\n",*a);
- a++;
- }
- }
-#endif /* BETADEBUG */
- }
- } else {
- if (!quiet) printf("Failed.\n");
- }
- } else if (!quiet) printf("(OK)\n");
- if (!quiet) fflush(stdout);
-
-
- if ( tcp_http_proxy ) {
- /* Erase the IP address since we cannot reuse it */
- http_ip[0] = '\0';
- } else {
- /* This should already have been done but just in case */
- ckstrncpy(http_ip,(char *)inet_ntoa(r_addr.sin_addr),20);
- }
- makestr(&http_agent,agent);
-
-#ifdef CK_SSL
- if (use_ssl && ck_ssleay_is_installed()) {
- if (!ssl_http_init(hostname)) {
- if (bio_err!=NULL) {
- BIO_printf(bio_err,"ssl_tn_init() failed\n");
- ERR_print_errors(bio_err);
- } else {
- fflush(stderr);
- fprintf(stderr,"ssl_tn_init() failed\n");
- ERR_print_errors_fp(stderr);
- }
- http_close();
- return(-1);
- } else if ( ck_ssl_http_client(httpfd,hostname) < 0 ) {
- http_close();
- return(-1);
- }
- }
-#endif /* CK_SSL */
-#endif /* TCPSOCKET */
-
- return(0); /* Done. */
-}
-
-int
-#ifdef CK_ANSIC
-http_close(VOID)
-#else /* CK_ANSIC */
-http_close()
-#endif /* CK_ANSIC */
-{
- int x = 0;
- debug(F101,"http_close","",httpfd);
-
-#ifdef HTTP_BUFFERING
- http_count = 0;
- http_bufp = 0;
-#endif /* HTTP_BUFFERING */
-
- if (httpfd == -1) /* Was open? */
- return(0); /* Wasn't. */
-
-#ifndef OS2
- if (httpfd > -1) /* Was. */
-#endif /* OS2 */
- {
-#ifdef CK_SSL
- if (tls_http_active_flag) {
- if (ssl_debug_flag)
- BIO_printf(bio_err,"calling SSL_shutdown\n");
- SSL_shutdown(tls_http_con);
- tls_http_active_flag = 0;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- x = socket_close(httpfd); /* Close it. */
-#else
-#ifndef OS2
- x = close(httpfd);
-#endif /* OS2 */
-#endif /* TCPIPLIB */
- }
- httpfd = -1; /* Mark it as closed. */
- /* do not erase http_host_port, http_ip, http_port so they */
- /* can be used by http_reopen() */
- return(x);
-}
-
-
-/* http_tol()
- * Call with s = pointer to string, n = length.
- * Returns number of bytes actually written on success, or
- * -1 on i/o error, -2 if called improperly.
- */
-
-int
-http_tol(s,n) CHAR *s; int n; {
- int count = 0;
- int len = n;
- int try = 0;
-
- if (httpfd == -1) {
- debug(F100,"http_tol socket is closed","",0);
- return -1;
- }
- debug(F101,"http_tol TCPIPLIB ttnet","",ttnet);
-#ifdef COMMENT
- ckhexdump("http_tol",s,n);
-#endif /* COMMENT */
-
-#ifdef CK_SSL
- if (tls_http_active_flag) {
- int error, r;
- /* Write using SSL */
- ssl_retry:
- r = SSL_write(tls_http_con, s, len /* >1024?1024:len */);
- switch (SSL_get_error(tls_http_con,r)) {
- case SSL_ERROR_NONE:
- debug(F111,"http_tol","SSL_write",r);
- if ( r == len )
- return(n);
- s += r;
- len -= r;
- goto ssl_retry;
- case SSL_ERROR_WANT_WRITE:
- debug(F100,"http_tol SSL_ERROR_WANT_WRITE","",0);
- return(-1);
- case SSL_ERROR_WANT_READ:
- debug(F100,"http_tol SSL_ERROR_WANT_READ","",0);
- return(-1);
- case SSL_ERROR_SYSCALL:
- if ( r == 0 ) { /* EOF */
- http_close();
- return(-2);
- } else {
- int rc = -1;
-#ifdef NT
- int gle = GetLastError();
- debug(F111,"http_tol SSL_ERROR_SYSCALL",
- "GetLastError()",gle);
- rc = os2socketerror(gle);
- if (rc == -1)
- rc = -2;
- else if ( rc == -2 )
- return -1;
-#endif /* NT */
- return(rc);
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- debug(F100,"http_tol SSL_ERROR_WANT_X509_LOOKUP","",0);
- http_close();
- return(-2);
- case SSL_ERROR_SSL:
- debug(F100,"http_tol SSL_ERROR_SSL","",0);
- http_close();
- return(-2);
- case SSL_ERROR_ZERO_RETURN:
- debug(F100,"http_tol SSL_ERROR_ZERO_RETURN","",0);
- http_close();
- return(-2);
- default:
- debug(F100,"http_tol SSL_ERROR_?????","",0);
- http_close();
- return(-2);
- }
- }
-#endif /* CK_SSL */
-
- http_tol_retry:
- try++; /* Increase the try counter */
-
- {
-#ifdef BSDSELECT
- fd_set wfds;
- struct timeval tv;
-
- debug(F101,"http_tol BSDSELECT","",0);
- tv.tv_usec = 0L;
- tv.tv_sec=30;
-#ifdef NT
- WSASafeToCancel = 1;
-#endif /* NT */
-#ifdef STREAMING
- do_select:
-#endif /* STREAMING */
- FD_ZERO(&wfds);
- FD_SET(httpfd, &wfds);
- if (select(FD_SETSIZE, NULL,
-#ifdef __DECC
-#ifndef __DECC_VER
- (int *)
-#endif /* __DECC_VER */
-#endif /* __DECC */
- &wfds, NULL, &tv) < 0) {
- int s_errno = socket_errno;
- debug(F101,"http_tol select failed","",s_errno);
-#ifdef BETADEBUG
- printf("http_tol select failed: %d\n", s_errno);
-#endif /* BETADEBUG */
-#ifdef NT
- WSASafeToCancel = 0;
- if (!win95selectbug)
-#endif /* NT */
- return(-1);
- }
- if (!FD_ISSET(httpfd, &wfds)) {
-#ifdef STREAMING
- if (streaming)
- goto do_select;
-#endif /* STREAMING */
- debug(F111,"http_tol","!FD_ISSET",ttyfd);
-#ifdef NT
- WSASafeToCancel = 0;
- if (!win95selectbug)
-#endif /* NT */
- return(-1);
- }
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
-#else /* BSDSELECT */
-#ifdef IBMSELECT
- {
- int tries = 0;
- debug(F101,"http_tol IBMSELECT","",0);
- while (select(&httpfd, 0, 1, 0, 1000) != 1) {
- int count;
- if (tries++ >= 60) {
- /* if after 60 seconds we can't get permission to write */
- debug(F101,"http_tol select failed","",socket_errno);
- return(-1);
- }
-#ifdef COMMENT
- if ((count = http_tchk()) < 0) {
- debug(F111,"http_tol","http_tchk()",count);
- return(count);
- }
-#endif /* COMMENT */
- }
- }
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
-#ifdef TCPIPLIB
- if ((count = socket_write(httpfd,s,n)) < 0) {
- int s_errno = socket_errno; /* maybe a function */
- debug(F101,"http_tol socket_write error","",s_errno);
-#ifdef OS2
- if (os2socketerror(s_errno) < 0)
- return(-2);
-#endif /* OS2 */
- return(-1); /* Call it an i/o error */
- }
-#else /* TCPIPLIB */
- if ((count = write(httpfd,s,n)) < 0) {
- debug(F101,"http_tol socket_write error","",errno);
- return(-1); /* Call it an i/o error */
- }
-#endif /* TCPIPLIB */
- if (count < n) {
- debug(F111,"http_tol socket_write",s,count);
- if (try > 25) {
- /* don't try more than 25 times */
- debug(F100,"http_tol tried more than 25 times","",0);
- return(-1);
- }
- if (count > 0) {
- s += count;
- n -= count;
- }
- debug(F111,"http_tol retry",s,n);
- goto http_tol_retry;
- } else {
- debug(F111,"http_tol socket_write",s,count);
- return(len); /* success - return total length */
- }
- }
-}
-
-int
-http_inc(timo) int timo; {
- int x=-1; unsigned char c; /* The locals. */
-
- if (httpfd == -1) {
-#ifdef HTTP_BUFFERING
- http_count = 0;
- http_bufp = 0;
-#endif /* HTTP_BUFFERING */
- debug(F100,"http_inc socket is closed","",0);
- return(-2);
- }
-
-#ifdef CK_SSL
- /*
- * In the case of OpenSSL, it is possible that there is still
- * data waiting in the SSL session buffers that has not yet
- * been read by Kermit. If this is the case we must process
- * it without calling select() because select() will not return
- * with an indication that there is data to be read from the
- * socket. If there is no data pending in the SSL session
- * buffers then fall through to the select() code and wait for
- * some data to arrive.
- */
- if (tls_http_active_flag) {
- int error;
-
- x = SSL_pending(tls_http_con);
- if (x < 0) {
- debug(F111,"http_inc","SSL_pending error",x);
- http_close();
- return(-1);
- } else if ( x > 0 ) {
- ssl_read:
- x = SSL_read(tls_http_con, &c, 1);
- error = SSL_get_error(tls_http_con,x);
- switch (error) {
- case SSL_ERROR_NONE:
- debug(F111,"http_inc SSL_ERROR_NONE","x",x);
- if (x > 0) {
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(c); /* Return character. */
- } else if (x < 0) {
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- } else {
- http_close();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- }
- case SSL_ERROR_WANT_WRITE:
- debug(F100,"http_inc SSL_ERROR_WANT_WRITE","",0);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- case SSL_ERROR_WANT_READ:
- debug(F100,"http_inc SSL_ERROR_WANT_READ","",0);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- case SSL_ERROR_SYSCALL:
- if ( x == 0 ) { /* EOF */
- http_close();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- } else {
- int rc = -1;
-#ifdef NT
- int gle = GetLastError();
- debug(F111,"http_inc SSL_ERROR_SYSCALL",
- "GetLastError()",gle);
- rc = os2socketerror(gle);
- if (rc == -1)
- rc = -2;
- else if ( rc == -2 )
- rc = -1;
-#endif /* NT */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(rc);
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- debug(F100,"http_inc SSL_ERROR_WANT_X509_LOOKUP","",0);
- http_close();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- case SSL_ERROR_SSL:
- debug(F100,"http_inc SSL_ERROR_SSL","",0);
-#ifdef COMMENT
- http_close();
-#endif /* COMMENT */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- case SSL_ERROR_ZERO_RETURN:
- debug(F100,"http_inc SSL_ERROR_ZERO_RETURN","",0);
- http_close();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- default:
- debug(F100,"http_inc SSL_ERROR_?????","",0);
- http_close();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- }
- }
- }
-#endif /* CK_SSL */
-
-#ifdef HTTP_BUFFERING
- /* Skip all the select() stuff if we have bytes buffered locally */
- if (http_count > 0)
- goto getfrombuffer;
-#endif /* HTTP_BUFFERING */
-
- {
-#ifdef BSDSELECT
- fd_set rfds;
- struct timeval tv;
- int timeout = timo < 0 ? -timo : 1000 * timo;
- debug(F101,"http_inc BSDSELECT","",timo);
-
- for ( ; timeout >= 0; timeout -= (timo ? 100 : 0)) {
- int rc;
- debug(F111,"http_inc","timeout",timeout);
- /* Don't move select() initialization out of the loop. */
- FD_ZERO(&rfds);
- FD_SET(httpfd, &rfds);
- tv.tv_sec = tv.tv_usec = 0L;
- if (timo)
- tv.tv_usec = (long) 100000L;
- else
- tv.tv_sec = 30;
-#ifdef NT
- WSASafeToCancel = 1;
-#endif /* NT */
- rc = select(FD_SETSIZE,
-#ifndef __DECC
- (fd_set *)
-#endif /* __DECC */
- &rfds, NULL, NULL, &tv);
- if (rc < 0) {
- int s_errno = socket_errno;
- debug(F111,"http_inc","select",rc);
- debug(F111,"http_inc","socket_errno",s_errno);
-#ifdef HTTP_BUFFERING
- http_count = 0;
- http_bufp = 0;
-#endif /* HTTP_BUFFERING */
- if (s_errno)
- return(-1);
- }
- debug(F111,"http_inc","select",rc);
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
- if (FD_ISSET(httpfd, &rfds)) {
- x = 0;
- break;
- } else {
- /* If waiting forever we have no way of knowing if the */
- /* socket closed so try writing a 0-length TCP packet */
- /* which should force an error if the socket is closed */
- if (!timo) {
-#ifdef TCPIPLIB
- if ((rc = socket_write(httpfd,"",0)) < 0) {
-#ifdef HTTP_BUFFERING
- http_count = 0;
- http_bufp = 0;
-#endif /* HTTP_BUFFERING */
- int s_errno = socket_errno;
- debug(F101,"http_inc socket_write error","",s_errno);
-#ifdef OS2
- if (os2socketerror(s_errno) < 0)
- return(-2);
-#endif /* OS2 */
- return(-1); /* Call it an i/o error */
- }
-#else /* TCPIPLIB */
- if ((rc = write(httpfd,"",0)) < 0) {
-#ifdef HTTP_BUFFERING
- http_count = 0;
- http_bufp = 0;
-#endif /* HTTP_BUFFERING */
- debug(F101,"http_inc socket_write error","",errno);
- return(-1); /* Call it an i/o error */
- }
-#endif /* TCPIPLIB */
- }
- continue;
- }
- }
-#ifdef NT
- WSASafeToCancel = 0;
-#endif /* NT */
-#else /* !BSDSELECT */
-#ifdef IBMSELECT
- /*
- Was used by OS/2, currently not used, but might come in handy some day...
- ... and it came in handy! For our TCP/IP layer, it avoids all the fd_set
- and timeval stuff since this is the only place where it is used.
- */
- int socket = httpfd;
- int timeout = timo < 0 ? -timo : 1000 * timo;
-
- debug(F101,"http_inc IBMSELECT","",timo);
- for ( ; timeout >= 0; timeout -= (timo ? 100 : 0)) {
- if (select(&socket, 1, 0, 0, 100L) == 1) {
- x = 0;
- break;
- }
- }
-#else /* !IBMSELECT */
- SELECT is required for this code
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
- }
-
- if (timo && x < 0) { /* select() timed out */
-#ifdef HTTP_BUFFERING
- http_count = 0;
- http_bufp = 0;
-#endif /* HTTP_BUFFERING */
- debug(F100,"http_inc select() timed out","",0);
- return(-1); /* Call it an i/o error */
- }
-
-#ifdef CK_SSL
- if ( tls_http_active_flag ) {
- int error;
- ssl_read2:
- x = SSL_read(tls_http_con, &c, 1);
- error = SSL_get_error(tls_http_con,x);
- switch (error) {
- case SSL_ERROR_NONE:
- debug(F111,"http_inc SSL_ERROR_NONE","x",x);
- if (x > 0) {
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(c); /* Return character. */
- } else if (x < 0) {
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- } else {
- http_close();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- }
- case SSL_ERROR_WANT_WRITE:
- debug(F100,"http_inc SSL_ERROR_WANT_WRITE","",0);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- case SSL_ERROR_WANT_READ:
- debug(F100,"http_inc SSL_ERROR_WANT_READ","",0);
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-1);
- case SSL_ERROR_SYSCALL:
- if ( x == 0 ) { /* EOF */
- http_close();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- } else {
- int rc = -1;
-#ifdef NT
- int gle = GetLastError();
- debug(F111,"http_inc SSL_ERROR_SYSCALL",
- "GetLastError()",gle);
- rc = os2socketerror(gle);
- if (rc == -1)
- rc = -2;
- else if ( rc == -2 )
- rc = -1;
-#endif /* NT */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(rc);
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- debug(F100,"http_inc SSL_ERROR_WANT_X509_LOOKUP","",0);
- http_close();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- case SSL_ERROR_SSL:
- debug(F100,"http_inc SSL_ERROR_SSL","",0);
-#ifdef COMMENT
- http_close();
-#endif /* COMMENT */
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- case SSL_ERROR_ZERO_RETURN:
- debug(F100,"http_inc SSL_ERROR_ZERO_RETURN","",0);
- http_close();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- default:
- debug(F100,"http_inc SSL_ERROR_?????","",0);
- http_close();
-#ifdef OS2
- ReleaseTCPIPMutex();
-#endif /* OS2 */
- return(-2);
- }
- }
-#endif /* CK_SSL */
-
-#ifdef HTTP_BUFFERING
-/*
- Buffering code added by fdc 15 Dec 2005 for non-SSL case only because HTTP
- GETs were orders of magnitude too slow due to the single-byte read()s. The
- file-descriptor swapping is pretty gross, but the more elegant solution
- (calling a nettchk() like routine with the fd as a parameter) doesn't work,
- because nettchk() relies on too many other routines that, like itself, are
- hardwired for ttyfd.
-*/
- getfrombuffer:
- if (--http_count >= 0) {
- c = http_inbuf[http_bufp++];
- x = 1;
- } else {
- int savefd;
- savefd = ttyfd;
- ttyfd = httpfd;
- x = nettchk();
- ttyfd = savefd;
- debug(F101,"http_inc nettchk","",x);
- if (x > HTTP_INBUFLEN)
- x = HTTP_INBUFLEN;
-#ifdef TCPIPLIB
- x = socket_read(httpfd,http_inbuf,x);
-#else /* Not TCPIPLIB */
- x = read(httpfd,http_inbuf,x);
-#endif /* TCPIPLIB */
- http_count = 0;
- http_bufp = 0;
- if (x > 0) {
- c = http_inbuf[http_bufp++];
- http_count = x - 1;
- }
- }
-#else /* Not HTTP_BUFFERING */
-#ifdef TCPIPLIB
- x = socket_read(httpfd,&c,1);
-#else /* Not TCPIPLIB */
- x = read(httpfd,&c,1);
-#endif /* TCPIPLIB */
-#endif /* HTTP_BUFFERING */
-
- if (x <= 0) {
- int s_errno = socket_errno;
- debug(F101,"ttbufr socket_read","",x);
- debug(F101,"ttbufr socket_errno","",s_errno);
-#ifdef OS2
- if (x == 0 || os2socketerror(s_errno) < 0) {
- http_close();
- ReleaseTCPIPMutex();
- return(-2);
- }
- ReleaseTCPIPMutex();
- return(-1);
-#else /* OS2 */
- http_close(); /* *** *** */
- return(-2);
-#endif /* OS2 */
- }
- return(c);
-}
-
-void
-#ifdef CK_ANSIC
-http_set_code_reply(char * msg)
-#else
-http_set_code_reply(msg)
- char * msg;
-#endif /* CK_ANSIC */
-{
- char * p = msg;
- char buf[16];
- int i=0;
-
- while ( *p != SP && *p != NUL ) {
- buf[i] = *p;
- p++;
- i++;
- }
-
- http_code = atoi(buf);
-
- while ( *p == SP )
- p++;
-
- ckstrncpy(http_reply_str,p,HTTPBUFLEN);
-}
-
-int
-#ifdef CK_ANSIC
-http_get(char * agent, char ** hdrlist, char * user,
- char * pwd, char array, char * local, char * remote,
- int stdio)
-#else
-http_get(agent, hdrlist, user, pwd, array, local, remote, stdio)
- char * agent; char ** hdrlist; char * user;
- char * pwd; char array; char * local; char * remote;
- int stdio;
-#endif /* CK_ANSIC */
-{
- char * request = NULL;
- int i, j, len = 0, hdcnt = 0, rc = 0;
- int ch;
- int http_fnd = 0;
- char buf[HTTPBUFLEN], *p;
- int nullline;
-#ifdef OS2
- struct utimbuf u_t;
-#else /* OS2 */
-#ifdef SYSUTIMEH
- struct utimbuf u_t;
-#else
- struct utimbuf {
- time_t atime;
- time_t mtime;
- } u_t;
-#endif /* SYSUTIMH */
-#endif /* OS2 */
- time_t mod_t = 0;
- time_t srv_t = 0;
- time_t local_t = 0;
- char passwd[64];
- char b64in[128];
- char b64out[256];
- char * headers[HTTPHEADCNT];
- int closecon = 0;
- int chunked = 0;
- int zfile = 0;
- int first = 1;
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"http_get httpfd","",httpfd);
- debug(F110,"http_agent",agent,0);
- debug(F110,"http_user",user,0);
- debug(F110,"http_local",local,0);
- debug(F110,"http_remote",remote,0);
- }
-#endif /* DEBUG */
- if (!remote) remote = "";
-
- if (httpfd == -1)
- return(-1);
-
- if (array) {
- for (i = 0; i < HTTPHEADCNT; i++)
- headers[i] = NULL;
- }
- len = 8; /* GET */
- len += strlen(HTTP_VERSION);
- len += strlen(remote);
- len += 16;
-
- if (hdrlist) {
- for (i = 0; hdrlist[i]; i++)
- len += strlen(hdrlist[i]) + 2;
- }
- len += (int) strlen(http_host_port) + 8;
-
- if (agent)
- len += 13 + strlen(agent);
- if (user) {
- if (!pwd) {
- readpass("Password: ",passwd,64);
- pwd = passwd;
- }
- ckmakmsg(b64in,sizeof(b64in),user,":",pwd,NULL);
- j = b8tob64(b64in,strlen(b64in),b64out,256);
- memset(pwd,0,strlen(pwd)); /* NOT PORTABLE */
- if (j < 0)
- return(-1);
- b64out[j] = '\0';
- len += j + 24;
- }
-#ifdef HTTP_CLOSE
- len += 19; /* Connection: close */
-#endif
- len += 3; /* blank line + null */
-
- request = malloc(len);
- if (!request)
- return(-1);
-
- sprintf(request,"GET %s %s\r\n",remote,HTTP_VERSION); /* safe */
- ckstrncat(request,"Host: ", len);
- ckstrncat(request,http_host_port, len);
- ckstrncat(request,"\r\n",len);
- if (agent) {
- ckstrncat(request,"User-agent: ",len);
- ckstrncat(request,agent,len);
- ckstrncat(request,"\r\n",len);
- }
- if (user) {
- ckstrncat(request,"Authorization: Basic ",len);
- ckstrncat(request,b64out,len);
- ckstrncat(request,"\r\n",len);
- }
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++) {
- ckstrncat(request,hdrlist[i],len);
- ckstrncat(request,"\r\n",len);
- }
- }
-#ifdef HTTP_CLOSE
- ckstrncat(request,"Connection: close\r\n",len);
-#endif
- ckstrncat(request,"\r\n",len);
-
- getreq:
- if (http_tol((CHAR *)request,strlen(request)) < 0)
- {
- http_close();
- if ( first ) {
- first--;
- http_reopen();
- goto getreq;
- }
- rc = -1;
- goto getexit;
- }
-
- /* Process the headers */
- local_t = time(NULL);
- nullline = 0;
- i = 0;
- len = -1;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if ( buf[i] == 10 ) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"HTTP",4,0)) {
- http_fnd = 1;
- j = ckindex(" ",buf,0,0,0);
- p = &buf[j];
- while ( isspace(*p) )
- p++;
- switch ( p[0] ) {
- case '1': /* Informational message */
- break;
- case '2': /* Success */
- break;
- case '3': /* Redirection */
- case '4': /* Client failure */
- case '5': /* Server failure */
- default: /* Unknown */
- if (!quiet)
- printf("Failure: Server reports %s\n",p);
- rc = -1;
- local = NULL;
- }
- http_set_code_reply(p);
-#ifdef CMDATE2TM
- } else if (!ckstrcmp(buf,"Last-Modified",13,0)) {
- mod_t = http_date(&buf[15]);
- } else if (!ckstrcmp(buf,"Date",4,0)) {
- srv_t = http_date(&buf[4]);
-#endif /* CMDATE2TM */
- } else if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- } else if (!ckstrcmp(buf,"Content-Length:",15,0)) {
- len = atoi(&buf[16]);
- } else if (!ckstrcmp(buf,"Transfer-Encoding:",18,0)) {
- if ( ckindex("chunked",buf,18,0,0) != 0 )
- chunked = 1;
- debug(F101,"http_get chunked","",chunked);
- }
- i = 0;
- } else {
- i++;
- }
- }
- if (ch < 0 && first) {
- first--;
- http_close();
- http_reopen();
- goto getreq;
- }
- if (http_fnd == 0) {
- rc = -1;
- closecon = 1;
- goto getexit;
- }
-
- /* Now we have the contents of the file */
- if ( local && local[0] ) {
- if (zopeno(ZOFILE,local,NULL,NULL))
- zfile = 1;
- else
- rc = -1;
- }
-
- if ( chunked ) {
- while ((len = http_get_chunk_len()) > 0) {
- while (len && (ch = http_inc(0)) >= 0) {
- len--;
- if ( zfile )
- zchout(ZOFILE,(CHAR)ch);
- if ( stdio )
- conoc((CHAR)ch);
- }
- if ((ch = http_inc(0)) != CR)
- break;
- if ((ch = http_inc(0)) != LF)
- break;
- }
- } else {
- while (len && (ch = http_inc(0)) >= 0) {
- len--;
- if ( zfile )
- zchout(ZOFILE,(CHAR)ch);
- if ( stdio )
- conoc((CHAR)ch);
- }
- }
-
- if ( zfile )
- zclose(ZOFILE);
-
- if ( chunked ) { /* Parse Trailing Headers */
- nullline = 0;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if ( buf[i] == 10 ) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
-#ifdef CMDATE2TM
- if (!ckstrcmp(buf,"Last-Modified",13,0)) {
- mod_t = http_date(&buf[15]);
- } else if (!ckstrcmp(buf,"Date",4,0)) {
- srv_t = http_date(&buf[4]);
- }
-#endif /* CMDATE2TM */
- else if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- }
- i = 0;
- } else {
- i++;
- }
- }
- }
-
- if ( zfile ) { /* Set timestamp */
-#ifndef NOSETTIME
-#ifdef OS2
- u_t.actime = srv_t ? srv_t : local_t;
- u_t.modtime = mod_t ? mod_t : local_t;
-#else /* OS2 */
-#ifdef SYSUTIMEH
- u_t.actime = srv_t ? srv_t : local_t;
- u_t.modtime = mod_t ? mod_t : local_t;
-#else
-#ifdef BSD44
- u_t[0].tv_sec = srv_t ? srv_t : local_t;
- u_t[1].tv_sec = mod_t ? mod_t : local_t;
-#else
- u_t.mtime = srv_t ? srv_t : local_t;
- u_t.atime = mod_t ? mod_t : local_t;
-#endif /* BSD44 */
-#endif /* SYSUTIMEH */
-#endif /* OS2 */
- utime(local,&u_t);
-#endif /* NOSETTIME */
- }
-
- getexit:
- if (array)
- http_mkarray(headers,hdcnt,array);
-
- if ( closecon )
- http_close();
- free(request);
- for (i = 0; i < hdcnt; i++) {
- if (headers[i])
- free(headers[i]);
- }
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-http_head(char * agent, char ** hdrlist, char * user,
- char * pwd, char array, char * local, char * remote,
- int stdio)
-#else
-http_head(agent, hdrlist, user, pwd, array, local, remote, stdio)
- char * agent; char ** hdrlist; char * user;
- char * pwd; char array; char * local; char * remote;
- int stdio;
-#endif /* CK_ANSIC */
-{
- char * request = NULL;
- int i, j, len = 0, hdcnt = 0, rc = 0;
- int ch;
- int http_fnd = 0;
- char buf[HTTPBUFLEN], *p;
- int nullline;
- time_t mod_t;
- time_t srv_t;
- time_t local_t;
- char passwd[64];
- char b64in[128];
- char b64out[256];
- char * headers[HTTPHEADCNT];
- int closecon = 0;
- int first = 1;
-
- if (httpfd == -1)
- return(-1);
-
- if (array) {
- for (i = 0; i < HTTPHEADCNT; i++)
- headers[i] = NULL;
- }
- len = 9; /* HEAD */
- len += strlen(HTTP_VERSION);
- len += strlen(remote);
- len += 16;
-
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++)
- len += strlen(hdrlist[i]) + 2;
- }
- len += strlen(http_host_port) + 8;
-
- if (agent)
- len += 13 + strlen(agent);
- if (user) {
- if (!pwd) {
- readpass("Password: ",passwd,64);
- pwd = passwd;
- }
- ckmakmsg(b64in,sizeof(b64in),user,":",pwd,NULL);
- j = b8tob64(b64in,strlen(b64in),b64out,256);
- memset(pwd,0,strlen(pwd)); /* NOT PORTABLE */
- if (j < 0)
- return(-1);
- b64out[j] = '\0';
- len += j + 24;
- }
-#ifdef HTTP_CLOSE
- len += 19; /* Connection: close */
-#endif
- len += 3; /* blank line + null */
-
- request = (char *)malloc(len);
- if (!request)
- return(-1);
-
- sprintf(request,"HEAD %s %s\r\n",remote,HTTP_VERSION);
- ckstrncat(request,"Host: ", len);
- ckstrncat(request,http_host_port, len);
- ckstrncat(request,"\r\n",len);
- if (agent) {
- ckstrncat(request,"User-agent: ",len);
- ckstrncat(request,agent,len);
- ckstrncat(request,"\r\n",len);
- }
- if (user) {
- ckstrncat(request,"Authorization: Basic ",len);
- ckstrncat(request,b64out,len);
- ckstrncat(request,"\r\n",len);
- }
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++) {
- ckstrncat(request,hdrlist[i],len);
- ckstrncat(request,"\r\n",len);
- }
- }
-#ifdef HTTP_CLOSE
- ckstrncat(request,"Connection: close\r\n",len);
-#endif
- ckstrncat(request,"\r\n",len);
-
- if ( local && local[0] ) {
- if (!zopeno(ZOFILE,local,NULL,NULL)) {
- free(request);
- return(-1);
- }
- }
-
- headreq:
- if (http_tol((CHAR *)request,strlen(request)) < 0)
- {
- http_close();
- if ( first ) {
- first--;
- http_reopen();
- goto headreq;
- }
- rc = -1;
- goto headexit;
- }
-
- /* Process the headers */
-
- local_t = time(NULL);
- nullline = 0;
- i = 0;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if (buf[i] == 10) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"HTTP",4,0)) {
- http_fnd = 1;
- j = ckindex(" ",buf,0,0,0);
- p = &buf[j];
- while (isspace(*p))
- p++;
- switch (p[0]) {
- case '1': /* Informational message */
- break;
- case '2': /* Success */
- break;
- case '3': /* Redirection */
- case '4': /* Client failure */
- case '5': /* Server failure */
- default: /* Unknown */
- if (!quiet)
- printf("Failure: Server reports %s\n",p);
- rc = -1;
- }
- http_set_code_reply(p);
- } else {
- if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- }
- if ( local && local[0] ) {
- zsout(ZOFILE,buf);
- zsout(ZOFILE,"\r\n");
- }
- if (stdio)
- printf("%s\r\n",buf);
- }
- i = 0;
- } else {
- i++;
- }
- }
- if (ch < 0 && first) {
- first--;
- http_close();
- http_reopen();
- goto headreq;
- }
- if ( http_fnd == 0 )
- rc = -1;
-
- if (array)
- http_mkarray(headers,hdcnt,array);
-
- headexit:
- if ( local && local[0] )
- zclose(ZOFILE);
- if (closecon)
- http_close();
- free(request);
- for (i = 0; i < hdcnt; i++) {
- if (headers[i])
- free(headers[i]);
- }
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-http_index(char * agent, char ** hdrlist, char * user, char * pwd,
- char array, char * local, char * remote, int stdio)
-#else
-http_index(agent, hdrlist, user, pwd, array, local, remote, stdio)
- char * agent; char ** hdrlist; char * user; char * pwd;
- char array; char * local; char * remote; int stdio;
-#endif /* CK_ANSIC */
-{
- char * request = NULL;
- int i, j, len = 0, hdcnt = 0, rc = 0;
- int ch;
- int http_fnd = 0;
- char buf[HTTPBUFLEN], *p;
- int nullline;
- time_t mod_t;
- time_t srv_t;
- time_t local_t;
- char passwd[64];
- char b64in[128];
- char b64out[256];
- char * headers[HTTPHEADCNT];
- int closecon = 0;
- int chunked = 0;
- int zfile = 0;
- int first = 1;
-
- if (httpfd == -1)
- return(-1);
-
- if (array) {
- for (i = 0; i < HTTPHEADCNT; i++)
- headers[i] = NULL;
- }
- len = 10; /* INDEX */
- len += strlen(HTTP_VERSION);
- len += strlen(remote);
- len += 16;
-
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++)
- len += strlen(hdrlist[i]) + 2;
- }
- len += strlen(http_host_port) + 8;
-
- if (agent)
- len += 13 + strlen(agent);
- if (user) {
- if (!pwd) {
- readpass("Password: ",passwd,64);
- pwd = passwd;
- }
- ckmakmsg(b64in,sizeof(b64in),user,":",pwd,NULL);
- j = b8tob64(b64in,strlen(b64in),b64out,256);
- memset(pwd,0,strlen(pwd));
- if (j < 0)
- return(-1);
- b64out[j] = '\0';
- len += j + 24;
- }
-#ifdef HTTP_CLOSE
- len += 19; /* Connection: close */
-#endif
- len += 3; /* blank line + null */
-
- request = malloc(len);
- if (!request)
- return(-1);
-
- sprintf(request,"INDEX %s\r\n",HTTP_VERSION);
- ckstrncat(request,"Host: ", len);
- ckstrncat(request,http_host_port, len);
- ckstrncat(request,"\r\n",len);
- if (agent) {
- ckstrncat(request,"User-agent: ",len);
- ckstrncat(request,agent,len);
- ckstrncat(request,"\r\n",len);
- }
- if (user) {
- ckstrncat(request,"Authorization: Basic ",len);
- ckstrncat(request,b64out,len);
- ckstrncat(request,"\r\n",len);
- }
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++) {
- ckstrncat(request,hdrlist[i],len);
- ckstrncat(request,"\r\n",len);
- }
- }
-#ifdef HTTP_CLOSE
- ckstrncat(request,"Connection: close\r\n",len);
-#endif
- ckstrncat(request,"\r\n",len);
- indexreq:
- if (http_tol((CHAR *)request,strlen(request)) < 0)
- {
- http_close();
- if ( first ) {
- first--;
- http_reopen();
- goto indexreq;
- }
- rc = -1;
- goto indexexit;
- }
-
- /* Process the headers */
- local_t = time(NULL);
- nullline = 0;
- i = 0;
- len = -1;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if (buf[i] == 10) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"HTTP",4,0)) {
- http_fnd = 1;
- j = ckindex(" ",buf,0,0,0);
- p = &buf[j];
- while (isspace(*p))
- p++;
- switch ( p[0] ) {
- case '1': /* Informational message */
- break;
- case '2': /* Success */
- break;
- case '3': /* Redirection */
- case '4': /* Client failure */
- case '5': /* Server failure */
- default: /* Unknown */
- if (!quiet)
- printf("Failure: Server reports %s\n",p);
- rc = -1;
- }
- http_set_code_reply(p);
- } else if ( !nullline ) {
- if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- } else if (!ckstrcmp(buf,"Content-Length:",15,0)) {
- len = atoi(&buf[16]);
- } else if (!ckstrcmp(buf,"Transfer-Encoding:",18,0)) {
- if ( ckindex("chunked",buf,18,0,0) != 0 )
- chunked = 1;
- debug(F101,"http_index chunked","",chunked);
- }
- printf("%s\n",buf);
- }
- i = 0;
- } else {
- i++;
- }
- }
-
- if (ch < 0 && first) {
- first--;
- http_close();
- http_reopen();
- goto indexreq;
- }
- if ( http_fnd == 0 ) {
- rc = -1;
- closecon = 1;
- goto indexexit;
- }
-
- /* Now we have the contents of the file */
- if ( local && local[0] ) {
- if (zopeno(ZOFILE,local,NULL,NULL))
- zfile = 1;
- else
- rc = -1;
- }
-
- if ( chunked ) {
- while ((len = http_get_chunk_len()) > 0) {
- while (len && (ch = http_inc(0)) >= 0) {
- len--;
- if ( zfile )
- zchout(ZOFILE,(CHAR)ch);
- if ( stdio )
- conoc((CHAR)ch);
- }
- if ((ch = http_inc(0)) != CR)
- break;
- if ((ch = http_inc(0)) != LF)
- break;
- }
- } else {
- while (len && (ch = http_inc(0)) >= 0) {
- len--;
- if ( zfile )
- zchout(ZOFILE,(CHAR)ch);
- if ( stdio )
- conoc((CHAR)ch);
- }
- }
-
- if ( zfile )
- zclose(ZOFILE);
-
- if ( chunked ) { /* Parse Trailing Headers */
- nullline = 0;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if ( buf[i] == 10 ) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- }
- i = 0;
- } else {
- i++;
- }
- }
- }
- rc = 0;
-
- indexexit:
- if (array)
- http_mkarray(headers,hdcnt,array);
-
- if (closecon)
- http_close();
- free(request);
- for (i = 0; i < hdcnt; i++) {
- if (headers[i])
- free(headers[i]);
- }
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-http_put(char * agent, char ** hdrlist, char * mime, char * user,
- char * pwd, char array, char * local, char * remote,
- char * dest, int stdio)
-#else
-http_put(agent, hdrlist, mime, user, pwd, array, local, remote, dest, stdio)
- char * agent; char ** hdrlist; char * mime; char * user;
- char * pwd; char array; char * local; char * remote; char * dest;
- int stdio;
-#endif /* CK_ANSIC */
-{
- char * request=NULL;
- int i, j, len = 0, hdcnt = 0, rc = 0;
- int ch;
- int http_fnd = 0;
- char buf[HTTPBUFLEN], *p;
- int nullline;
- time_t mod_t;
- time_t srv_t;
- time_t local_t;
- char passwd[64];
- char b64in[128];
- char b64out[256];
- int filelen;
- char * headers[HTTPHEADCNT];
- int closecon = 0;
- int chunked = 0;
- int first = 1;
- int zfile = 0;
-
- if (httpfd == -1)
- return(-1);
- if (!mime) mime = "";
- if (!remote) remote = "";
- if (!local) local = "";
- if (!*local) return(-1);
-
- if (array) {
- for (i = 0; i < HTTPHEADCNT; i++)
- headers[i] = NULL;
- }
- filelen = zchki(local);
- if (filelen < 0)
- return(-1);
-
- /* Compute length of request header */
- len = 8; /* PUT */
- len += strlen(HTTP_VERSION);
- len += strlen(remote);
- len += 16;
-
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++)
- len += strlen(hdrlist[i]) + 2;
- }
- len += strlen(http_host_port) + 8;
-
- if (agent)
- len += 13 + strlen(agent);
- if (user) {
- if (!pwd) {
- readpass("Password: ",passwd,64);
- pwd = passwd;
- }
- ckmakmsg(b64in,sizeof(b64in),user,":",pwd,NULL);
- j = b8tob64(b64in,strlen(b64in),b64out,256);
- memset(pwd,0,strlen(pwd));
- if (j < 0)
- return(-1);
- b64out[j] = '\0';
- len += j + 24;
- }
- len += 16 + strlen(mime); /* Content-type: */
- len += 32; /* Content-length: */
- len += 32; /* Date: */
-#ifdef HTTP_CLOSE
- len += 19; /* Connection: close */
-#endif
- len += 3; /* blank line + null */
-
- request = malloc(len);
- if (!request)
- return(-1);
-
- sprintf(request,"PUT %s %s\r\n",remote,HTTP_VERSION);
- ckstrncat(request,"Date: ",len);
-#ifdef CMDATE2TM
- ckstrncat(request,http_now(),len);
-#else
- ckstrncat(request,...,len);
-#endif /* CMDATE2TM */
- ckstrncat(request,"\r\n",len);
- ckstrncat(request,"Host: ", len);
- ckstrncat(request,http_host_port, len);
- ckstrncat(request,"\r\n",len);
- if (agent) {
- ckstrncat(request,"User-agent: ",len);
- ckstrncat(request,agent,len);
- ckstrncat(request,"\r\n",len);
- }
- if (user) {
- ckstrncat(request,"Authorization: Basic ",len);
- ckstrncat(request,b64out,len);
- ckstrncat(request,"\r\n",len);
- }
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++) {
- ckstrncat(request,hdrlist[i],len);
- ckstrncat(request,"\r\n",len);
- }
- }
- ckstrncat(request,"Content-type: ",len);
- ckstrncat(request,mime,len);
- ckstrncat(request,"\r\n",len);
- sprintf(buf,"Content-length: %d\r\n",filelen); /* safe */
- ckstrncat(request,buf,len);
-#ifdef HTTP_CLOSE
- ckstrncat(request,"Connection: close\r\n",len);
-#endif
- ckstrncat(request,"\r\n",len);
-
- /* Now we have the contents of the file */
- if (zopeni(ZIFILE,local)) {
-
- putreq: /* Send request */
- if (http_tol((CHAR *)request,strlen(request)) <= 0) {
- http_close();
- if ( first ) {
- first--;
- http_reopen();
- goto putreq;
- }
- zclose(ZIFILE);
- rc = -1;
- goto putexit;
- }
- /* Request headers have been sent */
-
- i = 0;
- while (zchin(ZIFILE,&ch) == 0) {
- buf[i++] = ch;
- if (i == HTTPBUFLEN) {
- if (http_tol((CHAR *)buf,HTTPBUFLEN) <= 0) {
- http_close();
- if ( first ) {
- first--;
- http_reopen();
- goto putreq;
- }
- }
- i = 0;
- }
- }
- if (i > 0) {
- if (http_tol((CHAR *)buf,i) < 0) {
- http_close();
- if ( first ) {
- first--;
- http_reopen();
- goto putreq;
- }
- }
- }
- zclose(ZIFILE);
-
- /* Process the response headers */
- local_t = time(NULL);
- nullline = 0;
- i = 0;
- len = -1;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if (buf[i] == 10) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"HTTP",4,0)) {
- http_fnd = 1;
- j = ckindex(" ",buf,0,0,0);
- p = &buf[j];
- while (isspace(*p))
- p++;
- switch (p[0]) {
- case '1': /* Informational message */
- break;
- case '2': /* Success */
- break;
- case '3': /* Redirection */
- case '4': /* Client failure */
- case '5': /* Server failure */
- default: /* Unknown */
- if (!quiet)
- printf("Failure: Server reports %s\n",p);
- rc = -1;
- }
- http_set_code_reply(p);
- } else {
- if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- } else if (!ckstrcmp(buf,"Content-Length:",15,0)) {
- len = atoi(&buf[16]);
- } else if (!ckstrcmp(buf,"Transfer-Encoding:",18,0)) {
- if ( ckindex("chunked",buf,18,0,0) != 0 )
- chunked = 1;
- debug(F101,"http_put chunked","",chunked);
- }
- if ( stdio )
- printf("%s\n",buf);
- }
- i = 0;
- } else {
- i++;
- }
- }
- if (ch < 0 && first) {
- first--;
- http_close();
- http_reopen();
- goto putreq;
- }
- if ( http_fnd == 0 ) {
- closecon = 1;
- rc = -1;
- goto putexit;
- }
-
- /* Any response data? */
- if ( dest && dest[0] ) {
- if (zopeno(ZOFILE,dest,NULL,NULL))
- zfile = 1;
- else
- rc = -1;
- }
-
- if ( chunked ) {
- while ((len = http_get_chunk_len()) > 0) {
- while (len && (ch = http_inc(0)) >= 0) {
- len--;
- if ( zfile )
- zchout(ZOFILE,(CHAR)ch);
- if ( stdio )
- conoc((CHAR)ch);
- }
- if ((ch = http_inc(0)) != CR)
- break;
- if ((ch = http_inc(0)) != LF)
- break;
- }
- } else {
- while (len && (ch = http_inc(0)) >= 0) {
- len--;
- if ( zfile )
- zchout(ZOFILE,(CHAR)ch);
- if ( stdio )
- conoc((CHAR)ch);
- }
- }
-
- if ( zfile )
- zclose(ZOFILE);
-
- if ( chunked ) { /* Parse Trailing Headers */
- nullline = 0;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if ( buf[i] == 10 ) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- }
- i = 0;
- } else {
- i++;
- }
- }
- }
- } else {
- rc = -1;
- }
-
- putexit:
- if ( array )
- http_mkarray(headers,hdcnt,array);
-
- if (closecon)
- http_close();
- free(request);
- for (i = 0; i < hdcnt; i++) {
- if (headers[i])
- free(headers[i]);
- }
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-http_delete(char * agent, char ** hdrlist, char * user,
- char * pwd, char array, char * remote)
-#else
-http_delete(agent, hdrlist, user, pwd, array, remote)
- char * agent; char ** hdrlist; char * user;
- char * pwd; char array; char * remote;
-#endif /* CK_ANSIC */
-{
- char * request=NULL;
- int i, j, len = 0, hdcnt = 0, rc = 0;
- int ch;
- int http_fnd = 0;
- char buf[HTTPBUFLEN], *p;
- int nullline;
- time_t mod_t;
- time_t srv_t;
- time_t local_t;
- char passwd[64];
- char b64in[128];
- char b64out[256];
- char * headers[HTTPHEADCNT];
- int closecon = 0;
- int chunked = 0;
- int first = 1;
-
- if (httpfd == -1)
- return(-1);
-
- if (array) {
- for (i = 0; i < HTTPHEADCNT; i++)
- headers[i] = NULL;
- }
-
- /* Compute length of request header */
- len = 11; /* DELETE */
- len += strlen(HTTP_VERSION);
- len += strlen(remote);
- len += 16;
-
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++)
- len += strlen(hdrlist[i]) + 2;
- }
- len += strlen(http_host_port) + 8;
-
- if (agent)
- len += 13 + strlen(agent);
- if (user) {
- if (!pwd) {
- readpass("Password: ",passwd,64);
- pwd = passwd;
- }
- ckmakmsg(b64in,sizeof(b64in),user,":",pwd,NULL);
- j = b8tob64(b64in,strlen(b64in),b64out,256);
- memset(pwd,0,strlen(pwd));
- if (j < 0)
- return(-1);
- b64out[j] = '\0';
- len += j + 24;
- }
- len += 32; /* Date: */
-#ifdef HTTP_CLOSE
- len += 19; /* Connection: close */
-#endif
- len += 3; /* blank line + null */
-
- request = malloc(len);
- if (!request)
- return(-1);
-
- sprintf(request,"DELETE %s %s\r\n",remote,HTTP_VERSION);
- ckstrncat(request,"Date: ",len);
-#ifdef CMDATE2TM
- ckstrncat(request,http_now(),len);
-#else
- ckstrncat(request,...,len);
-#endif /* CMDATE2TM */
- ckstrncat(request,"\r\n",len);
- ckstrncat(request,"Host: ", len);
- ckstrncat(request,http_host_port, len);
- ckstrncat(request,"\r\n",len);
- if (agent) {
- ckstrncat(request,"User-agent: ",len);
- ckstrncat(request,agent,len);
- ckstrncat(request,"\r\n",len);
- }
- if (user) {
- ckstrncat(request,"Authorization: Basic ",len);
- ckstrncat(request,b64out,len);
- ckstrncat(request,"\r\n",len);
- }
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++) {
- ckstrncat(request,hdrlist[i],len);
- ckstrncat(request,"\r\n",len);
- }
- }
-#ifdef HTTP_CLOSE
- ckstrncat(request,"Connection: close\r\n",len);
-#endif
- ckstrncat(request,"\r\n",len);
- delreq:
- if (http_tol((CHAR *)request,strlen(request)) < 0)
- {
- http_close();
- if ( first ) {
- first--;
- http_reopen();
- goto delreq;
- }
- rc = -1;
- goto delexit;
- }
-
- /* Process the response headers */
- local_t = time(NULL);
- nullline = 0;
- i = 0;
- len = -1;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if (buf[i] == 10) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"HTTP",4,0)) {
- http_fnd = 1;
- j = ckindex(" ",buf,0,0,0);
- p = &buf[j];
- while (isspace(*p))
- p++;
- switch (p[0]) {
- case '1': /* Informational message */
- break;
- case '2': /* Success */
- break;
- case '3': /* Redirection */
- case '4': /* Client failure */
- case '5': /* Server failure */
- default: /* Unknown */
- if (!quiet)
- printf("Failure: Server reports %s\n",p);
- rc = -1;
- }
- http_set_code_reply(p);
- } else {
- if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- } else if (!ckstrcmp(buf,"Content-Length:",15,0)) {
- len = atoi(&buf[16]);
- } else if (!ckstrcmp(buf,"Transfer-Encoding:",18,0)) {
- if ( ckindex("chunked",buf,18,0,0) != 0 )
- chunked = 1;
- debug(F101,"http_delete chunked","",chunked);
- }
- printf("%s\n",buf);
- }
- i = 0;
- } else {
- i++;
- }
- }
- if (ch < 0 && first) {
- first--;
- http_close();
- http_reopen();
- goto delreq;
- }
- if ( http_fnd == 0 ) {
- rc = -1;
- closecon = 1;
- goto delexit;
- }
-
- /* Any response data? */
- if ( chunked ) {
- while ((len = http_get_chunk_len()) > 0) {
- while (len && (ch = http_inc(0)) >= 0) {
- len--;
- conoc((CHAR)ch);
- }
- if ((ch = http_inc(0)) != CR)
- break;
- if ((ch = http_inc(0)) != LF)
- break;
- }
- } else {
- while (len && (ch = http_inc(0)) >= 0) {
- len--;
- conoc((CHAR)ch);
- }
- }
-
- if ( chunked ) { /* Parse Trailing Headers */
- nullline = 0;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if ( buf[i] == 10 ) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- }
- i = 0;
- } else {
- i++;
- }
- }
- }
-
- delexit:
- if (array)
- http_mkarray(headers,hdcnt,array);
-
- if (closecon)
- http_close();
- free(request);
- for (i = 0; i < hdcnt; i++) {
- if (headers[i])
- free(headers[i]);
- }
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-http_post(char * agent, char ** hdrlist, char * mime, char * user,
- char * pwd, char array, char * local, char * remote,
- char * dest, int stdio)
-#else
-http_post(agent, hdrlist, mime, user, pwd, array, local, remote, dest,
- stdio)
- char * agent; char ** hdrlist; char * mime; char * user;
- char * pwd; char array; char * local; char * remote; char * dest;
- int stdio;
-#endif /* CK_ANSIC */
-{
- char * request=NULL;
- int i, j, len = 0, hdcnt = 0, rc = 0;
- int ch;
- int http_fnd = 0;
- char buf[HTTPBUFLEN], *p;
- int nullline;
- time_t mod_t;
- time_t srv_t;
- time_t local_t;
- char passwd[64];
- char b64in[128];
- char b64out[256];
- int filelen;
- char * headers[HTTPHEADCNT];
- int closecon = 0;
- int chunked = 0;
- int zfile = 0;
- int first = 1;
-
- if (httpfd == -1)
- return(-1);
-
- if (array) {
- for (i = 0; i < HTTPHEADCNT; i++)
- headers[i] = NULL;
- }
- filelen = zchki(local);
- if (filelen < 0)
- return(-1);
-
- /* Compute length of request header */
- len = 9; /* POST */
- len += strlen(HTTP_VERSION);
- len += strlen(remote);
- len += 16;
-
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++)
- len += strlen(hdrlist[i]) + 2;
- }
- len += strlen(http_host_port) + 8;
-
- if (agent)
- len += 13 + strlen(agent);
- if (user) {
- if (!pwd) {
- readpass("Password: ",passwd,64);
- pwd = passwd;
- }
- ckmakmsg(b64in,sizeof(b64in),user,":",pwd,NULL);
- j = b8tob64(b64in,strlen(b64in),b64out,256);
- memset(pwd,0,strlen(pwd));
- if (j < 0)
- return(-1);
- b64out[j] = '\0';
- len += j + 24;
- }
- len += 16 + strlen(mime); /* Content-type: */
- len += 32; /* Content-length: */
- len += 32; /* Date: */
-#ifdef HTTP_CLOSE
- len += 19; /* Connection: close */
-#endif
- len += 3; /* blank line + null */
-
- request = malloc(len);
- if (!request)
- return(-1);
-
- sprintf(request,"POST %s %s\r\n",remote,HTTP_VERSION);
- ckstrncat(request,"Date: ",len);
- ckstrncat(request,http_now(),len);
- ckstrncat(request,"\r\n",len);
- ckstrncat(request,"Host: ", len);
- ckstrncat(request,http_host_port, len);
- ckstrncat(request,"\r\n",len);
- if (agent) {
- ckstrncat(request,"User-agent: ",len);
- ckstrncat(request,agent,len);
- ckstrncat(request,"\r\n",len);
- }
- if (user) {
- ckstrncat(request,"Authorization: Basic ",len);
- ckstrncat(request,b64out,len);
- ckstrncat(request,"\r\n",len);
- }
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++) {
- ckstrncat(request,hdrlist[i],len);
- ckstrncat(request,"\r\n",len);
- }
- }
- ckstrncat(request,"Content-type: ",len);
- ckstrncat(request,mime,len);
- ckstrncat(request,"\r\n",len);
-#ifdef HTTP_CLOSE
- ckstrncat(request,"Connection: close\r\n",len);
-#endif
- sprintf(buf,"Content-length: %d\r\n",filelen); /* safe */
- ckstrncat(request,buf,len);
- ckstrncat(request,"\r\n",len);
-#ifdef COMMENT
- /* This is apparently a mistake - the previous ckstrncat() already */
- /* appended a blank line to the request. There should only be one. */
- /* Servers are not required by RFC 2616 to ignore extraneous empty */
- /* lines. -fdc, 28 Aug 2005. */
- ckstrncat(request,"\r\n",len);
-#endif /* COMMENT */
-
- /* Now we have the contents of the file */
- postopen:
- if (zopeni(ZIFILE,local)) {
- postreq:
- if (http_tol((CHAR *)request,strlen(request)) < 0)
- {
- http_close();
- if ( first ) {
- first--;
- http_reopen();
- goto postreq;
- }
- rc = -1;
- zclose(ZIFILE);
- goto postexit;
- }
-
- i = 0;
- while (zchin(ZIFILE,&ch) == 0) {
- buf[i++] = ch;
- if (i == HTTPBUFLEN) {
- http_tol((CHAR *)buf,HTTPBUFLEN);
- i = 0;
- }
- }
- if (i > 0)
- http_tol((CHAR *)buf,HTTPBUFLEN);
- zclose(ZIFILE);
-
- /* Process the response headers */
- local_t = time(NULL);
- nullline = 0;
- i = 0;
- len = -1;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if (buf[i] == 10) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"HTTP",4,0)) {
- http_fnd = 1;
- j = ckindex(" ",buf,0,0,0);
- p = &buf[j];
- while (isspace(*p))
- p++;
- switch (p[0]) {
- case '1': /* Informational message */
- break;
- case '2': /* Success */
- break;
- case '3': /* Redirection */
- case '4': /* Client failure */
- case '5': /* Server failure */
- default: /* Unknown */
- if (!quiet)
- printf("Failure: Server reports %s\n",p);
- rc = -1;
- }
- http_set_code_reply(p);
- } else {
- if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- } else if (!ckstrcmp(buf,"Content-Length:",15,0)) {
- len = atoi(&buf[16]);
- } else if (!ckstrcmp(buf,"Transfer-Encoding:",18,0)) {
- if ( ckindex("chunked",buf,18,0,0) != 0 )
- chunked = 1;
- debug(F101,"http_post chunked","",chunked);
- }
- if (stdio)
- printf("%s\n",buf);
- }
- i = 0;
- } else {
- i++;
- }
- }
- if (ch < 0 && first) {
- first--;
- http_close();
- http_reopen();
- goto postopen;
- }
- if (http_fnd == 0) {
- rc = -1;
- closecon = 1;
- goto postexit;
- }
-
- /* Any response data? */
- if ( dest && dest[0] ) {
- if (zopeno(ZOFILE,dest,NULL,NULL))
- zfile = 1;
- else
- rc = -1;
- }
-
- if ( chunked ) {
- while ((len = http_get_chunk_len()) > 0) {
- while (len && (ch = http_inc(0)) >= 0) {
- len--;
- if ( zfile )
- zchout(ZOFILE,(CHAR)ch);
- if ( stdio )
- conoc((CHAR)ch);
- }
- if ((ch = http_inc(0)) != CR)
- break;
- if ((ch = http_inc(0)) != LF)
- break;
- }
- } else {
- while (len && (ch = http_inc(0)) >= 0) {
- len--;
- if ( zfile )
- zchout(ZOFILE,(CHAR)ch);
- if ( stdio )
- conoc((CHAR)ch);
- }
- }
-
- if ( zfile )
- zclose(ZOFILE);
-
- if ( chunked ) { /* Parse Trailing Headers */
- nullline = 0;
- while (!nullline && (ch = http_inc(0)) >= 0 && i < HTTPBUFLEN) {
- buf[i] = ch;
- if ( buf[i] == 10 ) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"Connection:",11,0)) {
- if ( ckindex("close",buf,11,0,0) != 0 )
- closecon = 1;
- }
- i = 0;
- } else {
- i++;
- }
- }
- }
- } else {
- rc = -1;
- }
-
- postexit:
- if (array)
- http_mkarray(headers,hdcnt,array);
- if (closecon)
- http_close();
- free(request);
- for (i = 0; i < hdcnt; i++) {
- if (headers[i])
- free(headers[i]);
- }
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-http_connect(int socket, char * agent, char ** hdrlist, char * user,
- char * pwd, char array, char * host_port)
-#else
-http_connect(socket, agent, hdrlist, user, pwd, array, host_port)
- int socket;
- char * agent; char ** hdrlist; char * user;
- char * pwd; char array; char * host_port;
-#endif /* CK_ANSIC */
-{
- char * request=NULL;
- int i, j, len = 0, hdcnt = 0, rc = 0;
- int http_fnd = 0;
- char buf[HTTPBUFLEN], *p, ch;
- int nullline;
- time_t mod_t;
- time_t srv_t;
- time_t local_t;
- char passwd[64];
- char b64in[128];
- char b64out[256];
- char * headers[HTTPHEADCNT];
- int connected = 0;
-
- tcp_http_proxy_errno = 0;
-
- if (socket == -1)
- return(-1);
-
- if (array) {
- for (i = 0; i < HTTPHEADCNT; i++)
- headers[i] = NULL;
- }
-
- /* Compute length of request header */
- len = 12; /* CONNECT */
- len += strlen(HTTP_VERSION);
- len += strlen(host_port);
- len += (int) strlen(http_host_port) + 8;
- len += 16;
- len += strlen("Proxy-Connection: Keep-Alive\r\n");
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++)
- len += strlen(hdrlist[i]) + 2;
- }
- if (agent && agent[0])
- len += 13 + strlen(agent);
- if (user && user[0]) {
- if (!pwd) {
- readpass("Password: ",passwd,64);
- pwd = passwd;
- }
- ckmakmsg(b64in,sizeof(b64in),user,":",pwd,NULL);
- j = b8tob64(b64in,strlen(b64in),b64out,256);
- memset(pwd,0,strlen(pwd));
- if (j < 0)
- return(-1);
- b64out[j] = '\0';
- len += j + 72;
- }
- len += 32; /* Date: */
- len += 3; /* blank line + null */
-
- request = malloc(len);
- if (!request)
- return(-1);
-
- sprintf(request,"CONNECT %s %s\r\n",host_port,HTTP_VERSION);
- ckstrncat(request,"Date: ",len);
-#ifdef CMDATE2TM
- ckstrncat(request,http_now(),len);
-#else
- strcat(request,...);
-#endif /* CMDATE2TM */
- ckstrncat(request,"\r\n",len);
- ckstrncat(request,"Host: ", len);
- ckstrncat(request,http_host_port, len);
- ckstrncat(request,"\r\n",len);
- if (agent && agent[0]) {
- ckstrncat(request,"User-agent: ",len);
- ckstrncat(request,agent,len);
- ckstrncat(request,"\r\n",len);
- }
- if (user && user[0]) {
- ckstrncat(request,"Proxy-authorization: Basic ",len);
- ckstrncat(request,b64out,len);
- ckstrncat(request,"\r\n",len);
- ckstrncat(request,"Extension: Security/Remote-Passphrase\r\n",len);
- }
- ckstrncat(request,"Proxy-Connection: Keep-Alive\r\n",len);
- if ( hdrlist ) {
- for (i = 0; hdrlist[i]; i++) {
- ckstrncat(request,hdrlist[i],len);
- ckstrncat(request,"\r\n",len);
- }
- }
- ckstrncat(request,"\r\n",len);
- len = strlen(request);
-
-#ifdef TCPIPLIB
- /* Send request */
- if (socket_write(socket,(CHAR *)request,strlen(request)) < 0) {
- rc = -1;
- goto connexit;
- }
-#else
- if (write(socket,(CHAR *)request,strlen(request)) < 0) { /* Send request */
- rc = -1;
- goto connexit;
- }
-#endif /* TCPIPLIB */
-
- /* Process the response headers */
- local_t = time(NULL);
- nullline = 0;
- i = 0;
- while (!nullline &&
-#ifdef TCPIPLIB
- (socket_read(socket,&ch,1) == 1) &&
-#else
- (read(socket,&ch,1) == 1) &&
-#endif /* TCPIPLIB */
- i < HTTPBUFLEN) {
- buf[i] = ch;
- if (buf[i] == 10) { /* found end of line */
- if (i > 0 && buf[i-1] == 13)
- i--;
- if (i < 1)
- nullline = 1;
- buf[i] = '\0';
-
- if (array && !nullline && hdcnt < HTTPHEADCNT)
- makestr(&headers[hdcnt++],buf);
- if (!ckstrcmp(buf,"HTTP",4,0)) {
- http_fnd = 1;
- j = ckindex(" ",buf,0,0,0);
- p = &buf[j];
- while (isspace(*p))
- p++;
- tcp_http_proxy_errno = atoi(p);
- switch (p[0]) {
- case '1': /* Informational message */
- break;
- case '2': /* Success */
- connected = 1;
- break;
- case '3': /* Redirection */
- case '4': /* Client failure */
- case '5': /* Server failure */
- default: /* Unknown */
- if (!quiet)
- printf("Failure: Server reports %s\n",p);
- rc = -1;
- }
- http_set_code_reply(p);
- } else {
- printf("%s\n",buf);
- }
- i = 0;
- } else {
- i++;
- }
- }
- if ( http_fnd == 0 )
- rc = -1;
-
- if (array)
- http_mkarray(headers,hdcnt,array);
-
- connexit:
- if ( !connected ) {
- if ( socket == ttyfd ) {
- ttclos(0);
- }
- else if ( socket == httpfd ) {
- http_close();
- }
- }
-
- free(request);
- for (i = 0; i < hdcnt; i++) {
- if (headers[i])
- free(headers[i]);
- }
- return(rc);
-}
-#endif /* NOHTTP */
-
-#ifdef CK_DNS_SRV
-
-#define INCR_CHECK(x,y) x += y; if (x > size + answer.bytes) goto dnsout
-#define CHECK(x,y) if (x + y > size + answer.bytes) goto dnsout
-#define NTOHSP(x,y) x[0] << 8 | x[1]; x += y
-
-#ifndef CKQUERYTYPE
-#ifdef UNIXWARE
-#ifndef UW7
-#define CKQUERYTYPE CHAR
-#endif /* UW7 */
-#endif /* UNIXWARE */
-#endif /* CKQUERYTYPE */
-
-#ifndef CKQUERYTYPE
-#define CKQUERYTYPE char
-#endif /* CKQUERYTYPE */
-
-/* 1 is success, 0 is failure */
-int
-locate_srv_dns(host, service, protocol, addr_pp, naddrs)
- char *host;
- char *service;
- char *protocol;
- struct sockaddr **addr_pp;
- int *naddrs;
-{
- int nout, j, count;
- union {
- unsigned char bytes[2048];
- HEADER hdr;
- } answer;
- unsigned char *p=NULL;
- CKQUERYTYPE query[MAX_DNS_NAMELEN];
-#ifdef CK_ANSIC
- const char * h;
-#else
- char * h;
-#endif /* CK_ANSIC */
- struct sockaddr *addr = NULL;
- struct sockaddr_in *sin = NULL;
- struct hostent *hp = NULL;
- int type, class;
- int priority, weight, size, len, numanswers, numqueries, rdlen;
- unsigned short port;
-#ifdef CK_ANSIC
- const
-#endif /* CK_ANSIC */
- int hdrsize = sizeof(HEADER);
- struct srv_dns_entry {
- struct srv_dns_entry *next;
- int priority;
- int weight;
- unsigned short port;
- char *host;
- };
- struct srv_dns_entry *head = NULL;
- struct srv_dns_entry *srv = NULL, *entry = NULL;
- char * s = NULL;
-
- nout = 0;
- addr = (struct sockaddr *) malloc(sizeof(struct sockaddr));
- if (addr == NULL)
- return 0;
-
- count = 1;
-
- /*
- * First build a query of the form:
- *
- * service.protocol.host
- *
- * which will most likely be something like:
- *
- * _telnet._tcp.host
- *
- */
- if (((int)strlen(service) + strlen(protocol) + strlen(host) + 5)
- > MAX_DNS_NAMELEN
- )
- goto dnsout;
-
- /* Realm names don't (normally) end with ".", but if the query
- doesn't end with "." and doesn't get an answer as is, the
- resolv code will try appending the local domain. Since the
- realm names are absolutes, let's stop that.
-
- But only if a name has been specified. If we are performing
- a search on the prefix alone then the intention is to allow
- the local domain or domain search lists to be expanded.
- */
- h = host + strlen (host);
- ckmakxmsg(query, sizeof(query), "_",service,"._",protocol,".", host,
- ((h > host) && (h[-1] != '.')?".":NULL),
- NULL,NULL,NULL,NULL,NULL);
-
- size = res_search(query, C_IN, T_SRV, answer.bytes, sizeof(answer.bytes));
-
- if (size < hdrsize)
- goto dnsout;
-
- /* We got a reply - See how many answers it contains. */
-
- p = answer.bytes;
-
- numqueries = ntohs(answer.hdr.qdcount);
- numanswers = ntohs(answer.hdr.ancount);
-
- p += sizeof(HEADER);
-
- /*
- * We need to skip over all of the questions, so we have to iterate
- * over every query record. dn_expand() is able to tell us the size
- * of compressed DNS names, so we use it.
- */
- while (numqueries--) {
- len = dn_expand(answer.bytes,answer.bytes+size,p,query,sizeof(query));
- if (len < 0)
- goto dnsout;
- INCR_CHECK(p, len + 4);
- }
-
- /*
- * We're now pointing at the answer records. Only process them if
- * they're actually T_SRV records (they might be CNAME records,
- * for instance).
- *
- * But in a DNS reply, if you get a CNAME you always get the associated
- * "real" RR for that CNAME. RFC 1034, 3.6.2:
- *
- * CNAME RRs cause special action in DNS software. When a name server
- * fails to find a desired RR in the resource set associated with the
- * domain name, it checks to see if the resource set consists of a CNAME
- * record with a matching class. If so, the name server includes the CNAME
- * record in the response and restarts the query at the domain name
- * specified in the data field of the CNAME record. The one exception to
- * this rule is that queries which match the CNAME type are not restarted.
- *
- * In other words, CNAMEs do not need to be expanded by the client.
- */
- while (numanswers--) {
-
- /* First is the name; use dn_expand() to get the compressed size. */
- len = dn_expand(answer.bytes,answer.bytes+size,p,query,sizeof(query));
- if (len < 0)
- goto dnsout;
- INCR_CHECK(p, len);
-
- CHECK(p,2); /* Query type */
- type = NTOHSP(p,2);
-
- CHECK(p, 6); /* Query class */
- class = NTOHSP(p,6); /* Also skip over 4-byte TTL */
-
- CHECK(p,2); /* Record data length */
- rdlen = NTOHSP(p,2);
- /*
- * If this is an SRV record, process it. Record format is:
- *
- * Priority
- * Weight
- * Port
- * Server name
- */
- if (class == C_IN && type == T_SRV) {
- CHECK(p,2);
- priority = NTOHSP(p,2);
- CHECK(p, 2);
- weight = NTOHSP(p,2);
- CHECK(p, 2);
- port = NTOHSP(p,2);
- len = dn_expand(answer.
- bytes,
- answer.bytes + size,
- p,
- query,
- sizeof(query)
- );
- if (len < 0)
- goto dnsout;
- INCR_CHECK(p, len);
- /*
- * We got everything. Insert it into our list, but make sure
- * it's in the right order. Right now we don't do anything
- * with the weight field
- */
- srv = (struct srv_dns_entry *)malloc(sizeof(struct srv_dns_entry));
- if (srv == NULL)
- goto dnsout;
-
- srv->priority = priority;
- srv->weight = weight;
- srv->port = port;
- makestr(&s,(char *)query); /* strdup() is not portable */
- srv->host = s;
-
- if (head == NULL || head->priority > srv->priority) {
- srv->next = head;
- head = srv;
- } else
- /*
- * Confusing. Insert an entry into this spot only if:
- * . The next person has a higher priority (lower
- * priorities are preferred), or:
- * . There is no next entry (we're at the end)
- */
- for (entry = head; entry != NULL; entry = entry->next)
- if ((entry->next &&
- entry->next->priority > srv->priority) ||
- entry->next == NULL) {
- srv->next = entry->next;
- entry->next = srv;
- break;
- }
- } else
- INCR_CHECK(p, rdlen);
- }
-
- /*
- * Now we've got a linked list of entries sorted by priority.
- * Start looking up A records and returning addresses.
- */
- if (head == NULL)
- goto dnsout;
-
- for (entry = head; entry != NULL; entry = entry->next) {
- hp = gethostbyname(entry->host);
- if (hp != 0) {
-
- /* Watch out - memset() and memcpy() are not portable... */
-
- switch (hp->h_addrtype) {
- case AF_INET:
- for (j = 0; hp->h_addr_list[j]; j++) {
- sin = (struct sockaddr_in *) &addr[nout++];
- memset ((char *) sin, 0, sizeof (struct sockaddr));
- sin->sin_family = hp->h_addrtype;
- sin->sin_port = htons(entry->port);
- memcpy((char *) &sin->sin_addr,
- (char *) hp->h_addr_list[j],
- sizeof(struct in_addr)); /* safe */
- if (nout + 1 >= count) {
- count += 5;
- addr = (struct sockaddr *)
- realloc((char *) addr,
- sizeof(struct sockaddr) * count);
- if (!addr)
- goto dnsout;
- }
- }
- break;
- default:
- break;
- }
- }
- }
- for (entry = head; entry != NULL;) {
- free(entry->host);
- entry->host = NULL;
- srv = entry;
- entry = entry->next;
- free(srv);
- srv = NULL;
- }
-
- dnsout:
- if (srv)
- free(srv);
-
- if (nout == 0) { /* No good servers */
- if (addr)
- free(addr);
- return 0;
- }
- *addr_pp = addr;
- *naddrs = nout;
- return 1;
-}
-#undef INCR_CHECK
-#undef CHECK
-#undef NTOHSP
-
-#define INCR_CHECK(x, y) x += y; if (x > size + answer.bytes) \
- return 0
-#define CHECK(x, y) if (x + y > size + answer.bytes) \
- return 0
-#define NTOHSP(x, y) x[0] << 8 | x[1]; x += y
-
-int
-locate_txt_rr(prefix, name, retstr)
- char *prefix, *name;
- char **retstr;
-{
- union {
- unsigned char bytes[2048];
- HEADER hdr;
- } answer;
- unsigned char *p;
- char host[MAX_DNS_NAMELEN], *h;
- int size;
- int type, class, numanswers, numqueries, rdlen, len;
-
- /*
- * Form our query, and send it via DNS
- */
-
- if (name == NULL || name[0] == '\0') {
- strcpy(host,prefix);
- } else {
- if ( strlen(prefix) + strlen(name) + 3 > MAX_DNS_NAMELEN )
- return 0;
-
- /* Realm names don't (normally) end with ".", but if the query
- doesn't end with "." and doesn't get an answer as is, the
- resolv code will try appending the local domain. Since the
- realm names are absolutes, let's stop that.
-
- But only if a name has been specified. If we are performing
- a search on the prefix alone then the intention is to allow
- the local domain or domain search lists to be expanded.
- */
- h = host + strlen (host);
- ckmakmsg(host,sizeof(host),prefix, ".", name,
- ((h > host) && (h[-1] != '.'))?".":NULL);
-
- }
- size = res_search(host, C_IN, T_TXT, answer.bytes, sizeof(answer.bytes));
-
- if (size < 0)
- return 0;
-
- p = answer.bytes;
-
- numqueries = ntohs(answer.hdr.qdcount);
- numanswers = ntohs(answer.hdr.ancount);
-
- p += sizeof(HEADER);
-
- /*
- * We need to skip over the questions before we can get to the answers,
- * which means we have to iterate over every query record. We use
- * dn_expand to tell us how long each compressed name is.
- */
-
- while (numqueries--) {
- len = dn_expand(answer.bytes, answer.bytes + size, p, host,
- sizeof(host));
- if (len < 0)
- return 0;
- INCR_CHECK(p, len + 4); /* Name plus type plus class */
- }
-
- /*
- * We're now pointing at the answer records. Process the first
- * TXT record we find.
- */
-
- while (numanswers--) {
-
- /* First the name; use dn_expand to get the compressed size */
- len = dn_expand(answer.bytes, answer.bytes + size, p,
- host, sizeof(host));
- if (len < 0)
- return 0;
- INCR_CHECK(p, len);
-
- /* Next is the query type */
- CHECK(p, 2);
- type = NTOHSP(p,2);
-
- /* Next is the query class; also skip over 4 byte TTL */
- CHECK(p,6);
- class = NTOHSP(p,6);
-
- /* Record data length - make sure we aren't truncated */
-
- CHECK(p,2);
- rdlen = NTOHSP(p,2);
-
- if (p + rdlen > answer.bytes + size)
- return 0;
-
- /*
- * If this is a TXT record, return the string. Note that the
- * string has a 1-byte length in the front
- */
- /* XXX What about flagging multiple TXT records as an error? */
-
- if (class == C_IN && type == T_TXT) {
- len = *p++;
- if (p + len > answer.bytes + size)
- return 0;
- *retstr = malloc(len + 1);
- if (*retstr == NULL)
- return ENOMEM;
- strncpy(*retstr, (char *) p, len);
- (*retstr)[len] = '\0';
- /* Avoid a common error. */
- if ( (*retstr)[len-1] == '.' )
- (*retstr)[len-1] = '\0';
- return 1;
- }
- }
-
- return 0;
-}
-#undef INCR_CHECK
-#undef CHECK
-#undef NTOHSP
-#endif /* CK_DNS_SRV */
-
-#ifdef TNCODE
-#ifdef CK_FORWARD_X
-#ifdef UNIX
-#include <sys/un.h>
-#define FWDX_UNIX_SOCK
-#ifndef AF_LOCAL
-#define AF_LOCAL AF_UNIX
-#endif
-#ifndef PF_LOCAL
-#define PF_LOCAL PF_UNIX
-#endif
-#ifndef SUN_LEN
-/* Evaluate to actual length of the `sockaddr_un' structure. */
-#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
- + strlen ((ptr)->sun_path))
-#endif
-#endif /* UNIX */
-int
-fwdx_create_listen_socket(screen) int screen; {
-#ifdef NOPUTENV
- return(-1);
-#else /* NOPUTENV */
- struct sockaddr_in saddr;
- int display, port, sock=-1, i;
- static char env[512];
-
- /*
- * X Windows Servers support multiple displays by listening on
- * one socket per display. Display 0 is port 6000; Display 1 is
- * port 6001; etc.
- *
- * We start by trying to open port 6001 so that display 0 is
- * reserved for the local X Windows Server.
- */
-
- for ( display=1; display < 1000 ; display++ ) {
-
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- debug(F111,"fwdx_create_listen_socket()","socket() < 0",sock);
- return(-1);
- }
-
- port = 6000 + display;
- bzero((char *)&saddr, sizeof(saddr));
- saddr.sin_family = AF_INET;
- saddr.sin_addr.s_addr = inet_addr(myipaddr);
- saddr.sin_port = htons(port);
-
- if (bind(sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
- i = errno; /* Save error code */
-#ifdef TCPIPLIB
- socket_close(sock);
-#else /* TCPIPLIB */
- close(sock);
-#endif /* TCPIPLIB */
- sock = -1;
- debug(F110,"fwdx_create_listen_socket()","bind() < 0",0);
- continue;
- }
-
- debug(F100,"fdwx_create_listen_socket() bind OK","",0);
- break;
- }
-
- if ( display > 1000 ) {
- debug(F100,"fwdx_create_listen_socket() Out of Displays","",0);
- return(-1);
- }
-
- if (listen(sock, 5) < 0) {
- i = errno; /* Save error code */
-#ifdef TCPIPLIB
- socket_close(sock);
-#else /* TCPIPLIB */
- close(sock);
-#endif /* TCPIPLIB */
- debug(F101,"fdwx_create_listen_socket() listen() errno","",errno);
- return(-1);
- }
- debug(F100,"fwdx_create_listen_socket() listen OK","",0);
-
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket = sock;
- if (!myipaddr[0])
- getlocalipaddr();
- if ( myipaddr[0] )
- ckmakxmsg(env,sizeof(env),"DISPLAY=",myipaddr,":",
- ckuitoa(display),":",ckuitoa(screen),
- NULL,NULL,NULL,NULL,NULL,NULL);
- else
- ckmakmsg(env,sizeof(env),"DISPLAY=",ckuitoa(display),":",
- ckuitoa(screen));
- putenv(env);
- return(0);
-#endif /* NOPUTENV */
-}
-
-
-int
-fwdx_open_client_channel(channel) int channel; {
- char * env;
- struct sockaddr_in saddr;
-#ifdef FWDX_UNIX_SOCK
- struct sockaddr_un saddr_un = { AF_LOCAL };
-#endif /* FWDX_UNIX_SOCK */
- int colon, dot, display, port, sock, i, screen;
- int family;
- char buf[256], * host=NULL, * rest=NULL;
-#ifdef TCP_NODELAY
- int on=1;
-#endif /* TCP_NODELAY */
-
- debug(F111,"fwdx_create_client_channel()","channel",channel);
-
- for ( i=0; i<MAXFWDX ; i++ ) {
- if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].id == channel) {
- /* Already open */
- debug(F110,"fwdx_create_client_channel()","already open",0);
- return(0);
- }
- }
-
- env = getenv("DISPLAY");
- if ( !env )
- env = (char *)tn_get_display();
- if ( env )
- ckstrncpy(buf,env,256);
- else
- ckstrncpy(buf,"127.0.0.1:0.0",256);
-
- bzero((char *)&saddr,sizeof(saddr));
- saddr.sin_family = AF_INET;
-
- if (!fwdx_parse_displayname(buf,
- &family,
- &host,
- &display,
- &screen,
- &rest
- )
- ) {
- if ( host ) free(host);
- if ( rest ) free(rest);
- return(0);
- }
- if (rest) free(rest);
-
-#ifndef FWDX_UNIX_SOCK
- /* if $DISPLAY indicates use of unix domain sockets, but we don't support it,
- * we change things to use inet sockets on the ip loopback interface instead,
- * and hope that it works.
- */
- if (family == FamilyLocal) {
- debug(F100,"fwdx_create_client_channel() FamilyLocal","",0);
- family = FamilyInternet;
- if (host) free(host);
- if (host = malloc(strlen("localhost") + 1))
- strcpy(host, "localhost");
- else {
- return(-1);
- }
- }
-#else /* FWDX_UNIX_SOCK */
- if (family == FamilyLocal) {
- if (host) free(host);
- sock = socket(PF_LOCAL, SOCK_STREAM, 0);
- if (sock < 0)
- return(-1);
-
- ckmakmsg(buf,sizeof(buf),"/tmp/.X11-unix/X",ckitoa(display),NULL,NULL);
- strncpy(saddr_un.sun_path, buf, sizeof(saddr_un.sun_path));
- if (connect(sock,(struct sockaddr *)&saddr_un, SUN_LEN(&saddr_un)) < 0)
- return(-1);
- } else
-#endif /* FWDX_UNIX_SOCK */
- {
- /* Otherwise, we are assuming FamilyInternet */
- if (host) {
- ckstrncpy(buf,host,sizeof(buf));
- free(host);
- } else
- ckstrncpy(buf,myipaddr,sizeof(buf));
-
- debug(F111,"fwdx_create_client_channel()","display",display);
-
- port = 6000 + display;
- saddr.sin_port = htons(port);
-
- debug(F110,"fwdx_create_client_channel() ip-address",buf,0);
- saddr.sin_addr.s_addr = inet_addr(buf);
- if ( saddr.sin_addr.s_addr == (unsigned long) -1
-#ifdef INADDR_NONE
- || saddr.sin_addr.s_addr == INADDR_NONE
-#endif /* INADDR_NONE */
- )
- {
- struct hostent *host;
- host = gethostbyname(buf);
- if ( host == NULL )
- return(-1);
- host = ck_copyhostent(host);
-#ifdef HADDRLIST
-#ifdef h_addr
- /* This is for trying multiple IP addresses - see <netdb.h> */
- if (!(host->h_addr_list))
- return(-1);
- bcopy(host->h_addr_list[0],
- (caddr_t)&saddr.sin_addr,
- host->h_length
- );
-#else
- bcopy(host->h_addr, (caddr_t)&saddr.sin_addr, host->h_length);
-#endif /* h_addr */
-#else /* HADDRLIST */
- bcopy(host->h_addr, (caddr_t)&saddr.sin_addr, host->h_length);
-#endif /* HADDRLIST */
- }
-
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- debug(F111,"fwdx_create_client_channel()","socket() < 0",sock);
- return(-1);
- }
-
- if ( connect(sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
- debug(F110,"fwdx_create_client_channel()","connect() failed",0);
-#ifdef TCPIPLIB
- socket_close(sock);
-#else /* TCPIPLIB */
- close(sock);
-#endif /* TCPIPLIB */
- return(-1);
- }
-
-#ifdef TCP_NODELAY
- setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,(char *)&on,sizeof(on));
-#endif /* TCP_NODELAY */
- }
-
- for (i = 0; i < MAXFWDX; i++) {
- if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].id == -1) {
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].fd = sock;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].id = channel;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 1;
- debug(F111,"fwdx_create_client_channel()","socket",sock);
- return(0);
- }
- }
- return(-1);
-}
-
-int
-fwdx_server_avail() {
- char * env;
- struct sockaddr_in saddr;
-#ifdef FWDX_UNIX_SOCK
- struct sockaddr_un saddr_un = { AF_LOCAL };
-#endif /* FWDX_UNIX_SOCK */
- int colon, dot, display, port, sock, i, screen;
- char buf[256], *host=NULL, *rest=NULL;
-#ifdef TCP_NODELAY
- int on=1;
-#endif /* TCP_NODELAY */
- int family;
-
- env = getenv("DISPLAY");
- if ( !env )
- env = (char *)tn_get_display();
- if ( env )
- ckstrncpy(buf,env,256);
- else
- ckstrncpy(buf,"127.0.0.1:0.0",256);
-
- bzero((char *)&saddr,sizeof(saddr));
- saddr.sin_family = AF_INET;
-
- if (!fwdx_parse_displayname(buf,&family,&host,&display,&screen,&rest)) {
- if ( host ) free(host);
- if ( rest ) free(rest);
- return(0);
- }
- if (rest) free(rest);
-
-#ifndef FWDX_UNIX_SOCK
- /* if $DISPLAY indicates use of unix domain sockets, but we don't support it,
- * we change things to use inet sockets on the ip loopback interface instead,
- * and hope that it works.
- */
- if (family == FamilyLocal) {
- family = FamilyInternet;
- if (host) free(host);
- if (host = malloc(strlen("localhost") + 1))
- strcpy(host, "localhost");
- else {
- return(-1);
- }
- }
-#else /* FWDX_UNIX_SOCK */
- if (family == FamilyLocal) {
- debug(F100,"fwdx_server_avail() FamilyLocal","",0);
- if (host) free(host);
- sock = socket(PF_LOCAL, SOCK_STREAM, 0);
- if (sock < 0)
- return(0);
-
- ckmakmsg(buf,sizeof(buf),"/tmp/.X11-unix/X",ckitoa(display),NULL,NULL);
- strncpy(saddr_un.sun_path, buf, sizeof(saddr_un.sun_path));
- if (connect(sock,(struct sockaddr *)&saddr_un,SUN_LEN(&saddr_un)) < 0)
- return(0);
- close(sock);
- return(1);
- }
-#endif /* FWDX_UNIX_SOCK */
-
- /* Otherwise, we are assuming FamilyInternet */
- if (host) {
- ckstrncpy(buf,host,sizeof(buf));
- free(host);
- } else
- ckstrncpy(buf,myipaddr,sizeof(buf));
-
- debug(F111,"fwdx_server_avail()","display",display);
-
- port = 6000 + display;
- saddr.sin_port = htons(port);
-
- debug(F110,"fwdx_server_avail() ip-address",buf,0);
- saddr.sin_addr.s_addr = inet_addr(buf);
- if ( saddr.sin_addr.s_addr == (unsigned long) -1
-#ifdef INADDR_NONE
- || saddr.sin_addr.s_addr == INADDR_NONE
-#endif /* INADDR_NONE */
- )
- {
- struct hostent *host;
- host = gethostbyname(buf);
- if ( host == NULL ) {
- debug(F110,"fwdx_server_avail() gethostbyname() failed",
- myipaddr,0);
- return(-1);
- }
- host = ck_copyhostent(host);
-#ifdef HADDRLIST
-#ifdef h_addr
- /* This is for trying multiple IP addresses - see <netdb.h> */
- if (!(host->h_addr_list))
- return(-1);
- bcopy(host->h_addr_list[0],
- (caddr_t)&saddr.sin_addr,
- host->h_length
- );
-#else
- bcopy(host->h_addr, (caddr_t)&saddr.sin_addr, host->h_length);
-#endif /* h_addr */
-#else /* HADDRLIST */
- bcopy(host->h_addr, (caddr_t)&saddr.sin_addr, host->h_length);
-#endif /* HADDRLIST */
- }
-
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- debug(F111,"fwdx_server_avail()","socket() < 0",sock);
- return(0);
- }
-
- if ( connect(sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
- debug(F110,"fwdx_server_avail()","connect() failed",0);
-#ifdef TCPIPLIB
- socket_close(sock);
-#else /* TCPIPLIB */
- close(sock);
-#endif /* TCPIPLIB */
- return(0);
- }
-
-#ifdef TCPIPLIB
- socket_close(sock);
-#else /* TCPIPLIB */
- close(sock);
-#endif /* TCPIPLIB */
- return(1);
-}
-
-int
-fwdx_open_server_channel() {
- int sock, ready_to_accept, sock2,channel,i;
-#ifdef TCP_NODELAY
- int on=1;
-#endif /* TCP_NODELAY */
-#ifdef UCX50
- static u_int saddrlen;
-#else
- static SOCKOPT_T saddrlen;
-#endif /* UCX50 */
- struct sockaddr_in saddr;
- char sb[8];
- extern char tn_msg[];
-#ifdef BSDSELECT
- fd_set rfds;
- struct timeval tv;
-#else
-#ifdef BELLSELCT
- fd_set rfds;
-#else
- fd_set rfds;
- struct timeval {
- long tv_sec;
- long tv_usec;
- } tv;
-#endif /* BELLSELECT */
-#endif /* BSDSELECT */
- unsigned short nchannel;
- unsigned char * p;
-
- sock = TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket;
-
- try_again:
-
-#ifdef BSDSELECT
- tv.tv_sec = tv.tv_usec = 0L;
- tv.tv_usec = 50;
- FD_ZERO(&rfds);
- FD_SET(sock, &rfds);
- ready_to_accept =
- ((select(FD_SETSIZE,
-#ifdef HPUX
-#ifdef HPUX1010
- (fd_set *)
-#else
-
- (int *)
-#endif /* HPUX1010 */
-#else
-#ifdef __DECC
- (fd_set *)
-#endif /* __DECC */
-#endif /* HPUX */
- &rfds, NULL, NULL, &tv) > 0) &&
- FD_ISSET(sock, &rfds));
-#else /* BSDSELECT */
-#ifdef IBMSELECT
- ready_to_accept = (select(&sock, 1, 0, 0, 50) == 1);
-#else
-#ifdef BELLSELECT
- FD_ZERO(rfds);
- FD_SET(sock, rfds);
- ready_to_accept =
- ((select(128, rfds, NULL, NULL, 50) > 0) &&
- FD_ISSET(sock, rfds));
-#else
-/* Try this - what's the worst that can happen... */
-
- tv.tv_sec = tv.tv_usec = 0L;
- tv.tv_usec = 50;
- FD_ZERO(&rfds);
- FD_SET(sock, &rfds);
- ready_to_accept =
- ((select(FD_SETSIZE,
- (fd_set *) &rfds, NULL, NULL, &tv) > 0) &&
- FD_ISSET(sock, &rfds));
-#endif /* BELLSELECT */
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
-
- if ( !ready_to_accept )
- return(0);
-
- if ((sock2 = accept(sock,(struct sockaddr *)&saddr,&saddrlen)) < 0) {
- int i = errno; /* save error code */
- debug(F101,"tcpsrv_open accept errno","",i);
- return(-1);
- }
-
- /*
- * Now we have the open socket. We must now find a channel to store
- * it in, and then notify the client.
- */
-
- for ( channel=0;channel<MAXFWDX;channel++ ) {
- if ( TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[channel].fd == -1 )
- break;
- }
-
- if ( channel == MAXFWDX ) {
-#ifdef TCPIPLIB
- socket_close(sock2);
-#else /* TCPIPLIB */
- close(sock2);
-#endif /* TCPIPLIB */
- return(-1);
- }
-
- if ( fwdx_send_open(channel) < 0 ) {
-#ifdef TCPIPLIB
- socket_close(sock2);
-#else /* TCPIPLIB */
- close(sock2);
-#endif /* TCPIPLIB */
- }
-
-#ifdef TCP_NODELAY
- setsockopt(sock2,IPPROTO_TCP,TCP_NODELAY,(char *)&on,sizeof(on));
-#endif /* TCP_NODELAY */
-
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[channel].fd = sock2;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[channel].id = channel;
- goto try_again;
-
- return(0); /* never reached */
-}
-
-int
-fwdx_close_channel(channel) int channel; {
- int i,fd;
-
- for ( i=0; i<MAXFWDX ; i++ ) {
- if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].id == channel)
- break;
- }
- if ( i == MAXFWDX )
- return(-1);
-
- fd = TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].fd;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].fd = -1;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].id = -1;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0;
-
-#ifdef TCPIPLIB
- socket_close(fd);
-#else /* TCPIPLIB */
- close(fd);
-#endif /* TCPIPLIB */
- return(0);
-}
-
-int
-fwdx_close_all() {
- int x,fd;
-
- debug(F111,"fwdx_close_all()",
- "TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket",
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket);
-
- if ( TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket != -1 ) {
-#ifdef TCPIPLIB
- socket_close(TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket);
-#else /* TCPIPLIB */
- close(TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket);
-#endif /* TCPIPLIB */
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket = -1;
- }
-
- for (x = 0; x < MAXFWDX; x++) {
- if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].fd != -1) {
- fd = TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].fd;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].fd = -1;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].id = -1;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].need_to_send_xauth = 0;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].suspend = 0;
-#ifdef TCPIPLIB
- socket_close(fd);
-#else /* TCPIPLIB */
- close(fd);
-#endif /* TCPIPLIB */
- }
- }
- return(0);
-}
-
-/* The following definitions are for Unix */
-#ifndef socket_write
-#define socket_write(f,s,n) write(f,s,n)
-#endif /* socket_write */
-#ifndef socket_read
-#define socket_read(f,s,n) read(f,s,n)
-#endif /* socket_read */
-
-int
-fwdx_write_data_to_channel(channel, data, len)
- int channel; char * data; int len;
-{
- int sock, count, try=0, length = len, i;
-
- if ( len <= 0 )
- return(0);
-
- for ( i=0; i<MAXFWDX ; i++ ) {
- if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].id == channel)
- break;
- }
- if ( i == MAXFWDX ) {
- debug(F110,"fwdx_write_data_to_channel",
- "attempting to write to closed channel",0);
- return(-1);
- }
-
- sock = TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].fd;
- debug(F111,"fwdx_write_data_to_channel","socket",sock);
- ckhexdump("fwdx_write_data_to_channel",data,len);
-
- fwdx_write_data_to_channel_retry:
-
- if ((count = socket_write(sock,data,len)) < 0) {
- int s_errno = socket_errno; /* maybe a function */
- debug(F101,"fwdx_write_data_to_channel socket_write error","",s_errno);
-#ifdef BETATEST
- printf("fwdx_write_data_to_channel error\r\n");
-#endif /* BETATEST */
-#ifdef OS2
- if (os2socketerror(s_errno) < 0)
- return(-2);
-#endif /* OS2 */
- return(-1); /* Call it an i/o error */
- }
- if (count < len) {
- debug(F111,"fwdx_write_data_to_channel socket_write",data,count);
- if (count > 0) {
- data += count;
- len -= count;
- }
- debug(F111,"fwdx_write_data_to_channel retry",data,len);
- if ( len > 0 )
- goto fwdx_write_data_to_channel_retry;
- }
-
- debug(F111,"fwdx_write_data_to_channel complete",data,length);
- return(length); /* success - return total length */
-}
-
-VOID
-fwdx_check_sockets(fd_set *ibits)
-{
- int x, sock, channel, bytes;
- static char buffer[32000];
-
- debug(F100,"fwdx_check_sockets()","",0);
- if ( sstelnet && !TELOPT_ME(TELOPT_FORWARD_X) ||
- !sstelnet && !TELOPT_U(TELOPT_FORWARD_X)) {
- debug(F110,"fwdx_check_sockets()","TELOPT_FORWARD_X not negotiated",0);
- return;
- }
-
- for (x = 0; x < MAXFWDX; x++) {
- if ( TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].fd == -1 ||
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].suspend )
- continue;
-
- sock = TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].fd;
- if (FD_ISSET(sock, ibits))
- {
- channel = TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].id;
- debug(F111,"fwdx_check_sockets()","channel set",channel);
-
- bytes = socket_read(sock, buffer, sizeof(buffer));
- if (bytes > 0)
- fwdx_send_data_from_channel(channel, buffer, bytes);
- else if (bytes == 0) {
- fwdx_close_channel(channel);
- fwdx_send_close(channel);
- }
- }
- }
-}
-
-int
-fwdx_init_fd_set(fd_set *ibits)
-{
- int x,set=0,cnt=0;
-
- if ( sstelnet && !TELOPT_ME(TELOPT_FORWARD_X) ||
- !sstelnet && !TELOPT_U(TELOPT_FORWARD_X)) {
- debug(F110,"fwdx_init_fd_set()","TELOPT_FORWARD_X not negotiated",0);
- return(0);
- }
-
- if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket != -1) {
- set++;
- FD_SET(TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket, ibits);
- }
- for (x = 0; x < MAXFWDX; x++) {
- if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].fd != -1) {
- cnt++;
- if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].suspend)
- continue;
- set++;
- FD_SET(TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].fd, ibits);
- }
- }
- if (set + cnt == 0) {
- return(-1);
- } else {
- return(set);
- }
-}
-
-#ifdef NT
-VOID
-fwdx_thread( VOID * dummy )
-{
- fd_set ifds;
- struct timeval tv;
- extern int priority;
- int n;
-
- setint();
- SetThreadPrty(priority,isWin95() ? 3 : 11);
-
- while ( !sstelnet && TELOPT_U(TELOPT_FORWARD_X) ||
- sstelnet && TELOPT_ME(TELOPT_FORWARD_X))
- {
- FD_ZERO(&ifds);
- n = fwdx_init_fd_set(&ifds);
- if (n > 0) {
- tv.tv_sec = 0;
- tv.tv_usec = 2500;
- if ( select(FD_SETSIZE, &ifds, NULL, NULL, &tv) > 0 )
- fwdx_check_sockets(&ifds);
-
- } else if (n < 0) {
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.thread_started = 0;
- ckThreadEnd(NULL);
- } else {
- sleep(1);
- }
- }
-}
-#endif /* NT */
-#endif /* CK_FORWARD_X */
-#endif /* TNCODE */
-#endif /* NETCONN */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcnet.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckcnet.h
deleted file mode 100644
index 040bc74..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcnet.h
+++ /dev/null
@@ -1,1509 +0,0 @@
-/* ckcnet.h -- Symbol and macro definitions for C-Kermit network support */
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#ifndef CKCNET_H
-#define CKCNET_H
-
-/* Network types */
-
-#define NET_NONE 0 /* None */
-#define NET_TCPB 1 /* TCP/IP Berkeley (socket) */
-#define NET_TCPA 2 /* TCP/IP AT&T (streams) */
-#define NET_SX25 3 /* SUNOS SunLink X.25 */
-#define NET_DEC 4 /* DECnet */
-#define NET_VPSI 5 /* VAX PSI */
-#define NET_PIPE 6 /* LAN Manager Named Pipe */
-#define NET_VX25 7 /* Stratus VOS X.25 */
-#define NET_BIOS 8 /* IBM NetBios */
-#define NET_SLAT 9 /* Meridian Technologies' SuperLAT */
-#define NET_FILE 10 /* Read from a file */
-#define NET_CMD 11 /* Read from a sub-process */
-#define NET_DLL 12 /* Load a DLL for use as comm channel*/
-#define NET_IX25 13 /* IBM AIX 4.1 X.25 */
-#define NET_HX25 14 /* HP-UX 10 X.25 */
-#define NET_PTY 15 /* Pseudoterminal */
-#define NET_SSH 16 /* SSH */
-
-#ifdef OS2 /* In OS/2, only the 32-bit */
-#ifndef __32BIT__ /* version gets NETBIOS */
-#ifdef CK_NETBIOS
-#undef CK_NETBIOS
-#endif /* CK_NETBIOS */
-#endif /* __32BIT__ */
-#endif /* OS2 */
-
-#ifdef _M_PPC
-#ifdef SUPERLAT
-#undef SUPERLAT
-#endif /* SUPERLAT */
-#endif /* _M_PPC */
-
-#ifdef NPIPE /* For items in common to */
-#define NPIPEORBIOS /* Named Pipes and NETBIOS */
-#endif /* NPIPE */
-#ifdef CK_NETBIOS
-#ifndef NPIPEORBIOS
-#define NPIPEORBIOS
-#endif /* NPIPEORBIOS */
-#endif /* CK_NETBIOS */
-
-/* Network virtual terminal protocols (for SET HOST connections) */
-/* FTP, HTTP and SSH have their own stacks */
-
-#define NP_DEFAULT 255
-#define NP_NONE 0 /* None (async) */
-#define NP_TELNET 1 /* TCP/IP telnet */
-#define NP_VTP 2 /* ISO Virtual Terminal Protocol */
-#define NP_X3 3 /* CCITT X.3 */
-#define NP_X28 4 /* CCITT X.28 */
-#define NP_X29 5 /* CCITT X.29 */
-#define NP_RLOGIN 6 /* TCP/IP Remote login */
-#define NP_KERMIT 7 /* TCP/IP Kermit */
-#define NP_TCPRAW 8 /* TCP/IP Raw socket */
-#define NP_TCPUNK 9 /* TCP/IP Unknown */
-#define NP_SSL 10 /* TCP/IP SSLv23 */
-#define NP_TLS 11 /* TCP/IP TLSv1 */
-#define NP_SSL_TELNET 12 /* TCP/IP Telnet over SSLv23 */
-#define NP_TLS_TELNET 13 /* TCP/IP Telnet over TLSv1 */
-#define NP_K4LOGIN 14 /* TCP/IP Kerberized remote login */
-#define NP_EK4LOGIN 15 /* TCP/IP Encrypted Kerberized ... */
-#define NP_K5LOGIN 16 /* TCP/IP Kerberized remote login */
-#define NP_EK5LOGIN 17 /* TCP/IP Encrypted Kerberized ... */
-#define NP_K5U2U 18 /* TCP/IP Kerberos 5 User to User */
-#define NP_CTERM 19 /* DEC CTERM */
-#define NP_LAT 20 /* DEC LAT */
-#define NP_SSL_RAW 21 /* SSL with no Telnet permitted */
-#define NP_TLS_RAW 22 /* TLS with no Telnet permitted */
-
-/* others here... */
-
-#ifdef CK_SSL
-#define IS_TELNET() (nettype == NET_TCPB && (ttnproto == NP_TELNET \
- || ttnproto == NP_SSL_TELNET \
- || ttnproto == NP_TLS_TELNET \
- || ttnproto == NP_KERMIT))
-#else /* CK_SSL */
-#define IS_TELNET() (nettype == NET_TCPB && (ttnproto == NP_TELNET \
- || ttnproto == NP_KERMIT))
-#endif /* CK_SSL */
-
-#ifdef CK_KERBEROS
-#ifdef KRB5
-#ifdef KRB4
-#define IS_RLOGIN() (nettype == NET_TCPB && (ttnproto == NP_RLOGIN \
- || ttnproto == NP_K5LOGIN \
- || ttnproto == NP_EK5LOGIN \
- || ttnproto == NP_K4LOGIN \
- || ttnproto == NP_EK4LOGIN \
- ))
-#else /* KRB4 */
-#define IS_RLOGIN() (nettype == NET_TCPB && (ttnproto == NP_RLOGIN \
- || ttnproto == NP_K5LOGIN \
- || ttnproto == NP_EK5LOGIN \
- ))
-#endif /* KRB4 */
-#else /* KRB5 */
-#ifdef KRB4
-#define IS_RLOGIN() (nettype == NET_TCPB && (ttnproto == NP_RLOGIN \
- || ttnproto == NP_K4LOGIN \
- || ttnproto == NP_EK4LOGIN \
- ))
-#else /* KRB4 */
-KERBEROS defined without either KRB4 or KRB5
-#endif /* KRB4 */
-#endif /* KRB5 */
-#else /* CK_KERBEROS */
-#define IS_RLOGIN() (nettype == NET_TCPB && (ttnproto == NP_RLOGIN))
-#endif /* CK_KERBEROS */
-
-#define IS_SSH() (nettype == NET_SSH)
-
-/* RLOGIN Modes */
-#define RL_RAW 0 /* Do Not Process XON/XOFF */
-#define RL_COOKED 1 /* Do Process XON/XOFF */
-
-/* Encryption types */
-
-#define CX_NONE 999
-
-#ifdef ENCTYPE_ANY
-#define CX_AUTO ENCTYPE_ANY
-#else
-#define CX_AUTO 0
-#endif /* ENCTYPE_ANY */
-
-#ifdef ENCTYPE_DES_CFB64
-#define CX_DESC64 ENCTYPE_DES_CFB64
-#else
-#define CX_DESC64 1
-#endif /* ENCTYPE_DES_CFB64 */
-
-#ifdef ENCTYPE_DES_OFB64
-#define CX_DESO64 ENCTYPE_DES_OFB64
-#else
-#define CX_DESO64 2
-#endif /* ENCTYPE_DES_OFB64 */
-
-#ifdef ENCTYPE_DES3_CFB64
-#define CX_DES3C64 ENCTYPE_DES3_CFB64
-#else
-#define CX_DES3C64 3
-#endif /* ENCTYPE_DES_CFB64 */
-
-#ifdef ENCTYPE_DES3_OFB64
-#define CX_DESO64 ENCTYPE_DES3_OFB64
-#else
-#define CX_DES3O64 4
-#endif /* ENCTYPE_DES_OFB64 */
-
-#ifdef ENCTYPE_CAST5_40_CFB64
-#define CX_C540C64 ENCTYPE_CAST5_40_CFB64
-#else
-#define CX_C540C64 8
-#endif /* ENCTYPE_CAST5_40_CFB64 */
-
-#ifdef ENCTYPE_CAST5_40_OFB64
-#define CX_C540O64 ENCTYPE_CAST5_40_OFB64
-#else
-#define CX_C540O64 9
-#endif /* ENCTYPE_CAST5_40_OFB64 */
-
-#ifdef ENCTYPE_CAST128_CFB64
-#define CX_C128C64 ENCTYPE_CAST128_CFB64
-#else
-#define CX_C128C64 10
-#endif /* ENCTYPE_CAST128_CFB64 */
-
-#ifdef ENCTYPE_CAST128_OFB64
-#define CX_C128O64 ENCTYPE_CAST128_OFB64
-#else
-#define CX_C128O64 11
-#endif /* ENCTYPE_CAST128_OFB64 */
-
-/* Basic network function prototypes, common to all. */
-
-_PROTOTYP( int netopen, (char *, int *, int) );
-_PROTOTYP( int netclos, (void) );
-_PROTOTYP( int netflui, (void) );
-_PROTOTYP( int nettchk, (void) );
-_PROTOTYP( int netxchk, (int) );
-_PROTOTYP( int netbreak, (void) );
-_PROTOTYP( int netinc, (int) );
-_PROTOTYP( int netxin, (int, CHAR *) );
-_PROTOTYP( int nettol, (CHAR *, int) );
-_PROTOTYP( int nettoc, (CHAR) );
-#ifdef TCPSOCKET
-_PROTOTYP( int gettcpport, (void) );
-_PROTOTYP( int gettcpport, (void) );
-#endif /* TCPSOCKET */
-
-/*
- SunLink X.25 support by Marcello Frutig, Catholic University,
- Rio de Janeiro, Brazil, 1990.
-
- Maybe this can be adapted to VAX PSI and other X.25 products too.
-*/
-#ifndef SUNOS4 /* Only valid for SUNOS4 */
-#ifndef SOLARIS
-#ifdef SUNX25
-#undef SUNX25
-#endif /* SUNX25 */
-#endif /* SOLARIS */
-#endif /* SUNOS4 */
-
-#ifdef STRATUSX25
-#define ANYX25
-#define MAX_USER_DATA 128 /* SUN defines this in a header file, I believe. */
-#endif /* STRATUSX25 */
-
-#ifdef SUNX25
-#define ANYX25
-#endif /* SUNX25 */
-
-#ifdef IBMX25 /* AIX 4.1 X.25 */
-#ifndef AIX41
-#undef IBMX25
-#else /* AIX41 */
-#define ANYX25
-#define MAX_USER_DATA NPI_MAX_DATA /* used for buffer sizes */
-#endif /* AIX41 */
-#endif /* IBMX25 */
-
-#ifdef HPX25 /* HP-UX 10.* X.25 */
-#ifndef HPUX10
-#undef HPX25
-#else /* HPUX10 */
-#define ANYX25
-#endif /* HPUX10 */
-#endif /* HPX25 */
-
-#ifdef ANYX25
-#ifndef NETCONN /* ANYX25 implies NETCONN */
-#define NETCONN
-#endif /* NETCONN */
-
-#define MAXPADPARMS 22 /* Number of PAD parameters */
-#define MAXCUDATA 12 /* Max length of X.25 call user data */
-#define X29PID 1 /* X.29 protocol ID */
-#define X29PIDLEN 4 /* X.29 protocol ID length */
-
-#define X29_SET_PARMS 2
-#define X29_READ_PARMS 4
-#define X29_SET_AND_READ_PARMS 6
-#define X29_INVITATION_TO_CLEAR 1
-#define X29_PARAMETER_INDICATION 0
-#define X29_INDICATION_OF_BREAK 3
-#define X29_ERROR 5
-
-#define INVALID_PAD_PARM 1
-
-#define PAD_BREAK_CHARACTER 0
-
-#define PAD_ESCAPE 1
-#define PAD_ECHO 2
-#define PAD_DATA_FORWARD_CHAR 3
-#define PAD_DATA_FORWARD_TIMEOUT 4
-#define PAD_FLOW_CONTROL_BY_PAD 5
-#define PAD_SUPPRESSION_OF_SIGNALS 6
-#define PAD_BREAK_ACTION 7
-#define PAD_SUPPRESSION_OF_DATA 8
-#define PAD_PADDING_AFTER_CR 9
-#define PAD_LINE_FOLDING 10
-#define PAD_LINE_SPEED 11
-#define PAD_FLOW_CONTROL_BY_USER 12
-#define PAD_LF_AFTER_CR 13
-#define PAD_PADDING_AFTER_LF 14
-#define PAD_EDITING 15
-#define PAD_CHAR_DELETE_CHAR 16
-#define PAD_BUFFER_DELETE_CHAR 17
-#define PAD_BUFFER_DISPLAY_CHAR 18
-
-#define MAXIX25 MAX_USER_DATA*7
-#define MAXOX25 MAX_USER_DATA
-#endif /* ANYX25 */
-
-#ifdef SUNX25
-#ifdef SOLARIS25 /* and presumably SunLink 9.xx */
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/ioccom.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sundev/syncstat.h>
-#include <netx25/x25_pk.h>
-#include <netx25/x25_ctl.h>
-#include <netx25/x25_ioctl.h>
-#else
-#include <sys/ioctl.h> /* X.25 includes, Sun only */
-#include <sys/systm.h>
-#ifndef SOLARIS
-#include <sys/mbuf.h>
-#endif /* SOLARIS */
-#include <sys/socket.h>
-#include <sys/protosw.h>
-#ifdef SOLARIS
-#include <sys/sockio.h>
-#else
-#include <sys/domain.h>
-#endif /* SOLARIS */
-#include <sys/socketvar.h>
-#include <net/if.h>
-#include <sundev/syncstat.h>
-#include <netx25/x25_pk.h>
-#include <netx25/x25_ctl.h>
-#include <netx25/x25_ioctl.h>
-#endif /* SOLARIS25 */
-#endif /* SUNX25 */
-
-#ifdef ANYX25
-
-#ifdef IBMX25 /* X.25 includes, AIX only */
-#include <fcntl.h>
-#include <sys/twtypes.h>
-#include <sys/twlib.h>
-
-#include <sys/stream.h>
-#include <stropts.h>
-
-#define NPI_20 /* required to include the whole NPI */
-#include <sys/npi_20.h>
-#include <sys/npiapi.h>
-#include <sys/pktintf.h>
-
-#include <odmi.h> /* required for access to the ODM */
-#include <sys/cfgodm.h> /* database, needed to find out the */
- /* local NUA. see x25local_nua() */
-
-
-/* IBM X25 NPI generic primitive type */
-typedef union N_npi_ctl_t {
- ulong PRIM_type; /* generic primitive type */
- char buffer[NPI_MAX_CTL]; /* maximum primitive size */
- N_bind_ack_t bind_ack;
- N_bind_req_t bind_req;
- N_conn_con_t conn_con;
- N_conn_ind_t conn_ind;
- N_conn_req_t conn_req;
- N_conn_res_t conn_res;
- N_data_req_t data_req;
- N_data_ind_t data_ind;
- N_discon_ind_t discon_ind;
- N_discon_req_t discon_req;
- N_error_ack_t error_ack;
- N_exdata_ind_t exdata_ind;
- N_info_ack_t info_ack;
- N_ok_ack_t ok_ack;
- N_reset_con_t reset_con;
- N_reset_req_t reset_req;
- N_reset_ind_t reset_ind;
-} N_npi_ctl_t;
-
-/* some extra definitions to help out */
-typedef char x25addr_t[45]; /* max 40 defined by CCITT */
-typedef char N_npi_data_t[NPI_MAX_DATA];
-
-/* fd or server waiting for connections, used by netclos and netopen */
-extern int x25serverfd;
-
-#endif /* IBMX25 */
-
-#ifdef HPX25 /* X.25 includes, HP-UX only */
-#include <x25/ccittproto.h>
-#include <x25/x25.h>
-#include <x25/x25addrstr.h>
-#include <x25/x25codes.h>
-#include <x25/x25hd_ioctl.h>
-#include <x25/x25ioctls.h>
-#include <x25/x25str.h>
-#include <sys/ioctl.h>
-#endif /* HPX25 */
-
-/* C-Kermit X.3 / X.25 / X.29 / X.121 support functions */
-
-/* (riehm: this list of functions isn't quite right for AIX) */
-
-_PROTOTYP( int shopad, (int) );
-_PROTOTYP( int shox25, (int) );
-_PROTOTYP( VOID initpad, (void) );
-_PROTOTYP( VOID setpad, (CHAR *, int) );
-_PROTOTYP( VOID readpad, (CHAR *, int, CHAR *) );
-_PROTOTYP( int qbitpkt, (CHAR *, int) );
-_PROTOTYP( VOID setqbit, (void) );
-_PROTOTYP( VOID resetqbit, (void) );
-_PROTOTYP( VOID breakact, (void) );
-_PROTOTYP( int pkx121, (char *, CHAR *) );
-_PROTOTYP( SIGTYP x25oobh, (int) );
-_PROTOTYP( int x25diag, (void) );
-_PROTOTYP( int x25intr, (char) );
-_PROTOTYP( int x25reset, (char, char) );
-_PROTOTYP( int x25clear, (void) );
-_PROTOTYP( int x25stat, (void) );
-_PROTOTYP( int x25in, (int, CHAR *) );
-_PROTOTYP( int setpadp, (void) );
-_PROTOTYP( int setx25, (void) );
-_PROTOTYP( int x25xin, (int, CHAR *) );
-_PROTOTYP( int x25inl, (CHAR *, int, int, CHAR) );
-
-#ifdef IBMX25
- /* setup x25 */
-_PROTOTYP( ulong x25bind, (int, char *, char *, int, int, int, ulong) );
-_PROTOTYP( int x25call, (int, char *, char *) ); /* connect to remote */
-_PROTOTYP( int x25unbind, (int) ); /* disconnect */
-_PROTOTYP( char *x25prim, (int) ); /* display primitives */
-_PROTOTYP( int x25local_nua, (char *) ); /* find local NUA */
-#endif /* IBMX25 */
-
-#endif /* ANYX25 */
-
-/* CMU-OpenVMS/IP */
-
-#ifdef CMU_TCPIP /* CMU_TCPIP implies TCPSOCKET */
-#ifndef TCPSOCKET
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#ifndef TCPIPLIB
-#define TCPIPLIB
-#endif /* TCPIPLIB */
-#endif /* CMU_TCPIP */
-
-/* DEC TCP/IP for (Open)VMS, previously known as UCX */
-
-#ifdef DEC_TCPIP /* DEC_TCPIP implies TCPSOCKET */
-#ifndef TCPSOCKET
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#ifndef TCPIPLIB
-#define TCPIPLIB
-#endif /* TCPIPLIB */
-#endif /* DEC_TCPIP */
-
-/* SRI/TGV/Cisco/Process MultiNet, TCP/IP for VAX/VMS */
-
-#ifdef MULTINET /* MULTINET implies TCPSOCKET */
-#ifndef TCPSOCKET
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#ifndef TCPIPLIB
-#define TCPIPLIB
-#endif /* TCPIPLIB */
-#ifndef TGVORWIN /* MULTINET and WINTCP */
-#define TGVORWIN /* share a lot of code... */
-#endif /* TGVORWIN */
-#endif /* MULTINET */
-
-/* Wollongong TCP/IP for VAX/VMS */
-
-#ifdef WINTCP /* WINTCP implies TCPSOCKET */
-#ifndef TCPSOCKET
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#ifndef TCPIPLIB
-#define TCPIPLIB
-#endif /* TCPIPLIB */
-#ifndef TGVORWIN /* WINTCP and MULTINET */
-#define TGVORWIN /* share a lot of code... */
-#endif /* TGVORWIN */
-#endif /* WINTCP */
-
-/* Wollongong TCP/IP for AT&T Sys V */
-
-#ifdef WOLLONGONG /* WOLLONGONG implies TCPSOCKET */
-#ifndef TCPSOCKET /* Don't confuse WOLLONGONG */
-#define TCPSOCKET /* (which is for UNIX) with */
-#endif /* TCPSOCKET */ /* WINTCP, which is for VMS! */
-#endif /* WOLLONGONG */
-
-#ifdef EXCELAN /* EXCELAN implies TCPSOCKET */
-#ifndef TCPSOCKET
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#endif /* EXCELAN */
-
-#ifdef INTERLAN /* INTERLAN implies TCPSOCKET */
-#ifndef TCPSOCKET
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#endif /* INTERLAN */
-
-#ifdef BEBOX
-#ifndef TCPSOCKET
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#ifndef TCPIPLIB
-#define TCPIPLIB
-#endif /* TCPIPLIB */
-#define socket_errno h_errno
-#define socket_read(x,y,z) recv(x,y,sizeof(char),z)
-#define socket_write(x,y,z) send(x,y,sizeof(char),z)
-#define socket_ioctl ioctl
-#define socket_close(x) closesocket(x)
-#ifndef FIONBIO
-#define FIONBIO 2
-#endif /* FIONBIO */
-#ifndef FIONREAD
-#define FIONREAD 1
-#endif /* FIONREAD */
-#ifndef SIOCATMARK
-#define SIOCATMARK 3
-#endif /* SIOCATMARK */
-#endif /* BEBOX */
-
-#ifdef COMMENT /* no longer used but might come in handy again later... */
-/*
- CK_READ0 can (and should) be defined if and only if:
- (a) read(fd,&x,0) can be used harmlessly on a TCP/IP socket connection.
- (b) read(fd,&x,0) returns 0 if the connection is up, -1 if it is down.
-*/
-#ifndef CK_READ0
-#ifdef TCPSOCKET
-#ifdef SUNOS41 /* It works in SunOS 4.1 */
-#define CK_READ0
-#else
-#ifdef NEXT /* and NeXTSTEP */
-#define CK_READ0
-#endif /* NEXT */
-#endif /* SUNOS41 */
-#endif /* TCPSOCKET */
-#endif /* CK_READ0 */
-#endif /* COMMENT */
-
-/* Telnet protocol */
-
-#ifdef TCPSOCKET /* TCPSOCKET implies TNCODE */
-#ifndef TNCODE /* Which means... */
-#define TNCODE /* Compile in telnet code */
-#endif /* TNCODE */
-
-/*
- Platforms where we must call gethostname(buf,len) and then
- gethostbyname(buf) to get local IP address, rather than calling
- gethostbyname("").
-*/
-#ifndef CKGHNLHOST
-#ifdef datageneral
-#define CKGHNLHOST
-#else
-#ifdef SOLARIS
-#define CKGHNLHOST
-#else
-#ifdef SUNOS4
-#define CKGHNLHOST
-#else
-#ifdef UNIXWARE
-#define CKGHNLHOST
-#else
-#ifdef SINIX
-#define CKGHNLHOST
-#endif /* SINIX */
-#endif /* UNIXWARE */
-#endif /* SUNOS4 */
-#endif /* SOLARIS */
-#endif /* datageneral */
-#endif /* CKGHNLHOST */
-
-#ifndef RLOGCODE /* What about Rlogin? */
-#ifndef NORLOGIN
-/*
- Rlogin can be enabled only for UNIX versions that have both SIGURG
- (SCO doesn't) and CK_TTGWSIZ (OSF/1 doesn't), so we don't assume that
- any others have these without verifying first. Not that it really makes
- much difference since you can only use Rlogin if you are root...
-*/
-#ifdef SUNOS41
-#define RLOGCODE
-#else
-#ifdef SOLARIS
-#define RLOGCODE
-#else
-#ifdef HPUX9
-#define RLOGCODE
-#else
-#ifdef HPUX10
-#define RLOGCODE
-#else
-#ifdef OSF40
-#define RLOGCODE
-#else
-#ifdef NEXT
-#define RLOGCODE
-#else
-#ifdef AIX41
-#define RLOGCODE
-#else
-#ifdef UNIXWARE
-#define RLOGCODE
-#else
-#ifdef IRIX51
-#define RLOGCODE
-#else
-#ifdef IRIX60
-#define RLOGCODE
-#else
-#ifdef QNX
-#define RLOGCODE
-#else
-#ifdef __linux__
-#define RLOGCODE
-#else
-#ifdef BSD44
-#define RLOGCODE
-#endif /* BSD44 */
-#endif /* __linux__ */
-#endif /* QNX */
-#endif /* IRIX60 */
-#endif /* IRIX51 */
-#endif /* UNIXWARE */
-#endif /* AIX41 */
-#endif /* NEXT */
-#endif /* OSF40 */
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* SOLARIS */
-#endif /* SUNOS41 */
-#endif /* NORLOGIN */
-#ifdef VMS /* VMS */
-#define RLOGCODE
-#endif /* VMS */
-#endif /* RLOGCODE */
-#endif /* TCPSOCKET */
-
-#ifdef TNCODE
-/*
- Telnet local-echo buffer, used for saving up user data that can't be
- properly displayed and/or evaluated until pending Telnet negotiations are
- complete. TTLEBUF is defined for platforms (like UNIX) where net i/o is
- done by the same routines that do serial i/o (in which case the relevant
- code goes into the ck?tio.c module, in the ttinc(), ttchk(), etc, routines);
- NETLETBUF is defined for platforms (like VMS) that use different APIs for
- network and serial i/o, and enables the copies of the same routines that
- are in ckcnet.c.
-*/
-#ifndef TTLEBUF
-#ifdef UNIX
-#define TTLEBUF
-#else
-#ifdef datageneral
-#define TTLEBUF
-#endif /* datageneral */
-#endif /* UNIX */
-#endif /* TTLEBUF */
-
-#ifndef NETLEBUF
-#ifdef VMS
-#define NETLEBUF
-#endif /* VMS */
-#endif /* NETLEBUF */
-#endif /* TNCODE */
-
-#ifdef SUNX25 /* SUNX25 implies TCPSOCKET */
-#ifndef TCPSOCKET /* But doesn't imply TNCODE */
-#define TCPSOCKET
-#endif /* TCPSOCKET */
-#endif /* SUNX25 */
-
-#ifndef TCPSOCKET
-#ifndef NO_DNS_SRV
-#define NO_DNS_SRV
-#endif /* NO_DNS_SRV */
-#endif /* TCPSOCKET */
-
-/* This is another TCPSOCKET section... */
-
-#ifdef TCPSOCKET
-#ifndef NETCONN /* TCPSOCKET implies NETCONN */
-#define NETCONN
-#endif /* NETCONN */
-
-#ifndef NO_DNS_SRV
-#ifdef NOLOCAL
-#define NO_DNS_SRV
-#endif /* NOLOCAL */
-#ifdef OS2ONLY
-#define NO_DNS_SRV
-#endif /* OS2ONLY */
-#ifdef NT
-#ifdef _M_PPC
-#define NO_DNS_SRV
-#endif /* _M_DNS */
-#endif /* NO_DNS_SRV */
-#ifdef VMS
-#define NO_DNS_SRV
-#endif /* VMS */
-#ifdef STRATUS
-#define NO_DNS_SRV
-#endif /* STRATUS */
-#ifdef datageneral
-#define NO_DNS_SRV
-#endif /* datageneral */
-#ifdef ultrix
-#define NO_DNS_SRV
-#endif /* ultrix */
-#ifdef NEXT
-#define NO_DNS_SRV
-#endif /* NEXT */
-#endif /* NO_DNS_SRV */
-
-#ifndef CK_DNS_SRV /* Use DNS SRV records to determine */
-#ifndef NO_DNS_SRV /* host and ports */
-#define CK_DNS_SRV
-#endif /* NO_DNS_SRV */
-#endif /* CK_DNS_SRV */
-
-#ifndef NOLISTEN /* select() is required to support */
-#ifndef SELECT /* incoming connections. */
-#ifndef VMS
-#ifndef OS2
-#define NOLISTEN
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* SELECT */
-#endif /* NOLISTEN */
-
-/* BSD sockets library header files */
-
-#ifdef VMS
-/*
- Because bzero() and bcopy() are not portable among VMS versions,
- or compilers, or TCP/IP products, etc.
-*/
-#ifndef bzero
-#define bzero(s,n) memset(s,0,n)
-#endif /* bzero */
-#ifndef bcopy
-#define bcopy(h,a,l) memcpy(a,h,l)
-#endif /* bcopy */
-#endif /* VMS */
-
-#ifdef HPUX6
-/* These are missing in HP-UX 6.xx */
-#ifndef bzero
-#define bzero(s,n) memset(s,0,n)
-#endif /* bzero */
-#ifndef bcopy
-#define bcopy(h,a,l) memcpy(a,h,l)
-#endif /* bcopy */
-#endif /* HPUX6 */
-
-#ifdef UNIX /* UNIX section */
-
-#ifdef SVR4
-/*
- These suggested by Rob Healey, rhealey@kas.helios.mn.org, to avoid
- bugs in Berkeley compatibility library on Sys V R4 systems, but untested
- by me (fdc). Remove this bit if it gives you trouble.
- (Later corrected by Marc Boucher <mboucher@iro.umontreal.ca> because
- bzero/bcopy are not argument-compatible with memset/memcpy|memmove.)
-*/
-#ifndef bzero
-#define bzero(s,n) memset(s,0,n)
-#endif
-#ifdef SOLARIS
-#ifdef SUNX25
-#undef bzero
-/*
- WOULD YOU BELIEVE... That the Solaris X.25 /opt/SUNWcomm/lib/libsockx25
- library references bzero, even though the use of bzero is forbidden in
- Solaris? Look for the function definition in ckcnet.c.
-*/
-_PROTOTYP( void bzero, (char *, int) );
-#endif /* SUNX25 */
-#ifndef bcopy
-#define bcopy(h,a,l) memcpy(a,h,l)
-#endif
-#else
-#ifndef bcopy
-#define bcopy(h,a,l) memmove(a,h,l)
-#endif
-#endif /* SOLARIS */
-#else /* !SVR4 */
-#ifdef PTX /* Sequent DYNIX PTX 1.3 */
-#ifndef bzero
-#define bzero(s,n) memset(s,0,n)
-#endif
-#ifndef bcopy
-#define bcopy(h,a,l) memcpy(a,h,l)
-#endif
-#endif /* PTX */
-#endif /* SVR4 */
-
-#ifdef INTERLAN /* Racal-Interlan TCP/IP */
-#include <interlan/socket.h>
-#include <interlan/il_types.h>
-#include <interlan/telnet.h>
-#include <interlan/il_errno.h>
-#include <interlan/in.h>
-#include <interlan/telnet.h> /* Why twice ? ? ? */
-#else /* Not Interlan */
-#ifdef BEBOX
-#include <socket.h>
-#else /* Not BEBOX */ /* Normal BSD TCP/IP library */
-#ifdef COMMENT
-#ifndef HPUX
-#include <arpa/telnet.h>
-#endif /* HPUX */
-#endif /* COMMENT */
-#ifdef SCO234
-#include <sys/errno.tcp.h>
-#include <sys/types.tcp.h>
-#endif /* SCO234 */
-#include <sys/socket.h>
-#ifdef WOLLONGONG
-#include <sys/in.h>
-#else
-#include <netinet/in.h>
-#ifndef SV68R3V6 /* (maybe this should be SVR3 in general) */
-#include <netinet/tcp.h> /* Added June 2001 */
-#endif /* SV68R3V6 */
-#endif /* WOLLONGONG */
-#endif /* BEBOX */
-#endif /* INTERLAN */
-
-#ifndef EXCELAN
-#include <netdb.h>
-#ifndef INTERLAN
-#ifdef WOLLONGONG
-#define minor /* Do not include <sys/macros.h> */
-#include <sys/inet.h>
-#else
-#ifndef OXOS
-#ifndef HPUX
-#ifndef BEBOX
-#include <arpa/inet.h>
-#endif /* BEBOX */
-#endif /* HPUX */
-#else /* OXOS */
-/* In too many releases of X/OS, <arpa/inet.h> declares inet_addr() as
- * ``struct in_addr''. This is definitively wrong, and could cause
- * core dumps. Instead of including that bad file, inet_addr() is
- * correctly declared here. Of course, all the declarations done there
- * has been copied here.
- */
-unsigned long inet_addr();
-char *inet_ntoa();
-struct in_addr inet_makeaddr();
-unsigned long inet_network();
-#endif /* OXOS */
-#endif /* WOLLONGONG */
-#endif /* INTERLAN */
-#endif /* EXCELAN */
-
-#ifdef EXCELAN /* Excelan TCP/IP */
-#ifndef bzero
-#define bzero(s,n) memset(s,0,n)
-#endif /* bzero */
-#ifndef bcopy
-#define bcopy(h,a,l) memcpy(a,h,l)
-#endif /* bcopy */
-#include <ex_errno.h>
-#endif /* EXCELAN */
-
-#ifdef I386IX /* Interactive Sys V R3 network. */
-/* #define TELOPTS */ /* This might need defining. */
-#define ORG_NLONG ENAMETOOLONG /* Resolve conflicting symbols */
-#undef ENAMETOOLONG /* in <errno.h> and <net/errno.h> */
-#define ORG_NEMPTY ENOTEMPTY
-#undef ENOTEMPTY
-#include <net/errno.h>
-#undef ENAMETOOLONG
-#define ENAMETOOLONG ORG_NLONG
-#undef ENOTEMPTY
-#define ENOTEMPTY ORG_NEMPTY
-#include <netinet/tcp.h> /* for inet_addr() */
-#endif /* I386IX */
-/*
- Data type of the inet_addr() function...
- We define INADDRX if it is of type struct inaddr.
- If it is undefined, unsigned long is assumed.
- Look at <arpa/inet.h> to find out. The following known cases are
- handled here. Other systems that need it can be added here, or else
- -DINADDRX can be included in the CFLAGS on the cc command line.
-*/
-#ifndef NOINADDRX
-#ifdef DU2 /* DEC Ultrix 2.0 */
-#define INADDRX
-#endif /* DU2 */
-#endif /* NOINADDRX */
-
-#else /* Not UNIX */
-
-#ifdef VMS /* (Open)VMS section */
-
-#ifdef MULTINET /* TGV MultiNet */
-/*
- In C-Kermit 7.0 Beta.08 we started getting scads of compile time warnings
- in Multinet builds: "blah" is implicitly declared as a function, where blah
- is socket_read/write/close, ntohs, htons, getpeername, accept, select, etc.
- I have no idea why -- these routines are declared in the header files below,
- and the includes haven't changed. The executable still seems to work OK.
- Messing with the order of the following includes is disastrous.
-*/
-#ifdef MULTINET_NO_PROTOTYPES
-#undef MULTINET_NO_PROTOTYPES
-#endif /* MULTINET_NO_PROTOTYPES */
-
-#ifdef __cplusplus
-#undef __cplusplus
-#endif /* __cplusplus */
-
-#include "multinet_root:[multinet.include]errno.h"
-#include "multinet_root:[multinet.include.sys]types.h"
-#include "multinet_root:[multinet.include.sys]socket.h"
-#include "multinet_root:[multinet.include]netdb.h"
-#include "multinet_root:[multinet.include.netinet]in.h"
-#include "multinet_root:[multinet.include.arpa]inet.h"
-#include "multinet_root:[multinet.include.sys]ioctl.h"
-
-#ifdef COMMENT
-/*
- No longer needed because now bzero/bcopy are macros defined as
- memset/memmove in all VMS builds.
-*/
-/*
- We should be able to pick these up from <strings.h> but it's
- not portable between VAXC and DECC. And even with DECC 5.x we have a
- difference between VAX and Alpha. We get warnings here on the VAX
- with DECC 5.6-003 but they are not fatal.
-*/
-#ifndef __DECC_VER
-#ifndef bzero
-_PROTOTYP( void bzero, (char *, int) );
-#endif /* bzero */
-#ifndef bcopy
-_PROTOTYP( void bcopy, (char *, char *, int) );
-#endif /* bcopy */
-#endif /* __DECC_VER */
-#endif /* COMMENT */
-
-#ifdef __DECC
-/*
- If compiling under DEC C the socket calls must not be prefixed with
- DECC$. This is done by using the compiler switch /Prefix=Ansi_C89.
- However, this causes some calls that should be prefixed to not be
- (which I think is a bug in the compiler - I've been told these calls
- are present in ANSI compilers). At any rate, such calls are fixed
- here by explicitly prefixing them.
-*/
-#ifdef COMMENT
-/*
- But this causes errors with VMS 6.2 / DEC C 5.3-006 / MultiNet 4.0A on
- a VAX (but not on an Alpha). So now what happens if we skip doing this?
-*/
-#define close decc$close
-#define alarm decc$alarm
-#endif /* COMMENT */
-#endif /* __DECC */
-
-#else /* Not MULTINET */
-
-#ifdef WINTCP /* WIN/TCP = PathWay for VMS */
-#ifdef OLD_TWG
-#include "twg$tcp:[netdist.include.sys]errno.h"
-#include "twg$tcp:[netdist.include.sys]types2.h" /* avoid some duplicates */
-#else
-#include "twg$tcp:[netdist.include]socket_aliases.h"
-#include <errno.h>
-#include "twg$tcp:[netdist.include.sys]types.h"
-#endif /* OLD_TWG */
-#include "twg$tcp:[netdist.include.sys]socket.h"
-#include "twg$tcp:[netdist.include]netdb.h"
-#include "twg$tcp:[netdist.include.sys]domain.h"
-#include "twg$tcp:[netdist.include.sys]protosw.h"
-#include "twg$tcp:[netdist.include.netinet]in.h"
-#include "twg$tcp:[netdist.include.arpa]inet.h"
-#include "twg$tcp:[netdist.include.sys]ioctl.h"
-
-#else /* Not WINTCP */
-
-#ifdef DEC_TCPIP
-#ifdef UCX50
-#ifndef IF_DOT_H
-#define IF_DOT_H
-#endif /* IF_DOT_H */
-#endif /* UCX50 */
-
-#ifdef IF_DOT_H
-#include <if.h> /* Needed to put up u_int typedef */
-#else
-#ifdef NEEDUINT
-typedef unsigned int u_int;
-#endif /* NEEDUINT */
-#endif /* IF_DOT_H */
-
-#include <in.h>
-#ifdef VMS
-#include <inet.h> /* (SMS 2007/02/15) */
-#endif /* VMS */
-#include <netdb.h>
-#include <socket.h>
-#include "ckvioc.h"
-#define socket_errno errno
-
-#ifdef COMMENT
-/*
- No longer needed because now bzero/bcopy are macros defined as
- memset/memmove in all VMS builds.
-*/
-/*
- Translation: In <strings.h>, which exists only for DECC >= 5.2, bzero()
- and bcopy() are declared only for OpenVMS >= 7.0. This still might need
- adjustment for DECC 5.0 and higher.
-*/
-#ifdef __DECC_VER
-#ifdef VMSV70
-/*
- Note: you can't use "#if (__VMS_VER>=70000000)" because that is not
- portable and kills non-VMS builds.
-*/
-#include <strings.h>
-#else
-#ifndef bzero
-#define bzero(s,n) memset(s,0,n)
-#endif
-#ifndef bcopy
-#define bcopy(h,a,l) memmove(a,h,l)
-#endif
-#endif /* VMSV70 */
-#else
-#ifndef bzero
-#define bzero(s,n) memset(s,0,n)
-#endif
-#ifndef bcopy
-#define bcopy(h,a,l) memmove(a,h,l)
-#endif
-#endif /* __DECC_VER */
-#endif /* COMMENT */
-
-#define socket_read read
-#define socket_write write
-#define socket_ioctl ioctl
-#define socket_close close
-
-#ifdef __DECC
-int ioctl (int d, int request, void *argp);
-#else
-int ioctl (int d, int request, char *argp);
-#endif /* DECC */
-/*
- UCX supports select(), but does not provide the needed symbol and
- structure definitions in any header file, so ...
-*/
-#include <types.h>
-#ifndef NBBY
-/*-
- * Copyright (c) 1982, 1986, 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)types.h 8.1 (Berkeley) 6/2/93
- */
-
-#define NBBY 8 /* number of bits in a byte */
-
-/*
- * Select uses bit masks of file descriptors in longs. These macros
- * manipulate such bit fields (the filesystem macros use chars).
- * FD_SETSIZE may be defined by the user, but the default here should
- * be enough for most uses.
- */
-#ifndef FD_SETSIZE
-#define FD_SETSIZE 256
-#endif
-
-typedef long fd_mask;
-#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
-
-#ifndef howmany
-#define howmany(x, y) (((x)+((y)-1))/(y))
-#endif
-
-typedef struct fd_set {
- fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
-} fd_set;
-
-#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
-#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
-#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
-#define FD_COPY(f, t) bcopy(f, t, sizeof(*(f)))
-#define FD_ZERO(p) bzero(p, sizeof(*(p)))
-#endif /* !NBBY */
-
-#else /* Not DEC_TCPIP */
-
-#ifdef CMU_TCPIP
-#include <types.h>
-#include <in.h>
-#include <netdb.h>
-#include <socket.h>
-#include <inet.h>
-#include <ioctl.h>
-#include "ckvioc.h"
-#define socket_errno errno
-
-/*
- * Routines supplied in LIBCMU.OLB
- */
-#define socket_ioctl ioctl
-#define socket_read cmu_read
-#define socket_write cmu_write
-#define socket_close cmu_close
-
-#endif /* CMU_TCPIP */
-#endif /* DEC_TCPIP */
-#endif /* WINTCP */
-#endif /* MULTINET */
-
-#else /* Not VMS */
-
-#ifdef OS2
-#include "ckonet.h"
-#ifndef NT
-#include <nerrno.h>
-#endif
-#endif /* OS2 */
-
-#ifdef STRATUS /* Stratus VOS using OS TCP/IP products S235, S236, S237 */
-#include <tcp_socket.h>
-/* This gets used some places when TCPSOCKET is defined. */
-/* OS TCP provides bzero(), but not bcopy()... go figure. */
-#define bcopy(s,d,z) memcpy(d,s,z)
-#endif /* STRATUS */
-
-#ifdef OSK
-#ifndef OSKXXC
-#include <inet/in.h>
-#include <inet/netdb.h>
-#include <inet/socket.h>
-#else
-#include <INET/in.h>
-#include <INET/netdb.h>
-#include <INET/socket.h>
-#endif /* OSKXXC */
-#ifndef bzero
-#define bzero(s,n) memset(s,0,n)
-#endif
-#ifndef bcopy
-#define bcopy(h,a,l) memcpy(a,h,l)
-#endif
-typedef char * caddr_t; /* core address type */
-#endif /* OSK */
-
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* TCPSOCKET */
-
-#ifndef NOINADDRX /* 301 - Needed for Solaris 10 and 11 */
-#ifdef SOLARIS
-#define NOINADDRX
-#ifdef INADDR_NONE
-#undef INADDR_NONE
-#endif /* INADDR_NONE */
-#endif /* SOLARIS */
-#endif /* NOINADDRX */
-
-#ifdef NOINADDRX
-#ifdef INADDRX
-#undef INADDRX
-#endif /* INADDRX */
-#endif /* NOINADDRX */
-
-#ifdef TCPSOCKET
-#ifndef NOHADDRLIST
-#ifndef HADDRLIST
-#ifdef SUNOS41
-#define HADDRLIST
-#endif /* SUNOS41 */
-#ifdef SOLARIS
-#define HADDRLIST
-#endif /* SOLARIS */
-#ifdef LINUX
-#define HADDRLIST
-#endif /* LINUX */
-#ifdef AIXRS
-#define HADDRLIST
-#endif /* AIXRS */
-#ifdef HPUX
-#define HADDRLIST
-#endif /* HPUX */
-#ifdef IRIX
-#define HADDRLIST
-#endif /* IRIX */
-#ifdef I386IX
-#define HADDRLIST
-#endif /* I386IX */
-#endif /* HADDRLIST */
-/* A system that defines h_addr as h_addr_list[0] should be HADDRLIST */
-#ifndef HADDRLIST
-#ifdef h_addr
-#define HADDRLIST
-#endif /* h_addr */
-#endif /* HADDRLIST */
-#endif /* NOHADDRLIST */
-#endif /* TCPSOCKET */
-
-#ifdef TNCODE /* If we're compiling telnet code... */
-#ifndef IKS_OPTION
-#ifndef STRATUS
-#define IKS_OPTION
-#endif /* STRATUS */
-#endif /* IKS_OPTION */
-#include "ckctel.h"
-#else
-extern int sstelnet;
-#ifdef IKSD
-#undef IKSD
-#endif /* IKSD */
-#ifndef NOIKSD
-#define NOIKSD
-#endif /* NOIKSD */
-#ifdef IKS_OPTION
-#undef IKS_OPTION
-#endif /* IKS_OPTION */
-#endif /* TNCODE */
-
-#ifndef NOTCPOPTS
-/*
- Automatically define NOTCPOPTS for configurations where they can't be
- used at runtime or cause too much trouble at compile time.
-*/
-#ifdef CMU_TCPIP /* CMU/Tek */
-#define NOTCPOPTS
-#endif /* CMU_TCPIP */
-#ifdef MULTINET /* Multinet on Alpha */
-#ifdef __alpha
-#define NOTCPOPTS
-#endif /* __alpha */
-#endif /* MULTINET */
-#endif /* NOTCPOPTS */
-
-#ifdef NOTCPOPTS
-#ifdef TCP_NODELAY
-#undef TCP_NODELAY
-#endif /* TCP_NODELAY */
-#ifdef SO_LINGER
-#undef SO_LINGER
-#endif /* SO_LINGER */
-#ifdef SO_KEEPALIVE
-#undef SO_KEEPALIVE
-#endif /* SO_KEEPALIVE */
-#ifdef SO_SNDBUF
-#undef SO_SNDBUF
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
-#undef SO_RCVBUF
-#endif /* SO_RCVBUF */
-#endif /* NOTCPOPTS */
-
-/* This function is declared even when TCPSOCKET is not available */
-_PROTOTYP( char * ckgetpeer, (VOID));
-
-#ifdef TCPSOCKET
-#ifdef SOL_SOCKET
-#ifdef TCP_NODELAY
-_PROTOTYP( int no_delay, (int, int) );
-#endif /* TCP_NODELAY */
-#ifdef SO_KEEPALIVE
-_PROTOTYP( int keepalive, (int, int) ) ;
-#endif /* SO_KEEPALIVE */
-#ifdef SO_LINGER
-_PROTOTYP( int ck_linger, (int, int, int) ) ;
-#endif /* SO_LINGER */
-#ifdef SO_SNDBUF
-_PROTOTYP( int sendbuf,(int, int) ) ;
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
-_PROTOTYP( int recvbuf, (int, int) ) ;
-#endif /* SO_RCVBUF */
-#ifdef SO_DONTROUTE
-_PROTOTYP(int dontroute, (int, int));
-#endif /* SO_DONTROUTE */
-#endif /* SOL_SOCKET */
-_PROTOTYP( int getlocalipaddr, (VOID));
-_PROTOTYP( int getlocalipaddrs, (char *,int,int));
-_PROTOTYP( char * ckgetfqhostname,(char *));
-_PROTOTYP( struct hostent * ck_copyhostent,(struct hostent *));
-_PROTOTYP( char * ckname2addr, (char *));
-_PROTOTYP( char * ckaddr2name, (char *));
-
-/* AIX */
-
-#ifdef AIXRS
-#ifndef TCP_NODELAY
-#define TCP_NODELAY 0x1
-#endif /* TCP_NODELAY */
-#ifndef TCP_MAXSEG
-#define TCP_MAXSEG 0x2
-#endif /* TCP_MAXSEG */
-#ifndef TCP_KEEPALIVE
-#define TCP_KEEPALIVE 0x8
-#endif /* TCP_KEEPALIVE */
-#endif /* AIXRS */
-#endif /* TCPSOCKET */
-
-#ifdef RLOGCODE
-#ifndef CK_TTGWSIZ
-SORRY_RLOGIN_REQUIRES_TTGWSIZ_see_ckcplm.doc
-#endif /* CK_TTGWSIZ */
-#endif /* RLOGCODE */
-
-#ifdef CK_NAWS
-#ifndef CK_TTGWSIZ
-SORRY_CK_NAWS_REQUIRES_TTGWSIZ_see_ckcplm.doc
-#endif /* CK_TTGWSIZ */
-#endif /* CK_NAWS */
-
-#ifndef PF_INET
-#ifdef AF_INET
-#define PF_INET AF_INET
-#endif /* AF_INET */
-#endif /* PF_INET */
-
-#ifndef IPPORT_ECHO
-#define IPPORT_ECHO 7
-#endif /* IPPORT_ECHO */
-
-#ifdef CK_KERBEROS
-#ifdef RLOGCODE
-_PROTOTYP(int ck_krb_rlogin,(CHAR *, int, CHAR *, CHAR *, CHAR *,
- struct sockaddr_in *,
- struct sockaddr_in *, int, int));
-#endif /* RLOGCODE */
-#endif /* CK_KERBEROS */
-
-_PROTOTYP( VOID ini_kerb, ( void ) ); /* Kerberos initialization routine */
-_PROTOTYP( int doauth, (int) ); /* AUTHENTICATE action routine */
-
-#ifdef CK_DNS_SRV
-_PROTOTYP(int locate_srv_dns,(char *host, char *service,
- char *protocol, struct sockaddr **addr_pp,
- int *naddrs));
-#endif /* CK_DNS_SRV */
-
-#ifndef NOHTTP
-_PROTOTYP(int http_open, (char *, char *, int, char *, int, char *));
-_PROTOTYP(int http_reopen, (VOID));
-_PROTOTYP(int http_close, (VOID));
-_PROTOTYP(int http_get, (char *,char **,char *,char *,char,char *,char *,
- int));
-_PROTOTYP(int http_head, (char *,char **,char *,char *,char,char *,char *,
- int));
-_PROTOTYP(int http_put, (char *,char **,char *,char *,char *,char,char *,
- char *, char *, int));
-_PROTOTYP(int http_delete, (char *,char **,char *,char *,char,char *));
-_PROTOTYP(int http_connect, (int, char *,char **,char *,char *,char,char *));
-_PROTOTYP(int http_post, (char *,char **,char *,char *,char *,char,char *,
- char *,char *, int));
-_PROTOTYP(int http_index, (char *,char **,char *,char *,char,char *,char *,
- int));
-_PROTOTYP(int http_inc, (int));
-_PROTOTYP(int http_isconnected, (void));
-
-extern char * tcp_http_proxy; /* Name[:port] of http proxy server */
-extern int tcp_http_proxy_errno; /* Return value from server */
-extern char * tcp_http_proxy_user; /* Name of user for authentication */
-extern char * tcp_http_proxy_pwd; /* Password of user */
-#endif /* NOHTTP */
-
-#ifdef TCPSOCKET
-
-/* Type needed as 5th argument (length) to get/setsockopt() */
-
-#ifdef TRU64
-/* They say it themselves - this does not conform to standards */
-#define socklen_t int
-#else
-#ifdef HPUX
-#define socklen_t int
-#endif /* HPUX */
-#endif /* TRU64 */
-
-#ifndef SOCKOPT_T
-#ifdef CK_64BIT
-#define SOCKOPT_T socklen_t
-#endif /* CK_64BIT */
-#endif /* SOCKOPT_T */
-
-#ifndef SOCKOPT_T
-#define SOCKOPT_T int
-#ifdef MACOSX10
-#undef SOCKOPT_T
-#define SOCKOPT_T unsigned int
-#else
-#ifdef AIX42
-#undef SOCKOPT_T
-#define SOCKOPT_T unsigned long
-#else
-#ifdef PTX
-#undef SOCKOPT_T
-#define SOCKOPT_T size_t
-#else
-#ifdef NT
-#undef SOCKOPT_T
-#define SOCKOPT_T int
-#else /* NT */
-#ifdef UNIXWARE
-#undef SOCKOPT_T
-#define SOCKOPT_T size_t
-#else /* UNIXWARE */
-#ifdef VMS
-#ifdef DEC_TCPIP
-#ifdef __DECC_VER
-#undef SOCKOPT_T
-#define SOCKOPT_T size_t
-#endif /* __DECC_VER */
-#endif /* DEC_TCPIP */
-#endif /* VMS */
-#endif /* UNIXWARE */
-#endif /* NT */
-#endif /* PTX */
-#endif /* AIX42 */
-#endif /* MACOSX10 */
-#endif /* SOCKOPT_T */
-
-/* Ditto for getsockname() */
-
-#ifndef GSOCKNAME_T
-#ifdef CK_64BIT
-#define GSOCKNAME_T socklen_t
-#endif /* CK_64BIT */
-#endif /* GSOCKNAME_T */
-
-#ifndef GSOCKNAME_T
-#define GSOCKNAME_T int
-#ifdef MACOSX10
-#undef GSOCKNAME_T
-#define GSOCKNAME_T unsigned int
-#else
-#ifdef PTX
-#undef GSOCKNAME_T
-#define GSOCKNAME_T size_t
-#else
-#ifdef AIX42 /* size_t in 4.2++, int in 4.1-- */
-#undef GSOCKNAME_T
-#define GSOCKNAME_T size_t
-#else
-#ifdef UNIXWARE
-#undef GSOCKNAME_T
-#define GSOCKNAME_T size_t
-#else
-#ifdef VMS
-#ifdef DEC_TCPIP
-#ifdef __DECC_VER
-#undef GSOCKNAME_T
-#define GSOCKNAME_T size_t
-#endif /* __DECC_VER */
-#endif /* DEC_TCPIP */
-#endif /* VMS */
-#endif /* UNIXWARE */
-#endif /* AIX41 */
-#endif /* PTX */
-#endif /* MACOSX10 */
-#endif /* GSOCKNAME_T */
-
-#endif /* TCPSOCKET */
-
-#ifdef MACOSX10
-#ifdef bcopy
-#undef bcopy
-#endif
-#ifdef bzero
-#undef bzero
-#endif
-#endif /* MACOSX10 */
-
-#endif /* CKCNET_H */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcplm.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckcplm.txt
deleted file mode 100644
index e00edde..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcplm.txt
+++ /dev/null
@@ -1,3113 +0,0 @@
-
- [1]The Columbia Crown The Kermit Project | Columbia University
- 612 West 115th Street, New York NY 10025 USA o [2]kermit@columbia.edu
- ...since 1981
- [3]Home [4]Kermit 95 [5]C-Kermit [6]Scripts [7]Current [8]New [9]FAQ
- [10]Support
-
-C-Kermit Program Logic Manual
-
- Frank da Cruz
- [11]The Kermit Project
-
- As of: C-Kermit 9.0.300, 30 June 2011
- Last update: Fri Jul 1 15:47:34 2011
-
- IF YOU ARE READING A PLAIN-TEXT version of this document, note that
- this file is a plain-text dump of a Web page. You can visit the
- original (and possibly more up-to-date) Web page here:
-
- [12]http://www.columbia.edu/kermit/ckcplm.html
-
-CONTENTS
-
- 1. [13]INTRODUCTION
- 2. [14]FILES
- 3. [15]SOURCE CODE PORTABILITY AND STYLE
- 4. [16]MODULES
- 4.A. [17]Group A: Library Routines
- 4.B. [18]Group B: Kermit File Transfer
- 4.C. [19]Group C: Character-Set Conversion
- 4.D. [20]Group D: User Interface
- 4.E. [21]Group E: Platform-Dependent I/O
- 4.F. [22]Group F: Network Support
- 4.G. [23]Group G: Formatted Screen Support
- 4.H. [24]Group H: Pseudoterminal Support
- 4.I. [25]Group I: Security
- I. [26]APPENDIX I: FILE PERMISSIONS
-
-1. INTRODUCTION
-
- The Kermit Protocol is specified in the book [27]Kermit, A File
- Transfer Protocol by Frank da Cruz, Digital Press / Butterworth
- Heinemann, Newton, MA, USA (1987), 379 pages, ISBN 0-932376-88-6. It is
- assumed the reader is familiar with the Kermit protocol specification.
-
- This file describes the relationship among the modules and functions of
- C-Kermit 5A and later, and other programming considerations. C-Kermit
- is designed to be portable to any kind of computer that has a C
- compiler. The source code is broken into many files that are grouped
- according to their function, as shown in the [28]Contents.
-
- C-Kermit has seen constant development since 1985. Throughout its
- history, there has been a neverending tug-of-war among:
-
- a. Functionality: adding new features, fixing bugs, improving
- performance.
- b. Adding support for new platforms or communication methods.
- c. "Buzzword 1.0 compliance".
-
- The latter category is the most frustrating, since it generally
- involves massive changes just to keep the software doing what it did
- before in some new setting: e.g. the K&R-to-ANSIC conversion (which had
- to be done, of course, without breaking K&R); Y2K (not a big deal in
- our case); the many and varied UNIX and other API "standards" with
- which to "comply".
-
- Upon first glance at the source code, you will probably be appalled.
- Many will be tempted to clean it up and modernize it. But as soon as
- you do, you are sure to break something. Remember that above all else,
- the C-Kermit code is portable to every Unix platform that ever existed,
- going back Unix V7 (1979)*, and to several other completely different
- and unrelated operating-system families such as DEC/HP VMS, DG AOS/VS,
- and Stratus VOS, as well as to some Unix offshoots like OS-9 and Plan 9
- (from Outer Space). Every release of Kermit has been checked on every
- platform available -- the older the better! -- to make sure it still
- builds and runs. Even today (2011), there are modern Unix systems that
- have non-ANSI C compilers, foremost among them HP-UX (where an ANSI
- optimizing C compiler is available, but only as an expensive add-on).
- In a way, portability is the most important feature of C-Kermit and
- every effort should be made to preserve it through future releases.
-
- Voluminous edit histories are available going back to May 1985. The
- first versions of C-Kermit were done on our [29]DEC VAX-11/750 with
- Ultrix 1.0 and 2.0 (as well as departmental 750s with 4.2BSD**), DEC
- Pro-380 workstations (desktop PDP-11s) running 2.9BSD, which was
- [30]ported to the 380 by us. Later (1988 or so) on a big VAX 8650 with
- Ultrix, which became an 8700 (these no doubt weighed several tons), and
- finally a succession of non-DEC equipment: an Encore Multimax, 25 years
- worth of Suns, and now Linux on [31]HP Blades. We also had our own VMS
- development systems for some years. All this plus a generous assortment
- of departmental and offsite guest accounts on a multitude of platforms.
- Anyway, the edit histories:
-
- [32]ckc04e.txt C-Kermit 4.2(030) May 1985 to 4E(072) Jan 1989.
- [33]ckc04f.txt C-Kermit 4F(077) Arp 1989 to 4F(095) Aug 1989.
- [34]ckc168.txt Updates to C-Kermit 5A(168) for VMS Nov 1991
- [35]ckc178.txt C-Kermit 5A(100) Jul 1989 to 5A(178) Jan 1992
- [36]ckc188.txt C-Kermit 5A(188) development, 1992
- [37]ckc189.txt C-Kermit 5A(189) development, 1993
- [38]ckc192.txt C-Kermit 6.0(192) development, 1998
- [39]ckc197.txt C-Kermit 7.0(197) development, 2000
- [40]ckc200.txt C-Kermit 8.0.200 development, 2001
- [41]ckc211.txt C-Kermit 8.0.201 through 8.0.209 2001-2004
- [42]ckc300.txt C-Kermit 9.0.300 June 2011
-
- _________________________________
- * C-Kermit 6.0 was the last one to be built on V7, as I recall. The
- code should still be good for V7 but it probably has outgrown the
- 16-bit address space. In any case there is still a V7 makefile target
- and a V7 path through the forest of #ifdefs in the code if anybody is
- running V7 on an emulator and would like to try building C-Kermit.
- There is no support for V6 but that is only because no V6 system was
- ever found for development. Notice that some other 16-bit Unixes are
- supported in the code, including 2.9BSD and Tandy Xenix 3.0, but have
- not been tried since C-Kermit 6.0
-
- ** C-Kermit 9.0.300 was built successfully on 4.2BSD about 25 years
- later, in June 2011.
-
- [ [43]Contents ] [ [44]C-Kermit ] [ [45]Kermit Home ]
-
-2. FILES
-
- C-Kermit source files begin with the two letters "ck", for example
- ckutio.c. Filenames are kept short (6.3) for maximum portability and
- (obviously I hope) do not contain spaces or more than one period. The
- third character in the name denotes something about the function group
- and the expected level of portability:
-
- a General descriptive material and documentation (text)
- b BOO file encoders and decoders (obsolete)
- c All platforms with C compilers (*)
- d Data General AOS/VS
- e Reserved for "ckermit" files, like ckermit.ini, ckermit2.txt
- f (reserved)
- g (reserved)
- h (reserved)
- i Commodore Amiga (Intuition)
- j (unused)
- k (unused)
- l Stratus VOS
- m Macintosh with Mac OS 1-9
- n (unused)
- o OS/2 and Microsoft Windows 9x/ME/NT/2000/XP/Vista/etc
- p Plan 9 from Bell Labs
- q (reserved)
- r DEC PDP-11 with RSTS/E (never used, open for reassignment)
- s Atari ST GEMDOS (last supported in version 5A(189))
- t DEC PDP-11 with RT-11 (never used, open for reassignment)
- u Unix-based operating systems (*)
- v VMS and OpenVMS
- w Wart (Lex-like preprocessor, platform independent)
- x (reserved)
- y (reserved)
- z (reserved)
- 0-3 (reserved)
- 4 IBM AS/400
- 5-8 (reserved)
- 9 Microware OS-9
- _ (underscore) Encryption modules
-
- (*) In fact there is little distinction between the ckc*.* and cku*.*
- categories. It would make more sense for all cku*.* modules to be
- ckc*.* ones, except ckufio.c, ckutio.c, ckucon.c, ckucns.c, and
- ckupty.c, which truly are specific to Unix. The rest (ckuus*.c,
- ckucmd.c, etc) are quite portable.
-
- One hint before proceeding: functions are scattered all over the ckc*.c
- and cku*.c modules, where function size has begun to take precedence
- over the desirability of grouping related functions together, the aim
- being to keep any particular module from growing disproportionately
- large. The easiest way (in UNIX) to find out in what source file a
- given function is defined is like this (where the desired function is
- foo()...):
-
- grep ^foo\( ck*.c
-
- This works because the coding convention has been to make function
- names always start on the left margin with their contents indented, for
- example:
-
-static char *
-foo(x,y) int x, y; {
- ...
-}
-
- Also note the style for bracket placement. This allows bracket-matching
- text editors (such as EMACS) to help you make sure you know which
- opening bracket a closing bracket matches, particularly when the
- opening bracket is above the visible screen, and it also makes it easy
- to find the end of a function (search for '}' on the left margin).
-
- Of course EMACS tags work nicely with this format too:
-
- $ cd kermit-source-directory
- $ etags ck[cu]*.c
- $ emacs
- Esc-X Visit-Tags-Table<CR><CR>
-
- (but remember that the source file for ckcpro.c is [46]ckcpro.w!)
-
- Also:
-
- * Tabs should be set every 8 spaces, as on a VT100.
- * All lines must no more than 79 characters wide after tab expansion.
- * Note the distinction between physical tabs (ASCII 9) and the
- indentation conventions, which are: 4 for block contents, 2 for
- most other stuff (obviously this is not a portability issue, just
- style).
-
- [ [47]Contents ] [ [48]C-Kermit ] [ [49]Kermit Home ]
-
-3. SOURCE CODE PORTABILITY AND STYLE
-
- C-Kermit was designed in 1985 as a platform-independent replacement for
- the earlier Unix Kermit. C-Kermit's design was expected to promote
- portability, and judging from the number of platforms to which it has
- been adapted since then, the model is effective, if not ideal
- (obviously if we had it all to do over, we'd change a few things). To
- answer the oft-repeated question: "Why are there so many #ifdefs?",
- it's because:
-
- * Many of them are related to feature selection and program size, and
- so need to be there anyway.
- * Those that treat compiler, library, platform, header-file, and
- similar differences have built up over time as hundreds of people
- all over the world adapted C-Kermit to their particular
- environments and sent back their changes. There might be more
- politically-correct ways to achieve portability, but this one is
- natural and proven. The basic idea is to introduce changes that can
- be selected by defining a symbol, which, if not defined, leaves the
- program exactly as it was before the changes.
- * Although it might be possible to "clean up" the "#ifdef mess",
- nobody has access to all the hundreds of platforms served by the
- #ifdefs to check the results.
-
- And to answer the second-most-oft-repeated question: "Why don't you
- just use GNU autoconfig / automake / autowhatever instead of
- hard-coding all those #ifdefs?" Answers:
-
- * The GNU tools are not available on all the platforms where C-Kermit
- must be built and I wouldn't necessarily trust them if they were.
- * Each platform is a moving target, so the tools themselves would
- need to updated before Kermit could be updated.
- * It would only add another layer of complexity to an already complex
- process.
- * Conversion at this point would not be practical unless there was a
- way to test the results on all the hundreds of platforms where
- C-Kermit is supposed to build.
-
- When writing code for the system-independent C-Kermit modules, please
- stick to the following coding conventions to ensure portability to the
- widest possible variety of C preprocessors, compilers, and linkers, as
- well as certain network and/or email transports. The same holds true
- for many of the "system dependent" modules too; particularly the Unix
- ones, since they must be buildable by a wide variety of compilers and
- linkers, new and old.
-
- This list does not purport to be comprehensive, and although some items
- on it might seem far-fetched, they would not be listed unless I had
- encountered them somewhere, some time. I wish I had kept better records
- so I could cite specific platforms and compilers.
-
- * Try to keep variable and function names unique within 6 characters,
- especially if they are used across modules, since 6 is the maximum
- for some old linkers (actually, this goes back to TOPS-10 and -20
- and other old DEC OS's where C-Kermit never ran anyway; a more
- realistic maximum is probably somewhere between 8 and 16). We know
- for certain that VAX C has a 31-character max because it complains
- -- others might not complain, but just silently truncate, thus
- folding two or more routines/variables into one.
- * Keep preprocessor symbols unique within 8 characters; that's the
- max for some preprocessors (sorry, I can't give a specific example,
- but in 1988 or thereabouts, I had to change character-set symbols
- like TC_LATIN1 and TC_LATIN2 to TC_1LATIN and TC_2LATIN because the
- digits were being truncated and ignored on a platform where I
- actually had to build C-Kermit 5A; unfortunately I didn't note
- which platform -- maybe some early Ultrix version?)
- * Don't create preprocessor symbols, or variable or function names,
- that start with underscore (_). These are usually reserved for
- internal use by the compiler and header files.
- * Don't put #include directives inside functions or { blocks }.
- * Don't use the #if or #elif preprocessor constructions, only use
- #ifdef, #ifndef, #define, #undef, and #endif.
- * Put tokens after #endif in comment brackets, e.g. #endif /* FOO */.
- * Don't indent preprocessor statements - # must always be first char
- on line.
- * Don't put whitespace after # in preprocessor statements.
- * Don't use #pragma, even within #ifdefs -- it makes some
- preprocessors give up.
- * Same goes for #module, #if, etc - #ifdefs do NOT protect them.
- * Don't use logical operators in preprocessor constructions.
- * Avoid #ifdefs inside argument list to function calls (I can't
- remember why this one is here, but probably needn't be; we do this
- all the time).
- * Always cast strlen() in expressions to int:
- if ((int)strlen(foo) < x)...
- * Avoid typedefs; they might be portable but they are very confusing
- and there's no way to test for their presence or absence at compile
- time. Use preprocessor symbols instead if possible; at least you
- can test their definitions.
- * Unsigned long is not portable; use a preprocessor symbol (Kermit
- uses ULONG for this).
- * Long long is not portable. If you really need it, be creative.
- * Similarly 1234LL is not portable, nor almost any other constant
- modifier other than L.
- * Unsigned char is not portable, use CHAR (a preprocessor symbol
- defined in the Kermit header files) and always take precautions
- against character signage (more about this [50]below).
- * Don't use initializers with automatic arrays or structs: it's not
- portable.
- * Don't use big automatic arrays or structs in functions that might
- be called recursively; some platforms have fixed-size stacks (e.g.
- Windows 9x: 256K) and recursive functions crash with stack
- overflow. Even when there is not a compiler limitation, this causes
- memory to be consumed without bound, and can end up filling swap
- space.
- * Don't assume that struct assignment performs a copy, or that it
- even exists.
- * Don't use sizeof to get the size of an array; someone might come
- along later and and change it from static to malloc'd. Always use a
- symbol to refer to the array's size.
- * Don't put prototypes for static functions into header files that
- are used by modules that don't contain that function; the link step
- can fail with unresolved references (e.g. on AOS/VS).
- * Avoid the construction *++p (the order of evaluation varies; it
- shouldn't but at least one compiler had a bug that made me include
- this item).
- * Don't use triple assignments, like a = b = c = 0; (or quadruple,
- etc). Some compilers generate bad code for these, or crash, etc
- (some version of DEC C as I recall).
- * Some compilers don't allow structure members to have the same names
- as other identifiers. Try to give structure members unique names.
- * Don't assume anything about order of evaluation in boolean
- expressions, or that they will stop early if a required condition
- is not true, e.g.:
- if (i > 0 && p[i-1] == blah)
-
- can still dump core if i == 0 (hopefully this is not true of any
- modern compiler, but I would not have said this if it did not
- actually happen somewhere).
- * Don't have a switch() statement with no cases (e.g. because of
- #ifdefs); this is a fatal error in some compilers.
- * Don't put lots of code in a switch case; move it out to a separate
- function; some compilers run out of memory when presented with a
- huge switch() statement -- it's not the number of cases that
- matters; it's the overall amount of code.
- * Some compilers might also limit the number of switch() cases, e.g.
- to 254.
- * Don't put anything between "switch() {" and "case:" -- switch
- blocks are not like other blocks.
- * Don't jump into or out of switches.
- * Don't make character-string constants longer than about 250 bytes.
- Longer strings should be broken up into arrays of strings.
- * Don't write into character-string constants (obviously). Even when
- you know you are not writing past the end; the compiler or linker
- might have put them into read-only and/or shared memory, and/or
- coalesced multiple equal constants so if you change one you change
- them all.
- * Don't depend on '\r' being carriage return.
- * Don't depend on '\n' being linefeed or for that matter any SINGLE
- character.
- * Don't depend on '\r' and '\n' being different (e.g. as separate
- switch() cases).
- * In other words, don't use \n or \r to stand for specific
- characters; use \012 and \015 instead.
- * Don't code for "buzzword 1.0 compliance", unless "buzzword" is K&R
- and "1.0" is the first edition.
- * Don't use or depend on anything_t (size_t, pid_t, etc), except
- time_t, without #ifdef protection (time_t is the only one I've
- found that is accepted everywhere). This is a tough one because the
- same function might require (say) a size_t arg on one platform,
- whereas size_t is unheard of on another; or worse, it might require
- a totally different data type, like int or long or some other
- typedef'd thing. It has often proved necessary to define a symbol
- to stand for the type of a particular argument to a particular
- library or system function to get around this problem.
- * Don't use or depend on internationalization ("i18n") features,
- wchar_t, locales, etc, in portable code; they are not portable.
- Anyway, locales are not the right model for Kermit's
- multi-character-set support. Kermit does all character-set
- conversion itself and does not use any external libraries or
- functions.
- * In particular, don't use any library functions that deal with wide
- characters or Unicode in any form. These are not only nonportable,
- but a constantly shifting target (e.g. the ones in glibc).
- * Don't make any assumption about signal handler type. It can be
- void, int, long, or anything else. Always declare signal handlers
- as SIGTYP (see definition in ckcdeb.h and augment it if necessary)
- and always use SIGRETURN at exit points from signal handlers.
- * Signals should always be re-armed to be used again (this barely
- scratches the surface -- the differences between BSD/V7 and System
- V and POSIX signal handling are numerous, and some platforms do not
- even support signals, alarms, or longjmps correctly or at all --
- avoid all of this if you can).
- * On the other hand, don't assume that signals are disarmed after
- being raised. In some platforms you have to re-arm them, in others
- they stay armed.
- * Don't call malloc() and friends from a signal handler; don't do
- anything but setting integer global variables in a signal handler.
- * malloc() does not initialize allocated memory -- it never said it
- did. Don't expect it to be all 0's.
- * Did You Know: malloc() can succeed and the program can still dump
- core later when it attempts to use the malloc'd memory? (This
- happens when allocation is deferred until use and swap space is
- full.)
- * memset(), memmove(), and memcpy() are not portable, don't use them
- without protecting them in ifdefs (we have USE_MEMCPY for this).
- bzero()/bcopy() too, except we're guaranteed to have
- bzero()/bcopy() when using the sockets library (not really). See
- examples in the source.
- * Don't assume that strncpy() stops on the first null byte -- most
- versions always copy the number of bytes given in arg 3, padding
- out with 0's and overwriting whatever was there before. Use
- C-Kermit ckstrncpy() if you want predictable non-padding behavior,
- guaranteed NUL-termination, and a useful return code.
- * DID YOU KNOW.. that some versions of inet_blah() routines return IP
- addresses in network byte order, while others return them local
- machine byte order? So passing them to ntohs() or whatever is not
- always the right thing to do.
- * Don't use ANSI-format function declarations without #ifdef
- CK_ANSIC, and always provide an #else for the non-ANSI case.
- * Use the Kermit _PROTOTYP() macro for declaring function prototypes;
- it works in both the ANSI and non-ANSI cases.
- * Don't depend on any other ANSI preprocessor features like "pasting"
- -- they are often missing or nonoperational.
- * Don't assume any C++ syntax or semantics.
- * Don't use // as a comment introducer. C is not C++.
- * Don't declare a string as "char foo[]" in one module and "extern
- char * foo" in another, or vice-versa: this causes core dumps.
- * With compiler makers falling all over themselves trying to outdo
- each other in ANSI strictness, it has become increasingly necessary
- to cast EVERYTHING. Especially char vs unsigned char. We need to
- use unsigned chars if we want to deal with 8-bit character sets,
- but most character- and string-oriented APIs want (signed) char
- arguments, so explicit casts are necessary. It would be nice if
- every compiler had a -funsigned-char option (as gcc does), but they
- don't.
- * a[x], where x is an unsigned char, can produce a wild memory
- reference if x, when promoted to an int, becomes negative. Cast it
- to (unsigned), even though it ALREADY IS unsigned.
- * Be careful how you declare functions that have char or long
- arguments; for ANSI compilers you MUST use ANSI declarations to
- avoid promotion problems, but you can't use ANSI declarations with
- non-ANSI compilers. Thus declarations of such functions must be
- hideously entwined in #ifdefs. Example:
- int /* Put character in server command buffer */
- #ifdef CK_ANSIC
- putsrv(char c)
- #else
- putsrv(c) char c;
- #endif /* CK_ANSIC */
- /* putsrv */ {
- *srvptr++ = c;
- *srvptr = '\0'; /* Make sure buffer is null-terminated */
- return(0);
- }
-
- * Be careful how you return characters from functions that return int
- values -- "getc-like functions" -- in the ANSI world. Unless you
- explicitly cast the return value to (unsigned), it is likely to be
- "promoted" to an int and have its sign extended.
- * At least one compiler (the one on DEC OSF/1 1.3) treats "/*" and
- "*/" within string constants as comment begin and end. No amount of
- #ifdefs will get around this one. You simply can't put these
- sequences in a string constant, e.g. "/usr/local/doc/*.*".
- * Avoid putting multiple macro references on a single line, e.g.:
- putchar(BS); putchar(SP); putchar(BS)
-
- This overflows the CPP output buffer of more than a few C preprocessors
- (this happened, for example, with SunOS 4.1 cc, which evidently has a
- 1K macro expansion buffer).
-
- C-Kermit needs constant adjustment to new OS and compiler releases.
- Every new OS release shuffles header files or their contents, or
- prototypes, or data types, or levels of ANSI strictness, etc. Every
- time you make an adjustment to remove a new compilation error, BE VERY
- CAREFUL to #ifdef it on a symbol unique to the new configuration so
- that the previous configuration (and all other configurations on all
- other platforms) remain as before.
-
- Assume nothing. Don't assume header files are where they are supposed
- to be, that they contain what you think they contain, that they define
- specific symbols to have certain values -- or define them at all! Don't
- assume system header files protect themselves against multiple
- inclusion. Don't assume that particular system or library calls are
- available, or that the arguments are what you think they are -- order,
- data type, passed by reference vs value, etc. Be conservative when
- attempting to write portable code. Avoid all advanced features.
-
- If you see something that does not make sense, don't assume it's a
- mistake -- it might be there for a reason, and changing it or removing
- is likely to cause compilation, linking, or runtime failures sometime,
- somewhere. Some huge percentage of the code, especially in the
- platform-dependent modules, is workarounds for compiler, linker, or API
- bugs.
-
- But finally... feel free to violate any or all of these rules in
- platform-specific modules for environments in which the rules are
- certain not to apply. For example, in VMS-specific code, it is OK to
- use #if, because VAX C, DEC C, and VMS GCC all support it.
-
- [ [51]Contents ] [ [52]C-Kermit ] [ [53]Kermit Home ]
-
-3.1. Memory Leaks
-
- The C language and standard C library are notoriously inadequate and
- unsafe. Strings are arrays of characters, usually referenced through
- pointers. There is no native string datatype. Buffers are fixed size,
- and C provides no runtime bounds checking, thus allowing overwriting of
- other data or even program code. With the popularization of the
- Internet, the "buffer exploit" has become a preferred method for
- hackers to hijack privileged programs; long data strings are fed to a
- program in hopes that it uses unsafe C library calls such as strcpy()
- or sprintf() to copy strings into automatic arrays, thus overwriting
- the call stack, and therefore the routine's return address. When such a
- hole is discovered, a "string" can be constructed that contains machine
- code to hijack the program's privileges and penetrate the system.
-
- This problem is partially addressed by the strn...() routines, which
- should always be used in preference to their str...() equivalents
- (except when the copy operation has already been prechecked, or there
- is a good reason for not using them, e.g. the sometimes undesirable
- side effect of strncpy() zeroing the remainder of the buffer). The most
- gaping whole, however, is sprintf(), which performs no length checking
- on its destination buffer, and is not easy to replace. Although
- snprintf() routines are starting to appear, they are not yet
- widespread, and certainly not universal, nor are they especially
- portable, or even full-featured.
-
- For these reasons, we have started to build up our own little library
- of C Library replacements, ckclib.[ch]. These are safe and highly
- portable primitives for memory management and string manipulation, such
- as:
-
- ckstrncpy()
- Like strncpy but returns a useful value, doesn't zero buffer.
-
- ckitoa()
- Opposite of atoi()
-
- ckltoa()
- Opposite of atol()
-
- ckctoa()
- Returns character as string
-
- ckmakmsg()
- Used with ck?to?() as a safe sprintf() replacement for up to 4
- items
-
- ckmakxmsg()
- Like ckmakmsg() but accepts up to 12 items
-
- More about library functions in [54]Section 4.A.
-
- [ [55]Contents ] [ [56]C-Kermit ] [ [57]Kermit Home ]
-
-3.2. The "char" vs "unsigned char" Dilemma
-
- This is one of the most aggravating and vexing characteristics of the C
- language. By design, chars (and char *'s) are SIGNED. But in the modern
- era, however, we need to process characters that can have (or include)
- 8-bit values, as in the ISO Latin-1, IBM CP 850, or UTF-8 character
- sets, so this data must be treated as unsigned. But some C compilers
- (such as those based on the Bell UNIX V7 compiler) do not support
- "unsigned char" as a data type. Therefore we have the macro or typedef
- CHAR, which we use when we need chars to be unsigned, but which,
- unfortunately, resolves itself to "char" on those compilers that don't
- support "unsigned char". AND SO... We have to do a lot of fiddling at
- runtime to avoid sign extension and so forth.
-
- Some modern compilers (e.g. IBM, DEC, Microsoft) have options that say
- "make all chars be unsigned" (e.g. GCC "-funsigned-char") and we use
- them when they are available. Other compilers don't have this option,
- and at the same time, are becoming increasingly strict about type
- mismatches, and spew out torrents of warnings when we use a CHAR where
- a char is expected, or vice versa. We fix these one by one using casts,
- and the code becomes increasingly ugly. But there remains a serious
- problem, namely that certain library and kernel functions have
- arguments that are declared as signed chars (or pointers to them),
- whereas our character data is unsigned. Fine, we can can use casts here
- too -- but who knows what happens inside these routines.
-
- [ [58]Contents ] [ [59]C-Kermit ] [ [60]Kermit Home ]
-
-4. MODULES
-
- When C-Kermit is on the far end of a connection, it is said to be in
- remote mode. When C-Kermit has made a connection to another computer,
- it is in local mode. (If C-Kermit is "in the middle" of a multihop
- connection, it is still in local mode.)
-
- On another axis, C-Kermit can be in any of several major states:
-
- Command State
- Reading and writing from the job's controlling terminal or
- "console". In this mode, all i/o is handled by the Group E
- conxxx() (console i/o) routines.
-
- Protocol State
- Reading and writing from the communications device. In this
- mode, all i/o is handled by the Group E ttxxx() (terminal i/o)
- routines.
-
- Terminal State
- Reading from the keyboard with conxxx() routines and writing to
- the communications device with ttxxx() routines AND vice-versa.
-
- When in local mode, the console and communications device are distinct.
- During file transfer, Kermit may put up a file-transfer display on the
- console and sample the console for interruption signals.
-
- When in remote mode, the console and communications device are the
- same, and therefore there can be no file-transfer display on the
- console or interruptions from it (except for "in-band" interruptions
- such as ^C^C^C).
-
- [ [61]Contents ] [ [62]C-Kermit ] [ [63]Kermit Home ]
-
-4.A. Group A: Library Functions
-
- Library functions, strictly portable, can be used by all modules on all
- platforms: [64]ckclib.h, [65]ckclib.c.
-
- (To be filled in... For now, see [66]Section 3.1 and the comments in
- ckclib.c.)
-
- [ [67]Contents ] [ [68]C-Kermit ] [ [69]Kermit Home ]
-
-4.B. Group B: Kermit File Transfer
-
- The Kermit protocol kernel. These files, whose names start with "ckc
- are supposed to be totally portable C, and are expected to compile
- correctly on any platform with any C compiler. "Portable" does not mean
- the same as as "ANSI" -- these modules must compile on 10- and 20-year
- old computers, with C preprocessors, compilers, and/or linkers that
- have all sorts of restrictions. The Group B modules do not include any
- header files other than those that come with Kermit itself. They do not
- contain any library calls except from the standard C library (e.g.
- printf()). They most certainly do not contain any system calls. Files:
-
- [70]ckcsym.h
- For use by C compilers that don't allow -D on the command line.
-
- [71]ckcasc.h
- ASCII character symbol definitions.
-
- [72]ckcsig.h
- System-independent signal-handling definitions and prototypes.
-
- [73]ckcdeb.h
- Originally, debugging definitions. Now this file also contains
- all definitions and prototypes that are shared by all modules in
- all groups.
-
- [74]ckcker.h
- Kermit protocol symbol definitions.
-
- [75]ckcxla.h
- Character-set-related symbol definitions (see next section).
-
- [76]ckcmai.c
- The main program. This module contains the declarations of all
- the protocol-related global variables that are shared among the
- other modules.
-
- [77]ckcpro.w
- The protocol module itself, written in "wart", a lex-like
- preprocessor that is distributed with Kermit under the name
- CKWART.C.
-
- [78]ckcfns.c, [79]ckcfn2.c, [80]ckcfn3.c
- The protocol support functions used by the protocol module.
-
- [81]Group B modules may call upon functions from [82]Group E, but not
- from [83]Group D modules (with the single exception that the main
- program invokes the user interface, which is in Group D). (This last
- assertion is really only a conjecture.)
-
- [ [84]Contents ] [ [85]C-Kermit ] [ [86]Kermit Home ]
-
-4.C. Group C: Character-Set Conversion
-
- Character set translation tables and functions. Used by the [87]Group
- B, protocol modules, but may be specific to different computers. (So
- far, all character character sets supported by C-Kermit are supported
- in [88]ckuxla.c and [89]ckuxla.h, including Macintosh and IBM character
- sets). These modules should be completely portable, and not rely on any
- kind of system or library services.
-
- [90]ckcxla.h
- Character-set definitions usable by all versions of C-Kermit.
-
- ck?xla.h
- Character-set definitions for computer "?", e.g. [91]ckuxla.h
- for UNIX, [92]ckmxla.h for Macintosh.
-
- [93]ck?xla
- Character-set translation tables and functions for computer "?",
- For example, CKUXLA.C for UNIX, CKMXLA.C for Macintosh. So far,
- these are the only two such modules. The UNIX module is used for
- all versions of C-Kermit except the Macintosh version.
-
- [94]ckcuni.h
- Unicode definitions
-
- [95]ckcuni.c
- Unicode module
-
- Here's how to add a new file character set in the original (non-Unicode
- modules). Assuming it is based on the Roman (Latin) alphabet. Let's
- call it "Barbarian". First, in ck?xla.h, add a definition for FC_BARBA
- (8 chars maximum length) and increase MAXFCSETS by 1. Then, in
- ck?xla.c:
-
- * Add a barbarian entry into the fcsinfo array.
- * Add a "barbarian" entry to file character set keyword table,
- fcstab.
- * Add a "barbarian" entry to terminal character set keyword table,
- ttcstab.
- * Add a translation table from Latin-1 to barbarian: yl1ba[].
- * Add a translation table from barbarian to Latin-1: ybal1[].
- * Add a translation function from Barbarian to ASCII: xbaas().
- * Add a translation function from Barbarian to Latin-1: xbal1().
- * Add a translation function from Latin-1 to Barbarian: xl1ba().
- * etc etc for each transfer character set...
- * Add translation function pointers to the xls and xlr tables.
-
- Other translations involving Barbarian (e.g. from Barbarian to
- Latin-Cyrillic) are performed through these tables and functions. See
- ckuxla.h and ckuxla.c for extensive examples.
-
- To add a new Transfer Character Set, e.g. Latin Alphabet 9 (for the
- Euro symbol), again in the "old" character-set modules:
-
- In ckcxla.h:
-
- + Add a TC_xxxx definition and increase MAXTCSETS accordingly.
-
- In ck?xla.h (since any transfer charset is also a file charset):
-
- + Add an FC_xxxx definition and increase MAXFCSETS accordingly.
-
- In ck?xla.c:
-
- + Add a tcsinfo[] entry.
- + Make a tcstab[] keyword table entry.
- + Make an fcsinfo[] table entry.
- + Make an fcstab[] keyword table entry.
- + Make a tcstab[] keyword table entry.
- + If necessary, make a langinfo[] table entry.
- + Make entries in the function pointer arrays.
- + Provide any needed functions.
-
- As of C-Kermit 7.0, character sets are also handled in parallel by the
- new (and very large) Unicode module, ckcuni.[ch]. Eventually we should
- phase out the old way, described just above, and operate entirely in
- (and through) Unicode. The advantages are many. The disadvantages are
- size and performance. To add a character to the Unicode modules:
-
- In ckcuni.h:
-
- + (To be filled in...)
-
- In ckcuni.c:
-
- + (To be filled in...)
-
- [ [96]Contents ] [ [97]C-Kermit ] [ [98]Kermit Home ]
-
-4.D. Group D: User Interface
-
- This is the code that communicates with the user, gets her commands,
- informs her of the results. It may be command-line oriented,
- interactive prompting dialog, menus and arrow keys, windows and mice,
- speech recognition, telepathy, etc. The one provided is command-and
- prompt, with the ability to read commands from various sources: the
- console keyboard, a file, or a macro definition. The user interface has
- three major functions:
-
- 1. Sets the parameters for the file transfer and then starts it. This
- is done by setting certain (many) global variables, such as the
- protocol machine start state, the file specification, file type,
- communication parameters, packet length, window size, character
- set, etc.
- 2. Displays messages on the user's screen during the file transfer,
- using the screen() function, which is called by the group-1
- modules.
- 3. Executes any commands directly that do not require Kermit protocol,
- such as the CONNECT command, local file management commands,
- parameter-setting commands, FTP client commands, etc.
-
- If you plan to embed the [99]Group B, files into a program with a
- different user interface, your interface must supply an appropriate
- screen() function, plus a couple related ones like chkint() and
- intmsg() for handling keyboard (or mouse, etc) interruptions during
- file transfer. The best way to find out about this is to link all the
- C-Kermit modules together except the ckuu*.o and ckucon.o modules, and
- see which missing symbols turn up.
-
- C-Kermit's character-oriented user interface (as opposed to the
- Macintosh version's graphical user interface) consists of the following
- modules. C-Kermit can be built with an interactive command parser, a
- command-line-option-only parser, a graphical user interface, or any
- combination, and it can even be built with no user interface at all (in
- which case it runs as a remote-mode Kermit server).
-
- [100]ckucmd.h
- [101]ckucmd.c
- The command parsing primitives used by the interactive command
- parser to parse keywords, numbers, filenames, etc, and to give
- help, complete fields, supply defaults, allow abbreviations and
- editing, etc. This package is totally independent of Kermit, but
- does depend on the [102]Group E functions.
-
- [103]ckuusr.h
- Definitions of symbols used in Kermit's commands.
-
- ckuus*.c
- Kermit's interactive command parser, including the script
- programming language: [104]ckuusr.c (includes top-level keyword
- tables); [105]ckuus2.c (HELP command text); [106]ckuus3.c (most
- of the SET command); [107]ckuus4.c (includes variables and
- functions); ckuus[567].c (miscellaneous);
-
- [108]ckuusy.c
- The command-line-option parser.
-
- [109]ckuusx.c
- User interface functions common to both the interactive and
- command-line parsers.
-
- [110]ckuver.h
- Version heralds for different implementations.
-
- [111]ckuscr.c
- The (old, uucp-like) SCRIPT command
-
- [112]ckudia.c
- The DIAL command. Includes specific knowledge of many types of
- modems.
-
- Note that none of the above files is actually Unix-specific. Over time
- they have proven to be portable among all platforms where C-Kermit is
- built: Unix, VMS, AOS/VS, Amiga, OS-9, VOS, etc etc. Thus the third
- letter should more properly be "c", but changing it would be too
- confusing.
-
- ck?con.c, ckucns.c
- The CONNECT command. Terminal connection, and in some cases
- (Macintosh, Windows) also terminal emulation. NOTE: As of
- C-Kermit 7.0, there are two different CONNECT modules for UNIX:
- [113]ckucon.c -- the traditional, portable, fork()-based version
- -- and [114]ckucns.c, a new version that uses select() rather
- than forks so it can handle encryption. ckucns.c is the
- preferred version for Unix; ckucon.c is not likely to keep pace
- with it in terms of upgrades, etc. However, since select() is
- not portable to every platform, ckucon.c will be kept
- indefinitely for those platforms that can't use ckucns.c. NOTE:
- SunLink X.25 support is available only in ckucon.c.
-
- ck_*.*, ckuat*.*
- Modules having to do with authentication and encryption. Since
- the relaxation of USA export laws, they are included with the
- general source-code distribution. Secure C-Kermit binaries can
- be built using special targets in the standard makefile.
- However, secure prebuilt binaries may not be distributed.
-
- For other implementations, the files may, and probably do, have
- different names. For example, the Macintosh graphical user interface
- filenames start with "ckm". Kermit 95 uses the ckucmd and ckuus*
- modules, but has its own CONNECT command modules. And so on.
-
- Here is a brief description of C-Kermit's "user interface interface",
- from ckuusr.c. It is nowhere near complete; in particular, hundreds of
- global variables are shared among the many modules. These should, some
- day, be collected into classes or structures that can be passed around
- as needed; not only for purity's sake, but also to allow for multiple
- simultaneous communication sessions and or user interfaces. Our list of
- things to do is endless, and reorganizing the source is almost always
- at the bottom.
-
- The ckuus*.c modules (like many of the ckc*.c modules) depend on the
- existence of C library features like fopen, fgets, feof, (f)printf,
- argv/argc, etc. Other functions that are likely to vary among operating
- systems -- like setting terminal modes or interrupts -- are invoked via
- calls to functions that are defined in the [115]Group E
- platform-dependent modules, ck?[ft]io.c. The command line parser
- processes any arguments found on the command line, as passed to main()
- via argv/argc. The interactive parser uses the facilities of the cmd
- package (developed for this program, but, in theory, usable by any
- program). Any command parser may be substituted for this one. The only
- requirements for the Kermit command parser are these:
-
- 1. Set parameters via global variables like duplex, speed, ttname,
- etc. See [116]ckcmai.c for the declarations and descriptions of
- these variables.
- 2. If a command can be executed without the use of Kermit protocol,
- then execute the command directly and set the sstate (start state)
- variable to 0. Examples include SET commands, local directory
- listings, the CONNECT command.
- 3. If a command requires the Kermit protocol, set the following
- variables:
- sstate string data
- 'x' (enter server mode) (none)
- 'r' (send a 'get' command) cmarg, cmarg2
- 'v' (enter receive mode) cmarg2
- 'g' (send a generic command) cmarg
- 's' (send files) nfils, cmarg & cmarg2 OR cmlist
- 'c' (send a remote host command) cmarg
-
-
- cmlist is an array of pointers to strings.
- cmarg, cmarg2 are pointers to strings.
- nfils is an integer (hmmm, probably should be an unsigned long).
-
- cmarg can be:
- A filename string (possibly wild), or:
- a pointer to a prefabricated generic command string, or:
- a pointer to a host command string.
-
- cmarg2 is:
- The name to send a single file under, or:
- the name under which to store an incoming file; must not
- be wild.
- If it's the name for receiving, a null value means to
- store the file under the name it arrives with.
-
- cmlist is:
- A list of nonwild filenames, such as passed via argv.
-
- nfils is an integer, interpreted as follows:
- -1: filespec (possibly wild) in cmarg, must be expanded
- internally.
- 0: send from stdin (standard input).
- >0: number of files to send, from cmlist.
-
- The screen() function is used to update the screen during file
- transfer. The tlog() function writes to a transaction log (if TLOG is
- defined). The debug() function writes to a debugging log (if DEBUG is
- defined). The intmsg() and chkint() functions provide the user i/o for
- interrupting file transfers.
-
- [ [117]Contents ] [ [118]C-Kermit ] [ [119]Kermit Home ]
-
-4.E. Group E: Platform-Dependent I/O
-
- Platform-dependent function definitions. All the Kermit modules,
- including the command package, call upon these functions, which are
- designed to provide system-independent primitives for controlling and
- manipulating devices and files. For Unix, these functions are defined
- in the files [120]ckufio.c (files), [121]ckutio.c (communications), and
- [122]ckusig.c (signal handling).
-
- For VMS, the files are [123]ckvfio.c, ckvtio.c, and [124]ckusig.c (VMS
- can use the same signal handling routines as Unix). It doesn't really
- matter what the files are called, except for Kermit distribution
- purposes (grouping related files together alphabetically), only that
- each function is provided with the name indicated, observes the same
- calling and return conventions, and has the same type.
-
- The Group E modules contain both functions and global variables that
- are accessed by modules in the other groups. These are now described.
-
- (By the way, I got this list by linking all the C-Kermit modules
- together except ckutio and ckufio. These are the symbols that ld
- reported as undefined. But that was a long time ago, probably circa
- Version 6.)
-
-4.E.1. Global Variables
-
- char *DELCMD;
- Pointer to string containing command for deleting files.
- Example: char *DELCMD = "rm -f "; (UNIX)
- Example: char *DELCMD = "delete "; (VMS)
- Note trailing space. Filename is concatenated to end of this
- string. NOTE: DELCMD is used only in versions that do not
- provide their own built-in DELETE command.
-
- char *DIRCMD;
- Pointer to string containing command for listing files when a
- filespec is given.
- Example: char *DIRCMD = "/bin/ls -l "; (UNIX)
- Example: char *DIRCMD = "directory "; (VMS)
- Note trailing space. Filename is concatenated to end of this
- string. NOTE: DIRCMD is used only in versions that do not
- provide their own built-in DIRECTORY command.
-
- char *DIRCM2;
- Pointer to string containing command for listing files when a
- filespec is not given. (currently not used, handled in another
- way.)
- Example: char *DIRCMD2 = "/bin/ls -ld *";
- NOTE: DIRCMD2 is used only in versions that do not provide their
- own built-in DIRECTORY command.
-
- char *PWDCMD;
- Pointer to string containing command to display current
- directory.
- Example: char *PWDCMD = "pwd ";
- NOTE: PWDCMD is used only in versions that do not provide their
- own built-in PWD command.
-
- char *SPACMD;
- Pointer to command to display free disk space in current
- device/directory.
- Example: char *SPACMD = "df .";
- NOTE: SPACMD is used only in versions that do not provide their
- own built-in SPACE command.
-
- char *SPACM2;
- Pointer to command to display free disk space in another
- device/directory.
- Example: char *SPACM2 = "df ";
- Note trailing space. Device or directory name is added to this
- string. NOTE: SPACMD2 is used only in versions that do not
- provide their own built-in SPACE command.
-
- char *TYPCMD;
- Pointer to command for displaying the contents of a file.
- Example: char *TYPCMD = "cat ";
- Note trailing space. Device or directory name is added to this
- string. NOTE: TYPCMD is used only in versions that do not
- provide their own built-in TYPE command.
-
- char *WHOCMD;
- Pointer to command for displaying logged-in users.
- Example: char *WHOCMD = "who ";
- Note trailing space. Specific user name may be added to this
- string.
-
- int backgrd = 0;
- Flag for whether program is running in foreground (0) or
- background (nonzero). Background operation implies that screen
- output should not be done and that all errors should be fatal.
-
- int ckxech;
- Flag for who is to echo console typein:
- 1: The program (system is not echoing).
- 0: The OS, front end, terminal, etc (not this program).
-
- char *ckxsys;
- Pointer to string that names the computer and operating system.
- Example: char *ckxsys = " NeXT Mach 1.0";
- Tells what computer system ckxv applies to. In UNIX Kermit, this
- variable is also used to print the program herald, and in the
- SHOW VERSION command.
-
- char *ckxv;
- Pointer to version/edit info of ck?tio.c module.
- Example: char *ckxv = "UNIX Communications Support, 6.0.169, 6
- Sep 96";
- Used by SHOW VERSION command.
-
- char *ckzsys;
- Like ckxsys, but briefer.
- Example: char *ckzsys = " 4.3 BSD";
- Tells what platform ckzv applies to. Used by the SHOW VERSION
- command.
-
- char *ckzv;
- Pointer to version/edit info of ck?fio.c module.
- Example: char *ckzv = "UNIX File support, 6.0.113, 6 Sep 96";
- Used by SHOW VERSION command.
-
- int dfflow;
- Default flow control. 0 = none, 1 = Xon/Xoff, ... (see FLO_xxx
- symbols in ckcdeb.h)
- Set by Group E module. Used by [125]ckcmai.c to initialize flow
- control variable.
-
- int dfloc;
- Default location. 0 = remote, 1 = local. Set by Group E module.
- Used by ckcmai.c to initialize local variable. Used in various
- places in the user interface.
-
- int dfprty;
- Default parity. 0 = none, 'e' = even, 'o' = odd, 'm' = mark, 's'
- = space. Set by Group E module. Used by ckcmai.c to initialize
- parity variable.
-
- char *dftty;
- Default communication device. Set by Group E module. Used in
- many places. This variable should be initialized the symbol
- CTTNAM, which is defined in ckcdeb.h, e.g. as "/dev/tty" for
- UNIX, "TT:" for VMS, etc. Example: char *dftty = CTTNAM;
-
- char *mtchs[];
- Array of string pointers to filenames that matched the most
- recent wildcard match, i.e. the most recent call to zxpand().
- Used (at least) by command parsing package for partial filename
- completion.
-
- int tilde_expand;
- Flag for whether to attempt to expand leading tildes in
- directory names (used in UNIX only, and then only when the
- symbol DTILDE is defined.
-
- int ttnproto;
- The protocol being used to communicate over a network device.
- Values are defined in ckcnet.h. Example: NP_TELNET is network
- protocol "telnet".
-
- int maxnam;
- The maximum length for a filename, exclusive of any device or
- directory information, in the format of the host operating
- system.
-
- int maxpath;
- The maximum length for a fully specified filename, including
- device designator, directory name, network node name, etc, in
- the format of the host operating system, and including all
- punctuation.
-
- int ttyfd;
- File descriptor of the communication device. -1 if there is no
- open or usable connection, including when C-Kermit is in remote
- mode. Since this is not implemented everywhere, references to it
- are in #ifdef CK_TTYFD..#endif.
-
- [ [126]Contents ] [ [127]C-Kermit ] [ [128]Kermit Home ]
-
-4.E.2. Functions
-
- These are divided into three categories: file-related functions (B.1),
- communication functions (B.2), and miscellaneous functions (B.3).
-
-4.E.2.1. File-Related Functions
-
- In most implementations, these are collected together into a module
- called ck?fio.c, where ? = "u" ([129]ckutio.c for Unix), "v"
- ([130]ckvtio.c for VMS), [131]etc. To be totally platform-independent,
- C-Kermit maintains its own file numbers, and provides the functions
- described in this section to deal with the files associated with them.
- The file numbers are referred to symbolically, and are defined as
- follows in ckcker.h:
-
- #define ZCTERM 0 /* Console terminal */
- #define ZSTDIO 1 /* Standard input/output */
- #define ZIFILE 2 /* Current input file for SEND command */
- #define ZOFILE 3 /* Current output file for RECEIVE command */
- #define ZDFILE 4 /* Current debugging log file */
- #define ZTFILE 5 /* Current transaction log file */
- #define ZPFILE 6 /* Current packet log file */
- #define ZSFILE 7 /* Current session log file */
- #define ZSYSFN 8 /* Input from a system function (pipe) */
- #define ZRFILE 9 /* Local file for READ command */ (NEW)
- #define ZWFILE 10 /* Local file for WRITE command */ (NEW)
- #define ZMFILE 11 /* Auxiliary file for internal use */ (NEW)
- #define ZNFILS 12 /* How many defined file numbers */
-
- In the descriptions below, fn refers to a filename, and n refers to one
- of these file numbers. Functions are of type int unless otherwise
- noted, and are listed mostly alphabetically.
-
- int
- chkfn(n) int n;
- Checks the file number n. Returns:
- -1: File number n is out of range
- 0: n is in range, but file is not open
- 1: n in range and file is open
-
- int
- iswild(filspec) char *filespec;
- Checks if the file specification is "wild", i.e. contains
- metacharacters or other notations intended to match multiple
- filenames. Returns:
- 0: not wild
- 1: wild.
-
- int
- isdir(string) char *string;
- Checks if the string is the name of an existing directory. The
- idea is to check whether the string can be "cd'd" to, so in some
- cases (e.g. DOS) it might also indicate any file structured
- device, such as a disk drive (like A:). Other nonzero returns
- indicate system-dependent information; e.g. in VMS
- isdir("[.FOO]") returns 1 but isdir("FOO.DIR;1") returns 2 to
- indicate the directory-file name is in a format that needs
- conversion before it can be combined with a filename. Returns:
- 0: not a directory (including any kind of error)
- 1: it is an existing directory
-
- char *
- zfcdat(name) char *name;
- Returns modification (preferably, otherwise creation) date/time
- of file whose name is given in the argument string. Return value
- is a pointer to a string of the form yyyymmdd hh:mm:ss, for
- example 19931231 23:59:59, which represents the local time (no
- timezone or daylight savings time finagling required). Returns
- the null string ("") on failure. The text pointed to by the
- string pointer might be in a static buffer, and so should be
- copied to a safe place by the caller before any subsequent calls
- to this function.
-
- struct zfnfp *
- zfnqfp(fn, buflen, buf) char * fn; int buflen; char * buf;
- Given the filename fn, the corresponding fully qualified,
- absolute filename is placed into the buffer buf, whose length is
- buflen. On failure returns a NULL pointer. On success returns a
- pointer to a struct zfnfp containing pointers to the full
- pathname and to just the filename, and an int giving the length
- of the full pathname. All references to this function in
- mainline code must be protected by #ifdef ZFNQFP..#endif,
- because it is not present in all of the ck*fio.c modules. So if
- you implement this function in a version that did not have it
- before, be sure to add #define ZFNQFP in the appropriate spot in
- ckcdeb.h or in the build-procedure CFLAGS.
-
- int
- zcmpfn(s1,s2) char * s2, * s2;
- Compares two filenames to see if they refer to the same.
- Internally, the arguments can be converted to fully qualified
- pathnames, e.g. with zfnqfp(), realpath(), or somesuch. In Unix
- or other systems where symbolic links exist, the link should be
- resolved before making the comparison or looking at the inodes.
- Returns:
- 0: Files are not identical.
- 1: Files are identical.
-
- int
- zfseek(pos) long pos;
- Positions the input pointer on the current input file to the
- given position. The pos argument is 0-based, the offset
- (distance in bytes) from beginning of the file. Needed for
- RESEND, PSEND, and other recovery operations. This function is
- not necessarily possible on all systems, e.g. record-oriented
- systems. It should only be used on binary files (i.e. files we
- are sending in binary mode) and stream-oriented file systems.
- Returns:
- -1: on failure.
- 0: On success.
-
- int
- zchdir(dirnam) char *dirnam;
- Changes current or default directory to the one given in dirnam.
- Returns:
- 0: On failure.
- 1: on success.
-
- long
- zchki(fn) char *fn;
- Check to see if file with name fn is a regular, readable,
- existing file, suitable for Kermit to send -- not a directory,
- not a symbolic link, etc. Returns:
- -3: if file exists but is not accessible (e.g. read-protected);
- -2: if file exists but is not of a readable type (e.g. a
- directory);
- -1: on error (e.g. file does not exist, or fn is garbage);
- >=0: (length of file) if file exists and is readable.
- Also see isdir(), zgetfs().
-
- int
- zchkpid(pid) unsigned long pid;
- Returns:
- 1: If the given process ID (e.g. pid in UNIX) is valid and
- active
- 0: otherwise.
-
- long
- zgetfs(fn) char *fn;
- Gets the size of the given file, regardless of accessibility.
- Used for directory listings. Unlike zchki(), should return the
- size of any kind of file, even a directory. zgetfs() also should
- serve as a mini "get file info" function that can be used until
- we design a better one, by also setting some global variables:
- int zgfs_link = 1/0 = file is (not) a symbolic link.
- int zgfs_dir = 1/0 = file is (not) a directory.
- char linkname[] = if zgfs_link != 0, name of file link points
- to.
- Returns:
- -1: on error (e.g. file does not exist, or fn is garbage);
- >=0: (length of file) if file exists and is readable.
-
- int
- zchko(fn) char *fn;
- Checks to see if a file of the given name can be created.
- Returns:
- -1: if file cannot be created, or on any kind of error.
- 0: if file can be created.
-
- int
- zchkspa(fn,len) char *f; long len;
- Checks to see if there is sufficient space to store the file
- named fn, which is len bytes long. If you can't write a function
- to do this, then just make a dummy that always returns 1; higher
- level code will recover from disk-full errors. The receiving
- Kermit uses this function to refuse an incoming file based on
- its size, via the attribute mechanism. Returns:
- -1: on error.
- 0: if there is not enough space.
- 1: if there is enough space.
-
- int
- zchin(n,c) int n; int *c;
- Gets a character from file number n, return it in c (call with
- &c). Returns:
- -1: on failure, including EOF.
- 0: on success with character in c.
-
- int
- zchout(n,c) int n; char c;
- Writes the character c to file number n. Returns:
- -1: on error.
- 0: on success.
-
- int
- zclose(n) int n;
- Closes file number n. Returns:
- -1: on error.
- 1: on success.
-
- int
- zdelet(fn) char *name;
- Attempts to delete (remove, erase) the named file. Returns:
- -1: on error.
- 1: if file was deleted successfully.
-
- char *
- zgperm(char * f)
- Returns a pointer to the system-dependent numeric
- permissions/protection string for file f, or NULL upon failure.
- Used if CK_PERMS is defined.
-
- char *
- ziperm(char * f)
- Returns a pointer to the system-dependent symbolic
- permissions/protection string for file f, or NULL upon failure.
- Used if CK_PERMS is defined. Example: In UNIX zgperm(f) might
- return "100770", but ziperm() might return "-rwxrwx---". In VMS,
- zgperm() would return a hexadecimal string, but ziperm() would
- return something like "(RWED,RWED,RE,)".
-
- char *
- zgtdir()
- Returns a pointer to the name of the current directory, folder,
- etc, or a NULL pointer if the current directory cannot be
- determined. If possible, the directory specification should be
- (a) fully specified, e.g. as a complete pathname, and (b) be
- suitable for appending a filename. Thus, for example, Unix
- directory names should end with '/'. VMS directory names should
- look like DEV:[NAME] (rather than, say, NAME.DIR;1).
-
- char *
- zhome()
- Returns a pointer to a string containing the user's home
- directory, or NULL upon error. Should be formatted like zgtdir()
- (q.v.).
-
- int
- zinfill()
- Fill buffer from input file. This function is used by the macro
- zminchar(), which is defined in ckcker.h. zminchar() manages its
- own buffer, and calls zinfill() to fill it whenever it becomes
- empty. It is used only for sending files, and reads characters
- only from file number ZIFILE. zinfill() returns -1 upon end of
- file, -2 upon fatal error, and -3 upon timeout (e.g. when
- reading from a pipe); otherwise it returns the first character
- from the buffer it just read.
-
- int
- zkself()
- Kills the current job, session, process, etc, logs out,
- disappears. Used by the Kermit server when it receives a BYE
- command. On failure, returns -1. On success, does not return at
- all! This function should not be called until all other steps
- have been taken to close files, etc.
-
- VOID
- zstrip(fn,&fn2) char *fn1, **fn2;
- Strips device and directory, etc, from file specification fn,
- leaving only the filename (including "extension" or "filetype"
- -- the part after the dot). For example DUA0:[PROGRAMS]OOFA.C;3
- becomes OOFA.C, or /usr/fdc/oofa.c becomes oofa.c. Returns a
- pointer to result in fn2.
-
- int
- zsetperm(char * file, unsigned int code)
- Set permissions of file to given system-dependent code. 0: On
- failure.
- 1: on success.
-
- int
- zsetroot(char * dir)
- Sets the root for the user's file access, like Unix chroot(),
- but does not require privilege. In Unix, this must be
- implemented entirely by Kermit's own file access routines.
- Returns:
- 1: Success
- -1: Invalid argument
- -2:
- -3: Internal error
- -4: Access to given directory denied
- -5: New root not within old root
-
- int
- zinroot(char * file)
- If no root is set (zsetroot()), returns 1.
- Otherwise, if given file is in the root, returns 1.
- Otherwise, returns 0.
-
- VOID
- zltor(fn,fn2) char *fn1, *fn2;
- Local-To-Remote filename translation. OBSOLETE: replaced by
- nzltor() (q.v.). Translates the local filename fn into a format
- suitable for transmission to an arbitrary type of computer, and
- copies the result into the buffer pointed to by fn2. Translation
- may involve (a) stripping the device and/or directory/path name,
- (b) converting lowercase to uppercase, (c) removing spaces and
- strange characters, or converting them to some innocuous
- alphabetic character like X, (d) discarding or converting extra
- periods (there should not be more than one). Does its best.
- Returns no value. name2 is a pointer to a buffer, furnished by
- the caller, into which zltor() writes the resulting name. No
- length checking is done.
-
- #ifdef NZLTOR
- VOID
- nzltor(fn,fn2,convert,pathnames,max) char *fn1,*fn2; int
- convert,pathnames,max;
- Replaces zltor(). This new version handles pathnames and checks
- length. fn1 and fn2 are as in zltor(). This version is called
- unconditionally for each file, rather than only when filename
- conversion is enabled. Pathnames can have the following values:
-
- PATH_OFF: Pathname, if any, is to be stripped
- PATH_REL: The relative pathname is to be included
- PATH_ABS: The full pathname is to be included
-
- After handling pathnames, conversion is done to the result as in
- the zltor() description if convert != 0; if relative or absolute
- pathnames are included, they are converted to UNIX format, i.e.
- with slash (/) as the directory separator. The max parameter
- specifies the maximum size of fn2. If convert > 0, the regular
- conversions are done; if convert < 0, minimal conversions are
- done (we skip uppercasing the letters, we allow more than one
- period, etc; this can be used when we know our partner is UNIX
- or similar).
-
- #endif /* NZLTOR */
-
- int
- nzxpand(fn,flags) char *fn; int flags;
- Replaces zxpand(), which is obsolete as of C-Kermit 7.0.
- Call with:
- fn = Pointer to filename or pattern.
- flags = option bits:
- flags & ZX_FILONLY Match regular files
- flags & ZX_DIRONLY Match directories
- flags & ZX_RECURSE Descend through directory tree
- flags & ZX_MATCHDOT Match "dot files"
- flags & ZX_NOBACKUP Don't match "backup files"
- flags & ZX_NOLINKS Don't follow symlinks.
-
- Returns the number of files that match fn, with data structures
- set up so the first file (if any) will be returned by the next
- znext() call. If ZX_FILONLY and ZX_DIRONLY are both set, or
- neither one is set, files and directories are matched. Notes:
-
- 1. It is essential that the number returned by nzxpand() reflect
- the actual number of filenames that will be returned by
- znext() calls. In other words:
- for (n = nzxpand(string,flags); n > 0; n--) {
- znext(buf);
- printf("%s\n", buf);
- }
-
- should print all the file names; no more, no less.
- 2. In UNIX, DOS, OS-9, etc, where directories contain entries for
- themselves (.) and the superior directory (..), these should
- NOT be included in the list under any circumstances, including
- when ZX_MATCHDOT is set.
- 3. Additional option bits might be added in the future, e.g. for
- sorting (sort by date/name/size, reverse/ascending, etc).
- Currently this is done only in higher level code (through a
- hack in which the nzxpand() exports its filename array, which
- is not portable because not all OS's can use this mechanism).
-
- int
- zmail(addr,fn) char *addr, fn;
- Send the local, existing file fn as e-mail to the address addr.
- Returns:
- 0: on success
- 2: if mail delivered but temp file can't be deleted
- -2: if mail can't be delivered
-
- int
- zmkdir(path) char *path;
- The path can be a file specification that might contain
- directory information, in which the filename is expected to be
- included, or an unambiguous directory specification (e.g. in
- UNIX it must end with "/"). This routine attempts to create any
- directories in the given path that don't already exist. Returns
- 0 or greater success: no directories needed creation, or else
- all directories that needed creation were created successfully;
- the return code is the number of directories that were created.
- Returns -1 on failure to create any of the needed directories.
-
- int
- zrmdir(path) char *path;
- Attempts to remove the given directory. Returns 0 on success, -1
- on failure. The detailed semantics are open -- should it fail if
- the directory contains any files or subdirectories, etc. It is
- probably best for this routine to behave in whatever manner is
- customary on the underlying platform; e.g. in UNIX, VMS, DOS,
- etc, where directories can not be removed unless they are empty.
-
- VOID
- znewn(fn,s) char *fn, **s;
- Transforms the name fn into a filename that is guaranteed to be
- unique. If the file fn does not exist, then the new name is the
- same as fn; Otherwise, it's different. this function does its
- best, returns no value. New name is created in caller's space.
- Call like this: znewn(old,&new);. The second parameter is a
- pointer to the new name. This pointer is set by znewn() to point
- to a static string in its own space, so be sure to the result to
- a safe place before calling this function again.
-
- int
- znext(fn) char *fn;
- Copies the next file name from a file list created by zxpand()
- into the string pointed to by fn (see zxpand). If no more files,
- then the null string is placed there. Returns 0 if there are no
- more filenames, with 0th element the array pointed to by fn set
- to NUL. If there is a filename, it is stored in the array
- pointed to by fn and a positive number is returned. NOTE: This
- is a change from earlier definitions of this function
- (pre-1999), which returned the number of files remaining; thus 0
- was the return value when returning the final file. However, no
- mainline code ever depended on the return value, so this change
- should be safe.
-
- int
- zopeni(n,fn) int n; char *fn;
- Opens the file named fn for input as file number n. Returns:
- 0: on failure.
- 1: on success.
-
- int
- zopeno(n,fn,zz,fcb) int n; char *name; struct zattr *zz; struct
- filinfo *fcb;
- Attempts to open the named file for output as file number n. zz
- is a Kermit file attribute structure as defined in ckcdeb.h,
- containing various information about the file, including its
- size, creation date, and so forth. This function should attempt
- to honor as many of these as possible. fcb is a "file control
- block" in the traditional sense, defined in ckcdeb.h, containing
- information relevant to complicated file systems like VMS (RMS),
- IBM MVS, etc, like blocksize, record length, organization,
- record format, carriage control, etc. Returns:
- 0: on failure.
- 1: on success.
-
- int
- zoutdump()
- Dumps a file output buffer. Used with the macro zmchout()
- defined in ckcker.h. Used only with file number ZOFILE, i.e. the
- file that is being received by Kermit during file transfer.
- Returns:
- -1: on failure.
- 0: on success.
-
- int
- zprint(p,fn) char *p, *f;
- Prints the file with name fn on a local printer, with options p.
- Returns:
- 0: on success
- 3: if file sent to printer but can't be deleted
- -3: if file can't be printed
-
- int
- zrename(fn,fn2) char *fn, *fn2;
- Changes the name of file fn to fn2. If fn2 is the name of an
- existing directory, or a file-structured device, then file fn is
- moved to that directory or device, keeping its original name. If
- fn2 lacks a directory separator when passed to this function, an
- appropriate one is supplied. Returns:
- -1: on failure.
- 0: on success.
-
- int
- zcopy(source,dest) char * source, * dest;
- Copies the source file to the destination. One file only. No
- wildcards. The destination string may be a filename or a
- directory name. Returns:
- 0: on success.
- <0: on failure:
- -2: source file is not a regular file.
- -3: source file not found.
- -4: permission denied.
- -5: source and destination are the same file.
- -6: i/o error.
- -1: other error.
-
- char *
- zlocaltime(char *)
- Call with: "yyyymmdd hh:mm:ss" GMT/UTC date-time. Returns
- pointer to local date-time string "yyyymmdd hh:mm:ss" on
- success, NULL on failure.
-
- VOID
- zrtol(fn,fn2) char *fn, *fn2;
- Remote-To-Local filename translation. OBSOLETE: replaced by
- nzrtol(). Translates a "standard" filename to a local filename.
- For example, in Unix this function might convert an
- all-uppercase name to lowercase, but leave lower- or mix-case
- names alone. Does its best, returns no value. New name is in
- string pointed to by fn2. No length checking is done.
-
- #ifdef NZLTOR
- int
- nzrtol(fn,fn2,convert,pathnames,max) char *fn1,*fn2; int
- convert,pathnames,max;
- Replaces zrtol. Like zrtol but handles pathnames and checks
- length. See nzltor for detailed description of parameters.
-
- #endif /* NZLTOR */
-
- int
- zsattr(xx) struct zattr *xx;
- Fills in a Kermit file attribute structure for the file which is
- to be sent, namely the currently open ZIFILE. Note that this is
- not a very good design, but we're stuck with it. Callers must
- ensure that zsattr() is called only on real files, not on pipes,
- internally generated file-like objects such as server REMOTE
- command responses, etc. Returns:
- -1: on failure.
- 0: on success with the structure filled in.
- If any string member is null, it should be ignored by the
- caller.
- If any numeric member is -1, it should be ignored by the caller.
-
- int
- zshcmd(s) char *s;
- s contains to pointer to a command to be executed by the host
- computer's shell, command parser, or operating system. If the
- system allows the user to choose from a variety of command
- processors (shells), then this function should employ the user's
- preferred shell. If possible, the user's job (environment,
- process, etc) should be set up to catch keyboard interruption
- signals to allow the user to halt the system command and return
- to Kermit. The command must run in ordinary, unprivileged user
- mode. If possible, this function should return -1 on failure to
- start the command, or else it should return 1 if the command
- succeeded and 0 if it failed.
-
- int
- pexitstatus
- zshcmd() and zsyscmd() should set this to the command's actual
- exit status code if possible.
-
- int
- zsyscmd(s) char *s;
- s contains to pointer to a command to be executed by the host
- computer's shell, command parser, or operating system. If the
- system allows the user to choose from a variety of command
- processors (shells), then this function should employ the system
- standard shell (e.g. /bin/sh for Unix), so that the results will
- always be the same for everybody. If possible, the user's job
- (environment, process, etc) should be set up to catch keyboard
- interruption signals to allow the user to halt the system
- command and return to Kermit. The command must run in ordinary,
- unprivileged user mode. If possible, this function should return
- -1 on failure to start the command, or else it should return 1
- if the command succeeded and 0 if it failed.
-
- VOID
- z_exec(s,args) char * s; char * args[];
- This one executes the command s (which is searched for using the
- system's normal searching mechanism, such as PATH in UNIX), with
- the given argument vector, which follows the conventions of UNIX
- argv[]: the name of the command pointed to by element 0, the
- first arg by element 1, and so on. A null args[] pointer
- indicates the end of the argument list. All open files must
- remain open so the exec'd process can use them. Returns only if
- unsuccessful.
-
- int
- zsinl(n,s,x) int n, x; char *s;
- Reads a line from file number n. Writes the line into the
- address s provided by the caller. Writing terminates when
- newline is read, but with newline discarded. Writing also
- terminates upon EOF or if length x is exhausted. Returns:
- -1: on EOF or error.
- 0: on success.
-
- int
- zsout(n,s) int n; char *s;
- Writes the string s out to file number n. Returns:
- -1: on failure.
- 0: on success.
-
- int
- zsoutl(n,s) int n; char *s;
- Writes the string s out to file number n and adds a line
- (record) terminator (boundary) appropriate for the system and
- the file format. Returns:
- -1: on failure.
- 0: on success.
-
- int
- zsoutx(n,s,x) int n, x; char *s;
- Writes exactly x characters from string s to file number n. If s
- has fewer than x characters, then the entire string s is
- written. Returns:
- -1: on failure.
- >= 0: on success, the number of characters actually written.
-
- int
- zstime(fn,yy,x) char *fn; struct zattr *yy; int x;
- Sets the creation date (and other attributes) of an existing
- file, or compares a file's creation date with a given date. Call
- with:
-
- fn: pointer to name of existing file.
- yy: Pointer to a Kermit file attribute structure in which yy->date.val
- is a date of the form yyyymmdd hh:mm:ss, e.g. 19900208 13:00:00, which
- is to be used for setting or comparing the file date. Other attributes
- in the struct can also be set, such as the protection/permission (See
- [132]Appendix I), when it makes sense (e.g. "yy->lprotect.val" can be
- set if the remote system ID matches the local one).
- x: A function code: 0 means to set the file's creation date as given.
- 1 means compare the date from the yy struct with the file's date.
-
- Returns:
- -1: on any kind of error.
- 0: if x is 0 and the file date was set successfully.
- 0: if x is 1 and date from attribute structure > file creation
- date.
- 1: if x is 1 and date from attribute structure <= file
- creation date.
-
- VOID
- zstrip(name,name2) char *name, **name2;
- Strips pathname from filename "name". Constructs the resulting
- string in a static buffer in its own space and returns a pointer
- to it in name2. Also strips device name, file version numbers,
- and other "non-name" material.
-
- int
- zxcmd(n,s) char *s;
- Runs a system command so its output can be accessed as if it
- were file n. The command is run in ordinary, unprivileged user
- mode.
- If n is ZSTDIO or ZCTERM, returns -1.
- If n is ZIFILE or ZRFILE, then Kermit reads from the command,
- otherwise Kermit writes to the command.
- Returns 0 on error, 1 on success.
-
- int
- zxpand(fn) char *fn;
- OBSOLETE: Replaced by nzxpand(), q.v.
-
- #ifdef ZXREWIND
- int
- zxrewind()
- Returns the number of files returned by the most recent
- nzxpand() call, and resets the list to the beginning so the next
- znext() call returns the first file. Returns -1 if zxpand has
- not yet been called. If this function is available, ZXREWIND
- should be defined; otherwise it should not be referenced.
-
- #endif /* ZXREWIND */
-
- int
- xsystem(cmd) char *cmd;
- Executes the system command without redirecting any of its i/o,
- similar (well, identical) to system() in Unix. But before
- passing the command to the system, xsystem() ensures that all
- privileges are turned off, so that the system command executes
- in ordinary unprivileged user mode. If possible, xsystem()
- returns the return code of the command that was executed.
-
-4.E.2.2. IKSD Variables and Functions
-
- These must be implemented in any C-Kermit version that is to be
- installed as an Internet Kermit Service Daemon (IKSD). IKSD is expected
- to be started by the Internet Daemon (e.g. inetd) with its standard i/o
- redirected to the incoming connection.
-
- int ckxanon;
- Nonzero if anonymous logins allowed.
-
- extern int inserver;
- Nonzero if started in IKSD mode.
-
- extern int isguest;
- Nonzero if IKSD and user logged in anonymously.
-
- extern char * homdir;
- Pointer to user's home directory.
-
- extern char * anonroot;
- Pointer to file-system root for anonymous users.
-
- Existing functions must make "if (inserver && isguest)" checks for
- actions that would not be legal for guests: zdelete(), zrmdir(),
- zprint(), zmail(), etc.
-
- int
- zvuser(name) char * name;
- Verifies that user "name" exists and is allowed to log in. If
- the name is "ftp" or "anonymous" and ckxanon != 0, a guest login
- is set up. Returns 0 if user not allowed to log in, nonzero if
- user may log in.
-
- int
- zvpass(string) char * string;
- Verifies password of the user from the most recent zvuser()
- call. Returns nonzero if password is valid for user, 0 if it
- isn't. Makes any appropriate system log entries (IKSD logins,
- failed login attempts, etc). If password is valid, logs the user
- in as herself (if real user), or sets up restricted anonymous
- access if user is guest (e.g. changes file-system root to
- anonroot and sets isguest = 1).
-
- VOID
- zsyslog()
- Begins any desired system logging of an IKSD session.
-
- VOID
- zvlogout()
- Terminates an IKSD session. In most cases this is simply a
- wrapper for exit() or doexit(), with some system logging added.
-
-4.E.2.3. Privilege Functions
-
- These functions are used by C-Kermit to adapt itself to operating
- systems where the program can be made to run in a "privileged" mode,
- e.g. setuid or setgid in Unix. C-Kermit should NOT read and write files
- or start subprocesses as a privileged program. This would present a
- serious threat to system security. The security package has been
- installed to prevent such security breaches by turning off the
- program's special privileges at all times except when they are needed.
-
- In UNIX, the only need Kermit has for privileged status is access to
- the UUCP lockfile directory, in order to read, create, and destroy
- lockfiles, and to open communication devices that are normally
- protected against the user (see the [133]Unix C-Kermit Installation
- Instructions for discussion). Therefore, privileges should only be
- enabled for these operations and disabled at all other times. This
- relieves the programmer of the responsibility of putting expensive and
- unreliable access checks around every file access and subprocess
- creation.
-
- Strictly speaking, these functions are not required in all C-Kermit
- implementations, because their use (so far, at least) is internal to
- the Group E modules. However, they should be included in all C-Kermit
- implementations for operating systems that support the notion of a
- privileged program (UNIX, RSTS/E, what others?).
-
- int
- priv_ini()
- Determine whether the program is running in privileged status.
- If so, turn off the privileges, in such a way that they can be
- turned on again when needed. Called from sysinit() at program
- startup time. Returns:
- 0 on success
- nonzero on failure, in which case the program should halt
- immediately.
-
- int
- priv_on()
- If the program is not privileged, this function does nothing. If
- the program is privileged, this function returns it to
- privileged status. priv_ini() must have been called first.
- Returns:
- 0 on success
- nonzero on failure
-
- int
- priv_off()
- Turns privileges off (if they are on) in such a way that they
- can be turned back on again. Returns:
- 0 on success
- nonzero on failure
-
- int
- priv_can()
- Turns privileges off in such a way that they cannot be turned
- back on. Returns:
- 0 on success
- nonzero on failure
-
- int
- priv_chk()
- Attempts to turns privileges off in such a way that they can be
- turned on again later. Then checks to make sure that they were
- really turned off. If they were not really turned off, then they
- are canceled permanently. Returns:
- 0 on success
- nonzero on failure
-
-4.E.2.4. Console-Related Functions
-
- These relate to the program's "console", or controlling terminal, i.e.
- the terminal that the user is logged in on and types commands at, or on
- a PC or workstation, the actual keyboard and screen.
-
- int
- conbin(esc) char esc;
- Puts the console into "binary" mode, so that Kermit's command
- parser can control echoing and other treatment of characters
- that the user types. esc is the character that will be used to
- get Kermit's attention during packet mode; puts this in a global
- place. Sets the ckxech variable. Returns:
- -1: on error.
- 0: on success.
-
- int
- concb(esc) char esc;
- Put console in "cbreak" (single-character wakeup) mode. That is,
- ensure that each console character is available to the program
- immediately when the user types it. Otherwise just like
- conbin(). Returns:
- -1: on error.
- 0: on success.
-
- int
- conchk()
- Returns a number, 0 or greater, the number of characters waiting
- to be read from the console, i.e. the number of characters that
- the user has typed that have not been read yet by Kermit.
-
- long
- congspd();
- Returns the speed ("baud rate") of the controlling terminal, if
- known, otherwise -1L.
-
- int
- congks(timo) int timo;
- Get Keyboard Scancode. Reads a keyboard scan code from the
- physical console keyboard. If the timo parameter is greater than
- zero, then times out and returns -2 if no character appears
- within the given number of seconds. Upon any other kind of
- error, returns -1. Upon success returns a scan code, which may
- be any positive integer. For situations where scan codes cannot
- be read (for example, when an ASCII terminal is used as the
- job's controlling terminal), this function is identical to
- coninc(), i.e. it returns an 8-bit character value. congks() is
- for use with workstations whose keyboards have Alternate,
- Command, Option, and similar modifier keys, and Function keys
- that generate codes greater than 255.
-
- int
- congm()
- Console get modes. Gets the current console terminal modes and
- saves them so that conres() can restore them later. Returns 1 if
- it got the modes OK, 0 if it did nothing (e.g. because Kermit is
- not connected with any terminal), -1 on error.
-
- int
- coninc(timo) int timo;
- Console Input Character. Reads a character from the console. If
- the timo parameter is greater than zero, then coninc() times out
- and returns -2 if no character appears within the given number
- of seconds. Upon any other kind of error, returns -1. Upon
- success, returns the character itself, with a value in the range
- 0-255 decimal.
-
- VOID
- conint(f,s) SIGTYP (*f)(), (*s)();
- Sets the console to generate an interrupt if the user types a
- keyboard interrupt character, and to transfer control the
- signal-handling function f. For systems with job control, s is
- the address of the function that suspends the job. Sets the
- global variable "backgrd" to zero if Kermit is running in the
- foreground, and to nonzero if Kermit is running in the
- background. See ckcdeb.h for the definition of SIGTYP. No return
- value.
-
- VOID
- connoi()
- Console no interrupts. Disable keyboard interrupts on the
- console. No return value.
-
- int
- conoc(c) char c;
- Writes character c to the console terminal. Returns:
- 0 on failure, 1 on success.
-
- int
- conol(s) char *s;
- Writes string s to the console. Returns -1 on error, 0 or
- greater on success.
-
- int
- conola(s) char *s[]; {
- Writes an array of strings to the console. Returns -1 on error,
- 0 or greater on success.
-
- int
- conoll(s) char *s;
- Writes string s to the console, followed by the necessary line
- termination characters to put the console cursor at the
- beginning of the next line. Returns -1 on error, 0 or greater on
- success.
-
- int
- conres()
- Restores the console terminal to the modes obtained by congm().
- Returns: -1 on error, 0 on success.
-
- int
- conxo(x,s) int x; char *s;
- Write x characters from string s to the console. Returns 0 or
- greater on success, -1 on error.
-
- char *
- conkbg();
- Returns a pointer to the designator of the console keyboard
- type. For example, on a PC, this function would return "88",
- "101", etc. Upon failure, returns a pointer to the empty string.
-
-4.E.2.5. Communications Functions
-
- The communication device is the device used for terminal emulation and
- file transfer. It may or may not be the same device as the console, and
- it may or may not be a terminal (serial-port) device; it could also be
- a network connection. For brevity, the communication device is referred
- to here as the "tty". When the communication device is the same as the
- console device, Kermit is said to be in remote mode. When the two
- devices are different, Kermit is in local mode.
-
- int
- ttchk()
- Returns the number of characters that have arrived at the
- communication device but have not yet been read by ttinc(),
- ttinl(), and friends. If communication input is buffered (and it
- should be), this is the sum of the number of unread characters
- in Kermit's buffer PLUS the number of unread characters in the
- operating system's internal buffer. The call must be
- nondestructive and nonblocking, and as inexpensive as possible.
- Returns:
- 0: or greater on success,
- 0: in case of internal error,
- -1: or less when it determines the connection has been broken,
- or there is no connection.
-
- That is, a negative return from ttchk() should reliably indicate
- that there is no usable connection. Furthermore, ttchk() should
- be callable at any time to see if the connection is open. When
- the connection is open, every effort must be made to ensure that
- ttchk returns an accurate number of characters waiting to be
- read, rather than just 0 (no characters) or 1 (1 or more
- characters), as would be the case when we use select(). This
- aspect of ttchk's operation is critical to successful operation
- of sliding windows and streaming, but "nondestructive buffer
- peeking" is an obscure operating system feature, and so when it
- is not available, we have to do it ourselves by managing our own
- internal buffer at a level below ttinc(), ttinl(), etc, as in
- the UNIX version (non-FIONREAD case).
-
- An external global variable, clsondisc, if nonzero, means that
- if a serial connection drops (carrier on-to-off transition
- detected by ttchk()), the device should be closed and released
- automatically.
-
- int
- ttclos()
- Closes the communication device (tty or network). If there were
- any kind of exclusive access locks connected with the tty, these
- are released. If the tty has a modem connection, it is hung up.
- For true tty devices, the original tty device modes are
- restored. Returns:
- -1: on failure.
- 0: on success.
-
- int
- ttflui()
- Flush communications input buffer. If any characters have
- arrived but have not yet been read, discard these characters. If
- communications input is buffered by Kermit (and it should be),
- this function flushes Kermit's buffer as well as the operating
- system's internal input buffer. Returns:
- -1: on failure.
- 0: on success.
-
- int
- ttfluo()
- Flush tty output buffer. If any characters have been written but
- not actually transmitted (e.g. because the system has been
- flow-controlled), remove them from the system's output buffer.
- (Note, this function is not actually used, but it is recommended
- that all C-Kermit programmers add it for future use, even if it
- is only a dummy function that returns 0 always.)
-
- int
- ttgmdm()
- Looks for the modem signals CTS, DSR, and CTS, and returns those
- that are on in as its return value, in a bit mask as described
- for ttwmdm, in which a bit is on (1) or off (0) according to
- whether the corresponding signal is on (asserted) or off (not
- asserted). Return values:
- -3: Not implemented
- -2: if the line does not have modem control
- -1: on error
- >=0: on success, with bit mask containing the modem signals.
-
- long
- ttgspd()
- Returns the current tty speed in BITS (not CHARACTERS) per
- second, or -1 if it is not known or if the tty is really a
- network, or upon any kind of error. On success, the speed
- returned is the actual number of bits per second, like 1200,
- 9600, 19200, etc.
-
- int
- ttgwsiz()
- Get terminal window size. Returns -1 on error, 0 if the window
- size can't be obtained, 1 if the window size has been
- successfully obtained. Upon success, the external global
- variables tt_rows and tt_cols are set to the number of screen
- rows and number of screen columns, respectively. As this
- function is not implemented in all ck*tio.c modules, calls to it
- must be wrapped in #ifdef CK_TTGWSIZ..#endif. NOTE: This
- function must be available to use the TELNET NAWS feature
- (Negotiate About Window Size) as well as Rlogin.
-
- int
- tthang()
- Hang up the current tty device. For real tty devices, turn off
- DTR for about 1/3-1/2 second (or other length of time, depending
- on the system). If the tty is really a network connection, close
- it. Returns:
- -1: on failure.
- 0: if it does not even try to hang up.
- 1: if it believes it hung up successfully.
-
- VOID
- ttimoff()
- Turns off all pending timer interrupts.
-
- int
- ttinc(timo) int timo; (function is old, return codes are new)
- Reads one character from the communication device. If timo is
- greater than zero, wait the given number of seconds and then
- time out if no character arrives, otherwise wait forever for a
- character. Returns:
- -3: internal error (e.g. tty modes set wrong)
- -2: communications disconnect
- -1: timeout or other error
- >=0: the character that was read.
- It is HIGHLY RECOMMENDED that ttinc() be internally buffered so
- that calls to it are relatively inexpensive. If it is possible
- to to implement ttinc() as a macro, all the better, for example
- something like:
-
- #define ttinc(t) ( (--txbufn >= 0) ? txbuf[ttbufp++] : txbufr(t) )
-
- (see description of txbufr() below)
-
- int
- ttinl(dest,max,timo,eol,start,turn) int max,timo,turn; CHAR
- *dest, eol, start;
- ttinl() is Kermit's packet reader. Reads a packet from the
- communications device, or up to max characters, whichever occurs
- first. A line is a string of characters starting with the start
- character up to and including the character given in eol or
- until the length is exhausted, or, if turn != 0, until the line
- turnaround character (turn) is read. If turn is 0, ttinl()
- *should* use the packet length field to detect the end, to allow
- for the possibility that the eol character appears unprefixed in
- the packet data. (The turnaround character is for half-duplex
- linemode connections.)
-
- If timo is greater than zero, ttinl() times out if the eol
- character is not encountered within the given number of seconds
- and returns -1.
-
- The characters that were input are copied into "dest" with their
- parity bits stripped if parity is not none. The first character
- copied into dest should be the start character, and the last
- should be the final character of the packet (the last block
- check character). ttinl() should also absorb and discard the eol
- and turn characters, and any other characters that are waiting
- to be read, up until the next start character, so that
- subsequent calls to ttchk() will not succeed simply because
- there are some terminators still sitting in the buffer that
- ttinl() didn't read. This operation, if performed, MUST NOT
- BLOCK (so if it can't be performed in a guaranteed nonblocking
- way, don't do it).
-
- On success, ttinl() returns the number of characters read.
- Optionally, ttinl() can sense the parity of incoming packets. If
- it does this, then it should set the global variable ttprty
- accordingly. ttinl() should be coded to be as efficient as
- possible, since it is at the "inner loop" of packet reception.
- ttinl() returns:
- -1: Timeout or other possibly correctable error.
- -2: Interrupted from keyboard.
- -3: Uncorrectable i/o error -- connection lost, configuration
- problem, etc.
- >=0: on success, the number of characters that were actually
- read and placed in the dest buffer, not counting the trailing
- null.
-
- int
- ttoc(c) char c;
- Outputs the character c to the communication line. If the
- operation fails to complete within two seconds, this function
- returns -1. Otherwise it returns the number of characters
- actually written to the tty (0 or 1). This function should only
- be used for interactive, character-mode operations, like
- terminal connection, script execution, dialer i/o, where the
- overhead of the signals and alarms does not create a bottleneck.
- (THIS DESCRIPTION NEEDS IMPROVEMENT -- If the operation fails
- within a "certain amount of time"... which might be dependent on
- the communication method, speed, etc. In particular,
- flow-control deadlocks must be accounted for and broken out of
- to prevent the program from hanging indefinitely, etc.)
-
- int
- ttol(s,n) int n; char *s;
- Kermit's packet writer. Writes the n characters of the string
- pointed to to by s. NOTE: It is ttol's responsibility to write
- ALL of the characters, not just some of them. Returns:
- -1: on a possibly correctable error (so it can be retried).
- -3: on a fatal error, e.g. connection lost.
- >=0: on success, the actual number of characters written (the
- specific number is not actually used for anything).
-
- int
- ttopen(ttname,lcl,modem,timo) char *ttname; int *lcl, modem,
- timo;
- Opens a tty device, if it is not already open. ttopen must check
- to make sure the SAME device is not already open; if it is,
- ttopen returns successfully without doing anything. If a
- DIFFERENT device is currently open, ttopen() must call ttclos()
- to close it before opening the new one.
-
- Parameters:
-
- ttname:
- character string - device name or network host name.
-
- lcl:
- If called with lcl < 0, sets value of lcl as
- follows:
- 0: the terminal named by ttname is the job's
- controlling terminal.
- 1: the terminal named by ttname is not the job's
- controlling terminal.
- If the device is already open, or if the requested
- device can't be opened, then lcl remains (and is
- returned as) -1.
-
- modem:
- Less than zero: this is the negative of the network
- type, and ttname is a network host name. Network
- types (from [134]ckcnet.h:
-
- NET_TCPB 1 TCP/IP Berkeley (socket) (implemented in [135]ckutio.c)
- NET_TCPA 2 TCP/IP AT&T (streams) (not yet implemented)
- NET_DEC 3 DECnet (not yet implemented)
-
- Zero or greater: ttname is a terminal device name.
- Zero means a direct connection (don't use modem
- signals). Positive means use modem signals depending
- on the current setting of ttcarr (see ttscarr()).
-
- timo:
- > 0: number of seconds to wait for open() to return
- before timing out.
- <=0: no timer, wait forever (e.g. for incoming
- call).
- For real tty devices, ttopen() attempts to gain
- exclusive access to the tty device, for example in
- UNIX by creating a "lockfile" (in other operating
- systems, like VMS, exclusive access probably
- requires no special action).
-
- Side effects:
- Copies its arguments and the tty file descriptor to global
- variables that are available to the other tty-related
- functions, with the lcl value altered as described above.
- Gets all parameters and settings associated with the line
- and puts them in a global area, so that they can be
- restored by ttres(), e.g. when the device is closed.
-
- Returns:
- 0: on success
- -5: if device is in use
- -4: if access to device is denied
- -3: if access to lock mechanism denied
- -2: upon timeout waiting for device to open
- -1: on other error
-
- int
- ttpkt(speed,flow,parity) long speed; int flow, parity;
- Puts the currently open tty device into the appropriate modes
- for transmitting and receiving Kermit packets.
-
- Arguments:
-
- speed:
- if speed > -1, and the device is a true tty device,
- and Kermit is in local mode, ttpkt also sets the
- speed.
-
- flow:
- if in the range 0-3, ttpkt selects the corresponding
- type of flow control. Currently 0 is defined as no
- flow control, 1 is Xon/Xoff, and no other types are
- defined. If (and this is a horrible hack, but it
- goes back many years and will be hard to eradicate)
- flow is 4, then the appropriate tty modes are set
- for modem dialing, a special case in which we talk
- to a modem-controlled line without requiring
- carrier. If flow is 5, then we require carrier.
-
- parity:
- This is simply copied into a global variable so that
- other functions (like ttinl, ttinc, etc) can use it.
-
- Side effects:
- Copies its arguments to global variables, flushes the
- terminal device input buffer.
-
- Returns:
- -1: on error.
- 0: on success.
-
- int
- ttsetflow(int)
- Enables the given type of flow control on the open serial
- communications device immediately. Arguments are the FLO_xxx
- values from ckcdeb.h, except FLO_DIAL, FLO_DIAX, or FLO_AUTO,
- which are not actual flow-control types. Returns 0 on success,
- -1 on failure.
-
- #ifdef TTSPDLIST
- long *
- ttspdlist()
- Returns a pointer to an array of longs, or NULL on failure. On
- success, element 0 of the array contains number, n, indicating
- how many follow. Elements 1-n are serial speeds, expressed in
- bits per second, that are legal on this platform. The user
- interface may use this list to construct a menu, keyword table,
- etc.
-
- #endif /* TTSPDLIST */
-
- int
- ttres()
- Restores the tty device to the modes and settings that were in
- effect at the time it was opened (see ttopen). Returns:
- -1: on error.
- 0: on success.
-
- int
- ttruncmd(string) char * string;
- Runs the given command on the local system, but redirects its
- input and output to the communication (SET LINE, SET PORT, or
- SET HOST) device. Returns:
- 0: on failure.
- 1: on success.
-
- int
- ttscarr(carrier) int carrier;
- Copies its argument to a variable that is global to the other
- tty-related functions, and then returns it. The values for
- carrier are defined in ckcdeb.h: CAR_ON, CAR_OFF, CAR_AUTO.
- ttopen(), ttpkt(), and ttvt() use this variable when deciding
- how to open the tty device and what modes to select. The
- meanings are these:
-
- CAR_OFF: Ignore carrier at all times.
- CAR_ON: Require carrier at all times, except when dialing. This means,
- for example, that ttopen() could hang forever waiting for carrier if it
- is not present.
- CAR_AUTO: If the modem type is zero (i.e. the connection is direct),
- this is the same as CAR_OFF. If the modem type is positive, then heed
- carrier during CONNECT (ttvt mode), but ignore it at other times
- (packet mode, during SET LINE, etc). Compatible with pre-5A versions of
- C-Kermit. This should be the default carrier mode.
-
- Kermit's DIAL command ignores the carrier setting, but ttopen(),
- ttvt(), and ttpkt() all honor the carrier option in effect at
- the time they are called. None of this applies to remote mode
- (the tty device is the job's controlling terminal) or to network
- host connections (modem type is negative).
-
- int
- ttsndb()
- Sends a BREAK signal on the tty device. On a real tty device,
- send a real BREAK lasting approximately 275 milliseconds. If
- this is not possible, simulate a BREAK by (for example) dropping
- down some very low baud rate, like 50, and sending a bunch of
- null characters. On a network connection, do the appropriate
- network protocol for BREAK. Returns:
- -1: on error.
- 0: on success.
-
- int
- ttsndlb()
- Like ttsndb(), but sends a "Long BREAK" (approx 1.5 seconds).
- For network connections, it is identical to ttsndb(). Currently,
- this function is used only if CK_LBRK is defined (as it is for
- UNIX and VMS).
-
- int
- ttsspd(cps) int cps;
- For serial devices only, set the device transmission speed to
- (note carefully) TEN TIMES the argument. The argument is in
- characters per second, but transmission speeds are in bits per
- second. cps are used rather than bps because high speeds like
- 38400 are not expressible in a 16-bit int but longs cannot be
- used because keyword-table values are ints and not longs. If the
- argument is 7, then the bps is 75, not 70. If the argument is
- 888, this is a special code for 75/1200 split-speed operation
- (75 bps out, 1200 bps in). Returns:
- -1: on error, meaning the requested speed is not valid or
- available.
- >=0: on success (don't try to use this value for anything).
-
- int
- ttvt(speed,flow) long speed; int flow;
- Puts the currently open tty device into the appropriate modes
- for terminal emulation. The arguments are interpreted as in
- ttpkt(). Side effects: ttvt() stores its arguments in global
- variables, and sets a flag that it has been called so that
- subsequent calls can be ignored so long as the arguments are the
- same as in the last effective call. Other functions, such as
- ttopen(), ttclose(), ttres(), ttvt(), etc, that change the tty
- device in any way must unset this flag. In UNIX Kermit, this
- flag is called tvtflg.
-
- int
- ttwmdm(mdmsig,timo) int mdmsig, timo;
- Waits up to timo seconds for all of the given modem signals to
- appear. mdmsig is a bit mask, in which a bit is on (1) or off
- (0) according to whether the corresponding signal is to be
- waited for. These symbols are defined in ckcdeb.h:
- BM_CTS (bit 0) means wait for Clear To Send
- BM_DSR (bit 1) means wait for Data Set Ready
- BM_DCD (bit 2) means wait for Carrier Detect
- Returns:
- -3: Not implemented.
- -2: This line does not have modem control.
- -1: Timeout: time limit exceeded before all signals were
- detected.
- 1: Success.
-
- int
- ttxin(n,buf) int n; CHAR *buf;
- Reads x characters from the tty device into the specified buf,
- stripping parity if parity is not none. This call waits forever,
- there is no timeout. This function is designed to be called only
- when you know that at least x characters are waiting to be read
- (as determined, for example, by ttchk()). This function should
- use the same buffer as ttinc().
-
- int
- txbufr(timo) int timo;
- Reads characters into the internal communications input buffer.
- timo is a timeout interval, in seconds. 0 means no timeout, wait
- forever. Called by ttinc() (and possibly ttxin() and ttinl())
- when the communications input buffer is empty. The buffer should
- be called ttxbuf[], its length is defined by the symbol TXBUFL.
- The global variable txbufn is the number of characters available
- to be read from ttxbuf[], and txbufp is the index of the next
- character to be read. Should not be called if txbufn > 0, in
- which case the buffer does not need refilling. This routine
- returns:
- -2: Communications disconnect
- -1: Timeout
- >=0: A character (0 - 255) On success, the first character that
- was read, with the variables txbufn and txbufp set appropriately
- for any remaining characters.
- NOTE: Currently this routine is used internally only by the UNIX
- and VMS versions. The aim is to make it available to all
- versions so there is one single coherent and efficient way of
- reading from the communications device or network.
-
-4.E.2.6. Miscellaneous system-dependent functions
-
- VOID
- ztime(s) char **s;
- Returns a pointer, s, to the current date-and-time string in s.
- This string must be in the fixed-field format associated with
- the C runtime asctime() function, like: "Sun Sep 16 13:23:45
- 1973\n" so that callers of this function can extract the
- different fields. The pointer value is filled in by ztime, and
- the data it points to is not safe, so should be copied to a safe
- place before use. ztime() has no return value. As a side effect,
- this routine can also fill in the following two external
- variables (which must be defined in the system-dependent modules
- for each platform):
- long ztusec: Fraction of seconds of clock time, microseconds.
- long ztmsec: Fraction of seconds of clock time, milliseconds.
- If these variables are not set by zstime(), they remain at their
- initial value of -1L.
-
- int
- gtimer()
- Returns the current value of the elapsed time counter in seconds
- (see rtimer), or 0 on any kind of error.
-
- #ifdef GFTIMER
- CKFLOAT
- gftimer()
- Returns the current value of the elapsed time counter in
- seconds, as a floating point number, capable of representing not
- only whole seconds, but also the fractional part, to the
- millisecond or microsecond level, whatever precision is
- available. Requires a function to get times at subsecond
- precision, as well as floating-point support. That's why it's
- #ifdef'd.
-
- #endif /* GFTIMER */
-
- int
- msleep(m) int m;
- Sleeps (pauses, does nothing) for m milliseconds (a millisecond
- is one thousandth of a second). Returns:
- -1: on failure.
- 0: on success.
-
- VOID
- rtimer()
- Sets the elapsed time counter to zero. If you want to time how
- long an operation takes, call rtimer() when it starts and gtimer
- when it ends. rtimer() has no return value.
-
- #ifdef GFTIMER
- VOID
- rftimer()
- Sets the elapsed time counter to zero. If you want to time how
- long an operation takes, call rftimer() when it starts and
- gftimer when it ends. rftimer() has no return value. Note:
- rftimer() is to be used with gftimer() and rtimer() is to be
- used with gtimer(). See the rftimer() description.
-
- #endif /* GFTIMER */
-
- int
- sysinit()
- Does whatever needs doing upon program start. In particular, if
- the program is running in any kind of privileged mode, turns off
- the privileges (see priv_ini()). Returns:
- -1: on error.
- 0: on success.
-
- int
- syscleanup()
- Does whatever needs doing upon program exit. Returns:
- -1: on error.
- 0: on success.
-
- int
- psuspend()
- Suspends the Kermit process, puts it in the background so it can
- be continued ("foregrounded") later. Returns:
- -1: if this function is not supported.
- 0: on success.
-
- [ [136]Contents ] [ [137]C-Kermit ] [ [138]Kermit Home ]
-
-4.F. Group F: Network Support
-
- As of version 5A, C-Kermit includes support for several networks.
- Originally, this was just worked into the ttopen(), ttclos(), ttinc(),
- ttinl(), and similar routines in [139]ckutio.c. But this made it
- impossible to share this code with non-UNIX versions, like VMS, AOS/VS,
- OS/2, etc. So as of edit 168, network code has been separated out into
- its own module and header file, ckcnet.c and ckcnet.h:
-
- [140]ckcnet.h: Network-related symbol definitions.
- [141]ckcnet.c: Network i/o (TCP/IP, X.25, etc), shared by most
- platforms.
- [142]cklnet.c: Network i/o (TCP/IP, X.25, etc) specific to Stratus
- VOS.
-
- The routines and variables in these modules fall into two categories:
-
- 1. Support for specific network packages like SunLink X.25 and TGV
- MultiNet, and:
- 2. support for specific network virtual terminal protocols like CCITT
- X.3 and TCP/IP Telnet.
-
- Category (1) functions are analogs to the tt*() functions, and have
- names like netopen, netclos, nettinc, etc. Group A-D modules do not
- (and must not) know anything about these functions -- they continue to
- call the old Group E functions (ttopen, ttinc, etc). Category (2)
- functions are protocol specific and have names prefixed by a protocol
- identifier, like tn for telnet x25 for X.25.
-
- ckcnet.h contains prototypes for all these functions, as well as symbol
- definitions for network types, protocols, and network- and protocol-
- specific symbols, as well as #includes for the header files necessary
- for each network and protocol.
-
- The following functions are to be provided for networks that do not use
- normal system i/o (open, read, write, close):
-
- int
- netopen()
- To be called from within ttopen() when a network connection is
- requested. Calling conventions and purpose same as Group E
- ttopen().
-
- int
- netclos()
- To be called from within ttclos() when a network connection is
- being closed. Calling conventions and purpose same as Group E
- ttclos().
-
- int
- nettchk()
- To be called from within ttchk(). Calling conventions and
- purpose same as Group E ttchk().
-
- int
- netflui()
- To be called from within ttflui(). Calling conventions and
- purpose same as Group E ttflui().
-
- int
- netbreak()
- To send a network break (attention) signal. Calling conventions
- and purpose same as Group E ttsndbrk().
-
- int
- netinc()
- To get a character from the network. Calling conventions same as
- Group E ttsndbrk().
-
- int
- nettoc()
- Send a "character" (byte) to the network. Calling conventions
- same as Group E ttoc().
-
- int
- nettol()
- Send a "line" (sequence of bytes) to the network. Calling
- conventions same as Group E ttol().
-
- Conceivably, some systems support network connections simply by letting
- you open a device of a certain name and letting you do i/o to it.
- Others (like the Berkeley sockets TCP/IP library on UNIX) require you
- to open the connection in a special way, but then do normal i/o (read,
- write). In such a case, you would use netopen(), but you would not use
- nettinc, nettoc, etc.
-
- VMS TCP/IP products have their own set of functions for all network
- operations, so in that case the full range of netxxx() functions is
- used.
-
- The technique is to put a test in each corresponding ttxxx() function
- to see if a network connection is active (or is being requested), test
- for which kind of network it is, and if necessary route the call to the
- corresponding netxxx() function. The netxxx() function must also
- contain code to test for the network type, which is available via the
- global variable ttnet.
-
- [ [143]Contents ] [ [144]C-Kermit ] [ [145]Kermit Home ]
-
-4.F.1. Telnet Protocol
-
- (This section needs a great deal of updating...)
-
- As of edit 195, Telnet protocol is split out into its own files, since
- it can be implemented in remote mode, which does not have a network
- connection:
-
- [146]ckctel.h: Telnet protocol symbol definitions.
- [147]ckctel.c: Telnet protocol.
-
- The Telnet protocol is supported by the following variables and
- routines:
-
- int tn_init
- Nonzero if telnet protocol initialized, zero otherwise.
-
- int
- tn_init()
- Initialize the telnet protocol (send initial options).
-
- int
- tn_sopt()
- Send a telnet option.
-
- int
- tn_doop()
- Receive and act on a telnet option from the remote.
-
- int
- tn_sttyp()
- Send terminal type using telnet protocol.
-
-4.F.2. FTP Protocol
-
- (To be filled in...) See the [148]source file
-
-4.F.3. HTTP Protocol
-
- (To be filled in...)
-
-4.F.4. X.25 Networks
-
- These routines were written SunLink X.25 and have since been adapted to
- at least on one other: IBM AIXLink/X.25.
-
- int
- x25diag()
- Reads and prints X.25 diagnostics
-
- int
- x25oobh()
- X.25 out of band signal handler
-
- int
- x25intr()
- Sends X.25 interrupt packet
-
- int
- x25reset()
- Resets X.25 virtual circuit
-
- int
- x25clear()
- Clear X.25 virtual circuit
-
- int
- x25stat()
- X.25 status
-
- int
- setqbit()
- Sets X.25 Q-bit
-
- int
- resetqbit()
- Resets X.25 Q-bit
-
- int
- x25xin()
- Reads n characters from X.25 circuit.
-
- int
- x25inl()
- Read a Kermit packet from X.25 circuit.
-
- [ [149]Contents ] [ [150]C-Kermit ] [ [151]Kermit Home ]
-
-4.F.5. Adding New Network Types
-
- Example: Adding support for IBM X.25 and Hewlett Packard X.25. First,
- add new network type symbols for each one. There are already some
- network types defined for other X.25 packages:
-
- NET_SX25 is the network-type ID for SunLink X.25.
- NET_VX25 is the network-type ID for VOS X.25.
-
- So first you should new symbols for the new network types, giving them
- the next numbers in the sequence, e.g.:
-
-#define NET_HX25 11 /* Hewlett-Packard X.25 */
-#define NET_IX25 12 /* IBM X.25 */
-
- This is in ckcnet.h.
-
- Then we need symbols to say that we are actually compiling in the code
- for these platforms. These would be defined on the cc command line:
-
- -DIBMX25 (for IBM)
- -DHPX25 (for HP)
-
- So we can build C-Kermit versions for AIX and HP-UX both with and
- without X.25 support (since not all AIX and IBM systems have the needed
- libraries, and so an executable that was linked with them might no
- load).
-
- Then in ckcnet.h:
-
-#ifdef IBMX25
-#define ANYX25
-#endif /* IBMX25 */
-
-#ifdef HPX25
-#define ANYX25
-#endif /* HPX25 */
-
- And then use ANYX25 for code that is common to all of them, and IBMX25
- or HPX25 for code specific to IBM or HP.
-
- It might also happen that some code can be shared between two or more
- of these, but not the others. Suppose, for example, that you write code
- that applies to both IBM and HP, but not Sun or VOS X.25. Then you add
- the following definition to ckcnet.h:
-
-#ifndef HPORIBMX25
-#ifdef HPX25
-#define HPORIBMX25
-#else
-#ifdef IBMX25
-#define HPORIBMX25
-#endif /* IBMX25 */
-#endif /* HPX25 */
-#endif /* HPORIBMX25 */
-
- You can NOT use constructions like "#if defined (HPX25 || IBMX25)";
- they are not portable.
-
- [ [152]Contents ] [ [153]C-Kermit ] [ [154]Kermit Home ]
-
-4.G. Group G: Formatted Screen Support
-
- So far, this is used only for the fullscreen local-mode file transfer
- display. In the future, it might be extended to other uses. The
- fullscreen display code is in and around the routine screenc() in
- [155]ckuusx.c.
-
- In the UNIX version, we use the curses library, plus one call from the
- termcap library. In other versions (OS/2, VMS, etc) we insert dummy
- routines that have the same names as curses routines. So far, there are
- two methods for simulating curses routines:
-
- 1. In VMS, we use the Screen Management Library (SMG), and insert
- stubs to convert curses calls into SMG calls.
- 2. In OS/2, we use the MYCURSES code, in which the stub routines
- actually emit the appropriate escape sequences themselves.
-
- Here are the stub routines:
-
- int
- tgetent(char *buf, char *term)
- Arguments are ignored. Returns 1 if the user has a supported
- terminal type, 0 otherwise. Sets a global variable (for example,
- "isvt52" or "isdasher") to indicate the terminal type.
-
- VOID
- move(int row, int col)
- Sends the escape sequence to position the cursor at the
- indicated row and column. The numbers are 0-based, e.g. the home
- position is 0,0.
-
- int
- clear()
- Sends the escape sequence to clear the screen.
-
- int
- clrtoeol()
- Sends the escape sequence to clear from the current cursor
- position to the end of the line.
-
- In the MYCURSES case, code must be added to each of the last three
- routines to emit the appropriate escape sequences for a new terminal
- type.
-
- clearok(curscr), wrefresh()
- In real curses, these two calls are required to refresh the
- screen, for example after it was fractured by a broadcast
- message. These are useful only if the underlying screen
- management service keeps a copy of the entire screen, as curses
- and SMG do. C-Kermit does not do this itself.
-
- [ [156]Contents ] [ [157]C-Kermit ] [ [158]Kermit Home ]
-
-4.H. Group H: Pseudoterminal Support
-
- (To be filled in...) But see: [159]these comments, and the source files
- [160]ckupty.h and [161]ckupty.c.
-
-4.I. Group I: Security
-
- (To be filled in...) Meanwhile, see [162]security.html.
-
- [ [163]Contents ] [ [164]C-Kermit ] [ [165]Kermit Home ]
-
-APPENDIX I. FILE PERMISSIONS
-
-I.1. Format of System-Dependent File Permissions in A-Packets
-
- The format of this field (the "," attribute) is interpreted according
- to the System ID ("." Attribute).
-
- For UNIX (System ID = U1), it's the familiar 3-digit octal number, the
- low-order 9 bits of the filemode: Owner, Group, World, e.g. 660 =
- read/write access for owner and group, none for world, recorded as a
- 3-digit octal string. High-order UNIX permission bits are not
- transmitted.
-
- For VMS (System ID = D7), it's a 4-digit hex string, representing the
- 16-bit file protection WGOS fields (World,Group,Owner,System), in that
- order (which is the reverse of how they're shown in a directory
- listing); in each field, Bit 0 = Read, 1 = Write, 2 = Execute, 3 =
- Delete. A bit value of 0 means permission is granted, 1 means
- permission is denied. Sample:
-
- r-01-00-^A/!FWERMIT.EXE'"
- s-01-00-^AE!Y/amd/watsun/w/fdc/new/wermit.exe.DV
- r-02-01-^A]"A."D7""B8#119980101 18:14:05!#8531&872960,$A20B-!7(#512@ #.Y
- s-02-01-^A%"Y.5!
-
- A VMS directory listing shows the file's protection as (E,RWED,RED,RE)
- which really means (S=E,O=RWED,G=RED,W=RE), which is reverse order from
- the internal storage, so (RE,RED,RWED,E). Now translate each letter to
- its corresponding bit:
-
- RE=0101, RED=1101, RWED=1111, E=0010
-
- Now reverse the bits:
-
- RE=1010, RED=0010, RWED=0000, E=1101
-
- This gives the 16-bit quantity:
-
- 1010001000001101
-
- This is the internal representation of the VMS file permission; in hex:
-
- A20B
-
- as shown in the sample packet above.
-
- The VMS format probably would also apply to RSX or any other FILES-11
- system.
-
-I.2. Handling of Generic Protection
-
- To be used when the two systems are different (and/or do not recognize
- or understand each other's local protection codes).
-
- First of all, the book is wrong. This should not be the World
- protection, but the Owner protection. The other fields should be set
- according to system defaults (e.g. UNIX umask, VMS default protection,
- etc), except that no non-Owner field should give more permissions than
- the Owner field.
-
- [ [166]Top ] [ [167]Contents ] [ [168]C-Kermit Home ] [ [169]Kermit
- Home ]
- __________________________________________________________________
-
-
- C-Kermit Program Logic Manual / [170]The Kermit Project /
- [171]kermit@columbia.edu / 30 June 2011
-
-References
-
- 1. http://www.columbia.edu/
- 2. mailto:kermit@columbia.edu
- 3. http://www.columbia.edu/kermit/index.html
- 4. http://www.columbia.edu/kermit/k95.html
- 5. http://www.columbia.edu/kermit/ckermit.html
- 6. http://www.columbia.edu/kermit/ckscripts.html
- 7. http://www.columbia.edu/kermit/current.html
- 8. http://www.columbia.edu/kermit/whatsnew.html
- 9. http://www.columbia.edu/kermit/ckfaq.html
- 10. http://www.columbia.edu/kermit/support.html
- 11. http://www.columbia.edu/kermit/
- 12. http://www.columbia.edu/kermit/ckcplm.html
- 13. http://www.columbia.edu/kermit/ckcplm.html#x1
- 14. http://www.columbia.edu/kermit/ckcplm.html#x2
- 15. http://www.columbia.edu/kermit/ckcplm.html#x3
- 16. http://www.columbia.edu/kermit/ckcplm.html#x4
- 17. http://www.columbia.edu/kermit/ckcplm.html#x4.A
- 18. http://www.columbia.edu/kermit/ckcplm.html#x4.B
- 19. http://www.columbia.edu/kermit/ckcplm.html#x4.C
- 20. http://www.columbia.edu/kermit/ckcplm.html#x4.D
- 21. http://www.columbia.edu/kermit/ckcplm.html#x4.E
- 22. http://www.columbia.edu/kermit/ckcplm.html#x4.F
- 23. http://www.columbia.edu/kermit/ckcplm.html#x4.G
- 24. http://www.columbia.edu/kermit/ckcplm.html#x4.H
- 25. http://www.columbia.edu/kermit/ckcplm.html#x4.I
- 26. http://www.columbia.edu/kermit/ckcplm.html#xa1
- 27. http://www.amazon.com/gp/product/0932376886?ie=UTF8&tag=aleidmoreldom-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0932376886
- 28. http://www.columbia.edu/kermit/ckcplm.html#contents
- 29. http://www.columbia.edu/kermit/vax_11-750.jpg
- 30. http://www.columbia.edu/cu/computinghistory/hermit.html
- 31. http://www.columbia.edu/kermit/cudocs/ilosetup.html
- 32. ftp://kermit.columbia.edu/kermit/f/ckc04e.txt
- 33. ftp://kermit.columbia.edu/kermit/f/ckc04f.txt
- 34. ftp://kermit.columbia.edu/kermit/f/ckc168.txt
- 35. ftp://kermit.columbia.edu/kermit/f/ckc178.txt
- 36. ftp://kermit.columbia.edu/kermit/f/ckc188.txt
- 37. ftp://kermit.columbia.edu/kermit/f/ckc189.txt
- 38. ftp://kermit.columbia.edu/kermit/f/ckc192.txt
- 39. ftp://kermit.columbia.edu/kermit/f/ckc197.txt
- 40. ftp://kermit.columbia.edu/kermit/f/ckc200.txt
- 41. ftp://kermit.columbia.edu/kermit/f/ckc211.txt
- 42. ftp://kermit.columbia.edu/kermit/f/ckc300.txt
- 43. http://www.columbia.edu/kermit/ckcplm.html#contents
- 44. http://www.columbia.edu/kermit/ckermit.html
- 45. http://www.columbia.edu/kermit/index.html
- 46. ftp://kermit.columbia.edu/kermit/c-kermit/ckcpro.w
- 47. http://www.columbia.edu/kermit/ckcplm.html#contents
- 48. http://www.columbia.edu/kermit/ckermit.html
- 49. http://www.columbia.edu/kermit/index.html
- 50. http://www.columbia.edu/kermit/ckcplm.html#x3.2
- 51. http://www.columbia.edu/kermit/ckcplm.html#contents
- 52. http://www.columbia.edu/kermit/ckermit.html
- 53. http://www.columbia.edu/kermit/index.html
- 54. http://www.columbia.edu/kermit/ckcplm.html#x4.A
- 55. http://www.columbia.edu/kermit/ckcplm.html#contents
- 56. http://www.columbia.edu/kermit/ckermit.html
- 57. http://www.columbia.edu/kermit/index.html
- 58. http://www.columbia.edu/kermit/ckcplm.html#contents
- 59. http://www.columbia.edu/kermit/ckermit.html
- 60. http://www.columbia.edu/kermit/index.html
- 61. http://www.columbia.edu/kermit/ckcplm.html#contents
- 62. http://www.columbia.edu/kermit/ckermit.html
- 63. http://www.columbia.edu/kermit/index.html
- 64. ftp://kermit.columbia.edu/kermit/c-kermit/ckclib.h
- 65. ftp://kermit.columbia.edu/kermit/c-kermit/ckclib.c
- 66. http://www.columbia.edu/kermit/ckcplm.html#x3.1
- 67. http://www.columbia.edu/kermit/ckcplm.html#contents
- 68. http://www.columbia.edu/kermit/ckermit.html
- 69. http://www.columbia.edu/kermit/index.html
- 70. ftp://kermit.columbia.edu/kermit/c-kermit/ckcsym.h
- 71. ftp://kermit.columbia.edu/kermit/c-kermit/ckcasc.h
- 72. ftp://kermit.columbia.edu/kermit/c-kermit/ckcsig.h
- 73. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h
- 74. ftp://kermit.columbia.edu/kermit/c-kermit/ckcker.h
- 75. ftp://kermit.columbia.edu/kermit/c-kermit/ckcxla.h
- 76. ftp://kermit.columbia.edu/kermit/c-kermit/ckcmai.c
- 77. ftp://kermit.columbia.edu/kermit/c-kermit/ckcpro.w
- 78. ftp://kermit.columbia.edu/kermit/c-kermit/ckcfns.c
- 79. ftp://kermit.columbia.edu/kermit/c-kermit/ckcfn2.c
- 80. ftp://kermit.columbia.edu/kermit/c-kermit/ckcfn3.c
- 81. http://www.columbia.edu/kermit/ckcplm.html#x4.B
- 82. http://www.columbia.edu/kermit/ckcplm.html#x4.E
- 83. http://www.columbia.edu/kermit/ckcplm.html#x4.D
- 84. http://www.columbia.edu/kermit/ckcplm.html#contents
- 85. http://www.columbia.edu/kermit/ckermit.html
- 86. http://www.columbia.edu/kermit/index.html
- 87. http://www.columbia.edu/kermit/ckcplm.html#x4.B
- 88. ftp://kermit.columbia.edu/kermit/c-kermit/ckuxla.c
- 89. ftp://kermit.columbia.edu/kermit/c-kermit/ckuxla.h
- 90. ftp://kermit.columbia.edu/kermit/c-kermit/ckcxla.h
- 91. ftp://kermit.columbia.edu/kermit/c-kermit/ckuxla.h
- 92. ftp://kermit.columbia.edu/kermit/c-kermit/ckmxla.h
- 93. ftp://kermit.columbia.edu/kermit/c-kermit/ck?xla
- 94. ftp://kermit.columbia.edu/kermit/c-kermit/ckcuni.h
- 95. ftp://kermit.columbia.edu/kermit/c-kermit/ckcuni.c
- 96. http://www.columbia.edu/kermit/ckcplm.html#contents
- 97. http://www.columbia.edu/kermit/ckermit.html
- 98. http://www.columbia.edu/kermit/index.html
- 99. http://www.columbia.edu/kermit/ckcplm.html#x4.B
- 100. ftp://kermit.columbia.edu/kermit/c-kermit/ckucmd.h
- 101. ftp://kermit.columbia.edu/kermit/c-kermit/ckucmd.c
- 102. http://www.columbia.edu/kermit/ckcplm.html#x4.E
- 103. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusr.h
- 104. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusr.c
- 105. ftp://kermit.columbia.edu/kermit/c-kermit/ckuus2.c
- 106. ftp://kermit.columbia.edu/kermit/c-kermit/ckuus3.c
- 107. ftp://kermit.columbia.edu/kermit/c-kermit/ckuus4.c
- 108. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusy.c
- 109. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusx.c
- 110. ftp://kermit.columbia.edu/kermit/c-kermit/ckuver.h
- 111. ftp://kermit.columbia.edu/kermit/c-kermit/ckuscr.c
- 112. ftp://kermit.columbia.edu/kermit/c-kermit/ckudia.c
- 113. ftp://kermit.columbia.edu/kermit/c-kermit/ckucon.c
- 114. ftp://kermit.columbia.edu/kermit/c-kermit/ckucns.c
- 115. http://www.columbia.edu/kermit/ckcplm.html#x4.E
- 116. ftp://kermit.columbia.edu/kermit/c-kermit/ckcmai.c
- 117. http://www.columbia.edu/kermit/ckcplm.html#contents
- 118. http://www.columbia.edu/kermit/ckermit.html
- 119. http://www.columbia.edu/kermit/index.html
- 120. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 121. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 122. ftp://kermit.columbia.edu/kermit/c-kermit/ckusig.c
- 123. ftp://kermit.columbia.edu/kermit/c-kermit/ckvfio.c
- 124. ftp://kermit.columbia.edu/kermit/c-kermit/ckusig.c
- 125. ftp://kermit.columbia.edu/kermit/c-kermit/ckcmai.c
- 126. http://www.columbia.edu/kermit/ckcplm.html#contents
- 127. http://www.columbia.edu/kermit/ckermit.html
- 128. http://www.columbia.edu/kermit/index.html
- 129. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 130. ftp://kermit.columbia.edu/kermit/c-kermit/ckvtio.c
- 131. http://www.columbia.edu/kermit/ckcplm.html#x2
- 132. http://www.columbia.edu/kermit/ckcplm.html#xa1
- 133. http://www.columbia.edu/kermit/ckuins.html
- 134. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.h
- 135. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 136. http://www.columbia.edu/kermit/ckcplm.html#contents
- 137. http://www.columbia.edu/kermit/ckermit.html
- 138. http://www.columbia.edu/kermit/index.html
- 139. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 140. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.h
- 141. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.c
- 142. ftp://kermit.columbia.edu/kermit/c-kermit/cklnet.c
- 143. http://www.columbia.edu/kermit/ckcplm.html#contents
- 144. http://www.columbia.edu/kermit/ckermit.html
- 145. http://www.columbia.edu/kermit/index.html
- 146. ftp://kermit.columbia.edu/kermit/c-kermit/ckctel.h
- 147. ftp://kermit.columbia.edu/kermit/c-kermit/ckctel.c
- 148. ftp://kermit.columbia.edu/kermit/c-kermit/ckcftp.c
- 149. http://www.columbia.edu/kermit/ckcplm.html#contents
- 150. http://www.columbia.edu/kermit/ckermit.html
- 151. http://www.columbia.edu/kermit/index.html
- 152. http://www.columbia.edu/kermit/ckcplm.html#contents
- 153. http://www.columbia.edu/kermit/ckermit.html
- 154. http://www.columbia.edu/kermit/index.html
- 155. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusx.c
- 156. http://www.columbia.edu/kermit/ckcplm.html#contents
- 157. http://www.columbia.edu/kermit/ckermit.html
- 158. http://www.columbia.edu/kermit/index.html
- 159. http://www.columbia.edu/kermit/ckermit90.html#LooseEnd
- 160. ftp://kermit.columbia.edu/kermit/f/ckupty.h
- 161. ftp://kermit.columbia.edu/kermit/f/ckupty.c
- 162. http://www.columbia.edu/kermit/security.html
- 163. http://www.columbia.edu/kermit/ckcplm.html#contents
- 164. http://www.columbia.edu/kermit/ckermit.html
- 165. http://www.columbia.edu/kermit/index.html
- 166. http://www.columbia.edu/kermit/ckcplm.html#top
- 167. http://www.columbia.edu/kermit/ckcplm.html#contents
- 168. http://www.columbia.edu/kermit/ckermit.html
- 169. http://www.columbia.edu/kermit/index.html
- 170. http://www.columbia.edu/kermit/index.html
- 171. mailto:kermit@columbia.edu
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcpro.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckcpro.c
deleted file mode 100644
index 3c51b6b..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcpro.c
+++ /dev/null
@@ -1,3814 +0,0 @@
-
-/* WARNING -- This C source program generated by Wart preprocessor. */
-/* Do not edit this file; edit the Wart-format source file instead, */
-/* and then run it through Wart to produce a new C source file. */
-
-/* Wart Version Info: */
-char *wartv = "Wart Version 2.14, 10 Nov 1999";
-
-char *protv = /* -*-C-*- */
-"C-Kermit Protocol Module 8.0.160, 12 Aug 2007";
-
-int kactive = 0; /* Kermit protocol is active */
-
-#define PKTZEROHACK
-
-/* C K C P R O -- C-Kermit Protocol Module, in Wart preprocessor notation. */
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2007,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#ifndef NOXFER
-#include "ckcsym.h"
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#ifdef OS2
-#ifndef NT
-#define INCL_NOPM
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#endif /* NT */
-#include "ckocon.h"
-#endif /* OS2 */
-
-/*
- Note -- This file may also be preprocessed by the UNIX Lex program, but
- you must indent the above #include statements before using Lex, and then
- restore them to the left margin in the resulting C program before compilation.
- Also, the invocation of the "wart()" function below must be replaced by an
- invocation of the "yylex()" function. It might also be necessary to remove
- comments in the (%)(%)...(%)(%) section.
-*/
-
-/* State definitions for Wart (or Lex) */
-#define ipkt 1
-#define rfile 2
-#define rattr 3
-#define rdpkt 4
-#define ssinit 5
-#define ssfile 6
-#define ssattr 7
-#define ssdata 8
-#define sseof 9
-#define sseot 10
-#define serve 11
-#define generic 12
-#define get 13
-#define rgen 14
-#define ssopkt 15
-#define ropkt 16
-
-_PROTOTYP(static VOID xxproto,(void));
-_PROTOTYP(static VOID wheremsg,(void));
-_PROTOTYP(int wart,(void));
-_PROTOTYP(static int sgetinit,(int,int));
-_PROTOTYP(int sndspace,(int));
-
-/* External C-Kermit variable declarations */
- extern char *versio, *srvtxt, *cmarg, *cmarg2, **cmlist, *rf_err;
- extern char * rfspec, * sfspec, * srfspec, * rrfspec;
- extern char * prfspec, * psfspec, * psrfspec, * prrfspec;
- extern char *cdmsgfile[];
- extern char * snd_move, * snd_rename, * srimsg;
- extern char filnam[], ofilnam[], fspec[], ttname[], ofn1[];
- extern CHAR sstate, *srvptr, *data;
- extern int timint, rtimo, nfils, hcflg, xflg, flow, mdmtyp, network;
- extern int oopts, omode, oname, opath, nopush, isguest, xcmdsrc, rcdactive;
- extern int rejection, moving, fncact, bye_active, urserver, fatalio;
- extern int protocol, prefixing, filcnt, carrier, fnspath, interrupted;
- extern int recursive, inserver, nzxopts, idletmo, srvidl, xfrint;
- extern struct ck_p ptab[];
- extern int remfile, rempipe, xferstat, filestatus, wearealike, fackpath;
- extern int patterns, filepeek, gnferror;
- extern char * remdest;
-
-#ifdef PKTZEROHACK
-#define PKTZEROLEN 32
-static char ipktack[PKTZEROLEN];
-static int ipktlen = 0;
-#endif /* PKTZEROHACK */
-
-static int s_timint = -1; /* For saving timeout value */
-static int myjob = 0;
-static int havefs = 0;
-#ifdef CK_LOGIN
-static int logtries = 0;
-#endif /* CK_LOGIN */
-
-static int cancel = 0;
-int fackbug = 0;
-
-#ifdef STREAMING
-extern int streaming, streamok;
-
-static VOID
-streamon() {
- if (streamok) {
- debug(F100,"streamon","",0);
- streaming = 1;
- timint = 0; /* No timeouts while streaming. */
- }
-}
-
-#ifdef COMMENT /* (not used) */
-static VOID
-streamoff() {
- if (streaming) {
- debug(F100,"streamoff","",0);
- streaming = 0;
- timint = s_timint; /* Restore timeout */
- }
-}
-#endif /* COMMENT */
-#else /* STREAMING */
-#define streamon()
-#define streamoff()
-#endif /* STREAMING */
-
-#ifndef NOSPL
-_PROTOTYP( int addmac, (char *, char *) );
-_PROTOTYP( int zzstring, (char *, char **, int *) );
-#endif /* NOSPL */
-#ifndef NOICP
-_PROTOTYP( int cmdsrc, (void) );
-#endif /* NOICP */
-
-#ifndef NOSERVER
- extern char * x_user, * x_passwd, * x_acct;
- extern int x_login, x_logged;
-#endif /* NOSERVER */
-
-#include "ckcnet.h"
-
-#ifdef TNCODE
- extern int ttnproto; /* Network protocol */
-#endif /* TNCODE */
-
-#ifdef CK_SPEED
- extern short ctlp[]; /* Control-character prefix table */
-#endif /* CK_SPEED */
-
-#ifdef TNCODE
- extern int tn_b_nlm, tn_b_xfer, tn_nlm;
-#ifdef CK_ENCRYPTION
- extern int tn_no_encrypt_xfer;
-#endif /* CK_ENCRYPTION */
-#endif /* TNCODE */
-
-#ifdef TCPSOCKET
-#ifndef NOLISTEN
- extern int tcpsrfd;
-#endif /* NOLISTEN */
-#endif /* TCPSOCKET */
-
- extern int cxseen, czseen, server, srvdis, local, displa, bctu, bctr, bctl;
- extern int quiet, tsecs, parity, backgrd, nakstate, atcapu, wslotn, winlo;
- extern int wslots, success, xitsta, rprintf, discard, cdtimo, keep, fdispla;
- extern int timef, stdinf, rscapu, sendmode, epktflg, epktrcvd, epktsent;
- extern int binary, fncnv;
- extern long speed, ffc, crc16, calibrate, dest;
-#ifdef COMMENT
- extern char *TYPCMD, *DIRCMD, *DIRCM2;
-#endif /* COMMENT */
-#ifndef OS2
- extern char *SPACMD, *SPACM2, *WHOCMD;
-#endif /* OS2 */
- extern CHAR *rdatap;
- extern struct zattr iattr;
-
-#ifdef VMS
- extern int batch;
-#endif /* VMS */
-
-#ifdef GFTIMER
- extern CKFLOAT fptsecs;
-#endif /* GFTIMER */
-
- extern CHAR *srvcmd;
- extern CHAR *epktmsg;
-
-#ifdef CK_TMPDIR
-extern int f_tmpdir; /* Directory changed temporarily */
-extern char savdir[]; /* For saving current directory */
-extern char * dldir;
-#endif /* CK_TMPDIR */
-
- extern int query; /* Query-active flag */
-#ifndef NOSPL
- extern int cmdlvl;
- char querybuf[QBUFL+1] = { NUL, NUL }; /* QUERY response buffer */
- char *qbufp = querybuf; /* Pointer to it */
- int qbufn = 0; /* Length of data in it */
-#else
- extern int tlevel;
-#endif /* NOSPL */
-
-#ifndef NOICP
- extern int escape;
-#endif /* NOICP */
-/*
- If the following flag is nonzero when the protocol module is entered,
- then server mode persists for exactly one transaction, rather than
- looping until BYE or FINISH is received.
-*/
-extern int justone;
-
-static int r_save = -1;
-static int p_save = -1;
-
-/* Function to let remote-mode user know where their file(s) went */
-
-int whereflg = 1; /* Unset with SET XFER REPORT */
-
-static VOID
-wheremsg() {
- extern int quiet, filrej;
- int n;
- n = filcnt - filrej;
- debug(F101,"wheremsg n","",n);
-
- debug(F110,"wheremsg prfspec",prfspec,0);
- debug(F110,"wheremsg rfspec",rfspec,0);
- debug(F110,"wheremsg psfspec",psfspec,0);
- debug(F110,"wheremsg sfspec",sfspec,0);
-
- debug(F110,"wheremsg prrfspec",prrfspec,0);
- debug(F110,"wheremsg rrfspec",rrfspec,0);
- debug(F110,"wheremsg psrfspec",psrfspec,0);
- debug(F110,"wheremsg srfspec",srfspec,0);
-
- if (!quiet && !local) {
- if (n == 1) {
- switch (myjob) {
- case 's':
- if (sfspec) {
- printf(" SENT: [%s]",sfspec);
- if (srfspec)
- printf(" To: [%s]",srfspec);
- printf(" (%s)\r\n", success ? "OK" : "FAILED");
- }
- break;
- case 'r':
- case 'v':
- if (rrfspec) {
- printf(" RCVD: [%s]",rrfspec);
- if (rfspec)
- printf(" To: [%s]",rfspec);
- printf(" (%s)\r\n", success ? "OK" : "FAILED");
- }
- }
- } else if (n > 1) {
- switch (myjob) {
- case 's':
- if (sfspec) {
- printf(" SENT: (%d files)",n);
- if (srfspec)
- printf(" Last: [%s]",srfspec);
- printf(" (%s)\r\n", success ? "OK" : "FAILED");
- }
- break;
- case 'r':
- case 'v':
- if (rrfspec) {
- printf(" RCVD: (%d files)",n);
- if (rfspec)
- printf(" Last: [%s]",rfspec);
- printf(" (%s)\r\n", success ? "OK" : "FAILED");
- }
- }
- } else if (n == 0) {
- if (myjob == 's')
- printf(" SENT: (0 files) \r\n");
- else if (myjob == 'r' || myjob == 'v')
- printf(" RCVD: (0 files) \r\n");
- }
- }
-}
-
-static VOID
-rdebug() {
- if (server)
- debug(F111,"RESUME","server=1",justone);
- else
- debug(F111,"RESUME","server=0",justone);
-}
-
-/* Flags for the ENABLE and DISABLE commands */
-extern int
- en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
- en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
- en_mkd, en_rmd;
-#ifndef NOSPL
-extern int en_asg, en_que;
-#endif /* NOSPL */
-extern int what, lastxfer;
-
-/* Global variables declared here */
-
- int whatru = 0; /* What are you. */
- int whatru2 = 0; /* What are you, cont'd. */
-
-/* Local variables */
-
- static char vstate = 0; /* Saved State */
- static char vcmd = 0; /* Saved Command */
- static int reget = 0; /* Flag for executing REGET */
- static int retrieve = 0; /* Flag for executing RETRIEVE */
- static int opkt = 0; /* Send Extended GET packet */
-
- static int x; /* General-purpose integer */
- static char *s; /* General-purpose string pointer */
-
-/* Macros - Note, BEGIN is predefined by Wart (and Lex) as "state = ", */
-/* BEGIN is NOT a GOTO! */
-#define TINIT if (tinit(1) < 0) return(-9)
-#define SERVE { TINIT; resetc(); nakstate=1; what=W_NOTHING; cmarg2=""; \
-sendmode=SM_SEND; havefs=0; recursive=r_save; fnspath=p_save; BEGIN serve; }
-#define RESUME { rdebug(); if (!server) { wheremsg(); return(0); } else \
-if (justone) { justone=0; wheremsg(); return(0); } else { SERVE; } }
-
-#ifdef GFTIMER
-#define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); \
- fptsecs=gftimer(); quiet=x; return(success)
-#else
-#define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); quiet=x; \
- return(success)
-#endif /* GFTIMER */
-
-/*
- By late 1999, the big switch() statement generated from the following state
- table began choking even gcc, so here we extract the code from the larger
- states into static routines to reduce the size of the cases and the
- switch() overall. The routines follow the state table; the prototypes are
- here. Each of these routines simply contains the text from the
- corresponding case, but with return(-1) added in appropriate places; see
- instructions after the state table switcher.
-*/
-static int rc; /* Return code for these routines */
-static int rcv_s_pkt(); /* Received an S packet */
-static int rcv_firstdata(); /* Received first Data packet */
-static int rcv_shortreply(); /* Short reply to a REMOTE command */
-static int srv_query(); /* Server answers an query */
-static int srv_copy(); /* Server executes REMOTE COPY */
-static int srv_rename(); /* Server executes REMOTE RENAME */
-static int srv_login(); /* Server executes REMOTE LOGIN */
-static int srv_timeout(); /* Server times out */
-
-
-#define BEGIN state =
-
-int state = 0;
-
-int
-wart()
-{
- int c,actno;
- extern char tbl[];
- while (1) {
- c = input() - 32;
- debug(F000,"PROTO input",ckitoa(state),c+32);
- if (c < 0 || c > 95) c = 0;
- if ((actno = tbl[c + state*96]) != -1)
- switch(actno) {
-case 1:
- { TINIT; /* Send file(s) */
- if (sinit() > 0) BEGIN ssinit;
- else RESUME; }
- break;
-case 2:
- { TINIT; nakstate = 1; BEGIN get; }
- break;
-case 3:
- { /* Client sends a GET command */
- TINIT;
- vstate = get;
- reget = 0;
- retrieve = 0;
- opkt = 0;
- vcmd = 0;
-#ifdef PKTZEROHACK
- ipktack[0] = NUL;
-#endif /* PKTZEROHACK */
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
- break;
-case 4:
- { /* Client sends a RETRIEVE command */
- TINIT;
- vstate = get;
- reget = 0;
- retrieve = 1;
- opkt = 0;
- vcmd = 0;
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
- break;
-case 5:
- { /* Client sends a REGET command */
- TINIT;
- vstate = get;
- reget = 1;
- retrieve = 0;
- opkt = 0;
- vcmd = 0;
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
- break;
-case 6:
- { /* Client sends Extended GET Packet */
- TINIT;
- vstate = get;
- reget = oopts & GOPT_RES;
- retrieve = oopts & GOPT_DEL;
- opkt = 1;
- vcmd = 0;
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
- break;
-case 7:
- { /* Client sends a Host command */
- TINIT;
- vstate = rgen;
- vcmd = 'C';
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
- break;
-case 8:
- { TINIT; /* Client sends a Kermit command */
- vstate = rgen;
- vcmd = 'K';
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
- break;
-case 9:
- { /* Client sends a REMOTE command */
- TINIT;
- vstate = rgen;
- vcmd = 'G';
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
- break;
-case 10:
- { /* Enter server mode */
- int x;
- x = justone;
- if (!ENABLED(en_del)) { /* If DELETE is disabled */
- if (fncact == XYFX_B || /* undo any file collision action */
- fncact == XYFX_U || /* that could result in deletion or */
- fncact == XYFX_A || /* modification of existing files. */
- fncact == XYFX_X) {
-#ifndef NOICP
- extern int g_fncact;
- g_fncact = fncact; /* Save current setting */
-#endif /* NOICP */
- fncact = XYFX_R; /* Change to RENAME */
- debug(F101,"server DELETE disabled so fncact RENAME","",fncact);
- }
- }
- SERVE; /* tinit() clears justone... */
- justone = x;
-#ifdef IKSDB
- if (ikdbopen) slotstate(what, "SERVER", "", "");
-#endif /* IKSDB */
-}
- break;
-case 11:
- {
- int b1 = 0, b2 = 0;
- if (!data) TINIT; /* "ABEND" -- Tell other side. */
-#ifndef pdp11
- if (epktflg) { /* If because of E-PACKET command */
- b1 = bctl; b2 = bctu; /* Save block check type */
- bctl = bctu = 1; /* set it to 1 */
- }
-#endif /* pdp11 */
- errpkt((CHAR *)"User cancelled"); /* Send the packet */
-#ifndef pdp11
- if (epktflg) { /* Restore the block check */
- epktflg = 0;
- bctl = b1; bctu = b2;
- }
-#endif /* pdp11 */
- success = 0;
- return(0); /* Return from protocol. */
-}
- break;
-case 12:
- { /* Receive Send-Init packet. */
- rc = rcv_s_pkt();
- cancel = 0; /* Reset cancellation counter */
- debug(F101,"rcv_s_pkt","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
- break;
-case 13:
- { /* Get ack for I-packet */
- int x = 0;
-#ifdef PKTZEROHACK
- ckstrncpy(ipktack,(char *)rdatap,PKTZEROLEN); /* Save a copy of the ACK */
- ipktlen = strlen(ipktack);
-#endif /* PKTZEROHACK */
- spar(rdatap); /* Set parameters */
- cancel = 0;
- winlo = 0; /* Set window-low back to zero */
- debug(F101,"<ipkt>Y winlo","",winlo);
- urserver = 1; /* So I know I'm talking to a server */
- if (vcmd) { /* If sending a generic command */
- if (tinit(0) < 0) return(-9); /* Initialize many things */
- x = scmd(vcmd,(CHAR *)cmarg); /* Do that */
- if (x >= 0) x = 0; /* (because of O-Packet) */
- debug(F101,"proto G packet scmd","",x);
- vcmd = 0; /* and then un-remember it. */
- } else if (vstate == get) {
- debug(F101,"REGET sstate","",sstate);
- x = srinit(reget, retrieve, opkt); /* GET or REGET, etc */
- }
- if (x < 0) { /* If command was too long */
- if (!srimsg)
- srimsg = "Error sending string";
- errpkt((CHAR *)srimsg); /* cancel both sides. */
- success = 0;
- RESUME;
- } else if (x > 0) { /* Need to send more O-Packets */
- BEGIN ssopkt;
- } else {
- rtimer(); /* Reset the elapsed seconds timer. */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- winlo = 0; /* Window back to 0, again. */
- debug(F101,"<ipkt>Y vstate","",vstate);
- nakstate = 1; /* Can send NAKs from here. */
- BEGIN vstate; /* Switch to desired state */
- }
-}
- break;
-case 14:
- { /* Got ACK to O-Packet */
- debug(F100,"CPCPRO <ssopkt>Y","",0);
- x = sopkt();
- debug(F101,"CPCPRO <ssopkt>Y x","",x);
- if (x < 0) { /* If error */
- errpkt((CHAR *)srimsg); /* cancel both sides. */
- success = 0;
- RESUME;
- } else if (x == 0) { /* This was the last O-Packet */
- rtimer(); /* Reset the elapsed seconds timer. */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- winlo = 0; /* Window back to 0, again. */
- debug(F101,"<ssopkt>Y winlo","",winlo);
- nakstate = 1; /* Can send NAKs from here. */
- BEGIN vstate; /* Switch to desired state */
- }
- debug(F101,"CPCPRO <ssopkt>Y not changing state","",x);
-}
- break;
-case 15:
- { /* Ignore Error reply to I packet */
- int x = 0;
- winlo = 0; /* Set window-low back to zero */
- debug(F101,"<ipkt>E winlo","",winlo);
- if (vcmd) { /* In case other Kermit doesn't */
- if (tinit(0) < 0) return(-9);
- x = scmd(vcmd,(CHAR *)cmarg); /* understand I-packets. */
- if (x >= 0) x = 0; /* (because of O-Packet) */
- vcmd = 0; /* Otherwise act as above... */
- } else if (vstate == get) x = srinit(reget, retrieve, opkt);
- if (x < 0) { /* If command was too long */
- errpkt((CHAR *)srimsg); /* cancel both sides. */
- success = 0;
- RESUME;
- } else if (x > 0) { /* Need to send more O-Packets */
- BEGIN ssopkt;
- } else {
- freerpkt(winlo); /* Discard the Error packet. */
- debug(F101,"<ipkt>E winlo","",winlo);
- winlo = 0; /* Back to packet 0 again. */
- nakstate = 1; /* Can send NAKs from here. */
- BEGIN vstate;
- }
-}
- break;
-case 16:
- { /* Resend of previous I-pkt ACK, same seq number */
- freerpkt(0); /* Free the ACK's receive buffer */
- resend(0); /* Send the GET packet again. */
-}
- break;
-case 17:
- { /* Get I-packet */
-#ifndef NOSERVER
- spar(rdatap); /* Set parameters from it */
- ack1(rpar()); /* Respond with our own parameters */
-#ifdef COMMENT
- pktinit(); /* Reinitialize packet numbers */
-#else
-#ifdef COMMENT
- /* This can't be right - it undoes the stuff we just negotiated */
- x = justone;
- tinit(1); /* Reinitialize EVERYTHING */
- justone = x; /* But this... */
-#else
- tinit(0); /* Initialize most things */
-#endif /* COMMENT */
-#endif /* COMMENT */
-#endif /* NOSERVER */
- cancel = 0; /* Reset cancellation counter */
-}
- break;
-case 18:
- { /* GET */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
- break;
-case 19:
- { /* GET /DELETE (RETRIEVE) */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- RESUME;
- } else if (!ENABLED(en_del)) {
- errpkt((CHAR *)"Deleting files is disabled");
- RESUME;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
- moving = 1;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET /DELETE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
- break;
-case 20:
- { /* GET /RECURSIVE */
-#ifndef NOSERVER
- recursive = 1; /* Set these before sgetinit() */
- if (fnspath == PATH_OFF)
- fnspath = PATH_REL; /* Don't worry, they will be */
- if (x_login && !x_logged) { /* reset next time through. */
- errpkt((CHAR *)"Login required");
- RESUME;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET /RECURSIVE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
- break;
-case 21:
- { /* GET /RECURSIVE /DELETE */
-#ifndef NOSERVER
- recursive = 1; /* Set these before sgetinit() */
- if (fnspath == PATH_OFF)
- fnspath = PATH_REL; /* Don't worry, they will be */
- moving = 1; /* reset next time through. */
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- RESUME;
- } else if (!ENABLED(en_del)) {
- errpkt((CHAR *)"Deleting files is disabled");
- RESUME;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR,1,"server",
- "GET /RECURSIVE /DELETE",(char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
- break;
-case 22:
- { /* GET /RECOVER (REGET) */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if (sgetinit(1,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET /RECOVER", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
- break;
-case 23:
- { /* Extended GET */
-#ifndef NOSERVER
- if (x_login && !x_logged) { /* (any combination of options) */
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if ((x = sgetinit(0,1)) < 0) {
- debug(F101,"CKCPRO <serve>O sgetinit fail","",x);
- RESUME;
- } else if (x == 0) {
- debug(F101,"CKCPRO <serve>O sgetinit done","",x);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- } else { /* Otherwise stay in this state */
- debug(F101,"CKCPRO <serve>O sgetinit TBC","",x);
- ack();
- BEGIN ropkt;
- }
-#endif /* NOSERVER */
-}
- break;
-case 24:
- {
-#ifndef NOSERVER
- if (x_login && !x_logged) { /* (any combination of options) */
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if ((x = sgetinit(0,1)) < 0) {
- debug(F101,"CKCPRO <ropkt>O sgetinit fail","",x);
- RESUME;
- } else if (x == 0) {
- debug(F101,"CKCPRO <ropkt>O sgetinit done","",x);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- } else { /* Otherwise stay in this state */
- debug(F101,"CKCPRO <ropkt>O sgetinit TBC","",x);
- ack();
- }
-#endif /* NOSERVER */
-}
- break;
-case 25:
- { /* Generic server command */
-#ifndef NOSERVER
- srvptr = srvcmd; /* Point to command buffer */
- decode(rdatap,putsrv,0); /* Decode packet data into it */
- putsrv(NUL); /* Insert a couple nulls */
- putsrv(NUL); /* for termination */
- if (srvcmd[0]) {
- sstate = srvcmd[0]; /* Set requested start state */
- if (x_login && !x_logged && /* Login required? */
- /* Login, Logout, and Help are allowed when not logged in */
- sstate != 'I' && sstate != 'L' && sstate != 'H') {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else {
- nakstate = 0; /* Now I'm the sender. */
- what = W_REMO; /* Doing a REMOTE command. */
-#ifdef STREAMING
- if (!streaming)
-#endif /* STREAMING */
- if (timint < 1)
- timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
- binary = XYFT_T; /* Switch to text mode */
- BEGIN generic; /* Switch to generic command state */
- }
- } else {
- errpkt((CHAR *)"Badly formed server command"); /* report error */
- RESUME; /* & go back to server command wait */
- }
-#endif /* NOSERVER */
-}
- break;
-case 26:
- { /* Receive Host command */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if (!ENABLED(en_hos)) {
- errpkt((CHAR *)"REMOTE HOST disabled");
- RESUME;
- } else if (nopush) {
- errpkt((CHAR *)"HOST commands not available");
- RESUME;
- } else {
- srvptr = srvcmd; /* Point to command buffer */
- decode(rdatap,putsrv,0); /* Decode command packet into it */
- putsrv(NUL); /* Null-terminate */
- nakstate = 0; /* Now sending, not receiving */
- binary = XYFT_T; /* Switch to text mode */
- if (syscmd((char *)srvcmd,"")) { /* Try to execute the command */
- what = W_REMO; /* Doing a REMOTE command. */
-#ifdef STREAMING
- if (!streaming)
-#endif /* STREAMING */
- if (timint < 1)
- timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE HOST", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit; /* If OK, send back its output */
- } else { /* Otherwise */
- errpkt((CHAR *)"Can't do system command"); /* report error */
- RESUME; /* & go back to server command wait */
- }
- }
-#endif /* NOSERVER */
-}
- break;
-case 27:
- { /* Interrupted or connection lost */
- rc = srv_timeout();
- debug(F101,"srv_timeout","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
- break;
-case 28:
- { /* Server got a NAK in command-wait */
-#ifndef NOSERVER
- errpkt((CHAR *)"Did you say RECEIVE instead of GET?");
- RESUME;
-#endif /* NOSERVER */
-}
- break;
-case 29:
- { /* Any other command in this state */
-#ifndef NOSERVER
- if (c != ('E' - SP) && c != ('Y' - SP)) /* except E and Y packets. */
- errpkt((CHAR *)"Unimplemented server function");
- /* If we answer an E with an E, we get an infinite loop. */
- /* A Y (ACK) can show up here if we sent back a short-form reply to */
- /* a G packet and it was echoed. ACKs can be safely ignored here. */
- RESUME; /* Go back to server command wait. */
-#endif /* NOSERVER */
-}
- break;
-case 30:
- { /* Login/Out */
- rc = srv_login();
- debug(F101,"<generic>I srv_login","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
- break;
-case 31:
- { /* Got REMOTE CD command */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE CD", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_cwd)) {
- errpkt((CHAR *)"REMOTE CD disabled");
- RESUME;
- } else {
- char * p = NULL;
- x = cwd((char *)(srvcmd+1)); /* Try to change directory */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE CD", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!x) { /* Failed */
- errpkt((CHAR *)"Can't change directory");
- RESUME; /* Back to server command wait */
- } else if (x == 2) { /* User wants message */
- if (!ENABLED(en_typ)) { /* Messages (REMOTE TYPE) disabled? */
- errpkt((CHAR *)"REMOTE TYPE disabled");
- RESUME;
- } else { /* TYPE is enabled */
- int i;
- for (i = 0; i < 8; i++) {
- if (zchki(cdmsgfile[i]) > -1) {
- break;
- }
- }
- binary = XYFT_T; /* Use text mode for this. */
- if (i < 8 && sndtype(cdmsgfile[i])) { /* Have readme file? */
- BEGIN ssinit; /* OK */
- } else { /* not OK */
- p = zgtdir();
- if (!p) p = "";
- success = (*p) ? 1 : 0;
- ack1((CHAR *)p); /* ACK with new directory name */
- success = 1;
- RESUME; /* wait for next server command */
- }
- }
- } else { /* User doesn't want message */
- p =zgtdir();
- if (!p) p = "";
- success = (*p) ? 1 : 0;
- ack1((CHAR *)p);
- success = 1;
- RESUME; /* Wait for next server command */
- }
- }
-#endif /* NOSERVER */
-}
- break;
-case 32:
- { /* Got REMOTE PWD command */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE PWD", NULL);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_cwd)) {
- errpkt((CHAR *)"REMOTE CD disabled");
- RESUME;
- } else {
- if (encstr((CHAR *)zgtdir()) > -1) { /* Encode current directory */
- ack1(data); /* If it fits, send it back in ACK */
- success = 1;
- } else { /* Failed */
- ack(); /* Send empty ACK */
- success = 0; /* and indicate failure locally */
- }
- RESUME; /* Back to server command wait */
- }
-#endif /* NOSERVER */
-}
- break;
-case 33:
- { /* REMOTE DIRECTORY command */
-#ifndef NOSERVER
- char *n2;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE DIRECTORY", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_dir)) { /* If DIR is disabled, */
- errpkt((CHAR *)"REMOTE DIRECTORY disabled"); /* refuse. */
- RESUME;
- } else { /* DIR is enabled. */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE DIR", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* But CWD is disabled */
- zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
- if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
-#ifdef COMMENT
- n2 = (*(srvcmd+2)) ? DIRCMD : DIRCM2;
- if (syscmd(n2,(char *)(srvcmd+2))) /* If it can be done */
-#else
- int x;
- if ((x = snddir((char*)(srvcmd+2))) > 0)
-#endif /* COMMENT */
- {
- BEGIN ssinit; /* send the results back; */
- } else { /* otherwise */
- if (x < 0)
- errpkt((CHAR *)"No files match");
- else
- errpkt((CHAR *)"Can't list directory");
- RESUME; /* return to server command wait */
- }
- }
- }
-#endif /* NOSERVER */
-}
- break;
-case 34:
- { /* REMOTE DELETE (Erase) */
-#ifndef NOSERVER
- char *n2;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE DELETE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_del)) {
- errpkt((CHAR *)"REMOTE DELETE disabled");
- RESUME;
- } else { /* DELETE is enabled */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE DELETE", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* but CWD is disabled */
- zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
- if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- }
- } else if (isdir((char *)(srvcmd+2))) { /* A directory name? */
- errpkt((CHAR *)"It's a directory");
- RESUME;
- }
- if (state == generic) { /* It's OK to go ahead. */
- int x;
- if ((x = snddel((char*)(srvcmd+2))) > 0) {
- BEGIN ssinit; /* If OK send results back */
- } else { /* otherwise */
- if (x < 0)
- errpkt((CHAR *)"File not found"); /* report failure */
- else
- errpkt((CHAR *)"DELETE failed");
- RESUME; /* & return to server command wait */
- }
- }
- }
-#endif /* NOSERVER */
-}
- break;
-case 35:
- { /* FINISH */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "FINISH", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"SERVER FINISH", "", "");
-#endif /* IKSDB */
- if (!ENABLED(en_fin)) {
- errpkt((CHAR *)"FINISH disabled");
- RESUME;
- } else {
- ack(); /* Acknowledge */
- xxscreen(SCR_TC,0,0L,""); /* Display */
- success = 1;
- return(0); /* Done */
- }
-#endif /* NOSERVER */
-}
- break;
-case 36:
- { /* EXIT */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE EXIT", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE EXIT", "", "");
-#endif /* IKSDB */
- if (!ENABLED(en_xit)) {
- errpkt((CHAR *)"EXIT disabled");
- RESUME;
- } else {
- ack(); /* Acknowledge */
- xxscreen(SCR_TC,0,0L,""); /* Display */
- doexit(GOOD_EXIT,xitsta);
- }
-#endif /* NOSERVER */
-}
- break;
-case 37:
- { /* BYE (Logout) */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "BYE", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"SERVER BYE", "", "");
-#endif /* IKSDB */
- if (!ENABLED(en_bye)) {
- errpkt((CHAR *)"BYE disabled");
- RESUME;
- } else {
- ack(); /* Acknowledge */
- success = 1;
- msleep(750); /* Give the ACK time to get out */
- if (local)
- ttres(); /* Reset the terminal */
- xxscreen(SCR_TC,0,0L,""); /* Display */
- doclean(1); /* Clean up files, etc */
-#ifdef DEBUG
- debug(F100,"C-Kermit BYE - Loggin out...","",0);
- zclose(ZDFILE);
-#endif /* DEBUG */
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver)
- ckxlogout();
- else
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-#ifdef TCPSOCKET
-#ifndef NOLISTEN
- if (network && tcpsrfd > 0 && !inserver)
- doexit(GOOD_EXIT,xitsta);
- else
-#endif /* NOLISTEN */
-#endif /* TCPSOCKET */
- return(zkself()); /* Try to log self out */
- }
-#endif /* NOSERVER */
-}
- break;
-case 38:
- { /* REMOTE HELP */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE HELP", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE HELP", "", "");
-#endif /* IKSDB */
-#ifndef NOSERVER
- if (sndhlp()) {
- BEGIN ssinit; /* try to send it */
- } else { /* If not ok, */
- errpkt((CHAR *)"Can't send help"); /* send error message instead */
- RESUME; /* and return to server command wait */
- }
-#endif /* NOSERVER */
-}
- break;
-case 39:
- { /* REMOTE RENAME */
- rc = srv_rename();
- debug(F101,"srv_rename","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
- break;
-case 40:
- { /* REMOTE COPY */
- rc = srv_copy();
- debug(F101,"srv_copy","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
- break;
-case 41:
- { /* REMOTE SET */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE SET", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifndef NOSERVER
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE SET", (char *)(srvcmd+1), "");
-#endif /* IKSDB */
- if (!ENABLED(en_set)) {
- errpkt((CHAR *)"REMOTE SET disabled");
- RESUME;
- } else {
- if (remset((char *)(srvcmd+1))) { /* Try to do what they ask */
- success = 1;
- ack(); /* If OK, then acknowledge */
- } else /* Otherwise */
- errpkt((CHAR *)"Unknown REMOTE SET parameter"); /* give error msg */
- RESUME; /* Return to server command wait */
- }
-#endif /* NOSERVER */
-}
- break;
-case 42:
- { /* REMOTE TYPE */
-#ifndef NOSERVER
- char *n2;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE TYPE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_typ)) {
- errpkt((CHAR *)"REMOTE TYPE disabled");
- RESUME;
- } else {
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE TYPE", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* If CWD disabled */
- zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
- if (strcmp((char *)(srvcmd+2),n2)) { /* refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
- binary = XYFT_T; /* Use text mode for this. */
- if ( /* (RESUME didn't change state) */
-#ifdef COMMENT
- syscmd(TYPCMD,(char *)(srvcmd+2)) /* Old way */
-#else
- sndtype((char *)(srvcmd+2)) /* New way */
-#endif /* COMMENT */
- )
- BEGIN ssinit; /* OK */
- else { /* not OK */
- errpkt((CHAR *)"Can't type file"); /* give error message */
- RESUME; /* wait for next server command */
- }
- }
- }
-#endif /* NOSERVER */
-}
- break;
-case 43:
- { /* REMOTE MKDIR */
-#ifndef NOSERVER
-#ifdef CK_MKDIR
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE MKDIR", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE MKDIR", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_mkd)) {
- errpkt((CHAR *)"REMOTE MKDIR disabled");
- RESUME;
- } else if (!ENABLED(en_cwd)) { /* If CWD disabled */
- errpkt((CHAR *)"Directory access restricted");
- RESUME; /* Remember, this is not a goto! */
- }
- if (state == generic) { /* OK to go ahead. */
- char *p = NULL;
- x = ckmkdir(0,(char *)(srvcmd+2),&p,0,1); /* Make the directory */
- if (!p) p = "";
- if (x > -1) {
- encstr((CHAR *)p); /* OK - encode the name */
- ack1(data); /* Send short-form response */
- success = 1;
- RESUME;
- } else { /* not OK */
- if (!*p) p = "Directory creation failure";
- errpkt((CHAR *)p); /* give error message */
- RESUME; /* Wait for next server command */
- }
- }
-#else
- errpkt((CHAR *)"REMOTE MKDIR not available");
- RESUME;
-#endif /* CK_MKDIR */
-#endif /* NOSERVER */
-}
- break;
-case 44:
- { /* REMOTE RMDIR */
-#ifndef NOSERVER
-#ifdef CK_MKDIR
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE RMDIR", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE RMDIR", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_rmd)) {
- errpkt((CHAR *)"REMOTE RMDIR disabled");
- RESUME;
- } else if (!ENABLED(en_cwd)) { /* If CWD disabled */
- errpkt((CHAR *)"Directory access restricted");
- RESUME; /* Remember, this is not a goto! */
- }
- if (state == generic) { /* OK to go ahead. */
- char *p = NULL;
- x = ckmkdir(1,(char *)(srvcmd+2),&p,0,1);
- if (!p) p = "";
- if (x > -1) {
- encstr((CHAR *)p); /* OK - encode the name */
- ack1(data); /* Send short-form response */
- success = 1;
- RESUME;
- } else { /* not OK */
- if (!*p) p = "Directory removal failure";
- errpkt((CHAR *)p); /* give error message */
- RESUME; /* Wait for next server command */
- }
- }
-#else
- errpkt((CHAR *)"REMOTE RMDIR not available");
- RESUME;
-#endif /* CK_MKDIR */
-#endif /* NOSERVER */
-}
- break;
-case 45:
- { /* REMOTE SPACE */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE SPACE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_spa)) {
- errpkt((CHAR *)"REMOTE SPACE disabled");
- RESUME;
- } else {
- x = srvcmd[1]; /* Get area to check */
- x = ((x == NUL) || (x == SP)
-#ifdef OS2
- || (x == '!') || (srvcmd[3] == ':')
-#endif /* OS2 */
- );
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- "REMOTE SPACE",
- (x ? "" : (char *)srvcmd),
- ""
- );
-#endif /* IKSDB */
- if (!x && !ENABLED(en_cwd)) { /* CWD disabled */
- errpkt((CHAR *)"Access denied"); /* and non-default area given, */
- RESUME; /* refuse. */
- } else {
-#ifdef OS2
-_PROTOTYP(int sndspace,(int));
- if (sndspace(x ? toupper(srvcmd[2]) : 0)) {
- BEGIN ssinit; /* send the report. */
- } else { /* If not ok, */
- errpkt((CHAR *)"Can't send space"); /* send error message */
- RESUME; /* and return to server command wait */
- }
-#else
- if (nopush)
- x = 0;
- else
- x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,(char *)(srvcmd+2)));
- if (x) { /* If we got the info */
- BEGIN ssinit; /* send it */
- } else { /* otherwise */
- errpkt((CHAR *)"Can't check space"); /* send error message */
- RESUME; /* and await next server command */
- }
-#endif /* OS2 */
- }
- }
-#endif /* NOSERVER */
-}
- break;
-case 46:
- { /* REMOTE WHO */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE WHO", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE WHO", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_who)) {
- errpkt((CHAR *)"REMOTE WHO disabled");
- RESUME;
- } else {
-#ifdef OS2
-_PROTOTYP(int sndwho,(char *));
- if (sndwho((char *)(srvcmd+2))) {
- BEGIN ssinit; /* try to send it */
- } else { /* If not ok, */
- errpkt((CHAR *)"Can't do who command"); /* send error msg */
- RESUME; /* and return to server command wait */
- }
-#else
- if (syscmd(WHOCMD,(char *)(srvcmd+2))) {
- BEGIN ssinit;
- } else {
- errpkt((CHAR *)"Can't do who command");
- RESUME;
- }
-#endif /* OS2 */
- }
-#endif /* NOSERVER */
-}
- break;
-case 47:
- { /* Variable query or set */
- rc = srv_query();
- debug(F101,"srv_query","",rc);
- if (rc > -1) return(rc);
-}
- break;
-case 48:
- { /* REMOTE MESSAGE command */
-#ifndef NOSERVER
- debug(F110,"RMSG",(char *)srvcmd+2,0);
- xxscreen(SCR_MS,0,0L,(char *)(srvcmd+2));
- ack();
- RESUME;
-#endif /* NOSERVER */
-}
- break;
-case 49:
- { /* Interrupted or connection lost */
-#ifndef NOSERVER
- if (fatalio) { /* Connection lost */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
-#endif /* CKSYSLOG */
- success = 0;
- xitsta |= (what & W_KERMIT);
- QUIT;
- } else if (interrupted) {
- if (!ENABLED(en_fin)) { /* Ctrl-C typed */
- errpkt((CHAR *)"QUIT disabled");
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
-#endif /* CKSYSLOG */
- success = 0;
- xitsta |= (what & W_KERMIT);
- QUIT;
- }
- } else { /* Shouldn't happen */
- debug(F100,"SERVER (generic) GOT UNEXPECTED 'q'","",0);
- QUIT;
- }
-#endif /* NOSERVER */
-}
- break;
-case 50:
- { /* Anything else in this state... */
-#ifndef NOSERVER
- errpkt((CHAR *)"Unimplemented REMOTE command"); /* Complain */
- RESUME; /* and return to server command wait */
-#endif /* NOSERVER */
-}
- break;
-case 51:
- { /* Sent BYE and connection broken */
- if (bye_active && ttchk() < 0) {
- msleep(500);
- bye_active = 0;
- ttclos(0); /* Close our end of the connection */
- clsof(0);
- return(success = 1);
- } else { /* Other generic command */
- return(success = 0); /* or connection not broken */
- }
-}
- break;
-case 52:
- { /* Short-Form reply */
- rc = rcv_shortreply();
- debug(F101,"<rgen>Y rcv_shortreply","",rc);
- if (rc > -1) return(rc);
-}
- break;
-case 53:
- { /* File header */
- /* char *n2; */
- extern int rsn;
- debug(F101,"<rfile>F winlo 1","",winlo);
- xflg = 0; /* Not screen data */
- if (!czseen)
- cancel = 0; /* Reset cancellation counter */
-#ifdef CALIBRATE
- if (dest == DEST_N)
- calibrate = 1;
-#endif /* CALIBRATE */
- if (!rcvfil(filnam)) { /* Figure out local filename */
- errpkt((CHAR *)rf_err); /* Trouble */
- RESUME;
- } else { /* Real file, OK to receive */
- char * fnp;
- debug(F111,"<rfile>F winlo 2",fspec,winlo);
- if (filcnt == 1) /* rcvfil set this to 1 for 1st file */
- crc16 = 0L; /* Clear file CRC */
- fnp = fspec; /* This is the full path */
- if (server && !ENABLED(en_cwd) || /* if DISABLE CD */
- !fackpath /* or F-ACK-PATH OFF */
- ) {
- zstrip(fspec,&fnp); /* don't send back full path */
- }
- encstr((CHAR *)fnp);
- if (fackbug)
- ack();
- else
- ack1(data); /* Send it back in ACK */
- initattr(&iattr); /* Clear file attribute structure */
- streamon();
- if (window(wslotn) < 0) { /* Allocate negotiated window slots */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- }
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- server ? "SERVER" : "",
- "RECEIVE",
- fspec
- );
-#endif /* IKSDB */
- BEGIN rattr; /* Now expect Attribute packets */
- }
-}
- break;
-case 54:
- { /* X-packet instead of file header */
- xflg = 1; /* Screen data */
- if (!czseen)
- cancel = 0; /* Reset cancellation counter */
- ack(); /* Acknowledge the X-packet */
- initattr(&iattr); /* Initialize attribute structure */
- streamon();
- if (window(wslotn) < 0) { /* allocate negotiated window slots */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- }
-#ifndef NOSPL
- if (query) { /* If this is the response to */
- qbufp = querybuf; /* a query that we sent, initialize */
- qbufn = 0; /* the response buffer */
- querybuf[0] = NUL;
- }
-#endif /* NOSPL */
- what = W_REMO; /* we're doing a REMOTE command */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- server ? "SERVER" : "",
- "RECEIVE",
- fspec
- );
-#endif /* IKSDB */
- BEGIN rattr; /* Expect Attribute packets */
-}
- break;
-case 55:
- { /* Attribute packet */
- if (gattr(rdatap,&iattr) == 0) { /* Read into attribute structure */
-#ifdef CK_RESEND
- ack1((CHAR *)iattr.reply.val); /* Reply with data */
-#else
- ack(); /* If OK, acknowledge */
-#endif /* CK_RESEND */
- } else { /* Otherwise */
- extern long fsize;
- char *r;
- r = getreason(iattr.reply.val);
- ack1((CHAR *)iattr.reply.val); /* refuse to accept the file */
- xxscreen(SCR_ST,ST_REFU,0L,r); /* reason */
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,filnam,fsize,binary,1,r);
-#endif /* TLOG */
- }
-}
- break;
-case 56:
- { /* First data packet */
- debug(F100,"<rattr> D firstdata","",0);
- rc = rcv_firstdata();
- debug(F101,"rcv_firstdata rc","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
- break;
-case 57:
- { /* EOT, no more files */
- ack(); /* Acknowledge the B packet */
- reot(); /* Do EOT things */
-#ifdef CK_TMPDIR
-/* If we were cd'd temporarily to another device or directory ... */
- if (f_tmpdir) {
- int x;
- x = zchdir((char *) savdir); /* ... restore previous directory */
- f_tmpdir = 0; /* and remember we did it. */
- debug(F111,"ckcpro.w B tmpdir restoring",savdir,x);
- }
-#endif /* CK_TMPDIR */
- RESUME; /* and quit */
-}
- break;
-case 58:
- { /* Got Data packet */
- debug(F101,"<rdpkt>D cxseen","",cxseen);
- debug(F101,"<rdpkt>D czseen","",czseen);
- if (cxseen || czseen || discard) { /* If file or group interruption */
- CHAR * msg;
- msg = czseen ? (CHAR *)"Z" : (CHAR *)"X";
-#ifdef STREAMING
- if (streaming) { /* Need to cancel */
- debug(F111,"<rdpkt>D streaming cancel",msg,cancel);
- if (cancel++ == 0) { /* Only do this once */
- ack1(msg); /* Put "X" or "Z" in ACK */
- } else if (czseen) {
- errpkt((CHAR *)"User canceled");
- RESUME;
- } else {
- fastack();
- }
- } else
-#endif /* STREAMING */
- ack1(msg);
- } else { /* No interruption */
- int rc, qf;
-#ifndef NOSPL
- qf = query;
-#else
- qf = 0;
-#endif /* NOSPL */
-#ifdef CKTUNING
- rc = (binary && !parity) ?
- bdecode(rdatap,putfil):
- decode(rdatap, qf ? puttrm : putfil, 1);
-#else
- rc = decode(rdatap, qf ? puttrm : putfil, 1);
-#endif /* CKTUNING */
- if (rc < 0) {
- discard = (keep == 0 || (keep == SET_AUTO && binary != XYFT_T));
- errpkt((CHAR *)"Error writing data"); /* If failure, */
- RESUME;
- } else /* Data written OK, send ACK */
-#ifdef STREAMING
- if (streaming)
- fastack();
- else
-#endif /* STREAMING */
- ack();
- }
-}
- break;
-case 59:
- { /* EOF immediately after A-Packet. */
- rf_err = "Can't create file";
- timint = s_timint;
- if (discard) { /* Discarding a real file... */
- x = 1;
- } else if (xflg) { /* If screen data */
- if (remfile) { /* redirected to file */
- if (rempipe) /* or pipe */
- x = openc(ZOFILE,remdest); /* Pipe: start command */
- else
- x = opena(remdest,&iattr); /* File: open with attributes */
- } else { /* otherwise */
- x = opent(&iattr); /* "open" the screen */
- }
-#ifdef CALIBRATE
- } else if (calibrate) { /* If calibration run */
- x = ckopenx(&iattr); /* do this */
-#endif /* CALIBRATE */
- } else { /* otherwise */
- x = opena(filnam,&iattr); /* open the file, with attributes */
- if (x == -17) { /* REGET skipped because same size */
- discard = 1;
- rejection = 1;
- }
- }
- if (!x || reof(filnam, &iattr) < 0) { /* Close output file */
- errpkt((CHAR *) rf_err); /* If problem, send error msg */
- RESUME; /* and quit */
- } else { /* otherwise */
- if (x == -17)
- xxscreen(SCR_ST,ST_SKIP,SKP_RES,"");
- ack(); /* acknowledge the EOF packet */
- BEGIN rfile; /* and await another file */
- }
-}
- break;
-case 60:
- { /* Ctrl-C or connection loss. */
- timint = s_timint;
- window(1); /* Set window size back to 1... */
- cxseen = 1;
- x = clsof(1); /* Close file */
- return(success = 0); /* Failed */
-}
- break;
-case 61:
- { /* End Of File (EOF) Packet */
-/* wslots = 1; */ /* (don't set) Window size back to 1 */
-#ifndef COHERENT /* Coherent compiler blows up on this switch() statement. */
- x = reof(filnam, &iattr); /* Handle the EOF packet */
- switch (x) { /* reof() sets the success flag */
- case -5: /* Handle problems */
- errpkt((CHAR *)"RENAME failed"); /* Fatal */
- RESUME;
- break;
- case -4:
- errpkt((CHAR *)"MOVE failed"); /* Fatal */
- RESUME;
- break;
- case -3: /* If problem, send error msg */
- errpkt((CHAR *)"Can't print file"); /* Fatal */
- RESUME;
- break;
- case -2:
- errpkt((CHAR *)"Can't mail file"); /* Fatal */
- RESUME;
- break;
- case 2: /* Not fatal */
- case 3:
- xxscreen(SCR_EM,0,0L,"Receiver can't delete temp file");
- RESUME;
- break;
- default:
- if (x < 0) { /* Fatal */
- errpkt((CHAR *)"Can't close file");
- RESUME;
- } else { /* Success */
-#ifndef NOSPL
- if (query) /* Query reponses generally */
- conoll(""); /* don't have line terminators */
-#endif /* NOSPL */
- if (czseen) { /* Batch canceled? */
- if (cancel++ == 0) { /* If we haven't tried this yet */
- ack1((CHAR *)"Z"); /* Try it once */
- } else { /* Otherwise */
- errpkt((CHAR *)"User canceled"); /* quite with Error */
- RESUME;
- }
- } else
- ack(); /* Acknowledge the EOF packet */
- BEGIN rfile; /* and await another file */
- }
- }
-#else
- if (reof(filnam, &iattr) < 0) { /* Close the file */
- errpkt((CHAR *)"Error at end of file");
- RESUME;
- } else { /* reof() sets success flag */
- ack();
- BEGIN rfile;
- }
-#endif /* COHERENT */
-}
- break;
-case 62:
- { /* ACK for Send-Init */
- spar(rdatap); /* set parameters from it */
- cancel = 0;
- bctu = bctr; /* switch to agreed-upon block check */
- bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */
-#ifdef CK_RESEND
- if ((sendmode == SM_RESEND) && (!atcapu || !rscapu)) { /* RESEND */
- errpkt((CHAR *) "RESEND capabilities not negotiated");
- RESUME;
- } else {
-#endif /* CK_RESEND */
- what = W_SEND; /* Remember we're sending */
- lastxfer = W_SEND;
- x = sfile(xflg); /* Send X or F header packet */
- cancel = 0; /* Reset cancellation counter */
- if (x) { /* If the packet was sent OK */
- if (!xflg && filcnt == 1) /* and it's a real file */
- crc16 = 0L; /* Clear the file CRC */
- resetc(); /* reset per-transaction counters */
- rtimer(); /* reset timers */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- streamon(); /* turn on streaming */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- (server ? "SERVER" : ""),
- "SEND",
- filnam
- );
-#endif /* IKSDB */
- BEGIN ssfile; /* and switch to receive-file state */
- } else { /* otherwise send error msg & quit */
- s = xflg ? "Can't execute command" : (char *)epktmsg;
- if (!*s) s = "Can't open file";
- errpkt((CHAR *)s);
- RESUME;
- }
-#ifdef CK_RESEND
- }
-#endif /* CK_RESEND */
-}
- break;
-case 63:
- { /* R packet was retransmitted. */
- xsinit(); /* Resend packet 0 */
-}
- break;
-case 64:
- { /* Same deal if G packet comes again */
- xsinit();
-}
- break;
-case 65:
- { /* Same deal if C packet comes again */
- xsinit();
-}
- break;
-case 66:
- { /* ACK for F or X packet */
- srvptr = srvcmd; /* Point to string buffer */
- decode(rdatap,putsrv,0); /* Decode data field, if any */
- putsrv(NUL); /* Terminate with null */
- ffc = 0L; /* Reset file byte counter */
- debug(F101,"<ssfile>Y cxseen","",cxseen);
- if (*srvcmd) { /* If remote name was recorded */
- if (sendmode != SM_RESEND) {
- if (fdispla == XYFD_C || fdispla == XYFD_S)
- xxscreen(SCR_AN,0,0L,(char *)srvcmd);
- tlog(F110," remote name:",(char *) srvcmd,0L);
- makestr(&psrfspec,(char *)srvcmd);
- }
- }
- if (cxseen||czseen) { /* Interrupted? */
- debug(F101,"<ssfile>Y canceling","",0);
- x = clsif(); /* Close input file */
- sxeof(1); /* Send EOF(D) */
- BEGIN sseof; /* and switch to EOF state. */
- } else if (atcapu) { /* If attributes are to be used */
- if (sattr(xflg | stdinf, 1) < 0) { /* send them */
- errpkt((CHAR *)"Can't send attributes"); /* if problem, say so */
- RESUME; /* and quit */
- } else BEGIN ssattr; /* if ok, switch to attribute state */
- } else { /* Attributes not negotiated */
- if (window(wslotn) < 0) { /* Open window */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- } else if ((x = sdata()) == -2) { /* Send first data packet data */
- window(1); /* Connection lost, reset window */
- x = clsif(); /* Close input file */
- return(success = 0); /* Return failure */
- } else if (x == -9) { /* User interrupted */
- errpkt((CHAR *)"User cancelled"); /* Send Error packet */
- window(1); /* Set window size back to 1... */
- timint = s_timint; /* Restore timeout */
- return(success = 0); /* Failed */
- } else if (x < 0) { /* EOF (empty file) or interrupted */
- window(1); /* put window size back to 1, */
- debug(F101,"<ssfile>Y cxseen","",cxseen);
- x = clsif(); /* If not ok, close input file, */
- if (x < 0) /* treating failure as interruption */
- cxseen = 1; /* Send EOF packet */
- seof(cxseen||czseen);
- BEGIN sseof; /* and switch to EOF state. */
- } else { /* First data sent OK */
- BEGIN ssdata; /* All ok, switch to send-data state */
- }
- }
-}
- break;
-case 67:
- { /* Got ACK to A packet */
- ffc = 0L; /* Reset file byte counter */
- debug(F101,"<ssattr>Y cxseen","",cxseen);
- if (cxseen||czseen) { /* Interrupted? */
- debug(F101,"<sattr>Y canceling","",0);
- x = clsif(); /* Close input file */
- sxeof(1); /* Send EOF(D) */
- BEGIN sseof; /* and switch to EOF state. */
- } else if (rsattr(rdatap) < 0) { /* Was the file refused? */
- discard = 1; /* Set the discard flag */
- clsif(); /* Close the file */
- sxeof(1); /* send EOF with "discard" code */
- BEGIN sseof; /* switch to send-EOF state */
- } else if ((x = sattr(xflg | stdinf, 0)) < 0) { /* Send more? */
- errpkt((CHAR *)"Can't send attributes"); /* Trouble... */
- RESUME;
- } else if (x == 0) { /* No more to send so now the data */
- if (window(wslotn) < 0) { /* Allocate negotiated window slots */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- }
- if ((x = sdata()) == -2) { /* File accepted, send first data */
- window(1); /* Connection broken */
- x = clsif(); /* Close file */
- return(success = 0); /* Return failure */
- } else if (x == -9) { /* User interrupted */
- errpkt((CHAR *)"User cancelled"); /* Send Error packet */
- window(1); /* Set window size back to 1... */
- timint = s_timint; /* Restore timeout */
- return(success = 0); /* Failed */
- } else if (x < 0) { /* If data was not sent */
- window(1); /* put window size back to 1, */
- debug(F101,"<ssattr>Y cxseen","",cxseen);
- if (clsif() < 0) /* Close input file */
- cxseen = 1; /* Send EOF packet */
- seof(cxseen||czseen);
- BEGIN sseof; /* and switch to EOF state. */
- } else {
- BEGIN ssdata; /* All ok, switch to send-data state */
- }
- }
-}
- break;
-case 68:
- { /* Ctrl-C or connection loss. */
- window(1); /* Set window size back to 1... */
- cxseen = 1; /* To indicate interruption */
- x = clsif(); /* Close file */
- return(success = 0); /* Failed */
-}
- break;
-case 69:
- { /* Got ACK to Data packet */
- canned(rdatap); /* Check if file transfer cancelled */
- debug(F111,"<ssdata>Y cxseen",rdatap,cxseen);
- debug(F111,"<ssdata>Y czseen",rdatap,czseen);
- if ((x = sdata()) == -2) { /* Try to send next data */
- window(1); /* Connection lost, reset window */
- x = clsif(); /* Close file */
- return(success = 0); /* Failed */
- } else if (x == -9) { /* User interrupted */
- errpkt((CHAR *)"User cancelled"); /* Send Error packet */
- window(1); /* Set window size back to 1... */
- timint = s_timint; /* Restore original timeout */
- return(success = 0); /* Failed */
- } else if (x < 0) { /* EOF - finished sending data */
- debug(F101,"<ssdata>Y cxseen","",cxseen);
- window(1); /* Set window size back to 1... */
- if (clsif() < 0) /* Close input file */
- cxseen = 1; /* Send EOF packet */
- debug(F101,"<ssdata>Y CALLING SEOF()","",cxseen);
- seof(cxseen||czseen);
- BEGIN sseof; /* and enter send-eof state */
- }
- /* NOTE: If x == 0 it means we're draining: see sdata()! */
-}
- break;
-case 70:
- { /* Got ACK to EOF */
- int g, xdiscard;
- canned(rdatap); /* Check if file transfer cancelled */
- debug(F111,"<sseof>Y cxseen",rdatap,cxseen);
- debug(F111,"<sseof>Y czseen",rdatap,czseen);
- debug(F111,"<sseof>Y discard",rdatap,discard);
- xdiscard = discard;
- discard = 0;
- success = (cxseen == 0 && czseen == 0); /* Transfer status... */
- debug(F101,"<sseof>Y success","",success);
- if (success && rejection > 0) /* If rejected, succeed if */
- if (rejection != '#' && /* reason was date */
- rejection != 1 && rejection != '?') /* or name; */
- success = 0; /* fail otherwise. */
- cxseen = 0; /* This goes back to zero. */
- if (success) { /* Only if transfer succeeded... */
- xxscreen(SCR_ST,ST_OK,0L,"");
- if (!xdiscard) {
- makestr(&sfspec,psfspec); /* Record filenames for WHERE */
- makestr(&srfspec,psrfspec);
- }
- if (moving) { /* If MOVE'ing */
- x = zdelet(filnam); /* Try to delete the source file */
-#ifdef TLOG
- if (tralog) {
- if (x > -1) {
- tlog(F110," deleted",filnam,0);
- } else {
- tlog(F110," delete failed:",ck_errstr(),0);
- }
- }
-#endif /* TLOG */
- } else if (snd_move) { /* Or move it */
- int x;
- x = zrename(filnam,snd_move);
-#ifdef TLOG
- if (tralog) {
- if (x > -1) {
- tlog(F110," moved to ",snd_move,0);
- } else {
- tlog(F110," move failed:",ck_errstr(),0);
- }
- }
-#endif /* TLOG */
- } else if (snd_rename) { /* Or rename it */
- char *s = snd_rename; /* Renaming string */
-#ifndef NOSPL
- int y; /* Pass it thru the evaluator */
- extern int cmd_quoting; /* for \v(filename) */
- if (cmd_quoting) { /* But only if cmd_quoting is on */
- y = MAXRP;
- s = (char *)srvcmd;
- zzstring(snd_rename,&s,&y);
- s = (char *)srvcmd;
- }
-#endif /* NOSPL */
- if (s) if (*s) {
- int x;
- x = zrename(filnam,s);
-#ifdef TLOG
- if (tralog) {
- if (x > -1) {
- tlog(F110," renamed to",s,0);
- } else {
- tlog(F110," rename failed:",ck_errstr(),0);
- }
- }
-#endif /* TLOG */
-#ifdef COMMENT
- *s = NUL;
-#endif /* COMMENT */
- }
- }
- }
- if (czseen) { /* Check group interruption flag */
- g = 0; /* No more files if interrupted */
- } else { /* Otherwise... */
-#ifdef COMMENT
- /* This code makes any open error fatal to a file-group transfer. */
- g = gnfile();
- debug(F111,"<sseof>Y gnfile",filnam,g);
- if (g > 0) { /* Any more files to send? */
- if (sfile(xflg)) /* Yes, try to send next file header */
- BEGIN ssfile; /* if ok, enter send-file state */
- else { /* otherwise */
- s = xflg ? "Can't execute command" : (char *)epktmsg;
- if (!*s) s = "Can't open file";
- errpkt((CHAR *)s); /* send error message */
- RESUME; /* and quit */
- }
- } else { /* No next file */
- tsecs = gtimer(); /* get statistics timers */
-#ifdef GFTIMER
- fptsecs = gftimer();
-#endif /* GFTIMER */
- seot(); /* send EOT packet */
- BEGIN sseot; /* enter send-eot state */
- }
-#else /* COMMENT */
- while (1) { /* Keep trying... */
- g = gnfile(); /* Get next file */
- debug(F111,"<sseof>Y gnfile",filnam,g);
- if (g == 0 && gnferror == 0) /* No more, stop trying */
- break;
- if (g > 0) { /* Have one */
- if (sfile(xflg)) { /* Try to open and send F packet */
- BEGIN ssfile; /* If OK, enter send-file state */
- break; /* and break out of loop. */
- }
- } /* Otherwise keep trying to get one we can send... */
- }
- }
- if (g == 0) {
- debug(F101,"<sseof>Y no more files","",czseen);
- tsecs = gtimer(); /* Get statistics timers */
-#ifdef GFTIMER
- fptsecs = gftimer();
-#endif /* GFTIMER */
- seot(); /* Send EOT packet */
- BEGIN sseot; /* Enter send-eot state */
- }
-#endif /* COMMENT */
-}
- break;
-case 71:
- { /* Got ACK to EOT */
- debug(F101,"sseot justone","",justone);
- RESUME; /* All done, just quit */
-}
- break;
-case 72:
- { /* Got Error packet, in any state */
- char *s = "";
- window(1); /* Close window */
- timint = s_timint; /* Restore original timeout */
- if (*epktmsg) /* Message from Error packet */
- s = (char *)epktmsg;
- if (!*s) { /* If not there then maybe here */
- s = (char *)rdatap;
- ckstrncpy((char *)epktmsg,(char *)rdatap,PKTMSGLEN);
- }
- if (!*s) /* Hopefully we'll never see this. */
- s = "Unknown error";
- success = 0; /* For IF SUCCESS/FAIL. */
- debug(F101,"ckcpro.w justone at E pkt","",justone);
-
- success = 0; /* Transfer failed */
- xferstat = success; /* Remember transfer status */
- if (!epktsent) {
- x = quiet; quiet = 1; /* Close files silently, */
- epktrcvd = 1; /* Prevent messages from clsof() */
- clsif();
- clsof(1); /* discarding any output file. */
- ermsg(s); /* Issue the message (calls screen). */
- quiet = x; /* Restore quiet state */
- }
- tstats(); /* Get stats */
-/*
- If we are executing commands from a command file or macro, let the command
- file or macro decide whether to exit, based on SET { TAKE, MACRO } ERROR.
-*/
- if (
-#ifndef NOICP
- !xcmdsrc &&
-#endif /* NOICP */
- backgrd && !server)
- fatal("Protocol error");
- xitsta |= (what & W_KERMIT); /* Save this for doexit(). */
-#ifdef CK_TMPDIR
-/* If we were cd'd temporarily to another device or directory ... */
- if (f_tmpdir) {
- int x;
- x = zchdir((char *) savdir); /* ... restore previous directory */
- f_tmpdir = 0; /* and remember we did it. */
- debug(F111,"ckcpro.w E tmpdir restored",savdir,x);
- }
-#endif /* CK_TMPDIR */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"ERROR", (char *)epktmsg, "");
-#endif /* IKSDB */
- RESUME;
-}
- break;
-case 73:
- { success = 0; QUIT; }
- break;
-case 74:
- { /* Anything not accounted for above */
- errpkt((CHAR *)"Unexpected packet type"); /* Give error message */
- window(1);
- xitsta |= (what & W_KERMIT); /* Save this for doexit(). */
- RESUME; /* and quit */
-}
- break;
-
- }
- }
-}
-
-char tbl[] = {
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 15, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 13, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 57, 74, 74, 72, 53, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 54, 74, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 55, 74, 74, 56, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 59, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 58, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 61, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 60, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 65, 74, 72, 74, 64, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 63, 74, 74, 74, 74, 74, 74, 62, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 66, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 67, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 69, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 68, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 70, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 71, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 26, 29, 29, 29, 25, 19, 17, 22, 29, 29, 29, 28, 23,
- 29, 29, 18, 12, 29, 29, 20, 21, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 11, 29, 7, 29, 29, 29, 9, 4, 29, 5, 8, 29, 29, 29, 6,
- 29, 27, 3, 1, 29, 29, 2, 29, 10, 29, 29, 29, 29, 29, 29, 29,
- -1, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 32, 50, 31, 33, 34, 35, 50, 38, 30, 50, 40, 37, 48, 50, 50,
- 50, 50, 39, 41, 42, 45, 47, 46, 36, 50, 50, 50, 50, 50, 50, 50,
- 50, 11, 50, 7, 44, 50, 50, 9, 4, 50, 5, 8, 50, 43, 50, 6,
- 50, 49, 3, 1, 50, 50, 2, 50, 10, 50, 50, 50, 50, 50, 50, 50,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 72, 74, 74, 74, 17, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 12, 74, 74, 74, 74, 74, 16, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 72, 53, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 12, 74, 74, 74, 74, 54, 52, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 51, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 14, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
- 0, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 24,
- 74, 74, 74, 12, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 11, 74, 7, 74, 74, 74, 9, 4, 74, 5, 8, 74, 74, 74, 6,
- 74, 73, 3, 1, 74, 74, 2, 74, 10, 74, 74, 74, 74, 74, 74,74
-};
-
-
-/*
- From here down to proto() are routines that were moved out of the state
- table switcher because the resulting switch() had become too large.
- To move the contents of a state-table case to a routine:
- 1. Add a prototype to the list above the state table switcher.
- 2. Make a routine with an appropriate name, returning int.
- 3. Move the code into it.
- 4. Put a call to the new routine in the former spot:
- rc = name_of_routine();
- if (rc > -1) return(rc);
- 5. Add "return(-1);" after every RESUME, SERVE, or BEGIN macro and
- at the end if the code is open-ended.
-*/
-static int
-rcv_firstdata() {
- extern int dispos;
- debug(F101,"rcv_firstdata","",dispos);
-
- if (discard) { /* if we're discarding the file */
- ack1((CHAR *)"X"); /* just ack the data like this. */
- cancel++; /* and count it */
- BEGIN rdpkt; /* and wait for more data packets. */
- return(-1);
- } else { /* Not discarding. */
- rf_err = "Can't open file";
- if (xflg) { /* If screen data */
- if (remfile) { /* redirected to file */
- if (rempipe) /* or pipe */
- x = openc(ZOFILE,remdest); /* Pipe: start command */
- else
- x = opena(remdest,&iattr); /* File: open with attributes */
- } else { /* otherwise */
- x = opent(&iattr); /* "open" the screen */
- }
- } else { /* otherwise */
-#ifdef CALIBRATE
- if (calibrate) { /* If calibration run */
- x = ckopenx(&iattr); /* open nothing */
-#ifdef STREAMING
- if (streaming) /* Streaming */
- fastack(); /* ACK without ACKing. */
- else
-#endif /* STREAMING */
- ack(); /* Send real ACK */
- BEGIN rdpkt; /* Proceed to next state */
- return(-1);
- } else
-#endif /* CALIBRATE */
-#ifdef UNIX
-/*
- In UNIX we can pipe the file data into the mail program, which is to be
- preferred to writing it out to a temp file and then mailing it afterwards.
- This depends rather heavily on all UNIXes having a mail command that
- accepts '-s "subject"' on the command line. MAILCMD (e.g. mail, Mail, mailx)
- is defined in ckufio.c.
-*/
- if (dispos == 'M') { /* Mail... */
- char *s;
- char * tmp = NULL;
- int n = 0;
- extern char *MAILCMD;
- s = iattr.disp.val + 1;
- n = (int)strlen(MAILCMD) + /* Mail command */
- (int)strlen(s) + /* address */
- (int)strlen(ofilnam) + 32; /* subject */
- if (tmp = (char *)malloc(n)) {
- ckmakxmsg(tmp,n,
- MAILCMD," -s \"",ofilnam,"\" ",s,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- debug(F111,"rcv_firsdata mail",tmp,(int)strlen(tmp));
- x = openc(ZOFILE,(char *)tmp);
- free(tmp);
- } else
- x = 0;
- } else if (dispos == 'P') { /* Ditto for print */
- char * tmp = NULL;
- int n;
- extern char *PRINTCMD;
- n = (int)strlen(PRINTCMD) + (int)strlen(iattr.disp.val+1) + 4;
- if (tmp = (char *)malloc(n)) {
- sprintf(tmp, /* safe (prechecked) */
- "%s %s", PRINTCMD, iattr.disp.val + 1);
- x = openc(ZOFILE,(char *)tmp);
- free(tmp);
- } else
- x = 0;
- } else
-#endif /* UNIX */
- x = opena(filnam,&iattr); /* open the file, with attributes */
- }
- if (x) { /* If file was opened ok */
- int rc, qf;
-#ifndef NOSPL
- qf = query;
-#else
- qf = 0;
-#endif /* NOSPL */
-
-#ifdef CKTUNING
- rc = (binary && !parity) ?
- bdecode(rdatap,putfil):
- decode(rdatap, qf ? puttrm : putfil, 1);
-#else
- rc = decode(rdatap, qf ? puttrm : putfil, 1);
-#endif /* CKTUNING */
- if (rc < 0) {
- errpkt((CHAR *)"Error writing data");
- RESUME;
- return(-1);
- }
-#ifdef STREAMING
- if (streaming) /* Streaming was negotiated */
- fastack(); /* ACK without ACKing. */
- else
-#endif /* STREAMING */
- ack(); /* acknowledge it */
- BEGIN rdpkt; /* and switch to receive-data state */
- return(-1);
- } else { /* otherwise */
- errpkt((CHAR *) rf_err); /* send error packet */
- RESUME; /* and quit. */
- return(-1);
- }
- }
-}
-
-static int
-rcv_shortreply() {
-#ifdef PKTZEROHACK
- success = 0;
- debug(F111,"rcv_shortreply",rdatap,ipktlen);
- if (ipktack[0] && !strncmp(ipktack,(char *)rdatap,ipktlen)) {
- /* No it's the ACK to the I packet again */
- x = scmd(vcmd,(CHAR *)cmarg); /* So send the REMOTE command again */
- /* Maybe this should be resend() */
- debug(F110,"IPKTZEROHACK",ipktack,x);
- if (x < 0) {
- errpkt((CHAR *)srimsg);
- RESUME;
- return(-1);
- }
- } else {
- ipktack[0] = NUL;
-#endif /* PKTZEROHACK */
- urserver = 1;
-#ifndef NOSERVER
-#ifndef NOSPL
- if (query) { /* If to query, */
- qbufp = querybuf; /* initialize query response buffer */
- qbufn = 0;
- querybuf[0] = NUL;
- }
-#endif /* NOSPL */
- x = 1;
- if (remfile) { /* Response redirected to file */
- rf_err = "Can't open file";
- if (rempipe) /* or pipe */
- x =
-#ifndef NOPUSH
- zxcmd(ZOFILE,remdest) /* Pipe: Start command */
-#else
- 0
-#endif /* NOPUSH */
- ;
- else
- x = opena(remdest,&iattr); /* File: Open with attributes */
- debug(F111,"rcv_shortreply remfile",remdest,x);
- } else {
- x = opent(&iattr); /* "open" the screen */
- }
- if (x) { /* If file was opened ok */
- if (decode(rdatap,
-#ifndef NOSPL
- (query || !remfile) ? puttrm :
-#else
- !remfile ? puttrm :
-#endif /* NOSPL */
- zputfil, 1) < 0) { /* Note: zputfil, not putfil. */
- errpkt((CHAR *)"Error writing data");
- RESUME;
- return(-1);
- } else {
- if (rdatap) /* If we had data */
- if (*rdatap) /* add a line terminator */
- if (remfile) { /* to file */
- zsoutl(ZOFILE,"");
- } else { /* or to screen. */
-#ifndef NOICP
- if (!query || !xcmdsrc)
-#endif /* NOICP */
- if (!(quiet && rcdactive))
- conoll("");
- }
- if (bye_active && network) { /* I sent BYE or REMOTE LOGOUT */
- msleep(500); /* command and got the ACK... */
- bye_active = 0;
- ttclos(0);
- }
- clsof(0);
- if (!epktsent && !epktrcvd) /* If no error packet... */
- success = 1; /* success. */
- RESUME;
- return(-1);
- }
- } else { /* File not opened OK */
- errpkt((CHAR *) rf_err); /* send error message */
- RESUME; /* and quit. */
- return(-1);
- }
-#endif /* NOSERVER */
-#ifdef PKTZEROHACK
- }
-#endif /* PKTZEROHACK */
- debug(F101,"rcv_shortreply fallthru","",success);
- return(-1);
-}
-
-
-static int
-srv_query() {
-#ifndef NOSERVER
-#ifndef NOSPL
- char c;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE QUERY", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE QUERY", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- c = *(srvcmd+2); /* Q = Query, S = Set */
- if (c == 'Q') { /* Query */
- if (!ENABLED(en_que)) { /* Security */
- errpkt((CHAR *)"REMOTE QUERY disabled");
- RESUME;
- return(-1);
- } else { /* Query allowed */
- int n; char *p, *q;
- qbufp = querybuf; /* Wipe out old stuff */
- qbufn = 0;
- querybuf[0] = NUL;
- p = (char *) srvcmd + 3; /* Pointer for making wrapper */
- n = strlen((char *)srvcmd); /* Position of end */
- c = *(srvcmd+4); /* Which type of variable */
-
- if (*(srvcmd+6) == CMDQ) { /* Starts with command quote? */
- p = (char *) srvcmd + 6; /* Take it literally */
- if (*p == CMDQ) p++;
- } else { /* They played by the rules */
- if (c == 'K') { /* Kermit variable */
- int k;
- k = (int) strlen(p);
- if (k > 0 && p[k-1] == ')') {
- p = (char *)(srvcmd + 4);
- *(srvcmd+4) = CMDQ;
- *(srvcmd+5) = 'f'; /* Function, so make it \f...() */
- } else {
- *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */
- *(srvcmd+4) = 'v'; /* Variable, so make it \v(...) */
- *(srvcmd+5) = '('; /* around variable name */
- *(srvcmd+n) = ')';
- *(srvcmd+n+1) = NUL;
- }
- } else {
- *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */
- *(srvcmd+4) = 'v'; /* Variable, so make it \v(...) */
- *(srvcmd+5) = '('; /* around variable name */
- *(srvcmd+n) = ')';
- *(srvcmd+n+1) = NUL;
- if (c == 'S') { /* System variable */
- *(srvcmd+4) = '$'; /* so it's \$(...) */
- } else if (c == 'G') { /* Non-\ Global variable */
- *(srvcmd+4) = 'm'; /* so wrap it in \m(...) */
- }
- }
- } /* Now evaluate it */
- n = QBUFL; /* Max length */
- q = querybuf; /* Where to put it */
- if (zzstring(p,&q,&n) < 0) {
- errpkt((n > 0) ? (CHAR *)"Can't get value"
- : (CHAR *)"Value too long"
- );
- RESUME;
- return(-1);
- } else {
- if (encstr((CHAR *)querybuf) > -1) { /* Encode it */
- ack1(data); /* If it fits, send it back in ACK */
- success = 1;
- RESUME;
- return(-1);
- } else if (sndstring(querybuf)) { /* Long form response */
- BEGIN ssinit;
- return(-1);
- } else { /* sndhlp() fails */
- errpkt((CHAR *)"Can't send value");
- RESUME;
- return(-1);
- }
- }
- }
- } else if (c == 'S') { /* Set (assign) */
- if (!ENABLED(en_asg)) { /* Security */
- errpkt((CHAR *)"REMOTE ASSIGN disabled");
- RESUME;
- return(-1);
- } else { /* OK */
- int n;
- n = xunchar(*(srvcmd+3)); /* Length of name */
- n = 3 + n + 1; /* Position of length of value */
- *(srvcmd+n) = NUL; /* Don't need it */
- if (addmac((char *)(srvcmd+4),(char *)(srvcmd+n+1)) < 0)
- errpkt((CHAR *)"REMOTE ASSIGN failed");
- else {
- ack();
- success = 1;
- }
- RESUME;
- return(-1);
- }
- } else {
- errpkt((CHAR *)"Badly formed server command");
- RESUME;
- return(-1);
- }
-#else
- errpkt((CHAR *)"Variable query/set not available");
- RESUME;
- return(-1);
-#endif /* NOSPL */
-#endif /* NOSERVER */
-}
-
-static int
-srv_copy() {
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE COPY", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef ZCOPY
- if (!ENABLED(en_cpy)) {
- errpkt((CHAR *)"REMOTE COPY disabled");
- RESUME;
- return(-1);
- } else {
- char *str1, *str2, f1[256], f2[256];
- int len1, len2;
- len1 = xunchar(srvcmd[1]); /* Separate the parameters */
- len2 = xunchar(srvcmd[2+len1]);
- strncpy(f1,(char *)(srvcmd+2),len1);
- f1[len1] = NUL;
- strncpy(f2,(char *)(srvcmd+3+len1),len2);
- f2[len2] = NUL;
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE COPY", f1, f2);
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* If CWD is disabled */
- zstrip(f1,&str1); /* and they included a pathname, */
- zstrip(f2,&str2);
- if (strcmp(f1,str1) || strcmp(f2,str2)) { /* Refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- return(-1);
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
- if (zcopy(f1,f2)) { /* Try */
- errpkt((CHAR *)"Can't copy file"); /* give error message */
- } else {
- success = 1;
- ack();
- }
- RESUME; /* wait for next server command */
- return(-1);
- }
- }
- return(-1);
-#else /* no ZCOPY */
- errpkt((CHAR *)"REMOTE COPY not available"); /* give error message */
- RESUME; /* wait for next server command */
- return(-1);
-#endif /* ZCOPY */
-#endif /* NOSERVER */
-}
-
-static int
-srv_rename() {
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE RENAME", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef ZRENAME
- if (!ENABLED(en_ren)) {
- errpkt((CHAR *)"REMOTE RENAME disabled");
- RESUME;
- return(-1);
- } else { /* RENAME is enabled */
- char *str1, *str2, f1[256], f2[256];
- int len1, len2;
- len1 = xunchar(srvcmd[1]); /* Separate the parameters */
- len2 = xunchar(srvcmd[2+len1]);
- strncpy(f1,(char *)(srvcmd+2),len1);
- f1[len1] = NUL;
- strncpy(f2,(char *)(srvcmd+3+len1),len2);
- f2[len2] = NUL;
- len2 = xunchar(srvcmd[2+len1]);
- strncpy(f1,(char *)(srvcmd+2),len1);
- f1[len1] = NUL;
- strncpy(f2,(char *)(srvcmd+3+len1),len2);
- f2[len2] = NUL;
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE RENAME", f1, f2);
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* If CWD is disabled */
- zstrip(f1,&str1); /* and they included a pathname, */
- zstrip(f2,&str2);
- if ( strcmp(f1,str1) || strcmp(f2,str2) ) { /* refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- return(-1);
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
- if (zrename(f1,f2)) { /* Try */
- errpkt((CHAR *)"Can't rename file"); /* Give error msg */
- } else {
- success = 1;
- ack();
- }
- RESUME; /* Wait for next server command */
- return(-1);
- }
- }
- return(-1);
-#else /* no ZRENAME */
- /* Give error message */
- errpkt((CHAR *)"REMOTE RENAME not available");
- RESUME; /* Wait for next server command */
- return(-1);
-#endif /* ZRENAME */
-#endif /* NOSERVER */
-}
-
-static int
-srv_login() {
-#ifndef NOSERVER
- char f1[LOGINLEN+1], f2[LOGINLEN+1], f3[LOGINLEN+1];
- CHAR *p;
- int len, i;
-
- debug(F101,"REMOTE LOGIN x_login","",x_login);
- debug(F101,"REMOTE LOGIN x_logged","",x_logged);
-
- f1[0] = NUL; f2[0] = NUL; f3[0] = NUL;
- len = 0;
- if (srvcmd[1]) /* First length field */
- len = xunchar(srvcmd[1]); /* Separate the parameters */
-
- if (x_login) { /* Login required */
- if (x_logged) { /* And already logged in */
- if (len > 0) { /* Logging in again */
- errpkt((CHAR *)"Already logged in.");
- } else { /* Logging out */
- debug(F101,"REMOTE LOGOUT","",x_logged);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGOUT", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE LOGOUT", "", "");
-#endif /* IKSDB */
- tlog(F110,"Logged out",x_user,0);
- ack1((CHAR *)"Logged out");
- success = 1;
- msleep(500);
-#ifdef CK_LOGIN
- x_logged = 0;
-#ifdef IKSD
- if (inserver)
- ckxlogout();
-#endif /* IKSD */
-#endif /* CK_LOGIN */
- }
- } else { /* Not logged in yet */
- debug(F101,"REMOTE LOGIN len","",len);
- if (len > 0) { /* Have username */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGIN", NULL);
-#endif /* CKSYSLOG */
- if (len > LOGINLEN) {
- errpkt((CHAR *)"Username too long");
- }
- p = srvcmd + 2; /* Point to it */
- for (i = 0; i < len; i++) /* Copy it */
- f1[i] = p[i];
- f1[len] = NUL; /* Terminate it */
- p += len; /* Point to next length field */
- if (*p) { /* If we have one */
- len = xunchar(*p++); /* decode it */
- if (len > 0 && len <= LOGINLEN) {
- for (i = 0; i < len; i++) /* Same deal for password */
- f2[i] = p[i];
- f2[len] = NUL;
- p += len; /* And account */
- if (*p) {
- len = xunchar(*p++);
- if (len > 0 && len <= LOGINLEN) {
- for (i = 0; i < len; i++)
- f3[i] = p[i]; /* Set but never used */
- f3[len] = NUL; /* (because account not used) */
- }
- }
- }
- }
- debug(F101,"REMOTE LOGIN 1","",x_logged);
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver) { /* Log in to system for real */
- x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0);
- debug(F101,"REMOTE LOGIN 2","",x_logged);
- if (x_logged) { /* Count attempts */
- logtries = 0;
- justone = 1;
- } else {
- logtries++;
- sleep(logtries);
- }
- } else
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- if (x_user && x_passwd) { /* User and password must match */
- if (!strcmp(x_user,f1)) /* SET SERVER LOGIN */
- if (!strcmp(x_passwd,f2))
- x_logged = 1;
- debug(F101,"REMOTE LOGIN 3","",x_logged);
- } else if (x_user) { /* Only username given, no password */
- if (!strcmp(x_user,f1)) /* so only username must match */
- x_logged = 1;
- debug(F101,"REMOTE LOGIN 4","",x_logged);
- }
-#ifdef CK_LOGIN
- else {
- x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0);
- debug(F101,"REMOTE LOGIN 5","",x_logged);
- }
-#endif /* CK_LOGIN */
- if (x_logged) { /* Logged in? */
- tlog(F110,"Logged in", x_user, 0);
- if (isguest)
- ack1((CHAR *)"Logged in as guest - restrictions apply");
- else
- ack1((CHAR *)"Logged in");
- success = 1;
- } else {
- tlog(F110,"Login failed", f1, 0);
- errpkt((CHAR *)"Access denied.");
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && logtries > 2)
- ckxlogout();
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- }
- } else { /* LOGOUT */
- errpkt((CHAR *)"Logout ignored");
- }
- }
- } else { /* Login not required */
- if (len > 0)
- errpkt((CHAR *)"Login ignored.");
- else
- errpkt((CHAR *)"Logout ignored.");
- }
-#endif /* NOSERVER */
- RESUME;
- return(-1);
-}
-
-static int
-srv_timeout() {
- /* K95 does this its own way */
- if (idletmo) {
-#ifdef IKSD
- if (inserver) {
- printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", srvidl);
- doexit(GOOD_EXIT,xitsta);
- }
-#endif /* IKSD */
- idletmo = 0;
- printf("\r\nSERVER IDLE TIMEOUT: %d sec\r\n", srvidl);
- xitsta |= (what & W_KERMIT);
- QUIT;
- }
-#ifndef NOSERVER
- else if (fatalio) { /* Connection lost */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Connection lost", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"SERVER DISCONNECT",(char *)srvcmd, "");
-#endif /* IKSDB */
- xitsta |= what;
- QUIT;
- } else if (interrupted) { /* Interrupted by hand */
- if (!ENABLED(en_fin)) {
- errpkt((CHAR *)"QUIT disabled");
- RESUME;
- return(-1);
- } else {
- if (what == W_SEND || what == W_RECV || what == W_REMO) {
- success = 0;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
-#endif /* CKSYSLOG */
- } else if (what == W_NOTHING && filcnt == 0) {
- success = 1;
- } /* Otherwise leave success alone */
- xitsta |= (what & W_KERMIT);
- QUIT;
- }
- } else { /* Shouldn't happen */
- debug(F100,"SERVER (top) GOT UNEXPECTED 'q'","",0);
- QUIT;
- }
-#endif /* NOSERVER */
-}
-
-static int
-rcv_s_pkt() {
-#ifndef NOSERVER
- if (state == rgen)
- urserver = 1;
- if (/* state == serve && */ x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else
-#endif /* NOSERVER */
- if (state == serve && !ENABLED(en_sen)) { /* Not in server mode */
- errpkt((CHAR *)"SEND disabled"); /* when SEND is disabled. */
- RESUME;
- return(-1);
- } else { /* OK to go ahead. */
-#ifdef CK_TMPDIR
- if (dldir && !f_tmpdir) { /* If they have a download directory */
- debug(F110,"receive download dir",dldir,0);
- if (s = zgtdir()) { /* Get current directory */
- debug(F110,"receive current dir",s,0);
- if (zchdir(dldir)) { /* Change to download directory */
- debug(F100,"receive zchdir ok","",0);
- ckstrncpy(savdir,s,TMPDIRLEN);
- f_tmpdir = 1; /* Remember that we did this */
- } else
- debug(F100,"receive zchdir failed","",0);
- }
- }
-#endif /* CK_TMPDIR */
- nakstate = 1; /* Can send NAKs from here. */
- rinit(rdatap); /* Set parameters */
- bctu = bctr; /* Switch to agreed-upon block check */
- bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */
- what = W_RECV; /* Remember we're receiving */
- lastxfer = W_RECV;
- resetc(); /* Reset counters */
- rtimer(); /* Reset timer */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- streamon();
- BEGIN rfile; /* Go into receive-file state */
- }
- return(-1);
-}
-
-
-/* END OF ROUTINES MOVED OUT OF STATE MACHINE */
-
-
-/* P R O T O -- Protocol entry function */
-
-static int is_tn = 0; /* It's a Telnet connection */
-
-#ifdef CK_SPEED
-int f_ctlp = 0; /* Control-character prefix table */
-#ifdef COMMENT
-short s_ctlp[256];
-#endif /* COMMENT */
-#endif /* CK_SPEED */
-
-/*
- This is simply a wrapper for the real protocol function just below,
- that saves any items that might be changed automatically by protocol
- negotiations and then restores them upon exit from protocol mode.
-*/
-VOID
-proto() {
- extern int b_save, f_save, c_save, ss_save, slostart, reliable, urclear;
-#ifndef NOCSETS
- extern int fcharset, fcs_save, tcharset, tcs_save;
-#endif /* NOCSETS */
-
-#ifdef PIPESEND
- extern int pipesend;
-#endif /* PIPESEND */
-#ifndef NOLOCAL
-#ifdef OS2
- extern int cursorena[], cursor_save, term_io;
- extern BYTE vmode;
- extern int display_demo;
- int term_io_save;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef TNCODE
- int _u_bin=0, _me_bin = 0;
-#ifdef IKS_OPTION
- int /* _u_start=0, */ _me_start = 0;
-#endif /* IKS_OPTION */
-#endif /* TNCODE */
-#ifdef PATTERNS
- int pa_save;
- int i;
-#endif /* PATTERNS */
- int scan_save;
-
-#ifdef PATTERNS
- pa_save = patterns;
-#endif /* PATTERNS */
- scan_save = filepeek;
-
- myjob = sstate;
-
-#ifdef CK_LOGIN
- if (isguest) { /* If user is anonymous */
- en_pri = 0; /* disable printing */
- en_mai = 0; /* and disable email */
- en_del = 0; /* and file deletion */
- }
-#endif /* CK_LOGIN */
-
-#ifndef NOLOCAL
-#ifdef OS2
- cursor_save = cursorena[vmode];
- cursorena[vmode] = 0;
- term_io_save = term_io;
- term_io = 0;
-#endif /* OS2 */
-#endif /* NOLOCAL */
- b_save = binary; /* SET FILE TYPE */
- f_save = fncnv; /* SET FILE NAMES */
- c_save = bctr;
- p_save = fnspath;
- r_save = recursive;
- s_timint = timint;
- ss_save = slostart;
-#ifndef NOCSETS
- fcs_save = fcharset;
- tcs_save = tcharset;
-#endif /* NOCSETS */
-
-#ifdef COMMENT
-/* Don't do this because then user can never find out what happened. */
-#ifdef CK_SPEED
- for (i = 0; i < 256; i++)
- s_ctlp[i] = ctlp[i];
- f_ctlp = 1;
-#endif /* CK_SPEED */
-#endif /* COMMENT */
- if (reliable == SET_ON)
- slostart = 0;
- is_tn = (!local && sstelnet)
-#ifdef TNCODE
- || (local && network && ttnproto == NP_TELNET)
-#endif /* TNCODE */
- ;
-#ifdef TNCODE
- if (is_tn) {
- if (tn_b_xfer && !(sstelnet || inserver)) {
- /* Save the current state of Telnet Binary */
- _u_bin = TELOPT_U(TELOPT_BINARY);
- _me_bin = TELOPT_ME(TELOPT_BINARY);
-
- /* If either direction is not Binary attempt to negotiate it */
- if (!_u_bin && TELOPT_U_MODE(TELOPT_BINARY) != TN_NG_RF) {
- tn_sopt(DO,TELOPT_BINARY);
- TELOPT_UNANSWERED_DO(TELOPT_BINARY) = 1;
- }
- if (!_me_bin && TELOPT_ME_MODE(TELOPT_BINARY) != TN_NG_RF) {
- tn_sopt(WILL,TELOPT_BINARY);
- TELOPT_UNANSWERED_WILL(TELOPT_BINARY) = 1;
- }
- if (!(_me_bin && _u_bin))
- tn_wait("proto set binary mode");
- }
-#ifdef IKS_OPTION
-#ifdef CK_XYZ
- if (protocol != PROTO_K) { /* Non-Kermit protocol selected */
- if (TELOPT_U(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */
- /* _u_start = 1; */
- }
- if (TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_STOP); /* I'm not servering */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- _me_start = 1;
- }
- } else
-#endif /* CK_XYZ */
- if (sstate == 'x' || sstate == 'v') { /* Responding to a request */
- if (!inserver && TELOPT_U(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */
- /* _u_start = 1; */
- }
- if (TELOPT_ME(TELOPT_KERMIT) &&
- !TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_START); /* Send Kermit-Server Start */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 1;
- }
- } else { /* Initiating a request */
- if (TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_STOP); /* I'm not servering */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- _me_start = 1;
- }
- if (TELOPT_U(TELOPT_KERMIT) &&
- !TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- /* Send Req-Server-Start */
- if (!iks_wait(KERMIT_REQ_START,0)) {
- if (sstate != 's') {
- success = 0; /* Other Kermit refused to serve */
- if (local)
- printf("A Kermit Server is not available\r\n");
- debug(F110,"proto()",
- "A Kermit Server is not available",0);
- tlog(F110,"IKS client/server failure",
- "A Kermit Server is not available",0);
- goto xxprotox;
- }
- }
- }
- }
-#endif /* IKS_OPTION */
-#ifdef CK_ENCRYPTION
- if (tn_no_encrypt_xfer && !(sstelnet || inserver)) {
- ck_tn_enc_stop();
- }
-#endif /* CK_ENCRYPTION */
- }
-#endif /* TNCODE */
-
- if (!xfrint) connoi();
- xxproto(); /* Call the real protocol function */
-
-#ifdef IKS_OPTION
- xxprotox:
-#endif /* IKS_OPTION */
- xferstat = success; /* Remember transfer status */
- kactive = 0;
-
-#ifdef TNCODE
-#ifdef CK_ENCRYPTION
- if (tn_no_encrypt_xfer && !(sstelnet || inserver)) {
- ck_tn_enc_start();
- }
-#endif /* CK_ENCRYPTION */
-#ifdef IKS_OPTION
- if (TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start && !_me_start) {
- tn_siks(KERMIT_STOP); /* Server is stopped */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- }
-#endif /* IKS_OPTION */
- if (is_tn && tn_b_xfer && !(sstelnet || inserver)) {
- /* if we negotiated Binary mode try to reset it */
- if (!_u_bin) {
- /* Check to see if the state changed during the transfer */
- if (TELOPT_U(TELOPT_BINARY)) {
- tn_sopt(DONT,TELOPT_BINARY);
- TELOPT_UNANSWERED_DONT(TELOPT_BINARY) = 1;
- } else
- _u_bin = 1; /* So we don't call tn_wait() */
- }
- if (!_me_bin) {
- /* Check to see if the state changed during the transfer */
- if (TELOPT_ME(TELOPT_BINARY)) {
- tn_sopt(WONT,TELOPT_BINARY);
- TELOPT_UNANSWERED_WONT(TELOPT_BINARY) = 1;
- } else
- _me_bin = 1; /* So we don't call tn_wait() */
- }
- if (!(_me_bin && _u_bin))
- tn_wait("proto reset binary mode");
- }
-#endif /* TNCODE */
-
-#ifdef PATTERNS
- patterns = pa_save;
-#endif /* PATTERNS */
- filepeek = scan_save;
-
-#ifdef STREAMING
- streaming = 0;
- /* streamok = 0; */
-#endif /* STREAMING */
-#ifdef COMMENT
-#ifdef CK_SPEED
- for (i = 0; i < 256; i++)
- ctlp[i] = s_ctlp[i];
- f_ctlp = 0;
-#endif /* CK_SPEED */
-#endif /* COMMENT */
- urclear = 0;
- if (!success) {
- xitsta |= (what & W_KERMIT);
- tlog(F110," failed:",(char *)epktmsg,0);
- }
- debug(F111,"proto xferstat",epktmsg,xferstat);
- slostart = ss_save;
- if (s_timint > -1) { /* Because of REMOTE SET */
- timint = s_timint;
- s_timint = -1;
- }
- recursive = r_save;
- fnspath = p_save;
- if (c_save > -1) { /* Because of REMOTE SET */
- bctr = c_save;
- c_save = -1;
- }
- fncnv = f_save;
- binary = b_save;
-#ifdef PIPESEND
- pipesend = 0; /* Next time might not be pipesend */
-#endif /* PIPESEND */
-#ifndef NOLOCAL
-#ifdef OS2
- cursorena[vmode] = cursor_save;
- term_io = term_io_save;
- display_demo = 1;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-}
-
-static VOID
-xxproto() {
- int x;
- long lx;
-#ifdef CK_XYZ
-#ifdef XYZ_INTERNAL
-_PROTOTYP( int pxyz, (int) );
-#endif /* XYZ_INTERNAL */
-#endif /* CK_XYZ */
-
- char xss[2]; /* String representation of sstate */
- xss[0] = sstate;
- xss[1] = NUL;
- s_timint = timint;
-
- debug(F101,"xxproto entry justone","",justone);
- success = 0;
-
- retrieve = 0; /* Reset these ... */
- reget = 0;
- opkt = 0;
-
- if (local && ttchk() < 0) { /* Giving BYE or FIN */
- if (bye_active) { /* but there is no connection */
- ttclos(0);
- success = 1;
- return;
- }
- /* Ditto for any REMOTE command */
- if (sstate == 'g' && cmarg ) {
- if (*cmarg == 'L' || *cmarg == 'F' || *cmarg == 'X')
- success = 1;
- else
- printf("?No connection\r\n");
- return;
- }
- }
-
-/* Set up the communication line for file transfer. */
-/* NOTE: All of the xxscreen() calls prior to the wart() invocation */
-/* could just as easily be printf's or, for that matter, hints. */
-
- if (local && (speed < 0L) && (network == 0)) {
- xxscreen(SCR_EM,0,0L,"Sorry, you must 'set speed' first");
- return;
- }
- x = -1;
- if (ttopen(ttname,&x,mdmtyp,cdtimo) < 0) {
- debug(F111,"failed: proto ttopen local",ttname,local);
- xxscreen(SCR_EM,0,0L,"Can't open line");
- return;
- }
- if (x > -1) local = x;
- debug(F111,"proto ttopen local",ttname,local);
-
- lx = (local && !network) ? speed : -1;
-#ifdef NETCONN
-#ifdef CK_SPEED
- if (is_tn) {
- ctlp[(unsigned)255] = ctlp[CR] = 1;
- if (parity == 'e' || parity == 'm') ctlp[127] = 1;
- if (flow == FLO_XONX) { /* Also watch out for Xon/Xoff */
- ctlp[17] = ctlp[19] = 1;
- ctlp[17+128] = ctlp[19+128] = 1;
- }
- }
-#endif /* CK_SPEED */
-#endif /* NETCONN */
- if (ttpkt(lx,flow,parity) < 0) { /* Put line in packet mode, */
- xxscreen(SCR_EM,0,0L,"Can't condition line");
- return;
- }
- if (local && !network && carrier != CAR_OFF) {
- int x; /* Serial connection */
- x = ttgmdm(); /* with carrier checking */
- if (x > -1) {
- if (!(x & BM_DCD)) {
- debug(F101,"proto ttgmdm","",0);
- xxscreen(SCR_EM,0,0L,"Carrier required but not detected");
- return;
- }
- }
- }
- /* Send remote side's "receive" or "server" startup string, if any */
- if (local && ckindex((char *)xss,"srgcjhk",0,0,1)) {
- char *s = NULL;
- if (
-#ifdef IKS_OPTION
- /* Don't send auto-blah string if we know other side is serving */
- !TELOPT_U(TELOPT_KERMIT) ||
- !TELOPT_SB(TELOPT_KERMIT).kermit.u_start
-#else
- 1
-#endif /* IKS_OPTION */
- ) {
- if (sstate == 's') { /* Sending file(s) */
- s = binary ? ptab[protocol].h_b_init : ptab[protocol].h_t_init;
- } else if (protocol == PROTO_K) { /* Command for server */
- s = ptab[protocol].h_x_init;
- }
- }
-#ifdef CK_SPEED
-#ifndef UNPREFIXZERO
- if (protocol == PROTO_K) /* Because of C-strings... */
- ctlp[0] = 1;
-#endif /* UNPREFIXZERO */
-#endif /* CK_SPEED */
- if (s) if (*s) { /* If we have a command to send... */
- char tmpbuf[356];
- int tmpbufsiz = 356;
- int stuff = -1, stuff2 = -1, len = 0;
- extern int tnlm;
- if (sstate == 's') { /* Sending file(s) */
-#ifdef CK_XYZ
- if (protocol == PROTO_X) {
- char * s2;
- s2 = cmarg2[0] ? cmarg2 : cmarg;
- if ((int)strlen(s) + (int)strlen(s2) + 4 < 356)
- sprintf(tmpbuf, s, s2);
- else
- tmpbuf[0] = NUL;
- } else {
-#endif /* CK_XYZ */
- ckmakmsg(tmpbuf, 356, s, NULL, NULL, NULL);
-#ifdef CK_XYZ
- }
-#endif /* CK_XYZ */
- } else { /* Command for server */
- ckstrncpy(tmpbuf,s,356);
- }
- ckstrncat(tmpbuf, "\015",sizeof(tmpbuf));
- if (tnlm) /* TERMINAL NEWLINE ON */
- stuff = LF; /* Stuff LF */
-#ifdef TNCODE
- /* TELNET NEWLINE MODE */
- if (is_tn) {
- switch (TELOPT_ME(TELOPT_BINARY) ? tn_b_nlm : tn_nlm) {
- case TNL_CR:
- break;
- case TNL_CRNUL:
- break;
- case TNL_CRLF:
- stuff2 = stuff;
- stuff = LF;
- break;
- }
- }
-#endif /* TNCODE */
-
-#ifdef NETCONN
-#ifdef TCPSOCKET
-#ifdef RLOGCODE
- if (network && ttnproto == NP_RLOGIN) {
- switch (tn_b_nlm) { /* Always BINARY */
- case TNL_CR:
- break;
- case TNL_CRNUL:
- stuff2 = stuff;
- stuff = NUL;
- break;
- case TNL_CRLF:
- stuff2 = stuff;
- stuff = LF;
- break;
- }
- }
-#endif /* RLOGCODE */
-#endif /* TCPSOCKET */
-#endif /* NETCONN */
-
- len = strlen(tmpbuf);
- if (stuff >= 0 && len < tmpbufsiz - 1) {
- tmpbuf[len++] = stuff;
- if (stuff2 >= 0 && len < tmpbufsiz - 1)
- tmpbuf[len++] = stuff2;
- tmpbuf[len] = NUL;
- }
- ttol((CHAR *)tmpbuf,len);
- if (protocol == PROTO_K) /* Give remote Kermit time to start */
- msleep(400);
- }
- }
-
-#ifdef CK_XYZ
- if (protocol != PROTO_K) { /* Non-Kermit protocol selected */
- char tmpbuf[356];
- int tmpbufsiz = 356;
- char * s = "";
-
-#ifdef CK_TMPDIR
- if (sstate == 'v') { /* If receiving and... */
- if (dldir && !f_tmpdir) { /* if they have a download directory */
- if (s = zgtdir()) { /* Get current directory */
- if (zchdir(dldir)) { /* Change to download directory */
- ckstrncpy(savdir,s,TMPDIRLEN);
- f_tmpdir = 1; /* Remember that we did this */
- }
- }
- }
- }
-#endif /* CK_TMPDIR */
-
-#ifdef XYZ_INTERNAL /* Internal */
- success = !pxyz(sstate);
-#else
-#ifdef CK_REDIR /* External */
- switch (sstate) {
- case 's': /* 'Tis better to SEND... */
- s = binary ? ptab[protocol].p_b_scmd : ptab[protocol].p_t_scmd;
- break;
- case 'v': /* ... than RECEIVE */
- s = binary ? ptab[protocol].p_b_rcmd : ptab[protocol].p_t_rcmd;
- break;
- }
- if (!s) s = "";
- if (*s) {
- if (sstate == 's') { /* Sending */
- extern int xfermode;
- int k = 0, x = 0, b = binary;
- /*
- If just one file we can scan it to set the xfer mode.
- Otherwise it's up to the external protocol program.
- */
- if (patterns && xfermode == XMODE_A && !iswild(fspec)) {
- extern int nscanfile;
- k = scanfile(fspec,&x,nscanfile);
- if (k > -1) {
- b = (k == FT_BIN) ? XYFT_B : XYFT_T;
- s = b ?
- ptab[protocol].p_b_scmd :
- ptab[protocol].p_t_scmd;
- }
- }
- if ((int)strlen(s) + (int)strlen(fspec) < tmpbufsiz) {
- sprintf(tmpbuf,s,fspec); /* safe (prechecked) */
- tlog(F110,"Sending",fspec,0L);
- }
- } else { /* Receiving */
- if ((int)strlen(s) + (int)strlen(cmarg2) < tmpbufsiz) {
- sprintf(tmpbuf,s,cmarg2); /* safe (prechecked) */
- tlog(F110,"Receiving",cmarg2,0L);
- }
- }
- tlog(F110," via external protocol:",tmpbuf,0);
- debug(F110,"ckcpro ttruncmd",tmpbuf,0);
- success = ttruncmd(tmpbuf);
- tlog(F110," status:",success ? "OK" : "FAILED", 0);
- } else {
- printf("?Sorry, no external protocol defined for %s\r\n",
- ptab[protocol].p_name
- );
- }
-#else
- printf(
-"Sorry, only Kermit protocol is supported in this version of Kermit\n"
- );
-#endif /* CK_REDIR */
-#endif /* XYZ_INTERNAL */
- return;
- }
-#endif /* CK_XYZ */
-
-#ifdef NTSIGX
- conraw();
- connoi();
-#else
- if (!local)
- connoi(); /* No console interrupts if remote */
-#endif /* NTSIG */
-
- kactive = 1;
- if (sstate == 'x') { /* If entering server mode, */
- extern int howcalled;
- server = 1; /* set flag, */
- debug(F101,"server backgrd","",backgrd);
- debug(F101,"server quiet","",quiet);
- debug(F100,"SHOULD NOT SEE THIS IF IN BACKGROUND!","",0);
- if (howcalled == I_AM_SSHSUB) { /* and issue appropriate message. */
- ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26);
- } else if (!local) {
- if (!quiet && !backgrd
-#ifdef IKS_OPTION
- && !TELOPT_ME(TELOPT_KERMIT) /* User was told by negotiation */
-#endif /* IKS_OPTION */
- ) {
- conoll(srvtxt);
- conoll("KERMIT READY TO SERVE...");
- }
- } else {
- conol("Entering server mode on ");
- conoll(ttname);
- conoll("Type Ctrl-C to quit.");
- if (srvdis) intmsg(-1L);
-#ifdef TCPSOCKET
-#ifndef NOLISTEN
- if (network && tcpsrfd > 0)
- ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26);
-#endif /* NOLISTEN */
-#endif /* TCPSOCKET */
- }
- } else
- server = 0;
-#ifdef VMS
- if (!quiet && !backgrd) /* So message doesn't overwrite prompt */
- conoll("");
- if (local) conres(); /* So Ctrl-C will work */
-#endif /* VMS */
-/*
- If in remote mode, not shushed, not in background, and at top command level,
- issue a helpful message telling what to do...
-*/
- if (!local && !quiet && !backgrd) {
- if (sstate == 'v') {
- conoll("Return to your local Kermit and give a SEND command.");
- conoll("");
- conoll("KERMIT READY TO RECEIVE...");
- } else if (sstate == 's') {
- conoll("Return to your local Kermit and give a RECEIVE command.");
- conoll("");
- conoll("KERMIT READY TO SEND...");
- } else if ( sstate == 'g' || sstate == 'r' || sstate == 'h' ||
- sstate == 'j' || sstate == 'c' ) {
- conoll("Return to your local Kermit and give a SERVER command.");
- conoll("");
- conoll((sstate == 'r' || sstate == 'j' || sstate == 'h') ?
- "KERMIT READY TO GET..." :
- "KERMIT READY TO SEND SERVER COMMAND...");
- }
- }
-#ifdef COMMENT
- if (!local) sleep(1);
-#endif /* COMMENT */
-/*
- The 'wart()' function is generated by the wart program. It gets a
- character from the input() routine and then based on that character and
- the current state, selects the appropriate action, according to the state
- table above, which is transformed by the wart program into a big case
- statement. The function is active for one transaction.
-*/
- rtimer(); /* Reset elapsed-time timer */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- resetc(); /* & other per-transaction counters. */
-
- debug(F101,"proto calling wart, justone","",justone);
-
- wart(); /* Enter the state table switcher. */
-/*
- Note: the following is necessary in case we have just done a remote-mode
- file transfer, in which case the controlling terminal modes have been
- changed by ttpkt(). In particular, special characters like Ctrl-C and
- Ctrl-\ might have been turned off (see ttpkt). So this call to ttres() is
- essential. IMPORTANT: restore interrupt handlers first, otherwise any
- terminal interrupts that occur before this is done in the normal place
- later will cause a crash.
-*/
-#ifdef OS2
- ttres(); /* Reset the communication device */
-#else
- if (!local) {
- setint(); /* Arm interrupt handlers FIRST */
- msleep(500);
- ttres(); /* Then restore terminal. */
- }
-#endif /* OS2 */
- xxscreen(SCR_TC,0,0L,""); /* Transaction complete */
- x = quiet;
- quiet=1;
- clsif(); /* Failsafe in case we missed */
- clsof(1); /* a case in the state machine. */
- quiet = x;
-
- if (server) { /* Back from packet protocol. */
- if (!quiet && !backgrd
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- ) { /* Give appropriate message */
- conoll("");
- conoll("C-Kermit server done");
- }
- server = 0; /* Not a server any more */
- }
-}
-
-/* S G E T I N I T -- Handle incoming GET-Class packets */
-
-/*
- Returns:
- -1: On error
- 0: GET packet processed OK - ready to Send.
- 1: Extended GET processed OK - wait for another.
-*/
-static int
-sgetinit(reget,xget) int reget, xget; { /* Server end of GET command */
- char * fs = NULL; /* Pointer to filespec */
- int i, n, done = 0;
-#ifdef PIPESEND
- extern int usepipes, pipesend;
-#endif /* PIPESEND */
- extern int nolinks;
-
- if (!ENABLED(en_get)) { /* Only if not disabled! */
- errpkt((CHAR *)"GET disabled");
- return(-1);
- }
-
- /* OK to proceed */
-
- nolinks = recursive;
- filcnt = 0;
-
-#ifdef WHATAMI
- /* If they are alike this was already done in whoarewe() */
- debug(F101,"sgetinit whatru","",whatru);
- if (whatru & WMI_FLAG) { /* Did we get WHATAMI info? */
- debug(F101,"sgetinit binary (1)","",binary);
-#ifdef VMS
- if (binary != XYFT_I && binary != XYFT_L)
-#else
-#ifdef OS2
- if (binary != XYFT_L)
-#endif /* OS2 */
-#endif /* VMS */
- binary = (whatru & WMI_FMODE) ? /* Yes, set file type */
- XYFT_B : XYFT_T; /* automatically */
- debug(F101,"sgetinit binary (2)","",binary);
- if (!wearealike)
- fncnv = (whatru & WMI_FNAME) ? 1 : 0; /* And name conversion */
- }
-#endif /* WHATAMI */
-
- fs = (char *)srvcmd;
- srvptr = srvcmd; /* Point to server command buffer */
- decode(rdatap,putsrv,0); /* Decode the GET command into it */
- /* Accept multiple filespecs */
- cmarg2 = ""; /* Don't use cmarg2 */
- cmarg = ""; /* Don't use cmarg */
-
- done = 1; /* Only 1 packet needed... */
- if (xget) { /* Special decoding for Extended GET */
- char L, next, c; /* PLV items */
- int len, val; /* More PLV items */
- char * p = (char *)srvcmd; /* String to decode */
-
- done = 0; /* Maybe more packets needed */
- fs = NULL; /* We don't know the filespec yet */
- c = *p++; /* Get first parameter */
-
- while (c) { /* For all parameters... */
- debug(F000,"sgetinit c","",c);
- L = *p++; /* Get length */
- if (L >= SP) /* Decode length */
- len = xunchar(L);
- else if (c == '@') { /* Allow missing EOP length field */
- len = 0;
- } else {
- len = (xunchar(*p++) * 95);
- len += xunchar(*p++);
- }
- debug(F101,"sgetinit len","",len);
- next = *(p+len); /* Get next parameter */
- *(p+len) = NUL; /* Zero it out to terminal value */
- debug(F110,"sgetinit p",p,0);
- switch (c) { /* Do the parameter */
- case 'O': /* GET Options */
- val = atoi(p); /* Convert to int */
- debug(F101,"sgetinit O val","",val);
- if (val & GOPT_DEL) moving = 1;
- if (val & GOPT_RES) reget = 1;
- if (val & GOPT_REC) {
- recursive = 1;
- nolinks = 2;
- if (fnspath == PATH_OFF)
- fnspath = PATH_REL;
- }
- break;
- case 'M': /* Transfer Mode */
- val = atoi(p);
- debug(F101,"sgetinit M val","",val);
- if (val < 1)
- break;
- patterns = 0; /* Takes precedence over patterns */
- filepeek = 0; /* and FILE SCAN */
- if (val == GMOD_TXT) binary = XYFT_T; /* Text */
- if (val == GMOD_BIN) binary = XYFT_B; /* Binary */
- if (val == GMOD_LBL) binary = XYFT_L; /* Labeled */
- break;
- case 'F': /* Filename */
- fs = p;
- debug(F110,"sgetinit filename",fs,0);
- break;
- case '@': /* End Of Parameters */
- done = 1;
- debug(F100,"sgetinit EOP","",0);
- break;
- default:
- errpkt((CHAR *)"Unknown GET Parameter");
- debug(F100,"sgetinit unknown parameter","",0);
- return(-1);
- }
- p += (len + 1);
- c = next;
- }
- }
- if (!fs) fs = ""; /* A filename is required */
- if (*fs) {
- havefs = 1;
- n = 0; /* Check for quoted name */
- if ((n = strlen(fs)) > 1) {
- /* Note: this does not allow for multiple quoted names */
- if ((fs[0] == '{' && fs[n-1] == '}') ||
- (fs[0] == '"' && fs[n-1] == '"')) {
- fs[n-1] = '\0';
- fs++;
- debug(F111,"sgetinit unquoted filename",fs,n);
- } else
- n = 0; /* This means no quoting */
- }
-
-#ifdef PIPESEND
- debug(F111,"sgetinit",fs,usepipes);
- if (usepipes && ENABLED(en_hos) && *fs == '!') {
- cmarg = fs + 1; /* Point past the bang */
- *fs = NUL;
- nfils = -1;
- pipesend = 1;
- debug(F111,"sgetinit pipesend",cmarg,pipesend);
- }
- if (!pipesend) { /* If it's not a pipe */
-#endif /* PIPESEND */
- if (n == 0) { /* If the name was not quoted */
-#ifndef NOMSEND
- nfils = fnparse(fs); /* Allow it to be a list of names */
- debug(F111,"sgetinit A",fs,nfils);
-#ifdef COMMENT
-/* This doesn't work if a GET-PATH is set. */
- if (nfils == 1 && !iswild(fs)) { /* Single file */
- char * m;
- if ((x = zchki(fs)) < 0) { /* Check if it's sendable */
- switch (x) {
- case -1: m = "File not found"; break;
- case -2: m = "Not a regular file"; break;
- case -3: m = "Read access denied"; break;
- }
- errpkt((CHAR *)m);
- return(-1);
- }
- }
-#endif /* COMMENT */
- } else { /* If it was quoted */
-#endif /* NOMSEND */
- nzxopts = 0;
-#ifdef UNIXOROSK
- if (matchdot) nzxopts |= ZX_MATCHDOT;
-#endif /* UNIXOROSK */
- if (recursive) nzxopts |= ZX_RECURSE;
- /* Treat as a single filespec */
- nfils = 0 - nzxpand(fs,nzxopts);
- debug(F111,"sgetinit B",fs,nfils);
- cmarg = fs;
- }
-#ifdef PIPESEND
- }
-#endif /* PIPESEND */
- }
- if (!done) { /* Need more O packets... */
- debug(F100,"sgetinit O-Packet TBC","",0); /* To Be Continued */
- return(1);
- }
- debug(F100,"sgetinit O-Packet done - havefs","",havefs);
- if (!havefs) { /* Done - make sure we have filename */
- errpkt((CHAR *)"GET without filename");
- return(-1);
- }
- freerpkt(winlo);
- winlo = 0; /* Back to packet 0 again. */
- debug(F101,"sgetinit winlo","",winlo);
- nakstate = 0; /* Now I'm the sender! */
- if (reget) sendmode = SM_RESEND;
- if (sinit() > 0) { /* Send Send-Init */
-#ifdef STREAMING
- if (!streaming)
-#endif /* STREAMING */
- timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
- return(0); /* If successful, switch state */
- } else return(-1); /* Else back to server command wait */
-}
-
-#else /* NOXFER */
-
-#include "ckcdeb.h"
-
-VOID
-proto() {
- extern int success;
- success = 0;
-}
-#endif /* NOXFER */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcpro.w b/ckermit-9.0.302-build/ckermit-9.0.302/ckcpro.w
deleted file mode 100644
index a6b5f48..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcpro.w
+++ /dev/null
@@ -1,3633 +0,0 @@
-char *protv = /* -*-C-*- */
-"C-Kermit Protocol Module 9.0.160, 16 Oct 2009";
-
-int kactive = 0; /* Kermit protocol is active */
-
-#define PKTZEROHACK
-
-/* C K C P R O -- C-Kermit Protocol Module, in Wart preprocessor notation. */
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#ifndef NOXFER
-#include "ckcsym.h"
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#ifdef OS2
-#ifndef NT
-#define INCL_NOPM
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#endif /* NT */
-#include "ckocon.h"
-#endif /* OS2 */
-
-/*
- Note -- This file may also be preprocessed by the UNIX Lex program, but
- you must indent the above #include statements before using Lex, and then
- restore them to the left margin in the resulting C program before compilation.
- Also, the invocation of the "wart()" function below must be replaced by an
- invocation of the "yylex()" function. It might also be necessary to remove
- comments in the (%)(%)...(%)(%) section.
-*/
-
-/* State definitions for Wart (or Lex) */
-%states ipkt rfile rattr rdpkt ssinit ssfile ssattr ssdata sseof sseot
-%states serve generic get rgen ssopkt ropkt
-
-_PROTOTYP(static VOID xxproto,(void));
-_PROTOTYP(static VOID wheremsg,(void));
-_PROTOTYP(int wart,(void));
-_PROTOTYP(static int sgetinit,(int,int));
-_PROTOTYP(int sndspace,(int));
-
-/* External C-Kermit variable declarations */
- extern char *versio, *srvtxt, *cmarg, *cmarg2, **cmlist, *rf_err;
- extern char * rfspec, * sfspec, * srfspec, * rrfspec;
- extern char * prfspec, * psfspec, * psrfspec, * prrfspec;
- extern char *cdmsgfile[];
- extern char * snd_move, * snd_rename, * srimsg;
- extern char filnam[], ofilnam[], fspec[], ttname[], ofn1[];
- extern CHAR sstate, *srvptr, *data;
- extern int timint, rtimo, nfils, hcflg, xflg, flow, mdmtyp, network;
- extern int oopts, omode, oname, opath, nopush, isguest, xcmdsrc, rcdactive;
- extern int rejection, moving, fncact, bye_active, urserver, fatalio;
- extern int protocol, prefixing, filcnt, carrier, fnspath, interrupted;
- extern int recursive, inserver, nzxopts, idletmo, srvidl, xfrint;
- extern struct ck_p ptab[];
- extern int remfile, rempipe, xferstat, filestatus, wearealike, fackpath;
- extern int patterns, filepeek, gnferror;
- extern char * remdest;
-
-#ifdef PKTZEROHACK
-#define PKTZEROLEN 32
-static char ipktack[PKTZEROLEN];
-static int ipktlen = 0;
-#endif /* PKTZEROHACK */
-
-static int s_timint = -1; /* For saving timeout value */
-static int myjob = 0;
-static int havefs = 0;
-#ifdef CK_LOGIN
-static int logtries = 0;
-#endif /* CK_LOGIN */
-
-static int cancel = 0;
-int fackbug = 0;
-
-#ifdef STREAMING
-extern int streaming, streamok;
-
-static VOID
-streamon() {
- if (streamok) {
- debug(F100,"streamon","",0);
- streaming = 1;
- timint = 0; /* No timeouts while streaming. */
- }
-}
-
-#ifdef COMMENT /* (not used) */
-static VOID
-streamoff() {
- if (streaming) {
- debug(F100,"streamoff","",0);
- streaming = 0;
- timint = s_timint; /* Restore timeout */
- }
-}
-#endif /* COMMENT */
-#else /* STREAMING */
-#define streamon()
-#define streamoff()
-#endif /* STREAMING */
-
-#ifndef NOSPL
-_PROTOTYP( int addmac, (char *, char *) );
-_PROTOTYP( int zzstring, (char *, char **, int *) );
-#endif /* NOSPL */
-#ifndef NOICP
-_PROTOTYP( int cmdsrc, (void) );
-#endif /* NOICP */
-
-#ifndef NOSERVER
- extern char * x_user, * x_passwd, * x_acct;
- extern int x_login, x_logged;
-#endif /* NOSERVER */
-
-#include "ckcnet.h"
-
-#ifdef TNCODE
- extern int ttnproto; /* Network protocol */
-#endif /* TNCODE */
-
-#ifdef CK_SPEED
- extern short ctlp[]; /* Control-character prefix table */
-#endif /* CK_SPEED */
-
-#ifdef TNCODE
- extern int tn_b_nlm, tn_b_xfer, tn_nlm;
-#ifdef CK_ENCRYPTION
- extern int tn_no_encrypt_xfer;
-#endif /* CK_ENCRYPTION */
-#endif /* TNCODE */
-
-#ifdef TCPSOCKET
-#ifndef NOLISTEN
- extern int tcpsrfd;
-#endif /* NOLISTEN */
-#endif /* TCPSOCKET */
-
- extern int cxseen, czseen, server, srvdis, local, displa, bctu, bctr, bctl;
- extern int bctf;
- extern int quiet, tsecs, parity, backgrd, nakstate, atcapu, wslotn, winlo;
- extern int wslots, success, xitsta, rprintf, discard, cdtimo, keep, fdispla;
- extern int timef, stdinf, rscapu, sendmode, epktflg, epktrcvd, epktsent;
- extern int binary, fncnv;
- extern long speed, ffc, crc16, calibrate, dest;
-#ifdef COMMENT
- extern char *TYPCMD, *DIRCMD, *DIRCM2;
-#endif /* COMMENT */
-#ifndef OS2
- extern char *SPACMD, *SPACM2, *WHOCMD;
-#endif /* OS2 */
- extern CHAR *rdatap;
- extern struct zattr iattr;
-
-#ifdef VMS
- extern int batch;
-#endif /* VMS */
-
-#ifdef GFTIMER
- extern CKFLOAT fptsecs;
-#endif /* GFTIMER */
-
- extern CHAR *srvcmd;
- extern CHAR *epktmsg;
-
-#ifdef CK_TMPDIR
-extern int f_tmpdir; /* Directory changed temporarily */
-extern char savdir[]; /* For saving current directory */
-extern char * dldir;
-#endif /* CK_TMPDIR */
-
- extern int query; /* Query-active flag */
-#ifndef NOSPL
- extern int cmdlvl;
- char querybuf[QBUFL+1] = { NUL, NUL }; /* QUERY response buffer */
- char *qbufp = querybuf; /* Pointer to it */
- int qbufn = 0; /* Length of data in it */
-#else
- extern int tlevel;
-#endif /* NOSPL */
-
-#ifndef NOICP
- extern int escape;
-#endif /* NOICP */
-/*
- If the following flag is nonzero when the protocol module is entered,
- then server mode persists for exactly one transaction, rather than
- looping until BYE or FINISH is received.
-*/
-extern int justone;
-
-static int r_save = -1;
-static int p_save = -1;
-
-/* Function to let remote-mode user know where their file(s) went */
-
-int whereflg = 1; /* Unset with SET XFER REPORT */
-
-static VOID
-wheremsg() {
- extern int quiet, filrej;
- int n;
- n = filcnt - filrej;
- debug(F101,"wheremsg n","",n);
-
- debug(F110,"wheremsg prfspec",prfspec,0);
- debug(F110,"wheremsg rfspec",rfspec,0);
- debug(F110,"wheremsg psfspec",psfspec,0);
- debug(F110,"wheremsg sfspec",sfspec,0);
-
- debug(F110,"wheremsg prrfspec",prrfspec,0);
- debug(F110,"wheremsg rrfspec",rrfspec,0);
- debug(F110,"wheremsg psrfspec",psrfspec,0);
- debug(F110,"wheremsg srfspec",srfspec,0);
-
- if (!quiet && !local) {
- if (n == 1) {
- switch (myjob) {
- case 's':
- if (sfspec) {
- printf(" SENT: [%s]",sfspec);
- if (srfspec)
- printf(" To: [%s]",srfspec);
- printf(" (%s)\r\n", success ? "OK" : "FAILED");
- }
- break;
- case 'r':
- case 'v':
- if (rrfspec) {
- printf(" RCVD: [%s]",rrfspec);
- if (rfspec)
- printf(" To: [%s]",rfspec);
- printf(" (%s)\r\n", success ? "OK" : "FAILED");
- }
- }
- } else if (n > 1) {
- switch (myjob) {
- case 's':
- if (sfspec) {
- printf(" SENT: (%d files)",n);
- if (srfspec)
- printf(" Last: [%s]",srfspec);
- printf(" (%s)\r\n", success ? "OK" : "FAILED");
- }
- break;
- case 'r':
- case 'v':
- if (rrfspec) {
- printf(" RCVD: (%d files)",n);
- if (rfspec)
- printf(" Last: [%s]",rfspec);
- printf(" (%s)\r\n", success ? "OK" : "FAILED");
- }
- }
- } else if (n == 0) {
- if (myjob == 's')
- printf(" SENT: (0 files) \r\n");
- else if (myjob == 'r' || myjob == 'v')
- printf(" RCVD: (0 files) \r\n");
- }
- }
-}
-
-static VOID
-rdebug() {
- if (server)
- debug(F111,"RESUME","server=1",justone);
- else
- debug(F111,"RESUME","server=0",justone);
-}
-
-/* Flags for the ENABLE and DISABLE commands */
-extern int
- en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
- en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
- en_mkd, en_rmd;
-#ifndef NOSPL
-extern int en_asg, en_que;
-#endif /* NOSPL */
-extern int what, lastxfer;
-
-/* Global variables declared here */
-
- int whatru = 0; /* What are you. */
- int whatru2 = 0; /* What are you, cont'd. */
-
-/* Local variables */
-
- static char vstate = 0; /* Saved State */
- static char vcmd = 0; /* Saved Command */
- static int reget = 0; /* Flag for executing REGET */
- static int retrieve = 0; /* Flag for executing RETRIEVE */
- static int opkt = 0; /* Send Extended GET packet */
-
- static int x; /* General-purpose integer */
- static char *s; /* General-purpose string pointer */
-
-/* Macros - Note, BEGIN is predefined by Wart (and Lex) as "state = ", */
-/* BEGIN is NOT a GOTO! */
-#define TINIT if (tinit(1) < 0) return(-9)
-#define SERVE { TINIT; resetc(); nakstate=1; what=W_NOTHING; cmarg2=""; \
-sendmode=SM_SEND; havefs=0; recursive=r_save; fnspath=p_save; BEGIN serve; }
-#define RESUME { rdebug(); if (!server) { wheremsg(); return(0); } else \
-if (justone) { justone=0; wheremsg(); return(0); } else { SERVE; } }
-
-#ifdef GFTIMER
-#define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); \
- fptsecs=gftimer(); quiet=x; return(success)
-#else
-#define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); quiet=x; \
- return(success)
-#endif /* GFTIMER */
-
-/*
- By late 1999, the big switch() statement generated from the following state
- table began choking even gcc, so here we extract the code from the larger
- states into static routines to reduce the size of the cases and the
- switch() overall. The routines follow the state table; the prototypes are
- here. Each of these routines simply contains the text from the
- corresponding case, but with return(-1) added in appropriate places; see
- instructions after the state table switcher.
-*/
-static int rc; /* Return code for these routines */
-static int rcv_s_pkt(); /* Received an S packet */
-static int rcv_firstdata(); /* Received first Data packet */
-static int rcv_shortreply(); /* Short reply to a REMOTE command */
-static int srv_query(); /* Server answers an query */
-static int srv_copy(); /* Server executes REMOTE COPY */
-static int srv_rename(); /* Server executes REMOTE RENAME */
-static int srv_login(); /* Server executes REMOTE LOGIN */
-static int srv_timeout(); /* Server times out */
-
-%%
-
-/*
- Protocol entry points, one for each start state (sstate).
- The lowercase letters are internal "inputs" from the user interface.
- NOTE: The start state letters that appear on the left margin immediately
- below can NOT be used as packet types OR as G-packet subcodes.
-*/
-
-s { TINIT; /* Send file(s) */
- if (sinit() > 0) BEGIN ssinit;
- else RESUME; }
-
-v { TINIT; nakstate = 1; BEGIN get; } /* Receive file(s) */
-
-r { /* Client sends a GET command */
- TINIT;
- vstate = get;
- reget = 0;
- retrieve = 0;
- opkt = 0;
- vcmd = 0;
-#ifdef PKTZEROHACK
- ipktack[0] = NUL;
-#endif /* PKTZEROHACK */
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-
-h { /* Client sends a RETRIEVE command */
- TINIT;
- vstate = get;
- reget = 0;
- retrieve = 1;
- opkt = 0;
- vcmd = 0;
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-j { /* Client sends a REGET command */
- TINIT;
- vstate = get;
- reget = 1;
- retrieve = 0;
- opkt = 0;
- vcmd = 0;
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-o { /* Client sends Extended GET Packet */
- TINIT;
- vstate = get;
- reget = oopts & GOPT_RES;
- retrieve = oopts & GOPT_DEL;
- opkt = 1;
- vcmd = 0;
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-c { /* Client sends a Host command */
- TINIT;
- vstate = rgen;
- vcmd = 'C';
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-k { TINIT; /* Client sends a Kermit command */
- vstate = rgen;
- vcmd = 'K';
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-g { /* Client sends a REMOTE command */
- TINIT;
- vstate = rgen;
- vcmd = 'G';
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-x { /* Enter server mode */
- int x;
- x = justone;
- if (!ENABLED(en_del)) { /* If DELETE is disabled */
- if (fncact == XYFX_B || /* undo any file collision action */
- fncact == XYFX_U || /* that could result in deletion or */
- fncact == XYFX_A || /* modification of existing files. */
- fncact == XYFX_X) {
-#ifndef NOICP
- extern int g_fncact;
- g_fncact = fncact; /* Save current setting */
-#endif /* NOICP */
- fncact = XYFX_R; /* Change to RENAME */
- debug(F101,"server DELETE disabled so fncact RENAME","",fncact);
- }
- }
- SERVE; /* tinit() clears justone... */
- justone = x;
-#ifdef IKSDB
- if (ikdbopen) slotstate(what, "SERVER", "", "");
-#endif /* IKSDB */
-}
-
-a {
- int b1 = 0, b2 = 0;
- if (!data) TINIT; /* "ABEND" -- Tell other side. */
-
- if (!bctf) { /* Block check 3 forced on all packets */
-#ifndef pdp11
- if (epktflg) { /* If because of E-PACKET command */
- b1 = bctl; b2 = bctu; /* Save block check type */
- bctl = bctu = 1; /* set it to 1 */
- }
-#endif /* pdp11 */
- }
- errpkt((CHAR *)"User cancelled"); /* Send the packet */
- if (!bctf) { /* Block check 3 forced on all packets */
-#ifndef pdp11
- if (epktflg) { /* Restore the block check */
- epktflg = 0;
- bctl = b1; bctu = b2;
- }
- }
-#endif /* pdp11 */
- success = 0;
- return(0); /* Return from protocol. */
-}
-
-/*
- Dynamic states: <current-states>input-character { action }
- nakstate != 0 means we're in a receiving state, in which we send ACKs & NAKs.
-*/
-
-<rgen,get,serve,ropkt>S { /* Receive Send-Init packet. */
- rc = rcv_s_pkt();
- cancel = 0; /* Reset cancellation counter */
- debug(F101,"rcv_s_pkt","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-/* States in which we get replies back from commands sent to a server. */
-/* Complicated because direction of protocol changes, packet number */
-/* stays at zero through I-G-S sequence, and complicated even more by */
-/* sliding windows buffer allocation. */
-
-<ipkt>Y { /* Get ack for I-packet */
- int x = 0;
-#ifdef PKTZEROHACK
- ckstrncpy(ipktack,(char *)rdatap,PKTZEROLEN); /* Save a copy of the ACK */
- ipktlen = strlen(ipktack);
-#endif /* PKTZEROHACK */
- spar(rdatap); /* Set parameters */
- cancel = 0;
- winlo = 0; /* Set window-low back to zero */
- debug(F101,"<ipkt>Y winlo","",winlo);
- urserver = 1; /* So I know I'm talking to a server */
- if (vcmd) { /* If sending a generic command */
- if (tinit(0) < 0) return(-9); /* Initialize many things */
- x = scmd(vcmd,(CHAR *)cmarg); /* Do that */
- if (x >= 0) x = 0; /* (because of O-Packet) */
- debug(F101,"proto G packet scmd","",x);
- vcmd = 0; /* and then un-remember it. */
- } else if (vstate == get) {
- debug(F101,"REGET sstate","",sstate);
- x = srinit(reget, retrieve, opkt); /* GET or REGET, etc */
- }
- if (x < 0) { /* If command was too long */
- if (!srimsg)
- srimsg = "Error sending string";
- errpkt((CHAR *)srimsg); /* cancel both sides. */
- success = 0;
- RESUME;
- } else if (x > 0) { /* Need to send more O-Packets */
- BEGIN ssopkt;
- } else {
- rtimer(); /* Reset the elapsed seconds timer. */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- winlo = 0; /* Window back to 0, again. */
- debug(F101,"<ipkt>Y vstate","",vstate);
- nakstate = 1; /* Can send NAKs from here. */
- BEGIN vstate; /* Switch to desired state */
- }
-}
-
-<ssopkt>Y { /* Got ACK to O-Packet */
- debug(F100,"CPCPRO <ssopkt>Y","",0);
- x = sopkt();
- debug(F101,"CPCPRO <ssopkt>Y x","",x);
- if (x < 0) { /* If error */
- errpkt((CHAR *)srimsg); /* cancel both sides. */
- success = 0;
- RESUME;
- } else if (x == 0) { /* This was the last O-Packet */
- rtimer(); /* Reset the elapsed seconds timer. */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- winlo = 0; /* Window back to 0, again. */
- debug(F101,"<ssopkt>Y winlo","",winlo);
- nakstate = 1; /* Can send NAKs from here. */
- BEGIN vstate; /* Switch to desired state */
- }
- debug(F101,"CPCPRO <ssopkt>Y not changing state","",x);
-}
-
-<ipkt>E { /* Ignore Error reply to I packet */
- int x = 0;
- winlo = 0; /* Set window-low back to zero */
- debug(F101,"<ipkt>E winlo","",winlo);
- if (vcmd) { /* In case other Kermit doesn't */
- if (tinit(0) < 0) return(-9);
- x = scmd(vcmd,(CHAR *)cmarg); /* understand I-packets. */
- if (x >= 0) x = 0; /* (because of O-Packet) */
- vcmd = 0; /* Otherwise act as above... */
- } else if (vstate == get) x = srinit(reget, retrieve, opkt);
- if (x < 0) { /* If command was too long */
- errpkt((CHAR *)srimsg); /* cancel both sides. */
- success = 0;
- RESUME;
- } else if (x > 0) { /* Need to send more O-Packets */
- BEGIN ssopkt;
- } else {
- freerpkt(winlo); /* Discard the Error packet. */
- debug(F101,"<ipkt>E winlo","",winlo);
- winlo = 0; /* Back to packet 0 again. */
- nakstate = 1; /* Can send NAKs from here. */
- BEGIN vstate;
- }
-}
-
-<get>Y { /* Resend of previous I-pkt ACK, same seq number */
- freerpkt(0); /* Free the ACK's receive buffer */
- resend(0); /* Send the GET packet again. */
-}
-
-/* States in which we're being a server */
-
-<serve,get>I { /* Get I-packet */
-#ifndef NOSERVER
- spar(rdatap); /* Set parameters from it */
- ack1(rpar()); /* Respond with our own parameters */
-#ifdef COMMENT
- pktinit(); /* Reinitialize packet numbers */
-#else
-#ifdef COMMENT
- /* This can't be right - it undoes the stuff we just negotiated */
- x = justone;
- tinit(1); /* Reinitialize EVERYTHING */
- justone = x; /* But this... */
-#else
- tinit(0); /* Initialize most things */
-#endif /* COMMENT */
-#endif /* COMMENT */
-#endif /* NOSERVER */
- cancel = 0; /* Reset cancellation counter */
-}
-
-<serve>R { /* GET */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
-
-<serve>H { /* GET /DELETE (RETRIEVE) */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- RESUME;
- } else if (!ENABLED(en_del)) {
- errpkt((CHAR *)"Deleting files is disabled");
- RESUME;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
- moving = 1;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET /DELETE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
-
-<serve>V { /* GET /RECURSIVE */
-#ifndef NOSERVER
- recursive = 1; /* Set these before sgetinit() */
- if (fnspath == PATH_OFF)
- fnspath = PATH_REL; /* Don't worry, they will be */
- if (x_login && !x_logged) { /* reset next time through. */
- errpkt((CHAR *)"Login required");
- RESUME;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET /RECURSIVE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
-
-<serve>W { /* GET /RECURSIVE /DELETE */
-#ifndef NOSERVER
- recursive = 1; /* Set these before sgetinit() */
- if (fnspath == PATH_OFF)
- fnspath = PATH_REL; /* Don't worry, they will be */
- moving = 1; /* reset next time through. */
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- RESUME;
- } else if (!ENABLED(en_del)) {
- errpkt((CHAR *)"Deleting files is disabled");
- RESUME;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR,1,"server",
- "GET /RECURSIVE /DELETE",(char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
-
-<serve>J { /* GET /RECOVER (REGET) */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if (sgetinit(1,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET /RECOVER", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
-
-<serve>O { /* Extended GET */
-#ifndef NOSERVER
- if (x_login && !x_logged) { /* (any combination of options) */
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if ((x = sgetinit(0,1)) < 0) {
- debug(F101,"CKCPRO <serve>O sgetinit fail","",x);
- RESUME;
- } else if (x == 0) {
- debug(F101,"CKCPRO <serve>O sgetinit done","",x);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- } else { /* Otherwise stay in this state */
- debug(F101,"CKCPRO <serve>O sgetinit TBC","",x);
- ack();
- BEGIN ropkt;
- }
-#endif /* NOSERVER */
-}
-
-<ropkt>O {
-#ifndef NOSERVER
- if (x_login && !x_logged) { /* (any combination of options) */
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if ((x = sgetinit(0,1)) < 0) {
- debug(F101,"CKCPRO <ropkt>O sgetinit fail","",x);
- RESUME;
- } else if (x == 0) {
- debug(F101,"CKCPRO <ropkt>O sgetinit done","",x);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- } else { /* Otherwise stay in this state */
- debug(F101,"CKCPRO <ropkt>O sgetinit TBC","",x);
- ack();
- }
-#endif /* NOSERVER */
-}
-
-<serve>G { /* Generic server command */
-#ifndef NOSERVER
- srvptr = srvcmd; /* Point to command buffer */
- decode(rdatap,putsrv,0); /* Decode packet data into it */
- putsrv(NUL); /* Insert a couple nulls */
- putsrv(NUL); /* for termination */
- if (srvcmd[0]) {
- sstate = srvcmd[0]; /* Set requested start state */
- if (x_login && !x_logged && /* Login required? */
- /* Login, Logout, and Help are allowed when not logged in */
- sstate != 'I' && sstate != 'L' && sstate != 'H') {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else {
- nakstate = 0; /* Now I'm the sender. */
- what = W_REMO; /* Doing a REMOTE command. */
-#ifdef STREAMING
- if (!streaming)
-#endif /* STREAMING */
- if (timint < 1)
- timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
- binary = XYFT_T; /* Switch to text mode */
- BEGIN generic; /* Switch to generic command state */
- }
- } else {
- errpkt((CHAR *)"Badly formed server command"); /* report error */
- RESUME; /* & go back to server command wait */
- }
-#endif /* NOSERVER */
-}
-
-<serve>C { /* Receive Host command */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if (!ENABLED(en_hos)) {
- errpkt((CHAR *)"REMOTE HOST disabled");
- RESUME;
- } else if (nopush) {
- errpkt((CHAR *)"HOST commands not available");
- RESUME;
- } else {
- srvptr = srvcmd; /* Point to command buffer */
- decode(rdatap,putsrv,0); /* Decode command packet into it */
- putsrv(NUL); /* Null-terminate */
- nakstate = 0; /* Now sending, not receiving */
- binary = XYFT_T; /* Switch to text mode */
- if (syscmd((char *)srvcmd,"")) { /* Try to execute the command */
- what = W_REMO; /* Doing a REMOTE command. */
-#ifdef STREAMING
- if (!streaming)
-#endif /* STREAMING */
- if (timint < 1)
- timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE HOST", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit; /* If OK, send back its output */
- } else { /* Otherwise */
- errpkt((CHAR *)"Can't do system command"); /* report error */
- RESUME; /* & go back to server command wait */
- }
- }
-#endif /* NOSERVER */
-}
-
-<serve>q { /* Interrupted or connection lost */
- rc = srv_timeout();
- debug(F101,"srv_timeout","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-<serve>N { /* Server got a NAK in command-wait */
-#ifndef NOSERVER
- errpkt((CHAR *)"Did you say RECEIVE instead of GET?");
- RESUME;
-#endif /* NOSERVER */
-}
-
-<serve>. { /* Any other command in this state */
-#ifndef NOSERVER
- if (c != ('E' - SP) && c != ('Y' - SP)) /* except E and Y packets. */
- errpkt((CHAR *)"Unimplemented server function");
- /* If we answer an E with an E, we get an infinite loop. */
- /* A Y (ACK) can show up here if we sent back a short-form reply to */
- /* a G packet and it was echoed. ACKs can be safely ignored here. */
- RESUME; /* Go back to server command wait. */
-#endif /* NOSERVER */
-}
-
-<generic>I { /* Login/Out */
- rc = srv_login();
- debug(F101,"<generic>I srv_login","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-<generic>C { /* Got REMOTE CD command */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE CD", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_cwd)) {
- errpkt((CHAR *)"REMOTE CD disabled");
- RESUME;
- } else {
- char * p = NULL;
- x = cwd((char *)(srvcmd+1)); /* Try to change directory */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE CD", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!x) { /* Failed */
- errpkt((CHAR *)"Can't change directory");
- RESUME; /* Back to server command wait */
- } else if (x == 2) { /* User wants message */
- if (!ENABLED(en_typ)) { /* Messages (REMOTE TYPE) disabled? */
- errpkt((CHAR *)"REMOTE TYPE disabled");
- RESUME;
- } else { /* TYPE is enabled */
- int i;
- for (i = 0; i < 8; i++) {
- if (zchki(cdmsgfile[i]) > -1) {
- break;
- }
- }
- binary = XYFT_T; /* Use text mode for this. */
- if (i < 8 && sndtype(cdmsgfile[i])) { /* Have readme file? */
- BEGIN ssinit; /* OK */
- } else { /* not OK */
- p = zgtdir();
- if (!p) p = "";
- success = (*p) ? 1 : 0;
- ack1((CHAR *)p); /* ACK with new directory name */
- success = 1;
- RESUME; /* wait for next server command */
- }
- }
- } else { /* User doesn't want message */
- p = zgtdir();
- if (!p) p = "";
- success = (*p) ? 1 : 0;
- ack1((CHAR *)p);
- success = 1;
- RESUME; /* Wait for next server command */
- }
- }
-#endif /* NOSERVER */
-}
-
-<generic>A { /* Got REMOTE PWD command */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE PWD", NULL);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_cwd)) {
- errpkt((CHAR *)"REMOTE CD disabled");
- RESUME;
- } else {
- if (encstr((CHAR *)zgtdir()) > -1) { /* Encode current directory */
- ack1(data); /* If it fits, send it back in ACK */
- success = 1;
- } else { /* Failed */
- ack(); /* Send empty ACK */
- success = 0; /* and indicate failure locally */
- }
- RESUME; /* Back to server command wait */
- }
-#endif /* NOSERVER */
-}
-
-<generic>D { /* REMOTE DIRECTORY command */
-#ifndef NOSERVER
- char *n2;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE DIRECTORY", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_dir)) { /* If DIR is disabled, */
- errpkt((CHAR *)"REMOTE DIRECTORY disabled"); /* refuse. */
- RESUME;
- } else { /* DIR is enabled. */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE DIR", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* But CWD is disabled */
- zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
- if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
-#ifdef COMMENT
- n2 = (*(srvcmd+2)) ? DIRCMD : DIRCM2;
- if (syscmd(n2,(char *)(srvcmd+2))) /* If it can be done */
-#else
- int x;
- if ((x = snddir((char*)(srvcmd+2))) > 0)
-#endif /* COMMENT */
- {
- BEGIN ssinit; /* send the results back; */
- } else { /* otherwise */
- if (x < 0)
- errpkt((CHAR *)"No files match");
- else
- errpkt((CHAR *)"Can't list directory");
- RESUME; /* return to server command wait */
- }
- }
- }
-#endif /* NOSERVER */
-}
-
-<generic>E { /* REMOTE DELETE (Erase) */
-#ifndef NOSERVER
- char *n2;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE DELETE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_del)) {
- errpkt((CHAR *)"REMOTE DELETE disabled");
- RESUME;
- } else { /* DELETE is enabled */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE DELETE", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* but CWD is disabled */
- zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
- if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- }
- } else if (isdir((char *)(srvcmd+2))) { /* A directory name? */
- errpkt((CHAR *)"It's a directory");
- RESUME;
- }
- if (state == generic) { /* It's OK to go ahead. */
- int x;
- if ((x = snddel((char*)(srvcmd+2))) > 0) {
- BEGIN ssinit; /* If OK send results back */
- } else { /* otherwise */
- if (x < 0)
- errpkt((CHAR *)"File not found"); /* report failure */
- else
- errpkt((CHAR *)"DELETE failed");
- RESUME; /* & return to server command wait */
- }
- }
- }
-#endif /* NOSERVER */
-}
-
-<generic>F { /* FINISH */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "FINISH", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"SERVER FINISH", "", "");
-#endif /* IKSDB */
- if (!ENABLED(en_fin)) {
- errpkt((CHAR *)"FINISH disabled");
- RESUME;
- } else {
- ack(); /* Acknowledge */
- xxscreen(SCR_TC,0,0L,""); /* Display */
- success = 1;
- return(0); /* Done */
- }
-#endif /* NOSERVER */
-}
-
-<generic>X { /* EXIT */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE EXIT", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE EXIT", "", "");
-#endif /* IKSDB */
- if (!ENABLED(en_xit)) {
- errpkt((CHAR *)"EXIT disabled");
- RESUME;
- } else {
- ack(); /* Acknowledge */
- xxscreen(SCR_TC,0,0L,""); /* Display */
- doexit(GOOD_EXIT,xitsta);
- }
-#endif /* NOSERVER */
-}
-
-<generic>L { /* BYE (Logout) */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "BYE", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"SERVER BYE", "", "");
-#endif /* IKSDB */
- if (!ENABLED(en_bye)) {
- errpkt((CHAR *)"BYE disabled");
- RESUME;
- } else {
- ack(); /* Acknowledge */
- success = 1;
- msleep(750); /* Give the ACK time to get out */
- if (local)
- ttres(); /* Reset the terminal */
- xxscreen(SCR_TC,0,0L,""); /* Display */
- doclean(1); /* Clean up files, etc */
-#ifdef DEBUG
- debug(F100,"C-Kermit BYE - Logging out...","",0);
- zclose(ZDFILE);
-#endif /* DEBUG */
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver)
- ckxlogout();
- else
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-#ifdef TCPSOCKET
-#ifndef NOLISTEN
- if (network && tcpsrfd > 0 && !inserver)
- doexit(GOOD_EXIT,xitsta);
- else
-#endif /* NOLISTEN */
-#endif /* TCPSOCKET */
- return(zkself()); /* Try to log self out */
- }
-#endif /* NOSERVER */
-}
-
-<generic>H { /* REMOTE HELP */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE HELP", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE HELP", "", "");
-#endif /* IKSDB */
-#ifndef NOSERVER
- if (sndhlp()) {
- BEGIN ssinit; /* try to send it */
- } else { /* If not ok, */
- errpkt((CHAR *)"Can't send help"); /* send error message instead */
- RESUME; /* and return to server command wait */
- }
-#endif /* NOSERVER */
-}
-
-<generic>R { /* REMOTE RENAME */
- rc = srv_rename();
- debug(F101,"srv_rename","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-<generic>K { /* REMOTE COPY */
- rc = srv_copy();
- debug(F101,"srv_copy","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-<generic>S { /* REMOTE SET */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE SET", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifndef NOSERVER
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE SET", (char *)(srvcmd+1), "");
-#endif /* IKSDB */
- if (!ENABLED(en_set)) {
- errpkt((CHAR *)"REMOTE SET disabled");
- RESUME;
- } else {
- if (remset((char *)(srvcmd+1))) { /* Try to do what they ask */
- success = 1;
- ack(); /* If OK, then acknowledge */
- } else /* Otherwise */
- errpkt((CHAR *)"Unknown REMOTE SET parameter"); /* give error msg */
- RESUME; /* Return to server command wait */
- }
-#endif /* NOSERVER */
-}
-
-<generic>T { /* REMOTE TYPE */
-#ifndef NOSERVER
- char *n2;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE TYPE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_typ)) {
- errpkt((CHAR *)"REMOTE TYPE disabled");
- RESUME;
- } else {
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE TYPE", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* If CWD disabled */
- zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
- if (strcmp((char *)(srvcmd+2),n2)) { /* refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
- binary = XYFT_T; /* Use text mode for this. */
- if ( /* (RESUME didn't change state) */
-#ifdef COMMENT
- syscmd(TYPCMD,(char *)(srvcmd+2)) /* Old way */
-#else
- sndtype((char *)(srvcmd+2)) /* New way */
-#endif /* COMMENT */
- )
- BEGIN ssinit; /* OK */
- else { /* not OK */
- errpkt((CHAR *)"Can't type file"); /* give error message */
- RESUME; /* wait for next server command */
- }
- }
- }
-#endif /* NOSERVER */
-}
-
-<generic>m { /* REMOTE MKDIR */
-#ifndef NOSERVER
-#ifdef CK_MKDIR
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE MKDIR", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE MKDIR", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_mkd)) {
- errpkt((CHAR *)"REMOTE MKDIR disabled");
- RESUME;
- } else if (!ENABLED(en_cwd)) { /* If CWD disabled */
- errpkt((CHAR *)"Directory access restricted");
- RESUME; /* Remember, this is not a goto! */
- }
- if (state == generic) { /* OK to go ahead. */
- char *p = NULL;
- x = ckmkdir(0,(char *)(srvcmd+2),&p,0,1); /* Make the directory */
- if (!p) p = "";
- if (x > -1) {
- encstr((CHAR *)p); /* OK - encode the name */
- ack1(data); /* Send short-form response */
- success = 1;
- RESUME;
- } else { /* not OK */
- if (!*p) p = "Directory creation failure";
- errpkt((CHAR *)p); /* give error message */
- RESUME; /* Wait for next server command */
- }
- }
-#else
- errpkt((CHAR *)"REMOTE MKDIR not available");
- RESUME;
-#endif /* CK_MKDIR */
-#endif /* NOSERVER */
-}
-
-<generic>d { /* REMOTE RMDIR */
-#ifndef NOSERVER
-#ifdef CK_MKDIR
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE RMDIR", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE RMDIR", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_rmd)) {
- errpkt((CHAR *)"REMOTE RMDIR disabled");
- RESUME;
- } else if (!ENABLED(en_cwd)) { /* If CWD disabled */
- errpkt((CHAR *)"Directory access restricted");
- RESUME; /* Remember, this is not a goto! */
- }
- if (state == generic) { /* OK to go ahead. */
- char *p = NULL;
- x = ckmkdir(1,(char *)(srvcmd+2),&p,0,1);
- if (!p) p = "";
- if (x > -1) {
- encstr((CHAR *)p); /* OK - encode the name */
- ack1(data); /* Send short-form response */
- success = 1;
- RESUME;
- } else { /* not OK */
- if (!*p) p = "Directory removal failure";
- errpkt((CHAR *)p); /* give error message */
- RESUME; /* Wait for next server command */
- }
- }
-#else
- errpkt((CHAR *)"REMOTE RMDIR not available");
- RESUME;
-#endif /* CK_MKDIR */
-#endif /* NOSERVER */
-}
-
-<generic>U { /* REMOTE SPACE */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE SPACE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_spa)) {
- errpkt((CHAR *)"REMOTE SPACE disabled");
- RESUME;
- } else {
- x = srvcmd[1]; /* Get area to check */
- x = ((x == NUL) || (x == SP)
-#ifdef OS2
- || (x == '!') || (srvcmd[3] == ':')
-#endif /* OS2 */
- );
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- "REMOTE SPACE",
- (x ? "" : (char *)srvcmd),
- ""
- );
-#endif /* IKSDB */
- if (!x && !ENABLED(en_cwd)) { /* CWD disabled */
- errpkt((CHAR *)"Access denied"); /* and non-default area given, */
- RESUME; /* refuse. */
- } else {
-#ifdef OS2
-_PROTOTYP(int sndspace,(int));
- if (sndspace(x ? toupper(srvcmd[2]) : 0)) {
- BEGIN ssinit; /* send the report. */
- } else { /* If not ok, */
- errpkt((CHAR *)"Can't send space"); /* send error message */
- RESUME; /* and return to server command wait */
- }
-#else
- if (nopush)
- x = 0;
- else
- x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,(char *)(srvcmd+2)));
- if (x) { /* If we got the info */
- BEGIN ssinit; /* send it */
- } else { /* otherwise */
- errpkt((CHAR *)"Can't check space"); /* send error message */
- RESUME; /* and await next server command */
- }
-#endif /* OS2 */
- }
- }
-#endif /* NOSERVER */
-}
-
-<generic>W { /* REMOTE WHO */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE WHO", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE WHO", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_who)) {
- errpkt((CHAR *)"REMOTE WHO disabled");
- RESUME;
- } else {
-#ifdef OS2
-_PROTOTYP(int sndwho,(char *));
- if (sndwho((char *)(srvcmd+2))) {
- BEGIN ssinit; /* try to send it */
- } else { /* If not ok, */
- errpkt((CHAR *)"Can't do who command"); /* send error msg */
- RESUME; /* and return to server command wait */
- }
-#else
- if (syscmd(WHOCMD,(char *)(srvcmd+2))) {
- BEGIN ssinit;
- } else {
- errpkt((CHAR *)"Can't do who command");
- RESUME;
- }
-#endif /* OS2 */
- }
-#endif /* NOSERVER */
-}
-
-<generic>V { /* Variable query or set */
- rc = srv_query();
- debug(F101,"srv_query","",rc);
- if (rc > -1) return(rc);
-}
-
-<generic>M { /* REMOTE MESSAGE command */
-#ifndef NOSERVER
- debug(F110,"RMSG",(char *)srvcmd+2,0);
- xxscreen(SCR_MS,0,0L,(char *)(srvcmd+2));
- ack();
- RESUME;
-#endif /* NOSERVER */
-}
-
-<generic>q { /* Interrupted or connection lost */
-#ifndef NOSERVER
- if (fatalio) { /* Connection lost */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
-#endif /* CKSYSLOG */
- success = 0;
- xitsta |= (what & W_KERMIT);
- QUIT;
- } else if (interrupted) {
- if (!ENABLED(en_fin)) { /* Ctrl-C typed */
- errpkt((CHAR *)"QUIT disabled");
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
-#endif /* CKSYSLOG */
- success = 0;
- xitsta |= (what & W_KERMIT);
- QUIT;
- }
- } else { /* Shouldn't happen */
- debug(F100,"SERVER (generic) GOT UNEXPECTED 'q'","",0);
- QUIT;
- }
-#endif /* NOSERVER */
-}
-
-<generic>. { /* Anything else in this state... */
-#ifndef NOSERVER
- errpkt((CHAR *)"Unimplemented REMOTE command"); /* Complain */
- RESUME; /* and return to server command wait */
-#endif /* NOSERVER */
-}
-
-<rgen>q { /* Sent BYE and connection broken */
- if (bye_active && ttchk() < 0) {
- msleep(500);
- bye_active = 0;
- ttclos(0); /* Close our end of the connection */
- clsof(0);
- return(success = 1);
- } else { /* Other generic command */
- return(success = 0); /* or connection not broken */
- }
-}
-
-<rgen>Y { /* Short-Form reply */
- rc = rcv_shortreply();
- debug(F101,"<rgen>Y rcv_shortreply","",rc);
- if (rc > -1) return(rc);
-}
-
-<rgen,rfile>F { /* File header */
- /* char *n2; */
- extern int rsn;
- debug(F101,"<rfile>F winlo 1","",winlo);
- xflg = 0; /* Not screen data */
- if (!czseen)
- cancel = 0; /* Reset cancellation counter */
-#ifdef CALIBRATE
- if (dest == DEST_N)
- calibrate = 1;
-#endif /* CALIBRATE */
- if (!rcvfil(filnam)) { /* Figure out local filename */
- errpkt((CHAR *)rf_err); /* Trouble */
- RESUME;
- } else { /* Real file, OK to receive */
- char * fnp;
- debug(F111,"<rfile>F winlo 2",fspec,winlo);
- if (filcnt == 1) /* rcvfil set this to 1 for 1st file */
- crc16 = 0L; /* Clear file CRC */
- fnp = fspec; /* This is the full path */
- if (server && !ENABLED(en_cwd) || /* if DISABLE CD */
- !fackpath /* or F-ACK-PATH OFF */
- ) {
- zstrip(fspec,&fnp); /* don't send back full path */
- }
- encstr((CHAR *)fnp);
- if (fackbug)
- ack();
- else
- ack1(data); /* Send it back in ACK */
- initattr(&iattr); /* Clear file attribute structure */
- streamon();
- if (window(wslotn) < 0) { /* Allocate negotiated window slots */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- }
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- server ? "SERVER" : "",
- "RECEIVE",
- fspec
- );
-#endif /* IKSDB */
- BEGIN rattr; /* Now expect Attribute packets */
- }
-}
-
-<rgen,rfile>X { /* X-packet instead of file header */
- xflg = 1; /* Screen data */
- if (!czseen)
- cancel = 0; /* Reset cancellation counter */
- ack(); /* Acknowledge the X-packet */
- initattr(&iattr); /* Initialize attribute structure */
- streamon();
- if (window(wslotn) < 0) { /* allocate negotiated window slots */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- }
-#ifndef NOSPL
- if (query) { /* If this is the response to */
- qbufp = querybuf; /* a query that we sent, initialize */
- qbufn = 0; /* the response buffer */
- querybuf[0] = NUL;
- }
-#endif /* NOSPL */
- what = W_REMO; /* we're doing a REMOTE command */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- server ? "SERVER" : "",
- "RECEIVE",
- fspec
- );
-#endif /* IKSDB */
- BEGIN rattr; /* Expect Attribute packets */
-}
-
-<rattr>A { /* Attribute packet */
- if (gattr(rdatap,&iattr) == 0) { /* Read into attribute structure */
-#ifdef CK_RESEND
- ack1((CHAR *)iattr.reply.val); /* Reply with data */
-#else
- ack(); /* If OK, acknowledge */
-#endif /* CK_RESEND */
- } else { /* Otherwise */
- extern long fsize;
- char *r;
- r = getreason(iattr.reply.val);
- ack1((CHAR *)iattr.reply.val); /* refuse to accept the file */
- xxscreen(SCR_ST,ST_REFU,0L,r); /* reason */
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,filnam,fsize,binary,1,r);
-#endif /* TLOG */
- }
-}
-
-<rattr>D { /* First data packet */
- debug(F100,"<rattr> D firstdata","",0);
- rc = rcv_firstdata();
- debug(F101,"rcv_firstdata rc","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-<rfile>B { /* EOT, no more files */
- ack(); /* Acknowledge the B packet */
- reot(); /* Do EOT things */
-#ifdef CK_TMPDIR
-/* If we were cd'd temporarily to another device or directory ... */
- if (f_tmpdir) {
- int x;
- x = zchdir((char *) savdir); /* ... restore previous directory */
- f_tmpdir = 0; /* and remember we did it. */
- debug(F111,"ckcpro.w B tmpdir restoring",savdir,x);
- }
-#endif /* CK_TMPDIR */
- RESUME; /* and quit */
-}
-
-<rdpkt>D { /* Got Data packet */
- debug(F101,"<rdpkt>D cxseen","",cxseen);
- debug(F101,"<rdpkt>D czseen","",czseen);
- if (cxseen || czseen || discard) { /* If file or group interruption */
- CHAR * msg;
- msg = czseen ? (CHAR *)"Z" : (CHAR *)"X";
-#ifdef STREAMING
- if (streaming) { /* Need to cancel */
- debug(F111,"<rdpkt>D streaming cancel",msg,cancel);
- if (cancel++ == 0) { /* Only do this once */
- ack1(msg); /* Put "X" or "Z" in ACK */
- } else if (czseen) {
- errpkt((CHAR *)"User canceled");
- RESUME;
- } else {
- fastack();
- }
- } else
-#endif /* STREAMING */
- ack1(msg);
- } else { /* No interruption */
- int rc, qf;
-#ifndef NOSPL
- qf = query;
-#else
- qf = 0;
-#endif /* NOSPL */
-#ifdef CKTUNING
- rc = (binary && !parity) ?
- bdecode(rdatap,putfil):
- decode(rdatap, qf ? puttrm : putfil, 1);
-#else
- rc = decode(rdatap, qf ? puttrm : putfil, 1);
-#endif /* CKTUNING */
- if (rc < 0) {
- discard = (keep == 0 || (keep == SET_AUTO && binary != XYFT_T));
- errpkt((CHAR *)"Error writing data"); /* If failure, */
- RESUME;
- } else /* Data written OK, send ACK */
-#ifdef STREAMING
- if (streaming)
- fastack();
- else
-#endif /* STREAMING */
- ack();
- }
-}
-
-<rattr>Z { /* EOF immediately after A-Packet. */
- rf_err = "Can't create file";
- timint = s_timint;
- if (discard) { /* Discarding a real file... */
- x = 1;
- } else if (xflg) { /* If screen data */
- if (remfile) { /* redirected to file */
- if (rempipe) /* or pipe */
- x = openc(ZOFILE,remdest); /* Pipe: start command */
- else
- x = opena(remdest,&iattr); /* File: open with attributes */
- } else { /* otherwise */
- x = opent(&iattr); /* "open" the screen */
- }
-#ifdef CALIBRATE
- } else if (calibrate) { /* If calibration run */
- x = ckopenx(&iattr); /* do this */
-#endif /* CALIBRATE */
- } else { /* otherwise */
- x = opena(filnam,&iattr); /* open the file, with attributes */
- if (x == -17) { /* REGET skipped because same size */
- discard = 1;
- rejection = 1;
- }
- }
- if (!x || reof(filnam, &iattr) < 0) { /* Close output file */
- errpkt((CHAR *) rf_err); /* If problem, send error msg */
- RESUME; /* and quit */
- } else { /* otherwise */
- if (x == -17)
- xxscreen(SCR_ST,ST_SKIP,SKP_RES,"");
- ack(); /* acknowledge the EOF packet */
- BEGIN rfile; /* and await another file */
- }
-}
-
-<rdpkt>q { /* Ctrl-C or connection loss. */
- timint = s_timint;
- window(1); /* Set window size back to 1... */
- cxseen = 1;
- x = clsof(1); /* Close file */
- return(success = 0); /* Failed */
-}
-
-<rdpkt>Z { /* End Of File (EOF) Packet */
-/* wslots = 1; */ /* (don't set) Window size back to 1 */
-#ifndef COHERENT /* Coherent compiler blows up on this switch() statement. */
- x = reof(filnam, &iattr); /* Handle the EOF packet */
- switch (x) { /* reof() sets the success flag */
- case -5: /* Handle problems */
- errpkt((CHAR *)"RENAME failed"); /* Fatal */
- RESUME;
- break;
- case -4:
- errpkt((CHAR *)"MOVE failed"); /* Fatal */
- RESUME;
- break;
- case -3: /* If problem, send error msg */
- errpkt((CHAR *)"Can't print file"); /* Fatal */
- RESUME;
- break;
- case -2:
- errpkt((CHAR *)"Can't mail file"); /* Fatal */
- RESUME;
- break;
- case 2: /* Not fatal */
- case 3:
- xxscreen(SCR_EM,0,0L,"Receiver can't delete temp file");
- RESUME;
- break;
- default:
- if (x < 0) { /* Fatal */
- errpkt((CHAR *)"Can't close file");
- RESUME;
- } else { /* Success */
-#ifndef NOSPL
- if (query) /* Query reponses generally */
- conoll(""); /* don't have line terminators */
-#endif /* NOSPL */
- if (czseen) { /* Batch canceled? */
- if (cancel++ == 0) { /* If we haven't tried this yet */
- ack1((CHAR *)"Z"); /* Try it once */
- } else { /* Otherwise */
- errpkt((CHAR *)"User canceled"); /* quite with Error */
- RESUME;
- }
- } else
- ack(); /* Acknowledge the EOF packet */
- BEGIN rfile; /* and await another file */
- }
- }
-#else
- if (reof(filnam, &iattr) < 0) { /* Close the file */
- errpkt((CHAR *)"Error at end of file");
- RESUME;
- } else { /* reof() sets success flag */
- ack();
- BEGIN rfile;
- }
-#endif /* COHERENT */
-}
-
-<ssinit>Y { /* ACK for Send-Init */
- spar(rdatap); /* set parameters from it */
- cancel = 0;
- if (bctf) {
- bctu = 3;
- bctl = 3;
- } else {
- bctu = bctr; /* switch to agreed-upon block check */
- bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */
- }
-
-#ifdef CK_RESEND
- if ((sendmode == SM_RESEND) && (!atcapu || !rscapu)) { /* RESEND */
- errpkt((CHAR *) "RESEND capabilities not negotiated");
- RESUME;
- } else {
-#endif /* CK_RESEND */
- what = W_SEND; /* Remember we're sending */
- lastxfer = W_SEND;
- x = sfile(xflg); /* Send X or F header packet */
- cancel = 0; /* Reset cancellation counter */
- if (x) { /* If the packet was sent OK */
- if (!xflg && filcnt == 1) /* and it's a real file */
- crc16 = 0L; /* Clear the file CRC */
- resetc(); /* reset per-transaction counters */
- rtimer(); /* reset timers */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- streamon(); /* turn on streaming */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- (server ? "SERVER" : ""),
- "SEND",
- filnam
- );
-#endif /* IKSDB */
- BEGIN ssfile; /* and switch to receive-file state */
- } else { /* otherwise send error msg & quit */
- s = xflg ? "Can't execute command" : (char *)epktmsg;
- if (!*s) s = "Can't open file";
- errpkt((CHAR *)s);
- RESUME;
- }
-#ifdef CK_RESEND
- }
-#endif /* CK_RESEND */
-}
-
-/*
- These states are necessary to handle the case where we get a server command
- packet (R, G, or C) reply with an S packet, but the client retransmits the
- command packet. The input() function doesn't catch this because the packet
- number is still zero.
-*/
-<ssinit>R { /* R packet was retransmitted. */
- xsinit(); /* Resend packet 0 */
-}
-
-<ssinit>G { /* Same deal if G packet comes again */
- xsinit();
-}
-
-/* should probably add cases for O, W, V, H, J, ... */
-
-<ssinit>C { /* Same deal if C packet comes again */
- xsinit();
-}
-
-<ssfile>Y { /* ACK for F or X packet */
- srvptr = srvcmd; /* Point to string buffer */
- decode(rdatap,putsrv,0); /* Decode data field, if any */
- putsrv(NUL); /* Terminate with null */
- ffc = 0L; /* Reset file byte counter */
- debug(F101,"<ssfile>Y cxseen","",cxseen);
- if (*srvcmd) { /* If remote name was recorded */
- if (sendmode != SM_RESEND) {
- if (fdispla == XYFD_C || fdispla == XYFD_S)
- xxscreen(SCR_AN,0,0L,(char *)srvcmd);
- tlog(F110," remote name:",(char *) srvcmd,0L);
- makestr(&psrfspec,(char *)srvcmd);
- }
- }
- if (cxseen||czseen) { /* Interrupted? */
- debug(F101,"<ssfile>Y canceling","",0);
- x = clsif(); /* Close input file */
- sxeof(1); /* Send EOF(D) */
- BEGIN sseof; /* and switch to EOF state. */
- } else if (atcapu) { /* If attributes are to be used */
- if (sattr(xflg | stdinf, 1) < 0) { /* send them */
- errpkt((CHAR *)"Can't send attributes"); /* if problem, say so */
- RESUME; /* and quit */
- } else BEGIN ssattr; /* if ok, switch to attribute state */
- } else { /* Attributes not negotiated */
- if (window(wslotn) < 0) { /* Open window */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- } else if ((x = sdata()) == -2) { /* Send first data packet data */
- window(1); /* Connection lost, reset window */
- x = clsif(); /* Close input file */
- return(success = 0); /* Return failure */
- } else if (x == -9) { /* User interrupted */
- errpkt((CHAR *)"User cancelled"); /* Send Error packet */
- window(1); /* Set window size back to 1... */
- timint = s_timint; /* Restore timeout */
- return(success = 0); /* Failed */
- } else if (x < 0) { /* EOF (empty file) or interrupted */
- window(1); /* put window size back to 1, */
- debug(F101,"<ssfile>Y cxseen","",cxseen);
- x = clsif(); /* If not ok, close input file, */
- if (x < 0) /* treating failure as interruption */
- cxseen = 1; /* Send EOF packet */
- seof(cxseen||czseen);
- BEGIN sseof; /* and switch to EOF state. */
- } else { /* First data sent OK */
- BEGIN ssdata; /* All ok, switch to send-data state */
- }
- }
-}
-
-<ssattr>Y { /* Got ACK to A packet */
- ffc = 0L; /* Reset file byte counter */
- debug(F101,"<ssattr>Y cxseen","",cxseen);
- if (cxseen||czseen) { /* Interrupted? */
- debug(F101,"<sattr>Y canceling","",0);
- x = clsif(); /* Close input file */
- sxeof(1); /* Send EOF(D) */
- BEGIN sseof; /* and switch to EOF state. */
- } else if (rsattr(rdatap) < 0) { /* Was the file refused? */
- discard = 1; /* Set the discard flag */
- clsif(); /* Close the file */
- sxeof(1); /* send EOF with "discard" code */
- BEGIN sseof; /* switch to send-EOF state */
- } else if ((x = sattr(xflg | stdinf, 0)) < 0) { /* Send more? */
- errpkt((CHAR *)"Can't send attributes"); /* Trouble... */
- RESUME;
- } else if (x == 0) { /* No more to send so now the data */
- if (window(wslotn) < 0) { /* Allocate negotiated window slots */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- }
- if ((x = sdata()) == -2) { /* File accepted, send first data */
- window(1); /* Connection broken */
- x = clsif(); /* Close file */
- return(success = 0); /* Return failure */
- } else if (x == -9) { /* User interrupted */
- errpkt((CHAR *)"User cancelled"); /* Send Error packet */
- window(1); /* Set window size back to 1... */
- timint = s_timint; /* Restore timeout */
- return(success = 0); /* Failed */
- } else if (x < 0) { /* If data was not sent */
- window(1); /* put window size back to 1, */
- debug(F101,"<ssattr>Y cxseen","",cxseen);
- if (clsif() < 0) /* Close input file */
- cxseen = 1; /* Send EOF packet */
- seof(cxseen||czseen);
- BEGIN sseof; /* and switch to EOF state. */
- } else {
- BEGIN ssdata; /* All ok, switch to send-data state */
- }
- }
-}
-
-<ssdata>q { /* Ctrl-C or connection loss. */
- window(1); /* Set window size back to 1... */
- cxseen = 1; /* To indicate interruption */
- x = clsif(); /* Close file */
- return(success = 0); /* Failed */
-}
-
-<ssdata>Y { /* Got ACK to Data packet */
- canned(rdatap); /* Check if file transfer cancelled */
- debug(F111,"<ssdata>Y cxseen",rdatap,cxseen);
- debug(F111,"<ssdata>Y czseen",rdatap,czseen);
- if ((x = sdata()) == -2) { /* Try to send next data */
- window(1); /* Connection lost, reset window */
- x = clsif(); /* Close file */
- return(success = 0); /* Failed */
- } else if (x == -9) { /* User interrupted */
- errpkt((CHAR *)"User cancelled"); /* Send Error packet */
- window(1); /* Set window size back to 1... */
- timint = s_timint; /* Restore original timeout */
- return(success = 0); /* Failed */
- } else if (x < 0) { /* EOF - finished sending data */
- debug(F101,"<ssdata>Y cxseen","",cxseen);
- window(1); /* Set window size back to 1... */
- if (clsif() < 0) /* Close input file */
- cxseen = 1; /* Send EOF packet */
- debug(F101,"<ssdata>Y CALLING SEOF()","",cxseen);
- seof(cxseen||czseen);
- BEGIN sseof; /* and enter send-eof state */
- }
- /* NOTE: If x == 0 it means we're draining: see sdata()! */
-}
-
-<sseof>Y { /* Got ACK to EOF */
- int g, xdiscard;
- canned(rdatap); /* Check if file transfer cancelled */
- debug(F111,"<sseof>Y cxseen",rdatap,cxseen);
- debug(F111,"<sseof>Y czseen",rdatap,czseen);
- debug(F111,"<sseof>Y discard",rdatap,discard);
- xdiscard = discard;
- discard = 0;
- success = (cxseen == 0 && czseen == 0); /* Transfer status... */
- debug(F101,"<sseof>Y success","",success);
- if (success && rejection > 0) /* If rejected, succeed if */
- if (rejection != '#' && /* reason was date */
- rejection != 1 && rejection != '?') /* or name; */
- success = 0; /* fail otherwise. */
- cxseen = 0; /* This goes back to zero. */
- if (success) { /* Only if transfer succeeded... */
- xxscreen(SCR_ST,ST_OK,0L,"");
- if (!xdiscard) {
- makestr(&sfspec,psfspec); /* Record filenames for WHERE */
- makestr(&srfspec,psrfspec);
- }
- if (moving) { /* If MOVE'ing */
- x = zdelet(filnam); /* Try to delete the source file */
-#ifdef TLOG
- if (tralog) {
- if (x > -1) {
- tlog(F110," deleted",filnam,0);
- } else {
- tlog(F110," delete failed:",ck_errstr(),0);
- }
- }
-#endif /* TLOG */
- } else if (snd_move) { /* Or move it */
- int x;
- x = zrename(filnam,snd_move);
-#ifdef TLOG
- if (tralog) {
- if (x > -1) {
- tlog(F110," moved to ",snd_move,0);
- } else {
- tlog(F110," move failed:",ck_errstr(),0);
- }
- }
-#endif /* TLOG */
- } else if (snd_rename) { /* Or rename it */
- char *s = snd_rename; /* Renaming string */
-#ifndef NOSPL
- int y; /* Pass it thru the evaluator */
- extern int cmd_quoting; /* for \v(filename) */
- if (cmd_quoting) { /* But only if cmd_quoting is on */
- y = MAXRP;
- s = (char *)srvcmd;
- zzstring(snd_rename,&s,&y);
- s = (char *)srvcmd;
- }
-#endif /* NOSPL */
- if (s) if (*s) {
- int x;
- x = zrename(filnam,s);
-#ifdef TLOG
- if (tralog) {
- if (x > -1) {
- tlog(F110," renamed to",s,0);
- } else {
- tlog(F110," rename failed:",ck_errstr(),0);
- }
- }
-#endif /* TLOG */
-#ifdef COMMENT
- *s = NUL;
-#endif /* COMMENT */
- }
- }
- }
- if (czseen) { /* Check group interruption flag */
- g = 0; /* No more files if interrupted */
- } else { /* Otherwise... */
-#ifdef COMMENT
- /* This code makes any open error fatal to a file-group transfer. */
- g = gnfile();
- debug(F111,"<sseof>Y gnfile",filnam,g);
- if (g > 0) { /* Any more files to send? */
- if (sfile(xflg)) /* Yes, try to send next file header */
- BEGIN ssfile; /* if ok, enter send-file state */
- else { /* otherwise */
- s = xflg ? "Can't execute command" : (char *)epktmsg;
- if (!*s) s = "Can't open file";
- errpkt((CHAR *)s); /* send error message */
- RESUME; /* and quit */
- }
- } else { /* No next file */
- tsecs = gtimer(); /* get statistics timers */
-#ifdef GFTIMER
- fptsecs = gftimer();
-#endif /* GFTIMER */
- seot(); /* send EOT packet */
- BEGIN sseot; /* enter send-eot state */
- }
-#else /* COMMENT */
- while (1) { /* Keep trying... */
- g = gnfile(); /* Get next file */
- debug(F111,"<sseof>Y gnfile",filnam,g);
- if (g == 0 && gnferror == 0) /* No more, stop trying */
- break;
- if (g > 0) { /* Have one */
- if (sfile(xflg)) { /* Try to open and send F packet */
- BEGIN ssfile; /* If OK, enter send-file state */
- break; /* and break out of loop. */
- }
- } /* Otherwise keep trying to get one we can send... */
- }
- }
- if (g == 0) {
- debug(F101,"<sseof>Y no more files","",czseen);
- tsecs = gtimer(); /* Get statistics timers */
-#ifdef GFTIMER
- fptsecs = gftimer();
-#endif /* GFTIMER */
- seot(); /* Send EOT packet */
- BEGIN sseot; /* Enter send-eot state */
- }
-#endif /* COMMENT */
-}
-
-<sseot>Y { /* Got ACK to EOT */
- debug(F101,"sseot justone","",justone);
- RESUME; /* All done, just quit */
-}
-
-E { /* Got Error packet, in any state */
- char *s = "";
- window(1); /* Close window */
- timint = s_timint; /* Restore original timeout */
- if (*epktmsg) /* Message from Error packet */
- s = (char *)epktmsg;
- if (!*s) { /* If not there then maybe here */
- s = (char *)rdatap;
- ckstrncpy((char *)epktmsg,(char *)rdatap,PKTMSGLEN);
- }
- if (!*s) /* Hopefully we'll never see this. */
- s = "Unknown error";
- success = 0; /* For IF SUCCESS/FAIL. */
- debug(F101,"ckcpro.w justone at E pkt","",justone);
-
- success = 0; /* Transfer failed */
- xferstat = success; /* Remember transfer status */
- if (!epktsent) {
- x = quiet; quiet = 1; /* Close files silently, */
- epktrcvd = 1; /* Prevent messages from clsof() */
- clsif();
- clsof(1); /* discarding any output file. */
- ermsg(s); /* Issue the message (calls screen). */
- quiet = x; /* Restore quiet state */
- }
- tstats(); /* Get stats */
-/*
- If we are executing commands from a command file or macro, let the command
- file or macro decide whether to exit, based on SET { TAKE, MACRO } ERROR.
-*/
- if (
-#ifndef NOICP
- !xcmdsrc &&
-#endif /* NOICP */
- backgrd && !server)
- fatal("Protocol error");
- xitsta |= (what & W_KERMIT); /* Save this for doexit(). */
-#ifdef CK_TMPDIR
-/* If we were cd'd temporarily to another device or directory ... */
- if (f_tmpdir) {
- int x;
- x = zchdir((char *) savdir); /* ... restore previous directory */
- f_tmpdir = 0; /* and remember we did it. */
- debug(F111,"ckcpro.w E tmpdir restored",savdir,x);
- }
-#endif /* CK_TMPDIR */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"ERROR", (char *)epktmsg, "");
-#endif /* IKSDB */
- RESUME;
-}
-
-q { success = 0; QUIT; } /* Ctrl-C or connection loss. */
-
-. { /* Anything not accounted for above */
- errpkt((CHAR *)"Unexpected packet type"); /* Give error message */
- window(1);
- xitsta |= (what & W_KERMIT); /* Save this for doexit(). */
- RESUME; /* and quit */
-}
-
-%%
-
-/*
- From here down to proto() are routines that were moved out of the state
- table switcher because the resulting switch() had become too large.
- To move the contents of a state-table case to a routine:
- 1. Add a prototype to the list above the state table switcher.
- 2. Make a routine with an appropriate name, returning int.
- 3. Move the code into it.
- 4. Put a call to the new routine in the former spot:
- rc = name_of_routine();
- if (rc > -1) return(rc);
- 5. Add "return(-1);" after every RESUME, SERVE, or BEGIN macro and
- at the end if the code is open-ended.
-*/
-static int
-rcv_firstdata() {
- extern int dispos;
- debug(F101,"rcv_firstdata","",dispos);
-
- if (discard) { /* if we're discarding the file */
- ack1((CHAR *)"X"); /* just ack the data like this. */
- cancel++; /* and count it */
- BEGIN rdpkt; /* and wait for more data packets. */
- return(-1);
- } else { /* Not discarding. */
- rf_err = "Can't open file";
- if (xflg) { /* If screen data */
- if (remfile) { /* redirected to file */
- if (rempipe) /* or pipe */
- x = openc(ZOFILE,remdest); /* Pipe: start command */
- else
- x = opena(remdest,&iattr); /* File: open with attributes */
- } else { /* otherwise */
- x = opent(&iattr); /* "open" the screen */
- }
- } else { /* otherwise */
-#ifdef CALIBRATE
- if (calibrate) { /* If calibration run */
- x = ckopenx(&iattr); /* open nothing */
-#ifdef STREAMING
- if (streaming) /* Streaming */
- fastack(); /* ACK without ACKing. */
- else
-#endif /* STREAMING */
- ack(); /* Send real ACK */
- BEGIN rdpkt; /* Proceed to next state */
- return(-1);
- } else
-#endif /* CALIBRATE */
-#ifdef UNIX
-/*
- In UNIX we can pipe the file data into the mail program, which is to be
- preferred to writing it out to a temp file and then mailing it afterwards.
- This depends rather heavily on all UNIXes having a mail command that
- accepts '-s "subject"' on the command line. MAILCMD (e.g. mail, Mail, mailx)
- is defined in ckufio.c.
-*/
- if (dispos == 'M') { /* Mail... */
- char *s;
- char * tmp = NULL;
- int n = 0;
- extern char *MAILCMD;
- s = iattr.disp.val + 1;
- n = (int)strlen(MAILCMD) + /* Mail command */
- (int)strlen(s) + /* address */
- (int)strlen(ofilnam) + 32; /* subject */
- if (tmp = (char *)malloc(n)) {
- ckmakxmsg(tmp,n,
- MAILCMD," -s \"",ofilnam,"\" ",s,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- debug(F111,"rcv_firsdata mail",tmp,(int)strlen(tmp));
- x = openc(ZOFILE,(char *)tmp);
- free(tmp);
- } else
- x = 0;
- } else if (dispos == 'P') { /* Ditto for print */
- char * tmp = NULL;
- int n;
- extern char *PRINTCMD;
- n = (int)strlen(PRINTCMD) + (int)strlen(iattr.disp.val+1) + 4;
- if (tmp = (char *)malloc(n)) {
- sprintf(tmp, /* safe (prechecked) */
- "%s %s", PRINTCMD, iattr.disp.val + 1);
- x = openc(ZOFILE,(char *)tmp);
- free(tmp);
- } else
- x = 0;
- } else
-#endif /* UNIX */
- x = opena(filnam,&iattr); /* open the file, with attributes */
- }
- if (x) { /* If file was opened ok */
- int rc, qf;
-#ifndef NOSPL
- qf = query;
-#else
- qf = 0;
-#endif /* NOSPL */
-
-#ifdef CKTUNING
- rc = (binary && !parity) ?
- bdecode(rdatap,putfil):
- decode(rdatap, qf ? puttrm : putfil, 1);
-#else
- rc = decode(rdatap, qf ? puttrm : putfil, 1);
-#endif /* CKTUNING */
- if (rc < 0) {
- errpkt((CHAR *)"Error writing data");
- RESUME;
- return(-1);
- }
-#ifdef STREAMING
- if (streaming) /* Streaming was negotiated */
- fastack(); /* ACK without ACKing. */
- else
-#endif /* STREAMING */
- ack(); /* acknowledge it */
- BEGIN rdpkt; /* and switch to receive-data state */
- return(-1);
- } else { /* otherwise */
- errpkt((CHAR *) rf_err); /* send error packet */
- RESUME; /* and quit. */
- return(-1);
- }
- }
-}
-
-static int
-rcv_shortreply() {
-#ifdef PKTZEROHACK
- success = 0;
- debug(F111,"rcv_shortreply",rdatap,ipktlen);
- if (ipktack[0] && !strncmp(ipktack,(char *)rdatap,ipktlen)) {
- /* No it's the ACK to the I packet again */
- x = scmd(vcmd,(CHAR *)cmarg); /* So send the REMOTE command again */
- /* Maybe this should be resend() */
- debug(F110,"IPKTZEROHACK",ipktack,x);
- if (x < 0) {
- errpkt((CHAR *)srimsg);
- RESUME;
- return(-1);
- }
- } else {
- ipktack[0] = NUL;
-#endif /* PKTZEROHACK */
- urserver = 1;
-#ifndef NOSERVER
-#ifndef NOSPL
- if (query) { /* If to query, */
- qbufp = querybuf; /* initialize query response buffer */
- qbufn = 0;
- querybuf[0] = NUL;
- }
-#endif /* NOSPL */
- x = 1;
- if (remfile) { /* Response redirected to file */
- rf_err = "Can't open file";
- if (rempipe) /* or pipe */
- x =
-#ifndef NOPUSH
- zxcmd(ZOFILE,remdest) /* Pipe: Start command */
-#else
- 0
-#endif /* NOPUSH */
- ;
- else
- x = opena(remdest,&iattr); /* File: Open with attributes */
- debug(F111,"rcv_shortreply remfile",remdest,x);
- } else {
- x = opent(&iattr); /* "open" the screen */
- }
- if (x) { /* If file was opened ok */
- if (decode(rdatap,
-#ifndef NOSPL
- (query || !remfile) ? puttrm :
-#else
- !remfile ? puttrm :
-#endif /* NOSPL */
- zputfil, 1) < 0) { /* Note: zputfil, not putfil. */
- errpkt((CHAR *)"Error writing data");
- RESUME;
- return(-1);
- } else {
- if (rdatap) /* If we had data */
- if (*rdatap) /* add a line terminator */
- if (remfile) { /* to file */
- zsoutl(ZOFILE,"");
- } else { /* or to screen. */
-#ifndef NOICP
- if (!query || !xcmdsrc)
-#endif /* NOICP */
- if (!(quiet && rcdactive))
- conoll("");
- }
- if (bye_active && network) { /* I sent BYE or REMOTE LOGOUT */
- msleep(500); /* command and got the ACK... */
- bye_active = 0;
- ttclos(0);
- }
- clsof(0);
- if (!epktsent && !epktrcvd) /* If no error packet... */
- success = 1; /* success. */
- RESUME;
- return(-1);
- }
- } else { /* File not opened OK */
- errpkt((CHAR *) rf_err); /* send error message */
- RESUME; /* and quit. */
- return(-1);
- }
-#endif /* NOSERVER */
-#ifdef PKTZEROHACK
- }
-#endif /* PKTZEROHACK */
- debug(F101,"rcv_shortreply fallthru","",success);
- return(-1);
-}
-
-
-static int
-srv_query() {
-#ifndef NOSERVER
-#ifndef NOSPL
- char c;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE QUERY", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE QUERY", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- c = *(srvcmd+2); /* Q = Query, S = Set */
- if (c == 'Q') { /* Query */
- if (!ENABLED(en_que)) { /* Security */
- errpkt((CHAR *)"REMOTE QUERY disabled");
- RESUME;
- return(-1);
- } else { /* Query allowed */
- int n; char *p, *q;
- qbufp = querybuf; /* Wipe out old stuff */
- qbufn = 0;
- querybuf[0] = NUL;
- p = (char *) srvcmd + 3; /* Pointer for making wrapper */
- n = strlen((char *)srvcmd); /* Position of end */
- c = *(srvcmd+4); /* Which type of variable */
-
- if (*(srvcmd+6) == CMDQ) { /* Starts with command quote? */
- p = (char *) srvcmd + 6; /* Take it literally */
- if (*p == CMDQ) p++;
- } else { /* They played by the rules */
- if (c == 'K') { /* Kermit variable */
- int k;
- k = (int) strlen(p);
- if (k > 0 && p[k-1] == ')') {
- p = (char *)(srvcmd + 4);
- *(srvcmd+4) = CMDQ;
- *(srvcmd+5) = 'f'; /* Function, so make it \f...() */
- } else {
- *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */
- *(srvcmd+4) = 'v'; /* Variable, so make it \v(...) */
- *(srvcmd+5) = '('; /* around variable name */
- *(srvcmd+n) = ')';
- *(srvcmd+n+1) = NUL;
- }
- } else {
- *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */
- *(srvcmd+4) = 'v'; /* Variable, so make it \v(...) */
- *(srvcmd+5) = '('; /* around variable name */
- *(srvcmd+n) = ')';
- *(srvcmd+n+1) = NUL;
- if (c == 'S') { /* System variable */
- *(srvcmd+4) = '$'; /* so it's \$(...) */
- } else if (c == 'G') { /* Non-\ Global variable */
- *(srvcmd+4) = 'm'; /* so wrap it in \m(...) */
- }
- }
- } /* Now evaluate it */
- n = QBUFL; /* Max length */
- q = querybuf; /* Where to put it */
- if (zzstring(p,&q,&n) < 0) {
- errpkt((n > 0) ? (CHAR *)"Can't get value"
- : (CHAR *)"Value too long"
- );
- RESUME;
- return(-1);
- } else {
- if (encstr((CHAR *)querybuf) > -1) { /* Encode it */
- ack1(data); /* If it fits, send it back in ACK */
- success = 1;
- RESUME;
- return(-1);
- } else if (sndstring(querybuf)) { /* Long form response */
- BEGIN ssinit;
- return(-1);
- } else { /* sndhlp() fails */
- errpkt((CHAR *)"Can't send value");
- RESUME;
- return(-1);
- }
- }
- }
- } else if (c == 'S') { /* Set (assign) */
- if (!ENABLED(en_asg)) { /* Security */
- errpkt((CHAR *)"REMOTE ASSIGN disabled");
- RESUME;
- return(-1);
- } else { /* OK */
- int n;
- n = xunchar(*(srvcmd+3)); /* Length of name */
- n = 3 + n + 1; /* Position of length of value */
- *(srvcmd+n) = NUL; /* Don't need it */
- if (addmac((char *)(srvcmd+4),(char *)(srvcmd+n+1)) < 0)
- errpkt((CHAR *)"REMOTE ASSIGN failed");
- else {
- ack();
- success = 1;
- }
- RESUME;
- return(-1);
- }
- } else {
- errpkt((CHAR *)"Badly formed server command");
- RESUME;
- return(-1);
- }
-#else
- errpkt((CHAR *)"Variable query/set not available");
- RESUME;
- return(-1);
-#endif /* NOSPL */
-#endif /* NOSERVER */
-}
-
-static int
-srv_copy() {
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE COPY", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef ZCOPY
- if (!ENABLED(en_cpy)) {
- errpkt((CHAR *)"REMOTE COPY disabled");
- RESUME;
- return(-1);
- } else {
- char *str1, *str2, f1[256], f2[256];
- int len1, len2;
- len1 = xunchar(srvcmd[1]); /* Separate the parameters */
- len2 = xunchar(srvcmd[2+len1]);
- strncpy(f1,(char *)(srvcmd+2),len1);
- f1[len1] = NUL;
- strncpy(f2,(char *)(srvcmd+3+len1),len2);
- f2[len2] = NUL;
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE COPY", f1, f2);
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* If CWD is disabled */
- zstrip(f1,&str1); /* and they included a pathname, */
- zstrip(f2,&str2);
- if (strcmp(f1,str1) || strcmp(f2,str2)) { /* Refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- return(-1);
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
- if (zcopy(f1,f2)) { /* Try */
- errpkt((CHAR *)"Can't copy file"); /* give error message */
- } else {
- success = 1;
- ack();
- }
- RESUME; /* wait for next server command */
- return(-1);
- }
- }
- return(-1);
-#else /* no ZCOPY */
- errpkt((CHAR *)"REMOTE COPY not available"); /* give error message */
- RESUME; /* wait for next server command */
- return(-1);
-#endif /* ZCOPY */
-#endif /* NOSERVER */
-}
-
-static int
-srv_rename() {
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE RENAME", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef ZRENAME
- if (!ENABLED(en_ren)) {
- errpkt((CHAR *)"REMOTE RENAME disabled");
- RESUME;
- return(-1);
- } else { /* RENAME is enabled */
- char *str1, *str2, f1[256], f2[256];
- int len1, len2;
- len1 = xunchar(srvcmd[1]); /* Separate the parameters */
- len2 = xunchar(srvcmd[2+len1]);
- strncpy(f1,(char *)(srvcmd+2),len1);
- f1[len1] = NUL;
- strncpy(f2,(char *)(srvcmd+3+len1),len2);
- f2[len2] = NUL;
- len2 = xunchar(srvcmd[2+len1]);
- strncpy(f1,(char *)(srvcmd+2),len1);
- f1[len1] = NUL;
- strncpy(f2,(char *)(srvcmd+3+len1),len2);
- f2[len2] = NUL;
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE RENAME", f1, f2);
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* If CWD is disabled */
- zstrip(f1,&str1); /* and they included a pathname, */
- zstrip(f2,&str2);
- if ( strcmp(f1,str1) || strcmp(f2,str2) ) { /* refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- return(-1);
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
- if (zrename(f1,f2)) { /* Try */
- errpkt((CHAR *)"Can't rename file"); /* Give error msg */
- } else {
- success = 1;
- ack();
- }
- RESUME; /* Wait for next server command */
- return(-1);
- }
- }
- return(-1);
-#else /* no ZRENAME */
- /* Give error message */
- errpkt((CHAR *)"REMOTE RENAME not available");
- RESUME; /* Wait for next server command */
- return(-1);
-#endif /* ZRENAME */
-#endif /* NOSERVER */
-}
-
-static int
-srv_login() {
-#ifndef NOSERVER
- char f1[LOGINLEN+1], f2[LOGINLEN+1], f3[LOGINLEN+1];
- CHAR *p;
- int len, i;
-
- debug(F101,"REMOTE LOGIN x_login","",x_login);
- debug(F101,"REMOTE LOGIN x_logged","",x_logged);
-
- f1[0] = NUL; f2[0] = NUL; f3[0] = NUL;
- len = 0;
- if (srvcmd[1]) /* First length field */
- len = xunchar(srvcmd[1]); /* Separate the parameters */
-
- if (x_login) { /* Login required */
- if (x_logged) { /* And already logged in */
- if (len > 0) { /* Logging in again */
- errpkt((CHAR *)"Already logged in.");
- } else { /* Logging out */
- debug(F101,"REMOTE LOGOUT","",x_logged);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGOUT", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE LOGOUT", "", "");
-#endif /* IKSDB */
- tlog(F110,"Logged out",x_user,0);
- ack1((CHAR *)"Logged out");
- success = 1;
- msleep(500);
-#ifdef CK_LOGIN
- x_logged = 0;
-#ifdef IKSD
- if (inserver)
- ckxlogout();
-#endif /* IKSD */
-#endif /* CK_LOGIN */
- }
- } else { /* Not logged in yet */
- debug(F101,"REMOTE LOGIN len","",len);
- if (len > 0) { /* Have username */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGIN", NULL);
-#endif /* CKSYSLOG */
- if (len > LOGINLEN) {
- errpkt((CHAR *)"Username too long");
- }
- p = srvcmd + 2; /* Point to it */
- for (i = 0; i < len; i++) /* Copy it */
- f1[i] = p[i];
- f1[len] = NUL; /* Terminate it */
- p += len; /* Point to next length field */
- if (*p) { /* If we have one */
- len = xunchar(*p++); /* decode it */
- if (len > 0 && len <= LOGINLEN) {
- for (i = 0; i < len; i++) /* Same deal for password */
- f2[i] = p[i];
- f2[len] = NUL;
- p += len; /* And account */
- if (*p) {
- len = xunchar(*p++);
- if (len > 0 && len <= LOGINLEN) {
- for (i = 0; i < len; i++)
- f3[i] = p[i]; /* Set but never used */
- f3[len] = NUL; /* (because account not used) */
- }
- }
- }
- }
- debug(F101,"REMOTE LOGIN 1","",x_logged);
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver) { /* Log in to system for real */
- x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0);
- debug(F101,"REMOTE LOGIN 2","",x_logged);
- if (x_logged) { /* Count attempts */
- logtries = 0;
- justone = 1;
- } else {
- logtries++;
- sleep(logtries);
- }
- } else
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- if (x_user && x_passwd) { /* User and password must match */
- if (!strcmp(x_user,f1)) /* SET SERVER LOGIN */
- if (!strcmp(x_passwd,f2))
- x_logged = 1;
- debug(F101,"REMOTE LOGIN 3","",x_logged);
- } else if (x_user) { /* Only username given, no password */
- if (!strcmp(x_user,f1)) /* so only username must match */
- x_logged = 1;
- debug(F101,"REMOTE LOGIN 4","",x_logged);
- }
-#ifdef CK_LOGIN
- else {
- x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0);
- debug(F101,"REMOTE LOGIN 5","",x_logged);
- }
-#endif /* CK_LOGIN */
- if (x_logged) { /* Logged in? */
- tlog(F110,"Logged in", x_user, 0);
- if (isguest)
- ack1((CHAR *)"Logged in as guest - restrictions apply");
- else
- ack1((CHAR *)"Logged in");
- success = 1;
- } else {
- tlog(F110,"Login failed", f1, 0);
- errpkt((CHAR *)"Access denied.");
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && logtries > 2)
- ckxlogout();
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- }
- } else { /* LOGOUT */
- errpkt((CHAR *)"Logout ignored");
- }
- }
- } else { /* Login not required */
- if (len > 0)
- errpkt((CHAR *)"Login ignored.");
- else
- errpkt((CHAR *)"Logout ignored.");
- }
-#endif /* NOSERVER */
- RESUME;
- return(-1);
-}
-
-static int
-srv_timeout() {
- /* K95 does this its own way */
- if (idletmo) {
-#ifdef IKSD
- if (inserver) {
- printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", srvidl);
- doexit(GOOD_EXIT,xitsta);
- }
-#endif /* IKSD */
- idletmo = 0;
- printf("\r\nSERVER IDLE TIMEOUT: %d sec\r\n", srvidl);
- xitsta |= (what & W_KERMIT);
- QUIT;
- }
-#ifndef NOSERVER
- else if (fatalio) { /* Connection lost */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Connection lost", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"SERVER DISCONNECT",(char *)srvcmd, "");
-#endif /* IKSDB */
- xitsta |= what;
- QUIT;
- } else if (interrupted) { /* Interrupted by hand */
- if (!ENABLED(en_fin)) {
- errpkt((CHAR *)"QUIT disabled");
- RESUME;
- return(-1);
- } else {
- if (what == W_SEND || what == W_RECV || what == W_REMO) {
- success = 0;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
-#endif /* CKSYSLOG */
- } else if (what == W_NOTHING && filcnt == 0) {
- success = 1;
- } /* Otherwise leave success alone */
- xitsta |= (what & W_KERMIT);
- QUIT;
- }
- } else { /* Shouldn't happen */
- debug(F100,"SERVER (top) GOT UNEXPECTED 'q'","",0);
- QUIT;
- }
-#endif /* NOSERVER */
-}
-
-static int
-rcv_s_pkt() {
-#ifndef NOSERVER
- if (state == rgen)
- urserver = 1;
- if (/* state == serve && */ x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else
-#endif /* NOSERVER */
- if (state == serve && !ENABLED(en_sen)) { /* Not in server mode */
- errpkt((CHAR *)"SEND disabled"); /* when SEND is disabled. */
- RESUME;
- return(-1);
- } else { /* OK to go ahead. */
-#ifdef CK_TMPDIR
- if (dldir && !f_tmpdir) { /* If they have a download directory */
- debug(F110,"receive download dir",dldir,0);
- if (s = zgtdir()) { /* Get current directory */
- debug(F110,"receive current dir",s,0);
- if (zchdir(dldir)) { /* Change to download directory */
- debug(F100,"receive zchdir ok","",0);
- ckstrncpy(savdir,s,TMPDIRLEN);
- f_tmpdir = 1; /* Remember that we did this */
- } else
- debug(F100,"receive zchdir failed","",0);
- }
- }
-#endif /* CK_TMPDIR */
- nakstate = 1; /* Can send NAKs from here. */
- rinit(rdatap); /* Set parameters */
- if (bctf) {
- bctu = 3;
- bctl = 3;
- } else {
- bctu = bctr; /* switch to agreed-upon block check */
- bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */
- }
- what = W_RECV; /* Remember we're receiving */
- lastxfer = W_RECV;
- resetc(); /* Reset counters */
- rtimer(); /* Reset timer */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- streamon();
- BEGIN rfile; /* Go into receive-file state */
- }
- return(-1);
-}
-
-
-/* END OF ROUTINES MOVED OUT OF STATE MACHINE */
-
-
-/* P R O T O -- Protocol entry function */
-
-static int is_tn = 0; /* It's a Telnet connection */
-
-#ifdef CK_SPEED
-int f_ctlp = 0; /* Control-character prefix table */
-#ifdef COMMENT
-short s_ctlp[256];
-#endif /* COMMENT */
-#endif /* CK_SPEED */
-
-/*
- This is simply a wrapper for the real protocol function just below,
- that saves any items that might be changed automatically by protocol
- negotiations and then restores them upon exit from protocol mode.
-*/
-VOID
-proto() {
- extern int b_save, f_save, c_save, ss_save, slostart, reliable, urclear;
-#ifndef NOCSETS
- extern int fcharset, fcs_save, tcharset, tcs_save;
-#endif /* NOCSETS */
-
-#ifdef PIPESEND
- extern int pipesend;
-#endif /* PIPESEND */
-#ifndef NOLOCAL
-#ifdef OS2
- extern int cursorena[], cursor_save, term_io;
- extern BYTE vmode;
- extern int display_demo;
- int term_io_save;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef TNCODE
- int _u_bin=0, _me_bin = 0;
-#ifdef IKS_OPTION
- int /* _u_start=0, */ _me_start = 0;
-#endif /* IKS_OPTION */
-#endif /* TNCODE */
-#ifdef PATTERNS
- int pa_save;
- int i;
-#endif /* PATTERNS */
- int scan_save;
-
-#ifdef PATTERNS
- pa_save = patterns;
-#endif /* PATTERNS */
- scan_save = filepeek;
-
- myjob = sstate;
-
-#ifdef CK_LOGIN
- if (isguest) { /* If user is anonymous */
- en_pri = 0; /* disable printing */
- en_mai = 0; /* and disable email */
- en_del = 0; /* and file deletion */
- }
-#endif /* CK_LOGIN */
-
-#ifndef NOLOCAL
-#ifdef OS2
- cursor_save = cursorena[vmode];
- cursorena[vmode] = 0;
- term_io_save = term_io;
- term_io = 0;
-#endif /* OS2 */
-#endif /* NOLOCAL */
- b_save = binary; /* SET FILE TYPE */
- f_save = fncnv; /* SET FILE NAMES */
- c_save = bctr;
- p_save = fnspath;
- r_save = recursive;
- s_timint = timint;
- ss_save = slostart;
-#ifndef NOCSETS
- fcs_save = fcharset;
- tcs_save = tcharset;
-#endif /* NOCSETS */
-
-#ifdef COMMENT
-/* Don't do this because then user can never find out what happened. */
-#ifdef CK_SPEED
- for (i = 0; i < 256; i++)
- s_ctlp[i] = ctlp[i];
- f_ctlp = 1;
-#endif /* CK_SPEED */
-#endif /* COMMENT */
- if (reliable == SET_ON)
- slostart = 0;
- is_tn = (!local && sstelnet)
-#ifdef TNCODE
- || (local && network && ttnproto == NP_TELNET)
-#endif /* TNCODE */
- ;
-#ifdef TNCODE
- if (is_tn) {
- if (tn_b_xfer && !(sstelnet || inserver)) {
- /* Save the current state of Telnet Binary */
- _u_bin = TELOPT_U(TELOPT_BINARY);
- _me_bin = TELOPT_ME(TELOPT_BINARY);
-
- /* If either direction is not Binary attempt to negotiate it */
- if (!_u_bin && TELOPT_U_MODE(TELOPT_BINARY) != TN_NG_RF) {
- tn_sopt(DO,TELOPT_BINARY);
- TELOPT_UNANSWERED_DO(TELOPT_BINARY) = 1;
- }
- if (!_me_bin && TELOPT_ME_MODE(TELOPT_BINARY) != TN_NG_RF) {
- tn_sopt(WILL,TELOPT_BINARY);
- TELOPT_UNANSWERED_WILL(TELOPT_BINARY) = 1;
- }
- if (!(_me_bin && _u_bin))
- tn_wait("proto set binary mode");
- }
-#ifdef IKS_OPTION
-#ifdef CK_XYZ
- if (protocol != PROTO_K) { /* Non-Kermit protocol selected */
- if (TELOPT_U(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */
- /* _u_start = 1; */
- }
- if (TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_STOP); /* I'm not servering */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- _me_start = 1;
- }
- } else
-#endif /* CK_XYZ */
- if (sstate == 'x' || sstate == 'v') { /* Responding to a request */
- if (!inserver && TELOPT_U(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */
- /* _u_start = 1; */
- }
- if (TELOPT_ME(TELOPT_KERMIT) &&
- !TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_START); /* Send Kermit-Server Start */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 1;
- }
- } else { /* Initiating a request */
- if (TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_STOP); /* I'm not servering */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- _me_start = 1;
- }
- if (TELOPT_U(TELOPT_KERMIT) &&
- !TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- /* Send Req-Server-Start */
- if (!iks_wait(KERMIT_REQ_START,0)) {
- if (sstate != 's') {
- success = 0; /* Other Kermit refused to serve */
- if (local)
- printf("A Kermit Server is not available\r\n");
- debug(F110,"proto()",
- "A Kermit Server is not available",0);
- tlog(F110,"IKS client/server failure",
- "A Kermit Server is not available",0);
- goto xxprotox;
- }
- }
- }
- }
-#endif /* IKS_OPTION */
-#ifdef CK_ENCRYPTION
- if (tn_no_encrypt_xfer && !(sstelnet || inserver)) {
- ck_tn_enc_stop();
- }
-#endif /* CK_ENCRYPTION */
- }
-#endif /* TNCODE */
-
- if (!xfrint) connoi();
- xxproto(); /* Call the real protocol function */
-
-#ifdef IKS_OPTION
- xxprotox:
-#endif /* IKS_OPTION */
- xferstat = success; /* Remember transfer status */
- kactive = 0;
-
-#ifdef TNCODE
-#ifdef CK_ENCRYPTION
- if (tn_no_encrypt_xfer && !(sstelnet || inserver)) {
- ck_tn_enc_start();
- }
-#endif /* CK_ENCRYPTION */
-#ifdef IKS_OPTION
- if (TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start && !_me_start) {
- tn_siks(KERMIT_STOP); /* Server is stopped */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- }
-#endif /* IKS_OPTION */
- if (is_tn && tn_b_xfer && !(sstelnet || inserver)) {
- /* if we negotiated Binary mode try to reset it */
- if (!_u_bin) {
- /* Check to see if the state changed during the transfer */
- if (TELOPT_U(TELOPT_BINARY)) {
- tn_sopt(DONT,TELOPT_BINARY);
- TELOPT_UNANSWERED_DONT(TELOPT_BINARY) = 1;
- } else
- _u_bin = 1; /* So we don't call tn_wait() */
- }
- if (!_me_bin) {
- /* Check to see if the state changed during the transfer */
- if (TELOPT_ME(TELOPT_BINARY)) {
- tn_sopt(WONT,TELOPT_BINARY);
- TELOPT_UNANSWERED_WONT(TELOPT_BINARY) = 1;
- } else
- _me_bin = 1; /* So we don't call tn_wait() */
- }
- if (!(_me_bin && _u_bin))
- tn_wait("proto reset binary mode");
- }
-#endif /* TNCODE */
-
-#ifdef PATTERNS
- patterns = pa_save;
-#endif /* PATTERNS */
- filepeek = scan_save;
-
-#ifdef STREAMING
- streaming = 0;
- /* streamok = 0; */
-#endif /* STREAMING */
-#ifdef COMMENT
-#ifdef CK_SPEED
- for (i = 0; i < 256; i++)
- ctlp[i] = s_ctlp[i];
- f_ctlp = 0;
-#endif /* CK_SPEED */
-#endif /* COMMENT */
- urclear = 0;
- if (!success) {
- xitsta |= (what & W_KERMIT);
- tlog(F110," failed:",(char *)epktmsg,0);
- }
- debug(F111,"proto xferstat",epktmsg,xferstat);
- slostart = ss_save;
- if (s_timint > -1) { /* Because of REMOTE SET */
- timint = s_timint;
- s_timint = -1;
- }
- recursive = r_save;
- fnspath = p_save;
- if (c_save > -1) { /* Because of REMOTE SET */
- bctr = c_save;
- c_save = -1;
- }
- fncnv = f_save;
- binary = b_save;
-#ifdef PIPESEND
- pipesend = 0; /* Next time might not be pipesend */
-#endif /* PIPESEND */
-#ifndef NOLOCAL
-#ifdef OS2
- cursorena[vmode] = cursor_save;
- term_io = term_io_save;
- display_demo = 1;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-}
-
-static VOID
-xxproto() {
- int x;
- long lx;
-#ifdef CK_XYZ
-#ifdef XYZ_INTERNAL
-_PROTOTYP( int pxyz, (int) );
-#endif /* XYZ_INTERNAL */
-#endif /* CK_XYZ */
-
- char xss[2]; /* String representation of sstate */
- xss[0] = sstate;
- xss[1] = NUL;
- s_timint = timint;
-
- debug(F101,"xxproto entry justone","",justone);
- success = 0;
-
- retrieve = 0; /* Reset these ... */
- reget = 0;
- opkt = 0;
-
- if (local && ttchk() < 0) { /* Giving BYE or FIN */
- if (bye_active) { /* but there is no connection */
- ttclos(0);
- success = 1;
- return;
- }
- /* Ditto for any REMOTE command */
- if (sstate == 'g' && cmarg ) {
- if (*cmarg == 'L' || *cmarg == 'F' || *cmarg == 'X')
- success = 1;
- else
- printf("?No connection\r\n");
- return;
- }
- }
-
-/* Set up the communication line for file transfer. */
-/* NOTE: All of the xxscreen() calls prior to the wart() invocation */
-/* could just as easily be printf's or, for that matter, hints. */
-
- if (local && (speed < 0L) && (network == 0)) {
- xxscreen(SCR_EM,0,0L,"Sorry, you must 'set speed' first");
- return;
- }
- x = -1;
- if (ttopen(ttname,&x,mdmtyp,cdtimo) < 0) {
- debug(F111,"failed: proto ttopen local",ttname,local);
- xxscreen(SCR_EM,0,0L,"Can't open line");
- return;
- }
- if (x > -1) local = x;
- debug(F111,"proto ttopen local",ttname,local);
-
- lx = (local && !network) ? speed : -1;
-#ifdef NETCONN
-#ifdef CK_SPEED
- if (is_tn) {
- ctlp[(unsigned)255] = ctlp[CR] = 1;
- if (parity == 'e' || parity == 'm') ctlp[127] = 1;
- if (flow == FLO_XONX) { /* Also watch out for Xon/Xoff */
- ctlp[17] = ctlp[19] = 1;
- ctlp[17+128] = ctlp[19+128] = 1;
- }
- }
-#endif /* CK_SPEED */
-#endif /* NETCONN */
- if (ttpkt(lx,flow,parity) < 0) { /* Put line in packet mode, */
- xxscreen(SCR_EM,0,0L,"Can't condition line");
- return;
- }
- if (local && !network && carrier != CAR_OFF) {
- int x; /* Serial connection */
- x = ttgmdm(); /* with carrier checking */
- if (x > -1) {
- if (!(x & BM_DCD)) {
- debug(F101,"proto ttgmdm","",0);
- xxscreen(SCR_EM,0,0L,"Carrier required but not detected");
- return;
- }
- }
- }
- /* Send remote side's "receive" or "server" startup string, if any */
- if (local && ckindex((char *)xss,"srgcjhk",0,0,1)) {
- char *s = NULL;
- if (
-#ifdef IKS_OPTION
- /* Don't send auto-blah string if we know other side is serving */
- !TELOPT_U(TELOPT_KERMIT) ||
- !TELOPT_SB(TELOPT_KERMIT).kermit.u_start
-#else
- 1
-#endif /* IKS_OPTION */
- ) {
- if (sstate == 's') { /* Sending file(s) */
- s = binary ? ptab[protocol].h_b_init : ptab[protocol].h_t_init;
- } else if (protocol == PROTO_K) { /* Command for server */
- s = ptab[protocol].h_x_init;
- }
- }
-#ifdef CK_SPEED
-#ifndef UNPREFIXZERO
- if (protocol == PROTO_K) /* Because of C-strings... */
- ctlp[0] = 1;
-#endif /* UNPREFIXZERO */
-#endif /* CK_SPEED */
- if (s) if (*s) { /* If we have a command to send... */
- char tmpbuf[356];
- int tmpbufsiz = 356;
- int stuff = -1, stuff2 = -1, len = 0;
- extern int tnlm;
- if (sstate == 's') { /* Sending file(s) */
-#ifdef CK_XYZ
- if (protocol == PROTO_X) {
- char * s2;
- s2 = cmarg2[0] ? cmarg2 : cmarg;
- if ((int)strlen(s) + (int)strlen(s2) + 4 < 356)
- sprintf(tmpbuf, s, s2);
- else
- tmpbuf[0] = NUL;
- } else {
-#endif /* CK_XYZ */
- ckmakmsg(tmpbuf, 356, s, NULL, NULL, NULL);
-#ifdef CK_XYZ
- }
-#endif /* CK_XYZ */
- } else { /* Command for server */
- ckstrncpy(tmpbuf,s,356);
- }
- ckstrncat(tmpbuf, "\015",sizeof(tmpbuf));
- if (tnlm) /* TERMINAL NEWLINE ON */
- stuff = LF; /* Stuff LF */
-#ifdef TNCODE
- /* TELNET NEWLINE MODE */
- if (is_tn) {
- switch (TELOPT_ME(TELOPT_BINARY) ? tn_b_nlm : tn_nlm) {
- case TNL_CR:
- break;
- case TNL_CRNUL:
- break;
- case TNL_CRLF:
- stuff2 = stuff;
- stuff = LF;
- break;
- }
- }
-#endif /* TNCODE */
-
-#ifdef NETCONN
-#ifdef TCPSOCKET
-#ifdef RLOGCODE
- if (network && ttnproto == NP_RLOGIN) {
- switch (tn_b_nlm) { /* Always BINARY */
- case TNL_CR:
- break;
- case TNL_CRNUL:
- stuff2 = stuff;
- stuff = NUL;
- break;
- case TNL_CRLF:
- stuff2 = stuff;
- stuff = LF;
- break;
- }
- }
-#endif /* RLOGCODE */
-#endif /* TCPSOCKET */
-#endif /* NETCONN */
-
- len = strlen(tmpbuf);
- if (stuff >= 0 && len < tmpbufsiz - 1) {
- tmpbuf[len++] = stuff;
- if (stuff2 >= 0 && len < tmpbufsiz - 1)
- tmpbuf[len++] = stuff2;
- tmpbuf[len] = NUL;
- }
- ttol((CHAR *)tmpbuf,len);
- if (protocol == PROTO_K) /* Give remote Kermit time to start */
- msleep(400);
- }
- }
-
-#ifdef CK_XYZ
- if (protocol != PROTO_K) { /* Non-Kermit protocol selected */
- char tmpbuf[356];
- int tmpbufsiz = 356;
- char * s = "";
-
-#ifdef CK_TMPDIR
- if (sstate == 'v') { /* If receiving and... */
- if (dldir && !f_tmpdir) { /* if they have a download directory */
- if (s = zgtdir()) { /* Get current directory */
- if (zchdir(dldir)) { /* Change to download directory */
- ckstrncpy(savdir,s,TMPDIRLEN);
- f_tmpdir = 1; /* Remember that we did this */
- }
- }
- }
- }
-#endif /* CK_TMPDIR */
-
-#ifdef XYZ_INTERNAL /* Internal */
- success = !pxyz(sstate);
-#else
-#ifdef CK_REDIR /* External */
- switch (sstate) {
- case 's': /* 'Tis better to SEND... */
- s = binary ? ptab[protocol].p_b_scmd : ptab[protocol].p_t_scmd;
- break;
- case 'v': /* ... than RECEIVE */
- s = binary ? ptab[protocol].p_b_rcmd : ptab[protocol].p_t_rcmd;
- break;
- }
- if (!s) s = "";
- if (*s) {
- if (sstate == 's') { /* Sending */
- extern int xfermode;
- int k = 0, x = 0, b = binary;
- /*
- If just one file we can scan it to set the xfer mode.
- Otherwise it's up to the external protocol program.
- */
- if (patterns && xfermode == XMODE_A && !iswild(fspec)) {
- extern int nscanfile;
- k = scanfile(fspec,&x,nscanfile);
- if (k > -1) {
- b = (k == FT_BIN) ? XYFT_B : XYFT_T;
- s = b ?
- ptab[protocol].p_b_scmd :
- ptab[protocol].p_t_scmd;
- }
- }
- if ((int)strlen(s) + (int)strlen(fspec) < tmpbufsiz) {
- sprintf(tmpbuf,s,fspec); /* safe (prechecked) */
- tlog(F110,"Sending",fspec,0L);
- }
- } else { /* Receiving */
- if ((int)strlen(s) + (int)strlen(cmarg2) < tmpbufsiz) {
- sprintf(tmpbuf,s,cmarg2); /* safe (prechecked) */
- tlog(F110,"Receiving",cmarg2,0L);
- }
- }
- tlog(F110," via external protocol:",tmpbuf,0);
- debug(F110,"ckcpro ttruncmd",tmpbuf,0);
- success = ttruncmd(tmpbuf);
- tlog(F110," status:",success ? "OK" : "FAILED", 0);
- } else {
- printf("?Sorry, no external protocol defined for %s\r\n",
- ptab[protocol].p_name
- );
- }
-#else
- printf(
-"Sorry, only Kermit protocol is supported in this version of Kermit\n"
- );
-#endif /* CK_REDIR */
-#endif /* XYZ_INTERNAL */
- return;
- }
-#endif /* CK_XYZ */
-
-#ifdef NTSIGX
- conraw();
- connoi();
-#else
- if (!local)
- connoi(); /* No console interrupts if remote */
-#endif /* NTSIG */
-
- kactive = 1;
- if (sstate == 'x') { /* If entering server mode, */
- extern int howcalled;
- server = 1; /* set flag, */
- debug(F101,"server backgrd","",backgrd);
- debug(F101,"server quiet","",quiet);
- debug(F100,"SHOULD NOT SEE THIS IF IN BACKGROUND!","",0);
- if (howcalled == I_AM_SSHSUB) { /* and issue appropriate message. */
- ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26);
- } else if (!local) {
- if (!quiet && !backgrd
-#ifdef IKS_OPTION
- && !TELOPT_ME(TELOPT_KERMIT) /* User was told by negotiation */
-#endif /* IKS_OPTION */
- ) {
- conoll(srvtxt);
- conoll("KERMIT READY TO SERVE...");
- }
- } else {
- conol("Entering server mode on ");
- conoll(ttname);
- conoll("Type Ctrl-C to quit.");
- if (srvdis) intmsg(-1L);
-#ifdef TCPSOCKET
-#ifndef NOLISTEN
- if (network && tcpsrfd > 0)
- ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26);
-#endif /* NOLISTEN */
-#endif /* TCPSOCKET */
- }
- } else
- server = 0;
-#ifdef VMS
- if (!quiet && !backgrd) /* So message doesn't overwrite prompt */
- conoll("");
- if (local) conres(); /* So Ctrl-C will work */
-#endif /* VMS */
-/*
- If in remote mode, not shushed, not in background, and at top command level,
- issue a helpful message telling what to do...
-*/
- if (!local && !quiet && !backgrd) {
- if (sstate == 'v') {
- conoll("Return to your local Kermit and give a SEND command.");
- conoll("");
- conoll("KERMIT READY TO RECEIVE...");
- } else if (sstate == 's') {
- conoll("Return to your local Kermit and give a RECEIVE command.");
- conoll("");
- conoll("KERMIT READY TO SEND...");
- } else if ( sstate == 'g' || sstate == 'r' || sstate == 'h' ||
- sstate == 'j' || sstate == 'c' ) {
- conoll("Return to your local Kermit and give a SERVER command.");
- conoll("");
- conoll((sstate == 'r' || sstate == 'j' || sstate == 'h') ?
- "KERMIT READY TO GET..." :
- "KERMIT READY TO SEND SERVER COMMAND...");
- }
- }
-#ifdef COMMENT
- if (!local) sleep(1);
-#endif /* COMMENT */
-/*
- The 'wart()' function is generated by the wart program. It gets a
- character from the input() routine and then based on that character and
- the current state, selects the appropriate action, according to the state
- table above, which is transformed by the wart program into a big case
- statement. The function is active for one transaction.
-*/
- rtimer(); /* Reset elapsed-time timer */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- resetc(); /* & other per-transaction counters. */
-
- debug(F101,"proto calling wart, justone","",justone);
-
- wart(); /* Enter the state table switcher. */
-/*
- Note: the following is necessary in case we have just done a remote-mode
- file transfer, in which case the controlling terminal modes have been
- changed by ttpkt(). In particular, special characters like Ctrl-C and
- Ctrl-\ might have been turned off (see ttpkt). So this call to ttres() is
- essential. IMPORTANT: restore interrupt handlers first, otherwise any
- terminal interrupts that occur before this is done in the normal place
- later will cause a crash.
-*/
-#ifdef OS2
- ttres(); /* Reset the communication device */
-#else
- if (!local) {
- setint(); /* Arm interrupt handlers FIRST */
- msleep(500);
- ttres(); /* Then restore terminal. */
- }
-#endif /* OS2 */
- xxscreen(SCR_TC,0,0L,""); /* Transaction complete */
- x = quiet;
- quiet=1;
- clsif(); /* Failsafe in case we missed */
- clsof(1); /* a case in the state machine. */
- quiet = x;
-
- if (server) { /* Back from packet protocol. */
- if (!quiet && !backgrd
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- ) { /* Give appropriate message */
- conoll("");
- conoll("C-Kermit server done");
- }
- server = 0; /* Not a server any more */
- }
-}
-
-/* S G E T I N I T -- Handle incoming GET-Class packets */
-
-/*
- Returns:
- -1: On error
- 0: GET packet processed OK - ready to Send.
- 1: Extended GET processed OK - wait for another.
-*/
-static int
-sgetinit(reget,xget) int reget, xget; { /* Server end of GET command */
- char * fs = NULL; /* Pointer to filespec */
- int i, n, done = 0;
-#ifdef PIPESEND
- extern int usepipes, pipesend;
-#endif /* PIPESEND */
- extern int nolinks;
-
- if (!ENABLED(en_get)) { /* Only if not disabled! */
- errpkt((CHAR *)"GET disabled");
- return(-1);
- }
-
- /* OK to proceed */
-
- nolinks = recursive;
- filcnt = 0;
-
-#ifdef WHATAMI
- /* If they are alike this was already done in whoarewe() */
- debug(F101,"sgetinit whatru","",whatru);
- if (whatru & WMI_FLAG) { /* Did we get WHATAMI info? */
- debug(F101,"sgetinit binary (1)","",binary);
-#ifdef VMS
- if (binary != XYFT_I && binary != XYFT_L)
-#else
-#ifdef OS2
- if (binary != XYFT_L)
-#endif /* OS2 */
-#endif /* VMS */
- binary = (whatru & WMI_FMODE) ? /* Yes, set file type */
- XYFT_B : XYFT_T; /* automatically */
- debug(F101,"sgetinit binary (2)","",binary);
- if (!wearealike)
- fncnv = (whatru & WMI_FNAME) ? 1 : 0; /* And name conversion */
- }
-#endif /* WHATAMI */
-
- fs = (char *)srvcmd;
- srvptr = srvcmd; /* Point to server command buffer */
- decode(rdatap,putsrv,0); /* Decode the GET command into it */
- /* Accept multiple filespecs */
- cmarg2 = ""; /* Don't use cmarg2 */
- cmarg = ""; /* Don't use cmarg */
-
- done = 1; /* Only 1 packet needed... */
- if (xget) { /* Special decoding for Extended GET */
- char L, next, c; /* PLV items */
- int len, val; /* More PLV items */
- char * p = (char *)srvcmd; /* String to decode */
-
- done = 0; /* Maybe more packets needed */
- fs = NULL; /* We don't know the filespec yet */
- c = *p++; /* Get first parameter */
-
- while (c) { /* For all parameters... */
- debug(F000,"sgetinit c","",c);
- L = *p++; /* Get length */
- if (L >= SP) /* Decode length */
- len = xunchar(L);
- else if (c == '@') { /* Allow missing EOP length field */
- len = 0;
- } else {
- len = (xunchar(*p++) * 95);
- len += xunchar(*p++);
- }
- debug(F101,"sgetinit len","",len);
- next = *(p+len); /* Get next parameter */
- *(p+len) = NUL; /* Zero it out to terminal value */
- debug(F110,"sgetinit p",p,0);
- switch (c) { /* Do the parameter */
- case 'O': /* GET Options */
- val = atoi(p); /* Convert to int */
- debug(F101,"sgetinit O val","",val);
- if (val & GOPT_DEL) moving = 1;
- if (val & GOPT_RES) reget = 1;
- if (val & GOPT_REC) {
- recursive = 1;
- nolinks = 2;
- if (fnspath == PATH_OFF)
- fnspath = PATH_REL;
- }
- break;
- case 'M': /* Transfer Mode */
- val = atoi(p);
- debug(F101,"sgetinit M val","",val);
- if (val < 1)
- break;
- patterns = 0; /* Takes precedence over patterns */
- filepeek = 0; /* and FILE SCAN */
- if (val == GMOD_TXT) binary = XYFT_T; /* Text */
- if (val == GMOD_BIN) binary = XYFT_B; /* Binary */
- if (val == GMOD_LBL) binary = XYFT_L; /* Labeled */
- break;
- case 'F': /* Filename */
- fs = p;
- debug(F110,"sgetinit filename",fs,0);
- break;
- case '@': /* End Of Parameters */
- done = 1;
- debug(F100,"sgetinit EOP","",0);
- break;
- default:
- errpkt((CHAR *)"Unknown GET Parameter");
- debug(F100,"sgetinit unknown parameter","",0);
- return(-1);
- }
- p += (len + 1);
- c = next;
- }
- }
- if (!fs) fs = ""; /* A filename is required */
- if (*fs) {
- havefs = 1;
- n = 0; /* Check for quoted name */
- if ((n = strlen(fs)) > 1) {
- /* Note: this does not allow for multiple quoted names */
- if ((fs[0] == '{' && fs[n-1] == '}') ||
- (fs[0] == '"' && fs[n-1] == '"')) {
- fs[n-1] = '\0';
- fs++;
- debug(F111,"sgetinit unquoted filename",fs,n);
- } else
- n = 0; /* This means no quoting */
- }
-
-#ifdef PIPESEND
- debug(F111,"sgetinit",fs,usepipes);
- if (usepipes && ENABLED(en_hos) && *fs == '!') {
- cmarg = fs + 1; /* Point past the bang */
- *fs = NUL;
- nfils = -1;
- pipesend = 1;
- debug(F111,"sgetinit pipesend",cmarg,pipesend);
- }
- if (!pipesend) { /* If it's not a pipe */
-#endif /* PIPESEND */
- if (n == 0) { /* If the name was not quoted */
-#ifndef NOMSEND
- nfils = fnparse(fs); /* Allow it to be a list of names */
- debug(F111,"sgetinit A",fs,nfils);
-#ifdef COMMENT
-/* This doesn't work if a GET-PATH is set. */
- if (nfils == 1 && !iswild(fs)) { /* Single file */
- char * m;
- if ((x = zchki(fs)) < 0) { /* Check if it's sendable */
- switch (x) {
- case -1: m = "File not found"; break;
- case -2: m = "Not a regular file"; break;
- case -3: m = "Read access denied"; break;
- }
- errpkt((CHAR *)m);
- return(-1);
- }
- }
-#endif /* COMMENT */
- } else { /* If it was quoted */
-#endif /* NOMSEND */
- nzxopts = 0;
-#ifdef UNIXOROSK
- if (matchdot) nzxopts |= ZX_MATCHDOT;
-#endif /* UNIXOROSK */
- if (recursive) nzxopts |= ZX_RECURSE;
- /* Treat as a single filespec */
- nfils = 0 - nzxpand(fs,nzxopts);
- debug(F111,"sgetinit B",fs,nfils);
- cmarg = fs;
- }
-#ifdef PIPESEND
- }
-#endif /* PIPESEND */
- }
- if (!done) { /* Need more O packets... */
- debug(F100,"sgetinit O-Packet TBC","",0); /* To Be Continued */
- return(1);
- }
- debug(F100,"sgetinit O-Packet done - havefs","",havefs);
- if (!havefs) { /* Done - make sure we have filename */
- errpkt((CHAR *)"GET without filename");
- return(-1);
- }
- freerpkt(winlo);
- winlo = 0; /* Back to packet 0 again. */
- debug(F101,"sgetinit winlo","",winlo);
- nakstate = 0; /* Now I'm the sender! */
- if (reget) sendmode = SM_RESEND;
- if (sinit() > 0) { /* Send Send-Init */
-#ifdef STREAMING
- if (!streaming)
-#endif /* STREAMING */
- timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
- return(0); /* If successful, switch state */
- } else return(-1); /* Else back to server command wait */
-}
-
-#else /* NOXFER */
-
-#include "ckcdeb.h"
-
-VOID
-proto() {
- extern int success;
- success = 0;
-}
-#endif /* NOXFER */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcsig.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckcsig.h
deleted file mode 100644
index f0ba85c..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcsig.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/* C K C S I G . H */
-
-/* Definitions and prototypes for signal handling */
-
-/*
- Author: Jeffrey E Altman (jaltman@secure-endpoints.com),
- Secure Endpoints Inc., New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#ifdef OS2
-#ifndef NT
-#ifndef __HEV__ /* INCL_SEMAPHORE may also define HEV */
-#define __HEV__
-typedef ULONG HEV; /* hev */
-typedef HEV *PHEV;
-#endif /* __HEV__ */
-#endif /* NT */
-struct _threadinfo {
- int inuse;
- int child;
- int sibling;
-#ifdef NT
- HANDLE id;
- HANDLE handle;
- HANDLE parent;
- HANDLE CompletionSem ;
- HANDLE DieSem ;
-#else /* NT */
- TID id;
- TID parent;
- HEV CompletionSem;
- HEV DieSem;
-#endif /* NT */
-};
-#endif /* OS2 */
-
-#ifdef CK_ANSIC
-typedef SIGTYP (*ck_sigfunc)(void *);
-typedef SIGTYP (*ck_sighand)(int);
-#else
-typedef SIGTYP (*ck_sigfunc)();
-typedef SIGTYP (*ck_sighand)();
-#endif /* CK_ANSIC */
-
-/* Macros for POSIX vs old-style signal handling. */
-
-#ifdef CK_POSIX_SIG
-typedef sigjmp_buf ckjmpbuf;
-#else
-#ifdef NT
-#define NOCRYPT
-#include <windows.h>
-#ifdef NTASM
-typedef struct {
- CONTEXT context;
- DWORD retcode;
-} ckjmpbuf;
-#else /* NTASM */
-typedef jmp_buf ckjmpbuf;
-#endif /* NTASM */
-#else
-typedef jmp_buf ckjmpbuf;
-#endif
-#endif /* CK_POSIX_SIG */
-/*
- Suppose you want to pass the address of a jmp_buf bar to a function foo.
- Since jmp_buf is normally defined (typedef'd) as an array, you would do
- it like this: foo(bar), where foo = foo(jmp_buf bar). But suppose a
- jmp_buf is (say) a struct rather than an array. Then you must do
- foo(&bar) where foo is foo(jmp_buf * bar). This is controlled here in
- the traditional fashion, by ifdefs. By default, we assume that jmp_buf
- is an array. Define the symbol JBNOTARRAY if jmp_buf is not an array.
-*/
-#ifndef JBNOTARRAY
-#ifdef NT
-#define JBNOTARRAY
-#endif /* NT */
-#endif /* JBNOTARRAY */
-
-#ifdef JBNOTARRAY
-typedef ckjmpbuf * ckjptr;
-#define ckjaddr(x) & x
-#define ckjdref(x) * x
-#ifdef CK_POSIX_SIG
-#define cksetjmp(x) sigsetjmp(x,1)
-#define cklongjmp(x,y) siglongjmp(x,y)
-#else
-#ifdef NT
-__inline int
-ck_ih(void) {
- extern int TlsIndex;
-#ifdef NTSIG
- struct _threadinfo * threadinfo;
- threadinfo = (struct _threadinfo *) TlsGetValue(TlsIndex);
- if (threadinfo) {
- if (WaitAndResetSem(threadinfo->DieSem,0)) {
- ckThreadDie(threadinfo);
- return 1; /* This should never execute */
- }
- }
-#ifdef COMMENT
- else debug( F100, "ck_ih() threadinfo is NULL","",0);
-#endif /* COMMENT */
-#endif /* NTSIG */
- return 0;
-}
-#ifdef NTSIG
-#define cksetjmp(x) setjmp(x)
-#define cklongjmp(x,y) longjmp(x,y)
-#else /* NTSIG */
-#ifdef NTASM
-__inline DWORD
-cksetjmp( ckjptr jmp ) {
- extern int isinterrupted;
- jmp->retcode = 0;
- memset( &jmp->context, 0, sizeof(CONTEXT) );
- jmp->context.ContextFlags = CONTEXT_FULL ;
- if ( !GetThreadContext( GetCurrentThread(), &jmp->context ) )
- debug( F101, "cksetjmp GetThreadContext failed","",GetLastError());
- debug(F101,"cksetjmp returns","",jmp->retcode);
- isinterrupted = 0;
- return (jmp->retcode);
-}
-
-__inline void
-cklongjmp( ckjptr jmp, int retval ) {
- extern HANDLE tidCommand;
- extern int ttyfd, mdmtyp ;
- extern DWORD CommandID;
- extern int isinterrupted;
-
- connoi();
- isinterrupted = 1;
- jmp->retcode = ( retval ? retval : 1 );
- debug(F101,"about to SetThreadContext for thread","", CommandID);
- debug(F101,"from Thread","",GetCurrentThreadId());
- if ( mdmtyp >= 0 ) {
- PurgeComm( (HANDLE) ttyfd, PURGE_TXABORT | PURGE_RXABORT );
- }
- if (SetThreadContext( tidCommand, &jmp->context ))
- debug(F100,"cklongjmp SetThreadContext success","",0);
- else
- debug(F101,"cklongjmp SetThreadContext failed","",GetLastError());
- msleep(50);
- cmini(1); /* Reset command parser */
- putkey(13); /* Stuff a carriage return */
- /* PostEventAvailSem(); */
-}
-#else /* NTASM */
-void crash( void ) ;
-#define cksetjmp(x) setjmp(x)
-__inline void
-cklongjmp( ckjptr jmp, int retval ) {
- extern HANDLE tidCommand;
- extern int ttyfd, mdmtyp;
- extern DWORD CommandID;
- CONTEXT context;
-
- if ( mdmtyp >= 0 ) {
- PurgeComm( (HANDLE) ttyfd, PURGE_TXABORT | PURGE_RXABORT ) ;
- }
- memset( &context, 0, sizeof(CONTEXT) );
- context.ContextFlags = CONTEXT_FULL;
- if ( !GetThreadContext( tidCommand, &context ) )
- debug( F101, "cklongjmp GetThreadContext failed","",GetLastError());
-
- /* Invalidate the instruction pointer */
- context.Eip = (unsigned long) crash;
-
- debug(F101,"about to SetThreadContext for thread","", CommandID);
- debug(F101,"from Thread","",GetCurrentThreadId());
- if (SetThreadContext( tidCommand, &context ))
- debug(F100,"cklongjmp SetThreadContext success","",0);
- else
- debug(F101,"cklongjmp SetThreadContext failed","",GetLastError());
-}
-#endif /* NTASM */
-#endif /* NTSIG */
-#else /* NT */
-#define cksetjmp(x) setjmp(x)
-#define cklongjmp(x,y) longjmp(x,y)
-#endif /* NT */
-#endif /* CK_POSIX_SIG */
-#else /* jmp_buf is an array */
-typedef ckjmpbuf ckjptr;
-#define ckjaddr(x) x
-#define ckjdref(x) x
-#ifdef CK_POSIX_SIG
-#define cksetjmp(x) sigsetjmp(x,1)
-#define cklongjmp(x,y) siglongjmp(x,y)
-#else
-#define cksetjmp(x) setjmp(x)
-#define cklongjmp(x,y) longjmp(x,y)
-#endif /* CK_POSIX_SIG */
-#endif /* JBNOTARRAY */
-
-_PROTOTYP( int cc_execute, (ckjptr, ck_sigfunc, ck_sigfunc) );
-_PROTOTYP( int alrm_execute,
- (ckjptr,
- int /* timo */,
- ck_sighand /* handler */,
- ck_sigfunc, ck_sigfunc) );
-_PROTOTYP( int cc_alrm_execute,
- (ckjptr,
- int /* timo */,
- ck_sighand /* handler */,
- ck_sigfunc,
- ck_sigfunc) );
-
-/* End of ckusig.h */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcssl.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckcssl.h
deleted file mode 100644
index 4e31f12..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcssl.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifdef CK_SSL
-#ifndef CK_ANSIC
-#define NOPROTO
-#endif /* CK_ANSIC */
-#include "bio.h"
-#include "buffer.h"
-#include "x509.h"
-#include "pem.h"
-#include "ssl.h"
-
-extern BIO *bio_err;
-extern SSL *ssl_con;
-extern SSL_CTX *ssl_ctx;
-extern int ssl_debug_flag;
-extern int ssl_only_flag;
-extern int ssl_active_flag;
-extern int ssl_verify_flag;
-extern int ssl_secure_flag;
-extern int ssl_verbose_flag;
-extern int ssl_disabled_flag;
-extern int ssl_cert_required;
-extern int ssl_certsok_flag;
-extern int ssl_dummy_flag;
-
-extern char *ssl_log_file;
-extern char *ssl_rsa_cert_file;
-extern char *ssl_rsa_key_file;
-extern char *ssl_dsa_cert_file;
-extern char *ssl_dh_key_file;
-extern char *ssl_cipher_list;
-
-extern SSL_CTX *tls_ctx;
-extern SSL *tls_con;
-extern int tls_only_flag;
-extern int tls_active_flag;
-extern int tls_secure_flag;
-
-_PROTOTYP(int ssl_do_init,(int));
-_PROTOTYP(int ssl_display_connect_details,(SSL *,int));
-_PROTOTYP(int ssl_server_verify_callback,(int, X509_STORE_CTX *));
-_PROTOTYP(int ssl_client_verify_callback,(int, X509_STORE_CTX *));
-
-#ifdef OS2
-#define SSL_get_error ck_SSL_get_error
-#define SSL_read ck_SSL_read
-#define SSL_peek ck_SSL_peek
-#define SSL_connect ck_SSL_connect
-#define SSL_set_fd ck_SSL_set_fd
-#define SSL_free ck_SSL_free
-#define SSL_shutdown ck_SSL_shutdown
-#define SSL_write ck_SSL_write
-#define SSL_pending ck_SSL_pending
-#define SSL_load_error_strings ck_SSL_load_error_strings
-#define SSL_get_peer_certificate ck_SSL_get_peer_certificate
-#define SSL_CIPHER_get_name ck_SSL_CIPHER_get_name
-#define SSL_get_current_cipher ck_SSL_get_current_cipher
-#define SSL_get_shared_ciphers ck_SSL_get_shared_ciphers
-#define SSL_get_ciphers ck_SSL_get_ciphers
-#define SSL_get_cipher_list ck_SSL_get_cipher_list
-#define SSL_CTX_set_default_verify_paths ck_SSL_CTX_set_default_verify_paths
-#define SSL_use_RSAPrivateKey_file ck_SSL_use_RSAPrivateKey_file
-#define SSL_use_DSAPrivateKey_file ck_SSL_use_DSAPrivateKey_file
-#define SSL_use_PrivateKey_file ck_SSL_use_PrivateKey_file
-#define SSL_use_certificate_file ck_SSL_use_certificate_file
-#define SSL_CTX_use_PrivateKey_file ck_SSL_CTX_use_PrivateKey_file
-#define SSL_CTX_use_certificate_file ck_SSL_CTX_use_certificate_file
-#define SSL_set_verify ck_SSL_set_verify
-#define SSL_new ck_SSL_new
-#define SSL_CTX_ctrl ck_SSL_CTX_ctrl
-#define SSL_CTX_new ck_SSL_CTX_new
-#define SSL_CTX_free ck_SSL_CTX_free
-#define SSL_CTX_set_default_passwd_cb ck_SSL_CTX_set_default_passwd_cb
-#define SSLv23_method ck_SSLv23_method
-#define SSLv3_method ck_SSLv3_method
-#define TLSv1_method ck_TLSv1_method
-#define SSLv23_client_method ck_SSLv23_client_method
-#define SSLv3_client_method ck_SSLv3_client_method
-#define TLSv1_client_method ck_TLSv1_client_method
-#define SSLv23_server_method ck_SSLv23_server_method
-#define SSLv3_server_method ck_SSLv3_server_method
-#define TLSv1_server_method ck_TLSv1_server_method
-#define SSL_library_init ck_SSL_library_init
-#define SSL_state_string ck_SSL_state_string
-#define SSL_state_string_long ck_SSL_state_string_long
-#define SSL_accept ck_SSL_accept
-#define SSL_set_cipher_list ck_SSL_set_cipher_list
-
-#define ERR_print_errors ck_ERR_print_errors
-#define ERR_print_errors_fp ck_ERR_print_errors_fp
-#define ERR_error_string ck_ERR_error_string
-#define ERR_get_error ck_ERR_get_error
-
-#define BIO_printf ck_BIO_printf
-#define BIO_ctrl ck_BIO_ctrl
-#define BIO_new ck_BIO_new
-#define BIO_s_file ck_BIO_s_file
-#define BIO_s_mem ck_BIO_s_mem
-#define BIO_s_null ck_BIO_s_null
-#define BIO_read ck_BIO_read
-#define BIO_new_file ck_BIO_new_file
-#define BIO_free ck_BIO_free
-
-#define X509_get_issuer_name ck_X509_get_issuer_name
-#define X509_verify_cert_error_string ck_X509_verify_cert_error_string
-#define X509_NAME_oneline ck_X509_NAME_oneline
-#define X509_get_subject_name ck_X509_get_subject_name
-#define X509_STORE_CTX_get_current_cert ck_X509_STORE_CTX_get_current_cert
-#define X509_get_default_cert_dir ck_X509_get_default_cert_dir
-#define X509_free ck_X509_free
-
-#define RSA_free ck_RSA_free
-#define RSA_generate_key ck_RSA_generate_key
-
-#define DH_new ck_DH_new
-#define DH_free ck_DH_free
-#define DH_generate_key ck_DH_generate_key
-#define DH_generate_parameters ck_DH_generate_parameters
-
-#define DSA_free ck_DSA_free
-#define DSA_generate_key ck_DSA_generate_key
-#define DSA_generate_parameters ck_DSA_generate_parameters
-
-#define PEM_read_bio_DHparams ck_PEM_read_bio_DHparams
-#define BN_bin2bn ck_BN_bin2bn
-#endif /* OS2 */
-#endif /* CK_SSL */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcsym.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckcsym.h
deleted file mode 100644
index c340ca3..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcsym.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/* This file is for use with compilers that don't have the capability to
- * #define symbols on the C compiler command line. This file must
- * be #include'd before all other ck*.h files so that the symbols #define'd
- * here can be used for any subsequent conditional code.
- */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckctel.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckctel.c
deleted file mode 100644
index e9f1295..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckctel.c
+++ /dev/null
@@ -1,9015 +0,0 @@
-char *cktelv = "Telnet support, 9.0.274, 16 Mar 2010";
-#define CKCTEL_C
-
-int sstelnet = 0; /* Do server-side Telnet negotiation */
-
-/* C K C T E L -- Telnet support */
-
-/*
- Authors:
- Telnet protocol by Frank da Cruz and Jeffrey Altman.
- Telnet Forward X by Jeffrey Altman
- Telnet START_TLS support by Jeffrey Altman
- Telnet AUTH and ENCRYPT support by Jeffrey Altman
- Telnet COMPORT support by Jeffrey Altman
- Telnet NEW-ENVIRONMENT support by Jeffrey Altman
- Telnet NAWS support by Frank da Cruz and Jeffrey Altman
- Telnet TERMTYPE support by Jeffrey Altman
- Telnet KERMIT support by Jeffrey Altman
- Other contributions as indicated in the code.
-
- Copyright (C) 1985, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- NOTE TO CONTRIBUTORS: This file, and all the other shared (ckc and cku)
- C-Kermit source files, must be compatible with C preprocessors that support
- only #ifdef, #else, #endif, #define, and #undef. Please do not use #if,
- logical operators, or other preprocessor features in this module. Also,
- don't use any ANSI C constructs except within #ifdef CK_ANSIC..#endif.
-*/
-
-#include "ckcsym.h"
-#include "ckcdeb.h"
-
-#ifdef TNCODE
-#include "ckcker.h"
-#define TELCMDS /* to define name array */
-#define TELOPTS /* to define name array */
-#define SLC_NAMES /* to define name array */
-#define ENCRYPT_NAMES
-#define AUTH_NAMES
-#define TELOPT_STATES
-#define TELOPT_MODES
-#define TNC_NAMES
-#include "ckcnet.h"
-#include "ckctel.h"
-#ifdef CK_AUTHENTICATION
-#include "ckuath.h"
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-
-#ifndef NOTERM
-#ifdef OS2 /* For terminal type name string */
-#include "ckuusr.h"
-#ifndef NT
-#include <os2.h>
-#undef COMMENT
-#else
-#define isascii __isascii
-#endif /* NT */
-#include "ckocon.h"
-extern int tt_type, max_tt;
-extern struct tt_info_rec tt_info[];
-#endif /* OS2 */
-#endif /* NOTERM */
-
-#ifdef OS2
-#include <assert.h>
-#ifdef NT
-#include <setjmpex.h>
-#else /* NT */
-#include <setjmp.h>
-#endif /* NT */
-#include <signal.h>
-#include "ckcsig.h"
-#include "ckosyn.h"
-#endif /* OS2 */
-
-#ifdef CK_NAWS /* Negotiate About Window Size */
-#ifdef RLOGCODE
-_PROTOTYP( int rlog_naws, (void) );
-#endif /* RLOGCODE */
-#endif /* CK_NAWS */
-
-int tn_init = 0; /* Telnet protocol initialized flag */
-int tn_begun = 0; /* Telnet protocol started flag */
-static int tn_first = 1; /* First time init flag */
-extern int tn_exit; /* Exit on disconnect */
-extern int nettype;
-extern int inserver; /* Running as IKSD */
-char *tn_term = NULL; /* Terminal type override */
-
-#ifdef CK_SNDLOC
-char *tn_loc = NULL; /* Location override */
-#endif /* CK_SNDLOC */
-int tn_nlm = TNL_CRLF; /* Telnet CR -> CR LF mode */
-int tn_b_nlm = TNL_CR; /* Telnet Binary CR RAW mode */
-int tn_b_meu = 0; /* Telnet Binary ME means U too */
-int tn_b_ume = 0; /* Telnet Binary U means ME too */
-int tn_wait_flg = 1; /* Telnet Wait for Negotiations */
-int tn_infinite = 0; /* Telnet Bug Infinite-Loop-Check */
-int tn_rem_echo = 1; /* We will echo if WILL ECHO */
-int tn_b_xfer = 0; /* Telnet Binary for Xfers? */
-int tn_sb_bug = 1; /* Telnet BUG - SB w/o WILL or DO */
-int tn_auth_krb5_des_bug = 1; /* Telnet BUG - AUTH KRB5 DES */
- /* truncates long keys */
-int tn_no_encrypt_xfer = 0; /* Turn off Telnet Encrypt? */
-int tn_delay_sb = 1; /* Delay SBs until safe */
-int tn_auth_how = TN_AUTH_HOW_ANY;
-int tn_auth_enc = TN_AUTH_ENC_ANY;
-int tn_deb = 0; /* Telnet Debug mode */
-int tn_sfu = 0; /* Microsoft SFU compatibility */
-#ifdef CK_FORWARD_X
-char * tn_fwdx_xauthority = NULL; /* Xauthority File */
-int fwdx_no_encrypt = 0; /* Forward-X requires encryption */
-#endif /* CK_FORWARD_X */
-
-#ifdef OS2
-int ttnum = -1; /* Last Telnet Terminal Type sent */
-int ttnumend = 0; /* Has end of list been found */
-#endif /* OS2 */
-
-char tn_msg[TN_MSG_LEN]; /* Telnet data can be rather long */
-char hexbuf[TN_MSG_LEN];
-char tn_msg_out[TN_MSG_LEN];
-#ifdef CK_FORWARD_X
-CHAR fwdx_msg_out[TN_MSG_LEN];
-#endif /* CK_FORWARD_X */
-
-/*
- In order to prevent an infinite telnet negotiation loop we maintain a
- count of the number of times the same telnet negotiation message is
- sent. When this count hits MAXTNCNT, we do not send any more of the
- message. The count is stored in the tncnts[][] array.
-
- The tncnts[][] array is indexed by negotiation option (SUPPRESS GO AHEAD,
- TERMINAL TYPE, NAWS, etc. - see the tnopts[] array) and the four
- negotiation message types (WILL, WONT, DO, DONT). All telnet negotiations
- are kept track of in this way.
-
- The count for a message is zeroed when the "opposite" message is sent.
- WILL is the opposite of WONT, and DO is the opposite of DONT.
- For example sending "WILL SGA" increments tncnts[TELOPT_SGA][0]
- and zeroes tncnts[TELOPT_SGA][1].
-
- The code that does this is in tn_sopt().
-
- rogersh@fsj.co.jp, 18/3/1995
-
- 8/16/1998 - with the recent rewrite of the telnet state machine I don't
- think this code is necessary anymore. However, it can't do any harm so
- I am leaving it in. - Jeff
-
- 12/28/1998 - all references to tncnts[] must be done with TELOPT_INDEX(opt)
- because the Telnet option list is no longer contiguous. We also must
- allocate NTELOPTS + 1 because the TELOPT_INDEX() macro returns NTELOPTS
- for an invalid option number.
-*/
-
-#define MAXTNCNT 4 /* Permits 4 intermediate telnet firewalls/gateways */
-
-char tncnts[NTELOPTS+1][4]; /* Counts */
-char tnopps[4] = { 1,0,3,2 }; /* Opposites */
-
-#ifdef CK_ENVIRONMENT
-#ifdef CK_FORWARD_X
-#define TSBUFSIZ 2056
-#else /* CK_FORWARD_X */
-#define TSBUFSIZ 1024
-#endif /* CK_FORWARD_X */
-char tn_env_acct[64];
-char tn_env_disp[64];
-char tn_env_job[64];
-char tn_env_prnt[64];
-char tn_env_sys[64];
-char * tn_env_uservar[8][2];
-int tn_env_flg = 1;
-#else /* CK_ENVIRONMENT */
-#define TSBUFSIZ 41
-int tn_env_flg = 0;
-#endif /* CK_ENVIRONMENT */
-
-#ifdef COMMENT
-/* SIGWINCH handler moved to ckuusx.c */
-#ifndef NOSIGWINCH
-#ifdef CK_NAWS /* Window size business */
-#ifdef UNIX
-#include <signal.h>
-#endif /* UNIX */
-#endif /* CK_NAWS */
-#endif /* NOSIGWINCH */
-#endif /* COMMENT */
-
-CHAR sb[TSBUFSIZ]; /* Buffer - incoming subnegotiations */
-CHAR sb_out[TSBUFSIZ]; /* Buffer - outgoing subnegotiations */
-
-int tn_duplex = 1; /* Local echo */
-
-extern char uidbuf[]; /* User ID buffer */
-extern int quiet, ttnet, ttnproto, debses, what, duplex, oldplex, local;
-extern int seslog, sessft, whyclosed;
-#ifdef OS2
-#ifndef NOTERM
-extern int tt_rows[], tt_cols[];
-extern int tt_status[VNUM];
-extern int scrninitialized[];
-#endif /* NOTERM */
-#else /* OS2 */
-extern int tt_rows, tt_cols; /* Everybody has this */
-#endif /* OS2 */
-extern int cmd_cols, cmd_rows;
-extern char namecopy[];
-extern char myipaddr[]; /* Global copy of my IP address */
-
-#ifndef TELOPT_MACRO
-int
-telopt_index(opt) int opt; {
- if (opt >= 0 && opt <= TELOPT_STDERR)
- return(opt);
- else if (opt >= TELOPT_PRAGMA_LOGON && opt <= TELOPT_PRAGMA_HEARTBEAT)
- return(opt-88);
- else if (opt == TELOPT_IBM_SAK)
- return(opt-147);
- else
- return(NTELOPTS);
-}
-
-int
-telopt_ok(opt) int opt; {
- return((opt >= TELOPT_BINARY && opt <= TELOPT_STDERR) ||
- (opt >= TELOPT_PRAGMA_LOGON && opt <= TELOPT_PRAGMA_HEARTBEAT) ||
- (opt == TELOPT_IBM_SAK));
-}
-
-CHAR *
-telopt(opt) int opt; {
- if (telopt_ok(opt))
- return((CHAR *)telopts[telopt_index(opt)]);
- else
- return((CHAR *)"UNKNOWN");
-}
-
-int
-telopt_mode_ok(opt) int opt; {
- return((unsigned int)(opt) <= TN_NG_MU);
-}
-
-CHAR *
-telopt_mode(opt) int opt; {
- if (telopt_mode_ok(opt))
- return((CHAR *)telopt_modes[opt-TN_NG_RF]);
- else
- return((CHAR *)"UNKNOWN");
-}
-#endif /* TELOPT_MACRO */
-
-static int
-tn_outst(notquiet) int notquiet; {
- int outstanding = 0;
- int x = 0;
-#ifdef CK_ENCRYPTION
- int e = 0;
- int d = 0;
-#endif /* CK_ENCRYPTION */
-
- if (tn_wait_flg) {
- for (x = TELOPT_FIRST; x <= TELOPT_LAST; x++) {
- if (TELOPT_OK(x)) {
- if (TELOPT_UNANSWERED_WILL(x)) {
- if ( notquiet )
- printf("?Telnet waiting for response to WILL %s\r\n",
- TELOPT(x));
- debug(F111,"tn_outst","unanswered WILL",x);
- outstanding = 1;
- if ( !notquiet )
- break;
- }
- if (TELOPT_UNANSWERED_DO(x)) {
- if ( notquiet )
- printf("?Telnet waiting for response to DO %s\r\n",
- TELOPT(x));
- debug(F111,"tn_outst","unanswered DO",x);
- outstanding = 1;
- if ( !notquiet )
- break;
- }
- if (TELOPT_UNANSWERED_WONT(x)) {
- if ( notquiet )
- printf("?Telnet waiting for response to WONT %s\r\n",
- TELOPT(x));
- debug(F111,"tn_outst","unanswered WONT",x);
- outstanding = 1;
- if ( !notquiet )
- break;
- }
- if (TELOPT_UNANSWERED_DONT(x)) {
- if ( notquiet )
- printf("?Telnet waiting for response to DONT %s\r\n",
- TELOPT(x));
- debug(F111,"tn_outst","unanswered DONT",x);
- outstanding = 1;
- if ( !notquiet )
- break;
- }
- if (TELOPT_UNANSWERED_SB(x)) {
- if ( notquiet )
- printf("?Telnet waiting for response to SB %s\r\n",
- TELOPT(x));
- debug(F111,"tn_outst","unanswered SB",x);
- outstanding = 1;
- if ( !notquiet )
- break;
- }
- }
- }
-#ifdef CK_AUTHENTICATION
- if (ck_tn_auth_in_progress()) {
- if (TELOPT_ME(TELOPT_AUTHENTICATION)) {
- if (notquiet)
- printf("?Telnet waiting for WILL %s subnegotiation\r\n",
- TELOPT(TELOPT_AUTHENTICATION));
- debug(F111,
- "tn_outst",
- "ME authentication in progress",
- TELOPT_AUTHENTICATION
- );
- outstanding = 1;
- } else if (TELOPT_U(TELOPT_AUTHENTICATION)) {
- if (notquiet)
- printf("?Telnet waiting for DO %s subnegotiation\r\n",
- TELOPT(TELOPT_AUTHENTICATION));
- debug(F111,
- "tn_outst",
- "U authentication in progress",
- TELOPT_AUTHENTICATION
- );
- outstanding = 1;
- }
- }
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
- if (!outstanding) {
- e = ck_tn_encrypting();
- d = ck_tn_decrypting();
- if (TELOPT_ME(TELOPT_ENCRYPTION)) {
- if (TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop && e ||
- !TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop && !e
- ) {
- if ( notquiet )
- printf("?Telnet waiting for WILL %s subnegotiation\r\n",
- TELOPT(TELOPT_ENCRYPTION));
- debug(F111,
- "tn_outst",
- "encryption mode switch",
- TELOPT_ENCRYPTION
- );
- outstanding = 1;
- }
- }
- if (TELOPT_U(TELOPT_ENCRYPTION)) {
- if (TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop && d ||
- !TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop && !d
- ) {
- if ( notquiet )
- printf("?Telnet waiting for DO %s subnegotiation\r\n",
- TELOPT(TELOPT_ENCRYPTION));
- debug(F111,
- "tn_outst",
- "decryption mode switch",
- TELOPT_ENCRYPTION
- );
- outstanding = 1;
- }
- }
- }
-#endif /* CK_ENCRYPTION */
- } /* if (tn_wait_flg) */
-
-#ifdef IKS_OPTION
- /* Even if we are not waiting for Telnet options we must wait for */
- /* Kermit Telnet Subnegotiations if we have sent a request to the */
- /* other guy. Otherwise we will get out of sync. */
- if (!outstanding) {
- if (TELOPT_U(TELOPT_KERMIT) &&
- (TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start ||
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop ||
- !TELOPT_SB(TELOPT_KERMIT).kermit.sop)
- ) {
- if ( notquiet )
- printf("?Telnet waiting for SB %s negotiation\r\n",
- TELOPT(TELOPT_KERMIT));
- debug(F111,"tn_outst","U kermit in progress",TELOPT_KERMIT);
- outstanding = 1;
- }
- }
-#endif /* IKS_OPTION */
-
-#ifdef TN_COMPORT
- if (!outstanding) {
- if (TELOPT_ME(TELOPT_COMPORT)) {
- if (TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb) {
- if (notquiet)
- printf("?Telnet waiting for SB %s negotiation\r\n",
- TELOPT(TELOPT_COMPORT));
- debug(F111,"tn_outst","ComPort SB in progress",TELOPT_COMPORT);
- outstanding = 1;
- }
- if (TELOPT_SB(TELOPT_COMPORT).comport.wait_for_ms) {
- if (notquiet)
- printf("?Telnet waiting for SB %s MODEM_STATUS negotiation\r\n",
- TELOPT(TELOPT_COMPORT));
- debug(F111,"tn_outst","ComPort SB MS in progress",TELOPT_COMPORT);
- outstanding = 1;
- }
- }
- }
-#endif /* TN_COMPORT */
- return(outstanding);
-}
-
-int
-istncomport() {
-#ifdef TN_COMPORT
- if (!local) return(0);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
- if (TELOPT_ME(TELOPT_COMPORT))
- return(1);
- else
-#endif /* TN_COMPORT */
- return(0);
-}
-
-/* tn_wait() -- Wait for response to Telnet negotiation. */
-/*
- Wait for up to <timeout> seconds for the response to arrive.
- Place all non-telnet data into Telnet Wait Buffer.
- If response does arrive return 1, else return 0.
-*/
-#ifndef TN_WAIT_BUF_SZ
-#define TN_WAIT_BUF_SZ 4096
-#endif /* TN_WAIT_BUF_SZ */
-static char tn_wait_buf[TN_WAIT_BUF_SZ];
-static int tn_wait_idx = 0;
-#ifndef TN_TIMEOUT
-#define TN_TIMEOUT 120
-#endif /* TN_TIMEOUT */
-static int tn_wait_tmo = TN_TIMEOUT;
-
-#ifdef CKSPINNER
-VOID
-prtwait(state) int state; {
- switch (state % 4) {
- case 0:
- printf("/");
- break;
- case 1:
- printf("-");
- break;
- case 2:
- printf("\\");
- break;
- case 3:
- printf("|");
- break;
- }
-}
-#endif /* CKSPINNER */
-
-static int nflag = 0;
-
-int
-#ifdef CK_ANSIC
-tn_wait(char * where)
-#else
-tn_wait(where) char * where;
-#endif /* CK_ANSIC */
-/* tn_wait */ {
- extern int ckxech, local;
- int ch = 0, count = 0;
-#ifndef NOHINTS
- int nohintgiven = 1;
- extern int hints;
-#endif /* NOHINTS */
- int outstanding;
-#ifdef TN_COMPORT
- int savcarr;
- extern int ttcarr;
-#endif /* TN_COMPORT */
-
- /* if (!IS_TELNET()) return(1); */
-
- rtimer();
-
- debug(F110,"tn_wait waiting for",where,0);
- tn_wait_tmo = TN_TIMEOUT;
- debug(F111,"tn_wait","timeout",tn_wait_tmo);
- outstanding = tn_outst(0);
- debug(F111,"tn_wait","outstanding",outstanding);
- debug(F111,"tn_wait","tn_wait_flg",tn_wait_flg);
-
- /* The following is meant to be !(||). We only want to return */
- /* immediately if both the tn_wait_flg && tn_outst() are false */
- if (!(outstanding || tn_wait_flg)) /* If no need to wait */
- return(1); /* Don't. */
-
- if (tn_deb || debses) tn_debug("<wait for outstanding negotiations>");
-
-#ifdef CKSPINNER
- if (!sstelnet && !quiet)
- prtwait(0);
-#endif /* CKSPINNER */
-
- /* Wait up to TN_TIMEOUT sec for responses to outstanding telnet negs */
- do {
-#ifdef NTSIG
- ck_ih();
-#endif /* NTSIG */
- ch = ttinc(1);
- if (ch == -1) { /* Timed out */
- if (!sstelnet && !quiet) { /* Let user know... */
-#ifdef CKSPINNER
- printf("\b");
- prtwait(gtimer());
-#else
- if (nflag == 0) {
- printf(" Negotiations.");
- nflag++;
- }
- if (nflag > 0) {
- printf(".");
- nflag++;
- fflush(stdout);
- }
-#endif /* CKSPINNER */
- }
- } else if (ch < -1) {
- printf("\r\n?Connection closed by peer.\r\n");
- if (tn_deb || debses) tn_debug("<connection closed by peer>");
- return(-1);
- } else
- switch (ch) {
- case IAC:
-#ifdef CKSPINNER
- if (!sstelnet && !quiet)
- printf("\b");
-#endif /* CKSPINNER */
- ch = tn_doop((CHAR)(ch & 0xff),inserver?ckxech:duplex,ttinc);
-#ifdef CKSPINNER
- if (!sstelnet && !quiet) {
- prtwait(gtimer());
- }
-#endif /* CKSPINNER */
- debug(F101,"tn_wait tn_doop","",ch);
- switch (ch) {
- case 1:
- duplex = 1; /* Turn on echoing */
- if (inserver)
- ckxech = 1;
- break;
- case 2:
- duplex = 0; /* Turn off echoing */
- if (inserver)
- ckxech = 0;
- break;
- case 3:
- tn_wait_buf[tn_wait_idx++] = IAC;
- break;
- case 4: /* IKS event */
- case 6: /* Logout */
- break;
- case -1:
- if (!quiet)
- printf("?Telnet Option negotiation error.\n");
- if (tn_deb || debses)
- tn_debug("<Telnet Option negotiation error>");
- return(-1);
- case -2:
- printf("?Connection closed by peer.\n");
- if (tn_deb || debses) tn_debug("<Connection closed by peer>");
- ttclos(0);
- return(-2);
- default:
- if (ch < 0) {
- if (tn_deb || debses) tn_debug("<Unknown connection error>");
- return(ch);
- }
- } /* switch */
- break;
- default:
-#ifdef CKSPINNER
- if (!sstelnet && !quiet) {
- printf("\b");
- prtwait(gtimer());
- }
-#endif /* CKSPINNER */
- tn_wait_buf[tn_wait_idx++] = (CHAR)(ch & 0xff);
- } /* switch */
-
- outstanding = tn_outst(0);
-
- if ( outstanding && ch != IAC ) {
- int timer = gtimer();
- if ( timer > tn_wait_tmo ) {
- if (!sstelnet) {
- printf(
- "\r\n?Telnet Protocol Timeout - connection closed\r\n");
- if (tn_deb || debses)
- tn_debug(
- "<telnet protocol timeout - connection closed>");
- tn_outst(1);
- }
- /* if we do not close the connection, then we will block */
- /* the next time we hit a wait. and if we don't we will */
- /* do the wrong thing if the host sends 0xFF and does */
- /* not intend it to be an IAC. */
- ttclos(0);
- whyclosed = WC_TELOPT;
- return(-1);
- }
-#ifndef NOHINTS
- else if ( hints && timer > 30 && nohintgiven && !inserver ) {
-#ifdef CKSPINNER
- printf("\b");
-#else /* CKSPINNER */
- printf("\r\n");
-#endif /* CKSPINNER */
- printf("*************************\r\n");
- printf("The Telnet %s is not sending required responses.\r\n\r\n",
- sstelnet?"client":"server");
- tn_outst(1);
- printf("\nYou can continue to wait or you can cancel with Ctrl-C.\r\n");
- printf("In case the Telnet server never responds as required,\r\n");
- printf("you can try connecting to this host with TELNET /NOWAIT.\r\n");
- printf("Use SET HINTS OFF to suppress further hints.\r\n");
- printf("*************************\r\n");
- nohintgiven = 0;
- }
-#endif /* NOHINTS */
- }
-
-#ifdef TN_COMPORT
- /* Must disable carrier detect check if we are using Telnet Comport */
- savcarr = ttcarr;
- ttscarr(CAR_OFF);
- count = ttchk();
- ttscarr(savcarr);
-#else /* TN_COMPORT */
- count = ttchk();
-#endif /* TN_COMPORT */
- } while ((tn_wait_idx < TN_WAIT_BUF_SZ) &&
- (outstanding && count >= 0));
-
- if (tn_wait_idx == TN_WAIT_BUF_SZ) {
- if (tn_deb || debses) tn_debug("<Telnet Wait Buffer filled>");
- return(0);
- }
-
- if (!sstelnet && !quiet) {
-#ifdef CKSPINNER
- printf("\b \b");
-#else
- if (nflag > 0) {
- printf(" (OK)\n");
- nflag = -1;
- }
-#endif /* CKSPINNER */
- }
- if (tn_deb || debses) tn_debug("<no outstanding negotiations>");
- return(0);
-}
-
-/* Push data from the Telnet Wait Buffer into the I/O Queue */
-/* Return 1 on success */
-
-int
-tn_push() {
-#ifdef NETLEBUF
- extern int tt_push_inited;
-#endif /* NETLEBUF */
- /* if (!IS_TELNET()) return(1); */
-
- if (tn_wait_idx) {
- ckhexdump((CHAR *)"tn_push",tn_wait_buf,tn_wait_idx);
-#ifdef NETLEBUF
- if (!tt_push_inited) /* Local handling */
- le_init();
- le_puts((CHAR *)tn_wait_buf,tn_wait_idx);
-#else /* External handling... */
-#ifdef OS2 /* K95 has its own way */
- le_puts((CHAR *)tn_wait_buf,tn_wait_idx);
-#else
-#ifdef TTLEBUF /* UNIX, etc */
- le_puts((CHAR *)tn_wait_buf,tn_wait_idx);
-#else
-/*
- If you see this message in AOS/VS, OS-9, VOS, etc, you need to copy
- the #ifdef TTLEBUF..#endif code from ckutio.c to the corresponding
- places in your ck?tio.c module.
-*/
- printf("tn_push called but not implemented - data lost.\n");
-#endif /* TTLEBUF */
-#endif /* OS2 */
-#endif /* NETLEBUF */
- tn_wait_idx = 0;
- }
- tn_wait_tmo = TN_TIMEOUT; /* Reset wait timer stats */
- return(1);
-}
-
-/* T N _ S O P T */
-/*
- Sends a telnet option, avoids loops.
- Returns 1 if command was sent, 0 if not, -1 on error.
-*/
-int
-tn_sopt(cmd,opt) int cmd, opt; { /* TELNET SEND OPTION */
- CHAR buf[5];
- char msg[128];
- int rc;
- if (ttnet != NET_TCPB) return(-1); /* Must be TCP/IP */
- if (ttnproto != NP_TELNET) return(-1); /* Must be telnet protocol */
- if (!TELCMD_OK(cmd)) return(-1);
- if (TELOPT_OK(opt)) {
- if (cmd == DO && TELOPT_UNANSWERED_DO(opt)) return(0);
- if (cmd == WILL && TELOPT_UNANSWERED_WILL(opt)) return(0);
- if (cmd == DONT && TELOPT_UNANSWERED_DONT(opt)) return(0);
- if (cmd == WONT && TELOPT_UNANSWERED_WONT(opt)) return(0);
- }
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if (cmd == DO && opt == TELOPT_AUTHENTICATION)
- buf[0] = 0;
-
- if (tn_infinite && TELOPT_OK(opt)) { /* See comment above about */
- int index = TELOPT_INDEX(opt); /* preventing infinite loops */
- int m = cmd - WILL;
-
- if (tncnts[index][m] > MAXTNCNT) {
-#ifdef DEBUG
- if (tn_deb || debses || deblog) {
- ckmakmsg(msg,sizeof(msg),
- "TELNET negotiation loop ",
- TELCMD(cmd), " ",
- TELOPT(opt));
- debug(F101,msg,"",opt);
- if (tn_deb || debses) tn_debug(msg);
- }
-#endif /* DEBUG */
- return(0);
- }
- tncnts[index][m]++;
- tncnts[index][tnopps[m]] = 0;
- }
- buf[0] = (CHAR) IAC;
- buf[1] = (CHAR) (cmd & 0xff);
- buf[2] = (CHAR) (opt & 0xff);
- buf[3] = (CHAR) 0;
-#ifdef DEBUG
- if ((tn_deb || debses || deblog) && cmd != SB)
- ckmakmsg(msg,sizeof(msg),"TELNET SENT ",TELCMD(cmd)," ",
- TELOPT(opt));
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- debug(F101,msg,"",opt);
- if ((tn_deb || debses) && cmd != SB)
- tn_debug(msg);
- rc = (ttol(buf,3) < 3);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
-
- if (TELOPT_OK(opt)) {
- if (cmd == DONT && TELOPT_UNANSWERED_DO(opt))
- TELOPT_UNANSWERED_DO(opt) = 0;
- if (cmd == WONT && TELOPT_UNANSWERED_WILL(opt))
- TELOPT_UNANSWERED_WILL(opt) = 0;
- if (cmd == DO && TELOPT_UNANSWERED_DONT(opt))
- TELOPT_UNANSWERED_DONT(opt) = 0;
- if (cmd == WILL && TELOPT_UNANSWERED_WONT(opt))
- TELOPT_UNANSWERED_WONT(opt) = 0;
- }
- return(1);
-}
-
-/* Send a telnet sub-option */
-/* Returns 1 if command was sent, 0 if not, -1 on error */
-
-int
-tn_ssbopt(opt,sub,data,len) int opt, sub; CHAR * data; int len; {
- CHAR buf[256];
- int n,m,rc;
-
- if (ttnet != NET_TCPB) return(0); /* Must be TCP/IP */
- if (ttnproto != NP_TELNET) return(0); /* Must be telnet protocol */
- if (!TELOPT_OK(opt)) return(-1);
- if (len < 0 || len > 250) {
- debug(F111,"Unable to Send TELNET SB - data too long","len",len);
- return(-1); /* Data too long */
- }
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- if (ttchk() < 0)
- return(-1);
- else
- return(1);
- }
-#endif /* CK_SSL */
-
- if (!data) len = 0;
-
- buf[0] = (CHAR) IAC;
- buf[1] = (CHAR) (SB & 0xff);
- buf[2] = (CHAR) (opt & 0xff);
- buf[3] = (CHAR) (sub & 0xff);
- if (data && len > 0) {
- memcpy(&buf[4],data,len);
- }
- buf[4+len] = (CHAR) IAC;
- buf[5+len] = (CHAR) SE;
-
-#ifdef DEBUG
- if (tn_deb || debses || deblog) {
- if (opt == TELOPT_START_TLS && sub == 1)
- ckmakmsg(tn_msg_out,TN_MSG_LEN,"TELNET SENT SB ",
- TELOPT(opt)," FOLLOWS IAC SE",NULL);
- else if (opt == TELOPT_TTYPE && sub == 1)
- ckmakmsg(tn_msg_out,TN_MSG_LEN,"TELNET SENT SB ", TELOPT(opt),
- " SEND IAC SE",NULL);
- else if (opt == TELOPT_TTYPE && sub == 0)
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,"TELNET SENT SB ",TELOPT(opt)," IS ",
- (char *)data," IAC SE",NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- else if (opt == TELOPT_NEWENVIRON) {
- int i, quote;
- ckmakmsg(tn_msg_out,TN_MSG_LEN,"TELNET SENT SB ",
- TELOPT(TELOPT_NEWENVIRON)," ",
- sub == TELQUAL_SEND ? "SEND" :
- sub == TELQUAL_IS ? "IS" :
- sub == TELQUAL_INFO ?"INFO" : "UNKNOWN" );
- for (i = 0, quote = 0; i < len; i++) {
- if (quote) {
- sprintf(hexbuf,"%02x",data[i]); /* safe but ugly */
- ckstrncat(tn_msg_out,hexbuf,TN_MSG_LEN);
- quote = 0;
- } else {
- switch (data[i]) {
- case TEL_ENV_USERVAR:
- ckstrncat(tn_msg_out," USERVAR ",TN_MSG_LEN);
- break;
- case TEL_ENV_VAR:
- ckstrncat(tn_msg_out," VAR ",TN_MSG_LEN);
- break;
- case TEL_ENV_VALUE:
- ckstrncat(tn_msg_out," VALUE ",TN_MSG_LEN);
- break;
- case TEL_ENV_ESC:
- ckstrncat(tn_msg_out," ESC ",TN_MSG_LEN);
- quote = 1;
- break;
- case IAC:
- ckstrncat(tn_msg_out," IAC ",TN_MSG_LEN);
- break;
- default:
- sprintf(hexbuf,"%c",data[i]); /* safe but ugly */
- ckstrncat(tn_msg_out,hexbuf,TN_MSG_LEN);
- }
- }
- }
- ckstrncat(tn_msg_out," IAC SE",TN_MSG_LEN);
- } else {
- sprintf(hexbuf,"%02x",sub); /* safe but ugly */
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(opt),
- " ",
- hexbuf,
- " <data> IAC SE",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- }
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif /* OS2 */
-#ifdef DEBUG
- debug(F101,tn_msg_out,"",opt);
- if (tn_deb || debses)
- tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol(buf,6+len) < 6+len);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
-
- if (rc)
- return(-1);
- return(1);
-}
-
-/*
- tn_flui() -- Processes all waiting data for Telnet commands.
- All non-Telnet data is to be stored into the Telnet Wait Buffer.
- Returns 1 on success.
-*/
-int
-tn_flui() {
- extern int ckxech;
- int x = 0;
-
- /* if (!IS_TELNET()) return(0); */
-
- /* Wait up to 5 sec for responses to outstanding telnet negotiations */
- while (x >= 0 && ttchk() > 0 && tn_wait_idx < TN_WAIT_BUF_SZ) {
- x = ttinc(1);
- switch (x) {
- case IAC:
- x = tn_doop((CHAR)(x & 0xff),inserver?ckxech:duplex,ttinc);
- debug(F101,"tn_flui tn_doop","",x);
- switch (x) {
- case 1: /* Turn on echoing */
- duplex = 1;
- if (inserver)
- ckxech = 1;
- break;
- case 2: /* Turn off echoing */
- duplex = 0;
- if (inserver)
- ckxech = 0;
- break;
- case 3:
- tn_wait_buf[tn_wait_idx++] = IAC;
- break;
- case 4: /* IKS event */
- case 6: /* Logout */
- break;
- }
- break;
- default:
- if (x >= 0)
- tn_wait_buf[tn_wait_idx++] = x;
- }
- }
- return(1);
-}
-
-unsigned char *
-tn_get_display()
-{
- char * disp = NULL;
- static char tmploc[256];
-
- /* Must compute the DISPLAY string we are going to send to the host */
- /* If one is not assigned, do not send a string unless the user has */
- /* explicitedly requested we try to send one via X-Display Location */
- /* But do not send a string at all if FORWARD_X is in use. */
-
- /* if (!IS_TELNET()) return(0); */
-
- debug(F110,"tn_get_display() myipaddr",myipaddr,0);
-#ifdef CK_ENVIRONMENT
- debug(F110,"tn_get_display() tn_env_disp",tn_env_disp,0);
- if (tn_env_disp[0]) {
- int colon = ckindex(":",tn_env_disp,0,0,1);
- if ( !colon ) {
- ckmakmsg(tmploc,256,myipaddr,":",tn_env_disp,NULL);
- disp = tmploc;
- } else if ( ckindex("localhost:",tn_env_disp,0,0,0) ||
- ckindex("unix:",tn_env_disp,0,0,0) ||
- ckindex("127.0.0.1:",tn_env_disp,0,0,0) ||
- !ckstrcmp("0:",tn_env_disp,2,1) ||
- tn_env_disp[0] == ':' ) {
- ckmakmsg(tmploc,256,myipaddr,":",&tn_env_disp[colon],NULL);
- disp = tmploc;
- } else
- disp = tn_env_disp;
- }
- else
-#endif /* CK_ENVIRONMENT */
- if (TELOPT_ME(TELOPT_XDISPLOC) ||
- TELOPT_U(TELOPT_FORWARD_X)) {
- ckmakmsg(tmploc,256,myipaddr,":0.0",NULL,NULL);
- disp = tmploc;
- }
- debug(F110,"tn_get_display() returns",disp,0);
- return((CHAR *)disp);
-}
-
-#ifdef CK_FORWARD_X
-static Xauth fake_xauth = {0,0,NULL,0,NULL,0,NULL,0,NULL};
-static Xauth *real_xauth=NULL;
-
-/*
- * Author: Jim Fulton, MIT X Consortium
- *
- * fwdx_parse_displayname -
- * display a display string up into its component parts
- */
-#ifdef UNIX
-#define UNIX_CONNECTION "unix"
-#define UNIX_CONNECTION_LENGTH 4
-#endif
-
-/*
- * private utility routines
- */
-
-static int
-#ifdef CK_ANSIC
-XmuGetHostname (char *buf, int maxlen)
-#else
-XmuGetHostname (buf, maxlen)
- char *buf;
- int maxlen;
-#endif /* CK_ANSIC */
-{
- int len;
-
-#ifdef NEED_UTSNAME
- /*
- * same host name crock as in server and xinit.
- */
- struct utsname name;
-
- uname (&name);
- len = strlen (name.nodename);
- if (len >= maxlen) len = maxlen - 1;
- strncpy (buf, name.nodename, len);
- buf[len] = '\0';
-#else
- buf[0] = '\0';
- (void) gethostname (buf, maxlen);
- buf [maxlen - 1] = '\0';
- len = strlen(buf);
-#endif /* hpux */
- return len;
-}
-
-static char *
-#ifdef CK_ANSIC
-copystring (char *src, int len)
-#else
-copystring (src, len)
- char *src;
- int len;
-#endif /* CK_ANSIC */
-{
- char *cp;
-
- if (!src && len != 0) return NULL;
- cp = malloc (len + 1);
- if (cp) {
- if (src) strncpy (cp, src, len);
- cp[len] = '\0';
- }
- return cp;
-}
-
-static char *
-#ifdef CK_ANSIC
-get_local_hostname (char *buf, int maxlen)
-#else
-get_local_hostname (buf, maxlen)
- char *buf;
- int maxlen;
-#endif
-{
- buf[0] = '\0';
- (void) XmuGetHostname (buf, maxlen);
- return (buf[0] ? buf : NULL);
-}
-
-#ifndef UNIX
-static char *
-copyhostname ()
-{
- char buf[256];
-
- return (get_local_hostname (buf, sizeof buf) ?
- copystring (buf, strlen (buf)) : NULL);
-}
-#endif
-
-
-int
-#ifdef CK_ANSIC
-fwdx_parse_displayname (char *displayname, int *familyp, char **hostp,
- int *dpynump, int *scrnump, char **restp)
-#else
-fwdx_parse_displayname (displayname, familyp, hostp, dpynump, scrnump, restp)
- char *displayname;
- int *familyp; /* return */
- char **hostp; /* return */
- int *dpynump, *scrnump; /* return */
- char **restp; /* return */
-#endif /* CK_ANSIC */
-{
- char *ptr; /* work variables */
- int len; /* work variable */
- int family = -1; /* value to be returned */
- char *host = NULL; /* must free if set and error return */
- int dpynum = -1; /* value to be returned */
- int scrnum = 0; /* value to be returned */
- char *rest = NULL; /* must free if set and error return */
- int dnet = 0; /* if 1 then using DECnet */
-
- /* check the name */
- if (!displayname || !displayname[0])
- return 0;
- /* must have at least :number */
- ptr = (char *)strchr(displayname, ':');
- if (!ptr || !ptr[1]) return 0;
- if (ptr[1] == ':') {
- if (ptr[2] == '\0') return 0;
- dnet = 1;
- }
-
- /*
- * get the host string; if none is given, use the most effiecient path
- */
-
- len = (ptr - displayname); /* length of host name */
- if (len == 0) { /* choose most efficient path */
-#ifdef UNIX
- host = copystring (UNIX_CONNECTION, UNIX_CONNECTION_LENGTH);
- family = FamilyLocal;
-#else
- if (dnet) {
- host = copystring ("0", 1);
- family = FamilyDECnet;
- } else {
- host = copyhostname ();
- family = FamilyInternet;
- }
-#endif
- } else {
- host = copystring (displayname, len);
- if (dnet) {
- family = dnet;
- } else {
-#ifdef UNIX
- if (host && strcmp (host, UNIX_CONNECTION) == 0)
- family = FamilyLocal;
- else
-#endif
- family = FamilyInternet;
- }
- }
-
- if (!host) return 0;
-
-
- /*
- * get the display number; we know that there is something after the
- * colon (or colons) from above. note that host is now set and must
- * be freed if there is an error.
- */
-
- if (dnet) ptr++; /* skip the extra DECnet colon */
- ptr++; /* move to start of display num */
- {
- register char *cp;
-
- for (cp = ptr; *cp && isascii(*cp) && isdigit(*cp); cp++) ;
- len = (cp - ptr);
- /* check present and valid follow */
- if (len == 0 || (*cp && *cp != '.')) {
- free (host);
- return 0;
- }
-
- dpynum = atoi (ptr); /* it will handle num. as well */
- ptr = cp;
- }
-
- /*
- * now get screen number if given; ptr may point to nul at this point
- */
- if (ptr[0] == '.') {
- register char *cp;
-
- ptr++;
- for (cp = ptr; *cp && isascii(*cp) && isdigit(*cp); cp++) ;
- len = (cp - ptr);
- if (len == 0 || (*cp && *cp != '.')) { /* all prop name */
- free (host);
- return 0;
- }
-
- scrnum = atoi (ptr); /* it will handle num. as well */
- ptr = cp;
- }
-
- /*
- * and finally, get any additional stuff that might be following the
- * the screen number; ptr must point to a period if there is anything
- */
-
- if (ptr[0] == '.') {
- ptr++;
- len = strlen (ptr);
- if (len > 0) {
- rest = copystring (ptr, len);
- if (!rest) {
- free (host);
- return 1;
- }
- }
- }
-
- /*
- * and we are done!
- */
-
- if ( familyp )
- *familyp = family;
- if ( hostp )
- *hostp = host;
- else
- free(host);
- if ( dpynump )
- *dpynump = dpynum;
- if ( scrnump )
- *scrnump = scrnum;
- if ( restp )
- *restp = rest;
- else
- free(rest);
- return 1;
-}
-
-
-int
-#ifdef CK_ANSIC
-fwdx_tn_sb( unsigned char * sb, int n )
-#else
-fwdx_tn_sb( sb, n ) unsigned char * sb; int n;
-#endif /* CK_ANSIC */
-{
- unsigned short hchannel, nchannel;
- unsigned char * p;
- int i;
- int rc = -1;
-
- /* check to ensure we have negotiated Forward X */
- if ( sstelnet && !TELOPT_ME(TELOPT_FORWARD_X) ||
- !sstelnet && !TELOPT_U(TELOPT_FORWARD_X) ) {
- debug(F100,"fwdx_tn_sb() not negotiated","",0);
- return(0);
- }
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- switch (sb[0]) {
- case FWDX_SCREEN:
- if (sstelnet && n == 4)
- rc = fwdx_create_listen_socket(sb[1]);
- break;
- case FWDX_OPEN:
- if ( !sstelnet && n >= 5 ) {
- p = (unsigned char *) &nchannel;
- i = 1;
- /* IAC quoting has been stripped in tn_sb() */
- p[0] = sb[i++];
- p[1] = sb[i++];
- hchannel = ntohs(nchannel);
- rc = fwdx_open_client_channel(hchannel);
- if ( rc < 0 ) {
- /* Failed; Send CLOSE channel */
- fwdx_send_close(hchannel);
- rc = 0; /* Do not consider this to be a telnet error */
- }
-#ifdef NT
- if ( !TELOPT_SB(TELOPT_FORWARD_X).forward_x.thread_started ) {
- ckThreadBegin( &fwdx_thread,32655, 0, FALSE, 0 ) ;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.thread_started = 1;
- }
-#endif /* NT */
- }
- break;
- case FWDX_CLOSE:
- p = (unsigned char *) &nchannel;
- i = 1;
- /* IAC quoting has been stripped in tn_sb() */
- p[0] = sb[i++];
- p[1] = sb[i++];
- hchannel = ntohs(nchannel);
- fwdx_close_channel(hchannel);
- rc = 0; /* no errors when closing */
- break;
- case FWDX_DATA:
- p = (unsigned char *) &nchannel;
- i = 1;
- /* IAC quoting has been stripped in tn_sb() */
- p[0] = sb[i++];
- p[1] = sb[i++];
- hchannel = ntohs(nchannel);
- rc = fwdx_send_xauth_to_xserver(hchannel,(CHAR *)&sb[3],n-5);
- if ( rc >= 0 && n-5-rc > 0) {
- rc = fwdx_write_data_to_channel(hchannel,(char *)&sb[3+rc],n-5-rc);
- if ( rc < 0 ) {
- /* Failed; Send CLOSE channel */
- rc = fwdx_send_close(hchannel);
- }
- }
- break;
- case FWDX_OPTIONS:
- if ( sstelnet ) {
-#ifndef FWDX_SERVER
- rc = 0;
-#else
- rc = fwdx_server_accept_options((char*)&sb[2],n-3);
-#endif
- } else {
- rc = fwdx_client_reply_options((char *)&sb[2],n-3);
- if ( rc >= 0 ) {
- rc = tn_sndfwdx();
- }
- }
- break;
- case FWDX_OPT_DATA:
- switch ( sb[1] ) {
- default:
- rc = 0; /* we don't recognize, not an error */
- }
- break;
-
- case FWDX_XOFF:
- case FWDX_XON:
- if ( !sstelnet ) {
- p = (unsigned char *) &nchannel;
- i = 1;
- /* IAC quoting has been stripped in tn_sb() */
- p[0] = sb[i++];
- p[1] = sb[i++];
- hchannel = ntohs(nchannel);
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[hchannel].suspend =
- (sb[0] == FWDX_XOFF);
- rc = 0;
- }
- break;
- }
- return(rc < 0 ? -1 : 0);
-}
-
-int
-#ifdef CK_ANSIC
-fwdx_send_xauth_to_xserver(int channel, unsigned char * data, int len)
-#else
-fwdx_send_xauth_to_xserver(channel, data, len)
- int channel; unsigned char * data; int len;
-#endif /* CK_ANSIC */
-{
- int name_len, data_len, i;
-
- for (i = 0; i < MAXFWDX ; i++) {
- if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].id == channel)
- break;
- }
- if ( i == MAXFWDX )
- goto auth_err;
-
- if (!TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth)
- return(0);
-
- if (len < 12)
- goto auth_err;
-
- /* Parse the lengths of variable-length fields. */
- if (data[0] == 0x42) { /* byte order MSB first. */
- /* Xauth packets appear to always have this format */
- if ( data[1] != 0x00 ||
- data[2] != 0x00 ||
- data[3] != 0x0B ||
- data[4] != 0x00 ||
- data[5] != 0x00 )
- goto auth_err;
-
- name_len = (data[6] << 8) + data[7];
- data_len = (data[8] << 8) + data[9];
- } else if (data[0] == 0x6c) { /* Byte order LSB first. */
- /* Xauth packets appear to always have this format */
- if ( data[1] != 0x00 ||
- data[2] != 0x0B ||
- data[3] != 0x00 ||
- data[4] != 0x00 ||
- data[5] != 0x00 )
- goto auth_err;
-
- name_len = data[6] + (data[7] << 8);
- data_len = data[8] + (data[9] << 8);
- } else {
- /* bad byte order byte */
- goto auth_err;
- }
-
- /* Check if the whole packet is in buffer. */
- if (len < 12 + ((name_len + 3) & ~3) + ((data_len + 3) & ~3))
- goto auth_err;
- /* If the Telnet Server allows a real Xauth message to be sent */
- /* Then let the message be processed by the Xserver. */
- if (name_len + data_len > 0) {
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0;
- return(0);
- }
- else
- /* If an empty Xauth message was received. We are going to */
- /* send our own Xauth message using the real Xauth data. And */
- /* then send any other data in the buffer. */
- {
- int c, err, dpynum, scrnum, family, sb_len;
- char *display, *host = NULL, *rest = NULL;
- unsigned char *sb, *p;
-
- /* parse the local DISPLAY env var */
- display = getenv("DISPLAY");
- if ( !display )
- display = "127.0.0.1:0.0";
-
- if (fwdx_parse_displayname(display,
- &family, &host, &dpynum, &scrnum, &rest)) {
- char * disp_no = ckitoa(dpynum); /* should be unsigned */
- if (family == FamilyLocal) {
- /* call with address = "<local host name>" */
- char address[300] = "localhost";
- gethostname(address, sizeof(address) - 1);
- real_xauth = XauGetAuthByAddr(family,
- strlen(address),
- address,
- strlen(disp_no),
- disp_no, 0, NULL);
- }
- else if (family == FamilyInternet) {
- /* call with address = 4 bytes numeric ip addr (MSB) */
- struct hostent *hi;
- if (hi = gethostbyname(host))
- real_xauth = XauGetAuthByAddr(family, 4,
- hi->h_addr, strlen(disp_no),
- disp_no, 0, NULL);
- }
- }
- if (host) free(host);
- if (rest) free(rest);
- if (!real_xauth) {
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0;
- return(0);
- }
-
- if (!strncmp(real_xauth->name,
- "MIT-MAGIC-COOKIE-1",
- real_xauth->name_length)) {
- char msg[64];
-
- name_len = real_xauth->name_length;
- data_len = 16;
-
- if ( data[0] == 0x42 ) {
- msg[0] = 0x42; /* MSB order */
- msg[1] = msg[2] = 0;
- msg[3] = 0x0B;
- msg[4] = msg[5] = 0;
- msg[6] = (name_len >> 8);
- msg[7] = (name_len & 0xFF);
- msg[8] = (data_len >> 8);
- msg[9] = (data_len & 0xFF);
- } else {
- msg[0] = 0x6c; /* LSB order */
- msg[1] = 0;
- msg[2] = 0x0B;
- msg[3] = msg[4] = msg[5] = 0;
- msg[6] = (name_len & 0xFF);
- msg[7] = (name_len >> 8);
- msg[8] = (data_len & 0xFF);
- msg[9] = (data_len >> 8);
- }
- msg[10] = msg[11] = 0;
- memcpy(&msg[12],real_xauth->name,18);
- msg[30] = msg[31] = 0;
- memcpy(&msg[32],real_xauth->data,16);
-
- if (fwdx_write_data_to_channel(channel,(char *)msg,48) < 0) {
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0;
- return(-1);
- } else {
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0;
- return(12);
- }
- } else {
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[i].need_to_send_xauth = 0;
- return(0); /* we do not know how to handle this type yet */
- }
- }
-
- auth_err:
- debug(F100,"fwdx_send_xauth_to_xserver error","",0);
- return(-1);
-}
-
-
-#ifdef COMMENT
-int
-#ifdef CK_ANSIC
-fwdx_authorize_channel(int channel, unsigned char * data, int len)
-#else
-fwdx_authorize_channel(channel, data, len)
- int channel; unsigned char * data; int len;
-#endif /* CK_ANSIC */
-{
- /* XXX maybe we should have some retry handling if not the whole first
- * authorization packet arrives complete
- */
- if ( !TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[channel].authorized ) {
- int name_len, data_len;
-
- if (len < 12)
- goto auth_err;
-
- /* Parse the lengths of variable-length fields. */
- if (data[0] == 0x42) { /* byte order MSB first. */
- /* Xauth packets appear to always have this format */
- if ( data[1] != 0x00 ||
- data[2] != 0x00 ||
- data[3] != 0x0B ||
- data[4] != 0x00 ||
- data[5] != 0x00 )
- goto auth_err;
-
- name_len = (data[6] << 8) + data[7];
- data_len = (data[8] << 8) + data[9];
- } else if (data[0] == 0x6c) { /* Byte order LSB first. */
- /* Xauth packets appear to always have this format */
- if ( data[1] != 0x00 ||
- data[2] != 0x0B ||
- data[3] != 0x00 ||
- data[4] != 0x00 ||
- data[5] != 0x00 )
- goto auth_err;
-
- name_len = data[6] + (data[7] << 8);
- data_len = data[8] + (data[9] << 8);
- } else {
- /* bad byte order byte */
- goto auth_err;
- }
- /* Check if authentication protocol matches. */
- if (name_len != fake_xauth.name_length ||
- memcmp(data + 12, fake_xauth.name, name_len) != 0) {
- /* connection uses different authentication protocol */
- goto auth_err;
- }
- /* Check if authentication data matches our fake data. */
- if (data_len != fake_xauth.data_length ||
- memcmp(data + 12 + ((name_len + 3) & ~3),
- fake_xauth.data, fake_xauth.data_length) != 0) {
- /* auth data does not match fake data */
- goto auth_err;
- }
- /* substitute the fake data with real data if we have any */
- if (real_xauth && real_xauth->data)
- memcpy(data + 12 + ((name_len + 3) & ~3),
- real_xauth->data, data_len);
-
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[channel].authorized = 1;
- }
- return(0);
- auth_err:
- return(-1);
-}
-#endif /* COMMENT */
-
-int
-#ifdef CK_ANSIC
-fwdx_send_close(int channel)
-#else
-fwdx_send_close(channel) int channel;
-#endif /* CK_ANSIC */
-{
- unsigned short nchannel;
- int i,rc;
- CHAR * p;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- nchannel = htons(channel);
- p = (unsigned char *) &nchannel;
-
- i = 0;
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_FORWARD_X; /* Forward X */
- sb_out[i++] = FWDX_CLOSE; /* Open */
- sb_out[i++] = p[0]; /* First Byte of Channel */
- if ( p[0] == IAC )
- sb_out[i++] = IAC;
- sb_out[i++] = p[1]; /* Second Byte of Channel */
- if ( p[1] == IAC )
- sb_out[i++] = IAC;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg((char *)fwdx_msg_out,TN_MSG_LEN,"TELNET SENT SB ",
- TELOPT(TELOPT_FORWARD_X),
- " CLOSE CHANNEL=",ckitoa(channel)," IAC SE",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,(char *)fwdx_msg_out,"",0);
- if (tn_deb || debses) tn_debug((char *)fwdx_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-fwdx_send_open(int channel)
-#else /* CK_ANSIC */
-fwdx_send_open(channel) int channel;
-#endif /* CK_ANSIC */
-{
- unsigned short nchannel;
- int i, rc;
- CHAR * p;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- nchannel = htons(channel);
- p = (unsigned char *) &nchannel;
-
- i = 0;
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_FORWARD_X; /* Forward X */
- sb_out[i++] = FWDX_OPEN; /* Open */
- sb_out[i++] = p[0]; /* First Byte of Channel */
- if ( p[0] == IAC )
- sb_out[i++] = IAC;
- sb_out[i++] = p[1]; /* Second Byte of Channel */
- if ( p[1] == IAC )
- sb_out[i++] = IAC;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg((char *)fwdx_msg_out,TN_MSG_LEN,"TELNET SENT SB ",
- TELOPT(TELOPT_FORWARD_X),
- " OPEN CHANNEL=",ckitoa(channel)," IAC SE",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,(char *)fwdx_msg_out,"",0);
- if (tn_deb || debses) tn_debug((char *)fwdx_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-fwdx_client_reply_options(char *opts, int n)
-#else
-fwdx_client_reply_options(opts, n) char *opts; int n;
-#endif /* CK_ANSIC */
-{
- int i,j,rc;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- i = 0;
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_FORWARD_X; /* Forward X */
- sb_out[i++] = FWDX_OPTIONS; /* Options */
-
- /* Look for the options we recognize and will support for this session */
- /* and reply with their bytes set */
- for (j=0; j<n; j++,i++) {
- sb_out[i] = FWDX_OPT_NONE; /* Add zero byte - no options */
-#ifdef COMMENT
- /* If we had any options to support, this is how we would do it */
- if ( j == 0 ) {
- if (opts[j] & FWDX_OPT_XXXX) {
- /* set flag to remember option is in use */
- flag = 1;
- sb_out[i] |= FWDX_OPT_XXXX;
- }
- }
-#endif /* COMMENT */
- }
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg((char *)fwdx_msg_out,TN_MSG_LEN,"TELNET SENT SB ",
- TELOPT(TELOPT_FORWARD_X),
- " OPTIONS ",ckctox(sb_out[4],1)," IAC SE",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,(char *)fwdx_msg_out,"",0);
- if (tn_deb || debses) tn_debug((char *)fwdx_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- return(0);
-}
-
-
-int
-fwdx_send_options() {
- int i, rc;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- i = 0;
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_FORWARD_X; /* Forward X */
- sb_out[i++] = FWDX_OPTIONS; /* Options */
- sb_out[i] = FWDX_OPT_NONE;
- /* activate options here */
- i++;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakmsg((char *)fwdx_msg_out,TN_MSG_LEN,"TELNET SENT SB ",
- TELOPT(TELOPT_FORWARD_X),
- " OPTIONS 00 IAC SE",NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,(char *)fwdx_msg_out,"",0);
- if (tn_deb || debses) tn_debug((char *)fwdx_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-fwdx_send_data_from_channel(int channel, char * data, int len)
-#else
-fwdx_send_data_from_channel(channel, data, len)
- int channel; char * data; int len;
-#endif
-{
- unsigned short nchannel;
- /* static */ CHAR sb_priv[2048];
- CHAR * p;
- int i, j, j_sav, rc;
- unsigned int tmp;
-
- debug(F111,"fwdx_send_data_from_channel()","channel",channel);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- nchannel = htons(channel);
- p = (unsigned char *) &nchannel;
-
- j = 0;
- sb_priv[j++] = (CHAR) IAC; /* I Am a Command */
- sb_priv[j++] = (CHAR) SB; /* Subnegotiation */
- sb_priv[j++] = TELOPT_FORWARD_X; /* Forward X */
- sb_priv[j++] = FWDX_DATA; /* Data */
- sb_priv[j++] = p[0]; /* First Byte of Channel */
- if ( p[0] == IAC )
- sb_priv[j++] = IAC;
- sb_priv[j++] = p[1]; /* Second Byte of Channel */
- if ( p[1] == IAC )
- sb_priv[j++] = IAC;
- j_sav = j;
-
- for (i = 0; i < len; i++) {
- tmp = (unsigned int)data[i];
- if ( tmp == IAC ) {
- sb_priv[j++] = IAC;
- sb_priv[j++] = IAC;
- } else {
- sb_priv[j++] = tmp;
- }
- if ( j >= 2045 && (i < len-1) ) {
- sb_priv[j++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_priv[j++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg( (char *)fwdx_msg_out,TN_MSG_LEN,"TELNET SENT SB ",
- TELOPT(TELOPT_FORWARD_X),
- " DATA CHANNEL=",ckitoa(channel)," ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL );
- tn_hex((CHAR *)fwdx_msg_out,
- TN_MSG_LEN,&sb_priv[j_sav],j-(j_sav+2));
- ckstrncat((char *)fwdx_msg_out," IAC SE",TN_MSG_LEN);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,(char *)fwdx_msg_out,"",0);
- if (tn_deb || debses) tn_debug((char *)fwdx_msg_out);
-#endif /* DEBUG */
- rc = (ttol(sb_priv,j) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc) {
- debug(F110,"fwdx_send_data_from_channel()","ttol() failed",0);
- return(-1);
- }
-
- j = 0;
- sb_priv[j++] = (CHAR) IAC; /* I Am a Command */
- sb_priv[j++] = (CHAR) SB; /* Subnegotiation */
- sb_priv[j++] = TELOPT_FORWARD_X; /* Forward X */
- sb_priv[j++] = FWDX_DATA; /* Data */
- sb_priv[j++] = p[0]; /* First Byte of Channel */
- if ( p[0] == IAC )
- sb_priv[j++] = IAC;
- sb_priv[j++] = p[1]; /* Second Byte of Channel */
- if ( p[1] == IAC )
- sb_priv[j++] = IAC;
- }
- }
-
- sb_priv[j++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_priv[j++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg( (char *)fwdx_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_FORWARD_X),
- " DATA ",ckctox(p[0],1)," ",ckctox(p[1],1)," ",
- NULL,NULL,NULL,NULL,NULL);
- tn_hex((CHAR *)fwdx_msg_out,TN_MSG_LEN,&sb_priv[6],j-8);
- ckstrncat((char *)fwdx_msg_out," IAC SE",TN_MSG_LEN);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,(char *)fwdx_msg_out,"",0);
- if (tn_deb || debses) tn_debug((char *)fwdx_msg_out);
-#endif /* DEBUG */
- rc = (ttol(sb_priv,j) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if ( rc ) {
- debug(F110,"fwdx_send_data_from_channel()","ttol() failed",0);
- return(-1);
- }
-
-
- return(0);
-}
-
-static unsigned char *
-#ifdef CK_ANSIC
-fwdx_add_quoted_twobyte(unsigned char *p, unsigned short twobyte)
-#else
-fwdx_add_quoted_twobyte(p, twobyte)
- unsigned char *p; unsigned short twobyte;
-#endif /* CK_ANSIC */
-/* adds the IAC quoted (MSB) representation of 'channel' at buffer pointer 'p',
- * returning pointer to new buffer position. NO OVERFLOW CHECK!
- */
-{
- *p++ = (unsigned char)((twobyte >> 8) & 0xFF);
- if (*(p - 1) == 0xFF)
- *p++ = 0xFF;
- *p++ = (unsigned char)(twobyte & 0xFF);
- if (*(p - 1) == 0xFF)
- *p++ = 0xFF;
- return p;
-}
-
-int
-#ifdef CK_ANSIC
-fwdx_create_fake_xauth(char *name, int name_len, int data_len)
-#else
-fwdx_create_fake_xauth(name, name_len, data_len)
- char *name; int name_len; int data_len;
-#endif /* CK_ANSIC */
-{
- char stackdata[256];
- unsigned int c, n;
-
- if (!name_len || !data_len)
- return 1;
- fake_xauth.name = malloc(name_len);
- fake_xauth.data = malloc(data_len);
- if (!fake_xauth.name || !fake_xauth.data)
- return 2;
- fake_xauth.name_length = name_len;
- memcpy(fake_xauth.name, name, name_len);
- fake_xauth.data_length = data_len;
-
- /* try to make a random unsigned int to feed srand() */
- c = time(NULL);
- c *= getpid();
- for (n = 0; n < sizeof(stackdata); n++)
- c += stackdata[n];
- srand((unsigned int)c);
- for (c = 0; c < data_len; c++)
- fake_xauth.data[c] = (unsigned char)rand();
- return 0;
-}
-
-#ifdef COMMENT
-/* No longer used */
-int
-fwdx_send_xauth(void)
-{
- int c, err, dpynum, family, sb_len, rc;
- char *display, *host = NULL;
- unsigned char *sb_priv, *p;
-
- /* parse the local DISPLAY env var */
- if (!(display = tn_get_display()))
- return (-1);
- if (fwdx_parse_displayname(display, &family, &host, &dpynum, NULL, NULL)) {
- char * disp_no = ckitoa(dpynum);
- if (family == FamilyLocal) {
- /* call with address = "<local host name>" */
- char address[300] = "localhost";
- gethostname(address, sizeof(address) - 1);
- real_xauth = XauGetAuthByAddr(family,
- strlen(address),
- address,
- strlen(disp_no),
- disp_no, 0, NULL
- );
- }
- else if (family == FamilyInternet) {
- /* call with address = 4 bytes numeric ip addr (MSB) */
- struct hostent *hi;
- if (hi = gethostbyname(host))
- real_xauth = XauGetAuthByAddr(family, 4,
- hi->h_addr,
- strlen(disp_no),
- disp_no, 0, NULL
- );
- }
- }
- if (host) {
- free(host);
- host = NULL;
- }
- if (real_xauth)
- err = fwdx_create_fake_xauth(real_xauth->name,
- real_xauth->name_length,
- real_xauth->data_length
- );
- else
- err = fwdx_create_fake_xauth("MIT-MAGIC-COOKIE-1",
- strlen("MIT-MAGIC-COOKIE-1"), 16);
- if (err)
- return(-1);
-
- /* allocate memory for the SB block, alloc for worst case */
- /* the following sprintf() calls are safe due to length checking */
- /* buffer is twice as big as the input just in case every byte was IAC */
- sb_len = 5 + 2 + 2 + fake_xauth.name_length + fake_xauth.data_length + 2;
- if (!(sb_priv = malloc(2 * sb_len)))
- return(-1);
- p = sb_priv;
- sprintf(p, "%c%c%c%c%c", IAC, SB, TELOPT_FORWARD_X,
- FWDX_OPT_DATA, FWDX_OPT_XAUTH);
- p += 5;
- p = fwdx_add_quoted_twobyte(p, fake_xauth.name_length);
- p = fwdx_add_quoted_twobyte(p, fake_xauth.data_length);
- for (c = 0; c < fake_xauth.name_length; c++) {
- *p++ = fake_xauth.name[c];
- if ((unsigned char)fake_xauth.name[c] == 0xFF)
- *p++ = 0xFF;
- }
- for (c = 0; c < fake_xauth.data_length; c++) {
- *p++ = fake_xauth.data[c];
- if ((unsigned char)fake_xauth.data[c] == 0xFF)
- *p++ = 0xFF;
- }
- sprintf(p, "%c%c", IAC, SE);
- p += 2;
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- sprintf((char *)fwdx_msg_out,"TELNET SENT SB %s OPTION_DATA XAUTH ",
- TELOPT(TELOPT_FORWARD_X));
- tn_hex((char *)fwdx_msg_out,TN_MSG_LEN,&sb_priv[5],(p-sb_priv)-7);
- ckstrncat((char *)fwdx_msg_out," IAC SE",TN_MSG_LEN);
- }
-#endif /* DEBUG */
-
- /* Add Telnet Debug info here */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,(char *)fwdx_msg_out,"",0);
- if (tn_deb || debses) tn_debug((char *)fwdx_msg_out);
-#endif /* DEBUG */
- rc = ( ttol(sb_priv,p-sb_priv) < 0 ); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc) {
- debug(F110,"fwdx_send_xauth()","ttol() failed",0);
- return(-1);
- }
-
-
- free(sb_priv);
- return(0);
-}
-#endif /* COMMENT */
-#ifdef FWDX_SERVER
-/* Only if we ever become a server - not yet ported to Kermit */
-/* And even so most of this code does not belong in this module */
-
-int
-fwdx_write_xauthfile(void)
-{
- int dpynum, scrnum, family;
- char myhost[300], *host, *rest = NULL;
- FILE *file;
- struct sockaddr_in saddr;
- struct hostent *hi;
-
- if (!fwdx_display && !fwdx_xauthfile)
- return 1;
- if (!parse_displayname(fwdx_display,
- &family, &host, &dpynum, &scrnum, &rest))
- return 2;
- if (rest) free(rest);
- if (host) free(host);
- if (family != FamilyInternet)
- return 3; /* every thing but FamilyInternet is unexpected */
-
- /* X connections to localhost:1 is actually treated as local unix sockets,
- * see the 'xauth' man page.
- */
- xauth.family = FamilyLocal;
- if (gethostname(myhost, sizeof(myhost) - 1))
- return 5;
- xauth.address_length = strlen(myhost);
- if (!(xauth.address = malloc(xauth.address_length)))
- return 5;
- memcpy(xauth.address, myhost, xauth.address_length);
-
- /* the display number is written as a string, not numeric */
- if (!(xauth.number = malloc(6)))
- return 6;
- snprintf(xauth.number, 5, "%u", dpynum);
- xauth.number_length = strlen(xauth.number);
- if (!(file = fopen(fwdx_xauthfile, "wb")))
- return 7;
- if (!XauWriteAuth(file, &xauth))
- return 8;
- fclose(file);
- setenv("XAUTHORITY", fwdx_xauthfile, 1);
- return 0;
-}
-
-int
-fwdx_setup_xauth(unsigned char *sp, int len)
-/* called with 'len' xauth bytes, starting at 'sp'
- * the data format is: <uint16 name_length> <uint16 data_length> <name> <data>
- */
-{
- int xauthfd;
-
- if (!fwdx_options[FWDX_OPT_XAUTH])
- return 1;
- if (len < 4)
- return 2;
-
- /* setup the xauth struct */
- xauth.name_length = (sp[0] << 8) + sp[1];
- xauth.data_length = (sp[2] << 8) + sp[3];
- if (len != 4 + xauth.name_length + xauth.data_length)
- return 3;
- xauth.name = malloc(xauth.name_length);
- xauth.data = malloc(xauth.data_length);
- if (!xauth.name || !xauth.data)
- return 4;
- memcpy(xauth.name, sp + 4, xauth.name_length);
- memcpy(xauth.data, sp + 4 + xauth.name_length, xauth.data_length);
-
- /* Setup to always have a local .Xauthority. */
- fwdx_xauthfile = malloc(MAXPATHLEN+1);
- snprintf(fwdx_xauthfile, MAXPATHLEN, "/tmp/XauthXXXXXX");
- if ((xauthfd = mkstemp(fwdx_xauthfile)) != -1)
- /* we change file ownership later, when we know who is to be owner! */
- close(xauthfd);
- else {
- free(fwdx_xauthfile);
- fwdx_xauthfile = NULL;
- return 5;
- }
-/* Must have the subshell's new DISPLAY env var to write xauth to xauthfile */
- if (fwdx_display)
- if (fwdx_write_xauthfile())
- return 6;
-
- return 0;
-}
-
-void fwdx_set_xauthfile_owner(int uid)
-{
- struct passwd *pwd;
-
- if (!fwdx_xauthfile || !(pwd = getpwuid(uid)))
- return;
- chown(fwdx_xauthfile, pwd->pw_uid, pwd->pw_gid);
-}
-
-int
-fwdx_server_accept_options(unsigned char *sp, int len)
-/* called with 'len' option bytes, starting at 'sp' */
-{
- int c;
-
- for (c = 0; c < len-2; c++) {
- if (c == 0) {
- if (sp[c] & FWDX_OPT_XAUTH)
- flag = 1;
- }
- }
- return(0);
-}
-#endif /* FWDX_SERVER */
-#endif /* CK_FORWARD_X */
-
-#ifdef IKS_OPTION
-/*
- iks_wait() -- Wait for an IKS subnegotiation response.
- sb - is either KERMIT_REQ_START or KERMIT_REQ_STOP depending on the desired
- state of the peer's Kermit server.
- flushok - specifies whether it is ok to throw away non-Telnet data
- if so, then we call ttflui() instead of tn_flui().
- Returns:
- 1 if the desired state is achieved or if it is unknown.
- 0 if the desired state is not achieved.
-*/
-int
-#ifdef CK_ANSIC
-iks_wait(int sb, int flushok)
-#else /* CK_ANSIC */
-iks_wait(sb,flushok) int sb; int flushok;
-#endif /* CK_ANSIC */
-{
- int tn_wait_save = tn_wait_flg;
- int x;
-
- if (TELOPT_U(TELOPT_KERMIT)) {
- switch (sb) {
- case KERMIT_REQ_START:
- debug(F111,
- "iks_wait KERMIT_REQ_START",
- "u_start",
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start
- );
- tn_siks(KERMIT_REQ_START);
- tn_wait_flg = 1; /* Kermit Option MUST wait */
- do {
- if (flushok)
- tn_wait_idx = 0;
- x = tn_wait("iks_wait() me_iks_req_start");
- } while (x == 0 && flushok && tn_wait_idx == TN_WAIT_BUF_SZ);
- tn_wait_flg = tn_wait_save;
- if (flushok)
- tn_wait_idx = 0;
- if (tn_wait_idx == TN_WAIT_BUF_SZ) {
- /*
- * We are attempting to start a kermit server on the peer
- * the most likely reason is because we want to perform a
- * file transfer. But there is a huge amount of non telnet
- * negotiation data coming in and so we have not been able
- * to find the response. So we will lie and assume that
- * response is 'yes'. The worse that will happen is that
- * a RESP_STOP is received after we enter protocol mode.
- * And the protocol operation will be canceled.
- */
- tn_push();
- return(1);
- } else {
- tn_push();
- return(TELOPT_SB(TELOPT_KERMIT).kermit.u_start);
- }
- case KERMIT_REQ_STOP:
- debug(F111,
- "iks_wait KERMIT_REQ_STOP",
- "u_start",
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start
- );
- tn_siks(KERMIT_REQ_STOP);
- tn_wait_flg = 1; /* Kermit Option MUST wait */
- do {
- if (flushok)
- tn_wait_idx = 0;
- x = tn_wait("iks_wait() me_iks_req_stop");
- } while (x == 0 && flushok && tn_wait_idx == TN_WAIT_BUF_SZ);
- tn_wait_flg = tn_wait_save;
- if (flushok)
- tn_wait_idx = 0;
-
- if (tn_wait_idx == TN_WAIT_BUF_SZ) {
- /*
- * We are attempting to stop a kermit server on the peer
- * the most likely reason being that we want to enter
- * CONNECT mode. But there is a huge amount of non telnet
- * negotiation data coming in and so we have not been able
- * to find the response. So we will lie and assume that
- * the answer is 'yes' and allow the CONNECT command to
- * succeed. The worst that happens is that CONNECT mode
- * swallows the incoming data displaying it to the user
- * and then it resumes Kermit client mode.
- */
- tn_push();
- return(1);
- } else {
- tn_push();
- return(!TELOPT_SB(TELOPT_KERMIT).kermit.u_start);
- }
- }
- tn_push();
- }
- return(1);
-}
-
-int
-#ifdef CK_ANSIC
-iks_tn_sb(CHAR * sb, int n)
-#else
-iks_tn_sb(sb, n) CHAR * sb; int n;
-#endif /* CK_ANSIC */
-{
- extern int server;
- extern CHAR sstate;
-#ifdef NOICP
- extern int autodl;
- int inautodl = 0, cmdadl = 1;
-#else
-#ifdef CK_AUTODL
- extern int autodl, inautodl, cmdadl;
-#endif /* CK_AUTODL */
-#endif /* NOICP */
- switch (sb[0]) {
- case KERMIT_START: /* START */
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start = 1;
- return(4);
-
- case KERMIT_STOP: /* STOP */
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start = 0;
- return(4);
-
- case KERMIT_REQ_START: /* REQ-START */
-#ifndef NOXFER
- if (inserver) {
-#ifdef CK_AUTODL
- cmdadl = 1; /* Turn on packet detection */
-#endif /* CK_AUTODL */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 1;
- tn_siks(KERMIT_RESP_START);
- } else if (TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_RESP_START);
- } else {
-#ifndef IKSDONLY
-#ifdef CK_AUTODL
-#ifdef OS2
- if (local && (IsConnectMode() && autodl) ||
- (!IsConnectMode() &&
- (inautodl || sstate == 'x' || sstate == 'v'))
- )
- tn_siks(KERMIT_RESP_START); /* START */
- else
-
-#else /* OS2 */
- if ((local && what == W_CONNECT && autodl) ||
- (local && what != W_CONNECT &&
- (inautodl || sstate == 'x' || sstate == 'v')
- ))
- tn_siks(KERMIT_RESP_START); /* START */
- else
-#endif /* OS2 */
-#endif /* CK_AUTODL */
-#endif /* IKSDONLY */
- tn_siks(KERMIT_RESP_STOP);
- }
-#else /* NOXFER */
- tn_siks(KERMIT_RESP_STOP);
-#endif /* NOXFER */
- return(4);
-
- case KERMIT_REQ_STOP: /* REQ-STOP */
- /* The protocol requires that the request be responded to */
- /* either by changing states or by reporting the current */
- /* state. */
-
- /* We need to provide the user some way of dictating what */
- /* the policies should be. For instance, if we are in */
- /* CONNECT mode with autodownload ON and we get a REQ-STOP*/
- /* what should the proper response be? */
-#ifndef NOXFER
- if (inserver
-#ifdef CK_AUTODL
- || !local && cmdadl
-#endif /* CK_AUTODL */
- ) {
-#ifdef CK_AUTODL
- cmdadl = 0; /* Turn off packet detection */
-#endif /* CK_AUTODL */
- tn_siks(KERMIT_RESP_STOP);
- } else if (server) {
- extern int en_fin;
- if (en_fin) { /* If the server is allowed to stop */
- tn_siks(KERMIT_RESP_STOP);
- } else { /* We are not allowed to stop */
- tn_siks(KERMIT_RESP_START);
- }
- }
-#ifndef IKSDONLY
-#ifdef CK_AUTODL
-#ifdef OS2
- else if (local && (IsConnectMode() && autodl) ||
- (!IsConnectMode() && inautodl)
- ) {
- /* If we are a pseudo-server and the other side requests */
- /* that we stop, tell then that we have even though we */
- /* have not. Otherwise, the other side might refuse to */
- /* enter SERVER mode. */
-
- tn_siks(KERMIT_RESP_STOP); /* STOP */
- }
-#else /* OS2 */
- else if ((local && what == W_CONNECT && autodl) ||
- (local && what != W_CONNECT && inautodl)
- ) {
- /* If we are a pseudo-server and the other side requests */
- /* that we stop, tell then that we have even though we */
- /* have not. Otherwise, the other side might refuse to */
- /* enter SERVER mode. */
-
- tn_siks(KERMIT_RESP_STOP); /* STOP */
- }
-#endif /* OS2 */
-#endif /* CK_AUTODL */
-#endif /* IKSDONLY */
- else
-#endif /* NOXFER */
- {
- /* If we are not currently in any mode that accepts */
- /* Kermit packets then of course report that we are */
- /* not being a Kermit server. */
-
- tn_siks(KERMIT_RESP_STOP); /* STOP */
- }
- return(4);
-
- case KERMIT_SOP: { /* SOP */
-#ifndef NOXFER
- extern CHAR stchr; /* Incoming SOP character */
- stchr = sb[1];
-#endif /* NOXFER */
- TELOPT_SB(TELOPT_KERMIT).kermit.sop = 1;
- return(4);
- }
-
- case KERMIT_RESP_START: /* START */
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start = 1;
- if (TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start) {
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start = 0;
- } else if (TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop) {
- /* If we have issued a request to stop a Kermit Server */
- /* and the response is Start, then we must report this */
- /* to the caller. */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop = 0;
- }
- return(4);
-
- case KERMIT_RESP_STOP: /* STOP */
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start = 0;
- if (TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start) {
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start = 0;
- /* If we have issued a request to start a Kermit Server */
- /* and the response is Stop, then we must report this */
- /* to the caller. */
- } else if (TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop) {
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop = 0;
- }
- return(4);
-
- default:
- return(0);
-
- } /* switch (sb[0]) */
-}
-#endif /* IKS_OPTION */
-
-/* Initialize telnet settings - set default values for ME and U modes */
-int
-tn_set_modes() {
- int opt,cmd;
-#ifdef CK_FORWARD_X
- int x;
-#endif /* CK_FORWARD_X */
-#ifdef CK_ENVIRONMENT
- {
- int i,j;
- for (i = 0; i < 8; i++) {
- tn_env_uservar[i][0] = NULL;
- tn_env_uservar[i][1] = NULL;
- }
- }
-#endif /* CK_ENVIRONMENT */
-
- /* initialize all options to refuse in both directions */
- for (opt = 0; opt < NTELOPTS; opt++) {
- TELOPT_ME(opt) = 0;
- TELOPT_U(opt) = 0;
- TELOPT_UNANSWERED_WILL(opt) = 0;
- TELOPT_UNANSWERED_DO(opt) = 0;
- TELOPT_UNANSWERED_WONT(opt) = 0;
- TELOPT_UNANSWERED_DONT(opt) = 0;
- TELOPT_UNANSWERED_SB(opt) = 0;
- TELOPT_ME_MODE(opt) = TN_NG_RF;
- TELOPT_U_MODE(opt) = TN_NG_RF;
- TELOPT_DEF_S_ME_MODE(opt) = TN_NG_RF;
- TELOPT_DEF_S_U_MODE(opt) = TN_NG_RF;
- TELOPT_DEF_C_ME_MODE(opt) = TN_NG_RF;
- TELOPT_DEF_C_U_MODE(opt) = TN_NG_RF;
- for (cmd = 0; cmd < 4; cmd ++)
- tncnts[TELOPT_INDEX(opt)][cmd] = 0;
- }
-#ifdef IKS_OPTION
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start = 0;
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start = 0;
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop = 0;
- TELOPT_SB(TELOPT_KERMIT).kermit.sop = 0;
-#endif /* IKS_OPTION */
-
-#ifdef CK_ENCRYPTION
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 0;
-#endif /* CK_ENCRYPTION */
-
-#ifdef CK_NAWS
- TELOPT_SB(TELOPT_NAWS).naws.x = 0;
- TELOPT_SB(TELOPT_NAWS).naws.y = 0;
-#endif /* CK_NAWS */
-
-#ifdef CK_SSL
- TELOPT_SB(TELOPT_START_TLS).start_tls.u_follows = 0;
- TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows = 0;
- TELOPT_SB(TELOPT_START_TLS).start_tls.auth_request = 0;
-#endif /* CK_SSL */
-
- /* Now set the ones we want to accept to the proper values */
- TELOPT_DEF_S_ME_MODE(TELOPT_SGA) = TN_NG_RQ;
- TELOPT_DEF_S_U_MODE(TELOPT_SGA) = TN_NG_RQ;
- TELOPT_DEF_C_ME_MODE(TELOPT_SGA) = TN_NG_AC;
- TELOPT_DEF_C_U_MODE(TELOPT_SGA) = TN_NG_AC;
-
- TELOPT_DEF_S_ME_MODE(TELOPT_BINARY) = TN_NG_AC;
- TELOPT_DEF_S_U_MODE(TELOPT_BINARY) = TN_NG_AC;
- TELOPT_DEF_C_ME_MODE(TELOPT_BINARY) = TN_NG_AC;
- TELOPT_DEF_C_U_MODE(TELOPT_BINARY) = TN_NG_AC;
-
- TELOPT_DEF_S_ME_MODE(TELOPT_LOGOUT) = TN_NG_AC;
- TELOPT_DEF_S_U_MODE(TELOPT_LOGOUT) = TN_NG_AC;
- TELOPT_DEF_C_ME_MODE(TELOPT_LOGOUT) = TN_NG_AC;
- TELOPT_DEF_C_U_MODE(TELOPT_LOGOUT) = TN_NG_AC;
-
-#ifdef IKS_OPTION
- TELOPT_DEF_S_ME_MODE(TELOPT_KERMIT) = TN_NG_RQ;
- TELOPT_DEF_S_U_MODE(TELOPT_KERMIT) = TN_NG_RQ;
- TELOPT_DEF_C_ME_MODE(TELOPT_KERMIT) = TN_NG_RQ;
- TELOPT_DEF_C_U_MODE(TELOPT_KERMIT) = TN_NG_RQ;
-#endif /* IKS_OPTION */
-
-#ifdef CK_ENCRYPTION
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
-#endif /* CK_ENCRYPTION */
-
- TELOPT_DEF_S_ME_MODE(TELOPT_ECHO) = TN_NG_RQ;
-#ifdef IKSD
- if ( !inserver )
-#endif /* IKSD */
- TELOPT_DEF_S_U_MODE(TELOPT_TTYPE) = TN_NG_RQ;
-
-#ifdef CK_ENVIRONMENT
- TELOPT_DEF_S_U_MODE(TELOPT_NEWENVIRON) = TN_NG_RQ;
-#endif /* CK_ENVIRONMENT */
-
-#ifdef CK_AUTHENTICATION
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
-#endif /* CK_AUTHENTICATION */
-
-#ifdef CK_SSL
- if (ck_ssleay_is_installed()) {
- TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RQ;
- TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = TN_NG_AC;
- }
-#endif /* CK_SSL */
-
-#ifdef CK_NAWS
- TELOPT_DEF_S_U_MODE(TELOPT_NAWS) = TN_NG_RQ;
-#endif /* CK_NAWS */
-
- TELOPT_DEF_C_U_MODE(TELOPT_ECHO) = TN_NG_AC;
- TELOPT_DEF_C_ME_MODE(TELOPT_TTYPE) = TN_NG_RQ;
-
-#ifdef CK_ENVIRONMENT
- TELOPT_DEF_C_ME_MODE(TELOPT_NEWENVIRON) = TN_NG_RQ;
-#endif /* CK_ENVIRONMENT */
-
-#ifdef CK_AUTHENTICATION
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
-#endif /* CK_AUTHENTICATION */
-
-#ifdef CK_NAWS
- TELOPT_DEF_C_ME_MODE(TELOPT_NAWS) = TN_NG_RQ;
-#endif /* CK_NAWS */
-
-#ifdef CK_SNDLOC
- TELOPT_DEF_C_ME_MODE(TELOPT_SNDLOC) = TN_NG_RQ;
-#endif /* CK_SNDLOC */
-
-#ifdef CK_FORWARD_X
- TELOPT_DEF_C_U_MODE(TELOPT_FORWARD_X) = TN_NG_AC;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket = -1;
- for (x = 0; x < MAXFWDX; x++) {
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].fd = -1;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].id = -1;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].need_to_send_xauth = 0;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].suspend = 0;
- }
-#endif /* CK_FORWARD_X */
-
-#ifdef TN_COMPORT
- TELOPT_DEF_C_ME_MODE(TELOPT_COMPORT) = TN_NG_RQ;
-#endif /* TN_COMPORT */
-
- /* Set the initial values for currently known mode */
- for (opt = TELOPT_FIRST; opt <= TELOPT_LAST; opt++) {
- if (TELOPT_OK(opt)) {
- TELOPT_ME_MODE(opt) = sstelnet ?
- TELOPT_DEF_S_ME_MODE(opt) :
- TELOPT_DEF_C_ME_MODE(opt);
- TELOPT_U_MODE(opt) = sstelnet ?
- TELOPT_DEF_S_U_MODE(opt) :
- TELOPT_DEF_C_U_MODE(opt);
- }
- }
- return(1);
-}
-
-
-/* Send Delayed Subnegotiations */
-
-VOID
-tn_sdsb() {
- /* if (!IS_TELNET()) return; */
-
- if (TELOPT_SB(TELOPT_TTYPE).term.need_to_send) {
- tn_sttyp();
- TELOPT_SB(TELOPT_TTYPE).term.need_to_send = 0;
- }
-#ifdef CK_ENVIRONMENT
- if (TELOPT_SB(TELOPT_NEWENVIRON).env.need_to_send &&
- TELOPT_SB(TELOPT_NEWENVIRON).env.str) {
- tn_snenv((CHAR *)TELOPT_SB(TELOPT_NEWENVIRON).env.str,
- TELOPT_SB(TELOPT_NEWENVIRON).env.len);
- free(TELOPT_SB(TELOPT_NEWENVIRON).env.str);
- TELOPT_SB(TELOPT_NEWENVIRON).env.str=NULL;
- TELOPT_SB(TELOPT_NEWENVIRON).env.len=0;
- TELOPT_SB(TELOPT_NEWENVIRON).env.need_to_send = 0;
- }
-#ifdef CK_XDISPLOC
- if (TELOPT_SB(TELOPT_XDISPLOC).xdisp.need_to_send) {
- tn_sxdisploc();
- TELOPT_SB(TELOPT_XDISPLOC).xdisp.need_to_send = 0;
- }
-#endif /* CK_XDISPLOC */
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_NAWS
- if (TELOPT_SB(TELOPT_NAWS).naws.need_to_send) {
- tn_snaws();
- TELOPT_SB(TELOPT_NAWS).naws.need_to_send = 0;
- }
-#endif /* CK_NAWS */
-#ifdef CK_SNDLOC
- if (TELOPT_SB(TELOPT_SNDLOC).sndloc.need_to_send) {
- tn_sndloc();
- TELOPT_SB(TELOPT_SNDLOC).sndloc.need_to_send = 0;
- }
-#endif /* CK_SNDLOC */
-#ifdef CK_FORWARD_X
- if (TELOPT_SB(TELOPT_FORWARD_X).forward_x.need_to_send) {
- if ( sstelnet )
- fwdx_send_options();
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.need_to_send = 0;
- }
-#endif /* CK_FORWARD_X */
-#ifdef TN_COMPORT
- if (TELOPT_SB(TELOPT_COMPORT).comport.need_to_send) {
- tn_sndcomport();
- TELOPT_SB(TELOPT_COMPORT).comport.need_to_send = 0;
- }
-#endif /* TN_COMPORT */
-
-}
-
-int
-tn_reset() {
- int x,opt,cmd;
-
- /* if (!IS_TELNET()) return(1); */
-
- tn_wait_idx = 0; /* Clear the tn_push() buffer */
- tn_wait_tmo = TN_TIMEOUT; /* Reset wait timer stats */
-
- nflag = 0;
-
- /* Reset the TELNET OPTIONS counts */
- for (opt = TELOPT_FIRST; opt <= TELOPT_LAST; opt++) {
- if (TELOPT_OK(opt)) {
- TELOPT_ME(opt) = 0;
- TELOPT_U(opt) = 0;
- TELOPT_UNANSWERED_WILL(opt) = 0;
- TELOPT_UNANSWERED_DO(opt) = 0;
- TELOPT_UNANSWERED_WONT(opt) = 0;
- TELOPT_UNANSWERED_DONT(opt) = 0;
- TELOPT_UNANSWERED_SB(opt) = 0;
- TELOPT_ME_MODE(opt) = sstelnet ?
- TELOPT_DEF_S_ME_MODE(opt) :
- TELOPT_DEF_C_ME_MODE(opt);
- TELOPT_U_MODE(opt) = sstelnet ?
- TELOPT_DEF_S_U_MODE(opt) :
- TELOPT_DEF_C_U_MODE(opt);
-
-#ifdef DEBUG
- if (deblog) {
- switch (TELOPT_ME_MODE(opt)) {
- case TN_NG_RF:
- debug(F110,"tn_ini ME REFUSE ",TELOPT(opt),0);
- break;
- case TN_NG_AC:
- debug(F110,"tn_ini ME ACCEPT ",TELOPT(opt),0);
- break;
- case TN_NG_RQ:
- debug(F110,"tn_ini ME REQUEST",TELOPT(opt),0);
- break;
- case TN_NG_MU:
- debug(F110,"tn_ini ME REQUIRE",TELOPT(opt),0);
- break;
- }
- switch (TELOPT_U_MODE(opt)) {
- case TN_NG_RF:
- debug(F110,"tn_ini U REFUSE ",TELOPT(opt),0);
- break;
- case TN_NG_AC:
- debug(F110,"tn_ini U ACCEPT ",TELOPT(opt),0);
- break;
- case TN_NG_RQ:
- debug(F110,"tn_ini U REQUEST",TELOPT(opt),0);
- break;
- case TN_NG_MU:
- debug(F110,"tn_ini U REQUIRE",TELOPT(opt),0);
- break;
- }
- }
-#endif /* DEBUG */
- for (cmd = 0; cmd < 4; cmd ++)
- tncnts[TELOPT_INDEX(opt)][cmd] = 0;
- }
- }
-#ifdef CK_ENVIRONMENT
- if (!tn_env_flg) {
- TELOPT_ME_MODE(TELOPT_NEWENVIRON) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_NEWENVIRON) = TN_NG_RF;
- }
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_SNDLOC
- if (!tn_loc)
- TELOPT_DEF_C_ME_MODE(TELOPT_SNDLOC) = TN_NG_RF;
-#endif /* CK_SNDLOC */
-#ifdef IKS_OPTION
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start = 0;
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start = 0;
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop = 0;
- TELOPT_SB(TELOPT_KERMIT).kermit.sop = 0;
-#endif /* IKS_OPTION */
-#ifdef CK_ENCRYPTION
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 0;
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.need_to_send = 0;
-#endif /* CK_ENCRYPTION */
-#ifdef CK_NAWS
- TELOPT_SB(TELOPT_NAWS).naws.need_to_send = 0;
- TELOPT_SB(TELOPT_NAWS).naws.x = 0;
- TELOPT_SB(TELOPT_NAWS).naws.y = 0;
-#endif /* CK_NAWS */
- TELOPT_SB(TELOPT_TTYPE).term.need_to_send = 0;
- TELOPT_SB(TELOPT_TTYPE).term.type[0] = '\0';
-#ifdef CK_ENVIRONMENT
- TELOPT_SB(TELOPT_NEWENVIRON).env.need_to_send = 0;
- if (tn_first)
- TELOPT_SB(TELOPT_NEWENVIRON).env.str=NULL;
- else if (TELOPT_SB(TELOPT_NEWENVIRON).env.str) {
- free(TELOPT_SB(TELOPT_NEWENVIRON).env.str);
- TELOPT_SB(TELOPT_NEWENVIRON).env.str=NULL;
- }
- TELOPT_SB(TELOPT_NEWENVIRON).env.len=0;
-#ifdef CK_XDISPLOC
- TELOPT_SB(TELOPT_XDISPLOC).xdisp.need_to_send = 0;
-#endif /* CK_XDISPLOC */
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_SNDLOC
- TELOPT_SB(TELOPT_SNDLOC).sndloc.need_to_send = 0;
-#endif /* CK_SNDLOC */
-#ifdef CK_FORWARD_X
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.need_to_send = 0;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.listen_socket = -1;
- for (x = 0; x < MAXFWDX; x++) {
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].fd = -1;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].id = -1;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].need_to_send_xauth = 0;
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.channel[x].suspend = 0;
- }
- /* Reset Xauth data */
- if ( real_xauth ) {
- XauDisposeAuth(real_xauth);
- real_xauth = NULL;
- }
- if ( fake_xauth.name )
- free(fake_xauth.name);
- if ( fake_xauth.data )
- free(fake_xauth.data);
- if ( fake_xauth.address )
- free(fake_xauth.address);
- if ( fake_xauth.number )
- free(fake_xauth.number);
- memset(&fake_xauth,0,sizeof(fake_xauth));
-#ifdef NT
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.thread_started = 0;
-#endif /* NT */
-#endif /* CK_FORWARD_X */
-#ifdef CK_SSL
- if (tls_only_flag || ssl_only_flag) {
- TELOPT_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- }
- TELOPT_SB(TELOPT_START_TLS).start_tls.u_follows = 0;
- TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows = 0;
- TELOPT_SB(TELOPT_START_TLS).start_tls.auth_request = 0;
-#endif /* CK_SSL */
-
-#ifdef CK_ENCRYPTION
- if (!ck_crypt_is_installed()
-#ifdef CK_SSL
- || tls_only_flag || ssl_only_flag
-#endif /* CK_SSL */
- ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
-#endif /* CK_ENCRYPTION */
-
-#ifdef TN_COMPORT
- TELOPT_SB(TELOPT_COMPORT).comport.need_to_send = 0;
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_ms = 0;
- tnc_init();
-#endif /* TN_COMPORT */
-
- tn_first = 0; /* No longer the first time init */
-
-#ifdef OS2
- ttnum = -1; /* Reset TermType negotiation */
- ttnumend = 0;
-#endif /* OS2 */
-
- return(0);
-}
-
-int
-tn_start() {
- int wait, x, opt;
-
- /* if (!IS_TELNET()) return(0); */
-
- if (tn_init && tn_begun)
- return(0);
- tn_begun = 1;
-
- debug(F111,"tn_start","sstelnet",sstelnet);
- wait = 0;
- if (tn_duplex) {
- oldplex = duplex; /* save old duplex value */
- duplex = 1; /* and set to half duplex for telnet */
- }
-#ifdef CK_SSL
- if (!TELOPT_ME(TELOPT_START_TLS) &&
- TELOPT_ME_MODE(TELOPT_START_TLS) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_START_TLS) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_START_TLS) = 1;
- wait = 1;
- }
- if (!TELOPT_U(TELOPT_START_TLS) &&
- TELOPT_U_MODE(TELOPT_START_TLS) >= TN_NG_RQ) {
- if (tn_sopt(DO, TELOPT_START_TLS) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(TELOPT_START_TLS) = 1;
- wait = 1;
- }
-#endif /* CK_SSL */
-
-#ifdef CK_AUTHENTICATION
- debug(F110,"tn_ini() CK_AUTHENTICATION","",0);
- if (tn_init) /* tn_ini() might be called recursively */
- return(0);
- if (!TELOPT_ME(TELOPT_AUTHENTICATION) &&
- TELOPT_ME_MODE(TELOPT_AUTHENTICATION) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_AUTHENTICATION) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_AUTHENTICATION) = 1;
- wait = 1;
- }
- if (!TELOPT_U(TELOPT_AUTHENTICATION) &&
- TELOPT_U_MODE(TELOPT_AUTHENTICATION) >= TN_NG_RQ) {
- if (tn_sopt(DO, TELOPT_AUTHENTICATION) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(TELOPT_AUTHENTICATION) = 1;
- wait = 1;
- }
-#ifdef CK_ENCRYPTION
- if (TELOPT_U_MODE(TELOPT_AUTHENTICATION) == TN_NG_RF &&
- TELOPT_ME_MODE(TELOPT_AUTHENTICATION) == TN_NG_RF) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
-#endif /* CK_ENCRYPTION */
-#endif /* CK_AUTHENTICATION */
-
-#ifdef CK_NAWS
-#ifndef NOLOCAL
- debug(F110,"tn_ini() CK_NAWS !NOLOCAL","",0);
- if (!sstelnet) {
- /* Console terminal screen rows and columns */
-#ifdef OS2
- debug(F101,
- "tn_ini tt_rows 1",
- "",
- VscrnGetHeight(VTERM)-(tt_status[VTERM]?1:0)
- );
- debug(F101,"tn_ini tt_cols 1","",VscrnGetWidth(VTERM));
- /* Not known yet */
- if (VscrnGetWidth(VTERM) < 0 ||
- VscrnGetHeight(VTERM)-(tt_status[VTERM]?1:0) < 0) {
- ttgwsiz(); /* Try to find out */
- }
- debug(F101,
- "tn_ini tt_rows 2",
- "",
- VscrnGetHeight(VTERM)-(tt_status[VTERM]?1:0)
- );
- debug(F101,"tn_ini tt_cols 2","",VscrnGetWidth(VTERM));
- /* Now do we know? */
- if (VscrnGetWidth(VTERM) > 0 &&
- VscrnGetHeight(VTERM)-(tt_status[VTERM]?1:0) > 0) {
- if (!TELOPT_ME(TELOPT_NAWS) &&
- TELOPT_ME_MODE(TELOPT_NAWS) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_NAWS) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_NAWS) = 1;
- wait = 1;
- }
- }
-#else /* OS2 */
- debug(F101,"tn_ini tt_rows 1","",tt_rows);
- debug(F101,"tn_ini tt_cols 1","",tt_cols);
- if (tt_rows < 0 || tt_cols < 0) { /* Not known yet */
- ttgwsiz(); /* Try to find out */
- }
- debug(F101,"tn_ini tt_rows 2","",tt_rows);
- debug(F101,"tn_ini tt_cols 2","",tt_cols);
- if (tt_rows > 0 && tt_cols > 0) { /* Now do we know? */
- if (!TELOPT_ME(TELOPT_NAWS) &&
- TELOPT_ME_MODE(TELOPT_NAWS) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_NAWS) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_NAWS) = 1;
- wait = 1;
- }
- }
-#endif /* OS2 */
- } else
-#endif /* NOLOCAL */
- {
- if (!TELOPT_U(TELOPT_NAWS) &&
- TELOPT_U_MODE(TELOPT_NAWS) >= TN_NG_RQ) {
- if (tn_sopt(DO, TELOPT_NAWS) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(TELOPT_NAWS) = 1;
- wait = 1;
- }
- }
-#endif /* CK_NAWS */
-
- if (!TELOPT_ME(TELOPT_SGA) &&
- TELOPT_ME_MODE(TELOPT_SGA) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_SGA) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_SGA) = 1;
- wait = 1;
- }
- if (!TELOPT_U(TELOPT_SGA) &&
- TELOPT_U_MODE(TELOPT_SGA) >= TN_NG_RQ) {
- if (tn_sopt(DO, TELOPT_SGA) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(TELOPT_SGA) = 1;
- wait = 1;
- }
- if (!tn_duplex) {
- if (!TELOPT_U(TELOPT_ECHO) &&
- TELOPT_U_MODE(TELOPT_ECHO) >= TN_NG_RQ) {
- if (tn_sopt(DO, TELOPT_ECHO) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(TELOPT_ECHO) = 1;
- wait = 1;
- }
- }
- if (!TELOPT_ME(TELOPT_ECHO) &&
- TELOPT_ME_MODE(TELOPT_ECHO) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_ECHO) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_ECHO) = 1;
- wait = 1;
- }
-
- debug(F100,"tn_ini about to send WILL TTYPE if requested","",0);
-/*
- Talking to TELNET port, so send WILL TERMINAL TYPE and DO SGA.
- Also send WILL NAWS if we know our screen dimensions.
-*/
- if (!TELOPT_ME(TELOPT_TTYPE) &&
- TELOPT_ME_MODE(TELOPT_TTYPE) >= TN_NG_RQ) {
- if ((x = tn_sopt(WILL,TELOPT_TTYPE)) < 0) {
- debug(F101,"tn_ini tn_sopt WILL TTYPE failed","",x);
- return(-1);
- }
- TELOPT_UNANSWERED_WILL(TELOPT_TTYPE) = 1;
- wait = 1;
- debug(F100,"tn_ini sent WILL TTYPE ok","",0);
- }
- if (!TELOPT_U(TELOPT_TTYPE) &&
- TELOPT_U_MODE(TELOPT_TTYPE) >= TN_NG_RQ) {
- if ((x = tn_sopt(DO,TELOPT_TTYPE)) < 0) {
- debug(F101,"tn_ini tn_sopt DO TTYPE failed","",x);
- return(-1);
- }
- TELOPT_UNANSWERED_DO(TELOPT_TTYPE) = 1;
- wait = 1;
- debug(F100,"tn_ini sent DO TTYPE ok","",0);
- }
- if (!TELOPT_ME(TELOPT_BINARY) &&
- TELOPT_ME_MODE(TELOPT_BINARY) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_BINARY) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_BINARY) = 1;
- wait = 1;
- }
- if (!TELOPT_U(TELOPT_BINARY) &&
- TELOPT_U_MODE(TELOPT_BINARY) >= TN_NG_RQ) {
- if (tn_sopt(DO, TELOPT_BINARY) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(TELOPT_BINARY) = 1;
- wait = 1;
- }
-#ifdef CK_SNDLOC
- if (tn_loc) {
- if (!TELOPT_ME(TELOPT_SNDLOC) &&
- TELOPT_ME_MODE(TELOPT_SNDLOC) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_SNDLOC) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_SNDLOC) = 1;
- wait = 1;
- }
- }
-#endif /* CK_SNDLOC */
-#ifdef CK_ENVIRONMENT
-#ifdef CK_FORWARD_X
- if (!TELOPT_U(TELOPT_FORWARD_X) &&
- TELOPT_U_MODE(TELOPT_FORWARD_X) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_FORWARD_X) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_FORWARD_X) = 1;
- wait = 1;
- }
-#endif /* FORWARD_X */
-#ifdef CK_XDISPLOC
- if (!TELOPT_ME(TELOPT_XDISPLOC) &&
- TELOPT_ME_MODE(TELOPT_XDISPLOC) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_XDISPLOC) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_XDISPLOC) = 1;
- wait = 1;
- }
-#endif /* CK_XDISPLOC */
- /* Will send terminal environment. */
- if (!TELOPT_ME(TELOPT_NEWENVIRON) &&
- TELOPT_ME_MODE(TELOPT_NEWENVIRON) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_NEWENVIRON) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_NEWENVIRON) = 1;
- wait = 1;
- }
- if (!TELOPT_U(TELOPT_NEWENVIRON) &&
- TELOPT_U_MODE(TELOPT_NEWENVIRON) >= TN_NG_RQ) {
- if (tn_sopt(DO, TELOPT_NEWENVIRON) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(TELOPT_NEWENVIRON) = 1;
- wait = 1;
- }
-#endif /* CK_ENVIRONMENT */
-
- /* Take care of any other telnet options that require handling. */
-
- for (opt = TELOPT_FIRST; opt <= TELOPT_LAST; opt++) {
- switch (opt) {
- case TELOPT_AUTHENTICATION:
- case TELOPT_ENCRYPTION:
- case TELOPT_TTYPE:
- case TELOPT_NAWS:
- case TELOPT_BINARY:
- case TELOPT_NEWENVIRON:
- case TELOPT_SNDLOC:
- case TELOPT_XDISPLOC:
- case TELOPT_SGA:
- case TELOPT_ECHO:
- case TELOPT_KERMIT:
- case TELOPT_START_TLS:
- case TELOPT_FORWARD_X:
- break;
- break;
- default:
- if (TELOPT_OK(opt)) {
- if (!TELOPT_ME(opt) &&
- TELOPT_ME_MODE(opt) >= TN_NG_RQ) {
- if (tn_sopt(WILL, opt) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(opt) = 1;
- wait = 1;
- }
- if (!TELOPT_U(opt) &&
- TELOPT_U_MODE(opt) >= TN_NG_RQ) {
- if (tn_sopt(DO, opt) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(opt) = 1;
- wait = 1;
- }
- }
- }
- }
- if (wait) {
- if (tn_wait("pre-encrypt") < 0) {
- tn_push();
- return(-1);
- }
- wait = 0;
- }
-
-#ifdef CK_ENCRYPTION
- if (tn_init) /* tn_ini() may be called recursively */
- return(0);
-
- if (!TELOPT_ME(TELOPT_ENCRYPTION) &&
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_ENCRYPTION) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_ENCRYPTION) = 1;
- wait = 1;
- }
- if (!TELOPT_U(TELOPT_ENCRYPTION) &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION) >= TN_NG_RQ) {
- if (tn_sopt(DO, TELOPT_ENCRYPTION) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(TELOPT_ENCRYPTION) = 1;
- wait = 1;
- }
-
- /* If we are going to encrypt, we want to do it before we send any more */
- /* data, especially the terminal type and environment variables. */
- if (wait) {
- if (tn_wait("post-encrypt") < 0) {
- tn_push();
- return(-1);
- }
- wait = 0;
- }
-#endif /* CK_ENCRYPTION */
-
- tn_sdsb();
-
- if (tn_init) /* tn_ini() may be called recursively */
- return(0);
-
-#ifdef IKS_OPTION
- /* Kermit Server negotiation must go last */
- /* Send U before ME */
-
- if (!TELOPT_U(TELOPT_KERMIT) &&
- TELOPT_U_MODE(TELOPT_KERMIT) >= TN_NG_RQ) {
- if (tn_sopt(DO, TELOPT_KERMIT) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(TELOPT_KERMIT) = 1;
- wait = 1;
- }
- if (!TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_ME_MODE(TELOPT_KERMIT) >= TN_NG_RQ) {
- if (tn_sopt(WILL, TELOPT_KERMIT) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(TELOPT_KERMIT) = 1;
- wait = 1;
- }
-#endif /* IKS_OPTION */
-
- if (wait) {
- if (tn_wait("end of telnet negotiations") < 0) {
- tn_push();
- return(-1);
- }
- wait = 0;
- }
-
- tn_sdsb(); /* Send delayed subnegotiations */
- tn_push();
- return(0);
-}
-
-/* Start a telnet connection. */
-/* Returns -1 on error, 0 if nothing happens, 1 if init msgs sent ok */
-
-int
-tn_ini() {
- int x;
-
- debug(F101,"tn_ini ttnproto","",ttnproto);
- debug(F101,"tn_ini tn_init","",tn_init);
-
- if (ttnet != NET_TCPB) /* Make sure connection is TCP/IP */
- return(0);
-/*
- if (!IS_TELNET())
- return(0);
-*/
- if (tn_init) /* Have we done this already? */
- return(0); /* Don't do it again. */
-
- tn_reset(); /* Reset telnet parameters */
- tn_begun = 0; /* Reset; will be set by tn_start() */
-
- switch ( ttnproto ) {
- case NP_RLOGIN:
- case NP_K4LOGIN:
- case NP_EK4LOGIN:
- case NP_K5LOGIN:
- case NP_EK5LOGIN:
- case NP_K5U2U:
- tn_init = 1;
- debug(F100,"tn_ini telnet negotiations ignored","tn_init",tn_init);
- return(0);
-#ifdef COMMENT
- /* Jeff's code from 30 Dec 2005 - doesn't work with SSL POP server */
- case NP_NONE:
- case NP_SSL:
- case NP_TLS:
- ttnproto = NP_TELNET; /* pretend it's telnet anyway, */
- oldplex = duplex; /* save old duplex value */
- duplex = 1; /* and set to half duplex for telnet */
- if (inserver)
- debug(F100,"tn_ini skipping telnet negotiations","",0);
- else
- tn_wait("tn_ini - waiting to see if telnet negotiations were sent");
- tn_push();
- return(0);
- case NP_SSL_RAW:
- case NP_TLS_RAW:
- case NP_TCPRAW: /* Raw socket requested. */
- debug(F100,"tn_ini telnet negotiations ignored","tn_init",tn_init);
- return(0);
-#else
- /* My code from 4 Dec 2005 - works with SSL POP server */
- case NP_NONE:
- case NP_SSL:
- case NP_TLS: /* If not talking to a telnet port, */
- case NP_SSL_RAW: /* SSL and TLS with Telnet */
- case NP_TLS_RAW: /* negotiations disabled. */
- ttnproto = NP_TELNET; /* pretend it's telnet anyway, */
- oldplex = duplex; /* save old duplex value */
- duplex = 1; /* and set to half duplex for telnet */
- if (inserver)
- debug(F100,"tn_ini skipping telnet negotiations","",0);
- else
- tn_wait("tn_ini - waiting to see if telnet negotiations were sent");
- tn_push();
- return(0);
- case NP_TCPRAW: /* Raw socket requested. */
- debug(F100,"tn_ini telnet negotiations ignored","tn_init",tn_init);
- return(0);
-#endif /* COMMENT */
- case NP_KERMIT: /* switching to Telnet protocol */
- case NP_SSL_TELNET:
- case NP_TLS_TELNET:
- debug(F101,"tn_ini switching from XXX to Telnet","",ttnproto);
- ttnproto = NP_TELNET;
- /* fall through */
- default:
- /* We are already using a variation on Telnet protocol */
- ;
- }
-
- x = tn_start();
- tn_init = 1; /* Remember successful completion. */
-
- /* Don't send anything else! */
- debug(F101,"tn_ini duplex","",duplex);
- debug(F101,"tn_ini done, tn_init","",tn_init);
- return(x);
-}
-
-int
-#ifdef CK_ANSIC
-tn_hex(CHAR * buf, int buflen, CHAR * data, int datalen)
-#else /* CK_ANSIC */
-tn_hex(buf, buflen, data, datalen)
- CHAR * buf;
- int buflen;
- CHAR * data;
- int datalen;
-#endif /* CK_ANSIC */
-{
- int i = 0, j = 0, k = 0;
- CHAR tmp[16]; /* in case value is treated as negative */
-#ifdef COMMENT
- int was_hex = 1;
-
- for (k=0; k < datalen; k++) {
- if (data[k] < 32 || data[k] >= 127) {
- sprintf(tmp,"%s%02X ",was_hex?"":"\" ",data[k]);
- was_hex = 1;
- } else {
- sprintf(tmp,"%s%c",was_hex?"\"":"",data[k]);
- was_hex = 0;
- }
- ckstrncat((char *)buf,tmp,buflen);
- }
- if (!was_hex)
- ckstrncat((char *)buf,"\" ",buflen);
-#else /* COMMENT */
- if (datalen <= 0 || data == NULL || buf == NULL || buflen <= 0)
- return(0);
-
- for (i = 0; i < datalen; i++) {
- ckstrncat((char *)buf,"\r\n ",buflen);
- for (j = 0 ; (j < 16); j++) {
- if ((i + j) < datalen)
- sprintf((char *)tmp,
- "%s%02x ",
- (j == 8 ? "| " : ""),
- (unsigned int) data[i + j]
- );
- else
- sprintf((char *)tmp,
- "%s ",
- (j == 8 ? "| " : "")
- );
- ckstrncat((char *)buf,(char *)tmp,buflen);
- }
- ckstrncat((char *)buf," ",buflen);
- for (k = 0; (k < 16) && ((i + k) < datalen); k++) {
- sprintf((char *)tmp,
- "%s%c",
- (k == 8 ? " " : ""),
- isprint((char)(data[i+k])) ? data[i+k] : '.'
- );
- ckstrncat((char *)buf,(char *)tmp,buflen);
- }
- i += j - 1;
- } /* end for */
- ckstrncat((char *)buf,"\r\n ",buflen);
-#endif /* COMMENT */
- return(strlen((char *)buf));
-}
-
-VOID
-tn_debug(s) char *s; {
-#ifdef NOLOCAL
- return;
-#else /* NOLOCAL */
-#ifdef OS2
- void cwrite(unsigned short);
- char *p = s;
- _PROTOTYP (void os2bold, (void));
- extern int tt_type_mode;
-#endif /* OS2 */
-
- if (!(tn_deb || debses))
- return;
- debug(F111,"tn_debug",s,what);
-#ifdef OS2
- if (1) {
- extern unsigned char colorcmd;
- colorcmd ^= 0x8 ;
- printf("%s\r\n",s);
- colorcmd ^= 0x8 ;
- }
- if (!scrninitialized[VTERM]) {
- USHORT x,y;
- checkscreenmode();
- GetCurPos(&y, &x);
- SaveCmdMode(x+1,y+1);
- scrninit();
- RestoreCmdMode();
- }
-
- if ( ISVTNT(tt_type_mode) && ttnum != -1 && !debses )
- return;
-
- RequestVscrnMutex( VTERM, SEM_INDEFINITE_WAIT ) ;
-
- os2bold(); /* Toggle boldness */
- while (*p)
- cwrite((CHAR) *p++); /* Go boldly ... */
- os2bold(); /* Toggle boldness back */
- if (debses) {
- debses = 0;
- cwrite((CHAR) '\015');
- cwrite((CHAR) '\012');
- debses = 1;
- } else {
- cwrite((CHAR) '\015');
- cwrite((CHAR) '\012');
- }
- ReleaseVscrnMutex(VTERM) ;
-#else
- if (what != W_CONNECT && what != W_DIALING &&
- what != W_COMMAND && what != W_NOTHING)
- return; /* CONNECT/command must be active */
- conoll(s);
-#endif /* OS2 */
-#endif /* NOLOCAL */
-}
-
-/*
- Process in-band Telnet negotiation characters from the remote host.
- Call with the telnet IAC character and the current duplex setting
- (0 = remote echo, 1 = local echo), and a pointer to a function to call
- to read more characters. Returns:
- 6 if DO LOGOUT was received and accepted
- 5 if the Kermit start of packet character has changed
- 4 if state of remote Internet Kermit Service has changed
- 3 if a quoted IAC was received
- 2 if local echo must be changed to remote
- 1 if remote echo must be changed to local
- 0 if nothing happens or no action necessary
- -1 on failure (= internal or i/o error)
-*/
-#ifdef IKS_OPTION
-int
-tn_siks(cmd) int cmd; { /* TELNET SEND IKS SUB */
- CHAR buf[8];
-#ifndef NOXFER
- extern CHAR mystch; /* Outgoing Start of Packet Char */
-#else
- CHAR mystch = '\1';
-#endif /* NOXFER */
- int n,m,rc;
-
- if (ttnet != NET_TCPB) return(0); /* Must be TCP/IP */
- if (ttnproto != NP_TELNET) return(0); /* Must be telnet protocol */
-
- if (cmd < KERMIT_START || cmd > KERMIT_RESP_STOP) /* Illegal subcommand */
- return(-1);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
- if (cmd == KERMIT_START || cmd == KERMIT_RESP_START) {
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 1;
- } else if (cmd == KERMIT_STOP || cmd == KERMIT_RESP_STOP) {
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- } else if (cmd == KERMIT_REQ_STOP)
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop = 1;
- else if (cmd == KERMIT_REQ_START)
- TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start = 1;
-
- if (cmd == KERMIT_SOP) {
- buf[0] = (CHAR) IAC;
- buf[1] = (CHAR) SB;
- buf[2] = (CHAR) TELOPT_KERMIT;
- buf[3] = (CHAR) (cmd & 0xff);
- buf[4] = (CHAR) mystch;
- buf[5] = (CHAR) IAC;
- buf[6] = (CHAR) SE;
- buf[7] = (CHAR) 0;
-#ifdef DEBUG
- if (tn_deb || debses || deblog)
- ckmakmsg( tn_msg_out,TN_MSG_LEN,"TELNET SENT SB KERMIT SOP ",
- ckctox(mystch,1)," IAC SE",NULL);
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F101,tn_msg_out,"",cmd);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = ( ttol(buf,7) < 7 ); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- } else {
- buf[0] = (CHAR) IAC;
- buf[1] = (CHAR) SB;
- buf[2] = (CHAR) TELOPT_KERMIT;
- buf[3] = (CHAR) (cmd & 0xff);
- buf[4] = (CHAR) IAC;
- buf[5] = (CHAR) SE;
- buf[6] = (CHAR) 0;
-
-#ifdef DEBUG
- if (tn_deb || debses || deblog) {
- char * s = 0;
- switch (cmd) {
- case KERMIT_START: s = "START"; break;
- case KERMIT_STOP: s = "STOP"; break;
- case KERMIT_REQ_START: s = "REQ-START"; break;
- case KERMIT_REQ_STOP: s = "REQ-STOP"; break;
- case KERMIT_RESP_START: s = "RESP-START"; break;
- case KERMIT_RESP_STOP: s = "RESP-STOP"; break;
- }
- ckmakmsg( tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB kermit ",s," IAC SE",NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F101,tn_msg_out,"",cmd);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = ( ttol(buf,6) < 6 ); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- }
- return(1);
-}
-#endif /* IKS_OPTION */
-
-/* tn_sb() performs Telnet Subnegotiation Parsing and Debugging */
-/* returns <= 0 on error, 1 on success */
-/* the length returned includes the IAC SE bytes */
-
-int
-#ifdef CK_ANSIC /* TELNET SB */
-tn_sb( int opt, int * len, int (*fn)(int) )
-#else
-tn_sb( opt, len, fn ) int opt; int * len; int (*fn)();
-#endif /* CK_ANSIC */
-/* tn_sb */ {
- int c, x, y, n, m, flag;
- /* if (!IS_TELNET()) return(1); */
-
- debug(F100,"Entering tn_sb()","",0);
- *len = 0; /* Initialize Len to 0 */
- n = flag = 0; /* Flag for when done reading SB */
- while (n < TSBUFSIZ) { /* Loop looking for IAC SE */
- if ((y = (*fn)(0)) < 0) /* Read a byte */
- return(y);
- y &= 0xff; /* Make sure it's just 8 bits. */
- sb[n++] = (char) y; /* Deposit in buffer. */
- if (seslog && sessft == XYFT_D) { /* Take care of session log */
- logchar((char) y);
- }
- if (y == IAC) { /* If this is an IAC */
- if (flag) { /* If previous char was IAC */
- n--; /* it's quoted, keep one IAC */
- flag = 0; /* and turn off the flag. */
- } else flag = 1; /* Otherwise set the flag. */
- } else if (flag) { /* Something else following IAC */
- if (y == SE) /* If not SE, it's a protocol error */
- break;
- else if (y == DONT) { /* Used DONT instead of SE */
- debug(F100,
- "TELNET Subnegotiation error - used DONT instead of SE!",
- ""
- ,0
- );
- if (tn_deb || debses)
- tn_debug(
- "TELNET Subnegotiation error - used DONT instead of SE!");
- flag = 3;
- break;
- } else { /* Other protocol error */
- flag = 0;
- break;
- }
- }
-
-#ifdef CK_FORWARD_X
- if ( opt == TELOPT_FORWARD_X && sb[0] == FWDX_DATA &&
- n >= (TSBUFSIZ-4) && !flag ) {
- /* do not let the buffer over flow */
- /* write the data to the channel and continue processing */
- /* the incoming data until IAC SE is reached. */
- sb[n++] = IAC;
- sb[n++] = SE;
-
-#ifdef DEBUG
- if ( deblog || tn_deb || debses ) {
- int i;
- ckmakmsg( tn_msg,TN_MSG_LEN,
- "TELNET RCVD SB ",TELOPT(opt),
- " DATA(buffer-full) ",NULL);
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&sb[1],n-3);
- if (flag == 2)
- ckstrncat(tn_msg," SE",TN_MSG_LEN);
- else if (flag == 3)
- ckstrncat(tn_msg," IAC DONT",TN_MSG_LEN);
- else
- ckstrncat(tn_msg," IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses)
- tn_debug(tn_msg);
- }
-#endif /* DEBUG */
-
- if ( fwdx_tn_sb(sb,n) < 0 ) {
- debug(F100,"fxdx_tn_sb() failed","",0);
- /* We can't return though because that would leave */
- /* data to be forwarded in the queue to the be sent */
- /* to the terminal emulator. */
- }
- /* reset leave the msg type and channel number in place */
- n = 3;
- }
-#endif /* CK_FORWARD_X */
- }
- debug(F111,"tn_sb end of while loop","flag",flag);
- if (!flag) { /* Make sure we got a valid SB */
- debug(F111, "TELNET Subnegotiation prematurely broken","opt",opt);
- if (tn_deb || debses) {
- ckmakmsg( tn_msg, TN_MSG_LEN,
- "TELNET ", TELOPT(opt),
- " Subnegotiation prematurely broken",NULL
- );
-
- tn_debug(tn_msg);
- }
- /* Was -1 but that would be an I/O error, so absorb it and go on. */
- return(0);
- }
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- int i;
- char * s[16];
- for (i = 0; i < 16; i++)
- s[i] = "";
- if (opt == TELOPT_NAWS) {
- i = 0;
- } else {
- i = 1;
- s[0] = "UNKNOWN";
-
- switch (sb[0]) {
- case 0:
- if (opt == TELOPT_FORWARD_X)
- s[0] = "SCREEN";
- else if (opt == TELOPT_KERMIT)
- s[0] = "START";
- else if (opt == TELOPT_LFLOW)
- s[0] = "OFF";
- else if (opt == TELOPT_COMPORT)
- s[0] = "SIGNATURE";
- else
- s[0] = "IS";
- if (opt == TELOPT_ENCRYPTION) {
- i++;
- if (sb[1] < ENCTYPE_CNT) {
- s[1] = enctype_names[sb[1]];
- i++;
- switch(sb[2]) {
- case 1:
- s[2] = "FB64_IV";
- break;
- case 2:
- s[2] = "FB64_IV_OK";
- break;
- case 3:
- s[2] = "FB64_IV_BAD";
- break;
- case 4:
- s[2] = "FB64_CHALLENGE";
- break;
- case 5:
- s[2] = "FB64_RESPONSE";
- break;
- }
- } else {
- s[1] = "UNKNOWN";
- }
- }
- if (opt == TELOPT_AUTHENTICATION) {
- i += 2;
- s[1] = AUTHTYPE_NAME(sb[1]);
- s[2] = AUTHMODE_NAME(sb[2]);
- if (sb[1]) {
- i++;
- switch (sb[3]) {
- case 0:
- switch (sb[1]) {
- case AUTHTYPE_NTLM:
- s[3] = "NTLM_AUTH";
- break;
- default:
- s[3] = "AUTH";
- }
- break;
- case 1:
- switch (sb[1]) {
- case AUTHTYPE_SSL:
- s[3] = "START";
- break;
- case AUTHTYPE_NTLM:
- s[3] = "NTLM_CHALLENGE";
- break;
- default:
- s[3] = "REJECT";
- }
- break;
- case 2:
- switch (sb[1]) {
- case AUTHTYPE_NTLM:
- s[3] = "NTLM_RESPONSE";
- break;
- default:
- s[3] = "ACCEPT";
- }
- break;
- case 3:
- switch (sb[1]) {
- case AUTHTYPE_NTLM:
- s[3] = "NTLM_ACCEPT";
- break;
- case 1: /* KERBEROS_v4 */
- case 5: /* SRP */
- s[3] = "CHALLENGE";
- break;
- case 2: /* KERBEROS_v5 */
- s[3] = "RESPONSE";
- break;
- case AUTHTYPE_SSL:
- s[3] = "REJECT";
- break;
- }
- break;
- case 4:
- switch (sb[1]) {
- case AUTHTYPE_NTLM:
- s[3] = "NTLM_REJECT";
- break;
- case 1: /* KERBEROS_V4 */
- case 5: /* SRP */
- s[3] = "RESPONSE";
- break;
- case 2: /* KERBEROS_V5 */
- s[3] = "FORWARD";
- break;
- }
- break;
- case 5:
- switch (sb[1]) {
- case 5: /* SRP */
- s[3] = "FORWARD";
- break;
- case 2: /* KERBEROS_V5 */
- s[3] = "FORWARD_ACCEPT";
- break;
- }
- break;
- case 6:
- switch (sb[1]) {
- case 5: /* SRP */
- s[3] = "FORWARD_ACCEPT";
- break;
- case 2: /* KERBEROS_V5 */
- s[3] = "FORWARD_REJECT";
- break;
- }
- break;
- case 7:
- switch (sb[1]) {
- case 5: /* SRP */
- s[3] = "FORWARD_REJECT";
- break;
- case 2: /* KERBEROS_V5 */
- s[3] = "TLS_VERIFY";
- break;
- }
- break;
- case 8:
- switch (sb[1]) {
- case 5: /* SRP */
- s[3] = "EXP";
- break;
- }
- break;
- case 9:
- switch (sb[1]) {
- case 5: /* SRP */
- s[3] = "PARAMS";
- break;
- }
- break;
- }
- }
- }
- break;
- case 1:
- switch (opt) {
- case TELOPT_FORWARD_X:
- s[0] = "OPEN";
- break;
- case TELOPT_LFLOW:
- s[0] = "ON";
- break;
- case TELOPT_KERMIT:
- s[0] = "STOP";
- break;
- case TELOPT_COMPORT:
- s[0] = "SET-BAUDRATE";
- break;
- case TELOPT_AUTHENTICATION:
- s[0] = "SEND";
- hexbuf[0] = '\0';
- for (; i < n-2; i += 2) {
- if ( AUTHTYPE_NAME_OK(sb[i]) &&
- AUTHMODE_NAME_OK(sb[i]))
- ckmakmsg( tn_msg, TN_MSG_LEN,
- AUTHTYPE_NAME(sb[i])," ",
- AUTHMODE_NAME(sb[i+1])," "
- );
- else
- ckmakxmsg(tn_msg, TN_MSG_LEN,
- AUTHTYPE_NAME(sb[i]),
- "=",
- ckitoa(sb[i]),
- " ",
- AUTHMODE_NAME(sb[i+1]),
- "=",
- ckitoa(sb[i+1]),
- " ",
- NULL,NULL,NULL,NULL
- );
- ckstrncat(hexbuf,tn_msg,sizeof(hexbuf));
- }
- s[1] = hexbuf;
- break;
-
- case TELOPT_ENCRYPTION:
- s[0] = "SUPPORT";
- while (i < n-2) {
- s[i] = enctype_names[sb[i]];
- i++;
- }
- break;
-
- case TELOPT_START_TLS:
- s[0] = "FOLLOWS";
- break;
- default:
- s[0] = "SEND";
- }
- break;
-
- case 2:
- switch (opt) {
- case TELOPT_FORWARD_X:
- s[0] = "CLOSE";
- break;
- case TELOPT_LFLOW:
- s[0] = "RESTART-ANY";
- break;
- case TELOPT_KERMIT:
- s[0] = "REQ-START";
- break;
- case TELOPT_COMPORT:
- s[0] = "SET-DATASIZE";
- break;
- case TELOPT_NEWENVIRON:
- s[0] = "INFO";
- break;
- case TELOPT_AUTHENTICATION:
- s[0] = "REPLY";
- i=4;
- s[1] = AUTHTYPE_NAME(sb[1]);
- s[2] = AUTHMODE_NAME(sb[2]);
- switch (sb[3]) {
- case 0:
- switch (sb[1]) {
- case AUTHTYPE_NTLM:
- s[3] = "NTLM_AUTH";
- break;
- default:
- s[3] = "AUTH";
- }
- break;
- case 1:
- switch (sb[1]) {
- case AUTHTYPE_NTLM:
- s[3] = "NTLM_CHALLENGE";
- break;
- default:
- s[3] = "REJECT";
- }
- break;
- case 2:
- switch (sb[1]) {
- case AUTHTYPE_NTLM:
- s[3] = "NTLM_RESPONSE";
- break;
- default:
- s[3] = "ACCEPT";
- }
- break;
- case 3:
- switch (sb[1]) {
- case AUTHTYPE_NTLM:
- s[3] = "NTLM_ACCEPT";
- break;
- case AUTHTYPE_KERBEROS_V4:
- case AUTHTYPE_SRP:
- s[3] = "CHALLENGE";
- break;
- case AUTHTYPE_KERBEROS_V5:
- s[3] = "RESPONSE";
- break;
- }
- break;
- case 4:
- switch (sb[1]) {
- case AUTHTYPE_NTLM:
- s[3] = "NTLM_REJECT";
- break;
- case AUTHTYPE_KERBEROS_V4:
- case AUTHTYPE_SRP:
- s[3] = "RESPONSE";
- break;
- case AUTHTYPE_KERBEROS_V5:
- s[3] = "FORWARD";
- break;
- }
- break;
- case 5:
- switch (sb[1]) {
- case AUTHTYPE_SRP:
- s[3] = "FORWARD";
- break;
- case AUTHTYPE_KERBEROS_V5:
- s[3] = "FORWARD_ACCEPT";
- break;
- }
- break;
- case 6:
- switch (sb[1]) {
- case AUTHTYPE_SRP:
- s[3] = "FORWARD_ACCEPT";
- break;
- case AUTHTYPE_KERBEROS_V5:
- s[3] = "FORWARD_REJECT";
- break;
- }
- break;
- case 7:
- switch (sb[1]) {
- case AUTHTYPE_SRP:
- s[3] = "FORWARD_REJECT";
- break;
- case AUTHTYPE_KERBEROS_V5:
- s[3] = "TLS_VERIFY";
- break;
- }
- break;
- case 8:
- switch (sb[1]) {
- case AUTHTYPE_SRP:
- s[3] = "EXP";
- break;
- }
- break;
- case 9:
- switch (sb[1]) {
- case AUTHTYPE_SRP:
- s[3] = "PARAMS";
- break;
- }
- break;
- }
- break;
- case TELOPT_ENCRYPTION:
- s[0] = "REPLY";
- s[1] = enctype_names[sb[1]];
- i++;
- switch (sb[2]) {
- case 1:
- i++;
- s[2] = "FB64_IV";
- break;
- case 2:
- i++;
- s[2] = "FB64_IV_OK";
- break;
- case 3:
- i++;
- s[2] = "FB64_IV_BAD";
- break;
- case 4:
- i++;
- s[2] = "FB64_CHALLENGE";
- break;
- case 5:
- i++;
- s[2] = "FB64_RESPONSE";
- break;
- }
- break;
- }
- break;
- case 3:
- switch (opt) {
- case TELOPT_FORWARD_X:
- s[0] = "DATA";
- break;
- case TELOPT_LFLOW:
- s[0] = "RESTART-XON";
- break;
- case TELOPT_KERMIT:
- s[0] = "REQ-STOP";
- break;
- case TELOPT_COMPORT:
- s[0] = "SET-PARITY";
- break;
- case TELOPT_AUTHENTICATION:
- s[0] = "NAME";
- break;
- case TELOPT_ENCRYPTION:
- s[0] = "START";
- break;
- }
- break;
- case 4:
- switch (opt) {
- case TELOPT_FORWARD_X:
- s[0] = "OPTIONS";
- break;
- case TELOPT_KERMIT:
- s[0] = "SOP";
- break;
- case TELOPT_COMPORT:
- s[0] = "SET-STOPSIZE";
- break;
- case TELOPT_ENCRYPTION:
- s[0] = "END";
- break;
- }
- break;
- case 5:
- switch (opt) {
- case TELOPT_FORWARD_X:
- s[0] = "OPTION_DATA";
- break;
- case TELOPT_ENCRYPTION:
- s[0] = "REQUEST-START";
- break;
- case TELOPT_COMPORT:
- s[0] = "SET-CONTROL";
- break;
- }
- break;
- case 6:
- switch (opt) {
- case TELOPT_FORWARD_X:
- s[0] = "XOFF";
- break;
- case TELOPT_ENCRYPTION:
- s[0] = "REQUEST-END";
- break;
- case TELOPT_COMPORT:
- s[0] = "NOTIFY-LINESTATE";
- break;
- }
- break;
- case 7:
- switch (opt) {
- case TELOPT_FORWARD_X:
- s[0] = "XON";
- break;
- case TELOPT_ENCRYPTION:
- s[0] = "ENC-KEYID";
- break;
- case TELOPT_COMPORT:
- s[0] = "NOTIFY-MODEMSTATE";
- break;
- }
- break;
- case 8:
- switch (opt) {
- case TELOPT_KERMIT:
- s[0] = "RESP-START";
- break;
- case TELOPT_ENCRYPTION:
- s[0] = "DEC-KEYID";
- break;
- case TELOPT_COMPORT:
- s[0] = "FLOWCONTROL-SUSPEND";
- break;
- }
- break;
- case 9:
- switch (opt) {
- case TELOPT_KERMIT:
- s[0] = "RESP-STOP";
- break;
- case TELOPT_COMPORT:
- s[0] = "FLOWCONTROL-RESUME";
- break;
- }
- break;
- case 10:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "SET-LINESTATE-MASK";
- break;
- }
- break;
- case 11:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "SET-MODEMSTATE-MASK";
- break;
- }
- break;
- case 12:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "PURGE-DATA";
- break;
- }
- break;
-
-
- case 100:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_SIGNATURE";
- break;
- }
- break;
- case 101:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_SET-BAUDRATE";
- break;
- }
- break;
- case 102:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_SET-DATASIZE";
- break;
- }
- break;
- case 103:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_SET-PARITY";
- break;
- }
- break;
- case 104:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_SET-STOPSIZE";
- break;
- }
- break;
- case 105:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_SET-CONTROL";
- break;
- }
- break;
- case 106:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_NOTIFY-LINESTATE";
- break;
- }
- break;
- case 107:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_NOTIFY-MODEMSTATE";
- break;
- }
- break;
- case 108:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_FLOWCONTROL-SUSPEND";
- break;
- }
- break;
- case 109:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_FLOWCONTROL-RESUME";
- break;
- }
- break;
- case 110:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_SET-LINESTATE-MASK";
- break;
- }
- break;
- case 111:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_SET-MODEMSTATE-MASK";
- break;
- }
- break;
- case 112:
- switch (opt) {
- case TELOPT_COMPORT:
- s[0] = "S_PURGE-DATA";
- break;
- }
- break;
- }
- }
-#ifdef M_XENIX
- {
- int len, param, param_len;
- ckmakmsg( tn_msg, TN_MSG_LEN,
- "TELNET RCVD SB ",
- TELOPT(opt)," ",NULL);
- len = strlen(tn_msg);
- for (param = 0; param <= 15; param++) {
- param_len = strlen(s[param]);
- if (param_len > 0) {
- strcpy(&tn_msg[len], s[param]);
- len += param_len;
- tn_msg[len++] = ' ';
- }
- }
- tn_msg[len] = '\0';
- }
-#else /* M_XENIX */
- ckmakxmsg(tn_msg,TN_MSG_LEN,"TELNET RCVD SB ",TELOPT(opt)," ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- {
- int i;
- for (i = 0; i < 16; i++) {
- if (s[i][0]) {
- ckstrncat(tn_msg,s[i],TN_MSG_LEN);
- ckstrncat(tn_msg," ",TN_MSG_LEN);
- }
- }
- }
-#endif /* M_XENIX */
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&sb[i],n-2-i);
- if (flag == 2)
- ckstrncat(tn_msg," SE",TN_MSG_LEN);
- else if (flag == 3)
- ckstrncat(tn_msg," IAC DONT",TN_MSG_LEN);
- else
- ckstrncat(tn_msg," IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses)
- tn_debug(tn_msg);
- }
- debug(F111,"tn_sb","len",n);
-#endif /* DEBUG */
- *len = n; /* return length */
- return(1); /* success */
-}
-
-static char rows_buf[16] = { 0, 0 }; /* LINES Environment variable */
-static char cols_buf[16] = { 0, 0 }; /* COLUMNS Enviornment variable */
-static char term_buf[64] = { 0, 0 }; /* TERM Environment variable */
-
-#ifdef CK_CURSES
-#ifndef VMS
-#ifndef COHERENT
-_PROTOTYP(int tgetent,(char *, char *));
-#endif /* COHERENT */
-#else
-#ifdef __DECC
-_PROTOTYP(int tgetent,(char *, char *));
-#endif /* __DECC */
-#endif /* VMS */
-extern char * trmbuf; /* Real curses */
-#endif /* CK_CURSES */
-
-#ifdef CK_ENCRYPTION
-static int
-tn_no_encrypt()
-{
- /* Prevent Encryption from being negotiated */
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
-
- /* Cancel any negotiation that might have started */
- ck_tn_enc_stop();
-
- if (TELOPT_ME(TELOPT_ENCRYPTION) ||
- TELOPT_UNANSWERED_WILL(TELOPT_ENCRYPTION)) {
- TELOPT_ME(TELOPT_ENCRYPTION) = 0;
- if (tn_sopt(WONT,TELOPT_ENCRYPTION) < 0)
- return(-1);
- TELOPT_UNANSWERED_WONT(TELOPT_ENCRYPTION) = 1;
- }
- if (TELOPT_U(TELOPT_ENCRYPTION) ||
- TELOPT_UNANSWERED_DO(TELOPT_ENCRYPTION)) {
- TELOPT_U(TELOPT_ENCRYPTION) = 0;
- if (tn_sopt(DONT,TELOPT_ENCRYPTION) < 0)
- return(-1);
- TELOPT_UNANSWERED_DONT(TELOPT_ENCRYPTION) = 1;
- }
- return(0);
-}
-#endif /* CK_ENCRYPTION */
-
-/* The following note came from the old SGA negotiation code. This should */
-/* no longer be necessary with the New Telnet negotiation state machine. */
-/*
- Note: The following is proper behavior, and required for talking to the
- Apertus interface to the NOTIS library system, e.g. at Iowa State U:
- scholar.iastate.edu. Without this reply, the server hangs forever. This
- code should not be loop-inducing, since C-Kermit never sends WILL SGA as
- an initial bid, so if DO SGA comes, it is never an ACK.
-*/
-/*
- Return values:
- -1 = Telnet Option negotiation error
- -2 = Connection closed by peer
- -3 = Connection closed by us
- 0 = Success
- 1 = Echoing on
- 2 = Echoing off
- 3 = Quoted IAC
- 4 = IKS Event
- 5 = (unassigned)
- 6 = Logout
-*/
-
-static int
-#ifdef CK_ANSIC /* TELNET DO OPTION */
-tn_xdoop(CHAR z, int echo, int (*fn)(int))
-#else
-tn_xdoop(z, echo, fn) CHAR z; int echo; int (*fn)();
-#endif /* CK_ANSIC */
-/* tn_xdoop */ {
- int c, x, y, n, m;
-#ifdef IKS_OPTION
- extern int server;
-#ifdef NOICP
- extern int autodl;
- int inautodl = 0, cmdadl = 1;
-#else
-#ifdef CK_AUTODL
- extern int autodl, inautodl, cmdadl;
-#endif /* CK_AUTODL */
-#endif /* NOICP */
-#endif /* IKS_OPTION */
-
- /* if (!IS_TELNET()) return(7); */
-
-/* Have IAC, read command character. */
-
- while ((c = (*fn)(0)) == -1); /* Read command character */
- if (c < 0)
- return(c);
- c &= 0xFF; /* Strip high bits */
-
- if (!TELCMD_OK(c)) {
-#ifdef DEBUG
- if (tn_deb || debses || deblog) {
- ckmakmsg(tn_msg,TN_MSG_LEN,"TELNET RCVD UNKNOWN (",
- ckitoa(c),")",NULL);
- debug(F101,tn_msg,"",c);
- if (tn_deb || debses)
- tn_debug(tn_msg);
- }
-#endif /* DEBUG */
- return(0);
- }
- if (ttnproto == NP_NONE) {
- debug(F100,"tn_doop discovered a Telnet command",
- "ttnproto = NP_TELNET",0);
- ttnproto = NP_TELNET;
- }
- if (seslog && sessft == XYFT_D) { /* Copy to session log, if any. */
- logchar((char)z);
- logchar((char)c);
- }
-
- if (c == (CHAR) IAC) /* Quoted IAC */
- return(3);
-
- if (c < SB) { /* Other command with no arguments. */
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakmsg(tn_msg,TN_MSG_LEN,"TELNET RCVD ",TELCMD(c),NULL,NULL);
- debug(F101,tn_msg,"",c);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#endif /* DEBUG */
- switch (c) { /* What we would like to do here */
- case TN_GA: /* Is substitute ASCII characters */
- break; /* for the Telnet Command so that */
- case TN_EL: /* the command may be processed by */
- break; /* either the internal emulator or */
- case TN_EC: /* by the superior process or shell */
- break;
- case TN_AYT:
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol((CHAR *)"[Yes]\015\012",7);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- break;
- case TN_AO:
-#ifdef BETADEBUG
- bleep(BP_NOTE);
-#endif /* BETADEBUG */
- break;
- case TN_IP:
- break;
- case BREAK:
- break;
- case TN_DM:
- break;
- case TN_NOP:
- break;
- case SE:
- break;
- case TN_EOR:
- break;
- case TN_ABORT:
- break;
- case TN_SUSP:
- break;
- case TN_EOF:
- break;
- case TN_SAK:
- break;
- }
- return(0);
- }
-
-/* SB, WILL, WONT, DO, or DONT need more bytes... */
-
- if ((x = (*fn)(0)) < 0) /* Get the option. */
- return(x);
- x &= 0xff; /* Trim to 8 bits. */
-
- if (seslog && sessft == XYFT_D) { /* Session log */
- logchar((char) x);
- }
-#ifdef DEBUG
- if ((deblog || tn_deb || debses) && c != SB) {
- ckmakmsg(tn_msg,TN_MSG_LEN,"TELNET RCVD ",TELCMD(c)," ",TELOPT(x));
- debug(F101,tn_msg,"",x);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#endif /* DEBUG */
- /* Now handle the command */
- switch (c) {
- case WILL:
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return(0);
-#endif /* CK_SSL */
-#ifdef CK_FORWARD_X
- if (x == TELOPT_FORWARD_X) {
- if (!fwdx_server_avail() || !(fwdx_no_encrypt ||
-#ifdef CK_SSL
- (ssl_active_flag || tls_active_flag)
-#else /* CK_SSL */
- 0
-#endif /* CK_SSL */
- ||
-#ifdef CK_ENCRYPTION
- (ck_tn_encrypting() && ck_tn_decrypting())
-#else /* CK_ENCRYPTION */
- 0
-#endif /* CK_ENCRYPTION */
- )) {
- TELOPT_U_MODE(TELOPT_FORWARD_X) = TN_NG_RF;
- TELOPT_ME_MODE(TELOPT_FORWARD_X) = TN_NG_RF;
- }
- }
-#endif /* CK_FORWARD_X */
- if (!TELOPT_OK(x) || TELOPT_U_MODE(x) == TN_NG_RF) {
- if (tn_sopt(DONT,x) < 0)
- return(-1);
- if (TELOPT_UNANSWERED_DO(x))
- TELOPT_UNANSWERED_DO(x) = 0;
- } else if (!TELOPT_U(x)) {
- if (!TELOPT_UNANSWERED_DO(x)) {
- if (tn_sopt(DO,x) < 0)
- return -1;
- }
- if (TELOPT_UNANSWERED_DO(x))
- TELOPT_UNANSWERED_DO(x) = 0;
- TELOPT_U(x) = 1;
-
- switch (x) {
-#ifdef CK_SSL
- case TELOPT_START_TLS:
- /*
- If my proposal is accepted, at this point the Telnet
- protocol is turned off and a TLS negotiation takes
- place.
-
- Start by sending SB START_TLS FOLLOWS to signal
- we are ready. Wait for the peer to send the same
- and then start the TLS negotiation.
-
- If the TLS negotiation succeeds we call tn_ini()
- again to reset the telnet state machine and restart
- the negotiation process over the now secure link.
-
- If the TLS negotiation fails, we call ttclos()
- to terminate the connection.
-
- Only the server should receive a WILL START_TLS
- */
- tn_ssbopt(TELOPT_START_TLS,1,NULL,0);
- TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows = 1;
- break;
-#endif /* CK_SSL */
-
-#ifdef CK_AUTHENTICATION
- case TELOPT_AUTHENTICATION: {
- /* We now have to perform a SB SEND to identify the */
- /* supported authentication types to the other side. */
- extern int authentication_version;
-
-#ifdef CK_SSL
- /* if we have an outstanding DO START_TLS then we must
- * wait for the response before we determine what to do
- */
- if (TELOPT_UNANSWERED_DO(TELOPT_START_TLS)) {
- TELOPT_SB(TELOPT_START_TLS).start_tls.auth_request = 1;
- break;
- }
-#endif /* CK_SSL */
- authentication_version = AUTHTYPE_AUTO;
- ck_tn_auth_request();
- break;
- }
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
- case TELOPT_ENCRYPTION:
- if (!(TELOPT_ME(TELOPT_AUTHENTICATION) ||
- TELOPT_U(TELOPT_AUTHENTICATION))
- ) {
- if (tn_sopt(DONT,x) < 0)
- return(-1);
- TELOPT_U(x) = 0;
- } else {
- if (ck_tn_auth_in_progress()) {
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.need_to_send = 1;
- } else {
- /* Perform subnegotiation */
- ck_encrypt_send_support();
- }
- if (!(TELOPT_ME(x) || TELOPT_UNANSWERED_WILL(x))
- && TELOPT_ME_MODE(x) != TN_NG_RF) {
- if (tn_sopt(WILL, x) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(x) = 1;
- }
- }
- break;
-#endif /* CK_ENCRYPTION */
-#ifdef IKS_OPTION
- case TELOPT_KERMIT:
- if (!TELOPT_ME(x)) {
- /* Tell the other side what Start of Packet Character */
- tn_siks(KERMIT_SOP); /* SOP */
-
- if (!TELOPT_UNANSWERED_WILL(x) &&
- TELOPT_ME_MODE(x) != TN_NG_RF) {
- if (tn_sopt(WILL, x) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(x) = 1;
- }
- }
- break;
-#endif /* IKS_OPTION */
- case TELOPT_BINARY:
- if (!TELOPT_ME(x)) {
- if (!TELOPT_UNANSWERED_WILL(x) &&
- TELOPT_ME_MODE(x) >= TN_NG_RQ) {
- if (tn_sopt(WILL, x) < 0)
- return(-1);
- TELOPT_UNANSWERED_WILL(x) = 1;
- }
- }
- break;
- case TELOPT_ECHO:
- if (echo) {
- if (TELOPT_UNANSWERED_DO(x))
- TELOPT_UNANSWERED_DO(x) = 0;
- return(2);
- }
- break;
- case TELOPT_TTYPE:
- /* SB TTYPE SEND */
- tn_ssbopt(TELOPT_TTYPE,TELQUAL_SEND,NULL,0);
- TELOPT_UNANSWERED_SB(TELOPT_TTYPE)=1;
- break;
-#ifdef CK_ENVIRONMENT
- case TELOPT_NEWENVIRON: /* SB NEW-ENVIRON SEND */
- {
- char request[6]; /* request it */
- sprintf(request,"%cUSER",TEL_ENV_VAR); /* safe */
- tn_ssbopt(TELOPT_NEWENVIRON,TELQUAL_SEND,request,
- strlen(request));
- TELOPT_UNANSWERED_SB(TELOPT_NEWENVIRON)=1;
- }
- break;
-#endif /* CK_ENVIRONMENT */
- } /* switch */
- } else {
- if (TELOPT_UNANSWERED_DO(x))
- TELOPT_UNANSWERED_DO(x) = 0;
- }
- break;
- case WONT:
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return(0);
-#endif /* CK_SSL */
- if (TELOPT_U(x) || TELOPT_UNANSWERED_DO(x)) {
- /* David Borman says we should not respond DONT when
- * the WONT is a response to a DO that we sent.
- * Nor should we send one if the state is already WONT
- * such as when we do not recognize the option since
- * options are initialized in the WONT/DONT state.
- */
- if (!(TELOPT_UNANSWERED_DO(x) || TELOPT_UNANSWERED_DONT(x)))
- if (tn_sopt(DONT,x) < 0)
- return(-1);
- if (TELOPT_UNANSWERED_DONT(x))
- TELOPT_UNANSWERED_DONT(x) = 0;
- if (TELOPT_UNANSWERED_DO(x))
- TELOPT_UNANSWERED_DO(x) = 0;
- if (TELOPT_U(x)) {
- TELOPT_U(x) = 0;
- }
- switch(x) {
-#ifdef CK_SSL
- case TELOPT_START_TLS:
- if (sstelnet) {
- if (TELOPT_U_MODE(x) == TN_NG_MU) {
- printf("Telnet Start-TLS refused.\n");
- ttclos(0);
- whyclosed = WC_TELOPT;
- return(-3);
- }
- if (TELOPT_SB(x).start_tls.auth_request) {
- extern int authentication_version;
- TELOPT_SB(x).start_tls.auth_request = 0;
- authentication_version = AUTHTYPE_AUTO;
- ck_tn_auth_request();
- }
- }
- break;
-#endif /* CK_SSL */
-#ifdef CK_AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- if (sstelnet && TELOPT_U_MODE(x) == TN_NG_MU) {
- printf("Telnet authentication refused.\n");
- ttclos(0);
- whyclosed = WC_TELOPT;
- return(-3);
- } else if (TELOPT_U_MODE(x) == TN_NG_RQ) {
- TELOPT_U_MODE(x) = TN_NG_AC;
- }
- if (ck_tn_auth_in_progress())
- printf("Telnet authentication refused.\n");
-#ifdef CK_ENCRYPTION
- if (sstelnet) {
- if (tn_no_encrypt()<0)
- return(-1);
- }
-#endif /* CK_ENCRYPTION */
- break;
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
- case TELOPT_ENCRYPTION:
- ck_tn_enc_stop();
- break;
-#endif /* CK_ENCRYPTION */
-#ifdef IKS_OPTION
- case TELOPT_KERMIT:
- TELOPT_SB(x).kermit.u_start = 0;
- TELOPT_SB(x).kermit.me_req_start = 0;
- TELOPT_SB(x).kermit.me_req_stop = 0;
- break;
-#endif /* IKS_OPTION */
- case TELOPT_NAWS: {
- /* The client does not support NAWS. */
- /* Assume a height of 24 and a width of 80 */
- if (sstelnet
-#ifdef IKSD
- || inserver
-#endif /* IKSD */
- ) {
- int w = 80, h = 24;
-#ifndef NOLOCAL
- if (tcp_incoming) {
-#ifdef OS2
- tt_cols[VTERM] = w;
- tt_rows[VTERM] = h;
- VscrnSetWidth(VTERM, w);
- VscrnSetHeight(VTERM, h+(tt_status[VTERM]?1:0));
-#else /* OS2 */
- tt_cols = w;
- tt_rows = h;
-#endif /* OS2 */
- } else {
-#ifdef OS2
- tt_cols[VCMD] = w;
- tt_rows[VCMD] = h;
- VscrnSetWidth(VCMD, w);
- VscrnSetHeight(VCMD, h);
-#endif /* OS2 */
- cmd_cols = w;
- cmd_rows = h;
- }
-#else /* NOLOCAL */
- cmd_cols = w;
- cmd_rows = h;
-#endif /* NOLOCAL */
- /* Add LINES and COLUMNS to the environment */
- ckmakmsg((char *)rows_buf,16,"LINES=",ckitoa(h),
- NULL,NULL);
- ckmakmsg((char *)cols_buf,16,"COLUMNS=",ckitoa(w),
- NULL,NULL);
-#ifdef OS2ORUNIX
-#ifndef NOPUTENV
- putenv(rows_buf);
- putenv(cols_buf);
-#endif /* NOPUTENV */
-#endif /* OS2ORUNIX */
- }
- break;
- }
- case TELOPT_ECHO:
- if (!echo) {
- if (TELOPT_UNANSWERED_DO(x))
- TELOPT_UNANSWERED_DO(x) = 0;
- return(1);
- }
- break;
- }
- } else {
- if (TELOPT_UNANSWERED_DONT(x))
- TELOPT_UNANSWERED_DONT(x) = 0;
- if (TELOPT_UNANSWERED_DO(x))
- TELOPT_UNANSWERED_DO(x) = 0;
- }
- if (TELOPT_U_MODE(x) == TN_NG_MU) {
- ckmakmsg( tn_msg,TN_MSG_LEN,
- "Peer refuses TELNET DO ",TELOPT(x),
- " negotiations - terminating connection",NULL
- );
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- printf("%s\n",tn_msg);
- ttclos(0);
- whyclosed = WC_TELOPT;
- return(-3);
- }
-#ifdef COMMENT
- if (x == TELOPT_ECHO && !echo) /* Special handling for echo */
- return(1); /* because we allow 'duplex' */
-#endif /* COMMENT */
- break;
-
- case DO:
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return(0);
-#endif /* CK_SSL */
- if (!TELOPT_OK(x) || TELOPT_ME_MODE(x) == TN_NG_RF) {
- if (tn_sopt(WONT,x) < 0)
- return(-1);
- if (TELOPT_UNANSWERED_WILL(x))
- TELOPT_UNANSWERED_WILL(x) = 0;
- } else if (!TELOPT_ME(x)) {
- if (!TELOPT_UNANSWERED_WILL(x)) {
- if (tn_sopt(WILL,x) < 0)
- return(-1);
- }
- if (TELOPT_UNANSWERED_WILL(x))
- TELOPT_UNANSWERED_WILL(x) = 0;
- TELOPT_ME(x) = 1;
-
- switch (x) {
-#ifdef CK_SSL
- case TELOPT_START_TLS:
- /*
- If my proposal is accepted at this point the Telnet
- protocol is turned off and a TLS negotiation takes
- place.
-
- Start by sending SB START_TLS FOLLOWS to signal
- we are ready. Wait for the peer to send the same
- and then start the TLS negotiation.
-
- If the TLS negotiation succeeds we call tn_ini()
- again to reset the telnet state machine and restart
- the negotiation process over the now secure link.
-
- If the TLS negotiation fails, we call ttclos()
- to terminate the connection. Then we set the
- U_MODE and ME_MODE for TELOPT_START_TLS to REFUSE
- and then call ttopen() to create a new connection
- to the same host but this time do not attempt
- TLS security.
-
- Only the client should receive DO START_TLS.
- */
- tn_ssbopt(TELOPT_START_TLS,1,NULL,0);
- TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows = 1;
- break;
-#endif /* CK_SSL */
-
-#ifdef CK_AUTHENTICATION
- case TELOPT_AUTHENTICATION: {
- /* We don't know what authentication we are using yet */
- /* but it is not NULL until a failure is detected so */
- /* use AUTO in the meantime. */
- extern int authentication_version;
- authentication_version = AUTHTYPE_AUTO;
- break;
- }
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
- case TELOPT_ENCRYPTION:
- if (!(TELOPT_ME(TELOPT_AUTHENTICATION) ||
- TELOPT_U(TELOPT_AUTHENTICATION))
- ) {
- if (tn_sopt(WONT,x) < 0)
- return(-1);
- TELOPT_ME(x) = 0;
- } else {
- if (!(TELOPT_U(x) || TELOPT_UNANSWERED_DO(x))
- && TELOPT_U_MODE(x) != TN_NG_RF) {
- if (tn_sopt(DO, x) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(x) = 1;
- }
- }
- break;
-#endif /* CK_ENCRYPTION */
-#ifdef IKS_OPTION
- case TELOPT_KERMIT:
-/* If currently processing Kermit server packets, must tell the other side */
-
- debug(F111,"tn_doop","what",what);
- debug(F111,"tn_doop","server",server);
-#ifdef CK_AUTODL
- debug(F111,"tn_doop","autodl",autodl);
- debug(F111,"tn_doop","inautodl",inautodl);
- debug(F111,"tn_doop","cmdadl",cmdadl);
-#endif /* CK_AUTODL */
-
- if (server
-#ifdef CK_AUTODL
- || (local && ((what == W_CONNECT && autodl) ||
- (what != W_CONNECT && inautodl)))
- || (!local && cmdadl)
-#endif /* CK_AUTODL */
- ) {
- tn_siks(KERMIT_START); /* START */
- }
- if (!TELOPT_U(x)) {
- /* Tell the other side what Start of Packet Character */
- tn_siks(KERMIT_SOP); /* SOP */
- if (!TELOPT_UNANSWERED_DO(x) &&
- TELOPT_U_MODE(x) != TN_NG_RF) {
- if (tn_sopt(DO, x) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(x) = 1;
- }
- }
- break;
-#endif /* IKS_OPTION */
-
- case TELOPT_BINARY:
- if (!TELOPT_U(x)) {
- if (!TELOPT_UNANSWERED_DO(x) &&
- TELOPT_U_MODE(x) >= TN_NG_RQ) {
- if (tn_sopt(DO, x) < 0)
- return(-1);
- TELOPT_UNANSWERED_DO(x) = 1;
- }
- }
- break;
- case TELOPT_NAWS:
-#ifdef CK_NAWS
- if ( !tn_delay_sb || !tn_outst(0) || tn_init ) {
- if (tn_snaws() < 0)
- return(-1);
- } else {
- TELOPT_SB(TELOPT_NAWS).naws.need_to_send = 1;
- }
-#endif /* CK_NAWS */
- break;
- case TELOPT_LOGOUT:
- ttclos(0); /* And then hangup */
- whyclosed = WC_TELOPT;
- return(6);
-#ifdef CK_SNDLOC
- case TELOPT_SNDLOC:
- if ( !tn_delay_sb || !tn_outst(0) || tn_init ) {
- if (tn_sndloc() < 0)
- return(-1);
- } else {
- TELOPT_SB(TELOPT_SNDLOC).sndloc.need_to_send = 1;
- }
- break;
-#endif /* CK_SNDLOC */
-#ifdef CK_FORWARD_X
- case TELOPT_FORWARD_X:
- if ( !tn_delay_sb || !tn_outst(0) || tn_init ) {
- if (fwdx_send_options() < 0) {
- if (tn_sopt(DONT,x) < 0)
- return(-1);
- TELOPT_UNANSWERED_DONT(x) = 1;
- }
- } else {
- TELOPT_SB(TELOPT_FORWARD_X).forward_x.need_to_send = 1;
- }
- break;
-#endif /* CK_FORWARD_X */
-#ifdef TN_COMPORT
- case TELOPT_COMPORT: {
- extern int reliable;
- if (!tn_delay_sb || !tn_outst(0) || tn_init) {
- if (tn_sndcomport() < 0)
- return(-1);
- } else {
- TELOPT_SB(TELOPT_COMPORT).comport.need_to_send = 1;
- }
- /* Telnet -> Serial -> ??? is not a reliable connection. */
- reliable = SET_OFF;
- break;
- }
-#endif /* TN_COMPORT */
- } /* switch */
- } else {
- if (TELOPT_UNANSWERED_WILL(x))
- TELOPT_UNANSWERED_WILL(x) = 0;
- }
- break;
-
- case DONT:
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return(0);
-#endif /* CK_SSL */
- if (TELOPT_ME(x) || TELOPT_UNANSWERED_WILL(x)) {
- /* David Borman says we should not respond WONT when
- * the DONT is a response to a WILL that we sent.
- * Nor should we send one if the state is already WONT
- * such as when we do not recognize the option since
- * options are initialized in the WONT/DONT state.
- */
- if (!(TELOPT_UNANSWERED_WILL(x) || TELOPT_UNANSWERED_WONT(x)))
- if (tn_sopt(WONT,x) < 0)
- return(-1);
-
- if (TELOPT_UNANSWERED_WILL(x))
- TELOPT_UNANSWERED_WILL(x) = 0;
- if (TELOPT_UNANSWERED_WONT(x))
- TELOPT_UNANSWERED_WONT(x) = 0;
- if (TELOPT_ME(x))
- TELOPT_ME(x) = 0;
-
- switch (x) {
-#ifdef CK_SSL
- case TELOPT_START_TLS:
- if (!sstelnet && TELOPT_ME_MODE(x) == TN_NG_MU) {
- printf("Telnet Start-TLS refused.\n");
- ttclos(0);
- whyclosed = WC_TELOPT;
- return(-3);
- }
- break;
-#endif /* CK_SSL */
-#ifdef CK_AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- if (!sstelnet && TELOPT_ME_MODE(x) == TN_NG_MU) {
-#ifdef CK_SSL
- if (tls_active_flag) {
- TELOPT_ME_MODE(x) = TN_NG_AC;
- break;
- } else
-#endif /* CK_SSL */
- {
- printf("Telnet authentication refused.\n");
- ttclos(0);
- whyclosed = WC_TELOPT;
- return(-3);
- }
- } else if (TELOPT_ME_MODE(x) == TN_NG_RQ) {
- TELOPT_ME_MODE(x) = TN_NG_AC;
- }
- if (ck_tn_auth_in_progress())
- printf("Telnet authentication refused.\n");
-#ifdef CK_ENCRYPTION
- if (!sstelnet) {
- if (tn_no_encrypt()<0)
- return(-1);
- }
-#endif /* CK_ENCRYPTION */
- break;
-#endif /* CK_AUTHENTICATION */
- case TELOPT_ENCRYPTION:
-#ifdef CK_ENCRYPTION
- ck_tn_enc_stop();
-#endif /* CK_ENCRYPTION */
- break;
- case TELOPT_KERMIT:
-#ifdef IKS_OPTION
- TELOPT_SB(x).kermit.me_start = 0;
-#endif /* IKS_OPTION */
- break;
- default:
- break;
- } /* switch */
- } else {
- if (TELOPT_UNANSWERED_WILL(x))
- TELOPT_UNANSWERED_WILL(x) = 0;
- if (TELOPT_UNANSWERED_WONT(x))
- TELOPT_UNANSWERED_WONT(x) = 0;
- }
- if (TELOPT_ME_MODE(x) == TN_NG_MU) {
- ckmakmsg( tn_msg,TN_MSG_LEN,
- "Peer refuses TELNET WILL ",TELOPT(x),
- " negotiations - terminating connection",
- NULL
- );
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- printf("%s\n",tn_msg);
- ttclos(0);
- whyclosed = WC_TELOPT;
- return(-3);
- }
- break;
- case SB:
- if ((y = tn_sb(x,&n,fn)) <= 0)
- return(y);
-
-#ifdef CK_SSL
- /* Do not process subnegotiations other than START_TLS after we */
- /* have agreed to begin the TLS negotiation sequence. */
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows &&
- x != TELOPT_START_TLS)
- break;
-#endif /* CK_SSL */
-
- if (!TELOPT_OK(x)) {
- ckhexdump("unknown telnet subnegotiation",sb,n);
- break;
- } else if ( !(TELOPT_ME(x) || TELOPT_U(x)) ) {
- ckhexdump("telnet option not negotiated",sb,n);
- if (!tn_sb_bug)
- break;
- if (TELOPT_UNANSWERED_WILL(x)) {
- TELOPT_UNANSWERED_WILL(x) = 0;
- TELOPT_U(x) = 1;
- ckmakmsg(tn_msg,TN_MSG_LEN,
- "TELNET DO ",TELOPT(x),
- "(implied by receipt of SB - protocol error ignored)",
- NULL
- );
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- if (TELOPT_UNANSWERED_DO(x)) {
- TELOPT_UNANSWERED_DO(x) = 0;
- TELOPT_ME(x) = 1;
- ckmakmsg(tn_msg,TN_MSG_LEN,"TELNET WILL ",TELOPT(x),
- " (implied by receipt of SB - protocol error ignored)",
- NULL);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- }
-
- TELOPT_UNANSWERED_SB(x)=0;
- switch (x) {
-#ifdef CK_FORWARD_X
- case TELOPT_FORWARD_X:
- return(fwdx_tn_sb(sb, n));
-#endif /* CK_FORWARD_X */
-#ifdef CK_SSL
- case TELOPT_START_TLS: {
- /*
- the other side is saying SB START_TLS FOLLOWS
- the incoming channel is now ready for starting the
- TLS negotiation.
- */
- int def_tls_u_mode, def_tls_me_mode;
- int def_enc_u_mode, def_enc_me_mode;
- int rc = 0;
-
- if (sb[0] != 1) {
- break;
- }
-
- TELOPT_SB(TELOPT_START_TLS).start_tls.u_follows = 1;
- /* Preserve the default modes and make sure we will */
- /* refuse START_TLS when we retry. */
- if (sstelnet) {
- def_tls_u_mode = TELOPT_DEF_S_U_MODE(TELOPT_START_TLS);
- def_tls_me_mode = TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS);
- TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS)= TN_NG_RF;
-#ifdef CK_ENCRYPTION
- def_enc_u_mode = TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION);
- def_enc_me_mode = TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION);
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION)= TN_NG_RF;
-#endif /* CK_ENCRYPTION */
- } else {
- def_tls_u_mode = TELOPT_DEF_C_U_MODE(TELOPT_START_TLS);
- def_tls_me_mode = TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS);
- TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
- TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS)= TN_NG_RF;
-#ifdef CK_ENCRYPTION
- def_enc_u_mode = TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION);
- def_enc_me_mode = TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION);
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION)= TN_NG_RF;
-#endif /* CK_ENCRYPTION */
- }
- /* Negotiate TLS */
- ttnproto = NP_TLS;
- tn_init = 0;
- tn_begun = 0;
- if (ck_tn_tls_negotiate()<0) {
- /* we failed. disconnect and if we are the client */
- /* then reconnect and try without START_TLS. */
- extern char * line;
- int x = -1;
- extern int mdmtyp;
-
- if (sstelnet) {
- printf("TLS failed: Disconnecting.\n");
- TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = def_tls_u_mode;
- TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = def_tls_me_mode;
-#ifdef CK_ENCRYPTION
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = def_enc_u_mode;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = def_enc_me_mode;
-#endif /* CK_ENCRYPTION */
- ttclos(0);
- whyclosed = WC_TELOPT;
- ttnproto = NP_TELNET;
- rc = -3;
- } else {
-#ifndef NOLOCAL
- extern int tls_norestore;
-#endif /* NOLOCAL */
- printf("TLS failed: Disconnecting...\n");
-#ifdef CK_ENCRYPTION
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = def_enc_u_mode;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = def_enc_me_mode;
-#endif /* CK_ENCRYPTION */
- /* if START_TLS is not REQUIRED, then retry without it */
- if ( def_tls_me_mode != TN_NG_MU ) {
- extern char ttname[];
-#ifndef NOLOCAL
- tls_norestore = 1;
-#endif /* NOLOCAL */
- ttclos(0);
- whyclosed = WC_TELOPT;
-#ifndef NOLOCAL
- tls_norestore = 0;
-#endif /* NOLOCAL */
- ttnproto = NP_TELNET;
- printf("Reconnecting without TLS.\n");
- sleep(2);
- if (ttopen(ttname,&x,mdmtyp,0)<0)
- rc = -3;
- } else {
- TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) =
- def_tls_u_mode;
- TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) =
- def_tls_me_mode;
- ttclos(0);
- whyclosed = WC_TELOPT;
- ttnproto = NP_TELNET;
- rc = -3;
- }
- }
- } else {
-#ifdef CK_AUTHENTICATION
- /* we succeeded. restart telnet negotiations from */
- /* the beginning. However, if we have received a */
- /* client certificate and we are a server, then do */
- /* not offer TELOPT_AUTH. */
- if ( ck_tn_auth_valid() == AUTH_VALID ) {
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_AC;
- TELOPT_DEF_S_ME_MODE(TELOPT_AUTHENTICATION)= TN_NG_AC;
- }
-#endif /* CK_AUTHENTICATION */
- ttnproto = NP_TELNET;
- if (tn_ini() < 0)
- if (ttchk() < 0)
- rc = -1;
- }
- /* Restore the default modes */
- if (sstelnet) {
- TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = def_tls_u_mode;
- TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = def_tls_me_mode;
-#ifdef CK_ENCRYPTION
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = def_enc_u_mode;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = def_enc_me_mode;
-#endif /* CK_ENCRYPTION */
- } else {
- TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = def_tls_u_mode;
- TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = def_tls_me_mode;
-#ifdef CK_ENCRYPTION
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = def_enc_u_mode;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = def_enc_me_mode;
-#endif /* CK_ENCRYPTION */
- }
- return(rc);
- }
-#endif /* CK_SSL */
-#ifdef CK_AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- if (ck_tn_sb_auth((char *)sb,n) < 0) {
- if (sstelnet && TELOPT_U_MODE(x) == TN_NG_MU) {
- ttclos(0);
- whyclosed = WC_TELOPT;
- return(-3);
- } else if (!sstelnet && TELOPT_ME_MODE(x) == TN_NG_MU) {
- ttclos(0);
- whyclosed = WC_TELOPT;
- return(-3);
- } else {
- if (TELOPT_ME_MODE(x) == TN_NG_RQ)
- TELOPT_ME_MODE(x) = TN_NG_AC;
- if (TELOPT_U_MODE(x) == TN_NG_RQ)
- TELOPT_U_MODE(x) = TN_NG_AC;
- }
- if (TELOPT_ME(x)) {
- TELOPT_ME(x) = 0;
- if (tn_sopt(WONT,x) < 0)
- return(-1);
- }
- if (TELOPT_U(x)) {
- TELOPT_U(x) = 0;
- if (tn_sopt(DONT,x) < 0)
- return(-1);
- }
-#ifdef CK_ENCRYPTION
- if (tn_no_encrypt()<0)
- return(-1);
-#endif /* CK_ENCRYPTION */
- } else {
-#ifdef CK_ENCRYPTION
- if (!ck_tn_auth_in_progress()) { /* we are finished */
- if (ck_tn_authenticated() == AUTHTYPE_SSL) {
- /* TLS was successful. Disable ENCRYPTION */
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
- if (TELOPT_SB(TELOPT_ENCRYPTION).encrypt.need_to_send) {
- ck_encrypt_send_support();
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.need_to_send = 0;
- }
- }
-#endif /* CK_ENCRYPTION */
- }
- break;
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
- case TELOPT_ENCRYPTION:
- if (ck_tn_sb_encrypt((char *)sb, n) < 0) {
- if (TELOPT_U_MODE(x) == TN_NG_MU ||
- TELOPT_ME_MODE(x) == TN_NG_MU)
- {
- ttclos(0);
- whyclosed = WC_TELOPT;
- return(-3);
- } else {
- if (TELOPT_ME_MODE(x) == TN_NG_RQ)
- TELOPT_ME_MODE(x) = TN_NG_AC;
- if (TELOPT_U_MODE(x) == TN_NG_RQ)
- TELOPT_U_MODE(x) = TN_NG_AC;
- }
- if (TELOPT_ME(x)) {
- TELOPT_ME(x) = 0;
- if (tn_sopt(WONT,x) < 0)
- return(-1);
- }
- if (TELOPT_U(x)) {
- TELOPT_U(x) = 0;
- if (tn_sopt(DONT,x) < 0)
- return(-1);
- }
- }
- break;
-#endif /* CK_ENCRYPTION */
-#ifdef IKS_OPTION
- case TELOPT_KERMIT:
- return(iks_tn_sb(sb, n-2));
-#endif /* IKS_OPTION */
-#ifdef TN_COMPORT
- case TELOPT_COMPORT:
- return(tnc_tn_sb(sb, n-2));
-#endif /* TN_COMPORT */
- case TELOPT_TTYPE:
- switch (sb[0]) {
- case TELQUAL_SEND: /* SEND terminal type? */
- if ( !tn_delay_sb || !tn_outst(0) || tn_init ) {
- if (tn_sttyp() < 0) /* Yes, so send it. */
- return(-1);
- } else {
- TELOPT_SB(TELOPT_TTYPE).term.need_to_send = 1;
- }
- break;
- case TELQUAL_IS: { /* IS terminal type? */
- /* IS terminal type -- remote gave us its current type */
- int i = 0;
-#ifndef OS2
- CHAR oldterm[64], *p;
-#endif /* OS2 */
- /* Isolate the specified terminal type string */
- while (sb[i++] != IAC) {
- if (i == 40 || /* max len of term string - RFC */
- sb[i] == IAC) {
- sb[i] = '\0';
- break;
- }
- }
-#ifdef OS2
-#ifndef NOTERM
- strupr(&(sb[1])); /* Upper case it */
- for (i = 0; i <= max_tt; i++) { /* find it in our list */
- if (!strcmp(&(sb[1]),tt_info[i].x_name)
- && i != TT_VTNT) /* can't support VTNT as server */
- {
- /* Set terminal type to the one chosen */
- if (i != tt_type)
- settermtype(i,0);
- break;
- }
- }
- if (i > max_tt &&
- strcmp(&(sb[1]),TELOPT_SB(TELOPT_TTYPE).term.type)) {
- /* Couldn't find the specified term type */
- sb[40] = '\0';
- strcpy(TELOPT_SB(TELOPT_TTYPE).term.type,&(sb[1]));
- /* SB TTYPE SEND */
- tn_ssbopt(TELOPT_TTYPE,TELQUAL_SEND,NULL,0);
- TELOPT_UNANSWERED_SB(TELOPT_TTYPE)=1;
- }
-#endif /* NOTERM */
-#else /* OS2 */
- p = (CHAR *) getenv("TERM");
- if (p)
- ckstrncpy((char *)oldterm,(char *)p,63);
- else
- oldterm[0] = '\0';
- cklower((char *)&(sb[1])); /* Lower case new term */
- ckmakmsg(term_buf,64,"TERM=",(char *)&(sb[1]),NULL,NULL);
-#ifdef OS2ORUNIX
-#ifndef NOPUTENV
- putenv(term_buf);
-#endif /* NOPUTENV */
-#endif /* OS2ORUNIX */
-#ifdef CK_CURSES
-#ifndef MYCURSES
-#ifndef COHERENT
- if (trmbuf) {
- if (tgetent(trmbuf,(char *)&sb[1]) < 1) {
- /* Unsupported terminal. If new and old terminal */
- /* types do not match, ask for another type. */
- if (strcmp((char *)oldterm,(char *)&sb[1])) {
- /* SB TTYPE SEND */
- tn_ssbopt(TELOPT_TTYPE,TELQUAL_SEND,NULL,0);
- TELOPT_UNANSWERED_SB(TELOPT_TTYPE)=1;
- }
- }
- }
-#endif /* COHERENT */
-#endif /* MYCURSES */
-#endif /* CK_CURSES */
-#endif /* OS2 */
- }
- }
- break;
-#ifdef CK_ENVIRONMENT
-#ifdef CK_XDISPLOC
- case TELOPT_XDISPLOC: /* Send X-Display Location */
- if (sb[0] == TELQUAL_SEND) {/* SEND X-Display Loc? */
- if ( !tn_delay_sb || !tn_outst(0) || tn_init ) {
- if (tn_sxdisploc() < 0) /* Yes, so send it. */
- return(-1);
- } else {
- TELOPT_SB(TELOPT_XDISPLOC).xdisp.need_to_send = 1;
- }
- }
- /* IS -- X Display Location (not supported) */
- else if (sb[0] == TELQUAL_IS) {
- int i = 0;
- /* Isolate the specified X-display string */
- while (sb[i++] != IAC) {
- if (i >= TSBUFSIZ)
- return (-1);
- if (sb[i] == IAC) {
- sb[i] = '\0';
- break;
- }
- }
- debug(F110,"TELNET SB XDISPLOC IS",&sb[1],0);
- }
- break;
-#endif /* CK_XDISPLOC */
-#endif /* CK_ENVIRONMENT */
- case TELOPT_NAWS:
- if (sstelnet
-#ifdef IKSD
- || inserver
-#endif /* IKSD */
- ) {
- int w = 0, h = 0;
- int i = 0;
- /* At this point sb[] should contain width and height */
- if (sb[i] == IAC) i++;
- w = (sb[i++] << 8); /* save upper height */
- if (sb[i] == IAC) i++;
- w += sb[i++]; /* save the width */
- if (sb[i] == IAC) i++;
- h = (sb[i++] << 8); /* save upper height */
- if (sb[i] == IAC) i++;
- h += sb[i++];
- debug(F111,"tn_doop NAWS SB","width",w);
- debug(F111,"tn_doop NAWS SB","height",h);
-
- if (w == 0)
- w = 80;
- if (h == 0)
- h = 24;
-#ifndef NOLOCAL
- if (tcp_incoming || inserver) {
-#ifdef OS2
- tt_cols[VTERM] = w;
- tt_rows[VTERM] = h;
- VscrnSetWidth(VTERM, w);
- VscrnSetHeight(VTERM, h+(tt_status[VTERM]?1:0));
-#ifdef IKSD
- if (inserver) {
- cmd_cols = tt_cols[VCMD] = w;
- cmd_rows = tt_rows[VCMD] = h;
- VscrnSetWidth(VCMD, w);
- VscrnSetHeight(VCMD, h);
- }
-#endif /* IKSD */
-#else /* OS2 */
- tt_cols = w;
- tt_rows = h;
-#endif /* OS2 */
- } else {
-#ifdef OS2
- tt_cols[VCMD] = w;
- tt_rows[VCMD] = h;
- VscrnSetWidth(VCMD, w);
- VscrnSetHeight(VCMD, h);
-#endif /* OS2 */
- cmd_cols = w;
- cmd_rows = h;
- }
-#else /* NOLOCAL */
- cmd_cols = w;
- cmd_rows = h;
-#endif /* NOLOCAL */
-
- /* Add LINES and COLUMNS to the environment */
- ckmakmsg((char *)rows_buf,16,"LINES=",ckitoa(h),NULL,NULL);
- ckmakmsg((char *)cols_buf,16,"COLUMNS=",ckitoa(w),NULL,NULL);
-#ifdef OS2ORUNIX
-#ifndef NOPUTENV
- putenv(rows_buf);
- putenv(cols_buf);
-#endif /* NOPUTENV */
-#endif /* OS2ORUNIX */
- }
- break;
-#ifdef CK_ENVIRONMENT
- case TELOPT_NEWENVIRON:
- switch (sb[0]) {
- case TELQUAL_IS: /* IS */
- case TELQUAL_INFO: /* INFO */
- if (sb[0] == TELQUAL_IS)
- debug(F101,"tn_doop NEW-ENV SB IS","",n-3);
- else
- debug(F101,"tn_doop NEW-ENV SB INFO","",n-3);
- if (sstelnet || inserver) { /* Yes, receive it. */
- if (tn_rnenv((CHAR *)&sb[1],n-3) < 0)
- return(-1);
- }
- break;
- case TELQUAL_SEND: /* SEND */
- if ( sstelnet || inserver ) /* ignore if server */
- break;
- /* We need to take the sb[] and build a structure */
- /* containing all of the variables and types that */
- /* we are supposed to keep track of and send to */
- /* the host, then call tn_snenv(). */
- /* Or we can punt ... */
- if ( !tn_delay_sb || !tn_outst(0) || tn_init ) {
- if (tn_snenv((CHAR *)&sb[1],n-3) < 0) /* Yes, send it. */
- return(-1);
- } else {
-#ifndef VMS
- CHAR * xxx;
- xxx = (CHAR *) malloc(n-1);
-#else
- unsigned char * xxx;
- xxx = (unsigned char *) malloc(n-1);
-#endif /* VMS */
- /* Postpone sending until end of tn_ini() */
- TELOPT_SB(TELOPT_NEWENVIRON).env.str = xxx;
- if (TELOPT_SB(TELOPT_NEWENVIRON).env.str) {
- memcpy((char *)TELOPT_SB(TELOPT_NEWENVIRON).env.str,
- (char *)&sb[1],n-3);
- TELOPT_SB(TELOPT_NEWENVIRON).env.str[n-3] = IAC;
- TELOPT_SB(TELOPT_NEWENVIRON).env.str[n-2] = '\0';
- TELOPT_SB(TELOPT_NEWENVIRON).env.len = n-3;
- TELOPT_SB(TELOPT_NEWENVIRON).env.need_to_send = 1;
- }
- }
- break;
- }
- break;
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_SNDLOC
- case TELOPT_SNDLOC: {
- if ( deblog ) {
- sb[n-2] = '\0';
- debug(F110,"TELNET Send-Location",sb,0);
- }
- break;
- }
-#endif /* CK_SNDLOC */
- } /* switch */
- break;
- }
- return(0);
-}
-
-int
-#ifdef CK_ANSIC /* TELNET DO OPTION */
-tn_doop(CHAR z, int echo, int (*fn)(int))
-#else
-tn_doop(z, echo, fn) CHAR z; int echo; int (*fn)();
-#endif /* CK_ANSIC */
-/* tn_doop */ {
- int x=0, y=0;
-
- debug(F101,"tn_doop char","",z);
- debug(F101,"tn_doop ttnproto","",ttnproto);
-
- if (!IS_TELNET()) return(3);
-
-#ifdef CK_SSL
- debug(F101,"tn_doop ssl_raw_flag","",ssl_raw_flag);
- if (ssl_raw_flag || tls_raw_flag) return(7);
-#endif /* CK_SSL */
- debug(F100,"tn_doop ttnproto proceeding...","",0);
-
- if (z != (CHAR) IAC) {
- debug(F101,"tn_doop bad call","",z);
- return(-1);
- }
- if (ttnet != NET_TCPB) /* Check network type */
- return(0);
- if (ttnproto != NP_TELNET &&
- ttnproto != NP_NONE) /* Check protocol */
- return(0);
-
- x = tn_xdoop(z,echo,fn);
- if (x >= 0 && !tn_begun) {
- y = tn_start();
- }
- return(y < 0 ? y : x);
-}
-
-#ifdef CK_ENVIRONMENT
-
-/* Telnet receive new environment */
-/* Returns -1 on error, 0 if nothing happens, 1 on success */
-/* In order for this code to work, sb[len] == IAC */
-/* We currently only support the USER environment variable */
-
-int
-#ifdef CK_ANSIC
-tn_rnenv(CHAR * sb, int len)
-#else
-tn_rnenv(sb, len) CHAR * sb; int len;
-#endif /* CK_ANSIC */
-/* tn_rnenv */ { /* Receive new environment */
- char varname[17];
- char value[65];
- char * reply = 0, * s = 0;
- int i,j,k,n; /* Worker. */
- int type = 0; /* 0 for NONE, 1 for VAR, 2 for USERVAR, */
- /* 3 for VALUE in progress */
-
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
- if (sb == NULL) return(-1);
-
- if (len == 0) return(1);
-
- /*
- Pairs of <type> [VAR=0, VALUE=1, ESC=2, USERVAR=3] <value> "unterminated"
- follow here until done...
- */
- for (i = 0, j = 0, k = 0, type = 0, varname[0]= '\0'; i <= len; i++) {
- switch (sb[i]) {
- case TEL_ENV_VAR: /* VAR */
- case TEL_ENV_USERVAR: /* USERVAR */
- case IAC: /* End of the list */
- switch (type) {
- case 0: /* Nothing in progress */
- /* If we get IAC only, then that means there were */
- /* no environment variables to send. we are done */
- if (j == 0 && sb[i] == IAC)
- return(1);
- case 1: /* VAR in progress */
- case 2: /* USERVAR in progress */
- case 3: /* VALUE in progress */
- value[k] = '\0';
- varname[j] = '\0';
- debug(F111,"tn_rnenv varname",varname,type);
- debug(F111,"tn_rnenv value",value,type);
- if (!strcmp(varname,"USER")) {
-#ifdef CK_AUTHENTICATION
- if (ck_tn_auth_valid() != AUTH_VALID) {
- extern char szUserNameRequested[];
- debug(F100,"tn_rnenv != AUTH_VALID","",0);
- ckstrncpy(szUserNameRequested,value,UIDBUFLEN);
- ckstrncpy(uidbuf,value,UIDBUFLEN);
-#ifdef CK_SSL
- if (ssl_active_flag) {
- if ( tls_is_user_valid(ssl_con, uidbuf) ) {
- extern char szUserNameAuthenticated[];
- ckstrncpy(szUserNameAuthenticated,uidbuf,
- UIDBUFLEN);
- auth_finished(AUTH_VALID);
- }
- } else if (tls_active_flag) {
- if ( tls_is_user_valid(tls_con, uidbuf) ) {
- extern char szUserNameAuthenticated[];
- ckstrncpy(szUserNameAuthenticated,uidbuf,
- UIDBUFLEN);
- auth_finished(AUTH_VALID);
- }
- }
-#endif /* CK_SSL */
- } else { /* AUTH_VALID */
- int x = 0;
- debug(F110,"tn_rnenv AUTH_VALID uidbuf",uidbuf,0);
-
-#ifdef OS2
- x = ckstrcmp(value,uidbuf,-1,0); /* case insensitive */
-#ifdef NT
- /* NTLM authentication returns names of the form */
- /* DOMAIN\user. We need to check to see of the */
- /* USER VAR contains a domain name or not. If */
- /* not, then we do not want to change state if */
- /* the uidbuf matches the USER VAR when the */
- /* DOMAIN is ignored. */
- if ( x && ck_tn_authenticated() == AUTHTYPE_NTLM ) {
- char * s1=NULL, * s2=NULL;
- int len1, len2, i;
-
- len1 = strlen(value);
- for ( i=len1-1 ; i>=0 ; i--) {
- if ( value[i] == '\\' ) {
- s1 = &value[i+1]; /* DOMAIN found */
- break;
- }
- }
-
- if ( s1 == NULL ) {
- len2 = strlen(uidbuf);
- for ( i=len2-1 ; i>=0 ; i--) {
- if ( uidbuf[i] == '\\' ) {
- s2 = &uidbuf[i+1]; /* DOMAIN found */
- break;
- }
- }
-
- if ( s2 )
- x = ckstrcmp(value,s2,-1,0);
- }
- }
-#endif /* NT */
-#else /* OS2 */
- x = ckstrcmp(value,uidbuf,-1,1); /* case sensitive */
-#endif /* OS2 */
- if ( x ) {
- extern char szUserNameRequested[];
- ckstrncpy(uidbuf,value,UIDBUFLEN);
- ckstrncpy(szUserNameRequested,value,UIDBUFLEN);
- auth_finished(AUTH_USER);
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- if ( tls_is_user_valid(ssl_con, uidbuf) )
- auth_finished(AUTH_VALID);
- }
-#endif /* CK_SSL */
- }
- }
-#else /* CK_AUTHENTICATION */
- ckstrncpy(uidbuf,value,UIDBUFLEN);
-#endif /* CK_AUTHENTICATION */
- }
- break;
- }
- varname[0] = '\0';
- value[0] = '\0';
- j = 0;
- k = 0;
- type = (sb[i] == TEL_ENV_USERVAR ? 2 : /* USERVAR */
- sb[i] == TEL_ENV_VAR ? 1 : /* VAR */
- 0
- );
- break;
- case TEL_ENV_VALUE: /* VALUE */
- if ( type == 1 || type == 2 )
- type = 3;
- break;
- case TEL_ENV_ESC: /* ESC */
- /* Take next character literally */
- if ( ++i >= len )
- break;
- /* otherwise, fallthrough so byte will be added to string. */
- default:
- switch (type) {
- case 1: /* VAR in progress */
- case 2: /* USERVAR in progress */
- if ( j < 16 )
- varname[j++] = sb[i];
- break;
- case 3:
- if ( k < 64 )
- value[k++] = sb[i];
- break;
- }
- }
- }
- return(0);
-}
-
-/* These are for Microsoft SFU version 2 Telnet Server */
-#define SFUTLNTVER "SFUTLNTVER"
-#define SFUTLNTMODE "SFUTLNTMODE"
-#define SFUTLNTVER_VALUE "2"
-#define SFUTLNTMODE_VALUE "console" /* The other value is "stream" */
-
-/* Telnet send new environment */
-/* Returns -1 on error, 0 if nothing happens, 1 on success */
-/* In order for this code to work, sb[len] == IAC */
-
-int
-#ifdef CK_ANSIC
-tn_snenv(CHAR * sb, int len)
-#else
-tn_snenv(sb, len) CHAR * sb; int len;
-#endif /* CK_ANSIC */
-/* tn_snenv */ { /* Send new environment */
- char varname[16];
- char * reply = 0, * s = 0;
- int i,j,n; /* Worker. */
- int type = 0; /* 0 for NONE, 1 for VAR, 2 for USERVAR in progress */
- extern int ck_lcname;
- char localuidbuf[UIDBUFLEN]; /* (Initialized just below) */
- char * uu = uidbuf;
- char * disp = NULL;
-
- localuidbuf[0] = '\0';
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
- if (!sb) return(-1);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
-#ifdef CK_FORWARD_X
- if (TELOPT_U(TELOPT_FORWARD_X)) {
- disp = NULL;
- } else
-#endif /* CK_FORWARD_X */
- disp = (char *)tn_get_display();
-
- if (ck_lcname) {
- ckstrncpy(localuidbuf,uidbuf,UIDBUFLEN);
- cklower(localuidbuf);
- uu = localuidbuf;
- }
-
- ckhexdump((CHAR *)"tn_snenv sb[]",sb,len);
- debug(F110,"tn_snenv uidbuf",uidbuf,0);
- debug(F110,"tn_snenv localuidbuf",localuidbuf,0);
- debug(F110,"tn_snenv tn_env_sys",tn_env_sys,0);
- debug(F110,"tn_snenv tn_env_disp",tn_env_disp,0);
- debug(F110,"tn_snenv disp",disp,0);
-
- /* First determine the size of the buffer we will need */
- for (i = 0, j = 0, n = 0, type = 0, varname[0]= '\0'; i <= len; i++) {
- switch (sb[i]) {
- case TEL_ENV_VAR: /* VAR */
- case TEL_ENV_USERVAR: /* USERVAR */
- case IAC: /* End of the list */
- switch (type) {
- case 0: /* Nothing in progress */
- /* If we get IAC only, then that means send all */
- /* VAR and USERVAR. */
- if (!(j == 0 && sb[i] == IAC))
- break;
- case 1: /* VAR in progress */
- varname[j] = '\0' ;
- if (!varname[0]) { /* Send All */
- if (uu[0])
- n += strlen(uu) + 4 + 2;
- if (tn_env_job[0])
- n += strlen(tn_env_job) + 3 + 2;
- if (tn_env_acct[0])
- n += strlen(tn_env_acct) + 4 + 2;
- if (tn_env_prnt[0])
- n += strlen(tn_env_prnt) + 7 + 2;
- if (tn_env_sys[0])
- n += strlen(tn_env_sys) + 10 + 2;
- if (disp)
- n += strlen(disp) + 7 + 2;
- } else if (!strcmp(varname,"USER") && uu[0])
- n += strlen(uu) + 4 + 2;
- else if (!strcmp(varname,"JOB") && tn_env_job[0])
- n += strlen(tn_env_job) + 3 + 2;
- else if (!strcmp(varname,"ACCT") && tn_env_acct[0])
- n += strlen(tn_env_acct) + 4 + 2;
- else if (!strcmp(varname,"PRINTER") && tn_env_prnt[0])
- n += strlen(tn_env_prnt) + 7 + 2;
- else if (!strcmp(varname,"SYSTEMTYPE") && tn_env_sys[0])
- n += strlen(tn_env_sys) + 10 + 2;
- else if (!strcmp(varname,"DISPLAY") && disp)
- n += strlen(disp) + 7 + 2;
- /* If we get IAC only, then that means send all */
- /* VAR and USERVAR. */
- if (!(j == 0 && sb[i] == IAC))
- break;
- case 2: /* USERVAR in progress */
- varname[j] = '\0' ;
- if (!varname[0]) { /* Send All */
- int x;
- for ( x=0 ; x<8 ; x++ ) {
- if ( tn_env_uservar[x][0] &&
- tn_env_uservar[x][1] )
- n += strlen(tn_env_uservar[x][0])
- + strlen(tn_env_uservar[x][1]) + 2;
- }
- if ( tn_sfu ) {
- /* For compatibility with Microsoft Telnet Server */
- n += strlen(SFUTLNTVER) + strlen(SFUTLNTVER_VALUE) + 2;
- n += strlen(SFUTLNTMODE) +
- strlen(SFUTLNTMODE_VALUE) + 2;
- }
-#ifdef CK_SNDLOC
- if ( tn_loc && tn_loc[0] )
- n += strlen("LOCATION") + strlen(tn_loc) + 2;
-#endif /* CK_SNDLOC */
- }
- else if (tn_sfu && !strcmp(varname,SFUTLNTVER))
- n += strlen(SFUTLNTVER) + strlen(SFUTLNTVER_VALUE) + 2;
- else if (tn_sfu && !strcmp(varname,SFUTLNTMODE))
- n += strlen(SFUTLNTMODE) + strlen(SFUTLNTMODE_VALUE) + 2;
-#ifdef CK_SNDLOC
- else if ( tn_loc && tn_loc[0] && !strcmp(varname,"LOCATION"))
- n += strlen("LOCATION") + strlen(tn_loc) + 2;
-#endif /* CK_SNDLOC */
- else {
- int x;
- for ( x=0 ; x<8 ; x++ ) {
- if ( tn_env_uservar[x][0] &&
- tn_env_uservar[x][1] &&
- !strcmp(varname,tn_env_uservar[x][0]))
- n += strlen(tn_env_uservar[x][0])
- + strlen(tn_env_uservar[x][1]) + 2;
- }
- }
- break;
- }
- varname[0] = '\0';
- j = 0;
- type = (sb[i] == TEL_ENV_USERVAR ? 2 : /* USERVAR */
- sb[i] == TEL_ENV_VAR ? 1 : /* VAR */
- 0
- );
- break;
- case TEL_ENV_VALUE: /* VALUE */
- /* Protocol Error */
- debug(F100, "TELNET Subnegotiation error - VALUE in SEND", "",0);
- if (tn_deb || debses)
- tn_debug("TELNET Subnegotiation error - VALUE in SEND");
- return(0);
- case TEL_ENV_ESC: /* ESC */
- if (++i >= len)
- break;
- default:
- if (j < 16 )
- varname[j++] = sb[i];
- }
- }
- reply = malloc(n + 16); /* Leave room for IAC stuff */
- if (!reply) {
- debug(F100, "TELNET Subnegotiation error - malloc failed", "",0);
- if (tn_deb || debses)
- tn_debug("TELNET Subnegotiation error - malloc failed");
-
- /* Send a return packet with no variables so that the host */
- /* may continue with additional negotiations */
- if (tn_ssbopt(TELOPT_NEWENVIRON,TELQUAL_IS,"",0) < 0)
- return(-1);
- return(0);
- }
-
- /* Now construct the real reply */
-
- n = 0; /* Start at beginning of buffer */
-/*
- Pairs of <type> [VAR=0, VALUE=1, ESC=2, USERVAR=3] <value> "unterminated"
- follow here until done...
-*/
- for (i = 0, j = 0, type = 0, varname[0]= '\0'; i <= len; i++) {
- switch (sb[i]) {
- case TEL_ENV_VAR: /* VAR */
- case TEL_ENV_USERVAR: /* USERVAR */
- case IAC: /* End of the list */
- switch (type) {
- case 0: /* Nothing in progress */
- /* If we get IAC only, then that means send all */
- /* VAR and USERVAR. */
- if (!(j == 0 && sb[i] == IAC))
- break;
- case 1: /* VAR in progress */
- varname[j] = '\0';
- if (!varname[0]) {
- /* Send All */
- if (uu[0]) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"USER");
- reply[n+5] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+6],uu);
- n += strlen(uu) + 4 + 2;
- }
- if (tn_env_job[0]) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"JOB");
- reply[n+4] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+5],tn_env_job);
- n += strlen(tn_env_job) + 3 + 2;
- }
- if (tn_env_acct[0]) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"ACCT");
- reply[n+5] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+6],tn_env_acct);
- n += strlen(tn_env_acct) + 4 + 2;
- }
- if (tn_env_prnt[0]) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"PRINTER");
- reply[n+8] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+9],tn_env_prnt);
- n += strlen(tn_env_prnt) + 7 + 2;
- }
- if (tn_env_sys[0]) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"SYSTEMTYPE");
- reply[n+11] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+12],tn_env_sys);
- n += strlen(tn_env_sys) + 10 + 2;
- }
- if (disp) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"DISPLAY");
- reply[n+8] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+9],disp);
- n += strlen(disp) + 7 + 2;
- }
- } else if (!strcmp(varname,"USER") && uu[0]) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"USER");
- reply[n+5] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+6],uu);
- n += strlen(uu) + 4 + 2;
- } else if (!strcmp(varname,"JOB") && tn_env_job[0]) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"JOB");
- reply[n+4] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+5],tn_env_job);
- n += strlen(tn_env_job) + 3 + 2;
- } else if (!strcmp(varname,"ACCT") && tn_env_acct[0]) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"ACCT");
- reply[n+5] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+6],tn_env_acct);
- n += strlen(tn_env_acct) + 4 + 2;
- } else if (!strcmp(varname,"PRINTER") && tn_env_prnt[0]) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"PRINTER");
- reply[n+8] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+9],tn_env_prnt);
- n += strlen(tn_env_prnt) + 7 + 2;
- } else if (!strcmp(varname,"SYSTEMTYPE") && tn_env_sys[0]) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"SYSTEMTYPE");
- reply[n+11] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+12],tn_env_sys);
- n += strlen(tn_env_sys) + 10 + 2;
- } else if (!strcmp(varname,"DISPLAY") && disp) {
- reply[n] = TEL_ENV_VAR; /* VAR */
- strcpy(&reply[n+1],"DISPLAY");
- reply[n+8] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+9],disp);
- n += strlen(disp) + 7 + 2;
- }
- /* If we get IAC only, then that means send all */
- /* VAR and USERVAR. */
- if (!(j == 0 && sb[i] == IAC))
- break;
- case 2: /* USERVAR in progress */
- varname[j] = '\0';
- if (!varname[0]) {
- /* Send All */
- int x,y;
- for ( x=0 ; x<8 ; x++ ) {
- if ( tn_env_uservar[x][0] &&
- tn_env_uservar[x][1] ) {
- reply[n] = TEL_ENV_USERVAR; /* VAR */
- y = strlen(tn_env_uservar[x][0]);
- strcpy(&reply[n+1],tn_env_uservar[x][0]);
- reply[n+y+1] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+y+2],tn_env_uservar[x][1]);
- n += y+strlen(tn_env_uservar[x][1])+2;
- }
- }
- if ( tn_sfu ) {
- /* Compatibility with Microsoft Telnet Server */
- reply[n] = TEL_ENV_USERVAR; /* VAR */
- strcpy(&reply[n+1],SFUTLNTVER);
- reply[n+11] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+12],SFUTLNTVER_VALUE);
- n += strlen(SFUTLNTVER)+strlen(SFUTLNTVER_VALUE)+2;
-
- reply[n] = TEL_ENV_USERVAR; /* VAR */
- strcpy(&reply[n+1],SFUTLNTMODE);
- reply[n+12] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+13],SFUTLNTMODE_VALUE);
- n += strlen(SFUTLNTMODE)+strlen(SFUTLNTMODE_VALUE)+2;
- }
- if (tn_loc && tn_loc[0]) {
- reply[n] = TEL_ENV_USERVAR; /* VAR */
- strcpy(&reply[n+1],"LOCATION");
- reply[n+9] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+10],tn_loc);
- n += strlen("LOCATION") + strlen(tn_loc) + 2;
- }
- } else if (tn_sfu && !strcmp(varname,SFUTLNTVER)) {
- reply[n] = TEL_ENV_USERVAR; /* VAR */
- strcpy(&reply[n+1],SFUTLNTVER);
- reply[n+11] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+12],SFUTLNTVER_VALUE);
- n += strlen(SFUTLNTVER) + strlen(SFUTLNTVER_VALUE) + 2;
- } else if (tn_sfu && !strcmp(varname,SFUTLNTMODE)) {
- reply[n] = TEL_ENV_USERVAR; /* VAR */
- strcpy(&reply[n+1],SFUTLNTMODE);
- reply[n+12] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+13],SFUTLNTMODE_VALUE);
- n += strlen(SFUTLNTMODE) + strlen(SFUTLNTMODE_VALUE) + 2;
- }
-#ifdef CK_SNDLOC
- else if (tn_loc && tn_loc[0] && !strcmp(varname,"LOCATION")){
- reply[n] = TEL_ENV_USERVAR; /* VAR */
- strcpy(&reply[n+1],"LOCATION");
- reply[n+9] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+10],tn_loc);
- n += strlen("LOCATION") + strlen(tn_loc) + 2;
- }
-#endif /* CK_SNDLOC */
- else {
- int x,y;
- for ( x=0 ; x<8 ; x++ ) {
- if ( tn_env_uservar[x][0] &&
- tn_env_uservar[x][1] &&
- !strcmp(varname,tn_env_uservar[x][0])) {
- reply[n] = TEL_ENV_USERVAR; /* VAR */
- y = strlen(tn_env_uservar[x][0]);
- strcpy(&reply[n+1],tn_env_uservar[x][0]);
- reply[n+y+1] = TEL_ENV_VALUE; /* VALUE */
- strcpy(&reply[n+y+2],tn_env_uservar[x][1]);
- n += y+strlen(tn_env_uservar[x][1])+2;
- }
- }
- }
- break;
- }
- varname[0] = '\0';
- j = 0;
- type = (sb[i] == TEL_ENV_USERVAR ? 2 : /* USERVAR */
- sb[i] == TEL_ENV_VAR ? 1 : /* VAR */
- 0
- );
- break;
- case TEL_ENV_VALUE: /* VALUE */
- /* Protocol Error */
- debug(F100, "TELNET Subnegotiation error - VALUE in SEND", "",0);
- if (tn_deb || debses)
- tn_debug("TELNET Subnegotiation error - VALUE in SEND");
- return(0); /* Was -1 but that would be taken as */
- /* an I/O error, so absorb it and go on. */
- case TEL_ENV_ESC: /* ESC */
- /* Not sure what this for. Quote next character? */
- break;
- default:
- varname[j++] = sb[i];
- }
- }
- if (tn_ssbopt(TELOPT_NEWENVIRON,TELQUAL_IS,reply,n) < 0) {
- free(reply);
- return(-1);
- }
- free(reply);
- return(1);
-}
-#endif /* CK_ENVIRONMENT */
-
-/* Telnet send terminal type */
-/* Returns -1 on error, 0 if nothing happens, 1 if type sent successfully */
-
-int
-tn_sttyp() { /* Send telnet terminal type. */
- char *ttn; /* Name of terminal type. */
-#ifdef OS2
- static int alias = -1; /* which alias are we using ? */
- int settype = 0;
-#endif /* OS2 */
- int i, rc; /* Worker. */
- int tntermflg = 0;
-
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_TTYPE)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
- ttn = NULL;
-
-#ifndef NOTERM
-#ifdef OS2
- if (!tn_term) {
- if (ttnum == -1) {
- ttnum = tt_type;
- settype = 0;
- alias = -1;
- } else if (ttnumend) {
- ttnumend = 0;
- settype = 0;
- } else {
- if (tt_info[tt_type].x_aliases[++alias] == NULL) {
- if (--tt_type < 0)
- tt_type = max_tt;
- if (ttnum == tt_type)
- ttnumend = 1;
- settype = 1;
- alias = -1;
- }
- }
- if (tt_type >= 0 && tt_type <= max_tt) {
- if (alias == -1)
- ttn = tt_info[tt_type].x_name;
- else
- ttn = tt_info[tt_type].x_aliases[alias];
- } else
- ttn = NULL;
- }
- else settype = 0;
-#endif /* OS2 */
-#endif /* NOTERM */
-
- if (tn_term) { /* Terminal type override? */
- debug(F110,"tn_sttyp",tn_term,0);
- if (*tn_term) {
- ttn = tn_term;
- tntermflg = 1;
- }
- } else debug(F100,"tn_sttyp no term override","",0);
-
-#ifndef datageneral
- if (!ttn) { /* If no override, */
- ttn = getenv("TERM"); /* get it from the environment. */
- }
-#endif /* datageneral */
- if ((ttn == ((char *)0)) || ((int)strlen(ttn) >= TSBUFSIZ))
- ttn = "UNKNOWN";
- sb_out[0] = (CHAR) IAC; /* I Am a Command */
- sb_out[1] = (CHAR) SB; /* Subnegotiation */
- sb_out[2] = TELOPT_TTYPE; /* Terminal Type */
- sb_out[3] = (CHAR) 0; /* Is... */
- for (i = 4; *ttn; ttn++,i++) { /* Copy and uppercase it */
-#ifdef VMS
- if (!tntermflg && *ttn == '-' &&
- (!strcmp(ttn,"-80") || !strcmp(ttn,"-132")))
- break;
- else
-#endif /* VMS */
- sb_out[i] = (char) ((!tntermflg && islower(*ttn)) ?
- toupper(*ttn) :
- *ttn);
- }
- ttn = (char *)sb_out; /* Point back to beginning */
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- sb_out[i] = '\0'; /* For debugging */
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,"TELNET SENT SB ",
- TELOPT(TELOPT_TTYPE)," IS ",(char *)sb_out+4," IAC SE",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-#ifndef NOTERM
-#ifdef OS2
- if (settype)
- settermtype(tt_type,0);
- else {
- ipadl25();
- VscrnIsDirty(VTERM);
- }
-#endif /* OS2 */
-#endif /* NOTERM */
- return(1);
-}
-
-#ifdef CK_ENVIRONMENT
-#ifdef CK_XDISPLOC
-
-/* Telnet send xdisplay location */
-/* Returns -1 on error, 0 if nothing happens, 1 if type sent successfully */
-
-int
-tn_sxdisploc() { /* Send telnet X display location. */
- char * disp=NULL;
- int i,rc;
-
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_XDISPLOC)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
-#ifdef CK_FORWARD_X
- if (TELOPT_U(TELOPT_FORWARD_X)) {
- disp = NULL;
- } else
-#endif /* CK_FORWARD_X */
- disp = (char *)tn_get_display();
- debug(F110,"tn_sxdisploc",disp,0);
-
- if (!disp) {
- /* Can't do both, send WONT */
- if (tn_sopt(WONT,TELOPT_XDISPLOC) < 0)
- return(-1);
- TELOPT_UNANSWERED_WONT(TELOPT_XDISPLOC) = 1;
- return(0);
- }
-
- sb_out[0] = (CHAR) IAC; /* I Am a Command */
- sb_out[1] = (CHAR) SB; /* Subnegotiation */
- sb_out[2] = TELOPT_XDISPLOC; /* X-Display Location */
- sb_out[3] = (CHAR) 0; /* Is... */
- for (i = 4; *disp; disp++,i++) { /* Copy and uppercase it */
- sb_out[i] = (char) *disp;
- }
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- sb_out[i] = '\0'; /* For debugging */
- ckmakxmsg( tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_XDISPLOC),
- " IS ",(char *)sb_out+4," IAC SE",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- return(1);
-}
-#endif /* CK_XDISPLOC */
-#endif /* CK_ENVIRONMENT */
-
-#ifdef CK_FORWARD_X
-int
-tn_sndfwdx() { /* Send Fwd X Screen number to host */
- unsigned char screen = 0;
- char * disp;
- int i,rc;
-
- /* if (!IS_TELNET()) return(0); */
-
- if (!TELOPT_U(TELOPT_FORWARD_X)) return(0);
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- /*
- * The format of the DISPLAY variable is [<host>:]<display>[.<screen>]
- * where <host> is an optional DNS name or ip address with a default of
- * the localhost; the screen defaults to 0
- */
-
- disp = (char *)tn_get_display();
- if (disp) {
- int colon,dot;
- colon = ckindex(":",disp,0,0,1);
- dot = ckindex(".",&disp[colon],0,0,1);
-
- if ( dot ) {
- screen = atoi(&disp[colon+dot]);
- }
- } else {
- screen = 0;
- }
-
- i = 0;
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_FORWARD_X; /* Forward X */
- sb_out[i++] = FWDX_SCREEN; /* Screen */
- sb_out[i++] = screen;
- if ( screen == IAC )
- sb_out[i++] = IAC;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg( tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_FORWARD_X),
- " SCREEN ",ckctox(screen,1)," IAC SE",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- return(0);
-}
-#endif /* CK_FORWARD_X */
-
-#ifdef CK_SNDLOC
-int
-tn_sndloc() { /* Send location. */
- int i,rc; /* Worker. */
- char *ttloc;
-
- /* if (!IS_TELNET()) return(0); */
-
- if (!TELOPT_ME(TELOPT_SNDLOC)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
- ttloc = (tn_loc ? tn_loc : ""); /* In case we are being called even */
- /* though there is no location. */
- sb_out[0] = (CHAR) IAC; /* I Am a Command */
- sb_out[1] = (CHAR) SB; /* Subnegotiation */
- sb_out[2] = TELOPT_SNDLOC; /* Location */
- for (i = 3; *ttloc && i < TSBUFSIZ; ttloc++,i++) /* Copy it */
- sb_out[i] = (char) *ttloc;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_SNDLOC)," ",(char *)sb_out+3,
- " IAC SE", NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- sb_out[i-2] = '\0'; /* For debugging */
- return(0);
-}
-#endif /* CK_SNDLOC */
-
-#ifdef CK_NAWS /* NAWS = Negotiate About Window Size */
-int
-tn_snaws() { /* Send terminal width and height, RFC 1073 */
-#ifndef NOLOCAL
- CHAR sb_out[24]; /* multiple threads */
- int i = 0,rc;
-#ifdef OS2
- int x = VscrnGetWidth(VTERM),
- y = VscrnGetHeight(VTERM) - (tt_status[VTERM] ? 1 : 0);
-#else /* OS2 */
- int x = tt_cols, y = tt_rows;
-#endif /* OS2 */
-
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
- if (!TELOPT_ME(TELOPT_NAWS)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
- if (x < 0) x = 0;
- if (y < 0) y = 0;
-
- if (x == TELOPT_SB(TELOPT_NAWS).naws.x && /* Only send if changed */
- y == TELOPT_SB(TELOPT_NAWS).naws.y
- )
- return(0);
- TELOPT_SB(TELOPT_NAWS).naws.x = x; /* Remember the size */
- TELOPT_SB(TELOPT_NAWS).naws.y = y;
-
- sb_out[i++] = (CHAR) IAC; /* Send the subnegotiation */
- sb_out[i++] = (CHAR) SB;
- sb_out[i++] = TELOPT_NAWS;
- sb_out[i++] = (CHAR) (x >> 8) & 0xff;
- if ((CHAR) sb_out[i-1] == (CHAR) IAC) /* IAC in data must be doubled */
- sb_out[i++] = (CHAR) IAC;
- sb_out[i++] = (CHAR) (x & 0xff);
- if ((CHAR) sb_out[i-1] == (CHAR) IAC)
- sb_out[i++] = (CHAR) IAC;
- sb_out[i++] = (CHAR) (y >> 8) & 0xff;
- if ((CHAR) sb_out[i-1] == (CHAR) IAC)
- sb_out[i++] = (CHAR) IAC;
- sb_out[i++] = (CHAR) (y & 0xff);
- if ((CHAR) sb_out[i-1] == (CHAR) IAC)
- sb_out[i++] = (CHAR) IAC;
- sb_out[i++] = (CHAR) IAC;
- sb_out[i++] = (CHAR) SE;
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,"TELNET SENT SB NAWS ",
- ckitoa(x)," ",ckitoa(y)," IAC SE",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-#endif /* NOLOCAL */
- return (0);
-}
-#endif /* CK_NAWS */
-
-#ifdef TN_COMPORT
-static char * tnc_signature = NULL;
-static int tnc_ls_mask = 0;
-static int tnc_ls = 0;
-static int tnc_ms_mask = 255;
-static int tnc_ms = 0;
-static int tnc_oflow = 0;
-static int tnc_iflow = 0;
-static int tnc_bps = 0;
-static int tnc_datasize = 0;
-static int tnc_parity = 0;
-static int tnc_stopbit = 0;
-static int tnc_break = 0;
-static int tnc_dtr = 0;
-static int tnc_rts = 0;
-static int tnc_suspend_xmit = 0;
-static int tnc_bps_index = -1;
-
-int
-#ifdef CK_ANSIC
-tnc_init(void)
-#else /* CK_ANSIC */
-tnc_init()
-#endif /* CK_ANSIC */
-/* tnc_init */ {
- debug(F100,"tnc_init","",0);
-
- /* if (!IS_TELNET()) return(0); */
-
- if (tnc_signature) {
- free(tnc_signature);
- tnc_signature = NULL;
- }
- tnc_ls_mask = 0;
- tnc_ls = 0;
- tnc_ms_mask = 255;
- tnc_ms = 0;
- tnc_oflow = 0;
- tnc_iflow = 0;
- tnc_bps = 0;
- tnc_datasize = 0;
- tnc_parity = 0;
- tnc_stopbit = 0;
- tnc_break = 0;
- tnc_dtr = 0;
- tnc_rts = 0;
- tnc_suspend_xmit = 0;
- tnc_bps_index = -1;
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-tn_sndcomport(void)
-#else /* CK_ANSIC */
-tn_sndcomport()
-#endif /* CK_ANSIC */
-/* tn_sndcomport */ {
- int baud, datasize, parity, stopsize, oflow, iflow;
- CONST char * signature;
-
- /* if (!IS_TELNET()) return(0); */
-
- debug(F100,"tnc_sndcomport","",0);
- signature = tnc_get_signature();
- baud = tnc_get_baud();
- datasize = tnc_get_datasize();
- parity = tnc_get_parity();
- stopsize = tnc_get_stopsize();
- oflow = tnc_get_oflow();
- iflow = tnc_get_iflow();
- tnc_set_ls_mask(255);
- tnc_set_ms_mask(255);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_wait(CHAR * msg, int ms)
-#else /* CK_ANSIC */
-tnc_wait(msg, ms) CHAR * msg; int ms;
-#endif /* CK_ANSIC */
-/* tnc_wait */ {
- int rc, tn_wait_save = tn_wait_flg;
-
- /* if (!IS_TELNET()) return(0); */
-
- debug(F111,"tnc_wait","begin",ms);
- if ( ms )
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_ms = 1;
- else
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 1;
- tn_wait_flg = 1;
- rc = tn_wait((char *)msg);
- tn_push();
- debug(F110,"tnc_wait","end",0);
- tn_wait_flg = tn_wait_save;
- return(rc);
-}
-
-/* Returns -1 on error, 0 on success */
-/* In order for this code to work, sb[len] == IAC */
-
-int
-#ifdef CK_ANSIC
-tnc_tn_sb(CHAR * sb, int len)
-#else
-tnc_tn_sb(sb, len) CHAR * sb; int len;
-#endif /* CK_ANSIC */
-/* tnc_tn_sb */ {
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
- if (!sb) return(-1);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- debug(F111,"tnc_tn_sb","sb[0]",sb[0]);
- debug(F111,"tnc_tn_sb","len",len);
-
- switch (sb[0]) {
- case TNC_C2S_SIGNATURE:
- case TNC_S2C_SIGNATURE:
- debug(F111,"tnc_tn_sb","signature",len);
- if (len == 1) {
- tnc_send_signature("Kermit Telnet Com Port Option");
- } else {
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- if (tnc_signature)
- free(tnc_signature);
- tnc_signature = malloc(len);
- if (tnc_signature) {
- memcpy(tnc_signature,&sb[1],len-1);
- tnc_signature[len-1] = '\0';
- }
- }
- break;
-
- case TNC_C2S_SET_BAUDRATE:
- case TNC_S2C_SET_BAUDRATE: {
- long baudrate;
- char * br = (char *)&baudrate;
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- if (len == 2) {
- /* Actual behavior of the Access Server... */
- debug(F111,"tnc_tn_sb","baudrate index",sb[1]);
- tnc_bps_index = 1;
- switch (sb[1]) {
- case TNC_BPS_300:
- tnc_bps = 300;
- break;
- case TNC_BPS_600:
- tnc_bps = 600;
- break;
- case TNC_BPS_1200:
- tnc_bps = 1200;
- break;
- case TNC_BPS_2400:
- tnc_bps = 2400;
- break;
- case TNC_BPS_4800:
- tnc_bps = 4800;
- break;
- case TNC_BPS_9600:
- tnc_bps = 9600;
- break;
- case TNC_BPS_14400:
- tnc_bps = 14400;
- break;
- case TNC_BPS_19200:
- tnc_bps = 19200;
- break;
- case TNC_BPS_28800:
- tnc_bps = 28800;
- break;
- case TNC_BPS_38400:
- tnc_bps = 38400;
- break;
- case TNC_BPS_57600:
- tnc_bps = 57600;
- break;
- case TNC_BPS_115200:
- tnc_bps = 115200;
- break;
- case TNC_BPS_230400:
- tnc_bps = 230400;
- break;
- case TNC_BPS_460800:
- tnc_bps = 460800;
- break;
- default:
- tnc_bps = -1;
- }
- } else if (len == 5) {
- /* This section attempts to follow RFC 2217 */
- tnc_bps_index = 0;
- br[0] = sb[1];
- br[1] = sb[2];
- br[2] = sb[3];
- br[3] = sb[4];
-#ifdef datageneral
- /* AOS/VS doesn't have ntohl() but MV's are big-endian */
- tnc_bps = baudrate;
-#else
- tnc_bps = ntohl(baudrate);
-#endif /* datageneral */
- debug(F111,"tnc_tn_sb","baudrate rfc",tnc_bps);
- } else {
- debug(F111,"tnc_tn_sb","baudrate invalid len",len);
- return(-1);
- }
- break;
- }
- case TNC_C2S_SET_DATASIZE:
- case TNC_S2C_SET_DATASIZE:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- if (len < 2)
- return(-1);
- tnc_datasize = sb[1];
- debug(F111,"tnc_tn_sb","datasize",sb[1]);
- break;
-
- case TNC_C2S_SET_PARITY:
- case TNC_S2C_SET_PARITY:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- if (len < 2)
- return(-1);
- tnc_parity = sb[1];
- debug(F111,"tnc_tn_sb","parity",sb[1]);
- break;
-
- case TNC_C2S_SET_STOPSIZE:
- case TNC_S2C_SET_STOPSIZE:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- if (len < 2)
- return(-1);
- tnc_stopbit = sb[1];
- debug(F111,"tnc_tn_sb","stopsize",sb[1]);
- break;
-
- case TNC_C2S_SET_CONTROL:
- case TNC_S2C_SET_CONTROL:
- if (len < 2) {
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- return(-1);
- }
-
-#ifdef COMMENT
- /* This line should be removed when testing is complete. */
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
-#endif /* COMMENT */
-
- switch ( sb[1] ) {
- case TNC_CTL_OFLOW_REQUEST:
- /* determine local outbound flow control and send to peer */
- /* Cisco IOS returns 0 (TNC_CTL_OFLOW_REQUEST) when attempting */
- /* to set the inbound flow control if it is not supported */
- /* separately from outbound flow control. So must reset */
- /* wait for sb flag. */
- debug(F110,"tnc_tn_sb","oflow request",0);
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- break;
- case TNC_CTL_OFLOW_NONE:
- case TNC_CTL_OFLOW_XON_XOFF:
- case TNC_CTL_OFLOW_RTS_CTS:
- case TNC_CTL_OFLOW_DCD:
- case TNC_CTL_OFLOW_DSR:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- tnc_oflow = sb[1];
- debug(F111,"tnc_tn_sb","oflow",sb[1]);
- break;
- case TNC_CTL_BREAK_REQUEST:
- /* determine local break state and send to peer */
- debug(F110,"tnc_tn_sb","break request",0);
- break;
- case TNC_CTL_BREAK_ON:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- tnc_break = 1;
- debug(F110,"tnc_tn_sb","break on",0);
- break;
-
- case TNC_CTL_BREAK_OFF:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- tnc_break = 0;
- debug(F110,"tnc_tn_sb","break off",0);
- break;
-
- case TNC_CTL_DTR_REQUEST:
- /* determine local dtr state and send to peer */
- debug(F110,"tnc_tn_sb","dtr request",0);
- break;
-
- case TNC_CTL_DTR_ON:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- tnc_dtr = 1;
- debug(F110,"tnc_tn_sb","dtr on",0);
- break;
-
- case TNC_CTL_DTR_OFF:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- tnc_dtr = 0;
- debug(F110,"tnc_tn_sb","dtr off",0);
- break;
-
- case TNC_CTL_RTS_REQUEST:
- /* determine local rts state and send to peer */
- debug(F110,"tnc_tn_sb","rts request",0);
- break;
-
- case TNC_CTL_RTS_ON:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- tnc_rts = 1;
- debug(F110,"tnc_tn_sb","rts on",0);
- break;
-
- case TNC_CTL_RTS_OFF:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- tnc_rts = 0;
- debug(F110,"tnc_tn_sb","rts off",0);
- break;
-
- case TNC_CTL_IFLOW_REQUEST:
- /* determine local inbound flow control and send to peer */
- debug(F110,"tnc_tn_sb","iflow request",0);
- break;
-
- case TNC_CTL_IFLOW_NONE:
- case TNC_CTL_IFLOW_XON_XOFF:
- case TNC_CTL_IFLOW_RTS_CTS:
- case TNC_CTL_IFLOW_DTR:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- tnc_iflow = sb[1];
- debug(F111,"tnc_tn_sb","iflow",sb[1]);
- break;
- default:
- return(-1);
- }
- break;
-
- case TNC_C2S_NOTIFY_LINESTATE:
- case TNC_S2C_SEND_LS:
- if (len < 2)
- return(-1);
- tnc_ls = sb[1];
- debug(F111,"tnc_tn_sb","linestate",sb[1]);
- if (tn_deb || debses) {
- if (tnc_ls & TNC_MS_DATA_READY )
- tn_debug(" ComPort Linestate Data Ready");
- if (tnc_ls & TNC_MS_OVERRUN_ERROR )
- tn_debug(" ComPort Linestate Overrun Error");
- if (tnc_ls & TNC_MS_PARITY_ERROR )
- tn_debug(" ComPort Linestate Parity Error");
- if (tnc_ls & TNC_MS_FRAME_ERROR )
- tn_debug(" ComPort Linestate Framing Error");
- if (tnc_ls & TNC_MS_BREAK_ERROR )
- tn_debug(" ComPort Linestate Break Detect Error");
- if (tnc_ls & TNC_MS_HR_EMPTY )
- tn_debug(" ComPort Linestate Holding Register Empty");
- if (tnc_ls & TNC_MS_SR_EMPTY )
- tn_debug(" ComPort Linestate Shift Register Empty");
- if (tnc_ls & TNC_MS_TIMEOUT_ERROR )
- tn_debug(" ComPort Linestate Timeout Error");
- }
- break;
-
- case TNC_C2S_NOTIFY_MODEMSTATE:
- case TNC_S2C_SEND_MS:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_ms = 0;
- if (len < 2)
- return(-1);
- tnc_ms = sb[1];
- debug(F111,"tnc_tn_sb","modemstate",sb[1]);
- if (tn_deb || debses) {
- if (tnc_ms & TNC_MS_CTS_DELTA )
- tn_debug(" ComPort Modemstate CTS State Change");
- if (tnc_ms & TNC_MS_DSR_DELTA )
- tn_debug(" ComPort Modemstate DSR State Change");
- if (tnc_ms & TNC_MS_EDGE_RING )
- tn_debug(" ComPort Modemstate Trailing Edge Ring Detector On");
- else
- tn_debug(" ComPort Modemstate Trailing Edge Ring Detector Off");
- if (tnc_ms & TNC_MS_RLSD_DELTA )
- tn_debug(" ComPort Modemstate RLSD State Change");
- if (tnc_ms & TNC_MS_CTS_SIG )
- tn_debug(" ComPort Modemstate CTS Signal On");
- else
- tn_debug(" ComPort Modemstate CTS Signal Off");
- if (tnc_ms & TNC_MS_DSR_SIG )
- tn_debug(" ComPort Modemstate DSR Signal On");
- else
- tn_debug(" ComPort Modemstate DSR Signal Off");
- if (tnc_ms & TNC_MS_RI_SIG )
- tn_debug(" ComPort Modemstate Ring Indicator On");
- else
- tn_debug(" ComPort Modemstate Ring Indicator Off");
- if (tnc_ms & TNC_MS_RLSD_SIG )
- tn_debug(" ComPort Modemstate RLSD Signal On");
- else
- tn_debug(" ComPort Modemstate RLSD Signal Off");
- }
- break;
-
- case TNC_C2S_FLOW_SUSPEND:
- case TNC_S2C_FLOW_SUSPEND:
- debug(F110,"tnc_tn_sb","flow suspend",0);
- tnc_suspend_xmit = 1;
- break;
-
- case TNC_C2S_FLOW_RESUME:
- case TNC_S2C_FLOW_RESUME:
- debug(F110,"tnc_tn_sb","flow resume",0);
- tnc_suspend_xmit = 0;
- break;
-
- case TNC_C2S_SET_LS_MASK:
- case TNC_S2C_SET_LS_MASK:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- if (len < 2)
- return(-1);
- debug(F111,"tnc_tn_sb","linestate mask",sb[1]);
- tnc_ls_mask = sb[1];
- break;
-
- case TNC_C2S_SET_MS_MASK:
- case TNC_S2C_SET_MS_MASK:
- TELOPT_SB(TELOPT_COMPORT).comport.wait_for_sb = 0;
- if (len < 2)
- return(-1);
- debug(F111,"tnc_tn_sb","modemstate mask",sb[1]);
- tnc_ls_mask = sb[1];
- break;
-
- case TNC_C2S_PURGE:
- case TNC_S2C_PURGE:
- if (len < 2)
- return(-1);
- debug(F111,"tnc_tn_sb","purge",sb[1]);
- switch ( sb[1] ) {
- case TNC_PURGE_RECEIVE:
- case TNC_PURGE_TRANSMIT:
- case TNC_PURGE_BOTH:
- /* purge local buffers */
- break;
- default:
- return(-1);
- }
- break;
- default:
- return(-1);
- }
- return(0);
-}
-
-CONST char *
-#ifdef CK_ANSIC
-tnc_get_signature(void)
-#else /* CK_ANSIC */
-tnc_get_signature()
-#endif /* CK_ANSIC */
-/* tnc_get_signature */ {
- /* send IAC SB COM-PORT SIGNATURE IAC SE */
- /* wait for response */
- int i = 0, rc;
-
- if (ttnet != NET_TCPB) return(NULL);
- if (ttnproto != NP_TELNET) return(NULL);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(NULL);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(NULL);
- }
-#endif /* CK_SSL */
-
- if ( tnc_signature )
- return(tnc_signature);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SIGNATURE; /* Signature */
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SIGNATURE IAC SE", NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(NULL);
-
- if (tnc_wait((CHAR *)"comport signature request",0) < 0) {
- tn_push();
- return(NULL);
- }
- debug(F110,"tnc_get_signature",tnc_signature,0);
- return(tnc_signature);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_send_signature(char * signature)
-#else /* CK_ANSIC */
-tnc_send_signature(signature) char * signature;
-#endif /* CK_ANSIC */
-/* tnc_send_signature */ {
- /* send IAC SB COM-PORT SIGNATURE <text> IAC SE */
- int i = 0, j = 0, rc;
-
- debug(F110,"tnc_send_signature",signature,0);
-
- if (!signature || !signature[0])
- return(0);
-
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SIGNATURE; /* Signature */
- for (; signature[j]; i++,j++)
- sb_out[i] = signature[j];
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SIGNATURE ", signature, " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_baud( long baud )
-#else /* CK_ANSIC */
-tnc_set_baud(baud) long baud;
-#endif /* CK_ANSIC */
-/* tnc_set_baud */ {
- /* send IAC SB COM-PORT SET-BAUD <value(4)> IAC SE */
- /* wait for response */
- /* 0 is used to request the current baud rate and */
- /* may not be sent by this func */
- /* return new host value */
-
- /*
- * the above comes from the RFC. But that is not what I am seeing
- * instead I appear to be seeing to following:
- *
- * Value Baud
- * 1 ?
- * 2 ?
- * 3 300
- * 4 600
- * 5 1200
- * 6 2400
- * 7 4800 ?
- * 8 9600
- * 9 ?
- * 10 19200 ?
- * 11 ?
- * 12 38400
- * 13 57600 ?
- * 14 115200
- * 15 230400 ?
- * 16 460800 ?
- */
-
- int i = 0, rc;
-#ifdef datageneral
- /* AOS/VS doesn't have htonl() but MV's are big-endian */
- long net_baud = baud;
-#else
- long net_baud = htonl(baud);
-#endif /* datageneral */
- CHAR b;
-
- debug(F111,"tnc_set_baud","begin",baud);
-
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if (baud <= 0)
- return(0);
-
- if ( net_baud != 0 && net_baud == tnc_bps)
- return(tnc_bps);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_BAUDRATE; /* Set Baud Rate */
-
- if (tnc_bps_index) {
- /* IOS Access Server */
- if (baud <= 300)
- b = TNC_BPS_300;
- else if (baud <= 600)
- b = TNC_BPS_600;
- else if (baud <= 1200)
- b = TNC_BPS_1200;
- else if (baud <= 2400)
- b = TNC_BPS_2400;
- else if (baud <= 4800)
- b = TNC_BPS_4800;
- else if (baud <= 9600)
- b = TNC_BPS_9600;
- else if (baud <= 14400)
- b = TNC_BPS_14400;
- else if (baud <= 19200)
- b = TNC_BPS_19200;
- else if (baud <= 28800)
- b = TNC_BPS_28800;
- else if (baud <= 38400)
- b = TNC_BPS_38400;
- else if (baud <= 57600)
- b = TNC_BPS_57600;
- else if (baud <= 115200)
- b = TNC_BPS_115200;
- else if (baud <= 230400)
- b = TNC_BPS_230400;
- else
- b = TNC_BPS_460800;
- sb_out[i++] = b;
- } else {
- /* RFC 2217 */
- sb_out[i++] = ((char *)&net_baud)[0];
- sb_out[i++] = ((char *)&net_baud)[1];
- sb_out[i++] = ((char *)&net_baud)[2];
- sb_out[i++] = ((char *)&net_baud)[3];
- }
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-BAUD-RATE ", ckltoa(baud)," IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport set baud rate",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_set_baud","end",tnc_bps);
- return(tnc_bps);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_baud(void)
-#else /* CK_ANSIC */
-tnc_get_baud()
-#endif /* CK_ANSIC */
-/* tnc_get_baud */ {
- /* send IAC SB COM-PORT SET-BAUD <value(4)=0> IAC SE */
- /* wait for response */
- int i = 0, rc;
-
- debug(F110,"tnc_get_baud","begin",0);
-
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_BAUDRATE; /* Set Baud Rate */
-
- if (tnc_bps_index > 0) {
- /* Access Server */
- sb_out[i++] = 0;
- } else {
- /* RFC 2217 */
- sb_out[i++] = 0;
- sb_out[i++] = 0;
- sb_out[i++] = 0;
- sb_out[i++] = 0;
- }
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-BAUD-RATE ", ckltoa(0)," IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport get baud rate",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_get_baud","end",tnc_bps);
- return(tnc_bps);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_datasize(int datasize)
-#else /* CK_ANSIC */
-tnc_set_datasize(datasize) int datasize;
-#endif /* CK_ANSIC */
-/* tnc_set_datasize */ {
- /* IAC SB COM-PORT SET_DATASIZE <value(1)> IAC SE */
- /* Valid <value>s are 5 through 8 */
- /* Wait for response */
- /* return new host value */
-
- int i = 0, rc;
-
- debug(F111,"tnc_set_datasize","begin",datasize);
-
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if ( !(datasize >= 5 && datasize <= 8) )
- return(0);
-
- if ( datasize != 0 && datasize == tnc_datasize )
- return(tnc_datasize);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_DATASIZE; /* Set DataSize */
- sb_out[i++] = (unsigned char)(datasize & 0xFF);
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-DATASIZE ", ckitoa(datasize)," IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport set datasize",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_set_datasize","end",tnc_datasize);
- return(tnc_datasize);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_datasize(void)
-#else /* CK_ANSIC */
-tnc_get_datasize()
-#endif /* CK_ANSIC */
-/* tnc_get_datasize */ {
- /* IAC SB COM-PORT SET_DATASIZE <value(1)=0> IAC SE */
- /* Wait for response */
- int i = 0, rc;
-
- debug(F110,"tnc_get_datasize","begin",0);
-
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_DATASIZE; /* Set DataSize */
- sb_out[i++] = 0;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-DATASIZE ", ckltoa(0)," IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport get datasize",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_get_datasize","end",tnc_datasize);
- return(tnc_datasize);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_parity(int parity)
-#else /* CK_ANSIC */
-tnc_set_parity(parity) int parity;
-#endif /* CK_ANSIC */
-/* tnc_set_parity */ {
- /* IAC SB COM-PORT SET_PARITY <value(1)> IAC SE */
- /* Value Parity
- * 1 None
- * 2 Odd
- * 3 Even
- * 4 Mark
- * 5 Space
- */
- /* Wait for response. Return new host value. */
- int i = 0, rc;
-
- debug(F110,"tnc_set_parity","begin",parity);
-
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if ( !(parity >= 1 && parity <= 5) )
- return(0);
-
- if ( parity != 0 && parity == tnc_parity )
- return(tnc_parity);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_PARITY; /* Set Parity */
- sb_out[i++] = (unsigned char)(parity & 0xFF);
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-PARITY ", ckitoa(parity)," IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport set parity",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_set_parity","end",tnc_parity);
- return(tnc_parity);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_parity(void)
-#else /* CK_ANSIC */
-tnc_get_parity()
-#endif /* CK_ANSIC */
-/* tnc_get_parity */ {
- /* IAC SB COM-PORT SET_PARITY <value(1)=0> IAC SE */
- /* wait for response */
- int i = 0, rc;
-
- debug(F110,"tnc_get_parity","begin",0);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_PARITY; /* Set Parity */
- sb_out[i++] = 0;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-PARITY ", ckitoa(0)," IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport get parity",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_get_parity","end",tnc_parity);
- return(tnc_parity);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_stopsize(int stopsize)
-#else /* CK_ANSIC */
-tnc_set_stopsize(stopsize) int stopsize;
-#endif /* CK_ANSIC */
-/* tnc_set_stopsize */ {
- /* IAC SB COM-PORT SET_STOPSIZE <value(1)> IAC SE */
- /* Value Stop Bit Size
- * 1 1
- * 2 2
- * 3 1.5
- */
- /* Wait for response. Return new host value. */
- int i = 0, rc;
-
- debug(F111,"tnc_set_stopsize","begin",stopsize);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if (!(stopsize >= 1 && stopsize <= 3) )
- return(0);
-
- if ( stopsize != 0 && stopsize == tnc_stopbit )
- return(tnc_stopbit);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_STOPSIZE; /* Set Stop Bits */
- sb_out[i++] = (unsigned char)(stopsize & 0xFF);
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-STOPSIZE ", ckitoa(stopsize)," IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport set stopsize",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_set_stopsize","end",tnc_stopbit);
- return(tnc_stopbit);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_stopsize(void)
-#else /* CK_ANSIC */
-tnc_get_stopsize()
-#endif /* CK_ANSIC */
-/* tnc_get_stopsize */ {
- /* IAC SB COM-PORT SET_STOPSIZE <value(1)=0> IAC SE */
- /* Wait for response */
- int i = 0, rc;
-
- debug(F110,"tnc_get_stopsize","begin",0);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_STOPSIZE; /* Set Stop Bits */
- sb_out[i++] = 0;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-STOPSIZE ", ckitoa(0)," IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport set stopsize",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_get_stopsize","end",tnc_stopbit);
- return(tnc_stopbit);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_oflow(int control)
-#else /* CK_ANSIC */
-tnc_set_oflow(control) int control;
-#endif /* CK_ANSIC */
-/* tnc_set_oflow */ {
- /* IAC SB COM_PORT SET_CONTROL <value(1)> IAC SE */
- /* Value Flow Control
- * 1 No Flow Control
- * 2 Xon/Xoff
- * 3 Rts/Cts
- * 17 DCD
- * 19 DSR
- */
- /* wait for response, return new host value. */
- int i = 0, rc;
-
- debug(F111,"tnc_set_oflow","begin",control);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if (control != 1 && control != 2 && control != 3 &&
- control != 17 && control != 19)
- return(0);
-
- if ( control != 0 && control == tnc_oflow )
- return(tnc_oflow);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_CONTROL; /* Set Control */
- sb_out[i++] = (unsigned char)(control & 0xFF);
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-CONTROL ", ckitoa(control)," IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport set outbound flow control",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_set_oflow","end",tnc_oflow);
- return(tnc_oflow);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_oflow(void)
-#else /* CK_ANSIC */
-tnc_get_oflow()
-#endif /* CK_ANSIC */
-/* tnc_get_oflow */ {
- /* IAC SB COM_PORT SET_CONTROL <value(1)=0> IAC SE */
- /* wait for response */
- int i = 0, rc;
-
- debug(F110,"tnc_get_oflow","begin",0);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_CONTROL; /* Set Control */
- sb_out[i++] = TNC_CTL_OFLOW_REQUEST;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-CONTROL ",
- ckitoa(TNC_CTL_OFLOW_REQUEST),
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport get outbound flow control",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_get_oflow","end",tnc_oflow);
- return(tnc_oflow);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_iflow(int control)
-#else /* CK_ANSIC */
-tnc_set_iflow(control) int control;
-#endif /* CK_ANSIC */
-/* tnc_set_iflow */ {
- /* IAC SB COM_PORT SET_CONTROL <value(1)> IAC SE */
- /* Value Flow Control
- * 14 No Flow Control
- * 15 Xon/Xoff
- * 16 Rts/Cts
- * 18 DTR
- */
- /* wait for response, return new host value. */
- int i = 0, rc;
-
- debug(F111,"tnc_set_iflow","begin",control);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if (control != 14 && control != 15 && control != 16 && control != 18)
- return(0);
-
- if ( control != 0 && control == tnc_iflow )
- return(tnc_iflow);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_CONTROL; /* Set Control */
- sb_out[i++] = (unsigned char)(control & 0xFF);
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-CONTROL ", ckitoa(control)," IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport set inbound flow control",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_set_iflow","end",tnc_iflow);
- return(tnc_iflow);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_iflow(void)
-#else /* CK_ANSIC */
-tnc_get_iflow()
-#endif /* CK_ANSIC */
-/* tnc_get_iflow */ {
- /* IAC SB COM_PORT SET_CONTROL <value(1)=13> IAC SE */
- /* wait for response */
- int i = 0, rc;
-
- debug(F110,"tnc_get_iflow","begin",0);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_CONTROL; /* Set Control */
- sb_out[i++] = TNC_CTL_IFLOW_REQUEST;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-CONTROL ",
- ckitoa(TNC_CTL_IFLOW_REQUEST),
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport get inbound flow control",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_get_iflow","end",tnc_iflow);
- return(tnc_iflow);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_break_state(int onoff)
-#else /* CK_ANSIC */
-tnc_set_break_state(onoff) int onoff;
-#endif /* CK_ANSIC */
-/* tnc_set_break_state */ {
- /* IAC SB COM_PORT SET_CONTROL <value(1)> IAC SE */
- /* Value Break State
- * 5 On
- * 6 Off
- */
- /* wait for response, return new host value. */
- int i = 0, rc;
-
- debug(F111,"tnc_set_break_state","begin",onoff);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if ( onoff != 0 && onoff == tnc_break )
- return(tnc_break);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_CONTROL; /* Set Control */
- sb_out[i++] = onoff ?
- TNC_CTL_BREAK_ON : TNC_CTL_BREAK_OFF;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-CONTROL ",
- onoff ? "BREAK-ON" : "BREAK-OFF",
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport set break state",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_set_break_state","end",tnc_break);
- return(tnc_break);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_break_state(void)
-#else /* CK_ANSIC */
-tnc_get_break_state()
-#endif /* CK_ANSIC */
-/* tnc_get_break_state */ {
- /* IAC SB COM_PORT SET_CONTROL <value(1)=4> IAC SE */
- /* wait for response */
- int i = 0, rc;
-
- debug(F110,"tnc_get_break_state","begin",0);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_CONTROL; /* Set Control */
- sb_out[i++] = TNC_CTL_BREAK_REQUEST;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-CONTROL ",
- "BREAK-REQUEST",
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport get break state",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_get_break_state","end",tnc_break);
- return(tnc_break);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_dtr_state(int onoff)
-#else /* CK_ANSIC */
-tnc_set_dtr_state(onoff) int onoff;
-#endif /* CK_ANSIC */
-/* tnc_set_dtr_state */ {
- /* IAC SB COM_PORT SET_CONTROL <value(1)> IAC SE */
- /* Value Dtr State
- * 8 On
- * 9 Off
- */
- /* wait for response, return new host value. */
- int i = 0, rc;
-
- debug(F111,"tnc_set_dtr_state","begin",onoff);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if ( onoff != 0 && onoff == tnc_dtr )
- return(tnc_dtr);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_CONTROL; /* Set Control */
- sb_out[i++] = onoff ?
- TNC_CTL_DTR_ON : TNC_CTL_DTR_OFF;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-CONTROL ",
- onoff ? "DTR-ON" : "DTR-OFF",
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport set dtr state",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_set_dtr_state","end",tnc_dtr);
- return(tnc_dtr);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_dtr_state(void)
-#else /* CK_ANSIC */
-tnc_get_dtr_state()
-#endif /* CK_ANSIC */
-/* tnc_get_dtr_state */ {
- /* IAC SB COM_PORT SET_CONTROL <value(1)=7> IAC SE */
- /* wait for response */
- int i = 0, rc;
-
- debug(F110,"tnc_get_dtr_state","begin",0);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_CONTROL; /* Set Control */
- sb_out[i++] = TNC_CTL_DTR_REQUEST;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-CONTROL ",
- "DTR-REQUEST",
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport get dtr state",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_get_dtr_state","end",tnc_dtr);
- return(tnc_dtr);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_rts_state(int onoff)
-#else /* CK_ANSIC */
-tnc_set_rts_state(onoff) int onoff;
-#endif /* CK_ANSIC */
-/* tnc_set_rts_state */ {
- /* IAC SB COM_PORT SET_CONTROL <value(1)> IAC SE */
- /* Value Rts State
- * 5 On
- * 6 Off
- */
- /* wait for response, return new host value. */
- int i = 0, rc;
-
- debug(F111,"tnc_set_rts_state","begin",onoff);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if ( onoff != 0 && onoff == tnc_rts )
- return(tnc_rts);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_CONTROL; /* Set Control */
- sb_out[i++] = onoff ?
- TNC_CTL_RTS_ON : TNC_CTL_RTS_OFF;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-CONTROL ",
- onoff ? "RTS-ON" : "RTS-OFF",
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport set rts state",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_set_rts_state","end",tnc_rts);
- return(tnc_rts);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_rts_state(void)
-#else /* CK_ANSIC */
-tnc_get_rts_state()
-#endif /* CK_ANSIC */
-/* tnc_get_rts_state */ {
- /* IAC SB COM_PORT SET_CONTROL <value(1)=10> IAC SE */
- /* wait for response */
- int i = 0, rc;
-
- debug(F110,"tnc_get_rts_state","begin",0);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_CONTROL; /* Set Control */
- sb_out[i++] = TNC_CTL_RTS_REQUEST;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-CONTROL ",
- "RTS-REQUEST",
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- if (tnc_wait((CHAR *)"comport get rts state",0) < 0) {
- tn_push();
- return(-1);
- }
- debug(F111,"tnc_get_rts_state","end",tnc_rts);
- return(tnc_rts);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_ls_mask(int mask)
-#else /* CK_ANSIC */
-tnc_set_ls_mask(mask) int mask;
-#endif /* CK_ANSIC */
-/* tnc_set_ls_mask */ {
- /* IAC SB COM_PORT SET_LINESTATE_MASK <value(1)> IAC SE */
- /* Bit Meaning
- * 0 Data Ready
- * 1 Overrun Error
- * 2 Parity Error
- * 3 Framing Error
- * 4 Break Detect Error
- * 5 Transfer Holding Register Empty
- * 6 Transfer Shift Register Empty
- * 7 Timeout Error
- */
- int i = 0, rc;
-
- debug(F111,"tnc_set_ls_mask","begin",mask);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if ( mask != 0 && mask == tnc_ls_mask )
- return(tnc_ls_mask);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_LS_MASK;
- sb_out[i++] = (unsigned char)(mask & 0xFF);
- if (sb_out[i-1] == IAC )
- sb_out[i++] = IAC;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-LINESTATE-MASK ",
- ckitoa(mask & 0xFF),
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- tnc_ls_mask = mask;
- debug(F111,"tnc_set_ls_mask","end",tnc_ls_mask);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_ls_mask(void)
-#else /* CK_ANSIC */
-tnc_get_ls_mask()
-#endif /* CK_ANSIC */
-/* tnc_get_ls_mask */ {
- debug(F101,"tnc_get_ls_mask","",tnc_ls_mask);
- return(tnc_ls_mask);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_ls(void)
-#else /* CK_ANSIC */
-tnc_get_ls()
-#endif /* CK_ANSIC */
-/* tnc_get_ls */ {
- int ls = tnc_ls;
- debug(F101,"tnc_get_ls","",tnc_ls);
- return(ls);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_set_ms_mask(int mask)
-#else /* CK_ANSIC */
-tnc_set_ms_mask(mask) int mask;
-#endif /* CK_ANSIC */
-/* tnc_set_ms_mask */ {
- /* IAC SB COM_PORT SET_MODEMSTATE_MASK <value(1)> IAC SE */
- /* Bit Meaning
- * 0 Delta Clear To Send
- * 1 Delta Data Set Ready
- * 2 Trailing Edge Ring Detector
- * 3 Delta Receive Line Signal (Carrier) Detect
- * 4 Clear To Send Signal State
- * 5 Data-Set-Ready Signal State
- * 6 Ring Indicator
- * 7 Receive Line Signal (Carrier) Detect
- */
-
- int i = 0, rc;
-
- debug(F111,"tnc_set_ms_mask","begin",mask);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if ( mask != 0 && mask == tnc_ms_mask )
- return(tnc_ms_mask);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_SET_MS_MASK;
- sb_out[i++] = (unsigned char)(mask & 0xFF);
- if (sb_out[i-1] == IAC )
- sb_out[i++] = IAC;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " SET-MODEMSTATE-MASK ",
- ckitoa(mask & 0xFF),
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
-
- tnc_ms_mask = mask;
- debug(F111,"tnc_set_ms_mask","end",tnc_ms_mask);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_ms_mask(void)
-#else /* CK_ANSIC */
-tnc_get_ms_mask()
-#endif /* CK_ANSIC */
-/* tnc_get_ms_mask */ {
- debug(F101,"tnc_get_gs_mask","",tnc_ms_mask);
- return(tnc_ms_mask);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_get_ms(void)
-#else /* CK_ANSIC */
-tnc_get_ms()
-#endif /* CK_ANSIC */
-/* tnc_get_ms */ {
- int ms = tnc_ms;
- debug(F101,"tnc_get_ms","",tnc_ms);
- return(ms);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_send_purge_data(int mode)
-#else /* CK_ANSIC */
-tnc_send_purge_data(mode) int mode;
-#endif /* CK_ANSIC */
-/* tnc_send_purge_data */ {
- /* IAC SB COM_PORT PURGE_DATA <value(1)> IAC SE */
- /* Value Meaning
- * 1 Purge access server receive data buffer
- * 2 Purge access server transmit data buffer
- * 3 Purge access server receive and transmit data buffers
- */
- /* No response */
- int i = 0, rc;
-
- debug(F111,"tnc_send_purge_data","begin",mode);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if ( !(mode >= 1 && mode <= 3) )
- return(0);
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_PURGE;
- sb_out[i++] = (unsigned char)(mode & 0xFF);
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " PURGE-DATA ",
- ckitoa(mode & 0xFF),
- " IAC SE", NULL,
- NULL,NULL,NULL,NULL,NULL,NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- debug(F110,"tnc_send_purge_data","end",0);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_flow_suspended(void)
-#else /* CK_ANSIC */
-tnc_flow_suspended()
-#endif /* CK_ANSIC */
-/* tnc_flow_suspended */ {
- debug(F111,"tnc_flow_suspended","",tnc_suspend_xmit);
- return(tnc_suspend_xmit);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_suspend_flow(void)
-#else /* CK_ANSIC */
-tnc_suspend_flow()
-#endif /* CK_ANSIC */
-/* tnc_suspend_flow */ {
- /* IAC SB COM_PORT FLOWCONTROL_SUSPEND IAC SE */
- int i = 0, rc;
-
- debug(F110,"tnc_suspend_flow","begin",0);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_FLOW_SUSPEND;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " FLOWCONTROL-SUSPEND IAC SE", NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- debug(F110,"tnc_suspend_flow","end",0);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-tnc_resume_flow(void)
-#else /* CK_ANSIC */
-tnc_resume_flow()
-#endif /* CK_ANSIC */
-/* tnc_resume_flow */ {
- /* IAC SB COM_PORT FLOWCONTROL_RESUME IAC SE */
- int i = 0, rc;
-
- debug(F110,"tnc_resume_flow","begin",0);
- if (ttnet != NET_TCPB) return(0);
- if (ttnproto != NP_TELNET) return(0);
-
- if (!TELOPT_ME(TELOPT_COMPORT)) return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- sb_out[i++] = (CHAR) IAC; /* I Am a Command */
- sb_out[i++] = (CHAR) SB; /* Subnegotiation */
- sb_out[i++] = TELOPT_COMPORT; /* ComPort */
- sb_out[i++] = TNC_C2S_FLOW_RESUME;
- sb_out[i++] = (CHAR) IAC; /* End of Subnegotiation */
- sb_out[i++] = (CHAR) SE; /* marked by IAC SE */
-
-#ifdef DEBUG
- if (deblog || tn_deb || debses) {
- ckmakmsg(tn_msg_out,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_COMPORT),
- " FLOWCONTROL-RESUME IAC SE", NULL);
- }
-#endif /* DEBUG */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
-#ifdef DEBUG
- debug(F100,tn_msg_out,"",0);
- if (tn_deb || debses) tn_debug(tn_msg_out);
-#endif /* DEBUG */
- rc = (ttol((CHAR *)sb_out,i) < 0); /* Send it. */
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if (rc)
- return(-1);
- debug(F110,"tnc_resume_flow","end",0);
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-tnsetflow(int nflow)
-#else
-tnsetflow(nflow) int nflow;
-#endif /* CK_ANSIC */
-/* tnsetflow */ {
-
- int rc = -1;
-
- debug(F111,"tnsetflow","begin",nflow);
- if (ttnet != NET_TCPB || ttnproto != NP_TELNET)
- return(-1);
-
- if (TELOPT_ME(TELOPT_COMPORT)) {
- switch(nflow) {
- case FLO_XONX:
- rc = tnc_set_oflow(
- TNC_CTL_OFLOW_XON_XOFF
- );
- if (rc >= 0)
- rc = tnc_set_iflow(
- TNC_CTL_IFLOW_XON_XOFF
- );
- break;
- case FLO_RTSC:
- rc = tnc_set_oflow(
- TNC_CTL_OFLOW_RTS_CTS
- );
- if (rc >= 0)
- rc = tnc_set_iflow(
- TNC_CTL_IFLOW_RTS_CTS
- );
- break;
- case FLO_KEEP:
- /* leave things exactly as they are */
- rc = 0;
- break;
- case FLO_NONE:
- case FLO_DIAL: /* dialing hack */
- case FLO_DIAX: /* cancel dialing hack */
- rc = tnc_set_oflow(
- TNC_CTL_OFLOW_NONE
- );
- if (rc >= 0)
- rc = tnc_set_iflow(
- TNC_CTL_IFLOW_NONE
- );
- break;
- case FLO_DTRC:
- case FLO_ETXA:
- case FLO_STRG:
- case FLO_DTRT:
- default:
- /* not supported */
- rc = -1;
- break;
- }
- }
- debug(F111,"tnsetflow","end",rc);
- return(rc >= 0 ? 0 : -1);
-}
-
-int
-#ifdef CK_ANSIC
-tnsettings(int par, int stop)
-#else
-tnsettings(par, stop) int par, stop;
-#endif /* CK_ANSIC */
-/* tnsettings */ {
- int rc = -1;
- int datasize = 0;
- extern int hwparity;
-
- debug(F111,"tnsettings begin","par",par);
- debug(F111,"tnsettings begin","stop",stop);
- if (ttnet != NET_TCPB || ttnproto != NP_TELNET)
- return(-1);
-
- datasize = par ? TNC_DS_7 : TNC_DS_8;
- if (!par) par = hwparity;
-
- if (TELOPT_ME(TELOPT_COMPORT)) {
- switch (par) {
- case 'e':
- rc = tnc_set_parity(TNC_PAR_EVEN);
- if (rc >= 0)
- rc = tnc_set_datasize(datasize);
- break;
- case 'o':
- rc = tnc_set_parity(TNC_PAR_ODD);
- if (rc >= 0)
- rc = tnc_set_datasize(datasize);
- break;
- case 'm':
- rc = tnc_set_parity(TNC_PAR_MARK);
- if (rc >= 0)
- rc = tnc_set_datasize(datasize);
- break;
- case 's':
- rc = tnc_set_parity(TNC_PAR_SPACE);
- if (rc >= 0)
- rc = tnc_set_datasize(datasize);
- break;
- case 0:
- case 'n':
- rc = tnc_set_parity(TNC_PAR_NONE);
- if (rc >= 0)
- rc = tnc_set_datasize(datasize);
- break;
- default:
- /* no change */
- rc = 0;
- }
- switch(stop) {
- case 2:
- if (rc >= 0)
- rc = tnc_set_stopsize(TNC_SB_2);
- break;
- case 1:
- if (rc >= 0)
- rc = tnc_set_stopsize(TNC_SB_1);
- break;
- default:
- /* no change */
- if (rc >= 0)
- rc = 0;
- }
- }
- debug(F111,"tnsettings","end",rc);
- return((rc >= 0) ? 0 : -1);
-}
-
-/* T N G M D M -- Telnet Get modem signals */
-/*
- Looks for the modem signals CTS, DSR, and CTS, and returns those that are
- on in as its return value, in a bit mask as described for ttwmdm.
- Returns:
- -3 Not implemented
- -2 if the line does not have modem control
- -1 on error.
- >= 0 on success, with a bit mask containing the modem signals that are on.
-*/
-int
-#ifdef CK_ANSIC
-tngmdm(void)
-#else
-tngmdm()
-#endif /* CK_ANSIC */
-/* tngmdm */ {
-
- int rc = -1;
-
- debug(F110,"tngmdm","begin",0);
- if (ttnet != NET_TCPB || ttnproto != NP_TELNET)
- return(-1);
-
- if (TELOPT_ME(TELOPT_COMPORT)) {
- int modemstate = tnc_get_ms();
- int modem = 0;
- if (modemstate & TNC_MS_CTS_SIG)
- modem |= BM_CTS;
- if (modemstate & TNC_MS_DSR_SIG)
- modem |= BM_DSR;
- if (modemstate & TNC_MS_RI_SIG)
- modem |= BM_RNG;
- if (modemstate & TNC_MS_RLSD_SIG)
- modem |= BM_DCD;
- debug(F111,"tngmdm","end",modem);
- return(modem);
- } else {
- debug(F111,"tngmdm","end",-2);
- return(-2);
- }
-}
-
-int
-#ifdef CK_ANSIC
-tnsndb(long wait)
-#else
-tnsndb(wait) long wait;
-#endif /* CK_ANSIC */
-/* tnsndb */ {
- int rc = -1;
-
- debug(F111,"tnsndb","begin",wait);
- if (ttnet != NET_TCPB || ttnproto != NP_TELNET)
- return(-1);
-
- if (TELOPT_ME(TELOPT_COMPORT)) {
- rc = tnc_set_break_state(1);
- if (rc >= 0) {
- msleep(wait); /* ZZZzzz */
- rc = tnc_set_break_state(0);
- }
- }
- debug(F111,"tnsndb","end",rc);
- return((rc >= 0) ? 0 : -1);
-}
-#endif /* TN_COMPORT */
-#endif /* TNCODE */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckctel.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckctel.h
deleted file mode 100644
index 242e396..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckctel.h
+++ /dev/null
@@ -1,1336 +0,0 @@
-/* ckctel.h -- Symbol and macro definitions for C-Kermit telnet support */
-
-/*
- Authors: Jeffrey E Altman <jaltman@secure-endpoints.com>,
- Secure Endpoints Inc., New York City
- Frank da Cruz <fdc@columbia.edu>
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Notes:
- . This file should be used in place of "arpa/telnet.h"
- . Only one source file should include #defines for
- TELCMDS, TELOPTS, TELOPT_STATES, SLC_NAMES, and AUTH_NAMES.
-*/
-
-#ifndef CKCTEL_H
-#define CKCTEL_H
-#ifdef TNCODE
-/*
- Definitions for the TELNET protocol.
- can't rely on library header files for any of them.
-*/
-#ifdef COMMENT
-/* In some compilers these are prone to sign extension */
-
-#ifndef IAC /* First the telnet commands */
-#define IAC 255
-#endif /* IAC */
-#ifndef DONT
-#define DONT 254
-#endif /* DONT */
-#ifndef DO
-#define DO 253
-#endif /* DO */
-#ifndef WONT
-#define WONT 252
-#endif /* WONT */
-#ifndef WILL
-#define WILL 251
-#endif /* WILL */
-#ifndef SB
-#define SB 250
-#endif /* SB */
-#ifndef TN_GA
-#define TN_GA 249
-#endif /* TN_GA */
-#ifndef TN_EL
-#define TN_EL 248
-#endif /* TN_EL */
-#ifndef TN_EC
-#define TN_EC 247
-#endif /* TN_EC */
-#ifndef TN_AYT
-#define TN_AYT 246
-#endif /* TN_AYT */
-#ifndef TN_AO
-#define TN_AO 245
-#endif /* TN_AO */
-#ifndef TN_IP
-#define TN_IP 244
-#endif /* TN_IP */
-#ifndef BREAK
-#define BREAK 243
-#endif /* BREAK */
-#ifndef TN_DM
-#define TN_DM 242
-#endif /* TN_DM */
-#ifndef TN_NOP
-#define TN_NOP 241
-#endif /* TN_NOP */
-#ifndef SE
-#define SE 240
-#endif /* SE */
-#ifndef TN_EOR
-#define TN_EOR 239
-#endif /* TN_EOR */
-#ifndef TN_ABORT
-#define TN_ABORT 238
-#endif /* TN_ABORT */
-#ifndef TN_SUSP
-#define TN_SUSP 237
-#endif /* TN_SUSP */
-#ifndef TN_EOF
-#define TN_EOF 236
-#endif /* TN_EOF */
-#ifndef LAST_TN_CMD
-#define LAST_TN_CMD 236
-
-#define TN_SAK 200 /* IBM Secure Attention Key */
-#endif /* LAST_TN_CMD */
-#define SYNCH 242 /* for telfunc calls */
-
-#else
-/* Hex notation seems to suppress the sugn extension effect */
-
-
-#ifndef IAC /* First the telnet commands */
-#define IAC 0xff
-#endif /* IAC */
-#ifndef DONT
-#define DONT 0xfe /* 254 */
-#endif /* DONT */
-#ifndef DO
-#define DO 0xfd /* 253 */
-#endif /* DO */
-#ifndef WONT
-#define WONT 0xfc /* 252 */
-#endif /* WONT */
-#ifndef WILL
-#define WILL 0xfb /* 251 */
-#endif /* WILL */
-#ifndef SB
-#define SB 0xfa /* 250 */
-#endif /* SB */
-#ifndef TN_GA
-#define TN_GA 0xf9 /* 249 */
-#endif /* TN_GA */
-#ifndef TN_EL
-#define TN_EL 0xf8 /* 248 */
-#endif /* TN_EL */
-#ifndef TN_EC
-#define TN_EC 0xf7 /* 247 */
-#endif /* TN_EC */
-#ifndef TN_AYT
-#define TN_AYT 0xf6 /* 246 */
-#endif /* TN_AYT */
-#ifndef TN_AO
-#define TN_AO 0xf5 /* 245 */
-#endif /* TN_AO */
-#ifndef TN_IP
-#define TN_IP 0xf4 /* 244 */
-#endif /* TN_IP */
-#ifndef BREAK
-#define BREAK 0xf3 /* 243 */
-#endif /* BREAK */
-#ifndef TN_DM
-#define TN_DM 0xf2 /* 242 */
-#endif /* TN_DM */
-#ifndef TN_NOP
-#define TN_NOP 0xf1 /* 241 */
-#endif /* TN_NOP */
-#ifndef SE
-#define SE 0xf0 /* 240 */
-#endif /* SE */
-#ifndef TN_EOR
-#define TN_EOR 0xef /* 239 */
-#endif /* TN_EOR */
-#ifndef TN_ABORT
-#define TN_ABORT 0xee /* 238 */
-#endif /* TN_ABORT */
-#ifndef TN_SUSP
-#define TN_SUSP 0xed /* 237 */
-#endif /* TN_SUSP */
-#ifndef TN_EOF
-#define TN_EOF 0xec /* 236 */
-#endif /* TN_EOF */
-#ifndef LAST_TN_CMD
-#define LAST_TN_CMD 0xec /* 236 */
-
-#define TN_SAK 0xc8 /* 200 - IBM Secure Attention Key */
-#endif /* LAST_TN_CMD */
-#define SYNCH 0xf2 /* 242 - for telfunc calls */
-
-#endif /* COMMENT */
-
-#ifdef TELCMDS
-char *telcmds[] = {
- "EOF", "SUSP", "ABORT", "EOR",
- "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
- "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0
-};
-#else /* TELCMDS */
-extern char *telcmds[];
-#endif /* TELCMDS */
-
-#define TELCMD_FIRST TN_EOF
-#define TELCMD_LAST IAC
-#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
- (unsigned int)(x) >= TELCMD_FIRST || \
- (unsigned int)(x) == TN_SAK)
-#define TELCMD(x) (TELCMD_OK(x)? ((x) == TN_SAK?"SAK": \
- telcmds[(x)-TELCMD_FIRST]):"UNKNOWN")
-
-/* Then the options */
-/* NB: the following platforms have TELOPT_AUTHENTICATION defined as */
-/* 45 instead of 37. */
-#ifdef TELOPT_AUTHENTICATION
-#ifdef __osf__
-#undef TELOPT_AUTHENTICATION
-#endif /* __osf__ */
-#ifndef IRIX
-#undef TELOPT_AUTHENTICATION
-#endif /* IRIX */
-#ifndef ultrix
-#undef TELOPT_AUTHENTICATION
-#endif /* ultrix */
-#endif /* TELOPT_AUTHENTICATION */
-
-/* telnet options */
-#ifndef TELOPT_BINARY
-#define TELOPT_BINARY 0 /* 8-bit data path (RFC 856)*/
-#endif
-#ifndef TELOPT_ECHO
-#define TELOPT_ECHO 1 /* echo (RFC 857)*/
-#endif
-#ifndef TELOPT_RCP
-#define TELOPT_RCP 2 /* prepare to reconnect (NIC 50005)*/
-#endif
-#ifndef TELOPT_SGA
-#define TELOPT_SGA 3 /* suppress go ahead (RFC 858) */
-#endif
-#ifndef TELOPT_NAMS
-#define TELOPT_NAMS 4 /* approximate message size (ETHERNET) */
-#endif
-#ifndef TELOPT_STATUS
-#define TELOPT_STATUS 5 /* give status (RFC 859) */
-#endif
-#ifndef TELOPT_TM
-#define TELOPT_TM 6 /* timing mark (RFC 860) */
-#endif
-#ifndef TELOPT_RCTE
-#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
-#endif /* (RFC 726) */
-#ifndef TELOPT_NAOL
-#define TELOPT_NAOL 8 /* negotiate about output line width */
-#endif /* (NIC 50005) */
-#ifndef TELOPT_NAOP
-#define TELOPT_NAOP 9 /* negotiate about output page size */
-#endif /* (NIC 50005) */
-#ifndef TELOPT_NAOCRD
-#define TELOPT_NAOCRD 10 /* negotiate about CR disposition (RFC 652) */
-#endif /* [Historic] */
-#ifndef TELOPT_NAOHTS
-#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
-#endif /* (RFC 653) [Historic] */
-#ifndef TELOPT_NAOHTD
-#define TELOPT_NAOHTD 12 /* negotiate about horiz tab disposition */
-#endif /* (RFC 654) [Historic] */
-#ifndef TELOPT_NAOFFD
-#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
-#endif /* (RFC 655) [Historic] */
-#ifndef TELOPT_NAOVTS
-#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
-#endif /* (RFC 656) [Historic] */
-#ifndef TELOPT_NAOVTD
-#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
-#endif /* (RFC 657) [Historic] */
-#ifndef TELOPT_NAOLFD
-#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
-#endif /* (RFC 658) [Historic] */
-#ifndef TELOPT_XASCII
-#define TELOPT_XASCII 17 /* extended ascii character set */
-#endif /* (RFC 698) */
-#ifndef TELOPT_LOGOUT
-#define TELOPT_LOGOUT 18 /* force logout (RFC 727) */
-#endif
-#ifndef TELOPT_BM
-#define TELOPT_BM 19 /* byte macro (RFC 735) */
-#endif
-#ifndef TELOPT_DET
-#define TELOPT_DET 20 /* data entry terminal (RFC 1043, 732) */
-#endif
-#ifndef TELOPT_SUPDUP
-#define TELOPT_SUPDUP 21 /* supdup protocol (RFC 736, 734) */
-#endif
-#ifndef TELOPT_SUPDUPOUTPUT
-#define TELOPT_SUPDUPOUTPUT 22 /* supdup output (RFC 749) */
-#endif
-#ifndef TELOPT_SNDLOC
-#define TELOPT_SNDLOC 23 /* send location (RFC 779) */
-#endif
-#ifndef TELOPT_TTYPE
-#define TELOPT_TTYPE 24 /* terminal type (RFC 1091) */
-#endif
-#ifndef TELOPT_EOR
-#define TELOPT_EOR 25 /* end of record (RFC 885) */
-#endif
-#ifndef TELOPT_TUID
-#define TELOPT_TUID 26 /* TACACS user identification (RFC 927) */
-#endif
-#ifndef TELOPT_OUTMRK
-#define TELOPT_OUTMRK 27 /* output marking (RFC 933) */
-#endif
-#ifndef TELOPT_TTYLOC
-#define TELOPT_TTYLOC 28 /* terminal location number (RFC 946) */
-#endif
-#ifndef TELOPT_3270REGIME
-#define TELOPT_3270REGIME 29 /* 3270 regime (RFC 1041) */
-#endif
-#ifndef TELOPT_X3PAD
-#define TELOPT_X3PAD 30 /* X.3 PAD (RFC 1053) */
-#endif
-#ifndef TELOPT_NAWS
-#define TELOPT_NAWS 31 /* window size (RFC 1073) */
-#endif
-#ifndef TELOPT_TSPEED
-#define TELOPT_TSPEED 32 /* terminal speed (RFC 1079) */
-#endif
-#ifndef TELOPT_LFLOW
-#define TELOPT_LFLOW 33 /* remote flow control (RFC 1372) */
-#endif
-#ifndef TELOPT_LINEMODE
-#define TELOPT_LINEMODE 34 /* Linemode option (RFC 1184) */
-#endif
-#ifndef TELOPT_XDISPLOC
-#define TELOPT_XDISPLOC 35 /* X Display Location (RFC 1096) */
-#endif
-#ifndef TELOPT_OLD_ENVIRON
-#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables (RFC 1408) */
-#endif
-#ifndef TELOPT_AUTHENTICATION
-#define TELOPT_AUTHENTICATION 37/* Authenticate (RFC 2941) */
-#endif
-#ifndef TELOPT_ENCRYPTION
-#define TELOPT_ENCRYPTION 38 /* Encryption option (RFC 2946) */
-#endif
-#ifndef TELOPT_NEWENVIRON
-#define TELOPT_NEWENVIRON 39 /* New - Environment variables (RFC 1572) */
-#endif
-#ifndef TELOPT_3270E
-#define TELOPT_3270E 40 /* 3270 Extended (RFC 1647) */
-#endif
-#ifndef TELOPT_XAUTH
-#define TELOPT_XAUTH 41 /* ??? (Earhart) */
-#endif
-#ifndef TELOPT_CHARSET
-#define TELOPT_CHARSET 42 /* Character-set (RFC 2066) */
-#endif
-#ifndef TELOPT_RSP
-#define TELOPT_RSP 43 /* Remote Serial Port (Barnes) */
-#endif
-#ifndef TELOPT_COMPORT
-#define TELOPT_COMPORT 44 /* Com Port Control (RFC 2217) */
-#endif
-#ifndef TELOPT_SLE
-#define TELOPT_SLE 45 /* Suppress Local Echo (Atmar) - [rejected] */
-#endif
-#ifndef TELOPT_START_TLS
-#define TELOPT_START_TLS 46 /* Telnet over Transport Layer Security */
-#endif /* (Boe) */
-#ifndef TELOPT_KERMIT
-#define TELOPT_KERMIT 47 /* Kermit (RFC 2840) */
-#endif
-#ifndef TELOPT_SEND_URL
-#define TELOPT_SEND_URL 48 /* Send URL */
-#endif
-
-#ifndef TELOPT_FORWARD_X
-#define TELOPT_FORWARD_X 49 /* X Windows Forwarding (Altman) */
-#endif /* TELOPT_FORWARD_X */
-
-#ifndef TELOPT_STDERR
-#define TELOPT_STDERR 50 /* Redirected Stderr (Altman) */
-#endif /* TELOPT_STDERR */
-
-#ifndef TELOPT_PRAGMA_LOGON
-#define TELOPT_PRAGMA_LOGON 138 /* Encrypted Logon option (PragmaSys) */
-#endif
-#ifndef TELOPT_SSPI_LOGON
-#define TELOPT_SSPI_LOGON 139 /* MS SSPI Logon option (PragmaSys) */
-#endif
-#ifndef TELOPT_PRAGMA_HEARTBEAT
- /* Server Send Heartbeat option (PragmaSys) */
-#define TELOPT_PRAGMA_HEARTBEAT 140
-#endif
-
-#define TELOPT_IBM_SAK 200 /* IBM Secure Attention Key */
-
-/*
- IBM Secure Attention Key (SAK) Option
-
- In addition to terminal negotiation, the telnet command allows
- negotiation for the Secure Attention Key (SAK)
- option. This option, when supported, provides the local user with
- a secure communication path to the remote
- host for tasks such as changing user IDs or passwords. If the remote
- host supports the SAK function, a trusted
- shell is opened on the remote host when the telnet send sak
- subcommand is issued. The SAK function can
- also be assigned to a single key available in telnet input mode,
- using the set sak subcommand.
-
- TN_SAK
-
- Sends the TELNET SAK (Secure Attention Key) sequence, which causes
- the remote system to invoke the trusted shell. If the SAK is not
- supported, then an error message is displayed that reads:
- Remote side does not support SAK.
-*/
-
-#ifndef TELOPT_EXOPL
-#define TELOPT_EXOPL 255 /* Extended-options-list (RFC 861) */
-#endif
-
-#ifdef NTELOPTS
-#undef NTELOPTS
-#endif /* NTELOPTS */
-/* The Telnet Option space is no longer being allocated by ICANN as a */
-/* continuous list. In other words it is becoming sparse. But we do */
-/* not want to have to allocate memory for a long list of strings and */
-/* structs which will never be used. Therefore, the NTELOPTS define */
-/* can no longer be equal to TELOPT_LAST+1. In fact, the notion of */
-/* TELOPT_FIRST and TELOPT_LAST no longer make sense. */
-#define NTELOPTS 55
-
-#define TELOPT_FIRST TELOPT_BINARY
-#define TELOPT_LAST TELOPT_IBM_SAK
-
-/*
- The following macros speed us up at runtime but are too complex
- for some preprocessors / compilers; if your compiler bombs on ckctel.c
- with "Instruction table overflow" or somesuch, rebuild with -DNOTOMACROS.
-*/
-#ifndef NOTOMACROS
-#ifndef TELOPT_MACRO
-#define TELOPT_MACRO
-#endif /* TELOPT_MACRO */
-#endif /* NOTOMACROS */
-
-#ifdef TELOPT_MACRO
-#define TELOPT_INDEX(x) (((x)>=0 && (x)<= TELOPT_STDERR)?(x):\
- ((x)>=TELOPT_PRAGMA_LOGON && (x)<=TELOPT_PRAGMA_HEARTBEAT)?(x)-87: \
- ((x) == TELOPT_IBM_SAK)?(x)-146: NTELOPTS)
-
-#define TELOPT_OK(x) (((x) >= TELOPT_BINARY && (x) <= TELOPT_STDERR) ||\
- ((x) >= TELOPT_PRAGMA_LOGON && (x) <= TELOPT_PRAGMA_HEARTBEAT) ||\
- ((x) == TELOPT_IBM_SAK))
-#define TELOPT(x) (TELOPT_OK(x)?telopts[TELOPT_INDEX(x)]:"UNKNOWN")
-#else /* TELOPT_MACRO */
-_PROTOTYP(int telopt_index,(int));
-_PROTOTYP(int telopt_ok,(int));
-_PROTOTYP(CHAR * telopt, (int));
-
-#define TELOPT_INDEX(x) telopt_index(x)
-#define TELOPT_OK(x) telopt_ok(x)
-#define TELOPT(x) telopt(x)
-#endif /* TELOPT_MACRO */
-
-#ifdef TELOPTS
-char *telopts[NTELOPTS+2] = {
-/* 0 */ "BINARY", "ECHO", "RCP", "SUPPRESS-GO-AHEAD",
-/* 4 */ "NAME", "STATUS", "TIMING-MARK", "RCTE",
-/* 8 */ "NAOL", "NAOP", "NAOCRD", "NAOHTS",
-/* 12 */ "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD",
-/* 16 */ "NAOLFD", "EXTEND-ASCII", "LOGOUT", "BYTE-MACRO",
-/* 20 */ "DATA-ENTRY-TERMINAL", "SUPDUP", "SUPDUP-OUTPUT", "SEND-LOCATION",
-/* 24 */ "TERMINAL-TYPE", "END-OF-RECORD", "TACACS-UID", "OUTPUT-MARKING",
-/* 28 */ "TTYLOC", "3270-REGIME", "X.3-PAD", "NAWS",
-/* 32 */ "TSPEED", "LFLOW", "LINEMODE", "XDISPLOC",
-/* 36 */ "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPTION", "NEW-ENVIRONMENT",
-/* 40 */ "TN3270E","xauth","CHARSET", "remote-serial-port",
-/* 44 */ "COM-PORT-CONTROL","suppress-local-echo","START-TLS","KERMIT",
-/* 48 */ "send-url","FORWARD-X","stderr",
-/* 138 */ "pragma-logon", "sspi-logon", "pragma-heartbeat",
-/* 200 */ "ibm-sak",
- "unknown",
- 0
-};
-#else /*TELOPTS */
-extern char * telopts[];
-#endif /* TELOPTS */
-
-/* TELNET Newline Mode */
-
-#define TNL_CR 0 /* CR sends bare carriage return */
-#define TNL_CRNUL 1 /* CR and NUL */
-#define TNL_CRLF 2 /* CR and LF */
-#define TNL_LF 3 /* LF instead of CR */
-
-/* TELNET Negotiation Mode */
-
-#define TN_NG_RF 0 /* Negotiation REFUSED */
-#define TN_NG_AC 1 /* Negotiation ACCEPTED */
-#define TN_NG_RQ 2 /* Negotiation REQUESTED */
-#define TN_NG_MU 3 /* Negotiation REQUIRED (must) */
-
-
-/* Systems where we know we can define TELNET NAWS automatically. */
-
-#ifndef CK_NAWS /* In other words, if both */
-#ifdef CK_TTGWSIZ /* TNCODE and TTGWSIZ are defined */
-#define CK_NAWS /* then we can do NAWS. */
-#endif /* CK_TTGWSIZ */
-#endif /* CK_NAWS */
-
-#ifdef CK_FORWARD_X
-#ifndef MAXFWDX
-#define MAXFWDX 64 /* Num of X windows to be fwd'd */
-#endif /* MAXFWDX */
-#endif /* CK_FORWARD_X */
-
-/* Telnet State structures and definitions */
-struct _telopt_state {
- unsigned char def_server_me_mode; /* Default Negotiation Mode */
- unsigned char def_server_u_mode; /* Default Negotiation Mode */
- unsigned char def_client_me_mode; /* Default Negotiation Mode */
- unsigned char def_client_u_mode; /* Default Negotiation Mode */
- unsigned char me_mode; /* Telnet Negotiation Mode */
- unsigned char u_mode; /* Telnet Negotiation Mode */
- unsigned char me; /* Am I ? */
- unsigned char u; /* Are you? */
- unsigned char unanswered_will; /* Sent Will, Waiting for DO/DONT */
- unsigned char unanswered_do; /* Send DO, Waiting for WILL/WONT */
- unsigned char unanswered_wont; /* Sent WONT, Waiting for DONT */
- unsigned char unanswered_dont; /* Sent DONT, Waiting for WONT */
- unsigned char unanswered_sb; /* Sent SB, Waiting for SB (server) */
- union {
-#ifdef IKS_OPTION
- struct _telopt_kermit { /* Kermit Option States */
- unsigned char me_start; /* I have a Server active */
- unsigned char me_req_start; /* Sent Req-Start, Waiting for response */
- unsigned char me_req_stop; /* Sent Req-Stop, Waiting for response */
- unsigned char u_start; /* You have a Server active */
- unsigned char sop; /* Have we received the SOP char? */
- } kermit;
-#endif /* IKS_OPTION */
-#ifdef CK_ENCRYPTION
- struct _telopt_encrypt { /* Encryption Option States */
- unsigned char need_to_send;
- unsigned char stop; /* Is encryption stopped? */
- } encrypt;
-#endif /* CK_ENCRYPTION */
-#ifdef CK_NAWS
- struct _telopt_naws { /* NAWS Option Information */
- unsigned char need_to_send;
- int x; /* Last Width */
- int y; /* Last Height */
- } naws;
-#endif /* CK_NAWS */
-#ifdef CK_SSL
- struct _telopt_start_tls { /* Start TLS Option */
- unsigned char u_follows; /* u ready for TLS negotiation */
- unsigned char me_follows; /* me ready for TLS negotiation */
- unsigned char auth_request; /* Rcvd WILL AUTH before WONT START_TLS */
- } start_tls;
-#endif /* CK_SSL */
- struct _telopt_term { /* Terminal Type */
- unsigned char need_to_send;
- unsigned char type[41]; /* Last terminal type */
- } term;
-#ifdef CK_ENVIRONMENT
- struct _telopt_new_env {
- unsigned char need_to_send;
- unsigned char * str;
- int len;
- } env;
-#ifdef CK_XDISPLOC
- struct _telopt_xdisp {
- unsigned char need_to_send;
- } xdisp;
-#endif /* CK_XDISPLOC */
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_SNDLOC
- struct _telopt_sndloc {
- unsigned char need_to_send;
- } sndloc;
-#endif /* CK_SNDLOC */
-#ifdef CK_FORWARD_X
- struct _telopt_fwd_x {
- unsigned char need_to_send;
- int listen_socket;
- struct _channel {
- int fd;
- int id;
- unsigned char need_to_send_xauth;
- unsigned char suspend;
- } channel[MAXFWDX];
-#ifdef NT
- int thread_started;
-#endif /* NT */
- } forward_x;
-#endif /* CK_FORWARD_X */
-#ifdef TN_COMPORT
- struct _telopt_comport {
- unsigned char need_to_send;
- unsigned char wait_for_sb;
- unsigned char wait_for_ms;
- } comport;
-#endif /* TN_COMPORT */
- /* additional options such as New Environment or Send Location */
- } sb;
-};
-typedef struct _telopt_state telopt_state, *p_telopt_state;
-
-/* telopt_states[] is the array of structs which the state of each telnet */
-/* option is stored. We allocate one more than we need in case we are */
-/* sent telnet options that we do not recognize. If by some chance the */
-/* TELOPT_OK() check is skipped, TELOPT_INDEX() will force the option to */
-/* use the extra cell. */
-
-#ifdef TELOPT_STATES
-telopt_state telopt_states[NTELOPTS+1];
-#else /* TELOPT_STATES */
-extern telopt_state telopt_states[];
-#endif /* TELOPT_STATES */
-
-#define TELOPT_ME(x) (telopt_states[TELOPT_INDEX(x)].me)
-#define TELOPT_U(x) (telopt_states[TELOPT_INDEX(x)].u)
-#define TELOPT_ME_MODE(x) \
- (telopt_states[TELOPT_INDEX(x)].me_mode)
-#define TELOPT_U_MODE(x) \
- (telopt_states[TELOPT_INDEX(x)].u_mode)
-#define TELOPT_UNANSWERED_WILL(x) \
- (telopt_states[TELOPT_INDEX(x)].unanswered_will)
-#define TELOPT_UNANSWERED_DO(x) \
- (telopt_states[TELOPT_INDEX(x)].unanswered_do)
-#define TELOPT_UNANSWERED_WONT(x) \
- (telopt_states[TELOPT_INDEX(x)].unanswered_wont)
-#define TELOPT_UNANSWERED_DONT(x) \
- (telopt_states[TELOPT_INDEX(x)].unanswered_dont)
-#define TELOPT_UNANSWERED_SB(x) \
- (telopt_states[TELOPT_INDEX(x)].unanswered_sb)
-#define TELOPT_SB(x) \
- (telopt_states[TELOPT_INDEX(x)].sb)
-#define TELOPT_DEF_S_ME_MODE(x) \
- (telopt_states[TELOPT_INDEX(x)].def_server_me_mode)
-#define TELOPT_DEF_S_U_MODE(x) \
- (telopt_states[TELOPT_INDEX(x)].def_server_u_mode)
-#define TELOPT_DEF_C_ME_MODE(x) \
- (telopt_states[TELOPT_INDEX(x)].def_client_me_mode)
-#define TELOPT_DEF_C_U_MODE(x) \
- (telopt_states[TELOPT_INDEX(x)].def_client_u_mode)
-
-#ifdef TELOPT_MODES
-char * telopt_modes[4] = {
- "REFUSED", "ACCEPTED", "REQUESTED", "REQUIRED"
-};
-#else /* TELOPT_MODES */
-extern char * telopt_modes[];
-#endif /* TELOPT_MODES */
-
-#ifdef TELOPT_MACRO
-#define TELOPT_MODE_OK(x) ((unsigned int)(x) <= TN_NG_MU)
-#define TELOPT_MODE(x) (TELOPT_MODE_OK(x)?telopt_modes[(x)-TN_NG_RF]:"UNKNOWN")
-#else /* TELOPT_MACRO */
-_PROTOTYP(int telopt_mode_ok,(int));
-_PROTOTYP(CHAR * telopt_mode,(int));
-
-#define TELOPT_MODE_OK(x) telopt_mode_ok(x)
-#define TELOPT_MODE(x) telopt_mode(x)
-#endif /* TELOPT_MACRO */
-
-/* Sub-option qualifiers */
-#define TELQUAL_IS 0 /* option is... */
-#define TELQUAL_SEND 1 /* send option */
-#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
-#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
-#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
-
-#define TEL_ENV_VAR 0
-#define TEL_ENV_VALUE 1
-#define TEL_ENV_ESC 2
-#define TEL_ENV_USERVAR 3
-
-#define LFLOW_OFF 0 /* Disable remote flow control */
-#define LFLOW_ON 1 /* Enable remote flow control */
-#define LFLOW_RESTART_ANY 2 /* Restart output on any char */
-#define LFLOW_RESTART_XON 3 /* Restart output only on XON */
-
-/*
- * LINEMODE suboptions
- */
-
-#define LM_MODE 1
-#define LM_FORWARDMASK 2
-#define LM_SLC 3
-
-#define MODE_EDIT 0x01
-#define MODE_TRAPSIG 0x02
-#define MODE_ACK 0x04
-#define MODE_SOFT_TAB 0x08
-#define MODE_LIT_ECHO 0x10
-
-#define MODE_MASK 0x1f
-
-/* Not part of protocol, but needed to simplify things... */
-#define MODE_FLOW 0x0100
-#define MODE_ECHO 0x0200
-#define MODE_INBIN 0x0400
-#define MODE_OUTBIN 0x0800
-#define MODE_FORCE 0x1000
-
-#define SLC_SYNCH 1
-#define SLC_BRK 2
-#define SLC_IP 3
-#define SLC_AO 4
-#define SLC_AYT 5
-#define SLC_EOR 6
-#define SLC_ABORT 7
-#define SLC_EOF 8
-#define SLC_SUSP 9
-#define SLC_EC 10
-#define SLC_EL 11
-#define SLC_EW 12
-#define SLC_RP 13
-#define SLC_LNEXT 14
-#define SLC_XON 15
-#define SLC_XOFF 16
-#define SLC_FORW1 17
-#define SLC_FORW2 18
-#define SLC_MCL 19
-#define SLC_MCR 20
-#define SLC_MCWL 21
-#define SLC_MCWR 22
-#define SLC_MCBOL 23
-#define SLC_MCEOL 24
-#define SLC_INSRT 25
-#define SLC_OVER 26
-#define SLC_ECR 27
-#define SLC_EWR 28
-#define SLC_EBOL 29
-#define SLC_EEOL 30
-
-#define NSLC 30
-
-/*
- * For backwards compatability, we define SLC_NAMES to be the
- * list of names if SLC_NAMES is not defined.
- */
-#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
- "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
- "LNEXT", "XON", "XOFF", "FORW1", "FORW2", \
- "MCL", "MCR", "MCWL", "MCWR", "MCBOL", "MCEOL", \
- "INSRT", "OVER", "ECR", "EWR", "EBOL", "EEOL", 0
-#ifdef SLC_NAMES
-char *slc_names[] = {
- SLC_NAMELIST
-};
-#else
-extern char *slc_names[];
-#define SLC_NAMES SLC_NAMELIST
-#endif
-
-#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
-#define SLC_NAME(x) (SLC_NAME_OK(x)?slc_names[x]:"UNKNOWN")
-
-#define SLC_NOSUPPORT 0
-#define SLC_CANTCHANGE 1
-#define SLC_VARIABLE 2
-#define SLC_DEFAULT 3
-#define SLC_LEVELBITS 0x03
-
-#define SLC_FUNC 0
-#define SLC_FLAGS 1
-#define SLC_VALUE 2
-
-#define SLC_ACK 0x80
-#define SLC_FLUSHIN 0x40
-#define SLC_FLUSHOUT 0x20
-
-#define OLD_ENV_VAR 1
-#define OLD_ENV_VALUE 0
-#define NEW_ENV_VAR 0
-#define NEW_ENV_VALUE 1
-#define ENV_ESC 2
-#define ENV_USERVAR 3
-
-#define FWDX_SCREEN 0
-#define FWDX_OPEN 1
-#define FWDX_CLOSE 2
-#define FWDX_DATA 3
-#define FWDX_OPTIONS 4
-#define FWDX_OPT_DATA 5
-#define FWDX_XOFF 6
-#define FWDX_XON 7
-
-#define FWDX_OPT_NONE 0
-#define FWDX_OPT_XAUTH 1
-
-/*
- * AUTHENTICATION suboptions
- */
-
-/*
- * Who is authenticating who ...
- */
-#define AUTH_CLIENT_TO_SERVER 0 /* Client authenticating server */
-#define AUTH_SERVER_TO_CLIENT 1 /* Server authenticating client */
-#define AUTH_WHO_MASK 1
-
-/*
- * amount of authentication done
- */
-#define AUTH_HOW_ONE_WAY 0
-#define AUTH_HOW_MUTUAL 2
-#define AUTH_HOW_MASK 2
-
-/*
- * should we be encrypting?
- */
-#define AUTH_ENCRYPT_OFF 0
-#define AUTH_ENCRYPT_USING_TELOPT 4
-#define AUTH_ENCRYPT_AFTER_EXCHANGE 16
-#define AUTH_ENCRYPT_START_TLS 20
-#define AUTH_ENCRYPT_MASK 20
-
-/*
- * will we be forwarding?
- * if we want to activate the use of this flag then
- * #define USE_INI_CRED_FWD
- */
-#define INI_CRED_FWD_OFF 0
-#define INI_CRED_FWD_ON 8
-#define INI_CRED_FWD_MASK 8
-#define USE_INI_CRED_FWD
-
-#define AUTHTYPE_NULL 0
-#define AUTHTYPE_KERBEROS_V4 1
-#define AUTHTYPE_KERBEROS_V5 2
-#define AUTHTYPE_SPX 3
-#define AUTHTYPE_MINK 4
-#define AUTHTYPE_SRP 5
-#define AUTHTYPE_RSA 6
-#define AUTHTYPE_SSL 7
-#define AUTHTYPE_LOKI 10
-#define AUTHTYPE_SSA 11
-#define AUTHTYPE_KEA_SJ 12
-#define AUTHTYPE_KEA_INTEG 13
-#define AUTHTYPE_DSS 14
-#define AUTHTYPE_NTLM 15
-#define AUTHTYPE_GSSAPI_KRB5 16 /* Not allocated by IANA */
-#ifdef AUTHTYPE_CNT
-#undef AUTHTYPE_CNT
-#endif /* AUTHTYPE_CNT */
-#define AUTHTYPE_CNT 17
-
-/*
- * AUTHTYPEs Last updated 21 March 1999
- * from http://www.isi.edu/in-notes/iana/assignments/telnet-options
- */
-
-#define AUTHTYPE_AUTO 99
-
-#ifdef AUTH_NAMES
-char *authtype_names[] = {
- "NULL", /* RFC 2941 */
- "KERBEROS_V4", /* RFC 2941 / 1411 */
- "KERBEROS_V5", /* RFC 2941 */
- "SPX", /* RFC 2941 (not Internet Standard) */
- "MINK", /* RFC 2941 (not Internet Standard) */
- "SRP", /* RFC 2944 */
- "RSA", /* RFC 2941 (not Internet Standard) */
- "SSL", /* RFC 2941 (not Internet Standard) */
- "IANA_8", /* not assigned by IANA */
- "IANA_9", /* not assigned by IANA */
- "LOKI", /* RFC 2941 (not Internet Standard) */
- "SSA", /* Schoch */
- "KEA_SJ", /* RFC 2951 */
- "KEA_SJ_INTEG", /* RFC 2951 */
- "DSS", /* RFC 2943 */
- "NTLM", /* Kahn <louisk@microsoft.com> */
- "GSSAPI-KRB5", /* experimental - altman */
- 0
-};
-char * authmode_names[] = {
- "CLIENT_TO_SERVER|ONE_WAY",
- "SERVER_TO_CLIENT|ONE_WAY",
- "CLIENT_TO_SERVER|MUTUAL",
- "SERVER_TO_CLIENT|MUTUAL",
- "CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_USING_TELOPT",
- "SERVER_TO_CLIENT|ONE_WAY|ENCRYPT_USING_TELOPT",
- "CLIENT_TO_SERVER|MUTUAL|ENCRYPT_USING_TELOPT",
- "SERVER_TO_CLIENT|MUTUAL|ENCRYPT_USING_TELOPT",
- "CLIENT_TO_SERVER|ONE_WAY|CRED_FWD",
- "SERVER_TO_CLIENT|ONE_WAY|CRED_FWD",
- "CLIENT_TO_SERVER|MUTUAL|CRED_FWD",
- "SERVER_TO_CLIENT|MUTUAL|CRED_FWD",
- "CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_USING_TELOPT|CRED_FWD",
- "SERVER_TO_CLIENT|ONE_WAY|ENCRYPT_USING_TELOPT|CRED_FWD",
- "CLIENT_TO_SERVER|MUTUAL|ENCRYPT_USING_TELOPT|CRED_FWD",
- "SERVER_TO_CLIENT|MUTUAL|ENCRYPT_USING_TELOPT|CRED_FWD",
- "CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_AFTER_EXCHANGE",
- "SERVER_TO_CLIENT|ONE_WAY|ENCRYPT_AFTER_EXCHANGE",
- "CLIENT_TO_SERVER|MUTUAL|ENCRYPT_AFTER_EXCHANGE",
- "SERVER_TO_CLIENT|MUTUAL|ENCRYPT_AFTER_EXCHANGE",
- "CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_START_TLS",
- "SERVER_TO_CLIENT|ONE_WAY|ENCRYPT_START_TLS",
- "CLIENT_TO_SERVER|MUTUAL|ENCRYPT_START_TLS",
- "SERVER_TO_CLIENT|MUTUAL|ENCRYPT_START_TLS",
- "CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_AFTER_EXCHANGE|CRED_FWD",
- "SERVER_TO_CLIENT|ONE_WAY|ENCRYPT_AFTER_EXCHANGE|CRED_FWD",
- "CLIENT_TO_SERVER|MUTUAL|ENCRYPT_AFTER_EXCHANGE|CRED_FWD",
- "SERVER_TO_CLIENT|MUTUAL|ENCRYPT_AFTER_EXCHANGE|CRED_FWD",
- "CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_START_TLS|CRED_FWD",
- "SERVER_TO_CLIENT|ONE_WAY|ENCRYPT_START_TLS|CRED_FWD",
- "CLIENT_TO_SERVER|MUTUAL|ENCRYPT_START_TLS|CRED_FWD",
- "SERVER_TO_CLIENT|MUTUAL|ENCRYPT_START_TLS|CRED_FWD",
- 0
-};
-#else
-extern char *authtype_names[];
-extern char *authmode_names[];
-#endif
-#define AUTHMODE_CNT 32
-
-#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
-#define AUTHTYPE_NAME(x) (AUTHTYPE_NAME_OK(x)?authtype_names[x]:"UNKNOWN")
-
-#define AUTHMODE_NAME_OK(x) ((unsigned int)(x) < AUTHMODE_CNT)
-#define AUTHMODE_NAME(x) (AUTHMODE_NAME_OK(x)?authmode_names[x]:"UNKNOWN")
-
-/* Kerberos Authentication Message Identifiers */
-#define KRB_AUTH 0 /* Authentication data follows */
-#define KRB_REJECT 1 /* Rejected (reason might follow) */
-#define KRB_ACCEPT 2 /* Accepted */
-#define KRB4_CHALLENGE 3
-#define KRB4_RESPONSE 4
-#define KRB5_RESPONSE 3 /* Response for mutual auth. */
-#define KRB5_FORWARD 4 /* Forwarded credentials follow */
-#define KRB5_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */
-#define KRB5_FORWARD_REJECT 6 /* Forwarded credentials rejected */
-#define KRB5_TLS_VERIFY 7 /* TLS Finished Msg verifier */
-
-/* GSSAPI-KRB5 Authentication Message Identifiers */
-#define GSS_AUTH_DATA 0 /* Authentication data follows */
-#define GSS_REJECT 1 /* Rejected (reason might follow) */
-#define GSS_ACCEPT 2 /* Accepted (username might follow) */
-#define GSS_CONTINUE 3
-
-/* Secure Remote Password Authentication Message Identifiers */
-#define SRP_AUTH 0 /* Authentication data follows */
-#define SRP_REJECT 1 /* Rejected (reason might follow) */
-#define SRP_ACCEPT 2 /* Accepted */
-#define SRP_CHALLENGE 3
-#define SRP_RESPONSE 4
-#define SRP_EXP 8 /* */
-#define SRP_PARAMS 9 /* */
-
-/* Telnet Auth using KEA and SKIPJACK */
-
-#define KEA_CERTA_RA 1
-#define KEA_CERTB_RB_IVB_NONCEB 2
-#define KEA_IVA_RESPONSEB_NONCEA 3
-#define KEA_RESPONSEA 4
-
-/* Tim Hudson's SSL Authentication Message Identifiers */
-#define SSL_START 1
-#define SSL_ACCEPT 2
-#define SSL_REJECT 3
-
-/* Microsoft NTLM Authentication Message Identifiers */
-#define NTLM_AUTH 0
-#define NTLM_CHALLENGE 1
-#define NTLM_RESPONSE 2
-#define NTLM_ACCEPT 3
-#define NTLM_REJECT 4
-
-/* Generic Constants */
-#define AUTH_SUCCESS 0
-#define AUTH_FAILURE 255
-
-/*
- * ENCRYPTion suboptions
- */
-#define ENCRYPT_IS 0 /* I pick encryption type ... */
-#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
-#define ENCRYPT_REPLY 2 /* Initial setup response */
-#define ENCRYPT_START 3 /* Am starting to send encrypted */
-#define ENCRYPT_END 4 /* Am ending encrypted */
-#define ENCRYPT_REQSTART 5 /* Request you start encrypting */
-#define ENCRYPT_REQEND 6 /* Request you send encrypting */
-#define ENCRYPT_ENC_KEYID 7
-#define ENCRYPT_DEC_KEYID 8
-#define ENCRYPT_CNT 9
-
-#define ENCTYPE_ANY 0
-#define ENCTYPE_DES_CFB64 1
-#define ENCTYPE_DES_OFB64 2
-#define ENCTYPE_DES3_CFB64 3
-#define ENCTYPE_DES3_OFB64 4
-#define ENCTYPE_CAST5_40_CFB64 8
-#define ENCTYPE_CAST5_40_OFB64 9
-#define ENCTYPE_CAST128_CFB64 10
-#define ENCTYPE_CAST128_OFB64 11
-#ifdef ENCTYPE_CNT
-#undef ENCTYPE_CNT
-#endif
-#define ENCTYPE_CNT 12
-
-#ifdef ENCRYPT_NAMES
-char *encrypt_names[] = {
- "IS", "SUPPORT", "REPLY", "START", "END",
- "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
- 0
-};
-char *enctype_names[] = {
- "ANY",
- "DES_CFB64", /* RFC 2952 */
- "DES_OFB64", /* RFC 2953 */
- "DES3_CFB64", /* RFC 2947 */
- "DES3_OFB64", /* RFC 2948 */
- "UNKNOWN-5",
- "UNKNOWN-6",
- "UNKNOWN-7",
- "CAST5_40_CFB64", /* RFC 2950 */
- "CAST5_40_OFB64", /* RFC 2949 */
- "CAST128_CFB64", /* RFC 2950*/
- "CAST128_OFB64", /* RFC 2949 */
- 0
-};
-#else
-extern char *encrypt_names[];
-extern char *enctype_names[];
-#endif
-
-#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
-#define ENCRYPT_NAME(x) (ENCRYPT_NAME_OK(x)?encrypt_names[x]:"UNKNOWN")
-
-#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
-#define ENCTYPE_NAME(x) (ENCTYPE_NAME_OK(x)?enctype_names[x]:"UNKNOWN")
-
-/* For setting the state of validUser */
-
-#define AUTH_REJECT 0 /* Rejected */
-#define AUTH_UNKNOWN 1 /* We don't know who he is, but he's okay */
-#define AUTH_OTHER 2 /* We know him, but not his name */
-#define AUTH_USER 3 /* We know he name */
-#define AUTH_VALID 4 /* We know him, and he needs no password */
-
-/* Kermit Option Subnegotiations */
-
-#define KERMIT_START 0
-#define KERMIT_STOP 1
-#define KERMIT_REQ_START 2
-#define KERMIT_REQ_STOP 3
-#define KERMIT_SOP 4
-#define KERMIT_RESP_START 8
-#define KERMIT_RESP_STOP 9
-
-/* For SET TELNET AUTH HOW */
-#define TN_AUTH_HOW_ANY 0
-#define TN_AUTH_HOW_ONE_WAY 1
-#define TN_AUTH_HOW_MUTUAL 2
-
-/* For SET TELNET AUTH ENCRYPT */
-#define TN_AUTH_ENC_ANY 0
-#define TN_AUTH_ENC_NONE 1
-#define TN_AUTH_ENC_TELOPT 2
-#define TN_AUTH_ENC_EXCH 3 /* not used in Kermit */
-#define TN_AUTH_ENC_TLS 4
-
-/* Telnet protocol functions defined in C-Kermit */
-
-_PROTOTYP( int tn_ini, (void) ); /* Telnet protocol support */
-_PROTOTYP( int tn_reset, (void));
-_PROTOTYP( int tn_set_modes, (void));
-_PROTOTYP( int tn_sopt, (int, int) );
-_PROTOTYP( int tn_doop, (CHAR, int, int (*)(int) ) );
-_PROTOTYP( int tn_sttyp, (void) );
-_PROTOTYP( int tn_snenv, (CHAR *, int) ) ;
-_PROTOTYP( int tn_rnenv, (CHAR *, int) ) ;
-_PROTOTYP( int tn_wait, (char *) ) ;
-_PROTOTYP( int tn_push, (void) ) ;
-_PROTOTYP( int tnsndbrk, (void) );
-_PROTOTYP( VOID tn_debug, (char *));
-_PROTOTYP( int tn_hex, (CHAR *, int, CHAR *, int));
-_PROTOTYP( unsigned char * tn_get_display, (void));
-#ifdef IKS_OPTION
-_PROTOTYP( int tn_siks, (int) );
-_PROTOTYP( int iks_wait, (int, int) );
-#endif /* IKS_OPTION */
-#ifdef CK_NAWS
-_PROTOTYP( int tn_snaws, (void) );
-#endif /* CK_NAWS */
-#ifdef CK_XDISPLOC
-_PROTOTYP( int tn_sxdisploc, (void) );
-#endif /* CK_XDISPLOC */
-#ifdef CK_SNDLOC
-_PROTOTYP( int tn_sndloc, (void) );
-#endif /* CK_SNDLOC */
-#ifdef CK_FORWARD_X
-/* From Xauth.h */
-typedef struct xauth {
- unsigned short family;
- unsigned short address_length;
- char *address;
- unsigned short number_length;
- char *number;
- unsigned short name_length;
- char *name;
- unsigned short data_length;
- char *data;
-} Xauth;
-
-#include <stdio.h>
-
-/* from X.h */
-#define FamilyInternet 0
-#define FamilyDECnet 1
-#define FamilyChaos 2
-
-# define FamilyLocal (256) /* not part of X standard (i.e. X.h) */
-# define FamilyWild (65535)
-# define FamilyNetname (254) /* not part of X standard */
-# define FamilyKrb5Principal (253) /* Kerberos 5 principal name */
-# define FamilyLocalHost (252) /* for local non-net authentication */
-char *XauFileName();
-
-Xauth *XauReadAuth(
-FILE* /* auth_file */
-);
-
-int XauWriteAuth(
-FILE* /* auth_file */,
-Xauth* /* auth */
-);
-
-Xauth *XauGetAuthByName(
-const char* /* display_name */
-);
-
-Xauth *XauGetAuthByAddr(
-unsigned int /* family */,
-unsigned int /* address_length */,
-const char* /* address */,
-unsigned int /* number_length */,
-const char* /* number */,
-unsigned int /* name_length */,
-const char* /* name */
-);
-
-void XauDisposeAuth(
-Xauth* /* auth */
-);
-
-
-_PROTOTYP( int fwdx_create_listen_socket,(int));
-_PROTOTYP( int fwdx_open_client_channel,(int));
-_PROTOTYP( int fwdx_open_server_channel,(VOID));
-_PROTOTYP( int fwdx_close_channel,(int));
-_PROTOTYP( int fwdx_write_data_to_channel,(int, char *,int));
-_PROTOTYP( int fwdx_send_data_from_channel,(int, char *,int));
-_PROTOTYP( int fwdx_close_all,(VOID));
-_PROTOTYP( int fwdx_tn_sb,(unsigned char *, int));
-_PROTOTYP( int tn_sndfwdx, (void));
-_PROTOTYP( int fwdx_send_close,(int));
-_PROTOTYP( int fwdx_send_open,(int));
-_PROTOTYP( int fwdx_client_reply_options,(char *, int));
-_PROTOTYP( int fwdx_send_options,(VOID));
-_PROTOTYP( VOID fwdx_check_sockets,(fd_set *));
-_PROTOTYP( int fwdx_init_fd_set,(fd_set *));
-_PROTOTYP( int fwdx_authorize_channel, (int, unsigned char *, int));
-_PROTOTYP( int fwdx_create_fake_xauth, (char *, int, int));
-_PROTOTYP( int fwdx_send_xauth_to_xserver, (int, unsigned char *, int len));
-_PROTOTYP( int fwdx_server_avail, (VOID));
-_PROTOTYP( int fwdx_parse_displayname, (char *, int *, char **, int *, int *, char **));
-
-#ifdef NT
-_PROTOTYP( VOID fwdx_thread,(VOID *));
-#endif /* NT */
-#endif /* CK_FORWARD_X */
-
-#ifdef TN_COMPORT
-#define TNC_C2S_SIGNATURE 0
-#define TNC_C2S_SET_BAUDRATE 1
-#define TNC_C2S_SET_DATASIZE 2
-#define TNC_C2S_SET_PARITY 3
-#define TNC_C2S_SET_STOPSIZE 4
-#define TNC_C2S_SET_CONTROL 5
-#define TNC_C2S_NOTIFY_LINESTATE 6
-#define TNC_C2S_NOTIFY_MODEMSTATE 7
-#define TNC_C2S_FLOW_SUSPEND 8
-#define TNC_C2S_FLOW_RESUME 9
-#define TNC_C2S_SET_LS_MASK 10
-#define TNC_C2S_SET_MS_MASK 11
-#define TNC_C2S_PURGE 12
-#define TNC_S2C_SIGNATURE 100
-#define TNC_S2C_SET_BAUDRATE 101
-#define TNC_S2C_SET_DATASIZE 102
-#define TNC_S2C_SET_PARITY 103
-#define TNC_S2C_SET_STOPSIZE 104
-#define TNC_S2C_SET_CONTROL 105
-#define TNC_S2C_SEND_LS 106
-#define TNC_S2C_SEND_MS 107
-#define TNC_S2C_FLOW_SUSPEND 108
-#define TNC_S2C_FLOW_RESUME 109
-#define TNC_S2C_SET_LS_MASK 110
-#define TNC_S2C_SET_MS_MASK 111
-#define TNC_S2C_PURGE 112
-
-/* The COMPORT values are not defined in RFC 2217 */
-#define TNC_BPS_REQUEST 0
-#define TNC_BPS_300 3
-#define TNC_BPS_600 4
-#define TNC_BPS_1200 5
-#define TNC_BPS_2400 6
-#define TNC_BPS_4800 7
-#define TNC_BPS_9600 8
-#define TNC_BPS_14400 9
-#define TNC_BPS_19200 10
-#define TNC_BPS_28800 11
-#define TNC_BPS_38400 12
-#define TNC_BPS_57600 13
-#define TNC_BPS_115200 14
-#define TNC_BPS_230400 15
-#define TNC_BPS_460800 16
-
-#define TNC_DS_REQUEST 0
-#define TNC_DS_5 5
-#define TNC_DS_6 6
-#define TNC_DS_7 7
-#define TNC_DS_8 8
-
-#define TNC_PAR_REQUEST 0
-#define TNC_PAR_NONE 1
-#define TNC_PAR_ODD 2
-#define TNC_PAR_EVEN 3
-#define TNC_PAR_MARK 4
-#define TNC_PAR_SPACE 5
-
-#define TNC_SB_REQUEST 0
-#define TNC_SB_1 1
-#define TNC_SB_1_5 3
-#define TNC_SB_2 2
-
-#define TNC_CTL_OFLOW_REQUEST 0
-#define TNC_CTL_OFLOW_NONE 1
-#define TNC_CTL_OFLOW_XON_XOFF 2
-#define TNC_CTL_OFLOW_RTS_CTS 3
-#define TNC_CTL_OFLOW_DCD 17
-#define TNC_CTL_OFLOW_DSR 19
-
-#define TNC_CTL_BREAK_REQUEST 4
-#define TNC_CTL_BREAK_ON 5
-#define TNC_CTL_BREAK_OFF 6
-
-#define TNC_CTL_DTR_REQUEST 7
-#define TNC_CTL_DTR_ON 8
-#define TNC_CTL_DTR_OFF 9
-
-#define TNC_CTL_RTS_REQUEST 10
-#define TNC_CTL_RTS_ON 11
-#define TNC_CTL_RTS_OFF 12
-
-#define TNC_CTL_IFLOW_REQUEST 13
-#define TNC_CTL_IFLOW_NONE 14
-#define TNC_CTL_IFLOW_XON_XOFF 15
-#define TNC_CTL_IFLOW_RTS_CTS 16
-#define TNC_CTL_IFLOW_DTR 18
-
-#define TNC_MS_DATA_READY 1
-#define TNC_MS_OVERRUN_ERROR 2
-#define TNC_MS_PARITY_ERROR 4
-#define TNC_MS_FRAME_ERROR 8
-#define TNC_MS_BREAK_ERROR 16
-#define TNC_MS_HR_EMPTY 32
-#define TNC_MS_SR_EMPTY 64
-#define TNC_MS_TIMEOUT_ERROR 128
-
-#define TNC_MS_CTS_DELTA 1
-#define TNC_MS_DSR_DELTA 2
-#define TNC_MS_EDGE_RING 4
-#define TNC_MS_RLSD_DELTA 8
-#define TNC_MS_CTS_SIG 16
-#define TNC_MS_DSR_SIG 32
-#define TNC_MS_RI_SIG 64
-#define TNC_MS_RLSD_SIG 128
-
-#define TNC_PURGE_RECEIVE 1
-#define TNC_PURGE_TRANSMIT 2
-#define TNC_PURGE_BOTH 3
-
-#ifdef TNC_NAMES
-char *tnc_names[] = {
- "SIGNATURE", "SET-BAUDRATE", "SET-DATARATE", "SET-PARITY", "SET-STOPSIZE",
- "SET-CONTROL", "NOTIFY-LINESTATE", "NOTIFY-MODEMSTATE",
- "FLOWCONTROL-SUSPEND", "FLOWCONTROL-RESUME", "SET-LINESTATE-MASK",
- "SET-MODEMSTATE-MASK", "PURGE-DATA",
- 0
-};
-#else
-extern char *tnc_names[];
-#endif
-
-#define TNC_NAME_OK(x) ((x) >= 0 && (x) <= 12 || (x) >= 100 && (x) <= 112)
-#define TNC_NAME(x) \
- (TNC_NAME_OK(x)?tnc_names[(x)>=100?(x)-100:(x)]:"UNKNOWN")
-
-_PROTOTYP(int tnc_init,(void));
-_PROTOTYP(int tnc_wait,(CHAR *, int));
-_PROTOTYP(int tnc_tn_sb,(CHAR *,int));
-_PROTOTYP(CONST char * tnc_get_signature, (void));
-_PROTOTYP(int tnc_send_signature, (char *));
-_PROTOTYP(int tnc_set_baud,(long));
-_PROTOTYP(int tnc_get_baud,(void));
-_PROTOTYP(int tnc_set_datasize,(int));
-_PROTOTYP(int tnc_get_datasize,(void));
-_PROTOTYP(int tnc_set_parity,(int));
-_PROTOTYP(int tnc_get_parity,(void));
-_PROTOTYP(int tnc_set_stopsize,(int));
-_PROTOTYP(int tnc_get_stopsize,(void));
-_PROTOTYP(int tnc_set_oflow,(int));
-_PROTOTYP(int tnc_get_oflow,(void));
-_PROTOTYP(int tnc_set_iflow,(int));
-_PROTOTYP(int tnc_get_iflow,(void));
-_PROTOTYP(int tnc_set_break_state,(int));
-_PROTOTYP(int tnc_get_break_state,(void));
-_PROTOTYP(int tnc_set_dtr_state,(int));
-_PROTOTYP(int tnc_get_dtr_state,(void));
-_PROTOTYP(int tnc_set_rts_state,(int));
-_PROTOTYP(int tnc_get_rts_state,(void));
-_PROTOTYP(int tnc_set_ls_mask,(int));
-_PROTOTYP(int tnc_get_ls_mask,(void));
-_PROTOTYP(int tnc_get_ls,(void));
-_PROTOTYP(int tnc_set_ms_mask,(int));
-_PROTOTYP(int tnc_get_ms_mask,(void));
-_PROTOTYP(int tnc_get_ms,(void));
-_PROTOTYP(int tnc_send_purge_data,(int));
-_PROTOTYP(int tnc_flow_suspended,(void));
-_PROTOTYP(int tnc_suspend_flow,(void));
-_PROTOTYP(int tnc_resume_flow,(void));
-
-/* The following methods are to be called by ck?tio.c routines */
-_PROTOTYP(int tnsetflow,(int));
-_PROTOTYP(int tnsettings,(int,int));
-_PROTOTYP(int tngmdm,(void));
-_PROTOTYP(int tnsndb,(long));
-_PROTOTYP(int istncomport,(void));
-_PROTOTYP(int tn_sndcomport,(void));
-#endif /* TN_COMPORT */
-
-#ifndef CKCTEL_C /* These are declared in ckctel.c */
-extern int tn_init; /* Telnet protocol initialized flag */
-extern char *tn_term; /* Terminal type override */
-extern int sstelnet; /* Server side telnet? */
-extern int tn_deb; /* Telnet option debugging flag */
-extern int tn_auth_krb5_des_bug; /* Telnet BUG */
-#endif /* CKCTEL_C */
-
-#define TN_MSG_LEN 12292
-#endif /* TNCODE */
-#endif /* CKCTEL_H */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcuni.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckcuni.c
deleted file mode 100644
index 1f58548..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcuni.c
+++ /dev/null
@@ -1,16173 +0,0 @@
-char * ckcuni = "Unicode support 9.0.115, 16 Oct 2009";
-
-#ifdef OS2
-#define KERMITFONT
-#endif /* OS2 */
-
-/* C K C U N I . C -- Unicode/Terminal character-set translations */
-
-/*
- Copyright (C) 1999, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Authors:
- Frank da Cruz <fdc@columbia.edu>
- The Kermit Project, Columbia University, New York City.
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Functions u_blah() translate from blah to Unicode (incoming material).
- Functions tx_blah() translate from Unicode to blah (keystrokes).
- Function pointers are kept in parallel arrays indexed by TX_blah values
- defined in ckcuni.h. NOTE: tx_decspec and tx_dectech are undefined since
- these character sets are never typed, only displayed.
-
- The blah_u() routines accept an unsigned character value in character-set
- blah, and return the Unicode translation, or 0xfffd if the character is not
- defined in Unicode. The 8th bit of the argument should be ignored, a`la ISO
- 4873 and 2022.
-
- The tx_blah() routines accept a unicode value and return the value of the
- corresponding character in character-set blah, or else -1 if the character
- does not exist in blah. In this case, the full 8-bit value is returned,
- since ISO 2022 only works in the host-to-terminal direction.
-
- NOTE: KERMITFONT should be defined only if we are using the new (still
- hypothetical) Kermit font that has all the VT/Heath/Wyse/TVI graphic
- characters in it. IMPORTANT: all Kermitfont code points need updating to
- the values in the final proposal to the UTC.
-
- LATER NOTE: The needed characters were approved for Unicode 3.1, and
- therefore nothing special should be required to use them, except that it
- will take some time for them to show up in commercial fonts.
-
- TO DO: A lot of the functions can be tightened up -- use ranges when
- possible, sort switch statements in order of frequency, etc.
-*/
-#include "ckcsym.h" /* Includes... */
-#include "ckcdeb.h"
-#include "ckcker.h"
-#include "ckucmd.h"
-#include "ckcxla.h"
-#include "ckuxla.h"
-
-#ifdef UNICODE
-
-#ifdef OS2
-/*
- This material is needed for the integration of TextPS into Kermit 95.
- When printing a file we use the SET FILE CHARACTER-SET value as the input
- character-set and then convert it to the special Latin1 set called
- CourierLatin1 using the Unicode translation functions.
-*/
-struct _pair { int tx; int fc; } TXFC[] = {
- TX_ASCII, FC_USASCII,
- TX_BRITISH, FC_UKASCII,
- TX_CN_FRENCH, FC_FCASCII,
- TX_CP437, FC_CP437,
- TX_CP850, FC_CP850,
- TX_CP852, FC_CP852,
- TX_CP857, -2,
- TX_CP862, FC_CP862,
- TX_CP864, -2,
- TX_CP866, FC_CP866,
- TX_CP869, -2,
- TX_CUBAN, -2,
- TX_CZECH, -2,
- TX_DANISH, -2,
- TX_DECMCS, FC_DECMCS,
- TX_DECSPEC, -2, /* while defined, not in fcs tables */
- TX_DECTECH, -2, /* while defined, not in fcs tables */
- TX_DGI, FC_DGMCS,
- TX_DUTCH, FC_DUASCII,
- TX_FINNISH, FC_FIASCII,
- TX_FRENCH, FC_FRASCII,
- TX_GERMAN, FC_GEASCII,
- TX_HE7, FC_HE7,
- TX_HPR8, FC_HPR8,
- TX_HUNGARIAN, FC_HUASCII,
- TX_ITALIAN, FC_ITASCII,
- TX_J201R, -2,
- TX_J201K, -2,
- TX_KOI7, FC_KOI7,
- TX_KOI8, FC_KOI8,
- TX_KOI8R, FC_KOI8R,
- TX_KOI8U, FC_KOI8U,
- TX_8859_1, FC_1LATIN,
- TX_8859_2, FC_2LATIN,
- TX_8859_3, -2,
- TX_8859_4, -2,
- TX_8859_5, FC_CYRILL,
- TX_8859_6, -2,
- TX_8859_7, -2,
- TX_8859_8, FC_HEBREW,
- TX_8859_9, -2,
- TX_8859_10, -2,
- TX_8859_15, -2,
- TX_MACL1, FC_APPQD,
- TX_NEXT, FC_NEXT,
- TX_NORWEGIAN, FC_NOASCII,
- TX_PORTUGUESE, FC_POASCII,
- TX_SPANISH, FC_SPASCII,
- TX_SWEDISH, FC_SWASCII,
- TX_SWISS, FC_CHASCII,
- TX_ICELANDIC, -2,
- TX_JIS7, -2,
- TX_SHJIS, FC_SHJIS,
- TX_JEUC, FC_JEUC,
- TX_JDEC, FC_JDEC,
- TX_ELOT927, FC_ELOT,
- TX_DGPCGRPH, -2,
- TX_DGLDGRPH, -2,
- TX_DGWPGRPH, -2,
- TX_HPLINE, -2,
- TX_HPMATH, -2,
- TX_QNXGRPH, -2,
- TX_SNIBRACK, -2,
- TX_SNIEURO, -2,
- TX_SNIFACET, -2,
- TX_SNIIBM, -2,
- TX_SNIBLANK, -2,
- TX_CP1252, -2,
- TX_CP1250, FC_CP1250,
- TX_CP1251, FC_CP1251,
- TX_CP1253, -2,
- TX_CP1254, -2,
- TX_CP1257, -2,
- TX_CP856, -2,
- TX_CP855, FC_CP855,
- TX_CP819, FC_1LATIN,
- TX_CP912, FC_2LATIN,
- TX_CP913, -2,
- TX_CP914, -2,
- TX_CP915, FC_CYRILL,
- TX_CP1089, -2,
- TX_CP813, FC_GREEK,
- TX_CP916, FC_HEBREW,
- TX_CP920, -2,
- TX_CP1051, -2,
- TX_CP858, FC_CP858,
- TX_8859_15, FC_9LATIN,
- TX_CP923, FC_CP923,
- TX_ELOT928, -2,
- TX_CP10000, -2,
- TX_CP37, -2,
- TX_CP1255, -2,
- TX_CP1256, -2,
- TX_CP1258, -2,
- TX_MAZOVIA, FC_MAZOVIA,
- TX_APL1, -2,
- TX_APL2, -2,
- TX_APL3, -2,
- TX_APL4, -2,
- TX_APL5, -2,
- TX_TRANSP, FC_TRANSP
-};
-int nTXFC = sizeof(TXFC) / sizeof(struct _pair);
-
-int
-#ifdef CK_ANSIC
-fc2tx(int fc)
-#else
-fc2tx(int c) int fc;
-#endif /* CK_ANSIC */
-{
- int i;
- for (i = 0; i < nTXFC ; i++)
- if (TXFC[i].fc == fc && TXFC[i].tx >= 0)
- return(TXFC[i].tx);
- return(TX_ASCII);
-}
-
-int
-#ifdef CK_ANSIC
-tx2fc(int tx)
-#else
-tx2fc(int x) int tx;
-#endif /* CK_ANSIC */
-{
- int i;
- for (i = 0; i < nTXFC ; i++)
- if (TXFC[i].tx == tx && TXFC[i].fc >= 0)
- return(TXFC[i].fc);
- return(FC_USASCII);
-}
-
-/* SET TERMINAL REMOTE CHARACTER-SET keyword table */
-
-struct keytab txrtab[] = {
- "apl2-ibm", TX_APL4, 0,
- "apl-2741", TX_APL5, 0,
- "apl-dyadic", TX_APL2, 0,
- "apl-iso", TX_APL1, 0,
- "apl-plus-2000", TX_APL3, 0, /* = APL-2000 */
- "arabic-iso", TX_8859_6, 0,
- "ascii", TX_ASCII, 0,
- "british", TX_BRITISH, 0,
- "canadian-french", TX_CN_FRENCH, 0,
- "bulgaria-pc", TX_CP856, 0,
-#ifdef COMMENT
- "cp037", TX_CP37, 0, /* U.S. EBCDIC */
-#endif /* COMMENT */
- "cp10000", TX_CP10000, 0, /* Apple Quickdraw */
- "cp1051", TX_CP1051, 0, /* Same as HP Roman 8 */
- "cp1089", TX_CP1089, 0, /* Same as ISO 8859-6 */
- "cp1250", TX_CP1250, 0, /* Latin-2 Windows */
- "cp1251", TX_CP1251, 0, /* Cyrillic Windows */
- "cp1252", TX_CP1252, 0, /* Latin-1 Windows */
- "cp1253", TX_CP1253, 0, /* Greek Windows */
- "cp1254", TX_CP1254, 0, /* Turkey Windows */
- "cp1255", TX_CP1255, 0, /* Hebrew Windows */
- "cp1256", TX_CP1256, 0, /* Arabic Windows */
- "cp1257", TX_CP1257, 0, /* Latin-4 Windows */
- "cp1258", TX_CP1258, 0, /* Viet Nam Windows */
- "cp437", TX_CP437, 0,
- "cp813", TX_CP813, 0, /* Same as ISO 8859-7 */
- "cp819", TX_CP819, 0, /* Same as ISO 8859-1 */
- "cp850", TX_CP850, 0,
- "cp852", TX_CP852, 0,
- "cp855", TX_CP855, 0, /* Cyrillic */
- "cp856", TX_CP856, CM_INV, /* Bulgaria */
- "cp857", TX_CP857, 0, /* Latin-5 */
- "cp858", TX_CP858, 0, /* Euro modified cp850 */
- "cp862-hebrew", TX_CP862, 0, /* Hebrew */
- "cp864", TX_CP864, 0, /* Arabic */
- "cp866", TX_CP866, 0, /* Cyrillic */
- "cp869", TX_CP869, 0, /* Greek */
- "cp912", TX_CP912, 0, /* Same as ISO 8859-2 */
- "cp913", TX_CP913, 0, /* Same as ISO 8859-3 */
- "cp914", TX_CP914, 0, /* Same as ISO 8859-4 */
- "cp915", TX_CP915, 0, /* Same as ISO 8859-5 */
- "cp916", TX_CP916, 0, /* Same as ISO 8859-8 */
- "cp920", TX_CP920, 0, /* Same as ISO 8859-9 */
- "cp923", TX_CP923, 0, /* Same as ISO 8859-15 */
-#ifdef COMMENT
-/* Not implemented yet */
- "cuban", TX_CUBAN, 0,
-#endif /* COMMENT */
- "cyrillic-iso", TX_8859_5, 0,
-#ifdef COMMENT
-/* Not implemented yet */
- "czech", TX_CZECH, 0,
-#endif /* COMMENT */
- "danish", TX_DANISH, 0,
- "dec-m", TX_DECMCS, CM_ABR|CM_INV,
- "dec-mcs", TX_DECMCS, CM_INV,
- "dec-multinational",TX_DECMCS, 0,
-#ifdef COMMENT /* Not implemented yet */
- "dec-kanji", TX_JDEC, 0,
-#endif /* COMMENT */
- "dec-special", TX_DECSPEC, 0,
- "dec-technical", TX_DECTECH, 0,
- "dg-international", TX_DGI, 0,
- "dg-linedrawing", TX_DGLDGRPH, 0,
- "dg-specialgraphcs",TX_DGPCGRPH, 0,
- "dg-wordprocessing",TX_DGWPGRPH, 0,
- "dutch", TX_DUTCH, 0,
- "elot927-greek", TX_ELOT927, 0,
- "elot928-greek", TX_ELOT928, 0,
- "finnish", TX_FINNISH, 0,
- "french", TX_FRENCH, 0,
- "german", TX_GERMAN, 0,
- "greek-iso", TX_8859_7, 0,
- "hebrew-7", TX_HE7, 0,
- "hebrew-iso", TX_8859_8, 0,
- "hp-line-drawing", TX_HPLINE, 0,
- "hp-math/technical",TX_HPMATH, 0,
- "hp-roman8", TX_HPR8, 0,
- "hungarian", TX_HUNGARIAN, 0,
- "italian", TX_ITALIAN, 0,
- "japanese-roman", TX_J201R, 0,
-#ifdef COMMENT /* Not implemented yet */
- "japanese-euc", TX_JEUC, 0,
- "jis7-kanji", TX_JIS7, 0,
-#endif /* COMMENT */
- "katakana", TX_J201K, 0,
- "ko", TX_KOI8, CM_ABR|CM_INV,
- "koi", TX_KOI8, CM_ABR|CM_INV,
- "koi8", TX_KOI8, 0,
- "koi8-cyrillic", TX_KOI8, CM_INV,
- "koi8r", TX_KOI8R, 0,
- "koi8u", TX_KOI8U, 0,
- "l", TX_8859_1, CM_ABR|CM_INV,
- "la", TX_8859_1, CM_ABR|CM_INV,
- "lat", TX_8859_1, CM_ABR|CM_INV,
- "lati", TX_8859_1, CM_ABR|CM_INV,
- "latin", TX_8859_1, CM_ABR|CM_INV,
- "latin1-iso", TX_8859_1, 0,
- "latin2-iso", TX_8859_2, 0,
- "latin3-iso", TX_8859_3, 0,
- "latin4-iso", TX_8859_4, 0,
- "latin5-iso", TX_8859_9, 0,
- "latin6-iso", TX_8859_10, 0,
- "latin9-iso", TX_8859_15, 0,
- "macintosh-latin", TX_MACL1, 0,
- "mazovia-pc", TX_MAZOVIA, 0,
- "next-multinational",TX_NEXT, 0,
- "norwegian", TX_NORWEGIAN, 0,
- "portuguese", TX_PORTUGUESE, 0,
- "qnx-console", TX_QNXGRPH, 0,
-#ifdef COMMENT /* Not implemented yet */
- "shift-jis", TX_SHJIS, 0,
-#endif /* COMMENT */
- "short-koi", TX_KOI7, 0,
- "sni-blanks", TX_SNIBLANK, 0,
- "sni-brackets", TX_SNIBRACK, 0,
- "sni-euro", TX_SNIEURO, 0,
- "sni-facet", TX_SNIFACET, 0,
- "sni-ibm", TX_SNIIBM, 0,
- "spanish", TX_SPANISH, 0,
- "swedish", TX_SWEDISH, 0,
- "swiss", TX_SWISS, 0,
- "transparent", TX_TRANSP, 0,
-#ifdef COMMENT
- "utf7", TX_UTF7, 0,
-#endif /* COMMENT */
- "utf8", TX_UTF8, 0,
- "", 0, 0
-};
-int ntxrtab = sizeof(txrtab)/sizeof(struct keytab) - 1;
-#endif /* OS2 */
-
-#ifdef KANJI
-/*
- All Kanji/Unicode translations are based on the Unicode 3.0
- Shift-JIS mapping. Other character sets, like EUC-JP, JIS-7, etc,
- are transformed algorithmically to/from Shift-JIS before/after
- conversion to/from Unicode. This is because Kanji/Unicode mapping
- tables add about 120K to the program, and we don't want to do this
- for each Kanji character set.
-*/
-static USHORT /* Shift-JIS to Unicode */
-sju_8140[] = { /* 0x8140 thru 0x9ffc */
- 0x3000, 0x3001, 0x3002, 0xff0c, 0xff0e, 0x30fb, 0xff1a, 0xff1b,
- 0xff1f, 0xff01, 0x309b, 0x309c, 0x00b4, 0xff40, 0x00a8, 0xff3e,
- 0xffe3, 0xff3f, 0x30fd, 0x30fe, 0x309d, 0x309e, 0x3003, 0x4edd,
- 0x3005, 0x3006, 0x3007, 0x30fc, 0x2015, 0x2010, 0xff0f, 0x005c,
- 0x301c, 0x2016, 0xff5c, 0x2026, 0x2025, 0x2018, 0x2019, 0x201c,
- 0x201d, 0xff08, 0xff09, 0x3014, 0x3015, 0xff3b, 0xff3d, 0xff5b,
- 0xff5d, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, 0x300d, 0x300e,
- 0x300f, 0x3010, 0x3011, 0xff0b, 0x2212, 0x00b1, 0x00d7, 0xfffd,
- 0x00f7, 0xff1d, 0x2260, 0xff1c, 0xff1e, 0x2266, 0x2267, 0x221e,
- 0x2234, 0x2642, 0x2640, 0x00b0, 0x2032, 0x2033, 0x2103, 0xffe5,
- 0xff04, 0x00a2, 0x00a3, 0xff05, 0xff03, 0xff06, 0xff0a, 0xff20,
- 0x00a7, 0x2606, 0x2605, 0x25cb, 0x25cf, 0x25ce, 0x25c7, 0x25c6,
- 0x25a1, 0x25a0, 0x25b3, 0x25b2, 0x25bd, 0x25bc, 0x203b, 0x3012,
- 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x2208, 0x220b, 0x2286, 0x2287, 0x2282, 0x2283, 0x222a, 0x2229,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x2227, 0x2228, 0x00ac, 0x21d2, 0x21d4, 0x2200, 0x2203, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x2220, 0x22a5, 0x2312, 0x2202, 0x2207, 0x2261,
- 0x2252, 0x226a, 0x226b, 0x221a, 0x223d, 0x221d, 0x2235, 0x222b,
- 0x222c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x212b, 0x2030, 0x266f, 0x266d, 0x266a, 0x2020, 0x2021, 0x00b6,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x25ef, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xff10,
- 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18,
- 0xff19, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28,
- 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30,
- 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38,
- 0xff39, 0xff3a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47,
- 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f,
- 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57,
- 0xff58, 0xff59, 0xff5a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x3041,
- 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049,
- 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, 0x3051,
- 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, 0x3059,
- 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, 0x3061,
- 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, 0x3069,
- 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, 0x3071,
- 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079,
- 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, 0x3081,
- 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, 0x3089,
- 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, 0x3091,
- 0x3092, 0x3093, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8,
- 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0,
- 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8,
- 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0,
- 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 0x30c8,
- 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0,
- 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 0x30d8,
- 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0xfffd,
- 0x30e0, 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7,
- 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef,
- 0x30f0, 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x0391,
- 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399,
- 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1,
- 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x03b1,
- 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9,
- 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1,
- 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416,
- 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
- 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426,
- 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e,
- 0x042f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436,
- 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0xfffd,
- 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445,
- 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d,
- 0x044e, 0x044f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2500,
- 0x2502, 0x250c, 0x2510, 0x2518, 0x2514, 0x251c, 0x252c, 0x2524,
- 0x2534, 0x253c, 0x2501, 0x2503, 0x250f, 0x2513, 0x251b, 0x2517,
- 0x2523, 0x2533, 0x252b, 0x253b, 0x254b, 0x2520, 0x252f, 0x2528,
- 0x2537, 0x253f, 0x251d, 0x2530, 0x2525, 0x2538, 0x2542, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x4e9c,
- 0x5516, 0x5a03, 0x963f, 0x54c0, 0x611b, 0x6328, 0x59f6, 0x9022,
- 0x8475, 0x831c, 0x7a50, 0x60aa, 0x63e1, 0x6e25, 0x65ed, 0x8466,
- 0x82a6, 0x9bf5, 0x6893, 0x5727, 0x65a1, 0x6271, 0x5b9b, 0x59d0,
- 0x867b, 0x98f4, 0x7d62, 0x7dbe, 0x9b8e, 0x6216, 0x7c9f, 0x88b7,
- 0x5b89, 0x5eb5, 0x6309, 0x6697, 0x6848, 0x95c7, 0x978d, 0x674f,
- 0x4ee5, 0x4f0a, 0x4f4d, 0x4f9d, 0x5049, 0x56f2, 0x5937, 0x59d4,
- 0x5a01, 0x5c09, 0x60df, 0x610f, 0x6170, 0x6613, 0x6905, 0x70ba,
- 0x754f, 0x7570, 0x79fb, 0x7dad, 0x7def, 0x80c3, 0x840e, 0x8863,
- 0x8b02, 0x9055, 0x907a, 0x533b, 0x4e95, 0x4ea5, 0x57df, 0x80b2,
- 0x90c1, 0x78ef, 0x4e00, 0x58f1, 0x6ea2, 0x9038, 0x7a32, 0x8328,
- 0x828b, 0x9c2f, 0x5141, 0x5370, 0x54bd, 0x54e1, 0x56e0, 0x59fb,
- 0x5f15, 0x98f2, 0x6deb, 0x80e4, 0x852d, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9662, 0x9670, 0x96a0, 0x97fb, 0x540b, 0x53f3, 0x5b87, 0x70cf,
- 0x7fbd, 0x8fc2, 0x96e8, 0x536f, 0x9d5c, 0x7aba, 0x4e11, 0x7893,
- 0x81fc, 0x6e26, 0x5618, 0x5504, 0x6b1d, 0x851a, 0x9c3b, 0x59e5,
- 0x53a9, 0x6d66, 0x74dc, 0x958f, 0x5642, 0x4e91, 0x904b, 0x96f2,
- 0x834f, 0x990c, 0x53e1, 0x55b6, 0x5b30, 0x5f71, 0x6620, 0x66f3,
- 0x6804, 0x6c38, 0x6cf3, 0x6d29, 0x745b, 0x76c8, 0x7a4e, 0x9834,
- 0x82f1, 0x885b, 0x8a60, 0x92ed, 0x6db2, 0x75ab, 0x76ca, 0x99c5,
- 0x60a6, 0x8b01, 0x8d8a, 0x95b2, 0x698e, 0x53ad, 0x5186, 0xfffd,
- 0x5712, 0x5830, 0x5944, 0x5bb4, 0x5ef6, 0x6028, 0x63a9, 0x63f4,
- 0x6cbf, 0x6f14, 0x708e, 0x7114, 0x7159, 0x71d5, 0x733f, 0x7e01,
- 0x8276, 0x82d1, 0x8597, 0x9060, 0x925b, 0x9d1b, 0x5869, 0x65bc,
- 0x6c5a, 0x7525, 0x51f9, 0x592e, 0x5965, 0x5f80, 0x5fdc, 0x62bc,
- 0x65fa, 0x6a2a, 0x6b27, 0x6bb4, 0x738b, 0x7fc1, 0x8956, 0x9d2c,
- 0x9d0e, 0x9ec4, 0x5ca1, 0x6c96, 0x837b, 0x5104, 0x5c4b, 0x61b6,
- 0x81c6, 0x6876, 0x7261, 0x4e59, 0x4ffa, 0x5378, 0x6069, 0x6e29,
- 0x7a4f, 0x97f3, 0x4e0b, 0x5316, 0x4eee, 0x4f55, 0x4f3d, 0x4fa1,
- 0x4f73, 0x52a0, 0x53ef, 0x5609, 0x590f, 0x5ac1, 0x5bb6, 0x5be1,
- 0x79d1, 0x6687, 0x679c, 0x67b6, 0x6b4c, 0x6cb3, 0x706b, 0x73c2,
- 0x798d, 0x79be, 0x7a3c, 0x7b87, 0x82b1, 0x82db, 0x8304, 0x8377,
- 0x83ef, 0x83d3, 0x8766, 0x8ab2, 0x5629, 0x8ca8, 0x8fe6, 0x904e,
- 0x971e, 0x868a, 0x4fc4, 0x5ce8, 0x6211, 0x7259, 0x753b, 0x81e5,
- 0x82bd, 0x86fe, 0x8cc0, 0x96c5, 0x9913, 0x99d5, 0x4ecb, 0x4f1a,
- 0x89e3, 0x56de, 0x584a, 0x58ca, 0x5efb, 0x5feb, 0x602a, 0x6094,
- 0x6062, 0x61d0, 0x6212, 0x62d0, 0x6539, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9b41, 0x6666, 0x68b0, 0x6d77, 0x7070, 0x754c, 0x7686, 0x7d75,
- 0x82a5, 0x87f9, 0x958b, 0x968e, 0x8c9d, 0x51f1, 0x52be, 0x5916,
- 0x54b3, 0x5bb3, 0x5d16, 0x6168, 0x6982, 0x6daf, 0x788d, 0x84cb,
- 0x8857, 0x8a72, 0x93a7, 0x9ab8, 0x6d6c, 0x99a8, 0x86d9, 0x57a3,
- 0x67ff, 0x86ce, 0x920e, 0x5283, 0x5687, 0x5404, 0x5ed3, 0x62e1,
- 0x64b9, 0x683c, 0x6838, 0x6bbb, 0x7372, 0x78ba, 0x7a6b, 0x899a,
- 0x89d2, 0x8d6b, 0x8f03, 0x90ed, 0x95a3, 0x9694, 0x9769, 0x5b66,
- 0x5cb3, 0x697d, 0x984d, 0x984e, 0x639b, 0x7b20, 0x6a2b, 0xfffd,
- 0x6a7f, 0x68b6, 0x9c0d, 0x6f5f, 0x5272, 0x559d, 0x6070, 0x62ec,
- 0x6d3b, 0x6e07, 0x6ed1, 0x845b, 0x8910, 0x8f44, 0x4e14, 0x9c39,
- 0x53f6, 0x691b, 0x6a3a, 0x9784, 0x682a, 0x515c, 0x7ac3, 0x84b2,
- 0x91dc, 0x938c, 0x565b, 0x9d28, 0x6822, 0x8305, 0x8431, 0x7ca5,
- 0x5208, 0x82c5, 0x74e6, 0x4e7e, 0x4f83, 0x51a0, 0x5bd2, 0x520a,
- 0x52d8, 0x52e7, 0x5dfb, 0x559a, 0x582a, 0x59e6, 0x5b8c, 0x5b98,
- 0x5bdb, 0x5e72, 0x5e79, 0x60a3, 0x611f, 0x6163, 0x61be, 0x63db,
- 0x6562, 0x67d1, 0x6853, 0x68fa, 0x6b3e, 0x6b53, 0x6c57, 0x6f22,
- 0x6f97, 0x6f45, 0x74b0, 0x7518, 0x76e3, 0x770b, 0x7aff, 0x7ba1,
- 0x7c21, 0x7de9, 0x7f36, 0x7ff0, 0x809d, 0x8266, 0x839e, 0x89b3,
- 0x8acc, 0x8cab, 0x9084, 0x9451, 0x9593, 0x9591, 0x95a2, 0x9665,
- 0x97d3, 0x9928, 0x8218, 0x4e38, 0x542b, 0x5cb8, 0x5dcc, 0x73a9,
- 0x764c, 0x773c, 0x5ca9, 0x7feb, 0x8d0b, 0x96c1, 0x9811, 0x9854,
- 0x9858, 0x4f01, 0x4f0e, 0x5371, 0x559c, 0x5668, 0x57fa, 0x5947,
- 0x5b09, 0x5bc4, 0x5c90, 0x5e0c, 0x5e7e, 0x5fcc, 0x63ee, 0x673a,
- 0x65d7, 0x65e2, 0x671f, 0x68cb, 0x68c4, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x6a5f, 0x5e30, 0x6bc5, 0x6c17, 0x6c7d, 0x757f, 0x7948, 0x5b63,
- 0x7a00, 0x7d00, 0x5fbd, 0x898f, 0x8a18, 0x8cb4, 0x8d77, 0x8ecc,
- 0x8f1d, 0x98e2, 0x9a0e, 0x9b3c, 0x4e80, 0x507d, 0x5100, 0x5993,
- 0x5b9c, 0x622f, 0x6280, 0x64ec, 0x6b3a, 0x72a0, 0x7591, 0x7947,
- 0x7fa9, 0x87fb, 0x8abc, 0x8b70, 0x63ac, 0x83ca, 0x97a0, 0x5409,
- 0x5403, 0x55ab, 0x6854, 0x6a58, 0x8a70, 0x7827, 0x6775, 0x9ecd,
- 0x5374, 0x5ba2, 0x811a, 0x8650, 0x9006, 0x4e18, 0x4e45, 0x4ec7,
- 0x4f11, 0x53ca, 0x5438, 0x5bae, 0x5f13, 0x6025, 0x6551, 0xfffd,
- 0x673d, 0x6c42, 0x6c72, 0x6ce3, 0x7078, 0x7403, 0x7a76, 0x7aae,
- 0x7b08, 0x7d1a, 0x7cfe, 0x7d66, 0x65e7, 0x725b, 0x53bb, 0x5c45,
- 0x5de8, 0x62d2, 0x62e0, 0x6319, 0x6e20, 0x865a, 0x8a31, 0x8ddd,
- 0x92f8, 0x6f01, 0x79a6, 0x9b5a, 0x4ea8, 0x4eab, 0x4eac, 0x4f9b,
- 0x4fa0, 0x50d1, 0x5147, 0x7af6, 0x5171, 0x51f6, 0x5354, 0x5321,
- 0x537f, 0x53eb, 0x55ac, 0x5883, 0x5ce1, 0x5f37, 0x5f4a, 0x602f,
- 0x6050, 0x606d, 0x631f, 0x6559, 0x6a4b, 0x6cc1, 0x72c2, 0x72ed,
- 0x77ef, 0x80f8, 0x8105, 0x8208, 0x854e, 0x90f7, 0x93e1, 0x97ff,
- 0x9957, 0x9a5a, 0x4ef0, 0x51dd, 0x5c2d, 0x6681, 0x696d, 0x5c40,
- 0x66f2, 0x6975, 0x7389, 0x6850, 0x7c81, 0x50c5, 0x52e4, 0x5747,
- 0x5dfe, 0x9326, 0x65a4, 0x6b23, 0x6b3d, 0x7434, 0x7981, 0x79bd,
- 0x7b4b, 0x7dca, 0x82b9, 0x83cc, 0x887f, 0x895f, 0x8b39, 0x8fd1,
- 0x91d1, 0x541f, 0x9280, 0x4e5d, 0x5036, 0x53e5, 0x533a, 0x72d7,
- 0x7396, 0x77e9, 0x82e6, 0x8eaf, 0x99c6, 0x99c8, 0x99d2, 0x5177,
- 0x611a, 0x865e, 0x55b0, 0x7a7a, 0x5076, 0x5bd3, 0x9047, 0x9685,
- 0x4e32, 0x6adb, 0x91e7, 0x5c51, 0x5c48, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x6398, 0x7a9f, 0x6c93, 0x9774, 0x8f61, 0x7aaa, 0x718a, 0x9688,
- 0x7c82, 0x6817, 0x7e70, 0x6851, 0x936c, 0x52f2, 0x541b, 0x85ab,
- 0x8a13, 0x7fa4, 0x8ecd, 0x90e1, 0x5366, 0x8888, 0x7941, 0x4fc2,
- 0x50be, 0x5211, 0x5144, 0x5553, 0x572d, 0x73ea, 0x578b, 0x5951,
- 0x5f62, 0x5f84, 0x6075, 0x6176, 0x6167, 0x61a9, 0x63b2, 0x643a,
- 0x656c, 0x666f, 0x6842, 0x6e13, 0x7566, 0x7a3d, 0x7cfb, 0x7d4c,
- 0x7d99, 0x7e4b, 0x7f6b, 0x830e, 0x834a, 0x86cd, 0x8a08, 0x8a63,
- 0x8b66, 0x8efd, 0x981a, 0x9d8f, 0x82b8, 0x8fce, 0x9be8, 0xfffd,
- 0x5287, 0x621f, 0x6483, 0x6fc0, 0x9699, 0x6841, 0x5091, 0x6b20,
- 0x6c7a, 0x6f54, 0x7a74, 0x7d50, 0x8840, 0x8a23, 0x6708, 0x4ef6,
- 0x5039, 0x5026, 0x5065, 0x517c, 0x5238, 0x5263, 0x55a7, 0x570f,
- 0x5805, 0x5acc, 0x5efa, 0x61b2, 0x61f8, 0x62f3, 0x6372, 0x691c,
- 0x6a29, 0x727d, 0x72ac, 0x732e, 0x7814, 0x786f, 0x7d79, 0x770c,
- 0x80a9, 0x898b, 0x8b19, 0x8ce2, 0x8ed2, 0x9063, 0x9375, 0x967a,
- 0x9855, 0x9a13, 0x9e78, 0x5143, 0x539f, 0x53b3, 0x5e7b, 0x5f26,
- 0x6e1b, 0x6e90, 0x7384, 0x73fe, 0x7d43, 0x8237, 0x8a00, 0x8afa,
- 0x9650, 0x4e4e, 0x500b, 0x53e4, 0x547c, 0x56fa, 0x59d1, 0x5b64,
- 0x5df1, 0x5eab, 0x5f27, 0x6238, 0x6545, 0x67af, 0x6e56, 0x72d0,
- 0x7cca, 0x88b4, 0x80a1, 0x80e1, 0x83f0, 0x864e, 0x8a87, 0x8de8,
- 0x9237, 0x96c7, 0x9867, 0x9f13, 0x4e94, 0x4e92, 0x4f0d, 0x5348,
- 0x5449, 0x543e, 0x5a2f, 0x5f8c, 0x5fa1, 0x609f, 0x68a7, 0x6a8e,
- 0x745a, 0x7881, 0x8a9e, 0x8aa4, 0x8b77, 0x9190, 0x4e5e, 0x9bc9,
- 0x4ea4, 0x4f7c, 0x4faf, 0x5019, 0x5016, 0x5149, 0x516c, 0x529f,
- 0x52b9, 0x52fe, 0x539a, 0x53e3, 0x5411, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x540e, 0x5589, 0x5751, 0x57a2, 0x597d, 0x5b54, 0x5b5d, 0x5b8f,
- 0x5de5, 0x5de7, 0x5df7, 0x5e78, 0x5e83, 0x5e9a, 0x5eb7, 0x5f18,
- 0x6052, 0x614c, 0x6297, 0x62d8, 0x63a7, 0x653b, 0x6602, 0x6643,
- 0x66f4, 0x676d, 0x6821, 0x6897, 0x69cb, 0x6c5f, 0x6d2a, 0x6d69,
- 0x6e2f, 0x6e9d, 0x7532, 0x7687, 0x786c, 0x7a3f, 0x7ce0, 0x7d05,
- 0x7d18, 0x7d5e, 0x7db1, 0x8015, 0x8003, 0x80af, 0x80b1, 0x8154,
- 0x818f, 0x822a, 0x8352, 0x884c, 0x8861, 0x8b1b, 0x8ca2, 0x8cfc,
- 0x90ca, 0x9175, 0x9271, 0x783f, 0x92fc, 0x95a4, 0x964d, 0xfffd,
- 0x9805, 0x9999, 0x9ad8, 0x9d3b, 0x525b, 0x52ab, 0x53f7, 0x5408,
- 0x58d5, 0x62f7, 0x6fe0, 0x8c6a, 0x8f5f, 0x9eb9, 0x514b, 0x523b,
- 0x544a, 0x56fd, 0x7a40, 0x9177, 0x9d60, 0x9ed2, 0x7344, 0x6f09,
- 0x8170, 0x7511, 0x5ffd, 0x60da, 0x9aa8, 0x72db, 0x8fbc, 0x6b64,
- 0x9803, 0x4eca, 0x56f0, 0x5764, 0x58be, 0x5a5a, 0x6068, 0x61c7,
- 0x660f, 0x6606, 0x6839, 0x68b1, 0x6df7, 0x75d5, 0x7d3a, 0x826e,
- 0x9b42, 0x4e9b, 0x4f50, 0x53c9, 0x5506, 0x5d6f, 0x5de6, 0x5dee,
- 0x67fb, 0x6c99, 0x7473, 0x7802, 0x8a50, 0x9396, 0x88df, 0x5750,
- 0x5ea7, 0x632b, 0x50b5, 0x50ac, 0x518d, 0x6700, 0x54c9, 0x585e,
- 0x59bb, 0x5bb0, 0x5f69, 0x624d, 0x63a1, 0x683d, 0x6b73, 0x6e08,
- 0x707d, 0x91c7, 0x7280, 0x7815, 0x7826, 0x796d, 0x658e, 0x7d30,
- 0x83dc, 0x88c1, 0x8f09, 0x969b, 0x5264, 0x5728, 0x6750, 0x7f6a,
- 0x8ca1, 0x51b4, 0x5742, 0x962a, 0x583a, 0x698a, 0x80b4, 0x54b2,
- 0x5d0e, 0x57fc, 0x7895, 0x9dfa, 0x4f5c, 0x524a, 0x548b, 0x643e,
- 0x6628, 0x6714, 0x67f5, 0x7a84, 0x7b56, 0x7d22, 0x932f, 0x685c,
- 0x9bad, 0x7b39, 0x5319, 0x518a, 0x5237, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x5bdf, 0x62f6, 0x64ae, 0x64e6, 0x672d, 0x6bba, 0x85a9, 0x96d1,
- 0x7690, 0x9bd6, 0x634c, 0x9306, 0x9bab, 0x76bf, 0x6652, 0x4e09,
- 0x5098, 0x53c2, 0x5c71, 0x60e8, 0x6492, 0x6563, 0x685f, 0x71e6,
- 0x73ca, 0x7523, 0x7b97, 0x7e82, 0x8695, 0x8b83, 0x8cdb, 0x9178,
- 0x9910, 0x65ac, 0x66ab, 0x6b8b, 0x4ed5, 0x4ed4, 0x4f3a, 0x4f7f,
- 0x523a, 0x53f8, 0x53f2, 0x55e3, 0x56db, 0x58eb, 0x59cb, 0x59c9,
- 0x59ff, 0x5b50, 0x5c4d, 0x5e02, 0x5e2b, 0x5fd7, 0x601d, 0x6307,
- 0x652f, 0x5b5c, 0x65af, 0x65bd, 0x65e8, 0x679d, 0x6b62, 0xfffd,
- 0x6b7b, 0x6c0f, 0x7345, 0x7949, 0x79c1, 0x7cf8, 0x7d19, 0x7d2b,
- 0x80a2, 0x8102, 0x81f3, 0x8996, 0x8a5e, 0x8a69, 0x8a66, 0x8a8c,
- 0x8aee, 0x8cc7, 0x8cdc, 0x96cc, 0x98fc, 0x6b6f, 0x4e8b, 0x4f3c,
- 0x4f8d, 0x5150, 0x5b57, 0x5bfa, 0x6148, 0x6301, 0x6642, 0x6b21,
- 0x6ecb, 0x6cbb, 0x723e, 0x74bd, 0x75d4, 0x78c1, 0x793a, 0x800c,
- 0x8033, 0x81ea, 0x8494, 0x8f9e, 0x6c50, 0x9e7f, 0x5f0f, 0x8b58,
- 0x9d2b, 0x7afa, 0x8ef8, 0x5b8d, 0x96eb, 0x4e03, 0x53f1, 0x57f7,
- 0x5931, 0x5ac9, 0x5ba4, 0x6089, 0x6e7f, 0x6f06, 0x75be, 0x8cea,
- 0x5b9f, 0x8500, 0x7be0, 0x5072, 0x67f4, 0x829d, 0x5c61, 0x854a,
- 0x7e1e, 0x820e, 0x5199, 0x5c04, 0x6368, 0x8d66, 0x659c, 0x716e,
- 0x793e, 0x7d17, 0x8005, 0x8b1d, 0x8eca, 0x906e, 0x86c7, 0x90aa,
- 0x501f, 0x52fa, 0x5c3a, 0x6753, 0x707c, 0x7235, 0x914c, 0x91c8,
- 0x932b, 0x82e5, 0x5bc2, 0x5f31, 0x60f9, 0x4e3b, 0x53d6, 0x5b88,
- 0x624b, 0x6731, 0x6b8a, 0x72e9, 0x73e0, 0x7a2e, 0x816b, 0x8da3,
- 0x9152, 0x9996, 0x5112, 0x53d7, 0x546a, 0x5bff, 0x6388, 0x6a39,
- 0x7dac, 0x9700, 0x56da, 0x53ce, 0x5468, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x5b97, 0x5c31, 0x5dde, 0x4fee, 0x6101, 0x62fe, 0x6d32, 0x79c0,
- 0x79cb, 0x7d42, 0x7e4d, 0x7fd2, 0x81ed, 0x821f, 0x8490, 0x8846,
- 0x8972, 0x8b90, 0x8e74, 0x8f2f, 0x9031, 0x914b, 0x916c, 0x96c6,
- 0x919c, 0x4ec0, 0x4f4f, 0x5145, 0x5341, 0x5f93, 0x620e, 0x67d4,
- 0x6c41, 0x6e0b, 0x7363, 0x7e26, 0x91cd, 0x9283, 0x53d4, 0x5919,
- 0x5bbf, 0x6dd1, 0x795d, 0x7e2e, 0x7c9b, 0x587e, 0x719f, 0x51fa,
- 0x8853, 0x8ff0, 0x4fca, 0x5cfb, 0x6625, 0x77ac, 0x7ae3, 0x821c,
- 0x99ff, 0x51c6, 0x5faa, 0x65ec, 0x696f, 0x6b89, 0x6df3, 0xfffd,
- 0x6e96, 0x6f64, 0x76fe, 0x7d14, 0x5de1, 0x9075, 0x9187, 0x9806,
- 0x51e6, 0x521d, 0x6240, 0x6691, 0x66d9, 0x6e1a, 0x5eb6, 0x7dd2,
- 0x7f72, 0x66f8, 0x85af, 0x85f7, 0x8af8, 0x52a9, 0x53d9, 0x5973,
- 0x5e8f, 0x5f90, 0x6055, 0x92e4, 0x9664, 0x50b7, 0x511f, 0x52dd,
- 0x5320, 0x5347, 0x53ec, 0x54e8, 0x5546, 0x5531, 0x5617, 0x5968,
- 0x59be, 0x5a3c, 0x5bb5, 0x5c06, 0x5c0f, 0x5c11, 0x5c1a, 0x5e84,
- 0x5e8a, 0x5ee0, 0x5f70, 0x627f, 0x6284, 0x62db, 0x638c, 0x6377,
- 0x6607, 0x660c, 0x662d, 0x6676, 0x677e, 0x68a2, 0x6a1f, 0x6a35,
- 0x6cbc, 0x6d88, 0x6e09, 0x6e58, 0x713c, 0x7126, 0x7167, 0x75c7,
- 0x7701, 0x785d, 0x7901, 0x7965, 0x79f0, 0x7ae0, 0x7b11, 0x7ca7,
- 0x7d39, 0x8096, 0x83d6, 0x848b, 0x8549, 0x885d, 0x88f3, 0x8a1f,
- 0x8a3c, 0x8a54, 0x8a73, 0x8c61, 0x8cde, 0x91a4, 0x9266, 0x937e,
- 0x9418, 0x969c, 0x9798, 0x4e0a, 0x4e08, 0x4e1e, 0x4e57, 0x5197,
- 0x5270, 0x57ce, 0x5834, 0x58cc, 0x5b22, 0x5e38, 0x60c5, 0x64fe,
- 0x6761, 0x6756, 0x6d44, 0x72b6, 0x7573, 0x7a63, 0x84b8, 0x8b72,
- 0x91b8, 0x9320, 0x5631, 0x57f4, 0x98fe, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x62ed, 0x690d, 0x6b96, 0x71ed, 0x7e54, 0x8077, 0x8272, 0x89e6,
- 0x98df, 0x8755, 0x8fb1, 0x5c3b, 0x4f38, 0x4fe1, 0x4fb5, 0x5507,
- 0x5a20, 0x5bdd, 0x5be9, 0x5fc3, 0x614e, 0x632f, 0x65b0, 0x664b,
- 0x68ee, 0x699b, 0x6d78, 0x6df1, 0x7533, 0x75b9, 0x771f, 0x795e,
- 0x79e6, 0x7d33, 0x81e3, 0x82af, 0x85aa, 0x89aa, 0x8a3a, 0x8eab,
- 0x8f9b, 0x9032, 0x91dd, 0x9707, 0x4eba, 0x4ec1, 0x5203, 0x5875,
- 0x58ec, 0x5c0b, 0x751a, 0x5c3d, 0x814e, 0x8a0a, 0x8fc5, 0x9663,
- 0x976d, 0x7b25, 0x8acf, 0x9808, 0x9162, 0x56f3, 0x53a8, 0xfffd,
- 0x9017, 0x5439, 0x5782, 0x5e25, 0x63a8, 0x6c34, 0x708a, 0x7761,
- 0x7c8b, 0x7fe0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968f,
- 0x745e, 0x9ac4, 0x5d07, 0x5d69, 0x6570, 0x67a2, 0x8da8, 0x96db,
- 0x636e, 0x6749, 0x6919, 0x83c5, 0x9817, 0x96c0, 0x88fe, 0x6f84,
- 0x647a, 0x5bf8, 0x4e16, 0x702c, 0x755d, 0x662f, 0x51c4, 0x5236,
- 0x52e2, 0x59d3, 0x5f81, 0x6027, 0x6210, 0x653f, 0x6574, 0x661f,
- 0x6674, 0x68f2, 0x6816, 0x6b63, 0x6e05, 0x7272, 0x751f, 0x76db,
- 0x7cbe, 0x8056, 0x58f0, 0x88fd, 0x897f, 0x8aa0, 0x8a93, 0x8acb,
- 0x901d, 0x9192, 0x9752, 0x9759, 0x6589, 0x7a0e, 0x8106, 0x96bb,
- 0x5e2d, 0x60dc, 0x621a, 0x65a5, 0x6614, 0x6790, 0x77f3, 0x7a4d,
- 0x7c4d, 0x7e3e, 0x810a, 0x8cac, 0x8d64, 0x8de1, 0x8e5f, 0x78a9,
- 0x5207, 0x62d9, 0x63a5, 0x6442, 0x6298, 0x8a2d, 0x7a83, 0x7bc0,
- 0x8aac, 0x96ea, 0x7d76, 0x820c, 0x8749, 0x4ed9, 0x5148, 0x5343,
- 0x5360, 0x5ba3, 0x5c02, 0x5c16, 0x5ddd, 0x6226, 0x6247, 0x64b0,
- 0x6813, 0x6834, 0x6cc9, 0x6d45, 0x6d17, 0x67d3, 0x6f5c, 0x714e,
- 0x717d, 0x65cb, 0x7a7f, 0x7bad, 0x7dda, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x7e4a, 0x7fa8, 0x817a, 0x821b, 0x8239, 0x85a6, 0x8a6e, 0x8cce,
- 0x8df5, 0x9078, 0x9077, 0x92ad, 0x9291, 0x9583, 0x9bae, 0x524d,
- 0x5584, 0x6f38, 0x7136, 0x5168, 0x7985, 0x7e55, 0x81b3, 0x7cce,
- 0x564c, 0x5851, 0x5ca8, 0x63aa, 0x66fe, 0x66fd, 0x695a, 0x72d9,
- 0x758f, 0x758e, 0x790e, 0x7956, 0x79df, 0x7c97, 0x7d20, 0x7d44,
- 0x8607, 0x8a34, 0x963b, 0x9061, 0x9f20, 0x50e7, 0x5275, 0x53cc,
- 0x53e2, 0x5009, 0x55aa, 0x58ee, 0x594f, 0x723d, 0x5b8b, 0x5c64,
- 0x531d, 0x60e3, 0x60f3, 0x635c, 0x6383, 0x633f, 0x63bb, 0xfffd,
- 0x64cd, 0x65e9, 0x66f9, 0x5de3, 0x69cd, 0x69fd, 0x6f15, 0x71e5,
- 0x4e89, 0x75e9, 0x76f8, 0x7a93, 0x7cdf, 0x7dcf, 0x7d9c, 0x8061,
- 0x8349, 0x8358, 0x846c, 0x84bc, 0x85fb, 0x88c5, 0x8d70, 0x9001,
- 0x906d, 0x9397, 0x971c, 0x9a12, 0x50cf, 0x5897, 0x618e, 0x81d3,
- 0x8535, 0x8d08, 0x9020, 0x4fc3, 0x5074, 0x5247, 0x5373, 0x606f,
- 0x6349, 0x675f, 0x6e2c, 0x8db3, 0x901f, 0x4fd7, 0x5c5e, 0x8cca,
- 0x65cf, 0x7d9a, 0x5352, 0x8896, 0x5176, 0x63c3, 0x5b58, 0x5b6b,
- 0x5c0a, 0x640d, 0x6751, 0x905c, 0x4ed6, 0x591a, 0x592a, 0x6c70,
- 0x8a51, 0x553e, 0x5815, 0x59a5, 0x60f0, 0x6253, 0x67c1, 0x8235,
- 0x6955, 0x9640, 0x99c4, 0x9a28, 0x4f53, 0x5806, 0x5bfe, 0x8010,
- 0x5cb1, 0x5e2f, 0x5f85, 0x6020, 0x614b, 0x6234, 0x66ff, 0x6cf0,
- 0x6ede, 0x80ce, 0x817f, 0x82d4, 0x888b, 0x8cb8, 0x9000, 0x902e,
- 0x968a, 0x9edb, 0x9bdb, 0x4ee3, 0x53f0, 0x5927, 0x7b2c, 0x918d,
- 0x984c, 0x9df9, 0x6edd, 0x7027, 0x5353, 0x5544, 0x5b85, 0x6258,
- 0x629e, 0x62d3, 0x6ca2, 0x6fef, 0x7422, 0x8a17, 0x9438, 0x6fc1,
- 0x8afe, 0x8338, 0x51e7, 0x86f8, 0x53ea, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x53e9, 0x4f46, 0x9054, 0x8fb0, 0x596a, 0x8131, 0x5dfd, 0x7aea,
- 0x8fbf, 0x68da, 0x8c37, 0x72f8, 0x9c48, 0x6a3d, 0x8ab0, 0x4e39,
- 0x5358, 0x5606, 0x5766, 0x62c5, 0x63a2, 0x65e6, 0x6b4e, 0x6de1,
- 0x6e5b, 0x70ad, 0x77ed, 0x7aef, 0x7baa, 0x7dbb, 0x803d, 0x80c6,
- 0x86cb, 0x8a95, 0x935b, 0x56e3, 0x58c7, 0x5f3e, 0x65ad, 0x6696,
- 0x6a80, 0x6bb5, 0x7537, 0x8ac7, 0x5024, 0x77e5, 0x5730, 0x5f1b,
- 0x6065, 0x667a, 0x6c60, 0x75f4, 0x7a1a, 0x7f6e, 0x81f4, 0x8718,
- 0x9045, 0x99b3, 0x7bc9, 0x755c, 0x7af9, 0x7b51, 0x84c4, 0xfffd,
- 0x9010, 0x79e9, 0x7a92, 0x8336, 0x5ae1, 0x7740, 0x4e2d, 0x4ef2,
- 0x5b99, 0x5fe0, 0x62bd, 0x663c, 0x67f1, 0x6ce8, 0x866b, 0x8877,
- 0x8a3b, 0x914e, 0x92f3, 0x99d0, 0x6a17, 0x7026, 0x732a, 0x82e7,
- 0x8457, 0x8caf, 0x4e01, 0x5146, 0x51cb, 0x558b, 0x5bf5, 0x5e16,
- 0x5e33, 0x5e81, 0x5f14, 0x5f35, 0x5f6b, 0x5fb4, 0x61f2, 0x6311,
- 0x66a2, 0x671d, 0x6f6e, 0x7252, 0x753a, 0x773a, 0x8074, 0x8139,
- 0x8178, 0x8776, 0x8abf, 0x8adc, 0x8d85, 0x8df3, 0x929a, 0x9577,
- 0x9802, 0x9ce5, 0x52c5, 0x6357, 0x76f4, 0x6715, 0x6c88, 0x73cd,
- 0x8cc3, 0x93ae, 0x9673, 0x6d25, 0x589c, 0x690e, 0x69cc, 0x8ffd,
- 0x939a, 0x75db, 0x901a, 0x585a, 0x6802, 0x63b4, 0x69fb, 0x4f43,
- 0x6f2c, 0x67d8, 0x8fbb, 0x8526, 0x7db4, 0x9354, 0x693f, 0x6f70,
- 0x576a, 0x58f7, 0x5b2c, 0x7d2c, 0x722a, 0x540a, 0x91e3, 0x9db4,
- 0x4ead, 0x4f4e, 0x505c, 0x5075, 0x5243, 0x8c9e, 0x5448, 0x5824,
- 0x5b9a, 0x5e1d, 0x5e95, 0x5ead, 0x5ef7, 0x5f1f, 0x608c, 0x62b5,
- 0x633a, 0x63d0, 0x68af, 0x6c40, 0x7887, 0x798e, 0x7a0b, 0x7de0,
- 0x8247, 0x8a02, 0x8ae6, 0x8e44, 0x9013, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x90b8, 0x912d, 0x91d8, 0x9f0e, 0x6ce5, 0x6458, 0x64e2, 0x6575,
- 0x6ef4, 0x7684, 0x7b1b, 0x9069, 0x93d1, 0x6eba, 0x54f2, 0x5fb9,
- 0x64a4, 0x8f4d, 0x8fed, 0x9244, 0x5178, 0x586b, 0x5929, 0x5c55,
- 0x5e97, 0x6dfb, 0x7e8f, 0x751c, 0x8cbc, 0x8ee2, 0x985b, 0x70b9,
- 0x4f1d, 0x6bbf, 0x6fb1, 0x7530, 0x96fb, 0x514e, 0x5410, 0x5835,
- 0x5857, 0x59ac, 0x5c60, 0x5f92, 0x6597, 0x675c, 0x6e21, 0x767b,
- 0x83df, 0x8ced, 0x9014, 0x90fd, 0x934d, 0x7825, 0x783a, 0x52aa,
- 0x5ea6, 0x571f, 0x5974, 0x6012, 0x5012, 0x515a, 0x51ac, 0xfffd,
- 0x51cd, 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5b95, 0x5cf6,
- 0x5d8b, 0x60bc, 0x6295, 0x642d, 0x6771, 0x6843, 0x68bc, 0x68df,
- 0x76d7, 0x6dd8, 0x6e6f, 0x6d9b, 0x706f, 0x71c8, 0x5f53, 0x75d8,
- 0x7977, 0x7b49, 0x7b54, 0x7b52, 0x7cd6, 0x7d71, 0x5230, 0x8463,
- 0x8569, 0x85e4, 0x8a0e, 0x8b04, 0x8c46, 0x8e0f, 0x9003, 0x900f,
- 0x9419, 0x9676, 0x982d, 0x9a30, 0x95d8, 0x50cd, 0x52d5, 0x540c,
- 0x5802, 0x5c0e, 0x61a7, 0x649e, 0x6d1e, 0x77b3, 0x7ae5, 0x80f4,
- 0x8404, 0x9053, 0x9285, 0x5ce0, 0x9d07, 0x533f, 0x5f97, 0x5fb3,
- 0x6d9c, 0x7279, 0x7763, 0x79bf, 0x7be4, 0x6bd2, 0x72ec, 0x8aad,
- 0x6803, 0x6a61, 0x51f8, 0x7a81, 0x6934, 0x5c4a, 0x9cf6, 0x82eb,
- 0x5bc5, 0x9149, 0x701e, 0x5678, 0x5c6f, 0x60c7, 0x6566, 0x6c8c,
- 0x8c5a, 0x9041, 0x9813, 0x5451, 0x66c7, 0x920d, 0x5948, 0x90a3,
- 0x5185, 0x4e4d, 0x51ea, 0x8599, 0x8b0e, 0x7058, 0x637a, 0x934b,
- 0x6962, 0x99b4, 0x7e04, 0x7577, 0x5357, 0x6960, 0x8edf, 0x96e3,
- 0x6c5d, 0x4e8c, 0x5c3c, 0x5f10, 0x8fe9, 0x5302, 0x8cd1, 0x8089,
- 0x8679, 0x5eff, 0x65e5, 0x4e73, 0x5165, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x5982, 0x5c3f, 0x97ee, 0x4efb, 0x598a, 0x5fcd, 0x8a8d, 0x6fe1,
- 0x79b0, 0x7962, 0x5be7, 0x8471, 0x732b, 0x71b1, 0x5e74, 0x5ff5,
- 0x637b, 0x649a, 0x71c3, 0x7c98, 0x4e43, 0x5efc, 0x4e4b, 0x57dc,
- 0x56a2, 0x60a9, 0x6fc3, 0x7d0d, 0x80fd, 0x8133, 0x81bf, 0x8fb2,
- 0x8997, 0x86a4, 0x5df4, 0x628a, 0x64ad, 0x8987, 0x6777, 0x6ce2,
- 0x6d3e, 0x7436, 0x7834, 0x5a46, 0x7f75, 0x82ad, 0x99ac, 0x4ff3,
- 0x5ec3, 0x62dd, 0x6392, 0x6557, 0x676f, 0x76c3, 0x724c, 0x80cc,
- 0x80ba, 0x8f29, 0x914d, 0x500d, 0x57f9, 0x5a92, 0x6885, 0xfffd,
- 0x6973, 0x7164, 0x72fd, 0x8cb7, 0x58f2, 0x8ce0, 0x966a, 0x9019,
- 0x877f, 0x79e4, 0x77e7, 0x8429, 0x4f2f, 0x5265, 0x535a, 0x62cd,
- 0x67cf, 0x6cca, 0x767d, 0x7b94, 0x7c95, 0x8236, 0x8584, 0x8feb,
- 0x66dd, 0x6f20, 0x7206, 0x7e1b, 0x83ab, 0x99c1, 0x9ea6, 0x51fd,
- 0x7bb1, 0x7872, 0x7bb8, 0x8087, 0x7b48, 0x6ae8, 0x5e61, 0x808c,
- 0x7551, 0x7560, 0x516b, 0x9262, 0x6e8c, 0x767a, 0x9197, 0x9aea,
- 0x4f10, 0x7f70, 0x629c, 0x7b4f, 0x95a5, 0x9ce9, 0x567a, 0x5859,
- 0x86e4, 0x96bc, 0x4f34, 0x5224, 0x534a, 0x53cd, 0x53db, 0x5e06,
- 0x642c, 0x6591, 0x677f, 0x6c3e, 0x6c4e, 0x7248, 0x72af, 0x73ed,
- 0x7554, 0x7e41, 0x822c, 0x85e9, 0x8ca9, 0x7bc4, 0x91c6, 0x7169,
- 0x9812, 0x98ef, 0x633d, 0x6669, 0x756a, 0x76e4, 0x78d0, 0x8543,
- 0x86ee, 0x532a, 0x5351, 0x5426, 0x5983, 0x5e87, 0x5f7c, 0x60b2,
- 0x6249, 0x6279, 0x62ab, 0x6590, 0x6bd4, 0x6ccc, 0x75b2, 0x76ae,
- 0x7891, 0x79d8, 0x7dcb, 0x7f77, 0x80a5, 0x88ab, 0x8ab9, 0x8cbb,
- 0x907f, 0x975e, 0x98db, 0x6a0b, 0x7c38, 0x5099, 0x5c3e, 0x5fae,
- 0x6787, 0x6bd8, 0x7435, 0x7709, 0x7f8e, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9f3b, 0x67ca, 0x7a17, 0x5339, 0x758b, 0x9aed, 0x5f66, 0x819d,
- 0x83f1, 0x8098, 0x5f3c, 0x5fc5, 0x7562, 0x7b46, 0x903c, 0x6867,
- 0x59eb, 0x5a9b, 0x7d10, 0x767e, 0x8b2c, 0x4ff5, 0x5f6a, 0x6a19,
- 0x6c37, 0x6f02, 0x74e2, 0x7968, 0x8868, 0x8a55, 0x8c79, 0x5edf,
- 0x63cf, 0x75c5, 0x79d2, 0x82d7, 0x9328, 0x92f2, 0x849c, 0x86ed,
- 0x9c2d, 0x54c1, 0x5f6c, 0x658c, 0x6d5c, 0x7015, 0x8ca7, 0x8cd3,
- 0x983b, 0x654f, 0x74f6, 0x4e0d, 0x4ed8, 0x57e0, 0x592b, 0x5a66,
- 0x5bcc, 0x51a8, 0x5e03, 0x5e9c, 0x6016, 0x6276, 0x6577, 0xfffd,
- 0x65a7, 0x666e, 0x6d6e, 0x7236, 0x7b26, 0x8150, 0x819a, 0x8299,
- 0x8b5c, 0x8ca0, 0x8ce6, 0x8d74, 0x961c, 0x9644, 0x4fae, 0x64ab,
- 0x6b66, 0x821e, 0x8461, 0x856a, 0x90e8, 0x5c01, 0x6953, 0x98a8,
- 0x847a, 0x8557, 0x4f0f, 0x526f, 0x5fa9, 0x5e45, 0x670d, 0x798f,
- 0x8179, 0x8907, 0x8986, 0x6df5, 0x5f17, 0x6255, 0x6cb8, 0x4ecf,
- 0x7269, 0x9b92, 0x5206, 0x543b, 0x5674, 0x58b3, 0x61a4, 0x626e,
- 0x711a, 0x596e, 0x7c89, 0x7cde, 0x7d1b, 0x96f0, 0x6587, 0x805e,
- 0x4e19, 0x4f75, 0x5175, 0x5840, 0x5e63, 0x5e73, 0x5f0a, 0x67c4,
- 0x4e26, 0x853d, 0x9589, 0x965b, 0x7c73, 0x9801, 0x50fb, 0x58c1,
- 0x7656, 0x78a7, 0x5225, 0x77a5, 0x8511, 0x7b86, 0x504f, 0x5909,
- 0x7247, 0x7bc7, 0x7de8, 0x8fba, 0x8fd4, 0x904d, 0x4fbf, 0x52c9,
- 0x5a29, 0x5f01, 0x97ad, 0x4fdd, 0x8217, 0x92ea, 0x5703, 0x6355,
- 0x6b69, 0x752b, 0x88dc, 0x8f14, 0x7a42, 0x52df, 0x5893, 0x6155,
- 0x620a, 0x66ae, 0x6bcd, 0x7c3f, 0x83e9, 0x5023, 0x4ff8, 0x5305,
- 0x5446, 0x5831, 0x5949, 0x5b9d, 0x5cf0, 0x5cef, 0x5d29, 0x5e96,
- 0x62b1, 0x6367, 0x653e, 0x65b9, 0x670b, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x6cd5, 0x6ce1, 0x70f9, 0x7832, 0x7e2b, 0x80de, 0x82b3, 0x840c,
- 0x84ec, 0x8702, 0x8912, 0x8a2a, 0x8c4a, 0x90a6, 0x92d2, 0x98fd,
- 0x9cf3, 0x9d6c, 0x4e4f, 0x4ea1, 0x508d, 0x5256, 0x574a, 0x59a8,
- 0x5e3d, 0x5fd8, 0x5fd9, 0x623f, 0x66b4, 0x671b, 0x67d0, 0x68d2,
- 0x5192, 0x7d21, 0x80aa, 0x81a8, 0x8b00, 0x8c8c, 0x8cbf, 0x927e,
- 0x9632, 0x5420, 0x982c, 0x5317, 0x50d5, 0x535c, 0x58a8, 0x64b2,
- 0x6734, 0x7267, 0x7766, 0x7a46, 0x91e6, 0x52c3, 0x6ca1, 0x6b86,
- 0x5800, 0x5e4c, 0x5954, 0x672c, 0x7ffb, 0x51e1, 0x76c6, 0xfffd,
- 0x6469, 0x78e8, 0x9b54, 0x9ebb, 0x57cb, 0x59b9, 0x6627, 0x679a,
- 0x6bce, 0x54e9, 0x69d9, 0x5e55, 0x819c, 0x6795, 0x9baa, 0x67fe,
- 0x9c52, 0x685d, 0x4ea6, 0x4fe3, 0x53c8, 0x62b9, 0x672b, 0x6cab,
- 0x8fc4, 0x4fad, 0x7e6d, 0x9ebf, 0x4e07, 0x6162, 0x6e80, 0x6f2b,
- 0x8513, 0x5473, 0x672a, 0x9b45, 0x5df3, 0x7b95, 0x5cac, 0x5bc6,
- 0x871c, 0x6e4a, 0x84d1, 0x7a14, 0x8108, 0x5999, 0x7c8d, 0x6c11,
- 0x7720, 0x52d9, 0x5922, 0x7121, 0x725f, 0x77db, 0x9727, 0x9d61,
- 0x690b, 0x5a7f, 0x5a18, 0x51a5, 0x540d, 0x547d, 0x660e, 0x76df,
- 0x8ff7, 0x9298, 0x9cf4, 0x59ea, 0x725d, 0x6ec5, 0x514d, 0x68c9,
- 0x7dbf, 0x7dec, 0x9762, 0x9eba, 0x6478, 0x6a21, 0x8302, 0x5984,
- 0x5b5f, 0x6bdb, 0x731b, 0x76f2, 0x7db2, 0x8017, 0x8499, 0x5132,
- 0x6728, 0x9ed9, 0x76ee, 0x6762, 0x52ff, 0x9905, 0x5c24, 0x623b,
- 0x7c7e, 0x8cb0, 0x554f, 0x60b6, 0x7d0b, 0x9580, 0x5301, 0x4e5f,
- 0x51b6, 0x591c, 0x723a, 0x8036, 0x91ce, 0x5f25, 0x77e2, 0x5384,
- 0x5f79, 0x7d04, 0x85ac, 0x8a33, 0x8e8d, 0x9756, 0x67f3, 0x85ae,
- 0x9453, 0x6109, 0x6108, 0x6cb9, 0x7652, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8aed, 0x8f38, 0x552f, 0x4f51, 0x512a, 0x52c7, 0x53cb, 0x5ba5,
- 0x5e7d, 0x60a0, 0x6182, 0x63d6, 0x6709, 0x67da, 0x6e67, 0x6d8c,
- 0x7336, 0x7337, 0x7531, 0x7950, 0x88d5, 0x8a98, 0x904a, 0x9091,
- 0x90f5, 0x96c4, 0x878d, 0x5915, 0x4e88, 0x4f59, 0x4e0e, 0x8a89,
- 0x8f3f, 0x9810, 0x50ad, 0x5e7c, 0x5996, 0x5bb9, 0x5eb8, 0x63da,
- 0x63fa, 0x64c1, 0x66dc, 0x694a, 0x69d8, 0x6d0b, 0x6eb6, 0x7194,
- 0x7528, 0x7aaf, 0x7f8a, 0x8000, 0x8449, 0x84c9, 0x8981, 0x8b21,
- 0x8e0a, 0x9065, 0x967d, 0x990a, 0x617e, 0x6291, 0x6b32, 0xfffd,
- 0x6c83, 0x6d74, 0x7fcc, 0x7ffc, 0x6dc0, 0x7f85, 0x87ba, 0x88f8,
- 0x6765, 0x83b1, 0x983c, 0x96f7, 0x6d1b, 0x7d61, 0x843d, 0x916a,
- 0x4e71, 0x5375, 0x5d50, 0x6b04, 0x6feb, 0x85cd, 0x862d, 0x89a7,
- 0x5229, 0x540f, 0x5c65, 0x674e, 0x68a8, 0x7406, 0x7483, 0x75e2,
- 0x88cf, 0x88e1, 0x91cc, 0x96e2, 0x9678, 0x5f8b, 0x7387, 0x7acb,
- 0x844e, 0x63a0, 0x7565, 0x5289, 0x6d41, 0x6e9c, 0x7409, 0x7559,
- 0x786b, 0x7c92, 0x9686, 0x7adc, 0x9f8d, 0x4fb6, 0x616e, 0x65c5,
- 0x865c, 0x4e86, 0x4eae, 0x50da, 0x4e21, 0x51cc, 0x5bee, 0x6599,
- 0x6881, 0x6dbc, 0x731f, 0x7642, 0x77ad, 0x7a1c, 0x7ce7, 0x826f,
- 0x8ad2, 0x907c, 0x91cf, 0x9675, 0x9818, 0x529b, 0x7dd1, 0x502b,
- 0x5398, 0x6797, 0x6dcb, 0x71d0, 0x7433, 0x81e8, 0x8f2a, 0x96a3,
- 0x9c57, 0x9e9f, 0x7460, 0x5841, 0x6d99, 0x7d2f, 0x985e, 0x4ee4,
- 0x4f36, 0x4f8b, 0x51b7, 0x52b1, 0x5dba, 0x601c, 0x73b2, 0x793c,
- 0x82d3, 0x9234, 0x96b7, 0x96f6, 0x970a, 0x9e97, 0x9f62, 0x66a6,
- 0x6b74, 0x5217, 0x52a3, 0x70c8, 0x88c2, 0x5ec9, 0x604b, 0x6190,
- 0x6f23, 0x7149, 0x7c3e, 0x7df4, 0x806f, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x84ee, 0x9023, 0x932c, 0x5442, 0x9b6f, 0x6ad3, 0x7089, 0x8cc2,
- 0x8def, 0x9732, 0x52b4, 0x5a41, 0x5eca, 0x5f04, 0x6717, 0x697c,
- 0x6994, 0x6d6a, 0x6f0f, 0x7262, 0x72fc, 0x7bed, 0x8001, 0x807e,
- 0x874b, 0x90ce, 0x516d, 0x9e93, 0x7984, 0x808b, 0x9332, 0x8ad6,
- 0x502d, 0x548c, 0x8a71, 0x6b6a, 0x8cc4, 0x8107, 0x60d1, 0x67a0,
- 0x9df2, 0x4e99, 0x4e98, 0x9c10, 0x8a6b, 0x85c1, 0x8568, 0x6900,
- 0x6e7e, 0x7897, 0x8155, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5f0c,
- 0x4e10, 0x4e15, 0x4e2a, 0x4e31, 0x4e36, 0x4e3c, 0x4e3f, 0x4e42,
- 0x4e56, 0x4e58, 0x4e82, 0x4e85, 0x8c6b, 0x4e8a, 0x8212, 0x5f0d,
- 0x4e8e, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea2, 0x4eb0, 0x4eb3, 0x4eb6,
- 0x4ece, 0x4ecd, 0x4ec4, 0x4ec6, 0x4ec2, 0x4ed7, 0x4ede, 0x4eed,
- 0x4edf, 0x4ef7, 0x4f09, 0x4f5a, 0x4f30, 0x4f5b, 0x4f5d, 0x4f57,
- 0x4f47, 0x4f76, 0x4f88, 0x4f8f, 0x4f98, 0x4f7b, 0x4f69, 0x4f70,
- 0x4f91, 0x4f6f, 0x4f86, 0x4f96, 0x5118, 0x4fd4, 0x4fdf, 0x4fce,
- 0x4fd8, 0x4fdb, 0x4fd1, 0x4fda, 0x4fd0, 0x4fe4, 0x4fe5, 0x501a,
- 0x5028, 0x5014, 0x502a, 0x5025, 0x5005, 0x4f1c, 0x4ff6, 0x5021,
- 0x5029, 0x502c, 0x4ffe, 0x4fef, 0x5011, 0x5006, 0x5043, 0x5047,
- 0x6703, 0x5055, 0x5050, 0x5048, 0x505a, 0x5056, 0x506c, 0x5078,
- 0x5080, 0x509a, 0x5085, 0x50b4, 0x50b2, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x50c9, 0x50ca, 0x50b3, 0x50c2, 0x50d6, 0x50de, 0x50e5, 0x50ed,
- 0x50e3, 0x50ee, 0x50f9, 0x50f5, 0x5109, 0x5101, 0x5102, 0x5116,
- 0x5115, 0x5114, 0x511a, 0x5121, 0x513a, 0x5137, 0x513c, 0x513b,
- 0x513f, 0x5140, 0x5152, 0x514c, 0x5154, 0x5162, 0x7af8, 0x5169,
- 0x516a, 0x516e, 0x5180, 0x5182, 0x56d8, 0x518c, 0x5189, 0x518f,
- 0x5191, 0x5193, 0x5195, 0x5196, 0x51a4, 0x51a6, 0x51a2, 0x51a9,
- 0x51aa, 0x51ab, 0x51b3, 0x51b1, 0x51b2, 0x51b0, 0x51b5, 0x51bd,
- 0x51c5, 0x51c9, 0x51db, 0x51e0, 0x8655, 0x51e9, 0x51ed, 0xfffd,
- 0x51f0, 0x51f5, 0x51fe, 0x5204, 0x520b, 0x5214, 0x520e, 0x5227,
- 0x522a, 0x522e, 0x5233, 0x5239, 0x524f, 0x5244, 0x524b, 0x524c,
- 0x525e, 0x5254, 0x526a, 0x5274, 0x5269, 0x5273, 0x527f, 0x527d,
- 0x528d, 0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8fa8, 0x8fa7,
- 0x52ac, 0x52ad, 0x52bc, 0x52b5, 0x52c1, 0x52cd, 0x52d7, 0x52de,
- 0x52e3, 0x52e6, 0x98ed, 0x52e0, 0x52f3, 0x52f5, 0x52f8, 0x52f9,
- 0x5306, 0x5308, 0x7538, 0x530d, 0x5310, 0x530f, 0x5315, 0x531a,
- 0x5323, 0x532f, 0x5331, 0x5333, 0x5338, 0x5340, 0x5346, 0x5345,
- 0x4e17, 0x5349, 0x534d, 0x51d6, 0x535e, 0x5369, 0x536e, 0x5918,
- 0x537b, 0x5377, 0x5382, 0x5396, 0x53a0, 0x53a6, 0x53a5, 0x53ae,
- 0x53b0, 0x53b6, 0x53c3, 0x7c12, 0x96d9, 0x53df, 0x66fc, 0x71ee,
- 0x53ee, 0x53e8, 0x53ed, 0x53fa, 0x5401, 0x543d, 0x5440, 0x542c,
- 0x542d, 0x543c, 0x542e, 0x5436, 0x5429, 0x541d, 0x544e, 0x548f,
- 0x5475, 0x548e, 0x545f, 0x5471, 0x5477, 0x5470, 0x5492, 0x547b,
- 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54c7, 0x54a2, 0x54b8,
- 0x54a5, 0x54ac, 0x54c4, 0x54c8, 0x54a8, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x54ab, 0x54c2, 0x54a4, 0x54be, 0x54bc, 0x54d8, 0x54e5, 0x54e6,
- 0x550f, 0x5514, 0x54fd, 0x54ee, 0x54ed, 0x54fa, 0x54e2, 0x5539,
- 0x5540, 0x5563, 0x554c, 0x552e, 0x555c, 0x5545, 0x5556, 0x5557,
- 0x5538, 0x5533, 0x555d, 0x5599, 0x5580, 0x54af, 0x558a, 0x559f,
- 0x557b, 0x557e, 0x5598, 0x559e, 0x55ae, 0x557c, 0x5583, 0x55a9,
- 0x5587, 0x55a8, 0x55da, 0x55c5, 0x55df, 0x55c4, 0x55dc, 0x55e4,
- 0x55d4, 0x5614, 0x55f7, 0x5616, 0x55fe, 0x55fd, 0x561b, 0x55f9,
- 0x564e, 0x5650, 0x71df, 0x5634, 0x5636, 0x5632, 0x5638, 0xfffd,
- 0x566b, 0x5664, 0x562f, 0x566c, 0x566a, 0x5686, 0x5680, 0x568a,
- 0x56a0, 0x5694, 0x568f, 0x56a5, 0x56ae, 0x56b6, 0x56b4, 0x56c2,
- 0x56bc, 0x56c1, 0x56c3, 0x56c0, 0x56c8, 0x56ce, 0x56d1, 0x56d3,
- 0x56d7, 0x56ee, 0x56f9, 0x5700, 0x56ff, 0x5704, 0x5709, 0x5708,
- 0x570b, 0x570d, 0x5713, 0x5718, 0x5716, 0x55c7, 0x571c, 0x5726,
- 0x5737, 0x5738, 0x574e, 0x573b, 0x5740, 0x574f, 0x5769, 0x57c0,
- 0x5788, 0x5761, 0x577f, 0x5789, 0x5793, 0x57a0, 0x57b3, 0x57a4,
- 0x57aa, 0x57b0, 0x57c3, 0x57c6, 0x57d4, 0x57d2, 0x57d3, 0x580a,
- 0x57d6, 0x57e3, 0x580b, 0x5819, 0x581d, 0x5872, 0x5821, 0x5862,
- 0x584b, 0x5870, 0x6bc0, 0x5852, 0x583d, 0x5879, 0x5885, 0x58b9,
- 0x589f, 0x58ab, 0x58ba, 0x58de, 0x58bb, 0x58b8, 0x58ae, 0x58c5,
- 0x58d3, 0x58d1, 0x58d7, 0x58d9, 0x58d8, 0x58e5, 0x58dc, 0x58e4,
- 0x58df, 0x58ef, 0x58fa, 0x58f9, 0x58fb, 0x58fc, 0x58fd, 0x5902,
- 0x590a, 0x5910, 0x591b, 0x68a6, 0x5925, 0x592c, 0x592d, 0x5932,
- 0x5938, 0x593e, 0x7ad2, 0x5955, 0x5950, 0x594e, 0x595a, 0x5958,
- 0x5962, 0x5960, 0x5967, 0x596c, 0x5969, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x5978, 0x5981, 0x599d, 0x4f5e, 0x4fab, 0x59a3, 0x59b2, 0x59c6,
- 0x59e8, 0x59dc, 0x598d, 0x59d9, 0x59da, 0x5a25, 0x5a1f, 0x5a11,
- 0x5a1c, 0x5a09, 0x5a1a, 0x5a40, 0x5a6c, 0x5a49, 0x5a35, 0x5a36,
- 0x5a62, 0x5a6a, 0x5a9a, 0x5abc, 0x5abe, 0x5acb, 0x5ac2, 0x5abd,
- 0x5ae3, 0x5ad7, 0x5ae6, 0x5ae9, 0x5ad6, 0x5afa, 0x5afb, 0x5b0c,
- 0x5b0b, 0x5b16, 0x5b32, 0x5ad0, 0x5b2a, 0x5b36, 0x5b3e, 0x5b43,
- 0x5b45, 0x5b40, 0x5b51, 0x5b55, 0x5b5a, 0x5b5b, 0x5b65, 0x5b69,
- 0x5b70, 0x5b73, 0x5b75, 0x5b78, 0x6588, 0x5b7a, 0x5b80, 0xfffd,
- 0x5b83, 0x5ba6, 0x5bb8, 0x5bc3, 0x5bc7, 0x5bc9, 0x5bd4, 0x5bd0,
- 0x5be4, 0x5be6, 0x5be2, 0x5bde, 0x5be5, 0x5beb, 0x5bf0, 0x5bf6,
- 0x5bf3, 0x5c05, 0x5c07, 0x5c08, 0x5c0d, 0x5c13, 0x5c20, 0x5c22,
- 0x5c28, 0x5c38, 0x5c39, 0x5c41, 0x5c46, 0x5c4e, 0x5c53, 0x5c50,
- 0x5c4f, 0x5b71, 0x5c6c, 0x5c6e, 0x4e62, 0x5c76, 0x5c79, 0x5c8c,
- 0x5c91, 0x5c94, 0x599b, 0x5cab, 0x5cbb, 0x5cb6, 0x5cbc, 0x5cb7,
- 0x5cc5, 0x5cbe, 0x5cc7, 0x5cd9, 0x5ce9, 0x5cfd, 0x5cfa, 0x5ced,
- 0x5d8c, 0x5cea, 0x5d0b, 0x5d15, 0x5d17, 0x5d5c, 0x5d1f, 0x5d1b,
- 0x5d11, 0x5d14, 0x5d22, 0x5d1a, 0x5d19, 0x5d18, 0x5d4c, 0x5d52,
- 0x5d4e, 0x5d4b, 0x5d6c, 0x5d73, 0x5d76, 0x5d87, 0x5d84, 0x5d82,
- 0x5da2, 0x5d9d, 0x5dac, 0x5dae, 0x5dbd, 0x5d90, 0x5db7, 0x5dbc,
- 0x5dc9, 0x5dcd, 0x5dd3, 0x5dd2, 0x5dd6, 0x5ddb, 0x5deb, 0x5df2,
- 0x5df5, 0x5e0b, 0x5e1a, 0x5e19, 0x5e11, 0x5e1b, 0x5e36, 0x5e37,
- 0x5e44, 0x5e43, 0x5e40, 0x5e4e, 0x5e57, 0x5e54, 0x5e5f, 0x5e62,
- 0x5e64, 0x5e47, 0x5e75, 0x5e76, 0x5e7a, 0x9ebc, 0x5e7f, 0x5ea0,
- 0x5ec1, 0x5ec2, 0x5ec8, 0x5ed0, 0x5ecf, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x5ed6, 0x5ee3, 0x5edd, 0x5eda, 0x5edb, 0x5ee2, 0x5ee1, 0x5ee8,
- 0x5ee9, 0x5eec, 0x5ef1, 0x5ef3, 0x5ef0, 0x5ef4, 0x5ef8, 0x5efe,
- 0x5f03, 0x5f09, 0x5f5d, 0x5f5c, 0x5f0b, 0x5f11, 0x5f16, 0x5f29,
- 0x5f2d, 0x5f38, 0x5f41, 0x5f48, 0x5f4c, 0x5f4e, 0x5f2f, 0x5f51,
- 0x5f56, 0x5f57, 0x5f59, 0x5f61, 0x5f6d, 0x5f73, 0x5f77, 0x5f83,
- 0x5f82, 0x5f7f, 0x5f8a, 0x5f88, 0x5f91, 0x5f87, 0x5f9e, 0x5f99,
- 0x5f98, 0x5fa0, 0x5fa8, 0x5fad, 0x5fbc, 0x5fd6, 0x5ffb, 0x5fe4,
- 0x5ff8, 0x5ff1, 0x5fdd, 0x60b3, 0x5fff, 0x6021, 0x6060, 0xfffd,
- 0x6019, 0x6010, 0x6029, 0x600e, 0x6031, 0x601b, 0x6015, 0x602b,
- 0x6026, 0x600f, 0x603a, 0x605a, 0x6041, 0x606a, 0x6077, 0x605f,
- 0x604a, 0x6046, 0x604d, 0x6063, 0x6043, 0x6064, 0x6042, 0x606c,
- 0x606b, 0x6059, 0x6081, 0x608d, 0x60e7, 0x6083, 0x609a, 0x6084,
- 0x609b, 0x6096, 0x6097, 0x6092, 0x60a7, 0x608b, 0x60e1, 0x60b8,
- 0x60e0, 0x60d3, 0x60b4, 0x5ff0, 0x60bd, 0x60c6, 0x60b5, 0x60d8,
- 0x614d, 0x6115, 0x6106, 0x60f6, 0x60f7, 0x6100, 0x60f4, 0x60fa,
- 0x6103, 0x6121, 0x60fb, 0x60f1, 0x610d, 0x610e, 0x6147, 0x613e,
- 0x6128, 0x6127, 0x614a, 0x613f, 0x613c, 0x612c, 0x6134, 0x613d,
- 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159, 0x615a, 0x616b,
- 0x6174, 0x616f, 0x6165, 0x6171, 0x615f, 0x615d, 0x6153, 0x6175,
- 0x6199, 0x6196, 0x6187, 0x61ac, 0x6194, 0x619a, 0x618a, 0x6191,
- 0x61ab, 0x61ae, 0x61cc, 0x61ca, 0x61c9, 0x61f7, 0x61c8, 0x61c3,
- 0x61c6, 0x61ba, 0x61cb, 0x7f79, 0x61cd, 0x61e6, 0x61e3, 0x61f6,
- 0x61fa, 0x61f4, 0x61ff, 0x61fd, 0x61fc, 0x61fe, 0x6200, 0x6208,
- 0x6209, 0x620d, 0x620c, 0x6214, 0x621b, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x621e, 0x6221, 0x622a, 0x622e, 0x6230, 0x6232, 0x6233, 0x6241,
- 0x624e, 0x625e, 0x6263, 0x625b, 0x6260, 0x6268, 0x627c, 0x6282,
- 0x6289, 0x627e, 0x6292, 0x6293, 0x6296, 0x62d4, 0x6283, 0x6294,
- 0x62d7, 0x62d1, 0x62bb, 0x62cf, 0x62ff, 0x62c6, 0x64d4, 0x62c8,
- 0x62dc, 0x62cc, 0x62ca, 0x62c2, 0x62c7, 0x629b, 0x62c9, 0x630c,
- 0x62ee, 0x62f1, 0x6327, 0x6302, 0x6308, 0x62ef, 0x62f5, 0x6350,
- 0x633e, 0x634d, 0x641c, 0x634f, 0x6396, 0x638e, 0x6380, 0x63ab,
- 0x6376, 0x63a3, 0x638f, 0x6389, 0x639f, 0x63b5, 0x636b, 0xfffd,
- 0x6369, 0x63be, 0x63e9, 0x63c0, 0x63c6, 0x63e3, 0x63c9, 0x63d2,
- 0x63f6, 0x63c4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436,
- 0x651d, 0x6417, 0x6428, 0x640f, 0x6467, 0x646f, 0x6476, 0x644e,
- 0x652a, 0x6495, 0x6493, 0x64a5, 0x64a9, 0x6488, 0x64bc, 0x64da,
- 0x64d2, 0x64c5, 0x64c7, 0x64bb, 0x64d8, 0x64c2, 0x64f1, 0x64e7,
- 0x8209, 0x64e0, 0x64e1, 0x62ac, 0x64e3, 0x64ef, 0x652c, 0x64f6,
- 0x64f4, 0x64f2, 0x64fa, 0x6500, 0x64fd, 0x6518, 0x651c, 0x6505,
- 0x6524, 0x6523, 0x652b, 0x6534, 0x6535, 0x6537, 0x6536, 0x6538,
- 0x754b, 0x6548, 0x6556, 0x6555, 0x654d, 0x6558, 0x655e, 0x655d,
- 0x6572, 0x6578, 0x6582, 0x6583, 0x8b8a, 0x659b, 0x659f, 0x65ab,
- 0x65b7, 0x65c3, 0x65c6, 0x65c1, 0x65c4, 0x65cc, 0x65d2, 0x65db,
- 0x65d9, 0x65e0, 0x65e1, 0x65f1, 0x6772, 0x660a, 0x6603, 0x65fb,
- 0x6773, 0x6635, 0x6636, 0x6634, 0x661c, 0x664f, 0x6644, 0x6649,
- 0x6641, 0x665e, 0x665d, 0x6664, 0x6667, 0x6668, 0x665f, 0x6662,
- 0x6670, 0x6683, 0x6688, 0x668e, 0x6689, 0x6684, 0x6698, 0x669d,
- 0x66c1, 0x66b9, 0x66c9, 0x66be, 0x66bc, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x66c4, 0x66b8, 0x66d6, 0x66da, 0x66e0, 0x663f, 0x66e6, 0x66e9,
- 0x66f0, 0x66f5, 0x66f7, 0x670f, 0x6716, 0x671e, 0x6726, 0x6727,
- 0x9738, 0x672e, 0x673f, 0x6736, 0x6741, 0x6738, 0x6737, 0x6746,
- 0x675e, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67a9,
- 0x677c, 0x676a, 0x678c, 0x678b, 0x67a6, 0x67a1, 0x6785, 0x67b7,
- 0x67ef, 0x67b4, 0x67ec, 0x67b3, 0x67e9, 0x67b8, 0x67e4, 0x67de,
- 0x67dd, 0x67e2, 0x67ee, 0x67b9, 0x67ce, 0x67c6, 0x67e7, 0x6a9c,
- 0x681e, 0x6846, 0x6829, 0x6840, 0x684d, 0x6832, 0x684e, 0xfffd,
- 0x68b3, 0x682b, 0x6859, 0x6863, 0x6877, 0x687f, 0x689f, 0x688f,
- 0x68ad, 0x6894, 0x689d, 0x689b, 0x6883, 0x6aae, 0x68b9, 0x6874,
- 0x68b5, 0x68a0, 0x68ba, 0x690f, 0x688d, 0x687e, 0x6901, 0x68ca,
- 0x6908, 0x68d8, 0x6922, 0x6926, 0x68e1, 0x690c, 0x68cd, 0x68d4,
- 0x68e7, 0x68d5, 0x6936, 0x6912, 0x6904, 0x68d7, 0x68e3, 0x6925,
- 0x68f9, 0x68e0, 0x68ef, 0x6928, 0x692a, 0x691a, 0x6923, 0x6921,
- 0x68c6, 0x6979, 0x6977, 0x695c, 0x6978, 0x696b, 0x6954, 0x697e,
- 0x696e, 0x6939, 0x6974, 0x693d, 0x6959, 0x6930, 0x6961, 0x695e,
- 0x695d, 0x6981, 0x696a, 0x69b2, 0x69ae, 0x69d0, 0x69bf, 0x69c1,
- 0x69d3, 0x69be, 0x69ce, 0x5be8, 0x69ca, 0x69dd, 0x69bb, 0x69c3,
- 0x69a7, 0x6a2e, 0x6991, 0x69a0, 0x699c, 0x6995, 0x69b4, 0x69de,
- 0x69e8, 0x6a02, 0x6a1b, 0x69ff, 0x6b0a, 0x69f9, 0x69f2, 0x69e7,
- 0x6a05, 0x69b1, 0x6a1e, 0x69ed, 0x6a14, 0x69eb, 0x6a0a, 0x6a12,
- 0x6ac1, 0x6a23, 0x6a13, 0x6a44, 0x6a0c, 0x6a72, 0x6a36, 0x6a78,
- 0x6a47, 0x6a62, 0x6a59, 0x6a66, 0x6a48, 0x6a38, 0x6a22, 0x6a90,
- 0x6a8d, 0x6aa0, 0x6a84, 0x6aa2, 0x6aa3, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x6a97, 0x8617, 0x6abb, 0x6ac3, 0x6ac2, 0x6ab8, 0x6ab3, 0x6aac,
- 0x6ade, 0x6ad1, 0x6adf, 0x6aaa, 0x6ada, 0x6aea, 0x6afb, 0x6b05,
- 0x8616, 0x6afa, 0x6b12, 0x6b16, 0x9b31, 0x6b1f, 0x6b38, 0x6b37,
- 0x76dc, 0x6b39, 0x98ee, 0x6b47, 0x6b43, 0x6b49, 0x6b50, 0x6b59,
- 0x6b54, 0x6b5b, 0x6b5f, 0x6b61, 0x6b78, 0x6b79, 0x6b7f, 0x6b80,
- 0x6b84, 0x6b83, 0x6b8d, 0x6b98, 0x6b95, 0x6b9e, 0x6ba4, 0x6baa,
- 0x6bab, 0x6baf, 0x6bb2, 0x6bb1, 0x6bb3, 0x6bb7, 0x6bbc, 0x6bc6,
- 0x6bcb, 0x6bd3, 0x6bdf, 0x6bec, 0x6beb, 0x6bf3, 0x6bef, 0xfffd,
- 0x9ebe, 0x6c08, 0x6c13, 0x6c14, 0x6c1b, 0x6c24, 0x6c23, 0x6c5e,
- 0x6c55, 0x6c62, 0x6c6a, 0x6c82, 0x6c8d, 0x6c9a, 0x6c81, 0x6c9b,
- 0x6c7e, 0x6c68, 0x6c73, 0x6c92, 0x6c90, 0x6cc4, 0x6cf1, 0x6cd3,
- 0x6cbd, 0x6cd7, 0x6cc5, 0x6cdd, 0x6cae, 0x6cb1, 0x6cbe, 0x6cba,
- 0x6cdb, 0x6cef, 0x6cd9, 0x6cea, 0x6d1f, 0x884d, 0x6d36, 0x6d2b,
- 0x6d3d, 0x6d38, 0x6d19, 0x6d35, 0x6d33, 0x6d12, 0x6d0c, 0x6d63,
- 0x6d93, 0x6d64, 0x6d5a, 0x6d79, 0x6d59, 0x6d8e, 0x6d95, 0x6fe4,
- 0x6d85, 0x6df9, 0x6e15, 0x6e0a, 0x6db5, 0x6dc7, 0x6de6, 0x6db8,
- 0x6dc6, 0x6dec, 0x6dde, 0x6dcc, 0x6de8, 0x6dd2, 0x6dc5, 0x6dfa,
- 0x6dd9, 0x6de4, 0x6dd5, 0x6dea, 0x6dee, 0x6e2d, 0x6e6e, 0x6e2e,
- 0x6e19, 0x6e72, 0x6e5f, 0x6e3e, 0x6e23, 0x6e6b, 0x6e2b, 0x6e76,
- 0x6e4d, 0x6e1f, 0x6e43, 0x6e3a, 0x6e4e, 0x6e24, 0x6eff, 0x6e1d,
- 0x6e38, 0x6e82, 0x6eaa, 0x6e98, 0x6ec9, 0x6eb7, 0x6ed3, 0x6ebd,
- 0x6eaf, 0x6ec4, 0x6eb2, 0x6ed4, 0x6ed5, 0x6e8f, 0x6ea5, 0x6ec2,
- 0x6e9f, 0x6f41, 0x6f11, 0x704c, 0x6eec, 0x6ef8, 0x6efe, 0x6f3f,
- 0x6ef2, 0x6f31, 0x6eef, 0x6f32, 0x6ecc
-};
-
-static USHORT /* Shift-JIS to Unicode */
-sju_e040[] = { /* 0xe040 thru 0xeaa4 */
- 0x6f3e, 0x6f13, 0x6ef7, 0x6f86, 0x6f7a, 0x6f78, 0x6f81, 0x6f80,
- 0x6f6f, 0x6f5b, 0x6ff3, 0x6f6d, 0x6f82, 0x6f7c, 0x6f58, 0x6f8e,
- 0x6f91, 0x6fc2, 0x6f66, 0x6fb3, 0x6fa3, 0x6fa1, 0x6fa4, 0x6fb9,
- 0x6fc6, 0x6faa, 0x6fdf, 0x6fd5, 0x6fec, 0x6fd4, 0x6fd8, 0x6ff1,
- 0x6fee, 0x6fdb, 0x7009, 0x700b, 0x6ffa, 0x7011, 0x7001, 0x700f,
- 0x6ffe, 0x701b, 0x701a, 0x6f74, 0x701d, 0x7018, 0x701f, 0x7030,
- 0x703e, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70af, 0x70f1,
- 0x70ac, 0x70b8, 0x70b3, 0x70ae, 0x70df, 0x70cb, 0x70dd, 0xfffd,
- 0x70d9, 0x7109, 0x70fd, 0x711c, 0x7119, 0x7165, 0x7155, 0x7188,
- 0x7166, 0x7162, 0x714c, 0x7156, 0x716c, 0x718f, 0x71fb, 0x7184,
- 0x7195, 0x71a8, 0x71ac, 0x71d7, 0x71b9, 0x71be, 0x71d2, 0x71c9,
- 0x71d4, 0x71ce, 0x71e0, 0x71ec, 0x71e7, 0x71f5, 0x71fc, 0x71f9,
- 0x71ff, 0x720d, 0x7210, 0x721b, 0x7228, 0x722d, 0x722c, 0x7230,
- 0x7232, 0x723b, 0x723c, 0x723f, 0x7240, 0x7246, 0x724b, 0x7258,
- 0x7274, 0x727e, 0x7282, 0x7281, 0x7287, 0x7292, 0x7296, 0x72a2,
- 0x72a7, 0x72b9, 0x72b2, 0x72c3, 0x72c6, 0x72c4, 0x72ce, 0x72d2,
- 0x72e2, 0x72e0, 0x72e1, 0x72f9, 0x72f7, 0x500f, 0x7317, 0x730a,
- 0x731c, 0x7316, 0x731d, 0x7334, 0x732f, 0x7329, 0x7325, 0x733e,
- 0x734e, 0x734f, 0x9ed8, 0x7357, 0x736a, 0x7368, 0x7370, 0x7378,
- 0x7375, 0x737b, 0x737a, 0x73c8, 0x73b3, 0x73ce, 0x73bb, 0x73c0,
- 0x73e5, 0x73ee, 0x73de, 0x74a2, 0x7405, 0x746f, 0x7425, 0x73f8,
- 0x7432, 0x743a, 0x7455, 0x743f, 0x745f, 0x7459, 0x7441, 0x745c,
- 0x7469, 0x7470, 0x7463, 0x746a, 0x7476, 0x747e, 0x748b, 0x749e,
- 0x74a7, 0x74ca, 0x74cf, 0x74d4, 0x73f1, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x74e0, 0x74e3, 0x74e7, 0x74e9, 0x74ee, 0x74f2, 0x74f0, 0x74f1,
- 0x74f8, 0x74f7, 0x7504, 0x7503, 0x7505, 0x750c, 0x750e, 0x750d,
- 0x7515, 0x7513, 0x751e, 0x7526, 0x752c, 0x753c, 0x7544, 0x754d,
- 0x754a, 0x7549, 0x755b, 0x7546, 0x755a, 0x7569, 0x7564, 0x7567,
- 0x756b, 0x756d, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574, 0x758a,
- 0x7589, 0x7582, 0x7594, 0x759a, 0x759d, 0x75a5, 0x75a3, 0x75c2,
- 0x75b3, 0x75c3, 0x75b5, 0x75bd, 0x75b8, 0x75bc, 0x75b1, 0x75cd,
- 0x75ca, 0x75d2, 0x75d9, 0x75e3, 0x75de, 0x75fe, 0x75ff, 0xfffd,
- 0x75fc, 0x7601, 0x75f0, 0x75fa, 0x75f2, 0x75f3, 0x760b, 0x760d,
- 0x7609, 0x761f, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634,
- 0x7630, 0x763b, 0x7647, 0x7648, 0x7646, 0x765c, 0x7658, 0x7661,
- 0x7662, 0x7668, 0x7669, 0x766a, 0x7667, 0x766c, 0x7670, 0x7672,
- 0x7676, 0x7678, 0x767c, 0x7680, 0x7683, 0x7688, 0x768b, 0x768e,
- 0x7696, 0x7693, 0x7699, 0x769a, 0x76b0, 0x76b4, 0x76b8, 0x76b9,
- 0x76ba, 0x76c2, 0x76cd, 0x76d6, 0x76d2, 0x76de, 0x76e1, 0x76e5,
- 0x76e7, 0x76ea, 0x862f, 0x76fb, 0x7708, 0x7707, 0x7704, 0x7729,
- 0x7724, 0x771e, 0x7725, 0x7726, 0x771b, 0x7737, 0x7738, 0x7747,
- 0x775a, 0x7768, 0x776b, 0x775b, 0x7765, 0x777f, 0x777e, 0x7779,
- 0x778e, 0x778b, 0x7791, 0x77a0, 0x779e, 0x77b0, 0x77b6, 0x77b9,
- 0x77bf, 0x77bc, 0x77bd, 0x77bb, 0x77c7, 0x77cd, 0x77d7, 0x77da,
- 0x77dc, 0x77e3, 0x77ee, 0x77fc, 0x780c, 0x7812, 0x7926, 0x7820,
- 0x792a, 0x7845, 0x788e, 0x7874, 0x7886, 0x787c, 0x789a, 0x788c,
- 0x78a3, 0x78b5, 0x78aa, 0x78af, 0x78d1, 0x78c6, 0x78cb, 0x78d4,
- 0x78be, 0x78bc, 0x78c5, 0x78ca, 0x78ec, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x78e7, 0x78da, 0x78fd, 0x78f4, 0x7907, 0x7912, 0x7911, 0x7919,
- 0x792c, 0x792b, 0x7940, 0x7960, 0x7957, 0x795f, 0x795a, 0x7955,
- 0x7953, 0x797a, 0x797f, 0x798a, 0x799d, 0x79a7, 0x9f4b, 0x79aa,
- 0x79ae, 0x79b3, 0x79b9, 0x79ba, 0x79c9, 0x79d5, 0x79e7, 0x79ec,
- 0x79e1, 0x79e3, 0x7a08, 0x7a0d, 0x7a18, 0x7a19, 0x7a20, 0x7a1f,
- 0x7980, 0x7a31, 0x7a3b, 0x7a3e, 0x7a37, 0x7a43, 0x7a57, 0x7a49,
- 0x7a61, 0x7a62, 0x7a69, 0x9f9d, 0x7a70, 0x7a79, 0x7a7d, 0x7a88,
- 0x7a97, 0x7a95, 0x7a98, 0x7a96, 0x7aa9, 0x7ac8, 0x7ab0, 0xfffd,
- 0x7ab6, 0x7ac5, 0x7ac4, 0x7abf, 0x9083, 0x7ac7, 0x7aca, 0x7acd,
- 0x7acf, 0x7ad5, 0x7ad3, 0x7ad9, 0x7ada, 0x7add, 0x7ae1, 0x7ae2,
- 0x7ae6, 0x7aed, 0x7af0, 0x7b02, 0x7b0f, 0x7b0a, 0x7b06, 0x7b33,
- 0x7b18, 0x7b19, 0x7b1e, 0x7b35, 0x7b28, 0x7b36, 0x7b50, 0x7b7a,
- 0x7b04, 0x7b4d, 0x7b0b, 0x7b4c, 0x7b45, 0x7b75, 0x7b65, 0x7b74,
- 0x7b67, 0x7b70, 0x7b71, 0x7b6c, 0x7b6e, 0x7b9d, 0x7b98, 0x7b9f,
- 0x7b8d, 0x7b9c, 0x7b9a, 0x7b8b, 0x7b92, 0x7b8f, 0x7b5d, 0x7b99,
- 0x7bcb, 0x7bc1, 0x7bcc, 0x7bcf, 0x7bb4, 0x7bc6, 0x7bdd, 0x7be9,
- 0x7c11, 0x7c14, 0x7be6, 0x7be5, 0x7c60, 0x7c00, 0x7c07, 0x7c13,
- 0x7bf3, 0x7bf7, 0x7c17, 0x7c0d, 0x7bf6, 0x7c23, 0x7c27, 0x7c2a,
- 0x7c1f, 0x7c37, 0x7c2b, 0x7c3d, 0x7c4c, 0x7c43, 0x7c54, 0x7c4f,
- 0x7c40, 0x7c50, 0x7c58, 0x7c5f, 0x7c64, 0x7c56, 0x7c65, 0x7c6c,
- 0x7c75, 0x7c83, 0x7c90, 0x7ca4, 0x7cad, 0x7ca2, 0x7cab, 0x7ca1,
- 0x7ca8, 0x7cb3, 0x7cb2, 0x7cb1, 0x7cae, 0x7cb9, 0x7cbd, 0x7cc0,
- 0x7cc5, 0x7cc2, 0x7cd8, 0x7cd2, 0x7cdc, 0x7ce2, 0x9b3b, 0x7cef,
- 0x7cf2, 0x7cf4, 0x7cf6, 0x7cfa, 0x7d06, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x7d02, 0x7d1c, 0x7d15, 0x7d0a, 0x7d45, 0x7d4b, 0x7d2e, 0x7d32,
- 0x7d3f, 0x7d35, 0x7d46, 0x7d73, 0x7d56, 0x7d4e, 0x7d72, 0x7d68,
- 0x7d6e, 0x7d4f, 0x7d63, 0x7d93, 0x7d89, 0x7d5b, 0x7d8f, 0x7d7d,
- 0x7d9b, 0x7dba, 0x7dae, 0x7da3, 0x7db5, 0x7dc7, 0x7dbd, 0x7dab,
- 0x7e3d, 0x7da2, 0x7daf, 0x7ddc, 0x7db8, 0x7d9f, 0x7db0, 0x7dd8,
- 0x7ddd, 0x7de4, 0x7dde, 0x7dfb, 0x7df2, 0x7de1, 0x7e05, 0x7e0a,
- 0x7e23, 0x7e21, 0x7e12, 0x7e31, 0x7e1f, 0x7e09, 0x7e0b, 0x7e22,
- 0x7e46, 0x7e66, 0x7e3b, 0x7e35, 0x7e39, 0x7e43, 0x7e37, 0xfffd,
- 0x7e32, 0x7e3a, 0x7e67, 0x7e5d, 0x7e56, 0x7e5e, 0x7e59, 0x7e5a,
- 0x7e79, 0x7e6a, 0x7e69, 0x7e7c, 0x7e7b, 0x7e83, 0x7dd5, 0x7e7d,
- 0x8fae, 0x7e7f, 0x7e88, 0x7e89, 0x7e8c, 0x7e92, 0x7e90, 0x7e93,
- 0x7e94, 0x7e96, 0x7e8e, 0x7e9b, 0x7e9c, 0x7f38, 0x7f3a, 0x7f45,
- 0x7f4c, 0x7f4d, 0x7f4e, 0x7f50, 0x7f51, 0x7f55, 0x7f54, 0x7f58,
- 0x7f5f, 0x7f60, 0x7f68, 0x7f69, 0x7f67, 0x7f78, 0x7f82, 0x7f86,
- 0x7f83, 0x7f88, 0x7f87, 0x7f8c, 0x7f94, 0x7f9e, 0x7f9d, 0x7f9a,
- 0x7fa3, 0x7faf, 0x7fb2, 0x7fb9, 0x7fae, 0x7fb6, 0x7fb8, 0x8b71,
- 0x7fc5, 0x7fc6, 0x7fca, 0x7fd5, 0x7fd4, 0x7fe1, 0x7fe6, 0x7fe9,
- 0x7ff3, 0x7ff9, 0x98dc, 0x8006, 0x8004, 0x800b, 0x8012, 0x8018,
- 0x8019, 0x801c, 0x8021, 0x8028, 0x803f, 0x803b, 0x804a, 0x8046,
- 0x8052, 0x8058, 0x805a, 0x805f, 0x8062, 0x8068, 0x8073, 0x8072,
- 0x8070, 0x8076, 0x8079, 0x807d, 0x807f, 0x8084, 0x8086, 0x8085,
- 0x809b, 0x8093, 0x809a, 0x80ad, 0x5190, 0x80ac, 0x80db, 0x80e5,
- 0x80d9, 0x80dd, 0x80c4, 0x80da, 0x80d6, 0x8109, 0x80ef, 0x80f1,
- 0x811b, 0x8129, 0x8123, 0x812f, 0x814b, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x968b, 0x8146, 0x813e, 0x8153, 0x8151, 0x80fc, 0x8171, 0x816e,
- 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818a, 0x8180, 0x8182,
- 0x81a0, 0x8195, 0x81a4, 0x81a3, 0x815f, 0x8193, 0x81a9, 0x81b0,
- 0x81b5, 0x81be, 0x81b8, 0x81bd, 0x81c0, 0x81c2, 0x81ba, 0x81c9,
- 0x81cd, 0x81d1, 0x81d9, 0x81d8, 0x81c8, 0x81da, 0x81df, 0x81e0,
- 0x81e7, 0x81fa, 0x81fb, 0x81fe, 0x8201, 0x8202, 0x8205, 0x8207,
- 0x820a, 0x820d, 0x8210, 0x8216, 0x8229, 0x822b, 0x8238, 0x8233,
- 0x8240, 0x8259, 0x8258, 0x825d, 0x825a, 0x825f, 0x8264, 0xfffd,
- 0x8262, 0x8268, 0x826a, 0x826b, 0x822e, 0x8271, 0x8277, 0x8278,
- 0x827e, 0x828d, 0x8292, 0x82ab, 0x829f, 0x82bb, 0x82ac, 0x82e1,
- 0x82e3, 0x82df, 0x82d2, 0x82f4, 0x82f3, 0x82fa, 0x8393, 0x8303,
- 0x82fb, 0x82f9, 0x82de, 0x8306, 0x82dc, 0x8309, 0x82d9, 0x8335,
- 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339, 0x8350, 0x8345,
- 0x832f, 0x832b, 0x8317, 0x8318, 0x8385, 0x839a, 0x83aa, 0x839f,
- 0x83a2, 0x8396, 0x8323, 0x838e, 0x8387, 0x838a, 0x837c, 0x83b5,
- 0x8373, 0x8375, 0x83a0, 0x8389, 0x83a8, 0x83f4, 0x8413, 0x83eb,
- 0x83ce, 0x83fd, 0x8403, 0x83d8, 0x840b, 0x83c1, 0x83f7, 0x8407,
- 0x83e0, 0x83f2, 0x840d, 0x8422, 0x8420, 0x83bd, 0x8438, 0x8506,
- 0x83fb, 0x846d, 0x842a, 0x843c, 0x855a, 0x8484, 0x8477, 0x846b,
- 0x84ad, 0x846e, 0x8482, 0x8469, 0x8446, 0x842c, 0x846f, 0x8479,
- 0x8435, 0x84ca, 0x8462, 0x84b9, 0x84bf, 0x849f, 0x84d9, 0x84cd,
- 0x84bb, 0x84da, 0x84d0, 0x84c1, 0x84c6, 0x84d6, 0x84a1, 0x8521,
- 0x84ff, 0x84f4, 0x8517, 0x8518, 0x852c, 0x851f, 0x8515, 0x8514,
- 0x84fc, 0x8540, 0x8563, 0x8558, 0x8548, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8541, 0x8602, 0x854b, 0x8555, 0x8580, 0x85a4, 0x8588, 0x8591,
- 0x858a, 0x85a8, 0x856d, 0x8594, 0x859b, 0x85ea, 0x8587, 0x859c,
- 0x8577, 0x857e, 0x8590, 0x85c9, 0x85ba, 0x85cf, 0x85b9, 0x85d0,
- 0x85d5, 0x85dd, 0x85e5, 0x85dc, 0x85f9, 0x860a, 0x8613, 0x860b,
- 0x85fe, 0x85fa, 0x8606, 0x8622, 0x861a, 0x8630, 0x863f, 0x864d,
- 0x4e55, 0x8654, 0x865f, 0x8667, 0x8671, 0x8693, 0x86a3, 0x86a9,
- 0x86aa, 0x868b, 0x868c, 0x86b6, 0x86af, 0x86c4, 0x86c6, 0x86b0,
- 0x86c9, 0x8823, 0x86ab, 0x86d4, 0x86de, 0x86e9, 0x86ec, 0xfffd,
- 0x86df, 0x86db, 0x86ef, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703,
- 0x86fb, 0x8711, 0x8709, 0x870d, 0x86f9, 0x870a, 0x8734, 0x873f,
- 0x8737, 0x873b, 0x8725, 0x8729, 0x871a, 0x8760, 0x875f, 0x8778,
- 0x874c, 0x874e, 0x8774, 0x8757, 0x8768, 0x876e, 0x8759, 0x8753,
- 0x8763, 0x876a, 0x8805, 0x87a2, 0x879f, 0x8782, 0x87af, 0x87cb,
- 0x87bd, 0x87c0, 0x87d0, 0x96d6, 0x87ab, 0x87c4, 0x87b3, 0x87c7,
- 0x87c6, 0x87bb, 0x87ef, 0x87f2, 0x87e0, 0x880f, 0x880d, 0x87fe,
- 0x87f6, 0x87f7, 0x880e, 0x87d2, 0x8811, 0x8816, 0x8815, 0x8822,
- 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883b, 0x8844, 0x8842,
- 0x8852, 0x8859, 0x885e, 0x8862, 0x886b, 0x8881, 0x887e, 0x889e,
- 0x8875, 0x887d, 0x88b5, 0x8872, 0x8882, 0x8897, 0x8892, 0x88ae,
- 0x8899, 0x88a2, 0x888d, 0x88a4, 0x88b0, 0x88bf, 0x88b1, 0x88c3,
- 0x88c4, 0x88d4, 0x88d8, 0x88d9, 0x88dd, 0x88f9, 0x8902, 0x88fc,
- 0x88f4, 0x88e8, 0x88f2, 0x8904, 0x890c, 0x890a, 0x8913, 0x8943,
- 0x891e, 0x8925, 0x892a, 0x892b, 0x8941, 0x8944, 0x893b, 0x8936,
- 0x8938, 0x894c, 0x891d, 0x8960, 0x895e, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8966, 0x8964, 0x896d, 0x896a, 0x896f, 0x8974, 0x8977, 0x897e,
- 0x8983, 0x8988, 0x898a, 0x8993, 0x8998, 0x89a1, 0x89a9, 0x89a6,
- 0x89ac, 0x89af, 0x89b2, 0x89ba, 0x89bd, 0x89bf, 0x89c0, 0x89da,
- 0x89dc, 0x89dd, 0x89e7, 0x89f4, 0x89f8, 0x8a03, 0x8a16, 0x8a10,
- 0x8a0c, 0x8a1b, 0x8a1d, 0x8a25, 0x8a36, 0x8a41, 0x8a5b, 0x8a52,
- 0x8a46, 0x8a48, 0x8a7c, 0x8a6d, 0x8a6c, 0x8a62, 0x8a85, 0x8a82,
- 0x8a84, 0x8aa8, 0x8aa1, 0x8a91, 0x8aa5, 0x8aa6, 0x8a9a, 0x8aa3,
- 0x8ac4, 0x8acd, 0x8ac2, 0x8ada, 0x8aeb, 0x8af3, 0x8ae7, 0xfffd,
- 0x8ae4, 0x8af1, 0x8b14, 0x8ae0, 0x8ae2, 0x8af7, 0x8ade, 0x8adb,
- 0x8b0c, 0x8b07, 0x8b1a, 0x8ae1, 0x8b16, 0x8b10, 0x8b17, 0x8b20,
- 0x8b33, 0x97ab, 0x8b26, 0x8b2b, 0x8b3e, 0x8b28, 0x8b41, 0x8b4c,
- 0x8b4f, 0x8b4e, 0x8b49, 0x8b56, 0x8b5b, 0x8b5a, 0x8b6b, 0x8b5f,
- 0x8b6c, 0x8b6f, 0x8b74, 0x8b7d, 0x8b80, 0x8b8c, 0x8b8e, 0x8b92,
- 0x8b93, 0x8b96, 0x8b99, 0x8b9a, 0x8c3a, 0x8c41, 0x8c3f, 0x8c48,
- 0x8c4c, 0x8c4e, 0x8c50, 0x8c55, 0x8c62, 0x8c6c, 0x8c78, 0x8c7a,
- 0x8c82, 0x8c89, 0x8c85, 0x8c8a, 0x8c8d, 0x8c8e, 0x8c94, 0x8c7c,
- 0x8c98, 0x621d, 0x8cad, 0x8caa, 0x8cbd, 0x8cb2, 0x8cb3, 0x8cae,
- 0x8cb6, 0x8cc8, 0x8cc1, 0x8ce4, 0x8ce3, 0x8cda, 0x8cfd, 0x8cfa,
- 0x8cfb, 0x8d04, 0x8d05, 0x8d0a, 0x8d07, 0x8d0f, 0x8d0d, 0x8d10,
- 0x9f4e, 0x8d13, 0x8ccd, 0x8d14, 0x8d16, 0x8d67, 0x8d6d, 0x8d71,
- 0x8d73, 0x8d81, 0x8d99, 0x8dc2, 0x8dbe, 0x8dba, 0x8dcf, 0x8dda,
- 0x8dd6, 0x8dcc, 0x8ddb, 0x8dcb, 0x8dea, 0x8deb, 0x8ddf, 0x8de3,
- 0x8dfc, 0x8e08, 0x8e09, 0x8dff, 0x8e1d, 0x8e1e, 0x8e10, 0x8e1f,
- 0x8e42, 0x8e35, 0x8e30, 0x8e34, 0x8e4a, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8e47, 0x8e49, 0x8e4c, 0x8e50, 0x8e48, 0x8e59, 0x8e64, 0x8e60,
- 0x8e2a, 0x8e63, 0x8e55, 0x8e76, 0x8e72, 0x8e7c, 0x8e81, 0x8e87,
- 0x8e85, 0x8e84, 0x8e8b, 0x8e8a, 0x8e93, 0x8e91, 0x8e94, 0x8e99,
- 0x8eaa, 0x8ea1, 0x8eac, 0x8eb0, 0x8ec6, 0x8eb1, 0x8ebe, 0x8ec5,
- 0x8ec8, 0x8ecb, 0x8edb, 0x8ee3, 0x8efc, 0x8efb, 0x8eeb, 0x8efe,
- 0x8f0a, 0x8f05, 0x8f15, 0x8f12, 0x8f19, 0x8f13, 0x8f1c, 0x8f1f,
- 0x8f1b, 0x8f0c, 0x8f26, 0x8f33, 0x8f3b, 0x8f39, 0x8f45, 0x8f42,
- 0x8f3e, 0x8f4c, 0x8f49, 0x8f46, 0x8f4e, 0x8f57, 0x8f5c, 0xfffd,
- 0x8f62, 0x8f63, 0x8f64, 0x8f9c, 0x8f9f, 0x8fa3, 0x8fad, 0x8faf,
- 0x8fb7, 0x8fda, 0x8fe5, 0x8fe2, 0x8fea, 0x8fef, 0x9087, 0x8ff4,
- 0x9005, 0x8ff9, 0x8ffa, 0x9011, 0x9015, 0x9021, 0x900d, 0x901e,
- 0x9016, 0x900b, 0x9027, 0x9036, 0x9035, 0x9039, 0x8ff8, 0x904f,
- 0x9050, 0x9051, 0x9052, 0x900e, 0x9049, 0x903e, 0x9056, 0x9058,
- 0x905e, 0x9068, 0x906f, 0x9076, 0x96a8, 0x9072, 0x9082, 0x907d,
- 0x9081, 0x9080, 0x908a, 0x9089, 0x908f, 0x90a8, 0x90af, 0x90b1,
- 0x90b5, 0x90e2, 0x90e4, 0x6248, 0x90db, 0x9102, 0x9112, 0x9119,
- 0x9132, 0x9130, 0x914a, 0x9156, 0x9158, 0x9163, 0x9165, 0x9169,
- 0x9173, 0x9172, 0x918b, 0x9189, 0x9182, 0x91a2, 0x91ab, 0x91af,
- 0x91aa, 0x91b5, 0x91b4, 0x91ba, 0x91c0, 0x91c1, 0x91c9, 0x91cb,
- 0x91d0, 0x91d6, 0x91df, 0x91e1, 0x91db, 0x91fc, 0x91f5, 0x91f6,
- 0x921e, 0x91ff, 0x9214, 0x922c, 0x9215, 0x9211, 0x925e, 0x9257,
- 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923f, 0x924b, 0x9250,
- 0x929c, 0x9296, 0x9293, 0x929b, 0x925a, 0x92cf, 0x92b9, 0x92b7,
- 0x92e9, 0x930f, 0x92fa, 0x9344, 0x932e, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9319, 0x9322, 0x931a, 0x9323, 0x933a, 0x9335, 0x933b, 0x935c,
- 0x9360, 0x937c, 0x936e, 0x9356, 0x93b0, 0x93ac, 0x93ad, 0x9394,
- 0x93b9, 0x93d6, 0x93d7, 0x93e8, 0x93e5, 0x93d8, 0x93c3, 0x93dd,
- 0x93d0, 0x93c8, 0x93e4, 0x941a, 0x9414, 0x9413, 0x9403, 0x9407,
- 0x9410, 0x9436, 0x942b, 0x9435, 0x9421, 0x943a, 0x9441, 0x9452,
- 0x9444, 0x945b, 0x9460, 0x9462, 0x945e, 0x946a, 0x9229, 0x9470,
- 0x9475, 0x9477, 0x947d, 0x945a, 0x947c, 0x947e, 0x9481, 0x947f,
- 0x9582, 0x9587, 0x958a, 0x9594, 0x9596, 0x9598, 0x9599, 0xfffd,
- 0x95a0, 0x95a8, 0x95a7, 0x95ad, 0x95bc, 0x95bb, 0x95b9, 0x95be,
- 0x95ca, 0x6ff6, 0x95c3, 0x95cd, 0x95cc, 0x95d5, 0x95d4, 0x95d6,
- 0x95dc, 0x95e1, 0x95e5, 0x95e2, 0x9621, 0x9628, 0x962e, 0x962f,
- 0x9642, 0x964c, 0x964f, 0x964b, 0x9677, 0x965c, 0x965e, 0x965d,
- 0x965f, 0x9666, 0x9672, 0x966c, 0x968d, 0x9698, 0x9695, 0x9697,
- 0x96aa, 0x96a7, 0x96b1, 0x96b2, 0x96b0, 0x96b4, 0x96b6, 0x96b8,
- 0x96b9, 0x96ce, 0x96cb, 0x96c9, 0x96cd, 0x894d, 0x96dc, 0x970d,
- 0x96d5, 0x96f9, 0x9704, 0x9706, 0x9708, 0x9713, 0x970e, 0x9711,
- 0x970f, 0x9716, 0x9719, 0x9724, 0x972a, 0x9730, 0x9739, 0x973d,
- 0x973e, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749, 0x975c, 0x9760,
- 0x9764, 0x9766, 0x9768, 0x52d2, 0x976b, 0x9771, 0x9779, 0x9785,
- 0x977c, 0x9781, 0x977a, 0x9786, 0x978b, 0x978f, 0x9790, 0x979c,
- 0x97a8, 0x97a6, 0x97a3, 0x97b3, 0x97b4, 0x97c3, 0x97c6, 0x97c8,
- 0x97cb, 0x97dc, 0x97ed, 0x9f4f, 0x97f2, 0x7adf, 0x97f6, 0x97f5,
- 0x980f, 0x980c, 0x9838, 0x9824, 0x9821, 0x9837, 0x983d, 0x9846,
- 0x984f, 0x984b, 0x986b, 0x986f, 0x9870, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9871, 0x9874, 0x9873, 0x98aa, 0x98af, 0x98b1, 0x98b6, 0x98c4,
- 0x98c3, 0x98c6, 0x98e9, 0x98eb, 0x9903, 0x9909, 0x9912, 0x9914,
- 0x9918, 0x9921, 0x991d, 0x991e, 0x9924, 0x9920, 0x992c, 0x992e,
- 0x993d, 0x993e, 0x9942, 0x9949, 0x9945, 0x9950, 0x994b, 0x9951,
- 0x9952, 0x994c, 0x9955, 0x9997, 0x9998, 0x99a5, 0x99ad, 0x99ae,
- 0x99bc, 0x99df, 0x99db, 0x99dd, 0x99d8, 0x99d1, 0x99ed, 0x99ee,
- 0x99f1, 0x99f2, 0x99fb, 0x99f8, 0x9a01, 0x9a0f, 0x9a05, 0x99e2,
- 0x9a19, 0x9a2b, 0x9a37, 0x9a45, 0x9a42, 0x9a40, 0x9a43, 0xfffd,
- 0x9a3e, 0x9a55, 0x9a4d, 0x9a5b, 0x9a57, 0x9a5f, 0x9a62, 0x9a65,
- 0x9a64, 0x9a69, 0x9a6b, 0x9a6a, 0x9aad, 0x9ab0, 0x9abc, 0x9ac0,
- 0x9acf, 0x9ad1, 0x9ad3, 0x9ad4, 0x9ade, 0x9adf, 0x9ae2, 0x9ae3,
- 0x9ae6, 0x9aef, 0x9aeb, 0x9aee, 0x9af4, 0x9af1, 0x9af7, 0x9afb,
- 0x9b06, 0x9b18, 0x9b1a, 0x9b1f, 0x9b22, 0x9b23, 0x9b25, 0x9b27,
- 0x9b28, 0x9b29, 0x9b2a, 0x9b2e, 0x9b2f, 0x9b32, 0x9b44, 0x9b43,
- 0x9b4f, 0x9b4d, 0x9b4e, 0x9b51, 0x9b58, 0x9b74, 0x9b93, 0x9b83,
- 0x9b91, 0x9b96, 0x9b97, 0x9b9f, 0x9ba0, 0x9ba8, 0x9bb4, 0x9bc0,
- 0x9bca, 0x9bb9, 0x9bc6, 0x9bcf, 0x9bd1, 0x9bd2, 0x9be3, 0x9be2,
- 0x9be4, 0x9bd4, 0x9be1, 0x9c3a, 0x9bf2, 0x9bf1, 0x9bf0, 0x9c15,
- 0x9c14, 0x9c09, 0x9c13, 0x9c0c, 0x9c06, 0x9c08, 0x9c12, 0x9c0a,
- 0x9c04, 0x9c2e, 0x9c1b, 0x9c25, 0x9c24, 0x9c21, 0x9c30, 0x9c47,
- 0x9c32, 0x9c46, 0x9c3e, 0x9c5a, 0x9c60, 0x9c67, 0x9c76, 0x9c78,
- 0x9ce7, 0x9cec, 0x9cf0, 0x9d09, 0x9d08, 0x9ceb, 0x9d03, 0x9d06,
- 0x9d2a, 0x9d26, 0x9daf, 0x9d23, 0x9d1f, 0x9d44, 0x9d15, 0x9d12,
- 0x9d41, 0x9d3f, 0x9d3e, 0x9d46, 0x9d48, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9d5d, 0x9d5e, 0x9d64, 0x9d51, 0x9d50, 0x9d59, 0x9d72, 0x9d89,
- 0x9d87, 0x9dab, 0x9d6f, 0x9d7a, 0x9d9a, 0x9da4, 0x9da9, 0x9db2,
- 0x9dc4, 0x9dc1, 0x9dbb, 0x9db8, 0x9dba, 0x9dc6, 0x9dcf, 0x9dc2,
- 0x9dd9, 0x9dd3, 0x9df8, 0x9de6, 0x9ded, 0x9def, 0x9dfd, 0x9e1a,
- 0x9e1b, 0x9e1e, 0x9e75, 0x9e79, 0x9e7d, 0x9e81, 0x9e88, 0x9e8b,
- 0x9e8c, 0x9e92, 0x9e95, 0x9e91, 0x9e9d, 0x9ea5, 0x9ea9, 0x9eb8,
- 0x9eaa, 0x9ead, 0x9761, 0x9ecc, 0x9ece, 0x9ecf, 0x9ed0, 0x9ed4,
- 0x9edc, 0x9ede, 0x9edd, 0x9ee0, 0x9ee5, 0x9ee8, 0x9eef, 0xfffd,
- 0x9ef4, 0x9ef6, 0x9ef7, 0x9ef9, 0x9efb, 0x9efc, 0x9efd, 0x9f07,
- 0x9f08, 0x76b7, 0x9f15, 0x9f21, 0x9f2c, 0x9f3e, 0x9f4a, 0x9f52,
- 0x9f54, 0x9f63, 0x9f5f, 0x9f60, 0x9f61, 0x9f66, 0x9f67, 0x9f6c,
- 0x9f6a, 0x9f77, 0x9f72, 0x9f76, 0x9f95, 0x9f9c, 0x9fa0, 0x582f,
- 0x69c7, 0x9059, 0x7464, 0x51dc, 0x7199
-};
-
-/* Unicode-to-Kanji tables... */
-
-static USHORT /* Unicode to Shift-JIS */
-usj_0391[] = { /* 0x0391 thru 0x039c */
- 0x839f, 0x83a0, 0x83a1, 0x83a2, 0x83a3, 0x83a4, 0x83a5, 0x83a6,
- 0x83a7, 0x83a8, 0x83a9, 0x83aa, 0x83ab, 0x83ac, 0x83ad, 0x83ae,
- 0x83af, 0xfffd, 0x83b0, 0x83b1, 0x83b2, 0x83b3, 0x83b4, 0x83b5,
- 0x83b6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x83bf, 0x83c0, 0x83c1, 0x83c2, 0x83c3, 0x83c4, 0x83c5, 0x83c6,
- 0x83c7, 0x83c8, 0x83c9, 0x83ca, 0x83cb, 0x83cc, 0x83cd, 0x83ce,
- 0x83cf, 0xfffd, 0x83d0, 0x83d1, 0x83d2, 0x83d3, 0x83d4, 0x83d5, 0x83d6
-};
-
-static USHORT /* Unicode to Shift-JIS */
-usj_0401[] = { /* 0x0401 thru 0x0451 */
- 0x8446, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8440,
- 0x8441, 0x8442, 0x8443, 0x8444, 0x8445, 0x8447, 0x8448, 0x8449,
- 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, 0x8450, 0x8451,
- 0x8452, 0x8453, 0x8454, 0x8455, 0x8456, 0x8457, 0x8458, 0x8459,
- 0x845a, 0x845b, 0x845c, 0x845d, 0x845e, 0x845f, 0x8460, 0x8470,
- 0x8471, 0x8472, 0x8473, 0x8474, 0x8475, 0x8477, 0x8478, 0x8479,
- 0x847a, 0x847b, 0x847c, 0x847d, 0x847e, 0x8480, 0x8481, 0x8482,
- 0x8483, 0x8484, 0x8485, 0x8486, 0x8487, 0x8488, 0x8489, 0x848a,
- 0x848b, 0x848c, 0x848d, 0x848e, 0x848f, 0x8490, 0x8491, 0xfffd, 0x8476
-};
-
-static USHORT /* Unicode to Shift-JIS */
-usj_3000[] = { /* 0x3000 thru 0x30ff */
- 0x8140, 0x8141, 0x8142, 0x8156, 0xfffd, 0x8158, 0x8159, 0x815a,
- 0x8171, 0x8172, 0x8173, 0x8174, 0x8175, 0x8176, 0x8177, 0x8178,
- 0x8179, 0x817a, 0x81a7, 0x81ac, 0x816b, 0x816c, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8160, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x829f, 0x82a0, 0x82a1, 0x82a2, 0x82a3, 0x82a4, 0x82a5,
- 0x82a6, 0x82a7, 0x82a8, 0x82a9, 0x82aa, 0x82ab, 0x82ac, 0x82ad,
- 0x82ae, 0x82af, 0x82b0, 0x82b1, 0x82b2, 0x82b3, 0x82b4, 0x82b5,
- 0x82b6, 0x82b7, 0x82b8, 0x82b9, 0x82ba, 0x82bb, 0x82bc, 0x82bd,
- 0x82be, 0x82bf, 0x82c0, 0x82c1, 0x82c2, 0x82c3, 0x82c4, 0x82c5,
- 0x82c6, 0x82c7, 0x82c8, 0x82c9, 0x82ca, 0x82cb, 0x82cc, 0x82cd,
- 0x82ce, 0x82cf, 0x82d0, 0x82d1, 0x82d2, 0x82d3, 0x82d4, 0x82d5,
- 0x82d6, 0x82d7, 0x82d8, 0x82d9, 0x82da, 0x82db, 0x82dc, 0x82dd,
- 0x82de, 0x82df, 0x82e0, 0x82e1, 0x82e2, 0x82e3, 0x82e4, 0x82e5,
- 0x82e6, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82eb, 0x82ec, 0x82ed,
- 0x82ee, 0x82ef, 0x82f0, 0x82f1, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x814a, 0x814b, 0x8154, 0x8155, 0xfffd,
- 0xfffd, 0x8340, 0x8341, 0x8342, 0x8343, 0x8344, 0x8345, 0x8346,
- 0x8347, 0x8348, 0x8349, 0x834a, 0x834b, 0x834c, 0x834d, 0x834e,
- 0x834f, 0x8350, 0x8351, 0x8352, 0x8353, 0x8354, 0x8355, 0x8356,
- 0x8357, 0x8358, 0x8359, 0x835a, 0x835b, 0x835c, 0x835d, 0x835e,
- 0x835f, 0x8360, 0x8361, 0x8362, 0x8363, 0x8364, 0x8365, 0x8366,
- 0x8367, 0x8368, 0x8369, 0x836a, 0x836b, 0x836c, 0x836d, 0x836e,
- 0x836f, 0x8370, 0x8371, 0x8372, 0x8373, 0x8374, 0x8375, 0x8376,
- 0x8377, 0x8378, 0x8379, 0x837a, 0x837b, 0x837c, 0x837d, 0x837e,
- 0x8380, 0x8381, 0x8382, 0x8383, 0x8384, 0x8385, 0x8386, 0x8387,
- 0x8388, 0x8389, 0x838a, 0x838b, 0x838c, 0x838d, 0x838e, 0x838f,
- 0x8390, 0x8391, 0x8392, 0x8393, 0x8394, 0x8395, 0x8396, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8145, 0x815b, 0x8152, 0x8153, 0xfffd
-};
-
-static USHORT /* Unicode to Shift-JIS */
-usj_ff00[] = { /* 0xff00 thru 0x0ff9f */
- 0xfffd, 0x8149, 0xfffd, 0x8194, 0x8190, 0x8193, 0x8195, 0xfffd,
- 0x8169, 0x816a, 0x8196, 0x817b, 0x8143, 0xfffd, 0x8144, 0x815e,
- 0x824f, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256,
- 0x8257, 0x8258, 0x8146, 0x8147, 0x8183, 0x8181, 0x8184, 0x8148,
- 0x8197, 0x8260, 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266,
- 0x8267, 0x8268, 0x8269, 0x826a, 0x826b, 0x826c, 0x826d, 0x826e,
- 0x826f, 0x8270, 0x8271, 0x8272, 0x8273, 0x8274, 0x8275, 0x8276,
- 0x8277, 0x8278, 0x8279, 0x816d, 0xfffd, 0x816e, 0x814f, 0x8151,
- 0x814d, 0x8281, 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287,
- 0x8288, 0x8289, 0x828a, 0x828b, 0x828c, 0x828d, 0x828e, 0x828f,
- 0x8290, 0x8291, 0x8292, 0x8293, 0x8294, 0x8295, 0x8296, 0x8297,
- 0x8298, 0x8299, 0x829a, 0x816f, 0x8162, 0x8170, 0xfffd, 0xfffd,
- 0xfffd, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
- 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
- 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
- 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
- 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df
-};
-
-/* Now one humongous table for Kanji */
-
-static USHORT /* Unicode to Shift-JIS */
-usj_4e00[] = { /* 0x4e00 thru 0x9fa0 */
- 0x88ea, 0x929a, 0xfffd, 0x8eb5, 0xfffd, 0xfffd, 0xfffd, 0x969c,
- 0x8fe4, 0x8e4f, 0x8fe3, 0x89ba, 0xfffd, 0x9573, 0x975e, 0xfffd,
- 0x98a0, 0x894e, 0xfffd, 0xfffd, 0x8a8e, 0x98a1, 0x90a2, 0x99c0,
- 0x8b75, 0x95b8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8fe5, 0xfffd,
- 0xfffd, 0x97bc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95c0, 0xfffd,
- 0xfffd, 0xfffd, 0x98a2, 0xfffd, 0xfffd, 0x9286, 0xfffd, 0xfffd,
- 0xfffd, 0x98a3, 0x8bf8, 0xfffd, 0xfffd, 0xfffd, 0x98a4, 0xfffd,
- 0x8adb, 0x924f, 0xfffd, 0x8ee5, 0x98a5, 0xfffd, 0xfffd, 0x98a6,
- 0xfffd, 0xfffd, 0x98a7, 0x9454, 0xfffd, 0x8b76, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9456, 0xfffd, 0x93e1, 0x8cc1, 0x9652,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe568, 0x98a8, 0x8fe6,
- 0x98a9, 0x89b3, 0xfffd, 0xfffd, 0xfffd, 0x8be3, 0x8cee, 0x96e7,
- 0xfffd, 0xfffd, 0x9ba4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9790, 0xfffd, 0x93fb, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8aa3, 0xfffd,
- 0x8b54, 0xfffd, 0x98aa, 0xfffd, 0xfffd, 0x98ab, 0x97b9, 0xfffd,
- 0x975c, 0x9188, 0x98ad, 0x8e96, 0x93f1, 0xfffd, 0x98b0, 0xfffd,
- 0xfffd, 0x895d, 0x8cdd, 0xfffd, 0x8cdc, 0x88e4, 0xfffd, 0xfffd,
- 0x986a, 0x9869, 0xfffd, 0x8db1, 0x889f, 0xfffd, 0x98b1, 0x98b2,
- 0x98b3, 0x9653, 0x98b4, 0xfffd, 0x8cf0, 0x88e5, 0x9692, 0xfffd,
- 0x8b9c, 0xfffd, 0xfffd, 0x8b9d, 0x8b9e, 0x92e0, 0x97ba, 0xfffd,
- 0x98b5, 0xfffd, 0xfffd, 0x98b6, 0xfffd, 0xfffd, 0x98b7, 0xfffd,
- 0xfffd, 0xfffd, 0x906c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8f59, 0x906d, 0x98bc, 0xfffd, 0x98ba, 0xfffd, 0x98bb, 0x8b77,
- 0xfffd, 0xfffd, 0x8da1, 0x89ee, 0xfffd, 0x98b9, 0x98b8, 0x95a7,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8e65, 0x8e64, 0x91bc, 0x98bd,
- 0x9574, 0x90e5, 0xfffd, 0xfffd, 0xfffd, 0x8157, 0x98be, 0x98c0,
- 0xfffd, 0xfffd, 0xfffd, 0x91e3, 0x97df, 0x88c8, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x98bf, 0x89bc, 0xfffd,
- 0x8bc2, 0xfffd, 0x9287, 0xfffd, 0xfffd, 0xfffd, 0x8c8f, 0x98c1,
- 0xfffd, 0xfffd, 0xfffd, 0x9443, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8ae9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x98c2, 0x88c9, 0xfffd, 0xfffd, 0x8cde, 0x8aea, 0x959a,
- 0x94b0, 0x8b78, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x89ef, 0xfffd, 0x98e5, 0x9360, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x948c,
- 0x98c4, 0xfffd, 0xfffd, 0xfffd, 0x94ba, 0xfffd, 0x97e0, 0xfffd,
- 0x904c, 0xfffd, 0x8e66, 0xfffd, 0x8e97, 0x89be, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x92cf, 0xfffd, 0xfffd, 0x9241, 0x98c8,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x88ca, 0x92e1, 0x8f5a,
- 0x8db2, 0x9743, 0xfffd, 0x91cc, 0xfffd, 0x89bd, 0xfffd, 0x98c7,
- 0xfffd, 0x975d, 0x98c3, 0x98c5, 0x8dec, 0x98c6, 0x9b43, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x98ce, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x98d1,
- 0x98cf, 0xfffd, 0xfffd, 0x89c0, 0xfffd, 0x95b9, 0x98c9, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x98cd, 0x8cf1, 0xfffd, 0xfffd, 0x8e67,
- 0xfffd, 0xfffd, 0xfffd, 0x8aa4, 0xfffd, 0xfffd, 0x98d2, 0xfffd,
- 0x98ca, 0xfffd, 0xfffd, 0x97e1, 0xfffd, 0x8e98, 0xfffd, 0x98cb,
- 0xfffd, 0x98d0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x98d3, 0xfffd,
- 0x98cc, 0xfffd, 0xfffd, 0x8b9f, 0xfffd, 0x88cb, 0xfffd, 0xfffd,
- 0x8ba0, 0x89bf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9b44, 0xfffd, 0x9699, 0x958e, 0x8cf2,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x904e, 0x97b5, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95d6,
- 0xfffd, 0xfffd, 0x8c57, 0x91a3, 0x89e2, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8f72, 0xfffd, 0xfffd, 0xfffd, 0x98d7, 0xfffd,
- 0x98dc, 0x98da, 0xfffd, 0xfffd, 0x98d5, 0xfffd, 0xfffd, 0x91ad,
- 0x98d8, 0xfffd, 0x98db, 0x98d9, 0xfffd, 0x95db, 0xfffd, 0x98d6,
- 0xfffd, 0x904d, 0xfffd, 0x9693, 0x98dd, 0x98de, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f43, 0x98eb,
- 0xfffd, 0xfffd, 0xfffd, 0x946f, 0xfffd, 0x9555, 0x98e6, 0xfffd,
- 0x95ee, 0xfffd, 0x89b4, 0xfffd, 0xfffd, 0xfffd, 0x98ea, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x98e4, 0x98ed, 0xfffd,
- 0xfffd, 0x9171, 0xfffd, 0x8cc2, 0xfffd, 0x947b, 0xfffd, 0xe0c5,
- 0xfffd, 0x98ec, 0x937c, 0xfffd, 0x98e1, 0xfffd, 0x8cf4, 0xfffd,
- 0xfffd, 0x8cf3, 0x98df, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ed8,
- 0xfffd, 0x98e7, 0xfffd, 0x95ed, 0x926c, 0x98e3, 0x8c91, 0xfffd,
- 0x98e0, 0x98e8, 0x98e2, 0x97cf, 0x98e9, 0x9860, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8be4, 0xfffd,
- 0xfffd, 0x8c90, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x98ee, 0xfffd, 0xfffd, 0xfffd, 0x98ef,
- 0x98f3, 0x88cc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95ce,
- 0x98f2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x98f1, 0x98f5, 0xfffd,
- 0xfffd, 0xfffd, 0x98f4, 0xfffd, 0x92e2, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c92, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x98f6, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8ec3, 0xfffd, 0x91a4, 0x92e3, 0x8bf4, 0xfffd,
- 0x98f7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b55, 0xfffd, 0xfffd,
- 0x98f8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x98fa, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9654, 0xfffd, 0xfffd,
- 0xfffd, 0x8c86, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8e50, 0x94f5, 0x98f9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8dc3, 0x9762, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x98fc, 0x9942, 0x98fb, 0x8dc2, 0xfffd, 0x8f9d,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c58, 0xfffd,
- 0xfffd, 0xfffd, 0x9943, 0xfffd, 0xfffd, 0x8bcd, 0xfffd, 0xfffd,
- 0xfffd, 0x9940, 0x9941, 0xfffd, 0xfffd, 0x93ad, 0xfffd, 0x919c,
- 0xfffd, 0x8ba1, 0xfffd, 0xfffd, 0xfffd, 0x966c, 0x9944, 0xfffd,
- 0xfffd, 0xfffd, 0x97bb, 0xfffd, 0xfffd, 0xfffd, 0x9945, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9948, 0xfffd, 0x9946, 0xfffd, 0x916d,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9947, 0x9949, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x994b, 0xfffd, 0xfffd,
- 0xfffd, 0x994a, 0xfffd, 0x95c6, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8b56, 0x994d, 0x994e, 0xfffd, 0x89ad, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x994c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8ef2, 0xfffd, 0x9951, 0x9950, 0x994f, 0xfffd,
- 0x98d4, 0xfffd, 0x9952, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f9e,
- 0xfffd, 0x9953, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9744, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x96d7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9955,
- 0xfffd, 0xfffd, 0x9954, 0x9957, 0x9956, 0xfffd, 0xfffd, 0x9958,
- 0x9959, 0x88f2, 0xfffd, 0x8cb3, 0x8c5a, 0x8f5b, 0x929b, 0x8ba2,
- 0x90e6, 0x8cf5, 0xfffd, 0x8d8e, 0x995b, 0x96c6, 0x9365, 0xfffd,
- 0x8e99, 0xfffd, 0x995a, 0xfffd, 0x995c, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x937d, 0xfffd, 0x8a95, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x995d, 0xfffd, 0xfffd, 0x93fc, 0xfffd, 0xfffd,
- 0x9153, 0x995f, 0x9960, 0x94aa, 0x8cf6, 0x985a, 0x9961, 0xfffd,
- 0xfffd, 0x8ba4, 0xfffd, 0xfffd, 0xfffd, 0x95ba, 0x91b4, 0x8bef,
- 0x9354, 0xfffd, 0xfffd, 0xfffd, 0x8c93, 0xfffd, 0xfffd, 0xfffd,
- 0x9962, 0xfffd, 0x9963, 0xfffd, 0xfffd, 0x93e0, 0x897e, 0xfffd,
- 0xfffd, 0x9966, 0x8dfb, 0xfffd, 0x9965, 0x8dc4, 0xfffd, 0x9967,
- 0xe3ec, 0x9968, 0x9660, 0x9969, 0xfffd, 0x996a, 0x996b, 0x8fe7,
- 0xfffd, 0x8eca, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8aa5, 0xfffd, 0x996e, 0xfffd, 0x996c, 0x96bb, 0x996d, 0xfffd,
- 0x9579, 0x996f, 0x9970, 0x9971, 0x937e, 0xfffd, 0xfffd, 0xfffd,
- 0x9975, 0x9973, 0x9974, 0x9972, 0x8de1, 0x9976, 0x96e8, 0x97e2,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9977, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x90a6, 0x9978, 0x8f79, 0xfffd,
- 0xfffd, 0x9979, 0xfffd, 0x929c, 0x97bd, 0x9380, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99c3, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x997a, 0xeaa3, 0x8bc3, 0xfffd, 0xfffd,
- 0x997b, 0x967d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f88, 0x91fa,
- 0xfffd, 0x997d, 0x93e2, 0xfffd, 0xfffd, 0x997e, 0xfffd, 0xfffd,
- 0x9980, 0x8a4d, 0xfffd, 0xfffd, 0xfffd, 0x9981, 0x8ba5, 0xfffd,
- 0x93ca, 0x899a, 0x8f6f, 0xfffd, 0xfffd, 0x949f, 0x9982, 0xfffd,
- 0x9381, 0xfffd, 0xfffd, 0x906e, 0x9983, 0xfffd, 0x95aa, 0x90d8,
- 0x8aa0, 0xfffd, 0x8aa7, 0x9984, 0xfffd, 0xfffd, 0x9986, 0xfffd,
- 0xfffd, 0x8c59, 0xfffd, 0xfffd, 0x9985, 0xfffd, 0xfffd, 0x97f1,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f89, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x94bb, 0x95ca, 0xfffd, 0x9987,
- 0xfffd, 0x9798, 0x9988, 0xfffd, 0xfffd, 0xfffd, 0x9989, 0xfffd,
- 0x939e, 0xfffd, 0xfffd, 0x998a, 0xfffd, 0xfffd, 0x90a7, 0x8dfc,
- 0x8c94, 0x998b, 0x8e68, 0x8d8f, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x92e4, 0x998d, 0xfffd, 0xfffd, 0x91a5,
- 0xfffd, 0xfffd, 0x8ded, 0x998e, 0x998f, 0x914f, 0xfffd, 0x998c,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9991, 0xfffd, 0x9655, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8d84, 0xfffd, 0xfffd, 0x9990, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8c95, 0x8ddc, 0x948d, 0xfffd, 0xfffd,
- 0xfffd, 0x9994, 0x9992, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x959b,
- 0x8fe8, 0x999b, 0x8a84, 0x9995, 0x9993, 0x916e, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9997, 0xfffd, 0x9996,
- 0xfffd, 0xfffd, 0xfffd, 0x8a63, 0xfffd, 0xfffd, 0xfffd, 0x8c80,
- 0x999c, 0x97ab, 0xfffd, 0xfffd, 0xfffd, 0x9998, 0xfffd, 0xfffd,
- 0xfffd, 0x999d, 0x999a, 0xfffd, 0x9999, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x97cd, 0xfffd, 0xfffd, 0xfffd, 0x8cf7,
- 0x89c1, 0xfffd, 0xfffd, 0x97f2, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8f95, 0x9377, 0x8d85, 0x99a0, 0x99a1, 0xfffd, 0xfffd,
- 0xfffd, 0x97e3, 0xfffd, 0xfffd, 0x984a, 0x99a3, 0xfffd, 0xfffd,
- 0xfffd, 0x8cf8, 0xfffd, 0xfffd, 0x99a2, 0xfffd, 0x8a4e, 0xfffd,
- 0xfffd, 0x99a4, 0xfffd, 0x9675, 0xfffd, 0x92ba, 0xfffd, 0x9745,
- 0xfffd, 0x95d7, 0xfffd, 0xfffd, 0xfffd, 0x99a5, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe8d3, 0xfffd, 0xfffd, 0x93ae, 0xfffd, 0x99a6,
- 0x8aa8, 0x96b1, 0xfffd, 0xfffd, 0xfffd, 0x8f9f, 0x99a7, 0x95e5,
- 0x99ab, 0xfffd, 0x90a8, 0x99a8, 0x8bce, 0xfffd, 0x99a9, 0x8aa9,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8c4d, 0x99ac, 0xfffd, 0x99ad, 0xfffd, 0xfffd,
- 0x99ae, 0x99af, 0x8ed9, 0xfffd, 0xfffd, 0xfffd, 0x8cf9, 0x96dc,
- 0xfffd, 0x96e6, 0x93f5, 0xfffd, 0xfffd, 0x95ef, 0x99b0, 0xfffd,
- 0x99b1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99b3, 0xfffd, 0x99b5,
- 0x99b4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99b6, 0x89bb, 0x966b,
- 0xfffd, 0x8dfa, 0x99b7, 0xfffd, 0xfffd, 0x9178, 0xfffd, 0xfffd,
- 0x8fa0, 0x8ba7, 0xfffd, 0x99b8, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x94d9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99b9,
- 0xfffd, 0x99ba, 0xfffd, 0x99bb, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x99bc, 0x9543, 0x8be6, 0x88e3, 0xfffd, 0xfffd, 0xfffd, 0x93bd,
- 0x99bd, 0x8f5c, 0xfffd, 0x90e7, 0xfffd, 0x99bf, 0x99be, 0x8fa1,
- 0x8cdf, 0x99c1, 0x94bc, 0xfffd, 0xfffd, 0x99c2, 0xfffd, 0xfffd,
- 0xfffd, 0x94da, 0x91b2, 0x91ec, 0x8ba6, 0xfffd, 0xfffd, 0x93ec,
- 0x9250, 0xfffd, 0x948e, 0xfffd, 0x966d, 0xfffd, 0x99c4, 0xfffd,
- 0x90e8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c54, 0xfffd,
- 0xfffd, 0x99c5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99c6, 0x894b,
- 0x88f3, 0x8aeb, 0xfffd, 0x91a6, 0x8b70, 0x9791, 0xfffd, 0x99c9,
- 0x89b5, 0xfffd, 0xfffd, 0x99c8, 0xfffd, 0xfffd, 0xfffd, 0x8ba8,
- 0xfffd, 0xfffd, 0x99ca, 0xfffd, 0x96ef, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99cb, 0xfffd,
- 0x97d0, 0xfffd, 0x8cfa, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8cb4,
- 0x99cc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99ce, 0x99cd, 0xfffd,
- 0x907e, 0x8958, 0xfffd, 0xfffd, 0xfffd, 0x897d, 0x99cf, 0xfffd,
- 0x99d0, 0xfffd, 0xfffd, 0x8cb5, 0xfffd, 0xfffd, 0x99d1, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8b8e, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8e51, 0x99d2, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9694, 0x8db3, 0x8b79, 0x9746, 0x916f, 0x94bd, 0x8efb, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f66, 0xfffd, 0x8ee6, 0x8ef3,
- 0xfffd, 0x8f96, 0xfffd, 0x94be, 0xfffd, 0xfffd, 0xfffd, 0x99d5,
- 0xfffd, 0x8962, 0x9170, 0x8cfb, 0x8cc3, 0x8be5, 0xfffd, 0xfffd,
- 0x99d9, 0x9240, 0x91fc, 0x8ba9, 0x8fa2, 0x99da, 0x99d8, 0x89c2,
- 0x91e4, 0x8eb6, 0x8e6a, 0x8945, 0xfffd, 0xfffd, 0x8a90, 0x8d86,
- 0x8e69, 0xfffd, 0x99db, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x99dc, 0xfffd, 0x8b68, 0x8a65, 0xfffd, 0xfffd, 0xfffd,
- 0x8d87, 0x8b67, 0x92dd, 0x8944, 0x93af, 0x96bc, 0x8d40, 0x9799,
- 0x9366, 0x8cfc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8c4e, 0xfffd, 0x99e5, 0xfffd, 0x8be1,
- 0x9669, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x94db, 0xfffd,
- 0xfffd, 0x99e4, 0xfffd, 0x8adc, 0x99df, 0x99e0, 0x99e2, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99e3, 0xfffd,
- 0x8b7a, 0x9081, 0xfffd, 0x95ab, 0x99e1, 0x99dd, 0x8ce1, 0xfffd,
- 0x99de, 0xfffd, 0x9843, 0xfffd, 0xfffd, 0xfffd, 0x95f0, 0xfffd,
- 0x92e6, 0x8ce0, 0x8d90, 0xfffd, 0xfffd, 0xfffd, 0x99e6, 0xfffd,
- 0xfffd, 0x93db, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99ea,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8efc, 0xfffd, 0x8ef4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x99ed, 0x99eb, 0xfffd, 0x96a1, 0xfffd, 0x99e8, 0x99f1, 0x99ec,
- 0xfffd, 0xfffd, 0xfffd, 0x99ef, 0x8cc4, 0x96bd, 0xfffd, 0xfffd,
- 0x99f0, 0xfffd, 0xfffd, 0xfffd, 0x99f2, 0xfffd, 0x99f4, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8dee, 0x9861, 0xfffd, 0x99e9, 0x99e7,
- 0x99f3, 0xfffd, 0x99ee, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x99f6, 0xfffd, 0x9a42, 0x99f8, 0xfffd, 0xfffd,
- 0x99fc, 0xfffd, 0xfffd, 0x9a40, 0x99f9, 0xfffd, 0xfffd, 0x9a5d,
- 0xfffd, 0xfffd, 0x8de7, 0x8a50, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x99f7, 0xfffd, 0xfffd, 0xfffd, 0x9a44, 0x88f4, 0x9a43, 0xfffd,
- 0x88a3, 0x9569, 0x9a41, 0xfffd, 0x99fa, 0xfffd, 0xfffd, 0x99f5,
- 0x99fb, 0x8dc6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9a45, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x88f5, 0x9a4e, 0xfffd, 0xfffd, 0x9a46, 0x9a47, 0xfffd,
- 0x8fa3, 0x9689, 0xfffd, 0xfffd, 0xfffd, 0x9a4c, 0x9a4b, 0xfffd,
- 0xfffd, 0xfffd, 0x934e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9a4d, 0xfffd, 0xfffd, 0x9a4a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8953, 0xfffd, 0x8db4, 0x904f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a48,
- 0x9382, 0xfffd, 0xfffd, 0xfffd, 0x9a49, 0xfffd, 0x88a0, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a53, 0x9742,
- 0xfffd, 0x8fa5, 0xfffd, 0x9a59, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9a58, 0x9a4f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91c1, 0xfffd,
- 0x9a50, 0xfffd, 0xfffd, 0xfffd, 0x91ed, 0x9a55, 0x8fa4, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a52, 0xfffd, 0xfffd, 0x96e2,
- 0xfffd, 0xfffd, 0xfffd, 0x8c5b, 0xfffd, 0xfffd, 0x9a56, 0x9a57,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a54, 0x9a5a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9a51, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9a60, 0x9a65, 0xfffd, 0x9a61, 0xfffd,
- 0x9a5c, 0xfffd, 0xfffd, 0x9a66, 0x9150, 0xfffd, 0xfffd, 0x9a68,
- 0xfffd, 0x8d41, 0x9a5e, 0x929d, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9a62, 0x9a5b, 0x8aab, 0xfffd, 0x8aec, 0x8a85, 0x9a63, 0x9a5f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c96,
- 0x9a69, 0x9a67, 0x9172, 0x8b69, 0x8baa, 0xfffd, 0x9a64, 0xfffd,
- 0x8bf2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8963, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a6d, 0x9a6b, 0xfffd, 0x9aa5,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a70, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9a6a, 0xfffd, 0x9a6e, 0xfffd, 0xfffd, 0x9a6c,
- 0xfffd, 0xfffd, 0xfffd, 0x8e6b, 0x9a6f, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a72,
- 0xfffd, 0x9a77, 0xfffd, 0xfffd, 0xfffd, 0x9a75, 0x9a74, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9251, 0xfffd,
- 0xfffd, 0x89c3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a71, 0xfffd, 0x9a73, 0x8fa6,
- 0x8952, 0xfffd, 0xfffd, 0x9a76, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x89dc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a82,
- 0xfffd, 0x8ffa, 0x9a7d, 0xfffd, 0x9a7b, 0xfffd, 0x9a7c, 0xfffd,
- 0x9a7e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x895c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9158, 0xfffd, 0x9a78, 0xfffd,
- 0x9a79, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8a9a, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a81, 0xfffd, 0xfffd, 0xfffd,
- 0x8aed, 0xfffd, 0x9a84, 0x9a80, 0x9a83, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95ac, 0xfffd, 0xfffd, 0xfffd,
- 0x93d3, 0xfffd, 0x94b6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9a86, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a85, 0x8a64,
- 0xfffd, 0xfffd, 0x9a87, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a8a,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a89, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9a88, 0xfffd, 0x9458, 0xfffd, 0xfffd, 0x9a8b, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a8c, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a8e, 0xfffd, 0x9a8d, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a90, 0xfffd, 0xfffd, 0xfffd,
- 0x9a93, 0x9a91, 0x9a8f, 0x9a92, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9a94, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a95, 0xfffd,
- 0xfffd, 0x9a96, 0xfffd, 0x9a97, 0xfffd, 0xfffd, 0xfffd, 0x9a98,
- 0x9964, 0xfffd, 0x8efa, 0x8e6c, 0xfffd, 0xfffd, 0x89f1, 0xfffd,
- 0x88f6, 0xfffd, 0xfffd, 0x9263, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a99, 0xfffd,
- 0x8da2, 0xfffd, 0x88cd, 0x907d, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9a9a, 0x8cc5, 0xfffd, 0xfffd, 0x8d91, 0xfffd, 0x9a9c,
- 0x9a9b, 0xfffd, 0xfffd, 0x95de, 0x9a9d, 0xfffd, 0xfffd, 0xfffd,
- 0x9a9f, 0x9a9e, 0xfffd, 0x9aa0, 0xfffd, 0x9aa1, 0xfffd, 0x8c97,
- 0xfffd, 0xfffd, 0x8980, 0x9aa2, 0xfffd, 0xfffd, 0x9aa4, 0xfffd,
- 0x9aa3, 0xfffd, 0xfffd, 0xfffd, 0x9aa6, 0xfffd, 0xfffd, 0x9379,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9aa7, 0x88b3,
- 0x8ddd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c5c, 0xfffd, 0xfffd,
- 0x926e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9aa8,
- 0x9aa9, 0xfffd, 0xfffd, 0x9aab, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9aac, 0xfffd, 0x8de2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8bcf,
- 0xfffd, 0xfffd, 0x9656, 0xfffd, 0xfffd, 0xfffd, 0x9aaa, 0x9aad,
- 0x8dbf, 0x8d42, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9ab1, 0xfffd, 0xfffd, 0x8da3, 0xfffd, 0x9252, 0xfffd,
- 0xfffd, 0x9aae, 0x92d8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ab2,
- 0xfffd, 0xfffd, 0x9082, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9ab0, 0x9ab3, 0xfffd, 0x8c5e, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9ab4, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9ab5, 0xfffd, 0x8d43, 0x8a5f, 0x9ab7, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9ab8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9ab9, 0xfffd, 0xfffd, 0x9ab6, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9aaf, 0xfffd, 0xfffd, 0x9aba, 0xfffd, 0xfffd, 0x9abb, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9684, 0xfffd, 0xfffd, 0x8fe9, 0xfffd,
- 0xfffd, 0xfffd, 0x9abd, 0x9abe, 0x9abc, 0xfffd, 0x9ac0, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9457, 0xfffd, 0xfffd, 0x88e6,
- 0x9575, 0xfffd, 0xfffd, 0x9ac1, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ffb, 0xfffd, 0xfffd, 0x8eb7,
- 0xfffd, 0x947c, 0x8aee, 0xfffd, 0x8de9, 0xfffd, 0xfffd, 0xfffd,
- 0x9678, 0xfffd, 0x93b0, 0xfffd, 0xfffd, 0x8c98, 0x91cd, 0xfffd,
- 0xfffd, 0xfffd, 0x9abf, 0x9ac2, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91c2, 0xfffd, 0xfffd,
- 0xfffd, 0x9ac3, 0xfffd, 0xfffd, 0xfffd, 0x9ac4, 0xfffd, 0xfffd,
- 0xfffd, 0x9ac6, 0xfffd, 0xfffd, 0x92e7, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8aac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea9f,
- 0x8981, 0x95f1, 0xfffd, 0xfffd, 0x8fea, 0x9367, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8de4, 0xfffd, 0xfffd, 0x9acc, 0xfffd, 0xfffd,
- 0x95bb, 0x97db, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x89f2, 0x9ac8, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9159, 0x9acb, 0xfffd, 0x9383, 0xfffd, 0xfffd, 0x9368,
- 0x9384, 0x94b7, 0x92cb, 0xfffd, 0xfffd, 0xfffd, 0x8dc7, 0xfffd,
- 0xfffd, 0xfffd, 0x9ac7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8996, 0xfffd, 0x9355, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9ac9, 0xfffd, 0x9ac5, 0xfffd, 0xfffd, 0x906f, 0xfffd, 0xfffd,
- 0xfffd, 0x9acd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f6d, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8bab, 0xfffd, 0x9ace, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x95e6, 0xfffd, 0xfffd, 0xfffd, 0x919d,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x92c4, 0xfffd, 0xfffd, 0x9ad0,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x966e, 0xfffd, 0xfffd, 0x9ad1, 0xfffd, 0xfffd, 0x9ad6, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x95ad, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9ad5, 0x9acf, 0x9ad2, 0x9ad4, 0xfffd, 0xfffd, 0x8da4, 0xfffd,
- 0xfffd, 0x95c7, 0xfffd, 0xfffd, 0xfffd, 0x9ad7, 0xfffd, 0x9264,
- 0xfffd, 0xfffd, 0x89f3, 0xfffd, 0x8feb, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9ad9, 0xfffd, 0x9ad8, 0xfffd, 0x8d88, 0xfffd, 0x9ada,
- 0x9adc, 0x9adb, 0xfffd, 0xfffd, 0x9ade, 0xfffd, 0x9ad3, 0x9ae0,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9adf, 0x9add, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8e6d, 0x9070, 0xfffd, 0x9173, 0x9ae1,
- 0x90ba, 0x88eb, 0x9484, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x92d9,
- 0xfffd, 0x9ae3, 0x9ae2, 0x9ae4, 0x9ae5, 0x9ae6, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9ae7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x95cf, 0x9ae8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x89c4,
- 0x9ae9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x975b, 0x8a4f, 0xfffd,
- 0x99c7, 0x8f67, 0x91bd, 0x9aea, 0x96e9, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x96b2, 0xfffd, 0xfffd, 0x9aec, 0xfffd, 0x91e5,
- 0xfffd, 0x9356, 0x91be, 0x9576, 0x9aed, 0x9aee, 0x899b, 0xfffd,
- 0xfffd, 0x8eb8, 0x9aef, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x88ce,
- 0x9af0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9af1, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8982, 0xfffd, 0xfffd, 0x8aef,
- 0x93de, 0x95f2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9af5, 0x9174,
- 0x9af4, 0x8c5f, 0xfffd, 0xfffd, 0x967a, 0x9af3, 0xfffd, 0x9385,
- 0x9af7, 0xfffd, 0x9af6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9af9, 0xfffd, 0x9af8, 0xfffd, 0xfffd, 0x899c, 0xfffd, 0x9afa,
- 0x8fa7, 0x9afc, 0x9244, 0xfffd, 0x9afb, 0xfffd, 0x95b1, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8f97, 0x937a, 0xfffd, 0xfffd, 0xfffd,
- 0x9b40, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8d44, 0xfffd, 0xfffd,
- 0xfffd, 0x9b41, 0x9440, 0x94dc, 0x96cf, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9444, 0xfffd, 0xfffd, 0x9b4a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8b57, 0xfffd, 0xfffd, 0x9764, 0xfffd,
- 0xfffd, 0x96ad, 0xfffd, 0x9baa, 0xfffd, 0x9b42, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9b45, 0xfffd, 0x91c3, 0xfffd, 0xfffd,
- 0x9657, 0xfffd, 0xfffd, 0xfffd, 0x9369, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9b46, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9685, 0xfffd, 0x8dc8, 0xfffd, 0xfffd, 0x8fa8, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9b47, 0xfffd,
- 0xfffd, 0x8e6f, 0xfffd, 0x8e6e, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x88b7, 0x8cc6, 0xfffd, 0x90a9, 0x88cf, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9b4b, 0x9b4c, 0xfffd, 0x9b49, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8957, 0x8aad, 0xfffd,
- 0x9b48, 0xfffd, 0x96c3, 0x9550, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x88a6, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x88f7, 0xfffd, 0xfffd, 0xfffd, 0x8e70,
- 0xfffd, 0x88d0, 0xfffd, 0x88a1, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9b51, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9b4f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x96ba, 0xfffd, 0x9b52, 0xfffd, 0x9b50, 0xfffd, 0xfffd, 0x9b4e,
- 0x9050, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9b4d, 0xfffd, 0xfffd,
- 0xfffd, 0x95d8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ce2,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9b56, 0x9b57, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8fa9, 0xfffd, 0xfffd, 0xfffd,
- 0x9b53, 0x984b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x946b, 0xfffd,
- 0xfffd, 0x9b55, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8da5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9b58, 0xfffd, 0xfffd, 0xfffd, 0x9577, 0xfffd,
- 0xfffd, 0xfffd, 0x9b59, 0xfffd, 0x9b54, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x96b9,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x947d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9b5a, 0x9551, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9b5b, 0x9b5f, 0x9b5c, 0xfffd,
- 0xfffd, 0x89c5, 0x9b5e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8eb9, 0xfffd, 0x9b5d, 0x8c99, 0xfffd, 0xfffd, 0xfffd,
- 0x9b6b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9b64, 0x9b61,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9284, 0xfffd, 0x9b60, 0xfffd, 0xfffd, 0x9b62, 0xfffd,
- 0xfffd, 0x9b63, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9b65, 0x9b66, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8af0, 0xfffd, 0x9b68, 0x9b67, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9b69, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8fec, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9b6c, 0xfffd, 0x92da, 0xfffd, 0xfffd, 0xfffd,
- 0x8964, 0xfffd, 0x9b6a, 0xfffd, 0xfffd, 0xfffd, 0x9b6d, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9b6e, 0xfffd,
- 0x9b71, 0xfffd, 0xfffd, 0x9b6f, 0xfffd, 0x9b70, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8e71, 0x9b72, 0xfffd, 0xfffd, 0x8d45, 0x9b73, 0xfffd, 0x8e9a,
- 0x91b6, 0xfffd, 0x9b74, 0x9b75, 0x8e79, 0x8d46, 0xfffd, 0x96d0,
- 0xfffd, 0xfffd, 0xfffd, 0x8b47, 0x8cc7, 0x9b76, 0x8a77, 0xfffd,
- 0xfffd, 0x9b77, 0xfffd, 0x91b7, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9b78, 0x9ba1, 0xfffd, 0x9b79, 0xfffd, 0x9b7a, 0xfffd, 0xfffd,
- 0x9b7b, 0xfffd, 0x9b7d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9b7e, 0xfffd, 0xfffd, 0x9b80, 0xfffd, 0x91ee, 0xfffd, 0x8946,
- 0x8ee7, 0x88c0, 0xfffd, 0x9176, 0x8aae, 0x8eb3, 0xfffd, 0x8d47,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9386, 0xfffd, 0x8f40,
- 0x8aaf, 0x9288, 0x92e8, 0x88b6, 0x8b58, 0x95f3, 0xfffd, 0x8ec0,
- 0xfffd, 0xfffd, 0x8b71, 0x90e9, 0x8eba, 0x9747, 0x9b81, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b7b, 0xfffd,
- 0x8dc9, 0xfffd, 0xfffd, 0x8a51, 0x8983, 0x8faa, 0x89c6, 0xfffd,
- 0x9b82, 0x9765, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f68,
- 0xfffd, 0xfffd, 0x8ee2, 0x9b83, 0x8af1, 0x93d0, 0x96a7, 0x9b84,
- 0xfffd, 0x9b85, 0xfffd, 0xfffd, 0x9578, 0xfffd, 0xfffd, 0xfffd,
- 0x9b87, 0xfffd, 0x8aa6, 0x8bf5, 0x9b86, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8ab0, 0xfffd, 0x9051, 0x9b8b, 0x8e40,
- 0xfffd, 0x89c7, 0x9b8a, 0xfffd, 0x9b88, 0x9b8c, 0x9b89, 0x944a,
- 0x9ecb, 0x9052, 0xfffd, 0x9b8d, 0xfffd, 0xfffd, 0x97be, 0xfffd,
- 0x9b8e, 0xfffd, 0xfffd, 0x9b90, 0xfffd, 0x929e, 0x9b8f, 0xfffd,
- 0x90a1, 0xfffd, 0x8e9b, 0xfffd, 0xfffd, 0xfffd, 0x91ce, 0x8ef5,
- 0xfffd, 0x9595, 0x90ea, 0xfffd, 0x8ecb, 0x9b91, 0x8fab, 0x9b92,
- 0x9b93, 0x88d1, 0x91b8, 0x9071, 0xfffd, 0x9b94, 0x93b1, 0x8fac,
- 0xfffd, 0x8fad, 0xfffd, 0x9b95, 0xfffd, 0xfffd, 0x90eb, 0xfffd,
- 0xfffd, 0xfffd, 0x8fae, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9b96, 0xfffd, 0x9b97, 0xfffd, 0x96de, 0xfffd, 0xfffd, 0xfffd,
- 0x9b98, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8bc4, 0xfffd, 0xfffd,
- 0xfffd, 0x8f41, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9b99, 0x9b9a, 0x8eda, 0x904b, 0x93f2, 0x9073, 0x94f6, 0x9441,
- 0x8bc7, 0x9b9b, 0xfffd, 0xfffd, 0xfffd, 0x8b8f, 0x9b9c, 0xfffd,
- 0x8bfc, 0xfffd, 0x93cd, 0x89ae, 0xfffd, 0x8e72, 0x9b9d, 0x9ba0,
- 0x9b9f, 0x8bfb, 0xfffd, 0x9b9e, 0xfffd, 0x9357, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91ae, 0xfffd,
- 0x936a, 0x8ec6, 0xfffd, 0xfffd, 0x9177, 0x979a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ba2, 0xfffd, 0x9ba3, 0x93d4,
- 0xfffd, 0x8e52, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ba5, 0xfffd,
- 0xfffd, 0x9ba6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ba7, 0xfffd, 0xfffd, 0xfffd,
- 0x8af2, 0x9ba8, 0xfffd, 0xfffd, 0x9ba9, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x89aa, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x915a, 0x8ae2, 0xfffd, 0x9bab, 0x96a6, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x91d0, 0xfffd, 0x8a78, 0xfffd, 0xfffd, 0x9bad, 0x9baf,
- 0x8add, 0xfffd, 0xfffd, 0x9bac, 0x9bae, 0xfffd, 0x9bb1, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9bb0, 0xfffd, 0x9bb2,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9bb3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x93bb, 0x8bac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x89e3, 0x9bb4, 0x9bb9, 0xfffd, 0xfffd, 0x9bb7, 0xfffd, 0x95f5,
- 0x95f4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9387, 0xfffd,
- 0xfffd, 0xfffd, 0x9bb6, 0x8f73, 0xfffd, 0x9bb5, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9092,
- 0xfffd, 0xfffd, 0xfffd, 0x9bba, 0xfffd, 0xfffd, 0x8de8, 0xfffd,
- 0xfffd, 0x9bc0, 0xfffd, 0xfffd, 0x9bc1, 0x9bbb, 0x8a52, 0x9bbc,
- 0x9bc5, 0x9bc4, 0x9bc3, 0x9bbf, 0xfffd, 0xfffd, 0xfffd, 0x9bbe,
- 0xfffd, 0xfffd, 0x9bc2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x95f6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9bc9, 0x9bc6, 0xfffd, 0x9bc8, 0xfffd,
- 0x9792, 0xfffd, 0x9bc7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9bbd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9093, 0xfffd, 0xfffd, 0x9bca, 0xfffd, 0xfffd, 0x8db5,
- 0xfffd, 0xfffd, 0xfffd, 0x9bcb, 0xfffd, 0xfffd, 0x9bcc, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9bcf, 0xfffd, 0x9bce, 0xfffd, 0xfffd, 0x9bcd,
- 0xfffd, 0xfffd, 0xfffd, 0x9388, 0x9bb8, 0xfffd, 0xfffd, 0xfffd,
- 0x9bd5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9bd1, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9bd0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9bd2, 0xfffd, 0x9bd3, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9bd6,
- 0xfffd, 0xfffd, 0x97e4, 0xfffd, 0x9bd7, 0x9bd4, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9bd8, 0xfffd, 0xfffd, 0x8ade, 0x9bd9, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9bdb, 0x9bda, 0xfffd, 0xfffd, 0x9bdc, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9bdd, 0xfffd, 0x90ec, 0x8f42, 0xfffd,
- 0xfffd, 0x8f84, 0xfffd, 0x9183, 0xfffd, 0x8d48, 0x8db6, 0x8d49,
- 0x8b90, 0xfffd, 0xfffd, 0x9bde, 0xfffd, 0xfffd, 0x8db7, 0xfffd,
- 0xfffd, 0x8cc8, 0x9bdf, 0x96a4, 0x9462, 0x9be0, 0xfffd, 0x8d4a,
- 0xfffd, 0xfffd, 0xfffd, 0x8aaa, 0xfffd, 0x9246, 0x8bd0, 0xfffd,
- 0xfffd, 0xfffd, 0x8e73, 0x957a, 0xfffd, 0xfffd, 0x94bf, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9be1, 0x8af3, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9be4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x929f, 0xfffd,
- 0xfffd, 0x9be3, 0x9be2, 0x9be5, 0xfffd, 0x92e9, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9083, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8e74, 0xfffd, 0x90c8, 0xfffd, 0x91d1,
- 0x8b41, 0xfffd, 0xfffd, 0x92a0, 0xfffd, 0xfffd, 0x9be6, 0x9be7,
- 0x8fed, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9658, 0xfffd, 0xfffd,
- 0x9bea, 0xfffd, 0xfffd, 0x9be9, 0x9be8, 0x959d, 0xfffd, 0x9bf1,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9679, 0xfffd, 0x9beb, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9bed, 0x968b, 0xfffd, 0x9bec,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9bee,
- 0xfffd, 0x94a6, 0x9bef, 0x95bc, 0x9bf0, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8ab1, 0x95bd, 0x944e, 0x9bf2, 0x9bf3, 0xfffd,
- 0x8d4b, 0x8ab2, 0x9bf4, 0x8cb6, 0x9763, 0x9748, 0x8af4, 0x9bf6,
- 0xfffd, 0x92a1, 0xfffd, 0x8d4c, 0x8faf, 0xfffd, 0xfffd, 0x94dd,
- 0xfffd, 0xfffd, 0x8fb0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f98,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x92ea, 0x95f7, 0x9358,
- 0xfffd, 0xfffd, 0x8d4d, 0xfffd, 0x957b, 0xfffd, 0xfffd, 0xfffd,
- 0x9bf7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9378, 0x8dc0,
- 0xfffd, 0xfffd, 0xfffd, 0x8cc9, 0xfffd, 0x92eb, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x88c1, 0x8f8e, 0x8d4e,
- 0x9766, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9bf8, 0x9bf9, 0x9470, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9bfa, 0x97f5, 0x984c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9bfc,
- 0x9bfb, 0xfffd, 0xfffd, 0x8a66, 0xfffd, 0xfffd, 0x9c40, 0xfffd,
- 0xfffd, 0xfffd, 0x9c43, 0x9c44, 0xfffd, 0x9c42, 0xfffd, 0x955f,
- 0x8fb1, 0x9c46, 0x9c45, 0x9c41, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9c47, 0x9c48, 0xfffd, 0xfffd, 0x9c49, 0xfffd, 0xfffd, 0xfffd,
- 0x9c4c, 0x9c4a, 0xfffd, 0x9c4b, 0x9c4d, 0xfffd, 0x8984, 0x92ec,
- 0x9c4e, 0xfffd, 0x8c9a, 0x89f4, 0x9455, 0xfffd, 0x9c4f, 0x93f9,
- 0xfffd, 0x95d9, 0xfffd, 0x9c50, 0x984d, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9c51, 0x95be, 0x9c54, 0x989f, 0x98af, 0xfffd, 0x8eae,
- 0x93f3, 0x9c55, 0xfffd, 0x8b7c, 0x92a2, 0x88f8, 0x9c56, 0x95a4,
- 0x8d4f, 0xfffd, 0xfffd, 0x926f, 0xfffd, 0xfffd, 0xfffd, 0x92ed,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x96ed, 0x8cb7, 0x8cca,
- 0xfffd, 0x9c57, 0xfffd, 0xfffd, 0xfffd, 0x9c58, 0xfffd, 0x9c5e,
- 0xfffd, 0x8ee3, 0xfffd, 0xfffd, 0xfffd, 0x92a3, 0xfffd, 0x8bad,
- 0x9c59, 0xfffd, 0xfffd, 0xfffd, 0x954a, 0xfffd, 0x9265, 0xfffd,
- 0xfffd, 0x9c5a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9c5b, 0xfffd, 0x8bae, 0xfffd, 0x9c5c, 0xfffd, 0x9c5d, 0xfffd,
- 0xfffd, 0x9c5f, 0xfffd, 0x9396, 0xfffd, 0xfffd, 0x9c60, 0x9c61,
- 0xfffd, 0x9c62, 0xfffd, 0xfffd, 0x9c53, 0x9c52, 0xfffd, 0xfffd,
- 0xfffd, 0x9c63, 0x8c60, 0xfffd, 0xfffd, 0xfffd, 0x9546, 0xfffd,
- 0xfffd, 0x8dca, 0x9556, 0x92a4, 0x956a, 0x9c64, 0xfffd, 0xfffd,
- 0x8fb2, 0x8965, 0xfffd, 0x9c65, 0xfffd, 0xfffd, 0xfffd, 0x9c66,
- 0xfffd, 0x96f0, 0xfffd, 0xfffd, 0x94de, 0xfffd, 0xfffd, 0x9c69,
- 0x899d, 0x90aa, 0x9c68, 0x9c67, 0x8c61, 0x91d2, 0xfffd, 0x9c6d,
- 0x9c6b, 0xfffd, 0x9c6a, 0x97a5, 0x8ce3, 0xfffd, 0xfffd, 0xfffd,
- 0x8f99, 0x9c6c, 0x936b, 0x8f5d, 0xfffd, 0xfffd, 0xfffd, 0x93be,
- 0x9c70, 0x9c6f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9c6e, 0xfffd,
- 0x9c71, 0x8ce4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9c72, 0x959c, 0x8f7a, 0xfffd, 0xfffd, 0x9c73, 0x94f7, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x93bf, 0x92a5, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x934f, 0xfffd, 0xfffd, 0x9c74, 0x8b4a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9053, 0xfffd, 0x954b, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8af5, 0x9445, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9c75, 0x8e75,
- 0x9659, 0x965a, 0xfffd, 0xfffd, 0x899e, 0x9c7a, 0xfffd, 0xfffd,
- 0x9289, 0xfffd, 0xfffd, 0xfffd, 0x9c77, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x89f5, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9cab, 0x9c79, 0xfffd, 0xfffd, 0xfffd, 0x944f, 0xfffd, 0xfffd,
- 0x9c78, 0xfffd, 0xfffd, 0x9c76, 0xfffd, 0x8d9a, 0xfffd, 0x9c7c,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9c83, 0x9c89,
- 0x9c81, 0xfffd, 0x937b, 0xfffd, 0xfffd, 0x9c86, 0x957c, 0xfffd,
- 0xfffd, 0x9c80, 0xfffd, 0x9c85, 0x97e5, 0x8e76, 0xfffd, 0xfffd,
- 0x91d3, 0x9c7d, 0xfffd, 0xfffd, 0xfffd, 0x8b7d, 0x9c88, 0x90ab,
- 0x8985, 0x9c82, 0x89f6, 0x9c87, 0xfffd, 0xfffd, 0xfffd, 0x8baf,
- 0xfffd, 0x9c84, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9c8a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9c8c, 0x9c96, 0x9c94, 0xfffd, 0xfffd, 0x9c91, 0xfffd,
- 0xfffd, 0xfffd, 0x9c90, 0x97f6, 0xfffd, 0x9c92, 0xfffd, 0xfffd,
- 0x8bb0, 0xfffd, 0x8d50, 0xfffd, 0xfffd, 0x8f9a, 0xfffd, 0xfffd,
- 0xfffd, 0x9c99, 0x9c8b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9c8f,
- 0x9c7e, 0xfffd, 0x89f8, 0x9c93, 0x9c95, 0x9270, 0xfffd, 0xfffd,
- 0x8da6, 0x89b6, 0x9c8d, 0x9c98, 0x9c97, 0x8bb1, 0xfffd, 0x91a7,
- 0x8a86, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c62, 0xfffd, 0x9c8e,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9c9a, 0xfffd, 0x9c9d, 0x9c9f, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8ebb, 0xfffd, 0x9ca5, 0x92ee, 0x9c9b, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9ca3, 0xfffd, 0x89f7, 0xfffd, 0x9ca1, 0x9ca2,
- 0xfffd, 0xfffd, 0x9c9e, 0x9ca0, 0xfffd, 0xfffd, 0xfffd, 0x8ce5,
- 0x9749, 0xfffd, 0xfffd, 0x8ab3, 0xfffd, 0xfffd, 0x8978, 0x9ca4,
- 0xfffd, 0x9459, 0x88ab, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x94df, 0x9c7b, 0x9caa, 0x9cae, 0x96e3, 0xfffd,
- 0x9ca7, 0xfffd, 0xfffd, 0xfffd, 0x9389, 0x9cac, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8fee, 0x9cad, 0x93d5,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9866, 0xfffd, 0x9ca9, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9caf, 0xfffd, 0x8d9b, 0xfffd, 0x90c9, 0xfffd, 0xfffd, 0x88d2,
- 0x9ca8, 0x9ca6, 0xfffd, 0x9179, 0xfffd, 0xfffd, 0xfffd, 0x9c9c,
- 0x8e53, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x91c4, 0x9cbb, 0xfffd, 0x917a, 0x9cb6, 0xfffd, 0x9cb3, 0x9cb4,
- 0xfffd, 0x8ee4, 0x9cb7, 0x9cba, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9cb5, 0x8f44, 0xfffd, 0x9cb8, 0xfffd, 0xfffd, 0x9cb2, 0xfffd,
- 0x96fa, 0x96f9, 0xfffd, 0xfffd, 0xfffd, 0x9cbc, 0x9cbd, 0x88d3,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9cb1, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8bf0, 0x88a4, 0xfffd, 0xfffd, 0xfffd, 0x8ab4,
- 0xfffd, 0x9cb9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9cc1,
- 0x9cc0, 0xfffd, 0xfffd, 0xfffd, 0x9cc5, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9cc6, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9cc4, 0x9cc7, 0x9cbf, 0x9cc3,
- 0xfffd, 0xfffd, 0x9cc8, 0xfffd, 0x9cc9, 0xfffd, 0xfffd, 0x9cbe,
- 0x8e9c, 0xfffd, 0x9cc2, 0x91d4, 0x8d51, 0x9cb0, 0x9054, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9cd6, 0xfffd, 0x95e7, 0xfffd, 0xfffd,
- 0x9ccc, 0x9ccd, 0x9cce, 0xfffd, 0xfffd, 0x9cd5, 0xfffd, 0x9cd4,
- 0xfffd, 0xfffd, 0x969d, 0x8ab5, 0xfffd, 0x9cd2, 0xfffd, 0x8c64,
- 0x8a53, 0xfffd, 0xfffd, 0x9ccf, 0xfffd, 0xfffd, 0x97b6, 0x9cd1,
- 0x88d4, 0x9cd3, 0xfffd, 0x9cca, 0x9cd0, 0x9cd7, 0x8c63, 0x9ccb,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x977c, 0xfffd,
- 0xfffd, 0xfffd, 0x974a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9cda,
- 0xfffd, 0xfffd, 0x9cde, 0xfffd, 0xfffd, 0xfffd, 0x919e, 0xfffd,
- 0x97f7, 0x9cdf, 0xfffd, 0xfffd, 0x9cdc, 0xfffd, 0x9cd9, 0xfffd,
- 0xfffd, 0x9cd8, 0x9cdd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95ae, 0xfffd, 0xfffd, 0x93b2,
- 0xfffd, 0x8c65, 0xfffd, 0x9ce0, 0x9cdb, 0xfffd, 0x9ce1, 0xfffd,
- 0xfffd, 0xfffd, 0x8c9b, 0xfffd, 0xfffd, 0xfffd, 0x89af, 0xfffd,
- 0xfffd, 0xfffd, 0x9ce9, 0xfffd, 0xfffd, 0xfffd, 0x8ab6, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9ce7, 0xfffd, 0xfffd, 0x9ce8, 0x8da7,
- 0x9ce6, 0x9ce4, 0x9ce3, 0x9cea, 0x9ce2, 0x9cec, 0xfffd, 0xfffd,
- 0x89f9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9cee, 0xfffd, 0xfffd, 0x9ced, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x92a6, 0xfffd, 0x9cf1, 0xfffd, 0x9cef, 0x9ce5,
- 0x8c9c, 0xfffd, 0x9cf0, 0xfffd, 0x9cf4, 0x9cf3, 0x9cf5, 0x9cf2,
- 0x9cf6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9cf7, 0x9cf8, 0x95e8, 0xfffd, 0x9cfa, 0x9cf9, 0x8f5e, 0xfffd,
- 0x90ac, 0x89e4, 0x89fa, 0xfffd, 0x9cfb, 0xfffd, 0x88bd, 0xfffd,
- 0xfffd, 0xfffd, 0x90ca, 0x9cfc, 0xfffd, 0xe6c1, 0x9d40, 0x8c81,
- 0xfffd, 0x9d41, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x90ed, 0xfffd,
- 0xfffd, 0xfffd, 0x9d42, 0xfffd, 0xfffd, 0xfffd, 0x9d43, 0x8b59,
- 0x9d44, 0xfffd, 0x9d45, 0x9d46, 0x91d5, 0xfffd, 0xfffd, 0xfffd,
- 0x8ccb, 0xfffd, 0xfffd, 0x96df, 0xfffd, 0xfffd, 0xfffd, 0x965b,
- 0x8f8a, 0x9d47, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x90ee,
- 0xe7bb, 0x94e0, 0xfffd, 0x8ee8, 0xfffd, 0x8dcb, 0x9d48, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x91c5, 0xfffd, 0x95a5, 0xfffd, 0xfffd,
- 0x91ef, 0xfffd, 0xfffd, 0x9d4b, 0xfffd, 0xfffd, 0x9d49, 0xfffd,
- 0x9d4c, 0xfffd, 0xfffd, 0x9d4a, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9d4d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95af, 0xfffd,
- 0xfffd, 0x88b5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x957d, 0xfffd,
- 0xfffd, 0x94e1, 0xfffd, 0xfffd, 0x9d4e, 0xfffd, 0x9d51, 0x8fb3,
- 0x8b5a, 0xfffd, 0x9d4f, 0x9d56, 0x8fb4, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9d50, 0x9463, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x977d, 0x9d52, 0x9d53, 0x9d57, 0x938a, 0x9d54, 0x8d52,
- 0x90dc, 0xfffd, 0xfffd, 0x9d65, 0x94b2, 0xfffd, 0x91f0, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x94e2, 0x9dab, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x95f8, 0xfffd, 0xfffd, 0xfffd, 0x92ef, 0xfffd, 0xfffd,
- 0xfffd, 0x9695, 0xfffd, 0x9d5a, 0x899f, 0x928a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9d63, 0xfffd, 0xfffd, 0x9253, 0x9d5d, 0x9d64,
- 0x9d5f, 0x9d66, 0x9d62, 0xfffd, 0x9d61, 0x948f, 0xfffd, 0x9d5b,
- 0x89fb, 0x9d59, 0x8b91, 0x91f1, 0x9d55, 0xfffd, 0xfffd, 0x9d58,
- 0x8d53, 0x90d9, 0xfffd, 0x8fb5, 0x9d60, 0x9471, 0xfffd, 0xfffd,
- 0x8b92, 0x8a67, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a87, 0x9040, 0x9d68, 0x9d6d,
- 0xfffd, 0x9d69, 0xfffd, 0x8c9d, 0xfffd, 0x9d6e, 0x8e41, 0x8d89,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f45, 0x9d5c,
- 0xfffd, 0x8e9d, 0x9d6b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8e77,
- 0x9d6c, 0x88c2, 0xfffd, 0xfffd, 0x9d67, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x92a7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8b93, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8bb2,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9d6a,
- 0x88a5, 0xfffd, 0xfffd, 0x8dc1, 0xfffd, 0xfffd, 0xfffd, 0x9055,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x92f0, 0xfffd, 0xfffd, 0x94d2, 0x9d70, 0x917d,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x91a8, 0xfffd, 0xfffd, 0x8e4a, 0x9d71, 0xfffd, 0x9d73,
- 0x9d6f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95df, 0xfffd, 0x92bb,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x917b, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95f9,
- 0x8ecc, 0x9d80, 0xfffd, 0x9d7e, 0xfffd, 0xfffd, 0x9098, 0xfffd,
- 0xfffd, 0xfffd, 0x8c9e, 0xfffd, 0xfffd, 0xfffd, 0x9d78, 0x8fb7,
- 0xfffd, 0xfffd, 0x93e6, 0x9450, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9d76, 0xfffd, 0xfffd, 0x917c, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8ef6, 0x9d7b, 0xfffd, 0xfffd, 0x8fb6, 0xfffd, 0x9d75, 0x9d7a,
- 0xfffd, 0xfffd, 0x9472, 0xfffd, 0xfffd, 0xfffd, 0x9d74, 0xfffd,
- 0x8c40, 0xfffd, 0xfffd, 0x8a7c, 0xfffd, 0xfffd, 0xfffd, 0x9d7c,
- 0x97a9, 0x8dcc, 0x9254, 0x9d79, 0xfffd, 0x90da, 0xfffd, 0x8d54,
- 0x9084, 0x8986, 0x915b, 0x9d77, 0x8b64, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8c66, 0xfffd, 0x92cd, 0x9d7d, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x917e, 0xfffd, 0xfffd, 0x9d81, 0xfffd,
- 0x9d83, 0xfffd, 0xfffd, 0x91b5, 0x9d89, 0xfffd, 0x9d84, 0xfffd,
- 0xfffd, 0x9d86, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9560,
- 0x92f1, 0xfffd, 0x9d87, 0xfffd, 0xfffd, 0xfffd, 0x974b, 0xfffd,
- 0xfffd, 0xfffd, 0x9767, 0x8ab7, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x88ac, 0xfffd, 0x9d85, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9d82, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8af6, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8987, 0xfffd, 0x9d88, 0xfffd,
- 0xfffd, 0xfffd, 0x9768, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9d8c, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91b9, 0xfffd, 0x9d93,
- 0xfffd, 0xfffd, 0xfffd, 0x9d8d, 0xfffd, 0xfffd, 0x9d8a, 0x9d91,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9d72, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9d8e, 0xfffd,
- 0x9d92, 0xfffd, 0xfffd, 0xfffd, 0x94c0, 0x938b, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9d8b, 0xfffd, 0x9d8f, 0xfffd,
- 0xfffd, 0xfffd, 0x8c67, 0xfffd, 0xfffd, 0xfffd, 0x8def, 0xfffd,
- 0xfffd, 0xfffd, 0x90db, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9d97, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9345, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9d94,
- 0xfffd, 0x9680, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9d95,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9d96, 0xfffd,
- 0x96cc, 0xfffd, 0x90a0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8c82, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9d9d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8e54, 0x9d9a, 0xfffd, 0x9d99, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9451, 0xfffd, 0xfffd, 0xfffd, 0x93b3, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9350, 0x9d9b, 0xfffd, 0xfffd,
- 0xfffd, 0x9d9c, 0xfffd, 0x958f, 0xfffd, 0x9464, 0x8e42, 0xfffd,
- 0x90ef, 0xfffd, 0x966f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8a68, 0xfffd, 0x9da3, 0x9d9e, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9769, 0x9da5, 0xfffd, 0xfffd, 0x9da1, 0xfffd, 0x9da2,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9180, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9da0, 0xfffd, 0x9d5e, 0xfffd, 0xfffd, 0xfffd,
- 0x9da4, 0xfffd, 0x9d9f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9da9, 0x9daa, 0x9346, 0x9dac, 0xfffd, 0xfffd, 0x8e43, 0x9da7,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b5b, 0xfffd, 0xfffd, 0x9dad,
- 0xfffd, 0x9da6, 0x9db1, 0xfffd, 0x9db0, 0xfffd, 0x9daf, 0xfffd,
- 0xfffd, 0xfffd, 0x9db2, 0xfffd, 0xfffd, 0x9db4, 0x8fef, 0xfffd,
- 0x9db3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9db7, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9db5, 0xfffd, 0xfffd, 0xfffd, 0x9db6, 0x9d90, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9db9, 0x9db8, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9d98, 0x9dba, 0x9dae, 0xfffd, 0xfffd, 0x8e78,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9dbb, 0x9dbc, 0x9dbe, 0x9dbd,
- 0x9dbf, 0x89fc, 0xfffd, 0x8d55, 0xfffd, 0xfffd, 0x95fa, 0x90ad,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ccc, 0xfffd, 0xfffd,
- 0x9dc1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9dc4, 0xfffd, 0x9571,
- 0xfffd, 0x8b7e, 0xfffd, 0xfffd, 0xfffd, 0x9dc3, 0x9dc2, 0x9473,
- 0x9dc5, 0x8bb3, 0xfffd, 0xfffd, 0xfffd, 0x9dc7, 0x9dc6, 0xfffd,
- 0xfffd, 0xfffd, 0x8ab8, 0x8e55, 0xfffd, 0xfffd, 0x93d6, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c68, 0xfffd, 0xfffd, 0xfffd,
- 0x9094, 0xfffd, 0x9dc8, 0xfffd, 0x90ae, 0x9347, 0xfffd, 0x957e,
- 0x9dc9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9dca, 0x9dcb, 0xfffd, 0xfffd, 0xfffd, 0x95b6,
- 0x9b7c, 0x90c4, 0xfffd, 0xfffd, 0x956b, 0xfffd, 0x8dd6, 0xfffd,
- 0x94e3, 0x94c1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x936c,
- 0xfffd, 0x97bf, 0xfffd, 0x9dcd, 0x8ece, 0xfffd, 0xfffd, 0x9dce,
- 0xfffd, 0x88b4, 0xfffd, 0xfffd, 0x8bd2, 0x90cb, 0xfffd, 0x9580,
- 0xfffd, 0xfffd, 0xfffd, 0x9dcf, 0x8e61, 0x9266, 0xfffd, 0x8e7a,
- 0x9056, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9dd0,
- 0xfffd, 0x95fb, 0xfffd, 0xfffd, 0x8997, 0x8e7b, 0xfffd, 0xfffd,
- 0xfffd, 0x9dd3, 0xfffd, 0x9dd1, 0x9dd4, 0x97b7, 0x9dd2, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x90f9, 0x9dd5, 0xfffd, 0xfffd, 0x91b0,
- 0xfffd, 0xfffd, 0x9dd6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8af8,
- 0xfffd, 0x9dd8, 0xfffd, 0x9dd7, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9dd9, 0x9dda, 0x8af9, 0xfffd, 0xfffd, 0x93fa, 0x9255, 0x8b8c,
- 0x8e7c, 0x9181, 0xfffd, 0xfffd, 0x8f7b, 0x88ae, 0xfffd, 0xfffd,
- 0xfffd, 0x9ddb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x89a0, 0x9ddf, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8d56, 0x9dde, 0xfffd, 0xfffd, 0x8da9, 0x8fb8,
- 0xfffd, 0xfffd, 0x9ddd, 0xfffd, 0x8fb9, 0xfffd, 0x96be, 0x8da8,
- 0xfffd, 0xfffd, 0xfffd, 0x88d5, 0x90cc, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9de4, 0xfffd, 0xfffd, 0x90af,
- 0x8966, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f74, 0xfffd, 0x9686,
- 0x8df0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8fba, 0xfffd, 0x90a5,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9de3, 0x9de1, 0x9de2, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x928b, 0xfffd, 0xfffd, 0x9e45,
- 0xfffd, 0x9de8, 0x8e9e, 0x8d57, 0x9de6, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9de7, 0xfffd, 0x9057, 0xfffd, 0xfffd, 0xfffd, 0x9de5,
- 0xfffd, 0xfffd, 0x8e4e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9dea, 0x9de9, 0x9dee,
- 0xfffd, 0xfffd, 0x9def, 0xfffd, 0x9deb, 0xfffd, 0x8a41, 0x9dec,
- 0x9ded, 0x94d3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9581, 0x8c69,
- 0x9df0, 0xfffd, 0xfffd, 0xfffd, 0x90b0, 0xfffd, 0x8fbb, 0xfffd,
- 0xfffd, 0xfffd, 0x9271, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8bc5, 0xfffd, 0x9df1, 0x9df5, 0xfffd, 0xfffd, 0x89c9,
- 0x9df2, 0x9df4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9df3, 0xfffd,
- 0xfffd, 0x8f8b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9267, 0x88c3,
- 0x9df6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9df7, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x92a8, 0xfffd, 0xfffd, 0xfffd, 0x97ef, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8e62, 0xfffd, 0xfffd, 0x95e9, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x965c, 0xfffd, 0xfffd, 0xfffd,
- 0x9e41, 0x9df9, 0xfffd, 0xfffd, 0x9dfc, 0xfffd, 0x9dfb, 0xfffd,
- 0xfffd, 0x9df8, 0xfffd, 0xfffd, 0x9e40, 0xfffd, 0xfffd, 0x93dc,
- 0xfffd, 0x9dfa, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e42, 0xfffd,
- 0xfffd, 0x8f8c, 0x9e43, 0xfffd, 0x976a, 0x9498, 0xfffd, 0xfffd,
- 0x9e44, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e46, 0xfffd,
- 0xfffd, 0x9e47, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9e48, 0xfffd, 0x8bc8, 0x8967, 0x8d58, 0x9e49, 0xfffd, 0x9e4a,
- 0x8f91, 0x9182, 0xfffd, 0xfffd, 0x99d6, 0x915d, 0x915c, 0x91d6,
- 0x8dc5, 0xfffd, 0xfffd, 0x98f0, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8c8e, 0x974c, 0xfffd, 0x95fc, 0xfffd, 0x959e, 0xfffd, 0x9e4b,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8df1, 0x92bd, 0x9e4c, 0x984e,
- 0xfffd, 0xfffd, 0xfffd, 0x965d, 0xfffd, 0x92a9, 0x9e4d, 0x8afa,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e4e, 0x9e4f,
- 0x96d8, 0xfffd, 0x96a2, 0x9696, 0x967b, 0x8e44, 0x9e51, 0xfffd,
- 0xfffd, 0x8ee9, 0xfffd, 0xfffd, 0x9670, 0xfffd, 0x9e53, 0x9e56,
- 0x9e55, 0xfffd, 0x8af7, 0xfffd, 0xfffd, 0x8b80, 0xfffd, 0x9e52,
- 0xfffd, 0x9e54, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e57, 0xfffd,
- 0xfffd, 0x9099, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x979b, 0x88c7,
- 0x8dde, 0x91ba, 0xfffd, 0x8edb, 0xfffd, 0xfffd, 0x8ff1, 0xfffd,
- 0xfffd, 0x9e5a, 0xfffd, 0xfffd, 0x936d, 0xfffd, 0x9e58, 0x91a9,
- 0x9e59, 0x8ff0, 0x96db, 0x9e5b, 0x9e5c, 0x9788, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9e61, 0xfffd, 0xfffd, 0x8d59, 0xfffd, 0x9474,
- 0x9e5e, 0x938c, 0x9ddc, 0x9de0, 0xfffd, 0x8b6e, 0xfffd, 0x9466,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e60, 0xfffd, 0x8fbc, 0x94c2,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e66, 0xfffd, 0x94f8,
- 0xfffd, 0x9e5d, 0xfffd, 0x9e63, 0x9e62, 0xfffd, 0xfffd, 0xfffd,
- 0x90cd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x968d, 0xfffd, 0x97d1,
- 0xfffd, 0xfffd, 0x9687, 0xfffd, 0x89ca, 0x8e7d, 0xfffd, 0xfffd,
- 0x9867, 0x9e65, 0x9095, 0xfffd, 0xfffd, 0xfffd, 0x9e64, 0xfffd,
- 0xfffd, 0x9e5f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ccd,
- 0xfffd, 0xfffd, 0xfffd, 0x9e6b, 0x9e69, 0xfffd, 0x89cb, 0x9e67,
- 0x9e6d, 0x9e73, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x91c6, 0xfffd, 0xfffd, 0x95bf, 0xfffd, 0x9e75, 0xfffd,
- 0xfffd, 0xfffd, 0x9541, 0xfffd, 0xfffd, 0xfffd, 0x9e74, 0x9490,
- 0x965e, 0x8ab9, 0xfffd, 0x90f5, 0x8f5f, 0xfffd, 0xfffd, 0xfffd,
- 0x92d1, 0xfffd, 0x974d, 0xfffd, 0xfffd, 0x9e70, 0x9e6f, 0xfffd,
- 0xfffd, 0xfffd, 0x9e71, 0xfffd, 0x9e6e, 0xfffd, 0xfffd, 0x9e76,
- 0xfffd, 0x9e6c, 0xfffd, 0xfffd, 0x9e6a, 0xfffd, 0x9e72, 0x9e68,
- 0xfffd, 0x928c, 0xfffd, 0x96f6, 0x8ec4, 0x8df2, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8db8, 0xfffd, 0xfffd, 0x968f, 0x8a60,
- 0xfffd, 0xfffd, 0x92cc, 0x93c8, 0x8968, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x90f0, 0xfffd, 0xfffd, 0x90b2, 0x8c49,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e78, 0xfffd,
- 0xfffd, 0x8d5a, 0x8a9c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9e7a, 0x8a94, 0x9e81, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9e7d, 0xfffd, 0x90f1, 0xfffd, 0xfffd, 0xfffd,
- 0x8a6a, 0x8daa, 0xfffd, 0xfffd, 0x8a69, 0x8dcd, 0xfffd, 0xfffd,
- 0x9e7b, 0x8c85, 0x8c6a, 0x938d, 0xfffd, 0xfffd, 0x9e79, 0xfffd,
- 0x88c4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e7c, 0x9e7e, 0xfffd,
- 0x8bcb, 0x8c4b, 0xfffd, 0x8aba, 0x8b6a, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9e82, 0xfffd, 0xfffd, 0x8df7, 0x9691, 0xfffd, 0x8e56,
- 0xfffd, 0xfffd, 0xfffd, 0x9e83, 0xfffd, 0xfffd, 0xfffd, 0x954f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e8f, 0xfffd, 0x89b1, 0x9e84,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e95, 0x9e85,
- 0xfffd, 0x97c0, 0xfffd, 0x9e8c, 0xfffd, 0x947e, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e94, 0xfffd, 0x9e87,
- 0xfffd, 0xfffd, 0xfffd, 0x88b2, 0x9e89, 0xfffd, 0xfffd, 0x8d5b,
- 0xfffd, 0xfffd, 0xfffd, 0x9e8b, 0xfffd, 0x9e8a, 0xfffd, 0x9e86,
- 0x9e91, 0xfffd, 0x8fbd, 0xfffd, 0xfffd, 0xfffd, 0x9aeb, 0x8ce6,
- 0x979c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e88, 0xfffd, 0x92f2,
- 0x8a42, 0x8dab, 0xfffd, 0x9e80, 0xfffd, 0x9e90, 0x8a81, 0xfffd,
- 0xfffd, 0x9e8e, 0x9e92, 0xfffd, 0x938e, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8afc, 0xfffd, 0x9eb0, 0xfffd,
- 0xfffd, 0x96c7, 0x9e97, 0x8afb, 0xfffd, 0x9e9e, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x965f, 0xfffd, 0x9e9f, 0x9ea1, 0xfffd, 0x9ea5,
- 0x9e99, 0xfffd, 0x9249, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x938f,
- 0x9ea9, 0x9e9c, 0xfffd, 0x9ea6, 0xfffd, 0xfffd, 0xfffd, 0x9ea0,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9058, 0x9eaa,
- 0xfffd, 0xfffd, 0x90b1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9ea8, 0x8abb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x986f, 0x9e96, 0xfffd, 0xfffd, 0x9ea4, 0x88d6, 0xfffd, 0xfffd,
- 0x9e98, 0xfffd, 0xfffd, 0x96b8, 0x9e9d, 0x9041, 0x92c5, 0x9e93,
- 0xfffd, 0xfffd, 0x9ea3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x909a, 0x9ead, 0x8a91, 0x8c9f, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9eaf, 0x9e9a, 0x9eae, 0xfffd, 0x9ea7, 0x9e9b, 0xfffd,
- 0x9eab, 0xfffd, 0x9eac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9ebd, 0xfffd, 0xfffd, 0xfffd, 0x93cc, 0xfffd, 0x9ea2, 0xfffd,
- 0xfffd, 0x9eb9, 0xfffd, 0xfffd, 0xfffd, 0x9ebb, 0xfffd, 0x92d6,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x976b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9596, 0x9eb6, 0x91c8, 0xfffd, 0xfffd,
- 0xfffd, 0x9ebc, 0x915e, 0xfffd, 0x9eb3, 0x9ec0, 0x9ebf, 0xfffd,
- 0x93ed, 0x9ebe, 0x93e8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9ec2, 0x9eb5, 0xfffd, 0x8bc6, 0x9eb8, 0x8f7c,
- 0xfffd, 0xfffd, 0xfffd, 0x9480, 0x9eba, 0x8bc9, 0xfffd, 0x9eb2,
- 0x9eb4, 0x9eb1, 0xfffd, 0xfffd, 0x984f, 0x8a79, 0x9eb7, 0xfffd,
- 0xfffd, 0x9ec1, 0x8a54, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8de5, 0xfffd, 0xfffd, 0xfffd, 0x897c, 0xfffd,
- 0xfffd, 0x9ed2, 0xfffd, 0xfffd, 0x9850, 0x9ed5, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9059, 0x9ed4, 0xfffd, 0xfffd, 0xfffd,
- 0x9ed3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ed0,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ec4, 0xfffd,
- 0xfffd, 0x9ee1, 0x9ec3, 0xfffd, 0x9ed6, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9ece, 0xfffd, 0xfffd, 0x9ec9, 0x9ec6,
- 0xfffd, 0x9ec7, 0xfffd, 0x9ecf, 0xfffd, 0xfffd, 0xfffd, 0xeaa0,
- 0xfffd, 0xfffd, 0x9ecc, 0x8d5c, 0x92c6, 0x9184, 0x9eca, 0xfffd,
- 0x9ec5, 0xfffd, 0xfffd, 0x9ec8, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x976c, 0x968a, 0xfffd, 0xfffd, 0xfffd, 0x9ecd, 0x9ed7, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9edf,
- 0x9ed8, 0xfffd, 0xfffd, 0x9ee5, 0xfffd, 0x9ee3, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9ede, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9edd, 0xfffd, 0x92ce, 0xfffd, 0x9185, 0xfffd, 0x9edb,
- 0xfffd, 0xfffd, 0x9ed9, 0xfffd, 0xfffd, 0x9ee0, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9ee6, 0x94f3, 0x9eec, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9ee7, 0x9eea, 0x9ee4, 0xfffd, 0xfffd, 0x9294,
- 0xfffd, 0x9557, 0xfffd, 0x9eda, 0xfffd, 0xfffd, 0x9ee2, 0x8fbe,
- 0xfffd, 0x96cd, 0x9ef6, 0x9ee9, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8ca0, 0x89a1, 0x8a7e, 0xfffd, 0xfffd, 0x9ed1, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8fbf, 0x9eee, 0xfffd,
- 0x9ef5, 0x8ef7, 0x8a92, 0xfffd, 0xfffd, 0x924d, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9eeb, 0xfffd, 0xfffd, 0x9ef0,
- 0x9ef4, 0xfffd, 0xfffd, 0x8bb4, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8b6b, 0x9ef2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b40,
- 0xfffd, 0x93c9, 0x9ef1, 0xfffd, 0xfffd, 0xfffd, 0x9ef3, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9eed, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9eef, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a80,
- 0x9268, 0xfffd, 0xfffd, 0xfffd, 0x9efa, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ef8, 0x8ce7, 0xfffd,
- 0x9ef7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9f40,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e77, 0xfffd, 0xfffd, 0xfffd,
- 0x9ef9, 0xfffd, 0x9efb, 0x9efc, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9f4b, 0xfffd, 0x9f47, 0xfffd, 0x9e8d, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9f46, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9f45, 0xfffd, 0xfffd, 0x9f42, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9ee8, 0x9f44, 0x9f43, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9f49, 0xfffd, 0x9845, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9f4c, 0x8bf9, 0xfffd, 0xfffd, 0x9f48, 0x9f4a,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x94a5, 0xfffd, 0x9f4d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9f51, 0x9f4e, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9793, 0x9f4f, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9edc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9f52, 0xfffd, 0xfffd, 0xfffd, 0x9f53, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8954, 0xfffd, 0x9f55,
- 0x8c87, 0x8e9f, 0xfffd, 0x8bd3, 0xfffd, 0xfffd, 0xfffd, 0x89a2,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x977e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9f57,
- 0x9f56, 0x9f59, 0x8b5c, 0xfffd, 0xfffd, 0x8bd4, 0x8abc, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9f5c, 0xfffd, 0xfffd, 0xfffd, 0x9f5b,
- 0xfffd, 0x9f5d, 0xfffd, 0xfffd, 0x89cc, 0xfffd, 0x9256, 0xfffd,
- 0x9f5e, 0xfffd, 0xfffd, 0x8abd, 0x9f60, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9f5f, 0xfffd, 0x9f61, 0xfffd, 0xfffd, 0xfffd, 0x9f62,
- 0xfffd, 0x9f63, 0x8e7e, 0x90b3, 0x8d9f, 0xfffd, 0x9590, 0xfffd,
- 0xfffd, 0x95e0, 0x9863, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8e95,
- 0xfffd, 0xfffd, 0xfffd, 0x8dce, 0x97f0, 0xfffd, 0xfffd, 0xfffd,
- 0x9f64, 0x9f65, 0xfffd, 0x8e80, 0xfffd, 0xfffd, 0xfffd, 0x9f66,
- 0x9f67, 0xfffd, 0xfffd, 0x9f69, 0x9f68, 0xfffd, 0x9677, 0xfffd,
- 0xfffd, 0x8f7d, 0x8eea, 0x8e63, 0xfffd, 0x9f6a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9f6c, 0x9042, 0xfffd,
- 0x9f6b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9f6d, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9f6e, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9f6f, 0x9f70, 0xfffd, 0xfffd, 0xfffd, 0x9f71,
- 0xfffd, 0x9f73, 0x9f72, 0x9f74, 0x89a3, 0x9269, 0xfffd, 0x9f75,
- 0xfffd, 0xfffd, 0x8e45, 0x8a6b, 0x9f76, 0xfffd, 0xfffd, 0x9361,
- 0x9aca, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b42, 0x9f77, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9f78, 0xfffd, 0x95ea, 0x9688, 0xfffd,
- 0xfffd, 0xfffd, 0x93c5, 0x9f79, 0x94e4, 0xfffd, 0xfffd, 0xfffd,
- 0x94f9, 0xfffd, 0xfffd, 0x96d1, 0xfffd, 0xfffd, 0xfffd, 0x9f7a,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9f7c, 0x9f7b, 0xfffd, 0xfffd, 0x9f7e,
- 0xfffd, 0xfffd, 0xfffd, 0x9f7d, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9f81, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8e81,
- 0xfffd, 0x96af, 0xfffd, 0x9f82, 0x9f83, 0xfffd, 0xfffd, 0x8b43,
- 0xfffd, 0xfffd, 0xfffd, 0x9f84, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9f86, 0x9f85, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9085, 0xfffd, 0xfffd, 0x9558,
- 0x8969, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x94c3, 0xfffd,
- 0x92f3, 0x8f60, 0x8b81, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x94c4, 0xfffd,
- 0x8eac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9f88, 0xfffd, 0x8abe,
- 0xfffd, 0xfffd, 0x8998, 0xfffd, 0xfffd, 0x93f0, 0x9f87, 0x8d5d,
- 0x9272, 0xfffd, 0x9f89, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9f91, 0xfffd, 0x9f8a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x91bf, 0xfffd, 0x8b82, 0x9f92, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8c88, 0xfffd, 0xfffd, 0x8b44, 0x9f90, 0xfffd,
- 0xfffd, 0x9f8e, 0x9f8b, 0x9780, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x92be, 0xfffd, 0xfffd, 0xfffd, 0x93d7, 0x9f8c, 0xfffd, 0xfffd,
- 0x9f94, 0xfffd, 0x9f93, 0x8c42, 0xfffd, 0xfffd, 0x89ab, 0xfffd,
- 0xfffd, 0x8db9, 0x9f8d, 0x9f8f, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9676, 0x91f2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9697, 0xfffd, 0xfffd, 0x9f9c, 0xfffd,
- 0xfffd, 0x9f9d, 0xfffd, 0x89cd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x95a6, 0x96fb, 0x9f9f, 0x8ea1, 0x8fc0, 0x9f98, 0x9f9e, 0x8988,
- 0xfffd, 0x8bb5, 0xfffd, 0xfffd, 0x9f95, 0x9f9a, 0xfffd, 0xfffd,
- 0xfffd, 0x90f2, 0x9491, 0xfffd, 0x94e5, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9f97, 0xfffd, 0x9640, 0xfffd, 0x9f99,
- 0xfffd, 0x9fa2, 0xfffd, 0x9fa0, 0xfffd, 0x9f9b, 0xfffd, 0xfffd,
- 0xfffd, 0x9641, 0x9467, 0x8b83, 0xfffd, 0x9344, 0xfffd, 0xfffd,
- 0x928d, 0xfffd, 0x9fa3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9fa1,
- 0x91d7, 0x9f96, 0xfffd, 0x896a, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x976d, 0x9fae, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9fad, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x90f4,
- 0xfffd, 0x9faa, 0xfffd, 0x978c, 0xfffd, 0xfffd, 0x93b4, 0x9fa4,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x92c3, 0xfffd, 0xfffd,
- 0xfffd, 0x896b, 0x8d5e, 0x9fa7, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8f46, 0x9fac, 0xfffd, 0x9fab, 0x9fa6, 0xfffd,
- 0x9fa9, 0xfffd, 0xfffd, 0x8a88, 0xfffd, 0x9fa8, 0x9468, 0xfffd,
- 0xfffd, 0x97ac, 0xfffd, 0xfffd, 0x8ff2, 0x90f3, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9fb4, 0x9fb2, 0xfffd, 0x956c, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9faf, 0x9fb1, 0xfffd, 0x8959, 0xfffd,
- 0xfffd, 0x8d5f, 0x9851, 0xfffd, 0x8a5c, 0xfffd, 0x9582, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9781, 0xfffd, 0xfffd, 0x8a43,
- 0x905a, 0x9fb3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9fb8, 0xfffd, 0xfffd,
- 0x8fc1, 0xfffd, 0xfffd, 0xfffd, 0x974f, 0xfffd, 0x9fb5, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9fb0, 0xfffd, 0x9fb6, 0xfffd, 0xfffd,
- 0xfffd, 0x97dc, 0xfffd, 0x9393, 0x93c0, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a55,
- 0xfffd, 0xfffd, 0x8974, 0xfffd, 0xfffd, 0x9fbc, 0xfffd, 0xfffd,
- 0x9fbf, 0xfffd, 0xfffd, 0xfffd, 0x97c1, 0xfffd, 0xfffd, 0xfffd,
- 0x9784, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9fc6, 0x9fc0, 0x9fbd,
- 0xfffd, 0xfffd, 0xfffd, 0x97d2, 0x9fc3, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8f69, 0x9fc5, 0xfffd, 0xfffd, 0x9fca, 0xfffd, 0xfffd,
- 0x9391, 0x9fc8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9fc2, 0xfffd,
- 0xfffd, 0x9257, 0xfffd, 0xfffd, 0x9fc9, 0xfffd, 0x9fbe, 0xfffd,
- 0x9fc4, 0xfffd, 0x9fcb, 0x88fa, 0x9fc1, 0xfffd, 0x9fcc, 0xfffd,
- 0xfffd, 0x905b, 0xfffd, 0x8f7e, 0xfffd, 0x95a3, 0xfffd, 0x8dac,
- 0xfffd, 0x9fb9, 0x9fc7, 0x9359, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x90b4, 0xfffd, 0x8a89,
- 0x8dcf, 0x8fc2, 0x9fbb, 0x8f61, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8c6b, 0xfffd, 0x9fba, 0xfffd, 0xfffd,
- 0xfffd, 0x9fd0, 0x8f8d, 0x8cb8, 0xfffd, 0x9fdf, 0xfffd, 0x9fd9,
- 0x8b94, 0x936e, 0xfffd, 0x9fd4, 0x9fdd, 0x88ad, 0x8951, 0xfffd,
- 0xfffd, 0x89b7, 0xfffd, 0x9fd6, 0x91aa, 0x9fcd, 0x9fcf, 0x8d60,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9fe0, 0xfffd, 0x9fdb, 0xfffd, 0xfffd, 0xfffd, 0x9fd3, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9fda, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x96a9, 0xfffd, 0xfffd, 0x9fd8, 0x9fdc, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8cce, 0xfffd,
- 0x8fc3, 0xfffd, 0xfffd, 0x9258, 0xfffd, 0xfffd, 0xfffd, 0x9fd2,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x974e,
- 0xfffd, 0xfffd, 0xfffd, 0x9fd5, 0xfffd, 0xfffd, 0x9fce, 0x9392,
- 0xfffd, 0xfffd, 0x9fd1, 0xfffd, 0xfffd, 0xfffd, 0x9fd7, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9870, 0x8ebc,
- 0x969e, 0xfffd, 0x9fe1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x94ac, 0xfffd, 0xfffd, 0x9fed,
- 0x8cb9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f80, 0xfffd,
- 0x9fe3, 0xfffd, 0xfffd, 0xfffd, 0x97ad, 0x8d61, 0xfffd, 0x9ff0,
- 0xfffd, 0xfffd, 0x88ec, 0xfffd, 0xfffd, 0x9fee, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9fe2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9fe8,
- 0xfffd, 0xfffd, 0x9fea, 0xfffd, 0xfffd, 0xfffd, 0x976e, 0x9fe5,
- 0xfffd, 0xfffd, 0x934d, 0xfffd, 0xfffd, 0x9fe7, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9fef, 0xfffd, 0x9fe9, 0x96c5, 0xfffd, 0xfffd,
- 0xfffd, 0x9fe4, 0xfffd, 0x8ea0, 0x9ffc, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8a8a, 0xfffd, 0x9fe6, 0x9feb, 0x9fec, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91ea, 0x91d8, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ff4, 0xfffd, 0xfffd, 0x9ffa,
- 0xfffd, 0xfffd, 0x9ff8, 0xfffd, 0x9348, 0xfffd, 0xfffd, 0xe042,
- 0x9ff5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ff6, 0x9fde,
- 0xfffd, 0x8b99, 0x9559, 0xfffd, 0xfffd, 0xfffd, 0x8ebd, 0xfffd,
- 0xfffd, 0x8d97, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9852,
- 0xfffd, 0x9ff2, 0xfffd, 0xe041, 0x8989, 0x9186, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9499, 0xfffd, 0x8abf, 0x97f8, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x969f, 0x92d0, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9ff9, 0x9ffb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9151, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe040, 0x9ff7,
- 0xfffd, 0x9ff1, 0xfffd, 0xfffd, 0xfffd, 0x8ac1, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c89, 0xfffd, 0xfffd, 0xfffd,
- 0xe04e, 0xfffd, 0xfffd, 0xe049, 0x90f6, 0xfffd, 0xfffd, 0x8a83,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f81, 0xfffd, 0xe052, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe04b, 0x92aa, 0xe048,
- 0x92d7, 0xfffd, 0xfffd, 0xfffd, 0xe06b, 0xfffd, 0xfffd, 0xfffd,
- 0xe045, 0xfffd, 0xe044, 0xfffd, 0xe04d, 0xfffd, 0xfffd, 0xfffd,
- 0xe047, 0xe046, 0xe04c, 0xfffd, 0x909f, 0xfffd, 0xe043, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe04f, 0xfffd,
- 0xfffd, 0xe050, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ac0,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe055, 0xfffd, 0xe054, 0xe056, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe059, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9362, 0xfffd, 0xe053, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe057, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8c83, 0x91f7, 0xe051, 0x945a, 0xfffd, 0xfffd, 0xe058, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe05d, 0xe05b, 0xfffd, 0xfffd,
- 0xe05e, 0xfffd, 0xfffd, 0xe061, 0xfffd, 0xfffd, 0xfffd, 0xe05a,
- 0x8d8a, 0x9447, 0xfffd, 0xfffd, 0x9fb7, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9794, 0xe05c, 0xfffd, 0xe060, 0x91f3,
- 0xfffd, 0xe05f, 0xfffd, 0xe04a, 0xfffd, 0xfffd, 0xe889, 0xfffd,
- 0xfffd, 0xfffd, 0xe064, 0xfffd, 0xfffd, 0xfffd, 0xe068, 0xfffd,
- 0xfffd, 0xe066, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe062, 0xfffd, 0xe063, 0xfffd, 0xfffd, 0xfffd, 0xe067,
- 0xfffd, 0xe065, 0xfffd, 0xfffd, 0xfffd, 0x956d, 0xfffd, 0xfffd,
- 0xe06d, 0xfffd, 0xe06a, 0xe069, 0xfffd, 0xe06c, 0x93d2, 0xe06e,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9295, 0x91eb,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x90a3, 0xfffd, 0xfffd, 0xfffd,
- 0xe06f, 0xfffd, 0xe071, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe070, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ff3, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe072, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x93e5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe073, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x89ce, 0xfffd, 0xfffd, 0xfffd, 0x9394,
- 0x8a44, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8b84, 0xfffd, 0xfffd, 0xfffd, 0x8edc, 0x8dd0, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9846, 0x9086, 0xfffd, 0xfffd, 0xfffd, 0x898a, 0xfffd,
- 0xfffd, 0xfffd, 0xe075, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe074, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe078, 0x9259, 0xe07b, 0xe076,
- 0xfffd, 0xfffd, 0xfffd, 0xe07a, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe079, 0x935f, 0x88d7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x97f3, 0xfffd, 0xfffd, 0xe07d, 0xfffd, 0xfffd, 0xfffd, 0x8947,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe080, 0xfffd, 0xfffd, 0xfffd, 0xe07e, 0xfffd, 0xe07c,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe077, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9642, 0xfffd, 0xfffd, 0xfffd, 0xe082, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe081, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x898b, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe084, 0x95b0, 0xfffd, 0xe083, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x96b3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8fc5, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9152, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8fc4, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x97f9, 0xfffd, 0xfffd, 0xe08a, 0xfffd, 0x90f7, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe086, 0xe08b, 0xfffd,
- 0xfffd, 0x898c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe089, 0xfffd, 0x9481, 0xe085, 0xe088, 0x8fc6,
- 0xfffd, 0x94cf, 0xfffd, 0xfffd, 0xe08c, 0xfffd, 0x8ecf, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x90f8, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe08f, 0xfffd, 0xfffd, 0xfffd,
- 0xe087, 0xfffd, 0x8c46, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe08d,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x976f, 0xe090, 0xfffd, 0xfffd,
- 0xfffd, 0xeaa4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f6e,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe091, 0xfffd, 0xfffd, 0xfffd, 0xe092, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x944d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe094, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe095, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9452, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9395, 0xe097, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe099, 0xfffd,
- 0x97d3, 0xfffd, 0xe096, 0xfffd, 0xe098, 0x898d, 0xfffd, 0xe093,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a7a,
- 0xe09a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9187, 0x8e57, 0xe09c,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe09b, 0x9043, 0x99d7, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe09d, 0xfffd, 0xfffd,
- 0xfffd, 0xe09f, 0xfffd, 0xe08e, 0xe09e, 0xfffd, 0xfffd, 0xe0a0,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x949a, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0a1, 0xfffd, 0xfffd,
- 0xe0a2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe0a3, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe0a4, 0xfffd, 0x92dc, 0xfffd, 0xe0a6, 0xe0a5, 0xfffd, 0xfffd,
- 0xe0a7, 0xfffd, 0xe0a8, 0xfffd, 0xfffd, 0x8edd, 0x9583, 0xfffd,
- 0xfffd, 0xfffd, 0x96ea, 0xe0a9, 0xe0aa, 0x9175, 0x8ea2, 0xe0ab,
- 0xe0ac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0ad, 0x95d0,
- 0x94c5, 0xfffd, 0xfffd, 0xe0ae, 0x9476, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x92ab, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe0af, 0x89e5, 0xfffd, 0x8b8d, 0xfffd, 0x96c4, 0xfffd, 0x96b4,
- 0xfffd, 0x89b2, 0x9853, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9671,
- 0xfffd, 0x95a8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x90b5, 0xfffd, 0xe0b0, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x93c1, 0xfffd, 0xfffd, 0xfffd, 0x8ca1, 0xe0b1, 0xfffd,
- 0x8dd2, 0xe0b3, 0xe0b2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0b4,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe0b5, 0xfffd, 0xfffd, 0xfffd, 0xe0b6, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8b5d, 0xfffd, 0xe0b7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0b8,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ca2, 0xfffd, 0xfffd, 0x94c6,
- 0xfffd, 0xfffd, 0xe0ba, 0xfffd, 0xfffd, 0xfffd, 0x8ff3, 0xfffd,
- 0xfffd, 0xe0b9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8bb6, 0xe0bb, 0xe0bd, 0xfffd, 0xe0bc, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0be, 0xfffd,
- 0x8ccf, 0xfffd, 0xe0bf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8be7,
- 0xfffd, 0x915f, 0xfffd, 0x8d9d, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe0c1, 0xe0c2, 0xe0c0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8eeb, 0xfffd, 0xfffd, 0x93c6, 0x8bb7, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0c4,
- 0x924b, 0xe0c3, 0xfffd, 0xfffd, 0x9854, 0x9482, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe0c7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0c9, 0xe0c6,
- 0xfffd, 0xfffd, 0xfffd, 0x96d2, 0xe0c8, 0xe0ca, 0xfffd, 0x97c2,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0ce, 0xfffd, 0xfffd,
- 0xfffd, 0xe0cd, 0x9296, 0x944c, 0xfffd, 0xfffd, 0x8ca3, 0xe0cc,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0cb, 0xfffd, 0x9750, 0x9751,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0cf, 0x898e,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8d96, 0x8e82, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0d0, 0xe0d1,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0d3,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8f62, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe0d5, 0xfffd, 0xe0d4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe0d6, 0xfffd, 0x8a6c, 0xfffd, 0xfffd, 0xe0d8, 0xfffd, 0xfffd,
- 0xe0d7, 0xfffd, 0xe0da, 0xe0d9, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8cba, 0xfffd, 0xfffd, 0x97a6,
- 0xfffd, 0x8bca, 0xfffd, 0x89a4, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8be8, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8adf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x97e6, 0xe0dc, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe0de, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe0df, 0xfffd, 0x89cf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe0db, 0xfffd, 0x8e58, 0xfffd, 0xfffd, 0x92bf, 0xe0dd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0e2, 0xfffd,
- 0x8eec, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0e0, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8c5d, 0xfffd, 0xfffd, 0x94c7, 0xe0e1, 0xfffd,
- 0xfffd, 0xe0fc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe0e7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8cbb, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8b85, 0xfffd, 0xe0e4, 0x979d, 0xfffd,
- 0xfffd, 0x97ae, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x91f4, 0xfffd, 0xfffd, 0xe0e6, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe0e8, 0x97d4, 0x8bd5, 0x94fa, 0x9469, 0xfffd,
- 0xfffd, 0xfffd, 0xe0e9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0eb,
- 0xfffd, 0xe0ee, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0ea, 0xfffd, 0xfffd,
- 0xfffd, 0xe0ed, 0x8ce8, 0x896c, 0xe0ef, 0xfffd, 0x9090, 0xe0ec,
- 0x97da, 0xfffd, 0xfffd, 0xe0f2, 0xeaa2, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe0f0, 0xe0f3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0e5,
- 0xe0f1, 0xfffd, 0xfffd, 0x8dba, 0xfffd, 0xfffd, 0xe0f4, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0f5, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x979e, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe0f6, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0f7, 0xfffd,
- 0xfffd, 0xfffd, 0xe0e3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0f8,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8ac2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ea3, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe0f9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0fa,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe0fb, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x895a, 0xfffd, 0xfffd, 0xfffd,
- 0xe140, 0xfffd, 0x955a, 0xe141, 0xfffd, 0xfffd, 0x8aa2, 0xe142,
- 0xfffd, 0xe143, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe144, 0xfffd,
- 0xe146, 0xe147, 0xe145, 0xfffd, 0xfffd, 0xfffd, 0x9572, 0xe149,
- 0xe148, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe14b, 0xe14a, 0xe14c, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe14d, 0xe14f, 0xe14e, 0xfffd,
- 0xfffd, 0x8d99, 0xfffd, 0xe151, 0xfffd, 0xe150, 0xfffd, 0xfffd,
- 0x8ac3, 0xfffd, 0x9072, 0xfffd, 0x935b, 0xfffd, 0xe152, 0x90b6,
- 0xfffd, 0xfffd, 0xfffd, 0x8e59, 0xfffd, 0x8999, 0xe153, 0xfffd,
- 0x9770, 0xfffd, 0xfffd, 0x95e1, 0xe154, 0xfffd, 0xfffd, 0xfffd,
- 0x9363, 0x9752, 0x8d62, 0x905c, 0xfffd, 0xfffd, 0xfffd, 0x926a,
- 0x99b2, 0xfffd, 0x92ac, 0x89e6, 0xe155, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe156, 0xfffd, 0xe15b, 0xfffd,
- 0xfffd, 0xe159, 0xe158, 0x9dc0, 0x8a45, 0xe157, 0xfffd, 0x88d8,
- 0xfffd, 0x94a8, 0xfffd, 0xfffd, 0x94c8, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x97af, 0xe15c, 0xe15a, 0x927b, 0x90a4, 0xfffd, 0xfffd,
- 0x94a9, 0xfffd, 0x954c, 0xfffd, 0xe15e, 0x97aa, 0x8c6c, 0xe15f,
- 0xfffd, 0xe15d, 0x94d4, 0xe160, 0xfffd, 0xe161, 0xfffd, 0xfffd,
- 0x88d9, 0xfffd, 0xfffd, 0x8ff4, 0xe166, 0xfffd, 0xe163, 0x93eb,
- 0xe162, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b45,
- 0xfffd, 0xfffd, 0xe169, 0xfffd, 0xfffd, 0xfffd, 0xe164, 0xe165,
- 0xfffd, 0xe168, 0xe167, 0x9544, 0xfffd, 0xfffd, 0x9161, 0x9160,
- 0xfffd, 0x8b5e, 0xfffd, 0xfffd, 0xe16a, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe16b, 0xfffd, 0xfffd, 0xe16c, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe16e, 0xfffd, 0xe16d, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8975, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe176, 0x94e6, 0xe170, 0xfffd, 0xe172, 0xfffd, 0xfffd,
- 0xe174, 0x905d, 0xfffd, 0xfffd, 0xe175, 0xe173, 0x8ebe, 0xfffd,
- 0xfffd, 0xfffd, 0xe16f, 0xe171, 0xfffd, 0x9561, 0xfffd, 0x8fc7,
- 0xfffd, 0xfffd, 0xe178, 0xfffd, 0xfffd, 0xe177, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe179, 0xfffd, 0x8ea4, 0x8dad, 0xfffd, 0xfffd,
- 0x9397, 0xe17a, 0xfffd, 0x92c9, 0xfffd, 0xfffd, 0xe17c, 0xfffd,
- 0xfffd, 0xfffd, 0x979f, 0xe17b, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9189, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe182, 0xfffd, 0xe184, 0xe185, 0x9273, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe183, 0xfffd, 0xe180, 0xfffd, 0xe17d, 0xe17e,
- 0xfffd, 0xe181, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe188, 0xfffd, 0xe186, 0xfffd, 0xe187, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe189,
- 0xe18b, 0xe18c, 0xe18d, 0xfffd, 0xe18e, 0xfffd, 0xfffd, 0xe18a,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe190, 0xfffd, 0xfffd, 0xfffd, 0xe18f, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe191, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x97c3, 0xfffd, 0xfffd, 0xfffd, 0xe194, 0xe192,
- 0xe193, 0xfffd, 0xfffd, 0xfffd, 0x8ae0, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x96fc, 0xfffd, 0xfffd, 0xfffd, 0x95c8, 0xfffd,
- 0xe196, 0xfffd, 0xfffd, 0xfffd, 0xe195, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe197, 0xe198, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe19c,
- 0xe199, 0xe19a, 0xe19b, 0xfffd, 0xe19d, 0xfffd, 0xfffd, 0xfffd,
- 0xe19e, 0xfffd, 0xe19f, 0xfffd, 0xfffd, 0xfffd, 0xe1a0, 0xfffd,
- 0xe1a1, 0xfffd, 0x94ad, 0x936f, 0xe1a2, 0x9492, 0x9553, 0xfffd,
- 0xe1a3, 0xfffd, 0xfffd, 0xe1a4, 0x9349, 0xfffd, 0x8a46, 0x8d63,
- 0xe1a5, 0xfffd, 0xfffd, 0xe1a6, 0xfffd, 0xfffd, 0xe1a7, 0xfffd,
- 0x8e48, 0xfffd, 0xfffd, 0xe1a9, 0xfffd, 0xfffd, 0xe1a8, 0xfffd,
- 0xfffd, 0xe1aa, 0xe1ab, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x94e7, 0xfffd,
- 0xe1ac, 0xfffd, 0xfffd, 0xfffd, 0xe1ad, 0xfffd, 0xfffd, 0xea89,
- 0xe1ae, 0xe1af, 0xe1b0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8e4d,
- 0xfffd, 0xfffd, 0xe1b1, 0x9475, 0xfffd, 0xfffd, 0x967e, 0xfffd,
- 0x896d, 0xfffd, 0x8976, 0xfffd, 0xfffd, 0xe1b2, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe1b4, 0xfffd, 0xfffd, 0xfffd, 0xe1b3, 0x9390,
- 0xfffd, 0xfffd, 0xfffd, 0x90b7, 0x9f58, 0xfffd, 0xe1b5, 0x96bf,
- 0xfffd, 0xe1b6, 0xfffd, 0x8ac4, 0x94d5, 0xe1b7, 0xfffd, 0xe1b8,
- 0xfffd, 0xfffd, 0xe1b9, 0xfffd, 0xfffd, 0xfffd, 0x96da, 0xfffd,
- 0xfffd, 0xfffd, 0x96d3, 0xfffd, 0x92bc, 0xfffd, 0xfffd, 0xfffd,
- 0x918a, 0xfffd, 0xfffd, 0xe1bb, 0xfffd, 0xfffd, 0x8f82, 0xfffd,
- 0xfffd, 0x8fc8, 0xfffd, 0xfffd, 0xe1be, 0xfffd, 0xfffd, 0xe1bd,
- 0xe1bc, 0x94fb, 0xfffd, 0x8ac5, 0x8ca7, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe1c4, 0xfffd, 0xfffd, 0xe1c1, 0x905e,
- 0x96b0, 0xfffd, 0xfffd, 0xfffd, 0xe1c0, 0xe1c2, 0xe1c3, 0xfffd,
- 0xfffd, 0xe1bf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1c5,
- 0xe1c6, 0xfffd, 0x92ad, 0xfffd, 0x8ae1, 0xfffd, 0xfffd, 0xfffd,
- 0x9285, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1c7,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe1c8, 0xe1cb, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9087, 0xfffd, 0x93c2, 0xfffd, 0xe1cc, 0x9672, 0xfffd,
- 0xe1c9, 0xfffd, 0xfffd, 0xe1ca, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe1cf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1ce, 0xe1cd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe1d1, 0xfffd, 0xfffd, 0xe1d0, 0xfffd,
- 0xfffd, 0xe1d2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1d4, 0xfffd,
- 0xe1d3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95cb, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f75, 0x97c4, 0xfffd, 0xfffd,
- 0xe1d5, 0xfffd, 0xfffd, 0x93b5, 0xfffd, 0xfffd, 0xe1d6, 0xfffd,
- 0xfffd, 0xe1d7, 0xfffd, 0xe1db, 0xe1d9, 0xe1da, 0xfffd, 0xe1d8,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1dc,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1dd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1de,
- 0xfffd, 0xfffd, 0xe1df, 0x96b5, 0xe1e0, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x96ee, 0xe1e1, 0xfffd, 0x926d, 0xfffd, 0x948a,
- 0xfffd, 0x8be9, 0xfffd, 0xfffd, 0xfffd, 0x925a, 0xe1e2, 0x8bb8,
- 0xfffd, 0xfffd, 0xfffd, 0x90ce, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1e3, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8dbb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1e4, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe1e5, 0xfffd, 0x8ca4, 0x8dd3, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe1e7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9375, 0x8dd4, 0x8b6d,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9643, 0xfffd, 0x946a, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9376, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8d7b,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1e9, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8fc9, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x97b0, 0x8d64, 0xfffd, 0xfffd, 0x8ca5,
- 0xfffd, 0xfffd, 0x94a1, 0xfffd, 0xe1eb, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1ed, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8ce9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1ec, 0x92f4,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1ef, 0x8a56, 0xe1ea, 0xfffd,
- 0xfffd, 0x94e8, 0xfffd, 0x894f, 0xfffd, 0x8dea, 0xfffd, 0x9871,
- 0xfffd, 0xfffd, 0xe1ee, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe1f0, 0xfffd, 0xfffd, 0xfffd, 0x95c9,
- 0xfffd, 0x90d7, 0xe1f2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1f3,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1f1, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8a6d, 0xfffd, 0xe1f9, 0xfffd, 0xe1f8, 0xfffd,
- 0xfffd, 0x8ea5, 0xfffd, 0xfffd, 0xfffd, 0xe1fa, 0xe1f5, 0xfffd,
- 0xfffd, 0xfffd, 0xe1fb, 0xe1f6, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x94d6, 0xe1f4, 0xfffd, 0xfffd, 0xe1f7, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe241, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe240,
- 0x9681, 0xfffd, 0xfffd, 0xfffd, 0xe1fc, 0xfffd, 0xfffd, 0x88e9,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe243, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe242, 0xfffd, 0xfffd,
- 0xfffd, 0x8fca, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe244,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9162, 0xfffd,
- 0xfffd, 0xe246, 0xe245, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe247, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe1e6, 0xfffd,
- 0xfffd, 0xfffd, 0xe1e8, 0xe249, 0xe248, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8ea6, 0xfffd, 0x97e7, 0xfffd, 0x8ed0, 0xfffd,
- 0xe24a, 0x8c56, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b5f,
- 0x8b46, 0x8e83, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9753, 0xfffd, 0xfffd, 0xe250, 0xfffd, 0xe24f, 0x9163, 0xe24c,
- 0xfffd, 0xfffd, 0xe24e, 0xfffd, 0xfffd, 0x8f6a, 0x905f, 0xe24d,
- 0xe24b, 0xfffd, 0x9449, 0xfffd, 0xfffd, 0x8fcb, 0xfffd, 0xfffd,
- 0x955b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8dd5, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9398,
- 0xfffd, 0xfffd, 0xe251, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe252,
- 0xe268, 0x8bd6, 0xfffd, 0xfffd, 0x985c, 0x9154, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe253, 0xfffd, 0xfffd, 0x89d0, 0x92f5, 0x959f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe254, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b9a, 0xe255,
- 0xfffd, 0xfffd, 0xe257, 0xfffd, 0xfffd, 0xfffd, 0xe258, 0xfffd,
- 0x9448, 0xfffd, 0xfffd, 0xe259, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe25a, 0xe25b, 0xfffd, 0xfffd, 0x8bd7, 0x89d1, 0x93c3,
- 0x8f47, 0x8e84, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe25c, 0xfffd, 0x8f48, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x89c8, 0x9562, 0xfffd, 0xfffd, 0xe25d, 0xfffd, 0xfffd,
- 0x94e9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9164,
- 0xfffd, 0xe260, 0xfffd, 0xe261, 0x9489, 0xfffd, 0x9060, 0xe25e,
- 0xfffd, 0x9281, 0xfffd, 0xfffd, 0xe25f, 0xfffd, 0xfffd, 0xfffd,
- 0x8fcc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x88da, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8b48, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe262, 0xfffd, 0xfffd, 0x92f6, 0xfffd, 0xe263, 0x90c5, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x96ab, 0xfffd, 0xfffd, 0x9542,
- 0xe264, 0xe265, 0x9274, 0xfffd, 0x97c5, 0xfffd, 0xfffd, 0xe267,
- 0xe266, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8eed, 0xfffd,
- 0xfffd, 0xe269, 0x88ee, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe26c,
- 0xfffd, 0xfffd, 0xfffd, 0xe26a, 0x89d2, 0x8c6d, 0xe26b, 0x8d65,
- 0x8d92, 0xfffd, 0x95e4, 0xe26d, 0xfffd, 0xfffd, 0x9673, 0xfffd,
- 0xfffd, 0xe26f, 0xfffd, 0xfffd, 0xfffd, 0x90cf, 0x896e, 0x89b8,
- 0x88aa, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe26e,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe270, 0xe271, 0x8ff5, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe272, 0xfffd, 0x8a6e, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe274, 0xfffd, 0xfffd, 0xfffd, 0x8c8a, 0xfffd, 0x8b86, 0xfffd,
- 0xfffd, 0xe275, 0x8bf3, 0xfffd, 0xfffd, 0xe276, 0xfffd, 0x90fa,
- 0xfffd, 0x93cb, 0xfffd, 0x90de, 0x8df3, 0xfffd, 0xfffd, 0xfffd,
- 0xe277, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9282, 0x918b, 0xfffd, 0xe279, 0xe27b, 0xe278,
- 0xe27a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c41,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe27c, 0x8c45, 0xfffd, 0xfffd, 0xfffd, 0x8b87, 0x9771,
- 0xe27e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe280, 0xfffd,
- 0xfffd, 0xfffd, 0x894d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe283,
- 0xfffd, 0xfffd, 0xfffd, 0x8a96, 0xe282, 0xe281, 0xfffd, 0xe285,
- 0xe27d, 0xfffd, 0xe286, 0x97a7, 0xfffd, 0xe287, 0xfffd, 0xe288,
- 0xfffd, 0xfffd, 0x9af2, 0xe28a, 0xfffd, 0xe289, 0xfffd, 0xfffd,
- 0xfffd, 0xe28b, 0xe28c, 0xfffd, 0x97b3, 0xe28d, 0xfffd, 0xe8ed,
- 0x8fcd, 0xe28e, 0xe28f, 0x8f76, 0xfffd, 0x93b6, 0xe290, 0xfffd,
- 0xfffd, 0xfffd, 0x9247, 0xfffd, 0xfffd, 0xe291, 0xfffd, 0x925b,
- 0xe292, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ba3, 0xfffd,
- 0x995e, 0x927c, 0x8eb1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ac6,
- 0xfffd, 0xfffd, 0xe293, 0xfffd, 0xe2a0, 0xfffd, 0xe296, 0xfffd,
- 0x8b88, 0xfffd, 0xe295, 0xe2a2, 0xfffd, 0xfffd, 0xfffd, 0xe294,
- 0xfffd, 0x8fce, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe298, 0xe299, 0xfffd, 0x934a, 0xfffd, 0xfffd, 0xe29a, 0xfffd,
- 0x8a7d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9079, 0x9584, 0xfffd,
- 0xe29c, 0xfffd, 0xfffd, 0xfffd, 0x91e6, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe297, 0xfffd, 0xe29b, 0xe29d, 0xfffd,
- 0xfffd, 0x8df9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2a4, 0x954d, 0xfffd,
- 0x94a4, 0x9399, 0xfffd, 0x8bd8, 0xe2a3, 0xe2a1, 0xfffd, 0x94b3,
- 0xe29e, 0x927d, 0x939b, 0xfffd, 0x939a, 0xfffd, 0x8df4, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2b6, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2a6, 0xfffd, 0xe2a8,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2ab, 0xfffd, 0xe2ac, 0xfffd,
- 0xe2a9, 0xe2aa, 0xfffd, 0xfffd, 0xe2a7, 0xe2a5, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe29f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95cd, 0x89d3,
- 0xfffd, 0xfffd, 0xfffd, 0xe2b3, 0xfffd, 0xe2b0, 0xfffd, 0xe2b5,
- 0xfffd, 0xfffd, 0xe2b4, 0xfffd, 0x9493, 0x96a5, 0xfffd, 0x8e5a,
- 0xe2ae, 0xe2b7, 0xe2b2, 0xfffd, 0xe2b1, 0xe2ad, 0xfffd, 0xe2af,
- 0xfffd, 0x8ac7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x925c, 0xfffd, 0xfffd, 0x90fb, 0xfffd, 0xfffd,
- 0xfffd, 0x94a0, 0xfffd, 0xfffd, 0xe2bc, 0xfffd, 0xfffd, 0xfffd,
- 0x94a2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x90df, 0xe2b9, 0xfffd, 0xfffd, 0x94cd, 0xfffd, 0xe2bd, 0x95d1,
- 0xfffd, 0x927a, 0xfffd, 0xe2b8, 0xe2ba, 0xfffd, 0xfffd, 0xe2bb,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2be, 0xfffd, 0xfffd,
- 0x8ec2, 0xfffd, 0xfffd, 0xfffd, 0x93c4, 0xe2c3, 0xe2c2, 0xfffd,
- 0xfffd, 0xe2bf, 0xfffd, 0xfffd, 0xfffd, 0x9855, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe2c8, 0xfffd, 0xfffd, 0xe2cc, 0xe2c9,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe2c5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2c6,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2cb, 0xfffd, 0xfffd,
- 0xfffd, 0xe2c0, 0x99d3, 0xe2c7, 0xe2c1, 0xfffd, 0xfffd, 0xe2ca,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2d0,
- 0xfffd, 0x8ac8, 0xfffd, 0xe2cd, 0xfffd, 0xfffd, 0xfffd, 0xe2ce,
- 0xfffd, 0xfffd, 0xe2cf, 0xe2d2, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2d1,
- 0x94f4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2d3, 0x97fa, 0x95eb,
- 0xe2d8, 0xfffd, 0xfffd, 0xe2d5, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2d4, 0x90d0, 0xfffd, 0xe2d7,
- 0xe2d9, 0xfffd, 0xfffd, 0xfffd, 0xe2d6, 0xfffd, 0xe2dd, 0xfffd,
- 0xe2da, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2db,
- 0xe2c4, 0xfffd, 0xfffd, 0xfffd, 0xe2dc, 0xe2de, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2df, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x95c4, 0xfffd, 0xe2e0, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x96e0, 0xfffd,
- 0xfffd, 0x8bcc, 0x8c48, 0xe2e1, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x95b2, 0xfffd, 0x9088, 0xfffd, 0x96ae, 0xfffd, 0xfffd,
- 0xe2e2, 0xfffd, 0x97b1, 0xfffd, 0xfffd, 0x9494, 0xfffd, 0x9165,
- 0x9453, 0xfffd, 0xfffd, 0x8f6c, 0xfffd, 0xfffd, 0xfffd, 0x88be,
- 0xfffd, 0xe2e7, 0xe2e5, 0xfffd, 0xe2e3, 0x8a9f, 0xfffd, 0x8fcf,
- 0xe2e8, 0xfffd, 0xfffd, 0xe2e6, 0xfffd, 0xe2e4, 0xe2ec, 0xfffd,
- 0xfffd, 0xe2eb, 0xe2ea, 0xe2e9, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe2ed, 0xfffd, 0xfffd, 0xfffd, 0xe2ee, 0x90b8, 0xfffd,
- 0xe2ef, 0xfffd, 0xe2f1, 0xfffd, 0xfffd, 0xe2f0, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8cd0, 0xfffd, 0xfffd, 0xfffd, 0x9157, 0xfffd,
- 0xfffd, 0xfffd, 0xe2f3, 0xfffd, 0xfffd, 0xfffd, 0x939c, 0xfffd,
- 0xe2f2, 0xfffd, 0xfffd, 0xfffd, 0xe2f4, 0xfffd, 0x95b3, 0x918c,
- 0x8d66, 0xfffd, 0xe2f5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x97c6,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe2f7,
- 0xfffd, 0xfffd, 0xe2f8, 0xfffd, 0xe2f9, 0xfffd, 0xe2fa, 0xfffd,
- 0x8e85, 0xfffd, 0xe2fb, 0x8c6e, 0xfffd, 0xfffd, 0x8b8a, 0xfffd,
- 0x8b49, 0xfffd, 0xe340, 0xfffd, 0x96f1, 0x8d67, 0xe2fc, 0xfffd,
- 0xfffd, 0xfffd, 0xe343, 0x96e4, 0xfffd, 0x945b, 0xfffd, 0xfffd,
- 0x9552, 0xfffd, 0xfffd, 0xfffd, 0x8f83, 0xe342, 0xfffd, 0x8ed1,
- 0x8d68, 0x8e86, 0x8b89, 0x95b4, 0xe341, 0xfffd, 0xfffd, 0xfffd,
- 0x9166, 0x9661, 0x8df5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8e87, 0x92db, 0xfffd, 0xe346, 0x97dd,
- 0x8dd7, 0xfffd, 0xe347, 0x9061, 0xfffd, 0xe349, 0xfffd, 0xfffd,
- 0xfffd, 0x8fd0, 0x8dae, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe348,
- 0xfffd, 0xfffd, 0x8f49, 0x8cbc, 0x9167, 0xe344, 0xe34a, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe345, 0x8c6f, 0xfffd, 0xe34d, 0xe351,
- 0x8c8b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe34c, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe355, 0xfffd, 0xfffd, 0x8d69, 0xfffd,
- 0xfffd, 0x978d, 0x88ba, 0xe352, 0xfffd, 0xfffd, 0x8b8b, 0xfffd,
- 0xe34f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe350, 0xfffd,
- 0xfffd, 0x939d, 0xe34e, 0xe34b, 0xfffd, 0x8a47, 0x90e2, 0xfffd,
- 0xfffd, 0x8ca6, 0xfffd, 0xfffd, 0xfffd, 0xe357, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe354, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe356,
- 0xfffd, 0xfffd, 0xfffd, 0xe353, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8c70, 0x91b1, 0xe358, 0x918e, 0xfffd, 0xfffd, 0xe365,
- 0xfffd, 0xfffd, 0xe361, 0xe35b, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe35f, 0x8ef8, 0x88db, 0xe35a, 0xe362,
- 0xe366, 0x8d6a, 0x96d4, 0xfffd, 0x92d4, 0xe35c, 0xfffd, 0xfffd,
- 0xe364, 0xfffd, 0xe359, 0x925d, 0xfffd, 0xe35e, 0x88bb, 0x96c8,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe35d,
- 0xfffd, 0xfffd, 0x8bd9, 0x94ea, 0xfffd, 0xfffd, 0xfffd, 0x918d,
- 0xfffd, 0x97ce, 0x8f8f, 0xfffd, 0xfffd, 0xe38e, 0xfffd, 0xfffd,
- 0xe367, 0xfffd, 0x90fc, 0xfffd, 0xe363, 0xe368, 0xe36a, 0xfffd,
- 0x92f7, 0xe36d, 0xfffd, 0xfffd, 0xe369, 0xfffd, 0xfffd, 0xfffd,
- 0x95d2, 0x8ac9, 0xfffd, 0xfffd, 0x96c9, 0xfffd, 0xfffd, 0x88dc,
- 0xfffd, 0xfffd, 0xe36c, 0xfffd, 0x97fb, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe36b, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x898f, 0xfffd, 0xfffd, 0x93ea, 0xe36e, 0xfffd, 0xfffd,
- 0xfffd, 0xe375, 0xe36f, 0xe376, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe372, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x949b, 0xfffd, 0xfffd, 0x8ec8, 0xe374,
- 0xfffd, 0xe371, 0xe377, 0xe370, 0xfffd, 0xfffd, 0x8f63, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9644, 0xfffd, 0xfffd, 0x8f6b, 0xfffd,
- 0xfffd, 0xe373, 0xe380, 0xfffd, 0xfffd, 0xe37b, 0xfffd, 0xe37e,
- 0xfffd, 0xe37c, 0xe381, 0xe37a, 0xfffd, 0xe360, 0x90d1, 0xfffd,
- 0xfffd, 0x94c9, 0xfffd, 0xe37d, 0xfffd, 0xfffd, 0xe378, 0xfffd,
- 0xfffd, 0xfffd, 0x9140, 0x8c71, 0xfffd, 0x8f4a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9044, 0x9155, 0xe384, 0xfffd,
- 0xfffd, 0xe386, 0xe387, 0xfffd, 0xfffd, 0xe383, 0xe385, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe379, 0xe382,
- 0xfffd, 0xe38a, 0xe389, 0xfffd, 0xfffd, 0x969a, 0xfffd, 0xfffd,
- 0x8c4a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe388, 0xfffd, 0xe38c, 0xe38b, 0xe38f, 0xfffd, 0xe391,
- 0xfffd, 0xfffd, 0x8e5b, 0xe38d, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe392, 0xe393, 0xfffd, 0xfffd, 0xe394, 0xfffd, 0xe39a, 0x935a,
- 0xe396, 0xfffd, 0xe395, 0xe397, 0xe398, 0xfffd, 0xe399, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe39b, 0xe39c, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8aca, 0xfffd,
- 0xe39d, 0xfffd, 0xe39e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe39f, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3a0, 0xe3a1, 0xe3a2, 0xfffd,
- 0xe3a3, 0xe3a4, 0xfffd, 0xfffd, 0xe3a6, 0xe3a5, 0xfffd, 0xfffd,
- 0xe3a7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3a8,
- 0xe3a9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3ac,
- 0xe3aa, 0xe3ab, 0x8ddf, 0x8c72, 0xfffd, 0xfffd, 0x9275, 0xfffd,
- 0x94b1, 0xfffd, 0x8f90, 0xfffd, 0xfffd, 0x946c, 0xfffd, 0x94eb,
- 0xe3ad, 0x9ceb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe3ae, 0xe3b0, 0xfffd, 0x9785, 0xe3af, 0xe3b2,
- 0xe3b1, 0xfffd, 0x9772, 0xfffd, 0xe3b3, 0xfffd, 0x94fc, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3b4, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe3b7, 0xfffd, 0xfffd, 0xe3b6, 0xe3b5, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe3b8, 0x8c51, 0xfffd, 0xfffd, 0xfffd,
- 0x9141, 0x8b60, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3bc, 0xe3b9,
- 0xfffd, 0xfffd, 0xe3ba, 0xfffd, 0xfffd, 0xfffd, 0xe3bd, 0xfffd,
- 0xe3be, 0xe3bb, 0xfffd, 0xfffd, 0xfffd, 0x8948, 0xfffd, 0xfffd,
- 0xfffd, 0x89a5, 0xfffd, 0xfffd, 0xfffd, 0xe3c0, 0xe3c1, 0xfffd,
- 0xfffd, 0xfffd, 0xe3c2, 0xfffd, 0x9782, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8f4b, 0xfffd, 0xe3c4, 0xe3c3, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9089, 0xe3c5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3c6, 0xfffd,
- 0xfffd, 0xe3c7, 0xfffd, 0x8ae3, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8acb, 0xfffd, 0xfffd, 0xe3c8, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe3c9, 0xfffd, 0x967c, 0x9783, 0xfffd, 0xfffd, 0xfffd,
- 0x9773, 0x9856, 0xfffd, 0x8d6c, 0xe3cc, 0x8ed2, 0xe3cb, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe3cd, 0x8ea7, 0xfffd, 0xfffd, 0xfffd,
- 0x91cf, 0xfffd, 0xe3ce, 0xfffd, 0xfffd, 0x8d6b, 0xfffd, 0x96d5,
- 0xe3cf, 0xe3d0, 0xfffd, 0xfffd, 0xe3d1, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe3d2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe3d3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8ea8, 0xfffd, 0xfffd, 0x96eb, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe3d5, 0xfffd, 0x925e, 0xfffd, 0xe3d4,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3d7, 0xfffd,
- 0xfffd, 0xfffd, 0xe3d6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe3d8, 0xfffd, 0xfffd, 0xfffd, 0x90b9, 0xfffd,
- 0xe3d9, 0xfffd, 0xe3da, 0xfffd, 0xfffd, 0xfffd, 0x95b7, 0xe3db,
- 0xfffd, 0x918f, 0xe3dc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe3dd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x97fc,
- 0xe3e0, 0xfffd, 0xe3df, 0xe3de, 0x92ae, 0xfffd, 0xe3e1, 0x9045,
- 0xfffd, 0xe3e2, 0xfffd, 0xfffd, 0xfffd, 0xe3e3, 0x9857, 0xe3e4,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3e5, 0xe3e7, 0xe3e6, 0x94a3,
- 0xfffd, 0x93f7, 0xfffd, 0x985d, 0x94a7, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe3e9, 0xfffd, 0xfffd, 0x8fd1, 0xfffd,
- 0x9549, 0xfffd, 0xe3ea, 0xe3e8, 0xfffd, 0x8acc, 0xfffd, 0xfffd,
- 0xfffd, 0x8cd2, 0x8e88, 0xfffd, 0xfffd, 0x94ec, 0xfffd, 0xfffd,
- 0xfffd, 0x8ca8, 0x9662, 0xfffd, 0xe3ed, 0xe3eb, 0xfffd, 0x8d6d,
- 0xfffd, 0x8d6e, 0x88e7, 0xfffd, 0x8de6, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9478, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x88dd, 0xe3f2, 0xfffd, 0x925f, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9477, 0xfffd, 0x91d9, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3f4, 0xfffd,
- 0xfffd, 0xe3f0, 0xe3f3, 0xe3ee, 0xfffd, 0xe3f1, 0x9645, 0xfffd,
- 0xfffd, 0x8cd3, 0xfffd, 0xfffd, 0x88fb, 0xe3ef, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3f6,
- 0xfffd, 0xe3f7, 0xfffd, 0xfffd, 0x93b7, 0xfffd, 0xfffd, 0xfffd,
- 0x8bb9, 0xfffd, 0xfffd, 0xfffd, 0xe445, 0x945c, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8e89, 0xfffd, 0xfffd, 0x8bba, 0x90c6, 0x9865,
- 0x96ac, 0xe3f5, 0x90d2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8b72, 0xe3f8, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe3fa, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe3f9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe3fb,
- 0xfffd, 0x9245, 0xfffd, 0x945d, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x92af, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe442, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe441, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe3fc, 0xfffd, 0xfffd, 0x9074, 0xfffd,
- 0x9585, 0xe444, 0xfffd, 0xe443, 0x8d6f, 0x9872, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe454,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe448, 0xe449, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8eee, 0xfffd, 0xfffd, 0xe447, 0xfffd,
- 0x8d98, 0xe446, 0xfffd, 0xfffd, 0xe44a, 0xfffd, 0xfffd, 0xfffd,
- 0x92b0, 0x95a0, 0x9142, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91da,
- 0xe44e, 0xfffd, 0xe44f, 0xe44b, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe44c, 0xfffd, 0xe44d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8d70,
- 0xfffd, 0xfffd, 0xfffd, 0xe455, 0xfffd, 0xe451, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9586, 0xfffd, 0x968c, 0x9547, 0xfffd, 0xfffd,
- 0xe450, 0xfffd, 0xfffd, 0xe453, 0xe452, 0xfffd, 0xfffd, 0xfffd,
- 0x9663, 0xe456, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe457, 0xfffd, 0xfffd, 0x9156, 0xfffd, 0xe458, 0xfffd, 0xfffd,
- 0xe45a, 0xfffd, 0xe45e, 0xfffd, 0xfffd, 0xe45b, 0xe459, 0x945e,
- 0xe45c, 0xfffd, 0xe45d, 0xfffd, 0xfffd, 0xfffd, 0x89b0, 0xfffd,
- 0xe464, 0xe45f, 0xfffd, 0xfffd, 0xfffd, 0xe460, 0xfffd, 0xfffd,
- 0xfffd, 0xe461, 0xfffd, 0x919f, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe463, 0xe462, 0xe465, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe466,
- 0xe467, 0xfffd, 0xfffd, 0x9062, 0xfffd, 0x89e7, 0xfffd, 0xe468,
- 0x97d5, 0xfffd, 0x8ea9, 0xfffd, 0xfffd, 0x8f4c, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8e8a, 0x9276, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe469, 0xe46a, 0x8950, 0xfffd, 0xe46b, 0xfffd,
- 0xfffd, 0xe46c, 0xe46d, 0xfffd, 0xfffd, 0xe46e, 0xfffd, 0xe46f,
- 0x8bbb, 0x9da8, 0xe470, 0xfffd, 0x90e3, 0xe471, 0x8ec9, 0xfffd,
- 0xe472, 0xfffd, 0x98ae, 0xfffd, 0xfffd, 0xfffd, 0xe473, 0x95dc,
- 0x8ada, 0xfffd, 0xfffd, 0x9143, 0x8f77, 0xfffd, 0x9591, 0x8f4d,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe474, 0x8d71, 0xe475, 0x94ca, 0xfffd, 0xe484, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe477, 0xfffd, 0x91c7, 0x9495, 0x8cbd,
- 0xe476, 0x9144, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe478, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x92f8,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe47a, 0xe479, 0xe47c, 0xfffd, 0xfffd, 0xe47b, 0xfffd, 0xe47d,
- 0xfffd, 0xfffd, 0xe480, 0xfffd, 0xe47e, 0xfffd, 0x8acd, 0xfffd,
- 0xe481, 0xfffd, 0xe482, 0xe483, 0xfffd, 0xfffd, 0x8daf, 0x97c7,
- 0xfffd, 0xe485, 0x9046, 0xfffd, 0xfffd, 0xfffd, 0x8990, 0xe486,
- 0xe487, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe488, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x88f0, 0xfffd, 0xe489, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe48a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9587, 0xfffd, 0xfffd, 0xfffd, 0x8ec5, 0xfffd, 0xe48c,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a48, 0x88b0, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe48b, 0xe48e, 0x946d, 0xfffd, 0x9063,
- 0xfffd, 0x89d4, 0xfffd, 0x9646, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8c7c, 0x8bda, 0xfffd, 0xe48d, 0xfffd, 0x89e8, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8aa1, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8991, 0xe492, 0x97e8, 0x91db, 0xfffd, 0xfffd, 0x9563,
- 0xfffd, 0xe49e, 0xfffd, 0x89d5, 0xe49c, 0xfffd, 0xe49a, 0xe491,
- 0xfffd, 0xe48f, 0xfffd, 0xe490, 0xfffd, 0x8ee1, 0x8bea, 0x9297,
- 0xfffd, 0xfffd, 0xfffd, 0x93cf, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8970, 0xfffd, 0xe494, 0xe493, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe499, 0xe495, 0xe498, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x96ce, 0xe497, 0x89d6, 0x8a9d, 0xe49b, 0xfffd,
- 0xfffd, 0xe49d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c73, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4a1, 0xe4aa,
- 0xe4ab, 0xfffd, 0xfffd, 0xfffd, 0x88a9, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe4b2, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x88ef, 0xfffd, 0xfffd, 0xe4a9, 0xfffd, 0xfffd, 0xfffd, 0xe4a8,
- 0xfffd, 0xe4a3, 0xe4a2, 0xfffd, 0xe4a0, 0xe49f, 0x9283, 0xfffd,
- 0x91f9, 0xe4a5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe4a4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4a7, 0xfffd, 0xfffd,
- 0xfffd, 0x9190, 0x8c74, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8960,
- 0xe4a6, 0xfffd, 0x8d72, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9191, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe4b8, 0xfffd, 0xe4b9, 0xfffd, 0x89d7,
- 0xfffd, 0xfffd, 0xfffd, 0x89ac, 0xe4b6, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4ac, 0xfffd, 0xe4b4,
- 0xfffd, 0xe4bb, 0xe4b5, 0xfffd, 0xfffd, 0xfffd, 0xe4b3, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe496, 0xfffd, 0xfffd, 0xe4b1, 0xfffd,
- 0xfffd, 0xfffd, 0xe4ad, 0xfffd, 0xfffd, 0xfffd, 0x8ace, 0xe4af,
- 0xe4ba, 0xfffd, 0xe4b0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe4bc, 0xfffd, 0xe4ae, 0x949c, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9789, 0xfffd, 0xfffd, 0xfffd, 0xe4b7, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4cd, 0xfffd, 0xfffd,
- 0xfffd, 0xe4c5, 0xfffd, 0xfffd, 0xfffd, 0x909b, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8b65, 0xfffd, 0x8bdb, 0xfffd, 0xe4c0, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x89d9, 0xfffd, 0xfffd, 0x8fd2, 0xfffd,
- 0xe4c3, 0xfffd, 0xfffd, 0xfffd, 0x8dd8, 0xfffd, 0xfffd, 0x9370,
- 0xe4c8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x95ec, 0xfffd, 0xe4bf, 0xfffd, 0xfffd, 0xfffd, 0x89d8,
- 0x8cd4, 0x9548, 0xe4c9, 0xfffd, 0xe4bd, 0xfffd, 0xfffd, 0xe4c6,
- 0xfffd, 0xfffd, 0xfffd, 0xe4d0, 0xfffd, 0xe4c1, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe4c2, 0x93b8, 0xfffd, 0xfffd, 0xe4c7,
- 0xfffd, 0xfffd, 0xfffd, 0xe4c4, 0x9647, 0xe4ca, 0x88de, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe4be, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe4cc, 0xfffd, 0xe4cb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x948b, 0xe4d2, 0xfffd, 0xe4dd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8a9e, 0xfffd, 0xfffd, 0xfffd, 0xe4e0, 0xfffd, 0xfffd,
- 0xe4ce, 0xfffd, 0xfffd, 0xfffd, 0xe4d3, 0x978e, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4dc, 0xfffd,
- 0xfffd, 0x9774, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x97a8, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9298,
- 0xfffd, 0xfffd, 0xfffd, 0x8a8b, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x9592, 0xe4e2, 0x939f, 0xfffd, 0xfffd, 0x88af, 0xfffd,
- 0xfffd, 0xe4db, 0xfffd, 0xe4d7, 0x9192, 0xe4d1, 0xe4d9, 0xe4de,
- 0xfffd, 0x944b, 0xfffd, 0xfffd, 0xfffd, 0x88a8, 0xfffd, 0xe4d6,
- 0xfffd, 0xe4df, 0x9598, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe4da, 0xfffd, 0xe4d5, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8fd3, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8f4e, 0xfffd, 0xfffd, 0xfffd, 0x8eaa, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x96d6, 0xfffd, 0xfffd, 0x9566, 0xfffd, 0xfffd, 0xe4e5,
- 0xfffd, 0xe4ee, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4d8, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8a97, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8ff6, 0xe4e3, 0xfffd, 0xe4e8, 0x9193, 0xfffd, 0xfffd, 0xe4e4,
- 0xfffd, 0xe4eb, 0xfffd, 0xfffd, 0x927e, 0xfffd, 0xe4ec, 0xfffd,
- 0xfffd, 0x9775, 0xe4e1, 0x8a57, 0xfffd, 0xe4e7, 0xfffd, 0xfffd,
- 0xe4ea, 0x96aa, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4ed, 0xfffd,
- 0xfffd, 0xe4e6, 0xe4e9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9648, 0xfffd, 0x9840, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4f1, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4f8, 0xfffd, 0xfffd, 0xe4f0,
- 0x8ec1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4cf, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x95cc, 0xfffd, 0x96a0, 0xe4f7, 0xe4f6, 0xfffd, 0xe4f2,
- 0xe4f3, 0xfffd, 0x8955, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4f5,
- 0xfffd, 0xe4ef, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x92d3, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe4f4, 0x88fc, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91a0, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95c1, 0xfffd, 0xfffd,
- 0xe4f9, 0xe540, 0xfffd, 0x94d7, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe4fc, 0x8fd4, 0x8ec7, 0xe542, 0xfffd, 0xfffd, 0x8bbc, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe543, 0xfffd, 0x9599,
- 0xe4fb, 0xfffd, 0xe4d4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe4fa, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x986e, 0x93a0, 0x9593, 0xfffd, 0xfffd, 0xe54a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe550,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe551, 0xfffd,
- 0xe544, 0xfffd, 0xfffd, 0xfffd, 0x9496, 0xfffd, 0xfffd, 0xe54e,
- 0xe546, 0xfffd, 0xe548, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe552, 0xe547, 0xfffd, 0xfffd, 0xe54b, 0xfffd, 0xfffd, 0x8992,
- 0xfffd, 0x93e3, 0xfffd, 0xe54c, 0xe54f, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe545, 0xfffd, 0x9145, 0xfffd,
- 0xe549, 0x8e46, 0x9064, 0x8c4f, 0x96f2, 0xfffd, 0x96f7, 0x8f92,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe556, 0xe554, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x986d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe553, 0xfffd, 0xfffd, 0xfffd, 0x9795, 0xfffd, 0xe555,
- 0xe557, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe558, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe55b, 0xe559, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x93a1, 0xe55a, 0xfffd, 0xfffd,
- 0xfffd, 0x94cb, 0xe54d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f93,
- 0xfffd, 0xe55c, 0xe561, 0x9194, 0xfffd, 0xfffd, 0xe560, 0xfffd,
- 0xfffd, 0xfffd, 0xe541, 0xfffd, 0xfffd, 0xfffd, 0xe562, 0x9168,
- 0xfffd, 0xfffd, 0xe55d, 0xe55f, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe55e, 0xfffd, 0xfffd, 0x9f50, 0x9f41,
- 0xfffd, 0xfffd, 0xe564, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe563, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9796, 0xfffd, 0xe1ba,
- 0xe565, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe566,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe567, 0x8cd5, 0xfffd,
- 0x8b73, 0xfffd, 0xfffd, 0xfffd, 0xe569, 0x997c, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8b95, 0xfffd, 0x97b8, 0xfffd, 0x8bf1, 0xe56a,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe56b,
- 0xfffd, 0xfffd, 0xfffd, 0x928e, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe56c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x93f8, 0xfffd, 0x88b8, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x89e1, 0xe571, 0xe572, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe56d, 0xfffd, 0x8e5c, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe56e, 0x9461, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe56f, 0xe570, 0xe57a, 0xfffd, 0xfffd, 0xfffd, 0xe574,
- 0xe577, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe573, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe575, 0xfffd, 0xe576, 0x8ed6,
- 0xfffd, 0xe578, 0xfffd, 0x9260, 0xfffd, 0x8c75, 0x8a61, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe57b, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8a5e, 0xfffd, 0xe581, 0xfffd, 0xfffd, 0xe57c, 0xe580,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x94b8, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe57d, 0xfffd, 0xfffd, 0xe57e, 0x9567, 0x94d8, 0xe582,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x91fb, 0xe58c, 0xfffd, 0xe588, 0xfffd, 0xfffd, 0x89e9, 0xfffd,
- 0xe586, 0xfffd, 0x9649, 0xe587, 0xfffd, 0xfffd, 0xe584, 0xfffd,
- 0xe585, 0xe58a, 0xe58d, 0xfffd, 0xfffd, 0xe58b, 0xfffd, 0xfffd,
- 0xfffd, 0xe589, 0xe583, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9277, 0xfffd, 0xe594, 0xfffd, 0x96a8, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe592, 0xfffd, 0xfffd,
- 0xfffd, 0xe593, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe58e, 0xfffd, 0xfffd, 0xe590,
- 0xfffd, 0xfffd, 0xfffd, 0xe591, 0xfffd, 0xfffd, 0xfffd, 0xe58f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x90e4, 0xfffd, 0x9858, 0xe598, 0xfffd, 0xe599, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe59f, 0xfffd, 0x9049, 0xfffd, 0xe59b,
- 0xfffd, 0xe59e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe596,
- 0xe595, 0xfffd, 0xfffd, 0xe5a0, 0xfffd, 0xfffd, 0x89da, 0xfffd,
- 0xe59c, 0xfffd, 0xe5a1, 0xfffd, 0xfffd, 0xfffd, 0xe59d, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe59a, 0xfffd, 0x92b1, 0xfffd,
- 0xe597, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9488,
- 0xfffd, 0xfffd, 0xe5a5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x975a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5a4,
- 0xfffd, 0xfffd, 0xe5a3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe5ac, 0xfffd, 0xfffd, 0xfffd, 0xe5a6,
- 0xfffd, 0xfffd, 0xfffd, 0xe5ae, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9786, 0xe5b1, 0xfffd, 0xe5a8, 0xfffd, 0xfffd,
- 0xe5a9, 0xfffd, 0xfffd, 0xfffd, 0xe5ad, 0xfffd, 0xe5b0, 0xe5af,
- 0xfffd, 0xfffd, 0xfffd, 0xe5a7, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe5aa, 0xfffd, 0xe5bb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe5b4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5b2,
- 0xfffd, 0xfffd, 0xe5b3, 0xfffd, 0xfffd, 0xfffd, 0xe5b8, 0xe5b9,
- 0xfffd, 0x8a49, 0xfffd, 0x8b61, 0xfffd, 0xfffd, 0xe5b7, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5a2, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5b6, 0xe5ba, 0xe5b5,
- 0xfffd, 0xe5bc, 0xfffd, 0xfffd, 0xfffd, 0xe5be, 0xe5bd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe5c0, 0xe5bf, 0xe579, 0xfffd, 0xfffd, 0xfffd, 0xe5c4,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe5c1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5c2, 0xfffd,
- 0xfffd, 0xe5c3, 0xfffd, 0xe5c5, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8c8c, 0xfffd, 0xe5c7, 0xfffd, 0xe5c6, 0xfffd, 0x8f4f, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8d73, 0x9fa5, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe5c8, 0x8f70, 0xfffd, 0xfffd, 0xfffd, 0x8a58,
- 0xfffd, 0xe5c9, 0xfffd, 0x8971, 0xfffd, 0x8fd5, 0xe5ca, 0xfffd,
- 0xfffd, 0x8d74, 0xe5cb, 0x88df, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x955c, 0xfffd, 0xfffd, 0xe5cc, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x908a, 0xfffd, 0xe5d3, 0xfffd, 0xfffd, 0xe5d0, 0xfffd, 0x928f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5d1, 0xe5ce, 0x8bdc,
- 0xfffd, 0xe5cd, 0xe5d4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8c55, 0xfffd, 0xfffd, 0x91dc, 0xfffd, 0xe5da, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe5d6, 0xfffd, 0xfffd, 0xfffd, 0x91b3, 0xe5d5,
- 0xfffd, 0xe5d8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5cf, 0xfffd,
- 0xfffd, 0xfffd, 0xe5d9, 0xfffd, 0xe5db, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x94ed, 0xfffd, 0xfffd, 0xe5d7, 0xfffd,
- 0xe5dc, 0xe5de, 0xfffd, 0xfffd, 0x8cd1, 0xe5d2, 0xfffd, 0x88bf,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5dd,
- 0xfffd, 0x8dd9, 0x97f4, 0xe5df, 0xe5e0, 0x9195, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x97a0,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5e1, 0x9754, 0xfffd, 0xfffd,
- 0xe5e2, 0xe5e3, 0xfffd, 0xfffd, 0x95e2, 0xe5e4, 0xfffd, 0x8dbe,
- 0xfffd, 0x97a1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe5e9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe5ea, 0x8fd6, 0xe5e8, 0xfffd, 0xfffd, 0xfffd,
- 0x9787, 0xe5e5, 0xfffd, 0xfffd, 0xe5e7, 0x90bb, 0x909e, 0xfffd,
- 0xfffd, 0xfffd, 0xe5e6, 0xfffd, 0xe5eb, 0xfffd, 0xfffd, 0x95a1,
- 0xfffd, 0xfffd, 0xe5ed, 0xfffd, 0xe5ec, 0xfffd, 0xfffd, 0xfffd,
- 0x8a8c, 0xfffd, 0x964a, 0xe5ee, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5fa, 0xe5f0, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5f1, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe5f2, 0xe5f3, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5f7, 0xfffd,
- 0xe5f8, 0xfffd, 0xfffd, 0xe5f6, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe5f4, 0xfffd, 0xe5ef, 0xe5f5, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5f9, 0xe8b5, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x89a6, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe5fc, 0x8bdd,
- 0xe5fb, 0xfffd, 0xfffd, 0xfffd, 0xe641, 0xfffd, 0xe640, 0xfffd,
- 0xfffd, 0xfffd, 0xe643, 0xfffd, 0xfffd, 0xe642, 0xfffd, 0xe644,
- 0xfffd, 0xfffd, 0x8f50, 0xfffd, 0xe645, 0xfffd, 0xfffd, 0xe646,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe647, 0x90bc,
- 0xfffd, 0x9776, 0xfffd, 0xe648, 0xfffd, 0xfffd, 0x95a2, 0x9465,
- 0xe649, 0xfffd, 0xe64a, 0x8ca9, 0xfffd, 0xfffd, 0xfffd, 0x8b4b,
- 0xfffd, 0xfffd, 0xfffd, 0xe64b, 0xfffd, 0xfffd, 0x8e8b, 0x9460,
- 0xe64c, 0xfffd, 0x8a6f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe64d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe64f, 0x9797,
- 0xfffd, 0xe64e, 0x9065, 0xfffd, 0xe650, 0xfffd, 0xfffd, 0xe651,
- 0xfffd, 0xfffd, 0xe652, 0x8acf, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe653, 0xfffd, 0xfffd, 0xe654, 0xfffd, 0xe655,
- 0xe656, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8a70, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe657, 0xfffd, 0xe658, 0xe659, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x89f0, 0xfffd, 0xfffd, 0x9047, 0xe65a,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe65b, 0xfffd, 0xfffd, 0xfffd,
- 0xe65c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8cbe, 0xfffd, 0x92f9, 0xe65d, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8c76, 0xfffd, 0x9075, 0xfffd, 0xe660, 0xfffd, 0x93a2, 0xfffd,
- 0xe65f, 0xfffd, 0xfffd, 0x8c50, 0xfffd, 0xfffd, 0xe65e, 0x91f5,
- 0x8b4c, 0xfffd, 0xfffd, 0xe661, 0xfffd, 0xe662, 0xfffd, 0x8fd7,
- 0xfffd, 0xfffd, 0xfffd, 0x8c8d, 0xfffd, 0xe663, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x964b, 0xfffd, 0xfffd, 0x90dd, 0xfffd, 0xfffd,
- 0xfffd, 0x8b96, 0xfffd, 0x96f3, 0x9169, 0xfffd, 0xe664, 0xfffd,
- 0xfffd, 0xfffd, 0x9066, 0x9290, 0x8fd8, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe665, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe668, 0xfffd,
- 0xe669, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8dbc, 0x91c0, 0xe667, 0xfffd, 0x8fd9, 0x955d, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe666, 0xfffd, 0xfffd, 0x8e8c, 0xfffd,
- 0x8972, 0xfffd, 0xe66d, 0x8c77, 0xfffd, 0xfffd, 0x8e8e, 0xfffd,
- 0xfffd, 0x8e8d, 0xfffd, 0x986c, 0xe66c, 0xe66b, 0x9146, 0xfffd,
- 0x8b6c, 0x9862, 0x8a59, 0x8fda, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe66a, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe66f, 0xfffd, 0xe670, 0xe66e, 0xfffd, 0x8cd6,
- 0xfffd, 0x975f, 0xfffd, 0xfffd, 0x8e8f, 0x9446, 0xfffd, 0xfffd,
- 0xfffd, 0xe673, 0xfffd, 0x90be, 0xfffd, 0x9261, 0xfffd, 0xfffd,
- 0x9755, 0xfffd, 0xe676, 0xfffd, 0xfffd, 0xfffd, 0x8cea, 0xfffd,
- 0x90bd, 0xe672, 0xfffd, 0xe677, 0x8ceb, 0xe674, 0xe675, 0xfffd,
- 0xe671, 0xfffd, 0xfffd, 0xfffd, 0x90e0, 0x93c7, 0xfffd, 0xfffd,
- 0x924e, 0xfffd, 0x89db, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x94ee, 0xfffd, 0xfffd, 0x8b62, 0xfffd, 0xfffd, 0x92b2,
- 0xfffd, 0xfffd, 0xe67a, 0xfffd, 0xe678, 0xfffd, 0xfffd, 0x926b,
- 0xfffd, 0xfffd, 0xfffd, 0x90bf, 0x8ad0, 0xe679, 0xfffd, 0x907a,
- 0xfffd, 0xfffd, 0x97c8, 0xfffd, 0xfffd, 0xfffd, 0x985f, 0xfffd,
- 0xfffd, 0xfffd, 0xe67b, 0xe687, 0x92b3, 0xfffd, 0xe686, 0xfffd,
- 0xe683, 0xe68b, 0xe684, 0xfffd, 0xe680, 0xfffd, 0x92fa, 0xe67e,
- 0xfffd, 0xfffd, 0xfffd, 0xe67c, 0xfffd, 0x9740, 0x8e90, 0xfffd,
- 0xfffd, 0xe681, 0xfffd, 0xe67d, 0xfffd, 0xfffd, 0xfffd, 0xe685,
- 0x8f94, 0xfffd, 0x8cbf, 0xfffd, 0xfffd, 0xfffd, 0x91f8, 0xfffd,
- 0x9664, 0x8979, 0x88e0, 0xfffd, 0x93a3, 0xfffd, 0xfffd, 0xe689,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe688, 0xfffd, 0x93e4, 0xfffd,
- 0xe68d, 0xfffd, 0xfffd, 0xfffd, 0xe682, 0xfffd, 0xe68c, 0xe68e,
- 0xfffd, 0x8caa, 0xe68a, 0x8d75, 0xfffd, 0x8ed3, 0xfffd, 0xfffd,
- 0xe68f, 0x9777, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe692, 0xfffd,
- 0xe695, 0xfffd, 0xfffd, 0xe693, 0x9554, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe690, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8bde, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe694, 0xfffd,
- 0xfffd, 0xe696, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe69a, 0xfffd, 0xfffd, 0xe697, 0xfffd, 0xe699, 0xe698,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe69b, 0xfffd,
- 0x8eaf, 0xfffd, 0xe69d, 0xe69c, 0x9588, 0xfffd, 0xfffd, 0xe69f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c78, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe69e, 0xe6a0, 0xfffd, 0xfffd, 0xe6a1,
- 0x8b63, 0xe3bf, 0x8ff7, 0xfffd, 0xe6a2, 0xfffd, 0xfffd, 0x8cec,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe6a3, 0xfffd, 0xfffd,
- 0xe6a4, 0xfffd, 0xfffd, 0x8e5d, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9dcc, 0xfffd, 0xe6a5, 0xfffd, 0xe6a6, 0xfffd,
- 0x8f51, 0xfffd, 0xe6a7, 0xe6a8, 0xfffd, 0xfffd, 0xe6a9, 0xfffd,
- 0xfffd, 0xe6aa, 0xe6ab, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x924a,
- 0xfffd, 0xfffd, 0xe6ac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe6ae,
- 0xfffd, 0xe6ad, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x93a4, 0xfffd,
- 0xe6af, 0xfffd, 0x964c, 0xfffd, 0xe6b0, 0xfffd, 0xe6b1, 0xfffd,
- 0xe6b2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe6b3, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x93d8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8fdb, 0xe6b4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8d8b, 0x98ac, 0xe6b5, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe6b6, 0x955e, 0xe6b7, 0xfffd, 0xe6bf, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe6b8, 0xfffd, 0xfffd, 0xe6ba, 0xfffd, 0xfffd,
- 0xfffd, 0xe6b9, 0xe6bb, 0xfffd, 0x9665, 0xe6bc, 0xe6bd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe6be, 0xfffd, 0xfffd, 0xfffd,
- 0xe6c0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a4c, 0x92e5, 0xfffd,
- 0x9589, 0x8de0, 0x8d76, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x956e,
- 0x89dd, 0x94cc, 0xe6c3, 0x8ad1, 0x90d3, 0xe6c2, 0xe6c7, 0x9299,
- 0x96e1, 0xfffd, 0xe6c5, 0xe6c6, 0x8b4d, 0xfffd, 0xe6c8, 0x9483,
- 0x91dd, 0xfffd, 0xfffd, 0x94ef, 0x935c, 0xe6c4, 0xfffd, 0x9666,
- 0x89ea, 0xe6ca, 0x9847, 0x92c0, 0x9864, 0xfffd, 0xfffd, 0x8e91,
- 0xe6c9, 0xfffd, 0x91af, 0xfffd, 0xfffd, 0xe6da, 0x9147, 0xfffd,
- 0xfffd, 0x93f6, 0xfffd, 0x956f, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe6cd, 0x8e5e, 0x8e92, 0xfffd, 0x8fdc, 0xfffd,
- 0x9485, 0xfffd, 0x8cab, 0xe6cc, 0xe6cb, 0xfffd, 0x958a, 0xfffd,
- 0xfffd, 0xfffd, 0x8ebf, 0xfffd, 0xfffd, 0x9371, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe6cf, 0xe6d0, 0x8d77, 0xe6ce, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe6d1, 0xe6d2, 0xfffd, 0xe6d4,
- 0x91a1, 0xfffd, 0xe6d3, 0x8ae4, 0xfffd, 0xe6d6, 0xfffd, 0xe6d5,
- 0xe6d7, 0xfffd, 0xfffd, 0xe6d9, 0xe6db, 0xfffd, 0xe6dc, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x90d4, 0xfffd, 0x8ecd, 0xe6dd,
- 0xfffd, 0xfffd, 0xfffd, 0x8a71, 0xfffd, 0xe6de, 0xfffd, 0xfffd,
- 0x9196, 0xe6df, 0xfffd, 0xe6e0, 0x958b, 0xfffd, 0xfffd, 0x8b4e,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe6e1, 0xfffd, 0xfffd, 0xfffd, 0x92b4, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x897a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe6e2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8eef, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9096, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x91ab, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe6e5, 0xfffd, 0xfffd, 0xfffd, 0xe6e4, 0xfffd,
- 0xfffd, 0xfffd, 0xe6e3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe6eb, 0xe6e9, 0xfffd, 0xfffd, 0xe6e6,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe6e8, 0xfffd,
- 0xfffd, 0xfffd, 0xe6e7, 0xe6ea, 0xfffd, 0x8b97, 0xfffd, 0xe6ee,
- 0xfffd, 0x90d5, 0xfffd, 0xe6ef, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8cd7, 0xfffd, 0xe6ec, 0xe6ed, 0xfffd, 0xfffd, 0xfffd, 0x9848,
- 0xfffd, 0xfffd, 0xfffd, 0x92b5, 0xfffd, 0x9148, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe6f0, 0xfffd, 0xfffd, 0xe6f3,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe6f1, 0xe6f2, 0x9778, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x93a5,
- 0xe6f6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe6f4, 0xe6f5, 0xe6f7,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe748, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe6fa, 0xfffd, 0xfffd, 0xfffd, 0xe6fb, 0xe6f9, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe6f8, 0xfffd, 0x92fb, 0xfffd, 0xfffd, 0xe740,
- 0xe744, 0xe741, 0xe6fc, 0xfffd, 0xe742, 0xfffd, 0xfffd, 0xfffd,
- 0xe743, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe74a, 0xfffd, 0xfffd,
- 0xfffd, 0xe745, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x90d6,
- 0xe747, 0xfffd, 0xfffd, 0xe749, 0xe746, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe74c, 0xfffd, 0x8f52, 0xfffd, 0xe74b, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe74d, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe74e, 0xfffd, 0xfffd, 0xe751, 0xe750, 0xfffd, 0xe74f,
- 0xfffd, 0xfffd, 0xe753, 0xe752, 0xfffd, 0x96f4, 0xfffd, 0xfffd,
- 0xfffd, 0xe755, 0xfffd, 0xe754, 0xe756, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe757, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe759, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe758, 0x9067, 0xe75a, 0xfffd, 0xfffd, 0x8beb,
- 0xe75b, 0xe75d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe75e, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe75f, 0xe75c, 0xfffd,
- 0xe760, 0xfffd, 0x8ed4, 0xe761, 0x8b4f, 0x8c52, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8cac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe762, 0xfffd, 0xfffd, 0xfffd, 0x93ee,
- 0xfffd, 0xfffd, 0x935d, 0xe763, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe766, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8eb2, 0xfffd, 0xfffd, 0xe765, 0xe764, 0x8c79, 0xe767, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8a72, 0xfffd, 0xe769, 0xfffd, 0xfffd,
- 0xfffd, 0x8dda, 0xe768, 0xfffd, 0xe771, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe76b, 0xe76d, 0x95e3, 0xe76a, 0xfffd, 0xfffd,
- 0xfffd, 0xe76c, 0xfffd, 0xe770, 0xe76e, 0x8b50, 0xfffd, 0xe76f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe772, 0xfffd,
- 0xfffd, 0x9479, 0x97d6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f53,
- 0xfffd, 0xfffd, 0xfffd, 0xe773, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9741, 0xe775, 0xfffd, 0xe774, 0xfffd, 0xfffd, 0xe778, 0x9760,
- 0xfffd, 0xfffd, 0xe777, 0xfffd, 0x8a8d, 0xe776, 0xe77b, 0xfffd,
- 0xfffd, 0xe77a, 0xfffd, 0xfffd, 0xe779, 0x9351, 0xe77c, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe77d,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe77e, 0xfffd, 0xfffd, 0x8d8c,
- 0xfffd, 0x8c44, 0xe780, 0xe781, 0xe782, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9068, 0xe783, 0xfffd, 0x8eab, 0xe784,
- 0xfffd, 0xfffd, 0xfffd, 0xe785, 0xfffd, 0xfffd, 0xfffd, 0x999f,
- 0x999e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe786, 0xe390, 0xe787,
- 0x9243, 0x904a, 0x945f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe788,
- 0xfffd, 0xfffd, 0x95d3, 0x92d2, 0x8d9e, 0xfffd, 0xfffd, 0x9248,
- 0xfffd, 0xfffd, 0x8949, 0xfffd, 0x9698, 0x9076, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c7d, 0xfffd,
- 0xfffd, 0x8bdf, 0xfffd, 0xfffd, 0x95d4, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe789, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe78b, 0xfffd, 0xfffd, 0xe78a, 0x89de, 0xfffd,
- 0xfffd, 0x93f4, 0xe78c, 0x9497, 0xfffd, 0x9352, 0xfffd, 0xe78d,
- 0x8f71, 0xfffd, 0xfffd, 0xfffd, 0xe78f, 0xfffd, 0xfffd, 0x96c0,
- 0xe79e, 0xe791, 0xe792, 0xfffd, 0xfffd, 0x92c7, 0xfffd, 0xfffd,
- 0x91de, 0x9197, 0xfffd, 0x93a6, 0xfffd, 0xe790, 0x8b74, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe799, 0xfffd, 0xe796, 0xe7a3, 0x93a7,
- 0x9280, 0xe793, 0xfffd, 0x92fc, 0x9372, 0xe794, 0xe798, 0x9080,
- 0xfffd, 0x9487, 0x92ca, 0xfffd, 0xfffd, 0x90c0, 0xe797, 0x91ac,
- 0x91a2, 0xe795, 0x88a7, 0x9841, 0xfffd, 0xfffd, 0xfffd, 0xe79a,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91df, 0xfffd,
- 0xfffd, 0x8f54, 0x9069, 0xfffd, 0xfffd, 0xe79c, 0xe79b, 0xfffd,
- 0x88ed, 0xe79d, 0xfffd, 0xfffd, 0x954e, 0xfffd, 0xe7a5, 0xfffd,
- 0xfffd, 0x93d9, 0x908b, 0xfffd, 0xfffd, 0x9278, 0xfffd, 0x8bf6,
- 0xfffd, 0xe7a4, 0x9756, 0x895e, 0xfffd, 0x95d5, 0x89df, 0xe79f,
- 0xe7a0, 0xe7a1, 0xe7a2, 0x93b9, 0x9242, 0x88e1, 0xe7a6, 0xfffd,
- 0xe7a7, 0xeaa1, 0xfffd, 0xfffd, 0x91bb, 0xfffd, 0xe7a8, 0xfffd,
- 0x8993, 0x916b, 0xfffd, 0x8cad, 0xfffd, 0x9779, 0xfffd, 0xfffd,
- 0xe7a9, 0x934b, 0xfffd, 0xfffd, 0xfffd, 0x9198, 0x8ed5, 0xe7aa,
- 0xfffd, 0xfffd, 0xe7ad, 0xfffd, 0xfffd, 0x8f85, 0xe7ab, 0x914a,
- 0x9149, 0xfffd, 0x88e2, 0xfffd, 0x97c9, 0xe7af, 0xfffd, 0x94f0,
- 0xe7b1, 0xe7b0, 0xe7ae, 0xe284, 0x8ad2, 0xfffd, 0xfffd, 0xe78e,
- 0xfffd, 0xe7b3, 0xe7b2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7b4,
- 0xfffd, 0x9757, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x93df, 0xfffd, 0xfffd, 0x964d, 0xfffd,
- 0xe7b5, 0xfffd, 0x8ed7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7b6,
- 0xfffd, 0xe7b7, 0xfffd, 0xfffd, 0xfffd, 0xe7b8, 0xfffd, 0xfffd,
- 0x9340, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x88e8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x8d78, 0xfffd, 0xfffd, 0xfffd, 0x9859, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe7bc, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8c53, 0xe7b9, 0xfffd, 0xe7ba, 0xfffd, 0xfffd, 0xfffd,
- 0x9594, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a73, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9758, 0xfffd, 0x8bbd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9373, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe7bd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe7be, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe7bf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9341, 0xfffd, 0xfffd,
- 0xe7c1, 0xfffd, 0xe7c0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x93d1, 0xe7c2, 0x8f55, 0x8ede, 0x947a, 0x9291, 0xfffd,
- 0xfffd, 0xfffd, 0x8ef0, 0xfffd, 0x908c, 0xfffd, 0xe7c3, 0xfffd,
- 0xe7c4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x907c, 0xe7c5, 0xfffd, 0xe7c6, 0xfffd, 0xfffd,
- 0xfffd, 0xe7c7, 0x978f, 0xfffd, 0x8f56, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe7c9, 0xe7c8, 0xfffd, 0x8d79, 0xfffd, 0x8d93,
- 0x8e5f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe7cc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f86,
- 0xfffd, 0xe7cb, 0xfffd, 0xe7ca, 0xfffd, 0x91e7, 0xfffd, 0xfffd,
- 0x8ced, 0xfffd, 0x90c1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x94ae,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f58, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe7cd, 0xfffd, 0x8fdd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe7d0, 0xe7ce, 0xfffd, 0xfffd, 0xfffd, 0xe7cf,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7d2, 0xe7d1, 0xfffd, 0xfffd,
- 0x8ff8, 0xfffd, 0xe7d3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe7d4, 0xe7d5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x94ce, 0x8dd1,
- 0x8edf, 0xe7d6, 0xfffd, 0xe7d7, 0x97a2, 0x8f64, 0x96ec, 0x97ca,
- 0xe7d8, 0x8be0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7d9, 0xfffd,
- 0x9342, 0xfffd, 0xfffd, 0xe7dc, 0x8a98, 0x906a, 0xfffd, 0xe7da,
- 0xfffd, 0xe7db, 0xfffd, 0x92de, 0xfffd, 0xfffd, 0x9674, 0x8bfa,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7de, 0xe7df, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7dd, 0xfffd, 0xfffd, 0xe7e1,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x93dd, 0x8a62, 0xfffd,
- 0xfffd, 0xe7e5, 0xfffd, 0xfffd, 0xe7e2, 0xe7e4, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7e0, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe86e, 0xfffd, 0xfffd, 0xe7e3, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x97e9, 0xfffd, 0xfffd, 0x8cd8,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7ed,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9353, 0xe7e8, 0xfffd, 0xfffd,
- 0xe7eb, 0xe7e9, 0xfffd, 0xe7ee, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe7ef, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7e7,
- 0xfffd, 0xfffd, 0xe7f4, 0x8994, 0xfffd, 0xfffd, 0xe7e6, 0xfffd,
- 0xfffd, 0xfffd, 0x94ab, 0xfffd, 0xe7ea, 0xfffd, 0x8fde, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8d7a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9667, 0xfffd,
- 0x8be2, 0xfffd, 0xfffd, 0x8f65, 0xfffd, 0x93ba, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x914c, 0xfffd, 0xe7f2, 0xfffd, 0xe7ec, 0xe7f1, 0xfffd,
- 0x96c1, 0xfffd, 0x92b6, 0xe7f3, 0xe7f0, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x914b, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7f7,
- 0xfffd, 0xe7f6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7f5,
- 0xfffd, 0xfffd, 0x964e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f9b, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe7f8, 0x95dd, 0xfffd, 0xfffd, 0x8973, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9565, 0x9292, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8b98, 0xfffd, 0xe7fa, 0xfffd, 0x8d7c, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8e4b, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7f9,
- 0x908d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x908e, 0xe840, 0xe842, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8ff9, 0xfffd, 0xe841, 0xe843, 0xfffd, 0xfffd, 0x8bd1, 0xfffd,
- 0x9564, 0xfffd, 0xfffd, 0x8ee0, 0x9842, 0xfffd, 0xe7fc, 0x8df6,
- 0xfffd, 0xfffd, 0x985e, 0xfffd, 0xfffd, 0xe845, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe844, 0xe846, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe7fb, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x93e7, 0xfffd, 0x9374, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x92d5, 0xfffd, 0xe84b, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9262, 0xe847, 0xfffd, 0xfffd, 0xfffd,
- 0xe848, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c4c, 0xfffd, 0xe84a, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8cae, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe849, 0xfffd, 0x8fdf, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a99, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe84f, 0xfffd, 0x8dbd, 0x9199,
- 0xfffd, 0xfffd, 0x92c8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a5a,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe84d, 0xe84e, 0x92c1, 0xfffd,
- 0xe84c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe850, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe856, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe859, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe858, 0x934c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe851, 0xe852,
- 0xe855, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe857, 0xfffd, 0xfffd,
- 0xfffd, 0x8bbe, 0xfffd, 0xfffd, 0xe85a, 0xe854, 0xfffd, 0xfffd,
- 0xe853, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe85e, 0xfffd, 0xfffd, 0xfffd, 0xe85f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe860, 0xfffd, 0xfffd, 0xe85d, 0xe85c, 0xfffd, 0xfffd, 0xfffd,
- 0x8fe0, 0x93a8, 0xe85b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe864, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe862, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe863, 0xe861, 0xfffd,
- 0x91f6, 0xfffd, 0xe865, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe866, 0xfffd, 0xfffd, 0xe868, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8ad3, 0xe867, 0x96f8, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe873, 0xe869, 0xfffd, 0xfffd, 0xe86c, 0xfffd,
- 0xe86a, 0xfffd, 0xe86b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xe86d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe86f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe870, 0xfffd, 0xe871,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe874, 0xe872, 0xe875, 0xe877,
- 0xfffd, 0xe876, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x92b7,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x96e5, 0xfffd, 0xe878, 0x914d, 0xfffd, 0xfffd, 0xfffd, 0xe879,
- 0xfffd, 0x95c2, 0xe87a, 0x8a4a, 0xfffd, 0xfffd, 0xfffd, 0x895b,
- 0xfffd, 0x8ad5, 0xfffd, 0x8ad4, 0xe87b, 0xfffd, 0xe87c, 0xfffd,
- 0xe87d, 0xe87e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe880, 0xfffd, 0x8ad6, 0x8a74, 0x8d7d, 0x94b4, 0xfffd, 0xe882,
- 0xe881, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe883, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x897b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe886, 0xfffd, 0xe885, 0xe884, 0xfffd, 0xe887, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe88a, 0xfffd, 0xfffd, 0xfffd, 0x88c5,
- 0xfffd, 0xfffd, 0xe888, 0xfffd, 0xe88c, 0xe88b, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe88e, 0xe88d, 0xe88f, 0xfffd,
- 0x93ac, 0xfffd, 0xfffd, 0xfffd, 0xe890, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe891, 0xe893, 0xfffd, 0xfffd, 0xe892, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x958c, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe894, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe895, 0xfffd, 0x8de3, 0xfffd, 0xfffd, 0xfffd, 0xe896, 0xe897,
- 0xfffd, 0xfffd, 0x9668, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x916a, 0xfffd, 0xfffd, 0xfffd, 0x88a2,
- 0x91c9, 0xfffd, 0xe898, 0xfffd, 0x958d, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe89b, 0xe899, 0x8d7e, 0xfffd, 0xe89a,
- 0x8cc0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x95c3, 0xe89d, 0xe89f, 0xe89e, 0xe8a0,
- 0xfffd, 0xfffd, 0x8940, 0x9077, 0x8f9c, 0x8ad7, 0xe8a1, 0xfffd,
- 0xfffd, 0xfffd, 0x9486, 0xfffd, 0xe8a3, 0xfffd, 0xfffd, 0xfffd,
- 0x8941, 0xfffd, 0xe8a2, 0x92c2, 0xfffd, 0x97cb, 0x93a9, 0xe89c,
- 0x97a4, 0xfffd, 0x8caf, 0xfffd, 0xfffd, 0x977a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8bf7, 0x97b2, 0xfffd,
- 0x8c47, 0xfffd, 0x91e0, 0xe440, 0xfffd, 0xe8a4, 0x8a4b, 0x908f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a75, 0xe8a6, 0xfffd, 0xe8a7,
- 0xe8a5, 0x8c84, 0xfffd, 0x8ddb, 0x8fe1, 0xfffd, 0xfffd, 0xfffd,
- 0x8942, 0xfffd, 0xfffd, 0x97d7, 0xfffd, 0xfffd, 0xfffd, 0xe8a9,
- 0xe7ac, 0xfffd, 0xe8a8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe8ac, 0xe8aa, 0xe8ab, 0xfffd, 0xe8ad, 0xfffd, 0xe8ae, 0x97ea,
- 0xe8af, 0xe8b0, 0xfffd, 0x90c7, 0x94b9, 0xfffd, 0xfffd, 0xfffd,
- 0x909d, 0x8ae5, 0xfffd, 0xfffd, 0x9759, 0x89eb, 0x8f57, 0x8cd9,
- 0xfffd, 0xe8b3, 0xfffd, 0xe8b2, 0x8e93, 0xe8b4, 0xe8b1, 0xfffd,
- 0xfffd, 0x8e47, 0xfffd, 0xfffd, 0xfffd, 0xe8b8, 0xe5ab, 0xfffd,
- 0xfffd, 0x99d4, 0xfffd, 0x9097, 0xe8b6, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x97a3, 0x93ef, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x894a, 0xfffd, 0x90e1, 0x8eb4, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x95b5, 0xfffd, 0x895f, 0xfffd, 0xfffd, 0xfffd, 0x97eb, 0x978b,
- 0xfffd, 0xe8b9, 0xfffd, 0x9364, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8ef9, 0xfffd, 0xfffd, 0xfffd, 0xe8ba, 0xfffd, 0xe8bb, 0x906b,
- 0xe8bc, 0xfffd, 0x97ec, 0xfffd, 0xfffd, 0xe8b7, 0xe8be, 0xe8c0,
- 0xfffd, 0xe8bf, 0xfffd, 0xe8bd, 0xfffd, 0xfffd, 0xe8c1, 0xfffd,
- 0xfffd, 0xe8c2, 0xfffd, 0xfffd, 0x919a, 0xfffd, 0x89e0, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe8c3, 0xfffd, 0xfffd, 0x96b6,
- 0xfffd, 0xfffd, 0xe8c4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe8c5, 0xfffd, 0x9849, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9e50, 0xe8c6, 0xfffd, 0xfffd, 0xfffd, 0xe8c7, 0xe8c8, 0xfffd,
- 0xfffd, 0xfffd, 0xe8cc, 0xfffd, 0xe8c9, 0xfffd, 0xe8ca, 0xfffd,
- 0xe8cb, 0xe8cd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x90c2, 0xfffd, 0xfffd, 0xfffd, 0x96f5, 0xfffd,
- 0xfffd, 0x90c3, 0xfffd, 0xfffd, 0xe8ce, 0xfffd, 0x94f1, 0xfffd,
- 0xe8cf, 0xea72, 0x96ca, 0xfffd, 0xe8d0, 0xfffd, 0xe8d1, 0xfffd,
- 0xe8d2, 0x8a76, 0xfffd, 0xe8d4, 0xfffd, 0x9078, 0xfffd, 0xfffd,
- 0xfffd, 0xe8d5, 0xfffd, 0xfffd, 0x8c43, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe8d6, 0xe8da, 0xfffd, 0xe8d8, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe8d9, 0xfffd, 0xfffd, 0x8a93, 0xe8d7, 0xe8db, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe8dc, 0xfffd, 0x88c6, 0xfffd, 0xe8dd,
- 0xe8de, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8fe2, 0xfffd, 0xfffd, 0xfffd, 0xe8df, 0xfffd, 0xfffd, 0xfffd,
- 0x8b66, 0xfffd, 0xfffd, 0xe8e2, 0xfffd, 0xfffd, 0xe8e1, 0xfffd,
- 0xe8e0, 0xfffd, 0xfffd, 0xe691, 0xfffd, 0x95da, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe8e3, 0xe8e4, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe8e5, 0xfffd, 0xfffd, 0xe8e6, 0xfffd,
- 0xe8e7, 0xfffd, 0xfffd, 0xe8e8, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8ad8, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe8e9, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe8ea, 0x9442, 0xfffd,
- 0xfffd, 0xfffd, 0xe8ec, 0x89b9, 0xfffd, 0xe8ef, 0xe8ee, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8943, 0xfffd, 0xfffd, 0xfffd, 0x8bbf,
- 0xfffd, 0x95c5, 0x92b8, 0x8da0, 0xfffd, 0x8d80, 0x8f87, 0xfffd,
- 0x907b, 0xfffd, 0xfffd, 0xfffd, 0xe8f1, 0xfffd, 0xfffd, 0xe8f0,
- 0x9761, 0x8ae6, 0x94d0, 0x93da, 0xfffd, 0xfffd, 0xfffd, 0x909c,
- 0x97cc, 0xfffd, 0x8c7a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe8f4, 0xfffd, 0xfffd, 0xe8f3, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x966a, 0x93aa, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x896f, 0xfffd, 0xfffd, 0xe8f5,
- 0xe8f2, 0xfffd, 0xfffd, 0x9570, 0x978a, 0xe8f6, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe8f7, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe8f9, 0x91e8, 0x8a7a, 0x8a7b, 0xe8f8,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ae7, 0x8cb0, 0xfffd, 0xfffd,
- 0x8ae8, 0xfffd, 0xfffd, 0x935e, 0xfffd, 0xfffd, 0x97de, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8cda,
- 0xfffd, 0xfffd, 0xfffd, 0xe8fa, 0xfffd, 0xfffd, 0xfffd, 0xe8fb,
- 0xe8fc, 0xe940, 0xfffd, 0xe942, 0xe941, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9597, 0xfffd, 0xe943, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe944,
- 0xfffd, 0xe945, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe946, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe948, 0xe947, 0xfffd, 0xe949, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x94f2, 0xe3ca, 0xfffd, 0xfffd, 0x9048,
- 0xfffd, 0xfffd, 0x8b51, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe94a, 0xfffd, 0xe94b, 0xfffd, 0x99aa, 0x9f5a, 0x94d1,
- 0xfffd, 0xfffd, 0x88f9, 0xfffd, 0x88b9, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8e94, 0x964f, 0x8ffc, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe94c, 0xfffd, 0x96dd, 0xfffd, 0xfffd,
- 0xfffd, 0xe94d, 0x977b, 0xfffd, 0x8961, 0xfffd, 0xfffd, 0xfffd,
- 0x8e60, 0xfffd, 0xe94e, 0x89ec, 0xe94f, 0xfffd, 0xfffd, 0xfffd,
- 0xe950, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe952, 0xe953, 0xfffd,
- 0xe955, 0xe951, 0xfffd, 0xfffd, 0xe954, 0xfffd, 0xfffd, 0xfffd,
- 0x8ad9, 0xfffd, 0xfffd, 0xfffd, 0xe956, 0xfffd, 0xe957, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe958, 0xe959, 0xfffd,
- 0xfffd, 0xfffd, 0xe95a, 0xfffd, 0xfffd, 0xe95c, 0xfffd, 0xfffd,
- 0xfffd, 0xe95b, 0xfffd, 0xe95e, 0xe961, 0xfffd, 0xfffd, 0xfffd,
- 0xe95d, 0xe95f, 0xe960, 0xfffd, 0xfffd, 0xe962, 0xfffd, 0x8bc0,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ef1, 0xe963,
- 0xe964, 0x8d81, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe965, 0xfffd, 0xfffd,
- 0x8a5d, 0xfffd, 0xfffd, 0xfffd, 0x946e, 0xe966, 0xe967, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9279, 0x93e9, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe968, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x949d, 0xfffd, 0xfffd, 0x91ca, 0x8977, 0x8bec, 0xfffd,
- 0x8bed, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x9293, 0xe96d, 0x8bee, 0xfffd, 0xfffd, 0x89ed, 0xfffd, 0xfffd,
- 0xe96c, 0xfffd, 0xfffd, 0xe96a, 0xfffd, 0xe96b, 0xfffd, 0xe969,
- 0xfffd, 0xfffd, 0xe977, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe96e, 0xe96f, 0xfffd,
- 0xfffd, 0xe970, 0xe971, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe973, 0xfffd, 0xfffd, 0xe972, 0xfffd, 0xfffd, 0xfffd, 0x8f78,
- 0xfffd, 0xe974, 0xfffd, 0xfffd, 0xfffd, 0xe976, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b52, 0xe975,
- 0xfffd, 0xfffd, 0x919b, 0x8cb1, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe978, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x91cb, 0xfffd, 0xfffd, 0xe979, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x93ab, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe97a,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe980, 0xfffd,
- 0xe97d, 0xfffd, 0xe97c, 0xe97e, 0xfffd, 0xe97b, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe982, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe981, 0xfffd, 0xe984,
- 0xfffd, 0xfffd, 0x8bc1, 0xe983, 0xfffd, 0xfffd, 0xfffd, 0xe985,
- 0xfffd, 0xfffd, 0xe986, 0xfffd, 0xe988, 0xe987, 0xfffd, 0xfffd,
- 0xfffd, 0xe989, 0xe98b, 0xe98a, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8d9c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe98c, 0xfffd, 0xfffd,
- 0xe98d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x8a5b, 0xfffd, 0xfffd, 0xfffd, 0xe98e, 0xfffd, 0xfffd, 0xfffd,
- 0xe98f, 0xfffd, 0xfffd, 0xfffd, 0x9091, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe990,
- 0xfffd, 0xe991, 0xfffd, 0xe992, 0xe993, 0xfffd, 0xfffd, 0xfffd,
- 0x8d82, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe994, 0xe995,
- 0xfffd, 0xfffd, 0xe996, 0xe997, 0xfffd, 0xfffd, 0xe998, 0xfffd,
- 0xfffd, 0xfffd, 0x94af, 0xe99a, 0xfffd, 0x9545, 0xe99b, 0xe999,
- 0xfffd, 0xe99d, 0xfffd, 0xfffd, 0xe99c, 0xfffd, 0xfffd, 0xe99e,
- 0xfffd, 0xfffd, 0xfffd, 0xe99f, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9a0, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe9a1, 0xfffd, 0xe9a2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9a3,
- 0xfffd, 0xfffd, 0xe9a4, 0xe9a5, 0xfffd, 0xe9a6, 0xfffd, 0xe9a7,
- 0xe9a8, 0xe9a9, 0xe9aa, 0xfffd, 0xfffd, 0xfffd, 0xe9ab, 0xe9ac,
- 0xfffd, 0x9f54, 0xe9ad, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe2f6, 0x8b53, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8a40, 0x8db0, 0xe9af, 0xe9ae, 0x96a3, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9b1, 0xe9b2, 0xe9b0,
- 0xfffd, 0xe9b3, 0xfffd, 0xfffd, 0x9682, 0xfffd, 0xfffd, 0xfffd,
- 0xe9b4, 0xfffd, 0x8b9b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9844,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9b5, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe9b7, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x88bc, 0xfffd,
- 0xfffd, 0xe9b8, 0x95a9, 0xe9b6, 0xfffd, 0xfffd, 0xe9b9, 0xe9ba,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9bb,
- 0xe9bc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe9bd, 0xfffd, 0x968e, 0x8e4c, 0xfffd, 0x8df8, 0x914e, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9be, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe9c1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe9bf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9c2, 0xfffd,
- 0xfffd, 0x8cef, 0xe9c0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9c3,
- 0xfffd, 0xe9c4, 0xe9c5, 0xfffd, 0xe9c9, 0xfffd, 0x8e49, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x91e2, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe9ca, 0xe9c7, 0xe9c6, 0xe9c8, 0xfffd, 0xfffd, 0xfffd,
- 0x8c7e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe9ce, 0xe9cd, 0xe9cc, 0xfffd, 0xfffd, 0x88b1, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9d8, 0xfffd, 0xe9d4, 0xfffd,
- 0xe9d5, 0xe9d1, 0xe9d7, 0xfffd, 0xe9d3, 0x8a82, 0xfffd, 0xfffd,
- 0x986b, 0xfffd, 0xe9d6, 0xe9d2, 0xe9d0, 0xe9cf, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe9da, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xe9dd, 0xfffd, 0xfffd, 0xe9dc, 0xe9db, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9568, 0xe9d9, 0x88f1,
- 0xe9de, 0xfffd, 0xe9e0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x8a8f, 0xe9cb, 0x8956, 0xfffd, 0xfffd, 0xe9e2, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9e1, 0xe9df,
- 0x924c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0x9690, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x97d8,
- 0xfffd, 0xfffd, 0xe9e3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xe9e4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9e5,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xe9e6, 0xfffd,
- 0xe9e7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x92b9, 0xfffd, 0xe9e8,
- 0xfffd, 0x94b5, 0xfffd, 0xe9ed, 0xe9e9, 0xfffd, 0xfffd, 0xfffd,
- 0xe9ea, 0xfffd, 0xfffd, 0x9650, 0x96c2, 0xfffd, 0x93ce, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xe9ee, 0xfffd, 0xfffd, 0xe9ef, 0x93bc,
- 0xe9ec, 0xe9eb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x89a8, 0xfffd,
- 0xfffd, 0xfffd, 0xe9f7, 0xfffd, 0xfffd, 0xe9f6, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8995, 0xfffd, 0xfffd, 0xfffd, 0xe9f4,
- 0xfffd, 0xfffd, 0xfffd, 0xe9f3, 0xfffd, 0xfffd, 0xe9f1, 0xfffd,
- 0x8a9b, 0xfffd, 0xe9f0, 0x8eb0, 0x89a7, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8d83, 0xfffd, 0xfffd, 0xe9fa, 0xe9f9,
- 0xfffd, 0xe9f8, 0xfffd, 0xfffd, 0xe9f5, 0xfffd, 0xe9fb, 0xfffd,
- 0xe9fc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xea44, 0xea43, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xea45, 0xfffd, 0xfffd, 0x894c, 0xea40, 0xea41, 0xfffd,
- 0x8d94, 0x96b7, 0xfffd, 0xfffd, 0xea42, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9651, 0xfffd, 0xfffd, 0xea4a,
- 0xfffd, 0xfffd, 0xea46, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xea4b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea48,
- 0xfffd, 0xea47, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8c7b,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xea4c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea4d, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xea4e, 0xfffd, 0xea49, 0xfffd, 0xfffd, 0xfffd, 0xe9f2,
- 0xfffd, 0xfffd, 0xea4f, 0xfffd, 0x92df, 0xfffd, 0xfffd, 0xfffd,
- 0xea53, 0xfffd, 0xea54, 0xea52, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xea51, 0xea57, 0xfffd, 0xea50, 0xfffd, 0xea55, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea56,
- 0xfffd, 0xfffd, 0xfffd, 0xea59, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xea58, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea5b, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea5c, 0xfffd, 0xea5d,
- 0xfffd, 0xfffd, 0x9868, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xea5a, 0x91e9, 0x8deb, 0xfffd, 0xfffd, 0xea5e, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xea5f, 0xea60, 0xfffd, 0xfffd, 0xea61, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea62, 0xfffd, 0xfffd,
- 0x8cb2, 0xea63, 0xfffd, 0xfffd, 0xfffd, 0xea64, 0xfffd, 0x8ead,
- 0xfffd, 0xea65, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xea66, 0xfffd, 0xfffd, 0xea67, 0xea68, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xea6b, 0xea69, 0x985b, 0xfffd, 0xea6a, 0xfffd, 0x97ed,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea6c, 0xfffd, 0x97d9,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea6d, 0x949e, 0xfffd,
- 0xfffd, 0xea6e, 0xea70, 0xfffd, 0xfffd, 0xea71, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xea6f, 0x8d8d, 0x96cb, 0x9683, 0x9bf5, 0xfffd, 0x9f80, 0x969b,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x89a9, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea73, 0x8b6f, 0xea74, 0xea75,
- 0xea76, 0xfffd, 0x8d95, 0xfffd, 0xea77, 0xfffd, 0xfffd, 0xfffd,
- 0xe0d2, 0x96d9, 0xfffd, 0x91e1, 0xea78, 0xea7a, 0xea79, 0xfffd,
- 0xea7b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea7c, 0xfffd, 0xfffd,
- 0xea7d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea7e,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea80, 0xfffd, 0xea81, 0xea82,
- 0xfffd, 0xea83, 0xfffd, 0xea84, 0xea85, 0xea86, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea87,
- 0xea88, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9343, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x8cdb, 0xfffd, 0xea8a, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x916c, 0xea8b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea8c, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x9540, 0xfffd, 0xfffd, 0xea8d, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xea8e, 0xe256, 0xfffd, 0xfffd, 0xe6d8, 0xe8eb,
- 0xfffd, 0xfffd, 0xea8f, 0xfffd, 0xea90, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea92,
- 0xea93, 0xea94, 0x97ee, 0xea91, 0xfffd, 0xfffd, 0xea95, 0xea96,
- 0xfffd, 0xfffd, 0xea98, 0xfffd, 0xea97, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xea9a, 0xfffd, 0xfffd, 0xfffd, 0xea9b, 0xea99,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x97b4, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea9c, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xea9d, 0xe273, 0xfffd, 0xfffd,
- 0xea9e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-};
-
-#endif /* KANJI */
-
-/* Blah-to-Unicode translation tables */
-
-struct x_to_unicode u_transparent = {
- 256, X2U_CXG, 0, 0, "Transparent", "transparent", 0, "",
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
- 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
- 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
- 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
- 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
- 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
- 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
- 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
- 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
- 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
- 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
-};
-
-/* 7-bit character sets: ISO 646, DEC NRCs, Short KOI, and Hebrew-7 */
-
-struct x_to_unicode u_ascii = {
- 94, 33, X2U_ISO|X2U_STD, AL_ROMAN, "US ASCII", "ascii", 6, "B",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e
-};
-
-struct x_to_unicode u_british = {
- 94, 33, X2U_ISO|X2U_STD, AL_ROMAN, "British ISO 646", "british", 1, "A",
- 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e
-};
-
-struct x_to_unicode u_dutch = {
- 94, 33, X2U_DEC|X2U_STD, AL_ROMAN, "Dutch NRC", "dutch", 0, "4",
- 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x00be, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00ff, 0x00bd, 0x007c, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00a8, 0x00a4, 0x00bc, 0x0027
-};
-
-struct x_to_unicode u_finnish = {
- 94, 33, X2U_DEC|X2U_STD, AL_ROMAN, "Finnish NRC", "finnish", 0, "5C",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00c5, 0x00dc, 0x005f,
- 0x00e9, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00e5, 0x00fc
-};
-
-struct x_to_unicode u_french = {
- 94, 33, X2U_ISO|X2U_STD, AL_ROMAN, "French ISO 646", "french", 0, "fR",
- 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00a8
-};
-
-struct x_to_unicode u_fr_canadian = {
- 94,33,X2U_DEC|X2U_STD,AL_ROMAN,"French Canadian NRC","canadian-french",0,"9Q",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00e2, 0x00e7, 0x00ea, 0x00ee, 0x005f,
- 0x00f4, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00fb
-};
-
-struct x_to_unicode u_german = {
- 94, 33, X2U_ISO|X2U_STD, AL_ROMAN, "German ISO 646", "german", 21, "K",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00dc, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00fc, 0x00df
-};
-
-struct x_to_unicode u_hungarian = {
- 94, 33, X2U_ISO|X2U_STD, AL_ROMAN, "Hungarian ISO 646","hungarian",86,"i",
- 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x00c1, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00c9, 0x00d6, 0x00dc, 0x005e, 0x005f,
- 0x00e1, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f6, 0x00fc, 0x0022, 0x02dd
-};
-
-struct x_to_unicode u_italian = {
- 94, 33, X2U_ISO|X2U_STD, AL_ROMAN, "Italian ISO 646", "italian", 15, "Y",
- 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00b0, 0x00e7, 0x00e9, 0x005e, 0x005f,
- 0x00f9, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e0, 0x00f2, 0x00e8, 0x00ec
-};
-
-struct x_to_unicode u_icelandic = {
- 94, 33, X2U_DEC|X2U_STD, AL_ROMAN, "Icelandic NRC", "icelandic", 0, NULL,
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x00de, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00f0, 0x00d8, 0x00c6, 0x00d6, 0x005f,
- 0x00fe, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00f0, 0x007c, 0x00e6, 0x00f6
-};
-
-struct x_to_unicode u_jis0201r = {
- 94, 33, X2U_ISO|X2U_STD,AL_ROMAN,"Japanese Roman","japanese-roman",14,"J",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x00a5, 0x005d, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e
-};
-
-struct x_to_unicode u_jis0201k = {
- 94, 33, X2U_ISO|X2U_STD,AL_KANA,"Japanese Katakana", "katakana", 13, "I",
- 0xff61, 0xff62, 0xff63, 0xff64, 0xff65, 0xff66, 0xff67,
- 0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f,
- 0xff70, 0xff71, 0xff72, 0xff73, 0xff74, 0xff75, 0xff76, 0xff77,
- 0xff78, 0xff79, 0xff7a, 0xff7b, 0xff7c, 0xff7d, 0xff7e, 0xff7f,
- 0xff80, 0xff81, 0xff82, 0xff83, 0xff84, 0xff85, 0xff86, 0xff87,
- 0xff88, 0xff89, 0xff8a, 0xff8b, 0xff8c, 0xff8d, 0xff8e, 0xff8f,
- 0xff90, 0xff91, 0xff92, 0xff93, 0xff94, 0xff95, 0xff96, 0xff97,
- 0xff98, 0xff99, 0xff9a, 0xff9b, 0xff9c, 0xff9d, 0xff9e, 0xff9f,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd
-};
-
-struct x_to_unicode u_norwegian = { /* Same as Danish */
- 94,33,X2U_ISO|X2U_STD,AL_ROMAN,"Norwegian ISO 646", "norwegian", 60, "`E6",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x007e
-};
-
-struct x_to_unicode u_danish = { /* Same as Norwegian */
- 94, 33, X2U_ISO|X2U_STD, AL_ROMAN, "Danish ISO 646", "danish", 60, "`E6",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x007e
-};
-
-struct x_to_unicode u_portuguese = {
- 94,33,X2U_ISO|X2U_STD,AL_ROMAN,"Portuguese ISO 646","portuguese",16,"L%6",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x007e
-};
-
-struct x_to_unicode u_spanish = {
- 94, 33, X2U_ISO|X2U_STD, AL_ROMAN, "Spanish ISO 646", "spanish", 17, "Z",
- 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00a1, 0x00d1, 0x00bf, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00b0, 0x00f1, 0x00e7, 0x007e
-};
-
-struct x_to_unicode u_swedish = {
- 94, 33, X2U_ISO|X2U_STD, AL_ROMAN, "Swedish ISO 646", "swedish", 11, "HG",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x00c9, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00c5, 0x00dc, 0x005f,
- 0x00e9, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00e5, 0x00fc
-};
-
-struct x_to_unicode u_swiss = {
- 94, 33, X2U_DEC|X2U_STD, AL_ROMAN, "Swiss NRC", "swiss", 0, "=",
- 0x0021, 0x0022, 0x00f9, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x00e9, 0x00e7, 0x00ea, 0x00ee, 0x00e8,
- 0x00f4, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00fc, 0x00fb
-};
-
-struct x_to_unicode u_koi7 = {
- 94, 33, X2U_STD, AL_CYRIL, "Short KOI", "short-koi", 0, NULL,
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
- 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
- 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
- 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
- 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427
-};
-
-struct x_to_unicode u_elot927 = {
- 94, 33, X2U_STD, AL_GREEK, "ELOT 927", "elot927-greek", 0, NULL,
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
- 0x0060, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
- 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
- 0x03a0, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8,
- 0x03a9, 0x0020, 0x0020, 0x007b, 0x007c, 0x007d, 0x007e
-};
-
-
-struct x_to_unicode u_hebrew7 = {
- 94, 33, X2U_STD, AL_HEBREW, "Hebrew-7", "hebrew-7", 0, NULL,
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
- 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7,
- 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
- 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7,
- 0x05e8, 0x05e9, 0x05ea, 0x007b, 0x007c, 0x007d, 0x007e
-};
-
-struct x_to_unicode u_apl1 = {
- 94, 33, X2U_ISO|X2U_STD, AL_ROMAN, "APL ISO", "apl-iso", 68, "e",
- 0x00a8, 0x0029, 0x003c, 0x2264, 0x003d, 0x003e, 0x005d,
- 0x2228, 0x2227, 0x2260, 0x00f7, 0x002c, 0x002b, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x0028, 0x005b, 0x003b, 0x00d7, 0x003a, 0x005c,
- 0x00af, 0x237a, 0x22a5, 0x22c2, 0x230a, 0x220a, 0x005f, 0x2207,
- 0x2206, 0x2373, 0x2218, 0x0027, 0x25af, 0x007c, 0x22a4, 0x25cb,
- 0x22c6, 0x003f, 0x2374, 0x2308, 0x223c, 0x2193, 0x222a, 0x2375,
- 0x2283, 0x2191, 0x2282, 0x2190, 0x22a2, 0x2192, 0x2265, 0x002d,
- 0x22c4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x007b, 0x22a3, 0x007d, 0x0024
-};
-
-/* ISO 8859 Latin Alphabets */
-
-struct x_to_unicode u_8859_1 = {
- 96, 32, X2U_ISO|X2U_STD, AL_ROMAN, "ISO Latin-1", "latin1", 100, "A",
- 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
- 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
- 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
- 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
- 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
- 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
-};
-
-struct x_to_unicode u_8859_2 = {
- 96, 32, X2U_ISO|X2U_STD, AL_ROMAN, "ISO Latin-2", "latin2", 101, "B",
- 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
- 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
- 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
- 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
- 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
- 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
- 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
- 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
- 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
- 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
- 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
- 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
-};
-
-struct x_to_unicode u_8859_3 = {
- 96, 32, X2U_ISO|X2U_STD, AL_ROMAN, "ISO Latin-3", "latin3", 109, "C",
- 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0xfffd, 0x0124, 0x00A7,
- 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0xfffd, 0x017B,
- 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7,
- 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0xfffd, 0x017C,
- 0x00C0, 0x00C1, 0x00C2, 0xfffd, 0x00C4, 0x010A, 0x0108, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0xfffd, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7,
- 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0xfffd, 0x00E4, 0x010B, 0x0109, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0xfffd, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7,
- 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9
-};
-
-struct x_to_unicode u_8859_4 = {
- 96, 32, X2U_ISO|X2U_STD, AL_ROMAN, "ISO Latin-4", "latin4", 110, "D",
- 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7,
- 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF,
- 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7,
- 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B,
- 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
- 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A,
- 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
- 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF,
- 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
- 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B,
- 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
- 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9
-};
-
-struct x_to_unicode u_8859_5 = {
- 96,32,X2U_ISO|X2U_STD,AL_CYRIL,"ISO Latin/Cyrillic","cyrillic-iso",144,"L",
- 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
- 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F,
- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
- 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
- 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
- 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
- 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
- 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
- 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F
-};
-
-struct x_to_unicode u_8859_6 = {
- 96, 32, X2U_ISO|X2U_STD,AL_ARABIC,"ISO Latin/Arabic","arabic-iso",127,"G",
- 0x00A0, 0xfffd, 0xfffd, 0xfffd, 0x00A4, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x060C, 0x00AD, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0x061B, 0xfffd, 0xfffd, 0xfffd, 0x061F,
- 0xfffd, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
- 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
- 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
- 0x0638, 0x0639, 0x063A, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
- 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F,
- 0x0650, 0x0651, 0x0652, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd
-};
-
-struct x_to_unicode u_8859_7 = {
- 96, 32, X2U_ISO|X2U_STD,AL_GREEK,"ISO Latin/Greek", "greek-iso", 126, "F",
- 0x00A0, 0x2018, 0x2019, 0x00A3, 0xFFFD, 0xFFFD, 0x00A6, 0x00A7,
- 0x00A8, 0x00A9, 0xFFFD, 0x00AB, 0x00AC, 0x00AD, 0xFFFD, 0x2015,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7,
- 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
- 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
- 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
- 0x03A0, 0x03A1, 0xfffd, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
- 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
- 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
- 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
- 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
- 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xfffd
-};
-
-struct x_to_unicode u_8859_8 = {
- 96, 32, X2U_ISO|X2U_STD,AL_HEBREW,"ISO Latin/Hebrew","hebrew-iso",121,"H",
- 0x00A0, 0xfffd, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
- 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x203E,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
- 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2017,
- 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
- 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
- 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
- 0x05E8, 0x05E9, 0x05EA, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd
-};
-
-struct x_to_unicode u_8859_9 = {
- 96, 32, X2U_ISO|X2U_STD, AL_ROMAN, "ISO Latin-5", "latin5", 148, "M",
- 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
- 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
- 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
- 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
- 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
- 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
-};
-
-struct x_to_unicode u_8859_10 = {
- 96, 32, X2U_ISO|X2U_STD, AL_ROMAN, "ISO Latin-6", "latin6", 157, "V",
- 0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x013b,
- 0x0143, 0x0156, 0x0160, 0x0166, 0x017d, 0x00ad, 0x0138, 0x014a,
- 0x0111, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x013c,
- 0x0144, 0x0157, 0x0161, 0x0167, 0x017e, 0x00bd, 0x00be, 0x014b,
- 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e,
- 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf,
- 0x0110, 0x0145, 0x014c, 0x00de, 0x00d4, 0x00d5, 0x00d6, 0x0168,
- 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x016a,
- 0x0101, 0x00e1, 0x00e2, 0x00d3, 0x00e4, 0x00e5, 0x00e6, 0x012f,
- 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef,
- 0x00f0, 0x00f1, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169,
- 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x016b
-};
-
-/* Latin-9 (ISO 8859-15) is the same as Latin-1 with the following changes:
- * A4 is Euro Symbol 20AC
- * A6 is Capital S Caron 0160
- * A8 is Small s caron 0161
- * B4 is Capital Z caron 017D
- * B8 is Small z caron 017E
- * BC is Capital OE ligature 0152
- * BD is Small oe ligature 0153
- * BE is Capital Y diaeresis 0178
- */
-
-struct x_to_unicode u_8859_15 = {
- 96, 32, X2U_ISO|X2U_STD, AL_ROMAN, "ISO Latin-9", "latin9", 0, NULL,
- 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7,
- 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7,
- 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF,
- 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
- 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
- 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
-};
-
-/* Dyadic Systems Dyalog/X APL, corresponds to APLTERMI.TTF. */
-/* Unicode mappings according to ISO-IEC / JTC 1 / SC 22 N 3067, 1999-12-28. */
-
-struct x_to_unicode u_apl2 = { /* Dyadic Systems APL + box drawings */
- 96, 32, X2U_STD, AL_ROMAN, "Dyadic Systems APL", "apl-dyadic", 0, NULL,
- 0x00a0, 0x00d7, 0x2502, 0x2524, 0x00a2, 0x2510, 0x2514, 0x2534,
- 0x252c, 0x251c, 0x2500, 0x253c, 0x2518, 0x250c, 0x2206, 0x00f7,
- 0x2260, 0x22c4, 0x2375, 0x2374, 0x237a, 0x220a, 0x2261, 0x2265,
- 0x2264, 0x22a5, 0x22a4, 0x2190, 0x2218, 0x235d, 0x233f, 0x2340,
- 0x234e, 0x2355, 0x234b, 0x2352, 0x2372, 0x2371, 0x2368, 0x235f,
- 0x25af, 0x235e, 0x2339, 0x236b, 0x236a, 0x2262, 0x230a, 0x2308,
- 0x2349, 0x2229, 0x222a, 0x236c, 0x00a3, 0x233d, 0x2296, 0x22a2,
- 0x22a3, 0x2337, 0x00af, 0x2373, 0x00a8, 0x25cb, 0x2192, 0x2228,
- 0x2282, 0x2283, 0x2359, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,
- 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d,
- 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055,
- 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x2207, 0x2191, 0x2193
-};
-
-struct x_to_unicode u_apl3 = { /* APL-Plus = APL-2000 */
- 128, 0, X2U_CXG, AL_ROMAN, "APL-2000", "apl-2000", 0, NULL,
- 0x20ac, 0x22a3, 0x22a4, 0x22a5, 0x2190, 0x2192, 0x2191, 0x2193,
- 0x2264, 0x2265, 0x2372, 0x2371, 0x25af, 0x235e, 0x2339, 0x2359,
- 0x236b, 0x2206, 0x2207, 0x234b, 0x2352, 0x2355, 0x234e, 0x2308,
- 0x230a, 0x2340, 0x233f, 0x2282, 0x2283, 0x2229, 0x222a, 0x2228,
- 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x22a2, 0x00a5, 0x00a6, 0x00a7,
- 0x00a8, 0x235d, 0x22c4, 0x00ab, 0x2260, 0x2261, 0x236a, 0x00af,
- 0x2218, 0x25cb, 0x233d, 0x2349, 0x2296, 0x235f, 0x00b6, 0x00b7,
- 0x237a, 0x220a, 0x2377, 0x00bb, 0x2373, 0x2374, 0x2375, 0x00bf,
- 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
- 0x236c, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x2337, 0x00df,
- 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
- 0x2364, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
- 0x2205, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x2368, 0x00ff
-};
-
-struct x_to_unicode u_apl4 = { /* IBM APL2 */
- 128, 0, X2U_CXG, AL_ROMAN, "IBM APL2", "apl2-ibm", 0, NULL,
- 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
- 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
- 0x25af, 0x235e, 0x2339, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
- 0x22a4, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x22a5, 0x2190, 0x2336,
- 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
- 0x00bf, 0x2308, 0x00ac, 0x2192, 0x222a, 0x00a1, 0x2355, 0x234e,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x235f, 0x2206, 0x2207,
- 0x2192, 0x2563, 0x2551, 0x2557, 0x255d, 0x2190, 0x230a, 0x2510,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x2191, 0x2193,
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2261,
- 0x2378, 0x2377, 0x2235, 0x2337, 0x2342, 0x233b, 0x22a2, 0x22a3,
- 0x22c4, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580,
- 0x237a, 0x00df, 0x2282, 0x2283, 0x235d, 0x2372, 0x2374, 0x2371,
- 0x233d, 0x2296, 0x25cb, 0x2228, 0x2373, 0x2349, 0x00c5, 0x2229,
- 0x233f, 0x2340, 0x2265, 0x2264, 0x2260, 0x00d7, 0x00f7, 0x2359,
- 0x2218, 0x2375, 0x236b, 0x234b, 0x2352, 0x00af, 0x00a8, 0x00a0
-};
-
-struct x_to_unicode u_apl5 = { /* APL-2741 */
- 128, 0, X2U_CXG, AL_ROMAN, "APL-2741", "apl-2741", 0, NULL,
- 0x20ac, 0x22a3, 0x22a4, 0x22a5, 0x2190, 0x2192, 0x2191, 0x2193,
- 0x2264, 0x2265, 0x2372, 0x2371, 0x25af, 0x235e, 0x2339, 0x2359,
- 0x236b, 0x2206, 0x2207, 0x234b, 0x2352, 0x2355, 0x234e, 0x2308,
- 0x230a, 0x2340, 0x233f, 0x2282, 0x2283, 0x2229, 0x222a, 0x2228,
- 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x22a2, 0x2378, 0x2261, 0x2336,
- 0x00a8, 0x235d, 0x22c4, 0x236c, 0x2260, 0x2261, 0x236a, 0x00af,
- 0x2218, 0x25cb, 0x233d, 0x2349, 0x2296, 0x235f, 0x00b6, 0x00b7,
- 0x237a, 0x220a, 0x2377, 0x2262, 0x2373, 0x2374, 0x2375, 0x00bf,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
- 0x00c8, 0x00c9, 0x2342, 0x233b, 0x2510, 0x00cd, 0x2500, 0x253c,
- 0x236c, 0x00d1, 0x2350, 0x2357, 0x2347, 0x2348, 0x00d6, 0x00d7,
- 0x00d8, 0x2518, 0x250c, 0x2502, 0x00dc, 0x2524, 0x2337, 0x00df,
- 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
- 0x2364, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
- 0x2205, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x2235, 0x2368, 0x2365
-};
-
-/* 8-bit GOST standard sets */
-
-struct x_to_unicode u_koi8 = {
- 96, 32, X2U_STD, AL_CYRIL, "KOI-8", "koi8", 0, NULL,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
- 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
- 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
- 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
- 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
- 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
- 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
- 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0xfffd
-};
-
-/* Other KOI-8 based sets */
-
-struct x_to_unicode u_koi8r = { /* (Russia) Table from RFC1489 */
- 128, 0, X2U_CP, AL_CYRIL, "KOI8-R", "koi8r", 0, NULL,
- 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
- 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
- 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
- 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
- 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
- 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
- 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
- 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
- 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
- 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
- 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
- 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
- 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
- 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
- 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
- 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
-};
-
-struct x_to_unicode u_koi8u = { /* (Ukraine) From RFC2319 */
- 128, 0, X2U_CP, AL_CYRIL, "KOI8-U", "koi8u", 0, NULL,
- 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
- 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
- 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
- 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
- 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457,
- 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x0491, 0x255D, 0x255E,
- 0x255F, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407,
- 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x0490, 0x256C, 0x00A9,
- 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
- 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
- 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
- 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
- 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
- 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
- 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
- 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
-};
-
-/* PC Code Pages */
-
-struct x_to_unicode u_cp437 = {
- 128, 0, X2U_CP, AL_ROMAN,"PC Code Page 437","cp437", 0, NULL,
- 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
- 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
- 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
- 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
- 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
- 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
- 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
- 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
- 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
- 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
- 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
- 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
- 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, /* 0x25ae */ 0x25a0, 0x00a0
-};
-
-struct x_to_unicode u_mazovia = {
- 128, 0, X2U_CP, AL_ROMAN,"Polish Mazovia PC Code Page","mazovia", 0, NULL,
- 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x0105, 0x00e7, /* 80 */
- 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0107, 0x00c4, 0x0104, /* 88 */
- 0x0118, 0x0119, 0x0142, 0x00f4, 0x00f6, 0x0106, 0x00fb, 0x00f9, /* 90 */
- 0x015a, 0x00d6, 0x00dc, 0x00a2, 0x0141, 0x00a5, 0x015b, 0x0192, /* 98 */
- 0x0179, 0x017b, 0x00f3, 0x00d3, 0x0144, 0x0143, 0x017a, 0x017c, /* a0 */
- 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, /* a8 */
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, /* b0 */
- 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, /* b8 */
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, /* c0 */
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, /* c8 */
- 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, /* d0 */
- 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, /* d8 */
- 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, /* e0 */
- 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, /* e8 */
- 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, /* f0 */
- 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 /* f8 */
-};
-
-struct x_to_unicode u_cp850 = {
- 128, 0, X2U_CP, AL_ROMAN,"PC Code Page 850","cp850", 0, NULL,
- 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
- 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
- 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
- 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192,
- 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
- 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0,
- 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3,
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4,
- 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce,
- 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580,
- 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe,
- 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4,
- 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8,
- 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0
-};
-
-struct x_to_unicode u_cp852 = {
- 128, 0, X2U_CP, AL_ROMAN,"PC Code Page 852","cp852", 0, NULL,
- 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x016f, 0x0107, 0x00e7,
- 0x0142, 0x00eb, 0x0150, 0x0151, 0x00ee, 0x0179, 0x00c4, 0x0106,
- 0x00c9, 0x0139, 0x013a, 0x00f4, 0x00f6, 0x013d, 0x013e, 0x015a,
- 0x015b, 0x00d6, 0x00dc, 0x0164, 0x0165, 0x0141, 0x00d7, 0x010d,
- 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x0104, 0x0105, 0x017d, 0x017e,
- 0x0118, 0x0119, 0x00ac, 0x017a, 0x010c, 0x015f, 0x00ab, 0x00bb,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x011a,
- 0x015e, 0x2563, 0x2551, 0x2557, 0x255d, 0x017b, 0x017c, 0x2510,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x0102, 0x0103,
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4,
- 0x0111, 0x0110, 0x010e, 0x00cb, 0x010f, 0x0147, 0x00cd, 0x00ce,
- 0x011b, 0x2518, 0x250c, 0x2588, 0x2584, 0x0162, 0x016e, 0x2580,
- 0x00d3, 0x00df, 0x00d4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
- 0x0154, 0x00da, 0x0155, 0x0170, 0x00fd, 0x00dd, 0x0163, 0x00b4,
- 0x00ad, 0x02dd, 0x02db, 0x02c7, 0x02d8, 0x00a7, 0x00f7, 0x00b8,
- 0x00b0, 0x00a8, 0x02d9, 0x0171, 0x0158, 0x0159, 0x25a0, 0x00a0
-};
-
-struct x_to_unicode u_cp855 = { /* CP855 Cyrillic to Unicode */
- 128, 0, X2U_CP, AL_CYRIL,"PC Code Page 855","cp855", 0, NULL,
- 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
- 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
- 0x0459, 0x0409, 0x045a, 0x040a, 0x045b, 0x040b, 0x045c, 0x040c,
- 0x045e, 0x040e, 0x045f, 0x040f, 0x044e, 0x042e, 0x044a, 0x042a,
- 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
- 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00ab, 0x00bb,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
- 0x0418, 0x2563, 0x2551, 0x2557, 0x255d, 0x0439, 0x0419, 0x2510,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x043a, 0x041a,
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4,
- 0x043b, 0x041b, 0x043c, 0x041c, 0x043d, 0x041d, 0x043e, 0x041e,
- 0x043f, 0x2518, 0x250c, 0x2588, 0x2584, 0x041f, 0x044f, 0x2580,
- 0x042f, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
- 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044c, 0x042c, 0x2116,
- 0x002d, 0x044b, 0x042b, 0x0437, 0x0417, 0x0448, 0x0428, 0x044d,
- 0x042d, 0x0449, 0x0429, 0x0447, 0x0427, 0x00a7, 0x25a0, 0x0020
-};
-
-struct x_to_unicode u_cp856 = { /* CP856 (Bulgaria) to Unicode */
- 128, 0, X2U_CP, AL_CYRIL,"PC Code Page 856","cp856", 0, NULL,
- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
- 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
- 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
- 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
- 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x2563, 0x2551,
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2510,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2116, 0x00a7, 0x2557,
- 0x255d, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
- 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
- 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
- 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
- 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
-};
-
-struct x_to_unicode u_cp857 = {
- 128, 0, X2U_CP, AL_ROMAN,"PC Code Page 857","cp857", 0, NULL,
- 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, /* 0x80 */
- 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0131, 0x00c4, 0x00c5, /* 0x88 */
- 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, /* 0x90 */
- 0x0130, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x015e, 0x015f, /* 0x98 */
- 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x011e, 0x011f, /* 0xa0 */
- 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, /* 0xa8 */
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, /* 0xb0 */
- 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, /* 0xb8 */
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, /* 0xc0 */
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, /* 0xc8 */
- 0x00ba, 0x00aa, 0x00ca, 0x00cb, 0x00c8, 0x20ac, 0x00cd, 0x00ce, /* 0xd0 */
- 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, /* 0xd8 */
- 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0xfffd, /* 0xe0 */
- 0x00d7, 0x00da, 0x00db, 0x00d9, 0x00ec, 0x00ff, 0x00af, 0x00b4, /* 0xe8 */
- 0x00ad, 0x00b1, 0xfffd, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, /* 0xf0 */
- 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0 /* 0xf8 */
-};
-
-struct x_to_unicode u_cp858 = {
- 128, 0, X2U_CP, AL_ROMAN,"PC Code Page 858","cp858", 0, NULL,
- 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
- 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
- 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
- 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192,
- 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
- 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0,
- 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3,
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4,
- 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x20ac, 0x00cd, 0x00ce,
- 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580,
- 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe,
- 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4,
- 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8,
- 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0
-};
-
-struct x_to_unicode u_cp862 = {
- 128, 0, X2U_CP, AL_HEBREW,"PC Code Page 862","cp862", 0, NULL,
- 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7,
- 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
- 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7,
- 0x05e8, 0x05e9, 0x05ea, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
- 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
- 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
- 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
- 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
- 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
- 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
- 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
- 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
- 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
-};
-
-struct x_to_unicode u_cp864 = {
- 128, 0, X2U_CP, AL_ARABIC,"PC Code Page 864","cp864", 0, NULL,
- 0x00b0, 0x00b7, 0x2219, 0x221a, 0x2592, 0x2500, 0x2502, 0x253c,
- 0x2524, 0x252c, 0x251c, 0x2534, 0x2510, 0x250c, 0x2514, 0x2518,
- 0x03b2, 0x221e, 0x03c6, 0x00b1, 0x00bd, 0x00bc, 0x2248, 0x00ab,
- 0x00bb, 0xfef7, 0xfef8, 0xfffd, 0xfffd, 0xfefb, 0xfefc, 0xfffd,
- 0x00a0, 0x00ad, 0xfe82, 0x00a3, 0x00a4, 0xfe84, 0xfffd, 0xfffd,
- 0xfe8e, 0xfe8f, 0xfe95, 0xfe99, 0x060c, 0xfe9d, 0xfea1, 0xfea5,
- 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667,
- 0x0668, 0x0669, 0xfed1, 0x061b, 0xfeb1, 0xfeb5, 0xfeb9, 0x061f,
- 0x00a2, 0xfe80, 0xfe81, 0xfe83, 0xfe85, 0xfeca, 0xfe8b, 0xfe8d,
- 0xfe91, 0xfe93, 0xfe97, 0xfe9b, 0xfe9f, 0xfea3, 0xfea7, 0xfea9,
- 0xfeab, 0xfead, 0xfeaf, 0xfeb3, 0xfeb7, 0xfebb, 0xfebf, 0xfec1,
- 0xfec5, 0xfecb, 0xfecf, 0x00a6, 0x00ac, 0x00f7, 0x00d7, 0xfec9,
- 0x0640, 0xfed3, 0xfed7, 0xfedb, 0xfedf, 0xfee3, 0xfee7, 0xfeeb,
- 0xfeed, 0xfeef, 0xfef3, 0xfebd, 0xfecc, 0xfece, 0xfecd, 0xfee1,
- 0xfe7d, 0x0651, 0xfee5, 0xfee9, 0xfeec, 0xfef0, 0xfef2, 0xfed0,
- 0xfed5, 0xfef5, 0xfef6, 0xfedd, 0xfed9, 0xfef1, 0x25a0, 0xfffd
-};
-
-struct x_to_unicode u_cp866 = {
- 128, 0, X2U_CP, AL_CYRIL,"PC Code Page 866","cp866", 0, NULL,
- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
- 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
- 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
- 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
- 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
- 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
- 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
- 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
- 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040e, 0x045e,
- 0x00b0, 0x2219, 0x00b7, 0x221a, 0x2116, 0x00a4, 0x25a0, 0x00a0
-};
-
-struct x_to_unicode u_cp869 = {
- 128, 0, X2U_CP, AL_GREEK,"PC Code Page 869","cp869", 0, NULL,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x0386, 0xfffd,
- 0x00b7, 0x00ac, 0x00a6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
- 0x038a, 0x03aa, 0x038c, 0xfffd, 0xfffd, 0x038e, 0x03ab, 0x00a9,
- 0x038f, 0x00b2, 0x00b3, 0x03ac, 0x00a3, 0x03ad, 0x03ae, 0x03af,
- 0x03ca, 0x0390, 0x03cc, 0x03cd, 0x0391, 0x0392, 0x0393, 0x0394,
- 0x0395, 0x0396, 0x0397, 0x00bd, 0x0398, 0x0399, 0x00ab, 0x00bb,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039a, 0x039b, 0x039c,
- 0x039d, 0x2563, 0x2551, 0x2557, 0x255d, 0x039e, 0x039f, 0x2510,
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x03a0, 0x03a1,
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x03a3,
- 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2,
- 0x03b3, 0x2518, 0x250c, 0x2588, 0x2584, 0x03b4, 0x03b5, 0x2580,
- 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd,
- 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x0384,
- 0x00ad, 0x00b1, 0x03c5, 0x03c6, 0x03c7, 0x00a7, 0x03c8, 0x0385,
- 0x00b0, 0x00a8, 0x03c9, 0x03cb, 0x03b0, 0x03ce, 0x25a0, 0x00a0
-};
-
-/* Windows code pages */
-
-struct x_to_unicode u_cp1250 = { /* Windows Latin-2 */
- 128, 0, X2U_CP, AL_ROMAN,"Windows Code Page 1250","cp1250", 0, NULL,
- 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, /* 80 */
- 0x005e, 0x2031, 0x0160, 0x003c, 0x015a, 0x0164, 0x017d, 0x0179, /* 88 */
- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2012, 0x2014, /* 90 */
- 0xfffd, 0x2122, 0x0161, 0x003e, 0x015b, 0x0165, 0x017e, 0x017a, /* 98 */
- 0x00A0, 0x02c7, 0x02d8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7, /* A0 */
- 0x00A8, 0x00a9, 0x015E, 0x00ab, 0x00ac, 0x002D, 0x00ae, 0x017B, /* A8 */
- 0x00B0, 0x00b1, 0x02DB, 0x0142, 0x00B4, 0x00b5, 0x00b6, 0x00b7, /* B0 */
- 0x00B8, 0x0105, 0x015F, 0x00bb, 0x013d, 0x02DD, 0x013E, 0x017C, /* B8 */
- 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, /* C0 */
- 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
- 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
- 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
- 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
- 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
- 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
- 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
-};
-
-struct x_to_unicode u_cp1251 = { /* Windows Cyrillic */
- 128, 0, X2U_CP, AL_CYRIL,"Windows Code Page 1251","cp1251", 0, NULL,
- 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, /* 80 */
- 0x20ac, 0x2031, 0x0409, 0x003c, 0x040a, 0x040c, 0x040b, 0x040f, /* 88 */
- 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2012, 0x2014, /* 90 */
- 0x007e, 0x2122, 0x0459, 0x003e, 0x045a, 0x045c, 0x045b, 0x045f, /* 98 */
- 0x00A0, 0x040e, 0x045e, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, /* a0 */
- 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, /* a8 */
- 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, /* b0 */
- 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, /* b8 */
- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, /* c0 */
- 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, /* c8 */
- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, /* d0 */
- 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, /* d8 */
- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, /* e0 */
- 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, /* e8 */
- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, /* f0 */
- 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f /* f8 */
-};
-
-struct x_to_unicode u_cp1252 = { /* Windows Latin-1 */
-/*
- The following code points added September 1998:
- 0x80: Euro
- 0x8E: Latin Capital Letter Z with Caron
- 0x9E: Latin Small Letter Z with Caron
- Announced by Murray Sargent <murrays@microsoft.com> to Unicode consortium,
- email, 3 September 1998. The code page was changed in June 1998. The
- change is reflected in Windows 98 and "recent service packs" for Window 95
- and Windows NT 4.0.
-*/
- 128, 0, X2U_CP, AL_ROMAN,"Windows Code Page 1252","cp1252", 0, NULL,
- 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
- 0x005e, 0x2031, 0x0160, 0x003c, 0x0152, 0xfffd, 0x017D, 0xfffd,
- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2012, 0x2014,
- 0x007e, 0x2122, 0x0161, 0x003e, 0x0153, 0xfffd, 0x017E, 0x0178,
- 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
- 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
- 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
- 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
- 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
- 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
-};
-
-struct x_to_unicode u_cp1253 = { /* Windows Greece */
- 128, 0, X2U_CP, AL_GREEK,"Windows Code Page 1253","cp1253", 0, NULL,
- 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, /* 80 */
- 0xfffd, 0x2031, 0xfffd, 0x003c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, /* 88 */
- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2012, 0x2014, /* 90 */
- 0xfffd, 0x2122, 0xfffd, 0x003e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, /* 98 */
- 0x00A0, 0x00b7, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, /* a0 */
- 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, /* a8 */
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B7, 0x00B5, 0x00B6, 0x00B7, /* b0 */
- 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, /* b8 */
- 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* c0 */
- 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, /* c8 */
- 0x03a0, 0x03a1, 0xfffd, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* d0 */
- 0x03a8, 0x03a9, 0x03aA, 0x03aB, 0x03aC, 0x03aD, 0x03aE, 0x03aF, /* d8 */
- 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* e0 */
- 0x03b8, 0x03b9, 0x03bA, 0x03bB, 0x03bC, 0x03bD, 0x03bE, 0x03bF, /* e8 */
- 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* f0 */
- 0x03c8, 0x03c9, 0x03cA, 0x03cB, 0x03cC, 0x03cD, 0x03cE, 0xfffd /* f8 */
-};
-
-struct x_to_unicode u_cp1254 = { /* Windows Turkey */
- 128, 0, X2U_CP, AL_ROMAN,"Windows Code Page 1254","cp1254", 0, NULL,
- 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, /* 80 */
- 0x005e, 0x2031, 0x0160, 0x003c, 0x0152, 0xfffd, 0xfffd, 0xfffd, /* 88 */
- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2012, 0x2014, /* 90 */
- 0x007e, 0x2122, 0x0161, 0x003e, 0x0153, 0xfffd, 0xfffd, 0x0178, /* 98 */
- 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
- 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
- 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
- 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0x011e, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
- 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015e, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0x011f, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
- 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015f, 0x00FF
-};
-
-struct x_to_unicode u_cp1255 = { /* Windows Hebrew */
- 128, 0, X2U_CP, AL_ROMAN,"Windows Code Page 1255 (Hebrew)","cp1255",
- 0, NULL,
- 0x20AC, 0xFFFD, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
- 0x02c6, 0x2030, 0xfffd, 0x2039, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
- 0x02dc, 0x2122, 0xfffd, 0x203a, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20aa, 0x00a5, 0x00a6, 0x00a7,
- 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
- 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
- 0x05b0, 0x05b1, 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7,
- 0x05b8, 0x05b9, 0xfffd, 0x05bb, 0x05bc, 0x05bd, 0x05be, 0x05bf,
- 0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05f0, 0x05f1, 0x05f2, 0x05f3,
- 0x05f4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7,
- 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
- 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7,
- 0x05e8, 0x05e9, 0x05ea, 0xfffd, 0xfffd, 0x200e, 0x200f, 0xfffd
-};
-
-struct x_to_unicode u_cp1256 = { /* Windows Arabic */
- 128, 0, X2U_CP, AL_ROMAN,"Windows Code Page 1256 (Arabic)","cp1256",
- 0, NULL,
- 0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
- 0x02c6, 0x2030, 0xfffd, 0x2039, 0x0152, 0x0686, 0x0698, 0xfffd, /* 88 */
- 0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, /* 90 */
- 0xfffd, 0x2122, 0xfffd, 0x003a, 0x0153, 0x200c, 0x200d, 0xfffd, /* 98 */
- 0x00A0, 0x060c, 0x00A2, 0x00A3, 0x00A4, 0x00a5, 0x00A6, 0x00A7, /* a0 */
- 0x00a8, 0x00A9, 0xfffd, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00af, /* a8 */
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00b4, 0x00B5, 0x00B6, 0x00B7, /* b0 */
- 0x00b8, 0x00B9, 0x061b, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061f, /* b8 */
- 0xfffd, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* c0 */
- 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* c8 */
- 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, /* d0 */
- 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643, /* d8 */
- 0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, /* e0 */
- 0x00e8, 0x00E9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef, /* e8 */
- 0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00F7, /* f0 */
- 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0xfffd /* f8 */
-};
-
-struct x_to_unicode u_cp1257 = { /* Windows Latin-4 */
- 128, 0, X2U_CP, AL_ROMAN,"Windows Code Page 1257","cp1257", 0, NULL,
- 0x20ac, 0xfffd, 0x201a, 0xfffd, 0x201e, 0x2026, 0x2020, 0x2021, /* 80 */
- 0xfffd, 0x2031, 0xfffd, 0x003c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, /* 88 */
- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2012, 0x2014, /* 90 */
- 0xfffd, 0x2122, 0xfffd, 0x003e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, /* 98 */
- 0x00A0, 0xfffd, 0x00A2, 0x00A3, 0x00A4, 0xfffd, 0x00A6, 0x00A7, /* a0 */
- 0x00d8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00c6, /* a8 */
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0xfffd, 0x00B5, 0x00B6, 0x00B7, /* b0 */
- 0x00f8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00e6, /* b8 */
- 0x0104, 0x012e, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, /* c0 */
- 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x00b7, /* c8 */
- 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00D5, 0x00D6, 0x00D7, /* d0 */
- 0x0172, 0x0141, 0x015A, 0x016a, 0x00DC, 0x017b, 0x017d, 0x00DF, /* d8 */
- 0x0105, 0x012f, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, /* e0 */
- 0x010D, 0x00E9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, /* e8 */
- 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00F5, 0x00F6, 0x00F7, /* f0 */
- 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0xfffd /* f8 */
-};
-
-struct x_to_unicode u_cp1258 = { /* Windows Viet Nam */
- 128, 0, X2U_CP, AL_ROMAN,"Windows Code Page 1258 (Viet Nam)","cp1258",
- 0, NULL,
- 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, /* 80 */
- 0x02c6, 0x2030, 0xfffd, 0x2039, 0x0152, 0xfffd, 0xfffd, 0xfffd, /* 88 */
- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, /* 90 */
- 0x02dc, 0x2122, 0xfffd, 0x203a, 0x0153, 0xfffd, 0xfffd, 0x0178, /* 98 */
- 0x00A0, 0x00a1, 0x00A2, 0x00A3, 0x00A4, 0x00a5, 0x00A6, 0x00A7, /* a0 */
- 0x00a8, 0x00A9, 0x00aa, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00af, /* a8 */
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00b4, 0x00B5, 0x00B6, 0x00B7, /* b0 */
- 0x00b8, 0x00B9, 0x00ba, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00bf, /* b8 */
- 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00C4, 0x00C5, 0x00c6, 0x00c7, /* c0 */
- 0x00c8, 0x00C9, 0x00ca, 0x00cb, 0x0300, 0x00cd, 0x00ce, 0x00cf, /* c8 */
- 0x0110, 0x00d1, 0x0309, 0x00d3, 0x00d4, 0x01a0, 0x00D6, 0x00D7, /* d0 */
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00DC, 0x01af, 0x0303, 0x00DF, /* d8 */
- 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00E4, 0x00E5, 0x00e6, 0x00d7, /* e0 */
- 0x00e8, 0x00E9, 0x00ea, 0x00eb, 0x0301, 0x00ed, 0x00ee, 0x00ef, /* e8 */
- 0x0111, 0x00f1, 0x0323, 0x00f3, 0x00f4, 0x01a1, 0x00F6, 0x00F7, /* f0 */
- 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x01b0, 0x20ab, 0x00ff /* f8 */
-};
-
-struct x_to_unicode u_cp37 = { /* EBCDIC U.S. */
- 256, 0, X2U_CP, AL_ROMAN,"Code Page 037 EBCDIC (U.S.)","cp037", 0, NULL,
- 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
- 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
- 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
- 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
- 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
- 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
- 0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
- 0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
- 0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
- 0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC,
- 0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
- 0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
- 0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
- 0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
- 0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
- 0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
- 0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
- 0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
- 0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
- 0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
- 0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
- 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
- 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
- 0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
- 0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
- 0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F
-};
-
-/* Other proprietary 8-bit sets */
-
-struct x_to_unicode u_decmcs = {
- 96, 32, X2U_DEC|X2U_STD, AL_ROMAN, "DEC Multinational", "dec-mcs", 0, "%5",
- 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0xfffd, 0x00A5, 0xfffd, 0x00A7,
- 0x00A4, 0x00A9, 0x00AA, 0x00AB, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0xfffd, 0x00B5, 0x00B6, 0x00B7,
- 0xfffd, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0xfffd, 0x00BF,
- 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0xfffd, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0152,
- 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0xfffd, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0xfffd, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0153,
- 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0xfffd, 0x00FF
-};
-
-struct x_to_unicode u_hproman8 = {
- 96, 32, X2U_STD, AL_ROMAN, "Hewlett Packard Roman 8", "hp-roman8", 0, NULL,
- 0x00a0, 0x00c0, 0x00c2, 0x00c8, 0x00ca, 0x00cb, 0x00ce, 0x00cf,
- 0x00b4, 0x00a6, 0x00a9, 0x00a8, 0x00ac, 0x00d9, 0x00db, 0x20a4,
- 0x00af, 0x00dd, 0x00fd, 0x00b0, 0x00c7, 0x00e7, 0x00d1, 0x00f1,
- 0x00a1, 0x00bf, 0x00a4, 0x00a3, 0x00a5, 0x00a7, 0x0192, 0x00a2,
- 0x00e2, 0x00ea, 0x00f4, 0x00fb, 0x00e1, 0x00e9, 0x00f3, 0x00fa,
- 0x00e0, 0x00e8, 0x00f2, 0x00f9, 0x00e4, 0x00eb, 0x00f6, 0x00fc,
- 0x00c5, 0x00ee, 0x00d8, 0x00c6, 0x00e5, 0x00ed, 0x00f8, 0x00e6,
- 0x00c4, 0x00ec, 0x00d6, 0x00dc, 0x00c9, 0x00ef, 0x00df, 0x00d4,
- 0x00c1, 0x00c3, 0x00e3, 0x00d0, 0x00f0, 0x00cd, 0x00cc, 0x00d3,
- 0x00d2, 0x00d5, 0x00f5, 0x0160, 0x0161, 0x00da, 0x00b8, 0x00ff,
- 0x00de, 0x00fe, 0x00b7, 0x00b5, 0x00b6, 0x00be, 0x2015, 0x00bc,
- 0x00bd, 0x00aa, 0x00ba, 0x00ab, 0x2588, 0x00bb, 0x00b1, 0xfffd
-};
-
-struct x_to_unicode u_dgi = {
- 96,32,X2U_STD,AL_ROMAN,"Data General International","dg-international",0,NULL,
- 0x00a0, 0x00ac, 0x00bd, 0x00b5, 0x00b2, 0x00b3, 0x00a4, 0x00a2,
- 0x00a3, 0x00aa, 0x00ba, 0x00a1, 0x00bf, 0x00a9, 0x00ae, 0x2021,
- 0x00bb, 0x00ab, 0x00b6, 0x2122, 0x0192, 0x00a5, 0x00b1, 0x2264,
- 0x2265, 0x00b7, 0x00b8, 0x00a7, 0x00b0, 0x00a8, 0x00b4, 0x2191,
- 0x00c1, 0x00c0, 0x00c2, 0x00c4, 0x00c3, 0x00c5, 0x00c6, 0x00c7,
- 0x00c9, 0x00c8, 0x00ca, 0x00cb, 0x00cd, 0x00cc, 0x00ce, 0x00cf,
- 0x00d1, 0x00d3, 0x00d2, 0x00d4, 0x00d6, 0x00d5, 0x00d8, 0x0276,
- 0x00da, 0x00d9, 0x00db, 0x00dc, 0xfffd, 0x0178, 0xfffd, 0xfffd,
- 0x00e1, 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e6, 0x00e7,
- 0x00e9, 0x00e8, 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef,
- 0x00f1, 0x00f3, 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00f8, 0x0153,
- 0x00fa, 0x00f9, 0x00fb, 0x00fc, 0x00df, 0x00ff, 0xfffd, 0x2588
-};
-
-struct x_to_unicode u_nextstep = {
- 128, 0, 0, AL_ROMAN,"NeXTSTEP Multinational","next-multinational",0,NULL,
- 0x00a0, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c7,
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
- 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d9,
- 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00b5, 0x00d7, 0x00f7,
- 0x00a9, 0x00a1, 0x00a2, 0x00a3, 0x2044, 0x00a5, 0x0192, 0x00a7,
- 0x00a4, 0x2019, 0x201c, 0x00ab, 0x2039, 0x203a, 0xfb01, 0xfb02,
- 0x00ae, 0x2013, 0x2020, 0x2021, 0x00b7, 0x00a6, 0x00b6, 0x2022,
- 0x201a, 0x201e, 0x201d, 0x00bb, 0x2026, 0x2030, 0x00ac, 0x00bf,
- 0x00b9, 0x02cb, 0x00b4, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9,
- 0x00a8, 0x00b2, 0x02da, 0x00b8, 0x00b3, 0x02dd, 0x02db, 0x02c7,
- 0x2014, 0x00b1, 0x00bc, 0x00bd, 0x00be, 0x00e0, 0x00e1, 0x00e2,
- 0x00e3, 0x00e4, 0x00e5, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb,
- 0x00ec, 0x00c6, 0x00ed, 0x00aa, 0x00ee, 0x00ef, 0x00f0, 0x00f1,
- 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00f2, 0x00f3, 0x00f4, 0x00f5,
- 0x00f6, 0x00e6, 0x00f9, 0x00fa, 0x00fb, 0x0131, 0x00fc, 0x00fd,
- 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x00ff, 0xfffd, 0xfffd
-};
-
-struct x_to_unicode u_maclatin = {
- 128, 0, 0, AL_ROMAN,"Macintosh Latin","maclatin", 0, NULL,
- 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1,
- 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8,
- 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3,
- 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC,
- 0x00DD, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF,
- 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8,
- 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211,
- 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x2126, 0x00E6, 0x00F8,
- 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB,
- 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153,
- 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA,
- 0x00FF, 0x0178, 0x2044, 0x00A4, 0x00D0, 0x00F0, 0x00DE, 0x00FE,
- 0x00FD, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1,
- 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4,
- 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC,
- 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7
-};
-
-struct x_to_unicode u_quickdraw = {
- 128, 0, 0, AL_ROMAN,"QuickDraw","quickdraw", 0, NULL,
- 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1,
- 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8,
- 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3,
- 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC,
- 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF,
- 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8,
- 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211,
- 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8,
- 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB,
- 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153,
- 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA,
- 0x00FF, 0x0178, 0x2044, 0x00A4, 0x2039, 0x203A, 0xFB01, 0xFB02,
- 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1,
- 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4,
- 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC,
- 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7
-};
-
-/* DEC special graphics / technical sets for VT emulation */
-
-#ifdef KERMITFONT
-struct x_to_unicode u_dectech = {
- 94, 33, X2U_DEC|X2U_STD,AL_ROMAN,"DEC Technical", "dec-technical", 0, ">",
- 0xE400, 0x250c, 0x2500, 0x2320, 0x2321, 0x2502, 0xE204,
- 0xE203, 0xE209, 0xE208, 0xE202, 0xE201, 0xE207, 0xE206, 0xE200,
- 0xE205, 0xE20D, 0xE20C, 0x2572, 0x2571, 0xE20E, 0xE20F, 0x232a,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2264, 0x2260, 0x2265, 0x222b,
- 0x2234, 0x221d, 0x221e, 0x00f7, 0x2206, 0x2207, 0x03a6, 0x0393,
- 0x223c, 0x2243, 0x0398, 0x00d7, 0x039b, 0x21d4, 0x21d2, 0x2261,
- 0x220f, 0x03a8, 0xE401, 0x03a3, 0xFFFD, 0xfffd, 0x221a, 0x03a9,
- 0x039e, 0x03d2, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228,
- 0x00ac, 0x03b1, 0x03b2, 0x03c7, 0x03b4, 0x03b5, 0x03c6, 0x03b3,
- 0x03b7, 0x03b9, 0x03b8, 0x03ba, 0x03bb, 0xFFFD, 0x03bd, 0x2202,
- 0x03c0, 0x03c8, 0x03c1, 0x03c3, 0x03c4, 0xFFFD, 0x0192, 0x03c9,
- 0x03be, 0x03c5, 0x03b6, 0x2190, 0x2191, 0x2192, 0x2193
-};
-#else
-struct x_to_unicode u_dectech = {
- 94, 33, X2U_DEC|X2U_STD,AL_ROMAN,"DEC Technical", "dec-technical", 0, ">",
- 0x221a, 0x250c, 0x2500, 0x2320, 0x2321, 0x2502, 0x2308, /* 21-27 */
- 0x230a, 0x2309, 0x230b, 0x256d, 0x2570, 0x256e, 0x256f, 0x2525, /* 28-2f */
- 0x251d, 0x2211, 0x2211, 0x2572, 0x2571, 0x231d, 0x231f, 0x232a, /* 30-37 */
- 0x005b, 0x2022, 0x005d, 0x00b1, 0x2264, 0x2260, 0x2265, 0x222b, /* 38-3f */
- 0x2234, 0x221d, 0x221e, 0x00f7, 0x25b3, 0x25bd, 0x03a6, 0x0393, /* 40-47 */
- 0x223c, 0x2243, 0x0398, 0x00d7, 0x039b, 0x21d4, 0x21d2, 0x2261, /* 48-4f */
- 0x220f, 0x03a8, 0x2218, 0x2211, 0x00a7, 0x00b6, 0x221a, 0x03a9, /* 50-57 */
- 0x039e, 0x03d2, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 58-5f */
- 0x00ac, 0x03b1, 0x03b2, 0x03c7, 0x03b4, 0x03b5, 0x03c6, 0x03b3, /* 60-67 */
- 0x03b7, 0x03b9, 0x03b8, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x2202, /* 68-6f */
- 0x03c0, 0x03c8, 0x03c1, 0x03c3, 0x03c4, 0x0020, 0x0192, 0x03c9, /* 70-77 */
- 0x03be, 0x03c5, 0x03b6, 0x2190, 0x2191, 0x2192, 0x2193 /* 78-7e */
-};
-#endif /* KERMITFONT */
-
-#ifdef KERMITFONT
-struct x_to_unicode u_decspec = {
- 94,33,X2U_DEC|X2U_STD,AL_ROMAN,"DEC Special Graphics","dec-special",0,"0",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
- 0x2666, 0x2591, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
- 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23BA,
- 0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251c, 0x2524, 0x2534, 0x252c,
- 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00B7
-};
-#else
-struct x_to_unicode u_decspec = {
- 94,33,X2U_DEC|X2U_STD,AL_ROMAN,"DEC Special Graphics","dec-special",0,"0",
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
- 0x2666, 0x2591, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
- 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2594,
- 0x2500, 0x2500, 0x2500, 0x2500, 0x251c, 0x2524, 0x2534, 0x252c,
- 0x2502, 0x2264, 0x2265, 0x03a0, 0x2260, 0x00a3, 0x00B7
-};
-#endif /* KERMITFONT */
-
-/*
- Hazeltine 1500/1520 graphic set. Includes several approximations:
- . (0,9) should be heavy black right arrow. Unicode has one of these
- at U+27A1 but...
- . (3,9) should be heavy black down arrow; Unicode doesn't have one.
- So we use the white versions of the heavy arrows instead.
- . (1,9) the letters "Pe" in one cell, doesn't exist in Unicode.
- Substitution is just "P".
-*/
-struct x_to_unicode u_hz1500 = {
- 94,33,X2U_STD,AL_ROMAN,"Hazeltime Graphics","hz1500-graphics",0,"0",
-/* 0 1 2 3 4 5 6 7 */
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, /* 0 */
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, /* 1 */
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, /* 2 */
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, /* 3 */
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, /* 4 */
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, /* 5 */
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, /* 6 */
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, /* 7 */
- 0x2500, 0x2502, 0x253c, 0x2534, 0x252c, 0x2514, 0x250c, 0x00b1, /* 8 */
- 0x21e8, 0x0050, 0x00f7, 0x21e9, 0x2510, 0x2518, 0x251c, 0x2524, /* 9 */
- 0x0070, 0x0071, 0x0072, 0x250c, 0x0074, 0x0075, 0x0076, 0x0077, /* a */
- 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e /* b */
-
-};
-
-#ifdef KERMITFONT
-struct x_to_unicode u_heath19g = {
- 94,33,X2U_STD,AL_ROMAN,"Heath-19 Special Graphics","h19-special",0,NULL,
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x25cf, 0xe30b,
- 0x2502, 0x2500, 0x253c, 0x2510, 0x2518, 0x2514, 0x250c, 0x00b1,
- 0x2192, 0x2592, 0x00f7, 0x2193, 0xe321, 0xe320, 0xe322, 0xe328,
- 0x2580, 0xe325, 0xe30a, 0x252c, 0x2524, 0x2534, 0x251c, 0x2573,
- 0x2571, 0x2572, 0xe311, 0xe319, 0xe300, 0xe309, 0x00b6
-};
-#else
-struct x_to_unicode u_heath19g = {
- 94,33,X2U_STD,AL_ROMAN,"Heath-19 Special Graphics","h19-special",0,NULL,
- 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x25cf, 0x25e5,
- 0x2502, 0x2500, 0x253c, 0x2510, 0x2518, 0x2514, 0x250c, 0x00b1,
- 0x2192, 0x2592, 0x00f7, 0x2193, 0x2590, 0x258c, 0x258c, 0x2590,
- 0x2580, 0x2590, 0x25e4, 0x252c, 0x2524, 0x2534, 0x251c, 0x2573,
- 0x2571, 0x2572, 0x2500, 0x2500, 0x2502, 0x2502, 0x00b6
-};
-#endif /* KERMITFONT */
-
-/* DG Graphic sets - "KERMITFONT" these later... */
-
-/* Missing, backwards question mark
- eighth note
- "DT" control pic
- horizontal scan lines
-*/
-struct x_to_unicode u_dgspec = { /* Needs to be checked */
- 94, 33, X2U_STD,AL_ROMAN,"DG Special Graphics","dg-specialgraphics",0,NULL,
- 0xfffd, 0xfffd, 0x2424, 0x2594, 0x2594, 0x2581, 0x2581,
- 0x25a1, 0x263a, 0x263b, 0x2665, 0x2663, 0x2660, 0x25cf, 0x25d8,
- 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266c, 0x263c, 0x2195,
- 0x2583, 0x21a8, 0x231e, 0x2194, 0x2207, 0x00ff, 0x20a7, 0x00aa,
- 0x00ba, 0x231c, 0x231d, 0x2591, 0x2591, 0x2593, 0x2561, 0x2562,
- 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b,
- 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550,
- 0x256c, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552,
- 0x2553, 0x256b, 0x256a, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
- 0x0393, 0x03c0, 0x03a3, 0x03a6, 0x0398, 0x03d5, 0x03b5, 0x03a0,
- 0x039e, 0x00b7, 0x03b7, 0x25a0, 0x0178, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd
-};
-
-/* Missing: arrow-to-line, various orientations */
-
-struct x_to_unicode u_dgline = {
- 94, 33, X2U_STD,AL_ROMAN,"DG Line Drawing","dg-linedrawing",0,NULL,
- 0x250c, 0x2510, 0x2514, 0x2518, 0x252c, 0x2524, 0x251c,
- 0x2534, 0x253c, 0x2502, 0x2500, 0x219f, 0x21e5, 0x21e4, 0x21a1,
- 0x2506, 0x250f, 0x2513, 0x2517, 0x251b, 0x2533, 0x252b, 0x2523,
- 0x253b, 0x254b, 0x2503, 0x2501, 0x2504, 0x00f7, 0x00a2, 0x2122,
- 0x00ae, 0x00a9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd
-};
-
-struct x_to_unicode u_dgword = {
- 94, 33, X2U_STD,AL_ROMAN,"DG Word Processing","dg-wordprocessing",0,NULL,
- 0x2308, 0x230a, 0x2309, 0x230b, 0x0192, 0x223c, 0x2202,
- 0xfffd, 0xfffd, 0x2320, 0x2321, 0x221a, 0xfffd, 0x221e, 0x221d,
- 0x2070, 0x00b9, 0x00b2, 0x00b3, 0x2074, 0x2075, 0x2076, 0x2077,
- 0x2078, 0x2079, 0x2260, 0xfffd, 0x21ef, 0xfffd, 0x21e5, 0x00b7,
- 0x203c, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
- 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
- 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8,
- 0x03c9, 0x03a9, 0x0394, 0x00b6, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x22a6, 0x25c6, 0x25b6, 0x25b7, 0x25c0, 0x25b2, 0x25bc, 0x2327,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x25e3, 0x25e2,
- 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087,
- 0x2088, 0x2089, 0xfffd, 0x2191, 0x2192, 0x2190, 0x2193
-};
-
-/* HP Graphic sets - "KERMITFONT" these later... */
-
-/*
- Many are missing from Unicode,
- Single-to-triple-line box-drawing characters.
- Double/double cross & some others.
-*/
-struct x_to_unicode u_hpline = { /* Needs to be checked */
- 94, 33, X2U_STD,AL_ROMAN,"HP Line Drawing Graphics",
- "hp-line-drawing",0,NULL,
- 0x2520, 0x2528, 0x252f, 0x2537, 0x255f, 0x2562, 0x2564,
- 0x2567, 0x2551, 0x2542, 0x253f, 0x2550, 0x230a, 0x2502, 0x253c,
- 0x254b, 0x2523, 0x252b, 0x2533, 0x253b, 0x251c, 0x2524, 0x252c,
- 0x2534, 0x2550, 0x2503, 0x2501, 0x256b, 0x2308, 0x256a, 0x256c,
- 0x255e, 0x2517, 0x2549, 0x2588, 0x258c, 0x258e, 0x2514, 0x2518,
- 0x2510, 0x2555, 0x252c, 0x2556, 0x2556, 0x2547, 0x2548, 0x2555,
- 0x230b, 0x250f, 0x250c, 0x251b, 0x2510, 0x2524, 0x254a, 0x2513,
- 0x2584, 0x2309, 0x2582, 0x2561, 0x2504, 0x2559, 0x2576, 0x2565,
- 0x255e, 0x2517, 0x2549, 0x2588, 0x258c, 0x258e, 0x2514, 0x2518,
- 0x2510, 0x2555, 0x252c, 0x2556, 0x2556, 0x2547, 0x2548, 0x2555,
- 0x230b, 0x250f, 0x250c, 0x251b, 0x2510, 0x2524, 0x254a, 0x2513,
- 0x2584, 0x2309, 0x2582, 0x2561, 0x2504, 0x2559, 0x2576
-};
-
-struct x_to_unicode u_hpmath = {
- 94, 33, X2U_STD,AL_ROMAN,"HP Math/Technical","hp-math/technical",0,NULL,
- 0x221a, 0x2223, 0x00a7, 0x2207, 0x00b1, 0x03b1, 0x2320,
- 0x00f7, 0x2243, 0x03a0, 0x0393, 0x03c8, 0x2261, 0x03a6, 0x039e,
- 0x2070, 0x00b9, 0x00b2, 0x00b3, 0x2074, 0x2075, 0x2076, 0x2077,
- 0x2078, 0x2079, 0x03a9, 0x039b, 0x221e, 0x2321, 0x2020, 0x03a3,
- 0x00b6, 0x03b1, 0x03b2, 0x03c8, 0x03d5, 0x03b5, 0x2202, 0x03bb,
- 0x03b7, 0x03b9, 0x0398, 0x03ba, 0x03c9, 0x03bc, 0x03bd, 0x03c1,
- 0x03c0, 0x03b3, 0x03b8, 0x03c3, 0x03c4, 0x03be, 0x0394, 0x03b4,
- 0x00d7, 0x03c5, 0x03b6, 0x2191, 0x2192, 0x03d2, 0x2190, 0x2193,
- 0x00b6, 0x03b1, 0x03b2, 0x03c8, 0x03d5, 0x03b5, 0x2202, 0x03bb,
- 0x03b7, 0x03b9, 0x0398, 0x03ba, 0x03c9, 0x03bc, 0x03bd, 0x03c1,
- 0x03c0, 0x03b3, 0x03b8, 0x03c3, 0x03c4, 0x03be, 0x0394, 0x03b4,
- 0x00d7, 0x03c5, 0x03b6, 0x2191, 0x2192, 0x03d2, 0x2190
-};
-
-struct x_to_unicode u_tvig = {
- 15,65,0,0,"Televideo Special Graphics","tvi-special",0,NULL,
- 0x2570, 0x256D, 0x256E, 0x256F, 0x2514, 0x250C, 0x2510,
- 0x2518, 0x253C, 0x2502, 0x2500, 0x2524, 0x251C, 0x252C, 0x2534
-};
-
-struct x_to_unicode u_wyse_gn = {
-#ifdef COMMENT
- 16,16,0,0,"Wyse Normal-Mode Graphics","wy-graphics-normal",0,NULL,
- 0x252C, 0x2514, 0x250C, 0x2510, 0x251C, 0x2518, 0x2502, 0x2588,
- 0x253C, 0x2524, 0x2500, 0x2592, 0x2550, 0x2534, 0x2551, 0x2591
-#else
- 80,48,0,0,"Wyse Normal-Mode Graphics","wy-graphics-normal",0,NULL,
- 0x252C, 0x2514, 0x250C, 0x2510, 0x251C, 0x2518, 0x2502, 0x2588,
- 0x253C, 0x2524, 0x2500, 0x2592, 0x2550, 0x2534, 0x2551, 0x2591,
- 0x252C, 0x2514, 0x250C, 0x2510, 0x251C, 0x2518, 0x2502, 0x2588,
- 0x253C, 0x2524, 0x2500, 0x2592, 0x2550, 0x2534, 0x2551, 0x2591,
- 0x252C, 0x2514, 0x250C, 0x2510, 0x251C, 0x2518, 0x2502, 0x2588,
- 0x253C, 0x2524, 0x2500, 0x2592, 0x2550, 0x2534, 0x2551, 0x2591,
- 0x252C, 0x2514, 0x250C, 0x2510, 0x251C, 0x2518, 0x2502, 0x2588,
- 0x253C, 0x2524, 0x2500, 0x2592, 0x2550, 0x2534, 0x2551, 0x2591,
- 0x252C, 0x2514, 0x250C, 0x2510, 0x251C, 0x2518, 0x2502, 0x2588,
- 0x253C, 0x2524, 0x2500, 0x2592, 0x2550, 0x2534, 0x2551, 0x2591
-#endif /* COMMENT */
-};
-
-struct x_to_unicode u_wyse_g1 = {
- 79,48,0,0,"Wyse Graphics 1","wy-graphics-1",0,NULL,
- 0x2070, 0x00B9, 0x00B2, 0x00B3, 0x2074, 0x2075, 0x2075, 0x2077,
- 0x2078, 0x2079, 0xFFFD, 0xFFFD, 0x25BA, 0x25C4, 0x25B2, 0x25BC,
- 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
- 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
- 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
- 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
- 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087,
- 0x2088, 0x2089, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x258C,
- 0x2590, 0x2500, 0x2584, 0x2580, 0x251C, 0x2524, 0x2534, 0x252C,
- 0x2502, 0xFFFD, 0x256E, 0x256F, 0x2570, 0x256D, 0x258C
-};
-
-struct x_to_unicode u_wyse_g2 = {
- 41,64,0,0,"Wyse Graphics 2","wy-graphics-2",0,NULL,
- 0x250C, 0xFFFD, 0xFFFD, 0xFFFD, 0x2510, 0xFFFD, 0xFFFD, 0xFFFD,
- 0x2514, 0xFFFD, 0xFFFD, 0xFFFD, 0x2518, 0xFFFD, 0xFFFD, 0xFFFD,
- 0x252C, 0xFFFD, 0xFFFD, 0xFFFD, 0x2524, 0xFFFD, 0xFFFD, 0xFFFD,
- 0x251C, 0xFFFD, 0xFFFD, 0xFFFD, 0x2534, 0xFFFD, 0xFFFD, 0xFFFD,
- 0x2500, 0xFFFD, 0xFFFD, 0xFFFD, 0x2502, 0xFFFD, 0xFFFD, 0xFFFD,
- 0x253C
-};
-
-#ifdef KERMITFONT
-struct x_to_unicode u_wyse_g3 = {
- 31,65,0,0,"Wyse Graphics 3","wy-graphics-3",0,NULL,
- 0x2570, 0x256D, 0x256E, 0x256F, 0x2514, 0x250C, 0x2510,
- 0x2518, 0x253C, 0x2502, 0x2500, 0x2524, 0x251C, 0x252C, 0x2534,
- 0x23BA, 0x23BD, 0x2666, 0xE328, 0xE321, 0xE320, 0xE322, 0x2590,
- 0x2584, 0x258C, 0x2580, 0xE323, 0xE326, 0xE327, 0xE329, 0x258C
-};
-#else
-struct x_to_unicode u_wyse_g3 = {
- 31,65,0,0,"Wyse Graphics 3","wy-graphics-3",0,NULL,
- 0x2570, 0x256D, 0x256E, 0x256F, 0x2514, 0x250C, 0x2510,
- 0x2518, 0x253C, 0x2502, 0x2500, 0x2524, 0x251C, 0x252C, 0x2534,
- 0x2500, 0x2500, 0x2666, 0x2590, 0x2590, 0x258c, 0x258c, 0x2590,
- 0x2584, 0x258C, 0x2580, 0x2588, 0x2588, 0x2588, 0x2588, 0x258C
-};
-#endif /* KERMITFONT */
-/*
- QNX Console -- This is exactly the same as CP437 except for the code
- point at 0xEE (epsilon vs element-of), which I think was just a mistake
- in reading glyphs by the QNX people, but who knows. Also the glyph at
- 0xED might be a fi (as it is in CP437, and as I have it here) or it might
- be a null-set symbol.
-*/
-struct x_to_unicode u_qnxgrph = {
- 128,0,0,0,"QNX Console","qnx-console",0,NULL,
- 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, /* 128 */
- 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, /* 136 */
- 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, /* 144 */
- 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, /* 152 */
- 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, /* 160 */
- 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, /* 168 */
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, /* 176 */
- 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, /* 184 */
- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, /* 192 */
- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, /* 200 */
- 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, /* 208 */
- 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, /* 216 */
- 0x221d, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, /* 224 */
- 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x2208, 0x2229, /* 232 */
- 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, /* 240 */
- 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25ae, 0x00a0 /* 248 */
-};
-
-struct x_to_unicode u_snibrack = {
- 94, 33, 0, 0,"Siemens Nixdorf 97801 Brackets","sni-brackets",0,"w",
- 0x2590, 0x258c, 0x2584, 0x2580, 0x2590, 0x258c, 0x2584, /* a0-7 */
- 0x2580, 0x2329, 0x2327, 0x25af, 0x00b7, 0x25b9, 0x25c1, 0x003c, /* a8-f */
- 0x253b, 0x2533, 0x2523, 0x252b, 0x2329, 0x232a, 0x2304, 0x2303, /* b0-7 */
- 0x25e4, 0x25e5, 0x25e3, 0x25e2, 0x253f, 0x231b, 0x25cf, 0x25cb, /* b8-f */
- 0x2502, 0x2500, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, /* c0-7 */
- 0x252c, 0x2534, 0x253c, 0x2192, 0x2190, 0x2191, 0x2193, 0x2575, /* c8-f */
- 0x2577, 0x25d4, 0x256d, 0x256e, 0x2570, 0x256f, 0x251c, 0x2524, /* d0-7 */
- 0x252c, 0x2534, 0x253c, 0x253c, 0x2592, 0x2591, 0x2592, 0x2593, /* d8-f */
- 0x2503, 0x2501, 0x250f, 0x2513, 0x2517, 0x251b, 0x2523, 0x252b, /* e0-7 */
- 0x2533, 0x253b, 0x254b, 0x279e, 0x2190, 0x2191, 0x2193, 0x2579, /* e8-f */
- 0x257b, 0x2261, 0x2554, 0x2557, 0x255a, 0x255d, 0x2523, 0x252b, /* f0-7 */
- 0x2533, 0x253b, 0x254b, 0x254b, 0x0393, 0x03c3, 0x03c4 /* f8-f */
-};
-
-struct x_to_unicode u_sniblanks = {
- 94, 33, 0, 0,"Siemens Nixdorf 97801 Blanks","sni-blanks",0,"y",
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* a0-7 */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* a8-f */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* b0-7 */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* b8-f */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* c0-7 */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* c8-f */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* d0-7 */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* d8-f */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* e0-7 */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* e8-f */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, /* f0-7 */
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 /* f8-f */
-};
-
-struct x_to_unicode u_snifacet = {
- 94, 33, 0, 0,"Siemens Nixdorf 97801 Facet","sni-facet",0,"c",
- 0x0020, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2587, /* a1-a7 */
- 0x005f, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, 0x2587, /* a8-af */
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, /* b0-b7 */
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, /* b8-bf */
- 0x2503, 0x2501, 0x250f, 0x2513, 0x2517, 0x251b, 0x2523, 0x252b, /* c0-c7 */
- 0x2533, 0x253b, 0x254b, 0x258f, 0x2595, 0xfffd, 0xfffd, 0xfffd, /* c8-cf */
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, /* d0-d7 */
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2591, 0x2591, 0x2588, /* d8-df */
- 0x2503, 0x2501, 0x250f, 0x2513, 0x2517, 0x251b, 0x2523, 0x252b, /* e0-e7 */
- 0x2533, 0x253b, 0x254b, 0xfffd, 0xfffd, 0x2593, 0x2593, 0x0020, /* e8-ef */
- 0x2585, 0x2586, 0x2587, 0x2588, 0xfffd, 0xfffd, 0xfffd, 0xfffd, /* f0-f7 */
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2594, 0x2594, 0xfffd /* f8-fe */
-};
-
-struct x_to_unicode u_sniibm = {
- 94, 33, 0, 0,"Siemens Nixdorf 97801 IBM","sni-ibm",0,"v",
- 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x25cf,
- 0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
- 0x25ba, 0x25c4, 0x2195, 0x203c, 0x00b6, 0x25c1, 0x2582, 0x21a8,
- 0x2191, 0x2193, 0x2192, 0x2190, 0x2319, 0x2194, 0x25b4, 0x25be,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, /* Hex */
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, /* bytes */
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0x2070, 0x00b9, 0x00b2, 0x00b3, 0x2074, 0x2075, 0x2076, 0x2077,
- 0x2078, 0x2079, 0x207b, 0x207a, 0xfffd, 0xfffd, 0x2320, 0x2321,
- 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087,
- 0x2088, 0x2089, 0x208b, 0x208a, 0x221e, 0x03b1, 0x03a6
-};
-
-struct x_to_unicode u_snieuro = {
- 94, 33, 0, 0,"Siemens Nixdorf 97801 Euro","sni-euro",0,"u",
- 0x00e0, 0x00e1, 0x00e2, 0x00e4, 0x00e5, 0x0105, 0x00e3,
- 0x0103, 0x00e6, 0x00e7, 0x010d, 0x0107, 0x00f0, 0x0111, 0x010f,
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x011b, 0x0119, 0x011f, 0x0131,
- 0x00ee, 0x00ec, 0x01d0, 0x00ef, 0x0133, 0x013a, 0x0142, 0x013e,
- 0x0148, 0x0144, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f6, 0x00f5,
- 0x00f8, 0x0151, 0x0153, 0x00fe, 0x0159, 0x0155, 0x0161, 0x015b,
- 0x015f, 0x00df, 0x0163, 0x0165, 0x00f9, 0x00fa, 0x00fb, 0x00fc,
- 0x016f, 0x0171, 0x00fd, 0x00ff, 0x017e, 0x017a, 0x017c, 0x00c9,
- 0x00c5, 0x00c6, 0x00d0, 0x0130, 0x0132, 0x0167, 0x00d8, 0x0152,
- 0x00de, 0x00c4, 0x00d6, 0x00dc, 0x00a7, 0x0024, 0x00a3, 0x00ae,
- 0x00a9, 0x03a9, 0x00b5, 0x00b0, 0x00c7, 0x20a7, 0x03c0, 0x02d8,
- 0x00b4, 0x02dd, 0x00d1, 0x2514, 0x2518, 0x007e, 0x02c7
-};
-
-struct x_to_unicode u_smiley = {
- 32,0,X2U_CXG,0,"PC C0 Graphics","smiley-faces",0,NULL,
- 0x00a0, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
- 0x25d8, 0x25ef, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266c, 0x263c,
- 0x25ba, 0x25c4, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
- 0x2191, 0x2193, 0x2192, 0x2190, 0x2319, 0x2194, 0x25b2, 0x25bc
-};
-
-struct x_to_unicode u_c0pics = {
- 128,0,X2U_CXG,0,"C0/C1 Display Controls","display-controls",0,NULL,
- 0x2400, 0x2401, 0x2402, 0x2403, 0x2404, 0x2405, 0x2406, 0x2407,
- 0x2408, 0x2409, 0x240a, 0x240b, 0x240c, 0x240d, 0x240e, 0x240f,
- 0x2410, 0x2411, 0x2412, 0x2413, 0x2414, 0x2415, 0x2416, 0x2417,
- 0x2418, 0x2419, 0x241a, 0x241b, 0x241c, 0x241d, 0x241e, 0x241f,
- 0x2420, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2421
-};
-
-#ifdef KERMITFONT
-struct x_to_unicode u_c1pics = {
- 32,0,X2U_CXG,0,"C1 Display Controls","c1-display-controls",0,NULL,
- 0xe080, 0xe081, 0xe082, 0xe083, 0xe084, 0xe085, 0xe086, 0xe087,
- 0xe088, 0xe089, 0xe08a, 0xe08b, 0xe08c, 0xe08d, 0xe08e, 0xe08f,
- 0xe090, 0xe091, 0xe092, 0xe093, 0xe094, 0xe095, 0xe096, 0xe097,
- 0xe098, 0xe099, 0xe09a, 0xe09b, 0xe09c, 0xe09d, 0xe09e, 0xe09f
-};
-#else
-struct x_to_unicode u_c1pics = {
- 32,0,X2U_CXG,0,"C1 Display Controls","c1-display-controls",0,NULL,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd
-};
-#endif /* KERMITFONT */
-
-
-/* Blah-to-Unicode functions */
-
-USHORT
-#ifdef CK_ANSIC
-ascii_u(CHAR c)
-#else
-ascii_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
-/*
- NOTE: Strict ANSI compilers complain about "<" and similar comparisons
- between unsigned and signed quantities, as found in all the routines of
- the "blah_u()" class -- casts must be added to squelch the warnings.
-*/
- if (c < u_ascii.offset)
- return(c);
- else if (c >= u_ascii.offset + u_ascii.size)
- return(c);
- else
- return(u_ascii.map[c - u_ascii.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-british_u(CHAR c)
-#else
-british_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_british.offset)
- return(c);
- else if (c >= u_british.offset + u_british.size)
- return(c);
- else
- return(u_british.map[c - u_british.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-dutch_u(CHAR c)
-#else
-dutch_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_dutch.offset)
- return(c);
- else if (c >= u_dutch.offset + u_dutch.size)
- return(c);
- else
- return(u_dutch.map[c - u_dutch.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-finnish_u(CHAR c)
-#else
-finnish_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_finnish.offset)
- return(c);
- else if (c >= u_finnish.offset + u_finnish.size)
- return(c);
- else
- return(u_finnish.map[c - u_finnish.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-french_u(CHAR c)
-#else
-french_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_french.offset)
- return(c);
- else if (c >= u_french.offset + u_french.size)
- return(c);
- else
- return(u_french.map[c - u_french.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-fr_canadian_u(CHAR c)
-#else
-fr_canadian_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_fr_canadian.offset)
- return(c);
- else if (c >= u_fr_canadian.offset + u_fr_canadian.size)
- return(c);
- else
- return(u_fr_canadian.map[c - u_fr_canadian.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-german_u(CHAR c)
-#else
-german_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_german.offset)
- return(c);
- else if (c >= u_german.offset + u_german.size)
- return(c);
- else
- return(u_german.map[c - u_german.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-hungarian_u(CHAR c)
-#else
-hungarian_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_hungarian.offset)
- return(c);
- else if (c >= u_hungarian.offset + u_hungarian.size)
- return(c);
- else
- return(u_hungarian.map[c - u_hungarian.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-italian_u(CHAR c)
-#else
-italian_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_italian.offset)
- return(c);
- else if (c >= u_italian.offset + u_italian.size)
- return(c);
- else
- return(u_italian.map[c - u_italian.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-icelandic_u(CHAR c)
-#else
-icelandic_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_icelandic.offset)
- return(c);
- else if (c >= u_icelandic.offset + u_icelandic.size)
- return(c);
- else
- return(u_icelandic.map[c - u_icelandic.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-jis0201r_u(CHAR c)
-#else
-jis0201r_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_jis0201r.offset)
- return(c);
- else if (c >= u_jis0201r.offset + u_jis0201r.size)
- return(c);
- else
- return(u_jis0201r.map[c - u_jis0201r.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-jis0201k_u(CHAR c)
-#else
-jis0201k_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_jis0201k.offset)
- return(c);
- else if (c >= u_jis0201k.offset + u_jis0201k.size)
- return(c);
- else
- return(u_jis0201k.map[c - u_jis0201k.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-norwegian_u(CHAR c)
-#else
-norwegian_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_norwegian.offset)
- return(c);
- else if (c >= u_norwegian.offset + u_norwegian.size)
- return(c);
- else
- return(u_norwegian.map[c - u_norwegian.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-danish_u(CHAR c)
-#else
-danish_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_danish.offset)
- return(c);
- else if (c >= u_danish.offset + u_danish.size)
- return(c);
- else
- return(u_danish.map[c - u_danish.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-portuguese_u(CHAR c)
-#else
-portuguese_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_portuguese.offset)
- return(c);
- else if (c >= u_portuguese.offset + u_portuguese.size)
- return(c);
- else
- return(u_portuguese.map[c - u_portuguese.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-spanish_u(CHAR c)
-#else
-spanish_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_spanish.offset)
- return(c);
- else if (c >= u_spanish.offset + u_spanish.size)
- return(c);
- else
- return(u_spanish.map[c - u_spanish.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-swedish_u(CHAR c)
-#else
-swedish_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_swedish.offset)
- return(c);
- else if (c >= u_swedish.offset + u_swedish.size)
- return(c);
- else
- return(u_swedish.map[c - u_swedish.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-swiss_u(CHAR c)
-#else
-swiss_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_swiss.offset)
- return(c);
- else if (c >= u_swiss.offset + u_swiss.size)
- return(c);
- else
- return(u_swiss.map[c - u_swiss.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-apl1_u(CHAR c)
-#else
-apl1_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_apl1.offset)
- return(c);
- else if (c >= u_apl1.offset + u_apl1.size)
- return(c);
- else
- return(u_apl1.map[c - u_apl1.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-ident_u(CHAR c)
-#else /* CK_ANSIC */
-ident_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return((USHORT)c);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_1_u(CHAR c)
-#else
-iso_8859_1_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_1.offset)
- return(c);
- else if (c >= u_8859_1.offset + u_8859_1.size)
- return(c);
- else
- return(u_8859_1.map[c - u_8859_1.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_2_u(CHAR c)
-#else
-iso_8859_2_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_2.offset)
- return(c);
- else if (c >= u_8859_2.offset + u_8859_2.size)
- return(c);
- else
- return(u_8859_2.map[c - u_8859_2.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_3_u(CHAR c)
-#else
-iso_8859_3_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_3.offset)
- return(c);
- else if (c >= u_8859_3.offset + u_8859_3.size)
- return(c);
- else
- return(u_8859_3.map[c - u_8859_3.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_4_u(CHAR c)
-#else
-iso_8859_4_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_4.offset)
- return(c);
- else if (c >= u_8859_4.offset + u_8859_4.size)
- return(c);
- else
- return(u_8859_4.map[c - u_8859_4.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_5_u(CHAR c)
-#else
-iso_8859_5_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_5.offset)
- return(c);
- else if (c >= u_8859_5.offset + u_8859_5.size)
- return(c);
- else
- return(u_8859_5.map[c - u_8859_5.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-koi8_u(CHAR c)
-#else
-koi8_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_koi8.offset)
- return(c);
- else if (c >= u_koi8.offset + u_koi8.size)
- return(c);
- else
- return(u_koi8.map[c - u_koi8.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-koi8r_u(CHAR c) /* KOI8-R to Unicode */
-#else
-koi8r_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_koi8r.offset)
- return(c);
- else if (c >= u_koi8r.offset + u_koi8r.size)
- return(c);
- else
- return(u_koi8r.map[c - u_koi8r.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-koi8u_u(CHAR c)
-#else
-koi8u_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_koi8u.offset)
- return(c);
- else if (c >= u_koi8u.offset + u_koi8u.size)
- return(c);
- else
- return(u_koi8u.map[c - u_koi8u.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_6_u(CHAR c)
-#else
-iso_8859_6_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_6.offset)
- return(c);
- else if (c >= u_8859_6.offset + u_8859_6.size)
- return(c);
- else
- return(u_8859_6.map[c - u_8859_6.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_7_u(CHAR c)
-#else
-iso_8859_7_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_7.offset)
- return(c);
- else if (c >= u_8859_7.offset + u_8859_7.size)
- return(c);
- else
- return(u_8859_7.map[c - u_8859_7.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_8_u(CHAR c)
-#else
-iso_8859_8_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_8.offset)
- return(c);
- else if (c >= u_8859_8.offset + u_8859_8.size)
- return(c);
- else
- return(u_8859_8.map[c - u_8859_8.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-hebrew7_u(CHAR c)
-#else
-hebrew7_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_hebrew7.offset)
- return(c);
- else if (c >= u_hebrew7.offset + u_hebrew7.size)
- return(c);
- else
- return(u_hebrew7.map[c - u_hebrew7.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-elot927_u(CHAR c)
-#else
-elot927_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_elot927.offset)
- return(c);
- else if (c >= u_elot927.offset + u_elot927.size)
- return(c);
- else
- return(u_elot927.map[c - u_elot927.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_9_u(CHAR c)
-#else
-iso_8859_9_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_9.offset)
- return(c);
- else if (c >= u_8859_9.offset + u_8859_9.size)
- return(c);
- else
- return(u_8859_9.map[c - u_8859_9.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_10_u(CHAR c)
-#else
-iso_8859_10_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_10.offset)
- return(c);
- else if (c >= u_8859_10.offset + u_8859_10.size)
- return(c);
- else
- return(u_8859_10.map[c - u_8859_10.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-iso_8859_15_u(CHAR c)
-#else
-iso_8859_15_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_8859_15.offset)
- return(c);
- else if (c >= u_8859_15.offset + u_8859_15.size)
- return(c);
- else
- return(u_8859_15.map[c - u_8859_15.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-apl2_u(CHAR c)
-#else
-apl2_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_apl2.offset)
- return(c);
- else if (c >= u_apl2.offset + u_apl2.size)
- return(c);
- else
- return(u_apl2.map[c - u_apl2.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-apl3_u(CHAR c)
-#else
-apl3_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_apl3.offset)
- return(c);
- else if (c >= u_apl3.offset + u_apl3.size)
- return(c);
- else
- return(u_apl3.map[c - u_apl3.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-apl4_u(CHAR c)
-#else
-apl4_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_apl4.offset)
- return(c);
- else if (c >= u_apl4.offset + u_apl4.size)
- return(c);
- else
- return(u_apl4.map[c - u_apl4.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-apl5_u(CHAR c)
-#else
-apl5_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_apl5.offset)
- return(c);
- else if (c >= u_apl5.offset + u_apl5.size)
- return(c);
- else
- return(u_apl5.map[c - u_apl5.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-koi7_u(CHAR c)
-#else
-koi7_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c & 0x80)
- return(UNK);
- if (c < u_koi7.offset)
- return(c);
- else if (c >= u_koi7.offset + u_koi7.size)
- return(c);
- else
- return(u_koi7.map[c - u_koi7.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-decmcs_u(CHAR c)
-#else
-decmcs_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- c &= 0x7f;
- if (c < u_decmcs.offset)
- return(c);
- else if (c >= u_decmcs.offset + u_decmcs.size)
- return(c);
- else
- return(u_decmcs.map[c - u_decmcs.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-nextstep_u(CHAR c)
-#else
-nextstep_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_nextstep.map[(c & 0x7f) - u_nextstep.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-dgi_u(CHAR c)
-#else
-dgi_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- return(u_dgi.map[(c & 0x7f) - u_dgi.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-hproman8_u(CHAR c)
-#else
-hproman8_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x80 && c < 0xa0)
- return(c);
- return(u_hproman8.map[(c & 0x7f) - u_hproman8.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp37_u(CHAR c)
-#else
-cp37_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp37.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp437_u(CHAR c)
-#else
-cp437_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp437.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-mazovia_u(CHAR c) /* Mazovia = CP437 with substitutions */
-#else
-mazovia_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_mazovia.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp850_u(CHAR c)
-#else
-cp850_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp850.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp858_u(CHAR c)
-#else
-cp858_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp858.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp1250_u(CHAR c)
-#else
-cp1250_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp1250.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp1251_u(CHAR c)
-#else
-cp1251_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp1251.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp1252_u(CHAR c)
-#else
-cp1252_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp1252.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp1253_u(CHAR c)
-#else
-cp1253_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp1253.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp1254_u(CHAR c)
-#else
-cp1254_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp1254.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp1255_u(CHAR c)
-#else
-cp1255_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp1255.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp1256_u(CHAR c)
-#else
-cp1256_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp1256.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp1257_u(CHAR c)
-#else
-cp1257_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp1257.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp1258_u(CHAR c)
-#else
-cp1258_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp1258.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp852_u(CHAR c)
-#else
-cp852_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp852.map[c & 0x7f]);
-}
-
-USHORT /* Cyrillic */
-#ifdef CK_ANSIC
-cp855_u(CHAR c)
-#else
-cp855_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp855.map[c & 0x7f]);
-}
-
-USHORT /* Bulgaria */
-#ifdef CK_ANSIC
-cp856_u(CHAR c)
-#else
-cp856_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp856.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp857_u(CHAR c)
-#else
-cp857_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp857.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp862_u(CHAR c)
-#else
-cp862_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp862.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp864_u(CHAR c)
-#else
-cp864_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp864.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp866_u(CHAR c)
-#else
-cp866_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp866.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-cp869_u(CHAR c)
-#else
-cp869_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_cp869.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-maclatin_u(CHAR c)
-#else
-maclatin_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_maclatin.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-quickdraw_u(CHAR c)
-#else
-quickdraw_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- return(u_quickdraw.map[c & 0x7f]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-decspec_u(CHAR c)
-#else
-decspec_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_decspec.offset)
- return(c);
- else if (c >= u_decspec.offset + u_decspec.size)
- return(c);
- else
- return (u_decspec.map[c - u_decspec.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-dectech_u(CHAR c)
-#else
-dectech_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_dectech.offset)
- return(c);
- else if (c >= u_dectech.offset + u_dectech.size)
- return(c);
- else
- return(u_dectech.map[c - u_dectech.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-dgspec_u(CHAR c)
-#else
-dgspec_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_dgspec.offset)
- return(c);
- else if (c >= u_dgspec.offset + u_dgspec.size)
- return(c);
- else
- return(u_dgspec.map[c - u_dgspec.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-dgline_u(CHAR c)
-#else
-dgline_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_dgline.offset)
- return(c);
- else if (c >= u_dgline.offset + u_dgline.size)
- return(c);
- else
- return(u_dgline.map[c - u_dgline.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-dgword_u(CHAR c)
-#else
-dgword_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_dgword.offset)
- return(c);
- else if (c >= u_dgword.offset + u_dgword.size)
- return(c);
- else
- return(u_dgword.map[c - u_dgword.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-hpline_u(CHAR c)
-#else
-hpline_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_hpline.offset)
- return(c);
- else if (c >= u_hpline.offset + u_hpline.size)
- return(c);
- else
- return(u_hpline.map[c - u_hpline.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-hpmath_u(CHAR c)
-#else
-hpmath_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_hpmath.offset)
- return(c);
- else if (c >= u_hpmath.offset + u_hpmath.size)
- return(c);
- else
- return(u_hpmath.map[c - u_hpmath.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-qnxgrph_u(CHAR c)
-#else
-qnxgrph_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_qnxgrph.offset)
- return(c);
- else if (c >= u_qnxgrph.offset + u_qnxgrph.size)
- return(c);
- else
- return(u_qnxgrph.map[c - u_qnxgrph.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-hz1500_u(CHAR c)
-#else
-hz1500_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_hz1500.offset)
- return(c);
- else if (c >= u_hz1500.offset + u_hz1500.size)
- return(c);
- else
- return(u_hz1500.map[c - u_hz1500.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-sniblanks_u(CHAR c)
-#else
-sniblanks_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_sniblanks.offset)
- return(c);
- else if (c >= u_sniblanks.offset + u_sniblanks.size)
- return(c);
- else
- return(u_sniblanks.map[c - u_sniblanks.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-snibrack_u(CHAR c)
-#else
-snibrack_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_snibrack.offset)
- return(c);
- else if (c >= u_snibrack.offset + u_snibrack.size)
- return(c);
- else
- return(u_snibrack.map[c - u_snibrack.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-snifacet_u(CHAR c)
-#else
-snifacet_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_snifacet.offset)
- return(c);
- else if (c >= u_snifacet.offset + u_snifacet.size)
- return(c);
- else
- return(u_snifacet.map[c - u_snifacet.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-sniibm_u(CHAR c)
-#else
-sniibm_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_sniibm.offset)
- return(c);
- else if (c >= u_sniibm.offset + u_sniibm.size)
- return(c);
- else
- return(u_sniibm.map[c - u_sniibm.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-snieuro_u(CHAR c)
-#else
-snieuro_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_snieuro.offset)
- return(c);
- else if (c >= u_snieuro.offset + u_snieuro.size)
- return(c);
- else
- return(u_snieuro.map[c - u_snieuro.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-heath19g_u(CHAR c)
-#else
-heath19g_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_heath19g.offset)
- return(c);
- else if (c >= u_heath19g.offset + u_heath19g.size)
- return(c);
- else
- return(u_heath19g.map[c - u_heath19g.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-tvig_u(CHAR c)
-#else
-tvig_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_tvig.offset)
- return(c);
- else if (c >= u_tvig.offset + u_tvig.size)
- return(c);
- else
- return(u_tvig.map[c - u_tvig.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-wyse_gn_u(CHAR c)
-#else
-wyse_gn_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_wyse_gn.offset)
- return(c);
- else if (c >= u_wyse_gn.offset + u_wyse_gn.size)
- return(c);
- else
- return(u_wyse_gn.map[c - u_wyse_gn.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-wyse_g1_u(CHAR c)
-#else
-wyse_g1_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_wyse_g1.offset)
- return(c);
- else if (c >= u_wyse_g1.offset + u_wyse_g1.size)
- return(c);
- else
- return(u_wyse_g1.map[c - u_wyse_g1.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-wyse_g2_u(CHAR c)
-#else
-wyse_g2_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_wyse_g2.offset)
- return(c);
- else if (c >= u_wyse_g2.offset + u_wyse_g2.size)
- return(c);
- else
- return(u_wyse_g2.map[c - u_wyse_g2.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-wyse_g3_u(CHAR c)
-#else
-wyse_g3_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_wyse_g3.offset)
- return(c);
- else if (c >= u_wyse_g3.offset + u_wyse_g3.size)
- return(c);
- else
- return(u_wyse_g3.map[c - u_wyse_g3.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-smiley_u(CHAR c)
-#else
-smiley_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_smiley.offset)
- return(c);
- else if (c >= u_smiley.offset + u_smiley.size)
- return(c);
- else
- return(u_smiley.map[c - u_smiley.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-c0pics_u(CHAR c)
-#else
-c0pics_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_c0pics.offset)
- return(c);
- else if (c >= u_c0pics.offset + u_c0pics.size)
- return(c);
- else
- return(u_c0pics.map[c - u_c0pics.offset]);
-}
-
-USHORT
-#ifdef CK_ANSIC
-c1pics_u(CHAR c)
-#else
-c1pics_u(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- c &= 0x7f;
- if (c < u_c1pics.offset)
- return(c);
- else if (c >= u_c1pics.offset + u_c1pics.size)
- return(c);
- else
- return(u_c1pics.map[c - u_c1pics.offset]);
-}
-
-#ifdef KANJI /* Kanji/Unicode functions */
-
-static long /* Statistics counters */
- bad = 0, /* REMOVE THESE LATER... */
- kanji = 0,
- kana = 0,
- greek = 0,
- cyrillic = 0,
- special = 0,
- roman = 0;
-
-USHORT
-#ifdef CK_ANSIC
-sj_to_un(USHORT sj) /* Shift-JIS to Unicode */
-#else
-sj_to_un(sj) USHORT sj;
-#endif /* CK_ANSIC */
-{
-
-/* Kanji blocks */
-
- if (sj >= 0x8140) { /* All possible Kanjis */
- kanji++; /* Optimistically count a Kanji */
- if (sj <= 0x9ffc) { /* 7869-element table */
- return(sju_8140[sj - 0x8140]);
- } else if (sj >= 0xe040 && sj <= 0xeaa4) { /* 2660-element table */
- return(sju_e040[sj - 0xe040]);
- } else if (sj >= 0xf040) { /* User-defined areas */
- if (sj <= 0xf0fc) { /* ten 189-char chunks */
- return(0xe000 + (sj - 0xf040));
- } else if (sj >= 0xf140 && sj <= 0xf1fc) {
- return(0xe0bc + (sj - 0xf140));
- } else if (sj >= 0xf240 && sj <= 0xf2fc) {
- return(0xe178 + (sj - 0xf240));
- } else if (sj >= 0xf340 && sj <= 0xf3fc) {
- return(0xe234 + (sj - 0xf340));
- } else if (sj >= 0xf440 && sj <= 0xf4fc) {
- return(0xe2f0 + (sj - 0xf440));
- } else if (sj >= 0xf540 && sj <= 0xf5fc) {
- return(0xe3ac + (sj - 0xf540));
- } else if (sj >= 0xf640 && sj <= 0xf6fc) {
- return(0xe468 + (sj - 0xf640));
- } else if (sj >= 0xf740 && sj <= 0xf7fc) {
- return(0xe524 + (sj - 0xf740));
- } else if (sj >= 0xf840 && sj <= 0xf8fc) {
- return(0xe5e0 + (sj - 0xf840));
- } else if (sj >= 0xf940 && sj <= 0xf9fc) {
- return(0xe69c + (sj - 0xf940));
- }
- }
- kanji--; /* None of the above, uncount */
- }
-
-/* C0 / Halfwidth-Roman / C1 block (0x00-0x9f, no holes) */
-
- else if (sj < 0x00a0) {
- roman++; /* Count a Roman */
- if (sj == 0x5c) { /* Yen sign */
- return(0x00a5);
- } else if (sj == 0x7e) { /* Overline (macron) */
- return(0x203e);
- } else { /* Control or Halfwidth Roman */
- return(sj);
- }
- }
-
-/* Halfwidth Katakana block (0xa0-0xdf, no holes) */
-
- else if (sj >= 0xa1 && sj <= 0xdf) {
- kana++;
- return(sj + 0xfec0);
- }
-
-/* Catch-all must be final */
-
- bad++;
- return(0xfffd);
-}
-
-USHORT
-#ifdef CK_ANSIC
-un_to_sj(USHORT un) /* Unicode to Shift-JIS */
-#else
-un_to_sj(un) USHORT un;
-#endif /* CK_ANSIC */
-{
-
- if (un < 0x00a0) {
- switch (un) {
- case 0x005c: roman++; return(0x815f); /* Backslash */
- case 0x007e: bad++; return(0xfffd); /* No tilde in Shift-JIS */
- default: /* ASCII or C0/C1 control */
- roman++;
- return(un);
- }
- }
- if (un >= 0x00a0 && un < 0x0391) { /* Latin-1 symbols */
- roman++;
- switch(un) {
- case 0x00A2: return(0x8191);
- case 0x00A3: return(0x8192);
- case 0x00A5: return(0x005C); /* Yen */
- case 0x00A7: return(0x8198);
- case 0x00A8: return(0x814E);
- case 0x00AC: return(0x81CA);
- case 0x00B0: return(0x818B);
- case 0x00B1: return(0x817D);
- case 0x00B4: return(0x814C);
- case 0x00B6: return(0x81F7);
- case 0x00D7: return(0x817E);
- case 0x00F7: return(0x8180);
- default:
- roman--;
- bad++;
- return(0xfffd);
- }
- }
- if (un >= 0x0391 && un < 0x0401) { /* Greek */
- greek++;
- if (un <= 0x039c)
- return(usj_0391[un-0x0391]);
- greek--;
- bad++;
- return(0xfffd);
- }
- if (un >= 0x0401 && un < 0x2010) { /* Cyrillic */
- cyrillic++;
- if (un <= 0x0451)
- return(usj_0401[un-0x0401]);
- cyrillic--;
- bad++;
- return(0xfffd);
- }
- if (un >= 0x2010 && un < 0x2500) { /* General punctuation */
- special++;
- switch(un) {
- case 0x2010: return(0x815D);
- case 0x2015: return(0x815C);
- case 0x2016: return(0x8161);
- case 0x2018: return(0x8165);
- case 0x2019: return(0x8166);
- case 0x201C: return(0x8167);
- case 0x201D: return(0x8168);
- case 0x2020: return(0x81F5);
- case 0x2021: return(0x81F6);
- case 0x2025: return(0x8164);
- case 0x2026: return(0x8163);
- case 0x2030: return(0x81F1);
- case 0x2032: return(0x818C);
- case 0x2033: return(0x818D);
- case 0x203B: return(0x81A6);
- case 0x203E: return(0x007E);
- case 0x2103: return(0x818E); /* Letterlike symbols */
- case 0x212B: return(0x81F0);
- case 0x2190: return(0x81A9); /* Arrows */
- case 0x2191: return(0x81AA);
- case 0x2192: return(0x81A8);
- case 0x2193: return(0x81AB);
- case 0x21D2: return(0x81CB);
- case 0x21D4: return(0x81CC);
- case 0x2200: return(0x81CD); /* Math */
- case 0x2202: return(0x81DD);
- case 0x2203: return(0x81CE);
- case 0x2207: return(0x81DE);
- case 0x2208: return(0x81B8);
- case 0x220B: return(0x81B9);
- case 0x2212: return(0x817C);
- case 0x221A: return(0x81E3);
- case 0x221D: return(0x81E5);
- case 0x221E: return(0x8187);
- case 0x2220: return(0x81DA);
- case 0x2227: return(0x81C8);
- case 0x2228: return(0x81C9);
- case 0x2229: return(0x81BF);
- case 0x222A: return(0x81BE);
- case 0x222B: return(0x81E7);
- case 0x222C: return(0x81E8);
- case 0x2234: return(0x8188);
- case 0x2235: return(0x81E6);
- case 0x223D: return(0x81E4);
- case 0x2252: return(0x81E0);
- case 0x2260: return(0x8182);
- case 0x2261: return(0x81DF);
- case 0x2266: return(0x8185);
- case 0x2267: return(0x8186);
- case 0x226A: return(0x81E1);
- case 0x226B: return(0x81E2);
- case 0x2282: return(0x81BC);
- case 0x2283: return(0x81BD);
- case 0x2286: return(0x81BA);
- case 0x2287: return(0x81BB);
- case 0x22A5: return(0x81DB);
- case 0x2312: return(0x81DC); /* Arc */
- default:
- special--;
- bad++;
- return(0xfffd);
- }
- }
- if (un >= 0x2500 && un < 0x3000) { /* Box drawing */
- special++;
- switch(un) {
- case 0x2500: return(0x849F);
- case 0x2501: return(0x84AA);
- case 0x2502: return(0x84A0);
- case 0x2503: return(0x84AB);
- case 0x250C: return(0x84A1);
- case 0x250F: return(0x84AC);
- case 0x2510: return(0x84A2);
- case 0x2513: return(0x84AD);
- case 0x2514: return(0x84A4);
- case 0x2517: return(0x84AF);
- case 0x2518: return(0x84A3);
- case 0x251B: return(0x84AE);
- case 0x251C: return(0x84A5);
- case 0x251D: return(0x84BA);
- case 0x2520: return(0x84B5);
- case 0x2523: return(0x84B0);
- case 0x2524: return(0x84A7);
- case 0x2525: return(0x84BC);
- case 0x2528: return(0x84B7);
- case 0x252B: return(0x84B2);
- case 0x252C: return(0x84A6);
- case 0x252F: return(0x84B6);
- case 0x2530: return(0x84BB);
- case 0x2533: return(0x84B1);
- case 0x2534: return(0x84A8);
- case 0x2537: return(0x84B8);
- case 0x2538: return(0x84BD);
- case 0x253B: return(0x84B3);
- case 0x253C: return(0x84A9);
- case 0x253F: return(0x84B9);
- case 0x2542: return(0x84BE);
- case 0x254B: return(0x84B4);
- case 0x25A0: return(0x81A1); /* Geometric shapes */
- case 0x25A1: return(0x81A0);
- case 0x25B2: return(0x81A3);
- case 0x25B3: return(0x81A2);
- case 0x25BC: return(0x81A5);
- case 0x25BD: return(0x81A4);
- case 0x25C6: return(0x819F);
- case 0x25C7: return(0x819E);
- case 0x25CB: return(0x819B);
- case 0x25CE: return(0x819D);
- case 0x25CF: return(0x819C);
- case 0x25EF: return(0x81FC);
- case 0x2605: return(0x819A); /* Misc symbols */
- case 0x2606: return(0x8199);
- case 0x2640: return(0x818A);
- case 0x2642: return(0x8189);
- case 0x266A: return(0x81F4);
- case 0x266D: return(0x81F3);
- case 0x266F: return(0x81F2);
- default:
- special--;
- bad++;
- return(0xfffd);
- }
- }
- if (un >= 0x3000 && un < 0x4e00) { /* CJK symbols & punc */
- kanji++;
- if (un <= 0x30ff)
- return(usj_3000[un-0x3000]);
- kanji--;
- bad++;
- return(0xfffd);
- }
- if (un >= 0xff00 && un < 0xffff) { /* Half/full-width Roman & Katakana */
- if (un <= 0xff9f) {
- if (un > 0xff60)
- kana++;
- return(usj_ff00[un-0xff00]);
- }
- bad++;
- return(0xfffd);
- }
- if (un >= 0x4e00 && un < 0xe000) { /* Kanji */
- kanji++;
- if (un <= 0x9fa0)
- return(usj_4e00[un-0x4e00]);
- kanji--;
- bad++;
- return(0xfffd);
- }
- if (un >= 0xe000 && un < 0xff00) { /* User-defined (Gaiji) */
- kanji++;
- if (un <= 0xe0bb) { /* ten 189-char chunks */
- return(0xf040 + (un - 0xe000));
- } else if (un >= 0xe0bc && un <= 0xe177) {
- return(0xf140 + (un - 0xe0bc));
- } else if (un >= 0xe178 && un <= 0xe233) {
- return(0xf240 + (un - 0xe178));
- } else if (un >= 0xe234 && un <= 0xe2ef) {
- return(0xf340 + (un - 0xe234));
- } else if (un >= 0xe2f0 && un <= 0xe3ab) {
- return(0xf440 + (un - 0xe2f0));
- } else if (un >= 0xe3ac && un <= 0xe467) {
- return(0xf540 + (un - 0xe3ac));
- } else if (un >= 0xe468 && un <= 0xe523) {
- return(0xf640 + (un - 0xe468));
- } else if (un >= 0xe524 && un <= 0xe5df) {
- return(0xf740 + (un - 0xe524));
- } else if (un >= 0xe5e0 && un <= 0xe69b) {
- return(0xf840 + (un - 0xe5e0));
- } else if (un >= 0xe69c && un <= 0xe757) {
- return(0xf940 + (un - 0xe69c));
- }
- bad++;
- return(0xfffd);
- }
- /* NOTREACHED */
- /* Some compilers (correctly) warn of "statement not reached" here. */
- /* But others give up the ghost with "no return value". The former */
- /* is the lesser of two evils. */
- bad++;
- return(0xfffd);
-}
-#endif /* KANJI */
-
-/* Unicode-to-blah functions, tx_blah(). */
-
-static int
-#ifdef CK_ANSIC
-tx_punc(USHORT c)
-#else
-tx_punc(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x2000 && c <= 0x200a) /* Various-width spaces */
- return((CHAR)(0x20));
- else if (c >= 0x2010 && c <= 0x2015) /* Various-width dashes */
- return((CHAR)'-');
- else if (c >= 0x2018 && c <= 0x201b) /* Assorted single quotes */
- return((CHAR)0x27);
- else if (c >= 0x201c && c <= 0x201f) /* Assorted double quotes */
- return((CHAR)0x22);
- else if ((c >= 0x2022 && c <= 0x2024) || c == 0x2043) /* Bullets */
- return((CHAR)0xb7);
- switch (c) {
- case 0x2039: /* Less-than sign */
- return((CHAR)0x3c);
- case 0x203a: /* Greater-than sign */
- return((CHAR)0x3e);
- case 0x2044: /* Solidus -> Slash */
- return((CHAR)0x2f);
- default:
- return(-1);
- }
-}
-
-
-int /* For Latin-1 */
-#ifdef CK_ANSIC
-tx_ident(USHORT c)
-#else
-tx_ident(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c == 0x203e) /* Overline -> Macron */
- return((CHAR)0xaf);
- else if (c < 0x100) /* Latin-1 range */
- return((CHAR)(c & 0xff));
- else /* Or maybe from punctuation block */
- return(tx_punc(c));
-}
-
-int
-#ifdef CK_ANSIC
-tx_usascii(USHORT c)
-#else
-tx_usascii(c) USHORT c; /* US ASCII */
-#endif /* CK_ANSIC */
-{
- if (c < 0x80)
- return((CHAR)(c & 0xff));
- else if (c >= 0x2000 && c <= 0x200a) /* Various-width spaces */
- return((CHAR)(0x20));
- else if (c >= 0x2010 && c <= 0x2015) /* Various-width dashes */
- return((CHAR)'-');
- else if (c >= 0x2018 && c <= 0x201b) /* Assorted single quotes */
- return((CHAR)0x27);
- else if (c >= 0x201c && c <= 0x201f) /* Assorted double quotes */
- return((CHAR)0x22);
- else if ((c >= 0x2022 && c <= 0x2024) || c == 0x2043) /* Bullets */
- return((CHAR)0xb7);
- switch (c) {
- case 0x2039: /* Less-than sign */
- return((CHAR)0x3c);
- case 0x203a: /* Greater-than sign */
- return((CHAR)0x3e);
- case 0x2044: /* Solidus -> Slash */
- return((CHAR)0x2f);
- }
- /*
- Here we might also (a) map accented Roman letters to unaccented ones;
- (b) map Greek/Cyrillic A (etc) to Roman, and so on.
- */
- return((c & 0xff80) ? -1 : (CHAR)(c & 0x7f));
-}
-
-int
-#ifdef CK_ANSIC
-tx_british(USHORT c)
-#else
-tx_british(c) USHORT c; /* British */
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00)
- return(-1);
- else if (c == (USHORT) 0x00a3) /* Pound sign */
- return(0x2b);
- else
- return(tx_usascii(c));
-}
-
-int
-#ifdef CK_ANSIC
-tx_apl1(USHORT c)
-#else
-tx_apl1(c) USHORT c; /* Apl1 */
-#endif /* CK_ANSIC */
-{
- if (c >= 0x0041 && c <= 0x005a) /* Letters */
- return(c + 0x20);
- switch (c) { /* Others */
- case 0x0024: return((CHAR)0x7e);
- case 0x0027: return((CHAR)0x4b);
- case 0x0028: return((CHAR)0x3a);
- case 0x0029: return((CHAR)0x22);
- case 0x002b: return((CHAR)0x2d);
- case 0x002c: return((CHAR)0x2c);
- case 0x002d: return((CHAR)0x5f);
- case 0x002e: return((CHAR)0x2e);
- case 0x002f: return((CHAR)0x2f);
- case 0x0030: return((CHAR)0x30);
- case 0x0031: return((CHAR)0x31);
- case 0x0032: return((CHAR)0x32);
- case 0x0033: return((CHAR)0x33);
- case 0x0034: return((CHAR)0x34);
- case 0x0035: return((CHAR)0x35);
- case 0x0036: return((CHAR)0x36);
- case 0x0037: return((CHAR)0x37);
- case 0x0038: return((CHAR)0x38);
- case 0x0039: return((CHAR)0x39);
- case 0x003a: return((CHAR)0x3e);
- case 0x003b: return((CHAR)0x3c);
- case 0x003c: return((CHAR)0x23);
- case 0x003d: return((CHAR)0x25);
- case 0x003e: return((CHAR)0x26);
- case 0x003f: return((CHAR)0x51);
- case 0x005b: return((CHAR)0x3b);
- case 0x005c: return((CHAR)0x3f);
- case 0x005d: return((CHAR)0x27);
- case 0x005f: return((CHAR)0x46);
- case 0x007b: return((CHAR)0x7b);
- case 0x007c: return((CHAR)0x4d);
- case 0x007d: return((CHAR)0x7d);
- case 0x00a8: return((CHAR)0x21);
- case 0x00af: return((CHAR)0x40);
- case 0x00d7: return((CHAR)0x3d);
- case 0x00f7: return((CHAR)0x2b);
- case 0x2190: return((CHAR)0x5b);
- case 0x2191: return((CHAR)0x59);
- case 0x2192: return((CHAR)0x5d);
- case 0x2193: return((CHAR)0x55);
- case 0x2206: return((CHAR)0x48);
- case 0x2207: return((CHAR)0x47);
- case 0x220a: return((CHAR)0x45);
- case 0x2218: return((CHAR)0x4a);
- case 0x2227: return((CHAR)0x29);
- case 0x2228: return((CHAR)0x28);
- case 0x222a: return((CHAR)0x56);
- case 0x223c: return((CHAR)0x54);
- case 0x2260: return((CHAR)0x2a);
- case 0x2264: return((CHAR)0x24);
- case 0x2265: return((CHAR)0x5e);
- case 0x2282: return((CHAR)0x5a);
- case 0x2283: return((CHAR)0x58);
- case 0x22a2: return((CHAR)0x5c);
- case 0x22a3: return((CHAR)0x7c);
- case 0x22a4: return((CHAR)0x4e);
- case 0x22a5: return((CHAR)0x42);
- case 0x22c2: return((CHAR)0x43);
- case 0x22c4: return((CHAR)0x60);
- case 0x22c6: return((CHAR)0x50);
- case 0x2308: return((CHAR)0x53);
- case 0x230a: return((CHAR)0x44);
- case 0x2373: return((CHAR)0x49);
- case 0x2374: return((CHAR)0x52);
- case 0x2375: return((CHAR)0x57);
- case 0x237a: return((CHAR)0x41);
- case 0x25af: return((CHAR)0x4c);
- case 0x25cb: return((CHAR)0x4f);
- default: return(tx_usascii(c));
- }
-}
-
-int /* Canadian French */
-#ifdef CK_ANSIC
-tx_fr_canadian(USHORT c)
-#else
-tx_fr_canadian(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xe0: return(0x40); /* a grave */
- case 0xe2: return(0x5b); /* a circumflex */
- case 0xe7: return(0x5c); /* c cedilla */
- case 0xe8: return(0x7d); /* e grave */
- case 0xe9: return(0x7b); /* e acute */
- case 0xea: return(0x5d); /* e circumflex */
- case 0xee: return(0x5e); /* i circumflex */
- case 0xf4: return(0x60); /* o circumflex */
- case 0xf9: return(0x7c); /* u grave */
- case 0xfb: return(0x6e); /* u circumflex */
- default: return(tx_usascii(c));
- }
-}
-
-int /* Danish/Norwegian */
-#ifdef CK_ANSIC
-tx_danish(USHORT c)
-#else
-tx_danish(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xc6: return(0x5b); /* AE */
- case 0xd8: return(0x5c); /* O stroke */
- case 0xe6: return(0x7b); /* ae */
- case 0xf8: return(0x7c); /* o stroke */
- case 0xe5: return(0x7d); /* a ring */
- case 0xaf: return(0x7e); /* macron */
- default: return(tx_usascii(c));
- }
-}
-
-int /* Dutch */
-#ifdef CK_ANSIC
-tx_dutch(USHORT c)
-#else
-tx_dutch(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xfe00) /* Out of range */
- return(-1);
- switch(c) {
- case 0x007c: return(0x5d); /* vertical bar */
- case 0x00a3: return(0x23); /* pound sign */
- case 0x00ab: return(0x7b); /* diaeresis */
- case 0x00b4: return(0x7e); /* acute accent */
- case 0x00bc: return(0x7d); /* 1/4 */
- case 0x00be: return(0x40); /* 3/4 */
- case 0x00bd: return(0x5c); /* 1/2 */
- case 0x00ff: return(0x5b); /* y diaeresis (ij) */
- case 0x0192: return(0x7c); /* Florin */
- default: return((c & 0x80) ? -1 : (CHAR)(c & 0x7f));
- }
-}
-
-int /* Finnish */
-#ifdef CK_ANSIC
-tx_finnish(USHORT c)
-#else
-tx_finnish(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xc4: return(0x5b); /* A diaeresis */
- case 0xd6: return(0x5c); /* O diaeresis */
- case 0xc5: return(0x5d); /* A ring */
- case 0xdc: return(0x5e); /* U diaeresis */
- case 0xe9: return(0x60); /* e acute */
- case 0xe4: return(0x7b); /* a diaeresis */
- case 0xf6: return(0x7c); /* o diaeresis */
- case 0xe5: return(0x7d); /* a ring */
- case 0xfc: return(0x7e); /* u diaeresis */
- default: return(tx_usascii(c));
- }
-}
-
-int /* French */
-#ifdef CK_ANSIC
-tx_french(USHORT c)
-#else
-tx_french(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xa3: return(0x23); /* pound sign */
- case 0xa7: return(0x5d); /* section sign */
- case 0xa8: return(0x7e); /* diaeresis */
- case 0xb0: return(0x5b); /* ring */
- case 0xb5: return(0x60); /* micron sign (mu) */
- case 0xe0: return(0x40); /* a grave */
- case 0xe7: return(0x5c); /* c cedilla */
- case 0xe8: return(0x7d); /* e grave */
- case 0xe9: return(0x7b); /* e acute */
- case 0xf9: return(0x7c); /* u grave */
- default: return(tx_usascii(c));
- }
-}
-
-int /* German */
-#ifdef CK_ANSIC
-tx_german(USHORT c)
-#else
-tx_german(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xa7: return(0x40); /* section sign */
- case 0xc4: return(0x5b); /* A umlaut */
- case 0xd6: return(0x5c); /* O umlaut */
- case 0xdc: return(0x5d); /* U umlaut */
- case 0xdf: return(0x7e); /* ess-zet */
- case 0xe4: return(0x7b); /* a umlaut */
- case 0xf6: return(0x7c); /* o umlaut */
- case 0xfc: return(0x7d); /* u umlaut*/
- default: return(tx_usascii(c));
- }
-}
-
-int /* Hebrew-7 */
-#ifdef CK_ANSIC
-tx_hebrew7(USHORT c)
-#else
-tx_hebrew7(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x60) /* ASCII */
- return((CHAR)(c & 0x7f));
- else if (c >= 123 && c < 128) /* ASCII */
- return((CHAR)(c & 0x7f));
- else if (c >= 0x05d0 && c <= 0x05ea) /* Hebrew 27 contiguous characters */
- return((CHAR)((int)c - 0x5d0 + 96));
- else return(-1);
-}
-
-int /* Greek ELOT 927 */
-#ifdef CK_ANSIC
-tx_elot927(USHORT c)
-#else
-tx_elot927(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c <= 0x80) { /* ASCII */
- if (islower(c)) c = toupper(c); /* Send all letters in uppercase */
- return((CHAR)(c & 0x7f));
- }
-
-/* Greek -- map all Greek characters to unaccented uppercase */
-
- if (c >= 0x0391 && c <= 0x03a1) /* Alpha thru Rho - uppercase */
- return((CHAR)((int)c - 0x0391 + 97));
- else if (c >= 0x03a3 && c <= 0x03a9) /* Sigma thru Omega - uppercase */
- return((CHAR)((int)c - 0x0391 + 96));
- else if (c >= 0x03b1 && c <= 0x03c1) /* Alpha thru Rho - lowercase */
- return((CHAR)((int)c - 0x0391 + 97));
- else if (c >= 0x03c3 && c <= 0x03c9) /* Sigma thru Omega - uppercase */
- return((CHAR)((int)c - 0x0391 + 96));
- switch (c) {
- case 0x03c2: return((CHAR)114); /* Terminal sigma */
- case 0x0386: return((CHAR)97); /* Alpha Tonos */
- case 0x03ac: return((CHAR)97); /* alpha Tonos */
- case 0x0388: return((CHAR)101); /* Epsilon Tonos */
- case 0x03ad: return((CHAR)101); /* epsilon Tonos */
- case 0x0389: return((CHAR)103); /* Eta Tonos */
- case 0x03ae: return((CHAR)103); /* eta Tonos */
- case 0x038a: return((CHAR)105); /* Iota Tonos */
- case 0x03af: return((CHAR)105); /* iota Tonos */
- case 0x03ca: return((CHAR)105); /* iota Dialytika */
- case 0x038c: return((CHAR)111); /* Omicron Tonos */
- case 0x03cc: return((CHAR)111); /* omicron Tonos */
- case 0x038e: return((CHAR)116); /* Upsilon Tonos */
- case 0x03d3: return((CHAR)116); /* Upsilon Tonos */
- case 0x03cd: return((CHAR)116); /* upsilon Tonos */
- case 0x03cb: return((CHAR)116); /* upsilon Dialytika */
- case 0x03b0: return((CHAR)116); /* upsilon Dialytika+Tonos */
- case 0x038f: return((CHAR)120); /* Omega Tonos */
- case 0x03ce: return((CHAR)120); /* omega Tonos */
- case 0x0390: return((CHAR)105); /* iota Dialytika+Tonos */
- case 0x03aa: return((CHAR)105); /* Iota Dialytika */
- case 0x03ab: return((CHAR)116); /* Upsilon Dialytika */
- case 0x03d4: return((CHAR)116); /* Upsilon Dialytika */
- case 0x03d0: return((CHAR)98); /* Alternative beta */
- case 0x03d1: return((CHAR)104); /* Open theta */
- case 0x03d5: return((CHAR)117); /* Open phi */
- case 0x03d6: return((CHAR)112); /* Alternative Pi */
- default: return(-1);
- }
-}
-
-int /* Hungarian */
-#ifdef CK_ANSIC
-tx_hungarian(USHORT c)
-#else
-tx_hungarian(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c == 0x02dd || c == 0x2033)
- return(0x7e); /* double acute accent */
- else if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xc1: return(0x40); /* A acute */
- case 0xc9: return(0x5b); /* E acute */
- case 0xd6: return(0x5c); /* O umlaut */
- case 0xdc: return(0x5d); /* U umlaut */
- case 0xe9: return(0x7b); /* e acute */
- case 0xf6: return(0x7c); /* o umlaut */
- case 0xfa: return(0x60); /* u acute */
- case 0xfc: return(0x7d); /* u umlaut */
- default: return(tx_usascii(c));
- }
-}
-
-int /* Icelandic */
-#ifdef CK_ANSIC
-tx_icelandic(USHORT c)
-#else
-tx_icelandic(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xde: return(0x40); /* Thorn */
- case 0xd0: return(0x5b); /* Eth */
- case 0xc6: return(0x5d); /* AE */
- case 0xd6: return(0x5e); /* O umlaut */
- case 0xfe: return(0x60); /* thorn */
- case 0xf0: return(0x7b); /* eth */
- case 0xe6: return(0x7d); /* ae */
- case 0xf6: return(0x7e); /* o umlaut */
- default: return(tx_usascii(c));
- }
-}
-
-int /* Italian */
-#ifdef CK_ANSIC
-tx_italian(USHORT c)
-#else
-tx_italian(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xa3: return(0x23); /* pound sign */
- case 0xa7: return(0x40); /* section sign */
- case 0xb0: return(0x5b); /* ring */
- case 0xe7: return(0x5c); /* c cedilla */
- case 0xe9: return(0x5d); /* e acute */
- case 0xf9: return(0x60); /* u grave */
- case 0xe0: return(0x7b); /* a grave */
- case 0xf2: return(0x7c); /* o grave */
- case 0xe8: return(0x7d); /* e grave */
- case 0xec: return(0x7e); /* i grave */
- default: return(tx_usascii(c));
- }
-}
-
-int /* JIS 0201 Roman */
-#ifdef CK_ANSIC
-tx_jis0201r(USHORT c)
-#else
-tx_jis0201r(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c && 0xff80) /* 7 bits */
- return(-1);
- switch (c) { /* Like ASCII with */
- case 0x00a5: return(92); /* two exceptions */
- case 0x00af: return(126);
- case 0x203e: return(126);
- default: return(tx_usascii(c));
- }
-}
-
-int /* JIS 0201 Katakana */
-#ifdef CK_ANSIC
-tx_jis0201k(USHORT c)
-#else
-tx_jis0201k(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xff61 || c > 0xff9f)
- return(-1); /* Out of range */
- else
- return((int)c - 0xfec0); /* 0xff61 - a0 = 0xfec0 */
-}
-
-int /* Short KOI */
-#ifdef CK_ANSIC
-tx_koi7(USHORT c)
-#else
-tx_koi7(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x50)
- return((CHAR)(c & 0x7f));
- else if (c > 0x7f)
- return(-1); /* Out of range */
- switch(c) {
- case 0x0410: return((CHAR)97);
- case 0x0411: return((CHAR)98);
- case 0x0412: return((CHAR)119);
- case 0x0413: return((CHAR)103);
- case 0x0414: return((CHAR)100);
- case 0x0415: return((CHAR)101);
- case 0x0416: return((CHAR)118);
- case 0x0417: return((CHAR)122);
- case 0x0418: return((CHAR)105);
- case 0x0419: return((CHAR)106);
- case 0x041a: return((CHAR)107);
- case 0x041b: return((CHAR)108);
- case 0x041c: return((CHAR)109);
- case 0x041d: return((CHAR)110);
- case 0x041e: return((CHAR)111);
- case 0x041f: return((CHAR)112);
- case 0x0420: return((CHAR)114);
- case 0x0421: return((CHAR)115);
- case 0x0422: return((CHAR)116);
- case 0x0423: return((CHAR)117);
- case 0x0424: return((CHAR)102);
- case 0x0425: return((CHAR)104);
- case 0x0426: return((CHAR)99);
- case 0x0427: return((CHAR)126);
- case 0x0428: return((CHAR)123);
- case 0x0429: return((CHAR)125);
- case 0x042b: return((CHAR)121);
- case 0x042c: return((CHAR)120);
- case 0x042d: return((CHAR)124);
- case 0x042e: return((CHAR)96);
- case 0x042f: return((CHAR)113);
- default: return(-1);
- }
-}
-
-int /* Portuguese */
-#ifdef CK_ANSIC
-tx_portuguese(USHORT c)
-#else
-tx_portuguese(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xe0: return(0xa7); /* section sign */
- case 0xb0: return(0xc3); /* A tilde */
- case 0xe7: return(0xc7); /* C cedilla */
- case 0xa7: return(0xd5); /* O tilde */
- case 0xe9: return(0xe3); /* a tilde */
- case 0xf9: return(0xe7); /* c cedilla */
- case 0xe8: return(0xf5); /* o tilde */
- case 0xa8: return(0xb0); /* ring */
- default: return(tx_usascii(c));
- }
-}
-
-int /* Spanish */
-#ifdef CK_ANSIC
-tx_spanish(USHORT c)
-#else
-tx_spanish(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xa3: return(0x23); /* pound sign */
- case 0xa7: return(0x40); /* section */
- case 0xa1: return(0x5b); /* inverted exclamation */
- case 0xd1: return(0x5c); /* N tilde */
- case 0xbf: return(0x5d); /* inverted question mark */
- case 0xb0: return(0x7b); /* ring */
- case 0xf1: return(0x7c); /* n tilde */
- case 0xe7: return(0x7d); /* c cedilla */
- default: return(tx_usascii(c));
- }
-}
-
-int /* Swedish */
-#ifdef CK_ANSIC
-tx_swedish(USHORT c)
-#else
-tx_swedish(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xc9: return(0x40); /* E acute */
- case 0xc4: return(0x5b); /* A umlaut*/
- case 0xd6: return(0x5c); /* O umlaut */
- case 0xc5: return(0x5d); /* A ring */
- case 0xdc: return(0x5e); /* U umlaut */
- case 0xe9: return(0x60); /* e acute */
- case 0xe4: return(0x7b); /* a umlaut */
- case 0xf6: return(0x7c); /* o umlaut */
- case 0xe5: return(0x7d); /* a ring */
- case 0xfc: return(0x7e); /* u umlaut */
- default: return(tx_usascii(c));
- }
-}
-
-
-int /* Swiss NRC */
-#ifdef CK_ANSIC
-tx_swiss(USHORT c)
-#else
-tx_swiss(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c & 0xff00) /* Out of range */
- return(-1);
- switch(c) {
- case 0xf9: return(0x23); /* u grave */
- case 0xe0: return(0x40); /* a grave */
- case 0xe9: return(0x5b); /* e acute */
- case 0xe7: return(0x5c); /* c cedilla */
- case 0xea: return(0x5d); /* e circumflex */
- case 0xee: return(0x5e); /* i circumflex */
- case 0xe8: return(0x5f); /* e grave */
- case 0xf4: return(0x60); /* o circumflex */
- case 0xe4: return(0x7b); /* a umlaut */
- case 0xf6: return(0x7c); /* o umlaut */
- case 0xfc: return(0x7d); /* u umlaut */
- case 0xfb: return(0x7e); /* u circumflex */
- default: return(tx_usascii(c));
- }
-}
-
-int /* Dyadic APL */
-#ifdef CK_ANSIC
-tx_apl2(USHORT c)
-#else
-tx_apl2(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x0041 && c <= 0x005a) /* Letters */
- return(c - 0xa2);
- switch (c) {
- case 0x00a0: return((CHAR)0xa0);
- case 0x00a2: return((CHAR)0xa4);
- case 0x00a3: return((CHAR)0xd4);
- case 0x00a8: return((CHAR)0xdc);
- case 0x00af: return((CHAR)0xda);
- case 0x00d7: return((CHAR)0xa1);
- case 0x00f7: return((CHAR)0xaf);
- case 0x2190: return((CHAR)0xbb);
- case 0x2191: return((CHAR)0xfe);
- case 0x2192: return((CHAR)0xde);
- case 0x2193: return((CHAR)0xff);
- case 0x2206: return((CHAR)0xae);
- case 0x2207: return((CHAR)0xfd);
- case 0x220a: return((CHAR)0xb5);
- case 0x2218: return((CHAR)0xbc);
- case 0x2228: return((CHAR)0xdf);
- case 0x2229: return((CHAR)0xd1);
- case 0x222a: return((CHAR)0xd2);
- case 0x2260: return((CHAR)0xb0);
- case 0x2261: return((CHAR)0xb6);
- case 0x2262: return((CHAR)0xcd);
- case 0x2264: return((CHAR)0xb8);
- case 0x2265: return((CHAR)0xb7);
- case 0x2282: return((CHAR)0xe0);
- case 0x2283: return((CHAR)0xe1);
- case 0x2296: return((CHAR)0xd6);
- case 0x22a2: return((CHAR)0xd7);
- case 0x22a3: return((CHAR)0xd8);
- case 0x22a4: return((CHAR)0xba);
- case 0x22a5: return((CHAR)0xb9);
- case 0x22c4: return((CHAR)0xb1);
- case 0x2308: return((CHAR)0xcf);
- case 0x230a: return((CHAR)0xce);
- case 0x2337: return((CHAR)0xd9);
- case 0x2339: return((CHAR)0xca);
- case 0x233d: return((CHAR)0xd5);
- case 0x233f: return((CHAR)0xbe);
- case 0x2340: return((CHAR)0xbf);
- case 0x2349: return((CHAR)0xd0);
- case 0x234b: return((CHAR)0xc2);
- case 0x234e: return((CHAR)0xc0);
- case 0x2352: return((CHAR)0xc3);
- case 0x2355: return((CHAR)0xc1);
- case 0x2359: return((CHAR)0xe2);
- case 0x235d: return((CHAR)0xbd);
- case 0x235e: return((CHAR)0xc9);
- case 0x235f: return((CHAR)0xc7);
- case 0x2368: return((CHAR)0xc6);
- case 0x236a: return((CHAR)0xcc);
- case 0x236b: return((CHAR)0xcb);
- case 0x236c: return((CHAR)0xd3);
- case 0x2371: return((CHAR)0xc5);
- case 0x2372: return((CHAR)0xc4);
- case 0x2373: return((CHAR)0xdb);
- case 0x2374: return((CHAR)0xb3);
- case 0x2375: return((CHAR)0xb2);
- case 0x237a: return((CHAR)0xb4);
- case 0x2500: return((CHAR)0xaa);
- case 0x2502: return((CHAR)0xa2);
- case 0x250c: return((CHAR)0xad);
- case 0x2510: return((CHAR)0xa5);
- case 0x2514: return((CHAR)0xa6);
- case 0x2518: return((CHAR)0xac);
- case 0x251c: return((CHAR)0xa9);
- case 0x2524: return((CHAR)0xa3);
- case 0x252c: return((CHAR)0xa8);
- case 0x2534: return((CHAR)0xa7);
- case 0x253c: return((CHAR)0xab);
- case 0x25af: return((CHAR)0xc8);
- case 0x25cb: return((CHAR)0xdd);
- default:
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- return(tx_punc(c));
- }
-}
-
-int /* APL-Plus */
-#ifdef CK_ANSIC
-tx_apl3(USHORT c)
-#else
-tx_apl3(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- switch (c) {
- case 0x00a0: return((CHAR)0xa0);
- case 0x00a1: return((CHAR)0xa1);
- case 0x00a2: return((CHAR)0xa2);
- case 0x00a3: return((CHAR)0xa3);
- case 0x00a5: return((CHAR)0xa5);
- case 0x00a6: return((CHAR)0xa6);
- case 0x00a7: return((CHAR)0xa7);
- case 0x00a8: return((CHAR)0xa8);
- case 0x00ab: return((CHAR)0xab);
- case 0x00af: return((CHAR)0xaf);
- case 0x00b6: return((CHAR)0xb6);
- case 0x00b7: return((CHAR)0xb7);
- case 0x00bb: return((CHAR)0xbb);
- case 0x00bf: return((CHAR)0xbf);
- case 0x00c0: return((CHAR)0xc0);
- case 0x00c1: return((CHAR)0xc1);
- case 0x00c2: return((CHAR)0xc2);
- case 0x00c3: return((CHAR)0xc3);
- case 0x00c4: return((CHAR)0xc4);
- case 0x00c5: return((CHAR)0xc5);
- case 0x00c6: return((CHAR)0xc6);
- case 0x00c7: return((CHAR)0xc7);
- case 0x00c8: return((CHAR)0xc8);
- case 0x00c9: return((CHAR)0xc9);
- case 0x00ca: return((CHAR)0xca);
- case 0x00cb: return((CHAR)0xcb);
- case 0x00cc: return((CHAR)0xcc);
- case 0x00cd: return((CHAR)0xcd);
- case 0x00ce: return((CHAR)0xce);
- case 0x00cf: return((CHAR)0xcf);
- case 0x00d1: return((CHAR)0xd1);
- case 0x00d2: return((CHAR)0xd2);
- case 0x00d3: return((CHAR)0xd3);
- case 0x00d4: return((CHAR)0xd4);
- case 0x00d5: return((CHAR)0xd5);
- case 0x00d6: return((CHAR)0xd6);
- case 0x00d7: return((CHAR)0xd7);
- case 0x00d8: return((CHAR)0xd8);
- case 0x00d9: return((CHAR)0xd9);
- case 0x00da: return((CHAR)0xda);
- case 0x00db: return((CHAR)0xdb);
- case 0x00dc: return((CHAR)0xdc);
- case 0x00dd: return((CHAR)0xdd);
- case 0x00df: return((CHAR)0xdf);
- case 0x00e0: return((CHAR)0xe0);
- case 0x00e1: return((CHAR)0xe1);
- case 0x00e2: return((CHAR)0xe2);
- case 0x00e3: return((CHAR)0xe3);
- case 0x00e4: return((CHAR)0xe4);
- case 0x00e5: return((CHAR)0xe5);
- case 0x00e6: return((CHAR)0xe6);
- case 0x00e7: return((CHAR)0xe7);
- case 0x00e8: return((CHAR)0xe8);
- case 0x00e9: return((CHAR)0xe9);
- case 0x00ea: return((CHAR)0xea);
- case 0x00eb: return((CHAR)0xeb);
- case 0x00ec: return((CHAR)0xec);
- case 0x00ed: return((CHAR)0xed);
- case 0x00ee: return((CHAR)0xee);
- case 0x00ef: return((CHAR)0xef);
- case 0x00f1: return((CHAR)0xf1);
- case 0x00f2: return((CHAR)0xf2);
- case 0x00f3: return((CHAR)0xf3);
- case 0x00f4: return((CHAR)0xf4);
- case 0x00f5: return((CHAR)0xf5);
- case 0x00f6: return((CHAR)0xf6);
- case 0x00f7: return((CHAR)0xf7);
- case 0x00f9: return((CHAR)0xf9);
- case 0x00fa: return((CHAR)0xfa);
- case 0x00fb: return((CHAR)0xfb);
- case 0x00fc: return((CHAR)0xfc);
- case 0x00fd: return((CHAR)0xfd);
- case 0x00ff: return((CHAR)0xff);
- case 0x20ac: return((CHAR)0x80);
- case 0x2190: return((CHAR)0x84);
- case 0x2191: return((CHAR)0x86);
- case 0x2192: return((CHAR)0x85);
- case 0x2193: return((CHAR)0x87);
- case 0x2205: return((CHAR)0xf8);
- case 0x2206: return((CHAR)0x91);
- case 0x2207: return((CHAR)0x92);
- case 0x220a: return((CHAR)0xb9);
- case 0x2218: return((CHAR)0xb0);
- case 0x2228: return((CHAR)0x9f);
- case 0x2229: return((CHAR)0x9d);
- case 0x222a: return((CHAR)0x9e);
- case 0x2260: return((CHAR)0xac);
- case 0x2261: return((CHAR)0xad);
- case 0x2264: return((CHAR)0x88);
- case 0x2265: return((CHAR)0x89);
- case 0x2282: return((CHAR)0x9b);
- case 0x2283: return((CHAR)0x9c);
- case 0x2296: return((CHAR)0xb4);
- case 0x22a2: return((CHAR)0xa4);
- case 0x22a3: return((CHAR)0x81);
- case 0x22a4: return((CHAR)0x82);
- case 0x22a5: return((CHAR)0x83);
- case 0x22c4: return((CHAR)0xaa);
- case 0x2308: return((CHAR)0x97);
- case 0x230a: return((CHAR)0x98);
- case 0x2337: return((CHAR)0xde);
- case 0x2339: return((CHAR)0x8e);
- case 0x233d: return((CHAR)0xb2);
- case 0x233f: return((CHAR)0x9a);
- case 0x2340: return((CHAR)0x99);
- case 0x2349: return((CHAR)0xb3);
- case 0x234b: return((CHAR)0x93);
- case 0x234e: return((CHAR)0x96);
- case 0x2352: return((CHAR)0x94);
- case 0x2355: return((CHAR)0x95);
- case 0x2359: return((CHAR)0x8f);
- case 0x235d: return((CHAR)0xa9);
- case 0x235e: return((CHAR)0x8d);
- case 0x235f: return((CHAR)0xb5);
- case 0x2364: return((CHAR)0xf0);
- case 0x2368: return((CHAR)0xfe);
- case 0x236a: return((CHAR)0xae);
- case 0x236b: return((CHAR)0x90);
- case 0x236c: return((CHAR)0xd0);
- case 0x2371: return((CHAR)0x8b);
- case 0x2372: return((CHAR)0x8a);
- case 0x2373: return((CHAR)0xbc);
- case 0x2374: return((CHAR)0xbd);
- case 0x2375: return((CHAR)0xbe);
- case 0x2377: return((CHAR)0xba);
- case 0x237a: return((CHAR)0xb8);
- case 0x25af: return((CHAR)0x8c);
- case 0x25cb: return((CHAR)0xb1);
- default:
- return(tx_punc(c));
- }
-}
-
-int /* IBM APL2 */
-#ifdef CK_ANSIC
-tx_apl4(USHORT c)
-#else
-tx_apl4(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- switch (c) {
- case 0x00a0: return((CHAR)0xff);
- case 0x00a1: return((CHAR)0xad);
- case 0x00a3: return((CHAR)0x9c);
- case 0x00a6: return((CHAR)0xdd);
- case 0x00a8: return((CHAR)0xfe);
- case 0x00aa: return((CHAR)0xa6);
- case 0x00ac: return((CHAR)0xaa);
- case 0x00af: return((CHAR)0xfd);
- case 0x00ba: return((CHAR)0xa7);
- case 0x00bf: return((CHAR)0xa8);
- case 0x00c4: return((CHAR)0x8e);
- case 0x00c5: return((CHAR)0xee); /* and 0x8f */
- case 0x00c7: return((CHAR)0x80);
- case 0x00cc: return((CHAR)0xde);
- case 0x00d1: return((CHAR)0xa5);
- case 0x00d6: return((CHAR)0x99);
- case 0x00d7: return((CHAR)0xf5);
- case 0x00dc: return((CHAR)0x9a);
- case 0x00df: return((CHAR)0xe1);
- case 0x00e0: return((CHAR)0x85);
- case 0x00e1: return((CHAR)0xa0);
- case 0x00e2: return((CHAR)0x83);
- case 0x00e4: return((CHAR)0x84);
- case 0x00e5: return((CHAR)0x86);
- case 0x00e7: return((CHAR)0x87);
- case 0x00e8: return((CHAR)0x8a);
- case 0x00e9: return((CHAR)0x82);
- case 0x00ea: return((CHAR)0x88);
- case 0x00eb: return((CHAR)0x89);
- case 0x00ec: return((CHAR)0x8d);
- case 0x00ed: return((CHAR)0xa1);
- case 0x00ee: return((CHAR)0x8c);
- case 0x00ef: return((CHAR)0x8b);
- case 0x00f1: return((CHAR)0xa4);
- case 0x00f2: return((CHAR)0x95);
- case 0x00f3: return((CHAR)0xa2);
- case 0x00f4: return((CHAR)0x93);
- case 0x00f6: return((CHAR)0x94);
- case 0x00f7: return((CHAR)0xf6);
- case 0x00f8: return((CHAR)0x9b);
- case 0x00f9: return((CHAR)0x97);
- case 0x00fa: return((CHAR)0xa3);
- case 0x00fb: return((CHAR)0x96);
- case 0x00fc: return((CHAR)0x81);
- case 0x2190: return((CHAR)0x9e);
- case 0x2191: return((CHAR)0xc6);
- case 0x2192: return((CHAR)0xab);
- case 0x2193: return((CHAR)0xc7);
- case 0x2206: return((CHAR)0xb6);
- case 0x2207: return((CHAR)0xb7);
- case 0x2218: return((CHAR)0xf8);
- case 0x2228: return((CHAR)0xeb);
- case 0x2229: return((CHAR)0xef);
- case 0x222a: return((CHAR)0xac);
- case 0x2235: return((CHAR)0xd2);
- case 0x2260: return((CHAR)0xf4);
- case 0x2261: return((CHAR)0xcf);
- case 0x2264: return((CHAR)0xf3);
- case 0x2265: return((CHAR)0xf2);
- case 0x2282: return((CHAR)0xe2);
- case 0x2283: return((CHAR)0xe3);
- case 0x2296: return((CHAR)0xe9);
- case 0x22a2: return((CHAR)0xd6);
- case 0x22a3: return((CHAR)0xd7);
- case 0x22a4: return((CHAR)0x98);
- case 0x22a5: return((CHAR)0x9d);
- case 0x22c4: return((CHAR)0xd8);
- case 0x2308: return((CHAR)0xa9);
- case 0x230a: return((CHAR)0xbe);
- case 0x2336: return((CHAR)0x9f);
- case 0x2337: return((CHAR)0xd3);
- case 0x2339: return((CHAR)0x92);
- case 0x233b: return((CHAR)0xd5);
- case 0x233d: return((CHAR)0xe8);
- case 0x233f: return((CHAR)0xf0);
- case 0x2340: return((CHAR)0xf1);
- case 0x2342: return((CHAR)0xd4);
- case 0x2349: return((CHAR)0xed);
- case 0x234b: return((CHAR)0xfb);
- case 0x234e: return((CHAR)0xaf);
- case 0x2352: return((CHAR)0xfc);
- case 0x2355: return((CHAR)0xae);
- case 0x2359: return((CHAR)0xf7);
- case 0x235d: return((CHAR)0xe4);
- case 0x235e: return((CHAR)0x91);
- case 0x235f: return((CHAR)0xb5);
- case 0x236b: return((CHAR)0xfa);
- case 0x2371: return((CHAR)0xe7);
- case 0x2372: return((CHAR)0xe5);
- case 0x2373: return((CHAR)0xec);
- case 0x2374: return((CHAR)0xe6);
- case 0x2375: return((CHAR)0xf9);
- case 0x2377: return((CHAR)0xd1);
- case 0x2378: return((CHAR)0xd0);
- case 0x237a: return((CHAR)0xe0);
- case 0x2500: return((CHAR)0xc4);
- case 0x2502: return((CHAR)0xb3);
- case 0x250c: return((CHAR)0xda);
- case 0x2510: return((CHAR)0xbf);
- case 0x2514: return((CHAR)0xc0);
- case 0x2518: return((CHAR)0xd9);
- case 0x251c: return((CHAR)0xc3);
- case 0x2524: return((CHAR)0xb4);
- case 0x252c: return((CHAR)0xc2);
- case 0x2534: return((CHAR)0xc1);
- case 0x253c: return((CHAR)0xc5);
- case 0x2550: return((CHAR)0xcd);
- case 0x2551: return((CHAR)0xba);
- case 0x2554: return((CHAR)0xc9);
- case 0x2557: return((CHAR)0xbb);
- case 0x255a: return((CHAR)0xc8);
- case 0x255d: return((CHAR)0xbc);
- case 0x2560: return((CHAR)0xcc);
- case 0x2563: return((CHAR)0xb9);
- case 0x2566: return((CHAR)0xcb);
- case 0x2569: return((CHAR)0xca);
- case 0x256c: return((CHAR)0xce);
- case 0x2580: return((CHAR)0xdf);
- case 0x2584: return((CHAR)0xdc);
- case 0x2588: return((CHAR)0xdb);
- case 0x2591: return((CHAR)0xb0);
- case 0x2592: return((CHAR)0xb1);
- case 0x2593: return((CHAR)0xb2);
- case 0x25af: return((CHAR)0x90);
- case 0x25cb: return((CHAR)0xea);
- default:
- return(tx_punc(c));
- }
-}
-
-int /* APL-2741 */
-#ifdef CK_ANSIC
-tx_apl5(USHORT c)
-#else
-tx_apl5(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- switch (c) {
- case 0x00a0: return((CHAR)0xa0);
- case 0x00a1: return((CHAR)0xa1);
- case 0x00a2: return((CHAR)0xa2);
- case 0x00a3: return((CHAR)0xa3);
- case 0x00a8: return((CHAR)0xa8);
- case 0x00af: return((CHAR)0xaf);
- case 0x00b6: return((CHAR)0xb6);
- case 0x00b7: return((CHAR)0xb7);
- case 0x00bf: return((CHAR)0xbf);
- case 0x00c4: return((CHAR)0xc4);
- case 0x00c5: return((CHAR)0xc5);
- case 0x00c6: return((CHAR)0xc6);
- case 0x00c7: return((CHAR)0xc7);
- case 0x00c8: return((CHAR)0xc8);
- case 0x00c9: return((CHAR)0xc9);
- case 0x00cd: return((CHAR)0xcd);
- case 0x00d1: return((CHAR)0xd1);
- case 0x00d6: return((CHAR)0xd6);
- case 0x00d7: return((CHAR)0xd7);
- case 0x00d8: return((CHAR)0xd8);
- case 0x00dc: return((CHAR)0xdc);
- case 0x00df: return((CHAR)0xdf);
- case 0x00e0: return((CHAR)0xe0);
- case 0x00e1: return((CHAR)0xe1);
- case 0x00e2: return((CHAR)0xe2);
- case 0x00e3: return((CHAR)0xe3);
- case 0x00e4: return((CHAR)0xe4);
- case 0x00e5: return((CHAR)0xe5);
- case 0x00e6: return((CHAR)0xe6);
- case 0x00e7: return((CHAR)0xe7);
- case 0x00e8: return((CHAR)0xe8);
- case 0x00e9: return((CHAR)0xe9);
- case 0x00ea: return((CHAR)0xea);
- case 0x00eb: return((CHAR)0xeb);
- case 0x00ec: return((CHAR)0xec);
- case 0x00ed: return((CHAR)0xed);
- case 0x00ee: return((CHAR)0xee);
- case 0x00ef: return((CHAR)0xef);
- case 0x00f1: return((CHAR)0xf1);
- case 0x00f2: return((CHAR)0xf2);
- case 0x00f3: return((CHAR)0xf3);
- case 0x00f4: return((CHAR)0xf4);
- case 0x00f5: return((CHAR)0xf5);
- case 0x00f6: return((CHAR)0xf6);
- case 0x00f7: return((CHAR)0xf7);
- case 0x00f9: return((CHAR)0xf9);
- case 0x00fa: return((CHAR)0xfa);
- case 0x00fb: return((CHAR)0xfb);
- case 0x00fc: return((CHAR)0xfc);
- case 0x20ac: return((CHAR)0x80);
- case 0x2190: return((CHAR)0x84);
- case 0x2191: return((CHAR)0x86);
- case 0x2192: return((CHAR)0x85);
- case 0x2193: return((CHAR)0x87);
- case 0x2205: return((CHAR)0xf8);
- case 0x2206: return((CHAR)0x91);
- case 0x2207: return((CHAR)0x92);
- case 0x220a: return((CHAR)0xb9);
- case 0x2218: return((CHAR)0xb0);
- case 0x2228: return((CHAR)0x9f);
- case 0x2229: return((CHAR)0x9d);
- case 0x222a: return((CHAR)0x9e);
- case 0x2235: return((CHAR)0xfd);
- case 0x2260: return((CHAR)0xac);
- case 0x2261: return((CHAR)0xa6);
- case 0x2262: return((CHAR)0xbb);
- case 0x2264: return((CHAR)0x88);
- case 0x2265: return((CHAR)0x89);
- case 0x2282: return((CHAR)0x9b);
- case 0x2283: return((CHAR)0x9c);
- case 0x2296: return((CHAR)0xb4);
- case 0x22a2: return((CHAR)0xa4);
- case 0x22a3: return((CHAR)0x81);
- case 0x22a4: return((CHAR)0x82);
- case 0x22a5: return((CHAR)0x83);
- case 0x22c4: return((CHAR)0xaa);
- case 0x2308: return((CHAR)0x97);
- case 0x230a: return((CHAR)0x98);
- case 0x2336: return((CHAR)0xa7);
- case 0x2337: return((CHAR)0xde);
- case 0x2339: return((CHAR)0x8e);
- case 0x233b: return((CHAR)0xcb);
- case 0x233d: return((CHAR)0xb2);
- case 0x233f: return((CHAR)0x9a);
- case 0x2340: return((CHAR)0x99);
- case 0x2342: return((CHAR)0xca);
- case 0x2347: return((CHAR)0xd4);
- case 0x2348: return((CHAR)0xd5);
- case 0x2349: return((CHAR)0xb3);
- case 0x234b: return((CHAR)0x93);
- case 0x234e: return((CHAR)0x96);
- case 0x2350: return((CHAR)0xd2);
- case 0x2352: return((CHAR)0x94);
- case 0x2355: return((CHAR)0x95);
- case 0x2357: return((CHAR)0xd3);
- case 0x2359: return((CHAR)0x8f);
- case 0x235d: return((CHAR)0xa9);
- case 0x235e: return((CHAR)0x8d);
- case 0x235f: return((CHAR)0xb5);
- case 0x2364: return((CHAR)0xf0);
- case 0x2365: return((CHAR)0xff);
- case 0x2368: return((CHAR)0xfe);
- case 0x236a: return((CHAR)0xae);
- case 0x236b: return((CHAR)0x90);
- case 0x236c: return((CHAR)0xab);
- case 0x2371: return((CHAR)0x8b);
- case 0x2372: return((CHAR)0x8a);
- case 0x2373: return((CHAR)0xbc);
- case 0x2374: return((CHAR)0xbd);
- case 0x2375: return((CHAR)0xbe);
- case 0x2377: return((CHAR)0xba);
- case 0x2378: return((CHAR)0xa5);
- case 0x237a: return((CHAR)0xb8);
- case 0x2500: return((CHAR)0xce);
- case 0x2502: return((CHAR)0xdb);
- case 0x250c: return((CHAR)0xda);
- case 0x2510: return((CHAR)0xcc);
- case 0x2514: return((CHAR)0xc0);
- case 0x2518: return((CHAR)0xd9);
- case 0x251c: return((CHAR)0xc3);
- case 0x2524: return((CHAR)0xdd);
- case 0x252c: return((CHAR)0xc2);
- case 0x2534: return((CHAR)0xc1);
- case 0x253c: return((CHAR)0xcf);
- case 0x25af: return((CHAR)0x8c);
- case 0x25cb: return((CHAR)0xb1);
- default:
- return(tx_punc(c));
- }
-}
-
-/* For Latin-1, use tx_ident() */
-
-int /* Latin-2 */
-#ifdef CK_ANSIC
-tx_8859_2(USHORT c)
-#else
-tx_8859_2(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00A0: return((CHAR)160);
- case 0x00A4: return((CHAR)164);
- case 0x00A7: return((CHAR)167);
- case 0x00A8: return((CHAR)168);
- case 0x00AD: return((CHAR)173);
- case 0x00B0: return((CHAR)176);
- case 0x00B4: return((CHAR)180);
- case 0x00B8: return((CHAR)184);
- case 0x00C1: return((CHAR)193);
- case 0x00C2: return((CHAR)194);
- case 0x00C4: return((CHAR)196);
- case 0x00C7: return((CHAR)199);
- case 0x00C9: return((CHAR)201);
- case 0x00CB: return((CHAR)203);
- case 0x00CD: return((CHAR)205);
- case 0x00CE: return((CHAR)206);
- case 0x00D3: return((CHAR)211);
- case 0x00D4: return((CHAR)212);
- case 0x00D6: return((CHAR)214);
- case 0x00D7: return((CHAR)215);
- case 0x00DA: return((CHAR)218);
- case 0x00DC: return((CHAR)220);
- case 0x00DD: return((CHAR)221);
- case 0x00DF: return((CHAR)223);
- case 0x00E1: return((CHAR)225);
- case 0x00E2: return((CHAR)226);
- case 0x00E4: return((CHAR)228);
- case 0x00E7: return((CHAR)231);
- case 0x00E9: return((CHAR)233);
- case 0x00EB: return((CHAR)235);
- case 0x00ED: return((CHAR)237);
- case 0x00EE: return((CHAR)238);
- case 0x00F3: return((CHAR)243);
- case 0x00F4: return((CHAR)244);
- case 0x00F6: return((CHAR)246);
- case 0x00F7: return((CHAR)247);
- case 0x00FA: return((CHAR)250);
- case 0x00FC: return((CHAR)252);
- case 0x00FD: return((CHAR)253);
- case 0x0102: return((CHAR)195);
- case 0x0103: return((CHAR)227);
- case 0x0104: return((CHAR)161);
- case 0x0105: return((CHAR)177);
- case 0x0106: return((CHAR)198);
- case 0x0107: return((CHAR)230);
- case 0x010C: return((CHAR)200);
- case 0x010D: return((CHAR)232);
- case 0x010E: return((CHAR)207);
- case 0x010F: return((CHAR)239);
- case 0x0110: return((CHAR)208);
- case 0x0111: return((CHAR)240);
- case 0x0118: return((CHAR)202);
- case 0x0119: return((CHAR)234);
- case 0x011A: return((CHAR)204);
- case 0x011B: return((CHAR)236);
- case 0x0139: return((CHAR)197);
- case 0x013A: return((CHAR)229);
- case 0x013D: return((CHAR)165);
- case 0x013E: return((CHAR)181);
- case 0x0141: return((CHAR)163);
- case 0x0142: return((CHAR)179);
- case 0x0143: return((CHAR)209);
- case 0x0144: return((CHAR)241);
- case 0x0147: return((CHAR)210);
- case 0x0148: return((CHAR)242);
- case 0x0150: return((CHAR)213);
- case 0x0151: return((CHAR)245);
- case 0x0154: return((CHAR)192);
- case 0x0155: return((CHAR)224);
- case 0x0158: return((CHAR)216);
- case 0x0159: return((CHAR)248);
- case 0x015A: return((CHAR)166);
- case 0x015B: return((CHAR)182);
- case 0x015E: return((CHAR)170);
- case 0x015F: return((CHAR)186);
- case 0x0160: return((CHAR)169);
- case 0x0161: return((CHAR)185);
- case 0x0162: return((CHAR)222);
- case 0x0163: return((CHAR)254);
- case 0x0164: return((CHAR)171);
- case 0x0165: return((CHAR)187);
- case 0x016E: return((CHAR)217);
- case 0x016F: return((CHAR)249);
- case 0x0170: return((CHAR)219);
- case 0x0171: return((CHAR)251);
- case 0x0179: return((CHAR)172);
- case 0x017A: return((CHAR)188);
- case 0x017B: return((CHAR)175);
- case 0x017C: return((CHAR)191);
- case 0x017D: return((CHAR)174);
- case 0x017E: return((CHAR)190);
- case 0x02C7: return((CHAR)183);
- case 0x02D8: return((CHAR)162);
- case 0x02D9: return((CHAR)255);
- case 0x02DB: return((CHAR)178);
- case 0x02DD: return((CHAR)189);
- default: return(tx_punc(c));
- }
-}
-
-int /* Latin-3 */
-#ifdef CK_ANSIC
-tx_8859_3(USHORT c)
-#else
-tx_8859_3(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00A0: return((CHAR)160);
- case 0x00A3: return((CHAR)163);
- case 0x00A4: return((CHAR)164);
- case 0x00A7: return((CHAR)167);
- case 0x00A8: return((CHAR)168);
- case 0x00AD: return((CHAR)173);
- case 0x00B0: return((CHAR)176);
- case 0x00B2: return((CHAR)178);
- case 0x00B3: return((CHAR)179);
- case 0x00B4: return((CHAR)180);
- case 0x00B5: return((CHAR)181);
- case 0x00B7: return((CHAR)183);
- case 0x00B8: return((CHAR)184);
- case 0x00BD: return((CHAR)189);
- case 0x00C0: return((CHAR)192);
- case 0x00C1: return((CHAR)193);
- case 0x00C2: return((CHAR)194);
- case 0x00C4: return((CHAR)196);
- case 0x00C7: return((CHAR)199);
- case 0x00C8: return((CHAR)200);
- case 0x00C9: return((CHAR)201);
- case 0x00CA: return((CHAR)202);
- case 0x00CB: return((CHAR)203);
- case 0x00CC: return((CHAR)204);
- case 0x00CD: return((CHAR)205);
- case 0x00CE: return((CHAR)206);
- case 0x00CF: return((CHAR)207);
- case 0x00D1: return((CHAR)209);
- case 0x00D2: return((CHAR)210);
- case 0x00D3: return((CHAR)211);
- case 0x00D4: return((CHAR)212);
- case 0x00D6: return((CHAR)214);
- case 0x00D7: return((CHAR)215);
- case 0x00D9: return((CHAR)217);
- case 0x00DA: return((CHAR)218);
- case 0x00DB: return((CHAR)219);
- case 0x00DC: return((CHAR)220);
- case 0x00DF: return((CHAR)223);
- case 0x00E0: return((CHAR)224);
- case 0x00E1: return((CHAR)225);
- case 0x00E2: return((CHAR)226);
- case 0x00E4: return((CHAR)228);
- case 0x00E7: return((CHAR)231);
- case 0x00E8: return((CHAR)232);
- case 0x00E9: return((CHAR)233);
- case 0x00EA: return((CHAR)234);
- case 0x00EB: return((CHAR)235);
- case 0x00EC: return((CHAR)236);
- case 0x00ED: return((CHAR)237);
- case 0x00EE: return((CHAR)238);
- case 0x00EF: return((CHAR)239);
- case 0x00F1: return((CHAR)241);
- case 0x00F2: return((CHAR)242);
- case 0x00F3: return((CHAR)243);
- case 0x00F4: return((CHAR)244);
- case 0x00F6: return((CHAR)246);
- case 0x00F7: return((CHAR)247);
- case 0x00F9: return((CHAR)249);
- case 0x00FA: return((CHAR)250);
- case 0x00FB: return((CHAR)251);
- case 0x00FC: return((CHAR)252);
- case 0x0108: return((CHAR)198);
- case 0x0109: return((CHAR)230);
- case 0x010A: return((CHAR)197);
- case 0x010B: return((CHAR)229);
- case 0x011C: return((CHAR)216);
- case 0x011D: return((CHAR)248);
- case 0x011E: return((CHAR)171);
- case 0x011F: return((CHAR)187);
- case 0x0120: return((CHAR)213);
- case 0x0121: return((CHAR)245);
- case 0x0124: return((CHAR)166);
- case 0x0125: return((CHAR)182);
- case 0x0126: return((CHAR)161);
- case 0x0127: return((CHAR)177);
- case 0x0130: return((CHAR)169);
- case 0x0131: return((CHAR)185);
- case 0x0134: return((CHAR)172);
- case 0x0135: return((CHAR)188);
- case 0x015C: return((CHAR)222);
- case 0x015D: return((CHAR)254);
- case 0x015E: return((CHAR)170);
- case 0x015F: return((CHAR)186);
- case 0x016C: return((CHAR)221);
- case 0x016D: return((CHAR)253);
- case 0x017B: return((CHAR)175);
- case 0x017C: return((CHAR)191);
- case 0x02D8: return((CHAR)162);
- case 0x02D9: return((CHAR)255);
- default: return(tx_punc(c));
- }
-}
-
-int /* Latin-4 */
-#ifdef CK_ANSIC
-tx_8859_4(USHORT c)
-#else
-tx_8859_4(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00A0: return((CHAR)160);
- case 0x00A4: return((CHAR)164);
- case 0x00A7: return((CHAR)167);
- case 0x00A8: return((CHAR)168);
- case 0x00AD: return((CHAR)173);
- case 0x00AF: return((CHAR)175);
- case 0x00B0: return((CHAR)176);
- case 0x00B4: return((CHAR)180);
- case 0x00B8: return((CHAR)184);
- case 0x00C1: return((CHAR)193);
- case 0x00C2: return((CHAR)194);
- case 0x00C3: return((CHAR)195);
- case 0x00C4: return((CHAR)196);
- case 0x00C5: return((CHAR)197);
- case 0x00C6: return((CHAR)198);
- case 0x00C9: return((CHAR)201);
- case 0x00CB: return((CHAR)203);
- case 0x00CD: return((CHAR)205);
- case 0x00CE: return((CHAR)206);
- case 0x00D4: return((CHAR)212);
- case 0x00D5: return((CHAR)213);
- case 0x00D6: return((CHAR)214);
- case 0x00D7: return((CHAR)215);
- case 0x00D8: return((CHAR)216);
- case 0x00DA: return((CHAR)218);
- case 0x00DB: return((CHAR)219);
- case 0x00DC: return((CHAR)220);
- case 0x00DF: return((CHAR)223);
- case 0x00E1: return((CHAR)225);
- case 0x00E2: return((CHAR)226);
- case 0x00E3: return((CHAR)227);
- case 0x00E4: return((CHAR)228);
- case 0x00E5: return((CHAR)229);
- case 0x00E6: return((CHAR)230);
- case 0x00E9: return((CHAR)233);
- case 0x00EB: return((CHAR)235);
- case 0x00ED: return((CHAR)237);
- case 0x00EE: return((CHAR)238);
- case 0x00F4: return((CHAR)244);
- case 0x00F5: return((CHAR)245);
- case 0x00F6: return((CHAR)246);
- case 0x00F7: return((CHAR)247);
- case 0x00F8: return((CHAR)248);
- case 0x00FA: return((CHAR)250);
- case 0x00FB: return((CHAR)251);
- case 0x00FC: return((CHAR)252);
- case 0x0100: return((CHAR)192);
- case 0x0101: return((CHAR)224);
- case 0x0104: return((CHAR)161);
- case 0x0105: return((CHAR)177);
- case 0x010C: return((CHAR)200);
- case 0x010D: return((CHAR)232);
- case 0x0110: return((CHAR)208);
- case 0x0111: return((CHAR)240);
- case 0x0112: return((CHAR)170);
- case 0x0113: return((CHAR)186);
- case 0x0116: return((CHAR)204);
- case 0x0117: return((CHAR)236);
- case 0x0118: return((CHAR)202);
- case 0x0119: return((CHAR)234);
- case 0x0122: return((CHAR)171);
- case 0x0123: return((CHAR)187);
- case 0x0128: return((CHAR)165);
- case 0x0129: return((CHAR)181);
- case 0x012A: return((CHAR)207);
- case 0x012B: return((CHAR)239);
- case 0x012E: return((CHAR)199);
- case 0x012F: return((CHAR)231);
- case 0x0136: return((CHAR)211);
- case 0x0137: return((CHAR)243);
- case 0x0138: return((CHAR)162);
- case 0x013B: return((CHAR)166);
- case 0x013C: return((CHAR)182);
- case 0x0145: return((CHAR)209);
- case 0x0146: return((CHAR)241);
- case 0x014A: return((CHAR)189);
- case 0x014B: return((CHAR)191);
- case 0x014C: return((CHAR)210);
- case 0x014D: return((CHAR)242);
- case 0x0156: return((CHAR)163);
- case 0x0157: return((CHAR)179);
- case 0x0160: return((CHAR)169);
- case 0x0161: return((CHAR)185);
- case 0x0166: return((CHAR)172);
- case 0x0167: return((CHAR)188);
- case 0x0168: return((CHAR)221);
- case 0x0169: return((CHAR)253);
- case 0x016A: return((CHAR)222);
- case 0x016B: return((CHAR)254);
- case 0x0172: return((CHAR)217);
- case 0x0173: return((CHAR)249);
- case 0x017D: return((CHAR)174);
- case 0x017E: return((CHAR)190);
- case 0x02C7: return((CHAR)183);
- case 0x02D9: return((CHAR)255);
- case 0x02DB: return((CHAR)178);
- default: return(tx_punc(c));
- }
-}
-
-int /* ISO 8859-5 (Latin/Cyrillic) */
-#ifdef CK_ANSIC
-tx_8859_5(USHORT c)
-#else
-tx_8859_5(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0) /* (8859-5 is not Latin-5!) */
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00A0: return((CHAR)160);
- case 0x00A7: return((CHAR)253);
- case 0x00AD: return((CHAR)173);
- case 0x0401: return((CHAR)161);
- case 0x0402: return((CHAR)162);
- case 0x0403: return((CHAR)163);
- case 0x0404: return((CHAR)164);
- case 0x0405: return((CHAR)165);
- case 0x0406: return((CHAR)166);
- case 0x0407: return((CHAR)167);
- case 0x0408: return((CHAR)168);
- case 0x0409: return((CHAR)169);
- case 0x040A: return((CHAR)170);
- case 0x040B: return((CHAR)171);
- case 0x040C: return((CHAR)172);
- case 0x040E: return((CHAR)174);
- case 0x040F: return((CHAR)175);
- case 0x0410: return((CHAR)176);
- case 0x0411: return((CHAR)177);
- case 0x0412: return((CHAR)178);
- case 0x0413: return((CHAR)179);
- case 0x0414: return((CHAR)180);
- case 0x0415: return((CHAR)181);
- case 0x0416: return((CHAR)182);
- case 0x0417: return((CHAR)183);
- case 0x0418: return((CHAR)184);
- case 0x0419: return((CHAR)185);
- case 0x041A: return((CHAR)186);
- case 0x041B: return((CHAR)187);
- case 0x041C: return((CHAR)188);
- case 0x041D: return((CHAR)189);
- case 0x041E: return((CHAR)190);
- case 0x041F: return((CHAR)191);
- case 0x0420: return((CHAR)192);
- case 0x0421: return((CHAR)193);
- case 0x0422: return((CHAR)194);
- case 0x0423: return((CHAR)195);
- case 0x0424: return((CHAR)196);
- case 0x0425: return((CHAR)197);
- case 0x0426: return((CHAR)198);
- case 0x0427: return((CHAR)199);
- case 0x0428: return((CHAR)200);
- case 0x0429: return((CHAR)201);
- case 0x042A: return((CHAR)202);
- case 0x042B: return((CHAR)203);
- case 0x042C: return((CHAR)204);
- case 0x042D: return((CHAR)205);
- case 0x042E: return((CHAR)206);
- case 0x042F: return((CHAR)207);
- case 0x0430: return((CHAR)208);
- case 0x0431: return((CHAR)209);
- case 0x0432: return((CHAR)210);
- case 0x0433: return((CHAR)211);
- case 0x0434: return((CHAR)212);
- case 0x0435: return((CHAR)213);
- case 0x0436: return((CHAR)214);
- case 0x0437: return((CHAR)215);
- case 0x0438: return((CHAR)216);
- case 0x0439: return((CHAR)217);
- case 0x043A: return((CHAR)218);
- case 0x043B: return((CHAR)219);
- case 0x043C: return((CHAR)220);
- case 0x043D: return((CHAR)221);
- case 0x043E: return((CHAR)222);
- case 0x043F: return((CHAR)223);
- case 0x0440: return((CHAR)224);
- case 0x0441: return((CHAR)225);
- case 0x0442: return((CHAR)226);
- case 0x0443: return((CHAR)227);
- case 0x0444: return((CHAR)228);
- case 0x0445: return((CHAR)229);
- case 0x0446: return((CHAR)230);
- case 0x0447: return((CHAR)231);
- case 0x0448: return((CHAR)232);
- case 0x0449: return((CHAR)233);
- case 0x044A: return((CHAR)234);
- case 0x044B: return((CHAR)235);
- case 0x044C: return((CHAR)236);
- case 0x044D: return((CHAR)237);
- case 0x044E: return((CHAR)238);
- case 0x044F: return((CHAR)239);
- case 0x0451: return((CHAR)241);
- case 0x0452: return((CHAR)242);
- case 0x0453: return((CHAR)243);
- case 0x0454: return((CHAR)244);
- case 0x0455: return((CHAR)245);
- case 0x0456: return((CHAR)246);
- case 0x0457: return((CHAR)247);
- case 0x0458: return((CHAR)248);
- case 0x0459: return((CHAR)249);
- case 0x045A: return((CHAR)250);
- case 0x045B: return((CHAR)251);
- case 0x045C: return((CHAR)252);
- case 0x045E: return((CHAR)254);
- case 0x045F: return((CHAR)255);
- case 0x2116: return((CHAR)240);
- default: return(tx_punc(c));
- }
-}
-
-int /* ISO 8859-6 (Latin/Arabic) */
-#ifdef CK_ANSIC
-tx_8859_6(USHORT c)
-#else
-tx_8859_6(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0) /* (8859-6 != Latin-6) */
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00A0: return((CHAR)160);
- case 0x00A4: return((CHAR)164);
- case 0x00AD: return((CHAR)173);
- case 0x060C: return((CHAR)172);
- case 0x061B: return((CHAR)187);
- case 0x061F: return((CHAR)191);
- case 0x0621: return((CHAR)193);
- case 0x0622: return((CHAR)194);
- case 0x0623: return((CHAR)195);
- case 0x0624: return((CHAR)196);
- case 0x0625: return((CHAR)197);
- case 0x0626: return((CHAR)198);
- case 0x0627: return((CHAR)199);
- case 0x0628: return((CHAR)200);
- case 0x0629: return((CHAR)201);
- case 0x062A: return((CHAR)202);
- case 0x062B: return((CHAR)203);
- case 0x062C: return((CHAR)204);
- case 0x062D: return((CHAR)205);
- case 0x062E: return((CHAR)206);
- case 0x062F: return((CHAR)207);
- case 0x0630: return((CHAR)208);
- case 0x0631: return((CHAR)209);
- case 0x0632: return((CHAR)210);
- case 0x0633: return((CHAR)211);
- case 0x0634: return((CHAR)212);
- case 0x0635: return((CHAR)213);
- case 0x0636: return((CHAR)214);
- case 0x0637: return((CHAR)215);
- case 0x0638: return((CHAR)216);
- case 0x0639: return((CHAR)217);
- case 0x063A: return((CHAR)218);
- case 0x0640: return((CHAR)224);
- case 0x0641: return((CHAR)225);
- case 0x0642: return((CHAR)226);
- case 0x0643: return((CHAR)227);
- case 0x0644: return((CHAR)228);
- case 0x0645: return((CHAR)229);
- case 0x0646: return((CHAR)230);
- case 0x0647: return((CHAR)231);
- case 0x0648: return((CHAR)232);
- case 0x0649: return((CHAR)233);
- case 0x064A: return((CHAR)234);
- case 0x064B: return((CHAR)235);
- case 0x064C: return((CHAR)236);
- case 0x064D: return((CHAR)237);
- case 0x064E: return((CHAR)238);
- case 0x064F: return((CHAR)239);
- case 0x0650: return((CHAR)240);
- case 0x0651: return((CHAR)241);
- case 0x0652: return((CHAR)242);
- default: return(tx_punc(c));
- }
-}
-
-int /* ISO 8859-7 (Latin/Greek) */
-#ifdef CK_ANSIC
-tx_8859_7(USHORT c)
-#else
-tx_8859_7(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00a0: return((CHAR)160);
- case 0x00a3: return((CHAR)163);
- case 0x00a6: return((CHAR)166);
- case 0x00a7: return((CHAR)167);
- case 0x00a8: return((CHAR)168);
- case 0x00a9: return((CHAR)169);
- case 0x00ab: return((CHAR)171);
- case 0x00ac: return((CHAR)172);
- case 0x00ad: return((CHAR)173);
- case 0x00b0: return((CHAR)176);
- case 0x00b1: return((CHAR)177);
- case 0x00b2: return((CHAR)178);
- case 0x00b3: return((CHAR)179);
- case 0x00b7: return((CHAR)183);
- case 0x00bb: return((CHAR)187);
- case 0x00bd: return((CHAR)189);
- case 0x02bc: return((CHAR)162);
- case 0x02bd: return((CHAR)161);
- case 0x0384: return((CHAR)180);
- case 0x0385: return((CHAR)181);
- case 0x0386: return((CHAR)182);
- case 0x0388: return((CHAR)184);
- case 0x0389: return((CHAR)185);
- case 0x038a: return((CHAR)186);
- case 0x038c: return((CHAR)188);
- case 0x038e: return((CHAR)190);
- case 0x038f: return((CHAR)191);
- case 0x0390: return((CHAR)192);
- case 0x0391: return((CHAR)193);
- case 0x0392: return((CHAR)194);
- case 0x0393: return((CHAR)195);
- case 0x0394: return((CHAR)196);
- case 0x0395: return((CHAR)197);
- case 0x0396: return((CHAR)198);
- case 0x0397: return((CHAR)199);
- case 0x0398: return((CHAR)200);
- case 0x0399: return((CHAR)201);
- case 0x039a: return((CHAR)202);
- case 0x039b: return((CHAR)203);
- case 0x039c: return((CHAR)204);
- case 0x039d: return((CHAR)205);
- case 0x039e: return((CHAR)206);
- case 0x039f: return((CHAR)207);
- case 0x03a0: return((CHAR)208);
- case 0x03a1: return((CHAR)209);
- case 0x03a3: return((CHAR)211);
- case 0x03a4: return((CHAR)212);
- case 0x03a5: return((CHAR)213);
- case 0x03a6: return((CHAR)214);
- case 0x03a7: return((CHAR)215);
- case 0x03a8: return((CHAR)216);
- case 0x03a9: return((CHAR)217);
- case 0x03aa: return((CHAR)218);
- case 0x03ab: return((CHAR)219);
- case 0x03ac: return((CHAR)220);
- case 0x03ad: return((CHAR)221);
- case 0x03ae: return((CHAR)222);
- case 0x03af: return((CHAR)223);
- case 0x03b0: return((CHAR)224);
- case 0x03b1: return((CHAR)225);
- case 0x03b2: return((CHAR)226);
- case 0x03b3: return((CHAR)227);
- case 0x03b4: return((CHAR)228);
- case 0x03b5: return((CHAR)229);
- case 0x03b6: return((CHAR)230);
- case 0x03b7: return((CHAR)231);
- case 0x03b8: return((CHAR)232);
- case 0x03b9: return((CHAR)233);
- case 0x03ba: return((CHAR)234);
- case 0x03bb: return((CHAR)235);
- case 0x03bc: return((CHAR)236);
- case 0x03bd: return((CHAR)237);
- case 0x03be: return((CHAR)238);
- case 0x03bf: return((CHAR)239);
- case 0x03c0: return((CHAR)240);
- case 0x03c1: return((CHAR)241);
- case 0x03c2: return((CHAR)242);
- case 0x03c3: return((CHAR)243);
- case 0x03c4: return((CHAR)244);
- case 0x03c5: return((CHAR)245);
- case 0x03c6: return((CHAR)246);
- case 0x03c7: return((CHAR)247);
- case 0x03c8: return((CHAR)248);
- case 0x03c9: return((CHAR)249);
- case 0x03ca: return((CHAR)250);
- case 0x03cb: return((CHAR)251);
- case 0x03cc: return((CHAR)252);
- case 0x03cd: return((CHAR)253);
- case 0x03ce: return((CHAR)254);
- case 0x2015: return((CHAR)175);
- case 0x2018: return((CHAR)161);
- case 0x2019: return((CHAR)162);
- default: return(tx_punc(c));
- }
-}
-
-int /* ISO 8859-8 (Latin/Hebrew) */
-#ifdef CK_ANSIC
-tx_8859_8(USHORT c)
-#else
-tx_8859_8(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00a0: return((CHAR)160);
- case 0x00a2: return((CHAR)162);
- case 0x00a3: return((CHAR)163);
- case 0x00a4: return((CHAR)164);
- case 0x00a5: return((CHAR)165);
- case 0x00a6: return((CHAR)166);
- case 0x00a7: return((CHAR)167);
- case 0x00a8: return((CHAR)168);
- case 0x00a9: return((CHAR)169);
- case 0x00d7: return((CHAR)170);
- case 0x00ab: return((CHAR)171);
- case 0x00ac: return((CHAR)172);
- case 0x00ad: return((CHAR)173);
- case 0x00ae: return((CHAR)174);
- case 0x203e: return((CHAR)175);
- case 0x00b0: return((CHAR)176);
- case 0x00b1: return((CHAR)177);
- case 0x00b2: return((CHAR)178);
- case 0x00b3: return((CHAR)179);
- case 0x00b4: return((CHAR)180);
- case 0x00b5: return((CHAR)181);
- case 0x00b6: return((CHAR)182);
- case 0x00b7: return((CHAR)183);
- case 0x00b8: return((CHAR)184);
- case 0x00b9: return((CHAR)185);
- case 0x00f7: return((CHAR)186);
- case 0x00bb: return((CHAR)187);
- case 0x00bc: return((CHAR)188);
- case 0x00bd: return((CHAR)189);
- case 0x00be: return((CHAR)190);
- case 0x2017: return((CHAR)223);
- case 0x05d0: return((CHAR)224);
- case 0x05d1: return((CHAR)225);
- case 0x05d2: return((CHAR)226);
- case 0x05d3: return((CHAR)227);
- case 0x05d4: return((CHAR)228);
- case 0x05d5: return((CHAR)229);
- case 0x05d6: return((CHAR)230);
- case 0x05d7: return((CHAR)231);
- case 0x05d8: return((CHAR)232);
- case 0x05d9: return((CHAR)233);
- case 0x05da: return((CHAR)234);
- case 0x05db: return((CHAR)235);
- case 0x05dc: return((CHAR)236);
- case 0x05dd: return((CHAR)237);
- case 0x05de: return((CHAR)238);
- case 0x05df: return((CHAR)239);
- case 0x05e0: return((CHAR)240);
- case 0x05e1: return((CHAR)241);
- case 0x05e2: return((CHAR)242);
- case 0x05e3: return((CHAR)243);
- case 0x05e4: return((CHAR)244);
- case 0x05e5: return((CHAR)245);
- case 0x05e6: return((CHAR)246);
- case 0x05e7: return((CHAR)247);
- case 0x05e8: return((CHAR)248);
- case 0x05e9: return((CHAR)249);
- case 0x05ea: return((CHAR)250);
- default: return(tx_punc(c));
- }
-}
-
-int /* ISO 8859-9 (Latin-4) */
-#ifdef CK_ANSIC
-tx_8859_9(USHORT c)
-#else
-tx_8859_9(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x011E: return((CHAR)208); /* Differs from Latin-1 in */
- case 0x011F: return((CHAR)240); /* only six places */
- case 0x0130: return((CHAR)221);
- case 0x0131: return((CHAR)253);
- case 0x015E: return((CHAR)222);
- case 0x015F: return((CHAR)254);
- default: return(tx_ident(c));
- }
-}
-
-int /* Latin-6 */
-#ifdef CK_ANSIC
-tx_8859_10(USHORT c)
-#else
-tx_8859_10(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00a0: return((CHAR)160);
- case 0x00ad: return((CHAR)173);
- case 0x00bd: return((CHAR)189);
- case 0x00be: return((CHAR)190);
- case 0x00c1: return((CHAR)193);
- case 0x00c2: return((CHAR)194);
- case 0x00c3: return((CHAR)195);
- case 0x00c4: return((CHAR)196);
- case 0x00c5: return((CHAR)197);
- case 0x00c6: return((CHAR)198);
- case 0x00c9: return((CHAR)201);
- case 0x00cb: return((CHAR)203);
- case 0x00cd: return((CHAR)205);
- case 0x00ce: return((CHAR)206);
- case 0x00cf: return((CHAR)207);
- case 0x00d3: return((CHAR)211);
- case 0x00d4: return((CHAR)212);
- case 0x00d5: return((CHAR)213);
- case 0x00d6: return((CHAR)214);
- case 0x00d8: return((CHAR)216);
- case 0x00da: return((CHAR)218);
- case 0x00db: return((CHAR)219);
- case 0x00dc: return((CHAR)220);
- case 0x00dd: return((CHAR)221);
- case 0x00de: return((CHAR)222);
- case 0x00e1: return((CHAR)225);
- case 0x00e2: return((CHAR)226);
- case 0x00e3: return((CHAR)227);
- case 0x00e4: return((CHAR)228);
- case 0x00e5: return((CHAR)229);
- case 0x00e6: return((CHAR)230);
- case 0x00e9: return((CHAR)233);
- case 0x00eb: return((CHAR)235);
- case 0x00ed: return((CHAR)237);
- case 0x00ee: return((CHAR)238);
- case 0x00ef: return((CHAR)239);
- case 0x00f0: return((CHAR)240);
- case 0x00f1: return((CHAR)241);
- case 0x00f3: return((CHAR)243);
- case 0x00f4: return((CHAR)244);
- case 0x00f5: return((CHAR)245);
- case 0x00f6: return((CHAR)246);
- case 0x00f8: return((CHAR)248);
- case 0x00fa: return((CHAR)250);
- case 0x00fb: return((CHAR)251);
- case 0x00fc: return((CHAR)252);
- case 0x00fd: return((CHAR)253);
- case 0x00fe: return((CHAR)254);
- case 0x0100: return((CHAR)192);
- case 0x0101: return((CHAR)224);
- case 0x0104: return((CHAR)161);
- case 0x0105: return((CHAR)177);
- case 0x010c: return((CHAR)200);
- case 0x010d: return((CHAR)232);
- case 0x0110: return((CHAR)208);
- case 0x0111: return((CHAR)176);
- case 0x0112: return((CHAR)162);
- case 0x0113: return((CHAR)178);
- case 0x0116: return((CHAR)204);
- case 0x0117: return((CHAR)236);
- case 0x0118: return((CHAR)202);
- case 0x0119: return((CHAR)234);
- case 0x0122: return((CHAR)163);
- case 0x0123: return((CHAR)179);
- case 0x0128: return((CHAR)165);
- case 0x0129: return((CHAR)181);
- case 0x012a: return((CHAR)164);
- case 0x012b: return((CHAR)180);
- case 0x012e: return((CHAR)199);
- case 0x012f: return((CHAR)231);
- case 0x0136: return((CHAR)166);
- case 0x0137: return((CHAR)182);
- case 0x0138: return((CHAR)174);
- case 0x013b: return((CHAR)167);
- case 0x013c: return((CHAR)183);
- case 0x0143: return((CHAR)168);
- case 0x0144: return((CHAR)184);
- case 0x0145: return((CHAR)209);
- case 0x014a: return((CHAR)175);
- case 0x014b: return((CHAR)191);
- case 0x014c: return((CHAR)210);
- case 0x014d: return((CHAR)242);
- case 0x0156: return((CHAR)169);
- case 0x0157: return((CHAR)185);
- case 0x0160: return((CHAR)170);
- case 0x0161: return((CHAR)186);
- case 0x0166: return((CHAR)171);
- case 0x0167: return((CHAR)187);
- case 0x0168: return((CHAR)215);
- case 0x0169: return((CHAR)247);
- case 0x016a: return((CHAR)223);
- case 0x016b: return((CHAR)255);
- case 0x0172: return((CHAR)217);
- case 0x0173: return((CHAR)249);
- case 0x017d: return((CHAR)172);
- case 0x017e: return((CHAR)188);
- default: return(tx_ident(c));
- }
-}
-
-
-int /* ISO 8859-15 Latin-9 */
-#ifdef CK_ANSIC
-tx_8859_15(USHORT c)
-#else
-tx_8859_15(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x20AC: return((CHAR)0xA4); /* Differs from Latin-1 in */
- case 0x0160: return((CHAR)0xAC); /* only eight places */
- case 0x0161: return((CHAR)0xA8);
- case 0x017D: return((CHAR)0xB4);
- case 0x017E: return((CHAR)0xB8);
- case 0x0152: return((CHAR)0xBC);
- case 0x0153: return((CHAR)0xBD);
- case 0x0178: return((CHAR)0xBE);
- default: return(tx_ident(c));
- }
-}
-
-int /* Old KOI-8 (ECMA 113 First Ed.) */
-#ifdef CK_ANSIC
-tx_koi8(USHORT c)
-#else
-tx_koi8(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x0410: return((CHAR)(225 & 0xff));
- case 0x0411: return((CHAR)(226 & 0xff));
- case 0x0412: return((CHAR)(247 & 0xff));
- case 0x0413: return((CHAR)(231 & 0xff));
- case 0x0414: return((CHAR)(228 & 0xff));
- case 0x0415: return((CHAR)(229 & 0xff));
- case 0x0416: return((CHAR)(246 & 0xff));
- case 0x0417: return((CHAR)(250 & 0xff));
- case 0x0418: return((CHAR)(233 & 0xff));
- case 0x0419: return((CHAR)(234 & 0xff));
- case 0x041a: return((CHAR)(235 & 0xff));
- case 0x041b: return((CHAR)(236 & 0xff));
- case 0x041c: return((CHAR)(237 & 0xff));
- case 0x041d: return((CHAR)(238 & 0xff));
- case 0x041e: return((CHAR)(239 & 0xff));
- case 0x041f: return((CHAR)(240 & 0xff));
- case 0x0420: return((CHAR)(242 & 0xff));
- case 0x0421: return((CHAR)(243 & 0xff));
- case 0x0422: return((CHAR)(244 & 0xff));
- case 0x0423: return((CHAR)(245 & 0xff));
- case 0x0424: return((CHAR)(230 & 0xff));
- case 0x0425: return((CHAR)(232 & 0xff));
- case 0x0426: return((CHAR)(227 & 0xff));
- case 0x0427: return((CHAR)(254 & 0xff));
- case 0x0428: return((CHAR)(251 & 0xff));
- case 0x0429: return((CHAR)(253 & 0xff));
- case 0x042b: return((CHAR)(249 & 0xff));
- case 0x042c: return((CHAR)(248 & 0xff));
- case 0x042d: return((CHAR)(252 & 0xff));
- case 0x042e: return((CHAR)(224 & 0xff));
- case 0x042f: return((CHAR)(241 & 0xff));
- case 0x0430: return((CHAR)(193 & 0xff));
- case 0x0431: return((CHAR)(194 & 0xff));
- case 0x0432: return((CHAR)(215 & 0xff));
- case 0x0433: return((CHAR)(199 & 0xff));
- case 0x0434: return((CHAR)(196 & 0xff));
- case 0x0435: return((CHAR)(197 & 0xff));
- case 0x0436: return((CHAR)(214 & 0xff));
- case 0x0437: return((CHAR)(218 & 0xff));
- case 0x0438: return((CHAR)(201 & 0xff));
- case 0x0439: return((CHAR)(202 & 0xff));
- case 0x043a: return((CHAR)(203 & 0xff));
- case 0x043b: return((CHAR)(204 & 0xff));
- case 0x043c: return((CHAR)(205 & 0xff));
- case 0x043d: return((CHAR)(206 & 0xff));
- case 0x043e: return((CHAR)(207 & 0xff));
- case 0x043f: return((CHAR)(208 & 0xff));
- case 0x0440: return((CHAR)(210 & 0xff));
- case 0x0441: return((CHAR)(211 & 0xff));
- case 0x0442: return((CHAR)(212 & 0xff));
- case 0x0443: return((CHAR)(213 & 0xff));
- case 0x0444: return((CHAR)(198 & 0xff));
- case 0x0445: return((CHAR)(200 & 0xff));
- case 0x0446: return((CHAR)(195 & 0xff));
- case 0x0447: return((CHAR)(222 & 0xff));
- case 0x0448: return((CHAR)(219 & 0xff));
- case 0x0449: return((CHAR)(221 & 0xff));
- case 0x044a: return((CHAR)(223 & 0xff));
- case 0x044b: return((CHAR)(217 & 0xff));
- case 0x044c: return((CHAR)(216 & 0xff));
- case 0x044d: return((CHAR)(220 & 0xff));
- case 0x044e: return((CHAR)(192 & 0xff));
- case 0x044f: return((CHAR)(209 & 0xff));
- default: return(tx_ident(c));
- }
-}
-
-int /* UCS-2 to KOI8-R (Russia) */
-#ifdef CK_ANSIC
-tx_koi8r(USHORT c)
-#else
-tx_koi8r(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x00A0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00A0: return((CHAR)(154 & 0xff));
- case 0x00A9: return((CHAR)(191 & 0xff));
- case 0x00B0: return((CHAR)(156 & 0xff));
- case 0x00B2: return((CHAR)(157 & 0xff));
- case 0x00B7: return((CHAR)(158 & 0xff));
- case 0x00F7: return((CHAR)(159 & 0xff));
- case 0x0401: return((CHAR)(179 & 0xff));
- case 0x0410: return((CHAR)(225 & 0xff));
- case 0x0411: return((CHAR)(226 & 0xff));
- case 0x0412: return((CHAR)(247 & 0xff));
- case 0x0413: return((CHAR)(231 & 0xff));
- case 0x0414: return((CHAR)(228 & 0xff));
- case 0x0415: return((CHAR)(229 & 0xff));
- case 0x0416: return((CHAR)(246 & 0xff));
- case 0x0417: return((CHAR)(250 & 0xff));
- case 0x0418: return((CHAR)(233 & 0xff));
- case 0x0419: return((CHAR)(234 & 0xff));
- case 0x041A: return((CHAR)(235 & 0xff));
- case 0x041B: return((CHAR)(236 & 0xff));
- case 0x041C: return((CHAR)(237 & 0xff));
- case 0x041D: return((CHAR)(238 & 0xff));
- case 0x041E: return((CHAR)(239 & 0xff));
- case 0x041F: return((CHAR)(240 & 0xff));
- case 0x0420: return((CHAR)(242 & 0xff));
- case 0x0421: return((CHAR)(243 & 0xff));
- case 0x0422: return((CHAR)(244 & 0xff));
- case 0x0423: return((CHAR)(245 & 0xff));
- case 0x0424: return((CHAR)(230 & 0xff));
- case 0x0425: return((CHAR)(232 & 0xff));
- case 0x0426: return((CHAR)(227 & 0xff));
- case 0x0427: return((CHAR)(254 & 0xff));
- case 0x0428: return((CHAR)(251 & 0xff));
- case 0x0429: return((CHAR)(253 & 0xff));
- case 0x042A: return((CHAR)(255 & 0xff));
- case 0x042B: return((CHAR)(249 & 0xff));
- case 0x042C: return((CHAR)(248 & 0xff));
- case 0x042D: return((CHAR)(252 & 0xff));
- case 0x042E: return((CHAR)(224 & 0xff));
- case 0x042F: return((CHAR)(241 & 0xff));
- case 0x0430: return((CHAR)(193 & 0xff));
- case 0x0431: return((CHAR)(194 & 0xff));
- case 0x0432: return((CHAR)(215 & 0xff));
- case 0x0433: return((CHAR)(199 & 0xff));
- case 0x0434: return((CHAR)(196 & 0xff));
- case 0x0435: return((CHAR)(197 & 0xff));
- case 0x0436: return((CHAR)(214 & 0xff));
- case 0x0437: return((CHAR)(218 & 0xff));
- case 0x0438: return((CHAR)(201 & 0xff));
- case 0x0439: return((CHAR)(202 & 0xff));
- case 0x043A: return((CHAR)(203 & 0xff));
- case 0x043B: return((CHAR)(204 & 0xff));
- case 0x043C: return((CHAR)(205 & 0xff));
- case 0x043D: return((CHAR)(206 & 0xff));
- case 0x043E: return((CHAR)(207 & 0xff));
- case 0x043F: return((CHAR)(208 & 0xff));
- case 0x0440: return((CHAR)(210 & 0xff));
- case 0x0441: return((CHAR)(211 & 0xff));
- case 0x0442: return((CHAR)(212 & 0xff));
- case 0x0443: return((CHAR)(213 & 0xff));
- case 0x0444: return((CHAR)(198 & 0xff));
- case 0x0445: return((CHAR)(200 & 0xff));
- case 0x0446: return((CHAR)(195 & 0xff));
- case 0x0447: return((CHAR)(222 & 0xff));
- case 0x0448: return((CHAR)(219 & 0xff));
- case 0x0449: return((CHAR)(221 & 0xff));
- case 0x044A: return((CHAR)(223 & 0xff));
- case 0x044B: return((CHAR)(217 & 0xff));
- case 0x044C: return((CHAR)(216 & 0xff));
- case 0x044D: return((CHAR)(220 & 0xff));
- case 0x044E: return((CHAR)(192 & 0xff));
- case 0x044F: return((CHAR)(209 & 0xff));
- case 0x0451: return((CHAR)(163 & 0xff));
- case 0x2219: return((CHAR)(149 & 0xff));
- case 0x221A: return((CHAR)(150 & 0xff));
- case 0x2248: return((CHAR)(151 & 0xff));
- case 0x2264: return((CHAR)(152 & 0xff));
- case 0x2265: return((CHAR)(153 & 0xff));
- case 0x2320: return((CHAR)(147 & 0xff));
- case 0x2321: return((CHAR)(155 & 0xff));
- case 0x2500: return((CHAR)(128 & 0xff));
- case 0x2502: return((CHAR)(129 & 0xff));
- case 0x250C: return((CHAR)(130 & 0xff));
- case 0x2510: return((CHAR)(131 & 0xff));
- case 0x2514: return((CHAR)(132 & 0xff));
- case 0x2518: return((CHAR)(133 & 0xff));
- case 0x251C: return((CHAR)(134 & 0xff));
- case 0x2524: return((CHAR)(135 & 0xff));
- case 0x252C: return((CHAR)(136 & 0xff));
- case 0x2534: return((CHAR)(137 & 0xff));
- case 0x253C: return((CHAR)(138 & 0xff));
- case 0x2550: return((CHAR)(160 & 0xff));
- case 0x2551: return((CHAR)(161 & 0xff));
- case 0x2552: return((CHAR)(162 & 0xff));
- case 0x2553: return((CHAR)(164 & 0xff));
- case 0x2554: return((CHAR)(165 & 0xff));
- case 0x2555: return((CHAR)(166 & 0xff));
- case 0x2556: return((CHAR)(167 & 0xff));
- case 0x2557: return((CHAR)(168 & 0xff));
- case 0x2558: return((CHAR)(169 & 0xff));
- case 0x2559: return((CHAR)(170 & 0xff));
- case 0x255A: return((CHAR)(171 & 0xff));
- case 0x255B: return((CHAR)(172 & 0xff));
- case 0x255C: return((CHAR)(173 & 0xff));
- case 0x255D: return((CHAR)(174 & 0xff));
- case 0x255E: return((CHAR)(175 & 0xff));
- case 0x255F: return((CHAR)(176 & 0xff));
- case 0x2560: return((CHAR)(177 & 0xff));
- case 0x2561: return((CHAR)(178 & 0xff));
- case 0x2562: return((CHAR)(180 & 0xff));
- case 0x2563: return((CHAR)(181 & 0xff));
- case 0x2564: return((CHAR)(182 & 0xff));
- case 0x2565: return((CHAR)(183 & 0xff));
- case 0x2566: return((CHAR)(184 & 0xff));
- case 0x2567: return((CHAR)(185 & 0xff));
- case 0x2568: return((CHAR)(186 & 0xff));
- case 0x2569: return((CHAR)(187 & 0xff));
- case 0x256A: return((CHAR)(188 & 0xff));
- case 0x256B: return((CHAR)(189 & 0xff));
- case 0x256C: return((CHAR)(190 & 0xff));
- case 0x2580: return((CHAR)(139 & 0xff));
- case 0x2584: return((CHAR)(140 & 0xff));
- case 0x2588: return((CHAR)(141 & 0xff));
- case 0x258C: return((CHAR)(142 & 0xff));
- case 0x2590: return((CHAR)(143 & 0xff));
- case 0x2591: return((CHAR)(144 & 0xff));
- case 0x2592: return((CHAR)(145 & 0xff));
- case 0x2593: return((CHAR)(146 & 0xff));
- case 0x25A0: return((CHAR)(148 & 0xff));
- default: return(tx_ident(c));
- }
-}
-
-int /* KOI8-U (Ukraine) */
-#ifdef CK_ANSIC
-tx_koi8u(USHORT c)
-#else
-tx_koi8u(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00A0: return((CHAR)(154 & 0xff));
- case 0x00A9: return((CHAR)(191 & 0xff));
- case 0x00B0: return((CHAR)(156 & 0xff));
- case 0x00B2: return((CHAR)(157 & 0xff));
- case 0x00B7: return((CHAR)(158 & 0xff));
- case 0x00F7: return((CHAR)(159 & 0xff));
- case 0x0401: return((CHAR)(179 & 0xff));
- case 0x0404: return((CHAR)(180 & 0xff));
- case 0x0406: return((CHAR)(182 & 0xff));
- case 0x0407: return((CHAR)(183 & 0xff));
- case 0x0410: return((CHAR)(225 & 0xff));
- case 0x0411: return((CHAR)(226 & 0xff));
- case 0x0412: return((CHAR)(247 & 0xff));
- case 0x0413: return((CHAR)(231 & 0xff));
- case 0x0414: return((CHAR)(228 & 0xff));
- case 0x0415: return((CHAR)(229 & 0xff));
- case 0x0416: return((CHAR)(246 & 0xff));
- case 0x0417: return((CHAR)(250 & 0xff));
- case 0x0418: return((CHAR)(233 & 0xff));
- case 0x0419: return((CHAR)(234 & 0xff));
- case 0x041A: return((CHAR)(235 & 0xff));
- case 0x041B: return((CHAR)(236 & 0xff));
- case 0x041C: return((CHAR)(237 & 0xff));
- case 0x041D: return((CHAR)(238 & 0xff));
- case 0x041E: return((CHAR)(239 & 0xff));
- case 0x041F: return((CHAR)(240 & 0xff));
- case 0x0420: return((CHAR)(242 & 0xff));
- case 0x0421: return((CHAR)(243 & 0xff));
- case 0x0422: return((CHAR)(244 & 0xff));
- case 0x0423: return((CHAR)(245 & 0xff));
- case 0x0424: return((CHAR)(230 & 0xff));
- case 0x0425: return((CHAR)(232 & 0xff));
- case 0x0426: return((CHAR)(227 & 0xff));
- case 0x0427: return((CHAR)(254 & 0xff));
- case 0x0428: return((CHAR)(251 & 0xff));
- case 0x0429: return((CHAR)(253 & 0xff));
- case 0x042A: return((CHAR)(255 & 0xff));
- case 0x042B: return((CHAR)(249 & 0xff));
- case 0x042C: return((CHAR)(248 & 0xff));
- case 0x042D: return((CHAR)(252 & 0xff));
- case 0x042E: return((CHAR)(224 & 0xff));
- case 0x042F: return((CHAR)(241 & 0xff));
- case 0x0430: return((CHAR)(193 & 0xff));
- case 0x0431: return((CHAR)(194 & 0xff));
- case 0x0432: return((CHAR)(215 & 0xff));
- case 0x0433: return((CHAR)(199 & 0xff));
- case 0x0434: return((CHAR)(196 & 0xff));
- case 0x0435: return((CHAR)(197 & 0xff));
- case 0x0436: return((CHAR)(214 & 0xff));
- case 0x0437: return((CHAR)(218 & 0xff));
- case 0x0438: return((CHAR)(201 & 0xff));
- case 0x0439: return((CHAR)(202 & 0xff));
- case 0x043A: return((CHAR)(203 & 0xff));
- case 0x043B: return((CHAR)(204 & 0xff));
- case 0x043C: return((CHAR)(205 & 0xff));
- case 0x043D: return((CHAR)(206 & 0xff));
- case 0x043E: return((CHAR)(207 & 0xff));
- case 0x043F: return((CHAR)(208 & 0xff));
- case 0x0440: return((CHAR)(210 & 0xff));
- case 0x0441: return((CHAR)(211 & 0xff));
- case 0x0442: return((CHAR)(212 & 0xff));
- case 0x0443: return((CHAR)(213 & 0xff));
- case 0x0444: return((CHAR)(198 & 0xff));
- case 0x0445: return((CHAR)(200 & 0xff));
- case 0x0446: return((CHAR)(195 & 0xff));
- case 0x0447: return((CHAR)(222 & 0xff));
- case 0x0448: return((CHAR)(219 & 0xff));
- case 0x0449: return((CHAR)(221 & 0xff));
- case 0x044A: return((CHAR)(223 & 0xff));
- case 0x044B: return((CHAR)(217 & 0xff));
- case 0x044C: return((CHAR)(216 & 0xff));
- case 0x044D: return((CHAR)(220 & 0xff));
- case 0x044E: return((CHAR)(192 & 0xff));
- case 0x044F: return((CHAR)(209 & 0xff));
- case 0x0451: return((CHAR)(163 & 0xff));
- case 0x0454: return((CHAR)(164 & 0xff));
- case 0x0456: return((CHAR)(166 & 0xff));
- case 0x0457: return((CHAR)(167 & 0xff));
- case 0x0490: return((CHAR)(189 & 0xff));
- case 0x0491: return((CHAR)(173 & 0xff));
- case 0x2219: return((CHAR)(149 & 0xff));
- case 0x221A: return((CHAR)(150 & 0xff));
- case 0x2248: return((CHAR)(151 & 0xff));
- case 0x2264: return((CHAR)(152 & 0xff));
- case 0x2265: return((CHAR)(153 & 0xff));
- case 0x2320: return((CHAR)(147 & 0xff));
- case 0x2321: return((CHAR)(155 & 0xff));
- case 0x2500: return((CHAR)(128 & 0xff));
- case 0x2502: return((CHAR)(129 & 0xff));
- case 0x250C: return((CHAR)(130 & 0xff));
- case 0x2510: return((CHAR)(131 & 0xff));
- case 0x2514: return((CHAR)(132 & 0xff));
- case 0x2518: return((CHAR)(133 & 0xff));
- case 0x251C: return((CHAR)(134 & 0xff));
- case 0x2524: return((CHAR)(135 & 0xff));
- case 0x252C: return((CHAR)(136 & 0xff));
- case 0x2534: return((CHAR)(137 & 0xff));
- case 0x253C: return((CHAR)(138 & 0xff));
- case 0x2550: return((CHAR)(160 & 0xff));
- case 0x2551: return((CHAR)(161 & 0xff));
- case 0x2552: return((CHAR)(162 & 0xff));
- case 0x2554: return((CHAR)(165 & 0xff));
- case 0x2557: return((CHAR)(168 & 0xff));
- case 0x2558: return((CHAR)(169 & 0xff));
- case 0x2559: return((CHAR)(170 & 0xff));
- case 0x255A: return((CHAR)(171 & 0xff));
- case 0x255B: return((CHAR)(172 & 0xff));
- case 0x255D: return((CHAR)(174 & 0xff));
- case 0x255E: return((CHAR)(175 & 0xff));
- case 0x255F: return((CHAR)(176 & 0xff));
- case 0x2560: return((CHAR)(177 & 0xff));
- case 0x2561: return((CHAR)(178 & 0xff));
- case 0x2563: return((CHAR)(181 & 0xff));
- case 0x2566: return((CHAR)(184 & 0xff));
- case 0x2567: return((CHAR)(185 & 0xff));
- case 0x2568: return((CHAR)(186 & 0xff));
- case 0x2569: return((CHAR)(187 & 0xff));
- case 0x256A: return((CHAR)(188 & 0xff));
- case 0x256C: return((CHAR)(190 & 0xff));
- case 0x2580: return((CHAR)(139 & 0xff));
- case 0x2584: return((CHAR)(140 & 0xff));
- case 0x2588: return((CHAR)(141 & 0xff));
- case 0x258C: return((CHAR)(142 & 0xff));
- case 0x2590: return((CHAR)(143 & 0xff));
- case 0x2591: return((CHAR)(144 & 0xff));
- case 0x2592: return((CHAR)(145 & 0xff));
- case 0x2593: return((CHAR)(146 & 0xff));
- case 0x25A0: return((CHAR)(148 & 0xff));
- default: return(tx_ident(c));
- }
-}
-
-
-int /* DEC MCS */
-#ifdef CK_ANSIC
-tx_decmcs(USHORT c)
-#else
-tx_decmcs(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00a6:
- case 0x00a8:
- case 0x00ac:
- case 0x00ae:
- case 0x00af:
- case 0x00b4:
- case 0x00b8:
- case 0x00be:
- case 0x00d0:
- case 0x00de:
- case 0x00f0:
- case 0x00fe:
- case 0x00ff:
- return(-1); /* These are all undefined in DECMCS */
- case 0x00a4: /* Currency sign */
- return((CHAR)0xa8);
- case 0x0152: /* OE */
- return((CHAR)0xd7);
- case 0x0153: /* oe */
- return((CHAR)0xf7);
- default: return(tx_ident(c));
- }
-}
-
-int /* NeXTSTEP */
-#ifdef CK_ANSIC
-tx_nextstep(USHORT c)
-#else
-tx_nextstep(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a0: return((CHAR)(128 & 0xff));
- case 0x00a1: return((CHAR)(161 & 0xff));
- case 0x00a2: return((CHAR)(162 & 0xff));
- case 0x00a3: return((CHAR)(163 & 0xff));
- case 0x00a4: return((CHAR)(168 & 0xff));
- case 0x00a5: return((CHAR)(165 & 0xff));
- case 0x00a6: return((CHAR)(181 & 0xff));
- case 0x00a7: return((CHAR)(167 & 0xff));
- case 0x00a8: return((CHAR)(200 & 0xff));
- case 0x00a9: return((CHAR)(160 & 0xff));
- case 0x00aa: return((CHAR)(227 & 0xff));
- case 0x00ab: return((CHAR)(171 & 0xff));
- case 0x00ac: return((CHAR)(190 & 0xff));
- case 0x00ae: return((CHAR)(176 & 0xff));
- case 0x00af: return((CHAR)(197 & 0xff));
- case 0x00b1: return((CHAR)(209 & 0xff));
- case 0x00b2: return((CHAR)(201 & 0xff));
- case 0x00b3: return((CHAR)(204 & 0xff));
- case 0x00b4: return((CHAR)(194 & 0xff));
- case 0x00b5: return((CHAR)(157 & 0xff));
- case 0x00b6: return((CHAR)(182 & 0xff));
- case 0x00b7: return((CHAR)(180 & 0xff));
- case 0x00b8: return((CHAR)(203 & 0xff));
- case 0x00b9: return((CHAR)(192 & 0xff));
- case 0x00ba: return((CHAR)(235 & 0xff));
- case 0x00bb: return((CHAR)(187 & 0xff));
- case 0x00bc: return((CHAR)(210 & 0xff));
- case 0x00bd: return((CHAR)(211 & 0xff));
- case 0x00be: return((CHAR)(212 & 0xff));
- case 0x00bf: return((CHAR)(191 & 0xff));
- case 0x00c0: return((CHAR)(129 & 0xff));
- case 0x00c1: return((CHAR)(130 & 0xff));
- case 0x00c2: return((CHAR)(131 & 0xff));
- case 0x00c3: return((CHAR)(132 & 0xff));
- case 0x00c4: return((CHAR)(133 & 0xff));
- case 0x00c5: return((CHAR)(134 & 0xff));
- case 0x00c6: return((CHAR)(225 & 0xff));
- case 0x00c7: return((CHAR)(135 & 0xff));
- case 0x00c8: return((CHAR)(136 & 0xff));
- case 0x00c9: return((CHAR)(137 & 0xff));
- case 0x00ca: return((CHAR)(138 & 0xff));
- case 0x00cb: return((CHAR)(139 & 0xff));
- case 0x00cc: return((CHAR)(140 & 0xff));
- case 0x00cd: return((CHAR)(141 & 0xff));
- case 0x00ce: return((CHAR)(142 & 0xff));
- case 0x00cf: return((CHAR)(143 & 0xff));
- case 0x00d0: return((CHAR)(144 & 0xff));
- case 0x00d1: return((CHAR)(145 & 0xff));
- case 0x00d2: return((CHAR)(146 & 0xff));
- case 0x00d3: return((CHAR)(147 & 0xff));
- case 0x00d4: return((CHAR)(148 & 0xff));
- case 0x00d5: return((CHAR)(149 & 0xff));
- case 0x00d6: return((CHAR)(150 & 0xff));
- case 0x00d7: return((CHAR)(158 & 0xff));
- case 0x00d8: return((CHAR)(233 & 0xff));
- case 0x00d9: return((CHAR)(151 & 0xff));
- case 0x00da: return((CHAR)(152 & 0xff));
- case 0x00db: return((CHAR)(153 & 0xff));
- case 0x00dc: return((CHAR)(154 & 0xff));
- case 0x00dd: return((CHAR)(155 & 0xff));
- case 0x00de: return((CHAR)(156 & 0xff));
- case 0x00df: return((CHAR)(251 & 0xff));
- case 0x00e0: return((CHAR)(213 & 0xff));
- case 0x00e1: return((CHAR)(214 & 0xff));
- case 0x00e2: return((CHAR)(215 & 0xff));
- case 0x00e3: return((CHAR)(216 & 0xff));
- case 0x00e4: return((CHAR)(217 & 0xff));
- case 0x00e5: return((CHAR)(218 & 0xff));
- case 0x00e6: return((CHAR)(241 & 0xff));
- case 0x00e7: return((CHAR)(219 & 0xff));
- case 0x00e8: return((CHAR)(220 & 0xff));
- case 0x00e9: return((CHAR)(221 & 0xff));
- case 0x00ea: return((CHAR)(222 & 0xff));
- case 0x00eb: return((CHAR)(223 & 0xff));
- case 0x00ec: return((CHAR)(224 & 0xff));
- case 0x00ed: return((CHAR)(226 & 0xff));
- case 0x00ee: return((CHAR)(228 & 0xff));
- case 0x00ef: return((CHAR)(229 & 0xff));
- case 0x00f0: return((CHAR)(230 & 0xff));
- case 0x00f1: return((CHAR)(231 & 0xff));
- case 0x00f2: return((CHAR)(236 & 0xff));
- case 0x00f3: return((CHAR)(237 & 0xff));
- case 0x00f4: return((CHAR)(238 & 0xff));
- case 0x00f5: return((CHAR)(239 & 0xff));
- case 0x00f6: return((CHAR)(240 & 0xff));
- case 0x00f7: return((CHAR)(159 & 0xff));
- case 0x00f8: return((CHAR)(249 & 0xff));
- case 0x00f9: return((CHAR)(242 & 0xff));
- case 0x00fa: return((CHAR)(243 & 0xff));
- case 0x00fb: return((CHAR)(244 & 0xff));
- case 0x00fc: return((CHAR)(246 & 0xff));
- case 0x00fd: return((CHAR)(247 & 0xff));
- case 0x00fe: return((CHAR)(252 & 0xff));
- case 0x00ff: return((CHAR)(253 & 0xff));
- case 0x0131: return((CHAR)(245 & 0xff));
- case 0x0141: return((CHAR)(232 & 0xff));
- case 0x0142: return((CHAR)(248 & 0xff));
- case 0x0152: return((CHAR)(234 & 0xff));
- case 0x0153: return((CHAR)(250 & 0xff));
- case 0x0192: return((CHAR)(166 & 0xff));
- case 0x02c6: return((CHAR)(195 & 0xff));
- case 0x02c7: return((CHAR)(207 & 0xff));
- case 0x02cb: return((CHAR)(193 & 0xff));
- case 0x02d8: return((CHAR)(198 & 0xff));
- case 0x02d9: return((CHAR)(199 & 0xff));
- case 0x02da: return((CHAR)(202 & 0xff));
- case 0x02db: return((CHAR)(206 & 0xff));
- case 0x02dc: return((CHAR)(196 & 0xff));
- case 0x02dd: return((CHAR)(205 & 0xff));
- case 0x2013: return((CHAR)(177 & 0xff));
- case 0x2014: return((CHAR)(208 & 0xff));
- case 0x2019: return((CHAR)(169 & 0xff));
- case 0x201a: return((CHAR)(184 & 0xff));
- case 0x201c: return((CHAR)(170 & 0xff));
- case 0x201d: return((CHAR)(186 & 0xff));
- case 0x201e: return((CHAR)(185 & 0xff));
- case 0x2020: return((CHAR)(178 & 0xff));
- case 0x2021: return((CHAR)(179 & 0xff));
- case 0x2022: return((CHAR)(183 & 0xff));
- case 0x2026: return((CHAR)(188 & 0xff));
- case 0x2030: return((CHAR)(189 & 0xff));
- case 0x2039: return((CHAR)(172 & 0xff));
- case 0x203a: return((CHAR)(173 & 0xff));
- case 0x2044: return((CHAR)(164 & 0xff));
- case 0xfb01: return((CHAR)(174 & 0xff));
- case 0xfb02: return((CHAR)(175 & 0xff));
- default: return(tx_punc(c));
- }
-}
-
-int /* DG International */
-#ifdef CK_ANSIC
-tx_dgi(USHORT c)
-#else
-tx_dgi(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00a0: return((CHAR)(160 & 0xff));
- case 0x00a1: return((CHAR)(171 & 0xff));
- case 0x00a2: return((CHAR)(167 & 0xff));
- case 0x00a3: return((CHAR)(168 & 0xff));
- case 0x00a4: return((CHAR)(166 & 0xff));
- case 0x00a5: return((CHAR)(181 & 0xff));
- case 0x00a7: return((CHAR)(187 & 0xff));
- case 0x00a8: return((CHAR)(189 & 0xff));
- case 0x00a9: return((CHAR)(173 & 0xff));
- case 0x00aa: return((CHAR)(169 & 0xff));
- case 0x00ab: return((CHAR)(177 & 0xff));
- case 0x00ac: return((CHAR)(161 & 0xff));
- case 0x00ae: return((CHAR)(174 & 0xff));
- case 0x00b0: return((CHAR)(188 & 0xff));
- case 0x00b1: return((CHAR)(182 & 0xff));
- case 0x00b2: return((CHAR)(164 & 0xff));
- case 0x00b3: return((CHAR)(165 & 0xff));
- case 0x00b4: return((CHAR)(190 & 0xff));
- case 0x00b5: return((CHAR)(163 & 0xff));
- case 0x00b6: return((CHAR)(178 & 0xff));
- case 0x00b7: return((CHAR)(185 & 0xff));
- case 0x00b8: return((CHAR)(186 & 0xff));
- case 0x00ba: return((CHAR)(170 & 0xff));
- case 0x00bb: return((CHAR)(176 & 0xff));
- case 0x00bd: return((CHAR)(162 & 0xff));
- case 0x00bf: return((CHAR)(172 & 0xff));
- case 0x00c0: return((CHAR)(193 & 0xff));
- case 0x00c1: return((CHAR)(192 & 0xff));
- case 0x00c2: return((CHAR)(194 & 0xff));
- case 0x00c3: return((CHAR)(196 & 0xff));
- case 0x00c4: return((CHAR)(195 & 0xff));
- case 0x00c5: return((CHAR)(197 & 0xff));
- case 0x00c6: return((CHAR)(198 & 0xff));
- case 0x00c7: return((CHAR)(199 & 0xff));
- case 0x00c8: return((CHAR)(201 & 0xff));
- case 0x00c9: return((CHAR)(200 & 0xff));
- case 0x00ca: return((CHAR)(202 & 0xff));
- case 0x00cb: return((CHAR)(203 & 0xff));
- case 0x00cc: return((CHAR)(205 & 0xff));
- case 0x00cd: return((CHAR)(204 & 0xff));
- case 0x00ce: return((CHAR)(206 & 0xff));
- case 0x00cf: return((CHAR)(207 & 0xff));
- case 0x00d1: return((CHAR)(208 & 0xff));
- case 0x00d2: return((CHAR)(210 & 0xff));
- case 0x00d3: return((CHAR)(209 & 0xff));
- case 0x00d4: return((CHAR)(211 & 0xff));
- case 0x00d5: return((CHAR)(213 & 0xff));
- case 0x00d6: return((CHAR)(212 & 0xff));
- case 0x00d8: return((CHAR)(214 & 0xff));
- case 0x00d9: return((CHAR)(217 & 0xff));
- case 0x00da: return((CHAR)(216 & 0xff));
- case 0x00db: return((CHAR)(218 & 0xff));
- case 0x00dc: return((CHAR)(219 & 0xff));
- case 0x00df: return((CHAR)(252 & 0xff));
- case 0x00e0: return((CHAR)(225 & 0xff));
- case 0x00e1: return((CHAR)(224 & 0xff));
- case 0x00e2: return((CHAR)(226 & 0xff));
- case 0x00e3: return((CHAR)(228 & 0xff));
- case 0x00e4: return((CHAR)(227 & 0xff));
- case 0x00e5: return((CHAR)(229 & 0xff));
- case 0x00e6: return((CHAR)(230 & 0xff));
- case 0x00e7: return((CHAR)(231 & 0xff));
- case 0x00e8: return((CHAR)(233 & 0xff));
- case 0x00e9: return((CHAR)(232 & 0xff));
- case 0x00ea: return((CHAR)(234 & 0xff));
- case 0x00eb: return((CHAR)(235 & 0xff));
- case 0x00ec: return((CHAR)(237 & 0xff));
- case 0x00ed: return((CHAR)(236 & 0xff));
- case 0x00ee: return((CHAR)(238 & 0xff));
- case 0x00ef: return((CHAR)(239 & 0xff));
- case 0x00f1: return((CHAR)(240 & 0xff));
- case 0x00f2: return((CHAR)(242 & 0xff));
- case 0x00f3: return((CHAR)(241 & 0xff));
- case 0x00f4: return((CHAR)(243 & 0xff));
- case 0x00f5: return((CHAR)(245 & 0xff));
- case 0x00f6: return((CHAR)(244 & 0xff));
- case 0x00f8: return((CHAR)(246 & 0xff));
- case 0x00f9: return((CHAR)(249 & 0xff));
- case 0x00fa: return((CHAR)(248 & 0xff));
- case 0x00fb: return((CHAR)(250 & 0xff));
- case 0x00fc: return((CHAR)(251 & 0xff));
- case 0x00ff: return((CHAR)(253 & 0xff));
- case 0x0153: return((CHAR)(247 & 0xff));
- case 0x0178: return((CHAR)(221 & 0xff));
- case 0x0192: return((CHAR)(180 & 0xff));
- case 0x0276: return((CHAR)(215 & 0xff));
- case 0x2021: return((CHAR)(175 & 0xff));
- case 0x2122: return((CHAR)(179 & 0xff));
- case 0x2191: return((CHAR)(191 & 0xff));
- case 0x2264: return((CHAR)(183 & 0xff));
- case 0x2265: return((CHAR)(184 & 0xff));
- case 0x2588: return((CHAR)(255 & 0xff));
- default: return(tx_punc(c));
- }
-}
-
-int /* Macintosh Latin */
-#ifdef CK_ANSIC
-tx_maclatin(USHORT c)
-#else
-tx_maclatin(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a0: return((CHAR)(202 & 0xff));
- case 0x00a1: return((CHAR)(193 & 0xff));
- case 0x00a2: return((CHAR)(162 & 0xff));
- case 0x00a3: return((CHAR)(163 & 0xff));
- case 0x00a4: return((CHAR)(219 & 0xff));
- case 0x00a5: return((CHAR)(180 & 0xff));
- case 0x00a7: return((CHAR)(164 & 0xff));
- case 0x00a8: return((CHAR)(172 & 0xff));
- case 0x00a9: return((CHAR)(169 & 0xff));
- case 0x00aa: return((CHAR)(187 & 0xff));
- case 0x00ab: return((CHAR)(199 & 0xff));
- case 0x00ac: return((CHAR)(194 & 0xff));
- case 0x00ae: return((CHAR)(168 & 0xff));
- case 0x00af: return((CHAR)(248 & 0xff));
- case 0x00b0: return((CHAR)(161 & 0xff));
- case 0x00b1: return((CHAR)(177 & 0xff));
- case 0x00b4: return((CHAR)(171 & 0xff));
- case 0x00b5: return((CHAR)(181 & 0xff));
- case 0x00b6: return((CHAR)(166 & 0xff));
- case 0x00b7: return((CHAR)(225 & 0xff));
- case 0x00b8: return((CHAR)(252 & 0xff));
- case 0x00ba: return((CHAR)(188 & 0xff));
- case 0x00bb: return((CHAR)(200 & 0xff));
- case 0x00bf: return((CHAR)(192 & 0xff));
- case 0x00c0: return((CHAR)(203 & 0xff));
- case 0x00c1: return((CHAR)(231 & 0xff));
- case 0x00c2: return((CHAR)(229 & 0xff));
- case 0x00c3: return((CHAR)(204 & 0xff));
- case 0x00c4: return((CHAR)(128 & 0xff));
- case 0x00c5: return((CHAR)(129 & 0xff));
- case 0x00c6: return((CHAR)(174 & 0xff));
- case 0x00c7: return((CHAR)(130 & 0xff));
- case 0x00c8: return((CHAR)(233 & 0xff));
- case 0x00c9: return((CHAR)(131 & 0xff));
- case 0x00ca: return((CHAR)(230 & 0xff));
- case 0x00cb: return((CHAR)(232 & 0xff));
- case 0x00cc: return((CHAR)(237 & 0xff));
- case 0x00cd: return((CHAR)(234 & 0xff));
- case 0x00ce: return((CHAR)(235 & 0xff));
- case 0x00cf: return((CHAR)(236 & 0xff));
- case 0x00d0: return((CHAR)(220 & 0xff));
- case 0x00d1: return((CHAR)(132 & 0xff));
- case 0x00d2: return((CHAR)(241 & 0xff));
- case 0x00d3: return((CHAR)(238 & 0xff));
- case 0x00d4: return((CHAR)(239 & 0xff));
- case 0x00d5: return((CHAR)(205 & 0xff));
- case 0x00d6: return((CHAR)(133 & 0xff));
- case 0x00d8: return((CHAR)(175 & 0xff));
- case 0x00d9: return((CHAR)(244 & 0xff));
- case 0x00da: return((CHAR)(242 & 0xff));
- case 0x00db: return((CHAR)(243 & 0xff));
- case 0x00dc: return((CHAR)(134 & 0xff));
- case 0x00dd: return((CHAR)(160 & 0xff));
- case 0x00de: return((CHAR)(222 & 0xff));
- case 0x00df: return((CHAR)(167 & 0xff));
- case 0x00e0: return((CHAR)(136 & 0xff));
- case 0x00e1: return((CHAR)(135 & 0xff));
- case 0x00e2: return((CHAR)(137 & 0xff));
- case 0x00e3: return((CHAR)(139 & 0xff));
- case 0x00e4: return((CHAR)(138 & 0xff));
- case 0x00e5: return((CHAR)(140 & 0xff));
- case 0x00e6: return((CHAR)(190 & 0xff));
- case 0x00e7: return((CHAR)(141 & 0xff));
- case 0x00e8: return((CHAR)(143 & 0xff));
- case 0x00e9: return((CHAR)(142 & 0xff));
- case 0x00ea: return((CHAR)(144 & 0xff));
- case 0x00eb: return((CHAR)(145 & 0xff));
- case 0x00ec: return((CHAR)(147 & 0xff));
- case 0x00ed: return((CHAR)(146 & 0xff));
- case 0x00ee: return((CHAR)(148 & 0xff));
- case 0x00ef: return((CHAR)(149 & 0xff));
- case 0x00f0: return((CHAR)(221 & 0xff));
- case 0x00f1: return((CHAR)(150 & 0xff));
- case 0x00f2: return((CHAR)(152 & 0xff));
- case 0x00f3: return((CHAR)(151 & 0xff));
- case 0x00f4: return((CHAR)(153 & 0xff));
- case 0x00f5: return((CHAR)(155 & 0xff));
- case 0x00f6: return((CHAR)(154 & 0xff));
- case 0x00f7: return((CHAR)(214 & 0xff));
- case 0x00f8: return((CHAR)(191 & 0xff));
- case 0x00f9: return((CHAR)(157 & 0xff));
- case 0x00fa: return((CHAR)(156 & 0xff));
- case 0x00fb: return((CHAR)(158 & 0xff));
- case 0x00fc: return((CHAR)(159 & 0xff));
- case 0x00fd: return((CHAR)(224 & 0xff));
- case 0x00fe: return((CHAR)(223 & 0xff));
- case 0x00ff: return((CHAR)(216 & 0xff));
- case 0x0131: return((CHAR)(245 & 0xff));
- case 0x0152: return((CHAR)(206 & 0xff));
- case 0x0153: return((CHAR)(207 & 0xff));
- case 0x0178: return((CHAR)(217 & 0xff));
- case 0x0192: return((CHAR)(196 & 0xff));
- case 0x02c6: return((CHAR)(246 & 0xff));
- case 0x02c7: return((CHAR)(255 & 0xff));
- case 0x02d8: return((CHAR)(249 & 0xff));
- case 0x02d9: return((CHAR)(250 & 0xff));
- case 0x02da: return((CHAR)(251 & 0xff));
- case 0x02db: return((CHAR)(254 & 0xff));
- case 0x02dc: return((CHAR)(247 & 0xff));
- case 0x02dd: return((CHAR)(253 & 0xff));
- case 0x03c0: return((CHAR)(185 & 0xff));
- case 0x2013: return((CHAR)(208 & 0xff));
- case 0x2014: return((CHAR)(209 & 0xff));
- case 0x2018: return((CHAR)(212 & 0xff));
- case 0x2019: return((CHAR)(213 & 0xff));
- case 0x201a: return((CHAR)(226 & 0xff));
- case 0x201c: return((CHAR)(210 & 0xff));
- case 0x201d: return((CHAR)(211 & 0xff));
- case 0x201e: return((CHAR)(227 & 0xff));
- case 0x2022: return((CHAR)(165 & 0xff));
- case 0x2026: return((CHAR)(201 & 0xff));
- case 0x2030: return((CHAR)(228 & 0xff));
- case 0x2044: return((CHAR)(218 & 0xff));
- case 0x2122: return((CHAR)(170 & 0xff));
- case 0x2126: return((CHAR)(189 & 0xff));
- case 0x2202: return((CHAR)(182 & 0xff));
- case 0x2206: return((CHAR)(198 & 0xff));
- case 0x220f: return((CHAR)(184 & 0xff));
- case 0x2211: return((CHAR)(183 & 0xff));
- case 0x221a: return((CHAR)(195 & 0xff));
- case 0x221e: return((CHAR)(176 & 0xff));
- case 0x222b: return((CHAR)(186 & 0xff));
- case 0x2248: return((CHAR)(197 & 0xff));
- case 0x2260: return((CHAR)(173 & 0xff));
- case 0x2264: return((CHAR)(178 & 0xff));
- case 0x2265: return((CHAR)(179 & 0xff));
- case 0x25ca: return((CHAR)(215 & 0xff));
- case 0xf8ff: return((CHAR)(240 & 0xff));
- default: return(tx_punc(c));
- }
-}
-
-int /* Apple QuickDraw / CP10000 */
-#ifdef CK_ANSIC
-tx_quickdraw(USHORT c)
-#else
-tx_quickdraw(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a0: return((CHAR)(202 & 0xff));
- case 0x00a1: return((CHAR)(193 & 0xff));
- case 0x00a2: return((CHAR)(162 & 0xff));
- case 0x00a3: return((CHAR)(163 & 0xff));
- case 0x00a4: return((CHAR)(219 & 0xff));
- case 0x00a5: return((CHAR)(180 & 0xff));
- case 0x00a7: return((CHAR)(164 & 0xff));
- case 0x00a8: return((CHAR)(172 & 0xff));
- case 0x00a9: return((CHAR)(169 & 0xff));
- case 0x00aa: return((CHAR)(187 & 0xff));
- case 0x00ab: return((CHAR)(199 & 0xff));
- case 0x00ac: return((CHAR)(194 & 0xff));
- case 0x00ae: return((CHAR)(168 & 0xff));
- case 0x00af: return((CHAR)(248 & 0xff));
- case 0x00b0: return((CHAR)(161 & 0xff));
- case 0x00b1: return((CHAR)(177 & 0xff));
- case 0x00b4: return((CHAR)(171 & 0xff));
- case 0x00b5: return((CHAR)(181 & 0xff));
- case 0x00b6: return((CHAR)(166 & 0xff));
- case 0x00b7: return((CHAR)(225 & 0xff));
- case 0x00b8: return((CHAR)(252 & 0xff));
- case 0x00ba: return((CHAR)(188 & 0xff));
- case 0x00bb: return((CHAR)(200 & 0xff));
- case 0x00bf: return((CHAR)(192 & 0xff));
- case 0x00c0: return((CHAR)(203 & 0xff));
- case 0x00c1: return((CHAR)(231 & 0xff));
- case 0x00c2: return((CHAR)(229 & 0xff));
- case 0x00c3: return((CHAR)(204 & 0xff));
- case 0x00c4: return((CHAR)(128 & 0xff));
- case 0x00c5: return((CHAR)(129 & 0xff));
- case 0x00c6: return((CHAR)(174 & 0xff));
- case 0x00c7: return((CHAR)(130 & 0xff));
- case 0x00c8: return((CHAR)(233 & 0xff));
- case 0x00c9: return((CHAR)(131 & 0xff));
- case 0x00ca: return((CHAR)(230 & 0xff));
- case 0x00cb: return((CHAR)(232 & 0xff));
- case 0x00cc: return((CHAR)(237 & 0xff));
- case 0x00cd: return((CHAR)(234 & 0xff));
- case 0x00ce: return((CHAR)(235 & 0xff));
- case 0x00cf: return((CHAR)(236 & 0xff));
- case 0x2039: return((CHAR)(220 & 0xff));
- case 0x00d1: return((CHAR)(132 & 0xff));
- case 0x00d2: return((CHAR)(241 & 0xff));
- case 0x00d3: return((CHAR)(238 & 0xff));
- case 0x00d4: return((CHAR)(239 & 0xff));
- case 0x00d5: return((CHAR)(205 & 0xff));
- case 0x00d6: return((CHAR)(133 & 0xff));
- case 0x00d8: return((CHAR)(175 & 0xff));
- case 0x00d9: return((CHAR)(244 & 0xff));
- case 0x00da: return((CHAR)(242 & 0xff));
- case 0x00db: return((CHAR)(243 & 0xff));
- case 0x00dc: return((CHAR)(134 & 0xff));
- case 0x2020: return((CHAR)(160 & 0xff));
- case 0xfb01: return((CHAR)(222 & 0xff));
- case 0x00df: return((CHAR)(167 & 0xff));
- case 0x00e0: return((CHAR)(136 & 0xff));
- case 0x00e1: return((CHAR)(135 & 0xff));
- case 0x00e2: return((CHAR)(137 & 0xff));
- case 0x00e3: return((CHAR)(139 & 0xff));
- case 0x00e4: return((CHAR)(138 & 0xff));
- case 0x00e5: return((CHAR)(140 & 0xff));
- case 0x00e6: return((CHAR)(190 & 0xff));
- case 0x00e7: return((CHAR)(141 & 0xff));
- case 0x00e8: return((CHAR)(143 & 0xff));
- case 0x00e9: return((CHAR)(142 & 0xff));
- case 0x00ea: return((CHAR)(144 & 0xff));
- case 0x00eb: return((CHAR)(145 & 0xff));
- case 0x00ec: return((CHAR)(147 & 0xff));
- case 0x00ed: return((CHAR)(146 & 0xff));
- case 0x00ee: return((CHAR)(148 & 0xff));
- case 0x00ef: return((CHAR)(149 & 0xff));
- case 0x203a: return((CHAR)(221 & 0xff));
- case 0x00f1: return((CHAR)(150 & 0xff));
- case 0x00f2: return((CHAR)(152 & 0xff));
- case 0x00f3: return((CHAR)(151 & 0xff));
- case 0x00f4: return((CHAR)(153 & 0xff));
- case 0x00f5: return((CHAR)(155 & 0xff));
- case 0x00f6: return((CHAR)(154 & 0xff));
- case 0x00f7: return((CHAR)(214 & 0xff));
- case 0x00f8: return((CHAR)(191 & 0xff));
- case 0x00f9: return((CHAR)(157 & 0xff));
- case 0x00fa: return((CHAR)(156 & 0xff));
- case 0x00fb: return((CHAR)(158 & 0xff));
- case 0x00fc: return((CHAR)(159 & 0xff));
- case 0x2021: return((CHAR)(224 & 0xff));
- case 0xfb02: return((CHAR)(223 & 0xff));
- case 0x00ff: return((CHAR)(216 & 0xff));
- case 0x0131: return((CHAR)(245 & 0xff));
- case 0x0152: return((CHAR)(206 & 0xff));
- case 0x0153: return((CHAR)(207 & 0xff));
- case 0x0178: return((CHAR)(217 & 0xff));
- case 0x0192: return((CHAR)(196 & 0xff));
- case 0x02c6: return((CHAR)(246 & 0xff));
- case 0x02c7: return((CHAR)(255 & 0xff));
- case 0x02d8: return((CHAR)(249 & 0xff));
- case 0x02d9: return((CHAR)(250 & 0xff));
- case 0x02da: return((CHAR)(251 & 0xff));
- case 0x02db: return((CHAR)(254 & 0xff));
- case 0x02dc: return((CHAR)(247 & 0xff));
- case 0x02dd: return((CHAR)(253 & 0xff));
- case 0x03c0: return((CHAR)(185 & 0xff));
- case 0x2013: return((CHAR)(208 & 0xff));
- case 0x2014: return((CHAR)(209 & 0xff));
- case 0x2018: return((CHAR)(212 & 0xff));
- case 0x2019: return((CHAR)(213 & 0xff));
- case 0x201a: return((CHAR)(226 & 0xff));
- case 0x201c: return((CHAR)(210 & 0xff));
- case 0x201d: return((CHAR)(211 & 0xff));
- case 0x201e: return((CHAR)(227 & 0xff));
- case 0x2022: return((CHAR)(165 & 0xff));
- case 0x2026: return((CHAR)(201 & 0xff));
- case 0x2030: return((CHAR)(228 & 0xff));
- case 0x2044: return((CHAR)(218 & 0xff));
- case 0x2122: return((CHAR)(170 & 0xff));
- case 0x03a9: return((CHAR)(189 & 0xff));
- case 0x2202: return((CHAR)(182 & 0xff));
- case 0x2206: return((CHAR)(198 & 0xff));
- case 0x220f: return((CHAR)(184 & 0xff));
- case 0x2211: return((CHAR)(183 & 0xff));
- case 0x221a: return((CHAR)(195 & 0xff));
- case 0x221e: return((CHAR)(176 & 0xff));
- case 0x222b: return((CHAR)(186 & 0xff));
- case 0x2248: return((CHAR)(197 & 0xff));
- case 0x2260: return((CHAR)(173 & 0xff));
- case 0x2264: return((CHAR)(178 & 0xff));
- case 0x2265: return((CHAR)(179 & 0xff));
- case 0x25ca: return((CHAR)(215 & 0xff));
- case 0xf8ff: return((CHAR)(240 & 0xff));
- default: return(tx_punc(c));
- }
-}
-
-int /* HP Roman-8 */
-#ifdef CK_ANSIC
-tx_hproman8(USHORT c)
-#else
-tx_hproman8(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xa0)
- return((CHAR)(c & 0xff));
- switch(c) {
- case 0x00a0: return((CHAR)(160 & 0xff));
- case 0x00a1: return((CHAR)(171 & 0xff));
- case 0x00a2: return((CHAR)(167 & 0xff));
- case 0x00a3: return((CHAR)(168 & 0xff));
- case 0x00a4: return((CHAR)(166 & 0xff));
- case 0x00a5: return((CHAR)(181 & 0xff));
- case 0x00a7: return((CHAR)(187 & 0xff));
- case 0x00a8: return((CHAR)(189 & 0xff));
- case 0x00a9: return((CHAR)(173 & 0xff));
- case 0x00aa: return((CHAR)(169 & 0xff));
- case 0x00ab: return((CHAR)(177 & 0xff));
- case 0x00ac: return((CHAR)(161 & 0xff));
- case 0x00ae: return((CHAR)(174 & 0xff));
- case 0x00b0: return((CHAR)(188 & 0xff));
- case 0x00b1: return((CHAR)(182 & 0xff));
- case 0x00b2: return((CHAR)(164 & 0xff));
- case 0x00b3: return((CHAR)(165 & 0xff));
- case 0x00b4: return((CHAR)(190 & 0xff));
- case 0x00b5: return((CHAR)(163 & 0xff));
- case 0x00b6: return((CHAR)(178 & 0xff));
- case 0x00b7: return((CHAR)(185 & 0xff));
- case 0x00b8: return((CHAR)(186 & 0xff));
- case 0x00ba: return((CHAR)(170 & 0xff));
- case 0x00bb: return((CHAR)(176 & 0xff));
- case 0x00bd: return((CHAR)(162 & 0xff));
- case 0x00bf: return((CHAR)(172 & 0xff));
- case 0x00c0: return((CHAR)(193 & 0xff));
- case 0x00c1: return((CHAR)(192 & 0xff));
- case 0x00c2: return((CHAR)(194 & 0xff));
- case 0x00c3: return((CHAR)(196 & 0xff));
- case 0x00c4: return((CHAR)(195 & 0xff));
- case 0x00c5: return((CHAR)(197 & 0xff));
- case 0x00c6: return((CHAR)(198 & 0xff));
- case 0x00c7: return((CHAR)(199 & 0xff));
- case 0x00c8: return((CHAR)(201 & 0xff));
- case 0x00c9: return((CHAR)(200 & 0xff));
- case 0x00ca: return((CHAR)(202 & 0xff));
- case 0x00cb: return((CHAR)(203 & 0xff));
- case 0x00cc: return((CHAR)(205 & 0xff));
- case 0x00cd: return((CHAR)(204 & 0xff));
- case 0x00ce: return((CHAR)(206 & 0xff));
- case 0x00cf: return((CHAR)(207 & 0xff));
- case 0x00d1: return((CHAR)(208 & 0xff));
- case 0x00d2: return((CHAR)(210 & 0xff));
- case 0x00d3: return((CHAR)(209 & 0xff));
- case 0x00d4: return((CHAR)(211 & 0xff));
- case 0x00d5: return((CHAR)(213 & 0xff));
- case 0x00d6: return((CHAR)(212 & 0xff));
- case 0x00d8: return((CHAR)(214 & 0xff));
- case 0x00d9: return((CHAR)(217 & 0xff));
- case 0x00da: return((CHAR)(216 & 0xff));
- case 0x00db: return((CHAR)(218 & 0xff));
- case 0x00dc: return((CHAR)(219 & 0xff));
- case 0x00df: return((CHAR)(252 & 0xff));
- case 0x00e0: return((CHAR)(225 & 0xff));
- case 0x00e1: return((CHAR)(224 & 0xff));
- case 0x00e2: return((CHAR)(226 & 0xff));
- case 0x00e3: return((CHAR)(228 & 0xff));
- case 0x00e4: return((CHAR)(227 & 0xff));
- case 0x00e5: return((CHAR)(229 & 0xff));
- case 0x00e6: return((CHAR)(230 & 0xff));
- case 0x00e7: return((CHAR)(231 & 0xff));
- case 0x00e8: return((CHAR)(233 & 0xff));
- case 0x00e9: return((CHAR)(232 & 0xff));
- case 0x00ea: return((CHAR)(234 & 0xff));
- case 0x00eb: return((CHAR)(235 & 0xff));
- case 0x00ec: return((CHAR)(237 & 0xff));
- case 0x00ed: return((CHAR)(236 & 0xff));
- case 0x00ee: return((CHAR)(238 & 0xff));
- case 0x00ef: return((CHAR)(239 & 0xff));
- case 0x00f1: return((CHAR)(240 & 0xff));
- case 0x00f2: return((CHAR)(242 & 0xff));
- case 0x00f3: return((CHAR)(241 & 0xff));
- case 0x00f4: return((CHAR)(243 & 0xff));
- case 0x00f5: return((CHAR)(245 & 0xff));
- case 0x00f6: return((CHAR)(244 & 0xff));
- case 0x00f8: return((CHAR)(246 & 0xff));
- case 0x00f9: return((CHAR)(249 & 0xff));
- case 0x00fa: return((CHAR)(248 & 0xff));
- case 0x00fb: return((CHAR)(250 & 0xff));
- case 0x00fc: return((CHAR)(251 & 0xff));
- case 0x00ff: return((CHAR)(253 & 0xff));
- case 0x0153: return((CHAR)(247 & 0xff));
- case 0x0178: return((CHAR)(221 & 0xff));
- case 0x0192: return((CHAR)(180 & 0xff));
- case 0x0276: return((CHAR)(215 & 0xff));
- case 0x2021: return((CHAR)(175 & 0xff));
- case 0x2122: return((CHAR)(179 & 0xff));
- case 0x2191: return((CHAR)(191 & 0xff));
- case 0x2264: return((CHAR)(183 & 0xff));
- case 0x2265: return((CHAR)(184 & 0xff));
- case 0x2588: return((CHAR)(255 & 0xff));
- default: return(tx_punc(c));
- }
-}
-
-int /* PC Code Page 437 */
-#ifdef CK_ANSIC
-tx_cp437(USHORT c)
-#else
-tx_cp437(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a0: return((CHAR)(255 & 0xff));
- case 0x00a1: return((CHAR)(173 & 0xff));
- case 0x00a2: return((CHAR)(155 & 0xff));
- case 0x00a3: return((CHAR)(156 & 0xff));
- case 0x00a4: return((CHAR)(15 & 0xff));
- case 0x00a5: return((CHAR)(157 & 0xff));
- case 0x00a6: return((CHAR)(124 & 0xff));
- case 0x00a7: return((CHAR)(21 & 0xff));
- case 0x00a8: return((CHAR)(34 & 0xff));
- case 0x00a9: return((CHAR)(67 & 0xff));
- case 0x00aa: return((CHAR)(166 & 0xff));
- case 0x00ab: return((CHAR)(174 & 0xff));
- case 0x00ac: return((CHAR)(170 & 0xff));
- case 0x00ad: return((CHAR)(45 & 0xff));
- case 0x00ae: return((CHAR)(84 & 0xff));
- case 0x00af: return((CHAR)(22 & 0xff));
- case 0x00b0: return((CHAR)(248 & 0xff));
- case 0x00b1: return((CHAR)(241 & 0xff));
- case 0x00b2: return((CHAR)(253 & 0xff));
- case 0x00b3: return((CHAR)(51 & 0xff));
- case 0x00b4: return((CHAR)(39 & 0xff));
- case 0x00b5: return((CHAR)(230 & 0xff));
- case 0x00b6: return((CHAR)(20 & 0xff));
- case 0x00b7: return((CHAR)(250 & 0xff));
- case 0x00b8: return((CHAR)(44 & 0xff));
- case 0x00b9: return((CHAR)(49 & 0xff));
- case 0x00ba: return((CHAR)(167 & 0xff));
- case 0x00bb: return((CHAR)(175 & 0xff));
- case 0x00bc: return((CHAR)(172 & 0xff));
- case 0x00bd: return((CHAR)(171 & 0xff));
- case 0x00be: return((CHAR)(19 & 0xff));
- case 0x00bf: return((CHAR)(168 & 0xff));
- case 0x00c0: return((CHAR)(65 & 0xff));
- case 0x00c1: return((CHAR)(65 & 0xff));
- case 0x00c2: return((CHAR)(65 & 0xff));
- case 0x00c3: return((CHAR)(65 & 0xff));
- case 0x00c4: return((CHAR)(142 & 0xff));
- case 0x00c5: return((CHAR)(143 & 0xff));
- case 0x00c6: return((CHAR)(146 & 0xff));
- case 0x00c7: return((CHAR)(128 & 0xff));
- case 0x00c8: return((CHAR)(69 & 0xff));
- case 0x00c9: return((CHAR)(144 & 0xff));
- case 0x00ca: return((CHAR)(69 & 0xff));
- case 0x00cb: return((CHAR)(69 & 0xff));
- case 0x00cc: return((CHAR)(73 & 0xff));
- case 0x00cd: return((CHAR)(73 & 0xff));
- case 0x00ce: return((CHAR)(73 & 0xff));
- case 0x00cf: return((CHAR)(73 & 0xff));
- case 0x00d0: return((CHAR)(19 & 0xff));
- case 0x00d1: return((CHAR)(165 & 0xff));
- case 0x00d2: return((CHAR)(79 & 0xff));
- case 0x00d3: return((CHAR)(79 & 0xff));
- case 0x00d4: return((CHAR)(79 & 0xff));
- case 0x00d5: return((CHAR)(79 & 0xff));
- case 0x00d6: return((CHAR)(153 & 0xff));
- case 0x00d7: return((CHAR)(120 & 0xff));
- case 0x00d8: return((CHAR)(79 & 0xff));
- case 0x00d9: return((CHAR)(85 & 0xff));
- case 0x00da: return((CHAR)(85 & 0xff));
- case 0x00db: return((CHAR)(85 & 0xff));
- case 0x00dc: return((CHAR)(154 & 0xff));
- case 0x00dd: return((CHAR)(89 & 0xff));
- case 0x00de: return((CHAR)(19 & 0xff));
- case 0x00df: return((CHAR)(225 & 0xff));
- case 0x00e0: return((CHAR)(133 & 0xff));
- case 0x00e1: return((CHAR)(160 & 0xff));
- case 0x00e2: return((CHAR)(131 & 0xff));
- case 0x00e3: return((CHAR)(97 & 0xff)); /* a-tilde -> a (not 101 = e) */
- case 0x00e4: return((CHAR)(132 & 0xff));
- case 0x00e5: return((CHAR)(134 & 0xff));
- case 0x00e6: return((CHAR)(145 & 0xff));
- case 0x00e7: return((CHAR)(135 & 0xff));
- case 0x00e8: return((CHAR)(138 & 0xff));
- case 0x00e9: return((CHAR)(130 & 0xff));
- case 0x00ea: return((CHAR)(136 & 0xff));
- case 0x00eb: return((CHAR)(137 & 0xff));
- case 0x00ec: return((CHAR)(141 & 0xff));
- case 0x00ed: return((CHAR)(161 & 0xff));
- case 0x00ee: return((CHAR)(140 & 0xff));
- case 0x00ef: return((CHAR)(139 & 0xff));
- case 0x00f0: return((CHAR)(19 & 0xff));
- case 0x00f1: return((CHAR)(164 & 0xff));
- case 0x00f2: return((CHAR)(149 & 0xff));
- case 0x00f3: return((CHAR)(162 & 0xff));
- case 0x00f4: return((CHAR)(147 & 0xff));
- case 0x00f5: return((CHAR)(111 & 0xff));
- case 0x00f6: return((CHAR)(148 & 0xff));
- case 0x00f7: return((CHAR)(246 & 0xff));
- case 0x00f8: return((CHAR)(111 & 0xff));
- case 0x00f9: return((CHAR)(151 & 0xff));
- case 0x00fa: return((CHAR)(163 & 0xff));
- case 0x00fb: return((CHAR)(150 & 0xff));
- case 0x00fc: return((CHAR)(129 & 0xff));
- case 0x00fd: return((CHAR)(121 & 0xff));
- case 0x00fe: return((CHAR)(19 & 0xff));
- case 0x00ff: return((CHAR)(152 & 0xff));
- case 0x0192: return((CHAR)(159 & 0xff));
- case 0x0393: return((CHAR)(226 & 0xff));
- case 0x0398: return((CHAR)(233 & 0xff));
- case 0x03a3: return((CHAR)(228 & 0xff));
- case 0x03a6: return((CHAR)(232 & 0xff));
- case 0x03a9: return((CHAR)(234 & 0xff));
- case 0x03b1: return((CHAR)(224 & 0xff));
- case 0x03b4: return((CHAR)(235 & 0xff));
- case 0x03b5: return((CHAR)(238 & 0xff));
- case 0x03c0: return((CHAR)(227 & 0xff));
- case 0x03c3: return((CHAR)(229 & 0xff));
- case 0x03c4: return((CHAR)(231 & 0xff));
- case 0x03c6: return((CHAR)(237 & 0xff));
- case 0x207f: return((CHAR)(252 & 0xff));
- case 0x20a7: return((CHAR)(158 & 0xff));
- case 0x2219: return((CHAR)(249 & 0xff));
- case 0x221a: return((CHAR)(251 & 0xff));
- case 0x221e: return((CHAR)(236 & 0xff));
- case 0x2229: return((CHAR)(239 & 0xff));
- case 0x2248: return((CHAR)(247 & 0xff));
- case 0x2261: return((CHAR)(240 & 0xff));
- case 0x2264: return((CHAR)(243 & 0xff));
- case 0x2265: return((CHAR)(242 & 0xff));
- case 0x2310: return((CHAR)(169 & 0xff));
- case 0x2320: return((CHAR)(244 & 0xff));
- case 0x2321: return((CHAR)(245 & 0xff));
- case 0x2500: return((CHAR)(196 & 0xff));
- case 0x2502: return((CHAR)(179 & 0xff));
- case 0x250c: return((CHAR)(218 & 0xff));
- case 0x2510: return((CHAR)(191 & 0xff));
- case 0x2514: return((CHAR)(192 & 0xff));
- case 0x2518: return((CHAR)(217 & 0xff));
- case 0x251c: return((CHAR)(195 & 0xff));
- case 0x2524: return((CHAR)(180 & 0xff));
- case 0x252c: return((CHAR)(194 & 0xff));
- case 0x2534: return((CHAR)(193 & 0xff));
- case 0x253c: return((CHAR)(197 & 0xff));
- case 0x2550: return((CHAR)(205 & 0xff));
- case 0x2551: return((CHAR)(186 & 0xff));
- case 0x2552: return((CHAR)(213 & 0xff));
- case 0x2553: return((CHAR)(214 & 0xff));
- case 0x2554: return((CHAR)(201 & 0xff));
- case 0x2555: return((CHAR)(184 & 0xff));
- case 0x2556: return((CHAR)(183 & 0xff));
- case 0x2557: return((CHAR)(187 & 0xff));
- case 0x2558: return((CHAR)(212 & 0xff));
- case 0x2559: return((CHAR)(211 & 0xff));
- case 0x255a: return((CHAR)(200 & 0xff));
- case 0x255b: return((CHAR)(190 & 0xff));
- case 0x255c: return((CHAR)(189 & 0xff));
- case 0x255d: return((CHAR)(188 & 0xff));
- case 0x255e: return((CHAR)(198 & 0xff));
- case 0x255f: return((CHAR)(199 & 0xff));
- case 0x2560: return((CHAR)(204 & 0xff));
- case 0x2561: return((CHAR)(181 & 0xff));
- case 0x2562: return((CHAR)(182 & 0xff));
- case 0x2563: return((CHAR)(185 & 0xff));
- case 0x2564: return((CHAR)(209 & 0xff));
- case 0x2565: return((CHAR)(210 & 0xff));
- case 0x2566: return((CHAR)(203 & 0xff));
- case 0x2567: return((CHAR)(207 & 0xff));
- case 0x2568: return((CHAR)(208 & 0xff));
- case 0x2569: return((CHAR)(202 & 0xff));
- case 0x256a: return((CHAR)(216 & 0xff));
- case 0x256b: return((CHAR)(215 & 0xff));
- case 0x256c: return((CHAR)(206 & 0xff));
- case 0x2580: return((CHAR)(223 & 0xff));
- case 0x2584: return((CHAR)(220 & 0xff));
- case 0x2588: return((CHAR)(219 & 0xff));
- case 0x258c: return((CHAR)(221 & 0xff));
- case 0x2590: return((CHAR)(222 & 0xff));
- case 0x2591: return((CHAR)(176 & 0xff));
- case 0x2592: return((CHAR)(177 & 0xff));
- case 0x2593: return((CHAR)(178 & 0xff));
- case 0x25a0: return((CHAR)(254 & 0xff)); /* Black square */
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* Mazovia */
-#ifdef CK_ANSIC
-tx_mazovia(USHORT c)
-#else
-tx_mazovia(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00d3: return((CHAR)0xa3 & 0xff); /* O acute */
- case 0x00f3: return((CHAR)0xa2 & 0xff); /* O acute */
- case 0x0104: return((CHAR)0x8f & 0xff); /* A Ogonek */
- case 0x0105: return((CHAR)0x86 & 0xff); /* a Ogonek */
- case 0x0106: return((CHAR)0x95 & 0xff); /* C acute */
- case 0x0107: return((CHAR)0x8d & 0xff); /* c acute */
- case 0x0118: return((CHAR)0x90 & 0xff); /* E Ogonek */
- case 0x0119: return((CHAR)0x91 & 0xff); /* E Ogonek */
- case 0x0141: return((CHAR)0x9c & 0xff); /* L stroke */
- case 0x0142: return((CHAR)0x92 & 0xff); /* L stroke */
- case 0x0143: return((CHAR)0xa5 & 0xff); /* N acute */
- case 0x0144: return((CHAR)0xa4 & 0xff); /* N acute */
- case 0x015a: return((CHAR)0x98 & 0xff); /* S acute */
- case 0x015b: return((CHAR)0x9e & 0xff); /* S acute */
- case 0x0179: return((CHAR)0xa0 & 0xff); /* Z acute */
- case 0x017a: return((CHAR)0xa6 & 0xff); /* Z acute */
- case 0x017b: return((CHAR)0xa1 & 0xff); /* Z dot above */
- case 0x017c: return((CHAR)0xa7 & 0xff); /* Z dot above */
- default: return(tx_cp437(c));
- }
-}
-
-int /* PC Code Page 850 */
-#ifdef CK_ANSIC
-tx_cp850(USHORT c)
-#else
-tx_cp850(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a0: return((CHAR)(255 & 0xff));
- case 0x00a1: return((CHAR)(173 & 0xff));
- case 0x00a2: return((CHAR)(189 & 0xff));
- case 0x00a3: return((CHAR)(156 & 0xff));
- case 0x00a4: return((CHAR)(207 & 0xff));
- case 0x00a5: return((CHAR)(190 & 0xff));
- case 0x00a6: return((CHAR)(221 & 0xff));
- case 0x00a7: return((CHAR)(245 & 0xff));
- case 0x00a8: return((CHAR)(249 & 0xff));
- case 0x00a9: return((CHAR)(184 & 0xff));
- case 0x00aa: return((CHAR)(166 & 0xff));
- case 0x00ab: return((CHAR)(174 & 0xff));
- case 0x00ac: return((CHAR)(170 & 0xff));
- case 0x00ad: return((CHAR)(240 & 0xff));
- case 0x00ae: return((CHAR)(169 & 0xff));
- case 0x00af: return((CHAR)(238 & 0xff));
- case 0x00b0: return((CHAR)(248 & 0xff));
- case 0x00b1: return((CHAR)(241 & 0xff));
- case 0x00b2: return((CHAR)(253 & 0xff));
- case 0x00b3: return((CHAR)(252 & 0xff));
- case 0x00b4: return((CHAR)(239 & 0xff));
- case 0x00b5: return((CHAR)(230 & 0xff));
- case 0x00b6: return((CHAR)(244 & 0xff));
- case 0x00b7: return((CHAR)(250 & 0xff));
- case 0x00b8: return((CHAR)(247 & 0xff));
- case 0x00b9: return((CHAR)(251 & 0xff));
- case 0x00ba: return((CHAR)(167 & 0xff));
- case 0x00bb: return((CHAR)(175 & 0xff));
- case 0x00bc: return((CHAR)(172 & 0xff));
- case 0x00bd: return((CHAR)(171 & 0xff));
- case 0x00be: return((CHAR)(243 & 0xff));
- case 0x00bf: return((CHAR)(168 & 0xff));
- case 0x00c0: return((CHAR)(183 & 0xff));
- case 0x00c1: return((CHAR)(181 & 0xff));
- case 0x00c2: return((CHAR)(182 & 0xff));
- case 0x00c3: return((CHAR)(199 & 0xff));
- case 0x00c4: return((CHAR)(142 & 0xff));
- case 0x00c5: return((CHAR)(143 & 0xff));
- case 0x00c6: return((CHAR)(146 & 0xff));
- case 0x00c7: return((CHAR)(128 & 0xff));
- case 0x00c8: return((CHAR)(212 & 0xff));
- case 0x00c9: return((CHAR)(144 & 0xff));
- case 0x00ca: return((CHAR)(210 & 0xff));
- case 0x00cb: return((CHAR)(211 & 0xff));
- case 0x00cc: return((CHAR)(222 & 0xff));
- case 0x00cd: return((CHAR)(214 & 0xff));
- case 0x00ce: return((CHAR)(215 & 0xff));
- case 0x00cf: return((CHAR)(216 & 0xff));
- case 0x00d0: return((CHAR)(209 & 0xff));
- case 0x00d1: return((CHAR)(165 & 0xff));
- case 0x00d2: return((CHAR)(227 & 0xff));
- case 0x00d3: return((CHAR)(224 & 0xff));
- case 0x00d4: return((CHAR)(226 & 0xff));
- case 0x00d5: return((CHAR)(229 & 0xff));
- case 0x00d6: return((CHAR)(153 & 0xff));
- case 0x00d7: return((CHAR)(158 & 0xff));
- case 0x00d8: return((CHAR)(157 & 0xff));
- case 0x00d9: return((CHAR)(235 & 0xff));
- case 0x00da: return((CHAR)(233 & 0xff));
- case 0x00db: return((CHAR)(234 & 0xff));
- case 0x00dc: return((CHAR)(154 & 0xff));
- case 0x00dd: return((CHAR)(237 & 0xff));
- case 0x00de: return((CHAR)(232 & 0xff));
- case 0x00df: return((CHAR)(225 & 0xff));
- case 0x00e0: return((CHAR)(133 & 0xff));
- case 0x00e1: return((CHAR)(160 & 0xff));
- case 0x00e2: return((CHAR)(131 & 0xff));
- case 0x00e3: return((CHAR)(198 & 0xff));
- case 0x00e4: return((CHAR)(132 & 0xff));
- case 0x00e5: return((CHAR)(134 & 0xff));
- case 0x00e6: return((CHAR)(145 & 0xff));
- case 0x00e7: return((CHAR)(135 & 0xff));
- case 0x00e8: return((CHAR)(138 & 0xff));
- case 0x00e9: return((CHAR)(130 & 0xff));
- case 0x00ea: return((CHAR)(136 & 0xff));
- case 0x00eb: return((CHAR)(137 & 0xff));
- case 0x00ec: return((CHAR)(141 & 0xff));
- case 0x00ed: return((CHAR)(161 & 0xff));
- case 0x00ee: return((CHAR)(140 & 0xff));
- case 0x00ef: return((CHAR)(139 & 0xff));
- case 0x00f0: return((CHAR)(208 & 0xff));
- case 0x00f1: return((CHAR)(164 & 0xff));
- case 0x00f2: return((CHAR)(149 & 0xff));
- case 0x00f3: return((CHAR)(162 & 0xff));
- case 0x00f4: return((CHAR)(147 & 0xff));
- case 0x00f5: return((CHAR)(228 & 0xff));
- case 0x00f6: return((CHAR)(148 & 0xff));
- case 0x00f7: return((CHAR)(246 & 0xff));
- case 0x00f8: return((CHAR)(155 & 0xff));
- case 0x00f9: return((CHAR)(151 & 0xff));
- case 0x00fa: return((CHAR)(163 & 0xff));
- case 0x00fb: return((CHAR)(150 & 0xff));
- case 0x00fc: return((CHAR)(129 & 0xff));
- case 0x00fd: return((CHAR)(236 & 0xff));
- case 0x00fe: return((CHAR)(231 & 0xff));
- case 0x00ff: return((CHAR)(152 & 0xff));
- case 0x0131: return((CHAR)(213 & 0xff));
- case 0x0192: return((CHAR)(159 & 0xff));
- case 0x2017: return((CHAR)(242 & 0xff));
- case 0x2500: return((CHAR)(196 & 0xff));
- case 0x2502: return((CHAR)(179 & 0xff));
- case 0x250c: return((CHAR)(218 & 0xff));
- case 0x2510: return((CHAR)(191 & 0xff));
- case 0x2514: return((CHAR)(192 & 0xff));
- case 0x2518: return((CHAR)(217 & 0xff));
- case 0x251c: return((CHAR)(195 & 0xff));
- case 0x2524: return((CHAR)(180 & 0xff));
- case 0x252c: return((CHAR)(194 & 0xff));
- case 0x2534: return((CHAR)(193 & 0xff));
- case 0x253c: return((CHAR)(197 & 0xff));
- case 0x2550: return((CHAR)(205 & 0xff));
- case 0x2551: return((CHAR)(186 & 0xff));
- case 0x2554: return((CHAR)(201 & 0xff));
- case 0x2557: return((CHAR)(187 & 0xff));
- case 0x255a: return((CHAR)(200 & 0xff));
- case 0x255d: return((CHAR)(188 & 0xff));
- case 0x2560: return((CHAR)(204 & 0xff));
- case 0x2563: return((CHAR)(185 & 0xff));
- case 0x2566: return((CHAR)(203 & 0xff));
- case 0x2569: return((CHAR)(202 & 0xff));
- case 0x256c: return((CHAR)(206 & 0xff));
- case 0x2580: return((CHAR)(223 & 0xff));
- case 0x2584: return((CHAR)(220 & 0xff));
- case 0x2588: return((CHAR)(219 & 0xff));
- case 0x2591: return((CHAR)(176 & 0xff));
- case 0x2592: return((CHAR)(177 & 0xff));
- case 0x2593: return((CHAR)(178 & 0xff));
- case 0x25a0: return((CHAR)(254 & 0xff));
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* PC Code Page 858 */
-#ifdef CK_ANSIC
-tx_cp858(USHORT c)
-#else
-tx_cp858(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a0: return((CHAR)(255 & 0xff));
- case 0x00a1: return((CHAR)(173 & 0xff));
- case 0x00a2: return((CHAR)(189 & 0xff));
- case 0x00a3: return((CHAR)(156 & 0xff));
- case 0x00a4: return((CHAR)(207 & 0xff));
- case 0x00a5: return((CHAR)(190 & 0xff));
- case 0x00a6: return((CHAR)(221 & 0xff));
- case 0x00a7: return((CHAR)(245 & 0xff));
- case 0x00a8: return((CHAR)(249 & 0xff));
- case 0x00a9: return((CHAR)(184 & 0xff));
- case 0x00aa: return((CHAR)(166 & 0xff));
- case 0x00ab: return((CHAR)(174 & 0xff));
- case 0x00ac: return((CHAR)(170 & 0xff));
- case 0x00ad: return((CHAR)(240 & 0xff));
- case 0x00ae: return((CHAR)(169 & 0xff));
- case 0x00af: return((CHAR)(238 & 0xff));
- case 0x00b0: return((CHAR)(248 & 0xff));
- case 0x00b1: return((CHAR)(241 & 0xff));
- case 0x00b2: return((CHAR)(253 & 0xff));
- case 0x00b3: return((CHAR)(252 & 0xff));
- case 0x00b4: return((CHAR)(239 & 0xff));
- case 0x00b5: return((CHAR)(230 & 0xff));
- case 0x00b6: return((CHAR)(244 & 0xff));
- case 0x00b7: return((CHAR)(250 & 0xff));
- case 0x00b8: return((CHAR)(247 & 0xff));
- case 0x00b9: return((CHAR)(251 & 0xff));
- case 0x00ba: return((CHAR)(167 & 0xff));
- case 0x00bb: return((CHAR)(175 & 0xff));
- case 0x00bc: return((CHAR)(172 & 0xff));
- case 0x00bd: return((CHAR)(171 & 0xff));
- case 0x00be: return((CHAR)(243 & 0xff));
- case 0x00bf: return((CHAR)(168 & 0xff));
- case 0x00c0: return((CHAR)(183 & 0xff));
- case 0x00c1: return((CHAR)(181 & 0xff));
- case 0x00c2: return((CHAR)(182 & 0xff));
- case 0x00c3: return((CHAR)(199 & 0xff));
- case 0x00c4: return((CHAR)(142 & 0xff));
- case 0x00c5: return((CHAR)(143 & 0xff));
- case 0x00c6: return((CHAR)(146 & 0xff));
- case 0x00c7: return((CHAR)(128 & 0xff));
- case 0x00c8: return((CHAR)(212 & 0xff));
- case 0x00c9: return((CHAR)(144 & 0xff));
- case 0x00ca: return((CHAR)(210 & 0xff));
- case 0x00cb: return((CHAR)(211 & 0xff));
- case 0x00cc: return((CHAR)(222 & 0xff));
- case 0x00cd: return((CHAR)(214 & 0xff));
- case 0x00ce: return((CHAR)(215 & 0xff));
- case 0x00cf: return((CHAR)(216 & 0xff));
- case 0x00d0: return((CHAR)(209 & 0xff));
- case 0x00d1: return((CHAR)(165 & 0xff));
- case 0x00d2: return((CHAR)(227 & 0xff));
- case 0x00d3: return((CHAR)(224 & 0xff));
- case 0x00d4: return((CHAR)(226 & 0xff));
- case 0x00d5: return((CHAR)(229 & 0xff));
- case 0x00d6: return((CHAR)(153 & 0xff));
- case 0x00d7: return((CHAR)(158 & 0xff));
- case 0x00d8: return((CHAR)(157 & 0xff));
- case 0x00d9: return((CHAR)(235 & 0xff));
- case 0x00da: return((CHAR)(233 & 0xff));
- case 0x00db: return((CHAR)(234 & 0xff));
- case 0x00dc: return((CHAR)(154 & 0xff));
- case 0x00dd: return((CHAR)(237 & 0xff));
- case 0x00de: return((CHAR)(232 & 0xff));
- case 0x00df: return((CHAR)(225 & 0xff));
- case 0x00e0: return((CHAR)(133 & 0xff));
- case 0x00e1: return((CHAR)(160 & 0xff));
- case 0x00e2: return((CHAR)(131 & 0xff));
- case 0x00e3: return((CHAR)(198 & 0xff));
- case 0x00e4: return((CHAR)(132 & 0xff));
- case 0x00e5: return((CHAR)(134 & 0xff));
- case 0x00e6: return((CHAR)(145 & 0xff));
- case 0x00e7: return((CHAR)(135 & 0xff));
- case 0x00e8: return((CHAR)(138 & 0xff));
- case 0x00e9: return((CHAR)(130 & 0xff));
- case 0x00ea: return((CHAR)(136 & 0xff));
- case 0x00eb: return((CHAR)(137 & 0xff));
- case 0x00ec: return((CHAR)(141 & 0xff));
- case 0x00ed: return((CHAR)(161 & 0xff));
- case 0x00ee: return((CHAR)(140 & 0xff));
- case 0x00ef: return((CHAR)(139 & 0xff));
- case 0x00f0: return((CHAR)(208 & 0xff));
- case 0x00f1: return((CHAR)(164 & 0xff));
- case 0x00f2: return((CHAR)(149 & 0xff));
- case 0x00f3: return((CHAR)(162 & 0xff));
- case 0x00f4: return((CHAR)(147 & 0xff));
- case 0x00f5: return((CHAR)(228 & 0xff));
- case 0x00f6: return((CHAR)(148 & 0xff));
- case 0x00f7: return((CHAR)(246 & 0xff));
- case 0x00f8: return((CHAR)(155 & 0xff));
- case 0x00f9: return((CHAR)(151 & 0xff));
- case 0x00fa: return((CHAR)(163 & 0xff));
- case 0x00fb: return((CHAR)(150 & 0xff));
- case 0x00fc: return((CHAR)(129 & 0xff));
- case 0x00fd: return((CHAR)(236 & 0xff));
- case 0x00fe: return((CHAR)(231 & 0xff));
- case 0x00ff: return((CHAR)(152 & 0xff));
- case 0x20ac: return((CHAR)(213 & 0xff));
- case 0x0192: return((CHAR)(159 & 0xff));
- case 0x2017: return((CHAR)(242 & 0xff));
- case 0x2500: return((CHAR)(196 & 0xff));
- case 0x2502: return((CHAR)(179 & 0xff));
- case 0x250c: return((CHAR)(218 & 0xff));
- case 0x2510: return((CHAR)(191 & 0xff));
- case 0x2514: return((CHAR)(192 & 0xff));
- case 0x2518: return((CHAR)(217 & 0xff));
- case 0x251c: return((CHAR)(195 & 0xff));
- case 0x2524: return((CHAR)(180 & 0xff));
- case 0x252c: return((CHAR)(194 & 0xff));
- case 0x2534: return((CHAR)(193 & 0xff));
- case 0x253c: return((CHAR)(197 & 0xff));
- case 0x2550: return((CHAR)(205 & 0xff));
- case 0x2551: return((CHAR)(186 & 0xff));
- case 0x2554: return((CHAR)(201 & 0xff));
- case 0x2557: return((CHAR)(187 & 0xff));
- case 0x255a: return((CHAR)(200 & 0xff));
- case 0x255d: return((CHAR)(188 & 0xff));
- case 0x2560: return((CHAR)(204 & 0xff));
- case 0x2563: return((CHAR)(185 & 0xff));
- case 0x2566: return((CHAR)(203 & 0xff));
- case 0x2569: return((CHAR)(202 & 0xff));
- case 0x256c: return((CHAR)(206 & 0xff));
- case 0x2580: return((CHAR)(223 & 0xff));
- case 0x2584: return((CHAR)(220 & 0xff));
- case 0x2588: return((CHAR)(219 & 0xff));
- case 0x2591: return((CHAR)(176 & 0xff));
- case 0x2592: return((CHAR)(177 & 0xff));
- case 0x2593: return((CHAR)(178 & 0xff));
- case 0x25a0: return((CHAR)(254 & 0xff));
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* Windows Code Page 1250 (Latin-2) */
-#ifdef CK_ANSIC
-tx_cp1250(USHORT c)
-#else
-tx_cp1250(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80 || (c > 0xbf && c <= 0xff)) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x002D: return((CHAR)(0xad & 0xff));
- case 0x00A0: return((CHAR)(0xa0 & 0xff));
- case 0x00A4: return((CHAR)(0xa4 & 0xff));
- case 0x00A6: return((CHAR)(0xa6 & 0xff));
- case 0x00A7: return((CHAR)(0xa7 & 0xff));
- case 0x00A8: return((CHAR)(0xa8 & 0xff));
- case 0x00A9: return((CHAR)(0xa9 & 0xff));
- case 0x00AB: return((CHAR)(0xab & 0xff));
- case 0x00AC: return((CHAR)(0xac & 0xff));
- case 0x00AE: return((CHAR)(0xae & 0xff));
- case 0x00B0: return((CHAR)(0xb0 & 0xff));
- case 0x00B1: return((CHAR)(0xb1 & 0xff));
- case 0x00B4: return((CHAR)(0xb4 & 0xff));
- case 0x00B5: return((CHAR)(0xb5 & 0xff));
- case 0x00B6: return((CHAR)(0xb6 & 0xff));
- case 0x00B7: return((CHAR)(0xb7 & 0xff));
- case 0x00B8: return((CHAR)(0xb8 & 0xff));
- case 0x00BB: return((CHAR)(0xbb & 0xff));
- case 0x0104: return((CHAR)(0xa5 & 0xff));
- case 0x0105: return((CHAR)(0xb9 & 0xff));
- case 0x013D: return((CHAR)(0xbc & 0xff));
- case 0x013E: return((CHAR)(0xbe & 0xff));
- case 0x0141: return((CHAR)(0xa3 & 0xff));
- case 0x0142: return((CHAR)(0xb3 & 0xff));
- case 0x015A: return((CHAR)(0x8c & 0xff)); /* S acute */
- case 0x015E: return((CHAR)(0xaa & 0xff));
- case 0x015F: return((CHAR)(0xba & 0xff));
- case 0x015b: return((CHAR)(0x9c & 0xff)); /* s acute */
- case 0x0164: return((CHAR)(0x8d & 0xff)); /* T caron */
- case 0x0165: return((CHAR)(0x9d & 0xff)); /* t caron */
- case 0x0173: return((CHAR)(0x9e & 0xff)); /* z caron */
- case 0x0179: return((CHAR)(0x8f & 0xff)); /* Z acute */
- case 0x017A: return((CHAR)(0x9f & 0xff)); /* z acute */
- case 0x017B: return((CHAR)(0xaf & 0xff));
- case 0x017C: return((CHAR)(0xbf & 0xff));
- case 0x017D: return((CHAR)(0x8e & 0xff)); /* Z caron */
- case 0x02C7: return((CHAR)(0xa1 & 0xff));
- case 0x02D8: return((CHAR)(0xa2 & 0xff));
- case 0x02DB: return((CHAR)(0xb2 & 0xff));
- case 0x02DD: return((CHAR)(0xbd & 0xff));
- case 0x2010: case 0x2011: /* Hyphens */
- return((CHAR)(0x2d & 0xff));
- case 0x2012: case 0x2013: /* en-dashes */
- return((CHAR)(0x96 & 0xff));
- case 0x2014: case 0x2015: /* em-dashes */
- return((CHAR)(0x97 & 0xff));
- case 0x2018: /* Various quotation marks... */
- return((CHAR)(0x91 & 0xff));
- case 0x2019:
- return((CHAR)(0x92 & 0xff));
- case 0x201c:
- return((CHAR)(0x93 & 0xff));
- case 0x201d:
- return((CHAR)(0x94 & 0xff));
- case 0x201e:
- return((CHAR)(0x84 & 0xff));
- case 0x2020: /* Dagger */
- return((CHAR)(0x86 & 0xff));
- case 0x2021: /* Double Dagger */
- return((CHAR)(0x87 & 0xff));
- case 0x2022: /* Bullet */
- return((CHAR)(0x95 & 0xff));
- case 0x2026: /* Ellipsis */
- return((CHAR)(0x85 & 0xff));
- case 0x2030: /* Per mil */
- return((CHAR)(0x89 & 0xff));
- case 0x20AC: /* Euro */
- return((CHAR)(0x80 & 0xff));
- case 0x2122: /* Trade Mark */
- return((CHAR)(0x99 & 0xff));
- default: return(0x003f);
- }
-}
-
-int /* Windows Code Page 1251 (Cyrillic) */
-#ifdef CK_ANSIC
-tx_cp1251(USHORT c)
-#else
-tx_cp1251(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- /* This is simply the inverse of u_cp1251.map */
- switch (c) {
- case 0x003c: return((CHAR)(0x8b & 0xff));
- case 0x003e: return((CHAR)(0x9b & 0xff));
- case 0x007e: return((CHAR)(0x98 & 0xff));
- case 0x00A0: return((CHAR)(0xa0 & 0xff));
- case 0x00A4: return((CHAR)(0xa4 & 0xff));
- case 0x00A6: return((CHAR)(0xa6 & 0xff));
- case 0x00A7: return((CHAR)(0xa7 & 0xff));
- case 0x00A9: return((CHAR)(0xa9 & 0xff));
- case 0x00AB: return((CHAR)(0xab & 0xff));
- case 0x00AC: return((CHAR)(0xac & 0xff));
- case 0x00AD: return((CHAR)(0xad & 0xff));
- case 0x00AE: return((CHAR)(0xae & 0xff));
- case 0x00b0: return((CHAR)(0xb0 & 0xff));
- case 0x00b1: return((CHAR)(0xb1 & 0xff));
- case 0x00B5: return((CHAR)(0xb5 & 0xff));
- case 0x00B6: return((CHAR)(0xb6 & 0xff));
- case 0x00B7: return((CHAR)(0xb7 & 0xff));
- case 0x00BB: return((CHAR)(0xbb & 0xff));
- case 0x0401: return((CHAR)(0xa8 & 0xff));
- case 0x0402: return((CHAR)(0x80 & 0xff));
- case 0x0403: return((CHAR)(0x81 & 0xff));
- case 0x0404: return((CHAR)(0xaa & 0xff));
- case 0x0405: return((CHAR)(0xbd & 0xff));
- case 0x0406: return((CHAR)(0xb2 & 0xff));
- case 0x0407: return((CHAR)(0xaf & 0xff));
- case 0x0408: return((CHAR)(0xa3 & 0xff));
- case 0x0409: return((CHAR)(0x8a & 0xff));
- case 0x040a: return((CHAR)(0x8c & 0xff));
- case 0x040b: return((CHAR)(0x8e & 0xff));
- case 0x040c: return((CHAR)(0x8d & 0xff));
- case 0x040e: return((CHAR)(0xa1 & 0xff));
- case 0x040f: return((CHAR)(0x8f & 0xff));
- case 0x0410: return((CHAR)(0xc0 & 0xff));
- case 0x0411: return((CHAR)(0xc1 & 0xff));
- case 0x0412: return((CHAR)(0xc2 & 0xff));
- case 0x0413: return((CHAR)(0xc3 & 0xff));
- case 0x0414: return((CHAR)(0xc4 & 0xff));
- case 0x0415: return((CHAR)(0xc5 & 0xff));
- case 0x0416: return((CHAR)(0xc6 & 0xff));
- case 0x0417: return((CHAR)(0xc7 & 0xff));
- case 0x0418: return((CHAR)(0xc8 & 0xff));
- case 0x0419: return((CHAR)(0xc9 & 0xff));
- case 0x041a: return((CHAR)(0xca & 0xff));
- case 0x041b: return((CHAR)(0xcb & 0xff));
- case 0x041c: return((CHAR)(0xcc & 0xff));
- case 0x041d: return((CHAR)(0xcd & 0xff));
- case 0x041e: return((CHAR)(0xce & 0xff));
- case 0x041f: return((CHAR)(0xcf & 0xff));
- case 0x0420: return((CHAR)(0xd0 & 0xff));
- case 0x0421: return((CHAR)(0xd1 & 0xff));
- case 0x0422: return((CHAR)(0xd2 & 0xff));
- case 0x0423: return((CHAR)(0xd3 & 0xff));
- case 0x0424: return((CHAR)(0xd4 & 0xff));
- case 0x0425: return((CHAR)(0xd5 & 0xff));
- case 0x0426: return((CHAR)(0xd6 & 0xff));
- case 0x0427: return((CHAR)(0xd7 & 0xff));
- case 0x0428: return((CHAR)(0xd8 & 0xff));
- case 0x0429: return((CHAR)(0xd9 & 0xff));
- case 0x042a: return((CHAR)(0xda & 0xff));
- case 0x042b: return((CHAR)(0xdb & 0xff));
- case 0x042c: return((CHAR)(0xdc & 0xff));
- case 0x042d: return((CHAR)(0xdd & 0xff));
- case 0x042e: return((CHAR)(0xde & 0xff));
- case 0x042f: return((CHAR)(0xdf & 0xff));
- case 0x0430: return((CHAR)(0xe0 & 0xff));
- case 0x0431: return((CHAR)(0xe1 & 0xff));
- case 0x0432: return((CHAR)(0xe2 & 0xff));
- case 0x0433: return((CHAR)(0xe3 & 0xff));
- case 0x0434: return((CHAR)(0xe4 & 0xff));
- case 0x0435: return((CHAR)(0xe5 & 0xff));
- case 0x0436: return((CHAR)(0xe6 & 0xff));
- case 0x0437: return((CHAR)(0xe7 & 0xff));
- case 0x0438: return((CHAR)(0xe8 & 0xff));
- case 0x0439: return((CHAR)(0xe9 & 0xff));
- case 0x043a: return((CHAR)(0xea & 0xff));
- case 0x043b: return((CHAR)(0xeb & 0xff));
- case 0x043c: return((CHAR)(0xec & 0xff));
- case 0x043d: return((CHAR)(0xed & 0xff));
- case 0x043e: return((CHAR)(0xee & 0xff));
- case 0x043f: return((CHAR)(0xef & 0xff));
- case 0x0440: return((CHAR)(0xf0 & 0xff));
- case 0x0441: return((CHAR)(0xf1 & 0xff));
- case 0x0442: return((CHAR)(0xf2 & 0xff));
- case 0x0443: return((CHAR)(0xf3 & 0xff));
- case 0x0444: return((CHAR)(0xf4 & 0xff));
- case 0x0445: return((CHAR)(0xf5 & 0xff));
- case 0x0446: return((CHAR)(0xf6 & 0xff));
- case 0x0447: return((CHAR)(0xf7 & 0xff));
- case 0x0448: return((CHAR)(0xf8 & 0xff));
- case 0x0449: return((CHAR)(0xf9 & 0xff));
- case 0x044a: return((CHAR)(0xfa & 0xff));
- case 0x044b: return((CHAR)(0xfb & 0xff));
- case 0x044c: return((CHAR)(0xfc & 0xff));
- case 0x044d: return((CHAR)(0xfd & 0xff));
- case 0x044e: return((CHAR)(0xfe & 0xff));
- case 0x044f: return((CHAR)(0xff & 0xff));
- case 0x0451: return((CHAR)(0xb8 & 0xff));
- case 0x0452: return((CHAR)(0x90 & 0xff));
- case 0x0453: return((CHAR)(0x83 & 0xff));
- case 0x0454: return((CHAR)(0xba & 0xff));
- case 0x0455: return((CHAR)(0xbe & 0xff));
- case 0x0456: return((CHAR)(0xb3 & 0xff));
- case 0x0457: return((CHAR)(0xbf & 0xff));
- case 0x0458: return((CHAR)(0xbc & 0xff));
- case 0x0459: return((CHAR)(0x9a & 0xff));
- case 0x045a: return((CHAR)(0x9c & 0xff));
- case 0x045b: return((CHAR)(0x9e & 0xff));
- case 0x045c: return((CHAR)(0x9d & 0xff));
- case 0x045e: return((CHAR)(0xa2 & 0xff));
- case 0x045f: return((CHAR)(0x9f & 0xff));
- case 0x0490: return((CHAR)(0xa5 & 0xff));
- case 0x0491: return((CHAR)(0xb4 & 0xff));
- case 0x2012: return((CHAR)(0x96 & 0xff));
- case 0x2014: return((CHAR)(0x97 & 0xff));
- case 0x2018: return((CHAR)(0x91 & 0xff));
- case 0x2019: return((CHAR)(0x92 & 0xff));
- case 0x201a: return((CHAR)(0x82 & 0xff));
- case 0x201c: return((CHAR)(0x93 & 0xff));
- case 0x201d: return((CHAR)(0x94 & 0xff));
- case 0x201e: return((CHAR)(0x84 & 0xff));
- case 0x2020: return((CHAR)(0x86 & 0xff));
- case 0x2021: return((CHAR)(0x87 & 0xff));
- case 0x2022: return((CHAR)(0x95 & 0xff));
- case 0x2026: return((CHAR)(0x85 & 0xff));
- case 0x2031: return((CHAR)(0x89 & 0xff));
- case 0x20AC: /* Euro */
- return((CHAR)(0x88 & 0xff));
- case 0x2116: return((CHAR)(0xb9 & 0xff));
- case 0x2122: return((CHAR)(0x99 & 0xff));
- default: return(0x003f);
- }
-}
-
-int /* Unicode to Windows Code Page 1252 (Latin-1) */
-#ifdef CK_ANSIC
-tx_cp1252(USHORT c)
-#else
-tx_cp1252(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80 || (c > 0x9f && c <= 0xff)) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x0152: /* OE */
- return((CHAR)(0x8c & 0xff));
- case 0x0153: /* oe */
- return((CHAR)(0x9c & 0xff));
- case 0x0160: /* S caron */
- return((CHAR)(0x8a & 0xff));
- case 0x0161: /* s caron */
- return((CHAR)(0x9a & 0xff));
- case 0x0178: /* Y diaeresis */
- return((CHAR)(0x9f & 0xff));
- case 0x017D: /* Z caron */
- return((CHAR)(0x8e & 0xff));
- case 0x017E: /* z caron */
- return((CHAR)(0x9e & 0xff));
- case 0x0192: /* Florin */
- return((CHAR)(0x83 & 0xff));
- case 0x2010: case 0x2011: /* Hyphens */
- return((CHAR)(0x2d & 0xff));
- case 0x2012: case 0x2013: /* en-dashes */
- return((CHAR)(0x96 & 0xff));
- case 0x2014: case 0x2015: /* em-dashes */
- return((CHAR)(0x97 & 0xff));
- case 0x2018: /* Various quotation marks... */
- return((CHAR)(0x91 & 0xff));
- case 0x2019:
- return((CHAR)(0x92 & 0xff));
- case 0x201c:
- return((CHAR)(0x93 & 0xff));
- case 0x201d:
- return((CHAR)(0x94 & 0xff));
- case 0x201e:
- return((CHAR)(0x84 & 0xff));
- case 0x2020: /* Dagger */
- return((CHAR)(0x86 & 0xff));
- case 0x2021: /* Double Dagger */
- return((CHAR)(0x87 & 0xff));
- case 0x2022: /* Bullet */
- return((CHAR)(0x95 & 0xff));
- case 0x2026: /* Ellipsis */
- return((CHAR)(0x85 & 0xff));
- case 0x2030: /* Per mil */
- return((CHAR)(0x89 & 0xff));
- case 0x20AC: /* Euro */
- return((CHAR)(0x80 & 0xff));
- case 0x2122: /* Trade Mark */
- return((CHAR)(0x99 & 0xff));
- default: return(0x003f);
- }
-}
-
-int /* PC Code Page 852 */
-#ifdef CK_ANSIC
-tx_cp852(USHORT c)
-#else
-tx_cp852(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a0: return((CHAR)(255 & 0xff));
- case 0x00a4: return((CHAR)(207 & 0xff));
- case 0x00a7: return((CHAR)(245 & 0xff));
- case 0x00a8: return((CHAR)(249 & 0xff));
- case 0x00ab: return((CHAR)(174 & 0xff));
- case 0x00ac: return((CHAR)(170 & 0xff));
- case 0x00ad: return((CHAR)(240 & 0xff));
- case 0x00b0: return((CHAR)(248 & 0xff));
- case 0x00b4: return((CHAR)(239 & 0xff));
- case 0x00b8: return((CHAR)(247 & 0xff));
- case 0x00bb: return((CHAR)(175 & 0xff));
- case 0x00c1: return((CHAR)(181 & 0xff));
- case 0x00c2: return((CHAR)(182 & 0xff));
- case 0x00c4: return((CHAR)(142 & 0xff));
- case 0x00c7: return((CHAR)(128 & 0xff));
- case 0x00c9: return((CHAR)(144 & 0xff));
- case 0x00cb: return((CHAR)(211 & 0xff));
- case 0x00cd: return((CHAR)(214 & 0xff));
- case 0x00ce: return((CHAR)(215 & 0xff));
- case 0x00d3: return((CHAR)(224 & 0xff));
- case 0x00d4: return((CHAR)(226 & 0xff));
- case 0x00d6: return((CHAR)(153 & 0xff));
- case 0x00d7: return((CHAR)(158 & 0xff));
- case 0x00da: return((CHAR)(233 & 0xff));
- case 0x00dc: return((CHAR)(154 & 0xff));
- case 0x00dd: return((CHAR)(237 & 0xff));
- case 0x00df: return((CHAR)(225 & 0xff));
- case 0x00e1: return((CHAR)(160 & 0xff));
- case 0x00e2: return((CHAR)(131 & 0xff));
- case 0x00e4: return((CHAR)(132 & 0xff));
- case 0x00e7: return((CHAR)(135 & 0xff));
- case 0x00e9: return((CHAR)(130 & 0xff));
- case 0x00eb: return((CHAR)(137 & 0xff));
- case 0x00ed: return((CHAR)(161 & 0xff));
- case 0x00ee: return((CHAR)(140 & 0xff));
- case 0x00f3: return((CHAR)(162 & 0xff));
- case 0x00f4: return((CHAR)(147 & 0xff));
- case 0x00f6: return((CHAR)(148 & 0xff));
- case 0x00f7: return((CHAR)(246 & 0xff));
- case 0x00fa: return((CHAR)(163 & 0xff));
- case 0x00fc: return((CHAR)(129 & 0xff));
- case 0x00fd: return((CHAR)(236 & 0xff));
- case 0x0102: return((CHAR)(198 & 0xff));
- case 0x0103: return((CHAR)(199 & 0xff));
- case 0x0104: return((CHAR)(164 & 0xff));
- case 0x0105: return((CHAR)(165 & 0xff));
- case 0x0106: return((CHAR)(143 & 0xff));
- case 0x0107: return((CHAR)(134 & 0xff));
- case 0x010c: return((CHAR)(172 & 0xff));
- case 0x010d: return((CHAR)(159 & 0xff));
- case 0x010e: return((CHAR)(210 & 0xff));
- case 0x010f: return((CHAR)(212 & 0xff));
- case 0x0110: return((CHAR)(209 & 0xff));
- case 0x0111: return((CHAR)(208 & 0xff));
- case 0x0118: return((CHAR)(168 & 0xff));
- case 0x0119: return((CHAR)(169 & 0xff));
- case 0x011a: return((CHAR)(183 & 0xff));
- case 0x011b: return((CHAR)(216 & 0xff));
- case 0x0139: return((CHAR)(145 & 0xff));
- case 0x013a: return((CHAR)(146 & 0xff));
- case 0x013d: return((CHAR)(149 & 0xff));
- case 0x013e: return((CHAR)(150 & 0xff));
- case 0x0141: return((CHAR)(157 & 0xff));
- case 0x0142: return((CHAR)(136 & 0xff));
- case 0x0143: return((CHAR)(227 & 0xff));
- case 0x0144: return((CHAR)(228 & 0xff));
- case 0x0147: return((CHAR)(213 & 0xff));
- case 0x0148: return((CHAR)(229 & 0xff));
- case 0x0150: return((CHAR)(138 & 0xff));
- case 0x0151: return((CHAR)(139 & 0xff));
- case 0x0154: return((CHAR)(232 & 0xff));
- case 0x0155: return((CHAR)(234 & 0xff));
- case 0x0158: return((CHAR)(252 & 0xff));
- case 0x0159: return((CHAR)(253 & 0xff));
- case 0x015a: return((CHAR)(151 & 0xff));
- case 0x015b: return((CHAR)(152 & 0xff));
- case 0x015e: return((CHAR)(184 & 0xff));
- case 0x015f: return((CHAR)(173 & 0xff));
- case 0x0160: return((CHAR)(230 & 0xff));
- case 0x0161: return((CHAR)(231 & 0xff));
- case 0x0162: return((CHAR)(221 & 0xff));
- case 0x0163: return((CHAR)(238 & 0xff));
- case 0x0164: return((CHAR)(155 & 0xff));
- case 0x0165: return((CHAR)(156 & 0xff));
- case 0x016e: return((CHAR)(222 & 0xff));
- case 0x016f: return((CHAR)(133 & 0xff));
- case 0x0170: return((CHAR)(235 & 0xff));
- case 0x0171: return((CHAR)(251 & 0xff));
- case 0x0179: return((CHAR)(141 & 0xff));
- case 0x017a: return((CHAR)(171 & 0xff));
- case 0x017b: return((CHAR)(189 & 0xff));
- case 0x017c: return((CHAR)(190 & 0xff));
- case 0x017d: return((CHAR)(166 & 0xff));
- case 0x017e: return((CHAR)(167 & 0xff));
- case 0x02c7: return((CHAR)(243 & 0xff));
- case 0x02d8: return((CHAR)(244 & 0xff));
- case 0x02d9: return((CHAR)(250 & 0xff));
- case 0x02db: return((CHAR)(242 & 0xff));
- case 0x02dd: return((CHAR)(241 & 0xff));
- case 0x2500: return((CHAR)(196 & 0xff));
- case 0x2502: return((CHAR)(179 & 0xff));
- case 0x250c: return((CHAR)(218 & 0xff));
- case 0x2510: return((CHAR)(191 & 0xff));
- case 0x2514: return((CHAR)(192 & 0xff));
- case 0x2518: return((CHAR)(217 & 0xff));
- case 0x251c: return((CHAR)(195 & 0xff));
- case 0x2524: return((CHAR)(180 & 0xff));
- case 0x252c: return((CHAR)(194 & 0xff));
- case 0x2534: return((CHAR)(193 & 0xff));
- case 0x253c: return((CHAR)(197 & 0xff));
- case 0x2550: return((CHAR)(205 & 0xff));
- case 0x2551: return((CHAR)(186 & 0xff));
- case 0x2554: return((CHAR)(201 & 0xff));
- case 0x2557: return((CHAR)(187 & 0xff));
- case 0x255a: return((CHAR)(200 & 0xff));
- case 0x255d: return((CHAR)(188 & 0xff));
- case 0x2560: return((CHAR)(204 & 0xff));
- case 0x2563: return((CHAR)(185 & 0xff));
- case 0x2566: return((CHAR)(203 & 0xff));
- case 0x2569: return((CHAR)(202 & 0xff));
- case 0x256c: return((CHAR)(206 & 0xff));
- case 0x2580: return((CHAR)(223 & 0xff));
- case 0x2584: return((CHAR)(220 & 0xff));
- case 0x2588: return((CHAR)(219 & 0xff));
- case 0x2591: return((CHAR)(176 & 0xff));
- case 0x2592: return((CHAR)(177 & 0xff));
- case 0x2593: return((CHAR)(178 & 0xff));
- case 0x25a0: return((CHAR)(254 & 0xff));
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* Windows Code Page 1253 (Greek) */
-#ifdef CK_ANSIC
-tx_cp1253(USHORT c)
-#else
-tx_cp1253(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x003c: return((CHAR)(0x8b & 0xff));
- case 0x003e: return((CHAR)(0x9b & 0xff));
- case 0x00A0: return((CHAR)(0xa0 & 0xff));
- case 0x00A3: return((CHAR)(0xa3 & 0xff));
- case 0x00A4: return((CHAR)(0xa4 & 0xff));
- case 0x00A5: return((CHAR)(0xa5 & 0xff));
- case 0x00A6: return((CHAR)(0xa6 & 0xff));
- case 0x00A7: return((CHAR)(0xa7 & 0xff));
- case 0x00A8: return((CHAR)(0xa8 & 0xff));
- case 0x00A9: return((CHAR)(0xa9 & 0xff));
- case 0x00AA: return((CHAR)(0xaa & 0xff));
- case 0x00AB: return((CHAR)(0xab & 0xff));
- case 0x00AC: return((CHAR)(0xac & 0xff));
- case 0x00AD: return((CHAR)(0xad & 0xff));
- case 0x00AE: return((CHAR)(0xae & 0xff));
- case 0x00AF: return((CHAR)(0xaf & 0xff));
- case 0x00B0: return((CHAR)(0xb0 & 0xff));
- case 0x00B1: return((CHAR)(0xb1 & 0xff));
- case 0x00B2: return((CHAR)(0xb2 & 0xff));
- case 0x00B3: return((CHAR)(0xb3 & 0xff));
- case 0x00B5: return((CHAR)(0xb5 & 0xff));
- case 0x00B6: return((CHAR)(0xb6 & 0xff));
- case 0x00b7: return((CHAR)(0xa1 & 0xff));
- case 0x00BB: return((CHAR)(0xbb & 0xff));
- case 0x00BD: return((CHAR)(0xbd & 0xff));
- case 0x0192: return((CHAR)(0x83 & 0xff));
- case 0x0386: return((CHAR)(0xa2 & 0xff));
- case 0x0388: return((CHAR)(0xb8 & 0xff));
- case 0x0389: return((CHAR)(0xb9 & 0xff));
- case 0x038A: return((CHAR)(0xba & 0xff));
- case 0x038C: return((CHAR)(0xbc & 0xff));
- case 0x038E: return((CHAR)(0xbe & 0xff));
- case 0x038F: return((CHAR)(0xbf & 0xff));
- case 0x0390: return((CHAR)(0xc0 & 0xff));
- case 0x0391: return((CHAR)(0xc1 & 0xff));
- case 0x0392: return((CHAR)(0xc2 & 0xff));
- case 0x0393: return((CHAR)(0xc3 & 0xff));
- case 0x0394: return((CHAR)(0xc4 & 0xff));
- case 0x0395: return((CHAR)(0xc5 & 0xff));
- case 0x0396: return((CHAR)(0xc6 & 0xff));
- case 0x0397: return((CHAR)(0xc7 & 0xff));
- case 0x0398: return((CHAR)(0xc8 & 0xff));
- case 0x0399: return((CHAR)(0xc9 & 0xff));
- case 0x039A: return((CHAR)(0xca & 0xff));
- case 0x039B: return((CHAR)(0xcb & 0xff));
- case 0x039C: return((CHAR)(0xcc & 0xff));
- case 0x039D: return((CHAR)(0xcd & 0xff));
- case 0x039E: return((CHAR)(0xce & 0xff));
- case 0x039F: return((CHAR)(0xcf & 0xff));
- case 0x03a0: return((CHAR)(0xd0 & 0xff));
- case 0x03a1: return((CHAR)(0xd1 & 0xff));
- case 0x03a3: return((CHAR)(0xd3 & 0xff));
- case 0x03a4: return((CHAR)(0xd4 & 0xff));
- case 0x03a5: return((CHAR)(0xd5 & 0xff));
- case 0x03a6: return((CHAR)(0xd6 & 0xff));
- case 0x03a7: return((CHAR)(0xd7 & 0xff));
- case 0x03a8: return((CHAR)(0xd8 & 0xff));
- case 0x03a9: return((CHAR)(0xd9 & 0xff));
- case 0x03aA: return((CHAR)(0xda & 0xff));
- case 0x03aB: return((CHAR)(0xdb & 0xff));
- case 0x03aC: return((CHAR)(0xdc & 0xff));
- case 0x03aD: return((CHAR)(0xdd & 0xff));
- case 0x03aE: return((CHAR)(0xde & 0xff));
- case 0x03aF: return((CHAR)(0xdf & 0xff));
- case 0x03b0: return((CHAR)(0xe0 & 0xff));
- case 0x03b1: return((CHAR)(0xe1 & 0xff));
- case 0x03b2: return((CHAR)(0xe2 & 0xff));
- case 0x03b3: return((CHAR)(0xe3 & 0xff));
- case 0x03b4: return((CHAR)(0xe4 & 0xff));
- case 0x03b5: return((CHAR)(0xe5 & 0xff));
- case 0x03b6: return((CHAR)(0xe6 & 0xff));
- case 0x03b7: return((CHAR)(0xe7 & 0xff));
- case 0x03b8: return((CHAR)(0xe8 & 0xff));
- case 0x03b9: return((CHAR)(0xe9 & 0xff));
- case 0x03bA: return((CHAR)(0xea & 0xff));
- case 0x03bB: return((CHAR)(0xeb & 0xff));
- case 0x03bC: return((CHAR)(0xec & 0xff));
- case 0x03bD: return((CHAR)(0xed & 0xff));
- case 0x03bE: return((CHAR)(0xee & 0xff));
- case 0x03bF: return((CHAR)(0xef & 0xff));
- case 0x03c0: return((CHAR)(0xf0 & 0xff));
- case 0x03c1: return((CHAR)(0xf1 & 0xff));
- case 0x03c2: return((CHAR)(0xf2 & 0xff));
- case 0x03c3: return((CHAR)(0xf3 & 0xff));
- case 0x03c4: return((CHAR)(0xf4 & 0xff));
- case 0x03c5: return((CHAR)(0xf5 & 0xff));
- case 0x03c6: return((CHAR)(0xf6 & 0xff));
- case 0x03c7: return((CHAR)(0xf7 & 0xff));
- case 0x03c8: return((CHAR)(0xf8 & 0xff));
- case 0x03c9: return((CHAR)(0xf9 & 0xff));
- case 0x03cA: return((CHAR)(0xfa & 0xff));
- case 0x03cB: return((CHAR)(0xfb & 0xff));
- case 0x03cC: return((CHAR)(0xfc & 0xff));
- case 0x03cD: return((CHAR)(0xfd & 0xff));
- case 0x03cE: return((CHAR)(0xfe & 0xff));
- case 0x2012: return((CHAR)(0x96 & 0xff));
- case 0x2014: return((CHAR)(0x97 & 0xff));
- case 0x2018: return((CHAR)(0x91 & 0xff));
- case 0x2019: return((CHAR)(0x92 & 0xff));
- case 0x201a: return((CHAR)(0x82 & 0xff));
- case 0x201c: return((CHAR)(0x93 & 0xff));
- case 0x201d: return((CHAR)(0x94 & 0xff));
- case 0x201e: return((CHAR)(0x84 & 0xff));
- case 0x2020: return((CHAR)(0x86 & 0xff));
- case 0x2021: return((CHAR)(0x87 & 0xff));
- case 0x2022: return((CHAR)(0x95 & 0xff));
- case 0x2026: return((CHAR)(0x85 & 0xff));
- case 0x2031: return((CHAR)(0x89 & 0xff));
- case 0x20AC: /* Euro */
- return((CHAR)(0x80 & 0xff));
- case 0x2122: return((CHAR)(0x99 & 0xff));
- default: return(0x003f);
- }
-}
-
-int /* Windows Code Page 1254 (Turkish) */
-#ifdef CK_ANSIC
-tx_cp1254(USHORT c)
-#else
-tx_cp1254(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80)
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x011e: return((CHAR)(0xd0 & 0xff)); /* G breve */
- case 0x0130: return((CHAR)(0xdd & 0xff)); /* I with dot */
- case 0x015e: return((CHAR)(0xde & 0xff)); /* S cedilla */
- case 0x011f: return((CHAR)(0xf0 & 0xff)); /* g breve */
- case 0x0131: return((CHAR)(0xfd & 0xff)); /* i dotless */
- case 0x015f: return((CHAR)(0xfe & 0xff)); /* s cedilla */
- default: return(tx_cp1252(c)); /* The rest is like Windows Latin-1 */
- }
-}
-
-int
-#ifdef CK_ANSIC
-tx_cp1255(USHORT c)
-#else
-tx_cp1255(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x080)
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x20AC:
- return((CHAR)(0x80 & 0xff)); /* EURO SIGN */
- case 0x201A:
- return((CHAR)(0x82 & 0xff)); /* SINGLE LOW-9 QUOTATION MARK */
- case 0x0192:
- return((CHAR)(0x83 & 0xff)); /* LATIN SMALL LETTER F WITH HOOK */
- case 0x201E:
- return((CHAR)(0x84 & 0xff)); /* DOUBLE LOW-9 QUOTATION MARK */
- case 0x2026:
- return((CHAR)(0x85 & 0xff)); /* HORIZONTAL ELLIPSIS */
- case 0x2020:
- return((CHAR)(0x86 & 0xff)); /* DAGGER */
- case 0x2021:
- return((CHAR)(0x87 & 0xff)); /* DOUBLE DAGGER */
- case 0x02C6:
- return((CHAR)(0x88 & 0xff)); /* MODIFIER LETTER CIRCUMFLEX ACCENT */
- case 0x2030:
- return((CHAR)(0x89 & 0xff)); /* PER MILLE SIGN */
- case 0x2039:
- return((CHAR)(0x8B & 0xff)); /* SINGLE LEFT-POINTING ANGLE QUOTE */
- case 0x2018:
- return((CHAR)(0x91 & 0xff)); /* LEFT SINGLE QUOTATION MARK */
- case 0x2019:
- return((CHAR)(0x92 & 0xff)); /* RIGHT SINGLE QUOTATION MARK */
- case 0x201C:
- return((CHAR)(0x93 & 0xff)); /* LEFT DOUBLE QUOTATION MARK */
- case 0x201D:
- return((CHAR)(0x94 & 0xff)); /* RIGHT DOUBLE QUOTATION MARK */
- case 0x2022:
- return((CHAR)(0x95 & 0xff)); /* BULLET */
- case 0x2013:
- return((CHAR)(0x96 & 0xff)); /* EN DASH */
- case 0x2014:
- return((CHAR)(0x97 & 0xff)); /* EM DASH */
- case 0x02DC:
- return((CHAR)(0x98 & 0xff)); /* SMALL TILDE */
- case 0x2122:
- return((CHAR)(0x99 & 0xff)); /* TRADE MARK SIGN */
- case 0x203A:
- return((CHAR)(0x9B & 0xff)); /* SINGLE RIGHT-POINTING ANGLE QUOTE */
- case 0x00A0:
- return((CHAR)(0xA0 & 0xff)); /* NO-BREAK SPACE */
- case 0x00A1:
- return((CHAR)(0xA1 & 0xff)); /* INVERTED EXCLAMATION MARK */
- case 0x00A2:
- return((CHAR)(0xA2 & 0xff)); /* CENT SIGN */
- case 0x00A3:
- return((CHAR)(0xA3 & 0xff)); /* POUND SIGN */
- case 0x20AA:
- return((CHAR)(0xA4 & 0xff)); /* NEW SHEQEL SIGN */
- case 0x00A5:
- return((CHAR)(0xA5 & 0xff)); /* YEN SIGN */
- case 0x00A6:
- return((CHAR)(0xA6 & 0xff)); /* BROKEN BAR */
- case 0x00A7:
- return((CHAR)(0xA7 & 0xff)); /* SECTION SIGN */
- case 0x00A8:
- return((CHAR)(0xA8 & 0xff)); /* DIAERESIS */
- case 0x00A9:
- return((CHAR)(0xA9 & 0xff)); /* COPYRIGHT SIGN */
- case 0x00D7:
- return((CHAR)(0xAA & 0xff)); /* MULTIPLICATION SIGN */
- case 0x00AB:
- return((CHAR)(0xAB & 0xff)); /* LEFT-POINTING DOUBLE ANGLE QUOTE */
- case 0x00AC:
- return((CHAR)(0xAC & 0xff)); /* NOT SIGN */
- case 0x00AD:
- return((CHAR)(0xAD & 0xff)); /* SOFT HYPHEN */
- case 0x00AE:
- return((CHAR)(0xAE & 0xff)); /* REGISTERED SIGN */
- case 0x00AF:
- return((CHAR)(0xAF & 0xff)); /* MACRON */
- case 0x00B0:
- return((CHAR)(0xB0 & 0xff)); /* DEGREE SIGN */
- case 0x00B1:
- return((CHAR)(0xB1 & 0xff)); /* PLUS-MINUS SIGN */
- case 0x00B2:
- return((CHAR)(0xB2 & 0xff)); /* SUPERSCRIPT TWO */
- case 0x00B3:
- return((CHAR)(0xB3 & 0xff)); /* SUPERSCRIPT THREE */
- case 0x00B4:
- return((CHAR)(0xB4 & 0xff)); /* ACUTE ACCENT */
- case 0x00B5:
- return((CHAR)(0xB5 & 0xff)); /* MICRO SIGN */
- case 0x00B6:
- return((CHAR)(0xB6 & 0xff)); /* PILCROW SIGN */
- case 0x00B7:
- return((CHAR)(0xB7 & 0xff)); /* MIDDLE DOT */
- case 0x00B8:
- return((CHAR)(0xB8 & 0xff)); /* CEDILLA */
- case 0x00B9:
- return((CHAR)(0xB9 & 0xff)); /* SUPERSCRIPT ONE */
- case 0x00F7:
- return((CHAR)(0xBA & 0xff)); /* DIVISION SIGN */
- case 0x00BB:
- return((CHAR)(0xBB & 0xff)); /* RIGHT-POINTING DOUBLE ANGLE QUOTE */
- case 0x00BC:
- return((CHAR)(0xBC & 0xff)); /* VULGAR FRACTION ONE QUARTER */
- case 0x00BD:
- return((CHAR)(0xBD & 0xff)); /* VULGAR FRACTION ONE HALF */
- case 0x00BE:
- return((CHAR)(0xBE & 0xff)); /* VULGAR FRACTION THREE QUARTERS */
- case 0x00BF:
- return((CHAR)(0xBF & 0xff)); /* INVERTED QUESTION MARK */
- case 0x05B0:
- return((CHAR)(0xC0 & 0xff)); /* HEBREW POINT SHEVA */
- case 0x05B1:
- return((CHAR)(0xC1 & 0xff)); /* HEBREW POINT HATAF SEGOL */
- case 0x05B2:
- return((CHAR)(0xC2 & 0xff)); /* HEBREW POINT HATAF PATAH */
- case 0x05B3:
- return((CHAR)(0xC3 & 0xff)); /* HEBREW POINT HATAF QAMATS */
- case 0x05B4:
- return((CHAR)(0xC4 & 0xff)); /* HEBREW POINT HIRIQ */
- case 0x05B5:
- return((CHAR)(0xC5 & 0xff)); /* HEBREW POINT TSERE */
- case 0x05B6:
- return((CHAR)(0xC6 & 0xff)); /* HEBREW POINT SEGOL */
- case 0x05B7:
- return((CHAR)(0xC7 & 0xff)); /* HEBREW POINT PATAH */
- case 0x05B8:
- return((CHAR)(0xC8 & 0xff)); /* HEBREW POINT QAMATS */
- case 0x05B9:
- return((CHAR)(0xC9 & 0xff)); /* HEBREW POINT HOLAM */
- case 0x05BB:
- return((CHAR)(0xCB & 0xff)); /* HEBREW POINT QUBUTS */
- case 0x05BC:
- return((CHAR)(0xCC & 0xff)); /* HEBREW POINT DAGESH OR MAPIQ */
- case 0x05BD:
- return((CHAR)(0xCD & 0xff)); /* HEBREW POINT METEG */
- case 0x05BE:
- return((CHAR)(0xCE & 0xff)); /* HEBREW PUNCTUATION MAQAF */
- case 0x05BF:
- return((CHAR)(0xCF & 0xff)); /* HEBREW POINT RAFE */
- case 0x05C0:
- return((CHAR)(0xD0 & 0xff)); /* HEBREW PUNCTUATION PASEQ */
- case 0x05C1:
- return((CHAR)(0xD1 & 0xff)); /* HEBREW POINT SHIN DOT */
- case 0x05C2:
- return((CHAR)(0xD2 & 0xff)); /* HEBREW POINT SIN DOT */
- case 0x05C3:
- return((CHAR)(0xD3 & 0xff)); /* HEBREW PUNCTUATION SOF PASUQ */
- case 0x05F0:
- return((CHAR)(0xD4 & 0xff)); /* HEBREW LIG. YIDDISH DOUBLE VAV */
- case 0x05F1:
- return((CHAR)(0xD5 & 0xff)); /* HEBREW LIGATURE YIDDISH VAV YOD */
- case 0x05F2:
- return((CHAR)(0xD6 & 0xff)); /* HEBREW LIG. YIDDISH DOUBLE YOD */
- case 0x05F3:
- return((CHAR)(0xD7 & 0xff)); /* HEBREW PUNCTUATION GERESH */
- case 0x05F4:
- return((CHAR)(0xD8 & 0xff)); /* HEBREW PUNCTUATION GERSHAYIM */
- case 0x05D0:
- return((CHAR)(0xE0 & 0xff)); /* HEBREW LETTER ALEF */
- case 0x05D1:
- return((CHAR)(0xE1 & 0xff)); /* HEBREW LETTER BET */
- case 0x05D2:
- return((CHAR)(0xE2 & 0xff)); /* HEBREW LETTER GIMEL */
- case 0x05D3:
- return((CHAR)(0xE3 & 0xff)); /* HEBREW LETTER DALET */
- case 0x05D4:
- return((CHAR)(0xE4 & 0xff)); /* HEBREW LETTER HE */
- case 0x05D5:
- return((CHAR)(0xE5 & 0xff)); /* HEBREW LETTER VAV */
- case 0x05D6:
- return((CHAR)(0xE6 & 0xff)); /* HEBREW LETTER ZAYIN */
- case 0x05D7:
- return((CHAR)(0xE7 & 0xff)); /* HEBREW LETTER HET */
- case 0x05D8:
- return((CHAR)(0xE8 & 0xff)); /* HEBREW LETTER TET */
- case 0x05D9:
- return((CHAR)(0xE9 & 0xff)); /* HEBREW LETTER YOD */
- case 0x05DA:
- return((CHAR)(0xEA & 0xff)); /* HEBREW LETTER FINAL KAF */
- case 0x05DB:
- return((CHAR)(0xEB & 0xff)); /* HEBREW LETTER KAF */
- case 0x05DC:
- return((CHAR)(0xEC & 0xff)); /* HEBREW LETTER LAMED */
- case 0x05DD:
- return((CHAR)(0xED & 0xff)); /* HEBREW LETTER FINAL MEM */
- case 0x05DE:
- return((CHAR)(0xEE & 0xff)); /* HEBREW LETTER MEM */
- case 0x05DF:
- return((CHAR)(0xEF & 0xff)); /* HEBREW LETTER FINAL NUN */
- case 0x05E0:
- return((CHAR)(0xF0 & 0xff)); /* HEBREW LETTER NUN */
- case 0x05E1:
- return((CHAR)(0xF1 & 0xff)); /* HEBREW LETTER SAMEKH */
- case 0x05E2:
- return((CHAR)(0xF2 & 0xff)); /* HEBREW LETTER AYIN */
- case 0x05E3:
- return((CHAR)(0xF3 & 0xff)); /* HEBREW LETTER FINAL PE */
- case 0x05E4:
- return((CHAR)(0xF4 & 0xff)); /* HEBREW LETTER PE */
- case 0x05E5:
- return((CHAR)(0xF5 & 0xff)); /* HEBREW LETTER FINAL TSADI */
- case 0x05E6:
- return((CHAR)(0xF6 & 0xff)); /* HEBREW LETTER TSADI */
- case 0x05E7:
- return((CHAR)(0xF7 & 0xff)); /* HEBREW LETTER QOF */
- case 0x05E8:
- return((CHAR)(0xF8 & 0xff)); /* HEBREW LETTER RESH */
- case 0x05E9:
- return((CHAR)(0xF9 & 0xff)); /* HEBREW LETTER SHIN */
- case 0x05EA:
- return((CHAR)(0xFA & 0xff)); /* HEBREW LETTER TAV */
- case 0x200E:
- return((CHAR)(0xFD & 0xff)); /* LEFT-TO-RIGHT MARK */
- case 0x200F:
- return((CHAR)(0xFE & 0xff)); /* RIGHT-TO-LEFT MARK */
- default: return(0x003f);
- }
-}
-
-int /* Windows Arabic */
-#ifdef CK_ANSIC
-tx_cp1256(USHORT c)
-#else
-tx_cp1256(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80)
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x20AC:
- return((CHAR)(0x80 & 0xff)); /* EURO SIGN */
- case 0x067E:
- return((CHAR)(0x81 & 0xff)); /* ARABIC LETTER PEH */
- case 0x201A:
- return((CHAR)(0x82 & 0xff)); /* SINGLE LOW-9 QUOTATION MARK */
- case 0x0192:
- return((CHAR)(0x83 & 0xff)); /* LATIN SMALL LETTER F WITH HOOK */
- case 0x201E:
- return((CHAR)(0x84 & 0xff)); /* DOUBLE LOW-9 QUOTATION MARK */
- case 0x2026:
- return((CHAR)(0x85 & 0xff)); /* HORIZONTAL ELLIPSIS */
- case 0x2020:
- return((CHAR)(0x86 & 0xff)); /* DAGGER */
- case 0x2021:
- return((CHAR)(0x87 & 0xff)); /* DOUBLE DAGGER */
- case 0x02C6:
- return((CHAR)(0x88 & 0xff)); /* MODIFIER LETTER CIRCUMFLEX ACCENT */
- case 0x2030:
- return((CHAR)(0x89 & 0xff)); /* PER MILLE SIGN */
- case 0x2039:
- return((CHAR)(0x8B & 0xff)); /* SINGLE LEFT-POINTING ANGLE QUOTE */
- case 0x0152:
- return((CHAR)(0x8C & 0xff)); /* LATIN CAPITAL LIGATURE OE */
- case 0x0686:
- return((CHAR)(0x8D & 0xff)); /* ARABIC LETTER TCHEH */
- case 0x0698:
- return((CHAR)(0x8E & 0xff)); /* ARABIC LETTER JEH */
- case 0x06AF:
- return((CHAR)(0x90 & 0xff)); /* ARABIC LETTER GAF */
- case 0x2018:
- return((CHAR)(0x91 & 0xff)); /* LEFT SINGLE QUOTATION MARK */
- case 0x2019:
- return((CHAR)(0x92 & 0xff)); /* RIGHT SINGLE QUOTATION MARK */
- case 0x201C:
- return((CHAR)(0x93 & 0xff)); /* LEFT DOUBLE QUOTATION MARK */
- case 0x201D:
- return((CHAR)(0x94 & 0xff)); /* RIGHT DOUBLE QUOTATION MARK */
- case 0x2022:
- return((CHAR)(0x95 & 0xff)); /* BULLET */
- case 0x2013:
- return((CHAR)(0x96 & 0xff)); /* EN DASH */
- case 0x2014:
- return((CHAR)(0x97 & 0xff)); /* EM DASH */
- case 0x2122:
- return((CHAR)(0x99 & 0xff)); /* TRADE MARK SIGN */
- case 0x203A:
- return((CHAR)(0x9B & 0xff)); /* SINGLE RIGHT-POINTING ANGLE QUOTE */
- case 0x0153:
- return((CHAR)(0x9C & 0xff)); /* LATIN SMALL LIGATURE OE */
- case 0x200C:
- return((CHAR)(0x9D & 0xff)); /* ZERO WIDTH NON-JOINER */
- case 0x200D:
- return((CHAR)(0x9E & 0xff)); /* ZERO WIDTH JOINER */
- case 0x00A0:
- return((CHAR)(0xA0 & 0xff)); /* NO-BREAK SPACE */
- case 0x060C:
- return((CHAR)(0xA1 & 0xff)); /* ARABIC COMMA */
- case 0x00A2:
- return((CHAR)(0xA2 & 0xff)); /* CENT SIGN */
- case 0x00A3:
- return((CHAR)(0xA3 & 0xff)); /* POUND SIGN */
- case 0x00A4:
- return((CHAR)(0xA4 & 0xff)); /* CURRENCY SIGN */
- case 0x00A5:
- return((CHAR)(0xA5 & 0xff)); /* YEN SIGN */
- case 0x00A6:
- return((CHAR)(0xA6 & 0xff)); /* BROKEN BAR */
- case 0x00A7:
- return((CHAR)(0xA7 & 0xff)); /* SECTION SIGN */
- case 0x00A8:
- return((CHAR)(0xA8 & 0xff)); /* DIAERESIS */
- case 0x00A9:
- return((CHAR)(0xA9 & 0xff)); /* COPYRIGHT SIGN */
- case 0x00AB:
- return((CHAR)(0xAB & 0xff)); /* LEFT-POINTING DOUBLE ANGLE QUOTE */
- case 0x00AC:
- return((CHAR)(0xAC & 0xff)); /* NOT SIGN */
- case 0x00AD:
- return((CHAR)(0xAD & 0xff)); /* SOFT HYPHEN */
- case 0x00AE:
- return((CHAR)(0xAE & 0xff)); /* REGISTERED SIGN */
- case 0x00AF:
- return((CHAR)(0xAF & 0xff)); /* MACRON */
- case 0x00B0:
- return((CHAR)(0xB0 & 0xff)); /* DEGREE SIGN */
- case 0x00B1:
- return((CHAR)(0xB1 & 0xff)); /* PLUS-MINUS SIGN */
- case 0x00B2:
- return((CHAR)(0xB2 & 0xff)); /* SUPERSCRIPT TWO */
- case 0x00B3:
- return((CHAR)(0xB3 & 0xff)); /* SUPERSCRIPT THREE */
- case 0x00B4:
- return((CHAR)(0xB4 & 0xff)); /* ACUTE ACCENT */
- case 0x00B5:
- return((CHAR)(0xB5 & 0xff)); /* MICRO SIGN */
- case 0x00B6:
- return((CHAR)(0xB6 & 0xff)); /* PILCROW SIGN */
- case 0x00B7:
- return((CHAR)(0xB7 & 0xff)); /* MIDDLE DOT */
- case 0x00B8:
- return((CHAR)(0xB8 & 0xff)); /* CEDILLA */
- case 0x00B9:
- return((CHAR)(0xB9 & 0xff)); /* SUPERSCRIPT ONE */
- case 0x061B:
- return((CHAR)(0xBA & 0xff)); /* ARABIC SEMICOLON */
- case 0x00BB:
- return((CHAR)(0xBB & 0xff)); /* RIGHT-POINTING DOUBLE ANGLE QUOTE */
- case 0x00BC:
- return((CHAR)(0xBC & 0xff)); /* VULGAR FRACTION ONE QUARTER */
- case 0x00BD:
- return((CHAR)(0xBD & 0xff)); /* VULGAR FRACTION ONE HALF */
- case 0x00BE:
- return((CHAR)(0xBE & 0xff)); /* VULGAR FRACTION THREE QUARTERS */
- case 0x061F:
- return((CHAR)(0xBF & 0xff)); /* ARABIC QUESTION MARK */
- case 0x0621:
- return((CHAR)(0xC1 & 0xff)); /* ARABIC LETTER HAMZA */
- case 0x0622:
- return((CHAR)(0xC2 & 0xff)); /* ARABIC LTR. ALEF WITH MADDA ABOVE */
- case 0x0623:
- return((CHAR)(0xC3 & 0xff)); /* ARABIC LTR. ALEF WITH HAMZA ABOVE */
- case 0x0624:
- return((CHAR)(0xC4 & 0xff)); /* ARABIC LTR. WAW WITH HAMZA ABOVE */
- case 0x0625:
- return((CHAR)(0xC5 & 0xff)); /* ARABIC LTR. ALEF WITH HAMZA BELOW */
- case 0x0626:
- return((CHAR)(0xC6 & 0xff)); /* ARABIC LTR. YEH WITH HAMZA ABOVE */
- case 0x0627:
- return((CHAR)(0xC7 & 0xff)); /* ARABIC LTR. ALEF */
- case 0x0628:
- return((CHAR)(0xC8 & 0xff)); /* ARABIC LTR. BEH */
- case 0x0629:
- return((CHAR)(0xC9 & 0xff)); /* ARABIC LETTER TEH MARBUTA */
- case 0x062A:
- return((CHAR)(0xCA & 0xff)); /* ARABIC LETTER TEH */
- case 0x062B:
- return((CHAR)(0xCB & 0xff)); /* ARABIC LETTER THEH */
- case 0x062C:
- return((CHAR)(0xCC & 0xff)); /* ARABIC LETTER JEEM */
- case 0x062D:
- return((CHAR)(0xCD & 0xff)); /* ARABIC LETTER HAH */
- case 0x062E:
- return((CHAR)(0xCE & 0xff)); /* ARABIC LETTER KHAH */
- case 0x062F:
- return((CHAR)(0xCF & 0xff)); /* ARABIC LETTER DAL */
- case 0x0630:
- return((CHAR)(0xD0 & 0xff)); /* ARABIC LETTER THAL */
- case 0x0631:
- return((CHAR)(0xD1 & 0xff)); /* ARABIC LETTER REH */
- case 0x0632:
- return((CHAR)(0xD2 & 0xff)); /* ARABIC LETTER ZAIN */
- case 0x0633:
- return((CHAR)(0xD3 & 0xff)); /* ARABIC LETTER SEEN */
- case 0x0634:
- return((CHAR)(0xD4 & 0xff)); /* ARABIC LETTER SHEEN */
- case 0x0635:
- return((CHAR)(0xD5 & 0xff)); /* ARABIC LETTER SAD */
- case 0x0636:
- return((CHAR)(0xD6 & 0xff)); /* ARABIC LETTER DAD */
- case 0x00D7:
- return((CHAR)(0xD7 & 0xff)); /* MULTIPLICATION SIGN */
- case 0x0637:
- return((CHAR)(0xD8 & 0xff)); /* ARABIC LETTER TAH */
- case 0x0638:
- return((CHAR)(0xD9 & 0xff)); /* ARABIC LETTER ZAH */
- case 0x0639:
- return((CHAR)(0xDA & 0xff)); /* ARABIC LETTER AIN */
- case 0x063A:
- return((CHAR)(0xDB & 0xff)); /* ARABIC LETTER GHAIN */
- case 0x0640:
- return((CHAR)(0xDC & 0xff)); /* ARABIC TATWEEL */
- case 0x0641:
- return((CHAR)(0xDD & 0xff)); /* ARABIC LETTER FEH */
- case 0x0642:
- return((CHAR)(0xDE & 0xff)); /* ARABIC LETTER QAF */
- case 0x0643:
- return((CHAR)(0xDF & 0xff)); /* ARABIC LETTER KAF */
- case 0x00E0:
- return((CHAR)(0xE0 & 0xff)); /* LATIN SMALL LETTER A WITH GRAVE */
- case 0x0644:
- return((CHAR)(0xE1 & 0xff)); /* ARABIC LETTER LAM */
- case 0x00E2:
- return((CHAR)(0xE2 & 0xff)); /* SMALL LETTER A WITH CIRCUMFLEX */
- case 0x0645:
- return((CHAR)(0xE3 & 0xff)); /* ARABIC LETTER MEEM */
- case 0x0646:
- return((CHAR)(0xE4 & 0xff)); /* ARABIC LETTER NOON */
- case 0x0647:
- return((CHAR)(0xE5 & 0xff)); /* ARABIC LETTER HEH */
- case 0x0648:
- return((CHAR)(0xE6 & 0xff)); /* ARABIC LETTER WAW */
- case 0x00E7:
- return((CHAR)(0xE7 & 0xff)); /* LATIN SMALL LETTER C WITH CEDILLA */
- case 0x00E8:
- return((CHAR)(0xE8 & 0xff)); /* LATIN SMALL LETTER E WITH GRAVE */
- case 0x00E9:
- return((CHAR)(0xE9 & 0xff)); /* LATIN SMALL LETTER E WITH ACUTE */
- case 0x00EA:
- return((CHAR)(0xEA & 0xff)); /* SMALL LETTER E WITH CIRCUMFLEX */
- case 0x00EB:
- return((CHAR)(0xEB & 0xff)); /* SMALL LETTER E WITH DIAERESIS */
- case 0x0649:
- return((CHAR)(0xEC & 0xff)); /* ARABIC LETTER ALEF MAKSURA */
- case 0x064A:
- return((CHAR)(0xED & 0xff)); /* ARABIC LETTER YEH */
- case 0x00EE:
- return((CHAR)(0xEE & 0xff)); /* SMALL LETTER I WITH CIRCUMFLEX */
- case 0x00EF:
- return((CHAR)(0xEF & 0xff)); /* SMALL LETTER I WITH DIAERESIS */
- case 0x064B:
- return((CHAR)(0xF0 & 0xff)); /* ARABIC FATHATAN */
- case 0x064C:
- return((CHAR)(0xF1 & 0xff)); /* ARABIC DAMMATAN */
- case 0x064D:
- return((CHAR)(0xF2 & 0xff)); /* ARABIC KASRATAN */
- case 0x064E:
- return((CHAR)(0xF3 & 0xff)); /* ARABIC FATHA */
- case 0x00F4:
- return((CHAR)(0xF4 & 0xff)); /* SMALL LETTER O WITH CIRCUMFLEX */
- case 0x064F:
- return((CHAR)(0xF5 & 0xff)); /* ARABIC DAMMA */
- case 0x0650:
- return((CHAR)(0xF6 & 0xff)); /* ARABIC KASRA */
- case 0x00F7:
- return((CHAR)(0xF7 & 0xff)); /* DIVISION SIGN */
- case 0x0651:
- return((CHAR)(0xF8 & 0xff)); /* ARABIC SHADDA */
- case 0x00F9:
- return((CHAR)(0xF9 & 0xff)); /* LATIN SMALL LETTER U WITH GRAVE */
- case 0x0652:
- return((CHAR)(0xFA & 0xff)); /* ARABIC SUKUN */
- case 0x00FB:
- return((CHAR)(0xFB & 0xff)); /* SMALL LETTER U WITH CIRCUMFLEX */
- case 0x00FC:
- return((CHAR)(0xFC & 0xff)); /* SMALL LETTER U WITH DIAERESIS */
- case 0x200E:
- return((CHAR)(0xFD & 0xff)); /* LEFT-TO-RIGHT MARK */
- case 0x200F:
- return((CHAR)(0xFE & 0xff)); /* RIGHT-TO-LEFT MARK */
- default: return(0x003f);
- }
-}
-
-int /* Windows Code Page 1257 (Latin-4) */
-#ifdef CK_ANSIC
-tx_cp1257(USHORT c)
-#else
-tx_cp1257(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80)
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x003c: return((CHAR)(0x8b & 0xff));
- case 0x003e: return((CHAR)(0x9b & 0xff));
- case 0x00A0: return((CHAR)(0xa0 & 0xff));
- case 0x00A2: return((CHAR)(0xa2 & 0xff));
- case 0x00A3: return((CHAR)(0xa3 & 0xff));
- case 0x00A4: return((CHAR)(0xa4 & 0xff));
- case 0x00A6: return((CHAR)(0xa6 & 0xff));
- case 0x00A7: return((CHAR)(0xa7 & 0xff));
- case 0x00A9: return((CHAR)(0xa9 & 0xff));
- case 0x00AB: return((CHAR)(0xab & 0xff));
- case 0x00AC: return((CHAR)(0xac & 0xff));
- case 0x00AD: return((CHAR)(0xad & 0xff));
- case 0x00AE: return((CHAR)(0xae & 0xff));
- case 0x00B0: return((CHAR)(0xb0 & 0xff));
- case 0x00B1: return((CHAR)(0xb1 & 0xff));
- case 0x00B2: return((CHAR)(0xb2 & 0xff));
- case 0x00B3: return((CHAR)(0xb3 & 0xff));
- case 0x00B5: return((CHAR)(0xb5 & 0xff));
- case 0x00B6: return((CHAR)(0xb6 & 0xff));
- case 0x00B7: return((CHAR)(0xb7 & 0xff));
- case 0x00B9: return((CHAR)(0xb9 & 0xff));
- case 0x00BB: return((CHAR)(0xbb & 0xff));
- case 0x00BC: return((CHAR)(0xbc & 0xff));
- case 0x00BD: return((CHAR)(0xbd & 0xff));
- case 0x00BE: return((CHAR)(0xbe & 0xff));
- case 0x00C4: return((CHAR)(0xc4 & 0xff));
- case 0x00C5: return((CHAR)(0xc5 & 0xff));
- case 0x00c6: return((CHAR)(0xaf & 0xff));
- case 0x00C9: return((CHAR)(0xc9 & 0xff));
- case 0x00d3: return((CHAR)(0xd3 & 0xff));
- case 0x00D5: return((CHAR)(0xd5 & 0xff));
- case 0x00D6: return((CHAR)(0xd6 & 0xff));
- case 0x00D7: return((CHAR)(0xd7 & 0xff));
- case 0x00d8: return((CHAR)(0xa8 & 0xff));
- case 0x00DC: return((CHAR)(0xdc & 0xff));
- case 0x00DF: return((CHAR)(0xdf & 0xff));
- case 0x00E4: return((CHAR)(0xe4 & 0xff));
- case 0x00E5: return((CHAR)(0xe5 & 0xff));
- case 0x00e6: return((CHAR)(0xbf & 0xff));
- case 0x00E9: return((CHAR)(0xe9 & 0xff));
- case 0x00f3: return((CHAR)(0xf3 & 0xff));
- case 0x00F5: return((CHAR)(0xf5 & 0xff));
- case 0x00F6: return((CHAR)(0xf6 & 0xff));
- case 0x00F7: return((CHAR)(0xf7 & 0xff));
- case 0x00f8: return((CHAR)(0xb8 & 0xff));
- case 0x00fc: return((CHAR)(0xfc & 0xff));
- case 0x0100: return((CHAR)(0xc2 & 0xff));
- case 0x0101: return((CHAR)(0xe2 & 0xff));
- case 0x0104: return((CHAR)(0xc0 & 0xff));
- case 0x0105: return((CHAR)(0xe0 & 0xff));
- case 0x0106: return((CHAR)(0xc3 & 0xff));
- case 0x0107: return((CHAR)(0xe3 & 0xff));
- case 0x010C: return((CHAR)(0xc8 & 0xff));
- case 0x010D: return((CHAR)(0xe8 & 0xff));
- case 0x0112: return((CHAR)(0xc7 & 0xff));
- case 0x0113: return((CHAR)(0xe7 & 0xff));
- case 0x0116: return((CHAR)(0xcb & 0xff));
- case 0x0117: return((CHAR)(0xeb & 0xff));
- case 0x0118: return((CHAR)(0xc6 & 0xff));
- case 0x0119: return((CHAR)(0xe6 & 0xff));
- case 0x0122: return((CHAR)(0xcc & 0xff));
- case 0x0123: return((CHAR)(0xec & 0xff));
- case 0x012a: return((CHAR)(0xce & 0xff));
- case 0x012b: return((CHAR)(0xee & 0xff));
- case 0x012e: return((CHAR)(0xc1 & 0xff));
- case 0x012f: return((CHAR)(0xe1 & 0xff));
- case 0x0136: return((CHAR)(0xcd & 0xff));
- case 0x0137: return((CHAR)(0xed & 0xff));
- case 0x013c: return((CHAR)(0xef & 0xff));
- case 0x0141: return((CHAR)(0xd9 & 0xff));
- case 0x0142: return((CHAR)(0xf9 & 0xff));
- case 0x0143: return((CHAR)(0xd1 & 0xff));
- case 0x0144: return((CHAR)(0xf1 & 0xff));
- case 0x0145: return((CHAR)(0xd2 & 0xff));
- case 0x0146: return((CHAR)(0xf2 & 0xff));
- case 0x014c: return((CHAR)(0xd4 & 0xff));
- case 0x014d: return((CHAR)(0xf4 & 0xff));
- case 0x0156: return((CHAR)(0xaa & 0xff));
- case 0x0157: return((CHAR)(0xba & 0xff));
- case 0x015A: return((CHAR)(0xda & 0xff));
- case 0x015b: return((CHAR)(0xfa & 0xff));
- case 0x0160: return((CHAR)(0xd0 & 0xff));
- case 0x0161: return((CHAR)(0xf0 & 0xff));
- case 0x016a: return((CHAR)(0xdb & 0xff));
- case 0x016b: return((CHAR)(0xfb & 0xff));
- case 0x0172: return((CHAR)(0xd8 & 0xff));
- case 0x0173: return((CHAR)(0xf8 & 0xff));
- case 0x0179: return((CHAR)(0xca & 0xff));
- case 0x017a: return((CHAR)(0xea & 0xff));
- case 0x017b: return((CHAR)(0xdd & 0xff));
- case 0x017c: return((CHAR)(0xfd & 0xff));
- case 0x017d: return((CHAR)(0xde & 0xff));
- case 0x017e: return((CHAR)(0xfe & 0xff));
- case 0x2012: return((CHAR)(0x96 & 0xff));
- case 0x2014: return((CHAR)(0x97 & 0xff));
- case 0x2018: return((CHAR)(0x91 & 0xff));
- case 0x2019: return((CHAR)(0x92 & 0xff));
- case 0x201a: return((CHAR)(0x82 & 0xff));
- case 0x201c: return((CHAR)(0x93 & 0xff));
- case 0x201d: return((CHAR)(0x94 & 0xff));
- case 0x201e: return((CHAR)(0x84 & 0xff));
- case 0x2020: return((CHAR)(0x86 & 0xff));
- case 0x2021: return((CHAR)(0x87 & 0xff));
- case 0x2022: return((CHAR)(0x95 & 0xff));
- case 0x2026: return((CHAR)(0x85 & 0xff));
- case 0x2031: return((CHAR)(0x89 & 0xff));
- case 0x20AC: /* Euro */
- return((CHAR)(0x80 & 0xff));
- case 0x2122: return((CHAR)(0x99 & 0xff));
- default: return(0x003f);
- }
-}
-
-int /* Windows Code Page 1258 (Viet Nam) */
-#ifdef CK_ANSIC
-tx_cp1258(USHORT c)
-#else
-tx_cp1258(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x20AC:
- return((CHAR)(0x80 & 0xff)); /* EURO SIGN */
- case 0x201A:
- return((CHAR)(0x82 & 0xff)); /* SINGLE LOW-9 QUOTATION MARK */
- case 0x0192:
- return((CHAR)(0x83 & 0xff)); /* LATIN SMALL LETTER F WITH HOOK */
- case 0x201E:
- return((CHAR)(0x84 & 0xff)); /* DOUBLE LOW-9 QUOTATION MARK */
- case 0x2026: return((CHAR)(0x85 & 0xff)); /* HORIZONTAL ELLIPSIS */
- case 0x2020: return((CHAR)(0x86 & 0xff)); /* DAGGER */
- case 0x2021: return((CHAR)(0x87 & 0xff)); /* DOUBLE DAGGER */
- case 0x02C6:
- return((CHAR)(0x88 & 0xff)); /* MODIFIER LETTER CIRCUMFLEX ACCENT */
- case 0x2030: return((CHAR)(0x89 & 0xff)); /* PER MILLE SIGN */
- case 0x2039:
- return((CHAR)(0x8B & 0xff)); /* SINGLE LEFT ANGLE QUOTATION MARK */
- case 0x0152: return((CHAR)(0x8C & 0xff)); /* LATIN CAPITAL LIGATURE OE */
- case 0x2018:
- return((CHAR)(0x91 & 0xff)); /* LEFT SINGLE QUOTATION MARK */
- case 0x2019:
- return((CHAR)(0x92 & 0xff)); /* RIGHT SINGLE QUOTATION MARK */
- case 0x201C:
- return((CHAR)(0x93 & 0xff)); /* LEFT DOUBLE QUOTATION MARK */
- case 0x201D:
- return((CHAR)(0x94 & 0xff)); /* RIGHT DOUBLE QUOTATION MARK */
- case 0x2022:
- return((CHAR)(0x95 & 0xff)); /* BULLET */
- case 0x2013:
- return((CHAR)(0x96 & 0xff)); /* EN DASH */
- case 0x2014:
- return((CHAR)(0x97 & 0xff)); /* EM DASH */
- case 0x02DC:
- return((CHAR)(0x98 & 0xff)); /* SMALL TILDE */
- case 0x2122:
- return((CHAR)(0x99 & 0xff)); /* TRADE MARK SIGN */
- case 0x203A:
- /* SINGLE RIGHT-POINTING ANGLE QUOTATION MAR K*/
- return((CHAR)(0x9B & 0xff));
- case 0x0153:
- return((CHAR)(0x9C & 0xff)); /* LATIN SMALL LIGATURE OE */
- case 0x0178:
- /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
- return((CHAR)(0x9F & 0xff));
- case 0x00A0:
- return((CHAR)(0xA0 & 0xff)); /* NO-BREAK SPACE */
- case 0x00A1:
- return((CHAR)(0xA1 & 0xff)); /* INVERTED EXCLAMATION MARK */
- case 0x00A2:
- return((CHAR)(0xA2 & 0xff)); /* CENT SIGN */
- case 0x00A3:
- return((CHAR)(0xA3 & 0xff)); /* POUND SIGN */
- case 0x00A4:
- return((CHAR)(0xA4 & 0xff)); /* CURRENCY SIGN */
- case 0x00A5:
- return((CHAR)(0xA5 & 0xff)); /* YEN SIGN */
- case 0x00A6:
- return((CHAR)(0xA6 & 0xff)); /* BROKEN BAR */
- case 0x00A7:
- return((CHAR)(0xA7 & 0xff)); /* SECTION SIGN */
- case 0x00A8:
- return((CHAR)(0xA8 & 0xff)); /* DIAERESIS */
- case 0x00A9:
- return((CHAR)(0xA9 & 0xff)); /* COPYRIGHT SIGN */
- case 0x00AA:
- return((CHAR)(0xAA & 0xff)); /* FEMININE ORDINAL INDICATOR */
- case 0x00AB:
- /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
- return((CHAR)(0xAB & 0xff));
- case 0x00AC:
- return((CHAR)(0xAC & 0xff)); /* NOT SIGN */
- case 0x00AD:
- return((CHAR)(0xAD & 0xff)); /* SOFT HYPHEN */
- case 0x00AE:
- return((CHAR)(0xAE & 0xff)); /* REGISTERED SIGN */
- case 0x00AF:
- return((CHAR)(0xAF & 0xff)); /* MACRON */
- case 0x00B0:
- return((CHAR)(0xB0 & 0xff)); /* DEGREE SIGN */
- case 0x00B1:
- return((CHAR)(0xB1 & 0xff)); /* PLUS-MINUS SIGN */
- case 0x00B2:
- return((CHAR)(0xB2 & 0xff)); /* SUPERSCRIPT TWO */
- case 0x00B3:
- return((CHAR)(0xB3 & 0xff)); /* SUPERSCRIPT THREE */
- case 0x00B4:
- return((CHAR)(0xB4 & 0xff)); /* ACUTE ACCENT */
- case 0x00B5:
- return((CHAR)(0xB5 & 0xff)); /* MICRO SIGN */
- case 0x00B6:
- return((CHAR)(0xB6 & 0xff)); /* PILCROW SIGN */
- case 0x00B7:
- return((CHAR)(0xB7 & 0xff)); /* MIDDLE DOT */
- case 0x00B8:
- return((CHAR)(0xB8 & 0xff)); /* CEDILLA */
- case 0x00B9:
- return((CHAR)(0xB9 & 0xff)); /* SUPERSCRIPT ONE */
- case 0x00BA:
- return((CHAR)(0xBA & 0xff)); /* MASCULINE ORDINAL INDICATOR */
- case 0x00BB:
- /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MAR K*/
- return((CHAR)(0xBB & 0xff));
- case 0x00BC:
- return((CHAR)(0xBC & 0xff)); /* VULGAR FRACTION ONE QUARTER */
- case 0x00BD:
- return((CHAR)(0xBD & 0xff)); /* VULGAR FRACTION ONE HALF */
- case 0x00BE:
- return((CHAR)(0xBE & 0xff)); /* VULGAR FRACTION THREE QUARTERS */
- case 0x00BF:
- return((CHAR)(0xBF & 0xff)); /* INVERTED QUESTION MARK */
- case 0x00C0:
- return((CHAR)(0xC0 & 0xff)); /* LATIN CAPITAL LETTER A WITH GRAVE */
- case 0x00C1:
- return((CHAR)(0xC1 & 0xff)); /* LATIN CAPITAL LETTER A WITH ACUTE */
- case 0x00C2:
- return((CHAR)(0xC2 & 0xff)); /* A CIRCUMFLEX */
- case 0x0102:
- return((CHAR)(0xC3 & 0xff)); /* LATIN CAPITAL LETTER A WITH BREVE */
- case 0x00C4:
- return((CHAR)(0xC4 & 0xff)); /* A DIAERESIS */
- case 0x00C5:
- return((CHAR)(0xC5 & 0xff)); /* A RING */
- case 0x00C6:
- return((CHAR)(0xC6 & 0xff)); /* LATIN CAPITAL LETTER AE */
- case 0x00C7:
- return((CHAR)(0xC7 & 0xff)); /* C CEDILLA */
- case 0x00C8:
- return((CHAR)(0xC8 & 0xff)); /* E GRAVE */
- case 0x00C9:
- return((CHAR)(0xC9 & 0xff)); /* LATIN CAPITAL LETTER E WITH ACUTE */
- case 0x00CA:
- return((CHAR)(0xCA & 0xff)); /* E WITH CIRCUMFLEX */
- case 0x00CB:
- return((CHAR)(0xCB & 0xff)); /* E WITH DIAERESIS */
- case 0x0300:
- return((CHAR)(0xCC & 0xff)); /* COMBINING GRAVE ACCENT */
- case 0x00CD:
- return((CHAR)(0xCD & 0xff)); /* I WITH ACUTE */
- case 0x00CE:
- return((CHAR)(0xCE & 0xff)); /* I WITH CIRCUMFLEX */
- case 0x00CF:
- return((CHAR)(0xCF & 0xff)); /* I WITH DIAERESIS */
- case 0x0110:
- return((CHAR)(0xD0 & 0xff)); /* D WITH STROKE */
- case 0x00D1:
- return((CHAR)(0xD1 & 0xff)); /* LATIN CAPITAL LETTER N WITH TILDE */
- case 0x0309:
- return((CHAR)(0xD2 & 0xff)); /* COMBINING HOOK ABOVE */
- case 0x00D3:
- return((CHAR)(0xD3 & 0xff)); /* LATIN CAPITAL LETTER O WITH ACUTE */
- case 0x00D4:
- return((CHAR)(0xD4 & 0xff)); /* O WITH CIRCUMFLEX */
- case 0x01A0:
- return((CHAR)(0xD5 & 0xff)); /* LATIN CAPITAL LETTER O WITH HORN */
- case 0x00D6:
- return((CHAR)(0xD6 & 0xff)); /* O WITH DIAERESIS */
- case 0x00D7:
- return((CHAR)(0xD7 & 0xff)); /* MULTIPLICATION SIGN */
- case 0x00D8:
- return((CHAR)(0xD8 & 0xff)); /* O WITH STROKE */
- case 0x00D9:
- return((CHAR)(0xD9 & 0xff)); /* LATIN CAPITAL LETTER U WITH GRAVE */
- case 0x00DA:
- return((CHAR)(0xDA & 0xff)); /* LATIN CAPITAL LETTER U WITH ACUTE */
- case 0x00DB:
- return((CHAR)(0xDB & 0xff)); /* U WITH CIRCUMFLEX */
- case 0x00DC:
- return((CHAR)(0xDC & 0xff)); /* U WITH DIAERESIS */
- case 0x01AF:
- return((CHAR)(0xDD & 0xff)); /* LATIN CAPITAL LETTER U WITH HORN */
- case 0x0303:
- return((CHAR)(0xDE & 0xff)); /* COMBINING TILDE */
- case 0x00DF:
- return((CHAR)(0xDF & 0xff)); /* LATIN SMALL LETTER SHARP S */
- case 0x00E0:
- return((CHAR)(0xE0 & 0xff)); /* LATIN SMALL LETTER A WITH GRAVE */
- case 0x00E1:
- return((CHAR)(0xE1 & 0xff)); /* LATIN SMALL LETTER A WITH ACUTE */
- case 0x00E2:
- return((CHAR)(0xE2 & 0xff)); /* SMALL A WITH CIRCUMFLEX */
- case 0x0103:
- return((CHAR)(0xE3 & 0xff)); /* LATIN SMALL LETTER A WITH BREVE */
- case 0x00E4:
- return((CHAR)(0xE4 & 0xff)); /* SMALL A WITH DIAERESIS */
- case 0x00E5:
- return((CHAR)(0xE5 & 0xff)); /* SMALL A WITH RING ABOVE */
- case 0x00E6:
- return((CHAR)(0xE6 & 0xff)); /* LATIN SMALL LETTER AE */
- case 0x00E7:
- return((CHAR)(0xE7 & 0xff)); /* LATIN SMALL LETTER C WITH CEDILLA */
- case 0x00E8:
- return((CHAR)(0xE8 & 0xff)); /* LATIN SMALL LETTER E WITH GRAVE */
- case 0x00E9:
- return((CHAR)(0xE9 & 0xff)); /* LATIN SMALL LETTER E WITH ACUTE */
- case 0x00EA:
- return((CHAR)(0xEA & 0xff)); /* SMALL E WITH CIRCUMFLEX */
- case 0x00EB:
- return((CHAR)(0xEB & 0xff)); /* SMALL E WITH DIAERESIS */
- case 0x0301:
- return((CHAR)(0xEC & 0xff)); /* COMBINING ACUTE ACCENT */
- case 0x00ED:
- return((CHAR)(0xED & 0xff)); /* LATIN SMALL LETTER I WITH ACUTE */
- case 0x00EE:
- return((CHAR)(0xEE & 0xff)); /* SMALL I WITH CIRCUMFLEX */
- case 0x00EF:
- return((CHAR)(0xEF & 0xff)); /* SMALL I WITH DIAERESIS */
- case 0x0111:
- return((CHAR)(0xF0 & 0xff)); /* LATIN SMALL LETTER D WITH STROKE */
- case 0x00F1:
- return((CHAR)(0xF1 & 0xff)); /* LATIN SMALL LETTER N WITH TILDE */
- case 0x0323:
- return((CHAR)(0xF2 & 0xff)); /* COMBINING DOT BELOW */
- case 0x00F3:
- return((CHAR)(0xF3 & 0xff)); /* LATIN SMALL LETTER O WITH ACUTE */
- case 0x00F4:
- return((CHAR)(0xF4 & 0xff)); /* SMALL O WITH CIRCUMFLEX */
- case 0x01A1:
- return((CHAR)(0xF5 & 0xff)); /* LATIN SMALL LETTER O WITH HORN */
- case 0x00F6:
- return((CHAR)(0xF6 & 0xff)); /* SMALL O WITH DIAERESIS */
- case 0x00F7:
- return((CHAR)(0xF7 & 0xff)); /* DIVISION SIGN */
- case 0x00F8:
- return((CHAR)(0xF8 & 0xff)); /* LATIN SMALL LETTER O WITH STROKE */
- case 0x00F9:
- return((CHAR)(0xF9 & 0xff)); /* LATIN SMALL LETTER U WITH GRAVE */
- case 0x00FA:
- return((CHAR)(0xFA & 0xff)); /* LATIN SMALL LETTER U WITH ACUTE */
- case 0x00FB:
- return((CHAR)(0xFB & 0xff)); /* SMALL U WITH CIRCUMFLEX */
- case 0x00FC:
- return((CHAR)(0xFC & 0xff)); /* SMALL U WITH DIAERESIS */
- case 0x01B0:
- return((CHAR)(0xFD & 0xff)); /* LATIN SMALL LETTER U WITH HORN */
- case 0x20AB:
- return((CHAR)(0xFE & 0xff)); /* DONG SIGN */
- case 0x00FF:
- return((CHAR)(0xFF & 0xff)); /* SMALL Y WITH DIAERESIS */
- default: return(0x003f);
- }
-}
-
-int /* Code Page 037 - EBCDIC (U.S.) */
-#ifdef CK_ANSIC
-tx_cp37(USHORT c)
-#else
-tx_cp37(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- switch (c) {
- case 0x0000:
- return((CHAR)(0x00 & 0xff)); /* NULL */
- case 0x0001:
- return((CHAR)(0x01 & 0xff)); /* START OF HEADING */
- case 0x0002:
- return((CHAR)(0x02 & 0xff)); /* START OF TEXT */
- case 0x0003:
- return((CHAR)(0x03 & 0xff)); /* END OF TEXT */
- case 0x009C:
- return((CHAR)(0x04 & 0xff)); /* CONTROL */
- case 0x0009:
- return((CHAR)(0x05 & 0xff)); /* HORIZONTAL TABULATION */
- case 0x0086:
- return((CHAR)(0x06 & 0xff)); /* CONTROL */
- case 0x007F:
- return((CHAR)(0x07 & 0xff)); /* DELETE */
- case 0x0097:
- return((CHAR)(0x08 & 0xff)); /* CONTROL */
- case 0x008D:
- return((CHAR)(0x09 & 0xff)); /* CONTROL */
- case 0x008E:
- return((CHAR)(0x0A & 0xff)); /* CONTROL */
- case 0x000B:
- return((CHAR)(0x0B & 0xff)); /* VERTICAL TABULATION */
- case 0x000C:
- return((CHAR)(0x0C & 0xff)); /* FORM FEED */
- case 0x000D:
- return((CHAR)(0x0D & 0xff)); /* CARRIAGE RETURN */
- case 0x000E:
- return((CHAR)(0x0E & 0xff)); /* SHIFT OUT */
- case 0x000F:
- return((CHAR)(0x0F & 0xff)); /* SHIFT IN */
- case 0x0010:
- return((CHAR)(0x10 & 0xff)); /* DATA LINK ESCAPE */
- case 0x0011:
- return((CHAR)(0x11 & 0xff)); /* DEVICE CONTROL ONE */
- case 0x0012:
- return((CHAR)(0x12 & 0xff)); /* DEVICE CONTROL TWO */
- case 0x0013:
- return((CHAR)(0x13 & 0xff)); /* DEVICE CONTROL THREE */
- case 0x009D:
- return((CHAR)(0x14 & 0xff)); /* CONTROL */
- case 0x0085:
- return((CHAR)(0x15 & 0xff)); /* CONTROL */
- case 0x0008:
- return((CHAR)(0x16 & 0xff)); /* BACKSPACE */
- case 0x0087:
- return((CHAR)(0x17 & 0xff)); /* CONTROL */
- case 0x0018:
- return((CHAR)(0x18 & 0xff)); /* CANCEL */
- case 0x0019:
- return((CHAR)(0x19 & 0xff)); /* END OF MEDIUM */
- case 0x0092:
- return((CHAR)(0x1A & 0xff)); /* CONTROL */
- case 0x008F:
- return((CHAR)(0x1B & 0xff)); /* CONTROL */
- case 0x001C:
- return((CHAR)(0x1C & 0xff)); /* FILE SEPARATOR */
- case 0x001D:
- return((CHAR)(0x1D & 0xff)); /* GROUP SEPARATOR */
- case 0x001E:
- return((CHAR)(0x1E & 0xff)); /* RECORD SEPARATOR */
- case 0x001F:
- return((CHAR)(0x1F & 0xff)); /* UNIT SEPARATOR */
- case 0x0080:
- return((CHAR)(0x20 & 0xff)); /* CONTROL */
- case 0x0081:
- return((CHAR)(0x21 & 0xff)); /* CONTROL */
- case 0x0082:
- return((CHAR)(0x22 & 0xff)); /* CONTROL */
- case 0x0083:
- return((CHAR)(0x23 & 0xff)); /* CONTROL */
- case 0x0084:
- return((CHAR)(0x24 & 0xff)); /* CONTROL */
- case 0x000A:
- return((CHAR)(0x25 & 0xff)); /* LINE FEED */
- case 0x0017:
- return((CHAR)(0x26 & 0xff)); /* END OF TRANSMISSION BLOCK */
- case 0x001B:
- return((CHAR)(0x27 & 0xff)); /* ESCAPE */
- case 0x0088:
- return((CHAR)(0x28 & 0xff)); /* CONTROL */
- case 0x0089:
- return((CHAR)(0x29 & 0xff)); /* CONTROL */
- case 0x008A:
- return((CHAR)(0x2A & 0xff)); /* CONTROL */
- case 0x008B:
- return((CHAR)(0x2B & 0xff)); /* CONTROL */
- case 0x008C:
- return((CHAR)(0x2C & 0xff)); /* CONTROL */
- case 0x0005:
- return((CHAR)(0x2D & 0xff)); /* ENQUIRY */
- case 0x0006:
- return((CHAR)(0x2E & 0xff)); /* ACKNOWLEDGE */
- case 0x0007:
- return((CHAR)(0x2F & 0xff)); /* BELL */
- case 0x0090:
- return((CHAR)(0x30 & 0xff)); /* CONTROL */
- case 0x0091:
- return((CHAR)(0x31 & 0xff)); /* CONTROL */
- case 0x0016:
- return((CHAR)(0x32 & 0xff)); /* SYNCHRONOUS IDLE */
- case 0x0093:
- return((CHAR)(0x33 & 0xff)); /* CONTROL */
- case 0x0094:
- return((CHAR)(0x34 & 0xff)); /* CONTROL */
- case 0x0095:
- return((CHAR)(0x35 & 0xff)); /* CONTROL */
- case 0x0096:
- return((CHAR)(0x36 & 0xff)); /* CONTROL */
- case 0x0004:
- return((CHAR)(0x37 & 0xff)); /* END OF TRANSMISSION */
- case 0x0098:
- return((CHAR)(0x38 & 0xff)); /* CONTROL */
- case 0x0099:
- return((CHAR)(0x39 & 0xff)); /* CONTROL */
- case 0x009A:
- return((CHAR)(0x3A & 0xff)); /* CONTROL */
- case 0x009B:
- return((CHAR)(0x3B & 0xff)); /* CONTROL */
- case 0x0014:
- return((CHAR)(0x3C & 0xff)); /* DEVICE CONTROL FOUR */
- case 0x0015:
- return((CHAR)(0x3D & 0xff)); /* NEGATIVE ACKNOWLEDGE */
- case 0x009E:
- return((CHAR)(0x3E & 0xff)); /* CONTROL */
- case 0x001A:
- return((CHAR)(0x3F & 0xff)); /* SUBSTITUTE */
- case 0x0020:
- return((CHAR)(0x40 & 0xff)); /* SPACE */
- case 0x00A0:
- return((CHAR)(0x41 & 0xff)); /* NO-BREAK SPACE */
- case 0x00E2:
- return((CHAR)(0x42 & 0xff)); /* SMALL LETTER A WITH CIRCUMFLEX */
- case 0x00E4:
- return((CHAR)(0x43 & 0xff)); /* SMALL LETTER A WITH DIAERESIS */
- case 0x00E0:
- return((CHAR)(0x44 & 0xff)); /* LATIN SMALL LETTER A WITH GRAVE */
- case 0x00E1:
- return((CHAR)(0x45 & 0xff)); /* LATIN SMALL LETTER A WITH ACUTE */
- case 0x00E3:
- return((CHAR)(0x46 & 0xff)); /* LATIN SMALL LETTER A WITH TILDE */
- case 0x00E5:
- return((CHAR)(0x47 & 0xff)); /* SMALL LETTER A WITH RING ABOVE */
- case 0x00E7:
- return((CHAR)(0x48 & 0xff)); /* LATIN SMALL LETTER C WITH CEDILLA */
- case 0x00F1:
- return((CHAR)(0x49 & 0xff)); /* LATIN SMALL LETTER N WITH TILDE */
- case 0x00A2:
- return((CHAR)(0x4A & 0xff)); /* CENT SIGN */
- case 0x002E:
- return((CHAR)(0x4B & 0xff)); /* FULL STOP */
- case 0x003C:
- return((CHAR)(0x4C & 0xff)); /* LESS-THAN SIGN */
- case 0x0028:
- return((CHAR)(0x4D & 0xff)); /* LEFT PARENTHESIS */
- case 0x002B:
- return((CHAR)(0x4E & 0xff)); /* PLUS SIGN */
- case 0x007C:
- return((CHAR)(0x4F & 0xff)); /* VERTICAL LINE */
- case 0x0026:
- return((CHAR)(0x50 & 0xff)); /* AMPERSAND */
- case 0x00E9:
- return((CHAR)(0x51 & 0xff)); /* SMALL LETTER E WITH ACUTE */
- case 0x00EA:
- return((CHAR)(0x52 & 0xff)); /* SMALL LETTER E WITH CIRCUMFLEX */
- case 0x00EB:
- return((CHAR)(0x53 & 0xff)); /* SMALL LETTER E WITH DIAERESIS */
- case 0x00E8:
- return((CHAR)(0x54 & 0xff)); /* LATIN SMALL LETTER E WITH GRAVE */
- case 0x00ED:
- return((CHAR)(0x55 & 0xff)); /* LATIN SMALL LETTER I WITH ACUTE */
- case 0x00EE:
- return((CHAR)(0x56 & 0xff)); /* SMALL LETTER I WITH CIRCUMFLEX */
- case 0x00EF:
- return((CHAR)(0x57 & 0xff)); /* SMALL LETTER I WITH DIAERESIS */
- case 0x00EC:
- return((CHAR)(0x58 & 0xff)); /* LATIN SMALL LETTER I WITH GRAVE */
- case 0x00DF:
- return((CHAR)(0x59 & 0xff)); /* SMALL LETTER SHARP S (GERMAN) */
- case 0x0021:
- return((CHAR)(0x5A & 0xff)); /* EXCLAMATION MARK */
- case 0x0024:
- return((CHAR)(0x5B & 0xff)); /* DOLLAR SIGN */
- case 0x002A:
- return((CHAR)(0x5C & 0xff)); /* ASTERISK */
- case 0x0029:
- return((CHAR)(0x5D & 0xff)); /* RIGHT PARENTHESIS */
- case 0x003B:
- return((CHAR)(0x5E & 0xff)); /* SEMICOLON */
- case 0x00AC:
- return((CHAR)(0x5F & 0xff)); /* NOT SIGN */
- case 0x002D:
- return((CHAR)(0x60 & 0xff)); /* HYPHEN-MINUS */
- case 0x002F:
- return((CHAR)(0x61 & 0xff)); /* SOLIDUS */
- case 0x00C2:
- return((CHAR)(0x62 & 0xff)); /* CAPITAL LETTER A WITH CIRCUMFLEX */
- case 0x00C4:
- return((CHAR)(0x63 & 0xff)); /* CAPITAL LETTER A WITH DIAERESIS */
- case 0x00C0:
- return((CHAR)(0x64 & 0xff)); /* LATIN CAPITAL LETTER A WITH GRAVE */
- case 0x00C1:
- return((CHAR)(0x65 & 0xff)); /* LATIN CAPITAL LETTER A WITH ACUTE */
- case 0x00C3:
- return((CHAR)(0x66 & 0xff)); /* LATIN CAPITAL LETTER A WITH TILDE */
- case 0x00C5:
- return((CHAR)(0x67 & 0xff)); /* CAPITAL LETTER A WITH RING ABOVE */
- case 0x00C7:
- return((CHAR)(0x68 & 0xff)); /* CAPITAL LETTER C WITH CEDILLA */
- case 0x00D1:
- return((CHAR)(0x69 & 0xff)); /* LATIN CAPITAL LETTER N WITH TILDE */
- case 0x00A6:
- return((CHAR)(0x6A & 0xff)); /* BROKEN BAR */
- case 0x002C:
- return((CHAR)(0x6B & 0xff)); /* COMMA */
- case 0x0025:
- return((CHAR)(0x6C & 0xff)); /* PERCENT SIGN */
- case 0x005F:
- return((CHAR)(0x6D & 0xff)); /* LOW LINE */
- case 0x003E:
- return((CHAR)(0x6E & 0xff)); /* GREATER-THAN SIGN */
- case 0x003F:
- return((CHAR)(0x6F & 0xff)); /* QUESTION MARK */
- case 0x00F8:
- return((CHAR)(0x70 & 0xff)); /* LATIN SMALL LETTER O WITH STROKE */
- case 0x00C9:
- return((CHAR)(0x71 & 0xff)); /* LATIN CAPITAL LETTER E WITH ACUTE */
- case 0x00CA:
- /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
- return((CHAR)(0x72 & 0xff));
- case 0x00CB:
- /* LATIN CAPITAL LETTER E WITH DIAERESIS */
- return((CHAR)(0x73 & 0xff));
- case 0x00C8:
- return((CHAR)(0x74 & 0xff)); /* LATIN CAPITAL LETTER E WITH GRAVE */
- case 0x00CD:
- return((CHAR)(0x75 & 0xff)); /* LATIN CAPITAL LETTER I WITH ACUTE */
- case 0x00CE:
- /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
- return((CHAR)(0x76 & 0xff));
- case 0x00CF:
- /* LATIN CAPITAL LETTER I WITH DIAERESIS */
- return((CHAR)(0x77 & 0xff));
- case 0x00CC:
- return((CHAR)(0x78 & 0xff)); /* LATIN CAPITAL LETTER I WITH GRAVE */
- case 0x0060:
- return((CHAR)(0x79 & 0xff)); /* GRAVE ACCENT */
- case 0x003A:
- return((CHAR)(0x7A & 0xff)); /* COLON */
- case 0x0023:
- return((CHAR)(0x7B & 0xff)); /* NUMBER SIGN */
- case 0x0040:
- return((CHAR)(0x7C & 0xff)); /* COMMERCIAL AT */
- case 0x0027:
- return((CHAR)(0x7D & 0xff)); /* APOSTROPHE */
- case 0x003D:
- return((CHAR)(0x7E & 0xff)); /* EQUALS SIGN */
- case 0x0022:
- return((CHAR)(0x7F & 0xff)); /* QUOTATION MARK */
- case 0x00D8:
- /* LATIN CAPITAL LETTER O WITH STROKE */
- return((CHAR)(0x80 & 0xff));
- case 0x0061:
- return((CHAR)(0x81 & 0xff)); /* LATIN SMALL LETTER A */
- case 0x0062:
- return((CHAR)(0x82 & 0xff)); /* LATIN SMALL LETTER B */
- case 0x0063:
- return((CHAR)(0x83 & 0xff)); /* LATIN SMALL LETTER C */
- case 0x0064:
- return((CHAR)(0x84 & 0xff)); /* LATIN SMALL LETTER D */
- case 0x0065:
- return((CHAR)(0x85 & 0xff)); /* LATIN SMALL LETTER E */
- case 0x0066:
- return((CHAR)(0x86 & 0xff)); /* LATIN SMALL LETTER F */
- case 0x0067:
- return((CHAR)(0x87 & 0xff)); /* LATIN SMALL LETTER G */
- case 0x0068:
- return((CHAR)(0x88 & 0xff)); /* LATIN SMALL LETTER H */
- case 0x0069:
- return((CHAR)(0x89 & 0xff)); /* LATIN SMALL LETTER I */
- case 0x00AB:
- /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
- return((CHAR)(0x8A & 0xff));
- case 0x00BB:
- /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MAR K*/
- return((CHAR)(0x8B & 0xff));
- case 0x00F0:
- /* LATIN SMALL LETTER ETH (ICELANDIC) */
- return((CHAR)(0x8C & 0xff));
- case 0x00FD:
- return((CHAR)(0x8D & 0xff)); /* LATIN SMALL LETTER Y WITH ACUTE */
- case 0x00FE:
- /* LATIN SMALL LETTER THORN (ICELANDIC) */
- return((CHAR)(0x8E & 0xff));
- case 0x00B1:
- return((CHAR)(0x8F & 0xff)); /* PLUS-MINUS SIGN */
- case 0x00B0:
- return((CHAR)(0x90 & 0xff)); /* DEGREE SIGN */
- case 0x006A:
- return((CHAR)(0x91 & 0xff)); /* LATIN SMALL LETTER J */
- case 0x006B:
- return((CHAR)(0x92 & 0xff)); /* LATIN SMALL LETTER K */
- case 0x006C:
- return((CHAR)(0x93 & 0xff)); /* LATIN SMALL LETTER L */
- case 0x006D:
- return((CHAR)(0x94 & 0xff)); /* LATIN SMALL LETTER M */
- case 0x006E:
- return((CHAR)(0x95 & 0xff)); /* LATIN SMALL LETTER N */
- case 0x006F:
- return((CHAR)(0x96 & 0xff)); /* LATIN SMALL LETTER O */
- case 0x0070:
- return((CHAR)(0x97 & 0xff)); /* LATIN SMALL LETTER P */
- case 0x0071:
- return((CHAR)(0x98 & 0xff)); /* LATIN SMALL LETTER Q */
- case 0x0072:
- return((CHAR)(0x99 & 0xff)); /* LATIN SMALL LETTER R */
- case 0x00AA:
- return((CHAR)(0x9A & 0xff)); /* FEMININE ORDINAL INDICATOR */
- case 0x00BA:
- return((CHAR)(0x9B & 0xff)); /* MASCULINE ORDINAL INDICATOR */
- case 0x00E6:
- return((CHAR)(0x9C & 0xff)); /* LATIN SMALL LIGATURE AE */
- case 0x00B8:
- return((CHAR)(0x9D & 0xff)); /* CEDILLA */
- case 0x00C6:
- return((CHAR)(0x9E & 0xff)); /* LATIN CAPITAL LIGATURE AE */
- case 0x00A4:
- return((CHAR)(0x9F & 0xff)); /* CURRENCY SIGN */
- case 0x00B5:
- return((CHAR)(0xA0 & 0xff)); /* MICRO SIGN */
- case 0x007E:
- return((CHAR)(0xA1 & 0xff)); /* TILDE */
- case 0x0073:
- return((CHAR)(0xA2 & 0xff)); /* LATIN SMALL LETTER S */
- case 0x0074:
- return((CHAR)(0xA3 & 0xff)); /* LATIN SMALL LETTER T */
- case 0x0075:
- return((CHAR)(0xA4 & 0xff)); /* LATIN SMALL LETTER U */
- case 0x0076:
- return((CHAR)(0xA5 & 0xff)); /* LATIN SMALL LETTER V */
- case 0x0077:
- return((CHAR)(0xA6 & 0xff)); /* LATIN SMALL LETTER W */
- case 0x0078:
- return((CHAR)(0xA7 & 0xff)); /* LATIN SMALL LETTER X */
- case 0x0079:
- return((CHAR)(0xA8 & 0xff)); /* LATIN SMALL LETTER Y */
- case 0x007A:
- return((CHAR)(0xA9 & 0xff)); /* LATIN SMALL LETTER Z */
- case 0x00A1:
- return((CHAR)(0xAA & 0xff)); /* INVERTED EXCLAMATION MARK */
- case 0x00BF:
- return((CHAR)(0xAB & 0xff)); /* INVERTED QUESTION MARK */
- case 0x00D0:
- /* LATIN CAPITAL LETTER ETH (ICELANDIC) */
- return((CHAR)(0xAC & 0xff));
- case 0x00DD:
- return((CHAR)(0xAD & 0xff)); /* LATIN CAPITAL LETTER Y WITH ACUTE */
- case 0x00DE:
- /* LATIN CAPITAL LETTER THORN (ICELANDIC) */
- return((CHAR)(0xAE & 0xff));
- case 0x00AE:
- return((CHAR)(0xAF & 0xff)); /* REGISTERED SIGN */
- case 0x005E:
- return((CHAR)(0xB0 & 0xff)); /* CIRCUMFLEX ACCENT */
- case 0x00A3:
- return((CHAR)(0xB1 & 0xff)); /* POUND SIGN */
- case 0x00A5:
- return((CHAR)(0xB2 & 0xff)); /* YEN SIGN */
- case 0x00B7:
- return((CHAR)(0xB3 & 0xff)); /* MIDDLE DOT */
- case 0x00A9:
- return((CHAR)(0xB4 & 0xff)); /* COPYRIGHT SIGN */
- case 0x00A7:
- return((CHAR)(0xB5 & 0xff)); /* SECTION SIGN */
- case 0x00B6:
- return((CHAR)(0xB6 & 0xff)); /* PILCROW SIGN */
- case 0x00BC:
- return((CHAR)(0xB7 & 0xff)); /* VULGAR FRACTION ONE QUARTER */
- case 0x00BD:
- return((CHAR)(0xB8 & 0xff)); /* VULGAR FRACTION ONE HALF */
- case 0x00BE:
- return((CHAR)(0xB9 & 0xff)); /* VULGAR FRACTION THREE QUARTERS */
- case 0x005B:
- return((CHAR)(0xBA & 0xff)); /* LEFT SQUARE BRACKET */
- case 0x005D:
- return((CHAR)(0xBB & 0xff)); /* RIGHT SQUARE BRACKET */
- case 0x00AF:
- return((CHAR)(0xBC & 0xff)); /* MACRON */
- case 0x00A8:
- return((CHAR)(0xBD & 0xff)); /* DIAERESIS */
- case 0x00B4:
- return((CHAR)(0xBE & 0xff)); /* ACUTE ACCENT */
- case 0x00D7:
- return((CHAR)(0xBF & 0xff)); /* MULTIPLICATION SIGN */
- case 0x007B:
- return((CHAR)(0xC0 & 0xff)); /* LEFT CURLY BRACKET */
- case 0x0041:
- return((CHAR)(0xC1 & 0xff)); /* LATIN CAPITAL LETTER A */
- case 0x0042:
- return((CHAR)(0xC2 & 0xff)); /* LATIN CAPITAL LETTER B */
- case 0x0043:
- return((CHAR)(0xC3 & 0xff)); /* LATIN CAPITAL LETTER C */
- case 0x0044:
- return((CHAR)(0xC4 & 0xff)); /* LATIN CAPITAL LETTER D */
- case 0x0045:
- return((CHAR)(0xC5 & 0xff)); /* LATIN CAPITAL LETTER E */
- case 0x0046:
- return((CHAR)(0xC6 & 0xff)); /* LATIN CAPITAL LETTER F */
- case 0x0047:
- return((CHAR)(0xC7 & 0xff)); /* LATIN CAPITAL LETTER G */
- case 0x0048:
- return((CHAR)(0xC8 & 0xff)); /* LATIN CAPITAL LETTER H */
- case 0x0049:
- return((CHAR)(0xC9 & 0xff)); /* LATIN CAPITAL LETTER I */
- case 0x00AD:
- return((CHAR)(0xCA & 0xff)); /* SOFT HYPHEN */
- case 0x00F4:
- return((CHAR)(0xCB & 0xff)); /* SMALL LETTER O WITH CIRCUMFLEX */
- case 0x00F6:
- return((CHAR)(0xCC & 0xff)); /* SMALL LETTER O WITH DIAERESIS */
- case 0x00F2:
- return((CHAR)(0xCD & 0xff)); /* LATIN SMALL LETTER O WITH GRAVE */
- case 0x00F3:
- return((CHAR)(0xCE & 0xff)); /* LATIN SMALL LETTER O WITH ACUTE */
- case 0x00F5:
- return((CHAR)(0xCF & 0xff)); /* LATIN SMALL LETTER O WITH TILDE */
- case 0x007D:
- return((CHAR)(0xD0 & 0xff)); /* RIGHT CURLY BRACKET */
- case 0x004A:
- return((CHAR)(0xD1 & 0xff)); /* LATIN CAPITAL LETTER J */
- case 0x004B:
- return((CHAR)(0xD2 & 0xff)); /* LATIN CAPITAL LETTER K */
- case 0x004C:
- return((CHAR)(0xD3 & 0xff)); /* LATIN CAPITAL LETTER L */
- case 0x004D:
- return((CHAR)(0xD4 & 0xff)); /* LATIN CAPITAL LETTER M */
- case 0x004E:
- return((CHAR)(0xD5 & 0xff)); /* LATIN CAPITAL LETTER N */
- case 0x004F:
- return((CHAR)(0xD6 & 0xff)); /* LATIN CAPITAL LETTER O */
- case 0x0050:
- return((CHAR)(0xD7 & 0xff)); /* LATIN CAPITAL LETTER P */
- case 0x0051:
- return((CHAR)(0xD8 & 0xff)); /* LATIN CAPITAL LETTER Q */
- case 0x0052:
- return((CHAR)(0xD9 & 0xff)); /* LATIN CAPITAL LETTER R */
- case 0x00B9:
- return((CHAR)(0xDA & 0xff)); /* SUPERSCRIPT ONE */
- case 0x00FB:
- return((CHAR)(0xDB & 0xff)); /* SMALL LETTER U WITH CIRCUMFLEX */
- case 0x00FC:
- return((CHAR)(0xDC & 0xff)); /* SMALL LETTER U WITH DIAERESIS */
- case 0x00F9:
- return((CHAR)(0xDD & 0xff)); /* SMALL LETTER U WITH GRAVE */
- case 0x00FA:
- return((CHAR)(0xDE & 0xff)); /* SMALL LETTER U WITH ACUTE */
- case 0x00FF:
- return((CHAR)(0xDF & 0xff)); /* SMALL LETTER Y WITH DIAERESIS */
- case 0x005C:
- return((CHAR)(0xE0 & 0xff)); /* REVERSE SOLIDUS */
- case 0x00F7:
- return((CHAR)(0xE1 & 0xff)); /* DIVISION SIGN */
- case 0x0053:
- return((CHAR)(0xE2 & 0xff)); /* LATIN CAPITAL LETTER S */
- case 0x0054:
- return((CHAR)(0xE3 & 0xff)); /* LATIN CAPITAL LETTER T */
- case 0x0055:
- return((CHAR)(0xE4 & 0xff)); /* LATIN CAPITAL LETTER U */
- case 0x0056:
- return((CHAR)(0xE5 & 0xff)); /* LATIN CAPITAL LETTER V */
- case 0x0057:
- return((CHAR)(0xE6 & 0xff)); /* LATIN CAPITAL LETTER W */
- case 0x0058:
- return((CHAR)(0xE7 & 0xff)); /* LATIN CAPITAL LETTER X */
- case 0x0059:
- return((CHAR)(0xE8 & 0xff)); /* LATIN CAPITAL LETTER Y */
- case 0x005A:
- return((CHAR)(0xE9 & 0xff)); /* LATIN CAPITAL LETTER Z */
- case 0x00B2:
- return((CHAR)(0xEA & 0xff)); /* SUPERSCRIPT TWO */
- case 0x00D4:
- return((CHAR)(0xEB & 0xff)); /* CAPITAL LETTER O WITH CIRCUMFLEX */
- case 0x00D6:
- return((CHAR)(0xEC & 0xff)); /* CAPITAL LETTER O WITH DIAERESIS */
- case 0x00D2:
- return((CHAR)(0xED & 0xff)); /* CAPITAL LETTER O WITH GRAVE */
- case 0x00D3:
- return((CHAR)(0xEE & 0xff)); /* CAPITAL LETTER O WITH ACUTE */
- case 0x00D5:
- return((CHAR)(0xEF & 0xff)); /* CAPITAL LETTER O WITH TILDE */
- case 0x0030:
- return((CHAR)(0xF0 & 0xff)); /* DIGIT ZERO */
- case 0x0031:
- return((CHAR)(0xF1 & 0xff)); /* DIGIT ONE */
- case 0x0032:
- return((CHAR)(0xF2 & 0xff)); /* DIGIT TWO */
- case 0x0033:
- return((CHAR)(0xF3 & 0xff)); /* DIGIT THREE */
- case 0x0034:
- return((CHAR)(0xF4 & 0xff)); /* DIGIT FOUR */
- case 0x0035:
- return((CHAR)(0xF5 & 0xff)); /* DIGIT FIVE */
- case 0x0036:
- return((CHAR)(0xF6 & 0xff)); /* DIGIT SIX */
- case 0x0037:
- return((CHAR)(0xF7 & 0xff)); /* DIGIT SEVEN */
- case 0x0038:
- return((CHAR)(0xF8 & 0xff)); /* DIGIT EIGHT */
- case 0x0039:
- return((CHAR)(0xF9 & 0xff)); /* DIGIT NINE */
- case 0x00B3:
- return((CHAR)(0xFA & 0xff)); /* SUPERSCRIPT THREE */
- case 0x00DB:
- return((CHAR)(0xFB & 0xff)); /* CAPITAL LETTER U WITH CIRCUMFLEX */
- case 0x00DC:
- return((CHAR)(0xFC & 0xff)); /* CAPITAL LETTER U WITH DIAERESIS */
- case 0x00D9:
- return((CHAR)(0xFD & 0xff)); /* LATIN CAPITAL LETTER U WITH GRAVE */
- case 0x00DA:
- return((CHAR)(0xFE & 0xff)); /* LATIN CAPITAL LETTER U WITH ACUTE */
- case 0x009F:
- return((CHAR)(0xFF & 0xff)); /* CONTROL */
- default: return(0x003f);
- }
-}
-
-
-int /* PC Code Page 855 */
-#ifdef CK_ANSIC
-tx_cp855(USHORT c)
-#else
-tx_cp855(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a4: return((CHAR)(207 & 0xff));
- case 0x00a7: return((CHAR)(253 & 0xff));
- case 0x00ab: return((CHAR)(174 & 0xff));
- case 0x00bb: return((CHAR)(175 & 0xff));
- case 0x0401: return((CHAR)(133 & 0xff));
- case 0x0402: return((CHAR)(129 & 0xff));
- case 0x0403: return((CHAR)(131 & 0xff));
- case 0x0404: return((CHAR)(135 & 0xff));
- case 0x0405: return((CHAR)(137 & 0xff));
- case 0x0406: return((CHAR)(139 & 0xff));
- case 0x0407: return((CHAR)(141 & 0xff));
- case 0x0408: return((CHAR)(143 & 0xff));
- case 0x0409: return((CHAR)(145 & 0xff));
- case 0x040a: return((CHAR)(147 & 0xff));
- case 0x040b: return((CHAR)(149 & 0xff));
- case 0x040c: return((CHAR)(151 & 0xff));
- case 0x040e: return((CHAR)(153 & 0xff));
- case 0x040f: return((CHAR)(155 & 0xff));
- case 0x0410: return((CHAR)(161 & 0xff));
- case 0x0411: return((CHAR)(163 & 0xff));
- case 0x0412: return((CHAR)(236 & 0xff));
- case 0x0413: return((CHAR)(173 & 0xff));
- case 0x0414: return((CHAR)(167 & 0xff));
- case 0x0415: return((CHAR)(169 & 0xff));
- case 0x0416: return((CHAR)(234 & 0xff));
- case 0x0417: return((CHAR)(244 & 0xff));
- case 0x0418: return((CHAR)(184 & 0xff));
- case 0x0419: return((CHAR)(190 & 0xff));
- case 0x041a: return((CHAR)(199 & 0xff));
- case 0x041b: return((CHAR)(209 & 0xff));
- case 0x041c: return((CHAR)(211 & 0xff));
- case 0x041d: return((CHAR)(213 & 0xff));
- case 0x041e: return((CHAR)(215 & 0xff));
- case 0x041f: return((CHAR)(221 & 0xff));
- case 0x0420: return((CHAR)(226 & 0xff));
- case 0x0421: return((CHAR)(228 & 0xff));
- case 0x0422: return((CHAR)(230 & 0xff));
- case 0x0423: return((CHAR)(232 & 0xff));
- case 0x0424: return((CHAR)(171 & 0xff));
- case 0x0425: return((CHAR)(182 & 0xff));
- case 0x0426: return((CHAR)(165 & 0xff));
- case 0x0427: return((CHAR)(252 & 0xff));
- case 0x0428: return((CHAR)(246 & 0xff));
- case 0x0429: return((CHAR)(250 & 0xff));
- case 0x042a: return((CHAR)(159 & 0xff));
- case 0x042b: return((CHAR)(242 & 0xff));
- case 0x042c: return((CHAR)(238 & 0xff));
- case 0x042d: return((CHAR)(248 & 0xff));
- case 0x042e: return((CHAR)(157 & 0xff));
- case 0x042f: return((CHAR)(224 & 0xff));
- case 0x0430: return((CHAR)(160 & 0xff));
- case 0x0431: return((CHAR)(162 & 0xff));
- case 0x0432: return((CHAR)(235 & 0xff));
- case 0x0433: return((CHAR)(172 & 0xff));
- case 0x0434: return((CHAR)(166 & 0xff));
- case 0x0435: return((CHAR)(168 & 0xff));
- case 0x0436: return((CHAR)(233 & 0xff));
- case 0x0437: return((CHAR)(243 & 0xff));
- case 0x0438: return((CHAR)(183 & 0xff));
- case 0x0439: return((CHAR)(189 & 0xff));
- case 0x043a: return((CHAR)(198 & 0xff));
- case 0x043b: return((CHAR)(208 & 0xff));
- case 0x043c: return((CHAR)(210 & 0xff));
- case 0x043d: return((CHAR)(212 & 0xff));
- case 0x043e: return((CHAR)(214 & 0xff));
- case 0x043f: return((CHAR)(216 & 0xff));
- case 0x0440: return((CHAR)(225 & 0xff));
- case 0x0441: return((CHAR)(227 & 0xff));
- case 0x0442: return((CHAR)(229 & 0xff));
- case 0x0443: return((CHAR)(231 & 0xff));
- case 0x0444: return((CHAR)(170 & 0xff));
- case 0x0445: return((CHAR)(181 & 0xff));
- case 0x0446: return((CHAR)(164 & 0xff));
- case 0x0447: return((CHAR)(251 & 0xff));
- case 0x0448: return((CHAR)(245 & 0xff));
- case 0x0449: return((CHAR)(249 & 0xff));
- case 0x044a: return((CHAR)(158 & 0xff));
- case 0x044b: return((CHAR)(241 & 0xff));
- case 0x044c: return((CHAR)(237 & 0xff));
- case 0x044d: return((CHAR)(247 & 0xff));
- case 0x044e: return((CHAR)(156 & 0xff));
- case 0x044f: return((CHAR)(222 & 0xff));
- case 0x0451: return((CHAR)(132 & 0xff));
- case 0x0452: return((CHAR)(128 & 0xff));
- case 0x0453: return((CHAR)(130 & 0xff));
- case 0x0454: return((CHAR)(134 & 0xff));
- case 0x0455: return((CHAR)(136 & 0xff));
- case 0x0456: return((CHAR)(138 & 0xff));
- case 0x0457: return((CHAR)(140 & 0xff));
- case 0x0458: return((CHAR)(142 & 0xff));
- case 0x0459: return((CHAR)(144 & 0xff));
- case 0x045a: return((CHAR)(146 & 0xff));
- case 0x045b: return((CHAR)(148 & 0xff));
- case 0x045c: return((CHAR)(150 & 0xff));
- case 0x045e: return((CHAR)(152 & 0xff));
- case 0x045f: return((CHAR)(154 & 0xff));
- case 0x2116: return((CHAR)(239 & 0xff));
- case 0x2500: return((CHAR)(196 & 0xff));
- case 0x2502: return((CHAR)(179 & 0xff));
- case 0x250c: return((CHAR)(218 & 0xff));
- case 0x2510: return((CHAR)(191 & 0xff));
- case 0x2514: return((CHAR)(192 & 0xff));
- case 0x2518: return((CHAR)(217 & 0xff));
- case 0x251c: return((CHAR)(195 & 0xff));
- case 0x2524: return((CHAR)(180 & 0xff));
- case 0x252c: return((CHAR)(194 & 0xff));
- case 0x2534: return((CHAR)(193 & 0xff));
- case 0x253c: return((CHAR)(197 & 0xff));
- case 0x2550: return((CHAR)(205 & 0xff));
- case 0x2551: return((CHAR)(186 & 0xff));
- case 0x2554: return((CHAR)(201 & 0xff));
- case 0x2557: return((CHAR)(187 & 0xff));
- case 0x255a: return((CHAR)(200 & 0xff));
- case 0x255d: return((CHAR)(188 & 0xff));
- case 0x2560: return((CHAR)(204 & 0xff));
- case 0x2563: return((CHAR)(185 & 0xff));
- case 0x2566: return((CHAR)(203 & 0xff));
- case 0x2569: return((CHAR)(202 & 0xff));
- case 0x256c: return((CHAR)(206 & 0xff));
- case 0x2580: return((CHAR)(223 & 0xff));
- case 0x2584: return((CHAR)(220 & 0xff));
- case 0x2588: return((CHAR)(219 & 0xff));
- case 0x2591: return((CHAR)(176 & 0xff));
- case 0x2592: return((CHAR)(177 & 0xff));
- case 0x2593: return((CHAR)(178 & 0xff));
- case 0x25a0: return((CHAR)(254 & 0xff));
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* PC Code Page 856 */
-#ifdef CK_ANSIC
-tx_cp856(USHORT c)
-#else
-tx_cp856(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a0: return((CHAR)(0xff & 0xff));
- case 0x00a7: return((CHAR)(0xd6 & 0xff));
- case 0x00b0: return((CHAR)(0xf8 & 0xff));
- case 0x00b1: return((CHAR)(0xf1 & 0xff));
- case 0x00b2: return((CHAR)(0xfd & 0xff));
- case 0x00b5: return((CHAR)(0xe6 & 0xff));
- case 0x00b7: return((CHAR)(0xfa & 0xff));
- case 0x00df: return((CHAR)(0xe1 & 0xff));
- case 0x00f7: return((CHAR)(0xf6 & 0xff));
- case 0x0393: return((CHAR)(0xe2 & 0xff));
- case 0x0398: return((CHAR)(0xe9 & 0xff));
- case 0x03a3: return((CHAR)(0xe4 & 0xff));
- case 0x03a6: return((CHAR)(0xe8 & 0xff));
- case 0x03a9: return((CHAR)(0xea & 0xff));
- case 0x03b1: return((CHAR)(0xe0 & 0xff));
- case 0x03b4: return((CHAR)(0xeb & 0xff));
- case 0x03b5: return((CHAR)(0xee & 0xff));
- case 0x03c0: return((CHAR)(0xe3 & 0xff));
- case 0x03c3: return((CHAR)(0xe5 & 0xff));
- case 0x03c4: return((CHAR)(0xe7 & 0xff));
- case 0x03c6: return((CHAR)(0xed & 0xff));
- case 0x0410: return((CHAR)(0x80 & 0xff));
- case 0x0411: return((CHAR)(0x81 & 0xff));
- case 0x0412: return((CHAR)(0x82 & 0xff));
- case 0x0413: return((CHAR)(0x83 & 0xff));
- case 0x0414: return((CHAR)(0x84 & 0xff));
- case 0x0415: return((CHAR)(0x85 & 0xff));
- case 0x0416: return((CHAR)(0x86 & 0xff));
- case 0x0417: return((CHAR)(0x87 & 0xff));
- case 0x0418: return((CHAR)(0x88 & 0xff));
- case 0x0419: return((CHAR)(0x89 & 0xff));
- case 0x041a: return((CHAR)(0x8a & 0xff));
- case 0x041b: return((CHAR)(0x8b & 0xff));
- case 0x041c: return((CHAR)(0x8c & 0xff));
- case 0x041d: return((CHAR)(0x8d & 0xff));
- case 0x041e: return((CHAR)(0x8e & 0xff));
- case 0x041f: return((CHAR)(0x8f & 0xff));
- case 0x0420: return((CHAR)(0x90 & 0xff));
- case 0x0421: return((CHAR)(0x91 & 0xff));
- case 0x0422: return((CHAR)(0x92 & 0xff));
- case 0x0423: return((CHAR)(0x93 & 0xff));
- case 0x0424: return((CHAR)(0x94 & 0xff));
- case 0x0425: return((CHAR)(0x95 & 0xff));
- case 0x0426: return((CHAR)(0x96 & 0xff));
- case 0x0427: return((CHAR)(0x97 & 0xff));
- case 0x0428: return((CHAR)(0x98 & 0xff));
- case 0x0429: return((CHAR)(0x99 & 0xff));
- case 0x042a: return((CHAR)(0x9a & 0xff));
- case 0x042b: return((CHAR)(0x9b & 0xff));
- case 0x042c: return((CHAR)(0x9c & 0xff));
- case 0x042d: return((CHAR)(0x9d & 0xff));
- case 0x042e: return((CHAR)(0x9e & 0xff));
- case 0x042f: return((CHAR)(0x9f & 0xff));
- case 0x0430: return((CHAR)(0xa0 & 0xff));
- case 0x0431: return((CHAR)(0xa1 & 0xff));
- case 0x0432: return((CHAR)(0xa2 & 0xff));
- case 0x0433: return((CHAR)(0xa3 & 0xff));
- case 0x0434: return((CHAR)(0xa4 & 0xff));
- case 0x0435: return((CHAR)(0xa5 & 0xff));
- case 0x0436: return((CHAR)(0xa6 & 0xff));
- case 0x0437: return((CHAR)(0xa7 & 0xff));
- case 0x0438: return((CHAR)(0xa8 & 0xff));
- case 0x0439: return((CHAR)(0xa9 & 0xff));
- case 0x043a: return((CHAR)(0xaa & 0xff));
- case 0x043b: return((CHAR)(0xab & 0xff));
- case 0x043c: return((CHAR)(0xac & 0xff));
- case 0x043d: return((CHAR)(0xad & 0xff));
- case 0x043e: return((CHAR)(0xae & 0xff));
- case 0x043f: return((CHAR)(0xaf & 0xff));
- case 0x0440: return((CHAR)(0xb0 & 0xff));
- case 0x0441: return((CHAR)(0xb1 & 0xff));
- case 0x0442: return((CHAR)(0xb2 & 0xff));
- case 0x0443: return((CHAR)(0xb3 & 0xff));
- case 0x0444: return((CHAR)(0xb4 & 0xff));
- case 0x0445: return((CHAR)(0xb5 & 0xff));
- case 0x0446: return((CHAR)(0xb6 & 0xff));
- case 0x0447: return((CHAR)(0xb7 & 0xff));
- case 0x0448: return((CHAR)(0xb8 & 0xff));
- case 0x0449: return((CHAR)(0xb9 & 0xff));
- case 0x044a: return((CHAR)(0xba & 0xff));
- case 0x044b: return((CHAR)(0xbb & 0xff));
- case 0x044c: return((CHAR)(0xbc & 0xff));
- case 0x044d: return((CHAR)(0xbd & 0xff));
- case 0x044e: return((CHAR)(0xbe & 0xff));
- case 0x044f: return((CHAR)(0xbf & 0xff));
- case 0x207f: return((CHAR)(0xfc & 0xff));
- case 0x2116: return((CHAR)(0xd5 & 0xff));
- case 0x2219: return((CHAR)(0xf9 & 0xff));
- case 0x221a: return((CHAR)(0xfb & 0xff));
- case 0x221e: return((CHAR)(0xec & 0xff));
- case 0x2229: return((CHAR)(0xef & 0xff));
- case 0x2248: return((CHAR)(0xf7 & 0xff));
- case 0x2261: return((CHAR)(0xf0 & 0xff));
- case 0x2264: return((CHAR)(0xf3 & 0xff));
- case 0x2265: return((CHAR)(0xf2 & 0xff));
- case 0x2320: return((CHAR)(0xf4 & 0xff));
- case 0x2321: return((CHAR)(0xf5 & 0xff));
- case 0x2500: return((CHAR)(0xc4 & 0xff));
- case 0x2502: return((CHAR)(0xd3 & 0xff));
- case 0x250c: return((CHAR)(0xda & 0xff));
- case 0x2510: return((CHAR)(0xcf & 0xff));
- case 0x2514: return((CHAR)(0xc0 & 0xff));
- case 0x2518: return((CHAR)(0xd9 & 0xff));
- case 0x251c: return((CHAR)(0xc3 & 0xff));
- case 0x2524: return((CHAR)(0xd4 & 0xff));
- case 0x252c: return((CHAR)(0xc2 & 0xff));
- case 0x2534: return((CHAR)(0xc1 & 0xff));
- case 0x253c: return((CHAR)(0xc5 & 0xff));
- case 0x2550: return((CHAR)(0xcd & 0xff));
- case 0x2551: return((CHAR)(0xc7 & 0xff));
- case 0x2554: return((CHAR)(0xc9 & 0xff));
- case 0x2557: return((CHAR)(0xd7 & 0xff));
- case 0x255a: return((CHAR)(0xc8 & 0xff));
- case 0x255d: return((CHAR)(0xd8 & 0xff));
- case 0x2560: return((CHAR)(0xcc & 0xff));
- case 0x2563: return((CHAR)(0xc6 & 0xff));
- case 0x2566: return((CHAR)(0xcb & 0xff));
- case 0x2569: return((CHAR)(0xca & 0xff));
- case 0x256c: return((CHAR)(0xce & 0xff));
- case 0x2580: return((CHAR)(0xdf & 0xff));
- case 0x2584: return((CHAR)(0xdc & 0xff));
- case 0x2588: return((CHAR)(0xdb & 0xff));
- case 0x258c: return((CHAR)(0xdd & 0xff));
- case 0x2590: return((CHAR)(0xde & 0xff));
- case 0x2591: return((CHAR)(0xd0 & 0xff));
- case 0x2592: return((CHAR)(0xd1 & 0xff));
- case 0x2593: return((CHAR)(0xd2 & 0xff));
- case 0x25a0: return((CHAR)(0xfe & 0xff));
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* PC Code Page 857 */
-#ifdef CK_ANSIC
-tx_cp857(USHORT c)
-#else
-tx_cp857(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00c7: return((CHAR)(128 & 0xff));
- case 0x00fc: return((CHAR)(129 & 0xff));
- case 0x00e9: return((CHAR)(130 & 0xff));
- case 0x00e2: return((CHAR)(131 & 0xff));
- case 0x00e4: return((CHAR)(132 & 0xff));
- case 0x00e0: return((CHAR)(133 & 0xff));
- case 0x00e5: return((CHAR)(134 & 0xff));
- case 0x00e7: return((CHAR)(135 & 0xff));
- case 0x00ea: return((CHAR)(136 & 0xff));
- case 0x00eb: return((CHAR)(137 & 0xff));
- case 0x00e8: return((CHAR)(138 & 0xff));
- case 0x00ef: return((CHAR)(139 & 0xff));
- case 0x00ee: return((CHAR)(140 & 0xff));
- case 0x0131: return((CHAR)(141 & 0xff));
- case 0x00c4: return((CHAR)(142 & 0xff));
- case 0x00c5: return((CHAR)(143 & 0xff));
- case 0x00c9: return((CHAR)(144 & 0xff));
- case 0x00e6: return((CHAR)(145 & 0xff));
- case 0x00c6: return((CHAR)(146 & 0xff));
- case 0x00f4: return((CHAR)(147 & 0xff));
- case 0x00f6: return((CHAR)(148 & 0xff));
- case 0x00f2: return((CHAR)(149 & 0xff));
- case 0x00fb: return((CHAR)(150 & 0xff));
- case 0x00f9: return((CHAR)(151 & 0xff));
- case 0x0130: return((CHAR)(152 & 0xff));
- case 0x00d6: return((CHAR)(153 & 0xff));
- case 0x00dc: return((CHAR)(154 & 0xff));
- case 0x00f8: return((CHAR)(155 & 0xff));
- case 0x00a3: return((CHAR)(156 & 0xff));
- case 0x00d8: return((CHAR)(157 & 0xff));
- case 0x015e: return((CHAR)(158 & 0xff));
- case 0x015f: return((CHAR)(159 & 0xff));
- case 0x00e1: return((CHAR)(160 & 0xff));
- case 0x00ed: return((CHAR)(161 & 0xff));
- case 0x00f3: return((CHAR)(162 & 0xff));
- case 0x00fa: return((CHAR)(163 & 0xff));
- case 0x00f1: return((CHAR)(164 & 0xff));
- case 0x00d1: return((CHAR)(165 & 0xff));
- case 0x011e: return((CHAR)(166 & 0xff));
- case 0x011f: return((CHAR)(167 & 0xff));
- case 0x00bf: return((CHAR)(168 & 0xff));
- case 0x00ae: return((CHAR)(169 & 0xff));
- case 0x00ac: return((CHAR)(170 & 0xff));
- case 0x00bd: return((CHAR)(171 & 0xff));
- case 0x00bc: return((CHAR)(172 & 0xff));
- case 0x00a1: return((CHAR)(173 & 0xff));
- case 0x00ab: return((CHAR)(174 & 0xff));
- case 0x00bb: return((CHAR)(175 & 0xff));
- case 0x20ac: return((CHAR)(213 & 0xff)); /* Euro */
- case 0x2591: return((CHAR)(176 & 0xff));
- case 0x2592: return((CHAR)(177 & 0xff));
- case 0x2593: return((CHAR)(178 & 0xff));
- case 0x2502: return((CHAR)(179 & 0xff));
- case 0x2524: return((CHAR)(180 & 0xff));
- case 0x00c1: return((CHAR)(181 & 0xff));
- case 0x00c2: return((CHAR)(182 & 0xff));
- case 0x00c0: return((CHAR)(183 & 0xff));
- case 0x00a9: return((CHAR)(184 & 0xff));
- case 0x2563: return((CHAR)(185 & 0xff));
- case 0x2551: return((CHAR)(186 & 0xff));
- case 0x2557: return((CHAR)(187 & 0xff));
- case 0x255d: return((CHAR)(188 & 0xff));
- case 0x00a2: return((CHAR)(189 & 0xff));
- case 0x00a5: return((CHAR)(190 & 0xff));
- case 0x2510: return((CHAR)(191 & 0xff));
- case 0x2514: return((CHAR)(192 & 0xff));
- case 0x2534: return((CHAR)(193 & 0xff));
- case 0x252c: return((CHAR)(194 & 0xff));
- case 0x251c: return((CHAR)(195 & 0xff));
- case 0x2500: return((CHAR)(196 & 0xff));
- case 0x253c: return((CHAR)(197 & 0xff));
- case 0x00e3: return((CHAR)(198 & 0xff));
- case 0x00c3: return((CHAR)(199 & 0xff));
- case 0x255a: return((CHAR)(200 & 0xff));
- case 0x2554: return((CHAR)(201 & 0xff));
- case 0x2569: return((CHAR)(202 & 0xff));
- case 0x2566: return((CHAR)(203 & 0xff));
- case 0x2560: return((CHAR)(204 & 0xff));
- case 0x2550: return((CHAR)(205 & 0xff));
- case 0x256c: return((CHAR)(206 & 0xff));
- case 0x00a4: return((CHAR)(207 & 0xff));
- case 0x00ba: return((CHAR)(208 & 0xff));
- case 0x00aa: return((CHAR)(209 & 0xff));
- case 0x00ca: return((CHAR)(210 & 0xff));
- case 0x00cb: return((CHAR)(211 & 0xff));
- case 0x00c8: return((CHAR)(212 & 0xff));
- case 0x00cd: return((CHAR)(214 & 0xff));
- case 0x00ce: return((CHAR)(215 & 0xff));
- case 0x00cf: return((CHAR)(216 & 0xff));
- case 0x2518: return((CHAR)(217 & 0xff));
- case 0x250c: return((CHAR)(218 & 0xff));
- case 0x2588: return((CHAR)(219 & 0xff));
- case 0x2584: return((CHAR)(220 & 0xff));
- case 0x00a6: return((CHAR)(221 & 0xff));
- case 0x00cc: return((CHAR)(222 & 0xff));
- case 0x2580: return((CHAR)(223 & 0xff));
- case 0x00d3: return((CHAR)(224 & 0xff));
- case 0x00df: return((CHAR)(225 & 0xff));
- case 0x00d4: return((CHAR)(226 & 0xff));
- case 0x00d2: return((CHAR)(227 & 0xff));
- case 0x00f5: return((CHAR)(228 & 0xff));
- case 0x00d5: return((CHAR)(229 & 0xff));
- case 0x00b5: return((CHAR)(230 & 0xff));
- case 0x00d7: return((CHAR)(232 & 0xff));
- case 0x00da: return((CHAR)(233 & 0xff));
- case 0x00db: return((CHAR)(234 & 0xff));
- case 0x00d9: return((CHAR)(235 & 0xff));
- case 0x00ec: return((CHAR)(236 & 0xff));
- case 0x00ff: return((CHAR)(237 & 0xff));
- case 0x00af: return((CHAR)(238 & 0xff));
- case 0x00b4: return((CHAR)(239 & 0xff));
- case 0x00ad: return((CHAR)(240 & 0xff));
- case 0x00b1: return((CHAR)(241 & 0xff));
- case 0x00be: return((CHAR)(243 & 0xff));
- case 0x00b6: return((CHAR)(244 & 0xff));
- case 0x00a7: return((CHAR)(245 & 0xff));
- case 0x00f7: return((CHAR)(246 & 0xff));
- case 0x00b8: return((CHAR)(247 & 0xff));
- case 0x00b0: return((CHAR)(248 & 0xff));
- case 0x00a8: return((CHAR)(249 & 0xff));
- case 0x00b7: return((CHAR)(250 & 0xff));
- case 0x00b9: return((CHAR)(251 & 0xff));
- case 0x00b3: return((CHAR)(252 & 0xff));
- case 0x00b2: return((CHAR)(253 & 0xff));
- case 0x25a0: return((CHAR)(254 & 0xff));
- case 0x00a0: return((CHAR)(255 & 0xff));
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* PC Code Page 862 */
-#ifdef CK_ANSIC
-tx_cp862(USHORT c)
-#else
-tx_cp862(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x05d0: return((CHAR)(128 & 0xff));
- case 0x05d1: return((CHAR)(129 & 0xff));
- case 0x05d2: return((CHAR)(130 & 0xff));
- case 0x05d3: return((CHAR)(131 & 0xff));
- case 0x05d4: return((CHAR)(132 & 0xff));
- case 0x05d5: return((CHAR)(133 & 0xff));
- case 0x05d6: return((CHAR)(134 & 0xff));
- case 0x05d7: return((CHAR)(135 & 0xff));
- case 0x05d8: return((CHAR)(136 & 0xff));
- case 0x05d9: return((CHAR)(137 & 0xff));
- case 0x05da: return((CHAR)(138 & 0xff));
- case 0x05db: return((CHAR)(139 & 0xff));
- case 0x05dc: return((CHAR)(140 & 0xff));
- case 0x05dd: return((CHAR)(141 & 0xff));
- case 0x05de: return((CHAR)(142 & 0xff));
- case 0x05df: return((CHAR)(143 & 0xff));
- case 0x05e0: return((CHAR)(144 & 0xff));
- case 0x05e1: return((CHAR)(145 & 0xff));
- case 0x05e2: return((CHAR)(146 & 0xff));
- case 0x05e3: return((CHAR)(147 & 0xff));
- case 0x05e4: return((CHAR)(148 & 0xff));
- case 0x05e5: return((CHAR)(149 & 0xff));
- case 0x05e6: return((CHAR)(150 & 0xff));
- case 0x05e7: return((CHAR)(151 & 0xff));
- case 0x05e8: return((CHAR)(152 & 0xff));
- case 0x05e9: return((CHAR)(153 & 0xff));
- case 0x05ea: return((CHAR)(154 & 0xff));
- case 0x00a2: return((CHAR)(155 & 0xff));
- case 0x00a3: return((CHAR)(156 & 0xff));
- case 0x00a5: return((CHAR)(157 & 0xff));
- case 0x20a7: return((CHAR)(158 & 0xff));
- case 0x0192: return((CHAR)(159 & 0xff));
- case 0x00e1: return((CHAR)(160 & 0xff));
- case 0x00ed: return((CHAR)(161 & 0xff));
- case 0x00f3: return((CHAR)(162 & 0xff));
- case 0x00fa: return((CHAR)(163 & 0xff));
- case 0x00f1: return((CHAR)(164 & 0xff));
- case 0x00d1: return((CHAR)(165 & 0xff));
- case 0x00aa: return((CHAR)(166 & 0xff));
- case 0x00ba: return((CHAR)(167 & 0xff));
- case 0x00bf: return((CHAR)(168 & 0xff));
- case 0x2310: return((CHAR)(169 & 0xff));
- case 0x00ac: return((CHAR)(170 & 0xff));
- case 0x00bd: return((CHAR)(171 & 0xff));
- case 0x00bc: return((CHAR)(172 & 0xff));
- case 0x00a1: return((CHAR)(173 & 0xff));
- case 0x00ab: return((CHAR)(174 & 0xff));
- case 0x00bb: return((CHAR)(175 & 0xff));
- case 0x2591: return((CHAR)(176 & 0xff));
- case 0x2592: return((CHAR)(177 & 0xff));
- case 0x2593: return((CHAR)(178 & 0xff));
- case 0x2502: return((CHAR)(179 & 0xff));
- case 0x2524: return((CHAR)(180 & 0xff));
- case 0x2561: return((CHAR)(181 & 0xff));
- case 0x2562: return((CHAR)(182 & 0xff));
- case 0x2556: return((CHAR)(183 & 0xff));
- case 0x2555: return((CHAR)(184 & 0xff));
- case 0x2563: return((CHAR)(185 & 0xff));
- case 0x2551: return((CHAR)(186 & 0xff));
- case 0x2557: return((CHAR)(187 & 0xff));
- case 0x255d: return((CHAR)(188 & 0xff));
- case 0x255c: return((CHAR)(189 & 0xff));
- case 0x255b: return((CHAR)(190 & 0xff));
- case 0x2510: return((CHAR)(191 & 0xff));
- case 0x2514: return((CHAR)(192 & 0xff));
- case 0x2534: return((CHAR)(193 & 0xff));
- case 0x252c: return((CHAR)(194 & 0xff));
- case 0x251c: return((CHAR)(195 & 0xff));
- case 0x2500: return((CHAR)(196 & 0xff));
- case 0x253c: return((CHAR)(197 & 0xff));
- case 0x255e: return((CHAR)(198 & 0xff));
- case 0x255f: return((CHAR)(199 & 0xff));
- case 0x255a: return((CHAR)(200 & 0xff));
- case 0x2554: return((CHAR)(201 & 0xff));
- case 0x2569: return((CHAR)(202 & 0xff));
- case 0x2566: return((CHAR)(203 & 0xff));
- case 0x2560: return((CHAR)(204 & 0xff));
- case 0x2550: return((CHAR)(205 & 0xff));
- case 0x256c: return((CHAR)(206 & 0xff));
- case 0x2567: return((CHAR)(207 & 0xff));
- case 0x2568: return((CHAR)(208 & 0xff));
- case 0x2564: return((CHAR)(209 & 0xff));
- case 0x2565: return((CHAR)(210 & 0xff));
- case 0x2559: return((CHAR)(211 & 0xff));
- case 0x2558: return((CHAR)(212 & 0xff));
- case 0x2552: return((CHAR)(213 & 0xff));
- case 0x2553: return((CHAR)(214 & 0xff));
- case 0x256b: return((CHAR)(215 & 0xff));
- case 0x256a: return((CHAR)(216 & 0xff));
- case 0x2518: return((CHAR)(217 & 0xff));
- case 0x250c: return((CHAR)(218 & 0xff));
- case 0x2588: return((CHAR)(219 & 0xff));
- case 0x2584: return((CHAR)(220 & 0xff));
- case 0x258c: return((CHAR)(221 & 0xff));
- case 0x2590: return((CHAR)(222 & 0xff));
- case 0x2580: return((CHAR)(223 & 0xff));
- case 0x03b1: return((CHAR)(224 & 0xff));
- case 0x00df: return((CHAR)(225 & 0xff));
- case 0x0393: return((CHAR)(226 & 0xff));
- case 0x03c0: return((CHAR)(227 & 0xff));
- case 0x03a3: return((CHAR)(228 & 0xff));
- case 0x03c3: return((CHAR)(229 & 0xff));
- case 0x00b5: return((CHAR)(230 & 0xff));
- case 0x03c4: return((CHAR)(231 & 0xff));
- case 0x03a6: return((CHAR)(232 & 0xff));
- case 0x0398: return((CHAR)(233 & 0xff));
- case 0x03a9: return((CHAR)(234 & 0xff));
- case 0x03b4: return((CHAR)(235 & 0xff));
- case 0x221e: return((CHAR)(236 & 0xff));
- case 0x03c6: return((CHAR)(237 & 0xff));
- case 0x03b5: return((CHAR)(238 & 0xff));
- case 0x2229: return((CHAR)(239 & 0xff));
- case 0x2261: return((CHAR)(240 & 0xff));
- case 0x00b1: return((CHAR)(241 & 0xff));
- case 0x2265: return((CHAR)(242 & 0xff));
- case 0x2264: return((CHAR)(243 & 0xff));
- case 0x2320: return((CHAR)(244 & 0xff));
- case 0x2321: return((CHAR)(245 & 0xff));
- case 0x00f7: return((CHAR)(246 & 0xff));
- case 0x2248: return((CHAR)(247 & 0xff));
- case 0x00b0: return((CHAR)(248 & 0xff));
- case 0x2219: return((CHAR)(249 & 0xff));
- case 0x00b7: return((CHAR)(250 & 0xff));
- case 0x221a: return((CHAR)(251 & 0xff));
- case 0x207f: return((CHAR)(252 & 0xff));
- case 0x00b2: return((CHAR)(253 & 0xff));
- case 0x25a0: return((CHAR)(254 & 0xff));
- case 0x00a0: return((CHAR)(255 & 0xff));
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* PC Code Page 864 */
-#ifdef CK_ANSIC
-tx_cp864(USHORT c)
-#else
-tx_cp864(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00b0: return((CHAR)0x80 & 0xff);
- case 0x00b7: return((CHAR)0x81 & 0xff);
- case 0x2219: return((CHAR)0x82 & 0xff);
- case 0x221a: return((CHAR)0x83 & 0xff);
- case 0x2592: return((CHAR)0x84 & 0xff);
- case 0x2500: return((CHAR)0x85 & 0xff);
- case 0x2502: return((CHAR)0x86 & 0xff);
- case 0x253c: return((CHAR)0x87 & 0xff);
- case 0x2524: return((CHAR)0x88 & 0xff);
- case 0x252c: return((CHAR)0x89 & 0xff);
- case 0x251c: return((CHAR)0x8a & 0xff);
- case 0x2534: return((CHAR)0x8b & 0xff);
- case 0x2510: return((CHAR)0x8c & 0xff);
- case 0x250c: return((CHAR)0x8d & 0xff);
- case 0x2514: return((CHAR)0x8e & 0xff);
- case 0x2518: return((CHAR)0x8f & 0xff);
- case 0x03b2: return((CHAR)0x90 & 0xff);
- case 0x221e: return((CHAR)0x91 & 0xff);
- case 0x03c6: return((CHAR)0x92 & 0xff);
- case 0x00b1: return((CHAR)0x93 & 0xff);
- case 0x00bd: return((CHAR)0x94 & 0xff);
- case 0x00bc: return((CHAR)0x95 & 0xff);
- case 0x2248: return((CHAR)0x96 & 0xff);
- case 0x00ab: return((CHAR)0x97 & 0xff);
- case 0x00bb: return((CHAR)0x98 & 0xff);
- case 0xfef7: return((CHAR)0x99 & 0xff);
- case 0xfef8: return((CHAR)0x9a & 0xff);
- case 0xfefb: return((CHAR)0x9d & 0xff);
- case 0xfefc: return((CHAR)0x9e & 0xff);
- case 0x00a0: return((CHAR)0xa0 & 0xff);
- case 0x00ad: return((CHAR)0xa1 & 0xff);
- case 0xfe82: return((CHAR)0xa2 & 0xff);
- case 0x00a3: return((CHAR)0xa3 & 0xff);
- case 0x00a4: return((CHAR)0xa4 & 0xff);
- case 0xfe84: return((CHAR)0xa5 & 0xff);
- case 0xfe8e: return((CHAR)0xa8 & 0xff);
- case 0xfe8f: return((CHAR)0xa9 & 0xff);
- case 0xfe95: return((CHAR)0xaa & 0xff);
- case 0xfe99: return((CHAR)0xab & 0xff);
- case 0x060c: return((CHAR)0xac & 0xff);
- case 0xfe9d: return((CHAR)0xad & 0xff);
- case 0xfea1: return((CHAR)0xae & 0xff);
- case 0xfea5: return((CHAR)0xaf & 0xff);
- case 0x0660: return((CHAR)0xb0 & 0xff);
- case 0x0661: return((CHAR)0xb1 & 0xff);
- case 0x0662: return((CHAR)0xb2 & 0xff);
- case 0x0663: return((CHAR)0xb3 & 0xff);
- case 0x0664: return((CHAR)0xb4 & 0xff);
- case 0x0665: return((CHAR)0xb5 & 0xff);
- case 0x0666: return((CHAR)0xb6 & 0xff);
- case 0x0667: return((CHAR)0xb7 & 0xff);
- case 0x0668: return((CHAR)0xb8 & 0xff);
- case 0x0669: return((CHAR)0xb9 & 0xff);
- case 0xfed1: return((CHAR)0xba & 0xff);
- case 0x061b: return((CHAR)0xbb & 0xff);
- case 0xfeb1: return((CHAR)0xbc & 0xff);
- case 0xfeb5: return((CHAR)0xbd & 0xff);
- case 0xfeb9: return((CHAR)0xbe & 0xff);
- case 0x061f: return((CHAR)0xbf & 0xff);
- case 0x00a2: return((CHAR)0xc0 & 0xff);
- case 0xfe80: return((CHAR)0xc1 & 0xff);
- case 0xfe81: return((CHAR)0xc2 & 0xff);
- case 0xfe83: return((CHAR)0xc3 & 0xff);
- case 0xfe85: return((CHAR)0xc4 & 0xff);
- case 0xfeca: return((CHAR)0xc5 & 0xff);
- case 0xfe8b: return((CHAR)0xc6 & 0xff);
- case 0xfe8d: return((CHAR)0xc7 & 0xff);
- case 0xfe91: return((CHAR)0xc8 & 0xff);
- case 0xfe93: return((CHAR)0xc9 & 0xff);
- case 0xfe97: return((CHAR)0xca & 0xff);
- case 0xfe9b: return((CHAR)0xcb & 0xff);
- case 0xfe9f: return((CHAR)0xcc & 0xff);
- case 0xfea3: return((CHAR)0xcd & 0xff);
- case 0xfea7: return((CHAR)0xce & 0xff);
- case 0xfea9: return((CHAR)0xcf & 0xff);
- case 0xfeab: return((CHAR)0xd0 & 0xff);
- case 0xfead: return((CHAR)0xd1 & 0xff);
- case 0xfeaf: return((CHAR)0xd2 & 0xff);
- case 0xfeb3: return((CHAR)0xd3 & 0xff);
- case 0xfeb7: return((CHAR)0xd4 & 0xff);
- case 0xfebb: return((CHAR)0xd5 & 0xff);
- case 0xfebf: return((CHAR)0xd6 & 0xff);
- case 0xfec1: return((CHAR)0xd7 & 0xff);
- case 0xfec5: return((CHAR)0xd8 & 0xff);
- case 0xfecb: return((CHAR)0xd9 & 0xff);
- case 0xfecf: return((CHAR)0xda & 0xff);
- case 0x00a6: return((CHAR)0xdb & 0xff);
- case 0x00ac: return((CHAR)0xdc & 0xff);
- case 0x00f7: return((CHAR)0xdd & 0xff);
- case 0x00d7: return((CHAR)0xde & 0xff);
- case 0xfec9: return((CHAR)0xdf & 0xff);
- case 0x0640: return((CHAR)0xe0 & 0xff);
- case 0xfed3: return((CHAR)0xe1 & 0xff);
- case 0xfed7: return((CHAR)0xe2 & 0xff);
- case 0xfedb: return((CHAR)0xe3 & 0xff);
- case 0xfedf: return((CHAR)0xe4 & 0xff);
- case 0xfee3: return((CHAR)0xe5 & 0xff);
- case 0xfee7: return((CHAR)0xe6 & 0xff);
- case 0xfeeb: return((CHAR)0xe7 & 0xff);
- case 0xfeed: return((CHAR)0xe8 & 0xff);
- case 0xfeef: return((CHAR)0xe9 & 0xff);
- case 0xfef3: return((CHAR)0xea & 0xff);
- case 0xfebd: return((CHAR)0xeb & 0xff);
- case 0xfecc: return((CHAR)0xec & 0xff);
- case 0xfece: return((CHAR)0xed & 0xff);
- case 0xfecd: return((CHAR)0xee & 0xff);
- case 0xfee1: return((CHAR)0xef & 0xff);
- case 0xfe7d: return((CHAR)0xf0 & 0xff);
- case 0x0651: return((CHAR)0xf1 & 0xff);
- case 0xfee5: return((CHAR)0xf2 & 0xff);
- case 0xfee9: return((CHAR)0xf3 & 0xff);
- case 0xfeec: return((CHAR)0xf4 & 0xff);
- case 0xfef0: return((CHAR)0xf5 & 0xff);
- case 0xfef2: return((CHAR)0xf6 & 0xff);
- case 0xfed0: return((CHAR)0xf7 & 0xff);
- case 0xfed5: return((CHAR)0xf8 & 0xff);
- case 0xfef5: return((CHAR)0xf9 & 0xff);
- case 0xfef6: return((CHAR)0xfa & 0xff);
- case 0xfedd: return((CHAR)0xfb & 0xff);
- case 0xfed9: return((CHAR)0xfc & 0xff);
- case 0xfef1: return((CHAR)0xfd & 0xff);
- case 0x25a0: return((CHAR)0xfe & 0xff);
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* PC Code Page 866 */
-#ifdef CK_ANSIC
-tx_cp866(USHORT c)
-#else
-tx_cp866(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a0: return((CHAR)(255 & 0xff));
- case 0x00a4: return((CHAR)(253 & 0xff));
- case 0x00b0: return((CHAR)(248 & 0xff));
- case 0x00b7: return((CHAR)(250 & 0xff));
- case 0x0401: return((CHAR)(240 & 0xff));
- case 0x0404: return((CHAR)(242 & 0xff));
- case 0x0407: return((CHAR)(244 & 0xff));
- case 0x040e: return((CHAR)(246 & 0xff));
- case 0x0410: return((CHAR)(128 & 0xff));
- case 0x0411: return((CHAR)(129 & 0xff));
- case 0x0412: return((CHAR)(130 & 0xff));
- case 0x0413: return((CHAR)(131 & 0xff));
- case 0x0414: return((CHAR)(132 & 0xff));
- case 0x0415: return((CHAR)(133 & 0xff));
- case 0x0416: return((CHAR)(134 & 0xff));
- case 0x0417: return((CHAR)(135 & 0xff));
- case 0x0418: return((CHAR)(136 & 0xff));
- case 0x0419: return((CHAR)(137 & 0xff));
- case 0x041a: return((CHAR)(138 & 0xff));
- case 0x041b: return((CHAR)(139 & 0xff));
- case 0x041c: return((CHAR)(140 & 0xff));
- case 0x041d: return((CHAR)(141 & 0xff));
- case 0x041e: return((CHAR)(142 & 0xff));
- case 0x041f: return((CHAR)(143 & 0xff));
- case 0x0420: return((CHAR)(144 & 0xff));
- case 0x0421: return((CHAR)(145 & 0xff));
- case 0x0422: return((CHAR)(146 & 0xff));
- case 0x0423: return((CHAR)(147 & 0xff));
- case 0x0424: return((CHAR)(148 & 0xff));
- case 0x0425: return((CHAR)(149 & 0xff));
- case 0x0426: return((CHAR)(150 & 0xff));
- case 0x0427: return((CHAR)(151 & 0xff));
- case 0x0428: return((CHAR)(152 & 0xff));
- case 0x0429: return((CHAR)(153 & 0xff));
- case 0x042a: return((CHAR)(154 & 0xff));
- case 0x042b: return((CHAR)(155 & 0xff));
- case 0x042c: return((CHAR)(156 & 0xff));
- case 0x042d: return((CHAR)(157 & 0xff));
- case 0x042e: return((CHAR)(158 & 0xff));
- case 0x042f: return((CHAR)(159 & 0xff));
- case 0x0430: return((CHAR)(160 & 0xff));
- case 0x0431: return((CHAR)(161 & 0xff));
- case 0x0432: return((CHAR)(162 & 0xff));
- case 0x0433: return((CHAR)(163 & 0xff));
- case 0x0434: return((CHAR)(164 & 0xff));
- case 0x0435: return((CHAR)(165 & 0xff));
- case 0x0436: return((CHAR)(166 & 0xff));
- case 0x0437: return((CHAR)(167 & 0xff));
- case 0x0438: return((CHAR)(168 & 0xff));
- case 0x0439: return((CHAR)(169 & 0xff));
- case 0x043a: return((CHAR)(170 & 0xff));
- case 0x043b: return((CHAR)(171 & 0xff));
- case 0x043c: return((CHAR)(172 & 0xff));
- case 0x043d: return((CHAR)(173 & 0xff));
- case 0x043e: return((CHAR)(174 & 0xff));
- case 0x043f: return((CHAR)(175 & 0xff));
- case 0x0440: return((CHAR)(224 & 0xff));
- case 0x0441: return((CHAR)(225 & 0xff));
- case 0x0442: return((CHAR)(226 & 0xff));
- case 0x0443: return((CHAR)(227 & 0xff));
- case 0x0444: return((CHAR)(228 & 0xff));
- case 0x0445: return((CHAR)(229 & 0xff));
- case 0x0446: return((CHAR)(230 & 0xff));
- case 0x0447: return((CHAR)(231 & 0xff));
- case 0x0448: return((CHAR)(232 & 0xff));
- case 0x0449: return((CHAR)(233 & 0xff));
- case 0x044a: return((CHAR)(234 & 0xff));
- case 0x044b: return((CHAR)(235 & 0xff));
- case 0x044c: return((CHAR)(236 & 0xff));
- case 0x044d: return((CHAR)(237 & 0xff));
- case 0x044e: return((CHAR)(238 & 0xff));
- case 0x044f: return((CHAR)(239 & 0xff));
- case 0x0451: return((CHAR)(241 & 0xff));
- case 0x0454: return((CHAR)(243 & 0xff));
- case 0x0457: return((CHAR)(245 & 0xff));
- case 0x045e: return((CHAR)(247 & 0xff));
- case 0x2116: return((CHAR)(252 & 0xff));
- case 0x2219: return((CHAR)(249 & 0xff));
- case 0x221a: return((CHAR)(251 & 0xff));
- case 0x2500: return((CHAR)(196 & 0xff));
- case 0x2502: return((CHAR)(179 & 0xff));
- case 0x250c: return((CHAR)(218 & 0xff));
- case 0x2510: return((CHAR)(191 & 0xff));
- case 0x2514: return((CHAR)(192 & 0xff));
- case 0x2518: return((CHAR)(217 & 0xff));
- case 0x251c: return((CHAR)(195 & 0xff));
- case 0x2524: return((CHAR)(180 & 0xff));
- case 0x252c: return((CHAR)(194 & 0xff));
- case 0x2534: return((CHAR)(193 & 0xff));
- case 0x253c: return((CHAR)(197 & 0xff));
- case 0x2550: return((CHAR)(205 & 0xff));
- case 0x2551: return((CHAR)(186 & 0xff));
- case 0x2552: return((CHAR)(213 & 0xff));
- case 0x2553: return((CHAR)(214 & 0xff));
- case 0x2554: return((CHAR)(201 & 0xff));
- case 0x2555: return((CHAR)(184 & 0xff));
- case 0x2556: return((CHAR)(183 & 0xff));
- case 0x2557: return((CHAR)(187 & 0xff));
- case 0x2558: return((CHAR)(212 & 0xff));
- case 0x2559: return((CHAR)(211 & 0xff));
- case 0x255a: return((CHAR)(200 & 0xff));
- case 0x255b: return((CHAR)(190 & 0xff));
- case 0x255c: return((CHAR)(189 & 0xff));
- case 0x255d: return((CHAR)(188 & 0xff));
- case 0x255e: return((CHAR)(198 & 0xff));
- case 0x255f: return((CHAR)(199 & 0xff));
- case 0x2560: return((CHAR)(204 & 0xff));
- case 0x2561: return((CHAR)(181 & 0xff));
- case 0x2562: return((CHAR)(182 & 0xff));
- case 0x2563: return((CHAR)(185 & 0xff));
- case 0x2564: return((CHAR)(209 & 0xff));
- case 0x2565: return((CHAR)(210 & 0xff));
- case 0x2566: return((CHAR)(203 & 0xff));
- case 0x2567: return((CHAR)(207 & 0xff));
- case 0x2568: return((CHAR)(208 & 0xff));
- case 0x2569: return((CHAR)(202 & 0xff));
- case 0x256a: return((CHAR)(216 & 0xff));
- case 0x256b: return((CHAR)(215 & 0xff));
- case 0x256c: return((CHAR)(206 & 0xff));
- case 0x2580: return((CHAR)(223 & 0xff));
- case 0x2584: return((CHAR)(220 & 0xff));
- case 0x2588: return((CHAR)(219 & 0xff));
- case 0x258c: return((CHAR)(221 & 0xff));
- case 0x2590: return((CHAR)(222 & 0xff));
- case 0x2591: return((CHAR)(176 & 0xff));
- case 0x2592: return((CHAR)(177 & 0xff));
- case 0x2593: return((CHAR)(178 & 0xff));
- case 0x25a0: return((CHAR)(254 & 0xff));
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* PC Code Page 869 */
-#ifdef CK_ANSIC
-tx_cp869(USHORT c)
-#else
-tx_cp869(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x80) /* Has C1 graphics */
- return((CHAR)(c & 0xff));
- switch (c) {
- case 0x00a0: return((CHAR)(255 & 0xff));
- case 0x00a3: return((CHAR)(156 & 0xff));
- case 0x00a6: return((CHAR)(138 & 0xff));
- case 0x00a7: return((CHAR)(245 & 0xff));
- case 0x00a8: return((CHAR)(249 & 0xff));
- case 0x00a9: return((CHAR)(151 & 0xff));
- case 0x00ab: return((CHAR)(174 & 0xff));
- case 0x00ac: return((CHAR)(137 & 0xff));
- case 0x00ad: return((CHAR)(240 & 0xff));
- case 0x00b0: return((CHAR)(248 & 0xff));
- case 0x00b1: return((CHAR)(241 & 0xff));
- case 0x00b2: return((CHAR)(153 & 0xff));
- case 0x00b3: return((CHAR)(154 & 0xff));
- case 0x00b7: return((CHAR)(136 & 0xff));
- case 0x00bb: return((CHAR)(175 & 0xff));
- case 0x00bd: return((CHAR)(171 & 0xff));
- case 0x0384: return((CHAR)(239 & 0xff));
- case 0x0385: return((CHAR)(247 & 0xff));
- case 0x0386: return((CHAR)(134 & 0xff));
- case 0x0388: return((CHAR)(141 & 0xff));
- case 0x0389: return((CHAR)(143 & 0xff));
- case 0x038a: return((CHAR)(144 & 0xff));
- case 0x038c: return((CHAR)(146 & 0xff));
- case 0x038e: return((CHAR)(149 & 0xff));
- case 0x038f: return((CHAR)(152 & 0xff));
- case 0x0390: return((CHAR)(161 & 0xff));
- case 0x0391: return((CHAR)(164 & 0xff));
- case 0x0392: return((CHAR)(165 & 0xff));
- case 0x0393: return((CHAR)(166 & 0xff));
- case 0x0394: return((CHAR)(167 & 0xff));
- case 0x0395: return((CHAR)(168 & 0xff));
- case 0x0396: return((CHAR)(169 & 0xff));
- case 0x0397: return((CHAR)(170 & 0xff));
- case 0x0398: return((CHAR)(172 & 0xff));
- case 0x0399: return((CHAR)(173 & 0xff));
- case 0x039a: return((CHAR)(181 & 0xff));
- case 0x039b: return((CHAR)(182 & 0xff));
- case 0x039c: return((CHAR)(183 & 0xff));
- case 0x039d: return((CHAR)(184 & 0xff));
- case 0x039e: return((CHAR)(189 & 0xff));
- case 0x039f: return((CHAR)(190 & 0xff));
- case 0x03a0: return((CHAR)(198 & 0xff));
- case 0x03a1: return((CHAR)(199 & 0xff));
- case 0x03a3: return((CHAR)(207 & 0xff));
- case 0x03a4: return((CHAR)(208 & 0xff));
- case 0x03a5: return((CHAR)(209 & 0xff));
- case 0x03a6: return((CHAR)(210 & 0xff));
- case 0x03a7: return((CHAR)(211 & 0xff));
- case 0x03a8: return((CHAR)(212 & 0xff));
- case 0x03a9: return((CHAR)(213 & 0xff));
- case 0x03aa: return((CHAR)(145 & 0xff));
- case 0x03ab: return((CHAR)(150 & 0xff));
- case 0x03ac: return((CHAR)(155 & 0xff));
- case 0x03ad: return((CHAR)(157 & 0xff));
- case 0x03ae: return((CHAR)(158 & 0xff));
- case 0x03af: return((CHAR)(159 & 0xff));
- case 0x03b0: return((CHAR)(252 & 0xff));
- case 0x03b1: return((CHAR)(214 & 0xff));
- case 0x03b2: return((CHAR)(215 & 0xff));
- case 0x03b3: return((CHAR)(216 & 0xff));
- case 0x03b4: return((CHAR)(221 & 0xff));
- case 0x03b5: return((CHAR)(222 & 0xff));
- case 0x03b6: return((CHAR)(224 & 0xff));
- case 0x03b7: return((CHAR)(225 & 0xff));
- case 0x03b8: return((CHAR)(226 & 0xff));
- case 0x03b9: return((CHAR)(227 & 0xff));
- case 0x03ba: return((CHAR)(228 & 0xff));
- case 0x03bb: return((CHAR)(229 & 0xff));
- case 0x03bc: return((CHAR)(230 & 0xff));
- case 0x03bd: return((CHAR)(231 & 0xff));
- case 0x03be: return((CHAR)(232 & 0xff));
- case 0x03bf: return((CHAR)(233 & 0xff));
- case 0x03c0: return((CHAR)(234 & 0xff));
- case 0x03c1: return((CHAR)(235 & 0xff));
- case 0x03c2: return((CHAR)(237 & 0xff));
- case 0x03c3: return((CHAR)(236 & 0xff));
- case 0x03c4: return((CHAR)(238 & 0xff));
- case 0x03c5: return((CHAR)(242 & 0xff));
- case 0x03c6: return((CHAR)(243 & 0xff));
- case 0x03c7: return((CHAR)(244 & 0xff));
- case 0x03c8: return((CHAR)(246 & 0xff));
- case 0x03c9: return((CHAR)(250 & 0xff));
- case 0x03ca: return((CHAR)(160 & 0xff));
- case 0x03cb: return((CHAR)(251 & 0xff));
- case 0x03cc: return((CHAR)(162 & 0xff));
- case 0x03cd: return((CHAR)(163 & 0xff));
- case 0x03ce: return((CHAR)(253 & 0xff));
- case 0x2015: return((CHAR)(142 & 0xff));
- case 0x2018: return((CHAR)(139 & 0xff));
- case 0x2019: return((CHAR)(140 & 0xff));
- case 0x2500: return((CHAR)(196 & 0xff));
- case 0x2502: return((CHAR)(179 & 0xff));
- case 0x250c: return((CHAR)(218 & 0xff));
- case 0x2510: return((CHAR)(191 & 0xff));
- case 0x2514: return((CHAR)(192 & 0xff));
- case 0x2518: return((CHAR)(217 & 0xff));
- case 0x251c: return((CHAR)(195 & 0xff));
- case 0x2524: return((CHAR)(180 & 0xff));
- case 0x252c: return((CHAR)(194 & 0xff));
- case 0x2534: return((CHAR)(193 & 0xff));
- case 0x253c: return((CHAR)(197 & 0xff));
- case 0x2550: return((CHAR)(205 & 0xff));
- case 0x2551: return((CHAR)(186 & 0xff));
- case 0x2554: return((CHAR)(201 & 0xff));
- case 0x2557: return((CHAR)(187 & 0xff));
- case 0x255a: return((CHAR)(200 & 0xff));
- case 0x255d: return((CHAR)(188 & 0xff));
- case 0x2560: return((CHAR)(204 & 0xff));
- case 0x2563: return((CHAR)(185 & 0xff));
- case 0x2566: return((CHAR)(203 & 0xff));
- case 0x2569: return((CHAR)(202 & 0xff));
- case 0x256c: return((CHAR)(206 & 0xff));
- case 0x2580: return((CHAR)(223 & 0xff));
- case 0x2584: return((CHAR)(220 & 0xff));
- case 0x2588: return((CHAR)(219 & 0xff));
- case 0x2591: return((CHAR)(176 & 0xff));
- case 0x2592: return((CHAR)(177 & 0xff));
- case 0x2593: return((CHAR)(178 & 0xff));
- case 0x25a0: return((CHAR)(254 & 0xff));
- default: return(tx_cpsub(c)); /* For box characters etc */
- }
-}
-
-int /* PC Code Page C0 graphics */
-#ifdef CK_ANSIC
-tx_smiley(USHORT c)
-#else
-tx_smiley(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c > 0x1f)
- return(-1);
- switch (c) {
- case 0x00a0: return((CHAR)0 & 0x7f);
- case 0x00a7: return((CHAR)21 & 0x7f);
- case 0x00b6: return((CHAR)20 & 0x7f);
- case 0x2022: return((CHAR)7 & 0x7f);
- case 0x203c: return((CHAR)19 & 0x7f);
- case 0x2190: return((CHAR)27 & 0x7f);
- case 0x2191: return((CHAR)24 & 0x7f);
- case 0x2192: return((CHAR)26 & 0x7f);
- case 0x2193: return((CHAR)25 & 0x7f);
- case 0x2194: return((CHAR)29 & 0x7f);
- case 0x2195: return((CHAR)18 & 0x7f);
- case 0x21a8: return((CHAR)23 & 0x7f);
- case 0x2319: return((CHAR)28 & 0x7f);
- case 0x25ac: return((CHAR)22 & 0x7f);
- case 0x25b2: return((CHAR)30 & 0x7f);
- case 0x25ba: return((CHAR)16 & 0x7f);
- case 0x25bc: return((CHAR)31 & 0x7f);
- case 0x25c4: return((CHAR)17 & 0x7f);
- case 0x25d8: return((CHAR)8 & 0x7f);
- case 0x25d9: return((CHAR)10 & 0x7f);
- case 0x25ef: return((CHAR)9 & 0x7f);
- case 0x263a: return((CHAR)1 & 0x7f);
- case 0x263b: return((CHAR)2 & 0x7f);
- case 0x263c: return((CHAR)15 & 0x7f);
- case 0x2640: return((CHAR)12 & 0x7f);
- case 0x2642: return((CHAR)11 & 0x7f);
- case 0x2660: return((CHAR)6 & 0x7f);
- case 0x2663: return((CHAR)5 & 0x7f);
- case 0x2665: return((CHAR)3 & 0x7f);
- case 0x2666: return((CHAR)4 & 0x7f);
- case 0x266a: return((CHAR)13 & 0x7f);
- case 0x266c: return((CHAR)14 & 0x7f);
- default: return(-1);
- }
-}
-
-USHORT /* Horizontal Scan Lines Unicode substitutions */
-#ifdef CK_ANSIC
-tx_hslsub(USHORT c)
-#else
-tx_hslsub(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c >= 0x23BA && c <= 0x23BD )
- switch (c) {
- case 0x23BA: return(0x2500); /* H line - Scan 1 */
- case 0x23BB: return(0x2500); /* H line - Scan 3 */
- case 0x23BC: return(0x2500); /* H line - Scan 7 */
- case 0x23BD: return(0x2500); /* H line - Scan 9 */
- }
- return(c);
-}
-
-USHORT /* Kermit font 0xE??? Unicode substitutions */
-#ifdef CK_ANSIC
-tx_usub(USHORT c)
-#else
-tx_usub(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0xE000 || c > 0xEFFF)
- return(c);
- switch (c) {
- case 0xE200: return(0x2524); /* Extensible Left Brace Middle */
- case 0xE201: return(0x2570); /* Extensible Left Parenthesis bot */
- case 0xE202: return(0x256d); /* Extensible left parenthesis top */
- case 0xE203: return(0x2514); /* Extensible left SB bot */
- case 0xE204: return(0x250c); /* Extensible left SB top */
- case 0xE205: return(0x251c); /* Extensible right brace middle */
- case 0xE206: return(0x256f); /* Extensible right parenthesis bot */
- case 0xE207: return(0x256e); /* Extensible right parenthesis top */
- case 0xE208: return(0x2518); /* Extensible right SB bot */
- case 0xE209: return(0x2510); /* Extensible right SB top */
- case 0xE20C: return(0x03a3); /* Summation symbol bot */
- case 0xE20D: return(0x03a3); /* Summation symbol top */
- case 0xE20E: return(0x2510); /* Right ceiling corner */
- case 0xE20F: return(0x2518); /* Right floor corner */
- case 0xE300: return(0x2502); /* V box line, extensible, left */
- case 0xE309: return(0x2502); /* V box line, extensible, right */
- case 0xE30A: return(0x258c); /* Diagonal fill, dark, UL */
- case 0xE30B: return(0x2590); /* Diagonal fill, dark, UR */
- case 0xE320: return(0x2583); /* Quadrant LL */
- case 0xE321: return(0x2490); /* Quadrant LR */
- case 0xE322: return(0x258c); /* Quadrant UL */
- case 0xE323: return(0x2588); /* Quadrant UL and LL and LR */
- case 0xE324: return(0x2588); /* Quadrant UL and LR */
- case 0xE325: return(0x2588); /* Quadrant UL and LR */
- case 0xE326: return(0x2588); /* Quadrant UL and UR and LL */
- case 0xE327: return(0x2588); /* Quadrant UL and UR and LR */
- case 0xE328: return(0x2590); /* Quadrant UR */
- case 0xE329: return(0x2588); /* Quadrant UR and LL and LR */
- case 0xE400: return(0x221a); /* Radical symbol, small */
- case 0xE401: return(0x00bf); /* Reverse question mark */
- default: return((unsigned)0xfffd);
- }
-}
-
-int /* Unicode to CP437 substitutions */
-#ifdef CK_ANSIC
-tx_cpsub(USHORT c)
-#else
-tx_cpsub(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- int x;
- if (c < 0x0080) /* ASCII */
- return((CHAR)(c & 0xff));
-
- if (c >= 0x0080 && c <= 0x0100) {
- switch (c) { /* Latin-1 */
- case 0x00A2: return(0x9b); /* Cent sign */
- case 0x00A3: return(156); /* Pound sign */
- case 0x00AC: return(170); /* Not symbol */
- case 0x00B0: return(248); /* Degree symbol */
- case 0x00B1: return(241); /* Plus or minus symbol */
- case 0x00B2: return(253); /* Superscript 2 */
- case 0x00B3: return(51); /* Superscript 3 */
- case 0x00B6: return(14); /* Pilcrow symbol */
- case 0x00B7: return(250); /* Center dot, small */
- case 0x00B9: return(49); /* Superscript 1 */
- case 0x00D0: return(68); /* Eth -> D */
- case 0x00D7: return(120); /* Multiplication symbol */
- case 0x00DE: return(84); /* Thorn -> T */
- case 0x00F0: return(100); /* eth -> eth */
- case 0x00F7: return(246); /* Division symbol */
- case 0x00FE: return(116); /* thorn -> t */
- default: return(0x13);
- }
- } else if (c >= 0x0100 && c <= 0x02ff) { /* Latin-2 etc */
- switch (c) {
- case 0x0103: return(97); /* a breve */
- case 0x0105: return(97); /* a ogonek */
- case 0x0107: /* c acute */
- case 0x010d: return(99); /* c caron */
- case 0x010f: /* d caron */
- case 0x0111: return(100); /* d with stroke */
- case 0x0119: /* e ogonek */
- case 0x011b: return(101); /* e caron */
- case 0x011f: return(103); /* g breve */
- case 0x0130: return(73); /* Capital I with Dot */
- case 0x0131: return(105); /* Dotless i */
- case 0x0132: return(89); /* IJ => Y */
- case 0x0133: return(152); /* ij -> y diaeresis */
- case 0x013a: /* l acute */
- case 0x013e: /* l caron */
- case 0x0142: return(108); /* l with stroke */
- case 0x0144: /* n acute */
- case 0x0148: return(110); /* n caron */
- case 0x0151: return(111); /* o double acute */
- case 0x0152: return(79); /* OE */
- case 0x0153: return(111); /* oe */
- case 0x0155: /* r acute */
- case 0x0159: return(114); /* r caron */
- case 0x015b: /* s acute */
- case 0x015f: /* s ogonek */
- case 0x0161: return(115); /* s caron */
- case 0x0163: /* t ogonek */
- case 0x0165: /* t caron */
- case 0x0167: return(116); /* t with stroke */
- case 0x016f: /* u ring */
- case 0x0171: return(117); /* u double acute */
- case 0x017a: /* z acute */
- case 0x017c: /* z dot above */
- case 0x017e: return(122); /* z caron */
- case 0x0192: return(159); /* Function-of symbol, Script f */
- case 0x01d0: return(105); /* i caron */
- case 0x02c7: /* caron -> UNK */
- case 0x02d8: return(0x13); /* breve -> UNK */
- case 0x02dd: return(34); /* Double acute -> Doublequote */
- default: return(0x13);
- }
- } else if (c >= 0x0300 && c <= 0x03ff) { /* Greek */
- switch (c) {
- case 0x0393: return(226); /* Uppercase Greek Gamma */
- case 0x0398: return(233); /* Uppercase Greek Theta */
- case 0x039B: return(235); /* Uppercase Greek Lambda */
- case 0x03A0: return(227); /* Uppercase Greek Pi */
- case 0x03A3: return(228); /* Uppercase Greek Sigma */
- case 0x03A4: return(0xEA); /* Omega */
- case 0x03A6: return(232); /* Uppercase Greek Phi */
- case 0x03A9: return(234); /* Uppercase Greek Omega */
- case 0x03B1: return(0xE0); /* alpha */
- case 0x03B2: return(0xE1); /* beta */
- case 0x03B3: return(226); /* Lowercase Greek gamma */
- case 0x03B4: return(0xEB); /* delta */
- case 0x03B5: return(238); /* Lowercase Greek epsilon */
- case 0x03B7: return(238); /* Lowercase Greek eta */
- case 0x03B8: return(233); /* Lowercase Greek theta */
- case 0x03B9: return(105); /* Lowercase Greek iota */
- case 0x03BA: return(107); /* Lowercase Greek kappa */
- case 0x03BB: return(235); /* Lowercase Greek lambda */
- case 0x03BC: return(230); /* Lowercase Greek mu */
- case 0x03C0: return(227); /* Lowercase Greek pi */
- case 0x03C3: return(229); /* Lowercase Greek sigma */
- case 0x03C4: return(231); /* Lowercase Greek tau */
- case 0x03C6: return(237); /* Lowercase Greek phi */
- case 0x03C7: return(120); /* Lowercase Greek chi */
- case 0x03C9: return(234); /* Lowercase Greek omega */
- default: return(0x13);
- }
- } else if (c >= 0x2000 && c <= 0x20ff) { /* Sub+Superscripts & Currency */
- switch (c) {
- case 0x203C: return(0x13); /* !! */
- case 0x2070: return(48); /* Superscript 0 */
- case 0x2074: return(52); /* Superscript 4 */
- case 0x2075: return(53); /* Superscript 5 */
- case 0x2076: return(54); /* Superscript 6 */
- case 0x2077: return(55); /* Superscript 7 */
- case 0x2078: return(56); /* Superscript 8 */
- case 0x2079: return(57); /* Superscript 9 */
- case 0x207a: return(43); /* Superscript + */
- case 0x207b: return(45); /* Superscript - */
- case 0x207F: return(252); /* Superscript n */
- case 0x2080: return(48); /* Subscript 0 */
- case 0x2081: return(49); /* Subscript 1 */
- case 0x2082: return(50); /* Subscript 2 */
- case 0x2083: return(51); /* Subscript 3 */
- case 0x2084: return(52); /* Subscript 4 */
- case 0x2085: return(53); /* Subscript 5 */
- case 0x2086: return(54); /* Subscript 6 */
- case 0x2087: return(55); /* Subscript 7 */
- case 0x2088: return(56); /* Subscript 8 */
- case 0x2089: return(57); /* Subscript 9 */
- case 0x208a: return(43); /* Subscript + */
- case 0x208b: return(45); /* Subscript - */
- case 0x20a7: return(0x93); /* Peseta */
- default:
- x = tx_punc(c); /* Various spaces, dashes, etc */
- return((x < 0) ? 0x13 : x);
- }
- } else if (c >= 0x2100 && c <= 0x21ff) { /* Arrows */
- switch (c) {
- case 0x2190: return(27); /* Arrow, left-pointing */
- case 0x2191: return(24); /* Arrow, up-pointing */
- case 0x2192: return(26); /* Arrow, right-pointing */
- case 0x2193: return(25); /* Arrow, down-pointing */
- case 0x2194: return(0x1d); /* Arrow, left-right */
- case 0x2195: return(0x12); /* Arrow, up-down */
- case 0x219F: return(0x18); /* Arrow, up, doublehead */
- case 0x21A1: return(0x19); /* Arrow, down, doublehead */
- case 0x21A8: return(0x17); /* Arrow, up-down with base */
- case 0x21D2: return(26); /* Implies symbol */
- case 0x21D4: return(29); /* If and only if symbol */
- case 0x21E4: return(0x1B); /* Arrow, left, to bar */
- case 0x21E5: return(0x1A); /* Arrow, right, to bar */
- case 0x21E8: return(0x10); /* Outline white right arrow */
- case 0x21E9: return(0x0f); /* Outline white down arrow */
- default: return(0x13);
- }
- } else if (c >= 0x2200 && c <= 0x22ff) { /* Math */
- switch (c) {
- case 0x2202: return(235); /* Partial differential symbol */
- case 0x2207: return(31); /* Nabla, Laplace operator */
- case 0x2208: return(0x33); /* (because of QNX misunderstanding) */
- case 0x221A: return(251); /* Radical symbol */
- case 0x221D: return(236); /* Proportional-to */
- case 0x221E: return(236); /* Infinity symbol */
- case 0x2227: return(30); /* Logical AND */
- case 0x2228: return(31); /* Logical OR */
- case 0x2229: return(239); /* Intersection symbol */
- case 0x222A: return(85); /* Union symbol */
- case 0x222B: return(244); /* Integral symbol */
- case 0x2234: return(254); /* Therefore symbol */
- case 0x223C: return(126); /* Centered tilde operator */
- case 0x2243: return(247); /* Asymptotically equals */
- case 0x2248: return(247); /* Almost equal to symbol */
- case 0x2260: return(88); /* Not equal symbol */
- case 0x2261: return(240); /* Identity symbol */
- case 0x2264: return(243); /* Less than or equal symbol */
- case 0x2265: return(242); /* Greater than or equal symbol */
- case 0x2282: return(40); /* Subset symbol */
- case 0x2283: return(41); /* Superset symbol */
- case 0x22A6: return(0xC3); /* Assertion symbol */
- default: return(0x13);
- }
- } else if (c >= 0x23BA && c <= 0x23BD ) {
- switch (c) {
- case 0x23BA: return(0x2500); /* H line - Scan 1 */
- case 0x23BB: return(0x2500); /* H line - Scan 3 */
- case 0x23BC: return(0x2500); /* H line - Scan 7 */
- case 0x23BD: return(0x2500); /* H line - Scan 9 */
- }
- } else if (c >= 0x2300 && c <= 0x24ff) { /* Tech */
- switch (c) {
- case 0x2308: return(0xDA); /* Left ceiling */
- case 0x2309: return(0xBF); /* Right ceiling */
- case 0x230A: return(0xC0); /* Left floor */
- case 0x230B: return(0xD9); /* Right floor */
- case 0x2319: return(0x1C); /* Turned Not sign */
- case 0x2320: return(244); /* Integral symbol top */
- case 0x2321: return(245); /* Integral symbol bot */
- case 0x2329: return(60); /* BRA, large left angle bracket */
- case 0x232A: return(62); /* KET, large right angle bracket */
- case 0x2409: return(26); /* "HT" becomes right arrow */
- case 0x240A: return(25); /* "LF" becomes down arrow */
- case 0x240B: return(23); /* "VT" becomes up-down arrow */
- case 0x240C: return(24); /* "FF" becomes up arrow */
- case 0x240D: return(27); /* "CR" becomes left arrow */
- case 0x2424: return(31); /* "NL" becomes down triangle */
- default: return(0x13);
- }
- } else if (c >= 0x2500 && c <= 0x2552) { /* Box drawing */
- switch (c) {
- case 0x2500: return(196); /* Center box bar horizontal */
- case 0x2501: return(0xCD); /* Bold -> Double */
- case 0x2502: return(179); /* Center box bar vertical */
- case 0x2503: return(0xBA); /* Bold */
- case 0x2504: return(45); /* Dashed line */
- case 0x2506: return(124); /* Broken vertical bar */
- case 0x250C: return(218); /* UL box corner */
- case 0x250F: return(0xC9); /* Bold */
- case 0x2510: return(191); /* UR Box Corner */
- case 0x2513: return(0xBB); /* Bold */
- case 0x2514: return(192); /* LL box corner */
- case 0x2517: return(0xC8); /* Bold */
- case 0x2518: return(217); /* LR box corner */
- case 0x251B: return(0xBC); /* Bold */
- case 0x251C: return(195); /* Left middle box side */
- case 0x2520: return(0xC3);
- case 0x2523: return(0xCC); /* Bold */
- case 0x2524: return(180); /* Right middle box side */
- case 0x2528: return(180);
- case 0x252B: return(0xB9); /* Bold */
- case 0x252C: return(194); /* Middle box top */
- case 0x252F: return(194);
- case 0x2533: return(0xCB); /* Bold */
- case 0x2534: return(193); /* Middle box bot */
- case 0x2537: return(193);
- case 0x253B: return(0xCA); /* Bold */
- case 0x253C: return(197); /* Box intersection */
- case 0x253F: return(197);
- case 0x2542: return(197);
- case 0x2547: return(197);
- case 0x2548: return(197);
- case 0x2549: return(197);
- case 0x254A: return(197);
- case 0x254B: return(0xCE); /* Bold */
- case 0x2550: return(205); /* Center box bar horizontal double */
- case 0x2551: return(186); /* Center box bar vertical double */
- case 0x2552: return(213); /* UL box corner single to double */
- default: return(0x13);
- }
- } else if (c >= 0x2553 && c <= 0x2579) { /* More box drawing */
- switch (c) {
- case 0x2553: return(214); /* UL box corner double to single */
- case 0x2554: return(201); /* UL box corner double */
- case 0x2555: return(184); /* UR box corner double to single */
- case 0x2556: return(183); /* UR box corner single to double */
- case 0x2557: return(187); /* UR box corner double */
- case 0x2558: return(212); /* LL box corner single to double */
- case 0x2559: return(211); /* LL box corner double to single */
- case 0x255A: return(200); /* LL box corner double */
- case 0x255B: return(190); /* LR box corner double to single */
- case 0x255C: return(189); /* LR box corner single to double */
- case 0x255D: return(188); /* LR box corner double */
- case 0x255E: return(198); /* Left mid box side single to doubl */
- case 0x255F: return(199); /* Left mid box side double to singl */
- case 0x2560: return(204); /* Left middle box side double */
- case 0x2561: return(181); /* Right box side double to single */
- case 0x2562: return(182); /* Right box side single to double */
- case 0x2563: return(185); /* Right middle box side double */
- case 0x2564: return(209); /* Middle box top double to single */
- case 0x2565: return(210); /* Middle box top single to double */
- case 0x2566: return(203); /* Middle box top double */
- case 0x2567: return(207); /* Middle box bot single to double */
- case 0x2568: return(208); /* Middle box bot double to single */
- case 0x2569: return(202); /* Middle box bot double */
- case 0x256A: return(216); /* Box intersection double to single */
- case 0x256B: return(215); /* Box intersection single to double */
- case 0x256C: return(206); /* Box intersection double */
- case 0x256D: return(218); /* UL arc */
- case 0x256E: return(191); /* UR arc */
- case 0x256F: return(217); /* LR arc */
- case 0x2570: return(192); /* LL arc */
- case 0x2571: return(179); /* Diagonal line LL to UR */
- case 0x2572: return(196); /* Diagonal line UL to LR */
- case 0x2573: return(88); /* Diagonal lines crossed */
- case 0x2575: return(0xb3); /* High vertical line */
- case 0x2576: return(45); /* Short horizontal line */
- case 0x2577: return(0xb3); /* Low vertical line */
- case 0x2579: return(0xb3); /* High vertical line bold */
- default: return(0x13);
- }
- } else if (c >= 0x257a && c <= 0x25ff) { /* Still more box drawing */
- switch (c) {
- case 0x257b: return(0xb3); /* Low vertical line bold */
- case 0x2580: return(223); /* Quadrant UL and UR (top half) */
- case 0x2581: return(0xc4); /* Scan line 9 */
- case 0x2582: return(0xDC); /* Black blob lower half */
- case 0x2584: return(220); /* Quadrant LL and LR (lower half) */
- case 0x2588: return(219); /* Fill character dark */
- case 0x258C: return(221); /* Quadrant UL and LL (left half) */
- case 0x258E: return(0xDD);
- case 0x2590: return(222); /* Quadrant UR and LR (right half) */
- case 0x2591: return(176); /* Fill character light */
- case 0x2592: return(177); /* Fill character medium */
- case 0x2593: return(178); /* Fill character heavy */
- case 0x2594: return(0xc4); /* Scan line 1 */
- case 0x25A0: return(254); /* Solid square, center */
- case 0x25A6: return(177); /* Blotch */
- case 0x25AC: /* Black rectangle */
- case 0x25AF: return(0x16); /* White rectangle */
- case 0x25B2: /* Triangle, up-pointing */
- case 0x25B4: return(0x1e); /* Triangle, up-pointing */
- case 0x25B6: /* Triangle, right-pointing, dark */
- case 0x25B7: /* Triangle, right-pointing, light */
- case 0x25B9: /* Triangle, right-pointing, light */
- case 0x25BA: return(0x10); /* Triangle, right-pointing, narrow */
- case 0x25BC: /* Triangle, down-pointing */
- case 0x25BE: return(0x1f); /* Triangle, down-pointing */
- case 0x25C0: /* Triangle, left-pointing, dark */
- case 0x25C1: /* Triangle, left-pointing, dark */
- case 0x25C4: return(0x11); /* Triangle, left-pointing, narrow */
- case 0x25C6: return(4); /* Diamond, center, solid */
- case 0x25CB: return(0x09); /* Circle */
- case 0x25CF: return(249); /* Center dot, large */
- case 0x25d8: return(0x08); /* Inverse bullet */
- case 0x25d9: return(0x0a); /* Inverse white circle */
- case 0x25E2: return(0xD9); /* Lower right triangle */
- case 0x25E3: return(0xC0); /* Lower left triangle */
- case 0x25E4: return(0xDA); /* Upper left triangle */
- case 0x25E5: return(0xBf); /* Upper right triangle */
- default: return(0x13);
- }
- } else if (c >= 0x2600) { /* All the rest */
- switch (c) {
- case 0x263a: return(0x01); /* Smiley */
- case 0x263b: return(0x02); /* Inverse Smiley */
- case 0x263c: return(0x0f); /* White Sun with Rays */
- case 0x2640: return(0x0c); /* Male sign */
- case 0x2642: return(0x0b); /* Female sign */
- case 0x2660: return(0x06); /* Spade */
- case 0x2663: return(0x05); /* Club */
- case 0x2665: return(0x03); /* Heart */
- case 0x2666: return(0x04); /* Diamond, center, solid */
- case 0x266a: return(0x0d); /* Quarter note */
- case 0x266b: /* Beamed quarter notes */
- case 0x266c: return(0x0e); /* Beamed 8th notes */
- case 0x279e: return(0x1a); /* Bold right arrow */
- case 0x27a1: return(0x1a); /* Heavy black right arrow. */
- case 0xE200: return(180); /* Extensible left brace middle */
- case 0xE201: return(192); /* Extensible Left parenthesis bot */
- case 0xE202: return(218); /* Extensible left parenthesis top */
- case 0xE203: return(192); /* Extensible left SB bot */
- case 0xE204: return(218); /* Extensible left SB top */
- case 0xE205: return(195); /* Extensible right brace middle */
- case 0xE206: return(217); /* Extensible right parenthesis bot */
- case 0xE207: return(191); /* Extensible right parenthesis top */
- case 0xE208: return(217); /* Extensible right SB bot */
- case 0xE209: return(191); /* Extensible right SB top */
- case 0xE20C: return(228); /* Summation symbol bot */
- case 0xE20D: return(228); /* Summation symbol top */
- case 0xE20E: return(191); /* Right ceiling corner */
- case 0xE20F: return(217); /* Right floor corner */
- case 0xE300: return(179); /* V box line, extensible, left */
- case 0xE309: return(179); /* V box line, extensible, right */
- case 0xE30A: return(221); /* Diagonal fill, dark, UL */
- case 0xE30B: return(222); /* Diagonal fill, dark, UR */
- case 0xE320: return(221); /* Quadrant LL */
- case 0xE321: return(222); /* Quadrant LR */
- case 0xE322: return(221); /* Quadrant UL */
- case 0xE323: return(219); /* Quadrant UL and LL and LR */
- case 0xE324: return(219); /* Quadrant UL and LR */
- case 0xE325: return(219); /* Quadrant UL and LR */
- case 0xE326: return(219); /* Quadrant UL and UR and LL */
- case 0xE327: return(219); /* Quadrant UL and UR and LR */
- case 0xE328: return(222); /* Quadrant UR */
- case 0xE329: return(219); /* Quadrant UR and LL and LR */
- case 0xE400: return(251); /* Radical symbol, small */
- case 0xE401: return(168); /* Reverse question mark */
- case 0xFFFD: return(0x13); /* !! for unknown */
- default: return(0x13);
- }
- }
- return(0x13);
-}
-
-#ifdef OS2
-/*
- Lucida Console is a Unicode font, but it is very sparsely populated.
- Since it is the only monospace Unicode font most people have, we have
- to make reasonable substitutions or else 3/4 of the glyphs will show
- up as blobs on the screen.
-*/
-USHORT /* Unicode to Lucida Console */
-#ifdef CK_ANSIC
-tx_lucidasub(USHORT c)
-#else
-tx_lucidasub(c) USHORT c;
-#endif /* CK_ANSIC */
-{
- if (c < 0x0180) /* Latin-1 and Extended A */
- return(c);
-
-/* For efficiency we try to arrange the sections by frequency of use. */
- if (c >= 0x23BA && c <= 0x23BD) {
- switch(c) {
- case 0x23BA: /* H line - Scan 1 */
- case 0x23BB: /* H line - Scan 3 */
- case 0x23BC: /* H line - Scan 7 */
- case 0x23BD: /* H line - Scan 9 */
- return(0x2500);
- }
- }
- if (c >= 0x2500 && c <= 0x257f) { /* Box drawing */
- if (c >= 0x2550 && c <= 0x256c)
- return(c);
- switch (c) {
- /* Themselves */
- case 0x2500:
- case 0x2502:
- case 0x250c:
- case 0x2510:
- case 0x2514:
- case 0x2518:
- case 0x251c:
- case 0x2524:
- case 0x252c:
- case 0x2534:
- case 0x253c:
- return(c);
- /* Horizontal lines */
- case 0x2501: /* Bold */
- return(0x2550); /* Use double */
- case 0x2504:
- case 0x2505:
- case 0x2508:
- case 0x2509:
- case 0x254c:
- case 0x254d:
- case 0x257c:
- case 0x257e:
- return(0x2500);
- /* Vertical lines */
- case 0x2503: /* Bold */
- return(0x2551); /* Use double */
- case 0x2506:
- case 0x2507:
- case 0x250a:
- case 0x250b: /* Other */
- case 0x254e:
- case 0x254f:
- case 0x257d:
- case 0x257f:
- case 0x2575:
- case 0x2577:
- case 0x2579:
- case 0x257b:
- return(0x2502);
- /* Upper left box corner */
- case 0x250f: /* Bold */
- return(0x2554); /* Use double */
- case 0x250d: case 0x250e: /* Other */
- return(0x250c);
- /* Upper right box corner */
- case 0x2513: /* Bold */
- return(0x2557);
- case 0x2511:
- case 0x2512: /* Other */
- return(0x2510);
- /* Lower left box corner */
- case 0x2517: /* Bold */
- return(0x255a);
- case 0x2515:
- case 0x2516: /* Other */
- return(0x2514);
- /* Lower right box corner */
- case 0x251b: /* Bold */
- return(0x255d);
- case 0x2519:
- case 0x251a: /* Other */
- return(0x2518);
- /* Vertical and right */
- case 0x2523: /* Bold */
- return(0x2560);
- case 0x251d:
- case 0x251e:
- case 0x251f:
- case 0x2520:
- case 0x2521:
- case 0x2522:
- return(0x251c);
- /* Vertical and left */
- case 0x252b: /* Bold */
- return(0x2563);
- case 0x2525:
- case 0x2526:
- case 0x2527:
- case 0x2528:
- case 0x2529:
- case 0x252a:
- return(0x2524);
- /* Horizontal and down */
- case 0x2533: /* Bold */
- return(0x2566);
- case 0x252d:
- case 0x252e:
- case 0x252f:
- case 0x2530:
- case 0x2531:
- case 0x2532:
- return(0x252c);
- /* Horizontal and up */
- case 0x253b: /* Bold */
- return(0x2569);
- case 0x2535: case 0x2536: case 0x2537:
- case 0x2538: case 0x2539: case 0x253a:
- return(0x2534);
- /* Horizontal and Vertical */
- case 0x254b: /* Bold */
- return(0x256c);
- case 0x253d: case 0x253e: case 0x253f:
- case 0x2540: case 0x2541: case 0x2542: case 0x2543:
- case 0x2544: case 0x2545: case 0x2546: case 0x2547:
- case 0x2548: case 0x2549: case 0x254a:
- return(0x253c);
- /* Curved corners */
- case 0x256d: /* UL */
- return(0x250c);
- case 0x256e: /* UR */
- return(0x2510);
- case 0x256f: /* LL */
- return(0x2518);
- case 0x2570: /* LR */
- return(0x2514);
- case 0x2571: /* Diagonal */
- return(0x002f);
- case 0x2572: /* Other diagonal */
- return(0x005c);
- case 0x2573: /* Diagonal cross */
- return(0x00d7);
- /* Partial horizontal lines */
- case 0x2574: case 0x2576: case 0x2578: case 0x257a:
- return(0x002d);
- default:
- return(0xfffd);
- }
- }
- if (c >= 0x2190 && c <= 0x21ff) { /* Arrows */
- if (c >= 0x2190 && c <= 0x2195 || c == 0x21a8)
- return(c);
- switch (c) {
- /* Left-arrow forms */
- case 0x219e: case 0x21a2: case 0x21a4: case 0x21a9:
- case 0x21bc: case 0x21d0: case 0x21da: case 0x21dc:
- case 0x21e0: case 0x21e4: case 0x21e6: case 0x21c7:
- return(0x2190);
- /* Right-arrow forms */
- case 0x21a0: case 0x21a3: case 0x21a6: case 0x21aa:
- case 0x21c0: case 0x21c1: case 0x21c9: case 0x21d2:
- case 0x21db: case 0x21dd: case 0x21e2: case 0x21e5:
- case 0x21e8:
- return(0x2192);
- /* Up-arrow forms */
- case 0x219f: case 0x21a5: case 0x21be: case 0x21bf:
- case 0x21c8: case 0x21d1: case 0x21de: case 0x21e1:
- case 0x21e7: case 0x21ea:
- return(0x2191);
- /* Down-arrow forms */
- case 0x21a1: case 0x21a7: case 0x21af: case 0x21c2:
- case 0x21ce: case 0x21ca: case 0x21d3: case 0x21df:
- case 0x21e3: case 0x21e9:
- return(0x2193);
- /* Up-down-arrow forms */
- case 0x21c5: case 0x21d5:
- return(0x2195);
- default:
- return(0xfffd);
- }
- }
- if (c >= 0x2580 && c <= 0x259f) { /* Block elements */
- switch (c) {
- case 0x2580: case 0x2584: case 0x2588: case 0x258c:
- case 0x2590: case 0x2591: case 0x2592: case 0x2593:
- return(c);
- case 0x2581: case 0x2582: case 0x2583:
- case 0x2585: case 0x2586: case 0x2587:
- return(0x2584);
- case 0x2589: case 0x258a: case 0x258b:
- case 0x258d: case 0x258e: case 0x258f:
- return(0x258c);
- case 0x2595:
- return(0x2502);
- default:
- return(0xfffd);
- }
- }
- if (c >= 0x2200 && c <= 0x22ff) { /* Mathematical operators */
- switch (c) {
- case 0x2202: case 0x2206: case 0x220f: case 0x2211: case 0x2212:
- case 0x2219: case 0x2220: case 0x221e: case 0x221f: case 0x2229:
- case 0x222b: case 0x2248: case 0x2260: case 0x2261: case 0x2264:
- case 0x2265:
- return(c);
- default:
- return(0xfffd);
- }
- }
- if (c >= 0x2300 && c <= 0x237f) { /* Miscellaneous Technical */
- if (c == 0x2302 || c == 0x2310 || c == 0x2320 || c == 0x2321)
- return(c);
- switch (c) {
- case 0x2329: /* BRA */
- return(0x003c);
- case 0x232a: /* KET */
- return(0x003e);
- default:
- return(0xfffd);
- }
- }
- if (c >= 0x25a0 && c <= 0x25ff) { /* Geometric shapes */
- switch (c) {
- /* Themselves */
- case 0x25a0: case 0x25ac: case 0x25b2: case 0x25ba:
- case 0x25bc: case 0x25c4: case 0x25ca: case 0x25cb:
- case 0x25d8: case 0x25d9:
- return(c);
- /* Squares */
- case 0x25a1: case 0x25a2: case 0x25a3: case 0x25a4:
- case 0x25a5: case 0x25a6: case 0x25a7: case 0x25a8:
- case 0x25a9: case 0x25aa: case 0x25ab:
- case 0x25e7: case 0x25e8: case 0x25e9: case 0x25ea: case 0x25eb:
- return(0x25a0);
- case 0x25ad: case 0x25ae: case 0x25af: /* Rectangles */
- case 0x25b0: case 0x25b1:
- return(0x25ac);
- case 0x25b3: case 0x25b4: case 0x25b5: /* Upright triangles */
- case 0x25ec: case 0x25ed: case 0x25ee:
- return(0x25b2);
- case 0x25b6: case 0x25b7: case 0x25b8: case 0x25b9: case 0x25bb:
- return(0x25ba); /* Right-pointing triangles */
- case 0x25bd: case 0x25be: case 0x25bf: /* Down-pointing triangles */
- return(0x25bc);
- case 0x25c0: case 0x25c1: case 0x25c2: case 0x25c3: case 0x25c5:
- return(0x25c4); /* Left-pointing triangles */
- case 0x25c6: case 0x25c7: case 0x25c8: /* Diamonds */
- return(0x2666);
- /* Circles */
- case 0x25c9: case 0x25cc: case 0x25cd: case 0x25ce: case 0x25cf:
- case 0x25d0: case 0x25d1: case 0x25d2: case 0x25d3: case 0x25d4:
- case 0x25d5: case 0x25e6: case 0x25ef:
- return(0x25cb);
- /* Curves and corner triangles */
- case 0x25dc: case 0x25e4: /* UL */
- return(0x250c);
- case 0x25dd: case 0x25e5: /* UR */
- return(0x2510);
- case 0x25df: case 0x25e3: /* LL */
- return(0x2514);
- case 0x25de: case 0x25e2: /* LR */
- return(0x2518);
- default:
- return(0xfffd);
- }
- }
- if (c >= 0x2600 && c <= 0x26ff) { /* Misc symbols */
- switch (c) {
- /* Themselves */
- case 0x263a: case 0x263b: case 0x263c: case 0x2640:
- case 0x2642: case 0x2660: case 0x2663: case 0x2665:
- case 0x2666: case 0x266a: case 0x266b:
- return(c);
- default:
- return(0xfffd);
- }
- }
- if (c >= 0x2794 && c <= 0x27be) /* Right-arrow Dingbats */
- return(0x2192);
- if (c >= 0x2070 && c <= 0x209f) { /* Super & subscripts */
- if (c == 0x207f) /* n */
- return(c);
- else if (c == 0x2070) /* 0 */
- return(0x0030);
- else if (c >= 0x2074 && c <= 0x2079)
- return(c - 0x2040);
- else if (c >= 0x2080 && c <= 0x2089)
- return(c - 0x2050);
- switch (c) {
- case 0x207a: case 0x208a:
- return(0x002b);
- case 0x207b: case 0x208b:
- return(0x002d);
- case 0x207c: case 0x208c:
- return(0x003d);
- case 0x207d: case 0x208d:
- return(0x0028);
- case 0x207e: case 0x208e:
- return(0x0029);
- default:
- return(0xfffd);
- }
- }
- if (c >= 0x0180 && c <= 0x024f) { /* Latin Extended B, Part I */
- if (c == 0x0192 || c >= 0x01fa && c <= 0x01ff)
- return(c); /* Latin Extended B */
- switch (c) {
- case 0x0180: case 0x0183: case 0x0184: case 0x0185:
- return(0x0062); /* Lowercase b variants */
- case 0x0181: case 0x0182:
- return(0x0042); /* Uppercase B variants */
- case 0x0186: case 0x0187:
- return(0x0043); /* Uppercase C variants */
- case 0x0189: /* D with stroke */
- return(0x00D0); /* Looks just like Eth */
- case 0x018a: /* D with hook */
- return(0x0044);
- case 0x018e: case 0x0190: /* E-like letters */
- return(0x0045);
- case 0x018f: /* e-like letters */
- return(0x0065);
- case 0x0191: /* F-like */
- return(0x0046);
- case 0x0193: /* G-like */
- return(0x0047);
- case 0x0194: /* Latin Capital Gamma */
- return(0x0393); /* Use Greek */
- case 0x0195: /* Gothic hv */
- return(0x0068); /* Use h */
- case 0x0196: /* Latin Capital Iota */
- return(0x0399); /* Use Greek */
- case 0x0197: /* I with bar */
- return(0x0069);
- case 0x0198: /* K with hook */
- return(0x004B);
- case 0x0199: /* k with hook */
- return(0x006B);
- case 0x019A: /* l with bar */
- return(0x006C);
- case 0x019B: /* lambda with bar */
- return(0x03bb); /* Use Greek */
- case 0x019C: /* Upside down m */
- return(0x006d);
- case 0x019D: /* N with left hook */
- return(0x004e);
- case 0x019E: /* n with long right leg */
- return(0x006e);
- case 0x019F: case 0x01a0: case 0x01a2: /* O-like letters */
- return(0x004f);
- case 0x01a1: case 0x01a3: /* o-like */
- return(0x006f);
- case 0x01A4: /* P with hook */
- return(0x0050);
- case 0x01A5: /* p with hook */
- return(0x0070);
- case 0x01A6: /* Old Norse YR */
- return(0x0052);
- case 0x01A7: /* Backwards S */
- return(0x0053);
- case 0x01A8: case 0x01AA: /* s-like letters */
- return(0x0073);
- case 0x01A9: /* Esh */
- return(0x03a3); /* Looks just like Sigma */
- case 0x01AB: case 0x01AD: /* t-like */
- return(0x0074);
- case 0x01AC: case 0x01AE: /* T-like */
- return(0x0054);
- case 0x01AF: case 0x01B1: /* U-like */
- return(0x0055);
- case 0x01B0: /* u-like */
- return(0x0075);
- case 0x01B2: /* V-like */
- return(0x0056);
- case 0x01B3: /* Y-like */
- return(0x0059);
- case 0x01B4: /* y-like */
- return(0x0079);
- case 0x01B5: /* Z-like */
- return(0x005a);
- case 0x01B6: /* z-like */
- return(0x007a);
- case 0x01B7: /* Yogh */
- return(0x0033); /* Use "3" */
- case 0x01BF: /* Wynn */
- return(0x0077); /* Use "w" */
- case 0x01CD: /* A caron */
- return(0x0041);
- case 0x01CE: /* a caron */
- return(0x0061);
- case 0x01CF: /* I caron */
- return(0x0049);
- case 0x01D0: /* i caron */
- return(0x0069);
- case 0x01D1: /* O caron */
- return(0x004f);
- case 0x01D2: /* o caron */
- return(0x006f);
- case 0x01D3: /* U caron */
- return(0x0055);
- case 0x01D4: /* u caron */
- return(0x0075);
- /* U diaeresis + other things */
- case 0x01D5: case 0x01D7: case 0x01D9: case 0x01DB:
- return(0x00dc);
- /* u diaeresis + other things */
- case 0x01D6: case 0x01Da: case 0x01Dc:
- return(0x00fc);
-
- /* Fill in more here if anybody asks */
-
- default:
- return(0xfffd);
- }
- }
- if (c >= 0x1e00 && c <= 0x1eff) { /* Latin Extended Additional */
- if (c >= 0x1e80 && c <= 0x1e85)
- return(c);
- else
- return(0xfffd);
- }
- if (c >= 0x0400 && c <= 0x04ff) { /* Cyrillic */
- if (c >= 0x0400 && c <= 0x045f || c == 0x0490 || c == 0x0491)
- return(c);
- else
- return(0xfffd);
- }
- if (c >= 0x0370 && c <= 0x03ff) { /* Greek */
- if (c == 0x037e || c >= 0x0384 && c <= 0x03ce)
- return(c);
- switch (c) {
- case 0x0374: case 0x0375:
- return(0x0027);
- case 0x037a:
- return(0x002c);
- /* Fill in more here if needed */
- default:
- return(0xfffd);
- }
- }
- if (c >= 0x1f00 && c <= 0x1fff) { /* Greek Extended */
- /* Fill in if asked */
- return(0xfffd);
- }
- if (c >= 0x20a0 && c <= 0x20cf) { /* Currency symbols */
- if (c == 0x20a3 || c == 0x20a4 || c == 0x20a7 || c == 0x20ac)
- return(c);
- else
- return(0xfffd);
- }
- if (c >= 0x2100 && c <= 0x214f) { /* Letterlike symbols */
- if (c == 0x2116 || c == 0x2122 || c == 0x2126)
- return(c);
- else
- return(0xfffd);
- }
- if (c >= 0x2150 && c <= 0x218f) { /* Number forms */
- if (c >= 0x215b && c <= 0x215e) /* Roman numerals etc */
- return(c);
- else
- return(0xfffd);
- }
- if (c >= 0x02b0 && c <= 0x02ff) { /* Spacing modifier letters */
- if (c == 0x02c6 || c == 0x02c7 || c == 0x02c9 ||
- c >= 0x02d8 && c <= 0x02dd)
- return(c);
- switch (c) {
- case 0x02b0: case 0x02b1:
- return(0x0068);
- case 0x02b2:
- return(0x006a);
- case 0x02b3: case 0x02b4: case 0x02b5:
- return(0x0072);
- case 0x02b7:
- return(0x0077);
- case 0x02b8:
- return(0x0079);
- case 0x02b9:
- return(0x00b4);
- case 0x02ba:
- return(0x0022);
- case 0x02bb: case 0x02bc: case 0x02bd: case 0x02be: case 0x02bf:
- return(0x0027);
- case 0x02c2: return(0x003c);
- case 0x02c3: return(0x003e);
- case 0x02da: return(0x00b0);
- case 0x02dc: return(0x007e);
- default: return(0xfffd);
- }
- }
- if (c >= 0x2000 && c <= 0x206f) { /* General Punctuation */
- if (c >= 0x2013 && c <= 0x2015 ||
- c >= 0x2017 && c <= 0x201a ||
- c >= 0x201c && c <= 0x201e ||
- c >= 0x2020 && c <= 0x2022 || c == 0x2026 || c == 0x2030 ||
- c >= 0x2039 && c <= 0x203a || c == 0x203c || c == 0x203e ||
- c == 0x2044)
- return(c);
- else if (c == 0x2016)
- return(0x2551);
- else if (c == 0x2017)
- return(0x2550);
- else if (c == 0x2044)
- return(0x002f);
- else
- return(0xfffd);
- }
- if (c == 0xfb01 || c == 0xfb02) /* Alphabetic Presentation Forms */
- return(c);
- return(0xfffd); /* Catch-all */
-}
-#endif /* OS2 */
-
-
-/*
- Table of Blah-to-Unicode information structures.
- KEEP THIS IN SYNC WITH THE TX_blah DEFINITIONS in ckcuni.h.
-*/
-struct x_to_unicode *
-txrinfo[MAXTXSETS+1] = {
- &u_ascii, /* 0 US ISO 646 (ASCII) */
- &u_british, /* 1 UK ISO 646 */
- &u_fr_canadian, /* 2 Canadian French NRC */
- NULL, /* 3 Cuba */
- NULL, /* 4 Czecho */
- &u_danish, /* 5 Danish/Norwegian ISO 646 */
- &u_dutch, /* 6 Dutch NRC */
- &u_finnish, /* 7 Finnish NRC */
- &u_french, /* 8 French ISO 646 */
- &u_german, /* 9 German ISO 646 */
- &u_hebrew7, /* 10 Hebrew-7 (DEC) */
- &u_hungarian, /* 11 Hungarian ISO 646 */
- &u_icelandic, /* 12 Icelandic NRC */
- &u_italian, /* 13 Italian ISO 646 */
- &u_jis0201r, /* 14 Japanese Roman ISO 646 */
- &u_jis0201k, /* 15 Japanese Katakana */
- &u_koi7, /* 16 Short KOI */
- &u_danish, /* 17 Norwegian/Danish ISO 646 */
- &u_portuguese, /* 18 Portuguese ISO 646 */
- &u_spanish, /* 19 spanish ISO 646 */
- &u_swedish, /* 20 Swedish ISO 646 */
- NULL, /* 21 Swedish ISO 646 for names */
- &u_swiss, /* 22 Swiss NRC */
- &u_8859_1, /* 23 ISO 8859-1 */
- &u_8859_2, /* 24 ISO 8859-2 */
- &u_8859_3, /* 25 ISO 8859-3 */
- &u_8859_4, /* 26 ISO 8859-4 */
- &u_8859_5, /* 27 ISO 8859-5 */ /* Cyrillic */
- &u_8859_6, /* 28 ISO 8859-6 */ /* Arabic */
- &u_8859_7, /* 29 ISO 8859-7 */ /* Greek */
- &u_8859_8, /* 30 ISO 8859-8 */ /* Hebrew */
- &u_8859_9, /* 31 ISO 8859-9 */
- &u_8859_10, /* 32 ISO 8859-10 */
- &u_koi8, /* 33 KOI-8 */
- NULL, /* 34 JIS-7 */
- NULL, /* 35 Shift JIS */
- NULL, /* 36 Japanese EUC (JAE) */
- NULL, /* 37 Japanese DEC Kanji */
- &u_decmcs, /* 38 DEC MCS */
- &u_nextstep, /* 39 NeXT */
- &u_dgi, /* 40 DGI */
- &u_maclatin, /* 41 Macintosh Latin */
- &u_hproman8, /* 42 HP Roman 8 */
- &u_cp437, /* 43 CP437 - Original */
- &u_cp850, /* 44 CP850 - W Europe */
- &u_cp852, /* 45 CP852 - E Europe */
- &u_cp857, /* 46 CP857 - Turkish */
- &u_cp862, /* 47 CP862 - Hebrew */
- &u_cp864, /* 48 CP864 - Arabic */
- &u_cp866, /* 49 CP866 - Cyrillic */
- &u_cp869, /* 50 CP869 - Greek */
- &u_decspec, /* 51 DEC Special Graphics */
- &u_dectech, /* 52 DEC Technical */
- &u_c0pics, /* 53 C0 Pictures */
- &u_c1pics, /* 54 C1 Pictures */
- &u_smiley, /* 55 IBM C0 Graphics */
- &u_heath19g, /* 56 Heath 19 Graphics */
- &u_tvig, /* 57 TVI Graphics */
- &u_wyse_gn, /* 58 Wyse 60 Graphics Normal */
- &u_wyse_g1, /* 59 Wyse 60 Graphics 1 */
- &u_wyse_g2, /* 60 Wyse 60 Graphics 2 */
- &u_wyse_g3, /* 61 Wyse 60 Graphics 3 */
- &u_elot927, /* 62 Greek ELOT 927 */
- &u_dgspec, /* 63 DG Special graphics */
- &u_dgline, /* 64 DG Line drawing */
- &u_dgword, /* 65 DG Word processing */
- &u_hpline, /* 66 HP Line drawing */
- &u_hpmath, /* 67 HP Math/Technical */
- &u_qnxgrph, /* 68 QNX Graphics */
- &u_snibrack, /* 69 SNI Brackets */
- &u_snieuro, /* 70 SNI Euro */
- &u_snifacet, /* 71 SNI Facet */
- &u_sniibm, /* 72 SNI IBM */
- &u_sniblanks, /* 73 SNI Blanks */
- &u_cp1252, /* 74 Windows Latin-1 */
- &u_cp1250, /* 75 Windows Latin-2 */
- &u_cp1251, /* 76 Windows Cyrillic */
- &u_cp1253, /* 77 Windows Greek */
- &u_cp1254, /* 78 Windows Turkish */
- &u_cp1257, /* 79 Windows Latin-4 */
- &u_cp856, /* 80 Cyrillic PC Code Page 856 */
- &u_cp855, /* 81 Cyrillic PC Code Page 855 */
- &u_8859_1, /* 82 CP819 - Same as 8859-1 */
- &u_8859_2, /* 83 CP912 - Same as 8859-2 */
- &u_8859_3, /* 84 CP913 - Same as 8859-3 */
- &u_8859_4, /* 85 CP914 - Same as 8859-4 */
- &u_8859_5, /* 86 CP915 - Same as 8859-5 */
- &u_8859_6, /* 87 CP1089 - Same as 8859-6 */
- &u_8859_7, /* 88 CP813 - Same as 8859-7 */
- &u_8859_8, /* 89 CP916 - Same as 8859-8 */
- &u_8859_9, /* 90 CP920 - Same as 8859-9 */
- &u_hproman8, /* 91 CP1051 - Same as HP Roman 8 */
- &u_cp858, /* 92 CP858 - W Europe w/Euro */
- &u_8859_15, /* 93 ISO 8859-15 Latin-15 */
- &u_8859_15, /* 94 CP923 - Same as 8859-15 */
- &u_8859_7, /* 95 ELOT928 - Same as 8859-7 */
- &u_quickdraw, /* 96 CP10000 - Apple Quickdraw */
- &u_cp37, /* 97 CP37 - U.S. EBCDIC */
- &u_cp1255, /* 98 CP1255 - Windows Hebrew */
- &u_cp1256, /* 99 CP1256 - Windows Arabic */
- &u_cp1258, /* 100 CP1258 - Windows Viet Nam */
- &u_mazovia, /* 101 Mazovia Polish code page */
- &u_transparent, /* 102 Transparent */
- &u_hz1500, /* 103 Hazeltine 1500/1520 graphics */
- &u_koi8r, /* 104 KOI8-R */
- &u_koi8u, /* 105 KOI8-U */
- &u_apl1, /* 106 APL 1 (ISO) */
- &u_apl2, /* 107 APL 2 (Dyadic) */
- &u_apl3, /* 108 APL 3 (Plus) */
- &u_apl4, /* 108 APL 4 (IBM) */
- &u_apl5 /* 110 APL 5 (2741) */
-};
-
-/*
- Table of Blah-to-Unicode translation functions.
- KEEP THIS IN SYNC WITH THE TX_blah DEFINITITIONS in ckcuni.h.
-*/
-USHORT
-#ifdef CK_ANSIC
-(*xl_u[MAXTXSETS+1])(CHAR)
-#else
-(*xl_u[MAXTXSETS+1])()
-#endif /* CK_ANSIC */
-= {
- ascii_u, /* 0 US ISO 646 (ASCII) */
- british_u, /* 1 UK ISO 646 */
- fr_canadian_u, /* 2 Canadian French NRC */
- NULL, /* 3 Cuba */
- NULL, /* 4 Czecho */
- danish_u, /* 5 Danish/Norwegian ISO 646 */
- dutch_u, /* 6 Dutch NRC */
- finnish_u, /* 7 Finnish NRC */
- french_u, /* 8 French ISO 646 */
- german_u, /* 9 German ISO 646 */
- hebrew7_u, /* 10 Hebrew-7 (DEC) */
- hungarian_u, /* 11 Hungarian ISO 646 */
- icelandic_u, /* 12 Icelandic */
- italian_u, /* 13 Italian ISO 646 */
- jis0201r_u, /* 14 Japanese Roman ISO 646 */
- jis0201k_u, /* 15 Japanese Katakana */
- koi7_u, /* 16 Short KOI */
- danish_u, /* 17 Norwegian/Danish ISO 646 */
- portuguese_u, /* 18 Portuguese ISO 646 */
- spanish_u, /* 19 spanish ISO 646 */
- swedish_u, /* 20 Swedish ISO 646 */
- NULL, /* 21 Swedish ISO 646 for names */
- swiss_u, /* 22 Swiss NRC */
- iso_8859_1_u, /* 23 ISO 8859-1 */
- iso_8859_2_u, /* 24 ISO 8859-2 */
- iso_8859_3_u, /* 25 ISO 8859-3 */
- iso_8859_4_u, /* 26 ISO 8859-4 */
- iso_8859_5_u, /* 27 ISO 8859-5 */ /* Cyrillic */
- iso_8859_6_u, /* 28 ISO 8859-6 */ /* Arabic */
- iso_8859_7_u, /* 29 ISO 8859-7 */ /* Greek */
- iso_8859_8_u, /* 30 ISO 8859-8 */ /* Hebrew */
- iso_8859_9_u, /* 31 ISO 8859-9 */ /* Latin-5 */
- iso_8859_10_u, /* 32 ISO 8859-10 */
- koi8_u, /* 33 KOI-8 */
- NULL, /* 34 JIS-7 */
- NULL, /* 35 Shift JIS */
- NULL, /* 36 Japanese EUC (JAE) */
- NULL, /* 37 Japanese DEC Kanji */
- decmcs_u, /* 38 DEC MCS */
- nextstep_u, /* 39 NeXT */
- dgi_u, /* 40 DGI */
- maclatin_u, /* 41 Macintosh Latin */
- hproman8_u, /* 42 HP Roman 8 */
- cp437_u, /* 43 CP437 - Original */
- cp850_u, /* 44 CP850 - W Europe */
- cp852_u, /* 45 CP852 - E Europe */
- cp857_u, /* 46 CP857 - Turkish */
- cp862_u, /* 47 CP862 - Hebrew */
- cp864_u, /* 48 CP864 - Arabic */
- cp866_u, /* 49 CP866 - Cyrillic */
- cp869_u, /* 50 CP869 - Greek */
- decspec_u, /* 51 DEC Special Graphics */
- dectech_u, /* 52 DEC Technical */
- c0pics_u, /* 53 C0 Pictures */
- c1pics_u, /* 54 C1 Pictures */
- smiley_u, /* 55 IBM C0 Graphics */
- heath19g_u, /* 56 Heath 19 graphics */
- tvig_u, /* 57 TVI graphics */
- wyse_gn_u, /* 58 Wyse 60 normal-mode graphics */
- wyse_g1_u, /* 59 Wyse 60 graphics 1 */
- wyse_g2_u, /* 60 Wyse 60 graphics 2 */
- wyse_g3_u, /* 61 Wyse 60 graphics 3 */
- elot927_u, /* 62 Greek ELOT 927 */
- dgspec_u, /* 63 DG Special graphics */
- dgline_u, /* 64 DG Line drawing */
- dgword_u, /* 65 DG Word processing */
- hpline_u, /* 66 HP Line drawing */
- hpmath_u, /* 67 HP Math/Technical */
- qnxgrph_u, /* 68 QNX Graphics */
- snibrack_u, /* 69 SNI Brackets */
- snieuro_u, /* 70 SNI Euro */
- snifacet_u, /* 71 SNI Facet */
- sniibm_u, /* 72 SNI IBM */
- sniblanks_u, /* 73 SNI Blanks */
- cp1252_u, /* 74 Windows Latin-1 */
- cp1250_u, /* 75 Windows Latin-2 */
- cp1251_u, /* 76 Windows Cyrillic */
- cp1253_u, /* 77 Windows Greek */
- cp1254_u, /* 78 Windows Turkish */
- cp1257_u, /* 79 Windows Latin-4 */
- cp856_u, /* 80 Cyrillic PC Code Page 856 */
- cp855_u, /* 81 Cyrillic PC Code Page 856 */
- iso_8859_1_u, /* 82 CP819 - Same as 8859-1 */
- iso_8859_2_u, /* 83 CP912 - Same as 8859-2 */
- iso_8859_3_u, /* 84 CP913 - Same as 8859-3 */
- iso_8859_4_u, /* 85 CP914 - Same as 8859-4 */
- iso_8859_5_u, /* 86 CP915 - Same as 8859-5 */
- iso_8859_6_u, /* 87 CP1089 - Same as 8859-6 */
- iso_8859_7_u, /* 88 CP813 - Same as 8859-7 */
- iso_8859_8_u, /* 89 CP916 - Same as 8859-8 */
- iso_8859_9_u, /* 90 CP920 - Same as 8859-9 */
- hproman8_u, /* 91 CP1051 -Same as HP Roman 8 */
- cp858_u, /* 92 CP858 - W Europe w/Euro */
- iso_8859_15_u, /* 93 ISO 8859-15 Latin 15 */
- iso_8859_15_u, /* 94 CP923 - Same as 8859-15 */
- iso_8859_7_u, /* 95 ELOT928 - Same as 8859-7 */
- quickdraw_u, /* 96 CP10000 - Apple Quickdraw */
- cp37_u, /* 97 CP37 - U.S. EBCDIC */
- cp1255_u, /* 98 CP1255 - Windows Hebrew */
- cp1256_u, /* 99 CP1256 - Windows Arabic */
- cp1258_u, /* 100 CP1258 - Windows Viet Nam */
- mazovia_u, /* 101 Mazovia PC code page */
- ident_u, /* 102 Transparent - no translation */
- hz1500_u, /* 103 Hazeltine 1500/1520 graphics */
- koi8r_u, /* 104 KOI8-R */
- koi8u_u, /* 105 KOI8-U */
- apl1_u, /* 106 APL 1 (ISO) */
- apl2_u, /* 107 APL 2 (AIX) */
- apl3_u, /* 108 APL 3 (Plus) */
- apl4_u, /* 109 APL 4 (IBM) */
- apl5_u /* 110 APL 5 (2741) */
-};
-/*
- Table of Unicode-to-Blah translation functions.
- KEEP THIS IN SYNC WITH THE TX_blah DEFINITITIONS in ckcuni.h, and also
- with the tables above.
-*/
-int
-#ifdef CK_ANSIC
-(*xl_tx[MAXTXSETS+1])(USHORT)
-#else
-(*xl_tx[MAXTXSETS+1])()
-#endif /* CK_ANSIC */
- = {
- tx_usascii, /* 0 US ISO 646 (ASCII) */
- tx_british, /* 1 UK ISO 646 */
- tx_fr_canadian, /* 2 Canadian French NRC */
- NULL, /* 3 Cuba */
- NULL, /* 4 Czecho */
- tx_danish, /* 5 Danish/Norwegian ISO 646 */
- tx_dutch, /* 6 Dutch NRC */
- tx_finnish, /* 7 Finnish NRC */
- tx_french, /* 8 French ISO 646 */
- tx_german, /* 9 German ISO 646 */
- tx_hebrew7, /* 10 Hebrew-7 (DEC) */
- tx_hungarian, /* 11 Hungarian ISO 646 */
- tx_icelandic, /* 12 Icelandic */
- tx_italian, /* 13 Italian ISO 646 */
- tx_jis0201r, /* 14 Japanese Roman ISO 646 */
- tx_jis0201k, /* 15 Japanese Katakana */
- tx_koi7, /* 16 Short KOI */
- tx_danish, /* 17 Norwegian/Danish ISO 646 */
- tx_portuguese, /* 18 Portuguese ISO 646 */
- tx_spanish, /* 19 spanish ISO 646 */
- tx_swedish, /* 20 Swedish ISO 646 */
- NULL, /* 21 Swedish ISO 646 for names */
- tx_swiss, /* 22 Swiss NRC */
- tx_ident, /* 23 ISO 8859-1 */
- tx_8859_2, /* 24 ISO 8859-2 */
- tx_8859_3, /* 25 ISO 8859-3 */
- tx_8859_4, /* 26 ISO 8859-4 */
- tx_8859_5, /* 27 ISO 8859-5 */ /* Cyrillic */
- tx_8859_6, /* 28 ISO 8859-6 */ /* Arabic */
- tx_8859_7, /* 29 ISO 8859-7 */ /* Greek */
- tx_8859_8, /* 30 ISO 8859-8 */ /* Hebrew */
- tx_8859_9, /* 31 ISO 8859-9 */ /* Latin-5 */
- tx_8859_10, /* 32 ISO 8859-10 */ /* Latin-6 */
- tx_koi8, /* 33 KOI-8 */
- NULL, /* 34 JIS-7 */
- NULL, /* 35 Shift JIS */
- NULL, /* 36 Japanese EUC (JAE) */
- NULL, /* 37 Japanese DEC Kanji */
- tx_decmcs, /* 38 DEC MCS */
- tx_nextstep, /* 39 NeXT */
- tx_dgi, /* 40 DGI */
- tx_maclatin, /* 41 Macintosh Latin */
- tx_hproman8, /* 42 HP Roman 8 */
- tx_cp437, /* 43 CP437 - Original */
- tx_cp850, /* 44 CP850 - W Europe */
- tx_cp852, /* 45 CP852 - E Europe */
- tx_cp857, /* 46 CP857 - Turkish */
- tx_cp862, /* 47 CP862 - Hebrew */
- tx_cp866, /* 48 CP864 - Arabic */
- tx_cp866, /* 49 CP866 - Cyrillic */
- tx_cp869, /* 50 CP869 - Greek */
- NULL, /* Display only */ /* 51 DEC Special Graphics */
- NULL, /* Display only */ /* 52 DEC Technical */
- NULL, /* Display only */ /* 53 C0 Pictures */
- NULL, /* Display only */ /* 54 C1 Pictures */
- NULL, /* Display only */ /* 55 IBM C0 Graphics */
- NULL, /* Display only */ /* 56 Heath 19 graphics */
- NULL, /* Display only */ /* 57 TVI graphics */
- NULL, /* Display only */ /* 58 Wyse 60 normal-mode graphics */
- NULL, /* Display only */ /* 59 Wyse 60 graphics 1 */
- NULL, /* Display only */ /* 60 Wyse 60 graphics 2 */
- NULL, /* Display only */ /* 61 Wyse 60 graphics 3 */
- tx_elot927, /* 62 Greek ELOT 927 */
- NULL, /* Display only */ /* 63 DG special graphics */
- NULL, /* Display only */ /* 64 DG line-drawing */
- NULL, /* Display only */ /* 65 DG word-processing */
- NULL, /* Display only */ /* 66 HP line-drawing */
- NULL, /* Display only */ /* 67 HP math/techical */
- NULL, /* Display only */ /* 68 QNX Graphics */
- NULL, /* Display only */ /* 69 SNI Brackets */
- NULL, /* Display only */ /* 70 SNI Euro */
- NULL, /* Display only */ /* 71 SNI Facet */
- NULL, /* Display only */ /* 72 SNI IBM */
- NULL, /* Display only */ /* 73 SNI Blanks */
- tx_cp1252, /* 74 Windows Latin-1 */
- tx_cp1250, /* 75 Windows Latin-2 */
- tx_cp1251, /* 76 Windows Cyrillic */
- tx_cp1253, /* 77 Windows Greek */
- tx_cp1254, /* 78 Windows Turkish */
- tx_cp1257, /* 79 Windows Latin-4 */
- tx_cp856, /* 80 Cyrillic PC Code Page 856 */
- tx_cp855, /* 81 Cyrillic PC Code Page 855 */
- tx_ident, /* 82 CP819 - Same as 8859-1 */
- tx_8859_2, /* 83 CP912 - Same as 8859-2 */
- tx_8859_3, /* 84 CP913 - Same as 8859-3 */
- tx_8859_4, /* 85 CP914 - Same as 8859-4 */
- tx_8859_5, /* 86 CP915 - Same as 8859-5 */
- tx_8859_6, /* 87 CP1089 - Same as 8859-6 */
- tx_8859_7, /* 88 CP813 - Same as 8859-7 */
- tx_8859_8, /* 89 CP916 - Same as 8859-8 */
- tx_8859_9, /* 90 CP920 - Same as 8859-9 */
- tx_hproman8, /* 91 CP1051 -Same as HP Roman 8 */
- tx_cp858, /* 92 CP858 - W Europe w/Euro */
- tx_8859_15, /* 93 ISO 8859-15 Latin 15 */
- tx_8859_15, /* 94 CP923 - Same as Latin 15 */
- tx_8859_7, /* 95 ELOT928 - Same as 8859-7 */
- tx_quickdraw, /* 96 CP10000 - Apple Quickdraw */
- tx_cp37, /* 97 CP37 - U.S. EBCDIC */
- tx_cp1255, /* 98 CP1255 - Windows Hebrew */
- tx_cp1256, /* 99 CP1256 - Windows Arabic */
- tx_cp1258, /* 100 CP1258 - Windows Viet Nam */
- tx_mazovia, /* 101 Mazovia PC code page */
- tx_ident, /* 102 Transparent - no translation */
- NULL, /* Display only */ /* 103 Hazeltine 1500/1520 graphics */
- tx_koi8r, /* 104 KOI8-R */
- tx_koi8u, /* 105 KOI8-U */
- tx_apl1, /* 106 APL 1 (ISO) */
- tx_apl2, /* 107 APL 2 (AIX) */
- tx_apl3, /* 108 APL 3 (Plus) */
- tx_apl4, /* 108 APL 4 (IBM) */
- tx_apl5 /* 110 APL 5 (2741) */
-};
-
-/*
- Table of FCS-to-Unicode translation functions.
- KEEP THIS IN SYNC WITH THE FC_blah DEFINITITIONS in ckuxla.h.
-*/
-USHORT
-#ifdef CK_ANSIC
-(*xl_fcu[MAXFCSETS+1])(CHAR)
-#else
-(*xl_fcu[MAXFCSETS+1])()
-#endif /* CK_ANSIC */
-= {
- ascii_u, /* 0 US ISO 646 (ASCII) */
- british_u, /* 1 UK ISO 646 */
- dutch_u, /* 2 Dutch NRC */
- finnish_u, /* 3 Finnish NRC */
- french_u, /* 4 French ISO 646 */
- fr_canadian_u, /* 5 Canadian French NRC */
- german_u, /* 6 German ISO 646 */
- hungarian_u, /* 7 Hungarian ISO 646 */
- italian_u, /* 8 Italian ISO 646 */
- danish_u, /* 9 Danish/Norwegian ISO 646 */
- portuguese_u, /* 10 Portuguese ISO 646 */
- spanish_u, /* 11 spanish ISO 646 */
- swedish_u, /* 12 Swedish ISO 646 */
- swiss_u, /* 13 Swiss NRC */
- iso_8859_1_u, /* 14 ISO 8859-1 Latin-1 */
- iso_8859_2_u, /* 15 ISO 8859-2 Latin-2 */
- decmcs_u, /* 16 DEC MCS */
- nextstep_u, /* 17 NeXT */
- cp437_u, /* 18 CP437 - Original */
- cp850_u, /* 19 CP850 - W Europe */
- cp852_u, /* 20 CP852 - E Europe */
- quickdraw_u, /* 21 CP10000 - Apple Quickdraw */
- dgi_u, /* 22 DGI */
- hproman8_u, /* 23 HP Roman 8 */
- iso_8859_5_u, /* 24 ISO 8859-5 Cyrillic */
- cp866_u, /* 25 CP866 - Cyrillic */
- koi7_u, /* 26 Short KOI */
- koi8_u, /* 27 KOI-8 */
- NULL, /* 28 JIS-7 */
- NULL, /* 29 Shift-JIS */
- NULL, /* 30 Japanese EUC */
- NULL, /* 31 DEC Kanji */
- hebrew7_u, /* 32 Hebrew-7 (DEC) */
- iso_8859_8_u, /* 33 ISO 8859-8 Hebrew */
- cp862_u, /* 34 CP862 Hebrew */
- elot927_u, /* 35 Greek ELOT 927 */
- iso_8859_7_u, /* 36 ISO 8859-7 Greek */
- cp869_u, /* 37 CP869 Greek */
- iso_8859_15_u, /* 38 ISO 8859-15 Latin-9 */
- cp858_u, /* 39 CP858 - W Europe w/Euro */
- cp855_u, /* 40 Cyrillic PC Code Page 856 */
- cp1251_u, /* 41 Windows Cyrillic */
- cp856_u, /* 42 Bulgarian PC Code Page 856 */
- cp1250_u, /* 43 Windows Latin-2 */
- mazovia_u, /* 44 Mazovia PC code page */
- NULL, /* 45 UCS-2 */
- NULL, /* 46 UTF-8 */
- koi8r_u, /* 47 KOI8-R */
- koi8u_u, /* 48 KOI8-U */
- cp1252_u /* 49 CP1252 */
-};
-
-/*
- Table of Unicode-to-FCS translation functions.
- KEEP THIS IN SYNC WITH THE FC_blah DEFINITITIONS in ckuxla.h.
-*/
-int
-#ifdef CK_ANSIC
-(*xl_ufc[MAXFCSETS+1])(USHORT)
-#else
-(*xl_ufc[MAXFCSETS+1])()
-#endif /* CK_ANSIC */
-= {
- tx_usascii, /* 0 US ISO 646 (ASCII) */
- tx_british, /* 1 UK ISO 646 */
- tx_dutch, /* 2 Dutch NRC */
- tx_finnish, /* 3 Finnish NRC */
- tx_french, /* 4 French ISO 646 */
- tx_fr_canadian, /* 5 Canadian French NRC */
- tx_german, /* 6 German ISO 646 */
- tx_hungarian, /* 7 Hungarian ISO 646 */
- tx_italian, /* 8 Italian ISO 646 */
- tx_danish, /* 9 Danish/Norwegian ISO 646 */
- tx_portuguese, /* 10 Portuguese ISO 646 */
- tx_spanish, /* 11 spanish ISO 646 */
- tx_swedish, /* 12 Swedish ISO 646 */
- tx_swiss, /* 13 Swiss NRC */
- tx_ident, /* 14 ISO 8859-1 Latin-1 */
- tx_8859_2, /* 15 ISO 8859-2 Latin-2 */
- tx_decmcs, /* 16 DEC MCS */
- tx_nextstep, /* 17 NeXT */
- tx_cp437, /* 18 CP437 - Original */
- tx_cp850, /* 19 CP850 - W Europe */
- tx_cp852, /* 20 CP852 - E Europe */
- tx_quickdraw, /* 21 CP10000 - Apple Quickdraw */
- tx_dgi, /* 22 DGI */
- tx_hproman8, /* 23 HP Roman 8 */
- tx_8859_5, /* 24 ISO 8859-5 Cyrillic */
- tx_cp866, /* 25 CP866 - Cyrillic */
- tx_koi7, /* 26 Short KOI */
- tx_koi8, /* 27 KOI-8 */
- NULL, /* 28 JIS-7 */
- NULL, /* 29 Shift-JIS */
- NULL, /* 30 Japanese EUC */
- NULL, /* 31 DEC Kanji */
- tx_hebrew7, /* 32 Hebrew-7 (DEC) */
- tx_8859_8, /* 33 ISO 8859-8 Hebrew */
- tx_cp862, /* 34 CP862 Hebrew */
- tx_elot927, /* 35 Greek ELOT 927 */
- tx_8859_7, /* 36 ISO 8859-7 Greek */
- tx_cp869, /* 37 CP869 Greek */
- tx_8859_15, /* 38 ISO 8859-15 Latin-9 */
- tx_cp858, /* 39 CP858 - W Europe w/Euro */
- tx_cp855, /* 40 Cyrillic PC Code Page 856 */
- tx_cp1251, /* 41 Windows Cyrillic */
- tx_cp856, /* 42 Bulgarian PC Code Page 856 */
- tx_cp1250, /* 43 Windows Latin-2 */
- tx_mazovia, /* 44 Mazovia PC code page */
- NULL, /* 45 UCS-2 */
- NULL, /* 46 UTF-8 */
- tx_koi8r, /* 47 KOI8-R */
- tx_koi8u, /* 48 KOI8-U */
- tx_cp1252 /* 49 CP1252 */
-};
-
-/*
- Table of TCS-to-Unicode translation functions.
- KEEP THIS IN SYNC WITH THE TC_blah DEFINITIONS in ckuxla.h.
-*/
-USHORT
-#ifdef CK_ANSIC
-(*xl_tcu[MAXTCSETS+1])(CHAR)
-#else
-(*xl_tcu[MAXTCSETS+1])()
-#endif /* CK_ANSIC */
-= {
- NULL, /* 0 = Transparent */
- ascii_u, /* 1 = ASCII */
- iso_8859_1_u, /* 2 ISO 8859-1 Latin-1 */
- iso_8859_2_u, /* 3 ISO 8859-2 Latin-2 */
- iso_8859_5_u, /* 4 ISO 8859-5 Cyrillic */
- NULL, /* 5 Japanese EUC */
- iso_8859_8_u, /* 6 ISO 8859-8 Hebrew */
- iso_8859_7_u, /* 7 ISO 8859-7 Greek */
- iso_8859_15_u, /* 8 ISO 8859-15 Latin-9 */
- NULL, /* 9 UCS-2 */
- NULL /* 10 UTF-8 */
-};
-
-
-/*
- Table of Unicode-to-TCS translation functions.
- KEEP THIS IN SYNC WITH THE TC_blah DEFINITIONS in ckuxla.h.
-*/
-int
-#ifdef CK_ANSIC
-(*xl_utc[MAXTCSETS+1])(USHORT)
-#else
-(*xl_utc[MAXTCSETS+1])()
-#endif /* CK_ANSIC */
-= {
- NULL, /* 0 = Transparent */
- tx_usascii, /* 1 = ASCII */
- tx_ident, /* 2 ISO 8859-1 Latin-1 */
- tx_8859_2, /* 3 ISO 8859-2 Latin-2 */
- tx_8859_5, /* 4 ISO 8859-5 Cyrillic */
- NULL, /* 5 Japanese EUC */
- tx_8859_8, /* 6 ISO 8859-8 Hebrew */
- tx_8859_7, /* 7 ISO 8859-7 Greek */
- tx_8859_15, /* 8 ISO 8859-15 Latin-9 */
- NULL, /* 9 UCS-2 */
- NULL /* 10 UTF-8 */
-};
-
-#ifdef COMMENT
-/*
- The UTF8 conversions are based on the ConvertUTF functions written
- by Mark E. Davis, copyright 1994 Taligent, Inc.
-
- Tables for use in calculating UTF8 conversions. These contain
- support for ISO-10646 which supports a 31-bit char size.
-
- NOTE: 0xnnnUL is NOT portable!
-*/
-ULONG
-offsetsFromUTF8[7] = {
-#ifdef CK_ANSIC
- 0x00000000UL, /* Ignored */
- 0x00000000UL, 0x00003080UL, 0x000E2080UL,
- 0x03C82080UL, 0xFA082080UL, 0x82082080UL
-#else
- 0x00000000L, /* Ignored */
- 0x00000000L, 0x00003080L, 0x000E2080L,
- 0x03C82080L, (unsigned) 0xFA082080L, (unsigned) 0x82082080L
-#endif /* CK_ANSIC */
-};
-
-CHAR bytesInUTF8[256] = {
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6
-};
-#endif /* COMMENT */
-
-CHAR firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
-
-/*
- utf8_to_ucs2() takes one UTF-8 byte at a time. It returns a pointer the
- UCS-2 character if and only if the entire UTF-8 string has been received.
- Return values:
- 0: Complete UTF-8 sequence received; ucs2 points to valid ucs2 character.
- >0: UTF-8 sequence incomplete, ignore ucs2 value.
- <0: UTF-8 error, 0xfffd should be inserted BEFORE the ucs2 value.
-
- NOTE: A negative value is returned only when two return values are indicated,
- e.g. when a UTF-8 sequence is interrupted by an ASCII char. In this case
- the incomplete UTF-8 sequence must be replaced by 0xfffd, and then the ASCII
- character is kept as-is. In other error cases, ucs2 is set to 0xfffd and
- the return value is 0.
-*/
-#define UTFBUFSIZ 16
-
-int
-#ifdef CK_ANSIC
-utf8_to_ucs2(CHAR ch, USHORT ** ucs2)
-#else
-utf8_to_ucs2(ch, ucs2) CHAR ch; USHORT ** ucs2;
-#endif /* CK_ANSIC */
-{
- static USHORT ucs2return = 0;
-
-#ifdef COMMENT
- /* Unicode Consortium sample code works only with well-formed UTF8 */
-
- int i = 0;
- static int len = 0;
- static CHAR utf8[UTFBUFSIZ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
- ULONG ucs4 = 0;
-
- utf8[len++] = ch; /* Add char to string to process */
-
- if (len < bytesInUTF8[utf8[0]]) /* Need more bytes */
- return(bytesInUTF8[utf8[0]] - len);
-
- switch (len) { /* Have complete sequence... */
- case 6: ucs4 += utf8[i++]; ucs4 <<= 6; /* (fall-thru is intentional) */
- case 5: ucs4 += utf8[i++]; ucs4 <<= 6;
- case 4: ucs4 += utf8[i++]; ucs4 <<= 6;
- case 3: ucs4 += utf8[i++]; ucs4 <<= 6;
- case 2: ucs4 += utf8[i++]; ucs4 <<= 6;
- case 1: ucs4 += utf8[i++];
- }
- ucs4 -= offsetsFromUTF8[len];
- ucs2return = (USHORT)(ucs4 & 0xFFFF);
-#ifdef DEBUG
- /* This shows that our return value is in the prevailing byte order: */
- /* e.g. LE on PC, BE on Sparc. */
- if (deblog) {
- char buf[16];
- union ck_short xx;
- xx.x_short = ucs2return;
- sprintf(buf,"%04X",ucs2return);
- debug(F111,"utf8_to_ucs2 short",buf,ucs2return);
- debug(F101,"utf8_to_ucs2 char[0]","",xx.x_char[0]);
- debug(F101,"utf8_to_ucs2 char[1]","",xx.x_char[1]);
- }
-#endif /* DEBUG */
- *ucs2 = &ucs2return;
- len = 0;
- return(0);
-#else
- /*
- Robuster code adapted from Thomas Dickey, Xfree86,
- recommended by Markus Kuhn.
- */
- static int utfcount = 0; /* Position in UTF sequence */
- int utferror = 0; /* Flag for malformed UTF */
- unsigned c = ch; /* Input byte */
- int haveucs2 = 0;
-
- if (ch < 0x80) { /* ASCII char... */
- if (utfcount > 0) /* Not legal in UTF-8 sequence */
- utferror = 1; /* so flag */
- haveucs2 = 1;
- ucs2return = ch; /* but also return it */
- utfcount = 0; /* reset UTF-8 count */
- } else if (ch < 0xc0) { /* 0x80 <= c < 0xc0... */
- if (utfcount < 1) { /* Not valid in first position... */
- utferror = 1;
- } else { /* Maybe valid */
- if (ucs2return > 0x03ff) { /* Value would be > 0xffff */
- utferror = 1; /* so not valid */
- } else { /* OK... */
- ucs2return <<= 6; /* Shift result */
- ucs2return |= (ch & 0x3f); /* and OR in this byte */
- }
- if (--utfcount == 0)
- haveucs2 = 1;
- }
- } else { /* c >= 0xc0... */
- if (utfcount > 0)
- utferror = 1;
- if (c < 0xe0) {
- utfcount = 1;
- ucs2return = (c & 0x1f);
- haveucs2 = 1;
- } else if (c < 0xf0) {
- utfcount = 2;
- ucs2return = (c & 0x0f);
- haveucs2 = 1;
- } else if (c < 0xf8) {
- utfcount = 3;
- ucs2return = (c & 0x07);
- haveucs2 = 1;
- } else if (c < 0xfc) {
- utfcount = 4;
- ucs2return = (c & 0x03);
- haveucs2 = 1;
- } else if (c < 0xfe) {
- utfcount = 5;
- ucs2return = (c & 0x01);
- haveucs2 = 1;
- } else {
- utferror = 1;
- utfcount = 0;
- }
- }
- if (haveucs2 == 0 && utferror != 0) {
- haveucs2 = 1;
- ucs2return = 0xfffd;
- utferror = 0;
- }
- if (haveucs2) {
- *ucs2 = &ucs2return;
- if (utferror)
- utfcount = 0 - utfcount;
- return(utfcount);
- } else {
- if (utfcount == 0)
- utfcount++;
- return(utfcount);
- }
-#endif /* COMMENT */
-}
-
-/*
- ucs2_to_utf8() takes one ucs2 character and returns the length and
- and a pointer to an array containing the equivalent utf8 string.
- This code can easily be altered to support UCS4 simply by changing
- the input from USHORT to ULONG. Returns:
- >0: Number of bytes in the utf8 string.
- 0: (or less) Error.
-*/
-
-int
-#ifdef CK_ANSIC
-ucs2_to_utf8(USHORT ucs2, CHAR ** utf8)
-#else
-ucs2_to_utf8(ucs2, utf8) USHORT ucs2; CHAR ** utf8;
-#endif /* CK_ANSIC */
-{
- static CHAR utf8return[8]={0,0,0,0,0,0,0,0};
- register CONST ULONG byteMask = 0xBF;
- register CONST ULONG byteMark = 0x80;
- int utf8len = 0;
- int i = 0;
-
- if (ucs2 < 0x80) {
- utf8len = 1;
- debug(F101,"ucs2_to_utf8 X1","",utf8len);
- } else if (ucs2 < 0x800) {
- utf8len = 2;
- debug(F101,"ucs2_to_utf8 X2","",utf8len);
- } else
-#ifdef DO_UCS4
- /* This is always true for UCS-2 but would be needed for UCS-4*/
- /* When ucs2 is USHORT this gives compiler warnings. */
- if (ucs2 <= 0xffff)
-#endif /* DO_UCS4 */
- {
- utf8len = 3;
- debug(F101,"ucs2_to_utf8 X3","",utf8len);
- }
-#ifdef DO_UCS4
-/* The following would be for UCS-4 */
- else if (ucs2 < 0x200000) {
- utf8len = 4;
- } else if (ucs2 < 0x4000000) {
- utf8len = 5;
- } else if (ucs2 <=
-#ifdef CK_ANSIC
- 0x7FFFFFFFUL /* (doesn't really need the "U") */
-#else
- 0x7FFFFFFFL
-#endif /* CK_ANSIC */
- ) { /* 31 bits = max for UCS4 */
- utf8len = 6;
- } else {
- utf8len = 2;
- ucs2 = 0xFFFD; /* Replacement for invalid char */
- }
-#endif /* DO_UCS4 */
- i = utf8len; /* index into utf8return */
- utf8return[i--] = 0; /* Null terminate the string */
-
- switch (utf8len) { /* code falls through cases! */
- case 6: utf8return[i--] = (ucs2 | byteMark) & byteMask; ucs2 >>= 6;
- case 5: utf8return[i--] = (ucs2 | byteMark) & byteMask; ucs2 >>= 6;
- case 4: utf8return[i--] = (ucs2 | byteMark) & byteMask; ucs2 >>= 6;
- case 3: utf8return[i--] = (ucs2 | byteMark) & byteMask; ucs2 >>= 6;
- case 2: utf8return[i--] = (ucs2 | byteMark) & byteMask; ucs2 >>= 6;
- case 1: utf8return[i--] = ucs2 | firstByteMark[utf8len];
- }
- debug(F111,"ucs2_to_utf8",utf8return,utf8len);
- *utf8 = utf8return;
- return(utf8len);
-}
-
-/* UTF-8 functions... */
-
-#ifdef CK_ANSIC
-extern int (*xuf)(USHORT); /* Translation function UCS to FCS */
-extern USHORT (*xfu)(CHAR); /* Translation function FCS to UCS */
-#else
-extern int (*xuf)();
-extern USHORT (*xfu)();
-#endif /* CK_ANSIC */
-
-/* u _ t o _ b -- UTF-8 to Byte */
-/*
- Converts from UTF-8 to the current terminal or file character set.
- Call with:
- c: a single byte, which is part of a UTF-8 stream.
- Returns:
- -9: Error, with second char to follow (call u_to_b2() to get it).
- -2: UCS line/paragraph end (LS or PS).
- -1: UTF-8 stream is incomplete and more input is required.
- >=0: Byte value of result, possibly the "error" byte (e.g. '?').
- Requires:
- Global (*xuf)() to point to a function that translates from UCS-2 to
- the appropriate term/file character set.
-*/
-static int savedbyte = 0;
-
-int /* Call if u_to_b() returns -9 */
-u_to_b2() {
- return((unsigned)(savedbyte & 0xff));
-}
-
-int /* UTF-8 to byte */
-#ifdef CK_ANSIC
-u_to_b(CHAR c)
-#else
-u_to_b(c) CHAR c;
-#endif /* CK_ANSIC */
-{
- int x;
- USHORT * ucs2, uc;
- if (!xuf) /* If no conversion function */
- return(c); /* don't convert (shouldn't happen). */
- x = utf8_to_ucs2(c,&ucs2); /* Send for conversion to UCS-2 */
- if (x > 0) /* Not done yet... */
- return(-1);
- uc = (x < 0) ? 0xfffd : *ucs2; /* Done, check result */
- if (uc == 0x2028 || uc == 0x2029) /* LS or PS */
- return(-2);
- return((unsigned)(((*xuf)(uc)) & 0xff)); /* Convert UCS-2 to byte */
-}
-
-/* b _ t o _ u -- Byte to UTF-8 */
-/*
- Converts a byte from the current terminal or file character set to UTF-8.
- Call with:
- c........ The byte to be converted.
- buf...... Pointer to buffer in which to place the result.
- buflen... Length of the result buffer.
- setsize.. The size of the source character set (128 or 256).
- Requires:
- Global (*xfu)() to point to the function to convert the byte to UCS-2.
- Returns:
- -1 if the xfu is NULL; otherwise:
- >0 indicating the length (in bytes) of the UTF-8 string.
- If the translation fails, the Unicode "Replacement Character" is returned
- (0xFFFD translated to UTF-8 == 0xFFBD).
-*/
-int /* Byte to UTF-8 */
-#ifdef CK_ANSIC
-b_to_u(CHAR c, CHAR * buf, int buflen, int setsize)
-#else
-b_to_u(c, buf, buflen, setsize) CHAR c, * buf; int buflen, setsize;
-#endif /* CK_ANSIC */
-{
- CHAR * tmp = NULL;
- int i, count = 0;
- USHORT uc;
- if (!xfu) {
- debug(F100,"b_to_u no xfu","",0);
- return(-1);
- }
- uc = c;
- if (((setsize > 128) && (c & 0x80)) || setsize <= 128) {
- if (xfu) /* FCS-to-UCS function */
- uc = (*xfu)(c);
- }
- count = ucs2_to_utf8(uc,&tmp);
- if (count < 0) {
- buf[0] = 0xef; /* == 0xFFFD in UTF-8 */
- buf[1] = 0xbf;
- buf[2] = 0xbd;
- buf[3] = '\0';
- return(2);
- }
- if (count >= buflen) {
- debug(F101,"WARNING: UTF8 buffer overflow","",count);
- count = buflen - 1;
- }
- for (i = 0; i < count; i++) /* Copy to result buffer */
- buf[i] = tmp[i];
- buf[i] = '\0';
- return(count);
-}
-
-#ifndef OS2
-int
-isunicode( /* Tells whether the host we are */
-#ifdef CK_ANSIC /* running on supports Unicode */
- void /* display */
-#endif /* CK_ANSIC */
- ) {
-#ifdef NT
- extern int tt_unicode;
-#ifdef KUI
- return(tt_unicode);
-#else /* KUI */
- if (tt_unicode && !isWin95())
- return(1);
- else
- return(0);
-#endif /* KUI */
-#else /* NT */
- return(0);
-#endif /* NT */
-}
-#endif /* OS2 */
-#endif /* UNICODE */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcuni.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckcuni.h
deleted file mode 100644
index 06dff9b..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcuni.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/* C K C U N I . H -- Unicode/Terminal character-set translations */
-
-/*
- Copyright (C) 1999, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Authors:
- Frank da Cruz <fdc@columbia.edu>
- The Kermit Project, Columbia University, New York City.
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
-*/
-
-/* Terminal character sets */
-
-#ifndef CKOUNI_H
-#define CKOUNI_H
-#ifdef OS2
-#ifndef CKOUNI
-#define CKOUNI /* Use UNICODE for OS/2 functions */
-#endif /* CKOUNI */
-#ifdef KUI
-#define X_CKOUNI_IN /* Use Unicode Input */
-#define CKOUNI_OUT
-#endif /* KUI */
-#endif /* OS2 */
-
-/* Terminal Character Sets */
-
-#define TX_ASCII 0 /* US ASCII */
-#define TX_BRITISH 1 /* British ISO 646 */
-#define TX_CN_FRENCH 2 /* Canadian French NRC */
-#define TX_CUBAN 3 /* Cuba */
-#define TX_CZECH 4 /* Czech Republic */
-#define TX_DANISH 5 /* Denmark / Norway ISO 646 */
-#define TX_DUTCH 6 /* Dutch NRC */
-#define TX_FINNISH 7 /* Finnish NRC */
-#define TX_FRENCH 8 /* French ISO 646 */
-#define TX_GERMAN 9 /* German ISO 646 */
-#define TX_HE7 10 /* Hebrew 7 (DEC) */
-#define TX_HUNGARIAN 11 /* Hungarian ISO 646 */
-#define TX_ICELANDIC 12 /* Icelandic NRC */
-#define TX_ITALIAN 13 /* Italian ISO 646 */
-#define TX_J201R 14 /* JIS 0201 Japanese Roman */
-#define TX_J201K 15 /* JIS 0201 Katakana */
-#define TX_KOI7 16 /* Short KOI */
-#define TX_NORWEGIAN 17 /* Denmark / Norway ISO 646 */
-#define TX_PORTUGUESE 18 /* Portuguese ISO 646 */
-#define TX_SPANISH 19 /* Spanish ISO 646 */
-#define TX_SWEDISH 20 /* Swedish ISO 646 */
-#define TX_SWE_2 21 /* Swedish for names ISO 646 */
-#define TX_SWISS 22 /* Swiss NRC */
-#define TX_8859_1 23 /* Latin-1 */
-#define TX_8859_2 24 /* Latin-2 */
-#define TX_8859_3 25 /* Latin-3 */
-#define TX_8859_4 26 /* Latin-4 */
-#define TX_8859_5 27 /* Latin/Cyrillic */
-#define TX_8859_6 28 /* Latin/Arabic */
-#define TX_8859_7 29 /* Latin/Greek */
-#define TX_8859_8 30 /* Latin/Hebrew */
-#define TX_8859_9 31 /* Latin-5 */
-#define TX_8859_10 32 /* Latin-6 */
-
-#define TX_KOI8 33 /* GOST 19768-74 KOI-8 */
-
-#define TX_JIS7 34 /* JIS-7 */
-#define TX_SHJIS 35 /* Shift JIS */
-#define TX_JEUC 36 /* Japanese EUC */
-#define TX_JDEC 37 /* Japanese DEC Kanji */
-
-#define TX_DECMCS 38 /* DEC MCS */
-#define TX_NEXT 39 /* NeXT */
-#define TX_DGI 40 /* Data General International */
-#define TX_MACL1 41 /* Macintosh Latin-1 */
-#define TX_HPR8 42 /* HP Roman 8 */
-
-/* Code pages */
-
-#define TX_CP437 43 /* Original */
-#define TX_CP850 44 /* Multinational (Western Europe) */
-#define TX_CP852 45 /* Eastern Europe */
-#define TX_CP857 46 /* Turkey */
-#define TX_CP862 47 /* Hebrew */
-#define TX_CP864 48 /* Arabic */
-#define TX_CP866 49 /* Cyrillic */
-#define TX_CP869 50 /* Greek */
-
-#define TX_DECSPEC 51 /* DEC Special Graphics */
-#define TX_DECTECH 52 /* DEC Technical */
-#define TX_C0PICT 53 /* C0 Display Controls */
-#define TX_C1PICT 54 /* C1 Display Controls */
-#define TX_IBMC0GRPH 55 /* IBM C0 Graphics (smileys) */
-#define TX_H19GRAPH 56 /* Heath/Zenith 19 Graphics */
-#define TX_TVIGRAPH 57 /* Televideo Graphics */
-#define TX_WYSE60G_N 58 /* Wyse 60 Native Mode Graphics */
-#define TX_WYSE60G_1 59 /* Wyse 60 Graphics 1 */
-#define TX_WYSE60G_2 60 /* Wyse 60 Graphics 2 */
-#define TX_WYSE60G_3 61 /* Wyse 60 Graphics 3 */
-
-/* New ones that came too late for the nice grouping... */
-
-#define TX_ELOT927 62 /* Greek ELOT 927 */
-#define TX_DGPCGRPH 63 /* DG PC Graphics */
-#define TX_DGLDGRPH 64 /* DG Line Drawing Graphics */
-#define TX_DGWPGRPH 65 /* DG Word Processing (etc) Graphics */
-#define TX_HPLINE 66 /* HP Line Drawing */
-#define TX_HPMATH 67 /* HP Math/Technical */
-#define TX_QNXGRPH 68 /* QNX Graphics */
-
-/* Siemens Nixdorf character sets */
-
-#define TX_SNIBRACK 69 /* SNI 97801 Brackets */
-#define TX_SNIEURO 70 /* SNI 97801 Euro */
-#define TX_SNIFACET 71 /* SNI 97801 Facet */
-#define TX_SNIIBM 72 /* SNI 97801 "IBM" */
-#define TX_SNIBLANK 73 /* SNI 97801 Blanks */
-
-/* Windows Code pages */
-
-#define TX_CP1252 74 /* Latin-1 Windows */
-#define TX_CP1250 75 /* Latin-2 Windows */
-#define TX_CP1251 76 /* Cyrillic Windows */
-#define TX_CP1253 77 /* Greece Windows */
-#define TX_CP1254 78 /* Turkey Windows */
-#define TX_CP1257 79 /* Latin-4 Windows */
-
-#define TX_CP856 80 /* Bulgaria CP856 (DATECS Ltd) */
-#define TX_CP855 81
-#define TX_CP819 82 /* Same as ISO 8859-1 */
-#define TX_CP912 83 /* Same as ISO 8859-2 */
-#define TX_CP913 84 /* Same as ISO 8859-3 */
-#define TX_CP914 85 /* Same as ISO 8859-4 */
-#define TX_CP915 86 /* Same as ISO 8859-5 */
-#define TX_CP1089 87 /* Same as ISO 8859-6 */
-#define TX_CP813 88 /* Same as ISO 8859-7 */
-#define TX_CP916 89 /* Same as ISO 8859-8 */
-#define TX_CP920 90 /* Same as ISO 8859-9 */
-#define TX_CP1051 91 /* Same as HP Roman 8 */
-#define TX_CP858 92 /* Multinational (W. Europe) w/Euro */
-#define TX_8859_15 93 /* Latin-9 */
-#define TX_CP923 94 /* Same as ISO 8859-15 */
-
-#define TX_ELOT928 95 /* Same as ISO 8859-7 */
-#define TX_CP10000 96 /* Same as original Apple Quickdraw */
-#define TX_CP37 97 /* EBCDIC */
-#define TX_CP1255 98 /* Israel Windows */
-#define TX_CP1256 99 /* Arabic Windows */
-#define TX_CP1258 100 /* Viet Nam Windows */
-#define TX_MAZOVIA 101
-#define TX_TRANSP 102 /* Transparent - no translation */
-#define TX_HZ1500 103 /* Hazeltine 1500 graphics set */
-#define TX_KOI8R 104 /* KOI8R - Russian */
-#define TX_KOI8U 105 /* KOI8U - Ukrainian */
-#define TX_APL1 106 /* APL ISO IR 68 */
-#define TX_APL2 107 /* Dyadic Systems Inc APL */
-#define TX_APL3 108 /* APL-Plus (APL-2000) */
-#define TX_APL4 109 /* IBM APL/2 */
-#define TX_APL5 110 /* APL-2741 */
-
-#define MAXTXSETS 111 /* Number of terminal character sets */
-
-/* The following are not implemented yet */
-/* UTF-8 is supported as a special mode in Kermit 95 (see utf8 flag) */
-
-#define TX_UTF7 128
-#define TX_UTF8 129
-
-#define TX_HEXBYTES 242 /* Hex bytes */
-#define TX_DEBUG 243 /* Debugging but not hex bytes */
-
-/* These are actually used */
-
-#define TX_UNDEF 255 /* Unknown character-set */
-
-/* Flag bit values */
-
-#define X2U_STD 1 /* Has standard ISO 4873 layout */
-#define X2U_ISO 2 /* ISO standard character set */
-#define X2U_JIS 4 /* Japan Industrial Standard */
-#define X2U_CP 8 /* PC Code Page */
-#define X2U_DEC 16 /* DEC Private character set */
-#define X2U_CXG 32 /* Control codes used for graphics */
-
-struct x_to_unicode {
- int size; /* 94, 96, 128, or other */
- int offset; /* 0, 32, 33, 128, 160, ... */
- int flags;
- int family; /* Language family, writing system */
- char * keywd; /* Keyword name */
- char * name; /* Descriptive name */
- int code; /* ISO reg number if Standard */
- /* CP number if Code-page, etc. */
- char * final; /* Esc seq final char(s) (ISO, DEC) */
- unsigned short map[256]; /* Mapping table */
-};
-
-extern struct keytab txrtab[];
-extern int ntxrtab;
-
-#ifndef NULL
-#define NULL (char *)0
-#endif /* NULL */
-
-#ifndef USHORT
-#define USHORT unsigned short
-#endif /* USHORT */
-
-#ifndef ULONG
-#define ULONG unsigned long
-#endif /* ULONG */
-
-#ifndef CHAR
-#define CHAR unsigned char
-#endif /* CHAR */
-
-#ifdef CK_ANSIC
-extern USHORT (*xl_u[MAXTXSETS+1])(CHAR); /* Blah-to-Unicode functions */
-extern int (*xl_tx[MAXTXSETS+1])(USHORT); /* Unicode-to-Blah functions */
-#else
-extern USHORT (*xl_u[MAXTXSETS+1])();
-extern int (*xl_tx[MAXTXSETS+1])();
-#endif /* CK_ANSIC */
-extern struct x_to_unicode * txrinfo[MAXTXSETS+1];
-
-_PROTOTYP(int isunicode, (void));
-_PROTOTYP(int utf8_to_ucs2, (CHAR, USHORT **));
-_PROTOTYP(int ucs2_to_utf8, (USHORT, CHAR **));
-_PROTOTYP(int tx_cpsub, (USHORT));
-_PROTOTYP(int u_to_b, (CHAR) );
-_PROTOTYP(int u_to_b2, (void) );
-_PROTOTYP(int b_to_u, (CHAR, CHAR *, int, int) );
-
-#ifdef KANJI
-_PROTOTYP(USHORT sj_to_un, (USHORT) ); /* Shift-JIS to Unicode */
-_PROTOTYP(USHORT un_to_sj, (USHORT) ); /* Unicode to Shift-JIS */
-#endif /* KANJI */
-
-#ifdef OS2
-#ifdef NT
-_inline
-#else
-_Inline
-#endif /* NT */
-int
-isunicode(
-#ifdef CK_ANSIC
- void
-#endif /* CK_ANSIC */
- ) {
- extern int tt_unicode;
-#ifdef NT
-#ifdef KUI
- return(tt_unicode);
-#else /* KUI */
- if (tt_unicode && !isWin95())
- return(1);
- else
- return(0);
-#endif /* KUI */
-#else /* NT */
- return(0);
-#endif /* NT */
-}
-#endif /* OS2 */
-#endif /* CKOUNI_H */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckcxla.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckcxla.h
deleted file mode 100644
index 6403c81..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckcxla.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- File CKCXLA.H
-
- System-independent character-set translation header file for C-Kermit.
-*/
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project - Columbia University, New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-/*
- NOTE:
- ISO 204 is Latin-1 + Euro.
- ISO 205 is Latin-4 + Euro.
- ISO 206 is Latin-7 + Euro.
-*/
-#ifndef CKCXLA_H /* Guard against multiple inclusion */
-#define CKCXLA_H
-
-#ifndef KANJI /* Systems supporting Kanji */
-#ifdef OS2
-#define KANJI
-#endif /* OS2 */
-#endif /* KANJI */
-
-#ifdef NOKANJI /* Except if NOKANJI is defined. */
-#ifdef KANJI
-#undef KANJI
-#endif /* KANJI */
-#endif /* NOKANJI */
-
-#ifndef NOUNICODE
-#ifndef UNICODE /* Unicode support */
-#ifdef OS2ORUNIX /* Only for K95, UNIX, VMS,... */
-#define UNICODE
-#else
-#ifdef VMS
-#define UNICODE
-#endif /* VMS */
-#endif /* OS2ORUNIX */
-#endif /* UNICODE */
-#endif /* NOUNICODE */
-
-#define XLA_NONE 0 /* Translation types - none */
-#define XLA_BYTE 1 /* Byte-for-byte */
-#define XLA_JAPAN 2 /* Japanese */
-#define XLA_UNICODE 3 /* Unicode */
-
-#ifndef UNIORKANJI /* Unicode OR Kanji */
-#ifdef UNICODE /* i.e. some support for */
-#define UNIORKANJI /* multibyte character sets */
-#endif /* UNICODE */
-#ifdef KANJI
-#define UNIORKANJI
-#endif /* KANJI */
-#endif /* UNIORKANJI */
-/*
- Disable all support for all classes of character sets
- if NOCSETS is defined.
-*/
-#ifdef NOCSETS
-
-#ifdef CKOUNI
-#undef CKOUNI
-#endif /* CKOUNI */
-#ifdef KANJI
-#undef KANJI
-#endif /* KANJI */
-#ifdef CYRILLIC
-#undef CYRILLIC
-#endif /* CYRILLIC */
-#ifdef LATIN2
-#undef LATIN2
-#endif /* LATIN2 */
-#ifdef HEBREW
-#undef HEBREW
-#endif /* HEBREW */
-#ifdef UNICODE
-#undef UNICODE
-#endif /* UNICODE */
-#ifndef NOUNICODE
-#define NOUNICODE
-#endif /* NOUNICODE */
-
-#else /* Not NOCSETS - Rest of this file... */
-
-#ifdef NOUNICODE /* Unicode */
-#ifdef UNICODE
-#undef UNICODE
-#endif /* UNICODE */
-#endif /* NOUNICODE */
-
-#ifdef UNICODE
-#ifdef OS2
-#ifndef CKOUNI
-#define CKOUNI /* Special Unicode features for K95 */
-#endif /* CKOUNI */
-#endif /* OS2 */
-#endif /* UNICODE */
-
-#ifndef OS2
-#ifdef CKOUNI
-#undef CKOUNI
-#endif /* CKOUNI */
-#endif /* OS2 */
-
-#ifndef NOLATIN2 /* If they didn't say "no Latin-2" */
-#ifndef LATIN2 /* Then if LATIN2 isn't already */
-#define LATIN2 /* defined, define it. */
-#endif /* LATIN2 */
-#endif /* NOLATIN2 */
-
-#ifdef NOCYRILLIC /* (spelling variant...) */
-#ifndef NOCYRIL
-#define NOCYRIL
-#endif /* NOCYRIL */
-#endif /* NOCYRILLIC */
-
-#ifndef NOCYRIL /* If they didn't say "no Cyrillic" */
-#ifndef CYRILLIC /* Then if CYRILLIC isn't already */
-#define CYRILLIC /* defined, define it. */
-#endif /* CYRILLIC */
-#endif /* NOCYRIL */
-
-#ifndef NOHEBREW /* If they didn't say "no Hebrew" */
-#ifndef HEBREW /* Then if HEBREW isn't already */
-#define HEBREW /* defined, define it. */
-#endif /* HEBREW */
-#endif /* NOHEBREW */
-
-#ifndef NOGREEK /* If not no Greek */
-#ifndef GREEK /* then if GREEK isn't already */
-#define GREEK /* defined, define it. */
-#endif /* GREEK */
-#endif /* NOGREEK */
-
-#ifndef NOKANJI /* If not no Kanji */
-#ifndef KANJI /* then if KANJI isn't already */
-#define KANJI /* defined, define it. */
-#endif /* KANJI */
-#endif /* NOKANJI */
-
-/* File ckcxla.h -- Character-set-related definitions, system independent */
-
-/* Codes for Kermit Transfer Syntax Level (obsolete) */
-
-#define TS_L0 0 /* Level 0 (Transparent) */
-#define TS_L1 1 /* Level 1 (one standard character set) */
-#define TS_L2 2 /* Level 2 (multiple character sets in same file) */
-
-#define UNK 63 /* Symbol to use for unknown character (63 = ?) */
-
-/*
- Codes for the base alphabet of a given character set.
- These are assigned in roughly ISO 8859 order.
- (Each is assumed to include ASCII/Roman.)
-*/
-#define AL_UNIV 0 /* Universal (like ISO 10646) */
-#define AL_ROMAN 1 /* Roman (Latin) alphabet */
-#define AL_CYRIL 2 /* Cyrillic alphabet */
-#define AL_ARABIC 3 /* Arabic */
-#define AL_GREEK 4 /* Greek */
-#define AL_HEBREW 5 /* Hebrew */
-#define AL_KANA 6 /* Japanese Katakana */
-#define AL_JAPAN 7 /* Japanese Katakana+Kanji ideograms */
-#define AL_HAN 8 /* Chinese/Japanese/Korean ideograms */
-#define AL_INDIA 9 /* Indian scripts (ISCII) */
-#define AL_VIET 10 /* Vietnamese (VISCII) */
- /* Add more here... */
-#define AL_UNK 999 /* Unknown (transparent) */
-
-/* Codes for languages */
-/*
- NOTE: It would perhaps be better to use ISO 639-1988 2-letter "Codes for
- Representation of Names of Languages" here, shown in the comments below.
-*/
-#define L_ASCII 0 /* EN ASCII, English */
-#define L_USASCII 0 /* EN ASCII, English */
-#define L_DUTCH 1 /* NL Dutch */
-#define L_FINNISH 2 /* FI Finnish */
-#define L_FRENCH 3 /* FR French */
-#define L_GERMAN 4 /* DE German */
-#define L_HUNGARIAN 5 /* HU Hungarian */
-#define L_ITALIAN 6 /* IT Italian */
-#define L_NORWEGIAN 7 /* NO Norwegian */
-#define L_PORTUGUESE 8 /* PT Portuguese */
-#define L_SPANISH 9 /* ES Spanish */
-#define L_SWEDISH 10 /* SV Swedish */
-#define L_SWISS 11 /* RM Swiss (Rhaeto-Romance) */
-#define L_DANISH 12 /* DA Danish */
-#define L_ICELANDIC 13 /* IS Icelandic */
-#define L_RUSSIAN 14 /* RU Russian */
-#define L_JAPANESE 15 /* JA Japanese */
-#define L_HEBREW 16 /* IW Hebrew */
-#define L_GREEK 17 /* Greek */
-
-#define MAXLANG 17 /* Number of languages */
-
-/*
- File character-sets are defined in the system-specific ck?xla.h file,
- except for the following ones, which must be available to all versions:
-*/
-#define FC_TRANSP 254 /* Transparent */
-#define FC_UNDEF 255 /* Undefined */
-/*
- Designators for Kermit's transfer character sets. These are all standard
- sets, or based on them. Symbols must be unique in the first 8 characters,
- because some C preprocessors have this limit.
-*/
-/* LIST1 */
-#define TC_TRANSP 0 /* Transparent, no character translation */
-#define TC_USASCII 1 /* ISO 646 IRV / US 7-bit ASCII */
-#define TC_1LATIN 2 /* ISO 8859-1, Latin Alphabet 1 */
-#define TC_2LATIN 3 /* ISO 8859-2, Latin Alphabet 2 */
-#define TC_CYRILL 4 /* ISO 8859-5, Latin/Cyrillic */
-#define TC_JEUC 5 /* Japanese EUC = JIS 0201+0202+0208 */
-#define TC_HEBREW 6 /* ISO 8859-8, Latin/Hebrew */
-#define TC_GREEK 7 /* ISO 8859-7, Latin/Greek */
-#define TC_9LATIN 8 /* ISO 8859-15 Latin Alphabet 9 (with Euro) */
-#define TC_UCS2 9 /* ISO 10646 / Unicode UCS-2 */
-#define TC_UTF8 10 /* ISO 10646 / Unicode UTF-8 */
-
-#define MAXTCSETS 10 /* Highest Transfer Character Set Number */
-
-#ifdef COMMENT
-/*
- Not used and probably won't be due to ISO-10646 / Unicode.
-*/
-#define TC_3LATIN 11 /* ISO 8859-3, Latin-3 */
-#define TC_4LATIN 12 /* ISO 8859-4, Latin-4 */
-#define TC_5LATIN 13 /* ISO 8859-9, Latin-5 */
-#define TC_ARABIC 14 /* ISO-8859-6, Latin/Arabic */
-#define TC_JIS208 15 /* Japanese JIS X 0208 multibyte set */
-#define TC_CHINES 16 /* Chinese Standard GB 2312-80 */
-#define TC_KOREAN 17 /* Korean KS C 5601-1987 */
-#define TC_ISCII 18 /* Indian standard code for ii... */
-#define TC_VSCII 19 /* Vietnam standard code for ii... */
-/* etc... */
-#endif /* COMMENT */
-
-/* Structure for character-set information */
-
-struct csinfo {
- char *name; /* Descriptive name of character set */
- int size; /* Size (e.g. 128, 256, 16384) */
- int code; /* Like TC_1LATIN, etc. */
- char *designator; /* Designator, like I2/100 = Latin-1 */
- int alphabet; /* Base alphabet */
- char *keyword; /* Keyword for this character-set */
-};
-
-/* Structure for language information */
-
-struct langinfo {
- int id; /* Language ID code (L_whatever) */
- int fc; /* File character set to use */
- int tc; /* Transfer character set to use */
- char *description; /* Description of language */
-};
-
-/* Now take in the system-specific definitions */
-
-#ifdef UNIX
-#include "ckuxla.h"
-#endif /* UNIX */
-
-#ifdef OSK /* OS-9 */
-#include "ckuxla.h"
-#endif /* OS-9 */
-
-#ifdef VMS /* VAX/VMS */
-#include "ckuxla.h"
-#endif /* VMS */
-
-#ifdef GEMDOS /* Atari ST */
-#include "ckuxla.h"
-#endif /* GEMDOS */
-
-#ifdef MAC /* Macintosh */
-#include "ckmxla.h"
-#endif /* MAC */
-
-#ifdef OS2 /* OS/2 */
-#include "ckuxla.h" /* Uses big UNIX version */
-#endif /* OS2 */
-
-#ifdef AMIGA /* Commodore Amiga */
-#include "ckuxla.h"
-#endif /* AMIGA */
-
-#ifdef datageneral /* Data General MV AOS/VS */
-#include "ckuxla.h"
-#endif /* datageneral */
-
-#ifdef STRATUS /* Stratus Computer, Inc. VOS */
-#include "ckuxla.h"
-#endif /* STRATUS */
-
-#ifdef UNICODE
-#include "ckcuni.h" /* Unicode */
-#endif /* UNICODE */
-
-#ifdef KANJI
-#define UNKSJIS 0x817f
-_PROTOTYP(USHORT eu_to_sj, (USHORT) ); /* EUC-JP to Shift-JIS */
-_PROTOTYP(USHORT sj_to_eu, (USHORT) ); /* Shift-JIS to EUC-JP */
-_PROTOTYP( int xkanjf, (void) );
-_PROTOTYP( int xkanji, (int, int (*)(char)) );
-_PROTOTYP( int xkanjz, (int (*)(char) ) );
-_PROTOTYP( int zkanjf, (void) );
-_PROTOTYP( int zkanji, (int (*)(void)) ); /* Kanji function prototypes */
-_PROTOTYP( int zkanjz, (void) );
-_PROTOTYP(VOID j7init, ( void ) ); /* Initialize JIS-7 parser */
-_PROTOTYP(int getj7, ( void ) ); /* Get next JIS-7 character */
-#endif /* KANJI */
-
-#ifndef MAC
-#ifndef NOLOCAL
-_PROTOTYP( int cs_size, (int) );
-_PROTOTYP( int cs_is_std, (int) );
-_PROTOTYP( int cs_is_nrc, (int) );
-_PROTOTYP( VOID setremcharset, (int, int) );
-_PROTOTYP( VOID setlclcharset, (int) );
-#endif /* NOLOCAL */
-#endif /* MAC */
-
-_PROTOTYP(VOID setxlatype, (int, int));
-
-#endif /* NOCSETS */
-#endif /* CKCXLA_H */
-
-/* End of ckcxla.h */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckermit.ini b/ckermit-9.0.302-build/ckermit-9.0.302/ckermit.ini
deleted file mode 100644
index b30f389..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckermit.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-COMMENT - Standard C-Kermit initialization file
-;
-echo
-echo The very long standard initialization file that was distributed
-echo with C-Kermit 6, 7, and 8 is no longer recommended as "standard",
-echo since its features were little used. It is still available in
-echo the C-Kermit distribution as ockermit.ini.
-echo
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckermit70.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckermit70.txt
deleted file mode 100644
index a796cfd..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckermit70.txt
+++ /dev/null
@@ -1,17690 +0,0 @@
-
- [1]The Columbia Crown The Kermit Project | Columbia University
- 612 West 115th Street, New York NY 10025 USA o [2]kermit@columbia.edu
- ...since 1981
- [3]Home [4]Kermit 95 [5]C-Kermit [6]Scripts [7]Current [8]New [9]FAQ
- [10]Support
-
-Supplement to [11]Using C-Kermit , 2nd Edition
-
-For C-Kermit 7.0
-
-As of C-Kermit version: 7.0.196
-This file created: 8 February 2000
-This file last updated:
-Mon Aug 8 10:39:18 2011
-
-
-Authors: Frank da Cruz and Christine M. Gianone
-Address: The Kermit Project
- Columbia University
- 612 West 115th Street
- New York NY 10025-7799
- USA
-Fax: +1 (212) 662-6442
-E-Mail: [12]kermit-support@columbia.edu
-Web: [13]http://www.columbia.edu/kermit/
-Or: [14]http://www.kermit-project.org/
-Or: [15]http://www.columbia.nyc.ny.us/kermit/
-
-NOTICES
-
- This document:
- Copyright � 1997, 2000, Frank da Cruz and Christine M. Gianone.
- All rights reserved.
-
- Kermit 95:
- Copyright � 1995, 2000, Trustees of Columbia University in the
- City of New York. All rights reserved.
-
- C-Kermit:
- Copyright � 1985, 2000,
- Trustees of Columbia University in the City of New York. All
- rights reserved. See the C-Kermit [16]COPYING.TXT file or the
- copyright text in the [17]ckcmai.c module for disclaimer and
- permissions.
-
- When Kerberos(TM) and/or SRP(TM) (Secure Remote Password) and/or SSL
- protocol are included:
- Portions Copyright � 1990, Massachusetts Institute of
- Technology.
- Portions Copyright � 1991, 1993 Regents of the University of
- California.
- Portions Copyright � 1991, 1992, 1993, 1994, 1995 by AT&T.
- Portions Copyright � 1997, Stanford University.
- Portions Copyright � 1995-1997, Eric Young <eay@cryptosoft.com>.
-
- For the full text of the third-party copyright notices, see
- [18]Appendix V.
-
-WHAT IS IN THIS FILE
-
- This file lists changes made to C-Kermit since the second edition of
- the book [19]Using C-Kermit was published and C-Kermit 6.0 was released
- in November 1996. Use this file as a supplement to the second edition
- of Using C-Kermit until the third edition is published some time in
- 2000. If the "most recent update" shown above is long ago, contact
- Columbia University to see if there is a newer release.
-
- For further information, also see the [20]CKCBWR.TXT ("C-Kermit
- beware") file for hints, tips, tricks, restrictions, frequently asked
- questions, etc, plus the system-specific "beware file", e.g.
- [21]CKUBWR.TXT for UNIX, [22]CKVBWR.TXT for VMS, etc, and also any
- system-specific update files such as KERMIT95.HTM for Kermit 95 (in the
- DOCS\MANUAL\ subdirectory of your K95 directory).
-
- This Web-based copy of the C-Kermit 7.0 update notes supersedes the
- plain-text CKERMIT2.TXT file. All changes after 19 January 2000
- appear only here in the Web version. If you need an up-to-date
- plain-text copy, use your Web browser to save this page as plain
- text.
-
-ABOUT FILENAMES
-
- In this document, filenames are generally shown in uppercase, but on
- file systems with case-sensitive names such as UNIX, OS-9, and AOS/VS,
- lowercase names are used: [23]ckubwr.txt, [24]ckermit70.txt, etc.
-
-ADDITIONAL FILES
-
- Several other files accompany this new Kermit release:
-
- SECURITY.TXT
- Discussion of Kermit's new authentication and encryption
- features:
-
- + [25]Plain-text version
- + [26]HTML (hypertext) version
-
- IKSD.TXT
- How to install and manage an Internet Kermit Service Daemon.
-
- + [27]Plain-text version
- + [28]HTML (hypertext) version
-
- Also see [29]cuiksd.htm for instructions for use.
-
- TELNET.TXT
- A thorough presentation of Kermit's new advanced Telnet features
- and controls.
-
- + [30]Plain-text version
- + [31]HTML (hypertext) version
-
-THE NEW C-KERMIT LICENSE
-
- The C-Kermit license was rewritten for version 7.0 to grant automatic
- permission to packagers of free operating-system distributions to
- include C-Kermit 7.0. Examples include Linux (GNU/Linux), FreeBSD,
- NetBSD, etc. The new license is in the [32]COPYING.TXT file, and is
- also displayed by C-Kermit itself when you give the VERSION or
- COPYRIGHT command. The new C-Kermit license does not apply to
- [33]Kermit 95.
-
-ACKNOWLEDGMENTS
-
- Thanks to Jeff Altman, who joined the Kermit Project in 1995, for much
- of what you see in C-Kermit 7.0, especially in the networking and
- security areas, and his key role in designing and implementing the
- Internet Kermit Service Daemon. And special thanks to Lucas Hart for
- lots of help with the VMS version; to Peter Eichhorn for continuous
- testing on the full range of HP-UX versions and for a consolidated set
- of HP-UX makefile targets; and to Colin Allen, Mark Allen, Roger Allen,
- Ric Anderson, William Bader, Mitch Baker, Mitchell Bass, Nelson Beebe,
- Gerry Belanger, Jeff Bernsten, Mark Berryman, John Bigg, Volker
- Borchert, Jonathan Boswell, Tim Boyer, Frederick Bruckman, Kenneth
- Cochran, Jared Crapo, Bill Delaney, Igor Sobrado Delgado, Clarence
- Dold, Joe Doupnik, John Dunlap, Max Evarts, Patrick French, Carl
- Friedberg, Carl Friend, Hirofumi Fujii, Andrew Gabriel, Gabe Garza,
- Boyd Gerber, David Gerber, George Gilmer, Hunter Goatley, DJ Hagberg,
- Kevin Handy, Andy Harper, Randolph Herber, Sven Holstr�m, Michal
- Jaegermann, Graham Jenkins, Dick Jones, Terry Kennedy, Robert D Keys,
- Nick Kisseberth, Igor Kovalenko, David Lane, Adam Laurie, Jeff
- Liebermann, Eric Lonvick, Hoi Wan Louis, Arthur Marsh, Gregorie Martin,
- Peter Mauzey, Dragan Milicic, Todd Miller, Christian Mondrup, Daniel
- Morato, Dat Nguyen, Herb Peyerl, Jean-Pierre Radley, Steve Rance,
- Stephen Riehm, Nigel Roles, Larry Rosenman, Jay S Rouman, David
- Sanderson, John Santos, Michael Schmitz, Steven Schultz, Bob Shair,
- Richard Shuford, Fred Smith, Michael Sokolov, Jim Spath, Peter Szell,
- Ted T'so, Brian Tillman, Linus Torvalds, Patrick Volkerding, Martin
- Vorl�nder, Steve Walton, Ken Weaverling, John Weekley, Martin Whitaker,
- Jim Whitby, Matt Willman, Joellen Windsor, Farrell Woods, and many
- others for binaries, hosting, reviews, suggestions, advice, bug
- reports, and all the rest over the 3+ year C-Kermit 7.0 development
- cycle. Thanks to Russ Nelson and the board of the Open Software
- Initiative ([34]http://www.opensource.org) for their cooperation in
- developing the new C-Kermit license and to the proprietors of those
- free UNIX distributions that have incorporated C-Kermit 7.0 for their
- cooperation and support, especially FreeBSD's J�rg Wunsch.
-
-NOTE TO KERMIT 95 USERS
-
- Kermit 95 and C-Kermit share the same command and scripting language,
- the same Kermit file-transfer protocol implementation, and much else
- besides.
-
- Like the book [35]Using C-Kermit, this file concentrates on the aspects
- of C-Kermit that are common to all versions: UNIX, VMS, Windows, OS/2,
- VOS, AOS/VS, etc. Please refer to your Kermit 95 documentation for
- information that is specific to Kermit 95.
-
- C-Kermit 7.0 corresponds to Kermit 95 1.1.19.
-
-C-KERMIT VERSIONS AND VERSION NUMBERS
-
- "C-Kermit" refers to all the many programs that are compiled in whole
- or in part from common C-language source code, comprising:
-
- * A Kermit file transfer protocol module
- * A command parser and script execution module
- * A modem-dialing module
- * A network support module
- * A character-set translation module.
-
- and several others. These "system-independent" modules are combined
- with system-dependent modules for each platform to provide the required
- input/output functions, and also in some cases overlaid with an
- alternative user interface, such as Macintosh Kermit's point-and-click
- interface, and in some cases also a terminal emulator, as Kermit 95.
-
- The C-Kermit version number started as 1.0, ... 3.0, 4.0, 4.1 and then
- (because of confusion at the time with Berkeley UNIX 4.2), 4B, 4C, and
- so on, with the specific edit number in parentheses, for example
- 4E(072) or 5A(188). This scheme was used through 5A(191), but now we
- have gone back to the traditional numbering scheme with decimal points:
- major.minor.edit; for example 7.0.196. Internal version numbers (the
- \v(version) variable), however, are compatible in C-Kermit 5A upwards.
-
- Meanwhile, C-Kermit derivatives for some platforms (Windows, Macintosh)
- might go through several releases while C-Kermit itself remains the
- same. These versions have their own platform-specific version numbers,
- such as Kermit 95 1.1.1, 1.1.2, and so on.
-
- C-Kermit Version History:
-
- 1.0 1981-1982 Command-line only, 4.2 BSD UNIX only
- 2.0 (*) (who remembers...)
- 3.0 May 1984 Command-line only, supports several platforms
- 4.0-4.1 Feb-Apr 1985 (*) First interactive and modular version
- 4C(050) May 1985
- 4D(060) April 1986
- 4E(066) August 1987 Long packets
- 4E(068) January 1988
- 4E(072) January 1989
- 4F(095) August 1989 (*) Attribute packets
- 5A(188) November 1992 Scripting, TCP/IP, sliding windows (1)
- 5A(189) September 1993 Control-char unprefixing
- 5A(190) October 1994 Recovery
- 5A(191) April 1995 OS/2 only
- 6.0.192 September 1996 Intelligent dialing, autodownload, lots more (2)
- 6.1.193 1997-98 (*) Development only
- 6.1.194 June 1998 K95 only - switches, directory recursion, more
- 7.0.195 August 1999 IKSD + more (CU only as K95 1.1.18-CU)
- 7.0.196 1 January 2000 Unicode, lots more
-
- (*) Never formally released (4.0 was a total rewrite)
- (1) Using C-Kermit, 1st Edition
- (2) Using C-Kermit, 2nd Edition
-
-CONTENTS
-
- I. [36]C-KERMIT DOCUMENTATION
-
- II. [37]NEW FEATURES
-
- (0) [38]INCOMPATIBILITIES WITH PREVIOUS RELEASES
- (1) [39]PROGRAM AND FILE MANAGEMENT AND COMMANDS
- 1.0. [40]Bug fixes
- 1.1. [41]Command Continuation
- 1.2. [42]Editor Interface
- 1.3. [43]Web Browser and FTP Interface
- 1.4. [44]Command Editing
- 1.5. [45]Command Switches
- 1.5.1. [46]General Switch Syntax
- 1.5.2. [47]Order and Effect of Switches
- 1.5.3. [48]Distinguishing Switches from Other Fields
- 1.5.4. [49]Standard File Selection Switches
- 1.5.5. [50]Setting Preferences for Different Commands
- 1.6. [51]Dates and Times
- 1.7. [52]Partial Completion of Keywords
- 1.8. [53]Command Recall
- 1.9. [54]EXIT Messages
- 1.10. [55]Managing Keyboard Interruptions
- 1.11. [56]Taming the Wild Backslash -- Part Deux
- 1.11.1. [57]Background
- 1.11.2. [58]Kermit's Quoting Rules
- 1.11.3. [59]Passing DOS Filenames from Kermit to Shell Commands
- 1.11.4. [60]Using Variables to Hold DOS Filenames
- 1.11.5. [61]Passing DOS Filenames as Parameters to Macros
- 1.11.6. [62]Passing DOS File Names from Macro Parameters to the D
-OS Shell
- 1.11.7. [63]Passing DOS Filenames to Kermit from the Shell
- 1.12. [64]Debugging
- 1.13. [65]Logs
- 1.14. [66]Automatic File-Transfer Packet Recognition at the Command Pro
-mpt
- 1.15. [67]The TYPE Command
- 1.16. [68]The RESET Command
- 1.17. [69]The COPY and RENAME Commands
- 1.18. [70]The MANUAL Command
- 1.19. [71]String and Filename Matching Patterns
- 1.20. [72]Multiple Commands on One Line
- 1.21. [73]What Do I Have?
- 1.22. [74]Generalized File Input and Output
- 1.22.1. [75]Why Another I/O System?
- 1.22.2. [76]The FILE Command
- 1.22.3. [77]FILE Command Examples
- 1.22.4. [78]Channel Numbers
- 1.22.5. [79]FILE Command Error Codes
- 1.22.6. [80]File I/O Variables
- 1.22.7. [81]File I/O Functions
- 1.22.8. [82]File I/O Function Examples
- 1.23. [83]The EXEC Command
- 1.24. [84]Getting Keyword Lists with '?'
- (2) [85]MAKING AND USING CONNECTIONS
- 2.0. [86]SET LINE and SET HOST Command Switches
- 2.1. [87]Dialing
- 2.1.1. [88]The Dial Result Message
- 2.1.2. [89]Long-Distance Dialing Changes
- 2.1.3. [90]Forcing Long-Distance Dialing
- 2.1.4. [91]Exchange-Specific Dialing Decisions
- 2.1.5. [92]Cautions about Cheapest-First Dialing
- 2.1.6. [93]Blind Dialing (Dialing with No Dialtone)
- 2.1.7. [94]Trimming the Dialing Dialog
- 2.1.8. [95]Controlling the Dialing Speed
- 2.1.9. [96]Pretesting Phone Number Conversions
- 2.1.10. [97]Greater Control over Partial Dialing
- 2.1.11. [98]New DIAL-related Variables and Functions
- 2.1.12. [99]Increased Flexibility of PBX Dialing
- 2.1.13. [100]The DIAL macro - Last-Minute Phone Number Conversions
- 2.1.14. [101]Automatic Tone/Pulse Dialing Selection
- 2.1.15. [102]Dial-Modifier Variables
- 2.1.16. [103]Giving Multiple Numbers to the DIAL Command
- 2.2. [104]Modems
- 2.2.1. [105]New Modem Types
- 2.2.2. [106]New Modem Controls
- 2.3. [107]TELNET and RLOGIN
- 2.3.0. [108]Bug Fixes
- 2.3.1. [109]Telnet Binary Mode Bug Adjustments
- 2.3.2. [110]VMS UCX Telnet Port Bug Adjustment
- 2.3.3. [111]Telnet New Environment Option
- 2.3.4. [112]Telnet Location Option
- 2.3.5. [113]Connecting to Raw TCP Sockets
- 2.3.6. [114]Incoming TCP Connections
- 2.4. [115]The EIGHTBIT Command
- 2.5. [116]The Services Directory
- 2.6. [117]Closing Connections
- 2.7. [118]Using C-Kermit with External Communication Programs
- 2.7.0. [119]C-Kermit over tn3270 and tn5250
- 2.7.1. [120]C-Kermit over Telnet
- 2.7.2. [121]C-Kermit over Rlogin
- 2.7.3. [122]C-Kermit over Serial Communication Programs
- 2.7.4. [123]C-Kermit over Secure Network Clients
- 2.7.4.1. [124]SSH
- 2.7.4.2. [125]SSL
- 2.7.4.3. [126]SRP
- 2.7.4.4. [127]SOCKS
- 2.7.4.5. [128]Kerberos and SRP
- 2.8. [129]Scripting Local Programs
- 2.9. [130]X.25 Networking
- 2.9.1. [131]IBM AIXLink/X.25 Network Provider Interface for AIX
- 2.9.2. [132]HP-UX X.25
- 2.10. [133]Additional Serial Port Controls
- 2.11. [134]Getting Access to the Dialout Device
- 2.12. [135]The Connection Log
- 2.13. [136]Automatic Connection-Specific Flow Control Selection
- 2.14. [137]Trapping Connection Establishment and Loss
- 2.15. [138]Contacting Web Servers with the HTTP Command
- (3) [139]TERMINAL CONNECTION
- 3.1. [140]CONNECT Command Switches
- 3.2. [141]Triggers
- 3.3. [142]Transparent Printing
- 3.4. [143]Binary and Text Session Logs
- (4) [144]FILE TRANSFER AND MANAGEMENT
- 4.0. [145]Bug Fixes, Minor Changes, and Clarifications
- 4.1. [146]File-Transfer Filename Templates
- 4.1.1. [147]Templates in the As-Name
- 4.1.2. [148]Templates on the Command Line
- 4.1.3. [149]Post-Transfer Renaming
- 4.2. [150]File-Transfer Pipes and Filters
- 4.2.1. [151]Introduction
- 4.2.1.1. [152]Terminology
- 4.2.1.2. [153]Notation
- 4.2.1.3. [154]Security
- 4.2.2. [155]Commands for Transferring from and to Pipes
- 4.2.2.1. [156]Sending from a Command
- 4.2.2.2. [157]Receiving to a Command
- 4.2.3. [158]Using File-Transfer Filters
- 4.2.3.1. [159]The SEND Filter
- 4.2.3.2. [160]The RECEIVE Filter
- 4.2.4. [161]Implicit Use of Pipes
- 4.2.5. [162]Success and Failure of Piped Commands
- 4.2.6. [163]Cautions about Using Pipes to Transfer Directory Trees
- 4.2.7. [164]Pipes and Encryption
- 4.2.8. [165]Commands and Functions Related to Pipes
- 4.2.8.1. [166]The OPEN !READ and OPEN !WRITE Commands
- 4.2.8.2. [167]The REDIRECT Command
- 4.2.8.3. [168]Receiving Mail and Print Jobs
- 4.2.8.4. [169]Pipe-Related Functions
- 4.3. [170]Automatic Per-File Text/Binary Mode Switching
- 4.3.1. [171]Exceptions
- 4.3.2. [172]Overview
- 4.3.3. [173]Commands
- 4.3.4. [174]Examples
- 4.4. [175]File Permissions
- 4.4.1. [176]When ATTRIBUTES PROTECTION is OFF
- 4.4.1.1. [177]Unix
- 4.4.1.2. [178]VMS
- 4.4.2. [179]When ATTRIBUTES PROTECTION is ON
- 4.4.2.1. [180]System-Specific Permissions
- 4.4.2.1.1. [181]UNIX
- 4.4.2.1.2. [182]VMS
- 4.4.2.2. [183]System-Independent Permissions
- 4.5. [184]File Management Commands
- 4.5.1. [185]The DIRECTORY Command
- 4.5.2. [186]The CD and BACK Commands
- 4.5.2.1. [187]Parsing Improvements
- 4.5.2.2. [188]The CDPATH
- 4.5.3. [189]Creating and Removing Directories
- 4.5.4. [190]The DELETE and PURGE Commands
- 4.6. [191]Starting the Remote Kermit Server Automatically
- 4.7. [192]File-Transfer Command Switches
- 4.7.1. [193]SEND Command Switches
- 4.7.2. [194]GET Command Switches
- 4.7.3. [195]RECEIVE Command Switches
- 4.8. [196]Minor Kermit Protocol Improvements
- 4.8.1. [197]Multiple Attribute Packets
- 4.8.2. [198]Very Short Packets
- 4.9. [199]Wildcard / File Group Expansion
- 4.9.1. [200]In UNIX C-Kermit
- 4.9.2. [201]In Kermit 95
- 4.9.3. [202]In VMS, AOS/VS, OS-9, VOS, etc.
- 4.10. [203]Additional Pathname Controls
- 4.11. [204]Recursive SEND and GET: Transferring Directory Trees
- 4.11.1. [205]Command-Line Options
- 4.11.2. [206]The SEND /RECURSIVE Command
- 4.11.3. [207]The GET /RECURSIVE Command
- 4.11.4. [208]New and Changed File Functions
- 4.11.5. [209]Moving Directory Trees Between Like Systems
- 4.11.6. [210]Moving Directory Trees Between Unlike Systems
- 4.12. [211]Where Did My File Go?
- 4.13. [212]File Output Buffer Control
- 4.14. [213]Improved Responsiveness
- 4.15. [214]Doubling and Ignoring Characters for Transparency
- 4.16. [215]New File-Transfer Display Formats
- 4.17. [216]New Transaction Log Formats
- 4.17.1. [217]The BRIEF Format
- 4.17.2. [218]The FTP Format
- 4.18. [219]Unprefixing NUL
- 4.19. [220]Clear-Channel Protocol
- 4.20. [221]Streaming Protocol
- 4.20.1. [222]Commands for Streaming
- 4.20.2. [223]Examples of Streaming
- 4.20.2.1. [224]Streaming on Socket-to-Socket Connections
- 4.20.2.2. [225]Streaming on Telnet Connections
- 4.20.2.3. [226]Streaming with Limited Packet Length
- 4.20.2.4. [227]Streaming on Dialup Connections
- 4.20.2.5. [228]Streaming on X.25 Connections
- 4.20.3. [229]Streaming - Preliminary Conclusions
- 4.21. [230]The TRANSMIT Command
- 4.22. [231]Coping with Faulty Kermit Implementations
- 4.22.1. [232]Failure to Accept Modern Negotiation Strings
- 4.22.2. [233]Failure to Negotiate 8th-bit Prefixing
- 4.22.3. [234]Corrupt Files
- 4.22.4. [235]Spurious Cancellations
- 4.22.5. [236]Spurious Refusals
- 4.22.6. [237]Failures during the Data Transfer Phase
- 4.22.7. [238]Fractured Filenames
- 4.22.8. [239]Bad File Dates
- 4.23. [240]File Transfer Recovery
- 4.24. [241]FILE COLLISION UPDATE Clarification
- 4.25. [242]Autodownload Improvements
- (5) [243]CLIENT/SERVER
- 5.0. [244]Hints
- 5.1. [245]New Command-Line Options
- 5.2. [246]New Client Commands
- 5.3. [247]New Server Capabilities
- 5.3.1. [248]Creating and Removing Directories
- 5.3.2. [249]Directory Listings
- 5.4. [250]Syntax for Remote Filenames with Embedded Spaces
- 5.5. [251]Automatic Orientation Messages upon Directory Change
- 5.6. [252]New Server Controls
- 5.7. [253]Timeouts during REMOTE HOST Command Execution
- (6) [254]INTERNATIONAL CHARACTER SETS
- 6.0. [255]ISO 8859-15 Latin Alphabet 9
- 6.1. [256]The HP-Roman8 Character Set
- 6.2. [257]Greek Character Sets
- 6.3. [258]Additional Latin-2 Character Sets
- 6.4. [259]Additional Cyrillic Character Sets
- 6.5. [260]Automatic Character-Set Switching
- 6.6. [261]Unicode
- 6.6.1. [262]Overview of Unicode
- 6.6.2. [263]UCS Byte Order
- 6.6.2. [264]UCS Transformation Formats
- 6.6.3. [265]Conformance Levels
- 6.6.4. [266]Relationship of Unicode with Kermit's Other Character Sets
- 6.6.5. [267]Kermit's Unicode Features
- 6.6.5.1. [268]File Transfer
- 6.6.5.2. [269]The TRANSLATE Command
- 6.6.5.3. [270]Terminal Connection
- 6.6.5.4. [271]The TRANSMIT Command
- 6.6.5.5. [272]Summary of Kermit Unicode Commands
- 6.7. [273]Client/Server Character-Set Switching
- (7) [274]SCRIPT PROGRAMMING
- 7.0. [275]Bug Fixes
- 7.1. [276]The INPUT Command
- 7.1.1. [277]INPUT Timeouts
- 7.1.2. [278]New INPUT Controls
- 7.1.3. [279]INPUT with Pattern Matching
- 7.1.4. [280]The INPUT Match Result
- 7.2. [281]New or Improved Built-In Variables
- 7.3. [282]New or Improved Built-In Functions
- 7.4. [283]New IF Conditions
- 7.5. [284]Using More than Ten Macro Arguments
- 7.6. [285]Clarification of Function Call Syntax
- 7.7. [286]Autodownload during INPUT Command Execution
- 7.8. [287]Built-in Help for Functions.
- 7.9. [288]Variable Assignments
- 7.9.1. [289]Assignment Operators
- 7.9.2. [290]New Assignment Commands
- 7.10. [291]Arrays
- 7.10.1. [292]Array Initializers
- 7.10.2. [293]Turning a String into an Array of Words
- 7.10.3. [294]Arrays of Filenames
- 7.10.4. [295]Automatic Arrays
- 7.10.5. [296]Sorting Arrays
- 7.10.6. [297]Displaying Arrays
- 7.10.7. [298]Other Array Operations
- 7.10.8. [299]Hints for Using Arrays
- 7.10.9. [300]Do-It-Yourself Arrays
- 7.10.10. [301]Associative Arrays
- 7.11. [302]OUTPUT Command Improvements
- 7.12. [303]Function and Variable Diagnostics
- 7.13. [304]Return Value of Macros
- 7.14. [305]The ASSERT, FAIL, and SUCCEED Commands.
- 7.15. [306]Using Alarms
- 7.16. [307]Passing Arguments to Command Files
- 7.17. [308]Dialogs with Timed Responses
- 7.18. [309]Increased Flexibility of SWITCH Case Labels
- 7.19. "[310]Kerbang" Scripts
- 7.20. [311]IF and XIF Statement Syntax
- 7.20.1. [312]The IF/XIF Distinction
- 7.20.2. [313]Boolean Expressions (The IF/WHILE Condition)
- 7.21. [314]Screen Formatting and Cursor Control
- 7.22. [315]Evaluating Arithmetic Expressions
- 7.23. [316]Floating-Point Arithmetic
- 7.24. [317]Tracing Script Execution
- 7.25. [318]Compact Substring Notation
- 7.26. [319]New WAIT Command Options
- 7.26.1. [320]Waiting for Modem Signals
- 7.26.2. [321]Waiting for File Events
- 7.27. [322]Relaxed FOR and SWITCH Syntax
- (8) [323]USING OTHER FILE TRANSFER PROTOCOLS
- (9) [324]COMMAND-LINE OPTIONS
- 9.0. [325]Extended-Format Command-Line Options
- 9.1. [326]Command Line Personalities
- 9.2. [327]Built-in Help for Command Line Options
- 9.3. [328]New Command-Line Options
- (10) [329]C-KERMIT AND G-KERMIT
-
-III. [330]APPENDICES
-
-III.1. [331]Character Set Tables
-III.1.1. [332]The Hewlett Packard Roman8 Character Set
-III.1.2. [333]Greek Character Sets
-III.1.2.1. [334]The ISO 8859-7 Latin / Greek Alphabet
-III.1.2.2. [335]The ELOT 927 Character Set
-III.1.2.3. [336]PC Code Page 869
-III.2. [337]Updated Country Codes
-
-IV. [338]ERRATA & CORRIGENDA: Corrections to "Using C-Kermit" 2nd Edition.
-V. [339]ADDITIONAL COPYRIGHT NOTICES
-
-I. C-KERMIT DOCUMENTATION
-
- The user manual for C-Kermit is:
-
- Frank da Cruz and Christine M. Gianone, [340]Using C-Kermit, Second
- Edition, Digital Press / Butterworth-Heinemann, Woburn, MA, 1997,
- 622 pages, ISBN 1-55558-164-1.
-
- [341]CLICK HERE for reviews.
-
- The present document is a supplement to Using C-Kermit 2nd Ed, not a
- replacement for it.
-
- US single-copy price: $52.95; quantity discounts available. Available
- in bookstores or directly from Columbia University:
-
- The Kermit Project
- Columbia University
- 612 West 115th Street
- New York NY 10025-7799
- USA
- Telephone: +1 (212) 854-3703
- Fax: +1 (212) 662-6442
-
- Domestic and overseas orders accepted. Price: US $44.95 (US, Canada,
- and Mexico). Shipping: $4.00 within the USA; $15.00 to all other
- countries. Orders may be paid by MasterCard or Visa, or prepaid by
- check in US dollars. Add $65 bank fee for checks not drawn on a US
- bank. Do not include sales tax. Inquire about quantity discounts.
-
- You can also order by phone from the publisher, Digital Press /
- [342]Butterworth-Heinemann, with MasterCard, Visa, or American Express:
-
- +1 800 366-2665 (Woburn, Massachusetts office for USA & Canada)
- +44 1865 314627 (Oxford, England distribution centre for UK & Europe)
- +61 03 9245 7111 (Melbourne, Vic, office for Australia & NZ)
- +65 356-1968 (Singapore office for Asia)
- +27 (31) 2683111 (Durban office for South Africa)
-
- A [343]German-language edition of the First Edition is also available:
-
- Frank da Cruz and Christine M. Gianone, C-Kermit - Einf�hrung und
- Referenz, Verlag Heinz Heise, Hannover, Germany (1994). ISBN
- 3-88229-023-4. Deutsch von Gisbert W. Selke. Price: DM 88,00. Verlag
- Heinz Heise GmbH & Co. KG, Helstorfer Strasse 7, D-30625 Hannover.
- Tel. +49 (05 11) 53 52-0, Fax. +49 (05 11) 53 52-1 29.
-
- The [344]Kermit file transfer protocol is specified in:
-
- Frank da Cruz, Kermit, A File Transfer Protocol, Digital Press,
- Bedford, MA, 1987, 379 pages, ISBN 0-932376-88-6. US single-copy
- price: $39.95. Availability as above.
-
- News and articles about Kermit software and protocol are published
- periodically in the journal, [345]Kermit News. Subscriptions are free;
- contact Columbia University at the address above.
-
- Online news about Kermit is published in the
- [346]comp.protocols.kermit.announce and [347]comp.protocols.kermit.misc
- newsgroups.
-
-II. NEW FEATURES
-
- Support for the Bell Labs Plan 9 operating system was added to version
- 6.0 too late to be mentioned in the book (although it does appear on
- the cover).
-
- Specific changes and additions are grouped together by major topic,
- roughly corresponding to the chapters of [348]Using C-Kermit.
-
-0. INCOMPATIBILITIES WITH PREVIOUS RELEASES
-
- 1. C-Kermit 7.0 uses FAST Kermit protocol settings by default. This
- includes "unprefixing" of certain control characters. Because of
- this, file transfers that worked with previous releases might not
- work in the new release (but it is more likely that they will work,
- and much faster). If a transfer fails, you'll get a
- context-sensitive hint suggesting possible causes and cures.
- Usually SET PREFIXING ALL does the trick.
- 2. C-Kermit 7.0 transfers files in BINARY mode by default. To restore
- the previous behavior, put SET FILE TYPE TEXT in your C-Kermit
- initialization file.
- 3. No matter whether FILE TYPE is BINARY or TEXT by default, C-Kermit
- 7.0 now switches between text and binary mode automatically on a
- per-file basis according to various criteria, including (a) which
- kind of platform is on the other end of the connection (if known),
- (b) the version of Kermit on the other end, and (c) the file's name
- (see [349]Section 4, especially [350]4.3). To disable this
- automatic switching and restore the earlier behavior, put SET
- TRANSFER MODE MANUAL in your C-Kermit initialization file. To
- disable automatic switching for a particular transfer, include a
- /TEXT or /BINARY switch with your SEND or GET command.
- 4. The RESEND and REGET commands automatically switch to binary mode;
- previously if RESEND or REGET were attempted when FILE TYPE was
- TEXT, these commands would fail immediately, with a message telling
- you they work only when the FILE TYPE is BINARY. Now they simply do
- this for you. See [351]Section 4.23 for additional (important)
- information.
- 5. SET PREFIXING CAUTIOUS and MINIMAL now both prefix linefeed (10 and
- 138) in case rlogin, ssh, or cu are "in the middle", since
- otherwise <LF>~ might appear in Kermit packets, and this would
- cause rlogin, ssh, or cu to disconnect, suspend, escape back, or
- otherwise wreck the file transfer. Xon and Xoff are now always
- prefixed too, even when Xon/Xoff flow control is not in effect,
- since unprefixing them has proven dangerous on TCP/IP connections.
- 6. In UNIX, VMS, Windows, and OS/2, the DIRECTORY command is built
- into C-Kermit itself rather than implemented by running an external
- command or program. The built-in command might not behave the way
- the platform-specific external one did, but many options are
- available for customization. Of course the underlying
- platform-specific command can still be accessed with "!", "@", or
- "RUN" wherever the installation does not forbid. In UNIX, the "ls"
- command can be accessed directly as "ls" in C-Kermit. See
- [352]Section 4.5.1 for details.
- 7. SEND ? prints a list of switches rather than a list of filenames.
- If you want to see a list of filenames, use a (system-dependent)
- construction such as SEND ./? (for UNIX, Windows, or OS/2), SEND
- []? (VMS), etc. See [353]Sections 1.5 and [354]4.7.1.
- 8. In UNIX, OS-9, and Kermit 95, the wildcard characters in previous
- versions were * and ?. In C-Kermit 7.0 they are *, ?, [, ], {, and
- }, with dash used inside []'s to denote ranges and comma used
- inside {} to separate list elements. If you need to include any of
- these characters literally in a filename, precede each one with
- backslash (\). See [355]Section 4.9.
- 9. SET QUIET { ON, OFF } is now on the command stack, just like SET
- INPUT CASE, SET COUNT, SET MACRO ERROR, etc, as described on p.458
- of [356]Using C-Kermit, 2nd Edition. This allows any macro or
- command file to SET QUIET ON or OFF without worrying about saving
- and restoring the global QUIET value. For example, this lets you
- write a script that tries SET LINE on lots of devices until it
- finds one free without spewing out loads of error messages, and
- also without disturbing the global QUIET setting, whatever it was.
- 10. Because of the new "." operator (which introduces assignments),
- macros whose names begin with "." can not be invoked "by name".
- However, they still can be invoked with DO.
- 11. The syntax of the EVALUATE command has changed. See [357]Section
- 7.9.2. To restore the previous syntax, use SET EVALUATE OLD.
- 12. The \v(directory) variable now includes the trailing directory
- separator; in previous releases it did not. This is to allow
- constructions such as:
- cd \v(dir)data.tmp
-
- to work across platforms that might have different directory
- notation, such as UNIX, Windows, and VMS.
- 13. Prior to C-Kermit 7.0, the FLOW-CONTROL setting was global and
- sticky. In C-Kermit 7.0, there is an array of default flow-control
- values for each kind of connection, that are applied automatically
- at SET LINE/PORT/HOST time. Thus a SET FLOW command given before
- SET LINE/PORT/HOST is likely to be undone. Therefore SET FLOW can
- be guaranteed to have the desired effect only if given after the
- SET LINE/PORT/HOST command.
- 14. Character-set translation works differently in the TRANSMIT command
- when (a) the file character-set is not the same as the local end of
- the terminal character-set, or (b) when the terminal character-set
- is TRANSPARENT.
-
-1. PROGRAM AND FILE MANAGEMENT AND COMMANDS
-
-1.0. Bug Fixes
-
- The following patches were issued to correct bugs in C-Kermit 6.0.
- These are described in detail in the 6.0 PATCHES file. All of these
- fixes have been incorporated in C-Kermit 6.1 (never released except as
- K95 1.1.16-17) and 7.0.
-
- 0001 All UNIX C-Kermit mishandles timestamps on files before 1970
- 0002 Solaris 2.5++ Compilation error on Solaris 2.5 with Pro C
- 0003 All VMS CKERMIT.INI Fix for VMS
- 0004 VMS/VAX/UCX 2.0 C-Kermit 6.0 can't TELNET on VAX/VMS with UCX 2.0
- 0005 All C-Kermit Might Send Packets Outside Window
- 0006 All MOVE from SEND-LIST does not delete original files
- 0007 Solaris 2.5++ Higher serial speeds on Solaris 2.5
- 0008 All C-Kermit application file name can't contain spaces
- 0009 AT&T 7300 UNIXPC setuid and hardware flow-control problems
- 0010 Linux on Alpha Patch to make ckutio.c compile on Linux/Alpha
- 0011 OS-9/68000 2.4 Patch to make ck9con.c compile on OS-9/68000 2.4
- 0012 MW Coherent 4.2 Patches for successful build on Coherent 4.2
- 0013 SINIX-Y 5.43 "delay" variable conflicts with <sys/clock.h>
- 0014 VMS/VAX/CMU-IP Subject: Patches for VAX/VMS 5.x + CMU-IP
- 0015 All XECHO doesn't flush its output
- 0016 VMS CD and other directory operations might not work
- 0017 Linux 1.2.x++ Use standard POSIX interface for high serial speeds
- 0018 UNIX SET WILDCARD-EXPANSION SHELL dumps core
- 0019 All Hayes V.34 modem init string problem
- 0020 All READ command does not fail if file not open
- 0021 All Problems with long function arguments
- 0022 All Certain \function()s can misbehave
- 0023 All X MOD 0 crashes program
- 0024 All Internal bulletproofing for lower() function
- 0025 OpenBSD Real OpenBSD support for C-Kermit 6.0
- 0026 All Incorrect checks for macro/command-file nesting depth
- 0027 All ANSWER doesn't automatically CONNECT
- 0028 All Overzealous EXIT warning
- 0029 All OUTPUT doesn't echo when DUPLEX is HALF
- 0030 All Minor problems with REMOTE DIRECTORY/DELETE/etc
- 0031 All CHECK command broken
- 0032 All Problem with SET TRANSMIT ECHO
- 0033 UNIX, VMS, etc HELP SET SERVER says too much
- 0034 All READ and !READ too picky about line terminators
- 0035 All END from inside SWITCH doesn't work
- 0036 All Problem telnetting to multihomed hosts
- 0037 All Redirection failures in REMOTE xxx > file
-
- REDIRECT was missing in many UNIX C-Kermit implementations; in version
- 7.0, it should be available in all of them.
-
-1.1. Command Continuation
-
- Comments that start with ";" or "#" can no longer be continued. In:
-
- ; this is a comment -
- echo blah
-
- the ECHO command will execute, rather than being taken as a
- continuation of the preceding comment line. This allows easy
- "commenting out" of commands from macro definitions.
-
- However, the text of the COMMENT command can still be continued onto
- subsequent lines:
-
- comment this is a comment -
- echo blah
-
- As of version 6.0, backslash is no longer a valid continuation
- character. Only hyphen should be used for command continuation. This is
- to make it possible to issue commands like "cd a:\" on DOS-like
- systems.
-
- As of version 7.0:
-
- * You can quote a final dash to prevent it from being a continuation
- character:
- echo foo\-
-
- This prints "foo-". The command is not continued.
- * You can enter commands such as:
- echo foo - ; this is a comment
-
- interactively and they are properly treated as continued commands.
- Previously this worked only in command files.
-
-1.2. Editor Interface
-
- SET EDITOR name [ options ]
- Lets you specify a text-editing program. The name can be a fully
- specified pathname like /usr/local/bin/emacs19/emacs, or it can
- be the name of any program in your PATH, e.g. "set editor
- emacs". In VMS, it must be a DCL command like "edit",
- "edit/tpu", "emacs", etc. If an environment variable EDITOR is
- defined when Kermit starts, its value is the default editor. You
- can also specify options to be included on the editor command
- line. Returns to Kermit when the editor exits.
-
- EDIT [ filename ]
- If the EDIT command is given without a filename, then if a
- previous filename had been given to an EDIT command, it is used;
- if not, the editor is started without a file. If a filename is
- given, the editor is started on that file, and the filename is
- remembered for subsequent EDIT commands.
-
- SHOW EDITOR
- Displays the full pathname of your text editor, if any, along
- with any command line options, and the file most recently edited
- (and therefore the default filename for your next EDIT command).
-
- Related variables: \v(editor), \v(editopts), \v(editfile).
-
-1.3. Web Browser and FTP Interface
-
- C-Kermit includes an FTP command, which simply runs the FTP program;
- C-Kermit does not include any built-in support for Internet File
- Transfer Protocol, nor any method for interacting directly with an FTP
- server. In version 7.0, however, C-Kermit lets you specify your FTP
- client:
-
- SET FTP-CLIENT [ name [ options ] ]
- The name is the name of the FTP executable. In UNIX, Windows, or
- OS/2, it can be the filename of any executable program in your
- PATH (e.g. "ftp.exe" in Windows, "ftp" in UNIX); elsewhere (or
- if you do not have a PATH definition), it must be the fully
- specified pathname of the FTP program. If the name contains any
- spaces, enclose it braces. Include any options after the
- filename; these depend the particular ftp client.
-
- The Web browser interface is covered in the following subsections.
-
-1.3.1. Invoking your Browser from C-Kermit
-
- BROWSE [ url ]
- Starts your preferred Web browser on the URL, if one is given,
- otherwise on the most recently given URL, if any. Returns to
- Kermit when the browser exits.
-
- SET BROWSER [ name [ options ] ]
- Use this command to specify the name of your Web browser
- program, for example: "set browser lynx". The name must be in
- your PATH, or else it must be a fully specified filename; in VMS
- it must be a DCL command.
-
- SHOW BROWSER
- Displays the current browser, options, and most recent URL.
-
- Related variables: \v(browser), \v(browsopts), \v(browsurl).
-
- Also see [358]Section 2.15: Contacting Web Servers with the HTTP
- Command.
-
-1.3.2. Invoking C-Kermit from your Browser
-
- The method for doing this depends, of course, on your browser. Here are
- some examples:
-
- Netscape on UNIX (X-based)
- In the Options->Applications section, set your Telnet
- application to:
-
- xterm -e /usr/local/bin/kermit/kermit -J %h %p
-
- (replace "/usr/local/bin/kermit/kermit" by C-Kermit's actual
- pathname). -J is C-Kermit's command-line option to "be like
- Telnet"; %h and %p are Netscape placeholders for hostname and
- port.
-
- Lynx on UNIX
- As far as we know, this can be done only at compile time. Add
- the following line to the Lynx userdefs.h file before building
- the Lynx binary:
-
- #define TELNET_COMMAND "/opt/bin/kermit -J"
-
- And then add lines like the following to the Lynx.cfg file:
-
- DOWNLOADER:Kermit binary download:/opt/bin/kermit -i -V -s %s -a %s:TRUE
- DOWNLOADER:Kermit text download:/opt/bin/kermit -s %s -a %s:TRUE
-
- UPLOADER:Kermit binary upload:/opt/bin/kermit -i -r -a %s:TRUE
- UPLOADER:Kermit text upload:/opt/bin/kermit -r -a %s:TRUE
- UPLOADER:Kermit text get:/opt/bin/kermit -g %s:TRUE
- UPLOADER:Kermit binary get:/opt/bin/kermit -ig %s:TRUE
-
- But none of the above is necessary if you make C-Kermit your default
- Telnet client, which you can do by making a symlink called 'telnet' to
- the C-Kermit 7.0 binary. See [359]Section 9.1 for details.
-
-1.4. Command Editing
-
- Ctrl-W ("Word delete") was changed in 7.0 to delete back to the
- previous non-alphanumeric, rather than all the way back to the previous
- space.
-
-1.5. Command Switches
-
- As of version 7.0, C-Kermit's command parser supports a new type of
- field, called a "switch". This is an optional command modifier.
-
-1.5.1. General Switch Syntax
-
- A switch is a keyword beginning with a slash (/). If it takes a value,
- then the value is appended to it (with no intervening spaces),
- separated by a colon (:) or equal sign (=). Depending on the switch,
- the value may be a number, a keyword, a filename, a date/time, etc.
- Examples:
-
- send oofa.txt ; No switches
- send /binary oofa.zip ; A switch without a value
- send /protocol:zmodem oofa.zip ; A switch with a value (:)
- send /protocol=zmodem oofa.zip ; A switch with a value (=)
- send /text /delete /as-name:x.x oofa.txt ; Several switches
-
- Like other command fields, switches are separated from other fields,
- and from each other, by whitespace, as shown in the examples just
- above. You can not put them together like so:
-
- send/text/delete/as-name:x.x oofa.txt
-
- (as you might do in VMS or DOS, or as we might once have done in
- TOPS-10 or TOPS0-20, or PIP). This is primarily due to ambiguity
- between "/" as switch introducer versus "/" as UNIX directory
- separator; e.g. in:
-
- send /delete/as-name:foo/text oofa.txt
-
- Does "foo/text" mean the filename is "foo" and the transfer is to be in
- text mode, or does it mean the filename is "foo/text"? Therefore we
- require whitespace between switches to resolve the ambiguity. (That's
- only one of several possible ambiguities -- it is also conceivable that
- a file called "text" exists in the path "/delete/as-name:foo/").
-
- In general, if a switch can take a value, but you omit it, then either
- a reasonable default value is supplied, or an error message is printed:
-
- send /print:-Plaserwriter oofa.txt ; Value included = print options
- send /print oofa.txt ; Value omitted, OK
- send /mail:kermit@columbia.edu oofa.txt ; Value included = address
- send /mail oofa.txt ; Not OK - address required
- ?Address required
-
- Context-sensitive help (?) and completion (Esc or Tab) are available in
- the normal manner:
-
- C-Kermit> send /pr? Switch, one of the following:
- /print /protocol
- C-Kermit> send /pro<ESC>tocol:? File-transfer protocol,
- one of the following:
- kermit xmodem ymodem ymodem-g zmodem
- C-Kermit> send /protocol:k<TAB>ermit
-
- If a switch takes a value and you use completion on it, a colon (:) is
- printed at the end of its name to indicate this. If it does not take a
- value, a space is printed.
-
- Also, if you type ? in a switch field, switches that take values are
- shown with a trailing colon; those that don't take values are shown
- without one.
-
-1.5.2. Order and Effect of Switches
-
- The order of switches should not matter, except that they are evaluated
- from left to right, so if you give two switches with opposite effects,
- the rightmost one is used:
-
- send /text /binary oofa.zip ; Sends oofa.zip in binary mode.
-
- Like other command fields, switches have no effect whatsoever until the
- command is entered (by pressing the Return or Enter key). Even then,
- switches affect only the command with which they are included; they do
- not have global effect or side effects.
-
-1.5.3. Distinguishing Switches from Other Fields
-
- All switches are optional. A command that uses switches lets you give
- any number of them, including none at all. Example:
-
- send /binary oofa.zip
- send /bin /delete oofa.zip
- send /bin /as-name:mupeen.zip oofa.zip
- send oofa.zip
-
- But how does Kermit know when the first "non-switch" is given? It has
- been told to look for both a switch and for something else, the data
- type of the next field (filename, number, etc). In most cases, this
- works well. But conflicts are not impossible. Suppose, for example, in
- UNIX there was a file named "text" in the top-level directory. The
- command to send it would be:
-
- send /text
-
- But C-Kermit would think this was the "/text" switch. To resolve the
- conflict, use braces:
-
- send {/text}
-
- or other circumlocutions such as "send //text", "send /./text", etc.
-
- The opposite problem can occur if you give an illegal switch that
- happens to match a directory name. For example:
-
- send /f oofa.txt
-
- There is no "/f" switch (there are several switches that begin with
- "/f", so "/f" is ambiguous). Now suppose there is an "f" directory in
- the root directory; then this command would be interpreted as:
-
- Send all the files in the "/f" directory, giving each one an as-name
- of "oofa.txt".
-
- This could be a mistake, or it could be exactly what you intended;
- C-Kermit has no way of telling the difference. To avoid situations like
- this, spell switches out in full until you are comfortable enough with
- them to know the minimum abbreviation for each one. Hint: use ? and
- completion while typing switches to obtain the necessary feedback.
-
-1.5.4. Standard File Selection Switches
-
- The following switches are used on different file-oriented commands
- (such as SEND, DIRECTORY, DELETE, PURGE) to refine the selection of
- files that match the given specification.
-
- /AFTER:date-time
- Select only those files having a date-time later than the one
- given. See [360]Section 1.6 for date-time formats. Synonym:
- /SINCE.
-
- /NOT-AFTER:date-time
- Select only those files having a date-time not later than (i.e.
- earlier or equal to) the one given. Synonym: /NOT-SINCE.
-
- /BEFORE:date-time
- Select only those files having a date-time earlier than the one
- given.
-
- /NOT-BEFORE:date-time
- Select only those files having a date-time not earlier than
- (i.e. later or equal to) the one given.
-
- /DOTFILES
- UNIX and OS-9 only: The filespec is allowed to match files whose
- names start with (dot) period. Normally these files are not
- shown.
-
- /NODOTFILES
- (UNIX and OS-9 only) Don't show files whose names start with dot
- (period). This is the opposite of /DOTFILES, and is the default.
- Note that when a directory name starts with a period, the
- directory and (in recursive operations) all its subdirectories
- are skipped.
-
- /LARGER-THAN:number
- Only select files larger than the given number of bytes.
-
- /SMALLER-THAN:number
- Only select files smaller than the given number of bytes.
-
- /EXCEPT:pattern
- Specifies that any files whose names match the pattern, which
- can be a regular filename, or may contain "*" and/or "?"
- metacharacters (wildcards), are not to be selected. Example:
-
- send /except:*.log *.*
-
- sends all files in the current directory except those with a
- filetype of ".log". Another:
-
- send /except:*.~*~ *.*
-
- sends all files except the ones that look like Kermit or EMACS
- backup files (such as "oofa.txt.~17~") (of course you can also
- use the /NOBACKUP switch for this).
-
- The pattern matcher is the same one used by IF MATCH string
- pattern ([361]Section 7.4), so you can test your patterns using
- IF MATCH. If you need to match a literal * or ? (etc), precede
- it by a backslash (\). If the pattern contains any spaces, it
- must be enclosed in braces:
-
- send /except:{Foo bar} *.*
-
- The pattern can also be a list of up to 8 patterns. In this
- case, the entire pattern must be enclosed in braces, and each
- sub-pattern must also be enclosed in braces; this eliminates the
- need for designating a separator character, which is likely to
- also be a legal filename character on some platform or other,
- and therefore a source of confusion. You may include spaces
- between the subpatterns but they are not necessary. The
- following two commands are equivalent:
-
- send /except:{{ck*.o} {ck*.c}} ck*.?
- send /except:{{ck*.o}{ck*.c}} ck*.?
-
- If a pattern is to include a literal brace character, precede it
- with "\". Also note the apparent conflict of this list format
- and the string-list format described in [362]Section 4.9.1. In
- case you want to include a wildcard string-list with braces on
- its outer ends as an /EXCEPT: argument, do it like this:
-
- send /except:{{{ckuusr.c,ckuus2.c,ckuus6.c}}} ckuus*.c
-
-1.5.5. Setting Preferences for Different Commands
-
- Certain oft-used commands offer lots of switches because different
- people have different requirements or preferences. For example, some
- people want to be able to delete files without having to watch a list
- of the deleted files scroll past, while others want to be prompted for
- permission to delete each file. Different people prefer different
- directory-listing styles. And so on. Such commands can be tailored with
- the SET OPTIONS command:
-
- SET OPTIONS command [ switch [ switch [ ... ] ] ]
- Sets each switch as the default for the given command, replacing
- the "factory default". Of course you can also override any
- defaults established by the SET OPTIONS command by including the
- relevant switches in the affected command any time you issue it.
-
- SHOW OPTIONS
- Lists the commands that allows option-setting, and the options
- currently in effect, if any, for each. Switches that have
- synonyms are shown under their primary name; for example. /LOG
- and /VERBOSE are shown as /LIST.
-
- Commands for which options may be set include DIRECTORY, DELETE, PURGE,
- and TYPE. Examples:
-
- SET OPTIONS DIRECTORY /PAGE /NOBACKUP /HEADING /SORT:DATE /REVERSE
- SET OPTIONS DELETE /LIST /NOHEADING /NOPAGE /NOASK /NODOTFILES
- SET OPTIONS TYPE /PAGE
-
- Not necessarily all of a command's switches can be set as options. For
- example, file selection switches, since these would normally be
- different for each command.
-
- Put the desired SET OPTIONS commands in your C-Kermit customization
- file for each command whose default switches you want to change every
- time you run C-Kermit.
-
-1.6. Dates and Times
-
- Some commands and switches take date-time values, such as:
-
- send /after:{8-Feb-2000 10:28:01}
-
- Various date-time formats are acceptable. The rules for the date are:
-
- * The year must have 4 digits.
- * If the year comes first, the second field is the month.
- * The day, month, and year may be separated by spaces, /, -, or
- underscore.
- * The month may be numeric (1 = January) or spelled out or
- abbreviated in English.
-
- If the date-time string contains any spaces, it must be enclosed in
- braces. Examples of legal dates:
-
- Interpretation:
- 2000-Feb-8 8 February 2000
- {2000 Feb 8} 8 February 2000
- 2000/Feb/8 8 February 2000
- 2000_Feb_8 8 February 2000
- 2000-2-8 8 February 2000
- 2000-02-08 8 February 2000
- 8-Feb-2000 8 February 2000
- 08-Feb-2000 8 February 2000
- 12/25/2000 25 December 2000
- 25/12/2000 25 December 2000
-
- The last two examples show that when the year comes last, and the month
- is given numerically, the order of the day and month doesn't matter as
- long as the day is 13 or greater (mm/dd/yyyy is commonly used in the
- USA, whereas dd/mm/yyyy is the norm in Europe). However:
-
- 08/02/2000 Is ambiguous and therefore not accepted.
-
- If a date is given, the time is optional and defaults to 00:00:00. If
- the time is given with a date, it must follow the date, separated by
- space, /, -, or underscore, and with hours, minutes, and seconds
- separated by colon (:). Example:
-
- 2000-Feb-8 10:28:01 Represents 8 February 2000, 10:28:01am
-
- If a date is not given, the current date is used and a time is
- required.
-
- Time format is hh:mm:ss or hh:mm or hh in 24-hour format, or followed
- by "am" or "pm" (or "AM" or "PM") to indicate morning or afternoon.
- Examples of times that are acceptable:
-
- Interpretation:
- 3:23:56 3:23:56am
- 3:23:56am 3:23:56am
- 3:23:56pm 3:23:56pm = 15:23:56
- 15:23:56 3:23:56pm = 15:23:56
- 3:23pm 3:23:00pm = 15:23:00
- 3:23PM 3:23:00pm = 15:23:00
- 3pm 3:00:00pm = 15:00:00
-
- Examples of legal date-times:
-
- send /after:{8 Feb 2000 10:28:01}
- send /after:8_Feb_2000_10:28:01
- send /after:8-Feb-2000/10:28:01
- send /after:2000/02/08/10:28:01
- send /after:2000/02/08_10:28:01
- send /after:2000/02/08_10:28:01am
- send /after:2000/02/08_10:28:01pm
- send /after:2000/02/08_10:28pm
- send /after:2000/02/08_10pm
- send /after:10:00:00pm
- send /after:10:00pm
- send /after:10pm
- send /after:22
-
- Finally, there is a special all-numeric format you can use:
-
- yyyymmdd hh:mm:ss
-
- For example:
-
- 20000208 10:28:01
-
- This is Kermit's standard date-time format (based on ISO 8601), and is
- accepted (among other formats) by any command or switch that requires a
- date-time, and is output by any function whose result is a calendar
- date-time.
-
- There are no optional parts to this format and it must be exactly 17
- characters long, punctuated as shown (except you can substitute
- underscore for space in contexts where a single "word" is required).
- The time is in 24-hour format (23:00:00 is 11:00pm). This is the format
- returned by \fdate(filename), so you can also use constructions like
- this:
-
- send /after:\fdate(oofa.txt)
-
- which means "all files newer than oofa.txt".
-
- Besides explicit dates, you can also use the any of the following
- shortcuts:
-
- TODAY
- Stands for the current date at 00:00:00.
-
- TODAY 12:34:56
- Stands for the current date at the given time.
-
- YESTERDAY
- Stands for yesterday's date at 00:00:00. A time may also be
- given.
-
- TOMORROW
- Stands for tomorrow's date at 00:00:00. A time may also be
- given.
-
- + number { DAYS, WEEKS, MONTHS, YEARS } [ time ]
- Is replaced by the future date indicated, relative to the
- current date. If the time is omitted, 00:00:00 is used.
- Examples: +3days, +2weeks, +1year, +37months.
-
- - number { DAYS, WEEKS, MONTHS, YEARS } [ time ]
-
- Is replaced by the past date indicated, relative to the current
- date. If the time is omitted, 00:00:00 is used.
-
- The time can be separated from the date shortcut by any of the same
- separators that are allowed for explicit date-times: space, hyphen,
- slash, period, or underscore. In switches and other space-delimited
- fields, use non-spaces to separate date/time fields, or enclose the
- date-time in braces, e.g.:
-
- purge /before:-4days_12:00:00
- purge /before:{- 4 days 12:00:00}
-
- Of course you can also use variables:
-
- define \%n 43
- purge /before:-\%ndays_12:00:00
-
- Shortcut names can be abbreviated to any length that still
- distinguishes them from any other name that can appear in the same
- context, e.g. "TOD" for today, "Y" for yesterday. Also, the special
- abbreviation "wks" is accepted for WEEKS, and "yrs" for "YEARS".
-
- (To see how to specify dates relative to a specific date, rather than
- the current one, see the [363]\fmjd() function description below.)
-
- You can check date formats with the DATE command. DATE by itself prints
- the current date and time in standard format: yyyymmdd hh:mm:ss. DATE
- followed by a date and/or time (including shortcuts) converts it to
- standard format if it can understand it, otherwise it prints an error
- message.
-
- The following variables and functions deal with dates and times; any
- function argument designated as "date-time" can be in any of the
- formats described above.
-
- \v(day)
- The first three letters of the English word for the current day
- of the week, e.g. "Wed".
-
- \fday(date-time)
- The first three letters of the English word for day of the week
- of the given date. If a time is included, it is ignored.
- Example: \fday(8 Feb 1988) = "Mon".
-
- \v(nday)
- The numeric day of the week: 0 = Sunday, 1 = Monday, ..., 6 =
- Saturday.
-
- \fnday(date-time)
- The numeric day of the week for the given date. If a time is
- included, it is ignored. Example: \fnday(8 Feb 1988) = "1".
-
- \v(date)
- The current date as dd mmm yyyy, e.g. "08 Feb 2000" (as in this
- example, a leading zero is supplied for day-of-month less than
- 10).
-
- \v(ndate)
- The current date in numeric format: yyyymmdd, e.g. "20000208".
-
- \v(time)
- The current time as hh:mm:ss, e.g. "15:27:14".
-
- \ftime(time)
- The given free-format date and/or time (e.g. "3pm") returns the
- time (without the date) converted to hh:mm:ss 24-hour format,
- e.g. "15:00:00" (the date, if given, is ignored).
-
- \v(ntime)
- The current time as seconds since midnight, e.g. "55634".
-
- \v(tftime)
- The elapsed time of the most recent file-transfer operation in
- seconds.
-
- \v(intime)
- The elapsed time for the most recent INPUT command to complete,
- in milliseconds.
-
- \fntime(time)
- The given free-format date and/or time is converted to seconds
- since midnight (the date, if given, is ignored). This function
- replaces \ftod2secs(), which is now a synonym for \fntime().
- Unlike \ftod2secs(), \fntime() allows a date to be included, and
- it allows the time to be in free format (like 3pm), and it
- allows the amount of time to be more than 24 hours. E.g.
- \fntime(48:00:00) = 172800. Example of use:
-
- set alarm \fntime(48:00:00) ; set alarm 48 hours from now.
-
- \fn2time(seconds)
- The given number of seconds is converted to hh:mm:ss format.
-
- \fdate(filename)
- Returns the modification date-time of the given file in standard
- format: yyyymmdd hh:mm:ss.
-
- \fcvtdate(date-time)
- Converts a free-format date and/or time to Kermit standard
- format: yyyymmdd hh:mm:ss. If no argument is given, returns the
- current date-time in standard format. If a date is given but no
- time, the converted date is returned without a time. If a time
- is given with no date, the current date is supplied. Examples:
-
- \fcvtdate(4 Jul 2000 2:21:17pm) = 20000704 14:21:17
- \fcvtdate() = 20000704 14:21:17 (on 4 Jul 2000 at 2:21:17pm).
- \fcvtd(4 Jul 2000) = 20000704
- \fcvtd(6pm) = 20000704 18:00:00 (on 4 Jul 2000 at 6:00pm).
-
- \fdayofyear(date-time)
- \fdoy(date-time)
- Converts a free-format date and/or time to yyyyddd, where ddd is
- the 3-digit day of the year, and 1 January is Day 1. If a time
- is included with the date, it is returned in standard format. If
- a date is included but no time, the date is returned without a
- time. If a time is given with no date, the time is converted and
- the current date is supplied. If no argument is given, the
- current date-time is returned. Synonym: \fdoy(). Examples:
-
- \fddayofyear(4 Jul 2000 2:21:17pm) = 2000185 14:21:17
- \fdoy() = 2000185 14:21:17 (on 4 Jul 2000 at 2:21:17pm).
- \fdoy(4 Jul 2000) = 2000185
- \fdoy(6pm) = 2000185 18:00:00 (on 4 Jul 2000 at 6:00pm).
-
- Note: The yyyyddd day-of-year format is often erroneously referred to
- as a Julian date. However, a true Julian date is a simple counting
- number, the number of days since a certain fixed day in the past.
- [364]See \fmjd() below.
-
- \fdoy2date(date-time)
- Converts a date or date-time in day-of-year format to a standard
- format date. A yyyyddd-format date must be supplied; time is
- optional. The given date is converted to yyyymmdd format. If a
- time is given, it is converted to 24-hour format. Examples:
-
- \fdoy2date(2000185) = 20000704
- \fdoy2(2000185 3pm) = 20000704 15:00:00
-
- \fmjd(date-time)
- Converts free-format date and/or time to a Modified Julian Date
- (MJD), the number of days since 17 Nov 1858 00:00:00. If a time
- is given, it is ignored. Examples:
-
- \fmjd(4 Jul 2000) = 50998
- \fmjd(17 Nov 1858) = 0
- \fmjd(16 Nov 1858) = -1
-
- \fmjd2date(mjd)
- Converts an MJD (integer) to standard date format, yyyymmdd:
-
- \fmjd2(50998) = 4 Jul 1998
- \fmjd2(0) = 17 Nov 1858
- \fmjd2(-1) = 16 Nov 1858
- \fmjd2(-365) = 17 Nov 1857
-
- MJDs are normal integers and, unlike DOYs, may be added, subtracted,
- etc, with each other or with other integers, to obtain meaningful
- results. For example, to find out the date 212 days ago:
-
- echo \fmjd2date(\fmjd()-212)
-
- Constructions such as this can be used in any command where a date-time
- is required, e.g.:
-
- send /after:\fmjd2date(\fmjd()-212)
-
- to send all files that are not older than 212 days (this is equivalent
- to "send /after:-212days").
-
- MJDs also have other regularities not exhibited by other date formats.
- For example, \fmodulus(\fmjd(any-date),7) gives the day of the week for
- any date (where 4=Sun, 5=Mon, ..., 3=Sat). (However, it is easier to
- use \fnday() for this purpose, and it gives the more conventional
- result of 0=Sun, 1=Mon, ..., 6=Sat).
-
- Note that if MJDs are to be compared, they must be compared numerically
- (IF <, =, >) and not lexically (IF LLT, EQUAL, LGT), whereas DOYs must
- be compared lexically if they include a time (which contains ":"
- characters); however, if DOYs do not include a time, they may also be
- compared numerically.
-
- In any case, lexical comparison of DOYs always produces the appropriate
- result, as does numeric comparison of MJDs.
-
- The same comments apply to sorting. Also note that DOYs are fixed
- length, but MJDs can vary in length. However, all MJDs between 3 April
- 1886 and 30 Aug 2132 are 5 decimal digits long. (MJDs become 6 digits
- long on 31 Aug 2132, and 7 digits long on 13 Oct 4596).
-
-1.7. Partial Completion of Keywords
-
- Partial completion of keywords was added in C-Kermit 7.0. In prior
- versions, if completion was attempted (by pressing the Esc or Tab key)
- on a string that matched different keywords, you'd just get a beep. Now
- Kermit completes up to the first character where the possibly matching
- keywords differ and then beeps. For example:
-
- C-Kermit> send /n<Tab>
-
- which matches /NOT-BEFORE and /NOT-AFTER, now completes up to the dash:
-
- C-Kermit> send /n<Tab>ot-<Beep>
-
- Partial completion works for filenames too (as it has for some years).
-
-1.8. Command Recall
-
- C-Kermit has had a command history buffer for some time, which could be
- scrolled interactively using control characters or (in Kermit 95 only)
- arrow keys. Version 7.0 adds a REDO command that allows the most recent
- command matching a given pattern to be re-executed:
-
- { REDO, RR, ^ } [ pattern ]
- Search the command history list for the most recent command that
- matches the given pattern, and if one is found, execute it
- again.
-
- The pattern can be a simple string (like "send"), in which case the
- last SEND command is re-executed. Or it can contain wildcard characters
- "*" and/or "?", which match any string and any single character,
- respectively (note that "?" must be preceded by backslash to override
- its normal function of giving help), and in most C-Kermit versions may
- also include [] character lists and {} string lists (see [365]Section
- 4.9).
-
- The match works by appending "*" to the end of the given pattern (if
- you didn't put one there yourself). Thus "redo *oofa" becomes "redo
- *oofa*" and therefore matches the most recent command that contains
- "oofa" anywhere within the command. If you want to inhibit the
- application of the trailing "*", e.g. to force matching a string at the
- end of a command, enclose the pattern in braces:
-
- redo {*oofa}
-
- matches the most recent command that ends with "oofa".
-
- REDO commands themselves are not entered into the command history list.
- If no pattern is given, the previous (non-REDO) command is re-executed.
- The REDOne command is reinserted at the end of the command history
- buffer, so the command scrollback character (Ctrl-P, Ctrl-B, or
- Uparrow) can retrieve it.
-
- Examples:
-
- C-Kermit> echo foo
- foo
- C-Kermit> show alarm
- (no alarm set)
- C-Kermit> echo blah
- blah
- C-Kermit> redo ; Most recent command
- blah
- C-Kermit> redo s ; Most recent command starting with "s"
- (no alarm set)
- C-Kermit> redo echo f ; Most recent command starting with "echo f"
- foo
- C-Kermit> redo *foo ; Most recent command that has "foo" in it
- foo
- C-Kermit> <Ctrl-P> ; Scroll back
- C-Kermit> echo foo ; The REDOne command is there
- C-Kermit> redo {*foo} ; Most recent command that ends with "foo"
- foo
- C-Kermit>
-
- Since REDO, REDIAL, and REDIRECT all start the same way, and RED is the
- designated non-unique abbreviation for REDIAL, REDO must be spelled out
- in full. For convenience, RR is included as an invisible easy-to-type
- synonym for REDO. You can also use the "^" character for this:
-
- C-Kermit> ^ ; Most recent command
- C-Kermit> ^ s ; Most recent command starting with "s"
- C-Kermit> ^s ; Ditto (space not required after "^").
- C-Kermit> ^*foo ; Most recent command that has "foo" in it.
- C-Kermit> ^{*foo} ; Most recent command ends with "foo".
-
- Unlike the manual command-history-scrolling keys, the REDO command can
- be used in a script, but it's not recommended (since the command to be
- REDOne might not be found, so if the REDO command fails, you can't tell
- whether it was because REDO failed to find the requested command, or
- because the command was found but it failed).
-
-1.9. EXIT Messages
-
- The EXIT and QUIT commands now accept an optional message to be
- printed. This makes the syntax of EXIT and QUIT just like END and STOP:
-
- { EXIT, QUIT, END, STOP } [ status-code [ message ] ]
-
- where status-code is a number (0 indicating success, nonzero indicating
- failure). This is handy in scripts that are never supposed to enter
- interactive mode:
-
- dial 7654321
- if fail exit 1 Can't make connection - try again later.
-
- Previously this could only be done in two steps:
-
- dial 7654321
- xif fail { echo Can't make connection - try again later, exit 1 }
-
- A status code must be included in order to specify a message. In the
- case of EXIT and QUIT, the default status code is contained in the
- variable \v(exitstatus), and is set automatically by various events
- (file transfer failures, etc; it can also be set explicitly with the
- SET EXIT STATUS command). If you want to give an EXIT or QUIT command
- with a message, but without changing the exit status from what it
- normally would have been, use the \v(exitstatus) variable, e.g.:
-
- exit \v(exitstatus) Goodbye from \v(cmdfile).
-
- The EXIT status is returned to the system shell or whatever other
- process invoked C-Kermit, e.g. in UNIX:
-
- C-Kermit> exit 97 bye bye
- bye bye
- $ echo $?
- 97
- $
-
-1.10. Managing Keyboard Interruptions
-
- When C-Kermit is in command or file-transfer mode (as opposed to
- CONNECT mode), it can be interrupted with Ctrl-C. Version 7.0 adds the
- ability to disarm the Ctrl-C interrupt:
-
- SET COMMAND INTERRUPT { ON, OFF }
- COMMAND INTERRUPT is ON by default, meaning the Ctrl-C can be
- used to interrupt a command or a file transfer in progress. Use
- OFF to disable these interruptions, and use it with great
- caution for obvious reasons.
-
- SET TRANSFER INTERRUPT { ON, OFF }
- This can be used to disable keyboard interruption of file
- transfer when C-Kermit is in local mode, or to re-enable it
- after it has been disabled. This applies to the X, Z, E, and
- similar keys as well as to the system interrupt character,
- usually Ctrl-C. This is distinct from SET TRANSFER CANCELLATION,
- which tells whether packet mode can be exited by sending a
- special sequence of characters.
-
- Several other commands can be interrupted by pressing any key while
- they are active. Version 7.0 adds the ability to disable this form of
- interruption also:
-
- SET INPUT CANCELLATION { ON, OFF }
- Whether an INPUT command in progress can be interrupted by
- pressing a key. Normally ON. Setting INPUT CANCELLATION OFF
- makes INPUT commands uninterruptible except by Ctrl-C (unless
- COMMAND INTERRUPTION is also OFF).
-
- SET SLEEP CANCELLATION { ON, OFF }
- Whether a SLEEP, PAUSE, or WAIT command in progress can be
- interrupted by pressing a key. Normally ON. Setting SLEEP
- CANCELLATION OFF makes these commands uninterruptible except by
- Ctrl-C (unless COMMAND INTERRUPTION is also OFF). Synonyms: SET
- PAUSE CANCELLATION, SET WAIT CANCELLATION.
-
- So to make certain a script is not interruptible by the user, include
- these commands:
-
- SET TRANSFER INTERRUPT OFF
- SET SLEEP CANCELLATION OFF
- SET INPUT CANCELLATION OFF
- SET COMMAND INTERRUPTION OFF
-
- Make sure to turn them back on afterwards if interruption is to be
- re-enabled.
-
- When a PAUSE, SLEEP, WAIT, or INPUT command is interrupted from the
- keyboard, the new variable \v(kbchar) contains a copy of the (first)
- character that was typed and caused the interruption, provided it was
- not the command interrupt character (usually Ctrl-C). If these commands
- complete successfully or time out without a keyboard interruption, the
- \v(kbchar) variable is empty.
-
- The \v(kbchar) variable (like any other variable) can be tested with:
-
- if defined \v(kbchar) command
-
- The command is executed if the variable is not empty.
-
- The \v(kbchar) variable can be reset with WAIT 0 (PAUSE 0, SLEEP 0,
- etc).
-
-1.11. Taming The Wild Backslash -- Part Deux
-
- [366]Using C-Kermit, 2nd Edition, contains a brief section, "Taming the
- Wild Backslash", on page 48, which subsequent experience has shown to
- be inadequate for Kermit users intent on writing scripts that deal with
- Windows, DOS, and OS/2 filenames, in which backslash (\) is used as the
- directory separator. This section fills in the blanks.
-
-1.11.1. Background
-
- The Kermit command language shares a certain unavoidable but annoying
- characteristic with most other command languages that are capable of
- string replacement, namely the necessity to "quote" certain characters
- when you want them to be taken literally. This is a consequence of the
- facts that:
-
- 1. One or more characters must be set aside to denote replacement,
- rather than acting as literal text.
- 2. We have only 96 printable characters to work with in ASCII, which
- is still the only universally portable character set.
- 3. There is no single printable character that is unused everywhere.
- 4. Variables are not restricted to certain contexts, as they are in
- formal programming languages like C and Fortran, but can appear
- anywhere at all within a command, and therefore require special
- syntax.
-
- Thus there can be conflicts. To illustrate, the standard UNIX shell
- uses dollar sign ($) to introduce variables. So the shell command:
-
- echo $TERM
-
- displays the value of the TERM variable, e.g. vt320. But suppose you
- want to display a real dollar sign:
-
- echo The price is $10.20
-
- This causes the shell to evaluate the variable "$1", which might or
- might not exist, and substitute its value, e.g.:
-
- The price is 0.20
-
- (in this case the $1 variable had no value.) This is probably not what
- you wanted. To force the dollar sign to be taken literally, you must
- apply a "quoting rule", such as "precede a character by backslash (\)
- to force the shell to take the character literally":
-
- echo The price is \$10.20
- The price is $10.20
-
- But now suppose you want the backslash AND the dollar sign to be taken
- literally:
-
- echo The price is \\$10.20
-
- This doesn't work, since the first backslash quotes the second one,
- thereby leaving the dollar sign unquoted again:
-
- The price is \0.20
-
- Quoting the dollar sign requires addition of a third backslash:
-
- echo The price is \\\$10.20
- The price is \$10.20
-
- The first backslash quotes the second one, and the third backslash
- quotes the dollar sign.
-
- Every command language -- all UNIX shells, VMS DCL, DOS Batch, AOS/VS
- CLI, etc etc -- has similar rules. UNIX shell rules are probably the
- most complicated, since many printable characters -- not just one --
- are special there: dollar sign, single quote, double quote, backslash,
- asterisk, accent grave, number sign, ampersand, question mark,
- parentheses, brackets, braces, etc -- practically every
- non-alphanumeric character needs some form of quoting if it is to be
- taken literally. And to add to the confusion, the UNIX shell offers
- many forms of quoting, and many alternative UNIX shells are available,
- each using slightly different syntax.
-
-1.11.2. Kermit's Quoting Rules
-
- Kermit's basic quoting rules are simple by comparison (there are, of
- course, additional syntax requirements for macro definitions, command
- blocks, function calls, etc, but they are not relevant here).
-
- The following characters are special in Kermit commands:
-
- Backslash (\)
- Introduces a variable, or the numeric representation of a
- special character, or a function, or other item for
- substitution. If the backslash is followed by a digit or by any
- of the following characters:
-
- x, o, d, m, s, f, v, $, %, &, :, {
-
- this indicates a special substitution item; otherwise the
- following character is to be taken literally (exceptions: \ at
- end of line is taken literally; \n, \b, and \n are special items
- in the OUTPUT command only).
-
- Semicolon (;)
- (Only when at the beginning of a line or preceded by at least
- one space or tab) Introduces a comment.
-
- Number sign (#)
- (Only when at the beginning of a line or preceded by at least
- one space or tab) Just like semicolon; introduces a comment.
-
- Question mark (?)
- (Only at the command prompt - not in command files or macros)
- Requests context-sensitive help.
-
- To force Kermit to take any of these characters literally, simply
- precede it by a backslash (\).
-
- Sounds easy! And it is, except when backslash also has a special
- meaning to the underlying operating system, as it does in DOS, Windows,
- and OS/2, where it serves as the directory separator in filenames such
- as:
-
- D:\K95\KEYMAPS\READ.ME
-
- Using our rule, we would need to refer to this file in Kermit commands
- as follows:
-
- D:\\K95\\KEYMAPS\\READ.ME
-
- But this would not be obvious to new users of Kermit software on DOS,
- Windows, or OS/2, and it would be annoying to seasoned ones. Thus
- MS-DOS Kermit and Kermit 95 go to rather extreme lengths to allow the
- more natural notation, as in:
-
- send d:\k95\keymaps\read.me
-
- The reason this is tricky is that we also need to allow for variables
- and other expressions introduced by backslash in the same command. For
- example, suppose \%a is a variable whose value is "oofa" (without the
- quotes). What does the following command do?
-
- send d:\%a
-
- Does it send the file named "oofa" in the current directory of the D:
- disk, or does it send a file named "%a" in the root directory of the D:
- disk? This is the kind of trouble we get into when we attempt to bend
- the rules in the interest of user friendliness. (The answer is: if the
- variable \%a has definition that is the name of an existing file, that
- file is sent; if a file d:\%a exists, it is sent; otherwise if both
- conditions are true, the variable takes precedence, and the literal
- filename can be forced by quoting: \\%a.)
-
- In Kermit 95 (but not MS-DOS Kermit), we also bend the rules another
- way by allowing you to use forward slash (/) rather than backslash (\)
- as the directory separator:
-
- send d:/k95/keymaps/read.me
-
- This looks more natural to UNIX users, and in fact is perfectly
- acceptable to the Windows 95/98/NT and OS/2 operating systems on the
- API level. BUT (there is always a "but") the Microsoft shell,
- COMMAND.COM, for Windows 95/98 and NT does not allow this notation, and
- therefore it can not be used in any Kermit command -- such as RUN --
- that invokes the Windows command shell AND your command shell is
- COMMAND.COM or any other shell that does not allow forward slash as
- directory separator (some alternative shells do allow this).
-
- NOTE: There exists a wide variety of alternative shells from third
- parties that do not have this restriction. If you are using a shell
- that accepts forward slash as a directory separator, you can stop
- reading right now -- UNLESS (there is always an "unless") you want
- your scripts to be portable to systems that have other shells. Also
- note that some Windows shells might actually REQUIRE forward slashes
- (instead of backslashes) as directory separators; we do not treat
- this situation below, but the treatment is obvious -- use slash
- rather backslash as the directory separator.
-
-1.11.3. Passing DOS Filenames from Kermit to Shell Commands
-
- The following Kermit commands invoke the system command shell:
-
- RUN (and its synonyms ! and @)
- REDIRECT
- PIPE
-
- Each of these commands takes a shell command as an operand. These shell
- commands are not, and can not be, parsed by Kermit since Kermit does
- not know the syntax of shell commands, and so can't tell the difference
- between a keyword, a filename, a variable, a switch, or other item.
- Therefore the rules can not be bent since Kermit doesn't know where or
- how to bend them. To illustrate (using the regular Windows shell):
-
- run c:\\windows\\command\\chkdsk.exe
-
- works OK, but:
-
- run c:/windows/command/chkdsk.exe
-
- is not accepted by COMMAND.COM. But:
-
- run c:\windows\command\chkdsk.exe
-
- results in Kermit applying its quoting rules before sending the text to
- the shell. Since "w" and "c" are not in the list of backslash-item
- codes, the backslash means "take the following character literally".
- Thus, by the time this filename gets to the Windows shell, it has
- become:
-
- c:windowscommandchkdsk.exe
-
- which is probably not what you wanted. (If "w" and "c" were in the
- list, the results could be even stranger.) Even more confusing is the
- case where a directory or filename starts with one or more digits:
-
- run c:\123\lotus.exe
-
- in which "\123" is the Kermit notation for ASCII character 123, which
- happens to be left brace ({), resulting in "c:{lotus.exe".
-
- So when passing filenames to a Windows shell, always use double
- backslashes as directory separators, to ensure that the shell gets
- single backslashes:
-
- run c:\\windows\\command\\chkdsk.exe
- run c:\\123\\lotus.exe
-
- Similar problems might occur with the built-in EDIT, BROWSE, and FTP
- commands. These commands result in Kermit building a shell command
- internally to invoke the associated helper program; the form of this
- command might conflict with the form demanded by certain alternative
- shells.
-
-1.11.4. Using Variables to Hold DOS Filenames
-
- Now to the next level. Suppose you want to write a script in which
- filenames are parameters, and therefore are stored in variables.
- Example:
-
- define \%f c:\windows\command\chkdsk.exe
- ...
- run \%f
-
- Obviously this won't work for the reasons just noted; the RUN command
- requires directory separators be coded as double backslashes:
-
- define \%f c:\\windows\\command\\chkdsk.exe
- ...
- run \%f
-
- This will work; no surprises here. However, if you had used ASSIGN
- rather than DEFINE, you might have been surprised after all; review
- pages 348-349 of [367]Using C-Kermit (2nd Ed) for the difference
- between DEFINE and ASSIGN.
-
- We have said that any Kermit 95 or MS-DOS Kermit command that parses
- filenames itself -- SEND, for example -- does not require double
- backslashes since it knows it is parsing a filename. So since the
- following works:
-
- send c:\windows\command\chkdsk.exe
-
- Should the following also work?
-
- define \%f c:\windows\command\chkdsk.exe
- ...
- send \%f
-
- Answer: No. Why? Because \%f is evaluated "recursively", to allow for
- the possibility that its definition contains further variable
- references. This is true of all "backslash-percent-letter" (or -digit)
- variables, and also for array references. So \%f becomes
- c:\windows\command\chkdsk.exe, which becomes
- c:windowscommandchkdsk.exe.
-
- The trick here is to use the "other" kind of variable, that is
- evaluated only "one level deep" rather than recursively:
-
- define filename c:\windows\command\chkdsk.exe
- ...
- send \m(filename)
-
- Similarly if you want to prompt the user for a filename:
-
- ask filename { Please type a filename: }
- Please type a filename: c:\windows\command\chkdsk.exe
- send \m(filename)
-
-1.11.5. Passing DOS Filenames as Parameters to Macros
-
- Suppose you want to pass a DOS filename containing backslashes as a
- parameter to a Kermit macro. This raises two issues:
-
- 1. Parameters to macros are "just text" and so are fully evaluated
- before they are passed to the macro.
- 2. Once inside the macro, the formal parameters \%1, \%2, ... \%9 are
- the type of variable that is evaluated recursively.
-
- Thus a DOS filename is ruined once in the act of parsing the macro
- invocation, and again when referring to it from within the macro. To
- illustrate, suppose "test" is a macro. Then in the invocation:
-
- test c:\mydir\blah.txt
-
- "c:mydirblah.txt" is assigned to \%1. However, if we double the
- backslashes:
-
- test c:\\mydir\\blah.txt
-
- "c:\mydir\blah.txt" is assigned to \%1. But then when you refer to \%1
- in the macro, it is evaluated recursively, resulting in
- "c:mydirblah.txt". To illustrate:
-
- define test echo \%1
- test c:\mydir\blah.txt
- c:mydirblah.txt
- test c:\\mydir\\blah.txt
- c:mydirblah.txt
- test c:\\\\mydir\\\\blah.txt
- c:\mydir\blah.txt
-
- Let's address each part of the problem separately. First, inside the
- macro. You can use the \fcontents() function to force a
- backslash-percent variable (such as a macro argument) to be evaluated
- one level deep instead of recursively, for example:
-
- define test echo { The filename is "\fcontents(\%1)"}
-
- test c:\mydir\blah.txt ; We don't expect this to work
- The filename is "c:mydirblah.txt" ; and it doesn't.
- test c:\\mydir\\blah.txt ; But this does...
- The filename is "c:\mydir\blah.txt"
-
- Thus if the filename arrives inside the macro with single backslashes,
- the backslashes are preserved if you always refer to the parameter
- through the \fcontents() function.
-
- Now how to ensure that backslashes are not stripped or misinterpreted
- when passing a filename to a macro? This brings us back to what we
- learned in earlier sections:
-
- 1. If it is a literal filename, either double the backslashes, or (if
- the filename is to be used only within Kermit itself and not passed
- to a DOS shell, or it is to be passed to an alternative shell that
- accepts forward slash as a directory separator), use forward slash
- instead of backslash as the directory separator.
- 2. If it is a variable that contains a filename, make sure you use a
- macro-style variable name, rather than a
- backslash-percent-character name.
-
- Examples:
-
- define test echo \fcontents(\%1)
- define filename c:\mydir\blah.txt
-
- test c:\\mydir\\blah.txt ; Literal filename with double backslashes
- c:\mydir\blah.txt
-
- test c:/mydir/blah.txt ; Literal filename with forward slashes
- c:/mydir/blah.txt
-
- test \m(filename) ; Variable
- c:\mydir\blah.txt
-
- But what if you don't like these rules and you still want to pass a
- literal filename containing single backslashes to a macro? This is
- possible too, but a bit tricky: turn command quoting off before
- invoking the macro, and then turn it back on inside the macro. Example:
-
- define test set command quoting on, echo \fcontents(\%1)
-
- set command quoting off
- test c:\mydir\blah.txt
- c:\mydir\blah.txt
-
- Upon return from the macro, command quoting is back on (since the macro
- turned it on).
-
- Obviously this trick can not be used if the filename is stored in a
- variable, since it prevents the variable from being evaluated.
-
-1.11.6. Passing DOS File Names from Macro Parameters to the DOS Shell
-
- Now suppose you need to pass a DOS filename to a macro, and the macro
- needs to pass it, in turn, to the Windows shell via (say) Kermit's RUN
- command. This works too:
-
- define xrun run \fcontents(\%1)
- xrun c:\\windows\\command\\chkdsk.exe
-
- (or you can use the SET COMMAND QUOTING OFF / ON technique described
- above to avoid the double backslashes.) But..
-
- xrun c:/windows/command/chkdsk.exe
-
- does not work if the Windows shell does not recognize "/" as a
- directory separator. If there is a chance that a filename might be
- passed to the macro in this form, the macro will need to convert it to
- a form acceptable to the shell:
-
- define xrun run \freplace(\fcontents(\%1),/,\\)
-
- Here we replace all occurrences (if any) of "/" in the argument with
- "\" prior to issuing the RUN command. Of course, in order to specify
- "\" as a literal character in the \freplace() argument list, we have to
- double it.
-
-1.11.7. Passing DOS Filenames to Kermit from the Shell
-
- As noted in the manual, the \&@[] array contains Kermit's command-line
- arguments. Suppose one of these arguments, say \&@[3], is a DOS
- filename such as C:\FOO\BAR\BAZ\OOFA.TXT. (Note: In C-Kermit 7.0 and
- K95 1.1.18 and later, command-line arguments after "=" or "--" are also
- available in the top-level \%1..9 variables; see [368]Section 7.5.)
-
- Of course you can eliminate any problems by using forward slashes
- rather than backslashes in the filename, but sometimes this is not
- possible, as when the Kermit command line is being generated by another
- program than can only generate "native" format DOS filenames.
-
- As noted in the manual, "\%x" variables and \&x[] arrays are always
- evaluated "all the way" (recursively). If the contents of one of these
- variables contains backslashes, this causes another level of
- evaluation.
-
- There is another kind of variable, which is evaluated only "one level
- deep". You can use this to prevent interpretation of the backslashes in
- the filenames. Example:
-
- assign filename \fcontents(\&@[3]) ; Transfer contents
- ...
- send \m(filename)
-
- Or, more simply:
-
- send \fcontents(\&@[3])
-
-1.12. Debugging
-
- The debug log is produced when you give a "log debug" command. This is
- normally done at the request of the Kermit help desk, for forwarding to
- the Kermit developers for analysis as a last resort in troubleshooting
- problems. (Last resort because it can grow quite huge in a very short
- time.) In cases where timing information is critical to understanding a
- problem, you can tell C-Kermit to put a timestamp on each debug log
- line by giving the command:
-
- SET DEBUG TIMESTAMP ON
-
- At any time before or after activating the debug log (SET DEBUG
- TIMESTAMP OFF turns off timestamping). Timestamps can be turned off and
- on as desired while logging. Obviously, they increase the size and
- growth rate of the log significantly, and so should be used sparingly.
- Timestamps are of the form hh:mm:ss.xxx, where .xxx is thousands of a
- second (but is included only on platforms that include this feature).
-
-1.13. Logs
-
- In UNIX C-Kermit and in K-95, you can now direct any log to a pipe.
- This not only lets you send your logs to places other than disk files,
- but also lets you customize them to any desired degree.
-
- LOG { DEBUG, PACKETS, SESSION, TRANSACTION, CONNECTION } { file, pipe }
- ...
- A "pipe" is the name of a command, preceded by a vertical bar.
- If the pipe contains any spaces, it must be enclosed in braces.
-
- Here are some examples for UNIX (always remember the importance of
- getting the UNIX shell quoting rules right):
-
- LOG TRANSACTIONS |lpr
- This sends the transaction log to the default UNIX printer,
- rather than to a file (use "lp" rather than "lpr" if necessary).
-
- LOG TRANSACTIONS {| myfilter > t.log}
- For those who don't like the format of the transaction log, or
- want to extract certain information from it; write your own
- output filter.
-
- LOG SESSION {| lpr -Plaserwriter}
- This sends the session log to a specific UNIX printer, rather
- than to a file. Note the braces around the pipeline. These are
- required because it contains spaces.
-
- LOG DEBUG {| tail -100 > debug.log}
- This causes the debug log file to contain only the final 100
- lines. Suppose C-Kermit crashes under some unpredictable
- circumstances, and you need a debug log to catch it in the act.
- But the debug log can grow to huge proportions very quickly,
- possibly filling up the disk. Piping the debug log through
- "tail" results in keeping only the last 100 lines (or other
- number of your choice).
-
- LOG DEBUG {| grep "^TELNET" > debug.log}
- This one shows how to log only Telnet negotiations. Piping the
- debug log through grep or egrep lets you log only specific
- information, rather than everything. "man grep" for further
- info.
-
- LOG DEBUG {| gzip -c > debug.log.gz}
- Creates a full debug log, but compressed by gzip to save space.
-
- LOG PACKETS {| tr "\\01" "X" | cut -c9- > packet.log}
- This one writes the regular packet log, but translates the
- Ctrl-A that starts each packet to the letter "X" and removes the
- s-nn-nn- notation from the beginning of each line. Note the
- double backslash (normal Kermit quoting rules). "man tr" and
- "man cut" for further info.
-
- See [369]Section 2.12 for information about the new connection log.
-
-1.14. Automatic File-Transfer Packet Recognition at the Command Prompt
-
- Beginning in version 7.0, C-Kermit can recognize Kermit (and in some
- cases also Zmodem) file-transfer packets while at its command prompt.
- This is convenient (for example), if you escaped back from a remote
- Kermit program and told the local Kermit program to send a file, but
- forgot to tell the remote Kermit program to receive it (and the local
- Kermit did not have the "send a Kermit receive command" feature
- available). This feature is controlled by the following command:
-
- SET COMMAND AUTODOWNLOAD { ON, OFF }
- When ON, which is the default, the command parser recognizes
- Kermit packets when Kermit is in remote mode. An S packet makes
- it go into receive mode, an I packet makes it go into server
- mode. When OFF, packet recognition is disabled and the behavior
- when a packet is received at the command prompt is as it was in
- C-Kermit 6.1 and earlier (namely to print an error message).
-
- COMMAND AUTODOWNLOAD is the command-mode equivalent of TERMINAL
- AUTODOWNLOAD, which is effective during CONNECT mode.
-
-1.15. The TYPE Command
-
- The TYPE command now accepts a selection of optional switches
- ([370]Section 1.5), and also sets several variables.
-
- Syntax: TYPE [ switches... ] filename
-
- Variables:
-
- \v(ty_ln)
- Line number of current line (during TYPE command; see /PREFIX)
-
- \v(ty_lc)
- Line count of file most recently TYPEd.
-
- \v(ty_mc)
- Match count of file most recently TYPEd (see /MATCH).
-
- Switches:
-
- /PAGE
- If /PAGE is included, Kermit pauses at the end of each screenful
- and issues a "more?" prompt. You may press the space bar to view
- the next page (screenful), or press "q" or "n" to return to the
- C-Kermit prompt. If this switch is given, it overrides the
- COMMAND MORE-PROMPTING setting for this command only. If it is
- not given, paging is according to COMMAND MORE-PROMPTING.
-
- /NOPAGE
- Do not pause at the end of each screenful; show the whole file
- (or all selected lines) at once. If this switch is given, it
- overrides the COMMAND MORE-PROMPTING setting for this command
- only. If it is not given, paging is according to COMMAND
- MORE-PROMPTING.
-
- /HEAD[:n]
- Only show the first n lines of the file (where n is a number).
- If n is omitted, 10 is used.
-
- /TAIL[:n]
- Only show the last n lines of the file (where n is a number). If
- nis omitted, 10 is used. Note: /HEAD and /TAIL can't be
- combined; if you give both switches, only the most recent one is
- used.
-
- /MATCH:pattern
- Only type lines from the file that match the given pattern (see
- [371]Section 4.9.1 for pattern notation). UNIX users familiar
- with grep should note a significant difference: there is no
- implied "*" at the beginning and end of the pattern. Thus:
-
- TYPE /MATCH:foo Lists lines whose entire contents are "foo".
- TYPE /MATCH:foo* Lists lines that start with "foo".
- TYPE /MATCH:*foo Lists lines that end with "foo".
- TYPE /MATCH:*foo* Lists lines that have "foo" anywhere in them.
-
- /HEAD and /TAIL apply after /MATCH, so "type /tail:20 /match:x*"
- shows the last 20 lines in the file that start with "x".
-
- /PREFIX:string
- Print the given string at the beginning of each line. The string
- may be a constant, a variable, or a quoted variable. If it's an
- unquoted variable, its value at the time the TYPE command was
- given is used as a constant. If it is a quoted variable, it is
- re-evaluated for each line; a useful variable for this context
- is \v(ty_ln) (the line number of the current line being typed).
- If the prefix is to include spaces, it must be enclosed in
- braces. Examples:
-
- type /prefix:{oofa.txt: } /match:*thing* oofa.txt
- Prints all lines in oofa.txt that contain "thing" with the
- filename itself as the prefix (similar to UNIX grep).
-
- type /prefix:{\v(time). } oofa.txt
- Prefixes each line of oofa.txt with the time at which the
- TYPE command was given (one backslash)
-
- type /prefix:{\\v(time). } oofa.txt
- Prefixes each line of oofa.txt with the time at which that
- line is being typed (two backslashes).
-
- type /prefix:{\\v(ty_ln). } oofa.txt
- Prefixes each line of oofa.txt with its line number.
-
- type /prefix:{\\flpad(\\v(ty_ln),4). } oofa.txt
- Same as the previous example, except the line number is
- right-adjusted in a 4-column field.
-
- /WIDTH[:n]
- Truncates each line at column n (which must be a number) prior
- to printing it. This option can be used for long lines when you
- don't want them to wrap. If nis omitted, your current screen
- width is used.
-
- /COUNT
- Counts lines and -- if /MATCH was included, matches -- but does
- not print any lines from the file. The line and match count is
- shown at the end, and the variables \v(ty_lc) and \v(ty_lm) are
- set accordingly.
-
- SET OPTIONS TYPE { /PAGE, /NOPAGE, /WIDTH:n }
- Sets the paging default for TYPE commands, which can be
- overridden in any particular TYPE command by including the
- desired switch.
-
- If a TYPE command is given with no switch, and no SET OPTIONS TYPE
- selection is in effect, paging is according to your COMMAND
- MORE-PROMPTING setting (SHOW COMMAND).
-
-1.16. The RESET Command
-
- The RESET command, added in 7.0, closes all open files and logs, but
- does not affect the open connection (if any).
-
-1.17. The COPY and RENAME Commands
-
- As of C-Kermit 7.0, in the UNIX version only, the COPY and RENAME
- commands are built in and do not call the underlying platform's COPY or
- RENAME command. This allows them to work in "NOPUSH" versions and other
- circumstances where it can't access system commands, and it allows file
- copying and renaming to be done portably in scripts. The
- characteristics of the built-in COPY or RENAME include:
- * It fails if the source file is a directory or is wild or lacks read
- access.
- * It fails if the source file is the destination file.
- * It allows the destination file to be a directory, in which case the
- source file is copied (or renamed) into it with the same name.
- * It overwrites an existing destination file if its permission
- allows.
- * It sets the new file's permission according to umask but also
- carries forward the source file's execute permission bits if the
- destination file did not already exist.
- * It fails if interrupted by Ctrl-C.
- * Upon error, it prints an appropriate message.
- * It returns standardized error codes that can be tested by IF
- SUCCESS / FAIL.
-
- These commands now also accept the following switches:
-
- /LIST (/LOG, /VERBOSE) = Print "file1 => file2 (OK)" (or error message).
- /NOLIST (/NOLOG, /QUIET) = Don't print anything (except error messages).
-
- /NOLIST is the default.
-
- The same built-in code is used by the UNIX C-Kermit server to execute
- REMOTE COPY commands (except in this case no switches are available).
-
- The COPY command also accepts the following additional switches. When
- any of these are given (and they can be used in any combination except
- /SWAP and /APPEND), some of the checks listed above are relaxed, and
- thus it might be possible to get into trouble in certain cases, e.g.
- when the source and target files are the same file:
-
- /APPEND = Append source file to destination file.
- /SWAP-BYTES = Swap bytes (see [372]Section 6.6.5).
- /FROMB64 = Decode the source file from Base64 encoding.
- /TOB64 = Encode the target file in Base64.
-
- Base64 is the encoding commonly used for enclosures in Internet email.
-
-1.18. The MANUAL Command
-
- The MANUAL command can be used to access the appropriate Kermit manual
- or other manual. The general syntax is:
-
- MANUAL [ string ]
- If the string is omitted, C-Kermit asks the underlying system to
- access the C-Kermit manual using whatever method is appropriate
- for the system.
-
- The specific action depends on the system. In UNIX, a "man" command is
- issued; "kermit" is the default argument but other manual topics may be
- specified. If the "man" command allows index or string searching, the
- appropriate syntax may be included.
-
- In Kermit 95, the MANUAL command brings up the HTML online K95 manual.
-
- In VMS and elsewhere, "man" is simply translated to "help", with a
- default argument of "kermit"; other and/or additional arguments may be
- included according to the definition of the system's "help" command.
-
- Correct operation of the "man" command in C-Kermit depends on the
- appropriate man page or help topic having been installed in the right
- place with the right permissions and format.
-
-1.19. String and Filename Matching Patterns
-
- A pattern is a string that includes special notation for matching
- classes or sequences of characters. C-Kermit 7.0 / K95 1.1.19 supports
- patterns in several places:
-
- * Filenames ([373]Section 4.9)
- * SWITCH case labels ([374]Section 7.18)
- * The new IF MATCH statement ([375]Section 7.4)
- * TYPE /MATCH ([376]Section 1.15)
- * SET FILE TEXT-PATTERNS and BINARY-PATTERNS ([377]Section 4.3)
- * The \fsearch() and \farraylook() functions ([378]Sections 7.3 and
- [379]7.10.7)
- * The \fpattern() function used with [M,RE]INPUT ([380]Section 7.1)
-
- Patterns are also called wildcards, especially when used for filename
- matching. C-Kermit's pattern syntax is explained in [381]Section 4.9.1,
- and also by the HELP WILDCARDS command.
-
-1.20. Multiple Commands on One Line
-
- As of C-Kermit 7.0, commands can be grouped together on one line by
- separating the commands with commas and enclosing the list in braces.
- For example:
-
- C-Kermit> { echo One, echo Two, echo Three }
- C-Kermit> do { echo One, echo Two, echo Three }
-
- Command lists can be nested:
-
- [ do ] { echo One, echo Two, if true { echo A, echo B}, echo Three }
-
- and the END command works as it does in macros:
-
- [ do ] { echo One, echo Two, if true end, echo Three }
-
- The "one line" stricture is, of course, pliant to line-continuation
- conventions, namely that lines ending in hyphen (-) or left brace ({)
- are to be continued. Thus the first example can also be rendered:
-
- [ do ] {
- echo One
- echo Two
- echo Three
- }
-
- (the "do" is optional).
-
-1.21. What Do I Have?
-
- C-Kermit can be built for hundreds of different platforms with
- practically countless configuration options. Certain commands might not
- be available in certain configurations, etc. Even on the same platform,
- different builds are possible: "maximum functionality", "minimum size",
- "maximum performance", and so on. You can find out a lot about the
- configuration of your C-Kermit program with the SHOW FEATURES command.
- Of course, a lot of what it says, especially in the bottom part, might
- seem like gibberish, but can be deciphered with a Rosetta Stone (such
- as the C-Kermit source or the [382]ckccfg.txt file). In any case, the
- output from SHOW FEATURES might easily explain why some expected
- feature is missing, or some buffer is smaller than expected. Here's a
- sample of the bottom section for the SunOS version:
-
-C-Kermit 7.0.196, 1 Jan 2000
-
-Major optional features included:
- Network support (type SHOW NET for further info)
- Telnet Kermit Option
- Hardware flow control
- External XYZMODEM protocol support
- Latin-1 (West European) character-set translation
- Latin-2 (East European) character-set translation
- Cyrillic (Russian, Ukrainian, etc) character-set translation
- Greek character-set translation
- Hebrew character-set translation
- Japanese character-set translation
- Unicode character-set translation
- Pseudoterminal control
- REDIRECT command
- RESEND command
- Fullscreen file transfer display
- Control-character unprefixing
- Streaming
- Autodownload
-
-Major optional features not included:
- No Kerberos(TM) authentication
- No SRP(TM) (Secure Remote Password) protocol
- No Secure Sockets Layer (SSL) protocol
- No Transport Layer Security (TLS) protocol
- No encryption
- No X Windows forwarding
-
-Host info:
- Machine: sun4m
- Model: (unknown)
- OS: SunOS
- OS Release: 4.1.3_U1
- OS Version: 4
-
-Target: sunos41gsc
-GCC version: 2.7.2
-Compiled Dec 31 1999 10:38:54, options:
- __GNUC__ __STDC__ _POSIX_JOB_CONTROL _SC_JOB_CONTROL ARRAYREFLEN=1024 BIGBUFOK
- BROWSER BSD4 CK_ANSIC CK_APC CK_AUTODL CK_CURSES CK_DNS_SRV CK_ENVIRONMENT
- CK_FAST CK_LOGIN CK_MKDIR CK_NAWS CK_PCT_BAR CK_PERMS CK_RECALL CK_RTSCTS
- CK_SPEED CK_TIMERS CK_TMPDIR CK_TTGWSIZ CK_TTYFD CK_WREFRESH CKEXEC
- CKFLOAT=double CKGHNLHOST ckmaxfiles=64 CKMAXOPEN=64 CKMAXPATH=1023 CKREALPATH
- CKREGEX CKSYSLOG CKTUNING CMDBL=32763 CMDDEP=64 CONGSPD DCMDBUF DIRENT DYNAMIC
- FNFLOAT FORDEPTH=32 GFTIMER HADDRLIST HDBUUCP IFDEBUG IKS_OPTION IKSDB
- IKSDCONF INBUFSIZE=32768 INPBUFSIZ=4096 MAC_MAX=16384 MACLEVEL=128 MAXDDIR=32
- MAXDNUMS=4095 MAXGETPATH=128 MAXTAKE=54 MAXWLD=102400 MSENDMAX=1024 NETCMD
- NETCONN NETPTY NOKVERBS NOSETBUF OBUFSIZE=32768 PARSENSE PATTERNS PIPESEND
- RENAME RLOGCODE SAVEDUID SELECT SIG_V SOL_SOCKET sparc STREAMING sun SUNOS4
- SYSTIMEH TCPSOCKET TIMEH TLOG TNCODE TTLEBUF TTSPDLIST UIDBUFLEN=256 UNIX
- UNPREFIXZERO USE_LSTAT USE_MEMCPY VNAML=4096 WHATAMI XFRCAN Z_MAXCHAN=46
- z_maxchan=46 ZXREWIND
-
- byte order: big endian
-
- sizeofs: int=4 long=4 short=2 char=1 char*=4 float=4 double=8
-
- floating-point: precision=16 rounding=1
-
- Without going into detail about what all the notation means, notice a
- couple things:
-
- * The Options section shows symbols ("macros") in effect during
- compilation, together with their values (for those that have
- values). The options are listed in alphabetical order to make any
- particular option easier to find.
- * MAXWLD is the maximum number of files that a wildcard can expand
- to.
- * Anything starting with "NO" is a feature (or something other than a
- feature) that has been deliberately "compiled out", or omitted.
- * Important items for script writers include: CMDBL=32763 (the size
- of the command buffer and therefore the maximum length for a macro
- or variable definition; CMDDEP=64 (the limit on recursion depth);
- FORDEPTH=32 (the nesting limit on FOR loops); INBUFSIZE=32768 (the
- size of the INPUT command circular buffer); MAC_MAX=16384 (the
- maximum number of macros), etc.
-
- See the [383]ckccfg.txt file for details.
-
-1.22. Generalized File Input and Output
-
- C-Kermit 7.0 adds a new generalized I/O system for stream files,
- augmenting (and to some extent, overlapping with) the older OPEN, READ,
- WRITE, and CLOSE commands. In the new file i/o system, which can be
- used simultaneously with the old one, all commands are grouped together
- under the new FILE keyword, and some related functions and variables
- are added.
-
-1.22.1. Why Another I/O System?
-
- The well-known LOG, OPEN, READ, WRITE, and CLOSE commands have the
- following restrictions:
-
- 1. Only one READ file and one WRITE file can be open at a time.
- 2. The READ and WRITE commands are strictly line oriented.
- 3. These commands can not be used with binary files.
- 4. They do not support read/write access or random access.
- 5. The syntax is a bit counterintuitive for programmers.
-
- The new file i/o system allows multiple files to be open at once, in
- any desired combination of modes (read/write/append) supported by the
- operating system, for line, block (record), or character i/o, for
- sequential or random access, using consistent syntax and conventions.
-
- The new system, however, does not replace the old one, since the old
- system still must be used for:
-
- 1. The session, packet, debug, transaction, and connection logs.
- 2. Reading and writing commands rather than files.
- 3. Existing scripts.
-
- The new system works only with regular files, not with commands or
- pipes or mailboxes or pseudoterminals. No special provisions are made
- in the FILE commands for handling devices or network connections, nor
- for preventing you from trying to open them; if the underlying
- operating system treats them like regular stream disk files, the FILE
- commands (except, of course SEEK, REWIND, and COUNT) might work with
- them. (In C programming terms, the FILE commands are, at present,
- nothing more than a front end to fopen() / fread() / fwrite() /
- fclose() and friends, which are a portable API to sequential files, but
- this might change in the future for platforms like VMS and VOS that
- have more complicated file systems.)
-
- Definitions:
-
- Channel
- A number assigned to a file when it is opened, by which it must
- be referred to in all input/output operations.
-
- Read/Write Pointer
- The current position in an open file, expressed as the 0-based
- byte count from the beginning.
-
-1.22.2. The FILE Command
-
- FILE keyword [ switches ] channel [ data ]
- The keyword specifies the function: FILE OPEN, FILE READ, FILE
- WRITE, FILE CLOSE, etc. For convenience (and for familiarity to
- C programmers), the two-word FILE commands can be shortened to
- the single words FOPEN, FREAD, FWRITE, FCLOSE, and so on.
- Switches are optional, and modify or amplify the requested file
- function.
-
- As in C, Fortran, and other programming languages, open files are
- referred to by "channels", integers such as 0, 1, 2, 3, and so on. A
- channel number is assigned when you open a file. The number of
- available channels depends on the underlying operating system, and can
- be seen in the variable:
-
- \v(f_max)
-
- or by giving the FILE LIST (FLIST) command. Channels are discussed in
- greater detail in [384]Section 1.22.4.
-
- FILE command errors can be caught with IF FAIL after the FILE command.
- In addition, the \v(f_error) variable is set to the completion code of
- the command: 0 if no error, or a negative number if there was an error.
- The error codes are listed in [385]Section 1.22.5.
-
- The command to open a file is:
-
- FILE OPEN [ switches ] variable filename
- Opens a file for the type of access specified by the switches,
- or for read-only access if no switches are given. Upon success,
- a channel number is assigned to this file and stored in the
- given variable so you can refer to the open file in subsequent
- i/o commands. If the file can not be opened, the FILE OPEN
- command fails. Synonym: FOPEN.
-
- The FILE OPEN switches are:
-
- /READ
- Open the file for read access. If no switches are given, /READ
- is assumed. If the file does not exist or can't be opened for
- read access, the FILE OPEN command fails.
-
- /WRITE
- Allow writing. If a file of the same name already exists, it is
- overwritten unless /READ or /APPEND is also included. If a file
- of the given name does not exist, it is created.
-
- /APPEND
- Equivalent to /WRITE, except that if the file exists, it is not
- destroyed. The read/write pointer is set to the end of the file,
- so unless you change it with FILE SEEK or REWIND (see below),
- the first FILE WRITE command adds to the end of the file,
- preserving what was there already. If /WRITE is also given, it
- is ignored.
-
- /BINARY
- Open the file in "binary" mode, rather than text mode. This
- switch is meaningless (but still can be used) in UNIX. In VMS,
- Windows, and OS/2, it inhibits end-of-line processing and
- conversion, and so should be used for binary files and/or files
- that are to be accessed in record or character mode rather than
- line by line.
-
- The variable for the channel number can be any kind of variable: the
- \%x kind, a macro name, or an array element. But it must be a variable,
- not a number -- C-Kermit assigns the channel number; you can't tell it
- what number to use.
-
- Example:
-
- FILE OPEN \%c oofa.txt ; Open oofa.txt for reading.
- IF FAIL exit 1 Can't open oofa.txt ; Always check to see if it worked.
- ECHO oofa.txt: channel = \%c
-
- If the file oofa.txt is opened successfully, a channel number is
- assigned to the variable \%c. Here's another example using a macro name
- for the channel number:
-
- FILE OPEN channel oofa.txt ; Open oofa.txt for reading.
- IF SUCCESS ECHO oofa.txt: channel = \m(channel)
-
- Switches can be combined when it makes sense and the underlying
- operating system allows it. For example, to open a file in binary mode
- for reading and writing (sometimes called "update"):
-
- FILE OPEN /READ /WRITE /BINARY \%c budget.db
-
- Some combinations might be allowed, others not. For example /READ
- /APPEND will usually not be allowed. /WRITE /APPEND is treated as
- /APPEND.
-
- A major advantage of the new system over the older one is that you can
- have multiple files open at once. Suppose, for example, that you want
- to open all the files in a certain directory at once:
-
- .\%n := \ffiles(/usr/olga*,&f) ; Get file list into array.
- if ( > \%n \v(f_max) ) { ; Make sure there aren't too many.
- exit 1 {\v(dir): \%n = Too many files}
- }
- declare \&c[\%n] ; Make array for channel numbers.
- for \%i 1 \%n 1 { ; Loop to open every file...
- file open \&c[\%i] \&f[\%i] ; Try to open this one
- if fail exit 1 Open error: \&f[\%i] ; Check for failure
- }
-
- If this loop completes successfully, the \&c[] array will contain \%n
- channel numbers of open files in elements 1 through \%n.
-
- Any file that you open with FILE OPEN stays open until Kermit exits, or
- you close it explicitly. The command to close a file is:
-
- FILE CLOSE { ALL, channel }
- If a channel number is given and the channel refers to an open
- file, the file is closed and the channel is freed for reuse; if
- the channel does not refer to an open file, an error message is
- printed and the command fails. If ALL is specified instead of a
- specific channel, all files opened with FILE OPEN are closed and
- if all open files were closed successfully (even if no files
- were open), the command succeeds; if any open file could not be
- closed, the command fails; however, all open files that could be
- closed are still closed. Synonym: FCLOSE.
-
- FILE CLOSE might fail because, for example, the disk filled up or a
- quota was exceeded. Example:
-
- fopen /write \%c new.txt ; Open new.txt for writing.
- if fail exit 1 ; Check for error.
- fclose \%c ; Close the file we just opened.
-
- This creates a 0-length file called new.txt.
-
- Note that FILE OPEN /WRITE (without /READ or /APPEND) always creates a
- new file, and therefore destroys any file with the same name that might
- already exist (assuming you have permission to delete it). To avoid
- overwriting existing files, simply check first:
-
- if exist new.txt exit 1 {Fatal - new.txt already exists}
- fopen /write \%c new.txt
- if fail ...
-
- The next two commands give information about open files:
-
- FILE STATUS channel
- Tells the name of the file, if any, open on the given channel
- and the switches it was opened with. The read/write pointer is
- also shown; this is where the next read or write will occur;
- "[EOF]" is shown if the current position in the open file is the
- end -- i.e. the next read will fail if the file was opened in
- /READ mode; the next write will add material to the end. The
- current line number (0-based) is also shown if known. The FILE
- STATUS command succeeds if the channel is open, and fails if
- there is no open file on the given channel, or if the channel
- number is invalid or out of range. Synonym: FSTATUS.
-
- FILE LIST
- Lists the channel number and name of each open file, along with
- its OPEN modes (R, W, A, B, RW, etc) and its current read/write
- pointer or "[EOF]" if it is at the end. Also tells the number of
- files currently opened with FILE OPEN, plus the maximum number
- of open files allowed by the system and the maximum number
- allowed for FILE OPEN. Synonym: FLIST.
-
- Next come the commands for reading and writing files:
-
- FILE READ [ switches ] channel [ variable ]
- Reads data from the file on the given channel number into the
- variable, if one was given; if no variable was given, the result
- is printed on the screen. IMPORTANT: The variable should
- normally be a macro name rather than a \%x or \&x[] variable if
- you want backslash characters in the file to be taken literally
- (see pp.408-412 of [386]Using C-Kermit for an explanation; you
- can also read into a \%x or \&x[] variable, but then you must
- remember to protect future references to by \fcontents() if you
- don't want C-Kermit to process any backslashes it might
- contain). The desired amount of data (according to the switches)
- is read from the file at the current read/write pointer, and
- upon completion the read/write position is updated to first byte
- after the data that was read, no matter what switches were
- given. Synonym: FREAD.
-
- FILE WRITE [ switches ] channel text
- Writes the given text to the file on the given channel number.
- The text, of course, can be literal text or a variable, or any
- combination. If the text might contain leading or trailing
- spaces, it must be enclosed in braces if you want to preserve
- them. Synonym: FWRITE.
-
- Before proceeding, a caution about the NUL character. C-Kermit is so
- named because it is a Kermit program written in the C language. In C,
- character strings are represented as a sequence of non-NUL bytes
- terminated by a NUL byte (a byte in which all bits are 0). Thus a C
- string can not contain NUL bytes; it always ends with the first NUL
- byte. C-Kermit variables are implemented as C strings and therefore
- can't contain NUL bytes either, so the FILE READ and FILE WRITE
- commands do not handle files or strings that contain NUL bytes, except
- when the /CHARACTER switch is included with the FILE READ or WRITE
- command, or when /LPAD:0 or /RPAD:0 is given with the FILE WRITE
- command; these switches are explained below.
-
- Also note that Kermit can not be used read or write binary numbers in
- the machine's internal format (integer or floating-point); in general,
- numbers can be processed only when represented as numeric or
- floating-point strings.
-
- FILE READ switches are:
-
- /LINE
- Specifies that a line of text is to be read. A line is defined
- according to the underlying operating system's text-file format.
- For example, in UNIX a line is a sequence of characters up to
- and including a linefeed, or the end of the file, which ever
- comes first. The line terminator (if any) is removed before
- assigning the text to the variable. If no switches are included
- with the FILE READ command, /LINE is assumed. Normally this
- switch should not be used with files opened in /BINARY mode (but
- nothing prevents it either).
-
- /SIZE:number
- Specifies that the given number of bytes (characters) is to be
- read. The actual number of bytes returned will be less if the
- end of file is reached (or a NUL byte is encountered). For
- example, if a file is 514 bytes long, FILE READ /SIZE:512
- returns 512 bytes the first time and 2 bytes the second time.
- FILE READ /SIZE provides a kind of "record i/o" for files that
- do not necessarily contain lines. The resulting block of
- characters is assigned to the variable without any editing.
- Synonym: /BLOCK.
-
- /CHARACTER
- Equivalent to /SIZE:1. If FILE READ /CHAR succeeds but the
- variable is empty, this indicates a NUL byte was read. Synonym:
- BYTE.
-
- FILE WRITE switches are:
-
- /LINE
- Specifies that an appropriate line terminator is to be added to
- the end of the text. If no switches are included, /LINE is
- assumed.
-
- /SIZE:number
- Specifies that the given number of bytes (characters) is to be
- written. If the given text is longer than the requested size, it
- is truncated; if is shorter, it is padded according /LPAD and
- /RPAD switches. Synonym: /BLOCK.
-
- /LPAD[:value]
- If /SIZE was given, but the text is shorter than the requested
- size, the text is padded on the left with sufficient copies of
- the character whose ASCII value is given to write the given
- length. If no value is specified, 32 (the code for Space) is
- used. The value can also be 0 to write the indicated number of
- NUL bytes. If /SIZE was not given, this switch is ignored.
-
- /RPAD[:value]
- Like LPAD, but pads on the right.
-
- /CHARACTER
- Specifies that one character should be written. If the text is
- empty or not given, a NUL character is written; otherwise the
- first character of text is given. Synonym: /BYTE.
-
- /STRING
- Specifies that the text is to be written as-is, with no
- terminator added.
-
- Here's an example in which we copy a text file line by line:
-
- file open /read \%c oofa.txt ; Open input file
- if fail exit 1 Can't open input file ; Check that it's open
- file open /write \%d new.txt ; Open output file
- if fail exit 1 Can't open output file ; Check
- while true { ; Loop to copy lines
- file read /line \%c line ; Read a line
- if fail break ; Assume failure = end of file
- file write /line \%d {\m(line)} ; Write the line to output file
- if fail exit 1 Write failure ; Failure here is fatal
- }
- file close \%c ; Close the two files
- file close \%d
-
- Note that since /LINE is the default for both FILE READ and FILE WRITE,
- it can be omitted as in the following example, where we also use the
- short names for the FILE commands.
-
- fopen /read \%c oofa.txt ; Open input file
- if fail exit 1 Can't open input file ; Check that it's open
- fopen /write \%d new.txt ; Open output file
- if fail exit 1 Can't open output file ; Check
- while true { ; Loop to copy lines
- fread \%c line ; Read a line
- if fail break ; Assume failure = end of file
- fwrite \%d {\m(line)} ; Write the line to output file
- if fail exit 1 Write failure ; Failure here is fatal
- }
- fclose \%c ; Close the two files
- fclose \%d
-
- Here's the same example using "record i/o" (the open and close
- sequences are are omitted since they are the same as above). The result
- is the same, but execution is much faster:
-
- while true { ; Loop to copy blocks
- fread /size:512 \%c block ; Read a block into \%a
- if fail break ; Assume failure = end of file
- fwrite /string \%d {\m(block)} ; Write the block to output file
- if fail exit 1 Write failure ; Failure here is fatal
- }
-
- Although record i/o is faster, it should not be used in line-oriented
- applications, since it returns arbitrary chunks of the file to your
- script, rather than lines. In this example, FWRITE /STRING is used
- rather than FWRITE /SIZE:512 to avoid the last output block being
- padded beyond the original file's length.
-
- A file can also be copied character by character, but this is much
- slower than line i/o and VERY much slower than block i/o:
-
- while true { ; Loop to copy blocks
- fread /char \%c c ; Read a character into c
- if fail break ; Assume failure = end of file
- fwrite /char \%d {\m(c)} ; Write character to output file
- if fail exit 1 Write failure ; Failure is fatal
- }
-
- Although character i/o is slow, it is the only way to process files
- that contain NUL characters (i.e. bytes composed of only zero bits). In
- the example above, when "fread /char \%c c" returns a NUL, the c
- variable is empty. But since the FREAD /CHAR command did not fail, we
- know the result was really a NUL. FWRITE /CHAR, when given an empty
- variable (or no variable at all) writes a NUL. Thus the loop above will
- copy any file at all (very slowly). In non-copying applications, NULs
- are detected like this:
-
- fread /char \%c c
- if fail (do something)
- if not def c (a NUL byte was read)
-
- Finally some advanced file operations:
-
- FILE FLUSH channel
- For output files only: commits all previous writes to disk, in
- case the computer was buffering them. Synonym: FFLUSH.
-
- FILE COUNT [ { /BYTES, /LINES, /LIST, /NOLIST } ] channel
- By default, or if the /BYTES switch is given, counts the bytes
- in the file, if any, open on the given channel. If the /LINES
- switch is given, counts lines in the file. If the /LIST switch
- is given, the result is printed. If the /NOLIST switch is given,
- the result is not printed. /QUIET is a synonym for /NOLIST. If
- neither /LIST nor /NOLIST is given, the result is printed if the
- command is given at top level, i.e. not from a command file or
- macro. In all cases, the result of the most recent FILE COUNT
- command is stored in the variable \v(f_count). Note that FILE
- COUNT /LINE works (and can only work) by reading the entire
- file; expect it to take some time if the file is large. Synonym:
- FCOUNT.
-
- FILE REWIND channel
- Moves the read/write pointer to the beginning of the file.
- Equivalent to FILE SEEK channel 0. Synonym: FREWIND.
-
- FILE SEEK [ switches ] channel { [{+,-}]number, LAST, EOF }
- Moves the read/write pointer for the file on this channel to the
- given position, which may be a byte (character) number or a line
- number, expressed in either absolute or relative terms.
- Switches:
-
- /BYTE
- The number given is a byte number. Synonym: /CHARACTER.
-
- /LINE
- The number given is a line number.
-
- /ABSOLUTE
- The number given is absolute.
-
- /RELATIVE
- The number given is relative to the current position.
-
- By default, or if the /BYTE switch is given, the number is a
- byte number (0 = first byte). If /LINE is given, the number is a
- line number (0 = first line). EOF means to move to the end of
- the file. LAST means to move to the last line or character of
- the file, depending on whether it's a line or character seek.
-
- If neither the /RELATIVE nor the /ABSOLUTE switch is given, then
- if a signed number is given, the motion is relative to the
- current position. An expression that evaluates to a negative
- number is not considered signed for this purpose; that is, a
- sign (+ or -) must be included as the first character of the
- number in the command itself to force a relative seek (in the
- absence of /RELATIVE or /ABSOLUTE).
-
- If the number has no sign, or if the /ABSOLUTE switch is given,
- the number represents an absolute position (relative to the
- beginning of the file). Subsequent FILE READs or WRITEs will
- take place at the new position.
-
- If the read/write pointer is placed after the end of the file, a
- subsequent FILE READ will fail, but a FILE WRITE will succeed
- (possibly creating a file with "holes"). If a FILE SEEK /BYTE
- command is given, the current line becomes unknown (unless the
- position is 0) and subsequent FILE SEEK /RELATIVE /LINE commands
- will fail until the next non-relative FILE SEEK /LINE command is
- given. Synonym: FSEEK.
-
- An absolute FILE SEEK to a negative position fails silently, as does a
- relative seek to a position before the beginning of the file.
-
- A caution about relative SEEKs: remember that the number is relative to
- the current position. Whenever you read or write, this changes the
- position. In each of the following examples, assume the file open on
- channel \%c is positioned at line n (the FREAD target variable is
- omitted for lack of space):
-
- { FREAD \%c, FSEEK /LINE \%c -1, FREAD \%c } <-- Reads line n twice
- { FREAD \%c, FSEEK /LINE \%c +0, FREAD \%c } <-- Reads lines n and n+1
- { FREAD \%c, FSEEK /LINE \%c +1, FREAD \%c } <-- Reads lines n and n+2
- { FREAD \%c, FSEEK /LINE \%c -2, FREAD \%c } <-- Reads lines n and n-1
- { FREAD \%c, FSEEK /LINE \%c -3, FREAD \%c } <-- Reads lines n and n-2
-
- Another caution: Using FSEEK and FREAD /SIZE to repeatedly read the
- same disk block (e.g. when sampling a database record that is
- frequently updated) might not give you updated disk blocks due to the
- internal buffering and caching of the C library (this probably varies
- from one platform/compiler combination to another). If necessary you
- can force a fresh disk read with a close/open sequence:
-
- FCLOS \%c
- FOPEN \%c samefilename
- FSEEK \%c samespot
- FREAD /SIZE:howmanybytes \%c variable
-
-1.22.3. FILE Command Examples
-
- To read the last 10 lines of a text file into an array:
-
- fopen /read \%c oofa.txt ; Open the file
- if fail exit 1 Can't open oofa.txt ; Always check for failure
- dcl \&a[10] ; Declare a 10-element array
- fcount /line \%c ; Count lines in the file
- fseek /line \%c \v(f_count)-10 ; Seek to 10 lines from the end
- if fail exit 1 Can't seek ; Check for failure
- for \%i 1 10 1 { fread \%c \&a[\%i] } ; Read the last 10 lines
- fclose \%c ; Close the file
-
- Note that blank lines show up as empty (undefined) array elements, for
- example if you give a "show array a" command at this point. This is
- normal. You can still use these elements; e.g.:
-
- for \%i 1 10 1 { echo \%i. \&a[\%i] } ; Display the 10 lines
-
- Here is how to read the last line of a file (already open on channel
- \%c):
-
- fseek /line \%c last ; Seek directly to last line
-
- Alternatively:
-
- fseek /line \%c eof ; Seek to end of file
- fseek /line \%c -1 ; Seek to beginning of last line
-
- Alternatively:
-
- fcount /line \%c ; Count the file's lines
- fseek /line \%c \v(f_count)-1 ; Seek to last line
- fread \%c ; Read it
-
- To read every other line from the file (using relative SEEK), skipping
- the first line:
-
- fopen /read \%c oofa.txt ; Open the file
- while ( success ) { ; Loop through lines
- fseek /line \%c +1 ; Skip a line
- if success fread \%c ; Read & display a line
- }
- fclose \%c ; Close the file
-
- Here is how to read the lines of a file in reverse order:
-
- fopen /read \%c oofa.txt ; Open
- if fail exit 1 ; Check
- fseek /line \%c last ; Seek to last line
- while success { ; Loop
- fread \%c ; Read line
- fseek /line \%c -2 ; Seek backwards two lines
- }
- fclose \%c ; Close the file
-
- The loop works because a relative SEEK outside the file fails.
-
- It is also possible to use block i/o to manage random-access files with
- fixed-length records (as long as they don't contain NUL characters).
- Suppose, for example, you have a file of "card image" records with
- fixed-field information about customers, such as:
-
- Name: Columns 1-32 (column numbers are 1-based)
- Address: Columns 33-72
- Balance: Columns 73-80
-
- The records are indexed by customer number, starting with 0. There are
- no line terminators separating them. Therefore the record for customer
- number n starts at position nx 80 (\%n*80).
-
- Now suppose we received a payment from customer number 173 and want to
- update the balance:
-
- .\%n = 173 ; Customer (record) number
- .\%a = 12.72 ; Amount
- fopen /read /write \%c customer.db ; Open the file
- if fail stop 1 OPEN FAILED: \f_errmsg() ; Check
- fseek /byte \%c 80*\%n ; Seek to record
- fread /size:80 \%c r ; Read the record
- if fail stop 1 READ FAILED: \f_errmsg() ; Check (IMPORTANT)
- .\%b := \fright(\m(r),8) ; Extract the balance
- .\%b := \ffpadd(\%b,\%a,2) ; Add the new payment
- if fail stop 1 ARITHMETIC ERROR: \%b/\%a ; Catch bad records
- .r := {\fleft(\m(r),72)\flpad(\%b,8)} ; Update the record
- fseek /byte \%c 80*\%n ; Reposition to same spot
- fwrite /size:80 \%c {\m(r)} ; Replace the record
- if fail stop 1 WRITE FAILED: \f_errmsg() ; Check
- fclose \%c ; Close the file
-
- REMEMBER: Using FILE SEEK to move beyond the end of file can result in
- a file with holes when writing; when reading, an end-of-file error will
- occur -- be sure to check for it.
-
-1.22.4. Channel Numbers
-
- C-Kermit's channel numbers are integers from 0 to some
- platform-dependent limit, such as 46 or 1985 (the value of \v(f_max)).
- This is the limit placed by the operating system on the number of files
- that may be opened by one process or user or job, minus the standard
- input, output, and error files, and minus the number of files reserved
- by C-Kermit for logs, OPEN READ and WRITE, and file transfer (and maybe
- some command files -- the \v(f_max) number can't be exact).
-
- Although you must include a variable in the FILE OPEN command, to which
- the channel number is assigned, you don't have to use a variable in the
- other FILE commands if you know what the number is -- you can just put
- the number. This saves you a few keystrokes when typing commands at the
- prompt:
-
- fopen \%c oofa.txt
- flist
- 0. /usr/olga.oofa.txt (R) 0
-
- This tells the channel number is 0 (the number on the left is the
- channel file's channel number). Of course you can also find it by
- echoing the variable:
-
- echo \%c
- 0
-
- Or with "fstatus \%c". Now you can type commands like:
-
- fread 0
-
- to read a line from the file. Obviously, however, using digits rather
- than a variable for the channel number would be poor practice in a
- script.
-
- If in commands like:
-
- fread \%c \%a
-
- you have trouble remembering which variable is which, note that the
- channel number is, indeed, a number. Anywhere C-Kermit accepts a number
- it can also accept an expression, so you can put parentheses around the
- channel number to remind you it's the channel number and not the
- variable into which data is to be read:
-
- fread (\%c) \%a
-
- Normally channel numbers are assigned sequentially as 0, 1, 2, ... up
- to the limit. However, once you start closing files, there can be holes
- in the sequence. New channels are assigned to fill in the holes. Thus
- you can't depend on channel numbers being in any particular sequence.
-
-1.22.5. FILE Command Errors
-
- Each FILE command sets the variable \v(f_error) to one of the following
- values:
-
- 0 = No error
- -1 = System error
- -2 = Attempt to read after end of file
- -3 = Channel not open
- -4 = Channel number out of range (negative or too large)
- -5 = Numeric argument (size, ...) out of range
- -6 = File not found
- -7 = Bad or missing filename
- -8 = Too many files are already open (FILE OPEN only)
- -9 = Forbidden operation (e.g. write to a read-only file)
- -10 = Access denied
- -11 = Illegal combination of OPEN modes (FILE OPEN only)
- -12 = Buffer overflow
- -13 = Current line number unknown (for relative line seeks)
- -14 through -98: Reserved.
- -99 = Requested operation not implemented in this version of C-Kermit
- -999 = Unknown error
-
- When \v(f_error) is -1, this means the FILE command failed because
- because of a system error, in which case you can examine the following
- variables:
-
- \v(errno) = System error number.
- \v(errstring) = Error message corresponding to \v(errno).
-
- A special function is available for translating the \v(f_error) code to
- an error message string:
-
-\f_errmsg([code])
- If the code is -1, returns error message of the most recent system
- error; otherwise if the code is a valid \v(f_error) value, the associated
- message is returned. If the code is omitted, the status message
- corresponding to the current \v(f_error) value is returned.
-
- A FILE command that fails prints the appropriate error message
- automatically, except when the command is READ or SEEK and the error is
- -2 (end of file); in that case, the command still fails, but does not
- print a message. This allows constructions such as:
-
- fopen \%c oofa.txt
- while success { fread \%c }
- fclose \%c
-
- to work as expected, i.e. without an annoying message when the end of
- file is reached.
-
-1.22.6. File I/O Variables
-
- The variables associated with the file i/o package are:
-
- \v(f_count)
- Result of the most recent FILE COUNT (FCOUNT) command.
-
- \v(f_error)
- Numeric error code of most recent FILE command (0 = no error).
-
- \v(f_max)
- Maximum number of files open simultaneously.
-
-1.22.7. File I/O Functions
-
- Some of the FILE commands can also be issued as function calls, which
- makes script writing a bit more convenient, especially for C
- programmers. Also, several functions are provided that do not have
- command equivalents. Each of these functions takes a channel number as
- the first argument. These functions do not work for OPEN { READ, !READ,
- WRITE, !WRITE, and APPEND } files.
-
- \f_status(channel)
- Returns 0 if the channel is not open, otherwise a number between
- 1 and 15 which is the sum of the OPEN modes:
-
- 1 = /READ
- 2 = /WRITE
- 4 = /APPEND
- 8 = /BINARY
-
- The remaining functions work only for open channels. Each of these
- functions can fail for the applicable reasons listed in [387]Section
- 1.22.5. For instructions on handling function errors, see [388]Section
- 7.12.
-
- \f_pos(channel)
- Returns the file's current read/write pointer (0-based). There
- is no FILE command equivalent.
-
- \f_line(channel)
- Returns the file's current line number (0-based), if known,
- otherwise -1. There is no FILE command equivalent. The line
- number is known as long as no character or block i/o has been
- done on the channel.
-
- \f_handle(channel)
- Returns the "file handle" of the file. That is, it translates
- the portable C-Kermit channel number into a system-specific file
- handle or number that can be passed to other programs on the
- same platform. In UNIX this is a file descriptor. There is no
- FILE command equivalent.
-
- \f_eof(channel)
- Returns 1 if the read/write pointer of the file on the given
- channel is at the end of the file, 0 otherwise. Convenient in
- WHILE statements, e.g.:
-
- while not \f_eof(\%c) { fread \%c }
-
- \f_getchar(channel)
- Equivalent to FREAD /CHAR. Returns the character actually read.
- If \f_getchar() does not fail but the return value is empty,
- this means a NULL character was read.
-
- \f_getline(channel)
- Equivalent to FREAD /LINE. Returns the line actually read, but
- with the line terminator stripped. If \f_getline() does not fail
- but the return value is empty, this normally means an empty line
- was read.
-
- \f_getblock(channel,n)
- Equivalent to FREAD /SIZE:n. Returns the block of characters
- actually read. If the returned block is smaller than n, it
- indicates either that the end of file was reached or a NUL
- character is in the block.
-
- \f_putchar(channel,c)
- Equivalent to FWRITE /CHARACTER. Writes the character c. If c
- contains more than one character, only the first is written. If
- c is empty a NUL is written. Returns the number of characters
- written on success, or a negative error code upon failure.
-
- \f_putline(channel,string)
- Equivalent to FWRITE /LINE. Writes the string and adds the
- appropriate line termination character or sequence. If the
- string is empty or omitted, an empty line is written. Returns
- the number of characters written on success, or a negative error
- code upon failure.
-
- \f_putblock(channel,string)
- Equivalent to FWRITE /STRING. Writes the string as given. If the
- string is empty or omitted, nothing is written. Returns the
- number of characters written on success, or a negative error
- code upon failure.
-
-1.22.8. File I/O Function Examples
-
- fopen /read \%c oofa.txt ; Open our favorite file for reading
- if failure exit 1 ; Check that it's open
- while not \f_eof(\%c) { ; Loop until EOF
- .line := \f_getline(\%c) ; Get a line
- if success echo {\m(line)} ; Echo it
- }
- if not \f_eof(\%c) { ; Check reason for loop exit
- exit 1 File Error: \f_errmsg() ; If not EOF say so.
- }
-
- frewind \%c ; Rewind the file
- while not \f_eof(\%c) { ; Same thing but with block i/o
- .block := \f_getblock(\%c,256) ; (much faster than line i/o)
- if success xecho {\m(block)}
- }
-
- frewind \%c ; Rewind again
- while not \f_eof(\%c) { ; Same deal but with character i/o
- .c := \f_getchar(\%c) ; (much slower than line i/o)
- if success xecho {\m(c)}
- }
- close \%c
-
- To close all open files (equivalent to FCLOSE ALL):
-
- for \%i 0 \v(f_max)-1 1 {
- if \f_status(\%i) fclose \%i
- }
-
-1.23. The EXEC Command
-
- The EXEC command is available only in UNIX.
-
- EXEC [ /REDIRECT ] command [ arg1 [ arg2 [ ... ] ]
- Runs the given command with the arguments in such a way that the
- command replaces C-Kermit in memory, and C-Kermit ceases to
- execute. EXEC is like RUN, except instead of returning to
- C-Kermit when finished, the command returns to whatever process
- invoked Kermit.
-
- In the normal case, no files are closed, so the EXEC'd command inherits
- the open files, read/write pointers, working directory, process ID,
- user ID (unless command is SUID), group ID (unless command is SGID),
- groups, etc. (In UNIX, the EXEC command is simply a front end for
- execvp().)
-
- If the /REDIRECT switch is included, then if a connection is open (SET
- LINE or SET HOST), it becomes the standard input and output of the
- EXEC'd program. If no connection is open, the /REDIRECT switch has no
- effect. For example to use C-Kermit for PPP dialing in Linux:
-
- set modem type usr ; Specify the kind of modem you have
- set line /dev/ttyS1 ; Specify the device it's connected to
- set speed 57600 ; and the speed
- set flow rts/cts ; and flow control.
- set dial retries 100 ; Try the dial sequence up to 100 times.
- dial {{9-212-555-1212}{9-212-555-1213}{9-212-555-1214}{9-212-555-1215}}
- if fail exit 1
- for \%i 1 16 1 { ; Try up to 16 times to get login prompt
- input 10 Login: ; Wait 10 sec for it to appear
- if success break ; Got it - proceed...
- output \13 ; Send a carriage return and try again
- }
- if ( > \%i 16 ) stop 1 NO LOGIN PROMPT
- lineout \(myuserid) ; Send user ID
- input 30 assword: ; Wait for Password prompt
- if fail stop 1 NO PASSWORD PROMPT
- lineout \m(mypassword) ; Send the password.
- exec /redirect pppd ; Replace ourselves with pppd.
-
- In this example we assume that the script has already set up the
- myuserid and mypassword variables -- normally the password should be
- prompted for, rather than stored on disk. Notice the advantages over
- the well-known "chat script":
- * You don't have to control the modem itself with AT commands;
- Kermit's DIAL command does this for you.
- * You can have Kermit automatically redial as many times as you want
- until it gets a connection (if this is legal in your country).
- * You can have Kermit fetch the number or numbers from a dialing
- directory.
- * You can have Kermit cycle through a list of phone numbers (this is
- new in C-Kermit 7.0; see [389]Section 2.1.16) without having to
- enter the numbers in a dialing directory.
- * Dialing is location-independent; you can use the same script to
- dial from different areas or countries.
- * Once the connection is made, the full power of Kermit's script
- language is available to manage the dialog with the terminal server
- or other device that answers the phone call.
-
- NOTE: PPP and SLIP dialing are not available in Windows 95/98/NT/2000,
- whose APIs do not provide a method for an application to hand over a
- connection to the PPP or SLIP driver.
-
-1.24. Getting Keyword Lists with '?'
-
- Suppose you type "te" at the C-Kermit> 6.0 prompt and then Esc or Tab
- to request keyword completion. Kermit beeps, indicating that more than
- one command starts with "te". But if you type '?' to see what they are,
- Kermit shows only "telnet". So why the beep? Because of invisible
- keywords like "telopt", "terminal", and "text". Lots of keywords are
- invisible because they are either synonyms for other keywords or else
- esoteric options to be used only in special circumstances, so we don't
- want them cluttering up the menus.
-
- But then there is no way for you to discover them. So in C-Kermit 7.0,
- if you type '?' AFTER the beginning of a keyword field, then invisible
- keywords are shown too:
-
- C-Kermit> te<Esc><BEEP>
- C-Kermit> te? Command, one of the following:
- telnet telopt terminal text
- C-Kermit>te
-
- But if '?' is typed at the beginning of a field, only visible keywords
- are shown, as before (so, in this example, if '?' is typed at the
- C-Kermit> prompt, "telnet" is the only command shown that starts with
- "te").
-
-2. MAKING AND USING CONNECTIONS The SET LINE, SET HOST, and SET PORT (a
-synonym for SET LINE) commands have new synonyms, in which the word SET is
-replaced by the word OPEN: OPEN LINE, etc. There is no new functionality
-here, but OPEN is a better verb, since SET generally takes no action, whereas
-these commands actually try to open a connection. Furthermore, there is the
-symmetry with CLOSE. 2.0. SET LINE and SET HOST Command SwitchesThe SET LINE
-(SET PORT) and SET HOST commands now allow switches before the device or host
-name, in most cases, and under certain circumstances, also at the end. The
-new syntax is backwards compatible with the previous syntax; thus SET LINE,
-SET PORT, and SET HOST commands in command files written for C-Kermit 6.0 or
-earlier still work. The expanded syntax is:
-
-{ OPEN, SET } { LINE, PORT, HOST } [ switches ] device-or-address [ switches
-]
-
-The first group of switches is:
-
- /NETWORK-TYPE:{TCP/IP,X.25,PIPE,PTY...}
- When more than one network type is available, this lets you
- specify the type of network to use for this connection without
- affecting your global SET NETWORK TYPE. See [390]Section 2.7
- about pipes and ptys.
-
- /USERID:[string]
- This switch is equivalent to SET LOGIN USERID. If a string is
- given, it sent to host during Telnet negotiations; if this
- switch is given but the string is omitted, no user ID is sent to
- the host. If this switch is not given, your current LOGIN USERID
- (\v(userid) value), if any, is sent. Unlike most other switches,
- this one is "sticky", since the value must persist throughout
- the session in case the server requests the ID string at a later
- time.
-
- /CONNECT
- Enter CONNECT mode immediately and automatically after the
- device or connection is open. On serial devices, however, when
- CARRIER-WATCH is not OFF, wait up to 1 second for the Carrier
- Detect signal to appear before trying to connect, to give the
- device time to react DTR, which might have been off prior to
- opening the device.
-
- /SERVER
- Enter server mode immediately and automatically after the device
- or connection is open. Treatment of carrier is the same as for
- /CONNECT.
-
- /WAIT
- /NOWAIT
- For Telnet connections only: Like SET TELNET WAIT { ON, OFF },
- but applies only to this connection, and in fact applies only
- when OPENing this connection (which is usually the only place it
- matters). Typically you would use TELNET /NOWAIT to make a
- connection to a misbehaving Telnet server that does not reply to
- negotiations as required by the Telnet protocol definition.
-
- Note: /CONNECT and /SERVER switches are not available in the RLOGIN and
- TELNET commands, since these commands already include an implicit
- /CONNECT and preclude automatic entry into server mode.
-
- The /CONNECT and /SERVER switches are especially useful with "set host
- *" connections. For example, suppose you want to start a Kermit server
- on socket 3000 of your TCP host. Normally you would have to give the
- command:
-
- set host * 3000
-
- and then wait for a connection to come in, and only then could you give
- the SERVER command (or else define a macro to do this, and then execute
- the macro). Now you can do it in one step:
-
- set host /server * 3000
-
- This tells C-Kermit to wait for the connection and then enter server
- mode once it comes in, no matter how long it takes. Similarly, "set
- host /conn *" can be used to wait for a "chat" connection to come in.
-
- Another set of switches is available in VMS only, for use only with SET
- LINE:
-
- /SHARE
- Allows the SET LINE device to be opened in shared mode. Normally
- it makes no sense to open a serial device in shared mode, but
- it's necessary when C-Kermit is running in an environment such
- as DECIntact, that opens your job's controlling terminal in such
- a way that C-Kermit can't open it too, unless it enables SHARE
- privilege. Note: SHARE privilege is required.
-
- /NOSHARE
- Requires that the SET LINE device not be in use by any other
- process in order for it to be successfully opened by C-Kermit.
- If neither /SHARE nor /NOSHARE is specified, /NOSHARE is used.
-
- The second group of switches is:
-
- /NO-TELNET-INIT
- Do not send initial Telnet negotiations even if this is a Telnet
- port.
-
- /RAW-SOCKET
- This is a connection to a raw TCP socket ([391]Section 2.3.5).
-
- /RLOGIN
- Use Rlogin protocol even if this is not an Rlogin port.
-
- /TELNET
- Send initial Telnet negotiations even if this is not a Telnet
- port.
-
- As of C-Kermit 7.0 and K95 1.1.19, the TELNET command includes an
- implicit /TELNET switch. So if you TELNET to a non-TELNET port, Kermit
- sends initial Telnet negotiations. This makes sense, since that's what
- "telnet" means.
-
- If you want to make a connection to a non-Telnet port without sending
- initial Telnet negotiations, use:
-
- set host [ /connect ] name-or-address port
-
- or:
-
- telnet name-or-address port /no-telnet-init
-
- Additional switches might be added in the future; type "set host ?" or
- "set line ?" to see a current list.
-
-2.1. Dialing
-
- Automatic redialing is illegal or restricted in many countries, so
- until C-Kermit 7.0, it was disabled by default, i.e. until a SET DIAL
- RETRIES command was given. In C-Kermit 7.0, if no SET DIAL RETRIES
- command has been given, a default is picked dynamically at DIAL time
- based on the calling country code, if known. At this writing, the only
- country code known to have no restrictions on automatic redialing is 1.
- So in this case a limit of 10 is chosen; otherwise 1. If you have not
- given an explicit SET DIAL RETRIES command, SHOW DIAL shows the value
- as "(auto)", and then the value actually used is shown when you give
- the DIAL command.
-
- As of C-Kermit 7.0, automatic redialing is automatically canceled if
- the call could not be placed because no dialtone was detected.
-
-2.1.1. The Dial Result Message
-
- If DIAL DISPLAY is not ON, the "Call complete" message now shows the
- modem's call result message, for example:
-
- Dialing: ...
- Call complete: "CONNECT 31200/ARQ/V32/LAPM/V42BIS"
-
- The exact format and contents of this message, of course, depends on
- the make, model, and configuration of your modem, so use your modem
- manual to interpret it. The call result message is also available in
- C-Kermit's \v(dialresult) variable.
-
- C-Kermit> echo \v(dialresult)
- CONNECT 31200/ARQ/V32/LAPM/V42BIS
- C-Kermit> echo Speed = \fword(\v(dialresult),2)
- Speed = 31200
- C-Kermit>
-
- Suppose your modem reports the modulation speed as shown above and you
- want to ensure your call is completed at (say) 24000 bps or more. You
- can use a little macro to do the job:
-
-define HSDIAL { ; High Speed DIAL
- local \%s
- if < \v(argc) 1 if not def \v(dialnumber) end 1 Usage: \%0 number
- set dial retries 100
- set dial interval 1
- while true {
- dial \%*
- if fail end 1 DIAL failed.
- asg \%s \fword(\v(dialresult),2)
- if def \%s if numeric \%s if not < \%s 24000 break
- }
-}
-
- (See [392]Section 7.5 about the \%* variable.)
-
-2.1.2. Long-Distance Dialing Changes
-
- Due to the glut of cell phones, pagers, fax machines, ISPs, etc, area
- codes and dialing rules are changing all the time. In the North
- American Numbering Plan (NANP) countries (USA, Canada, etc), area codes
- are split or overlayed with increasing frequency, and 10- and 11-digit
- dialing is gradually becoming the norm for local calls. Changes are
- occurring In Europe, too, partly for these reasons and partly because
- of some new EC rules.
-
- In France, effective 18 October 1996, all calls, even local ones, must
- be dialed with an area code. French area codes are presently 1-digit
- numbers, 1-6, and the long-distance dialing prefix is 0. All calls
- within France are considered long distance and begin with 01, 02, ...,
- 06.
-
- Effective 1 May 1997, all calls within the US state of Maryland, even
- local ones, must be dialed with an area code but without the
- long-distance prefix -- this is the now widely-known North American
- phenomenon of "ten digit dialing". The same is happening elsewhere --
- many cities in Florida adopted 10-digit dialing in 1998.
-
- In Italy beginning 19 June 1998, all calls to fixed (as opposed to
- mobile) numbers must be prefixed by 0. When calling into Italy from
- outside, the 0 must follow the country code (39). Calls to cell phones,
- however, must be placed without the 0. Then on 29 December 2000, the 0
- will become a 4 (for calling fixed numbers) and a prefix of 3 must used
- for calling mobile phones. More info at:
- http://www.telecomitalia.it/npnn/.
-
- In Spain, effective 4 April 1998, with hard cutover on 18 July 1998,
- all calls within the country must be dialed with 9 digits, and all
- calls from outside Spain must also be dialed with 9 digits (after the
- country code, 34). The new 9-digit numbers all begin with "9". More
- info at: [393]http://www.telefonica.es/cambiodenumeracion/
-
- Several new dialing features and commands have been added in version
- 6.1 and 7.0 to address these changes.
-
- C-Kermit 6.0 and Kermit 95 1.1.11 and earlier handle the French
- situation via a reasonable subterfuge (setting the local area code to a
- nonexistent one), but did not handle "ten-digit dialing" well at all;
- the recommended technique was to change the long-distance dialing
- prefix to nothing, but this defeated Kermit's "list numbers for one
- name" feature when the numbers were in different locations. For
- example:
-
- set dial ld-prefix
- dial onlineservice
-
- where "onlineservice" is a dialing directory entry name corresponding
- to entries that are in (say) Maryland as well as other states, would
- not correctly dial the numbers not in Maryland.
-
- A new command lets you specify a list of area codes to be considered
- local, except that the area code must be dialed:
-
- SET DIAL LC-AREA-CODES [ areacode [ areacode [ areacode [ ... ] ] ] ]
- The list may include up to 32 area codes. If a number is called
- whose area code is in this list, it is dialed WITHOUT the
- long-distance prefix, but WITH the area code.
-
- So in Maryland, which (last time we looked) has two area codes, 410 and
- 301, the setup would be:
-
- SET DIAL LC-AREA-CODES 410 301
-
- Example:
-
- SET DIAL LD-PREFIX 1
- SET DIAL AREA-CODE 301
- SET DIAL LC-AREA-CODES 410 301 <-- Area codes in 10-digit dialing region
- DIAL +1 (301) 765-4321 <-- Dials 3017654321 (local with area code)
- DIAL +1 (410) 765-4321 <-- Dials 4107654321 (local with area code)
- DIAL +1 (212) 765-4321 <-- Dials 12127654321 (long distance)
-
- The SET DIAL LC-AREA-CODES command does not replace the SET DIAL
- AREA-CODE command. The latter specifies the area code you are dialing
- from. If the called number is in the same area code, then the area code
- is dialed if it is also in the LC-AREA-CODES list, and it is not dialed
- otherwise. So if "301" had not appeared in the LC-AREA-CODES list in
- the previous example:
-
- SET DIAL LD-PREFIX 1
- SET DIAL AREA-CODE 301
- SET DIAL LC-AREA-CODES 410 <-- Area codes in 10-digit dialing region
- DIAL +1 (301) 765-4321 <-- Dials 7654321 (local)
- DIAL +1 (410) 765-4321 <-- Dials 4107654321 (local with area code)
- DIAL +1 (212) 765-4321 <-- Dials 12127654321 (long distance)
-
- The new Kermit versions also add a Local Call Prefix and Local Call
- Suffix, in case you have any need for it. These are added to the
- beginning and of local phone numbers (i.e. numbers that are not
- long-distance or international). Examples:
-
- SET DIAL LD-PREFIX 1
- SET DIAL LC-PREFIX 9
- SET DIAL LC-SUFFIX *
- SET DIAL LC-AREA-CODES 410 <-- Area codes in 10-digit dialing region
- SET DIAL AREA-CODE 301
- DIAL +1 (301) 765-4321 <-- Dials 97654321* (local)
- DIAL +1 (410) 765-4321 <-- Dials 94107654321* (local with area code)
- DIAL +1 (212) 765-4321 <-- Dials 12127654321 (long distance)
-
-2.1.3. Forcing Long-Distance Dialing
-
- Suppose a number is in your country and area, but for some reason you
- need to dial it long-distance anyway (as is always the case in France).
- There have always been various ways to handle this:
-
- 1. Temporarily set your area code to a different (or nonexistent or
- impossible) one (but this required knowledge of which area codes
- were nonexistent or impossible in each country).
- 2. Dial the number literally instead of using the portable format, but
- this defeats the purpose of the portable dialing directory.
-
- Now there is also a new command that, very simply, can force
- long-distance dialing:
-
- SET DIAL FORCE-LONG-DISTANCE { ON, OFF }
- If a call is placed to a portable phone number within the same
- country code as the calling number, it is dialed with the
- long-distance prefix and the area code if FORCE-LONG-DISTANCE is
- ON. If OFF, the regular rules and procedures apply.
-
- Example (France):
-
- SET DIAL COUNTRY-CODE 33
- SET DIAL AREA-CODE 6
- SET DIAL FORCE-LONG-DISTANCE ON
-
- (In fact, SET DIAL COUNTRY-CODE 33 automatically sets DIAL
- FORCE-LONG-DISTANCE ON...)
-
- Example (USA, for a certain type of reverse-charge calling in which the
- called number must always be fully specified):
-
- SET DIAL PREFIX 18002666328$ ; 1-800-COLLECT
- SET DIAL COUNTRY-CODE 1
- SET DIAL AREA-CODE 212
- SET DIAL FORCE-LONG-DISTANCE ON
-
- Example (Toronto, where calls to exchange 976 within area code 416 must
- be dialed as long distance, even when you are dialing from area code
- 416):
-
- SET DIAL COUNTRY-CODE 1
- SET DIAL AREA-CODE 416
- SET DIAL FORCE-LONG-DISTANCE ON
- DIAL +1 (416) 976-xxxx
-
- If dialing methods were consistent and sensible, of course it would be
- possible to always dial every domestic call as if it were long
- distance. But in many locations this doesn't work or if it does, it
- costs extra. The following macro can be used for dialing any given
- number with forced long-distance format:
-
- define LDIAL {
- local \%x
- set dial force-long-distance on
- dial \%*
- asg \%x \v(success)
- set dial force-long-distance off
- end \%x
- }
-
- (See [394]Section 7.5 about the \%* variable.)
-
-2.1.4. Exchange-Specific Dialing Decisions
-
- This applies mainly to the North American Numbering Plan (NANP). Refer
- to the section "Alternative notations" in [395]Using C-Kermit 2nd
- Edition, pages 106-107, and the story about Toronto on page 110. Using
- the new LC-AREA-CODES list, we can address the problem by treating the
- exchange as part of the area code:
-
- SET DIAL LD-PREFIX 1
- SET DIAL AREA-CODE 416
- SET DIAL LC-AREA-CODES 905276
- DIAL +1 416 765 4321 <-- 7654321 (local)
- DIAL +1 905 276 4321 <-- 9052764321 (local with area code)
- DIAL +1 905 528 4321 <-- 19055284321 (long distance)
-
- The same technique can be used in Massachusetts (story at top of page
- 111) and in any other place where dialing to some exchanges within a
- particular area code is local, but to others in the same area code is
- long distance.
-
-2.1.5. Cautions about Cheapest-First Dialing
-
- Kermit does not maintain a knowledge base of telephony information; it
- only provides the tools to let you enter a phone number in a standard
- format and dial it correctly from any location in most cases.
-
- In particular, Kermit does not differentiate the charging method from
- the dialing method. If a call that is DIALED as long-distance (e.g.
- from 212 to 718 in country code 1) is not CHARGED as long distance, we
- have no way of knowing that without keeping a matrix of charging
- information for every area-code combination within every country, and
- any such matrix would be obsolete five minutes after it was
- constructed. Thus, "cheapest-first" sorting is only as reliable as our
- assumption that the charging method follows the dialing method. A good
- illustration would be certain online services that have toll-free
- dialup numbers which they charge you a premium (in your online service
- bill) for using.
-
-2.1.6. Blind Dialing (Dialing with No Dialtone)
-
- C-Kermit's init string for Hayes-like modems generally includes an X4
- command to enable as many result codes as possible, so that Kermit can
- react appropriately to different failure reasons. One of the result
- codes that X4 enables is "NO DIALTONE". A perhaps not obvious side
- effect of enabling this result code that the modem must hear dialtone
- before it will dial.
-
- It is becoming increasingly necessary to force a modem to dial even
- though it does not hear a dialtone on the phone line; for example, with
- PBXs that have strange dialtones, or with phone systems in different
- countries, or with ISDN phones, etc. This is called "blind dialing".
-
- C-Kermit 7.0 has two new commands to cope with this situation:
-
- SET DIAL IGNORE-DIALTONE { ON, OFF }
- OFF (the default) means to tell the modem to wait for dialtone
- before dialing. ON means to enable "blind dialing", i.e. tell
- the modem NOT to wait for dialtone before dialing. Generally
- this is accomplished by sending ATX3 to the modem just prior to
- dialing. SET MODEM TYPE xxx and then SHOW MODEM displays
- Kermit's built-in "ignore dialtone" command.
-
- SET DIAL COMMAND IGNORE-DIALTONE text
- This lets you change the built-in ignore-dialtone command (such
- as ATX3) to whatever you choose, in case the built-in one does
- not work, or another command works better.
-
- Notes:
- 1. The ignore-dialtone command is not sent unless SET DIAL
- IGNORE-DIALTONE is ON.
- 2. The ATX3 command generally disables not only NO DIALTONE, but also
- BUSY. So this will prevent Kermit from detecting when the line is
- busy. This is a property of the modem, not of Kermit.
-
-2.1.7. Trimming the Dialing Dialog
-
- The command:
-
- SET MODEM COMMAND action [ command ]
-
- is used to override Kermit's built-in modem commands for each action,
- for each kind of modem in its internal database. If you include a
- command, this is used instead of the built-in one. If you omit the
- command, this restores the original built-in command.
-
- If you want to omit the command altogether, so Kermit doesn't send the
- command at all, or wait for a response, use:
-
- SET MODEM COMMAND action {}
-
- That is, specify a pair of empty braces as the command, for example:
-
- SET MODEM COMMAND ERROR-CORRECTION ON {}
-
-2.1.8. Controlling the Dialing Speed
-
- The rate at which characters are sent to the modem during dialing is
- normally controlled by the built-in modem database. You might want to
- override this if Kermit seems to be dialing too slowly, or it is
- sending characters to the modem faster than the modem handle them. A
- new command was added for this in C-Kermit 7.0:
-
- SET DIAL PACING number
- Specifies the number of milliseconds (thousandths of seconds) to
- pause between each character when sending commands to the modem
- during DIAL or ANSWER command execution. 0 means no pause at
- all, -1 (the default) or any other negative number means to use
- the value from the database. Any number greater than 0 is the
- number of milliseconds to pause.
-
- HINT: You might also need to control the rate at which the modem
- generates Touch Tones during dialing, for example when sending a
- numeric page. There are two ways to do this. One way is to insert pause
- characters into the dialing string. For modems that use the AT command
- set, the pause character is comma (,) and causes a 2-second pause. On
- most modems, you can use the S8 register to change the pause interval
- caused by comma in the dialing string. The other way is to set your
- modem's tone generation interval, if it has a command for that. Most
- AT-command-set modems use S11 for this; the value is in milliseconds.
- For example on USR modems:
-
- ATS11=200
-
- selects an interval of 200 milliseconds to separate each dialing tone.
-
- Hint: To add S-Register settings or other commands to your dialing
- procedure, use the new SET MODEM COMMAND PREDIAL-INIT command
- ([396]Section 2.2.2).
-
-2.1.9. Pretesting Phone Number Conversions
-
- The LOOKUP command now accepts telephone numbers as well as
- directory-entry names, for example:
-
- LOOKUP +1 (212) 7654321
-
- When given a phone number, LOOKUP prints the result of converting the
- phone number for dialing under the current dialing rules. For example,
- if my country code is 1 and my area code is 212, and I am dialing out
- from a PBX whose outside-line prefix is "93,":
-
- C-Kermit> lookup +1 (212) 7654321
- +1 (212) 7654321 => 93,7654321
- C-Kermit>
-
- You can also use the \fdialconvert(phone-number) function ([397]Section
- 2.1.11) to do this programmatically:
-
- C-Kermit> echo "\fdialconvert(+1 (212) 7654321)"
- "93,7654321"
- C-Kermit>
-
- So the new LOOKUP behaves as follows:
-
- LOOKUP portable-format-phone-number
- Displays how the number would actually be dialed Sets FAILURE if
- there was a conversion error, otherwise SUCCESS.
-
- LOOKUP literal-format-phone-number
- Displays the same literal-format-phone-number Always sets
- SUCCESS.
-
- LOOKUP dialing-directory-name
- Displays all matching entries and converts portable phone
- numbers. Sets SUCCESS if at least one entry was found, otherwise
- FAILURE.
-
- LOOKUP =anything
- Displays "=anything" and sets SUCCESS.
-
- There is, at present, no programmatic way to fetch numbers from the
- dialing directory. This will be considered for a future release.
-
-2.1.10. Greater Control over Partial Dialing
-
- The following rules now apply to partial dialing:
-
- * Phone number transformations based on country and area code,
- application of prefixes, etc, are performed only on the first
- PDIAL.
- * Each PDIAL argument is looked up in the dialing directory, so it is
- possible have directory entries for pieces of phone numbers or
- other information.
- * Suffixes are not applied automatically, since there is no way for
- C-Kermit to know in which PDIAL segment you want them to be
- applied.
-
- However, the suffix that *would* have been applied, based on the
- dialing rules that were invoked when processing the first PDIAL
- command, is stored in the variable:
-
- \v(dialsuffix)
-
- which you can include in any subsequent PDIAL or DIAL commands.
-
- Example:
-
- pdial {\m(my_long_distance_pager_number_part_1)}
- pdial {\m(my_long_distance_pager_number_part_2)}
- pdial {\v(dialsuffix)}
- pdial {\m(my_long_distance_pager_number_part_3)}
- pdial {@\m(numeric_pager_code)#}
-
-2.1.11. New DIAL-related Variables and Functions
-
- \fdialconvert(s)
- s is a phone number in either literal or portable format (not a
- dialing directory entry name). The function returns the dial
- string that would actually be used by the DIAL command when
- dialing from the current location, after processing country
- code, area code, and other SET DIAL values, and should be the
- same as the result of LOOKUP when given a telephone number.
-
- \v(dialsuffix)
- Contains the suffix, if any, that was applied in the most recent
- DIAL command, or the suffix that would have been applied in the
- most recent PDIAL command. Use this variable to send the dial
- suffix at any desired point in a PDIAL sequence.
-
- \v(dialtype)
- A number indicating the type of call that was most recently
- placed. Can be used after a normal DIAL command, or after the
- first PDIAL command in a PDIAL sequence. Values are:
-
- -2: Unknown because TAPI handled the phone number translation.
- -1: Unknown because some kind of error occurred.
- 0: Internal within PBX.
- 1: Toll-free.
- 2: Local within calling area.
- 3: Unknown (e.g. because a literal-format phone number was given).
- 4: Long distance within country.
- 5: International
-
- \v(dialcount)
- The current value of the DIAL retry counter, for use in a DIAL
- macro ([398]Section 2.1.13).
-
- \v(d$px)
- PBX Exchange (see [399]Section 2.1.12).
-
- Other dial-related variables, already documented in [400]Using C-Kermit
- (or other sections of this document, e.g. [401]Section 2.1.1), include
- \v(dialnumber), \v(dialstatus), etc. A convenient way to display all of
- them is:
-
- show variable dial ; hint: abbreviate "sho var dial"
-
- This shows the values of all the variables whose names start with
- "dial". Also "show variable d$" (to show the \v(d$...) variables).
-
-2.1.12. Increased Flexibility of PBX Dialing
-
- Refer to [402]Using C-Kermit, 2nd Edition, pages 107-108. Recall that
- three commands are needed to configure C-Kermit for dialing from a PBX:
-
- SET DIAL PBX-EXCHANGE number
- SET DIAL PBX-INSIDE-PREFIX number
- SET DIAL PBX-OUTSIDE-PREFIX number
-
- Unfortunately, this model does not accommodate PBXs that have more than
- one exchange. For example our PBX at Columbia University (which must
- handle more than 10,000 phones) has 853-xxxx and 854-xxxx exchanges.
-
- Beginning in C-Kermit 7.0, the SET DIAL PBX-EXCHANGE command accepts a
- list of exchanges, e.g.:
-
- SET DIAL PBX-EXCHANGE 853 854
-
- (multiple exchanges are separated by spaces, not commas).
-
- So now when dialing a portable-format number that has the same country
- and area codes as those of your dialing location, C-Kermit compares the
- exchange of the dialed number with each number in the PBX Exchange list
- (rather than with a single PBX Exchange number, as it did formerly) to
- determine whether this is an internal PBX number or an external call.
- If it is an external call, then the PBX Outside Prefix is applied, and
- then the normal dialing rules for local or long-distance calls.
-
- If it is an inside call, the exchange is replaced by the PBX Inside
- Prefix. But if the PBX has more than one exchange, a single fixed PBX
- Inside Prefix is probably not sufficient. For example, at Columbia
- University, we must dial 3-xxxx for an internal call to 853-xxxx, but
- 4-xxxx for a call to 854-xxxx. That is, the inside prefix is the final
- digit of the exchange we are dialing. For this reason, C-Kermit 7.0
- provides a method to determine the inside prefix dynamically at dialing
- time, consisting of a new variable and new syntax for the SET DIAL
- PBX-INSIDE-PREFIX command:
-
- \v(d$px)
- This variable contains the exchange that was matched when a PBX
- internal call was detected. For example, if the PBX exchange
- list is "853 854" and a call is placed to +1 (212) 854-9999,
- \v(d$px) is set to 854.
-
- SET DIAL PBX-INSIDE-PREFIX \fxxx(...)
- If the PBX Inside Prefix is defined to be a function, its
- evaluation is deferred until dialing time. Normally, this would
- be a string function having \v(d$px) as an operand. Of course,
- you can still specify a constant string, as before.
-
- So given the following setup:
-
- SET DIAL COUNTRY-CODE 1
- SET DIAL AREA-CODE 212
- SET DIAL PBX-OUTSIDE-PREFIX 93,
- SET DIAL PBX-EXCHANGE 853 854
- SET DIAL PBX-INSIDE-PREFIX \fright(\v(d$px),1)
-
- The following numbers give the results indicated:
-
- Number Result
- +1 (212) 854-9876 4-9876
- +1 (212) 853-1234 3-1234
- +1 (212) 765-4321 93,765-4321
- +1 (333) 765-4321 93,1333765-4321
-
- Furthermore, the K_PBX_XCH environment variable may now be set to a
- list of exchanges to automatically initialize C-Kermit's PBX exchange
- list, for example (in UNIX ksh or bash):
-
- export K_PBX_XCH="853 854"
-
- (Quotes required because of the space.) Of course, this variable can
- also be set to a single exchange, as before:
-
- export K_PBX_XCH=853
-
-2.1.13. The DIAL macro - Last-Minute Phone Number Conversions
-
- After a DIAL or LOOKUP command is given, a list of phone numbers is
- assembled from the dialing directory (if any), with all
- location-dependent conversion rules applied as described in Chapter 5
- of [403]Using C-Kermit.
-
- However, additional conversions might still be required at the last
- minute based on local or ephemeral conditions. So that you can have the
- final word on the exact format of the dial string, C-Kermit 7.0 lets
- you pass the converted string through a macro of your own design for
- final processing before dialing. The relevant command is:
-
- SET DIAL MACRO [ name ]
- Specifies the name of a macro to be run on each phone number
- after all built-in conversions have been applied, just before
- the number is dialed. If no name is given, no macro is run. The
- phone number, as it would have been dialed if there were no dial
- macro, is passed to the macro.
-
- The dial macro can do anything at all (except start a file transfer).
- However, the normal use for the macro would be to modify the phone
- number. For this reason the phone number is passed to the macro as
- argument number 1 (\%1). To cause a modified number to be dialed, the
- macro should terminate with a RETURN statement specifying a return
- value. To leave the number alone, the macro should simply end. Example:
-
- define xxx return 10108889999$\%1
- set dial macro xxx
- dial xyzcorp
-
- This defines a DIAL MACRO called xxx, which puts an access code on the
- front of the number. Another example might be:
-
- def xxx if equal "\v(modem)" "hayes-1200" return \freplace(\%1,$,{,,,,,})
- set dial macro xxx
- dial xyzcorp
-
- which replaces any dollar-sign in the dial string by a series of five
- commas, e.g. because this particular modem does not support the "wait
- for bong" feature (remember that commas that are to be included
- literally in function arguments must be enclosed in braces to
- distinguish them from the commas that separate the arguments) and when
- the IF condition is not satisfied, the macro does not return a value,
- and so the number is not modified. Then when a DIAL command is given
- referencing a dialing directory entry, "xyzcorp". The macro is
- automatically applied to each matching number.
-
- Numerous dial-, modem-, communications-, and time-related variables are
- available for decision making your dial macro. Type SHOW VARIABLES for
- a list. Of particular interest is the \v(dialcount) variable, which
- tells how many times the DIAL command gone through its retry loop: 1 on
- the first try, 2 on the second, 3 on the third, and so on, and the
- \v(dialresult) and \v(dialstatus) variables.
-
- Here are some other applications for the DIAL MACRO (from users):
-
- * Phone numbers in the dialing directory are formatted with '-' for
- readability, but some modems don't like the hyphens, so the DIAL
- macro is used to remove them before dialing; e.g 0090-123-456-78-99
- becomes 00901234567899: "def xxx return \freplace(\%1,-)".
- * To set some specific modem (or other) options depending on the
- called customer or telephone number.
- * Choosing the most appropriate provider based on (e.g.) time of day,
- or cycling through a list of providers in case some providers might
- be busy.
-
- To illustrate the final item, suppose you have a choice among many
- phone service providers; the provider is chosen by dialing an access
- code before the number. Different providers might be better (e.g.
- cheaper) for certain times of day or days of the week, or for dialing
- certain locations; you can use the DIAL macro to add the access for the
- most desirable provider.
-
- Similarly, when the same number might be reached through multiple
- providers, it's possible that one provider might not be able to
- complete the call, but another one can. In that case, you can use the
- DIAL macro to switch providers each time through the DIAL loop --
- that's where the \v(dialcount) variable comes in handy.
-
- The following command can be used to debug the DIAL macro:
-
- SET DIAL TEST { ON, OFF }
- Normally OFF, so the DIAL command actually dials. When ON, the
- DIAL command performs all lookups and number conversions, and
- then goes through the number list and retry loop, but instead of
- actually dialing, lists the numbers it would have called if none
- of the DIAL attempts succeeded (or more precisely, every number
- was always busy).
-
-2.1.14. Automatic Tone/Pulse Dialing Selection
-
- SET DIAL METHOD { AUTO, DEFAULT, PULSE, TONE }
- Chooses the dialing method for subsequent calls.
-
- Prior to version 7.0, C-Kermit's DIAL METHOD was DEFAULT by default,
- meaning it does not specify a dialing method to the modem, but relies
- on the modem to have an appropriate default dialing method set. So, for
- example, when using Hayes compatible modems, the dial string would be
- something like ATD7654321, rather than ATDT7654321 or ATDP7654321.
-
- In C-Kermit 7.0 and K95 1.1.19, the dial method can be set from the
- environment variable:
-
- K_DIAL_METHOD
-
- when Kermit starts. The values can be TONE, PULSE, or DEFAULT, e.g.
- (UNIX):
-
- set K_DIAL_METHOD=TONE; export K_DIAL_METHOD
-
- In the absence of a K_DIAL_METHOD definition, the new default SET DIAL
- METHOD is AUTO rather than DEFAULT. When DIAL METHOD is AUTO and the
- local country code is known, then if tone dialing is universally
- available in the corresponding area, tone dialing is used; if dialing
- from a location where pulse dialing is mandatory, pulse dialing is
- used.
-
- The "tone country" and "pulse country" lists are preloaded according to
- our knowledge at the time of release. You can see their contents in the
- SHOW DIAL listing. You can change the lists with:
-
- SET DIAL TONE-COUNTRIES [ cc [ cc [ ... ] ] ]
- Replaces the current TONE-COUNTRIES list with the one given.
- Each cc is a country code; separate them with spaces (not
- commas). Example:
-
- set dial tone-countries 1 358 44 46 49
-
- If no country codes are given, the current list, if any, is
- removed, in which case SET DIAL METHOD AUTO is equivalent to SET
- DIAL METHOD DEFAULT.
-
- SET DIAL PULSE-COUNTRIES [ cc [ cc [ ... ] ] ]
- Replaces the current PULSE-COUNTRIES list with the one give.
- Syntax and operation is like SET DIAL TONE-COUNTRIES.
-
- If the same country code appears in both lists, Pulse takes precedence.
-
- The SET DIAL TONE- and PULSE-COUNTRIES commands perform no verification
- whatsoever on the cc's, since almost any syntax might be legal in some
- settings. Furthermore, there is no facility to edit the lists; you can
- only replace the whole list. However, since the only purpose of these
- lists is to establish a basis for picking tone or pulse dialing
- automatically, all you need to override the effect of the list is to
- set a specific dialing method with SET DIAL METHOD TONE or SET DIAL
- METHOD PULSE.
-
-2.1.15. Dial-Modifier Variables
-
- As of C-Kermit 7.0, dial modifiers are available in the following
- variables:
-
- \v(dm_lp) Long pause
- \v(dm_sp) Short pause
- \v(dm_pd) Pulse dial
- \v(dm_td) Tone dial
- \v(dm_wa) Wait for answer
- \v(dm_wd) Wait for dialtone
- \v(dm_rc) Return to command mode
-
- You can use these in your dial strings in place of hardwired modifiers
- like "@", ",", etc, for increased portability of scripts. Example:
-
- C-Kermit>set modem type usrobotics
- C-Kermit>sho variables dm
- \v(dm_lp) = ,
- \v(dm_sp) = /
- \v(dm_pd) = P
- \v(dm_td) = T
- \v(dm_wa) = @
- \v(dm_wd) = W
- \v(dm_rc) = ;
- C-Kermit>exit
-
-2.1.16. Giving Multiple Numbers to the DIAL Command
-
- Prior to C-Kermit 7.0, the only way to give a DIAL command a list of
- phone numbers to try until one answers was to create a dialing
- directory that had multiple entries under the same name, and then use
- that entry name in the DIAL command. Now a list of numbers can be given
- to the DIAL command directly in the following format:
-
- dial {{number1}{number2}{number3}...}
-
- This is the same list format used by SEND /EXCEPT: and other commands
- that allow a list where normally a single item is given. Restrictions
- on this form of the DIAL command are:
-
- * The first two braces must be adjacent; spacing is optional
- thereafter.
- * Each number must be an actual number to dial, not a dialing
- directory entry.
- * Dialing directory entries may not contain number lists in this
- format.
-
- In all other respects, the numbers are treated as if they had been
- fetched from the dialing directory; they can be in literal or portable
- format, etc. Example:
-
- dial {{7654321} {+1 (212) 5551212} { 1-212-5556789 }}
-
- The list can be any length at all, within reason.
-
- This feature is especially handy for use with the K95 Dialer, allowing
- a list of phone numbers to be specified in the Telephone Number box
- without having to set up or reference a separate dialing directory.
-
- You can also use it to add commonly-dialed sequences as variables in
- your C-Kermit customization file, e.g.:
-
- define work {{7654321}{7654322}{7654323}}
-
- and then:
-
- dial {\m(work)}
-
- (the variable name must be enclosed in braces).
-
- Or more simply:
-
- define work dial {{7654321}{7654322}{7654323}}
-
- and then:
-
- work
-
-2.2. Modems
-
-2.2.1. New Modem Types
-
- Since C-Kermit 6.0:
-
- atlas-newcom-33600ifxC Atlas/Newcom 33600
- att-keepintouch AT&T KeepinTouch PCMCIA V.32bis Card Modem
- att-1900-stu-iii AT&T Secure Data STU-III Model 1900
- att-1910-stu-iii AT&T Secure Data STU-III Model 1910
- bestdata Best Data
- cardinal Cardinal V.34 MVP288X series.
- compaq Compaq Data+Fax (e.g. in Presario)
- fujitsu Fujitsu Fax/Modem Adapter
- generic-high-speed Any modern error-correcting data-compressing modem
- itu-t-v25ter/v250 ITU-T (CCITT) V.25ter (V.250) standard command set
- megahertz-att-v34 Megahertz AT&T V.34
- megahertz-xjack Megahertz X-Jack
- motorola-codex Motorola Codex 326X Series
- motorola-montana Motorola Montana
- mt5634zpx Multitech MT5634ZPX
- rockwell-v90 Rockwell V.90 56K
- rolm-244pc Siemens/Rolm 244PC (AT command set)
- rolm-600-series Siemens/Rolm 600 Series (AT command set)
- spirit-ii QuickComm Spirit II
- suprasonic SupraSonic V288+
- supra-express-v90 Supra Express V.90
-
- One of the new types, "generic-high-speed" needs a bit of explanation.
- This type was added to easily handle other types that are not
- explicitly covered, without going through the bother of adding a
- complete user-defined modem type. This one works for modern modems that
- use the AT command set, on the assumption that all the default
- ("factory") settings of the modem (a) are appropriate for Kermit, (b)
- include error correction, data compression, and speed buffering; and
- (c) are recallable with the command AT&F.
-
- If the command to recall your modem's profile is not AT&F, use the SET
- MODEM COMMAND INIT-STRING command to specify the appropriate modem
- command. The default init-string is AT&F\13 (that is, AT, ampersand, F,
- and then carriage return); a survey of about 20 modern modem types
- shows they all support this, but they might mean different things by
- it. For example, the USR Sportster or Courier needs AT&F1 (not AT&F,
- which is equivalent to AT&F0, which recalls an inappropriate profile),
- so for USR modems:
-
- set modem type generic-high-speed
- set modem command init AT&F1\13
-
- Of course, USR modems already have their own built-in modem type. But
- if you use this one instead, it will dial faster because it has fewer
- commands to give to the modem; in that sense "&F1" is like a macro that
- bundles numerous commands into a single one. See your modem manual for
- details about factory profiles and commands to recall them.
-
- WARNING: Do not use the generic-high-speed modem type in operating
- systems like VMS where hardware flow control is not available, at least
- not unless you change the init string from AT&F\13 to something else
- that enables local Xon/Xoff or other appropriate type of flow control.
-
- Also see [404]Section 2.1.7 for additional hints about making dialing
- go faster.
-
-2.2.2. New Modem Controls
-
- SET MODEM CAPABILITIES list
- In C-Kermit 7.0, this command automatically turns MODEM
- SPEED-MATCHING OFF if SB (Speed Buffering) is in the list, and
- turns it ON if SB is absent.
-
- SET MODEM COMMAND PREDIAL-INIT [ text ]
- Commands to be sent to the modem just prior to dialing. Normally
- none.
-
- SET MODEM SPEAKER { ON, OFF }
- Determines whether modem speaker is on or off while call is
- being placed. ON by default. Note: This command does not provide
- fine-grained control over when the speaker is on or off.
- Normally, ON means while the call is being placed, until the
- point at which carrier is successfully established. If your
- modem has a different speaker option that you want to choose,
- then use the SET MODEM COMMAND SPEAKER ON text command to
- specify this option.
-
- SET MODEM COMMAND SPEAKER { ON, OFF } [ text ]
- Specify or override the commands to turn your modem's speaker on
- and off.
-
- SET MODEM VOLUME { LOW, MEDIUM, HIGH }
- When MODEM SPEAKER is on, select volume. Note: In some modems,
- especially internal ones, these commands have no effect; this is
- a limitation of the particular modem, not of Kermit.
-
- SET MODEM COMMAND VOLUME { LOW, MEDIUM, HIGH } [ text ]
- Specify or override the commands to set your modem's speaker
- volume.
-
- SET MODEM COMMAND IGNORE-DIALTONE [ text ]
- The command to enable blind dialing ([405]Section 2.1.6).
-
- SET MODEM ESCAPE-CHARACTER code
- Has been augmented to allow codes of 0 or less: < 0 means the
- escape mechanism is disabled. = 0 means to use (restore) the
- default value from the modem database. > 0 and < 128 is a
- literal value to be used instead of the default one. > 127 means
- the escape mechanism is disabled. This affects "modem hangup".
- When the escape mechanism is disabled, but SET MODEM
- HANGUP-METHOD is MODEM-COMMAND, it sends the hangup command
- immediately, without the <pause>+++<pause> business first. This
- is useful (for example) when sending lots of numeric pages, a
- process in which never we go online, and so never need to escape
- back. Eliminating the unnecessary pauses and escape sequence
- allows a lot more pages to be sent per unit time.
-
- Recall that C-Kermit can dial modems to which it is connected via
- TCP/IP (Telnet or Rlogin) as described on page 126 of [406]Using
- C-Kermit, 2nd Ed. In this case the MODEM HANGUP-METHOD should be
- MODEM-COMMAND, since RS-232 signals don't work over TCP/IP connections.
- As noted in the manual, such connections are set up by the following
- sequence:
-
- set host host [ port ]
- set modem type name
- dial number
-
- But this can cause complications when you use Kermit to switch between
- serial and TCP/IP connections. In the following sequence:
-
- set host name
- set modem type name
- set port name
-
- the first two commands obey the rules for dialing out over Telnet.
- However, the SET PORT command requires that Kermit close its current
- (Telnet) connection before it can open the serial port (since Kermit
- can only have one connection open at a time). But since a modem type
- was set after the "set host" command was given, Kermit assumes it is a
- Telnet dialout connection and so sends the modem's hangup sequence is
- sent to the Telnet host. To avoid this, close the network connection
- explicitly before opening the serial one:
-
- set host name
- close
- set modem type name
- set port name
-
-2.3. TELNET and RLOGIN
-
- For additional background, please also read the [407]TELNET.TXT file,
- also available on the Web in [408]HTML format.
-
- Cautions:
-
- * If making a Telnet connection with C-Kermit takes a very long time,
- like over a minute, whereas the system Telnet program makes the
- same connection immediately, try including the /NOWAIT switch:
- C-Kermit> telnet /nowait hostname
-
- See [409]TELNET.TXT or [410]TELNET.HTM for details. If it also
- takes a very long time to make a Telnet connection with system
- Telnet, then the delay is most likely caused by reverse DNS lookups
- when your host is not properly registered in DNS.
- * When supplying numeric IP addresses to C-Kermit or to any other
- application (regular Telnet, Rlogin, etc), do not include leading
- 0's in any fields unless you intend for those fields to be
- interpreted as octal (or hex) numbers. The description of the
- Internet address interpreter (the sockets library inet_addr()
- routine) includes these words:
-
- All numbers supplied as "parts" in a "." notation may be decimal,
- octal, or hexadecimal, as specified in the C language (that is, a
- leading 0x or 0X implies hexadecimal; otherwise, a leading 0 implies
- octal; otherwise, the number is interpreted as decimal).
- To illustrate, 128.59.39.2 and 128.059.039.002 are not the same
- host! Even though most of the fields contain non-octal digits.
- Using system Telnet (not Kermit):
- $ telnet 128.059.039.002
- Trying 128.49.33.2 ...
-
- Of course the same thing happens with Kermit because it uses (as it
- must) the same system service for resolving network addresses that
- Telnet, FTP, and all other TCP/IP applications use.
- * The RLOGIN section on page 123 does not make it clear that you can
- use the SET TELNET TERMINAL-TYPE command to govern the terminal
- type that is reported by C-Kermit to the RLOGIN server.
- * Note that the SET TCP commands described on pages 122-123 might be
- absent; some platforms that support TCP/IP do not support these
- particular controls.
-
- New commands:
-
- TELOPT { AO, AYT, BREAK, CANCEL, EC, EL, EOF, EOR, GA, IP, DMARK,
- DO, DONT, NOP, SB, SE, SUSP, WILL, WONT }
- This command was available previously, but supported only DO,
- DONT, WILL, and WONT. Now it lets you send all the Telnet
- protocol commands. Note that certain commands do not require a
- response, and therefore can be used as nondestructive "probes"
- to see if the Telnet session is still open; e.g.:
-
- set host xyzcorp.com
- ...
- telopt nop
- if fail stop 1 Connection lost
-
- SET TCP ADDRESS [ ip-address ]
- Specifies the IP address of the computer that C-Kermit is
- running on. Normally this is not necessary. The exception would
- be if your machine has multiple network adapters (physical or
- virtual) with a different address for each adapter AND you want
- C-Kermit to use a specific address when making outgoing
- connections or accepting incoming connections.
-
- SET TCP DNS-SERVICE-RECORDS { ON, OFF }
- Tells C-Kermit whether to try to use DNS SRV records to
- determine the host and port number upon which to find an
- advertised service. For example, if a host wants regular Telnet
- connections redirected to some port other than 23, this feature
- allows C-Kermit to ask the host which port it should use. Since
- not all domain servers are set up to answer such requests, this
- feature is OFF by default.
-
- SET TCP REVERSE-DNS-LOOKUP { ON, OFF, AUTO }
- Tells Kermit whether to perform a reverse DNS lookup on TCP/IP
- connections. This allows Kermit to determine the actual hostname
- of the host it is connected to, which is useful for connections
- to host pools, and is required for Kerberos connections to host
- pools and for incoming connections. If the other host does not
- have a DNS entry, the reverse lookup could take a long time
- (minutes) to fail, but the connection will still be made. Turn
- this option OFF for speedier connections if you do not need to
- know exactly which host you are connected to and you are not
- using Kerberos. AUTO, the default, means the lookup is done on
- hostnames, but not on numeric IP addresses.
-
- SET TELNET WAIT-FOR-NEGOTIATIONS { ON, OFF }
- Each Telnet option must be fully negotiated either On or Off
- before the session can continue. This is especially true with
- options that require sub-negotiations such as Authentication,
- Encryption, and Kermit; for proper support of these options
- Kermit must wait for the negotiations to complete. Of course,
- Kermit has no way of knowing whether a reply is delayed or not
- coming at all, and so will wait a minute or more for required
- replies before continuing the session. If you know that Kermit's
- Telnet partner will not be sending the required replies, you can
- set this option of OFF to avoid the long timeouts. Or you can
- instruct Kermit to REFUSE specific options with the SET TELOPT
- command.
-
- SET TELOPT [ { /CLIENT, /SERVER } ] option
- { ACCEPTED, REFUSED, REQUESTED, REQUIRED }
- [ { ACCEPTED, REFUSED, REQUESTED, REQUIRED } ]
- SET TELOPT lets you specify policy requirements for Kermit's
- handling of Telnet option negotiations. Setting an option is
- REQUIRED causes Kermit to offer the option to the peer and
- disconnect if the option is refused. REQUESTED causes Kermit to
- offer an option to the peer. ACCEPTED results in no offer but
- Kermit will attempt to negotiate the option if it is requested.
- REFUSED instructs Kermit to refuse the option if it is requested
- by the peer.
-
- Some options are negotiated in two directions and accept
- separate policies for each direction; the first keyword applies
- to Kermit itself, the second applies to Kermit's Telnet partner;
- if the second keyword is omitted, an appropriate
- (option-specific) default is applied. You can also include a
- /CLIENT or /SERVER switch to indicate whether the given policies
- apply when Kermit is the Telnet client or the Telnet server; if
- no switch is given, the command applies to the client.
-
- Note that some of Kermit's Telnet partners fail to refuse
- options that they do not recognize and instead do not respond at
- all. In this case it is possible to use SET TELOPT to instruct
- Kermit to REFUSE the option before connecting to the problem
- host, thus skipping the problematic negotiation.
-
- Use SHOW TELOPT to view current Telnet Option negotiation
- settings. SHOW TELNET displays current Telnet settings.
-
-2.3.0. Bug Fixes
-
- If "set host nonexistent-host" was given (and it properly failed),
- followed by certain commands like SEND, the original line and modem
- type were not restored and C-Kermit thought that it still had a network
- hostname; fixed in 7.0.
-
-2.3.1. Telnet Binary Mode Bug Adjustments
-
- SET TELNET BUG BINARY-ME-MEANS-U-TOO { ON, OFF } was added to edit 192
- after the book was printed. Also SET TELNET BUG BINARY-U-MEANS-ME-TOO.
- The default for both is OFF. ON should be used when communicating with
- a Telnet partner (client or server) that mistakenly believes that
- telling C-Kermit to enter Telnet binary mode also means that it, too,
- is in binary mode, contrary to the Telnet specification, which says
- that binary mode must be negotiated in each direction separately.
-
-2.3.2. VMS UCX Telnet Port Bug Adjustment
-
- A new command, SET TCP UCX-PORT-BUG, was added for VMS versions with
- UCX (DEC TCP/IP), applying only to early versions of UCX, like 2.2 or
- earlier. If you try to use VMS C-Kermit to make a Telnet connection
- using a port name (like "telnet", which is used by default), the
- underlying UCX getservbyname() function might return the service number
- with its bytes swapped and the connection will fail. If "telnet
- hostname 23" works, then your version of UCX has this bug and you can
- put "set tcp ucx-port-bug on" in your CKERMIT.INI file to get around
- it.
-
-2.3.3. Telnet New Environment Option
-
- The TELNET NEW-ENVIRONMENT option ([411]RFC 1572) is supported as 7.0.
- This option allows the C-Kermit Telnet client to send certain
- well-known variables to the Telnet server, including USER, PRINTER,
- DISPLAY, and several others. This feature is enabled by default in
- Windows and OS/2, disabled by default elsewhere. The command to enable
- and disable it is:
-
- SET TELNET ENVIRONMENT { ON, OFF }
-
- When ON, and you Telnet to another computer, you might (or might not)
- notice that the "login:" or "Username:" prompt does not appear --
- that's because your username was sent ahead, in which case the remote
- system might prompt you only for your password (similar to Rlogin). Use
- "set telnet environment off" to defeat this feature, particularly in
- scripts where the dialog must be predictable. You can also use this
- command to specify or override specific well-known environment variable
- values:
-
- SET TELNET ENVIRONMENT { ACCT,DISPLAY,JOB,PRINTER,SYSTEMTYPE,USER } [ text ]
-
-2.3.4. Telnet Location Option
-
- The TELNET LOCATION option ([412]RFC 779) is supported in 7.0. This
- option allows the C-Kermit Telnet client to send a location string to
- the server if the server indicates its willingness to accept one. If an
- environment variable named LOCATION exists at the time C-Kermit starts,
- its value is used as the location string. If you want to change it,
- use:
-
- SET TELNET LOCATION text
-
- If you omit the text from this command, the Telnet location feature is
- disabled.
-
- SET TELNET ENVIRONMENT DISPLAY is used to set the DISPLAY variable that
- is sent to the host, as well as the XDISPLAY location.
-
-2.3.5. Connecting to Raw TCP Sockets
-
- The SET HOST and TELNET commands now accept an optional switch,
- /RAW-SOCKET, at the end, only if you first give a host and a port.
- Example:
-
- set host xyzcorp.com 23 /raw-socket
- set host 128.49.39.2:2000 /raw-socket
- telnet xyzcorp.com 3000 /raw
-
- Without this switch, C-Kermit behaves as a Telnet client when (a) the
- port is 23 or 1649, or (b) the port is not 513 and the server sent what
- appeared to be Telnet negotiations -- that is, messages starting with
- 0xFF (IAC). With this switch, Kermit should treat all incoming bytes as
- raw data, and will not engage in any Telnet negotiations or NVT CRLF
- manipulations. This allows transparent operation through (e.g.) raw TCP
- ports on Cisco terminal servers, through the 'modemd' modem server,
- etc.
-
-2.3.6. Incoming TCP Connections
-
- Accomplished via SET HOST * port, were introduced in C-Kermit 6.0, but
- for UNIX only. In Version 7.0, they are also available for VMS.
-
-2.4. The EIGHTBIT Command
-
- EIGHTBIT is simply a shorthand for: SET PARITY NONE, SET TERMINAL
- BYTESIZE 8, SET COMMAND BYTESIZE 8; that is, a way to set up an 8-bit
- clean connection in a single command.
-
-2.5. The Services Directory
-
- Chapter 7 of [413]Using C-Kermit does not mention the ULOGIN macro,
- which is used by our sample services directory, CKERMIT.KND. Unlike
- UNIXLOGIN, VMSLOGIN, etc, this one is for use with systems that require
- a user ID but no password. Therefore it doesn't prompt for a password
- or wait for a password prompt from the remote service.
-
- In version 7.0, the CALL macro was changed to not execute a SET MODEM
- TYPE command if the given modem type was the same as the current one;
- otherwise the new SET MODEM TYPE command would overwrite any
- customizations that the user had made to the modem settings. Ditto for
- SET LINE / SET PORT and SET SPEED.
-
-2.6. Closing Connections
-
- Until version 7.0, there was never an obvious and general way to close
- a connection. If a serial connection was open, it could be closed by
- "set line" or "set port" (giving no device name); if a network
- connection was open, it could be closed by "set host" (no host name).
-
- In version 7.0, a new command closes the connection in an obvious and
- straightforward way, no matter what the connection type:
-
- CLOSE [ CONNECTION ]
-
- The CLOSE command was already present, and required an operand such as
- DEBUG-LOG, WRITE-FILE, etc, and so could never be given by itself. The
- new CONNECTION operand is now the default operand for CLOSE, so CLOSE
- by itself closes the connection, if one is open, just as you would
- expect, especially if you are a Telnet or Ftp user.
-
- Also see the description of the new SET CLOSE-ON-DISCONNECT command in
- [414]Section 2.10.
-
-2.7. Using C-Kermit with External Communication Programs
-
- C-Kermit 7.0 includes a new ability to create and conduct sessions
- through other communications programs. Two methods are available:
-
- 1. Pty (pseudoterminal): The external program is run on a
- "pseudoterminal", which is controlled by Kermit. This method works
- with practically any external program, but it is not portable. At
- this writing, it works only on some (not all) UNIX versions, and
- not on any non-UNIX platforms.
- 2. Pipe: The external program's standard input and output are
- redirected through a "pipe" controlled by Kermit. This method is
- relatively portable -- it should work across all UNIX versions, and
- it also works in Windows and OS/2 -- but it is effective only when
- the external program actually uses standard i/o (and many don't).
-
- The two methods are started differently but are used the same way
- thereafter.
-
- The purpose of this feature is to let you use C-Kermit services like
- file transfer, character-set translation, scripting, automatic dialing,
- etc, on connections that Kermit can't otherwise make itself.
-
- This feature is the opposite of the REDIRECT feature, in which C-Kermit
- makes the connection, and redirects an external (local) command or
- program over this connection. In a pty or pipe connection, C-Kermit
- runs and controls a local command or program, which makes the
- connection. (The same method can be used to simply to control a local
- program without making a connection; see [415]Section 2.8.)
-
- To find out if your version of Kermit includes PTY support, type "show
- features" and look for NETPTY in the alphabetical list of options. For
- pipes, look for NETCMD.
-
- The commands are:
-
- SET NETWORK TYPE PTY or SET NETWORK TYPE PIPE
- SET HOST command
- where command is any interactive command. If the command does
- not use standard i/o, you must use SET NETWORK TYPE PTY.
-
- Notes:
-
- * COMMAND is an invisible synonym for PIPE.
- * The command and its arguments are case-sensitive in UNIX.
-
- The SET NETWORK TYPE, SET HOST sequence sets the given network type for
- all subsequent SET HOST commands until another SET NETWORK TYPE command
- is given to change it.
-
- You can also use the new /NETWORK-TYPE:PTY or /NETWORK-TYPE:PIPE (or
- simply /PIPE or /PTY) switches on the SET HOST command itself:
-
- SET HOST /NETWORK-TYPE:PIPE command ; These two are the same
- SET HOST /PIPE command
-
- SET HOST /NETWORK-TYPE:PTY command ; Ditto
- SET HOST /PTY command
-
- These are like SET NETWORK TYPE followed by SET HOST, except they apply
- only to the connection being made and do not change the global network
- type setting (see [416]Section 1.5 about the difference between
- switches and SET commands).
-
- Include any command-line options with the command that might be needed,
- as in this example where C-Kermit uses another copy of itself as the
- communications program:
-
- SET HOST /PIPE /CONNECT kermit -YQJ xyzcorp.com
-
- IMPORTANT: In Unix, wildcards and redirectors are interpreted by the
- shell. If you want to run a program with (say) SET HOST /PTY with
- its i/o redirected or with wildcard file arguments, you will need to
- invoke the shell too. Example:
-
-SET HOST /PTY {sh -c "crypt < foo.x"}
-SET HOST /PTY {sh -c "grep somestring *.txt"}
-
- As usual, if you include the /CONNECT switch, SET HOST enters CONNECT
- mode immediately upon successful execution of the given command.
- Therefore new commands are available as a shorthand for SET HOST
- /CONNECT /PTY and /PIPE:
-
- PTY [ command ]
- PIPE [ command ]
- The PTY and PIPE commands work like the TELNET and RLOGIN
- commands: they set up the connection (in this case, using the
- given command) and then enter CONNECT mode automatically (if the
- PIPE or PTY command is given without a command, it continues the
- current session if one is active; otherwise it gives an error
- message).
-
- The PIPE command is named after the mechanism by which C-Kermit
- communicates with the command: UNIX pipes. C-Kermit's i/o is "piped"
- through the given command. Here is a typical example:
-
- PIPE rlogin -8 xyzcorp.com
-
- This is equivalent to:
-
- SET HOST /PIPE rlogin -8 xyzcorp.com
- CONNECT
-
- and to:
-
- SET HOST /PIPE /CONNECT rlogin -8 xyzcorp.com
-
- IMPORTANT:
- If you are writing a script, do not use the PIPE, PTY, TELNET,
- or RLOGIN command unless you really want C-Kermit to enter
- CONNECT mode at that point. Normally SET HOST is used in scripts
- to allow the login and other dialogs to be controlled by the
- script itself, rather than by an actively participating human at
- the keyboard.
-
- Throughput of pty and pipe connections is limited by the performance of
- the chosen command or program and by the interprocess communication
- (IPC) method used and/or buffering capacity of the pipe or pty, which
- in turn depends on the underlying operating system.
-
- In one trial (on SunOS 4.1.3), we observed file transfer rates over an
- rlogin connection proceeding at 200Kcps for downloads, but only 10Kcps
- for uploads on the same connection with the same settings (similar
- disparities were noted in HP-UX). Examination of the logs revealed that
- a write to the pipe could take as long as 5 seconds, whereas reads were
- practically instantaneous. On the other hand, using Telnet as the
- external program rather than rlogin, downloads and uploads were better
- matched at about 177K each.
-
- Most external communication programs, like C-Kermit itself, have escape
- characters or sequences. Normally these begin with (or consist entirely
- of) a control character. You must be sure that this control character
- is not "unprefixed" when uploading files, otherwise the external
- program will "escape back" to its prompt, or close the connection, or
- take some other unwanted action. When in CONNECT mode, observe the
- program's normal interaction rules. Of course C-Kermit's own escape
- character (normally Ctrl-\) is active too, unless you have taken some
- action to disable it.
-
- On PTY connections, the underlying PTY driver is not guaranteed to be
- transparent to control characters -- for example, it might expand tabs,
- translate carriage returns, generate signals if it sees an interrupt
- character, and so on. Similar things might happen on a PIPE connection.
- For this reason, if you plan to transfer files over a PTY or PIPE
- connection, tell the file sender to:
-
- SET PREFIXING ALL
- This causes all control characters to be prefixed and
- transmitted as printable ASCII characters.
-
- If the external connection program is not 8-bit clean, you should also:
-
- SET PARITY SPACE
- This causes 8-bit data to be encoded in 7 bits using single
- and/or locking shifts.
-
- And if it does not make a reliable connection (such as those made by
- Telnet, Rlogin, Ssh, etc), you should:
-
- SET STREAMING OFF
- This forces C-Kermit to treat the connection as unreliable and
- to engage in its normal ACK/NAK protocol for error detection and
- correction, rather than "streaming" its packets, as it normally
- does on a network connection ([417]Section 4.20).
-
- In some cases, buffer sizes might be restricted, so you might also need
- to reduce the Kermit packet length to fit; this is a trial-and-error
- affair. For example, if transfers always fail with 4000-byte packets,
- try 2000. If that fails too, try 1000, and so on. The commands are:
-
- SET RECEIVE PACKET-LENGTH number
- This tells the file receiver to tell the file sender the longest
- packet length it can accept.
-
- SET SEND PACKET-LENGTH number
- This tells the file sender not to send packets longer than the
- given length, even if the receiver says longer ones are OK. Of
- course, if the receiver's length is shorter, the shorter length
- is used.
-
- If none of this seems to help, try falling back to the bare minimum,
- lowest-common-denominator protocol settings:
-
- ROBUST
- No sliding windows, no streaming, no control-character
- unprefixing, packet length 90.
-
- And then work your way back up by trial and error to get greater
- throughput.
-
- Note that when starting a PIPE connection, and the connection program
- (such as telnet or rlogin) prints some greeting or information messages
- before starting the connection, these are quite likely to be printed
- with a stairstep effect (linefeed without carriage return). This is
- because the program is not connected with the UNIX terminal driver;
- there's not much Kermit can do about it. Once the connection is made,
- everything should go back to normal. This shouldn't happen on a PTY
- connection because a PTY is, indeed, a terminal.
-
- On a similar note, some connection programs (like Solaris 2.5 rlogin)
- might print lots of error messages like "ioctl TIOCGETP: invalid
- argument" when used through a pipe. They are annoying but usually
- harmless. If you want to avoid these messages, and your shell allows
- redirection of stderr, you can redirect stderr in your pipe command, as
- in this example where the user's shell is bash:
-
- PIPE rlogin xyzcorp.com 2> /dev/null
-
- Or use PTY rather than PIPE, since PTY is available on Solaris.
-
-2.7.0. C-Kermit over tn3270 and tn5250
-
- Now you can make a connection from C-Kermit "directly" to an IBM
- mainframe and transfer files with it, assuming it has Kermit-370
- installed. Because tn3270 is neither 8-bit clean nor transparent to
- control characters, you must give these commands:
-
- SET PREFIXING ALL ; Prefix all control characters
- SET PARITY SPACE ; Telnet connections are usually not 8-bit clean
-
- and then:
-
- SET HOST /PTY /CONNECT tn3270 abccorp.com
-
- or simply:
-
- pty tn3270 abccorp.com
-
- SET HOST /PIPE does not work in this case, at least not for file
- transfer. File transfer does work, however, with SET HOST /PTY,
- provided you use the default packet length of 90 bytes; anything longer
- seems to kill the session.
-
- You can also make connections to IBM AS/400 computers if you have a
- tn5250 program installed:
-
- pty tn5250 hostname
-
- In this case, however, file transfer is probably not in the cards since
- nobody has ever succeeded in writing a Kermit program for the AS/400.
- Hint:
-
- define tn3270 {
- check pty
- if fail end 1 Sorry - no PTY support...
- pty tn3270 \%*
- }
-
- Similarly for tn5250. Note that CHECK PTY and CHECK PIPE can be used in
- macros and scripts to test whether PTY or PIPE support is available.
-
-2.7.1. C-Kermit over Telnet
-
- Although C-Kermit includes its own Telnet implementation, you might
- need to use an external Telnet program to make certain connections;
- perhaps because it has access or security features not available in
- C-Kermit itself. As noted above, the only precautions necessary are
- usually:
-
- SET PREFIXING ALL ; Prefix all control characters
- SET PARITY SPACE ; Telnet connections might not be 8-bit clean
-
- and then:
-
- SET HOST /PTY (or /PIPE) /CONNECT telnet abccorp.com
-
- or, equivalently:
-
- PTY (or PIPE) telnet abccorp.com
-
-2.7.2. C-Kermit over Rlogin
-
- C-Kermit includes its own Rlogin client, but this can normally be used
- only if you are root, since the rlogin TCP port is privileged. But ptys
- and pipes let you make rlogin connections with C-Kermit through your
- computer's external rlogin program, which is normally installed as a
- privileged program:
-
- SET PREFIXING ALL
-
- and then:
-
- SET HOST /PTY (or /PIPE) /CONNECT rlogin -8 abccorp.com
-
- or, equivalently:
-
- PTY (or PIPE) rlogin -8 abccorp.com
-
- The "-8" option to rlogin enables transmission of 8-bit data. If this
- is not available, then include SET PARITY SPACE if you intend to
- transfer files.
-
- Note that the normal escape sequence for rlogin is Carriage Return
- followed by Tilde (~), but only when the tilde is followed by certain
- other characters; the exact behavior depends on your rlogin client, so
- read its documentation.
-
-2.7.3. C-Kermit over Serial Communication Programs
-
- Ptys and pipes also let you use programs that make serial connections,
- such as cu or tip. For example, C-Kermit can be used through cu to make
- connections that otherwise might not be allowed, e.g. because C-Kermit
- is not installed with the required write permissions to the dialout
- device and the UUCP lockfile directory.
-
- Suppose your UUCP Devices file contains an entry for a serial device
- tty04 to be used for direct connections, but this device is protected
- against you (and Kermit when you run it). In this case you can:
-
- SET CONTROL PREFIX ALL
- PTY (or PIPE) cu -l tty04
-
- (Similarly for dialout devices, except then you also need to include
- the phone number in the "cu" command.)
-
- As with other communication programs, watch out for cu's escape
- sequence, which is the same as the rlogin program's: Carriage Return
- followed by Tilde (followed by another character to specify an action,
- like "." for closing the connection and exiting from cu).
-
-2.7.4. C-Kermit over Secure Network Clients
-
- DISCLAIMER: There are laws in the USA and other countries regarding
- use, import, and/or export of encryption and/or decryption or other
- forms of security software, algorithms, technology, and intellectual
- property. The Kermit Project attempts to follow all known statutes,
- and neither intends nor suggests that Kermit software can or should
- be used in any way, in any location, that circumvents any
- regulations, laws, treaties, covenants, or other legitimate canons
- or instruments of law, international relations, trade, ethics, or
- propriety.
-
- For secure connections or connections through firewalls, C-Kermit 7.0
- can be a Kerberos, SRP, and/or SOCKS client when built with the
- appropriate options and libraries. But other application-level security
- acronyms and methods -- SSH, SSL, SRP, TLS -- pop up at an alarming
- rate and are (a) impossible to keep up with, (b) usually mutually
- incompatible, and (c) have restrictions on export or redistribution and
- so cannot be included in C-Kermit itself.
-
- However, if you have a secure text-based Telnet (or other) client that
- employs one of these security methods, you can use C-Kermit "through"
- it via a pty or pipe.
-
-2.7.4.1. SSH
-
- C-Kermit does not and can not incorporate SSH due to licensing, patent,
- and USA export law restrictions.
-
- The UNIX SSH client does not use standard input/output, and therefore
- can be used only by Kermit's PTY interface, if one is present. The
- cautions about file transfer, etc, are the same as for Rlogin. Example:
-
- SET PREFIXING ALL
- PTY ssh XYZCORP.COM
-
- Or, for a scripted session:
-
- SET PREFIXING ALL
- SET HOST /PTY ssh XYZCORP.COM
-
- Hint:
-
- define ssh {
- check pty
- if fail end 1 Sorry - no PTY support...
- pty ssh \%*
- }
-
-2.7.4.2. SSL
-
- Secure Sockets Layer (SSL) is another TCP/IP security overlay, this one
- designed by and for Netscape. An SSL Telnet client is available for
- UNIX from the University of Queensland. More info at:
-
- [418]http://www.psy.uq.oz.au/~ftp/Crypto/
-
- Interoperability with C-Kermit is unknown. C-Kermit also includes its
- own built-in SSL/TLS support, but it is not exportable; [419]CLICK HERE
- file for details.
-
-2.7.4.3. SRP
-
- SRP(TM) is Stanford University's Secure Remote Password protocol. An
- SRP Telnet client is available from Stanford:
-
- [420]http://srp.stanford.edu/srp/
-
- Stanford's SRP Telnet client for UNIX has been tested on SunOS and
- works fine with C-Kermit, as described in [421]Section 2.7.1, e.g.
-
- SET PREFIX ALL
- PTY (or PIPE) srp-telnet xenon.stanford.edu
-
- C-Kermit itself can be built as an SRP Telnet client on systems that
- have libsrp.a installed; the C-Kermit support code, however, may not be
- exported outside the USA or Canada.
-
-2.7.4.4. SOCKS
-
- C-Kermit can be built as a SOCKS-aware client on systems that have a
- SOCKS library. See section 8.1.1 of the [422]ckccfg.txt file.
-
- C-Kermit 7.0 can also be run over SOCKSified Telnet or rlogin clients
- with SET NETWORK TYPE COMMAND. Suppose the Telnet program on your
- system is SOCKS enabled but C-Kermit is not. Make Kermit connections
- like this:
-
- SET PREFIX ALL
- PTY (or PIPE) telnet zzz.com
-
-2.7.4.5. Kerberos
-
- UNIX C-Kermit can be built with MIT Kerberos IV or V authentication and
- encryption. Instructions are available in a [423]separate document.
- Additional modules are required that can not be exported from the USA
- to any country except Canada, by US law.
-
- If you have Kerberos installed but you don't have a Kerberized version
- of C-Kermit, you can use ktelnet as C-Kermit's external communications
- program to make secure connections without giving up C-Kermit's
- services:
-
- SET PREFIX ALL
- PTY (or PIPE) ktelnet cia.gov
-
-2.8. Scripting Local Programs
-
- If your version of Kermit has PTY support built in, then any text-based
- program can be invoked with SET HOST /PTY or equivalent command and
- controlled using the normal sequence of OUTPUT, INPUT, IF SUCCESS
- commands (this is the same service that is provided by the 'expect'
- program, but controlled by the Kermit script language rather than Tcl).
-
- When PTY service is not available, then any program that uses standard
- input and output can be invoked with SET HOST /PIPE.
-
- Here's an example in which we start an external Kermit program, wait
- for its prompt, give it a VERSION command, and then extract the numeric
- version number from its response:
-
- set host /pty kermit -Y
- if fail stop 1 {Can't start external command}
- input 10 C-Kermit>
- if fail stop 1 {No C-Kermit> prompt}
- output version\13
- input 10 {Numeric: }
- if fail stop 1 {No match for "Numeric:"}
- clear input
- input 10 \10
- echo VERSION = "\fsubstr(\v(input),1,6)"
- output exit\13
-
- This technique could be used to control any other interactive program,
- even those that do screen formatting (like Emacs or Vi), if you can
- figure out the sequence of events. If your Kermit program doesn't have
- PTY support, then the commands are restricted to those using standard
- i/o, including certain shells, interactive text-mode "hardcopy" editors
- like ex, and so on.
-
- If you are using the PTY interface, you should be aware that it runs
- the given program or command directly on the pty, without any
- intervening shell to interpret metacharacters, redirectors, etc. If you
- need this sort of thing, include the appropriate shell invocation as
- part of your command; for example:
-
- pty echo *
-
- just echoes "*"; whereas:
-
- pty ksh -c "echo *"
-
- echoes all the filenames that ksh finds matching "*".
-
- Similarly for redirection:
-
- set host /pty ksh -c "cat > foo" ; Note: use shell quoting rules here
- set transmit eof \4
- transmit bar
-
- And for that matter, for built-in shell commands:
-
- set host /pty ksh -c "for i in *; do echo $i; done"
-
- The PIPE interface, on the other hand, invokes the shell automatically,
- so:
-
- pipe echo *
-
- prints filenames, not "*".
-
-2.9. X.25 Networking
-
- X.25 networking is documented in [424]Using C-Kermit, 2nd Edition. When
- the book was published, X.25 was available only in SunOS, Solaris, and
- Stratus VOS. Unlike TCP/IP, X.25 APIs are not standardized; each
- vendor's X.25 libraries and services (if they have them at all) are
- unique.
-
- This section describes new additions.
-
-2.9.1. IBM AIXLink/X.25 Network Provider Interface for AIX
-
- Support for X.25 was added via IBM's Network Provider Interface (NPI),
- AIXLink/X.25 1.1, to the AIX 4.x version of C-Kermit 7.0.
- Unfortunately, AIXLink/X.25 is a rather bare-bones facility, lacking in
- particular any form of PAD support (X.3, X.28, X.29). Thus, the AIX
- version of C-Kermit, when built to include X.25 networking, has neither
- a PAD command, nor a SET PAD command. The same is true for the
- underlying AIX system: no PAD support. Thus it is not possible to have
- an interactive shell session over an X.25 connection into an AIX system
- (as far as we know), even from X.25-capable Kermit versions (such as
- Solaris or VOS) that do include PAD support.
-
- Thus the X.25 capabilities in AIX C-Kermit are limited to peer-to-peer
- connections, e.g. from a C-Kermit client to a C-Kermit server. Unlike
- the Solaris, SunOS, and VOS versions, the AIX version can accept
- incoming X.25 connections:
-
- set network type x.25
- if fail stop 1 Sorry - no X.25 support
- ; Put any desired DISABLE or ENABLE or SET commands here.
- set host /server *
- if fail stop 1 X.25 "set host *" failed
-
- And then access it from the client as follows:
-
- set network type x.25
- if fail stop 1 Sorry - no X.25 support
- set host xxxxxxx ; Specify the X.25/X.121 address
- if fail stop 1 Can't open connection
-
- And at this point the client can use the full range of client commands:
- SEND, GET, REMOTE xxx, FINISH, BYE.
-
- The AIX version also adds two new variables:
-
- \v(x25local_nua)
- The local X.25 address.
-
- \v(x25remote_nua)
- The X.25 address of the host on the other end of the connection.
-
- C-Kermit's AIX X.25 client has not been tested against anything other
- than a C-Kermit X.25 server on AIX. It is not known if it will
- interoperate with C-Kermit servers on Solaris, SunOS, or VOS.
-
- To make an X.25 connection from AIX C-Kermit, you must:
-
- set x25 call-user-data xxxx
-
- where xxxx can be any even-length string of hexadecimal digits, e.g.
- 123ABC.
-
-2.9.2. HP-UX X.25
-
- Although C-Kermit presently does not include built-in support for HP-UX
- X.25, it can still be used to make X.25 connections as follows: start
- Kermit and tell it to:
-
- set prefixing all
- set parity space
- pty padem address
-
- This should work in HP-UX 9.00 and later (see [425]Section 2.7). If you
- have an earlier HP-UX version, or the PTY interface doesn't work or
- isn't available, try:
-
- set prefixing all
- set parity space
- pipe padem address
-
- Failing that, use Kermit to telnet to localhost and then after logging
- back in, start padem as you would normally do to connect over X.25.
-
-2.10. Additional Serial Port Controls
-
- C-Kermit 7.0 adds the following commands for greater control over
- serial ports. These commands are available only in C-Kermit versions
- whose underlying operating systems provide the corresponding services
- (such as POSIX and UNIX System V), and even then their successful
- operation depends on the capabilities of the specific device and
- driver.
-
- SET DISCONNECT { ON, OFF }
- On a SET LINE or SET PORT connection with SET CARRIER ON or
- AUTO, if the carrier signal drops during the connection,
- indicating that the connection has been lost, and C-Kermit
- notices it, this setting governs what happens next. With SET
- DISCONNECT OFF, which is consistent with previous behavior, and
- therefore the default, C-Kermit continues to keep the device
- open and allocated. With SET DISCONNECT ON, C-Kermit
- automatically closes and releases the device when it senses a
- carrier on-to-off transition, thus allowing others to use it.
- However, it remains the default device for i/o (DIAL, REDIAL,
- INPUT, SEND, CONNECT, etc), so if a subsequent i/o command is
- given, the device is reopened if it is still available. When it
- has been automatically closed in this manner, SHOW
- COMMUNICATIONS puts "(closed)" after its name, and in UNIX, the
- lockfile disappears -- both from SHOW COMM and from the lockfile
- directory itself. Synonym: SET CLOSE-ON-DISCONNECT.
-
- SET EXIT ON-DISCONNECT { ON, OFF }
- Like DISCONNECT, but makes the program exit if a connection
- drops.
-
- Note that SET CLOSE-ON-DISCONNECT and SET EXIT ON-DISCONNECT apply only
- to connections that drop; they do not apply to connections that can't
- be made in the first place. For example, they have no effect when a SET
- LINE, SET HOST, TELNET, or DIAL command fails.
-
- HANGUP
- If [CLOSE-ON-]DISCONNECT is ON, and the HANGUP command is given
- on a serial device, and the carrier signal is no longer present
- after the HANGUP command, the device is closed and released.
-
- SET PARITY HARDWARE { EVEN, ODD }
- Unlike SET PARITY { EVEN, ODD, MARK, SPACE }, which selects 7
- data bits plus the indicated kind of parity (to be done in
- software by Kermit itself), SET PARITY HARDWARE selects 8 data
- bits plus even or odd parity, to be done by the underlying
- hardware, operating system, or device driver. This command is
- effective only with a SET LINE or SET PORT device. That is, it
- has no effect in remote mode, nor on network connections. There
- is presently no method for selecting 8 data bits plus mark or
- space parity. If hardware parity is in effect, the variable
- \v(hwparity) is set to "even" or "odd". Note: some platforms
- might also support settings of SPACE, MARK, or NONE.
-
- SET STOP-BITS { 1, 2 }
- This tells the number of 1-bits to insert after an outbound
- character's data and parity bits, to separate it from the next
- character. Normally 1. Choosing 2 stop bits should do no harm,
- but will slow down serial transmission by approximately 10
- percent. Historically, 2 stop bits were used with Teletypes (at
- 110 bps or below) for print-head recovery time. There is
- presently no method for choosing any number of stop bits besides
- 1 and 2.
-
- SET SERIAL [ dps ]
- dps stands for Data-bits, Parity, Stop-bits. This is the
- notation familiar to many people for serial port configuration:
- 7E1, 8N1, 7O2, etc. The data bits number also becomes the
- TERMINAL BYTESIZE setting. The second character is E for Even, O
- for Odd, M for Mark, S for Space, or N for None. The list of
- available options depends on the capabilities of the specific
- platform. If dps is omitted, 8N1 is used. Type "set serial ?"
- for a list of available choices. Examples:
-
- SET SERIAL 7E1
- Equivalent to SET PARITY EVEN, SET STOP-BITS 1, SET TERM
- BYTE 7.
-
- SET SERIAL 8N1
- Equivalent to SET PARITY NONE, SET STOP-BITS 1, SET TERM
- BYTE 8.
-
- SET SERIAL 7E2
- Equivalent to SET PARITY EVEN and SET STOP-BITS 2, SET
- TERM BYTE 7.
-
- SET SERIAL 8E2
- Same as SET PARITY HARDWARE EVEN, SET STOP-BITS 2, SET
- TERM BYTE 8.
-
- SET SERIAL
- Same as SET PARITY NONE and SET STOP-BITS 1, SET TERM BYTE
- 8.
-
- Notes:
-
- * The SET SERIAL xx2 options are available only in Kermit versions
- where the SET PARITY HARDWARE command is also available. (SHOW
- FEATURES includes "HWPARITY" in its options list.)
- * The SET SERIAL 7xx and 8N1 options affect the software parity
- setting, even for network connections.
- * As noted in the manual, selecting 8 data bits does not give you
- 8-bit terminal sessions in CONNECT mode unless you also SET
- TERMINAL BYTESIZE 8. The default terminal bytesize remains 7, to
- protect against the situation where the remote host is generating
- parity but you don't know about it. If the terminal bytesize was 8
- by default and you CONNECTed to such a host, you would see only
- garbage on your screen.
- * If you do not give a SET STOP-BITS or SET SET SERIAL command,
- C-Kermit does not attempt to set the device's stop bits; instead,
- it uses whatever setting the device uses when not given explicit
- instructions about stop bits.
-
- SHOW COMMUNICATIONS displays the current settings. Stop bits and
- hardware parity are shown only for SET PORT / SET LINE (serial)
- devices, since they do not apply to network connections or to remote
- mode. STOP-BITS is shown as "(default)" if you have not given an
- explicit SET STOP-BITS or SET SERIAL command.
-
- The \v(serial) variable shows the SET SERIAL setting (8N1, 7E1, etc).
-
-2.11. Getting Access to the Dialout Device
-
- This section is for UNIX only; note the special words about QNX at
- the end. Also see [426]Section 2.0 for SET LINE switches,
- particularly the /SHARE switch for VMS only.
-
- C-Kermit does its best to obey the UUCP lockfile conventions of each
- platform (machine, operating system, OS version) where it runs, if that
- platform uses UUCP.
-
- But simply obeying the conventions is often not good enough, due to the
- increasing likelihood that a particular serial device might have more
- than one name (e.g. /dev/tty00 and /dev/term/00 are the same device in
- Unixware 7; /dev/cua and /dev/cufa are the same device in NeXTSTEP),
- plus the increasingly widespread use of symlinks for device names, such
- as /dev/modem.
-
- C-Kermit 7.0 goes to greater lengths than previous versions to
- successfully interlock with other communications program (and other
- instances of Kermit itself); for example, by:
-
- * Creation of dual lockfiles whenever a symlink is used; one for the
- link name and one for the real name.
- * Creation of dual lockfiles in HP-UX according to HP rules.
- * Creation of dual uppercase/lowercase lockfile names in SCO
- UNIX/ODT/OSR5.
- * The use of ttylock() in versions of AIX where it works.
- * The use, wherever possible, of lockfile names based on
- inode/major/minor device number rather than device name.
-
- See the [427]ckuins.txt and [428]ckubwr.txt files for details.
-
- QNX is almost unique among UNIX varieties in having no UUCP programs
- nor UUCP-oriented dialout-device locking conventions. QNX does,
- however, allow a program to get the device open count. This can not be
- a reliable form of locking unless all applications do it (and they
- don't), so by default, Kermit uses this information only for printing a
- warning message such as:
-
- C-Kermit>set line /dev/ser1
- WARNING - "/dev/ser1" looks busy...
-
- However, if you want to use it as a lock, you can do so with:
-
- SET QNX-PORT-LOCK { ON, OFF }
-
- QNX-PORT-LOCK is OFF by default; if you set in ON, C-Kermit fails to
- open any dialout device when its open count indicates that another
- process has it open. SHOW COMM (in QNX only) displays the setting, and
- if you have a port open, it also shows the current open count (with
- C-Kermit's own access always counting as 1).
-
-2.12. The Connection Log
-
- C-Kermit 7.0 adds the ability to log connections, so you can see where
- you've been and have a record of calls you've made. A connection is
- defined as any communications session that is begun by SET LINE, SET
- PORT, DIAL, SET HOST, TELNET, or RLOGIN. Connections are not logged
- unless you request it; the command is:
-
- LOG CX [ filename [ { NEW, APPEND } ] ]
- Enables logging of connections in the given file. If the
- trailing { NEW, APPEND } keyword is omitted, the file is opened
- for appending; i.e. new records are written to the end. If NEW
- is specified, a new file is created; if a file of the same name
- already existed, it is overwritten. If the filename is omitted,
- CX.LOG in your home (login) directory is used (note: uppercase).
- To accept all defaults, just use "log connections" (or "l c" for
- short). Synonym: LOG CONNECTIONS.
-
- CLOSE CX-LOG
- This closes the connection log if it was open. (Note, the CLOSE
- CONNECTION command closes the connection itself).
-
- SHOW CX
- This shows your current connection, if any, including the
- elapsed time (since you opened it). Synonym: SHOW CONNECTION.
-
- \v(cx_time)
- This variable shows the elapsed time of your current connection,
- or if there is no current connection, of your most recent
- connection, of if there have been no connections, 0.
-
- The connection contains one line per connection, of the form:
-
- yyyymmdd hh:mm:ss username pid p=v [ p=v [ ... ] ]
-
- where the timestamp (in columns 1-18) shows when the connection was
- made; username is the login identity of the person who made the
- connection; pid is Kermit's process ID when it made the connection. The
- p's are parameters that depend on the type of connection, and the v's
- are their values:
-
- T = Connection Type (TCP, SERIAL, DIAL, DECNET, etc).
- H = The name of the Host from which the connection was made.
- N = Destination phone Number or Network host name or address.
- D = Serial connections only: Device name.
- O = Dialed calls only: Originating country code & area code if known.
- E = Elapsed time in hh:mm:ss format (or hhh:mm:ss, etc).
-
- If you always want to keep a connection log, simply add:
-
- log connections
-
- to your C-Kermit customization file. Note, however, that if you make a
- lot of connections, your CX.LOG will grow and grow. You can handle this
- by adding a "logrotate" procedure like the following to your
- customization file, before the "log connections" command:
-
- define LOGROTATE { ; Define LOGROTATE macro
- local \%i \%m \%d \%n \%f MAX
- def MAX 4 ; How many months to keep
- if not def \%1 - ; No argument given
- end 1 \%0: No filename given
- if not = 1 \ffiles(\%1) - ; Exactly 1 file must match
- end 1 \%0: \%1 - File not found
- .\%d := \fsubstr(\fdate(\%1),1,6) ; Arg OK - get file year & month
- if = \%d - ; Compare file year & month
- \fsubstr(\v(ndate),1,6) - ; with current year & month
- end 0 ; Same year & month - done
- rename \%1 \%1.\%d ; Different - rename file
- .\%n := \ffiles(\%1.*) ; How many old files
- if < \%n \m(MAX) end 0 ; Not enough to rotate
- .\%m := \%1.999999 ; Initial compare string
- for \%i 1 \%n 1 { ; Loop thru old logs
- .\%f := \fnextfile() ; Get next file name
- if llt \%f \%m .\%m := \%f ; If this one older remember it
- }
- delete \%m ; Delete the oldest one
- }
- log connections ; Now open the (possibly new) log
- logrotate \v(home)CX.LOG ; Run the LOGROTATE macro
-
- As you can see, this compares the yyyymm portion of the modification
- date (\fdate()) of the given file (\%1) with the current yyyymm. If
- they differ, the current file has the yyyymm suffix (from its most
- recent modification date) appended to its name. Then we search through
- all other such files, find the oldest one, and delete it. Thus the
- current log, plus the logs from the most recent four months, are kept.
- This is all done automatically every time you start C-Kermit.
-
- On multiuser systems, it is possible to keep a single, shared,
- system-wide connection log, but this is not recommended since (a) it
- requires you keep a publicly write-accessible logfile (a glaring target
- for mischief), and (b) it would require each user to log to that file
- and not disable logging. A better method for logging connections, in
- UNIX at least, is syslogging (see [429]ckuins.txt Section 15 and
- [430]Section 4.2 of the [431]IKSD Administration Guide for details).
-
-2.13. Automatic Connection-Specific Flow Control Selection
-
- Beginning in C-Kermit 7.0, the appropriate flow-control method for each
- connection type is kept in a table, for example:
-
- Remote: NONE
- Modem: RTS/CTS
- Direct-Serial: NONE
- TCPIP: NONE
-
- The size of the table and values for each connection type can vary from
- platform to platform. Type "set flow ?" for a list of available
- flow-control types.
-
- The table is used to automatically select the appropriate kind of flow
- control whenever you make a connection. You can display the table with:
-
- SHOW FLOW-CONTROL
-
- The defaults are as follows:
-
- Remote:
- NONE or XON/XOFF. This is because C-Kermit is not allowed to
- find out what type of connection the incoming user has (*). No
- kind of flow control will work on every kind of connection,
- including (unexpectedly) KEEP, which we would have liked to use,
- but not turning off flow control at the remote end during file
- transfer on TCP/IP connections is fatal to the transfer (except
- in VMS and HP-UX, where it must be set to Xon/Xoff!) Therefore
- if you are dialing in to a serial port on a server (UNIX or VMS)
- where C-Kermit is running, you will need to tell C-Kermit to
- "set flow keep" before transferring files (assuming the modem
- and port are configured correctly by the system administrator;
- otherwise you'll need to give a specific kind of flow control,
- e.g. "set flow xon/xoff"), so in this case C-Kermit will not
- disable flow control, as it must do when you are coming via
- Telnet (directly or through a terminal server, except on VMS and
- HP-UX).
-
- Modem:
- This applies when you dial out with a modem. In this case, the
- MODEM FLOW-CONTROL setting takes affect after the SET FLOW
- setting, so it can pick the most appropriate flow control for
- the combination of the particular modem and the
- computer/port/driver that is dialing.
-
- Direct-Serial:
- The default here is NONE because C-Kermit has no way of knowing
- what kind of flow control, if any, is or can be done by the
- device at the other end of the connection. RTS/CTS would be a
- bad choice here, because if the CTS signal is not asserted, the
- connection will hang. And since direct connections are often
- made with 3-wire cables, there is a good chance the CTS signal
- will not be received.
-
- TCPIP:
- NONE, since TCP and IP provide their own flow control
- transparently to the application, except in VMS, where Xon/Xoff
- is the default due to the requirements of the VMS TCP/IP
- products.
-
- Other networks:
- NONE, since networks should provide their flow control
- transparently to the application.
-
- (*) This is possibly the worst feature of UNIX, VMS, and other
- platforms where C-Kermit runs. If C-Kermit was able to ask the
- operating system what kind of connection it had to the user, it could
- set up many things for you automatically.
-
- You can modify the default-flow-control table with:
-
- SET FLOW-CONTROL /xxx { NONE, KEEP, RTS/CTS, XON/XOFF, ... }
-
- where "xxx" is the connection type, e.g.
-
- SET FLOW /REMOTE NONE
- SET FLOW /DIRECT RTS/CTS
-
- If you leave out the switch, SET FLOW works as before, choosing the
- flow control method to be used on the current connection:
-
- SET FLOW XON/XOFF
-
- Thus, whenever you make a connection with SET PORT, SET LINE, DIAL, SET
- HOST, TELNET, RLOGIN, etc, an appropriate form of flow control is
- selected automatically. You can override the automatic selection with a
- subsequent SET FLOW command, such as SET FLOW NONE (no switch
- included).
-
- The flow control is changed automatically too when you give a SET MODEM
- TYPE command. For example, suppose your operating system (say Linux)
- supports hardware flow control (RTS/CTS). Now suppose you give the
- following commands:
-
- set line /dev/ttyS2 ; Automatically sets flow to NONE
- set modem type usr ; Automatically sets flow to RTS/CTS
- set modem type rolm ; Doesn't support RTS/CTS so now flow is XON/XOFF
-
- IMPORTANT: This new feature tends to make the order of SET LINE/HOST
- and SET FLOW commands matter, where it didn't before. For example, in
- VMS:
-
- SET FLOW KEEP
- SET LINE TTA0:
-
- the SET LINE undoes the SET FLOW KEEP command; the sequence now must
- be:
-
- SET FLOW /DIRECT KEEP
- SET LINE TTA0:
-
- or:
-
- SET LINE TTA0:
- SET FLOW KEEP
-
-2.14. Trapping Connection Establishment and Loss
-
- If you define a macro called ON_OPEN, it is executed any time that a
- SET LINE, SET PORT, SET HOST, TELNET, RLOGIN or similar command
- succeeds in opening a connection. The argument is the host or device
- name (as shown by SHOW COMMUNICATIONS, and the same as \v(line)). This
- macro can be used for all sorts of things, like automatically setting
- connection- or host-specific parameters when the connection is opened.
- Example:
-
- def ON_OPEN {
- switch \%1 {
- :abccorp.com, set reliable off, break
- :xyzcorp.com, set receive packet-length 1000, break
- etc etc...
- }
- }
-
- If you define a macro called ON_CLOSE, it will be executed any time
- that a SET LINE, SET PORT, SET HOST, TELNET, RLOGIN or any other kind
- of connection that C-Kermit has made is closed, either by the remote or
- by a local CLOSE, HANGUP, or EXIT command or other local action, such
- as when a new connection is opened before an old one was explicitly
- closed.
-
- As soon as C-Kermit notices the connection has been closed, the
- ON_CLOSE macro is invoked at (a) the top of the command parsing loop,
- or (b) when a connection is closed implicitly by a command such as SET
- LINE that closes any open connection prior to making a new connection,
- or (c) when C-Kermit closes an open connection in the act of exiting.
-
- The ON_CLOSE macro was inspired by the neverending quest to unite
- Kermit and SSH. In this case using the "tunnel" mechanism:
-
- def TUNNEL { ; \%1 = host to tunnel to
- local \%p
- if not def \%1 stop 1
- assign tunnelhost \%1 ; Make global copy
- undef on_close
- set macro error off
- close connection ; Ignore any error
- open !read tunnel start \%1
- read \%p ; Get port number
- if fail stop 1 Tunnel failure: \%1
- close read
- if fail stop 1 Tunnel failure: \%1 ; See [432]Section 4.2.8.1
- assign on_close { ; Set up close handler
- echo Closing tunnel: \m(tunnelhost)
- !tunnel stop \m(tunnelhost)
- undef on_close
- }
- set host localhost:\%p /telnet
- if success end 0
- undef on_close
- stop 1 Connection failure: \%1
- }
-
- In this case, when the connection stops, we also need to shut down the
- tunnel, even if it is at a later time after TUNNEL has finished
- executing. This way we can escape back, reconnect, transfer files, and
- so on until the connection is broken by logging out from the remote, or
- by explicitly closing it, or by EXITing from C-Kermit, at which time
- the tunnel is shut down.
-
- When the connection is closed, no matter how, the ON_CLOSE macro
- executes and then undefines (destroys) itself, since we don't want to
- be closing tunnels in the future when we close subsequent connections.
-
- Other such tricks can be imagined, including ending ON_CLOSE with a
- STOP command to force the command stack to be peeled all the way back
- to the top, for example in a deeply nested script that depends on the
- connection being open:
-
- def on_close { stop 1 CONNECTION LOST }
-
- When C-Kermit invokes the ON_CLOSE macro, it supplies one argument
- (\%1): the reason the connection was closed as a number, one of the
- following:
-
- 2 - Fatal failure to negotiate a required item on a network connection.
- 1 - Closed by C-Kermit command.
- 0 - All others (normally closed by remote).
-
- which may be used for any purpose; for example, to add a comment to the
- connection log:
-
- def on_close {
- local \%m
- if not open cx end 0
- switch \%1 {
- :0, .\%m = Closed by remote, break
- :1, .\%m = Closed by me, break
- :2, .\%m = Network protocol negotiation failure, break
- }
- if def \%m writeln cx {# \%m}
- }
-
-2.15. Contacting Web Servers with the HTTP Command
-
- C-Kermit 7.0 (at this writing, the UNIX version only) supports direct
- contact and interaction with Web servers via HTTP 1.0 protocol. To make
- a connection, use Kermit's normal method for making a TCP/IP
- connection, but specify the HTTP port:
-
- SET HOST host http [ switches ]
-
- where host is the IP hostname or address, and http is the name of the
- TCP port for the Web server. Relevant switches include:
-
- /RAW
- Treat the connection as a transparent binary pipe. This switch
- may be required if a port other than 'http' is used.
-
- /SSL
- Make an secure private connection with SSL (only if SSL support
- is included in your version of Kermit). In this case the port
- name might need to be https rather than http, e.g. "set host
- secureserver.xyzcorp.com https /ssl".
-
- /TLS
- Make an secure private connection with TLS (only if TLS support
- is included in your version of Kermit). In this case the port
- name would be https rather than http.
-
- Then you can issue an HTTP command. In most cases, the server closes
- the connection when the command is complete. Example:
-
- SET HOST www.columbia.edu http
- IF FAIL EXIT 1 Can't contact server
- HTTP GET kermit/index.html
-
- At this point the connection is closed, since that's how HTTP 1.0
- works. If you want to perform additional operations, you must establish
- a new connection with another SET HOST command.
-
- The HTTP command acts as a client to the Web server, except instead of
- displaying the results like a Web browser would, it stores them. Any
- HTTP command can (but need not) include any or all of the following
- switches:
-
- /AGENT:user-agent
- Identifies the client to the server; "C-Kermit" or "Kermit-95"
- by default.
-
- /HEADER:header-line
- Used for specifying any optional headers. A list of headers is
- provided using braces for grouping:
-
- /HEADER:{{tag:value}{tag:value}...}
-
- For a listing of valid tag value and value formats see [433]RFC
- 1945: Hypertext Transfer Protocol -- HTTP/1.0. A maximum of
- eight headers may be specified.
-
- /USER:name
- In case a page requires a username for access.
-
- /PASSWORD:password
- In case a page requires a password for access.
-
- /ARRAY:arrayname
- Tells Kermit to store the response headers in the given array,
- one line per element. The array need not be declared in advance.
- Example:
-
- C-Kermit? http /array:c get kermit/index.html
- C-Kermit? show array c
- Dimension = 9
- 1. Date: Fri, 26 Nov 1999 23:12:22 GMT
- 2. Server: Apache/1.3.4 (Unix)
- 3. Last-Modified: Mon, 06 Sep 1999 22:35:58 GMT
- 4. ETag: "bc049-f72-37d441ce"
- 5. Accept-Ranges: bytes
- 6. Content-Length: 3954
- 7. Connection: close
- 8. Content-Type: text/html
-
- As you can see, the header lines are like MIME e-mail header lines:
- identifier, colon, value. The /ARRAY switch is the only method
- available to a script to process the server responses for a POST or PUT
- command.
-
- The HTTP commands are:
-
- HTTP [ switches ] GET remote-filename [ local-filename ]
- Retrieves the named file. If a local-filename is given, the file
- is stored locally under that name; otherwise it is stored with
- its own name.
-
- HTTP [ switches ] HEAD remote-filename local-filename
- Like GET except without actually getting the file; instead it
- gets only the headers, storing them into the given file, whose
- name must be given, one line per header item, as shown above in
- the /ARRAY: switch description.
-
- HTTP [ switches ] INDEX remote-directory [ local-filename ]
- Retrieves the file listing for the given server directory. NOTE:
- This command is not supported by most Web servers.
-
- HTTP [ switches ] POST [ /MIME-TYPE:type ] local-file remote-file
- Used to send a response as if it were sent from a form. The data
- to be posted must be read from a file.
-
- HTTP [ switches ] PUT [ /MIME-TYPE:type ] local-file remote-file
- Uploads a local file to a server file.
-
- HTTP [ switches ] DELETE remote-filename
- Instructs the server to delete the specified filename.
-
-3. TERMINAL CONNECTION
-
-3.1. CONNECT Command Switches
-
- The following switches (see [434]Section 1.5) were added to the CONNECT
- command in 7.0:
-
- /QUIETLY
- Don't print the "Connecting to..." or "Back at..." messages. CQ
- is an invisible command synonym for CONNECT /QUIETLY.
-
- /TRIGGER:string
- Specify a trigger or triggers ([435]Section 3.2) effective for
- this CONNECT command only, temporarily overriding any current
- SET TERMINAL TRIGGER values ([436]Section 3.2).
-
- Note: Other switches might also be available; type "connect ?" for a
- list, "help connect" for a description of each.
-
-3.2. Triggers
-
- Triggers were added for UNIX, VMS, AOS/VS, and K95 in C-Kermit 7.0.
-
- SET TERMINAL TRIGGER string
- Tells C-Kermit to look for the given string during all
- subsequent CONNECT sessions, and if seen, to return to command
- mode automatically, as if you had escaped back manually. If the
- string includes any spaces, you must enclose it in braces.
- Example:
-
- set terminal trigger {NO CARRIER}
-
- Comparisons are made after character-set translation.
-
- If a string is to include a literal brace character, precede it with a
- backslash:
-
- ; My modem always makes this noise when the connection is lost:
- set terminal trigger |||ppp\{\{\{\{UUUUUUU
-
- If you want Kermit to look for more than one string simultaneously, use
- the following syntax:
-
- set terminal trigger {{string1}{string2}...{stringn}}
-
- In this case, C-Kermit will return to command mode automatically if any
- of the given strings is encountered. Up to 8 strings may be specified.
-
- If the most recent return to command mode was caused by a trigger, the
- new variable, \v(trigger), shows the trigger value; otherwise
- \v(trigger) is empty.
-
- The SHOW TRIGGER command displays the SET TERMINAL TRIGGER values as
- well as the \v(trigger) value.
-
-3.3. Transparent Printing
-
- As noted in the manual, C-Kermit's CONNECT command on UNIX is not a
- terminal emulator, but rather a "semitransparent pipe" between the
- terminal or emulator you are using to access C-Kermit, and the remote
- host to which C-Kermit is connected. The "semitransparent" qualifier is
- because of character-set translation as well as several actions taken
- by the emulator in response to the characters or strings that pass
- through it, such as APCs, Kermit packets (autodownload), triggers, etc.
-
- The UNIX version of C-Kermit 7.0 adds another such action: Transparent
- printing, also called Controller printing (as distinct from Autoprint
- or line or screen print). It is intended mainly for use on UNIX
- workstation consoles (as opposed to remote logins), but with some care
- can also be used when accessing C-Kermit remotely.
-
- Transparent printing is related to APC by sharing C-Kermit's built-in
- ANSI escape-sequence parser to detect "printer on" and "printer off"
- sequences from the host. When the printer-on sequence is received, all
- subsequent arriving characters -- including NUL, control characters,
- and escape sequences -- are sent to the SET PRINTER device instead of
- to your screen until the printer-off sequence is received, or you
- escape back, whichever happens first. These bytes are not translated or
- modified or filtered in any way by Kermit (except for possibly
- stripping of the 8th bit, as noted below), but if filtering or
- translation is desired, this can be accomplished by your SET PRINTER
- selection (e.g. by choosing a pipeline of filters).
-
- By default, your SET PRINTER device is your default UNIX printer, but
- it can also be a file, a command, or the null device (which causes all
- printer material to be discarded). See [437]Using C-Kermit, 2nd Ed.,
- p.41 for details.
-
- Transparent printing is controlled by the command:
-
- SET TERMINAL PRINT { ON, OFF }
- When ON, transparent-print sequences are obeyed, and printing
- occurs on the system where C-Kermit is running. When OFF,
- transparent print sequences are ignored and passed through to
- your actual terminal or emulator, along with the data they
- enclose. OFF is the default, for compatibility with earlier
- C-Kermit releases. As noted in the manual, when the current SET
- PRINTER device is a file, transparent-print material is appended
- to it; the file is not overwritten.
-
- SET TERMINAL BYTESIZE { 7, 8 }
- SET PARITY { EVEN, ODD, MARK, SPACE, NONE }
- If the terminal bytesize is 7, or PARITY is not NONE, the 8th
- bit of each byte is stripped prior to printing.
-
- The transparent-print escape sequences are:
-
- <ESC>[5i
- Printer On. Send all subsequent incoming bytes to the printer
- without any kind of filtering, translation, or alteration. Note:
- <ESC> stands for ASCII character number 27 (decimal), Escape.
-
- <ESC>[4i
- Printer Off. Resume displaying incoming bytes on the screen.
-
- These are the same sequences used by DEC VT100 and higher terminals and
- other ANSI X3.64 and ISO 6429 compatible terminals. There is no
- provision for selecting other printer-control sequences.
-
- Restrictions:
-
- 1. You must SET TERM TRANSPARENT-PRINT ON before you can use this
- feature.
- 2. Only the 7-bit forms of the escape sequences are supported. The
- 8-bit CSI C1 control is not recognized.
- 3. Autoprint is not supported, since this requires a full-fledged
- terminal emulator with direct access to the screen.
- 4. The start-print and stop-print sequences pass through to the screen
- (there is no way to avoid this without causing unacceptable delays
- or deadlocks in CONNECT mode). Thus if your terminal or emulator
- also supports transparent printing via these same sequences, an
- empty file will be sent to its printer. Normally this has no
- effect.
-
- Point (4) is similar to the situation with autodownload and APC -- when
- you have several Kermit clients in a chain, you should take care that
- these features are enabled in only one of them.
-
- Example 1:
-
- set printer {|lpr -Plaser} ; Specify the printer (if not default).
- set term print on ; Enable transparent printing.
- set term byte 8 ; Enable 8-bit characters.
- connect ; Enter CONNECT mode.
-
- Example 2:
-
- set printer /home/users/olga/printer.log ; Send printer material to a file.
-
- Example 3:
-
- set printer {| grep -v ^Received | lpr} ; Filter out some lines
-
- Then use "pcprint" or "vtprint" commands on the host to initiate
- transparent print operations. See [438]Using C-Kermit, 2nd Ed., p.406
- for details.
-
- Here is a sample "pcprint" shell script for UNIX:
-
- #!/bin/sh
- echo -n '<ESC>[5i'
- if [ $# -eq 0 ]; then
- cat
- else
- cat $*
- fi
- echo -n '<FF><ESC>[4i'
- # (end)
-
- (Replace "<ESC>" by the actual ASCII Escape character and "<FF>" by the
- ASCII Formfeed character).
-
- If you always want transparent printing enabled, put "set term print
- on" in your C-Kermit customization file (~/.mykermrc in UNIX). The "set
- term bytesize" selection, however, is a property of each separate
- connection.
-
-3.4. Binary and Text Session Logs
-
- C-Kermit 7.0 corrects an oversight in earlier releases, in which binary
- session logs (SET SESSION-LOG BINARY) translated character sets and
- performed various formatting transformations (e.g. "newline mode")
- before writing characters to the session log. In C-Kermit 7.0,
- binary-mode session logging writes characters as they come in, before
- anything (other that parity-bit stripping) is done to them. Text-mode
- session logging records the characters after processing.
-
-4. FILE TRANSFER
-
- Every file is transferred either in text mode (which implies
- record-format and character-set translation) or binary mode (in which
- each byte is sent literally without any kind of conversion). The mode
- in which a file is transferred is controlled by (a) the default mode,
- in the absence of any other indications; (b) the SET FILE TYPE command;
- (c) various automatic mechanisms based on client/server negotiations,
- directory information or filename patterns, etc.
-
- The default FILE TYPE was changed from TEXT to BINARY in C-Kermit 7.0
- because:
-
- * Transferring a text file in binary mode does less damage than
- transferring a binary file in text mode.
- * Only binary-mode transfers can be recovered from the point of
- failure.
- * The automatic transfer-mode mechanisms switch to text mode on a
- per-file basis anyway, so only those files that are not covered by
- the automatic mechanisms are affected.
- * All file transfers on the Web are done in binary mode, so people
- are accustomed to it and expect it.
-
-4.0. BUG FIXES, MINOR CHANGES, AND CLARIFICATIONS
-
-4.0.0. Filenames with Spaces
-
- Filenames that contain spaces are a major nuisance to a program like
- Kermit, whose command language is line- and word-oriented, in which
- words are separated by spaces and a filename is assumed to be a "word".
- In general (unless noted otherwise in the description of a particular
- command), there is only one way to refer to such files in Kermit
- commands, and that is to enclose the name in braces:
-
- send {this file}
-
- Tells Kermit to send the file whose name is "this file" (two words, no
- quotes). Of course, various circumlocutions are also possible, such as:
-
- define \%a this file
- send \%a
-
- BUT, perhaps contrary to expectation, you can't use "\32" to represent
- the space:
-
- send this\32file
-
- does not work. Why? Because the Kermit parser, which must work on many
- operating systems including Windows, has no way of knowing what you
- mean by "this\32file". Do you mean a file whose name is "this file" in
- the current directory? Or do you mean a file whose name is "32file" in
- the "this" subdirectory of the current directory? Guessing won't do
- here; Kermit must behave consistently and deterministically in all
- cases on all platforms.
-
- Note that you can't use Esc or Tab within {...} for filename
- completion, or question mark to get a filename list. However, you can
- include wildcards; for example:
-
- send {* *}
-
- sends all files whose name contains a space.
-
- All things considered, it is best to avoid spaces in file and directory
- names if you can. Also see [439]Section 5.4 on this topic.
-
-4.0.1. Packet out of Window
-
- C-Kermit 6.0 could send packets "out of window" if the window size was
- greater than 1 and ACKs had arrived out of order. Fixed in 6.1.
-
-4.0.2. MOVE after ADD SEND-LIST
-
- ADD SEND-LIST followed by MOVE did not delete original files; fixed in
- 6.1. Carrier loss was not detected during transfer; in 7.0 C-Kermit
- checks for this (but results can not be guaranteed). In any case, the
- protocol will eventually time out if the connection is lost.
-
-4.0.3. GET and RECEIVE As-Names
-
- In 5A(190) through 6.0.192, the GET and RECEIVE as-name did not
- properly override the RECEIVE PATHNAMES setting. In 7.0 it does.
-
-4.0.4. New Brief Statistics Listing
-
- Version 7.0 adds a /BRIEF switch to the STATISTICS command, to display
- a short file-transfer statistics report. /BRIEF is now the default. Use
- /VERBOSE to see the full display, which is about 25 lines long.
-
-4.0.5. Improved FAST Command
-
- The preinstalled definition of the FAST macro did not take enough
- factors into account. Now it sets packet lengths and window sizes
- appropriate to the configuration. Furthermore, in IRIX only, it might
- restrict the SEND packet length to 4000, to work around a bug in the
- IRIX Telnet server, depending on the IRIX version (see [440]ckubwr.txt,
- IRIX section). To see the built-in definition of the FAST macro, type
- "show macro fast". To change it, simply define it to be whatever you
- want -- it's just a macro, like any other.
-
-4.0.6. The SET SEND BACKUP Command
-
- Version 7.0 adds SET SEND BACKUP { ON, OFF }. This tells whether backup
- files should be sent. Backup files are the ones created by Kermit (and
- EMACS, and possibly other applications) to preserve old copies of files
- when creating new ones with the same name. Kermit does this when
- receiving a file and its FILE COLLISION setting is BACKUP (or RENAME,
- in which case it the new file gets the backup name). On most platforms,
- the backup name is formed by adding:
-
- .~n~
-
- to the end of the filename, where "n" is a number. For example, if the
- original file is oofa.txt, a backup file might be called:
-
- oofa.txt.~1~
-
- (or oofa.txt.~2~, etc). If you SET SEND BACKUP OFF, this tells Kermit
- not to send files that have backup names. Normally, SET SEND BACKUP is
- ON (as shown by SHOW PROTOCOL), and backup files are sent if their
- names match the SEND file specification.
-
- Also see PURGE, SET FILE COLLISION, SEND /NOBACKUP, DIRECTORY
- /[NO]BACKUP.
-
-4.0.7. The SET { SEND, RECEIVE } VERSION-NUMBERS Command
-
- VMS Only. Normally when sending files, VMS C-Kermit strips the version
- number. For example, if the file is FOO.BAR;34, the name is sent as
- FOO.BAR (without the ";34"). If you want to keep version numbers on
- when sending files, use SET SEND VERSION-NUMBERS ON. The effect depends
- on the receiver.
-
- Normally when receiving files, and an incoming filename includes a
- VMS-style version number (such as FOO.BAR;34) VMS C-Kermit strips it
- before trying to create the new file; this way the new file receives
- the next highest version number in the customary manner for VMS. If you
- want version numbers on incoming filenames to be used in creating the
- new files, use SET RECEIVE VERSION-NUMBERS ON.
-
- Normally these commands would be effective only when VMS C-Kermit is
- exchanging files with a non-VMS Kermit program, since VMS-to-VMS
- transfers use labeled mode unless you have gone out of your way to
- defeat it.
-
- Example: You want to send all versions of all files in the current
- directory from a VMS C-Kermit client to a UNIX C-Kermit server. Use:
-
- set send version-numbers on
- send *.*;*
-
- The resulting Unix files will have VMS-style version numbers as part of
- their name, for example "foo.bar;1", "foo.bar;2", etc.
-
- Now suppose you want to send these files from Unix to another VMS
- system and preserve the version numbers. Again we have a Unix C-Kermit
- server and VMS C-Kermit client. Give these commands to the client:
-
- set receive version-numbers on
- get *
-
-4.0.8. The SET { SEND, RECEIVE } { MOVE-TO, RENAME-TO } Commands
-
- These commands are persistent global versions of the /MOVE-TO: and
- /RENAME-TO: switches of the SEND, GET, and RECEIVE commands. They
- should normally be used only when setting up a dedicated
- transaction-processing application, in which each file is to be moved
- or renamed immediately after, and only if, it is transferred
- successfully, so that (for example) an independent, concurrent process
- can notice when new files appear and process them immediately without
- having to guess whether they are complete.
-
-4.0.9. SET FILE INCOMPLETE AUTO
-
- SET FILE INCOMPLETE { KEEP, DISCARD }, which tells whether to keep or
- discard incompletely received files, has a new option, AUTO, which is
- also the default. It means KEEP the incomplete file if the transfer is
- in binary mode, otherwise DISCARD it. This reduces the chances that a
- subsequent recovery operation (RESEND, REGET, etc) could produce a
- corrupt file, since recovery works only for binary-mode transfers.
-
-4.1. FILE-TRANSFER FILENAME TEMPLATES
-
- File-transfer filename templates allow files to be renamed
- automatically by the file sender, the receiver, or both, during
- transfer of groups of files.
-
-4.1.1. Templates in the As-Name
-
- Prior to C-Kermit 6.1 and Kermit 95 1.1.12 the only options that could
- be used to affect the names of files being transferred were SET
- FILENAMES { LITERAL, CONVERTED } and SET { SEND, RECEIVE } PATHNAMES {
- ON, OFF }, plus the "as-name" feature of the SEND (MOVE, etc) and
- RECEIVE commands.
-
- Previously, the as-name could be used only for a single file. For
- example:
-
- SEND FOO BAR
-
- would send the file FOO under the name BAR, but:
-
- SEND *.TXT anything
-
- was not allowed, since it would give the same name to each file that
- was sent. When receiving:
-
- RECEIVE FOO
-
- would rename the first incoming file to FOO before storing it on the
- disk, but subsequent files would not be renamed to FOO, since this
- would result in overwriting the same file repeatedly. Instead, they
- were stored under the names they arrived with.
-
- Beginning in C-Kermit 6.1 and Kermit 95 1.1.12, it is possible to
- specify as-names in SEND, RECEIVE, and related commands even for file
- groups. This is accomplished by using replacement variables in the
- as-name, along with optional material such character-string functions
- and/or constant strings. An as-name containing replacement variables is
- called a filename template.
-
- The key to filename templates is the new variable:
-
- \v(filename)
-
- During file transfer it is replaced by the name of each file currently
- being transferred (after transfer, it is the name of the last file
- transferred).
-
- So, for example:
-
- send *.txt \v(filename).new
-
- sends each file with its own name, but with ".new" appended to it. Of
- course if the name already contains periods, this could confuse the
- file receiver, so you can also achieve fancier effects with
- constructions like:
-
- send *.txt \freplace(\v(filename),.,_).new
-
- which replaces all periods in the original filename by underscores, and
- then appends ".new" to the result. So, for example, oofa.txt would be
- sent as oofa_txt.new.
-
- Another new variable that is useful in this regard is \v(filenumber),
- which is the ordinal number of the current file in the file group, so
- you can also:
-
- send *.txt FILE\flpad(\v(filenum),2,0)
-
- resulting in a series of files called FILE00, FILE01, FILE02, etc. (At
- the end of the transfer, \v(filenum) tells the number of files that
- were transferred).
-
- If you specify a constant as-name when sending a file group:
-
- send *.txt thisnameonly
-
- Kermit complains and asks you to include replacement variables in the
- as-name. You should generally use \v(filename) or \v(filenumber) for
- this purpose, since other variables (with the possible exception of
- date/time related variables) do not change from one file to the next.
- But Kermit accepts any as-name at all that contains any kind of
- variables for file group, even if the variable will not change. So:
-
- send *.txt \%a
-
- is accepted, but all files are sent with the same name (the value of
- \%a, if it has one and it is constant). If the variable has no value at
- all, the files are sent under their own names.
-
- Of course, the value of \%a in the previous example need not be
- constant:
-
- define \%a FILE\flpad(\v(filenum),2,0)_at_\v(time)
- send *.txt \%a
-
- The RECEIVE command, when given without an as-name, behaves as always,
- storing all incoming files under the names they arrive with, subject to
- SET FILE NAME and SET RECEIVE PATHNAMES modifications ([441]Section
- 4.10).
-
- However, when an as-name is given in the RECEIVE command, it is applied
- to all incoming files rather than to just the first. If it does not
- contain replacement variables, then the current FILE COLLISION setting
- governs the result. For example:
-
- receive foo
-
- will result in incoming files named foo, foo.~1~, foo.~2~, and so on,
- with the default FILE COLLISION setting of BACKUP. If it does contain
- replacement variables, of course they are used.
-
- When receiving files, the \v(filename) variable refers to the name that
- was received in the incoming file-header packet, BEFORE any processing
- by SET FILE NAMES or SET RECEIVE PATHNAMES. Since the filenames in
- file-header packets are usually in uppercase, you would need to convert
- them explicitly if you want them in lowercase, e.g.:
-
- receive \flower(\v(filename)).new
-
-4.1.2. Templates on the Command Line
-
- On the command-line, use templates as shown above as the -a option
- argument, bearing in mind the propensity of UNIX and perhaps other
- shells to treat backslash as a shell escape character. So in UNIX (for
- example):
-
- kermit -s oofa.* -a x.\\v(filenum)
-
- By the way, this represents a change from 6.0 and earlier releases in
- which the as-name (-a argument or otherwise) was not evaluated by the
- command parser. Thus, for example, in VMS (where the shell does not
- care about backslashes), it was possible to:
-
- kermit -s oofa.txt -a c:\tmp\oofa.txt
-
- Now backslashes in the as-name must be quoted not only for the shell
- (if necessary) but also for Kermit itself:
-
- kermit -s oofa.txt -a c:\\tmp\\oofa.txt ; Kermit only
- kermit -s oofa.txt -a c:\\\\tmp\\\\oofa.txt ; Shell and Kermit
-
- You can also use the \fliteral() function for this:
-
- kermit -s oofa.txt -a \fliteral(c:\tmp\oofa.txt) ; Kermit only
- kermit -s oofa.txt -a \\fliteral(c:\\tmp\\oofa.txt) ; Shell and Kermit
-
-4.1.3. Post-Transfer Renaming
-
- Filename templates are now also useful in SET { SEND, RECEIVE }
- RENAME-TO and in the /RENAME-TO: switch, that can be given to the SEND,
- GET, or RECEIVE commands; this is similar to an as-name, but is
- effective on a per-file basis if and only if the file was transferred
- successfully.
-
- MOVE-TO and RENAME-TO address a requirement commonly stated for
- transaction processing and similar systems. Suppose, for example, a
- central system "X" accepts connections from multiple clients
- simultaneously; a process on X waits for a file to appear and then
- processes the file. This process must have a way of knowing when the
- file has been completely and successfully transferred before it starts
- to process it. This can be accomplished easily using C-Kermit's SET {
- SEND, RECEIVE } { MOVE-TO, RENAME-TO } command or /MOVE-TO: or
- /RENAME-TO: switches, described in [442]Sections 4.7.1 through
- [443]4.7.3.
-
- Here's an example for the client side, in which files to be sent are
- placed in a certain directory (/usr/olga/tosend in this example) by
- another process when they are ready to go. This might be in a hospital
- or big doctor's office, where medical insurance claims are entered at a
- number of workstations, and then deposited in the "tosend" directory,
- from which they are sent to a claims clearinghouse. We assume the
- connection is already made and a Kermit server is on the other end.
-
- local srcdir findir ; Declare local (automatic) variables
- assign srcdir /usr/olga/tosend ; Local source directory (files to send)
- assign findir /usr/olga/sent ; Where to move files after they are sent
- log transactions ; Keep a log of transfers
- cd \m(srcdir) ; Change to the source directory
- while true { ; Loop forever...
- send /move-to:\m(findir) * ; Send all files
- sleep 60 ; Sleep a minute
- } ; Go back and do it again
-
- Note how simple this is. Once each file is sent, it is moved so it
- won't be sent again (you could also use SEND /RENAME-TO: or even SEND
- /DELETE). If a transfer fails, the file is not moved and so we try
- again to send it next time around. If there are no files to send, the
- SEND command does nothing but a message is printed; you can avoid the
- message by checking first to see if any files are in the directory:
-
- while true { ; Loop forever...
- if > \ffiles(*) 0 - ; If there are any files
- send /move-to:\m(findir) * ; send them.
- sleep 60 ; Sleep a minute.
- } ; Go back and do it again.
-
- It's even simpler on the server side (here again we assume the
- connection is already in place):
-
- local rcvdir findir ; Declare local (automatic) variables
- assign rcvdir /usr/ivan/tmp ; Temporary receiving directory
- assign findir /usr/ivan/new ; Where to move files after reception
- log transactions ; Keep a log of transfers
- cd \m(rcvdir) ; Change to the source directory
- set receive move-to \m(findir) ; Declare move-to directory.
- server ; Enter server mode.
-
- A separate process (e.g. the medical claim-form decoder) can look for
- files appearing in the /usr/ivan/new directory and process them with
- every confidence that they have been completely received.
-
- Note that the use of MOVE-TO can result in moved files overwriting one
- another (the application would normally avoid this by assigning each
- transaction a unique, e.g. based on customer number and claim number).
- But if filename collisions are a possibility in your application,
- RENAME-TO might be a better choice; you can use any variables you like
- in the template to ensure uniqueness of the RENAME-TO filename; for
- example:
-
- SET RECEIVE RENAME-TO \v(filename)_\v(ndate)_\v(ntime)_\v(userid)_\v(pid)
-
-4.2. FILE-TRANSFER PIPES AND FILTERS
-
-4.2.1. INTRODUCTION
-
- Beginning in C-Kermit 6.1 and Kermit 95 1.1.12, it is possible to send
- from a command, or "pipe", as well as from a file, and to receive to a
- pipe or command. In a typical example, we might want to transfer an
- entire directory tree from one UNIX system to another (but without
- using the methods described in [444]Sections 4.3 , [445]4.10,
- [446]4.11, and [447]4.15). We could do this in multiple steps as
- follows:
-
- 1. Create a tar archive of the desired directory tree
- 2. Compress the tar archive
- 3. Transfer it in binary mode to the other computer
- 4. Decompress it
- 5. Extract the directory tree from the tar archive
-
- But this is inconvenient and it requires a temporary file, which might
- be larger than we have room for.
-
- The new pipe-transfer feature lets you do such things in a single step,
- and without intermediate files.
-
- Additional new features, also discussed here, let you specify pre- and
- post- processing filters for outbound and incoming files, and give you
- a way to insert the output from shell or system commands into C-Kermit
- commands.
-
- The file-transfer related features are available only with Kermit
- protocol, not with any external protocols, nor with K95's built-in
- XYZMODEM protocols (because XYZMODEM recovers from transmission errors
- by rewinding the source file, and you can't rewind a pipe).
-
- This section begins by discussing the simple and straightforward use of
- these features in UNIX, in which pipes and input/output redirection are
- a fundamental component and therefore "just work", and then goes on to
- discuss their operation in Windows and OS/2, where matters are much
- more complicated.
-
-4.2.1.1. TERMINOLOGY
-
- Standard Input
- This is a precise technical term denoting the normal source of
- input for a command or program, which is the keyboard of your
- terminal by default, but which can be redirected to a file or
- pipe.
-
- Stdin
- Abbreviation for Standard Input.
-
- Standard Output
- A precise technical term denoting the normal destination for
- output from a command or program, which is your terminal screen
- by default, but which can be redirected to a file.
-
- Stdout
- Abbreviation for Standard Output.
-
- Stdio
- Abbreviation for Standard Input / Standard Output.
-
- I/O
- Abbreviation for Input / Output.
-
- Shell
- Text-based system command processor, such as the UNIX shell, DOS
- COMMAND.COM, etc.
-
- Pipe
- A mechanism by which the standard output of one program is sent
- to the standard input of another.
-
- Pipeline
- A series of programs connected by pipes.
-
-4.2.1.2. NOTATION
-
- In command descriptions, "command" is replaced by a shell or system
- command or pipeline. The command names specified in these commands are
- interpreted by your shell, just as if you were typing them at the shell
- prompt, and so if they are in your PATH, they will be found in the
- expected manner. Therefore you don't have to specify complete pathnames
- for commands that are programs (but it shouldn't hurt if you do).
-
- The normal notation for I/O redirection is as follows:
-
- < Read Stdin from the given file.
- > Send Stdout to the given file.
- | Send Stdout from the command on the left to the command on the right.
-
- Examples:
-
- sort < foo > bar
- Sorts the lines in file "foo" and writes the results to file
- "bar"
-
- grep -c "some text" *.txt | grep -v ":0" | sort | pr -3 | lpr
- This is a command pipeline composed of 5 commands:
-
- grep -c "some text" *.txt
- Looks in all files whose names end with ".txt" for the string
- "some text" and writes to Stdout the names of each file followed
- by a colon and the number of occurrences in each.
-
- grep -v ":0"
- Prints to Stdout the lines from Stdin that do NOT contain the
- string ":0", in this case, it removes the names of files that do
- not contain "some text".
-
- sort
- Sorts the lines from Stdin alphabetically to Stdout.
-
- pr -3
- Arranges the lines from Stdin in three columns.
-
- lpr
- Prints its Stdin on the default printer.
-
- Note that the Kermit features described here work only with commands
- that use Stdio. If you attempt to use them with commands whose input
- and output can not be redirected, Kermit will most likely get stuck.
- Kermit has no way of telling how an external command works, nor what
- the syntax of the shell is, so it's up to you to make sure you use
- these features only with redirectable commands.
-
- The quoting rules of your shell apply to the command. Thus in UNIX,
- where C-Kermit tries to use your preferred shell for running commands,
- shell "metacharacters" within commands must be escaped if they are to
- be taken literally, using the methods normal for your shell. For
- example, the UNIX tr (translate) command must have its arguments in
- quotes:
-
- tr "[a-z]" "[A-Z]"
-
- otherwise the shell is likely to replace them by all filenames that
- match, which is probably not what you want. This is also true when
- using your shell directly, and has nothing to do with Kermit.
-
-4.2.1.3. SECURITY
-
- Some sites might not wish to allow access to system commands or
- external programs from within Kermit. Such access, including all the
- features described here, can be disabled in various ways:
-
- 1. When building from source code, include -DNOPUSH among the CFLAGS.
- 2. At runtime, give the NOPUSH command.
- 3. For server mode, give the DISABLE HOST command.
- 4. Implicit use of pipes can be disabled as described in [448]Section
- 4.2.4.
-
- Note: 3 and 4 are not necessary if you have done 1 or 2.
-
-4.2.2. Commands for Transferring from and to Pipes
-
- SEND /COMMAND sends data from a command or command pipeline, and
- RECEIVE /COMMENT writes data to a command or pipeline. The GET /COMMAND
- command asks a server to send material, and then writes the incoming
- material to a command or pipeline. These features, along with switches
- (like "/COMMAND", described in [449]Section 4.7) are new to C-Kermit
- 6.1. The following synonyms are also provided:
-
- CSEND = SEND /COMMAND
- CRECEIVE = RECEIVE /COMMAND
- CGET = GET /COMMAND
-
- None of these commands can be used if a SEND or RECEIVE FILTER
- (respectively, [450]Section 4.2.3) is in effect, or if a NOPUSH command
- ([451]Section 4.2.1.3) has been given, or if the current protocol is
- not Kermit.
-
-4.2.2.1. Sending from a Command
-
- SEND /COMMAND command [ as-name ]
- SEND /AS-NAME:as-name /COMMAND command
- CSEND command [ as-name ]
- These three forms are the same. They work like the SEND command,
- but instead of sending a file, it sends the standard output of
- the given command, either under the command's own name, or else
- with the given as-name. If the command contains spaces, it must
- be enclosed in braces. Braces should also be used for the
- as-name if it contains spaces. If braces are included around
- either the command or the as-name, they are removed after
- parsing but before use. As with SEND, the transfer is in text or
- binary mode according the current FILE TYPE setting, unless you
- override the global transfer mode by including a /TEXT or
- /BINARY switch. The command must require no input.
-
- When sending from a command or pipeline, C-Kermit has no way of knowing
- in advance how much data will be sent, and so it can not send the size
- to the other Kermit in the Attribute packet, and so the receiving
- Kermit has no way of displaying "percent done" or a progress bar
- (thermometer).
-
- Examples that make sense in text mode (illustrated by common UNIX
- commands):
-
- SEND /COMMAND finger
- CSEND finger
- sends the current "finger" listing (who's logged in) under the
- name "finger". The two forms "send /command" and "csend" are
- equivalent; we won't bother showing them both in the rest of the
- examples.
-
- SEND /COMMAND:{finger}
- CSEND {finger}
- Same as previous example (braces are removed from "{finger}").
-
- SEND /COMMAND:{ finger }
- CSEND { finger }
- Same as previous example, but note that the spaces are kept.
- This does not prevent the shell from running the "finger"
- program, but its output is sent under the name " finger " (with
- a leading and trailing space).
-
- SEND /COMMAND:finger /AS-NAME:userlist
- CSEND finger userlist
- sends the current finger listing under the name "userlist".
-
- SEND /COMMAND:{finger | sort -r} /AS-NAME:userlist
- CSEND {finger | sort -r} userlist
- sends the current finger listing, sorted in reverse order, under
- the name "userlist". The braces are needed to distinguish the
- command from the as-name.
-
- SEND /COMMAND:{finger | sort -r} /AS-NAME:{userlist}
- CSEND {finger | sort -r} {userlist}
- Same as previous example (braces are removed from "{userlist}").
-
- SEND /COMMAND:{finger | sort -r}
- /AS-NAME:{\freplace(\v(filename),\32,_)}
-
- CSEND {finger | sort -r} {\freplace(\v(filename),\32,_)}
- Like the previous example, but sends the output of the command
- under the name of the command, but with all spaces (\32)
- replaced by underscores, so the as-name is "finger_|_sort_-r".
-
- Examples that make sense in binary mode (three equivalent forms are
- shown):
-
- SEND /COMMAND /BINARY {tar cf - . | gzip -c} mydir.tar.gz
- SEND /COMMAND /BINARY /AS-NAME:mydir.tar.gz {tar cf - . | gzip -c}
- CSEND /BINARY {tar cf - . | gzip -c} mydir.tar.gz
- Makes a tar archive of the current directory, compresses it with
- the GNU gzip program, and sends it as "mydir.tar.gz". The other
- Kermit can, of course, just store it as a file, or it can use
- CRECEIVE to uncompress and dearchive it as part of the transfer
- process.
-
- When using a "pipeline" of commands in the command field, obviously,
- the first command must not require any input, and the last command
- should produce some output, and all intermediate commands should get
- some input and produce some output.
-
-4.2.2.2. Receiving to a Command
-
- RECEIVE /COMMAND command
- CRECEIVE command
- This is like RECEIVE, except incoming material is written to the
- standard input of the given command, in text or binary mode
- according to the normal rules for file reception. Be sure to
- include a redirector to a file (if the command normally writes
- to standard output), or the output of the command won't go
- anywhere. The command may contain spaces; braces are not needed,
- but they are removed if used.
-
- WARNING: C-Kermit has no way of knowing anything about the command, or
- even whether it is a command. Thus this command will always cause
- C-Kermit to enter protocol mode, as long as some text is specified in
- the command field. However, if the text does not correspond to a
- command, the transfer will eventually fail with a message such as
- "Error writing data" or "Failure to close file".
-
- Examples for text mode (in UNIX):
-
- RECEIVE /COMMAND sort -r > reverse.txt
- CRECEIVE sort -r > reverse.txt
- The text that is received is sorted in reverse order and stored
- in the file "reverse.txt". The two forms shown are equivalent.
-
- RECEIVE /COMMAND {sort -r > reverse.txt}
- CRECEIVE {sort -r > reverse.txt}
- The same as the previous example; if braces are included, they
- are simply removed.
-
- RECEIVE /COMMAND {sort -r > \flower(\v(filename)).reverse}
- CRECEIVE {sort -r > \flower(\v(filename)).reverse}
- Same but stores result under the incoming filename, lowercased,
- and with ".reverse" appended to it.
-
- RECEIVE /COMMAND sort
- CRECEIVE sort
- Does nothing useful, since the output of sort has nowhere to go.
-
- RECEIVE /COMMAND sort -r | pr -3 | lpr -Plaserjet
- CRECEIVE sort -r | pr -3 | lpr -Plaserjet
- The text that is received is sorted in reverse order, arranged
- into three columns, and sent to the "laserjet" printer.
-
- Examples for binary mode:
-
- RECEIVE /COMMAND:{gunzip -c | tar xf -}
- CRECEIVE {gunzip -c | tar xf -}
- Assuming the data that is received is a compressed tar archive,
- uncompresses the archive and passes it to tar for extraction. In
- this case the braces are needed because otherwise the final "-"
- would be taken as a command continuation character (see
- [452]Using C-Kermit, 2nd Edition, p.33).
-
- GET /COMMAND remote-file command
- GET /COMMAND /AS-NAME:command remote-file
- CGET remote-file command
- This command tells the Kermit client to send a GET request for
- the given remote file to a Kermit server. Unlike GET, however,
- the incoming material is written to a command, rather than to a
- file. If the remote-file or the command contain spaces, they
- must be enclosed in braces. The same cautions about the command
- apply as for CRECEIVE.
-
- Examples (for UNIX):
-
- GET /COMMAND oofa.txt sort -r > oofa.new
- GET /COMMAND {oofa.txt} {sort -r > oofa.new}
- CGET oofa.txt sort -r > oofa.new
- CGET {oofa.txt} {sort -r > oofa.new}
- These four are equivalent. Each of them requests the server to
- send its "oofa.txt" file, and as it arrives, it is sorted in
- reverse order and written to "oofa.new".
-
- GET /COMMAND {profile exec a} lpr
- GET /COMMAND {profile exec a} {lpr}
- GET /COMMAND /AS-NAME:lpr {profile exec a}
- GET /COMMAND /AS-NAME:{lpr} {profile exec a}
- GET /COMMAND /AS:lpr {profile exec a}
- CGET {profile exec a} lpr
- CGET {profile exec a} {lpr}
- Here the remote filename contains spaces so it MUST be enclosed
- in braces. As it arrives it is sent to the lpr program for
- printing. Braces are optional around "lpr" since it contains no
- spaces.
-
- GET /COMMAND *.txt {cat >> new.txt}
- GET /AS-NAME:{cat >> new.txt} /COMMAND *.txt
- CGET *.txt {cat >> new.txt}
- This gets all the ".txt" files from the server and concatenates
- them all into a single "new.txt" file on the client.
-
- GET /COMMAND *.txt {echo \v(filename)>>new.txt;cat>>new.txt}
- CGET *.txt {echo \v(filename)>>new.txt;cat>>new.txt}
- As above, but inserts each file's name before its contents.
-
-4.2.3. Using File-Transfer Filters
-
- The commands described in [453]Section 4.2.2 let you send the output of
- a command, or receive data into a command. But what if you want to
- specify preprocessing for files that you send, or postprocessing of
- files that you receive, even when multiple files are involved? For this
- you need a way to specify send and receive filters. The commands are
- SET SEND FILTER and SET RECEIVE FILTER; SHOW PROTOCOL displays the
- current settings.
-
-4.2.3.1. The SEND Filter
-
- SET SEND FILTER [ command ]
- This command specifies a command to be run on any file that you
- SEND (or MOVE, MSEND, etc). It also applies to files sent when
- in server mode, in response to GET commands, but not to the
- results of REMOTE commands like REMOTE DIRECTORY, REMOTE TYPE,
- REMOTE HOST, etc. The command may be, but need not be, enclosed
- in braces; if it is, the braces are stripped before use. The
- output of this command is sent, rather than the file itself. The
- current FILE TYPE setting (TEXT or BINARY) applies to the output
- of the command. The command must contain at least one instance
- of \v(filename), for which the name of the actual file is
- substituted. If the command is omitted, the send filter is
- removed and files are sent in the normal manner.
-
- The SET SEND FILTER sets up a "global" filter -- that is, one that
- applies to all subsequent file-sending commands until you change or
- remove it. You can also specify a "local" filter to be used in a
- specific file-sending command by using the /FILTER switch (see
- [454]Section 1.5); for example:
-
- SEND /FILTER:command [ other-switches ] filename
-
- Besides \v(filename), you can include any other script programming
- notation in the send filter: variable names, array references, calls to
- built-in string or other functions, and so on. These are evaluated
- during file transfer, NOT during parsing, and they are evaluated
- separately for each file.
-
- When the SEND or MOVE (SEND /DELETE) command is used with a send
- filter, the output from the filter is sent under the file's original
- name unless you specify an "as-name" or template. The Attribute packet
- (if any) contains the original file's attributes (size, creation date,
- etc). So (for example) if the filter changes the file's size, the
- progress thermometer might be wrong. (We can't send the size of the
- output from the filter, because it is not known until the transfer is
- finished.) If you prefer that the size not be sent, use "set attributes
- size off".
-
- You can not use send filters with RESEND (SEND /RECOVER) or PSEND (SEND
- /START).
-
- Examples for text mode:
-
- SET SEND FILTER sort -r \v(filename) ; Braces may be omitted
- SET SEND FILTER {sort -r \v(filename)} ; Braces may be included
- SEND *.txt
- This sends every file in the current directory whose name ends
- with ".txt" under its own name, but with its lines sorted in
- reverse order.
-
- SEND /FILTER:{sort -r \v(filename)} *.txt
- Same as above, but the filter applies only to this SEND command.
- Braces are required in this case.
-
- SET SEND FILTER {sort -r \v(filename)}
- SEND oofa.txt reverse.txt
- Sends the oofa.txt file with its lines sorted in reverse order
- under the name "reverse.txt".
-
- SET SEND FILTER {sort -r \v(filename)}
- SEND oofa.* \v(filename).reverse
- Sends all the oofa.* files with their lines sorted in reverse
- order; each file is sent under its own name but with ".reverse"
- appended to it.
-
- SET SEND FILTER {tr "[a-z]" "[A-Z]" < \v(filename)}
- SEND *.txt
- Sends all ".txt" files under their own names, but uppercasing
- their contents.
-
- Note that the SEND FILTER applies not only to files that are sent with
- SEND, MOVE, MSEND, etc, but also to files sent by the C-Kermit server
- in response to GET requests.
-
- Examples for binary mode:
-
- SET SEND FILTER {gzip -c \v(filename)}
- SEND /BINARY oofa.txt oofa.txt.gz
- Sends the oofa.txt file, compressed by gzip, as oofa.txt.gz.
-
- SEND /BINARY /FILTER:{gzip -c \v(filename)} oofa.txt oofa.txt.gz
- As above, but the filter applies only to this SEND command.
-
- SET SEND FILTER {gzip -c \v(filename)}
- SEND /BINARY oofa.* \fupper(\replace(\v(filename),.,_)).GZ
- Sends all the oofa.* files, compressed by gzip, each under its
- own name, but with the name uppercased, all periods within the
- name converted to underscores, and ".GZ" appended to it. So, for
- example, "oofa.txt" is sent as "OOFA_TXT.GZ".
-
- In the gzip examples, note that the amount of data that is sent is
- normally less than the original file size because gzip compresses the
- file. But Kermit sends the original file size ahead in the attribute
- packet anyway (unless you tell it not too). Thus the transfer will
- probably appear to terminate early, e.g. when the receiver's
- file-transfer display thermometer is only at 40%. If this annoys you,
- tell Kermit to "set attribute length off". On the other hand, you can
- use the final position of the thermometer as a measure of the
- effectiveness of compression.
-
-4.2.3.2. The RECEIVE Filter
-
- SET RECEIVE FILTER [ command ]
- This command specifies that the given command will be run on any
- file that is received before it is written to disk. The command
- may be, but need not be, enclosed in braces; if it is the braces
- are stripped before use. The following two commands are
- equivalent:
-
- SET RECEIVE FILTER sort -r > \v(filename)
- SET RECEIVE FILTER {sort -r > \v(filename)}
-
- The RECEIVE filter command may contain a "\v(filename)" sequence to be
- replaced by the incoming filename from the file header packet, but it
- is not required. However you must use it whenever your filter would
- normally write to Stdout, otherwise its output will be lost.
-
- The RECEIVE filter command may contain one or more "\v(filename)"
- sequence to be replaced by the incoming filename from the file header
- packet, but it is not required. However you must use it whenever your
- filter would normally write to Stdout, otherwise its output will be
- lost.
-
- RECEIVE /FILTER:command and GET /FILTER:command can also be used to
- specify a filter to be used for only one file-transfer operation.
-
- UNIX examples for text mode:
-
- SET RECEIVE FILTER lpr
- RECEIVE
- All the files that are received are sent to the default UNIX
- print spooler.
-
- RECEIVE /FILTER:lpr
- Same as above, except the lpr filter is used only with this
- RECEIVE command.
-
- RECEIVE lpr
- This is probably not what you want; it creates a file called
- lpr.
-
- SET RECEIVE FILTER {sort -r > \v(filename)}
- RECEIVE
- Stores each incoming file with its lines sorted in reverse
- order, under its own name.
-
- RECEIVE /FILTER:{sort -r > \v(filename)}
- As above, but the filter is used only for this RECEIVE command.
-
- SET RECEIVE FILTER sort -r > \v(filename)
- RECEIVE reverse.txt
- Stores each incoming file with its lines sorted in reverse
- order, under the name "reverse.txt". The actual result depends
- on the FILE COLLISION setting. If it is OVERWRITE and multiple
- files arrive, then each incoming file destroys the previous one.
- If it is BACKUP (the default), filename conflicts are resolve by
- adding "version numbers" to the filenames: reverse.txt,
- reverse.txt.~1~, reverse.txt.~2~, etc.
-
- SET RECEIVE FILTER sort -r > \v(filename)
- RECEIVE \v(filename).reverse
- Stores each incoming file with its lines sorted in reverse
- order, under the name it arrived with, but with ".reverse"
- appended to it.
-
- SET RECEIVE FILTER sort -r > \v(filename)
- RECEIVE \flower(\v(filename)).reverse
- Like the previous example, but ensures that the filename is
- lowercase.
-
- Examples for binary mode:
-
- SET RECEIVE FILTER gunzip -c > \v(filename)
- RECEIVE
- This receives one or more presumably compressed file and
- uncompresses each one into a file having the same name it was
- sent with. For example, if the file is sent with the name
- OOFA.TXT.GZ, it is stored with that name, even after
- decompression.
-
- SET RECEIVE FILTER gunzip -c > \v(filename)
- RECEIVE \flower(\fsubstring(\v(filename),1,\flength(\v(filename))-3))
- Like the previous example, but the resulting filename has its
- rightmost three characters removed from it and the remainder is
- lowercased. So if the incoming filename is OOFA.TXT.GZ, it is
- stored as oofa.txt after decompression.
-
- Of course you don't want to type such long hideous commands, so we have
- also introduced several new functions:
-
- \fstripx(string[,character])
- This function removes the rightmost segment of the string that
- starts with the given character. If no character is given,
- period (.) is used. Thus it is most conveniently used for
- stripping the extension from a filename (or the decimal portion
- from a floating-point number written in US/UK style). Examples:
-
- \fstripx(OOFA.TXT.GZ) => OOFA.TXT
- \fstripx(OOFA.TXT.GZ,.) => OOFA.TXT
- \fstripx(OOFA.TXT.GZ,X) => OOFA.T
- \fstripx(\fstripx(OOFA.TXT.GZ)) => OOFA
- \fstripx($100.00) => $100
-
- \fstripn(string,number)
- Removes the rightmost number characters from the string.
- Examples:
-
- \fstripn(OOFA.TXT.GZ) => OOFA.TXT.GZ
- \fstripn(OOFA.TXT.GZ,3) => OOFA.TXT
- \fstripn(OOFA.TXT.GZ,7) => OOFA
-
- \fstripb(string[,c1[,c2]])
- Strips enclosing matching braces, brackets, parentheses, or
- quotes from the string. The second argument, c1, specifies which
- kind of enclosure to look for; if not specified, any enclosing
- (), [], <>, {}, "", '', or `' are removed. If c1 is specified
- and c2 is not, then if c1 is an opening brace, bracket, or
- parenthesis, the matching closing one is supplied automatically
- as c2. If both c1 and c2 are specified, then to be stripped the
- string must begin with c1 and end with c2. If the string is not
- enclosed in the indicated manner, the result is the original
- string. Examples:
-
- \fstripb("abc") => abc
- \fstripb([abc]) => abc
- \fstripb([abc) => [abc
- \fstripb(<abc>) => abc
- \fstripb(<abc>,[) => <abc>
- \fstripb((abc)) => abc
- \fstripb((abc),[) => (abc)
- \fstripb((abc),{(}) => abc
- \fstripb(+abc+) => +abc+
- \fstripb(+abc+,+) => abc
- \fstripb(+abc+,+,^) => +abc+
- \fstripb(+abc^,+,^) => abc
- \fstripb('abc') => abc
- \fstripb(`abc') => abc
- \fstripb(``abc'') => `abc'
- \fstripb(\fstripb(``abc'')) => abc
-
- Notice the special syntax required for including a literal
- parenthesis in the argument list. As the last two examples
- illustrate, \fstripb() strips only one level at at a time;
- nesting can be used to strip a small fixed number of levels;
- loops can be used to strip larger or indeterminate numbers of
- levels.
-
- \flop(string[,char])
- Removes the leftmost segment of the string that ends with the
- given character. If no character is given, period (.) is used.
- Examples:
-
- \flop(OOFA.TXT.GZ) => TXT.GZ
- \flop(OOFA.TXT.GZ,.) => TXT.GZ
- \flop(OOFA.TXT.GZ,X) => T.GZ
-
- To remove the leftmost number characters, just use
- \fsubstring(s,number+1). To return the rightmost number
- characters, use \fright(s,number).
-
- So the hideous example:
-
- receive \flower(\fsubstring(\v(filename),1,\flength(\v(filename))-3))
-
- can now be written as:
-
- receive \flower(\fstripx(\v(filename)))
-
- That is, the filename stripped of its extension and then lowercased.
- This is not only shorter and less hideous, but also does not depend on
- the length of the extension being 3.
-
- Note that when a receive filter is in effect, this overrides your FILE
- COLLISION setting, since Kermit has no way of knowing what the final
- destination filename will be (because it does not know, and can not be
- expected to know, the syntax of every version of every command shell on
- every platform on the planet).
-
-4.2.4. Implicit Use of Pipes
-
- If you wish, C-Kermit can also examine incoming filenames to see if
- they start with "!", and if so, the subsequent text is treated as a
- command to read from or write to. For example, if a Kermit client is
- given the following command:
-
- get {!finger | sort}
-
- the server on the other end, if it supports this feature, will run the
- "finger" program, pipe its standard output to the "sort" program, and
- send sort's standard output back to you. Similarly, if you:
-
- send oofa.txt !sort -r > oofa.new
-
- or, equivalently:
-
- send oofa.txt {!sort -r > oofa.new}
-
- or:
-
- send /as-name:{!sort -r > oofa.new} oofa.txt
-
- this has the receiver send the contents of the incoming oofa.txt file
- to the sort program, which sorts the text in reverse order and stores
- the result in oofa.new.
-
- This use of the exclamation mark should be familiar to UNIX users as
- the "bang" feature that lets you run an external application or command
- from within another application.
-
- Kermit's "bang" feature is disabled by default, since it is not unheard
- for filenames to actually begin with "!". So if you want to use this
- feature, you must enable it with the following command:
-
- SET TRANSFER PIPES { ON, OFF }
- ON enables the recognition of "!" notation in incoming filenames
- during file transfer as an indicator that the remaining text is
- the name of a command. OFF, the default, disables this feature
- and uses the text as a filename in the normal fashion. This
- command does NOT affect SEND /COMMAND, GET /COMMAND, CSEND, etc.
-
- So using a combination of CSEND (SEND /COMMAND) and the "bang" feature,
- you can transfer a directory tree all in one command (assuming the
- remote Kermit supports pipe transfers and has them enabled):
-
- CSEND {tar cf - . | gzip -c} {!gunzip -c | tar xf -}
-
- or:
-
- SEND /COMMAND:{tar cf - . | gzip -c} /as:{!gunzip -c | tar xf -}
-
- Pay close attention to the syntax. Braces are needed around the command
- because it contains spaces; braces are needed around the as-name
- because it ends with "-". The as-name must begin with "!" or receiving
- Kermit will not recognize it as a command. The CSEND command must NOT
- begin with "!" unless you are running a command whose name really does
- start that character.
-
- Similarly, you have a Kermit server send a directory tree to be
- unpacked on the client end:
-
- CGET {!tar cf - . | gzip -c} {gunzip -c | tar xf -}
-
- or:
-
- GET /COMMAND {!tar cf - . | gzip -c} /as:{gunzip -c | tar xf -}
-
- Notice how, in this case, the bang is required in the remote command,
- to distinguish it from a filename, but not in the local command, since
- by definition of CGET (or GET /COMMAND), it is known to be a command.
-
- SEND and RECEIVE FILTERs supersede the bang feature. For example, if a
- file arrives under the name "!gunzip -c | tar xf -", but the receiving
- Kermit also has been given a command like:
-
- set receive filter sort -r > \v(filename)
-
- then the incoming data will be sorted rather than gunzipped.
-
- Finally, if SET TRANSFER PIPES is ON (and in this case, this must be
- done in your C-Kermit initialization file), you can send from a pipe on
- the C-Kermit command line:
-
- kermit -s "!finger | sort -r" -a userlist
-
- In this case the "filename" contains spaces and so must be quoting
- using your shell's quoting rules.
-
-4.2.5. Success and Failure of Piped Commands
-
- Commands or programs started by Kermit as a result of CSEND or CRECEIVE
- commands, CGET, SEND /COMMAND, REDIRECT commands (see [455]Section
- 4.2.8.2), implicit use of pipes, RUN commands, and so forth, should
- return their exit status codes to the Kermit command that caused them
- to be run, and therefore IF SUCCESS and IF FAILURE tests after these
- commands should work as expected. For example:
-
- CSEND blah < filename
-
- should fail if there is no command called "blah" or if there is no file
- called "filename". However, this is not foolproof and sometimes
- C-Kermit might think a command succeeded when it failed, or vice versa.
- This is most likely to happen when the highly system-dependent methods
- that Kermit must use to determine a command's exit status code do not
- supply the right information.
-
- It can also happen because some commands might define success and
- failure differently from what you expect, or because you are using a
- pipeline composed of many commands, and one of them fails to pass
- failing exit status codes up the chain. The most likely culprit is the
- shell itself, which in most cases must be interposed between Kermit and
- any external program to be run.
-
- In any case, you can examine the following variable to find out the
- exit status code returned to Kermit by the process most recently run by
- any command that runs external commands or programs, including CSEND,
- CRECEIVE, REDIRECT, RUN, etc:
-
- \v(pexitstat)
-
- In UNIX, Windows and OS/2, the value should be -2 if no command has
- been run yet, 0 if the most recent command succeeded, -1, -3, or -4 if
- there was an internal error, and a positive number returned by the
- command itself if the command failed. If the number is in the range
- 1-127, this is the program's exit status code. If it is 128 or greater,
- this is supposed to indicate that the command or program was
- interrupted or terminated from outside itself.
-
- In Windows 95 and 98, the return values of the default shell are
- unreliable; various third-party shells can be used to work around this
- deficiency.
-
- In VMS, it is the actual exit status code of the command that was run.
- This is an odd number if the command succeeded, and an even number if
- it failed. You can see the associated message as follows:
-
- run write sys$output f$message(\v(pexitstat))
-
- Or, more conveniently, use the new Kermit function:
-
- echo \ferrstring(\v(pexitstat))
-
- which converts a system error code (number) to the corresponding
- message.
-
-4.2.6. Cautions about Using Pipes to Transfer Directory Trees
-
- Although utilities such as tar and zip/unzip might be available on
- different platforms (such as UNIX and Windows), this does not
- necessarily mean you can use them successfully to transfer directory
- trees between unlike platforms. For example:
-
- CSEND {tar cf - . | gzip -c} {!gunzip -c | tar xf -}
-
- when used from UNIX to Windows will have satisfactory results for
- binary files, but not for text files. UNIX text files have lines ending
- with Linefeed (LF) only, whereas Windows text files have lines ending
- in Carriage Return and Linefeed (CRLF). Thus any text files that were
- in the archive formed by the first tar command will be unpacked by the
- second tar command in their original form, and will display and print
- incorrectly in Windows (except in applications that have been
- explicitly coded to handle UNIX-format text files). On the other hand
- if you told gzip to use "text mode" to do record format conversion
- (assuming there was a way to tell it, as there is with most "zip"
- programs), this would destroy any binary files in the archive.
-
- Furthermore, if the archive contains text files that are written in
- languages other than English, the "special" (accented and/or non-Roman)
- characters are NOT translated, and are therefore likely show up as
- gibberish on the target system. For example, West European languages
- are usually encoded in ISO Latin Alphabet 1 in UNIX, but in PC code
- page 850 on the PC. Capital A with acute accent is code point 193
- (decimal) Latin-1, but 181 in CP850. So A-acute in the UNIX file
- becomes Middle Box Bottom on the PC, and similarly for all the other
- special characters, and for all other languages -- Greek, Russian,
- Hebrew, Japanese, etc.
-
- So when transferring text files between unlike platforms, you should
- use direct Kermit file transfers so Kermit can apply the needed
- record-format and character-set transformations. Use pipelines
- containing archivers like tar or zip only if all the files are binary
- or the two systems use the same record format and character set for
- text files.
-
- Also see [456]Sections 4.3, [457]4.10, [458]4.11, and [459]4.15 for how
- to transfer directory trees between both like and unlike systems
- directly with Kermit.
-
-4.2.7. Pipes and Encryption
-
- Of course pipelines could be used for encrypted file transfers,
- assuming proper precautions could be taken concerning the transmission
- of the key. But there is rarely a good way to do this. To illustrate
- using UNIX crypt:
-
- csend {crypt key < filename} {!crypt key > filename}
-
- Or, more ambitiously:
-
- csend {tar cf - . | gzip -c | crypt key} {!crypt key | gunzip -c | tar xf -}
-
- transmits the key in the file header packet as part of the (clear-text)
- remote command, defeating the entire purpose of encrypting the file
- data.
-
- But if you are connected in terminal mode to the remote computer and
- type:
-
- creceive {crypt key > filename}
-
- at the remote Kermit prompt, you have also transmitted the key in clear
- text over the communications link.
-
- At present, the only secure way to use CSEND and CRECEIVE with an
- encryption filter is to have a human operator at both ends, so the key
- does not have to be transmitted.
-
- Theoretically it would be possible to use PGP software (Pretty Good
- Privacy, by Phil Zimmerman, Phil's Pretty Good Software) to avoid key
- transmission (since PGP uses separate public and private key and "lets
- you communicate securely with people you've never met, with no secure
- channels needed for prior exchange of keys"), but the specific method
- has yet to be worked out.
-
- HINT: See the PGP User's Guide, e.g. at:
- [460]http://www.telstra.com.au/docs/PGP/
- Especially the topic "Using PGP as a UNIX-Style Filter":
- [461]http://www.telstra.com.au/docs/PGP/pgpdoc2/pgpdoc2_17.html
-
- In any case, better and more convenient security options are now
- available: Kerberos authentication and encryption ([462]CLICK HERE for
- details) and the new ability to run C-Kermit "though" other
- communication programs, described in [463]Section 2.7.
-
-4.2.8. Commands and Functions Related to Pipes
-
-4.2.8.1. The OPEN !READ and OPEN !WRITE Commands
-
- These are described in [464]Using C-Kermit, and are generally useful
- with reading output from commands that produce more than one line on
- their standard output, or writing multiple lines into commands that
- accept them on their standard input.
-
- In C-Kermit 7.0 CLOSE !READ is accepted as a synonym for CLOSE READ,
- and CLOSE !WRITE for CLOSE WRITE.
-
- Testing the success and failure of these commands, however, can be a
- bit tricky. Consider:
-
- open !read lalaskjfsldkfjsldkfj
-
- (where "lalaskjfsldkfjsldkfj" is neither a valid command nor the name
- of a program or script that can be run). OPEN !READ, in UNIX at least,
- translates this into execl(shellpath,shellname,"-c",command). This
- means it starts your preferred shell (e.g. from the SHELL environment
- variable) and asks it to execute the given command. It must be this
- way, because your command can be a either an internal shell command
- (which only your shell can execute) or an external command, which only
- your shell knows how to find (it knows your PATH and interprets, etc).
- Therefore unless OPEN !READ can't start your shell, it always succeeds.
-
- Continuing with the nonexistent-command example:
-
- C-Kermit> open !read lalaskjfsldkfjsldkfj
- C-Kermit> status
- SUCCESS
- C-Kermit> read line
- C-Kermit> status
- SUCCESS
- C-Kermit> echo "\m(line)"
- "bash: lalaskjfsldkfjsldkfj: command not found"
- C-Kermit> close read
- C-Kermit> status
- FAILURE
- C-Kermit>
-
- In other words, the failure can not be detected on OPEN, since the OPEN
- command succeeds if it can start your shell. It can't be detected on
- READ, since all this does is read output from the shell, which in this
- case happens to be an error message. However, failure IS detected upon
- close, since this is the occasion upon which the shell gives Kermit its
- exit status code.
-
- For an illustration of this situation, see [465]Section 2.14.
-
-4.2.8.2. The REDIRECT Command
-
- A second method of I/O redirection is offered by the REDIRECT command.
- This is a rather advanced and tricky feature that is presently
- supported only in UNIX C-Kermit, in OS-9 C-Kermit, and in Kermit 95.
- Syntax:
-
- REDIRECT command
- Runs the given command, sending its standard output to the
- current communications channel (SET LINE, SET PORT, or SET HOST
- connection), and reading its standard input from the same
- connection. Works only in local mode -- i.e. a connection is
- required -- and then only if the given command uses Standard
- I/O.
-
- Example:
-
- redirect finger
-
- runs the local "finger" command and sends its output over the
- connection as plain text, where presumably there is a process set up to
- read it. Another example:
-
- redirect finger | sort -r
-
- shows the use of a pipeline.
-
- Note: REDIRECT differs from CSEND/CRECEIVE in two important ways: (1)
- it does not use the Kermit protocol, and (2) it uses a bidirectional
- pipe rather than a one-way pipe.
-
- The primary use of the REDIRECT command is to run external protocols,
- such as sz/rz in UNIX for ZMODEM, when they work over Standard I/O(*).
- Example:
-
- set host xyzcorp.com
- (login, etc)
- redirect sz oofa.zip
-
- lets you make a Telnet connection with C-Kermit and then do a ZMODEM
- transfer over it. ZMODEM protocol messages go both ways over the same
- connection simultaneously.
-
- It is possible to use C-Kermit on UNIX as your PPP dialer and then to
- REDIRECT the connection to the PPP software, but C-Kermit 7.0 offers a
- better approach to PPP dialing in its new EXEC command ([466]Section
- 1.23).
-
- In theory, you can also redirect an interactive process. For example,
- suppose you tell Kermit 95 to wait for an incoming TCP/IP connection:
-
- set host * 3000
-
- and then tell C-Kermit on UNIX to:
-
- set host kermit95hostname 3000
- redirect ksh
-
- and then tell Kermit 95 to CONNECT: now you are talking to the UNIX
- K-shell; you can give commands (pwd, ls, etc) and see the results. In
- practice, the K-shell's terminal modes are messed up because (a) it is
- not going through the Unix terminal driver, and (b) it is "smart" and
- knows it is being redirected, and so acts in a decidedly inhospitable
- manner (other applications like EMACS, vi, etc, simply refuse to run if
- their standard i/o has been redirected).
-
- (*) The publicly-distributed sz/rz programs do not work as clients.
- However, Omen Technology does offer an up-to-date redirectable
- client XYZMODEM program called crzsz.
-
-4.2.8.3. Receiving Mail and Print Jobs
-
- As of 7.0, and in UNIX only, files that are sent to C-Kermit as mail
- (when the other Kermit uses a MAIL or SEND /MAIL command) or to be
- printed (via REMOTE PRINT or SEND /PRINT) are now piped directly to the
- mail or print program, rather than written to temporary files and then
- mailed or printed and then deleted. This has the advantages of (a) not
- requiring a temporary file, and (b) allowing mail to have a proper
- subject in place of the filename. Temporary files were bad not only
- because they required (a) space, and (b) writability of the current
- directory, but also because using them could result in wiping out an
- existing file. See [467]Section 4.7 for more about SEND /MAIL and SEND
- /PRINT.
-
-4.2.8.4. Pipe-Related Functions
-
- The \fcommand(command) function runs the given shell or system command
- and returns the command's standard output as its value (with any
- newline characters stripped from the end), unless the result is too
- long, in which case it returns the empty string. The maximum length for
- the result is at least 1022 bytes, and it might be longer on some
- platforms. Examples (UNIX):
-
- C-Kermit> echo "\fcommand(date)"
- "Fri Apr 18 13:31:42 1997"
- C-Kermit> echo "\fcommand(finger | wc -l)" ; how many users logged in?
- " 83"
- C-Kermit> evaluate \fcommand(finger | wc -l) * 2
- 166
- C-Kermit> echo Welcome to \fcommand(tty) on \fcommand(date)
- Welcome to /dev/ttyre on Fri Apr 18 13:31:42 1997
- C-Kermit> echo "\fcommand(ls oofa.*)"
- "oofa.c
- oofa.h
- oofa.o"
- C-Kermit> cd /directory-with-thousands-of-files
- C-Kermit> echo "\fcommand(ls -l)" ; This would be too long
- ""
- C-Kermit>
-
- If a command's output would be too long, you can use the other, more
- laborious method of reading from a command: OPEN !READ command, READ
- each line, CLOSE !READ.
-
- The \frawcommand(command) function is identical to \fcommand(command),
- except it does not remove trailing newline characters:
-
- C-Kermit> echo "\frawcommand(date)"
- "Fri Apr 18 13:31:42 1997
- "
- C-Kermit> echo "\frawcommand(ls oofa.*)"
- "oofa.c
- oofa.h
- oofa.o
- "
- C-Kermit>
-
- Use \frawcommand() if you want to retain the final line terminators, or
- if the command's output is "binary". But remember that if the result of
- this (or any other) function contains any NUL (ASCII code 0)
- characters, the first NUL will terminate the result string because this
- is how C strings work (it's "C-Kermit", remember?).
-
- These functions are useful not only locally, but also in the
- client/server arena. If you need to get the results from a system
- command on the server end into a variable on the client end, just do:
-
- [ remote ] query kermit command(date)
-
- The result is in the local \v(query) variable; see [468]Using C-Kermit,
- 2nd Ed., pp.359-360 for details.
-
-4.3. Automatic Per-File Text/Binary Mode Switching
-
- When transferring files between like systems (e.g. UNIX-to-UNIX),
- binary mode can be used for all files unless character-set translation
- is needed, and in fact Kermit programs of recent vintage recognize each
- others' platforms and switch to binary mode automatically when it is
- appropriate (e.g. DOS to OS/2, or UNIX to UNIX). (Exception: LABELED
- mode is chosen for VMS-to-VMS and OS/2-to-OS/2 transfers so complex
- file formats can be preserved.)
-
- On a client/server connection between like systems, the transfer mode
- is currently determined by the file sender, rather than always by the
- client. If the client is sending, it controls the transfer mode. If a
- GET command is sent to the server, the server sends all files in binary
- mode if its TRANSFER CHARACTER-SET is TRANSPARENT; otherwise it uses
- text mode for text files (according to its text-pattern list) and
- binary mode for binary files. Of course, the client can control the
- server's transfer character-set with the REMOTE SET TRANSFER
- CHARACTER-SET command.
-
- When transferring files between unlike systems, however, (e.g.
- UNIX-to-DOS), some files (such as executable program images) must be
- transferred in binary mode but others (such as plain-text files) must
- be transferred in text mode so their record format and character sets
- can be appropriately converted. If a binary file is transferred in text
- mode, it is ruined. If a text file is transferred in binary mode, then
- at the very least, its format can be incorrect; at worst it is also
- corrupted because its character set was not converted (in extreme cases
- the corruption is total, e.g. because one system is ASCII-based and the
- other EBCDIC).
-
-4.3.1. Exceptions
-
- VMS C-Kermit, when sending files to a non-VMS system, switches to text
- or binary mode automatically for each file, based on the record format
- in the file's directory entry; thus the mechanisms described in this
- section do not apply to VMS C-Kermit, yet the effect is the same:
- automatic text/binary mode switching when VMS C-Kermit is sending
- files. See the VMS Appendix of [469]Using C-Kermit for details.
-
- Kermit versions that support LABELED or IMAGE transfer mode are
- likewise not affected by this feature when one of those modes is
- selected (normally used only when transferring between like systems).
-
- Kermit versions that support file-transfer pipes and filters are not
- affected by this feature when pipes or filters are used, since the
- output of a pipe or filter (such as gzip) is likely to require transfer
- in a different mode than the original file.
-
- Finally, SEND /TEXT or SEND /BINARY will force files to be sent in the
- indicated mode, overriding all automatic transfer-mode-choosing
- mechanisms.
-
-4.3.2. Overview
-
- Suppose you give C-Kermit a command like:
-
- SEND *.*
-
- And suppose the pattern *.* matches a mixture of text files (such as
- program source code) and binary files (such os object modules or
- executable programs).
-
- C-Kermit 6.0 and earlier (except on VMS) send all files in the same
- mode: whatever you said in your most recent SET FILE TYPE command, or
- else whatever mode was chosen automatically according to the rules on
- page 236 of Using C-Kermit, 2nd Ed.
-
- But when text and binary files are mixed in the same group, and the
- files are being transferred to an unlike system (e.g. UNIX to IBM
- Mainframe), this results in corruption of either all the text files or
- all the binary files.
-
- Stream-oriented file systems such as in UNIX and DOS do not record any
- information about the file to tell us whether the file should be
- transferred in binary or text mode, making it impossible to select the
- transfer mode for each file in a group automatically with any
- certainty.
-
- However, we can use some fairly-well established file naming
- conventions for this purpose. C-Kermit 7.0 lets you provide lists of
- filename patterns that are used to separately determine the file type
- for each individual file being transferred. A pattern is a string,
- possibly containing the special characters "*" (asterisk, which matches
- any string of zero of more characters) and/or "?" (question mark, which
- matches any single character). For example "a*b" matches all files
- whose names start with "a" and end with "b", such as "ab", "arb",
- "ababababab", etc, but not "abba". And "a?b" matches any file whose
- name starts with "a", ends with "b", and is exactly 3 characters long.
-
- NOTE: When typing commands at the C-Kermit prompt, you must prefix
- "?" with \ to override its normal function of giving help.
-
- (Also see [470]Section 4.9 for additional pattern-matching notations
- that might be available in your version of C-Kermit.)
-
- When you have specified filename recognition patterns, C-Kermit can
- transfer the ones whose names match any of the binary-mode patterns in
- binary mode, and those with names that match any of the text-mode
- patterns in text mode, and those whose names match neither in the
- prevailing mode you have chosen, or that was chosen automatically via
- peer recognition.
-
-4.3.3. Commands
-
- SET FILE PATTERNS { ON, OFF, AUTO }
- This tells Kermit whether to do per-file filename
- pattern-matching to determine text or binary mode. The normal
- and default setting is AUTO, which means to use pattern lists to
- switch transfer mode only when it is certain that the other
- Kermit program supports automatic notification of transfer mode
- (via Attribute packets) on a per-file basis (this information is
- obtained automatically during protocol startup negotiation). ON
- means to always determine the transfer mode from the filename
- and pattern list when sending files. Use OFF to disable this
- feature (without resetting your pattern lists). Also note that
- if you have selected LABELED file transfer (SET FILE TYPE
- LABELED), this takes precedence over filename-matching patterns
- and all files are sent in labeled mode.
-
- SET TRANSFER MODE MANUAL
- Disables the use of filename patterns, no matter what the FILE
- PATTERNS setting.
-
- REMOTE SET TRANSFER MODE MANUAL
- Client command to disable automatic transfer mode, and therefore
- also filename patterns, in the server. Synonym: REMOTE SET XFER
- MODE MANUAL.
-
- { GET, SEND, etc } { /BINARY, /TEXT }
- Including a /BINARY or /TEXT (or, where supported, /IMAGE or
- /LABELED) switch with a file-transfer command changes the
- transfer mode to manual for that command only, and therefore
- disables patterns that that command.
-
- SET FILE BINARY-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
- A list of zero or more patterns, separated by spaces (not
- commas). Letters in a pattern are case-sensitive if the
- underlying filenames are case sensitive (as in UNIX), and
- case-insensitive otherwise (as in Windows). If a file's name is
- matched by any pattern in the list and SET FILE PATTERNS is ON,
- the file is sent in binary mode. Examples:
-
- SET FILE BINARY-PATTERNS *.gz *.Z *.tar *.zip *.o *.so *.a *.out ; UNIX
- SET FILE BINARY-PATTERNS *.EXE *.ZIP *.OBJ *.COM ; DOS or OS/2 or Windows
-
- If a pattern contains spaces, enclose it in braces.
-
- SET FILE TEXT-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
- Like SET FILE BINARY-PATTERNS, but the patterns choose text
- files rather than binary ones. Examples:
-
- SET FILE TEXT-PATTERNS *.TXT *.KSC *.HTM* *.BAT ; DOS, Windows, OS/2
-
- ADD BINARY-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
- Adds one or more patterns to the BINARY-PATTERN list.
-
- ADD TEXT-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
- Adds one or more patterns to the TEXT-PATTERN list.
-
- REMOVE BINARY-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
- Removes one or more patterns from the BINARY-PATTERN list. The
- given patterns are matched with the ones in the BINARY-PATTERNS
- list with case sensitivity if the underlying file system has
- case-sensitive names (as do UNIX and OS-9), otherwise with case
- independence.
-
- REMOVE TEXT-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
- Removes one or more patterns from the TEXT-PATTERN list.
-
- SHOW PATTERNS
- Displays the current pattern selections.
-
- Whenever you give a SET FILE BINARY-PATTERNS or SET FILE TEXT-PATTERNS
- command, the previous list is replaced. If you give one of these
- commands without a pattern list, the previous list is removed.
-
- When patterns are active and files are being sent, text patterns (if
- any) are applied first (but only if not RESENDing and not sending in
- LABELED mode), then binary patterns, so if the same pattern appears in
- both lists, binary mode is chosen.
-
-4.3.4. Examples
-
- Here's an example that might be used when sending files from UNIX:
-
- set file type binary
- set file text-patterns *.c *.h *.w *.txt makefile
- set file binary-patterns *.o
- msend makefile wermit wart ck*.[cwho] ck*.txt
-
- Note that "wermit" and "wart" do not match any patterns so they are
- sent in the prevailing mode, which is binary. Also note the use of
- "makefile" as a pattern that does not contain any wildcard characters
- (there is no other convention to distinguish among "wermit" and "wart",
- which are binary executables, and "makefile", which is a text file,
- purely by their names).
-
- Most C-Kermit implementations have a default pattern list built in,
- which includes patterns that are almost certain to succeed in picking
- the right transfer mode. Others are omitted due to ambiguity. For
- example ".hlp", and ".ini" are generally binary types in Windows but
- text types everywhere else.
-
- NOTE: ".doc", used for decades to denote plain-text documentation
- files, now more often than not denotes a Microsoft Word Document, so
- ".doc" is now considered a binary type since it does less harm to
- transfer a plain-text document in binary mode than it does to
- transfer an MS Word file in text mode (except when IBM mainframes
- are involved!)
-
- ANOTHER NOTE: ".com" files are binary in DOS-like operating systems,
- but they are text (DCL command procedures) in VMS. VMS C-Kermit
- sends .COM files in text mode; K95 sends them in binary mode. If you
- download a .COM file from VMS to DOS or Windows, and then upload it
- to another VMS system, be sure to use SEND /TEXT to preserve its
- textness.
-
- You can see the default pattern list by starting C-Kermit without its
- initialization file (e.g. "kermit -Y") and using the SHOW PATTERNS
- command. If you will be depending on this feature, be sure to examine
- the list carefully in conjunction with the applications that you use.
-
- The default pattern list does not take "backup files" into account
- because (a) people usually don't want to transfer them; and (b) it
- would make the pattern lists more than twice as long. For example, we
- would need to include both *.txt and *.txt.~[0-9]*~ for ".txt" files,
- and similarly for all the others. Instead, you can use SEND /NOBACKUP
- (or SET SEND BACKUP OFF) to skip over all backup files.
-
- Put your most commonly-used safe pattern declarations in your C-Kermit
- customization file (ckermod.ini, .mykermrc, k95custom.ini, etc).
-
- As noted, SET FILE PATTERNS is ON by default. Sometimes, however, it is
- desirable, or necessary, to force files to be sent in a particular
- mode, and often this must be done from the command line (e.g. when
- using Kermit as a download helper in a Web browser like Lynx). The -V
- command-line options is equivalent to SET FILE PATTERNS OFF and SET
- TRANSFER MODE MANUAL. Example:
-
- kermit -Vis oofa.txt
-
- forces oofa.txt to be sent in binary mode, even though ".txt" might
- match a text pattern.
-
-4.4. File Permissions
-
- "Permissions" refers to a code associated with a file that specifies
- who is allowed to access it, and in what manner. For example, the
- owner, the members of one or more groups, the system administrator, and
- everybody else, might be allowed various combinations of Read, Write,
- Append, Execute, or Listing access.
-
- The permission code goes by different names on different platforms. In
- UNIX, it might be called the filemode. In VMS, it is called the file
- protection (or protection mask).
-
- The comments in this section presently apply only to the UNIX and VMS
- versions of C-Kermit, to which these features were added in version
- 7.0; the DOS, Windows, and OS/2 file systems embody no notions of
- protection, and so MS-DOS Kermit and Kermit 95 do not send file
- permissions, and ignore them when received.
-
- The permissions for a received file are determined by a combination of
- the file transfer mode (VMS-to-VMS transfers only), whether a file of
- the same name exists already, whether permissions of the file are
- received in the file attribute packet, and the setting of ATTRIBUTES
- PROTECTION.
-
- The default for ATTRIBUTES PROTECTION is ON. If no attributes are
- received, the effect is the same as if attributes PROTECTION were OFF.
-
- For VMS-to-VMS transfers, the default LABELED mode simply copies the
- protection code from source to destination.
-
-4.4.1. When ATTRIBUTES PROTECTION is OFF
-
- If no file of the same name exists, system defaults determine the
- permissions of the new file. Otherwise, the actions taken depend on the
- current FILE COLLISION setting: BACKUP, OVERWRITE, RENAME, etc, as
- documented in [471]Using C-Kermit. But now the new file (if it is
- created at all) automatically inherits the permissions (mode bits) of
- the existing file in a way that is appropriate for the platform.
-
-4.4.1.1. Unix
-
- All mode bits are inherited except the directory bit, since the
- incoming file can not possibly be a directory. (In any case, it is not
- possible to receive a file that has the same name as an existing
- directory unless FILE COLLISION is set to RENAME).
-
-4.4.1.2. VMS
-
- Files with the same name as an existing file, transferred in modes
- other than LABELED between VMS systems, inherit the protection of the
- prior version.
-
-4.4.2 When ATTRIBUTES PROTECTION is ON
-
- File permissions can be conveyed as part of the file transfer process,
- in accordance with the Kermit protocol definition. If the file sender
- puts system-dependent and/or system-independent versions of the file
- protection (permissions) into the Attribute (A) packet, the file
- receiver can set the new file's permissions from them. Otherwise, the
- permissions are set the same as for ATTRIBUTES PROTECTION OFF.
-
- When the incoming A packet contains system-dependent permissions, the
- file receiver checks to see if the sender has the same system ID (e.g.
- both the sending and receiving systems are UNIX, or both are VMS); if
- so, it decodes and uses the system-dependent permissions; otherwise it
- uses the generic ones (if any) and applies them to the owner field,
- setting the other fields appropriately as described in the following
- sections.
-
- Setting the incoming file's protection from the A packet is controlled
- by SET ATTRIBUTES PROTECTION (or PERMISSION), which is ON by default,
- and its status is displayed by SHOW ATTRIBUTES.
-
- The main benefit of this feature is to not have to "chmod +x" an
- executable file after transfer from UNIX to UNIX. Its cross-platform
- benefits are less evident, perhaps to retain the status of the Unix 'x'
- bit on a VMS system, for subsequent transfer back to a Unix system.
-
-4.4.2.1. System-Specific Permissions
-
- System-specific file permissions are used when the two Kermit programs
- recognize each other as running on the same type of system. For
- example, both are running under some form of UNIX (it doesn't matter
- which UNIX variation -- HP-UX, Solaris, AIX, etc -- all use the same
- scheme for file permissions); or both are running under VMS (even if
- one is on an Alpha and the other on a VAX, and/or one is old and the
- other is new).
-
-4.4.2.1.1. UNIX
-
- UNIX supports three categories of users, File Owner, Group, and World,
- and three types of file access permission: Read, Write, and Execute.
- Thus, a UNIX file's permissions are expressed in 9 bits.
-
- The system-dependent permission string for UNIX is a 3-digit octal
- string, the low-order 9 bits of the st_mode member of the stat struct;
- we deliberately chop off the "file format" bits because they are not
- permissions, nor do we convey the setuid/setgid bits, lock bit, sticky
- bit, etc.
-
-4.4.2.1.2. VMS
-
- VMS supports four categories of users, System, File Owner, Group, and
- World, and four types of file access permission: Read, Write, Execute,
- and Delete. Thus, a VMS file's permissions are expressed in 16 bits.
-
- The system-dependent protection string for VMS is a 4-digit hexadecimal
- string, corresponding to the internal-format protection word of the
- file (RWED for each of World,Group,Owner,System). A new file normally
- gets all 16 protection bits from the original file of the same name.
-
- Note: VMS-to-VMS transfers take place in LABELED mode when the two
- C-Kermits recognize each other's platform as VMS (unless you have
- disabled LABELED-mode transfers). In this case, all of a file's
- attributes are preserved in the transfer and the protection mask (and
- other information) is taken from the file's internal information, and
- this takes precedence over any information in the Attribute packets.
- You can defeat the automatic switching into LABELED mode (if you want
- to) with SET TRANSFER MODE MANUAL.
-
-4.4.2.2. System-Independent Permissions
-
- The system-independent ("generic") protection is used when the system
- IDs of the two Kermit programs do not agree (e.g. one is UNIX, the
- other is VMS). The generic protection attribute includes the following
- permissions (not all are applicable to every file system): Read, Write,
- Append, Execute, Delete, Search. The generic permissions are derived
- from the owner permissions of the source file, thus, a Unix 'w'
- permission becomes VMS Write,Delete.
-
- The Owner field of the new file's permissions is set from the incoming
- generic protection attribute.
-
- In UNIX, the Group and World permissions are set according to your
- umask, except that execute permission is NOT set in these fields if it
- was not also set in the generic protection (and consequently, is set in
- the Owner field).
-
- In VMS, the System, Group, and World permissions are set according to
- the process default file permission (as shown in VMS by SHOW
- PROTECTION), except that no permissions are allowed in these fields
- that are not included in the generic permissions.
-
- Note that the VMS and UNIX interpretations of Execute permission are
- not identical. In UNIX, a file (binary executable, shell script, etc)
- may not be executed unless it has Execute permission, and normally
- files that are not intended for execution do not have Execute
- permission. In VMS, Read permission implicitly supplies Execute
- capability. Generally files that have Read permission also have
- explicit Execute permission, but files (binary executables, DCL command
- procedures) that have Read permission and not Execute permission can
- still be executed.
-
-4.5. File Management Commands
-
-4.5.1. The DIRECTORY Command
-
- Prior to C-Kermit 7.0, the DIRECTORY command always ran an external
- system command (such as "ls" on UNIX) or program to product the
- directory listing. This had certain advantages, mostly that you could
- include system-dependent options for customized listings, e.g. on UNIX:
-
- dir -lt c* | more
-
- or in VMS:
-
- directory /size/date/protection/except=*.obj oofa.*;0
-
- This approach, however, carries some disadvantages: C-Kermit can't
- return SUCCESS or FAILURE status for (e.g.) "dir foo" according to
- whether the file "foo" exists; and it runs an inferior process, which
- might be a problem in some environments for resource and/or security
- reasons, and won't work at all in a "nopush" environment (e.g. one in
- which C-Kermit is configured to forbid access to exterior commands and
- programs, e.g. in a VMS "captive account").
-
- In C-Kermit 7.0 on VMS and UNIX, and in K95 1.1.19 and later, the
- DIRECTORY command is internal to Kermit. It can be run in a "nopush"
- environment and returns SUCCESS or FAILURE status appropriately. In
- UNIX it prints all dates and times in a consistent way (unlike ls). In
- VMS it prints precise file sizes, rather than "blocks". It offers
- several formatting and other options, but it is not necessarily more
- flexible than the corresponding external commands or programs (the UNIX
- "ls" program, the VMS "directory" command). The syntax is:
-
- DIRECTORY [ switch [ switch [ ... ] ] ] [ filespec ]
-
- If no filespec is given, all files in the current directory are listed.
-
- Optional switches include all the standard file-selection switches
- presented in [472]Section 1.5.4, plus:
-
- /ALL
- Show both regular files and directories; this is the default.
-
- /ARRAY:x
- Instead of displaying a directory listing, put the files that
- would have been shown (based on the filespec and other selection
- switches) in the given array. The array need not (and should
- not) be predeclared; if the array already exists, it is
- destroyed and reused. The array name can be a single letter,
- like "a", or any fuller form, such as "&a", "\&a", "\&a[]", etc.
- If the /ARRAY switch is included, the following other switches
- are ignored: /BRIEF, /VERBOSE, /HEADING, /PAGE, /ENGLISHDATE,
- /ISODATE, /XFERMODE, /MESSAGE, /SORT, /REVERSE, /ASCENDING. In
- other words, only file selection switches are meaningful with
- /ARRAY: /FILES, /DIRECTORIES, /ALL, /DOTFILES, /NOBACKUP,
- /RECURSIVE, /SMALLER, /LARGER, /AFTER, /BEFORE, /EXCEPT, etc.
- The resulting array has the number of files (n) as its 0th
- element, and the filenames in elements 1 through n Example:
-
- dir /array:&a /files /nobackup /after:19990101 /larger:10000 [ab]*
- show array &a
-
- /FILES
- Only show regular files.
-
- /DIRECTORIES
- Only show directories.
-
- /BACKUP
- In UNIX, OS-9, K-95, and other versions that support SET FILE
- COLLISION BACKUP and create backup files by appending .~n~ to
- the filename (where "n" is a number), /BACKUP means to include
- these files in directory listings. This is the default.
-
- /NOBACKUP
- This is the opposite of /BACKUP: that is, do not include backup
- files in the listing.
-
- /BRIEF
- List filenames only; use a compact format, as many filenames as
- will fit across the screen (based on the longest name). A brief
- listing is always sorted alphabetically.
-
- /VERBOSE
- List one file per line, and include date, size, and (in UNIX
- only) permissions of each file. This is the opposite of /BRIEF,
- and is the default.
-
- /PAGE
- Pause at the end of each screenful and give a "more?" prompt,
- even if SET COMMAND MORE-PROMPTING is OFF.
-
- /NOPAGE
- Don't pause at the end of each screenful and give a "more?"
- prompt, even if SET COMMAND MORE-PROMPTING is ON. If neither
- /PAGE or /NOPAGE is given, paging is according to the prevailing
- COMMAND MORE-PROMPTING setting (which can be displayed with SHOW
- COMMAND).
-
- /ENGLISHDATE
- Show dates in dd-mmm-yyyy format; mmm is the first three letters
- of the English month name.
-
- /ISODATE
- Show dates in yyyy-mm-dd format; mm is the month number, 1-12.
- This is the opposite of /ENGLISHDATE, and is the default.
-
- /HEADINGS
- Print a heading before the listing and a summary at the end.
-
- /NOHEADINGS
- Don't print a heading before the listing or a summary at the
- end. This is the opposite of /HEADINGS, and is the default.
-
- /XFERMODE
- Only in Kermit programs that support SET FILE PATTERNS. If this
- switch is included, and the filename matches any FILE
- BINARY-PATTERN ([473]Section 4.3), "(B)" is printed after the
- filename; otherwise, if it matches a FILE TEXT-PATTERN, "(T)" is
- printed.
-
- /NOXFERMODE
- Don't display transfer-mode indicators. This is the opposite of
- /XFERMODE and is the default.
-
- /RECURSIVE
- Show files not only in the given directory, but also in its
- subdirectories (if any), their subdirectories, etc.
-
- /NORECURSIVE
- Don't show files in subdirectories. This is the opposite of
- /RECURSIVE, and is the default.
-
- /MESSAGE:text
- This lets you specify a short text string to be appended to the
- end of each directory listing line (a space is supplied
- automatically). If the text contains any spaces, enclose it in
- braces, e.g. /MESSAGE:{two words}.
-
- /NOMESSAGE
- Don't append any message to the end of each directory listing
- line (default).
-
- /SORT:[{NAME,SIZE,DATE}]
- Sort the listing by name, size, or date. If the /SORT switch is
- given but the "sort-by" keyword is omitted, the listing is
- sorted by name. /SORT:NAME /ASCENDING (alphabetic sort by name)
- is the default.
-
- /NOSORT
- Don't sort the listing. Files are listed in whatever order they
- are supplied by the operating system, e.g. inode order in UNIX.
-
- /REVERSE
- If the /SORT switch is given, reverse the order of the sort.
- Synonym: /DESCENDING.
-
- /ASCENDING
- If the /SORT switch is given, sort the listing in normal order.
- This is the opposite of /REVERSE and is the default.
-
- Note that most of the DIRECTORY-specific switches come in pairs, in
- which one member of a pair (e.g. /NOHEADINGS) is the opposite of the
- other (e.g. /HEADINGS).
-
- If you always want to use certain options, you can set them with the
- SET OPTIONS DIRECTORY command ([474]Section 1.5.5). Use SHOW OPTIONS to
- list the options currently in effect. To make the desired options apply
- every time you run C-Kermit, put a SET OPTIONS DIRECTORY command in
- your C-Kermit customization file, specifying the desired options.
- Options set in this manner apply to every subsequent DIRECTORY command.
- Of course, if you include switches in a DIRECTORY command, these
- override any defaults, built-in or custom. Example:
-
- DIRECTORY ; Use "factory defaults"
- SET OPTIONS DIRECTORY /SORT:SIZE /REVERSE /HEADINGS ; Customize defaults
- DIRECTORY ; Use customized defaults
- DIR /SORT:NAME ; Override customized default SORT key
- SET OPT DIR /RECURS ; Add /RECURSIVE to customized defaults
- DIR /ASCEND ; Override customized default SORT order
-
- Notes:
-
- * Only a single sort key is supported; there is presently no way to
- have multiple sort keys.
- * If the /BRIEF switch is given, all other switches (except
- /[NO]RECURSIVE, /[NO]DOTFILES, /DIRECTORIES, /FILES, and /ALL) are
- ignored.
- * /SORT:anything gives incorrect results if any files have lengths
- greater than 10 digits (i.e. that are more than 9999999999 bytes
- long, i.e. if they are 10GB or more in size) because the overlong
- length field causes the date and name fields to be misaligned.
- * /SORT:NAME is redundant in VMS since VMS returns filenames in
- alphabetic order anyway.
- * /SORT:NAME ignores alphabetic case on platforms where case does not
- matter in filenames, but this works only for unaccented Roman
- letters A-Z.
- * /SORT:NAME is currently based on code values, and so works fine for
- ASCII, but will probably produce unexpected results for files with
- non-ASCII or 8-bit characters in their names. (Locale-based sorting
- raises rather significant issues of portability, size, performance,
- etc.)
- * /SORT:DATE works right only for ISO-format dates, not English ones.
- * /SORT:SIZE sorts the size field lexically. On some platforms (e.g.
- Windows), the size of a directory file is listed as "<DIR>" rather
- than as a number; in this case, the "<DIR>" files are gathered at
- the end (or beginning, depending on the sort order) of the listing.
- * /RECURSIVE is accepted but ignored in AOS/VS. Use the normal
- system-specific filespec notation, e.g. "dir #.txt".
- * /RECURSIVE has no affect when a full, absolute pathname is given;
- e.g. "dir /recursive /tmp/foo" (where "foo" is a regular file) only
- shows the "/tmp/foo" file. If you want to see all "foo" files in
- the /tmp tree, do "cd /tmp" and then "dir /recursive foo".
- * If a file size of -1 is shown, or date-time of 0000-00-00 00:00:00,
- this means the file was located, but access to information about
- the file was denied to C-Kermit.
- * In VMS, if FOO.DIR;1 is a directory within your current directory,
- "directory foo" and "directory [.foo]" list the files in the [.FOO]
- subdirectory, but "directory foo.dir" lists the directory file
- itself; similarly for "*.dir" versus "[.*]", etc.
- * In UNIX, if "foo" is a directory within your current directory,
- "directory foo" lists the files in the foo directory. If you want
- to list the foo directory file itself, put an asterisk at the end:
- "dir foo*".
-
- Hint: How to find the biggest files in a directory tree:
-
- cd xxx ; (root of tree)
- directory /sort:size /recursive /reverse /dotfiles /page
-
- Another hint: If you often use several different directory-listing
- formats, define macro shortcuts for them:
-
- DEFINE WD DIRECTORY /SORT:DATE /REVERSE \%* ; Reverse chronological order
- DEFINE SD DIRECTORY /SORT:SIZE /REVERSE \%* ; Reverse order of size
- DEFINE ND DIRECTORY /SORT:NAME /ASCEND \%* ; Alphabetical by name
- DEFINE DL DIR /DIR /SORT:NAME /ASCEND \%* ; Alphabetical directory list
-
- Put these definitions in your C-Kermit customization file. Note that
- "\%*" ([475]Section 7.5) in these definitions lets you include other
- switches in your macro invocations, e.g.:
-
- wd /headings *.txt
-
- Of course you can still access your external directory listing program
- by using RUN or "!", e.g. in VMS:
-
- run directory /size/date/protection/except=*.obj oofa.*;0
-
- or:
-
- !dir /size/date/prot/exc=*.obj oofa.*;0
-
- In UNIX, use "!ls" or just "ls" (which is a special synonym for "!ls").
-
-4.5.2. The CD and BACK Commands
-
- In C-Kermit 7.0, the CD command has a new friend, the BACK command.
- BACK means "CD to my previous current directory". A second BACK brings
- you back to where you were before the first one; thus successive BACK
- commands switch back and forth between two directories.
-
-4.5.2.1. Parsing Improvements
-
- The CD command, as well as other commands that parse a directory name,
- were changed in 7.0 to provide all the expected functions: completion
- on Tab or Esc, directory-name lists on ?, etc. Other affected commands
- include SET SERVER GET-PATH, SET TEMP-DIRECTORY, SET FILE
- DOWNLOAD-DIRECTORY, and SPACE. CD and REMOTE CD also now work with
- logical names.
-
- In VMS, the situation is a bit complicated since a directory name can
- look like "DEV:", "[FOO.BAR]", "DEV:[FOO.BAR]", "[FOO]BAR.DIR;1", etc.
- Completion and ?-help might not always work, but they do in many cases.
- Examples:
-
- cd ? Lists all subdirectories of the current directory
- cd []? Ditto
- cd k? Ditto, but only those starting with K
- cd [foo]? Lists all subdirectories of the [FOO] directory
- cd [-]? Lists all subdirectories of the superior directory
- cd [--]? Lists all subdirectories of the directory 2 levels up
- cd [...]? Lists all directories below the current one
- cd [foo.? Does not work.
-
- C-Kermit allows all of the following in VMS:
-
- cd bar CD to subdirectory BAR of the current directory
- cd .bar Ditto
- cd [.bar] Ditto
- cd bar.dir etc...
- cd bar.dir;
- cd bar.dir;1
- cd [foo.bar]
- cd <foo.bar>
- cd bar.baz This can go more than 1 level deep...
- cd dir: (where logical name DIR is defined as [FOO.BAR])
-
- As well as the following:
-
- cd .. Go up one level as in UNIX
- cd . The current directory
- cd My login directory
-
- Note that "cd -" (go up one level) does not work as expected, because
- "-" is Kermit's command continuation character. However, "cd [-]", and
- "
- cd {-}" have the desired effect (and so does "cd ..", which is easier
- to type).
-
-4.5.2.2. The CDPATH
-
- The CD command in the UNIX, Windows, OS/2, and VMS versions of
- C-Kermit, as of version 6.1 / 1.1.12, searches the CDPATH for the given
- directory, if it is not absolute and if a CDPATH environment variable
- is defined. Example (in UNIX ksh or bash):
-
- $ export CDPATH=$HOME:$HOME/kermit:/tmp
-
- Now if you give a "cd xxx" command, no matter what your current
- directory is, if the "xxx" directory is not a subdirectory of your
- current directory, then the xxx subdirectory of your home directory is
- used or if that does not exist, then the xxx subdirectory of the kermit
- subdirectory of your home directory is used or if that does not exist,
- then /tmp/xxx is used. This is how the ksh "cd" command works, and now
- the C-Kermit CD command works the same way.
-
- In VMS, you can define CDPATH to be a list of directories that contain
- actual directory delimiters, and/or logical names representing
- directories, using commas to separate them, e.g.:
-
- $ define cdpath [HOME],[SOMEOTHERDIR],[HOME.MISC]
- $ define cdpath SYS$LOGIN:,DISK1:[HOME],DISK2:[SCRATCH.IVAN]
-
- Example:
-
- $ define cdpath SYS$LOGIN:,[IVAN],[OLAF],[OLGA.MISC]
- $ kermit
- DISK1:[OLGA] C-Kermit> cd blah
-
- tries the BLAH subdirectory of the user's login directory, then
- [OLGA.BLAH], [IVAN.BLAH], [OLAF.BLAH], and [OLGA.MISC.BLAH], in that
- order, using the first one it finds, failing if it finds none.
-
- In C-Kermit 7.0, you may also set the CDPATH from the Kermit prompt:
-
- SET CD PATH path
- Allows the CD PATH to be set from within C-Kermit.
-
- SHOW CD shows the CD path and all other information relevant to the CD
- command.
-
-4.5.2.3. CD Messages
-
- Whenever you change directory, you can have C-Kermit display a "Read
- Me" file from the new directory automatically. The commands are:
-
- SET CD MESSAGE { ON, OFF, FILE list }
- ON enables this feature; OFF (the default) disables it. File
- lets you specify the name of the "Read Me" file. A list of names
- to look for can be given in the following format:
-
- {{name1}{name2}{name3}{...}}
-
- e.g.:
-
- SET SERVER CD-MESSAGE FILE {{./.readme}{README.TXT}{READ.ME}}
-
- The default list of CD-message files is system dependent.
-
- SHOW CD shows your current directory, previous directory, CD path, and
- CD message info.
-
-4.5.3. Creating and Removing Directories
-
- The MKDIR command now allows you to create multiple directories at
- once:
-
- C-Kermit> mkdir a/b/c/d
-
- creates the directory a in the current directory (if it doesn't exist
- already), and then creates subdirectory b in the a directory (if it
- didn't exist already), and so on.
-
- If you use MKDIR to try to create a directory that already exists,
- C-Kermit will print a warning ("?Directory already exists"), but the
- MKDIR command will still succeed. If you want to avoid the warning
- message, use IF DIRECTORY first to check if the directory already
- exists.
-
- The RMDIR command, however, will not remove more than one directory,
- nor will it remove a directory that contains any files. (There is, as
- yet, no RMDIR /RECURSIVE command, although one might be added later.)
-
- In VMS, these commands (like CD) are more forgiving of your syntax than
- is the DCL command shell; "mkdir oofa" is equivalent to "mkdir [.oofa]"
- and so on. Also in VMS, you'll find that C-Kermit's RMDIR command is
- easier than deleting a directory in DCL, since it automatically first
- gives it owner delete permission if you are the owner.
-
-4.5.4. The DELETE and PURGE Commands
-
- The DELETE command now offers a selection of switches, and has a new
- companion, the PURGE command. First, DELETE:
-
- DELETE [ switches... ] filespec
- Deletes the file or files that match the filespec, which may
- contain wildcards ([476]Section 4.9).
-
- Optional switches include the standard file-selection switches
- presented in [477]Section 1.5.4, plus:
-
- /ASK
- Before deleting each file, ask permission interactively. Answers
- are Yes or OK (delete the file), No (don't delete it), or Quit
- (stop executing the DELETE command).
-
- /NOASK
- Don't ask permission to delete each file.
-
- /LIST
- List each file and show whether it was deleted. Synonyms: /LOG,
- /VERBOSE.
-
- /NOLIST
- Don't list files while deleting them. Synonyms: /NOLOG, /QUIET.
-
- /HEADING
- Print a heading and summary line.
-
- /NOHEADING
- Don't print a heading and summary line.
-
- /PAGE
- When listing, pause at the end of each screenful and give the
- "More?" prompt. If you reply "n" (no), the DELETE command
- terminates.
-
- /SIMULATE
- Do everything implied by the given switches and filespec, except
- do not actually delete any files. This lets you preview which
- files would be deleted; implies /LIST.
-
- Now the PURGE command:
-
- PURGE [ switches... ] [ filespec ]
- (VMS only) Runs the DCL PURGE command. Switches and filespec, if
- any, are passed directly to DCL without parsing or verification.
- Deletes excess versions of the given (or all) files. The rest of
- this section does not apply to VMS.
-
- PURGE [ switches... ] [ filespec ]
- (UNIX only) Deletes "backup files" that match the filespec,
- which may contain wildcards ([478]Section 4.9). If no filespec
- is given, all backup files in the current directory are selected
- (subject to modification by any switches). Do not include backup
- notation in the filespec.
-
- Explanation:
-
- To avoid destroying preexisting files when a new file arrives that has
- the same name, C-Kermit backs up the old file by appending a "backup
- number" to its name. In UNIX, the backup suffix consists of a period, a
- tilde, a number, and another tilde. For example, if a file called
- oofa.txt exists and a new oofa.txt file arrives, the original is
- renamed to oofa.txt.~1~. If another oofa.txt file arrives, the existing
- one is renamed to oofa.txt.~2~. And so on. This system is compatible
- with the one used by EMACS. Thus over time, if you receive a lot of
- files with C-Kermit or edit them with EMACS, backup files can build up.
- The new PURGE command lets you clean out accumulated backup files:
-
- Optional switches include the standard file-selection switches
- presented in [479]Section 1.5.4, plus all the switches listed above for
- the DELETE command, plus:
-
- /KEEP:n
- Retains the n most recent (highest-numbered) backup files for
- each file. For example, if oofa.txt, oofa.txt.~1~, oofa.txt.~2~,
- oofa.txt.~10~, oofa.txt.~12~, and oofa.txt.~100~ exist, "purge
- /keep:2 oofa.txt" deletes oofa.txt.~1~, oofa.txt.~2~, and
- oofa.txt.~10~, and keeps oofa.txt, oofa.txt.~12~, and
- oofa.txt.~100~. If /KEEP is given without a number, one (the
- highest numbered) backup file is kept.
-
- CAUTION: The PURGE command should be used only when *.~*~ files truly
- are backup files. This is the case for EMACS, and it is the DEFAULT for
- C-Kermit. However, if C-Kermit's FILE COLLISION has been set to RENAME,
- newly received files will look like backup files. In that case, don't
- use the PURGE command or you'll be removing new files rather than old
- ones. (Use SHOW FILE to find the FILE COLLISION setting.)
-
- The PURGE command is presently available only in UNIX. The command
- succeeds if it deleted any files, or if it deleted no files but there
- were no errors. It fails if it deleted no files and there were errors
- (i.e. deletion was attempted but failed). In VMS, backup file versions
- are handled automatically by the OS, and a PURGE command can be used at
- the VMS prompt to clean them up.
-
- If you want certain switches to be supplied automatically with each
- DELETE or PURGE command, you can set them with SET OPTIONS
- ([480]Section 1.5.5) and you can display any such settings with SHOW
- OPTIONS. Of course you can override them on a per-command basis by
- including switches in your PURGE or DELETE command.
-
- Also see SET FILE COLLISION, SHOW FILE, SEND /NOBACKUP, SET SEND
- BACKUP, and DIRECTORY /[NO]BACKUP.
-
-4.6. Starting the Remote Kermit Server Automatically
-
- As noted on pages 275-276 of [481]Using C-Kermit 2nd edition, you can
- have Kermit send "kermit receive" commands automatically when it is in
- local mode and you give a SEND or similar command, to start the remote
- Kermit receiver in case it is not already started. The "kermit receive"
- commands are specified by:
-
- SET PROTOCOL KERMIT binary-receive-command text-receive-command
-
- As of version 7.0, a Kermit protocol option has been added to send a
- string to the host in advance of any Kermit packets when you give a
- GET-class or REMOTE command. This will switch the remote C-Kermit into
- the appropriate mode or, if the remote system is at a system command
- (shell) prompt, execute the string on the remote system. The new syntax
- of the SET PROTOCOL KERMIT command is:
-
- SET PROTOCOL KERMIT [ s1 [ s2 [ s3 ] ] ]
-
- where:
-
- Default Meaning
- s1 {kermit -ir} Remote "kermit receive in binary mode" command.
- s2 {kermit -r} Remote "kermit receive in text mode" command.
- s3 {kermit -x} Remote "start kermit server" command.
-
- NOTE: If the remote Kermit is 6.0, the following are recommended for
- fast startup and high-performance file transfer (see Appendix I in
- [482]Using C-Kermit, second Edition, for command-line options):
-
- s1 kermit -YQir (Kermit receive binary, skip init file, fast.)
- s2 kermit -YQTr (Kermit receive text, skip init file, fast.)
- s3 kermit -YQx (Kermit server, skip init file, fast.)
-
- If the remote is C-Kermit 7.0 or later, change the -x option (enter
- server mode) to -O (uppercase letter O), which means "enter server mode
- for One transaction only); this way, it is not stuck in server after
- the transfer. Also note that the Q is redundant in version 7.0, since
- fast Kermit protocol settings are now the default.
-
- Note that in case the C-Kermit executable is called "wermit" or
- "ckermit" you can change "kermit" in the strings above to "wermit" or
- "ckermit" and C-Kermit 7.0 or later will recognize these as synonyms
- for "kermit", in case it is at its command prompt when one of these
- strings is sent to it.
-
-4.7. File-Transfer Command Switches
-
- Over the years, various new methods of transferring a file have
- accumulated, until we had, in addition to the SEND command, also MOVE
- (send and then delete), MAIL (send as email), REMOTE PRINT (send to be
- printed), CSEND (send the output of a command), PSEND (send a part of a
- file), BSEND (send in binary mode), RESEND (resume an interrupted
- SEND), etc etc. Similarly: GET, REGET, CGET, RETRIEVE, and so on.
-
- Not only is it confusing to have different names for these commands,
- many of which are not real words, but this also does not allow all
- combinations, like "send a file as mail, then delete it".
-
- In C-Kermit 7.0, the SEND, GET, and RECEIVE commands were restructured
- to accept modifier switches (switches are explained in [483]Section
- 1.5).
-
-4.7.1. SEND Command Switches
-
- Without switches, the SEND command still works exactly as before:
-
- send oofa.txt ; send a single file
- send oofa.* ; send multiple files
- send oofa.txt x.x ; send oofa.txt as x.x (tell receiver its name is x.x)
- send ; send from SEND-LIST
-
- But now the following modifier switches may be included between "send"
- and the filename. Zero, one, two, or more switches may be included in
- any combination that makes sense. Switch names (such as /BINARY) can be
- abbreviated, just like any other keywords. Most of these switches work
- only when using Kermit protocol (/TEXT and /BINARY are the exceptions).
-
- /AFTER:date-time
- Specifies that only those files modified (or, in VMS, created)
- after the given date-time (see [484]Section 1.6) are to be sent.
- Examples:
-
- send /text /after:{2-Feb-1997 10:28:30} *.txt
- send /text /after:\fdate(oofa.txt) *.txt
-
- Synonym: /SINCE.
-
- /ARRAY:arrayname
- Specifies that instead of sending a file, C-Kermit is to send
- the contents of the given array. Since an array does not have a
- filename, you should include an /AS-NAME switch to specify the
- name under which the array is to be sent (if you do not, the
- name "_array_x_" is used, where 'x' is replaced by the array
- designator). See [485]section 7.10 for array-name syntax. As
- noted in that section, you can also include a range to have a
- segment of the array sent, rather than the whole thing; for
- example: "send /array:&a[100:199]". It is strongly recommended
- that you accompany the /ARRAY switch with a /TEXT or /BINARY
- switch to force the desired transfer mode, since otherwise the
- various automatic mechanisms might switch to binary mode when
- you really wanted text, or vice versa. In text mode a line
- terminator is added to the end of each array element, but not in
- binary mode. For details and examples see [486]Section 7.10.11.
-
- /AS-NAME:text
- Specifies "text" as the name to send the file under. You can
- also still specify the as-name as the second filename on the
- SEND command line. The following two commands are equivalent:
-
- send oofa.txt oofa.new
- send /as:oofa.new oofa.txt
-
- /BEFORE:date-time
- Specifies that only those files modified (or, in VMS, created)
- before the given date-time ([487]Section 1.6) are to be sent.
-
- /BINARY
- Performs this transfer in binary mode without affecting the
- global transfer mode, overriding not only the FILE TYPE and
- TRANSFER MODE settings, but also the FILE PATTERN setting, but
- for this SEND command only. In other words, SEND /BINARY means
- what it says: send the file in binary mode, regardless of any
- other settings. Example:
-
- set file type text ; Set global transfer mode to text
- send /binary oofa.zip ; Send a file in binary
- send oofa.txt ; This one is sent in text mode
-
- /COMMAND
- SEND /COMMAND is equivalent to CSEND ([488]Section 4.2.2) -- it
- says to send the output from a command, rather than the contents
- of a file. The first "filename" on the SEND command line is
- interpreted as the name of a command; the second (if any) is the
- as-name. Examples:
-
- send /command {grep Sunday oofa.txt} sunday.txt
- send /as-name:sunday.txt /command {grep Sunday oofa.txt}
- send /bin /command {tar cf - . | gzip -c} {!gunzip -c | tar xf -}
-
- /DELETE
- Deletes the file (or each file in the group) after it has been
- sent successfully (but does not delete it if it was not sent
- successfully). SEND /DELETE is equivalent to MOVE. Has no effect
- when used with /COMMAND. Example:
-
- send /delete *.log
-
- /DOTFILES
- (UNIX and OS-9 only) Normally files whose names begin with "."
- are skipped when matching wildcards that do not also begin with
- ".". Include /DOTFILES to force these files to be included too.
-
- /RECURSIVE
- Descend the through the directory tree when locating files to
- send. Automatically sets /PATHNAMES:RELATIVE. Explained in
- [489]Section 4.11 .
-
- /EXCEPT:pattern
- See [490]Section 1.5.4.
-
- /NOBACKUP
- This means to skip backup files when sending, even if they match
- the SEND file specification. This is equivalent to using SEND
- /EXCEPT and including *.~[0-9]*~ in the exception list (or *.~*~
- if Kermit was built without pattern-matching support; see
- [491]Section 4.9.1). Including this switch is equivalent to
- giving SET SEND BACKUP OFF ([492]Section 4.0.6) prior to SEND,
- except its effect is local to the SEND command with which it was
- given.
-
- /NODOTFILES
- The opposite of /DOTFILES (q.v.)
-
- /FILENAMES:{CONVERTED,LITERAL}
- Use this switch to override the current global SET FILE NAMES
- setting for this transfer only.
-
- /FILTER:command
- This specifies a filter to pass the file through before sending
- it. See the [493]section on file-transfer pipes and filters. The
- /FILTER switch applies only to the file-transfer command it is
- given with; it does not affect the global SEND FILTER setting,
- if any.
-
- /IMAGE
- VMS: Sends in image mode. Non-VMS: same as /BINARY.
-
- /LABELED
- VMS and OS/2 only: Sends in labeled mode.
-
- /LARGER-THAN:number
- Specifies that only those files that are longer than the given
- number of bytes are to be sent.
-
- /LISTFILE:filename
- Specifies that the files to be sent are listed in a file with
- the given filename. The file contains one filename per line.
- These filenames are not checked in any way; each filename is
- taken and does not use or depend on any Kermit-specific syntax.
- In particular, backslashes are not treated specially, leading
- and trailing spaces are not stripped, etc. However, if a
- filename contains wildcards, they are expanded. Example: If a
- file named files.txt contains the following lines:
-
- blah.txt
- oofa*
- x.x
-
- (but without leading or trailing spaces), then the C-Kermit
- command "send /listfile:files.txt" will send the files blah.txt,
- x.x, and all files whose names start with "oofa", assuming the
- files exist and are readable. The /LISTFILE switch, can, of
- course, be used with other switches when it makes sense, for
- example, /EXCEPT, /BINARY, /AFTER, /SMALLER, /MOVE-TO, /DELETE,
- /AS-NAME with a template, etc.
-
- /MAIL:address
- Sends the file as e-mail to the given address or addresses.
- "send /mail:address filename" is equivalent to "mail filename
- address". You can include multiple addresses separated by
- commas. Examples:
-
- send /mail:kermit-support@columbia.edu packet.log
- send /mail:cmg,fdc,jrd oofa.txt
-
- As with any switch argument, if the address or address list
- contains any spaces, you must enclose it in braces. The format
- of the addresses must agree with that understood by the
- mail-sending program on the receiver's computer.
-
- /MOVE-TO:directory-name
- Specifies that after each (or the only) source file is sent
- successfully, and ONLY if it is sent successfully, it should be
- moved to the named directory. If the directory name contains
- spaces, enclose it in braces. If the directory does not exist,
- it is created if possible; if it can't be created, the command
- fails and an error message is printed. Example:
-
- send /text /move-to:/users/olga/backup/ *.txt
-
- /NOT-AFTER:date-time
- Specifies that only those files modified at or before the given
- date and time are to be sent.
-
- /NOT-BEFORE:date-time
- Specifies that only those files modified at or after the given
- date and time are to be sent.
-
- /PATHNAMES:{OFF,ABSOLUTE,RELATIVE}
- Use this switch to override the current global SET SEND
- PATHNAMES setting for this transfer only. /PATHNAMES:ABSOLUTE or
- RELATIVE also sets /FILENAMES:LITERAL (also for this transfer
- only) since pathnames are not sent otherwise.
-
- /RENAME-TO:text
- Specifies that after the (or each) source file is sent
- successfully, and ONLY if it is sent successfully, it should be
- renamed to the name given. If the name contains spaces, enclose
- it in braces. If a file group is being sent, then the "text"
- must contain a variable reference such as \v(filename) (see
- [494]Section 4.1). Example:
-
- send /rename-to:ok_\v(filename) *.*
-
- This sends each file in the current directory and if it was sent
- successfully, changes its name to begin with "ok_".
-
- /SMALLER-THAN:number
- Specifies that only those files that are smaller than the given
- number of bytes are to be sent.
-
- /SUBJECT:text
- Subject for email. Actually, this is just a synonym for
- /AS-NAME. If the text includes spaces, you must enclose it in
- braces. If you don't specify a subject (or as-name), the name of
- the file is used as the subject. Example:
-
- send /mail:kermit-support@columbia.edu /subj:{As requested} packet.log
-
- /PRINT:options
- Sends the file to be printed, optionally specifying options for
- the printer. Equivalent to REMOTE PRINT filename options.
- Examples:
-
- send /print oofa.txt ; No options.
- send /print:/copies=3 oofa.txt ; "/copies=3" is a VMS PRINT switch.
- send /print:-#3 oofa.txt ; "-#3" is a UNIX lpr switch.
-
- /PROTOCOL:name
- Uses the given protocol to send the file (Kermit, Zmodem, etc)
- for this transfer without changing global protocol. Only
- available in Kermit 95, UNIX, and OS-9. Example:
-
- set protocol kermit ; Set global protocol
- send /proto:zmodem /bin oofa.zip ; Send just this file with Zmodem
- send oofa.txt ; This file is sent with Kermit
-
- /QUIET
- When sending in local mode, this suppresses the file-transfer
- display.
-
- /RECOVER
- Used to recover from a previously interrupted transfer; SEND
- /RECOVER is equivalent to RESEND. Recovery only works in binary
- mode; SEND /RECOVER and RESEND include an implied /BINARY
- switch. Even then, recovery will successful only if (a) the
- original (interrupted) transfer was also in binary mode, or (b)
- if it was in text mode, the two Kermit programs run on platforms
- where text-mode transfers are not length-changing.
-
- /STARTING:number
- Starts sending the file from the given byte position. SEND
- /STARTING:n filename is equivalent to PSEND filename n.
-
- /TEXT
- Performs this transfer in text mode without affecting the global
- transfer mode, overriding not only the FILE TYPE and TRANSFER
- MODE settings, but also the FILE PATTERN setting, for this SEND
- command only. In other words, SEND /TEXT really send the file in
- text mode, regardless of any other settings or negotiations.
-
- About mail... Refer to [495]Section 4.7.1. The same rules apply as for
- file transfer. If you are mailing multiple files, you can't use an
- as-name (in this case, a subject) unless it contains replacement
- variables like \v(filenum). For example, if you:
-
- send /mail:somebody@xyz.com *.txt
-
- Then each file will arrive as a separate email message with its name as
- the subject. But if you:
-
- send /mail:somebody@xyz.com /subject:{Here is a file} *.txt
-
- Then each file message will have the same subject, which is probably
- not what you want. You can get around this with constructions like:
-
- send /mail:somebody@xyz.com /subject:{Here is \v(filename)} *.txt
-
- which embed the filename in the subject.
-
- The MOVE, CSEND, MAIL, and RESEND commands now also accept the same
- switches. And the switches are also operative when sending from a
- SEND-LIST (see [496]Using C-Kermit, 2nd Ed, pp.191-192), so, for
- example, it is now possible to SEND /PRINT or SEND /MAIL from a
- SEND-LIST.
-
- The MSEND and MMOVE commands also take switches, but not all of them.
- With these commands, which take an arbitrary list of filespecs, you can
- use /BINARY, /DELETE, /MAIL, /PRINT, /PROTOCOL, /QUIET, /RECOVER, and
- /TEXT (and /IMAGE or /LABELED, depending on the platform). MMOVE is
- equivalent to MSEND /DELETE. (If you want to send a group of files, but
- in mixed transfer modes with per-file as-names, use ADD SEND-LIST and
- then SEND.)
-
- The MSEND/MMOVE switches come before the filenames, and apply to all of
- them:
-
- msend /print /text *.log oofa.txt /etc/motd
-
- If you type any of these commands (SEND, CSEND, MSEND, etc) followed by
- a question mark (?), you will see a list of the switches you can use.
- If you want to see a list of filenames, you'll need to type something
- like "send ./?" (UNIX, OS/2, Windows, etc), or "send []?" (VMS), etc.
- Of course, you can also type pieces of a filename (anything that does
- not start with "/") and then "?" to get a list of filenames that start
- that way; e.g. "send x.?" still works as before.
-
- In UNIX, where "/" is also the directory separator, there is usually no
- ambiguity between a fully-specified pathname and a switch, except when
- a file in the root directory has the same name as a switch (as noted in
- [497]Section 1.5):
-
- send /etc/motd ; Works as expected
- send /command ; ???
-
- The second example interprets "/command" as a switch, not a filename.
- To send a file actually called "command" in the root directory, use:
-
- send {/command}
-
- or other system-dependent forms such as //command, /./command,
- c:/command, etc, or cd to / and then "send command".
-
-4.7.2. GET Command Switches
-
- Without switches, the GET command still works about the same as before:
-
- get oofa.txt ; GET a single file
- get oofa.* ; GET multiple files
-
- However, the mechanism for including an "as-name" has changed.
- Previously, in order to include an as-name, you were required to use
- the "multiline" form of GET:
-
- get
- remote-filespec
- local-name
-
- This was because the remote filespec might contain spaces, and so there
- would be no good way of telling where it ended and where the local name
- began, e.g:
-
- get profile exec a foo
-
- But now since we can use {braces} for grouping, we don't need the
- multiline GET form any more, and in fact, support for it has been
- removed. If you give a GET command by itself on a line, it fails and an
- error message is printed. The new form is:
-
- GET [ switches... ] remote-name [ local-name ]
- Ask the server to send the file whose name is remote-name. If
- the optional local-name is given, store it locally under this
- name. If the remote-name or local-name contains spaces, they
- must be enclosed in braces:
-
- get {profile exec a} foo
- get oofa.txt {~/My Files/Oofa text}
-
- If you want to give a list of remote file specifications, use the MGET
- command:
-
- MGET [ switches... ] remote-name [ remote-name [ remote-name ... ] ]
- Ask the server to send the files whose names are given.
-
- Now you can also include modifier switches between GET or MGET and the
- remote-name; most of the same switches as SEND:
-
- /AS-NAME:text
- Specifies "text" as the name to store the incoming file under.
- (This switch is not available for MGET.) You can also still
- specify the as-name as the second filename on the GET command
- line. The following two commands are equivalent:
-
- get oofa.txt oofa.new
- get /as:oofa.new oofa.txt
-
- /BINARY
- Tells the server to send the given file(s) in binary mode
- without affecting the global transfer mode. Example:
-
- set file type text ; Set global transfer mode to text
- get /binary oofa.zip ; get a file in binary mode
- get oofa.txt ; This one is transferred in text mode
-
- Or, perhaps more to the point:
-
- get /binary foo.txt ; where "*.txt" is a text-pattern
-
- This has the expected effect only if the server is C-Kermit 7.0
- or later or K95 1.1.19 or later.
-
- /COMMAND
- GET /COMMAND is equivalent to CGET ([498]Section 4.2.2) -- it
- says to receive the file into the standard input of a command,
- rather than saving it on disk. The /AS-NAME or the second
- "filename" on the GET command line is interpreted as the name of
- a command. Examples:
-
- get /command sunday.txt {grep Sunday oofa.txt}
- get /command /as-name:{grep Sunday oofa.txt} sunday.txt
- get /bin /command {!gunzip -c | tar xf -} {tar cf - . | gzip -c}
-
- /DELETE
- Asks the Kermit server to delete the file (or each file in the
- group) after it has been transferred successfully (but not to
- delete it if it was not sent successfully). GET /DELETE is
- equivalent to RETRIEVE. Example:
-
- get /delete *.log
-
- /EXCEPT:pattern
- Specifies that any files whose names match the pattern, which
- can be a regular filename, or may contain "*" and/or "?"
- metacharacters, are to be refused upon arrival. To specify
- multiple patterns (up to 8), use outer braces around the group,
- and inner braces around each pattern:
-
- /EXCEPT:{{pattern1}{pattern2}...}
-
- See the description of SEND /EXCEPT in [499]Section 4.7.1 for
- examples, etc. Refusal is accomplished using the Attribute
- Rejection mechanism (reason "name"), which works only when
- Attribute packets have been successfully negotiated.
-
- /FILENAMES:{CONVERTED,LITERAL}
- Use this switch to override the current global SET FILE NAMES
- setting for this transfer only.
-
- /FILTER:command
- This specifies a filter to pass the incoming file through before
- writing to disk. See the [500]section on file-transfer pipes and
- filters. The /FILTER switch applies only to the file-transfer
- command it is given with; it does not affect the global RECEIVE
- FILTER setting, if any.
-
- /IMAGE
- VMS: Transfer in image mode. Non-VMS: same as /BINARY.
-
- /LABELED
- VMS and OS/2 only: Specifies labeled transfer mode.
-
- /MOVE-TO:directory
- This tells C-Kermit to move each file that is successfully
- received to the given directory. Files that are not successfully
- received are not moved. By default, files are not moved.
-
- /PATHNAMES:{OFF,ABSOLUTE,RELATIVE,AUTO}
- Use this switch to override the current global SET RECEIVE
- PATHNAMES setting for this transfer only. /PATHNAMES:ABSOLUTE or
- RELATIVE also sets /FILENAMES:LITERAL (also for this transfer
- only) since incoming pathnames would not be treated as pathnames
- otherwise. See [501]Section 4.10.
-
- /QUIET
- When sending in local mode, this suppresses the file-transfer
- display.
-
- /RECOVER
- Used to recover from a previously interrupted transfer; GET
- /RECOVER is equivalent to REGET. Recovery only works in binary
- mode; SEND /RECOVER and RESEND include an implied /BINARY
- switch. Even then, recovery will successful only if (a) the
- original (interrupted) transfer was also in binary mode, or (b)
- if it was in text mode, the two Kermit programs run on platforms
- where text-mode transfers are not length-changing.
-
- /RECURSIVE
- Tells the server that the GET file specification applies
- recursively. This switch also automatically sets
- /PATHNAMES:RELATIVE in both the server AND the client. When used
- in conjunction with /DELETE, this "moves" a directory tree from
- the server's computer to the client's computer (except that only
- regular files are deleted from the server's computer, not
- directories; thus the original directories will be left, but
- will contain no files). Note that all servers that support
- /RECURSIVE do not necessarily do so in combination with other
- switches, such as /RECOVER. (Servers that do include C-Kermit
- 7.0 and later, K95 1.1.19 and later.)
-
- /RENAME-TO:string
- This tells C-Kermit to rename each file that is successfully
- received to the given string. Files that are not successfully
- received are not renamed. By default, files are not renamed. The
- string can be a literal string, which is appropriate when only
- one file is being received, or it can contain one or more
- variables that are to be evaluated at the time each file is
- received, such as \v(filename), \v(filenumber), \v(ntime),
- \v(pid), \v(user), etc. WARNING: if you give a literal string
- and more than one file arrives, each incoming file will be given
- the same name (but SET FILE COLLISION BACKUP or RENAME can be
- used to keep the incoming files from overwriting each other).
-
- /TEXT
- Tells the server to perform this transfer in text mode without
- affecting its global transfer mode. See /BINARY for additional
- info.
-
- The /MAIL and /PRINT options are not available (as they are for SEND),
- but you can use /COMMAND to achieve the same effect, as in these UNIX
- examples:
-
- get /command oofa.txt {mail kermit@columbia.edu}
- get /command oofa.txt lpr
-
- In OS/2 or Windows, you can GET and print like this:
-
- get oofa.txt prn
-
- The CGET, REGET, RETRIEVE commands also accept the same switches as
- GET. CGET automatically sets /COMMAND; REGET automatically sets
- /RECOVER and /BINARY, and RETRIEVE automatically sets /DELETE.
-
-4.7.3. RECEIVE Command Switches
-
- Without switches, the RECEIVE command still works as before:
-
- receive ; Receives files under their own names
- receive /tmp ; Ditto, but into the /tmp directory
- r ; Same as "receive"
- receive foo.txt ; Receives a file and renames to foo.txt
-
- Now you can also include modifier switches may be included between
- "receive" and the as-name; most of the same switches as GET:
-
- /AS-NAME:text
- Specifies "text" as the name to store the incoming file under.
- You can also still specify the as-name as a filename on the
- command line. The following two commands are equivalent:
-
- r oofa.new
- r /as:oofa.new
-
- /BINARY
- Performs this transfer in binary mode without affecting the
- global transfer mode. NOTE: This does not override the incoming
- filetype (as it does with GET), so this switch is useful only if
- ATTRIBUTE TYPE is OFF, or if the other Kermit does not send a
- TYPE (text or binary) attribute. In any case, it has no affect
- whatsoever on the file sender.
-
- /COMMAND
- RECEIVE /COMMAND is equivalent to CRECEIVE ([502]Section 4.2.2)
- -- it says to receive the file into the standard input of a
- command, rather than saving it on disk. The /AS-NAME or the
- "filename" on the RECEIVE command line is interpreted as the
- name of a command.
-
- r /command {grep Sunday oofa.txt}
- r /command /as-name:{grep Sunday oofa.txt}
- r /bin /command {tar cf - . | gzip -c}
-
- /EXCEPT:pattern
- Specifies that any files whose names match the pattern, which
- can be a regular filename, or may contain "*" and/or "?"
- metacharacters, are to be refused upon arrival. To specify
- multiple patterns (up to 8), use outer braces around the group,
- and inner braces around each pattern:
-
- /EXCEPT:{{pattern1}{pattern2}...}
-
- See the description of SEND /EXCEPT in [503]Section 4.7.1 for
- examples, etc. Refusal is accomplished using the Attribute
- Rejection mechanism (reason "name"), which works only when
- Attribute packets have been successfully negotiated.
-
- /FILENAMES:{CONVERTED,LITERAL}
- Use this switch to override the current global SET FILE NAMES
- setting for this transfer only.
-
- /FILTER:command
- This specifies a filter to pass the incoming file through before
- writing to disk. See the [504]section on file-transfer pipes and
- filters. The /FILTER switch applies only to the file-transfer
- command it is given with; it does not affect the global RECEIVE
- FILTER setting, if any.
-
- /IMAGE
- VMS: Transfer in image mode. Non-VMS: same as /BINARY. See
- comments under RECEIVE /BINARY.
-
- /LABELED
- VMS and OS/2 only: Specifies labeled transfer mode. See comments
- under RECEIVE /BINARY.
-
- /MOVE-TO:directory
- This tells C-Kermit to move each file that is successfully
- received to the given directory. Files that are not successfully
- received are not moved. By default, files are not moved.
-
- /PATHNAMES:{ABSOLUTE,RELATIVE,OFF,AUTO}
- Use this switch to override the current global SET RECEIVE
- PATHNAMES setting for this transfer only. See [505]Section 4.10.
-
- /RECURSIVE
- When used with the RECEIVE command, /RECURSIVE is simply a
- synonym for /PATHNAMES:RELATIVE.
-
- /RENAME-TO:string
- This tells C-Kermit to rename each file that is successfully
- received to the given string. Files that are not successfully
- received are not renamed. By default, files are not renamed. The
- string can be a literal string, which is appropriate when only
- one file is being received, or it can contain one or more
- variables that are to be evaluated at the time each file is
- received, such as \v(filename), \v(filenumber), \v(ntime),
- \v(pid), \v(user), etc. WARNING: if you give a literal string
- and more than one file arrives, each incoming file will be given
- the same name (but SET FILE COLLISION BACKUP or RENAME can be
- used to keep the incoming files from overwriting each other).
-
- /QUIET
- When receiving in local mode, this suppresses the file-transfer
- display.
-
- /TEXT
- Receives in text mode without affecting the global transfer
- mode. See comments under RECEIVE /BINARY.
-
- The /MAIL and /PRINT options are not available, but you can use
- /COMMAND to achieve the same effect, as in these UNIX examples:
-
- r /command {mail kermit@columbia.edu}
- r /command lpr
-
- In OS/2 or Windows, you can RECEIVE and print like this:
-
- receive prn
-
- The CRECEIVE command now also accepts the same switches.
-
-4.8. Minor Kermit Protocol Improvements
-
-4.8.1. Multiple Attribute Packets
-
- C-Kermit 7.0 now sends more than one Attribute packet if a file's
- attributes do not fit into a single packet of the negotiated length. If
- a particular attribute (such as file creation date-time) does not fit
- within the negotiated length (which will only happen when the
- negotiated length is around 20 or less), that attribute is not sent at
- all.
-
-4.8.2. Very Short Packets
-
- There are certain situations where extremely short packets must be
- used; 20 or 30 bytes at most. This can happen when one or more devices
- along the communication path have very small buffers and lack an
- effective means of flow control. Examples are sometimes cited involving
- radio modems.
-
- When the maximum packet length is shorter than certain packets that
- would be sent, those packets are either truncated or else broken up
- into multiple packets. Specifically:
-
- 1. Parameter negotiation packets (I, S, and their ACKs) are truncated
- to the negotiated length. Any parameters that do not fit are reset
- to their default values. There is no provision in the Kermit
- protocol for fragmentation and reassembly of parameter strings.
- 2. File header packets (containing the filename) are simply truncated.
- There is no provision in the Kermit protocol for fragmentation and
- reassembly of filenames.
- 3. Attribute packets are fragmented and reassembled as described in
- 4.8.1 without loss of data, except in case a field will not fit at
- all in the negotiated length (the longest attribute is usually the
- date and time of file creation/modification) because of the rule
- that attributes may not be broken across packets.
- 4. Data packets and other packets are unaffected -- they can be as
- short as they need to be, within reason.
-
-4.9. Wildcard / File Group Expansion
-
- "Wildcard" refers to the notation used in filenames to specify a group
- of files by pattern matching.
-
-4.9.1. In UNIX C-Kermit
-
- Prior to C-Kermit 7.0, C-Kermit was capable of expanding wildcard
- strings containing only the "metacharacters" '*' and '?':
-
- *
- Matches any sequence of zero or more characters. For example:
- "ck*.c" matches all files whose names start with "ck" and end
- with ".c", including "ck.c".
-
- ?
- Matches any single character. For example, "ck?.c" matches all
- files whose names are exactly 5 characters long and start with
- "ck" and end with ".c". When typing commands at the prompt, you
- must precede any question mark to be used for matching by a
- backslash (\) to override the normal function of question mark,
- which is providing menus and file lists.
-
- C-Kermit 7.0 adds the additional features that users of ksh, csh, and
- bash are accustomed to:
-
- [abc]
- Square brackets enclosing a list of characters matches any
- single character in the list. Example: ckuusr.[ch] matches
- ckuusr.c and ckuusr.h.
-
- [a-z]
- Square brackets enclosing a range of characters; the hyphen
- separates the low and high elements of the range. For example,
- [a-z] matches any character from a to z.
-
- [acdm-z]
- Lists and ranges may be combined. This example matches a, c, d,
- or m through z.
-
- {string1,string2,...}
- Braces enclose a list of strings to be matched. For example:
- ck{ufio,vcon,cmai}.c matches ckufio.c, ckvcon.c, or ckcmai.c.
- The strings may themselves contain metacharacters, bracket
- lists, or indeed, other lists of strings, but (when matching
- filenames) they may not contain directory separators.
-
- Thus, the metacharacters in filenames (and in any other field
- that can be a pattern, such as the IF MATCH pattern, SEND or GET
- exception lists, etc) are:
-
- * ? [ {
-
- And within braces only, comma (,) is a metacharacter.
-
- To include a metacharacter in a pattern literally, precede it with a
- backslash '\' (or two if you are passing the pattern to a macro).
- Examples:
-
- send a*b ; Send all files whose names start with 'a' and end with 'b'.
- send a?b ; Ditto, but the name must be exactly three characters long.
- send a[a-z]b ; Ditto, but the second character must be a lowercase letter.
- send a[x\-z]b ; Ditto, except the second character must be 'x', '-', or 'y'.
- send a[ghi]b ; Ditto, except the second character must be 'g', 'h', or 'i'.
- send a[?*]b ; Ditto, except the second character must be '?' or '*'.
- send a[\?\*]b ; Same as previous.
- send *?[a-z]* ; All files with names containing at least one character
- ; that is followed by a lowercase letter.
-
- Or, more practically:
-
- send ck[cuw]*.[cwh] ; Send the UNIX C-Kermit source files.
-
- To refer to the C-Kermit sources files and makefile all in one
- filespec:
-
- {{makefile,ck[cuw]*.[cwh]}}
-
- (NOTE: if the entire pattern is a {stringlist}, you must enclose it it
- TWO pairs of braces, since the SEND command strips the outer brace
- pair, because of the "enclose in braces if the filename contains
- spaces" rule).
-
- If the makefile is called ckuker.mak:
-
- ck[cuw]*.{[cwh],mak}
-
- (NOTE: double braces are not needed here since the pattern does not
- both begin and end with a brace.)
-
- To add in all the C-Kermit text files:
-
- ck[cuw]*.{[cwh],mak,txt}
-
- All of these features can be used anywhere you would type a filename
- that is allowed to contain wildcards.
-
- When you are typing at the command prompt, an extra level of quoting is
- required for the '?' character to defeat its regular function of
- producing a list of files that match what you have typed so far, for
- example:
-
- send ck[cu]?
-
- lists all the files whose names start with ckc and cku. If you quote
- the question mark, it is used as a pattern-matching character, for
- example:
-
- send ck\?[ft]io.c
-
- sends all the file and communications i/o modules for all the
- platforms: ckufio.c, ckutio.c, ckvfio.c, ckvtio.c, etc.
-
- If, however, a filename actually contains a question mark and you need
- to refer to it on the command line, you must use three (3) backslashes.
- For example, if the file is actually called ck?fio.c, you would use:
-
- send ck\\\?fio.c
-
- Further notes on quoting:
-
- * A single backslash is sufficient for quoting a special character at
- the command prompt or in a command file. However, when passing
- patterns to macros you'll need double backslashes, and when
- referring to these patterns within the macro, you'll need to use
- \fcontents(\%1) (see [506]Section 1.11.5). You should enclose macro
- argument references in braces in case grouped arguments were
- passed. Example:
- define ismatch {
- if match {\fcont(\%1)} {\fcont(\%2)} {
- end 0 MATCH
- } else {
- end 1 NO MATCH
- }
- }
- ismatch ab*yz a*\\**z ; Backslash must be doubled
- ismatch {abc def xyz} *b*e*y* ; Braces must be used for grouping
-
- * Watch out for possible conflicts between {} in filename patterns
- and {} used for grouping multiple words into a single field, when
- the pattern has outer braces. For example, in:
- if match {abc xyz} {a* *z} echo THEY MATCH
-
- braces must be used to group "abc xyz" into a single string. Kermit
- strips off the braces before comparing the string with the pattern.
- Therefore:
- if match makefile {makefile,Makefile} echo THEY MATCH
-
- does not work, but:
- if match makefile {{makefile,Makefile}} echo THEY MATCH
-
- does.
- * If you use a pattern that has outer braces, like {*.txt,*.doc}, in
- a field that accepts a pattern list (like SEND /EXCEPT:xxx), you'll
- need to add two extra sets of outer braces:
- send /except:{{{*.txt,*.doc}}} *.*
-
- C-Kermit's new pattern matching capabilities are also used when
- C-Kermit is in server mode, so now you can send requests such as:
-
- get ck[cuw]*.[cwh]
-
- to a C-Kermit server without having to tell it to SET WILD SHELL first.
- Previously this would have required:
-
- mget ckc*.c ckc*.w ckc*.h cku*.c cku*.w cku*.h ckw*.c ckw*.w ckw*.h
-
- The new pattern matching features make SET WILD SHELL redundant, and
- barring any objections, it will eventually be phased out. (One possible
- reason for retaining it would be as an escape mechanism when Kermit
- does not understand the underlying file system.)
-
- By the way, patterns such as these are sometimes referred to as
- "regular expressions", but they are not quite the same. In a true
- regular expression (for example), "*" means "zero or more repetitions
- of the previous item", so (for example), "([0-9]*)" would match zero or
- more digits in parentheses. In Kermit (and in most shells), this
- matches one digit followed by zero or more characters, within
- parentheses. Here are some hints:
-
- * Although you can't match any sequence of digits (or letters, etc),
- you can match (say) 1, 2, or 3 of them in row. For example, the
- following pattern matches Kermit backup files (with backup numbers
- from 1 to 999):
- *.~{[1-9],[1-9][0-9],[1-9][0-9][0-9]}~
-
- * There is presently no NOT operator, so no way to match any
- character or string EXCEPT the one(s) shown.
-
- In other wildcarding news...
-
- * You may now "send xxx" where "xxx" is a directory name, and this
- will send all the files from the directory xxx, as if you had typed
- "send xxx/*". You can also use the special shorthand "send ." to
- send all the files from the current directory.
- * To easily skip over backup files (the ones whose names end like
- .~22~) when sending, you can use SEND /NOBACKUP (see [507]Section
- 4.0.6 for details).
- * When choosing Kermit to expand wildcards, rather than the shell,
- you can choose whether "dot files" -- files whose names begin with
- ".", which are normally "invisible" -- should be matched:
- SET WILD KERMIT /NO-MATCH-DOT-FILES (this is the default)
- SET WILD KERMIT /MATCH-DOT-FILES (this allows matching of "." files)
-
- or include the /DOTFILES or /NODOTFILES switch on the command you
- are using, such as SEND or DIRECTORY.
- * Commands such as DIRECTORY and SEND allow recursive directory
- traversal. There are also new functions for this to use in scripts.
- See [508]Section 4.11 for details.
-
- When building file lists in UNIX, C-Kermit follows symbolic links.
- Because of this, you might encounter any or all of the following
- phenomena:
-
- * Multiple copies of the same file; e.g. one from its real directory
- and others from links to its real directory, if both the real
- directory and the links to it are in the wildcard expansion list.
- * A command might unexpectedly "hang" for a long time because an NFS
- link might not be responding, or the directory you are looking at
- contains a link to a huge directory tree (example: "directory
- /recursive /etc" when /etc/spool is a symlink to /var/spool, which
- is a large organization's incoming email directory, containing tens
- of thousands of subdirectories).
-
- The size of the file list that Kermit can build is limited in most
- C-Kermit implementations. The limit, if any, depends on the
- implementation. Use the SHOW FEATURES command and look in the
- alphabetized options list for MAXWLD to see the value.
-
-4.9.2. In Kermit 95
-
- Kermit 95 1.1.19 and later uses the same pattern matching syntax as in
- UNIX, but (as always) you will encounter numerous difficulties if you
- use backslash (\) as the directory separator. In any command where K95
- parses filenames itself (that is, practically any file-oriented command
- except RUN), you can use forward slash (/) as the directory separator
- to avoid all the nasty conflicts.
-
-4.9.3. In VMS, AOS/VS, OS-9, VOS, etc.
-
- Platforms other than UNIX, Windows 95/98/NT, and OS/2 have their own
- filename matching capabilities that are, in general, different from
- Kermit's built-in ones and in any case might conflict with them. For
- example, [] encloses directory names in VMS.
-
- Nevertheless you can still use all the pattern-matching capabilities
- described in [509]Section 4.9.1 by loading a file list into an array
- (e.g. with \ffiles(*,&a), see [510]Section 4.11.3) and then using IF
- MATCH on the members.
-
-4.10. Additional Pathname Controls
-
- In version 6.0 and earlier, C-Kermit's SET { SEND, RECEIVE } PATHNAMES
- command had only ON and OFF as options. In version 7.0, there are more
- choices:
-
- SET SEND PATHNAMES OFF
- When sending a file, strip all disk/directory information from
- the name. Example: "send /usr/olga/letters/oofa.txt" sends the
- file as "oofa.txt". This applies to actual filenames, not to any
- as-name you might specify.
-
- SET SEND PATHNAMES RELATIVE
- When sending a file, leave the pathname on as given. For
- example, if your current directory is /usr/olga, "send
- letters/oofa.txt" sends the file as "letters/oofa.txt", not
- "/usr/olga/letters/oofa.txt" or "letters.txt".
-
- SET SEND PATHNAMES ABSOLUTE
- When sending a file, convert its name to the full, absolute
- local pathname. For example, if your current directory is
- /usr/olga, "send letters/oofa.txt" sends the file as
- "/usr/olga/letters/oofa.txt". NOTE: Even with this setting,
- device and/or node names are not included. For example, in VMS,
- any node or device name is stripped; in Windows or OS/2, any
- disk letter is stripped.
-
- SET RECEIVE PATHNAMES OFF
- When receiving a file, strip all disk/directory information from
- the name before attempting to store it. This applies to incoming
- filename, not to any as-name you might specify. Example: If a
- file arrives under the name "/usr/olga/letters/oofa.txt" it is
- stored simply as "oofa.txt" in your download directory or, if no
- download directory has been specified, in your current
- directory.
-
- SET RECEIVE PATHNAMES RELATIVE
- When receiving a file, leave the pathname on as it appears in
- the incoming name, but if the incoming name appears to be
- absolute, make it relative to your current or download
- directory. Examples:
-
- + "oofa.txt" is stored as "oofa.txt".
- + "letters/oofa.txt" is stored as "letters/oofa.txt"; the
- "letters" subdirectory is created if it does not already
- exist.
- + "/usr/olga/letters/oofa.txt" is stored as
- "usr/olga/letters/oofa.txt" in your current or download
- directory, and the "usr", "usr/olga", etc, directories are
- created if they do not exist.
-
- SET RECEIVE PATHNAMES ABSOLUTE
- The incoming filename is used as given. Thus it cannot be stored
- unless the given path (if any) already exists or can be created.
- In this case, node, device, or disk designations are NOT
- stripped, since they most likely were given explicitly by the
- user as an as-name, meant to be used as given.
-
- SET RECEIVE PATHNAMES AUTO
- This is the default, and means RELATIVE if the sender tells me
- it is a recursive transfer, OFF otherwise.
-
- Set FILE NAMES CONVERTED now also affects pathnames too. When PATHNAMES
- are RELATIVE or ABSOLUTE and FILE NAMES are CONVERTED, the file sender
- converts its native directory-name format to UNIX format, and the file
- receiver converts from UNIX format to its native one; thus UNIX format
- is the common intermediate representation for directory hierarchies, as
- it is in the ZIP/UNZIP programs (which is why ZIP archives are
- transportable among, UNIX, DOS, and VMS).
-
- Here's an example in which a file is sent from Windows to UNIX with
- relative pathnames and FILE NAMES CONVERTED:
-
- Source name Intermediate name Destination Name
- C:\K95\TMP\OOFA.TXT K95/TMP/OOFA.TXT k95/tmp/oofa.txt
-
- In a more complicated example, we send the same file from Windows to
- VMS:
-
- Source name Intermediate name Destination Name
- C:\K95\TMP\OOFA.TXT K95/TMP/OOFA.TXT [.K95.TMP]OOFA.TXT
-
- (Note that disk letters and device designations are always stripped
- when pathnames are relative).
-
- As you can imagine, as more and more directory formats are considered,
- this approach keeps matters simple: on each platform, Kermit must know
- only its own local format and the common intermediate one. In most
- cases, the receiver can detect which format is used automatically.
-
-4.11. Recursive SEND and GET: Transferring Directory Trees
-
- C-Kermit 7.0 in selected versions (UNIX, VMS, VOS, AOS/VS, Windows, and
- OS/2 at this writing) now permits the SEND command to traverse
- directories "recursively" if you ask it to; that is, to send files from
- the current or specified directory and all of its subdirectories too,
- and their subdirectories, etc. (Some other commands can do this too,
- including DIRECTORY.)
-
- This feature is new to UNIX, Windows, VOS, and OS/2. VMS and AOS/VS
- have always included "wildcard" or "template" characters that allow
- this, and in this case, recursive directory traversal could happen
- behind Kermit's back, i.e. Kermit does not have to do it itself (in
- VMS, the notation is "[...]" or "[directory...]"; in AOS/VS is "#"). In
- C-Kermit 7.0, however, SEND /RECURSIVE is supported by C-Kermit itself
- for VMS.
-
-4.11.1. Command-Line Options
-
- To descend a directory tree when sending files, use the -L command-line
- option to indicate that the send operation is to be recursive, and
- include a name or pattern to be sent. When giving a pattern, you should
- enclose it in quotes to prevent the shell from expanding it. Examples:
-
- $ kermit -Ls "/usr/olga/*" # send all of Olga's files in all her directories
- $ kermit -Ls foo.txt # send all foo.txt files in this directory tree
- $ kermit -Ls "*.txt" # send all .txt files in this directory tree
- $ kermit -Ls "letters/*" # send all files in the letters directory tree
- $ kermit -Ls letters # send all files in the letters directory tree
- $ kermit -Ls "*" # send all files in this directory tree
- $ kermit -Ls . # UNIX only: send all files in this directory tree
- $ kermit -s . # UNIX only: a filename of . implies -L
-
- If you let the shell expand wildcards, Kermit only sends files whose
- names match files in the current or given directory, because the shell
- replaces an unquoted wildcard expression with the list of matching
- files -- and the shell does not build recursive lists. Note that the
- "." notation for the tree rooted at the current directory is allowed
- only in UNIX, since in Windows and OS/2, it means "*.*" (nonrecursive).
-
-4.11.2. The SEND /RECURSIVE Command
-
- If you include the /RECURSIVE switch in a SEND (or MOVE, or similar)
- command, it means to descend the current or specified directory tree
- searching for files whose names match the given name or pattern. Since
- this is not terribly useful unless you also include pathnames with the
- outbound files, the /RECURSIVE switch also includes an implicit
- /PATHNAMES:RELATIVE switch (which you can undo by including an explicit
- /PATHNAMES switch after the /RECURSIVE switch).
-
- Examples:
-
- SEND /RECURSIVE *
- Sends all of the files in the current directory and all the
- files in all of its subdirectories, and all of their
- subdirectories, etc, including their relative pathnames. Empty
- directories are not sent.
-
- SEND /RECURSIVE /PATHNAMES:ABSOLUTE *
- Sends all of the files in the current directory and all the
- files in all of its subdirectories, and all of their
- subdirectories, etc, including their absolute pathnames.
-
- SEND /RECURSIVE /PATHNAMES:OFF *
- Sends all of the files in the current directory and all the
- files in all of its subdirectories, and all of their
- subdirectories, etc, without pathnames.
-
- SEND /RECURSIVE /usr/olga/*
- Sends all of the files in the /usr/olga directory and all the
- files in all of its subdirectories, and all of their
- subdirectories, etc.
-
- SEND /RECURSIVE /usr/olga (or /usr/olga/)
- Same as above. If the name is a directory name (with or without
- a trailing slash), its files are sent, and those of its
- subdirectories, and their subdirectories, etc (see [511]Section
- 4.9).
-
- SEND /RECURSIVE /TEXT /usr/olga/*.txt
- As above, but only files whose names end with ".txt" are sent,
- and they are sent in text mode (as they would be by default
- anyway if SET FILE PATTERNS is ON or AUTO).
-
- SEND .
- UNIX only: Send all the files in the current directory.
-
- SEND /RECURSIVE .
- UNIX only: Sends all of the files in the current directory and
- all of its subdirectories, etc ([512]Section 4.9).
-
- The /RECURSIVE switch is different from most other switches in that its
- effect is immediate (but still local to the command in which it is
- given), because it determines how filenames are to be parsed. For
- example, "send *.txt" fails with a parse error ("No files match") if
- there are no *.txt files in the current directory, but "send /recursive
- *.txt" succeeds if there are ".txt" files anywhere in the tree rooted
- at the current directory.
-
- The /RECURSIVE switch also affects the file lists displayed if you type
- "?" in a filename field. "send ./?" lists the regular files in the
- current directory, but "send /recursive ./?" lists the entire directory
- tree rooted at the current directory.
-
-4.11.3. The GET /RECURSIVE Command
-
- In a client/server setting, the client can also request a recursive
- transfer with:
-
- GET /RECURSIVE [ other switches ] remote-filespec [ local-spec ]
-
- In which remote file specification can be a directory name, a filename,
- a wildcard, or any combination. If the local-spec is not given (and
- PATHNAMES are RELATIVE), incoming files and directories go into the
- current local directory. If local-spec is given and is a directory, it
- becomes the root of the tree into which the incoming files and
- directories are placed. If local-spec has the syntax of a directory
- name (e.g. in UNIX it ends with /), C-Kermit creates the directory and
- then places the incoming files into it. If local-spec is a filename
- (not recommended), then all incoming files are stored with that name
- with collisions handled according to the FILE COLLISION setting.
-
- Again, the normal method for transferring directory trees uses relative
- pathnames, and this is the default when the sender has been given the
- /RECURSIVE switch. The action at the receiver depends on its RECEIVE
- PATHNAMES setting. The default is AUTO, meaning that if the sender
- tells it to expect a recursive transfer, then it should automatically
- switch to relative pathnames for this transfer only; otherwise it obeys
- the RECEIVE PATHNAMES setting of OFF, ABSOLUTE, or RELATIVE.
-
- What happens if a file arrives that has an absolute pathname, when the
- receiver has been told to use only relative pathnames? As a security
- precaution, in this case the receiver treats the name as if it was
- relative. For example, if a file arrives as:
-
- /usr/olga/oofa.txt
-
- The receiver creates a "usr" subdirectory in its current directory, and
- then an "olga" subdirectory under the "usr" subdirectory in which to
- store the incoming file.
-
- Suppose, however there is a sequence of directories:
-
- /usr/olga/a/b/c/d/
-
- in which "a" contains nothing but a subdirectory "b", which in turn
- contains nothing but a subdirectory "c", which in turn contains nothing
- but a subdirectory "d", which contains nothing at all. Thus there are
- no files in the "/usr/olga/a/" tree, and so it is not sent, and
- therefore it is not reproduced on the target computer.
-
-4.11.4. New and Changed File Functions
-
- C-Kermit 7.0 adds the following functions:
-
- \ffiles(pattern[,&a])
- This function has been changed to match only regular files in
- the current or given directory, and to take an optional array
- name as a second argument (explained below).
-
- \fdirectories(pattern[,&a])
- Returns the number of directories that match the given pattern.
- If the pattern does not include a directory, then the search is
- performed in the current directory.
-
- \frfiles(pattern[,&a])
- Returns the number of files in the current or given directory
- and all of its subdirectories, and their subdirectories, etc,
- that match the given pattern. Warning -- this one can take quite
- some time if performed at the root of a large directory tree.
-
- \frdirectories(pattern[,&a])
- Returns the number of directories in the current or given
- directory and all of its subdirectories, and their
- subdirectories, etc, that match the given pattern.
-
- Each of these functions builds up a list of files to be returned by the
- \fnextfile() function, just as \ffiles() always has done. (This can
- also be done with the /ARRAY switch of the DIRECTORY command; see
- [513]Sections 4.5.1 and [514]7.10).
-
- Each of these functions can be given an array name as an optional
- second argument. If an array name is supplied, the array will contain
- the number of files as its 0th element, and the filenames in elements 1
- through last. If the array already existed, its previous contents are
- lost. For example, if the current directory contains two files,
- oofa.txt and foo.bar, then "\ffiles(*,&a)" creates an array \&a[] with
- a dimension of 2, containing the following elements:
-
- \&a[0] = 2
- \&a[1] = oofa.txt
- \&a[2] = foo.bar
-
- If no files match the specification given in the first argument, the
- array gets a dimension of 0, which is the same as undeclaring the
- array.
-
- Note that the order in which the array is filled (and in which
- \fnextfile() returns filenames) is indeterminate (but see [515]Section
- 7.10.5).
-
- Here's an example that builds and prints a list of all the file whose
- names end in .txt in the current directory and all its descendents:
-
- asg \%n \frfiles(*.txt)
- declare \&a[\%n]
- for \%i 1 \%n 1 {
- asg \&a[\%i] \fnextfile()
- echo \flpad(\%i,4). "\&a[\%i]"
- }
-
- Alternatively, using the array method, and then printing the filenames
- in alphabetic order (see [516]Section 7.10.3 and [517]7.10.5):
-
- asg \%n \frfiles(*.txt,&a)
- sort &a
- for \%i 1 \%n 1 {
- echo \flpad(\%i,4). "\&a[\%i]"
- }
-
- Or even more simply:
-
- asg \%n \frfiles(*.txt,&a)
- sort &a
- show array &a
-
- As noted elsewhere, the file lists built by \ffiles(), \frfiles(), etc,
- are now "safe" in the sense that SEND and other file-related commands
- can reference \fnextfile() without resetting the list:
-
- set send pathnames relative
- for \%i 1 \frfiles(*.txt) 1 {
- asg \%a \fnextfile()
- echo Sending \%a...
- send \%a
- if fail break
- }
-
- Copying to an array (as shown on p.398 of [518]Using C-Kermit 2nd Ed)
- is no longer necessary.
-
-4.11.5. Moving Directory Trees Between Like Systems
-
-4.11.5.1. UNIX to UNIX
-
- Transferring a directory tree from one computer to another replicates
- the file sender's arrangement of files and directories on the file
- receiver's computer. Normally this is done using relative pathnames,
- since the user IDs might not be identical on the two computers. Let's
- say both computers are UNIX based, running C-Kermit 7.0 or later. On
- the sending computer (leaving out the connection details, etc):
-
- C-Kermit> cd /usr/olga
- C-Kermit> send /recursive .
-
- The /RECURSIVE switch tells C-Kermit to descend through the directory
- tree and to include relative pathnames on outbound filenames.
-
- On the receiving computer:
-
- C-Kermit> mkdir olgas-files ; Make a new directory.
- C-Kermit> cd olgas-files ; CD to it.
- C-Kermit> receive /recursive ; = /PATHNAMES:RELATIVE
-
- Each Kermit program recognizes that the other is running under UNIX and
- switches to binary mode and literal filenames automatically.
- Directories are automatically created on the receiving system as
- needed. File dates and permissions are automatically reproduced from
- source to destination.
-
-4.11.5.2. VMS to VMS
-
- To send recursively from VMS, simply include the /RECURSIVE switch, for
- example at the sender:
-
- $ kermit
- C-Kermit> cd [olga]
- C-Kermit> send /recursive *.*;0
-
- And at the receiver:
-
- C-Kermit> cd [.olga]
- C-Kermit> receive /recursive
-
- The notation "..." within directory brackets in VMS means "this
- directory and all directories below it"; the /RECURSIVE switch, when
- given to the sender, implies the use of "..." in the file specification
- so you don't have to include "..."; but it makes no difference if you
- do:
-
- $ kermit
- C-Kermit> send /recursive [olga...]*.*;0
-
- And at the receiver:
-
- C-Kermit> cd [.olga]
- C-Kermit> receive /recursive
-
- In either case, since both systems recognize each other as VMS, they
- switch into LABELED transfer mode automatically.
-
-4.11.6. Moving Directory Trees Between Unlike Systems
-
- There are several difficulties with recursive transfers between unlike
- systems:
-
- * File formats can be different, especially text files character sets
- and record formats. This can now be handled by using SET FILE
- PATTERN, SET FILE TEXT-PATTERNS, and SET FILE BINARY-PATTERNS
- ([519]Section 4.3).
- * File naming conventions are different. For example, one system
- might allow (and use) longer filenames than the other. You can tell
- Kermit how to handle file names with the normal "set file names"
- and "set file collision" mechanisms. Most modern Kermits are fairly
- tolerant of illegal filenames and should not fail simply because of
- an incoming filename; rather, it will do its best to convert it to
- a recognizable and unique legal filename.
- * Directory notations can be different, e.g. backslashes instead of
- slashes, brackets, parentheses, spaces, etc. But this is now
- handled by converting pathnames to a standard format during
- transfer ([520]Section 4.10).
-
- So now, for the first time, it is possible to send directory trees
- among any combination of UNIX, DOS, Windows, OS/2, VMS, AOS/VS, etc.
- Here's an example sending files from an HP-UX system (where text files
- are encoded in the HP Roman8 character set) to a PC with K95 (where
- text files are encoded in CP850):
-
- Sender:
- cd xxx ; CD to root of source tree
- set file type binary ; Default transfer mode
- set file character-set hp-roman8 ; Local character set for text files
- set xfer character-set latin1 ; Transfer character set
- set file patterns on ; Enable automatic file-type switching...
- set file binary-patterns *.Z *.gz *.o ; based on these patterns...
- set file text-patterns *.txt *.c *.h ; for binary and text files.
- send /recursive * ; Send all the file in this directory tree
-
- Receiver:
- cd yyy ; CD to root of destination tree
- set file character-set cp850 ; Local character set for text files
- receive /pathnames:relative ; Receive with pathnames
-
- Notes:
- * Replace "xxx" and "yyy" with the desired directories.
- * Replace the file character sets appropriately.
- * Change the patterns as needed (or just use the built-in default
- lists).
- * SEND /RECURSIVE also implies /PATHNAMES:RELATIVE.
- * The file sender tells the file receiver the transfer mode of each
- file.
- * The file sender tells the file receiver the transfer character set.
- * By default, destination file dates will be the same as on the
- source.
- * Many of the settings shown might already be set by default.
- * See [521]Sections 4.3, [522]4.10, and [523]4.15 for additional
- explanation.
-
- If you are refreshing an existing directory on the destination
- computer, use "set file collision update" or other appropriate file
- collision option to handle filename collisions.
-
-4.12. Where Did My File Go?
-
- Now that Kermit can be started by clicking on desktop icons (thus
- obscuring the concept of "current directory"), and can have a download
- directory, and can create directories for incoming files on the fly,
- etc, sometimes it is easy to lose a file after transfer. Of course, if
- you keep a transaction log:
-
- LOG TRANSACTIONS
-
- it will record the fate and final resting place of each file. But in
- case you did not keep a log, the new command:
-
- WHERE
-
- added in C-Kermit 7.0, gives you as much information as it has about
- the location of the last files transferred, including the pathname
- reported by the receiving Kermit, if any, when C-Kermit is the sender.
- This information was also added to SHOW FILE in somewhat less detail.
-
-4.13. File Output Buffer Control
-
- (UNIX only). The new command SET FILE OUTPUT lets you control how
- incoming files are written to disk:
-
- SET FILE OUTPUT BUFFERED [ size ]
- Chooses buffered file output; this is the default. UNIX does its
- normal sort of disk buffering. The optional size specifies
- Kermit's own file output buffer size, and therefore the
- frequency of disk accesses (write() system calls) -- the bigger
- the size, the fewer the disk accesses.
-
- SET FILE OUTPUT UNBUFFERED [ size ]
- This forces each file output write() call to actually commit the
- data to disk immediately. Choosing this option will usually slow
- file reception down.
-
- SET FILE OUTPUT BLOCKING
- Write() calls should not return until they are complete. This is
- the normal setting, and it lets Kermit detect disk-write errors
- immediately.
-
- SET FILE OUTPUT NONBLOCKING
- Write() calls should return immediately. This can speed up file
- reception, but also delay the detection of disk-write errors.
-
- Experimentation with these parameters should be harmless, and might (or
- might not) have a perceptible, even dramatic, effect on performance.
-
-4.14. Improved Responsiveness
-
- In version 7.0, C-Kermit's file-transfer protocol engine has been tuned
- for additional speed and responsiveness.
-
- * Binary-mode transfers over 8-bit connections, a very common case,
- are now handled in a special way that minimizes overhead.
- * SET TRANSFER CRC-CALCULATION is now OFF by default, rather than ON.
- (This affects only the overall per-transfer CRC, \v(crc16), not the
- per-packet CRCs)
- * Connection loss during file transfer is now detected immediately in
- most cases on Internet connections and on serial connections when
- CARRIER-WATCH is not set to OFF.
-
-4.15. Doubling and Ignoring Characters for Transparency
-
- The following commands were added in 7.0, primarily to allow successful
- file transfer through ARPAnet TACs and with Honeywell DPS6 systems, but
- can be used in any setting where they might be needed:
-
- SET SEND DOUBLE-CHAR { [ char [ char [ ... ] ] ], NONE }
- Tells C-Kermit to double the specified characters (use decimal
- notation) in packets that it sends. For example, if you are
- sending files through a device that uses @ as an escape
- character, but allows you to send a single copy of @ through by
- doubling it, use "set send double 64".
-
- SET RECEIVE IGNORE-CHAR [ char [ char [ ... ] ] ]
- Tells C-Kermit to ignore the specified character(s) in incoming
- packets. Use this, for example, when something between the
- sender and receiver is inserting linefeeds for wrapping, NULs
- for padding, etc.
-
-4.16. New File-Transfer Display Formats
-
- SET TRANSFER DISPLAY { BRIEF, CRT, FULLSCREEN, NONE, SERIAL }
- Selects the file-transfer display format.
-
- BRIEF is the new one. This writes one line to the screen per file,
- showing the file's name, transfer mode, size, the status of the
- transfer, and when the transfer is successful, the effective data rate
- in characters per second (CPS). Example:
-
- SEND ckcfn3.o (binary) (59216 bytes): OK (0.104 sec, 570206 cps)
- SEND ckcfns.o (binary) (114436 bytes): OK (0.148 sec, 772006 cps)
- SEND ckcmai.c (text) (79147 bytes): OK (0.180 sec, 438543 cps)
- SEND ckcmai.o (binary) (35396 bytes): OK (0.060 sec, 587494 cps)
- SEND ckcnet.o (binary) (62772 bytes): REFUSED
- SEND ckcpro.o (binary) (121448 bytes): OK (0.173 sec, 703928 cps)
- SEND ckcpro.w (text) (63687 bytes): OK (0.141 sec, 453059 cps)
- SEND makefile (text) (186636 bytes): OK (0.444 sec, 420471 cps)
- SEND wermit (binary) (1064960 bytes): OK (2.207 sec, 482477 cps)
-
- Note that transfer times are now obtained in fractional seconds, rather
- than whole seconds, so the CPS figures are more accurate (the display
- shows 3 decimal places, but internally the figure is generally precise
- to the microsecond).
-
-4.17. New Transaction Log Formats
-
- The new command:
-
- SET TRANSACTION-LOG { VERBOSE, FTP, BRIEF [ separator ] }
-
- lets you choose the format of the transaction log. VERBOSE (the
- default) indicates the traditional format described in the book. BRIEF
- and FTP are new. This command must be given prior to the LOG
- TRANSACTION command if a non-VERBOSE type is desired.
-
-4.17.1. The BRIEF Format
-
- BRIEF chooses a one-line per file format suitable for direct
- importation into databases like Informix, Oracle, or Sybase, in which:
-
- * Each record has 8 fields.
- * Fields are separated by a non-alphanumeric separator character.
- * The default separator character is comma (,).
- * Any field containing the separator character is enclosed in
- doublequotes.
- * The final field is enclosed in doublequotes.
-
- The fields are:
-
- 1. Date in yyyymmdd format
- 2. Time in hh:mm:ss format
- 3. Action: SEND or RECV
- 4. The local filename
- 5. The size of the file
- 6. The transfer mode (text, binary, image, labeled)
- 7. The status of the transfer: OK or FAILED
- 8. Additional status-dependent info, in doublequotes.
-
- Examples:
-
- 20000208,12:08:52,RECV,/u/olga/oofa.txt,5246,text,OK,"0.284sec 18443cps"
- 20000208,12:09:31,SEND,/u/olga/oofa.exe,32768,binary,OK,"1.243sec 26362cps"
- 20000208,12:10:02,SEND,"/u/olga/a,b",10130,text,FAILED,"Refused: date"
-
- Note how the filename is enclosed in doublequotes in the final example,
- because it contains a comma.
-
- To obtain BRIEF format, you must give the SET TRANSACTION-LOG BRIEF
- command before the LOG TRANSACTIONS command. (If you give them in the
- opposite order, a heading is written to the log by the LOG command.)
-
-4.17.2. The FTP Format
-
- SET TRANSACTION-LOG FTP (available only in UNIX) chooses a format that
- is compatible with the WU-FTPD (Washington University FTP daemon) log,
- and so can be processed by any software that processes the WU-FTPD log.
- It logs only transfers in and out, both successful and failed (but
- success or failure is not indicated, due to lack of a field in the
- WU-FTPD log format for this purpose). Non-transfer events are not
- recorded.
-
- Unlike other logs, the FTP-format transaction log is opened in append
- mode by default. This allows you to easily keep a record of all your
- kermit transfers, and it also allows the same log to be shared by
- multiple simultaneous Kermit processes or (permissions permitting)
- users. You can, of course, force creation of a new logfile by
- specifying the NEW keyword after the filename, e.g.
-
- log transactions oofa.log new
-
- All records in the FTP-style log are in a consistent format. The first
- field is fixed-length and contains spaces; subsequent fields are
- variable length, contain no spaces, and are separated by one or more
- spaces. The fields are:
-
- Timestamp
- This is an asctime-style timestamp, example: "Wed Sep 16
- 20:19:05 1999" It is always exactly 24 characters long, and the
- subfields are always in fixed positions.
-
- Elapsed time
- The whole number of seconds required to transfer the file, as a
- string of decimal digits, e.g. "24".
-
- Connection
- The name of the network host to which C-Kermit is connected, or
- the name of the serial device through which it has dialed (or
- has a direct connection), or "/dev/tty" for transfers in remote
- mode.
-
- Bytes transferred
- The number of bytes transferred, decimal digits, e.g. "1537904".
-
- Filename
- The name of the file that was transferred, e.g.
- "/pub/ftp/kermit/a/README.TXT". If the filename contains any
- spaces or control characters, each such character is replaced by
- an underscore ('_') character.
-
- Mode
- The letter 'b' if the file was transferred in binary mode, or
- 'a' if it was transferred in text (ASCII) mode.
-
- Options
- This field always contains an underscore ('_') character.
-
- Direction
- The letter 'o' if the file was transferred Out, and 'i' if the
- file was transferred In.
-
- User class
- The letter 'r' indicates the file was transferred by a Real
- user.
-
- User identification
- The ID of the user who transferred the file.
-
- Server identification
- The string "kermit". This distinguishes a Kermit transfer log
- record from a WU-FTPD record, which contains "ftp" in this
- field.
-
- Authentication class
- The digit '1' if we know the user's ID on the client system,
- otherwise '0'. Currently, always '0'.
-
- Authenticated user
- If the authentication class is '1', this is the user's ID on the
- client system. Otherwise it is an asterisk ('*'). Currently it
- is always an asterisk.
-
- Examples:
-
- Thu Oct 22 17:42:48 1998 0 * 94 /usr/olga/new.x a _ i r olga kermit 0 *
- Thu Oct 22 17:51:29 1998 1 * 147899 /usr/olga/test.c a _ o r olga kermit 0 *
- Thu Oct 22 17:51:44 1998 1 * 235 /usr/olga/test.o b _ i r olga kermit 0 *
- Fri Oct 23 12:10:25 1998 0 * 235 /usr/olga/x.ksc a _ o r olga kermit 0 *
-
- Note that an ftp-format transaction log can also be selected on the
- Kermit command line as follows:
-
- kermit --xferfile:filespec
-
- This is equivalent to:
-
- SET TRANSACTION-LOG FTP
- LOG TRANSACTIONS filespec APPEND
-
- Conceivably it could be possible to have a system-wide shared Kermit
- log, except that UNIX lacks any notion of an append-only file; thus any
- user who could append to the log could also delete it (or alter it).
- This problem could be worked around using setuid/setgid tricks, but
- these would most likely interfere with the other setuid/setgid tricks
- C-Kermit must use for getting at dialout devices and UUCP logfiles.
-
-4.18. Unprefixing NUL
-
- As of 6.1.193 Alpha.10, C-Kermit can finally send and receive
- file-transfer packets in which NUL (ASCII 0) is unprefixed (no more
- NUL-terminated packets!). NUL is, of course, extremely prevalent in
- binary files such as executables, and this has been a significant
- source of packet overhead. For example, when transferring itself (the
- SunOS C-Kermit executable) with minimal prefixing and 9000-byte
- packets, we see:
-
- File size: 1064960
- Packet chars with 0 prefixed: 1199629 overhead = 12.65%
- Packet chars with 0 unprefixed: 1062393 overhead = -0.03%
-
- Transfer rates go up accordingly, not only because of the reduced
- amount of i/o, but also because less computation is required on each
- end.
-
-4.19. Clear-Channel Protocol
-
- Now that C-Kermit itself is capable of sending and receiving any byte
- at all on a clear channel ([524]Section 4.18), it is, for the first
- time, in a position to negotiate a clear channel with the other Kermit,
- giving it permission (but not requiring it) to unprefix any and all
- characters that it knows are safe. In general this means all but the
- Kermit start-of-packet character (normally Ctrl-A), Carriage Return
- (not only Kermit's end-of-packet character, but also treated specially
- on Telnet NVT links), and IAC (255, also special to Telnet).
-
- By default, C-Kermit will say it has a clear channel only if it has
- opened a TCP socket. Since the Kermit program on the far end of a
- TCP/IP connection generally does not know it has a TCP/IP connection,
- it will not announce a clear channel unless it has been told to do so.
- The command is:
-
- SET CLEAR-CHANNEL { ON, OFF, AUTO }
-
- AUTO is the default, meaning that the clear-channel status is
- determined automatically from the type of connection. ON means to
- announce a clear channel, OFF means not to announce it. Use SHOW
- STREAMING ([525]Section 4.20) to see the current CLEAR-CHANNEL status.
- Synonym: SET CLEARCHANNEL.
-
- CLEAR-CHANNEL is also set if you start C-Kermit with the -I switch (see
- [526]Section 4.20).
-
- Whenever a clear channel is negotiated, the resulting control-character
- unprefixing is "sticky"; that is, it remains in effect after the
- transfer so you can use SHOW CONTROL to see what was negotiated.
-
- You can also see whether a clear channel was negotiated in the
- STATISTICS /VERBOSE Display.
-
- The advantage of the clear channel feature is that it can make file
- transfers go faster automatically. The disadvantage would be
- file-transfer failures if the channel is not truly clear, for example
- if C-Kermit made a Telnet connection to a terminal server, and then
- dialed out from there; or if C-Kermit made an Rlogin connection to host
- and then made a Telnet connection from there to another host. If a file
- transfer fails on a TCP/IP connection, use SHOW CONTROL to check
- whether control characters became unprefixed as a result of protocol
- negotiations, and/or SHOW STREAMING ([527]Section 4.20) to see if
- "clear-channel" was negotiated. If this happened, use SET CLEAR-CHANNEL
- OFF and SET PREFIXING CAUTIOUS (or whatever) to prevent it from
- happening again.
-
-4.20. Streaming Protocol
-
- A new Kermit protocol option called "streaming" was added in C-Kermit
- 7.0. The idea is that if the two Kermit partners have a reliable
- transport (such as TCP/IP or X.25) between them, then there is no need
- to send ACKs for Data packets, or NAKs, since a reliable transport
- will, by definition, deliver all packets in order and undamaged. On
- such a connection, streaming cuts down not only on Kermit program
- overhead (switching back and forth between reading and sending
- packets), but also tends to make the underlying transport use itself
- more efficiently (e.g. by defeating the Nagle algorithm and/or Delayed
- ACK stratagem of the TCP layer). Furthermore, it allows transfers to
- work smoothly on extremely slow network congestions that would
- otherwise cause timeouts and retransmissions, and even failure when the
- retry limit was exceeded.
-
- The trick is knowing when we can stream:
-
- 1. If C-Kermit has opened a TCP socket or X.25 connection, it offers
- stream.
- 2. If C-Kermit has been started with the -I (uppercase) option, or if
- it has been told to SET RELIABLE ON, it offers to stream.
- 3. If C-Kermit is in remote mode, and has been told to SET RELIABLE
- AUTO (or ON), it always offers to stream, and also always agrees to
- stream, if the other Kermit offers. Unless you take explicit
- actions to override the defaults, this allows the local Kermit (the
- one that made the connection, and so knows whether it's reliable)
- to control streaming.
-
- (Note that an offer to stream also results in a Clear-Channel
- announcement if CLEAR-CHANNEL is set to AUTO; see [528]Section 4.19.)
-
- When BOTH Kermits offer to stream, then they stream; otherwise they
- don't. Thus streaming-capable Kermit programs interoperate
- automatically and transparently with nonstreaming ones. If the two
- Kermits do agree to stream, you'll see the word "STREAMING" on the
- fullscreen file-transfer display in the Window Slots field. You can
- also find out afterwards with the STATISTICS or SHOW STREAMING
- commands.
-
- WARNING: Automatic choice of streaming is based on the assumption of
- a "direct" end-to-end network connection; for example, a Telnet or
- Rlogin connection from host A to host B, and transferring files
- between A and B. However, if your connection has additional
- components -- something "in the middle" (B) that you have made a
- network connection to, which makes a separate connection to the
- destination host (C), then you don't really have a reliable
- connection, but C-Kermit has no way of knowing this; transferring
- files between A and C will probably fail. In such cases, you'll need
- to tell the *local* C-Kermit to "set reliable off" before
- transferring files (it does no good to give this command to the
- remote Kermit since the local one controls the RELIABLE setting).
-
- Streaming is like using an infinite window size, with no timeouts and
- no tolerance for transmission errors (since there shouldn't be any). It
- relies on the underlying transport for flow control, error correction,
- timeouts, and retransmission. Thus it is very suitable for use on
- TCP/IP connections, especially slow or bursty ones, since Kermit's
- packet timeouts won't interfere with the transfer -- each packet takes
- as long to reach its destination as it takes TCP to deliver it. If TCP
- can't deliver the packet within its own timeout period (over which
- Kermit has no control), it signals a fatal error. Just like FTP.
-
- Streaming goes much faster than non-streaming when a relatively small
- packet length is used, and it tends to go faster than non-streaming
- with even the longest packet lengths. The Kermit window size is
- irrelevant to streaming protocol, but still might affect performance in
- small ways since it can result in different paths through the code.
-
- The definition of "reliable transport" does not necessarily demand
- 8-bit and control-character transparency. Streaming can work with
- parity and/or control-character prefixing just as well (but not as
- fast) as without them; in such cases you can leave RELIABLE set to ON,
- but set CLEARCHANNEL and/or PARITY appropriately.
-
- Maximum performance -- comparable to and often exceeding FTP -- is
- achieved on socket-to-socket connections (in which the considerable
- overhead of the terminal driver and Telnet or Rlogin server is
- eliminated) with long packets and the new "brief" file-transfer display
- ([529]Section 4.16).
-
-4.20.1. Commands for Streaming
-
- SET RELIABLE { ON, OFF, AUTO }
- SET RELIABLE ON tells Kermit that it has a reliable transport.
- SET RELIABLE OFF tells Kermit the transport is not reliable.
- SET RELIABLE AUTO tells Kermit that it should SET RELIABLE ON
- whenever it makes a reliable connection (e.g. TELNET or SET HOST
- on a TCP/IP or X.25 network), and when in remote mode it should
- believe the transport is reliable if the other Kermit says it is
- during Kermit protocol negotiation.
-
- AUTO is the default; the Kermit program that makes the connection knows
- whether it is reliable, and tells the remote Kermit.
-
- The RELIABLE setting has several effects, including:
-
- * It can affect the timeouts used during normal ACK/NAK protocol.
- * It can affect the clear-channel announcement.
- * It can affect streaming.
-
- If you TELNET or SET HOST somewhere, this includes an implicit SET
- RELIABLE ON command. The -I command-line option is equivalent to SET
- RELIABLE ON.
-
- Since SET RELIABLE ON (and -I) also implies SET CLEAR CHANNEL ON, you
- might find that in certain cases you need to tell Kermit that even
- though the connection is reliable, it doesn't have a clear channel
- after all:
-
- SET CLEAR-CHANNEL OFF
- SET PREFIXING CAUTIOUS ; or whatever...
-
- You can control streaming without affecting the other items with:
-
- SET STREAMING { ON, OFF, AUTO }
-
- AUTO is the default, meaning streaming will occur if Kermit has made a
- TCP/IP connection or if RELIABLE is ON (or it was started with the -I
- command line option). OFF means don't stream; ON means offer to stream
- no matter what.
-
-4.20.2. Examples of Streaming
-
- Here we look at the use and behavior of streaming on several different
- kinds of connections, and compare its performance with non-streaming
- transfers.
-
-4.20.2.1. Streaming on Socket-to-Socket Connections
-
- Here we get streaming automatically when both Kermit programs are
- capable of it, since they both make socket connections. For example, on
- the far end:
-
- C-Kermit> set host * 3000
- C-Kermit> server
-
- and on the near end:
-
- C-Kermit> set host foo.bar.xyz.com 3000
- (now give SEND and GET command)
-
- All subsequent file transfers use streaming automatically.
-
- Here are the results from 84 trials, run on a production network,
- disk-to-disk, in which a 1-MB binary file (the SunOS C-Kermit Sparc
- executable) was sent from a Sun Sparc-10 with SunOS 4.1.3 to an IBM
- Power Server 850 with AIX 4.1, socket-to-socket, over a 10Mbps 10BaseT
- Ethernet, using minimal control-character unprefixing, window sizes
- from 10 to 32, and packet sizes from 1450 to 9010:
-
- Streaming Nonstreaming
- Max CPS 748955 683354
- Min CPS 221522 172491
- Mean CPS 646134 558680
- Median CPS 678043 595874
- Std Dev 101424 111493
-
- Correlations:
-
- CPS and window size: -0.036
- CPS and packet length: 0.254
- CPS and streaming: 0.382
-
- Note that the relationship between streaming and throughput is
- significantly stronger than that between CPS and window size or packet
- length.
-
- Also note that this and all other performance measurements in this
- section are snapshots in time; the results could be much different at
- other times when the load on the systems and/or the network is higher
- or lower.
-
- In a similar socket-to-socket trial, but this time over a wide-area
- TCP/IP connection (from New York City to Logan, Utah, about 2000
- miles), the following results were obtained:
-
- Streaming Nonstreaming
- Max CPS 338226 318203
- Min CPS 191659 132314
- Mean CPS 293744 259240
- Median CPS 300845 273271
- Std Dev 41914 52351
-
- Correlations:
-
- CPS and window size: 0.164
- CPS and packet length: 0.123
- CPS and streaming: 0.346
-
-4.20.2.2. Streaming on Telnet Connections
-
- In this case the local copy of Kermit is told to TELNET or SET HOST,
- and so it knows it has a reliable connection and -- unless it has been
- told not to -- will offer to stream, and the other Kermit program,
- since it has STREAMING set to AUTO, agrees.
-
- Since we have a reliable connection, we'll also get control-character
- unprefixing automatically because of the new clear-channel protocol
- ([530]Section 4.19).
-
- Any errors that occur during streaming are fatal to the transfer. The
- message is "Transmission error on reliable link". Should this happen:
-
- 1. Check the remote Kermit's flow control setting (SHOW
- COMMUNICATIONS). If it is NONE, change it to XON/XOFF, or vice
- versa. If it is XON/XOFF (or you just changed it to XOFF/XOFF),
- make sure the file sender is prefixing the XON and XOFF characters.
- In the most drastic case, use "set prefix all" to force prefixing
- of all control characters.
- 2. The remote Telnet server might chop off the 8th bit. In that case,
- tell C-Kermit to "set parity space". Or, you might be able to force
- the Telnet to allow eight-bit data by telling C-Kermit to "set
- telopt binary request accept" -- that is, request the Telnet server
- to enter binary mode, and accept binary-mode bids from the server.
- 3. The remote Telnet server might have a buffering limitation. If a
- and b don't cure the problem, tell the file receiver to "set
- receive packet-length 1000" (or other number -- use the largest one
- that works). This too, is no different from the non-streaming case
- (more about this in [531]Section 4.20.2.3).
-
- And remember you can continue interrupted binary-mode transfers where
- they left off with the RESEND (= SEND /RECOVER) command.
-
- Here are the figures for the same 84 trials between the same Sun and
- IBM hosts as in 4.20.2.1, on the same network, but over a Telnet
- connection rather than socket-to-socket:
-
- Streaming Nonstreaming
- Max CPS 350088 322523
- Min CPS 95547 173152
- Mean CPS 321372 281830
- Median CPS 342604 291469
- Std Dev 40503 29948
-
- Correlations:
-
- CPS and window size: 0.001
- CPS and packet length: 0.152
- CPS and streaming: 0.128
-
- Here the effect is not as emphatic as in the socket-to-socket case, yet
- on the whole streaming tends to be beneficial.
-
- Additional measurements on HP-UX using C-Kermit 7.0 Beta.06:
-
- Windowing Streaming
- HP-UX 8->8 not tested 14Kcps
- HP-UX 8->9 not tested 76Kcps
- HP-UX 8->10 36Kcps 66Kcps
- HP-UX 9->9 not tested 190Kcps
- HP-UX 9->10 160Kcps 378Kcps
-
-4.20.2.3. Streaming with Limited Packet Length
-
- The IRIX telnet server (at least the ones observed in IRIX 5.3 and 6.2)
- does not allow Kermit to send packets longer than 4096 bytes. Thus when
- sending from IRIX C-Kermit when it is on the remote end of a Telnet
- connection, the packet length must be 4K or less. Trials in this case
- (in which packet lengths range from 1450 to 4000) show a strong
- advantage for streaming, which would be evident in any other case where
- the packet length is restricted, and stronger the shorter the maximum
- packet length.
-
- Streaming Nonstreaming
- Max CPS 426187 366870
- Min CPS 407500 276517
- Mean CPS 415226 339168
- Median CPS 414139 343803
- Std Dev 6094 25851
-
- Correlations:
-
- CPS and window size: 0.116
- CPS and packet length: 0.241
- CPS and streaming: 0.901
-
-4.20.2.4. Streaming on Dialup Connections
-
- Here "dialup" refers to a "direct" dialup connection, not a SLIP or PPP
- connection, which is only a particular kind of TCP/IP connection.
-
- Attempt this at your own risk, and then only if (a) you have
- error-correcting modems, and (b) the connections between the modems and
- computers are also error-free, perfectly flow-controlled, and free of
- interrupt conflicts. Streaming can be used effectively and to fairly
- good advantage on such connections, but remember that the transfer is
- fatal if even one error is detected (also remember that should a
- binary-mode transfer fail, it can be recovered from the point of
- failure with RESEND).
-
- To use streaming on an unreliable connection, you must tell both
- Kermits that the connection is reliable:
-
- kermit -I
-
- or:
-
- C-Kermit> set reliable on
-
- In this case, it will probably be necessary to prefix some control
- characters, for example if your connection is through a terminal server
- that has an escape character. Most Cisco terminal servers, for example,
- require Ctrl-^ (30, as well as its high-bit equivalent, 158) to be
- prefixed. To unprefix these, you'll need to defeat the "clear channel"
- feature:
-
- C-Kermit> set reliable on
- C-Kermit> set clear-channel off
- C-Kermit> set prefixing none
- C-Kermit> set control prefix 1 13 30 158 ; and whatever else is necessary
-
- Dialup trials were done using fixed large window and packet sizes. They
- compare uploading and downloading of two common types of files, with
- and without streaming. Configuration:
-
- HP-9000/715/33 -- 57600bps, RTS/CTS -- USR Courier V.34 --
- V.34+V.42, 31200bps -- USR V.34+ Rackmount -- 57600bps, RTS/CTS --
- Cisco terminal server -- Solaris 2.5.1. Packet size = 8000, Window
- Size = 30, Control Character Unprefixing Minimal (but including the
- Cisco escape character).
-
- Since this is not a truly reliable connection, a few trials failed when
- a bad packet was received (most likely due to UART overruns); the
- failure was graceful and immediate, and the message was informative.
- The results of ten successful trials uploading and downloading the two
- files with and without streaming are:
-
- Streaming..
- Off On
- Upload 5194 5565 txt (= C source code, 78K)
- 3135 3406 gz (= gzip file, compressed, 85K)
- Download 5194 5565 txt
- 3041 3406 gz
-
- Each CPS figure is the mean of 10 results.
-
- A brief test was also performed on a LAT-based dialout connection from
- a VAX 3100 with VMS 5.5 to a USR Courier V.34 connected to a DECserver
- 700 at 19200 bps. The 1-MB Sparc executable downloaded from a Sun to
- the VAX at 1100cps without streaming and 1900cps with streaming, using
- 8000-byte packets, 30 window slots, and minimal prefixing in both
- cases.
-
-4.20.2.5. Streaming on X.25 Connections
-
- We have only limited access to X.25 networks. One trial was performed
- in which the 1MB Solaris 2.4 Sparc executable was transferred over a
- SunLink X.25 connection; nothing is known about the actual physical
- connection. With a packet length of 8000 and a window size of 30, the
- file transferred at 6400 cps (using a maximum of 6 window slots). With
- the same packet length, but with streaming, it transferred without
- mishap at 6710 cps, about 5% faster.
-
-4.20.3. Streaming - Preliminary Conclusions
-
- The results vary with the particular connection, but are good overall.
- Although numerous lower-level tricks can be used to improve performance
- on specific platforms or connection methods, streaming occurs at a
- high, system-independent level of the Kermit protocol and therefore can
- apply to all types of platforms and (reliable) connections
- transparently.
-
-4.21. The TRANSMIT Command
-
- Prior to C-Kermit 7.0, the TRANSMIT command transmitted in text or
- binary mode according to SET FILE TYPE { TEXT, BINARY }. But now that
- binary mode is likely to be the default for protocol transfers, it is
- evident that this not also an appropriate default for TRANSMIT, since
- binary-mode TRANSMIT is a rather specialized and tricky operation.
- Therefore, TRANSMIT defaults to text mode always, regardless of the
- FILE TYPE setting.
-
- C-Kermit 7.0 expands the capabilities of the TRANSMIT command by adding
- the following switches (see [532]Section 1.5). The new syntax is:
-
- TRANSMIT [ switches... ] filename
-
- Zero or more switches may be included:
-
- /PIPE
- When /PIPE is included, "filename" is interpreted as a system
- command or program whose output is to be sent. Synonym:
- /COMMAND. Example:
-
- transmit /pipe finger
-
- You may enclose the command in braces, but you don't have to:
-
- xmit /pipe {ls -l | sort -r +0.22 -0.32 | head}
-
- /BINARY
- Transmits the file (or pipe output) in binary mode.
-
- /TEXT
- Transmits the file (or pipe output) in line-oriented text mode.
- Current FILE CHARACTER-SET and TERMINAL CHARACTER-SET selections
- govern translation. Default.
-
- /TRANSPARENT
- Specifies text mode without character-set translation, no matter
- what the FILE and TERMINAL CHARACTER-SET selections are.
-
- /NOWAIT
- This is equivalent to SET TRANSMIT PROMPT 0, but for this
- TRANSMIT command only. Applies only to text mode; it means to
- not wait for any kind of echo or turnaround character after
- sending a line before sending the next line. (Normally Kermit
- waits for a linefeed.)
-
- When TRANSMIT ECHO is ON, C-Kermit tries to read back the echo of each
- character that is sent. Prior to C-Kermit 7.0, 1 second was allowed for
- each echo to appear; if it didn't show up in a second, the TRANSMIT
- command would fail. Similarly for the TRANSMIT PROMPT character.
- However, with today's congested Internet connections, etc, more time is
- often needed:
-
- SET TRANSMIT TIMEOUT number
-
- Specifies the number of seconds to wait for an echo or the prompt
- character when TRANSMIT PROMPT is nonzero; the default wait is 1
- second. If you specify 0, the wait is indefinite. When a timeout
- interval of 0 is specified, and a desired echo or prompt does not show
- up, the TRANSMIT command will not terminate until or unless you
- interrupt it with Ctrl-C; use SET TRANSMIT TIMEOUT 0 with caution.
-
- Note: to blast a file out the communications connection without any
- kind of synchronization or timeouts or other manner of checking, use:
-
- SET TRANSMIT ECHO OFF
- SET TRANSMIT PROMPT 0 (or include the /NOWAIT switch)
- SET TRANSMIT PAUSE 0
- TRANSMIT [ switches ] filename
-
- In this case, text-file transmission is not-line oriented and large
- blocks can be sent, resulting in a significant performance improvement
- over line-at-at-time transmission. Successful operation depends (even
- more than usual for the TRANSMIT command!) on a clean connection with
- effective flow control.
-
- For details on TRANSMIT and character sets, see [533]Section 6.6.5.4.
-
- 4.22. Coping with Faulty Kermit Implementations
-
- Kermit protocol has been implemented in quite a few third-party
- commercial, shareware, and freeware software packages, with varying
- degrees of success. In most cases operation is satisfactory but slow --
- only the bare minimum subset of the protocol is available -- short
- packets, no sliding windows, no attributes, etc. In other cases, the
- implementation is incorrect, resulting in failures at the initial
- negotiation stage or corrupted files.
-
- C-Kermit 7.0 and Kermit 95 1.1.19 include some new defense mechanisms
- to help cope with the most common situations. However, bear in mind
- there is only so much we can do in such cases -- the responsibility for
- fixing the problem lies with the maker of the faulty software.
-
- 4.22.1. Failure to Accept Modern Negotiation Strings
-
- The published Kermit protocol specification states that new fields can
- be added to the parameter negotiation string. These are to be ignored
- by any Kermit implementation that does not understand them; this is
- what makes the Kermit protocol extensible. Unfortunately, some Kermit
- implementations become confused (or worse) when receiving a negotiation
- string longer than the one they expect. You can try working around such
- problems by telling Kermit to shorten its negotiation string (and thus
- disable the corresponding new features):
-
- SET SEND NEGOTIATION-STRING-MAX-LENGTH number
-
- Try a number like 10. If that doesn't work, try 9, 8, 7, 6, and so on.
-
- 4.22.2. Failure to Negotiate 8th-bit Prefixing
-
- The published Kermit protocol specification states that 8th-bit
- prefixing (which allows transfer of 8-bit data over a 7-bit connection)
- occurs if the file sender puts a valid prefix character (normally "&")
- in the 8th-bit-prefix field of the negotiation string, and the receiver
- puts either a letter "Y" or the same prefix character. At least one
- faulty Kermit implementation exists that does not accept the letter
- "Y". To force C-Kermit / K-95 to reply with the other Kermit's prefix
- character rather than a "Y", give the following (invisible) command:
-
- SET Q8FLAG ON
-
- Use SET Q8FLAG OFF to restore the normal behavior.
-
- 4.22.3. Corrupt Files
-
- Refer to [534]Section 4.22.2. Some Kermit implementations mistakenly
- interpret the "Y" as a prefix character. Then, whenever a letter Y
- appears in the data, the Y and the character that follows it are
- replaced by a garbage character. At this writing, we are not sure if
- there is any solution, but try "set send negotiation-string-max-length
- 6" and/or "set q8flag on".
-
- File corruption can also occur when control characters within the file
- data are sent without prefixing, as at least some are by default in
- C-Kermit 7.0 and K-95. Some Kermit implementations do not handle
- incoming "bare" control characters. To work around, "set prefixing
- all".
-
- 4.22.4. Spurious Cancellations
-
- The Kermit protocol specification states that if an ACK to a Data
- packet contains X in its data field, the transfer of the current file
- is canceled, and if it contains a Z, the entire transfer is canceled.
- At least one overzealous Kermit implementation applies this rule to
- non-Data packets as well, the typical symptom being that any attempt to
- transfer a file whose name begins with X or Z results in cancellation.
- This is because the file receiver typically sends back the name under
- which it stored the file (which might not be the same as the name it
- was sent with) in the ACK to the File Header packet. This is
- information only and should not cause cancellation. To work around the
- problem, use:
-
- SET F-ACK-BUG { ON, OFF }
-
- ON tells Kermit not to send back the filename in the ACK to the file
- header packet as it normally would do (OFF puts Kermit back to normal
- after using ON).
-
- A variation on the this bug occurs in an obscure Kermit program for
- MUMPS: When this Kermit program sends a file called (say) FOO.BAR, it
- requires that the ACK to its F packet contain exactly the same name,
- FOO.BAR. However, C-Kermit likes to send back the full pathname,
- causing the MUMPS Kermit to fail. SET F-ACK-BUG ON doesn't help here.
- So a separate command has been added to handle this situation:
-
- SET F-ACK-PATH { ON, OFF }
-
- Normally it is ON (regardless of the SET SEND PATHNAMES setting). Use
- SET F-ACK-PATH OFF to instruct Kermit to send back only the filename
- without the path in the ACK to the F packet.
-
- 4.22.5. Spurious Refusals
-
- Some Kermit implementations, notably PDP-11 Kermit 3.60 and earlier,
- have bugs in their handling of Attribute packets that can cause
- unwarranted refusal of incoming files, e.g. based on date or size. This
- can be worked around by telling one or both of the Kermit partners to:
-
- SET ATTRIBUTES OFF
-
- 4.22.6. Failures during the Data Transfer Phase
-
- This can be caused by control-character unprefixing ([535]Section
- 4.22.3 ), and fixed by:
-
- SET PREFIXING ALL
-
- It can also have numerous other causes, explained in Chapter 10 of
- [536]Using C-Kermit: the connection is not 8-bit transparent (so use
- "set parity space" or somesuch), inadequate flow control, etc. Consult
- the manual.
-
- 4.22.7. Fractured Filenames
-
- At least one well-known PC-based communications package negotiates data
- compression, which (according to the protocol specification) applies to
- both the filename and the file data, but then fails to decompress the
- filename. Example: C-Kermit sends a file called R000101.DAT (where
- 000101 might be non-Y2K-wise YYMMDD notation), and the package in
- question stores the files as R~#0101.DAT. Workaround: Tell C-Kermit to
- SET REPEAT COUNTS OFF.
-
- 4.22.8. Bad File Dates
-
- At least one well-known PC-based communications package negotiates the
- passing of file timestamps from sender to receiver, but when it is
- sending files, it always gives them a timestamp of 1 February 1970.
- Workaround: tell C-Kermit to SET ATTRIBUTE DATE OFF. You don't get the
- file's real date, but you also don't get 1 Feb 1970; instead the file
- gets the current date and time.
-
- 4.23. File Transfer Recovery
-
- Prior to C-Kermit 7.0, RESEND (SEND /RECOVER) and REGET (GET /RECOVER)
- refused to work if FILE TYPE was not BINARY or the /BINARY switch was
- not included. Now these commands include an implied /BINARY switch,
- meaning they set the file type to binary for the duration of the
- command automatically.
-
- In the client/server arrangement, this also forces the server into
- binary mode (if it is C-Kermit 7.0 or greater, or K95 1.1.19 or
- greater) so the recovery operation proceeds, just as you asked and
- expected.
-
- BUT... Just as before, the results are correct only under the following
- conditions:
-
- * If the prior interrupted transfer was also in binary mode; or:
- * If the prior transfer was in text mode and the other computer was a
- "like platform" (e.g. UNIX-to-UNIX, Windows-to-Windows,
- DOS-to-Windows) AND there was no character-set translation (i.e.
- TRANSFER CHARACTER-SET was TRANSPARENT).
-
- Note that these circumstances are more likely to obtain in C-Kermit
- 7.0, in which:
-
- * The default FILE TYPE in C-Kermit 7.0 is BINARY.
- * The default FILE INCOMPLETE setting is AUTO, which means KEEP if
- the transfer is in binary mode, DISCARD otherwise.
- * C-Kermit 7.0, Kermit 95 1.1.17, and MS-DOS Kermit 3.15 and later
- can recognize "like platforms" and switch into binary mode
- automatically. Transfers between like platforms are always binary
- unless character-set translation has been requested, and then is
- still binary for all files whose names match a binary pattern,
- unless the automatic mechanisms have been disabled (with a /TEXT
- switch, or with SET TRANSFER MODE MANUAL).
- * SEND /BINARY and GET /BINARY always force binary-mode transfers,
- even when FILE TYPE is TEXT, even when TRANSFER MODE is AUTOMATIC,
- even when PATTERNS are ON and the file's name matches a text
- pattern.
-
- But also note that the automatic client/server transfer-mode
- adjustments do not work with versions of C-Kermit prior to 7.0 or K95
- prior to 1.1.16.
-
- If the prior transfer was in text mode:
-
- * If text-mode transfers between the two platforms are
- "length-changing" (as they are between UNIX -- which terminates
- text lines with LF -- and DOS or Windows -- which terminates text
- lines with CRLF), the recovered file will be corrupt.
- * If text-mode transfers between the two platforms are not
- length-changing, but character-set translation was active in the
- prior transfer, the result will be a file in which the first part
- has translated characters and the second part does not.
-
- But in C-Kermit 7.0 and K95 1.1.19 and later, incompletely transferred
- text files are not kept unless you change the default. But if you have
- done this, and you have an incompletely transferred text file, you'll
- need to:
-
- * Transfer the whole file again in text mode, or:
- * Use SEND /STARTING-AT: to recover the transfer at the correct
- point; but you have to find out what that point is, as described in
- the manual.
-
- Kermit has no way of knowing whether the previous transfer was in text
- or binary mode so it is your responsibility to choose the appropriate
- recovery method.
-
- If you use C-Kermit to maintain parallel directories on different
- computers, using SET FILE COLLISION to transfer only those files that
- changed since last time, and the files are big enough (or the
- connection slow enough) to require SEND /RECOVER to resume interrupted
- transfers, you should remember that SEND /RECOVER (RESEND) overrides
- all FILE COLLISION settings. Therefore you should use SEND /RECOVER
- (RESEND) only on the file that was interrupted, not the file group. For
- example, if the original transfer was initiated with:
-
- SEND *
-
- and was interrupted, then after reestablishing your connection and
- starting the Kermit receiver with SET FILE COLLISION UPDATE on the
- remote end, use the following sequence at the sender to resume the
- transfer:
-
- SEND /RECOVER name-of-interrupted-file
-
- and then:
-
- SEND *
-
- (In C-Kermit 7.0 and later, \v(filename) contains the name of the file
- most recently transferred, as long you have not EXITed from Kermit or
- changed directory, etc.
-
- 4.24. FILE COLLISION UPDATE Clarification
-
- In UNIX, file modification dates are used when comparing the file date
- with the date in the attribute packet. In VMS, however, the file
- creation date is used. These two policies reflect the preferences of
- the two user communities.
-
- Also, remember that the file date/time given in the attribute packet is
- the local time at the file sender. At present, no timezone conversions
- are defined in or performed by the Kermit protocol. This is primarily
- because this feature was designed at a time when many of the systems
- where Kermit runs had no concept of timezone, and therefore would be
- unable to convert (say, to/from GMT or UTC or Zulu time).
-
- As a consequence, some unexpected results might occur when transferring
- files across timezones; e.g. commands on the target system that are
- sensitive to file dates might not work (UNIX "make", backups, etc).
-
- Timezone handling is deferred for a future release.
-
- 4.25. Autodownload Improvements
-
- Refer to pages 164-165 of [537]Using C-Kermit about the hazards of
- autodownload when C-Kermit is "in the middle". As of C-Kermit 7.0, no
- more hazards. If C-Kermit has TERMINAL AUTODOWNLOAD ON and it detects a
- packet of the current protocol type (Kermit or Zmodem), it "erases" the
- visual aspect of the packet that would be seen by the terminal (or,
- more to the point, the emulator, such as K95). This way, only C-Kermit
- goes into RECEIVE mode, and not also the terminal emulator through
- which C-Kermit is accessed. And therefore, it is no longer necessary to
- SET TERMINAL AUTODOWNLOAD OFF to prevent multiple Kermits from going
- into receive mode at once, but of course it is still necessary to
- ensure that, when you have multiple Kermits in a chain, that the
- desired one receives the autodownload.
-
- The defaults have not been changed; Kermit 95 still has autodownload ON
- by default, and C-Kermit has it OFF by default.
-
- 5. CLIENT/SERVER
-
- 5.0. Hints
-
- If you use SET SERVER GET-PATH to set up your server, and the GET-PATH
- does not include the server's current directory, clients can become
- quite confused. For example, "remote dir oofa.txt" shows a file named
- oofa.txt, but "get oofa.txt" fails. In this situation, you should
- either DISABLE DIR or make your GET-PATH include the current directory.
-
- 5.1. New Command-Line Options
-
- The -G command-line option is like -g (GET), except the incoming file
- is sent to standard output rather than written to disk.
-
- The -I option ("Internet") is used to tell a remote C-Kermit program
- that you are coming in via Internet Telnet or Rlogin and therefore have
- a reliable connection. The -I option is equivalent to SET RELIABLE ON
- and SET FLOW NONE.
-
- The -O option ("Only One") tells C-Kermit to enter server mode but then
- exit after the first client operation.
-
- See [538]Section 9.3 for details.
-
- 5.2. New Client Commands
-
- BYE and FINISH no longer try to do anything if a connection is not
- active. Thus a sequence like "hangup" followed by "bye" or "finish"
- will no longer get stuck in a long timeout-and-retransmission cycle,
- nor will it try to open a new connection.
-
- REMOTE EXIT
- Similar to FINISH, except it ensures that the Kermit server
- program exits back to the operating system or shell prompt.
- (FINISH would return it to its interactive prompt if it was
- started in interactive mode, and would cause it to exit if it
- entered server mode via command-line option.) When C-Kermit is
- to be the server, you can use { ENABLE, DISABLE } EXIT to
- control the client's access to this feature.
-
- REMOTE MKDIR directory-name
- Tells the client to ask the server to create a directory with
- the given name, which can be absolute or relative. The syntax of
- the directory name depends on the Kermit server (see [539]next
- section); in all cases, it can be in the syntax of the system
- where the server is running (UNIX, VMS, DOS, etc) but newer
- servers also accept UNIX syntax, no matter what the underlying
- platform. The server will not execute this command if (a) it
- does not understand it, (b) a DISABLE MKDIR command has been
- given, or (c) a DISABLE CWD command has been given; otherwise,
- the command is executed, but will fail if the directory can not
- be created, in which cases most servers will attempt to return a
- message giving the reason for failure. The REMOTE MKDIR command
- succeeds if the remote directory is created, or if it already
- exists and therefore does not need to be created, and fails
- otherwise.
-
- REMOTE RMDIR directory-name
- Tells the client to ask the server to remove (delete) a
- directory with the given name. The same considerations apply as
- for REMOTE MKDIR.
-
- REMOTE SET FILE INCOMPLETE { DISCARD, KEEP, AUTO }
- Previously this was only available in its earlier form, REMOTE
- SET INCOMPLETE (no FILE). The earlier form is still available,
- but invisible. Also, AUTO was added, meaning KEEP if in binary
- mode, DISCARD otherwise.
-
- REMOTE SET TRANSFER MODE { AUTOMATIC, MANUAL }
- Tells the client to ask the server to set the given
- file-transfer mode. Automatic means (roughly): if the client and
- the server are running on the same kind of computer (e.g. both
- are on UNIX), then use binary mode automatically; if the system
- types are different, use some other method to automatically
- determine text or binary mode, such as filename pattern
- matching. MANUAL means, in this context, obey the client's FILE
- TYPE setting (TEXT or BINARY). Synonym: REMOTE SET XFER MODE.
-
- [ REMOTE ] QUERY KERMIT function(args...)
- Prior to C-Kermit 7.0, the arguments were not evaluated locally.
- Thus it was not possible to have the server run the function
- with client-side variables as arguments. Now:
-
- define \%a oofa.*
- remote query kermit files(\%a) ; Client's \%a
- remote query kermit files(\\%a) ; Server's \%a
-
- [ REMOTE ] LOGIN [ user [ password ] ]
- LOGIN is now a synonym for REMOTE LOGIN.
-
- LOGOUT
- This command, when given in local mode, is equivalent to REMOTE
- LOGOUT. When given at the IKSD prompt, it logs out the IKSD.
- When given at the C-Kermit prompt when it has no connection, it
- does nothing.
-
- Note that in C-Kermit 7.0, the REMOTE (or R) prefix is not required for
- QUERY, since there is no local QUERY command. The new top-level QUERY
- command does exactly what REMOTE QUERY (RQUERY) does.
-
- All REMOTE commands now have single-word shortcuts:
-
- Shortcut Full Form
- RASG REMOTE ASSIGN
- RCD REMOTE CD
- RCOPY REMOTE COPY
- RDEL REMOTE DELETE
- RDIR REMOTE DIRECTORY
- REXIT REMOTE EXIT
- RHELP REMOTE HELP
- RHOST REMOTE HOST
- RPWD REMOTE PWD
- RSET REMOTE SET
- etc.
-
- The R prefix is not applied to LOGIN because there is already an RLOGIN
- command with a different meaning. It is not applied to LOGOUT either,
- since LOGOUT knows what to do in each case, and for symmetry with
- LOGIN.
-
- 5.2.1. Remote Procedure Definitions and Calls
-
- This is nothing new, but it might not be obvious... REMOTE ASSIGN and
- REMOTE QUERY may be used to achieve remote procedure execution. The
- remote procedure can be defined locally or remotely.
-
- A remote procedure call is accomplished as noted in the previous
- section:
-
- [ remote ] query kermit function-name(args...)
-
- This invokes any function that is built in to the Kermit server, e.g.:
-
- [ remote ] query kermit size(foo.bar)
-
- returns the size of the remote file, foo.bar.
-
- Now note that C-Kermit includes an \fexecute() function, allowing it to
- execute any macro as if it were a built-in function. So suppose MYMACRO
- is the name of a macro defined in the server. You can execute it from
- the client as follows (the redundant "remote" prefix is omitted in the
- remaining examples):
-
- query kermit execute(mymacro arg1 arg2...)
-
- The return value, if any, is the value of the RETURN command that
- terminated execution of the macro, for example:
-
- define addtwonumbers return \feval(\%1+\%2)
-
- The client invocation would be:
-
- query kermit execute(addtwonumbers 3 4)
- 7
-
- The result ("7" in this case) is also assigned to the client's
- \v(query) variable.
-
- To execute a remote system command or command procedure (shell script,
- etc) use:
-
- query kermit command(name args...)
-
- Finally, suppose you want the client to send a macro to the server to
- be executed on the server end. This is done as follows:
-
- remote assign macroname definition
- query kermit execute(macroname arg1 arg2...)
-
- Quoting is required if the definition contains formal parameters.
-
- 5.3. New Server Capabilities
-
- 5.3.1. Creating and Removing Directories
-
- The C-Kermit 7.0 server responds to REMOTE MKDIR and REMOTE RMDIR
- commands. The directory name may be in either the native format of the
- server's computer, or in UNIX format. For example, a server running on
- VMS with a current directory of [IVAN] can accept commands from the
- client like:
-
- remote mkdir olga ; Makes [IVAN.OLGA] (nonspecific format)
- remote mkdir .olga ; Makes [IVAN.OLGA] (VMS format without brackets)
- remote mkdir olga/ ; Makes [IVAN.OLGA] (UNIX relative format)
- remote mkdir /ivan/olga ; Makes [IVAN.OLGA] (UNIX absolute format)
- remote mkdir [ivan.olga] ; Makes [IVAN.OLGA] (VMS absolute format)
- remote mkdir [.olga] ; Makes [IVAN.OLGA] (VMS relative format)
-
- 5.3.1.1. Creating Directories
-
- If a directory name is given that contains more than one segment that
- does not exist, the server attempts to create all the segments. For
- example, if the client says:
-
- REMOTE MKDIR letters/angry
-
- a "letters" subdirectory is created in the server's current directory
- if it does not already exist, and then an "angry" subdirectory is
- created beneath it, if it does not already have one. This can repeated
- to any reasonable depth:
-
- REMOTE MKDIR a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/z/y/z
-
- 5.3.1.2. Removing Directories
-
- When attempting to execute a REMOTE RMDIR, the server can remove only a
- single directory, not an entire sequence or tree. The system service
- that is called to remove the directory generally requires not only that
- the server process has write delete access, but also that the directory
- contain no files.
-
- In the future, a REMOTE RMDIR /RECURSIVE command (and the accompanying
- protocol) might be added. For now, use the equivalent REMOTE HOST
- command(s), if any.
-
- 5.3.2. Directory Listings
-
- Directory listings are generated by C-Kermit itself, rather than by
- running the underlying system's directory command. Some control over
- the listing format can be obtained with the SET OPTIONS DIRECTORY
- command ([540]Section 4.5.1). The following options affect listings
- sent by the server: /[NO]HEADING, /[NO]DOTFILES, and /[NO]BACKUP. In
- UNIX and VMS, the listing is always sorted by filename. There is, at
- present, no protocol defined for the client to request listing options
- of the server; this might be added in the future.
-
- The server's directory listings are in the following format:
-
- Protection or permissions:
- In UNIX and OS-9, this is a 10-character field, left adjusted.
- In VMS it is a 22-character field, left-adjusted. In each case,
- the protection / permission codes are shown in the server
- platform's native format. In other operating systems, this field
- is not shown.
-
- Size in bytes:
- This is always a 10-character field. The file's size is shown as
- a decimal number, right adjusted in the field. If the file is a
- directory and its size can not be obtained, the size is shown as
- "<DIR>". Two blanks follow this field.
-
- Date:
- Always in yyyy-mm-dd hh:mm:ss numeric format, and therefore 19
- characters long. If the file's date/time can't be obtained,
- zeros (0) are shown for all the digits. This field is followed
- by two blanks.
-
- Filename:
- This field extends to the end of the line. Filenames are shown
- relative to the server's current directory. In UNIX, symbolic
- links are shown as they are in an "ls -l" listing as "linkname
- -> filename".
-
- In UNIX and VMS, listings are returned by the server in alphabetical
- order of filename. There are presently no other sort or selection
- options.
-
- However, since these are fixed-field listings, all fields can be used
- as sort keys by external sort programs. Note, in particular, that the
- format used for the date allows a normal lexical on that field to
- achieve the date ordering. For example, let's assume we have a UNIX
- client and a UNIX server. In this case, the server's listing has the
- date in columns 22-40, and thus could be sorted by the UNIX sort
- program using "sort +0.22 -0.40" or in reverse order by "sort +0.22
- -0.40r".
-
- Since the UNIX client can pipe responses to REMOTE commands through
- filters, any desired sorting can be accomplished this way, for example:
-
-C-Kermit> remote directory | sort +0.22 -0.40
-
- You can also sort by size:
-
- C-Kermit> remote directory | sort +0.11 -0.19
-
- You can use sort options to select reverse or ascending order. "man
- sort" (in UNIX) for more information. And of course, you can pipe these
- listings through any other filter of your choice, such as grep to skip
- unwanted lines.
-
- 5.4. Syntax for Remote Filenames with Embedded Spaces
-
- C-Kermit and K95, when in server mode, assume that any spaces in the
- file specification in an incoming GET command are filename separators.
- Thus if the client gives a command like:
-
- get {oofa.txt oofa.bin}
-
- or, equivalently:
-
- mget oofa.txt oofa.bin
-
- the server tries to send the two files, oofa.txt and oofa.bin. But what
- if you want the server to send you a file named, say:
-
- D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL
-
- How does the server know this is supposed to be one file and not seven?
- In this case, you need to the send file name to the server enclosed in
- either curly braces:
-
- {D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL}
-
- or ASCII doublequotes:
-
- "D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL"
-
- The method for doing this depends on your client. If your client is
- C-Kermit 7.0, any recent version of Kermit 95, or MS-DOS Kermit 3.16,
- then you have to enclose the name in braces just so the client can
- parse it, so to send braces or doublequotes to the server, you must put
- them inside the first, outside pair of braces. And you also need to
- double the backslashes to prevent them from being interpreted:
-
- get {{D:\\HP OfficeJet 500\\Images\\My Pretty Picture Dot PCL}}
- get {"D:\\HP OfficeJet 500\\Images\\My Pretty Picture Dot PCL"}
-
- To get around the requirement to double backslashes in literal
- filenames, of course you can also use:
-
- set command quoting off
- get {{D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL}}
- get {"D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL"}
- set command quoting on
-
- If you are giving a "kermit" command to the UNIX shell, you have to
- observe the shell's quoting rules, something like this:
-
- kermit -ig "{D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL}"
-
- Here, the quotes go on the outside so UNIX will pass the entire
- filename, spaces, braces, and all, as a single argument to Kermit, and
- the backslashes are not doubled because (a) the UNIX shell ignores them
- since they are in a quoted string, and (b) Kermit ignores them since
- the interactive command parser is not activated in this case.
-
- 5.5. Automatic Orientation Messages upon Directory Change
-
- C-Kermit 7.0, when acting as a server, can send an orientation message
- to the client whenever the server directory changes. For example, when
- the client gives a REMOTE CD command, the server sends the contents of
- the new directory's "Read Me" file to the client's screen. The
- following commands govern this feature:
-
- SET SERVER CD-MESSAGE FILE name
- Given to the servr, allows the message-file name to be specified
- at runtime. A list of names to look for can be given in the
- following format:
-
- {{name1}{name2}{name3}{...}}
-
- e.g. SET SERVER CD-MESSAGE FILE
- {{./.readme}{README.TXT}{READ.ME}}
-
- REMOTE SET SERVER CD-MESSAGE { ON, OFF }
- Given to the client, lets the client control whether the server
- sends automatic CD messages.
-
- SHOW SERVER
- Given to server, includes CD-Message status.
-
- The default CD message file name is system dependent. SHOW CD or SHOW
- SERVER displays the list. Also see [541]Section 4.5.2.
-
- 5.6. New Server Controls
-
- DISABLE ENABLE
- Allows the server to configured such that DISABLEd features can
- not be re-enabled by any means -- e.g. if the client is somehow
- able to get the server into command mode. Once DISABLEd, ENABLE
- can not be re-ENABLEd.
-
- SET SERVER IDLE-TIMEOUT seconds
- This was available previously in Kermit 95 only. Now it can be
- used in C-Kermit also to specify a maximum number of seconds the
- server is allowed to be idle before exiting server mode. 0
- seconds means no idle timeout. In C-Kermit (but not K-95), SET
- SERVER TIMEOUT and SET SERVER IDLE-TIMEOUT are mutually
- exclusive -- you can have one or the other (or neither), but not
- both. (Server timeouts are for the benefit of primitive Kermit
- clients that are not capable of timing out on their own; to our
- knowledge, no such clients are still in circulation.)
-
- SET SERVER KEEPALIVE { ON, OFF }
- (See next section).
-
- 5.7. Timeouts during REMOTE HOST Command Execution
-
- Prior to C-Kermit 7.0, the C-Kermit server would block waiting for
- output from a system command invoked via REMOTE HOST from the client.
- If the system command took a long time to execute, the client would
- time out and send NAK packets. If the command took too long, the client
- would reach its retry limit and give up. Even if it didn't, the NAKs
- would cause unnecessary retransmissions.
-
- In version 7.0, the C-Kermit server (VMS and select()-capable UNIX
- versions only), sends "keepalive packets" (empty data packets) once per
- second while waiting for the system command to complete. This procedure
- should be entirely transparent to the Kermit client, and should prevent
- the unwanted timeouts and NAKs. When C-Kermit 7.0 itself (or K95
- 1.1.19) is the client, it prints dots to show the keepalive packets.
-
- The keepalive feature can be turned off and on with:
-
- SET SERVER KEEPALIVE { ON, OFF }
-
- Normally it should be on. Turn it off it if causes trouble with the
- client, or if it seems to slow down the server (as it might on some
- platforms under certain circumstances).
-
- 6. INTERNATIONAL CHARACTER SETS
-
- Support for several new single-byte character sets was added in
- C-Kermit 7.0. Unicode / ISO 10646 is not yet supported, but is a high
- priority for forthcoming releases.
-
- 6.0. ISO 8859-15 Latin Alphabet 9
-
- To accommodate the Euro currency symbol, and to correct several other
- longstanding problems with ISO Latin Alphabet 1, ISO 8859-15 Latin
- Alphabet 9 was issued in May 1998. It is supported by C-Kermit 7.0 as a
- transfer character set, a file character set, and a terminal character
- set. Translations that preserve the new characters are available
- between Latin-9 and several other sets including:
-
- PC Code Page 858 (Western European languages, similar to CP850)
- Windows Code Page 1252 (Western European languages, similar to Latin-1)
- Windows Code Page 1250 (Eastern European languages, similar to Latin-2)
-
- The Latin-9 transfer character set also allows for the OE digraph
- character, used primarily in French, to be preserved in transfers
- involving the DEC MCS or NeXT character sets.
-
- The Euro character is also present in the Universal Character Set,
- described in [542]Section 6.6.
-
- 6.1. The HP-Roman8 Character Set
-
- The HP-Roman8 character set is supported in C-Kermit 6.0 and later but
- was omitted from Table VII-4 in the 2nd Edition of Using C-Kermit due
- to lack of space. It is listed in [543]Appendix III.
-
- 6.2. Greek Character Sets
-
- Greek character sets were added in 6.1:
-
- SET FILE CHARACTER-SET { CP869, ELOT927, GREEK-ISO }
- SET TRANSFER CHARACTER-SET { GREEK-ISO }
-
- GREEK-ISO is ISO 8859-7, which the same as ELOT 928.
-
- The new Greek character sets are listed in [544]Appendix III.
-
- 6.3. Additional Latin-2 Character Sets
-
- The following have been added as FILE and TERMINAL CHARACTER-SETs:
-
- MAZOVIA-PC
- A PC code page used in Poland, equivalent to CP437, but with 18
- substitutions needed for Polish.
-
- CP1250
- The Windows Latin 2 Code Page. Equivalent to ISO 8859-2, but
- with different encoding.
-
- 6.4. Additional Cyrillic Character Sets
-
- The following have been added as FILE and TERMINAL CHARACTER-SETs:
-
- BULGARIA-PC
- This is the Cyrillic PC code page used in Bulgaria, where it is
- called Code Page 856. It is attributed to a company called
- DATEC, Inc, but CP856 is not a proper designation, since it
- refers to a Hebrew Code Page (see the IBM Registry).
-
- CP855
- This PC Code Page contains all the Cyrillic letters that are
- also in ISO 8859-5, and is therefore useful for non-Russian
- Cyrillic text (Ukrainian, Belarusian, etc), unlike CP866, which
- has a smaller repertoire of Cyrillic letters.
-
- CP1251
- The Windows Cyrillic Code Page. Equivalent to CP855, but with
- different encoding.
-
- KOI8R
- An extension to "Old KOI-8" that adds upper and lower case
- Cyrillic letter Io (looks like Roman E with diaeresis) plus a
- selection of box-drawing characters to columns 8 through 11,
- which are vacant in original Old KOI-8. KOI8-R is used for the
- Russian language. It is specified in [545]RFC 1489.
-
- KOI8U
- A similar extension of Old KOI-8, but for Ukrainian. It is
- specified in [546]RFC 2319.
-
- 6.5. Automatic Character-Set Switching
-
- Prior to version 7.0, C-Kermit's file character-set always had to be
- set explicitly. In 7.0 and later, it is set automatically when:
-
- 1. This feature is enabled (as it is unless you disable it).
- 2. An incoming text-mode transfer includes a transfer-character-set
- announcer and you have not previously given a SET FILE
- CHARACTER-SET command. In this case, C-Kermit switches to an
- appropriate file character set. For example, on an HP-UX
- workstation, an incoming Latin-1 file automatically selects
- HP-Roman8 for the local copy of the file; in Data General AOS/VS,
- it would select DG International.
- 3. You give a SET TRANSFER CHARACTER-SET command without having
- previously specified a FILE CHARACTER-SET. An appropriate file
- character-set is chosen automatically.
-
- In addition, when you give a SET FILE CHARACTER-SET command, the
- appropriate transfer character-set is automatically chosen, to be used
- when you are sending files (but this does not override the one
- announced by the sender when you are receiving files).
-
- You might not agree about what is "appropriate", so of course you can
- disable or change all of the above actions.
-
- You can disable (or re-enable) the new automatic character-set
- switching feature in each direction separately:
-
- SET RECEIVE CHARACTER-SET-SELECTION { AUTOMATIC, MANUAL }
- AUTOMATIC is the default, causing the behavior described above
- when an incoming file arrives. Choose MANUAL to defeat this
- behavior and force your current FILE CHARACTER-SET setting to be
- used, no matter what it is. Note that SET RECEIVE CHARACTER-SET
- MANUAL does not disable recognition of the incoming transfer
- character-set announcer, and translation from the corresponding
- character-set to your current file character-set. To disable
- that, use SET ATTRIBUTE CHARACTER-SET OFF.
-
- SET SEND CHARACTER-SET-SELECTION { AUTOMATIC, MANUAL }
- Again AUTOMATIC is the default, causing the behavior described
- above when you give a SET { FILE, TRANSFER } CHARACTER-SET
- command. Use MANUAL to allow you to specify the transfer and
- file character-sets independently.
-
- SHOW CHARACTER-SETS
- Tells settings of { SEND, RECEIVE } CHARACTER-SET-SELECTION.
-
- Normally, however, it is more convenient to leave automatic switching
- active, and change any associations that are not appropriate for your
- application, area, or country. The commands are:
-
- SHOW ASSOCIATIONS
- This command lists all the associations in each direction: for
- each possible transfer character-set, it lists the associated
- file character-set, and vice versa. These are two separate and
- independent lists.
-
- ASSOCIATE TRANSFER-CHARACTER-SET name1 [ name2 ]
- Changes the association for the transfer character-set name1 to
- be the file character-set name2. If name2 is omitted, automatic
- switching is disabled for this transfer character-set only.
-
- ASSOCIATE FILE-CHARACTER-SET name1 [ name2 ]
- Changes the association for the file character-set name1 to be
- the transfer character-set name2. If name2 is omitted, automatic
- switching is disabled for this file character-set only.
-
- 6.6. UNICODE
-
- C-Kermit 7.0 adds support for Unicode, the Universal Character Set,
- for:
-
- * File Transfer (SEND, RECEIVE, GET, etc)
- * Terminal connection (CONNECT)
- * Unguarded file capture (LOG SESSION)
- * Unguarded file transmission (TRANSMIT)
- * Local file character-set conversion (TRANSLATE)
-
- C-Kermit is not, however, a "Unicode application" in the sense that its
- commands, messages, or user interface are Unicode. Rather, it is
- "Unicode aware" in its ability to handle and convert Unicode text in
- the course of file transfer and terminal connection, and you can also
- use Kermit to convert local files between Unicode and other character
- sets. TLA's:
-
- BMP - Base Multilingual Plane
- BOM - Byte Order Mark
- CJK - Chinese, Japanese, and Korean
- ISO - International Standards Organization
- TLA - Three-Letter Acronym
- UCS - Universal Character Set
- UTF - UCS Transformation Format
-
- Unicode and ISO 10646 are the coordinated and compatible corporate and
- international standards for the Universal Character Set (UCS). Unlike
- single-byte and even most multibyte character sets, the UCS can
- represent all characters in every existing writing system. A flat
- plain-text file encoded in some form of UCS can contain any mixture of
- English, Spanish, Italian, German, Hebrew, Arabic, Greek, Russian,
- Armenian, Georgian, Japanese, Chinese, Korean, Vietnamese, Tibetan,
- Hindi, Bengali, Tamil, Thai, Ethiopic, and so on, plus scientific and
- mathematical notation, as well as texts in Runes, Ogham, Glagolitic,
- and other historic scripts.
-
- The UCS already covers these scripts and many more, but it's an
- evolving standard with efforts underway to accommodate even more
- languages and writing systems. Support is growing for native UCS use on
- many platforms and in many applications. The goal of the framers of the
- UCS is for it to replace ASCII, the ISO Latin Alphabets, ISCII, VISCII,
- the Chinese, Japanese, and Korean (CJK) multibyte sets, etc, as well as
- the many private character sets in use today, in other words to become
- *the* Universal Character Set.
-
- Until that time, however, conversions between existing sets and the UCS
- will be necessary when moving text between platforms and applications.
- Now Kermit can help.
-
- 6.6.1. Overview of Unicode
-
- For a more complete picture, please visit:
-
- [547]http://www.unicode.org/
-
- and access the various online introductions, FAQs, technical reports,
- and other information. For greater depth, order the latest version of
- the published Unicode Standard. The following overview contains a great
- many oversimplifications and perhaps an opinion or two.
-
- At present, the UCS is a 16-bit (2-byte) character set, but with
- provisions to grow to a 4-byte set. UCS-2 refers to the two-byte set,
- also called the Base Multilingual Plane (BMP), in which each character
- has 16 bits, and therefore there are 2^16 = 65536 possible characters.
- The first 128 characters are the same as US ASCII (C0 control
- characters and DEL included), the next 32 are the C1 control characters
- of ISO 6429, and the next 96 are the Right Half of ISO 8859-1 Latin
- Alphabet 1. The remaining tens of thousands of characters are arranged
- newly for the UCS, usually (but not always) in sections corresponding
- to existing standards, such as ISO Latin/Cyrillic, often plus
- additional characters not appearing in the existing standards due to
- lack of space (or other reasons).
-
- ISO 10646 allows for additional planes, e.g. for Egyptian hieroglyphics
- or ancient (or other esoteric) CJK characters, but these planes are not
- yet defined and so we will say nothing more about them here, except
- that their use will require the 4-byte form of UCS, called UCS-4, in
- some form (more about "forms" in [548]Section 6.6.2).
-
- Unicode and ISO 10646 are constantly under revision, mainly to add new
- characters. The Unicode revision is denoted by a version number, such
- as 1.0, 1.1, 2.0, 3.0. The ISO 10646 standard revision is identified by
- Edition (such as ISO 10646-1 1993), plus reference to any amendments.
- The first versions of these standards included encodings for Korean
- Hangul syllables (Jamos); these encodings were changed in version 1.1
- of Unicode and by Amendment 5 to ISO 10646-1. The Unicode Technical
- Committee and the ISO acknowledge that this was a bad thing to do, and
- promise never change encodings or character names again, since this
- poses serious problems for conformance and data interchange.
-
- A UCS-2 value is customarily written like this:
-
- U+xxxx
-
- where "xxxx" represents four hexadecimal digits, 0-9 and A-F. For
- example, U+0041 is "A", U+00C1 is A-acute, U+042F is uppercase Cyrillic
- "Ya", U+FB4F is Hebrew Ligature Alef Lamed, and U+FFFD is the special
- character that means "not a character".
-
- Most characters from widely-used alphabetic writing systems such as the
- West European ones, Cyrillic, Greek, Hebrew, Vietnamese, etc, are
- available in "precomposed" form; for example Uppercase Latin Letter A
- with Acute Accent is a single character (as it is in Latin-1). However,
- the UCS also permits composition of a base character with one or more
- nonspacing diacritics. This means the same character can be represented
- in more than one way, which can present problems in many application
- areas, including transfer and character-set conversion of text.
-
- Conversion from ASCII or Latin-1 to UCS-2 text is "trivial": simply
- insert a NUL (0) byte before each ASCII or Latin-1 byte. Converting in
- the reverse direction (provided the UCS-2 file contains only U+0000 to
- U+00FF) is equally simple (if we ignore the issue of composition):
- remove every second (NUL) byte. Conversion of other character sets to
- and from UCS, however, requires tables or algorithms specific to each
- set. Nevertheless, the relatively transparent upwards compatibility
- from ASCII and Latin-1, in which a very large share of the world's
- textual data is encoded, gives the UCS an entree onto existing
- platforms.
-
- But the 2-byte format and the preponderance of NUL and other control
- bytes in UCS-2 text pose problems for current applications and
- transmission methods. And to make matters worse, different hardware
- platforms store UCS-2 characters in different byte order. Thus a UCS-2
- file transferred by FTP (or accessed via NFS, etc) between two
- computers with different architecture might have its bytes in the wrong
- order (or worse; see [549]Section 6.6.5.1 ).
-
- 6.6.2. UCS Byte Order
-
- Consider the number 1. In an 8-bit byte, this would be represented by
- the following series of 0- and 1-bits:
-
- +-----------------+
- | 0 0 0 0 0 0 0 1 |
- +-----------------+
-
- Therefore in a 16-bit "word" the representation might be:
-
- +-----------------+-----------------+
- | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 |
- +-----------------+-----------------+
-
- Now consider the number 256, which is 2 to the 8th power. The binary
- representation is 100000000 (1 followed by 8 zeros). 256 would go into
- a 16-bit word like this:
-
- +-----------------+-----------------+
- | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 |
- +-----------------+-----------------+
-
- When a computer works this way, it is said to be Big Endian, meaning it
- puts the most significant (biggest) byte first (on the "left") in a
- 16-bit word, and the least significant byte second (on the right).
-
- However, some other computers have the opposite arrangement, called
- Little Endian, in which 1 is:
-
- +-----------------+-----------------+
- | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 |
- +-----------------+-----------------+
-
- and 256 is:
-
- +-----------------+-----------------+
- | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 |
- +-----------------+-----------------+
-
- Computers such as Sparc, MIPS, PA-RISC, and PowerPC are Big Endian,
- whereas the PC and the Alpha are Little Endian. Endianness has never
- been an issue with 7- or 8-bit characters, but it is with UCS
- characters. It can be a tricky business to share or transfer a UCS-2
- file between two different kinds of computers.
-
- To alleviate (but not entirely solve) the problem, UCS-2 files are
- supposed to begin with the Unicode character U+FEFF, Zero-Width
- No-Break Space (ZWNBS). This is a kind of "no-op" (note: any such
- assertion must normally be qualified with many "but ifs" and "excepts"
- which are omitted here in the interest of brevity). If the bytes are
- reversed the ZWNBS becomes U+FFFE, which is not (and never will be) a
- defined UCS character. U+FEFF at the beginning of a UCS file is
- therefore called a Byte Order Mark, or BOM.
-
- Any application that creates a UCS-2 (or UTF-16, or UCS-4) file should
- include a BOM, and any application that reads one should test for a
- BOM, and if one is found, infer the byte order from it. This is a
- convention, however -- not a standard or a requirement -- and
- applications vary in their ability to handle BOMs and "backwards" UCS-2
- files.
-
- Note that a BOM is useful only at the beginning of a file. If you
- append one UCS-2 file to another, and both have BOMs, the internal BOM
- is no longer a BOM. And if the byte orders of the two files differ,
- then either the first part or the second will be backwards. (Various
- other undesirable effects might also occur, not discussed here.)
-
- 6.6.2. UCS Transformation Formats
-
- UCS textual data can be modified in various ways for transmission or
- storage. Any officially sanctioned method of doing this is called a UCS
- Transformation Format, or UTF. One such method, called UTF-16, is
- essentially identical with UCS-2 except that it designates certain code
- values as "escape sequences" (called surrogate pairs) to access
- characters in other planes without having to use full UCS-4. We won't
- discuss UTF-16 further here, since at the moment there are no other
- planes. Several other UTF's (such as UTF-1, UTF-2, and UTF-7) have
- fallen into disuse and are not discussed here. The most important
- transformation format today is UTF-8.
-
- UTF-8, so called because it "serializes" UCS-2 data into a stream of
- 8-bit bytes, is designed to allow the UCS to work with present-day
- communications gear, computers, and software. The most important
- properties of UTF-8 are that byte order is constant (no byte swapping)
- and all (7-bit) ASCII characters represent themselves. Therefore
- conversion between ASCII and UTF-8 is no conversion at all, and
- applications or platforms (such as Plan 9 from Bell Labs) that use
- UTF-8 "for everything" can still run traditional ASCII-only
- applications and be accessed from them. In particular, unlike UCS-2,
- ASCII characters are not padded with NUL bytes. But also unlike UCS-2,
- there is no transparency for Latin-1 or any other non-ASCII character
- set. Every non-ASCII UCS-2 character is represented by a sequence of 2
- or 3 UTF-8 bytes. Thus UTF-8 is more compact than UCS-2 for text
- containing a preponderance of ABC's (or other ASCII characters), about
- the same as UCS-2 for other alphabetic scripts (Cyrillic, Roman, Greek,
- etc), and larger than UCS-2 for Chinese, Japanese, and Korean.
-
- The UTF-8 uncoding of the UCS has been adopted by the Internet as the
- preferred character set for new applications, and is gradually being
- retrofitted into traditional applications like FTP ([550]RFC 2640).
-
- 6.6.3. Conformance Levels
-
- Although the Unicode and ISO 10646 standards both describe the same
- character set, these standards differ in many ways, including their
- stated requirements for conformance and their classification of
- conformance levels.
-
- Kermit has always abided by ISO character-set standards, including ISO
- character-set designation and invocation methods. In adapting Unicode,
- therefore, we had to choose from among the available ISO designations
- which, in turn, correspond with ISO 10646 conformance levels. At
- present, Kermit claims the lowest conformance level, 1, meaning
- (roughly) that it does not handle combining forms and it does not
- handle Korean Hangul Jamos (just as, at present, it does not handle
- Korean in general). Note that ISO 10646 Conformance Levels 1 and 2
- sidestep the issue of the code changes for Korean Hangul by announcing
- non-support for Hangul regardless of encoding.
-
- ISO 10646 Conformance Level 1 is approximately equivalent to Unicode
- Normalization Form C (described in Unicode Technical Report 15,
- incorporated into Unicode 3.0).
-
- As noted in [551]Section 6.6.2, Kermit does not claim to support UTF-16
- at the present time, hence the UCS-2 nomenclature. Kermit treats
- surrogates just as if they were any other UCS-2 characters, rather than
- as escapes to other planes, which means that (except when converting
- between UCS-2 and UTF-8) they are translated to "error" characters,
- since (a) no other planes are defined yet (and if they were, no other
- character sets supported by Kermit would encode their characters), and
- (b) no valid surrogate character corresponds to any other UCS-2
- character.
-
- A minor yet significant aspect of Unicode 3.0 and some recent
- perturbation of ISO 10646-1 (probably Amendment 18, "Symbols and Other
- Characters") is the addition of the Euro Sign at U+20AC. As noted in
- [552]Section 6.0, Kermit's "Euro compliance" includes conversion
- between Latin Alphabet 9 and various PC code pages. Text can also be
- converted between UCS-2 or UTF-8 and any other Euro-compliant character
- set (Latin-9, CP858, CP1250, CP1252) without loss of the Euro Sign.
-
- 6.6.4. Relationship of Unicode with Kermit's Other Character Sets
-
- Kermit's character sets are divided into two groups: single-byte sets
- (such as Roman, Hebrew, Cyrillic, Greek) and multibyte (various
- Japanese sets). The two groups are distinct since one normally would
- not expect to convert Kanji ideograms to Roman (or other) letters, or
- vice versa.
-
- Unicode character-set conversion works with both groups, but obviously
- the result depends on the repertoires of the source and destination
- character-sets both including the characters in the file. For example,
- you can translate a Hungarian text file between Latin-2 and Unicode,
- but not between (say) Unicode and Latin/Greek. By the same token you
- can convert Japanese text from Shift-JIS or EUC or JIS-7 to Unicode and
- back, but you can't convert the same file to (say) Latin-1 if it
- contains Japanese characters.
-
- JIS-7 is equivalent to DEC Kanji and ISO-2022-JP except that the
- latter two do not support halfwidth Katakana. Kermit treats all
- three of these sets the same way, i.e. as JIS-7.
-
- As noted, Kermit presently does not handle combining diacritics, and so
- will not correctly convert UCS files that use them into a single-byte
- character set. For example, if a UCS file contains Latin Capital Letter
- A (U+0041) followed by Combining Acute Accent (U+0301), the result will
- be a two-character sequence, A followed by another character. This is
- what is meant by Conformance Level 1. (The situation grows worse with
- multiple diacritics, since they can occur in any order.)
-
- A higher level of conformance is possible, in which "canonical
- equivalences" are handled via algorithms and databases, at some
- (perhaps considerable) cost in performance, since a fair amount of
- additional code must be executed for every character during data
- transfer (database lookup, sorting of combining sequences into
- canonical order, etc). This can be added in future releases if there is
- a need (but in many cases, pre- and postpostprocessing might be a
- better option).
-
- Within these constraints, Kermit converts between the UCS and its other
- character sets. For example, a mixture of Russian and English (and/or
- Dutch, or Latin) text can bet converted between the UCS and ISO
- Latin/Cyrillic or KOI-8. But since Kermit does not presently support
- Arabic character-set conversion, the new availability of UCS conversion
- does not mean that Kermit can convert from Arabic UCS text to some
- other character set, because Kermit does not support any other
- character set that includes Arabic. Ditto for Thai, Armenian, Georgian,
- Tibetan, Chinese, Korean, etc. However, Kermit CAN convert Arabic (or
- any other script) between UCS-2 and UTF-8.
-
- Considering Cyrillic more carefully, note that the UCS also contains
- numerous Cyrillic characters not found in any of the Cyrillic sets (ISO
- Latin/Cyrillic, KOI8, CP866, etc) that Kermit supports; characters
- needed for Abkhasian, Yakut, Tatar, Bashkir, Altaic, Old Church
- Slavonic, etc; UCS text containing any of these historic or "extended"
- Cyrillic characters can not be converted to any of Kermit's current
- single-byte Cyrillic sets without loss. The situation is similar for
- Greek, Hebrew, etc, and even worse for Japanese since Unicode contains
- thousands of Kanjis that are lacking from the Japanese character sets
- based on JIS X 0208, such as EUC-JP, JIS-7, and Shift-JIS.
-
- In general, when converting from UCS to a single-byte set, there is
- always the possibility of data loss, just as there is when converting
- from any larger set to a smaller one. For example, if a UCS file
- contains Devanagari characters, these characters will be lost when
- converting to (say) Latin-1, just as Roman vowels with acute accents
- are lost when converting from Latin-1 (an 8-bit set) to German ISO 646
- (a 7-bit set).
-
- 6.6.5. Kermit's Unicode Features
-
- C-Kermit can convert between UCS-2 or UTF-8 and any of its other
- character sets, and also between UCS-2 and UTF-8. When converting
- between UCS-2 or UTF-8 and a non-Unicode character set (such as
- Latin-1), the UCS Line Separator (LS, U+2028) and Paragraph Separator
- (PS, U+2029) characters are converted to the appropriate line
- terminator (CR, LF, or CRLF). When converting from a non-Unicode set to
- UCS-2 or UTF-8, however, line terminators are not converted to LS or
- PS. This is in accordance with the recommendations of Unicode Technical
- Report #13.
-
- When C-Kermit starts, it tests the native byte order of the computer.
- You can see the result in the SHOW FEATURES or SHOW FILE display. It's
- also available in the variable \v(byteorder): 0 means Big Endian, 1
- means Little Endian.
-
- When UCS-2 is involved in file transfer or translation, the following
- commands tell C-Kermit what to do about byte order:
-
- SET FILE UCS BYTE-ORDER { BIG-ENDIAN, LITTLE-ENDIAN }
- This is for reading UCS-2 files that don't have a BOM, and also
- for writing UCS-2 files. If this command is not given, the
- machine's native byte order is used when writing UCS-2 files,
- and also when reading UCS-2 files that don't have a BOM.
-
- SET FILE UCS BOM { ON, OFF }
- This setting is used when creating UCS-2 files. A BOM is added
- at the beginning by default. Use OFF to not add the BOM. This
- command has no affect when writing files.
-
- COPY /SWAP-BYTES sourcefile destinationfile
- Use this for fixing a UCS-2 file whose bytes are in the wrong
- order.
-
- Use SHOW FILE to display the FILE UCS settings.
-
- Please note, again, that C-Kermit's user interface, including its
- script language, is not internationalized in any way. String
- comparisons, case conversion, and so on, work only for US ASCII
- (comparisons for equality work with other sets, but not
- lexically-greater-or-less-than or caseless comparisons; even
- comparisons for equality can fail when composed characters or byte
- order are involved). String functions such as \findex() and
- \fsubstring() that reference byte positions do just that; they won't
- work with UTF-8 text that contains any non-ASCII characters, and they
- will not work with UCS-2 text at all since they use C strings
- internally, which are NUL-terminated. These are just a few examples to
- illustrate that neither Unicode nor any other character-set beyond
- ASCII is supported at the user-interface, command, or scripting level
- in this version of C-Kermit.
-
- 6.6.5.1. File Transfer
-
- Kermit supports both UCS-2 and UTF-8 as file and transfer character
- sets in text-mode file transfer.
-
- To select UCS-2 or UTF-8 as a file character-set, use:
-
- SET FILE CHARACTER-SET { UCS2, UTF8 }
-
- If you want to send a UCS-2 text file (or save an incoming file in
- UCS-2 format), tell Kermit to:
-
- SET FILE CHARACTER-SET UCS2
-
- and if you want to send a UTF-8 text file (or store an incoming file in
- UTF-8 format), tell Kermit to:
-
- SET FILE CHARACTER-SET UTF8
-
- When sending UCS-2 files, Kermit determines the byte order from the
- BOM, if there is one (and if there is a BOM, it is stripped, i.e. not
- sent). If there is no BOM, the byte order is the one specified in the
- most recent SET FILE UCS BYTE-ORDER command, if any, otherwise the
- computer's native byte order is assumed. When storing incoming files as
- UCS-2, the byte order is according SET FILE UCS BYTE-ORDER, if given,
- otherwise the native one; a BOM is written according to SET FILE UCS
- BOM.
-
- A transfer character-set should be chosen that includes all of the
- characters in the source file. So, for example, if you are sending a
- UCS-2 file containing only German-language text, your transfer
- character-set can be Latin-1, Latin-2, Latin-9, UCS-2, or UTF-8. But if
- you are sending a file that contains a combination of Hebrew and Greek,
- your transfer character-set must be UCS-2 or UTF-8 if you don't want to
- lose one script or the other. Furthermore, the transfer character-set
- must be one that is supported by the receiving Kermit program. Since
- UCS support is new, it is possible that the other Kermit program (if it
- supports character sets at all) does not support it, but does support
- single-byte sets such as Latin-1, Latin/Cyrillic, etc.
-
- To select UCS-2 or UTF-8 as a transfer character-set, use:
-
- SET TRANSFER CHARACTER-SET { UCS2, UTF8 }
-
- It is up to the receiving Kermit program to convert the transfer format
- to its own local format, if necessary. If it does not understand the
- UTF-8 or UCS-2 transfer character-set, and your file can not be
- adequately represented by any single-byte transfer character-set (such
- as Latin-1 or Latin/Cyrillic) then, if UTF-8 format is acceptable on
- the receiving computer, use UTF-8 as the transfer character-set, with
- the receiver told to "set unknown-char keep", or with the sender told
- to "set attribute char off". If you want the file to be stored in UCS-2
- format at the receiver, send it it binary mode if the source file is
- also UCS-2, or else use the TRANSLATE command (next section) to convert
- it to UCS-2 first, then send it in binary mode. You should not use
- UCS-2 as a transfer character-set in text-mode transfers to Kermit
- programs that don't support it, because they are likely to corrupt the
- result the same way FTP would (see the final paragraph of this
- section).
-
- When UCS-2 is the transfer character set, it always goes into Kermit
- packets in Big Endian format, with no BOM. As always, the transfer
- character-set is announced by the sender to the receiver. The
- announcement for UCS-2 is "I162" (ISO Registration 162 = UCS-2 Level 1)
- and by definition it is Big Endian (the standards say that when UCS-2
- is serialized into bytes, the order must be Big Endian). The
- announcement for UTF-8 is "I190" (UTF-8 Level 1).
-
- When receiving a file whose transfer character-set is UCS-2 or UTF-8,
- you must choose the appropriate file character set for the result.
- There is no way Kermit can do this for you automatically, since UCS
- data can be in any script at all, or any combination.
-
- In general, UTF-8 or UCS-2 should be chosen as a transfer character-set
- if the source file is also encoded in some form of UCS and it contains
- more than one script. But there are other situations where where UTF-8
- or UCS-2 offer advantages. For example, suppose the source file is on a
- NeXTstation and the destination file is on VMS. Both the NeXT and the
- DEC Multinational character sets include the French OE digraph, but
- Latin-1 does not. Therefore French words containing this character
- might not arrive intact when Latin-1 is the transfer character-set, but
- will with UTF-8 or UCS-2, since the UCS includes the OE digraph (but so
- does Latin-9).
-
- UCS-2 should be chosen as a transfer character-set only for Japanese
- text files that contain a large preponderance of Kanji, since in this
- case (and only this case) UCS-2 (two bytes per Kanji) is more efficient
- than UTF-8 (three bytes per Kanji). The same will be true for Chinese
- and Korean when they are supported by Kermit. UCS-2 should never be
- used as a transfer character-set with a transfer partner that does not
- support UCS-2 since this can cause file corruption (see last paragraph
- in this section).
-
- Note that Kermit's repeat-count compression is 100% ineffective for
- UCS-2, and is also ineffective for multibyte characters in UTF-8 and
- EUC-JP; this is because repeat-compression is a transport-level
- mechanism that operates on a per-byte basis; it has no knowledge of the
- distinction between a byte and a character.
-
- When C-Kermit starts, it sets up associations ([553]Section 6.5) for
- incoming files whose transfer character sets are UCS-2 or UTF-8
- appropriately for the platform so that the file character-set for the
- incoming file is UCS-2 in Windows and UTF-8 elsewhere. Otherwise,
- C-Kermit does not make any default associations for UCS-2 or UTF-8, but
- of course you may add or change associations to suit your needs and
- preferences by including the appropriate ASSOCIATE commands in your
- Kermit startup file. For example, if you are a PC user and deal only
- with text written in Greek and English, you can:
-
- ASSOCIATE TRANSFER-CHARACTER-SET UTF8 CP869
- ASSOCIATE TRANSFER-CHARACTER-SET UCS2 CP869
- ASSOCIATE FILE-CHARACTER-SET CP869 UTF8
-
- Note that when file transfer involves conversion between a single-byte
- character set and UCS-2 or UTF-8, the file-transfer thermometer and
- estimated time left might be inaccurate, since they are based on the
- source file size, not the transfer encoding. This is purely a cosmetic
- issue and does not effect the final result. (And is not, strictly
- speaking, a bug; Kermit protocol presently includes no method for the
- sender to furnish an "estimated transfer size" to the receiver, and in
- any case any such guess could be as far off as the file size, given the
- many other factors that come into play, such as compression and
- prefixing).
-
- A caution about FTP and UCS-2. As noted previously, if you transfer a
- UCS-2 file with FTP in binary mode between two computers with opposite
- Endianness, the result will have its bytes in the wrong order. However,
- if you use FTP to transfer a UCS-2 file in "ascii" (text) mode to ANY
- computer, even if it is identical to yours, the result will be
- corrupted because FTP's line-terminator conversions do not account for
- UCS-2. The same holds when sending from a UCS-aware Kermit program to
- an older Kermit program in text mode with a transfer character-set of
- UCS-2. So use UCS-2 as a transfer character-set ONLY with a UCS-2-aware
- Kermit partner.
-
- 6.6.5.2. The TRANSLATE Command
-
- In Kermit versions that have Unicode support included, TRANSLATE now
- always goes through Unicode; that is, the source set is converted to
- UCS-2 and thence to the target set. This is a major improvement, since
- in prior releases, C-Kermit had to pick the "most appropriate" transfer
- character-set as the intermediate set, and this would result in the
- loss of any characters that the source and target sets had in common
- but were lacking from the intermediate set (for example the OE digraph
- when translating from NeXT to DEC MCS through Latin-1). This never
- happens when Unicode is the intermediate set because Unicode is a
- superset of all other character sets supported by Kermit. A more
- dramatic example would be translation between Cyrillic PC code page 866
- and KOI8-R ([554]Section 6.4); formerly all the line- and box-drawing
- characters would be lost (since ISO 8859-5 does not have any); now the
- ones that these two sets have in common are preserved.
-
- UCS-2 and UTF-8 are now both supported as source-file and
- destination-file character sets by C-Kermit's TRANSLATE command, for
- example:
-
- translate oofa.txt ucs2 latin1 oofa-l1.txt
-
- translates oofa.txt from UCS-2 to Latin-1, storing the result as
- oofa-l1.txt. Similarly:
-
- translate oofa.txt utf8 latin1 oofa-l1.txt
- translate oofa.txt latin1 ucs2 oofa-ucs2.txt
- translate oofa.txt latin1 utf8 oofa-utf8.txt
- translate oofa.txt ucs2 utf8 oofa-utf8.txt
- translate oofa.txt utf8 ucs2 oofa-ucs2.txt
-
- Treatment of the UCS-2 BOM is exactly the same as for file transfer.
- Note that if a UCS-2 source file is in the "wrong" byte order and lacks
- a BOM, and you don't tell Kermit about it with SET FILE UCS BYTE-ORDER,
- the result of the translation is total gibberish. Recall that you can
- use COPY /SWAP-BYTES to switch the byte order of an errant UCS-2 file
- (or any other file for that matter, if you can think of a reason to).
- Also note that:
-
- translate oofa.txt ucs2 ucs2 new.txt
-
- Produces a result in the native (or SET FILE UCS) byte-order as long as
- oofa.txt has a BOM.
-
- As a side benefit of the Unicode work, the TRANSLATE command now works
- for the first time also for all Japanese character sets that Kermit
- supports. In other words, if you have a Japanese text file in any of
- the following encodings:
-
- EUC-JP
- Shift-JIS
- JIS-7
- UCS-2
- UTF-8
-
- You can use the TRANSLATE command to convert to any other encoding from
- the same list.
-
- 6.6.5.3. Terminal Connection
-
- The CONNECT command now allows UTF-8 as a local or remote terminal
- character-set:
-
- SET TERMINAL CHARACTER-SET { ..., UTF8 } { ..., UTF8 }
- SET TERMINAL REMOTE-CHARACTER-SET { ..., UTF8 }
- SET TERMINAL LOCAL-CHARACTER-SET { ..., UTF8 }
-
- (Recall that Kermit's terminal character-set has two "ends" -- the set
- used on the host to which Kermit is connected, and the set used on the
- local keyboard and screen.)
-
- UCS-2 is not supported as a terminal character-set (either end) since
- (a) it is not used that way anywhere to our knowledge, and (b) the
- problems of Endianness and the high likelihood of loss of
- synchronization make it impractical. (Telecommunications is
- byte-oriented; if one byte, or any odd number of bytes, is lost because
- of buffer overruns, circuit resets, etc (or likewise if a burst of
- noise appears that takes the guise of an odd number of bytes), the byte
- order of the subsequent data stream will be backwards; unlike UTF-8 and
- traditional byte-based character sets, UCS-2 is not "self
- synchronizing".)
-
- UTF-8 does not have byte-order or synchronization problems and is
- growing in popularity as a terminal character set as well as in other
- application areas. It allows a single terminal session to use multiple
- scripts (Roman, Cyrillic, Greek, etc) without ISO 2022 character-set
- switching (which terminal emulators like Kermit 95 can handle but few
- host applications understand or use), and meshes nicely with the
- Unicode screen fonts that are beginning to appear.
-
- UTF-8 was first used in Plan 9 and soon will be available in Linux. It
- will probably spread from there (Unicode in some form is, of course,
- also used in Windows NT, but only internally -- not for access from
- outside).
-
- To use UTF-8 or any other character set that uses 8-bit bytes in your
- terminal session, be sure to tell C-Kermit to:
-
- SET TERMINAL BYTESIZE 8
- SET COMMAND BYTESIZE 8
- SET PARITY NONE
-
- (or use the shortcut command, EIGHTBIT, which does all three at once).
-
- In a setup where your local Kermit program uses a single-byte character
- set such as PC Code Page 850 and the remote host uses UTF-8:
-
- SET TERM CHAR UTF8 CP850
-
- or:
-
- SET TERM REMOTE CHAR UTF8
- SET TERM LOCAL CHAR CP850
-
- all works as expected. UTF-8 text on the remote displays correctly on
- your screen, and when you type CP850 characters, they are translated to
- UTF-8 sequences for transmission, and the echo from the host is
- translated from UTF-8 back to CP850. Telnet negotiations and
- autodownload take place before any character-set translation and work
- as before. The session log (if text mode was selected for it) contains
- only the local terminal character-set. And so on.
-
- Kermit merely supplies translations from UTF-8 to your local terminal
- character-set (this includes treating UTF-8 Line Separator and
- Paragraph separator as CRLF). However, Kermit does does not, at
- present, perform "canonicalization" of composed sequences, nor does it
- automatically execute bidirectionality algorithms for display of
- mixed-direction text (e.g. Hebrew and English). Such presentation
- issues, like all others in the terminal-host regime, are left to the
- host.
-
- By the way, C-Kermit also allows UTF-8 to be the local end of the
- terminal character-set, but so far this code is not tested, since we
- don't have a UTF-8 console or terminal to work with. However, it can be
- stated without doubt that C-Kermit's key mapping will not work for
- UTF-8 values, since (a) the key map is indexed by 8-bit byte values and
- (b) C-Kermit reads keystrokes a byte at a time (these comments do not
- apply to K95, which has direct access to the keyboard and can read
- "wide" keycodes and uses them to index a "wide" keymap).
-
- Restrictions: As noted, the CONNECT command does not support UCS-2 as a
- REMOTE TERMINAL character-set. Neither does it support the Japanese
- sets EUC-JP, JIS-7, and Shift-JIS. Support for the Japanese sets (and
- possibly Chinese and Korean too) might be added in a future release.
- Since the TRANSMIT command (next section) uses the same REMOTE TERMINAL
- character-sets as the CONNECT command, it has the same restrictions.
-
- 6.6.5.4. The TRANSMIT Command
-
- As described in Chapter 15 of [555]Using C-Kermit and [556]Section 4.21
- of this document, the TRANSMIT command can be used to upload a file
- without protocol, more or less as if you were typing it on your
- keyboard while connected to the host. When TRANSMITting in text mode,
- the file's character set is converted to the host's unless you have SET
- TERMINAL CHARACTER-SET TRANSPARENT, or you include the new TRANSMIT
- switch, /TRANSPARENT.
-
- Before C-Kermit 7.0, the file character-set was assumed to be the same
- as the local end of the terminal character-set, and the TRANSMIT
- command used the same translations as the CONNECT command, ignoring the
- file character-set.
-
- In C-Kermit 7.0, that assumption (a poor one to begin with) can no
- longer be made, since UCS-2 can be a file character-set but not a
- terminal character-set. So now the file's character-set is given by
- your most recent SET FILE CHARACTER-SET command. The host's character
- set is the remote end of your most recent SET TERMINAL CHARACTER-SET
- command:
-
- SET TERMINAL CHARACTER-SET remote-set [ local-set ]
-
- or:
-
- SET TERMINAL REMOTE-CHARACTER-SET remote-set
-
- The TRANSMIT command converts each source-file character from the FILE
- character-set to the REMOTE TERMINAL character-set, and then transmits
- the translated characters according to your SET TRANSMIT preferences
- (Chapter 15).
-
- If you have SET TRANSMIT ECHO ON, and the host is echoing the
- transmitted characters, the echos are converted from the remote
- terminal character-set to the local terminal character-set.
-
- [ A picture would help... ]
-
- Confused? Let's work through an example. Suppose your local computer is
- a NeXTstation, on which text files are encoded in the NeXT character
- set, and that the remote computer is a Data General AViiON, which uses
- the Data General International character set. Further suppose that you
- are logged in to the NeXT from a VT220 terminal which uses the DEC
- Multinational character set.
-
- You need to convert the file from NeXT encoding to DG encoding and
- convert the echoes from DG encoding to DEC encoding. So on the NeXT,
- tell C-Kermit to:
-
- eightbit
- set file character-set next
- set term character-set dg-international dec-mcs
- transmit /text nextdata.txt
-
- (This assumes you have some sort of collection process already set up
- on the Data General, such as a text editor or the venerable "cat >
- foo". The EIGHTBIT command is equivalent to SET TERMINAL BYTESIZE 8,
- SET COMMAND BYTESIZE 8, SET PARITY NONE.)
-
- To further complicate matters, suppose your local terminal character
- set is the same as the remote one, so you don't need terminal
- character-set translation, but you need to TRANSMIT a file that is in a
- different character set and you want it translated to the host set. In
- this case, use SET TERM CHARACTER-SET to actually specify the character
- set used on each end, rather than specifying TRANSPARENT:
-
- eightbit
- set file character-set ucs2
- set term character-set latin1 latin1
- transmit /text ucs2data.txt
-
- The distinction between:
-
- SET TERMINAL CHARACTER-SET xxx yyy
-
- (where xxx and yyy are the same set) and:
-
- SET TERMINAL CHARACTER-SET TRANSPARENT
-
- is new to C-Kermit 7.0, but affects only the TRANSMIT command.
-
- The TRANSMIT command currently does nothing special with UCS-2/UTF-8
- Line and Paragraph Separator characters; more experience is required to
- find out how these behave in a genuine Unicode terminal-host setting.
-
- Restrictions: As noted, the TRANSMIT command translates from the FILE
- character-set to the REMOTE TERMINAL character-set. This rules out
- translations to any character set that is not supported as a REMOTE
- TERMINAL character-set, such as UCS-2, EUC-JP, JIS-7, and Shift-JIS.
-
- 6.6.5.5. Summary of Kermit Unicode Commands
-
- Specifying file character-set and byte order:
- SET FILE CHARACTER-SET { ..., UCS2, UTF8 }
- REMOTE SET FILE CHARACTER-SET { ..., UCS2, UTF8 } (See next
- section)
- SET FILE UCS BOM { ON, OFF }
- SET FILE UCS BYTE-ORDER { BIG-ENDIAN, LITTLE-ENDIAN }
-
- Specifying the transfer character-set:
- SET TRANSFER CHARACTER-SET { ..., UCS-2, UTF-8 }
- REMOTE SET TRANSFER CHARACTER-SET { ..., UCS-2, UTF-8 }
-
- Specifying the terminal character-set:
- SET TERMINAL CHARACTER-SET { ..., UTF8 } { ..., UTF8 }
- SET TERMINAL REMOTE-CHARACTER-SET { ..., UTF8 }
- SET TERMINAL LOCAL-CHARACTER-SET { ..., UTF8 }
-
- Displaying settings:
- SHOW FILE
- SHOW TRANSFER
- SHOW TERMINAL
- SHOW CHARACTER-SETS
-
- Commands that use these settings include:
- SEND, RECEIVE, GET, etc.
- CONNECT
- TRANSMIT
- LOG SESSION
-
- Converting files:
- TRANSLATE infile { ..., UCS-2, UTF-8 } { ..., UCS-2, UTF-8 }
- outfile
- COPY /SWAP-BYTES infile outfile
-
- 6.7. Client/Server Character-Set Switching
-
- A simple mechanism has been added to allow the client to change the
- server's FILE CHARACTER-SET:
-
- REMOTE SET FILE CHARACTER-SET name
- The client asks the server to change its file character-set to
- the one given. The name must match one of the server's file
- character-set names. For convenience, C-Kermit uses its own file
- character-set keyword list for parsing this command so you can
- use ? for help and Tab or Esc for completion. However, since the
- server might have a different repertoire (or even use different
- names for the same sets), C-Kermit accepts any string you supply
- and sends it to the server. The server, if it supports this
- command (C-Kermit 7.0 and K95 1.1.19 do), sets its file
- character-set as requested, and also disables automatic
- character-set switching ([557]Section 6.5). If the server does
- not support this command or if it does not support the given
- character set, the REMOTE SET FILE CHARACTER-SET command fails.
-
- Here's an example that sends a Japanese text file encoded in Shift-JIS
- to a server using every combination of Kermit's Japanese-capable file
- and transfer character sets:
-
- dcl \&x[] = euc ucs2 utf8 ; transfer character-sets
- dcl \&y[] = eu uc ut ; 2-letter abbreviations for them
- dcl \&f[] = shift euc jis7 ucs2 utf8 ; file character-sets
- dcl \&g[] = sj eu j7 uc ut ; 2-letter abbreviations
-
- set file char shift-jis ; local file character-set is Shift-JIS
- for \%i 1 \fdim(&x) 1 { ; for each transfer character-set...
- set xfer char \&x[\%i] ; set it
- for \%j 1 \fdim(&f) 1 { ; for each remote file character-set...
- remote set file char \&f[\%j] ; set it
- if fail exit 1 SERVER REJECTED CHARSET
- send /text meibo-sj.html meibo-sj-\&y[\%i]-\&g[\%j].txt ; send the fil
-e
- if fail exit 1 TRANSFER FAILED
- }
- }
-
- The Kermit-370 server does not support REMOTE SET FILE CHARACTER-SET,
- but since it supports REMOTE KERMIT commands, you can get the same
- effect with REMOTE KERMIT SET FILE CHARACTER-SET name.
-
- 7. SCRIPT PROGRAMMING
-
- (Also see [558]Section 2.8, Scripting Local Programs.)
-
- 7.0. Bug Fixes
-
- The following script programming bugs were fixed in C-Kermit 7.0:
-
- * IF EXIST and IF DIRECTORY were fixed to properly strip braces from
- around their arguments, so "if directory {C:\Program Files}", etc,
- would work as expected. However, this means that if the file or
- directory name is actually enclosed in braces, the braces must be
- doubled.
- * The READ command did not fail if the READ file wasn't open; now it
- does.
- * The READ command refused to read the last or only line of a file if
- it did not end with a proper line terminator; now it does.
- * The END command, when given from within a SWITCH statement, did not
- exit from the current macro or command file; instead it just
- terminated the SWITCH.
-
- 7.1. The INPUT Command
-
- 7.1.1. INPUT Timeouts
-
- The description of the INPUT command on page 422 fails to mention the
- following two points about the timeout (which apply to C-Kermit 6.0 and
- later):
-
- 1. "INPUT -1 text" (or "INPUT \%x text", where \%x is any variable
- whose value is -1 or less) means "wait forever". This form of the
- INPUT command fails only if it is interrupted, since it will never
- time out.
- 2. INPUT 0 performs a nonblocking read of material that has already
- arrived but has not yet been read, and succeeds immediately if the
- target string is found, or fails immediately if it is not found.
-
- The same points apply to MINPUT. REINPUT ignores its timeout parameter.
-
- 7.1.2. New INPUT Controls
-
- The following new INPUT controls were added in version 7.0:
-
- SET INPUT AUTODOWNLOAD { ON, OFF }
- Explained in [559]Section 7.7.
-
- SET INPUT CANCELLATION { ON, OFF }
- This governs whether an INPUT command can be canceled by
- "pressing any key" on the keyboard. Normally it can be, in which
- case the INPUT command fails immediately and \v(instatus) is set
- to 2, indicating interruption. SET INPUT CANCELLATION OFF
- disables keyboard cancellations; thus if the search text is not
- encountered, the INPUT command will run for its entire timeout
- interval. SET INPUT CANCELLATION OFF does not disable
- interruption by Ctrl-C, however; every command needs an
- emergency exit. (If you really want to disable interruption by
- Ctrl-C, use SET COMMAND INTERRUPTION OFF.)
-
- Also see [560]Section 7.2 for any new variables related to INPUT.
-
- 7.1.3. INPUT with Pattern Matching
-
- C-Kermit 7.0 allows INPUT, MINPUT, and REINPUT targets to be a pattern
- (explained in [561]Sections 1.19 and [562]4.9). This solves a
- long-standing problem illustrated by the following scenario: a certain
- company has a bank of TCP/IP modem servers, with hostnames server1,
- server2, server3, and so on. Each server's prompt is its name, followed
- by a colon (:), for example "Server72:". Without INPUT patterns, it
- would be rather difficult to wait for the prompt. The brute force
- approach:
-
- minput 20 Server1: Server2: Server3: ... (enumerating each one)
-
- is subject to failure whenever a new server is added. A more subtle
- approach:
-
- input 20 Server
- if fail ...
- input 2 :
-
- is liable to false positives, e.g. "Welcome to the XYZ Corp Modem
- Server. Please read the following message:"...
-
- With patterns, you can match the prompt with "Server*:" (which doesn't
- solve the "false positives" problem, but certainly is more compact than
- the brute force method), or with more specific patterns such as
- "Server[1-9]:" and "Server[1-9][0-9]:", or equivalently:
-
- Server{[1-9],[1-9][0-9]}:
-
- meaning the word "Server" followed by a single digit (1-9) or by two
- digits representing a number from 1 to 99, followed by a colon.
-
- INPUT pattern matching has been added in a way that does not interfere
- with existing scripts. No new commands or switches are used. The simple
- rule is: if an INPUT search target is the argument of the (new)
- \fpattern() function, it is a pattern. Otherwise it is taken literally,
- as before. For example:
-
- input 5 a*b
-
- searches for an 'a' followed by an asterisk ('*'), followed by a 'b'.
- But:
-
- input 5 \fpattern(a*b)
-
- searches for an 'a' followed by anything at all up to and including the
- first 'b'. This means that any search target to INPUT, MINPUT, or
- REINPUT can be a pattern or a literal string, and in particular that
- MINPUT can accommodate any mixture of patterns and literal strings.
-
- In selecting patterns, note that:
-
- * A leading '*' is always implied so there is no need to include one.
- * A trailing '*' is meaningless and ignored.
- * A '*' by itself matches the first character that arrives.
-
- A syntax note: If your pattern is a selection list, meaning a list of
- alternatives separated by commas and enclosed in braces, then the outer
- braces will be stripped by various levels of parsers, so you must
- include three of each:
-
- input 10 \fpattern({{{abc,mno,xyz}}})
-
- Note that this is equivalent to:
-
- minput 10 abc mno xyz
-
- except for the setting of the \v(minput) variable.
-
- And a caution: INPUT pattern matching has a limitation that you
- probably never noticed with literal-string matching, namely that there
- is a limit on the size of the match. For example, if the pattern is
- "a*b", the match will succeed if the 'a' and 'b' are not separated by
- more than (say) 8K bytes, but will fail if they are farther apart than
- that. In such cases, it better to use two INPUTs (e.g. "input 10 a" and
- then "input 100 b").
-
- 7.1.4. The INPUT Match Result
-
- The result of any INPUT, MINPUT, or REINPUT command, no matter whether
- the search targets are patterns or literal strings, is available in the
- new \v(inmatch) variable. For example:
-
- minput 10 cat \fpattern([dh]og)
- if success echo MINPUT matched "\v(inmatch)"
-
- This is especially useful when a pattern was matched, since it makes
- the string that matched the pattern available to Kermit; there would be
- no way to get it otherwise.
-
- After an INPUT command, you can view all the INPUT-related variables by
- typing "show variables in" (abbreviate as "sho var in"), which shows
- the values of all built-in variables whose names start with "in".
-
- 7.2. New or Improved Built-In Variables
-
- \v(blockcheck)
- Current BLOCK-CHECK setting, 1, 2, 3, or 4. 4 is the code for
- BLANK-FREE-2.
-
- \v(byteorder)
- The machine's byte order: 0 = Big Endian, 1 = Little Endian.
-
- \v(cmdbufsize)
- The length of the command buffer, which is the maximum size for
- a macro, a command, a variable, or anything else in C-Kermit's
- script language.
-
- \v(ctty)
- The device name of C-Kermit's controlling (login) terminal.
-
- \v(filename)
- Described in [563]Sections 4.1 and [564]4.2.
-
- \v(filenumber)
- Described in [565]Sections 4.1 and [566]4.2.
-
- \v(filespec)
- As of C-Kermit 7.0, contains fully qualified filenames rather
- than (usually) relative ones.
-
- \v(return)
- Now holds the END n value of the macro that most recently
- returned, in case END was used rather than RETURN.
-
- \v(editor)
- Pathname of preferred text editor
-
- \v(editopts)
- Command-line options for editor
-
- \v(editfile)
- File most recently edited
-
- \v(browser)
- Pathname of preferred Web browser
-
- \v(browsopts)
- Command-line options for Web browser
-
- \v(browsurl)
- URL most recently given to Web browser
-
- \v(dialtype)
- Type of call most recently placed (see [567]Section 2.1.11).
-
- \v(kbchar)
- The character, if any, that was typed at the keyboard to to
- interrupt the most recent PAUSE, SLEEP, WAIT, MSLEEP, or INPUT
- command; empty if the most recent such command was not
- interrupted from the keyboard.
-
- \v(lockdir)
- UNIX only - The name of the UUCP lockfile directory, if known,
- otherwise "(unknown)".
-
- \v(lockpid)
- UNIX only - PID of process that owns the communication port that
- you tried to open with a SET LINE command that failed because
- the port was in use, otherwise empty. This variable is set with
- every SET LINE command.
-
- \v(cx_time)
- If no connection (SET HOST, SET LINE, DIAL, TELNET, etc) is
- active, this is 0. If a connection is active, this is the number
- of seconds since the connection was made.
-
- \v(hwparity)
- If hardware parity is in effect, this variable gives its value,
- such as "even" or "odd" (in which case, the \v(parity) variable
- will be "none"). Otherwise this variable is empty.
-
- \v(serial)
- Current serial port settings in 8N1 format ([568]Section 2.10).
-
- \v(errno)
- In UNIX, the current value of the C runtime errno variable,
- which is quite volatile (meaning that often an "interesting"
- error code can be overwritten by some other library call or
- system service that sets errno before you have a chance to look
- at it). In VMS, the error code returned by the system or library
- call that most recently failed (success codes are not saved).
- Not available in other operating systems.
-
- \v(errstring)
- The UNIX or VMS system error message that corresponds to
- \v(errno). Not available in all OS's. Also see
- [569]\ferrstring().
-
- \v(setlinemsg)
- The error message, if any, from the most recent SET LINE, SET
- PORT, SET HOST, TELNET, or other connection-making command. This
- is not necessarily the same as \v(errstring) since these
- commands might fail without generating a system error code, for
- example (in UNIX) because a lockfile existed indicating the
- device was assigned by another user.
-
- \v(exitstatus)
- The exit status C-Kermit would return if it exited now.
-
- \v(pexitstat)
- The exit status of the inferior process most recently invoked by
- C-Kermit (by RUN, !, REDIRECT, SEND /COMMAND, etc). In VMS, this
- code can be given to \ferrstring() to get the corresponding
- error message (in UNIX, program/command return codes are not the
- same as system error codes). Not available in operating systems
- other than UNIX and VMS. See [570]Section 4.2.5 for details.
-
- \v(inmatch)
- The incoming string of characters, if any, that matched the most
- recent INPUT, REINPUT, or MINPUT command.
-
- \v(intime)
- The number of milliseconds (thousandths of seconds) it took for
- the most recent INPUT command to find its match, or -1 if no
- INPUT command has been given yet. If the INPUT command timed
- out, the value is approximately equal to 1000 times the INPUT
- timeout. If INPUT failed for some other reason, the value is
- undefined (\v(instatus) gives INPUT completion status). If your
- version of C-Kermit is built without high-precision
- floating-point timers, this number will always be a multiple of
- 1000.
-
- \v(inwait)
- The number of seconds specified as the timeout in the most
- recent INPUT command.
-
- \v(dialsuffix)
- Dialing suffix for use during PDIAL sequence; see [571]Section
- 2.1.10.
-
- \v(pid)
- UNIX, VMS, and K95 only. C-Kermit's primary process ID, numeric,
- decimal. If you want to show it in hex, use \fn2hex(\v(pid)) If
- you want to show it in octal, use \fn2octal(\v(pid)).
-
- \v(printer)
- Current printer name or SET PRINTER value.
-
- \v(p_ctl)
- Control prefix char \v(p_8bit) 8-bit prefix char (if parity not
- none)
-
- \v(p_rpt)
- Repeat prefix char (if repeat compression enabled)
-
- \v(herald)
- Kermit's version herald
-
- \v(test)
- Kermit's test version, if any, or 0 if this is not a test
- version. Typical values for test versions are "Alpha.03" or
- "Beta.14".
-
- \v(sendlist)
- The number of entries in the SEND-LIST, 0 if none. Note: entries
- do not necessarily correspond to files, since an entry might
- contain wildcards. Also note that the value does not go back to
- 0 after the files in the list are sent. To reset this variable,
- use CLEAR SEND-LIST. The purpose of this variable is to
- determine if a SEND command, when given without any filenames,
- will be legal. Example:
-
- xif \v(sendlist) { send } else { send oofa.txt }
-
- \v(trigger)
- If the most recent CONNECT session was terminated automatically
- by a trigger, this variable contains the trigger value.
-
- \v(ty_ln)
- TYPE line number (during TYPE)
-
- \v(ty_lc)
- TYPE line count (after TYPE)
-
- \v(ty_mc)
- TYPE match count (after TYPE)
-
- \v(xferstat)
- Status of most recent file transfer:
-
--1: No transfer yet
- 0: Succeeded
- 1: Failed
-
- \v(xfermsg)
- If the most recent file transfer failed, this is the reason. If
- it succeeded, \v(xfermsg) is an empty string.
-
- \v(tftime)
- Total elapsed time of most recent file transfer operation, in
- seconds.
-
- \v(textdir)
- Directory that holds (or is supposed to hold) Kermit text files
- such as installation instructions, release notes, update notes,
- read-me files, "beware" files, etc.
-
- \v(name)
- The name with which the Kermit program was invoked, e.g.
- "kermit", "wermit", "k95", "k2", etc (see [572]Section 9.1).
-
- \v(osname)
- Name of operating system on computer where C-Kermit is running,
- obtained at runtime (from uname or equivalent).
-
- \v(osversion)
- Version of operating system on computer where C-Kermit is
- running, obtained at runtime (from uname or equivalent).
-
- \v(osrelease)
- Release of operating system on computer where C-Kermit is
- running, obtained at runtime (from uname or equivalent).
-
- \v(model)
- The specific hardware model of the computer where C-Kermit is
- running, if known.
-
- \v(math_pi)
- The value of Pi (see [573]Section 7.23)
-
- \v(math_e)
- The value of e (see [574]Section 7.23)
-
- \v(math_precision)
- How many significant digits in a floating-point number.
-
- \v(f_count)
- Result of the most recent FILE COUNT (FCOUNT) command.
-
- \v(f_error)
- Numeric error code of most recent FILE command.
-
- \v(f_max)
- Maximum number of files open simultaneously.
-
- The math constants are given in the precision of underlying computer's
- floating-point arithmetic.
-
- Note the distinction between \v(osname), \v(osversion), and
- \v(platform); the latter refers to the platform for which and/or upon
- which C-Kermit was built, as opposed to the one on which it is actually
- running. Also note that each operating system can, and probably will,
- interpret and fill in the os* variables differently, or not at all.
-
- The SHOW VARIABLES command now accepts a variable name, prefix, or
- pattern:
-
- show variables Shows all variables.
- show variables t Shows all variables that start with "t".
- show variables *ver* Shows all variables whose names contain "ver".
- show variables *ver Ditto (an implied "*" is appended).
-
- 7.3. New or Improved Built-In Functions
-
- The following new file-i/o functions are explained in [575]Section
- 1.22.
-
- \f_status(channel) Status of file open on channel
- \f_pos(channel) Read/write (byte) pointer of given file
- \f_line(channel) Current line of file
- \f_handle(channel) Handle of file
- \f_eof(channel) Whether given file is at EOF
- \f_getchar(channel) Read a char from given file
- \f_getline(channel) Read a line from given file
- \f_getblock(channel,n) Read a block from given file
- \f_putchar(channel,c) Write a char to given file
- \f_putline(channel,string) Write a line to given file
- \f_putblock(channel,string) Write a block to given file
-
- The following new date-time-related functions are explained in
- [576]Section 1.6:
-
- \fday() Returns day of week of given date
- \fnday() Returns numeric day of week of given date
- \ftime() Returns time portion of given date-time
- \fntime() Converts time to seconds since midnight
- \fn2time() Converts seconds since midnight to hh:mm:ss
- \fcvtdate(date-time) Converts free-format date to yyyymmdd hh:mm:ss
- \fdayofyear(date-time) Converts date to yyyyddd (day-of-year) format
- \fdoy(date-time) Synonym for \fdayofyear()
- \fdoy2date(dayofyear) Converts yyyyddd to yyyymmdd
- \fmjd(date-time) Converts free-format date to Modified Julian Date
- \fmjd2date(mjd) Converts modified Julian date to yyyymmdd
-
- The new floating-point arithmetic functions are explained in
- [577]Section 7.23. f1 and f2 are floating-point (real) numbers; d is
- the number of decimal places to show:
-
- \ffpabsolute(f1,d) Absolute value of f1
- \ffpadd(f1,f2,d) f1 + f1
- \ffpcosine(f1,d) Cosine of f1
- \ffpdivide(f1,f2,d) f1 divided by f2
- \ffpexp(f1,d) e to the f1 power
- \ffpint(f1) Integer part of f1
- \ffplog10(f1,d) Log base 10 of f1
- \ffplogn(f1,d) Natural log of f1
- \ffpmaximum(f1,f2,d) Maximum of f1 and f2
- \ffpminimum(f1,f2,d) Minimum of f1 and f2
- \ffpmodulus(f1,f2,d) Modulus of f1 and f2
- \ffpmultiply(f1,f2,d) Product of f1 and f2
- \ffpraise(f1,f2,d) Raise f1 to power f2
- \ffpround(f1,d) Round f1 to d places
- \ffpsine(f1,d) Sine of f1
- \ffpsqrt(f1,d) Square root of f1
- \ffpsubtract(f1,f2,d) f2 - f1
- \ffptangent(f1,d) Tangent of f1
-
- Integer number functions:
-
- \fabsolute(n)
- Absolute value of integer n.
-
- \frandom(n)
- Returns a random integer between 0 and n-1.
-
- \fradix(s,n1,n2)
- If the string s is an integer in radix n1, the result is the
- same number expressed in radix n2, where n1 and n2 may be any
- number from 2 through 36, expressed as decimal numbers, or
- variables (etc) that evaluate to decimal numbers. For the source
- and result, the digits of any radix, r, are the first r
- characters in the sequence 0-9,a-z (case doesn't matter for the
- letters). The string s may have a sign, + or -; if it starts
- with a minus (-) sign, the result also has a minus sign.
-
- The \fradix() function does not work with floating-point numbers. It
- does not reveal the internal storage format of a number; for example,
- \fradix(-1,10,16) is -1, not something like FFFFFFFFFF. If all three
- arguments are not given, or if n1 or n2 are not numbers between 2 and
- 36 inclusive, or s is not a number in radix n1, an error occurs and the
- empty string is returned. \fradix() also does not offer
- extended-precision arithmetic; number values are limited to those
- expressed as a long integer in the architecture of the underlying
- computer, usually 32 or 64 bits. If you give it an argument whose
- absolute value is larger than can be held in an unsigned long, the
- result is -1.
-
- The next four are shorthand functions for decimal/hexadecimal and
- decimal/octal number conversion:
-
- \fn2hex(n)
- Returns the hexadecimal (base 16) representation of the integer
- n. This is different from \fhexify(s), which treats its argument
- as a string rather than a number. The result is always
- left-padded with 0's to make its length even. Examples:
-
- \n2hex(0) = "00" \fhexify(0) = "30"
- \n2hex(255) = "ff" \fhexify(255) = "323535"
- \n2hex(256) = "0100" \fhexify(256) = "323536"
-
- \fhex2n(x)
- Converts hexadecimal number x to decimal equivalent decimal
- number. This is the inverse of \fn2hex(). Equivalent to
- \fradix(s,16,10).
-
- \fn2octal(n)
- Returns the octal (base 8) representation of the number n.
- Examples:
-
- \n2octal(0) = "0"
- \n2oct(255) = "377"
- \n2oct(256) = "400"
- Equivalent to \fradix(n,10,8).
-
- \foct2n(n)
- Returns the decimal representation of the given octal number, n.
- The inverse of \fn2octal(). Equivalent to \fradix(n,8,10).
-
- String functions:
-
- \s(name[n:m])
- Equivalent to \fsubstring(\m(name),n,m) ([578]Section 7.24).
-
- \:(name[n:m])
- Equivalent to \fsubstring(name,n,m) (where "name" is any
- \-quantity) ([579]Section 7.24).
-
- \fleft(s,n)
- The leftmost ncharacters of string s; equivalent to
- \fsubstring(s,1,n).
-
- \fstripx(string,char)
- Returns the part of the string up to the rightmost occurrence,
- if any, of the given character. The default character is period
- (.) Examples:
-
- \fstripx(foo/bar,/) = "foo"
- \fstripx(foo/bar/baz,/) = "foo/bar"
- \fstripx(autoexec.bat,.) = "autoexec"
- \fstripx(autoexec.bat) = "autoexec"
- \fstripx(fstripx(foo/bar/baz,/),/) = "foo"
-
- \flop(string,character)
- Returns the portion of the string starting after the first
- occurrence of the given character. The default character is
- period (.) Examples:
-
- \flop(autoexec.bat) = "bat"
- \flop(baz.foo/bar) = "foo/bar"
- \flop(baz.foo/bar,/) = "bar
-
- \fstripn(string,n)
- Returns the string with ncharacters removed from the end.
- Example:
-
- \fstripn(12345678,3) = "12345"
-
- (For more discussion of \fstripx(), \fstripn(), and \flop() see
- [580]Section 4.2.3).
-
- \fb64encode(s)
- Returns the Base-64 encoding of the string s.
-
- \fb64decode(s)
- Returns the decoding of the Base-64 string s. Fails if s is not
- a Base-64 string, or if its length is not a multiple of 4. Note
- that if any of the result bytes are null (0), the result string
- stops there. There is no way to represent strings that contain
- null bytes in C-Kermit (the same is true for \funhexify()).
-
- \fword(s1,n,s2,s3)
- Extracts word number nfrom string s1. By default, a "word" is
- any sequence of ASCII letters or digits; nis 1-based. If n is
- omitted, "1" is used. Examples:
-
- \fword(one two three) = "one"
- \fword(one two three,1) = "one"
- \fword(one two three,2) = "two"
- \fword(one two three,3) = "three"
-
- and:
-
- \fword(\v(dialresult),2) = "31200"
-
- is "31200" if \v(dialresult) is (e.g.) "CONNECT
- 31200/ARQ/V32/LAPM/V42BIS".
-
- If you include s2, this replaces the default break set. For
- example, suppose you have a string \%a whose value is:
-
- $150.00 $300.00 $39.95
-
- and you want each dollar amount to be a word; use:
-
- \fword(\%a,\%n,{ })
-
- This returns dollar amount number \%n, e.g. "$300.00" for \%n =
- 2. "{ }" denotes a space (you must enclose it in braces,
- otherwise it is squeezed out). Note that ASCII control
- characters are always included in the break set; you don't have
- to specify them (and you can't not specify them).
-
- The optional s3 argument lists characters (even control
- characters) that normally would be considered separators that
- you want included in words. So the dollars-and-cents example
- could also be handled this way:
-
- \fword(\%a,\%n,,$.)
-
- in other words, use the default separator list, but remove "$"
- and "." from it so they will be considered part of a word.
-
- Note that since 8-bit characters are not ASCII, they act as
- break characters unless you put them in the include list.
- Suppose, for example, you have a file in which each line is a
- Tab-separated list of words, numbers, or phrases that might
- contain punctuation, special characters like $ and @, 8-bit bit
- characters, etc (like something that might have been exported
- from a spreadsheet or database), and you want to split only on
- Tab; here is a way (\m(line) is a line read from the file):
-
-undef keep
-for \%i 1 255 1 {
- if == \%i 9 continue
- .keep := \m(keep)\fchar(\%i)
-}
-while true {
- fread /line \%c line
- if fail break
- .\%n := \fsplit(\m(line),&a,\9,\m(keep))
- ...
-}
-
- This problem is addressed in [581]C-Kermit 9.0.
-
- \fsplit(s1,&a,s2,s3)
- This is like \fword(), except instead of extracting and
- returning a particular word from string s1, it counts the words
- and optionally assigns them to the array whose identifying
- letter, a-z, is given after the "&" in the second argument, with
- the first word going into element 1, the second into element 2,
- and so on. The rules regarding break and include lists (s2 and
- s3) are exactly the same as for \fword(). \fsplit() returns the
- number of words that were assigned, which is either the number
- of words in the string, or the dimension of the array, whichever
- is less. If the array is not declared, \fsplit() creates it and
- returns a number which is both the number of words in s1 and the
- dimension of the new array. Examples:
-
- declare \&w[20] ; (Optional.)
- ...
- read \%s ; \%s is "This is a sentence with seven words."
- ...
- echo "\fsplit(\%s)" ; This would print "7".
- echo "\fsplit(\%s,&w)" ; Ditto, and also assigns them to array \&w[].
-
- echo "\&w[7]" ; This would print "words".
-
- If the line contained fields that were delimited by colon (:),
- you would use \fsplit(\%s,&w,:). If the fields were delimited by
- comma, then you would use \fsplit(\%s,&w,{,}); in this case the
- literal comma must be enclosed in braces to distinguish it from
- the comma that separates function arguments. To get a word count
- without loading an array, but still specify break and/or include
- lists, leave the array argument empty:
-
- echo "\fsplit(\%s,,:)" ; Use colon as the separator.
-
- WARNINGS:
-
- 1. If you use the same array repeatedly, \fsplit() leaves any
- trailing members undisturbed. For example:
- dcl \&w[10]
- \fsplit(1 2 3 4 5,&w) ; Sets \&w[1] thru \&w[5].
- \fsplit(a b c,&w) ; Sets \&w[1]-[3] leaving [4]-[5] as they were.
-
- 2. If you allow \fsplit to create the array (by not declaring it
- first), it is dimensioned to the number of elements it was
- created with:
- \fsplit(1 2 3,&x) ; Creates an array \&x[] with 3 elements.
- \fsplit(a b c d e,&x) ; This overflows the array.
-
- Thus if you want to use \fsplit() repeatedly on the same array,
- either dimension it in advance to the maximum expected size (and
- then some -- more efficient), or else destroy it after each use
- (to allow for unexpectedly large arguments). Example using a
- dynamic array:
-
- fopen /read \%c some-file
- if fail ...
- set function error on ; See [582]Section 7.12
- while true {
- dcl \&w[] ; Destroy \&[w] each time thru the loop
- fread /line \%c \%a
- if fail break
- asg \%x \fsplit(\%a,&w)
- if fail ...
- ; (do what you want with \&w[] here...)
- }
- fclose \%c
-
- \frindex(s1,s2,n)
- The "n" argument to \frindex() now works consistently (in mirror
- image) with the corresponding \findex() argument. In each case,
- the (n-1)-most characters of s2 are ignored in the search; for
- findex, this means the starting position of the search is n (the
- default n is 1, and 0 is treated like 1). For \frindex() it
- means the default starting point is:
-
- length(s2) - length(s1) - n (with the same defaults for n).
-
- \fsearch(pattern,string[,position])
- Exactly like \findex(), except with a pattern (see [583]Section
- 7.9) rather than a literal string.
-
- \frsearch(pattern,string[,position])
- Exactly like \frindex(), except with a pattern rather than a
- literal string.
-
- File Functions:
-
- \ffiles(), \fnextfile()
- It is no longer necessary to copy the file list to an array
- before use, as shown on p.398 of [584]Using C-Kermit 2nd
- Edition. \ffiles() and friends now make their own safe copies of
- the file list. Thus constructions like the following are now
- possible:
-
- for \%i 1 \ffiles(*.txt) 1 { send \fnextfile() }
-
- The same is true for the new function \frfiles(),
- \fdirectories(), and \frdirectories(), described in [585]Section
- 4.11.3.
-
- But note that each reference to \fnextfile() still gets you the
- next file. So "if newer \fnextfile() foo.txt send \fnextfile()"
- compares one file's age with that of foo.txt, and then sends an
- entirely different file. If you're going to refer to the same
- file more than once, assign it to a variable:
-
- asg \%f \fnextfile()
- if newer \%f foo.txt send \%f
-
- (note: assign, not define).
-
- Also note that \ffiles(), \frfiles(), \fdirectories(), and
- \frdirectories() all now accept on optional 2nd argument: the
- name of an array to load with the resulting file or directory
- list, explained in [586]Section 4.11.3. So you can also load an
- array with the filelist when you need to refer to the same file
- more than once:
-
- for \%i 1 \ffiles(*,&a) 1 { if newer \&a[\%i] foo.txt send \&a[\%i] }
-
- \fpermissions(file)
- Returns the platform-specific permissions string for the file,
- such as "-rw-rw-r--" in UNIX or "(RWE,RWE,RE,E)" in VMS.
-
- \fdirname(f)
- Given a file specification f, this function returns the complete
- pathname of directory the file is in.
-
- Array Functions:
-
- \fdimension(&a)
- Returns the dimension declared for the array whose identifying
- letter, a-z, or special character "_" or "@", is given after the
- "&" in the argument. If the array is not declared, 0 is
- returned. Note that when used with the macro argument vector
- array, \&_[] (see [587]Section 7.5), the value of this function
- is one less than \v(argc), and when used with the C-Kermit
- command-line argument vector array, \&@[], it is equal to the
- \v(args) variable. Examples:
-
- echo \fdimension(&a) ; Not declared.
- 0
- declare \&a[12] ; Now it's declared.
- echo \fdim(&a)
- 12
-
- \farraylook(pattern,arrayname)
- Looks in the given array for the pattern and returns the index
- of the first element that matches, if any, or -1 if none match.
- The arrayname can include a range specifier to restrict to
- search to a segment of the array, e.g.
- \farraylook(*xyz*,&a[32:63]). For greater detail see
- [588]Section 7.10.7.
-
- \ftablelook(keyword,arrayname[,delimiter])
- Looks in the given "table", which must be sorted, for the given
- keyword. Returns the index of the table element that uniquely
- matches the given keyword, or -1 if none match, or -2 if more
- than 1 match. For greater detail see [589]Section 7.10.7.
-
- Other new functions:
-
- \fip2hex(s)
- Converts a dotted decimal IP address to an 8-digit hexadecimal
- number. \fip2hex(128.59.39.2) = 803b2702.
-
- \fhex2ip(x)
- Converts an 8-digit hexadecimal IP address to dotted decimal
- form, e.g. \fhex2ip(803b2702) = 128.59.39.2. The inverse of
- \fip2hex().
-
- \fcommand()
- \frawcommand()
- These run an external command and return its output; see
- [590]Section 4.2.8.4.
-
- \fdialconvert(s)
- s is a phone number in either literal or portable format (not a
- dialing directory entry name). The function returns the dial
- string that would actually be used when dialing from the current
- location (after processing country code, area code, and other
- SET DIAL values).
-
- \ferrstring(n)
- Returns the system error message associated with the (numeric)
- error code n. UNIX and VMS only. Use in conjunction with
- \v(errno) or \v(pexitstat). See [591]Section 4.2.5 for a usage
- example. Note: This function doesn't work in Windows because
- there is not a consistent error-code-to-message mapping; error
- code "x" means something completely different depending on
- whether it comes from the C runtime library, Winsock, a
- Windows-32 API, TAPI, etc,
-
- \fpattern(s)
- Used in INPUT, REINPUT, and MINPUT commands to denote search
- strings that are to be treated as patterns rather than
- literally.
-
- Also see [592]Section 7.8 on built-in help for functions.
-
- 7.4. New IF Conditions
-
- IF AVAILABLE feature command
- Executes the command if the given feature is available.
- Presently used only to determine if specific authentication and
- encryption options are available. Type "if available ?" to see
- which features may be tested.
-
- IF FLOAT f1 command
- Executes command if f1 is a legal floating point number (which
- includes integers). Use this to preverify arguments for the
- \ffp...() floating-point arithmetic functions, e.g. "if float
- \%1 echo \ffpint(\%1)".
-
- IF == n1 n2 command
- Synonym for "if =" (numeric equality). Note that as of C-Kermit
- 7.0, this and all other numeric comparison operators also work
- for floating-point numbers.
-
- IF != n1 n2 command
- Executes the command if n1 and n2 are both numbers or variables
- containing numbers and the value of n1 is not equal to the value
- of n2. This is equivalent to "if not = n1 n2".
-
- IF <= n1 n2 command
- Executes the command if n1 and n2 are both numbers or variables
- containing numbers and the value of n1 is less than or equal to
- the value of n2. This is equivalent to "if not > n1 n2".
-
- IF >= n1 n2 command
- Executes the command if n1 and n2 are both numbers or variables
- containing numbers and the value of n1 is greater than or equal
- to the value of n2. Equivalent to "if not < n1 n2".
-
- IF COMMAND word command
- Executes the command if word is a built-in C-Kermit command.
- Example:
-
- if not command copy define { copy run copy \%1 \%2 }".
-
- This defines a COPY macro that runs an external COPY command if
- COPY is not already a built-in command.
-
- IF LOCAL command
- Executes the command if Kermit is in local mode, i.e. if it has
- a SET LINE, SET PORT, or SET HOST (TELNET, RLOGIN, etc) device
- or connection open. Does not execute the command if in remote
- mode.
-
- IF MATCH string pattern command
- Executes the command if the string matches the pattern. For a
- description of the syntax for the pattern, see [593]Section
- 4.9.1. If you want to test if the string contains pattern, use
- IF \fsearch(pattern,string).
-
- IF OPEN { DEBUG-LOG, SESSION-LOG, TRANSACTION-LOG, ... } command
- Executes the command if the given file is open, fails if it is
- not open. Type IF OPEN ? for a complete list of files that can
- be checked (all the files that can be opened with the OPEN or
- LOG commands).
-
- IF QUIET command
- Executes the command if SET QUIET is ON, and does not execute it
- if SET QUIET is OFF. Example: IF NOT QUIET ECHO { This is a
- message.}.
-
- IF READABLE name
- Succeeds if name is the name of an existing file or directory
- that is readable.
-
- IF WRITEABLE name
- Succeeds if name is the name of an existing file or directory
- that is writable, e.g.:
-
- if not writeable \v(lockdir) echo Please read installation instructions!
-
- IF FLAG command
- This tests a user-settable condition, which can mean anything
- you like. SET FLAG ON causes subsequent IF FLAG commands to
- succeed; SET FLAG OFF causes them to fail. One way to use it
- would be for debugging your scripts; precede any debugging
- statements with IF FLAG. Then SET FLAG on to debug your script,
- SET FLAG OFF to run it without debugging. Another common use is
- for causing an inner loop to cause an outer loop to exit.
-
- IF C-KERMIT command
- C-Kermit, but not Kermit 95 or MS-DOS Kermit, executes the
- command.
-
- IF K-95 command
- Kermit 95, but not C-Kermit or MS-DOS Kermit, executes the
- command.
-
- IF MS-KERMIT command
- MS-DOS Kermit, but not C-Kermit or Kermit 95, executes the
- command.
-
- 7.5. Using More than Ten Macro Arguments
-
- The \v(argc) variable now gives the actual number of arguments, even if
- the number is greater than 9:
-
- C-Kermit> define xx echo \v(argc)
- C-Kermit> xx a b c d e f g h i j k l m n o p q r s t u v w x y z
- 27
-
- Remember that \v(argc) includes the name of the macro itself, so it is
- always at least 1, and is always 1 greater than the actual number of
- arguments. As in versions 6.0 and earlier, if more than 9 arguments are
- given, only the first nine are assigned to the variables \%1..\%9.
-
- The \&_[] array, discussed on page 353 of [594]Using C-Kermit, 2nd ed,
- now holds all the arguments, up to some implementation-dependent limit
- (64 or greater), rather than only the first 9. To illustrate: the
- following macro tells the number of arguments it was called with and
- then prints them:
-
- define show_all_args {
- local \%i
- echo \&_[0] - Number of arguments: \feval(\v(argc)-1)
- for \%i 1 \v(argc)-1 1 { echo \flpad(\%i,3). "\&_[\%i]" }
- }
-
- Within a macro \&_[0], like \%0, contains the name of the macro.
-
- At top level, the \&_[] array is filled as follows:
-
- * If the first argument on the C-Kermit command line was a filename,
- or C-Kermit was invoked from a "Kerbang" script ([595]Section
- 7.19), element 0 contains the filename, and elements 1 through
- \v(argc)-1 hold the remaining command-line arguments.
- * Otherwise the program name goes in element 0, and elements 1
- through \v(argc)-1 hold any arguments that were included after "--"
- or "="
-
- The new \%* variable, when used within a macro, is replaced by the text
- that followed the macro name in the macro invocation. If no arguments
- were given, \%* is replaced by the empty string. Examples:
-
- C-Kermit> define xx echo [\%*]
- C-Kermit> define \%a oofa
- C-Kermit> xx
- []
- C-Kermit> xx \%a
- [oofa]
- C-Kermit> xx a
- [a]
- C-Kermit> xx a b
- [a b]
- C-Kermit> xx a b c
- [a b c]
- C-Kermit> xx a b c d e f g h i j k l m n o p q r s t u v w x y z
- [a b c d e f g h i j k l m n o p q r s t u v w x y z]
-
- Note that \%* can not be used at top level, since Kermit does not have
- access to the raw command line (only to its elements separately, after
- they have been processed by the shell and the C library).
-
- C-Kermit 7.0 also adds a SHIFT command:
-
- SHIFT [ number ]
- Shifts the macro arguments (except argument 0) the given number
- of places to the left and adjusts \v(argc) accordingly. The
- default number is 1.
-
- To illustrate, suppose macro XXX is invoked as follows:
-
- xxx arg1 arg2 arg3
-
- Then inside XXX, \%1 is "arg1", \%2 is "arg2", and \%3 is "arg3". After
- a SHIFT command is given inside XXX, then \%1 is "arg2", \%2 is "arg3",
- and \%3 is empty. \%0 (the name of the macro) remains unchanged.
-
- If more than 9 arguments were given, then arguments are shifted into
- the \%1..9 variables from the argument vector array.
-
- At top level, the SHIFT command operates on the \&_[] array and \%1..9
- variables; the \&@[] array is not affected. See [596]Section 7.16 for
- details.
-
- The \%* variable is not affected by the SHIFT command.
-
- 7.6. Clarification of Function Call Syntax
-
- Spaces are normally stripped from the front and back of each function
- argument; to prevent this enclose the argument in braces:
-
- \fsplit(\%a,&a,{ })
-
- However, function calls that contain spaces can make trouble when the
- function is to be used in a "word" field, since space separates words.
- For example:
-
- for \%i 1 \fsplit(\%a,&a,{ }) 1 {
- echo \%i. "\&a[\%i]"
- }
-
- In most cases, the trouble can be averted by enclosing the function
- reference in braces:
-
- for \%i 1 {\fsplit(\%a,&a,{ })} 1 {
- echo \%i. "\&a[\%i]"
- }
-
- or by replacing spaces with \32 (the ASCII code for space):
-
- for \%i 1 \fsplit(\%a,&a,\32) 1 {
- echo \%i. "\&a[\%i]"
- }
-
- Braces are also used in function calls to indicate grouping. For
- example:
-
- \fsubstring(abcd,2,2) = "bc"
-
- But suppose "abcd" needed to contain a comma:
-
- \fsubstring(ab,cd,2,2)
-
- This would cause an error, since "cd" appears to be the second
- argument, when really you want the first "2" to be the second argument.
- Braces to the rescue:
-
- \fsubstring({ab,cd},2,2) = "b,"
-
- Similarly, leading and trailing spaces are stripped from each argument,
- so:
-
- \fsubstring( abcd ,2,2) = "bc"
-
- but braces preserve them:
-
- \fsubstring({ abcd },2,2) = "ab"
-
- Given these special uses for braces, there is no way to pass literal
- braces to the function itself. For example:
-
- \fsubstring(ab{cd,2,2)
-
- causes an error.
-
- So if you need a function to include braces, define a variable
- containing the string that has braces. Example:
-
- define \%a ab{cd
- \fsubstring(\%a,2,2) = "b{"
-
- If the string is to start with a leading brace and end with a closing
- brace, then double braces must appear around the string (which itself
- is enclosed in braces):
-
- define \%a {{{foo}}}
- \fsubstring(\%a) = "{foo}"
-
- This also works for any other kind of string:
-
- define \%a {{ab{cd}}
- echo \fsubstring(\%a) = "ab{cd"
-
- 7.7. Autodownload during INPUT Command Execution
-
- As of 6.1 / 1.1.12, C-Kermit can be told to look for incoming Kermit
- (or Zmodem) packets during execution of an INPUT command. By default
- (for consistency with earlier releases), this is not done. You can
- enable this feature with:
-
- SET INPUT AUTODOWNLOAD ON
-
- (and disable it again with OFF.)
-
- One possible use for this feature is as a server mode with a time
- limit:
-
- INPUT 3600 secret-string-to-end-the-INPUT-command
-
- In this example, any GET, SEND, or REMOTE commands received within one
- hour (3600 seconds) of when the INPUT command was issued will be
- executed. Here's another example, in which we want to stay open until
- 11:30pm, or until interrupted by seven consecutive Ctrl-C (\3)
- characters:
-
- INPUT 23:30:00 \3\3\3\3\3\3\3
-
- The INPUT AUTODOWNLOAD setting is displayed by SHOW SCRIPTS or SHOW
- INPUT.
-
- 7.8. Built-in Help for Functions.
-
- Beginning in C-Kermit 7.0, you may obtain a description of the calling
- conventions and return values of any built-in function, such as
- \fsubstring(), with the new HELP FUNCTION command; give the function's
- name without the leading "\f", e.g. "help func substring". You can use
- ?, completion, and abbreviation in the normal manner.
-
- 7.9. Variable Assignments
-
- 7.9.1. Assignment Operators
-
- Programmers accustomed to languages such as C or Fortran might find
- Kermit's method of assigning values to variables unnatural or awkward.
- Beginning in C-Kermit 7.0, you can use the following alternative
- notation:
-
- .name = value is equivalent to DEFINE name value
- .name := value is equivalent to ASSIGN name value
- .name ::= value is equivalent to ASSIGN name \feval(value)
-
- When the command begins with a period (.), this indicates an
- assignment. The name can be a macro name, a \%{digit,letter} variable,
- or an array element. There can be space(s) between "." and the name.
- Examples:
-
- .\%a = This is a string ; Same as "define \%a This is a string"
- echo \%a
- This is a string
-
- .xxx = \%a ; Same as "define xxx \%a"
- echo \m(xxx)
- \%a
-
- .xxx := \%a ; Same as "assign xxx \%a"
- echo \m(xxx)
- This is a string
-
- declare \&a[2] ; Use with arrays...
- define \%i 2
- .\&a[1] = first
- .\&a[\%i] = second
-
- The following sequence illustrates the differences among three levels
- of evaluation:
-
- .\%x = 2 ; Define a variable to have a numeric value
- .\%y = (3 + \%x) ; Define another variable as an arithmetic expression
-
- .xxx = 4 * \%y ; "=" simply copies the right-hand side.
- echo \m(xxx)
- 4 * \%y
-
- .xxx := 4 * \%y ; ":=" evaluates the variables first, then copies.
- echo \m(xxx)
- 4 * (3 + 2)
-
- .xxx ::= 4 * \%y ; "::=" evaluates the expression, then copies.
- echo \m(xxx)
- 20
-
- You can also use this syntax to clear (undefine) a variable:
-
- .\%a = oofa ; Define the variable
- echo "\%a"
- "oofa"
- .\%a ; Clear the variable
- echo "\%a"
- ""
-
- Extra credit: Can you guess what happens below when the file "abc" does
- not exist?
-
- fopen /read \%c abc
- if fail ...
-
- 7.9.2. New Assignment Commands
-
- Recall the DEFINE and ASSIGN commands, and their hidden counterparts,
- _DEFINE and _ASSIGN. The former take the variable name literally, the
- latter evaluate the variable-name field to form the variable name
- dynamically. Examples:
-
- DEFINE \%x foo ; Sets the value of the variable \%x to "foo".
- DEFINE \%a \%x ; Sets the value of the variable \%a to "\%x".
- _DEFINE x_\%a \%x ; Sets the value of the variable x_foo to "\%x".
- ASSIGN \%a \%x ; Sets the value of the variable \%a to the "foo".
- _ASSIGN x_\%a \%x ; Sets the value of the variable x_foo to "foo".
-
- This concept has been carried over to the remaining variable-assignment
- commands: EVALUATE, INCREMENT, and DECREMENT:
-
- EVALUATE variablename expression
- Evaluates the arithmetic expression and assigns its value to the
- variable whose name is given. Example: "eval \%a 1+1" assigns
- "2" to \%a.
-
- _EVALUATE metaname expression
- Evaluates the arithmetic expression and assigns its value to the
- variable whose name is computed from the given metaname.
- Example: "eval foo<\%a>::\%1 \%2 * (\%3 + \%4)" assigns the
- value of "\%2 * (\%3 + \%4)" to the variable whose name is
- computed from "foo<\%a>::\%1".
-
- INCREMENT variablename [ expression ]
- Evaluates the arithmetic expression and adds its value to the
- value of the variable whose name is given. Example: "increment
- \%a".
-
- _INCREMENT metaname [ expression ]
- Evaluates the arithmetic expression and adds its value to the
- value of the variable whose name is computed from the given
- metaname. Example: "_increment Words::\%1.count[\%2]".
-
- DECREMENT variablename [ expression ]
- Evaluates the arithmetic expression and subtracts its value from
- the value of the variable whose name is given.
-
- _DECREMENT metaname [ expression ]
- Evaluates the arithmetic expression and subtracts its value from
- the value of the variable whose name is computed from the given
- metaname.
-
- WARNING: The syntax of the EVALUATE command has changed since C-Kermit
- 6.0 and K95 1.1.17. Previously, it did not include a variable name,
- only an expression. To restore the old behavior, use SET EVALUATE OLD.
- To return to the new behavior after restoring the old behavior, use SET
- EVALUATE NEW.
-
- NOTE: There are no analogs to the "_" commands for the operators
- described in [597]Section 7.9.1; those operators can not be used to
- assign values to variables whose names must be computed.
-
- 7.10. Arrays
-
- C-Kermit 7.0 adds lots of new array-related features, and groups them
- together under the NEW ARRAY command:
-
- ARRAY { CLEAR, COPY, DECLARE, DESTROY, RESIZE, SHOW, SORT }
-
- In each of the ARRAY commands, wherever an array name is expected,
- "short forms" may be used. For example, all of the following are
- acceptable:
-
- array show \&a[] (or SHOW ARRAY...)
- array show &a[]
- array show a[]
- array show &a
- array show a
-
- In addition, ranges are accepted in the ARRAY COPY, ARRAY CLEAR, ARRAY
- SET, ARRAY SHOW, and ARRAY SORT commands:
-
- array clear \&a[16] ; Clears 16 thru end
- array clear &a[16] ; Ditto
- array clear a[16] ; Ditto
-
- array clear \&a[16:32] ; Clears 16 thru 32
- array clear &a[16:32] ; Ditto
- array clear a[16:32] ; Ditto
-
- When using array names as function arguments, you must omit the "\" and
- you must include the "&". You may optionally include empty brackets.
- Examples:
-
- \fsplit(\%a,a) ; Bad
- \fsplit(\%a,\&a) ; Bad
- \fsplit(\%a,&a[3]) ; Bad
-
- \fsplit(\%a,&a) ; Good
- \fsplit(\%a,&a[]) ; Good
-
- 7.10.1. Array Initializers
-
- Beginning in C-Kermit 7.0, you may initialize an array -- in whole or
- in part -- in its declaration:
-
- [ ARRAY ] DECLARE array-name[size] [ = ] [ value1 [ value2 [...] ] ]
-
- For compatibility with versions 5A and 6.0, the ARRAY keyword is
- optional. DECLARE can also be spelled DCL.
-
- Initializers are (a) optional, (b) start with element 1, (c) must be
- enclosed in braces if they contain spaces, and (d) are evaluated
- according to normal rules by the DECLARE command prior to assignment.
- Thus the assignments made here are the same as those made by the ASSIGN
- command. This allows you to initialize array elements from the values
- of other variables. If you actually want to initialize an array element
- to variable's name, as opposed to its value, use double backslashes (as
- in "\\&a", "\\v(time)", etc).
-
- The size (dimension) of the array is optional. If the size is omitted,
- as in "\&a[]", then the array sizes itself to the number of
- initializers; if there are no initializers the array is not declared
- or, if it was declared previously, it is destroyed. If a size is given,
- any extra elements in the initialization list are discarded and
- ignored.
-
- NOTE: Unlike in C, the list of initializers is NOT enclosed in braces.
- Instead, braces are used to group multiple words together. So:
-
- ARRAY DECLARE \&a[] = { one two three }
-
- would create an array with two elements (0 and 1), with element 1
- having the value " one two three ".
-
- Examples:
-
- ARRAY DECLARE \&a[16]
- Declares the array \&a with 17 elements (0 through 16), in which
- all elements are initially empty. If the array \&a[] existed
- before, the earlier copy is destroyed.
-
- ARRAY DECLARE &a[16]
- ARRAY DECLARE a[16]
- ARRAY DCL \&a[16]
- ARRAY DCL &a[16]
- ARRAY DCL a[16]
- DECLARE \&a[16]
- DECLARE &a[16]
- DECLARE a[16]
- DCL \&a[16]
- DCL &a[16]
- DCL a[16]
- All of the above are the same as the first example.
-
- ARRAY DECLARE \&a[16] = alpha beta {gamma delta}
- Declares the array \&a with 17 elements (0 through 16),
- initializing \&a[1] to "alpha", \&a[2] to "beta", and \&a[3] to
- "gamma delta". The remaining elements are empty.
-
- ARRAY DECLARE \&a[] = alpha beta {gamma delta}
- Same as the previous example, but the array is automatically
- dimensioned to 3.
-
- ARRAY DECLARE \&a[3] = alpha beta {gamma delta} epsilon zeta
- Too many initializers; only the first three are kept.
-
- ARRAY DECLARE \&a[0]
- ARRAY DECLARE \&a[]
- ARRAY DECLARE &a[]
- ARRAY DECLARE &a
- ARRAY DECLARE a
- DECLARE \&[0]
- DECLARE a
- DCL a
- All of these are equivalent. Each destroys \&a[] if it exists.
- Declaring an array with a dimension of 0 is the same as ARRAY
- DESTROY arrayname.
-
- ARRAY DECLARE \&a[] = \%1 \%2 \%3
- Declares the array \&a with 3 elements (0 through 3),
- initializing \&a[1] to the value of \%1, \&a[2] to the value of
- \%2, and \&a[3] to the value of \%3. In this case, any reference
- to one of these array elements is replaced by the value of the
- corresponding \%n variable at the time the declaration was
- executed (immediate evaluation; the array element's value does
- not change if the initializer variable's value changes).
-
- ARRAY DECLARE \&a[] = \\%1 \\%2 \\%3
- Declares the array \&a with 3 elements (0 through 3),
- initializing \&a[1] to the string "\%1", \&a[2] to "\%2", and
- \&a[3] to "\%3". In this case any reference to one of these
- array elements is replaced by the CURRENT value of the
- corresponding \%n variable (deferred evaluation -- the array
- element's value follows the value of the initializer variable).
-
- The equal sign (=) preceding the initializer list is optional, but is
- recommended for clarity. If you need to initialize element 1 to a
- literal equal sign, use two of them, separated by a space, as in this
- example:
-
- ARRAY DECLARE \&a[] = = + - * /
-
- Remember, element 0 is not initialized by the DECLARE command. To
- initialize element 0, use a regular DEFINE or ASSIGN command:
-
- ARRAY DECLARE \&a[] one two three four five six seven eight nine
- DEFINE \&a[0] zero
-
- Finally, remember that every command level has its own local array,
- \&_[], containing all the macro arguments (\%0, \%1, ...) for that
- level. See [598]Section 7.5 for details.
-
- 7.10.2. Turning a String into an Array of Words
-
- The \fsplit(s1,&a,s2,s3) function assigns the words of string s1 to
- successive elements of the array (beginning with element 1) whose
- identifying letter, a-z, is given after the "&" in the second argument,
- using break and include characters given in s2 and s3. See [599]Section
- 7.3 for details.
-
- 7.10.3. Arrays of Filenames
-
- See [600]Section 4.11.3 for news about how \ffiles() and related
- functions can assign a list of filenames to an array. To recapitulate
- briefly here:
-
- \ffiles(*,&a)
-
- assigns all files that match the first argument to the array denoted by
- the second argument. If the array has not been declared, it is declared
- automatically, with exactly the number of elements needed to hold the
- file list; if it was previously declared, it is destroyed and reused.
- The filenames are assigned starting at array element 1. Element 0 holds
- the number of files in the list.
-
- The DIRECTORY command ([601]Section 4.5.1) can also create filename
- arrays if you give it the /ARRAY: switch; this allows selection
- criteria beyond whether the filename matches the given pattern.
-
- All functions and commands that create filename arrays store the number
- of filenames, n, as element 0 of the array, and the filenames as
- elements 1 through n.
-
- 7.10.4. Automatic Arrays
-
- In a command file or macro, you can now have local (automatic) arrays.
- Just give the name followed by empty subscript brackets (no spaces
- inside the brackets please) in a LOCAL command, and then declare the
- array:
-
- LOCAL \%a \&a[] oofa
- ARRAY DECLARE \&a[32] = value1 value2 value3 ...
-
- This declares the scalar variable \%a, the array \&a[], and the macro
- name "oofa" to be local, and then declares the new local copy of \&a[]
- with 32 elements, perhaps assigning some initial values. When C-Kermit
- exits from the command file or macro containing these command, the
- previous \&a[] array is restored (and if there was no \&a[] at any
- higher level, this will still be true). The process can be repeated to
- any level. Thus it is now safe to write scripts or macros containing
- arrays without danger of interfering with global arrays of the same
- name.
-
- Just as scalars are inherited by lower command levels, so are arrays.
- So, for example, if \&a[] is declared at top level, all lower levels
- will see it unless they include a "local \&a[]" statement, in which
- case all levels at and beneath the level where the LOCAL statement was
- executed will see the local copy. This too can be repeated to any
- level.
-
- On the other hand, if you DECLARE an array at a lower command level
- without also making it LOCAL, this replaces the copy that was declared
- at the lowest command level above this one.
-
- 7.10.5. Sorting Arrays
-
- Although arrays can be sorted using FOR loops as shown on page 383 of
- Using C-Kermit, 2nd Ed., this involves quite a bit of repetitive
- interpretation by the command parser, and so can be slow for large
- arrays. For this reason, C-Kermit 7.0 adds a built-in SORT command:
-
- ARRAY SORT [ switches ] array [ array2 ]
- Sorts the given array in place. Sorting is strictly lexical
- (string based). The array name can be given fully, e.g. "\&a[]",
- or the "\" and/or "&" and/or brackets can be omitted, e.g.
- "array sort \&a[]", "sort &a", "sort a". Also, a range can be
- indicated in the brackets as noted in [602]Section 7.10, to
- restrict the sort to a range of elements (equivalent to the
- /RANGE switch, described just below), e.g. "array sort
- &a[20:30]".
-
- A second array may be specified. If it is, and if it is at least as big
- as the first array, it is sorted according to the first array. For a
- sample application, see [603]Section 7.10.10.
-
- See [604]Section 1.5 for an explanation of switches. The optional
- switches are:
-
- /CASE:{ON,OFF}
- /CASE:ON means that alphabetic case is significant in
- comparisons; uppercase letters are sorted before lowercase ones.
- /CASE:OFF means case is ignored, e.g. "A" is the same as "a". If
- this switch is not given, sorting is according the current SET
- CASE setting.
-
- /KEY:n
- Comparison begins at position n(1-based) in each string. If no
- key is given, the entire strings are compared. Only one key can
- be given. If an array element is shorter than the key value, n,
- that element is considered empty for comparison purposes, and
- therefore lexically less than any element at least ncharacters
- long.
-
- /NUMERIC
- If this switch is included, it means sorting should be numeric,
- rather than lexical. The sort key is the string starting at the
- key position, skipping any leading blanks or tabs, and then as
- much of the string from that point on that fits the definition
- of "numeric", terminating at the first character that does not
- qualify. A numeric string has an optional sign (+ or -) followed
- by one or more digits, and (if your version of Kermit was built
- with floating-point support; see [605]Section 7.23 ) zero or one
- decimal point (period). If both /CASE and /NUMERIC are given,
- /NUMERIC takes precedence.
-
- /RANGE:n[:m]
- Sort elements nthrough m of the array. By default, the entire
- array from element 1 to its dimensioned size is sorted, which
- might produce surprising results if the array is not full; see
- example in [606]Section 7.10.7. If ":m" is omitted from the
- range, the dimensioned size is used. Thus, to sort an entire
- array, \&a[], including its 0th element, use "sort /range:0 &a".
- You can also sort any desired section of an array, e.g. "sort
- /range:10:20 &a" or "sort /range:\%i:\%j-1 &b". As noted above,
- you can also specify a range in the array-name brackets. If you
- specify a range in the array-name brackets AND with a /RANGE
- switch, the ones in the brackets take precedence.
-
- /REVERSE
- Sort in reverse order. If this switch is not given, the array is
- sorted in ascending order.
-
- Remember that numeric switch arguments can be numbers, arithmetic
- expressions, or variables whose values are numbers or expressions, as
- illustrated in the /RANGE examples above.
-
- A typical sorting application might be to list students' test scores in
- descending order. Suppose you had the following records:
-
- olaf 65
- olga 98
- ivan 83
- xena 100
-
- (and so on) stored in array \&s[] (e.g. by reading them from a file as
- illustrated in [607]section 7.10.7). In these records, the student's
- name is in columns 1-9 and the score in 10-12. So to rearrange the list
- in descending order of score:
-
- sort /key:10 /reverse &s
-
- Then to list your top five students:
-
- for \%i 1 5 1 { echo \&s[\%i] }
-
- Or more simply (see next section):
-
- show array a[1:5]
-
- To illustrate the difference between a lexical and a numeric sort,
- suppose you have the following records (the lines that are numbered,
- starting at column 1) in array \&a[]:
-
- Column 1 2
- 12345678901234567890
-
- 1. Ivan 10.0 2. Olaf 9.95 3. Olga 101.5
-
- ARRAY SORT /KEY:10 &a[] would order them 3,1,2, but ARRAY SORT /KEY:10
- /NUMERIC &a[] would order them 2,1,3.
-
- 7.10.6. Displaying Arrays
-
- The SHOW ARRAY command (or ARRAY SHOW) now accepts an optional
- array-name argument:
-
- SHOW ARRAY \&a[]
-
- (you can leave off the \, the \&, and/or the []'s if you like; "show
- array a" is equivalent to "show array \&a[]"). When an array is
- specified, its dimension is shown and all defined (non-empty) elements
- are listed.
-
- Example:
-
- assign \%n \ffiles(*,&a) ; Fill an array with filenames ([608]Section 4.11.3)
- show array \&a[] ; Show the array we just read
- array show \&a[] ; Same as previous
- array sort \&a[] ; Sort the array
- array show \&a[] ; Show it after sorting
- array show \&a ; Show it again
- array show &a ; Show it again
- array show a ; Show it again
-
- (The final four commands demonstrate the alternative forms that are
- accepted for the array name.)
-
- If you SHOW ARRAY without giving an array name, all defined arrays are
- listed by name and dimension, but their contents are not shown.
-
- You can also show a piece of an array by including a subscript or range
- within the array brackets:
-
- array show \&a[5] ; Shows \&a[5]
- array show &a[3:8] ; Shows \&a[3] through \&a[8]
- array show a[:\%n-1] ; Shows \&a[0] through \&a[\%n-1]
-
- 7.10.7. Other Array Operations
-
- ARRAY DESTROY arrayname
- Destroys and undeclares the named array. Subscripts or ranges
- are not accepted in this command.
-
- ARRAY COPY array1 array2
- Copies the first array to the second array. If the target array
- has not been declared, it is created automatically with the same
- size as the first. If it has been declared, it will be used as
- declared; if the source array is larger, only as much of it as
- will fit is copied to the target array. Syntax for array1 and
- array2 is as in ARRAY SHOW (SHOW ARRAY). Example:
-
- .\%n := \ffiles(*,&a) ; Create and load array A with a file list.
- array copy &a &b ; Copy array A to array B.
-
- The ARRAY COPY command also lets you copy pieces of arrays by
- including range specifiers, as in these examples:
-
- ARRAY COPY \&a[4:27] \&b
- This copies \&a[] elements 4-27 to \&b[] elements 1-23,
- creating \&b[] if necessary or, if \&b[] is already
- declared, stopping early if its size is less than 23.
-
- ARRAY COPY \&a[4:27] \&b[12]
- This copies \&a[] elements 4-27 to \&b[] elements 12-35,
- creating \&b[] if necessary or, if \&b[] is already
- declared, stopping early if its size is less than 35.
-
- ARRAY COPY \&a[4:27] \&b[12:14]
- This copies \&a[] elements 4-6 to \&b[] elements 12-14,
- creating \&b[] if necessary or, if \&b[] is already
- declared, stopping early if its size is less than 14.
-
- ARRAY COPY \&a[17:] \&b
- This copies all the elements of \&a[] starting with 17
- until the last to \&b[], creating \&b[] if necessary or,
- if \&b[] is already declared, stopping early if \&b[] is
- not big enough. Suppose, for example, you have a script
- whose arguments are string1, string2, and a list of files,
- whose job is to change all occurrences of string1 to
- string2 in each of the files. But if the list of files is
- omitted, then "*" (all files in the current directory) is
- assumed:
-
-if < \v(argc) 3 exit 1 "Usage: \%0 string1 string2 [ files ]"
-if not def \%3 {
- .n := \ffiles(*,&a)
-} else {
- array copy &_[3:] &a
- .n := \fdim(&a)
-}
-for i 1 n 1 {
- ! cat \&a[i] | sed -e "s|\%1|\%2|g" > /tmp/_x
- rename /tmp/_x \&a[i]
-}
-
- ARRAY COPY \&a[17] \&b
- Same as previous example.
-
- ARRAY CLEAR arrayname
- Sets all the elements of the array to the empty value. You may
- also include a range specifier to clear only a selected portion
- of the array; for example "array clear \&a[37:214]". If the
- range is out of bounds, only the part of the array that is in
- bounds is cleared.
-
- ARRAY SET arrayname [ value ]
- Sets all the elements of the array to the given value. If no
- value is given, the array is cleared. You may also include a
- range specifier to set only a selected portion of the array; for
- example "array set \&a[1:9] -1". If the range is out of bounds,
- only the part of the array that is in bounds is set.
-
- ARRAY RESIZE arrayname size
- Resizes the given array. If the size is greater than the array's
- current dimension, new empty elements are added to the end. If
- the size is less than the current dimension, the extra elements
- are discarded. Note: If you have stored the array size in
- element 0, ARRAY RESIZE does not change this value. Alternative
- notation: ARRAY RESIZE arrayname[size]. For a practical example,
- see [609]Section 7.10.11.
-
- \farraylook(pattern,arrayname)
- This function returns the index of the first element of the
- given array that matches the given pattern (for details about
- pattern syntax, see [610]section 4.9). The array name can
- include a range specification to restrict the search to a given
- segment of the array. If no elements match the pattern, -1 is
- returned.
-
- \ftablelook(keyword,arrayname[,delimiter])
- Looks in the given "table", which must be sorted, for the given
- keyword. The keyword need not be spelled out in full.
- Pattern-matching characters should not be included as part of
- the keyword. The function returns the index of the table element
- that uniquely matches the given keyword, or -1 if none match, or
- -2 if more than 1 match.
-
- A "table" is an array that is sorted in lexical order; each of its
- elements may contain multiple fields, delimited by the given delimiter
- character or, if no delimiter is specified, a colon (:).
-
- The \farraylook() function does exactly what you tell it. If you give
- it a pattern that does not include wildcard characters (such as *, ?,
- etc), it requires an exact match. For example:
-
- \farraylook(oofa,&a)
-
- searches for the first element of \&a[] whose value is "oofa". But:
-
- \farraylook(oofa*,&a)
-
- finds the first element whose value starts with "oofa", and;
-
- \farraylook(*oofa,&a)
-
- finds the first element whose value ends with "oofa", and;
-
- \farraylook(*oofa*,&a)
-
- finds the first element whose value contains "oofa".
-
- Here's a simple demonstration of looking up patterns in arrays:
-
- local \&a[] \%x \%n
- declare \&a[] = zero one two three four five six seven eight nine ten
- while true {
- .\%x = 1
- .\%n = 0
- ask \%a { Pattern? }
- if not def \%a exit 0 Done.
- while <= \%x \fdim(&a) {
- .\%x := \farraylook(\%a,&a[\%x])
- if ( < \%x 0 ) break
- echo \flpad(\%x,3). \&a[\%x]
- increment \%x
- increment \%n
- }
- if ( < \%n 1 ) echo Pattern not found - "\%a"
- }
-
- The array need not be sorted. When a pattern is given, a search is
- performed; if there is a match, the matching element's index and the
- element itself are printed, and the search begins again at the next
- element. Thus each matching element is printed. If none match, the
- "Pattern not found" message is printed. The process repeats for as many
- patterns as the user wants to type, and terminates when the user types
- an empty pattern.
-
- Now let's build a little command parser, consisting of a keyword table,
- and a loop to look up the user's commands in it with \ftablelook(). In
- this case the array elements have "fields" separated by colon (:) -- a
- keyword and a value. Keyword tables must be sorted if \tablelook() is
- to work right, so after declaring and initializing the table array, we
- sort it.
-
- local \&k[] \%a \%i \%n
-
- array declare \&k[] = drive:9 do:8 discuss:7 live:6 spend:5 help:4 quit:0
-
- array sort &k ; Make sure array is sorted
- echo Type "help" for help. ; Print greeting & instructions
-
- while true { ; Loop to get commands
- undefine \%a
- while not defined \%a { ; Get a command
- ask \%a { Command? }
- }
- .\%n := \ftablelook(\%a,&k) ; Look up the command
- switch \%n { ; Handle errors
- :-1, echo Not found - "\%a" ; Doesn't match
- continue
- :-2, echo Ambiguous - "\%a" ; Matches too many
- continue
- }
- switch \fword(\&k[\%n],2) { ; Dispatch according to value
- :9, echo Driving..., break
- :8, echo Doing..., break
- :7, echo Discussing..., break
- :6, echo Living..., break
- :5, echo Spending..., break
- :4, echo { Commands (may be abbreviated):}
- for \%i 1 \fdim(&k) 1 {
- echo { \%i. \fword(\&k[\%i],1) }
- }
- break
- :0, exit 0 Bye!
- :default, stop 1 Internal error
- }
- }
-
- In this example, keywords are "drive", "do", "discuss", etc, and their
- values are unique numbers (values need not be numbers, and there need
- not be only one value -- there can be 0, 1, 2, or more of them). The
- user types a command, which can be the whole word (like "help") or any
- abbreviation (like "hel", "he", or just "h"). If this does not match
- any keywords, \ftablelook() returns -1; if it matches more than one (as
- would "d"), it returns -2. Otherwise the array index is returned, 1 or
- higher.
-
- Given the array index \%n, we can get the table values as follows:
-
- \fword(\&k[\%n],1) is the keyword (first field)
- \fword(\&k[\%n],2) is the value (second field, in this case a number)
-
- In our example, we use the value (number) as the SWITCH variable. As
- noted, \fablelook() expects the array elements to contain multiple
- fields separated by colon (:) (or other character that you specify,
- e.g. \ftablelook(\%a,&a,^)) and when matching the keyword, ignores the
- first delimiter and everything after it.
-
- 7.10.8. Hints for Using Arrays
-
- C programmers are accustomed to out-of-bounds array references causing
- core dumps or worse. In C-Kermit:
-
- * A reference to an an out-of-bounds array element returns the empty
- string.
- * An attempt to set the value of an array element that is out of
- bounds or that has not been declared simply fails.
-
- C programmers expect an array of size n to have elements 0 through n-1.
- Fortran programmers expect the same array to have elements 1 through n.
- C-Kermit accommodates both styles; when you declare an array of size n,
- it has n+1 elements, 0 through n, and you can use the array in your
- accustomed manner, 0-based or 1-based.
-
- However, note that C-Kermit has certain biases towards 1-based arrays:
-
- * Assignment of file lists starts with element 1 ([611]Section
- 7.10.3).
- * Assignment by \fsplit() starts with element 1 ([612]Section 7.3).
- * Array initialization skips the 0th element. To initialize a 0-based
- array, use something like this:
- declare \&a[3] = one two three
- .\&a[0] = zero
-
- * The ARRAY SORT command skips the 0th element unless you include
- /RANGE:0
- * The SHIFT command ignores element 0 of the \&_[] array.
-
- The distinction between an array's dimensioned size and the number of
- elements in the array is important when sorting. To illustrate:
-
- declare \&a[100] ; Declare array &a with 100 elements
- fopen /read \%c oofa.txt ; Open a file
- if fail...
- for \%i 1 \fdim(&a) 1 { ; Read the file into the array
- fread \%c \&a[\%i]
- if fail break
- }
- fclose \%c
- if > \%i \fdim(&a) end 1 File has too many lines for array.
- .\%n ::= \%i - 1
- echo File has \%n line(s).
-
- Let's say the file had 95 lines. This leaves elements 96-100 of the
- array empty. Now suppose you sort the array and write out the result:
-
- sort &a ; Sort the whole array
- fopen /write \%o oofa.txt.sorted ; Open an output file
- if fail ...
- for \%i 1 \%n 1 { ; Write out 95 records
- fwrite /line \%o \&a[\%i]
- if fail end 1 Write error
- }
- close write
-
- You might be surprised at the contents of "oofa.txt.sorted" -- five
- empty elements, 96-100, floated to the top of the array in the sort,
- and since your write loop only had 95 iterations, the final 5 lines of
- the sorted file are lost.
-
- Therefore, when dealing with partially filled arrays -- especially when
- sorting them -- remember to specify the number of elements. A handy way
- of recording an array's "true" size is to put it in the 0th element.
- That way, it "travels with the array". To illustrate (continuing the
- previous example at the "close read" statement):
-
- close read
- if > \%i \fdim(&a) end 1 File has too many lines for array.
- .\&a[0] ::= \%i - 1 ; Assign number of lines to \&a[0].
- echo File has \&a[0] line(s).
- sort /range:1:\&a[0] &a
- open write oofa.txt.sorted
- if fail ...
- for \%i 1 \&a[0] 1 {
- writeln file \&a[\%j]
- if fail end 1 Write error
- }
- close write
-
- Note the SORT switch, /RANGE:1:\&a[0]. This keeps the sort 1-based, and
- uses element 0 of the array as its size indicator.
-
- Finally, note that even though some commands or functions might put a
- size in array element 0, no built-in functions or commands depend on a
- size actually being there. Thus you are perfectly free to replace the
- size with something else and treat the array as 0-based.
-
- 7.10.9. Do-It-Yourself Arrays
-
- Kermit's \&x[] arrays are nice because of the accompanying built-in
- functionality -- ARRAY commands, built-in functions that load and
- search arrays, automatic evaluation of arithmetic expressions within
- the subscript brackets, and so on. Yet they also have certain
- limitations:
-
- 1. Except when created by dynamic loading (e.g. by \ffiles()) they
- must be declared and dimensioned in advance.
- 2. Indices must be numeric, positive, and in range.
- 3. There can be only one dimension. Matrices or other
- higher-dimensioned arrays are not available.
-
- But none of this is to say you can't invent any kind of data structure
- you like. In [613]Section 7.9.2 you can see some examples. Here's
- another (courtesy of Dat Thuc Nguyen), in which a pair of matrices is
- created and then added: no dimensioning necessary.
-
- .row = 4
- .col = 9
-
- ; MACRO TO PRINT A MATRIX
- define PMATRIX {
- echo Matrix \%1:
- for \%r 1 \m(row) 1 {
- for \%c 1 \m(col) 1 {
- xecho \flpad(\m(\%1[\%r][\%c]),4)
- }
- echo
- }
- echo
- }
- ; CREATE MATRICES A AND B
- for \%r 1 \m(row) 1 {
- for \%c 1 \m(col) 1 {
- _eval A[\%r][\%c] \%r + \%c
- _eval B[\%r][\%c] \%r * \%c
- }
- }
- ; CREATE MATRIX C = SUM OF MATRIX A AND MATRIX B
- for \%r 1 \m(row) 1 {
- for \%c 1 \m(col) 1 {
- _eval C[\%r][\%c] \m(A[\%r][\%c]) + \m(B[\%r][\%c])
- }
- }
- pmatrix A ; Print Matrix A
- pmatrix B ; Print Matrix B
- pmatrix C ; Print Matrix C
-
- In the example, we use matrix-like notation to create macros with names
- like "A[1][1]", "B[3][7]", and so on.
-
- 7.10.10. Associative Arrays
-
- An associative array is a special kind of Do-It-Yourself array. It
- differs from a regular array in that its indices need not be numbers --
- they can be anything at all -- words, filenames, names of months, any
- character string at all, and that it doesn't have to be (and in fact
- can't be) declared. An associative array element is simply a macro
- whose name ends with an index enclosed in angle brackets, for example:
-
- file<oofa.txt>
-
- More formally:
-
- basename<index>
-
- An associative array is a collection of all associative array elements
- that have the same basename. Any number of associative arrays, each
- with any number of elements, can exist at the same time.
-
- An associative array element can be assigned a value, such as "1", just
- like any other macro:
-
- define file<oofa.txt> 1 ; Give "file<oofa.txt>" the value "1".
-
- or:
-
- assign file<oofa.txt> \%a ; Give it the value of the variable \%a.
-
- However, since an associative array element is a macro, it may not have
- an empty (null) value, since assigning an empty value to a macro
- undefines the macro.
-
- You can refer to the value of an associative array element using the
- familiar notation for macro values:
-
- echo \m(file<oofa.txt>) ; Echo the value of "file<oofa.txt>".
-
- Associative arrays are most useful, however, when the value of the
- index is a variable. In that case, you must use the "hidden" forms of
- the DEFINE or ASSIGN commands that evaluate the macro name before
- making the assignment (see [614]Using C-Kermit, page 457). Example:
-
- define \%f oofa.txt
- _define file<\%f> 1
- echo file<\%f> = \m(file<\%f>)
-
- prints:
-
- file<oofa.txt> = 1
-
- and then:
-
- _increment file<\%f>
- echo file<\%f> = \m(file<\%f>)
-
- prints:
-
- file<oofa.txt> = 2
-
- What are associative arrays good for? The classic example is "word
- counts": finding the number of times each word is used in a text
- without knowing in advance what the words are. Without associative
- arrays, your program would have to build a table of some kind, and
- every time a word was encountered, look it up in the table to find its
- position and counter, or add it to the table if it wasn't found -- a
- time-consuming and laborious process. Associative arrays, however, let
- you use the word itself as the table index and therefore sidestep all
- the table building and lookups.
-
- Let's work through a practical example. Suppose you have a
- file-transfer log in which each line is composed of a number of
- blank-separated fields, and the 9th field is a filename (which happens
- to be the format of certain FTP server logs, as well as of C-Kermit's
- new FTP-format transaction log, described in [615]Section 4.17.2), for
- example:
-
- Wed Jul 14 09:35:31 1999 22 xx.mit.edu 13412 /pub/ftp/mm/intro.txt ....
-
- and you want to find out how many times each file was transferred. The
- following code builds an associative array, file<>, containing the
- counts for each file:
-
- local name line max \%c \%n ; Declare local variables
- fopen /read \%c /var/log/ftpd.log ; Open the log file ([616]Section 1.22)
- if fail exit 1 Can't open log ; Check
- while true { ; Loop for each record
- fread /line \%c line ; Read a line
- if fail break ; Check for end of file
- .name := \fword(\m(line),9,{ }) ; Get 9th field = filename (Sec 7.3)
- _increment file<\m(name)> ; Increment its counter (Sec 7.9.2)
- }
- fclose \%c ; Close file when done.
-
- Note that _INCREMENT (and INCREMENT, and [_]DECREMENT) treat an empty
- (i.e. nonexistent) variable as having a value of 0, and therefore
- creates the variable with a value of 1.
-
- At this point, if you told Kermit to "show macro file<", it would list
- the associative array. But since you don't necessarily know the names
- of the files in the array, or even how many elements are in the array,
- how can you use it in a script program?
-
- The idea of creating macro names that include character-string indices
- enclosed in angle brackets is perfectly arbitrary and doesn't depend on
- any Kermit features that weren't already there -- we could just as
- easily have used some other notation, such as "file[index]",
- "file:index", or "file.index", and the code above would have worked
- just as well (with the corresponding syntax adjustments). But to be
- able to use an associative array in a program after the array is built,
- we need a method of accessing all its elements without knowing in
- advance what they are. That's where the chosen notation comes in.
-
- First of all, any macro name that ends with "<xxx>" (where "xxx" is any
- string) is case sensitive, unlike all other macro names, which are case
- independent. To illustrate, "file<oofa.txt>" and "file<OOFA.TXT>" are
- two distinct macros, whereas "OOFA", "Oofa", and "oofa", when used as
- macro names, are all the same.
-
- Second, the new \faaconvert() function converts an associative array
- (that is, all macros with names of the form "base<index>" that have the
- same "base" part) into a pair of regular arrays and returns the number
- of elements:
-
- \faaconvert(name,&a[,&b])
-
- "name" is the name of the associative array, without the angle brackets
- or index ("file" in our example).
-
- The second argument is the name of a regular array in which to store
- the indices of the associative array (filenames in our example); if an
- array of this name already exists, it is destroyed unless the array is
- LOCAL. The third argument is the name of another regular array in which
- to store the values (the counts in our example), with the same rules
- about array name collisions. If you care only about the indices and not
- the values, you can omit the third argument to \faaconvert(). In any
- case, the associative array is converted, not copied: its elements are
- moved to the specified regular arrays, so after conversion the original
- associative array is gone.
-
- As with other array-loading functions, \faaconvert() sets element 0 of
- each array to the number of elements in the array.
-
- To continue our example:
-
- .max := 0 ; Maximum count
- .\%n := \faaconvert(file,&a,&b) ; Convert
- for \%i 1 \%n 1 { ; Loop through values
- echo \flpad(\%i,3). \&a[\%i]: \&b[\%i] ; Echo this pair
- if ( > \&b[\%i] \m(max) ) { ; Check for new maximum
- .name := \&a[\%i]
- .max := \&b[\%i]
- }
- }
- echo Most popular file: \m(name), accesses: \m(max)
-
- This lists the files and counts and then announces which file has the
- highest count.
-
- Now suppose you want to sort the array pair created from an associative
- array. In our example, \&a[] contains filenames, and \&b[] contains the
- associated counts. Here we take advantage of the ARRAY SORT command's
- ability to sort a second array according to the first one:
-
- array sort /reverse /numeric &b &a ; Descending sort by count
-
- Now to see the top five files and their counts:
-
- echo The top 5 files are:
- for \%i 1 5 1 { ; Loop through top 5 values
- echo \flpad(\%i,3). \&a[\%i]: \&b[\%i] ; Echo this pair
- }
-
- 7.10.11. Transferring Array Contents to Other Computers
-
- The SEND /ARRAY:arrayname command ([617]Section 4.7.1) allows you to
- send the contents of any array, or any contiguous segment of it, in
- either text or binary mode to another computer, using Kermit protocol.
- When used in conjunction with C-Kermit's other features (the array
- features described in this section; the file i/o package from
- [618]Section 1.22; its decision-making, pattern-matching, and string
- manipulation capabilities, and so on) the possibilities are endless:
- extracts of large files, remote database queries, ..., all without
- recourse to system-dependent mechanisms such UNIX pipes and filters,
- thus ensuring cross-platform portability of scripts that use these
- features.
-
- When sending an array in text mode, Kermit appends a line terminator to
- each array element, even empty ones, and it also converts the character
- set from your current FILE character-set to your current TRANSFER
- character-set, if any. No conversions are made or line terminations
- added in binary mode. For example, the following array:
-
- dcl \&a[] = One Two Three Four Five Six
-
- is sent as six lines, one word per line, in text mode, and as the bare
- unterminated string "OneTwoThreeFourFiveSix" in binary mode.
-
- You should always include a /TEXT or /BINARY switch in any SEND /ARRAY
- command to force the desired transfer mode, otherwise you're likely to
- be surprised by the effects described in [619]Section 4.3.
-
- Here are some examples:
-
- send /text /array:\&a[]
- Sends the entire contents of the array \&a[] in text mode. Since
- an as-name is not included, the receiver is told the filename is
- _array_a_.
-
- send /text /array:&a[]
- send /text /array:a[]
- send /text /array:&a
- send /text /array:a
- These are all equivalent to the previous example.
-
- send /text /array:&a /as-name:foo.bar
- As above, but the array is sent under the name foo.bar.
-
- send /text /array:&a[100:199] /as:foo.bar
- As above, but only the elements from 100 through 199 are sent.
-
- In text-mode transfers, character sets are translated according to your
- current settings, just as for text files. In binary mode, of course,
- there is no character-set translation or other conversion of any kind.
- But remember that array elements can not contain the NUL (ASCII 0)
- character, since they are implemented as NUL-terminated strings.
-
- Here's an example that shows how to send all the lines (up to 1000 of
- them) from a file animals.txt that contain the words "cat", "dog", or
- "hog" (see [620]Section 4.9 about pattern matching):
-
- declare \&a[1000]
- fopen /read \%c animals.txt
- if fail exit 1
- .\%i = 0
- while true {
- fread \%c line
- if fail break
- if match {\m(line)} {*{cat,[dh]og}*} {
- increment \%i
- if ( > \%i \fdim(&a) ) break
- .\&a[\%i] := \m(line)
- }
- }
- fclose \%c
- send /array:a[1:\%i] /text
-
- Note that we are careful to send only the part of the array that was
- filled, not the entire array, because there are likely to be lots of
- unused elements at the end, and these would be sent as blank lines
- otherwise.
-
- This example raises an interesting question: what if we want to send
- ALL the matching lines, even if there are more than 1000 of them, but
- we don't know the number in advance? Clearly the problem is limited by
- Kermit's (and the computer's) memory. If there are a thousand trillion
- matching lines, they most likely will not fit in memory, and in this
- case the only solution is to write them first to a temporary file on
- mass storage and then send the temporary file and delete it afterwards.
-
- However, when the selection is likely to fit in memory, the
- once-familiar technique of initial allocation with extents can be used:
-
- if match {\m(line)} {*{cat,[dh]og}*} {
- increment \%i
- if ( > \%i \fdim(&a) ) {
- array resize a \fdim(&a)+100
- if fail stop 1 MEMORY FULL
- echo NEW DIMENSION: \fdim(&a)
- }
- .\&a[\%i] := \m(line)
- }
-
- This grows the array in chunks of 100 as needed.
-
- 7.11. OUTPUT Command Improvements
-
- LINEOUT [ text ]
- This command is exactly like OUTPUT, except it supplies a
- carriage return at the end of the text. "lineout exit" is
- exactly the same as "output exit\13".
-
- SET OUTPUT SPECIAL-ESCAPES { ON, OFF }
- This command lets you tell C-Kermit whether to process \N, \L,
- and \B specially in an OUTPUT command, as distinct from other \
- sequences (such as \%a, \13, \v(time), etc). Normally the
- special escapes are handled. Use SET OUTPUT SPECIAL-ESCAPES OFF
- to disable them.
-
- Disabling special escapes is necessary in situations when you need to
- transmit lines of data and you have no control over what is in the
- lines. For example, a file oofa.txt that contains:
-
- This is a file
- It has \%a variables in it
- And it has \B in it.
- And it has \L in it.
- And it has \N in it.
- And this is the last line.
-
- can be sent like this:
-
- local line
- set output special-escapes off
- fopen /read \%c oofa.txt
- if fail stop 1 Can't open oofa.txt
- while success {
- fread \%c line
- if fail break
- ; Add filtering or processing commands here...
- output \m(line)\13
- }
-
- 7.12. Function and Variable Diagnostics
-
- In C-Kermit 6.0 and earlier, the only diagnostic returned by a failing
- function call was an empty value, which (a) could not be distinguished
- from an empty value returned by a successful function call; (b) did not
- give any indication of the cause of failure; and (c) did not cause the
- enclosing statement to fail. C-Kermit 7.0 corrects these deficiencies.
-
- SET FUNCTION DIAGNOSTICS { ON, OFF }
- when ON, allows built-in functions to return diagnostic messages
- when improperly referenced, instead of an empty string. FUNCTION
- DIAGNOSTICS are ON by default. When OFF, improperly referenced
- functions continue to return an empty string. This command also
- affects built-in variables; in this case, an error message is
- returned only if the variable does not exist. When FUNCTION
- DIAGNOSTICS are ON, the error message is also printed.
-
- For variables, the only message is:
-
- <ERROR:NO_SUCH_VARIABLE:\v(name)>
-
- where "name" is the name of the nonexistent variable.
-
- For functions, the diagnostic message is:
-
- <ERROR:message:\fname()>
-
- where "message" is replaced by a message, and "name" is replaced by the
- function name, e.g. <ERROR:ARG_NOT_NUMERIC:\fmod()>. Messages include:
-
- ARG_BAD_ARRAY An argument contains a malformed array reference.
- ARG_BAD_DATE An argument contains a malformed date and/or time.
- ARG_BAD_PHONENUM An argument contains a malformed telephone number.
- ARG_BAD_VARIABLE An argument contains a malformed \%x variable.
- ARG_INCOMPLETE An argument is incomplete (e.g. a broken Base64 string).
- ARG_EVAL_FAILURE An argument could not be evaluated (internal error).
- ARG_NOT_ARRAY An argument references an array that is not declared.
- ARG_NOT_NUMERIC An argument that must be integer contains non-digits.
- ARG_NOT_FLOAT An argument has bad floating-point number format.
- ARG_NOT_VARIABLE An argument that must be a variable is not a variable.
- ARG_OUT_OF_RANGE An argument's numeric value is too big or too small,
- or an argument contains illegal characters (e.g. a hex
- or Base-64 string).
- ARG_TOO_LONG An argument's value is too long.
- ARRAY_FAILURE Failure to create an array.
- DIVIDE_BY_ZERO Execution of the function would cause division by zero.
- FLOATING_POINT_OP Execution error in a floating-point operation.
- FILE_NOT_FOUND Filename argument names a file that can't be found.
- FILE_NOT_READABLE Filename argument is not a regular file.
- FILE_NOT_ACCESSIBLE Filename argument names a file that is read-protected.
- FILE_ERROR Other error with filename argument.
- FILE_NOT_OPEN A file function was given a channel that is not open.
- FILE_ERROR_-n A file function got error -n ([621]Section 1.22).
- LOOKUP_FAILURE Error looking up function (shouldn't happen).
- MALLOC_FAILURE Failure to allocate needed memory (shouldn't happen).
- NAME_AMBIGUOUS The function is not uniquely identified.
- MISSING_ARG A required argument is missing.
- NO_SUCH_FUNCTION An argument references a function that is not defined.
- NO_SUCH_MACRO An argument references a macro that is not defined.
- RESULT_TOO_LONG The result of a function is too long.
- UNKNOWN_FUNCTION Internal error locating function (shouldn't happen).
-
- Examples:
-
- assign \%m \fmod()
- ?<ERROR:MISSING_ARG:\fmod()>
- echo "\fcontents(\%m)"
- "<ERROR:MISSING_ARG:\fmod()>"
- echo \fmod(3,x)
- ?<ERROR:ARG_NOT_NUMERIC:\fmod()>
- echo \fmod(3,4-2*2)
- ?<ERROR:DIVIDE_BY_ZERO:\fmod()>
-
- Notice the use of \fcontents() in echoing the value of a variable that
- contains a returned error message. That's because the error message
- includes the name of the variable or function that failed, so you must
- use \fcontents() to prevent it from being evaluated again -- otherwise
- the same error will occur.
-
- The handling of function and variable errors is controlled by:
-
- SET FUNCTION ERROR { ON, OFF }
- Tells whether invalid function calls or variable references
- should cause command errors. FUNCTION ERROR is ON by default.
- When ON, and an error is diagnosed in a built-in function or
- variable, the command that includes the function call or
- variable reference fails. The failing command can be handled in
- the normal way with IF FAILURE / IF SUCCESS, SET TAKE ERROR, or
- SET MACRO ERROR.
-
- When FUNCTION DIAGNOSTICS is OFF, there is no error message.
-
- SHOW SCRIPTS displays the current FUNCTION DIAGNOSTICS and ERROR
- settings.
-
- 7.13. Return Value of Macros
-
- In C-Kermit 5A and 6.0, there are two ways to return one level from a
- macro: RETURN value and END number text. When RETURN is used, the
- value, which can be a number or a text string, is assigned to
- \v(return). When END was used, however, \v(return) was not set.
- SUCCESS/FAILURE was set according to whether the number was zero, and
- the text was printed, but the actual value of the number was lost.
-
- In C-Kermit 7.0, the END number is available in the \v(return)
- variable.
-
- 7.14. The ASSERT, FAIL, and SUCCEED Commands.
-
- The ASSERT command is just like the IF command, but without a command
- to execute. It simply succeeds or fails, and this can be tested by a
- subsequent IF SUCCESS or IF FAILURE command. Example:
-
- ASSERT = 1 1
- IF SUCCESS echo 1 = 1.
-
- The FAIL command does nothing, but always fails. The SUCCEED command
- does nothing, but always succeeds.
-
- These commands are handy in debugging scripts when you want to induce a
- failure (or success) that normally would not occur, e.g. for testing
- blocks of code that normally are not executed.
-
- 7.15. Using Alarms
-
- Alarms may be set in two ways:
-
- SET ALARM number
- Sets an alarm for the given number of seconds "from now", i.e.
- in the future, relative to when the SET ALARM command was given.
- Examples:
-
- set alarm 60 ; 60 seconds from now
- set alarm +60 ; The same as "60"
- set alarm -60 ; Not legal - you can't set an alarm in the past.
- set alarm 60*60 ; 60 minutes from now.
- set alarm \%a+10 ; You can use variables, etc.
-
- SET ALARM hh:mm:ss
- Sets an alarm for the specified time. If the given time is
- earlier than the current time, the alarm is set for the given
- time in the next day. You may give the time in various formats:
-
- set alarm 15:00:00 ; 3:00:00pm
- set alarm 3:00:00pm ; 3:00:00pm
- set alarm 3:00pm ; 3:00:00pm
- set alarm 3pm ; 3:00:00pm
-
- SHOW ALARM
- Displays the current alarm, if any, in standard date-time format
- (see [622]Section 1.6): yyyymmdd hh:mm:ss.
-
- IF ALARM command
- Executes the command if an alarm has been set and the alarm time
- has passed.
-
- IF ALARM { command-list } [ ELSE { command-list } ]
- Executes the command-list if an alarm has been set and the alarm
- time has passed. Otherwise, if an ELSE part is given, its
- command-list is executed.
-
- CLEAR ALARM
- Clears the alarm.
-
- Only one alarm may be set at a time.
-
- Example: Suppose you have a script that is always running, and that
- transfers files periodically, and that keeps a transaction log. Suppose
- you want to start a new transaction log each day:
-
- log transactions \v(date).log
- set alarm 00:00:00 ; Set an alarm for midnight
- while true { ; Main script loop
- xif alarm { ; If the alarm time is past...
- close transactions ; Close current log
- log transactions \v(date).log ; Start new one
- pause 1 ; To make sure 00:00:00 is past
- set alarm 00:00:00 ; Set a new alarm
- }
- ; put the rest of the script here...
- }
-
- Note that IF ALARM -- no matter whether it succeeds or fails -- does
- NOT clear an expired alarm. Thus, once an alarm has expired, every IF
- ALARM will succeed until the alarm is cleared (with the CLEAR ALARM
- command) or reset with a new SET ALARM command.
-
- 7.16. Passing Arguments to Command Files
-
- Beginning in version 7.0, C-Kermit accepts arguments on the TAKE
- command line, for example:
-
- C-Kermit> take oofa.ksc one two {this is three} four
-
- This automatically sets the variables \%1 through \%9 to the arguments,
- and \%0 to the name of the file, in this case:
-
- \%0 = /usr/olga/oofa.ksc
- \%1 = one
- \%2 = two
- \%3 = this is three
- \%4 = four
-
- and \%5..\%9 are undefined (empty). Arguments past the ninth are
- available in the \&_[] argument-vector array ( [623]Section 7.5).
-
- The variables are those at the current macro level. Thus, if the TAKE
- command is executed from within a macro, the macro's arguments are
- replaced by those given on the TAKE command line (but only if at least
- one argument is given). The command shown above is exactly equivalent
- to:
-
- assign \%0 /usr/olga/oofa.ksc
- assign \%1 one
- assign \%2 two
- assign \%3 this is three
- assign \%4 four
- assign \%5
- assign \%6
- assign \%7
- assign \%8
- assign \%9
- take oofa.ksc
-
- Remember, the variables \%0..\%9 are on the macro call stack, and
- command files are independent of the macro stack. Thus, if a command
- file TAKEs another command file and passes arguments to it, the
- variables are changed from that point on for both files, and so forth
- for all levels of nested command files without intervening macro
- invocations.
-
- It would have been possible to change C-Kermit to use the overall
- command stack, rather than the macro stack, for arguments -- this would
- have made TAKE work exactly like DO, which is "nicer", but it would
- also have broken countless existing scripts. However, the new SHIFT
- command ([624]Section 7.5) makes it possible to create an alternative
- TAKE command that does indeed save and restore the argument variables
- at its own level around execution of a command file:
-
- define mtake {
- local \%f
- assign \%f \fcontents(\%1)
- shift
- take \%f
- }
-
- C-Kermit 7.0 also supports a new, easier way to pass arguments to
- scripts from the system command line:
-
- kermit filename arg1 arg2 arg3 ...
-
- in which arg1, arg2, arg3 (etc) are arguments for the script (whose
- filename is given), and are assigned to \%1, \%2, ... \%9. The filename
- is assigned to \%0. This applies equally to "Kerbang" scripts in UNIX
- ([625]Section 7.19). For example, suppose you have a file called
- "showargs" containing the following lines:
-
- #!/usr/local/bin/kermit +
- echo Hello from \%0
- show args
- exit
-
- (except not indented, since the "#!" line must be on the left margin).
- If you give this file execute permission:
-
- chmod +x showargs
-
- then you can run it exactly as you would run a UNIX shell script, e.g.:
-
- $ showargs one two three
- Hello from /usr/olga/showargs
- Top-level arguments (\v(argc) = 4):
- \&_[0] = /usr/olga/showargs
- \&_[1] = one
- \&_[2] = two
- \&_[3] = three
-
- Furthermore, the \&_[] array now contains the filename, if one was
- given as the first command line argument, or it is a "Kerbang" script,
- in element 0.
-
- Otherwise element 0 is program name, and elements 1 through \v(argc)-1
- contain the command-line arguments, if any, that appear after "--" or
- "=", if any. This array is saved and restored around macro calls;
- recall that inside macros it contains the macro argument vector
- (allowing you to access arguments programmatically, and to have more
- than 9 of them).
-
- At top level, notice the difference between the \&@[] and \&_[] arrays.
- The former includes C-Kermit options; the latter omits them.
-
- 7.17. Dialogs with Timed Responses
-
- The ASK, ASKQ, GETOK, and GETC commands (let's call them the "ASK-class
- commands") let you write scripts that carry on dialogs with the user,
- asking them for text, a Yes/No answer, or a character, respectively.
- Prior to C-Kermit 7.0, these questions would always wait forever for an
- answer. In C-Kermit 7.0, you may specify a time limit for them with the
- new command:
-
- SET ASK-TIMER number
- Sets a time-limit on ASK-CLASS commands to the given number of
- seconds. If the number is 0 or less, there is no time limit and
- these commands wait forever for a response. Any timer that is
- established by this command remains in effect for all future
- ASK-class commands until another SET ASK-TIMER command is given
- (e.g. with a value of 0 to disable ASK timeouts).
-
- IF ASKTIMEOUT command
- An ASK-class command that times out returns a failure status.
- You can test explicitly for a timeout with:
-
- 7.18. Increased Flexibility of SWITCH Case Labels
-
- Prior to C-Kermit 7.0 / K95 1.1.19, the case labels in SWITCH
- statements were string constants.
-
- Now case labels can be variables, function calls, or any mixture of
- these with each other and/or with regular characters.
-
- Furthermore, after the case label is evaluated, it is treated not as a
- string constant, but as a pattern against which the SWITCH variable is
- matched ([626]Section 4.9.1).
-
- This introduces a possible incompatibility with previous releases,
- since the following characters in case labels are no longer taken
- literally:
-
- \ * ? [ {
-
- Any scripts that previously included any of these characters in case
- labels must now quote them with backslash (\).
-
- 7.19. "Kerbang" Scripts
-
- In UNIX only, Kermit scripts can be stored in files and run "directly",
- without starting Kermit first (as noted on page 467 of the manual),
- just as a shell script can be "run" as if it were a program. This
- section amplifies on that idea a bit, and presents some new aspects of
- version 7.0 that make it easier to write and run Kermit scripts
- directly.
-
- NOTE: On non-UNIX platforms, such as VMS or Windows, Kerbang scripts
- can be run as "kermit + scriptfilename arg1 arg2 arg3 ...". Windows
- 95/98/NT file associations do not allow for the passing of
- parameters. In VMS, however, you can achieve the Kerbang effect by
- defining a symbol, as in this example:
-
- $ autotelnet :== "$SYS$TOOLS:KERMIT.EXE + AUTOTELNET.KSC"
-
- and then running the script like any other command:
-
- $ autotelnet xyzcorp.com myuserid
-
- See [627]Section 9.3 for an explanation of the "+" symbol.
-
- UNIX shell scripts can specify which shell should run them by including
- a "shebang" line at the top, e.g.:
-
- #!/bin/sh
-
- (but not indented; the shebang line must be on the left margin). The
- term "shebang" is a contraction of "shell" and "bang". "Bang" is a
- slang word for the exclamation mark ("!"); "shebang" itself is an
- American slang word used in in the phrase "the whole shebang".
-
- We can run Kermit scripts directly too, by including a "shebang" line
- that names Kermit as the "shell"; thus we call these "Kerbang" scripts.
- This mechanism has been considerably simplified in C-Kermit 7.0 to
- facilitate C-Kermit's use a scripting tool just like any of the UNIX
- shells or scripting languages. The rules are the same as for shell
- scripts:
-
- 1. The first line of the Kermit script must begin with "#!"
- immediately followed by the full pathname of the program that will
- execute the script (in this case, C-Kermit rather than a UNIX
- shell), followed by any Kermit command-line options. To suppress
- execution of the C-Kermit initialization file and to make command
- line arguments available to the script, the final option should be
- "+":
- #!/usr/local/bin/kermit +
-
- Some users have reported that in some circumstances a space might
- be necessary after the plus sign; this depends on your shell -- it
- has nothing to do with Kermit. In most cases, no space is needed.
- 2. The file must have execute permission (granted via "chmod +x
- filename").
-
- When C-Kermit is invoked from a Kerbang script (or from the system
- prompt with a "+" command-line argument, which amounts to the same
- thing), the following special rules apply:
-
- 1. The C-Kermit initialization file is NOT executed automatically. If
- you want it to be executed, include a TAKE command for it in the
- script, e.g. "take \v(home).kermrc". (In previous releases, the
- initialization file was always executed, with no way to prevent it
- except for the user to include Kermit-specific command line options
- which had nothing to do with the script). Many scripts have no need
- for the standard Kermit initialization file, which is quite lengthy
- and not only delays startup of the script, but also spews forth
- numerous messages that are most likely unrelated to the script.
- 2. If the initialization file is not executed, neither is your
- customization file, since the initialization file is the command
- file from which the customization file is TAKEn. Again, you can
- include a TAKE command for the initialization file if desired, or
- for the customization file by itself, or for any other file.
- 3. C-Kermit does not process command-line arguments at all. Instead,
- it passes all words on the command line after the "+" to the script
- as \%0 (the script name), \%1..\%9 (the first nine arguments), as
- well as in the argument vector array \&_[]. The variable \v(argc)
- is set to the total number of "words" (as passed by the shell to
- Kermit) including the script name. Quoting and grouping rules are
- those of the shell.
- 4. At any point where the script terminates, it must include an EXIT
- command if you want it to exit back to the shell; otherwise
- C-Kermit enters interactive prompting mode when the script
- terminates. The EXIT command can include a numeric status to be
- returned to the shell (0, 1, etc), plus an optional message.
-
- Here is a simple Kerbang script that prints its arguments:
-
- #/usr/local/bin/kermit +
- echo Hello from \%0
- for \%i 0 \v(argc)-1 1 {
- echo \%i. "\&_[\%i]"
- }
- exit 0
-
- Save this file as (say) "showargs", then give it execute permission and
- run it (the \&_[] array is the same as \%0..\%9, but allows you to
- refer to argument variables programmatically; see [628]Section 7.5).
- (Yes, you could substitute SHOW ARGUMENTS for the loop.)
-
- $ chmod +x showargs
- $ ./showargs one "this is two" three
-
- The script displays its arguments:
-
- Hello from /usr/olga/showargs
- 0. "/usr/olga/showargs"
- 1. "one"
- 2. "this is two"
- 3. "three"
- $
-
- Notice that no banners or greetings are printed and that startup is
- instantaneous, just like a shell script. Also notice that grouping of
- arguments is determined by *shell* quoting rules, not Kermit ones,
- since the command line is parsed by the shell before Kermit ever sees
- it.
-
- Of course you can put any commands at all into a Kerbang script. It can
- read and write files, make connections, transfer files, anything that
- Kermit can do -- because it *is* Kermit. And of course, Kerbang scripts
- can also be executed from the Kermit prompt (or from another script)
- with a TAKE command; the Kerbang line is ignored since it starts with
- "#", which is a comment introducer to Kermit just as it is to the UNIX
- shell. In VMS and other non-UNIX platforms, the Kerbang line has no
- effect and can be omitted.
-
- It might be desirable for a script to know whether it has been invoked
- directly from the shell (as a Kerbang script) or by a TAKE command
- given to the Kermit prompt or in a Kermit command file or macro. This
- can be done as in this example:
-
- #!/usr/local/bin/kermit +
- assign \%m \fbasename(\%0)
- define usage { exit 1 {usage: \%m phonenumber message} }
- define apage { (definition of APAGE...) } ; (See [629]book pp.454-456)
- xif equal "\%0" "\v(cmdfil)" {
- if not def \%1 usage
- if not def \%2 usage
- apage {\%1} {\%2}
- exit \v(status)
- }
-
- In a Kerbang script, \%0 and \v(cmdfile) are the same; both of them are
- the name of the script. When a script is invoked by a Kermit TAKE
- command, \%0 is the name of the Kermit program, but \v(cmdfile) is the
- name of the script. In the example above, a macro called APAGE is
- defined. If the script was invoked directly, the APAGE macro is also
- executed. Otherwise, it is available for subsequent and perhaps
- repeated use later in the Kermit session.
-
- An especially handy use for Kerbang scripts is to have the
- initialization file itself be one. Since the standard initialization
- file is rather long and time-consuming to execute, it is often overkill
- if you want to start Kermit just to transfer a file. Of course there
- are command-line switches to suppress initialization-file execution,
- etc, but another approach is to "run" the initialization file when you
- want its features (notably the services directory), and run C-Kermit
- directly when you don't. A setup like this requires that (a) the
- C-Kermit initialization file is configured as a Kerbang script (has
- #!/path.../kermit as first line), has execute permission, and is in
- your PATH; and (b) that you don't have a .kermrc file in your login
- directory.
-
- 7.20. IF and XIF Statement Syntax
-
- The IF command has been improved in two significant ways in C-Kermit
- 7.0, described in the following subsections. All changes are backwards
- compatible.
-
- 7.20.1. The IF/XIF Distinction
-
- The distinction between IF and XIF is no longer important as of
- C-Kermit 7.0. You should be able to use IF in all cases (and of course,
- also XIF for backwards compatibility). In the past, IF was used for
- single-command THEN parts, followed optionally by a separate ELSE
- command:
-
- IF condition command1 ; THEN part
- ELSE command2 ; ELSE part
-
- whereas XIF was required if either part had multiple commands:
-
- XIF condition { command, command, ... } ELSE { command, command, ... }
-
- The syntactic differences were primarily that IF / ELSE was two
- commands on two separate lines, whereas XIF was one command on one
- line, and that XIF allowed (and in fact required) braces around its
- command lists, whereas IF did not allow them.
-
- Furthermore, the chaining or nesting of parts and conditions was
- inconsistent. For example, the IF command could be used like this:
-
- IF condition command
- ELSE IF condition command
- ELSE IF condition command
- ELSE IF condition command
- ...
-
- but XIF could not. C-Kermit 7.0 accepts the old syntax and executes it
- the same as previous versions, but also accepts a new unified and more
- convenient syntax:
-
- IF condition command-list [ ELSE command-list ]
-
- or:
-
-IF condition command-list
-ELSE command-list
-
- in which the ELSE part is optional, and where command-list can be a
- single command (with or without braces around it) or a list of commands
- enclosed in braces. Examples:
-
- Example 1:
-
- IF condition { command1, command2 } ELSE { command3, command4 }
-
- Example 2 (same as Example 1):
-
- IF condition {
- command1
- command2
- } ELSE {
- command3
- command4
- }
-
- Example 3 (same as 1 and 2):
-
- IF condition {
- command1
- command2
- }
- ELSE { command3, command4 }
-
- Example 4 (same as 1-3):
-
- IF condition {
- command1
- command2
- }
- ELSE {
- command3
- command4
- }
-
- Example 5 (ELSE can be followed by another command):
-
- IF condition1 {
- command1
- command2
- } ELSE IF condition2 {
- command3
- command4
- } ELSE {
- command5
- command6
- }
-
- Example 5 suggests other possibilities:
-
- IF condition {
- command1
- command2
- } ELSE FOR variable initial final increment {
- command3
- command4
- }
-
- And this too is possible, except for some non-obvious quoting
- considerations:
-
- dcl \&a[6] = one two three four five six
-
- IF < \%n 3 {
- echo \\%n is too small: \%n
- } ELSE FOR \\%i 1 \\%n 1 {
- echo \\%i. \\&a[\\%i]
- }
-
- (The loop variable must be quoted in this context to prevent premature
- evaluation.)
-
- Many C programmers prefer to code IF-ELSE, WHILE, FOR, and SWITCH with
- the block-open bracket on its own line. This does not work in Kermit:
-
- IF condition ; THIS FORMAT DOES NOT NOT WORK
- {
- command1
- command2
- }
- ELSE
- {
- command3
- command4
- }
-
- Explanation: the Kermit command language is line oriented; each line is
- a command, each command is a line. The first line above, having no hint
- of continuation, is an incomplete command, yet syntactically correct --
- an IF statement with an empty THEN part. Interestingly enough, since
- the next line begins with "{" it is a block that (in [630]C-Kermit 8.0
- and later) is a block that is executed unconditionally. Thus the
- commands in the THEN part are executed regardless of whether the
- condition is true -- not what you wanted!
-
- The new block syntax used in the IF, WHILE, FOR, and SWITCH commands
- employs certain tricks to allow multiple lines to be treated as a
- single line:
-
- * Any line ending with "{" (ignoring whitespace and comments) marks
- the beginning of a block;
- * Any line beginning with "}" (ignoring whitespace) marks the end of
- a block;
- * Line breaks within a block separate commands; the comma is implied
- by the line end.
-
- Thus:
-
- IF condition {
- command1
- command2
- } ELSE {
- command3
- command4
- }
-
- is "assembled" into:
-
- IF condition { command1, command2 } ELSE { command3, command4 }
-
- Note the addition of commas to separate commands within blocks. As
- always, if you need continue a command onto additional lines, you can
- end the continued lines with the continuation character, "-". You can
- also do this if you want to put opening brackets on their own line:
-
- IF condition -
- {
- command1
- command2
- }
- ELSE -
- {
- command3
- command4
- }
-
- 7.20.2. Boolean Expressions (The IF/WHILE Condition)
-
- Prior to C-Kermit 7.0, the IF and WHILE commands accepted only a single
- Boolean ("true or false") assertion, e.g. "if > \%m 0 command" or "if
- exist filename command". There was no way to form Boolean expressions
- and, in particular, nothing that approached a Boolean OR function (AND
- could be simulated by concatenating IF statements: "if condition1 if
- condition2..").
-
- C-Kermit 7.0 (and K95 1.1.19) allow grouping of Boolean assertions
- using parentheses and combining them using AND (or &&) and OR (or ||).
- Each of these operators -- including the parentheses -- is a field and
- must be set off by spaces. AND has higher precedence than OR, NOT has
- higher precedence than AND, but parentheses can be used to force any
- desired order of evaluation. The old syntax is still accepted.
-
- Here are some examples:
-
- define \%z 0 ; Define some variables
- define \%n 1 ; for use in the examples.
-
- if > \%n \%z echo \%n is greater. ; Original format - still accepted.
- if ( > \%n \%z ) echo \%n is greater. ; Parentheses may be used in 7.0.
- if ( > \%n \%z && not = \%z 0 ) ... ; Two assertions combined with AND.
- if ( > \%n \%z and not = \%z 0 ) ... ; Same as previous ("and" = "&&").
- if ( > \%n \%z || not = \%z 0 ) ... ; Two assertions combined with OR.
- if ( > \%n \%z or not = \%z 0 ) ... ; Same as previous ("or" = "||").
- if ( > \%n \%z || != \%z 0 ) ... ; Ditto ("!=" = "not =").
- while ( 1 ) { ... } ; Just like C.
-
- Notice the spaces around all operators including the parentheses --
- these are required. The following examples show how parentheses can be
- used to alter the precedence of the AND and OR operators:
-
- if ( false || false && false || true ) ,.. ; True
- if ( false || ( false && false ) || true ) ... ; Same as previous
- if ( ( false || false ) && ( false || true ) ) ... ; False
-
- Similarly for NOT:
-
- if ( not true && false ) ... ; False (NOT binds to TRUE only)
- if ( ( not true ) && false ) ... ; Same as previous
- if ( not ( true && false ) ) ... ; True (NOT binds to (TRUE && FALSE))
-
- Notes:
-
- 1. The syntax of the Boolean expression itself has not changed; each
- expression begins with a keyword or token such as "EXIST", ">", or
- "=", etc; operators such as "<", "=", and ">" do not go between
- their operands but precede them as before; this might be called
- "reverse reverse Polish notation"; it allows deterministic
- on-the-fly parsing of these expressions at the C-Kermit> prompt as
- well as in scripts, and allows ?-help to be given for each item
- when IF or WHILE commands are typed at the prompt.
- 2. Parentheses are required when there is more than one Boolean
- assertion.
- 3. Parentheses are not required, but are allowed, when there is only
- one Boolean assertion.
- 4. Evaluation of Boolean assertions occurs left to right, but the
- resulting Boolean expression is evaluated afterwards according to
- the rules of precedence. All Boolean assertions are always
- evaluated; there is no "early stopping" property and therefore no
- question about when or if side effects will occur -- if any Boolean
- assertion has side effects, they will always occur. (Early stopping
- is, however, possible with the [631]S-Expression IF introduced in
- C-Kermit 8.0.)
-
- Constructions of arbitrary complexity are possible, within reason.
-
- Also see [632]Section 7.4 for new IF / WHILE conditions.
-
- 7.21. Screen Formatting and Cursor Control
-
- C-Kermit 7.0 adds a simple way to create formatted screens, the SCREEN
- command:
-
- SCREEN { CLEAR, CLEOL, MOVE-TO row [ column ] }
- Performs screen-formatting actions. Correct operation of these
- commands depends on proper terminal setup on both ends of the
- connection -- mainly that the host terminal type is set to agree
- with the kind of terminal or the emulation you are viewing
- C-Kermit through. The UNIX version uses terminfo or termcap (not
- curses); the VMS version uses SMG; K-95 uses its built in screen
- manager.
-
- SCREEN CLEAR
- Moves the cursor to home position and clears the entire screen.
- Synonyms: CLEAR COMMAND-SCREEN ALL (K-95 only), CLS, CLEAR
- SCREEN.
-
- SCREEN CLEOL
- Clears from the current cursor position to the end of the line.
- Synonym: CLEAR COMMAND-SCREEN EOL (K-95 only)
-
- SCREEN MOVE-TO row column
- Moves the cursor to the indicated row and column. The row and
- column numbers are 1-based, so on a 24x80 screen the home
- position is 1 1 and the lower right corner is 24 80. If a row or
- column number is given that too large for what Kermit or the
- operating system thinks is your screen size, the appropriate
- number is substituted.
-
- These escape sequences used by these commands depends on the platform.
- In UNIX, your TERM environment variable is used to query the
- terminfo/termcap database; if the query fails, ANSI/VT100 sequences are
- used. In VMS, the SMG library is used, which sends sequences based on
- your VMS terminal type. K95 does its own screen control. On other
- platforms (such as AOS/VS, VOS, etc), screen formatting is not
- supported, and the SCREEN command does nothing.
-
- The three SCREEN actions can be used in scripts to produce menus,
- formatted screens, dynamic displays, etc. Related variables include:
-
- \v(terminal) The type terminal C-Kermit thinks you have.
- \v(rows) The number of rows C-Kermit thinks your terminal has.
- \v(columns) The number of columns C-Kermit thinks your terminal has.
-
- And functions:
-
- \fscrncurx() The current X coordinate of the cursor (K-95 only).
- \fscrncury() The current Y coordinate of the cursor (K-95 only).
- \fscrnstr(x,y,n) The string of length nat position (x,y) (K-95 only).
-
- And commands:
-
- ECHO string Writes string + CRLF at the current cursor position.
- XECHO string Writes string at current cursor position; CRLF not supplied.
- GETC v prompt Issues prompt, reads one character into variable v, no echo.
-
- And special characters:
-
- Ctrl-L At the C-Kermit> command prompt, or in a C-Kermit command,
- works like Return or Enter, but also clears the screen
-
- Example 1: A macro that prints a message \%1 at cursor position
- (\%2,\%3):
-
- define MSG {
- if not def \%3 def \%3 0 ; Default column to 0
- if > \v(argc) 2 screen move \%2 \%3 ; Move to given row/col (if any)
- screen cleol ; Clear to end of line
- if def \%1 xecho \fcontents(\%1) ; Print message (if any)
- }
-
- Example 2: A macro put the cursor on the bottom screen line, left
- margin:
-
- define BOT {
- screen move \v(rows) 0
- }
-
- Example 3: A macro to center message \%1 on line \%2.
-
- define CENTER {
- if not def \%2 def \%2 1
- .\%x ::= (\v(cols)-\flen(\%1))/2
- msg {\%1} {\%2} {\%x}
- }
-
- Example 4: A simple menu (building on Examples 1-3):
-
- def \%c 0 ; Menu choice variable
- screen clear ; Clear the screen
- center {Welcome to This Menu} 2 ; Display the menu
- msg {Choices:} 4
- msg { 1. File} 6
- msg { 2. Edit} 7
- msg { 3. Exit} 8
- while ( != \%c 3 ) { ; Read and verify choice
- while true { ; Keep trying till we get a good one
- screen move 10 ; Move to line 10
- screen cleol ; Clear this line
- getc \%c {Your choice: } ; Prompt and get and echo 1 character
- xecho \%c
- if ( not numeric \%c ) { msg {Not numeric - "\%c"} 12, continue }
- if ( >= \%c 1 && <= \%c 3 ) break
- msg {Out of range - "\%c"} 12
- }
- switch \%c { ; Valid choice - execute it.
- :1, msg {Filing... } 12, break
- :2, msg {Editing...} 12, break
- :3, msg {Exiting...} 12, break
- }
- }
- echo Bye ; Exit chosen - say goodbye.
- bot ; Leave cursor at screen bottom.
- exit ; And exit.
-
- Similar scripts can work over the communication connection; substitute
- INPUT and OUTPUT for GETC and ECHO/XECHO.
-
- 7.22. Evaluating Arithmetic Expressions
-
- A new arithmetic operator was added to the list recognized by the
- EVALUATE command, the \feval() function, and which can also be used
- anywhere else arithmetic expressions are accepted (numeric command
- fields, array subscripts, etc):
-
- Prefix "!"
- This operator inverts the "truth value" of the number or
- arithmetic expression that follows. If the value of the operand
- is 0, the result is 1. If the value is nonzero, the result is 0.
-
- Examples:
-
- set eval old
- evaluate 0
- 0
-
- evaluate !0
- 1
-
- evaluate !3
- 0
-
- evaluate !(-3)
- 0
-
- .\%a = 1
- .\%b = 0
- evaluate !(\%a|\%b)
- 0
-
- evaluate !(\%a&\%b)
- 1
-
- evaluate !(!(\%a&\%b))
- 0
-
- Note the distinction between Prefix ! (invert truth value) and Suffix !
- (factorial). Also the distinction between Prefix ! and Prefix ~ (which
- inverts all the bits in its operand). Also note that prefix operators
- (!, -, and ~) can not be adjacent unless you use parentheses to
- separate them, as shown in the final example above.
-
- 7.23. Floating-Point Arithmetic
-
- For a more convenient way of dealing with floating-point numbers
- than the one described here, see the [633]C-Kermit 8.0 update notes,
- the section on [634]S-Expressions.
-
- C-Kermit 7.0 adds limited support for floating-point numbers (numbers
- that have fractional parts, like 3.141592653). This support is provided
- through a small repertoire of functions and in Boolean expressions that
- compare numbers, but does not apply to number parsing in general, or to
- expression evaluation, array subscripts, the INCREMENT and DECREMENT
- commands, or in any context other than those listed in this section.
-
- A floating point number has an optional sign (+ or -), followed by a
- series of decimal digits containing either zero or one period (.)
- character, which is the decimal point. The use of comma or any other
- character besides period as a decimal point is not supported.
- Scientific notation is not supported either. Examples of legal
- floating-point numbers:
-
- 0 Integers can be used
- 1 Ditto
- 2. A decimal point without decimal digits
- 3.0 A decimal point with decimal digits
- 3.141592653 Ditto
- -4.0 A negative sign can be included
- +5.0 A positive sign can be included
-
- Examples of notations that are not accepted:
-
- 1,000,000 Separators can not be used
- 1.000.000 Ditto (or multiple decimal points)
- 6.022137E23 No scientific notation
- 6.62606868e-34 Ditto
- 12.5+6.25 No "bare" expressions
-
- You can use IF FLOAT test a string or variable to see if it's in
- acceptable floating-point format. Example:
-
- ask \%f { Type a number: }
- if not def \%f .\%f = 0.0
- if not float \%f stop 1 Invalid floating-point number: "\%f"
-
- C-Kermit's floating-point support, like its support for whole numbers
- (integers), relies on the capabilities of the underlying computer. Your
- computer has only a limited amount of precision for numbers, depending
- on its architecture. Thus floating-point numbers that have too many
- digits will not be accurate; adding a very small number to a very large
- one might have no effect at all; and so on. For details, read a text on
- numerical analysis. Example:
-
- .\%a = 11111111111111111111 ; A long number
- .\%b = 22222222222222222222 ; Another one
- echo \ffpadd(\%a,\%b) ; Add them - the result should be all 3's
- 33333333333333330000.0 ; See the result
-
- In this example, the computer has 16 digits of precision; after that,
- the (low-order) digits are set to 0, since the computer doesn't know
- what they really are. In fact, the computer returns random digits, but
- Kermit sets all digits beyond the computer's precision to 0.
-
- C-Kermit's floating-point functions have names of the form
- "\ffpxxx(args)" ("\f" for function, "fp" for floating-point), where
- "xxx" is replaced by the name of the function, such as "sqrt", and
- "args" is the argument list, consisting of one or two floating-point
- numbers (depending on the function), and an optional "d" argument that
- says now many decimal places should be shown in the result. Example:
-
- \ffpdiv(10,3,1) returns "3.3"
- \ffpdiv(10,3,2) returns "3.33"
- \ffpdiv(10,3,3) returns "3.333"
-
- and so on, up to the precision of the computer. If the decimal-places
- argument is less than zero, the fractional part of the result is
- truncated:
-
- \ffpdiv(10,3,-1) returns "3".
-
- If the decimal-places argument is 0, or is omitted, C-Kermit returns as
- many decimal places as are meaningful in the computer's floating-point
- precision, truncating any extraneous trailing 0's:
-
- \ffpdiv(10,8) returns "1.25".
- \ffpdiv(10,4) returns "2.5".
- \ffpdiv(10,2) returns "5.0".
- \ffpdiv(10,3) returns "3.333333333333333" (for 16-digit precision).
-
- There is no way to request that a floating-point function return a
- decimal point but no decimal places. However, this is easy enough to
- accomplish in other ways, for example by supplying it outside the
- function call:
-
- echo \ffpadd(\%a,\%b,-1).
-
- Kermit's floating-point functions always round the result for the
- requested number of decimal places when the "d" argument is given and
- has a value greater than 0 (see the description of \ffpround() just
- below).
-
- Floating-point arguments can be constants in floating-point format or
- variables whose values are floating-point numbers. If a floating-point
- argument is omitted, or is a variable with no value, 0.0 is supplied
- automatically. Example:
-
- def \%x 999.999
- undef \%y
- echo \ffpmin(\%x,\%y)
- 0.0
-
- Or equivalently:
-
- echo \ffpmin(999.999)
- 0.0
-
- The floating-point functions are:
-
- \ffpround(f1,d)
- Returns f1 rounded to d decimal places. For this function only,
- d = 0 (or d omitted) has a special meaning: return the integer
- part of f1 rounded according to the fractional part. Examples:
-
- \ffpround(2.74653,-1) returns "2" (fraction truncated, no rounding).
- \ffpround(2.74653,0) returns "3" (integer part is rounded).
- \ffpround(2.74653) returns "3" (d omitted same as d = 0).
- \ffpround(2.74653,1) returns "2.7".
- \ffpround(2.74653,2) returns "2.75".
- \ffpround(2.74653,3) returns "2.747".
- \ffpround(2.74653,4) returns "2.7465", etc.
-
- \ffpadd(f1,f2,d)
- Returns the sum of f1 and f2.
-
- \ffpsubtract(f1,f2,d)
- Subtracts f2 from f1 and returns the result.
-
- \ffpmultiply(f1,f2,d)
- Returns the product of f1 and f2.
-
- \ffpdivide(f1,f2,d)
- If f2 is not 0, divides f1 by f2 and returns the quotient.
- If f2 is 0, a DIVIDE_BY_ZERO error occurs.
-
- \ffpraise(f1,f2,d)
- If f1 = 0 and f2 <= 0, or if f1 < 0 and f2 has a fractional
- part, an ARG_OUT_OF_RANGE error occurs; otherwise f1 raised to
- the f2 power is returned.
-
- \ffpsqrt(f1,d)
- If f1 >= 0, returns the square root of f1; otherwise
- ARG_OUT_OF_RANGE.
-
- \ffpabsolute(f1,d)
- Returns the absolute value of f1 (i.e. f1 without a sign). This
- is the floating-point analog of \fabsolute(n1).
-
- \ffpint(f1)
- Returns the integer part of f1. Equivalent to \ffpround(f1,-1).
-
- \ffpexp(f1,d)
- The base of natural logarithms, e (2.718282...), raised to the
- f1 power.
-
- \ffplogn(f1,d)
- The natural logarithm of f1 (the power to which e must be raised
- to obtain f1).
-
- \ffplog10(f1,d)
- The base-10 logarithm of f1 (the power to which 10 must be
- raised to obtain f1).
-
- \ffpmodulus(f1,f2,d)
- If f2 is not 0, the remainder after dividing f1 by f2.
- If f2 is 0, a DIVIDE_BY_ZERO error occurs.
- This is the floating-point analog of \fmod(n1,n2).
-
- \ffpmaximum(f1,f2,d)
- Returns the maximum of f1 and f2. This is the floating-point
- analog of \fmax(n1,n2).
-
- \ffpminimum(f1,f2,d)
- Returns the minimum of f1 and f2. This is the floating-point
- analog of \fmin(n1,n2).
-
- \ffpsine(f1,d)
- Returns the sine of f1 radians.
-
- \ffpcosine(f1,d)
- Returns the cosine of f1 radians.
-
- \ffptangent(f1,d)
- Returns the tangent of f1 radians.
-
- Note that all of these functions can be used with integer arguments. If
- you want an integer result, specify d = -1 (to truncate) or feed the
- result to \ffpround(xxx,0) (to round).
-
- Floating-point numbers (or variables or functions that return them) can
- be used in Boolean expressions (see [635]Section 7.20.2) that compare
- numbers:
-
- = x y
- != x y
- < x y
- > x y
- <= x y
- >= x y
-
- In these examples, x and y can be either integers or floating-point
- numbers in any combination. In an arithmetic comparison of an integer
- and a floating-point number, the integer is converted to floating-point
- before the comparison is made. Examples:
-
- .\%t = 3.000000000
- .\%f = 3.141592653
- .\%i = 3
-
- if > \%f \%i echo Pi is greater.
- if = \%t \%i echo "\%i" = "\%t".
-
- A floating-point number can also be used in:
-
- IF number command
-
- where the command is executed if the number is nonzero. If the number
- is floating-point, the command is not executed if the number is 0.0,
- and is executed otherwise.
-
- Floating-point numbers can be sorted using ARRAY SORT /NUMERIC (see
- [636]Section 7.10.5 ).
-
- Two floating-point constants are provided:
-
- \v(math_pi) = Pi (3.141592653...)
- \v(math_e) = e, the base of natural logarithms (2.71828...)
-
- These are given to the computer's precision, e.g. 16 digits. This
- number itself is available in a variable:
-
- \v(math_precision)
- How many significant digits in a floating-point number.
-
- 7.24. Tracing Script Execution
-
- The TRACE command is handy for debugging scripts.
-
- TRACE [ { /ON, /OFF } ] [ { ASSIGNMENTS, COMMAND-LEVEL, ALL } ]
- Selects tracing of the given object.
-
- Optional switches are /ON and /OFF. If no switch is given, /ON is
- implied. The trace objects are ASSIGNMENTS, COMMAND-LEVEL, and ALL. The
- default object is ALL, meaning to select all trace objects (besides
- ALL). Thus TRACE by itself selects tracing of everything, as does TRACE
- /ON, and TRACE /OFF turns off all tracing.
-
- When tracing of ASSIGNMENTS is on, every time the value of any
- user-defined variable or macro changes, C-Kermit prints one of the
- following:
-
- >>> name: "value"
- The name of the variable or macro followed by the new value in
- quotes. This includes implicit macro-parameter assignments
- during macro invocation.
-
- >>> name: (undef)
- This indicates that the variable or macro has been undefined.
-
- <<< name: "value"
- For RETURN statements: the name of the macro and the return
- value.
-
- <<< name: (null)
- For RETURN statements that include no value or an empty value.
-
- When tracing of COMMAND-LEVEL is on, C-Kermit prints:
-
- [n] +F: "name"
- Whenever a command file is entered, where "n" is the command
- level (0 = top); the name of the command file is shown in
- quotes.
-
- [n] +M: "name"
- Whenever a macro is entered; "n" is the command level. The name
- of the macro is shown in quotes.
-
- [n] -F: "name"
- Whenever a command file is reentered from below, when a macro or
- command file that it has invoked has returned.
-
- [n] -M: "name"
- Whenever a macro is reentered from below.
-
- For other debugging tools, see SHOW ARGS, SHOW STACK, SET TAKE, SET
- MACRO, and of course, ECHO.
-
- 7.25. Compact Substring Notation
-
- It is often desirable to extract a substring from a string which is
- stored in a variable, and for this we have the \fsubstring() function,
- which is used like this:
-
- define \%a 1234567890
- echo \fsubstring(\%a,3,4) ; substring from 3rd character length 4
- 3456
-
- or like this with macro-named variables:
-
- define string 1234567890
- echo \fsubstring(\m(string),3,4)
- 3456
-
- C-Kermit 7.0 adds a pair of alternative compact notations:
-
-\:(variablename[start:length]) <-- Substring of variable's value
-\s(macroname[start:length]) <-- Substring of macro's definition
-
- These are exactly equivalent to using \fsubstring(), except more
- compact to write and also faster since evaluation is in one step
- instead of two.
-
- The "\:()" notation can be used with any Kermit variable, that is,
- almost anything that starts with a backslash:
-
- \:(\%a[2:6]) <-- equivalent to \fsubstring(\%a,2,6)
- \:(\&x[1][2:6]) <-- equivalent to \fsubstring(\&x[1],2,6)
- \:(\m(foo)[2:6]) <-- equivalent to \fsubstring(\m(foo),2,6)
- \:(\v(time)[2:6]) <-- equivalent to \fsubstring(\v(time),2,6)
- \:(\$(TERM)[2:6]) <-- equivalent to \fsubstring(\$(TERM),2,6)
- \:(ABCDEFGH[2:6]) <-- equivalent to \fsubstring(ABCDEFGH,2,6)
-
- Whatever appears between the left parenthesis and the left bracket is
- evaluated and then the indicated substring of the result is returned.
-
- The "\s()" notation is the same, except after evaluating the variable,
- the result is treated as a macro name and is looked up in the macro
- table. Then the indicated substring of the macro definition is
- returned. Example:
-
- define testing abcdefghijklmnopqrstuvwxyz
- define \%a testing
-
- \s(testing[2:6]) --> bcdefg
- \:(testing[2:6]) --> esting
- \:(\%a[2:6]) --> esting
- \s(\%a[2:6]) --> bcdefg
-
- Note that the following two examples are equivalent:
-
- \:(\m(foo)[2:6])
- \s(foo[2:6])
-
- The first number in the brackets is the 1-based starting position. If
- it is omitted, or less than 1, it is treated as 1. If it is greater
- than the length of the string, an empty string is returned.
-
- The second number is the length of the desired substring. If the second
- number is omitted, is less than 0, or would be past the end of the
- string, then "through the end of the string" is assumed. If it is 0,
- the empty string is returned.
-
- If the brackets are empty or omitted, the original string is returned.
-
- The starting position and length need not be literal numbers; they can
- also be variables, functions, arithmetic expressions, or even other
- \s() or \:() quantities; anything that evaluates to a number, for
- example:
-
- \s(block[1025:\fhex2n(\s(block[\%b:\%n+4]))/2])
-
- Syntactically, \m(name) and \s(name) differ only in that the sequence
- [*] at the end of the name (where * is any sequence of 0 or more
- characters) is treated as substring notation in \s(name), but is
- considered part of the name in \m(name) (to see why, see [637]Section
- 7.10.9).
-
- 7.26. New WAIT Command Options
-
- The WAIT command has been extended to allow waiting for different kinds
- of things (formerly it only waited for modem signals). Now it also can
- wait for file events.
-
- 7.26.1. Waiting for Modem Signals
-
- The previous syntax:
-
- WAIT time { CD, DSR, RTS, RI, ... }
-
- has changed to:
-
- WAIT time MODEM-SIGNALS { CD, DSR, RTS, RI, ... }
-
- However, the previous syntax is still accepted. The behavior is the
- same in either case.
-
- 7.26.2. Waiting for File Events
-
- The new WAIT option:
-
- WAIT time FILE { CREATION, DELETION, MODIFICATION } filename
-
- lets you tell Kermit to wait the given amount of time (or until the
- given time of day) for a file whose name is filename to be created,
- deleted, or modified, respectively. The filename may not contain
- wildcards. If the specified event does not occur within the time limit,
- or if WAIT CANCELLATION is ON and you interrupt from the keyboard
- before the time is up, the WAIT command fails. If the event is
- MODIFICATION and the file does not exist, the command fails. Otherwise,
- if the given event occurs within the time limit, the command succeeds.
- Examples:
-
- WAIT 600 FILE DELETION oofa.tmp
- Wait up to 10 minutes for file oofa.tmp to disappear.
-
- WAIT 23:59:59 FILE MOD orders.db
- Wait until just before midnight for the orders.db file to be
- changed.
-
- Example: Suppose you want to have the current copy of /etc/motd on your
- screen at all times, and you want to hear a bell whenever it changes:
-
- def \%f /etc/motd ; The file of interest.
- while 1 { ; Loop forever...
- cls ; Clear the screen.
- echo \%f: \v(date) \v(time)... ; Print 2-line heading...
- echo
- if ( not exist \%f ) { ; If file doesn't exist,
- echo \%f does not exist... ; print message,
- wait 600 file creat \%f ; and wait for it to appear.
- continue
- }
- beep ; Something new - beep.
- type /head:\v(rows-2) \%f ; Display the file
- if fail exit 1 \%f: \ferrstring() ; (checking for errors).
- wait 999 file mod \%f ; Wait for it to change.
- }
-
- This notices when the file is created, deleted, or modified, and acts
- only then (or when you interrupt it with); the time shown in the
- heading is the time of the most recent event (including when the
- program started).
-
- See [638]Section 1.10, where the \v(kbchar) variable is explained. This
- lets you modify a loop like the one above to also accept
- single-character commands, which interrupt the WAIT, and dispatch
- accordingly. For example:
-
- wait 999 file mod \%f ; Wait for the file to change.
- if defined \v(kbchar) { ; Interrupted from keyboard?
- switch \v(kbchar) { ; Handle the keystroke...
- :q, exit ; Q to Quit
- :h, echo blah blah, break ; H for Help
- :default, beep, continue ; Anything else beep and ignore
- }
- }
-
- This lets you write event-driven applications that wait for up to three
- events at once: a file or modem event, a timeout, and a keystroke.
-
- 7.27. Relaxed FOR and SWITCH Syntax
-
- For consistency with the extended IF and WHILE syntax, the FOR and
- SWITCH control lists may (but need not be) enclosed in parentheses:
-
- FOR ( \%i 1 \%n 1 ) { command-list... }
- SWITCH ( \%c ) { command-list... }
-
- In the FOR command, the increment item can be omitted if the control
- list is enclosed in parentheses, in which case the increment defaults
- appropriately to 1 or -1, depending on the values of the first two
- variables.
-
- As with IF, the parentheses around the FOR-command control list must be
- set off by spaces (in the SWITCH command, the spaces are not required
- since the SWITCH expression is a single arithmetic expression).
-
- Also, outer braces around the command list are supplied automatically
- if you omit them, e.g.:
-
- FOR ( \%i 1 %n 1 ) echo \%i
-
- 8. USING OTHER FILE TRANSFER PROTOCOLS
-
- In C-Kermit 7.0, alternative protocols can be selected using switches.
- Switches are described in [639]Section 1.5; the use of
- protocol-selection switches is described in [640]Section 4.7.1.
- Example:
-
- send /binary /protocol:zmodem x.tar.gz
-
- Note that file transfer recovery works only with Kermit and Zmodem
- protocols. With Zmodem, recovery can be initiated only by the sender.
-
- Only pre-1988 versions of the publicly-distributed sz/rz programs use
- Standard I/O; those released later than that do not use Standard I/O
- and therefore do not work with REDIRECT. However, Omen Technology does
- offer an up-to-date redirectable version called crzsz, which must be
- licensed for use:
-
- "Unix Crz and Csz support XMODEM, YMODEM, and ZMODEM transfers when
- called by dial-out programs such as Kermit and certain versions of
- cu(1). They are clients designed for this use.
-
- "Crz and Csz are Copyrighted shareware programs. Use of these
- programs beyond a brief evaluation period requires registration.
- Please print the "mailer.rz" file, fill out the form and return same
- with your registration."
-
- To use the crzsz programs as your external XYZMODEM programs in
- C-Kermit, follow the instructions in the book, but put a "c" before
- each command, e.g.:
-
- set protocol zmodem {csz %s} {csz -a %s} crz crz crz crz
-
- To use Zmodem protocol over Telnet or other non-transparent
- connections, you might need to add the -e (Escape) option:
-
- set protocol zmodem {csz -e %s} {csz -e -a %s} crz crz crz crz
-
- 9. COMMAND-LINE OPTIONS
-
- 9.0. Extended-Format Command-Line Options
-
- Standard UNIX command line options are a single letter. C-Kermit has
- run out of letters, so new options are in a new extended format:
-
- --word[:arg]
-
- where a keyword (rather than a single letter) specifies the function,
- and if an argument is to be included, it is separated by a colon (or
- equal sign). Most of the new extended-format command-line options are
- only for use with the Internet Kermit Service Daemon; see the [641]IKSD
- Administration Guide for details. However, several of them are also
- general in nature:
-
- --nointerrupts
- Disables keyboard interrupts that are normally enabled, which
- are usually Ctrl-C (to interrupt a command) and Ctrl-Z (UNIX
- only, to suspend C-Kermit).
-
- --help
- Lists the extended command-line options that are available in
- your version of C-Kermit. If any options seem to be missing,
- that is because your copy of C-Kermit was built with
- compile-time options to deselect them.
-
- --helpfile:filename
- Specifies the name of a file to be displayed if the user types
- HELP (not followed by a specific command or topic), in place of
- the built-in top-level help text. The file need not fit on one
- screen; more-prompting is used if the file is more than one
- screen long if COMMAND MORE-PROMPTING is ON, as it is by
- default.
-
- --bannerfile:filename
- The name of a file containing a message to be printed after the
- user logs in, in place of the normal message (Copyright notice,
- "Type HELP or ? for help", "Default transfer mode is...", etc).
-
- --cdmessage:{on,off,0,1,2}
- For use in the Server-Side Server configuration; whenever the
- client tells the server to change directory, the server sends
- the contents of a "read me" file to the client's screen. This
- feature is On by default, and operates only in client/server
- mode when ON or 1. If set to 2 or higher, it also operates when
- the CD command is given at the IKSD> prompt. Synonym: --cdmsg.
-
- --cdfile:filename
- When cdmessage is on, this is the name of the "read me" file to
- be sent. Normally you would specify a relative (not absolute)
- name, since the file is opened using the literal name you
- specified, after changing to the new directory. Example:
-
- --cdfile:READ.ME
-
- You can also give a list of up to 8 filenames by (a) enclosing
- each filename in braces, and (b) enclosing the entire list in
- braces. Example:
- --cdfile:{{./.readme}{READ.ME}{aaareadme.txt}{README}{read-this-
- first}} When a list is given, it is searched from left to right
- and the first file found is displayed. The default list for UNIX
- is:
-
- {{./.readme}{README.TXT}{READ.ME}}
-
- 9.1. Command Line Personalities
-
- Beginning in version 7.0, if the C-Kermit binary is renamed to "telnet"
- (or TELNET.EXE, telnet.pr, etc, depending on the platform), it accepts
- the Telnet command line:
-
- telnet [ host [ port ] ]
-
- In Unix, you can achieve the same effect with a symlink:
-
- cd /usr/bin
- mv telnet oldtelnet
- ln -ls /usr/local/bin/kermit telnet
-
- When installed in this manner, C-Kermit always reads its initialization
- file. If no host (and therefore no port) is given, C-Kermit starts in
- interactive prompting mode. If a host is given as the first
- command-line argument, C-Kermit makes a connection to it. The host
- argument can be an IP host name or address, or the name of a TCP/IP
- entry in your C-Kermit network directory.
-
- If a port is given, it is used. If a port is not given, then if the
- hostname was found in your network directory and port was also listed
- there, then that port is used. Otherwise port 23 (the Telnet port) is
- used.
-
- When C-Kermit is called "telnet" and it is invoked with a hostname on
- the command line, it exits automatically when the connection is closed.
- While the connection is open, however, you may escape back and forth as
- many times as you like, transfer files, etc.
-
- An rlogin personality is also available, but it is less useful, at
- least in UNIX and VMS, where the Rlogin TCP port is privileged.
-
- The new variable \v(name) indicates the name with which C-Kermit was
- invoked ("kermit", "wermit", "k95", "telnet", etc).
-
- 9.2. Built-in Help for Command Line Options
-
- "kermit -h", given from the system prompt, lists as many command-line
- options as will fit on a standard 24x80 screen. For more comprehensive
- help, use the interactive HELP OPTIONS command that was added in
- C-Kermit 7.0:
-
- HELP OPTIONS
- Explains how command-line options work, their syntax, etc.
-
- HELP OPTIONS ALL
- Lists all command-line options and gives brief help about each one.
-
- HELP OPTION x
- Gives brief help about option "x".
-
- HELP EXTENDED-OPTIONS
- Lists the available extended-format command-line options.
-
- HELP EXTENDED-OPTION xxx
- Gives help for the specified extended option.
-
- 9.3. New Command-Line Options
-
- Command-line options added since C-Kermit 6.0 are:
-
- +
- (plus sign by itself): The next argument is the name of a script
- to execute; all subsequent arguments are ignored by C-Kermit
- itself, but passed to the script as top-level copies of \%1,
- \%2, etc; the \&_[] is also set accordingly. \%0 and \&_[0]
- become the name of the script file, rather than the pathname of
- the C-Kermit program, which is its normal value. Primarily for
- use in the top line of "Kerbang" scripts in UNIX (see
- [642]Section 7.19). Example from UNIX command line:
-
- $ kermit [ regular kermit args ] + filename
-
- Sample first line of Kerbang script:
-
- #!/usr/local/bin/kermit +
-
- --
- (two hyphens surrounded by whitespace) Equivalent to "=", for
- compatibility with UNIX getopt(1,3).
-
- -G
- GET (like -g), but send the incoming file to standard output.
- Example: "kermit -G oofa.txt | lpr" retrieves a file from your
- local computer (providing it is running a Kermit program that
- supports the autodownload feature and has it enabled) and prints
- it.
-
- -O
- equivalent to -x (start up in server mode), but exits after the
- first client command has been executed (mnemonic: O = Only One).
- This one is handy replacing "kermit -x" in the "automatically
- start Kermit on the other end" string:
-
- set protocol kermit {kermit -ir} {kermit -r} {kermit -x}
-
- since -x leaves the remote Kermit in server mode after the
- transfer, which can be confusing, whereas -O makes it go away
- automatically after the transfer.
-
- -L
- Recursive, when used in combination with -s (mnemonic: L =
- Levels). In UNIX or other environments where the shell expands
- wildcards itself, the -s argument, if it contains wildcards,
- must be quoted to prevent this, e.g.:
-
- kermit -L -s "*.c"
-
- In UNIX only, "kermit -L -s ." means to send the current
- directory tree. See [643]Sections 4.10 and [644]4.11 about
- recursive file transfer.
-
- -V
- Equivalent to SET FILE PATTERNS OFF ([645]Section 4.3) and SET
- TRANSFER MODE MANUAL. In other words, take the FILE TYPE setting
- literally. For example, "kermit -VT oofa.bin" means send the
- file in Text mode, no matter what its name is and no matter
- whether a kindred spirit is recognized at the other end of the
- connection.
-
- -0
- (digit zero) means "be 100% transparent in CONNECT mode". This
- is equivalent to the following series of commands: SET PARITY
- NONE, SET COMMAND BYTESIZE 8, SET TERMINAL BYTESIZE 8, SET FLOW
- NONE, SET TERM ESCAPE DISABLED, SET TERM CHAR TRANSPARENT, SET
- TERM AUTODOWNLOAD OFF, SET TERM APC OFF, SET TELOPT KERMIT
- REFUSE REFUSE.
-
- 10. C-KERMIT AND G-KERMIT
-
- Every multifunctioned and long-lived software program grows in
- complexity and size over time to meet the needs and requests of its
- users and the demands of the underlying technology as it changes.
-
- Eventually users begin to notice how big the application has grown, how
- much disk space it occupies, how long it takes to load, and they start
- to long for the good old days when it was lean and mean. Not long after
- that they begin asking for a "light" version that only does the basics
- with no frills.
-
- And so it is with C-Kermit. A "light" version of Kermit was released
- (for UNIX only) in December 1999 under the GNU General Public License;
- thus it is called G-Kermit (for GNU Kermit). All it does is send and
- receive files, period. You can find it at:
-
- [646]http://www.columbia.edu/kermit/gkermit.html
-
- Where the C-Kermit 7.0 binary might be anywhere from 1 to 3 million
- bytes in size, the G-Kermit binary ranges from 30K to 100K, depending
- on the underlying architecture (RISC vs CISC, etc).
-
- G-Kermit and C-Kermit may reside side-by-side on the same computer.
- G-Kermit does not make connections; it does not have a script language;
- it does not translate character sets. G-Kermit may be used instead of
- C-Kermit when:
-
- * It is on the remote end.
- * Files are to be transferred in binary mode or in text mode without
- character-set translation.
- * File timestamps don't need to be preserved.
-
- In such cases G-Kermit might be preferred since it generally starts up
- faster, and yet transfers files just as fast on most (but not
- necessarily all) kinds of connections; for example, it supports
- streaming ([647]Section 4.20).
-
- G-Kermit is also handy for bootstrapping. It is easier to load on a new
- computer than C-Kermit -- it fits on a floppy diskette with plenty of
- room to spare. Thus if you have (say) an old PC running (say) SCO Xenix
- and no network connection, you can download the Xenix version of
- G-Kermit to (say) a DOS or Windows PC, copy it to diskette, read the
- diskette on Xenix with "dosread", and then use G-Kermit to receive
- C-Kermit (which does not fit on a diskette). If diskettes aren't an
- option, other bootstrapping methods are possible too -- see the
- [648]G-Kermit web page for details.
-
-III. APPENDICES
-
- III.1. Character Set Tables
-
- III.1.1. The Hewlett Packard Roman8 Character Set
-
-dec col/row oct hex description
-160 10/00 240 A0 (Undefined)
-161 10/01 241 A1 A grave
-162 10/02 242 A2 A circumflex
-163 10/03 243 A3 E grave
-164 10/04 244 A4 E circumflex
-165 10/05 245 A5 E diaeresis
-166 10/06 246 A6 I circumflex
-167 10/07 247 A7 I diaeresis
-168 10/08 250 A8 Acute accent
-169 10/09 251 A9 Grave accent
-170 10/10 252 AA Circumflex accent
-171 10/11 253 AB Diaeresis
-172 10/12 254 AC Tilde accent
-173 10/13 255 AD U grave
-174 10/14 256 AE U circumflex
-175 10/15 257 AF Lira symbol
-176 11/00 260 B0 Top bar (macron)
-177 11/01 261 B1 Y acute
-178 11/02 262 B2 y acute
-179 11/03 263 B3 Degree Sign
-180 11/04 264 B4 C cedilla
-181 11/05 265 B5 c cedilla
-182 11/06 266 B6 N tilde
-183 11/07 267 B7 n tilde
-184 11/08 270 B8 Inverted exclamation mark
-185 11/09 271 B9 Inverted question mark
-186 11/10 272 BA Currency symbol
-187 11/11 273 BB Pound sterling symbol
-188 11/12 274 BC Yen symbol
-189 11/13 275 BD Paragraph
-190 11/14 276 BE Florin (Guilder) symbol
-191 11/15 277 BF Cent symbol
-192 12/00 300 C0 a circumflex
-193 12/01 301 C1 e circumflex
-194 12/02 302 C2 o circumflex
-195 12/03 303 C3 u circumflex
-196 12/04 304 C4 a acute
-197 12/05 305 C5 e acute
-198 12/06 306 C6 o acute
-199 12/07 307 C7 u acute
-200 12/08 310 C8 a grave
-201 12/09 311 C9 e grave
-202 12/10 312 CA o grave
-203 12/11 313 CB u grave
-204 12/12 314 CC a diaeresis
-205 12/13 315 CD e diaeresis
-206 12/14 316 CE o diaeresis
-207 12/15 317 CF u diaeresis
-208 13/00 320 D0 A ring
-209 13/01 321 D1 i circumflex
-210 13/02 322 D2 O with stroke
-211 13/03 323 D3 AE digraph
-212 13/04 324 D4 a ring
-213 13/05 325 D5 i acute
-214 13/06 326 D6 o with stroke
-215 13/07 327 D7 ae digraph
-216 13/08 330 D8 A diaeresis
-217 13/09 331 D9 i grave
-218 13/10 332 DA O diaeresis
-219 13/11 333 DB U diaeresis
-220 13/12 334 DC E acute
-221 13/13 335 DD i diaeresis
-222 13/14 336 DE German sharp s
-223 13/15 337 DF O circumflex
-224 14/00 340 E0 A acute
-225 14/01 341 E1 A tilde
-226 14/02 342 E2 a tilde
-227 14/03 343 E3 Icelandic Eth
-228 14/04 344 E4 Icelandic eth
-229 14/05 345 E5 I acute
-230 14/06 346 E6 I grave
-231 14/07 347 E7 O acute
-232 14/08 350 E8 O grave
-233 14/09 351 E9 O tilde
-234 14/10 352 EA o tilde
-235 14/11 353 EB S caron
-236 14/12 354 EC s caron
-237 14/13 355 ED U acute
-238 14/14 356 EE Y diaeresis
-239 14/15 357 EF y diaeresis
-240 15/00 360 F0 Icelandic Thorn
-241 15/01 361 F1 Icelandic thorn
-242 15/02 362 F2 Middle dot
-243 15/03 363 F3 Greek mu
-244 15/04 364 F4 Pilcrow sign
-245 15/05 365 F5 Fraction 3/4
-246 15/06 366 F6 Long dash, horizontal bar
-247 15/07 367 F7 Fraction 1/4
-248 15/08 370 F8 Fraction 1/2
-249 15/09 371 F9 Feminine ordinal
-250 15/10 372 FA Masculine ordinal
-251 15/11 373 FB Left guillemot
-252 15/12 374 FC Solid box
-253 15/13 375 FD Right guillemot
-254 15/14 376 FE Plus or minus sign
-255 15/15 377 FF (Undefined)
-
- III.1.2. Greek Character Sets
-
- III.1.2.1. The ISO 8859-7 Latin / Greek Alphabet = ELOT 928
-
-dec col/row oct hex description
-160 10/00 240 A0 No-break space
-161 10/01 241 A1 Left single quotation mark
-162 10/02 242 A2 right single quotation mark
-163 10/03 243 A3 Pound sign
-164 10/04 244 A4 (UNUSED)
-165 10/05 245 A5 (UNUSED)
-166 10/06 246 A6 Broken bar
-167 10/07 247 A7 Paragraph sign
-168 10/08 250 A8 Diaeresis (Dialytika)
-169 10/09 251 A9 Copyright sign
-170 10/10 252 AA (UNUSED)
-171 10/11 253 AB Left angle quotation
-172 10/12 254 AC Not sign
-173 10/13 255 AD Soft hyphen
-174 10/14 256 AE (UNUSED)
-175 10/15 257 AF Horizontal bar (Parenthetiki pavla)
-176 11/00 260 B0 Degree sign
-177 11/01 261 B1 Plus-minus sign
-178 11/02 262 B2 Superscript two
-179 11/03 263 B3 Superscript three
-180 11/04 264 B4 Accent (tonos)
-181 11/05 265 B5 Diaeresis and accent (Dialytika and Tonos)
-182 11/06 266 B6 Alpha with accent
-183 11/07 267 B7 Middle dot (Ano Teleia)
-184 11/08 270 B8 Epsilon with accent
-185 11/09 271 B9 Eta with accent
-186 11/10 272 BA Iota with accent
-187 11/11 273 BB Right angle quotation
-188 11/12 274 BC Omicron with accent
-189 11/13 275 BD One half
-190 11/14 276 BE Upsilon with accent
-191 11/15 277 BF Omega with accent
-192 12/00 300 C0 iota with diaeresis and accent
-193 12/01 301 C1 Alpha
-194 12/02 302 C2 Beta
-195 12/03 303 C3 Gamma
-196 12/04 304 C4 Delta
-197 12/05 305 C5 Epsilon
-198 12/06 306 C6 Zeta
-199 12/07 307 C7 Eta
-200 12/08 310 C8 Theta
-201 12/09 311 C9 Iota
-202 12/10 312 CA Kappa
-203 12/11 313 CB Lamda
-204 12/12 314 CC Mu
-205 12/13 315 CD Nu
-206 12/14 316 CE Ksi
-207 12/15 317 CF Omicron
-208 13/00 320 D0 Pi
-209 13/01 321 D1 Rho
-210 13/02 322 D2 (UNUSED)
-211 13/03 323 D3 Sigma
-212 13/04 324 D4 Tau
-213 13/05 325 D5 Upsilon
-214 13/06 326 D6 Phi
-215 13/07 327 D7 Khi
-216 13/08 330 D8 Psi
-217 13/09 331 D9 Omega
-218 13/10 332 DA Iota with diaeresis
-219 13/11 333 DB Upsilon with diaeresis
-220 13/12 334 DC alpha with accent
-221 13/13 335 DD epsilon with accent
-222 13/14 336 DE eta with accent
-223 13/15 337 DF iota with accent
-224 14/00 340 E0 upsilon with diaeresis and accent
-225 14/01 341 E1 alpha
-226 14/02 342 E2 beta
-227 14/03 343 E3 gamma
-228 14/04 344 E4 delta
-229 14/05 345 E5 epsilon
-230 14/06 346 E6 zeta
-231 14/07 347 E7 eta
-232 14/08 350 E8 theta
-233 14/09 351 E9 iota
-234 14/10 352 EA kappa
-235 14/11 353 EB lamda
-236 14/12 354 EC mu
-237 14/13 355 ED nu
-238 14/14 356 EE ksi
-239 14/15 357 EF omicron
-240 15/00 360 F0 pi
-241 15/01 361 F1 rho
-242 15/02 362 F2 terminal sigma
-243 15/03 363 F3 sigma
-244 15/04 364 F4 tau
-245 15/05 365 F5 upsilon
-246 15/06 366 F6 phi
-247 15/07 367 F7 khi
-248 15/08 370 F8 psi
-249 15/09 371 F9 omega
-250 15/10 372 FA iota with diaeresis
-251 15/11 373 FB upsilon with diaeresis
-252 15/12 374 FC omicron with diaeresis
-253 15/13 375 FD upsilon with accent
-254 15/14 376 FE omega with accent
-255 15/15 377 FF (UNUSED)
-
- III.1.2.2. The ELOT 927 Character Set
-
-dec col/row oct hex description
- 32 02/00 40 20 SPACE
- 33 02/01 41 21 EXCLAMATION MARK
- 34 02/02 42 22 QUOTATION MARK
- 35 02/03 43 23 NUMBER SIGN
- 36 02/04 44 24 DOLLAR SIGN
- 37 02/05 45 25 PERCENT SIGN
- 38 02/06 46 26 AMPERSAND
- 39 02/07 47 27 APOSTROPHE
- 40 02/08 50 28 LEFT PARENTHESIS
- 41 02/09 51 29 RIGHT PARENTHESIS
- 42 02/10 52 2A ASTERISK
- 43 02/11 53 2B PLUS SIGN
- 44 02/12 54 2C COMMA
- 45 02/13 55 2D HYPHEN, MINUS SIGN
- 46 02/14 56 2E PERIOD, FULL STOP
- 47 02/15 57 2F SOLIDUS, SLASH
- 48 03/00 60 30 DIGIT ZERO
- 49 03/01 61 31 DIGIT ONE
- 50 03/02 62 32 DIGIT TWO
- 51 03/03 63 33 DIGIT THREE
- 52 03/04 64 34 DIGIT FOUR
- 53 03/05 65 35 DIGIT FIVE
- 54 03/06 66 36 DIGIT SIX
- 55 03/07 67 37 DIGIT SEVEN
- 56 03/08 70 38 DIGIT EIGHT
- 57 03/09 71 39 DIGIT NINE
- 58 03/10 72 3A COLON
- 59 03/11 73 3B SEMICOLON
- 60 03/12 74 3C LESS-THAN SIGN, LEFT ANGLE BRACKET
- 61 03/13 75 3D EQUALS SIGN
- 62 03/14 76 3E GREATER-THAN SIGN, RIGHT ANGLE BRACKET
- 63 03/15 77 3F QUESTION MARK
- 64 04/00 100 40 COMMERCIAL AT SIGN
- 65 04/01 101 41 CAPITAL LETTER A
- 66 04/02 102 42 CAPITAL LETTER B
- 67 04/03 103 43 CAPITAL LETTER C
- 68 04/04 104 44 CAPITAL LETTER D
- 69 04/05 105 45 CAPITAL LETTER E
- 70 04/06 106 46 CAPITAL LETTER F
- 71 04/07 107 47 CAPITAL LETTER G
- 72 04/08 110 48 CAPITAL LETTER H
- 73 04/09 111 49 CAPITAL LETTER I
- 74 04/10 112 4A CAPITAL LETTER J
- 75 04/11 113 4B CAPITAL LETTER K
- 76 04/12 114 4C CAPITAL LETTER L
- 77 04/13 115 4D CAPITAL LETTER M
- 78 04/14 116 4E CAPITAL LETTER N
- 79 04/15 117 4F CAPITAL LETTER O
- 80 05/00 120 50 CAPITAL LETTER P
- 81 05/01 121 51 CAPITAL LETTER Q
- 82 05/02 122 52 CAPITAL LETTER R
- 83 05/03 123 53 CAPITAL LETTER S
- 84 05/04 124 54 CAPITAL LETTER T
- 85 05/05 125 55 CAPITAL LETTER U
- 86 05/06 126 56 CAPITAL LETTER V
- 87 05/07 127 57 CAPITAL LETTER W
- 88 05/08 130 58 CAPITAL LETTER X
- 89 05/09 131 59 CAPITAL LETTER Y
- 90 05/10 132 5A CAPITAL LETTER Z
- 91 05/11 133 5B LEFT SQUARE BRACKET
- 92 05/12 134 5C REVERSE SOLIDUS, BACKSLASH
- 93 05/13 135 5D RIGHT SQUARE BRACKET
- 94 05/14 136 5E CIRCUMFLEX ACCENT
- 95 05/15 137 5F UNDERSCORE
- 96 06/00 140 60 ACCENT GRAVE
- 97 06/01 141 61 GREEK LETTER ALPHA
- 98 06/02 142 62 GREEK LETTER BETA
- 99 06/03 143 63 GREEK LETTER GAMMA
-100 06/04 144 64 GREEK LETTER DELTA
-101 06/05 145 65 GREEK LETTER EPSILON
-102 06/06 146 66 GREEK LETTER ZETA
-103 06/07 147 67 GREEK LETTER ETA
-104 06/08 150 68 GREEK LETTER THETA
-105 06/09 151 69 GREEK LETTER IOTA
-106 06/10 152 6A GREEK LETTER KAPPA
-107 06/11 153 6B GREEK LETTER LAMDA
-108 06/12 154 6C GREEK LETTER MU
-109 06/13 155 6D GREEK LETTER NU
-110 06/14 156 6E GREEK LETTER KSI
-111 06/15 157 6F GREEK LETTER OMICRON
-112 07/00 160 70 GREEK LETTER PI
-113 07/01 161 71 GREEK LETTER RHO
-114 07/02 162 72 GREEK LETTER SIGMA
-115 07/03 163 73 GREEK LETTER TAU
-116 07/04 164 74 GREEK LETTER UPSILON
-117 07/05 165 75 GREEK LETTER FI
-118 07/06 166 76 GREEK LETTER XI
-119 07/07 167 77 GREEK LETTER PSI
-120 07/08 170 78 GREEK LETTER OMEGA
-121 07/09 171 79 SPACE
-122 07/10 172 7A SPACE
-123 07/11 173 7B LEFT CURLY BRACKET, LEFT BRACE
-124 07/12 174 7C VERTICAL LINE, VERTICAL BAR
-125 07/13 175 7D RIGHT CURLY BRACKET, RIGHT BRACE
-126 07/14 176 7E TILDE
-127 07/15 177 7F RUBOUT, DELETE
-
- III.1.2.3. PC Code Page 869
-
- (to be filled in...)
-
- III.2. Updated Country Codes
-
- Date: Mon, 7 Apr 1997 23:23:49 EDT
- From: Dave Leibold <dleibold@else.net>
- Newsgroups: comp.dcom.telecom
- Subject: Ex-USSR Country Codes Profile
- Organization: TELECOM Digest
-
- Ex-USSR Country Codes Profile
- 4 April 1997
-
- Below is a summary of the country codes that have formed in the wake of
- the USSR dissolution, along with some updated findings and reports.
- Additional or corrected information on any of these nations would be
- welcome (c/o dleibold@else.net).
- * Kyrgyz Republic country code 996 will take effect, at least in
- Canada, effective 1 May 1997, according to CRTC Telecom Order
- 97-464, based on Stentor Tariff Notice 433. There is no indication
- whether there will be a permissive dialing period involved or for
- how long such a permissive operation would remain.
- * Country code 992 was reported as a recent assignment for
- Tajikistan, which will be moving from country code 7 at some
- unknown time.
- * Uzbekistan has its own country code assignment, but I have no
- information if this is in service yet or what implementation dates
- have been set.
- * Kazakstan does not have a known separate country code assignment at
- present. It remains in country code 7 for the time being.
- * Russia seems destined to keep country code 7.
- * Recent news reports speak of some agreements forming between Russia
- and Belarus. While there is no outright reunification yet, there is
- expected to be much closer ties between the two nations. Whether
- this will lead to a reunification of telephone codes remains to be
- seen.
-
- In the table, "Effective" means the date at which the country code
- began service (which could vary according to the nation). "Mandatory"
- means the date at which the country code 7 is invalid for calls to that
- nation. There are a number of question marks since exact dates have not
- been collected in all cases.
-
-CC Nation Effective Mandatory Notes
-
-370 Lithuania 1993? ??? Announced Jan 1993
-371 Latvia 1993? ???
-372 Estonia 1 Feb 1993? March 1993?
-373 Moldova 1993? ??? Announced Jan 1993
-374 Armenia 1 May 1995 1 July 1995 Announced Jan 1995 (ITU)
-375 Belarus 16 Apr 1995 1997?
-380 Ukraine 16 Apr 1995 Oct 1995?
-7 Kazakstan (no known changes)
-7 Russia (presumably not changing)
-992 Tajikistan ??? ??? Announced 1996-7?
-993 Turkmenistan 3 Jan 1997 3 Apr 1997 Canada as of 29 Nov 1996
-994 Azerbaijan Sept 1994? ??? Announced 1992
-995 Georgia 1994? ??? ref: Telecom Digest Oct 1994
-996 Kyrgyz Republic 1 May 1997 ??? ref: Stentor Canada/CRTC
-998 Uzbekistan ??? ??? Announced 1996? (ITU)
-
- Details courtesy Toby Nixon, ITU, Stentor (Canada), CRTC (Canada),
- TELECOM Digest (including information collected for the country code
- listings).
-
-IV. ERRATA & CORRIGENDA
-
- The following errors in [649]Using C-Kermit, Second Edition, first
- printing, have been noted.
-
- First, some missing acknowledgements for C-Kermit 6.0: JE Jones of
- Microware for help with OS-9, Nigel Roles for his help with Plan 9,
- Lucas Hart for help with VMS and Digital UNIX, Igor Kovalenko for his
- help with QNX. And later, to Susan Kleinmann for her help with Debian
- Linux packaging; Patrick Volkerding for his help with Slackware Linux
- packaging; Jim Knoble for his help with Red Hat Linux packaging; and to
- dozens of others for sending individual C-Kermit binaries for varied
- and diverse platforms.
-
- Thanks to James Spath for both binaries and reporting many of the typos
- noted below. Also to Dat Thuc Nguyen for spotting several typos.
-
-PAGE REMARKS
-COVER "COS" is a misprint. There is no COS. Pretend it says "SCO" or "VOS".
- (This is fixed in the second printing.)
- xxi Second line: Fred Smith's affiliation should be Computrition.
- 83 Change "commands other" to "commands as other" (1st paragraph)
- 87 Change "The the" to "The" (2nd paragraph)
- 92 "set modem-type user-defined supra" should be "set modem type ..."
- 95 Change "VI" to "vi" (1st paragraph)
- 96 Change "it it" to "it is" (1st paragraph)
- 97 Change "advantage a literal" to "advantage of a literal" (2nd
- paragraph)
-102 The call-waiting example would be better as SET DIAL PREFIX *70W
- (rather than "*70,") because the former will not cause an incorrect
- call to be placed with pulse dialing.
-123 Third paragraph from bottom: "..otherwise if a your local username.."
- should be "..otherwise your local username..".
-160 Delete the "it" between "and" and "to" (2nd paragraph)
-185 In "When TRANSFER DISPLAY is OFF, C-Kermit skips the display...",
- "OFF" should be "NONE".
-187 The last paragraph says the "A command" is ignored, should be "S".
-194 Change "it known" to "it is known" (4th paragraph).
-235 In C-Kermit 7.0, the syntax of the GET command changed. MGET now
- must be used to get a list of files and there is no more multiline
- GET command.
-268 Last paragraph: "effect" should be "affect".
-275 In the SET PROTOCOL KERMIT description, the following sentence is
- incorrect and should be removed: 'If you omit the commands, the
- default ones are restored: "kermit -ir" and "kermit -r" respectively".
- The correct information is given at the bottom of page 281.
-279 9th line. The decimal value of ST is 156, not 155.
-295 In the stepping stones, skip ahead to Chapter 17 on p. 327.
-298 Table 16-2, Portuguese entry. Column 4/00 should show section sign,
- not acute accent.
-316 Other languages written in the Hebrew alphabet include Karaim (a Turkic
- language spoken in Lithuania and Poland), Judeo-Kurdish, and Judeo-
- Georgian.
-332 UNDEFINE definition, change "This just" to "This is just".
-344 It might be necessary to set the modem's pulse generation rate when
- sending numeric pages; most Hayes compatible modems use the S11
- register for this.
-350 Delete "is" from between "It" and "ceases" (4th paragraph)
-351 Top - both occurrences of "print \%a" should be "echo \%a".
-364 \v(input) and \v(query) out of alphabetical order.
-378 In the MYSEND macro, "if not \m(rc) goto bad" should be:
- "if \m(rc) goto bad" (remove the "not").
-382-383 It should be stated that the loop control variable must be of the \%a
- type, or else an array element; macro names can not be used for this.
-383 In line 3, "\%f[\%i]" should be "\&f[\%i]".
-383 In the sort example, it should be stated that the array is 1-based.
-387 Change "You can list" to "You can get a list" (5th paragraph)
-393 \Fverify() description. The 3rd sentence could be stated more clearly
- as "If all characters in string2 are also in string1, 0 is returned."
-398 Copying \ffiles() results to an array before is not required as of
- C-Kermit 7.0 (see [650]Section 7.3).
-403 In "(\%a + 3) * (\%b 5)", a minus sign is missing between b and 5.
-407 C-Kermit 7.0 no longer supports multiline GET. Change
- "get, \%1, \%2" to "get {\%1} {\%2}" or "get /as:{\%2} {\%1}".
-409 READ example while loop should be:
- while success { echo \m(line), read line }
-409 "WRITE file" should be "WRITE keyword" (you can't put a filename there)
- (The same applies to WRITE-LINE / WRITELN).
-414 \Funhexify() missing from Table 18-3.
-425 MINPUT definition, change 2nd "text2" to "text3".
-436 Several lines are missing from the UNIXLOGIN macro listing.
- After the "xif fail" block, insert:
-
- out \%1\13 ; Send username, carriage return
- inp 5 Password: ; Wait 5 sec for this prompt
- if fail end 1 No password prompt
- pause ; Wait a sec
- out \%2\13 ; Send password
-
-440 Change "set terminal byteszie" to "set terminal bytesize".
- Change "input Password:" to "input 10 Password".
-448 Franchise script: "access line" should be "access \m(line)".
-453 There are two incorrectly coded IF statements in the DELIVER macro
- definition. Replace both occurrences of "if > \%1 \%3 {" with
- "xif > \%i \%3 {" (replace "if" by "xif" and "\%1" with "\%i").
-453 "the the" (last paragraph) should be "the".
-454 EOT (last paragraph) is End of Transmission, not End of Text.
-457 _DEFINE definition: "name constructed" should be "name is constructed".
-457 "macro for and" (last paragraph) should be "macro and".
-459 Should explain that \v(user) is a legal abbreviation of \v(userid).
-480 Figure II-2 is backwards; the least-significant bit is transmitted
- first, then up to the highest, and the parity bit last.
-534 The VMS Appendix section on Odd Record Lengths no longer applies;
- C-Kermit 7.0 handles odd record lengths as well as even ones.
-559 Table VIII-3, Portuguese entry. Column 4/00 should show section sign,
- not acute accent.
-560-563 HP-Roman8 missing from Table VII-4; there wasn't room to squeeze it in.
- It is listed in section II(6).
-565 "d stroke" in Table VII-5 has the wrong appearance; the stem should
- be upright. The letter shown in the table is actually a lowercase
- Icelandic eth, which has a curved stem.
-601-604 BeBox, BeOS, Plan 9, and probably others not listed in trademarks.
-604 The words "SCRIBE TEXT FORMATTER" appear at the end of the last
- sentence of the first paragraph of the Colophon. They should have
- been in the Index.
-Index: Missing entries: SET { SEND, RECEIVE } PATHNAMES, Call waiting, ...
- \F() Page 605, add also 413-414
- \Fbreak 389
- \Fcapitalize 390
- \Fchecksum 414
- \Fcrc16 414
- \Fexecute 414
- \Fhexify 390
- \Fltrim 391
- \Frepeat 392
- \Fspawn 392
- \Ftod2secs 399
- \v() built_in Page 606, add also 361-364
- \v(_line) 354, 361
- \v(apcactive) 361
- \v(charset) 362
- \v(cpu) 362
- \v(crc16) 357, 362
- \v(d$xxx) add page 362
- \v(dialnumber) 362
- \v(dialresult) 362
- \v(errno) 362
- \v(errstring) 362
- \v(exedir) 362
- \v(inidir) 363
- \v(ipaddress) 363
- \v(keyboard) 363
- \v(macro) 363
- \v(minput) 363
- \v(m_xxx) 94, 363
- \v(password) 364
- \v(query) 364
- \v(prompt) 364
- \v(speed) 356, 364
- \v(startup) 364
- \v(status) 364
- \v(sysid) 364
- \v(system) 364
- \v(fsize) at lower half page 606 should read \v(tfsize)
- \v(xversion) 364
- BEEP Command 40
- SET FLOW 62, 212
-
- Figure II-5 on page 493. The pin assignments of the Mini Din-8
- connector are not described anywhere. As noted in the text, these tend
- to vary from vendor to vendor. One common arrangement is:
-
- 1. HSKout (Handshake out -- definition depends on software)
- 2. HSKin (Handshake in or external clock)
- 3. TxD-
- 4. Not used
- 5. RxD-
- 6. TxD+
- 7. Not used
- 8. RxD+
-
- Note the "balanced pairs" for Receive Data (RxD) and Transmit Data
- (TxD), and the utter lack of modem signals. These connectors follow the
- RS-423 standard, rather than RS-232. In some arrangements, Pin 1 is
- used for DTR and Pin 2 for CD; in others Pin 1 is RTS and Pin 2 is CTS.
-
- Please send reports of other errors to the authors, as well as
- suggestions for improvements, additional index entries, and any other
- comments:
-
- [651]kermit@columbia.edu
-
-APPENDIX V. ADDITIONAL COPYRIGHT NOTICES
-
- The following copyrights cover some of the source code used in the
- development of C-Kermit, Kermit 95, or Kermit 95 support libraries.
-
-/*****************************************************************************/
-/* */
-/* Copyright (c) 1995 by Oy Online Solutions Ltd. */
-/* */
-/* Distribution of this source code is strictly forbidden. Use of this */
-/* source code is granted to the University of Columbia C-Kermit project */
-/* to be distributed in binary format only. Please familiarize yourself */
-/* with the accompanying LICENSE.P file. */
-/* */
-/*****************************************************************************/
-
- used for Xmodem, Ymodem, and Zmodem protocol in Kermit 95 (p95.dll,
- p2.dll)
-
- Copyright (c) 1997 Stanford University
-
- The use of this software for revenue-generating purposes may require a
- license from the owners of the underlying intellectual property.
- Specifically, the SRP-3 protocol may not be used for revenue-generating
- purposes without a license.
-
- Within that constraint, permission to use, copy, modify, and distribute
- this software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notices and this
- permission notice appear in all copies of the software and related
- documentation.
-
- THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
- IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
- ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
-
- Used for Secure Remote Password (TM) protocol (SRP) in C-Kermit, Kermit
- 95 (k95.exe, k2.exe, k95crypt.dll, k2crypt.dll)
-
- Copyright 1990 by the Massachusetts Institute of Technology. All Rights
- Reserved.
-
- Export of this software from the United States of America may require a
- specific license from the United States Government. It is the
- responsibility of any person or organization contemplating export to
- obtain such a license before exporting.
-
- WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute
- this software and its documentation for any purpose and without fee is
- hereby granted, provided that the above copyright notice appear in all
- copies and that both that copyright notice and this permission notice
- appear in supporting documentation, and that the name of M.I.T. not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission. M.I.T. makes no
- representations about the suitability of this software for any purpose.
- It is provided "as is" without express or implied warranty.
-
- Used for Telnet Authentication Option, Telnet Encryption Option, and
- Kerberos (TM) authentication in C-Kermit, Kermit 95 (k95.exe, k2.exe,
- k95crypt.dll, k2crypt.dll)
-
- Copyright (c) 1991, 1993 The Regents of the University of California.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the
- distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgement:
-
- This product includes software developed by the University of
- California, Berkeley and its contributors.
- 4. Neither the name of the University nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Used for Telnet Authentication Option, Telnet Encryption Option, and
- Kerberos (TM) authentication in C-Kermit, Kermit 95 (k95.exe, k2.exe,
- k95crypt.dll, k2crypt.dll)
-
- Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) All rights
- reserved.
-
- This package is an DES implementation written by Eric Young
- (eay@cryptsoft.com). The implementation was written so as to conform
- with MIT's libdes.
-
- This library is free for commercial and non-commercial use as long as
- the following conditions are aheared to. The following conditions apply
- to all code found in this distribution.
-
- Copyright remains Eric Young's, and as such any Copyright notices in
- the code are not to be removed. If this package is used in a product,
- Eric Young should be given attribution as the author of that the SSL
- library. This can be in the form of a textual message at program
- startup or in documentation (online or textual) provided with the
- package.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- 1. Redistributions of source code must retain the copyright notice,
- this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the
- distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgement: This product
- includes software developed by Eric Young (eay@cryptsoft.com)
-
- THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- The license and distribution terms for any publically available version
- or derivative of this code cannot be changed. i.e. this code cannot
- simply be copied and put under another distribution license [including
- the GNU Public License.]
-
- The reason behind this being stated in this direct manner is past
- experience in code simply being copied and the attribution removed from
- it and then being distributed as part of other packages. This
- implementation was a non-trivial and unpaid effort.
-
- Used DES encryption in Kermit 95 (k95crypt.dll, k2crypt.dll)
- __________________________________________________________________
-
- * This is version 1.1 of CryptoLib
- *
- * The authors of this software are Jack Lacy, Don Mitchell and Matt Blaze
- * Copyright (c) 1991, 1992, 1993, 1994, 1995 by AT&T.
- * Permission to use, copy, and modify this software without fee
- * is hereby granted, provided that this entire notice is included in
- * all copies of any software which is or includes a copy or
- * modification of this software and in all copies of the supporting
- * documentation for such software.
- *
- * NOTE:
- * Some of the algorithms in cryptolib may be covered by patents.
- * It is the responsibility of the user to ensure that any required
- * licenses are obtained.
- *
- *
- * SOME PARTS OF CRYPTOLIB MAY BE RESTRICTED UNDER UNITED STATES EXPORT
- * REGULATIONS.
- *
- *
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
- * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
-
- Used for Big Number library in Kermit 95 (k95crypt.dll, k2crypt.dll).
-
- [ [652]Top ] [ [653]C-Kermit ] [ [654]Kermit Home ]
- __________________________________________________________________
-
- CKERMIT70.HTM / The Kermit Project / Columbia University / 8 Feb 2000 /
- Last update: 8 Aug 2011
-
-References
-
- 1. http://www.columbia.edu/
- 2. mailto:kermit@columbia.edu
- 3. http://www.columbia.edu/kermit/index.html
- 4. http://www.columbia.edu/kermit/k95.html
- 5. http://www.columbia.edu/kermit/ckermit.html
- 6. http://www.columbia.edu/kermit/ckscripts.html
- 7. http://www.columbia.edu/kermit/current.html
- 8. http://www.columbia.edu/kermit/whatsnew.html
- 9. http://www.columbia.edu/kermit/faq.html
- 10. http://www.columbia.edu/kermit/support.html
- 11. http://www.amazon.com/gp/product/1555581641?ie=UTF8&tag=aleidmoreldom-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1555581641
- 12. mailto:kermit-support@columbia.edu
- 13. http://www.columbia.edu/kermit/
- 14. http://www.kermit-project.org/
- 15. http://www.columbia.nyc.ny.us/kermit/
- 16. ftp://kermit.columbia.edu/kermit/f/COPYING.TXT
- 17. ftp://kermit.columbia.edu/kermit/f/ckcmai.c
- 18. http://www.columbia.edu/kermit/ckermit70.html#xv
- 19. http://www.columbia.edu/kermit/ckb2.htm
- 20. ftp://kermit.columbia.edu/kermit/f/ckcbwr.txt
- 21. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt
- 22. ftp://kermit.columbia.edu/kermit/f/ckvbwr.txt
- 23. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt
- 24. ftp://kermit.columbia.edu/kermit/f/ckermit70.txt
- 25. ftp://kermit.columbia.edu/kermit/f/security.txt
- 26. http://www.columbia.edu/kermit/security.htm
- 27. ftp://kermit.columbia.edu/kermit/f/iksd.txt
- 28. http://www.columbia.edu/kermit/iksd.htm
- 29. http://www.columbia.edu/kermit/cuiksd.htm
- 30. ftp://kermit.columbia.edu/kermit/f/telnet.txt
- 31. http://www.columbia.edu/kermit/telnet.htm
- 32. ftp://kermit.columbia.edu/kermit/f/COPYING.TXT
- 33. http://www.columbia.edu/kermit/k95.html
- 34. http://www.opensource.org/
- 35. http://www.columbia.edu/kermit/ckb2.htm
- 36. http://www.columbia.edu/kermit/ckermit70.html#xi
- 37. http://www.columbia.edu/kermit/ckermit70.html#xii
- 38. http://www.columbia.edu/kermit/ckermit70.html#x0
- 39. http://www.columbia.edu/kermit/ckermit70.html#x1
- 40. http://www.columbia.edu/kermit/ckermit70.html#x1.0
- 41. http://www.columbia.edu/kermit/ckermit70.html#x1.1
- 42. http://www.columbia.edu/kermit/ckermit70.html#x1.2
- 43. http://www.columbia.edu/kermit/ckermit70.html#x1.3
- 44. http://www.columbia.edu/kermit/ckermit70.html#x1.4
- 45. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 46. http://www.columbia.edu/kermit/ckermit70.html#x1.5.1
- 47. http://www.columbia.edu/kermit/ckermit70.html#x1.5.2
- 48. http://www.columbia.edu/kermit/ckermit70.html#x1.5.3
- 49. http://www.columbia.edu/kermit/ckermit70.html#x1.5.4
- 50. http://www.columbia.edu/kermit/ckermit70.html#x1.5.5
- 51. http://www.columbia.edu/kermit/ckermit70.html#x1.6
- 52. http://www.columbia.edu/kermit/ckermit70.html#x1.7
- 53. http://www.columbia.edu/kermit/ckermit70.html#x1.8
- 54. http://www.columbia.edu/kermit/ckermit70.html#x1.9
- 55. http://www.columbia.edu/kermit/ckermit70.html#x1.10
- 56. http://www.columbia.edu/kermit/ckermit70.html#x1.11
- 57. http://www.columbia.edu/kermit/ckermit70.html#x1.11.1
- 58. http://www.columbia.edu/kermit/ckermit70.html#x1.11.2
- 59. http://www.columbia.edu/kermit/ckermit70.html#x1.11.3
- 60. http://www.columbia.edu/kermit/ckermit70.html#x1.11.4
- 61. http://www.columbia.edu/kermit/ckermit70.html#x1.11.5
- 62. http://www.columbia.edu/kermit/ckermit70.html#x1.11.6
- 63. http://www.columbia.edu/kermit/ckermit70.html#x1.11.7
- 64. http://www.columbia.edu/kermit/ckermit70.html#x1.12
- 65. http://www.columbia.edu/kermit/ckermit70.html#x1.13
- 66. http://www.columbia.edu/kermit/ckermit70.html#x1.14
- 67. http://www.columbia.edu/kermit/ckermit70.html#x1.15
- 68. http://www.columbia.edu/kermit/ckermit70.html#x1.16
- 69. http://www.columbia.edu/kermit/ckermit70.html#x1.17
- 70. http://www.columbia.edu/kermit/ckermit70.html#x1.18
- 71. http://www.columbia.edu/kermit/ckermit70.html#x1.19
- 72. http://www.columbia.edu/kermit/ckermit70.html#x1.20
- 73. http://www.columbia.edu/kermit/ckermit70.html#x1.21
- 74. http://www.columbia.edu/kermit/ckermit70.html#x1.22
- 75. http://www.columbia.edu/kermit/ckermit70.html#x1.22.1
- 76. http://www.columbia.edu/kermit/ckermit70.html#x1.22.2
- 77. http://www.columbia.edu/kermit/ckermit70.html#x1.22.3
- 78. http://www.columbia.edu/kermit/ckermit70.html#x1.22.4
- 79. http://www.columbia.edu/kermit/ckermit70.html#x1.22.5
- 80. http://www.columbia.edu/kermit/ckermit70.html#x1.22.6
- 81. http://www.columbia.edu/kermit/ckermit70.html#x1.22.7
- 82. http://www.columbia.edu/kermit/ckermit70.html#x1.22.8
- 83. http://www.columbia.edu/kermit/ckermit70.html#x1.23
- 84. http://www.columbia.edu/kermit/ckermit70.html#x1.24
- 85. http://www.columbia.edu/kermit/ckermit70.html#x2
- 86. http://www.columbia.edu/kermit/ckermit70.html#x2.0
- 87. http://www.columbia.edu/kermit/ckermit70.html#x2.1
- 88. http://www.columbia.edu/kermit/ckermit70.html#x2.1.1
- 89. http://www.columbia.edu/kermit/ckermit70.html#x2.1.2
- 90. http://www.columbia.edu/kermit/ckermit70.html#x2.1.3
- 91. http://www.columbia.edu/kermit/ckermit70.html#x2.1.4
- 92. http://www.columbia.edu/kermit/ckermit70.html#x2.1.5
- 93. http://www.columbia.edu/kermit/ckermit70.html#x2.1.6
- 94. http://www.columbia.edu/kermit/ckermit70.html#x2.1.7
- 95. http://www.columbia.edu/kermit/ckermit70.html#x2.1.8
- 96. http://www.columbia.edu/kermit/ckermit70.html#x2.1.9
- 97. http://www.columbia.edu/kermit/ckermit70.html#x2.1.10
- 98. http://www.columbia.edu/kermit/ckermit70.html#x2.1.11
- 99. http://www.columbia.edu/kermit/ckermit70.html#x2.1.12
- 100. http://www.columbia.edu/kermit/ckermit70.html#x2.1.13
- 101. http://www.columbia.edu/kermit/ckermit70.html#x2.1.14
- 102. http://www.columbia.edu/kermit/ckermit70.html#x2.1.15
- 103. http://www.columbia.edu/kermit/ckermit70.html#x2.1.16
- 104. http://www.columbia.edu/kermit/ckermit70.html#x2.2
- 105. http://www.columbia.edu/kermit/ckermit70.html#x2.2.1
- 106. http://www.columbia.edu/kermit/ckermit70.html#x2.2.2
- 107. http://www.columbia.edu/kermit/ckermit70.html#x2.3
- 108. http://www.columbia.edu/kermit/ckermit70.html#x2.3.0
- 109. http://www.columbia.edu/kermit/ckermit70.html#x2.3.1
- 110. http://www.columbia.edu/kermit/ckermit70.html#x2.3.2
- 111. http://www.columbia.edu/kermit/ckermit70.html#x2.3.3
- 112. http://www.columbia.edu/kermit/ckermit70.html#x2.3.4
- 113. http://www.columbia.edu/kermit/ckermit70.html#x2.3.5
- 114. http://www.columbia.edu/kermit/ckermit70.html#x2.3.6
- 115. http://www.columbia.edu/kermit/ckermit70.html#x2.4
- 116. http://www.columbia.edu/kermit/ckermit70.html#x2.5
- 117. http://www.columbia.edu/kermit/ckermit70.html#x2.6
- 118. http://www.columbia.edu/kermit/ckermit70.html#x2.7
- 119. http://www.columbia.edu/kermit/ckermit70.html#x2.7.0
- 120. http://www.columbia.edu/kermit/ckermit70.html#x2.7.1
- 121. http://www.columbia.edu/kermit/ckermit70.html#x2.7.2
- 122. http://www.columbia.edu/kermit/ckermit70.html#x2.7.3
- 123. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4
- 124. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4.1
- 125. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4.2
- 126. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4.3
- 127. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4.4
- 128. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4.5
- 129. http://www.columbia.edu/kermit/ckermit70.html#x2.8
- 130. http://www.columbia.edu/kermit/ckermit70.html#x2.9
- 131. http://www.columbia.edu/kermit/ckermit70.html#x2.9.1
- 132. http://www.columbia.edu/kermit/ckermit70.html#x2.9.2
- 133. http://www.columbia.edu/kermit/ckermit70.html#x2.10
- 134. http://www.columbia.edu/kermit/ckermit70.html#x2.11
- 135. http://www.columbia.edu/kermit/ckermit70.html#x2.12
- 136. http://www.columbia.edu/kermit/ckermit70.html#x2.13
- 137. http://www.columbia.edu/kermit/ckermit70.html#x2.14
- 138. http://www.columbia.edu/kermit/ckermit70.html#x2.15
- 139. http://www.columbia.edu/kermit/ckermit70.html#x3
- 140. http://www.columbia.edu/kermit/ckermit70.html#x3.1
- 141. http://www.columbia.edu/kermit/ckermit70.html#x3.2
- 142. http://www.columbia.edu/kermit/ckermit70.html#x3.3
- 143. http://www.columbia.edu/kermit/ckermit70.html#x3.4
- 144. http://www.columbia.edu/kermit/ckermit70.html#x4
- 145. http://www.columbia.edu/kermit/ckermit70.html#x4.0
- 146. http://www.columbia.edu/kermit/ckermit70.html#x4.1
- 147. http://www.columbia.edu/kermit/ckermit70.html#x4.1.1
- 148. http://www.columbia.edu/kermit/ckermit70.html#x4.1.2
- 149. http://www.columbia.edu/kermit/ckermit70.html#x4.1.3
- 150. http://www.columbia.edu/kermit/ckermit70.html#x4.2
- 151. http://www.columbia.edu/kermit/ckermit70.html#x4.2.1
- 152. http://www.columbia.edu/kermit/ckermit70.html#x4.2.1.1
- 153. http://www.columbia.edu/kermit/ckermit70.html#x4.2.1.2
- 154. http://www.columbia.edu/kermit/ckermit70.html#x4.2.1.3
- 155. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2
- 156. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2.1
- 157. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2.2
- 158. http://www.columbia.edu/kermit/ckermit70.html#x4.2.3
- 159. http://www.columbia.edu/kermit/ckermit70.html#x4.2.3.1
- 160. http://www.columbia.edu/kermit/ckermit70.html#x4.2.3.2
- 161. http://www.columbia.edu/kermit/ckermit70.html#x4.2.4
- 162. http://www.columbia.edu/kermit/ckermit70.html#x4.2.5
- 163. http://www.columbia.edu/kermit/ckermit70.html#x4.2.6
- 164. http://www.columbia.edu/kermit/ckermit70.html#x4.2.7
- 165. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8
- 166. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.1
- 167. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.2
- 168. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.3
- 169. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.4
- 170. http://www.columbia.edu/kermit/ckermit70.html#x4.3
- 171. http://www.columbia.edu/kermit/ckermit70.html#x4.3.1
- 172. http://www.columbia.edu/kermit/ckermit70.html#x4.3.2
- 173. http://www.columbia.edu/kermit/ckermit70.html#x4.3.3
- 174. http://www.columbia.edu/kermit/ckermit70.html#x4.3.4
- 175. http://www.columbia.edu/kermit/ckermit70.html#x4.4
- 176. http://www.columbia.edu/kermit/ckermit70.html#x4.4.1
- 177. http://www.columbia.edu/kermit/ckermit70.html#x4.4.1.1
- 178. http://www.columbia.edu/kermit/ckermit70.html#x4.4.1.2
- 179. http://www.columbia.edu/kermit/ckermit70.html#x4.4.2
- 180. http://www.columbia.edu/kermit/ckermit70.html#x4.4.2.1
- 181. http://www.columbia.edu/kermit/ckermit70.html#x4.4.2.1.1
- 182. http://www.columbia.edu/kermit/ckermit70.html#x4.4.2.1.2
- 183. http://www.columbia.edu/kermit/ckermit70.html#x4.4.2.2
- 184. http://www.columbia.edu/kermit/ckermit70.html#x4.5
- 185. http://www.columbia.edu/kermit/ckermit70.html#x4.5.1
- 186. http://www.columbia.edu/kermit/ckermit70.html#x4.5.2
- 187. http://www.columbia.edu/kermit/ckermit70.html#x4.5.2.1
- 188. http://www.columbia.edu/kermit/ckermit70.html#x4.5.2.2
- 189. http://www.columbia.edu/kermit/ckermit70.html#x4.5.3
- 190. http://www.columbia.edu/kermit/ckermit70.html#x4.5.4
- 191. http://www.columbia.edu/kermit/ckermit70.html#x4.6
- 192. http://www.columbia.edu/kermit/ckermit70.html#x4.7
- 193. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
- 194. http://www.columbia.edu/kermit/ckermit70.html#x4.7.2
- 195. http://www.columbia.edu/kermit/ckermit70.html#x4.7.3
- 196. http://www.columbia.edu/kermit/ckermit70.html#x4.8
- 197. http://www.columbia.edu/kermit/ckermit70.html#x4.8.1
- 198. http://www.columbia.edu/kermit/ckermit70.html#x4.8.2
- 199. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 200. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
- 201. http://www.columbia.edu/kermit/ckermit70.html#x4.9.2
- 202. http://www.columbia.edu/kermit/ckermit70.html#x4.9.3
- 203. http://www.columbia.edu/kermit/ckermit70.html#x4.10
- 204. http://www.columbia.edu/kermit/ckermit70.html#x4.11
- 205. http://www.columbia.edu/kermit/ckermit70.html#x4.11.1
- 206. http://www.columbia.edu/kermit/ckermit70.html#x4.11.2
- 207. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
- 208. http://www.columbia.edu/kermit/ckermit70.html#x4.11.4
- 209. http://www.columbia.edu/kermit/ckermit70.html#x4.11.5
- 210. http://www.columbia.edu/kermit/ckermit70.html#x4.11.6
- 211. http://www.columbia.edu/kermit/ckermit70.html#x4.12
- 212. http://www.columbia.edu/kermit/ckermit70.html#x4.13
- 213. http://www.columbia.edu/kermit/ckermit70.html#x4.14
- 214. http://www.columbia.edu/kermit/ckermit70.html#x4.15
- 215. http://www.columbia.edu/kermit/ckermit70.html#x4.16
- 216. http://www.columbia.edu/kermit/ckermit70.html#x4.17
- 217. http://www.columbia.edu/kermit/ckermit70.html#x4.17.1
- 218. http://www.columbia.edu/kermit/ckermit70.html#x4.17.2
- 219. http://www.columbia.edu/kermit/ckermit70.html#x4.18
- 220. http://www.columbia.edu/kermit/ckermit70.html#x4.19
- 221. http://www.columbia.edu/kermit/ckermit70.html#x4.20
- 222. http://www.columbia.edu/kermit/ckermit70.html#x4.20.1
- 223. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2
- 224. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.1
- 225. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.2
- 226. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.3
- 227. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.4
- 228. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.5
- 229. http://www.columbia.edu/kermit/ckermit70.html#x4.20.3
- 230. http://www.columbia.edu/kermit/ckermit70.html#x4.21
- 231. http://www.columbia.edu/kermit/ckermit70.html#x4.22
- 232. http://www.columbia.edu/kermit/ckermit70.html#x4.22.1
- 233. http://www.columbia.edu/kermit/ckermit70.html#x4.22.2
- 234. http://www.columbia.edu/kermit/ckermit70.html#x4.22.3
- 235. http://www.columbia.edu/kermit/ckermit70.html#x4.22.4
- 236. http://www.columbia.edu/kermit/ckermit70.html#x4.22.5
- 237. http://www.columbia.edu/kermit/ckermit70.html#x4.22.6
- 238. http://www.columbia.edu/kermit/ckermit70.html#x4.22.7
- 239. http://www.columbia.edu/kermit/ckermit70.html#x4.22.8
- 240. http://www.columbia.edu/kermit/ckermit70.html#x4.23
- 241. http://www.columbia.edu/kermit/ckermit70.html#x4.24
- 242. http://www.columbia.edu/kermit/ckermit70.html#x4.25
- 243. http://www.columbia.edu/kermit/ckermit70.html#x5
- 244. http://www.columbia.edu/kermit/ckermit70.html#x5.0
- 245. http://www.columbia.edu/kermit/ckermit70.html#x5.1
- 246. http://www.columbia.edu/kermit/ckermit70.html#x5.2
- 247. http://www.columbia.edu/kermit/ckermit70.html#x5.3
- 248. http://www.columbia.edu/kermit/ckermit70.html#x5.3.1
- 249. http://www.columbia.edu/kermit/ckermit70.html#x5.3.2
- 250. http://www.columbia.edu/kermit/ckermit70.html#x5.4
- 251. http://www.columbia.edu/kermit/ckermit70.html#x5.5
- 252. http://www.columbia.edu/kermit/ckermit70.html#x5.6
- 253. http://www.columbia.edu/kermit/ckermit70.html#x5.7
- 254. http://www.columbia.edu/kermit/ckermit70.html#x6
- 255. http://www.columbia.edu/kermit/ckermit70.html#x6.0
- 256. http://www.columbia.edu/kermit/ckermit70.html#x6.1
- 257. http://www.columbia.edu/kermit/ckermit70.html#x6.2
- 258. http://www.columbia.edu/kermit/ckermit70.html#x6.3
- 259. http://www.columbia.edu/kermit/ckermit70.html#x6.4
- 260. http://www.columbia.edu/kermit/ckermit70.html#x6.5
- 261. http://www.columbia.edu/kermit/ckermit70.html#x6.6
- 262. http://www.columbia.edu/kermit/ckermit70.html#x6.6.1
- 263. http://www.columbia.edu/kermit/ckermit70.html#x6.6.2
- 264. http://www.columbia.edu/kermit/ckermit70.html#x6.6.2
- 265. http://www.columbia.edu/kermit/ckermit70.html#x6.6.3
- 266. http://www.columbia.edu/kermit/ckermit70.html#x6.6.4
- 267. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5
- 268. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.1
- 269. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.2
- 270. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.3
- 271. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.4
- 272. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.5
- 273. http://www.columbia.edu/kermit/ckermit70.html#x6.7
- 274. http://www.columbia.edu/kermit/ckermit70.html#x7
- 275. http://www.columbia.edu/kermit/ckermit70.html#x7.0
- 276. http://www.columbia.edu/kermit/ckermit70.html#x7.1
- 277. http://www.columbia.edu/kermit/ckermit70.html#x7.1.1
- 278. http://www.columbia.edu/kermit/ckermit70.html#x7.1.2
- 279. http://www.columbia.edu/kermit/ckermit70.html#x7.1.3
- 280. http://www.columbia.edu/kermit/ckermit70.html#x7.1.4
- 281. http://www.columbia.edu/kermit/ckermit70.html#x7.2
- 282. http://www.columbia.edu/kermit/ckermit70.html#x7.3
- 283. http://www.columbia.edu/kermit/ckermit70.html#x7.4
- 284. http://www.columbia.edu/kermit/ckermit70.html#x7.5
- 285. http://www.columbia.edu/kermit/ckermit70.html#x7.6
- 286. http://www.columbia.edu/kermit/ckermit70.html#x7.7
- 287. http://www.columbia.edu/kermit/ckermit70.html#x7.8
- 288. http://www.columbia.edu/kermit/ckermit70.html#x7.9
- 289. http://www.columbia.edu/kermit/ckermit70.html#x7.9.1
- 290. http://www.columbia.edu/kermit/ckermit70.html#x7.9.2
- 291. http://www.columbia.edu/kermit/ckermit70.html#x7.10
- 292. http://www.columbia.edu/kermit/ckermit70.html#x7.10.1
- 293. http://www.columbia.edu/kermit/ckermit70.html#x7.10.2
- 294. http://www.columbia.edu/kermit/ckermit70.html#x7.10.3
- 295. http://www.columbia.edu/kermit/ckermit70.html#x7.10.4
- 296. http://www.columbia.edu/kermit/ckermit70.html#x7.10.5
- 297. http://www.columbia.edu/kermit/ckermit70.html#x7.10.6
- 298. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
- 299. http://www.columbia.edu/kermit/ckermit70.html#x7.10.8
- 300. http://www.columbia.edu/kermit/ckermit70.html#x7.10.9
- 301. http://www.columbia.edu/kermit/ckermit70.html#x7.10.10
- 302. http://www.columbia.edu/kermit/ckermit70.html#x7.11
- 303. http://www.columbia.edu/kermit/ckermit70.html#x7.12
- 304. http://www.columbia.edu/kermit/ckermit70.html#x7.13
- 305. http://www.columbia.edu/kermit/ckermit70.html#x7.14
- 306. http://www.columbia.edu/kermit/ckermit70.html#x7.15
- 307. http://www.columbia.edu/kermit/ckermit70.html#x7.16
- 308. http://www.columbia.edu/kermit/ckermit70.html#x7.17
- 309. http://www.columbia.edu/kermit/ckermit70.html#x7.18
- 310. http://www.columbia.edu/kermit/ckermit70.html#x7.19
- 311. http://www.columbia.edu/kermit/ckermit70.html#x7.20
- 312. http://www.columbia.edu/kermit/ckermit70.html#x7.20.1
- 313. http://www.columbia.edu/kermit/ckermit70.html#x7.20.2
- 314. http://www.columbia.edu/kermit/ckermit70.html#x7.21
- 315. http://www.columbia.edu/kermit/ckermit70.html#x7.22
- 316. http://www.columbia.edu/kermit/ckermit70.html#x7.23
- 317. http://www.columbia.edu/kermit/ckermit70.html#x7.24
- 318. http://www.columbia.edu/kermit/ckermit70.html#x7.25
- 319. http://www.columbia.edu/kermit/ckermit70.html#x7.26
- 320. http://www.columbia.edu/kermit/ckermit70.html#x7.26.1
- 321. http://www.columbia.edu/kermit/ckermit70.html#x7.26.2
- 322. http://www.columbia.edu/kermit/ckermit70.html#x7.27
- 323. http://www.columbia.edu/kermit/ckermit70.html#x8
- 324. http://www.columbia.edu/kermit/ckermit70.html#x9
- 325. http://www.columbia.edu/kermit/ckermit70.html#x9.0
- 326. http://www.columbia.edu/kermit/ckermit70.html#x9.1
- 327. http://www.columbia.edu/kermit/ckermit70.html#x9.2
- 328. http://www.columbia.edu/kermit/ckermit70.html#x9.3
- 329. http://www.columbia.edu/kermit/ckermit70.html#x10
- 330. http://www.columbia.edu/kermit/ckermit70.html#xiii
- 331. http://www.columbia.edu/kermit/ckermit70.html#xiii.1
- 332. http://www.columbia.edu/kermit/ckermit70.html#xiii.1.1
- 333. http://www.columbia.edu/kermit/ckermit70.html#xiii.1.2
- 334. http://www.columbia.edu/kermit/ckermit70.html#xiii.1.2.1
- 335. http://www.columbia.edu/kermit/ckermit70.html#xiii.1.2.2
- 336. http://www.columbia.edu/kermit/ckermit70.html#xiii.1.2.3
- 337. http://www.columbia.edu/kermit/ckermit70.html#xiii.2
- 338. http://www.columbia.edu/kermit/ckermit70.html#xiv
- 339. http://www.columbia.edu/kermit/ckermit70.html#xv
- 340. http://www.columbia.edu/kermit/ckb2.htm
- 341. http://www.columbia.edu/kermit/ckbreviews.html
- 342. http://www.bhusa.com/
- 343. http://www.columbia.edu/kermit/manuals.html#ckde
- 344. http://www.columbia.edu/kermit/manuals.html#ktb
- 345. http://www.columbia.edu/kermit/news.html
- 346. news:comp.protocols.kermit.announce
- 347. news:comp.protocols.kermit.misc
- 348. http://www.columbia.edu/kermit/ckb2.htm
- 349. http://www.columbia.edu/kermit/ckermit70.html#x4
- 350. http://www.columbia.edu/kermit/ckermit70.html#x4.3
- 351. http://www.columbia.edu/kermit/ckermit70.html#x4.23
- 352. http://www.columbia.edu/kermit/ckermit70.html#x4.5.1
- 353. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 354. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
- 355. http://www.columbia.edu/kermit/ckermit70.html#x4.9.
- 356. http://www.columbia.edu/kermit/ckb2.htm
- 357. http://www.columbia.edu/kermit/ckermit70.html#x7.9.2
- 358. http://www.columbia.edu/kermit/ckermit70.html#x2.15
- 359. http://www.columbia.edu/kermit/ckermit70.html#x9.1
- 360. http://www.columbia.edu/kermit/ckermit70.html#x1.6
- 361. http://www.columbia.edu/kermit/ckermit70.html#x7.4
- 362. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
- 363. http://www.columbia.edu/kermit/ckermit70.html#mjd
- 364. http://www.columbia.edu/kermit/ckermit70.html#mjd
- 365. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 366. http://www.columbia.edu/kermit/ckb2.htm
- 367. http://www.columbia.edu/kermit/ckb2.htm
- 368. http://www.columbia.edu/kermit/ckermit70.html#x7.5
- 369. http://www.columbia.edu/kermit/ckermit70.html#x2.12
- 370. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 371. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
- 372. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5
- 373. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 374. http://www.columbia.edu/kermit/ckermit70.html#x7.18
- 375. http://www.columbia.edu/kermit/ckermit70.html#x7.4
- 376. http://www.columbia.edu/kermit/ckermit70.html#x1.15
- 377. http://www.columbia.edu/kermit/ckermit70.html#x4.3
- 378. http://www.columbia.edu/kermit/ckermit70.html#x7.3
- 379. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
- 380. http://www.columbia.edu/kermit/ckermit70.html#x7.1
- 381. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
- 382. ftp://kermit.columbia.edu/kermit/f/ckccfg.txt
- 383. ftp://kermit.columbia.edu/kermit/f/ckccfg.txt
- 384. http://www.columbia.edu/kermit/ckermit70.html#x1.22.4
- 385. http://www.columbia.edu/kermit/ckermit70.html#x1.22.5
- 386. http://www.columbia.edu/kermit/ckb2.htm
- 387. http://www.columbia.edu/kermit/ckermit70.html#x1.22.5
- 388. http://www.columbia.edu/kermit/ckermit70.html#x7.12
- 389. http://www.columbia.edu/kermit/ckermit70.html#x2.1.16
- 390. http://www.columbia.edu/kermit/ckermit70.html#x2.7
- 391. http://www.columbia.edu/kermit/ckermit70.html#x2.3.5
- 392. http://www.columbia.edu/kermit/ckermit70.html#x7.5
- 393. http://www.telefonica.es/cambiodenumeracion/
- 394. http://www.columbia.edu/kermit/ckermit70.html#x7.5
- 395. http://www.columbia.edu/kermit/ckb2.htm
- 396. http://www.columbia.edu/kermit/ckermit70.html#x2.2.2
- 397. http://www.columbia.edu/kermit/ckermit70.html#x2.1.11
- 398. http://www.columbia.edu/kermit/ckermit70.html#x2.1.13
- 399. http://www.columbia.edu/kermit/ckermit70.html#x2.1.12
- 400. http://www.columbia.edu/kermit/ckb2.htm
- 401. http://www.columbia.edu/kermit/ckermit70.html#x2.1.1
- 402. http://www.columbia.edu/kermit/ckb2.htm
- 403. http://www.columbia.edu/kermit/ckb2.htm
- 404. http://www.columbia.edu/kermit/ckermit70.html#x2.1.7
- 405. http://www.columbia.edu/kermit/ckermit70.html#x2.1.6
- 406. http://www.columbia.edu/kermit/ckb2.htm
- 407. ftp://kermit.columbia.edu/kermit/f/telnet.txt
- 408. http://www.columbia.edu/kermit/telnet.htm
- 409. ftp://kermit.columbia.edu/kermit/f/telnet.txt
- 410. http://www.columbia.edu/kermit/telnet.htm
- 411. ftp://ftp.isi.edu/in-notes/rfc1572.txt
- 412. ftp://ftp.isi.edu/in-notes/rfc779.txt
- 413. http://www.columbia.edu/kermit/ckb2.htm
- 414. http://www.columbia.edu/kermit/ckermit70.html#x2.10
- 415. http://www.columbia.edu/kermit/ckermit70.html#x2.8
- 416. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 417. http://www.columbia.edu/kermit/ckermit70.html#x4.20
- 418. http://www.psy.uq.oz.au/~ftp/Crypto/
- 419. http://www.columbia.edu/kermit/security.htm
- 420. http://srp.stanford.edu/srp/
- 421. http://www.columbia.edu/kermit/ckermit70.html#x2.7.1,
- 422. ftp://kermit.columbia.edu/kermit/f/ckccfg.txt
- 423. http://www.columbia.edu/kermit/security.htm
- 424. http://www.columbia.edu/kermit/ckb2.htm
- 425. http://www.columbia.edu/kermit/ckermit70.html#x2.7
- 426. http://www.columbia.edu/kermit/ckermit70.html#x2.0
- 427. ftp://kermit.columbia.edu/kermit/f/ckuins.txt
- 428. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt
- 429. ftp://kermit.columbia.edu/kermit/f/ckuins.txt
- 430. http://www.columbia.edu/kermit/iksd.html#x4.2
- 431. http://www.columbia.edu/kermit/iksd.html
- 432. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.1
- 433. ftp://ftp.isi.edu/in-notes/rfc1945.txt
- 434. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 435. http://www.columbia.edu/kermit/ckermit70.html#x3.2
- 436. http://www.columbia.edu/kermit/ckermit70.html#x3.2
- 437. http://www.columbia.edu/kermit/ckb2.htm
- 438. http://www.columbia.edu/kermit/ckb2.htm
- 439. http://www.columbia.edu/kermit/ckermit70.html#x5.4
- 440. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt
- 441. http://www.columbia.edu/kermit/ckermit70.html#x4.10
- 442. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
- 443. http://www.columbia.edu/kermit/ckermit70.html#x4.7.3
- 444. http://www.columbia.edu/kermit/ckermit70.html#x4.3
- 445. http://www.columbia.edu/kermit/ckermit70.html#x4.10
- 446. http://www.columbia.edu/kermit/ckermit70.html#x4.11
- 447. http://www.columbia.edu/kermit/ckermit70.html#x4.15
- 448. http://www.columbia.edu/kermit/ckermit70.html#x4.2.4
- 449. http://www.columbia.edu/kermit/ckermit70.html#x4.7
- 450. http://www.columbia.edu/kermit/ckermit70.html#x4.2.3
- 451. http://www.columbia.edu/kermit/ckermit70.html#x4.2.1.3
- 452. http://www.columbia.edu/kermit/ckb2.htm
- 453. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2
- 454. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 455. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.2
- 456. http://www.columbia.edu/kermit/ckermit70.html#x4.3
- 457. http://www.columbia.edu/kermit/ckermit70.html#x4.10
- 458. http://www.columbia.edu/kermit/ckermit70.html#x4.11
- 459. http://www.columbia.edu/kermit/ckermit70.html#x4.15
- 460. http://www.telstra.com.au/docs/PGP/
- 461. http://www.telstra.com.au/docs/PGP/pgpdoc2/pgpdoc2_17.html
- 462. http://www.columbia.edu/kermit/security.htm
- 463. http://www.columbia.edu/kermit/ckermit70.html#x2.7
- 464. http://www.columbia.edu/kermit/ckb2.htm
- 465. http://www.columbia.edu/kermit/ckermit70.html#x2.14
- 466. http://www.columbia.edu/kermit/ckermit70.html#x1.23
- 467. http://www.columbia.edu/kermit/ckermit70.html#x4.7
- 468. http://www.columbia.edu/kermit/ckb2.htm
- 469. http://www.columbia.edu/kermit/ckb2.htm
- 470. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 471. http://www.columbia.edu/kermit/ckb2.htm
- 472. http://www.columbia.edu/kermit/ckermit70.html#x1.5.4
- 473. http://www.columbia.edu/kermit/ckermit70.html#x4.3
- 474. http://www.columbia.edu/kermit/ckermit70.html#x1.5.5
- 475. http://www.columbia.edu/kermit/ckermit70.html#x7.5
- 476. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 477. http://www.columbia.edu/kermit/ckermit70.html#x1.5.4
- 478. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 479. http://www.columbia.edu/kermit/ckermit70.html#x1.5.4
- 480. http://www.columbia.edu/kermit/ckermit70.html#x1.5.5
- 481. http://www.columbia.edu/kermit/ckb2.htm
- 482. http://www.columbia.edu/kermit/ckb2.htm
- 483. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 484. http://www.columbia.edu/kermit/ckermit70.html#x1.6
- 485. http://www.columbia.edu/kermit/ckermit70.html#x7.10
- 486. http://www.columbia.edu/kermit/ckermit70.html#x7.10.11
- 487. http://www.columbia.edu/kermit/ckermit70.html#x1.6
- 488. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2
- 489. http://www.columbia.edu/kermit/ckermit70.html#x4.11
- 490. http://www.columbia.edu/kermit/ckermit70.html#x1.5.4
- 491. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
- 492. http://www.columbia.edu/kermit/ckermit70.html#x4.0.6
- 493. http://www.columbia.edu/kermit/ckermit70.html#x4.2
- 494. http://www.columbia.edu/kermit/ckermit70.html#x4.1
- 495. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
- 496. http://www.columbia.edu/kermit/ckb2.htm
- 497. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 498. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2
- 499. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
- 500. http://www.columbia.edu/kermit/ckermit70.html#x4.2
- 501. http://www.columbia.edu/kermit/ckermit70.html#x4.10
- 502. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2
- 503. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
- 504. http://www.columbia.edu/kermit/ckermit70.html#x4.2
- 505. http://www.columbia.edu/kermit/ckermit70.html#x4.10
- 506. http://www.columbia.edu/kermit/ckermit70.html#x1.11.5
- 507. http://www.columbia.edu/kermit/ckermit70.html#x4.0.6
- 508. http://www.columbia.edu/kermit/ckermit70.html#x4.11
- 509. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
- 510. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
- 511. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 512. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 513. http://www.columbia.edu/kermit/ckermit70.html#x4.5.1
- 514. http://www.columbia.edu/kermit/ckermit70.html#x7.10
- 515. http://www.columbia.edu/kermit/ckermit70.html#x7.10.5
- 516. http://www.columbia.edu/kermit/ckermit70.html#x7.10.3
- 517. http://www.columbia.edu/kermit/ckermit70.html#x7.10.5
- 518. http://www.columbia.edu/kermit/ckb2.htm
- 519. http://www.columbia.edu/kermit/ckermit70.html#x4.3
- 520. http://www.columbia.edu/kermit/ckermit70.html#x4.10
- 521. http://www.columbia.edu/kermit/ckermit70.html#x4.3
- 522. http://www.columbia.edu/kermit/ckermit70.html#x4.10
- 523. http://www.columbia.edu/kermit/ckermit70.html#x4.15
- 524. http://www.columbia.edu/kermit/ckermit70.html#x4.18
- 525. http://www.columbia.edu/kermit/ckermit70.html#x4.20
- 526. http://www.columbia.edu/kermit/ckermit70.html#x4.20
- 527. http://www.columbia.edu/kermit/ckermit70.html#x4.20
- 528. http://www.columbia.edu/kermit/ckermit70.html#x4.19
- 529. http://www.columbia.edu/kermit/ckermit70.html#x4.16
- 530. http://www.columbia.edu/kermit/ckermit70.html#x4.19
- 531. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.3
- 532. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 533. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.4
- 534. http://www.columbia.edu/kermit/ckermit70.html#x4.22.2
- 535. http://www.columbia.edu/kermit/ckermit70.html#x4.22.3
- 536. http://www.columbia.edu/kermit/ckb2.htm
- 537. http://www.columbia.edu/kermit/ckb2.htm
- 538. http://www.columbia.edu/kermit/ckermit70.html#x9.3
- 539. http://www.columbia.edu/kermit/ckermit70.html#x5.2.1
- 540. http://www.columbia.edu/kermit/ckermit70.html#x4.5.1
- 541. http://www.columbia.edu/kermit/ckermit70.html#x4.5.2
- 542. http://www.columbia.edu/kermit/ckermit70.html#x6.6
- 543. http://www.columbia.edu/kermit/ckermit70.html#xiii
- 544. http://www.columbia.edu/kermit/ckermit70.html#xiii
- 545. ftp://ftp.isi.edu/in-notes/rfc1489.txt
- 546. ftp://ftp.isi.edu/in-notes/rfc2319.txt
- 547. http://www.unicode.org/
- 548. http://www.columbia.edu/kermit/ckermit70.html#x6.6.2
- 549. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.1
- 550. ftp://ftp.isi.edu/in-notes/rfc2640.txt
- 551. http://www.columbia.edu/kermit/ckermit70.html#x6.6.2
- 552. http://www.columbia.edu/kermit/ckermit70.html#x6.0
- 553. http://www.columbia.edu/kermit/ckermit70.html#x6.5
- 554. http://www.columbia.edu/kermit/ckermit70.html#x6.4
- 555. http://www.columbia.edu/kermit/ckb2.htm
- 556. http://www.columbia.edu/kermit/ckermit70.html#x4.21
- 557. http://www.columbia.edu/kermit/ckermit70.html#x6.5
- 558. http://www.columbia.edu/kermit/ckermit70.html#x2.8
- 559. http://www.columbia.edu/kermit/ckermit70.html#x7.7
- 560. http://www.columbia.edu/kermit/ckermit70.html#x7.2
- 561. http://www.columbia.edu/kermit/ckermit70.html#x1.19
- 562. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 563. http://www.columbia.edu/kermit/ckermit70.html#x4.1
- 564. http://www.columbia.edu/kermit/ckermit70.html#x4.2
- 565. http://www.columbia.edu/kermit/ckermit70.html#x4.1
- 566. http://www.columbia.edu/kermit/ckermit70.html#x4.2
- 567. http://www.columbia.edu/kermit/ckermit70.html#x2.1.11
- 568. http://www.columbia.edu/kermit/ckermit70.html#x2.10
- 569. http://www.columbia.edu/kermit/ckermit70.html#ferrstring
- 570. http://www.columbia.edu/kermit/ckermit70.html#x4.2.5
- 571. http://www.columbia.edu/kermit/ckermit70.html#x2.1.10
- 572. http://www.columbia.edu/kermit/ckermit70.html#x9.1
- 573. http://www.columbia.edu/kermit/ckermit70.html#x7.23
- 574. http://www.columbia.edu/kermit/ckermit70.html#x7.23
- 575. http://www.columbia.edu/kermit/ckermit70.html#x1.22
- 576. http://www.columbia.edu/kermit/ckermit70.html#x1.6
- 577. http://www.columbia.edu/kermit/ckermit70.html#x7.23
- 578. http://www.columbia.edu/kermit/ckermit70.html#x7.24
- 579. http://www.columbia.edu/kermit/ckermit70.html#x7.24
- 580. http://www.columbia.edu/kermit/ckermit70.html#x4.2.3
- 581. http://www.columbia.edu/kermit/ck90.html
- 582. http://www.columbia.edu/kermit/ckermit70.html#x7.12
- 583. http://www.columbia.edu/kermit/ckermit70.html#x7.9
- 584. http://www.columbia.edu/kermit/ckb2.htm
- 585. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
- 586. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
- 587. http://www.columbia.edu/kermit/ckermit70.html#x7.5
- 588. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
- 589. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
- 590. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.4
- 591. http://www.columbia.edu/kermit/ckermit70.html#x4.2.5
- 592. http://www.columbia.edu/kermit/ckermit70.html#x7.8
- 593. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
- 594. http://www.columbia.edu/kermit/ckb2.htm
- 595. http://www.columbia.edu/kermit/ckermit70.html#x7.19
- 596. http://www.columbia.edu/kermit/ckermit70.html#x7.16
- 597. http://www.columbia.edu/kermit/ckermit70.html#x7.9.1
- 598. http://www.columbia.edu/kermit/ckermit70.html#x7.5
- 599. http://www.columbia.edu/kermit/ckermit70.html#x7.3
- 600. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
- 601. http://www.columbia.edu/kermit/ckermit70.html#x4.5.1
- 602. http://www.columbia.edu/kermit/ckermit70.html#x7.10
- 603. http://www.columbia.edu/kermit/ckermit70.html#x7.10.10
- 604. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 605. http://www.columbia.edu/kermit/ckermit70.html#x7.23
- 606. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
- 607. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
- 608. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
- 609. http://www.columbia.edu/kermit/ckermit70.html#x7.10.11
- 610. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 611. http://www.columbia.edu/kermit/ckermit70.html#x7.10.3
- 612. http://www.columbia.edu/kermit/ckermit70.html#x7.3
- 613. http://www.columbia.edu/kermit/ckermit70.html#x7.9.2
- 614. http://www.columbia.edu/kermit/ckb2.htm
- 615. http://www.columbia.edu/kermit/ckermit70.html#x4.17.2
- 616. http://www.columbia.edu/kermit/ckermit70.html#x1.22
- 617. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
- 618. http://www.columbia.edu/kermit/ckermit70.html#x1.22
- 619. http://www.columbia.edu/kermit/ckermit70.html#x4.3
- 620. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 621. http://www.columbia.edu/kermit/ckermit70.html#x1.22
- 622. http://www.columbia.edu/kermit/ckermit70.html#x1.6
- 623. http://www.columbia.edu/kermit/ckermit70.html#x7.5
- 624. http://www.columbia.edu/kermit/ckermit70.html#x7.5
- 625. http://www.columbia.edu/kermit/ckermit70.html#x7.19
- 626. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
- 627. http://www.columbia.edu/kermit/ckermit70.html#x9.3
- 628. http://www.columbia.edu/kermit/ckermit70.html#x7.5
- 629. http://www.columbia.edu/kermit/ckb2.htm
- 630. http://www.columbia.edu/kermit/ckermit80.html
- 631. http://www.columbia.edu/kermit/ckermit80.html#x9
- 632. http://www.columbia.edu/kermit/ckermit70.html#x7.4
- 633. http://www.columbia.edu/kermit/ckermit80.html
- 634. http://www.columbia.edu/kermit/ckermit80.html#x9
- 635. http://www.columbia.edu/kermit/ckermit70.html#x7.20.2
- 636. http://www.columbia.edu/kermit/ckermit70.html#x7.10.5
- 637. http://www.columbia.edu/kermit/ckermit70.html#x7.10.9
- 638. http://www.columbia.edu/kermit/ckermit70.html#x1.10
- 639. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 640. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
- 641. http://www.columbia.edu/kermit/iksd.html
- 642. http://www.columbia.edu/kermit/ckermit70.html#x7.19
- 643. http://www.columbia.edu/kermit/ckermit70.html#x4.10
- 644. http://www.columbia.edu/kermit/ckermit70.html#x4.11
- 645. http://www.columbia.edu/kermit/ckermit70.html#x4.3
- 646. http://www.columbia.edu/kermit/gkermit.html
- 647. http://www.columbia.edu/kermit/ckermit70.html#x4.20
- 648. http://www.columbia.edu/kermit/gkermit.html
- 649. http://www.columbia.edu/kermit/ckb2.htm
- 650. http://www.columbia.edu/kermit/ckermit70.html#x7.3
- 651. mailto:kermit@columbia.edu
- 652. http://www.columbia.edu/kermit/ckermit70.html#top
- 653. http://www.columbia.edu/kermit/ckermit.html
- 654. http://www.columbia.edu/kermit/index.html
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckermit80.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckermit80.txt
deleted file mode 100644
index 196b68b..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckermit80.txt
+++ /dev/null
@@ -1,10286 +0,0 @@
-
- [1]The Columbia Crown The Kermit Project | Columbia University
- 612 West 115th Street, New York NY 10025 USA o [2]kermit@columbia.edu
- ...since 1981
- [3]Home [4]Kermit 95 [5]C-Kermit [6]Scripts [7]Current [8]New [9]FAQ
- [10]Support
-
-C-Kermit 8.0 Update Notes
-
- [ [11]Contents ] [ [12]C-Kermit ] [ [13]Kermit Home ]
-
-Second Supplement to [14]Using C-Kermit, 2nd Edition
-
-For C-Kermit 8.0
-
- As of C-Kermit version: 8.0.211
- Date of C-Kermit release: 10 April 2003
- This file last updated: Mon Sep 13 08:52:36 2010
-
- * IF YOU ARE READING A PLAIN-TEXT version of this document, note that
- it is a plain-text dump of a Web page. You can visit the original
- (and possibly more up-to-date) Web page here:
- [15]http://www.columbia.edu/kermit/ckermit80.html
-
- * If you are reading the HTML version of this file with a GUI Web
- browser, the features added since C-Kermit 8.0.201 are shown in red
- if your browser and monitor permit. Features that were new to
- versions 8.0.200 and 201 are in black.
-
-Authors: Frank da Cruz and Christine M. Gianone
-Address: The Kermit Project
- Columbia University
- 612 West 115th Street
- New York NY 10025-7799
- USA
-Fax: +1 (212) 662-6442
-E-Mail: [16]kermit-support@columbia.edu
-Web: [17]http://www.columbia.edu/kermit/
-Or: [18]http://www.kermit-project.org/
-Or: [19]http://www.columbia.nyc.ny.us/kermit/
-
-NOTICES
-
- This document:
- Copyright � 1997, 2002, Frank da Cruz and Christine M. Gianone.
- All rights reserved.
-
- Kermit 95:
- Copyright � 1995, 2002, Trustees of Columbia University in the
- City of New York. All rights reserved.
-
- C-Kermit:
- Copyright � 1985, 2002,
- Trustees of Columbia University in the City of New York. All
- rights reserved. See the C-Kermit [20]COPYING.TXT file or the
- copyright text in the [21]ckcmai.c module for disclaimer and
- permissions.
-
- When Kerberos(TM) and/or SRP(TM) (Secure Remote Password) and/or
- SSL/TLS protocol are included:
- Portions Copyright � 1990, Massachusetts Institute of
- Technology.
- Portions Copyright � 1991, 1993 Regents of the University of
- California.
- Portions Copyright � 1991, 1992, 1993, 1994, 1995 by AT&T.
- Portions Copyright � 1997, Stanford University.
- Portions Copyright � 1995-1997, Eric Young <eay@cryptosoft.com>.
-
- For the full text of the third-party copyright notices, see
- [22]Appendix V.
-
-WHAT IS IN THIS FILE
-
- This file lists changes made to C-Kermit since version 7.0 was released
- in January 2000. Use this file as a supplement to:
-
- * The second edition of [23]Using C-Kermit; and:
- * The [24]C-Kermit 7.0 Update Notes. Also available in plain-text
- form as [25]ckermit70.txt.
-
- until the third edition of Using C-Kermit is published. We apologize
- for the scattered documentation and will consolidate it when we are
- able.
-
-ADDITIONAL FILES
-
- Several other files accompany this new Kermit release:
-
- [26]ckututor.html
- C-Kermit Tutorial (for Unix). Also distributed in Nroff form as
- [27]ckuker.nr, the Unix C-Kermit manual page.
-
- [28]security.htm
- Discussion of Kermit's new authentication and encryption
- features, updated for C-Kermit 8.0.
-
- [29]telnet.htm
- Detailed documentation of Kermit's Telnet client, updated for
- C-Kermit 8.0.
-
- [30]ftpscripts.html
- Tutorial: Writing FTP automation scripts
-
- [31]ckcbwr.html
- Platform-independent C-Kermit hints and tips. Also distributed
- in plain text form as [32]ckcbwr.txt
-
- [33]ckubwr.html
- Unix-specific C-Kermit hints and tips. Also distributed in plain
- text form as [34]ckubwr.txt.
-
- [35]ckvbwr.html
- VMS-specific C-Kermit hints and tips. Also distributed in plain
- text form as [36]ckvbwr.txt.
-
- [37]ckuins.html
- Unix C-Kermit installation instructions. Also distributed in
- plain text form as [38]ckuins.txt.
-
- [39]ckvins.html
- VMS C-Kermit installation instructions. Also distributed in
- plain text form as [40]ckvins.txt.
-
- [41]ckccfg.html
- Compile-time configuration options. Also distributed in plain
- text form as [42]ckccfg.txt.
-
- [43]ckcplm.html
- C-Kermit Program Logic Manual. Also distributed in plain text
- form as [44]ckcplm.txt.
-
- [45]iksd.html
- Internet Kermit Service Administrators Guide for Unix.
-
- [46]skermit.html
- C-Kermit as an SSH Subsystem (SFTP server replacement).
-
- [ [47]Top ] [ [48]C-Kermit ] [ [49]Kermit Home ]
-
-CONTENTS
-
- [50]0. WHAT'S NEW
- [51]1. FIXES SINCE VERSION 7.0.196
- [52]2. SSH AND HTTP
- [53]2.1. SSH Connections
- [54]2.2. HTTP Connections
- [55]2.2.1. HTTP Command Switches
- [56]2.2.2. HTTP Action Commands
- [57]2.2.3. HTTP Headers
- [58]2.2.4. Secure HTTP Connections
- [59]2.2.5. HTTP Variables
- [60]2.2.6. The HTTP Command-Line Personality
- [61]3. THE BUILT-IN FTP CLIENT
- [62]3.1. Making and Managing FTP Connections
- [63]3.1.1. Kermit Command-Line Options for FTP
- [64]3.1.2. The FTP Command-Line Personality
- [65]3.1.3. The FTP URL Interpreter
- [66]3.1.4. Interactive FTP Session Establishment
- [67]3.2. Making Secure FTP Connections
- [68]3.3. Setting FTP Preferences
- [69]3.4. Managing Directories and Files
- [70]3.5. Uploading Files With FTP
- [71]3.5.1. FTP PUT Switches
- [72]3.5.2. Update Mode
- [73]3.5.3. Recovery
- [74]3.6. Downloading Files With FTP
- [75]3.6.1. FTP GET Switches
- [76]3.6.2. Filename Collisions
- [77]3.6.3. Recovery
- [78]3.7. Translating Character Sets
- [79]3.7.1. Character Sets and Uploading
- [80]3.7.2. Character Sets and Downloading
- [81]3.8. FTP Command Shortcuts
- [82]3.9. Dual Sessions
- [83]3.10. Automating FTP Sessions
- [84]3.10.1. FTP-Specific Variables and Functions
- [85]3.10.2. Examples
- [86]3.10.3. Automating Secure FTP Connections
- [87]3.11. Advanced FTP Protocol Features [88]4. FILE SCANNING
- [89]5. FILE AND DIRECTORY NAMES CONTAINING SPACES
- [90]6. OTHER COMMAND PARSING IMPROVEMENTS
- [91]6.1. Grouping Macro Arguments
- [92]6.2. Directory and File Name Completion
- [93]6.3. Passing Arguments to Command Files
- [94]6.4. More-Prompting
- [95]6.5. Commas in Macro Definitions
- [96]6.6. Arrow Keys
- [97]7. NEW COMMANDS AND SWITCHES
- [98]8. SCRIPTING IMPROVEMENTS
- [99]8.1. Performance and Debugging
- [100]8.2. Using Macros as Numeric Variables
- [101]8.3. New IF Conditions
- [102]8.4. The ON_UNKNOWN_COMMAND and ON_CD Macros
- [103]8.5. The SHOW MACRO Command
- [104]8.6. Arrays
- [105]8.7. New or Improved Built-in Variables and Functions
- [106]8.8. The RETURN and END Commands
- [107]8.9. UNDEFINing Groups of Variables
- [108]8.10. The INPUT and MINPUT Commands
- [109]8.11. Learned Scripts
- [110]8.12. Pattern Matching
- [111]8.13. Dates and Times
- [112]8.14. Trapping Keyboard Interruption
- [113]9. S-EXPRESSIONS
- [114]9.1. What is an S-Expression?
- [115]9.2. Integer and Floating-Point-Arithmetic
- [116]9.3. How to Use S-Expressions
- [117]9.4. Summary of Built-in Constants and Operators
- [118]9.5. Variables
- [119]9.6. Assignments and Scope
- [120]9.7. Conditional Expressions
- [121]9.8. Extensibility
- [122]9.9. Examples
- [123]9.10. Differences from Algebraic Notation
- [124]9.11.Differences from Lisp
- [125]10. FILE TRANSFER
- [126]11. MODEMS AND DIALING
- [127]12. TERMINAL CONNECTION
- [128]13. CHARACTER SETS
- [129]14. DIALOUT FROM TELNET TERMINAL SERVERS
- [130]15. COPING WITH BROKEN KERMIT PARTNERS
- [131]16. NEW COMMAND-LINE OPTIONS
- [132]17. LOGS
-
- [ [133]Top ] [ [134]C-Kermit ] [ [135]Kermit Home ]
-
-0. WHAT'S NEW
-
- The Initialization and Customization Files
- C-Kermit 8.0 now supports specification of the initialization
- file name (path) in an environment variable, CKERMIT_INI. It
- also relies far less than before on the initialization for
- functioning. See [136]Section 5 of the Unix C-Kermit
- [137]installation instructions for details. As of version
- 8.0.201, C-Kermit also executes your customization file (if you
- have one) even if the initialization file was not found.
- Previously, the customization file was executed by a TAKE
- command in the initialization file (and it still is, if an
- initialization is found).
-
- Incompatible Changes
- As always, we do our best to avoid changes that break existing
- scripts. However, C-Kermit 8.0 does include a rather pervasive
- syntax change that might alter the behavior of scripts that
- depend on the previous behavior. As described in [138]Section 5,
- C-Kermit now accepts doublequotes in most contexts where you
- previously had to use braces to group multiple words into a
- single field, or to force inclusion of leading or trailing
- blanks. Most noticeably, in C-Kermit 7.0 and earlier:
-
- echo {this is a string}
-
- would print:
-
- this is a string
-
- whereas:
-
- echo "this is a string"
-
- printed:
-
- "this is a string"
-
- In C-Kermit 8.0, both print:
-
- this is a string
-
- To force the doublequotes to be treated as part of the string,
- use either of the following forms:
-
- echo {"this is a string"}
- echo ""this is a string""
-
- Similarly, to force braces to be treated as part of the string:
-
- echo "{this is a string}"
- echo {{this is a string}}
-
- Other incompatibilities:
-
- 1. Using the SET HOST command to make HTTP connections is no
- longer supported. Instead, use the new HTTP OPEN command,
- described in [139]Section 2.2.
-
- C-Kermit 7.1 Alpha.01 (8 December 2000)
-
- Its major new features are those listed in the [140]Table of
- Contents: the FTP client, file scanning, command parsing and
- scripting improvements, S-Expressions, and support for the
- Telnet Com Port Option, plus wider availability of the Kerberos,
- SSL/TLS, and SRP security options for secure Internet
- connections.
-
- C-Kermit 7.1.199 Alpha.02 (4 January 2001)
-
- + C-Kermit now accepts [141]FTP, TELNET, and IKSD URLs as its
- first command-line argument.
- + Character-set translation added to the FTP client for
- [142]filenames.
- + Optional [143]setting of date of incoming files by FTP [M]GET
- from the server date.
- + [144]FTP CHECK filename added to let FTP client check the
- existence of a file on the server.
- + [145]FTP GET /NAMELIST:filename added to get list of server
- filenames into a local file.
- + [146]FTP [M]PUT /SERVER-RENAME:template added to make server
- rename a file as indicated by the template after it has
- arrived completely.
- + FTP [M]GET /SERVER-RENAME:template added to make server rename
- a file as indicated by the template after it has been sent
- completely.
- + FTP [147]VDIRECTORY added for getting verbose directory
- listings from TOPS-20.
- + [148]FTP TYPE TENEX added for transferring 8-bit binary files
- with PDP-10s.
- + Added [149]automatic text/binary mode switching for FTP
- [M]GET, based on filename patterns (e.g. *.zip, *.gz, *.exe
- are binary; *.txt, *.c are text).
- + [150]SET SEND I-PACKETS OFF added for coping with Kermit
- servers that do not support I packets.
- + A new option was added to [151]\fword() and \fsplit() for
- parsing comma-separated lists that might contain empty
- elements.
- + Bug fixes including:
- o {} or "" could not be used as expected to represent the
- empty string.
- o ,- on a line by itself in a macro definition caused
- subsequent statements to be skipped.
- o FTP [M]GET didn't work right if path segments were
- included in the filespec.
- o FTP MGET, if interrupted, did not clear its file list.
- o Various problems with FTP PUT /AS-NAME that nobody
- noticed.
- o Some FTP messages and displays interfered with each
- other.
- o Parsing of YESTERDAY, TODAY, and TOMORROW in date-time
- fields was broken.
- o Automatic old-to-new dialing directory format conversion
- was broken on VMS.
- o Various source-code portability problems fixed.
- + Improvement of various HELP and SHOW messages.
-
- C-Kermit 7.1.199 Alpha.04 (1 April 2001)
-
- + Big changes:
- o Changed default modem type from NONE to GENERIC.
- o Generic dialing now sends no init string at all.
- o Changed default terminal bytesize from 7 to 8.
- + New features:
- o SET SESSION-LOG TIMESTAMPED-TEXT for timestamped session
- log.
- + New modem types:
- o Conexant modem family
- o Lucent VENUS chipset
- o PCTel V.90 chipset
- o Zoom V.90
- o Zoom V.92
- + FTP client:
- o FTP OPEN /PASSIVE and /ACTIVE switches added.
- o Now works with servers that that don't include path in
- NLST response.
- o Fixed SEND /RECURSIVE not to follow symlinks (UNIX).
- o SET FTP VERBOSE-MODE default is now OFF instead of ON.
- + Kermit protocol:
- o Fixed what I hope is the last "Receive window full"
- error.
- o SET PREFIXING or SET CONTROL PREFIX now automatically
- sets CLEARCHANNEL OFF.
- o Fixed incorrect report of number of files transferred at
- end of transfer.
- o Fixed SEND /RECURSIVE not to follow symlinks (UNIX).
- + UNIX:
- o HTTP and shadow passwords enabled for SCO 5.0.6.
- o Even with SET FILENAMES CONVERTED, spaces were still
- accepted in incoming filenames; now they are converted to
- underscores.
- o Added support for compile-time mktemp()/mkstemp()
- selection.
- + VMS:
- o Session-log format for scripted sessions fixed.
- + Scripting:
- o Fixed \frdir() not to follow symlinks (UNIX).
- o Fixed \fday() not to dump core for dates prior to 17 Mar
- 1858.
- + General:
- o "Closing blah..." message upon exit could not be
- suppressed.
- o Added /PAGE and /NOPAGE to DELETE switches.
- o Added GO response for DELETE /ASK (delete all the rest
- without asking).
- o Added GO response to "more?" prompt (for multi-page
- screen output).
- o Updated HELP texts.
-
- C-Kermit 7.1.199 Beta.01 (10 May 2001)
-
- + FTP client verbosity adjustments.
- + Bug with generic modem dialing pausing several secs fixed.
- + SET HOST /USER:, SET LOGIN USERID, etc, fixed when given no
- user ID.
- + A couple \v(dm_blah) dial modifier variables added.
- + "--version" command-line switch added.
- + Fixed NetBSD serial-port DTR handling.
- + Lots of syntax cleanups for Flexelint and gcc -Wall.
- + Fixed modem-type aliases to not take precedence over real
- names.
- + Fixed funny treatment of doublequotes by ECHO command.
- + Enabled SET SESSION-LOG for VMS and other non-UNIX platforms.
- + Fixed changing direction in command history buffer.
- + Fixed handling of IKSD URLs.
- + Made sure DELETE prints a message if it got any errors.
-
- C-Kermit 8.0.200 Beta.02 (28 June 2001)
-
- + Major version number increased from 7 to 8.
- + [152]SSH command.
- + More-consistent Kermit protocol defaults.
- + CONNECT idle timeout and action selection.
- + CONNECT status variable.
- + A way to allocate more space for filename lists.
- + Pseudoterminal handler fixed for late-model Linuxes.
- + Command-line option -dd for timestamped debug log.
- + Download directory now works for external protocols too.
- + GREP /COUNT:variable.
- + SET ATTRIBUTE RECORD-FORMAT { OFF, ON }.
- + Bug fixes.
-
- C-Kermit 8.0.200 Beta.03 (9 Sep 2001)
-
- + [153]HTTP 1.1 connections and scripting
- + [154]ON_CTRLC macro for trapping Ctrl-C in scripts
- + [155]Date-time parsing improvements, timezones, comparison,
- arithmetic
- + [156]Pattern-matching improvements
- + FTP improvements
- + SET EXIT HANGUP { ON, OFF }
- + SET FILE EOF { CTRL-Z, LENGTH }
- + ASK[Q] /TIMEOUT
- + Bug fixes
- + New platforms
-
- C-Kermit 8.0.200 Beta.04 (16 Nov 2001)
-
- + [157]New Unix man page
- + [158]New Unix installation instructions
- + SET TELOPT policies are now enforced on non-Telnet ports if
- the server begins Telnet negotiations.
- + SET TERMINAL IDLE-ACTION { TELNET-NOP, TELNET-AYT }.
- + UUCP lockfile creation race condition fixed.
- + Dialout, modem signals, hangup, hardware flow control, etc,
- tested extensively on many platforms, numerous problems fixed.
- + Improved hints when dialing fails.
- + SET STOP-BITS 2 can now be given without SET FLOW HARDWARE.
- + Major improvements in RFC 2217 Telnet Com-Port Control.
- + Improved ability to REDIAL a modem server port.
- + kermit -h now shows the command name in the usage usage
- string.
- + kermit -h now shows ALL command-line options.
- + kermit -s blah, where blah is a symlink, now works.
- + --noperms command-line option = SET ATTRIBUTE PERMISSIONS OFF.
- + HTTP and HTTPS URLs now supported on the command line.
- + An http command-line personality is now available.
- + Initialization file streamlined to load faster, anachronisms
- removed.
- + Updated NEWS, INTRO, HELP text, SHOW commands. In particular,
- see SHOW COMM, HELP SET LINE, HELP WAIT.
- + Date/time arithmetic routines converted from floating-point to
- integer arithmetic (internally) for greater accuracy and
- portability.
- + Quoted strings containing commas no longer break macro
- execution.
- + Dynamic Kermit file-transfer timeouts are now much more
- aggressive.
- + New "hot keys" to turn debug.log on/off during file transfer.
- + Improved hints when file transfer fails.
- + FTP CD orientation messages are now printed.
- + -R now accepted on the FTP command line to request Recursion.
- + -m allows Active or Passive mode to be chosen on the FTP
- command line.
- + -dd on the FTP command line creates a timestamped debug.log.
- + FTP command-line security options filled in.
- + Improved automatic text/binary mode switching for MGET.
- + Removed spurious error messages that sometimes occur during
- MGET.
- + DIRECTORY, GREP, TYPE, HEAD, and TAIL now have a /OUTPUT:file
- option.
- + TYPE /NUMBER adds line numbers.
- + CAT = TYPE /NOPAGE; MORE = TYPE /PAGE.
- + GETOK ?-help fixed.
- + \v(timestamp) (= "\v(ndate) \v(time)")
- + \v(hour) (hour of the day, 0-23)
- + \funix2dospath() converts a UNIX path (/) to a DOS one (\).
- + \fdos2unixpath() converts a DOS (Windows, OS/2) path to a UNIX
- one.
- + \fkeywordval() parses name=value pair, allows macro keyword
- parameters.
- + We now make every attempt to not write passwords to the
- debug.log.
- + New Certificate Authority certificates file, includes the
- Kermit Project at Columbia University so you can access our
- IKSD securely.
- + Secure targets improved and better documented in Unix
- makefile.
- + All Linux (libc and glibc) builds consolidated under "make
- linux".
- + HP-UX makefile targets now have consistent names.
- + New aix50 and aix51 targets added.
-
- C-Kermit 8.0.200 Final (12 Dec 2001)
-
- + Remote/local-mode confusion on some platforms introduced in
- Beta.04, fixed.
- + Many of the makefile targets adjusted, new ones added.
- + New "make install" target should please most people.
- + New command: SHOW IKSD.
- + FTP over TLS.
- + Last-minute touchups to text messages, HELP text, etc.
- + Enable modem-signal reading for SCO OSR5 and Unixware 7.
- + Special superfast TRANSMIT /BINARY /NOECHO /NOWAIT mode added.
- + Fixed PBX dialing in unmarked-area-code case.
- + Improved SHOW COMMUNICATIONS tells lockfile directory, typical
- dialout device name.
- + Some FTP OPEN command parsing problems fixed.
- + Some errors in date arithmetic fixed.
- + New command: SET TERMINAL AUTODOWNLOAD { ..., ERROR { STOP,
- CONTINUE } }
- + New command: HELP FIREWALL.
- + SET MODEM HANGUP-METHOD DTR added as synonym for RS232-SIGNAL
- + Support for secure URL protocols added: telnets:, ftps:,
- https:.
-
- C-Kermit 8.0.201 (8 Feb 2002)
-
- + Installability as an [159]SSH v2 Subsystem.
- + [160]SET LOCUS command.
- + [161]L-versions of CD, DIR, DELETE, MKDIR, etc, to force local
- execution.
- + [162]USER and ACCOUNT added as synonyms for FTP USER and FTP
- ACCOUNT.
- + [163]SHOW VARIABLES now accepts a list of variables.
- + Rudimentary support for [164]Caller ID when receiving phone
- calls.
- + Up/Down [165]Arrow-key navigation of command history buffer.
- + [166]Automatic execution of customization file if init file is
- missing.
-
- C-Kermit 8.0.206 Beta.01 (11 Oct 2002)
-
- New commands:
-
- o ORIENTATION lists location-related variables and their
- values.
- o KCD changes to special directories by their symbolic
- names ("kcd ?" for a list).
- o SET CD HOME path to specify home directory for CD and KCD
- commands.
- o CONTINUE given at top level is equivalent to END -- handy
- when PROMPT'ed out of a script, to continue the script.
-
- New switches or operands for existing commands:
-
- o GETOK /TIMEOUT
- o ASK, ASKQ, GETOK /QUIET (suppresses error message on
- timeout)
- o COPY /APPEND now allows concatenating multiple source
- files into one dest file.
- o SET TCP { HTTP-PROXY, SOCKS-SERVER } /USER, /PASSWORD.
- o DIRECTORY command now accepts multiple filespecs, e.g.
- "dir a b c".
-
- SET QUIET ON now also applies to:
-
- o SET HOST connection progress messages.
- o "Press the X or E key to cancel" file-transfer message.
- o REMOTE CD response.
- o REMOTE LOGIN response.
-
- Improvements and new features:
-
- o Numerous FTP client fixes and new features, listed below.
- o C-Kermit, when in remote mode at the end of a file
- transfer, now prints a one-line "where" message. Control
- with SET TRANSFER REPORT.
- o Unix makefile "install" target now creates an UNINSTALL
- script.
- o Improved operation and performance on RFC 2217 Telnet
- connections.
- o Improved CONNECT (interactive terminal connection)
- performance.
- o HELP text updated for many commands.
-
- New or fixed makefile targets:
-
- o Solaris 9 (several variations)
- o Concurrent PowerMAX
- o Mac OS X 10.2
- o FreeBSD 1.0
- o FreeBSD 4.6, 5.0
- o AIX 5.2, 5.3
-
- Bugs fixed (general):
-
- o Failure to run in VMS Batch fixed.
- o LDIRECTORY fixed to run Kermit's built-in DIRECTORY
- command rather than an external one.
- o Fixed Solaris and other SVORPOSIX builds to find out
- their full hostnames rather than just the "uname -n"
- name.
- o Fixed some problems matching strings that start with ".".
- o Fixed some problems matching pattern that contain {a,b,c}
- lists.
- o Fixed erroneous reporting of text-mode reception as
- binary when sender did not report the file size (cosmetic
- only).
- o Many problems with SWITCH statements fixed.
- o Fixed SET OPTIONS DIRECTORY /DOTFILES to work for server
- too.
- o Fixed DELETE to print an error message if the file was
- not found.
- o Fixed SET CONTROL UNPREFIX ALL and SET PREFIXING NONE to
- do the same thing.
- o Fixed bugs executing macros from within the ON_EXIT
- macro.
- o \fday() and \fnday() fixed for dates prior to 17 Nov
- 1858.
- o Serial speed-changing bug in Linux fixed.
- o "Unbalanced braces" script parsing errors when using
- \{number} fixed.
- o "if defined \v(name)" fixed to behave as described in the
- book.
- o Fixed Problems caused by LOCAL variables whose names are
- left substrings of macro names.
- o The INPUT command was fixed to honor the PARITY setting.
- o Fixed bug with COPY to existing file that is longer than
- source file.
- o REINPUT command failed to strip braces/quotes around its
- target string.
- o Network directory lookups didn't work for SSH
- connections.
- o REMOTE SET { FILE, TRANSFER } CHARACTER-SET fixed.
- o Closed some holes whereby an incompletely received file
- was not deleted when SET FILE INCOMPLETE is DISCARD, e.g.
- when the Kermit is hung up upon.
- o SET XFER CHARACTER-SET TRANSPARENT fixed to do the same
- as SET XFER TRANSLATION OFF.
- o SET HOST PTY (e.g. SSH) connection fixed to pass along
- window-size changes.
- o C-Kermit search path for TAKE files was accidentally
- disabled.
-
- FTP client bugs fixed:
-
- o Character set translation was broken on little-endian
- (e.g. PC) architectures.
- o FTP PUT /SERVER-RENAME:, /RENAME-TO:, /MOVE-TO: switches
- were sticky.
- o Make SET TRANSFER MODE MANUAL apply to FTP.
- o Make SET FILE INCOMPLETE { KEEP, DISCARD } apply to FTP.
- o FTP MGET /UPDATE handled equal times incorrectly.
- o FTP MGET /RECOVER fixed to ignore file dates, use only
- size.
- o FTP MGET /RECOVER sometimes downloaded files it didn't
- need to.
- o FTP downloads with TRANSFER DISPLAY BRIEF could give
- misleading error messages.
- o FTP MGET temp file not deleted if FTP DEBUG set to OFF
- after it was ON.
- o LOCUS not switched back when FTP connection is lost.
- o Set incoming file date even if it was not completely
- received.
- o FTP MGET sent SIZE and MDTM commands even when it didn't
- have to.
- o FTP MGET sent SIZE and MDTM commands even when it knew
- they wouldn't work.
- o FTP MGET failed if no files were selected for download.
- o FTP MGET a* b* c* would fail to get any c*'s if no b*'s
- existed.
- o Big problems canceling MGET with Ctrl-C.
- o Some extraneous LOCUS dialogs squelched.
- o Some inconsistencies in SET FTP FILENAMES AUTO fixed.
- o Fixed file-descriptor pileup after multiple MGETs when
- using mkstemp().
- o Fixed "mget foo", where foo is a directory name.
-
- FTP improvements:
-
- o New [167]FTP protocol features added (FEAT, MLSD).
- o FTP MGET /RECURSIVE now works as expected if server
- supports MLSD.
- o FTP MGET /DATES-DIFFER to download if local and remote
- file dates differ.
- o FTP DATES default changed to ON.
- o FTP MPUT, MGET /EXCEPT now allows up to 64 patterns (up
- from 8).
- o Top-level SITE and PASSIVE commands added for
- convenience.
- o MGET /COLLISION:APPEND /AS-NAME:newfile *.* puts all
- remote files into one local file.
- o SET FTP SERVER-TIME-OFFSET for when server has wrong
- timezone set.
- o Allow for alternative server interpretations of [M]MPUT
- /UNIQUE.
- o SET FTP ANONYMOUS-PASSWORD lets you specify the default
- anonymous password.
- o Allow "GET /RECURSIVE path/file" to force local
- subdirectory creation.
- o SET FTP DISPLAY is like SET TRANSFER DISPLAY but applies
- only to FTP.
- o FTP { ENABLE, DISABLE } new-protocol-feature-name.
- o FTP MGET /NODOTFILES.
- o Debug log now records FTP commands and responses in
- grep-able format.
-
- [ [168]Top ] [ [169]Contents ] [ [170]C-Kermit ] [ [171]Kermit Home ]
-
-1. FIXES SINCE VERSION 7.0.196 First, the changes from 7.0.196 to 7.0.197...
-Source and makefile tweaks to get successful builds on platforms that were
-not available in time for the 7.0 release:
-
- * 4.2BSD
- * 4.3BSD
- * AIX 4.3
- * AT&T 3B2 and 3B20
- * BeOS 4.5
- * CLIX
- * Interactive UNIX System V/386 R3.2 V4.1.1
- * OS-9/68000
- * OSF/1 1.3.
- * PS/2 AIX 1.2.1
- * SCO OSR5.0.x
- * SCO Xenix 2.3.4
- * SINIX 5.41/Intel
- * Stratus FTX
- * Stratus VOS
- * SunOS 4.1 with X.25
- * Ultrix 4.2
- * Unixware 2.0
-
- There were no functional changes from 196 to 197.
-
- Fixes applied after C-Kermit 7.0.197 was released:
-
- Source code: Big flexelint and "gcc -Wall" audit and cleanup.
-
- Configuration:
- * Solaris RTS/CTS (hardware flow control) didn't work.
- * BSDI RTS/CTS worked only in one direction.
- * FreeBSD 4.0 with ncurses 5.0 broke interactive command parsing.
- * QNX-32 build lacked -DBIGBUFOK so couldn't execute big macros.
-
- Connections:
- * SET HOST /PTY didn't work on some platforms.
- * Broken SET HOST /USER:xxx /PASSWORD:yyy /ACCOUNT:zzz switches
- fixed.
- * Transparent printing was broken in Unix.
- * ANSWER 0 (wait forever) didn't work.
- * Some problems in Multitech modem command strings.
- * Spurious "?Sorry, can't condition console terminal" errors.
- * Disabling modem command strings by setting them to nothing broke
- dialing.
- * SET DIAL TIMEOUT value was usually ignored.
- * SET DIAL METHOD PULSE didn't work.
- * Certain modem commands, if changed, not refreshed if modem type
- changed.
- * SET SESSION-LOG command was missing from VMS.
- * VMS session log format fixed for scripts.
- * HANGUP by dropping DTR didn't work in NetBSD.
- * SET FLOW /AUTO versus SET FLOW confusion fixed.
- * Spurious secondary Solaris lockfile removed.
- * SCO OSR5 DTR On/Off hangup.
- * UUCP lockfile race condition.
-
- Commands and scripts:
- * Missing CAUTIOUS and FAST commands restored.
- * Broken PTY command in late-model Linuxes fixed (API changed).
- * Fixed off-by-one error in command recall when switching direction.
- * Fixed recall of commands that contain '?'.
- * COPY /SWAP-BYTES didn't work on some architectures.
- * Various combinations of COPY switches didn't work.
- * Various problems with COPY or RENAME with a directory name as
- target.
- * SHIFT didn't decrement \v(argc) if used within IF, ELSE, or SWITCH
- block.
- * SHIFT didn't affect the \%* variable.
- * Divide by zero improperly handled in some \function()s.
- * Problems with RETURN from right-recursive functions.
- * FSEEK /LINE \%c LAST didn't work if already at end.
- * Some buffer vulnerabilities and potential memory leaks were
- discovered and fixed.
- * \frdirectory() fixed not to follow symbolic links.
- * SET EXIT WARNING OFF fixed to work when EXIT given in a script.
- * Missing DELETE and MKDIR error message fixed.
- * \fday() core dump for ancient dates fixed.
-
- File transfer:
- * SEND /COMMAND was broken.
- * CRECEIVE was broken (but RECEIVE /COMMAND was OK).
- * Quoting wildcard chars in filenames didn't work.
- * Problems canceling streaming file transfers with X or Z.
- * Problems shifting between streaming and windowing file transfer.
- * Non-FULL file-transfer displays erroneously said STREAMING when
- not.
- * An active SEND-LIST prevented GET from working.
- * SET SERVER GET-PATH interpretation of relative names like "." was
- wrong.
- * The MAIL command was broken.
- * "kermit -s *" might have skipped some files.
- * Transaction log entries were not made for external protocol
- transfers.
- * File count report fixed to show number of files actually
- transferred.
- * Fixed filename conversion to convert spaces to underscores.
- * Made SET PREFIXING / SET CONTROL PREFIX also adjust CLEARCHANNEL.
- * More "Receive window full" errors fixed.
- * Broken terminal buffering after curses display in Solaris fixed.
- * SET FILE INCOMPLETE DISCARD did not work in all cases.
- * Packet log changed to reformat the start-of-packet character
- printably.
- * Dynamic timeouts could grow ridiculously large.
-
- Character sets:
- * Hebrew-7 translations missed the letter Tav.
- * C1 area of CP1252 was ignored.
- * SET TRANSFER CHARACTER-SET TRANSPARENT could give garbage
- translations.
- * TRANSLATE might not work on Little Endian architectures.
- * Insufficient range checking in certain TRANSLATE operations.
-
- The following bugs in C-Kermit 8.0.200 were fixed in 8.0.201:
-
- * An obscure path through the code could cause the Unix version of
- C-Kermit to dump core during its startup sequence. This happened to
- only one person, but now it's fixed.
- * When C-Kermit 8.0 is in Kermit server mode and the client says "get
- blah", where blah (on the server) is a symlink rather than a real
- file, the server unreasonably refused to send the linked-to file.
- * When C-Kermit is an FTP client and says "get foo/bar" (i.e. a
- filename that includes one or more path segments), it failed to
- accept the incoming file (this happened only with GET, not MGET).
- * Array references should be case insensitive but only lowercase
- array letters were accepted.
- * SHOW VARIABLES dumped core on \v(sexpression) and \v(svalue).
- * Spurious refusals of remote directory listings if the remote
- server's date was set in the past.
- * In AIX, and maybe elsewhere too, Kermit's COPY command always
- failed with "Source and destination are the same file" when the
- destination file didn't exist.
- * The VMS version of C-Kermit did not work in Batch or when SPAWN'd.
- To compound the problem, it also pretty much ignored the -B and -z
- command-line options, whose purpose is to work around such
- problems.
- * C-Kermit 8.0 could not be built on IRIX 5.x.
- * The C-Kermit 8.0 build for QNX6 said it was an "(unknown version)".
-
- Other fixes are listed in the [172]previous section.
-
- [ [173]Top ] [ [174]Contents ] [ [175]C-Kermit ] [ [176]Kermit Home ]
-
-2. SSH AND HTTP
-
-2.1. SSH Connections
-
- This section does not apply to [177]Kermit 95 2.0, which has its own
- built-in SSH client, which is documented [178]SEPARATELY.
-
- On most UNIX platforms, C-Kermit can make SSH (Secure SHell) connection
- by running the external SSH command or program through its
- pseudoterminal interface. The command is:
-
- SSH text
- Tells Kermit to start the external SSH client, passing the given
- text to it on the command line. Normally the text is just the
- hostname, but it can be anything else that is acceptable to the
- ssh client. If the command succeeds, the connection is made and
- Kermit automatically enters CONNECT (terminal) mode. You can use
- the SSH command to make a connection to any host that has an SSH
- server.
-
- Kermit's SSH command gives you all the features of Kermit on an SSH
- connection: command language, file transfer, character-set translation,
- scripting, and all the rest. By default, C-Kermit invokes SSH with "-e
- none", which disables the ssh escape character and makes the connection
- transparent for purposes of file transfer. You can, however, change the
- SSH invocation to whatever else you might need (an explicit path,
- additional command-line arguments, etc) with:
-
- SET SSH COMMAND text
- Specifies the system command that Kermit's SSH command should
- use to invoke the external SSH client. Use this command to
- supply a specific path or alternative name, or to include
- different or more command-line options.
-
- In most cases, these connections work quite well. They can be scripted
- like any other connection, and file transfer goes as fast as, or faster
- than, on a regular Telnet connection. In some cases, however, the
- underlying pseudoterminal driver is a limiting factor, resulting in
- slow or failed file transfers. Sometimes you can work around such
- problems by reducing the Kermit packet length. Note that Kermit does
- not consider SSH connections to be reliable, so it does not offer to
- use streaming in Kermit protocol transfers (but you can force it with
- SET RELIABLE or SET STREAMING if you wish).
-
- The SSH command is like the TELNET command: it enters CONNECT mode
- automatically when the connection is made. Therefore, to script an SSH
- connection, use:
-
- set host /pty ssh -e none [ other-options ] host
- if fail ...
-
- to make the connection.
-
- Here's a sequence that can be used to make a connection to a given host
- using Telnet if the host accepts it, otherwise SSH:
-
- if not defined \%1 exit 1 Usage: \%0 host
- set quiet on
- set host \%1 23 /telnet
- if fail {
- set host /pty ssh -l \m(user) -e none \%1
- if fail exit 1 \%1: Telnet and SSH both fail
- echo SSH connection to \%1 successful
- } else {
- echo Telnet connection to \%1 successful
- }
-
- In SSH v2, it is possible to make an SSH connection direct to a Kermit
- server system if the host administrator has configured the SSH server
- to allow this; [179]CLICK HERE for details.
-
- Since Kermit uses external ssh client software, and since there are
- different ssh clients (and different releases of each one), the exact
- command to be used to make an SSH/Kermit connection can vary. Here is
- the command for the OpenSSH 3.0.2p1 client:
-
-set host /pipe ssh -e none [ -l username ] -T -s hostname kermit
-
- Example:
-
-set host /pipe ssh -e none -l olga -T -s hq.xyzcorp.com kermit
-
- The SSH client might or might not prompt you for a password or other
- information before it makes the connection; this depends on your SSH
- configuration (your public and private keys, your authorized hosts
- file, etc). Here's a brief synopsis of the OpenSSH client command
- syntax ("man ssh" for details):
-
- -e none
- This tells the SSH client to use no escape character. Since we
- will be transferring files across the connection, we don't want
- the connection to suddenly block because some character in the
- data.
-
- -l username
- This is the username on the remote host. You can omit the -l
- option and its argument if your local and remote usernames are
- the same. If they are different, you must supply the remote
- username.
-
- -T
- This tells the SSH client to tell the SSH server not to allocate
- a pseudoterminal. We are not making a terminal connection, we
- don't need a terminal, and in fact if a terminal were allocated
- on the remote end, the connection would not work.
-
- -s ... kermit
- This tells the SSH client to tell the SSH server to start the
- specified subsystem ("kermit") once the connection is made. The
- subsystem name comes after the hostname.
-
- hostname
- The IP host name or address of the desired host.
-
- You might want to include other or additional ssh command-line options;
- "man ssh" explains what they are. Here are some examples for the
- OpenSSH 3.0.2p1 client:
-
- -oClearAllForwardings yes
- -oForwardAgent no
- -oForwardX11 no
- -oFallbackToRsh no
- These ensure that a secure connection is used and that the
- connection used for file transfer is not also used for
- forwarding other things that might be specified in the
- ssh_config file.
-
- -oProtocol 2
- (i.e. SSH v2) Ensures that the negotiated protocol supports
- subsystems.
-
- Once you have an SSH connection to a Kermit server, it's just like any
- other connection to a Kermit server (and very similar to a connection
- to an FTP server). You give the client file transfer and management
- commands for the server, and the server executes them. Of course you
- can also give the client any other commands you wish.
-
- [ [180]SSH Kermit Server Subsystem ] [ [181]Kermit 95 Built-in SSH
- Client ]
-
-2.2. HTTP Connections
-
- Hypertext Transfer Protocol, or HTTP, is the application protocol of
- the World Wide Web (WWW), used between Web browsers (clients) and Web
- servers. It allows a client to get files from websites, upload files to
- websites, delete files from websites, get information about website
- directories and files, and interact with server-side CGI scripts.
- C-Kermit includes an HTTP client capable of both clear-text and secure
- HTTP connections, that can do all these tasks and can be automated
- through the Kermit scripting language.
-
- Although C-Kermit 7.0 could make HTTP connections to Web servers, it
- could do so only when no other connection was open, and the procedure
- was somewhat awkward. C-Kermit 8.0 improves matters by:
-
- * Allowing an HTTP connection to be open at the same time as a
- regular SET LINE or SET HOST connection, and also at the same time
- as an FTP connection ([182]Section 3);
- * Upgrading the HTTP protocol level from 1.0 to 1.1, thus allowing
- for persistent connections, in which a series of commands can be
- sent on the same connection, rather than only one as in HTTP 1.0
- (and C-Kermit 7.0);
- * Providing for "one-shot" URL-driven HTTP operations such as GET or
- PUT.
- * Providing a distinct HTTP command-line personality.
-
- Persistent HTTP connections are managed with the following commands:
-
- HTTP [ switches ] OPEN [ security-options ] host-or-url [ port ]
- Opens a persistent connection to the specified host (IP host
- name or address) on the specified port. If any switches
- (options, listed in the next section) are included, their values
- are saved and used for all subsequent HTTP action commands on
- the same connection. If no port is specified, HTTP (80) is used.
- A Uniform Resource Locator (URL, [183]RFC 1738) can be given
- instead of a hostname (or address) and port (but the URL can not
- include a directory/file path). The security options are
- explained [184]below. The HTTP OPEN command replaces the
- C-Kermit 7.0 SET HOST hostname HTTP command, which no longer
- works with HTTP GET and related commands.
-
- HTTP CLOSE
- Closes any open HTTP connection and clears any saved switch
- values.
-
- A URL starts with a protocol name, which must be http or https in this
- case; optionally includes a username and password; and must contain a
- host name or address:
-
- protocol://[user[.password]]@host[:port][URI]
-
- HTTP is Hypertext Transfer Protocol. HTTPS is the secure (SSL/TLS)
- version of HTTP. The TCP service port is derived from the protocol
- prefix (so normally the ":port" field is omitted). Thus the URL
- protocol name specifies a default TCP service port and the URL user and
- password fields can take the place of the /USER and /PASSWORD switches
- ([185]Section 2.2.1). The optional URI is a "compact string of
- characters for identifying an abstract or physical resource" ([186]RFC
- 2396), such as a file. It must begin with a slash (/); if the URI is
- omitted, "/" is supplied. Examples:
-
- http open http://www.columbia.edu/
- Equivalent to http open www.columbia.edu or http open
- www.columbia.edu http.
-
- http open https://olga.secret@www1.xyzcorp.com/
- Equivalent to http /user:olga /pass:secret open www1.xyzcorp.com
- https.
-
- Persistence is accomplished unilaterally by C-Kermit 8.0. An HTTP 1.0
- server closes the connection after each action. Although HTTP 1.1
- allows multiple actions on the same connection, an HTTP 1.1 server
- tends to close the connection if it is idle for more than a few
- seconds, to defend itself against denial-of-service attacks. But when
- you use Kermit's HTTP OPEN command to create a connection, Kermit
- reopens it automatically (if necessary) for each HTTP action until you
- close it with HTTP CLOSE, regardless of the server's HTTP protocol
- version, or how many times it closes the connection.
-
- Firewalls can be negotiated through proxies with the following
- commands:
-
- SET TCP HTTP-PROXY [ host[:port] ]
- If a host (by hostname or IP address) is specified, Kermit uses
- it as a proxy server when attempting outgoing TCP connections --
- not only HTTP connections, but all TCP/IP connections, Telnet
- and FTP included. This allows Kermit to adapt to the HTTP
- firewall penetration method (as opposed to other methods such as
- SOCKS4). If no hostname or ip-address is specified, any
- previously specified Proxy server is removed. If no port number
- is specified, the "http" service is used. This command must be
- given before the HTTP OPEN command if a proxy is to be used or
- canceled.
-
- HTTP [ switches ] CONNECT host[:port]
- Instructs the HTTP server to act as a proxy, establishing a
- connection to the specified host (IP hostname or address) on the
- given port (80 = HTTP by default) and to redirect all data
- transmitted between Kermit and itself to the given host for the
- life of the connection. This command is to be used only for
- debugging HTTP proxy connections. If a proxy connection is
- required, instruct Kermit to use the proxy with the SET TCP
- HTTP-PROXY command.
-
-2.2.1. HTTP Command Switches
-
- HTTP switches, like all other switches, are optional. When HTTP
- switches are included with the HTTP OPEN command, they apply
- automatically to this and all subsequent HTTP actions (GET, PUT, ...)
- on the same connection until an HTTP CLOSE command is given. So if you
- include switches (or the equivalent URL fields, such as user and
- password) in the HTTP OPEN command, you can omit them from subsequent
- commands on the same connection. If the connection has closed since
- your last command, it is automatically reopened with the same options.
-
- If you include switches with an HTTP action command (such as GET or
- PUT), they apply only to that command.
-
- /USER:name
- To be used in case a page requires a username for access. The
- username is sent with page requests. If it is given with the
- OPEN command it is saved until needed. If a username is included
- in a URL, it overrides the username given in the switch.
- CAUTION: Username and password (and all other information,
- including credit card numbers and other material that you might
- prefer to protect from public view) are sent across the network
- in clear text on regular HTTP connections, but authentication is
- performed securely on HTTPS connections.
-
- /PASSWORD:text
- To be used in case a web page requires a password for access.
- The password is sent with page requests. If it is given with the
- OPEN command it is saved until needed. If a password is given in
- a URL, it overrides the one given here. CAUTION: (same as for
- /USER:).
-
- /AGENT:user-agent
- Identifies the client to the server. Overrides the default agent
- string, which is "C-Kermit" (for C-Kermit) or "Kermit-95" (for
- Kermit 95).
-
- /ARRAY:array-designator
- Tells Kermit to store the response headers in the given array,
- one line per element. The array need not be declared in advance.
- Example: /array:&a.
-
- /TOSCREEN
- Tells Kermit to display any response text on the screen. It
- applies independently of the output file specification; thus it
- is possible to have the server response go to the screen, a
- file, both, or neither.
-
- /HEADER:header-item(s)
- Used for specifying any optional headers to be sent with HTTP
- requests.
-
- /HEADER:tag:value
-
- To send more than one header, use braces for grouping:
-
- /HEADER:{{tag:value}{tag:value}...}
-
- For a list of valid tags and value formats see [187]RFC 2616,
- "Hypertext Transfer Protocol -- HTTP/1.1". A maximum of eight
- headers may be specified.
-
-2.2.2. HTTP Action Commands
-
- HTTP actions can occur within a persistent connection, or they can be
- self-contained ("connectionless"). A persistent HTTP connection begins
- with an HTTP OPEN command, followed by zero or more HTTP action
- commands, and is terminated with an HTTP CLOSE command:
-
- http open www.columbia.edu
- if failure stop 1 HTTP OPEN failed: \v(http_message)
- http get kermit/index.html
- if failure stop 1 HTTP GET failed: \v(http_message)
- (more actions possible here...)
- http close
-
- A self-contained HTTP action occurs when a URL is given instead of a
- remote file name to an HTTP action command. In this case, Kermit makes
- the HTTP connection, takes the action, and then closes the connection.
- If an HTTP connection was already open, it is closed silently and
- automatically.
-
- http get http://www.columbia.edu/kermit/index.html
-
- Kermit's HTTP action commands are as follows. Switches may be included
- with any of these to override switch (or default) values given in the
- HTTP OPEN command.
-
- HTTP [ switches ] GET remote-filename [ local-filename ]
- Retrieves the named file from the server specified in the most
- recent HTTP OPEN command for which a corresponding HTTP CLOSE
- command has not been given. The filename may not include
- wildcards (HTTP protocol does not support them). If no HTTP OPEN
- command is in effect, this form of the HTTP GET command fails.
- The default local filename is the same as the remote name, but
- with any pathname stripped. For example, the command http get
- kermit/index.html stores the file in the current local directory
- as index.html. If the /HEADERS: switch is included, information
- about the file is also stored in the specified array (explained
- in [188]Section 2.2.3). All files are transferred in binary
- mode. HTTP does not provide for record-format or character-set
- conversion.
-
- HTTP [ switches ] GET url [ local-filename ]
- When HTTP GET is given a URL rather than a filename, Kermit
- opens a connection to the designated server (closing any
- previously open HTTP connection), gets the file, and then closes
- the connection. If the URL does not include a filename,
- index.html is supplied. This is the self-contained one-step
- "connectionless" method for getting a file from a Web server.
- The data is not interpreted; HTTP GET is like "lynx -source"
- rather than "lynx -dump".
-
- In the remaining HTTP action commands, the distinction between a remote
- filename and a URL are the same as in the HTTP GET command.
-
- HTTP [ switches ] HEAD remote-filename-or-url [ local-filename ]
- Like GET except without actually getting the file; instead it
- retrieves only the headers. If the /ARRAY: or /TOSCREEN switch
- is included, there is no default local output filename but you
- can still specify one. If neither of these switches is included,
- the default local filename is the same as the remote filename,
- but with any path stripped and with ".head" appended. The HEAD
- command can be used in a script with the /ARRAY: switch to
- retrieve information about the requested resource to determine
- whether the resource should actually be retrieved with a
- subsequent GET request.
-
- HTTP [ switches ] INDEX remote-directory-or-url [ local-filename ]
- Asks the server to send a listing of the files in the given
- server directory. This command is not supported by most Web
- servers. Even when it is supported, there is no standard format
- for the listing.
-
- HTTP [ switches ] POST [ /MIME-TYPE:type ] source-file
- remote-path-or-url [ result-file ]
- Sends data to a process running on the remote host; the result
- is usually an HTML file but could be anything. The data to be
- posted must be read from a local file (the source-file). If a
- result file is specified, Kermit stores the server's response in
- it.
-
- HTTP [ switches ] PUT [ MIME-TYPE:type ] local-file [
- remote-file-or-url [ result-file ] ]
- Uploads a local file to the server. Only the name of a single
- file can be given; wildcards (and group transfers) are not
- supported by HTTP protocol. If no remote filename is given, the
- file is sent with the same name as the local file, but with any
- pathname stripped.
-
- HTTP [ switches ] DELETE remote-file-or-url [ local-result-file ]
- Asks the server to delete the specified single file. If a result
- file is specified, it will contain any response data returned by
- the server.
-
- Note the limitations of HTTP protocol compared to (say) FTP or Kermit.
- There is no command for changing directories, no standard way to get
- file or directory lists, no way to transfer file groups by using
- wildcard notation, etc, and therefore no good way to (say) fetch all
- pages, descend through subdirectories, perform automatic updates, etc.
- There is no assurance a connection will stay open and, as noted, there
- is no provision for data conversion between unlike platforms. The
- data's MIME headers can be used for postprocessing.
-
-2.2.3. HTTP Headers
-
- Each HTTP request and response contains a set of name/value pairs
- called headers. HTTP headers are specified in [189]RFC 2616. For
- example, an HTTP GET request for /index.html on www.columbia.edu
- contains the following headers:
-
- GET /index.html HTTP/1.1
- Host: www.columbia.edu:80
- User-agent: C-Kermit 8.0
- Authorization: Basic base64-encoded-username-password
-
- These might be followed by any others specified with a /HEADERS:
- switch:
-
- Accept: image/gif, image/x-xbitmap, image/jpeg, *.*
- Accept-Encoding: gzip
- Accept-Language: en
- Accept-Charset: iso-8859-1,utf-8
- Cookie: cookie-data
-
- The server sends back a short report about the file prior to sending
- the file contents. Example:
-
- HTTP/1.1 200 OK
- Date: Fri, 24 Aug 2001 21:09:39 GMT
- Server: Apache/1.3.4 (Unix)
- Last-Modified: Mon, 06 Aug 2001 21:16:13 GMT
- ETag: "1fa137-10d7-3b6f091d"
- Accept-Ranges: bytes
- Content-Length: 4311
- Content-Type: text/html
-
- If you want to have this information available to a Kermit script you
- can use the /ARRAY switch to have Kermit put it in array, one line per
- array element. Example:
-
- set exit warning off
- http open www.columbia.edu
- if fail exit 1 Can't reach server
- http /array:&a get /index.html
- if fail exit 1 Can't get file
- echo Header lines: \fdim(&a)
- for \%i 1 \fdim(&a) 1 {
- echo \%i. \&a[\%i]
- }
-
- Note that the "Date:" item is the current date and time; the
- "Last-Modified:" item is the file's modification date and time. An
- example showing how to use this information is presented in
- [190]Section 8.13.7.
-
-2.2.4. Secure HTTP Connections
-
- SSL/TLS (Secure Sockets Layer / Transport Layer Security) is the
- protocol used to secure HTTP, SMTP, and other Internet applications.
- See the [191]C-Kermit Reference Section 5.4 for an introduction to
- SSL/TLS. To make a secure HTTP connection, you need:
-
- 1. A secure client (a version of C-Kermit or Kermit 95 with SSL/TLS
- security built in). Type "check ssl" at the Kermit prompt to make
- sure you have it.
- 2. A secure server to connect to.
- 3. The CA Root Certificate used to authenticate the server to the
- client. (see [192]Section 15 of the security reference for an
- introduction to certificates).
-
- And you must make a connection to the secure HTTP port: service name
- HTTPS, port number 443 (as opposed to service HTTP, port 80). You can
- also make secure connections to other ports by including the /TLS or
- /SSL switch with the HTTP OPEN command, if the host supports SSL/TLS on
- the given port:
-
- The quality of the SSL/TLS connection depends on the cipher suite.
- There are several possibilities:
-
- Anonymous cipher suite:
- If an anonymous cipher suite is negotiated, the connection is
- encrypted but there is no authentication. This connection is
- subject to a Man-In-The-Middle (MITM) attack.
-
- X.509 certificate on the server:
- When you connect to certain secure servers, an X.509 certificate
- is returned. This certificate is issued to a special hostname,
- something like www1.xyzcorp.com or wwws.xyzcorp.com (rather than
- the normal www.xyzcorp.com). It is signed by the host's
- Certificate Authority (CA). If the host certificate is
- configured on the client, it can be used to verify the
- certificate received from the server. If the certificate it
- verified as authentic, a check is made to ensure it has not
- expired and it was issued to the host you were attempting to
- connect to. If you had asked to connect to (say) www.xyzcorp.com
- but were given a certificate for www1.xyzcorp.com, you would be
- prompted for permission to continue.
-
- If the verification succeeded, the connection would be encrypted
- with one-way (server-to-client) authentication. This connection
- is not subject to a MITM attack.
-
- If a username and password are transmitted over this connection,
- they are not subject to interception. However, the standard
- risks associated with passing the password to the host for
- verification apply; for example, if the host has been
- compromised, the password will be compromised.
-
- X.509 client certificate:
- If a connection has been established with an X.509 server
- certificate, the server can ask the client to send a certificate
- of its own. This certificate must be verified against a CA Root
- certificate. The certificate itself (or subject info from the
- certificate) is used to determine the authorization for the
- client, and if successful, the username and password need not be
- sent to the server.
-
- Kerberos 5:
- Instead of using X.509 certificates, Kerberos 5 can be used to
- perform the authentication and key exchange. In this situation,
- there is mutual authentication between the client and server.
- The Kerberos 5 principal is used by the server to look up the
- appropriate authorization data. There is no need to send
- username and password.
-
- An HTTP connection is made with the HTTP OPEN command:
-
- HTTP [ switches ] OPEN [ { /SSL, /TLS } ] host [ port ]
- If /SSL or /TLS switches are included (these are synonyms), or
- if the service is HTTPS or the port is 443, a secure connection
- is attempted using the current authentication settings; see HELP
- SET AUTHENTICATION for details ([193]Section 6.2 of the security
- reference). If the no /SSL or /TLS switch is included but the
- port is 443 or the service is HTTPS, a secure connection is
- attempted. If an /SSL or /TLS switch is included but a port is
- not specified, an SSL/TLS connection is attempted on the default
- port (80).
-
- Certificates are covered in the separate [194]Kermit Security Reference
- for C-Kermit 8.0. You should let Kermit know to verify certificates
- with the SET AUTHENTICATION TLS command. For example:
-
- SET AUTHENTICATION TLS CRL-DIR directory
- Specifies a directory that contains certificate revocation files
- where each file is named by the hash of the certificate that has
- been revoked.
-
- SET AUTHENTICATION TLS CRL-FILE filename
- Specifies a file that contains a list of certificate
- revocations.
-
- SET AUTHENTICATION TLS VERIFY-DIR directory
- Specifies a directory that contains root CA certificate files
- used to verify the certificate chains presented by the peer.
- Each file is named by a hash of the certificate.
-
- SET AUTHENTICATION TLS VERIFY-FILE filename
- Specifies a file that contains root CA certificates to be used
- for verifying certificate chains.
-
- SET AUTHENTICATION TLS VERIFY OFF
- Tells Kermit not to require a certificate and accept any
- certificate that is presented regardless of whether it is valid.
-
- There are many other options; see the security document for details.
-
- Now suppose you need need to fetch the file denoted by the following
- URL:
-
- https://myuserid:mypassword@wwws.xyzcorp.com/clients/info/secret.html
-
- Once you have set up the handling of certificates as desired, you can
- use the following Kermit commands:
-
- http /user:myuserid /password:mypassword open www1.xyzcorp.com https
- if success {
- http get /clients/info/secret.html
- http close
- }
-
- As another example, let's say that you have a web form you need to
- populate with three fields: red,white and blue.
-
- <FORM ACTION="http://www.xyzcorp.com/cgi-bin/form.cgi" METHOD="POST">
- <INPUT NAME="Red">
- <INPUT NAME="White">
- <INPUT NAME="Blue">
- </FORM>
-
- You can handle this with the HTTP POST command. The data to be posted
- is stored in the local file data.txt.
-
- Red=seven stripes&White=six stripes&Blue=fifty stars
-
- and the response from the server will be stored into response.txt.
-
- http open www.xyzcorp.com http
- if success {
- http /array:c post data.txt /cgi-bin/form.cgi response.txt
- http close
- }
-
- In this scenario, the Common Gateway Interface (CGI) sends a response
- whether it succeeds or fails in a script-dependent manner. The script
- can either report success and enclose the response data; or it might
- send a 302 Found error which indicates that the "Location:" header
- should be used to determine the URL at which the data can be found.
-
-2.2.5. HTTP Variables
-
- \v(http_code)
- The HTTP protocol code number of the most recent server reply,
- e.g. 404 for "not found".
-
- \v(http_connected)
- 1 when an HTTP connection is open, 0 when there is no HTTP
- connection.
-
- \v(http_host)
- If an HTTP connection is open, the hostname:port, e.g.
- www.columbia.edu:80; otherwise, empty.
-
- \v(http_message)
- Server error message, if any, from most recent HTTP command.
-
- \v(http_security)
- A list of the security parameters and values for the current
- connection, if any. Empty if the connection is not to a secure
- server, or there is no connection.
-
- To display all the HTTP variables at once, type SHOW VAR HTTP:
-
- C-Kermit> http open www.columbia.edu
- C-Kermit> http get lkjlkjlkjlkj
- C-Kermit> sho var http
- \v(http_code) = 404
- \v(http_connected) = 1
- \v(http_host) = www.columbia.edu:80
- \v(http_message) = Not Found
- \v(http_security) = NULL
- C-Kermit>
-
-2.2.6. The HTTP Command-Line Personality
-
- If you invoke C-Kermit with the name "http" or "https", you can use a
- special set of HTTP-specific command-line options. You can do this by
- creating a symbolic linke "http" or "https" to the C-Kermit 8.0
- executable, or by having a separate copy of it called "http" or
- "https". Here's the usage message ("http -h"):
-
- Usage: ./http host [ options... ]
- -h This message.
- -d Debug to debug.log.
- -S Stay (issue command prompt when done).
- -Y Do not execute Kermit initialization file.
- -q Quiet (suppress most messages).
- -u name Username.
- -P password Password.
- -g pathname Get remote pathname.
- -p pathname Put remote pathname.
- -H pathname Head remote pathname.
- -l pathname Local path for -g, -p, and -H.
- -z opt[=value] Security options...
- cert=file Client certificate file
- certsok Accept all certificates
- key=file Client private key file
- secure Use SSL
- verify=n 0 = none, 1 = peer , 2 = certificate required
-
- The "host" argument is the name of a Web host, e.g. www.columbia.edu.
- The action options are -p, -g, and -H. If you give an action option,
- Kermit does the action and then exits. If you give a host without an
- action option, Kermit makes an HTTP connection to the host and then
- gives you the C-Kermit prompt. Here's a simple example that fetches a
- publicly readable Web page:
-
- http www.columbia.edu -g kermit/index.html
-
- If you need to access a website for which a username and password are
- required, you can supply them on the command line with -u and -P. If
- you include a username but omit the password, Kermit prompts you for
- it:
-
- http www.columbia.edu -u olga -p kermit/index.html -l index.html
- Password:
-
- Note that when PUT'ing files to websites, you have to supply both the
- -p (remote pathname) and -l (local path) options.
-
- If your version of Kermit is built with SSL/TLS security, you can also
- use the -z option to make secure HTTP (https) connections.
-
- Finally, as noted in [195]Section 16, you can also give a URL instead
- of a host name and options.
-
- [ [196]Top ] [ [197]Contents ] [ [198]C-Kermit Home ] [ [199]Kermit
- Home ]
-
-3. KERMIT'S BUILT-IN FTP CLIENT
-
- 3.1. [200]Making and Managing FTP Connections
- 3.2. [201]Making Secure FTP Connections
- 3.3. [202]Setting FTP Preferences
- 3.4. [203]Managing Directories and Files
- 3.5. [204]Uploading Files With FTP
- 3.6. [205]Downloading Files With FTP
- 3.7. [206]Translating Character Sets
- 3.8. [207]FTP Command Shortcuts
- 3.9. [208]Dual Sessions
- 3.10. [209]Automating FTP Sessions
- 3.11. [210]Advanced FTP Protocol Features
-
- Earlier versions of C-Kermit and K95 included an FTP command, but it
- simply invoked an external FTP client. Now, by popular demand, Kermit
- includes its own built-in FTP client that offers the following
- advantages over traditional FTP clients (and its previous interface to
- them):
-
- * Any of Kermit's built-in [211]security methods can be used to
- establish and conduct secure FTP sessions with [212]FTP servers
- that support these methods. (Security modules can be subject to
- export restrictions.)
- * Kermit's FTP client uses "passive mode" by default to avoid
- blockage by firewalls and network address translators. Of course
- active mode can be chosen too when needed.
- * [213]Character sets can be translated as part of the transfer
- process even when the FTP server does not support character-set
- translation, including to/from the new Internet standard
- international character set, [214]Unicode UTF-8. This includes both
- the file's name and (for text files only) its contents.
- * All of C-Kermit's [215]file-selection mechanisms are available:
- size, date, name patterns and lists, exception lists, etc.
- * [216]Atomic file movement capabilities are provided (delete, move,
- or rename files automatically after successful transfer).
- * The correct file type, "ascii" (i.e. text) or binary, is chosen
- automatically for each file (explained in [217]Section 4), and any
- mixture of text and binary files can be sent in a single operation,
- even across platforms.
- * Update mode ("don't bother transferring files that didn't change
- since last time") and recovery (resumption of an interrupted
- transfer from the point of failure) are available in both
- directions.
- * When uploading files from UNIX to UNIX, the file's permissions can
- be preserved if desired.
- * Recursive directory-tree PUTs are supported between any two
- platforms that have tree-structured file systems. Recursive GETs
- are supported between like platforms if the server cooperates and
- between like or unlike platforms if the server supports MLSD
- ([218]Section 3.11).
- * When receiving files, all of Kermit's file collision actions are
- available: backup, update, refuse, rename, etc.
- * Multi-file transfers can be interrupted on a per-file basis,
- automatically skipping to the next file.
- * FTP sessions are [219]fully scriptable.
- * An entire FTP session (connect, login, CD, upload or download,
- logout) can be specified on the command line without using a
- script.
- * All of Kermit's logging options and formats are available to keep
- an accurate and complete record of each connection and file
- transfer, and to aid in troubleshooting.
- * All of Kermit's file-transfer display options are available
- (fullscreen, brief, CRT, serial, none).
-
- And best of all:
- * Kermit doesn't give you those annoying per-file prompts every time
- you start a multi-file transfer without remembering to give a
- "prompt" command first :-).
-
- [ [220]Top ] [ [221]FTP Top ] [ [222]FTP Client Overview ] [ [223]FTP
- Script Tutorial ] [ [224]C-Kermit Home ] [ [225]Kermit Home ]
-
-3.1. Making and Managing FTP Connections
-
- Each copy of Kermit can have one FTP connection open at a time. FTP
- connections are independent of regular terminal connections; a terminal
- connection (serial or network via SET LINE, DIAL, SET HOST, TELNET,
- etc) may be, but need not be, open at the same time as an FTP
- connection, and terminal connections can also be closed, and new
- connections opened, without interfering with the FTP connection (and
- vice versa). Thus, for example, Kermit can have an FTP connection and a
- TELNET connection open to the same host simultaneously, using the
- TELNET connection (e.g.) to send mail or take other desired actions as
- various FTP actions complete. Of course, each copy of Kermit can do
- only one thing at a time, so it can't (for example) transfer a file
- with FTP and another file with Kermit protocol simultaneously.
-
- A Kermit FTP session can be established by [226]command-line options,
- by [227]URL, or by [228]interactive commands.
-
-3.1.1. Kermit Command-Line Options for FTP
-
- The new command-line option '-9' (sorry, we're out of letters) can be
- used when starting C-Kermit, telling it to make an FTP connection:
-
- kermit -9 hostname
-
- or if a non-default FTP port is needed:
-
- kermit -9 hostname:port
-
- You can also specify the username on the command line with the -M ("My
- User ID") option that was already there for other connection types:
-
- kermit -9 hostname -M olga
-
- If you specify the username on the command line, Kermit uses it when
- making the connection and does not prompt you for it (but it does
- prompt you for the password if one is required).
-
- Once the connection is made, you get the regular Kermit prompt, and can
- give interactive commands such as the ones described below. When you
- give a BYE command, Kermit closes the session and exits, just as a
- regular FTP client would do. If you don't want Kermit to exit when you
- give a BYE command, include the -S ("Stay") option on the command line.
-
- Other Kermit command-line options that are not specific to non-FTP
- connections should affect the FTP session in the expected ways; for
- example, -i and -T force binary and text mode transfers, respectively.
-
- File transfers can not be initiated on the "kermit -9" command line;
- for that you need to use Kermit's FTP personality (next section) or you
- can use URLs ([229]Section 3.1.3).
-
-3.1.2. The FTP Command-Line Personality
-
- If you want to replace your regular FTP client with C-Kermit, you can
- make a link called "ftp" to the C-Kermit binary (or you can store a
- copy of the C-Kermit binary under the name "ftp"). When C-Kermit is
- invoked with a program name of "ftp" (or "FTP", case doesn't matter),
- it assumes the command-line personality of the regular FTP client:
-
- ftp [ options ] hostname [ port ]
-
- In this case the options are like those of a regular FTP client:
-
- -d Debug: enables debug messages and creates a debug.log file.
- -n No autologin: Kermit should not send your user ID automatically.
- -t Packet trace: accepted but is treated the same as -d.
- -v Verbose: accepted but ignored (operation is verbose by default).
- -i Not interactive: accepted but ignored.
-
- and the hostname can also be a URL (explained in [230]Section 3.1.3).
- To specify a non-default TCP port for the FTP server, include the port
- number or name after the hostname.
-
- There are also some bonus options that allow you to execute an entire
- FTP session from the shell command line, as long as you don't include
- the -n option. These are not available with regular FTP clients, and at
- least one of these options (-g) conflicts with UNIX ftp (where -g means
- "no globbing", which does not apply to Kermit), and some of them (like
- the options above) also conflict with regular Kermit command-line
- options:
-
- -m mode = "passive" (default) or "active"
- -Y Don't execute the Kermit initialization file [1]
- -q Quiet, suppresses all but error messages [1]
- -S Stay, don't exit automatically [1]
- -A Autologin anonymously [2]
- -u name Username for autologin [2] (synonym: -M [1])
- -P password Password for autologin (see cautions below) [2]
- -D directory cd after autologin [2]
- -b Binary mode [2]
- -a Text ("ascii") mode [2] (synonym: -T [1])
- -R Recursive (works with -p) [4]
- -p files Files to put (upload) after autologin [2] (synonym: -s [1])
- -g files Files to get (download) after autologin [3]
-
- [1] Same as Kermit, not available in regular FTP clients.
- [2] Conflicts with Kermit, not available in regular FTP clients.
- [3] Same as Kermit, conflicts with regular FTP clients.
- [4] Conflicts with Kermit, available in some FTP clients.
-
- Fancier options such as restart, character-set translation, filename
- collision selection, automatic move/rename/delete, etc, are not
- available from the command line; for these you can use the commands
- described in the following sections. The -R option might also work with
- -g (GET) but that depends on the server.
-
- The following security options are also available, explained in
- [231]Section 3.2:
-
- -k realm Kerberos 4 realm [4]
- -f Kerberos 5 credentials forwarding [4]
- -x autoencryption mode [4]
- -c cipher SRP cipher type [4]
- -H hash SRP encryption hash [4]
- -z option Security options [4]
-
- If you include -A or specify a name of "anonymous" or "ftp", you are
- logged in anonymously and, in the absence of -P, Kermit automatically
- supplies a password of "user@host", where "user" is your local user ID,
- and "host" is the hostname of the computer where Kermit is running. If
- you do not include -p or -g, Kermit enters command mode so you can type
- commands or execute them from a script.
-
- If you include -p or -g, Kermit attempts to transfer the specified
- files and then exits automatically at the end of the transfer unless
- you also included -S (Stay). It uses the "brief" file transfer display
- (one line per file) unless you include the -q option to suppress it.
-
- When uploading files with -p, Kermit switches automatically between
- text and binary mode for each file.
-
- When downloading, you can either specify a particular mode (text or
- binary) to be used for all the files, or you can let Kermit select the
- type for each file automatically, based on its name (see [232]Sections
- 3.5 and [233]3.6 for greater detail). In UNIX be sure to quote any
- wildcard characters to prevent the shell from expanding them, as shown
- in the examples just below. Filename collisions are handled according
- Kermit's FILE COLLISION setting (if specified in your Kermit
- customization file; otherwise the default, which is BACKUP).
-
- It should go without saying that the -P option should be used with
- caution. In addition to the well-known risks of transmitting plaintext
- passwords over the Internet, in this case the password also echos to
- the screen if you type it, and can be seen in ps and w listings that
- show the user's currently active command and command-line arguments.
- Thus command-line FTP sessions are most appropriate for secure or
- anonymous connections (those that do not require passwords).
-
- Here's an example in which you download the latest C-Kermit "tarball"
- from the Columbia University FTP archive:
-
- ftp -A kermit.columbia.edu -bg kermit/archives/ckermit.tar.gz
-
- This assumes that "ftp" is a symbolic link to C-Kermit. It logs you in
- anonymously and gets the ckermit.tar.gz file in binary mode from the
- kermit/archives directory.
-
- Here's a slightly more ambitious example that illustrates CD'ing to the
- desired server directory to get a group of files in text mode (in this
- case the C-Kermit source files):
-
- ftp -A kermit.columbia.edu -D kermit/f -ag "ck[cuw]*.[cwh]" makefile
-
- In this case we CD to the kermit/f directory so we don't have to
- include it in each file specification, and we quote the ck[cuw]*.[cwh]
- specification so the shell doesn't expand it, since we have to pass it
- as-is to the server. Note also that the quotes don't go around the
- entire file list; only around each file specification that needs to be
- quoted.
-
- Here's one more example, that uploads a debug log file in binary mode
- to the Kermit incoming directory (as we might ask you to do when
- following up on a problem report):
-
- ftp -A kermit.columbia.edu -D kermit/incoming -bp debug.log
-
- In this case the -D option is required to tell the server where to put
- the incoming file.
-
- Unless the -Y option is included, your Kermit initialization file
- (.mykermrc in UNIX, K95.INI in Windows) is executed before the command
- line options, so you can set any FTP-related preferences there, as
- described in the subsequent sections.
-
-3.1.3. The FTP URL Interpreter
-
- If Kermit is invoked with either its regular personality (as "kermit")
- or its FTP personality (as "ftp"), you can also give a URL
- (Universal Resource Locator) instead of a hostname and options,
- with or without a username and password:
- ftp ftp://user:password@host/path
- ftp ftp://user@host/path
- ftp ftp://@host/path (or ftp://:@host/path)
- ftp ftp://host/path
- kermit ftp://host/path
-
- If the FTP personality is used, the service must be "ftp". In all
- cases, a hostname or address must be included. If a user is included
- but no password, you are prompted for the password. If a path
- (filename) is included:
- * If "@" is included without a user, Kermit prompts for the username
- and password.
- * If no user and no "@" are included, "anonymous" is used.
- * GET is assumed.
-
- If no path (and no action options) are included, an interactive FTP
- session is started, as in this example:
- ftp ftp://kermit.columbia.edu
-
- If a path is included, but a username is not included, "anonymous" is
- used and an appropriate user@host password is supplied automatically.
- If authentication is successful, Kermit attempts to GET the file
- indicated by the path or, if the path is the name of a directory, it
- asks the server for a directory listing. In both cases, Kermit
- disconnects from the server and exits after the operation is complete
- (unless you have included the -S option on the command line).
-
- Here's an example that gets a listing of the Kermit directory at the
- Kermit ftp site:
- ftp ftp://kermit.columbia.edu/kermit/
-
- This example gets the top-level READ.ME file from the same directory:
- ftp ftp://kermit.columbia.edu/kermit/READ.ME
-
- Here's the same example, but requesting a text-mode transfer:
- ftp -T ftp://kermit.columbia.edu/kermit/READ.ME
- This illustrates that you can mix command-line options and URLs
- if you desire.
-
- Here's an example that logs in as a (fictitious) real user to get a
- file:
- ftp ftp://olga@ftp.xyzcorp.com/resume.txt
- The password is not included, so Kermit prompts for it.
-
- This scheme allows Kermit to be used as the FTP helper of other
- applications, such as Web browsers, with all its advantages over other
- FTP clients (especially the ones that are built in to most Web
- browsers), e.g. that it can be given wildcards, and it can pick text
- and binary mode automatically for each file.
-
- HINT: suppose somebody sends you an FTP URL in email, or you see it in
- some text. If your terminal screen supports copy/paste, copy the url,
- and then at the shell prompt type "kermit", a space, and then paste the
- URL, e.g.:
-
- $ kermit ftp://alpha.greenie.net/pub/mgetty/source/1.1/mgetty1.1.27-O
-
- "$ is the shell prompt; the part you type is underlined, the rest is
- pasted in. Kermit does the rest.
-
-3.1.4. Interactive FTP Session Establishment
-
- As you read this and the following sections, bear in mind that any
- command that can be given at the prompt can also be used in a script
- program. Kermit's script programming language is the same as its
- interactive command language. [234]CLICK HERE if you would like to
- learn a bit more about script writing.
-
- An FTP session is established with the FTP OPEN command:
-
- FTP [ OPEN ] [ { /SSL, /TLS } ] hostname [ switches ] [ port ]
- Opens an FTP connection to the given host on the given port and,
- if FTP AUTOLOGIN is ON, also logs you in to the server,
- prompting for username and password if necessary. If no port is
- specified, the regular FTP protocol port (21) is used. The OPEN
- keyword is optional (unless the hostname conflicts with one of
- the FTP command keywords, which you can list by typing "ftp ?").
-
- The hostname can be an IP host name, numeric IP address, or if you have
- a network directory active (SET NETWORK DIRECTORY; see Chapter 6 of
- [235]Using C-Kermit), an entry name in the directory. In the latter
- case, if the given hostname matches exactly one entry, the associated
- name or address is used; if it matches more than one, Kermit cycles
- through them until one is found that can be opened; if it matches none,
- then the hostname is used as-is. If a directory is active but you want
- to bypass directory lookup, include an "=" sign at the beginning of the
- hostname, and/or use a numeric IP address.
-
- When an FTP connection is opened, the default file-transfer mode is set
- to binary if the client and server platforms are alike (e.g. both of
- them are some kind of UNIX), and to text ("ascii") if they are not
- alike. This has no particular effect for uploading since Kermit
- automatically switches between text and binary mode for each file, but
- might be important for downloading. The connection is also set to
- Stream mode and File structure. Record- or page-oriented file transfers
- are not supported by C-Kermit's FTP client.
-
- The optional FTP OPEN switches are:
-
- /ANONYMOUS
- Logs you in anonymously, automatically supplying username
- "anonymous" and user@host as the password, based on your local
- user and host names.
-
- /NOLOGIN
-
- Overrides SET FTP AUTOLOGIN ON for this connection only.
-
- /USER:name
- Uses the given username to log you in, thus avoiding the Name:
- prompt.
- Overrides SET FTP AUTOLOGIN OFF for this connection only.
-
- /PASSWORD:text
- Uses the given text as your password, thus avoiding the
- Password: prompt. This switch is not recommended for use in
- script files, which would be a security risk.
-
- /ACCOUNT:text
- Uses the given text as your account (or secondary password,
- depending on the requirements of the server; most servers do not
- require or accept an account name). If an account is not
- supplied, you are not prompted for one.
-
- /PASSIVE
- Opens the connection in passive mode. Passive mode is the
- default in Kermit's FTP client, unlike in most others, since it
- works better through firewalls. The /PASSIVE and /ACTIVE
- switches apply only to the connection that is being opened, and
- do not affect the global FTP PASSIVE-MODE setting.
-
- /ACTIVE
- Opens the connection in active mode. Use this switch if the
- server does not support passive mode, or use the command SET FTP
- PASSIVE-MODE OFF.
-
- /NOINIT
- Added in C-Kermit 8.0.201. Tells C-Kermit not to send REST,
- STRU, FEAT, and MODE commands to the server when the connection
- is opened, since these have been reported to cause confusion in
- certain servers.
-
- When a username or password is missing, a prompt is issued at the
- controlling terminal and you must type the response; the response can
- not be scripted. Use the switches to avoid prompts, or one of the
- secure authentication methods described in the next section, or see
- [236]SET FTP AUTOLOGIN and the [237]FTP USER and similar commands
- described later in this section.
-
- Examples:
-
- ftp open kermit.columbia.edu /anonymous ; Open and log in anonymously
- ftp kermit.columbia.edu /anonymous ; The OPEN keyword can be omitted
- ftp xyzcorp.com ; Open and maybe prompt for username
- ftp xyzcorp.com /user:olga ; Open and log in as olga
- ftp testing.abccorp.com 449 ; Specify a special TCP port number
- ftp testing.abccorp.com /user:olaf /password:secret 449
-
- The FTP OPEN command succeeds if a connection was opened to the server
- (even if the given username and password were not valid) and fails
- otherwise (see [238]Section 3.8 for details).
-
- When your FTP session is complete, you can terminate it as follows:
-
- FTP BYE
- Closes the FTP connection if one was open. The FTP prefix can be
- omitted if no other connection is open at the same time (see
- [239]Section 3.8 for details). If a connection log is active, an
- FTP record is written to it. If Kermit was started with the -9
- command-line option or with its FTP command-line personality,
- and the -S (Stay) option was not given, AND there is no other
- active connection, the FTP BYE command also exits, just as it
- does on a regular FTP client. Synonyms: FTP CLOSE, FTP QUIT (but
- if the FTP prefix is omitted from QUIT, this becomes the regular
- Kermit QUIT command, which is equivalent to EXIT; i.e. it closes
- the connection and exits from Kermit).
-
- The following commands can be used to achieve greater control over the
- connection and login process:
-
- SET FTP ANONYMOUS-PASSWORD text
- Allows you to choose the password text to be sent automatically
- by Kermit when you open an FTP connection with the /ANONYMOUS
- switch.
-
- SET FTP AUTOLOGIN { ON, OFF }
- If you give this command prior to opening an FTP connection, it
- controls whether Kermit tries to log you in automatically as
- part of the connection process. Normally ON, which means the
- username and password are sent automatically (and prompted for
- if they are not yet known). When OFF, FTP OPEN connects to the
- server without logging in. OFF is equivalent to the -n
- command-line option when using Kermit's FTP command-line
- personality.
-
- FTP USER name [ password [ account ] ]
- Used to log in to an FTP server to which a connection has been
- made without autologin, or when autologin failed. If the
- password is furnished on the command line, it is used; otherwise
- you are prompted for a password. An account may also be
- furnished if required by the server; it is not required by
- Kermit and is not prompted for if omitted. Synonyms: USER, FTP
- LOGIN.
-
- FTP ACCOUNT text
- Sends an account name to a server that supports accounts. If the
- server does not support accounts, an error response occurs. If
- the server does support accounts, the account is accepted if it
- is valid and rejected if it is not. The account might be used
- for charging purposes or it might be a secondary password, or it
- might be used for any other purpose, such as an access password
- for a particular disk. Servers that support accounts might or
- might not allow or require the account to be sent prior to
- login; usually it is sent after login, if at all. Synonym:
- ACCOUNT.
-
- Example:
-
-set ftp autologin off ; One thing at a time please
-ftp xyzcorp.com ; Try to make the connection
-if fail exit 1 FTP connection failed ; Check that it was made
-ftp user olga secret ; Now log in to the server
-if fail exit 1 FTP login failed ; Check that it worked
-ftp account 103896854 ; Login OK - send account
-if fail echo WARNING - FTP ACCT failed ; Warn if problem
-... ; (have session here)
-bye ; Log out and disconnect
-
- The following commands are used to control or get information about the
- FTP connection. Any particular FTP server does not necessarily support
- all of them.
-
- FTP RESET
- Terminates a user session but leaves the connection open,
- allowing a new login via FTP USER.
-
- FTP IDLE [ number ]
- Most FTP servers automatically log you out and and disconnect
- your session if there has been no activity for a certain amount
- of time. Use this command to ask the server to set its idle
- limit to the given number of seconds. Omit the number to ask the
- server to inform you of its current idle limit.
-
- FTP STATUS [ filename ]
- Asks the FTP server to send information about the current
- session. The result is a free-format report that might include
- server identification, username and login time, FTP protocol
- settings, and file-transfer statistics. If a filename is given,
- the server is supposed to send detailed information about the
- file.
-
- FTP SYSTEM
- Asks the FTP server to identify its operating system (Listed in
- Internet Assigned Numbers, Operating System Names). Examples:
- UNIX, VMS, VM/CMS, WINDOWS-NT. Unfortunately many variations are
- allowed (e.g. LINUX-2.0, LINUX-2.2, FREEBSD, ULTRIX, etc,
- instead of UNIX; WINDOWS-NT-3, WINDOWS-NT-3.5, WINDOWS-NT-3.51,
- WINDOWS-NT-4, etc). The report might also include other
- information like "Type L8", "Type I", or "Type A", indicating
- the file-transfer mode.
-
- FTP HELP [ keyword [ keyword [ ... ] ]
- Asks the server to list the commands it supports. The response
- is usually cryptic, listing FTP command mnemonics, not the
- commands used by the client (since the server has no way of
- knowing anything about the client's user interface). For
- example, the PUT command is STOR in FTP protocol. If a keyword
- is given, which should be an FTP protocol command,
- slightly-more- detailed help is given about the corresponding
- command (if the FTP server supports this feature). Examples:
- "ftp help", "ftp help stor".
-
- FTP SITE text
- (Advanced) Sends an FTP SITE (site-specific) command. Usually
- this means that the FTP server is asked to run an external
- command with the given arguments. You might be able to find out
- what SITE commands are available by sending "ftp help site" to
- the server, but in general the availability of and response to
- SITE commands is (not surprisingly) site specific.
-
- FTP QUOTE text
- (Advanced) Sends an FTP command in FTP protocol format. Use this
- command to send commands to the server that the FTP client might
- not know about.
-
- SHOW FTP
- Lists client (Kermit) FTP settings and information. Also SHOW
- CONNECTION, SHOW COMMUNICATIONS.
-
- HELP FTP [ keyword ]
- Asks Kermit to list and describe its built-in FTP commands.
-
- HELP SET FTP [ keyword ]
- Asks Kermit to list and describe its built-in SET FTP commands.
-
- [ [240]Top ] [ [241]FTP Top ] [ [242]C-Kermit Home ] [ [243]Kermit Home
- ]
-
-3.1.5. Making Proxy Connections
-
- The simplist form of firewall traversal is the HTTP CONNECT command.
- The CONNECT command was implemented to allow a public web server which
- usually resides on the boundary between the public and private networks
- to forward HTTP requests from clients on the private network to public
- web sites. In order to allow secure web connections to be established,
- the CONNECT command works by authenticating the client with a
- username/password and then establishing a tunnel to the desired host.
-
- Many web servers support the CONNECT command and it can be configured
- to allow outgoing connections to authenticated user to any TCP/IP
- hostname/port combination accessible to the web server. The limitations
- of HTTP CONNECT is that it can only be used for outgoing connections
- for protocols that are implemented using TCP/IP. Protocols such as
- Kerberos authentication that use UDP/IP cannot be tunneled using HTTP
- CONNECT.
-
- Kermit provides support for the use of HTTP CONNECT proxy services with
- the command:
-
- SET TCP HTTP-PROXY [/USER:username /PASSWORD:password] hostname/ip-address[:po
-rt]
-
- When a port is not specified the default port configured on the HTTP
- server is used. This is frequently port 443. When a hostname is
- specified, it is resolved using the DNS available to the web server.
-
-3.2. Making Secure FTP Connections
-
- Also see: [244]Accessing IBM Information Exchange with Kermit.
-
- In the previous section, you can see several examples of traditional
- insecure authentication: username and password sent across the network
- in clear text. Of course this is bad practice on at least two counts:
- (1) storing passwords in files (such as script files) gives access to
- the target systems to anybody who can obtain read access to your
- scripts; and (2) sending this information over the network leaves it
- open to interception by network sniffers or compromised hosts.
-
- Because of the increasing need for security on the Internet, FTP
- servers are beginning to appear that offer secure forms of
- authentication, in which no information is sent over the network that
- would allow anyone who intercepts it to usurp your identity and gain
- your access rights.
-
- Kermit provides an equivalent form of FTP security for each type of
- IETF standard security implemented in Telnet. These include
- GSSAPI-KERBEROS5, KERBEROS4, Secure Remote Password (SRP), and
- Transport Layer Security (SSL and TLS). It does not presently include
- SSL tunneling nor any form of SSH v1 or v2. When Kermit is built with
- the necessary libraries, secure FTP connections are attempted by
- default, in which all connections are authenticated and the command and
- data channels are private.
-
- The use of authentication and encryption for FTP connections can be
- adjusted with the commands listed below, which are available only if
- your version of Kermit was built with the corresponding security
- options and libraries:
-
- SET FTP AUTHTYPE { AUTOMATIC, GSSAPI-KRB5, KERBEROS4, SRP, SSL, TLS }
- Specifies an ordered list of authentication methods to be
- attempted when AUTOAUTHENTICATION is ON. The default list is:
- GSSAPI-KRB5, SRP, KERBEROS_V4, TLS, SSL. If none of the selected
- methods are supported by the server, an insecure login is used
- as a fallback. Note, by the way, that SSL or TLS can be used to
- secure an anonymous connection.
-
- SET FTP AUTOAUTHENTICATION { ON, OFF }
- Tells whether authentication should be negotiated by the FTP
- OPEN command. Default is ON. Use SET FTP AUTOAUTHENTICATION OFF
- to force a clear-text, unencrypted connection to FTP servers
- (such as the one at the Kermit FTP site) that normally would try
- to negotiate secure authentication and encryption.
-
- SET FTP AUTOENCRYPTION { ON, OFF }
- Tells whether encryption (privacy) should be negotiated by the
- FTP OPEN command, which can happen only if secure authentication
- is also negotiated. Default is ON.
-
- SET FTP AUTOLOGIN { ON, OFF }
- Tells Kermit whether to try logging in automatically when you
- make an FTP connection, as opposed to letting you do it "by
- hand" with the FTP USER command.
-
- SET FTP COMMAND-PROTECTION-LEVEL { CLEAR, CONFIDENTIAL, PRIVATE, SAFE }
- Determines the level of protection applied to the command
- channel:
-
- CLEAR Data is sent in plaintext and not protected against tampering.
- CONFIDENTIAL Data is encrypted but not protected against tampering.
- PRIVATE Data is encrypted and is protected against tampering.
- SAFE Data is sent in plaintext but protected against tampering.
-
- The default is PRIVATE.
-
- SET FTP CREDENTIAL-FORWARDING { ON, OFF }
- Tells whether end-user credentials are to be forwarded to the
- server if supported by the authentication method (GSSAPI-KRB5
- only). This is often required to allow access to distributed
- file systems (e.g. AFS.)
-
- SET FTP DATA-PROTECTION-LEVEL { CLEAR, CONFIDENTIAL, PRIVATE, SAFE }
- Tells what level of protection is applied to subsequent data
- channels. The meanings of the protection-level keywords are the
- same as for SET FTP COMMAND-PROTECTION-LEVEL. The default is
- PRIVATE.
-
- SET FTP SRP CIPHER name
- Specifies the cipher to be used for encryption when SRP
- authentication is in use. The list of possible choices is
- computed based on the capabilities of the local SRP library and
- includes NONE plus zero or more of the following:
-
- BLOWFISH_ECB CAST5_ECB DES_ECB DES3_ECB
- BLOWFISH_CBC CAST5_CBC DES_CBC DES3_CBC
- BLOWFISH_CFB64 CAST5_CFB64 DES_CFB64 DES3_CFB64
- BLOWFISH_OFB64 CAST5_OFB64 DES_OFB64 DES3_OFB64
-
- The default is DES3_ECB.
-
- SET FTP SRP HASH name
- Specifies the hash to be used for data protection when SRP
- authentication is in use. The choices are MD5 and SHA. The
- default is SHA.
-
- Command-line options:
-
- -k name
- Specifies the realm to be used with Kerberos 4 authentication (=
- SET AUTH K4 REALM name).
-
- -f
- Enables forwarding of Kerberos 5 credentials to the host when
- using GSSAPI authentication (= SET AUTH K5 FORWARDABLE ON).
-
- -x
- Enables autoencryption (= SET FTP AUTOENCRYPTION ON).
-
- -c cipher
- Specifies the kind of cipher to be used for encryption with SRP
- authentication. Equivalent to SET FTP SRP CIPHER, with the same
- choices. If this option is not given, CAST5_CBC is used.
-
- -H hash
- Specifies the hash to be used for encryption with SRP
- authentication. Equivalent to SET FTP SRP HASH, with the same
- choices. If this option is not given, SHA is used.
-
- -z debug
- Turns on SSL/TLS debugging.
-
- -z secure
- Requires secure connection.
-
- -z certsok
- Says to accept all certificates without checking validity.
-
- -z verify=n
- Sets certificate verification mode to the given number, n:
- 0 = no verification
- 1 = verify certificate if presented
- 2 = require verification of certificate
-
- -z cert=filename
- Specifies a file containing a client certificate to be presented
- to the FTP server.
-
- -z key=filename
- Specifies a file containing a private key matching the client
- certificate.
-
- -z !krb4
- (nokrb4) Disables the use of Kerberos 4.
-
- -z !gss
- -z nogss
- Disables the use of GSSAPI - Kerberos 5.
-
- -z !srp
- -z nosrp
- Disables use of SRP.
-
- -z !ssl
- -z nossl
- Disables the use of SSL.
-
- -z !tls
- -z notls
- Disables the use of TLS.
-
- Caution: If your FTP connection is secured via AUTH TLS, it is not
- possible to interrupt a file transfer. This is a limitation of all
- known FTP servers that support AUTH TLS.
-
- Note that when using certain security methods, such as SSL or TLS, you
- may be prompted to confirm or verify certain actions or conditions, for
- example, whether to accept self-signed certificates. This can interfere
- with unattended operation of scripts; see [245]Section 3.10.
-
- [ [246]Top ] [ [247]FTP Top ] [ [248]C-Kermit Home ] [ [249]Kermit Home
- ]
-
-3.3. Setting FTP Preferences
-
- FTP preferences can be set globally and persistently with the commands
- in the following sections; many of these can also be overridden on a
- per-command basis with switches that have the same name.
-
-3.3.1. Logs, Messages, and Other Feedback
-
- You can control the amount of feedback received from your FTP session
- with the commands in this section. First, you can create a log of your
- FTP transfers with the following commands:
-
- SET TRANSACTION-LOG { VERBOSE, FTP, BRIEF }
- Selects the log format. VERBOSE is the default, and is described
- in [250]the manual. FTP chooses a WU-FTPD format, the same as is
- used by the popular FTP server. BRIEF creates per-file records
- in comma-separated-list format. For greater detail, see
- [251]Section 4.17 of the [252]C-Kermit 7.0 Update Notes.
-
- LOG TRANSACTIONS filename
- Records FTP (or Kermit, or any other protocol) uploads and
- downloads in the given file using the format selected by the
- most recent SET TRANSACTION-LOG command, if any, or else the
- default format.
-
- FTP screen messages and displays are controlled by the following
- commands:
-
- SET TRANSFER DISPLAY { FULLSCREEN, CRT, SERIAL, BRIEF, NONE, OFF }
- FTP transfers use Kermit's normal file-transfer display styles.
- Use this command to choose the desired format; the default on
- most platforms is FULLSCREEN. The display is automatically
- disabled if Kermit is running in the background or in batch.
- BRIEF is always used for command-line initiated transfers
- (unless suppressed by -q). While a file-transfer is in progress,
- you can interrupt it in the normal Kermit way by typing one of
- the following keys or key combinations:
- X - Cancel current file but go on to the next one (if any).
- Z - Cancel the entire transfer. Ctrl-L or Ctrl-W - Refresh
- the file-transfer display (if any).
-
- SET FTP DISPLAY { FULLSCREEN, CRT, SERIAL, BRIEF, NONE, OFF }
- Like SET TRANSFER DISPLAY, but applies only to FTP connections,
- and does not affect Kermit- or other protocol file transfers.
-
- SET QUIET { ON, OFF }
- This command applies to Kermit in general, not just FTP. OFF by
- default; when ON, it suppresses most messages from most commands
- as well as the file-transfer display.
-
- SET FTP PROGRESS-MESSAGES { ON, OFF }
- Tells whether Kermit should print locally-generated feedback
- messages for each non-file-transfer command. ON by default.
-
- SET FTP VERBOSE-MODE { ON, OFF }
- Tells whether to display all responses from the FTP server. OFF
- by default. This shows all responses to all commands, except
- when the file-transfer display is active, and unless you have
- SET QUIET ON. When OFF, responses are shown only for commands
- such as FTP PWD whose purpose is to display a response.
-
- SET FTP DEBUG { ON, OFF }
- Tells whether local client debugging information should be
- displayed. OFF by default. When ON, the commands that are sent
- to the server are shown, as well as its responses (even if
- VERBOSE-MODE is OFF), plus additional informational messages are
- printed regarding the progress of secure operations. Also, the
- temporary file created by the [253]MGET command is not deleted
- so you can see what's in it.
-
- Set all of these to OFF when silent running is desired.
-
-3.3.2. Operational Preferences
-
- FTP DISABLE new-protocol-feature-name
- FTP ENABLE new-protocol-feature-name
- Explained in [254]Section 3.11.
-
- SET FTP AUTOLOGIN { ON, OFF }
- If you give this command prior to opening an FTP connection, it
- controls whether Kermit tries to log you in automatically as
- part of the connection process. Normally ON, which means the
- username and password are sent automatically (and prompted for
- if they are not yet known). When OFF, FTP OPEN connects to the
- server without logging in. OFF is equivalent to the -n
- command-line option when using Kermit's FTP command-line
- personality. See [255]Section 3.1.4 for usage.
-
- SET FTP PASSIVE-MODE { ON, OFF }
- ON by default, to avoid random TCP port assignment for data
- connections, which can prevent FTP protocol from working through
- firewalls and network address translators (for more on these
- topics, see the [256]Kermit security reference. Set to OFF in
- case the FTP server does not support passive mode, or in case
- the client has problems with it (it has been observed, for
- example, that when using passive mode, the SCO XENIX 2.3.4
- TCP/IP stack hangs in the connect() call forever). Synonyms:
- PASSIVE [ ON ], PASSIVE OFF, PASV [ ON ], PASV OFF.
-
- SET FTP SEND-PORT-COMMANDS { ON, OFF }
- This command determines whether the FTP client sends a new PORT
- command to the server when accepting incoming data connections
- (as when not using passive mode.) When PASSIVE-MODE is OFF and
- SET SEND-PORT is OFF, the port that was originally specified is
- reused. This is the default behavior for normal FTP clients but
- it is not compatible with many firewalls.
-
- SET FTP CHARACTER-SET-TRANSLATION { ON, OFF }
- Whether to translate character sets when transferring files with
- FTP (explained in [257]Section 3.7). OFF by default.
-
- SET FTP SERVER-CHARACTER-SET name
- Tells Kermit the character set used by the FTP server, UTF-8 by
- default ([258]Section 3.7).
-
- SET FTP SERVER-TIME-OFFSET delta-time
- Tells Kermit to apply the given [259]delta time to file
- timestamps provided by the server for its files; for use when
- (for example) the server does not have its timezone set
- correctly.
-
- SET FTP ERROR-ACTION { PROCEED, QUIT }
- When transferring a group of files with FTP, and an error occurs
- with one of the files, Kermit normally goes on the next file.
- Use SET FTP ERROR-ACTION to QUIT to make Kermit stop the
- transfer immediately and fail if an error occurs with any single
- file in the group. Example: you have given Kermit a list of
- files to send, and one of the files can not be found, or read
- permission is denied. Note that canceling a file by typing 'X'
- during transfer is not considered an error (if you want to
- cancel the entire transfer, type 'Z' or Ctrl-C).
-
- SET FTP PERMISSIONS { AUTO, ON, OFF }
- When uploading files with PUT or MPUT, this tells whether Kermit
- should send each file's permissions. The default is OFF, which
- means not to send permissions, in which case the uploaded file's
- permissions are set by the FTP server according to its own
- criteria. ON means to send them, AUTO means to send them only if
- the client (Kermit) and server are on like platforms (e.g. both
- UNIX). This command has no effect when downloading, since the
- FTP protocol does not include a way for the server to inform the
- client of a file's permissions. Also see [260]FTP PUT
- /PERMISSIONS. Note that setting permissions after uploading is
- likely to work (correctly or at all) only when the client and
- server platforms are alike (e.g. both of them are some form of
- UNIX). Also note that Windows files don't have permissions. Also
- see [261]FTP CHMOD.
-
- SET FTP DATES { ON, OFF }
- When downloading files with GET or MGET, this tells whether
- Kermit should try to set the received file's date from the
- server's date. FTP DATES is ON by default. Note, however, that
- FTP protocol does not allow date preservation when uploading. So
- at best, SET FTP DATES ON can work only when downloading, and
- then only when the server agrees to furnish file dates.
-
- SET FTP FILENAMES { AUTO, CONVERTED, LITERAL }
- When uploading (sending) files, this tells whether to convert
- outbound filenames to "common form". This means allowing only
- one period in a name, uppercasing any lowercase letters,
- replacing spaces by underscores, etc. AUTOMATIC is the default,
- meaning LITERAL when client and server are the same type of
- system (e.g. UNIX) and CONVERTED otherwise. Special case: if the
- setting is AUTOMATIC and the client is not UNIX and the server
- identifies itself as UNIX, Kermit uses a less-strict form of
- conversion, in which lowercase letters are not uppercased and
- the filename can contain any number of periods, but spaces are
- still converted to underscore. When receiving, conversion
- generally means to change all-uppercase names to lowercase and
- spaces to underscore.
-
- SET FTP UNIQUE-SERVER-NAMES { ON, OFF }
- Applies only to uploads. Tells the server to create new, unique
- names for incoming files that have the same names as existing
- files. OFF by default, in which case the server overwrites
- existing files with new files of the same name. When ON, the
- server uses its own built-in method for creating new names for
- incoming files; for example, appending a period (.) and a number
- to the name. CAUTION: Use this option only if you do not need to
- refer to the file after it is uploaded, since FTP protocol
- provides no mechanism for the client to find out what name was
- assigned by the server.
-
- SET FTP COLLISION { ... }
- When downloading, what to do if an incoming file has the same
- name as an existing file. Options are the same as for SET FILE
- COLLISION. If this command is not given, Kermit's regular FILE
- COLLISION setting is used. If this command is given, it
- overrides the FILE COLLISION setting for FTP transfers only. See
- [262]Section 3.6.2 for details.
-
- SET FTP TYPE { TEXT, BINARY, TENEX }
- Changes the default transfer mode. When sending (uploading)
- files, this command has no effect unless you disable automatic
- text/binary mode switching ([263]Section 4) with SET FILE SCAN
- OFF or SET TRANSFER MODE MANUAL. When receiving (downloading)
- files, this command establishes the transfer mode to be used
- when a filename does not match any of Kermit's text or binary
- filename patterns, unless you use SET FTP GET-FILETYPE-SWITCHING
- or SET TRANSFER MODE MANUAL to disable automatic switching, in
- which case, this command establishes the transfer mode for all
- downloaded files. In all cases, however, the FTP TYPE can be
- overridden in any GET or PUT command by including a /TEXT
- (/ASCII), /BINARY, or /TENEX switch. The FTP TYPE is independent
- of the Kermit FILE TYPE setting. TENEX is used for sending 8-bit
- binary files to 36-bit platforms such as TOPS-10, TOPS-20, and
- TENEX, and getting them back again. Synonym: ASCII = TEXT. Note:
- there is also an FTP TYPE command, which does what SET FTP TYPE
- does but also sends a TYPE command to the server immediately if
- the given type is different from the current one.
-
- If you want want specific FTP preference settings to be in effect for
- all your Kermit FTP sessions, put the desired SET FTP commands in your
- Kermit customization file (~/.mykermrc in UNIX, K95CUSTOM.INI in
- Windows).
-
- [ [264]Top ] [ [265]FTP Top ] [ [266]C-Kermit Home ] [ [267]Kermit Home
- ]
-
-3.4. Managing Directories and Files
-
- In Kermit, commands for directory and file management can refer to:
-
- * The local computer
- * A remote computer when you have a connection to a Kermit server or
- IKSD.
- * A remote computer when you have a connection to an FTP server.
-
- (There can also be an HTTP connection, but the commands in this section
- don't apply to HTTP connections.)
-
- Thus in general, each such command comes in three forms:
-
- 1. With no prefix in C-Kermit 8.0.200, it refers to the local computer
- (CD, DIR, etc). In C-Kermit 8.0.201 and later, however, the "locus"
- switches to automatically to the remote FTP server when you make an
- FTP connection (see the SET LOCUS description [268]Section 7); thus
- C-Kermit 8.0.201 acts almost exactly like a regular FTP client when
- it has an FTP connection, yet still acts like itself on other kinds
- of connections.
- 2. With the REMOTE prefix, it is for a Kermit server (REMOTE CD,
- REMOTE DIR).
- 3. With the FTP prefix, it's for an FTP server (FTP CD, FTP DIR).
- 4. Also see [269]Section 3.8, which explains "R-commands" and
- "L-commands".
-
- Kermit's FTP file and directory management commands are as follows.
- When an R-command is included in the Synonyms list, be sure to read
- [270]Section 3.8 about rules for use of R-commands.
-
- FTP CD [ directory ]
- Tells the FTP server to change its default (working) directory
- to the one given, which usually must be expressed in the syntax
- of the server platform (UNIX, VMS, etc). If the directory is not
- specified, the result depends on the FTP server -- it might
- complain that the command is illegal, or it might change to your
- original login directory. Synonyms: FTP CWD (Change Wording
- Directory); RCD.
-
- FTP CDUP
- Tells the FTP server to change its default (working) directory
- to the parent directory of its current one (equivalent to
- "cd .." in UNIX, or "cd [-]" in VMS). Synonyms: RCDUP, FTP UP.
-
- FTP PWD
- Asks the FTP server to report ("print") its current working
- directory. Synonym: RPWD.
-
- FTP MKDIR directory
- Asks the FTP server to create the directory whose name is given.
- In general, the name must be in the syntax of the server's file
- system, and it must be either absolute (a full pathname) or
- relative to the server's current (working) directory. This
- command fails if the directory can't be created for any reason,
- including that it exists already. Synonym: RMKDIR.
-
- FTP RMDIR directory
- Asks the FTP server to remove the directory whose name is given.
- The rules are the same as for MKDIR, plus in most cases, the
- server will not remove any directory unless it is empty.
- Synonym: RRMDIR.
-
- FTP DIRECTORY [ filespec ] [ redirectors ]
- Tells the FTP server to send a directory listing of the
- specified files. If no filespec is given, the server lists all
- files in its current working directory. The results are in
- whatever format the server chooses to send them. You can use
- UNIX-like redirectors to send the listing to a file or a
- pipeline, exactly as with the regular Kermit client/server
- REMOTE DIRECTORY command ([271]Using C-Kermit, Chapter 11).
- Synonym: RDIRECTORY. Examples:
-
- ftp dir ; Show listing of all files on screen
- ftp dir *.txt ; List *.txt files on screen
- ftp dir *.txt > somefile ; Put listing in somefile
- ftp dir *.txt >> somefile ; Append listing to somefile
- ftp dir *.txt | sort > somefile ; Put sorted listing in somefile
- ftp dir | more ; Runs list through "more"
- ftp dir | sort | more ; Runs list through "sort" and "more"
-
- FTP VDIRECTORY [ filespec ] [ redirectors ]
- "Verbose" directory. This is an alternative FTP DIRECTORY
- command primarily for use with DECSYSTEM-20 (TOPS-20) FTP
- servers, which send only filenames when given a DIRECTORY
- command; the VDIRECTORY command makes them also send file sizes,
- dates, and attributes.
-
- FTP CHECK filespec
- Asks the FTP server whether the given file exists or, if the
- filespec contains wildcards, if any files match, and this
- command succeeds or fails accordingly.
-
- FTP MODTIME filename
- Asks the FTP server, via the not-yet-standard FTP MDTM command,
- to send the modification date and time of the given file. The
- response should be a numeric string in the format:
- yyyymmddhhmmssxxxxx... where yyyy is the year, mm is the month,
- dd is the day, hh is the hour (0-23), mm is the minute, ss is
- the second, and xxx... is the optional fraction of the second (0
- or more digits). The date and time is expressed in UTC (GMT,
- Zulu, Zero-Meridian). The result is available programmatically
- in the [272]\v(ftp_message) variable, and is understandable by
- Kermit's date-time switches and functions. For example, suppose
- we want to upload all local files that are newer than a
- particular file on the server:
-
- C-Kermit> ftp modtime signpost
- C-Kermit> echo \v(ftp_message)
- 20010807113542.014
- C-Kermit> ftp mput /after:\v(ftp_message)GMT *
-
- Note that we must append "GMT" to the date-time string to let
- the /AFTER switch know the time is GMT rather than local.
-
- FTP SIZE filename
- Asks the FTP server to send the size (in bytes) of the given
- file. The result might vary depending on whether the current FTP
- TYPE is binary or text ("ascii"). For a reliable byte count, do
- FTP TYPE BINARY first. The result is available programmatically
- in the [273]\v(ftp_message) variable.
-
- FTP CHMOD permissions filename
- Tells the FTP server to set the permissions (protection) of the
- given file to the ones given. The permissions and filename must
- be given in whatever syntax is required by the server. Example
- (for a UNIX-based FTP server):
-
- ftp chmod 664 oofa.txt
-
- Not all servers support this command. For non-UNIX-based
- servers, you might need to use FTP QUOTE or FTP SITE and the
- appropriate platform-specific FTP server command.
-
- FTP UMASK [ number ]
- This command is probably specific to UNIX-based servers; it sets
- the UNIX "umask", which is the default permissions mask for new
- (in this case, incoming) files. Crudely put, the UNIX umask is
- an octal representation of a binary number in in which a 1 bit
- stands for a permission bit that must be 0, and a 0 bit stands
- for a permission bit that can be 0 or 1 depending on other
- factors, such as the permissions of the parent directory.
- Example: "umask 007" requires that new files are created without
- read/write/execute world permission. If the number is not
- specified, the server's current umask is reported.
-
- FTP RENAME filename newname
- Asks the FTP server to rename the file whose name is "filename"
- to "newname". Works only for one file; can not be used with
- wildcards. The server's interpretation of "newname" can vary (in
- some cases it must be a filename, in others perhaps it can also
- be a directory name, in which case if the filename denote a
- regular file, the file might be moved to the given directory).
- Some servers might allow files to be renamed ("moved") between
- physical disks or partitions, others might not. Synonym:
- RRENAME.
-
- FTP DELETE [ switches ] filespec [ filespec [ ... ] ]
- Tells the FTP server to delete the file or files listed. Each
- file specification may, but need not, contain wildcard
- characters to match multiple files. File specifications and
- wildcard syntax must be those of the server. Any file
- specifications that contain spaces must be enclosed in braces or
- doublequotes. FTP DELETE switches are:
-
- /ERROR-ACTION: /FILENAMES: /NOBACKUPFILES /QUIET
- /EXCEPT: /LARGER-THAN: /NODOTFILES /NOPAGE
- /PAGE /RECURSIVE /SMALLER-THAN:
-
- When used with FTP DELETE, the /RECURSIVE switch deletes files
- but not directories, and furthermore depends on the server
- providing recursive file lists, which is not the normal
- behavior. For further details, see the descriptions of these
- switches in [274]Section 3.6. Synonyms: FTP MDELETE (Kermit
- makes no distinction between DELETE and MDELETE); RDELETE.
-
- FTP TYPE { TEXT, BINARY, TENEX }
- Tells the FTP server to change its file-transfer type to the one
- given, immediately. See [275]SET FTP TYPE for details.
-
- [ [276]Top ] [ [277]FTP Top ] [ [278]C-Kermit Home ] [ [279]Kermit Home
- ]
-
-3.5. Uploading Files With FTP
-
- Uploading means sending files from the client (Kermit) to the FTP
- server. The basic command for uploading files with FTP is PUT:
-
- FTP PUT [ switches ] [ filespec [ as-name ] ]
- Uploads (sends) the file or files that match the file
- specification, which may include wildcards, to the server. If no
- filespec is given, the names of files to send are taken from the
- /LISTFILE: file, if any, otherwise from the SEND-LIST, if any.
- Unless you go out of your way to prevent it, Kermit determines
- the transfer mode (text or binary) for each file automatically,
- and switches automatically on a per-file basis. If an as-name is
- given, the file is sent under that name instead of its own (if
- an as-name is given with a wildcard filespec, the result is a
- bit more complicated, and is explained later in this section).
-
- Unlike normal FTP clients, Kermit does not prompt you by default (or at
- all) for each file; it just sends them, just as it does with Kermit
- protocol. The filespec can be a literal filename or a Kermit pattern,
- described in:
-
- [280]http://www.columbia.edu/kermit/ckermit70.html#x4.9
-
- Kermit patterns are equivalent to C-Shell patterns and provide a fair
- amount of flexibility in selecting which files to send, which is
- augmented by the file-selection switches presented in [281]Section
- 3.5.1.
-
- FTP MPUT [ switches ] filespec [ filespec [ ... ] ]
- FTP MPUT is just like FTP PUT except it allows you to give more
- than one file specification, and it does not allow an as-name in
- the file list. However, as-names can be given to either PUT or
- MPUT with the /AS-NAME: switch.
-
- If a PUT or MPUT command results in one file being uploaded, it
- succeeds if the file is uploaded completely and fails otherwise. If
- more than one file is selected for upload, success or failure depends
- on the [282]FTP ERROR-ACTION setting; if it is PROCEED (the default
- setting), then the [M]PUT command succeeds if at least one of the files
- was completely uploaded, and fails otherwise, If FTP ERROR-ACTION is
- QUIT, the [M]PUT command succeeds if all selected files were uploaded
- successfully, and fails if any file failed.
-
- FTP uploads may be interrupted just like Kermit uploads. While the
- transfer is in progress, type:
-
- X to interrupt the current file and go on to the next file.
- Z to cancel the current file and all remaining files.
- ^C (Control-C): Like Z, but might act more quickly.
-
- MPUT may be used as in regular FTP clients, but it is not required to
- send multiple files; in Kermit it is required only if you want to give
- multiple file specifications. Examples:
-
- ftp put oofa.txt ; Send a single file oofa.txt
- ftp put oofa.txt budget.txt ; Send single file oofa.txt as budget.txt
- ftp put *.txt ; Send all *.txt files
- ftp mput *.txt ; Send all *.txt files (same as "put *.txt")
- ftp mput *.txt foo.bar ; Send all *.txt files plus foo.bar
-
- The distinction between PUT and MPUT is important only when more than
- one filespec is given, just like the distinction between Kermit SEND
- and MSEND:
-
- ftp put oofa.txt budget.txt ; Send oofa.txt AS budget.txt
- ftp mput oofa.txt budget.txt ; Send oofa.txt AND budget.txt
-
- If the source file specification includes any path segments, for
- example:
-
- put /tmp/oofa.txt
- put subdir/another/andanother/oofa.txt
-
- the path portion is stripped from the filename that is sent to the
- server. However, if an as-name contains a path, it is retained.
- Examples:
-
- ftp put /usr/doc/oofa.txt ; Send as "oofa.txt".
- ftp put oofa.txt /tmp/oofa.txt ; Send as "/tmp/oofa.txt"
-
- The latter example sends the file oofa.txt from your current local
- directory to the server's /tmp directory. This works only if the server
- uses the same directory notation that you used in the as-name AND the
- given directory already exists on the server AND if you have write
- access to it.
-
- Use caution when uploading from a case-sensitive file system, such as
- UNIX, to a file system that is not case sensitive, such as Windows or
- VMS. If you have two files in UNIX, AA and aa and upload both of them,
- the second one will overwrite the first. The only way around this
- provided by FTP protocol is its "unique server names" feature (SET FTP
- UNIQUE-SERVER-NAMES or the /UNIQUE switch described below).
-
-3.5.1. FTP PUT Switches
-
- FTP PUT and MPUT are similar in format and behavior to the regular
- Kermit SEND and MSEND commands, and they allow most of the same
- optional switches:
-
-C-Kermit>ftp put ? Filename, or switch, one of the following:
- /after: /larger-than: /rename-to:
- /array: /listfile: /server-character-set:
- /as-name: /local-character-set: /server-rename-to:
- /before: /move-to: /simulate
- /binary /nobackupfiles /smaller-than:
- /command /nodotfiles /tenex
- /delete /nofollowlinks /text
- /dotfiles /not-after: /transparent
- /error-action: /not-before: /type:
- /except: /permissions: /update
- /filenames: /quiet /unique-server-names
- /filter: /recover
- /followlinks /recursive
-
- Since most of these switches are common to Kermit's SEND and MSEND
- commands, they described only briefly here. For greater detail see:
-
- [283]http://www.columbia.edu/kermit/ckermit70.html#x1.5 (explanation
- of switches)
- [284]http://www.columbia.edu/kermit/ckermit70.html#x4.7
- (file-transfer switches)
-
- First the file-selection switches:
-
- /AFTER:date-time
- /BEFORE:date-time
- /NOT-AFTER:date-time
- /NOT-BEFORE:date-time
- Only send those files modified on or after or before the given
- date and time. These switches can be combined to select files
- modified between two date/times. Various date-time formats are
- accepted; if the date-time contains spaces, it must be enclosed
- in braces or doublequotes. See
- [285]http://www.columbia.edu/kermit/ckermit70.html#x1.6 and
- [286]Section 8.13 of this document for details about date-time
- formats. Examples:
-
- ftp put /after:{1 jan 2000 0:00:00} *
- ftp put /after:-5days *
-
- /LARGER-THAN:number
- /SMALLER-THAN:number
- Only send files larger (smaller) than the given number of bytes
- (octets). These switches can be combined to select files in a
- certain size range.
-
- /TYPE:{TEXT,BINARY}
- Only send files that are the given type, which is determined for
- each file just before sending it by file scanning. BINARY
- includes TENEX; if you have included a /TENEX switch, or
- previously given a [SET] FTP TYPE TENEX command, binary files
- are sent in TENEX, rather than BINARY mode.
-
- /[NO]DOTFILES
- [Don't] include files whose names begin with dot (.). By
- default, such files are not included unless your filespec
- explicitly mentions them.
-
- /NOBACKUPFILES
- Don't include files whose names end with .~nnn~, where nnn is a
- number, e.g. oofa.txt.~27~. These are backup files created by
- Kermit, EMACS, and other applications. By default, backup files
- are included.
-
- /NOFOLLOWLINKS
- (UNIX only) Skip over symbolic links rather than following them
- (default). This applies to wildcard and/or recursive [M]PUTs; if
- a single filename is given, and it happens to be a symbolic
- link, the file it points to is sent.
-
- /FOLLOWLINKS
- (UNIX only) Always follow (resolve) symbolic links, even in
- wildcard or recursive [M]PUTs. Use with caution. Watch out for
- circular links, endless loops, etc.
-
- /EXCEPT:pattern
- Exception list -- don't send files whose names match the given
- pattern. See [287]Section 1.5.4 of the [288]C-Kermit 7.0 Update
- Notes for details. If you want to exclude a directory from a
- recursive [M]PUT, use /EXCEPT:{dirname/*}.
-
- /RECURSIVE
- Sends the desired files from the current (or given) directory,
- plus all directories beneath it, including empty directories,
- replicating the directory structure on the server. No special
- capabilities are required in the server, but of course your
- login ID on the server must have the appropriate access and
- permission to create directories. Recursive PUTs work not only
- between like platforms (e.g. UNIX to UNIX) but also between
- unlike ones (e.g. UNIX to VMS or Windows), in which case
- text-file format differences are handled by Kermit's automatic
- text/binary mode switching ([289]Section 4) and character-set
- translation ([290]Section 3.7). Synonym: /SUBDIRECTORIES.
-
- /UPDATE
- Send only files that have changed since last time ([291]Section
- 3.5.2).
-
- /ARRAY:arrayname
- The "file" to be sent is an array, or a segment of one, rather
- than a real file. In this case the other selection switches
- don't apply. The array contents are sent in text mode, and each
- array element is treated as a line. Example:
-
- ftp put /as-name:array.txt /array:&a
-
- (or, to send a segment of the array, /array:&a[100:199]). If you
- don't include an /AS-NAME, a name of "_array_x_" is used (where
- x is the array letter). If you include this switch, most other
- switches are meaningless and ignored.
-
- /COMMAND
- The "file" to be sent is the standard output of a command,
- rather than a real file. It is sent in text or binary mode
- according to the prevailing FTP TYPE, which can be overridden
- with a /TEXT or /BINARY switch. Example: Example:
-
- ftp put /command /as-name:{userlist} {finger | sort -r}
-
- /LISTFILE:filename
- Tells Kermit to obtain the list of files to be sent from the
- file whose name is given. This file must contain one file
- specification (which may be wild) per line. If the list includes
- files from different directories, such as a recursive listing of
- a directory tree, the paths are recreated on the server (if
- possible) if you include the /RECURSIVE switch; otherwise all
- the files are sent to the current directory on the server.
-
- Now the other switches:
-
- /AS-NAME:text
- If a single file is being sent, send it with the given text as
- its name. If multiple files are being sent, the text must be a
- template that includes variables such as \v(filename),
- \v(filenumber), \v(ntime), to allow dynamic creation of each
- name. The same applies to the as-name field of the FTP PUT
- command. If this switch is not included (and an as-name is not
- included as the second filename to PUT), each file is sent with
- its own name.
-
- /BINARY
- /TEXT
- /TENEX
- Forces this upload to take place in the given mode, regardless
- of the current FTP TYPE setting, and without automatic
- text/binary switching. /ASCII is a synonym for /TEXT.
-
- /FILTER:command
- Specifies that the file(s) is/are to be passed through the given
- command or pipeline on their way to the server. Example:
-
- ftp put /binary /filter:{gzip -c \v(filename)} /as-name:\v(filename).gz *
-
- /TRANSPARENT
- /LOCAL-CHARACTER-SET:name
- /SERVER-CHARACTER-SET:name
- Character-set translation for text files, explained in
- [292]Section 3.7.
-
- /ERROR-ACTION:{PROCEED,QUIT}
- Overrides the prevailing [293]FTP ERROR-ACTION for the duration
- of this PUT or MPUT command only.
-
- /RECOVER
- Resume an interrupted transfer where from the point of
- interruption (explained in [294]Section 3.5.2). Synonym:
- /RESTART.
-
- /DELETE
- Tells Kermit to delete each source file immediately after, and
- only if, it has been uploaded completely and successfully. This,
- in effect, moves the file from the client to the server.
-
- /MOVE-TO:directory
- Tells Kermit to move each source file to the named local
- directory after, and only if, it has been uploaded completely
- and successfully.
-
- /RENAME-TO:template
- Tells Kermit to rename each (local) source file according to the
- given template after, and only if, it has been uploaded
- completely and successfully. The template works as in /AS-NAME.
-
- /SERVER-RENAME-TO:template
- Tells Kermit to ask the server to rename each file according to
- the given template as soon as, and only if, it has been received
- completely and successfully. The template works as in /AS-NAME.
- Requires write and rename access on the server, so doesn't
- usually work with (e.g.) anonymous uploads to public incoming
- areas where the permissions don't allow renaming. Examples:
-
- ftp mput /server-rename:\v(filename).ok *
- Appends ".ok" to each filename on the server when it's
- finished uploading.
-
- ftp mput /as-name:\v(filename).tmp /server-rename:\v(filename) *
- This is the reverse of the previous example; it uses a
- temporary name while uploading is in progress and reverts
- the file to its real name when uploading is complete.
-
- ftp mput /as-name:\v(filename)
- /server-rename:../final/\v(filename) *
- Moves the file from the working directory to a final
- directory when the upload is complete, but in this case
- you have to know the pathname syntax of the server. If the
- rename fails, the [M]PUT command fails according to the
- [295]FTP ERROR-ACTION selection.
-
- /FILENAMES:{AUTOMATIC,CONVERTED,LITERAL}
- Overrides the [296]FTP FILENAMES setting for this upload only.
-
- /PERMISSIONS:{ON,OFF}
- Overrides the [297]FTP PERMISSIONS setting for this upload only.
-
- /UNIQUE
- Tells Kermit to tell the server to give [298]unique names to
- incoming files that would otherwise overwrite existing files
- that have the same name. This switch conflicts with /UPDATE,
- /RECOVER, /PERMISSIONS, and /SERVER-RENAME since the client has
- no way of knowing the name assigned by the server.
-
- /QUIET
- Don't display file-transfer progress or statistics.
-
- /SIMULATE
- Shows which files would be sent without actually sending them.
- Useful (for example) with /UPDATE (next section). The results
- are shown in the file-transfer display (if it is not disabled)
- and in the transaction log (if one is active). Hint: use SET
- TRANSFER DISPLAY BRIEF.
-
-3.5.2. Update Mode
-
- When you include the /UPDATE switch, this means to skip sending any
- file that already exists on the server if the local file's modification
- date/time is not later than that of the corresponding file on the
- server. Here is a typical application for update mode: Suppose that on
- Computer A, you maintain a large set of files (say, a collection of Web
- pages and graphics images, or the source files for a software
- application), and you need to keep a parallel copy on another Computer,
- B. Of course you could upload the entire collection every day:
-
- cd source-directory
- ftp computerb.xyzcorp.com
- ( authentication details... )
- ftp cd target-directory
- ftp put [ switches ] *
-
- But if the total size is large or the network slow, this would be
- unnecessarily time-consuming. Worse, if other users or sites had to
- update whenever new files appeared in B's directory, this would cause
- them unnecessary work. By including the /UPDATE switch:
-
- ftp put /update [ other-switches ] *
-
- only those files that changed since last time are uploaded. Here's how
- it works. For each local file that is selected for uploading:
-
- * The remote filename is determined in the normal way, according to
- the [299]FTP FILENAMES setting, /FILENAMES switch, or the as-name,
- if any.
- * Kermit sends an MDTM (modification time) command for the
- corresponding remote filename to the server.
- * If the server does not understand the MDTM command, the file is
- sent.
- * If the server can't find a file with the given name, the file is
- sent.
- * If the local file's modification time is later than that of the
- remote file, the file is sent.
- * Otherwise -- the remote file exists but its modification time is
- equal to or earlier than that of the local file -- the file is
- skipped.
-
- All time comparisons take place in Coordinated Universal Time
- (UTC)([300]1), also known as GMT or Zulu time: Timezone 0; standard
- time, without daylight savings.
-
- WARNING: Some FTP servers, such as Novell NWFTPD.NLM, ignore or
- misimplement the FTP specification and send local time rather than
- UTC.
-
- Update mode is useful only when always used in the same direction. When
- you upload (PUT) a file with FTP, the destination file receives the
- current timestamp on the server's computer, not the original file's
- timestamp ([301]2). If you try to FTP PUT /UPDATE the same file again,
- it will be skipped (as expected) since the remote copy is newer.
- However, if you try to FTP GET /UPDATE the same file ([302]Section
- 3.6), it will be transferred for the same reason.
-
- To check the availability of PUT /UPDATE on a particular connection,
- issue an FTP MODTIME command for a file that is known to exist on the
- server. If it succeeds, PUT /UPDATE should work and in that case, you
- can run a procedure like the one above every day: the first time, it
- sends all the files; after that, it sends only the ones that changed.
- If a transaction log is active, a notation is included for any files
- that are skipped.
-
- Notes:
- 1. Why is Coordinated Universal Time abbreviated UTC? From the
- [303]National Institute of Standards and Technology FAQ: "In 1970
- the Coordinated Universal Time system was devised by an
- international advisory group of technical experts within the
- International Telecommunication Union (ITU). The ITU felt it was
- best to designate a single abbreviation for use in all languages in
- order to minimize confusion. Since unanimous agreement could not be
- achieved on using either the English word order, CUT, or the French
- word order, TUC, the acronym UTC was chosen as a compromise."
- 2. The Kermit FTP client is unusual in that, when downloading only, it
- can set the received file's date from the file's date on the
- server, but this should not affect the update feature. When
- uploading to an FTP server, however, there is no mechanism for the
- client to set the date of the uploaded file on the server.
-
-3.5.3 Recovery
-
- Suppose that while you are uploading a large file over a slow
- connection, the connection is lost before the entire file is
- transferred. With most FTP clients, you would have to start over, thus
- resending the portion of the file that was sent already, and that is
- already on the server. But Kermit's /RECOVER switch (Synonym: /RESTART)
- lets you continue an interrupted transfer from the point of failure,
- thus transferring only the part that wasn't sent already. The
- prerequisites for recovery are:
-
- * The transfer must be in BINARY mode, or else the client and server
- must reside on like systems (e.g. both on some form of UNIX).
- * The FTP server must support the SIZE command.
-
- Here's how it works. When you include the /RECOVER switch:
-
- * Kermit checks for conflicting switches, such as /UPDATE and
- /UNIQUE; if /RECOVER is given with these switches an error occurs.
- If /RECOVER is given in other circumstances where it could serve no
- useful purpose (e.g. with arrays, pipes, or filters), it is
- ignored.
-
- If the switch is accepted, then for each selected file:
-
- * If it is not binary (determined by scanning) and the client and
- server are not on like platforms, recovery is canceled (the entire
- file is sent). Otherwise:
- * A SIZE command is sent for the file (using its remote name). If the
- reply indicates the file was not found, or the SIZE command was not
- understood, or any other kind of error, recovery is canceled.
- Otherwise:
- * A MDTM (modification time) command is sent for the file. If a valid
- reply is received, and the modification time of the local file is
- later than that of the remote file, recovery is canceled.
- Otherwise:
- * If the sizes of the two files are identical, the file is not sent.
- Otherwise:
- * Kermit seeks to the recovery spot in the local file, tells the
- server to APPEND the data which is about to arrive to the remote
- file, and then sends the data starting at the recovery point.
-
- To safeguard file integrity, recovery is not attempted unless all the
- preconditions are met. For the widest possible usefulness, APPEND is
- used rather than RESTART. For stream transfers (the only kind that
- Kermit supports) the results are the same.
-
- By design, the /RECOVER switch can be included with any FTP PUT or MPUT
- command, even if it specifies a group of files. This allows you to
- resume an interrupted batch transfer from where it left off. The files
- that were already completely sent are skipped, the file that was
- interrupted is recovered, and the remaining files are uploaded.
-
- By the way, it doesn't matter how the original partial file was
- uploaded -- FTP, Kermit, Zmodem, etc: as long as the preconditions are
- met, it can be recovered with FTP PUT /RECOVER, or for that matter also
- using Kermit protocol and SEND /RECOVER.
-
- A word of caution, however, when the original upload was in text mode
- with character-set translation ([304]Section 3.7):
-
- * If the original upload involved a translation from one single-byte
- character set to another (e.g. Code Page 850 to Latin-1), recovery
- is safe if you specify the same translations for the recovery. If
- you don't, the resulting file will contain a mixture of character
- sets.
- * If the original upload involved a translation that changed the size
- of the file (e.g. from an alphabetic Code Page or Latin Alphabet to
- Unicode, or vice versa), recovery is NOT safe, even if you specify
- the same translations.
-
- Kermit has no way of knowing anything about the previous upload. As a
- safeguard, an error occurs if you include /RECOVER and also specify a
- character-set of UCS2 or UTF8, since recovery can't possibly work in
- that situation. Otherwise, it's up to you to avoid unsafe recovery
- operations.
-
- [ [305]Top ] [ [306]FTP Top ] [ [307]C-Kermit Home ] [ [308]Kermit Home
- ]
-
-3.6. Downloading Files With FTP
-
- Although uploading files with Kermit's FTP client is just as easy and
- flexible as sending files with Kermit protocol, the same is not always
- true for downloading because FTP servers lack some of the capabilities
- of a Kermit server:
-
- * If you want to get more than one file, you have to use MGET, not
- GET, since the underlying FTP protocol is different in the two
- cases. Kermit can't "autodetect" which one you mean, as it can with
- PUT and MPUT, since it can't be expected to know the wildcard
- syntax of the remote platform and/or FTP server (the same is true
- for all other FTP clients). To complicate matters, FTP protocol now
- includes two underlying mechanisms (NLST and MLSD) for
- accomplishing MGET operations and, as explained in [309]Section
- 3.11, the two behave differently.
- * Automatic text-binary mode switching is not done by the server. It
- can be done by the client (Kermit), but in this case it is not
- based on a file scan (since there is no way for Kermit prescan a
- server file), but rather on the filename, using C-Kermit 7.0
- [310]filename patterns.
- * Some options that are available with FTP PUT can not be used with
- FTP [M]GET or don't work the same way:
- /PERMISSIONS (FTP protocol has no mechanism for this).
- /[NOT-]BEFORE, /[NOT-]AFTER (because of the timezone problem).
- /RECOVER works only in binary mode. /RECURSIVE has limited
- utility.
-
- The commands for downloading are:
-
- SET FILE DOWNLOAD-DIRECTORY [ directory ]
- As with Kermit transfers, this command, if given, tells C-Kermit
- where to store incoming files in the absence of a specific
- as-name. If not given, incoming files are stored as indicated by
- the as-name, if any, otherwise in the current directory, just as
- with Kermit transfers. The more verbose transfer display formats
- give the full pathname of each received file, and, in case you
- have trouble finding a downloaded file afterwards, its full path
- is also listed in the transaction log (if you kept one), and you
- can also ask Kermit where it went with the [311]WHERE command.
-
- SET FTP GET-FILETYPE-SWITCHING { ON, OFF }
- ON by default, causing Kermit to switch automatically into text
- or binary mode for each file based on whether its name matches a
- text pattern or binary pattern. Set this OFF, or use a /TEXT,
- /BINARY, or /TENEX switch to defeat this feature. Use SHOW
- PATTERNS to see the current pattern list.
-
- [ FTP ] GET [ switches ] filename [ as-name ]
- Asks the server to send the given file, and if it comes, stores
- it locally under the given as-name, if any, otherwise under its
- original name (modified according to the selected filename
- conversion option), in your download directory, if you have
- specified one, otherwise in the directory indicated in the
- as-name, if any, otherwise in your current directory. If you
- accidentally use a wildcard in the filename ("get *.txt") the
- server will reply with a message like "File not found" (unless
- there is a file whose name actually is "*.txt"). If FTP
- GET-FILETYPE-SWITCHING is ON, and in the absence of any GET
- switches to override it, the file is transferred in binary mode
- if it matches any of Kermit's binary name patterns, and in text
- mode if it matches any of Kermit's text name patterns, and in
- the prevailing FTP TYPE if it matches none of these patterns.
-
- [ FTP ] MGET [ switches ] filespec [ filespec [ filespec [ ... ] ] ]
- Like GET, but for multiple files. One or more file
- specifications can be given, and any or all (or none) of them
- can contain wildcards or can be directory names. The file list
- may not include an as-name, but you can still give one with the
- /AS-NAME: switch.
-
- In both the FTP GET and MGET commands, any filenames that contain
- spaces must be enclosed in braces or doublequotes (see [312]Section 5
- for details).
-
- FTP downloads may be interrupted just like Kermit transfers. While the
- transfer is in progress, type:
-
- * X to interrupt the current file and go on to the next file.
- * Z (or Control-C) to cancel the current file and all remaining
- files.
-
- Before proceeding, a brief word about temporary files. In FTP protocol,
- the MGET command works by requesting a file list from the server, and
- then (internally) issuing a GET command (FTP RETR protocol directive)
- for each file. The file list returned by the server can be any size at
- all, so in case it is huge, we don't store it in memory; instead we put
- it in a temporary file. For troubleshooting purposes, you should be
- aware of two points:
-
- 1. The location of the temporary file is chosen according the TMP or
- TEMP environment variables. If neither of these variables is
- defined, you might need to define it. In case there is not enough
- space on the indicated disk or partition for the server's file
- list, you might need to either clean up the temporary area, or
- redefine the environment variable to indicate a different area that
- has sufficient space.
- 2. If you want to look at the list yourself, use SET FTP DEBUG ON.
- This tells Kermit to (a) give you the full pathname of the
- temporary file at the end of each MGET command, and (b) not to
- delete it, as it normally does.
-
-3.6.1. FTP GET Switches
-
- The following switches are available with FTP GET and MGET:
-
- /TEXT
- Specifies a text-mode transfer. Overrides the global FTP TYPE
- setting and filename pattern-matching for the duration of the
- current command only, All files are downloaded in text mode.
- Synonym: /ASCII.
-
- /BINARY
- Specifies a binary-mode transfer. Overrides the global FTP TYPE
- setting and filename pattern-matching for the duration of the
- current command only. All files are downloaded in binary mode.
-
- /TENEX
- Like /BINARY but specifies a special binary transfer mode to be
- used when getting 8-bit binary files from a 36-bit platform such
- as TOPS-10, TOPS-20, or TENEX. All files are downloaded in the
- special binary mode.
-
- /RECOVER
- This instructs Kermit to try to recover an incomplete download
- from the point of failure. Works only in binary mode, and only
- if the server supports the (not-yet-standard) FTP "REST"
- directive. See [313]Section 3.6.3 for details. Synonym:
- /RESTART.
-
- /FILENAMES:{CONVERTED,LITERAL}
- Overrides the [314]FTP FILENAMES (filename conversion) setting
- for this download only, forcing incoming filenames to be either
- converted or taken literally.
-
- /AS-NAME:text
- For GET, this is equivalent to giving an as-name after the
- filename. For MGET, this is the only way to specify alternative
- names for the incoming files. With MGET, the /AS-NAME text
- should (must) contain a Kermit variable, usually \v(filename) or
- \v(filenumber). Example:
-
- mget /text /as-name:\v(filename).new *.c
-
- This gets all ".c" files and stores them with "
-
- .new" appended to their names. See the [315]C-Kermit 7.0 Update
- Notes for details.
-
- /COMMAND
- This specifies that the incoming file is to be written to the
- standard input of a command, rather than to a file. The command
- name is the as-name from the GET command or the /AS-NAME
- argument. If you need to refer to the incoming file's name in
- the command, use \v(filename). See the description of the
- regular Kermit [316]GET /COMMAND command for details and
- examples.
-
- /QUIET
- Transfers the files quietly; don't put up a file-transfer
- display.
-
- /ERROR-ACTION:{QUIT,PROCEED}
- This switch affects only MGET. If an error occurs with a
- particular file, this tells whether to go on to the next file
- (PROCEED) or to stop right away and fail (QUIT). The default is
- PROCEED.
-
- The file selection switches are:
-
- /EXCEPT:{pattern} or /EXCEPT:{{pattern}{pattern}{...}}
- Exception list for MGET; skip downloading any file whose name
- matches any of the given patterns (when using the second format,
- up to 64 patterns may be specified). [317]CLICK HERE for syntax
- details.
-
- /SMALLER-THAN:number
- Download only files whose size is smaller than the given number
- of bytes (octets). Requires that the FTP server support the SIZE
- or MLSD directive.
-
- /LARGER-THAN:number
- Download only files whose size is greater than the given number
- of bytes. Requires that the FTP server support the SIZE or MLSD
- directive.
-
- /NOBACKUPFILES
- During MGET, don't download any files whose names end with
- backup suffixes (.~n~ where n is a number).
-
- /NODOTFILES
- During MGET, don't download any files whose names begin with
- period (.). Equivalent to /EXCEPT:{.*}.
-
- /LISTFILE:local-filename
- The given file contains a list of files to GET, one per line.
- Filenames in the listfile can contain wildcard characters in the
- syntax of the server. There is no limit on the number of lines
- in the listfile.
-
- /NAMELIST:local-filename
- If this switch is given, then instead of actually retrieving the
- selected files, the GET command retrieves a list of the names of
- the files that would be retrieved, and places it in the
- specified file. The resulting file is an ordinary text file,
- with one filename per line, suitable for reading by a person, or
- processing by a computer program, including Kermit itself (FOPEN
- / FREAD / FWRITE / FCLOSE), and as /FILELIST: file. If the
- filename is omitted or given as "-" (dash, hyphen), the list
- goes to the screen. NOTE: if you want a copy of the complete
- list sent by the server, use SET FTP DEBUG ON, perform an MGET,
- and the temporary file containing the list will be kept rather
- than deleted (and Kermit tells you its name).
-
- /UPDATE, /COLLISION:keyword
- Explained in [318]Section 3.6.2.
-
- /RECURSIVE
- This means to try to download an entire directory tree, rather
- than just files from a particular directory. In fact, FTP
- protocol does not provide a method to request a recursive
- download (unless the server supports MLSD; see [319]Section
- 3.11), so this works only if the FTP server does it anyway,
- without being asked, as some do. In this case, Kermit detects
- that names in the returned file list contain directory
- separators, and therefore attempts to create the needed
- directories as the files arrive. But this can work only if the
- server is on the same kind of platform as the client, so the
- pathname syntax can be recognized, and also because the server
- does not switch between text and binary mode, which would be
- vital for cross-platform transfers. Use with caution. Synonym:
- /SUBDIRECTORIES.
-
- Even when the server does not provide recursive file lists,
- [M]GET /RECURSIVE forces Kermit to replicate any directory
- structure implied or expressed by the server's file list. For
- example:
-
- get somepath/somefile
-
- Gets the file named somefile from the server's somepath
- directory and puts it Kermit's current (or download) directory,
- whereas:
-
- get /recursive somepath/somefile
-
- creates the path locally and then puts the file in it. Similarly
- for MGET:
-
- mget */data/*
-
- downloads all the files in all the data subdirectories of all
- the subdirectories of the server's current directory and stores
- them locally in Kermit's current (or download) directory,
- whereas:
-
- mget /recursive */data/*
-
- re-creates the server's directory structure locally.
-
- The FTP protocol does not include explicit mechanisms for recursion, so
- Kermit builds upon what is available. Although an Internet draft
- describes a mechanism ("MLSD") that would allow protocol-driven
- recursion, similar to Kermit's File Attribute packets (circa 1984), it
- has not yet attained RFC or standard status, and servers are not yet
- widely available that offer this feature. In the meantime, the
- effectiveness of MGET /RECURSIVE depends on the FTP server
- implementation. If the server returns a recursive list in response to
- the standard NLST command (whose behavior is ill-defined), Kermit's FTP
- MGET /RECURSIVE command uses it to re-create the remote directory tree
- locally. If the server supports MLSD, C-Kermit 8.0.206 and Kermit 95
- 2.1 and later are able to sense it automatically and use it, as
- described below in [320]Section 3.11.
-
- The /BEFORE:, /AFTER:, /NOT-BEFORE:, and /NOT-AFTER: switches are not
- available for downloading because of the confusion with timezones.
- Would the given times be in the local timezone, the server's timezone,
- or GMT? The FTP server's directory listings show its own local times
- but since we don't know what timezone the server is in, there's no way
- to reconcile our local times with the server's. Similarly, /PERMISSIONS
- can't be preserved in downloads because FTP protocol provides no means
- of querying the server for a file's permission.
-
- Source-file disposition switches:
-
- /DELETE
- Each file that is downloaded successfully is to be deleted from
- the server. Requires the appropriate file access rights on the
- server.
-
- /SERVER-RENAME-TO:template
- Asks the server to rename each (remote) source file immediately
- after, and only if, it is sent correctly. See [321]PUT
- /SERVER-RENAME-TO: for details.
-
- Destination-file disposition switches:
-
- /TO-SCREEN
- Displays the incoming file on the screen rather than storing it
- on disk. If this switch is given, the /RENAME-TO and /MOVE-TO
- switches are ignored, the file-transfer display is suppressed,
- and the given file(s) is/are shown on the screen. Can be used
- with /FILTER, e.g.
-
- get /text /to-screen /filter:more oofa.txt
-
- In fact, you should always use /TO-SCREEN with /FILTER or
- /COMMAND when the command would result in displaying the
- incoming file on the screen; otherwise C-Kermit would have no
- way of knowing to suppress its file transfer display (since it
- can't be expected to know what the command or filter does).
-
- /RENAME-TO:template
- Each file that is downloaded is to be renamed as indicated if
- and only if it was received completely and without error. The
- template can be literal text or can contain variables that are
- evaluated for each file. For MGET, the text must contain
- variables; for GET it can be a literal string. The \v(filename)
- variable contains the name of the current file, so:
-
- ftp mget /rename-to:\v(filename).ok *
-
- causes each file that is successfully downloaded to have ".ok"
- appended to its name. For details see [322]Section 4.1 of the
- [323]C-Kermit 7.0 Update Notes.
-
- /MOVE-TO:text
- Just like /RENAME-TO:, except the text denotes the name of a
- directory to which successfully downloaded files are to be
- moved. If the directory does not exist, it is created.
-
- The file transfer display does not show the /MOVE-TO or /RENAME-TO
- value, since the incoming file has not yet been moved or renamed.
-
-3.6.2. Filename Collisions
-
- What should happen if an incoming file has the same name as an existing
- file in the same directory? By default, Kermit's FILE COLLISION setting
- applies: BACKUP, RENAME, UPDATE, DISCARD, etc, as described in
- [324]Using C-Kermit. Kermit's default FILE COLLISION setting is BACKUP
- (rename the existing file and store the incoming file under its own
- name) and therefore this is also the default FTP collision action.
-
- The name under which an incoming file is to be stored is determined as
- follows:
-
- * If an as-name was given, the as-name is used. Otherwise:
- * If the client and server platforms are alike or [325]FTP FILENAMES
- is set to LITERAL (or the /FILENAMES:LITERAL switch was given for
- this download), the incoming filename is used literally. Otherwise:
- * The incoming filename is converted to a form that is friendly to
- the local platform. For UNIX, for example, incoming filenames that
- are all uppercase (as they might be from, say, VMS or an IBM
- mainframe) are converted to lowercase.
-
- If the resulting name coincides with the name of a local file that
- already exists, we have a filename collision. Collisions are handled
- according to the currently selected collision action:
-
- SET FTP COLLISION { BACKUP, RENAME, UPDATE, DISCARD, APPEND, OVERWRITE
- }
- This establishes a filename collision for FTP, separate from the
- Kermit one. The initial FTP collision setting is inherited from
- Kermit's FILE COLLISION setting when the first FTP command is
- given, but subsequent changes to Kermit's FILE COLLISION setting
- do not affect the FTP COLLISION setting. SHOW FTP tells the
- current FTP COLLISION setting.
-
- FTP GET /COLLISION:{BACKUP,RENAME,UPDATE,DISCARD,APPEND,OVERWRITE}
- Overrides the current FTP COLLISION action for this download
- only.
-
- FTP GET /UPDATE
- This is equivalent to GET /COLLISION:UPDATE, and is included for
- symmetry with PUT /UPDATE
-
- FTP GET /UPDATE and /COLLISION:UPDATE mean to download only those files
- whose modification dates on the server are later than those on the
- client. Date-time comparisons are done in Coordinated Universal Time
- (UTC, GMT, ZULU). The command:
-
- FTP MGET /COLLISION:APPEND /AS-NAME:newfilename *.*
-
- Downloads all matching remote files into a single local file (in
- whatever order the server sends them).
-
-3.6.3. Recovery
-
- Recovery is available for downloads too, but there are some differences
- from the uploading case described in [326]Section 3.5.3:
-
- * The transfer must be in BINARY mode. It can not be in text mode,
- even if the FTP server is on the same kind of platform as Kermit,
- and even if there is no character-set translation. The original
- download must also have been in binary mode.
- * The FTP server must support the REST ("restart") directive.
- Unfortunately, this is not a standard command; at this writing, it
- is described only in an Internet Draft, not an RFC or Internet
- Standard, but nevertheless it is found in several popular FTP
- servers, such as [327]ProFTPD.
-
- Here's how download recovery works:
-
- * Kermit checks for conflicting switches, such as /UPDATE, /COMMAND,
- or /FILTER. If /RECOVER is given with these switches an error
- occurs.
- * The prevailing transfer mode (SET FTP TYPE) must be BINARY. If it
- is not, the /BINARY switch must have been included with the FTP
- [M]GET command.
-
- If the /RECOVER switch is accepted, then for each selected file:
-
- * A SIZE command is sent for the file (using its remote name). If the
- reply indicates the file was not found, or the SIZE command was not
- understood, or any other kind of error, recovery is canceled (i.e.
- the entire file is downloaded).
- * If the sizes of the two files are identical, the file is not sent.
- Otherwise:
- * Kermit sends the REST directive to the server, indicating the size
- of the local file. If the server responds affirmatively, Kermit
- opens the local file in append mode and appends the incoming data
- to it. Otherwise, recovery is canceled and the entire file is
- downloaded.
-
- The /RECOVER switch can be included with any FTP GET or MGET command,
- even if it specifies a group of files. This lets you resume an
- interrupted batch transfer from where it left off. The files that were
- already completely sent are skipped, the file that was interrupted is
- recovered, and the remaining files are uploaded. BUT... unlike with
- uploading, where this can be done with any mixture of text and binary
- files, when downloading, it can only be done if all the files are
- binary.
-
- It doesn't matter how the original partial file was downloaded -- FTP,
- Kermit, HTTP, Zmodem, etc: as long as the preconditions are met, it can
- be recovered with FTP [M]GET /RECOVER, or for that matter also with GET
- /RECOVER (using Kermit protocol).
-
- [ [328]Top ] [ [329]FTP Top ] [ [330]C-Kermit Home ] [ [331]Kermit Home
- ]
-
-3.7. Translating Character Sets
-
- A possibly unique feature of Kermit's FTP client is its ability to
- convert character sets when transferring files in text mode,
- independent of the capabilities of the FTP server, as well as to
- translate the character sets of filenames regardless of transfer mode.
- For compatibility with existing FTP clients, and because there is a
- certain performance penalty, Kermit won't do this unless you ask for
- it. If you enable this feature, you need to inform Kermit of the
- character set (to be) used on the server and in some cases (explained
- below) also the local file character set. This discussion assumes you
- know a bit about character sets (as you must if you have to use them);
- see Chapter 16 of [332]Using C-Kermit for a detailed treatment. The
- Kermit commands for FTP character-set conversion are:
-
- SET FTP CHARACTER-SET-TRANSLATION { ON, OFF }
- Whether to translate character sets when transferring text files
- with FTP. OFF by default. Set this to ON to enable character-set
- translation for subsequent FTP uploads and downloads.
-
- SET FTP SERVER-CHARACTER-SET [333]name
- Text character set (to be) used by the server. Most FTP servers
- are ignorant of character sets, so all translations are done
- unilaterally by Kermit's FTP client. This means that when
- downloading files, you must know in advance the character-set
- used in the files you are downloading (and in their names). When
- uploading, you must specify the character-set to which local
- filenames and text-file contents are to be translated for
- transmission to the server. If you SET FTP
- CHARACTER-SET-TRANSLATION ON but do not specify an FTP
- SERVER-CHARACTER-SET, [334]UTF8 is used, since this is the new
- Internet standard international character set; it is upwards
- compatible with ASCII and it encompasses most written languages
- and therefore does not favor any particular group of people, as
- any other default would do. If you SET FTP SERVER-CHARACTER-SET
- to something (anything) when FTP CHARACTER-SET TRANSLATION is
- OFF, this also sets the latter ON.
-
- SET FILE CHARACTER-SET [335]name
- This is the regular Kermit (non-FTP-specific) command for
- identifying the character set (to be) used in local text files
- and filenames.
-
- TO REITERATE: If you SET FTP CHARACTER-SET TRANSLATION ON but do not
- specify an FTP SERVER-CHARACTER-SET, outbound text files are converted
- to UTF-8 and inbound text files are assumed to be UTF-8. If this is not
- appropriate, be sure to also specify the desired FTP
- SERVER-CHARACTER-SET.
-
- You can use "special" (non-ASCII) characters in filenames in all the
- client / server file management commands (FTP MKDIR, RMDIR, DIRECTORY,
- VDIRECTORY, DELETE, etc), and also in file-transfer commands. When
- giving commands such as FTP DIR (RDIR) and FTP PWD (RPWD), the reply is
- translated too, so you can read it. In this example, the client and
- server use entirely different codes to represent the special characters
- of German:
-
- C-Kermit> ftp xyzcorp.de /anonymous
- C-Kermit> set ftp server-character-set latin1
- C-Kermit> set file character-set german
- C-Kermit> rcd St�dte
- C-Kermit> rpwd
- "/pub/ftp/St�dte is current directory"
- C-Kermit> rdir
- -rw-rw---- 1 olaf 54018 Jan 6 17:58 Adenb�ttel.txt
- -rw-rw---- 1 ursula 373 Jan 5 15:19 A�lar.txt
- -rw-rw---- 1 gisbert 482 Jan 5 15:20 Blowatz.txt
- -rw-rw---- 1 gudrun 124 Jan 5 15:19 B�blingen.txt
- -rw-rw---- 1 olga 14348 Jan 7 14:23 K�ln.txt
-
- When the client and server file systems use different character sets,
- you should take care to use only those characters that the two sets
- share in common when creating filenames or text-file contents. For
- example, PC code pages contain a lot line- and box-drawing characters,
- and sometimes "smart quotes", etc, that are not found in ISO standard
- 8-bit character sets. You should be especially careful to avoid using
- such characters in filenames.
-
- [ [336]C-Kermit Character Sets ]
-
-3.7.1. Character Sets and Uploading
-
- Kermit's PUT and MPUT commands include full file-scanning capabilities,
- as described in [337]Section 4. Thus if FTP CHARACTER-SET-TRANSLATION
- is ON and your character-set associations are set up appropriately,
- Kermit automatically switches on a per-file basis between text and
- binary mode, and for each text file between your chosen 7-bit text
- character set (e.g. ASCII or ISO 646 German), 8-bit text (e.g. Latin-1
- or Japanese EUC), UCS-2, and UTF-8, and converts each of these
- automatically to the server character-set, and furthermore
- automatically differentiates between the Little and Big Endian forms of
- UCS-2, always sending in Big Endian form.
-
- WARNING: It is not advisable to use UCS-2 (or any Unicode
- transformation other than UTF-8) "on the wire", i.e. as a server
- character set. Most FTP servers are not able to cope with it, since
- it contains lots of 0 (NUL) characters. If you do use it, Kermit
- does not translate filenames to or from UCS-2, for reasons well
- known to C programmers (for example, UNIX APIs assume filename
- strings are NUL-terminated). [338]UTF-8 is the preferred (and
- standard) Unicode format for the Internet.
-
- FTP character-set translations differ from the regular Kermit ones by
- not restricting translations to a file-character-set /
- transfer-character-set pair. You can have Kermit's FTP client translate
- between any pair of character sets it knows about. You can see the list
- of supported character sets by typing either of the following:
-
- set ftp server-character-set ?
- set file character-set ?
-
- A typical list looks like this ([339]CLICK HERE for an explanation of
- the names):
-
- C-Kermit>set file char ? One of the following:
- ascii cp869-greek hebrew-7 mazovia-pc
- british cyrillic-iso hebrew-iso next-multinational
- bulgaria-pc danish hp-roman8 norwegian
- canadian-french dec-kanji hungarian portuguese
- cp1250 dec-multinational iso2022jp-kanji shift-jis-kanji
- cp1251-cyrillic dg-international italian short-koi
- cp1252 dutch jis7-kanji spanish
- cp437 elot927-greek koi8 swedish
- cp850 elot928-greek koi8r swiss
- cp852 euc-jp koi8u ucs2
- cp855-cyrillic finnish latin1-iso utf8
- cp858 french latin2-iso
- cp862-hebrew german latin9-iso
- cp866-cyrillic greek-iso macintosh-latin
- C-Kermit>
-
- Thus you can translate not only between private sets (like PC code
- pages) and standard ones (like Latin-1) as in Kermit protocol, but also
- between any given pair of private sets (e.g. CP852 and Mazovia). All
- conversions go through Unicode as the intermediate character set,
- resulting in a minimum of character loss, since Unicode is a superset
- of all other character sets known to Kermit.
-
- In addition to the SET commands listed above, the FTP PUT and MPUT
- commands include switches that apply only to the current command:
-
- /LOCAL-CHARACTER-SET:name
- /SERVER-CHARACTER-SET:name
- Use these switches to force a particular translation. These
- switches override the global FTP CHARACTER-SET-TRANSLATION and
- SERVER-CHARACTER-SET settings and also character-set
- differentiation by file scanning for the duration of the PUT or
- MPUT command. The file scan is still performed, however, to
- determine whether the file is text or binary; thus these
- switches do not affect binary files unless you also include the
- /TEXT switch to force all files to be treated as text.
-
- In other words, if you include one or both of these switches with a PUT
- or MPUT command, they are used. Similarly, the /TRANSPARENT switch
- disables character-set translation for the PUT or MPUT command despite
- the prevailing FTP CHARACTER-SET-TRANSLATION and SERVER-CHARACTER-SET
- settings.
-
- When uploading, the FILE CHARACTER-SET setting is ignored unless you
- have forced Kermit not to [340]scan local files by including a /TEXT or
- /BINARY switch with your [M]PUT command, or by disabling automatic
- text/binary switching in some other way.
-
- Examples:
-
- 1. Suppose you have a CP852 (East European) text file that you want to
- upload and store in ISO Latin Alphabet 2 encoding:
- ftp put /local-char:cp852 /server-char:latin2 magyar.txt
-
- 2. Suppose you always want your text files converted to Latin-2 when
- uploading with FTP. Then put:
- set ftp server-character-set latin2
-
- in your Kermit customization file, and then you can omit the
- /SERVER-CHARACTER-SET: switch from your FTP PUT commands:
- ftp put /local-char:cp852 magyar.txt
-
- 3. Now suppose that all the text files on your PC are written in
- Hungarian, but they have a variety of encodings, and you don't want
- to have to include the /LOCAL-CHARACTER-SET: switch on every FTP
- PUT command, or (more to the point) you want to be able to send a
- mixture of these files all at once. Put these commands in your
- Kermit customization file:
- set ftp server-character-set latin2 ; ISO 8859-2
- set file default 7-bit-character-set hungarian ; ISO 646 Hungarian
- set file default 8-bit-character-set cp852 ; PC East European Code Page
-
- and now PUT and MPUT will automatically detect and switch among ISO
- 646 Hungarian, Code Page 852, UTF-8, and UCS-2 encodings,
- translating each one to Latin-2 for uploading:
- ftp put *.txt
-
- And since binary files are also detected automatically, the latter can
- be simplified to:
-
- ftp put *
-
- even when "*" matches a diverse collection of binary and text files,
- because translations are skipped automatically for binary files.
-
-3.7.2. Character Sets and Downloading
-
- The commands and switches are the same as for uploading, but automatic
- character-set switching works differently, since Kermit can't scan the
- server files in advance. Instead, the transfer mode (text or binary) is
- based on the filenames; each name is compared with Kermit's list of
- text name patterns and binary name patterns. If the name matches a
- binary pattern (for example, if the filename is oofa.tar.gz and one of
- the filename patterns is "*.gz"), the file is downloaded in binary
- mode; otherwise if it matches a text pattern (e.g. oofa.txt matches
- "*.txt"), it is transferred in text ("ascii") mode. Otherwise, it is
- transferred in the prevailing FTP TYPE.
-
- In C-Kermit 8.0, the pattern lists used with FTP GET are not the same
- lists used with Kermit transfers, and can not be viewed with SHOW
- PATTERNS, nor adjusted with ADD and REMOVE TEXT-PATTERNS and
- BINARY-PATTERNS, or SET FILE TEXT-PATTERNS and BINARY-PATTERNS.
- Configuration of the FTP patterns list will be added in a future
- release.
-
- Examples:
-
- get /server-char:latin1 /local-char:cp850 Gr��e.txt
- In this command, the filename contains special characters, which
- you enter using whatever character set your local computer uses,
- in this case PC Code Page 850 (cp850). The command tells Kermit
- (in case it didn't know already from its FILE CHARACTER-SET
- setting) that the local character set is cp850 and the server's
- character-set is ISO 8859-1 Latin Alphabet 1 (latin1). Kermit
- translates the filename from cp850 to latin1 and sends the
- latin1 name to the server. Since it's a text file (matches
- "*.txt"), its contents are translated to cp850 on arrival, and
- it is saved with a cp850 name.
-
- mget /text /server:latin1 /local:utf8 *.txt
- This command:
-
- + Tells C-Kermit that the server's files are encoded in ISO
- 8859-1 Latin Alphabet 1.
- + Tells C-Kermit to translate the incoming files into Unicode
- UTF-8 for storage.
- + Asks the server to send all ".txt" files in text mode.
-
- mget /server:latin1 /local:utf8 *
- Tells Kermit to get all files from the server's directory,
- switching between text and binary mode based on the filename.
- The names of all the files are translated (to UTF-8 in this
- case), but contents are translated (also to UTF-8) only for text
- files.
-
- Note that any pair of 8-bit character sets is likely to have some
- incompatibilities. Any characters in the source file that do not have
- equivalents in the destination file's character set are converted to
- question marks. This applies to both filenames and to text file
- contents.
-
- Also note that the server's ability to accept special characters in
- filenames depends on the particular server. For example:
-
- get Gr��e.txt
-
- works with WU-FTPD, but:
-
- mget Gr��*.txt
-
- does not.
-
-3.7.3. RFC2640
-
- [341]RFC2640, July 1999, specifies a method by which the FTP client and
- server can negotiate the use of UTF8. However, RFC2640-capable servers
- are rare to nonexistent at this writing, and in any case you don't need
- them to be able to transfer text in UTF8. C-Kermit lets you upload and
- download text files in any character set it knows about, converting to
- or from any other character set it knows about, without the knowledge,
- permission, or cooperation of the server, and regardless of its
- capabilities.
-
- [ [342]Top ] [ [343]FTP Top ] [ [344]C-Kermit Home ] [ [345]Kermit Home
- ]
-
-3.8. FTP Command Shortcuts
-
- C-Kermit's FTP client coexists with other C-Kermit functions by
- requiring the "ftp" prefix for each FTP-related command: FTP OPEN, FTP
- GET, FTP BYE, and so on. For interactive use, however, this can be
- rather awkward and sometimes surprising, for example when a GET command
- starts a Kermit GET rather than an FTP GET. In fact, many Kermit
- commands might just as easily apply to an FTP connection: GET, PUT
- (SEND), BYE, and CLOSE. The following command lets you choose how these
- commands are interpreted:
-
- SET GET-PUT-REMOTE { AUTO, KERMIT, FTP }
- Controls the orientation of GET, PUT, REMOTE and other
- file-transfer and client/server commands that might apply to
- either Kermit or FTP. The default setting is AUTO, meaning that
- these commands apply to FTP if an FTP connection is open, and to
- Kermit otherwise. KERMIT means they always apply to Kermit, FTP
- means they always apply to FTP.
-
- Here is a complete list of affected commands:
-
- Kermit Command FTP Equivalent
- (none) FTP [ OPEN ]
- LOGIN FTP USER
- LOGOUT FTP RESET
- BYE FTP BYE
- FINISH FTP BYE
- CLOSE FTP BYE
- HANGUP FTP BYE
- BINARY FTP TYPE BINARY
- TEXT (or ASCII) FTP TYPE ASCII
- SEND (or PUT) FTP PUT
- MSEND (or MPUT) FTP MPUT
- RESEND FTP PUT /RECOVER
- CSEND FTP PUT /COMMAND
- GET FTP GET
- MGET FTP MGET
- REGET FTP GET /RECOVER
- REMOTE HELP (RHELP) FTP HELP
- REMOTE CD (RCD) FTP CD (CWD)
- REMOTE PWD (RPWD) FTP PWD
- REMOTE DIRECTORY (RDIR) FTP DIRECTORY
- REMOTE DELETE (RDEL) FTP DELETE
- REMOTE MKDIR (RMKDIR) FTP MKDIR
- REMOTE RMDIR (RRMDIR) FTP RMDIR
- REMOTE RENAME (RRENAME) FTP RENAME
- REMOTE TYPE (RTYPE) FTP TYPE
- REMOTE EXIT (REXIT) FTP BYE
-
- The commands in the right-hand column always access FTP. The commands
- in the left column can access either Kermit protocol or FTP:
-
- * When GET-PUT-REMOTE is set to KERMIT, or to AUTO when there is no
- FTP connection, the commands in the left-hand column access Kermit
- protocol, and those right-hand column are required for FTP.
- * When GET-PUT-REMOTE is set to FTP, or to AUTO when there is an
- active FTP connection, the commands in the left-hand column access
- the FTP connection and can not be used to access Kermit protocol.
- In this case, if you want to be able to use both Kermit protocol
- and the FTP connection, you must SET GET-PUT-REMOTE KERMIT, and
- then use the FTP commands in the right-hand column to access the
- FTP connection.
-
- Note that file-management commands such as DIRECTORY, DELETE, CD, PWD,
- MKDIR, RMDIR, HELP, RENAME, COPY, TYPE, and so on, always apply
- locally, no matter what kind of connection you have. This is the
- opposite of most FTP clients, where these commands are intended for the
- server, and require an "L" prefix for local execution (e.g. "dir" gets
- a directory listing from the server, "ldir" gets a local directory
- listing). To illustrate with the CD command and a typical UNIX FTP
- client:
-
- Client Server Change Local Directory Change Remote Directory
- FTP FTP lcd cd (cwd)
- Kermit Kermit cd rcd, remote cd
- Kermit FTP cd ftp cd, rcd, remote cd
-
- Also note that not all REMOTE commands are useful with FTP, since FTP
- servers do not offer the corresponding functions. These include:
-
- * REMOTE ASSIGN - FTP servers don't have variables
- * REMOTE COPY - FTP servers don't copy files
- * REMOTE HOST - FTP servers don't execute host (shell) commands
- * REMOTE KERMIT - FTP servers don't execute Kermit commands
- * REMOTE PRINT - FTP servers don't print files
- * REMOTE QUERY - FTP servers don't have variables
- * REMOTE SET - FTP servers don't have Kermit settings
- * REMOTE WHO - FTP servers don't send user lists
-
- Finally note that command shortcuts do not apply to the HELP command.
- For help about an FTP command, use (for example) "help ftp delete", not
- "help delete" or "help rdelete".
-
- [ [346]Top ] [ [347]FTP Top ] [ [348]C-Kermit Home ] [ [349]Kermit Home
- ]
-
-3.9. Dual Sessions
-
- You can have an FTP session open at the same time as a regular Kermit
- SET LINE or SET HOST (terminal) session. In this case, the default SET
- GET-PUT-REMOTE AUTO setting should ensure that all "two-faced" commands
- like GET, PUT, REMOTE, HANGUP, BYE, etc, apply to the Kermit session,
- and all commands for the FTP session must include the FTP prefix. To be
- absolutely certain, you can use SET GET-PUT-REMOTE KERMIT.
-
- ftp foo.bar.baz.com
- if fail ...
- (log in)
- set host foo.bar.baz.com
- if fail ...
- (log in)
-
- Now you have both an FTP and Telnet connection to the same host (of
- course they could also be to different hosts, and you could also have a
- direct or dialed serial connection instead of a Telnet connection). Now
- assuming you have a Kermit server on the far end of the Kermit
- connection:
-
- rcd incoming ; Changes Kermit server's directory (= REMOTE CD)
- ftp cd incoming ; Changes FTP server's directory
- put oofa.txt ; Sends a file on the Kermit connection
- ftp put oofa.txt ; Sends a file on the FTP connection
- bye ; Shuts down the Kermit connection
- ftp bye ; Shuts down the FTP connection
-
- Note that PUT and SEND are synonyms for both FTP and Kermit
- connections.
-
- You can also establish dual sessions on the Kermit command line:
-
- kermit -j host1 -9 host2
-
- This makes a Telnet connection to host1 and an FTP connection to host2.
-
- [ [350]Top ] [ [351]FTP Top ] [ [352]C-Kermit Home ] [ [353]Kermit Home
- ]
-
-3.10. Automating FTP Sessions
-
- Most of Kermit's scripting features can be used to make and control FTP
- sessions: FOR and WHILE loops, IF-ELSE and SWITCH constructions,
- variables, arrays, built-in functions, and all the rest. You can't use
- INPUT, MINPUT, OUTPUT, CLEAR, or SCRIPT on an FTP session, but these
- are not needed since the FTP protocol is well defined.
-
- [354]CLICK HERE for an FTP scripting tutorial.
-
-3.10.1. FTP-Specific Variables and Functions
-
- The following variable tells whether an FTP connection is open:
-
- \v(ftp_connected)
- 1 if there is an active FTP connection, 0 if there isn't.
-
- The FTP OPEN command sets:
-
- \v(ftp_host)
- The host to which the most recent FTP connection was made.
-
- \v(ftp_security)
- The security method negotiated for the current FTP session. The
- value is "NULL" when no security is used. Other possibilities
- are GSSAPI, KERBEROS_V4, SSL, TLS, and SRP. Also see
- \v(authname), \v(authstate), and \v(authtype). See [355]3.2.
- Making Secure FTP Connections.
-
- \v(ftp_server)
- The OS type (UNIX, VMS, etc) of the FTP server host.
-
- The FTP USER command (or FTP OPEN /USER:, or FTP with automatic login)
- sets:
-
- \v(ftp_loggedin)
- 1 if you are logged in to an FTP server, 0 if you are not.
-
- The current COMMAND-PROTECTION-LEVEL and DATA-PROTECTION-LEVEL values
- are reflected in:
-
- \v(ftp_cpl)
- \v(ftp_dpl)
- The values are "clear", "confidential", "safe" or "private". See
- [356]3.2. Making Secure FTP Connections.
-
- The FTP GET-PUT-REMOTE setting is reflected in:
-
- \v(ftp_getputremote)
- The values are "auto", "ftp", or "kermit".
-
- Every FTP command sets the \v(success) variable, as well as the
- following two FTP-specific variables:
-
- \v(ftp_code)
- The standardized numeric FTP protocol code from the server's
- response to the last client command, a 3-digit decimal number
- defined in [357]RFC959. Briefly:
-
- 1xx = Positive Preliminary Reply
- 2xx = Positive Completion Reply
- 3xx = Positive Intermediate Reply
- 4xx = Transient Negative Completion Reply
- 5xx = Permanent Negative Completion Reply
-
- \v(ftp_message)
- The text message, if any, from the server's response to the last
- client command. If the most recent response had multiple lines,
- this variable has only the final line. These messages are not
- standardized and vary in format and content from server to
- server. Synonym: \v(ftp_msg).
-
- FTP file transfers set the regular Kermit transfer status variables:
-
- \v(cps) Characters per second of most recent transfer.
- \v(filespec) File specification used in most recent transfer.
- \v(fsize) Size of file most recently transferred.
- \v(tfsize) Total size of file group most recently transferred.
- \v(xferstatus) Status of most recent transfer (0 = success, 1 = failure).
- \v(tftime) Elapsed time of most recent transfer, in seconds.
-
- During an FTP transfer, the per-file variables are:
-
- \v(filename) Name of current file.
- \v(filenumber) Ordinal file number in group (1, 2, 3, ...)
-
-3.10.2. Examples
-
- Let's begin with a simple example showing how to log in, send some
- files, and log out:
-
- define error if fail { ftp bye, stop 1 Error: \%1 }
- set transact brief
- log t
- ftp ftp.xyzcorp.com /anonymous
- if fail stop 1 Connection failed
- if not \v(ftp_loggedin) stop 1 Login failed
- ftp cd incoming
- error {ftp cd}
- cd upload
- error {local cd}
- ftp put /delete *
- error {put}
- ftp bye
-
- First we define an error handling macro to be used after the connection
- is made. Then we set up a brief-format transaction log to keep a record
- of our file transfers. Then we make a connection to the host and log in
- anonymously. The "if fail" command checks whether the connection was
- made. The "if not" command checks whether login was successful.
- Obviously the script should not continue unless both tests succeed.
-
- Next we change to the server's 'incoming' directory and to our own
- 'upload' directory, and send all the files that are in it (they can be
- any mixture of text and binary files), deleting each source file
- automatically after it is successfully uploaded. Each of these
- operations is checked with the ERROR macro, which prevents the script
- from continuing past a failure.
-
- Finally we close the FTP session with the "bye" command.
-
- Just like any other Kermit script, this one can be used in many ways:
-
- * It can be stored in a file, and Kermit can be told to TAKE the
- file.
- * In UNIX, it can be a "[358]kerbang" script and therefore run
- directly from the shell prompt or as a cron job.
-
- We could have used command shortcuts like "rcd", "put", and "bye", but
- since they can be ambiguous under certain circumstances, it is better
- to avoid them in scripts; they are intended mainly for convenience
- during interactive use. However, if you wish to use the shortcuts in a
- script, you can do it this way (error handling omitted for brevity):
-
- local \%t ; Declare a local temporary variable
- assign \%t \v(ftp_getputremote) ; Save current FTP GET-PUT-REMOTE setting
- set ftp get-put-remote ftp ; Choose FTP orientation
- ftp xyzcorp.com /anonymous ; Open an FTP connection
- get oofa.txt ; GET a file
- put foo.bar ; PUT a file
- rdel yesterday.log ; Delete a file on the server
- bye ; Log out and disconnect from server.
- set ftp get-put-remote \%t ; Restore previous GET-PUT-REMOTE setting
-
- Of course, FTP scripts can also be written as macros. This lets you
- pass parameters such as hostnames, usernames, and filenames to them:
-
- define doftpget {
- if < \v(argc) 4 end 1 Usage: \%0 host user remotefile [ localfile ]
- ftp \%1 /user:\%2
- if fail end 1 FTP OPEN \%1 failed
- if not \v(ftp_loggedin) end 1 FTP LOGIN failed
- ftp get {\%3} {\%4}
- if fail end 1 FTP GET \%3 failed
- ftp bye
- }
-
- Add this definition to your Kermit customization file, and it will
- always be available when you start Kermit. This macro lets you download
- a file with FTP by giving a single command, e.g.:
-
- doftpget xyzcorp.com anonymous oofa.txt
-
-3.10.3. Automating Secure FTP Sessions
-
- Often when making secure connections, you are prompted interactively
- for certain information or permission to proceed. These prompts can
- stop an automated procedure. To avoid them, you must give the
- appropriate commands to disable them, and/or supply the prompted-for
- information beforehand. Here are a few hints:
-
- * Make sure that SET TAKE ERROR and SET MACRO ERROR are both OFF.
- This is the default, but in case you have set either one of these
- ON in your script or initialization file, this makes the script
- halt on any kind of error. Normally you would want to check each
- operation for success or failure and take appropriate action.
- * On SSL and TLS connections, you may be asked whether it is OK to
- proceed with a connection to server that presents a self-signed
- certificate. You can use the SET AUTHENTICATION SSL (or TLS) VERIFY
- or SET AUTH SSL (or TLS) CERTS-OK commands to avoid this prompt by
- not requesting a certificate from the peer.
- * (More to be added...)
-
- [ [359]Top ] [ [360]FTP Top ] [ [361]FTP Script Tutorial ] [
- [362]C-Kermit Home ] [ [363]Kermit Home ]
-
-3.11. Advanced FTP Protocol Features
-
- The remainder of the FTP documentation (through the end of Section 3)
- is new to C-Kermit 8.0.206, but we leave it in black to prevent
- headaches. Except for titles.
- * [364]TERMINOLOGY
- * [365]FEATURE NEGOTIATION
- * [366]USING MGET: NLST VERSUS MLSD
- * [367]EXAMPLES
- * [368]REFERENCES
-
- The new releases of [369]C-Kermit (8.0.206) and [370]Kermit 95 (2.1)
- support new FTP protocol features from RFC 2389 as well as most of
- what's in the Elz and Hethmon Extensions to FTP Internet Draft (see
- [371]References). Some of these features, such as SIZE (request a
- file's size), MDTM (request file's modification time), and REST
- (restart interrupted transfer) have been widely implemented in FTP
- clients and servers for years (as well as in the initial release of the
- Kermit FTP clients). Others such as FEAT and MLSD are rarely seen and
- are new to the upcoming Kermit releases. TVFS (Trivial Virtual File
- Store) is supported implicitly, and the UTF-8 character-set is already
- fully supported at the protocol and data-interchange level.
-
- For Kermit users, the main benefit of the new FTP protocol extensions
- is the ability to do recursive downloads. But the extensions also
- introduce complications and tradeoffs that you should be aware of. Of
- course Kermit tries to "do the right thing" automatically in every case
- for backwards compatibility. But (as noted later) some cases are
- inherently ambiguous and/or can result in nasty surprises, and for
- those situations new commands and switches are available to give you
- precise control over Kermit's behavior, in case the defaults don't
- produce the desired results.
-
-3.11.1. Terminology
-
- Command-line FTP clients such as Kermit (as well as the traditional FTP
- programs found on Unix, VMS, ..., even Windows) have commands like PUT,
- MPUT, GET, MGET, and BYE, which they convert into zero or more FTP
- protocol commands, such as NLST, RETR, QUIT. For clarity, we'll use
- "command" to refer to commands given by the user to the FTP client, and
- "directive" for FTP protocol commands sent by the FTP client to the FTP
- server.
-
-3.11.2. Feature Negotiation
-
- New FTP protocol features are negotiated by the client sending a FEAT
- directive and the server responding with a list of (new) features it
- supports, or else with an error indication if it does not support the
- FEAT directive at all, in which case the client has to guess which new
- features it supports (Kermit guesses that it supports SIZE and MDTM but
- not MLST). Note that the MLST feature includes MLSD, which is not
- listed separately as a feature.
-
- Guessing is nice when it works, but sometimes it doesn't, and some FTP
- servers become confused when you send them a directive they don't
- understand, or they do something you didn't want, sometimes to the
- point of closing the connection. For this reason, Kermit lets you
- override default or negotiated features with the following new
- commands:
-
- FTP { ENABLE, DISABLE } FEAT
- Enables or disables the automatic sending of a FEAT directive
- upon connection to an FTP server. Note that FTP [ OPEN ] /NOINIT
- also inhibits sending the FEAT directive (and several others)
- for the connection being OPEN'd, but without necessarily
- disabling FEAT for subsequent connections in the same Kermit
- instance. FEAT is ENABLED by default, in which case many FTP
- servers are likely to reply:
-
-500 'FEAT': command not understood
-
- which is normally harmless (but you never know). (In C-Kermit
- 8.0.208, this error message is suppressed unless you SET FTP
- DEBUG ON.)
-
- FTP ENABLE { MDTM, MLST, SIZE }
- Enables the given directive for implicit use by the FTP GET and
- MGET commands in case it has been disabled or erroneously
- omitted by the server in its FEAT response. Note: MLSD can be
- used in the FTP ENABLE and DISABLE commands as a synonym for
- MLST. YOU MUST GIVE THIS COMMAND AFTER MAKING THE FTP
- CONNECTION.
-
- FTP DISABLE { MDTM, MLST, SIZE }
- Disables implicit use of the given directive by GET or MGET in
- case it causes problems; for example, because it makes multifile
- downloads take too long or the server announces it erroneously
- or misimplements it. Use DISABLE FEAT before making a connection
- to prevent Kermit from sending the FEAT directive as part of its
- initial sequence. Note that disabling FEAT, SIZE, or MDTM does
- not prevent you from executing explicit FTP FEATURES, FTP SIZE,
- or FTP MODTIME commands. Also note that disabling SIZE prevents
- PUT /RESTART (recovery of interrupted uploads) from working. YOU
- MUST GIVE THIS COMMAND AFTER MAKING THE FTP CONNECTION.
-
- To enable or disable more than one feature, use multiple FTP ENABLE or
- FTP DISABLE commands. The SHOW FTP command shows which features are
- currently enabled and disabled.
-
- FTP FEATURES
- This command sends a FEAT directive to the server. In case you
- have been disabling and enabling different features, this
- resynchronizes Kermit's feature list with the server's. If the
- server does not support the FEAT directive, Kermit's feature
- list is not changed.
-
- FTP OPTIONS directive
- Informational only: the server tells what options, if any, it
- supports for the given directive, e.g. MLST. Fails if the server
- does not support the OPTS directive or if the directive for
- which options are requested is not valid. The directive is
- case-insensitive.
-
- FTP SIZE filename
- Sends a SIZE directive to the server for the given file. The
- filename must not contain wildcards. The server responds with an
- error if the file can't be found, is not accessible, or the SIZE
- directive is not supported, otherwise with the length of the
- file in bytes, which Kermit displays and also makes available to
- you in its \v(ftp_message) variable. If the directive is
- successful, Kermit (re-)enables it for internal use by the GET
- and MGET directives on this connection.
-
- FTP MODTIME filename
- Works just like the SIZE directive except it sends an MDTM
- directive. Upon success, the server sends modification date-time
- string, which Kermit interprets for you and also makes available
- in its \v(ftp_message) variable.
-
- Whenever a SIZE or MDTM directive is sent implicitly and rejected by
- the server because it is unknown, Kermit automatically disables it.
-
-3.11.3. Using MGET: NLST versus MLSD
-
- When you give an MGET command to an FTP client, it sends a request to
- the FTP server for a list of files, and then upon successful receipt of
- the list, goes through it and issues a RETR (retrieve) directive for
- each file on the list (or possibly only for selected files).
-
- With the new FTP protocol extensions, now there are two ways to get the
- list of files: the NLST directive, which has been part of FTP protocol
- since the beginning, and the new MLSD directive, which is new and not
- yet widely implemented. When NLST is used and you give a command like
- "mget *.txt", the FTP client sends:
-
-NLST *.txt
-
- and the server sends back a list of the files whose names match, e.g.
-
-foo.txt
-bar.txt
-baz.txt
-
- Then when downloading each file, the client sends SIZE (if it wants
- have a percent-done display) and MDTM (if it wants to set the
- downloaded file's timestamp to match that of the original), as well as
- RETR (to retrieve the file).
-
- But when MLSD is used, the client is not supposed to send the filename
- or wildcard to the server; instead it sends an MLSD directive with no
- argument (or the name of a directory), and the server sends back a list
- of all the files in the current or given directory; then the client
- goes through the list and checks each file to see if it matches the
- given pattern, the rationale being that the user knows only the local
- conventions for wildcards and not necessarily the server's conventions.
- So with NLST the server interprets wildcards; with MLSD the client
- does.
-
- The interpretation of NLST wildcards by the server is not
- necessarily required or even envisioned by the FTP protocol
- definition (RFC 959), but in practice most clients and servers work
- this way.
-
- The principal advantage of MLSD is that instead of sending back a
- simple list of filenames, it sends back a kind of database in which
- each entry contains a filename together with information about the
- file: type, size, timestamp, and so on; for example:
-
-size=0;type=dir;perm=el;modify=20020409191530; bin
-size=3919312;type=file;perm=r;modify=20000310140400; bar.txt
-size=6686176;type=file;perm=r;modify=20001215181000; baz.txt
-size=3820092;type=file;perm=r;modify=20000310140300; foo.txt
-size=27439;type=file;perm=r;modify=20020923151312; foo.zip
-(etc etc...)
-
- (If the format of the file list were the only difference between NLST
- and MLSD, the discussion would be finished: it would always be better
- to use MLSD when available, and the MGET user interface would need no
- changes. But there's a lot more to MLSD than the file-list format; read
- on...)
-
- The client learns whether the server supports MLSD in FEAT exchange.
- But the fact that the server supports MLSD doesn't mean the client
- should always use it. It is better to use MLSD:
-
- * On connections where the server imposes a time penalty for every
- command, e.g. the Red Hat Rawhide server. With MLSD, the client
- needs to send only one command (RETR) per file, whereas NLST
- requires three (SIZE, RETR, and MDTM). Suppose there is a 30-second
- delay for each command and 1000 files are to be fetched; in that
- case, MLSD saves 60,000 seconds = 1000 minutes = 16 hours and 40
- minutes.
- * For recursive downloads since there is no dependable way to
- download directory trees with NLST.
-
- But it is better to use NLST:
-
- * If you want only a couple short files out of a large directory. In
- this case, NLST is the better choice since the server sends a list
- of only the files you want, not a list of (say) a million files,
- which can make a big difference on slow connections. For example,
- suppose your wildcard matches three files of 1K each, but the
- million-file listing is 80MB long, and your connection is through a
- modem. The overhead of using MLSD is practically infinite.
- * If the server supports wildcarding features not known to the
- client, but that can be used to achieve desirable effects otherwise
- unobtainable, such as "[dir...]*.txt" in VMS or AOS/VS "except"
- clauses.
- * If you have been given a wildcard string by an FTP site
- administrator for fetching a specific group of files out of a
- larger directory, e.g. "mget ck[cuw]*.[cwh] makefile", that is
- expected to work with any client (an FTP site administrator can't
- be expected to know the wildcard syntax of every FTP client).
-
- But when using MLSD there are complications:
-
- * MLSD wants either a blank argument (meaning the current directory)
- or else the name of a specific directory. The client must not send
- it a wildcard or a filename.
- * But if the user's command is "mget xxx", how does the client know
- whether to send "xxx" in the MLSD directive? It might be the name
- of a directory on on the server, in which case it should be sent,
- or it might be the name of a file on the server (or a wildcard), in
- which case it must not be sent. Since the client knows its own
- wildcard syntax, then in most cases it would be right to send
- "MLSD" with no argument if xxx is wild, and to send "MLSD xxx" if
- it is not.
- * But suppose the server's file system allows filename characters
- that correspond with the client's wildcard syntax? For example:
- "[abc]" could be either a valid VMS directory name or a wildcard
- pattern used by the FTP client. What should the client do with
- "mget [abc]"? In this case there must be a way for the user to
- force sending the MGET argument as the MLSD argument.
- * If "xxx" is a regular file in the server's current directory, "mget
- xxx" works with NLST but not with MLSD.
-
- To further complicate matters, NLST can (in theory) work just like
- MLSD: if sent with a blank argument or a directory name, it is supposed
- to return a complete list of files in the current or given directory,
- which the client can match locally against some pattern. It is not
- known if any FTP server or client does this but nevertheless, it should
- be possible since this behavior can be inferred from RFC 959.
-
- In view of these considerations, and given the need to preserve the
- traditional FTP client command structure and behavior so the software
- will be usable by most people:
-
- 1. The MGET command should produce the expected result in the common
- cases, regardless of whether NLST or MLSD is used underneath.
- 2. For anomalous cases, the user needs a way to control whether the
- MGET argument is sent to the server or kept for local use.
- 3. At the same time, the user might need a way to send a directory
- name to the server, independent of any wildcard pattern.
- 4. The user needs a way to force NLST or MLSD for a given MGET
- command.
-
- By default, Kermit's MGET command uses MLSD if MLST is reported by the
- server in its FEAT list. When MLSD is used, the filespec is sent to the
- server if it is not wild (according to Kermit's own definition of
- "wild" since it can't possibly know the server's definition). If the
- filespec is wild it is held for local use to select files from the list
- returned by the server. If MLST is not reported by the server or is
- disabled, Kermit sends the MGET filespec with the NLST directive.
-
- The default behavior can be overridden globally with FTP DISABLE MLST,
- which forces Kermit to use NLST to get file lists. And then for
- situations in which MLSD is enabled, the following MGET switches can be
- used to override the defaults for a specific MGET operation:
-
- /NLST
- Forces the client to send NLST. Example:
-
-mget /nlst foo.*
-
- /MLSD
- Forces the client to send MLSD (even if MLST is disabled).
- Example:
-
-mget /mlsd foo.*
-
- /MATCH:pattern
- When this switch is given, it forces the client to hold the
- pattern for local use against the returned file list. If a
- remote filespec is also given (e.g. the "blah" in "mget
- /match:*.txt blah"), then it is sent as the NLST or MLSD
- argument, presumably to specify the directory whose files are to
- be listed. When the /MATCH switch is not given, the MGET
- filespec is sent to the server if the directive is NLST or if
- the filespec is not wild. Examples:
-
- Command: With NLST: With MLSD:
- mget NLST MLSD
- mget *.txt NLST *.txt MLSD
- mget foo NLST foo MLSD foo
- mget /match:*.txt NLST MLSD
- mget /match:*.txt foo NLST foo MLSD foo
-
- In other words, the pattern is always interpreted locally unless MGET
- uses NLST and no /MATCH switch was given.
-
-3.11.4. Examples
-
-3.11.4.1. Downloading a Single File
-
- There are no choices here, just use the FTP GET command. Kermit always
- sends the RETR directive, and possibly SIZE and/or MDTM. The small
- advantage of using MLST in this case is outweighed by the risk and
- effort of coding a special case.
-
-3.11.4.2. Downloading a Group of Files from a Single Directory
-
- This case presents tradeoffs, especially on slow connections:
-
- * For downloading all or most of the files in a directory, MLSD is
- better because it eliminates the need to send SIZE and MDTM for
- each file. No special actions are required in this case; Kermit
- uses MLSD automatically if the server supports it (unless you have
- disabled it).
- * For a small number of files from a large directory, NLST is better
- because it bypasses downloading of a potentially huge file list
- prior to the files themselves. If you have a connection to a server
- that supports MLSD, use the /NLST switch to force NLST:
-
-mget /nlst t[1234].h
-
- * If the server supports MLSD but does not support separate SIZE or
- MDTM directives, and you need the size and/or timestamp
- information, MLSD is better; no special actions required.
- * If the server supports MLSD but does not support the "size" and
- "modify" facts, but it does support the SIZE or MDTM directives,
- and you need the size and/or timestamp information, NLST is better.
-
-3.11.4.3. Downloading a Directory Tree
-
- MLSD is the only choice for recursive downloads; they rarely, if ever,
- work with NLST (the few cases where they do work rely on extra-protocol
- "secret" notations for the NLST argument). No special actions are
- required to force MLSD when the server supports it, unless you have
- disabled it. Examples:
-
- MGET /RECURSIVE
- This tells the server to send all files and directories in the
- tree rooted at its current directory.
-
- MGET /RECURSIVE *.txt
- This tells the server to send all *.txt files in the tree rooted
- at its current directory.
-
- MGET /MLSD /RECURSIVE *.txt
- Same as the previous example but forces Kermit to send MLSD in
- case it was disabled, or in case the server is known to support
- it even though it did not announce it in its FEAT listing.
-
- MGET /RECURSIVE /MATCH:*.zip archives
- Tells the server to send all ZIP files in the tree rooted at its
- "archives" directory.
-
- MGET /RECURSIVE /MATCH:* [abc]
- The server is running on VMS and you want it to send all the
- files in the directory tree rooted at [ABC]. But since "[abc]"
- looks just like a wildcard, you have to include a /MATCH: switch
- to force Kermit to send "[abc]" as the MLSD argument.
-
- In all cases in which the /RECURSIVE switch is included, the server's
- tree is duplicated locally.
-
- Although MLSD allows recursion and NLST does not, the MLSD
- specification places a heavy burden on the client; the obvious,
- straightforward, and elegant implementation (depth-first, the one
- that Kermit currently uses) requires as many open temporary files as
- the server's directory tree is deep, and therefore client resource
- exhaustion -- e.g. exceeding the maximum number of open files -- is
- a danger. Unfortunately MLSD was not designed with recursion in
- mind. (Breadth-first traversal could be problematic due to lack of
- sufficient navigation information.)
-
- Of course all of Kermit's other MGET switches can be used too, e.g. for
- finer-grained file selection (by date, size, etc), for moving or
- renaming files as they arrive, to override Kermit's automatic per-file
- text/binary mode switching, to pass the incoming files through a
- filter, to convert text-file character sets, and so on.
-
-3.11.4.4. NLST/MLSD Summary Table
-
- Here's a table summarizing MGET behavior when the server supports both
- NLST and MLSD. /NLST and /MLSD switches are included for clarity to
- indicate which protocol is being used, and the expected effects. In
- practice you can omit the /NLST and /MLSD switches and the Kermit
- client chooses the appropriate or desired protocol as described above.
- Sample commands presume a Unix file system on the server, but of course
- the server can have any file system or syntax at all.
-
- User's Command FTP Sends Remarks
- mget /nlst NLST Gets a list of all the files in the server's current
- and downloads each file. The list includes names only, so Kermit also
- must send SIZE and MDTM directives if size and timestamp information is
- required (this is always true of NLST). Sending NLST without an
- argument is allowed by the RFC959 NLST definition and by the Kermit FTP
- client, but might not work with other clients, and also might not work
- with every server.
- mget /nlst foo NLST foo If "foo" is a directory, this gets a list of
- all the files from the server's "foo" directory and downloads each
- file; otherwise this downloads the file named "foo" (if any) from the
- server's current directory.
- mget /nlst *.txt NLST *.txt Gets a list of the files in the server's
- current directory whose names match the pattern *.txt, and then
- downloads each file from the list. Because we are using NLST, we send
- the filespec (*.txt) to the server and the server interprets any
- wildcards.
- mget /nlst foo/*.txt NLST foo/*.txt Gets a list of the files in the
- server's "foo" directory whose names match the pattern *.txt, and then
- downloads each file from the list (server interprets wildcards).
- mget /nlst /match:*.txt NLST Gets a list of all the files in the
- server's current directory and then downloads each one whose name
- matches the pattern *.txt (client interprets wildcards).
- mget /nlst /match:*.txt foo NLST foo Gets a list of all the files in
- the server's "foo" directory and then downloads each one whose name
- matches the pattern *.txt (client interprets wildcards).
- mget /mlsd MLSD Gets a list of all the files from the server's current
- directory and then downloads each one. The list might include size and
- timestamp information, in which case Kermit does not need to send SIZE
- and MDTM directives for each file (this is always true of MLSD).
- mget /mlsd foo MLSD foo Gets a list of all the files from the server's
- "foo" directory (where the string "foo" does not contain wildcards) and
- then downloads each one. If "foo" is a regular file and not a
- directory, this command is supposed to fail, but some servers have been
- observed that send the file.
- mget /mlsd *.txt MLSD Gets a list of all the files from the server's
- current directory and then downloads only the ones whose names match
- the pattern "*.txt". Because we are using MLSD and the MGET filespec is
- wild, we do not send the filespec to the server, but treat it as though
- it had been given in a /MATCH: switch and use it locally to match the
- names in the list.
- mget /mlsd foo/*.txt MLSD This one won't work because MLSD requires
- that the notions of server directory and filename-matching pattern be
- separated. However, the client, which can't be expected to know the
- server's file-system syntax, winds up sending a request that the server
- will (or should) reject.
- mget /mlsd /match:*.txt MLSD Gets a list of all the files from the
- server's current directory and then downloads only the ones whose names
- match the pattern "*.txt" (client interprets wildcards).
- mget /mlsd /match:*.txt foo MLSD foo If "foo" is a directory on the
- server, this gets a list of all the files from the server's "foo"
- directory and then downloads only the ones whose names match the
- pattern "*.txt" (client interprets wildcards). This leaves the server
- CD'd to the "foo" directory; there's no way the client can restore the
- server's original directory because MLSD doesn't give that information,
- and since the client can not be expected to know the server's
- file-system syntax, it would not be safe to guess. If "foo" is a
- regular file, MLSD fails.
- mget /mlsd foo bar MLSD This one is problematic. You're supposed to be
- able to give MGET a list a filespecs; in this case we name two
- directories. The client must change the server's directory to "foo" to
- get the list of files, and then the files themselves. But then it has
- no way to return to the server's previous directory in order to do the
- same for "bar", as explained in the previous example.
- mget /mlsd /match:* [abc] MLSD [abc] Including a /MATCH: switch forces
- [abc] to be sent to the server even though the client would normally
- think it was a wildcard and hold it for local interpretation. In this
- example, [abc] might be a VMS directory name.
- mget /mlsd /match:* t*.h MLSD t*.h Contrary to the MLSD specification,
- some MLSD-capable FTP servers do interpret wildcards. This form of the
- MGET command can be used to force a wildcard to be sent to the server
- for interpretation.
-
- When MLSD is used implicitly (that is, without an /MLSD switch given to
- force the use of MLSD) and an MGET command such as "mget foo/*.txt"
- fails, Kermit automatically falls back to NLST and tries again.
-
-3.11.5. References
-
- 1. Postel, J., and J. Reynolds, File Transfer Protocol (FTP), RFC 959,
- October 1985: [372]ftp://ftp.isi.edu/in-notes/rfc959.txt.
- 2. Hethmon, P, and R. Elz, Feature negotiation mechanism for the File
- Transfer Protocol, RFC 2389, August 1998:
- [373]ftp://ftp.isi.edu/in-notes/rfc2389.txt.
- 3. Elz, R, and P. Hethmon, Extensions to FTP, Internet Draft
- draft-ietf-ftpext-mlst-16.txt, September 2002:
- [374]http://www.ietf.org/internet-drafts/draft-ietf-ftpext-mlst-16.
- txt.
- 4. [375]The Kermit FTP Client (overview).
-
- [ [376]Top ] [ [377]FTP Top ] [ [378]C-Kermit Home ] [ [379]Kermit Home
- ]
-
-4. FILE SCANNING
-
- A new feature called file scanning is used in various contexts to
- determine if a file is text or binary, and if it is text, what kind of
- text. The overhead of file scanning is surprisingly tolerable, usually
- about a quarter second per file. File scanning is now used instead of
- filename patterns unless you SET FILE SCAN OFF, which restores the
- previous behavior.
-
- The primary benefit of file scanning is in file transfer. For all
- practical purposes, now you can stop worrying about whether a file
- should be sent in binary or text mode, or about sending mixtures of
- text and binary files in a single operation, or configuring and
- fine-tuning your lists of binary-file and text-file name patterns: now
- it all just works.
-
- File scanning is done by the file sender, which determines the type of
- each file before it sends it and informs the receiver (Kermit or FTP
- server) of the type. File scanning is NOT done by the receiver, because
- it is the sender's responsibility to determine each file's type, send
- the file in the right mode, and inform the receiver of the mode. If
- both transfer partners are capable of this (or any other) form of
- automatic text/binary mode switching, then files can be sent in both
- directions with no worries about corruption due to inappropriate
- transfer mode. (As noted in [380]Section 3, FTP servers don't do this,
- so this discussion does not apply when using Kermit to download from an
- FTP server.)
-
- The rest of this section is mainly for the curious. If you don't read
- it and simply accept all defaults, every file you send should go in the
- appropriate mode automatically. As always, however, for character-set
- translation to work for 7- and 8-bit character-set files, the
- appropriate SET FILE CHARACTER-SET command(s) must have been executed
- to identify their encoding (Kermit's default file character-set is
- neutral ASCII except on platforms like HP-UX or DG/UX, where the
- default file character-set is known). And of course, receiving is
- another matter -- obviously the other Kermit must also send each file
- in the appropriate mode.
-
- Scanning is more reliable than filename patterns simply because
- filenames are not reliable indicators of the file's contents. Classic
- examples include ".doc" files, which are binary if Microsoft Word
- documents but text on most other platforms, and ".com" files, which are
- binary on DOS and Windows but text on VMS. Anyway, nobody knows the
- naming conventions (if any) of all the applications (and persons!) on
- your computer. Scanning, on the other hand, determines each file's type
- by inspecting its contents rather than just looking at its name.
-
- Also, file patterns -- even when they work as intended -- categorize
- each file only as text or binary, whereas file scanning can make finer
- distinctions:
-
- BINARY
- Binary data, not to be converted in any way. Examples include
- binary machine code (executable programs), graphics images (GIF,
- JPG, etc), compressed files (Z, GZ, etc), archives and packages
- (ZIP, TAR, RPM, etc), object files and libraries (OBJ, DLL,
- etc).
-
- 7-BIT TEXT
- Text encoded in a 7-bit character set such as ASCII or one of
- the ISO 646 national versions. Kermit has no way to tell which
- character is used, only that it's 7-bit text. Typical examples
- include program source code, README files, Perl or Kermit
- scripts, plain-text email, HTML, TeX, and various textual
- encodings of binary files: Hex, Base64, etc. When sending such
- files, the FILE DEFAULT 7BIT-CHARACTER-SET is used as the file
- character-set, and then the appropriate transfer character set
- is chosen from the associations list (ASSOCIATE, SHOW
- ASSOCIATIONS).
-
- 8-BIT TEXT
- Text encoded in an 8-bit character set such as Latin-1, Latin-2,
- Latin/Hebrew, Latin/Cyrillic, KOI8, HP-Roman8, JIS X 0208, Code
- Page 437, or Code Page 1252. Again, Kermit has no way of knowing
- which particular set is in use, only that it's 8-bit text. When
- sending such files, the FILE DEFAULT 8BIT-CHARACTER-SET is used
- as the file character-set, and then the appropriate transfer
- character set is chosen from the associations list.
-
- UCS2 TEXT
- Unicode in its basic form, 16 bits (2 octets) per character.
- When sending such files, UCS2 is the file character-set and the
- byte order is identified automatically; the appropriate transfer
- character set is chosen from the associations list. Normally
- this would be UTF8. UTF-16 is not supported yet; Kermit's
- Unicode translations are restricted to Plane 0, the Base
- Multilingual Plane (BMP).
-
- UTF8 TEXT
- Unicode in its 8-bit transformation format. When sending such
- files, UTF8 is the file character-set; the appropriate transfer
- character set is chosen from the associations list, normally
- UCS2 or UTF8.
-
- File scanning is available in UNIX C-Kermit, in K-95, and to a limited
- extent, in VMS C-Kermit (full scanning is problematic in VMS because
- even plain-text files might contain binary record-format information).
- The relevant commands are:
-
- SET TRANSFER MODE { AUTOMATIC, MANUAL }
- Tells whether the file-transfer mode (text or binary) should be
- set by automatic or "manual" means. AUTOMATIC is the default,
- which allows any of the automatic methods that are enabled to do
- their jobs: FILE SCAN, FILE PATTERNS, peer recognition, etc.
- MANUAL lets you control the transfer mode with the SET FILE TYPE
- commands. As always, /TEXT and /BINARY switches on your
- file-transfer commands override all other methods; if you give
- one of these switches, scanning is not done. SHOW TRANSFER
- displays the current TRANSFER MODE setting.
-
- SET FILE SCAN { ON [ number ], OFF }
- Turns this feature on and off. It's ON by default. When OFF, the
- previous rules apply (SET FILE PATTERNS, etc). When ON is given,
- you can also specify a number of bytes to be scanned. The
- default is 49152 (= 48K). If a negative number is given, the
- entire file is scanned, no matter how big, for maximum certainty
- (for example, a PostScript file that appears to be plain text
- might include an embedded graphic past the normal scanning
- limit). SHOW FILE displays the current FILE SCAN setting.
-
- SET FILE DEFAULT 7BIT-CHARACTER-SET name
- Tells the 7-bit character-set to use if scanning identifies a
- 7-bit text file, e.g. GERMAN. SHOW FILE displays the current SET
- FILE DEFAULT settings. So does SHOW CHARACTER-SETS.
-
- SET FILE DEFAULT 8BIT-CHARACTER-SET name
- Tells the 8-bit character-set to use if scanning identifies an
- 8-bit text file, e.g. LATIN1. SHOW FILE and SHOW CHARACTER-SET
- display this.
-
- ASSOCIATE FILE-CHARACTER-SET fcs tcs
- When sending files and a file character-set (fcs) is identified
- by scanning, this tells C-Kermit which transfer character-set
- (tcs) to translate it to. It also allows C-Kermit to set the
- appropriate transfer character-set automatically whenever you
- give a SET FILE CHARACTER-SET command.
-
- ASSOCIATE TRANSFER-CHARACTER-SET tcs fcs
- When receiving files and a file arrives whose transfer
- character-set (tcs) is announced by the sender, this command
- tells C-Kermit which file character-set (fcs) to translate it
- to. It also allows C-Kermit to set the appropriate file
- character-set whenever you give a SET TRANSFER CHARACTER-SET
- command.
-
- SET FILE CHARACTER-SET name
- When given for a 7-bit set, also sets FILE DEFAULT
- 7BIT-CHARACTER-SET to the same set. When given for an 8-bit set,
- also sets FILE DEFAULT 8BIT-CHARACTER-SET to the same set. If an
- ASSOCIATE FILE-CHARACTER-SET command has been given for this
- set, also sets the corresponding transfer character-set.
-
- DIRECTORY /XFERMODE [ filespec ]
- Performs a file scan of the given files, listing the result for
- each file. If FILE SCAN is OFF but PATTERNS are ON, the result
- shown according to the current FILE TEXT-PATTERNS and
- BINARY-PATTERNS, and are restricted to (B) and (T). When FILE
- SCAN is ON, the results are:
-
- (B) Binary
- (T)(7BIT) Text: 7-bit
- (T)(8BIT) Text: 8-bit
- (T)(UTF8) Text: Unicode UTF8
- (T)(UCS2BE) Text: Unicode UCS2 Big Endian
- (T)(UCS2LE) Text: Unicode UCS2 Little Endian
-
- So you can use DIR /XFER to get a preview of how each file in a
- selected group will be transferred. Everything to the right of
- the (B) or (T) is new. If FILE SCAN is OFF, you only get the (B)
- or (T) as before.
-
- Note: Big and Little Endian refer to the ordering of bytes
- within a computer word. Big Endian architecture is standard and
- is used on most non-PC computers. Little Endian architecture is
- used on PCs.
-
- To illustrate file-transfer with scanning, suppose you have a directory
- containing a mixture of text and binary files, and each text file can
- be 7-bit German ISO 646, 8-bit Latin-1, or Unicode in any of the
- following forms: UCS2 Little Endian, UCS2 Big Endian, or UTF8
- ([381]UTF-16 is not supported yet). Assuming all the built-in defaults
- are in effect, the following three commands do the job:
-
- set file char german ; This sets the default for 7-bit text files
- set file char latin1 ; This sets the default for 8-bit text files
- send *
-
- Each file is sent in the appropriate mode (text or binary), with text
- files converted to the appropriate transfer character-set and labeled
- so the receiver can convert them according to its own local
- conventions.
-
- By the way, what if you want to inhibit character-set translation but
- still allow automatic text/binary mode switching? Previously, you could
- simply SET TRANSFER CHARACTER-SET TRANSPARENT. But now with file
- scanning, the file and transfer character-sets are set automatically
- per file. A new command was added for this purpose:
-
- SET TRANSFER TRANSLATION { ON, OFF }
- Enables and disables file-transfer character-set translation. It
- is enabled by default.
-
- When TRANSFER TRANSLATION is OFF but FILE SCAN is ON, files are still
- scanned to see if they are text or binary, but no character-set
- translation is done when they text: only the normal record-format
- conversion.
-
- Like all SET commands, SET TRANSFER TRANSLATION is global and
- persistent. You can also force a particular file-transfer command
- (SEND, MSEND, GET, RECEIVE, TRANSMIT, etc) to not translate without
- affecting the global translation settings by including the new
- /TRANSPARENT switch, e.g.
-
- send /transparent oofa.txt
-
- As of C-Kermit 8.0.206, SET TRANSFER CHARACTER-SET TRANSPARENT implies
- SET TRANSFER TRANSLATION OFF.
-
- File scanning is also used in the TYPE command. The source file type
- and character set are determined as above, and then the file is
- automatically converted to your display character-set, line by line. In
- Kermit 95, the display character-set is Unicode, perhaps converted to
- your current console code page; in other versions of C-Kermit, it is
- your current file character-set. Thus if you have the following set
- appropriately:
-
- SET FILE CHARACTER-SET (necessary in Unix but not K95)
- SET FILE DEFAULT 7BIT CHARACTER-SET
- SET FILE DEFAULT 8BIT CHARACTER-SET
-
- then you should be able to TYPE any text file and see something
- reasonable. For example, in Unix, if your DEFAULT 7BIT-CHARACTER-SET is
- ITALIAN and your DEFAULT 8BIT-CHARACTER-SET is LATIN1, and your FILE
- CHARACTER-SET is LATIN1, you can TYPE an Italian ISO 646 file, a
- Latin-1 file, or any kind of Unicode file, and have it translated
- automatically to Latin-1 for your display.
-
- In the GUI version of Kermit 95, you can see mixtures of many different
- scripts if the file is UTF8 or UCS2: Roman, Cyrillic, Hebrew, Greek,
- Armenian, Georgian, etc, all on the same screen at once.
-
- File scanning also adds a new criterion for file selection, i.e. to
- select only text (or binary) files. Several commands now include a new
- switch, /TYPE:{BINARY,TEXT,ALL}. BINARY means select only binary
- regular files (not directories). TEXT means select only text files. ALL
- means don't scan; select all files. Examples:
-
- SEND /TYPE:BINARY *.*
- Sends only binary files, skipping over text files.
-
- NOTE: File scanning is NOT done when using external protocols (because
- the external protocol programs, such as sz, are processing each file,
- not Kermit).
-
- DIRECTORY /TYPE:TEXT
- Lists only text files but not binary files.
-
- DELETE /TYPE:BINARY foo.*
- Deletes all foo.* files that are regular binary files but does
- not delete any text files.
-
- CHMOD /TYPE:BINARY 775 *
- (UNIX) Changes the permissions of all binary files to 775.
-
- When FILE SCAN is OFF and FILE PATTERNS are ON, behavior is as before
- with PATTERNS ON, but with some improvements:
-
- * Pathnames are now stripped prior to pattern matching.
- * Backup suffixes (like .~3~) are stripped prior to pattern matching.
-
- [ [382]Top ] [ [383]Contents ] [ [384]C-Kermit Home ] [ [385]Kermit
- Home ]
-
-5. FILE AND DIRECTORY NAMES CONTAINING SPACES
-
- Prior to the introduction of the graphical user interface (GUI), it was
- inconceivable that file or directory names could contain spaces,
- because space is a field delimiter in all command languages. GUIs,
- however, use dialog boxes for filenames, so there is never any question
- of distinguishing a filename from adjacent fields -- because there are
- no adjacent fields -- and therefore it has become quite common on
- computers that have GUIs to have file and directory names composed of
- multiple words. Of course this poses problems for command shells and
- other text-oriented programs.
-
- Most command shells address these problems by allowing such names to be
- enclosed in doublequotes, e.g.:
-
- cd "c:\Program Files"
-
- C-Kermit previously used braces for this:
-
- cd {c:\Program Files}
-
- which was not what most people expected. And even when braces were
- used, Kermit had difficulties with completion, file menus, and so
- forth, within braced fields.
-
- C-Kermit 8.0 allows either doublequotes or braces to be used for
- grouping:
-
- send "this file"
- send {this file}
- rename "this file" "that file"
- rename {this file} "that file"
- rename "this file" {that file}
- cd {Program Files}
- cd "Program Files"
-
- Note that the doublequotes or brackets must enclose the whole file or
- directory specification:
-
- "c:\My Directory"
-
- not:
-
- c:\"My Directory"
-
- In C-Kermit 8.0, you can also use completion on these filenames, in
- which case Kermit supplies the quotes (or braces) automatically.
- Example (in which the current directory contains only one file whose
- name starts with "th" and its full name is "this file" (without the
- quotes, but with the space)):
-
- cat th<Tab>
-
- Kermit repaints the filename field like this:
-
- cat "this file"
-
- That is, it backspaces over the original "th" and then writes the
- filename in doublequotes.
-
- If completion is only partial, Kermit still supplies the quotes, but in
- this case also beeps. To continue the filename, you must first
- backspace over the closing quote. The closing quote is supplied in this
- case to make sure that you can see the spaces, especially if they are
- trailing. For example, if the current directory contains two files
- whose names start with "th", and their fill names are "this file" and
- "this other file":
-
- cat th<Tab>
-
- Kermit prints:
-
- cat "this "<Beep>
-
- If it didn't print the closing quote, you would probably wonder why it
- was beeping.
-
- Also, if you begin a filename field with a doublequote or opening
- brace, now you can use completion or get ?-help; this was never
- possible before.
-
- C-Kermit>type "thi? Input file specification, one of the following:
- this file this other file
- C-Kermit>type "thi_
-
- [ [386]Top ] [ [387]Contents ] [ [388]C-Kermit Home ] [ [389]Kermit
- Home ]
-
-6. OTHER COMMAND PARSING IMPROVEMENTS
-
-6.1. Grouping Macro Arguments
-
- Doublequotes now can be used in macro invocations to group arguments
- containing spaces, where previously only braces could be used:
-
- define xx show args
- xx one "this is two" three
-
- Result:
-
- Macro arguments at level 0 (\v(argc) = 4):
- \%0 = xx
- \%1 = one
- \%2 = this is two
- \%3 = three
-
- Also, you can now quote braces and quotes in macro args (this didn't
- work before). Examples:
-
- xx "{" ; The argument is a single left brace
- xx {"} ; The argument is a doublequote character
-
- In case this new behavior interferes with your scripts, you can restore
- the previous behavior with:
-
- SET COMMAND DOUBLEQUOTING OFF
-
-6.2. Directory and File Name Completion
-
- C-Kermit 8.0 also includes better completion for directory names, e.g.
- in the CD command. If the name typed so far uniquely matches a
- directory name, it is completed (as before), but now if the directory
- contains any subdirectories, completion is partial (allowing you to
- supply additional path segments without backspacing); otherwise it is
- complete.
-
- Completion has also been improved for file and directory names that
- contain not only spaces (as described above) but also "metacharacters"
- such as asterisk (*) and tilde (~): now the field is repainted if
- necessary. For example, if the current directory contains only one file
- whose name contains "blah", then in:
-
- type *blah<Tab>
-
- "*blah" is replaced by the filename. In earlier releases, the part
- typed so far was left on the command line (and in the history buffer),
- so even when the original command worked, the recalled version would
- not. Similarly for ~ (the nearly-universal Unix notation for username):
-
- type ~olga/x<Tab>
-
- is repainted as (e.g.):
-
- type /users/home/olga/x(Beep)
-
- Speaking of command history, the new SHOW HISTORY command shows your
- command history and recall buffer. SAVE COMMAND HISTORY saves it into a
- file of your choice.
-
-6.3. Passing Arguments to Command Files
-
- The method for passing arguments to command files has been improved.
- Prior to C-Kermit 7.0 there was no provision for doing this. In
- C-Kermit 7.0, the TAKE command was changed to allow arguments to be
- given after the filename:
-
- take commandfile arg1 arg2 ...
-
- This was accomplished by replacing the current \%1, \%2, etc, with the
- given arguments, since a new set of macro argument variables is created
- only when a macro is executed, not a command file. It is much more
- intuitive, however, if arguments to command files worked like those to
- macros: the command file sees the arguments as its own \%1, \%2, etc,
- but the caller's variables are not disturbed. C-Kermit 8.0 accomplishes
- this by automatically creating an intermediate temporary macro to start
- the command file (if any arguments were given), thus creating a new
- level of arguments as expected.
-
-6.4. More-Prompting
-
- The familiar --more?-- prompt that appears at the end of each screenful
- of command-response output now accepts a new answer: G (Go) meaning
- "show all the rest without pausing and asking me any more questions". P
- (Proceed) is a synonym for G.
-
-6.5. Commas in Macro Definitions
-
- As noted in the [390]C-Kermit manual, comma is used to separate
- commands in a macro definition. Even when the macro is defined on
- multiple lines using curly-brace block-structure notation without
- commas, the definition is still stored internally as a comma-separated
- list of commands. Therefore special tricks are needed to include a
- comma in a command. The classic example is:
-
- define foo {
- (some command)
- if fail echo Sorry, blah failed...
- }
-
- This would result in Kermit trying to execute a "blah" command. This
- could always be handled by enclosing the text in braces:
-
- define foo {
- (some command)
- if fail echo {Sorry, blah failed...}
- }
-
- but doublequotes (more intuitive) should have worked too. Now they do:
-
- define foo {
- (some command)
- if fail echo "Sorry, blah failed..."
- }
-
-6.6. Arrow Keys
-
- As of version 8.0.201, C-Kermit on most platforms lets you access the
- command history buffer with arrow keys, just as you always could with
- control characters. The restrictions are:
-
- 1. Only Up and Down arrow keys are accepted.
- 2. Only 7-bit ANSI arrow-key sequences are understood (ESC followed by
- [ or uppercase letter O, followed by uppercase letter A or (up) B
- (down).
-
- This change was made to facilitate command recall in Linux-based PDAs
- that don't have a Control key, or at least not one that's easily (or
- always) accessible, such as the Sharp Zaurus SL5500.
-
- [ [391]Top ] [ [392]Contents ] [ [393]C-Kermit Home ] [ [394]Kermit
- Home ]
-
-7. NEW COMMANDS AND SWITCHES
-
- See [395]Section 4 for more about file scanning and the /TYPE: switch.
-
- ASK[Q] [ /TIMEOUT:number /QUIET /DEFAULT:text ] variable [ prompt ]
- The new optional /TIMEOUT: switch for ASK and ASKQ causes the
- command to time out and and fail if no response is given within
- the specified number of seconds, 1 or greater (0 or less means
- no timeout, wait forever). This works just like SET ASK-TIMER,
- except its effect is local to the ASK command with which it is
- given and it does not disturb the global ask timer setting. The
- new /QUIET switch tells Kermit not to print an error message if
- the ASK or ASKQ command times out waiting for a response.
-
- Version 8.0.211 adds the /DEFAULT:text switch for ASK-Class
- commands (ASK, ASKQ, and GETOK). This lets you supply a default
- answer in case the user supplies an empty answer or the
- /TIMEOUT: switch was included and the time limit expired without
- an answer. In both these cases, the command succeeds.
-
- CAT filename
- Equivalent to TYPE /NOPAGE.
-
- CDUP
- Changes Kermit's local working directory to the parent of the
- current one. Equivalent to "cd .." in UNIX or Windows, "cd [-]"
- in VMS, "cd ^" in AOS/VS, etc; in other words, it's a
- platform-independent way of moving one level up in a directory
- tree.
-
- CHMOD [ switches ] permission files
- UNIX only. Sets file permissions for one or more files or
- directories. The permission must be given as an octal number,
- e.g. 664, 755. Switches: /DIRECTORIES, /FILES, /NOLIST, /PAGE,
- /DOTFILES, /LIST, /NOPAGE, /RECURSIVE, /TYPE:{TEXT,BINARY,ALL},
- /SIMULATE. The /TYPE: switch allows selection of only text or
- binary files. For example, if you have a mixture of source files
- and executables, you can use "chmod /files /type:text 664" to
- give owner/group read/write and world read permission to the
- text files, and "chmod /files /type:binary 775" to give the same
- plus execute permission to the executables. Use /SIMULATE to see
- which files would be affected, without actually changing their
- permissions.
-
- CLEAR KEYBOARD-BUFFER
- Flushes any as-yet unread characters from the keyboard input
- buffer. Useful for flushing typeahead in scripts.
-
- CONTINUE
- When given at an interactive command prompt that was reached by
- issuing a PROMPT command (described in this section) from a
- script, this command returns to the script, continuing its
- execution at the command after the PROMPT command. In this
- context, CONTINUE is simply a more-intuitive synonym for END.
-
- COPY, RENAME, and TRANSLATE
- These commands now work on file groups if the target filename is
- a directory, e.g. "copy oofa.* ..", "rename * ~olga/tmp/"
-
- COPY /APPEND source destination
- The source file specification can now include wildcards, in
- which case all of the source files that match will go into the
- destination file in alphabetical order by name.
-
- DELETE /ASK
- Asks permission to delete each file before deleting it. In
- C-Kermit 7.0, the answers were "yes" (or "ok") and "no".
- C-Kermit 8.0 adds "go" (meaning, delete all the rest without
- asking) and "quit" (cancel the DELETE command and return to the
- prompt).
-
- DELETE /DIRECTORIES
- Deletes not only files but also directories.
-
- DELETE /RECURSIVE
- Deletes all files that match the given file specification in the
- current (or given) directory and all directories beneath it.
-
- DELETE /SUMMARY
- Prints only the number of files deleted and total size freed,
- without listing each file.
-
- DELETE /TREE
- Shorthand for DELETE /RECURSIVE /DIRECTORIES /DOTFILES/.
- Equivalent to Windows DELTREE or Unix "rm -Rf". If no file
- specification is given, the contents of the current directory,
- plus all of its subdirectories and their contents, are deleted.
-
- DELETE /TYPE:BINARY
- Delete only regular binary files (requires FILE SCAN ON).
-
- DELETE /TYPE:TEXT
- Delete only regular text files (requires FILE SCAN ON).
-
- DIRECTORY [ switches ] [ filespec [ filespec [ filespec ... ] ] ]
- The DIRECTORY command now accepts more than one file
- specification; e.g. "directory moon.txt sun.doc stars.*".
-
- DIRECTORY /NORECURSIVE xxx
- If xxx is a directory name, forces listing of the directory
- itself rather than its contents.
-
- DIRECTORY /FOLLOWLINKS xxx
- (UNIX only) Tells the DIRECTORY command to follow symbolic
- links. This not the default because it can cause endless loops.
-
- DIRECTORY /NOFOLLOWLINKS xxx
- (UNIX only) Tells the DIRECTORY command not to follow symbolic
- links, but rather, merely to list them. This is the default.
-
- DIRECTORY /OUTPUT:filename
- Sends the results of the DIRECTORY command to the given file.
-
- DIRECTORY /SUMMARY
- Prints only the number of directories and files and the total
- size, without listing each file.
-
- DIRECTORY /TYPE:{TEXT,BINARY}
- Shows only files of the selected type, based on file scan.
-
- DIRECTORY /XFERMODE
- Now shows results of file scan (see [396]Section 4).
-
- FOPEN [ switches ] channel filename
-
- As of version 8.0.211, FOPEN allows /dev/tty as a filename in
- Unix-based operating systems.
-
- FREAD /TRIM
- (8.0.211) Trims any trailing blanks or tabs from the item (such
- as a line of text) that it has read.
-
- FREAD /UNTABIFY
- (8.0.211) Converts Horizontal Tab characters to the appropriate
- number of spaces, based on VT100-like tab stops (1,9,17,25,...).
-
- GREP [ switches ] pattern files
- Similar to Unix grep command: displays file lines that match the
- given [397]pattern. Switches:
-
- /COUNT[:variable]
- Don't show the matching lines, just tell how many lines
- match. If a variable name is specified, the count is
- stored in the given variable.
-
- /DOTFILES
- Include files whose names begin with dot.
-
- /LINENUMBERS
- Show line numbers of matching lines.
-
- /NAMEONLY
- only list the names of files that contain matching lines,
- but not the lines themselves.
-
- /NOBACKUP
- Skip backup files.
-
- /NOCASE
- Ignore alphabetic case while pattern matching.
-
- /NODOTFILES
- skip files whose names start with dot (period).
-
- /NOLIST
- Suppress output but set SUCCESS or FAILURE according to
- search result.
-
- /NOMATCH
- Look for lines that do not match the pattern.
-
- /NOPAGE
- Don't pause between screens of output.
-
- /OUTPUT:filename
- Write results into the given file.
-
- /PAGE
- Pause between screens of output.
-
- /RECURSIVE
- Search files in subdirectories too.
-
- /TYPE:{TEXT,BINARY}
- Search only files of the specified type.
-
- Synonyms: FIND, SEARCH.
-
- GETOK /TIMEOUT:n /QUIET /DEFAULT:text
- The new /QUIET switch instructs GETOK, when given a timeout, not
- to print an error message if it times out. As of 8.0.211, a
- default answer can be supplied (see ASK).
-
- HEAD [ switches ] filename
- Equivalent to TYPE /HEAD [ other-switches ] filename.
-
- HELP DATE
- Explains date-time formats, including timezone notation and
- delta times.
-
- HELP FIREWALLS
- Explains the firewall negotiation capabilities of your version
- of Kermit.
-
- KCD [ symbolic-directory-name ]
- Changes Kermit's working directory to the named symbolic
- directory, such as such as exedir, inidir, startup, download, or
- and home. Type "kcd ?" for a list of symbolic directory names
- known to your copy of Kermit, or give the new ORIENTATION
- command for a more detailed explanation. If you give a KCD
- command without a directory name, Kermit returns to its "home"
- directory, which is determined in some way that depends on the
- underlying operating system, but which you can redefine with the
- (new) SET CD HOME command. Your home directory is shown by SHOW
- CD and it's also the value of the \v(home) variable.
-
- LICENSE
- Displays the C-Kermit license.
-
- L-commands
- When Kermit has a connection to a Kermit or FTP server, file
- management commands such as CD, DIRECTORY, and DELETE might be
- intended for the local computer or the remote server. C-Kermit
- 8.0.200 and earlier always executes these commands on the local
- computer. If you want them executed by the remote server, you
- have to prefix them with REMOTE (e.g. REMOTE CD) or use special
- R-command aliases (e.g. RCD = REMOTE CD, RDIR = REMOTE DIR,
- etc). But this feels unnatural to FTP users, who expect
- unprefixed file management commands to be executed by the remote
- server, rather than locally. C-Kermit 8.0.201 adds automatic
- locus switching to present an FTP-like interface for FTP
- connections and the normal Kermit interface for Kermit
- connections, and a SET LOCUS command (described below) to
- control whether or how this is done. For when LOCUS is REMOTE, a
- new set of commands was added for local management: LCD (Local
- CD), LDIR (Local DIR), etc. These are described below under SET
- LOCUS.
-
- MORE filename
- Equivalent to TYPE /PAGE.
-
- ORIENTATION
- Displays symbolic directory names and the corresponding variable
- names and values. The symbolic names, such as exedir, inidir,
- startup, download, and home, can be used as arguments to the new
- KCD command.
-
- PROMPT [ text ]
- For use in a macro or command file: enters interactive command
- mode within the current context ([398]Section 8.1). If the
- optional text is included, the prompt is set to it. The text can
- include variables, functions, etc, as in the SET PROMPT command.
- They are evaluated each time the prompt is printed. Unlike the
- SET PROMPT command, the text argument applies only to the
- current command level. Thus you can have different prompts at
- different levels.
-
- REMOTE SET MATCH { DOTFILE, FIFO } { ON, OFF }
- Allows the client to tell the server whether wildcards sent to
- the server should match dot files (files whose names begin with
- period) or FIFOs (named pipes). See SET MATCH.
-
- SET ATTRIBUTE RECORD-FORMAT { ON, OFF }
- Allows control of the Kermit's Record-Format attribute. Set this
- to OFF in case incoming file are refused due to unknown or
- invalid record formats if you want to accept the file anyway
- (and, perhaps, postprocess it to fix its record format).
-
- SET CD HOME [ directory ]
- Specifies the target directory for the CD and KCD commands, when
- they are given without an argument, and also sets the value of
- the \v(home) variable.
-
- SET EXIT HANGUP { OFF, ON }
- Normally ON, meaning that when Kermit exits, it also explicitly
- hangs up the current SET LINE / SET PORT serial port according
- to the current SET MODEM TYPE and SET MODEM HANGUP METHOD, and
- closes the port device if it was opened by Kermit in the first
- place (as opposed to inherited). SET EXIT HANGUP OFF tells
- Kermit not to do this. This can't prevent the operating system
- from closing the device when Kermit exits (and it's a "last
- close") but if the port or modem have been conditioned to
- somehow ignore the close and keep the connection open, at least
- Kermit itself won't do anything explicit to hang it up or close
- it.
-
- SET FILE EOF { CTRL-Z, LENGTH }
- Specifies the end-of-file detection method to be used by
- C-Kermit when sending and receiving text files, and in the TYPE
- and similar text-file oriented commands. The normal and default
- method is LENGTH. You can specify CTRL-Z when handling CP/M or
- MS-DOS format text files, in which a Ctrl-Z (ASCII 26) character
- within the file marks the end of the file.
-
- SET FILE LISTSIZE number
- Allocates space for the given number of filenames to be filled
- in by the wildcard expander. The current number is shown by SHOW
- FILE. If you give a command that includes a filename containing
- a wildcard (such as "*") that matches more files that Kermit's
- list has room for, you can adjust the list size with this
- command.
-
- SET FILE STRINGSPACE number
- Allocates space for the given amount of filename strings for use
- by the wildcard expander. The current number is shown by SHOW
- FILE. The number is the total number of bytes of all the file
- specifications that match the given wildcard.
-
- If you need to process a bigger list of files than your computer has
- memory for, you might be able use an external file list. The Kermit
- SEND and the FTP PUT and GET commands accept a /LISTFILE: switch,
- which gives the name of a file that contains the list of files to be
- transferred. Example for UNIX:
-
- !find . -print | grep / > /tmp/names
- ftp put /update /recursive /listfile:/tmp/names
-
- SET LOCUS { AUTO, LOCAL, REMOTE }
- Added in C-Kermit 8.0.201. Sets the locus for unprefixed file
- management commands such as CD, DIRECTORY, MKDIR, etc. When
- LOCUS is LOCAL these commands act locally and a REMOTE (or R)
- prefix (e.g. REMOTE CD, RCD, RDIR) is required to send file
- management commands to a remote server. When LOCUS is REMOTE, an
- L prefix is required to issue local file management commands
- (e.g. LCD, LDIR). The word LOCAL can't be used as a prefix since
- it is already used for declaring local variables. LOCUS applies
- to all types of connections, and thus is orthogonal to SET
- GET-PUT-REMOTE, which selects between Kermit and FTP for remote
- file-transfer and management commands. The default LOCUS is
- AUTO, which means we switch to REMOTE whenever an FTP connection
- is made, and to LOCAL whenever a non-FTP connection is made, and
- switch back accordingly whenever a connection is closed. So by
- default, Kermit behaves in its traditional manner unless you
- make an FTP connection, in which case it acts like a regular FTP
- client (but better :-) LOCUS applies to the following
- commands:
-
- Unprefixed Remote Local Description
- CD (CWD) RCD LCD Change (Working) Directory
- CDUP RCDUP LCDUP CD Up
- PWD RPWD LPWD Print Working Directory
- DIRECTORY RDIR LDIR Request a directory listing
- DELETE RDEL LDEL Delete (a) file(s)
- RENAME RREN LREN Rename a file
- MKDIR RMKDIR LMKDIR Create a directory
- RMDIR RRMDIR LRMDIR Remove a directory
-
- SET MATCH { DOTFILE, FIFO } { ON, OFF }
- Whether C-Kermit filename patterns (wildcards) should match
- filenames that start with dot (period), or (Unix only) FIFOs
- (named pipes). The defaults are to skip dotfiles in Unix but
- match them elsewhere, and to skip FIFOs. Applies to both
- interactive use and to server mode, when the server receives
- wildcards, e.g. in a GET command. Also see REMOTE SET MATCH.
-
- SET OPTIONS DIRECTORY /DOTFILES
- Now works for server listings too (UNIX only). Give this command
- prior to having Kermit enter server mode, and then it will show
- files whose names begin with dot (period) when sent a REMOTE
- DIRECTORY command.
-
- SET QUIET ON
- (as well as the -q command-line option) Now applies also to:
-
- + SET HOST connection progress messages.
- + "Press the X or E key to cancel" file-transfer message.
- + REMOTE CD response.
- + REMOTE LOGIN response.
-
- SET RECEIVE PERMISSIONS { ON, OFF }
- Tells C-Kermit whether to set the permissions of incoming files
- (received with Kermit protocol) from the permissions supplied in
- the file's Attribute packet (if any). Normally ON. Also see SET
- SEND PERMISSIONS.
-
- SET ROOT directory
- Like UNIX chroot, without requiring privilege. Sets the root for
- file access, does not allow reference to or creation of files
- outside the root, and can't be undone.
-
- SET SEND PERMISSIONS { ON, OFF }
- Tells C-Kermit whether to include file permissions in the
- attributes it includes with each file when sending with Kermit
- protocol. Also see SET RECEIVE PERMISSIONS.
-
- SET TCP { HTTP-PROXY, SOCKS-SERVER } /USER:name /PASSWORD:text
- These commands now allow specification of username and password.
-
- SET TERMINAL . . .
- (See [399]Section 12.)
-
- SET TRANSFER MESSAGE [ text ]
- Sets an initial text message to be displayed in the
- file-transfer display. The transfer message is automatically
- deleted once used, so must be set each time a message a desired.
- Any variables in the message are evaluated at the time the SET
- command is given. If the optional text is omitted, any transfer
- message that is currently set is removed. Synonym: SET XFER MSG.
- SHOW TRANSFER displays it if it has been set but not yet used.
-
- SHOW COMMUNICATIONS
- In C-Kermit 8.0, SHOW COMMUNICATIONS, when given in remote mode
- (i.e. before any connection has been established), tells the
- typical dialout device name for the particular platform on which
- it's running (e.g. TXA0: for VMS, or /dev/cua0p0 for HP-UX). On
- Unix platforms, it also tells the name of the lockfile
- directory. This way, you have an idea of what the SET LINE
- device name should look like, and if the SET LINE command fails,
- you know the name of the directory or device that is protected
- against you.
-
- SHOW VARIABLES [ name [ name [ ... ] ] ]
- In C-Kermit 8.0.201 you can request values of a list of built-in
- (\v(xxx)) variables. Each name is a pattern, as before, but now
- it a free pattern rather than an anchored one (explained in
- [400]Section 8.12) so now "show var date time" shows the values
- of all variables whose names include the strings "date" or
- "time".
-
- TAIL [ switches ] filename
- Equivalent to TYPE /TAIL [ other-switches ] filename.
-
- TRANSMIT /NOECHO [ other switches ] filename
- The /NOECHO switch is equivalent to giving the command SET
- TRANSMIT ECHO OFF prior to the TRANSMIT command, except the
- switch affects only the command with which it was given and does
- not affect the prevailing global setting.
-
- TRANSMIT /NOWAIT [ other switches ] filename
- The /NOWAIT switch is equivalent to giving the command SET
- TRANSMIT PROMPT 0 prior to the TRANSMIT command, except the
- switch affects only the command with which it was given and does
- not affect the prevailing global setting.
-
- TRANSMIT /NOWAIT /NOECHO /BINARY [ other switches ] filename
- When the TRANSMIT command is given with the /NOWAIT, /NOECHO,
- and /BINARY switches, this activates a special "blast the whole
- file out the communications connection all at once" mode that
- Kermit didn't have prior to version 8.0. There has been
- increasing demand for this type of transmission with the advent
- of devices that expect image (e.g. .JPG) or sound (e.g. .MP3)
- files as raw input. The obvious question is: how does the
- receiving device know when it has the whole file? This depends
- on the device, of course; usually after a certain amount of time
- elapses with nothing arriving, or else when Kermit hangs up or
- closes the connection.
-
- TYPE /CHARACTER-SET:name
- Allows you to specify the character set in which the file to be
- typed is encoded.
-
- TYPE /NUMBER
- Adds line numbers.
-
- TYPE /OUTPUT:filename
- Sends the results of the TYPE command to the given file.
-
- TYPE /TRANSLATE-TO:name
- Used in conjunction with TYPE /CHARACTER-SET:xxx; allows you to
- specify the character set in which the file is to be displayed.
-
- TYPE /TRANSPARENT
- Used to disable character-set translation in the TYPE command,
- which otherwise can take place automatically based on file
- scanning, even when /CHARACTER-SET and /TRANSLATE-TO switches
- are not given.
-
- VOID text
- Parses the text, evaluating any backslash items in it (such as
- function calls) but doesn't do anything further, except possibly
- printing error messages. Useful for invoking functions that have
- side effects without using or printing their direct results,
- e.g. "void \fsplit(\%a,&a)".
-
-Symbolic Links in UNIX
-
- The UNIX versions of C-Kermit have had /FOLLOWLINKS and /NOFOLLOWLINKS
- switches added to several commands to control the treatment of symbolic
- links. Different commands deal differently with symbolic links:
-
- Kermit SEND, FTP MPUT
- /NOFOLLOWLINKS is the default, which means symbolic links are
- skipped entirely. The alternative, /FOLLOWLINKS, should be used
- with caution, since an innocent link might point to a whole file
- system, or it might cause a loop. There is no way in Kermit or
- FTP protocol to send the link itself. We either skip them or
- follow them; we can't duplicate them.
-
- DIRECTORY
- /NOFOLLOWLINKS is the default, which means the DIRECTORY command
- lists symbolic links in a way that shows they are links, but it
- does not follow them. The alternative, /FOLLOWLINKS, follows
- links and gives information about the linked-to directories and
- files.
-
- DELETE, RMDIR
- The DELETE command does not have link-specific switches. DELETE
- never follows links. If you tell Kermit to delete a symbolic
- link, it deletes the link itself, not the linked-to file. Ditto
- for RMDIR.
-
- COPY
- The COPY command behaves just like the UNIX cp command; it
- always follows links.
-
- RENAME
- The RENAME command behaves just like the UNIX mv command; it
- operates on links directly rather than following.
-
- [ [401]Top ] [ [402]Contents ] [ [403]C-Kermit Home ] [ [404]Kermit
- Home ]
-
-8. OTHER SCRIPTING IMPROVEMENTS
-
-8.1. Performance and Debugging
-
- A command cache for frequently used commands plus some related
- optimizations increases the speed of compute-bound scripts by anywhere
- from 50% to 1000%.
-
- The new PROMPT command can be used to set breakpoints for debugging
- scripts. If executed in a command file or macro, it gives you an
- interactive command prompt in the current context of the script, with
- all its variables, arguments, command stack, etc, available for
- examination or change, and the ability to resume the script at any
- point (END resumes it, Ctrl-C or STOP cancels it and returns to top
- level).
-
- The new Ctrl-C trapping feature ([405]Section 8.14) lets you intercept
- interruption of scripts. This can be used in combination with the
- PROMPT command to debug scripts. Example:
-
-define ON_CTRLC {
- echo INTERRUPTED BY CTRL-C...
- echo The command stack has not yet been rolled back:
- show stack
- echo Type Ctrl-C again or use the END command to return to top level.
- prompt Debug>
-}
-
- Adding this ON_CTRL definition to your script lets you interrupt it at
- any point and get prompt that is issued at the current command level,
- so you can query local variables, etc.
-
- [ [406]Top ] [ [407]Contents ] [ [408]C-Kermit Home ] [ [409]Kermit
- Home ]
-
-8.2. Using Macros as Numeric Variables
-
- A macro is a way to assign a value to a name, and then use the name to
- refer to the value. Macros are used in two ways in Kermit: as
- "subroutines" or functions composed of Kermit commands, which are
- executed, or as variables to hold arbitrary values -- text, numbers,
- filenames, etc.
-
- When a macro is to be executed, its name is given as if it were a
- C-Kermit command, optionally preceded by the word "do". When a macro is
- used as a variable, it must be "escaped" with \m(xxx) (or equivalent
- function, e.g. \s(xxx), \:(xxx), \fdefinition(xxx)), where xxx is the
- macro name, for example:
-
- define filename /usr/olga/oofa.txt
- send \m(filename)
-
- Of course variables can also hold numbers:
-
- define size 17
- declare \&a[\m(size)]
- ...
- define index 3
- if ( == \m(index) 3 ) echo The third value is: \&a[\m(index)]
- evaluate index (\m(index) * 4)
- if ( > \m(index) \m(size) ) echo Out of range!
-
- But these are contexts in which only numbers are valid. C-Kermit 8.0
- has been changed to treat non-escaped non-numeric items in strictly
- numeric contexts as macro names. So it is now possible (but not
- required) to omit the \m(...) notation and just use the macro name in
- these contexts:
-
- define size 17
- declare \&a[size]
- ...
- define index 3
- if ( == index 3 ) echo The third value is: \&a[index]
- evaluate index (index * 4)
- if ( > index size ) echo Out of range!
-
- This is especially nice for loops that deal with arrays. Here, for
- example, is a loop that reverses the order of the elements in an array.
- Whereas formerly it was necessary to write:
-
- .\%n ::= \fdim(&a)
- for \%i 1 \%n/2 1 {
- .tmp := \&a[\%n-\%i+1]
- .\&a[\%n-\%i+1] := \&a[\%i]
- .\&a[\%i] := \m(tmp)
- }
-
- Recoding this to use macro names "i" and "n" instead of the backslash
- variables \%i and \%n, we have:
-
- .n ::= \fdim(&a)
- for i 1 n/2 1 {
- .tmp := \&a[n-i+1]
- .\&a[n-i+1] := \&a[i]
- .\&a[i] := \m(tmp)
- }
-
- which reduces the backslash count to less than half. The final
- statement in the loop could be written ".\&a[i] ::= tmp" if the array
- contained only numbers (since ::= indicates arithmetic expression
- evaluation).
-
- Also, now you can use floating-point numbers in integer contexts (such
- as array subscripts), in which case they are truncated to an integer
- value (i.e. the fractional part is discarded).
-
- Examples of numeric contexts include:
-
- * Array subscripts.
- * Any numeric function argument.
- * Right-hand side of ::= assignments.
- * EVALUATE command or \fevaluate() function expression.
- * The INCREMENT or DECREMENT by-value.
- * IF =, >, <, !=, >=, and <= comparands.
- * The IF number construct.
- * FOR-loop variables.
- * STOP, END, and EXIT status codes.
- * The INPUT timeout value.
- * PAUSE, WAIT, SLEEP, MSLEEP intervals.
- * The SHIFT argument.
- * Numeric switch arguments, e.g. TYPE /WIDTH:number, SEND
- /LARGER:number.
- * SCREEN MOVE-TO row and column number.
- * Various SET DIAL parameters (timeout, retry limit, etc).
- * Various SET SEND or RECEIVE parameters (packet length, window size,
- etc).
- * Various other SET parameters.
-
- and:
-
- * S-Expressions (explained in [410]Section 9).
-
- Macro names used in numeric contexts must not include mathematical
- operators. Although it is legal to create a macro called "foo+bar", in
- a numeric context this would be taken as the sum of the values of "foo"
- and "bar". Any such conflict can be avoided, of course, by enclosing
- the macro name in \m(...).
-
- [ [411]Top ] [ [412]Contents ] [ [413]C-Kermit Home ] [ [414]Kermit
- Home ]
-
-8.3. New IF Conditions
-
- Several new IF conditions are available:
-
- IF DECLARED arrayname
- Explained in [415]Section 8.6.
-
- IF KBHIT
- Allows a script to test whether a key was pressed without
- actually trying to read it.
-
- IF KERBANG (Unix only)
- True if Kermit was started from a Kerbang script. This is useful
- for knowing how to interpret the \&@[] and \&_[] argument vector
- arrays, and under what conditions to exit.
-
- IF INTEGER n
- This is just a synonym for IF NUMERIC, which is true if n
- contains only digits (or, if n is a variable, its value contains
- only digits).
-
- By contrast, IF FLOAT n succeeds if n is a floating-point number OR an
- integer (or a variable with floating-point or integer value).
- Therefore, IF FLOAT should be used whenever any kind of number is
- acceptable, whereas IF INTEGER (or IF NUMERIC) when only an integer can
- be used.
-
- [ [416]Top ] [ [417]Contents ] [ [418]C-Kermit Home ] [ [419]Kermit
- Home ]
-
-8.4. The ON_UNKNOWN_COMMAND Macro
-
- The new ON_UNKNOWN_COMMAND macro, if defined, is executed whenever you
- give a command that is not known to C-Kermit; any operands are passed
- as arguments. Here are some sample definitions:
-
- DEF ON_UNKNOWN_COMMAND telnet \%1 ; Treat unknown commands as hostnames
- DEF ON_UNKNOWN_COMMAND dial \%1 ; Treat unknown commands phone numbers
- DEF ON_UNKNOWN_COMMAND take \%1 ; Treat unknown commands as filenames
- DEF ON_UNKNOWN_COMMAND !\%* ; Treat unknown commands as shell commands
-
- The ON_CD macro, if defined, is executed whenever Kermit is given a CD
- (change directory) command (8.0.211). Upon entry to this macro, the
- directory has already changed and the new directory string is available
- in the \v(directory) variable, and also as the first argument (\%1).
-
- [ [420]Top ] [ [421]Contents ] [ [422]C-Kermit Home ] [ [423]Kermit
- Home ]
-
-8.5. The SHOW MACRO Command
-
- The SHOW MACRO command has been changed to accept more than one macro
- name:
-
- (setq a 1 b 2 c 3)
- show mac a b c
- a = 1
- b = 2
- c = 3
-
- An exact match is required for each name (except that case doesn't
- matter). If you include wildcard characters, however, a pattern match
- is performed:
-
- show mac [a-c]*x
-
- shows all macros whose names start with a, b, or c, and end with x.
-
- [ [424]Top ] [ [425]Contents ] [ [426]C-Kermit Home ] [ [427]Kermit
- Home ]
-
-8.6. Arrays
-
- A clarification regarding references to array names (as opposed to
- array elements): You can use array-name "abbreviations" like &a only in
- contexts that expect array names, like ARRAY commands or array-name
- function arguments such as the second argument of \fsplit(). In a LOCAL
- statement, however, you have to write \&a[], since "local &a" might
- refer to a macro named "&a".
-
- In function arguments, however, you MUST use the abbreviated form:
- \fsplit(\%a,&a) or \fsplit(\%a,&a[]). If you include the backslash (as
- in "\fsplit(\%a,\&a[])") a parse error occurs.
-
- Here are the new array-related commands:
-
- IF DECLARED arrayname
- Allows a script to test whether an array has been declared. The
- arrayname can be a non-array backslash variable such as \%1 or
- \m(name), in which case it is evaluated first, and the result is
- treated as the array name. Otherwise, arrayname is treated as in
- the ARRAY commands: it can be a, &a, &a[], \&a, \&a[], \&a[3],
- \&a[3:9], etc, with the appropriate results in each case.
- Synonym: IF DCL.
-
- UNDECLARE arrayname
- UNDECLARE is a new top-level command to undeclare an array.
- Previously this could only be done with "declare \&a[0]" (i.e.
- re-declare the array with a dimension of 0).
-
- ARRAY LINK linkname arrayname
- Creates a symbolic link from the array named by linkname (which
- must be the name of an array that is not yet declared in the
- current context) to the array named by arrayname (which must the
- name of a currently declared array that is not itself a link, or
- a variable containing the name of such an array). The two names
- indicate the same array: if you change an array element, the
- change is reflected in the link too, and vice versa. If you
- undeclare the link, the real array is unaffected. If you
- undeclare the real array, all links to it disappear. If you
- resize an array (directly or through a link), all links to it
- are updated automatically.
-
- Array links let you pass array names as arguments to macros. For
- example, suppose you had a program that needed to uppercase all the
- elements of different arrays at different times. You could write a
- macro to do this, with the array name as an argument. But without array
- links, there would be no way to refer to the argument array within the
- macro. Array links make it easy:
-
- define arrayupper {
- local \&e[] \%i
- array link \&e[] \%1
- for i 1 \fdim(&e) 1 { .\&e[i] := \fupper(\&e[i]) }
- }
- declare \&a[] = these are some words
- arrayupper &a
- show array &a
-
- The macro declares the array link LOCAL, which means it doesn't
- conflict with any array of the same name that might exist outside the
- macro, and that the link is destroyed automatically when the macro
- exits. This works, by the way, even if the link name and the macro
- argument name are the same, as long as the link is declared LOCAL.
-
- As noted, you can't make a link to a nonexistent array. So when writing
- a macro whose job is to create an array whose name is passed as an
- argument, you must declare the array first (the size doesn't matter as
- long as it's greater than 0). Example:
-
- define tryme { ; Demonstration macro
- local \&e[] ; We only need this inside the macro
- array link \&e[] \%1 ; Make local link
- shift ; Shift argument list
- void \fsplit(\%*,&e) ; Split remainder of arg list into array
- }
- declare \&a[1] ; Declare target array in advance
- tryme &a here are some words ; Invoke the macro with array name and words
- show array a ; See the results
-
- One final improvement allows the macro itself to declare the array
- (this was not possible in earlier Kermit releases): if the array name
- in the DECLARE command is a variable (and not an array name), or
- includes variables, the resulting value is used as the array name. So:
-
- define tryme { ; Demonstration macro
- declare \%1[1] ; Preliminary declaration for target array
- local \&e[] ; We only need this inside the macro
- array link \&e[] \%1 ; Make local link
- shift ; Shift argument list
- void \fsplit(\%*,&e) ; Split remainder of arg list into array
- }
- tryme &a here are some words ; Invoke the macro with array name and words
- show array a ; See the results
-
- The SHOW ARRAY command now indicates whether an array name is a link.
-
- Also see the descriptions of [428]\fjoin() and [429]\fsplit(), plus
- [430]Section 8.10 on the MINPUT command, which shows how an entire
- array (or segment of it) can be used as the MINPUT target list.
-
- [ [431]Top ] [ [432]Contents ] [ [433]C-Kermit Home ] [ [434]Kermit
- Home ]
-
-8.7. New or Improved Built-in Variables and Functions
-
- The following new built-in variables are available:
-
- \v(buildid) A date string like "20000808" indicating when C-Kermit was b
-uilt.
- \v(ftime) Current time, secs since midnight, including fraction of sec
-ond.
- \v(iprompt) The current SET PROMPT value
- \v(sexp) The most recent S-Expression (see [435]Section 9)
- \v(sdepth) The current S-Expression invocation depth ([436]Section 9)
- \v(svalue) The value of the most recent S-Expression ([437]Section 9)
-
- \v(ftp_code) Most recent FTP response code ([438]Section 3)
- \v(ftp_connected) FTP connection status ([439]Section 3)
- \v(ftp_cpl) FTP Command Protection Level ([440]Section 3.2)
- \v(ftp_dpl) FTP Data Protection Level ([441]Section 3.2)
- \v(ftp_getputremote) The current SET GET-PUT-REMOTE setting ([442]Section 3.8)
-
- \v(ftp_host) Name or IP address of FTP server ([443]Section 3)
- \v(ftp_loggedin) FTP login status ([444]Section 3)
- \v(ftp_message) Most recent FTP response message ([445]Section 3)
- \v(ftp_security) FTP Security method ([446]Section 3.2)
- \v(ftp_server) OS type of FTP server ([447]Section 3)
-
- \v(http_code) Most recent HTTP response code
- \v(http_connected) HTTP connection status
- \v(http_host) Name or IP address of HTTP server
- \v(http_message) Most recent HTTP response message
- \v(http_security) TLS cipher used to secure the HTTP session
-
- \v(hour) Hour of the day, 0 to 23.
- \v(timestamp) Equivalent to "\v(ndate) \v(time)".
-
- \v(log_debug) Current debug log file, if any.
- \v(log_packet) Current packet log file, if any.
- \v(log_session) Current session log file, if any.
- \v(log_transaction) Current transaction log file, if any.
- \v(log_connection) Current connection log file, if any.
-
- The following new or improved built-in functions are available:
-
- \fcmdstack() Allows programmatic access to the command stack.
- \fcvtdate() [448]Section 8.13, format options added
- \fdelta2secs() [449]Section 8.13
- \fdostounixpath(s1) Converts a DOS filename to Unix format.
- \fsplit() Now allows grouping/nesting in source string.
- \fword() Allows the same grouping and nesting.
- \fjoin(&a,s1,n1,n2) Copies an array into a single string.
- \fsubstitute(s1,s2,s3) Substitutes characters within a string.
- \freplace() Has new 4th "occurrence" argument.
- \fsexpression() Evaluates an S-Expression (explained in [450]Section 9
-).
- \ftrim(), \fltrim() Now trim CR and LF by default, as well as SP and Tab.
- \funixtodospath(s1) Converts a Unix filename to DOS format.
- \fkeywordval(s1,c1) Assigns values to keywords (macros) (explained below).
-
- Most functions that have "2" in their names to stand for the word "to"
- can now also be written with "to", e.g. "\fdelta2secs(),"
- \fdeltatosecs()."
-
- \funtabify(string)
- (New to 8.0.211) Replaces Horizontal Tab characters in the given
- string with spaces based on VT100-like tab stops.
-
- \fverify(s1,s2,n)
- As of version 8.0.211, returns -1 if s2 is an empty string.
- Previously it returned 0, making \fverify(abc,\%a) look as if
- \%a was a string composed of a's, b's, and/or c's when in fact
- it contained nothing.
-
- \fcode(string)
- As of version 8.0.211, returns 0 if string is empty or missing.
- Previously it returned the empty string, which made it unsafe to
- use in arithmetic or boolean expressions.
-
- \v(inscale)
- New to version 8.0.211, its value is the INPUT SCALE-FACTOR
- ([451]Section 8.10), default 1.0.
-
-8.7.1. The \fkeywordval() Function
-
- \fkeywordval(s1,c1) is new to C-Kermit 8.0. Given a string s1 of the
- form "name=value", it creates a macro with the given name and assigns
- it the given value. If no value appears after the equal sign, any
- existing macro of the given name is undefined. Blanks are automatically
- trimmed from around the name and value. The optional c1 parameter is
- the assignment operator character, equal sign (=) by default. This
- function is handy for processing keyword parameters or any other form
- of parameter-value pair. Suppose, for example, you want to write a
- macro that accepts keyword parameters rather than positional ones:
-
- define MYDIAL {
- local \%i modem hangup method device speed number
- def number 5551234 ; Assign default parameter values
- def speed 57600
- def modem usrobotics
- def hangup rs232
- def method tone
- def country 1
- for \%i 1 \v(argc)-1 1 { ; Parse any keyword parameters...
- if not \fkeywordval(\&_[\%i]) end 1 Bad parameter: "\&_[\%i]"
- }
- set dial country \m(country)
- set modem type \m(modem)
- set modem hang \m(hangup)
- set dial method \m(tone)
- set line \m(device)
- if fail stop 1
- set speed \m(speed)
- if fail stop 1
- show comm
- set dial display on
- dial \m(number)
- if success connect
- }
-
- In this example, all the defaults are set up inside the macro, and
- therefore it can be invoked with no parameters at all. But if you want
- to have the macro dial a different number, you can supply it as
- follows:
-
- mydial number=7654321
-
- You can supply any number of keyword parameters, and you can give them
- in any order:
-
- mydial number=7654321 hangup=modem speed=115200
-
-8.7.2. The \fsplit(), \fjoin(), and \fword() Functions
-
- \fjoin(&a,s1,n1,n2) is also new; it creates a string from an array (or
- a piece of one). &a is the name of the array (a range specifier can be
- included); s1 is a character or string to separate each element in the
- result string (can be omitted, in which case the elements are not
- separated at all), and n1 is a grouping mask, explained below. If s1 is
- empty or not specified, the array elements are separated with spaces.
- If you want the elements concatenated with no separator, include a
- nonzero n2 argument. Given the array:
-
- declare \&a[] = 0 1 2 3 4 5 6 7 8 9
-
- you can get effects like this:
-
- \fjoin(&a) 0 1 2 3 4 5 6 7 8 9
- \fjoin(&a,:) 0:1:2:3:4:5:6:7:8:9
- \fjoin(&a,{,}) 0,1,2,3,4,5,6,7,8,9
- \fjoin(&a,...) 0...1...2...3...4...5...6...7...8...9
- \fjoin(&a,,,1) 0123456789
-
- \fsplit(), \fword(), \fstripb(), and \fjoin() accept a "grouping mask"
- argument, n1, which is a number from 0 to 63, in which:
-
- 1 = "" doublequotes
- 2 = {} braces
- 4 = '' singlequotes
- 8 = () parentheses
- 16 = [] square brackets
- 32 = <> angle brackets
-
- These can be OR'd (added) together to make any number 0-63 (-1 is
- treated the same as 63, 0 means no grouping). If a bit is on, the
- corresponding kind of grouping is selected. (If more than 1 bit is set
- for \fjoin(), only the lowest-order one is used.)
-
- If you include the same character in the grouping mask and the include
- list, the grouping mask takes precedence. Example:
-
- def \%a a "b c d" e
- \fsplit(\%a,&a[],,,-1) = 3 <-- doublequote used for grouping
- \fsplit(\%a,&a[],,",-1) = 3 <-- doublequote still used for grouping
-
- Nesting of matched left and right grouping characters (parentheses,
- braces, and brackets, but not quotes) is recognized. Example:
-
- def \%a a (b c <d e [f g {h i} j k] l m> n o) p
- \fsplit(\%a,&a,,,0) = 16 (no grouping)
- \fsplit(\%a,&a,,,2) = 15 (braces only)
- \fsplit(\%a,&a,,,16) = 11 (square brackets only)
- \fsplit(\%a,&a,,,32) = 7 (angle brackets only)
- \fsplit(\%a,&a,,,63) = 3 (all)
- \fsplit(\%a,&a,,,-1) = 3 (all)
-
- \fsplit() and \fjoin() are "reciprocal" functions. You can split a
- string up into an array and join it back into a new string that is
- equivalent, as long as \fsplit() and \fjoin() are given equivalent
- grouping masks, except that the type of braces might change. Example:
-
- def \%a a {b c [d e] f g} "h i" j <k l> m
- echo STRING=[\%a]
- echo WORDS=\fsplit(\%a,&a,,,-1)
- show array a
- asg \%b \fjoin(&a,{ },2)
- echo JOIN =[\%b]
- echo WORDS=\fsplit(\%b,&b,,,-1)
- show array b
-
- The arrays a and b are identical. The strings a and b are as follows:
-
- \%a: a {b c [d e] f g} "h i" j <k l> m
- \%b: a {b c [d e] f g} {h i} j {k l} m
-
- It is possible to quote separator grouping characters with backslash to
- override their grouping function. And of course to include backslash
- itself in the string, it must be quoted too. Furthermore, each
- backslash must be doubled, so the command parser will still pass one
- backslash to \fsplit() for each two that it sees. Here are some
- examples using \fsplit() with a grouping mask of 8 (treat parentheses
- as grouping characters).
-
- String Result
- a b c d e f 6
- a b\\ c d e f 5
- a b (c d e) f 4
- a b \\(c d e\\) f 6
- a b \\\\(c d e\\\\) f 7
-
- \fsplit() has also been changed to create its array (if one is given)
- each time it is called, so now it can be conveniently called in a loop
- without having to redeclare the array each time.
-
- Incidentally... Sometimes you might want to invoke \fsplit() in a
- situation where you don't care about its return value, e.g. when you
- just want to fill the array. Now you can "call" \fsplit() or any other
- function with the new [452]VOID command:
-
- void \fsplit(\%a,&a)
-
- \fsplit() and \fjoin() also accept a new, optional 6th argument, an
- options flag, a number that can specify a number of options. So far
- there is just one option, whose value is 1:
-
- separator-flag
- Normally separators are collapsed. So, for example,
-
- \fword(Three little words,2)
-
- returns "little" (the second word). Space is a separator, but
- there are multiple spaces between each word. If the value 1 is
- included in the option flag, however, each separator counts. If
- two separators are adjacent, an empty word is produced between
- them. This is useful for parsing (e.g.) comma-separated lists
- exported from databases or spreadsheets.
-
-8.7.3. The \fcmdstack() Function
-
- The new \fcmdstack() function gives access to the command stack:
-
- \fcmdstack(n1,n2)
- Arguments: n1 is the command stack level. If omitted, the
- current level, \v(cmdlevel), is used. n2 is a function code
- specifying the desired type of information:
-
- 0 (default) = name of object at level n1.
- 1 (nonzero) = object type (0 = prompt; 1 = command file; 2 = macro).
-
- The default for n2 is 0.
-
- The name associated with prompt is "(prompt)". Here's a loop that can
- be included in a macro or command file to show the stack (similar to
- what the SHOW STACK command does):
-
- for \%i \v(cmdlevel) 0 -1 {
- echo \%i. [\fcmdstack(\%i,1)] \fcmdstack(\%i,0)
- }
-
- In this connection, note that \v(cmdfile) always indicates the most
- recently invoked active command file (if any), even if that file is
- executing a macro. Similarly, \v(macro) indicates the most recently
- invoked macro (if any), even if the current command source is not a
- macro. The name of the "caller" of the currently executing object
- (command file or macro) is:
-
- \fcmdstack(\v(cmdlevel)-1)
-
- and its type is:
-
- \fcmdstack(\v(cmdlevel)-1,1)
-
- To find the name of the macro that invoked the currently executing
- object, even if one or more intermediate command files (or prompting
- levels) are involved, use a loop like this:
-
- for \%i \v(cmdlevel)-1 0 -1 {
- if = \fcmdstack(\%i,1) 2 echo CALLER = \fcmdstack(\%i,0)
- }
-
- Of course if you make a macro to do this, the macro must account for
- its own additional level:
-
- define CALLER {
- for \%i \v(cmdlevel)-2 0 -1 {
- if = \fcmdstack(\%i,1) 2 return \fcmdstack(\%i,0)
- }
- return "(none)"
- }
-
- The built-in variable \v(cmdsource) gives the current command source as
- a word ("prompt", "file", or "macro").
-
-8.7.4. The VOID Command
-
- VOID is like ECHO in that all functions and variables in its argument
- text are evaluated. but it doesn't print anything (except possibly an
- error message if a function was invocation contained or resulted in any
- errors). VOID sets FAILURE if it encounters any errors, SUCCESS
- otherwise.
-
- [ [453]Top ] [ [454]Contents ] [ [455]C-Kermit Home ] [ [456]Kermit
- Home ]
-
-8.8. The RETURN and END Commands
-
- The execution of a macro is terminated in any of the following ways:
-
- * With an END [ number [ message ] ] command. If a number is given,
- the macro succeeds if the number is 0, and fails if it is not zero;
- if a number is not given, the macro succeeds.
- * With a STOP command, which works just like END except it peels back
- the command stack all the way to top level.
- * With a RETURN [ text ] command, in which case the macro always
- succeeds.
- * By running out of commands to execute, in which case the macro
- succeeds or fails according the most recently executed command that
- sets success or failure.
-
- The same considerations apply to command files invoked by the TAKE
- command.
-
- If a macro does not execute any commands that set success or failure,
- then invoking the macro does not change the current SUCCESS/FAILURE
- status. It follows, then, that the mere invocation of a macro does not
- change the SUCCESS/FAILURE status either. This makes it possible to
- write macros to react to the status of other commands (or macros), for
- example:
-
- define CHKLINE {
- if success end 0
- stop 1 SET LINE failed - please try another device.
- }
- set modem type usrobotics
- set line /dev/cua0
- chkline
- set speed 57600
- dial 7654321
-
- By the way, none of this is news. But it was not explicitly documented
- before, and C-Kermit 7.0 and earlier did not always handle the RETURN
- statement as it should have.
-
- [ [457]Top ] [ [458]Contents ] [ [459]C-Kermit Home ] [ [460]Kermit
- Home ]
-
-8.9. UNDEFINing Groups of Variables
-
- The UNDEFINE command, which previously accepted one variable name, now
- accepts a list of them, and also accepts wildcard notation to allow
- deletion of variables that match a given pattern.
-
- UNDEFINE [ switches ] name [ name [ name [ ... ] ] ]
- Undefines the variables whose names are given. Up to 64 names
- may be given in one UNDEFINE command.
-
- If you omit the switches and include only one name, the UNDEFINE
- command works as before.
-
- Switches include:
-
- /MATCHING
- Specifies that the names given are to treated as patterns rather
- than literal variable names. Note: pattern matching can't be
- used with array references; use the ARRAY command to manipulate
- arrays and subarrays.
-
- /LIST
- List the name of each variable to be undefined, and whether it
- was undefined successfully ("ok" or "error"), plus a summary
- count at the end.
-
- /SIMULATE
- List the names of the variables that would be deleted without
- actually deleting them. Implies /LIST.
-
- The UNDEFINE command fails if there were any errors and succeeds
- otherwise.
-
- The new _UNDEFINE command is like UNDEFINE, except the names are
- assumed to be variable names themselves, which contain the names (or
- parts of them) of the variables to be undefined. For example, if you
- have the following definitions:
-
- define \%a foo
- define foo This is some text
-
- then:
-
- undef \%a
-
- undefines the variable \%a, but:
-
- _undef \%a
-
- undefines the macro foo.
-
- Normal Kermit patterns are used for matching; metacharacters include
- asterisk, question mark, braces, and square brackets. Thus, when using
- the /MATCHING switch, if the names of the macros you want to undefine
- contain any of these characters, you must quote them with backslash to
- force them to be taken literally. Also note that \%* is not the name of
- a variable; it is a special notation used within a macro for "all my
- arguments". The command "undef /match \%*" deletes all \%x variables,
- where x is 0..9 and a..z. Use "undef /match \%[0-9]" to delete macro
- argument variables or "undef /match \%[i-n]" to delete a range of \%x
- variables.
-
- [ [461]Top ] [ [462]Contents ] [ [463]C-Kermit Home ] [ [464]Kermit
- Home ]
-
-8.10. The INPUT and MINPUT Commands
-
- As of C-Kermit 8.0.211, the INPUT and MINPUT commands accept a switch:
-
- [M]INPUT /NOMATCH timeout
- The /NOMATCH switch allows INPUT or MINPUT to read incoming
- material for the specified amount of time, without attempting to
- match it with any text or patterns. When this switch is
- included, the [M]INPUT command succeeds when the timeout
- interval expires, with \v(instatus) set to 1, meaning "timed
- out", or fails upon interruption or i/o error.
-
- Also in version 8.0.211, there is a new way to apply a scale factor to
- [M]INPUT timeouts:
-
- SET INPUT SCALE-FACTOR floating-point-number
- This scales all [M]INPUT timeouts by the given factor, allowing
- time-sensitive scripts to be adjusted to changing conditions
- such as congested networks or different-speed modems without
- having to change each INPUT-class command. This affects only
- those timeouts that are given in seconds, not as wall-clock
- times. Although the scale factor can have a fractional part, the
- INPUT timeout is still an integer. The new built-in variable
- \v(inscale) tells the current INPUT SCALE-FACTOR.
-
- The MINPUT command can be used to search the incoming data stream for
- several targets simultaneously. For example:
-
- MINPUT 8 one two three
-
- waits up to 8 seconds for one of the words "one", "two", or "three" to
- arrive. Words can be grouped to indicate targets that contain spaces:
-
- MINPUT 8 nineteen twenty "twenty one"
-
- And of course you can also use variables in place of (or as part of)
- the target names:
-
- MINPUT 8 \%a \&x[3] \m(foo)
-
- Until now you had to know the number of targets in advance when writing
- the MINPUT statement. Each of the examples above has exactly three
- targets.
-
- But suppose your script needs to look for a variable number of targets.
- For this you can use arrays and \fjoin(), described in [465]Section
- 8.7. Any number of \fjoin() invocations can be included in the MINPUT
- target list, and each one is expanded into the appropriate number of
- separate targets each time the MINPUT command is executed. Example:
-
- declare \&a[10] = one two three
- minput 10 foo \fjoin(&a) bar
-
- This declares an array of ten elements, and assigns values to the first
- three of them. The MINPUT command looks for these three (as well as the
- words "foo" and "bar"). Later, if you assign additional elements to the
- array, the same MINPUT command also looks for the new elements.
-
- If an array element contains spaces, each word becomes a separate
- target. To create one target per array element, use \fjoin()'s grouping
- feature:
-
- dcl \&a[] = {aaa bbb} {ccc ddd} {xxx yyy zzz}
-
- minput 10 \fjoin(&a) <-- 7 targets
- minput 10 \fjoin(&a,,2) <-- 3 targets
-
- [ [466]Top ] [ [467]Contents ] [ [468]C-Kermit Home ] [ [469]Kermit
- Home ]
-
-8.11. Learned Scripts
-
- C-Kermit now includes a simple script recorder that monitors your
- commands, plus your actions during CONNECT mode, and automatically
- generates a script program that mimics what it observed. You should
- think of this feature as a script-writing ASSISTANT since, as you will
- see [470]later in this section, the result generally needs some editing
- to make it both secure and flexible. The script recorder is controlled
- by the new LEARN command:
-
- LEARN [ /ON /OFF /CLOSE ] [ filename ]
- If you give a filename, the file is opened for subsequent
- recording. The /ON switch enables recording to the current file
- (if any); /OFF disables recording. /CLOSE closes the current
- script recording file (if any). If you give a filename without
- any switches, /ON is assumed.
-
- The /OFF and /ON switches let you turn recording off and on during a
- session without closing the file.
-
- When recording:
-
- * All commands that you type (or recall) at the prompt are recorded
- in the file except:
- + LEARN commands are not recorded.
- + The CONNECT command is not recorded.
- + The TELNET command is converted to SET HOST /NETWORK:TCP.
- * Commands obtained from macros or command files are not recorded.
- * During CONNECT:
- + Every line you type is converted to an OUTPUT command.
- + The last prompt before any line you type becomes an INPUT
- command.
- + Timeouts are calculated automatically for each INPUT command.
- + A PAUSE command is inserted before each OUTPUT command just to
- be safe.
-
- Thus the script recorder is inherently line-oriented. It can't be used
- to script character-oriented interactions like typing Space to a
- "More?" prompt or editing a text file with VI or EMACS.
-
- But it has advantages too; for example it takes control characters into
- account that might not be visible to you otherwise, and it
- automatically converts control characters in both the input and output
- streams to the appropriate notation. It can tell, for example that the
- "$ " prompt on the left margin in UNIX is really {\{13}\{10}$ },
- whereas in VMS it might be {\{13}\{10}\{13}$ }. These sequences are
- detected and recorded automatically.
-
- A learned script should execute correctly when you give a TAKE command
- for it. However, it is usually appropriate to edit the script a bit.
- The most important change would be to remove any passwords from it. For
- example, if the script contains:
-
- INPUT 9 {\{13}\{10}Password: }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT bigsecret\{13}
-
- you should replace this by something like:
-
- INPUT 9 {\{13}\{10}Password: }
- IF FAIL STOP 1 INPUT timeout
- ASKQ pswd Please type your password:
- PAUSE 1
- OUTPUT \m(pswd)\{13}
-
- The LEARN command can't do this for you since it knows nothing about
- "content"; it only knows about lines and can't be expected to parse or
- understand them -- after all, the Password prompt might be in some
- other language. So remember: if you use the LEARN command to record a
- login script, be sure edit the resulting file to remove any passwords.
- Also be sure to delete any backup copies your editor or OS might have
- made of the file.
-
- Other manual adjustments might also be appropriate:
-
- * If the target of an INPUT command can vary, you can replace the
- INPUT command with MINPUT and the appropriate target list, and/or
- the target with a \fpattern(). For example, suppose you are dialing
- a number that can be answered by any one of 100 terminal servers,
- whose prompts are ts-00>, ts-01>, ts-02>, ... ts-99>. The script
- records a particular one of these, but you want it to work for all
- of them, so change (e.g.):
- INPUT 10 ts-23> ; or whatever
-
- to:
- INPUT 10 \fpattern(ts-[0-9][0-9]>)
-
- * The INPUT timeout values are conservative, but they are based only
- on a single observation; you might need to tune them.
- * The PAUSE commands might not be necessary, or the PAUSE interval
- might need adjustment.
- * In case you made typographical errors during recording, they are
- incorporated in your script; you can edit them out if you want to.
-
- Here is a sample script generated by Kermit ("learn vms.ksc") in which
- a Telnet connection is made to a VMS computer, the user logs in, starts
- Kermit on VMS, sends it a file, and then logs out:
-
- ; Scriptfile: vms.ksc
- ; Directory: /usr/olga
- ; Recorded: 20001124 15:21:23
-
- SET HOST /NETWORK:TCP vms.xyzcorp.com
- IF FAIL STOP 1 Connection failed
-
- INPUT 7 {\{13}\{10}\{13}Username: }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT olga\{13}
- INPUT 3 {\{13}\{10}\{13}Password: }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT secret\{13}
- INPUT 18 {\{13}\{10}\{13}$ }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT set default [.incoming]\{13}
- INPUT 12 {\{13}\{10}\{13}$ }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT kermit\{13}
- INPUT 15 {\{13}\{10}\{13}ALTO:[OLGA.INCOMING] C-Kermit>}
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT receive\{13}
- send myfile.txt
-
- INPUT 18 {\{13}\{10}\{13}ALTO:[OLGA.INCOMING] C-Kermit>}
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT exit\{13}
- INPUT 6 {\{13}\{10}\{13}$ }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT logout\{13}
- close
- exit
-
- The commands generated by Kermit during CONNECT (INPUT, IF FAIL, PAUSE,
- and OUTPUT) have uppercase keywords; the commands typed by the user are
- in whatever form the user typed them (in this case, lowercase).
-
- [ [471]Top ] [ [472]Contents ] [ [473]C-Kermit Home ] [ [474]Kermit
- Home ]
-
-8.12. Pattern Matching
-
- A pattern is a character string that is used to match other strings.
- Patterns can contain metacharacters that represent special actions like
- "match any single character", "match zero or more characters", "match
- any single character from a list", and so on. The best known
- application of patterns is in file specifications that contain
- wildcards, as in "send *.txt", meaning "send all files whose names end
- with .txt".
-
- Patterns are also used in increasingly many other ways, to the extent
- it is useful to point out certain important distinctions in the ways in
- which they are used:
-
- Anchored Patterns
- If an anchored pattern does not begin with "*", it must match
- the beginning of the string, and if it does not end with "*", it
- must match the end of the string. For example, the anchored
- pattern "abc" matches only the string "abc", not "abcde" or
- "xyzabc" or "abcabc". The anchored pattern "abc*" matches any
- string that starts with "abc"; the anchored pattern "*abc"
- matches any string that ends with "abc"; the anchored pattern
- "*abc*" matches any string that contains "abc" (including any
- that start and/or end with it).
-
- Floating Patterns
- A floating pattern matches any string that contains a substring
- that matches the pattern. In other words, a floating pattern has
- an implied "*" at the beginning and end. You can anchor a
- floating pattern to the beginning by starting it with "^", and
- you can anchor it to the end by ending it with "$" (see examples
- below).
-
- Wildcards
- A wildcard is an anchored pattern that has the additional
- property that "*" does not match directory separators.
-
- This terminology lets us describe Kermit's commands with a bit more
- precision. When a pattern is used for matching filenames, it is a
- wildcard, except in the TEXT-PATTERNS and BINARY-PATTERNS lists and
- /EXCEPT: clauses, in which case directory separators are not
- significant (for example, a BINARY-PATTERN of "*.exe" matches any file
- whose name ends in .exe, no matter how deeply it might be buried in
- subdirectories). When Kermit parses a file specification directly,
- however, it uses the strict wildcard definition. For example, "send
- a*b" sends all files whose names start with "a" and end with "b" in the
- current directory, and not any files whose names end with "b" that
- happen to be in subdirectories whose names start with "a". And as
- noted, wildcards are anchored, so "delete foo" deletes the file named
- "foo", and not all files whose names happen to contain "foo".
-
- Most other patterns are anchored. For example:
-
- if match abc bc ...
-
- does not succeed (and you would be surprised if it did!). In fact, the
- only floating patterns are the ones used by commands or functions that
- search for patterns in files, arrays, or strings. These include:
-
- * The GREP and TYPE /MATCH commands.
- * The \fsearch(), \frsearch(), and \farraylook() functions.
-
- Thus these are the only contexts in which explicit anchors ("^" and
- "$") may be used:
-
- grep abc *.txt
- Prints all lines containing "abc" in all files whose names end
- with ".txt".
-
- grep ^abc *.txt
- Prints all lines that start with "abc" in all ".txt" files.
-
- grep abc$ *.txt
- Prints all lines that end with "abc" in all ".txt" files.
-
- grep ^a*z$ *.txt
- Prints all lines that start with "a" and end with "z" in all
- ".txt" files.
-
- Similarly for TYPE /PAGE, /fsearch(), /frsearch(), and \farraylook().
-
- Here is a brief summary of anchored and floating pattern equivalences:
-
- Anchored Floating
- abc ^abc$
- *abc abc$
- abc* ^abc
- *abc* abc
-
- [ [475]Top ] [ [476]Contents ] [ [477]C-Kermit Home ] [ [478]Kermit
- Home ]
-
-8.13. Dates and Times
-
- C-Kermit's comprehension of date-time formats is considerably expanded
- in version 8.0. Any command that reads dates, including the DATE
- command itself, or any switch, such as the /BEFORE: and /AFTER:
- switches, or any function such as \fcvtdate(), now can understand dates
- and times expressed in any ISO 8601 format, in Unix "asctime" format,
- in FTP MDTM format, and in practically any format used in RFC 822 or
- RFC 2822 electronic mail, with or without timezones, and in a great
- many other formats as well. HELP DATE briefly summarizes the acceptable
- date-time formats.
-
- Furthermore, C-Kermit 8.0 includes a new and easy-to-use form of
- date-time arithmetic, in which any date or time can be combined with a
- "delta time", to add or subtract the desired time interval (years,
- months, weeks, days, hours, minutes, seconds) to/from the given date.
- And new functions are available to compare dates and to compute their
- differences.
-
- As you can imagine, all this requires quite a bit of "syntax". The
- basic format is:
-
- [ date ] [ time ] [ delta ]
-
- Each field is optional, but in most cases (depending on the context)
- there must be at least one field. If a date is given, it must come
- first. If no date is given, the current date is assumed. If no time is
- given, an appropriate time is supplied depending on whether a date was
- supplied. If no delta is given, no arithmetic is done. If a delta is
- given without a date or time, the current date and time are used as the
- base.
-
- Date-time-delta fields are likely to contain spaces (although they need
- not; space-free forms are always available). Therefore, in most
- contexts -- and notably as switch arguments -- date-time information
- must be enclosed in braces or doublequotes, for example:
-
- send /after:"8-Aug-2001 12:00 UTC" *.txt
-
- Kermit's standard internal format for dates and times is:
-
- yyyymmdd hh:mm:ss
-
- for example:
-
- 20010208 10:28:01
-
- Date-times can always be given in this format. yyyy is the 4-digit
- year, mm is the two-digit month (1-12; supply leading zero for
- Jan-Sep), dd is the 2-digit day (leading zero for 1-9), hh is the hour
- (0-23), mm the minute (0-59), ss the second (0-59), each with leading
- zero if less than the field width. The date and time can be separated
- by a space, an underscore, a colon, or the letter T. The time is in
- 24-hour format. Thus the various quantities are at the following fixed
- positions:
-
-Position Contents
- 1-4 Year (4 digits, 0000-9999)
- 5-6 Month (2 digits, 1-12)
- 7-8 Day (2 digits, 1-31)
- 9 Date-Time Separator (space, :, _, or the letter T)
- 10-11 Hour (2 digits, 0-23)
- 12 Hour-Minute Separator (colon)
- 13-14 Minute (2 digits, 0-59)
- 15 Minute-Second Separator (colon)
- 16-17 Second (2 digits, 0-59)
-
- Example:
-
- 19800526 13:07:12 26 May 1980, 13:07:12 (1:07:12PM)
-
- This is the format produced by the DATE command and by any function
- that returns a date-time. It is suitable for lexical comparison and
- sorting, and for use as a date-time in any Kermit command. When this
- format is given as input to a command or function, various date-time
- separators (as noted) are accepted:
-
- 19800526 13:07:12 26 May 1980, 13:07:12 (1:07:12PM)
- 20010208_10:28:35 2 February 2001, 10:28:35 AM
- 18580101:12:00:00 1 January 1858, noon
- 20110208T00:00:00 2 February 2011, midnight
-
- Certain other special date-time formats that are encountered on
- computer networks are recognized:
-
- Asctime Format
- This is a fixed format used by Unix, named after Unix's
- asctime() ("ASCII time") function. It is always exactly 24
- characters long. Example: Fri Aug 10 16:38:01 2001
-
- Asctime with Timezone
- This is like Asctime format, but includes a 3-character timezone
- between the time and year. It is exactly 28 characters long.
- Example: Fri Aug 10 16:38:01 GMT 2001
-
- E-Mail Format
- E-mail date-time formats are defined in [479]RFC 2822 with a
- fair amount of flexibility and options. The following examples
- are typical of e-mails and HTTP (web-page) headers:
-
- Sat, 14 Jul 2001 11:49:29 (No timezone)
- Fri, 24 Mar 2000 14:19:59 EST (Symbolic timezone)
- Tue, 26 Jun 2001 10:19:45 -0400 (EDT) (GMT Offset + comment)
-
- FTP MDTM Format
- This is the date-time format supplied by FTP servers that
- support the (not yet standard but widely used nevertheless) MDTM
- command, by which the FTP client asks for a file's modification
- time:
-
- yyyymmddhhmmss[.ffff]
-
- where yyyy is the 4-digit year, mm is the 2-digit month, and so
- on, exactly 14 digits long. An optional fractional part
- (fraction of second) may also be included, separated by a
- decimal point (period). Kermit rounds to the nearest second.
- Example:
-
- 20020208102835.515 (8 February 2002 10:28:36 AM)
-
-8.13.1. The Date
-
- The date, if given, must precede the time and/or delta, and can be in
- many, many formats. For starters, you can use several symbolic date
- names in place of actual dates:
-
- NOW
- This is replaced by the current date and time. The time can not
- be overriden (if you want to supply a specific time, use TODAY
- rather than NOW).
-
- TODAY
- This is replaced by the current date and a default time of
- 00:00:00 is supplied, but can be overridden by a specific time;
- for example, if today is 8 February 2002, then "TODAY" is
- "20020802 00:00:00" but "TODAY 10:28" is "20020802 10:28:00".
-
- TOMORROW
- Like TODAY, but one day later (if today is 8 February 2002, then
- "TOMORROW" is "20020803 00:00:00" but "TOMORROW 16:30" is
- "20020803 16:30:00").
-
- YESTERDAY
- Like TODAY, but one day earlier.
-
- MONDAY, TUESDAY, WEDNESDAY, ..., SUNDAY
- The date on the given day of the week, today or later. A default
- time of 00:00:00 is supplied but can be overridden. Example:
- "SATURDAY 12:00" means next Saturday (or today, if today is
- Saturday) at noon.
-
- You can give an explicit date in almost any conceivable format, but
- there are some rules:
-
- * If a date is given, it must have three fields: day, month, and
- year; the order can vary (except that the month can not be last).
- * If names are used for days, months, etc, they must be English.
- * The year must lie between 0000 and 9999, inclusive.
- * All calendar calculations use Gregorian dating, so calculated dates
- for years prior to 1582 (or later, depending on the country) will
- not agree with historical dates. Other forms of dating (e.g.
- Hebrew, Chinese) are not supported.
-
- Various date-field separators are accepted: hyphen, slash, space,
- underscore, period. The same field separator (if any) must be used in
- both places; for example 18-Sep-2001 but not 18-Sep/2001. Months can be
- numeric (1-12) or English names or abbreviations. Month name
- abbreviations are normally three letters, e.g. Apr, May, Jun, Jul.
- Capitalization doesn't matter.
-
- Here are a few examples:
-
- 18 Sep 2001 (English month, abbreviated)
- 18 September 2001 (English month, spelled out)
- 2001 Sept 18 (Year, month, day)
- 18-Sep-2001 (With hyphens)
- 18/09/2001 (All numeric with slashes)
- 18.09.2001 (Ditto, with periods)
- 18_09_2001 (Ditto, with underscores)
- 09/18/2001 (See below)
- 2001/09/18 (See below)
- September 18, 2001 (Correspondence style)
- Sep-18-2001 (Month-day-year)
- 20010918 (Numeric, no separators)
-
- You can also include the day of the week with a specific date, in which
- case it is accepted (if it is a valid day name), but not verified to
- agree with the given date:
-
- Tue, 18 Sep 2001 (Abbreviated, with comma)
- Tue,18 Sep 2001 (Comma but no space)
- Tue 18 Sep 2001 (Abbreviated, no comma)
- Tuesday 18 Sep 2001 (Spelled out)
- Tuesday, 18 Sep 2001 (etc)
- Friday, 18 Sep 2001 (Accepted even if not Friday)
-
- In all-numeric dates with the year last, such as 18/09/2001, Kermit
- identifies the year because it's 4 digits, then decides which of the
- other two numbers is the month or day based on its value. If both are
- 12 or less and are unequal, the date is ambiguous and is rejected. In
- all-numeric dates with the year first, the second field is always the
- month and the third is the day. The month never comes last. A date with
- no separators is accepted only if it is all numeric and has exactly
- eight digits, and is assumed to be in yyyymmdd format.
-
- 20010918 (18-Sep-2001 00:00:00)
-
- or 14 digits (as in FTP MDTM format):
-
- 20010918123456 (18-Sep-2001 12:34:56)
-
- You can always avoid ambiguity by putting the year first, or by using
- an English, rather than numeric, month. A date such as 09/08/2001 would
- be ambiguous but 2001/09/08 is not, nor is 09-Aug-2001.
-
- Until the late 1990s, it was common to encounter 2-digit years, and
- these are found to this day in old e-mails and other documents. Kermit
- accepts these dates if they have English months, and interprets them
- according to the windowing rules of [480]RFC 2822: "If a two digit year
- is encountered whose value is between 00 and 49, the year is
- interpreted by adding 2000, ending up with a value between 2000 and
- 2049. If a two digit year is encountered with a value between 50 and
- 99, or any three digit year is encountered, the year is interpreted by
- adding 1900."
-
- If you need to specify a year prior to 1000, use leading zeros to
- ensure it is not misinterpreted as a "non-Y2K-compliant" modern year:
-
- 7-Oct-77 (19771007 00:00:00)
- 7-Oct-0077 (00771007 00:00:00)
-
-8.13.2. The Time
-
- The basic time format is hh:mm:dd; that is hours, minutes, seconds,
- separated by colons, perhaps with an optional fractional second
- separated by a decimal point (period). The hours are in 24-hour format;
- 12 is noon, 13 is 1pm, and so on. Fields omitted from the right default
- to zero. Fields can be omitted from the left or middle by including the
- field's terminating colon. Examples:
-
- 11:59:59 (11:59:59 AM)
- 11:59 (11:59:00 AM)
- 11 (11:00:00 AM)
- 11:59:59.33 (11:59:59 AM)
- 11:59:59.66 (Noon)
- 03:21:00 (3:21:00 AM)
- 3:21:00 (3:21:00 AM)
- 15:21:00 (3:21:00 PM)
- :21:00 (00:21:00 AM)
- ::01 (00:00:01 AM)
- 11::59 (11:00:59 AM)
-
- Leading zeros can be omitted, but it is customary and more readable to
- keep them in the minute and second fields:
-
- 03:02:01 (03:02:01 AM)
- 3:02:01 (03:02:01 AM)
- 3:2:1 (03:02:01 AM)
-
- AM/PM notation is accepted if you wish to use it:
-
- 11:59:59 (11:59:59 AM)
- 11:59:59AM (11:59:59 AM)
- 11:59:59A.M. (11:59:59 AM)
- 11:59:59am (11:59:59 AM)
- 11:59:59a.m. (11:59:59 AM)
- 11:59:59PM (11:59:59 PM = 23:59:59)
- 11:59:59P.M. (11:59:59 PM = 23:59:59)
- 11:59:59pm (11:59:59 PM = 23:59:59)
- 11:59:59p.m. (11:59:59 PM = 23:59:59)
-
- You can omit the colons if you wish, in which case Kermit uses the
- following rules to interpret the time:
-
- 1. 6 digits is hh:mm:ss, e.g. 123456 is 12:34:56.
- 2. 5 digits is h:mm:ss, e.g. 12345 is 1:23:45.
- 3. 4 digits is hh:mm, e.g. 1234 is 12:34.
- 4. 3 digits is h:mm, e.g. 123 is 1:23.
- 5. 2 digits is hh, e.g. 12 is 12:00.
- 6. 1 digit is h (the hour), e.g. 1 is 1:00.
-
- Examples:
-
- 1 (01:00:00 AM)
- 10 (10:00:00 AM)
- 230 (02:30:00 AM)
- 230pm (02:30:00 PM = 14:30:00)
- 1115 (11:15:00 AM)
- 2315 (11:15:00 PM = 23:15:00 PM)
- 23150 (02:31:50 AM)
- 231500 (23:15:00 PM)
-
-8.13.3. Time Zones
-
- If a time is given, it can (but need not) be followed by a time zone
- designator. If no time zone is included, the time is treated as local
- time and no timezone conversions are performed.
-
- The preferred time zone designator is the UTC Offset, as specified in
- [481]RFC 2822: a plus sign or minus sign immediately followed by
- exactly four decimal digits, signifying the difference in hh (hours)
- and mm (minutes) from Universal Coordinated Time (UTC, also known as
- Greenwich Mean Time, or GMT), with negative numbers to the West and
- positive numbers to the East. For example:
-
- Fri, 13 Jul 2001 12:54:29 -0700
-
- indicates a local time of 12:54:29 that is 07 hours and 00 minutes
- behind (less than, East of) Universal Time. The space is optional, so
- the example could also be written as:
-
- Fri, 13 Jul 2001 12:54:29-0700
-
- The following symbolic time zones are also accepted, as specified by
- [482]RFC 2822 and/or in ISO 8601:
-
- GMT = +0000 Greenwich Mean Time
- Z = +0000 Zulu (Zero Meridian) Time
- UTC = +0000 Universal Coordinated Time
- UT = +0000 Universal Time
- EDT = -0400 Eastern (USA) Daylight Time
- EST = -0500 Eastern (USA) Standard Time
- CDT = -0500 Central (USA) Daylight Time
- CST = -0600 Central (USA) Standard Time
- MDT = -0600 Mountain (USA) Daylight Time
- MST = -0700 Mountain (USA) Standard Time
- PDT = -0700 Pacific (USA) Daylight Time
- PST = -0800 Pacific (USA) Standard Time
-
- Note that GMT, Z, UTC, and UT all express the same concept: standard
- (not daylight) time at the Zero Meridian. UTC, by the way, is an
- international standard symbol and does not correspond to the order of
- the English words, Universal Coordinated Time, but it happens to have
- the same initial letters as these words. Of course hundreds of other
- symbolic timezones and variations exist, but they are not standardized,
- and are therefore not supported by Kermit.
-
- When a time zone is included with a time, the time is converted to
- local time. In case the conversion crosses a midnight boundary, the
- date is adjusted accordingly. Examples converting to EST (Eastern USA
- Standard Time = -0500):
-
- 11:30:00 = 11:30:00
- 11:30:00 EST = 11:30:00
- 11:30:00 GMT = 06:30:00
- 11:30:00 PST = 14:30:00
- 11:30:00Z = 06:30:00
- 11:30PM GMT = 18:30:00
- 11:30 -0500 = 11:30:00
- 11:30 -0800 = 08:30:00
- 11:30 +0200 = 04:30:00
-
- Unlike most of Kermit's other date-time conversions, timezone knowledge
- (specifically, the offset of local time from UTC) is embodied in the
- underlying operating system, not in Kermit itself, and any conversion
- errors in this department are the fault of the OS. For example, most
- UNIX platforms do not perform conversions for years prior to 1970.
-
-8.13.4. Delta Time
-
- Date/time expressions can be composed of a date and/or time and a delta
- time, or a delta time by itself. When a delta time is given by itself,
- it is relative to the current local date and time. Delta times have the
- following general format:
-
- {+,-}[number units][hh[:mm[:ss]]]
-
- In other words, a delta time always starts with a plus or minus sign,
- which is followed by a "part1", a "part2", or both. The "part1", if
- given, specifies a number of days, weeks, months, or years; "part2"
- specifies a time in hh:mm:ss notation. In arithmetic terms, these
- represents some number of days or other big time units, and then a
- fraction of a day expressed as hours, minutes, and seconds; these are
- to be added to or subtracted from the given (or implied) date and time.
- The syntax is somewhat flexible, as shown by the following examples:
-
- +1 day (Plus one day)
- +1day (Ditto)
- +1d (Ditto)
- + 1 day (Ditto)
- + 1 day 3:00 (Plus one day and 3 hours)
- +1d3:00 (Ditto)
- +1d3 (Ditto)
- +3:00:00 (Plus 3 hours)
- +3:00 (Ditto)
- +3 (Ditto)
- +2 days (Plus 2 days)
- -12 days 7:14:22 (Minus 12 days, 7 hours, 14 minutes, and 22 seconds)
-
- The words "week", "month", and "year" can be used like "day" in the
- examples above. A week is exactly equivalent to 7 days. When months are
- specified, the numeric month number of the date is incremented or
- decremented by the given number, and the year and day adjusted
- accordingly if necessary (for example, 31-Jan-2001 +1month =
- 03-Mar-2001 because February does not have 31 days). When years are
- specified, they are added or subtracted to the base year. Examples
- (assuming the current date is 10-Aug-2001 and the current time is
- 19:21:11):
-
- 18-Sep-2001 +1day (20010918 00:00:00)
- today +1day (20010811 00:00:00)
- now+1d (20010811 19:21:11)
- + 1 day (20010811 19:21:11)
- + 1 day 3:14:42 (20010811 22:35:54)
- + 7 weeks (20010928 19:21:11)
- +1d3:14:42 (20010811 22:35:54)
- +1w3:14:42 (20010817 22:35:54)
- +1m3:14:42 (20010910 22:35:54)
- +1y3:14:42 (20020810 22:35:54)
- 2 feb 2001 + 10 years (20110208 00:00:00)
- 2001-02-08 +10y12 (20110208 12:00:00)
- 31-dec-1999 23:59:59+00:00:01 (20000101 00:00:00)
- 28-feb-1996 +1day (19960229 00:00:00) (leap year)
- 28-feb-1997 +1day (19970301 00:00:00) (nonleap year)
- 28-feb-1997 +1month (19970328 00:00:00)
- 28-feb-1997 +1month 11:59:59 (19970328 11:59:59)
- 28-feb-1997 +20years (20170228 00:00:00)
- 28-feb-1997 +8000years (99970228 00:00:00)
-
- For compatibility with VMS, the following special delta-time format is
- also accepted:
-
- +number-hh:mm:ss
- -number-hh:mm:ss
-
- (no spaces). The hyphen after the number indicates days. It corresponds
- exactly to the Kermit notation:
-
- +numberdhh:mm:ss
- -numberdhh:mm:ss
-
- The following forms all indicate exactly the same date and time:
-
- 18-Sep-2001 12:34:56 +1-3:23:01
- 18-Sep-2001 12:34:56 +1d3:23:01
- 18-Sep-2001 12:34:56 +1 day 3:23:01
-
- and mean "add a day plus 3 hours, 23 minutes, and 1 second" to the
- given date.
-
- Note that delta times are not at all the same as UTC offsets; the
- former specifies an adjustment to the given date/time and the latter
- specifies that the local time is a particular distance from Universal
- Time, for example:
-
- 11-Aug-2001 12:34:56 -0800 (20010811 16:34:56 -- UTC Offset)
- 11-Aug-2001 12:34:56 -08:00 (20010811 04:34:56 -- Delta time)
-
- If you give a time followed by a modifier that starts with a + or -
- sign, how does Kermit know whether it's a UTC offset or a delta time?
- It is treated as a UTC offset if the sign is followed by exactly four
- decimal digits; otherwise it is a delta time. Examples (for USA Eastern
- Daylight Time):
-
- 11-Aug-2001 12:34:56 -0800 (20010811 16:34:56 -- UTC Offset)
- 11-Aug-2001 12:34:56 -08:00 (20010811 04:34:56 -- Delta time)
- 11-Aug-2001 12:34:56 -800 (20010811 04:34:56 -- Delta time)
- 11-Aug-2001 12:34:56 -8 (20010811 04:34:56 -- Delta time)
-
- The first example says that at some unknown place which is 8 hours
- ahead of Universal Time, the time is 12:34:56, and this corresponds to
- 16:34:56 in Eastern Daylight time. The second example says to subtract
- 8 hours from the local time. The third and fourth are delta times
- because, even though a colon is not included, the time does not consist
- of exactly 4 digits.
-
- When a delta time is written after a timezone, however, there is no
- ambiguity and no syntax distinction is required:
-
- 11-Aug-2001 12:34:56 -0800 -0800 (20010811 08:34:56)
- 11-Aug-2001 12:34:56 -0800 -08:00 (Ditto)
- 11-Aug-2001 12:34:56 -08:00 -08:00 (Illegal)
-
-8.13.5. The DATE Command
-
- Obviously a great many combinations of date, time, time zone, and delta
- time are possible, as well as many formatting options. The purpose of
- all this flexibility is to comply with as many standards as possible --
- Internet RFCs, ISO standards, and proven corporate standards -- as well
- as with notations commonly used by real people, in order that dates and
- times from the widest variety of sources can be assigned to a variable
- and used in any date-time field in any Kermit command.
-
- You can test any date-and/or-time format with the DATE command, which
- converts it to standard yyyymmdd hh:mm:ss format if it is understood,
- or else gives an explicit error message (rather than just "BAD DATE" as
- in previous C-Kermit releases) to indicate what is wrong with it.
- Examples (on Tuesday, 31 July 2001 in New York City, Eastern Daylight
- Time, UTC -0400):
-
- DATE command argument Result
- 12:30 20010731 12:30:00
- 12:30:01 20010731 12:30:01
- 12:30:01.5 20010731 12:30:02
- 1230 20010731 12:30:00
- 230 20010731 02:30:00
- 230+1d 20010801 02:30:00
- 230+1d3:00 20010801 05:30:00
- 20010718 19:21:15 20010718 19:21:15
- 20010718_192115 20010718 19:21:15
- 20010718T192115 20010718 19:21:15
- 18 Jul 2001 +0400 20010717 23:59:59
- 18 Jul 2001 192115 20010718 19:21:15
- 18 Jul 2001 192115.8 20010718 19:21:16
- 18-Jul-2001T1921 20010718 19:21:00
- 18-Jul-2001 1921Z 20010718 15:21:00
- 18-Jul-2001 1921 GMT 20010718 15:21:00
- 18-Jul-2001 1921 UTC 20010718 15:21:00
- 18-Jul-2001 1921 Z 20010718 15:21:00
- 18-Jul-2001 1921Z 20010718 15:21:00
- 18-Jul-2001 1921 -04:00:00 20010718 19:21:00
- 21-Jul-2001_08:20:00am 20010721 08:20:00
- 21-Jul-2001_8:20:00P.M. 20010721 20:20:00
- Fri Jul 20 11:26:25 2001 20010720 11:26:25
- Fri Jul 20 11:26:25 GMT 2001 20010720 07:26:25
- Sun, 9 Apr 2000 06:46:46 +0100 20000409 01:46:46
- Sunday, 9 Apr 2000 06:46:46 +0100 20000409 01:46:46
- now 20010731 19:41:12
- today 20010731 00:00:00
- today 09:00 20010731 09:00:00
- tomorrow 20010801 00:00:00
- tomorrow 09:00 20010801 09:00:00
- tomorrow 09:00 GMT 20010801 05:00:00
- yesterday 20010730 00:00:00
- yesterday 09:00 20010730 09:00:00
- + 3 days 20010803 00:00:00
- +3 days 20010803 00:00:00
- +3days 20010803 00:00:00
- + 3days 20010803 00:00:00
- + 3 days 09:00 20010803 09:00:00
- + 2 weeks 20010814 00:00:00
- + 1 month 20010831 00:00:00
- - 7 months 20001231 00:00:00
- + 10 years 20110731 00:00:00
- friday 20010803 00:00:00
- saturday 20010804 00:00:00
- sunday 20010805 00:00:00
- monday 20010806 00:00:00
- tuesday 20010731 00:00:00
- wednesday 20010801 00:00:00
- thursday 20010802 00:00:00
- friday 07:00 20010803 07:00:00
- thursday 1:00pm 20010802 13:00:00
- thursday 1:00pm GMT 20010802 09:00:00
- Thu, 10 Nov 94 10:50:47 EST 19941110 10:50:47
- Fri, 20 Oct 1995 18:35:15 -0400 (EDT) 19951020 18:35:15
- 31/12/2001 20011231 00:00:00
- 12/31/2001 20011231 00:00:00
- 2001-July-20 20010720 00:00:00
- 2001-September-30 20010930 00:00:00
- 30-September-2001 20010930 00:00:00
- Sep 30, 2001 12:34:56 20010930 12:34:56
- September 30, 2001 20010930 00:00:00
- September 30, 2001 630 20010930 06:30:00
- September 30 2001 630 20010930 06:30:00
- Sep-30-2001 12:34:59 20010930 12:34:59
- 20010807113542.014 20010807 11:35.42
- 20010807113542.014Z 20010807 07:35:42
-
-8.13.6. New Date-Time Functions
-
- In the following descriptions, date-time function arguments are the
- same free-format date-time strings discussed above, with the same
- defaults for missing fields. They are automatically converted to
- standard format internally prior to processing.
-
- \fcvtdate(d1)
- Converts the date-time d1 to standard format and local time.
- This function is not new, but now it accepts a wider range of
- argument formats that can include timezones and/or delta times.
- If the first argument is omitted, the current date and time are
- assumed. The optional second argument is a format code for the
- result:
-
- n1 = 1: yyyy-mmm-dd hh:mm:ss (mmm = English 3-letter month
- abbreviation)
- n1 = 2: dd-mmm-yyyy hh:mm:ss (ditto)
- n1 = 3: yyyymmddhhmmss (all numeric)
-
- \futcdate(d1)
- Converts the date-time d1 to Universal Coordinated Time (UTC),
- also known as GMT or Zulu or Zero-Meridian time. The default d1
- is NOW. If d1 is a valid date-time, the UTC result is returned
- in standard format, yyyymmdd hh:ss:mm.
-
- \fcmpdates(d1,d2)
- Compares two free-format date-times, d1 and d2, and, if both
- arguments are valid, returns a number: -1 if d1 is earlier than
- (before) d2; 0 if d1 is the same as d2; 1 if d1 is later than
- (after) d2.
-
- \fdiffdates(d1,d2)
- Computes the difference between two free-format date-times, d1
- and d2. If both arguments are valid, returns a delta time which
- is negative if d1 is earlier than (before) d2 and positive
- otherwise. If d1 and d2 are equal, the result is "+0:00".
- Otherwise, the result consists of the number of days, hours,
- minutes, and seconds that separate the two date-times. If the
- number of days is zero, it is omitted. If the number of days is
- nonzero but the hours, minutes, and seconds are all zero, the
- time is omitted. if the seconds are zero, they are omitted.
-
- \fdelta2secs(dt)
- Converts a delta time to seconds. For example, "+1d00:00:01" to
- 86401. Valid delta times must start with a + or - sign. Days are
- accepted as time units, but not years, months, or weeks. If the
- result would overflow a computer long word (as would happen with
- 32-bit long words when the number of days is greater than
- 24854), the function fails.
-
- HINT: Although Kermit has a number of built-in date and time variables,
- it doesn't have a single one suitable for writing a timestamp. For this
- you would normally use something like "\v(ndate) \v(time)". But
- \fcvtdate() (with no arguments) is equivalent: it returns the current
- date and time in yyyymmdd hh:mm:ss format, suitable for time stamping.
-
-8.13.7. Date-Time Programming Examples
-
- Here's a macro that converts any date-time to UTC, which you might use
- if C-Kermit didn't already have a \futcdate() function:
-
- define utcdate {
- .local := \fcvtdate(\%*) ; 1.
- .tmp := \fcvtdate(\m(local)UTC) ; 2.
- .offset := \fdiffdate(\m(local),\m(tmp)) ; 3.
- .utc := \fcvtdate(\m(local)\m(offset)) ; 4.
- sho mac utc ; 5.
- }
-
- Brief explanation: Line 1 converts the macro argument, a free-format
- date-time, to standard-format local time. Line 2 appends the "UTC"
- timezone to the local time and converts the result to local time. In
- other words, we take the same time as the local time, but pretend it's
- UTC time, and convert it to local time. For example, if New York time
- is 4 hours ahead of UTC, then 6:00pm New York time is 2:00pm UTC. Line
- 3 gets the difference of the two results (e.g. "+04:00"). Line 4
- appends the difference (delta time) to the local time, and converts it
- again, which adds (or subtracts) the UTC offset to the given time. Line
- 5 displays the result.
-
- Here's a script that opens a web page, gets its headers into an array,
- scans the array for the "Last-Modified:" header, and interprets it:
- http open www.columbia.edu
- if fail stop 1 HTTP OPEN failed
- http /array:a head index.html /dev/null
- if fail stop 1 HTTP GET failed
- show array a
- for \%i 1 \fdim(&a) 1 {
- .\%x := \findex(:,\&a[\%i])
- if not \%x continue
- .tag := \fleft(\&a[\%i],\%x-1)
- .val := \fltrim(\fsubstr(\&a[\%i],\%x+1))
- if ( eq "\m(tag)" "Last-Modified" ) {
- echo HTTP Date: \m(val)
- .rdate := \fcvtdate(\m(val))
- echo {Standard Date (local): \m(rdate)}
- echo {Standard Date (UTC): \futcdate(\m(rdate))}
- break
- }
- }
- http close
-
- The result:
-
- HTTP Date: Mon, 13 Aug 2001 20:05:42 GMT
- Standard Date (local): 20010813 16:05:42
- Standard Date (UTC): 20010813 20:05:42
-
- As you can see, Kermit had no trouble decoding the date-time-string
- from the website, converting to local time, and converting back to UTC
- with no conflicts or loss of information. If it had been in any other
- known format, the result would have been the same.
-
- Now suppose we want to download the web page only if it is newer than
- our local copy. The \fdate(filename) function (which returns the
- modification date-time of the given file) and the new \fcmpdates()
- function make it easy. Insert the following just before the BREAK
- statement:
-
- if ( < 0 \fcmpdates(\m(rdate),\fdate(index.html)) ) {
- echo GETTING index.html...
- http get index.html index.html
- if success echo HTTP GET OK
- } else {
- echo index.html: no update needed
- }
- http close
- exit
-
- This says, "if 0 is less than the comparison of the remote file date
- and the local file date, get the remote file, otherwise skip it." And
- it automatically reconciles the time-zone difference (if any).
-
- It would be nice to be able to extend this script into a
- general-purpose website updater, but unfortunately HTTP protocol
- doesn't provide any mechanism for the client to ask the server for a
- list of files, recursive or otherwise.
-
- [ [483]Top ] [ [484]Contents ] [ [485]C-Kermit Home ] [ [486]Kermit
- Home ]
-
-8.14. Trapping Keyboard Interruption
-
- Normally when you type Ctrl-C and Kermit is in command mode (as opposed
- to CONNECT mode) with COMMAND INTERRUPTION ON (as it is unless you have
- set it OFF), Kermit interrupts any command that is currently in
- progress, and if a command file or macro is executing, rolls the
- command stack back to top level, closing all open command files,
- deactivating all macros, deallocating all local variables and arrays,
- and leaving you at the command prompt.
-
- Suppose, however, you want certain actions to occur when a script is
- interrupted; for example, closing open files, writing log entries, or
- displaying summary results. You can do this by defining a macro named
- ON_CTRLC. When Ctrl-C is detected, and a macro with this name is
- defined, Kermit executes it from the current command level, thus giving
- it full access to the environment in which the interruption occurred,
- including local variables and open files. Only when the ON_CTRLC macro
- completes execution is the command stack rolled back to top level.
-
- Once the ON_CTRLC macro is defined, it can be executed only once. This
- is to prevent recursion if the user types Ctrl-C while the ON_CTRLC
- macro is executing. If you type Ctrl-C while the Ctrl-C macro is
- active, this does not start a new copy of ON_CTRLC; rather, it returns
- to the top-level command prompt. After the ON_CTRLC macro returns, it
- has been removed from the macro table so if you want to use it again or
- install a different Ctrl-C trap, you must execute a new DEFINE ON_CTRLC
- command. In any case, as always when you interrupt a script with
- Ctrl-C, its completion status is FAILURE.
-
- Normally the ON_CTRLC macro would be defined in the command file or
- macro to which it applies, and should be declared LOCAL. This way, if
- the command file or macro completes successfully without being
- interrupted, the ON_CTRLC definition disappears automatically.
- Otherwise the definition would still be valid and the macro would be
- executed, probably out of context, the next time you typed Ctrl-C.
-
- Here's a simple example of a command file that sets a Ctrl-C trap for
- itself:
-
- local on_ctrlc ; Make Ctrl-C trap local to this command file.
- define on_ctrlc { ; Define the ON_CTRLC macro.
- echo Interrupted at \v(time).
- echo Iterations: \%n
- }
- xecho Type Ctrl-C to quit
- for \%n 1 999 1 { ; Prints a dot every second until interrupted.
- sleep 1
- xecho .
- }
- echo Finished normally at \v(time) ; Get here only if not interrupted.
- decrement \%n
- echo Iterations: \%n
-
- This prints a summary no matter whether it completes normally or is
- interrupted from the keyboard. In both cases the trap is automatically
- removed afterwards.
-
- For an example of how to use ON_CTRLC to debug scripts, see
- [487]Section 8.1.
-
- [ [488]Top ] [ [489]Contents ] [ [490]C-Kermit Home ] [ [491]Kermit
- Home ]
-
-9. S-EXPRESSIONS
-
- This section is primarily for those who want to write
- calculation-intensive scripts, especially if they require
- floating-point arithmetic, and/or for those who are familiar with the
- LISP programming language.
-
- Ever since C-Kermit version 5 was released in 1988, scripting has been
- one of its major attractions, and arithmetic is a key part of it.
- Versions 5 and 6 included integer arithmetic only, using traditional
- algebraic notation, e.g.:
-
- echo \fevaluate(3*(2+7)/2)
- 13
-
- C-Kermit 7.0 added support for floating-point arithmetic, but only
- through function calls:
-
- echo \ffpdivide(\ffpmultiply(3.0,\ffpadd(2.0,7.0)),2.0)
- 13.5
-
- C-Kermit 8.0 introduces a third form of arithmetic that treats integers
- and floating-point numbers uniformly, is easier to read and write, and
- executes very quickly:
-
- (/ (* 3 (+ 2 7)) 2)
- 13.5
-
- But first some background.
-
- The Kermit command and scripting language differs from true programming
- languages (such as C or Fortran) in many ways; one of the most
- prominent differences is the way in which variables are distinguished
- from constants. In a command language, words are taken literally; for
- example, the Unix shell:
-
- cat foo.bar
-
- displays the file named foo.bar. Whereas in a programming language like
- C, words are assumed to be variables:
-
- s = foo.bar; /* Assigns the value of foo.bar to the variable s */
-
- To make a programming language take words literally, you have to quote
- or "escape" them:
-
- s = "foo.bar"; /* Assigns a pointer to the string "foo.bar" to the variable s
- */
-
- The opposite holds for command languages: to get them to treat a word
- as a variable rather than a constant, you have to escape them. For
- example, in the Unix shell:
-
- foo=123 ; Assign value 123 to variable foo.
- echo foo ; Prints "foo"
- echo $foo ; Prints "123"
-
- And in Kermit:
-
- define foo 123 ; Assign value 123 to variable foo.
- echo 123 ; This prints "123".
- echo foo ; This prints "foo".
- echo \m(foo) ; This prints "123".
-
- In other words, character strings (such as "foo" above) are interpreted
- as literal strings, rather than variable names, except in special
- commands like DEFINE that deal specifically with variable names (or in
- numeric contexts as explained in [492]Section 8.2). The special
- "escape" character (dollar sign ($) for the shell, backslash (\) for
- Kermit) indicates that a variable is to be replaced by its value.
-
- The requirement to escape variable names in command languages normally
- does not impose any special hardship, but can add a considerable
- notational burden to arithmetic expressions, which are typically full
- of variables. Especially in Kermit when floating point numbers are
- involved, where you must use special \ffpxxx() functions, e.g.
- "\ffpadd(\m(a),\m(b))" rather than the simple "+" operator to add two
- floating-point numbers together, because the original arithmetic
- handler doesn't support floating point (this might change in the
- future). To illustrate, the general formula for the area of a triangle
- is:
-
- sqrt(s * (s - a) * (s - b) * (s - c))
-
- where a, b, and c are the lengths of the triangle's three sides and:
-
- s = (a + b + c) / 2
-
- Except in special cases (e.g. a = 3, b = 4, c = 5), the result has a
- fractional part so the computation must be done using floating-point
- arithmetic. We can create a Kermit 7.0 function for this as follows:
-
- def area {
- local s t1 t2 t3
- assign s \ffpdiv(\ffpadd(\ffpadd(\%1,\%2),\%3),2.0)
- assign t1 \ffpsub(\m(s),\%1)
- assign t2 \ffpsub(\m(s),\%2)
- assign t3 \ffpsub(\m(s),\%3)
- return \ffpsqrt(\ffpmul(\m(s),\ffpmul(\m(t1),\ffpmul(\m(t2),\m(t3)))))
- }
-
- But as you can see, this is rather cumbersome. Note, in particular,
- that arithmetic functions like \ffpadd(), \ffpmul(), etc, take exactly
- two operands (like their symbolic counterparts + and *), so obtaining
- the product of three or more numbers (as we do in this case) is
- awkward.
-
- Using the alternative S-Expression notation, we can reduce this to a
- form that is both easier to read and executes faster (the details are
- explained later):
-
- def newarea {
- (let s (/ (+ \%1 \%2 \%3) 2.0))
- (sqrt (* s (- s \%1) (- s \%2) (- s \%3)))
- }
-
- In both examples, the \%1..3 variables are the normal Kermit macro
- arguments, referenced by the normal escaping mechanism. For increased
- readability, we can also assign the macro arguments \%1, \%2, and \%3
- to the letters a, b, and c corresponding to our formula:
-
-def newarea {
- (let a \%1 b \%2 c \%3)
- (let s (/ (+ a b c) 2.0))
- (sqrt (* s (- s a) (- s b) (- s c)))
-}
-
- And now the Kermit function reads almost like the original formula.
- Here Kermit behaves more like a regular programming language. In an
- S-Expression, macro names need not be escaped when they are used as the
- names of numeric variables.
-
- [ [493]Top ] [ [494]Contents ] [ [495]C-Kermit Home ] [ [496]Kermit
- Home ]
-
-9.1. What is an S-Expression?
-
- The S-Expression concept is borrowed from the Lisp programming
- language. "S-Expression" is short for Symbolic Expression (itself
- sometimes shortened to SEXP). S-Expressions provide a kind of
- Alternative Mini-Universe within the Kermit command language when the
- regular rules don't apply, a universe enclosed in parentheses.
-
- C-Kermit does not pretend to be a full Lisp interpreter; only the
- arithmetic parts of Lisp have been incorporated: S-Expressions that
- operate on numbers and return numeric values (plus extensibility
- features described in [497]Section 9.8, which allow some degree of
- string processing).
-
- An S-Expression is a list of zero or more items, separated by spaces,
- within parentheses. Examples:
-
- ()
- (1)
- (a)
- (+ a 1)
- (* 2 a b)
-
- If the S-Expression is empty, it has the NIL (empty) value. If it is
- not empty and the first item is an operator (such as + or *), there can
- be zero or more subsequent items, called the operands:
-
- (+ 1 2)
-
- Here the operator is "+" and the operands are "1" and "2", and the
- value of the S-Expression is the value of the operation (in this case
- 3). The operator always comes first, which is different from the
- familiar algebraic notation; this because S-Expression operators can
- have different numbers of operands:
-
- (+ 1)
- (+ 1 2)
- (+ 1 2 3 4 5 6 7 8 9)
-
- If the first item in the S-Expression is not an operator, then it must
- be a variable or a number (or a macro; see [498]Section 9.8), and the
- S-Expression can only contain one item; in this case, the
- S-Expression's value is the value of the variable or number:
-
- (a)
- (3)
-
- Operands can be numbers, variables that have numeric values, functions
- that return numbers, or other S-Expressions. To illustrate an
- S-Expression within an S-Expression, observe that:
-
- (+ 1 2)
-
- is equivalent to any of the following (plus an infinite number of
- others):
-
- (+ 1 (+ 1 1))
- (+ (- 3 2) (/ 14 (+ 3 4)))
-
- S-Expressions can be nested to any reasonable level; for example, the
- value of the following S-Expression is 64:
-
- (- (* (+ 2 (* 3 4)) (- 9 (* 2 2))) 6)
-
- Operators have no precedence, implied or otherwise, since they can't be
- mixed. The only exceptions are unary + and -, which simply indicate the
- sign of a number:
-
- (* 3 -1)
-
- Order of evaluation is specified entirely by parentheses, which are
- required around each operator and its operands: (+ a (* b c)) instead
- of (a + b * c).
-
- S-Expressions provide a simple and isolated environment in which
- Kermit's macro names can be used without the \m(...) escaping that is
- normally required. Given:
-
- define a 1
- define b 2
- define c 3
-
- Then:
-
- (+ \m(a) \m(b) \m(c))
-
- is equivalent to:
-
- (+ a b c)
-
- Within an S-Expression, as in other strictly numeric contexts
- ([499]Section 8.2), any operand that starts with a letter is treated as
- a Kermit macro name. In this context, abbreviations are not accepted;
- variable names must be spelled out in full. Alphabetic case is not
- significant; "a" and "A" are the same variable, but both are different
- from "area".
-
- Of course, regular Kermit variables and functions can be used in
- S-Expressions in the normal ways:
-
- (* \v(math_pi) (^ \%r 2)) ; Area of a circle with radius \%r
- (+ \fjoin(&a)) ; Sum of all elements of array \&a[]
-
- [ [500]Top ] [ [501]Contents ] [ [502]C-Kermit Home ] [ [503]Kermit
- Home ]
-
-9.2. Integer and Floating-Point-Arithmetic
-
- Normally, if all numbers in an S-Expression are integers, the result is
- an integer:
-
- (+ 1 1) ; Result is 2
- (/ 9 3) ; Result is 3
-
- If any of the operands is floating point, however, the result is also
- floating point:
-
- (+ 1 1.0) ; Result is 2.0
- (/ 9.0 3) ; Result is 3.0
-
- If all the operands are integers but the result has a fractional part,
- the result is floating point:
-
- (/ 10 3) ; Result is 3.333333333333333
-
- To force an integer result in such cases, use the TRUNCATE operator:
-
- (truncate (/ 10 3)) ; Result is 3
-
- Similarly, to force a computation to occur in floating point, you can
- coerce one of its operands to FLOAT:
-
- (+ 1 (float 1)) ; Result is 2.0
-
- The result is also floating point if the magnitude of any integer
- operand, intermediate result, or the result itself, is larger than the
- maximum for the underlying machine architecture:
-
- (^ 100 100)
-
- If the result is too large even for floating-point representation,
- "Infinity" is printed; if it is too small to be distinguished from 0,
- 0.0 is returned.
-
- Large numbers can be used and large results generated, but they are
- accurate only to the precision of the underlying machine. For example,
- the result of:
-
- (+ 111111111111111111111 222222222222222222222)
-
- should be 333333333333333333333, but 333333333333333300000.0 is
- produced instead if the machine is accurate to only about 16 decimal
- digits, even with coercion to floating-point. The order of magnitude is
- correct but the least significant digits are wrong. The imprecise
- nature of the result is indicated by the ".0" at the end. Contrast
- with:
-
- (+ 111111111 222222222)
-
- which produces an exact integer result.
-
- [ [504]Top ] [ [505]Contents ] [ [506]C-Kermit Home ] [ [507]Kermit
- Home ]
-
-9.3. How to Use S-Expressions
-
- S-Expressions may be given as commands to C-Kermit. Any command whose
- first character is "(" (left parenthesis) is interpreted as an
- S-Expression.
-
- If you enter an S-Expression at the C-Kermit> prompt, its result is
- printed:
-
- C-Kermit>(/ 10.0 3)
- 3.333333333333333
- C-Kermit>
-
- If an S-Expression is executed within a macro or command file, its
- value is not printed. However, you can control the printing action
- with:
-
- SET SEXPRESSION ECHO { AUTO, ON, OFF }
- AUTO is the default, meaning print the value at top level only;
- ON means always print the value; OFF means never print it.
-
- In any case, the value of the most recent S-Expression (and the
- S-Expression itself) may be accessed programmatically through the
- following variables:
-
- \v(sexpression)
- The S-Expression most recently executed.
-
- \v(svalue)
- The value of the S-Expression most recently executed.
-
- Besides issuing S-Expressions as commands in themselves, you can also
- execute them anywhere within a Kermit command, but in this case they
- must be enclosed in a function call (otherwise they are taken
- literally):
-
- \fsexpression(s)
- The argument "s" is an S-Expression; the outer parentheses may
- be omitted. The value of the S-Expression is returned. Note that
- since S-Expressions usually contain spaces, some form of
- grouping or quoting might be needed in some contexts:
-
- echo \fsexpression((+ 1 1)) ; Outer parentheses may be included
- echo \fsexpr(+ 1 1) ; Outer parentheses may be omitted
- echo Value = "\fsexp(+ 1 a)" ; Can be embedded in strings
- echo Value = \&a[\fsexp(/ b 2)] ; Can be used in array subscripts
- if = {\fsexp(+ 1 1)} 2 { ; Braces needed here for grouping
- echo One plus one still equals two
- }
-
- The IF statement illustrates how to use S-Expressions as (or in) IF or
- WHILE conditions:
-
- * Although S-Expressions and IF conditions are similar in appearance,
- they are not interchangeable. Therefore you must use \fsexpr() to
- let Kermit know it's an S-Expression rather than a regular IF
- condition, or a boolean or algebraic expression within an IF
- condition.
- * In contexts where a single "word" is expected, you must enclose the
- \fsexp() invocation in braces if the S-Expression contains spaces
- (and most of them do).
-
- If an S-Expression is the last command executed in a macro, its value
- becomes the return value of the macro; no RETURN command is needed.
- Example:
-
- def newarea {
- (let s (/ (+ \%1 \%2 \%3) 2.0))
- (sqrt (* s (- s \%1) (- s \%2) (- s \%3)))
- }
-
- This is equivalent to (but more efficient than):
-
- def newarea {
- (let s (/ (+ \%1 \%2 \%3) 2.0))
- return \fsexp(sqrt (* s (- s \%1) (- s \%2) (- s \%3)))
- }
-
- When an S-Expression is entered as a command -- that is, the first
- nonblank character of the command is a left parenthesis -- then it is
- allowed to span multiple lines, as many as you like, until the first
- left parenthesis is matched:
-
- (let s (/
- (+
- \%1
- \%2
- \%3
- )
- 2.0
- )
- )
- (sqrt (*
- s
- (- s \%1)
- (- s \%2)
- (- s \%3)
- )
- )
-
- The S-Expression concept lends itself easily to embedding and
- recursion, but the depth to which recursion can occur is limited by the
- resources of the computer (memory size, address space, swap space on
- disk) and other factors. There is no way that C-Kermit can know what
- this limit is, since it varies not only from computer to computer, but
- also from moment to moment. If resources are exhausted by recursion,
- C-Kermit simply crashes; there's no way to trap this error. However,
- you can set a depth limit on S-Expressions:
-
- SET SEXPRESSION DEPTH-LIMIT number
- Limits the number of times the S-Expression reader can invoke
- itself without returning to the given number. The default limit
- is 1000. This limit applies to S-Expressions embedded within
- other S-Expressions as well as to S-Expressions that invoke
- recursive macros. If the limit is exceeded, Kermit prints
- "?S-Expression depth limit exceeded" and returns to its prompt.
- More about recursion in [508]Section 9.8.
-
- You can also test the depth programmatically:
-
- \v(sdepth)
- The current S-Expression invocation depth. The depth includes
- both nesting level and recursion. For example, in:
- (foo (foo (foo (foo (foo))))), the innermost (foo) is at depth
- 5.
-
- Help, completion, and syntax checking are not available within an
- S-Expression. If you type ? within an S-Expression, it says:
-
- C-Kermit>(? S-Expression ("help sexp" for details)
-
- As it says, typing "help sexp" will display a brief help text.
-
- The SHOW SEXPRESSION command displays current SET SEXPRESSION settings
- and related information.
-
- [ [509]Top ] [ [510]Contents ] [ [511]C-Kermit Home ] [ [512]Kermit
- Home ]
-
-9.4. Summary of Built-in Constants and Operators
-
- Three constants are built in:
-
- * PI, whose value is the value of pi (the quotient of circumference
- of any circle and its diameter, 3.141592653...) to the underlying
- machine's precision;
- * T, which always has the value 1, which signifies truth in Kermit
- logical expressions or S-Expressions;
- * NIL, which always has the empty value, and can serve as a False
- truth value.
-
- These constants are specific to S-Expressions and are not visible
- outside them. They may not be used as the target of an assignment. So,
- for example:
-
- (setq t 0) Fails
- assign t 0 Succeeds but this is not the same T!
-
- E (the base of natural logarithms, 2.7182818184...) is not built in
- since it is not intrinsic in most Lisp dialects. If you want E to be
- the base of natural logarithms you can:
-
- (setq e (exp 1))
-
- Operators are either symbols (such as "+") or words. Words must be
- spelled out in full, not abbreviated. Differences of alphabetic case
- are ignored.
-
- The most basic operation in S-Expressions is evaluation:
-
- EVAL [ s-expression or variable or number [ another [ another ... ] ] ]
- Evaluates its operands and returns the value of the last one
- evaluated. Examples:
-
- (eval) 0
- (eval 1) 1
- (eval a) value of a
- (eval (+ 1 a)) value of a+1
- (eval (setq a 1) (setq b (+ a 0.5))) value of b (= a+0.5)
-
- You can use "." as a shorthand for EVAL:
-
- (.)
- (. 1)
- (. a)
- (. (+ 1 a))
- (. (setq a 1) (setq b (+ a 0.5)))
-
- Opposite of EVAL is the operator that suppresses evaluation of its
- operand:
-
- QUOTE item
- The value (quote item) is "item". If the item is itself an
- S-Expression, the result is the S-Expression with the outer
- parentheses stripped. Examples:
-
- (quote) (illegal)
- (quote a) a
- (quote hello) hello
- (quote (this is a string)) this is a string
- (quote this is a string) (illegal)
-
- A shorthand notation is also accepted for quoting:
- 'a is equivalent to (quote a). And therefore:
- '(a b c) is equivalent to (quote (a b c)).
- More about quoting in [513]Section 9.8.
-
- STRING item
- Is a combination of EVAL and QUOTE. It evaluates the item as an
- S-Expression, and then puts quotes around the result (more about
- this in [514]Section 9.8).
-
- The following operators assign values to variables:
-
- SETQ [ variable [ value [ variable [ value [ ... ] ] ] ] ]
- Applies to global variables. For each variable given: if a value
- is not given, the variable is undefined. If a value is given,
- assigns the value to the variable. The value may be a number, a
- variable, or anything that resolves to a number including an
- S-Expression. Returns the value of the last assignment.
- Examples:
-
- (setq) Does nothing, returns NIL.
- (setq a) Undefines a, returns NIL.
- (setq a 1) Assigns 1 to a, returns 1.
- (setq a 1 b 2) Assigns 1 to a, 2 to b, returns 2.
- (setq a 1 b 2 c) Assigns 1 to a, 2 to b, undefines c, returns NIL.
-
- To undefine a variable that is not the final one in the list, give it a
- value of "()" or NIL:
-
- (setq a () b 2) Undefines a, assigns 2 to b, returns 2.
- (setq a nil b 2) Ditto.
-
- Note that a variable can be used right away once it has a value:
-
- (setq a 1 b a) Assigns 1 to a, the value of a (1) to b, returns 1.
-
- The results of SETQ (when used with macro names) can be checked
- conveniently with SHOW MACRO, e.g:
-
- show mac a b c
-
- LET [ variable [ value [ variable [ value [ ... ] ] ] ] ]
- Like SETQ, but applies to local variables. Note that "local" is
- used in the Kermit sense, not the Lisp sense; it applies to the
- current Kermit command level, not to the current S-Expression.
-
- If you want to use SETQ or LET to assign a value to a backslash
- variable such as \%a or \&a[2], you must double the backslash:
-
- (setq \\%a 3)
- (setq \\%b (+ \%a 1))
- (setq \\&a[2] (setq (\\%c (+ \%a \%b))))
-
- In other words:
-
- * Double the backslash when you want to indicate the variable's NAME;
- * Don't double the backslash when you want its VALUE.
-
- See [515]Section 9.6 for a fuller explanation of variable syntax and
- scope.
-
- Here's a summary table of arithmetic operators; in the examples, a is 2
- and b is -1.3:
-
- Operator Description Example Result
- + Adds all operands (0 or more) (+ a b) 0.7
- - Subtracts all operands (0 or more) (- 9 5 2 1) 1
- * Multiplies all operands (0 or more) (* a (+ b 1) 3) -1.80
- / Divides all operands (2 or more) (/ b a 2) -0.325
- ^ Raise given number to given power (^ 3 2) 9
- ++ Increments variables (++ a 1.2) 3.2
- -- Decrements variables (-- a) 1
- ABS Absolute value of 1 operand (abs (* a b 3)) 7.8
- MAX Maximum of all operands (1 or more) (max 1 2 3 4) 4
- MIN Minimum of all operands (1 or more) (min 1 2 3 4) 1
- MOD (%) Modulus of all operands (1 or more) (mod 7 4 2) 1
- FLOAT Convert an integer to floating-point (float 1) 1.0
- TRUNCATE Integer part of floating-point operand (truncate 3.333) 3
- CEILING Ceiling of floating-point operand (ceiling 1.25) 2
- FLOOR Floor of floating-point operand (floor 1.25) 1
- ROUND Operand rounded to nearest integer (round 1.75) 2
- SQRT Square root of 1 operand (sqrt 2) 1.414..
- EXP e (2.71828..) to the given power (exp -1) 0.367..
- SIN Sine of angle-in-radians (sin (/ pi 2)) 1.0
- COS Cosine of angle-in-radians (cos pi) -1.0
- TAN Tangent of angle-in-radians (tan pi) 0.0
- LOG Natural log (base e) of given number (log 2.7183) 1.000..
- LOG10 Log base 10 of given number (log10 1000) 3.0
-
- The ++ and -- operators are also assignment operators and work just
- like SETQ and LET in their interpretations of operators and operands,
- but:
-
- * Each target variable must already be defined and have a numeric
- value;
- * The assignment value is the amount by which to increment or
- decrement the variable.
- * If an assignment value is not given, 1 is used.
-
- If you include more than one variable-value pair in a ++ or --
- expression, every variable (except, optionally, the last) must be
- followed by a value. Examples:
-
- (++ a) Equivalent to (setq a (+ a 1)) and to (++ a 1)
- (++ a 2) Equivalent to (setq a (+ a 2))
- (-- a (* 2 pi)) Equivalent to (setq a (- a (* 2 pi)))
- (++ a 1 b 1 c 1 d) Equivalent to four SETQs incrementing a,b,c,d by 1.
-
- Another group of operators forms the predicates. These return a "truth
- value", in which 0 (or NIL) is false, and 1 or any other nonzero number
- is true.
-
- Operator Description Example Result
- = (or ==) Operands are equal (= 1 1.0) 1
- != Operands are not equal (!= 1 1.0) 0
- < Operands in strictly ascending order (< 1 2 3) 1
- <= Operands in ascending order (<= 1 1 2 3) 1
- > Operands in strictly descending order (> 3 2 1) 1
- >= Operands in descending order (<= 3 3 2 1) 1
- AND (&&) Operands are all true (and 1 1 1 1 0) 0
- OR (||) At least one operand is true (or 1 1 1 1 0) 1
- XOR Logical Exclusive OR (xor 3 1) 0
- NOT (!) Reverses truth value of operand (not 3) 0
-
- The Exclusive OR of two values is true if one value is true and the
- other value is false.
-
- And another group operates on bits within an integer word:
-
- Operator Description Example Result
- & Bitwise AND (& 7 2) 2
- | Bitwise OR (| 1 2 3 4) 7
- # Bitwise Exclusive OR (# 3 1) 2
- ~ Reverses all bits (~ 3) -4
-
- These operators coerce their operands to integer by truncation if
- necessary. The result of bit reversal is hardware dependent.
-
- The final category of operator works on truth values:
-
- Operator Description Example Result
- IF Conditional evaluation (if (1) 2 3) 2
-
- IF (predicate) (s1) [ (s2) ]
- The IF operator is similar to Kermit's IF command. If the
- predicate is true (i.e. evaluates to a nonzero number), the
- first S-Expression (s1) is evaluated and its value is returned.
- Otherwise, if (s2) is given, it is evaluated and its value
- returned; if (s2) is not given, nothing happens and the NIL
- (empty) value is returned.
-
- You can group multiple expressions in the s1 and s2 expressions using
- EVAL (or "."):
-
- (if (< a 0) (eval (setq x 0) (setq y 0)) (eval (setq x a) (setq y b)))
-
- or equivalently:
-
- (if (< a 0) (. (setq x 0) (setq y 0)) (. (setq x a) (setq y b)))
-
- Each operator has its own requirement as to number and type of
- operands. In the following table, "number" means any kind of number --
- integer or floating-point -- or a variable, function, macro, or
- S-Expression that returns a number; "vname" means variable name,
- "fpnumber" means a floating-point number (or anything that resolves to
- one), and "integer" means integer (or anything that resolves to one).
- "truthvalue" means anything that resolves to a value of zero or an
- empty value (which indicates false) or a nonzero value (which indicates
- true). "any" means any kind of value, including none at all.
-
- Operator Number of operands Type of operands Returns
- EVAL (.) 0 or more S-Expression Last value (default NIL)
- STRING 1 S-Expression string
- QUOTE (') 1 word string
- SETQ 0 or more vname value pairs Last value (default NIL)
- LET 0 or more vname value pairs Last value (default NIL)
- + 0 or more number number (default 0)
- - 0 or more number number (default 0)
- * 0 or more number number (see note (1))
- / 2 or more number number
- ^ 2 or more number number
- ++ 1 or more vname value pairs Result of last increment
- -- 1 or more vname value pairs Result of last decrement
- ABS 1 number number
- MAX 1 or more number number
- MIN 1 or more number number
- MOD (%) 2 number number
- FLOAT 1 number fpnumber
- TRUNCATE 1 number integer
- CEILING 1 number integer
- FLOOR 1 number integer
- ROUND 1 number integer
- SQRT 1 number fpnumber
- EXP 1 number fpnumber
- SIN 1 number fpnumber
- COS 1 number fpnumber
- TAN 1 number fpnumber
- LOG 1 number fpnumber
- LOG10 1 number fpnumber
- = (==) 1 or more number truthvalue
- != 1 or more number truthvalue
- < 1 or more number truthvalue
- <= 1 or more number truthvalue
- > 1 or more number truthvalue
- >= 1 or more number truthvalue
- AND (&&) 1 or more truthvalue truthvalue
- OR (||) 1 or more truthvalue truthvalue
- XOR 2 truthvalue truthvalue
- NOT (!) 1 truthvalue truthvalue
- & 1 or more number (see note 2) integer
- | 1 or more number (see note 2) integer
- # 2 number (see note 2) integer
- ~ 1 number (see note 2) integer
- IF 2 or 3 truthvalue,any,any any
-
- Operators that don't require any arguments return the default values
- shown.
-
- 1. The value of "*", when used as an operand, is initially "1" and the
- value of the most recent S-Expression thereafter, as in Franz Lisp.
- This is handy when doing a series of calculations by hand:
- C-Kermit>(* 13272.42 0.40)
- 5308.968
- C-Kermit>(/ * 2)
- 2654.4840
- C-Kermit>
-
- 2. The bitwise operators coerce their operands to integer by
- truncation.
-
- [ [516]Top ] [ [517]Contents ] [ [518]C-Kermit Home ] [ [519]Kermit
- Home ]
-
-9.5. Variables
-
- As noted elsewhere in this discussion, all backslash items (variables
- such as \%a, macro parameters such as \%1, array elements such as
- \&a[\%i], built-in variables such as \v(ndate), built-in functions such
- as \fjoin(), macro names enclosed in \m(), \s(), or \:(), etc) are
- evaluated at "top level" before the S-Expression is sent to the
- S-Expression reader. To use a backslash variable as the target of an
- assignment (e.g. by SETQ, LET, ++, or --), you must double the
- backslash, e.g. (setq \\%r 1234). This is discussed at greater length
- in the next section.
-
- Thus S-Expression reader generally deals only with macro names (not
- backslash items) as variables. It is important to understand how the
- reader handles macro names. There are fundamentally two kinds of
- S-Expressions: those that contain a single element, such as:
-
- (foo)
-
- and those that contain more than one element:
-
- (foo a b c)
-
- If an S-Expression contains only one element, and it is the name of a
- macro, the macro's definition is examined. If the definition is a
- number (integer or floating-point, positive or negative), then this
- becomes the value of the expression. If the definition starts with '
- (apostrophe), then the quoted word or string is the value of the
- expression (explained in [520]Section 9.8). Otherwise, the macro is
- assumed to be composed of Kermit commands (possibly including
- S-Expressions), which are executed. If the macro has a RETURN value, or
- it executes an S-Expression as its last command, the result becomes the
- value of the S-Expression; otherwise the result is empty.
-
- For S-Expressions that contain more than one element, and the first
- element is the name of a macro, then this macro is executed with the
- arguments that are given, after the arguments are evaluated by the
- S-Expression reader. Likewise, If the first element is a built-in
- operator, then it is applied to the operands after they are evaluated.
- In both cases, each operand is fed to the S-Expression reader
- recursively for evaluation. If an operand is a number or a quoted
- string, it is used as-is. But if it's a macro name, this degenerates
- into the first case, and the previous paragraph applies.
-
- Examples:
-
- define foo 123
- (foo) Result: 123
- define foo 'abc
- (foo) Result: abc
- define foo '(one two three)
- (foo) Result: one two three
- define foo return \frandom(1000)
- (foo) Result: 713 (or other number)
- define foo (+ a b)
- (foo) Result: The sum of a and b
-
- A more difficult example:
-
- define foo abc
- (foo) Result: ???
-
- The result in the last example depends on the definition of abc:
-
- * If it has no definition, an error occurs; otherwise:
- * If the definition is an S-Expression, the result is the
- S-Expression's value; otherwise:
- * If the definition consists of Kermit commands, they are executed.
- But in this case "(foo)" produces the empty result, because it
- doesn't RETURN anything.
-
- The use of macros as S-Expression operators is described in
- [521]Section 9.8.
-
- [ [522]Top ] [ [523]Contents ] [ [524]C-Kermit Home ] [ [525]Kermit
- Home ]
-
-9.6. Assignments and Scope
-
- The assignment operators SETQ and LET apply to global and local
- variables, respectively. SETQ and LET are standard Lisp operators
- adapted to Kermit scoping rules. When the operands are numeric or
- arithmetic, SETQ is equivalent to Kermit's EVALUATE command:
-
- (setq a (+ 1 2))
- evaluate a 1 + 2
-
- When the operand is a string, SETQ is equivalent to DEFINE:
-
- (setq a '(this is a string))
- define a this is a string
-
- In the first case, both statements create a macro named "a" with a
- value of 3. But in neither case is the macro "a" necessarily global. If
- either of these commands executes in an environment (i.e. macro
- invocation level) where a "local a" command has been given, the "a"
- macro is global to that environment, but is not visible outside it.
-
- LET is equivalent to the Kermit LOCAL command, followed by the
- corresponding EVALUATE:
-
- (let a (+ 1 2))
-
- is equivalent to:
-
- local a
- evaluate a 1 + 2
-
- Again, "local" in this context applies to the Kermit macro invocation
- stack, not to the S-Expression nesting level. To illustrate, recall our
- "newarea" macro:
-
-def newarea {
- (let a \%1 b \%2 c \%3)
- (let s (/ (+ a b c) 2.0))
- (sqrt (* s (- s a) (- s b) (- s c)))
-}
-
- Because SETQ and LET expressions return a value, they can be placed
- within a larger S-Expression. In this case we can replace the first
- reference to the "s" variable by its defining expression:
-
-def newarea {
- (let a \%1 b \%2 c \%3)
- (sqrt (* (let s (/ (+ a b c) 2.0)) (- s a) (- s b) (- s c)))
-}
-
- This would not work if LET were local to the S-Expression, but it works
- nicely in the context of Kermit macros. The previous definition is
- equivalent to:
-
-def newarea {
- local a b c s
- (setq a \%1 b \%2 c \%3)
- (sqrt (* (setq s (/ (+ a b c) 2.0)) (- s a) (- s b) (- s c)))
-}
-
- In both cases, the variables a, b, c, and s are local to the "newarea"
- macro, and global within it.
-
- Multiple assignments can be handled in several ways. Here is the
- obvious way to initialize a series of variables to the same value:
-
- (setq a 0)
- (setq b 0)
- (setq c 0)
- (setq s 0)
-
- Here is a more compact and efficient way of doing the same thing:
-
- (setq a 0 b 0 c 0 s 0)
-
- However, in case the value was more complex, it's better to put only
- one copy of it in the S-Expression; in this case we rely on the fact
- that SETQ returns the value of its last assignment:
-
- (setq a (setq b (setq c (setq s (* x (^ y 2))))))
-
- Similarly, to set a series of variables to x, x+1, x+2, ...
-
- (setq c (+ (setq b (+ (setq a (+ (setq s x) 1)) 1)) 1))
-
- In the last example, you can see why "last" does not always correspond
- to "rightmost" (the leftmost variable "c" is assigned last).
-
- If you are working with backslash variables like \%a or array elements
- like \&a[1], remember two rules:
- 1. Don't put spaces inside array brackets.
- 2. You must double the backslash when using SETQ, LET, ++, or -- to
- assign a value to a backslash variable.
-
- Examples of assigning to a backslash variable:
-
- (setq x 1)
- (setq \\%a 0)
- (setq \\&a[x+1] 1)
- (++ \\%x)
- (-- \\&a[x+2])
-
- Examples of referring to a backslash variable's value:
-
- (setq a (+ \%a 1))
- (setq b (+ \%a \&a[1]))
- (++ a \%x)
- (-- b \&a[1])
-
- The special notation is required because all backslashed items (\%x
- variables, array elements, built-in \v(xxx) variables, and \fxxx()
- function invocations) are evaluated in a single pass BEFORE the
- S-Expression is executed; any other approach would result in
- unacceptable performance. So, for example, in:
-
- declare \&a[] = 1 2 3
- define \%x 4
- define \%y 0
- (setq \\%y (+ \%x \&a[1]))
-
- the S-Expression becomes:
-
- (setq \%y (+ 4 1))
-
- before it is sent to the S-Expression evaluator. If the backslash had
- not been doubled on the assignment target, the result would have been:
-
- (setq 0 (+ 4 1))
-
- which is illegal because you can't assign a value to a number.
- Conversely, if backslashes were doubled on right-hand-side values:
-
- (setq \\%y (+ \\%x \\&a[1])
-
- this too, would give an error (not numeric - "\%x").
-
- If you omit the double backslash in the assignment target, the result
- depends on whether the variable already has a value:
-
- (setq \%a (* 3 3))
-
- If \%a has a non-numeric single-word value, then this becomes the name
- of the variable that is assigned by SETQ. To illustrate:
-
- define \%a foo
- echo \%a
- foo
- (setq \%a (* 3 3))
- echo \%a
- foo
- show macro foo
- foo = 9
-
- If \%a has no value, a numeric value, or a multiword value, an "invalid
- assignment" error occurs.
-
- [ [526]Top ] [ [527]Contents ] [ [528]C-Kermit Home ] [ [529]Kermit
- Home ]
-
-9.7. Conditional Expressions
-
- The IF operator provides a compact form of decision-making within
- S-Expressions. An IF expression can stand wherever a number might
- stand, as long is it returns a number. Here's a quick way to obtain the
- average value of all the elements in an array that contains only
- numbers:
-
- (/ (+ \fjoin(&a)) (float \fdim(&a)))
-
- This results in a "Divide by zero" error if the array is empty. If you
- want to define the average value of an empty array to be 0 instead of
- getting an error, you can use IF to check the array size:
-
- (if \fdim(&a) (/ (+ \fjoin(&a)) (float \fdim(&a))) 0)
-
- or equivalently:
-
- (if (not \fdim(&a)) 0 (/ (+ \fjoin(&a)) (float \fdim(&a))))
-
- Of course, IF can fit anywhere else into an S-Expression:
-
- (setq a (+ b (if (< c 0) 0 c)))
-
- and the IF expression can be as complex as you like:
-
- (setq a (+ b (if (and (or (> x 0) (> y 0)) (< c 0) (> d 1) (!= e 0)) 1 0)))
-
- and the "then" and "else" parts can contain multiple S-Expressions
- enclosed within (EVAL ...):
-
- (if x (eval (...) (...) (...)) (eval (...) (...) (...)))
-
- AND and OR operators are guaranteed to "short circuit". If any operand
- of AND is false, none of the subsequent operands is evaluated;
- likewise, if an OR operand is true, no further operands are evaluated.
-
- Bear in mind that the S-Expression IF is not the same as Kermit IF; the
- condition is only allowed to be an S-Expression or a variable or
- number, not the whole list of possibilities you see when you type "if
- ?" at the C-Kermit> prompt. But keep reading...
-
- [ [530]Top ] [ [531]Contents ] [ [532]C-Kermit Home ] [ [533]Kermit
- Home ]
-
-9.8. Extensibility
-
- To extend the capabilities of S-Expressions, you can use Kermit macro
- names as operators, with the following limitations:
-
- * The macro must not have the same name as a built-in operator.
- * You must use the full macro name, not an abbreviation.
-
- And with the following enhancement:
-
- * If the last statement executed by the macro is an S-Expression, its
- value is returned automatically. In other words:
-
- define bump (++ \%1)
-
- is equivalent to:
-
- define bump return \fsexpression(++ \%1)
-
- Here's an example in which we define a FIBONACCI operator that returns
- the nth element, n >= 0, of the Fibonacci series, 0 1 1 2 3 5 8 13 21
- 34 55, . . ., in which the first element is 0, the second is 1, and
- each subsequent element is the sum of the two before it. This series
- was devised by Leonardo Pisano, Filius Bonacci (Fibonacci for short) in
- 1202 to describe how fast rabbits can breed, and also forms the basis
- for the Golden Mean, the branching behavior of plants, the spiral of a
- nautilus shell, etc. (Thanks to [534]Dat Thuc Nguyen for December 2003
- corrections to this section!)
-
- We can write a FIBONACCI function as a macro easily with S-Expressions:
-
- define FIBONACCI {
- (if (== \%1 0) 0
- (if (== \%1 1) 1 (+ (fibonacci (- \%1 2)) (fibonacci (- \%1 1)))))
- }
-
- You can read this as:
-
- If the argument (\%1) is 0, return a result of 0; if it is 1,
- return 1; otherwise:
- return the sum of fibonacci(argument - 2) and fibonacci(argument -
- 1)
-
- Note that a RETURN statement is not needed, since S-Expressions
- automatically set the return value of their containing macros.
-
- For comparison, here's how it would be coded without S-Expressions:
-
- define FIBONACCI {
- if == \%1 0 {
- return 0
- } else if == \%1 1 {
- return 1
- } else {
- return \feval(\fexec(fibonacci \feval(\%1-2)) -
- + \fexec(fibonacci \feval(\%1-1)))
- }
- }
-
- Now we can use the FIBONACCI function (whichever way you write it) just
- as if it were a built-in operator:
-
- (fibonacci 6)
-
- Or:
-
- (setq a 10)
- (fibonacci a)
-
- Within S-Expressions only (not outside them), S-Expressions themselves
- can be used as macro arguments:
-
- (setq a 2 b 4)
- (setq x (fibonacci (* a b )))
-
- The value of the S-Expression (in this case "8"), and not the
- S-Expression itself, is sent to the macro.
-
- Your macro is responsible for argument validation and error handling. A
- robust Fibonacci macro would be more like this:
-
- define FIBONACCI {
- if < \v(argc) 2 end 1 ?\%0: Missing argument
- if > \v(argc) 2 end 1 ?\%0: Too many arguments
- if not integer \%1 end 1 ?\%0: Integers only
- if < \%1 1 end 1 ?\%0: Argument out of range
- (if (== \%1 0) 0
- (if (== \%1 1) 1 (+ (fibonacci (- \%1 2)) (fibonacci (- \%1 1)))))
- }
-
- Recall that "END nonzero-number [ message ]" causes a macro invocation
- to fail. When the macro is the operator in an S-Expression, this makes
- the S-Expression fail too. Also note that our Fibonacci macro is just
- an illustration, not a practical example. Since it is recursive (calls
- itself), it won't work for large arguments because the call stack can
- exceed available memory. See [535]Section 9.9.2 for a practical
- alternative.
-
- Kermit macros, when used as S-Expression operators, can do anything at
- all except initiate file transfers: they can print messages on the
- screen, read and write files, interact with the user, and so on. For
- example, here's a macro ASKME that asks you to enter a number, makes
- sure that you did, and then returns its value for use in the
- S-Expression:
-
- define ASKME {
- local \%n
- while true {
- ask \%n { Number: }
- if not def \%n continue
- if not numeric \%n {
- echo Not numeric - "\%n"
- continue
- }
- break
- }
- return \%n
- }
- (setq a (* 2 (askme))) ; Get number from user, double it, assign result to a.
-
- Here's a macro you can use to validate that a number is in a given
- range:
-
- define inrange {
- if != \v(argc) 4 end 1 ?\%0: Wrong number of arguments
- if ( < \%1 \%2 || > \%1 \%3 ) return 0
- return 1
- }
-
- The first argument is the number to be checked, the second is the
- minimum acceptable value, the third is the maximum. You can use this
- (for example) in IF conditions:
-
- define yes echo \%1 IS OK
- define no echo \%1 IS NOT OK
-
- (setq a -1 b 999)
- (if (inrange a 0 100) (yes a) (no a))
- (if (inrange b -1000 +1000) (yes b) (no b))
-
- This is just an illustration, of course; there's already a built-in
- operator to let you do range checking without help from macros:
-
- (if (<= 0 a 100) (yes a) (no a))
- (if (<= -1000 b +1000) (yes b) (no b))
-
- To send string parameters to a macro, some kind of quoting is required
- to tell the S-Expression parser to take a given "word" literally rather
- than replacing it by its value. For this we use the Lisp QUOTE
- operator:
-
- define length return \flength(\%1)
- (length (quote abcdefghijklmnopqrstuvwxyz))
- 26
-
- This causes the string "abcdefghijklmnopqrstuvwxyz" to be sent
- literally to the LENGTH macro. Kermit, like Lisp, also offers a
- shortcut for QUOTE, that lets us quote a word by prefixing it with a
- single quote (') character, also called apostrophe (ASCII 39):
-
- (length 'abcdefghijklmnopqrstuvwxyz)
- 26
-
- The two forms are equivalent.
-
- How the macro treats its arguments is up to the macro. In the example
- above, the argument is treated as a literal string. However, it can
- also be treated as a variable name:
-
- define string This is a string
- define length return \flength(\m(\%1))
- (length 'string)
- 16
-
- Note the construct \m(\%1). This means "the value of the macro whose
- name is the value of
- \%1". The value of \%1 in this case is the word "string", and the value
- of the macro whose name is "string" is "This is a string".
-
- What if the macro takes multiple arguments, or a variable number of
- them? Here's a simple macro that prints a phrase that includes its
- arguments:
-
- define complain echo It's too \%*!
-
- (Recall that \%* means "all arguments".)
-
- It can be called in the traditional way:
-
- complain hot Result: "It's too hot!"
- complain cold and wet Result: "It's too cold and wet!"
-
- Or from an S-Expression if you quote the arguments:
-
- (complain 'hot) Result: "It's too hot!"
- (complain 'cold 'and 'wet) Result: "It's too cold and wet!"
-
- To group multiple words into a single argument, use parentheses:
-
- (complain (quote (cold and wet))) Result: "It's too cold and wet!"
- (complain '(cold and wet)) Result: "It's too cold and wet!"
-
- Note the difference:
-
- (complain 'cold 'and 'wet) Three arguments
- (complain '(cold and wet)) One argument
-
- Since the COMPLAIN macro uses \%* to refer to all its arguments, no
- matter how many, it doesn't care which form you use. But it makes a
- difference in cases where the macro refers to its arguments
- individually.
-
- To illustrate, let's consider a macro that receives the name of a macro
- and its argument list and executes it with its arguments, without
- knowing how many arguments there are. The following LOOP macro is used
- to execute the given macro with the given argument list the requested
- number of times:
-
- def loop { local i, for i 1 \%1 1 do \%2 \%3 }
-
- Within the LOOP macro, the first argument (\%1) is the loop count, \%2
- is the macro name, and \%3 is the argument list. When the LOOP macro is
- invoked traditionally like this:
-
- loop 3 complain hot
-
- it prints "It's too hot!" three times. To invoke it from an
- S-Expression, you must quote both the macro name as well as the
- argument, since in this case the macro name itself is an argument:
-
- (loop 3 'complain 'hot)
-
- Now what if you need to send different or variable numbers of arguments
- to the LOOP macro? The LOOP macro can handle it already, provided you
- group the arguments into LOOP's third argument (\%3). In Kermit syntax,
- without grouping:
-
- loop 3 complain cold and wet
-
- prints "It's too cold!" three times ("and wet" is lost); but with
- grouping (either of the following two forms):
-
- loop 3 complain {cold and wet}
- loop 3 complain "cold and wet"
-
- the LOOP macro prints "It's too cold and wet!" three times as desired.
-
- To do the same thing in an S-Expression, just use the Lisp forms of
- quoting instead of the Kermit forms; the following two are equivalent:
-
- (loop 3 'complain (quote (cold and wet)))
- (loop 3 'complain '(cold and wet))
-
- Here's a similar example in which we write a macro that shows both the
- name and the value of one or more other macros, whose names are given
- as arguments (similar to "show macro"):
-
- define display {
- local \%i
- for \%i 1 \v(argc)-1 1 {
- echo \&_[\%i] = \m(\&_[\%i])
- }
- }
-
- (Recall that \&_[] is the macro's argument vector array, equivalent to
- \%1, \%2, ...) The DISPLAY macro can be used in S-Expressions like
- this:
-
- (setq a 1 b 2 c 3)
- (display 'a 'b 'c 'd)
-
- which prints:
-
- a = 1
- b = 2
- c = 3
- d =
-
- The names must be quoted to prevent their evaluation before they are
- sent to the macro. This ability to pass variables "by name" to macros,
- rather than by value, lets you write macros that change the values of
- argument variables. For example, here's a macro that doubles the value
- of its argument variable:
-
- define double (++ \%1 \%1)
-
- which you can call like this:
-
- (setq a 12)
- (double 'a)
-
- In the macro, \%1 is replace by the variable name "a"; "(++ a a)" adds
- "a" to itself, and sets the value of "a" to the result.
-
- There are no built-in operators other than QUOTE, ', and STRING for
- handling strings in S-Expressions, but using just these, plus macros
- that use Kermit's regular string-handling features, you can easily
- extend S-Expressions to do string manipulation:
-
- define len return \flen(\%1) Returns length of argument string
- define cap return \fupper(\%1) Uppercase argument string
- define rev return \freverse(\%1) Reverses argument string
- define sub return \fsubstr(\%1,\%2,\%3) Returns substring of arg string
-
- (len '(this is a string)) Result: 16
- (rev '(this is a string)) Result: gnirts a si siht
- (rev (cap '(this is a string))) Result: GNIRTS A SI SIHT
- (sub (rev (cap '(this is a string))) 5 9) Result: TS A SI S
-
- You can assign a string to a macro name as follows:
-
- (setq foo '(this is a string))
- (setq foo (quote (this is a string)))
-
- The two are exactly equivalent. In both cases, the macro "foo" has the
- value:
-
- '(this is a string)
-
- so when it is retrieved it can be identified as a string rather than a
- number or commands to be executed. Thus:
-
- (setq foo (quote (this is a string)))
- show macro foo
- foo = '(this is a string)
- (foo)
- this is a string
-
- Note the different results for "show macro foo" and "(foo)". The former
- shows the internal definition; the latter evaluates the variable, which
- removes the quoting. And perhaps more important, note that if the
- apostrophe and surrounding parentheses were not stored as part of the
- definition, (foo) would try to execute "this is a string" as a command.
-
- Given the assignment above, the following work as expected:
-
- (len foo) Result: 16
- (rev foo) Result: gnirts a si siht
- (rev (cap foo)) Result: GNIRTS A SI SIHT
- (sub (rev (cap foo)) 5 8) Result: TS A SI S
-
- Note that, unlike built-in S-Expression operators that return numbers
- or truth values, these operators return strings. If you want to assign
- their return values to other variables, you can do so:
-
- (setq bar (rev (cap foo))) Result: GNIRTS A SI SIHT
-
- But now the S-Expression processor doesn't know the value of "bar" is
- supposed to be a string, rather than a macro to execute. For this you
- need one final special operator, STRING. The STRING operator takes an
- S-Expression as an operand, evaluates it, and then returns its value
- enclosed in '(), so you can use the value as a string is subsequent
- S-Expressions. Use STRING for referencing macros that return strings:
-
- (setq bar (string (rev (cap foo)))) Result: '(GNIRTS A SI SIHT)
-
- STRING is like QUOTE, except that it evaluates its operand before
- applying the quoting, rather than taking the operand literally.
-
- To reference backslash variables or functions that return string
- values, you must use the regular quoting mechanisms:
-
- (setq time '(\v(time)))
- (setq date '(\v(date)))
- assign \%r this is a string
- (setq s1 '(\%r))
-
- That's because backslash items are evaluated BEFORE the S-Expression
- parser ever sees them, and the values of \v(time) and so on are not
- valid S-Expressions, so STRING won't like them.
-
- Finally a brief word on the touchy topic of quoting. Suppose you want
- to include (say) literal parentheses in a string that will later be
- processed by the S-Expression reader (or \fsplit() or \fword()).
- Normally, you can't do this because parentheses are meaningful in these
- contexts. To defeat the normal parsing rules, you can quote the
- parentheses with backslash. However, due to the many levels of string
- processing involved, a surprisingly large amount of backslashes might
- be required, for example:
-
- (setq s '(a b (c d) \\\\\\\\\\\\\\\\(e f (g h) x\\\\\\\\\\\\\\\\) j k))
-
- This is nearly impossible to explain(*). Instead, just remember two
- points:
-
- * In situations like this, it's better to use DEFINE to create the
- string, rather than SETQ. The example above requires only double
- backslashes when DEFINE is used:
- define s '(a b (c d) \\(e f (g h) x\\) j k)
-
- * The level of quoting depends on how many levels of evaluation the
- string must pass through, which is not always obvious. However, the
- number of backslashes required in any given situation is always a
- power of 2. So if 1 doesn't work, try 2; if 2 doesn't work, try 4;
- if 4 doesn't work, try 8, 16, 32, and so on.
-
- Considerations like this apply in any scripting language (shell, Tcl,
- Perl, Python, etc). The situation is known as "Quoting Hell".
-
- (*) If you really want an explanation, here it is:
-
- * Every SEXP has its backslash items evaluated in a single pass at
- top level before being passed to the SEXP reader, so \%1,
- \v(ftime), etc, can be evaluated up front, freeing the SEXP reader
- of having to know about such things, which in turn makes it much
- more efficient. Therefore one level of quoting is lost right away,
- and therefore you must double each backslash that is to be used as
- a quote.
- * When the SEXP reader sees '\', it treats it as a quote; discards it
- and keeps the next character. Thus '\\' becomes '\'. This would be
- the end of it, except that:
- * The SEXP reader must call itself recursively on its operands, so we
- must double any quotes in the operands: 2^2 = 4.
- * If the result is to be passed as an argument to a macro, the
- backslashes must again be doubled, because the macro processor
- evaluates the arguments before sending them to the macro: 2^3 = 8.
- * If the macro itself is to see the quotes, rather than just the
- result of the quoting, the quotes must be doubled again: 2^4 = 16.
-
- Moral: To create string constants in which grouping characters must be
- quoted, use DEFINE rather than SETQ.
-
- [ [536]Top ] [ [537]Contents ] [ [538]C-Kermit Home ] [ [539]Kermit
- Home ]
-
-9.9. Examples
-
-9.9.1. Statistics
-
- The following program computes statistics -- means, maxima, minima,
- variance, standard deviation, and correlation -- from data stored in
- parallel arrays, \&x[] and \&y[], which can contain any mixture of
- integer and floating-point numbers: positive, negative, or zero. Array
- setup and validation are not shown. Except for the traditional FOR loop
- and printing the results at the end, the entire computation is done
- with S-Expressions:
-
-; Initialize sums, maxima, minima, and number of elements
-
- (setq xsum 0 ysum 0 xsum2 0 ysum2 0 xysum 0)
- (setq xmin (setq xmax \&x[1]) ymin (setq ymax \&y[1]))
- (setq n \fdim(&x))
-
-; Loop through elements and accumulate sums, maxima, and minima
-
- for i 1 n 1 {
- (setq x \&x[i] y \&y[i]) ; Notational convenience
- (setq xmax (max xmax x) ymax (max ymax y)) ; X and Y maxima
- (setq xmin (min xmin x) ymin (min ymin y)) ; X and Y minima
- (++ xsum x ysum y) ; X and Y sums
- (++ xsum2 (^ x 2) ysum2 (^ y 2)) ; Sum of X and Y squares
- (++ xysum (* x y)) ; Sum of XY products
- }
-
-; Calculate results
-
- (setq xmean (/ xsum n) ymean (/ ysum n)) ; Mean X and Y
- (setq xss (- xsum2 (/ (^ xsum 2) n))) ; Intermediate values
- (setq yss (- ysum2 (/ (^ ysum 2) n)))
- (setq xyss (- xysum (/ (* xsum ysum) n)))
- (setq xvar (/ xss n) yvar (/ yss n)) ; X and Y variance
- (setq sdx (sqrt xvar) sdy (sqrt yvar)) ; Std deviation in X and Y
- (setq tmp (* xss yss))
- (setq cc (if tmp (/ xyss (sqrt tmp)) 1.0)) ; Correlation coefficient
- show macro xmean ymean xvar yvar sdx sdy cc ; Print the results
-
- The final "if tmp" check accounts for the possibility that both arrays
- contain all 0's. Results can also be printed with "echo CC = \m(cc)",
- or any other desired way. Interestingly, if we had not needed the sum
- of the squares and products, we could have obtained the sums, maxima,
- and minima of the X's and Y's without a loop like this:
-
- (setq xsum (+ \fjoin(&x)) ysum (+ \fjoin(&y)))
- (setq xmax (max \fjoin(&x)) ymax (max \fjoin(&y)))
- (setq xmin (min \fjoin(&x)) ymin (min \fjoin(&y)))
-
- Any Kermit function that returns numbers or lists of numbers can be
- included in an S-Expression as an operand.
-
-9.9.2. Practical Fibonacci Series
-
- The recursive Fibonacci example given previously is simple and elegant,
- but not very useful since it causes memory occupation to grow each time
- it calls itself, until eventually both physical memory and disk swap
- space are filled and the program crashes. Even for small arguments,
- like 17, execution time can be prohibitive:
-
- (setq t1 \v(ftime))
- (setq result (fibonacci 17))
- (setq t2 (- \v(ftime) t1))
- echo FIBONACCI(17) = \m(result): TIME = \ffpround(t2,3)
-
- prints (on a certain rather slow computer):
-
- FIBONACCI(17) = 1597: TIME = 5.861
-
- Any recursive function can be recoded iteratively. The result is not as
- pretty, but execution is far less expensive:
-
- define FIBITER {
- (if (== \%3 0) (\%2) (fibiter (+ \%1 \%2) \%1 (- \%3 1)))
- }
- define FIBONACCI {
- (fibiter 1 0 \%1)
- }
-
- Here's the result on the same computer for the same argument of 17:
-
- FIBONACCI(17) = 1597: TIME = 0.015
-
- (47 times faster.) Execution time increases proportionally to the size
- of the argument in the iterative case, whereas in the recursive case it
- goes up geometrically, quickly reaching infinity.
-
- [ [540]Top ] [ [541]Contents ] [ [542]C-Kermit Home ] [ [543]Kermit
- Home ]
-
-9.10. Differences from Algebraic Notation
-
- In C-Kermit:
-
- * Algebraic notation uses infix operators and normal rules of
- operator precedence, with parentheses used to force exceptions to
- the rules; many operations can be included in an expression.
- S-Expressions use prefix operators with no intrinsic precedence;
- each operation is enclosed in parentheses, and the arrangement of
- parentheses determines precedence.
- * Algebraic infix operators require two operands; S-Expression prefix
- operators can accept a variable number of operands.
- * You can use algebraic notation anywhere that C-Kermit accepts a
- number, e.g. "echo \&a[((1+1)*2-1]", but you can use S-Expressions
- only as top-level commands. You can, however, use either algebraic
- or S-Expressions anywhere at all by enclosing them in \fevaluate()
- or \fsexpression(), respectively.
- * You can use any mixture of integer and floating-point numbers in
- S-Expressions, but only integers are permitted in algebraic
- expressions. Outside of S-Expressions, floating point arithmetic is
- supported only by \ffp...() function calls.
- * Operators and operands in S-Expressions must be separated by
- spaces, e.g. "(+ a b)". Spaces are not required in algebraic
- expressions: "((a+b)*c)".
- * When assigning values to backslash variables (such as \%x or
- \&a[2]) using SETQ or LET, you must double the backslash.
-
- [ [544]Top ] [ [545]Contents ] [ [546]C-Kermit Home ] [ [547]Kermit
- Home ]
-
-9.11. Differences from Lisp
-
- * Kermit has a lot of built-in operators not found in Lisp: ++, ^,
- etc.
- * Most dialects of real Lisp do not allow S-Expressions that don't
- start with an operator, for example:
- (a)
-
- This expression can cause an error in Lisp (even if "a" has a
- value), but is acceptable in Kermit, where it returns the value of
- the variable "a". Similarly, (1) returns the value "1".
- * In real Lisp, EVAL requires exactly one operand. In Kermit, it can
- have 0, 1, 2, or more operands. It returns the value of the last
- operand evaluated.
- * Real Lisp SETQ and LET usually require an even number of operands.
- Kermit allows an odd number, in which case the last (or only)
- variable is undefined (i.e. deleted, destroyed).
- * Kermit does not support ratios such as "7/8". Some Lisp dialects
- accept ratios as numbers, and generate ratios when told to divide
- two integers whose quotient is not a whole number; e.g. in Common
- Lisp:
- [13] USER(37): (/ (+ 1 2 3 4) 3)
- 10/3
- [13] USER(38):
-
- * The result of (/ 10 3) is 3.333.... Some Lisp dialects truncate the
- result to 3 since both operands are integers, some don't; some give
- the result as a ratio. C-Kermit always gives a floating point
- result when there is a fractional part. If you want an integer
- result, you can use TRUNCATE, FLOOR, or CEILING, e.g. (truncate (/
- 10 3)).
- * There is currently no "bignum" support. Large numbers can be used
- and large results generated, but (as noted in [548]Section 9.2)
- they are accurate only to the precision of the underlying machine.
- \v(math_precision) gives the machine precision as a number of
- decimal digits, e.g. 16.
- * Scientific notation for floating-point numbers is not supported. If
- the magnitude of a number is greater than the precision of the
- underlying hardware, the less-significant digits are shown but
- their values are meaningless. If it the number is too small to be
- represented internally, it is shown as "0.0".
- * Many Lisp features are omitted: List processing (CAR, CDR, etc),
- DEFUN, Lisp-specific control structures, and so on.
-
- [ [549]Top ] [ [550]Contents ] [ [551]C-Kermit Home ] [ [552]Kermit
- Home ]
-
-10. FILE TRANSFER
-
- New commands and switches:
-
- SET TRANSFER REPORT { OFF, ON }
- Enables or disables the (new) one-line message printed by Kermit
- after a remote-mode file transfer to indicate the source and
- destination file, complete with path, to let you know where the
- file went.
-
- SEND /TYPE:{TEXT,BINARY}
- Sends only files of the given type (see [553]Section 4).
-
- SEND /NOFOLLOWLINKS:
- (UNIX only) Skip over symbolic links rather than following them
- (default). This applies to wildcard and/or recursive SENDs; if a
- single filename is given, and it happens to be a symbolic link,
- the file it points to is sent.
-
- SEND /FOLLOWLINKS:
- (UNIX only) Follow (resolve) symbolic links. Watch out for
- circular links, endless loops, etc.
-
- SET SEND I-PACKETS { OFF, ON }
- When sending commands to a Kermit server, this tells whether
- command packets should be preceded by an I (information) packet,
- which is used to synchronize parameters prior to executing the
- command. Normally ON. The only reason to set this OFF is for
- communicating with buggy Kermit servers that misbehave when an I
- packet is sent to them. There is also a SET RECEIVE I-PACKETS
- command, but presently it has no effect.
-
- SET TRANSFER MESSAGE [ text ]
- Sets an initial message to be shown in the Last Message field of
- the fullscreen file-transfer display.
-
- SET TRANSFER TRANSLATION { ON, OFF }
- Inhibits or re-enables text-file transfer character-set
- translation globally.
-
- { SEND, MSEND, GET, RECEIVE } /TRANSPARENT
- Inhibits character-set translation for this transfer only.
-
- { GET, RECEIVE } /PIPES:{ON,OFF}
- Overrides global TRANSFER PIPES setting for this transfer only;
- ON allows incoming files with names like "!tar xf -" to be
- opened as pipelines rather than regular files.
-
- The following new "hot keys" are available when Kermit's file-transfer
- display is visible:
-
- D: Turn on debugging, open "debug.log" if not already open.
- d: Turn off debugging but leave log open (if it was open).
- T: Turn on debug-log timestamps.
- t: Turn off debug-log timestamps.
-
- Other improvements:
- * SET FILE DOWNLOAD-DIRECTORY now works for external protocols (e.g.
- sz/rz) too.
- * Improved automatic per-file text/binary switching, described in
- [554]Section 4.
- * When sending a file group (e.g. "send *.*"), failure to open a file
- is no longer fatal; now C-Kermit simply goes ahead to the next
- file.
- * Transaction log entries are now made for external protocols too.
-
- [ [555]Top ] [ [556]Contents ] [ [557]C-Kermit Home ] [ [558]Kermit
- Home ]
-
-11. MODEMS AND DIALING
-
- In C-Kermit 8.0, the default modem type for dialing has changed from
- NONE (= DIRECT, meaning no modem) to GENERIC. This change should have
- no impact on direct connections. For dialing, it means that, unless you
- SET MODEM TYPE to a specific type, such as USROBOTICS or CONEXANT,
- Kermit assumes:
-
- 1. The modem uses the Hayes AT command set.
- 2. The modem supports error correction, data compression, and hardware
- flow control and is already configured to use them.
-
- In fact, Kermit assumes the modem is completely configured, and
- therefore does not send it an initialization string or any
- configuration commands. Instead, it sends only the simplest and most
- portable commands:
-
- ATQ0V1 Give dial result codes.
- ATDTnumber Dial the number.
-
- (or ATD or ATDP, as appropriate).
-
- The new defaults work for direct connections and for most modern modems
- on most platforms, and they work much faster than "full-treatment"
- dialing. If the new defaults don't work for you, or if you need to
- perform explicit modem configurations or interactions, then set a
- specific modem type and use the SET MODEM and SET DIAL commands as
- documented in Using C-Kermit.
-
- WARNING: Don't use the generic modem on hosts that do not support
- RTS/CTS flow control. If Xon/Xoff is in use on the serial port,
- you'll need to select a particular modem type so Kermit knows what
- command to give it to enable Xon/Xoff flow control between itself
- and your serial port.
-
- The following new modem types were added in C-Kermit 8.0:
-
- lucent: Lucent Venus chipset
- pctel: PCTel V.90 chipset
- conexant: Conexant (ex-Rockwell) modem family
- zoom-v32bis: New name for "Zoom"
- zoom-v34 Zoom V.34
- zoom-v90 Zoom V.90 56K
- zoom-v92: Zoom V.92 with V.44 data compression
- zoltrix-v34: New name for "zoltrix"
- zoltrix-hsp-v90: Synonym for PCTel
- zoltrix-hcf-v90: Synonym for ITU-T-V250
- smartlink-v90: Synonym for usrobotics (same chipset)
- acer-v90: Synonym for Rockwell-v90
-
- New DIAL-related variables:
-
- \v(dm_hf): Dial modifier: Wait for Hook-Flash.
- \v(dm_wb): Dial modifier: Wait for Bong.
-
- Finally, if dialing fails, Kermit now prints a context-sensitive hint
- suggesting possible reasons and remedies.
-
- Added in C-Kermit 8.0.201: Rudimentary support for Caller ID, for use
- with the ANSWER command. If the modem reports Caller ID information,
- Kermit stores it in variables that you can access after the call is
- answered:
-
- \v(callid_date) The date of the call
- \v(callid_time) The time of the call
- \v(callid_name) The name of the caller
- \v(callid_nmbr) The telephone number of the caller
- \v(callid_mesg) A message
-
- The format of these items depends on the originating and answering
- phone companies and the modems and their configuration.
-
- Not very many modems support Caller ID, and those that do (a) tend to
- have it disabled by default, and (b) use different commands to enable
- it. A quick survey shows of some current models shows:
-
- - USR V.90: No
- - ITU-T V.250: No
- - Lucent Venus: No
- - Diamond Supra: #CID=1
- - Rockwell 56K: #CID=1
- - PCTEL: #CID=1
- - Zoltrix: +VCID=1
- - Conexant: +VCID=1
-
- To use Kermit's Caller ID feature, you have to set the modem to wait
- for at least two rings before answering, and you have to give the
- command to enable Caller ID; for example (after choosing a modem with
- SET MODEM TYPE):
-
- set modem command autoanswer on ATS0=2#CID=1\{13}
- set modem command autoanswer on ATS0=2+VCID=1\{13}
-
- These commands can be undone with:
-
- set modem command autoanswer on ATS0=1#CID=0\{13}
- set modem command autoanswer on ATS0=1+VCID=0\{13}
-
- Kermit presently has no built-in knowledge of the Caller ID
- capabilities or commands of the modems in its database.
-
- Since the variables can be accessed only after the call is answered,
- the only way to refuse a call is to answer it, inspect the variables,
- and then hang it up if desired.
-
- [ [559]Top ] [ [560]Contents ] [ [561]C-Kermit Home ] [ [562]Kermit
- Home ]
-
-12. TERMINAL CONNECTION
-
- Now that 7-bit connections are no longer the norm, the default terminal
- bytesize (also called "data size" or "word size") in C-Kermit 8.0 is 8
- bits, rather than 7 bits as it was in C-Kermit 7.0 and earlier:
-
- SET ESCAPE character
- This command, which specifies your CONNECT-mode escape
- character, allows you to specify any ASCII control character in
- a variety of formats. C-Kermit 8.0.201 now also lets you specify
- any 8-bit value, 128-255, as the escape character. In the SET
- ESCAPE command, you can type the 8-bit character literally or
- you can enter its numeric code. Here are examples that you can
- enter from a terminal or console that uses the ISO Latin-1
- character set:
-
- C-Kermit> set escape �
- C-Kermit> set escape 195
- C-Kermit> show escape
- Escape character: Code 195 (�): enabled
- C-Kermit>
-
- Both of these commands set the escape character value to 195
- (decimal), which happens to be uppercase letter A with Tilde in
- Latin-1. SHOW ESCAPE and SHOW TERMINAL show the value, as does
- the CONNECT message.
-
- SET TERMINAL AUTODOWNLOAD ERROR { STOP, CONTINUE }
- When Kermit has a terminal connection to another computer, and a
- file transfer is initiated automatically because a Kermit packet
- was received in CONNECT mode (i.e. in the terminal screen), this
- command tells what Kermit should do if the transfer fails. The
- default is to STOP, which leaves Kermit in command mode with its
- file-transfer display showing, so you can see that the transfer
- failed and why. If you SET TERMINAL AUTODOWNLOAD ERROR CONTINUE,
- this causes Kermit to return automatically to its terminal
- screen (i.e. resume its CONNECT session) as if the transfer had
- succeeded; this can be desirable if the entire session is under
- control of a host-based script.
-
- SET TERMINAL BYTESIZE { 7, 8 }
- The byte size to use during CONNECT and INPUT command execution,
- which can be more restrictive than the bytesize implied by the
- current PARITY setting, but not less restrictive. In C-Kermit
- 7.0 and earlier, the terminal bytesize was 7 by default to
- protect against the likelihood that parity was in use on the
- connection without the user's knowledge. When the terminal
- bytesize is 8 (as it is in C-Kermit 8.0 and later), the user
- will see garbage in this (increasingly unlikely) situation. Note
- that 8 data bits are required for most character sets other than
- ASCII: Latin-1, UTF-8, and so on.
-
- A new command has been added to produce timestamped session logs:
-
- SET TERMINAL SESSION-LOG TIMESTAMPED-TEXT
- Records the terminal session in text mode (like SET TERMINAL
- SESSION-LOG TEXT) but adds a timestamp at the beginning of each
- line. The timestamp format is hh:mm:ss.nnn, and indicates the
- time at which the first character of the line appeared.
-
- In most UNIX versions (those built with the select()-capable CONNECT
- module -- pretty much all the ones that have or could have TELNET
- included), an idle timeout feature has been added:
-
- SET TERMINAL IDLE-TIMEOUT number
- If the number is not 0, then Kermit is to take an action when
- the given amount of time passes with no activity during CONNECT
- mode. If the number is positive it is the maximum number of idle
- seconds; if number is negative it represents milliseconds
- (thousandths of seconds). If 0 is given as the number, there are
- no idle timeouts. Synonym: SET TERMINAL IDLE-LIMIT.
-
- SET TERMINAL IDLE-ACTION { RETURN, HANGUP, EXIT, OUTPUT [ string ] }
- The action to be taken upon an idle timeout in CONNECT mode.
- RETURN to the prompt, HANGUP the connection, EXIT from Kermit,
- or OUTPUT the given string (if no string is given, a NUL (ASCII
- 0) character is sent).
-
- SET TERMINAL IDLE-ACTION { TELNET-NOP, TELNET-AYT }
- Actions that can be selected on Telnet connections only, that
- might be useful if idle limits are enforced by the Telnet server
- or in the TCP/IP protocol: TELNET-NOP sends a "NO Operation"
- (do-nothing) command, which causes no response from the server;
- TELNET-AYT sends an "Are You There" message to the server, which
- should make the server send back a message. Neither of these
- actions interferes with your remote session.
-
- SET TERMINAL IDLE-ACTION is useful for connections to hosts or services
- that automatically log you out after a certain amount of idle time,
- e.g.:
-
- set term idle-timeout 300
- set term idle-action output \32
-
- sends a space (as if you had pressed the space bar) every 300 seconds
- (five minutes) while there is no activity (32 is the ASCII code for
- space).
-
- When C-Kermit returns from CONNECT to command mode, the reason for the
- transition is given in a new variable, \v(cx_status):
-
- 0 No CONNECT command given yet.
- 1 User escaped back manually.
- 2 A trigger string was encountered.
- 3 IKSD entered server mode.
- 4 Application Program Command received from host.
- 5 Idle timeout.
- 6 Telnet protocol error.
- 7 Keystroke macro.
- 8 Time limit exceeded.
- 100 Internal error.
- 101 Carrier required by not detected.
- 102 I/O error on connection.
- 103 Disconnected by host.
- 104 Disconnected by user.
- 105 Session limit exceeded.
- 106 Rejected due to Telnet policy.
- 107 Received kill signal.
-
- Values 100 and above indicate there is no connection.
-
- [ [563]Top ] [ [564]Contents ] [ [565]C-Kermit Home ] [ [566]Kermit
- Home ]
-
-13. CHARACTER SETS
-
- See the section on [567]file scanning above, and the section on
- character-set conversion in [568]FTP. Also:
-
- * True support for CP1252 (rather than treating it as Latin-1).
- * Proper handling of C1 values when converting ISO 8-bit text to
- UTF-8.
- * TYPE /CHARACTER-SET: /TRANSLATE-TO: allows specific translations.
- * The TRANSLATE command now works on multiple files.
- * K_CHARSET environment variable to set the file character-set.
- * SET TRANSFER TRANSLATION OFF.
- * FTP client character-set translation ([569]Section 3.7).
-
- [ [570]Top ] [ [571]Contents ] [ [572]C-Kermit Home ] [ [573]Kermit
- Home ]
-
-14. DIALOUT FROM TELNET TERMINAL SERVERS
-
- For years, C-Kermit has supported dialing out from Telnet modem servers
- (also called reverse terminal servers or access servers), but until now
- there was no way for Kermit to control the communication parameters
- (speed, parity, etc) on the serial port of the terminal server; it had
- to use whatever was there.
-
- But now, if you make a connection to a server that supports the Telnet
- Com Port Control Option, [574]RFC 2217, you have the same degree of
- control as you would have over a serial port on the computer where
- Kermit is running: SET SPEED, SET FLOW, SET PARITY, SET STOP-BITS, SHOW
- COMM, WAIT, SET CARRIER-WATCH, the modem-signal variables, sending
- Break, and so on, apply to the connection between the terminal server
- and the modem.
-
- For example, using a Cisco Access Server 2509, where specifying a TCP
- port in the 6000's selects a serial port that can be used for dialing
- out:
-
- set host xxx 6001 ; xxx is the IP hostname or address of the server
- (log in if necessary) ; With a script or by hand
- set modem type usr ; Tell Kermit what kind of modem it has
- set speed 57600 ; This affects the server's port
- set flow rts/cts ; Ditto
- dial 7654321
-
- The modem server might or might not require a login sequence. It might
- also allow for automatic authentication, e.g. via Kerberos tickets.
- NOTE: If the modem server requires a login sequence, then REDIAL might
- not work as expected.
-
- When you have a Telnet Com Port connection, your SET SPEED and SET FLOW
- options change automatically to reflect the capabilities of the server,
- rather than those of your local computer.
-
- See the configuration manual for your server for additional
- information. For example, how to set up the server to drop the Telnet
- connection automatically when the telephone call is hung up (e.g.
- "autohangup" on Cisco models).
-
- For a Linux-based Telnet Com-Port server, click the Sredird link:
-
- [ [575]Top ] [ [576]Contents ] [ [577]Sredird ] [ [578]C-Kermit Home ]
- [ [579]Kermit Home ]
-
-15. COPING WITH BROKEN KERMIT PARTNERS
-
- There are lots of faulty Kermit protocol implementations out there,
- found mainly in 3rd-party products ranging from communications software
- packages to file-transfer functions embedded within devices. This topic
- is covered [580]HERE for C-Kermit 7.0, but C-Kermit 8.0 adds some
- additional tricks.
-
- SET ATTRIBUTE RECORD-FORMAT { ON, OFF }
- Allows control of the Kermit's Record-Format attribute. Set this
- to OFF in case incoming file are refused due to unknown or
- invalid record formats if you want to accept the file anyway.
-
- SET ATTRIBUTES OFF
- This is not a new trick, but it was recently discovered that the
- Kermit implementation embedded within a certain kind of
- punching/bending machine (Salvagnini if you must know) hangs
- upon reception of standard format Kermit attributes when
- receiving files. When sending files, it sends attributes of its
- own, one per A-packet, which is slightly unusual but legal. When
- receiving files from C-Kermit, K95, MS-DOS Kermit, Kermit-370,
- etc, it simply exits upon reception of the first A-packet;
- apparently it was not coded according to the protocol
- specification, which allows multiple attributes per A-packet.
- Solution: tell the file sender to SET ATTRIBUTES OFF.
-
- SET SEND I-PACKETS { ON, OFF }
- A Kermit server is supposed to accept I-packets; this is how the
- client lets the server know its capabilities and preferences
- before sending a command. Apparently there is at least one
- Kermit server implementation that does not accept I-packets, and
- does not properly respond with an Error packet if it gets one.
- To get around such situations in C-Kermit 8.0, you can use SET
- SEND I-PACKETS OFF to inhibit the sending of I packets. In this
- case, the client must be able to adjust to the server's
- configuration, rather than the other way around as we are used
- to.
-
- SET PROTOCOL KERMIT {} {} {}
- C-Kermit 6.0 and later automatically send "autoupload" and
- "autodownload" commands when in local mode and you give a file
- transfer command. For example, if you tell kermit to "send
- oofa.txt", Kermit sends "kermit -r" and a carriage return, in
- case you had forgotten to start Kermit on the far end and told
- it to receive a file. If a Kermit program had already been
- started on the far end, it should harmlessly absorb this string.
- However, some Kermit programs violate the Kermit protocol
- definition and treat such strings as Kermit packets even though
- they are not. In such cases, give this command to set the Kermit
- protocol autoupload and download strings to nothing, which tells
- Kermit not to send them. (This is not a new feature, but it was
- not previously included in the "Coping" section of the
- documentation.)
-
- [ [581]Top ] [ [582]Contents ] [ [583]C-Kermit Home ] [ [584]Kermit
- Home ]
-
-16. NEW COMMAND-LINE OPTIONS
-
- kermit -h Now prints a complete listing of its command-line options,
- rather than an abbreviated list squeezed into a 24x80 space.
-
- -dd Debug, like -d but adds timestamps
- --version Shows C-Kermit version number.
- --noperms Equivalent to SET ATTRIBUTE PROTECTION OFF.
-
- Kermit now accepts a selection of URLs (Universal Resource Locators) as
- its first command-line argument. These are:
-
- telnet:hostname
- Makes a Telnet connection to the given host (IP hostname or
- address).
-
- ftp://[user[:password]@]hostname[/path...]
- Makes an FTP connection to the given host (IP hostname or
- address). If a username is given, Kermit tries to log you in; if
- a password is given, it is used; if not, you are prompted for
- one. If no username is given, an anonymous login is performed.
- If a pathname is included, Kermit tries to GET the given file.
- See [585]Section 3.1.3 for details.
-
- ftps://[user[:password]@]hostname[/path...]
- Makes a secure FTP connection over SSL.
-
- telnets://[user[:password]@]hostname
- Makes a secure Telnet connection over SSL.
-
- kermit://[user[:password]@]hostname[/path...]
- Makes a connection to an [586]Internet Kermit Server.
-
- http://[user[:password]@]hostname[/path...]
- Makes a connection to Web server.
-
- https://[user[:password]@]hostname[/path...]
- Makes a connection to secure Web server.
-
- [ [587]Top ] [ [588]Contents ] [ [589]C-Kermit Home ] [ [590]Kermit
- Home ]
-
-17. LOGS
-
- In C-Kermit 8.0, we make an effort to keep passwords out of the debug
- log. This can never be 100% effective, but it's better than before,
- when there were no precautions at all. Whenever Kermit knows it's
- prompting for, parsing, or transmitting a password, it temporarily
- turns off logging and then turns it back on afterwards. This keeps the
- debug log password-free in most common cases, but there can be no
- guarantees.
-
- As noted elsewhere, the new "-dd" command-line option selects a
- timestamped debug log (equivalent to "set debug timestamps on", "log
- debug debug.log").
-
- C-Kermit 8.0 also supports a new timestamped session log via "set
- session-log timestamped-text", "log session".
-
- There have been requests for other kinds of logs, for example a command
- log. These might be added at some point. One person wanted to be able
- to log commands with timestamps, but only commands issued at the
- prompt, not commands from files or macros, and also wanted a header
- line at the beginning showing the date, user, and host. This can be
- done as follows:
-
- .filename := \v(home)commands.log ; (for example)
- fopen /write \%c \m(filename)
- if success {
- fwrite /line \%c \v(date): User=\v(user) Host=\v(host)
- fclose \%c
- set debug timestamps on
- log debug {| grep "CMD(P)" >> \m(filename)} append
- }
-
- [ [591]Top ] [ [592]Contents ] [ [593]C-Kermit Home ] [ [594]Kermit
- Home ]
- __________________________________________________________________
-
-
- C-Kermit 8.0 Update Notes / [595]The Kermit Project / Columbia
- University / 15 Dec 2003 - 13 Sep 2010
-
-References
-
- 1. http://www.columbia.edu/
- 2. mailto:kermit@columbia.edu
- 3. http://www.columbia.edu/kermit/index.html
- 4. http://www.columbia.edu/kermit/k95.html
- 5. http://www.columbia.edu/kermit/ckermit.html
- 6. http://www.columbia.edu/kermit/ckscripts.html
- 7. http://www.columbia.edu/kermit/current.html
- 8. http://www.columbia.edu/kermit/whatsnew.html
- 9. http://www.columbia.edu/kermit/faq.html
- 10. http://www.columbia.edu/kermit/support.html
- 11. http://www.columbia.edu/kermit/ckermit80.html#contents
- 12. http://www.columbia.edu/kermit/ckermit.html
- 13. http://www.columbia.edu/kermit/index.html
- 14. http://www.amazon.com/gp/product/1555581641?ie=UTF8&tag=aleidmoreldom-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1555581641
- 15. http://www.columbia.edu/kermit/ckermit80.html
- 16. mailto:kermit-support@columbia.edu
- 17. http://www.columbia.edu/kermit/
- 18. http://www.kermit-project.org/
- 19. http://www.columbia.nyc.ny.us/kermit/
- 20. ftp://kermit.columbia.edu/kermit/f/COPYING.TXT
- 21. ftp://kermit.columbia.edu/kermit/f/ckcmai.c
- 22. http://www.columbia.edu/kermit/ckermit80.html#xv
- 23. http://www.columbia.edu/kermit/ck60manual.html
- 24. http://www.columbia.edu/kermit/ckermi70.html
- 25. ftp://kermit.columbia.edu/kermit/f/ckermit70.txt
- 26. http://www.columbia.edu/kermit/ckututor.html
- 27. ftp://kermit.columbia.edu/kermit/f/ckuker.nr
- 28. http://www.columbia.edu/kermit/security.htm
- 29. http://www.columbia.edu/kermit/telnet.htm
- 30. http://www.columbia.edu/kermit/ftpscripts.html
- 31. http://www.columbia.edu/kermit/ckcbwr.html
- 32. ftp://kermit.columbia.edu/kermit/f/ckcbwr.txt
- 33. http://www.columbia.edu/kermit/ckubwr.html
- 34. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt
- 35. http://www.columbia.edu/kermit/ckvbwr.html
- 36. ftp://kermit.columbia.edu/kermit/f/ckvbwr.txt
- 37. http://www.columbia.edu/kermit/ckuins.html
- 38. ftp://kermit.columbia.edu/kermit/f/ckuins.txt
- 39. http://www.columbia.edu/kermit/ckvins.html
- 40. ftp://kermit.columbia.edu/kermit/f/ckvins.txt
- 41. http://www.columbia.edu/kermit/ckccfg.html
- 42. ftp://kermit.columbia.edu/kermit/f/ckccfg.txt
- 43. http://www.columbia.edu/kermit/ckcplm.html
- 44. ftp://kermit.columbia.edu/kermit/f/ckcplm.txt
- 45. http://www.columbia.edu/kermit/iksd.html
- 46. http://www.columbia.edu/kermit/skermit.html
- 47. http://www.columbia.edu/kermit/ckermit80.html#top
- 48. http://www.columbia.edu/kermit/ckermit.html
- 49. http://www.columbia.edu/kermit/index.html
- 50. http://www.columbia.edu/kermit/ckermit80.html#x0
- 51. http://www.columbia.edu/kermit/ckermit80.html#x1
- 52. http://www.columbia.edu/kermit/ckermit80.html#x2
- 53. http://www.columbia.edu/kermit/ckermit80.html#x2.1
- 54. http://www.columbia.edu/kermit/ckermit80.html#x2.2
- 55. http://www.columbia.edu/kermit/ckermit80.html#x2.2.1
- 56. http://www.columbia.edu/kermit/ckermit80.html#x2.2.2
- 57. http://www.columbia.edu/kermit/ckermit80.html#x2.2.3
- 58. http://www.columbia.edu/kermit/ckermit80.html#x2.2.4
- 59. http://www.columbia.edu/kermit/ckermit80.html#x2.2.5
- 60. http://www.columbia.edu/kermit/ckermit80.html#x2.2.6
- 61. http://www.columbia.edu/kermit/ckermit80.html#x3
- 62. http://www.columbia.edu/kermit/ckermit80.html#x3.1
- 63. http://www.columbia.edu/kermit/ckermit80.html#x3.1.1
- 64. http://www.columbia.edu/kermit/ckermit80.html#x3.1.2
- 65. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3
- 66. http://www.columbia.edu/kermit/ckermit80.html#x3.1.4
- 67. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 68. http://www.columbia.edu/kermit/ckermit80.html#x3.3
- 69. http://www.columbia.edu/kermit/ckermit80.html#x3.4
- 70. http://www.columbia.edu/kermit/ckermit80.html#x3.5
- 71. http://www.columbia.edu/kermit/ckermit80.html#x3.5.1
- 72. http://www.columbia.edu/kermit/ckermit80.html#x3.5.2
- 73. http://www.columbia.edu/kermit/ckermit80.html#x3.5.3
- 74. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 75. http://www.columbia.edu/kermit/ckermit80.html#x3.6.1
- 76. http://www.columbia.edu/kermit/ckermit80.html#x3.6.2
- 77. http://www.columbia.edu/kermit/ckermit80.html#x3.6.3
- 78. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 79. http://www.columbia.edu/kermit/ckermit80.html#x3.7.1
- 80. http://www.columbia.edu/kermit/ckermit80.html#x3.7.2
- 81. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 82. http://www.columbia.edu/kermit/ckermit80.html#x3.9
- 83. http://www.columbia.edu/kermit/ckermit80.html#x3.10
- 84. http://www.columbia.edu/kermit/ckermit80.html#x3.10.1
- 85. http://www.columbia.edu/kermit/ckermit80.html#x3.10.2
- 86. http://www.columbia.edu/kermit/ckermit80.html#x3.10.3
- 87. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 88. http://www.columbia.edu/kermit/ckermit80.html#x4
- 89. http://www.columbia.edu/kermit/ckermit80.html#x5
- 90. http://www.columbia.edu/kermit/ckermit80.html#x6
- 91. http://www.columbia.edu/kermit/ckermit80.html#x6.1
- 92. http://www.columbia.edu/kermit/ckermit80.html#x6.2
- 93. http://www.columbia.edu/kermit/ckermit80.html#x6.3
- 94. http://www.columbia.edu/kermit/ckermit80.html#x6.4
- 95. http://www.columbia.edu/kermit/ckermit80.html#x6.5
- 96. http://www.columbia.edu/kermit/ckermit80.html#x6.6
- 97. http://www.columbia.edu/kermit/ckermit80.html#x7
- 98. http://www.columbia.edu/kermit/ckermit80.html#x8
- 99. http://www.columbia.edu/kermit/ckermit80.html#x8.1
- 100. http://www.columbia.edu/kermit/ckermit80.html#x8.2
- 101. http://www.columbia.edu/kermit/ckermit80.html#x8.3
- 102. http://www.columbia.edu/kermit/ckermit80.html#x8.4
- 103. http://www.columbia.edu/kermit/ckermit80.html#x8.5
- 104. http://www.columbia.edu/kermit/ckermit80.html#x8.6
- 105. http://www.columbia.edu/kermit/ckermit80.html#x8.7
- 106. http://www.columbia.edu/kermit/ckermit80.html#x8.8
- 107. http://www.columbia.edu/kermit/ckermit80.html#x8.9
- 108. http://www.columbia.edu/kermit/ckermit80.html#x8.10
- 109. http://www.columbia.edu/kermit/ckermit80.html#x8.11
- 110. http://www.columbia.edu/kermit/ckermit80.html#x8.12
- 111. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 112. http://www.columbia.edu/kermit/ckermit80.html#x8.14
- 113. http://www.columbia.edu/kermit/ckermit80.html#x9
- 114. http://www.columbia.edu/kermit/ckermit80.html#x9.1
- 115. http://www.columbia.edu/kermit/ckermit80.html#x9.2
- 116. http://www.columbia.edu/kermit/ckermit80.html#x9.3
- 117. http://www.columbia.edu/kermit/ckermit80.html#x9.4
- 118. http://www.columbia.edu/kermit/ckermit80.html#x9.5
- 119. http://www.columbia.edu/kermit/ckermit80.html#x9.6
- 120. http://www.columbia.edu/kermit/ckermit80.html#x9.7
- 121. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 122. http://www.columbia.edu/kermit/ckermit80.html#x9.9
- 123. http://www.columbia.edu/kermit/ckermit80.html#x9.10
- 124. http://www.columbia.edu/kermit/ckermit80.html#x9.11
- 125. http://www.columbia.edu/kermit/ckermit80.html#x10
- 126. http://www.columbia.edu/kermit/ckermit80.html#x11
- 127. http://www.columbia.edu/kermit/ckermit80.html#x12
- 128. http://www.columbia.edu/kermit/ckermit80.html#x13
- 129. http://www.columbia.edu/kermit/ckermit80.html#x14
- 130. http://www.columbia.edu/kermit/ckermit80.html#x15
- 131. http://www.columbia.edu/kermit/ckermit80.html#x16
- 132. http://www.columbia.edu/kermit/ckermit80.html#x17
- 133. http://www.columbia.edu/kermit/ckermit80.html#top
- 134. http://www.columbia.edu/kermit/ckermit.html
- 135. http://www.columbia.edu/kermit/index.html
- 136. http://www.columbia.edu/kermit/ckuins.html#x5
- 137. http://www.columbia.edu/kermit/ckuins.html
- 138. http://www.columbia.edu/kermit/ckermit80.html#x5
- 139. http://www.columbia.edu/kermit/ckermit80.html#x2.2
- 140. http://www.columbia.edu/kermit/ckermit80.html#contents
- 141. http://www.columbia.edu/kermit/ckermit80.html#x15
- 142. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 143. http://www.columbia.edu/kermit/ckermit80.html#ftpdates
- 144. http://www.columbia.edu/kermit/ckermit80.html#ftpcheck
- 145. http://www.columbia.edu/kermit/ckermit80.html#ftpnamelist
- 146. http://www.columbia.edu/kermit/ckermit80.html#srvrename
- 147. http://www.columbia.edu/kermit/ckermit80.html#ftpvdir
- 148. http://www.columbia.edu/kermit/ckermit80.html#setftptype
- 149. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 150. http://www.columbia.edu/kermit/ckermit80.html#x15
- 151. http://www.columbia.edu/kermit/ckermit80.html#x8.7
- 152. http://www.columbia.edu/kermit/ckermit80.html#x2.1
- 153. http://www.columbia.edu/kermit/ckermit80.html#x2.2
- 154. http://www.columbia.edu/kermit/ckermit80.html#x8.14
- 155. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 156. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 157. http://www.columbia.edu/kermit/ckututor.html
- 158. http://www.columbia.edu/kermit/ckuins.html
- 159. http://www.columbia.edu/kermit/skermit.html
- 160. http://www.columbia.edu/kermit/ckermit80.html#setlocus
- 161. http://www.columbia.edu/kermit/ckermit80.html#lcommands
- 162. http://www.columbia.edu/kermit/ckermit80.html#ftpuser
- 163. http://www.columbia.edu/kermit/ckermit80.html#showvar
- 164. http://www.columbia.edu/kermit/ckermit80.html#callerid
- 165. http://www.columbia.edu/kermit/ckermit80.html#x6.6
- 166. http://www.columbia.edu/kermit/ckermit80.html#x0
- 167. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 168. http://www.columbia.edu/kermit/ckermit80.html#top
- 169. http://www.columbia.edu/kermit/ckermit80.html#contents
- 170. http://www.columbia.edu/kermit/ckermit.html
- 171. http://www.columbia.edu/kermit/index.html
- 172. http://www.columbia.edu/kermit/ckermit80.html#x0
- 173. http://www.columbia.edu/kermit/ckermit80.html#top
- 174. http://www.columbia.edu/kermit/ckermit80.html#contents
- 175. http://www.columbia.edu/kermit/ckermit.html
- 176. http://www.columbia.edu/kermit/index.html
- 177. http://www.columbia.edu/kermit/k95.html
- 178. http://www.columbia.edu/kermit/sshclient.html
- 179. http://www.columbia.edu/kermit/skermit.html
- 180. http://www.columbia.edu/kermit/skermit.html
- 181. http://www.columbia.edu/kermit/sshclien.htm
- 182. http://www.columbia.edu/kermit/ckermit80.html#x3
- 183. ftp://ftp.isi.edu/in-notes/rfc1738.txt
- 184. http://www.columbia.edu/kermit/ckermit80.html#x2.2.2
- 185. http://www.columbia.edu/kermit/ckermit80.html#x2.2.1
- 186. ftp://ftp.isi.edu/in-notes/rfc2396.txt
- 187. ftp://ftp.isi.edu/in-notes/rfc2616.txt
- 188. http://www.columbia.edu/kermit/ckermit80.html#x2.2.3
- 189. ftp://ftp.isi.edu/in-notes/rfc2616.txt
- 190. http://www.columbia.edu/kermit/ckermit80.html#x8.13.7
- 191. http://www.columbia.edu/kermit/security.htm#x5.4
- 192. http://www.columbia.edu/kermit/security.htm#x15
- 193. http://www.columbia.edu/kermit/security.htm#x6.2
- 194. http://www.columbia.edu/kermit/security.html
- 195. http://www.columbia.edu/kermit/ckermit80.html#x16
- 196. http://www.columbia.edu/kermit/ckermit80.html#top
- 197. http://www.columbia.edu/kermit/ckermit80.html#contents
- 198. http://www.columbia.edu/kermit/ckermit.html
- 199. http://www.columbia.edu/kermit/index.html
- 200. http://www.columbia.edu/kermit/ckermit80.html#x3.1
- 201. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 202. http://www.columbia.edu/kermit/ckermit80.html#x3.3
- 203. http://www.columbia.edu/kermit/ckermit80.html#x3.4
- 204. http://www.columbia.edu/kermit/ckermit80.html#x3.5
- 205. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 206. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 207. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 208. http://www.columbia.edu/kermit/ckermit80.html#x3.9
- 209. http://www.columbia.edu/kermit/ckermit80.html#x3.10
- 210. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 211. http://www.columbia.edu/kermit/security.htm
- 212. http://www.columbia.edu/kermit/security.htm#servers
- 213. http://www.columbia.edu/kermit/ckcsets.html
- 214. http://www.columbia.edu/kermit/unicode.html
- 215. http://www.columbia.edu/kermit/ckermi70.htm#x1.5.4
- 216. http://www.columbia.edu/kermit/case10.html
- 217. http://www.columbia.edu/kermit/ckermit80.html#x4
- 218. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 219. http://www.columbia.edu/kermit/ftpscripts.html
- 220. http://www.columbia.edu/kermit/ckermit80.html#top
- 221. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 222. http://www.columbia.edu/kermit/ftpclient.html
- 223. http://www.columbia.edu/kermit/ftpscripts.html
- 224. http://www.columbia.edu/kermit/ckermit.html
- 225. http://www.columbia.edu/kermit/index.html
- 226. http://www.columbia.edu/kermit/ckermit80.html#x3.1.1
- 227. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3
- 228. http://www.columbia.edu/kermit/ckermit80.html#x3.1.4
- 229. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3
- 230. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3
- 231. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 232. http://www.columbia.edu/kermit/ckermit80.html#x3.5
- 233. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 234. http://www.columbia.edu/kermit/ftpscripts.html
- 235. http://www.columbia.edu/kermit/ckb2.htm
- 236. http://www.columbia.edu/kermit/ckermit80.html#ftpautolog
- 237. http://www.columbia.edu/kermit/ckermit80.html#ftpuser
- 238. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 239. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 240. http://www.columbia.edu/kermit/ckermit80.html#top
- 241. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 242. http://www.columbia.edu/kermit/ckermit.html
- 243. http://www.columbia.edu/kermit/index.html
- 244. http://www.columbia.edu/kermit/ibm_ie.html
- 245. http://www.columbia.edu/kermit/ckermit80.html#x3.10
- 246. http://www.columbia.edu/kermit/ckermit80.html#top
- 247. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 248. http://www.columbia.edu/kermit/ckermit.html
- 249. http://www.columbia.edu/kermit/index.html
- 250. http://www.columbia.edu/kermit/ck60manual.html
- 251. http://www.columbia.edu/kermit/ckermit70.html#x4.17
- 252. http://www.columbia.edu/kermit/ckermit70.html
- 253. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 254. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 255. http://www.columbia.edu/kermit/ckermit80.html#x3.1.4
- 256. http://www.columbia.edu/kermit/security.html
- 257. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 258. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 259. http://www.columbia.edu/kermit/ckermit80.html#x8.13.4
- 260. http://www.columbia.edu/kermit/ckermit80.html#permswitch
- 261. http://www.columbia.edu/kermit/ckermit80.html#ftpchmod
- 262. http://www.columbia.edu/kermit/ckermit80.html#x3.6.2
- 263. http://www.columbia.edu/kermit/ckermit80.html#x4
- 264. http://www.columbia.edu/kermit/ckermit80.html#top
- 265. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 266. http://www.columbia.edu/kermit/ckermit.html
- 267. http://www.columbia.edu/kermit/index.html
- 268. http://www.columbia.edu/kermit/ckermit80.html#x7
- 269. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 270. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 271. http://www.columbia.edu/kermit/ckb2.htm
- 272. http://www.columbia.edu/kermit/ckermit80.html#x3.10
- 273. http://www.columbia.edu/kermit/ckermit80.html#x3.10
- 274. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 275. http://www.columbia.edu/kermit/ckermit80.html#setftptype
- 276. http://www.columbia.edu/kermit/ckermit80.html#top
- 277. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 278. http://www.columbia.edu/kermit/ckermit.html
- 279. http://www.columbia.edu/kermit/index.html
- 280. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 281. http://www.columbia.edu/kermit/ckermit80.html#x3.5.1
- 282. http://www.columbia.edu/kermit/ckermit80.html#erroraction
- 283. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 284. http://www.columbia.edu/kermit/ckermit70.html#x4.7
- 285. http://www.columbia.edu/kermit/ckermit70.html#x1.6
- 286. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 287. http://www.columbia.edu/kermit/ckermi70.htm#x1.5.4
- 288. http://www.columbia.edu/kermit/ckermi70.htm
- 289. http://www.columbia.edu/kermit/ckermit80.html#x4
- 290. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 291. http://www.columbia.edu/kermit/ckermit80.html#x3.5.2
- 292. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 293. http://www.columbia.edu/kermit/ckermit80.html#erroraction
- 294. http://www.columbia.edu/kermit/ckermit80.html#x3.5.2
- 295. http://www.columbia.edu/kermit/ckermit80.html#erroraction
- 296. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames
- 297. http://www.columbia.edu/kermit/ckermit80.html#ftpperms
- 298. http://www.columbia.edu/kermit/ckermit80.html#ftpunique
- 299. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames
- 300. http://www.columbia.edu/kermit/ckermit80.html#note_utc
- 301. http://www.columbia.edu/kermit/ckermit80.html#note_date
- 302. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 303. http://www.boulder.nist.gov/timefreq/faq/faq.htm#10:
- 304. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 305. http://www.columbia.edu/kermit/ckermit80.html#top
- 306. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 307. http://www.columbia.edu/kermit/ckermit.html
- 308. http://www.columbia.edu/kermit/index.html
- 309. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 310. http://www.columbia.edu/kermit/ckermi70.htm#x4.3
- 311. http://www.columbia.edu/kermit/ckermit70.html
- 312. http://www.columbia.edu/kermit/ckermit80.html#x5
- 313. http://www.columbia.edu/kermit/ckermit80.html#x3.6.3
- 314. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames
- 315. http://www.columbia.edu/kermit/ckermi70.htm#x4.1
- 316. http://www.columbia.edu/kermit/ckermi70.htm#x4.2.2
- 317. http://www.columbia.edu/kermit/ckermi70.htm#x1.5.4
- 318. http://www.columbia.edu/kermit/ckermit80.html#x3.6.2
- 319. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 320. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 321. http://www.columbia.edu/kermit/ckermit80.html#srvrename
- 322. http://www.columbia.edu/kermit/ckermi70.htm#x4.1
- 323. http://www.columbia.edu/kermit/ckermi70.htm
- 324. http://www.columbia.edu/kermit/ckb2.htm
- 325. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames
- 326. http://www.columbia.edu/kermit/ckermit80.html#x3.5.3
- 327. http://www.proftpd.net/
- 328. http://www.columbia.edu/kermit/ckermit80.html#top
- 329. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 330. http://www.columbia.edu/kermit/ckermit.html
- 331. http://www.columbia.edu/kermit/index.html
- 332. http://www.columbia.edu/kermit/ckb2.htm
- 333. http://www.columbia.edu/kermit/ckcsets.html
- 334. http://www.columbia.edu/kermit/unicode.html
- 335. http://www.columbia.edu/kermit/ckcsets.html
- 336. http://www.columbia.edu/kermit/ckcsets.html
- 337. http://www.columbia.edu/kermit/ckermit80.html#x4
- 338. http://www.columbia.edu/kermit/utf8.html
- 339. http://www.columbia.edu/kermit/ckcsets.html
- 340. http://www.columbia.edu/kermit/ckermit80.html#x4
- 341. ftp://ftp.isi.edu/in-notes/rfc2640.txt
- 342. http://www.columbia.edu/kermit/ckermit80.html#top
- 343. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 344. http://www.columbia.edu/kermit/ckermit.html
- 345. http://www.columbia.edu/kermit/index.html
- 346. http://www.columbia.edu/kermit/ckermit80.html#top
- 347. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 348. http://www.columbia.edu/kermit/ckermit.html
- 349. http://www.columbia.edu/kermit/index.html
- 350. http://www.columbia.edu/kermit/ckermit80.html#top
- 351. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 352. http://www.columbia.edu/kermit/ckermit.html
- 353. http://www.columbia.edu/kermit/index.html
- 354. http://www.columbia.edu/kermit/ftpscripts.html
- 355. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 356. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 357. ftp://ftp.isi.edu/in-notes/rfc959.txt
- 358. http://www.columbia.edu/kermit/ckscripts.html
- 359. http://www.columbia.edu/kermit/ckermit80.html#top
- 360. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 361. http://www.columbia.edu/kermit/ftpscript.html
- 362. http://www.columbia.edu/kermit/ckermit.html
- 363. http://www.columbia.edu/kermit/index.html
- 364. http://www.columbia.edu/kermit/ckermit80.html#x3.11.1
- 365. http://www.columbia.edu/kermit/ckermit80.html#x3.11.2
- 366. http://www.columbia.edu/kermit/ckermit80.html#x3.11.3
- 367. http://www.columbia.edu/kermit/ckermit80.html#x3.11.4
- 368. http://www.columbia.edu/kermit/ckermit80.html#x3.11.5
- 369. http://www.columbia.edu/kermit/ckermit.html
- 370. http://www.columbia.edu/kermit/k95.html
- 371. http://www.columbia.edu/kermit/ckermit80.html#x3.11.5
- 372. ftp://ftp.isi.edu/in-notes/rfc959.txt
- 373. ftp://ftp.isi.edu/in-notes/rfc2389.txt
- 374. http://www.ietf.org/internet-drafts/draft-ietf-ftpext-mlst-16.txt
- 375. http://www.columbia.edu/kermit/ftpclient.html
- 376. http://www.columbia.edu/kermit/ckermit80.html#top
- 377. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 378. http://www.columbia.edu/kermit/ckermit.html
- 379. http://www.columbia.edu/kermit/index.html
- 380. http://www.columbia.edu/kermit/ckermit80.html#x3
- 381. http://www.columbia.edu/kermit/ckermit80.html#ucs2
- 382. http://www.columbia.edu/kermit/ckermit80.html#top
- 383. http://www.columbia.edu/kermit/ckermit80.html#contents
- 384. http://www.columbia.edu/kermit/ckermit.html
- 385. http://www.columbia.edu/kermit/index.html
- 386. http://www.columbia.edu/kermit/ckermit80.html#top
- 387. http://www.columbia.edu/kermit/ckermit80.html#contents
- 388. http://www.columbia.edu/kermit/ckermit.html
- 389. http://www.columbia.edu/kermit/index.html
- 390. http://www.columbia.edu/kermit/ckb2.htm
- 391. http://www.columbia.edu/kermit/ckermit80.html#top
- 392. http://www.columbia.edu/kermit/ckermit80.html#contents
- 393. http://www.columbia.edu/kermit/ckermit.html
- 394. http://www.columbia.edu/kermit/index.html
- 395. http://www.columbia.edu/kermit/ckermit80.html#x4
- 396. http://www.columbia.edu/kermit/ckermit80.html#x4
- 397. http://www.columbia.edu/kermit/ckermit80.html#x8.12
- 398. http://www.columbia.edu/kermit/ckermit80.html#x8.1
- 399. http://www.columbia.edu/kermit/ckermit80.html#x12
- 400. http://www.columbia.edu/kermit/ckermit80.html#x8.12
- 401. http://www.columbia.edu/kermit/ckermit80.html#top
- 402. http://www.columbia.edu/kermit/ckermit80.html#contents
- 403. http://www.columbia.edu/kermit/ckermit.html
- 404. http://www.columbia.edu/kermit/index.html
- 405. http://www.columbia.edu/kermit/ckermit80.html#x8.14
- 406. http://www.columbia.edu/kermit/ckermit80.html#top
- 407. http://www.columbia.edu/kermit/ckermit80.html#contents
- 408. http://www.columbia.edu/kermit/ckermit.html
- 409. http://www.columbia.edu/kermit/index.html
- 410. http://www.columbia.edu/kermit/ckermit80.html#x9
- 411. http://www.columbia.edu/kermit/ckermit80.html#top
- 412. http://www.columbia.edu/kermit/ckermit80.html#contents
- 413. http://www.columbia.edu/kermit/ckermit.html
- 414. http://www.columbia.edu/kermit/index.html
- 415. http://www.columbia.edu/kermit/ckermit80.html#x8.6
- 416. http://www.columbia.edu/kermit/ckermit80.html#top
- 417. http://www.columbia.edu/kermit/ckermit80.html#contents
- 418. http://www.columbia.edu/kermit/ckermit.html
- 419. http://www.columbia.edu/kermit/index.html
- 420. http://www.columbia.edu/kermit/ckermit80.html#top
- 421. http://www.columbia.edu/kermit/ckermit80.html#contents
- 422. http://www.columbia.edu/kermit/ckermit.html
- 423. http://www.columbia.edu/kermit/index.html
- 424. http://www.columbia.edu/kermit/ckermit80.html#top
- 425. http://www.columbia.edu/kermit/ckermit80.html#contents
- 426. http://www.columbia.edu/kermit/ckermit.html
- 427. http://www.columbia.edu/kermit/index.html
- 428. http://www.columbia.edu/kermit/ckermit80.html#fjoin
- 429. http://www.columbia.edu/kermit/ckermit80.html#fsplit
- 430. http://www.columbia.edu/kermit/ckermit80.html#x8.10
- 431. http://www.columbia.edu/kermit/ckermit80.html#top
- 432. http://www.columbia.edu/kermit/ckermit80.html#contents
- 433. http://www.columbia.edu/kermit/ckermit.html
- 434. http://www.columbia.edu/kermit/index.html
- 435. http://www.columbia.edu/kermit/ckermit80.html#x9
- 436. http://www.columbia.edu/kermit/ckermit80.html#x9
- 437. http://www.columbia.edu/kermit/ckermit80.html#x9
- 438. http://www.columbia.edu/kermit/ckermit80.html#x3
- 439. http://www.columbia.edu/kermit/ckermit80.html#x3
- 440. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 441. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 442. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 443. http://www.columbia.edu/kermit/ckermit80.html#x3
- 444. http://www.columbia.edu/kermit/ckermit80.html#x3
- 445. http://www.columbia.edu/kermit/ckermit80.html#x3
- 446. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 447. http://www.columbia.edu/kermit/ckermit80.html#x3
- 448. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 449. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 450. http://www.columbia.edu/kermit/ckermit80.html#x9
- 451. http://www.columbia.edu/kermit/ckermit80.html#x8.10
- 452. http://www.columbia.edu/kermit/ckermit80.html#x8.7.4
- 453. http://www.columbia.edu/kermit/ckermit80.html#top
- 454. http://www.columbia.edu/kermit/ckermit80.html#contents
- 455. http://www.columbia.edu/kermit/ckermit.html
- 456. http://www.columbia.edu/kermit/index.html
- 457. http://www.columbia.edu/kermit/ckermit80.html#top
- 458. http://www.columbia.edu/kermit/ckermit80.html#contents
- 459. http://www.columbia.edu/kermit/ckermit.html
- 460. http://www.columbia.edu/kermit/index.html
- 461. http://www.columbia.edu/kermit/ckermit80.html#top
- 462. http://www.columbia.edu/kermit/ckermit80.html#contents
- 463. http://www.columbia.edu/kermit/ckermit.html
- 464. http://www.columbia.edu/kermit/index.html
- 465. http://www.columbia.edu/kermit/ckermit80.html#x8.7
- 466. http://www.columbia.edu/kermit/ckermit80.html#top
- 467. http://www.columbia.edu/kermit/ckermit80.html#contents
- 468. http://www.columbia.edu/kermit/ckermit.html
- 469. http://www.columbia.edu/kermit/index.html
- 470. http://www.columbia.edu/kermit/ckermit80.html#scriptedit
- 471. http://www.columbia.edu/kermit/ckermit80.html#top
- 472. http://www.columbia.edu/kermit/ckermit80.html#contents
- 473. http://www.columbia.edu/kermit/ckermit.html
- 474. http://www.columbia.edu/kermit/index.html
- 475. http://www.columbia.edu/kermit/ckermit80.html#top
- 476. http://www.columbia.edu/kermit/ckermit80.html#contents
- 477. http://www.columbia.edu/kermit/ckermit.html
- 478. http://www.columbia.edu/kermit/index.html
- 479. ftp://ftp.isi.edu/in-notes/rfc2822.txt
- 480. ftp://ftp.isi.edu/in-notes/rfc2822.txt
- 481. ftp://ftp.isi.edu/in-notes/rfc2822.txt
- 482. ftp://ftp.isi.edu/in-notes/rfc2822.txt
- 483. http://www.columbia.edu/kermit/ckermit80.html#top
- 484. http://www.columbia.edu/kermit/ckermit80.html#contents
- 485. http://www.columbia.edu/kermit/ckermit.html
- 486. http://www.columbia.edu/kermit/index.html
- 487. http://www.columbia.edu/kermit/ckermit80.html#x8.1
- 488. http://www.columbia.edu/kermit/ckermit80.html#top
- 489. http://www.columbia.edu/kermit/ckermit80.html#contents
- 490. http://www.columbia.edu/kermit/ckermit.html
- 491. http://www.columbia.edu/kermit/index.html
- 492. http://www.columbia.edu/kermit/ckermit80.html#x8.2
- 493. http://www.columbia.edu/kermit/ckermit80.html#top
- 494. http://www.columbia.edu/kermit/ckermit80.html#contents
- 495. http://www.columbia.edu/kermit/ckermit.html
- 496. http://www.columbia.edu/kermit/index.html
- 497. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 498. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 499. http://www.columbia.edu/kermit/ckermit80.html#x8.2
- 500. http://www.columbia.edu/kermit/ckermit80.html#top
- 501. http://www.columbia.edu/kermit/ckermit80.html#contents
- 502. http://www.columbia.edu/kermit/ckermit.html
- 503. http://www.columbia.edu/kermit/index.html
- 504. http://www.columbia.edu/kermit/ckermit80.html#top
- 505. http://www.columbia.edu/kermit/ckermit80.html#contents
- 506. http://www.columbia.edu/kermit/ckermit.html
- 507. http://www.columbia.edu/kermit/index.html
- 508. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 509. http://www.columbia.edu/kermit/ckermit80.html#top
- 510. http://www.columbia.edu/kermit/ckermit80.html#contents
- 511. http://www.columbia.edu/kermit/ckermit.html
- 512. http://www.columbia.edu/kermit/index.html
- 513. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 514. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 515. http://www.columbia.edu/kermit/ckermit80.html#x9.6
- 516. http://www.columbia.edu/kermit/ckermit80.html#top
- 517. http://www.columbia.edu/kermit/ckermit80.html#contents
- 518. http://www.columbia.edu/kermit/ckermit.html
- 519. http://www.columbia.edu/kermit/index.html
- 520. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 521. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 522. http://www.columbia.edu/kermit/ckermit80.html#top
- 523. http://www.columbia.edu/kermit/ckermit80.html#contents
- 524. http://www.columbia.edu/kermit/ckermit.html
- 525. http://www.columbia.edu/kermit/index.html
- 526. http://www.columbia.edu/kermit/ckermit80.html#top
- 527. http://www.columbia.edu/kermit/ckermit80.html#contents
- 528. http://www.columbia.edu/kermit/ckermit.html
- 529. http://www.columbia.edu/kermit/index.html
- 530. http://www.columbia.edu/kermit/ckermit80.html#top
- 531. http://www.columbia.edu/kermit/ckermit80.html#contents
- 532. http://www.columbia.edu/kermit/ckermit.html
- 533. http://www.columbia.edu/kermit/index.html
- 534. mailto:thucdat@hotmail.com
- 535. http://www.columbia.edu/kermit/ckermit80.html#x9.9.2
- 536. http://www.columbia.edu/kermit/ckermit80.html#top
- 537. http://www.columbia.edu/kermit/ckermit80.html#contents
- 538. http://www.columbia.edu/kermit/ckermit.html
- 539. http://www.columbia.edu/kermit/index.html
- 540. http://www.columbia.edu/kermit/ckermit80.html#top
- 541. http://www.columbia.edu/kermit/ckermit80.html#contents
- 542. http://www.columbia.edu/kermit/ckermit.html
- 543. http://www.columbia.edu/kermit/index.html
- 544. http://www.columbia.edu/kermit/ckermit80.html#top
- 545. http://www.columbia.edu/kermit/ckermit80.html#contents
- 546. http://www.columbia.edu/kermit/ckermit.html
- 547. http://www.columbia.edu/kermit/index.html
- 548. http://www.columbia.edu/kermit/ckermit80.html#x9.2
- 549. http://www.columbia.edu/kermit/ckermit80.html#top
- 550. http://www.columbia.edu/kermit/ckermit80.html#contents
- 551. http://www.columbia.edu/kermit/ckermit.html
- 552. http://www.columbia.edu/kermit/index.html
- 553. http://www.columbia.edu/kermit/ckermit80.html#x4
- 554. http://www.columbia.edu/kermit/ckermit80.html#x4
- 555. http://www.columbia.edu/kermit/ckermit80.html#top
- 556. http://www.columbia.edu/kermit/ckermit80.html#contents
- 557. http://www.columbia.edu/kermit/ckermit.html
- 558. http://www.columbia.edu/kermit/index.html
- 559. http://www.columbia.edu/kermit/ckermit80.html#top
- 560. http://www.columbia.edu/kermit/ckermit80.html#contents
- 561. http://www.columbia.edu/kermit/ckermit.html
- 562. http://www.columbia.edu/kermit/index.html
- 563. http://www.columbia.edu/kermit/ckermit80.html#top
- 564. http://www.columbia.edu/kermit/ckermit80.html#contents
- 565. http://www.columbia.edu/kermit/ckermit.html
- 566. http://www.columbia.edu/kermit/index.html
- 567. http://www.columbia.edu/kermit/ckermit80.html#x4
- 568. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 569. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 570. http://www.columbia.edu/kermit/ckermit80.html#top
- 571. http://www.columbia.edu/kermit/ckermit80.html#contents
- 572. http://www.columbia.edu/kermit/ckermit.html
- 573. http://www.columbia.edu/kermit/index.html
- 574. ftp://ftp.isi.edu/in-notes/rfc2217.txt
- 575. http://www.columbia.edu/kermit/ckermit80.html#top
- 576. http://www.columbia.edu/kermit/ckermit80.html#contents
- 577. ftp://kermit.columbia.edu/kermit/sredird/
- 578. http://www.columbia.edu/kermit/ckermit.html
- 579. http://www.columbia.edu/kermit/index.html
- 580. http://www.columbia.edu/kermit/ckermi70.htm#x4.22
- 581. http://www.columbia.edu/kermit/ckermit80.html#top
- 582. http://www.columbia.edu/kermit/ckermit80.html#contents
- 583. http://www.columbia.edu/kermit/ckermit.html
- 584. http://www.columbia.edu/kermit/index.html
- 585. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3
- 586. http://www.columbia.edu/kermit/cuiksd.html
- 587. http://www.columbia.edu/kermit/ckermit80.html#top
- 588. http://www.columbia.edu/kermit/ckermit80.html#contents
- 589. http://www.columbia.edu/kermit/ckermit.html
- 590. http://www.columbia.edu/kermit/index.html
- 591. http://www.columbia.edu/kermit/ckermit80.html#top
- 592. http://www.columbia.edu/kermit/ckermit80.html#contents
- 593. http://www.columbia.edu/kermit/ckermit.html
- 594. http://www.columbia.edu/kermit/index.html
- 595. http://www.columbia.edu/kermit/index.html
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckermit90.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckermit90.txt
deleted file mode 100644
index adf6ee3..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckermit90.txt
+++ /dev/null
@@ -1,2152 +0,0 @@
-
- [1]The Columbia Crown The Kermit Project | Columbia University
- 612 West 115th Street, New York NY 10025 USA o [2]kermit@columbia.edu
- ...since 1981
- [3]Home [4]Kermit 95 [5]C-Kermit [6]Scripts [7]Current [8]New [9]FAQ
- [10]Support
-
-
- [11]CLICK HERE to read about some of these items.
-
- [12]Table of platforms [13]Book: Using C-Kermit [14]Download
- C-Kermit 9.0
-
-C-Kermit 9.0 Update Notes
-
- Note: C-Kermit 9.0.301 contains a correction that applies only to
- Solaris 10 and 11.
- C-Kermit 9.0.302 contains corrections that apply only to FreeBSD 8
- and 9.
- * [15]Large Files
- * [16]How to Test Large-File Transfer
- * [17]Arithmetic with Large Integers
- * [18]FORCE-3 Packet Protocol
- * [19]Variable Evaluation
-
- * [20]The RENAME Command You Always Wanted
- * [21]Other New Features
- * [22]Incompatibilities
- * [23]What's Not In C-Kermit 9.0
- * [24]And a Loose End
-
- * [25]Demonstration: Secure POP mail fetcher
- * [26]Demonstration: HP Switch Configuration Backup
- * [27]Demonstration: HP iLO Blade Configuration
- * [28]Demonstration: IBM/Rolm/Siemens CBX Management
- * [29]Demonstration: CSV and TSV Files
- * [30]Demonstration Scripts for Webmasters
-
- This is the third supplement to [31]Using C-Kermit, Second Edition. I
- apologize for the scattered nature of the information and I hope I can
- organize it and gather it all into one place for easy and definitive
- reference some day. It's a big job so it depends on the demand. For the
- time being the definitive reference and introduction is the book (which
- is now available also in a [32]Kindle Edition), plus the [33]C-Kermit
- 7.0 update, [34]C-Kermit 8.0 update, and now this one. Plus tons of
- other web pages on this site, sample script programs, and so on.
-
- In version 6.0, C-Kermit was a pretty powerful and flexible
- communication program with scripting capabilities. By version 9.0, I'd
- like to think of it more as a scripting language with built-in
- communications. You can get an idea of the kinds of programs you can
- write in Kermit language [35]here. You can develop programs quickly
- because it's an interactive program, not a compiler. The scripting
- language is the command language. Kind of like the Unix shell but
- "somewhat" less cryptic, including concepts not only from C but from
- PL/I, Snobol, LISP, Bliss, and Smalltalk. The language itself is built
- upon the command language of the much-loved [36]DECSYSTEM-20 from the
- 1970s and 80s, the Clipper Ship of the Text Era. (Text is not a bad
- word. Those of us who can touch-type and who are proficient in
- text-based computing environments like Unix shell or VMS DCL are likely
- to be orders of magnitude more productive than users of GUIs.)
-
- Thanks to (at least) Jeff Altman, William Bader, Ian Beckwith, Nelson
- Beebe, Gerry Belanger, Joop Boonen, Rob Brown, Christian Corti, Alexey
- Dokuchaev, John Dunlap, Peter Eichhorn, Carl Friedberg, Terry Kennedy,
- G�nter Knauf, Jason Lehr, Arthur Marsh, Lewis McCarthy, Gary Mills, Ed
- Ravin, Jonathan Reams, Mike Rechtman, Mark Sapiro, Steven Schweda
- (SMS), Kinjal Shah, Michael Sokolov, Andy Tanenbaum, Seth Theriault,
- Zach A. Thomas, Martin Vorl�nder, and Eric Weaver for assistance, and
- to Hewlett-Packard Company for support.
-
- - Frank da Cruz [37]fdc@columbia.edu, 30 June 2011
-
- P.S. It occurred to me just before the end of the day that maybe I
- should back up the Kermit website on DVD, just in case. Using
- [38]Kermit 95 on the desktop over an SSH connection to the Unix file
- system where the website resides, I made a fresh directory on the PC,
- CD'd to it, and on Unix cd'd to the Website directory, and told
- C-Kermit 9.0 to:
-
-C-Kermit> send /recursive /dotfiles /nobackup *
-
- and it re-created the website directory tree in the PC directory, text
- files correctly converted to Windows format and binary files correctly
- left as-is. The /dotfiles switch means to include files such as
- .htaccess whose names start with a dot (period), and the /nobackup
- switch means to skip backup files created by EMACs (such as
- index.html.~243~). And then I did the same with the FTP sites, about
- 8GB in all. Watching the file-transfer display was kind of like having
- 30 years of my life flash before my eyes in a few minutes. Then I
- copied the two directories to DVD (the FTP site had to be split over 2
- DVDs). The whole operation took under half an hour. The directory tree
- on the CD is directly usable in Windows, Unix, or any other operating
- system (unlike if I had transferred the files all in binary mode or all
- in text mode, or if I had made, say, a gzipped tar archive or a zip
- archive). I believe that, to this day, Kermit is the only software that
- can do this. If someday I have to upload from these DVDs to Unix, VMS,
- or any other operating system, it can be done exactly the same way,
- with any necessary conversions on text files done automatically, and
- binary files left intact, recursively through a whole very large
- directory tree.
-
-What's New in General
-
- Very briefly, the major items:
- * [39]Open Source license.
- * [40]64-bit file access and transfer and 64-bit integer arithmetic
- on most common platforms.
- * Support for recent releases of Linux, Mac OS X, *BSD, etc ([41]see
- table).
- * Support for newer OpenSSL releases up to and including 1.0.0d
- ([42]see table).
- * [43]Strengthened error checking for file transfer under extremely
- harsh conditions.
- * [44]Simplified semantics for variables used in scripts.
- * Super-handy [45]extensions to the RENAME command.
- * Other scripting improvements including support for reading and
- writing [46]CSV and TSV files.
- * [47]MIME character-set names are now recognized.
- * Improved logging and debugging (see demo [48]here).
- * Lots more described or listed below, and [49]here.
-
-Open Source License
-
- C-Kermit 9.0 has the [50]Revised 3-Clause BSD License, an open source
- license approved by OSI, the [51]Open Source Initiative.
-
-Large Files
-
- Kermit is, first and foremost, a file-transfer program. One might
- expect it to be able to transfer any kind of file, but that has been
- decreasingly the case as file sizes began to cross the 2 gigabyte
- threshold.
-
- The biggest change since C-Kermit 8.0.211 is support for large files on
- platforms that support them. A "large file" is one whose size is
- greater than 2^31-1 (2,147,483,647) bytes (2GB-1); that is, one whose
- size requires more than 31 bits to represent. Before now, Kermit was
- able to access such files only on 100% 64-bit platforms such as Digital
- Unix, later known as Tru64 Unix. In the new release, Kermit takes
- advantage of the X/Open Single UNIX Specification Version 2 (UNIX 98)
- Large File Support (LFS) specification, which allows 32-bit platforms
- to create, access, and manage files larger than 2GB.
-
- Accommodating large files required code changes in many modules,
- affecting not only file transfer, but also file management functions
- from directory listings to local file manipulation, plus the user
- interface itself to allow entry and display of large numbers. All this
- had to be done in a way that would not affect pure 32-bit builds on
- platforms that do not support large files. Large file support is
- summarized in the [52]Table of Platforms; entries in Yellow (32-bit
- builds that support 64-bit integers) and Green (64-bit builds) support
- large files.
-
- Note that VMS C-Kermit and Kermit 95 for Windows have always been able
- to transfer large files. However their user interface used 32-bit
- integers for statistics and the file transfer display. In C-Kermit 9.0
- Alpha.03, VMS C-Kermit on 64-bit platforms (Alpha and Itanium) should
- now give correct statistics and progress displays. (We'll see about
- Kermit 95 later.)
-
-How to Test Large-File Transfer
-
- Several methods are available for testing large-file transfers:
- * By transferring a real file that is more than 2147483648 bytes long
- (a file whose length requires more than 31 bits to express); or to
- be totally sure, that is longer than 4294967296 bytes (32 bits or
- more). Or to be double super sure, longer than 8589934592 (33
- bits).
- * If you don't have such a file or there is not sufficient disk space
- for such a file, you can create a special kind of file that takes
- up one block on the disk but appears to be 4.3GB long by compiling
- and running [53]THIS C PROGRAM on Linux, Solaris, HP-UX, or other
- Unix platform that supports large files. Kermit or FTP or any other
- file transfer program will transfer the result (BIGFILE) in such a
- way as to actually put 4.3GB (or other desired size; see source) on
- the wire.
- * You can use Kermit's CALIBRATE feature to transfer a large file
- that doesn't exist. At the receiver, use RECEIVE /CALIBRATE. At the
- sender, use SEND /CALIBRATE:length, e.g.:
-
- (At remote kermit...)
- $ kermit -Y
- C-Kermit> receive /calibrate
- (Return to local kermit...)
- Ctrl-\c
- C-Kermit> send /calibrate:4300000000
- This sends a simulated file 4.3GB in length, that does not exist on
- the sender and will not take up any disk space on the receiver.
- SEND /CALIBRATE: accepts big numbers only in Kermit versions that
- support them (this does not include Kermit 95 on Windows). This
- method tests only Kermit's ability to express and understand large
- file sizes, but does not test Kermit's file-system interface, since
- no files are involved.
-
-Arithmetic with Large Integers
-
- Because large file support requires the availability of a 64-bit signed
- integer data type, other aspects of C-Kermit were adapted to use it
- too, most notably Kermit's algebraic expression evaluator and its
- [54]S-Expression interpreter, on all platforms that support large files
- (those listed as 64 or 32/64 in the Word column of the [55]table). In
- fact, every Kermit command that parses a number in any field can now
- parse a large number on those platforms.
-
- S-Expressions can now be forced to operate with integers only, without
- floating-point conversion or having to explicitly truncate each result;
- as an example. see the revised [56]Easter date calculation script.
-
-FORCE-3 Packet Protocol
-
- The Kermit protocol has proven itself over the past 30 years to be
- robust in terms of surviving harsh transmission environments and
- delivering the data correctly and completely. In these times of
- Internet everywhere and error-correcting modems in the few places where
- the Internet isn't, few people even recall the kinds of difficult
- conditions that were common when the Kermit protocol was first
- developed: noisy telephone lines, serial interfaces that drop
- characters, lack of transparency to control or 8-bit characters,
- absence of flow control, "bare" modems without error correction.
-
- But the Internet is not everywhere, and not all modems are
- error-correcting. Perhaps the most difficult trial so far for Kermit or
- any other protocol is the [57]EM-APEX project, in which floats are
- dropped into the ocean from an aircraft into the path of a hurricane;
- these floats dive into the water measuring current, temperature, and
- salinity at different depths and then surface to phone home, sending
- the data to land stations using Kermit protocol over
- non-error-correcting 300bps [58]Iridium satellite modems, with high
- seas and winds battering the floats and heavy ([59]sometimes
- electrical) storms between the modem and the satellite.
-
- Because of the transmission speed and long distances involved, the
- transfers were very slow. The Kermit software in the floats is
- [60]Embedded Kermit, which did not implement sliding windows, which
- would have sped up the flow considerably. John Dunlap, engineer at the
- University of Washington's Applied Physics Laboratory, undertook the
- task of adding sliding windows to E-Kermit. For testing, he rigged up a
- [61]simulator in which Kermit transfers take place over a connection
- with different amounts of noise and delay. He found that occasionally,
- a transfer would appear to succeed, but the received file would be
- corrupt.
-
- According to the Kermit protocol definition, the first packet always
- has block-check type 1, a 6-bit checksum, which is the only block check
- type that all Kermit implementations are required to support; thus any
- Kermit partner can process this packet. This packet itself can
- negotiate a higher level of checking, such that subsequent packets have
- (say) block-check type 3, a 16-bit cyclic redundancy check (CRC)
- encoded as three printable 7-bit ASCII characters. The 16-bit CRC can
- catch all errors of certain kinds (single-bit, double-bit, bursts of 16
- bits or less), and more than 99.9984741210937% of all other possible
- errors.
-
- John's simulations revealed that file corruption could occur undetected
- when the initial packet was corrupted in such a way that a parameter or
- capability byte was changed and the checksum also changed to make the
- packet appear to be correct, thus allowing the transfer to proceed with
- the two Kermit partners out of sync as to packet encoding and
- interpretation (the chances of two such errors producing a seemingly
- valid packet are about 1 in 6000 when using the 6-bit checksum). For
- example, the compression technique might be misnegotiated and then the
- receiver might store incoming data without decompressing it.
-
- The solution is a new option, selected by:
-
- BLOCK-CHECK TYPE 5
-
- to require a type 3 block check (16-bit CRC) on every packet, including
- the initial ones, thus reducing the probability of a misnegotiation by
- many orders of magnitude. THIS PARAMETER CAN NOT BE NEGOTIATED. Each
- Kermit program must be given the "set block 5" command prior to
- transfer. That's because normally every Kermit program expects the
- first packet to have a 6-bit checksum, and if the first packet has a
- 3-byte, 16-bit CRC, the packet receiver will think it is corrupted.
-
- In practice, however, it is possible to code the packet receiver
- "cheat" by reading the packet data before verifying the block check.
- Thus when the receiver is C-Kermit 9.0 or later or E-Kermit 1.7 or
- later, it is only necessary to give the "set block 5" command to the
- file sender, and the receiver will check for a FORCE-3 first packet. If
- the receiver does not support this feature, however, the initial packet
- will be be rejected (after several retries) and the file transfer will
- not take place. There is no attempt to "back off" to normal behavior.
-
- CAPTION: Table 4. Kermit Protocol Packet Block Check Types
-
- Type Command Bytes Status Explanation
- 1 SET BLOCK 1 1 Required in all Kermit implementations. Negotiated.
- 6-bit checksum, suitable for good connections.
- 2 SET BLOCK 2 2 Optional, negotiated. 12-bit checksum. 64 times
- stronger than type 1.
- 3 SET BLOCK 3 3 Optional, negotiated. 16-bit CRC.
- BLANK-FREE-2 SET BLOCK 4 2 Optional, negotiated. 12-bit checksum, two
- nonblank bytes.
- FORCE-3 SET BLOCK 5 3 Optional, not negotiated. 16-bit CRC forced all
- packets.
-
- BLANK-FREE-2 is for environments where Kermit packets are treated as
- lines of text, and in which trailing blanks can be stripped; for
- example, when transferring files with an IBM mainframe through a 3270
- protocol converter.
- [62]E-Kermit 1.7
-
-Variable Evaluation
-
- Does the strange behavior of Kermit's \%x variables puzzle or annoy
- you?
-
- Kermit software development has been a collaborative project over the
- years, with contributions coming in from almost every country and every
- sector of the economy - academic, corporate, government. Thus not all
- versions, and not all features of a given version, are a product of
- systematic design.
-
- One example was the introduction of variables for text substitution,
- first in a version of MS-DOS Kermit that was sent in by someone
- somewhere (I could look it up, but no time...) Although the design of
- the notation for variable names (table below) is mine, the underlying
- code was contributed. In that code there was only one kind of variable,
- and if I recall correctly the variable name was a backslash followed by
- a single letter, for example \a, \b, etc. The contributed code
- evaluated these variables recursively, meaning if the definition of a
- variable contained variable references, then these were resolved when
- dereferencing the variable, and the process would continue as deep down
- as necessary to resolve the thing fully.
-
- This was sometimes handy, but it had one severe drawback: There was no
- way to use variables in a straightforward way to represent strings that
- contained literal backslashes; for example, DOS or Windows pathnames.
- This gave rise to all kinds of quoting rules and conventions (e.g.
- doubling backslashes or forcing single-level evaluation with
- \\fcontents()), and also to the introduction of other kinds of
- variables that were evaluated one level deep, rather than recursively.
-
- To accommodate coexistence of different kinds of variables as well as
- "escape sequences" for representing control and 8-bit characters, the
- syntax for variable names was extended to include three elements: the
- leading backslash, then a single character indicating the type of
- variable, and then the name of the variable in a format corresponding
- to the type designator, as shown in this somewhat simplified table:
-
- CAPTION: Table 1. Variable-name Syntax in Kermit
-
- Notation Meaning
- \000 - \255 8-bit character constant (decimal)
- \d000 - \d255 Alternative notation for 8-bit character (byte) constant
- (decimal)
- \o000 - \o377 8-bit character constant (octal)
- \x00 - \xff 8-bit character constant (hexadecimal)
- \%a - \%z Scalar variable, evaluated recursively.
- \%0 - \%9 Macro argument, scalar, evaluated recursively.
- \&a - \%& Array name
- \&a[x] Array reference, evaluated recursively (x is any constant or
- variable)
- \v(name) Built-in scalar variable, evaluated one level deep.
- \m(name) User-defined scalar variable, evaluated one level deep.
- \$(name) An environment variable, evaluated one level deep.
- \s(name[n:m]) Compact substring notation, evaluated one level deep.
- \fname(args...) Built-in function with zero or more arguments.
- \\ Literal backslash
- \N OUTPUT command only: NUL, ASCII 0
- \B OUTPUT command only: BREAK (250ms, for serial connections)
- \L OUTPUT command only: Long BREAK (1.5sec, ditto)
-
- Variable names in Kermit are case-independent. The simplifications in
- the table are that the notation for decimal and octal bytes can have
- from one to three digits, and can include braces to separate them from
- text digits, e.g. \7, \{123}, \o{50}. Hex bytes too, except they must
- always have exactly two hex digits, 0-9a-f. Array indices must be, or
- must evaluate to, numbers (floating point numbers are truncated).
- Associative arrays are also available (dynamic arrays with arbitrary
- text as subscript), but they are really just a variation on \m()
- variables (read about associative arrays [63]here). Also, there are
- some alternative notations for compact substring notation.
-
- We didn't want to have lots of "distinguished" characters, as the UNIX
- shell does; one is enough, clarity over brevity. Although the notation
- can be a bit cumbersome, we can use the \m(name) form to circumvent the
- overevaluation in most contexts. But macro arguments are always
- assigned to the \%0-9 variables, and thus always evaluated recursively,
- making it difficult and confusing to pass (e.g.) Windows pathnames as
- arguments to macros. The same is true for array elements, especially in
- contexts where they are used to return results from built-in functions
- (for example, \fsplit() used to return the elements of a
- [64]comma-separated value list if any of the values contained
- backslashes). An even worse scenario is when macro arguments are passed
- from one macro to another; for some graphic illustrations see
- [65]Taming the Wild Backslash - Part Deux from the [66]C-Kermit 7.0
- Update Notes.
-
- We can't just change how variables are evaluated because that would
- break existing scripts. But we can always add Yet Another SET Command:
-
- SET COMMAND VARIABLE-EVALUATION { RECURSIVE, SIMPLE }
-
- This applies only to \%a-z and \%0-9 variables and to \&a-z[] arrays
- (since all other kinds of variables are evaluated only one level deep).
- The default, of course, for backwards compatibility, is RECURSIVE.
- SIMPLE forces the evaluation of these variables to return their literal
- contents, without further evaluation:
-
- * An exception is made in the case of array subscripts, because
- changing how they are evaluated could break a lot of scripts, and
- anyway there should never be any harm in evaluating them
- recursively because their final value is always (or should be)
- numeric, not some string that might contain backslashes.
- * The VARIABLE-EVALUATION setting is on the command stack. Thus you
- can give this command in a macro, command file, or user-defined
- function without affecting the calling environment.
- * The new \frecurse() function forces recursive evaluation of its
- argument regardless of the VARIABLE-EVALUATION setting. The
- argument can be any string (or nothing at all); all the variables
- in the string, even \m() ones, are evaluated recursively:
-
-def \%a 1 \%b 3
-def \%b 2
-def xx easy as \%a
-show mac xx
-echo \frecurse(\m(xx))
-easy as 1 2 3
-echo \frecurse(it's as easy as \m(xx))
-it's as easy as easy as 1 2 3
-
- * The new \v(vareval) built-in variable contains the current setting
- (recursive or simple) at the current command-stack level.
-
- Here's a short script for illustration:
-
-define path c:\users\fdc\somefile.txt
-define test1 { # Normal recursive argument evaluation
- echo \%0: arg=\%1
-}
-define test2 { # Simple argument evaluation
- set var simple
- echo \%0: arg=\%1
-}
-test1 \m(path)
-test2 \m(path)
-exit
-
- And here's the result:
-
-?<ERROR:NO_SUCH_FUNCTION:\fdc\somefile.txt()>
-test2: arg=c:\users\fdc\somefile.txt
-
- The first line might seem surprising, but under the normal rules (see
- table above) \f indicates a function call, with the letters following
- the 'f' being the name of the function. But there is no function by
- that name... and if there were, you probably didn't intend to call it!
-
- SET COMMAND VARIABLE-EVALUATION SIMPLE has no effect on constants, only
- on variables. Note how \m(path) is defined. The DEFINE command assigns
- the literal value of its argument to the named variable (see Table 3
- below), thus in this case no special syntax is needed. But in other
- contexts, you must double the backslashes or use the \fliteral()
- function to use literal backslashes in data:
-
-test2 c:\\users\\fdc\\somefile.txt
-test2 \fliteral(c:\users\fdc\somefile.txt)
-
- C-Kermit 9.0 adds a new notation for \fliteral() which also has certain
- advantages over it: \q(string):
-
-test2 \q(c:\users\fdc\somefile.txt)
-
- Since \fliteral() is a function, its argument list (the text within
- parentheses) has special syntax of its own, in which commas and braces
- are treated specially and introduce another set of quoting problems.
- \q(string) doesn't have these problems. The only consideration is that
- parentheses must be balanced or else quoted (preceded by backslash), or
- represented as numeric character entities (left paren = \40, (right
- paren = \41).
-
- Or else hold the value in a simple variable as we did with \\m(path)
- above.
-
- SET COMMAND VARIABLE-EVALUATION SIMPLE is a big change and might have
- repercussions that didn't show up in the initial tests; a lot more
- testing is needed.
-
- On the topic of variables, let's summarize in one place the ways in
- which values can be explicitly assigned to variables. There is nothing
- new here except the table itself:
-
- CAPTION: Table 2. Variable Assignment in Kermit
-
- Command Shorthand Explanation
- DEFINE name value .name = value The literal value becomes the contents
- of the named variable; variables names in the value are copied without
- evaluation. This command is for defining macros that take parameters,
- as well as for defining simple variables, especially if the values
- contain backslashes.
- _DEFINE name value Like DEFINE but the name is evaluated before use.
- ASSIGN name value .name := value The value is evaluated and the result
- becomes the contents of the named variable.
- _ASSIGN name value Like ASSIGN but the name is evaluated before use.
- EVALUATE name expression .name ::= value The expression (in regular
- algebraic notation) is evaluated arithmetically and the result becomes
- the contents of the named variable. If the expression contains any
- variables they are evaluated first.
- _EVALUATE name expression Like EVALUATE but the name is evaluated
- before use.
- INCREMENT name expression Evaluates the variables in the expression,
- then evaluates the expression arithmetically, and then adds the value
- to the contents of the named variable, which must be a number or an
- algebraic expression. If the expression is empty, a value of 1 is used.
- _INCREMENT name expression Like INCREMENT but the name is evaluated
- before use.
- DECREMENT name expression Evaluates the variables in the expression,
- then evaluates the expression arithmetically, and then subtracts the
- value from the contents of the named variable, which must be a number
- or an algebraic expression. If the expression is empty, a value of 1 is
- used.
- _DECREMENT name expression Like DECREMENT but the name is evaluated
- before use.
- DECLARE name = list An array declaration can include an initializer
- list; items in the list are evaluated before assignment. This can be
- defeated by doubling any backslashes or enclosing individual arguments
- in \fliteral().
- DO name arguments name arguments When invoking a macro with a DO
- command (or an implied one), the arguments are evaluated, then assigned
- to \%1, \%2, etc, and the macro's name to \%0.
- (SETQ name value) Kermit also includes a mini-[67]LISP interpreter
-
- Variables are evaluated automatically in Kermit commands simply by
- referencing them, according to rules given in Table 1. The following
- functions can be used to change how a a particular variable is
- evaluated:
-
- CAPTION: Table 3. Kermit Functions for Evaluating Variables
-
- Function Argument Description
- \fcontents() \%x or \&x[y] Evaluates the variable or array element
- (which normally would be evaluated recursively) one level deep.
- \fdefinition() name If the argument is a \%x variable or an array
- element, it is evaluated to get the name; otherwise the argument is the
- name. Its definition is returned with no recursion.
- \m() name Equivalent to \fdefinition().
- \frecurse() \m(name) Forces recursive evaluation of a macro definition
- (a.k.a. long variable name). NOTE: \frecurse() can operate on any kind
- of variable as well as on any string containing any mixture of
- variables.
-
-C-Kermit's RENAME Command
-
- C-Kermit's RENAME command, which is used for changing the names of
- local files or for moving files locally, has two basic forms:
-
- RENAME [ optional-switches ] oldfilename newfilename
- This form lets you change the name of a single file from
- oldfilename to newfilename. Example:
- rename thismonth.log lastmonth.log
-
- RENAME [ optional-switches ] filespec directoryname
- This form lets you move (without renaming) one or more files
- (all the files that match the filespec, which may contain
- wildcard characters such as "*") to the given directory.
- Example:
- rename *.txt ~/textfiles/
-
- Traditionally, the optional switches have been:
-
- RENAME /LIST oldname newname
- Display the old and new name for each file while renaming.
- Synonyms: /LOG, /VERBOSE. Example:
- rename /list *.txt ~/textfiles/
-
- RENAME /NOLIST oldname newname
- Don't display the old and new name for each file while renaming.
- This is the default behavior. Synonyms: /NOLOG, /QUIET. Example:
- rename /nolist *.txt ~/textfiles/
-
- Reminder: Every switch starts with a slash (/) and must be preceded by
- a space.
-
-New RENAME Features for C-Kermit 9.0
-
- A series of new options (switches) have been added to let you change
- the names of multiple files at once by case conversion, string
- substitution, or character-set conversion, and optionally also move
- them to a different directory:
-
- /LOWER: Convert the filename to lowercase
- /UPPER: Convert the filename to uppercase
- /CONVERT: Change the filename's character encoding
- /REPLACE: Do string substitutions on the filename
-
- If the source-file specification includes a path or directory, any
- changes are applied to the filenames only, not to the directory or path
- specification.
-
- Since name changes, when applied to many files at once, can have
- consequences that are not easily undone, there are also some new
- controls, safeguards, and conveniences:
-
- RENAME /SIMULATE
- This switch tells Kermit to show you what the RENAME command
- would do without actually doing it. /SIMULATE implies /LIST.
-
- RENAME /COLLISION:{FAIL,SKIP,OVERWRITE}
- This switch governs Kermit's behavior when renaming multiple
- files, and any of the names would collide with the name of a
- file that already exists. The default, for compatibility with
- earlier releases of C-Kermit, is OVERWRITE, i.e. write over the
- existing file. The other two protect existing files. SKIP means
- to skip (not rename) the file that would cause the collision,
- and proceed to the next file, if any. FAIL means that no files
- will be renamed if there would be any collisions; for this
- Kermit makes two passes, checking each new name it constructs
- for existence before starting the second pass (however, there is
- no guarantee that in the second pass, it won't create the same
- new name for more than one file; in that case, it will stop
- before executing the second rename). Example:
- rename /simulate /collision:proceed * ~/tmp/
-
- Reminder: In switches such as /COLLISION that take arguments
- (operands), the switch name and its argument(s) are separated by a
- colon (:) with no intervening spaces. Also remember that Kermit
- keywords can always be abbreviated by leaving off characters from the
- right, as long as the result is still unique in its context. Thus "ren
- /col:f" would be equivalent to "rename /collision:fail".
-
- You can change the following preferences for the RENAME command with
- the new SET RENAME command:
-
- SET RENAME LIST { ON, OFF }
- Tells the RENAME command whether to list its actions if you
- don't include a /LIST or /NOLIST or equivalent switch.
-
- SET RENAME COLLISION { FAIL, OVERWRITE, SKIP }
- Tells the RENAME command how to handle filename collisions in
- the absence of a /COLLISION switch. That is, it replaces the
- default action of OVERWRITE with action of your choosing, which
- is then used in any RENAME command that does not include an
- explicit /COLLISION switch.
-
- SHOW RENAME
- Displays the current SET RENAME settings.
-
-Changing the Case of Filenames
-
- RENAME /UPPER:{ALL,LOWER} filespec [ directory ]
- RENAME /LOWER:{ALL,UPPER} filespec [ directory ]
- These switches let you change the alphabetic case of letters in
- all the files whose names match the filespec. If a directory
- name is given after the filespec, then the files are also moved
- to the given directory.
-
- By default, all files that match the given filespec have their names
- changed (if necessary). This is what the ALL argument means, e.g.:
-
- RENAME /LOWER:ALL *
- RENAME /LOWER *
-
- You can use either form: RENAME /LOWER is equivalent to RENAME
- /LOWER:ALL. The other argument (/LOWER:UPPER or /UPPER:LOWER) means to
- leave mixed-case filenames alone, and rename only those files whose
- names contain letters of only the given case. Examples:
-
- RENAME /UPPER:ALL foo.bar
- Changes the filename to FOO.BAR.
-
- RENAME /UPPER foo.bar
- Same as "rename /upper:all foo.bar".
-
- RENAME /UPPER foo.bar ~/old/
- Renames foo.bar to FOO.BAR and moves it to the user's old
- directory (Unix).
-
- RENAME /LOWER *
- Changes the names of all files to have only lowercase letters.
-
- RENAME /LOWER:UPPER *
- Changes the names of only those files whose names contain no
- lowercase letters to have only lowercase letters. For example,
- FOO.BAR would be changed, Foo.Bar would not be changed. foo.bar
- would not be changed either because it's already all lowercase.
-
- RENAME /LOWER:UPPER * ~/new/
- Same as the previous example, but also moves each file to the
- user's new directory (whether it was renamed or not).
-
- Case conversion works reliably for ASCII characters only. Kermit uses
- the C library for this, which on any given platform might or might not
- handle non-ASCII letters, and if it does, then how it works would
- normally depend on your locale definitions (the LC_CTYPE and/or LANG
- environment variable in Unix). When non-ASCII letters are not handled
- by the C library, the RENAME command does change their case. For
- example, Olga_Ta��n.txt might become OLGA_TA��N.TXT.
-
-String Replacement in Filenames
-
- The RENAME command also lets you change filenames by string
- substitution.
-
- RENAME /FIXSPACES[:String] filespec [ directory ]
- Replaces all spaces in each matching filename by the given
- string, if any, or if none is given, by underscore. Examples:
-
- RENAME /FIX *
- RENAME /FIXSPACES:_ *
- RENAME /FIXSPACES:"" *
- RENAME /FIXSPACES:<040> *
-
- The first two are equivalent, replacing each space with
- underscore; a file called "My Favorite Photo.jpg" becomes
- "My_Favorite_Photo.jpg". The third example removes all spaces
- ("MyFavoritePhoto.jpg"). The fourth replaces each space with the
- string "<040>" ("My<040>Favorite<040>Photo.jpg").
-
- RENAME /REPLACE:{{String1}{String2}} filespec [ directory ]
- Renames each matching file by changing occurrences of String1 in
- its name to String2. If a directory specification is included,
- the file is also moved to the given directory (even if the name
- was not changed). Note that in this case, the curly braces are
- part of the command. Example:
-
- RENAME /REPLACE:{{.jpeg}{.jpg}} *
-
- changes all *.jpeg files to *.jpg.
-
- By default, RENAME /REPLACE changes all occurrences of String1 in each
- filename to String2 so, for example, if you had a file called
- abcjpegxyz.jpeg, the command just shown would change its name to
- abcjpgxyz.jpg.
-
- For greater control and flexibility, the /REPLACE: switch argument can
- take several distinct forms:
-
- RENAME /REPLACE:String1 filespec [ directory ]
- This means to remove all occurrences of String1 from the given
- filenames name. It is equivalent to /REPLACE:{{String1}{}}. A
- handy use for this option is to remove spaces from filenames.
-
- RENAME /REPLACE:{{String1}{String2}} filespec [ directory ]
- As already noted, this replaces every occurrence of String1 with
- String2 in each filename. Alphabetic case in string matching is
- done according to the current SET CASE setting.
-
- RENAME /REPLACE:{{ }{_}} filespec [ directory ]
- This replaces all spaces in the given filenames with underscore,
- equivalent to RENAME /FIXSPACES.
-
- RENAME /REPLACE:{{String1}{String2}{Options}} filespec [ directory ]
- Options can be included that add more control to the process.
- The option string is a sequence of characters; each character in
- the string is an option. The choices are:
-
- A String matching is to be case-sensitive, regardless of SET CASE.
- a String matching is to be case-independent, regardless of SET CASE.
- ^ String replacement will occur only at the beginning of the filename.
- $ String replacement will occur only at the end of the filename.
- 1 Only the first occurrence of the string will be replaced.
- 2 Only the second occurrence of the string will be replaced.
- 3 4 5 6 7 8 ...
- 9 Only the ninth occurrence of the string will be replaced.
- - (hyphen, minus sign) Before a digit: occurrences will be counted from
- the right.
- ~ (tilde) Before digit or minus sign: all occurrences but the given one
- will be replaced.
-
- The tilde modifier works only with single-byte character sets such as
- ASCII, CP437, ISO 8859-1, etc, but not with multibyte character sets
- such as UCS2, UTF8, or any of the Japanese Kanji sets.
-
- Here are some examples showing how to use the /REPLACE options:
-
- RENAME /REPLACE:{{foo}{bar}{^}} *
- For all files whose names start with "foo", replaces the "foo"
- at the beginning with "bar".
-
- RENAME /REPLACE:{{}{New-}{^}} *
- Prepends "New-" to the name of each file.
-
- RENAME /REPLACE:{{.jpeg}{.jpg}{$}} *
- Replaces ".jpeg" at the end of each filename with ".jpg".
-
- RENAME /REPLACE:{{}{-Old}{$}} *
- Appends "-Old" to the name of each file.
-
- RENAME /REPLACE:{{foo}{bar}{a}} *
- Replaces "foo", "FOO", "Foo", "fOO", etc, with "bar" in each
- filename.
-
- RENAME /REPLACE:{{foo}{bar}{A}} *
- Replaces only (lowercase) "foo" in filenames with "bar".
-
- RENAME /REPLACE:{{a}{XX}} *
- Changes every "a" to "XX". For example a file called "a.a.a.a"
- would become "XX.XX.XX.XX".
-
- RENAME /REPLACE:{{a}{X}{2}}
- Changes only the second "a" to "X". For example a file called
- "a.a.a.a" would become "a.X.a.a".
-
- RENAME /REPLACE:{{a}{X}{-1}}
- Changes only the final "a" in the filename (it doesn't have to
- be at the end) to "X". For example a file called "a.b.a.c.a.d"
- would become "a.b.a.c.X.d".
-
- RENAME /REPLACE:{{foo}{NOTFOO}{-2}}
- Changes the second-to-last "foo" (if any) in the filename to
- "NOTFOO".
-
- RENAME /REPLACE:{{foo}{}{-2}}
- Deletes the second-to-last "foo" (if any) from the filename.
-
- RENAME /REPLACE:{{.}{_}{~1}}
- Changes all but the first period to an underscore; for example,
- "a.b.c.d.e" would become "a.b_c_d_e".
-
- RENAME /REPLACE:{{.}{_}{~-1}}
- Changes all but the final period to an underscore; for example,
- "a.b.c.d.e" would become "a_b_c_d.e".
-
- In the Options field, digits (and their modifiers), ^, and $ are
- mutually exclusive. If you include more than one of these in the option
- string, only the last one is used. Similarly for 'a' and 'A':
-
- RENAME /REPLACE:{{foo}{bar}{Aa2$^}} *
- This replaces "foo" with "bar" no matter what combination of
- upper and lower case letters are used in "foo" ('a' overrides
- 'A' in the option string), but only if "foo" is at the beginning
- of the filename ('^' overrides '$' and '2').
-
- If you give an /UPPER or /LOWER switch and a /REPLACE switch in the
- same RENAME command, the /REPLACE action occurs first, then the case
- conversion:
-
- RENAME /REPLACE:{{foo}{bar}} /UPPER * /tmp
- For each file: changes all occurrences of "foo" in the name to
- "bar", then converts the result to uppercase, and then moves the
- file to the /tmp directory. So (for example) "foot.txt" would
- become "/tmp/BART.TXT".
-
-Changing the Character Encoding of Filenames
-
- As you know, text is represented on the computer as a series of
- numbers, with a given number corresponding to a given character
- according to some convention or standard. Filenames are represented the
- same way. The trouble is, different computers, or even different
- applications on the same computer, might use different standards or
- conventions ("character sets") for representing the same characters.
- Usually ASCII is safe, but anything beyond that -- non-ASCII characters
- such as accented or non-Roman letters -- is likely to vary. Sometimes
- you have text that's in the "wrong" character set and you need to
- convert it to something you can can use. Kermit has always been able to
- handle this as part of file transfer and terminal emulation, as well as
- being able to convert text files locally with its TRANSLATE command.
- Now there's a way to convert filenames too, for example after copying
- files from a CD that uses a different encoding:
-
- RENAME /CONVERT:charset1:charset2 filespec [ directory ]
- Converts filenames from the first character set to the second
- one. The two character sets can be chosen from the SET FILE
- CHARACTER-SET list; for complete details see [68]this page. For
- example suppose you have a file called "Olga_Ta��n.txt" on a
- computer where ISO 8859-1 Latin Alphabet 1 is used, and you have
- transported it (e.g. on CDROM) to another computer where the
- text encoding is UTF8. Maybe you also have a lot of other files
- with similar names in the same directory. You can convert the
- filenames to UTF8 like this:
-
- RENAME /CONVERT:latin1:utf8 *
-
- /CONVERT can not be combined with /UPPER, /LOWER, or /REPLACE.
-
- You should NOT use UCS2 for filenames since this encoding is not
- compatible with C strings used in Unix and elsewhere.
-
- RENAME /CONVERT affects only the filename, not the file's contents. You
- can use the TRANSLATE command to convert the encoding of the contents
- of a text file.
-
-Other New Features
-
- See the [69]C-Kermit Daily Builds page for details. Very briefly:
-
- * Perhaps most important, modernized makefile targets for the major
- Unix platforms: Linux, Mac OS X, AIX, Solaris, etc. These are
- somewhat automated; not autoconf exactly, but they cut down
- significantly on redundant targets. For example, one single "linux"
- target works on many (hopefully all) different Linux
- configurations, where before different targets were required for
- different combinations of (e.g.) curses / ncurses / no curses;
- 32-bit / 64-bit; different feature sets and library locations.
- (Separate targets are still required for Kerberos and/or SSL
- builds, but they are "subroutinized".)
- * Bigger buffers, more storage for commands, macros, scripts,
- strings, and filename expansion in 64-bit versions and in 32-bit
- versions that support large files.
- * User-settable FTP timeout, works on both the data and control
- connection.
- * FTP access to ports higher than 16383.
- * Built-in FTP client for VMS. This is the [70]same FTP client Unix
- C-Kermit has had since version 8.0, minimally adapted to VMS by
- SMS, supporting binary and Stream_LF file transfer only (in other
- words, nothing to handle RMS files), but otherwise fully functional
- (and scriptable) and theoretically capable of making connections
- secured by SSL (at least it compiles and links OK with SSL - HP SSL
- 1.3 in this case).
- * Large file support in VMS, also by SMS. Alpha and Itanium only (not
- VAX). VMS C-Kermit was already able to transfer large files, but
- the file-transfer display (numbers and progress bar) and statistics
- were wrong because they used ints. In the present Alpha test
- release, this is an optional feature requested by including the "f"
- option in P1.
- * New PUTENV command that allows Kermit to pass environment variables
- to subprocesses (Unix only, "help putenv").
- * New TOUCH command, many file selection options ("help touch").
- * New DIRECTORY command options and switches (/TOP, /COUNT;
- HDIRECTORY, WDIRECTORY...). To see the ten biggest files in the
- current directory: "dir /top:10 /sort:size /reverse *" or
- equivalently, "hdir /top:10 *". WDIR lists files in reverse
- chronological order, shorthand for "dir /sort:date /reverse".
- * New command FSEEK /FIND:string-or-pattern, seeks to the first line
- in an FOPEN'd file that contains the given string or matches the
- given pattern. Example: Suppose you have a file of lines like this:
-
- quantity description...
- in which the first "word" is a number, followed by a description
- (for example, the name of an item). Here is how to use FSEEK to
- quickly get the total quantity of any given item, which is passed
- as a parameter (either a literal string or a pattern) on the
- command line:
-
-#!/usr/local/bin/kermit +
-if not def \%1 exit 1 Usage: \fbasename(\%0) string-or-pattern
-
-.filename = /usr/local/data/items.log # Substitute the actual filename
-set case off # Searches are case-independent
-fopen /read \%c \m(filename) # Open the file
-if fail exit 1 "\m(filename): \v(errstring)" # Fail: exit with error message
-.total = 0 # OK: Initialize the total
-echo Searching "\%1"...
-
-while true {
- fseek /line /relative /find:\%1 \%c 0 # Get next line that has target
- if fail break # Failure indicates EOF
- fread /line \%c line # Read it
- if fail break # (shouldn't happen)
- increment total \fword(\m(line),1) # Increment the total
-}
-fclose \%c # Close the file
-echo Total for "\%1" : \m(total) # Print the result
-exit 0
-
- The syntax of the FSEEK command in this example indicates that each
- search should start relative to the current file line. Since Kermit
- is an interpretive language, FSEEK is a lot faster than FREAD'ing
- each line and checking it for the target, especially for big files.
- An especially handy use for FSEEK is for use with potentially huge
- sequentially timestamped logs, to seek directly to the date-time
- where you want to start processing. Some other improvements for the
- FOPEN/FREAD/FWRITE/FCLOSE family of commands are included also
- (performance, bug fixes, convenience features), listed in the
- [71]change log. (Prior to 9.0.299 Alpha.02, the FSEEK /FIND:
- command always started from the top.)
- * MIME synonyms for character-set names: A new equivalence between
- MIME names and Kermit names for character sets, with a new table
- showing the supported sets [72]HERE (this feature is also
- illustrated in the [73]Weblog script).
- * Unix C-Kermit SET TERMINAL TYPE now passes its arguments to
- subprocesses as an environment variable.
- * SET SESSION-LOG TEXT now strips out ANSI escape sequences from the
- session log.
- * For interacting with POP servers over clear-text or SSL-secured
- connections:
- + New SSL and TLS "raw" connections (no Telnet protocol).
- + New INPUT command options for reading and capturing (perhaps
- while scanning) continuous incoming text, such as INPUT
- /NOWRAP (explained [74]HERE).
- + New \femailaddress() command to extract the e-mail address
- from an Internet mail message To: or From: line, used in
- fetching mail from POP servers.
- + Improved date parsing commands and functions for parsing the
- different date formats that can appear in e-mail.
- + Production scripts for fetching mail from a secure POP server,
- available [75]HERE.
- * Various features added to make Kermit more useful for writing CGI
- scripts such as INPUT /COUNT:n to INPUT exactly n characters
- (useful for reading form data).
- * New \fpictureinfo() function for getting orientation and dimensions
- of JPG and GIF images, described [76]HERE.
- * New \fgetpidinfo() function for testing whether a given process
- exists.
- * \fkwdvalue() function fixed to allow multiword values.
- * New function \fcount(s1,s2) to tell the number of occurrences of s1
- in s2.
- * New \flopx() function returns rightmost field from string (such as
- a file's extension).
- * New function \ffunction(s1) to tell whether a built-in s1 function
- exists.
- * New \fsqueeze(s1) function removes leading and trailing whitespace
- from string s1, changes tabs to spaces, squeezing each run of
- repeated whitespace characters to a single space.
- * Compact substring notation: \s(somestring[12:18]) is the same as
- \fsubstring(\m(somestring),12,18), i.e. the substring starting at
- position 12, 18 characters long. \s(somestring[12_18]) means
- characters 12 through 18 of the string (7 characters). Also,
- \s(somestring[17.]) returns character number 17 of somestring.
- * The string indexing functions now accept an optional trailing
- argument specifying the occurrence number of the target string.
- Likewise, \fword() can fetch words from the right as well as the
- left.
- * The COPY command in Unix C-Kermit has a new /PRESERVE switch,
- equivalent to Unix "cp -p".
- * ASKQ /ECHO:c can be used to make the characters the user types echo
- as the character c, e.g. asterisk when typing a password.
- * IF LINK filename to test if the filename is a symlink.
- * Ctrl-K, when typed at the command parser, replaces itself with most
- recently entered file specification.
- * In Unix, the ability to log a terminal session to a serial port,
- for use with speaking devices or serial printers; described
- [77]HERE. Also for the same purpose, SET SESSION-LOG
- NULL-PADDED-LINES for a speech synthesizer than needed this.
- * Adaptation to OpenSSL 0.9.8 and 1.0.0.
- * Lifted the restriction on having a remote Kermit program send
- REMOTE commands to the local. A very big ex-client needed to be
- able to do this (branches would connect to headquarters and upload
- files; HQ would then download patches, a REMOTE HOST command was
- necessary to allow the remote headquarters machines to install the
- patches on the local client; of course the client first has to
- ENABLE HOST because this is a risky scenario). The reason for the
- restriction was that the server, upon receiving any REMOTE command
- would send the results (output) back to the client as a file
- transfer with "destination screen", but of course the remote has no
- screen.
- * Added XMESSAGE, which is to [78]MESSAGE as XECHO is ECHO: it
- outputs a string with no line terminator DEBUG MESSAGE is ON.
- * Fixed \frecurse() to not dump core when invoked with no arguments.
- * Improved text for HELP FUNCTION SPLIT and HELP FUNCTION WORD.
- * Patches for Debian 6.0 "Squeeze" from Ian Beckwith.
- * \fcontents(\&a[3]) got an error if the array was declared but its
- dimension was less than 3. Now it simply returns and empty string.
- * \fsplit(), when parsing lines from CSV and TSV files, was treating
- backslash in the data the same way it treats backslash in Kermit
- commands. This was fixed to treat backslash like any other
- character.
- * Builds for Solaris 9 and later now use streams ptys rather then the
- old BSD-style ptys. Thanks to Gary Mills for this one, who noticed
- that he couldn't have more than 48 C-Kermit SSH sessions going at
- once and figured out why.
- * As noted [79]below DES encryption is being retired from many
- platforms and libraries that once used it. I changed the Solaris
- and Linux OpenSSL builds to account for this by testing for it. I
- probably should also add a OMITDES option to omit DES even if it is
- installed, but "KFLAGS=-UCK_DES" seems to do the job for now.
- * I changed the Linux build to test for the OpenSSL version (like the
- Solaris version already did), rather than assuming OpenSSL 0.9.7.
- * A couple minor changes for Tru64 Unix 5.1B from Steven Schweda but
- we still have some trouble on that platform. As a workaround "make
- osf1" can be used there.
- * Unix makefile and man page are now included in the Zip
- distribution.
- * \fjoin(), which is the inverse function of fsplit() now accepts CSV
- and TSV as a second argument, to transform an array into a
- comma-separated or tab-separated value list, as described [80]HERE.
- * Even in 2010, Unix distributions continue to change their UUCP
- lockfile conventions. C-Kermit 9.0 contains support from Joop
- Boonen for OpenSuSE >= 11.3 and recent Debian, which no longer have
- baudboy.h, which first appeared in Red Hat 7.2 in 2003.
- * From Lewis McCarthy:
-
- Based on code inspection, C-Kermit appears to have an SSL-related
- security vulnerability analogous to that identified as CVE-2009-3767
- (see e.g.
- [81]http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3767).
-
- I'm attaching a patch for this issue relative to the revision of
- ck_ssl.c obtained from a copy of
- [82]http://www.columbia.edu/kermit/ftp/test/tar/x.zip downloaded on
- 2010/07/30, which I believe is the latest.
- When this flaw was first widely publicized at last year's Black Hat
- conference, it was claimed that some public certificate authorities
- had indeed issued certificates that could be used to exploit this
- class of vulnerability. As far as I know they have not revealed
- specifically which public CA(s) had been found issuing such
- certificates. Some references:
- + [83]http://www.mseclab.com/?p=180
- + [84]http://www.theregister.co.uk/2009/07/30/universal_ssl_cert
- ificate/
-
- * Peter Eichhorn reported that "RENAME ../x ." didn't work; fixed
- now.
- * If only one file is FOPEN'd, FCLOSE given with no arguments would
- close it; this was a "convenience feature" that turned out to be
- dangerous. For safety FCLOSE has to require a specific channel
- number or the word ALL.
- * Added \fstrcmp(s1,s2,case,start,length), which has the advantage
- over IF EQU,LGT,LLT that case sensitivity can be specified as a
- function arg, and also substrings can be specified.
- * New built-in functions:
-
- \fcvtcsets(string,cs1,cs2)
- Function to convert a string from one character set to
- another.
-
- \fdecodehex(string[,prefix])
- Function to decode a string containing hex escapes.
-
- \fstringtype(string)
- Function to tell whether a string is 7-bit, 8-bit, or
- UTF-8.
-
- For the motivation for these features and an application that uses
- them to analyze web logs, see the Weblog script below.
- *
-
- Lazy IF Conditions: Now you can do this:
- define foo some number
- if foo command
-
- instead of this:
- define foo some number
- if \m(foo) command
-
- Of course the old way still works too. But watch out because if the
- variable name is the same as a symbolic IF condition (for example
- COUNT), it won't do what you expected. (IF COUNT was used for loop
- control in early versions of MS-DOS Kermit, before it got real FOR
- and WHILE loops; it was added to C-Kermit for compatibility, and it
- can't be removed because that could break existing scripts).
- * Escape sequences are now stripped from text-mode session logs not
- only in CONNECT sessions but also in whatever is logged by the
- INPUT command; described in the [85]next section.
- * New commands for selectively issuing progress or debugging messages
- from scripts, also described in the next section.
- * Fix from [86]John Dunlap to prevent the fixed packet-timeout
- interval from going to an unexpected value.
- * Alpha.04 fixes a problem with FTP connections made from 64-bit Unix
- platforms. All the other changes in this section were to Alpha.03.
- * Relaunching a closed SSH connection with the CONNECT command is now
- possible, as it always has been with Telnet and other connection
- types; suggested by Peter Eichhorn (needs testing).
- * A symbol conflict fixed that prevented successful build on
- [87]FreeBSD 8.0.
- * Fixes from Christian Corti for building on SunOS 4.1.
- * New aixg target for building on AIX with gcc.
- * New aix+ibmssl target. This is nice because the IBM-supplied SSL
- libraries and header files are in a known location; no need to
- [88]set environment variables giving their locations.
- * "Large File Support" is now included by default on Alpha and IA64
- hardware on VMS 7.3 and later, and it should work much better than
- before.
- * Kermit's internal FTP client is now included by default in any
- build that also includes TCP/IP networking. At present, the FTP
- client seems to work well for binary-mode transfers; text (ASCII)
- mode transfers still need some work. In builds that also include
- Secure Sockets Layer (SSL) security (next item) the FTP client
- should be able to make securely authenticated and encrypted
- connections.
- * In network builds that request OpenSSL support, e.g.:
-
- $ @ckvker "" "" "CK_SSL"
- the OpenSSL version is detected automatically and the appropriate
- compile-time options are emitted (such as
- OPENSSL_DISABLE_OLD_DES_SUPPORT).
- * Preliminary / limited support for the ODS-5 file system on VMS 7.2
- and later, Alpha and Itanium only (needs testing): Filenames can be
- mixed case and can be longer.
- * Support for older and older VMS versions.
- * In the VMS build procedure, CKVKER.COM, the "i" option in P1 now
- means don't include the internal FTP client, and the "f" option
- means do not include "Large File" support. Large File support in
- VMS really only applies to the file-transfer display and
- statistics, which would go out of whack as soon as the byte count
- overflowed 31 bits because this is C-Kermit, built with the C
- compiler and the C library (runtime system), which did not support
- long integers until VMS 7.3.
- * The [89]LISP Operator ROUND now takes an optional second argument
- that specifies the number of places to round to, e.g.
- (ROUND dollars 2) rounds dollars to 2 decimal places.
- * Improved pattern matching in many commands for both strings and
- filenames.
- * Various minor new features, plus numerous bug fixes and speedups.
-
-Incompatibilities
-
- A top priority for new Kermit software releases has always been
- backwards compatibility. A script written for a previous Kermit release
- should run the same way in the new release.
-
- There's one exception this time. The [90]\fsplit() function is
- incredibly handy, it can do almost anything, up to and including
- parsing a LISP program (the underlying code is the basis of the
- [91]S-Expression interpreter). But did you ever try to use it to parse
- (say) a Tab-Separated-List (TSV file) or Comma-Separated-List (CSV)? It
- works as expected as long as the data contains only 7-bit characters.
- But if your data contains (say) Spanish or German or Russian text
- written in an 8-bit character set such as ISO 8859-1, every 8-bit
- character (any value 128-255) is treated as a break character. This is
- fixed in C-Kermit 9.0 by treating all 8-bit bytes as "include"
- characters rather than break characters, a total reversal of past
- behavior. I don't think it will affect anyone though, because if this
- had happened to anyone, I would have heard about it!
-
- Since most standard 8-bit character sets have control characters in
- positions 128-160, it might have made sense to keep 128-160 in the
- break set, but with the proliferation of Microsoft Windows code pages,
- there is no telling which 8-bit character is likely to be some kind of
- text, e.g. "smart quotes" or East European or Turkish accented letters.
-
-What's Not In C-Kermit 9.0
-
- Some large projects that were contemplated have not been done,
- including:
- * IPv6. Honestly, there has been zero demand for this, and it would
- be a lot of work and disruption to the code base. Volunteers
- welcome, I guess. It could be a CS project.
- * A database interface - MySQL or ODBC. For this one, there is some
- demand but I haven't had a chance to even look into it.
- * There's a looming issue with DES encryption; major vendors are
- removing it from their platforms, starting with Apple in Mac OS X
- 10.6, with Microsoft to follow suit. A secure version of Kermit can
- be built without DES, but in limited testing successful connections
- were spotty (e.g. with Kerberos 5).
- * Cleaning up the Unix makefile. It has 25 years' worth of targets in
- it. It is very likely safe to remove most of them, since (a) most
- old platforms have gone away by now, or have been upgraded, due to
- hacking vulnerabilities; (b) the market has consolidated
- considerably; and (c) most of the new features of C-Kermit 9.0,
- such as large files, won't be of any use on older platforms and
- previous C-Kermit versions will remain available.
- * Packages. Everybody wants an install package custom made for their
- own computer, Linux RPMs being the prime example but far from the
- only one. These will come, I suppose (especially with some Linux
- sites having a policy against installing any application that does
- not come as an RPM). In the meantime, here's a page that describes
- some Kermit-specific issues in package construction:
- [92]ckpackages.html.
-
-And a Loose End...
-Using External File-Transfer Protocols on Secure Connections
-
- After C-Kermit 8.0.212 Dev.27 (2006/12/22), I spent a big chunk of time
- trying to solve a particular problem that some of you have complained
- about and others might be familiar with: If you use C-Kermit to make a
- secure Telnet connection to another host (e.g. with Telnet SSL/TLS,
- Kerberos, or SRP) and then attempt to transfer a file using an external
- protocol such as Zmodem, it doesn't work.
-
- That's because as coded (through 8.0.211), C-Kermit simply starts the
- external protocol in a fork with its standard i/o redirected to the
- connection. This completely bypasses the encryption and decryption that
- is done by C-Kermit itself, and of course it doesn't work. The same
- thing occurs if you use the REDIRECT command. The routine that handles
- this is ttruncmd() in ckutio.c.
-
- In order to allow (say) Zmodem transfers on secure connections, it is
- necessary for C-Kermit to interpose itself between the external Zmodem
- program and the connection, decrypting the incoming stream before
- feeding it to Zmodem and encrypting Zmodem's output before sending out
- the connection.
-
- In principal, this is simple enough. We open a pseudoterminal pair
- ("master" and "slave") for Zmodem's i/o and we create a fork and start
- Zmodem in it; we read from the fork pty's standard output, encrypt, and
- send to the net; we read from the net, decrypt, and write to the fork
- pty's standard input.
-
- In practice, it's not so simple. First of all, pseudoterminals (ptys)
- don't seem to interface correctly with certain crucial APIs, at least
- not in the OS's I have tried (Mac OS X, Linux, NetBSD, etc), such as
- select(). And i/o with the pty often - perhaps always - fails to
- indicate errors when they occur; for example, when the fork has exited.
-
- But, even after coding around the apparent uselessness of select() for
- multiplexing pty and net, and using various tricks to detect when the
- external protocol exits and what its exit status is, I'm still left
- with a show-stopping problem: I just simply can not download (receive)
- a file with Zmodem, which is the main thing that people would probably
- want to do. I can send files just fine, but not receive. The incoming
- stream is delivered to Zmodem (to the pty slave) but upon arrival at
- the Zmodem process itself, pieces are always missing and/or corrupt.
- Yet I can receive files just fine if I use Kermit itself (C-Kermit or
- G-Kermit) as the external protocol, rather than Zmodem.
-
- I can think of two reasons why this might be the case:
-
- 1. Zmodem sends all 8-bit bytes and control codes in the clear, and
- maybe the pty is choking on them because it thinks it is a real
- terminal.
-
- But Zmodem puts its controlling terminal into raw mode. And C-Kermit
- puts the pty into raw mode too, just for good measure. If any 0xFF
- codes are in the Zmodem data stream, and it's a Telnet session, Kermit
- does any needed byte stuffing/unstuffing automatically. Anyway, if I
- tell Zmodem to prefix everything, it makes no difference.
-
- 2. Zmodem is a streaming protocol and perhaps the pty driver can't
- keep up with a sustained stream of input at network speeds. What
- would be the method of flow control?
-
- I can vary the size of the i/o buffers used for writing to the pty, and
- get different effects, but I am not able to get a clean download, no
- matter what buffer size I use. write()'ing to the pty does not return
- an error, and I can't see the errors because they happen on the master
- side. It's as if the path between the pty slave and master lacks flow
- control; I deliver a valid data stream to the pty slave and the master
- gets bits and pieces. This impression is bolstered somewhat by the
- "[93]man 7 pty" page in HP-UX, which talks about some special modes for
- ptys that turn off all termio processing and guarantee a
- flow-controlled reliable stream of bytes in both directions - a feature
- that seems to be specific to HP-UX, and exactly the one we need
- everywhere.
-
- Well, in Pass One I used C-Kermit's existing pty routines from
- ckupty.[ch], which are well-proven in terms of portability and of
- actually working. They are currently used by SET HOST /PTY for making
- terminal connections to external processes. But these routines are
- written on the assumption that the pty is to be accessed interactively,
- and maybe they are setting the fork/pty arrangement up in such a way
- that that's not suitable for file transfer. The Pass One routine is
- called xttptycmd() in ckutio.c.
-
- So in Pass Two I made a second copy of the routine, yttptycmd(), that
- manages the pty and fork itself, so all the code is in one place and
- it's simple and understandable. But it still doesn't work for Zmodem
- downloads. In this routine, I use openpty() to get the pty pair, which
- is not portable, so I can have access to both the master and slave pty
- file descriptors. This version can be used only a platforms that have
- openpty(): Linux, Mac OS X, NetBSD, etc.
-
- In Pass Three, zttptycmd(), I tried using pipes instead of ptys, in
- case ptys are simply not up to this task (but that can't be true
- because if I make a Telnet or SSH connection into a host, I can send
- files to it with Zmodem, and the remote Zmodem receiver is, indeed,
- running on a pty). But pipes didn't work either.
-
- In Pass Four, I extracted the relevant routines into a standalone
- program based on yttptycmd() (the openpty() version, for simplicity),
- which I tested on Mac OS X, the idea being to rule out any
- "environmental" effects of running inside the C-Kermit process. There
- was no difference -- Kermit transfers (with C-Kermit itself as the
- external protocol) worked; Zmodem transfers (neither sz or lsz) did
- not.
-
- Well, it's a much longer story. As the external protocol, I've tried
- rzsz, crzsz, and lrzsz. We know that some of these have quirks
- regarding standard i/o, etc, which is one of the reasons for using ptys
- in the first place, and i/o does work - just not reliably. Anyway, the
- 1100 lines or so of [94]ckc299.txt, starting just below where it says
- "--- Dev.27 ---" tell the full story. At this point I have to give up
- and move on; it might be more productive to let somebody else who has
- more experience with ptys take a look at it - if indeed anyone still
- cares about being able to do Zmodem transfers over secure Telnet
- connections.
-
- C-Kermit 9.0 contains the three new routines (and some auxiliary ones),
- but they are not compiled or called unless you build it specially:
-
- make targetname KFLAGS=-DXTTPTYCMD (builds with xttptycmd())
- make targetname KFLAGS=-DYTTPTYCMD (builds with yttptycmd())
- make targetname KFLAGS=-DZTTPTYCMD (builds with zttptycmd())
-
- These are all in [95]ckutio.c. As noted, the second one works only for
- Linux, FreeBSD, NetBSD, and Mac OS X, because it uses non-POSIX,
- non-portable openpty(). If you want to try it on some other platform
- that has openpty(), you can build it like this:
-
- make targetname "KFLAGS=-DYTTPTYCMD -DHAVE_OPENPTY"
-
- (and let me know, so I can have HAVE_OPENPTY predefined for that
- platform too). The best strategy to get this working, I think, would be
- to concentrate on yttptycmd(), which is the simpler of the two
- pty-based routines. If it can be made to work, then we'll see if we can
- retrofit it to use the ckupty.c routines so it will be portable to
- non-BSD platforms.
-
- By the way, if you build with any of [XYZ]TTPTYCMD defined, then the
- selected routine will always be used in place of ttruncmd(). This is to
- allow testing on all kinds of connections, not just secure ones, in
- both local and remote mode. Once the thing works, if it ever does, I'll
- add the appropriate tests and/or commands.
-
- By default, in the initial test release, C-Kermit 9.0 uses ttruncmd()
- on serial connections and ttyptycmd() on network connections. Even when
- a network connection is not encrypted, Kermit still needs to handle the
- network protocol, e.g. the quoting of 0xff bytes on Telnet connections.
-
-Demonstration: Fetch Mail from POP Server Secured by SSL
-
- [96]pop.ksc is a fully elaborated production script for fetching one's
- mail from a POP3 server over a connection secured by SSL. For
- explanation and documentation, [97]CLICK HERE. [98]mailcheck is a
- wrapper for the pop.ksc script, which collects your password one time,
- and then checks for new mail every 5 minutes (or other selected
- interval) and calls pop.ksc to fetch it if there is any.
-
-Demonstration: HP Switch Configuration Backup
-
- A common use for Kermit software is to make automated backups of the
- configuration of network switches and routers, such as those made by
- Cisco or Hewlett-Packard (although [99]tftp can be used for this, it is
- not available in all such devices; Kermit, however, works with those
- that have tftp as well as those that don't).
-
- Typically a backup can be done by making a Telnet, SSH, or serial
- connection to the device with Kermit and giving a command such as "show
- config" at the command-line prompt of the device with Kermit's session
- log activated. The result is a list of the commands that were used to
- establish the current configuration, suitable for feeding back to the
- device's console (e.g. with C-Kermit's TRANSMIT command) to reestablish
- the same configuration or to duplicate it on another device.
-
- At an HP installation it was noted, however, that while the HP switches
- (various ProCurve models) produced the desired list of commands, they
- were interspersed with escape sequences for special effects, thus
- rendering the recorded sessions unsuitable for feeding back into the
- switches.
-
- C-Kermit 9.0 introduces a new feature to strip the offending sequences
- out of a session log, leaving just the text. The command SET
- SESSION-LOG TEXT activates this feature. In C-Kermit 9.0 Alpha.02 and
- earlier, escape sequence stripping occurred only while logging
- interactive (CONNECT) sessions; beginning with Alpha.03 it is done also
- for data that is read by INPUT commands and therefore works for scripts
- too.
-
- A sample HP Switch Configuration Backup script is [100]HERE, and its
- data file is [101]HERE. This script also illustrates some other new
- features of Alpha.03:
-
- MESSAGE text
- This lets you put debugging messages in your script that can be
- displayed or not, according to SET DEBUG MESSAGE (below). This
- way you don't have to change your script for debugging. Hint:
- In Unix, invoke the script like this:
-
- $ DEBUG=1 scriptname arg1 arg2...
-
- and then include the following command in your script:
-
- if defined \$(DEBUG) set debug message on
-
- XMESSAGE text
- Like MESSAGE but prints the text with no line terminator, so it
- can be continued by subsequent messages.
-
- SET DEBUG MESSAGE { ON, OFF, STDERR }
- ON means MESSAGE commands should print to standard output; OFF
- means they shouldn't print anything; STDERR means the messages
- should be printed to [102]stderr. DEBUG MESSAGE is OFF by
- default, i.e. unless you SET it to ON or STDERR.
-
- IF DEBUG command
- Executes the command if SET DEBUG MESSAGE is not OFF.
-
- The \v(lastcommand) variable
- This variable contains the previous command. You can use it in
- debugging and error message to show (for example) exactly what
- the command was that just failed, without having to make a copy
- of the command:
-
-set host somehost.somecompany.com
-if fail exit 1 "FATAL - \v(lastcommand)"
-
- which, if the SET HOST command fails, prints "FATAL - set host
- somehost.somecompany.com" and then exits with status 1 (which
- normally indicates failure).
-
-Demonstration: HP iLO Blade Configuration
-
- [103]THIS DOCUMENT describes a script in production use at Columbia
- University for configuring and deploying racks full of HP blade servers
- through their "integrated Lights Out" (iLO) management interface,
- bypassing the tedious and error-prone process of configuring the
- servers one by one through the vendor-provided point-and-click Web
- interface, which is ill-suited to configuring large numbers of blades.
- The script illustrates some of C-Kermit 9.0's new features; source code
- is available through the link. The code is apt to change from time to
- time as new requirements surface.
-
-Demonstration: IBM/Rolm/Siemens CBX Management
-
- [104]THIS DOCUMENT describes a suite of scripts (some in production,
- some in development) used to manage the Columbia campus 20,000-line
- main telephone switch, along with about 10 satellite switches at
- off-campus locations. These switches are 1980s technology*, their
- management consoles are serial ports. Access is via Telnet to reverse
- terminal servers. The scripts allow for interactive sessions as well as
- automatic production (and in some cases formatting) of different
- reports required by different groups at different intervals. These
- scripts replace a whole assortment of ad-hoc ProComm ASPECT scripts
- that were scattered all over the place, with passwords embedded. The
- new scripts are intended to be run from a centralized server where
- there is a single well-secured configuration file, and where they can
- be used on demand, or in cron jobs. They are modular so code
- duplication is minimal.
- __________________________
- * Of course the University is deploying new technology but the but the
- old system will be used in parallel for some time to come.
-
-Demonstration: CSV and TSV Files
-
- Contents
-
- * [105]Reading a CSV or TSV Record and Converting it to an Array
- * [106]Using \fjoin() to create a Comma- or Tab-Separated Value List
- from an Array
- * [107]Using CSV or TSV Files
-
- Comma-Separated Value (CSV) format is commonly output by spreadsheets
- and databases when exporting data into plain-text files for import into
- other applications. Here are the details:
-
- Comma-Separated List Syntax
-
- 1. Each record is a series of fields.
- 2. Records are in whatever format is used by the underlying file
- system for lines of text.
- 3. Fields within records are separated by commas, with zero or more
- whitespace characters (space or tab) before and/or after the comma;
- such whitespace is considered part of the separator.
- 4. Fields with embedded commas must be enclosed in ASCII doublequote
- characters.
- 5. Fields with leading or trailing spaces must be enclosed in ASCII
- doublequotes.
- 6. Any field may be enclosed in ASCII doublequotes.
- 7. Fields with embedded doublequotes must be enclosed in doublequotes
- and each interior doublequote is doubled.
-
- Here is an example:
-
-aaa, bbb, has spaces,,"ddd,eee,fff", " has spaces ","Muhammad ""The Greatest"" A
-li"
-
- The first two are regular fields. The second is a field that has an
- embedded space but in which any leading or trailing spaces are to be
- ignored. The fourth is an empty field, but still a field. The fifth is
- a field that contains embedded commas. The sixth has leading and
- trailing spaces. The last field has embedded quotation marks.
-
- Prior to C-Kermit 9.0 Alpha.06, C-Kermit did not handle CSV files
- according to the specification above. Most seriously, there was no
- provision for a separator to be surrounded by whitespace that was to be
- considered part of the separator. Also there was no provision for
- quoting doublequotes inside of a quoted string.
-
-Reading a CSV record
-
- Now the \fsplit() function can handle any CSV-format string if you
- include the symbolic include set "CSV" as the 4th parameter. To
- illustrate, this program:
-
-def xx {
- echo [\fcontents(\%1)]
- .\%9 := \fsplit(\fcontents(\%1), &a, \44, CSV)
- for \%i 1 \%9 1 { echo "\flpad(\%i,3). [\&a[\%i]]" }
- echo "-----------"
-}
-xx {a,b,c}
-xx { a , b , c }
-xx { aaa,,ccc," with spaces ",zzz }
-xx { "1","2","3","","5" }
-xx { this is a single field }
-xx { this is one field, " and this is another " }
-xx { name,"Mohammad ""The Greatest"" Ali", age, 67 }
-xx { """field enclosed in doublequotes""" }
-exit
-
- gives the following results:
-
-[a,b,c]
- 1. [a]
- 2. [b]
- 3. [c]
------------
-[ a , b , c ]
- 1. [a]
- 2. [b]
- 3. [c]
------------
-[ aaa,,ccc," with spaces ",zzz ]
- 1. [aaa]
- 2. []
- 3. [ccc]
- 4. [ with spaces ]
- 5. [zzz]
------------
-[ "1","2","3","","5" ]
- 1. [1]
- 2. [2]
- 3. [3]
- 4. []
- 5. [5]
------------
-[ this is a single field ]
- 1. [this is a single field]
------------
-[ this is one field, " and this is another " ]
- 1. [this is one field]
- 2. [ and this is another ]
------------
-[ name,"Mohammad ""The Greatest"" Ali", age, 67 ]
- 1. [name]
- 2. [Mohammad "The Greatest" Ali]
- 3. [age]
- 4. [67]
------------
-[ """field enclosed in doublequotes""" ]
- 1. ["field enclosed in doublequotes"]
------------
-
- The separator \44 (comma) must still be specified as the break set (3rd
- \fsplit() parameter). When "CSV" is specified as the include set:
- * The Grouping Mask is automatically set to 1 (which specifies that
- the ASCII doublequote character (") is used for grouping;
- * The Separator Flag is automatically set to 1 so that adjacent field
- separators will not be collapsed;
- * All bytes (values 0 through 255) other than the break character are
- added to the include set;
- * Any leading whitespace is stripped from the first element unless it
- is enclosed in doublequotes;
- * Any trailing whitespace is trimmed from the end of the last element
- unless it is enclosed in doublequotes;
- * If the separator character has any spaces or tabs preceding it or
- following it, they are ignored and discarded;
- * The separator character is treated as an ordinary data character if
- it appears in a quoted field;
- * A sequence of two doublequote characters ("") within a quoted field
- is converted to a single doublequote.
-
- There is also a new TSV symbolic include set, which is like CSV except
- without the quoting rules or the stripping of whitespace around the
- separator because, by definition, TSV fields do not contain tabs.
-
- Of course you can specify any separator(s) you want with either the
- CSV, TSV, or ALL symbolic include sets. For example, if you have a TSV
- file in which you want the spaces around each Tab to be discarded, you
- can use:
-
-\fsplit(variable, &a, \9, CSV)
-
- \9 is Tab.
-
- The new symbolic include sets can also be used with \fword(), which is
- just like \fsplit() except that it retrieves the nth word from the
- argument string, rather than an array of all the words. In C-Kermit you
- can get information about these or any other functions with the HELP
- FUNCTION command, e.g.:
-
-C-Kermit> help func word
-
-Function \fword(s1,n1,s2,s3,n2,n3) - Extracts a word from a string.
- s1 = source string.
- n1 = word number (1-based) counting from left; if negative, from right.
- s2 = optional break set.
- s3 = optional include set (or ALL, CSV, or TSV).
- n2 = optional grouping mask.
- n3 = optional separator flag:
- 0 = collapse adjacent separators;
- 1 = don't collapse adjacent separators.
-
- \fword() returns the n1th "word" of the string s1, according to the
- criteria specified by the other parameters.
-
- The BREAK SET is the set of all characters that separate words. The
- default break set is all characters except ASCII letters and digits.
- ASCII (C0) control characters are treated as break characters by default,
- as are spacing and punctuation characters, brackets, and so on, and
- all 8-bit characters.
-
- The INCLUDE SET is the set of characters that are to be treated as
- parts of words even though they normally would be separators. The
- default include set is empty. Three special symbolic include sets are
- also allowed:
-
- ALL (meaning include all bytes that are not in the break set)
- CSV (special treatment for Comma-Separated-Value records)
- TSV (special treatment for Tab-Separated-Value records)
-
- For operating on 8-bit character sets, the include set should be ALL.
-
- If the GROUPING MASK is given and is nonzero, words can be grouped by
- quotes or brackets selected by the sum of the following:
-
- 1 = doublequotes: "a b c"
- 2 = braces: {a b c}
- 4 = apostrophes: 'a b c'
- 8 = parentheses: (a b c)
- 16 = square brackets: [a b c]
- 32 = angle brackets: <a b c>
-
- Nesting is possible with {}()[]<> but not with quotes or apostrophes.
-
-Returns string:
- Word number n1, if there is one, otherwise an empty string.
-
-Also see:
- HELP FUNCTION SPLIT
-
-C-Kermit>
-
-Using \fjoin() to create Comma- or Tab-Separated Value Lists from Arrays
-
- In C-Kermit 9.0, \fsplit()'s inverse function, [108]\fjoin() received
- the capability of converting an array into a comma-separated or a
- tab-separated value list. Thus, given a CSV, if you split it into an
- array with \fsplit() and then join the array with \fjoin(), giving each
- function the new CSV parameter in the appropriate argument position,
- the result will be will be equivalent to the original, according to the
- CSV definition. It might not be identical, because if the result had
- extraneous spaces before or after the separating commas, these are
- discarded, but that does not affect the elements themselves. The new
- syntax for \fjoin() is:
-
- \fjoin(&a,CSV)
- Given the array \&a[] or any other valid array designator, joins
- its elements into a comma-separated list according to the
- [109]rules listed above.
-
- \fjoin(&a,TSV)
- Joins the elements of the given array into a tab-separated list,
- also described above.
-
- [110]Previous calling conventions for \fjoin() are undisturbed,
- including the ability to specify a portion of an array, rather than the
- whole array:
-
-declare \&a[] = 1 2 3 4 5 6 7 8 9
-echo \fjoin(&a[3:7],CSV)
-3,4,5,6,7
-
- Using \fsplit() and \fjoin() it is now possible to convert a
- comma-separated value list into a tab-separated value list, and vice
- versa (which is not a simple matter of changing commas to tabs or vice
- versa).
-
-Applications for CSV Files
-
- Databases such as MS Access or MySQL can export tables or reports in
- CSV format, and then Kermit can read the resulting CSV file and do
- whatever you like with it; typically something that could not be done
- with the database query language itself (or that you didn't know how to
- do that way): create reports or datasets based on complex criteria or
- procedures, edit or modify some fields, etc, and then use \fjoin() to
- put each record back in CSV form so it can be reimported into a
- spreadsheet or database.
-
- Here is a simple example in which we purge all records of customers who
- have two or more unpaid bills. The file is sorted so that each license
- purchase record is followed by its annual maintenance payment records
- in chronological order.
-
-#!/usr/local/bin/kermit
-.filename = somefile.csv # Input file in CSV format
-fopen /read \%c \m(filename) # Open it
-if fail exit # Don't go on if open failed
-copy \m(filename) ./new # Make a copy of the file
-
-.oldserial = 00000000000 # Multiple records for each serial number
-.zeros = 0 # Unpaid bill counter
-
-while true { # Loop
- fread /line \%c line # Get a record
- if fail exit # End of file
- .n := \fsplit(\m(line),&a,\44,CSV) # Split the fields into an array
- if not equ "\m(oldserial)" "\&a[6]" { # Have new serial number?
- # Remove all records for previous serial number
- # if two or more bills were not paid...
- if > \m(zeros) 1 {
- grep /nomatch \m(oldserial) /output:./new2 ./new
- rename ./new2 ./new
- }
- .oldserial := \&a[6] # To detect next time serial number changes
- .zeros = 0 # Reset unpaid bill counter
- }
- if equ "\&a[5]" "$0.00" { # Element 5 is amount paid
- increment zeros # If it's zero, count it.
- }
-}
-fclose \%c
-
- Rewriting the file multiple times is inelegant, but this is a quick and
- dirty use-once-and-discard script, so elegance doesn't count. The
- example is interesting in that it purges certain records based on the
- contents of other records. Maybe there is a way to do this directly
- with SQL, but why use SQL when you can use Kermit?
-
- Here is the same task but this time no shelling out, and this time we
- do change and add some fields and then join the result back into a CSV
- record and write it out to a new file. The object is to create a record
- for each license that shows not only the date and purchase price of the
- license but also the date and amount of the last maintenance payment,
- and to add new fields for sorting by anniversary (month and day):
-
-#!usr/local/bin/kermit +
-cd ~/somedirectory # CD to appropriate directory
-if fail exit 1 # Make sure we did
-.filename := \%1 # Filename from command line
-if not def filename { # If none give usage message
- exit 1 "Usage: \%0: infile [ outfile ]"
-}
-fopen /read \%c \m(filename) # Open the input CSV file
-if fail exit # Make sure we did
-
-.output := \%2 # Output filename from command line
-if not def output { # Supply one if not given
- .output := New_\m(filename)
-}
-fopen /write \%o \m(output) # Open output file
-if fail exit # Check that we did
-
-.serial = 00000000000 # Initialize serial number
-.licenses = 0 # and license counter
-
-fread /line \%c line # First line is column labels
-if fail exit # Check
-fwrite /line \%o "\m(line),AMM_DD,AYYYY" # Write new labels line
-
-# Remaining lines are license purchases (K95B) followed by zero or more
-# maintenance invoices (K95BM) for each license.
-
-.datepaid = 00/00/0000 # Initialize last maint payment date
-.amtpaid = $0.00 # Initialize last maint payment amount
-set flag off # For remembering we're at end of file
-while not flag { # Loop to read all records
- fread /line \%c line # Read a record
- if fail set flag on # If EOF set flag for later
- .n := \fsplit(\m(line),&a,\44,CSV) # Break record into array
- if ( flag || equ "\&a[3]" "K95B" ) { # License or EOF
- if fail exit 1 "FAILED: \v(lastcommand)"
- if licenses { # If this is not the first license
- .\&x[5] := \m(amtpaid) # Substitute most recent amount paid
- .\&x[21] := \m(datepaid) # Substitute most recent date paid
- void \fsplit(\&x[18],&d,/) # Break up original (anniversary) date
- # and put mm_dd and yyyy in separate fields for sorting...
- fwrite /line \%o "\fjoin(&x,CSV),\flpad(\&d[1],2,0)_\flpad(\&d[2],2,
-0),\&d[3]"
- if fail exit 1 WRITE # Check for error
- xecho . # Show progress as one dot per record
- }
- if flag break # We're at EOF so we're finished
- increment licenses # New license - count it
- array copy &a &x # Keep this record while reading next
- .serial := \&a[6] # Remember serial number
- .datepaid = 00/00/0000 # Initial maintenance payment date
- .amtpaid = $0.00 # and amount
- continue # and go back to read next record
- }
- if not eq "\m(serial)" "\&a[6]" { # Catch out-of-sequence record
- echo
- echo "SEQUENCE: \m(serial)..\&a[6]: \&a[7] [\&a[1]]"
- continue
- }
- if equ "\&a[5]" "" .\&a[5] = $0.00 # If amount is empty make it $0.00
- if not equ "\&a[5]" "$0.00" { # If amount is not $0.00
- .datepaid := \&a[21] # remember date paid
- .amtpaid := \&a[5] # and amount paid
- }
-}
-fclose ALL # Done - close all files and exit
-exit 0 Done.
-
-
- The result imports back into Excel, where it can be sorted, formatted,
- or otherwise manipulated as desired.
-
-Using CSV Files: Extending Kermit's Data Structures
-
- Now that we can parse a CSV record, what would we do with a CSV file -
- that is, a sequence of records? If we needed all the data available at
- once, we would want to load it into a matrix of (row,column) values.
- But Kermit doesn't have matrices. Or does it?
-
- Kermit has several built-in data types, but you can invent your own
- data types as needed using Kermit's macro feature:
-
-define variablename value
-
- For example:
-
-define alphabet abcdefghijklmnopqrstuvwxyz
-
- This defines a macro named alphabet and gives it the value
- abcdefghijklmnopqrstuvwxyz. A more convenient notation (added in
- C-Kermit 7.0, see [111]Table 2) for this is:
-
-.alphabet = abcdefghijklmnopqrstuvwxyz
-
- The two are exactly equivalent: they make a literal copy the "right
- hand side" as the value of the macro. Then you can refer to the macro
- anywhere in a Kermit command as "\m(macroname)":
-
-echo "Alphabet = \m(alphabet)"
-
- There is a second way to define a macro, which is like the first except
- that the right-hand side is evaluated first; that is, any variable
- references or function calls in the right-hand side are replaced by
- their values before the result is assigned to the macro. The command
- for this is ASSIGN rather than DEFINE:
-
-define alphabet abcdefghijklmnopqrstuvwxyz
-assign backwards \freverse(\m(alphabet))
-echo "Alphabet backwards = \m(backwards)"
-
- which prints:
-
-Alphabet backwards = zyxwvutsrqponmlkjihgfedcba
-
- This kind of assignment can also be done like this:
-
-.alphabet = abcdefghijklmnopqrstuvwxyz
-.backwards := \freverse(\m(alphabet))
-
- [112]Any command starting with a period is an assignment, and the
- operator (= or :=) tells what to do with the right-hand side before
- making the assignment.
-
- In both the DEFINE and ASSIGN commands, the variable name itself is
- taken literally. It is also possible, however, to have Kermit compute
- the variable name. This is done (as described in [113]Using C-Kermit,
- 2nd Ed., p.457), using parallel commands that start with underscore:
- _DEFINE and _ASSIGN (alias _DEF and _ASG). These are just like DEFINE
- and ASSIGN except they evaluate the variable name before making the
- assignment. For example:
-
-define \%a one
-_define \%a\%a\%a 111
-
- would create a macro named ONEONEONE with a value of 111, and:
-
-define \%a one
-define number 111
-_assign \%a\%a\%a \m(number)
-
- would create the same macro with the same value, but:
-
-define \%a one
-define number 111
-_define \%a\%a\%a \m(number)
-
- would give the macro a value of "\m(number)".
-
- You can use the _ASSIGN command to create any kind of data structure
- you want; you can find some examples in the [114]Object-Oriented
- Programming section of the [115]Kermit Script Library. In the following
- program we use this capability to create a two-dimensional array, or
- matrix, to hold the all the elements of the CSV file, and then to
- display the matrix:
-
-fopen /read \%c data.csv # Open CSV file
-if fail exit 1
-
-.\%r = 0 # Row
-.\%m = 0 # Maximum columns
-while true {
- fread /line \%c line # Read a record
- if fail break # End of file
- .\%n := \fsplit(\m(line),&a,\44,CSV) # Split record into items
- incr \%r # Count this row
- for \%i 1 \%n 1 { # Assign items to this row of matrix
- _asg a[\%r][\%i] \&a[\%i]
- }
- if > \%i \%m { .\%m := \%i } # Remember width of widest row
-}
-fclose \%c # Close CSV file
-decrement \%m # (because of how FOR loop works)
-echo MATRIX A ROWS: \%r COLUMNS: \%m # Show the matrix
-
-for \%i 1 \%r 1 { # Loop through rows
- for \%j 1 \%m 1 { # Loop through columns of each row
- xecho "\flpad(\m(a[\%i][\%j]),6)"
- }
- echo
-}
-exit 0
-
- The matrix is called a and its elements are a[1][1], a[1][2], a[1][3],
- ... a[2][1], etc, and you can treat this data structure exactly like a
- two-dimensional array, in which you can refer to any element by its "X
- and Y coordinates". For example, if the CSV file contained numeric data
- you could compute row and column sums using simple FOR loops and
- Kermit's built-in one-dimensional array data type:
-
-declare \&r[\%r] # Make an array for the row sums
-declare \&c[\%m] # Make an array for the column sums
-for \%i 1 \%r 1 { # Loop through rows
- for \%j 1 \%m 1 { # Loop through columns of each row
- increment \&r[\%i] \m(a[\%i][\%j]) # Accumulate row sum
- increment \&c[\%j] \m(a[\%i][\%j]) # Accumulate column sum
- }
-}
-
- Note that the sum arrays don't have to be initialized to zero because
- Kermit's INCREMENT command treats empty definitions as zero.
-
-Demonstration Scripts for Webmasters
-
- These scripts all use new features of C-Kermit 9.0.
-
- [116]ksitemap
- A C-Kermit 9.0 script to build sitemap.xml for a website,
- complete with Google image extensions (this is the file used by
- webmasters to get their sites crawled and indexed optimally).
-
- [117]The Weblog Script
- Reads a web log, extracts the Google searches, normalizes the
- search strings, and prints the top 20 searches, along with their
- counts.
-
- [118]The Amazon Script
- Reads an Amazon Associate orders report and lists the products
- according to the number of orders for each, or the number of
- clicks on each.
-
- [119]Photoalbum
- Makes a website from a collection of JPG images.
-
- [120]Home [121]Kermit 95 [122]C-Kermit [123]Scripts [124]Current
- [125]New [126]FAQ [127]Support
-
-
- C-Kermit 9.0 / [128]The Kermit Project / [129]Columbia University /
- [130]kermit@columbia.edu / [131]validate
-
-References
-
- 1. http://www.columbia.edu/
- 2. mailto:kermit@columbia.edu
- 3. http://www.columbia.edu/kermit/index.html
- 4. http://www.columbia.edu/kermit/k95.html
- 5. http://www.columbia.edu/kermit/ckermit.html
- 6. http://www.columbia.edu/kermit/ckscripts.html
- 7. http://www.columbia.edu/kermit/current.html
- 8. http://www.columbia.edu/kermit/whatsnew.html
- 9. http://www.columbia.edu/kermit/faq.html
- 10. http://www.columbia.edu/kermit/support.html
- 11. http://www.columbia.edu/cu/computinghistory/books/#menagerie
- 12. http://www.columbia.edu/kermit/ck90tables.html
- 13. http://www.amazon.com/gp/product/1555581641?ie=UTF8&tag=aleidmoreldom-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1555581641
- 14. http://www.columbia.edu/kermit/ckermit.html#download
- 15. http://www.columbia.edu/kermit/ckermit90.html#LargeFiles
- 16. http://www.columbia.edu/kermit/ckermit90.html#TestLargeFiles
- 17. http://www.columbia.edu/kermit/ckermit90.html#Bignums
- 18. http://www.columbia.edu/kermit/ckermit90.html#force3
- 19. http://www.columbia.edu/kermit/ckermit90.html#Vareval
- 20. http://www.columbia.edu/kermit/ckermit90.html#rename
- 21. http://www.columbia.edu/kermit/ckermit90.html#Other
- 22. http://www.columbia.edu/kermit/ckermit90.html#Incompatibilities
- 23. http://www.columbia.edu/kermit/ckermit90.html#NotIn9.0
- 24. http://www.columbia.edu/kermit/ckermit90.html#LooseEnd
- 25. http://www.columbia.edu/kermit/ckermit90.html#pop
- 26. http://www.columbia.edu/kermit/ckermit90.html#HPswitch
- 27. http://www.columbia.edu/kermit/ckermit90.html#iLO
- 28. http://www.columbia.edu/kermit/ckermit90.html#Rolm
- 29. http://www.columbia.edu/kermit/ckermit90.html#CSV
- 30. http://www.columbia.edu/kermit/ckermit90.html#Otherdemos
- 31. http://www.columbia.edu/kermit/ck60manual.html
- 32. http://www.amazon.com/gp/product/B002ACPF9M?ie=UTF8&tag=aleidmoreldom-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=B002ACPF9M
- 33. http://www.columbia.edu/kermit/ckermit70.html
- 34. http://www.columbia.edu/kermit/ckermit80.html
- 35. http://www.columbia.edu/kermit/ckscripts.html
- 36. http://www.columbia.edu/cu/computinghistory/dec20.html
- 37. mailto:fdc@columbia.edu
- 38. http://www.columbia.edu/kermit/k95.html
- 39. http://www.columbia.edu/kermit/cu-bsd-license.html
- 40. http://www.columbia.edu/kermit/ckermit90.html#LargeFiles
- 41. http://www.columbia.edu/kermit/ck90tables.html
- 42. http://www.columbia.edu/kermit/ck90tables.html
- 43. http://www.columbia.edu/kermit/ckermit90.html#force3
- 44. http://www.columbia.edu/kermit/ckermit90.html#Vareval
- 45. http://www.columbia.edu/kermit/ckrename.html
- 46. http://www.columbia.edu/kermit/csv.html
- 47. http://www.columbia.edu/kermit/csetnames.html
- 48. http://www.columbia.edu/kermit/ckermit90.html#HPswitch
- 49. http://www.columbia.edu/kermit/ckdaily.html
- 50. http://www.columbia.edu/kermit/cu-bsd-license.html
- 51. http://www.opensource.org/
- 52. http://kermit.columbia.edu/ck90tables.html#LF
- 53. ftp://kermit.columbia.edu/kermit/utils/bigfile.c
- 54. http://www.columbia.edu/kermit/ckermit80.html#x9
- 55. http://www.columbia.edu/kermit/ck90tables.html#LF
- 56. ftp://kermit.columbia.edu/kermit/scripts/ckermit/easter2
- 57. http://www.columbia.edu/kermit/em-apex.html
- 58. http://www.iridium.com/
- 59. http://science1.nasa.gov/science-news/science-at-nasa/2006/09jan_electrichurricanes/
- 60. http://www.columbia.edu/kermit/ek.html
- 61. ftp://kermit.columbia.edu/kermit/ek/simirid/
- 62. http://www.columbia.edu/kermit/ek.html
- 63. http://www.columbia.edu/kermit/ckermit70.html#x7.10.10
- 64. http://www.columbia.edu/kermit/csv.html
- 65. http://www.columbia.edu/kermit/ckermit70.html#x1.11
- 66. http://www.columbia.edu/kermit/ckermit70.html
- 67. http://www.columbia.edu/kermit/ckermit80.html#x9
- 68. http://www.columbia.edu/kermit/csetnames.html
- 69. http://www.columbia.edu/kermit/ckdaily.html
- 70. http://www.columbia.edu/kermit/ftpclient.html
- 71. http://www.columbia.edu/kermit/ckdaily.html
- 72. http://www.columbia.edu/kermit/csetnames.html
- 73. http://www.columbia.edu/kermit/ckermit90.html#Otherdemos
- 74. http://www.columbia.edu/kermit/input_nowrap.html
- 75. http://www.columbia.edu/~fdc/mm/index.html
- 76. http://www.columbia.edu/kermit/photoalbum.html
- 77. http://www.columbia.edu/~fdc/kermit/logserial.html
- 78. http://www.columbia.edu/kermit/ckermit90.html#message
- 79. http://www.columbia.edu/kermit/ckermit90.html#NotIn9.0
- 80. http://www.columbia.edu/kermit/csv.html#join
- 81. http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3767
- 82. http://www.columbia.edu/kermit/ftp/test/tar/x.zip
- 83. http://www.mseclab.com/?p=180
- 84. http://www.theregister.co.uk/2009/07/30/universal_ssl_certificate/
- 85. http://www.columbia.edu/kermit/ckermit90.html#HPswitch
- 86. http://www.columbia.edu/kermit/em-apex.html
- 87. http://www.freebsd.org/releases/8.0R/announce.html
- 88. http://www.columbia.edu/kermit/security81.html#x4.2.3
- 89. http://www.columbia.edu/kermit/ckermit80.html#x9
- 90. http://www.columbia.edu/kermit/ckermit80.html#x8.7.2
- 91. http://www.columbia.edu/kermit/ckermit80.html#x9
- 92. http://www.columbia.edu/kermit/ckpackages.html
- 93. http://docs.hp.com/en/B9106-90013/pty.7.html
- 94. http://www.columbia.edu/kermit/test/text/ckc299.txt
- 95. http://www.columbia.edu/kermit/test/text/ckutio.c
- 96. http://www.columbia.edu/~fdc/mm/pop
- 97. http://www.columbia.edu/~fdc/mm/
- 98. http://www.columbia.edu/~fdc/mm/mailcheck
- 99. http://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol
- 100. http://www.columbia.edu/kermit/ftp/scripts/ckermit/gethpconfig
- 101. http://www.columbia.edu/kermit/ftp/scripts/ckermit/TestSwitches.txt
- 102. http://en.wikipedia.org/wiki/Standard_streams
- 103. http://kermit.columbia.edu/cudocs/ilosetup.html
- 104. http://www.columbia.edu/kermit/cudocs/cbx.html
- 105. http://www.columbia.edu/kermit/ckermit90.html#record
- 106. http://www.columbia.edu/kermit/ckermit90.html#join
- 107. http://www.columbia.edu/kermit/ckermit90.html#file
- 108. http://www.columbia.edu/kermit/ckermit80.html#fjoin
- 109. http://www.columbia.edu/kermit/ckermit90.html#rules
- 110. http://www.columbia.edu/kermit/ckermit80.html#fjoin
- 111. http://www.columbia.edu/kermit/ckermit90.html#varasg
- 112. http://www.columbia.edu/kermit/ckermit70.html#x7.9
- 113. http://www.amazon.com/gp/product/1555581641?ie=UTF8&tag=aleidmoreldom-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1555581641
- 114. http://www.columbia.edu/kermit/ckscripts.html#oops
- 115. http://www.columbia.edu/kermit/ckscripts.html
- 116. http://www.columbia.edu/kermit/ksitemap.html
- 117. http://www.columbia.edu/kermit/weblog.html
- 118. http://kermit.columbia.edu/ftp/scripts/ckermit/amazon
- 119. http://www.columbia.edu/kermit/photoalbum.html
- 120. http://www.columbia.edu/kermit/index.html
- 121. http://www.columbia.edu/kermit/k95.html
- 122. http://www.columbia.edu/kermit/ckermit.html
- 123. http://www.columbia.edu/kermit/ckscripts.html
- 124. http://www.columbia.edu/kermit/current.html
- 125. http://www.columbia.edu/kermit/whatsnew.html
- 126. http://www.columbia.edu/kermit/faq.html
- 127. http://www.columbia.edu/kermit/support.html
- 128. http://www.columbia.edu/kermit/index.html
- 129. http://www.columbia.edu/
- 130. mailto:kermit@columbia.edu
- 131. http://validator.w3.org/check?uri=http%3A%2F%2Fkermit.columbia.edu%2Fckermit90.html
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckermod.ini b/ckermit-9.0.302-build/ckermit-9.0.302/ckermod.ini
deleted file mode 100644
index 6b13c85..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckermod.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-; File CKERMOD.INI, Sample C-Kermit 7.0 customization file.
-;
-echo
-echo The very long standard initialization file that was distributed
-echo with C-Kermit 6, 7, and 8 is no longer recommended as "standard",
-echo since its features were little used. It is still available in
-echo the C-Kermit distribution as ockermod.ini.
-echo
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuat2.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckuat2.h
deleted file mode 100644
index 8679a99..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuat2.h
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- C K U A T 2 . H -- Kerberos headers for C-Kermit
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Author:
- Kerberos IV and V intergration.
- Jeffrey E Altman (jaltman@secure-endpoints.com)
- Secure Endpoints Inc., New York City
-*/
-/*
- * Based on a concatenation of all necessary include files distributed with
- * the Kerberos 5 NT Alpha 2 Telnet package from MIT.
- */
-
-#ifndef KRB5_TELNET_H
-#define KRB5_TELNET_H
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)encrypt.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#ifdef CK_ENCRYPTION
-
-#ifndef __ENCRYPTION__
-#define __ENCRYPTION__
-
-#define DIR_DECRYPT 1
-#define DIR_ENCRYPT 2
-
-#ifndef CK_DES_C
-#ifndef NOBLOCKDEF
-typedef unsigned char Block[8];
-#endif /* NOBLOCKDEF */
-typedef unsigned char *BlockT;
-#ifndef KRB4 /* already defined in kerberosiv/des.h */
-typedef struct des_ks_struct { Block _; } Schedule[16];
-#else /* KRB4 */
-#ifndef OS2
-#ifndef NOBLOCKDEF /* already defined in kerberosiv/des.h */
-typedef struct des_ks_struct { Block _; } Schedule[16];
-#endif /* NOBLOCKDEF */
-#endif /* OS2 */
-#endif /* KRB4 */
-
-#define VALIDKEY(key) (key[0]|key[1]|key[2]|key[3]|key[4]|key[5]|key[6]|key[7])
-
-#define SAMEKEY(k1, k2) (!memcmp((void *)k1, (void *)k2, sizeof(Block)))
-#endif /* CK_DES_C */
-
-typedef struct _session_key {
- short type;
- int length;
- unsigned char *data;
-} Session_Key;
-
-#ifdef __STDC__
-typedef struct {
- char *name;
- int type;
- void (*output)(unsigned char *, int);
- int (*input)(int);
- void (*init)(int);
- int (*start)(int, int);
- int (*is)(unsigned char *, int);
- int (*reply)(unsigned char *, int);
- int (*session)(Session_Key *, int);
- int (*keyid)(int, unsigned char *, int *);
- void (*printsub)(unsigned char *, int, unsigned char *, int);
-} Encryptions;
-#if !defined(P)
-#define P(x) x
-#endif
-#else
-typedef struct {
- char *name;
- int type;
- void (*output)();
- int (*input)();
- void (*init)();
- int (*start)();
- int (*is)();
- int (*reply)();
- int (*session)();
- int (*keyid)();
- void (*printsub)();
-} Encryptions;
-#if !defined(P)
-#define P(x) ()
-#endif
-#endif
-
-int encrypt_parse(unsigned char *, int);
-
-#ifdef DEBUG
-int printsub(char, unsigned char *, size_t);
-#endif
-
-#define SK_GENERIC 0 /* Just a string of bits */
-#define SK_DES 1 /* Matched Kerberos v5 ENCTYPE_DES */
-
-void encrypt_init P((kstream,int));
-Encryptions *findencryption P((int));
-void encrypt_send_support P((void));
-void encrypt_auto P((int));
-void decrypt_auto P((int));
-int encrypt_is P((unsigned char *, int));
-int encrypt_reply P((unsigned char *, int));
-void encrypt_start_input P((int));
-int encrypt_session_key P((Session_Key *, int));
-int encrypt_dont_support P((int));
-void encrypt_end_input P((void));
-void encrypt_start_output P((int));
-void encrypt_end_output P((void));
-void encrypt_send_request_start P((void));
-void encrypt_send_request_end P((void));
-void encrypt_send_end P((void));
-void encrypt_wait P((void));
-int encrypt_is_encrypting P((void));
-void encrypt_send_support P((void));
-int encrypt_send_keyid P((int, unsigned char *, int, int));
-
-int encrypt_cmd P((int, char **));
-void encrypt_display P((void));
-
-#ifdef CK_KERBEROS
-void krbdes_encrypt P((unsigned char *, int));
-int krbdes_decrypt P((int));
-int krbdes_is P((unsigned char *, int));
-int krbdes_reply P((unsigned char *, int));
-void krbdes_init P((int));
-int krbdes_start P((int, int));
-void krbdes_session P((Session_Key *, int));
-void krbdes_printsub P((unsigned char *, int, unsigned char *, int));
-#endif /* CK_KERBEROS */
-
-void cfb64_encrypt P((unsigned char *, int));
-int cfb64_decrypt P((int));
-void cfb64_init P((int));
-int cfb64_start P((int, int));
-int cfb64_is P((unsigned char *, int));
-int cfb64_reply P((unsigned char *, int));
-int cfb64_session P((Session_Key *, int));
-int cfb64_keyid P((int, unsigned char *, int *));
-void cfb64_printsub P((unsigned char *, int, unsigned char *, int));
-
-void ofb64_encrypt P((unsigned char *, int));
-int ofb64_decrypt P((int));
-void ofb64_init P((int));
-int ofb64_start P((int, int));
-int ofb64_is P((unsigned char *, int));
-int ofb64_reply P((unsigned char *, int));
-int ofb64_session P((Session_Key *, int));
-int ofb64_keyid P((int, unsigned char *, int *));
-void ofb64_printsub P((unsigned char *, int, unsigned char *, int));
-
-void des3_cfb64_encrypt P((unsigned char *, int));
-int des3_cfb64_decrypt P((int));
-void des3_cfb64_init P((int));
-int des3_cfb64_start P((int, int));
-int des3_cfb64_is P((unsigned char *, int));
-int des3_cfb64_reply P((unsigned char *, int));
-int des3_cfb64_session P((Session_Key *, int));
-int des3_cfb64_keyid P((int, unsigned char *, int *));
-void des3_cfb64_printsub P((unsigned char *, int, unsigned char *, int));
-
-void des3_ofb64_encrypt P((unsigned char *, int));
-int des3_ofb64_decrypt P((int));
-void des3_ofb64_init P((int));
-int des3_ofb64_start P((int, int));
-int des3_ofb64_is P((unsigned char *, int));
-int des3_ofb64_reply P((unsigned char *, int));
-int des3_ofb64_session P((Session_Key *, int));
-int des3_ofb64_keyid P((int, unsigned char *, int *));
-void des3_ofb64_printsub P((unsigned char *, int, unsigned char *, int));
-
-#ifdef CAST_ENCRYPTION
-void cast_cfb64_encrypt P((unsigned char *, int));
-int cast_cfb64_decrypt P((int));
-void cast_cfb64_init P((int));
-int cast_cfb64_start P((int, int));
-int cast_cfb64_is P((unsigned char *, int));
-int cast_cfb64_reply P((unsigned char *, int));
-int cast_cfb64_session P((Session_Key *, int));
-int cast_cfb64_keyid P((int, unsigned char *, int *));
-void cast_cfb64_printsub P((unsigned char *, int, unsigned char *, int));
-
-void cast_ofb64_encrypt P((unsigned char *, int));
-int cast_ofb64_decrypt P((int));
-void cast_ofb64_init P((int));
-int cast_ofb64_start P((int, int));
-int cast_ofb64_is P((unsigned char *, int));
-int cast_ofb64_reply P((unsigned char *, int));
-int cast_ofb64_session P((Session_Key *, int));
-int cast_ofb64_keyid P((int, unsigned char *, int *));
-void cast_ofb64_printsub P((unsigned char *, int, unsigned char *, int));
-
-void castexp_cfb64_encrypt P((unsigned char *, int));
-int castexp_cfb64_decrypt P((int));
-void castexp_cfb64_init P((int));
-int castexp_cfb64_start P((int, int));
-int castexp_cfb64_is P((unsigned char *, int));
-int castexp_cfb64_reply P((unsigned char *, int));
-int castexp_cfb64_session P((Session_Key *, int));
-int castexp_cfb64_keyid P((int, unsigned char *, int *));
-void castexp_cfb64_printsub P((unsigned char *, int, unsigned char *, int));
-
-void castexp_ofb64_encrypt P((unsigned char *, int));
-int castexp_ofb64_decrypt P((int));
-void castexp_ofb64_init P((int));
-int castexp_ofb64_start P((int, int));
-int castexp_ofb64_is P((unsigned char *, int));
-int castexp_ofb64_reply P((unsigned char *, int));
-int castexp_ofb64_session P((Session_Key *, int));
-int castexp_ofb64_keyid P((int, unsigned char *, int *));
-void castexp_ofb64_printsub P((unsigned char *, int, unsigned char *, int));
-#endif /* CAST_ENCRYPTION */
-
-/* int des_string_to_key P((char *, Block)); */
-
-#ifdef DEBUG
-extern int encrypt_debug_mode;
-#endif
-
-int decrypt_ks_hack(unsigned char *, int);
-
-#endif /* __ENCRYPTION__ */
-#endif /* ENCRYPTION */
-
-#ifdef CRYPT_DLL
-struct _crypt_dll_init {
- int version;
-
- /* Version 1 variables */
- int (*p_ttol)(char *,int);
- int (*p_dodebug)(int,char *,char *,CK_OFF_T);
- int (*p_dohexdump)(char *,char *,int);
- void (*p_tn_debug)(char *);
- int (*p_vscrnprintf)(char *, ...);
-
- /* Version 2 variables */
- void * p_k5_context;
-
- /* Version 3 variables */
- void (*p_install_funcs)(char *,void *);
-
- /* Version 5 variables */
- unsigned long (*p_reqtelmutex)(unsigned long);
- unsigned long (*p_reltelmutex)(void);
-};
-#endif /* CRYPT_DLL */
-
-/* per Kerberos v5 protocol spec */
-#ifndef ENCTYPE_NULL
-#define ENCTYPE_NULL 0x0000
-#endif
-#ifndef ENCTYPE_DES_CBC_CRC
-#define ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */
-#endif
-#ifndef ENCTYPE_DES_CBC_MD4
-#define ENCTYPE_DES_CBC_MD4 0x0002 /* DES cbc mode with RSA-MD4 */
-#endif
-#ifndef ENCTYPE_DES_CBC_MD5
-#define ENCTYPE_DES_CBC_MD5 0x0003 /* DES cbc mode with RSA-MD5 */
-#endif
-#ifndef ENCTYPE_DES_CBC_RAW
-#define ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */
-#endif
-/* XXX deprecated? */
-#ifndef ENCTYPE_DES3_CBC_SHA
-#define ENCTYPE_DES3_CBC_SHA 0x0005 /* DES-3 cbc mode with NIST-SHA */
-#endif
-#ifndef ENCTYPE_DES3_CBC_RAW
-#define ENCTYPE_DES3_CBC_RAW 0x0006 /* DES-3 cbc mode raw */
-#endif
-#ifndef ENCTYPE_DES_HMAC_SHA1
-#define ENCTYPE_DES_HMAC_SHA1 0x0008
-#endif
-#ifndef ENCTYPE_DES3_CBC_SHA1
-#define ENCTYPE_DES3_CBC_SHA1 0x0010
-#endif
-#ifndef ENCTYPE_AES128_CTS_HMAC_SHA1_96
-#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011
-#endif
-#ifndef ENCTYPE_AES256_CTS_HMAC_SHA1_96
-#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012
-#endif
-#ifndef ENCTYPE_ARCFOUR_HMAC
-#define ENCTYPE_ARCFOUR_HMAC 0x0017
-#endif
-#ifndef ENCTYPE_ARCFOUR_HMAC_EXP
-#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018
-#endif
-#ifndef ENCTYPE_LOCAL_RC4_MD4
-#define ENCTYPE_LOCAL_RC4_MD4 0xFFFFFF80
-#endif
-#ifndef ENCTYPE_UNKNOWN
-#define ENCTYPE_UNKNOWN 0x01ff
-#endif
-/* local crud */
-/* marc's DES-3 with 32-bit length */
-#ifndef ENCTYPE_LOCAL_DES3_HMAC_SHA1
-#define ENCTYPE_LOCAL_DES3_HMAC_SHA1 0x7007
-#endif
-#endif /* KRB5_TELNET_H */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuath.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuath.c
deleted file mode 100644
index ea9bc7d..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuath.c
+++ /dev/null
@@ -1,13362 +0,0 @@
-char *ckathv = "Authentication, 9.0.235, 16 Mar 2010";
-/*
- C K U A T H . C -- Authentication for C-Kermit
-
- Copyright (C) 1999, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Author: Jeffrey E Altman (jaltman@secure-endpoints.com)
- Secure Endpoints Inc., New York City
-*/
-/*
- * Additional copyrights included with affected code.
- */
-
-#ifdef HEIMDAL
-/*
- Turned off User to User support
- Turned off KDESTROY support
- Turned off KLIST support
- Turned off krb5_prompter() support
- Turned off ticket validation
- Turned off ticket renewal
- Turned off alternative cache support in k5_get_ccache()
-
- Remaining link problems:
-
- ckuath.o: In function `ck_krb5_initTGT':
- ckuath.o(.text+0x50c2): undefined reference to `krb5_string_to_deltat'
- ckuath.o(.text+0x516d): undefined reference to `krb5_string_to_deltat'
- ckuath.o(.text+0x51ef): undefined reference to `krb5_string_to_deltat'
-*/
-#endif /* HEIMDAL */
-
-/*
- * Implements Kerberos 4/5, SRP, SSL, NTLM authentication and START_TLS
- */
-
-#include "ckcsym.h"
-#include "ckcdeb.h"
-
-#ifdef CK_SECURITY
-
-#define CKUATH_C
-#include "ckcker.h"
-#include "ckuusr.h"
-#include "ckucmd.h" /* For struct keytab */
-#include "ckcnet.h"
-#include "ckctel.h"
-
-char szUserNameRequested[UIDBUFLEN+1]; /* for incoming connections */
-char szUserNameAuthenticated[UIDBUFLEN+1];/* for incoming connections */
-char szHostName[UIDBUFLEN+1];
-char szUserName[UIDBUFLEN+1];
-static char szIP[16];
-static int validUser = AUTH_REJECT; /* User starts out invalid */
-int authentication_version = AUTHTYPE_NULL;
-int accept_complete = 0;
-
-#ifdef CK_AUTHENTICATION
-#ifdef CK_SSL
-#ifdef KRB5
-#define TLS_VERIFY
-#endif /* KRB5 */
-#endif /* CK_SSL */
-
-#ifdef CK_DES
-#ifdef CK_SSL
-#ifndef LIBDES
-#define LIBDES
-#endif /* LIBDES */
-#endif /* CK_SSL */
-#endif /* CK_DES */
-
-#ifdef CRYPT_DLL
-#ifndef LIBDES
-#define LIBDES
-#endif /* LIBDES */
-#ifdef OS2
-#ifdef NT
-#include <windows.h>
-#else /* NT */
-#define INCL_DOSMODULEMGR
-#include <os2.h>
-#endif /* NT */
-#endif /* OS2 */
-#endif /* CRYPT_DLL */
-
-#ifdef NT
-#define KRB5_AUTOCONF__
-#define NTLM
-#endif /* NT */
-
-#ifdef CK_KERBEROS
-#define KINIT
-#ifndef HEIMDAL
-#define KLIST
-#define KDESTROY
-#endif /* HEIMDAL */
-#define CHECKADDRS
-#else /* CK_KERBEROS */
-#ifdef KRB4
-#undef KRB4
-#endif /* KRB4 */
-#ifdef KRB5
-#undef KRB5
-#endif /* KRB5 */
-#ifdef KRB524
-#undef KRB524
-#endif /* KRB524 */
-#endif /* CK_KERBEROS */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <time.h>
-#include <fcntl.h>
-#include <errno.h>
-#ifndef malloc
-#ifndef VMS
-#ifndef FREEBSD4
-#ifndef OpenBSD
-#ifdef MACOSX
-#include <sys/malloc.h>
-#else /* MACOSX */
-#include <malloc.h>
-#endif /* MACOSX */
-#endif /* OpenBSD */
-#endif /* FREEBSD4 */
-#endif /* VMS */
-#endif /* malloc */
-#ifdef OS2
-#include <io.h>
-#endif /* OS2 */
-
-#ifdef KRB5
-#ifdef HEIMDAL
-#ifdef printf
-#define saveprintf printf
-#undef printf
-#endif /* printf */
-#include "krb5.h"
-
-#include "com_err.h"
-
-#ifdef saveprintf
-#define printf saveprintf
-#endif /* saveprintf */
-#else /* HEIMDAL */
-#include "krb5.h"
-#include "profile.h"
-#include "com_err.h"
-#ifdef KRB5_GET_INIT_CREDS_OPT_TKT_LIFE
-#define KRB5_HAVE_GET_INIT_CREDS
-#else
-#define krb5_free_unparsed_name(con,val) krb5_xfree((char *)(val))
-#endif
-#ifndef KRB5_HAVE_GET_INIT_CREDS
-#define krb5_free_data_contents(c,v) krb5_xfree((char *)(v)->data)
-#endif
-#endif /* HEIMDAL */
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#endif /* KRB5 */
-
-#ifdef KRB4
-#define des_cblock Block
-#define const_des_cblock const Block
-#define des_key_schedule Schedule
-#ifdef KRB524
-#ifdef NT
-#define _WINDOWS
-#endif /* NT */
-#include "kerberosIV/krb.h"
-#ifndef OS2
-#ifdef KRB524_CONV
-#include "krb524.h"
-#endif /* KRB524_CONV */
-_PROTOTYP(const char * krb_get_err_text_entry, (int));
-#endif /* OS2 */
-#else /* KRB524 */
-#ifdef SOLARIS
-#ifndef sun
-/* for some reason the Makefile entries for the Solaris systems have -Usun */
-#define sun
-#endif /* sun */
-#endif /* SOLARIS */
-#include "krb.h"
-#define krb_get_err_text_entry krb_get_err_text
-#endif /* KRB524 */
-#else /* KRB4 */
-#ifdef CK_SSL
-#define des_cblock Block
-#ifdef COMMENT
-#define const_des_cblock const Block
-#endif /* COMMENT */
-#define des_key_schedule Schedule
-#endif /* CK_SSL */
-#endif /* KRB4 */
-
-#include "ckuath.h"
-#ifdef CK_KERBEROS
-#ifndef KRB5
-#define NOBLOCKDEF
-#else /* KRB5 */
-#ifdef KRB524
-#define NOBLOCKDEF
-#endif /* KRB524 */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-#include "ckuat2.h"
-
-#ifdef CK_SSL
-#ifdef LIBDES
-#ifdef OPENSSL_097
-#ifdef CK_DES
-#define OPENSSL_ENABLE_OLD_DES_SUPPORT
-#include <openssl/des.h>
-#endif /* CK_DES */
-#endif /* OPENSSL_097 */
-#ifndef HEADER_DES_H
-#define HEADER_DES_H
-#endif /* HEADER_DES_H */
-#endif /* LIBDES */
-#include "ck_ssl.h"
-extern int ssl_finished_messages;
-#endif /* SSL */
-
-#define PWD_SZ 128
-
-#ifndef LIBDES
-#ifdef UNIX
-#define des_set_random_generator_seed(x) des_init_random_number_generator(x)
-#endif /* UNIX */
-#else /* LIBDES */
-#define des_fixup_key_parity des_set_odd_parity
-#endif /* LIBDES */
-
-#ifdef OS2
-#ifdef CK_ENCRYPTION
-#define MAP_DES
-#endif /* CK_ENCRYPTION */
-#ifdef KRB4
-#define MAP_KRB4
-#endif /* KRB4 */
-#ifdef SRPDLL
-#define MAP_SRP
-#endif /* SRPDLL */
-#ifdef KRB5
-#define MAP_KRB5
-#endif /* KRB5 */
-#ifdef CRYPT_DLL
-#define MAP_CRYPT
-#endif /* CRYPT_DLL */
-#define MAP_NTLM
-#include "ckoath.h"
-#include "ckosyn.h"
-#endif /* OS2 */
-
-/*
- * Globals
- */
-int auth_type_user[AUTHTYPLSTSZ] = {AUTHTYPE_AUTO, AUTHTYPE_NULL};
-int auth_how=0;
-int auth_crypt=0;
-int auth_fwd=0;
-
-/* These are state completion variables */
-static int mutual_complete = 0;
-
-#ifdef KRB4
-#ifdef OS2
-static LEASH_CREDENTIALS cred;
-#else /* OS2 */
-static CREDENTIALS cred;
-#endif /* OS2 */
-static KTEXT_ST k4_auth;
-static char k4_name[ANAME_SZ];
-static AUTH_DAT k4_adat = { 0 };
-static MSG_DAT k4_msg_data;
-#ifdef CK_ENCRYPTION
-static Block k4_session_key = { 0 };
-static Schedule k4_sched;
-static Block k4_challenge = { 0 };
-#ifdef MIT_CURRENT
-static krb5_keyblock k4_krbkey;
-#endif /* MIT_CURRENT */
-#endif /* ENCRYPTION */
-#define KRB4_SERVICE_NAME "rcmd"
-
-_PROTOTYP(static int k4_auth_send,(VOID));
-_PROTOTYP(static int k4_auth_reply,(unsigned char *, int));
-_PROTOTYP(static int k4_auth_is,(unsigned char *, int));
-#endif /* KRB4 */
-
-#ifdef KRB5
-static krb5_data k5_auth;
-static krb5_auth_context auth_context;
-static krb5_keyblock *k5_session_key = NULL;
-static krb5_ticket *k5_ticket = NULL;
-#ifndef KRB5_SERVICE_NAME
-#define KRB5_SERVICE_NAME "host"
-#ifdef MACOSX
-#define MIT_CURRENT 1
-#define decode_krb5_ticket krb5_decode_ticket
-#define krb5_read_message ck_krb5_read_message
-#define krb5_write_message ck_krb5_write_message
-#endif /* MACOSX */
-#endif
-
-_PROTOTYP(static int k5_auth_send,(int,int,int));
-_PROTOTYP(static int k5_auth_reply,(int, unsigned char *, int));
-_PROTOTYP(static int k5_auth_is,(int,unsigned char *, int));
-_PROTOTYP(static int SendK5AuthSB,(int, void *, int));
-#ifdef TLS_VERIFY
-static int krb5_tls_verified = 0;
-#endif /* TLS_VERIFY */
-#endif /* KRB5 */
-
-#ifdef GSSAPI_KRB5
-#include <gssapi/gssapi.h>
-#include <gssapi/gssapi_generic.h>
-#include <gssapi/gssapi_krb5.h>
-
-static gss_ctx_id_t gcontext;
-#define GSS_BUFSIZ 4096
-static gss_buffer_desc gss_send_tok, gss_recv_tok, *gss_token_ptr;
-static char gss_stbuf[GSS_BUFSIZ];
-static gss_name_t gss_target_name;
-static struct gss_channel_bindings_struct gss_chan;
-
-_PROTOTYP(static int gssk5_auth_send,(int,int,int));
-_PROTOTYP(static int gssk5_auth_reply,(int, unsigned char *, int));
-_PROTOTYP(static int gssk5_auth_is,(int,unsigned char *, int));
-_PROTOTYP(static int SendGSSK5AuthSB,(int, void *, int));
-#endif /* GSSAPI_KRB5 */
-
-#ifdef CK_SRP
-#ifdef PRE_SRP_1_7_3
-_PROTOTYP(static int srp_reply,(int, unsigned char *, int));
-_PROTOTYP(static int srp_is,(int, unsigned char *, int));
-#else /* PRE_SRP_1_7_3 */
-_PROTOTYP(static int new_srp_reply,(int, unsigned char *, int));
-_PROTOTYP(static int new_srp_is,(int, unsigned char *, int));
-#endif /* PRE_SRP_1_7_3 */
-#endif /* SRP */
-
-#ifdef CK_ENCRYPTION
-int encrypt_flag = 1;
-#endif
-#ifdef FORWARD
-int forward_flag = 0; /* forward tickets? */
-int forwardable_flag = 1; /* get forwardable tickets to forward? */
-int forwarded_tickets = 0; /* were tickets forwarded? */
-#endif
-
-static unsigned char str_data[4096] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
- AUTHTYPE_KERBEROS_V5, };
-#define AUTHTMPBL 2048
-static char strTmp[AUTHTMPBL+1];
-static char szLocalHostName[UIDBUFLEN+1];
-static kstream g_kstream=NULL;
-
-#ifdef KRB5
-krb5_context k5_context=NULL;
-static krb5_creds * ret_cred=NULL;
-static krb5_context telnet_context=NULL;
-static char * telnet_krb5_realm = NULL;
-static krb5_principal fwd_server = NULL;
-#endif /* KRB5 */
-
-#ifdef CK_SRP
-#ifdef PRE_SRP_1_4_4
-#ifndef PRE_SRP_1_4_5
-#define PRE_SRP_1_4_5
-#endif /* PRE_SRP_1_4_5 */
-#endif /* PRE_SRP_1_4_5 */
-#ifdef PRE_SRP_1_4_5
-#ifndef PRE_SRP_1_7_3
-#define PRE_SRP_1_7_3
-#endif /* PRE_SRP_1_7_3 */
-#endif /* PRE_SRP_1_4_5 */
-#include <t_pwd.h>
-#include <t_client.h>
-#include <t_server.h>
-static struct t_server * ts = NULL;
-static struct t_client * tc = NULL;
-#ifdef PRE_SRP_1_4_4
-static struct t_pw * tpw = NULL;
-static struct t_conf * tconf = NULL;
-#endif /* PRE_SRP_1_4_4 */
-#ifndef PRE_SRP_1_7_3
-#ifndef STDC_HEADERS
-#define STDC_HEADERS 1
-#endif /* STDC_HEADERS */
-#include <srp.h>
-static SRP * s_srp = NULL;
-static cstr * s_key = NULL;
-static SRP * c_srp = NULL;
-static cstr * c_key = NULL;
-#endif /* PRE_SRP_1_7_3 */
-static int srp_waitresp = 0; /* Flag to indicate readiness for response */
-static char srp_passwd[PWD_SZ];
-#endif /* CK_SRP */
-
-#ifdef CK_KERBEROS
-#ifdef RLOGCODE
-#define OPTS_FORWARD_CREDS 0x00000020
-#define OPTS_FORWARDABLE_CREDS 0x00000010
-#define KCMD_KEYUSAGE 1026
-
-#define RLOG_BUFSIZ 5120
-static int rlog_encrypt = 0;
-char des_inbuf[2*RLOG_BUFSIZ]; /* needs to be > largest read size */
-char des_outpkt[2*RLOG_BUFSIZ+4]; /* needs to be > largest write size */
-#ifdef KRB5
-krb5_data desinbuf,desoutbuf;
-krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */
-static krb5_data encivec_i[2], encivec_o[2];
-
-enum krb5_kcmd_proto {
- /* Old protocol: DES encryption only. No subkeys. No protection
- for cleartext length. No ivec supplied. OOB hacks used for
- rlogin. Checksum may be omitted at connection startup. */
- KCMD_OLD_PROTOCOL = 1,
- /* New protocol: Any encryption scheme. Client-generated subkey
- required. Prepend cleartext-length to cleartext data (but don't
- include it in count). Starting ivec defined, chained. In-band
- signalling. Checksum required. */
- KCMD_NEW_PROTOCOL,
- /* Hack: Get credentials, and use the old protocol iff the session
- key type is single-DES. */
- KCMD_PROTOCOL_COMPAT_HACK,
- KCMD_UNKNOWN_PROTOCOL
-};
-enum krb5_kcmd_proto krb5_rlog_ver = KCMD_PROTOCOL_COMPAT_HACK;
-#endif /* KRB5 */
-#endif /* RLOGCODE */
-static char storage[65536]; /* storage for the decryption */
-static int nstored = 0;
-static char *store_ptr = storage;
-
-extern char * krb5_d_principal; /* Default principal */
-extern char * krb5_d_instance; /* Default instance */
-extern char * krb5_d_realm; /* Default realm */
-extern char * krb5_d_cc; /* Default credentials cache */
-extern char * krb5_d_srv; /* Default service name */
-extern int krb5_d_lifetime; /* Default lifetime */
-extern int krb5_d_forwardable;
-extern int krb5_d_proxiable;
-extern int krb5_d_renewable;
-extern int krb5_autoget;
-extern int krb5_checkaddrs;
-extern int krb5_d_getk4;
-extern int krb5_d_no_addresses;
-extern char * k5_keytab;
-
-extern int krb5_errno;
-extern char * krb5_errmsg;
-
-extern char * krb4_d_principal; /* Default principal */
-extern char * krb4_d_realm; /* Default realm */
-extern char * krb4_d_srv; /* Default service name */
-extern int krb4_d_lifetime; /* Default lifetime */
-extern int krb4_d_preauth;
-extern char * krb4_d_instance;
-extern int krb4_autoget;
-extern int krb4_checkaddrs;
-extern char * k4_keytab;
-
-extern int krb4_errno;
-extern char * krb4_errmsg;
-#endif /* CK_KERBEROS */
-
-extern char tn_msg[], hexbuf[]; /* from ckcnet.c */
-extern CHAR pwbuf[];
-extern int pwflg, pwcrypt;
-extern int deblog, debses, tn_deb;
-extern int sstelnet, inserver;
-#ifdef CK_LOGIN
-extern int ckxanon;
-#endif /* CK_LOGIN */
-extern int tn_auth_how;
-extern int tn_auth_enc;
-#ifdef CK_ENCRYPTION
-extern int cx_type;
-#endif /* CK_ENCRYPTION */
-extern int quiet, ttyfd, ttnproto;
-
-int
-ck_gssapi_is_installed()
-{
-#ifdef KRB5
-#ifdef OS2
- return(hGSSAPI != NULL);
-#else /* OS2 */
- return(1);
-#endif /* OS2 */
-#else /* KRB5 */
- return(0);
-#endif /* KRB5 */
-}
-
-int
-ck_krb5_is_installed()
-{
-#ifdef KRB5
-#ifdef OS2
- return(hKRB5_32 != NULL);
-#else /* OS2 */
- return(1);
-#endif /* OS2 */
-#else /* KRB5 */
- return(0);
-#endif /* KRB5 */
-}
-
-
-int
-ck_krb5_is_installed_as_server()
-{
-#ifdef KRB5
-#ifdef HEIMDAL
- krb5_error_code ret;
- krb5_keytab kt;
- krb5_kt_cursor cursor;
-
- ret = krb5_kt_default(k5_context, &kt);
- if ( ret ) {
- krb5_kt_close(k5_context, kt);
- return(0);
- } else {
- krb5_kt_end_seq_get(k5_context, kt, &cursor);
- krb5_kt_close(k5_context, kt);
- return(1);
- }
-#else /* HEIMDAL */
-#ifndef COMMENT
- char ktname[CKMAXPATH]="";
-
- if ( k5_keytab ) {
- ckstrncpy(ktname,k5_keytab,CKMAXPATH);
- } else {
- krb5_error_code code;
-
- if ( k5_context == NULL)
- if (krb5_init_context(&k5_context))
- return(0);
-
- code = krb5_kt_default_name(k5_context,ktname,CKMAXPATH);
- debug(F101,"krb5_kt_default_name","",code);
- if ( code ) {
- /* We can't check the existence of the file since we can't */
- /* determine the file name. So we return TRUE and let */
- /* Krb5 be offered to the user even though it may fail later */
- return(1);
- }
- }
-
- if ( !strncmp("FILE:",ktname,5) ) {
- if ( zchki(&ktname[5]) > 0 )
- return(1);
- else
- return(0);
- } else {
- if (ktname[0])
- return(1);
- else
- return(0);
- }
-#else /* COMMENT */
- krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC;
- krb5_context krb5context = NULL;
- krb5_ccache krb5ccdef = NULL;
- krb5_creds krb5creds, *krb5credsp = NULL;
- int rc = 0;
-
- if ( !ck_krb5_is_installed() )
- return(0);
-
- memset((char *)&krb5creds, 0, sizeof(krb5creds));
-
- if ((krb5rc = krb5_init_context(&krb5context)) != 0)
- goto err;
-
- if ((krb5rc = krb5_sname_to_principal(krb5context,
- szHostName,
- krb5_d_srv ?
- krb5_d_srv :
- KRB5_SERVICE_NAME,
- KRB5_NT_SRV_HST,
- &krb5creds.server)) != 0)
- goto err;
-
- if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)
- goto err;
-
- if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
- &krb5creds.client)) != 0)
- goto err;
-
- if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
- &krb5creds, &krb5credsp)) != 0)
- goto err;
- rc = 1;
-
- err:
-
- if (krb5creds.client)
- krb5_free_principal(krb5context, krb5creds.client);
- if (krb5creds.server)
- krb5_free_principal(krb5context, krb5creds.server);
- if (krb5context)
- krb5_free_context(krb5context);
- return(rc);
-
-#endif /* COMMENT */
-#endif /* HEIMDAL */
-#else /* KRB5 */
- return(0);
-#endif /* KRB5 */
-}
-
-int
-ck_krb4_is_installed()
-{
-#ifdef KRB4
-#ifdef OS2
- return(hKRB4_32 != NULL);
-#else /* OS2 */
- return(1);
-#endif /* OS2 */
-#else /* KRB4 */
- return(0);
-#endif /* KRB4 */
-}
-
-int
-ck_krb4_is_installed_as_server()
-{
- if ( !ck_krb4_is_installed() )
- return(0);
-
-#ifdef KRB4
- if ( !k4_keytab ) {
-#ifdef NT
- char name[CKMAXPATH]="";
- DWORD len = CKMAXPATH;
-
- len = GetWindowsDirectory(name,len);
- if ( len > 0 )
- ckstrncat(name,"/srvtab",CKMAXPATH);
- if ( name[0] )
- makestr(&k4_keytab,name);
-#else /* NT */
- makestr(&k4_keytab,"/etc/srvtab");
-#endif /* NT */
- }
-
- if ( !k4_keytab )
- return(0);
-
- if ( zchki(k4_keytab) > 0 )
- return(1);
-#ifdef KRB524
- else if (ck_krb5_is_installed_as_server())
- return(1);
-#endif /* KRB524 */
- else
- return(0);
-#endif /* KRB4 */
-}
-
-int
-ck_srp_is_installed_as_server()
-{
-#ifdef CK_SRP
-#ifdef SRPDLL
- if ( hSRP == NULL )
- return(0);
-#endif /* SRPDLL */
-#ifdef COMMENT
- /* This is the new API as of 1.7.4. However, all it does
- is allocate a data structure. It can never fail.
- */
- {
- SRP * s_srp = SRP_new(SRP_RFC2945_server_method());
- if ( s_srp ) {
- SRP_free(s_srp);
- s_srp = NULL;
- return(1);
- }
- return(0);
- }
-#else /* COMMENT */
- {
- struct t_pw * tpw = NULL;
- struct t_conf * tconf = NULL;
- if((tconf = t_openconf(NULL)) == NULL)
- return(0);
- if((tpw = t_openpw(NULL)) == NULL) {
- t_closeconf(tconf);
- return(0);
- }
- t_closeconf(tconf);
- t_closepw(tpw);
- return(1);
- }
-#endif /* COMMENT */
-#else /* SRP */
- return(0);
-#endif /* SRP */
-}
-
-int
-ck_srp_is_installed()
-{
-#ifdef CK_SRP
-#ifdef SRPDLL
- if ( hSRP == NULL )
- return(0);
-#endif /* SRPDLL */
- return(1);
-#else /* CK_SRP */
- return(0);
-#endif /* CK_SRP */
-}
-
-int
-ck_krypto_is_installed()
-{
-#ifdef CK_SRP
-#ifdef OS2
- if ( hLIBKRYPTO == NULL )
- return(0);
-#endif /* OS2 */
- return(1);
-#else /* CK_SRP */
- return(0);
-#endif /* CK_SRP */
-}
-
-int
-ck_crypt_is_installed()
-{
-#ifdef CK_ENCRYPTION
-#ifdef CRYPT_DLL
- return(hCRYPT != NULL);
-#else /* CRYPT_DLL */
- return(1);
-#endif /* CRYPT_DLL */
-#else /* ENCRYPTION */
- return(0);
-#endif /* ENCRYPTION */
-}
-
-int
-ck_ntlm_is_installed()
-{
-#ifdef NT
- return(hSSPI != NULL);
-#else /* NT */
- return(0);
-#endif /* NT */
-}
-
-int
-ck_tn_auth_valid()
-{
- return(validUser);
-}
-
-/* C K _ K R B _ A U T H _ I N _ P R O G R E S S
- *
- * Is an authentication negotiation still in progress?
- *
- */
-
-int
-#ifdef CK_ANSIC
-ck_tn_auth_in_progress(void)
-#else
-ck_tn_auth_in_progress()
-#endif
-{
- switch (authentication_version) {
- case AUTHTYPE_AUTO:
- return(1);
- case AUTHTYPE_NULL:
- return(0);
-#ifdef KRB4
- case AUTHTYPE_KERBEROS_V4:
- if (!accept_complete) {
- debug(F100,"ck_auth_in_progress() Kerberos 4 !accept_complete",
- "",0);
- return(1);
- }
- else if ((auth_how & AUTH_HOW_MASK) && !mutual_complete) {
- debug(F100,"ck_auth_in_progress() Kerberos 4 !mutual_complete",
- "",0);
- return(1);
- }
- else
- return(0);
-#endif /* KRB4 */
-#ifdef KRB5
- case AUTHTYPE_KERBEROS_V5:
- if (!accept_complete) {
- debug(F100,"ck_auth_in_progress() Kerberos 5 !accept_complete",
- "",0);
- return(1);
- }
- else if ((auth_how & AUTH_HOW_MASK) && !mutual_complete) {
- debug(F100,"ck_auth_in_progress() Kerberos 5 !mutual_complete",
- "",0);
- return(1);
- }
- else
- return(0);
-#ifdef GSSAPI_K5
- case AUTHTYPE_GSSAPI_KRB5:
- if (!accept_complete) {
- debug(F100,
- "ck_auth_in_progress() GSSAPI Kerberos 5 !accept_complete",
- "",
- 0
- );
- return(1);
- }
- else if ((auth_how & AUTH_HOW_MASK) && !mutual_complete) {
- debug(F100,
- "ck_auth_in_progress() GSSAPI Kerberos 5 !mutual_complete",
- "",
- 0
- );
- return(1);
- } else
- return(0);
- break;
-#endif /* GSSAPI_K5 */
-#endif /* KRB5 */
-#ifdef CK_SRP
- case AUTHTYPE_SRP:
- if (!accept_complete || srp_waitresp)
- return(1);
- else
- return(0);
-#endif /* CK_SRP */
-#ifdef NTLM
- case AUTHTYPE_NTLM:
- if (!accept_complete) {
- debug(F100,"ck_auth_in_progress() NTLM !accept_complete",
- "",0);
- return(1);
- }
- else
- return(0);
-#endif /* NTLM */
- case AUTHTYPE_SSL:
- if (!accept_complete) {
- debug(F100,"ck_auth_in_progress() SSL !accept_complete",
- "",0);
- return(1);
- }
- else
- return(0);
- default:
- return(0);
- }
- return(0);
-}
-
-
-/* C K _ K R B _ T N _ A U T H _ R E Q U E S T
- *
- * Builds a Telnet Authentication Send Negotiation providing the
- * list of supported authentication methods. To be used only
- * when accepting incoming connections as only the server (DO) side of the
- * Telnet negotiation is allowed to send an AUTH SEND.
- *
- * Returns: 0 on success and -1 on failure
- */
-
-static unsigned char str_request[64] = { IAC, SB,
- TELOPT_AUTHENTICATION,
- TELQUAL_SEND };
-#ifdef GSSAPI_K5
-static int
-ck_tn_auth_request_gsskrb5(int i)
-{
- if (ck_gssapi_is_installed() && ck_krb5_is_installed_as_server()) {
- if ( (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_EXCH) ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_AFTER_EXCHANGE;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,
- "KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT_AFTER_EXCHANGE ",
- TN_MSG_LEN);
- i++;
- }
- }
-}
-#endif /* GSSAPI_K5 */
-
-#ifdef KRB5
-static int
-ck_tn_auth_request_krb5(int i)
-{
- if (ck_krb5_is_installed_as_server()) {
-#ifdef CK_SSL
- if ( ck_ssleay_is_installed() &&
- (tls_active_flag || ssl_active_flag) &&
- ssl_finished_messages )
- {
-#ifdef USE_INI_CRED_FWD
- if ( forward_flag &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT)
- )
- {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_START_TLS;
- str_request[i] |= INI_CRED_FWD_ON;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,
- "KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT_START_TLS|INI_CRED_FWD_ON ",
- TN_MSG_LEN);
- i++;
- }
-#endif /* USE_INI_CRED_FWD */
- if ( (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_START_TLS;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,
- "KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT_START_TLS ",
- TN_MSG_LEN);
- i++;
- }
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_START_TLS;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,
- "KERBEROS_V5 CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_START_TLS ",
- TN_MSG_LEN);
- i++;
- }
- }
-#ifdef CK_ENCRYPTION
- else
- {
-#endif /* CK_ENCRYPTION */
-#endif /* CK_SSL */
-#ifdef CK_ENCRYPTION
-#ifdef USE_INI_CRED_FWD
- if ( forward_flag &&
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT)
- )
- {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
- str_request[i] |= INI_CRED_FWD_ON;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,
- "KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT_USING_TELOPT|INI_CRED_FWD_ON ",
- TN_MSG_LEN);
- i++;
- }
-#endif /* USE_INI_CRED_FWD */
-
- if ( TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,
- "KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT_USING_TELOPT ",
- TN_MSG_LEN);
- i++;
- }
-#ifdef CK_SSL
- }
-#endif /* CK_SSL */
-#endif /* CK_ENCRYPTION */
-
- if ( TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE)
-#ifdef CK_SSL
- && !(ck_ssleay_is_installed() &&
- (tls_active_flag || ssl_active_flag) &&
- tls_is_anon(0))
-#endif /* CK_SSL */
- )
- {
-#ifdef CK_ENCRYPTION
- /* Can't perform mutual authentication without encryption */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_OFF;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL ",
- TN_MSG_LEN);
- i++;
- }
-#endif /* CK_ENCRYPTION */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|ONE_WAY ",
- TN_MSG_LEN);
- i++;
- }
- }
- }
- return(i);
-}
-#endif /* KRB5 */
-#ifdef KRB4
-static int
-ck_tn_auth_request_krb4(int i)
-{
- if (ck_krb4_is_installed_as_server()) {
-#ifdef CK_ENCRYPTION
- if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) )
- {
- str_request[i++] = AUTHTYPE_KERBEROS_V4;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ",
- TN_MSG_LEN);
- i++;
- }
-#endif /* CK_ENCRYPTION */
-
- if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
-#ifdef CK_ENCRYPTION
- /* Can't perform mutual authentication without encryption */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V4;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_OFF;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL ",
- TN_MSG_LEN);
- i++;
- }
-#endif /* CK_ENCRYPTION */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V4;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|ONE_WAY ",
- TN_MSG_LEN);
- i++;
- }
- }
- }
-
- return(i);
-}
-#endif /* KRB4 */
-
-#ifdef CK_SRP
-static int
-ck_tn_auth_request_srp(int i)
-{
- if (ck_srp_is_installed_as_server()) {
-#ifndef PRE_SRP_1_4_5
- /* Dont' do this yet. SRP when it uses the ENCRYPT_USING_TELOPT */
- /* flag it must perform a checksum of the auth-type-pair but there */
- /* is no mechansim to do that yet. */
-#ifdef CK_SSL
- if ( ck_ssleay_is_installed() &&
- (tls_active_flag || ssl_active_flag) &&
- ssl_finished_messages &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT))
- {
- str_request[i++] = AUTHTYPE_SRP;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_START_TLS;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,
- "SRP CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_START_TLS ",
- TN_MSG_LEN);
- i++;
- }
-#ifdef CK_ENCRYPTION
- else {
-#endif /* CK_ENCRYPTION */
-#endif /* CK_SSL */
-#ifdef CK_ENCRYPTION
- if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT)
- ) {
- str_request[i++] = AUTHTYPE_SRP;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,
- "SRP CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_USING_TELOPT ",
- TN_MSG_LEN);
- i++;
- }
-#ifdef CK_SSL
- }
-#endif /* CK_SSL */
-#endif /* CK_ENCRYPTION */
-#endif /* PRE_SRP_1_4_5 */
- if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE)
-#ifdef CK_SSL
- && !(ck_ssleay_is_installed() &&
- (tls_active_flag || ssl_active_flag) &&
- tls_is_anon(0))
-#endif /* CK_SSL */
- )
- {
- str_request[i++] = AUTHTYPE_SRP;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
-
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,"SRP CLIENT_TO_SERVER|ONE_WAY ",
- TN_MSG_LEN);
- i++;
- }
- }
-
- return(i);
-}
-#endif /* CK_SRP */
-
-#ifdef CK_SSL
-static int
-ck_tn_auth_request_ssl(int i)
-{
- if (ck_ssleay_is_installed()
- && !tls_active_flag && !ssl_active_flag && ssl_initialized
- ) {
- if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- str_request[i++] = AUTHTYPE_SSL;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,"SSL CLIENT_TO_SERVER|ONE_WAY ",
- TN_MSG_LEN);
- i++;
- }
- }
-
- return(i);
-}
-#endif /* CK_SSL */
-#ifdef NTLM
-static int
-ck_tn_auth_request_ntlm(int i)
-{
- /* Microsoft's Telnet client won't perform authentication if */
- /* NTLM is not first. */
- if ( ck_ntlm_is_valid(1) ) {
- if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- str_request[i++] = AUTHTYPE_NTLM;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- ckstrncat(tn_msg,"NTLM CLIENT_TO_SERVER|ONE_WAY ",
- TN_MSG_LEN);
- i++;
- }
- }
-
- return(i);
-}
-#endif /* NTLM */
-int
-#ifdef CK_ANSIC
-ck_tn_auth_request(void)
-#else
-ck_tn_auth_request()
-#endif
-{
- int i = 4, rc = -1;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
-#endif /* CK_SSL */
-
- if ( deblog || tn_deb || debses )
- strcpy(tn_msg,"TELNET SENT SB AUTHENTICATION SEND ");
-
- /* Create a list of acceptable Authentication types to send to */
- /* the client and let it choose find one that we support */
-
- /* For those authentication methods that support Encryption or */
- /* Credentials Forwarding we must send all of the appropriate */
- /* combinations based upon the state of */
- /* TELOPT_x_MODE(TELOPT_ENCRYPTION) and forward_flag. */
-
- if ( auth_type_user[0] == AUTHTYPE_AUTO ) {
-#ifdef GSSAPI_K5
- i = ck_tn_auth_request_gsskrb5(i);
-#endif /* GSSAPI_K5 */
-#ifdef KRB5
- i = ck_tn_auth_request_krb5(i);
-#endif /* KRB5 */
-#ifdef KRB4
- i = ck_tn_auth_request_krb4(i);
-#endif /* KRB4 */
-#ifdef CK_SRP
- i = ck_tn_auth_request_srp(i);
-#endif /* SRP */
-#ifdef CK_SSL
- i = ck_tn_auth_request_ssl(i);
-#endif /* CK_SSL */
-#ifdef NTLM
- i = ck_tn_auth_request_ntlm(i);
-#endif /* NTLM */
- } else {
- int j;
- for ( j=0;
- j<AUTHTYPLSTSZ && auth_type_user[j] != AUTHTYPE_NULL;
- j++) {
-#ifdef NTLM
- if (auth_type_user[j] == AUTHTYPE_NTLM)
- i = ck_tn_auth_request_ntlm(i);
-#endif /* NTLM */
-#ifdef CK_SSL
- if ( auth_type_user[j] == AUTHTYPE_SSL )
- i = ck_tn_auth_request_ssl(i);
-#endif /* CK_SSL */
-#ifdef CK_SRP
- if ( auth_type_user[j] == AUTHTYPE_SRP )
- i = ck_tn_auth_request_srp(i);
-#endif /* SRP */
-#ifdef GSSAPI_K5
- if ( auth_type_user[j] == AUTHTYPE_GSSAPI_KRB5 )
- i = ck_tn_auth_request_gsskrb5(i);
-#endif /* GSSAPI_K5 */
-#ifdef KRB5
- if ( auth_type_user[j] == AUTHTYPE_KERBEROS_V5 )
- i = ck_tn_auth_request_krb5(i);
-#endif /* KRB5 */
-#ifdef KRB4
- if ( auth_type_user[j] == AUTHTYPE_KERBEROS_V4 )
- i = ck_tn_auth_request_krb4(i);
-#endif /* KRB4 */
- }
- }
-
- str_request[i++] = IAC;
- str_request[i++] = SE;
- if ( deblog || tn_deb || debses ) {
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-
- /* Send data */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- rc = ttol((CHAR *)str_request, i);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- if ( rc == i )
- return(0);
- else
- return(-1);
-}
-
-#ifdef CK_ENCRYPTION
-VOID
-ck_tn_enc_start()
-{
- if (!TELOPT_ME(TELOPT_ENCRYPTION) && !TELOPT_U(TELOPT_ENCRYPTION))
- return;
- if (!TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop &&
- (!encrypt_is_decrypting() || !encrypt_is_encrypting())) {
- debug(F110,"ck_tn_enc_start","nothing to do",0);
- return;
- }
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 0;
- if (TELOPT_ME(TELOPT_ENCRYPTION) && !encrypt_is_encrypting()) {
- debug(F110,"ck_tn_enc_start","encrypt_request_start",0);
- encrypt_request_start();
- }
- if (TELOPT_U(TELOPT_ENCRYPTION) && !encrypt_is_decrypting()) {
- debug(F110,"ck_tn_enc_start","encrypt_send_request_start",0);
- encrypt_send_request_start();
- }
- tn_wait("encrypt start");
- tn_push();
-}
-
-VOID
-ck_tn_enc_stop()
-{
- if (!TELOPT_ME(TELOPT_ENCRYPTION) && !TELOPT_U(TELOPT_ENCRYPTION))
- return;
- if (TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop ||
- !(encrypt_is_decrypting() || encrypt_is_encrypting())) {
- debug(F110,"ck_tn_enc_stop","nothing to do",0);
- return;
- }
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 1;
- if (TELOPT_U(TELOPT_ENCRYPTION) && encrypt_is_decrypting()) {
- debug(F110,"ck_tn_enc_stop","encrypt_send_request_end",0);
- encrypt_send_request_end();
- }
- if (TELOPT_ME(TELOPT_ENCRYPTION) && encrypt_is_encrypting()) {
- debug(F110,"ck_tn_enc_stop","encrypt_send_end",0);
- encrypt_send_end();
- }
- tn_wait("encrypt stop");
- tn_push();
-}
-#endif /* CK_ENCRYPTION */
-
-/* C K _ K R B _ T N _ S B _ A U T H
- * An interface between the C-Kermit Telnet Command Parser and the Authent-
- * ication option parser implemented in the Kerberos Telnet client.
- *
- * sb - the subnegotiation as calculated in ckcnet.c
- * len - the length of the buffer
- *
- * Returns: 0 on success and -1 on failure
- */
-
-int
-#ifdef CK_ANSIC
-ck_tn_sb_auth(char * sb, int len)
-#else /* CK_ANSIC */
-ck_tn_sb_auth(sb,len) char * sb; int len;
-#endif /* CK_ANSIC */
-{
- /* auth_parse() assumes that sb starts at pos 1 not 0 as in ckcnet.c */
- /* and it wants the length to exclude the IAC SE bytes */
- CHAR * buf;
- int rc = -1;
-
- buf = malloc(len-1);
- if ( !buf ) return(-1);
-
- buf[0] = SB;
- memcpy( &buf[1], sb, len-2 );
- rc = auth_parse(buf,len-1);
- free(buf);
- debug(F111,"ck_tn_sb_auth","rc",rc);
- if (rc == AUTH_FAILURE) {
- authentication_version = AUTHTYPE_NULL;
-#ifndef NOLOCAL
-#ifdef OS2
- ipadl25();
-#endif /* OS2 */
-#endif /* NOLOCAL */
- return(-1);
- }
-#ifndef NOLOCAL
-#ifdef OS2
- ipadl25();
-#endif /* OS2 */
-#endif /* NOLOCAL */
- return(0);
-}
-
-/* C K _ K R B _ T N _ S B _ E N C R Y P T
- * An interface between the C-Kermit Telnet Command Parser and the Encryption
- * option parser implemented in the Kerberos Telnet client.
- *
- * sb - the subnegotiation as calculated in ckcnet.c
- * len - the length of the buffer
- *
- * Returns: Always returns 0 for success since encrypt_parse is void
- */
-
-
-int
-#ifdef CK_ANSIC
-ck_tn_sb_encrypt(char * sb, int len)
-#else
-ck_tn_sb_encrypt(sb,len) char * sb; int len;
-#endif /* CK_ANSIC */
-{
- /* encrypt_parse() assumes that sb starts at pos 1 not 0 as in ckcnet.c */
- /* and it wants the length to exclude the IAC SE bytes */
-#ifdef CK_ENCRYPTION
- char * buf;
- int rc = -1;
-
- buf = malloc(len-1);
- if ( !buf ) return(-1);
-
- buf[0] = SB;
- memcpy( &buf[1], sb, len-2 );
- rc = encrypt_parse((CHAR *)buf,len-1);
-
- if (rc < 0) {
- free(buf);
- return(-1);
- }
-
- /* This is a hack. It does not belong here but should really be in */
- /* encrypt_parse() but in K95 the encrypt_parse() routine does not */
- /* have access to the telopt_states array. */
- if ( buf[1] == ENCRYPT_REQEND )
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 1;
- else if ( buf[1] == ENCRYPT_REQSTART )
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 0;
-#ifndef NOLOCAL
-#ifdef OS2
- ipadl25();
-#endif /* OS2 */
-#endif /* NOLOCAL */
- free(buf);
-#endif /* ENCRYPTION */
- return(0);
-}
-
-
-/* C K _ K R B _ E N C R Y P T I N G
- * Returns 1 if we are encrypting and 0 if we are not
- */
-
-int
-#ifdef CK_ANSIC
-ck_tn_encrypting(VOID)
-#else /* CK_ANSIC */
-ck_tn_encrypting()
-#endif /* CK_ANSIC */
-{
-#ifdef CK_ENCRYPTION
- if ( g_kstream == NULL )
- return(0);
- if ( g_kstream->encrypt && encrypt_is_encrypting()) {
- debug(F111,"ck_tn_encrypting","encrypting",
- g_kstream->encrypt_type);
- return(g_kstream->encrypt_type);
- }
-#endif /* CK_ENCRYPTION */
- debug(F110,"ck_tn_encrypting","not encrypting",0);
- return(0);
-}
-
-/* C K _ K R B _ D E C R Y P T I N G
- * Returns 1 if we are decrypting and 0 if we are not
- */
-
-int
-#ifdef CK_ANSIC
-ck_tn_decrypting(VOID)
-#else
-ck_tn_decrypting()
-#endif /* CK_ANSIC */
-{
-#ifdef CK_ENCRYPTION
- if ( g_kstream == NULL )
- return(0);
- if ( g_kstream->decrypt && encrypt_is_decrypting()) {
- debug(F111,"ck_tn_decrypting","decrypting",
- g_kstream->decrypt_type);
- return(g_kstream->decrypt_type);
- }
-#endif /* CK_ENCRYPTION */
- debug(F110,"ck_tn_decrypting","not decrypting",0);
- return(0);
-}
-
-/* C K _ K R B _ A U T H E N T I C A T E D
- * Returns the authentication type: AUTHTYPE_NULL, AUTHTYPE_KERBEROS4,
- * or AUTHTYPE_KERBEROS5, AUTHTYPE_SRP, ... (see ckctel.h)
- */
-
-int
-#ifdef CK_ANSIC
-ck_tn_authenticated(VOID)
-#else
-ck_tn_authenticated()
-#endif
-{
- return(authentication_version);
-}
-
-/* C K _ K R B _ E N C R Y P T
- * encrypts n characters in s if we are encrypting
- */
-
-VOID
-#ifdef CK_ANSIC
-ck_tn_encrypt( char * s, int n )
-#else
-ck_tn_encrypt( s,n ) char * s; int n;
-#endif
-{
-#ifdef CK_ENCRYPTION
- struct kstream_data_block i;
-
- if (g_kstream->encrypt && encrypt_is_encrypting()) {
-#ifdef DEBUG
- ckhexdump("from plaintext", s, n);
-#endif
- i.ptr = s;
- i.length = n;
- g_kstream->encrypt(&i, NULL);
-#ifdef DEBUG
- ckhexdump("to cyphertext", s, n);
-#endif
- }
- else debug(F101,"ck_tn_encrypt not encrypting","",n);
-#endif /* ENCRYPTION */
-}
-
-/* C K _ K R B _ D E C R Y P T
- * decrypts n characters in s if we are decrypting
- */
-
-VOID
-#ifdef CK_ANSIC
-ck_tn_decrypt( char * s, int n )
-#else
-ck_tn_decrypt( s,n ) char * s; int n;
-#endif
-{
-#ifdef CK_ENCRYPTION
- struct kstream_data_block i;
-
- if (g_kstream->decrypt && encrypt_is_decrypting()) {
-
-#ifdef DEBUG
- ckhexdump("from cyphertext", s, n);
-#endif
-
- i.ptr = s;
- i.length = n;
- g_kstream->decrypt(&i, NULL);
-#ifdef DEBUG
- ckhexdump("to plaintext", s, n);
-#endif
- }
- else debug(F101,"ck_tn_decrypt not decrypting","",n);
-#endif /* ENCRYPTION */
-}
-
-/* S E N D K 5 A U T H S B
- * Send a Kerberos 5 Authentication Subnegotiation to host and
- * output appropriate Telnet Debug messages
- *
- * type - Sub Negotiation type
- * data - ptr to buffer containing data
- * len - len of buffer if not NUL terminated
- *
- * returns number of characters sent or error value
- */
-
-static int
-#ifdef CK_ANSIC
-SendK5AuthSB(int type, void *data, int len)
-#else
-SendK5AuthSB(type,data,len) int type; void *data; int len;
-#endif
-{
- int rc;
- unsigned char *p = str_data + 3;
- unsigned char *cd = (unsigned char *)data;
- extern int sstelnet;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- if (ttchk() < 0)
- return(0);
- else
- return(1);
- }
-#endif /* CK_SSL */
-
- if ( type < 0 || type > 7 ) /* Check for invalid values */
- return(0);
-
- if (!cd) {
- cd = (unsigned char *)"";
- len = 0;
- }
-
- if (len == -1) /* Use strlen() for len */
- len = strlen((char *)cd);
-
- /* Construct Message */
- *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
- *p++ = AUTHTYPE_KERBEROS_V5;
- *p = AUTH_CLIENT_TO_SERVER;
- *p |= auth_how;
-#ifdef CK_ENCRYPTION
- *p |= auth_crypt;
-#endif
-#ifdef USE_INI_CRED_FWD
- if (auth_fwd)
- *p |= INI_CRED_FWD_ON;
-#endif /* USE_INI_CRED_FWD */
- p++;
- *p++ = type;
- while (len-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
-
- /* Handle Telnet Debugging Messages */
- if (deblog || tn_deb || debses) {
- int i;
- int deblen=p-str_data-2;
- char *s=NULL;
- int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
- auth_crypt
-#ifdef USE_INI_CRED_FWD
- | (auth_fwd?INI_CRED_FWD_ON:INI_CRED_FWD_OFF)
-#endif /* USE_INI_CRED_FWD */
- ;
-
- switch (type) {
- case 0:
- s = "AUTH";
- break;
- case 1:
- s = "REJECT";
- break;
- case 2:
- s = "ACCEPT";
- break;
- case 3:
- s = "RESPONSE";
- break;
- case 4:
- s = "FORWARD";
- break;
- case 5:
- s = "FORWARD_ACCEPT";
- break;
- case 6:
- s = "FORWARD_REJECT";
- break;
- case 7:
- s = "TLS_VERIFY";
- break;
- }
-
- ckmakxmsg(tn_msg,TN_MSG_LEN,
- "TELNET SENT SB ",
- TELOPT(TELOPT_AUTHENTICATION)," ",
- str_data[3] == TELQUAL_IS ? "IS" :
- str_data[3] == TELQUAL_REPLY ? "REPLY" : "???"," ",
- AUTHTYPE_NAME(authentication_version)," ",
- AUTHMODE_NAME(mode)," ",
- s," ",NULL);
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_data[7],deblen-7);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-
- /* Send data */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- rc = ttol((CHAR *)str_data, p - str_data);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- debug(F111,"SendK5AuthSB","ttol()",rc);
- return(rc);
-}
-
-/* S E N D K 4 A U T H S B
- * Send a Kerberos 4 Authentication Subnegotiation to host and
- * output appropriate Telnet Debug messages
- *
- * type - Sub Negotiation type
- * data - ptr to buffer containing data
- * len - len of buffer if not NUL terminated
- *
- * returns number of characters sent or error value
- */
-
-static int
-#ifdef CK_ANSIC
-SendK4AuthSB(int type, void *data, int len)
-#else
-SendK4AuthSB(type,data,len) int type; void *data; int len;
-#endif
-{
- int rc;
- unsigned char *p = str_data + 3;
- unsigned char *cd = (unsigned char *)data;
- extern int sstelnet;
- int mode = (auth_how & AUTH_HOW_MASK) |
- auth_crypt;
-
- if ( type < 0 || type > 4 ) /* Check for invalid values */
- return(0);
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- if (ttchk() < 0)
- return(0);
- else
- return(1);
- }
-#endif /* CK_SSL */
-
- if (!cd) {
- cd = (unsigned char *)"";
- len = 0;
- }
-
- if (len == -1) /* Use strlen() for len */
- len = strlen((char *)cd);
-
-
- /* Construct Message */
- *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
- *p++ = AUTHTYPE_KERBEROS_V4;
- *p = AUTH_CLIENT_TO_SERVER;
- *p |= mode;
- p++;
- *p++ = type;
- while (len-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
-
- /* Handle Telnet Debugging Messages */
- if (deblog || tn_deb || debses) {
- int i;
- int deblen=p-str_data-2;
- char *s=NULL;
-
- switch (type) {
- case 0:
- s = "AUTH";
- break;
- case 1:
- s = "REJECT";
- break;
- case 2:
- s = "ACCEPT";
- break;
- case 3:
- s = "CHALLENGE";
- break;
- case 4:
- s = "RESPONSE";
- break;
- }
-
- ckmakxmsg(tn_msg,TN_MSG_LEN,"TELNET SENT SB ",
- TELOPT(TELOPT_AUTHENTICATION)," ",
- str_data[3] == TELQUAL_IS ? "IS" :
- (str_data[3] == TELQUAL_REPLY ? "REPLY" : "???")," ",
- AUTHTYPE_NAME(authentication_version)," ",
- AUTHMODE_NAME(mode)," ",
- s," ",NULL);
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_data[7],deblen-7);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-
- /* Send data */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- rc = ttol((CHAR *)str_data, p - str_data);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- debug(F111,"SendK4AuthSB","ttol()",rc);
- return(rc);
-}
-
-/* S E N D S R P A U T H S B
- * Send a SRP Authentication Subnegotiation to host and
- * output appropriate Telnet Debug messages
- *
- * type - Sub Negotiation type
- * data - ptr to buffer containing data
- * len - len of buffer if not NUL terminated
- *
- * returns number of characters sent or error value
- */
-
-static int
-#ifdef CK_ANSIC
-SendSRPAuthSB(int type, void *data, int len)
-#else
-SendSRPAuthSB(type,data,len) int type; void *data; int len;
-#endif
-{
- int rc;
- unsigned char *p = str_data + 3;
- unsigned char *cd = (unsigned char *)data;
- extern int sstelnet;
-
- /* Check for invalid values */
- if ( type != SRP_EXP && type != SRP_RESPONSE &&
- type != SRP_REJECT && type != SRP_ACCEPT &&
- type != SRP_CHALLENGE && type != SRP_PARAMS &&
- type != SRP_AUTH)
- return(0);
-
- if (len == -1) /* Use strlen() for len */
- len = strlen((char *)cd);
-
- /* Construct Message */
- *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
- *p++ = AUTHTYPE_SRP;
- *p = AUTH_CLIENT_TO_SERVER;
- *p |= auth_how;
-#ifdef CK_ENCRYPTION
- *p |= auth_crypt;
-#endif
- p++;
- *p++ = type;
- while (len-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
-
- /* Handle Telnet Debugging Messages */
- if (deblog || tn_deb || debses) {
- int i;
- int deblen=p-str_data-2;
- char *s=NULL;
- int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
- auth_crypt;
-
- switch (type) {
- case 0:
- s = "AUTH";
- break;
- case 1:
- s = "REJECT";
- break;
- case 2:
- s = "ACCEPT";
- break;
- case 3:
- s = "CHALLENGE";
- break;
- case 4:
- s = "RESPONSE";
- break;
- case 5:
- s = "FORWARD";
- break;
- case 6:
- s = "FORWARD_ACCEPT";
- break;
- case 7:
- s = "FORWARD_REJECT";
- break;
- case 8:
- s = "EXP";
- break;
- case 9:
- s = "PARAMS";
- break;
- }
-
- ckmakxmsg(tn_msg,TN_MSG_LEN,
- "TELNET SENT SB ",
- TELOPT(TELOPT_AUTHENTICATION)," ",
- str_data[3] == TELQUAL_REPLY ? "REPLY" :
- str_data[3] == TELQUAL_IS ? "IS" : "???"," ",
- AUTHTYPE_NAME(authentication_version)," ",
- AUTHMODE_NAME(mode)," ",
- s," ",NULL);
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_data[7],deblen-7);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-
- /* Send data */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- rc = ttol((CHAR *)str_data, p - str_data);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- return(rc);
-}
-
-#ifdef CK_ENCRYPTION
-/*
- * Function: Enable or disable the encryption process.
- *
- * Parameters:
- * enable - TRUE to enable, FALSE to disable.
- */
-static VOID
-#ifdef CK_ANSIC
-auth_encrypt_enable(BOOL enable)
-#else
-auth_encrypt_enable(enable) BOOL enable;
-#endif
-{
- encrypt_flag = enable;
-}
-#endif
-
-/*
- * Function: Abort the authentication process
- *
- * Parameters:
- */
-static VOID
-#ifdef CK_ANSIC
-auth_abort(char *errmsg, long r)
-#else
-auth_abort(errmsg,r) char *errmsg; long r;
-#endif
-{
- char buf[9];
- extern int sstelnet;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return;
- }
-#endif /* CK_SSL */
- debug(F111,"auth_abort",errmsg,r);
-
- /* Construct Telnet Debugging messages */
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION),
- " IS ",AUTHTYPE_NAME(AUTHTYPE_NULL)," ",
- AUTHTYPE_NAME(AUTHTYPE_NULL)," IAC SE",
- NULL,NULL,NULL,NULL,NULL
- );
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-
- /* Construct the Abort message to send to the host */
- /* Basicly we change the authentication type to NULL */
- sprintf(buf, "%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION,
- sstelnet ? TELQUAL_REPLY : TELQUAL_IS, AUTHTYPE_NULL,
- AUTHTYPE_NULL, IAC, SE); /* safe */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol((CHAR *)buf, 8);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
-
- /* If there is an error message, and error number construct */
- /* an explanation to display to the user */
- if (errmsg != NULL) {
- ckstrncpy(strTmp, errmsg, AUTHTMPBL);
- } else
- strTmp[0] = '\0';
-
-
- if (r != AUTH_SUCCESS) {
- ckstrncat(strTmp, "\r\n",AUTHTMPBL);
-#ifdef KRB4
- if ( authentication_version == AUTHTYPE_KERBEROS_V4 ) {
- ckstrncat(strTmp, (char *)krb_get_err_text_entry(r),
- AUTHTMPBL);
- debug(F111,"auth_abort",(char *)krb_get_err_text_entry(r),r);
- }
-#endif
-#ifdef KRB5
- if ( authentication_version == AUTHTYPE_KERBEROS_V5 ) {
- ckstrncat(strTmp, error_message(r),AUTHTMPBL);
- debug(F111,"auth_abort",error_message(r),r);
- }
-#endif
- }
- printf("Authentication failed: %s\r\n",strTmp);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- cksyslog(SYSLG_LI, 0, "Telnet authentication failure",
- (char *) szUserNameRequested,
- strTmp);
- }
-#endif /* CKSYSLOG */
- authentication_version = AUTHTYPE_NULL;
-}
-
-
-/*
- * Function: Copy data to buffer, doubling IAC character if present.
- *
- */
-int
-#ifdef CK_ANSIC
-copy_for_net(unsigned char *to, unsigned char *from, int c)
-#else
-copy_for_net(to,from,c) unsigned char *to; unsigned char *from; int c;
-#endif
-{
- int n;
-
- n = c;
- debug(F111,"copy_for_net","before",n);
- while (c-- > 0) {
- if ((*to++ = *from++) == IAC) {
- n++;
- *to++ = IAC;
- }
- }
- debug(F111,"copy_for_net","after",n);
- return n;
-}
-
-#ifdef CK_SSL
-/* S E N D S S L A U T H S B
- * Send a SSL Authentication Subnegotiation to host and
- * output appropriate Telnet Debug messages
- *
- * type - Sub Negotiation type
- * data - ptr to buffer containing data
- * len - len of buffer if not NUL terminated
- *
- * returns number of characters sent or error value
- */
-
-int
-#ifdef CK_ANSIC
-SendSSLAuthSB(int type, void *data, int len)
-#else
-SendSSLAuthSB(type,data,len) int type; void *data; int len;
-#endif
-{
- int rc;
- unsigned char *p = str_data + 3;
- unsigned char *cd = (unsigned char *)data;
- extern int sstelnet;
-
- /* Check for invalid values */
- if ( type != SSL_START && type != SSL_ACCEPT &&
- type != SSL_REJECT)
- return(0);
-
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- if (ttchk() < 0)
- return(0);
- else
- return(1);
- }
-
- if (len == -1) /* Use strlen() for len */
- len = strlen((char *)cd);
-
- /* Construct Message */
- *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
- *p++ = AUTHTYPE_SSL;
- *p = AUTH_CLIENT_TO_SERVER;
- *p |= auth_how;
-#ifdef CK_ENCRYPTION
- *p |= auth_crypt;
-#endif
- p++;
- *p++ = type;
- while (len-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
-
- /* Handle Telnet Debugging Messages */
- if (deblog || tn_deb || debses) {
- int i;
- int deblen=p-str_data-2;
- char *s=NULL;
- int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
- (auth_crypt?AUTH_ENCRYPT_USING_TELOPT:AUTH_ENCRYPT_OFF);
-
- switch (type) {
- case SSL_START:
- s = "START";
- break;
- case SSL_ACCEPT:
- s = "ACCEPT";
- break;
- case SSL_REJECT:
- s = "REJECT";
- break;
- }
-
- ckmakxmsg(tn_msg,TN_MSG_LEN,
- "TELNET SENT SB ",
- TELOPT(TELOPT_AUTHENTICATION)," ",
- str_data[3] == TELQUAL_REPLY ? "REPLY" :
- str_data[3] == TELQUAL_IS ? "IS" : "???"," ",
- AUTHTYPE_NAME(authentication_version)," ",
- AUTHMODE_NAME(mode)," ",
- s," ",NULL);
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_data[7],deblen-7);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-
- /* Send data */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- rc = ttol((CHAR *)str_data, p - str_data);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- return(rc);
-}
-#endif /* CK_SSL */
-
-int
-tn_how_ok(int how)
-{
- switch ( tn_auth_how ) {
- case TN_AUTH_HOW_ANY:
- return(1);
- case TN_AUTH_HOW_ONE_WAY:
- return((how & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY);
- case TN_AUTH_HOW_MUTUAL:
- return((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL);
- default:
- return(0);
- }
-}
-
-int
-tn_enc_ok(int enc)
-{
- switch ( tn_auth_enc ) {
- case TN_AUTH_ENC_ANY:
- if ((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS &&
- (!ck_ssleay_is_installed()
-#ifdef CK_SSL
- || !ssl_finished_messages ||
- !(tls_active_flag || ssl_active_flag)
-#endif /* CK_SSL */
- )) {
-#ifdef CK_SSL
- if (!ssl_finished_messages)
- debug(F100,"tn_enc_ok !ssl_finished_messages","",0);
-#endif /* CK_SSL */
- return(0);
- }
- return(1);
- case TN_AUTH_ENC_NONE:
- return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_OFF);
- case TN_AUTH_ENC_TELOPT:
- return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_USING_TELOPT);
- case TN_AUTH_ENC_EXCH:
- return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_AFTER_EXCHANGE);
- case TN_AUTH_ENC_TLS:
- return(((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) &&
- ck_ssleay_is_installed()
-#ifdef CK_SSL
- && ssl_finished_messages &&
- (tls_active_flag || ssl_active_flag)
-#endif /* CK_SSL */
- );
- default:
- return(0);
- }
-}
-
-static int
-atok(int at) {
- int i;
- if ( auth_type_user[0] == AUTHTYPE_AUTO )
- return(1);
- if ( auth_type_user[0] == AUTHTYPE_NULL )
- return(0);
-
- for ( i=0;
- i<AUTHTYPLSTSZ && auth_type_user[i] != AUTHTYPE_NULL;
- i++ ) {
- if ( auth_type_user[i] == at )
- return(1);
- }
-
- return(0);
-}
-
-
-/*
- * Function: Parse authentication send command
- *
- * Parameters:
- * parsedat - the sub-command data.
- *
- * end_sub - index of the character in the 'parsedat' array which
- * is the last byte in a sub-negotiation
- *
- * Returns: Kerberos error code.
- */
-
-static unsigned char send_list[512];
-static int send_len = 0;
-
-_PROTOTYP(static int auth_send, (unsigned char *parsedat, int end_sub));
-
-static int
-#ifdef CK_ANSIC
-auth_resend(int type)
-#else
-auth_resend(type) int type;
-#endif /* CK_ANSIC */
-{
- int i=2;
- while (i+1 <= send_len) {
- if (send_list[i] == type) {
- int j;
- send_len -= 2;
- for (j = i; j < send_len; j++)
- send_list[j] = send_list[j+2];
- } else {
- i += 2;
- }
- }
- return(auth_send(send_list,send_len));
-}
-
-static int
-#ifdef CK_ANSIC
-auth_send(unsigned char *parsedat, int end_sub)
-#else
-auth_send(parsedat,end_sub) unsigned char *parsedat; int end_sub;
-#endif
-{
- static unsigned char buf[4096];
- unsigned char *pname;
- int plen;
- int r;
- int i;
- int mode;
-#ifdef MIT_CURRENT
-#ifdef CK_ENCRYPTION
- krb5_data data;
- krb5_enc_data encdata;
- krb5_error_code code;
- krb5_keyblock random_key;
-#endif /* ENCRYPTION */
-#endif /* MIT_CURRENT */
-#ifdef KRB5
- int krb5_msg = 0;
-#endif /* KRB5 */
-#ifdef KRB4
- int krb4_msg = 0;
-#endif /* KRB4 */
-#ifdef GSSAPI_KRB5
- int gssk5_msg = 0;
-#endif /* GSSAPI_KRB5 */
- int iaccnt=0;
-
-#ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return(AUTH_SUCCESS);
-#endif /* CK_SSL */
-
- auth_how = -1; /* We have not found an auth method */
- auth_crypt = 0; /* We are not using encryption (yet) */
- send_len = end_sub > 512 ? 512 : end_sub;
- memcpy(send_list,parsedat,send_len);
-
- /* Search the list of acceptable Authentication types sent from */
- /* the host and find one that we support */
-
- /* For Kerberos authentications, try to determine if we have a */
- /* valid TGT, if not skip over the authentication type because */
- /* we wouldn't be able to successfully login anyway. Perhaps */
- /* there is another supported authentication which we could use */
-
-#ifdef NO_FTP_AUTH
- /* If the userid is "ftp" or "anonymous" refuse to perform AUTH */
- /* for Kerberos or SRP. */
-#endif /* NO_FTP_AUTH */
-
- if ( auth_type_user[0] == AUTHTYPE_AUTO ) {
- for (i = 2; i+1 <= end_sub; i += 2) {
-#ifdef NTLM
- if (parsedat[i] == AUTHTYPE_NTLM &&
- ck_ntlm_is_valid(1) &&
- ntlm_auth_send() == 0) {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
-#ifdef CK_ENCRYPTION
- /* NTLM does not support Telnet Encryption */
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
-#endif /* CK_ENCRYPTION */
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- authentication_version = AUTHTYPE_NTLM;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
-#endif /* NTLM */
-#ifdef CK_SSL
- if ( parsedat[i] == AUTHTYPE_SSL && ssl_initialized &&
-#ifdef SSLDLL
- ck_ssleay_is_installed() &&
-#endif /* SSLDLL */
- !tls_active_flag && !ssl_active_flag
-#ifndef USE_CERT_CB
- && tls_load_certs(ssl_ctx,ssl_con,0)
-#endif /* USE_CERT_CB */
- ) {
-
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
-#ifdef CK_ENCRYPTION
- /* SSL does not support Telnet Encryption */
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
-#endif /* CK_ENCRYPTION */
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- authentication_version = AUTHTYPE_SSL;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
-#endif /* SSL */
-#ifdef CK_SRP
- if ( parsedat[i] == AUTHTYPE_SRP
-#ifdef SRPDLL
- && hSRP
-#endif /* SRPDLL */
-#ifdef NO_FTP_AUTH
- && strcmp("ftp",szUserName) && strcmp("anonymous",szUserName)
-#endif /* NO_FTP_AUTH */
- ) {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
-#ifdef PRE_SRP_1_4_5
- if (parsedat[i+1] & AUTH_ENCRYPT_MASK)
- /* Do not support ENCRYPT_USING_TELOPT yet. */
- continue;
-#endif /* PRE_SRP_1_4_5 */
- if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
- AUTH_ENCRYPT_USING_TELOPT) &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
- continue;
-
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
-#ifdef CK_ENCRYPTION
- if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if ( auth_crypt == AUTH_ENCRYPT_START_TLS &&
- ck_ssleay_is_installed() &&
- (tls_active_flag || ssl_active_flag) ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
-#endif /* CK_SSL */
- authentication_version = AUTHTYPE_SRP;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
-#endif /* SRP */
-#ifdef GSSAPI_KRB5
- if (parsedat[i] == AUTHTYPE_GSSAPI_KRB5 &&
- (parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
- AUTH_ENCRYPT_AFTER_EXCHANGE &&
-#ifdef OS2
- hGSSAPI &&
-#endif /* OS2 */
-#ifdef NO_FTP_AUTH
- strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
-#endif /* NO_FTP_AUTH */
- ck_gssapi_is_installed() && !gssk5_msg)
- {
- if ( !gssk5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
- parsedat[i+1] & AUTH_ENCRYPT_MASK,
- parsedat[i+1] & INI_CRED_FWD_MASK) )
- {
- /* If we are auto-getting TGTs, try */
- if ( !ck_krb5_is_tgt_valid() ) {
- printf("Kerberos 5: Ticket Getting Ticket not valid.\r\n");
- }
- gssk5_msg = 1;
- }
- else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
- AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
-#ifdef CK_ENCRYPTION
- if ( auth_crypt == AUTH_ENCRYPT_AFTER_EXCHANGE ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
-#endif /* CK_ENCRYPTION */
- auth_fwd = parsedat[i+1] & INI_CRED_FWD_MASK;
- authentication_version = AUTHTYPE_GSSAPI_KRB5;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
-#endif /* GSSAPI_KRB5 */
-#ifdef KRB5
- if (parsedat[i] == AUTHTYPE_KERBEROS_V5 &&
-#ifdef OS2
- hKRB5_32 &&
-#endif /* OS2 */
-#ifdef NO_FTP_AUTH
- strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
-#endif /* NO_FTP_AUTH */
- ck_krb5_is_installed() && !krb5_msg) {
-
- /* Without encryption we can't perform mutual authentication */
- if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
- !ck_crypt_is_installed())
- continue;
-
- /* Skip over entries that request credential forwarding */
- /* if we are not forwarding. */
- if ((!forward_flag && (parsedat[i+1] & INI_CRED_FWD_MASK)) ||
- (forward_flag &&
- ((parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY)))
- continue;
-
- if ( !k5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
- parsedat[i+1] & AUTH_ENCRYPT_MASK,
- parsedat[i+1] & INI_CRED_FWD_MASK) )
- {
- /* If we are auto-getting TGTs, try */
- if ( !ck_krb5_is_tgt_valid() ) {
- printf("Kerberos 5: Ticket Getting Ticket not valid.\r\n");
- }
- krb5_msg = 1;
- }
- else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
- AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
- AUTH_ENCRYPT_USING_TELOPT) &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
- continue;
- if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
- AUTH_ENCRYPT_START_TLS) &&
- (!ck_ssleay_is_installed()
-#ifdef CK_SSL
- || !(tls_active_flag || ssl_active_flag)
-#endif /* CK_SSL */
- ))
- continue;
-
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
-#ifdef CK_ENCRYPTION
- if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if ( auth_crypt == AUTH_ENCRYPT_START_TLS &&
- ck_ssleay_is_installed() &&
- (tls_active_flag || ssl_active_flag) ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
-#endif /* CK_SSL */
- auth_fwd = parsedat[i+1] & INI_CRED_FWD_MASK;
- authentication_version = AUTHTYPE_KERBEROS_V5;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- if ( auth_how == AUTH_HOW_ONE_WAY ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
- break;
- }
- }
-#endif /* KRB5 */
-#ifdef KRB4
- if (parsedat[i] == AUTHTYPE_KERBEROS_V4 &&
-#ifdef OS2
- hKRB4_32 &&
-#endif /* OS2 */
-#ifdef NO_FTP_AUTH
- strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
-#endif /* NO_FTP_AUTH */
- ck_krb4_is_installed() && !krb4_msg) {
- int rc = 0;
-
- /* Without encryption we can't perform mutual authentication */
- if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
- !ck_crypt_is_installed() )
- continue;
-
- if ( !k4_auth_send() )
- {
- /* If we are auto-getting TGTs, try */
- if ( !ck_krb4_is_tgt_valid() ) {
- printf("Kerberos 4: Ticket Getting Ticket not valid.\r\n");
- }
- krb4_msg = 1;
- }
- else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
- AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
-#ifdef CK_ENCRYPTION
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
-#endif /* CK_ENCRYPTION */
- authentication_version = AUTHTYPE_KERBEROS_V4;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- if ( auth_how == AUTH_HOW_ONE_WAY ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
- break;
- }
- }
-#endif /* KRB4 */
- }
- } else {
- for (i = 2; i+1 <= end_sub; i += 2) {
-#ifdef CK_SSL
- if ( atok(AUTHTYPE_SSL) && parsedat[i] == AUTHTYPE_SSL &&
-#ifdef SSLDLL
- ck_ssleay_is_installed() &&
-#endif /* SSLDLL */
- !tls_active_flag && !ssl_active_flag && ssl_initialized
-#ifndef USE_CERT_CB
- && tls_load_certs(ssl_ctx,ssl_con,0)
-#endif /* USE_CERT_CB */
- )
- {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
-#ifdef CK_ENCRYPTION
- /* SSL does not support Telnet Encryption */
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
-#endif /* CK_ENCRYPTION */
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- authentication_version = AUTHTYPE_SSL;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
-#endif /* SSL */
-#ifdef CK_SRP
- if ( atok(AUTHTYPE_SRP) &&
- parsedat[i] == AUTHTYPE_SRP
-#ifdef SRPDLL
- && hSRP
-#endif /* SRPDLL */
-#ifdef NO_FTP_AUTH
- && strcmp("ftp",szUserName) && strcmp("anonymous",szUserName)
-#endif /* NO_FTP_AUTH */
- ) {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
-#ifdef PRE_SRP_1_4_5
- if (parsedat[i+1] & AUTH_ENCRYPT_MASK)
- /* Do not support ENCRYPT_USING_TELOPT yet. */
- continue;
-#endif /* PRE_SRP_1_4_5 */
- if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
- AUTH_ENCRYPT_USING_TELOPT) &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
- continue;
- if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
- AUTH_ENCRYPT_START_TLS) &&
- (!ck_ssleay_is_installed()
-#ifdef CK_SSL
- || !(tls_active_flag || ssl_active_flag)
-#endif /* CK_SSL */
- ))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
-#ifdef CK_ENCRYPTION
- if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if ( auth_crypt == AUTH_ENCRYPT_START_TLS &&
- ck_ssleay_is_installed() &&
- (tls_active_flag || ssl_active_flag) ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
-#endif /* CK_SSL */
- authentication_version = AUTHTYPE_SRP;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
-#endif /* SRP */
-#ifdef GSSAPI_KRB5
- if (atok(AUTHTYPE_GSSAPI_KRB5) &&
- parsedat[i] == AUTHTYPE_GSSAPI_KRB5 &&
- (parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
- AUTH_ENCRYPT_AFTER_EXCHANGE &&
-#ifdef OS2
- hGSSAPI &&
-#endif /* OS2 */
-#ifdef NO_FTP_AUTH
- strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
-#endif /* NO_FTP_AUTH */
- ck_gssapi_is_installed() && !gssk5_msg)
- {
- if ( !gssk5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
- parsedat[i+1] & AUTH_ENCRYPT_MASK,
- parsedat[i+1] & INI_CRED_FWD_MASK) )
- {
- /* If we are auto-getting TGTs, try */
- if ( !ck_krb5_is_tgt_valid() ) {
- printf("Kerberos 5: Ticket Getting Ticket not valid.\r\n");
- }
- gssk5_msg = 1;
- }
- else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
- AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
-#ifdef CK_ENCRYPTION
- if ( auth_crypt == AUTH_ENCRYPT_AFTER_EXCHANGE ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
-#endif /* CK_ENCRYPTION */
- auth_fwd = parsedat[i+1] & INI_CRED_FWD_MASK;
- authentication_version = AUTHTYPE_GSSAPI_KRB5;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
-#endif /* GSSAPI_KRB5 */
-#ifdef KRB5
- if ( atok(AUTHTYPE_KERBEROS_V5) &&
- parsedat[i] == AUTHTYPE_KERBEROS_V5 &&
-#ifdef OS2
- hKRB5_32 &&
-#endif /* OS2 */
-#ifdef NO_FTP_AUTH
- strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
-#endif /* NO_FTP_AUTH */
- ck_krb5_is_installed() && !krb5_msg) {
-
- /* Without encryption we can't perform mutual authentication */
- if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
- !ck_crypt_is_installed())
- continue;
-
- /* Skip over entries that request credential forwarding */
- /* if we are not forwarding. */
- if ((!forward_flag && (parsedat[i+1] & INI_CRED_FWD_MASK)) ||
- (forward_flag &&
- ((parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY)))
- continue;
-
- if ( !k5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
- parsedat[i+1] & AUTH_ENCRYPT_MASK,
- parsedat[i+1] & INI_CRED_FWD_MASK) )
- {
- /* If we are auto-getting TGTs, try */
- if ( !ck_krb5_is_tgt_valid() ) {
- printf(
- "Kerberos 5: Ticket Getting Ticket not valid.\r\n");
- }
- krb5_msg = 1;
- }
- else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
- AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1]))
- {
- if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
- AUTH_ENCRYPT_USING_TELOPT) &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
- continue;
- if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
- AUTH_ENCRYPT_START_TLS) &&
- (!ck_ssleay_is_installed()
-#ifdef CK_SSL
- || !(tls_active_flag || ssl_active_flag)
-#endif /* CK_SSL */
- ))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
-#ifdef CK_ENCRYPTION
- if (auth_crypt) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if ( auth_crypt == AUTH_ENCRYPT_START_TLS &&
- ck_ssleay_is_installed() &&
- (tls_active_flag || ssl_active_flag) ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
-#endif /* CK_SSL */
- authentication_version = AUTHTYPE_KERBEROS_V5;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- if ( auth_how == AUTH_HOW_ONE_WAY ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
- break;
- }
- }
-#endif /* KRB5 */
-#ifdef KRB4
- if ( atok(AUTHTYPE_KERBEROS_V4) &&
- parsedat[i] == AUTHTYPE_KERBEROS_V4 &&
-#ifdef OS2
- hKRB4_32 &&
-#endif /* OS2 */
-#ifdef NO_FTP_AUTH
- strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
-#endif /* NO_FTP_AUTH */
- ck_krb4_is_installed() && !krb4_msg) {
- int rc = 0;
-
- /* Without encryption we can't perform mutual authentication */
- if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
- !ck_crypt_is_installed())
- continue;
-
- if ( !k4_auth_send() )
- {
- /* If we are auto-getting TGTs, try */
- if ( !ck_krb4_is_tgt_valid() ) {
- printf("Kerberos 4: Ticket Getting Ticket not valid.\r\n");
- }
- krb4_msg = 1;
- }
- else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
- AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1]))
- {
-#ifdef CK_ENCRYPTION
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- if (auth_crypt) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
-#endif /* CK_ENCRYPTION */
- authentication_version = AUTHTYPE_KERBEROS_V4;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- if ( auth_how == AUTH_HOW_ONE_WAY ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
- break;
- }
- }
-#endif /* KRB4 */
-#ifdef NTLM
- if ( atok(AUTHTYPE_NTLM) &&
- parsedat[i] == AUTHTYPE_NTLM &&
- ck_ntlm_is_valid(1) &&
- ntlm_auth_send() == 0) {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
-#ifdef CK_ENCRYPTION
- /* NTLM does not support Telnet Encryption */
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
-#endif /* CK_ENCRYPTION */
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- authentication_version = AUTHTYPE_NTLM;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
-#endif /* NTLM */
- }
- }
-
- if (auth_how == -1) { /* Did we find one? */
- switch ( auth_type_user[0] ) { /* If not, abort the negotiation */
- case AUTHTYPE_NULL:
- auth_abort("User refused to accept any authentication method",0);
- break;
- case AUTHTYPE_AUTO:
- auth_abort("No authentication method available", 0);
- break;
- default: {
- char msg[80];
- ckmakmsg(msg,80,AUTHTYPE_NAME(auth_type_user[0]),
- " could not be negotiated",NULL,NULL
- );
- auth_abort(msg, 0);
- }
- }
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- printf("Authenticating with %s\r\n",
- AUTHTYPE_NAME(authentication_version));
-
- /* Send Telnet Auth Name message (if necessary) */
- switch ( authentication_version ) {
- case AUTHTYPE_SRP:
- case AUTHTYPE_KERBEROS_V4:
- case AUTHTYPE_KERBEROS_V5:
- case AUTHTYPE_GSSAPI_KRB5:
- /* if we do not have a name to login with get one now. */
- while ( szUserName[0] == '\0' ) {
- extern char * tn_pr_uid;
- int ok = uq_txt(NULL,
- tn_pr_uid && tn_pr_uid[0] ? tn_pr_uid : "Host Userid: ",
- 1, NULL, szUserName, 63, NULL,DEFAULT_UQ_TIMEOUT);
- if ( !ok )
- return AUTH_FAILURE;
- }
- plen = strlen(szUserName);
- pname = (unsigned char *) szUserName;
-
- /* Construct Telnet Debugging Message */
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION),
- " NAME ",(char *)pname," IAC SE",NULL,
- NULL,NULL,NULL,NULL,NULL,NULL
- );
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-
- /* Construct and send Authentication Name subnegotiation */
- if ( plen < sizeof(buf) - 6 ) {
- sprintf((char *)buf, "%c%c%c%c", IAC, SB,
- TELOPT_AUTHENTICATION,
- TELQUAL_NAME);
- memcpy(&buf[4], pname, plen); /* safe */
- sprintf((char *)&buf[plen + 4], "%c%c", IAC, SE); /* safe */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol((CHAR *)buf, plen+6);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- } else {
- sprintf((char *)buf, "%c%c%c%c%c%c", IAC, SB,
- TELOPT_AUTHENTICATION,
- TELQUAL_NAME, IAC, SE); /* safe */
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol((CHAR *)buf, 6);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- }
- }
-
- /* Construct Authentication Mode subnegotiation message (if necessary) */
- switch ( authentication_version ) {
- case AUTHTYPE_SRP:
- case AUTHTYPE_KERBEROS_V4:
- case AUTHTYPE_KERBEROS_V5:
- case AUTHTYPE_GSSAPI_KRB5:
- case AUTHTYPE_NTLM:
- mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) | auth_crypt
-#ifdef USE_INI_CRED_FWD
- | (((authentication_version == AUTHTYPE_KERBEROS_V5) &&
- auth_fwd)?INI_CRED_FWD_ON:INI_CRED_FWD_OFF)
-#endif /* USE_INI_CRED_FWD */
- ;
- sprintf((char *)buf, "%c%c%c%c%c%c%c",
- IAC, SB, TELOPT_AUTHENTICATION,
- TELQUAL_IS,
- authentication_version,
- mode,
- KRB_AUTH); /* safe */
- break;
- }
-
- /* Send initial authentication data */
- switch ( authentication_version ) {
-#ifdef CK_SSL
- case AUTHTYPE_SSL:
- SendSSLAuthSB(SSL_START,NULL,0);
- break;
-#endif /* SSL */
-#ifdef CK_SRP
- case AUTHTYPE_SRP:
- sprintf(&buf[7], "%c%c", IAC, SE); /* safe */
- if (deblog || tn_deb || debses) {
- ckmakxmsg(tn_msg,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION),
- " IS ",AUTHTYPE_NAME(authentication_version),
- " AUTH ",AUTHMODE_NAME(mode)," IAC SE",
- NULL,NULL,NULL,NULL,NULL
- );
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol((CHAR *)buf, 9);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- break;
-#endif /* SRP */
-#ifdef NTLM
- case AUTHTYPE_NTLM: {
- int length = 0;
-
- for ( i=0 ; i<NTLMSecBuf[0].cbBuffer ; i++ ) {
- if ( ((char *)NTLMSecBuf[0].pvBuffer)[i] == IAC )
- iaccnt++;
- }
-
- if ( ( 2*sizeof(ULONG) + NTLMSecBuf[0].cbBuffer + iaccnt + 10) <
- sizeof(buf) ) {
- length = copy_for_net(&buf[7],(char *)&NTLMSecBuf[0],
- 2*sizeof(ULONG));
- length += copy_for_net(&buf[7+length], NTLMSecBuf[0].pvBuffer,
- NTLMSecBuf[0].cbBuffer);
- }
- sprintf(&buf[7+length], "%c%c", IAC, SE);
-
- if (deblog || tn_deb || debses) {
- int i;
- ckmakxmsg(tn_msg,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION),
- " IS ",AUTHTYPE_NAME(authentication_version)," ",
- AUTHMODE_NAME(mode)," NTLM_AUTH ",
- NULL,NULL,NULL,NULL,NULL
- );
- tn_hex((char *)tn_msg,TN_MSG_LEN,&buf[7],length);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol((CHAR *)buf, length+9);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- break;
- }
-#endif /* NTLM */
-#ifdef KRB4
- case AUTHTYPE_KERBEROS_V4:
- for ( i=0 ; i<k4_auth.length ; i++ ) {
- if ( k4_auth.dat[i] == IAC )
- iaccnt++;
- }
-
- if ( k4_auth.length + iaccnt + 10 < sizeof(buf) )
- k4_auth.length = copy_for_net(&buf[7], k4_auth.dat, k4_auth.length);
- else
- k4_auth.length = 0;
- sprintf(&buf[k4_auth.length+7], "%c%c", IAC, SE);
-
- if (deblog || tn_deb || debses) {
- int i;
- ckmakxmsg(tn_msg,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION)," IS ",
- AUTHTYPE_NAME(authentication_version)," ",
- AUTHMODE_NAME(mode)," AUTH ",
- NULL,NULL,NULL,NULL,NULL
- );
- tn_hex((char *)tn_msg,TN_MSG_LEN,&buf[7],k4_auth.length);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol((CHAR *)buf, k4_auth.length+9);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
-
-#ifndef REMOVE_FOR_EXPORT
-#ifdef CK_ENCRYPTION
- /*
- * If we are doing mutual authentication, get set up to send
- * the challenge, and verify it when the response comes back.
- */
- if ((auth_how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- register int i;
- int rc = 0;
-
-#ifdef MIT_CURRENT
- data.data = cred.session;
- data.length = 8; /* sizeof(cred.session) */;
-
- if (code = krb5_c_random_seed(k5_context, &data)) {
- com_err("libtelnet", code,
- "while seeding random number generator");
- return(0);
- }
-
- if (code = krb5_c_make_random_key(k5_context,
- ENCTYPE_DES_CBC_RAW,
- &random_key)) {
- com_err("libtelnet", code,
- "while creating random session key");
- return(0);
- }
-
- /* the krb4 code uses ecb mode, but on a single block
- with a zero ivec, ecb and cbc are the same */
- k4_krbkey.enctype = ENCTYPE_DES_CBC_RAW;
- k4_krbkey.length = 8;
- k4_krbkey.contents = cred.session;
-
- encdata.ciphertext.data = random_key.contents;
- encdata.ciphertext.length = random_key.length;
- encdata.enctype = ENCTYPE_UNKNOWN;
-
- data.data = k4_session_key;
- data.length = 8;
-
- code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
- &encdata, &data);
-
- krb5_free_keyblock_contents(k5_context, &random_key);
-
- if (code) {
- com_err("libtelnet", code, "while encrypting random key");
- return(0);
- }
-
- encdata.ciphertext.data = k4_session_key;
- encdata.ciphertext.length = 8;
- encdata.enctype = ENCTYPE_UNKNOWN;
-
- data.data = k4_challenge;
- data.length = 8;
-
- code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
- &encdata, &data);
-#else /* MIT_CURRENT */
- memset(k4_sched,0,sizeof(Schedule));
- ckhexdump("auth_send",cred.session,8);
- rc = des_key_sched(cred.session, k4_sched);
- if ( rc == -1 ) {
- printf("?Invalid DES key specified in credentials\r\n");
- debug(F110,"auth_send",
- "invalid DES Key specified in credentials",0);
- } else if ( rc == -2 ) {
- printf("?Weak DES key specified in credentials\r\n");
- debug(F110,"auth_send",
- "weak DES Key specified in credentials",0);
- } else if ( rc != 0 ) {
- printf("?DES Key Schedule not set by credentials\r\n");
- debug(F110,"auth_send",
- "DES Key Schedule not set by credentials",0);
- }
- ckhexdump("auth_send schedule",k4_sched,8*16);
-
- des_set_random_generator_seed(cred.session);
-
- do {
- des_new_random_key(k4_session_key);
- des_fixup_key_parity(k4_session_key);
- } while ( ck_des_is_weak_key(k4_session_key) );
-
- ckhexdump("auth_send des_new_random_key(k4_session_key)",
- k4_session_key,8);
-
- /* Decrypt the session key so that we can send it to the */
- /* host as a challenge */
-#ifdef NT
- des_ecb_encrypt(k4_session_key, k4_session_key, k4_sched, 0);
-#else /* NT */
- des_ecb_encrypt(&k4_session_key, &k4_session_key, k4_sched, 0);
-#endif /* NT */
- ckhexdump(
- "auth_send des_ecb_encrypt(k4_session_key,k4_session_key,0)",
- k4_session_key,8
- );
- /* Prepare the result of the challenge */
- /* Decrypt the session_key, add 1, and then encrypt it */
- /* The result stored in k4_challenge should match the */
- /* KRB4_RESPONSE value from the host. */
-#ifdef NT
- des_ecb_encrypt(k4_session_key, k4_challenge, k4_sched, 0);
-#else /* NT */
- des_ecb_encrypt(&k4_session_key, &k4_challenge, k4_sched, 0);
-#endif /* NT */
-
- ckhexdump("auth_send des_ecb_encrypt(k4_session_key,k4_challenge,0)",
- k4_challenge,8);
-#endif /* MIT_CURRENT */
- /*
- * Increment the challenge by 1, and encrypt it for
- * later comparison.
- */
- for (i = 7; i >= 0; --i) {
- register int x;
- x = (unsigned int)k4_challenge[i] + 1;
- k4_challenge[i] = x; /* ignore overflow */
- if (x < 256) /* if no overflow, all done */
- break;
- }
- ckhexdump("auth_send k4_challenge+1",k4_challenge,8);
-#ifdef MIT_CURRENT
- data.data = k4_challenge;
- data.length = 8;
-
- encdata.ciphertext.data = k4_challenge;
- encdata.ciphertext.length = 8;
- encdata.enctype = ENCTYPE_UNKNOWN;
-
- if (code = krb5_c_encrypt(k5_context, &k4_krbkey, 0, 0, &data,
- &encdata)) {
- com_err("libtelnet", code, "while encrypting random key");
- return(0);
- }
-#else /* MIT_CURRENT */
-#ifdef NT
- des_ecb_encrypt(k4_challenge, k4_challenge, k4_sched, 1);
-#else /* NT */
- des_ecb_encrypt(&k4_challenge, &k4_challenge, k4_sched, 1);
-#endif /* NT */
- ckhexdump("auth_send des_ecb_encrypt(k4_session_key,k4_challenge,1)",
- k4_challenge,8);
-#endif /* MIT_CURRENT */
- }
-#endif /* ENCRYPTION */
-#endif /* REMOVE_FOR_EXPORT */
- break;
-#endif /* KRB4 */
-#ifdef GSSAPI_KRB5
- case AUTHTYPE_GSSAPI_KRB5:
- for ( i=0 ; i<gss_send_tok.length ; i++ ) {
- if ( ((char *)gss_send_tok.value)[i] == IAC )
- iaccnt++;
- }
-
- if ( gss_send_tok.length + iaccnt + 10 < sizeof(buf) )
- gss_send_tok.length = copy_for_net(&buf[7], gss_send_tok.value,
- gss_send_tok.length);
- else
- gss_send_tok.length = 0;
- sprintf(&buf[gss_send_tok.length+7], "%c%c", IAC, SE); /* safe */
- if (deblog || tn_deb || debses) {
- int i;
- ckmakxmsg(tn_msg,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION)," IS ",
- AUTHTYPE_NAME(authentication_version)," ",
- AUTHMODE_NAME(mode)," AUTH ",
- NULL,NULL,NULL,NULL,NULL
- );
- tn_hex((char *)tn_msg,TN_MSG_LEN,&buf[7],gss_send_tok.length);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol((CHAR *)buf, gss_send_tok.length+9);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
- break;
-#endif /* GSSAPI_KRB5 */
-#ifdef KRB5
- case AUTHTYPE_KERBEROS_V5:
- debug(F111,"auth_send KRB5","k5_auth.length",k5_auth.length);
- for ( i=0 ; i<k5_auth.length ; i++ ) {
- if ( (char *)k5_auth.data[i] == IAC )
- iaccnt++;
- }
- if ( k5_auth.length + iaccnt + 10 < sizeof(buf) ) {
- k5_auth.length = copy_for_net(&buf[7],
- (CHAR *)k5_auth.data,
- k5_auth.length);
- } else {
- debug(F100,"auth_send() KRB5 auth data too large for buffer","",0);
- k5_auth.length = 0;
- }
-
- sprintf((char *)&buf[k5_auth.length+7], "%c%c", IAC, SE); /* safe */
- if (deblog || tn_deb || debses) {
- int i;
- ckmakxmsg(tn_msg,TN_MSG_LEN,
- "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION)," IS ",
- AUTHTYPE_NAME(authentication_version)," ",
- AUTHMODE_NAME(mode)," AUTH ",
- NULL,NULL,NULL,NULL,NULL
- );
- tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&buf[7],k5_auth.length);
- ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
-#ifdef OS2
- RequestTelnetMutex( SEM_INDEFINITE_WAIT );
-#endif
- ttol((CHAR *)buf, k5_auth.length+9);
-#ifdef OS2
- ReleaseTelnetMutex();
-#endif
-#ifdef HEIMDAL
- krb5_data_free(&k5_auth);
-#else /* HEIMDAL */
- krb5_free_data_contents(k5_context,&k5_auth);
- memset(&k5_auth,0,sizeof(krb5_data));
-#endif /* HEIMDAL */
- break;
-#endif /* KRB5 */
- }
- return AUTH_SUCCESS;
-}
-
-/*
- * Function: Parse authentication REPLY command
- *
- * Parameters:
- * parsedat - the sub-command data.
- *
- * end_sub - index of the character in the 'parsedat' array which
- * is the last byte in a sub-negotiation
- *
- * Returns: Kerberos error code.
- */
-static int
-#ifdef CK_ANSIC
-auth_reply(unsigned char *parsedat, int end_sub)
-#else
-auth_reply(parsedat,end_sub) unsigned char *parsedat; int end_sub;
-#endif
-{
- int n = AUTH_FAILURE;
-
- if ( parsedat[2] != authentication_version ) {
- printf("Authentication version mismatch (%s [%d] != %s [%d])\r\n",
- AUTHTYPE_NAME(parsedat[2]),parsedat[2],
- AUTHTYPE_NAME(authentication_version),authentication_version);
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
- if ( parsedat[3] != (auth_how|auth_crypt|auth_fwd) ) {
- printf("Authentication mode mismatch (%s != %s)\r\n",
- AUTHMODE_NAME(parsedat[3]),
- AUTHMODE_NAME(auth_how|auth_crypt|auth_fwd));
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
-
-#ifdef KRB4
- if (authentication_version == AUTHTYPE_KERBEROS_V4)
- n = k4_auth_reply(parsedat, end_sub);
-#endif
-#ifdef KRB5
- if (authentication_version == AUTHTYPE_KERBEROS_V5)
- n = k5_auth_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
-#endif
-#ifdef CK_SRP
- if (authentication_version == AUTHTYPE_SRP) {
-#ifndef PRE_SRP_1_7_3
- n = new_srp_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
-#else /* PRE_SRP_1_7_3 */
- n = srp_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
-#endif /* PRE_SRP_1_7_3 */
- }
-#endif /* SRP */
-#ifdef CK_SSL
- if (authentication_version == AUTHTYPE_SSL)
- n = ssl_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
-#endif /* SSL */
-#ifdef NTLM
- if (authentication_version == AUTHTYPE_NTLM)
- n = ntlm_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
-#endif /* NTLM */
- return n;
-}
-
-
-/*
- * Function: Parse authentication IS command
- *
- * Parameters:
- * parsedat - the sub-command data.
- *
- * end_sub - index of the character in the 'parsedat' array which
- * is the last byte in a sub-negotiation
- *
- * Returns: Kerberos error code.
- */
-static int
-#ifdef CK_ANSIC
-auth_is(unsigned char *parsedat, int end_sub)
-#else
-auth_is(parsedat,end_sub) unsigned char *parsedat; int end_sub;
-#endif
-{
- int n = AUTH_FAILURE;
-
- if ( parsedat[2] == AUTHTYPE_NULL ) {
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
-
- /*
- * If CLIENT_CHOOSE_ONCE is selected the server will not allow the
- * client to switch to an alternate authentication method if the one
- * it originally selected fails. (ie, if the host's SRP parameters
- * are invalid.) However, I think this is a bit of a security risk
- * since allowing that functionality means that it is impossible to
- * detect if an attack is being carried out on
- */
-#define CLIENT_CHOOSE_ONCE
-#ifdef CLIENT_CHOOSE_ONCE
- if ( authentication_version == AUTHTYPE_AUTO )
-#endif /* CLIENT_CHOOSE_ONCE */
- {
- /* this block of code needs to check the initial parameters */
- /* to ensure that those returned match one of the sets that */
- /* were sent to the client in the first place. */
-
- int i=0;
- for ( i=4; str_request[i] != IAC ; i+=2) {
- if (str_request[i] == parsedat[2] &&
- str_request[i+1] == parsedat[3])
- break;
- }
-
- if ( str_request[i] == IAC ) {
- printf("Invalid authentication type pair (%s,%s)\r\n",
- AUTHTYPE_NAME(parsedat[2]),
- AUTHMODE_NAME(parsedat[3]));
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
-
- if (authentication_version != parsedat[2]) {
- authentication_version = parsedat[2];
- auth_how = (parsedat[3] & AUTH_HOW_MASK);
- auth_crypt = (parsedat[3] & AUTH_ENCRYPT_MASK);
- auth_fwd = (parsedat[3] & INI_CRED_FWD_MASK);
- debug(F111,"auth_is","authentication_version",
- authentication_version);
- debug(F111,"auth_is","auth_how",auth_how);
- debug(F111,"auth_is","auth_crypt",auth_crypt);
- debug(F111,"auth_is","auth_fwd",auth_fwd);
- }
- }
-
-#ifdef CLIENT_CHOOSE_ONCE
- if ( parsedat[2] != authentication_version ) {
- printf("Authentication version mismatch (%s [%d] != %s [%d])\r\n",
- AUTHTYPE_NAME(parsedat[2]),parsedat[2],
- AUTHTYPE_NAME(authentication_version),authentication_version);
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
- if ( parsedat[3] != (auth_how|auth_crypt|auth_fwd) ) {
- printf("Authentication mode mismatch (%s != %s)\r\n",
- AUTHMODE_NAME(parsedat[3]),
- AUTHMODE_NAME(auth_how|auth_crypt|auth_fwd));
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
-#endif /* CLIENT_CHOOSE_ONCE */
-
- switch (authentication_version) {
-#ifdef KRB4
- case AUTHTYPE_KERBEROS_V4:
- n = k4_auth_is(parsedat, end_sub);
- break;
-#endif
-#ifdef KRB5
- case AUTHTYPE_KERBEROS_V5:
- n = k5_auth_is(parsedat[3],parsedat, end_sub);
- break;
-#endif
-#ifdef CK_SRP
- case AUTHTYPE_SRP:
-#ifndef PRE_SRP_1_7_3
- n = new_srp_is(parsedat[3], parsedat, end_sub);
-#else /* PRE_SRP_1_7_3 */
- n = srp_is(parsedat[3], parsedat, end_sub);
-#endif /* PRE_SRP_1_7_3 */
- break;
-#endif /* SRP */
-#ifdef CK_SSL
- case AUTHTYPE_SSL:
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- n = ssl_is(parsedat, end_sub);
- break;
-#endif /* SSL */
-#ifdef NTLM
- case AUTHTYPE_NTLM:
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- n = ntlm_is(parsedat, end_sub);
- break;
-#endif /* NTLM */
- case AUTHTYPE_NULL:
- default:
- n = AUTH_FAILURE;
- }
- debug(F111,"auth_is","n",n);
- return n;
-}
-
-/*
- * Function: Parse authentication NAME command
- *
- * Parameters:
- * parsedat - the sub-command data.
- *
- * end_sub - index of the character in the 'parsedat' array which
- * is the last byte in a sub-negotiation
- *
- * Returns: Kerberos error code.
- */
-static int
-#ifdef CK_ANSIC
-auth_name(unsigned char *parsedat, int end_sub)
-#else
-auth_name(parsedat,end_sub) unsigned char *parsedat; int end_sub;
-#endif
-{
- int len = (end_sub-2) > 63 ? 63 : (end_sub-2);
- if ( len > 0 && (len + 1) < sizeof(szUserNameRequested)) {
- memcpy(szUserNameRequested,&parsedat[2],len); /* safe */
- szUserNameRequested[len] = '\0';
- } else
- szUserNameRequested[0] = '\0';
- debug(F111,"auth_name szUserNameRequested",szUserNameRequested,len);
- return(AUTH_SUCCESS);
-}
-
-/*
- * Function: Parse the athorization sub-options and reply.
- *
- * Parameters:
- * parsedat - sub-option string to parse.
- *
- * end_sub - last charcter position in parsedat.
- */
-int
-auth_parse(unsigned char *parsedat, int end_sub)
-{
- int rc = AUTH_FAILURE;
- switch (parsedat[1]) {
- case TELQUAL_SEND:
- rc = auth_send(parsedat, end_sub);
- break;
- case TELQUAL_REPLY:
- rc= auth_reply(parsedat, end_sub);
- break;
- case TELQUAL_IS:
- rc = auth_is(parsedat, end_sub);
- break;
- case TELQUAL_NAME:
- rc = auth_name(parsedat, end_sub);
- break;
- }
- debug(F111,"auth_parse","rc",rc);
- return(rc);
-}
-
-
-/*
- * Function: Initialization routine called kstream encryption system.
- *
- * Parameters:
- * data - user data.
- */
-int
-#ifdef CK_ANSIC
-auth_init(kstream ks)
-#else
-auth_init(ks) kstream_ptr ks;
-#endif
-{
-#ifdef FORWARD
- forwarded_tickets = 0; /* were tickets forwarded? */
-#endif /* FORWARD */
-#ifdef CK_ENCRYPTION
- encrypt_init(ks,cx_type);
-#endif
- return 0;
-}
-
-
-/*
- * Function: Destroy routine called kstream encryption system.
- *
- * Parameters:
- * data - user data.
- */
-VOID
-#ifdef CK_ANSIC
-auth_destroy(void)
-#else
-auth_destroy()
-#endif
-{
-}
-
-
-/*
- * Function: Callback to encrypt a block of characters
- *
- * Parameters:
- * out - return as pointer to converted buffer.
- *
- * in - the buffer to convert
- *
- * Returns: number of characters converted.
- */
-int
-#ifdef CK_ANSIC
-auth_encrypt(struct kstream_data_block *out,
- struct kstream_data_block *in)
-#else
-auth_encrypt(out,in)
- struct kstream_data_block *out; struct kstream_data_block *in;
-#endif
-{
- out->ptr = in->ptr;
-
- out->length = in->length;
-
- return(out->length);
-}
-
-
-/*
- * Function: Callback to decrypt a block of characters
- *
- * Parameters:
- * out - return as pointer to converted buffer.
- *
- * in - the buffer to convert
- *
- * Returns: number of characters converted.
- */
-int
-#ifdef CK_ANSIC
-auth_decrypt(struct kstream_data_block *out,
- struct kstream_data_block *in)
-#else
-auth_decrypt(out,in)
- struct kstream_data_block *out; struct kstream_data_block *in;
-#endif
-{
- out->ptr = in->ptr;
-
- out->length = in->length;
-
- return(out->length);
-}
-
-#ifdef KRB4
-#ifdef NT
-void
-ck_krb4_debug(int x)
-{
- set_krb_debug(x);
- set_krb_ap_req_debug(x);
-}
-#endif /* NT */
-int
-ck_krb4_autoget_TGT(char * realm)
-{
- extern struct krb_op_data krb_op;
- extern struct krb4_init_data krb4_init;
- char passwd[PWD_SZ];
- char prompt[256];
- char * saverealm=NULL;
- int rc = -1;
- extern char * k4prprompt;
- extern char * k4pwprompt;
-
- ini_kerb(); /* Place defaults in above structs */
- passwd[0] = '\0';
-
- if ( krb4_init.principal == NULL ||
- krb4_init.principal[0] == '\0') {
- int ok = uq_txt(NULL,
- k4prprompt && k4prprompt[0] ?
- k4prprompt :
- "Kerberos 4 Principal: ",
- 2, NULL, passwd,PWD_SZ-1, NULL, DEFAULT_UQ_TIMEOUT);
- if ( ok && passwd[0] )
- makestr(&krb4_init.principal,passwd);
- else
- return(0);
- }
-
- /* Save realm in init structure so it can be restored */
- if ( realm ) {
- saverealm = krb4_init.realm;
- krb4_init.realm = realm;
- }
-
- if ( passwd[0] || !(pwbuf[0] && pwflg) ) {
- int ok;
- if ( k4pwprompt && k4pwprompt[0] &&
- (strlen(k4pwprompt) + strlen(krb4_init.principal) +
- strlen(krb4_init.realm) - 4) < sizeof(prompt)) {
- sprintf(prompt,k4pwprompt,krb4_init.principal,krb4_init.realm);
- } else
- ckmakxmsg(prompt,sizeof(prompt),
- "Kerberos 4 Password for ",krb4_init.principal,"@",
- krb4_init.realm,": ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- ok = uq_txt(NULL,prompt,2,NULL,passwd,PWD_SZ-1,NULL,
- DEFAULT_UQ_TIMEOUT);
- if ( !ok )
- passwd[0] = '\0';
- } else {
- ckstrncpy(passwd,pwbuf,sizeof(passwd));
-#ifdef OS2
- if ( pwcrypt )
- ck_encrypt((char *)passwd);
-#endif /* OS2 */
- }
-
- if ( passwd[0] ) {
- makestr(&krb4_init.password,passwd);
- rc = ck_krb4_initTGT(&krb_op, &krb4_init);
- free(krb4_init.password);
- krb4_init.password = NULL;
- }
-
- krb4_init.password = NULL;
- memset(passwd,0,PWD_SZ);
-
- /* restore realm to init structure if needed */
- if ( saverealm )
- krb4_init.realm = saverealm;
- return(rc == 0);
-}
-
-char *
-ck_krb4_realmofhost(char *host)
-{
- return (char *)krb_realmofhost(host);
-}
-
-/*
- *
- * K4_auth_send - gets authentication bits we need to send to KDC.
- *
- * Result is left in auth
- *
- * Returns: 0 on failure, 1 on success
- */
-static int
-#ifdef CK_ANSIC
-k4_auth_send(void)
-#else
-k4_auth_send()
-#endif
-{
- int r=0; /* Return value */
- char instance[INST_SZ+1]="";
- char *realm=NULL;
- char tgt[4*REALM_SZ+1];
-
- memset(instance, 0, sizeof(instance));
-
-#ifdef COMMENT
- /* we only need to call krb_get_phost if the hostname */
- /* is not fully qualified. But we have already done */
- /* this in netopen() call. This will save a round of */
- /* DNS queries. */
- debug(F110,"k4_auth_send","krb_get_phost",0);
- if (realm = (char *)krb_get_phost(szHostName)) {
- ckstrncpy(instance, realm, INST_SZ);
- }
-#else /* COMMENT */
- {
- char *p;
- ckstrncpy(instance, szHostName, INST_SZ);
- for ( p=instance; *p && *p != '.' ; p++ );
- *p = '\0';
- }
-#endif /* COMMENT */
-
- debug(F110,"k4_auth_send","krb_get_realmofhost",0);
- realm = (char *)krb_realmofhost(szHostName);
-
- if (!realm) {
- strcpy(strTmp, "Can't find realm for host \"");
- ckstrncat(strTmp, szHostName,AUTHTMPBL);
- ckstrncat(strTmp, "\"",AUTHTMPBL);
- printf("?Kerberos 4 error: %s\r\n",strTmp);
- krb4_errno = r;
- makestr(&krb4_errmsg,strTmp);
- return(0);
- }
-
- ckmakmsg(tgt,sizeof(tgt),"krbtgt.",realm,"@",realm);
- r = ck_krb4_tkt_isvalid(tgt);
-
- if ( r <= 0 && krb4_autoget )
- ck_krb4_autoget_TGT(realm);
-
- debug(F110,"k4_auth_send","krb_mk_req",0);
- r = krb_mk_req(&k4_auth, krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
- instance, realm, 0);
-
- if (r == 0) {
- debug(F110,"k4_auth_send","krb_get_cred",0);
- r = krb_get_cred(krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
- instance, realm, &cred);
- if (r)
- debug(F111,"k4_auth_send","krb_get_cred() failed",r);
- }
- else
- debug(F111,"k4_auth_send","krb_mk_req() failed",r);
-
- if (r) {
- strcpy(strTmp, "Can't get \"");
- ckstrncat(strTmp,
- krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,AUTHTMPBL);
- if (instance[0] != 0) {
- ckstrncat(strTmp, ".",AUTHTMPBL);
- ckstrncat(strTmp, instance,AUTHTMPBL);
- }
- ckstrncat(strTmp, "@",AUTHTMPBL);
- ckstrncat(strTmp, realm,AUTHTMPBL);
- ckstrncat(strTmp, "\" ticket\r\n ",AUTHTMPBL);
- ckstrncat(strTmp, (char *)krb_get_err_text_entry(r),AUTHTMPBL);
- debug(F111,"k4_auth_send",(char *)krb_get_err_text_entry(r),r);
- printf("?Kerberos 4 error: %s\r\n",strTmp);
- krb4_errno = r;
- makestr(&krb4_errmsg,krb_get_err_text_entry(krb4_errno));
- return(0);
- }
-
-#ifdef OS2
- if ( !szUserName[0] || !stricmp(szUserName,cred.pname) ) {
- ckstrncpy(szUserName, cred.pname, UIDBUFLEN);
- }
-#endif /* OS2 */
- krb4_errno = r;
- makestr(&krb4_errmsg,krb_get_err_text_entry(krb4_errno));
- debug(F110,"k4_auth_send",krb4_errmsg,0);
- return(1);
-}
-
-/*
- * Function: K4 parse authentication reply command
- *
- * Parameters:
- * parsedat - the sub-command data.
- *
- * end_sub - index of the character in the 'parsedat' array which
- * is the last byte in a sub-negotiation
- *
- * Returns: Kerberos error code.
- */
-static int
-#ifdef CK_ANSIC
-k4_auth_reply(unsigned char *parsedat, int end_sub)
-#else
-k4_auth_reply(parsedat,end_sub) unsigned char *parsedat; int end_sub;
-#endif
-{
-#ifdef CK_ENCRYPTION
- Session_Key skey;
-#ifdef MIT_CURRENT
- krb5_data kdata;
- krb5_enc_data encdata;
- krb5_error_code code;
-#endif /* MIT_CURRENT */
-#endif
- time_t t;
- int x;
- int i;
-
- if (end_sub < 4 || parsedat[2] != AUTHTYPE_KERBEROS_V4) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- if (parsedat[4] == KRB_REJECT) {
- strTmp[0] = 0;
-
- for (i = 5; i <= end_sub; i++) {
- if (parsedat[i] == IAC)
- break;
- strTmp[i-5] = parsedat[i];
- strTmp[i-4] = 0;
- }
-
- if (!strTmp[0])
- strcpy(strTmp, "Authentication rejected by remote machine!");
- printf("Kerberos V4 authentication failed!\r\n%s\r\n",strTmp);
- krb4_errno = -1;
- makestr(&krb4_errmsg,strTmp);
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- if (parsedat[4] == KRB_ACCEPT) {
- int net_len;
- if ((parsedat[3] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) {
- ckmakmsg(strTmp,sizeof(strTmp),"Kerberos V4 accepts you as ",
- szUserName,NULL,NULL);
- printf("%s\r\n",strTmp);
- accept_complete = 1;
- krb4_errno = 0;
- makestr(&krb4_errmsg,strTmp);
- auth_finished(AUTH_USER);
- return AUTH_SUCCESS;
- }
-
- if ((parsedat[3] & AUTH_HOW_MASK) != AUTH_HOW_MUTUAL) {
- printf("Kerberos V4 authentication failed!\r\n");
- ckstrncpy(strTmp,
- "Kerberos V4 accepted you, but didn't provide mutual authentication",
- sizeof(strTmp));
- printf("%s\r\n",strTmp);
- krb4_errno = -1;
- makestr(&krb4_errmsg,strTmp);
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
-#ifndef REMOVE_FOR_EXPORT
-#ifdef CK_ENCRYPTION
- SendK4AuthSB(KRB4_CHALLENGE,k4_session_key,sizeof(k4_session_key));
-
- /* We have sent the decrypted session key to the host as a challenge */
- /* now encrypt it to restore it to its original valid DES key value */
-#ifdef MIT_CURRENT
- kdata.data = k4_session_key;
- kdata.length = 8;
-
- encdata.ciphertext.data = k4_session_key;
- encdata.ciphertext.length = 8;
- encdata.enctype = ENCTYPE_UNKNOWN;
-
- if (code = krb5_c_encrypt(k5_context, &k4_krbkey,
- 0, 0, &kdata, &encdata)) {
- com_err("k4_auth_reply", code,
- "while encrypting session_key");
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-#else /* MIT_CURRENT */
-#ifdef NT
- des_ecb_encrypt(k4_session_key, k4_session_key, k4_sched, 1);
-#else /* NT */
- des_ecb_encrypt(&k4_session_key, &k4_session_key, k4_sched, 1);
-#endif /* NT */
- ckhexdump(
- "k4_auth_reply des_ecb_encrypt(k4_session_key,k4_session_key,1)",
- k4_session_key,
- 8
- );
-#endif /* MIT_CURRENT */
-
-#ifdef CK_SSL
- if (!(ssl_active_flag || tls_active_flag))
-#endif /* CK_SSL */
- {
- /* And then use it to configure the encryption state machine. */
- skey.type = SK_DES;
- skey.length = 8;
- skey.data = k4_session_key;
- encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
- }
-#endif /* ENCRYPTION */
-#endif /* REMOVE_FOR_EXPORT */
- accept_complete = 1;
- ckmakmsg(strTmp,sizeof(strTmp),
- "Kerberos V4 accepts you as ",szUserName,NULL,NULL);
- printf("%s\r\n",strTmp);
- krb4_errno = 0;
- makestr(&krb4_errmsg,strTmp);
- auth_finished(AUTH_USER);
- return AUTH_SUCCESS;
- }
-
- if (parsedat[4] == KRB4_RESPONSE) {
- if (end_sub < 12) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- ckhexdump("KRB4_RESPONSE &parsedat[5]",&parsedat[5],8);
-#ifdef CK_ENCRYPTION
- ckhexdump("KRB4_RESPONSE k4_challenge",k4_challenge,8);
-
- /* The datablock returned from the host should match the value */
- /* we stored in k4_challenge. */
- if (memcmp(&parsedat[5], k4_challenge, sizeof(k4_challenge)) != 0) {
- printf("Kerberos V4 authentication failed!\r\n%s\r\n",
- "Remote machine is being impersonated!");
- krb4_errno = -1;
- makestr(&krb4_errmsg,"Remote machine is being impersonated!");
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-#else /* ENCRYPTION */
- makestr(&krb4_errmsg,"Kermit built without support for encryption.");
- return AUTH_FAILURE;
-#endif /* ENCRYPTION */
- mutual_complete = 1;
- ckstrncpy(strTmp,"Remote machine has been mutually authenticated",
- sizeof(strTmp));
- printf("%s\r\n",strTmp);
- krb4_errno = 0;
- makestr(&krb4_errmsg,strTmp);
- auth_finished(AUTH_USER);
- return AUTH_SUCCESS;
- }
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
-}
-
-/*
- * Function: K4 parse authentication IS command
- *
- * Parameters:
- * parsedat - the sub-command data.
- *
- * end_sub - index of the character in the 'parsedat' array which
- * is the last byte in a sub-negotiation
- *
- * Returns: Kerberos error code.
- */
-
-static int
-#ifdef CK_ANSIC
-k4_auth_is(unsigned char *parsedat, int end_sub)
-#else
-k4_auth_is(parsedat,end_sub) unsigned char *parsedat; int end_sub;
-#endif
-{
-#ifdef CK_ENCRYPTION
- Session_Key skey;
-#ifdef MIT_CURRENT
- Block datablock, tmpkey;
- krb5_data kdata;
- krb5_enc_data encdata;
- krb5_error_code code;
-#else /* MIT_CURRENT */
- Block datablock;
-#endif /* MIT_CURRENT */
-#endif /* ENCRYPTION */
- char realm[REALM_SZ+1];
- char instance[INST_SZ];
- int r = 0;
- char * data = &parsedat[5];
- int cnt = end_sub - 5;
- extern char myipaddr[];
- struct hostent *host;
- struct in_addr inaddr;
- int i;
-
- if (end_sub < 4 || parsedat[2] != AUTHTYPE_KERBEROS_V4) {
- debug(F110,"k4_auth_is","Not kerberos v4",0);
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- switch (parsedat[4]) {
- case KRB_AUTH:
- debug(F110,"k4_auth_is","KRB_AUTH",0);
- ckstrncpy(realm,ck_krb4_getrealm(),REALM_SZ+1);
- if (realm[0] == '\0') {
- SendK4AuthSB(KRB_REJECT, (void *)"No local V4 Realm.", -1);
- printf("\r\n? Kerberos 4 - No Local Realm\r\n");
- debug(F110,"k4_auth_is","No local realm",0);
- krb4_errno = -1;
- makestr(&krb4_errmsg,"No local realm");
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
- debug(F110,"k4_auth_is",realm,0);
- if ( cnt < sizeof(k4_auth.dat) ) {
- k4_auth.length = cnt;
- memcpy((void *)k4_auth.dat, (void *)data, k4_auth.length);
- } else
- k4_auth.length = 0;
- ckhexdump("k4_auth.dat",k4_auth.dat, k4_auth.length);
-
- /* Get Instance */
- inaddr.s_addr = inet_addr(myipaddr);
- host = gethostbyaddr((unsigned char *)&inaddr,4,PF_INET);
- if ( host ) {
-#ifdef HADDRLIST
- host = ck_copyhostent(host);
-#endif /* HADDRLIST */
- ckstrncpy(instance,host->h_name,INST_SZ);
- for ( i=0;i<INST_SZ;i++ ) {
- if ( instance[i] == '.' )
- instance[i] = '\0';
- else
- instance[i] = tolower(instance[i]);
- }
- } else {
- instance[0] = '*';
- instance[1] = 0;
- }
-
- if (r = krb_rd_req(&k4_auth,
- krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
- instance, 0, &k4_adat, k4_keytab)) {
-
- ckhexdump("k4_adat", &k4_adat, sizeof(AUTH_DAT));
- krb_kntoln(&k4_adat, k4_name);
- ckmakmsg(strTmp,sizeof(strTmp),
- "Kerberos failed him as ", k4_name,NULL,NULL);
- printf("%s\r\n",strTmp);
- krb4_errno = r;
- makestr(&krb4_errmsg,strTmp);
- SendK4AuthSB(KRB_REJECT, (void *)krb_get_err_text_entry(r), -1);
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
-#ifdef CK_ENCRYPTION
- memcpy((void *)k4_session_key, (void *)k4_adat.session,
- sizeof(Block)); /* safe */
- ckhexdump("k4_auth_is k4_session_key",k4_session_key,sizeof(Block));
-#endif /* ENCRYPTION */
- krb_kntoln(&k4_adat, k4_name);
-
- ckstrncpy(szUserNameAuthenticated,k4_name,UIDBUFLEN);
- if (szUserNameRequested && !kuserok(&k4_adat, k4_name)) {
- SendK4AuthSB(KRB_ACCEPT, (void *)0, 0);
- if ( !strcmp(k4_name,szUserNameRequested) )
- auth_finished(AUTH_VALID);
- else
- auth_finished(AUTH_USER);
- accept_complete = 1;
- }
- else {
- SendK4AuthSB(KRB_REJECT,
- (void *)"user is not authorized", -1);
- auth_finished(AUTH_REJECT);
- krb4_errno = r;
- makestr(&krb4_errmsg,"user is not authorized");
- return(AUTH_FAILURE);
- }
- break;
-
- case KRB4_CHALLENGE:
- debug(F110,"k4_auth_is","KRB_CHALLENGE",0);
-#ifndef CK_ENCRYPTION
- SendK4AuthSB(KRB4_RESPONSE, (void *)0, 0);
-#else /* ENCRYPTION */
- if (!VALIDKEY(k4_session_key)) {
- /*
- * We don't have a valid session key, so just
- * send back a response with an empty session
- * key.
- */
- SendK4AuthSB(KRB4_RESPONSE, (void *)0, 0);
- mutual_complete = 1;
- break;
- }
-
- /*
- * Initialize the random number generator since it's
- * used later on by the encryption routine.
- */
-#ifdef MIT_CURRENT
- kdata.data = k4_session_key;
- kdata.length = 8;
-
- if (code = krb5_c_random_seed(k5_context, &kdata)) {
- com_err("k4_auth_is", code,
- "while seeding random number generator");
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- memcpy((void *)datablock, (void *)data, sizeof(Block)); /* safe */
- /*
- * Take the received encrypted challenge, and encrypt
- * it again to get a unique session_key for the
- * ENCRYPT option.
- */
- k4_krbkey.enctype = ENCTYPE_DES_CBC_RAW;
- k4_krbkey.length = 8;
- k4_krbkey.contents = k4_session_key;
-
- kdata.data = datablock;
- kdata.length = 8;
-
- encdata.ciphertext.data = tmpkey;
- encdata.ciphertext.length = 8;
- encdata.enctype = ENCTYPE_UNKNOWN;
-
- if (code = krb5_c_encrypt(k5_context, &k4_krbkey, 0, 0,
- &kdata, &encdata)) {
- com_err("k4_auth_is", code, "while encrypting random key");
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
-#ifdef CK_SSL
- if (!(ssl_active_flag || tls_active_flag))
-#endif /* CK_SSL */
- {
- skey.type = SK_DES;
- skey.length = 8;
- skey.data = tmpkey;
- encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
- }
- /*
- * Now decrypt the received encrypted challenge,
- * increment by one, re-encrypt it and send it back.
- */
- encdata.ciphertext.data = datablock;
- encdata.ciphertext.length = 8;
- encdata.enctype = ENCTYPE_UNKNOWN;
-
- kdata.data = k4_challenge;
- kdata.length = 8;
-
- if (code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
- &encdata, &kdata)) {
- com_err("k4_auth_is", code, "while decrypting challenge");
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-#else /* MIT_CURRENT */
- des_set_random_generator_seed(k4_session_key);
- r = des_key_sched(k4_session_key, k4_sched);
- if ( r == -1 ) {
- printf("?Invalid DES key specified in credentials\r\n");
- debug(F110,"auth_is CHALLENGE",
- "invalid DES Key specified in credentials",0);
- } else if ( r == -2 ) {
- printf("?Weak DES key specified in credentials\r\n");
- debug(F110,"auth_is CHALLENGE",
- "weak DES Key specified in credentials",0);
- } else if ( r != 0 ) {
- printf("?DES Key Schedule not set by credentials\r\n");
- debug(F110,"auth_is CHALLENGE",
- "DES Key Schedule not set by credentials",0);
- }
- ckhexdump("auth_is schedule",k4_sched,8*16);
-
- memcpy((void *)datablock, (void *)data, sizeof(Block)); /* safe */
- ckhexdump("auth_is challege",datablock,sizeof(Block));
-
- /*
- * Take the received encrypted challenge, and encrypt
- * it again to get a unique k4_session_key for the
- * ENCRYPT option.
- */
-#ifdef NT
- des_ecb_encrypt(datablock, k4_session_key, k4_sched, 1);
-#else /* NT */
- des_ecb_encrypt(&datablock, &k4_session_key, k4_sched, 1);
-#endif /* NT */
- ckhexdump("auth_is des_ecb_encrypt(datablock,k4_session_key,1)",
- k4_session_key,8);
-
-#ifdef CK_SSL
- if (!(ssl_active_flag || tls_active_flag))
-#endif /* CK_SSL */
- {
- skey.type = SK_DES;
- skey.length = 8;
- skey.data = k4_session_key;
- encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
- }
- /*
- * Now decrypt the received encrypted challenge,
- * increment by one, re-encrypt it and send it back.
- */
-#ifdef NT
- des_ecb_encrypt(datablock, k4_challenge, k4_sched, 0);
-#else /* NT */
- des_ecb_encrypt(&datablock, &k4_challenge, k4_sched, 0);
-#endif /* NT */
- ckhexdump("auth_is des_ecb_encrypt(datablock,k4_challenge,0)",
- k4_session_key,8);
-#endif /* MIT_CURRENT */
- for (r = 7; r >= 0; r--) {
- register int t;
- t = (unsigned int)k4_challenge[r] + 1;
- k4_challenge[r] = t; /* ignore overflow */
- if (t < 256) /* if no overflow, all done */
- break;
- }
- ckhexdump("auth_is k4_challenge+1",k4_challenge,8);
-
-#ifdef MIT_CURRENT
- kdata.data = k4_challenge;
- kdata.length = 8;
-
- encdata.ciphertext.data = k4_challenge;
- encdata.ciphertext.length = 8;
- encdata.enctype = ENCTYPE_UNKNOWN;
-
- if (code = krb5_c_encrypt(k5_context, &k4_krbkey, 0, 0,
- &kdata, &encdata)) {
- com_err("k4_auth_is", code, "while decrypting challenge");
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-#else /* MIT_CURRENT */
-#ifdef NT
- des_ecb_encrypt(k4_challenge, k4_challenge, k4_sched, 1);
-#else /* NT */
- des_ecb_encrypt(&k4_challenge, &k4_challenge, k4_sched, 1);
-#endif /* NT */
- ckhexdump("auth_is des_ecb_encrypt(k4_challenge_key,k4_challenge,1)",
- k4_challenge,8);
-
-#endif /* MIT_CURRENT */
- SendK4AuthSB(KRB4_RESPONSE,(void *)k4_challenge,sizeof(k4_challenge));
-#endif /* ENCRYPTION */
- mutual_complete = 1;
- break;
-
- default:
- if (1)
- printf("Unknown Kerberos option %d\r\n", data[-1]);
- SendK4AuthSB(KRB_REJECT, 0, 0);
- return(AUTH_FAILURE);
- }
- krb4_errno = r;
- makestr(&krb4_errmsg,krb_get_err_text_entry(krb4_errno));
- return(AUTH_SUCCESS);
-}
-#endif /* KRB4 */
-
-#ifdef KRB5
-int
-ck_krb5_autoget_TGT(char * realm)
-{
- extern struct krb_op_data krb_op;
- extern struct krb5_init_data krb5_init;
- char passwd[PWD_SZ];
- char prompt[64];
- char * saverealm=NULL;
- int rc = -1;
- extern char * k5prprompt;
- extern char * k5pwprompt;
-
- ini_kerb(); /* Place defaults in above structs */
- passwd[0] = '\0';
-
- if ( krb5_init.principal == NULL ||
- krb5_init.principal[0] == '\0') {
- int ok = uq_txt(NULL,k5prprompt && k5prprompt[0] ? k5prprompt :
- "Kerberos 5 Principal: ",2,NULL,passwd,PWD_SZ-1,NULL,
- DEFAULT_UQ_TIMEOUT);
- if ( ok && passwd[0] )
- makestr(&krb5_init.principal,passwd);
- else
- return(0);
- }
-
- /* Save realm in init structure so it can be restored */
- if ( realm ) {
- saverealm = krb5_init.realm;
- krb5_init.realm = realm;
- }
-
- if ( passwd[0] || !(pwbuf[0] && pwflg) ) {
- int ok;
- if ( k5pwprompt && k5pwprompt[0] &&
- (strlen(k5pwprompt) + strlen(krb5_init.principal) +
- strlen(krb5_init.realm) - 4) < sizeof(prompt)) {
- sprintf(prompt,k5pwprompt,krb5_init.principal,krb5_init.realm);
- } else
- ckmakxmsg(prompt,sizeof(prompt),
- k5pwprompt && k5pwprompt[0] ? k5pwprompt :
- "Kerberos 5 Password for ",
- krb5_init.principal,"@",krb5_init.realm,": ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- ok = uq_txt(NULL,prompt,2,NULL,passwd,PWD_SZ-1,NULL,
- DEFAULT_UQ_TIMEOUT);
- if ( !ok )
- passwd[0] = '\0';
- } else {
- ckstrncpy(passwd,(char *)pwbuf,sizeof(passwd));
-#ifdef OS2
- if ( pwcrypt )
- ck_encrypt((char *)passwd);
-#endif /* OS2 */
- }
-
- if ( passwd[0] ) {
- extern struct krb4_init_data krb4_init;
- char * savek4realm=NULL;
-
- makestr(&krb5_init.password,passwd);
-
- if ( krb5_d_getk4 ) {
- krb5_init.getk4 = 1;
- makestr(&krb4_init.principal,krb5_init.principal);
- makestr(&krb4_init.password,passwd);
- if ( realm ) {
- savek4realm = krb4_init.realm;
- krb4_init.realm = realm;
- }
- rc = ck_krb5_initTGT(&krb_op, &krb5_init,&krb4_init);
-
- if ( savek4realm )
- krb4_init.realm = savek4realm;
- free(krb4_init.password);
- krb4_init.password = NULL;
- } else {
- rc = ck_krb5_initTGT(&krb_op, &krb5_init,NULL);
- }
-
- free(krb5_init.password);
- krb5_init.password = NULL;
-
- memset(passwd,0,PWD_SZ);
- }
-
- /* restore realm to init structure if needed */
- if ( saverealm )
- krb5_init.realm = saverealm;
- return(rc == 0);
-}
-
-static krb5_error_code
-#ifdef CK_ANSIC
-k5_get_ccache( krb5_context k5_context, krb5_ccache * p_ccache,
- char * cc_name )
-#else /* CK_ANSIC */
-k5_get_ccache(k5_context, p_ccache, cc_name)
- krb5_context k5_context;
- krb5_ccache * p_ccache;
- char * cc_name;
-#endif /* CK_ANSIC */
-{
- krb5_error_code r=0;
- char cc_tmp[CKMAXPATH+1];
- const char * def_name = NULL;
-
-#ifndef HEIMDAL
- if ( cc_name ) {
- if ( strncmp("FILE:",cc_name,5) &&
- strncmp("MEMORY:",cc_name,7) &&
- strncmp("API:",cc_name,4) &&
- strncmp("STDIO:",cc_name,6) &&
- strncmp("MSLSA:",cc_name,6))
-#ifdef NT
- ckmakmsg(cc_tmp,CKMAXPATH,"API:",cc_name,NULL,NULL);
-#else /* NT */
- ckmakmsg(cc_tmp,CKMAXPATH,"FILE:",cc_name,NULL,NULL);
-#endif /* NT */
- else {
- ckstrncpy(cc_tmp,cc_name,CKMAXPATH);
- }
- r = krb5_cc_resolve (k5_context, cc_tmp, p_ccache);
- if (r != 0) {
- com_err("k5_get_ccache resolving ccache",r,
- cc_tmp);
- } else {
- /* Make sure GSSAPI sees the same cache we are using */
- char buf[128];
- ckmakmsg((char *)buf,128,"KRB5CCNAME=",cc_tmp,NULL,NULL);
- putenv(buf);
- }
- } else if ( krb5_d_cc ) {
- if ( strncmp("FILE:",krb5_d_cc,5) &&
- strncmp("MEMORY:",krb5_d_cc,7) &&
- strncmp("API:",krb5_d_cc,4) &&
- strncmp("STDIO:",krb5_d_cc,6) &&
- strncmp("MSLSA:", krb5_d_cc,6))
-#ifdef NT
- ckmakmsg(cc_tmp,CKMAXPATH,"API:",krb5_d_cc,NULL,NULL);
-#else /* NT */
- ckmakmsg(cc_tmp,CKMAXPATH,"FILE:",krb5_d_cc,NULL,NULL);
-#endif /* NT */
- else {
- ckstrncpy(cc_tmp,krb5_d_cc,CKMAXPATH);
- }
- r = krb5_cc_resolve (k5_context, cc_tmp, p_ccache);
- if (r != 0) {
- com_err("k5_get_ccache resolving ccache",r,
- krb5_d_cc);
- } else {
- /* Make sure GSSAPI sees the same cache we are using */
- char buf[128];
- ckmakmsg((char *)buf,128,"KRB5CCNAME=",cc_tmp,NULL,NULL);
- putenv(buf);
- }
- } else
-#endif /* HEIMDAL */
- {
- if ((r = krb5_cc_default(k5_context, p_ccache))) {
- com_err("k5_get_ccache",r,"while getting default ccache");
- }
- }
- /* do not set krb5_errno/krb5_errmsg here since the value returned */
- /* is being passed internally within the krb5 functions. */
- return(r);
-}
-
-
-char *
-ck_krb5_realmofhost(char *host)
-{
- char ** realmlist=NULL;
- krb5_context private_context=NULL;
- static char * realm = NULL;
-
- if ( !host )
- return NULL;
-
- if ( realm ) {
- free(realm);
- realm = NULL;
- }
-
- /* create private_context */
- if (krb5_init_context(&private_context)) {
- debug(F110,"ck_krb5_realmofhost()","unable to init_context",0);
- return(NULL);
- }
-
- krb5_get_host_realm(private_context,host,&realmlist);
- if (realmlist && realmlist[0]) {
- makestr(&realm,realmlist[0]);
- krb5_free_host_realm(private_context,realmlist);
- realmlist = NULL;
- }
-
- if ( private_context ) {
- krb5_free_context(private_context);
- private_context = NULL;
- }
-
- if (ckstrchr(realm,'.') == NULL) {
- int n = 0;
- char * p = host;
- while ( (p = ckstrchr(p,'.')) != NULL ) {
- n++;
- p++;
- }
- if (n == 1) {
- makestr(&realm,host);
- ckupper(realm);
- } else {
- free(realm);
- realm = NULL;
- }
- }
- return(realm);
-}
-
-/*
- *
- * K5_auth_send - gets authentication bits we need to send to KDC.
- *
- * Code lifted from telnet sample code in the appl directory.
- *
- * Result is left in k5_auth
- *
- * Returns: 0 on failure, 1 on success
- *
- */
-
-static int
-#ifdef CK_ANSIC
-k5_auth_send(int how, int encrypt, int forward)
-#else
-k5_auth_send(how,encrypt,forward) int how; int encrypt; int forward;
-#endif
-{
- krb5_error_code r=0;
- krb5_ccache ccache=NULL;
-#ifndef HEIMDAL
- krb5_creds creds;
-#endif /* HEIMDAL */
- krb5_creds * new_creds=NULL;
-#ifdef CK_ENCRYPTION
- krb5_keyblock *newkey = 0;
-#endif /* CK_ENCRYPTION */
- krb5_flags ap_opts, auth_flags;
- char type_check[32];
- krb5_data checksum;
- int len=0;
- char * realm = NULL;
- char tgt[256];
-
- realm = ck_krb5_realmofhost(szHostName);
- if (!realm) {
- ckstrncpy(strTmp, "Can't find realm for host \"",AUTHTMPBL);
- ckstrncat(strTmp, szHostName,AUTHTMPBL);
- ckstrncat(strTmp, "\"",AUTHTMPBL);
- printf("?Kerberos 5 error: %s\r\n",strTmp);
- krb5_errno = KRB5_ERR_HOST_REALM_UNKNOWN;
- makestr(&krb5_errmsg,strTmp);
- return(0);
- }
-
- ckmakmsg(tgt,sizeof(tgt),"krbtgt/",realm,"@",realm);
- debug(F110,"k5_auth_send TGT",tgt,0);
- if ( krb5_autoget &&
- !((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
- (ck_krb5_is_tgt_valid() > 0)) )
- ck_krb5_autoget_TGT(realm);
-
- r = k5_get_ccache(k5_context,&ccache,NULL);
- if ( r ) {
- com_err(NULL, r, "while authorizing (0).");
- krb5_errno = r;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(0);
- }
-
-#ifndef HEIMDAL
- memset((char *)&creds, 0, sizeof(creds));
- if (r = krb5_sname_to_principal(k5_context, szHostName,
- krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
- KRB5_NT_SRV_HST, &creds.server)) {
- com_err(NULL, r, "while authorizing (1).");
- krb5_errno = r;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(0);
- }
-
- if (forward_flag) {
- if (fwd_server) {
- krb5_free_principal(k5_context,fwd_server);
- fwd_server = NULL;
- }
- krb5_copy_principal(k5_context,creds.server,&fwd_server);
- }
-
- r = krb5_cc_get_principal(k5_context, ccache, &creds.client);
- if (r) {
- com_err(NULL, r, "while authorizing (2).");
- krb5_free_cred_contents(k5_context, &creds);
- krb5_errno = r;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(0);
- }
-
- if (szUserName[0] == '\0') { /* Get user name now */
- len = krb5_princ_component(k5_context, creds.client, 0)->length;
- if ( len < sizeof(szUserName) ) {
- memcpy(szUserName,
- krb5_princ_component(k5_context, creds.client, 0)->data,
- len); /* safe */
- } else
- len = 0;
- szUserName[len] = '\0';
- } else {
- char * name = NULL;
- len = krb5_princ_component(k5_context, creds.client, 0)->length;
- if ( len == strlen(szUserName) ) {
- name = krb5_princ_component(k5_context, creds.client, 0)->data;
-#ifdef OS2
- if ( !strnicmp(szUserName,name,len) )
- memcpy(szUserName,name,len); /* safe */
-#endif /* OS2 */
- }
- }
- if ( tn_auth_krb5_des_bug ) { /* !ALLOW_KRB_3DES_ENCRYPT */
- /* Not sure if this is necessary anymore. What impact does it have
- * on Win2000 TGTs that use DES_CBC_MD5 or RC4_HMAC?
- *
- * This prevents using 3DES Service Tickets.
- */
- creds.keyblock.enctype=ENCTYPE_DES_CBC_CRC;
- }
-
- if (r = krb5_get_credentials(k5_context, 0,
- ccache, &creds, &new_creds)) {
- com_err(NULL, r, "while authorizing (3).");
- krb5_free_cred_contents(k5_context, &creds);
- krb5_errno = r;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(0);
- }
-#endif /* HEIMDAL */
-
- if (auth_context) {
- krb5_auth_con_free(k5_context, auth_context);
- auth_context = 0;
- }
- if (r = krb5_auth_con_init(k5_context, &auth_context)) {
- com_err(NULL, r, "while initializing auth context");
- krb5_errno = r;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(0);
- }
-
- /* UPDATE for START_TLS. AUTH_ENCRYPT_START_TLS and inclusion of */
- /* client and then server finished messages. */
-
- type_check[0] = AUTHTYPE_KERBEROS_V5;
- type_check[1] = AUTH_CLIENT_TO_SERVER |
- (how ? AUTH_HOW_MUTUAL : AUTH_HOW_ONE_WAY) |
- (encrypt) |
- (forward ? INI_CRED_FWD_ON : INI_CRED_FWD_OFF);
-#ifdef CK_SSL
- if (encrypt == AUTH_ENCRYPT_START_TLS) {
- ssl_get_client_finished(&type_check[2],12);
- ssl_get_server_finished(&type_check[14],12);
- }
-#endif /* CK_SSL */
-
-#ifndef HEIMDAL
- checksum.magic = KV5M_DATA;
-#endif /* HEIMDAL */
- checksum.length =
-#ifdef CK_SSL
- (encrypt == AUTH_ENCRYPT_START_TLS) ? 26 :
-#endif /* CK_SSL */
- 2;
- checksum.data = (char *)&type_check;
-
- ap_opts = 0;
- if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
- ap_opts |= AP_OPTS_MUTUAL_REQUIRED;
-
-#ifdef HEIMDAL
- r = krb5_auth_setkeytype(k5_context, auth_context, KEYTYPE_DES);
- if (r)
- com_err(NULL, r, "while setting auth keytype");
- r = krb5_auth_con_setaddrs_from_fd(k5_context,auth_context, &ttyfd);
- if (r)
- com_err(NULL, r, "while setting auth addrs");
- r = krb5_mk_req(k5_context, &auth_context, ap_opts,
- krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
- szHostName, &checksum, ccache, &k5_auth);
- if (r)
- com_err(NULL, r, "while making request");
-#else /* HEIMDAL */
- auth_flags = KRB5_AUTH_CONTEXT_RET_TIME;
-#ifdef CK_ENCRYPTION
- ap_opts |= AP_OPTS_USE_SUBKEY;
-#endif /* CK_ENCRYPTION */
-#ifdef TLS_VERIFY
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- auth_flags |= KRB5_AUTH_CONTEXT_DO_SEQUENCE;
- if (!krb5_d_no_addresses)
- r = krb5_auth_con_genaddrs(k5_context, auth_context, ttyfd,
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR);
- }
-#endif /* CK_SSL */
- krb5_auth_con_setflags(k5_context, auth_context, auth_flags);
- r = krb5_mk_req_extended(k5_context, &auth_context, ap_opts,
- &checksum, new_creds, &k5_auth);
-#endif /* HEIMDAL */
-
-#ifdef CK_ENCRYPTION
- if (!r) {
- r = krb5_auth_con_getlocalsubkey(k5_context, auth_context, &newkey);
- if (r)
- r = krb5_auth_con_getkey(k5_context, auth_context, &newkey);
-
- if (k5_session_key) {
- krb5_free_keyblock(k5_context, k5_session_key);
- k5_session_key = 0;
- }
- }
- if (newkey) {
- /*
- * keep the key in our private storage, but don't use it
- * yet---see kerberos5_reply() below
- */
-#ifdef HEIMDAL
- if ((newkey->keytype == ETYPE_DES_CBC_CRC) ||
- (newkey->keytype == ETYPE_DES_CBC_MD5) ||
- (newkey->keytype == ETYPE_DES_CBC_MD4))
- {
- debug(F111,"k5_auth_send()","newkey->keytype",newkey->keytype);
- krb5_copy_keyblock(k5_context, newkey, &k5_session_key);
- }
-#else /* HEIMDAL */
- /* look for all possible DES keys first - just for compatibility */
- /* other key types are much less likely to be available */
- if ((newkey->enctype == ENCTYPE_DES_CBC_CRC) ||
- (newkey->enctype == ENCTYPE_DES_CBC_MD5) ||
- (newkey->enctype == ENCTYPE_DES_CBC_MD4))
- {
- debug(F111,"k5_auth_send()","newkey->enctype",newkey->enctype);
- krb5_copy_keyblock(k5_context, newkey, &k5_session_key);
- }
- else if ((new_creds->keyblock.enctype == ENCTYPE_DES_CBC_CRC) ||
- (new_creds->keyblock.enctype == ENCTYPE_DES_CBC_MD5))
- {
- /* use the session key in credentials instead */
- debug(F111,"k5_auth_send()","new_creds->keyblock.enctype",
- new_creds->keyblock.enctype);
- krb5_copy_keyblock(k5_context,
- &new_creds->keyblock, &k5_session_key);
- }
- else if (newkey->enctype != 0)
- {
- debug(F111,"k5_auth_send()","newkey->enctype",newkey->enctype);
- krb5_copy_keyblock(k5_context, newkey, &k5_session_key);
- }
- else if (new_creds->keyblock.enctype != 0)
- {
- /* use the session key in credentials instead */
- debug(F111,"k5_auth_send()","new_creds->keyblock.enctype",
- new_creds->keyblock.enctype);
- krb5_copy_keyblock(k5_context,
- &new_creds->keyblock, &k5_session_key);
- }
- else {
- debug(F110,"k5_auth_send()","NO KEY in newkey",0);
- }
-#endif /* HEIMDAL */
- krb5_free_keyblock(k5_context, newkey);
- }
-#endif /* CK_ENCRYPTION */
-#ifndef HEIMDAL
- krb5_free_cred_contents(k5_context, &creds);
- krb5_free_creds(k5_context, new_creds);
-#endif /* HEIMDAL */
- krb5_cc_close(k5_context,ccache);
-
- if (r) {
- com_err(NULL, r, "while authorizing (4).");
- krb5_errno = r;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(0);
- }
- krb5_errno = 0;
- makestr(&krb5_errmsg,"OK");
- return(1);
-}
-
-/*
- * K5_auth_reply -- checks the reply for mutual authentication.
- */
-static int
-#ifdef CK_ANSIC
-k5_auth_reply(int how, unsigned char *data, int cnt)
-#else
-k5_auth_reply(how,data,cnt) int how; unsigned char *data; int cnt;
-#endif
-{
-#ifdef CK_ENCRYPTION
- Session_Key skey;
-#endif /* CK_ENCRYPTION */
-
- data += 4; /* Point to status byte */
- cnt -=5;
-
- switch (*data++) {
- case KRB_REJECT:
- if (cnt > 0) {
- char *s;
- int len;
- ckstrncpy(strTmp,"Kerberos V5 refuses authentication because\r\n",
- sizeof(strTmp));
- len = strlen(strTmp);
- if ( len + cnt < sizeof(strTmp) ) {
- s = strTmp + strlen(strTmp);
- memcpy(s, data, cnt); /* safe */
- s[cnt] = 0;
- }
- } else
- ckstrncpy(strTmp,"Kerberos V5 refuses authentication",
- sizeof(strTmp));
- krb5_errno = -1;
- makestr(&krb5_errmsg,strTmp);
- printf("Kerberos authentication failed!\r\n%s\r\n",strTmp);
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
-
- case KRB_ACCEPT:
- if (!mutual_complete) {
- if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && !mutual_complete) {
- ckstrncpy(strTmp,
- "Kerberos V5 accepted you, but didn't provide"
- " mutual authentication",sizeof(strTmp));
- printf("Kerberos authentication failed!\r\n%s\r\n",strTmp);
- krb5_errno = -1;
- makestr(&krb5_errmsg,strTmp);
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
-#ifdef CK_ENCRYPTION
- if (k5_session_key) {
- if ( tn_auth_krb5_des_bug ) { /* !ALLOW_KRB_3DES_ENCRYPT */
- skey.type = SK_DES;
- skey.length = 8;
-#ifdef HEIMDAL
- skey.data = k5_session_key->keyvalue.data;
-#else /* HEIMDAL */
- skey.data = k5_session_key->contents;
-#endif /* HEIMDAL */
- } else {
-#ifdef HEIMDAL
- switch ( k5_session_key->keytype ) {
- case ETYPE_DES_CBC_CRC:
- case ETYPE_DES_CBC_MD5:
- case ETYPE_DES_CBC_MD4:
- skey.type = SK_DES;
- skey.length = 8;
- break;
- default:
- skey.type = SK_GENERIC;
- skey.length = k5_session_key->length;
- encrypt_dont_support(ENCTYPE_DES_CFB64);
- encrypt_dont_support(ENCTYPE_DES_OFB64);
- }
- skey.data = k5_session_key->keyvalue.data;
-#else /* HEIMDAL */
- switch ( k5_session_key->enctype ) {
- case ENCTYPE_DES_CBC_CRC:
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES_CBC_MD4:
- skey.type = SK_DES;
- skey.length = 8;
- default:
- skey.type = SK_GENERIC;
- skey.length = k5_session_key->length;
- encrypt_dont_support(ENCTYPE_DES_CFB64);
- encrypt_dont_support(ENCTYPE_DES_OFB64);
- }
- skey.data = k5_session_key->contents;
-#endif /* HEIMDAL */
- }
- encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
- }
-#endif /* CK_ENCRYPTION */
- }
- if ( cnt > 0 ) {
- char *s;
- int len;
- ckstrncpy(strTmp,"Kerberos V5 accepts you as ",sizeof(strTmp));
- len = strlen(strTmp);
- if ( len + cnt < sizeof(strTmp) ) {
- s = strTmp + strlen(strTmp);
- memcpy(s,data,cnt);
- s[cnt] = 0;
- }
- }
- accept_complete = 1;
- printf("%s\r\n",strTmp);
-
-#ifdef FORWARD
- if (forward_flag
-#ifdef COMMENT
- /* Marc Horowitz <marc@mit.edu> has successfully argued
- that it is indeed safe to send Forwarded credentials
- to an untrusted host.
- */
- && (auth_how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL
-#endif /* COMMENT */
- )
- kerberos5_forward();
-#endif /* FORWARD */
- krb5_errno = 0;
- makestr(&krb5_errmsg,strTmp);
- auth_finished(AUTH_USER);
- return AUTH_SUCCESS;
-
- case KRB5_RESPONSE:
-#ifdef TLS_VERIFY
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS &&
- !krb5_tls_verified) {
- printf(
- "Man in the middle attack detected. Session terminated.\r\n");
-#ifndef BETATEST
- netclos();
-#endif /* BETATEST */
- krb5_errno = -1;
- makestr(&krb5_errmsg,"TLS not verified");
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
- if((ssl_active_flag || tls_active_flag) &&
- (how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- printf("TLS session parameters verified by Kerberos 5\r\n");
- }
-#endif /* TLS_VERIFY */
- if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- /* the rest of the reply should contain a krb_ap_rep */
- krb5_ap_rep_enc_part *reply;
- krb5_data inbuf;
- krb5_error_code r;
-
- inbuf.length = cnt;
- inbuf.data = (char *)data;
-
- if (r = krb5_rd_rep(k5_context, auth_context, &inbuf, &reply)) {
- com_err(NULL, r, "while authorizing. (5)");
- krb5_errno = r;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
- krb5_free_ap_rep_enc_part(k5_context, reply);
-
-#ifdef CK_ENCRYPTION
- if (encrypt_flag && k5_session_key) {
- if ( tn_auth_krb5_des_bug ) { /* !ALLOW_KRB_3DES_ENCRYPT */
- skey.type = SK_DES;
- skey.length = 8;
-#ifdef HEIMDAL
- skey.data = k5_session_key->keyvalue.data;
-#else /* HEIMDAL */
- skey.data = k5_session_key->contents;
-#endif /* HEIMDAL */
- } else {
-#ifdef HEIMDAL
- switch ( k5_session_key->keytype ) {
- case ETYPE_DES_CBC_CRC:
- case ETYPE_DES_CBC_MD5:
- case ETYPE_DES_CBC_MD4:
- skey.type = SK_DES;
- skey.length = 8;
- default:
- skey.type = SK_GENERIC;
- skey.length = k5_session_key->length;
- }
- skey.data = k5_session_key->keyvalue.data;
-#else /* HEIMDAL */
- switch ( k5_session_key->enctype ) {
- case ENCTYPE_DES_CBC_CRC:
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES_CBC_MD4:
- skey.type = SK_DES;
- skey.length = 8;
- break;
- default:
- skey.type = SK_GENERIC;
- skey.length = k5_session_key->length;
- }
- skey.data = k5_session_key->contents;
-#endif /* HEIMDAL */
- }
- encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
- }
-#endif /* ENCRYPTION */
- mutual_complete = 1;
- }
- ckstrncpy(strTmp,"Remote machine has been mutually authenticated",
- sizeof(strTmp));
- krb5_errno = 0;
- makestr(&krb5_errmsg,strTmp);
- printf("%s\r\n",strTmp);
- auth_finished(AUTH_USER);
- return AUTH_SUCCESS;
-
-#ifdef FORWARD
- case KRB5_FORWARD_ACCEPT:
- forwarded_tickets = 1;
- ckstrncpy(strTmp,"Remote machine has accepted forwarded credentials",
- sizeof(strTmp));
- krb5_errno = 0;
- makestr(&krb5_errmsg,strTmp);
- printf("%s\r\n",strTmp);
- return AUTH_SUCCESS;
-
- case KRB5_FORWARD_REJECT:
- forwarded_tickets = 0;
- if (cnt > 0) {
- char *s;
- int len;
- len = ckstrncpy(strTmp,
- "Kerberos V5 refuses forwarded credentials because ",
- sizeof(strTmp));
- if ( len + cnt < sizeof(strTmp) ) {
- s = strTmp + strlen(strTmp);
- memcpy(s, data, cnt);
- s[cnt] = 0;
- }
- } else
- ckstrncpy(strTmp, "Kerberos V5 refuses forwarded credentials",
- sizeof(strTmp));
-
- printf("%s\r\n",strTmp);
- krb5_errno = -1;
- makestr(&krb5_errmsg,strTmp);
- return AUTH_SUCCESS;
-#endif /* FORWARD */
-
-#ifdef TLS_VERIFY
- case KRB5_TLS_VERIFY:
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- krb5_data reply, msg;
- char tls_verify[24];
- krb5_replay_data repdata;
- krb5_error_code r;
-
- ssl_get_server_finished(&tls_verify[0],12);
- ssl_get_client_finished(&tls_verify[12],12);
-
- reply.data = (char *)data;
- reply.length = cnt;
-
- krb5_auth_con_genaddrs(k5_context, auth_context, ttyfd,
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR);
-
- if (r = krb5_rd_safe(k5_context,auth_context,&reply,&msg,&repdata))
- {
- com_err("", r, "decoding tls verifier");
- krb5_errno = r;
- makestr(&krb5_errmsg,"TLS verify failure");
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
- if ( msg.length == 24 && !memcmp(msg.data,tls_verify,24) )
- krb5_tls_verified = 1;
- krb5_free_data_contents(k5_context,&msg);
- if (krb5_tls_verified)
- return(AUTH_SUCCESS);
- }
- printf("Man in the middle attack detected. Session terminated.\r\n");
- netclos();
- krb5_errno = -1;
- makestr(&krb5_errmsg,"TLS verify failure");
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
-#endif /* CK_SSL */
-
- default:
- krb5_errno = -1;
- makestr(&krb5_errmsg,"Unknown reply type");
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE; /* Unknown reply type */
- }
-}
-
-#ifdef FORWARD
-/* Decode, decrypt and store the forwarded creds in the local ccache. */
-/* Needed for KRB5_FORWARD */
-static krb5_error_code
-rd_and_store_for_creds(context, auth_context, inbuf, client)
- krb5_context context;
- krb5_auth_context auth_context;
- krb5_data *inbuf;
- krb5_const_principal client;
-{
- krb5_creds ** creds=NULL;
- krb5_error_code retval;
- krb5_ccache ccache=NULL;
-
-#ifdef HEIMDAL
- /*
- Heimdal Telnetd creates the cache file at this point and sets
- the KRB5CCNAME environment variable.
-
- struct passwd *pwd;
- char ccname[1024];
-
- pwd = getpwnam(szUserNameRequested);
- if (pwd == NULL)
- break;
- snprintf(ccname, sizeof(ccname)-1, "FILE:/tmp/krb5cc_%u",pwd->pw_uid);
- retval = krb5_cc_resolve(context,ccname,&ccache);
-
- chown(ccname + 5, pwd->pw_uid, -1);
- */
-#endif /* HEIMDAL */
-
- if (retval = k5_get_ccache(context,&ccache,NULL))
- return(retval);
-
-#ifdef HEIMDAL
- if ((retval = krb5_cc_initialize(context, ccache, client)))
- return(retval);
-
- if ((retval = krb5_rd_cred(context, auth_context, ccache, inbuf)))
- return(retval);
-#else /* HEIMDAL */
- if ((retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL)))
- return(retval);
-
- if ((retval = krb5_cc_initialize(context, ccache, creds[0]->client)))
- goto cleanup;
-
- if ((retval = krb5_cc_store_cred(context, ccache, creds[0])))
- goto cleanup;
-
- if ((retval = krb5_cc_close(context, ccache)))
- goto cleanup;
-
- cleanup:
- krb5_free_tgt_creds(context, creds);
-#endif /* HEIMDAL */
- return retval;
-}
-#endif /* FORWARD */
-
-/*
- *
- * K5_auth_is.
- *
- */
-
-static int
-#ifdef CK_ANSIC
-k5_auth_is(int how, unsigned char *data, int cnt)
-#else
-k5_auth_is(how,data,cnt) int how; unsigned char *data; int cnt;
-#endif
-{
- int r = 0;
- krb5_principal server;
- krb5_keyblock *newkey = NULL;
- krb5_data outbuf;
- char errbuf[128]="";
- char *getenv();
-#ifndef HEIMDAL
- krb5_authenticator *authenticator;
- krb5_keytab keytabid = 0;
-#endif /* HEIMDAL */
- krb5_data inbuf;
-#ifdef CK_ENCRYPTION
- Session_Key skey;
-#endif /* CK_ENCRYPTION */
- char princ[256]="";
- int len;
-
- data += 4; /* Point to status byte */
- cnt -= 4;
-
- ckhexdump("k5_auth_is data",data,cnt);
- debug(F111,"k5_auth_is","how",how);
-
- if (cnt-- < 1) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
- switch (*data++) {
- case KRB_AUTH:
- k5_auth.data = (char *)data;
- k5_auth.length = cnt;
-
- debug(F110,"k5_auth_is","KRB_AUTH",0);
- debug(F111,"k5_auth_is","auth_context",auth_context);
-
- if (!r && !auth_context) {
- r = krb5_auth_con_init(k5_context, &auth_context);
- debug(F111,"k5_auth_is","krb5_auth_con_init",r);
- }
-
-#ifdef HEIMDAL
- if (!r)
- r = krb5_auth_con_setaddrs_from_fd(k5_context,
- auth_context,
- &ttyfd);
- if (!r)
- r = krb5_sock_to_principal(k5_context,
- 0,
- "host",
- KRB5_NT_SRV_HST,
- &server);
- if (!r)
-#else /* HEIMDAL */
- if (!r) {
- krb5_rcache rcache = NULL;
-
- r = krb5_auth_con_getrcache(k5_context, auth_context,
- &rcache);
- debug(F111,"k5_auth_is","krb5_auth_con_getrcache",r);
-
- if (!r && !rcache) {
- /* Do not resolve server's principal name, we will check */
- /* for validity after the krb5_rd_req() call. */
- r = krb5_sname_to_principal(k5_context, 0, 0,
- KRB5_NT_SRV_HST, &server);
- debug(F111,"k5_auth_is","krb5_sname_to_principal",r);
-
- if (!r) {
- r = krb5_get_server_rcache(k5_context,
- krb5_princ_component(k5_context, server, 0),
- &rcache);
- debug(F111,"k5_auth_is","krb5_get_server_rcache",r);
- krb5_free_principal(k5_context, server);
- }
- }
- if (!r) {
- r = krb5_auth_con_setrcache(k5_context,
- auth_context, rcache);
- debug(F111,"k5_auth_is","krb5_auth_con_setrcache",r);
- }
- }
- if (!r && k5_keytab) {
- r = krb5_kt_resolve(k5_context,
- k5_keytab, &keytabid);
- debug(F111,"k5_auth_is","krb5_kt_resolve",r);
- }
-#endif /* HEIMDAL */
- if (!r) {
- r = krb5_rd_req(k5_context, &auth_context, &k5_auth,
-#ifdef HEIMDAL
- server, NULL, NULL,
-#else /* HEIMDAL */
- NULL, keytabid, NULL,
-#endif /* HEIMDAL */
- &k5_ticket);
- debug(F111,"k5_auth_is","krb5_rd_req",r);
- }
- if (r) {
- (void) ckstrncpy(errbuf, "krb5_rd_req failed: ",sizeof(errbuf));
- (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
- goto errout;
- }
-#ifdef HEIMDAL
- krb5_free_principal(k5_context, server);
-
- {
- char type_check[26];
-
- /* UPDATE for START_TLS. AUTH_ENCRYPT_START_TLS and inclusion of */
- /* client and then server finished messages. */
-
- type_check[0] = AUTHTYPE_KERBEROS_V5;
- type_check[1] = how; /* not broken into parts */
-#ifdef CK_SSL
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- ssl_get_client_finished(&type_check[2],12);
- ssl_get_server_finished(&type_check[14],12);
- ckhexdump("k5_auth_is type_check",type_check,26);
- }
-#endif /* CK_SSL */
-
- r = krb5_verify_authenticator_checksum(k5_context,
- auth_context,
- type_check,
-#ifdef CK_SSL
- ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) ? 26 :
-#endif /* CK_SSL */
- 2);
- }
-#else /* HEIMDAL */
- len = krb5_princ_component(k5_context,k5_ticket->server,0)->length;
- if (len < 256)
- {
- memcpy(princ,
- krb5_princ_component(k5_context,k5_ticket->server,0)->data,
- len);
- princ[len] = '\0';
- }
- if ( strcmp((krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME), princ) )
- {
- debug(F110,"k5_auth_is incorrect service name",princ,0);
- ckstrncpy(errbuf,"incorrect service name: ",sizeof(errbuf));
- ckstrncat(errbuf,krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
- sizeof(errbuf));
- ckstrncat(errbuf," != ",sizeof(errbuf));
- ckstrncat(errbuf,princ,sizeof(errbuf));
- goto errout;
- }
-
- r = krb5_auth_con_getauthenticator(k5_context,
- auth_context,
- &authenticator);
- debug(F111,"k5_auth_is","krb5_auth_con_getauthenticator",r);
- if (r) {
- (void) ckstrncpy(errbuf,
- "krb5_auth_con_getauthenticator failed: ",
- sizeof(errbuf)
- );
- (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
- goto errout;
- }
-
- if (authenticator->checksum) {
- char type_check[26];
- krb5_checksum *cksum = authenticator->checksum;
- krb5_keyblock *key;
-
- /* UPDATE for START_TLS. AUTH_ENCRYPT_START_TLS and inclusion of */
- /* client and then server finished messages. */
-
- type_check[0] = AUTHTYPE_KERBEROS_V5;
- type_check[1] = how; /* not broken into parts */
-#ifdef CK_SSL
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- ssl_get_client_finished(&type_check[2],12);
- ssl_get_server_finished(&type_check[14],12);
- ckhexdump("k5_auth_is type_check",type_check,26);
- }
-#endif /* CK_SSL */
-
- r = krb5_auth_con_getkey(k5_context, auth_context,
- &key);
- debug(F111,"k5_auth_is","krb5_auth_con_getkey",r);
- if (r) {
- (void) ckstrncpy(errbuf, "krb5_auth_con_getkey failed: ",
- sizeof(errbuf));
- (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
- goto errout;
- }
-
- r = krb5_verify_checksum(k5_context,
- cksum->checksum_type,
- cksum,
- &type_check,
- ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) ? 26 :
- 2,
- key->contents,
- key->length
- );
- debug(F111,"k5_auth_is","krb5_verify_checksum",r);
- if (r) {
- (void) ckstrncpy(errbuf,
- "checksum verification failed: ",
- sizeof(errbuf)
- );
- (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
- goto errout;
- }
- krb5_free_keyblock(k5_context, key);
- } else {
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_USING_TELOPT) {
- (void) strcpy(errbuf,
- "authenticator is missing required checksum");
- goto errout;
- }
- }
-
- krb5_free_authenticator(k5_context, authenticator);
-#endif /* HEIMDAL */
-
-#ifdef TLS_VERIFY
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- krb5_data in, msg;
- char tls_verify[24];
- krb5_replay_data repdata;
-
- ssl_get_server_finished(&tls_verify[0],12);
- ssl_get_client_finished(&tls_verify[12],12);
-
- in.data = tls_verify;
- in.length = 24;
-
- krb5_auth_con_genaddrs(k5_context, auth_context, ttyfd,
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
- if (r = krb5_mk_safe(k5_context,auth_context,&in,&msg,&repdata)) {
- com_err("", r, "encoding tls verifier");
- (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
- goto errout;
- }
- SendK5AuthSB(KRB5_TLS_VERIFY, msg.data, msg.length);
- krb5_free_data_contents(k5_context,&msg);
- }
-#endif /* CK_SSL */
- if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- /* do ap_rep stuff here */
- if ((r = krb5_mk_rep(k5_context,
-#ifdef HEIMDAL
- &auth_context,
-#else /* HEIMDAL */
- auth_context,
-#endif /* HEIMDAL */
- &outbuf))) {
- debug(F111,"k5_auth_is","krb5_mk_rep",r);
- (void) ckstrncpy(errbuf, "Make reply failed: ",sizeof(errbuf));
- (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
- goto errout;
- }
- debug(F111,"k5_auth_is","krb5_mk_rep",r);
-
- SendK5AuthSB(KRB5_RESPONSE, outbuf.data, outbuf.length);
- mutual_complete = 1;
- }
-
-#ifdef HEIMDAL
- {
- char * name = NULL;
- if (krb5_unparse_name(k5_context, k5_ticket->client,
- &name))
- {
- szUserNameAuthenticated[0] = '\0';
- } else {
- ckstrncpy(szUserNameAuthenticated,UIDBUFLEN,name);
- free(name);
- }
- }
-#else /* HEIMDAL */
- if ( krb5_aname_to_localname(k5_context,
- k5_ticket->enc_part2->client,
- UIDBUFLEN,szUserNameAuthenticated) )
- szUserNameAuthenticated[0] = '\0';
-#endif /* HEIMDAL */
-
- SendK5AuthSB(KRB_ACCEPT, szUserNameAuthenticated,
- szUserNameAuthenticated[0] ? -1 : 0);
- accept_complete = 1;
- ckmakmsg(strTmp,sizeof(strTmp),
- "Kerberos5 identifies him as ``",
- szUserNameAuthenticated,"''",NULL);
- printf("%s\r\n",strTmp);
-
- if (szUserNameRequested[0] &&
- krb5_kuserok(k5_context,
-#ifdef HEIMDAL
- k5_ticket->client,
-#else /* HEIMDAL */
- k5_ticket->enc_part2->client,
-#endif /* HEIMDAL */
- szUserNameRequested))
- auth_finished(AUTH_VALID);
- else
- auth_finished(AUTH_USER);
-
- krb5_auth_con_getremotesubkey(k5_context, auth_context,
- &newkey);
- if (k5_session_key) {
- krb5_free_keyblock(k5_context, k5_session_key);
- k5_session_key = 0;
- }
- if (newkey) {
- krb5_copy_keyblock(k5_context, newkey, &k5_session_key);
- krb5_free_keyblock(k5_context, newkey);
- } else {
- krb5_copy_keyblock(k5_context,
-#ifdef HEIMDAL
- &k5_ticket->ticket.key,
-#else /* HEIMDAL */
- k5_ticket->enc_part2->session,
-#endif /* HEIMDAL */
- &k5_session_key);
- }
-
-#ifdef CK_ENCRYPTION
-#ifdef HEIMDAL
- skey.type = k5_session_key->keyvalue.length == 8 ? SK_DES : SK_GENERIC;
- skey.length = k5_session_key->keyvalue.length;
- skey.data = k5_session_key->keyvalue.data;
-#else /* HEIMDAL */
- skey.type = k5_session_key->length == 8 ? SK_DES : SK_GENERIC;
- skey.length = k5_session_key->length;
- skey.data = k5_session_key->contents;
-#endif /* HEIMDAL */
- encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
-#endif /* CK_ENCRYPTION */
- debug(F100,"k5_auth_is AUTH_SUCCESS","",0);
- krb5_errno = r;
- if ( krb5_errno )
- makestr(&krb5_errmsg,error_message(krb5_errno));
- else
- makestr(&krb5_errmsg,strTmp);
- return AUTH_SUCCESS;
-
-#ifdef FORWARD
- case KRB5_FORWARD:
- if ( !forward_flag ) {
- SendK5AuthSB(KRB5_FORWARD_REJECT,
- "forwarded credentials are being refused.",
- -1);
- return(AUTH_SUCCESS);
- }
-
- inbuf.length = cnt;
- inbuf.data = (char *)data;
- if (
-#ifndef HEIMDAL
- (!krb5_d_no_addresses &&
- (r = krb5_auth_con_genaddrs(k5_context,auth_context,g_kstream->fd,
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))) ||
-#endif /* HEIMDAL */
- (r = rd_and_store_for_creds(k5_context, auth_context,&inbuf,
-#ifdef HEIMDAL
- k5_ticket->client
-#else /* HEIMDAL */
- k5_ticket->enc_part2->client
-#endif /* HEIMDAL */
- ))) {
- (void) ckstrncpy(errbuf, "Read forwarded creds failed: ",
- sizeof(errbuf));
- (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
- SendK5AuthSB(KRB5_FORWARD_REJECT, errbuf, -1);
- printf("Could not read forwarded credentials\r\n");
- krb5_errno = r;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- }
- else {
- SendK5AuthSB(KRB5_FORWARD_ACCEPT, 0, 0);
- ckstrncpy(strTmp,"Forwarded credentials obtained",sizeof(strTmp));
- printf("%s\r\n",strTmp);
- krb5_errno = 0;
- makestr(&krb5_errmsg,strTmp);
- }
- /* A failure to accept forwarded credentials is not an */
- /* authentication failure. */
- return AUTH_SUCCESS;
-#endif /* FORWARD */
- default:
- printf("Unknown Kerberos option %d\r\n", data[-1]);
- SendK5AuthSB(KRB_REJECT, 0, 0);
- break;
- }
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
-
- errout:
- SendK5AuthSB(KRB_REJECT, errbuf, -1);
- krb5_errno = r;
- makestr(&krb5_errmsg,errbuf);
- printf("%s\r\n", errbuf);
- if (auth_context) {
- krb5_auth_con_free(k5_context, auth_context);
- auth_context = 0;
- }
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
-}
-
-#ifdef FORWARD
-int
-#ifdef CK_ANSIC
-kerberos5_forward(void)
-#else
-kerberos5_forward()
-#endif
-{
- krb5_error_code r;
- krb5_ccache ccache=NULL;
- krb5_principal client = 0;
- krb5_principal server = 0;
- krb5_data forw_creds;
-#ifdef HEIMDAL
- krb5_creds creds;
-#endif /* HEIMDAL */
-
- forw_creds.data = 0;
-
- r = k5_get_ccache(k5_context,&ccache,NULL);
- if ( r ) {
- com_err(NULL, r, "Kerberos V5: could not get default ccache");
- krb5_errno = r;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(AUTH_FAILURE);
- }
-
- if ((r = krb5_cc_get_principal(k5_context, ccache, &client))) {
- com_err(NULL, r, "Kerberos V5: could not get default principal");
- goto cleanup;
- }
-
-#ifdef HEIMDAL
- memset(&creds, 0, sizeof(creds));
- creds.client = client;
-
- if (r = krb5_build_principal(k5_context,
- &creds.server,
- strlen(client->realm),
- client->realm,
- "krbtgt",
- client->realm,
- NULL)) {
- com_err(NULL, r, "Kerberos V5: could not get principal");
- goto cleanup;
- }
-
- creds.times.endtime = 0;
-
- if (r = krb5_get_forwarded_creds(k5_context,
- auth_context,
- ccache,
- 0,
- szHostName,
- &creds,
- &forw_creds)) {
- com_err(NULL, r, "Kerberos V5: error getting forwarded creds");
- goto cleanup;
- }
-#else /* HEIMDAL */
- /* we should not need to make this call since we are storing the */
- /* server's principal in fwd_server from our call to */
- /* krb5_sname_to_principal() in k5_auth_send() */
- if (fwd_server == NULL) {
- if ((r = krb5_sname_to_principal(k5_context, szHostName,
- krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
- KRB5_NT_SRV_HST, &server))) {
- com_err(NULL, r, "Kerberos V5: could not make server principal");
- goto cleanup;
- }
- }
-
- if (!krb5_d_no_addresses &&
- (r = krb5_auth_con_genaddrs(k5_context, auth_context, g_kstream->fd,
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR)))
- {
- com_err(NULL, r, "Kerberos V5: could not gen local full address");
- goto cleanup;
- }
-
- if (r = krb5_fwd_tgt_creds(k5_context, auth_context, 0, client,
- fwd_server ? fwd_server : server,
- ccache, forwardable_flag, &forw_creds)) {
- com_err(NULL, r, "Kerberos V5: error getting forwardable credentials");
- goto cleanup;
- }
-#endif /* HEIMDAL */
-
- /* Send forwarded credentials */
- if (!SendK5AuthSB(KRB5_FORWARD, forw_creds.data, forw_creds.length)) {
- printf("Kerberos V5 forwarding error!\r\n%s\r\n",
- "Not enough room for authentication data");
- }
-
-cleanup:
- if (client)
- krb5_free_principal(k5_context, client);
- if (server)
- krb5_free_principal(k5_context, server);
-#ifdef HEIMDAL
- krb5_data_free(&forw_creds);
-#else /* HEIMDAL */
- krb5_free_data_contents(k5_context,&forw_creds);
-#endif /* HEIMDAL */
- krb5_cc_close(k5_context, ccache);
-
- krb5_errno = r;
- makestr(&krb5_errmsg,krb5_errno?error_message(krb5_errno):"OK");
- return(r?AUTH_FAILURE:AUTH_SUCCESS);
-}
-#endif /* FORWARD */
-#else /* KRB5 */
-int
-ck_krb5_autoget_TGT(char * dummy)
-{
- return(0);
-}
-#ifdef CK_KERBEROS
-int
-#ifdef CK_ANSIC
-ck_krb5_initTGT( struct krb_op_data * op, struct krb5_init_data * init,
- struct krb4_init_data * k4_init)
-#else
-ck_krb5_initTGT(op,init,k4_init)
- krb_op_data * op; struct krb5_init_data * init;
- struct krb4_init_data * k4_init;
-#endif /* CK_ANSIC*/
-{
- return(-1);
-}
-
-int
-#ifdef CK_ANSIC
-ck_krb5_destroy(struct krb_op_data * op)
-#else
-ck_krb5_destroy(op) struct krb_op_data * op;
-#endif
-{
- return(-1);
-}
-
-int
-#ifdef CK_ANSIC
-ck_krb5_list_creds(struct krb_op_data * op, struct krb5_list_cred_data * lc)
-#else
-ck_krb5_list_creds(op,lc)
- struct krb_op_data * op; struct krb5_list_cred_data * lc;
-#endif
-{
- return(-1);
-}
-#else /* CK_KERBEROS */
-int
-#ifdef CK_ANSIC
-ck_krb5_initTGT(void * op, void * init, void * k4_init )
-#else
-ck_krb5_initTGT(op,init,k4_init)
- void * op; void * init; void * k4_init;
-#endif /* CK_ANSIC*/
-{
- return(-1);
-}
-
-int
-#ifdef CK_ANSIC
-ck_krb5_destroy(void * op)
-#else
-ck_krb5_destroy(op) void * op;
-#endif
-{
- return(-1);
-}
-
-int
-#ifdef CK_ANSIC
-ck_krb5_list_creds(void * op, void * lc)
-#else
-ck_krb5_list_creds(op,lc)
- void * op; void * lc;
-#endif
-{
- return(-1);
-}
-#endif /* CK_KERBEROS */
-#endif /* KRB5 */
-
-#ifdef GSSAPI_KRB5
-/*
- *
- * gssk5_auth_send - gets authentication bits we need to send to KDC.
- *
- * Result is left in k5_auth
- *
- * Returns: 0 on failure, 1 on success
- *
- */
-
-static int
-#ifdef CK_ANSIC
-gssk5_auth_send(int how, int encrypt, int forward)
-#else
-gssk5_auth_send(how,encrypt,forward) int how; int encrypt; int forward;
-#endif
-{
- OM_uint32 maj_stat, min_stat;
-#ifdef KRB5
- char * realm = NULL;
- char tgt[256];
-#endif /* KRB5 */
-
- gss_chan.initiator_addrtype = GSS_C_AF_INET; /* OM_uint32 */
- gss_chan.initiator_address.length = 4;
- gss_chan.initiator_address.value = &myctladdr.sin_addr.s_addr;
- gss_chan.acceptor_addrtype = GSS_C_AF_INET; /* OM_uint32 */
- gss_chan.acceptor_address.length = 4;
- gss_chan.acceptor_address.value = &hisctladdr.sin_addr.s_addr;
- gss_chan.application_data.length = 0;
- gss_chan.application_data.value = 0;
-
-#ifdef KRB5
- realm = ck_krb5_realmofhost(ftp_host);
- if (realm) {
- ckmakmsg(tgt,sizeof(tgt),"krbtgt/",realm,"@",realm);
- debug(F110,"ftp_auth(GSSAPI) TGT",tgt,0);
- if ( krb5_autoget &&
- !((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
- (ck_krb5_is_tgt_valid() > 0)) )
- ck_krb5_autoget_TGT(realm);
- }
-#endif /* KRB5 */
-
- /* Blob from gss-client */
- /* host@hostname */
- /* the V5 GSSAPI binding canonicalizes this for us... */
- ckmakmsg(gss_stbuf,GSS_BUFSIZ,
- krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
- "@",
- szHostName,
- NULL
- );
- fprintf(stderr, "Authenticating to <%s>...\n", gss_stbuf);
- gss_send_tok.value = gss_stbuf;
- gss_send_tok.length = strlen(gss_stbuf);
- maj_stat = gss_import_name(&min_stat, &gss_send_tok,
- gss_nt_service_name,
- &gss_target_name
- );
- if (maj_stat != GSS_S_COMPLETE) {
- user_gss_error(maj_stat, min_stat, "parsing name");
- secure_error("name parsed <%s>\n", gss_stbuf);
- return(0);
- }
- token_ptr = GSS_C_NO_BUFFER;
- gcontext = GSS_C_NO_CONTEXT; /* structure copy */
-
- fprintf(stderr, "calling gss_init_sec_context\n");
- maj_stat =
- gss_init_sec_context(&min_stat,
- GSS_C_NO_CREDENTIAL,
- &gcontext,
- gss_target_name,
- gss_mech_krb5,
- GSS_C_MUTUAL_FLAG |
- GSS_C_REPLAY_FLAG |
- ((forward && forward_flag) ?
- GSS_C_DELEG_FLAG : 0),
- 0,
- (krb5_d_no_addresses ? /* channel bindings */
- GSS_C_NO_CHANNEL_BINDINGS :
- &gss_chan),
- gss_token_ptr,
- NULL, /* ignore mech type */
- &gss_send_tok,
- NULL, /* ignore ret_flags */
- NULL
- ); /* ignore time_rec */
-
-
- if (maj_stat != GSS_S_COMPLETE &&
- maj_stat != GSS_S_CONTINUE_NEEDED) {
- user_gss_error(maj_stat,
- min_stat,
- "initializing context"
- );
- gss_release_name(&min_stat, &gss_target_name);
- return(0);
- }
- return(1);
-}
-
-/*
- * gssk5_auth_reply -- checks the reply for mutual authentication.
- */
-static int
-#ifdef CK_ANSIC
-gssk5_auth_reply(int how, unsigned char *data, int cnt)
-#else
-gssk5_auth_reply(how,data,cnt) int how; unsigned char *data; int cnt;
-#endif
-{
- data += 4; /* Point to status byte */
- cnt -=5;
-
- switch (*data++) {
- case GSS_REJECT:
- if (cnt > 0) {
- char *s;
- int len;
- ckstrncpy(strTmp,"GSSAPI refuses authentication because\r\n",
- sizeof(strTmp));
- len = strlen(strTmp);
- if ( len + cnt < sizeof(strTmp) ) {
- s = strTmp + strlen(strTmp);
- memcpy(s, data, cnt); /* safe */
- s[cnt] = 0;
- }
- } else
- ckstrncpy(strTmp,"GSSAPI refuses authentication",
- sizeof(strTmp));
- printf("GSSAPI authentication failed!\r\n%s\r\n",strTmp);
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
-
- case GSS_ACCEPT:
- if ( cnt > 0 ) {
- char *s;
- int len;
- ckstrncpy(strTmp,"GSSAPI accepts you as ",sizeof(strTmp));
- len = strlen(strTmp);
- if ( len + cnt < sizeof(strTmp) ) {
- s = strTmp + strlen(strTmp);
- memcpy(s,data,cnt);
- s[cnt] = 0;
- }
- }
- accept_complete = 1;
- printf("%s\r\n",strTmp);
- auth_finished(AUTH_USER);
- return AUTH_SUCCESS;
-
- case GSS_RESPONSE:
- gss_token_ptr = &gss_recv_tok;
- gss_recv_tok.value = data;
- gss_recv_tok.length = cnt;
-
- maj_stat =
- gss_init_sec_context(&min_stat,
- GSS_C_NO_CREDENTIAL,
- &gcontext,
- gss_target_name,
- gss_krb5_mech,
- GSS_C_MUTUAL_FLAG |
- GSS_C_REPLAY_FLAG |
- (forward_flag ?
- GSS_C_DELEG_FLAG : 0),
- 0,
- (krb5_d_no_addresses ? /* channel bindings */
- GSS_C_NO_CHANNEL_BINDINGS :
- &gss_chan),
- gss_token_ptr,
- NULL, /* ignore mech type */
- &gss_send_tok,
- NULL, /* ignore ret_flags */
- NULL
- ); /* ignore time_rec */
-
- if ( maj_stat == GSS_S_COMPLETE )
- {
-
- } else if ( maj_stat == CSS_S_CONTINUE_NEEDED ) {
- } else {
- }
-
- ckstrncpy(strTmp,"Remote machine has been mutually authenticated",
- sizeof(strTmp));
- printf("%s\r\n",strTmp);
- auth_finished(AUTH_USER);
- return AUTH_SUCCESS;
-
- default:
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE; /* Unknown reply type */
- }
-}
-
-/*
- *
- * gssk5_auth_is.
- *
- */
-
-static int
-#ifdef CK_ANSIC
-k5_auth_is(int how, unsigned char *data, int cnt)
-#else
-k5_auth_is(how,data,cnt) int how; unsigned char *data; int cnt;
-#endif
-{
- int replied = 0;
- gss_cred_id_t server_creds, deleg_creds;
- gss_name_t client;
- int ret_flags;
- gss_buffer_desc name_buf;
- gss_name_t server_name;
- OM_uint32 acquire_maj,
- acquire_min,
- accept_maj,
- accept_min,
- stat_maj,
- stat_min;
- gss_OID mechid;
- gss_buffer_desc tok, out_tok;
- char gbuf[GSS_BUFSIZ];
- u_char gout_buf[GSS_BUFSIZ];
- char localname[MAXHOSTNAMELEN];
- char service_name[MAXHOSTNAMELEN+10];
- char **service;
- struct hostent *hp;
-
- data += 4; /* Point to status byte */
- cnt -= 4;
-
- ckhexdump("gssk5_auth_is data",data,cnt);
- debug(F111,"gssk5_auth_is","how",how);
-
- if (cnt-- < 1) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
- switch (*data++) {
- case GSS_AUTH:
- gss_chan.initiator_addrtype = GSS_C_AF_INET;
- gss_chan.initiator_address.length = 4;
- gss_chan.initiator_address.value = &his_addr.sin_addr.s_addr;
- gss_chan.acceptor_addrtype = GSS_C_AF_INET;
- gss_chan.acceptor_address.length = 4;
- gss_chan.acceptor_address.value = &ctrl_addr.sin_addr.s_addr;
- gss_chan.application_data.length = 0;
- gss_chan.application_data.value = 0;
-
- tok.value = data;
- tok.length = cnt;
-
- if (gethostname(localname, MAXHOSTNAMELEN)) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
- if (!(hp = gethostbyname(localname))) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-#ifdef HADDRLIST
- hp = ck_copyhostent(hp);
-#endif /* HADDRLIST */
- strncpy(localname, hp->h_name, sizeof(localname) - 1);
- localname[sizeof(localname) - 1] = '\0';
-
- sprintf(service_name, "%s@%s", *service, localname);
- name_buf.value = service_name;
- name_buf.length = strlen(name_buf.value) + 1;
- stat_maj = gss_import_name(&stat_min, &name_buf,
- gss_nt_service_name,
- &server_name);
- if (stat_maj != GSS_S_COMPLETE) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- acquire_maj = gss_acquire_cred(&acquire_min, server_name, 0,
- GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
- &server_creds, NULL, NULL);
- (void) gss_release_name(&stat_min, &server_name);
-
- if (acquire_maj != GSS_S_COMPLETE) {
- reply_gss_error(535, accept_maj, accept_min,
- "accepting context");
- syslog(LOG_ERR, "failed accepting context");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min,
- &deleg_creds);
- return 0;
- }
-
- gcontext = GSS_C_NO_CONTEXT;
- accept_maj = gss_accept_sec_context(&accept_min,
- &gcontext, /* context_handle */
- /* verifier_cred_handle */
- server_creds,
- &tok, /* input_token */
- (krb5_d_no_addresses ?
- /* channel bindings */
- GSS_C_NO_CHANNEL_BINDINGS :
- &gss_chan),
- &client, /* src_name */
- &mechid, /* mech_type */
- &out_tok, /* output_token */
- &ret_flags,
- NULL, /* ignore time_rec */
- /* forwarded credentials */
- &deleg_creds
- );
-
- if (accept_maj!=GSS_S_COMPLETE && accept_maj!=GSS_S_CONTINUE_NEEDED) {
- reply_gss_error(535, accept_maj, accept_min,
- "accepting context");
- syslog(LOG_ERR, "failed accepting context");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min,
- &deleg_creds);
- return 0;
- }
-
- if (out_tok.length) {
- if (kerror = radix_encode(out_tok.value,gbuf,&out_tok.length, 0)) {
- secure_error("Couldn't encode ADAT reply (%s)",
- radix_error(kerror));
- syslog(LOG_ERR, "couldn't encode ADAT reply");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min,
- &deleg_creds);
- return(0);
- }
- if (stat_maj == GSS_S_COMPLETE) {
- reply(235, "ADAT=%s", gbuf);
- replied = 1;
- } else {
- /* If the server accepts the security data, and
- requires additional data, it should respond
- with reply code 335. */
- reply(335, "ADAT=%s", gbuf);
- }
- (void) gss_release_buffer(&stat_min, &out_tok);
- }
-
- if (stat_maj == GSS_S_COMPLETE) {
- /* GSSAPI authentication succeeded */
- stat_maj = gss_display_name(&stat_min, client,
- &client_name, &mechid);
- if (stat_maj != GSS_S_COMPLETE) {
- /* "If the server rejects the security data (if
- a checksum fails, for instance), it should
- respond with reply code 535." */
- reply_gss_error(535, stat_maj, stat_min,
- "extracting GSSAPI identity name");
- syslog(LOG_ERR, "gssapi error extracting identity");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min,
- &deleg_creds);
- return 0;
- }
- auth_type = temp_auth_type;
- temp_auth_type = NULL;
-
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG) {
- if (want_creds)
- ftpd_gss_convert_creds(client_name.value,
- deleg_creds);
- (void) gss_release_cred(&stat_min, &deleg_creds);
- }
-
- /* If the server accepts the security data, but does
- not require any additional data (i.e., the security
- data exchange has completed successfully), it must
- respond with reply code 235. */
- if (!replied)
- {
- if (ret_flags & GSS_C_DELEG_FLAG && !have_creds)
- reply(235,
- "GSSAPI Authentication succeeded, but could not accept forwarded credentials"
- );
- else
- reply(235, "GSSAPI Authentication succeeded");
- }
- return(1);
- } else if (stat_maj == GSS_S_CONTINUE_NEEDED) {
- /* If the server accepts the security data, and
- requires additional data, it should respond with
- reply code 335. */
- reply(335, "more data needed");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min, &deleg_creds);
- return(0);
- } else {
- /* "If the server rejects the security data (if
- a checksum fails, for instance), it should
- respond with reply code 535." */
- reply_gss_error(535, stat_maj, stat_min,
- "GSSAPI failed processing ADAT");
- syslog(LOG_ERR, "GSSAPI failed processing ADAT");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min, &deleg_creds);
- return(0);
- }
-
- debug(F100,"gssk5_auth_is AUTH_SUCCESS","",0);
- krb5_errno = r;
- if ( krb5_errno )
- makestr(&krb5_errmsg,error_message(krb5_errno));
- else
- makestr(&krb5_errmsg,strTmp);
- return AUTH_SUCCESS;
-
- default:
- printf("Unknown Kerberos option %d\r\n", data[-1]);
- SendGSSK5AuthSB(GSS_REJECT, 0, 0);
- break;
- }
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
-}
-#endif /* GSSAPI_KRB5 */
-
-#ifdef CK_SRP
-/*
- * Copyright (c) 1997 Stanford University
- *
- * The use of this software for revenue-generating purposes may require a
- * license from the owners of the underlying intellectual property.
- * Specifically, the SRP-3 protocol may not be used for revenue-generating
- * purposes without a license.
- *
- * NOTE: Columbia University has a license.
- *
- * Within that constraint, permission to use, copy, modify, and distribute
- * this software and its documentation for any purpose is hereby granted
- * without fee, provided that the above copyright notices and this permission
- * notice appear in all copies of the software and related documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-static void
-srp_encode_length(data, num)
- unsigned char * data;
- int num;
-{
- *data = (num >> 8) & 0xff;
- *++data = num & 0xff;
-}
-
-static int
-srp_decode_length(data)
- unsigned char * data;
-{
- return (((int) *data & 0xff) << 8) | (*(data + 1) & 0xff);
-}
-
-#ifdef PRE_SRP_1_7_3
-static int
-#ifdef CK_ANSIC
-srp_reply(int how, unsigned char *data, int cnt)
-#else
-srp_reply(how,data,cnt) int how; unsigned char *data; int cnt;
-#endif
-{
- struct t_num n;
- struct t_num g;
- struct t_num s;
- struct t_num B;
- struct t_num * A;
- char type_check[26];
- int pflag;
-
-#ifdef CK_ENCRYPTION
- Session_Key skey;
-#endif /* ENCRYPTION */
-
- char * str=NULL;
-
- data += 4; /* Point to status byte */
- cnt -= 4;
-
- if(cnt-- < 1) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- switch(*data++) {
- case SRP_REJECT:
- ckmakmsg(strTmp,sizeof(strTmp),
- "SRP refuses authentication for '",szUserName,
- "'\r\n",NULL);
- if (cnt > 0) {
- int len = strlen(strTmp);
- if ( len + cnt < sizeof(strTmp) ) {
- str = strTmp + strlen(strTmp);
- memcpy(str,data,cnt);
- str[cnt] = 0;
- }
- }
- printf("SRP authentication failed!\r\n%s\r\n",strTmp);
- if (tc != NULL) {
- t_clientclose(tc);
- tc = NULL;
- }
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
-
- case SRP_ACCEPT:
- if(cnt < RESPONSE_LEN || !srp_waitresp ||
- tc == NULL
- ) {
- printf("SRP Protocol error\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- srp_waitresp = 0;
-
- if(t_clientverify(tc, data) == 0) {
- printf("SRP accepts you as %s\r\n",szUserName);
-#ifdef CK_SSL
- if((ssl_active_flag || tls_active_flag) &&
- (how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- printf("TLS session parameters verified by SRP\r\n");
- } else
-#endif /* CK_SSL */
-
-#ifdef CK_ENCRYPTION
- {
- skey.type = SK_GENERIC;
- skey.length = SESSION_KEY_LEN;
- skey.data = tc->session_key;
- encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
- }
-#endif /* ENCRYPTION */
- t_clientclose(tc);
- tc = NULL;
- accept_complete = 1;
- auth_finished(AUTH_VALID);
- return AUTH_SUCCESS;
- } else {
- printf("SRP server authentication failed!\r\n");
- t_clientclose(tc);
- tc = NULL;
- return(auth_resend(AUTHTYPE_SRP));
- }
- break;
-
- case SRP_PARAMS:
- if(!szUserName) {
- printf("No username available\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
-
- n.len = srp_decode_length(data);
- data += 2;
- cnt -= 2;
- if(n.len > cnt) {
- printf("n too long\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- n.data = data;
- data += n.len;
- cnt -= n.len;
-
- g.len = srp_decode_length(data);
- data += 2;
- cnt -= 2;
- if(g.len > cnt) {
- printf("g too long\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- g.data = data;
- data += g.len;
- cnt -= g.len;
-
- s.len = srp_decode_length(data);
- data += 2;
- cnt -= 2;
- if(s.len > cnt) {
- printf("salt too long\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- s.data = data;
- data += s.len;
- cnt -= s.len;
-
- /* If the parameters provided by the server cannot be
- * validated the following function will fail.
- */
- tc = t_clientopen(szUserName, &n, &g, &s);
- if (tc == NULL) {
- printf("SRP parameter initialization error\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- A = t_clientgenexp(tc);
- if(A == NULL) {
- printf("SRP protocol error\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- SendSRPAuthSB(SRP_EXP, A->data, A->len);
-
- if ( pwbuf[0] && pwflg ) {
- printf("SRP using %d-bit modulus for '%s'\r\n",
- 8 * n.len,
- szUserName
- );
- ckstrncpy(srp_passwd,pwbuf,sizeof(srp_passwd));
-#ifdef OS2
- if ( pwcrypt )
- ck_encrypt((char *)srp_passwd);
-#endif /* OS2 */
- } else {
- extern char * srppwprompt;
- char preface[128];
- int ok;
-
- if (srppwprompt && srppwprompt[0] &&
- (strlen(srppwprompt) + strlen(szUserName) - 2) <
- sizeof(preface)) {
- sprintf(preface,srppwprompt,szUserName);
- } else {
- ckmakxmsg( preface,sizeof(preface),
- "SRP using ",ckitoa(8*n.len),"-bit modulus for '",
- szUserName, "'", NULL, NULL, NULL, NULL, NULL,
- NULL, NULL);
- }
- ok = uq_txt( preface,"Password: ",2,NULL,
- srp_passwd,sizeof(srp_passwd)-1,NULL,
- DEFAULT_UQ_TIMEOUT);
- if ( !ok )
- srp_passwd[0] = '\0';
- }
-
- t_clientpasswd(tc, srp_passwd);
- memset(srp_passwd, 0, sizeof(srp_passwd));
- return AUTH_SUCCESS;
-
- case SRP_CHALLENGE:
- if(tc == NULL) {
- printf("SRP protocol error\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
-
-#ifndef PRE_SRP_1_4_5
- /*
- * The original SRP AUTH implementation did not protect against
- * tampering of the auth-type-pairs. Therefore, when the
- * AUTH_ENCRYPT_MASK bits are zero, no extra data is inserted
- * into the SRP hash computation. When AUTH_ENCRYPT_START_TLS
- * is set we also insert the SSL/TLS client and server finished
- * messages to ensure that there is no man in the middle attack
- * underway on the SSL/TLS connection.
- */
- if ((how & AUTH_ENCRYPT_MASK) != AUTH_ENCRYPT_OFF) {
- type_check[0] = AUTHTYPE_SRP;
- type_check[1] = how;
-#ifdef CK_SSL
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- ssl_get_client_finished(&type_check[2],12);
- ssl_get_server_finished(&type_check[14],12);
- t_clientaddexdata(tc,type_check,26);
- } else
-#endif /* CK_SSL */
- t_clientaddexdata(tc,type_check,2);
- }
-#endif /* PRE_SRP_1_4_5 */
-
- B.data = data;
- B.len = cnt;
- t_clientgetkey(tc, &B);
-
- SendSRPAuthSB(SRP_RESPONSE, t_clientresponse(tc), RESPONSE_LEN);
- srp_waitresp = 1;
- return AUTH_SUCCESS;
-
- default:
- return(auth_resend(AUTHTYPE_SRP));
- }
- return AUTH_FAILURE;
-}
-
-static int
-#ifdef CK_ANSIC
-srp_is(int how, unsigned char *data, int cnt)
-#else
-srp_is(how,data,cnt) int how; unsigned char *data; int cnt;
-#endif
-{
- char * pbuf = NULL;
- char * ptr;
-#ifdef CK_ENCRYPTION
- Session_Key skey;
-#endif
- struct t_num A;
- struct t_pw * tpw = NULL;
- struct t_conf * tconf = NULL;
- struct passwd * pass;
- static struct t_num * B = NULL; /* Holder for B */
-#ifdef CK_SSL
- char type_check[26];
-#else
- char type_check[2];
-#endif /* CK_SSL */
-
- if ((cnt -= 4) < 1) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- data += 4;
- cnt -= 1;
- switch(*data++) {
- case SRP_AUTH:
- /* Send parameters back to client */
- if(ts != NULL) {
- t_serverclose(ts);
- ts = NULL;
- }
- if(!szUserNameRequested[0]) {
- if (1)
- printf("No username available\r\n");
- SendSRPAuthSB(SRP_REJECT, (void *) "No username supplied", -1);
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && ckxanon &&
- !strcmp(szUserNameRequested,"anonymous")) {
- SendSRPAuthSB(SRP_REJECT, (void *)
- "anonymous login cannot be performed with Secure Remote Password",
- -1);
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-#ifndef PRE_SRP_1_4_4
- if(tpw == NULL) {
- if((tpw = t_openpw(NULL)) == NULL) {
- if (1)
- printf("Unable to open password file\r\n");
- SendSRPAuthSB(SRP_REJECT, (void *) "No password file", -1);
- return(AUTH_FAILURE);
- }
- }
- if(tconf == NULL) {
- if((tconf = t_openconf(NULL)) == NULL) {
- if (1)
- printf("Unable to open configuration file\r\n");
- SendSRPAuthSB(SRP_REJECT, (void *)"No configuration file", -1);
- return(AUTH_FAILURE);
- }
- }
- ts = t_serveropenfromfiles(szUserNameRequested, tpw, tconf);
- t_closepw(tpw);
- tpw = NULL;
- t_closeconf(tconf);
- tconf = NULL;
-#else /* PRE_SRP_1_4_4 */
-#ifdef COMMENT
- /* the code in this block should no longer be necessary on OS/2
- or Windows because I have added functionality to libsrp.lib
- to find the srp files. 4/22/2000
- */
-
- /* On Windows and OS/2 there is no well defined place for the */
- /* ETC directory. So we look for either an SRP_ETC or ETC */
- /* environment variable in that order. If we find one we */
- /* attempt to open the files manually. */
- /* We will reuse the strTmp[] for the file names. */
- ptr = getenv("SRP_ETC");
- if ( !ptr )
- ptr = getenv("ETC");
-#ifdef NT
- if ( !ptr ) {
- DWORD len;
- len = AUTHTMPBL;
-
- len = GetWindowsDirectory(strTmp,len);
- if ( len > 0 && len < AUTHTMPBL) {
- if ( !isWin95() ) {
- if ( len == 1 )
- ckstrncat(strTmp,"SYSTEM32/DRIVERS/ETC",sizeof(strTmp));
- else
- ckstrncat(strTmp,"/SYSTEM32/DRIVERS/ETC",sizeof(strTmp));
- }
- }
- ptr = strTmp;
- }
-#endif /* NT */
- if ( ptr ) {
- int len = strlen(ptr);
- int i;
- if (ptr != strTmp)
- strcpy(strTmp,ptr);
- for ( i=0;i<len;i++ ) {
- if ( strTmp[i] == '\\' )
- strTmp[i] = '/';
- }
- if ( strTmp[len-1] != '/' )
- ckstrncat(strTmp,"/tpasswd",sizeof(strTmp));
- else
- ckstrncat(strTmp,"tpasswd",sizeof(strTmp));
- tpw = t_openpwbyname(strTmp);
-
- ckstrncat(strTmp,".conf",sizeof(strTmp));
- tconf = t_openconfbyname(strTmp);
- }
-
- if ( tpw && tconf )
- ts = t_serveropenfromfiles(szUserNameRequested, tpw, tconf);
- else
- ts = t_serveropen(szUserNameRequested);
- if ( tpw ) {
- t_closepw(tpw);
- tpw = NULL;
- }
- if ( tconf ) {
- t_closeconf(tconf);
- tconf = NULL;
- }
-#else /* COMMENT */
- ts = t_serveropen(szUserNameRequested);
-#endif /* COMMENT */
-#endif /* PRE_SRP_1_4_4 */
-
- if( ts == NULL ) {
- printf("User %s not found\r\n", szUserNameRequested);
- SendSRPAuthSB(SRP_REJECT, (void *) "Password not set", -1);
- return(AUTH_FAILURE);
- }
-
- pbuf = (char *)malloc(ts->n.len + ts->g.len + ts->s.len + 7);
- ptr = pbuf;
-
- srp_encode_length(ptr, ts->n.len);
- ptr += 2;
- memcpy(ptr, ts->n.data, ts->n.len); /* safe */
- ptr += ts->n.len;
-
- srp_encode_length(ptr, ts->g.len);
- ptr += 2;
- memcpy(ptr, ts->g.data, ts->g.len); /* safe */
- ptr += ts->g.len;
-
- srp_encode_length(ptr, ts->s.len);
- ptr += 2;
- memcpy(ptr, ts->s.data, ts->s.len); /* safe */
- ptr += ts->s.len;
-
- SendSRPAuthSB(SRP_PARAMS, pbuf, ptr - pbuf);
- free(pbuf); pbuf = NULL;
-
- B = t_servergenexp(ts);
- ckstrncpy(szUserNameAuthenticated,szUserNameRequested,UIDBUFLEN);
- return AUTH_SUCCESS;
-
- case SRP_EXP:
- /* Client is sending A to us, compute challenge & expected response. */
- if (ts == NULL || B == NULL) {
- printf("Protocol error: SRP_EXP unexpected\r\n");
- SendSRPAuthSB(SRP_REJECT,
- (void *) "Protocol error: unexpected EXP",
- -1
- );
- return(AUTH_FAILURE);
- }
-
- /* Wait until now to send B, since it contains the key to "u" */
- SendSRPAuthSB(SRP_CHALLENGE, B->data, B->len);
- B = NULL;
-
-#ifndef PRE_SRP_1_4_5
- /*
- * The original SRP AUTH implementation did not protect against
- * tampering of the auth-type-pairs. Therefore, when the
- * AUTH_ENCRYPT_MASK bits are zero, no extra data is inserted
- * into the SRP hash computation. When AUTH_ENCRYPT_START_TLS
- * is set we also insert the SSL/TLS client and server finished
- * messages to ensure that there is no man in the middle attack
- * underway on the SSL/TLS connection.
- */
- if ( (how & AUTH_ENCRYPT_MASK) != AUTH_ENCRYPT_OFF ) {
- type_check[0] = AUTHTYPE_SRP;
- type_check[1] = how;
-#ifdef CK_SSL
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- ssl_get_client_finished(&type_check[2],12);
- ssl_get_server_finished(&type_check[14],12);
- }
-#endif /* CK_SSL */
- t_serveraddexdata(ts,type_check,
-#ifdef CK_SSL
- ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) ? 26 :
-#endif /* CK_SSL */
- 2);
- }
-#endif /* PRE_SRP_1_4_5 */
-
- A.data = data;
- A.len = cnt;
- ptr = t_servergetkey(ts, &A);
-
- if(ptr == NULL) {
- if (1)
- printf("Security alert: Trivial session key attempted\r\n");
- SendSRPAuthSB(SRP_REJECT,
- (void *) "Trivial session key detected",
- -1
- );
- return(AUTH_FAILURE);
- }
- srp_waitresp = 1;
- return AUTH_SUCCESS;
-
- case SRP_RESPONSE:
- /* Got the response; see if it's correct */
- if (!srp_waitresp ||
- ts == NULL
- ) {
- if (1)
- printf("Protocol error: SRP_RESPONSE unexpected\r\n");
- SendSRPAuthSB(SRP_REJECT,
- (void *) "Protocol error: unexpected RESPONSE",
- -1
- );
- return(AUTH_FAILURE);
- }
- srp_waitresp = 0; /* we got a response */
-
- if (cnt < RESPONSE_LEN) {
- if (1)
- printf("Protocol error: malformed response\r\n");
- SendSRPAuthSB(SRP_REJECT,
- (void *) "Protocol error: malformed response",
- -1
- );
- return(AUTH_FAILURE);
- }
-
- if (t_serververify(ts, data) == 0) {
- SendSRPAuthSB(SRP_ACCEPT, t_serverresponse(ts), RESPONSE_LEN);
- accept_complete = 1;
-#ifdef CK_ENCRYPTION
-#ifdef CK_SSL
- if (!(ssl_active_flag || tls_active_flag))
-#endif /* CK_SSL */
- {
- ckhexdump("SRP_RESPONSE ts",ts,sizeof(ts));
- ckhexdump("SRP_RESPONSE session_key",
- ts->session_key,
- SESSION_KEY_LEN
- );
- skey.type = SK_GENERIC;
- skey.length = SESSION_KEY_LEN;
- skey.data = ts->session_key;
- encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
- }
-#endif /* CK_ENCRYPTION */
- auth_finished(AUTH_VALID);
- }
- else {
- SendSRPAuthSB(SRP_REJECT, (void *) "Login incorrect", -1);
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
- return AUTH_SUCCESS;
-
- default:
- printf("Unknown SRP option %d\r\n", data[-1]);
- SendSRPAuthSB(SRP_REJECT, (void *) "Unknown option received", -1);
- return(AUTH_FAILURE);
- }
-}
-#else /* PRE_SRP_1_7_3 */
-static int
-#ifdef CK_ANSIC
-new_srp_reply(int how, unsigned char *data, int cnt)
-#else
-new_srp_reply(how,data,cnt) int how; unsigned char *data; int cnt;
-#endif
-{
- data += 4; /* Point to status byte */
- cnt -= 4;
-
- if(cnt-- < 1) { /* Matches with data++ */
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- switch(*data++) {
- case SRP_PARAMS: {
- struct t_num n;
- struct t_num g;
- struct t_num s;
- cstr * A;
-
- if(!szUserName) {
- printf("No username available\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
-
- n.len = srp_decode_length(data);
- data += 2;
- cnt -= 2;
- if(n.len > cnt) {
- printf("n too long\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- n.data = data;
- data += n.len;
- cnt -= n.len;
-
- g.len = srp_decode_length(data);
- data += 2;
- cnt -= 2;
- if(g.len > cnt) {
- printf("g too long\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- g.data = data;
- data += g.len;
- cnt -= g.len;
-
- s.len = srp_decode_length(data);
- data += 2;
- cnt -= 2;
- if(s.len != cnt) {
- printf("invalid salt\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- s.data = data;
- data += s.len;
- cnt -= s.len;
-
- /* If the parameters provided by the server cannot be
- * validated the following function will fail.
- */
- c_srp = SRP_new(SRP_RFC2945_client_method());
- if (c_srp == NULL ||
- SRP_set_username(c_srp, szUserName) != SRP_SUCCESS ||
- SRP_set_params(c_srp,n.data,n.len,g.data,g.len,s.data,s.len) !=
- SRP_SUCCESS) {
- printf("SRP Parameter initialization error\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
-
- A = cstr_new();
- if(SRP_gen_pub(c_srp, &A) != SRP_SUCCESS) {
- printf("SRP Error generating key exchange\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
-
- SendSRPAuthSB(SRP_EXP, A->data, A->length);
- cstr_free(A);
-
- if ( pwbuf[0] && pwflg ) {
- printf("SRP using %d-bit modulus for '%s'\r\n",
- 8 * n.len,
- szUserName
- );
- ckstrncpy(srp_passwd,pwbuf,sizeof(srp_passwd));
-#ifdef OS2
- if ( pwcrypt )
- ck_encrypt((char *)srp_passwd);
-#endif /* OS2 */
- } else {
- extern char * srppwprompt;
- char preface[128];
- int ok;
-
- if (srppwprompt && srppwprompt[0] &&
- (strlen(srppwprompt) + strlen(szUserName) - 2) <
- sizeof(preface)) {
- sprintf(preface,srppwprompt,szUserName);
- } else {
- ckmakxmsg( preface,sizeof(preface),
- "SRP using ",ckitoa(8*n.len),"-bit modulus for '",
- szUserName, "'", NULL, NULL, NULL, NULL, NULL,
- NULL, NULL);
- }
- ok = uq_txt(preface,"Password: ",2,NULL,
- srp_passwd,sizeof(srp_passwd)-1,NULL,
- DEFAULT_UQ_TIMEOUT);
- if ( !ok )
- srp_passwd[0] = '\0';
- }
-
- if(SRP_set_auth_password(c_srp, srp_passwd) != SRP_SUCCESS) {
- memset(srp_passwd, 0, sizeof(srp_passwd));
- printf("SRP Error setting client password\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- memset(srp_passwd, 0, sizeof(srp_passwd));
- return AUTH_SUCCESS;
- }
- case SRP_CHALLENGE: {
- char type_check[26];
- cstr * resp = NULL;
-
- if(c_srp == NULL) {
- printf("SRP protocol error\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
-
- /*
- * The original SRP AUTH implementation did not protect against
- * tampering of the auth-type-pairs. Therefore, when the
- * AUTH_ENCRYPT_MASK bits are zero, no extra data is inserted
- * into the SRP hash computation. When AUTH_ENCRYPT_START_TLS
- * is set we also insert the SSL/TLS client and server finished
- * messages to ensure that there is no man in the middle attack
- * underway on the SSL/TLS connection.
- */
- if ((how & AUTH_ENCRYPT_MASK) != AUTH_ENCRYPT_OFF) {
- type_check[0] = AUTHTYPE_SRP;
- type_check[1] = how;
-#ifdef CK_SSL
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- ssl_get_client_finished(&type_check[2],12);
- ssl_get_server_finished(&type_check[14],12);
- SRP_add_ex_data(c_srp, type_check, 26);
- } else
-#endif /* CK_SSL */
- SRP_add_ex_data(c_srp, type_check, 2);
- }
-
- if(SRP_compute_key(c_srp, &c_key, data, cnt) != SRP_SUCCESS) {
- printf("SRP ERROR: unable to compute client key\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
-
- resp = cstr_new();
- if(SRP_respond(c_srp, &resp) != SRP_SUCCESS) {
- printf("SRP ERROR: unable to compute client response\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- SendSRPAuthSB(SRP_RESPONSE, resp->data, resp->length);
- cstr_free(resp);
- srp_waitresp = 1;
- return AUTH_SUCCESS;
- }
- case SRP_ACCEPT: {
-#ifdef CK_ENCRYPTION
- Session_Key skey;
-#endif /* ENCRYPTION */
-
- if(cnt < RESPONSE_LEN || !srp_waitresp || c_srp == NULL) {
- printf("SRP Protocol error\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- srp_waitresp = 0;
-
- if(SRP_verify(c_srp, data, cnt) == SRP_SUCCESS) {
- printf("SRP accepts you as %s\r\n",szUserName);
-
-#ifdef CK_SSL
- if((ssl_active_flag || tls_active_flag) &&
- (how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- printf("TLS session parameters verified by SRP\r\n");
- } else
-#endif /* CK_SSL */
-#ifdef CK_ENCRYPTION
- {
- skey.type = SK_GENERIC;
- skey.length = c_key->length;
- skey.data = c_key->data;
- encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
- cstr_clear_free(c_key);
- c_key = NULL;
- }
-#endif /* CK_ENCRYPTION */
- accept_complete = 1;
- auth_finished(AUTH_VALID);
- SRP_free(c_srp);
- c_srp = NULL;
- return AUTH_SUCCESS;
- }
- else {
- printf("[ Error: SRP server authentication failed ]\r\n");
- return(auth_resend(AUTHTYPE_SRP));
- }
- }
- case SRP_REJECT: {
- char * str=NULL;
-
- ckmakmsg(strTmp,sizeof(strTmp),
- "SRP refuses authentication for '",szUserName,
- "'\r\n",NULL);
- if (cnt > 0) {
- int len = strlen(strTmp);
- if ( len + cnt < sizeof(strTmp) ) {
- str = strTmp + strlen(strTmp);
- memcpy(str,data,cnt);
- str[cnt] = 0;
- }
- }
- printf("SRP authentication failed!\r\n%s\r\n",strTmp);
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
- default:
- printf("Unknown SRP option %d\r\n", data[-1]);
- return(auth_resend(AUTHTYPE_SRP));
- }
- /* NEVER REACHED */
-}
-
-static int
-#ifdef CK_ANSIC
-new_srp_is(int how, unsigned char *data, int cnt)
-#else
-new_srp_is(how,data,cnt) int how; unsigned char *data; int cnt;
-#endif
-{
- char * pbuf = NULL;
- char * ptr;
-#ifdef CK_ENCRYPTION
- Session_Key skey;
-#endif
- static cstr * B = NULL; /* Holder for B */
- struct t_passwd * pass;
- cstr * resp;
- char type_check[26];
-
- if ((cnt -= 4) < 1) {
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
-
- data += 4;
- cnt -= 1;
- switch(*data++) {
- case SRP_AUTH:
- /* Send parameters back to client */
- if(s_srp != NULL) {
- SRP_free(s_srp);
- s_srp = NULL;
- }
- if (B != NULL) {
- cstr_free(B);
- B = NULL;
- }
- if(!szUserNameRequested[0]) {
- if (1)
- printf("No username available\r\n");
- SendSRPAuthSB(SRP_REJECT, (void *) "No username supplied", -1);
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && ckxanon &&
- !strcmp(szUserNameRequested,"anonymous")) {
- SendSRPAuthSB(SRP_REJECT, (void *)
- "anonymous login cannot be performed with Secure Remote Password",
- -1);
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- s_srp = SRP_new(SRP_RFC2945_server_method());
- if(s_srp == NULL) {
- printf("Error initializing SRP server\r\n");
- SendSRPAuthSB(SRP_REJECT,
- (void *) "SRP server init failed",
- -1
- );
- return(AUTH_FAILURE);
- }
- pass = gettpnam(szUserNameRequested);
- if(pass == NULL) {
- printf("User %s not found\r\n", szUserNameRequested);
- SendSRPAuthSB(SRP_REJECT, (void *) "Password not set", -1);
- return(AUTH_FAILURE);
- }
- if(SRP_set_username(s_srp, szUserNameRequested) != SRP_SUCCESS ||
- SRP_set_params(s_srp, pass->tc.modulus.data,
- pass->tc.modulus.len,
- pass->tc.generator.data,
- pass->tc.generator.len,
- pass->tp.salt.data,
- pass->tp.salt.len) != SRP_SUCCESS ||
- SRP_set_authenticator(s_srp,
- pass->tp.password.data,
- pass->tp.password.len) != SRP_SUCCESS) {
- printf("Error initializing SRP parameters\r\n");
- SendSRPAuthSB(SRP_REJECT,(void *)"SRP parameter init failed", -1);
- return(AUTH_FAILURE);
- }
-
- pbuf = (char *)malloc(pass->tc.modulus.len + pass->tc.generator.len +
- pass->tp.salt.len + 7);
- ptr = pbuf;
-
- srp_encode_length(ptr, pass->tc.modulus.len);
- ptr += 2;
- memcpy(ptr, pass->tc.modulus.data, pass->tc.modulus.len);
- ptr += pass->tc.modulus.len;
-
- srp_encode_length(ptr, pass->tc.generator.len);
- ptr += 2;
- memcpy(ptr, pass->tc.generator.data, pass->tc.generator.len);
- ptr += pass->tc.generator.len;
-
- srp_encode_length(ptr, pass->tp.salt.len);
- ptr += 2;
- memcpy(ptr, pass->tp.salt.data, pass->tp.salt.len);
- ptr += pass->tp.salt.len;
-
- SendSRPAuthSB(SRP_PARAMS, pbuf, ptr - pbuf);
- free(pbuf);
- pbuf = NULL;
-
- if(SRP_gen_pub(s_srp, &B) != SRP_SUCCESS) {
- printf("Error generating SRP public value\r\n");
- SendSRPAuthSB(SRP_REJECT, (void *) "SRP_gen_pub failed", -1);
- return(AUTH_FAILURE);
- }
- ckstrncpy(szUserNameAuthenticated,szUserNameRequested,UIDBUFLEN);
- return AUTH_SUCCESS;
-
- case SRP_EXP:
- /* Client is sending A to us, compute challenge and expected response. */
- if (s_srp == NULL || B == NULL) {
- printf("Protocol error: SRP_EXP unexpected\r\n");
- SendSRPAuthSB(SRP_REJECT,
- (void *)"Protocol error: unexpected EXP", -1);
- return(AUTH_FAILURE);
- }
- /* Wait until now to send B, since it contains the key to "u" */
- SendSRPAuthSB(SRP_CHALLENGE, B->data, B->length);
- cstr_free(B);
- B = NULL;
-
- /*
- * The original SRP AUTH implementation did not protect against
- * tampering of the auth-type-pairs. Therefore, when the
- * AUTH_ENCRYPT_MASK bits are zero, no extra data is inserted
- * into the SRP hash computation. When AUTH_ENCRYPT_START_TLS
- * is set we also insert the SSL/TLS client and server finished
- * messages to ensure that there is no man in the middle attack
- * underway on the SSL/TLS connection.
- */
- if ( (how & AUTH_ENCRYPT_MASK) != AUTH_ENCRYPT_OFF ) {
- type_check[0] = AUTHTYPE_SRP;
- type_check[1] = how;
-#ifdef CK_SSL
- if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
- ssl_get_client_finished(&type_check[2],12);
- ssl_get_server_finished(&type_check[14],12);
- SRP_add_ex_data(s_srp, type_check, 26);
- } else
-#endif /* CK_SSL */
- SRP_add_ex_data(s_srp, type_check, 2);
- }
-
- if(SRP_compute_key(s_srp, &s_key, data, cnt) != SRP_SUCCESS) {
- printf("Security alert: Trivial session key attempted\r\n");
- SendSRPAuthSB(SRP_REJECT,
- (void *) "Trivial session key detected", -1);
- return(AUTH_FAILURE);
- }
- srp_waitresp = 1;
- return AUTH_SUCCESS;
-
- case SRP_RESPONSE:
- /* Got the response; see if it's correct */
- if (!srp_waitresp || s_srp == NULL) {
- if (1)
- printf("Protocol error: SRP_RESPONSE unexpected\r\n");
- SendSRPAuthSB(SRP_REJECT,
- (void *) "Protocol error: unexpected RESPONSE",
- -1
- );
- return(AUTH_FAILURE);
- }
- srp_waitresp = 0; /* we got a response */
-
- if (cnt < RESPONSE_LEN) {
- if (1)
- printf("Protocol error: malformed response\r\n");
- SendSRPAuthSB(SRP_REJECT,
- (void *) "Protocol error: malformed response",
- -1
- );
- return(AUTH_FAILURE);
- }
-
- if(SRP_verify(s_srp, data, cnt) == SRP_SUCCESS) {
- resp = cstr_new();
- if(SRP_respond(s_srp, &resp) != SRP_SUCCESS) {
- printf("Error computing response\r\n");
- SendSRPAuthSB(SRP_REJECT,
- (void *) "Error computing response", -1);
- return(AUTH_FAILURE);
- }
- SendSRPAuthSB(SRP_ACCEPT, resp->data, resp->length);
- accept_complete = 1;
- cstr_free(resp);
-
-#ifdef CK_ENCRYPTION
-#ifdef CK_SSL
- if (!(ssl_active_flag || tls_active_flag))
-#endif /* CK_SSL */
- {
- skey.type = SK_GENERIC;
- skey.length = s_key->length;
- skey.data = s_key->data;
- encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
- cstr_clear_free(s_key);
- s_key = NULL;
- }
-#endif /* CK_ENCRYPTION */
- auth_finished(AUTH_VALID);
- }
- else {
- SendSRPAuthSB(SRP_REJECT, (void *) "Login incorrect", -1);
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
- return AUTH_SUCCESS;
-
- default:
- printf("Unknown SRP option %d\r\n", data[-1]);
- SendSRPAuthSB(SRP_REJECT, (void *) "Unknown option received", -1);
- return(AUTH_FAILURE);
- }
-}
-#endif /* PRE_SRP_1_7_3 */
-#endif /* SRP */
-
-#ifdef KRB5
-#ifdef KINIT
-/*
- * clients/kinit/kinit.c
- *
- * Copyright 1990 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- *
- * Initialize a credentials cache.
- */
-
-#define KRB5_DEFAULT_OPTIONS 0
-#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
-
-static krb5_data tgtname = {
-#ifndef HEIMDAL
- 0,
-#endif /* HEIMDAL */
- KRB5_TGS_NAME_SIZE,
- KRB5_TGS_NAME
-};
-
-/* Internal prototypes */
-_PROTOTYP(static krb5_error_code krb5_validate_tgt,
- (krb5_context, krb5_ccache,krb5_principal, krb5_data *));
-_PROTOTYP(static krb5_error_code krb5_renew_tgt,
- (krb5_context, krb5_ccache,
- krb5_principal, krb5_data *));
-_PROTOTYP(static krb5_error_code krb5_tgt_gen,
- (krb5_context, krb5_ccache,
- krb5_principal, krb5_data *, int opt));
-
-#ifdef KRB5_HAVE_GET_INIT_CREDS
-static krb5_error_code KRB5_CALLCONV
-ck_krb5_prompter( krb5_context context,
- void *data,
- const char *name,
- const char *banner,
- int num_prompts,
- krb5_prompt prompts[])
-{
- krb5_error_code errcode = 0;
- int i;
-#ifdef KUI
- struct txtbox * tb = NULL;
-#else /* KUI */
- char * prompt = NULL;
-#endif /* KUI */
- int len = 0, blen=0, nlen=0;
-
- debug(F110,"ck_krb5_prompter name",name,0);
- debug(F110,"ck_krb5_prompter banner",banner,0);
- debug(F101,"ck_krb5_prompter num_prompts","",num_prompts);
-
- if (name)
- nlen = strlen(name)+2;
-
- if (banner)
- blen = strlen(banner)+2;
-
-#ifdef KUI
- tb = (struct txtbox *) malloc(sizeof(struct txtbox) * num_prompts);
- if ( tb != NULL ) {
- int ok;
- memset(tb,0,sizeof(struct txtbox) * num_prompts);
- for ( i=0; i < num_prompts; i++ ) {
- tb[i].t_buf = prompts[i].reply->data;
- tb[i].t_len = prompts[i].reply->length;
- tb[i].t_lbl = prompts[i].prompt;
- tb[i].t_dflt = NULL;
- tb[i].t_echo = (prompts[i].hidden ? 2 : 1);
- }
-
- ok = uq_mtxt((char *)banner,NULL,num_prompts,tb);
- if ( ok ) {
- for ( i=0; i < num_prompts; i++ )
- prompts[i].reply->length = strlen(prompts[i].reply->data);
- } else
- errcode = -2;
- }
-#else /* KUI */
- for (i = 0; i < num_prompts; i++) {
- debug(F111,"ck_krb5_prompter prompt",prompts[i].prompt,i);
-
- if ( prompt && len < (nlen + blen + strlen(prompts[i].prompt)+2) ) {
- free(prompt);
- prompt = NULL;
- }
- if ( !prompt )
- prompt = (char *)malloc(nlen + blen + strlen(prompts[i].prompt)+2);
- if ( !prompt ) {
- errcode = KRB5_RC_MALLOC;
- goto cleanup;
- }
- len = nlen + blen + strlen(prompts[i].prompt)+2;
- ckmakxmsg(prompt,len,
- (char *) (name?name:""),
- name?"\r\n":"",
- (char *) (banner?banner:""),
- banner?"\r\n":"",
- (char *)prompts[i].prompt,
- ": ",NULL,NULL,NULL,NULL,NULL,NULL);
-
- memset(prompts[i].reply->data, 0, prompts[i].reply->length);
- if (prompts[i].hidden) {
- readpass(prompt, prompts[i].reply->data,
- prompts[i].reply->length);
- } else {
- readtext(prompt, prompts[i].reply->data,
- prompts[i].reply->length);
- }
- prompts[i].reply->length = strlen(prompts[i].reply->data);
- }
-#endif /* KUI */
-
- cleanup:
-#ifdef KUI
- if ( tb )
- free(tb);
-#else /* KUI */
- if ( prompt )
- free(prompt);
-#endif /* KUI */
- if (errcode) {
- for (i = 0; i < num_prompts; i++) {
- memset(prompts[i].reply->data, 0, prompts[i].reply->length);
- }
- }
- return errcode;
-}
-
-/*
- * I'm not really sure what to do with this. The NRL DLLs use a
- * different interface for the krb5_prompter callback. It has
- * one less parameter. This is going to be ugly.
- */
-static krb5_error_code KRB5_CALLCONV
-ck_NRL_krb5_prompter( krb5_context context,
- const char *name,
- const char *banner,
- int num_prompts,
- krb5_prompt prompts[])
-{
- return(ck_krb5_prompter(context,NULL,name,banner,num_prompts,prompts));
-}
-#endif /* KRB5_HAVE_GET_INIT_CREDS */
-
-#ifdef KRB524_CONV
-long
-try_convert524(krb5_context ctx, krb5_principal me, krb5_ccache cc)
-{
- char * progname = "convert524";
- krb5_error_code code = 0;
- int icode = 0;
- krb5_principal kpcserver = 0;
- krb5_creds *v5creds = 0;
- krb5_creds increds;
-#ifdef OS2
- LEASH_CREDENTIALS v4creds;
-#else /* OS2 */
- CREDENTIALS v4creds;
-#endif /* OS2 */
-
- memset((char *) &increds, 0, sizeof(increds));
- /*
- From this point on, we can goto cleanup because increds is
- initialized.
- */
-
- if ((code = krb5_build_principal(ctx,
- &kpcserver,
- krb5_princ_realm(ctx, me)->length,
- krb5_princ_realm(ctx, me)->data,
- "krbtgt",
- krb5_princ_realm(ctx, me)->data,
- NULL))) {
- com_err(progname, code,
- "while creating service principal name");
- goto cleanup;
- }
-
- memset((char*) &increds, 0, sizeof(increds));
- increds.client = me;
- increds.server = kpcserver;
- /* Prevent duplicate free calls. */
- kpcserver = 0;
-
- increds.times.endtime = 0;
- increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
- if ((code = krb5_get_credentials(ctx, 0,
- cc,
- &increds,
- &v5creds))) {
- com_err(progname, code,
- "getting V5 credentials");
- goto cleanup;
- }
- if ((icode = krb524_convert_creds_kdc(ctx,
- v5creds,
- &v4creds))) {
- com_err(progname, icode,
- "converting to V4 credentials");
- goto cleanup;
- }
- /* this is stolen from the v4 kinit */
- /* initialize ticket cache */
- if ((icode = krb_in_tkt(v4creds.pname, v4creds.pinst, v4creds.realm)
- != KSUCCESS)) {
- com_err(progname, icode,
- "trying to create the V4 ticket file");
- goto cleanup;
- }
- /* stash ticket, session key, etc. for future use */
- if ((icode = krb_save_credentials(v4creds.service,
- v4creds.instance,
- v4creds.realm,
- v4creds.session,
- v4creds.lifetime,
- v4creds.kvno,
- &(v4creds.ticket_st),
- v4creds.issue_date))) {
- com_err(progname, icode,
- "trying to save the V4 ticket");
- goto cleanup;
- }
-
- cleanup:
- memset(&v4creds, 0, sizeof(v4creds));
- if (v5creds)
- krb5_free_creds(ctx, v5creds);
- increds.client = 0;
- krb5_free_cred_contents(ctx, &increds);
- if (kpcserver)
- krb5_free_principal(ctx, kpcserver);
- return !(code || icode);
-}
-#endif /* KRB524_CONV */
-
-#define NO_KEYTAB
-
-int
-#ifdef CK_ANSIC
-ck_krb5_initTGT( struct krb_op_data * op, struct krb5_init_data * init,
- struct krb4_init_data * k4_init)
-#else
-ck_krb5_initTGT(op,init,k4_init)
- krb_op_data * op; struct krb5_init_data * init;
- struct krb4_init_data * k4_init;
-#endif /* CK_ANSIC*/
-{
- krb5_context kcontext;
- krb5_ccache ccache = NULL;
- krb5_deltat lifetime = KRB5_DEFAULT_LIFE; /* -l option */
- krb5_timestamp starttime = 0;
- krb5_deltat rlife = 0;
- int options = KRB5_DEFAULT_OPTIONS;
- int option;
- int errflg = 0;
- krb5_error_code code;
- krb5_principal me=NULL;
- krb5_principal server=NULL;
- krb5_creds my_creds;
- krb5_timestamp now;
-#ifndef HEIMDAL
- krb5_address **addrs = (krb5_address **)0;
-#endif /* HEIMDAL */
- int addr_count=0;
- int i,j;
-#ifndef NO_KEYTAB
- int use_keytab = 0; /* -k option */
- krb5_keytab keytab = NULL;
-#endif /* NO_KEYTAB */
- struct passwd *pw = 0;
- int pwsize;
- char *client_name=NULL, principal[256]="", realm[256]="", numstr[40]="";
- char *password=NULL, passwd[80]="";
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- krb5_get_init_creds_opt opts;
-#endif
- char * name;
- int len;
-
- if ( !ck_krb5_is_installed() )
- return(-1);
-
-#ifdef COMMENT
- printf("Kerberos V initialization\r\n");
-#endif /* COMMENT */
-
- code = krb5_init_context(&kcontext);
- if (code) {
- com_err("krb5_kinit",code,"while init_context");
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
-
- debug(F110,"krb5_init","krb5_init_context",0);
-
- if ((code = krb5_timeofday(kcontext, &now))) {
- com_err("krb5_kinit",code,"while getting time of day");
- goto exit_k5_init;
- }
-
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- memset(&opts, 0, sizeof(opts));
- krb5_get_init_creds_opt_init(&opts);
- debug(F110,"krb5_init","krb5_get_init_creds_opt_init",0);
-#endif
-
- if ( init->renewable ) {
- options |= KDC_OPT_RENEWABLE;
- ckmakmsg(numstr,sizeof(numstr),ckitoa(init->renewable),"m",NULL,NULL);
-#ifdef HEIMDAL
- code = -1;
-#else /* HEIMDAL */
- code = krb5_string_to_deltat(numstr, &rlife);
-#endif /* HEIMDAL */
- if (code != 0 || rlife == 0) {
- printf("Bad renewable time value %s\r\n", numstr);
- errflg++;
- }
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- krb5_get_init_creds_opt_set_renew_life(&opts, rlife);
-#endif
- }
- if ( init->renew ) {
- /* renew the ticket */
- options |= KDC_OPT_RENEW;
- }
-
- if ( init->validate ) {
- /* validate the ticket */
- options |= KDC_OPT_VALIDATE;
- }
- if ( init->proxiable ) {
- options |= KDC_OPT_PROXIABLE;
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- krb5_get_init_creds_opt_set_proxiable(&opts, 1);
-#endif
- }
- if ( init->forwardable ) {
- options |= KDC_OPT_FORWARDABLE;
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- krb5_get_init_creds_opt_set_forwardable(&opts, 1);
-#endif
- }
-#ifndef NO_KEYTAB
- if ( ) {
- use_keytab = 1;
- }
- if ( ) {
- if (keytab == NULL && keytab_name != NULL) {
- code = krb5_kt_resolve(kcontext, keytab_name, &keytab);
- if (code != 0) {
- debug(F111,"krb5_init resolving keytab",
- keytab_name,code);
- errflg++;
- }
- }
- }
-#endif /* NO_KEYTAB */
- if ( init->lifetime ) {
- ckmakmsg(numstr,sizeof(numstr),ckitoa(init->lifetime),"m",NULL,NULL);
-#ifdef HEIMDAL
- code = -1;
-#else /* HEIMDAL */
- code = krb5_string_to_deltat(numstr, &lifetime);
-#endif /* HEIMDAL */
- if (code != 0 || lifetime == 0) {
- printf("Bad lifetime value %s\r\n", numstr);
- errflg++;
- }
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- krb5_get_init_creds_opt_set_tkt_life(&opts, lifetime);
-#endif
- }
- if ( init->postdate ) {
- /* Convert cmdate() to a time_t value */
- struct tm * time_tm;
- struct tm * cmdate2tm(char *,int);
- time_tm = cmdate2tm(init->postdate,0);
- if ( time_tm )
- starttime = (krb5_timestamp) mktime(time_tm);
-
- if (code != 0 || starttime == 0 || starttime == -1) {
- krb5_deltat ktmp;
-#ifdef HEIMDAL
- code = -1;
-#else /* HEIMDAL */
- code = krb5_string_to_deltat(init->postdate, &ktmp);
-#endif /* HEIMDAL */
- if (code == 0 && ktmp != 0) {
- starttime = now + ktmp;
- options |= KDC_OPT_POSTDATED;
- } else {
- printf("Bad postdate start time value %s\r\n",
- init->postdate);
- errflg++;
- }
- } else {
- options |= KDC_OPT_POSTDATED;
- }
- }
-
- debug(F110,"krb5_init searching for ccache",op->cache,0);
-
- code = k5_get_ccache(kcontext,&ccache,op->cache);
- if (code != 0) {
- com_err("krb5_kinit",code,"while getting default ccache");
- goto exit_k5_init;
- }
-
- /* This is our realm unless it is changed */
- ckstrncpy(realm,init->realm ? init->realm : krb5_d_realm, 256);
-
-#ifdef BETATEST
- /* This code is going to take the realm and attempt to correct */
- /* the case. */
- {
- profile_t profile;
-
- code = krb5_get_profile(kcontext, &profile);
- if ( !code ) {
- const char *names[4];
- char ** realms;
- int found = 0;
-
- names[0] = "realms";
- names[1] = NULL;
-
- code = profile_get_subsection_names(profile,names,&realms);
- if ( code == 0 ) {
- int i=0;
- while ( realms[i] ) {
- if (ckstrcmp(realm,realms[i],-1,0) == 0) {
- strcpy(realm,realms[i]);
- found = 1;
- break;
- }
- i++;
- }
- }
-
-#ifdef CK_DNS_SRV
- if ( !found ) {
- char * dns_realm = NULL;
-
- /* We did not find the realm in the profile so let's try DNS */
- locate_txt_rr("_kerberos",realm,&dns_realm);
- if ( dns_realm &&
- ckstrcmp(realm,dns_realm,-1,0) == 0 &&
- ckstrcmp(realm,dns_realm,-1,1) != 0
- ) {
- ckstrncpy(realm,dns_realm,256);
- free(dns_realm);
- }
- }
-#endif /* CK_DNS_SRV */
- }
-
- if (init->realm &&
- ckstrcmp(realm,init->realm,-1,0) == 0 &&
- ckstrcmp(realm,init->realm,-1,1) != 0)
- strcpy(init->realm,realm);
- if (ckstrcmp(realm,krb5_d_realm,-1,0) == 0 &&
- ckstrcmp(realm,krb5_d_realm,-1,1) != 0)
- strcpy(krb5_d_realm,realm);
- }
-#endif /* BETATEST */
-
- if (init->principal == NULL) { /* No principal name specified */
-#ifndef NO_KEYTAB
- if (use_keytab) {
- /* Use the default host/service name */
- code = krb5_sname_to_principal(kcontext, NULL, NULL,
- KRB5_NT_SRV_HST, &me);
- if (code == 0 &&
- krb5_princ_realm(kcontext, me)->length < sizeof(realm))
- {
- /* Save the realm */
- memcpy(realm,krb5_princ_realm(kcontext, me)->data,
- krb5_princ_realm(kcontext, me)->length); /* safe */
- realm[krb5_princ_realm(kcontext, me)->length]='\0';
- } else {
- com_err("krb5_kinit",
- code,
- "when creating default server principal name");
- goto exit_k5_init;
- }
- } else
-#endif /* NO_KEYTAB */
- {
- int len;
- char * name;
-
- /* Get default principal from cache if one exists */
- code = krb5_cc_get_principal(kcontext, ccache, &me);
-#ifdef HEIMDAL
- name = me->realm;
- len = strlen(name);
-#else /* HEIMDAL */
- len = krb5_princ_realm(kcontext, me)->length;
- name = krb5_princ_realm(kcontext, me)->data;
-#endif /* HEIMDAL */
- if (code == 0 && len < sizeof(realm))
- {
- /* Save the realm */
- memcpy(realm,name,len); /* safe */
- realm[len]='\0';
- } else {
-#ifdef HAVE_PWD_H
- /* Else search passwd file for client */
-
- pw = getpwuid((int) getuid());
- if (pw) {
- char princ_realm[256];
- if ( (strlen(pw->pw_name) + strlen(realm) + 1) > 255 )
- goto exit_k5_init;
-
- ckstrncpy(principal,pw->pw_name,256);
- ckstrncpy(princ_realm,pw->pw_name,256);
- ckstrncat(princ_realm,"@",256);
- ckstrncat(princ_realm,realm,256);
-
- if ((code = krb5_parse_name(kcontext,princ_realm,&me))) {
- krb5_errno = code;
- com_err("krb5_kinit",code,"when parsing name",
- princ_realm);
- goto exit_k5_init;
- }
- } else {
- printf(
- "Unable to identify user from password file\r\n");
- goto exit_k5_init;
- }
-#else /* HAVE_PWD_H */
- printf("Unable to identify user\r\n");
- goto exit_k5_init;
-#endif /* HAVE_PWD_H */
- }
- }
-
-#ifdef HEIMDAL
- len = me->name.name_string.len;
- name = *me->name.name_string.val;
-#else /* HEIMDAL */
- len = krb5_princ_name(kcontext, me)->length;
- name = krb5_princ_name(kcontext, me)->data;
-#endif /* HEIMDAL */
- if ( len < sizeof(principal) ) {
- memcpy(principal,name,len); /* safe */
- principal[len]='\0';
- }
- } /* Use specified name */
- else {
- char princ_realm[256];
- if ( (strlen(init->principal) +
- (init->instance ? strlen(init->instance)+1 : 0) +
- strlen(realm)
- + 2) > 255 )
- goto exit_k5_init;
-
- ckstrncpy(principal,init->principal,256);
- ckstrncpy(princ_realm,init->principal,256);
- if (init->instance) {
- ckstrncat(princ_realm,"/",256);
- ckstrncat(princ_realm,init->instance,256);
- }
- if (realm[0]) {
- ckstrncat(princ_realm,"@",256);
- ckstrncat(princ_realm,realm,256);
- }
- if ((code = krb5_parse_name (kcontext, princ_realm, &me))) {
- com_err("krb5_kinit",code,"when parsing name",princ_realm);
- goto exit_k5_init;
- }
- }
-
- if ((code = krb5_unparse_name(kcontext, me, &client_name))) {
- com_err("krb5_kinit",code,"when unparsing name");
- goto exit_k5_init;
- }
- debug(F110,"krb5_init client_name",client_name,0);
-
-
- memset((char *)&my_creds, 0, sizeof(my_creds));
- my_creds.client = me;
-
- if (init->service == NULL) {
- if ((code =
- krb5_build_principal_ext(kcontext,
- &server,
- strlen(realm),realm,
- tgtname.length, tgtname.data,
- strlen(realm),realm,
- 0))) {
- com_err("krb5_kinit",code,"while building server name");
- goto exit_k5_init;
- }
- } else {
- if (code = krb5_parse_name(kcontext, init->service, &server)) {
- com_err("krb5_kinit",code,"while parsing service name",
- init->service);
- goto exit_k5_init;
- }
- }
-
- my_creds.server = server;
-
- if (options & KDC_OPT_POSTDATED) {
- my_creds.times.starttime = starttime;
- my_creds.times.endtime = starttime + lifetime;
- } else {
- my_creds.times.starttime = 0; /* start timer when request
- gets to KDC */
- my_creds.times.endtime = now + lifetime;
- }
- if (options & KDC_OPT_RENEWABLE) {
- my_creds.times.renew_till = now + rlife;
- } else
- my_creds.times.renew_till = 0;
-
- if (options & KDC_OPT_VALIDATE) {
- krb5_data outbuf;
-
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- code = krb5_get_validated_creds(kcontext,
- &my_creds, me, ccache, init->service);
- if ( code == -1 )
-#endif
- {
-#ifdef HEIMDAL
- printf("?validate not implemented\r\n");
- code = -1;
- goto exit_k5_init;
-#else /* HEIMDAL */
- code = krb5_validate_tgt(kcontext, ccache, server, &outbuf);
-#endif /* HEIMDAL */
- }
- if (code) {
- com_err("krb5_kinit",code,"validating tgt");
- goto exit_k5_init;
- }
- /* should be done... */
- goto exit_k5_init;
- }
-
- if (options & KDC_OPT_RENEW) {
- krb5_data outbuf;
-
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- code = krb5_get_renewed_creds(kcontext,
- &my_creds, me, ccache, init->service);
- if ( code == -1 )
-#endif
- {
-#ifdef HEIMDAL
- printf("?renew not implemented\r\n");
- code = -1;
- goto exit_k5_init;
-#else /* HEIMDAL */
- code = krb5_renew_tgt(kcontext, ccache, server, &outbuf);
-#endif /* HEIMDAL */
- }
- if (code) {
- com_err("krb5_kinit",code,"while renewing tgt");
- goto exit_k5_init;
- }
- /* should be done... */
- goto store_cred;
- }
-
-#ifndef HEIMDAL
- if ( init->addrs && !init->no_addresses ) {
- /* construct an array of krb5_address structs to pass to get_in_tkt */
- /* include both the local ip addresses as well as any other that */
- /* are specified. */
- unsigned long ipaddr;
-
- for ( addr_count=0;addr_count<KRB5_NUM_OF_ADDRS;addr_count++ )
- if ( init->addrs[addr_count] == NULL )
- break;
-
- if (addr_count > 0) {
- krb5_address ** local_addrs=NULL;
- krb5_os_localaddr(kcontext, &local_addrs);
- i = 0;
- while ( local_addrs[i] )
- i++;
- addr_count += i;
-
- addrs = (krb5_address **)
- malloc((addr_count+1) * sizeof(krb5_address *));
- if ( !addrs ) {
- krb5_free_addresses(kcontext, local_addrs);
- goto exit_k5_init;
- }
- memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1));
- i = 0;
- while ( local_addrs[i] ) {
- addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
- if (addrs[i] == NULL) {
- krb5_free_addresses(kcontext, local_addrs);
- goto exit_k5_init;
- }
-
- addrs[i]->magic = local_addrs[i]->magic;
- addrs[i]->addrtype = local_addrs[i]->addrtype;
- addrs[i]->length = local_addrs[i]->length;
- addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
- if (!addrs[i]->contents) {
- krb5_free_addresses(kcontext, local_addrs);
- goto exit_k5_init;
- }
-
- memcpy(addrs[i]->contents,local_addrs[i]->contents,
- local_addrs[i]->length); /* safe */
- i++;
- }
- krb5_free_addresses(kcontext, local_addrs);
-
- for ( j=0;i<addr_count;i++,j++ ) {
- addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
- if (addrs[i] == NULL)
- goto exit_k5_init;
-
- addrs[i]->magic = KV5M_ADDRESS;
- addrs[i]->addrtype = AF_INET;
- addrs[i]->length = 4;
- addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
- if (!addrs[i]->contents)
- goto exit_k5_init;
-
- ipaddr = inet_addr(init->addrs[j]);
- memcpy(addrs[i]->contents,&ipaddr,4); /* safe */
- }
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- krb5_get_init_creds_opt_set_address_list(&opts,addrs);
-#endif
- }
- }
-#endif /* !HEIMDAL */
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- if ( init->no_addresses )
- krb5_get_init_creds_opt_set_address_list(&opts,NULL);
-#endif
-
-#ifndef NO_KEYTAB
- if (!use_keytab)
-#endif
- {
- if ( init->password ) {
- pwsize = strlen(init->password);
- if ( pwsize )
- password = init->password;
- } else if (init->getk4 && k4_init) {
- /* When we are requesting that K4 tickets be automatically */
- /* acquired when K5 tickets are acquired, we must get the */
- /* password up front. */
- char prmpt[256];
- extern char * k5prprompt;
- extern char * k5pwprompt;
- int ok = 0;
-
- if ( k5pwprompt && k5pwprompt[0] &&
- (strlen(k5pwprompt) + strlen(principal) +
- strlen(realm) - 4) < sizeof(prmpt)) {
- sprintf(prmpt,k5pwprompt,principal,realm);
- } else
- ckmakxmsg(prmpt,sizeof(prmpt),
- k5pwprompt && k5pwprompt[0] ? k5pwprompt :
- "Kerberos 5 Password for ",
- principal,"@",realm,": ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- ok = uq_txt(NULL,prmpt,2,NULL,passwd,80,NULL,DEFAULT_UQ_TIMEOUT);
- if ( ok )
- password = passwd;
-
- if ( k4_init->password == NULL )
- makestr(&k4_init->password,passwd);
- }
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- debug(F100,"krb5_init calling krb5_get_init_creds_password()","",0);
-#ifdef OS2
- if ( is_NRL_KRB5() )
- code = krb5_get_init_creds_password(kcontext, &my_creds, me,
- password,
- (void *)ck_NRL_krb5_prompter,
- NULL,
- starttime, init->service,
- &opts);
- else
-#endif /* OS2 */
- code = krb5_get_init_creds_password(kcontext, &my_creds, me,
- password,
- ck_krb5_prompter,
- NULL,
- starttime, init->service,
- &opts);
- debug(F111,"krb5_init","krb5_get_init_creds_password()",code);
-
- if ( code == -1 )
- {
- if (!password) {
- char prmpt[256];
- int ok;
-
- ckmakmsg(prmpt,sizeof(prmpt),"Kerberos 5 Password for ",
- client_name,": ",NULL);
- ok = uq_txt(NULL,prmpt,2,NULL,passwd,80,NULL,
- DEFAULT_UQ_TIMEOUT);
- if ( ok )
- password = passwd;
- else {
- code = -2;
- goto exit_k5_init;
- }
- }
-
- if ( !password )
- password = "";
- code = krb5_get_in_tkt_with_password(kcontext, options,
-#ifdef HEIMDAL
- NULL,
-#else /* HEIMDAL */
- init->no_addresses ? NULL :addrs,
-#endif /* HEIMDAL */
- NULL, NULL,
- password,
- NULL, &my_creds, NULL);
- if ( code )
- debug(F111,"krb5_init","krb5_get_in_tkt_with_password()",code);
- }
-#else /* KRB5_HAVE_GET_INIT_CREDS */
- if (!password) {
- char prmpt[256];
- int ok;
-
- ckmakmsg(prmpt,sizeof(prmpt),"Kerberos 5 Password for ",
- client_name,": ",NULL);
- ok = uq_txt(NULL,prmpt,2,NULL,passwd,80,NULL,DEFAULT_UQ_TIMEOUT);
- if ( ok )
- password = passwd;
- else {
- code = -2;
- goto exit_k5_init;
- }
- }
- if ( !password )
- password = "";
- code = krb5_get_in_tkt_with_password(kcontext, options,
-#ifdef HEIMDAL
- NULL,
-#else /* HEIMDAL */
- init->no_addresses ? NULL :addrs,
-#endif /* HEIMDAL */
- NULL, NULL,
- password,
- NULL, &my_creds, NULL);
- if ( code )
- debug(F111,"krb5_init","krb5_get_in_tkt_with_password()",code);
-#endif /* KRB5_HAVE_GET_INIT_CREDS */
-
- if ( init->password && pwsize > 0 )
- memset(init->password, 0, pwsize);
- memset(passwd,0,80);
- }
-#ifndef NO_KEYTAB
- else {
-#ifdef KRB5_HAVE_GET_INIT_CREDS
- code = krb5_get_init_creds_keytab(kcontext, &my_creds, me, keytab,
- starttime, init->service,
- &opts);
-#ifdef OS2
- if ( code == -1)
- code = krb5_get_in_tkt_with_keytab(kcontext, options,
- init->no_addresses ? NULL :addrs,
- NULL, NULL, keytab, NULL,
- &my_creds, 0);
-#endif /* OS2 */
-#else /* KRB5_HAVE_GET_INIT_CREDS */
- code = krb5_get_in_tkt_with_keytab(kcontext, options,
-#ifdef HEIMDAL
- NULL,
-#else /* HEIMDAL */
- init->no_addresses ? NULL :addrs,
-#endif /* HEIMDAL */
- NULL, NULL, keytab, NULL,
- &my_creds, 0);
-#endif /* KRB5_HAVE_GET_INIT_CREDS */
- }
-#endif
-
- if (code) {
- switch (code) {
- case KRB5KRB_AP_ERR_BAD_INTEGRITY:
- printf("Password incorrect\r\n");
- goto exit_k5_init;
- case KRB5KRB_AP_ERR_V4_REPLY:
- if (init->getk4 && k4_init) {
- printf("Kerberos 5 Tickets not support by server. ");
- printf("A version 4 Ticket will be requested.\r\n");
- }
- goto exit_k5_init;
- default:
- goto exit_k5_init;
- }
- }
-
- store_cred:
- debug(F100,"krb5_init calling krb5_cc_initialize()","",0);
-
- code = krb5_cc_initialize (kcontext, ccache, me);
- if ( code == KRB5_CC_BADNAME ) {
- /* This is a really ugly hack that should not have to be here.
- * krb5_cc_initialize should not fail with an error if the
- * cache already exists. The reason the problem is occuring
- * is that the krb5 library is no longer calling cc_destroy()
- * when cc_initialize() is called and the CCAPI implementation
- * on Windows has not yet been corrected to handle it. To
- * ensure that K95 will continue to work with both we will call
- * cc_destroy() if the cc_initialize() call fails with a BADNAME
- * error. If the cc_destroy() is successful, we will try again.
- */
-
- debug(F100,"krb5_init calling krb5_cc_destroy()","",0);
- code = krb5_cc_destroy (kcontext, ccache);
- if ( !code ) {
- debug(F100,"krb5_init calling k5_get_ccache()","",0);
- code = k5_get_ccache(kcontext,&ccache,op->cache);
- debug(F100,"krb5_init calling krb5_cc_initialize()","",0);
- code = krb5_cc_initialize (kcontext, ccache, me);
- } else
- code = KRB5_CC_BADNAME;
- }
- if (code) {
- com_err("krb5_kinit",code,"when initializing cache",op->cache);
- goto exit_k5_init;
- }
-
- debug(F100,"krb5_init calling krb5_cc_store_cred()","",0);
- code = krb5_cc_store_cred(kcontext, ccache, &my_creds);
- if (code) {
- com_err("krb5_kinit",code,"while storing credentials");
- goto exit_k5_init;
- }
-
- if ( init->getk4 &&
-#ifdef KRB524_CONV
- !try_convert524(kcontext,me,ccache) &&
-#endif /* KRB524_CONV */
- k4_init ) {
- int k4rc = ck_krb4_initTGT(op,k4_init);
- if (k4rc < 0)
- code = -3;
- }
-
-exit_k5_init:
- debug(F100,"krb5_init exit_k5_init","",0);
-
-#ifndef HEIMDAL
- /* Free krb5_address structures if we created them */
- if ( addrs ) {
- for ( i=0;i<addr_count;i++ ) {
- if ( addrs[i] ) {
- if ( addrs[i]->contents )
- free(addrs[i]->contents);
- free(addrs[i]);
- }
- }
- }
-#endif /* HEIMDAL */
-
-
- krb5_errno = code;
- makestr(&krb5_errmsg,krb5_errno ? error_message(krb5_errno) : "OK");
-
- if (client_name)
- krb5_free_unparsed_name(kcontext, client_name);
-
- /* my_creds is pointing at server */
- debug(F100,"krb5_init calling krb5_free_principal()","",0);
- krb5_free_principal(kcontext, server);
- debug(F100,"krb5_init calling krb5_cc_close()","",0);
- krb5_cc_close(kcontext,ccache);
- debug(F100,"krb5_init calling krb5_free_context()","",0);
- krb5_free_context(kcontext);
-
- if (code != -2)
- printf("Result from realm %s: %s\r\n",realm,
- code==-3?"Unable to retrieve Kerberos IV credentials":
- code?error_message(code):"OK");
- return(code?-1:0);
-}
-
-#ifndef HEIMDAL
-#define VALIDATE 0
-#define RENEW 1
-
-/* stripped down version of krb5_mk_req */
-static krb5_error_code
-#ifdef CK_ANSIC
-krb5_validate_tgt( krb5_context context,
- krb5_ccache ccache,
- krb5_principal server, /* tgtname */
- krb5_data *outbuf )
-#else
-krb5_validate_tgt(context, ccache, server, outbuf)
- krb5_context context;
- krb5_ccache ccache;
- krb5_principal server; /* tgtname */
- krb5_data *outbuf;
-#endif
-{
- return krb5_tgt_gen(context, ccache, server, outbuf, VALIDATE);
-}
-
-/* stripped down version of krb5_mk_req */
-static krb5_error_code
-#ifdef CK_ANSIC
-krb5_renew_tgt(krb5_context context,
- krb5_ccache ccache,
- krb5_principal server, /* tgtname */
- krb5_data *outbuf)
-#else
-krb5_renew_tgt(context, ccache, server, outbuf)
- krb5_context context;
- krb5_ccache ccache;
- krb5_principal server; /* tgtname */
- krb5_data *outbuf;
-#endif
-{
- return krb5_tgt_gen(context, ccache, server, outbuf, RENEW);
-}
-
-
-/* stripped down version of krb5_mk_req */
-static krb5_error_code
-#ifdef CK_ANSIC
-krb5_tgt_gen(krb5_context context,
- krb5_ccache ccache,
- krb5_principal server, /* tgtname */
- krb5_data *outbuf,
- int opt)
-#else
-krb5_tgt_gen(context, ccache, server, outbuf, opt)
- krb5_context context;
- krb5_ccache ccache;
- krb5_principal server; /* tgtname */
- krb5_data *outbuf;
- int opt;
-#endif
-{
- krb5_error_code retval;
- krb5_creds * credsp;
- krb5_creds creds;
-
- /* obtain ticket & session key */
- memset((char *)&creds, 0, sizeof(creds));
- if ((retval = krb5_copy_principal(context, server, &creds.server)))
- goto cleanup;
-
- if ((retval = krb5_cc_get_principal(context, ccache, &creds.client)))
- goto cleanup_creds;
-
- if (opt == VALIDATE) {
- if ((retval = krb5_get_credentials_validate(context, 0,
- ccache, &creds, &credsp)))
- goto cleanup_creds;
- } else {
- if ((retval = krb5_get_credentials_renew(context, 0,
- ccache, &creds, &credsp)))
- goto cleanup_creds;
- }
-
- /* we don't actually need to do the mk_req, just get the creds. */
-cleanup_creds:
- krb5_free_cred_contents(context, &creds);
-
-cleanup:
-
- return retval;
-}
-#endif /* HEIMDAL */
-#endif /* KINIT */
-#ifdef KDESTROY
-int
-#ifdef CK_ANSIC
-ck_krb5_destroy(struct krb_op_data * op)
-#else
-ck_krb5_destroy(op) struct krb_op_data * op;
-#endif
-{
- krb5_context kcontext;
- krb5_error_code retval;
- int c;
- krb5_ccache ccache = NULL;
- char *cache_name = NULL;
- int code;
- int errflg=0;
- int quiet = 0;
-
- if ( !ck_krb5_is_installed() )
- return(-1);
-
- code = krb5_init_context(&kcontext);
- if (code) {
- debug(F101,"ck_krb5_destroy while initializing krb5","",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
-
- code = k5_get_ccache(kcontext,&ccache,op->cache);
- if (code != 0) {
- debug(F101,"ck_krb5_destroy while getting ccache",
- "",code);
- krb5_free_context(kcontext);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
-
- code = krb5_cc_destroy (kcontext, ccache);
- if (code != 0) {
- debug(F101,"ck_krb5_destroy while destroying cache","",code);
- if ( code == KRB5_FCC_NOFILE )
- printf("No ticket cache to destroy.\r\n");
- else
- printf("Ticket cache NOT destroyed!\r\n");
- krb5_cc_close(kcontext,ccache);
- krb5_free_context(kcontext);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
-
- printf("Tickets destroyed.\r\n");
- /* Do not call krb5_cc_close() because cache has been destroyed */
- krb5_free_context(kcontext);
- krb5_errno = 0;
- makestr(&krb5_errmsg,"OK");
- return (0);
-}
-#else /* KDESTROY */
-#ifdef KRB5
-int
-#ifdef CK_ANSIC
-ck_krb5_destroy(struct krb_op_data * op)
-#else
-ck_krb5_destroy(op) struct krb_op_data * op;
-#endif
-{
- printf("?Not implemented.\r\n");
- return(-1);
-}
-#endif /* KRB5 */
-#endif /* KDESTROY */
-#ifndef KLIST
-#ifdef KRB5
-int
-#ifdef CK_ANSIC
-ck_krb5_list_creds(struct krb_op_data * op, struct krb5_list_cred_data * lc)
-#else
-ck_krb5_list_creds(op,lc)
- struct krb_op_data * op; struct krb5_list_cred_data * lc;
-#endif
-{
- printf("?Not implemented.\r\n");
- return(-1);
-}
-#endif /* KRB5 */
-#else /* KLIST */
-static int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
-static int show_etype = 0, show_addr = 0;
-static char *defname;
-static char *progname;
-static krb5_int32 now;
-static int timestamp_width;
-
-_PROTOTYP(static char * etype_string, (krb5_enctype ));
-_PROTOTYP(static void show_credential,(krb5_context,krb5_creds *));
-_PROTOTYP(static int do_ccache, (krb5_context,char *));
-_PROTOTYP(static int do_keytab, (krb5_context,char *));
-_PROTOTYP(static void printtime, (time_t));
-_PROTOTYP(static void fillit, (int, int));
-
-#define DEFAULT 0
-#define CCACHE 1
-#define KEYTAB 2
-
-int
-#ifdef CK_ANSIC
-ck_krb5_list_creds(struct krb_op_data * op, struct krb5_list_cred_data * lc)
-#else
-ck_krb5_list_creds(op,lc)
- struct krb_op_data * op; struct krb5_list_cred_data * lc;
-#endif
-{
- krb5_context kcontext;
- krb5_error_code retval;
- int code;
- char *name = op->cache;
- int mode;
-
- if ( !ck_krb5_is_installed() )
- return(-1);
-
- code = krb5_init_context(&kcontext);
- if (code) {
- debug(F101,"ck_krb5_list_creds while initializing krb5","",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
-
- name = op->cache;
- mode = DEFAULT;
- show_flags = 0;
- show_time = 0;
- status_only = 0;
- show_keys = 0;
- show_etype = 0;
- show_addr = 0;
-
- show_flags = lc->flags;
- show_etype = lc->encryption;
- show_addr = lc->addr;
- show_time = 1;
- show_keys = 1;
- mode = CCACHE;
-
- if ((code = krb5_timeofday(kcontext, &now))) {
- if (!status_only)
- debug(F101,"ck_krb5_list_creds while getting time of day.",
- "",code);
- krb5_free_context(kcontext);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
- else {
- char tmp[BUFSIZ];
-
- if (!krb5_timestamp_to_sfstring(now, tmp, 20, (char *) NULL) ||
- !krb5_timestamp_to_sfstring(now, tmp, sizeof(tmp), (char *) NULL))
- timestamp_width = (int) strlen(tmp);
- else
- timestamp_width = 15;
- }
-
- if (mode == DEFAULT || mode == CCACHE)
- retval = do_ccache(kcontext,name);
- else
- retval = do_keytab(kcontext,name);
- krb5_free_context(kcontext);
- return(retval);
-}
-
-static int
-#ifdef CK_ANSIC
-do_keytab(krb5_context kcontext, char * name)
-#else
-do_keytab(kcontext,name) krb5_context kcontext; char * name;
-#endif
-{
- krb5_keytab kt;
- krb5_keytab_entry entry;
- krb5_kt_cursor cursor;
- char buf[BUFSIZ]; /* hopefully large enough for any type */
- char *pname;
- int code = 0;
-
- if (name == NULL) {
- if ((code = krb5_kt_default(kcontext, &kt))) {
- debug(F101,"ck_krb5_list_creds while getting default keytab",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
- } else {
- if ((code = krb5_kt_resolve(kcontext, name, &kt))) {
- debug(F111,"ck_krb5_list_creds while resolving keytab",
- name,code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
- }
-
- if ((code = krb5_kt_get_name(kcontext, kt, buf, BUFSIZ))) {
- debug(F101,"ck_krb5_list_creds while getting keytab name",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
-
- printf("Keytab name: %s\r\n", buf);
-
- if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor))) {
- debug(F101,"ck_krb5_list_creds while starting keytab scan",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
-
- if (show_time) {
- printf("KVNO Timestamp");
- fillit(timestamp_width - sizeof("Timestamp") + 2, (int) ' ');
- printf("Principal\r\n");
- printf("---- ");
- fillit(timestamp_width, (int) '-');
- printf(" ");
- fillit(78 - timestamp_width - sizeof("KVNO"), (int) '-');
- printf("\r\n");
- } else {
- printf("KVNO Principal\r\n");
- printf(
-"---- --------------------------------------------------------------------\
-------\r\n");
- }
-
- while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) {
- if ((code = krb5_unparse_name(kcontext, entry.principal, &pname))) {
- debug(F101,"ck_krb5_list_creds while unparsing principal name",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
- printf("%4d ", entry.vno);
- if (show_time) {
- printtime(entry.timestamp);
- printf(" ");
- }
- printf("%s", pname);
- if (show_etype)
- printf(" (%s) " ,
-#ifdef HEIMDAL
- etype_string(entry.key.keytype)
-#else /* HEIMDAL */
- etype_string(entry.key.enctype)
-#endif /* HEIMDAL */
- );
- if (show_keys) {
- printf(" (0x");
- {
- int i;
- for (i = 0; i < entry.key.length; i++)
- printf("%02x",
-#ifdef HEIMDAL
- entry.key.keyvalue[i]
-#else /* HEIMDAL */
- entry.key.contents[i]
-#endif /* HEIMDAL */
- );
- }
- printf(")");
- }
- printf("\r\n");
- krb5_free_unparsed_name(kcontext,pname);
- }
- if (code && code != KRB5_KT_END) {
- debug(F101,"ck_krb5_list_creds while scanning keytab",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
- if ((code = krb5_kt_end_seq_get(kcontext, kt, &cursor))) {
- debug(F101,"ck_krb5_list_creds while ending keytab scan",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
- krb5_errno = 0;
- makestr(&krb5_errmsg,"OK");
- return(0);
-}
-
-static int
-#ifdef CK_ANSIC
-do_ccache(krb5_context kcontext, char * cc_name)
-#else
-do_ccache(kcontext,name) krb5_context kcontext; char * cc_name;
-#endif
-{
- krb5_ccache cache = NULL;
- krb5_cc_cursor cur;
- krb5_creds creds;
- krb5_principal princ=NULL;
- krb5_flags flags=0;
- krb5_error_code code = 0;
- int exit_status = 0;
-
- if (status_only)
- /* exit_status is set back to 0 if a valid tgt is found */
- exit_status = 1;
-
- code = k5_get_ccache(kcontext,&cache,cc_name);
- if (code != 0) {
- debug(F111,"do_ccache while getting ccache",
- error_message(code),code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return(-1);
- }
-
- flags = 0; /* turns off OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- if (code == ENOENT) {
- debug(F111,"ck_krb5_list_creds (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- } else {
- debug(F111,
- "ck_krb5_list_creds while setting cache flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- }
- printf("No ticket File.\r\n");
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- krb5_cc_close(kcontext,cache);
- return(-1);
- }
- if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
- debug(F101,"ck_krb5_list_creds while retrieving principal name",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- krb5_cc_close(kcontext,cache);
- return(-1);
- }
- if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
- debug(F101,"ck_krb5_list_creds while unparsing principal name",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- krb5_cc_close(kcontext,cache);
- return(-1);
- }
- if (!status_only) {
- printf("Ticket cache: %s:%s\r\nDefault principal: %s\r\n\r\n",
- krb5_cc_get_type(kcontext, cache),
- krb5_cc_get_name(kcontext, cache), defname);
- printf("Valid starting");
- fillit(timestamp_width - sizeof("Valid starting") + 3,
- (int) ' ');
- printf("Expires");
- fillit(timestamp_width - sizeof("Expires") + 3,
- (int) ' ');
- printf("Service principal\r\n");
- }
- if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_list_creds while starting to retrieve tickets",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- krb5_cc_close(kcontext,cache);
- return(-1);
- }
- while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
- if (status_only) {
- if (exit_status && creds.server->length == 2 &&
- strcmp(creds.server->realm.data, princ->realm.data) == 0 &&
- strcmp((char *)creds.server->data[0].data, "krbtgt") == 0 &&
- strcmp((char *)creds.server->data[1].data,
- princ->realm.data) == 0 &&
- creds.times.endtime > now)
- exit_status = 0;
- } else {
- show_credential(kcontext, &creds);
- }
- krb5_free_cred_contents(kcontext, &creds);
- }
- printf("\r\n");
- if (code == KRB5_CC_END || code == KRB5_CC_NOTFOUND) {
- if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_list_creds while finishing ticket retrieval",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- krb5_cc_close(kcontext,cache);
- return(-1);
- }
- flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- debug(F101,"ck_krb5_list_creds while closing ccache",
- "",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- krb5_cc_close(kcontext,cache);
- return(-1);
- }
- krb5_errno = 0;
- makestr(&krb5_errmsg,"OK");
- krb5_cc_close(kcontext,cache);
- return(0);
- } else {
- debug(F101,"ck_krb5_list_creds while retrieving a ticket","",code);
- krb5_errno = code;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- krb5_cc_close(kcontext,cache);
- return(-1);
- }
- krb5_errno = 0;
- makestr(&krb5_errmsg,"OK");
- krb5_cc_close(kcontext,cache);
- return(0);
-}
-
-static char *
-#ifdef CK_ANSIC
-#ifdef HEIMDAL
-etype_string(krb5_keytype enctype)
-#else /* HEIMDAL */
-etype_string(krb5_enctype enctype)
-#endif /* HEIMDAL */
-#else
-#ifdef HEIMDAL
-etype_string(enctype) krb5_keytype enctype;
-#else /* HEIMDAL */
-etype_string(enctype) krb5_enctype enctype;
-#endif /* HEIMDAL */
-#endif
-{
- static char buf[12];
-
- switch (enctype) {
- case ENCTYPE_NULL:
- return "NULL";
- case ENCTYPE_DES_CBC_CRC:
- return "DES-CBC-CRC";
- case ENCTYPE_DES_CBC_MD4:
- return "DES-CBC-MD4";
- case ENCTYPE_DES_CBC_MD5:
- return "DES-CBC-MD5";
- case ENCTYPE_DES_CBC_RAW:
- return "DES-CBC-RAW";
- case ENCTYPE_DES3_CBC_SHA:
- return "DES3-CBC-SHA";
- case ENCTYPE_DES3_CBC_RAW:
- return "DES3-CBC-RAW";
- case ENCTYPE_DES_HMAC_SHA1:
- return "DES-HMAC-SHA1";
- case ENCTYPE_DES3_CBC_SHA1:
- return "DES3-CBC-SHA1";
- case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
- return "AES128_CTS-HMAC-SHA1_96";
- case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
- return "AES256_CTS-HMAC-SHA1_96";
- case ENCTYPE_ARCFOUR_HMAC:
- return "RC4-HMAC-NT";
- case ENCTYPE_ARCFOUR_HMAC_EXP:
- return "RC4-HMAC-NT-EXP";
- case ENCTYPE_UNKNOWN:
- return "UNKNOWN";
- case ENCTYPE_LOCAL_DES3_HMAC_SHA1:
- return "LOCAL-DES3-HMAC-SHA1";
- case ENCTYPE_LOCAL_RC4_MD4:
- return "LOCAL-RC4-MD4";
- default:
- ckmakmsg(buf, sizeof(buf),"etype ", ckitoa(enctype),NULL,NULL);
- return buf;
- break;
- }
-}
-
-static char *
-#ifdef CK_ANSIC
-flags_string(register krb5_creds *cred)
-#else
-flags_string(cred) register krb5_creds *cred;
-#endif
-{
- static char buf[32];
- int i = 0;
-
- if (cred->ticket_flags & TKT_FLG_FORWARDABLE)
- buf[i++] = 'F';
- if (cred->ticket_flags & TKT_FLG_FORWARDED)
- buf[i++] = 'f';
- if (cred->ticket_flags & TKT_FLG_PROXIABLE)
- buf[i++] = 'P';
- if (cred->ticket_flags & TKT_FLG_PROXY)
- buf[i++] = 'p';
- if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE)
- buf[i++] = 'D';
- if (cred->ticket_flags & TKT_FLG_POSTDATED)
- buf[i++] = 'd';
- if (cred->ticket_flags & TKT_FLG_INVALID)
- buf[i++] = 'i';
- if (cred->ticket_flags & TKT_FLG_RENEWABLE)
- buf[i++] = 'R';
- if (cred->ticket_flags & TKT_FLG_INITIAL)
- buf[i++] = 'I';
- if (cred->ticket_flags & TKT_FLG_HW_AUTH)
- buf[i++] = 'H';
- if (cred->ticket_flags & TKT_FLG_PRE_AUTH)
- buf[i++] = 'A';
- buf[i] = '\0';
- return(buf);
-}
-
-static char *
-#ifdef CK_ANSIC
-short_date(long *dp)
-#else
-short_date(dp) long *dp;
-#endif
-{
- register char *cp;
-#ifndef ctime
- extern char *ctime();
-#endif /* ctime */
- cp = ctime(dp) + 4;
- cp[15] = '\0';
- return (cp);
-}
-
-
-static VOID
-#ifdef CK_ANSIC
-printtime(time_t tv)
-#else
-printtime(tv) time_t tv;
-#endif
-{
- char timestring[BUFSIZ];
- char format[12];
- char fill;
-
- fill = ' ';
- sprintf(format,"%%-%ds",timestamp_width); /* safe */
- if (!krb5_timestamp_to_sfstring((krb5_timestamp) tv,
- timestring,
- timestamp_width+1,
- &fill)) {
- printf(format,timestring);
- }
- else {
- printf(format,short_date(&tv));
- }
-
-}
-
-static void
-#ifdef CK_ANSIC
-one_addr(krb5_address *a)
-#else
-one_addr(a) krb5_address *a;
-#endif
-{
- struct hostent *h;
- extern tcp_rdns;
-
- if ((a->addrtype == ADDRTYPE_INET) &&
- (a->length == 4)) {
- if (tcp_rdns != SET_OFF) {
- h = gethostbyaddr(a->contents, 4, AF_INET);
- if (h) {
-#ifdef HADDRLIST
- h = ck_copyhostent(h);
-#endif /* HADDRLIST */
- printf("%s (%d.%d.%d.%d)", h->h_name,
- a->contents[0], a->contents[1],
- a->contents[2], a->contents[3]);
- }
- }
- if (tcp_rdns == SET_OFF || !h) {
- printf("%d.%d.%d.%d", a->contents[0], a->contents[1],
- a->contents[2], a->contents[3]);
- }
- } else {
- printf("unknown addr type %d", a->addrtype);
- }
-}
-
-static VOID
-#ifdef CK_ANSIC
-show_credential(krb5_context kcontext, register krb5_creds * cred)
-#else
-show_credential(kcontext, cred)
- krb5_context kcontext;
- register krb5_creds * cred;
-#endif
-{
- krb5_error_code retval=0;
- krb5_ticket *tkt=NULL;
- char *name=NULL, *sname=NULL, *flags=NULL;
- int extra_field = 0;
-
- retval = krb5_unparse_name(kcontext, cred->client, &name);
- if (retval) {
- debug(F101,"ck_krb5_list_creds while unparsing client name","",retval);
- krb5_errno = retval;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return;
- }
- retval = krb5_unparse_name(kcontext, cred->server, &sname);
- if (retval) {
- debug(F101,"ck_krb5_list_creds while unparsing server name","",retval);
- free(name);
- krb5_errno = retval;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return;
- }
- if (!cred->times.starttime)
- cred->times.starttime = cred->times.authtime;
-
- printtime(cred->times.starttime);
- printf(" ");
-
- if ( time(0) < cred->times.endtime )
- printtime(cred->times.endtime);
- else
- printf("** expired ** ");
-
- printf(" %s\r\n", sname);
-
- if (strcmp(name, defname)) {
- printf(" for client %s", name);
- extra_field++;
- }
-
- if (cred->times.renew_till) {
- if (!extra_field)
- printf(" ");
- else
- printf(", ");
- printf("renew until ");
- printtime(cred->times.renew_till);
- extra_field += 2;
- }
-
- if (extra_field > 3) {
- printf("\r\n");
- extra_field = 0;
- }
-
- if (show_flags) {
- flags = flags_string(cred);
- if (flags && *flags) {
- if (!extra_field)
- printf(" ");
- else
- printf(", ");
- printf("Flags: %s", flags);
- extra_field++;
- }
- }
-
- if (extra_field > 2) {
- printf("\r\n");
- extra_field = 0;
- }
-
- if (show_etype) {
- retval = decode_krb5_ticket(&cred->ticket, &tkt);
- if (!extra_field)
- printf(" ");
- else
- printf(", ");
-#ifdef HEIMDAL
- printf("Etype (skey, tkt): %s, %s ",
- etype_string(cred->session.keytype),
- etype_string(tkt->enc_part.keytype));
-#else /* HEIMDAL */
- printf("Etype (skey, tkt): %s, %s ",
- etype_string(cred->keyblock.enctype),
- etype_string(tkt->enc_part.enctype));
-#endif /* HEIMDAL */
- krb5_free_ticket(kcontext, tkt);
- extra_field++;
- }
-
- /* if any additional info was printed, extra_field is non-zero */
- if (extra_field)
- printf("\r\n");
-
- if ( show_addr ) {
- if (!cred->addresses || !cred->addresses[0]) {
- printf("\tAddresses: (none)\r\n");
- } else {
- int i;
- for (i=0; cred->addresses[i]; i++) {
- if (i)
- printf(" ");
- else
- printf(" Addresses: ");
- one_addr(cred->addresses[i]);
- printf("\r\n");
- }
- }
- }
-
- krb5_free_unparsed_name(kcontext,name);
- krb5_free_unparsed_name(kcontext,sname);
-
- krb5_errno = 0;
- makestr(&krb5_errmsg,"OK");
-}
-
-static VOID
-#ifdef CK_ANSIC
-fillit(int num, int c)
-#else
-fillit(num, c) int num; int c;
-#endif
-{
- int i;
-
- for (i=0; i<num; i++)
- printf("%c",c);
-}
-#endif /* KLIST */
-#endif /* KRB5 */
-
-#ifdef KRB4
-#define KDEBUG 1
-int k4debug = 0; /* Kerberos 4 runtime debugging */
-
-#ifdef KINIT
-#define KRB_DEFAULT_LIFE 120 /* 10 hours in 5 minute intervals */
-
-#ifdef SNK4
-/* SNK4 is a hardware authentication system used to pre-authenticate */
-/* a ticket getting ticket. We do not support this code at the present */
-/* time in Kermit. */
-void
-get_input(s, size, stream)
-char *s;
-int size;
-FILE *stream;
-{
- char *p;
-
- if (fgets(s, size, stream) == NULL)
- exit(1);
- if ( (p = strchr(s, '\n')) != NULL)
- *p = '\0';
-}
-#endif /* SNK4 */
-
-#ifdef COMMENT
-static char
-#ifdef CK_ANSIC
-hex_scan_nybble(char c)
-#else
-hex_scan_nybble(c) char c;
-#endif
-{
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- return -1;
-}
-
-/* returns: NULL for ok, pointer to error string for bad input */
-static char*
-#ifdef CK_ANSIC
-hex_scan_four_bytes(char *out, char *in)
-#else
-hex_scan_four_bytes(out, in) char *out; char *in;
-#endif
-{
- int i;
- int c;
- char c1;
- for (i=0; i<8; i++) {
- if(!in[i])
- return "not enough input";
- c = hex_scan_nybble(in[i]);
- if(c<0)
- return "invalid digit";
- c1 = c;
- i++;
- if(!in[i])
- return "not enough input";
- c = hex_scan_nybble(in[i]);
- if(c<0)
- return "invalid digit";
- *out++ = (c1 << 4) + c;
- }
- switch(in[i]) {
- case 0:
- case '\r':
- case '\n':
- return NULL;
- default:
- return "extra characters at end of input";
- }
-}
-#endif /* COMMENT */
-
-/* ck_krb4_initTGT() returns 0 on success */
-int
-#ifdef CK_ANSIC
-ck_krb4_initTGT(struct krb_op_data * op, struct krb4_init_data * init)
-#else
-ck_krb4_initTGT(op,init)
- struct krb_op_data * op, struct krb4_init_data * init
-#endif
-{
- char aname[ANAME_SZ+1];
- char inst[INST_SZ+1];
- char realm[REALM_SZ+1];
- char *password=NULL;
- char passwd[80]="";
- char *username = NULL;
- char *usernameptr=NULL;
- int iflag, /* Instance */
- rflag, /* Realm */
- vflag, /* Verbose */
- lflag, /* Lifetime */
- pflag, /* Preauth */
- lifetime=KRB_DEFAULT_LIFE, /* Life Time */
- k_errno;
- register char *cp;
- register i;
-
- if ( !ck_krb4_is_installed() )
- return(-1);
-
- *inst = *realm = '\0';
- iflag = rflag = vflag = lflag = pflag = 0;
-
- vflag = init->verbose;
- pflag = init->preauth;
-
- if ( init->lifetime ) {
- lifetime = init->lifetime<5?1:init->lifetime/5;
- if ( lifetime > 255 ) lifetime = 255;
- }
- else
- lifetime = KRB_DEFAULT_LIFE;
-
- username = init->principal;
-
- if (username && username[0] &&
- (k_errno = kname_parse(aname, inst, realm, username))
- != AUTH_SUCCESS) {
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- printf("%s\r\n", krb_get_err_text_entry(k_errno));
- iflag = rflag = 1;
- username = NULL;
- }
-
- if ( init->realm ) {
- ckstrncpy(realm,init->realm,REALM_SZ);
- }
-
- if ( init->instance ) {
- ckstrncpy(inst,init->instance, INST_SZ);
- }
-
-#ifdef COMMENT
- if ( vflag )
- printf("Kerberos IV initialization\r\n");
-#endif /* COMMENT */
-
- if (!username || !username[0]) {
- debug(F100,"ck_krb4_initTGT no username specified","",0);
- printf("?Invalid principal specified.\r\n");
- krb4_errno = -1;
- makestr(&krb4_errmsg,"No principal specified");
- return(-1);
- }
- if (!*realm) {
- ckstrncpy(realm,ck_krb4_getrealm(),REALM_SZ);
- }
-
- if ( init->password )
- password = init->password;
- else {
- char prmpt[80];
- int ok;
-
- ckmakxmsg(prmpt,sizeof(prmpt),
- "Kerberos 4 Password for ",username,"@",realm,": ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- ok = uq_txt(NULL,prmpt,2,NULL,passwd,80,NULL,DEFAULT_UQ_TIMEOUT);
- if ( ok )
- password = passwd;
- }
-
- if (pflag) {
- k_errno = krb_get_pw_in_tkt_preauth( aname, inst, realm,
- "krbtgt", realm,
- lifetime,
- password);
- if (k_errno == -1) { /* preauth method not available */
- k_errno = krb_get_pw_in_tkt(aname,
- inst, realm,
- "krbtgt", realm,
- lifetime,
- password);
- }
- } else {
- k_errno = krb_get_pw_in_tkt(aname,
- inst, realm,
- "krbtgt", realm,
- lifetime,
- password);
- }
-
- memset(passwd,0,sizeof(passwd));
- if (k_errno) {
- printf("%s for principal %s%s%s@%s\r\n",
- krb_get_err_text_entry(k_errno), aname,
- inst[0]?".":"", inst, realm);
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(-1);
- } else if (vflag) {
- printf("Result from realm %s: ", realm);
- printf("%s\r\n", krb_get_err_text_entry(k_errno));
- }
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(0);
-}
-#endif /* KINIT */
-#ifdef KDESTROY
-int
-#ifdef CK_ANSIC
-ck_krb4_destroy(struct krb_op_data * op)
-#else
-ck_krb4_destroy(op) struct krb_op_data * op;
-#endif
-{
- int k_errno=0;
-
- if ( !ck_krb4_is_installed() )
- return(-1);
-
- k_errno = dest_tkt();
-
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
-
- if (k_errno == 0)
- printf("Tickets destroyed.\r\n");
- else if (k_errno == RET_TKFIL)
- printf("No tickets to destroy.\r\n");
- else {
- printf("Tickets MAY NOT be destroyed.\r\n");
- return(-1);
- }
- return(0);
-}
-#endif /* KDESTROY */
-#ifdef KLIST
-_PROTOTYP(static int display_tktfile,(char *, int, int, int));
-
-int
-#ifdef CK_ANSIC
-ck_krb4_list_creds(struct krb_op_data * op)
-#else
-ck_krb4_list_creds(op) struct krb_op_data * op;
-#endif
-{
- int long_form = 1;
- int tgt_test = 0;
- int do_srvtab = 0;
- int show_kvnos = 0;
- char *tkt_file = NULL;
-
- if ( !ck_krb4_is_installed() )
- return(-1);
-
- if ( op->cache )
- tkt_file = op->cache;
-
- if ( k4debug ) {
- show_kvnos = 1;
- }
-
- if (do_srvtab)
- return(display_srvtab(tkt_file));
- else
- return(display_tktfile(tkt_file, tgt_test, long_form, show_kvnos));
-}
-
-#ifndef KRB5
-static int timestamp_width=0;
-
-static char *
-#ifdef CK_ANSIC
-short_date(long *dp)
-#else
-short_date(dp) long *dp;
-#endif
-{
- register char *cp;
- extern char *ctime();
- cp = ctime(dp) + 4;
- cp[15] = '\0';
- return (cp);
-}
-
-
-static VOID
-#ifdef CK_ANSIC
-printtime(time_t tv)
-#else
-printtime(tv) time_t tv;
-#endif
-{
- char timestring[BUFSIZ];
- char format[12];
- char fill;
-
- fill = ' ';
- sprintf(format,"%%-%ds",timestamp_width); /* safe */
- printf(format,short_date(&tv));
-}
-#endif /* KRB5 */
-
-static int
-#ifdef CK_ANSIC
-display_tktfile(char *file, int tgt_test, int long_form, int show_kvnos)
-#else
-display_tktfile(file,tgt_test,long_form,show_kvnos)
- char *file; int tgt_test; int long_form; int show_kvnos;
-#endif
-{
- char pname[ANAME_SZ];
- char pinst[INST_SZ];
- char prealm[REALM_SZ];
- char buf1[20], buf2[20];
- int k_errno;
-#ifdef OS2
- LEASH_CREDENTIALS creds;
-#else /* OS2 */
- CREDENTIALS creds;
-#endif /* OS2 */
- int header = 1;
-
- file = tkt_string();
-
- if (long_form) {
- printf("Ticket cache: %s\r\n", file);
- }
-
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file. Otherwise, the error that
- * the user would see would be
- * klist: can't find realm of ticket file: No ticket file (tf_util)
- * instead of
- * klist: No ticket file (tf_util)
- */
-
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- if (!tgt_test)
- printf("%s\r\n", krb_get_err_text_entry (k_errno));
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(-1);
- }
-
-
- /* Close ticket file */
- (void) tf_close();
-
- /*
- * We must find the realm of the ticket file here before calling
- * tf_init because since the realm of the ticket file is not
- * really stored in the principal section of the file, the
- * routine we use must itself call tf_init and tf_close.
- */
- if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
- if (!tgt_test)
- printf("can't find realm of ticket file: %s\r\n",
- krb_get_err_text_entry (k_errno));
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(-1);
- }
-
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- if (!tgt_test)
- printf("%s\r\n", krb_get_err_text_entry (k_errno));
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(-1);
- }
- /* Get principal name and instance */
- if ((k_errno = tf_get_pname(pname)) ||
- (k_errno = tf_get_pinst(pinst))) {
- (void) tf_close();
- if (!tgt_test)
- printf("%s\r\n", krb_get_err_text_entry (k_errno));
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(-1);
- }
-
- /*
- * You may think that this is the obvious place to get the
- * realm of the ticket file, but it can't be done here as the
- * routine to do this must open the ticket file. This is why
- * it was done before tf_init.
- */
-
- if (!tgt_test && long_form)
- printf("Default principal: %s%s%s%s%s\r\n\r\n", pname,
- (pinst[0] ? "." : ""), pinst,
- (prealm[0] ? "@" : ""), prealm);
-
- while ((k_errno = tf_get_cred(&creds)) == AUTH_SUCCESS) {
- if (!tgt_test && long_form && header) {
- printf("%-17s %-17s %s\r\n",
- "Valid starting", "Expires", "Service principal");
- header = 0;
- }
- if (tgt_test) {
- creds.issue_date += ((unsigned char) creds.lifetime) * 5 * 60;
- if (!strcmp(creds.service, "krbtgt") &&
- !strcmp(creds.instance, prealm)) {
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
-
- (void) tf_close();
- if (time(0) < creds.issue_date) {
- return(0); /* tgt hasn't expired */
- } else {
- return(-1); /* has expired */
- }
- }
- continue; /* not a tgt */
- }
- if (long_form) {
- timestamp_width = 17; /* for k5 display function */
- /* if available */
- printtime(creds.issue_date);
- printf(" ");
- creds.issue_date += ((unsigned char) creds.lifetime) * 5 * 60;
- if ( time(0) < creds.issue_date )
- printtime(creds.issue_date);
- else
- printf("*** expired *** ");
- printf(" ");
- }
- if (show_kvnos)
- printf("%s%s%s%s%s (%d)\r\n",
- creds.service, (creds.instance[0] ? "." : ""), creds.instance,
- (creds.realm[0] ? "@" : ""), creds.realm, creds.kvno);
- else
- printf("%s%s%s%s%s\r\n",
- creds.service, (creds.instance[0] ? "." : ""), creds.instance,
- (creds.realm[0] ? "@" : ""), creds.realm);
-
-#ifdef OS2
- if ( creds.address[0] )
- printf(" Address: %s\r\n",creds.address);
-#endif /* OS2 */
- }
-
- (void) tf_close();
-
- if (tgt_test) {
- return(-1);
- }/* no tgt found */
- if (header && long_form && k_errno == EOF) {
- printf("No tickets in file.\r\n");
- }
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(0);
-}
-
-#ifdef COMMENT
-/* Just so we remember what the command line interface looked like */
-usage()
-{
- printf(
- "Usage: [ -s | -t ] [ -file filename ] [ -srvtab ] [ -version ]\r\n");
- return(-1);
-}
-#endif /* COMMENT */
-
-/* adapted from getst() in librkb */
-/*
- * ok_getst() takes a file descriptor, a string and a count. It reads
- * from the file until either it has read "count" characters, or until
- * it reads a null byte. When finished, what has been read exists in
- * the given string "s". If "count" characters were actually read, the
- * last is changed to a null, so the returned string is always null-
- * terminated. ok_getst() returns the number of characters read, including
- * the null terminator.
- *
- * If there is a read error, it returns -1 (like the read(2) system call)
- */
-
-static int
-#ifdef CK_ANSIC
-ok_getst(int fd, register char *s, int n)
-#else
-ok_getst(fd, s, n) int fd; register char *s; int n;
-#endif
-{
- register int count = n;
- int err;
- while ((err = read(fd, s, 1)) > 0 && --count)
- if (*s++ == '\0')
- return (n - count);
- if (err < 0)
- return(-1);
- *s = '\0';
- return (n - count);
-}
-
-int
-#ifdef CK_ANSIC
-display_srvtab(char *file)
-#else
-display_srvtab(file) char *file;
-#endif
-{
- int stab;
- char serv[SNAME_SZ];
- char inst[INST_SZ];
- char rlm[REALM_SZ];
- unsigned char key[8];
- unsigned char vno;
- int count;
-
- printf("Server key file: %s\r\n", file);
-#ifdef NT
-#ifndef O_RDONLY
-#define O_RDONLY _O_RDONLY
-#endif /* O_RDONLY */
-#endif /* NT */
-
- if ((stab = open(file, O_RDONLY, 0400)) < 0) {
- perror(file);
- return(-1);
- }
- printf("%-15s %-15s %-10s %s\r\n","Service","Instance","Realm",
- "Key Version");
- printf("------------------------------------------------------\r\n");
-
- /* argh. getst doesn't return error codes, it silently fails */
- while (((count = ok_getst(stab, serv, SNAME_SZ)) > 0)
- && ((count = ok_getst(stab, inst, INST_SZ)) > 0)
- && ((count = ok_getst(stab, rlm, REALM_SZ)) > 0)) {
- if (((count = read(stab,(char *) &vno,1)) != 1) ||
- ((count = read(stab,(char *) key,8)) != 8)) {
- if (count < 0)
- perror("reading from key file");
- else
- printf("key file truncated\r\n");
- return(-1);
- }
- printf("%-15s %-15s %-15s %d\r\n",serv,inst,rlm,vno);
- }
- if (count < 0)
- perror(file);
- (void) close(stab);
- return(0);
-}
-#endif /* KLIST */
-#else /* KRB4 */
-int
-ck_krb4_autoget_TGT(char * dummy)
-{
- return(-1);
-}
-#ifdef CK_KERBEROS
-int
-#ifdef CK_ANSIC
-ck_krb4_initTGT(struct krb_op_data * op, struct krb4_init_data * init)
-#else
-ck_krb4_initTGT(op,init)
- struct krb_op_data * op, struct krb4_init_data * init
-#endif
-{
- return(-1);
-}
-
-#ifdef CK_ANSIC
-ck_krb4_destroy(struct krb_op_data * op)
-#else
-ck_krb4_destroy(op) struct krb_op_data * op;
-#endif
-{
- return(-1);
-}
-int
-#ifdef CK_ANSIC
-ck_krb4_list_creds(struct krb_op_data * op)
-#else
-ck_krb4_list_creds(op) struct krb_op_data * op;
-#endif
-{
- return(-1);
-}
-#else /* CK_KERBEROS */
-int ck_krb4_initTGT(void * a, void *b)
-{
- return(-1);
-}
-int ck_krb4_destroy(void *a)
-{
- return(-1);
-}
-int ck_krb4_list_creds(void *a)
-{
- return(-1);
-}
-#endif /* CK_KERBEROS */
-#endif /* KRB4 */
-
-/* The following functions are used to implement the Kermit Script Language */
-/* functions */
-
-struct tkt_list_item {
- char * name;
- struct tkt_list_item * next;
-};
-
-static struct tkt_list_item * k4_tkt_list = NULL;
-
-int
-#ifdef CK_ANSIC
-ck_krb4_get_tkts(VOID)
-#else
-ck_krb4_get_tkts()
-#endif
-{
-#ifdef KRB4
- char *file=NULL;
- char pname[ANAME_SZ];
- char pinst[INST_SZ];
- char prealm[REALM_SZ];
- char buf1[20], buf2[20];
- int k_errno;
-#ifdef OS2
- LEASH_CREDENTIALS creds;
-#else /* OS2 */
- CREDENTIALS creds;
-#endif /* OS2 */
- int tkt_count=0;
- struct tkt_list_item ** list = &k4_tkt_list;
-
- while ( k4_tkt_list ) {
- struct tkt_list_item * next;
- next = k4_tkt_list->next;
- free(k4_tkt_list->name);
- free(k4_tkt_list);
- k4_tkt_list = next;
- }
-
- if ( !ck_krb4_is_installed() )
- return(-1);
-
- file = tkt_string();
-
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file. Otherwise, the error that
- * the user would see would be
- * klist: can't find realm of ticket file: No ticket file (tf_util)
- * instead of
- * klist: No ticket file (tf_util)
- */
-
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
-
- /* Close ticket file */
- (void) tf_close();
-
- /*
- * We must find the realm of the ticket file here before calling
- * tf_init because since the realm of the ticket file is not
- * really stored in the principal section of the file, the
- * routine we use must itself call tf_init and tf_close.
- */
- if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
- return(-1);
- }
-
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
- /* Get principal name and instance */
- if ((k_errno = tf_get_pname(pname)) ||
- (k_errno = tf_get_pinst(pinst))) {
- return(-1);
- }
-
- /*
- * You may think that this is the obvious place to get the
- * realm of the ticket file, but it can't be done here as the
- * routine to do this must open the ticket file. This is why
- * it was done before tf_init.
- */
-
- while ((k_errno = tf_get_cred(&creds)) == AUTH_SUCCESS) {
- char tkt_buf[256];
- ckmakxmsg(tkt_buf,sizeof(tkt_buf),
- creds.service, (creds.instance[0] ? "." : ""), creds.instance,
- (creds.realm[0] ? "@" : ""), creds.realm,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- *list = (struct tkt_list_item *) malloc(sizeof(struct tkt_list_item));
- (*list)->name = strdup(tkt_buf);
- (*list)->next = NULL;
- list = &((*list)->next);
- tkt_count++;
- }
-
- tf_close();
- return(tkt_count);
-#else /* KRB4 */
- return(0);
-#endif /* KRB4 */
-}
-
-char *
-#ifdef CK_ANSIC
-ck_krb4_get_next_tkt(VOID)
-#else
-ck_krb4_get_next_tkt()
-#endif
-{
-#ifdef KRB4
- static char * s=NULL;
- struct tkt_list_item * next=NULL;
-
- if ( s ) {
- free(s);
- s = NULL;
- }
-
- if ( k4_tkt_list == NULL )
- return(NULL);
-
- next = k4_tkt_list->next;
- s = k4_tkt_list->name;
- free(k4_tkt_list);
- k4_tkt_list = next;
- return(s);
-#else /* KRB4 */
- return(NULL);
-#endif /* KRB4 */
-}
-
-int
-#ifdef CK_ANSIC
-ck_krb4_tkt_isvalid(char * tktname)
-#else
-ck_krb4_tkt_isvalid(tktname) char * tktname;
-#endif
-{
-#ifdef KRB4
- char *file=NULL;
- char pname[ANAME_SZ];
- char pinst[INST_SZ];
- char prealm[REALM_SZ];
- char buf1[20], buf2[20];
- int k_errno;
- time_t issue_t, expire_t, now_t;
-#ifdef OS2
- LEASH_CREDENTIALS creds;
-#else /* OS2 */
- CREDENTIALS creds;
-#endif /* OS2 */
-
- if ( !ck_krb4_is_installed() )
- return(-1);
-
- debug(F110,"ck_krb4_tkt_isvalid","tkt_string",0);
- file = tkt_string();
-
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file. Otherwise, the error that
- * the user would see would be
- * klist: can't find realm of ticket file: No ticket file (tf_util)
- * instead of
- * klist: No ticket file (tf_util)
- */
-
- /* Open ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_init",0);
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
-
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
-
- /*
- * We must find the realm of the ticket file here before calling
- * tf_init because since the realm of the ticket file is not
- * really stored in the principal section of the file, the
- * routine we use must itself call tf_init and tf_close.
- */
- debug(F110,"ck_krb4_tkt_isvalid","krb_get_tf_realm",0);
- if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
- return(-1);
- }
-
- /* Open ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_init",0);
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
- /* Get principal name and instance */
- debug(F110,"ck_krb4_tkt_isvalid","tf_get_name/tf_get_pinst",0);
- if ((k_errno = tf_get_pname(pname)) ||
- (k_errno = tf_get_pinst(pinst))) {
-
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
-
- return(-1);
- }
-
- /*
- * You may think that this is the obvious place to get the
- * realm of the ticket file, but it can't be done here as the
- * routine to do this must open the ticket file. This is why
- * it was done before tf_init.
- */
-
- debug(F110,"ck_krb4_tkt_isvalid","tf_get_cred",0);
- while ((k_errno = tf_get_cred(&creds)) == AUTH_SUCCESS) {
- char tkt_buf[256];
- ckmakxmsg(tkt_buf,sizeof(tkt_buf),
- creds.service, (creds.instance[0] ? "." : ""), creds.instance,
- (creds.realm[0] ? "@" : ""), creds.realm,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- if ( !strcmp(tktname,tkt_buf) ) {
-
- /* we found the ticket we are looking for */
- issue_t = creds.issue_date;
- expire_t = creds.issue_date
- + ((unsigned char) creds.lifetime) * 5 * 60;
- now_t = time(0);
-
- /* We add a 5 minutes fudge factor to compensate for potential */
- /* clock skew errors between the KDC and K95's host OS */
-
- if ( now_t >= (issue_t-300) && now_t < expire_t) {
-#ifdef OS2
-#ifdef CHECKADDRS
- if ( krb4_checkaddrs ) {
- extern char myipaddr[20]; /* From ckcnet.c */
- if ( !myipaddr[0] ) {
- int i;
- char buf[60];
- for ( i=0;i<64;i++ ) {
- if ( getlocalipaddrs(buf,60,i) < 0 )
- break;
-
- if ( !strcmp(buf,creds.address) ) {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(1); /* They're the same */
- }
- }
-
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(0); /* They're different */
- } else if ( strcmp(myipaddr,creds.address) ) {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(0); /* They're different */
- }
- else {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(1); /* They're the same */
- }
- } else {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(1); /* They're the same */
- }
-#else /* CHECKADDRS */
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(1); /* valid but no ip address check */
-#endif /* CHECKADDRS */
-#else /* OS2 */
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(1); /* Valid but no ip address check */
-#endif /* OS2 */
- }
- else {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(0); /* expired or otherwise invalid */
- }
- }
- }
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(0); /* could not find the desired ticket */
-#else /* KRB4 */
- return(-1);
-#endif /* KRB4 */
-}
-
-int
-#ifdef CK_ANSIC
-ck_krb4_is_tgt_valid(VOID)
-#else
-ck_krb4_is_tgt_valid()
-#endif
-{
-#ifdef KRB4
- char tgt[256];
- char * s;
- int rc = 0;
-
- s = krb4_d_realm ? krb4_d_realm : ck_krb4_getrealm();
- ckmakmsg(tgt,sizeof(tgt),"krbtgt.",s,"@",s);
- rc = ck_krb4_tkt_isvalid(tgt);
- debug(F111,"ck_krb4_is_tgt_valid",tgt,rc);
- return(rc > 0);
-#else /* KRB4 */
- return(0);
-#endif /* KRB4 */
-}
-
-int
-#ifdef CK_ANSIC
-ck_krb4_tkt_time(char * tktname)
-#else
-ck_krb4_tkt_time(tktname) char * tktname;
-#endif
-{
-#ifdef KRB4
- char *file=NULL;
- char pname[ANAME_SZ];
- char pinst[INST_SZ];
- char prealm[REALM_SZ];
- char buf1[20], buf2[20];
- int k_errno;
-#ifdef OS2
- LEASH_CREDENTIALS creds;
-#else /* OS2 */
- CREDENTIALS creds;
-#endif /* OS2 */
-
- if ( !ck_krb4_is_installed() )
- return(-1);
-
- file = tkt_string();
-
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file. Otherwise, the error that
- * the user would see would be
- * klist: can't find realm of ticket file: No ticket file (tf_util)
- * instead of
- * klist: No ticket file (tf_util)
- */
-
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
-
- /* Close ticket file */
- (void) tf_close();
-
- /*
- * We must find the realm of the ticket file here before calling
- * tf_init because since the realm of the ticket file is not
- * really stored in the principal section of the file, the
- * routine we use must itself call tf_init and tf_close.
- */
- if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
- return(-1);
- }
-
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
- /* Get principal name and instance */
- if ((k_errno = tf_get_pname(pname)) ||
- (k_errno = tf_get_pinst(pinst))) {
- tf_close();
- return(-1);
- }
-
- /*
- * You may think that this is the obvious place to get the
- * realm of the ticket file, but it can't be done here as the
- * routine to do this must open the ticket file. This is why
- * it was done before tf_init.
- */
-
- while ((k_errno = tf_get_cred(&creds)) == AUTH_SUCCESS) {
- char tkt_buf[256];
- ckmakxmsg(tkt_buf,sizeof(tkt_buf),
- creds.service, (creds.instance[0] ? "." : ""),
- creds.instance,
- (creds.realm[0] ? "@" : ""), creds.realm,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- if ( !strcmp(tktname,tkt_buf) ) {
- /* we found the ticket we are looking for */
- int n = (creds.issue_date
- + (((unsigned char) creds.lifetime) * 5 * 60))
- - time(0);
- tf_close();
- return(n <= 0 ? 0 : n);
- }
- }
- tf_close();
- return(0); /* could not find the desired ticket */
-#else /* KRB4 */
- return(-1);
-#endif /* KRB4 */
-}
-
-char *
-#ifdef CK_ANSIC
-ck_krb4_getrealm(void)
-#else
-ck_krb4_getrealm()
-#endif
-{
-#ifdef KRB4
- char *file=NULL;
- int k_errno;
- static char realm[256]="";
- realm[0]='\0';
-
- if ( !ck_krb4_is_installed() )
- return(realm);
-
- /* Try to get realm from ticket file */
- /* If failure get the local realm */
-
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file.
- */
-
- /* Open ticket file */
- file = tkt_string();
- if (file == NULL || !file[0])
- return(realm);
-
- if ((k_errno = tf_init(file, R_TKT_FIL)) == KSUCCESS) {
- /* Close ticket file */
- (void) tf_close();
-
- k_errno = krb_get_tf_realm(file, realm);
- }
- if (k_errno != KSUCCESS) {
- k_errno = krb_get_lrealm(realm, 1);
- }
- return(realm);
-#else /* KRB4 */
- return("");
-#endif /* KRB4 */
-}
-
-char *
-#ifdef CK_ANSIC
-ck_krb4_getprincipal(void)
-#else
-ck_krb4_getprincipal()
-#endif
-{
-#ifdef KRB4
- char *file=NULL;
- int k_errno;
- static char principal[256]="";
- char instance[256]="";
- char realm[256]="";
- principal[0]='\0';
-
- if ( !ck_krb4_is_installed() )
- return(principal);
-
- /* Try to get realm from ticket file */
- /* If failure get the local realm */
-
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file.
- */
-
- /* Open ticket file */
- file = tkt_string();
- if (file == NULL || !file[0])
- return(principal);
-
- if ((k_errno = tf_init(file, R_TKT_FIL)) == KSUCCESS) {
- /* Close ticket file */
- (void) tf_close();
-
- k_errno = krb_get_tf_fullname(file, principal, instance, realm);
- }
- return(principal);
-#else /* KRB4 */
- return("");
-#endif /* KRB4 */
-}
-
-static struct tkt_list_item * k5_tkt_list = NULL;
-
-int
-#ifdef CK_ANSIC
-ck_krb5_get_tkts(char * cc_name)
-#else
-ck_krb5_get_tkts(cc_name) char * cc_name;
-#endif
-{
-#ifdef KRB5
-#ifndef HEIMDAL
- krb5_context kcontext;
- krb5_error_code retval;
- krb5_ccache cache = NULL;
- krb5_cc_cursor cur;
- krb5_creds creds;
- krb5_principal princ=NULL;
- krb5_flags flags=0;
- krb5_error_code code=0;
- int exit_status = 0;
-
- int tkt_count=0;
- struct tkt_list_item ** list = &k5_tkt_list;
-
- while ( k5_tkt_list ) {
- struct tkt_list_item * next;
- next = k5_tkt_list->next;
- free(k5_tkt_list->name);
- free(k5_tkt_list);
- k5_tkt_list = next;
- }
-
- if ( !ck_krb5_is_installed() )
- return(-1);
-
- retval = krb5_init_context(&kcontext);
- if (retval) {
- debug(F101,"ck_krb5_get_tkts while initializing krb5","",retval);
- return(-1);
- }
-
- code = k5_get_ccache(kcontext,&cache,cc_name);
- if (code != 0) {
- debug(F111,"ck_krb5_get_tkts while getting ccache",
- error_message(code),code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
-
- flags = 0; /* turns off OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- if (code == ENOENT) {
- debug(F111,"ck_krb5_get_tkts (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- } else {
- debug(F111,
- "ck_krb5_get_tkts while setting cache flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- }
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
- debug(F101,"ck_krb5_get_tkts while retrieving principal name",
- "",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
- debug(F101,"ck_krb5_get_tkts while unparsing principal name",
- "",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
-
- if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_get_tkts while starting to retrieve tickets",
- "",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
-
- while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
- char *sname=NULL;
-
- retval = krb5_unparse_name(kcontext, creds.server, &sname);
- if (retval) {
- debug(F101,
- "ck_krb5_get_tkts while unparsing server name","",retval);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
-
- *list = (struct tkt_list_item *) malloc(sizeof(struct tkt_list_item));
- (*list)->name = sname;
- (*list)->next = NULL;
- list = &((*list)->next);
-
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- tkt_count++;
- }
-
- if (code == KRB5_CC_END) {
- if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_get_tkts while finishing ticket retrieval",
- "",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- debug(F101,"ck_krb5_get_tkts while closing ccache",
- "",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- } else {
- debug(F101,"ck_krb5_get_tkts while retrieving a ticket","",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
-
- exit_k5_get_tkt:
- krb5_free_principal(kcontext,princ);
- krb5_free_unparsed_name(kcontext,defname);
- krb5_cc_close(kcontext,cache);
- krb5_free_context(kcontext);
- return(tkt_count);
-#else /* HEIMDAL */
- return(-1);
-#endif /* HEIMDAL */
-#else /* KRB5 */
- return(0);
-#endif /* KRB5 */
-}
-
-char *
-#ifdef CK_ANSIC
-ck_krb5_get_next_tkt(VOID)
-#else
-ck_krb5_get_next_tkt()
-#endif
-{
-#ifdef KRB5
-#ifndef HEIMDAL
- static char * s=NULL;
- struct tkt_list_item * next=NULL;
-
- if ( s ) {
- free(s);
- s = NULL;
- }
-
- if ( k5_tkt_list == NULL )
- return(NULL);
-
- next = k5_tkt_list->next;
- s = k5_tkt_list->name;
- free(k5_tkt_list);
- k5_tkt_list = next;
- return(s);
-#else /* HEIMDAL */
- return("Not implemented");
-#endif /* HEIMDAL */
-#else /* KRB5 */
- return(NULL);
-#endif /* KRB5 */
-}
-
-char *
-#ifdef CK_ANSIC
-ck_krb5_tkt_flags(char * cc_name, char * tktname)
-#else
-ck_krb5_tkt_flags(cc_name,tktname) char * cc_name; char * tktname;
-#endif
-{
-#ifdef KRB5
-#ifndef HEIMDAL
- krb5_context kcontext;
- krb5_error_code retval;
- krb5_ccache cache = NULL;
- krb5_cc_cursor cur;
- krb5_creds creds;
- krb5_principal princ=NULL;
- krb5_flags flags=0;
- krb5_error_code code=0;
- char * flag_str = "";
-
- if ( !ck_krb5_is_installed() )
- return("");
-
- retval = krb5_init_context(&kcontext);
- if (retval) {
- debug(F101,"ck_krb5_tkt_flags while initializing krb5","",retval);
- return("");
- }
-
- code = k5_get_ccache(kcontext,&cache,cc_name);
- if (code != 0) {
- debug(F111,"ck_krb5_tkt_isvalid while getting ccache",
- error_message(code),code);
- goto exit_k5_get_tkt;
- }
-
- flags = 0; /* turns off OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- if (code == ENOENT) {
- debug(F111,"ck_krb5_tkt_flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- } else {
- debug(F111,
- "ck_krb5_tkt_flags while setting cache flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- }
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
- debug(F101,"ck_krb5_tkt_flags while retrieving principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
- debug(F101,"ck_krb5_tkt_flags while unparsing principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_tkt_flags while starting to retrieve tickets",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- if ((code = krb5_timeofday(kcontext, &now))) {
- if (!status_only)
- debug(F101,"ck_krb5_tkt_flags while getting time of day.",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
- char *sname=NULL;
-
- retval = krb5_unparse_name(kcontext, creds.server, &sname);
- if (retval) {
- debug(F101,
- "ck_krb5_tkt_flags while unparsing server name","",retval);
- retval = -1;
- krb5_free_cred_contents(kcontext, &creds);
- goto exit_k5_get_tkt;
- }
-
- if ( !strcmp(sname,tktname) ) {
- /* we found the ticket we are looking for */
-
- flag_str = flags_string(&creds);
-
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- break;
- }
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- }
-
- if (code == KRB5_CC_END) {
- if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_tkt_flags while finishing ticket retrieval",
- "",code);
- goto exit_k5_get_tkt;
- }
- flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- debug(F101,"ck_krb5_tkt_flags while closing ccache",
- "",code);
- goto exit_k5_get_tkt;
- }
- } else {
- debug(F101,"ck_krb5_tkt_flags while retrieving a ticket","",code);
- goto exit_k5_get_tkt;
- }
-
- exit_k5_get_tkt:
- krb5_free_principal(kcontext,princ);
- krb5_free_unparsed_name(kcontext,defname);
- krb5_cc_close(kcontext,cache);
- krb5_free_context(kcontext);
- return(flag_str);
-#else /* HEIMDAL */
- return("Not implemented");
-#endif /* HEIMDAL */
-#else /* KRB5 */
- return("");
-#endif /* KRB5 */
-}
-
-
-int
-#ifdef CK_ANSIC
-ck_krb5_tkt_isvalid(char * cc_name, char * tktname)
-#else
-ck_krb5_tkt_isvalid(cc_name,tktname) char * cc_name; char * tktname;
-#endif
-{
-#ifdef KRB5
-#ifndef HEIMDAL
- krb5_context kcontext=NULL;
- krb5_error_code retval;
- krb5_ccache cache = NULL;
- krb5_cc_cursor cur;
- krb5_creds creds;
- krb5_principal princ=NULL;
- krb5_flags flags=0;
- krb5_error_code code=0;
-#ifdef CHECKADDRS
- krb5_address ** myAddrs=NULL;
- krb5_address ** p=NULL;
- BOOL Addrfound = FALSE;
-#endif /*CHECKADDRS*/
-
- if ( !ck_krb5_is_installed() )
- return(-1);
-
- retval = krb5_init_context(&kcontext);
- if (retval) {
- debug(F101,"ck_krb5_tkt_isvalid while initializing krb5","",retval);
- return(-1);
- }
-
- code = k5_get_ccache(kcontext,&cache,cc_name);
- if (code != 0) {
- debug(F111,"ck_krb5_tkt_isvalid while getting ccache",
- error_message(code),code);
- goto exit_k5_get_tkt;
- }
-
- flags = 0; /* turns off OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- if (code == ENOENT) {
- debug(F111,"ck_krb5_tkt_isvalid (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- } else {
- debug(F111,
- "ck_krb5_tkt_isvalid while setting cache flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- }
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
- debug(F101,"ck_krb5_tkt_isvalid while retrieving principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
- debug(F101,"ck_krb5_tkt_isvalid while unparsing principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_tkt_isvalid while starting to retrieve tickets",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- if ((code = krb5_timeofday(kcontext, &now))) {
- if (!status_only)
- debug(F101,"ck_krb5_tkt_isvalid while getting time of day.",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
- char *sname=NULL;
-
- retval = krb5_unparse_name(kcontext, creds.server, &sname);
- if (retval) {
- debug(F101,
- "ck_krb5_tkt_isvalid while unparsing server name","",retval);
- retval = -1;
- krb5_free_cred_contents(kcontext, &creds);
- goto exit_k5_get_tkt;
- }
-
- if ( !strcmp(sname,tktname) ) {
- /* we found the ticket we are looking for */
-
- /* We add a 5 minutes fudge factor to compensate for potential */
- /* clock skew errors between the KDC and K95's host OS */
-
- retval = ((creds.times.starttime > 0) &&
- now >= (creds.times.starttime - 300) &&
- now < (creds.times.endtime + 300) &&
- !(creds.ticket_flags & TKT_FLG_INVALID));
-
-#ifdef CHECKADDRS
- if ( retval && krb5_checkaddrs &&
- creds.addresses && creds.addresses[0] ) {
- /* if we think it is valid, then lets check the IP Addresses */
- /* to make sure it is valid for our current connection. */
- /* Also make sure it's for the correct IP address */
- retval = krb5_os_localaddr(kcontext, &myAddrs);
- if (retval) {
- com_err(NULL, retval, "retrieving my IP address");
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- retval = -1;
- break;
- }
-
- /* See if any of our addresses match any in cached credentials */
-
- for (Addrfound=FALSE, p=myAddrs;
- (Addrfound==FALSE) && (*p);
- p++
- ) {
- if (krb5_address_search(kcontext, *p, creds.addresses)) {
- Addrfound = TRUE;
- }
- }
- krb5_free_addresses(k5_context, myAddrs);
-
- if (Addrfound) {
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- retval = 1;
- break;
- } else {
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- retval = 0;
- break;
- }
- }
-#endif /* CHECKADDRS */
-
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- break;
- }
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- }
-
- if (code == KRB5_CC_END) {
- if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_tkt_isvalid while finishing ticket retrieval",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- debug(F101,"ck_krb5_tkt_isvalid while closing ccache",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- } else {
- debug(F101,"ck_krb5_tkt_isvalid while retrieving a ticket","",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- exit_k5_get_tkt:
- krb5_free_principal(kcontext,princ);
- krb5_free_unparsed_name(kcontext,defname);
- krb5_cc_close(kcontext,cache);
- krb5_free_context(kcontext);
- return(retval);
-#else /* HEIMDAL */
- return(-1);
-#endif /* HEIMDAL */
-#else /* KRB5 */
- return(-1);
-#endif /* KRB5 */
-}
-
-int
-#ifdef CK_ANSIC
-ck_krb5_is_tgt_valid(VOID)
-#else
-ck_krb5_is_tgt_valid()
-#endif
-{
-#ifdef KRB5
-#ifndef HEIMDAL
- char tgt[256];
- char * s;
- int rc = 0;
-
- s = ck_krb5_getrealm(krb5_d_cc);
- ckmakmsg(tgt,sizeof(tgt),"krbtgt/",s,"@",s);
- rc = ck_krb5_tkt_isvalid(krb5_d_cc,tgt);
- debug(F111,"ck_krb5_is_tgt_valid",tgt,rc);
- return(rc>0);
-#else /* HEIMDAL */
- return(-1);
-#endif /* HEIMDAL */
-#else /* KRB5 */
- return(0);
-#endif /* KRB5 */
-}
-
-int
-#ifdef CK_ANSIC
-ck_krb5_tkt_time(char * cc_name, char * tktname)
-#else
-ck_krb5_tkt_time(cc_name, tktname) char * cc_name; char * tktname;
-#endif
-{
-#ifdef KRB5
-#ifndef HEIMDAL
- krb5_context kcontext;
- krb5_error_code retval;
- krb5_ccache cache = NULL;
- krb5_cc_cursor cur;
- krb5_creds creds;
- krb5_principal princ=NULL;
- krb5_flags flags=0;
- krb5_error_code code=0;
-
- if ( !ck_krb5_is_installed() )
- return(-1);
-
- retval = krb5_init_context(&kcontext);
- if (retval) {
- debug(F101,"ck_krb5_list_creds while initializing krb5","",retval);
- return(-1);
- }
-
- code = k5_get_ccache(kcontext,&cache,cc_name);
- if (code != 0) {
- debug(F111,"ck_krb5_tkt_time while getting ccache",
- error_message(code),code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- flags = 0; /* turns off OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- if (code == ENOENT) {
- debug(F111,"ck_krb5_list_creds (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- } else {
- debug(F111,
- "ck_krb5_list_creds while setting cache flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- }
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
- debug(F101,"ck_krb5_list_creds while retrieving principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
- debug(F101,"ck_krb5_list_creds while unparsing principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_list_creds while starting to retrieve tickets",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- if ((code = krb5_timeofday(kcontext, &now))) {
- if (!status_only)
- debug(F101,"ck_krb5_list_creds while getting time of day.",
- "",code);
- krb5_free_context(kcontext);
- return(-1);
- }
-
- while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
- char *sname=NULL;
-
- retval = krb5_unparse_name(kcontext, creds.server, &sname);
- if (retval) {
- debug(F101,
- "ck_krb5_list_creds while unparsing server name","",retval);
- retval = -1;
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- goto exit_k5_get_tkt;
- }
-
- if ( !strcmp(sname,tktname) ) {
- /* we found the ticket we are looking for */
- int valid = (creds.times.starttime &&
- now > creds.times.starttime &&
- now < creds.times.endtime &&
- !(creds.ticket_flags & TKT_FLG_INVALID));
- if ( valid ) {
- retval = creds.times.endtime - now;
- }
- else
- retval = 0;
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- break;
- }
- krb5_free_unparsed_name(kcontext,sname);
- krb5_free_cred_contents(kcontext, &creds);
- }
-
- if (code == KRB5_CC_END) {
- if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_list_creds while finishing ticket retrieval",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- debug(F101,"ck_krb5_list_creds while closing ccache",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- } else {
- debug(F101,"ck_krb5_list_creds while retrieving a ticket","",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
-
- exit_k5_get_tkt:
- krb5_free_principal(kcontext,princ);
- krb5_free_unparsed_name(kcontext,defname);
- krb5_cc_close(kcontext,cache);
- krb5_free_context(kcontext);
- return(retval);
-#else /* HEIMDAL */
- return(-1);
-#endif /* HEIMDAL */
-#else /* KRB5 */
- return(-1);
-#endif /* KRB5 */
-}
-
-char *
-#ifdef CK_ANSIC
-ck_krb5_get_cc_name(void)
-#else
-ck_krb5_get_cc_name()
-#endif
-{
-#ifdef KRB5
-#ifndef HEIMDAL
- static char cc_name[CKMAXPATH+1]="";
- krb5_context kcontext = NULL;
- krb5_ccache ccache = NULL;
- krb5_error_code code;
- char * p=NULL;
-
- cc_name[0] = '\0';
-
- if ( !ck_krb5_is_installed() )
- return(cc_name);
-
- p = getenv("KRB5CCNAME");
- if ( !p ) {
- code = krb5_init_context(&kcontext);
- if (code) {
- com_err("ck_krb5_get_cc_name",code,"while init_context");
- return(cc_name);
- }
- if ((code = krb5_cc_default(kcontext, &ccache))) {
- com_err("ck_krb5_get_cc_name",code,"while getting default ccache");
- goto exit_k5_get_cc;
- }
-
- ckmakmsg(cc_name,sizeof(cc_name),
- (char *)krb5_cc_get_type(kcontext,ccache),":",
- (char *)krb5_cc_get_name(kcontext,ccache),NULL);
- } else {
- ckstrncpy(cc_name,p,CKMAXPATH);
- }
-
- if ( !strncmp("FILE:",cc_name,5) ) {
- for ( p=cc_name; *p ; p++ )
- if ( *p == '\\' ) *p = '/';
- }
-
- exit_k5_get_cc:
- if ( ccache )
- krb5_cc_close(kcontext,ccache);
- if ( kcontext )
- krb5_free_context(kcontext);
- return(cc_name);
-#else /* HEIMDAL */
- return("Not implemented");
-#endif /* HEIMDAL */
-#else /* KRB5 */
- return("");
-#endif /* KRB5 */
-}
-
-char *
-#ifdef CK_ANSIC
-ck_krb5_getrealm(char * cc_name)
-#else
-ck_krb5_getrealm(cc_name) char * cc_name;
-#endif
-{
-#ifdef KRB5
-#ifndef HEIMDAL
- static char realm[256]="";
- krb5_context kcontext;
- krb5_ccache ccache = NULL;
- krb5_error_code code;
- krb5_principal me=NULL;
-
- realm[0] = '\0';
-
- if ( !ck_krb5_is_installed() )
- return(realm);
-
- code = krb5_init_context(&kcontext);
- if (code) {
- return(realm);
- }
-
- code = k5_get_ccache(kcontext,&ccache,cc_name);
- if (code != 0) {
- goto exit_k5_getrealm;
- }
-
- code = krb5_cc_get_principal(kcontext, ccache, &me);
- if (code)
- code = krb5_parse_name(kcontext, "foo", &me);
- if (code) {
- goto exit_k5_getrealm;
- }
- if ( krb5_princ_realm(kcontext, me)->length < sizeof(realm) ) {
- memcpy(realm,krb5_princ_realm(kcontext, me)->data,
- krb5_princ_realm(kcontext, me)->length); /* safe */
- realm[krb5_princ_realm(kcontext, me)->length]='\0';
- }
- exit_k5_getrealm:
- if ( me )
- krb5_free_principal(kcontext,me);
- if ( ccache )
- krb5_cc_close(kcontext,ccache);
- if (kcontext)
- krb5_free_context(kcontext);
- return(realm);
-#else /* HEIMDAL */
- return("Not implemented");
-#endif /* HEIMDAL */
-#else /* KRB5 */
- return("");
-#endif /* KRB5 */
-}
-
-char *
-#ifdef CK_ANSIC
-ck_krb5_getprincipal(char * cc_name)
-#else
-ck_krb5_getprincipal(cc_name) char * cc_name;
-#endif
-{
-#ifdef KRB5
-#ifndef HEIMDAL
- static char principal[UIDBUFLEN+1]="";
- krb5_context kcontext;
- krb5_ccache ccache = NULL;
- krb5_error_code code;
- krb5_principal me;
- char * p=NULL;
- int i;
-
- principal[0] = '\0';
-
- if ( !ck_krb5_is_installed() )
- return(principal);
-
- code = krb5_init_context(&kcontext);
- if (code) {
- return(principal);
- }
-
- code = k5_get_ccache(kcontext,&ccache,cc_name);
- if (code != 0) {
- goto exit_k5_getprincipal;
- }
-
- if ((code = krb5_cc_get_principal(kcontext, ccache, &me))) {
- goto exit_k5_getprincipal;
- }
-
- if ((code = krb5_unparse_name (kcontext, me, &p))) {
- krb5_free_principal(kcontext,me);
- goto exit_k5_getprincipal;
- }
-
- ckstrncpy(principal,p,UIDBUFLEN);
- i = ckindex("@",principal,0,0,0);
- if (i)
- principal[i-1] = '\0';
-
- krb5_free_unparsed_name(kcontext,p);
-
- exit_k5_getprincipal:
- if ( ccache )
- krb5_cc_close(kcontext,ccache);
- if (kcontext)
- krb5_free_context(kcontext);
- return(principal);
-#else /* HEIMDAL */
- return("Not implemented");
-#endif /* HEIMDAL */
-#else /* KRB5 */
- return("");
-#endif /* KRB5 */
-}
-
-#ifndef CRYPT_DLL
-int
-ck_get_crypt_table(struct keytab ** pTable, int * pN)
-{
-#ifdef CK_ENCRYPTION
- return(get_crypt_table(pTable, pN));
-#else /* ENCRYPTION */
- int i=0;
-#ifndef OS2
- char * tmpstring = NULL;
-#endif /* OS2 */
-
- if ( *pTable )
- {
- for ( i=0 ; i < *pN ; i++ )
- free( (*pTable)[i].kwd ) ;
- free ( *pTable ) ;
- }
- *pTable = NULL;
- *pN = 0;
-
- *pTable = malloc( sizeof(struct keytab) * 2 ) ;
- if ( !(*pTable) )
- return(0);
-
-#ifdef OS2
- (*pTable)[0].kwd =strdup("automatic");
-#else /* OS2 */
- makestr(&tmpstring,"automatic");
- (*pTable)[0].kwd = tmpstring;
- tmpstring = NULL;
-#endif /* OS2 */
- (*pTable)[0].kwval = ENCTYPE_ANY;
- (*pTable)[0].flgs = 0;
-#ifdef OS2
- (*pTable)[1].kwd =strdup("none");
-#else /* OS2 */
- makestr(&tmpstring,"none");
- (*pTable)[1].kwd = tmpstring;
- tmpstring = NULL;
-#endif /* OS2 */
- (*pTable)[1].kwval = 999;
- (*pTable)[1].flgs = 0;
- (*pN) = 2;
-
- return(2);
-#endif /* ENCRYPTION */
-}
-
-VOID
-ck_encrypt_send_support()
-{
-#ifdef CK_ENCRYPTION
- encrypt_send_support();
-#endif /* ENCRYPTION */
-}
-#endif /* CRYPT_DLL */
-
-/*
- *
- * Kstream
- *
- * Emulates the kstream package in Kerberos 4
- *
- */
-
-int
-kstream_destroy()
-{
- if (g_kstream != NULL) {
- auth_destroy(); /* Destroy authorizing */
- free(g_kstream);
- g_kstream=NULL;
- }
- return 0;
-}
-
-VOID
-#ifdef CK_ANSIC
-kstream_set_buffer_mode(int mode)
-#else
-kstream_set_buffer_mode(mode) int mode;
-#endif
-{
-}
-
-
-int
-#ifdef CK_ANSIC
-kstream_create_from_fd(int fd,
- kstream_ptr data)
-#else
-kstream_create_from_fd(fd,data)
- int fd; kstream_ptr data;
-#endif
-{
- int n;
-
- g_kstream = malloc(sizeof(struct kstream_int));
- if (g_kstream == NULL)
- return 0;
-
- g_kstream->fd = fd;
-
- n = auth_init(g_kstream); /* Initialize authorizing */
- if (n) {
- free(g_kstream);
- g_kstream = NULL;
- return 0;
- }
-
- g_kstream->encrypt = NULL;
- g_kstream->decrypt = NULL;
- g_kstream->encrypt_type = ENCTYPE_ANY;
- g_kstream->decrypt_type = ENCTYPE_ANY;
- return 1;
-}
-
-#ifdef CK_KERBEROS
-#ifdef RLOGCODE
-static int do_lencheck, use_ivecs;
-extern int rlog_inband;
-
-#ifdef KRB5
-void
-rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck, am_client,
- protonum)
- krb5_keyblock *in_keyblock;
- int encrypt_flag;
- int lencheck;
- int am_client;
- enum krb5_kcmd_proto protonum;
-{
- krb5_error_code status;
- size_t blocksize;
-
- if (!encrypt_flag)
- return;
-
- desinbuf.data = des_inbuf;
- desoutbuf.data = des_outpkt+4; /* Set up des buffers */
- k5_session_key = in_keyblock;
-
- do_lencheck = lencheck;
-
- if ( protonum == KCMD_OLD_PROTOCOL ) {
- use_ivecs = 0;
- return;
- }
-
- use_ivecs = 1;
-
- if (status = krb5_c_block_size(k5_context, k5_session_key->enctype,
- &blocksize)) {
- /* XXX what do I do? */
- printf("fatal kerberos 5 crypto library error\n");
- ttclos(0);
- return;
- }
-
- encivec_i[0].length = encivec_i[1].length =
- encivec_o[0].length = encivec_o[1].length = blocksize;
-
- if ((encivec_i[0].data = malloc(encivec_i[0].length * 4)) == NULL) {
- /* XXX what do I do? */
- printf("fatal malloc failed\n");
- ttclos(0);
- return;
- }
-
- encivec_i[1].data = encivec_i[0].data + encivec_i[0].length;
- encivec_o[0].data = encivec_i[1].data + encivec_i[1].length;
- encivec_o[1].data = encivec_o[0].data + encivec_o[0].length;
-
- /* is there a better way to initialize this? */
- memset(encivec_i[0].data, am_client, blocksize);
- memset(encivec_o[0].data, 1 - am_client, blocksize);
- memset(encivec_i[1].data, 2 | am_client, blocksize);
- memset(encivec_o[1].data, 2 | (1 - am_client), blocksize);
-}
-#endif /* KRB5 */
-
-int
-#ifdef CK_ANSIC
-ck_krb_rlogin(CHAR * hostname, int port,
- CHAR * localuser, CHAR * remoteuser, CHAR * term_speed,
- struct sockaddr_in * l_addr, struct sockaddr_in * r_addr,
- int kversion, int encrypt_flag)
-#else /* CK_ANSIC */
-ck_krb_rlogin(hostname, port,
- localuser, remoteuser, term_speed, l_addr, r_addr, encrypt_flag)
- CHAR * hostname; int port;
- CHAR * localuser; CHAR * remoteuser; CHAR * term_speed;
- struct sockaddr_in * l_addr; struct sockaddr_in * r_addr;
- int kversion; int encrypt_flag;
-#endif /* CK_ANSIC */
-{
- unsigned long status;
- char * realm=NULL;
- extern int ttyfd;
- int c;
- long msglen;
-
- debug(F111,"ck_krb_rlogin",hostname,port);
-
- if ( kversion == 4 && !ck_krb4_is_installed() ) {
- printf("?Kerberos 4 is not installed\r\n");
- return(-1);
- } else if ( kversion == 5 && !ck_krb5_is_installed() ) {
- printf("?Kerberos 5 is not installed\r\n");
- return(-1);
- }
-
- if ( encrypt_flag && !ck_crypt_is_installed() ) {
- printf("?Encryption is not installed\r\n");
- return(-1);
- }
-
- if ( kversion == 5 ) {
-#ifdef KRB5
- krb5_flags authopts=0;
- krb5_ccache ccache=NULL;
- char *cksumbuf=NULL;
- char *service=NULL;
- char * kcmd_version=NULL;
- enum krb5_kcmd_proto use_proto;
- krb5_data cksumdat;
- krb5_creds *get_cred = 0;
- krb5_error_code status;
- krb5_error *error = 0;
- krb5_ap_rep_enc_part *rep_ret = NULL;
- krb5_data outbuf;
- int rc;
- krb5_int32 seqno=0;
- krb5_int32 server_seqno=0;
- char ** realmlist=NULL;
- int buflen;
- char tgt[256];
-
- debug(F100,"ck_krb_rlogin version 5","",0);
-
- realm = ck_krb5_realmofhost((char *)hostname);
- if (!realm) {
- ckstrncpy(strTmp, "Can't find realm for host \"",AUTHTMPBL);
- ckstrncat(strTmp, (char *)hostname,AUTHTMPBL);
- ckstrncat(strTmp, "\"",AUTHTMPBL);
- printf("?Kerberos 5 error: %s\r\n",strTmp);
- krb5_errno = KRB5_ERR_HOST_REALM_UNKNOWN;
- makestr(&krb5_errmsg,strTmp);
- return(0);
- }
-
- ckmakmsg(tgt,sizeof(tgt),"krbtgt/",realm,"@",realm);
- debug(F110,"ck_rlog_rlogin TGT",tgt,0);
- if ( krb5_autoget &&
- !((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
- (ck_krb5_is_tgt_valid() > 0)) )
- ck_krb5_autoget_TGT(realm);
-
- buflen = strlen((char *)term_speed) + strlen((char *)remoteuser) + 64;
- if ((cksumbuf = malloc(buflen)) == 0) {
- printf("Unable to allocate memory for checksum buffer.\r\n");
- return(-1);
- }
- ckmakmsg(cksumbuf,buflen,ckuitoa((unsigned short) ntohs(port)),":",
- (char *)term_speed,(char *)remoteuser);
- cksumdat.data = cksumbuf;
- cksumdat.length = strlen(cksumbuf);
-
- status = krb5_init_context(&k5_context);
- if (status) {
- debug(F110,"ck_krb_rlogin()","unable to init_context",0);
- return(-1);
- }
-
- desinbuf.data = des_inbuf;
- desoutbuf.data = des_outpkt+4; /* Set up des buffers */
-
- rc = k5_get_ccache(k5_context,&ccache,NULL);
- if (rc != 0) {
- com_err(NULL, rc, "while getting ccache.");
- return(0);
- }
-
- service = krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME;
-
- if (!(get_cred = (krb5_creds *)calloc(1, sizeof(krb5_creds)))) {
- printf("ck_krb_rlogin: no memory\r\n");
- return(-1);
- }
- memset(get_cred,0,sizeof(krb5_creds));
- status = krb5_sname_to_principal(k5_context, (char *) hostname,
- service, KRB5_NT_SRV_HST,
- &get_cred->server);
- if (status) {
- printf("ck_krb_rlogin: krb5_sname_to_principal failed: %s\r\n",
- error_message(status));
- return(-1);
- }
-
- ttoc(0);
-
- if (status = krb5_cc_get_principal(k5_context,
- ccache,
- &get_cred->client)
- ) {
- (void) krb5_cc_close(k5_context, ccache);
- krb5_free_creds(k5_context, get_cred);
- goto bad;
- }
-
- if (krb5_rlog_ver == KCMD_OLD_PROTOCOL)
- get_cred->keyblock.enctype=ENCTYPE_DES_CBC_CRC;
-
- /* Get ticket from credentials cache or kdc */
- status = krb5_get_credentials(k5_context,
- 0,
- ccache,
- get_cred,
- &ret_cred
- );
- krb5_free_creds(k5_context, get_cred);
- get_cred = NULL;
- (void) krb5_cc_close(k5_context, ccache);
-
- if (status)
- goto bad;
-
- /* Reset internal flags; these should not be set. */
- authopts &= (~OPTS_FORWARD_CREDS);
- authopts &= (~OPTS_FORWARDABLE_CREDS);
-
- if (krb5_auth_con_init(k5_context, &auth_context))
- goto bad;
-
- if (krb5_auth_con_setflags(k5_context, auth_context,
- KRB5_AUTH_CONTEXT_RET_TIME))
- goto bad;
-
- /* Only need local address for mk_cred() to send to krlogind */
- if (!krb5_d_no_addresses)
- if (status = krb5_auth_con_genaddrs(k5_context,
- auth_context,
- ttyfd,
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR
- ))
- goto bad;
-
- /* Here is where we start to handle the new protocol in earnest */
- if ( krb5_rlog_ver == KCMD_PROTOCOL_COMPAT_HACK ) {
- krb5_boolean is_des;
-
- if (status = krb5_c_enctype_compare( k5_context,
- ENCTYPE_DES_CBC_CRC,
-#ifdef HEIMDAL
- ret_cred->session.keytype,
-#else /* HEIMDAL */
- ret_cred->keyblock.enctype,
-#endif /* HEIMDAL */
- &is_des)) {
- krb5_free_creds(k5_context, ret_cred);
- ret_cred = NULL;
- goto bad;
- }
-
- if ( is_des ) {
- kcmd_version = "KCMDV0.1";
- use_proto = KCMD_OLD_PROTOCOL;
- } else {
- authopts = AP_OPTS_USE_SUBKEY;
- kcmd_version = "KCMDV0.2";
- use_proto = KCMD_NEW_PROTOCOL;
- }
- } else {
- use_proto = krb5_rlog_ver;
- switch ( krb5_rlog_ver ) {
- case KCMD_NEW_PROTOCOL:
- authopts = AP_OPTS_USE_SUBKEY;
- kcmd_version = "KCMDV0.2";
- break;
- case KCMD_OLD_PROTOCOL:
- kcmd_version = "KCMDV0.1";
- break;
- default:
- goto bad;
- }
- }
-
- /* call Kerberos library routine to obtain an authenticator,
- pass it over the socket to the server, and obtain mutual
- authentication.
- */
- status = krb5_sendauth(k5_context,
- &auth_context,
- (krb5_pointer) &ttyfd,
- kcmd_version,
- ret_cred->client,
- ret_cred->server,
- authopts,
- &cksumdat,
- ret_cred,
- 0,
- &error,
- &rep_ret,
- NULL
- );
- krb5_free_data_contents(k5_context,&cksumdat);
-
- if (status) {
- if ( !quiet )
- printf("Couldn't authenticate to server: %s\r\n",
- error_message(status));
- if (error) {
- if ( !quiet ) {
- printf("Server returned error code %d (%s)\r\n",
- error->error,
- error_message(ERROR_TABLE_BASE_krb5 + error->error));
- if (error->text.length) {
- printf("Error text sent from server: %s\r\n",
- error->text.data);
- }
- }
- krb5_free_error(k5_context, error);
- error = 0;
- }
- goto bad;
- }
-
- if (rep_ret) {
- server_seqno = rep_ret->seq_number;
- krb5_free_ap_rep_enc_part(k5_context, rep_ret);
- }
-
- (void) ttol(remoteuser, strlen((char *)remoteuser)+1);
- (void) ttol(term_speed, strlen((char *)term_speed)+1);
- (void) ttol(localuser, strlen((char *)localuser)+1);
-
- if (forward_flag) { /* Forward credentials (global) */
- if (status = krb5_fwd_tgt_creds( k5_context,
- auth_context,
- (char *)hostname,
- ret_cred->client,
- ret_cred->server,
- 0,
- (forwardable_flag ?
- OPTS_FORWARDABLE_CREDS :
- 0),
- &outbuf
- )
- )
- {
- printf("Error forwarding credentials: %s\r\n",
- error_message(status));
- goto bad2;
- }
-
- /* Send forwarded credentials */
- status = krb5_write_message(k5_context,
- (krb5_pointer)&ttyfd,
- &outbuf
- );
- }
- else { /* Dummy write to signal no forwarding */
- bad2:
- outbuf.length = 0;
- status = krb5_write_message(k5_context,
- (krb5_pointer)&ttyfd,
- &outbuf);
- }
-
- if ((c = ttinc(0)) < 0) {
- if (c==-1) {
- perror((char *)hostname);
- } else {
- printf("ck_krb_rlogin: bad connection with remote host\r\n");
- }
- status = -1;
- goto bad;
- }
- if (c != 0) {
- while ((c = ttinc(1)) >= 0) {
- (void) printf("%c",c);
- if (c == '\n')
- break;
- }
- status = -1;
- goto bad;
- }
-
- if ( status == 0 ) { /* success */
- krb5_keyblock * key = 0;
-
- if ( use_proto == KCMD_NEW_PROTOCOL ) {
- int on = 1;
- rlog_inband = 1;
- setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,
- (char *) &on, sizeof on);
-
- status = krb5_auth_con_getlocalsubkey( k5_context,
- auth_context,
- &key);
- if ((status || !key) && encrypt_flag )
- goto bad2;
- }
- if ( key == 0 ) {
-#ifdef HEIMDAL
- key = &ret_cred->session;
-#else /* HEIMDAL */
- key = &ret_cred->keyblock;
-#endif /* HEIMDAL */
- }
-
- rcmd_stream_init_krb5(key, encrypt_flag, 1, 1, use_proto);
- if ( encrypt_flag )
- rlog_encrypt = 1;
- }
- return (0); /* success */
-
- bad:
- if ( status && !quiet ) {
- printf("Kerberos authentication error: %s\r\n",
- error_message(status));
- }
- if (ret_cred) {
- krb5_free_creds(k5_context, ret_cred);
- ret_cred = NULL;
- }
- return (status);
-#else /* KRB5 */
- return(-1);
-#endif /* KRB5 */
- } else if (kversion == 4) {
-#ifdef KRB4
- char tgt[4*REALM_SZ+1];
- debug(F100,"ck_krb_rlogin version 4","",0);
-
- realm = (char *)krb_realmofhost(hostname);
- if (!realm) {
- strcpy(strTmp, "Can't find realm for host \"");
- ckstrncat(strTmp, hostname,AUTHTMPBL);
- ckstrncat(strTmp, "\"",AUTHTMPBL);
- printf("?Kerberos 4 error: %s\r\n",strTmp);
- krb4_errno = 0;
- makestr(&krb4_errmsg,strTmp);
- return(0);
- }
-
- ckmakmsg(tgt,sizeof(tgt),"krbtgt.",realm,"@",realm);
- status = ck_krb4_tkt_isvalid(tgt);
-
- if ( status <= 0 && krb4_autoget )
- ck_krb4_autoget_TGT(realm);
-
- ttoc(0); /* write a NUL */
-
- status = krb_sendauth(encrypt_flag?KOPT_DO_MUTUAL:0,
- ttyfd,
- &k4_auth,
- krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
- hostname,
- realm,
- (unsigned long) getpid(),
- &k4_msg_data,
- &cred,
-#ifdef CK_ENCRYPTION
- &k4_sched,
-#else /* ENCRYPTION */
- NULL,
-#endif /* ENCRYPTION */
- l_addr,
- r_addr,
- "KCMDV0.1");
- debug(F111,"ck_krb_rlogin","krb_sendauth",status);
- if (status != KSUCCESS) {
- printf( "krb_sendauth failed: %s\r\n",
- krb_get_err_text_entry(status)
- );
- return(-1);
- }
- ttol(remoteuser,strlen(remoteuser)+1);
- ttol(term_speed,strlen(term_speed)+1);
-
- reread:
- if ((c = ttinc(0)) < 0) {
- printf("rcmd: bad connection with remote host\r\n");
- return(-1);
- }
- debug(F111,"ck_krb_rlogin","first byte",c);
-
- if (c != 0) {
- char *check = "ld.so: warning:";
- /* If rlogind was compiled on SunOS4, and it somehow
- got the shared library version numbers wrong, it
- may give an ld.so warning about an old version of a
- shared library. Just ignore any such warning.
- Note that the warning is a characteristic of the
- server; we may not ourselves be running under
- SunOS4. */
- if (c == 'l') {
- char *p;
- char cc;
-
- p = &check[1];
- while ((c = ttinc(0)) >= 0) {
- if (*p == '\0') {
- if (c == '\n')
- break;
- } else {
- if (c != *p)
- break;
- ++p;
- }
- }
-
- if (*p == '\0')
- goto reread;
- }
-
- printf(check);
- while ((c = ttinc(1)) >= 0) {
- printf("%c",c);
- if (c == '\n')
- break;
- }
- debug(F110,"ck_krb_rlogin","fatal error 1",0);
- return(-1);
- }
-
-#ifdef CK_ENCRYPTION
- if ( encrypt_flag ) {
- /* if we are encrypting we need to setup the encryption */
- /* routines. */
- des_key_sched(cred.session, k4_sched);
- rlog_encrypt = 1;
- }
-#endif /* ENCRYPTION */
-#else /* KRB4 */
- return(-1);
-#endif /* KRB4 */
- }
- return(0); /* success */
-}
-
-#define SRAND srand
-#define RAND rand
-#define RAND_TYPE int
-
-static long
-random_confounder(size, fillin)
-size_t size;
-char * fillin;
-{
- static int seeded = 0;
- register unsigned char *real_fill;
- RAND_TYPE rval;
-
- if (!seeded) {
- /* time() defined in 4.12.2.4, but returns a time_t, which is an
- "arithmetic type" (4.12.1) */
- rval = (RAND_TYPE) time(0);
- SRAND(rval);
- rval = RAND();
- rval ^= getpid();
- SRAND(rval);
- seeded = 1;
- }
-
- real_fill = (unsigned char *)fillin;
- while (size > 0) {
- rval = RAND();
- *real_fill = rval & 0xff;
- real_fill++;
- size--;
- if (size) {
- *real_fill = (rval >> 8) & 0xff;
- real_fill++;
- size--;
- }
- }
- return 0;
-}
-
-#ifdef KRB5
-int
-krb5_des_avail(fd)
- int fd;
-{
- return(nstored);
-}
-
-int
-krb5_des_read(fd, buf, len, secondary)
- int fd;
- register char *buf;
- int len;
- int secondary;
-{
- int nreturned = 0;
- long net_len,rd_len;
- int cc;
- krb5_error_code status;
- unsigned char c;
- krb5_data plain;
- krb5_enc_data cipher;
-
- debug(F111,"krb5_des_read","len",len);
- debug(F111,"krb5_des_read","rlog_encrypt",rlog_encrypt);
- if ( !rlog_encrypt ) {
- cc = net_read(fd, buf, len);
- debug(F111,"krb5_des_read","chars read",cc);
- if ( cc < 0 )
- netclos();
- return(cc);
- }
-
- if (nstored >= len) {
- if ( buf ) {
- memcpy(buf, store_ptr, len); /* safe */
- store_ptr += len;
- nstored -= len;
- return(len);
- } else
- return(0);
- } else if (nstored) {
- if ( buf ) {
- memcpy(buf, store_ptr, nstored); /* safe */
- nreturned += nstored;
- buf += nstored;
- len -= nstored;
- nstored = 0;
- }
- else
- return(0);
- }
-
- /* See the comment in v4_des_read. */
- while (1) {
- cc = net_read(fd, &c, 1);
- /* we should check for non-blocking here, but we'd have
- to make it save partial reads as well. */
- if (cc <= 0) {
- return cc; /* read error */
- }
- if (cc == 1) {
- if (c == 0 || !do_lencheck)
- break;
- }
- }
-
- rd_len = c;
- if ((cc = net_read(fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
- if ((cc = net_read(fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
- if ((cc = net_read(fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
-
- if (status = krb5_c_encrypt_length(k5_context,
- k5_session_key->enctype,
- use_ivecs ? rd_len + 4 : rd_len,
- (size_t *)&net_len)) {
- errno = status;
- return(-1);
- }
-
- if ((net_len <= 0) || (net_len > sizeof(des_inbuf))) {
- /* preposterous length; assume out-of-sync; only
- recourse is to close connection, so return 0 */
- printf("Read size problem.\r\n");
- return(0);
- }
- if ((cc = net_read(fd, desinbuf.data, net_len)) != net_len )
- {
- /* pipe must have closed, return 0 */
- printf( "Read error: length received %d != expected %d.\r\n",
- cc,
- net_len
- );
- return(cc);
- }
-
-
- /* decrypt info */
- cipher.enctype = ENCTYPE_UNKNOWN;
- cipher.ciphertext.length = net_len;
- cipher.ciphertext.data = desinbuf.data;
- plain.length = sizeof(storage);
- plain.data = storage;
-
- if ( status = krb5_c_decrypt(k5_context, k5_session_key, KCMD_KEYUSAGE,
- use_ivecs ? encivec_i + secondary : 0,
- &cipher,&plain) ) {
- /* probably out of sync */
- printf("Cannot decrypt data from network: %s\r\n",
- error_message(status));
- errno = EIO;
- return(-1);
- }
-
- store_ptr = storage;
- nstored = rd_len;
-
- if ( use_ivecs ) {
- int rd_len2;
- rd_len2 = storage[0] & 0xff;
- rd_len2 <<= 8; rd_len2 |= storage[1] & 0xff;
- rd_len2 <<= 8; rd_len2 |= storage[2] & 0xff;
- rd_len2 <<= 8; rd_len2 |= storage[3] & 0xff;
- if (rd_len2 != rd_len) {
- /* cleartext length trashed? */
- errno = EIO;
- return -1;
- }
- store_ptr += 4;
- }
-
- if ( !buf )
- return(0);
-
-#ifdef RLOGCODE /* blah */
- if (rlog_inband && (ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN))
- {
- int i, left, n;
-
- for (i = 0; i < nstored; i++) {
- if (store_ptr[i] == '\377' &&
- store_ptr[i+1] == '\377') {
- left = nstored - i;
- n = rlog_ctrl(&store_ptr[i], left);
- if (n < 0) {
- left -= (-n);
- nstored = left;
- /* flush before, and (-n) bytes */
- if (left > 0)
- memmove(store_ptr, &store_ptr[i-n], left);
- } else if (n) {
- left -= n;
- nstored -= n;
- if (left > 0)
- memmove(store_ptr, &store_ptr[n], left);
- }
- }
- }
- }
-#endif /* RLOGCODE */
-
- if (nstored > len) {
- memcpy(buf, store_ptr, len); /* safe */
- nreturned += len;
- store_ptr += len;
- nstored -= len;
- } else {
- memcpy(buf, store_ptr, nstored); /* safe */
- nreturned += nstored;
- nstored = 0;
- }
- return(nreturned);
-}
-
-int
-krb5_des_write(fd, buf, len, secondary)
- int fd;
- char *buf;
- int len;
- int secondary;
-{
- char tmpbuf[2*RLOG_BUFSIZ+8];
- unsigned char *len_buf = (unsigned char *) tmpbuf;
- krb5_error_code status;
- krb5_data plain;
- krb5_enc_data cipher;
-
- debug(F111,"krb5_des_write","rlog_encrypt",rlog_encrypt);
- if ( !rlog_encrypt ) {
- int cc = net_write(fd, buf, len);
- debug(F111,"net_write","chars written",cc);
- return(cc != len ? -1 : len);
- }
-
- if (use_ivecs) {
- unsigned char *lenbuf2 = (unsigned char *) tmpbuf;
- if (len + 4 > sizeof(tmpbuf))
- abort ();
- lenbuf2[0] = (len & 0xff000000) >> 24;
- lenbuf2[1] = (len & 0xff0000) >> 16;
- lenbuf2[2] = (len & 0xff00) >> 8;
- lenbuf2[3] = (len & 0xff);
- memcpy (tmpbuf + 4, buf, len);
-
- plain.data = tmpbuf;
- plain.length = len + 4;
- } else {
- plain.data = buf;
- plain.length = len;
- }
-
- cipher.ciphertext.length = sizeof(des_outpkt)-4;
- cipher.ciphertext.data = desoutbuf.data;
-
- if ( status = krb5_c_encrypt(k5_context, k5_session_key, KCMD_KEYUSAGE,
- use_ivecs ? encivec_o + secondary : 0,
- &plain, &cipher)) {
- printf("Write encrypt problem: %s.\r\n",
- error_message(status));
- errno = EIO;
- return(-1);
- }
- desoutbuf.length = cipher.ciphertext.length;
-
- len_buf = (unsigned char *) des_outpkt;
- len_buf[0] = (len & 0xff000000) >> 24;
- len_buf[1] = (len & 0xff0000) >> 16;
- len_buf[2] = (len & 0xff00) >> 8;
- len_buf[3] = (len & 0xff);
-
- if (net_write(fd, des_outpkt,desoutbuf.length+4)
- != desoutbuf.length+4){
- printf("Could not write out all data\r\n");
- return(-1);
- }
- else return(len);
-}
-#endif /* KRB5 */
-
-#ifdef KRB4
-/*
- * Note that the encrypted rlogin packets take the form of a four-byte
- * length followed by encrypted data. On writing the data out, a significant
- * performance penalty is suffered (at least one RTT per character, two if we
- * are waiting for a shell to echo) by writing the data separately from the
- * length. So, unlike the input buffer, which just contains the output
- * data, the output buffer represents the entire packet.
- */
-
-int
-krb4_des_avail(fd)
- int fd;
-{
- return(nstored);
-}
-
-int
-krb4_des_read(fd, buf, len)
-int fd;
-register char *buf;
-int len;
-{
- int nreturned = 0;
- unsigned long net_len, rd_len;
- int cc;
- unsigned char c;
- int gotzero = 0;
-
- debug(F111,"krb4_des_read","rlog_encrypt",rlog_encrypt);
- debug(F111,"krb4_des_read","len",len);
- if ( !rlog_encrypt ) {
- cc = net_read(fd, buf, len);
- debug(F111,"krb4_des_read","chars read",cc);
- if ( cc < 0 )
- netclos();
- return(cc);
- }
-
- if (nstored >= len) {
- if ( buf ) {
- debug(F111,"krb4_des_read (nstored >= len)","nstored",nstored);
- memcpy(buf, store_ptr, len); /* safe */
- store_ptr += len;
- nstored -= len;
- return(len);
- } else
- return(0);
- } else if (nstored) {
- if ( buf ) {
- debug(F111,"krb4_des_read (nstored)","nstored",nstored);
- memcpy(buf, store_ptr, nstored); /* safe */
- nreturned += nstored;
- buf += nstored;
- len -= nstored;
- nstored = 0;
- } else
- return(0);
- }
-
- /* We're fetching the length which is MSB first, and the MSB
- has to be zero unless the client is sending more than 2^24
- (16M) bytes in a single write (which is why this code is in
- rlogin but not rcp or rsh.) The only reasons we'd get something
- other than zero are:
- -- corruption of the tcp stream (which will show up when
- everything else is out of sync too)
- -- un-caught Berkeley-style "pseudo out-of-band data" which
- happens any time the user hits ^C twice.
- The latter is *very* common, as shown by an 'rlogin -x -d'
- using the CNS V4 rlogin. Mark EIchin 1/95
- */
- debug(F110,"krb4_des_read",
- "about to call net_read() this will block",
- 0
- );
- do {
- cc = net_read(fd, &c, 1);
- debug(F111,"net_read","chars read",cc);
- if (cc <= 0) {
- netclos();
- return(-1);
- }
- if (cc != 1) return 0; /* read error */
- if (cc == 1) {
- if (c == 0) gotzero = 1;
- }
- } while (!gotzero);
-
- debug(F110,"krb4_des_read","gotzero",0);
- cc = net_read(fd, &c, 1);
- debug(F111,"net_read","chars read",cc);
- if (cc < 0) {
- netclos();
- return(-1);
- } else if ( cc != 1 )
- return(0);
- net_len = c;
- cc = net_read(fd, &c, 1);
- debug(F111,"net_read","chars read",cc);
- if (cc < 0) {
- netclos();
- return(-1);
- } else if ( cc != 1 )
- return(0);
- net_len = (net_len << 8) | c;
- debug(F111,"net_read","chars read",cc);
- cc = net_read(fd, &c, 1);
- if (cc < 0) {
- netclos();
- return(-1);
- } else if ( cc != 1 )
- return(0);
- net_len = (net_len << 8) | c;
- debug(F111,"krb4_des_read","net_len",net_len);
-
- /* Note: net_len is unsigned */
- if (net_len > sizeof(des_inbuf)) {
- /* XXX preposterous length, probably out of sync.
- act as if pipe closed */
- return(0);
- }
- /* the writer tells us how much real data we are getting, but
- we need to read the pad bytes (8-byte boundary) */
-#ifndef roundup
-#define roundup(x,y) ((((x)+(y)-1)/(y))*(y))
-#endif /* roundup */
- rd_len = roundup(net_len, 8);
- debug(F111,"krb4_des_read","rd_len",rd_len);
- cc = net_read(fd, des_inbuf, rd_len);
- debug(F111,"net_read","chars read",cc);
- if (cc < 0) {
- netclos();
- return(-1);
- } else if ( cc != rd_len )
- return(0);
-
- ckhexdump("krb4_des_read des_inbuf",des_inbuf,8);
-#ifdef CK_ENCRYPTION
-#ifdef KRB524
- (void) des_pcbc_encrypt(des_inbuf,
- storage,
- (net_len < 8) ? 8 : net_len,
- k4_sched,
- cred.session,
- DECRYPT);
-#else /* KRB524 */
- (void) des_pcbc_encrypt((Block *)des_inbuf,
- (Block *)storage,
- (net_len < 8) ? 8 : net_len,
- k4_sched,
- &cred.session,
- DECRYPT);
-#endif /* KRB524 */
-#endif /* ENCRYPTION */
- ckhexdump("krb4_des_read storage",storage,8);
-
- /*
- * when the cleartext block is < 8 bytes, it is "right-justified"
- * in the block, so we need to adjust the pointer to the data
- */
- if (net_len < 8)
- store_ptr = storage + 8 - net_len;
- else
- store_ptr = storage;
- nstored = net_len;
-
- if ( !buf )
- return(0);
-
- if (nstored > len) {
- memcpy(buf, store_ptr, len); /* safe */
- nreturned += len;
- store_ptr += len;
- nstored -= len;
- } else {
- memcpy(buf, store_ptr, nstored); /* safe */
- nreturned += nstored;
- nstored = 0;
- }
-
- debug(F111,"net_read","nreturned",nreturned);
- return(nreturned);
-}
-
-int
-krb4_des_write(fd, buf, len)
-int fd;
-char *buf;
-int len;
-{
- static char garbage_buf[8];
- unsigned char *len_buf = (unsigned char *) des_outpkt;
- int cc;
-
- debug(F111,"krb4_des_write","rlog_encrypt",rlog_encrypt);
- if ( !rlog_encrypt ) {
- cc = net_write(fd, buf, len);
- debug(F111,"net_write","chars written",cc);
- return(cc);
- }
-
- /*
- * pcbc_encrypt outputs in 8-byte (64 bit) increments
- *
- * it zero-fills the cleartext to 8-byte padding,
- * so if we have cleartext of < 8 bytes, we want
- * to insert random garbage before it so that the ciphertext
- * differs for each transmission of the same cleartext.
- * if len < 8 - sizeof(long), sizeof(long) bytes of random
- * garbage should be sufficient; leave the rest as-is in the buffer.
- * if len > 8 - sizeof(long), just garbage fill the rest.
- */
- if (len < 8) {
- random_confounder(8 - len, garbage_buf);
- /* this "right-justifies" the data in the buffer */
- (void) memcpy(garbage_buf + 8 - len, buf, len); /* safe */
- ckhexdump("krb4_des_write garbage_buf",garbage_buf,8);
- } else
- ckhexdump("krb4_des_write buf",buf,8);
-#ifdef CK_ENCRYPTION
-#ifdef KRB524
- (void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf,
- des_outpkt+4,
- (len < 8) ? 8 : len,
- k4_sched,
- cred.session,
- ENCRYPT);
-#else /* KRB524 */
- (void) des_pcbc_encrypt((Block *)((len < 8) ? garbage_buf : buf),
- (Block *)(des_outpkt+4),
- (len < 8) ? 8 : len,
- k4_sched,
- &cred.session,
- ENCRYPT);
-#endif /* KRB524 */
-#endif /* ENCRYPTION */
- if ( len < 8 )
- ckhexdump("krb4_des_write (post pcbc) garbage_buf",garbage_buf,8);
- else
- ckhexdump("krb4_des_write (post pcbc) buf",buf,8);
- ckhexdump("krb4_des_write (des_outpkt+4)",(des_outpkt+4),8);
-
- /* tell the other end the real amount, but send an 8-byte padded
- packet */
- len_buf[0] = (len & 0xff000000) >> 24;
- len_buf[1] = (len & 0xff0000) >> 16;
- len_buf[2] = (len & 0xff00) >> 8;
- len_buf[3] = (len & 0xff);
- ckhexdump("krb4_des_write des_outpkt len",des_outpkt,12);
- cc = net_write(fd, des_outpkt, roundup(len,8)+4);
- debug(F111,"net_write","chars written",cc);
- return(len);
-}
-#endif /* KRB4 */
-#endif /* RLOGCODE */
-
-#ifdef KRB524
-#ifndef OS2
-/* The following functions are missing from the compatibility library */
-const char *
-krb_get_err_text_entry(r) int r;
-{
- extern char krb_err_text[];
- return(krb_err_txt[r]);
-}
-#endif /* OS2 */
-#endif /* KRB524 */
-#endif /* CK_KERBEROS */
-
-#ifdef CK_KERBEROS
-#ifdef KRB5_U2U
-/* Kerberos 5 User to User Client */
-int
-k5_user_to_user_client_auth()
-{
- extern int ttyfd;
- register int retval, i;
- char **srealms; /* realm(s) of server */
- char *princ; /* principal in credentials cache */
- krb5_ccache cc;
- krb5_creds creds, *new_creds;
- krb5_data reply, msg, msgtext, princ_data;
- krb5_ticket * ticket = NULL;
-
- if (retval = k5_get_ccache(k5_context,&cc,NULL))
- {
- com_err("uu-client", retval, "getting credentials cache");
- return(-1);
- }
-
- memset ((char*)&creds, 0, sizeof(creds));
- if (retval = krb5_cc_get_principal(k5_context, cc, &creds.client))
- {
- com_err("uu-client", retval, "getting principal name");
- return(-1);
- }
-
- if (retval = krb5_get_host_realm(k5_context, szHostName, &srealms))
- {
- com_err("uu-client", retval, "getting realms for \"%s\"", szHostName);
- return(-1);
- }
-
- if (retval = krb5_build_principal_ext(k5_context, &creds.server,
- krb5_princ_realm(k5_context,
- creds.client)->length,
- krb5_princ_realm(k5_context,
- creds.client)->data,
- 6, "krbtgt",
- krb5_princ_realm(k5_context,
- creds.client)->length,
- krb5_princ_realm(k5_context,
- creds.client)->data,
- 0))
- {
- com_err("uu-client", retval, "setting up tgt server name");
- return(-1);
- }
-
- /* Get TGT from credentials cache */
- if (retval = krb5_get_credentials(k5_context, KRB5_GC_CACHED, cc,
- &creds, &new_creds))
- {
- com_err("uu-client", retval, "getting TGT");
- return(-1);
- }
-
- if (retval = krb5_unparse_name(k5_context, creds.client, &princ)) {
- com_err("uu-client", retval, "printing principal name");
- return(-1);
- }
- i = strlen(princ) + 1;
- princ_data.data = princ;
- princ_data.length = i; /* include null terminator for
- server's convenience */
- retval = krb5_write_message(k5_context,
- (krb5_pointer) &ttyfd, &princ_data);
- if (retval)
- {
- com_err("uu-client", retval, "sending principal name to server");
- return(-1);
- }
- krb5_free_unparsed_name(k5_context,princ);
-
- retval = krb5_write_message(k5_context,
- (krb5_pointer) &ttyfd, &new_creds->ticket);
- if (retval)
- {
- com_err("uu-client", retval, "sending ticket to server");
- return(-1);
- }
-
- retval = krb5_read_message(k5_context, (krb5_pointer) &ttyfd, &reply);
- if (retval)
- {
- com_err("uu-client", retval, "reading reply from server");
- return(-1);
- }
-
- if (retval = krb5_auth_con_init(k5_context, &auth_context)) {
- com_err("uu-client", retval, "initializing the auth_context");
- return(-1);
- }
-
- if (!krb5_d_no_addresses) {
- if (retval = krb5_auth_con_genaddrs(k5_context, auth_context, ttyfd,
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR |
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) {
- com_err("uu-client", retval, "generating addrs for auth_context");
- return(-1);
- }
- }
-
- if (retval = krb5_auth_con_setflags(k5_context, auth_context,
- KRB5_AUTH_CONTEXT_DO_SEQUENCE)) {
- com_err("uu-client", retval, "initializing the auth_context flags");
- return(-1);
- }
-
- if (retval = krb5_auth_con_setuseruserkey(k5_context, auth_context,
- &new_creds->keyblock)) {
- com_err("uu-client", retval, "setting useruserkey for authcontext");
- return(-1);
- }
-
- /* read the ap_req to get the session key */
- retval = krb5_rd_req(k5_context, &auth_context, &reply,
- NULL, NULL, NULL, &ticket);
- if (retval) {
- com_err("uu-client", retval, "reading AP_REQ from server");
- return(-1);
- }
-
- if (k5_u2u_read_msg(k5_context,&msg) < 0)
- return(-1);
-
- if ( strcmp("Kermit implements Kerberos 5 User to User",msg.data) )
- return(-1);
- krb5_free_data_contents(k5_context,&msg);
-
- msgtext.data = "As do I! :-)";
- msgtext.length = strlen(msgtext.data)+1;
-
- if (k5_u2u_write_msg(k5_context,&msgtext) < 0)
- return(-1);
-
- if (retval = krb5_unparse_name(k5_context,
-#ifdef HEIMDAL
- ticket->client,
-#else /* HEIMDAL */
- ticket->enc_part2->client,
-#endif /* HEIMDAL */
- &princ))
- com_err("uu-client", retval, "while unparsing client name");
- else {
- ckstrncpy(szUserNameAuthenticated,princ,UIDBUFLEN);
- validUser = AUTH_VALID;
- authentication_version = AUTHTYPE_KERBEROS_V5;
- if ( !quiet )
- printf("Peer name is \"%s\"\n", princ);
- krb5_free_unparsed_name(k5_context,princ);
- }
- return 0;
-}
-
-/* Kerberos 5 User to User Server */
-
-int
-k5_user_to_user_server_auth()
-{
- krb5_data pname_data, tkt_data;
- int retval;
- krb5_creds creds, *new_creds;
- krb5_ccache cc;
- krb5_data msg, msgtext;
- extern int ttyfd;
-
- if (retval = krb5_read_message(k5_context,
- (krb5_pointer) &ttyfd, &pname_data)) {
- com_err ("uu-server", retval, "reading pname");
- return(-1);
- }
- /* client sends it already null-terminated. */
- if ( !quiet )
- printf ("Peer name is \"%s\".\n", pname_data.data);
- ckstrncpy(szUserNameAuthenticated,pname_data.data,UIDBUFLEN);
- validUser = AUTH_VALID;
- authentication_version = AUTHTYPE_KERBEROS_V5;
-
- if (retval = krb5_read_message(k5_context,
- (krb5_pointer) &ttyfd, &tkt_data)) {
- com_err ("uu-server", retval, "reading ticket data");
- return(-1);
- }
-
- if (retval = k5_get_ccache(k5_context,&cc,NULL))
- {
- com_err("uu-server", retval, "getting credentials cache");
- return(-1);
- }
-
- memset ((char*)&creds, 0, sizeof(creds));
- if (retval = krb5_cc_get_principal(k5_context, cc, &creds.client))
- {
- com_err("uu-server", retval, "getting principal name");
- return(-1);
- }
-
- if (retval = krb5_parse_name(k5_context, pname_data.data, &creds.server))
- {
- com_err("uu-server", retval, "parsing client name");
- return(-1);
- }
- creds.second_ticket = tkt_data;
-
- if (retval = krb5_get_credentials(k5_context, KRB5_GC_USER_USER,
- cc, &creds, &new_creds))
- {
- com_err("uu-server", retval, "getting user-user ticket");
- return(-1);
- }
-
- /* send a ticket/authenticator to the other side, so it can get the key
- we're using for the krb_safe below. */
-
- if (retval = krb5_auth_con_init(k5_context, &auth_context)) {
- com_err("uu-server", retval, "making auth_context");
- return(-1);
- }
-
- if (retval = krb5_auth_con_setflags(k5_context, auth_context,
- KRB5_AUTH_CONTEXT_DO_SEQUENCE)) {
- com_err("uu-server", retval, "initializing the auth_context flags");
- return(-1);
- }
-
- if (!krb5_d_no_addresses) {
- if (retval = krb5_auth_con_genaddrs(k5_context, auth_context, ttyfd,
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR |
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) {
- com_err("uu-server", retval, "generating addrs for auth_context");
- return(-1);
- }
- }
-
- if (retval = krb5_auth_con_setuseruserkey(k5_context, auth_context,
- &new_creds->keyblock)) {
- com_err("uu-server", retval, "setting useruserkey for authcontext");
- return(-1);
- }
-
- if (retval = krb5_mk_req_extended(k5_context, &auth_context,
- AP_OPTS_USE_SESSION_KEY |
- AP_OPTS_MUTUAL_REQUIRED,
- NULL, new_creds, &msg)) {
- com_err("uu-server", retval, "making AP_REQ");
- return(-1);
- }
- retval = krb5_write_message(k5_context, (krb5_pointer) &ttyfd, &msg);
- if (retval) {
- com_err("uu-server", retval, "writing message to client");
- return(-1);
- }
- krb5_free_data_contents(k5_context,&msg);
-
- msgtext.data = "Kermit implements Kerberos 5 User to User";
- msgtext.length = strlen(msgtext.data)+1;
-
- if (k5_u2u_write_msg(k5_context,&msgtext) < 0)
- return(-1);
-
- if (k5_u2u_read_msg(k5_context,&msg) < 0)
- return(-1);
-
- if ( strcmp("As do I! :-)",msg.data) )
- return(-1);
- krb5_free_data_contents(k5_context,&msg);
-
-
- return(0);
-}
-
-int
-k5_u2u_read_msg(krb5_context context, int fd, krb5_data * msg)
-{
- int retval;
- krb5_data reply;
-
- retval = krb5_read_message(context, (krb5_pointer) &fd, &reply);
- if (retval)
- {
- com_err("uu-client", retval, "reading reply");
- return(-1);
- }
-
- if (retval = krb5_rd_priv(context, auth_context, &reply, msg, NULL)) {
- com_err("uu-client", retval, "decoding reply");
- return(-1);
- }
- return(0);
-}
-
-int
-k5_u2u_write_msg(krb5_context context, int fd, krb5_data * msgtext)
-{
- int retval;
- krb5_data msg;
-
- if (retval = krb5_mk_priv(k5_context, auth_context, msgtext, &msg, NULL))
- {
- com_err("uu-server", retval, "encoding message");
- return(-1);
- }
-
- retval = krb5_write_message(k5_context, (krb5_pointer) &fd, &msg);
- krb5_free_data_contents(k5_context,&msg);
- if (retval)
- {
- com_err("uu-server", retval, "writing message");
- return(-1);
- }
- return(0);
-}
-
-int
-krb5_u2u_avail(fd)
- int fd;
-{
- return(nstored);
-}
-
-int
-krb5_u2u_read(fd, buf, len)
- int fd;
- register char *buf;
- int len;
-{
- int nreturned = 0;
- krb5_data msg;
-
- debug(F111,"krb5_u2u_read","len",len);
-
- if ( !buf )
- return(0);
-
- if (nstored >= len) {
- memcpy(buf, store_ptr, len); /* safe */
- store_ptr += len;
- nstored -= len;
- return(len);
- } else if (nstored) {
- memcpy(buf, store_ptr, nstored); /* safe */
- nreturned += nstored;
- buf += nstored;
- len -= nstored;
- nstored = 0;
- }
-
- if (k5_u2u_read_msg(k5_context, fd, &msg) < 0)
- return(-1);
-
- if ( msg.length <= len ) {
- memcpy(buf, msg.data, msg.length);
- nreturned += msg.length;
- nstored = 0;
- } else {
- memcpy(buf, msg.data, len);
- nreturned += len;
-
- if ( msg.length - len < sizeof(storage) ) {
- store_ptr = storage;
- nstored = msg.length - len;
- memcpy(storage,msg.data+len,nstored);
- } else {
- nstored = 0;
- return(-1);
- }
- }
- return(nreturned);
-}
-
-int
-krb5_u2u_write(fd, buf, len)
- int fd;
- char *buf;
- int len;
-{
- krb5_data msg;
-
- msg.length = len;
- msg.data = buf;
-
- if ( k5_u2u_write_msg(k5_context, fd, &msg) < 0 )
- return(-1);
- else
- return(len);
-}
-
-#endif /* KRB5_U2U */
-#endif /* CK_KERBEROS */
-
-#ifdef CK_FORWARD_X
-/*
-
-Copyright (c) 1988 X Consortium
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from the X Consortium.
-
-*/
-/* Modified for stand-alone compiling by
- * Peter 'Luna' Runestig <peter@runestig.com>
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <time.h>
-#define Time_t time_t
-
-void
-XauDisposeAuth (auth)
-Xauth *auth;
-{
- if (auth) {
- if (auth->address) (void) free (auth->address);
- if (auth->number) (void) free (auth->number);
- if (auth->name) (void) free (auth->name);
- if (auth->data) {
- (void) bzero (auth->data, auth->data_length);
- (void) free (auth->data);
- }
- free ((char *) auth);
- }
- return;
-}
-
-char *
-XauFileName ()
-{
- char *slashDotXauthority = "/.Xauthority";
- char *name;
- static char *buf=NULL;
- static int bsize=0;
- int size, namelen;
- extern char * tn_fwdx_xauthority;
-
- if ( tn_fwdx_xauthority )
- return(tn_fwdx_xauthority);
-
- if (name = getenv ("XAUTHORITY"))
- return(name);
- name = zhome();
- if ( !name )
- return(NULL);
- namelen = strlen (name);
- size = namelen + strlen(slashDotXauthority) + 1;
- if (size > bsize) {
- if (buf)
- free (buf);
- buf = malloc ((unsigned) size);
- if (!buf)
- return 0;
- bsize = size;
- }
- ckstrncpy (buf, name, bsize);
- if ( name[namelen-1] != '/'
-#ifdef OS2
- && name[namelen-1] != '\\'
-#endif /* OS2 */
- )
- ckstrncat (buf, slashDotXauthority, bsize);
- else
- ckstrncat (buf, &slashDotXauthority[1], bsize);
- return(buf);
-}
-
-static int
-binaryEqual (a, b, len)
-register char *a, *b;
-register int len;
-{
- while (len--)
- if (*a++ != *b++)
- return 0;
- return 1;
-}
-
-#ifndef R_OK
-#define R_OK 04
-#endif /* R_OK */
-
-Xauth *
-XauGetAuthByAddr (family, address_length, address,
- number_length, number,
- name_length, name)
-unsigned int family;
-unsigned int address_length;
-const char *address;
-unsigned int number_length;
-const char *number;
-unsigned int name_length;
-const char *name;
-{
- FILE *auth_file;
- char *auth_name;
- Xauth *entry;
-
- auth_name = XauFileName();
- if (!auth_name)
- return 0;
- if (access (auth_name, R_OK) != 0) /* checks REAL id */
- return 0;
- auth_file = fopen (auth_name, "rb");
- if (!auth_file)
- return 0;
- for (;;) {
- entry = XauReadAuth (auth_file);
- if (!entry)
- break;
- /*
- * Match when:
- * either family or entry->family are FamilyWild or
- * family and entry->family are the same
- * and
- * either address or entry->address are empty or
- * address and entry->address are the same
- * and
- * either number or entry->number are empty or
- * number and entry->number are the same
- * and
- * either name or entry->name are empty or
- * name and entry->name are the same
- */
-
-/* if ((family == FamilyWild || entry->family == FamilyWild ||
- (entry->family == family &&
- address_length == entry->address_length &&
- binaryEqual (entry->address, address, (int)address_length))) &&
- (number_length == 0 || entry->number_length == 0 ||
- (number_length == entry->number_length &&
- binaryEqual (entry->number, number, (int)number_length))) &&
- (name_length == 0 || entry->name_length == 0 ||
- (entry->name_length == name_length &&
- binaryEqual (entry->name, name, (int)name_length)))) */
- /* the original matching code above doesn't seem to meet the matching
- * algorithm, it doesn't check if "address_length == 0 ||
- * entry->address_length == 0". / Luna 2000-02-09
- */
- if ((family == FamilyWild || entry->family == FamilyWild ||
- entry->family == family) &&
- (address_length == 0 || entry->address_length == 0 ||
- (address_length == entry->address_length &&
- binaryEqual (entry->address, address, (int)address_length))) &&
- (number_length == 0 || entry->number_length == 0 ||
- (number_length == entry->number_length &&
- binaryEqual (entry->number, number, (int)number_length))) &&
- (name_length == 0 || entry->name_length == 0 ||
- (entry->name_length == name_length &&
- binaryEqual (entry->name, name, (int)name_length))))
- break;
- XauDisposeAuth (entry);
- }
- (void) fclose (auth_file);
- return entry;
-}
-
-static int
-read_short (shortp, file)
-unsigned short *shortp;
-FILE *file;
-{
- unsigned char file_short[2];
-
- if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
- return 0;
- *shortp = file_short[0] * 256 + file_short[1];
- return 1;
-}
-
-static int
-read_counted_string (countp, stringp, file)
-unsigned short *countp;
-char **stringp;
-FILE *file;
-{
- unsigned short len;
- char *data;
-
- if (read_short (&len, file) == 0)
- return 0;
- if (len == 0) {
- data = 0;
- } else {
- data = malloc ((unsigned) len);
- if (!data)
- return 0;
- if (fread (data, (int) sizeof (char), (int) len, file) != len) {
- bzero (data, len);
- free (data);
- return 0;
- }
- }
- *stringp = data;
- *countp = len;
- return 1;
-}
-
-Xauth *
-XauReadAuth (auth_file)
-FILE *auth_file;
-{
- Xauth local;
- Xauth *ret;
-
- if (read_short (&local.family, auth_file) == 0)
- return 0;
- if (read_counted_string (&local.address_length,
- &local.address, auth_file) == 0)
- return 0;
- if (read_counted_string (&local.number_length,
- &local.number, auth_file) == 0) {
- if (local.address) free (local.address);
- return 0;
- }
- if (read_counted_string (&local.name_length,
- &local.name, auth_file) == 0) {
- if (local.address) free (local.address);
- if (local.number) free (local.number);
- return 0;
- }
- if (read_counted_string (&local.data_length,
- &local.data, auth_file) == 0) {
- if (local.address) free (local.address);
- if (local.number) free (local.number);
- if (local.name) free (local.name);
- return 0;
- }
- ret = (Xauth *) malloc (sizeof (Xauth));
- if (!ret) {
- if (local.address) free (local.address);
- if (local.number) free (local.number);
- if (local.name) free (local.name);
- if (local.data) {
- bzero (local.data, local.data_length);
- free (local.data);
- }
- return 0;
- }
- *ret = local;
- return ret;
-}
-
-static int
-write_short (s, file)
-unsigned short s;
-FILE *file;
-{
- unsigned char file_short[2];
-
- file_short[0] = (s & (unsigned)0xff00) >> 8;
- file_short[1] = s & 0xff;
- if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
- return 0;
- return 1;
-}
-
-static int
-write_counted_string (count, string, file)
-unsigned short count;
-char *string;
-FILE *file;
-{
- if (write_short (count, file) == 0)
- return 0;
- if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
- return 0;
- return 1;
-}
-
-int
-XauWriteAuth (auth_file, auth)
-FILE *auth_file;
-Xauth *auth;
-{
- if (write_short (auth->family, auth_file) == 0)
- return 0;
- if (write_counted_string (auth->address_length,
- auth->address, auth_file) == 0)
- return 0;
- if (write_counted_string (auth->number_length,
- auth->number, auth_file) == 0)
- return 0;
- if (write_counted_string (auth->name_length, auth->name, auth_file) == 0)
- return 0;
- if (write_counted_string (auth->data_length, auth->data, auth_file) == 0)
- return 0;
- return 1;
-}
-
-#ifdef KRB5
-#ifdef K5_XAUTH
-/*
- * functions to encode/decode Kerberos V5 principals
- * into something that can be reasonable spewed over
- * the wire
- *
- * Author: Tom Yu <tlyu@MIT.EDU>
- *
- * Still needs to be fixed up wrt signed/unsigned lengths, but we'll worry
- * about that later.
- */
-
-/*
- * XauKrb5Encode
- *
- * this function encodes the principal passed to it in a format that can
- * easily be dealt with by stuffing it into an X packet. Encoding is as
- * follows:
- * length count of the realm name
- * realm
- * component count
- * length of component
- * actual principal component
- * etc....
- *
- * Note that this function allocates a hunk of memory, which must be
- * freed to avoid nasty memory leak type things. All counts are
- * byte-swapped if needed. (except for the total length returned)
- *
- * nevermind.... stuffing the encoded packet in net byte order just to
- * always do the right thing. Don't have to frob with alignment that way.
- */
-int
-XauKrb5Encode(princ, outbuf)
- krb5_principal princ; /* principal to encode */
- krb5_data *outbuf; /* output buffer */
-{
- CARD16 i, numparts, totlen = 0, plen, rlen;
- char *cp, *pdata;
-
- rlen = krb5_princ_realm(princ)->length;
- numparts = krb5_princ_size(princ);
- totlen = 2 + rlen + 2; /* include room for realm length
- and component count */
- for (i = 0; i < numparts; i++)
- totlen += krb5_princ_component(princ, i)->length + 2;
- /* add 2 bytes each time for length */
- if ((outbuf->data = (char *)malloc(totlen)) == NULL)
- return -1;
- cp = outbuf->data;
- *cp++ = (char)((int)(0xff00 & rlen) >> 8);
- *cp++ = (char)(0x00ff & rlen);
- memcpy(cp, krb5_princ_realm(princ)->data, rlen); /* safe */
- cp += rlen;
- *cp++ = (char)((int)(0xff00 & numparts) >> 8);
- *cp++ = (char)(0x00ff & numparts);
- for (i = 0; i < numparts; i++)
- {
- plen = krb5_princ_component(princ, i)->length;
- pdata = krb5_princ_component(princ, i)->data;
- *cp++ = (char)((int)(0xff00 & plen) >> 8);
- *cp++ = (char)(0x00ff & plen);
- memcpy(cp, pdata, plen); /* safe */
- cp += plen;
- }
- outbuf->length = totlen;
- return 0;
-}
-
-/*
- * XauKrb5Decode
- *
- * This function essentially reverses what XauKrb5Encode does.
- * return value: 0 if okay, -1 if malloc fails, -2 if inbuf format bad
- */
-int
-XauKrb5Decode(inbuf, princ)
- krb5_data inbuf;
- krb5_principal *princ;
-{
- CARD16 i, numparts, plen, rlen;
- CARD8 *cp, *pdata;
-
- if (inbuf.length < 4)
- {
- return -2;
- }
- *princ = (krb5_principal)malloc(sizeof (krb5_principal_data));
- if (*princ == NULL)
- return -1;
- bzero(*princ, sizeof (krb5_principal_data));
- cp = (CARD8 *)inbuf.data;
- rlen = *cp++ << 8;
- rlen |= *cp++;
- if (inbuf.length < 4 + (int)rlen + 2)
- {
- krb5_free_principal(*princ);
- return -2;
- }
- krb5_princ_realm(*princ)->data = (char *)malloc(rlen);
- if (krb5_princ_realm(*princ)->data == NULL)
- {
- krb5_free_principal(*princ);
- return -1;
- }
- krb5_princ_realm(*princ)->length = rlen;
- memcpy(krb5_princ_realm(*princ)->data, cp, rlen); /* safe */
- cp += rlen;
- numparts = *cp++ << 8;
- numparts |= *cp++;
- krb5_princ_name(*princ) =
- (krb5_data *)malloc(numparts * sizeof (krb5_data));
- if (krb5_princ_name(*princ) == NULL)
- {
- krb5_free_principal(*princ);
- return -1;
- }
- krb5_princ_size(*princ) = 0;
- for (i = 0; i < numparts; i++)
- {
- if (cp + 2 > (CARD8 *)inbuf.data + inbuf.length)
- {
- krb5_free_principal(*princ);
- return -2;
- }
- plen = *cp++ << 8;
- plen |= *cp++;
- if (cp + plen > (CARD8 *)inbuf.data + inbuf.length)
- {
- krb5_free_principal(*princ);
- return -2;
- }
- pdata = (CARD8 *)malloc(plen);
- if (pdata == NULL)
- {
- krb5_free_principal(*princ);
- return -1;
- }
- krb5_princ_component(*princ, i)->data = (char *)pdata;
- krb5_princ_component(*princ, i)->length = plen;
- memcpy(pdata, cp, plen); /* safe */
- cp += plen;
- krb5_princ_size(*princ)++;
- }
- return 0;
-}
-#endif /* K5_XAUTH */
-#endif /* KRB5 */
-#endif /* CK_FORWARD_X */
-#endif /* CK_AUTHENTICATION */
-
-/* C K _ A U T H _ I N I T
- * Initialize the Kerberos system for a pending connection
- * hostname - a reverse DNS lookup of the hostname when possible
- * ipaddr - the ip address of the host
- * username - the name the user wants to connect under not necessarily
- * the same as principal
- * socket - the socket handle (ttyfd in Kermit speak)
- *
- * Returns: 1 on success and 0 on failure
- */
-
-int
-#ifdef CK_ANSIC
-ck_auth_init( char * hostname, char * ipaddr, char * username, int socket )
-#else /* CK_ANSIC */
-ck_auth_init( hostname, ipaddr, username, socket )
- char * hostname; char * ipaddr; char *username; int socket;
-#endif /* CK_ANSIC */
-{
-#ifdef CK_AUTHENTICATION
-#ifdef OS2
- if ( !ck_security_loaddll() ) {
- TELOPT_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
- return(0);
- }
-#endif /* OS2 */
-#endif /* CK_AUTHENTICAITON */
-#ifdef CK_ENCRYPTION
- if ( !!ck_crypt_is_installed() ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
-#endif /* CK_ENCRYPTION */
-
- if (!hostname) hostname = "";
- if (!ipaddr) ipaddr = "";
- if (!username) username = "";
-
- debug(F110,"ck_auth_init Username",username,0);
- debug(F110,"ck_auth_init Hostname",hostname,0);
- debug(F110,"ck_auth_init Ipaddr",ipaddr,0);
-
- ckstrncpy( szUserName, username, UIDBUFLEN );
- ckstrncpy( szHostName, hostname, UIDBUFLEN );
- ckstrncpy( szIP, ipaddr, 16 );
- szUserNameRequested[0] = '\0';
- szUserNameAuthenticated[0] = '\0';
- validUser = AUTH_REJECT;
- accept_complete = 0;
- authentication_version = AUTHTYPE_NULL;
-
-#ifdef CK_AUTHENTICATION
- auth_how = 0;
- auth_crypt = 0;
- auth_fwd = 0;
- mutual_complete = 0;
- if ( sstelnet )
- str_data[3] = TELQUAL_REPLY;
- else
- str_data[3] = TELQUAL_IS;
-#endif /* CK_AUTHENTICATION */
-
-#ifdef CK_SRP
- srp_waitresp = 0;
-#endif /* SRP */
-
-#ifdef CK_KERBEROS
-#ifdef KRB5
- /* free previous ret_cred */
- if ( ret_cred ) {
-#ifdef CK_ENCRYPTION
-#ifdef HEIMDAL
- if ( k5_session_key == &ret_cred->session)
- k5_session_key = NULL;
-#else /* HEIMDAL */
- if ( k5_session_key == &ret_cred->keyblock)
- k5_session_key = NULL;
-#endif /* HEIMDAL */
-#endif /* CK_ENCRYPTION */
- krb5_free_creds(k5_context, ret_cred);
- ret_cred = NULL;
- }
- if (k5_ticket) {
- krb5_free_ticket(k5_context, k5_ticket);
- k5_ticket = NULL;
- }
- /* and context */
- if ( k5_context ) {
- krb5_free_context(k5_context);
- k5_context = NULL;
- }
-
- /* create k5_context */
- krb5_init_context(&k5_context);
-#ifndef MIT_CURRENT
-#ifndef NO_KRB5_INIT_ETS
-/* This routine is a no-op in Kerberos 1.4.x and later */
-/* and in some installations it can't be found in which case */
-/* define NO_KRB5_INIT_ETS */
- if (k5_context)
- krb5_init_ets(k5_context);
-#endif /* NO_KRB5_INIT_ETS */
-#endif /* MIT_CURRENT */
-#ifdef KRB524_CONV
- krb524_init_ets(k5_context);
-#endif /* KRB524_CONV */
- memset(&k5_auth,0,sizeof(k5_auth));
- if (auth_context) {
- krb5_auth_con_free(k5_context, auth_context);
- auth_context = 0;
- }
-#ifdef CK_ENCRYPTION
- if (k5_session_key) {
- krb5_free_keyblock(k5_context, k5_session_key);
- k5_session_key = 0;
- }
-#endif /* ENCRYPTION */
-#ifdef TLS_VERIFY
- krb5_tls_verified = 0;
-#endif /* TLS_VERIFY */
-#endif /* KRB5 */
-
-#ifdef KRB4
-#ifdef CK_ENCRYPTION
- /* Initialize buffers used for authentication */
- memset(&k4_session_key, 0, sizeof(k4_session_key));
- memset(&k4_challenge, 0, sizeof(k4_challenge));
-#endif /* CK_ENCRYPTION */
-#endif /* KRB4 */
-
-#ifdef RLOGCODE
- rlog_encrypt = 0;
-#endif /* RLOGCODE */
- nstored = 0;
- store_ptr = storage;
- memset(storage,0,sizeof(storage));
-#endif /* CK_KERBEROS */
-
-#ifdef CK_ENCRYPTION
- kstream_destroy();
- if (!kstream_create_from_fd(socket, NULL))
- return(0);
-#endif /* CK_ENCRYPTION */
- return(1);
-}
-
-void
-auth_finished(result) int result; {
- extern char uidbuf[];
- extern int sstelnet;
-
- validUser = result;
- switch (result) {
- case AUTH_REJECT: /* Rejected */
- if (sstelnet)
- uidbuf[0] = '\0';
- authentication_version = AUTHTYPE_NULL;
- break;
- case AUTH_UNKNOWN: /* We don't know who he is, but he's okay */
- if (sstelnet)
- strcpy(uidbuf,"(unknown)");
- break;
- case AUTH_OTHER: /* We know him, but not his name */
- if (sstelnet)
- strcpy(uidbuf,"(other)");
- break;
- case AUTH_USER: /* We know he name */
- case AUTH_VALID: /* We know him, and he needs no password */
- if (sstelnet)
- strcpy(uidbuf,szUserNameRequested);
- break;
- }
-}
-
-#ifdef MACOSX
-#ifdef KRB5
-
-krb5_error_code
-ck_krb5_write_message(krb5_context con, krb5_pointer ptr, krb5_data *data)
-{
- int fd = *((int *)ptr);
- long msglen;
-
- msglen = htonl(data->length);
- if (net_write(fd,(CHAR *)&msglen,4) != 4) {
- return(-1);
- }
- if ( data->length ) {
- if (net_write(fd,data->data,data->length) != data->length) {
- return(-1);
- }
- }
- return(0);
-}
-
-krb5_error_code
-ck_krb5_read_message( krb5_context context,
- krb5_pointer ptr,
- krb5_data * data)
-{
- extern int ttyfd;
- int fd = *((int *)ptr);
- long msglen;
- char *p;
- int i, rc;
-
- if (net_read(fd,&msglen,4) < 0)
- return(-1);
-
- data->length = ntohl(msglen);
- if ( data->length ) {
- data->data = malloc(data->length);
-
- i = 0;
- while ( i < data->length ) {
- if ((rc = net_read(fd,&data->data[i],(data->length - i))) < 0)
- return(-1);
- i += rc;
- }
- }
- return(0);
-}
-#endif /* KRB5 */
-#endif /* MACOSX */
-#endif /* CK_SECURITY */
-
-
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuath.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckuath.h
deleted file mode 100644
index 914a06f..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuath.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/* C K U A T H . H -- "C-Kermit to Authentication" interface */
-
-/*
- Author: Jeffrey E Altman <jaltman@secure-endpoints.com>,
- Secure Endpoints Inc., New York City.
-
- Copyright (C) 1999, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- * Based on a concatenation of all necessary include files distributed with
- * the Kerberos 5 NT Alpha 2 Telnet package from MIT.
- */
-
-#ifndef KRB5_KERMIT_H
-#define KRB5_KERMIT_H
-
-#ifndef BOOL
-#define BOOL int
-#endif
-
-/* Header file for encrypted-stream library.
- * Written by Ken Raeburn (Raeburn@Cygnus.COM).
- * Copyright (C) 1991, 1992, 1994 by Cygnus Support.
- *
- * Permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation.
- * Cygnus Support makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#ifndef K5STREAM_H
-#define K5STREAM_H
-
-typedef void *kstream_ptr; /* Data send on the kstream */
-struct kstream_data_block {
- kstream_ptr ptr;
- size_t length;
-};
-
-typedef struct kstream_int { /* Object we pass around */
- int fd; /* Open socket descriptor */
- int (*encrypt)(struct kstream_data_block *, /* output */
- struct kstream_data_block *); /* input */
- int encrypt_type;
- int (*decrypt)(struct kstream_data_block *, /* output */
- struct kstream_data_block *); /* input */
- int decrypt_type;
-} *kstream;
-
-/* Prototypes */
-
-int kstream_destroy();
-void kstream_set_buffer_mode(int);
-int kstream_create_from_fd(int fd, kstream_ptr);
-int kstream_write(void *, size_t);
-int kstream_read(void *, size_t);
-
-#endif /* K5STREAM_H */
-
-/*
- * Implements Telnet authentication and encryption
- */
-
-#ifndef TELNET_AUTH_H
-#define TELNET_AUTH_H
-
-int auth_parse(unsigned char *, int);
-
-int auth_init(kstream);
-
-void auth_destroy(void);
-
-int auth_encrypt(struct kstream_data_block *, struct kstream_data_block *);
-
-int auth_decrypt(struct kstream_data_block *, struct kstream_data_block *);
-
-extern BOOL forward_flag;
-extern BOOL forwardable_flag;
-extern BOOL forwarded_tickets;
-#endif /* TEL_AUTH_H */
-
-
-/* C-Kermit specific functions */
-_PROTOTYP(void auth_finished,(int));
-_PROTOTYP(int ck_auth_init, (char *, char *, char *, int));
-_PROTOTYP(int ck_tn_auth_valid, (VOID));
-_PROTOTYP(int ck_tn_auth_in_progress,(VOID));
-_PROTOTYP(int ck_tn_sb_auth, (char *, int));
-_PROTOTYP(int ck_tn_sb_encrypt, (char *, int));
-_PROTOTYP(int ck_tn_auth_request, (VOID));
-_PROTOTYP(void ck_tn_encrypt, (char *, int));
-_PROTOTYP(void ck_tn_decrypt, (char *, int));
-_PROTOTYP(void ck_tn_encrypt_start, (VOID));
-_PROTOTYP(void ck_tn_encrypt_stop, (VOID));
-_PROTOTYP(int ck_tn_authenticated, (VOID));
-#ifdef CK_ENCRYPTION
-_PROTOTYP(int ck_tn_encrypting, (VOID));
-_PROTOTYP(int ck_tn_decrypting, (VOID));
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
-_PROTOTYP(int ck_tn_tls_negotiate, (VOID));
-_PROTOTYP(int SendSSLAuthSB, (int, void *, int));
-#endif /* CK_SSL */
-
-#ifdef CK_KERBEROS
- /* Define MIT_CURRENT to compile the code for use with versions of */
- /* Kerberos later than KRB5 1.0.5. Note. This will not compile */
- /* successfully in Kermit 95 due to the segmentation of crypto */
- /* into a separate DLL. */
-
-#ifndef KRB5_INIT_ETS
-/* krb5_init_ets() is a no-op in Kerberos 1.4.x and later */
-/* and in some installations it can't be found so now by default */
-/* we don't use it. */
-#define NO_KRB5_INIT_ETS
-#endif /* KRB5_INIT_ETS */
-
-#define KRB_DEFTIM 600 /* Default lifetime (minutes) */
-
-/* Kerberos structure definitions */
-
-struct krb_op_data { /* Operational data for all actions */
- int version; /* Kerberos version */
- char * cache; /* Kerberos cache file */
-};
-
-struct krb4_init_data { /* INITIALIZE data structure */
- int lifetime;
- char * principal; /* Principal string */
- char * instance;
- char * realm; /* Realm string */
- char * password; /* Kerberos password */
- int preauth; /* Use preauth mode? */
- int verbose; /* Verbose output? */
-};
-
-#define KRB5_NUM_OF_ADDRS 16
-struct krb5_init_data { /* INITIALIZE data structure */
- int forwardable; /* Switch values */
- int proxiable; /* Correspond to switch names... */
- int lifetime;
- int renew;
- int renewable;
- int validate;
- char * postdate;
- char * service;
- char * principal; /* Principal string */
- char * instance;
- char * realm; /* Realm string */
- char * password; /* Kerberos password */
- int preauth; /* Use preauth mode? */
- int verbose; /* Verbose output? */
- int getk4; /* Get K4 TGT? */
- char * addrs[KRB5_NUM_OF_ADDRS+1]; /* List of IP Addresses */
- int no_addresses; /* Do not include IP Addresses */
-};
-
-struct krb5_list_cred_data { /* List Credentials data */
- int encryption;
- int flags;
- int addr;
-};
-
-_PROTOTYP(int ck_krb5_autoget_TGT, (char *));
-_PROTOTYP(int ck_krb5_initTGT, (struct krb_op_data *,struct krb5_init_data *,
- struct krb4_init_data *));
-_PROTOTYP(int ck_krb5_destroy, (struct krb_op_data *));
-_PROTOTYP(int ck_krb5_list_creds, (struct krb_op_data *,
- struct krb5_list_cred_data *));
-_PROTOTYP(char * ck_krb5_getrealm, (char *));
-_PROTOTYP(char * ck_krb5_getprincipal, (char *));
-_PROTOTYP(char * ck_krb5_get_cc_name, (VOID));
-
-_PROTOTYP(int ck_krb4_autoget_TGT, (char *));
-_PROTOTYP(int ck_krb4_initTGT, (struct krb_op_data *,struct krb4_init_data *));
-_PROTOTYP(int ck_krb4_destroy, (struct krb_op_data *));
-_PROTOTYP(int ck_krb4_list_creds, (struct krb_op_data *));
-_PROTOTYP(char * ck_krb4_getrealm, (VOID));
-_PROTOTYP(char * ck_krb4_getprincipal, (VOID));
-
-_PROTOTYP(int ck_krb4_get_tkts, (VOID));
-_PROTOTYP(char * ck_krb4_get_next_tkt, (VOID));
-_PROTOTYP(int ck_krb4_tkt_isvalid,(char *));
-_PROTOTYP(int ck_krb4_is_tgt_valid,(VOID));
-_PROTOTYP(int ck_krb4_tkt_time,(char *));
-
-_PROTOTYP(int ck_krb5_get_tkts, (char *));
-_PROTOTYP(char * ck_krb5_get_next_tkt, (VOID));
-_PROTOTYP(int ck_krb5_tkt_isvalid,(char *,char *));
-_PROTOTYP(char * ck_krb5_tkt_flags,(char *,char *));
-_PROTOTYP(int ck_krb5_is_tgt_valid,(VOID));
-_PROTOTYP(int ck_krb5_tkt_time,(char *,char *));
-
-_PROTOTYP(int krb4_des_avail,(int));
-_PROTOTYP(int krb4_des_write,(int,char *,int));
-_PROTOTYP(int krb4_des_read, (int,char *,int));
-_PROTOTYP(int krb5_des_avail,(int));
-_PROTOTYP(int krb5_des_write,(int,char *,int,int));
-_PROTOTYP(int krb5_des_read, (int,char *,int,int));
-_PROTOTYP(int krb5_u2u_avail,(int));
-_PROTOTYP(int krb5_u2u_write,(int,char *,int));
-_PROTOTYP(int krb5_u2u_read, (int,char *,int));
-_PROTOTYP(int k5_user_to_user_server_auth,(VOID));
-_PROTOTYP(int k5_user_to_user_client_auth,(VOID));
-#endif /* CK_KERBEROS */
-
-_PROTOTYP(int ck_krb5_is_installed,(void));
-_PROTOTYP(int ck_krb4_is_installed,(void));
-_PROTOTYP(int ck_srp_is_installed,(void));
-_PROTOTYP(int ck_ntlm_is_installed,(void));
-_PROTOTYP(int ck_crypt_is_installed,(void));
-_PROTOTYP(int ck_ssleay_is_installed,(void));
-_PROTOTYP(int ck_gssapi_is_installed,(void));
-_PROTOTYP(int ck_krypto_is_installed,(void));
-
-_PROTOTYP(VOID ck_encrypt_send_support,(VOID));
-_PROTOTYP(int ck_get_crypt_table,(struct keytab **, int *));
-_PROTOTYP(char * ck_krb4_realmofhost,(char *));
-_PROTOTYP(char * ck_krb5_realmofhost,(char *));
-
-#define FORWARD /* allow forwarding of credential */
-#ifdef FORWARD
-_PROTOTYP(int kerberos5_forward,(VOID));
-#endif /* FORWARD */
-
-#define AUTHTYPLSTSZ 8
-#endif /*KRB5_KERMIT_H*/
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckubwr.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckubwr.txt
deleted file mode 100644
index 38b064a..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckubwr.txt
+++ /dev/null
@@ -1,5363 +0,0 @@
-
- [1]The Columbia Crown The Kermit Project | Columbia University
- 612 West 115th Street, New York NY 10025 USA o [2]kermit@columbia.edu
- ...since 1981
- [3]Home [4]Kermit 95 [5]C-Kermit [6]Scripts [7]Current [8]New [9]FAQ
- [10]Support
-
-C-Kermit Unix Hints and Tips
-
- Frank da Cruz
- [11]The Kermit Project, [12]Columbia University
-
- As of: C-Kermit 9.0.302, 20 August 2011
- This page last updated: Sun Aug 21 12:08:52 2011 (New York USA Time)
-
- IF YOU ARE READING A PLAIN-TEXT version of this document, note it is
- a plain-text dump of a Web page. You can visit the original (and
- possibly more up-to-date) Web page here:
-
- [13]http://www.columbia.edu/kermit/ckubwr.html
-
- Since the material in this file has been accumulating since 1985,
- some (much) of it might be dated.
-
-Known problems with C-Kermit 9.0
-
- * Domain name resolution does not work in Solaris 10 or 11 (fixed in
- [14]9.0.301).
- * UUCP lockfile failure in FreeBSD 8 (fixed in [15]9.0.302).
- * Build failure FreeBSD 9 (fixed in [16]9.0.302).
- * Opening new SSH sessions after closing previous ones sometimes
- fails.
- * Heimdal Kerberos not supported.
-
- [ [17]C-Kermit ] [ [18]Installation Instructions ] [ [19]TUTORIAL ]
-
-CONTENTS
-
- 1. [20]INTRODUCTION
- 2. [21]PREBUILT C-KERMIT BINARIES
- 3. [22]PLATFORM-SPECIFIC NOTES
- 4. [23]GENERAL UNIX-SPECIFIC LIMITATIONS AND BUGS
- 5. [24]INITIALIZATION AND COMMAND FILES
- 6. [25]COMMUNICATION SPEED SELECTION
- 7. [26]COMMUNICATIONS AND DIALING
- 8. [27]HARDWARE FLOW CONTROL
- 9. [28]TERMINAL CONNECTION AND KEY MAPPING
- 10. [29]FILE TRANSFER
- 11. [30]EXTERNAL FILE TRANSFER PROTOCOLS
- 12. [31]SECURITY
- 13. [32]MISCELLANEOUS USER REPORTS
- 14. [33]THIRD-PARTY DRIVERS
-
- Quick Links: [ [34]Linux ] [ [35]*BSD ] [[36]Mac OS X] [ [37]AIX ] [
- [38]HP-UX ] [ [39]Solaris ] [ [40]SCO ]
-
-1. INTRODUCTION
-
- [ [41]Top ] [ [42]Contents ] [ [43]Next ]
-
- SECTION CONTENTS
-
- 1.1. [44]Documentation
- 1.2. [45]Technical Support
- 1.3. [46]The Year 2000
- 1.4. [47]The Euro
-
- THIS IS WHAT USED TO BE CALLED the "beware file" for the Unix version
- of C-Kermit, previously distributed as ckubwr.txt and, before that, as
- ckuker.bwr, after the fashion of old Digital Equipment Corporation
- (DEC) software releases that came with release notes (describing what
- had changed) and a "beware file" listing known bugs, limitations,
- "non-goals", and things to watch out for. The C-Kermit beware file has
- been accumulating since 1985, and it applies to many different hardware
- platforms and operating systems, and many versions of them, so it is
- quite large. Prior to C-Kermit 8.0, it was distributed only in
- plain-text format. Now it is available as a Web document with links,
- internal cross references, and so on, to make it easier to use.
-
- This document applies to Unix C-Kermit in general, as well as to
- specific Unix variations like [48]Linux, [49]AIX, [50]HP-UX,
- [51]Solaris, and so on, and should be read in conjunction with the
- [52]platform-independent C-Kermit beware file, which contains similar
- information, but applying to all versions of C-Kermit (VMS, Windows,
- OS/2, AOS/VS, VOS, etc, as well as to Unix).
-
- There is much in this document that is (only) of historical interest.
- The navigation links should help you skip directly to the sections that
- are relevant to you. Numerous offsite Web links are supposed to lead to
- further information but, as you know, Web links go stale frequently and
- without warning. If you can supply additional, corrected, updated, or
- better Web links, please feel free to [53]let me know.
-
-1.1. Documentation
-
- [ [54]Top ] [ [55]Contents ] [ [56]Next ]
-
- C-Kermit 6.0 is documented in the book [57]Using C-Kermit, Second
- Edition, by Frank da Cruz and Christine M. Gianone, Digital Press,
- Burlington, MA, USA, ISBN 1-55558-164-1 (1997), 622 pages. This remains
- the definitive C-Kermit documentation. Until the third edition is
- published (sorry, there is no firm timeframe for this), please also
- refer to:
-
- [58]Supplement to Using C-Kermit, Second Edition, For C-Kermit 7.0
- Thorough documentation of features new to version 7.0.
-
- [59]Supplement to Using C-Kermit, Second Edition, For C-Kermit 8.0
- Thorough documentation of features new to version 8.0.
-
- [60]Supplement to Using C-Kermit, Second Edition, For C-Kermit 9.0
- Thorough documentation of features new to version 9.0.
-
-1.2. Technical Support
-
- [ [61]Top ] [ [62]Contents ] [ [63]Section Contents ] [ [64]Next ] [
- [65]Previous ]
-
- For information on how to get technical support, please visit:
-
- [66]http://www.columbia.edu/kermit/support.html
-
-1.3. The Year 2000
-
- [ [67]Top ] [ [68]Contents ] [ [69]Section Contents ] [ [70]Next ] [
- [71]Previous ]
-
- The Unix version of C-Kermit, release 6.0 and later, is "Year 2000
- compliant", but only if the underlying operating system is too. Contact
- your Unix operating system vendor to find out which operating system
- versions, patches, hardware, and/or updates are required. (Quite a few
- old Unixes are still in operation in the new millenium, but with their
- date set 28 years in the past so at least the non-year parts of the
- calendar are correct.)
-
- As of C-Kermit 6.0 (6 September 1996), post-millenium file dates are
- recognized, transmitted, received, and reproduced correctly during the
- file transfer process in C-Kermit's File Attribute packets. If
- post-millenium dates are not processed correctly on the other end, file
- transfer still takes place, but the modification or creation date of
- the received file might be incorrect. The only exception would be if
- the "file collision update" feature is being used to prevent
- unnecessary transfer of files that have not changed since the last time
- a transfer took place; in this case, a file might be transferred
- unnecessarily, or it might not be transferred when it should have been.
- Correct operation of the update feature depends on both Kermit programs
- having the correct date and time.
-
- Of secondary importance are the time stamps in the transaction and/or
- debug logs, and the date-related script programming constructs, such as
- \v(date), \v(ndate), \v(day), \v(nday), and perhaps also the
- time-related ones, \v(time) and \v(ntime), insofar as they might be
- affected by the date. The \v(ndate) is a numeric-format date of the
- form yyyymmdd, suitable for both lexical and numeric comparison and
- sorting: e.g. 19970208 or 20011231. If the underlying operating system
- returns the correct date information, these variables will have the
- proper values. If not, then scripts that make decisions based on these
- variables might not operate correctly.
-
- Most date-related code is based upon the C Library asctime() string,
- which always has a four-digit year. In Unix, the one bit of code in
- C-Kermit that is an exception to this rule is several calls to
- localtime(), which returns a pointer to a tm struct, in which the year
- is presumed to be expressed as "years since 1900". The code depends on
- this assumption. Any platforms that violate it will need special
- coding. As of this writing, no such platforms are known.
-
- Command and script programming functions that deal with dates use
- C-Kermit specific code that always uses full years.
-
-1.4. The Euro
-
- [ [72]Top ] [ [73]Contents ] [ [74]Section Contents ] [ [75]Previous ]
-
- C-Kermit 7.0 and later support Unicode (ISO 10646), ISO 8859-15 Latin
- Alphabet 9, PC Code Page 858, Windows Code Pages 1250 and 1251, and
- perhaps other character sets, that encode the Euro symbol, and can
- translate among them as long as no intermediate character-set is
- involved that does not include the Euro.
-
-2. PREBUILT C-KERMIT BINARIES
-
- [ [76]Top ] [ [77]Contents ] [ [78]Next ] [ [79]Previous ]
-
- It is often dangerous to run a binary C-Kermit (or any other) program
- built on a different computer. Particularly if that computer had a
- different C compiler, libraries, operating system version, processor
- features, etc, and especially if the program was built with shared
- libraries, because as soon as you update the libraries on your system,
- they no longer match the ones referenced in the binary, and the binary
- might refuse to load when you run it, in which case you'll see error
- messages similar to:
-
- Could not load program kermit
- Member shr4.o not found or file not an archive
- Could not load library libcurses.a[shr4.o]
- Error was: No such file or directory
-
- (These samples are from AIX.) To avoid this problem, we try to build
- C-Kermit with statically linked libraries whenever we can, but this is
- increasingly impossible as shared libraries become the norm.
-
- It is often OK to run a binary built on an earlier OS version, but it
- is rarely possible (or safe) to run a binary built on a later one, for
- example to run a binary built under Solaris 8 on Solaris 2.6. Sometimes
- even the OS-or-library patch/ECO level makes a difference.
-
- A particularly insidious problem occurs when a binary was built on a
- version of the OS that has patches from the vendor (e.g. to libraries);
- in many cases you won't be able to run such a binary on an unpatched
- version of the same platform.
-
- When in doubt, build C-Kermit from the source code on the computer
- where it is to be run (if possible!). If not, ask us for a binary
- specific to your configuration. We might have one, and if we don't, we
- might be able to find somebody who will build one for you.
-
-3. NOTES ON SPECIFIC UNIX VERSIONS
-
- [ [80]Top ] [ [81]Contents ] [ [82]Next ] [ [83]Previous ]
-
- SECTION CONTENTS
-
- 3.0. [84]C-KERMIT ON PC-BASED UNIXES
- 3.1. [85]C-KERMIT AND AIX
- 3.2. [86]C-KERMIT AND HP-UX
- 3.3. [87]C-KERMIT AND LINUX
- 3.4. [88]C-KERMIT AND NEXTSTEP
- 3.5. [89]C-KERMIT AND QNX
- 3.6. [90]C-KERMIT AND SCO
- 3.7. [91]C-KERMIT AND SOLARIS
- 3.8. [92]C-KERMIT AND SUNOS
- 3.9. [93]C-KERMIT AND ULTRIX
- 3.10. [94]C-KERMIT AND UNIXWARE
- 3.11. [95]C-KERMIT AND APOLLO SR10
- 3.12. [96]C-KERMIT AND TANDY XENIX 3.0
- 3.13. [97]C-KERMIT AND OSF/1 (DIGITAL UNIX) (TRU64 UNIX)
- 3.14. [98]C-KERMIT AND SGI IRIX
- 3.15. [99]C-KERMIT AND THE BEBOX
- 3.16. [100]C-KERMIT AND DG/UX
- 3.17. [101]C-KERMIT AND SEQUENT DYNIX
- 3.18. [102]C-KERMIT AND {FREE,OPEN,NET}BSD
- 3.19. [103]C-KERMIT AND MAC OS X
- 3.20. [104]C-KERMIT AND COHERENT
-
- The following sections apply to specific Unix versions. Most of them
- contain references to FAQs (Frequently Asked Questions), but these tend
- to be ephemeral. For possibly more current information see:
-
- [105]http://www.faqs.org
- [106]http://aplawrence.com/Unixart/newtounix.html
-
- One thread that runs through many of them, and implicitly perhaps
- through all, concerns the problems that occur when trying to dial out
- on a serial device that is (also) enabled for dialing in. The
- "solutions" to this problem are many, varied, diverse, and usually
- gross, involving configuring the device for bidirectional use. This is
- done in a highly OS-dependent and often obscure manner, and the effects
- (good or evil) are also highly dependent on the particular OS (and
- getty variety, etc). Many examples are given in the [107]OS-specific
- sections below.
-
- An important point to keep in mind is that C-Kermit is a
- cross-platform, portable software program. It was not designed
- specifically and only for your particular Unix version, or for that
- matter, for Unix in particular at all. It also runs on VMS, AOS/VS,
- VOS, and other non-Unix platforms. All the Unix versions of C-Kermit
- share common i/o modules, with compile-time #ifdef constructions used
- to account for the differences among the many Unix products and
- releases. If you think that C-Kermit is behaving badly or missing
- something on your particular Unix version, you might be right -- we
- can't claim to be expert in hundreds of different OS / version /
- hardware / library combinations. If you're a programmer, take a look at
- the source code and [108]send us your suggested fixes or changes. Or
- else just [109]send us a report about what seems to be wrong and we'll
- see what we can do.
-
-3.0. C-KERMIT ON PC-BASED UNIXES
-
- [ [110]Top ] [ [111]Contents ] [ [112]Section Contents ] [ [113]Next ]
-
- Also see: [114]http://www.pcunix.com/.
-
- SECTION CONTENTS
-
- 3.0.1. [115]Interrupt Conflicts
- 3.0.2. [116]Windows-Specific Hardware
- 3.0.3. [117]Modems
- 3.0.4. [118]Character Sets
- 3.0.5. [119]Keyboard, Screen, and Mouse Access
- 3.0.6. [120]Laptops
-
-3.0.1. Interrupt Conflicts
-
- [ [121]Top ] [ [122]Contents ] [ [123]Section Contents ] [ [124]Next ]
-
- PCs are not the best platform for real operating systems like Unix. The
- architecture suffers from numerous deficiencies, not the least of which
- is the stiflingly small number of hardware interrupts (either 7 or 15,
- many of which are preallocated). Thus adding devices, using multiple
- serial ports, etc, is always a challenge and often a nightmare. The
- free-for-all nature of the PC market and the lack of standards combined
- with the diversity of Unix OS versions make it difficult to find
- drivers for any particular device on any particular version of Unix.
-
- Of special interest to Kermit users is the fact that there is no
- standard provision in the PC architecture for more than 2 communication
- (serial) ports. COM3 and COM4 (or higher) will not work unless you (a)
- find out the hardware address and interrupt for each, (b) find out how
- to provide your Unix version with this information, and (c) actually
- set up the configuration in the Unix startup files (or whatever other
- method is used). Watch out for interrupt conflicts, especially when
- using a serial mouse, and don't expect to be able to use more than two
- serial ports.
-
- The techniques for resolving interrupt conflicts are different for each
- operating system (Linux, NetBSD, etc). In general, there is a
- configuration file somewhere that lists COM ports, something like this:
-
- com0 at isa? port 0x3f8 irq 4 # DOS COM1
- com1 at isa? port 0x2f8 irq 3 # DOS COM2
-
- The address and IRQ values in this file must agree with the values in
- the PC BIOS and with the ports themselves, and there must not be more
- than one device with the same interrupt. Unfortunately, due to the
- small number of available interrupts, installing new devices on a PC
- almost always creates a conflict. Here is a typical tale from a Linux
- user (Fred Smith) about installing a third serial port:
-
- ...problems can come from a number of causes. The one I fought with
- for some time, and finally conquered, was that my modem is on an
- add-in serial port, cua3/IRQ5. By default IRQ5 has a very low
- priority, and does not get enough service in times when the system
- is busy to prevent losing data. This in turn causes many resends.
- There are two 'fixes' that I know of, one is to relax hard disk
- interrupt hogging by using the correct parameter to hdparm, but I
- don't like that one because the hdparm man page indicates it is
- risky to use. The other one, the one I used, was to get 'irqtune'
- and use it to give IRQ5 the highest priority instead of nearly the
- lowest. Completely cured the problem.
-
- Here's another one from a newsgroup posting:
-
- After much hair pulling, I've discovered why my serial port won't
- work. Apparently my [PC] has three serial devices (two comm ports
- and an IR port), of which only two at a time can be active. I looked
- in the BIOS setup and noticed that the IR port was activated, but
- didn't realize at the time that this meant that COM2 was thereby
- de-activated. I turned off the IR port and now the serial port works
- as advertised.
-
-3.0.2. Windows-Specific Hardware
-
- [ [125]Top ] [ [126]Contents ] [ [127]Section Contents ] [ [128]Next ]
- [ [129]Previous ]
-
- To complicate matters, the PC platform is becoming increasingly and
- inexorably Windows-oriented. More and more add-on devices are "Windows
- only" -- meaning they are incomplete and rely on proprietary
- Windows-based software drivers to do the jobs that you would expect the
- device itself to do. PCMCIA, PCI, or "Plug-n-Play" devices are rarely
- supported on PC-based Unix versions such as SCO; Winmodems,
- Winprinters, and the like are not supported on any Unix variety (with
- [130]a few exceptions). The self-proclaimed Microsoft PC 97 (or later)
- standard only makes matters worse since its only purpose to ensure that
- PCs are "optimized to run Windows 95 and Windows NT 4.0 and future
- versions of these operating systems".
-
- With the exception noted (the Lucent modem, perhaps a handful of others
- by the time you read this), drivers for "Win" devices are available
- only for Windows, since the Windows market dwarfs that of any
- particular Unix brand, and for that matter all Unixes (or for that
- matter, all non-Windows operating systems) combined. If your version of
- Unix (SCO, Linux, BSDI, FreeBSD, etc) does not support a particular
- device, then C-Kermit can't use it either. C-Kermit, like any Unix
- application, must access all devices through drivers and not directly
- because Unix is a real operating system.
-
- Don't waste time thinking that you, or anybody else, could write a
- Linux (or other Unix) driver for a Winmodem or other "Win" device.
- First of all, these devices generally require realtime control, but
- since Unix is a true multitasking operating system, realtime device
- control is not possible outside the kernel. Second, the specifications
- for these devices are secret and proprietary, and each one (and each
- version of each one) is potentially different. Third, a Winmodem driver
- would be enormously complex; it would take years to write and debug, by
- which time it would be obsolete.
-
- A more recent generation of PCs (circa 1999-2000) is marketed as
- "Legacy Free". One can only speculate what that could mean. Most likely
- it means it will ONLY run the very latest versions of Windows, and is
- made exclusively of Winmodems, Winprinters, Winmemory, and Win-CPU-fans
- (Legacy Free is a concept [131]pioneered by Microsoft).
-
- Before you buy a new PC or add-on equipment, especially serial ports,
- internal modems, or printers, make sure they are compatible with your
- version of Unix. This is becoming an ever-greater challenge; only a
- huge company like Microsoft can afford to be constantly cranking out
- and/or verifying drivers for the thousands of video boards, sound
- cards, network adapters, SCSI adapters, buses, etc, that spew forth in
- an uncontrolled manner from all corners of the world on a daily basis.
- With very few exceptions, makers of PCs assemble the various components
- and then verify them only with Windows, which they must do since they
- are, no doubt, preloading the PC with Windows. To find a modern PC that
- is capable of running a variety of non-Windows operating systems (e.g.
- Linux, SCO OpenServer, Unixware, and Solaris) is a formidable challenge
- requiring careful study of each vendor's "compatibility lists" and
- precise attention to exact component model numbers and revision levels.
-
-3.0.3. Modems
-
- [ [132]Top ] [ [133]Contents ] [ [134]Section Contents ] [ [135]Next ]
- [ [136]Previous ]
-
- External modems are recommended:
-
- * They don't need any special drivers.
- * You can use the lights and speaker to troubleshoot dialing.
- * You can share them among all types of computers.
- * You can easily turn them off and on when power-cycling seems
- warranted.
- * They are more likely to have manuals.
-
- Internal PC modems (even when they are not Winmodems, which is
- increasingly unlikely in new PCs) are always trouble, especially in
- Unix. Even when they work for dialing out, they might not work for
- dialing in, etc. Problems that occur when using an internal modem can
- almost always be eliminated by switching to an external one. Even when
- an internal modem is not a Winmodem or Plug-n-Play, it is often a
- no-name model of unknown quality -- not the sort of thing you want
- sitting directly on your computer's bus. (Even if it does not cause
- hardware problems, it probably came without a command list, so no Unix
- software will know how to control it.) For more about Unix compatible
- modems, see:
-
- [137]http://www.idir.net/~gromitkc/winmodem.html
-
- Remember that PCs, even now -- more than two decades after they were
- first introduced -- are not (in general) capable of supporting more
- than 2 serial devices. Here's a short success story from a recent
- newsgroup posting: "I have a Diamond SupraSonic II dual modem in my
- machine. What I had to end up doing is buying a PS/2 mouse and port and
- install it. Had to get rid of my serial mouse. I also had to disable
- PnP in my computer bios. I was having IRQ conflicts between my serial
- mouse and 'com 3'. Both modems work fine for me. My first modem is
- ttyS0 and my second is ttyS1." Special third-party multiport boards
- such as [138]DigiBoard are available for certain Unix platforms
- (typically SCO, maybe Linux) that come with special platform-specific
- drivers.
-
-3.0.4. Character Sets
-
- [ [139]Top ] [ [140]Contents ] [ [141]Section Contents ] [ [142]Next ]
- [ [143]Previous ]
-
- PCs generally have PC code pages such as CP437 or CP850, and these are
- often used by PC-based Unix operating systems, particularly on the
- console. These are supported directly by C-Kermit's SET FILE
- CHARACTER-SET and SET TERMINAL CHARACTER-SET commands. Some PC-based
- Unix versions, such as recent Red Hat Linux releases, might also
- support Microsoft Windows code pages such as CP1252, or even Latin
- Alphabet 1 itself (perhaps displayed with CP437 glyphs). (And work is
- in progress to support Unicode UTF8 in Linux.)
-
- Certain Windows code pages are not supported directly by C-Kermit, but
- since they are ISO Latin Alphabets with nonstandard "extensions" in the
- C1 control range, you can substitute the corresponding Latin alphabet
- (or other character set) in any C-Kermit character-set related
- commands:
-
- Windows Code Page Substitution
- CP 1004 Latin-1
- CP 1051 HP Roman-8
-
- Other Windows code pages are mostly (or totally) incompatible with
- their Latin Alphabet counterparts (e.g. CP1250 and Latin-2), and
- several of these are already supported by C-Kermit 7.0 and later (1250,
- 1251, and 1252).
-
-3.0.5. Keyboard, Screen, and Mouse Access
-
- [ [144]Top ] [ [145]Contents ] [ [146]Section Contents ] [ [147]Next ]
- [ [148]Previous ]
-
- Finally, note that as a real operating system, Unix (unlike Windows)
- does not provide the intimate connection to the PC keyboard, screen,
- and mouse that you might expect. Unix applications can not "see" the
- keyboard, and therefore can not be programmed to understand F-keys,
- Editing keys, Arrow keys, Alt-key combinations, and the like. This is
- because:
-
- a. Unix is a portable operating system, not only for PCs;
- b. Unix sessions can come from anywhere, not just the PC's own
- keyboard and screen; and:
- c. even though it might be possible for an application that actually
- is running on the PC's keyboard and screen to access these devices
- directly, there are no APIs (outside of X) for this.
-
-3.0.6. Laptops
-
- [ [149]Top ] [ [150]Contents ] [ [151]Section Contents ] [
- [152]Previous ]
-
- (To be filled in . . .)
-
-3.1. C-KERMIT AND AIX
-
- [ [153]Top ] [ [154]Contents ] [ [155]Section Contents ] [ [156]Next ]
- [ [157]Previous ]
-
- SECTION CONTENTS
-
- 3.1.1. [158]AIX: General
- 3.1.2. [159]AIX: Network Connections
- 3.1.3. [160]AIX: Serial Connections
- 3.1.4. [161]AIX: File Transfer
- 3.1.5. [162]AIX: Xterm Key Map
-
- For additional information see:
- * [163]http://www.emerson.emory.edu/services/aix-faq/
- * [164]http://www.faqs.org/faqs/by-newsgroup/comp/comp.unix.aix.html
- * [165]http://www.cis.ohio-state.edu/hypertext/faq/usenet/aix-faq/top
- .html
- * [166]http://aixpdslib.seas.ucla.edu/
- * [167]http://www.rootvg.net (AIX history)
- * [168]ftp://rtfm.mit.edu/pub/usenet/news.answers/aix-faq/part1
- * [169]ftp://mirrors.aol.com/pub/rtfm/usenet-by-hierarchy/comp/unix/a
- ix
-
- and/or read the [170]comp.unix.aix newsgroup.
- ________________________________________________________________________
-
-3.1.1. AIX: General
-
- [ [171]Top ] [ [172]Contents ] [ [173]Section Contents ] [ [174]Next ]
-
- About AIX version numbers: "uname -a" tells the two-digit version
- number, such as 3.2 or 4.1. The three-digit form can be seen with the
- "oslevel" command (this information is unavailable at the API level and
- is reportedly obtained by scanning the installed patch list).
- Supposedly all three-digit versions within the same two-digit version
- (e.g. 4.3.1, 4.3.2) are binary compatible; i.e. a binary built on any
- one of them should run on all others, but who knows. Most AIX advocates
- tell you that any AIX binary will run on any AIX version greater than
- or equal to the one under which it was built, but experience with
- C-Kermit suggests otherwise. It is always best to run a binary built
- under your exact same AIX version, down to the third decimal place, if
- possible. Ideally, build it from source code yourself. Yes, this advice
- would be easier to follow if AIX came with a C compiler.
- ________________________________________________________________________
-
-3.1.2. AIX: Network Connections
-
- [ [175]Top ] [ [176]Contents ] [ [177]Section Contents ] [ [178]Next ]
- [ [179]Previous ]
-
- File transfers into AIX 4.2 or 4.3 through the AIX Telnet or Rlogin
- server have been observed to fail (or accumulate huge numbers of
- correctable errors, or even disconnect the session), when exactly the
- same kind of transfers into AIX 4.1 work without incident, as do such
- transfers into all non-AIX platforms on the same kind of connections
- (with a few exceptions noted elsewhere in this document). AIX 4.3.3
- seems to be particularly fragile in this regard; the weakness seems to
- be in its pseudoterminal (pty) driver. High-speed streaming transfers
- work perfectly, however, if the AIX Telnet server and pty driver are
- removed from the picture; e.g, by using "set host * 3000" on AIX.
-
- The problem can be completely cured by replacing the IBM Telnet server
- with [180]MIT's Kerberos Telnet server -- even if you don't actually
- use the Kerberos part. Diagnosis: AIX pseudoterminals (which are
- controlled by the Telnet server to give you a login terminal for your
- session) have quirks that not even IBM knows about. The situation with
- AIX 5.x is not known, but if it has the same problem, the same cure is
- available.
-
- Meanwhile, the only remedy when going through the IBM Telnet server is
- to cut back on Kermit's performance settings until you find a
- combination that works:
-
- * SET STREAMING OFF
- * SET WINDOW-SIZE small-number
- * SET { SEND, RECEIVE } PACKET-LENGTH small-number
- * SET PREFIXING { CAUTIOUS, ALL }
-
- In some cases, severe cutbacks are required, e.g. those implied by the
- ROBUST command. Also be sure that the AIX C-Kermit on the remote end
- has "set flow none" (which is the default). NOTE: Maybe this one can
- also be addressed by starting AIX telnetd with the "-a" option. The
- situation with SSH connections is not known, but almost certainly the
- same.
-
- When these problems occur, the system error log contains:
-
- LABEL: TTY_TTYHOG
- IDENTIFIER: 0873CF9F
- Type: TEMP
- Resource Name: pts/1
-
- Description
- TTYHOG OVER-RUN
-
- Failure Causes
- EXCESSIVE LOAD ON PROCESSOR
-
- Recommended Actions
- REDUCE SYSTEM LOAD.
- REDUCE SERIAL PORT BAUD RATE
-
- Before leaving the topic of AIX pseudoterminals, it is very likely that
- Kermit's PTY and SSH commands do not work well either, for the same
- reason that Telnet connections into AIX don't work well. A brief test
- with "pty rlogin somehost" got a perfectly usable terminal (CONNECT)
- session, but file-transfer problems like those just described.
-
- Reportedly, telnet from AIX 4.1-point-something to non-Telnet ports
- does not work unless the port number is in the /etc/services file; it's
- not clear from the report whether this is a problem with AIX Telnet (in
- which case it would not affect Kermit), or with the sockets library (in
- which case it would). The purported fix is IBM APAR IX61523.
-
- C-Kermit SET HOST or TELNET from one AIX 3.1 (or earlier) system to
- another won't work right unless you set your local terminal type to
- something other than AIXTERM. When your terminal type is AIXTERM, AIX
- TELNET sends two escapes whenever you type one, and the AIX telnet
- server swallows one of them. This has something to do with the "hft"
- device. This behavior seems to be removed in AIX 3.2 and later.
- ________________________________________________________________________
-
-3.1.3. AIX: Serial Connections
-
- [ [181]Top ] [ [182]Contents ] [ [183]Section Contents ] [ [184]Next ]
- [ [185]Previous ]
-
- In AIX 3, 4, or 5, C-Kermit won't be able to "set line /dev/tty0" (or
- any other dialout device) if you haven't installed "cu" or "uucp" on
- your system, because installing these is what creates the UUCP lockfile
- directory. If SET LINE commands always result in "Sorry, access to lock
- denied", even when C-Kermit has been given the same owner, group, and
- permissions as cu:
-
- -r-sr-xr-x 1 uucp uucp 67216 Jul 27 1999 cu
-
- and even when you run it as root, then you must go back and install
- "cu" from your AIX installation media.
-
- According to IBM's "From Strength to Strength" document (21 April
- 1998), in AIX 4.2 and later "Async supports speeds on native serial
- ports up to 115.2kbps". However, no API is documented to achieve serial
- speeds higher than 38400 bps. Apparently the way to do this -- which
- might or might not work only on the IBM 128-port multiplexer -- is:
-
- cxma-stty fastbaud /dev/tty0
-
- which, according to "man cxma-stty":
-
- fastbaud Alters the baud rate table, so 50 baud becomes 57600 baud.
- -fastbaud Restores the baud rate table, so 57600 baud becomes 50
- baud.
-
- Presumably (but not certainly) this extrapolates to 110 "baud" becomes
- 76800 bps, and 150 becomes 115200 bps. So to use high serial speeds in
- AIX 4.2 or 4.3, the trick would be to give the "cxma-stty fastbaud"
- command for the desired tty device before starting Kermit, and then use
- "set speed 50", "set speed 110", or "set speed 150" to select 56700,
- 76800, or 115200 bps. It is not known whether cxma-stty requires
- privilege.
-
- According to one report, "Further investigation with IBM seems to
- indicate that the only hardware capable of doing this is the 128-port
- multiplexor with one (or more) of the 16 port breakout cables (Enhanced
- Remote Async Node 16-Port EIA-232). We are looking at about CDN$4,000
- in hardware just to hang a 56kb modem on there. Of course, we can then
- hang 15 more, if we want. This hardware combo is described to be good
- to 230.4kbps."
-
- Another report says (quote from AIX newsgroup, March 1999):
-
- The machine type and the adapter determine the speed that one can
- actually run at. The older microchannel machines have much slower
- crystal frequencies and may not go beyond 76,800. A feature put into
- AIX 421 allows one to key in non-POSIX baud rates and if the uart
- can support that speed, it will get set. this applies also to 43p's
- and beyond. 115200 is the max for the 43P's native serial port. As
- crytal frequencies continue to increase, the built-in serial ports
- speeds will improve. To use 'uucp' or 'ate' at the higher baud
- rates, configure the port for the desired speed, but set the speed
- of uucp or ate to 50. Any non-POSIX speeds set in the ttys
- configuration will the be used. In the case of the 128-port adapters
- or the ISA 8-port or PCI 8-port adapter, there are only a few higher
- baud rates.
-
- a. Change the port to enable high baud rates:
- + B50 for 57600
- + B75 for 76800
- + B110 for 115200
- + B200 for 230000
- b. chdev -l ttyX -a fastbaud=enable
- + For the 128 ports original style rans, only 57600 bps is
- supported.
- + For the new enhanced RANs, up to 230Kbps is supported.
-
- In AIX 2.2.1 on the RT PC with the 8-port multiplexer, SET SPEED 38400
- gives 9600 bps, but SET SPEED 19200 gives 19200 (on the built-in S1
- port).
-
- Note that some RS/6000s (e.g. the IBM PowerServer 320) have nonstandard
- rectangular 10-pin serial ports; the DB-25 connector is NOT a serial
- port; it is a parallel printer port. IBM cables are required for the
- serial ports, (The IBM RT PC also had rectangular serial ports --
- perhaps the same as these, perhaps different.)
-
- If you dial in to AIX through a modem that is connected directly to an
- AIX port (e.g. on the 128-port multiplexer) and find that data is lost,
- especially when uploading files to the AIX system (and system error
- logs report buffer overruns on the port):
-
- 1. Make sure the port and modem are BOTH configured for hardware
- (RTS/CTS) flow control. The port is configured somewhere in the
- system configuration, outside of Kermit.
- 2. Tell C-Kermit to "set flow keep"; experimentation shows that SET
- FLOW RTS/CTS has no effect when used in remote mode (i.e. on
- /dev/tty, as opposed to a specify port device).
- 3. Fixes for bugs in the original AIX 4.2 tty (serial i/o) support and
- other AIX bugs are available from IBM at:
- [186]http://service.software.ibm.com/rs6000/
-
- Downloads -> Software Fixes -> Download FixDist gets an application
- for looking up known problems.
-
- Many problems reported with bidirectional terminal lines on AIX 3.2.x
- on the RS/6000. Workaround: don't use bidirectional terminal lines, or
- write a shell-script wrapper for Kermit that turns getty off on the
- line before starting Kermit, or before Kermit attempts to do the SET
- LINE. (But note: These problems MIGHT be fixed in C-Kermit 6.0 and
- later.) The commands for turning getty off and on (respectively) are
- /usr/sbin/pdisable and /usr/sbin/penable.
- ________________________________________________________________________
-
-3.1.4. AIX: File Transfer
-
- [ [187]Top ] [ [188]Contents ] [ [189]Section Contents ] [ [190]Next ]
- [ [191]Previous ]
-
- Evidently AIX 4.3 (I don't know about earlier versions) does not allow
- open files to be overwritten. This can cause Kermit transfers to fail
- when FILE COLLISION is OVERWRITE, where they might work on other Unix
- varieties or earlier AIX versions.
-
- Transfer of binary -- and maybe even text -- files can fail in AIX if
- the AIX terminal has particular port can have character-set translation
- done for it by the tty driver. The following advice from a
- knowledgeable AIX user:
-
- [This feature] has to be checked (and set/cleared) with a separate
- command, unfortunately stty doesn't handle this. To check:
-
- $ setmaps
- input map: none installed
- output map: none installed
-
- If it says anything other than "none installed" for either one, it
- is likely to cause a problem with kermit. To get rid of installed
- maps:
-
- $ setmaps -t NOMAP
-
- However, I seem to recall that with some versions of AIX before
- 3.2.5, only root could change the setting. I'm not sure what
- versions - it might have only been under AIX 3.1 that this was true.
- At least with AIX 3.2.5 an ordinary user can set or clear the maps.
-
- On the same problem, another knowledgeable AIX user says:
-
- The way to get information on the NLS mapping under AIX (3.2.5
- anyway) is as follows. From the command line type:
-
- lsattr -l tty# -a imap -a omap -E -H
-
- Replace the tty number for the number sign above. This will give a
- human readable output of the settings that looks like this;
-
- # lsattr -l tty2 -a imap -a omap -E -H
- attribute value description user_settable
-
- imap none INPUT map file True
- omap none OUTPUT map file True
-
- If you change the -H to a -O, you get output that can easily be
- processed by another program or a shell script, for example:
-
- # lsattr -l tty2 -a imap -a omap -E -O
- #imap:omap
- none:none
-
- To change the settings from the command line, the chdev command is
- used with the following syntax.
-
- chdev -l tty# -a imap='none' -a omap='none'
-
- Again substituting the appropriate tty port number for the number
- sign, "none" being the value we want for C-Kermit. Of course, the
- above can also be changed by using the SMIT utility and selecting
- devices - tty. (...end quote)
-
- In 2007 I noticed the following on high-speed SSH connections (local
- network) into AIX 5.3: streaming transfers into AIX just don't work.
- The same might be true for Telnet connections; I have no way to check.
- It appears that the AIX pty driver and/or the SSH (and possibly Telnet)
- server are not capable of receiving a steady stream of incoming data at
- high speed. Solution: unknown. Workaround: put "set streaming off" in
- your .kermrc or .mykermrc file, since streaming is the default for
- network connections.
- ________________________________________________________________________
-
-3.1.5. AIX: Xterm Key Map
-
- [ [192]Top ] [ [193]Contents ] [ [194]Section Contents ] [
- [195]Previous ]
-
- Here is a sample configuration for setting up an xterm keyboard for
- VT220 or higher terminal emulation on AIX, courtesy of Bruce Momjian,
- Drexel Hill, PA. Xterm can be started like this:
-
- xterm $XTERMFLAGS +rw +sb +ls $@ -tm 'erase ^? intr ^c' -name vt220 \
- -title vt220 -tn xterm-220 "$@" &
-
----------------------------------------------------------------------------
- XTerm*VT100.Translations: #override \n\
- <Key>Home: string(0x1b) string("[3~") \n \
- <Key>End: string(0x1b) string("[4~") \n
- vt220*VT100.Translations: #override \n\
- Shift <Key>F1: string("[23~") \n \
- Shift <Key>F2: string("[24~") \n \
- Shift <Key>F3: string("[25~") \n \
- Shift <Key>F4: string("[26~") \n \
- Shift <Key>F5: string("[K~") \n \
- Shift <Key>F6: string("[31~") \n \
- Shift <Key>F7: string("[31~") \n \
- Shift <Key>F8: string("[32~") \n \
- Shift <Key>F9: string("[33~") \n \
- Shift <Key>F10: string("[34~") \n \
- Shift <Key>F11: string("[28~") \n \
- Shift <Key>F12: string("[29~") \n \
- <Key>Print: string(0x1b) string("[32~") \n\
- <Key>Cancel: string(0x1b) string("[33~") \n\
- <Key>Pause: string(0x1b) string("[34~") \n\
- <Key>Insert: string(0x1b) string("[2~") \n\
- <Key>Delete: string(0x1b) string("[3~") \n\
- <Key>Home: string(0x1b) string("[1~") \n\
- <Key>End: string(0x1b) string("[4~") \n\
- <Key>Prior: string(0x1b) string("[5~") \n\
- <Key>Next: string(0x1b) string("[6~") \n\
- <Key>BackSpace: string(0x7f) \n\
- <Key>Num_Lock: string(0x1b) string("OP") \n\
- <Key>KP_Divide: string(0x1b) string("Ol") \n\
- <Key>KP_Multiply: string(0x1b) string("Om") \n\
- <Key>KP_Subtract: string(0x1b) string("OS") \n\
- <Key>KP_Add: string(0x1b) string("OM") \n\
- <Key>KP_Enter: string(0x1b) string("OM") \n\
- <Key>KP_Decimal: string(0x1b) string("On") \n\
- <Key>KP_0: string(0x1b) string("Op") \n\
- <Key>KP_1: string(0x1b) string("Oq") \n\
- <Key>KP_2: string(0x1b) string("Or") \n\
- <Key>KP_3: string(0x1b) string("Os") \n\
- <Key>KP_4: string(0x1b) string("Ot") \n\
- <Key>KP_5: string(0x1b) string("Ou") \n\
- <Key>KP_6: string(0x1b) string("Ov") \n\
- <Key>KP_7: string(0x1b) string("Ow") \n\
- <Key>KP_8: string(0x1b) string("Ox") \n\
- <Key>KP_9: string(0x1b) string("Oy") \n
-
- ! <Key>Up: string(0x1b) string("[A") \n\
- ! <Key>Down: string(0x1b) string("[B") \n\
- ! <Key>Right: string(0x1b) string("[C") \n\
- ! <Key>Left: string(0x1b) string("[D") \n\
-
- *visualBell: true
- *saveLines: 1000
- *cursesemul: true
- *scrollKey: true
- *scrollBar: true
-
-3.2. C-KERMIT AND HP-UX
-
- [ [196]Top ] [ [197]Contents ] [ [198]Section Contents ] [ [199]Next ]
- [ [200]Previous ]
-
- SECTION CONTENTS
-
- 3.2.0. [201]Common Problems
- 3.2.1. [202]Building C-Kermit on HP-UX
- 3.2.2. [203]File Transfer
- 3.2.3. [204]Dialing Out and UUCP Lockfiles in HP-UX
- 3.2.4. [205]Notes on Specific HP-UX Releases
- 3.2.5. [206]HP-UX and X.25
-
- REFERENCES
-
- For further information, read the [207]comp.sys.hp.hpux newsgroup.
-
- C-Kermit is included as part of the HP-UX operating system by contract
- between Hewlett Packard and Columbia University for HP-UX 10.00 and
- later. Each level of HP-UX includes a freshly built C-Kermit binary in
- /bin/kermit, which should work correctly. Binaries built for regular
- HP-UX may be used on Trusted HP-UX and vice-versa, except for use as
- IKSD because of the different authentication methods.
-
- Note that HP does not update C-Kermit versions for any but its most
- current HP-UX release. So, for example, HP-UX 10.20 has C-Kermit 6.0;
- 11.00 has C-Kermit 7.0, and 11.22 has 8.0. Of course, as with all
- software, older Kermit versions have bugs (such as buffer overflow
- vulnerabilities) that are fixed in later versions. From time to time,
- HP discovers one of these (long-ago fixed) bugs and issues a security
- alert for the older OS's, recommending some draconian measure to avoid
- the problem. The true fix in each situation is to install the current
- release of C-Kermit.
-
-3.2.0. Common Problems
-
- [ [208]Top ] [ [209]Contents ] [ [210]Section Contents ] [ [211]Next ]
-
- Some HP workstations have a BREAK/RESET key. If you hit this key while
- C-Kermit is running, it might kill or suspend the C-Kermit process.
- C-Kermit arms itself against these signals, but evidently the
- BREAK/RESET key is -- at least in some circumstances, on certain HP-UX
- versions -- too powerful to be caught. (Some report that the first
- BREAK/RESET shows up as SIGINT and is caught by C-Kermit's former
- SIGINT handler even when SIGINT is currently set to SIG_IGN; the second
- kills Kermit; other reports suggest the first BREAK/RESET sends a
- SIGTSTP (suspend signal) to Kermit, which it catches and suspends
- itself. You can tell C-Kermit to ignore suspend signals with SET
- SUSPEND OFF. You can tell C-Kermit to ignore SIGINT with SET COMMAND
- INTERRUPTION OFF. It is not known whether these commands also grant
- immunity to the BREAK/RESET key (one report states that with SET
- SUSPEND OFF, the BREAK/RESET key is ignored the first four times, but
- kills Kermit the 5th time). In any case:
-
- 1. If this key is mapped to SIGINT or SIGTSTP, C-Kermit catches or
- ignores it, depending on which mode (CONNECT, command, etc) Kermit
- is in.
- 2. If it causes HP-UX to kill C-Kermit, there is nothing C-Kermit can
- do to prevent it.
-
- When HP-UX is on the remote end of the connection, it is essential that
- HP-UX C-Kermit be configured for Xon/Xoff flow control (this is the
- default, but in case you change it and then experience file-transfer
- failures, this is a likely reason).
-
-3.2.1. Building C-Kermit on HP-UX
-
- [ [212]Top ] [ [213]Contents ] [ [214]Section Contents ] [ [215]Next ]
- [ [216]Previous ]
-
- This section applies mainly to old (pre-10.20) HP-UX version on old,
- slow, and/or memory-constrained hardware.
-
- During the C-Kermit 6.0 Beta cycle, something happened to ckcpro.w (or,
- more precisely, the ckcpro.c file that is generated from it) which
- causes HP optimizing compilers under HP-UX versions 7.0 and 8.0
- (apparently on all platforms) as well as under HP-UX 9.0 on Motorola
- platforms only, to blow up. In versions 7.0 and 8.0 the problem has
- spread to other modules.
-
- The symptoms vary from the system grinding to a halt, to the compiler
- crashing, to the compilation of the ckcpro.c module taking very long
- periods of time, like 9 hours. This problem is handled by compiling the
- modules that tickle it without optimization; the new C-Kermit makefile
- takes care of this, and shows how to do it in case the same thing
- begins happening with other modules.
-
- On HP-UX 9.0, a kernel parameter, maxdsiz (maximum process data segment
- size), seems to be important. On Motorola systems, it is 16MB by
- default, whereas on RISC systems the default is much bigger. Increasing
- maxdsiz to about 80MB seems to make the problem go away, but only if
- the system also has a lot of physical memory -- otherwise it swaps
- itself to death.
-
- The optimizing compiler might complain about "some optimizations
- skipped" on certain modules, due to lack of space available to the
- optimizer. You can increase the space (the incantation depends on the
- particular compiler version -- see the [217]makefile), but doing so
- tends to make the compilations take a much longer time. For example,
- the "hpux0100o+" makefile target adds the "+Onolimit" compiler flag,
- and about an hour to the compile time on an HP-9000/730. But it *does*
- produce an executable that is about 10K smaller :-)
-
- In the makefile, all HP-UX entries automatically skip optimization of
- problematic modules.
-
-3.2.2. File Transfer
-
- [ [218]Top ] [ [219]Contents ] [ [220]Section Contents ] [ [221]Next ]
- [ [222]Previous ]
-
- Telnet connections into HP-UX versions up to and including 11.11 (and
- possibly 11.20) tend not to lend themselves to file transfer due to
- limitations, restrictions, and/or bugs in the HP-UX Telnet server
- and/or pseudoterminal (pty) driver.
-
- In C-Kermit 6.0 (1996) an unexpected slowness was noted when
- transferring files over local Ethernet connections when an HP-UX system
- (9.05 or 10.00) was on the remote end. The following experiment was
- conducted to determine the cause. C-Kermit 6.0 was used; the situation
- is slightly better using C-Kermit 7.0's streaming feature and HP-UX
- 10.20 on the far end.
-
- The systems were HP-UX 10.00 (on 715/33) and SunOS 4.1.3 (on Sparc-20),
- both on the same local 10Mbps Ethernet, packet length 4096, parity
- none, control prefixing "cautious", using only local disks on each
- machine -- no NFS. In the C-Kermit 6.0 (ACK/NAK) case, the window size
- was 20; in the streaming case there is no window size (i.e. it is
- infinite). The test file was C-Kermit executable, transferred in binary
- mode. Conditions were relatively poor: the Sun and the local net
- heavily loaded; the HP system is old, slow, and memory-constrained.
-
- C-Kermit 6.0... C-Kermit 7.0...
- Local Remote ACK/NAK........ Streaming......
- Client Server Send Receive Send Receive
- Sun HP 36 18 64 18
- HP HP 25 15 37 16
- HP Sun 77 83 118 92
- Sun Sun 60 60 153 158
-
- So whenever HP is the remote we have poor performance. Why?
-
- * Changing file display to CRT has no effect (so it's not the curses
- library on the client side).
- * Changing TCP RECV-BUFFER or SEND-BUFFER has little effect.
- * Telling the client to make a binary-mode connection (SET TELNET
- BINARY REQUESTED, which successfully negotiates a binary
- connection) has no effect on throughput.
-
- BUT... If I start HP-UX C-Kermit as a TCP service:
-
- set host * 3000
- server
-
- and then from the client "set host xxx 3000", I get:
-
- C-Kermit 6.0... C-Kermit 7.0...
- Local Remote ACK/NAK........ Streaming......
- Client Server Send Receive Send Receive
- Sun HP 77 67 106 139
- HP HP 50 50 64 62
- HP Sun 57 85 155 105
- Sun Sun 57 50 321 314
-
- Therefore the HP-UX telnet server or pty driver seems to be adding more
- overhead than the SunOS one, and most others. When going through this
- type of connection (a remote telnet server) there is little Kermit can
- do improve matters, since the telnet server and pty driver are between
- the two Kermits, and neither Kermit program can have any influence over
- them (except putting the Telnet connection in binary mode, but that
- doesn't help).
-
- (The numbers for the HP-HP transfers are lower than the others since
- both Kermit processes are running on the same slow 33MHz CPU.)
-
- Matters seem to have deteriorated in HP-UX 11. Now file transfers over
- Telnet connections fail completely, rather than just being slow. In the
- following trial, a Telnet connection was made from Kermit 95 to HP-UX
- 11.11 on an HP-9000/785/B2000 over local 10Mbps Ethernet running
- C-Kermit 8.00 in server mode (under the HP-UX Telnet server):
-
- Text........ Binary......
- Stream Pktlen GET SEND GET SEND
- On 4000 Fail Fail Fail Fail
- Off 4000 Fail Fail Fail Fail
- Off 2000 OK Fail OK Fail
- On 2000 OK Fail OK Fail
- On 3000 Fail Fail Fail Fail
- On 2500 Fail Fail Fail Fail
- On 2047 OK Fail OK Fail
- On 2045 OK Fail OK Fail
- Off 500 OK OK OK OK
- On 500 OK Fail OK Fail
- On 240 OK Fail OK Fail
-
- As you can see, downloads are problematic unless the receiver's Kermit
- packet length is 2045 or less, but uploads work only with streaming
- disabled and the packet length restricted to 500. To force file
- transfers to work on this connection, the desktop Kermit must be told
- to:
-
- set streaming off
- set receive packet-length 2000
- set send packet-length 500
-
- However, if a connection is made between the same two programs on the
- same two computers over the same network, but this time a direct
- socket-to-socket connection bypassing the HP-UX Telnet server and pty
- driver (tell HP-UX C-Kermit to "set host /server * 3000 /raw"; tell
- desktop client program to "set host blah 3000 /raw"), everything works
- perfectly with the default Kermit settings (streaming, 4K packets,
- liberal control-character unprefixing, 8-bit transparency, etc):
-
- Text........ Binary......
- Stream Pktlen GET SEND GET SEND
- On 4000 OK OK OK OK
-
- And in this case, transfer rates were approximately 900,000 cps. To
- verify that the behavior reported here is not caused by the new Kermit
- release, the same experiment was performed on a Telnet connection from
- the same PC over the same network to the old 715/33 running HP-UX 10.20
- and C-Kermit 8.00. Text and binary uploads and downloads worked
- perfectly (albeit slowly) with all the default settings -- streaming,
- 4K packets, etc.
-
-3.2.3. Dialing Out and UUCP Lockfiles in HP-UX
-
- [ [223]Top ] [ [224]Contents ] [ [225]Section Contents ] [ [226]Next ]
- [ [227]Previous ]
-
- HP workstations do not come with dialout devices configured; you have
- to do it yourself (as root). First look in /dev to see what's there;
- for example in HP-UX 10.00 or later:
-
- ls -l /dev/cua*
- ls -l /dev/tty*
-
- If you find a tty0p0 device but no cua0p0, you'll need to creat one if
- you want to dial out; the tty0p0 does not work for dialing out. It's
- easy: start SAM; in the main Sam window, double-click on Peripheral
- Device, then in the Peripheral Devices window, double-click on
- Terminals and Modems. In the Terminals and Modems dialog, click on
- Actions, then choose "Add modem" and fill in the blanks. For example:
- Port number 0, speed 57600 (higher speeds tend not to work reliably),
- "Use device for calling out", do NOT "Receive incoming calls" (unless
- you know what you are doing), leave "CCITT modem" unchecked unless you
- really have one, and do select "Use hardware flow control (RTS/CTS)".
- Then click OK. This creates cua0p0 as well as cul0p0 and ttyd0p0
-
- If the following sequence:
-
- set line /dev/cua0p0 ; or other device
- set speed 115200 ; or other normal speed
-
- produces the message "?Unsupported line speed". This means either that
- the port is not configured for dialout (go into SAM as described above
- and make sure "Use device for calling out" is selected), or else that
- speed you have given (such as 460800) is supported by the operating
- system but not by the physical device (in which case, use a lower speed
- like 57600).
-
- In HP-UX 9.0, serial device names began to change. The older names
- looked like "/dev/cua00", "/dev/tty01", etc (sometimes with only one
- digit). The newer names have two digits with the letter "p" in between.
- HP-UX 8.xx and earlier have the older form, HP-UX 10.00 and later have
- the newer form. HP-UX 9.xx has the newer form on Series 800 machines,
- and the older form on other hardware models. The situation is
- summarized in the following table (the Convio 10.0 column applies to
- HP-UX 10 and 11).
-
- Converged HP-UX Serial I/O Filenames : TTY Mux Naming
- ---------------------------------------------------------------------
- General meaning Old Form S800 9.0 Convio 10.0
- ---------------------------------------------------------------------
- tty* hardwired ports tty<YY> tty<X>p<Y> tty<D>p<p>
- diag:mux<X> diag:mux<D>
- ---------------------------------------------------------------------
- ttyd* dial-in modems ttyd<YY> ttyd<X>p<Y> ttyd<D>p<p>
- diag:ttyd<X>p<Y> diag:ttyd<D>p<p>
- ---------------------------------------------------------------------
- cua* auto-dial out cua<YY> cua<X>p<Y> cua<D>p<p>
- diag:cua<X>p<Y>
- ---------------------------------------------------------------------
- cul* dial-out cul<YY> cul<X>p<Y> cul<D>p<p>
- diag:cul<X>p<Y>
- ---------------------------------------------------------------------
- <X>= LU (Logical Unit) <D>= Devspec (decimal card instance)
- <Y> or <YY> = Port <p>= Port
-
- For dialing out, you should use the cua or cul devices. When C-Kermit's
- CARRIER setting is AUTO or ON, C-Kermit should pop back to its prompt
- automatically if the carrier signal drops, e.g. when you log out from
- the remote computer or service. If you use the tty<D>p<d> (e.g. tty0p0)
- device, the carrier signal should be ignored. The tty<D>p<d> device
- should be used for direct connections where the carrier signal does not
- follow RS-232 conventions (use the cul device for hardwired connections
- through a true null modem). Do not use the ttyd<D>p<d> device for
- dialing out.
-
- Kermit's access to serial devices is controlled by "UUCP lockfiles",
- which are intended to prevent different users using different software
- programs (Kermit, cu, etc, and UUCP itself) from accessing the same
- serial device at the same time. When a device is in use by a particular
- user, a file with a special name is created in:
-
- /var/spool/locks (HP-UX 10.00 and later)
- /usr/spool/uucp (HP-UX 9.xx and earlier)
-
- The file's name indicates the device that is in use, and its contents
- indicates the process ID (pid) of the process that is using the device.
- Since serial devices and the locks directory are not both publicly
- readable and writable, Kermit and other communication software must be
- installed setuid to the owner (bin) of the serial device and setgid to
- the group (daemon) of the /var/spool/locks directory. Kermit's setuid
- and setgid privileges are enabled only when opening the device and
- accessing the lockfiles.
-
- Let's say "unit" means a string of decimal digits (the interface
- instance number) followed (in HP-UX 10.00 and later) by the letter "p"
- (lowercase), followed by another string of decimal digits (the port
- number on the interface), e.g.:
-
- "0p0", "0p1", "1p0", etc (HP-UX 10.00 and later)
- "0p0", "0p1", "1p0", etc (HP-UX 9.xx on Series 800)
- "00", "01", "10", "0", etc (HP-UX 9.xx not on Series 800)
- "00", "01", "10", "0", etc (HP-UX 8.xx and earlier)
-
- Then a normal serial device (driver) name consists of a prefix ("tty",
- "ttyd", "cua", "cul", or possibly "cuad" or "culd") followed by a unit,
- e.g. "cua0p0". Kermit's treatment of UUCP lockfiles is as close as
- possible to that of the HP-UX "cu" program. Here is a table of the
- lockfiles that Kermit creates for unit 0p0:
-
- Selection Lockfile 1 Lockfile 2
- /dev/tty0p0 LCK..tty0p0 (none)
-* /dev/ttyd0p0 LCK..ttyd0p0 (none)
- /dev/cua0p0 LCK..cua0p0 LCK..ttyd0p0
- /dev/cul0p0 LCK..cul0p0 LCK..ttyd0p0
- /dev/cuad0p0 LCK..cuad0p0 LCK..ttyd0p0
- /dev/culd0p0 LCK..culd0p0 LCK..ttyd0p0
- <other> LCK..<other> (none)
-
- (* = Dialin device, should not be used.)
-
- In other words, if the device name begins with "cu", a second lockfile
- for the "ttyd" device, same unit, is created, which should prevent
- dialin access on that device.
-
- The <other> case allows for symbolic links, etc, but of course it is
- not foolproof since we have no way of telling which device is really
- being used.
-
- When C-Kermit tries to open a dialout device whose name ends with a
- "unit", it searches the lockfile directory for all possible names for
- the same unit. For example, if user selects /dev/cul2p3, Kermit looks
- for lockfiles named:
-
- LCK..tty2p3
- LCK..ttyd2p3
- LCK..cua2p3
- LCK..cul2p3
- LCK..cuad2p3
- LCK..culd2p3
-
- If any of these files are found, Kermit opens them to find out the ID
- (pid) of the process that created them; if the pid is still valid, the
- process is still active, and so the SET LINE command fails and the user
- is informed of the pid so s/he can use "ps" to find out who is using
- the device.
-
- If the pid is not valid, the file is deleted. If all such files (i.e.
- with same "unit" designation) are successfully removed, then the SET
- LINE command succeeds; up to six messages are printed telling the user
- which "stale lockfiles" are being removed.
-
- When the "set line" command succeeds in HP-UX 10.00 and later, C-Kermit
- also creates a Unix System V R4 "advisory lock" as a further precaution
- (but not guarantee) against any other process obtaining access to the
- device while you are using it.
-
- If the selected device was in use by "cu", Kermit can't open it,
- because "cu" has changed its ownership, so we never get as far as
- looking at the lockfiles. In the normal case, we can't even look at the
- device to see who the owner is because it is visible only to its
- (present) owner. In this case, Kermit says (for example):
-
- /dev/cua0p0: Permission denied
-
- When Kermit releases a device it has successfully opened, it removes
- all the lockfiles that it created. This also happens whenever Kermit
- exits "under its own power".
-
- If Kermit is killed with a device open, the lockfile(s) are left
- behind. The next Kermit program that tries to assign the device, under
- any of its various names, will automatically clean up the stale
- lockfiles because the pids they contain are invalid. The behavior of cu
- and other communication programs under these conditions should be the
- same.
-
- Here, by the way, is a summary of the differences between the HP-UX
- port driver types from John Pezzano of HP:
-
- There are three types of device files for each port.
-
- The ttydXXX device file is designed to work as follows:
-
- 1. The process that opens it does NOT get control of the port until CD
- is asserted. This was intentional (over 15 years ago) to allow
- getty to open the port but not control it until someone called in.
- If a process wants to use the direct or callout device files
- (ttyXXX and culXXX respectively), they will then get control and
- getty would be blocked. This eliminated the need to use uugetty
- (and its inherent problems with lock files) for modems. You can see
- this demonstrated by the fact that "ps -ef" shows a ? in the tty
- column for the getty process as getty does not have the port yet.
- 2. Once CD is asserted, the port is controlled by getty (or the
- process handling an incoming call) if there was no process using
- the port. The ? in the "ps" command now shows the port. At this
- point, the port accepts data.
-
- Therefore you should use either the callout culXXX device file
- (immediate control but no data until CD is asserted) or the direct
- device file ttyXXX which gives immediate control and immediate data
- and which ignores by default modem control signals.
-
- The ttydXXX device should be used only for callin and my
- recommendation is to use it only for getty and uugetty.
-
-3.2.4 Notes on Specific HP-UX Releases
-
- SECTION CONTENTS
-
- 3.2.4.1. [228]HP-UX 11
- 3.2.4.2. [229]HP-UX 10
- 3.2.4.3. [230]HP-UX 9
- 3.2.4.4. [231]HP-UX 8
- 3.2.4.5. [232]HP-UX 7 and Earlier
-
-3.2.4.1. HP-UX 11
-
- [ [233]Top ] [ [234]Contents ] [ [235]Section Contents ] [ [236]Next ]
-
- As noted in [237]Section 3.2.2, the HP-UX 11 Telnet server and/or
- pseudoterminal driver are a serious impediment to file transfer over
- Telnet connections into HP-UX. If you have a Telnet connection into
- HP-UX 11, tell your desktop Kermit program to:
-
- set streaming off
- set receive packet-length 2000
- set send packet-length 500
-
- File transfer speeds over connections from HP-UX 11 (dialed or Telnet)
- are not impeded whatsoever, and can go at whatever speed is allowed by
- the connection and the Kermit partner on the far end.
-
- PA-RISC binaries for HP-UX 10.20 or later should run on any PA-RISC
- system, S700 or S800, as long as the binary was not built under a later
- HP-UX version than the host operating system. HP-UX 11.00 and 11.11 are
- only for PA-RISC systems. HP-UX 11.20 is only for IA64 (subsequent
- HP-UX releases will be for both PA-RISC and IA64). To check binary
- compatibility, the following C-Kermit 8.0 binaries were run
- successfully on an HP-9000/785 with HP-UX 11.11:
-
- * Model 7xx HP-UX 10.20
- * Model 8xx HP-UX 10.20
- * Model 7xx HP-UX 11.00
- * Model 8xx HP-UX 11.00
- * Model 7xx HP-UX 11.11
- * Model 8xx HP-UX 11.11
-
- Binaries built under some of the earlier HP-UX releases, such as 9.05,
- might also work, but only if built for the same hardware family (e.g.
- s700).
-
-3.2.4.2. HP-UX 10
-
- [ [238]Top ] [ [239]Contents ] [ [240]Section Contents ] [ [241]Next ]
- [ [242]Previous ]
-
- Beginning in HP-UX 10.10, libcurses is linked to libxcurses, the new
- UNIX95 (X/Open) version of curses, which has some serious bugs; some
- routines, when called, would hang and never return, some would dump
- core. Evidently libxcurses contains a select() routine, and whenever
- C-Kermit calls what it thinks is the regular (sockets) select(), it
- gets the curses one, causing a segmentation fault. There is a patch for
- this from HP, PHCO_8086, "s700_800 10.10 libcurses patch", "shared lib
- curses program hangs on 10.10", "10.10 enhanced X/Open curses core
- dumps due to using wrong select call", 96/08/02 (you can tell if the
- patch is installed with "what /usr/lib/libxcurses.1"; the unpatched
- version is 76.20, the patched one is 76.20.1.2). It has been verified
- that C-Kermit works OK with the patched library, but results are not
- definite for HP-UX 10.20 or higher.
-
- To ensure that C-Kermit works even on non-patched HP-UX 10.10 systems,
- separate makefile entries are provided for HP-UX 10.00/10.01, 10.10,
- 10.20, etc, in which the entries for 10.10 and above link with
- libHcurses, which is "HP curses", the one that was used in 10.00/10.01.
- HP-UX 11.20 and later, however, link with libcurses, as libHcurses
- disappeared in 11.20.
-
-3.2.4.3. HP-UX 9
-
- [ [243]Top ] [ [244]Contents ] [ [245]Section Contents ] [ [246]Next ]
- [ [247]Previous ]
-
- HP-UX 9.00 and 9.01 need patch PHNE_10572 (note: this replaces
- PHNE_3641) for hptt0.o, asio0.o, and ttycomn.o in libhp-ux.a. Contact
- Hewlett Packard if you need this patch. Without it, the dialout device
- (tty) will be hung after first use; subsequent attempts to use will
- return an error like "device busy". (There are also equivalent patches
- for s700 9.03 9.05 9.07 (PHNE_10573) and s800 9.00 9.04 (PHNE_10416).
-
- When C-Kermit is in server mode, it might have trouble executing REMOTE
- HOST commands. This problem happens under HP-UX 9.00 (Motorola) and
- HP-UX 9.01 (RISC) IF the C-Shell is the login shell AND with the
- C-Shell Revision 70.15. Best thing is to install HP's Patch PHCO_4919
- for Series 300/400 and PHCO_5015 for the Series 700/800. PHCO_5015 is
- called "s700_800 9.X cumulative csh(1) patch with memory leak fix"
- which works for HP-UX 9.00, 9.01, 9.03, 9.04, 9.05 and 9.07. At least
- you need C-Shell Revision 72.12!
-
- C-Kermit works fine -- including its curses-based file-transfer display
- -- on the console terminal, in a remote session (e.g. when logged in to
- the HP 9000 on a terminal port or when telnetted or rlogin'd), and in
- an HP-VUE hpterm window or an xterm window.
-
-3.2.4.4. HP-UX 8
-
- [ [248]Top ] [ [249]Contents ] [ [250]Section Contents ] [ [251]Next ]
- [ [252]Previous ]
-
- To make C-Kermit work on HP-UX 8.05 on a model 720, obtain and install
- HP-UX patch PHNE_0899. This patch deals with a lot of driver issues,
- particularly related to communication at higher speeds.
-
- One user reports:
-
- On HP-UX 8 DON'T install 'tty patch' PHKL_4656, install PHKL_3047
- instead! Yesterday I tried this latest tty patch PHKL_4656 and had
- terrible problems. This patch should fix RTS/CTS problems. With text
- transfer all looks nice. But when I switched over to binary files
- the serial interface returned only rubish to C-Kermit. All sorts of
- protocol, CRC and packed errors I had. After several tests and after
- uninstalling that patch, all transfers worked fine. MB's of data
- without any errors. So keep your fingers away from that patch. If
- anybody needs the PHKL_3047 patch I have it here. It is no longer
- available from HP's patch base.
-
-3.2.4.5. HP-UX 7 and Earlier
-
- [ [253]Top ] [ [254]Contents ] [ [255]Section Contents ] [
- [256]Previous ]
-
- When transferring files into HP-UX 5 or 6 over a Telnet connection, you
- must not use streaming, and you must not use a packet length greater
- than 512. However, you can use streaming and longer packets when
- sending files from HP-UX on a Telnet connection. In C-Kermit 8.0, the
- default receive packet length for HP-UX 5 and 6 was changed to 500 (but
- you can still increase it with SET RECEIVE PACKET-LENGTH if you wish,
- e.g. for non-Telnet connections). Disable streaming with SET STREAMING
- OFF.
-
- The HP-UX 5.00 version of C-Kermit does not include the fullscreen
- file-transfer because of problems with the curses library.
-
- If HP-UX 5.21 with Wollongong TCP/IP is on the remote end of a Telnet
- connection, streaming transfers to HP-UX invariably fail. Workaround:
- SET STREAMING OFF. Packets longer than about 1000 should not be used.
- Transfers from these systems, however, can use streaming and/or longer
- packets.
-
- Reportedly, "[there is] a bug in C-Kermit using HP-UX version 5.21 on
- the HP-9000 series 500 computers. It only occurs when the controlling
- terminal is using an HP-27140 six-port modem mux. The problem is not
- present if the controlling terminal is logged into an HP-27130
- eight-port mux. The symptom is that just after dialing successfully and
- connecting Kermit locks up and the port is unusable until both forks of
- Kermit and the login shell are killed." (This report predates C-Kermit
- 6.0 and might no longer apply.)
-
-3.2.5. HP-UX and X.25
-
- [ [257]Top ] [ [258]Contents ] [ [259]Section Contents ] [
- [260]Previous ]
-
- Although C-Kermit presently does not include built-in support for HP-UX
- X.25 (as it does for the Sun and IBM X.25 products), it can still be
- used to make X.25 connections as follows: start Kermit and then telnet
- to localhost. After logging back in, start padem as you would normally
- do to connect over X.25. Padem acts as a pipe between Kermit and X.25.
- In C-Kermit 7.0, you might also be able to avoid the "telnet localhost"
- step by using:
-
- C-Kermit> pty padem address
-
- This works if padem uses standard i/o (who knows?).
-
-3.3. C-KERMIT AND LINUX
-
- [ [261]Top ] [ [262]Contents ] [ [263]Section Contents ] [ [264]Next ]
- [ [265]Previous ]
-
- SECTION CONTENTS
-
- 3.3.1. [266]Problems Building C-Kermit for Linux
- 3.3.2. [267]Problems with Serial Devices in Linux
- 3.3.3. [268]Terminal Emulation in Linux
- 3.3.4. [269]Dates and Times
- 3.3.5. [270]Startup Errors
- 3.3.6. [271]The Fullscreen File Transfer Display
-
- (August 2010) Reportedly C-Kermit packages for certain Linux
- distributions such as Centos and Ubuntu have certain features
- disabled, for example the SSH command, SET HOST PTY /SSH, and
- perhaps anything else to do with SSH and/or pseudoterminals and who
- knows what else. If you download the regular package ("tarball")
- from the Kermit Project and build from it ("make linux"), everything
- is fine.
-
- C-Kermit in Ubuntu 10.04 and 9.10 was reported slow to start because
- it was trying to resolve the IP address 255.255.255.255. Later, also
- in recent Debian versions. The following is seen in the strace:
-
-write(3, "RESOLVE-ADDRESS 255.255.255.255\n", 32)
-
- This is not Kermit Project code. Turns out to be something in
- glibc's resolver, and can be fixed by changing /etc/nsswitch.conf,
- but it might break other software, such as [272]Avahi or anything
- (such as Gnome, Java, or Cups) that depends on it. I'm not sure
- where it happens; I don't think Kermit tries to get its IP address
- at startup time, only when it's needed or asked for, e.g. when
- making a connection or evaluating \v(ipaddress).
-
- REFERENCES
-
- For further information, read the [273]comp.os.linux.misc,
- [274]comp.os.linux.answers, and other Linux-oriented newsgroups, and
- see:
-
- The Linux Document Project (LDP)
- [275]http://www.tldp.org/
-
- The Linux FAQ
- [276]http://www.tldp.org/FAQ/Linux-FAQ.html
-
- The Linux HOWTOs (especially the Serial HOWTO)
-
- [277]http://www.tldp.org/HOWTO/Serial-HOWTO.html
-
- [278]http://tldp.org/HOWTO/Modem-HOWTO.html
-
- [279]ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO
-
- [280]ftp://tsx-11.mit.edu/pub/linux/docs/HOWTO
-
- [281]http://www.tldp.org/HOWTO/
-
- [282]http://www.tldp.org/hmirrors.html
-
- Linux Vendor Tech Support Pages:
-
- [283]http://www.redhat.com/apps/support/
-
- [284]http://www.debian.org/support
-
- [285]http://www.slackware.com/support/
-
- [286]http://www.caldera.com/support/
-
- [287]SUSE Linux Support
-
- [288]http://www.mandrake.com/support/
-
- [289]http://www.turbolinux.com/support/
-
- Linux Winmodem Support
- [290]http://www.linmodems.org/
-
- Also see general comments on PC-based Unixes in [291]Section 3.0.
-
- What Linux version is it? -- "uname -a" supplies only kernel
- information, but these days it's the distribution that matters: Red Hat
- 7.3, Debian 2.2, Slackware 8.0, etc. Unfortunately there's no
- consistent way to get the distribution version. Usually it's in a
- distribution-specific file:
-
- Red Hat: /etc/issue or /etc/redhat-release
- Debian: /etc/debian_version
- Slackware: /etc/slackware-version (at least in later versions)
-
- Did you know: DECnet is available for Linux? See:
-
- [292]http://linux.dreamtime.org/decnet/
-
- (But there is no support for it in C-Kermit -- anybody interested in
- adding it, please [293]let me know).
-
- Before proceeding, let's handle the some of the most frequently asked
- question in the Linux newsgroups:
-
- 1. Neither C-Kermit nor any other Linux application can use Winmodems,
- except in the [294]rare cases where Linux drivers have been written
- for them. See [295]Section 3.0.2 for details.
- 2. "Why does it take such a long time to make a telnet connection to
- (or from) my Linux PC?" (this applies to C-Kermit and to regular
- Telnet). Most telnet servers these days perform reverse DNS lookups
- on the client (for security and/or logging reasons). If the Telnet
- client's address cannot be found by the server's local DNS server,
- the DNS request goes out to the Internet at large, and this can
- take quite some time. The solution to this problem is to make sure
- that both client and host are registered in DNS, and that the
- registrations are exported. C-Kermit itself performs reverse DNS
- lookups unless you tell it not to; this is to allow C-Kermit to let
- you know which host it is actually connected to in case you have
- made a connection to a host pool (multihomed host). You can disable
- C-Kermit's reverse DNS lookup with SET TCP REVERSE-DNS-LOOKUP OFF.
- 3. (Any question that has the word "Telnet" in it...) The knee-jerk
- reaction is "don't use Telnet, use SSH!" There's nothing wrong with
- Telnet. In fact it's far superior to SSH as a protocol in terms of
- features and extensibility, not to mention platform neutrality. The
- issue lurking behind the knee-jerk reaction is security. SSH is
- thought to be secure, whereas Telnet is thought to be insecure.
- This is true for clear-text Telnet (because passwords travel in the
- clear across the network), but apparently few people realize that
- [296]secure Telnet clients and servers have been available for
- years, and these are more secure than SSH (for reasons explained
- [297]HERE).
- 4. (Any question that has the word "FTP" in it...) The knee-jerk
- reaction being "Don't use FTP, use SCP!" (or SFTP). Same answer as
- above, but moreso. SCP and SFTP are not only not platform neutral,
- they're diversity-hostile. They transfer files only in binary mode,
- which mangles text files across different platforms, to the same
- degree the platform's text-file record format and character set
- differ. An extreme example would be an Variable-Block format EBCDIC
- text file on an IBM mainframe, binary transfer of which to Unix
- would do you little good indeed. FTP was designed with diversity in
- mind and secure versions are available.
-
-3.3.1. Problems Building C-Kermit for Linux
-
- [ [298]Top ] [ [299]Contents ] [ [300]Section Contents ] [ [301]Next ]
-
- Modern Linux distributions like Red Hat give you a choice at
- installation whether to include "developer tools". Obviously, you can't
- build C-Kermit or any other C program from source code if you have not
- installed the developer tools. But to confuse matters, you might also
- have to choose (separately) to install the "curses" or "ncurses"
- terminal control library; thus it is possible to install the C compiler
- and linker, but omit the (n)curses library and headers. If curses is
- not installed, you will not be able to build a version of C-Kermit that
- supports the fullscreen file-transfer display, in which case you'll
- need to use the "linuxnc" makefile target (nc = No Curses) or else
- install ncurses before building.
-
- There are all sorts of confusing issues caused by the many and varied
- Linux distributions. Some of the worst involve the curses library and
- header files: where are they, what are they called, which ones are they
- really? Other vexing questions involve libc5 vs libc6 vs glibc vs
- glibc2 (C libraries), gcc vs egcs vs lcc (compilers), plus using or
- avoiding features that were added in a certain version of Linux or a
- library or a distribution, and are not available in others. As of
- C-Kermit 8.0, these questions should be resolved by the "linux"
- makefile target itself, which does a bit of looking around to see
- what's what, and then sets the appropriate CFLAGS.
-
-3.3.2. Problems with Serial Devices in Linux
-
- [ [302]Top ] [ [303]Contents ] [ [304]Section Contents ] [ [305]Next ]
- [ [306]Previous ]
-
- Also see: "man setserial", "man irqtune".
- And: [307]Sections 3.0, [308]6, [309]7, and [310]8 of this document.
-
- NOTE: Red Hat Linux 7.2 and later include a new API that allows
- serial-port arbitration by non-setuid/gid programs. This API has not
- yet been added to C-Kermit. If C-Kermit is to be used for dialing
- out on Red Hat 7.2 or later, it must still be installed as described
- in in Sections [311]10 and [312]11 of the [313]Installation
- Instructions.
-
- Don't expect it to be easy. Queries like the following are posted to
- the Linux newsgroups almost daily:
-
- Problem of a major kind with my Compaq Presario 1805 in the sense
- that the pnpdump doesn't find the modem and the configuration tells
- me that the modem is busy when I set everything by hand!
-
- I have <some recent SuSE distribution>, kernel 2.0.35. Using the
- Compaq tells me that the modem (which is internal) is on COM2, with
- the usual IRQ and port numbers. Running various Windows diagnostics
- show me AT-style commands exchanged so I have no reason to believe
- that it is a Winmodem. Also, the diagnostics under Win98 tell me
- that I am talking to an NS 16550AN.
-
- [Editor's note: This does not necessarily mean it isn't a Winmodem.]
-
- Under Linux, no joy trying to talk to the modem on /dev/cua1 whether
- via minicom, kppp, or chat; kppp at least tells me that tcgetattr()
- failed.
-
- Usage of setserial:
-
- setserial /dev/cua1 port 0x2F8 irq 3 autoconfig
- setserial -g /dev/cua1
-
- tells me that the uart is 'unknown'. I have tried setting the UART
- manually via. setserial to 16550A, 16550, and the other one (8550?)
- (I didn't try 16540). None of these manual settings resulted in any
- success.
-
- A look at past articles leads me to investigate PNP issues by
- calling pnpdump but pnpdump returns "no boards found". I have looked
- around on my BIOS (Phoenix) and there is not much evidence of it
- being PNP aware. However for what it calls "Serial port A", it
- offers a choice of Auto, Disabled or Manual settings (currently set
- to Auto), but using the BIOS interface I tried to change to 'manual'
- and saw the default settings offered to be were 0x3F8 and IRQ 4
- (COM1). The BIOS menus did not give me any chance to configure COM2
- or any "modem". I ended up not saving any BIOS changes in the course
- of my investigations.
-
- You can also find out a fair amount about your PC's hardware
- configuration in the text files in /proc, e.g.:
-
- -r--r--r-- 1 root 0 Sep 4 14:00 /proc/devices
- -r--r--r-- 1 root 0 Sep 4 14:00 /proc/interrupts
- -r--r--r-- 1 root 0 Sep 4 14:00 /proc/ioports
- -r--r--r-- 1 root 0 Sep 4 14:00 /proc/pci
-
- From the directory listing they look like empty files, but in fact they
- are text files that you "cat":
-
-$ cat /proc/pci
- Bus 0, device 14, function 0:
- Serial controller: US Robotics/3Com 56K FaxModem Model 5610 (rev 1).
- IRQ 10.
- I/O at 0x1050 [0x1057].
-
-$ setserial -g /dev/ttyS4
-/dev/ttyS4, UART: 16550A, Port: 0x1050, IRQ: 10
-
-$ cat /proc/ioports
-1050-1057 : US Robotics/3Com 56K FaxModem Model 5610
- 1050-1057 : serial(auto)
-
-$ cat /proc/interrupts
- CPU0
- 0: 7037515 XT-PIC timer
- 1: 2 XT-PIC keyboard
- 2: 0 XT-PIC cascade
- 4: 0 XT-PIC serial
- 8: 1 XT-PIC rtc
- 9: 209811 XT-PIC usb-uhci, eth0
- 14: 282015 XT-PIC ide0
- 15: 6 XT-PIC ide1
-
- Watch out for PCI, PCMCIA and Plug-n-Play devices, Winmodems, and the
- like (see cautions in [314]Section 3.0 Linux supports Plug-n-Play
- devices to some degree via the isapnp and pnpdump programs; read the
- man pages for them. (If you don't have them, look on your installation
- CD for isapnptool or download it from sunsite or a sunsite mirror or
- other politically correct location du jour).
-
- PCI modems do not use standard COM port addresses. The I/O address and
- IRQ are assigned by the BIOS. All you need to do to get one working,
- find out the I/O address and interrupt number with (as root) "lspci -v
- | more" and then give the resulting address and interrupt number to
- setserial.
-
- Even when you have a real serial port, always be wary of interrupt
- conflicts and similar PC hardware configuration issues: a PC is not a
- real computer like other Unix workstations -- it is generally pieced
- together from whatever random components were the best bargain on the
- commodity market the week it was built. Once it's assembled and boxed,
- not even the manufacturer will remember what it's made of or how it was
- put together because they've moved on to a new model. Their job is to
- get it (barely) working with Windows; for Linux and other OS's you are
- on your own.
-
- "set line /dev/modem" or "set line /dev/ttyS2", etc, results in an
- error, "/dev/modem is not a tty". Cause unknown, but obviously a driver
- issue, not a Kermit one (Kermit uses "isatty()" to check that the
- device is a tty, so it knows it will be able to issue all the
- tty-related ioctl's on it, like setting the speed & flow control). Try
- a different name (i.e. driver) for the same port, e.g. "set line
- /dev/cua2" or whatever.
-
- To find what serial ports were registered at the most recent system
- boot, type (as root): "grep tty /var/log/dmesg".
-
- "set modem type xxx" (where xxx is the name of a modem) followed by
- "set line /dev/modem" or "set
- line /dev/ttyS2", etc, hangs (but can be interrupted with Ctrl-C).
- Experimentation shows that if the modem is configured to always assert
- carrier (&C0) the same command does not hang. Again, a driver issue.
- Use /dev/cua2 (or whatever) instead. (Or not -- hopefully none of these
- symptoms occurs in C-Kermit 7.0 or later.)
-
- "set line /dev/cua0" reports "Device is busy", but "set line
- /dev/ttyS0" works OK.
-
- In short: If the cua device doesn't work, try the corresponding ttyS
- device. If the ttyS device doesn't work, try the corresponding cua
- device -- but note that Linux developers do not recommend this, and are
- phasing out the cua devices. From /usr/doc/faq/howto/Serial-HOWTO:
-
- 12.4. What's The Real Difference Between the /dev/cuaN And /dev/ttySN
- Devices?
- The only difference is the way that the devices are opened. The
- dialin devices /dev/ttySN are opened in blocking mode, until CD
- is asserted (ie someone connects). So, when someone wants to use
- the /dev/cuaN device, there is no conflict with a program
- watching the /dev/ttySN device (unless someone is connected of
- course). The multiple /dev entries, allow operation of the same
- physical device with different operating characteristics. It
- also allows standard getty programs to coexist with any other
- serial program, without the getty being retrofitted with locking
- of some sort. It's especially useful since standard Unix kernel
- file locking, and UUCP locking are both advisory and not
- mandatory.
-
- It was discovered during development of C-Kermit 7.0 that rebuilding
- C-Kermit with -DNOCOTFMC (No Close/Open To Force Mode Change) made the
- aforementioned problem with /dev/ttyS0 go away. It is not yet clear,
- however, what its affect might be on the /dev/cua* devices. As of 19
- March 1998, this option has been added to the CFLAGS in the makefile
- entries for Linux ("make linux").
-
- Note that the cua device is now "deprecated", and new editions of Linux
- will phase (have phased) it out in favor of the ttyS device. See (if
- it's still there):
-
- [315]http://linuxwww.db.erau.edu/mail_archives/linux-kernel/Mar_98/1441.html
-
- (no, of course it isn't; you'll have to use your imagination). One user
- reported that C-Kermit 7.0, when built with egcs 1.1.2 and run on Linux
- 2.2.6 with glibc 2.1 (hardware unknown but probably a PC) dumps core
- when given a "set line /dev/ttyS1" command. When rebuilt with gcc, it
- works fine.
-
- All versions of Linux seem to have the following deficiency: When a
- modem call is hung up and CD drops, Kermit can no longer read the modem
- signals; SHOW COMMUNICATIONS says "Modem signals not available". The
- TIOCMGET ioctl() returns -1 with errno 5 ("I/O Error").
-
- The Linux version of POSIX tcsendbreak(), which is used by C-Kermit to
- send regular (275msec) and long (1.5sec) BREAK signals, appears to
- ignore its argument (despite its description in the man page and info
- topic), and always sends a regular 275msec BREAK. This has been
- observed in Linux versions ranging from Debian 2.1 to Red Hat 7.1.
-
-3.3.3. Terminal Emulation in Linux
-
- [ [316]Top ] [ [317]Contents ] [ [318]Section Contents ] [ [319]Next ]
- [ [320]Previous ]
-
- C-Kermit is not a terminal emulator. For a brief explanation of why
- not, see [321]Section 3.0.5. For a fuller explanation, [322]ClICK HERE.
-
- In Unix, terminal emulation is supplied by the Window in which you run
- Kermit: the regular console screen, which provides Linux Console
- "emulation" via the "console" termcap entry, or under X-Windows in an
- xterm window, which gives VTxxx emulation. An xterm that includes color
- ANSI and VT220 emulation is available with Xfree86:
-
- [323]http://dickey.his.com/xterm/xterm.html
-
- Before starting C-Kermit in an xterm window, you might need to tell the
- xterm window's shell to "stty sane".
-
- To set up your PC console keyboard to send VT220 key sequences when
- using C-Kermit as your communications program in an X terminal window
- (if it doesn't already), create a file somewhere (e.g. in /root/)
- called .xmodmaprc, containing something like the following:
-
- keycode 77 = KP_F1 ! Num Lock => DEC Gold (PF1)
- keycode 112 = KP_F2 ! Keypad / => DEC PF1
- keycode 63 = KP_F3 ! Keypad * => DEC PF3
- keycode 82 = KP_F4 ! Keypad - => DEC PF4
- keycode 111 = Help ! Print Screen => DEC Help
- keycode 78 = F16 ! Scroll Lock => DEC Do
- keycode 110 = F16 ! Pause => DEC Do
- keycode 106 = Find ! Insert => DEC Find
- keycode 97 = Insert ! Home => DEC Insert
- keycode 99 = 0x1000ff00 ! Page Up => DEC Remove
- keycode 107 = Select ! Delete => DEC Select
- keycode 103 = Page_Up ! End => DEC Prev Screen
- keycode 22 = Delete ! Backspace sends Delete (127)
-
- Then put "xmodmap filename" in your .xinitrc file (in your login
- directory), e.g.
-
- xmodmap /root/.xmodmaprc
-
- Of course you can move things around. Use the xev program to find out
- key codes.
-
- Console-mode keys are mapped separately using loadkeys, and different
- keycodes are used. Find out what they are with showkey.
-
- For a much more complete VT220/320 key mapping for [324]Xfree86 xterm,
- [325]CLICK HERE.
-
-3.3.4. Dates and Times
-
- [ [326]Top ] [ [327]Contents ] [ [328]Section Contents ] [ [329]Next ]
- [ [330]Previous ]
-
- If C-Kermit's date-time (e.g. as shown by its DATE command) differs
- from the system's date and time:
-
- a. Make sure the libc to which Kermit is linked is set to GMT or is
- not set to any time zone. Watch out for mixed libc5/libc6 systems;
- each must be set independently.
- b. If you have changed your TZ environment variable, make sure it is
- exported. This is normally done in /etc/profile or /etc/TZ.
-
-3.3.5. Startup Errors
-
- [ [331]Top ] [ [332]Contents ] [ [333]Section Contents ] [ [334]Next ]
- [ [335]Previous ]
-
- C-Kermit should work on all versions of Linux current through March
- 2003, provided it was built on the same version you have, with the same
- libraries and header files (just get the source code and "make linux").
- Binaries tend not to travel well from one Linux machine to another, due
- to their many differences. There is no guarantee that a particular
- C-Kermit binary will not stop working at a later date, since Linux
- tends to change out from under its applications. If that happens,
- rebuild C-Kermit from source. If something goes wrong with the build
- process, look on the [336]C-Kermit website for a newer version. If you
- have the latest version, then [337]report the problem to us.
-
- Inability to transfer files in Red Hat 7.2: the typical symptom would
- be if you start Kermit and tell it to RECEIVE, it fails right away with
- "?/dev/tty: No such device or address" or "?Bad file descriptor". One
- report says this is because of csh, and if you change your shell to
- bash or other shell, it doesn't happen. Another report cite bugs in Red
- Hat 7.2 Telnetd "very seldom (if ever) providing a controlling tty, and
- lots of other people piled on saying they have the same problem.") A
- third theory is that this happens only when Linux has been installed
- without "virtual terminal support".
-
- A search of RedHat's errata pages shows a bug advisory (RHBA-2001-153)
- issued 13 November 2001, but updated 6 December, about this same
- symptom (but with tcsh and login.) Seems that login was not always
- assigning a controlling TTY for the session, which would make most use
- of "/dev/tty" somewhat less than useful.
-
- [338]http://www.redhat.com/support/errata/RHBA-2001-153.html
-
- Quoting: "Due to terminal handling problems in /bin/login, tcsh would
- not find the controlling terminal correctly, and a shell in single user
- mode would exhibit strange terminal input characteristics. This update
- fixes both of these problems."
-
- Since the Red Hat 5.1 release (circa August 1998), there have been
- numerous reports of prebuilt Linux executables, and particularly the
- Kermit RPM for Red Hat Linux, not working; either it won't start at
- all, or it gives error messages about "terminal type unknown" and
- refuses to initialize its curses support. The following is from the
- [339]Kermit newsgroup:
-
- From: rchandra@hal9000.buf.servtech.com
- Newsgroups: comp.protocols.kermit.misc
- Subject: Red Hat Linux/Intel 5.1 and ncurses: suggestions
- Date: 22 Aug 1998 15:54:46 GMT
- Organization: Verio New York
- Keywords: RedHat RPM 5.1
-
- Several factors can influence whether "linux" is recognized as a
- terminal type on many Linux systems.
-
- 1. Your program, or the libraries it linked with (if statically
- linked), or the libraries it dynamically links with at runtime, are
- looking for an entry in /etc/termcap that isn't there. (not likely,
- but possible... I believe but am not certain that this is a very
- old practice in very old [n]curses library implementations to use a
- single file for all terminal descriptions.)
- 2. Your program, or the libraries...are looking for a terminfo file
- that just plain isn't there. (also not so likely, since many people
- in other recent message threads said that other programs work OK).
- 3. Your program, or the libraries...are looking for a terminfo file
- that is stored at a pathname that isn't expected by your program,
- the libraries--and so on. I forgot if I read this in the errata Web
- page or where exactly I discovered this (Netscape install? Acrobat
- install?), but it may just be that one libc (let's say for sake of
- argument, libc5, but I don't know this to be true) expects your
- terminfo to be in /usr/share/terminfo, and the other (let's say
- libc6/glibc) expects /usr/lib/terminfo. I remember that the
- specific instructions in this bugfix/workaround were to do the
- following or equivalent:
- cd /usr/lib
- ln -s ../share/terminfo ./terminfo
-
- or:
- ln -s /usr/share/terminfo /usr/lib/terminfo
-
- So what this says is that the terminfo database/directory structure
- can be accessed by either path. When something goes to reference
- /usr/lib/terminfo, the symlink redirects it to essentially
- /usr/share/terminfo, which is where it really resides on your
- system. I personally prefer wherever possible to use relative
- symlinks, because they still hold, more often than break, across
- mount points, particularly NFS mounts, where the directory structure
- may be different on the different systems.
-
- Evidently the terminfo file moved between Red Hat 5.0 and 5.1, but Red
- Hat did not include a link to let applications built prior to 5.1 find
- it. Users reported that installing the link fixes the problem.
-
-3.3.6. The Fullscreen File Transfer Display
-
- [ [340]Top ] [ [341]Contents ] [ [342]Section Contents ] [
- [343]Previous ]
-
- Starting with ncurses versions dated 1998-12-12 (about a year before
- ncurses 5.0), ncurses sets the terminal for buffered i/o, but
- unfortunately is not able to restore it upon exit from curses (via
- endwin()). Thus after a file transfer that uses the fullscreen file
- transfer display, the terminal no longer echos nor responds immediately
- to Tab, ?, and other special command characters. The same thing happens
- on other platforms that use ncurses, e.g. FreeBSD. Workarounds:
-
- * Use SET XFER DISPLAY BRIEF, CRT, SERIAL, or NONE instead of
- FULLSCREEN; or:
- * Rebuild with KFLAGS=-DNONOSETBUF (C-Kermit 8.0)
-
- In Red Hat 7.1, when using C-Kermit in a Gnome terminal window, it was
- noticed that when the fullscreen file transfer display exits (via
- endwin()), the previous (pre-file-transfer-display) screen is restored.
- Thus you can't look at the completed display to see what happened. This
- is a evidently a new feature of xterm. I can only speculate that
- initscreen() and endwin() must send some kind of special escape
- sequences that command xterm to save and restore the screen. To defeat
- this effect, tell Linux you have a vt100 or other xterm-compatible
- terminal that is not actually an xterm, or else tell Kermit to SET
- TRANSFER DISPLAY to something besides FULLSCREEN.
-
-3.4. C-KERMIT AND NEXTSTEP
-
- [ [344]Top ] [ [345]Contents ] [ [346]Section Contents ] [ [347]Next ]
- [ [348]Previous ]
-
- Run C-Kermit in a Terminal, Stuart, or xterm window, or when logged in
- remotely through a serial port or TELNET connection. C-Kermit does not
- work correctly when invoked directly from the NeXTSTEP File Viewer or
- Dock. This is because the terminal-oriented gtty, stty, & ioctl calls
- don't work on the little window that NeXTSTEP pops up for non-NeXTSTEP
- applications like Kermit. CBREAK and No-ECHO settings do not take
- effect in the command parser -- commands are parsed strictly line at a
- time. "set line /dev/cua" works. During CONNECT mode, the console stays
- in cooked mode, so characters are not transmitted until carriage return
- or linefeed is typed, and you can't escape back. If you want to run
- Kermit directly from the File Viewer, then launch it from a shell
- script that puts it in the desired kind of window, something like this
- (for "Terminal"):
-
- Terminal -Lines 24 -Columns 80 -WinLocX 100 -WinLocY 100 $FONT $FONTSIZE \
- -SourceDotLogin -Shell /usr/local/bin/kermit &
-
- C-Kermit does not work correctly on a NeXT with NeXTSTEP 3.0 to which
- you have established an rlogin connection, due to a bug in NeXTSTEP
- 3.0, which has been reported to NeXT.
-
- The SET CARRIER command has no effect on the NeXT -- this is a
- limitation of the NeXTSTEP serial-port device drivers.
-
- Hardware flow control on the NeXT is selected not by "set flow rts/cts"
- in Kermit (since NeXTSTEP offers no API for this), but rather, by using
- a specially-named driver for the serial device: /dev/cufa instead
- /dev/cua; /dev/cufb instead of /dev/cub. This is available only on
- 68040-based NeXT models (the situation for Intel NeXTSTEP
- implementations is unknown).
-
- NeXT-built 68030 and 68040 models have different kinds of serial
- interfaces; the 68030 has a Macintosh-like RS-422 interface, which
- lacks RTS and CTS signals; the 68040 has an RS-423 (RS-232 compatible)
- interface, which supports the commonly-used modem signals. WARNING: the
- connectors look exactly the same, but the pins are used in completely
- DIFFERENT ways -- different cables are required for the two kinds of
- interfaces.
-
- IF YOU GET LOTS OF RETRANSMISSIONS during file transfer, even when
- using a /dev/cuf* device and the modem is correctly configured for
- RTS/CTS flow control, YOU PROBABLY HAVE THE WRONG KIND OF CABLE.
-
- On the NeXT, Kermit reportedly (by TimeMon) causes the kernel to use a
- lot of CPU time when using a "set line" connection. That's because
- there is no DMA channel for the NeXT serial port, so the port must
- interrupt the kernel for each character in or out.
-
- One user reported trouble running C-Kermit on a NeXT from within NeXT's
- Subprocess class under NeXTstep 3.0, and/or when rlogin'd from one NeXT
- to another: Error opening /dev/tty:, congm: No such device or address.
- Diagnosis: Bug in NeXTSTEP 3.0, cure unknown.
-
-3.5. C-KERMIT AND QNX
-
- [ [349]Top ] [ [350]Contents ] [ [351]Section Contents ] [ [352]Next ]
- [ [353]Previous ]
-
- See also: The [354]comp.os.qnx newsgroup.
-
- Support for QNX 4.x was added in C-Kermit 5A(190). This is a
- full-function implementation, thoroughly tested on QNX 4.21 and later,
- and verified to work in both 16-bit and 32-bit versions. The 16-bit
- version was dropped in C-Kermit 7.0 since it can no longer be built
- successfully (after stripping most most features, I succeeded in
- getting it to compile and link without complaint, but the executable
- just beeps when you run it); for 16-bit QNX 4.2x, use C-Kermit 6.0 or
- earlier, or else [355]G-Kermit.
-
- The 32-bit version (and the 16-bit version prior to C-Kermit 7.0)
- supports most of C-Kermit's advanced features including TCP/IP, high
- serial speeds, hardware flow-control, modem-signal awareness, curses
- support, etc.
-
- BUG: In C-Kermit 6.0 on QNX 4.22 and earlier, the fullscreen file
- transfer display worked fine the first time, but was fractured on
- subsequent file transfers. Cause and cure unknown. In C-Kermit 7.0 and
- QNX 4.25, this no longer occurs. It is not known if it would occur in
- C-Kermit 7.0 or later on earlier QNX versions.
-
- Dialout devices are normally /dev/ser1, /dev/ser2, ..., and can be
- opened explicitly with SET LINE. Reportedly, "/dev/ser" (no unit
- number) opens the first available /dev/sern device.
-
- Like all other Unix C-Kermit implementations, QNX C-Kermit does not
- provide any kind of terminal emulation. Terminal specific functions are
- provided by your terminal, terminal window (e.g. QNX Terminal or
- xterm), or emulator.
-
- QNX C-Kermit, as distributed, does not include support for UUCP
- line-locking; the QNX makefile entries (qnx32 and qnx16) include the
- -DNOUUCP switch. This is because QNX, as distributed, does not include
- UUCP, and its own communications software (e.g. qterm) does not use
- UUCP line locking. If you have a UUCP product installed on your QNX
- system, remove the -DNOUUCP switch from the makefile entry and rebuild.
- Then check to see that Kermit's UUCP lockfile conventions are the same
- as those of your UUCP package; if not, read the [356]UUCP lockfile
- section of the [357]Installation Instructions and make the necessary
- changes to the makefile entry (e.g. add -DHDBUUCP).
-
- QNX does, however, allow a program to get the device open count. This
- can not be a reliable form of locking unless all applications do it, so
- by default, Kermit uses this information only for printing a warning
- message such as:
-
- C-Kermit>set line /dev/ser1
- WARNING - "/dev/ser1" looks busy...
-
- However, if you want to use it as a lock, you can do so with:
-
- SET QNX-PORT-LOCK { ON, OFF }
-
- This is OFF by default; if you set in ON, C-Kermit will fail to open
- any dialout device when its open count indicates that another process
- has it open. SHOW COMM (in QNX only) displays the setting, and if you
- have a port open, it also shows the open count.
-
- As of C-Kermit 8.0, C-Kermit's "open-count" form of line locking works
- only in QNX4, not in QNX6 (this might change in a future C-Kermit
- release).
-
-3.6. C-KERMIT AND SCO
-
- [ [358]Top ] [ [359]Contents ] [ [360]Section Contents ] [ [361]Next ]
- [ [362]Previous ]
-
- SECTION CONTENTS
-
-3.6.1. [363]SCO XENIX
-3.6.2. [364]SCO UNIX and OSR5
-3.6.3. [365]Unixware
-3.6.4. [366]Open UNIX 8
-
- REFERENCES
-
- * The comp.unix.sco.* newsgroups.
- * [367]Section 3.10 below for Unixware.
- * The following FAQs:
-
- The comp.sco.misc FAQ:
- [368]http://aplawrence.com/SCOFAQ/
-
- Caldera (SCO) comp.unix.sco.programmer FAQ:
- [369]http://www.zenez.com/cgi-bin/scoprogfaq/faq.pl
-
- The UnixWare 7/OpenUNIX 8 FAQ:
- [370]http://www.zenez.com/cgi-bin/scouw7faq/faq.pl
- [371]http://zenez.pcunix.com/cgi-bin/scouw7faq/faq.pl
-
- High Speed Modems for SCO Unix:
- [372]http://pcunix.com/Unixart/modems.html
-
- The UnixWare FAQ
- [373]http://www.freebird.org/faq/
-
- The UnixWare 1.x and 2.0 Programmer FAQ
- [374]http://www.freebird.org/faq/developer.html
-
- Caldera Support Knowledge Base
- [375]http://support.caldera.com/caldera
-
- [376]http://stage.caldera.com/ta/
- Caldera (SCO) Technical Article Search Center
-
- [377]http://aplawrence.com/newtosco.html
- New to SCO (Tony Lawrence)
-
- The same comments regarding terminal emulation and key mapping apply to
- SCO operating systems as to all other Unixes. C-Kermit is not a
- terminal emulator, and you can't use it to map F-keys, Arrow keys, etc.
- The way to do this is with xmodmap (xterm) or loadkeys (console). For a
- brief explanation, see [378]Section 3.0.5. For a fuller explanation,
- [379]ClICK HERE.
-
- Also see general comments on PC-based Unixes in [380]Section 3.0.
-
-3.6.1. SCO XENIX
-
- [ [381]Top ] [ [382]Contents ] [ [383]Section Contents ] [ [384]Next ]
-
- Old Xenix versions... Did you know: Xenix 3.0 is *older* than Xenix
- 2.0?
-
- In Xenix 2.3.4 and probably other Xenix versions, momentarily dropping
- DTR to hang up a modem does not work. DTR goes down but does not come
- up again. Workaround: Use SET MODEM HANGUP-METHOD MODEM-COMMAND.
- Anybody who would like to fix this is welcome to take a look at
- tthang() in [385]ckutio.c. Also: modem signals can not be read in
- Xenix, and the maximum serial speed is 38400.
-
- There is all sorts of confusion among SCO versions, particularly when
- third- party communications boards and drivers are installed, regarding
- lockfile naming conventions, as well as basic functionality. As far as
- lockfiles go, all bets are off if you are using a third-party multiport
- board. At least you have the source code. Hopefully you also have a C
- compiler :-)
-
- Xenix 2.3.0 and later claim to support RTSFLOW and CTSFLOW, but this is
- not modern bidirectional hardware flow control; rather it implements
- the original RS-232 meanings of these signals for unidirectional
- half-duplex line access: If both RTSFLOW and CTSFLOW bits are set,
- Xenix asserts RTS when it wants to send data and waits for CTS
- assertion before it actually starts sending data (also, reportedly,
- even this is broken in Xenix 2.3.0 and 2.3.1).
-
-3.6.2. SCO UNIX AND OSR5
-
- [ [386]Top ] [ [387]Contents ] [ [388]Section Contents ] [ [389]Next ]
- [ [390]Previous ]
-
- SCO systems tend to use different names (i.e. drivers) for the same
- device. Typically /dev/tty1a refers to a terminal device that has no
- modem control; open, read, write, and close operations do not depend on
- carrier. On the other hand, /dev/tty1A (same name, but with final
- letter upper case), is the same device with modem control, in which
- carrier is required (the SET LINE command does not complete until
- carrier appears, read/write operations fail if there is no carrier,
- etc).
-
- SCO OpenServer 5.0.5 and earlier do not support the reading of modem
- signals. Thus "show comm" does not list modem signals, and C-Kermit
- does not automatically pop back to its prompt when the modem hangs up
- the connection (drops CD). The ioctl() call for this is simply not
- implemented, at least not in the standard drivers. OSR5.0.6 attempts to
- deal with modem signals but fails; however OSR5.0.6a appears to
- function properly.
-
- Dialing is likely not to work well in SCO OpenServer 5.0.x because many
- of the serial-port APIs simply do not operate when using the standard
- drivers. For example, if DTR is dropped by the recommended method
- (setting speed to 0 for half a seconds, then restoring the speed), DTR
- and RTS go down but never come back up. When in doubt SET MODEM
- HANGUP-METHOD MODEM-COMMAND or SET DIAL HANGUP OFF.
-
- On the other hand, certain functions that might not (do not) work right
- or at all when using SCO drivers (e.g. high serial speeds, hardware
- flow control, and/or reading of modem signals) might work right when
- using third-party drivers. (Example: hardware flow control works,
- reportedly, only on uppercase device like tty1A -- not tty1a -- and
- only when CLOCAL is clear when using the SCO sio driver, but there are
- no such restrictions in, e.g., [391]Digiboard drivers).
-
- One user reports that he can't transfer large files with C-Kermit under
- SCO OSR5.0.0 and 5.0.4 -- after the first 5K, everything falls apart.
- Same thing without Kermit -- e.g. with ftp over a PPP connection.
- Later, he said that replacing SCO's SIO driver with FAS, an alternative
- communications driver, made the problem go away:
-
- [392]ftp://ftp.fu-berlin.de/pub/unix/driver/fas
-
- With regard to bidirectional serial ports on OpenServer 5.0.4, the
- following advice appeared on an SCO-related newsgroup:
-
- No amount of configuration information is going to help you on 5.0.4
- unless it includes the kludge for the primary problem. With almost
- every modem, the 5.0.4 getty will barf messages and may or may not
- connect. There are 2 solutions and only one works on 5.0.4. Get the
- atdialer binary from a 5.0.0 system and substitute it for the native
- 5.0.4 atdialer. The other solution is to upgrade to 5.0.5. And, most
- of all, on any OpenServer products, do NOT run the badly broken
- Modem Manager. Configure the modems in the time honored way that
- dates back to Xenix.
-
- Use SCO-provided utilities for switching the directionality of a modem
- line, such as "enable" and "disable" commands. For example, to dial out
- on tty1a, which is normally set up for logins:
-
- disable tty1a
- kermit -l /dev/tty1a
- enable tty1a
-
- If a tty device is listed as an ACU in /usr/lib/uucp/Devices and is
- enabled, getty resets the ownership and permissions to uucp.uucp and
- 640 every time the device is released. If you want to use the device
- only for dialout, and you want to specify other owners or permissions,
- you should disable it in /usr/lib/uucp/Devices; this will prevent getty
- from doing things to it. You should also changes the device's file
- modes in /etc/conf/node.d/sio by changing fields 5-7 for the desired
- device(s); this determines how the devices are set if you relink the
- kernel.
-
- One SCO user of C-Kermit 5A(190) reported that only one copy of Kermit
- can run at a time when a Stallion Technologies multiport boards are
- installed. Cause, cure, and present status unknown (see [393]Section 14
- for more info regarding Stallion).
-
- Prior to SCO OpenServer 5.0.4, the highest serial port speed supported
- by SCO was 38400. However, in some SCO versions (e.g. OSR5) it is
- possible to map rarely-used lower speeds (like 600 and 1800) to higher
- ones like 57600 and 115200. To find out how, go to
- [394]http://www.sco.com/ and search for "115200". In OSR5.0.4, serial
- speeds up to 921600 are supported through the POSIX interface; C-Kermit
- 6.1.193 or later, when built for OSR5.0.4 using /bin/cc (NOT the UDK,
- which hides the high-speed definitions from CPP), supports these
- speeds, but you might be able to run this binary on earlier releases to
- get the high serial speeds, depending on various factors, described by
- Bela Lubkin of SCO:
-
- Serial speeds under SCO Unix / Open Desktop / OpenServer
- ========================================================
- Third party drivers (intelligent serial boards) may provide any speeds
- they desire; most support up to 115.2Kbps.
-
- SCO's "sio" driver, which is used to drive standard serial ports with
- 8250/16450/16550 and similar UARTs, was limited to 38400bps in older
- releases. Support for rates through 115.2Kbps was added in the
- following releases:
-
- SCO OpenServer Release 5.0.0 (requires supplement "rs40b")
- SCO OpenServer Release 5.0.2 (requires supplement "rs40a" or "rs40b")
- SCO OpenServer Release 5.0.4 or later
- SCO Internet FastStart Release 1.0.0 or later
-
- SCO supplements are at [395]ftp://ftp.sco.com/; the "rs40" series are
- under directory /Supplements/internet
-
- Kermit includes the high serial speeds in all OSR5 builds, but that
- does not necessarily mean they work. For example, on our in-house 5.0.5
- system, SET SPEED 57600 or higher seems to succeed (no error occurs)
- but when we read the speed back the driver says it is 50. Similarly,
- 76800 becomes 75, and 115200 becomes 110. Testing shows the resulting
- speed is indeed the low one we read back, not the high one we asked
- for. Moral: Use speeds higher than 38400 with caution on SCO OSR5.
-
- Reportedly, if you have a script that makes a TCP/IP SET HOST (e.g.
- Telnet) connection to SCO 3.2v4.2 with TCP/IP 1.2.1, and then does the
- following:
-
- script $ exit
- hangup
-
- this causes a pseudoterminal (pty) to be consumed on the SCO system; if
- you do it enough times, it will run out of ptys. An "exit" command is
- being sent to the SCO shell, and a HANGUP command is executed locally,
- so the chances are good that both sides are trying to close the
- connection at once, perhaps inducing a race condition in which the
- remote pty is not released. It was speculated that this would be fixed
- by applying SLS net382e, but it did not. Meanwhile, the workaround is
- to insert a "pause" between the SCRIPT and HANGUP commands. (The
- situation with later SCO releases is not known.)
-
- SCO UNIX and OpenServer allow their console and/or terminal drivers to
- be configured to translate character sets for you. DON'T DO THIS WHEN
- USING KERMIT! First of all, you don't need it -- Kermit itself already
- does this for you. And second, it will (a) probably ruin the formatting
- of your screens (depending on which emulation you are using); and (b)
- interfere with all sorts of other things -- legibility of non-ASCII
- text on the terminal screen, file transfer, etc. Use:
-
- mapchan -n
-
- to turn off this feature.
-
- Note that there is a multitude of SCO entries in the makefile, many of
- them exhibiting an unusually large number of compiler options. Some
- people actually understand all of this. Reportedly, things are settling
- down with SCO OpenServer 5.x and Unixware 7 (and Open UNIX 8 and who
- knows what the next one will be -- Linux probably) -- the SCO UDK
- compiler is said to generate binaries that will run on either platform,
- by default, automatically. When using gcc or egcs, on the other hand,
- differences persist, plus issues regarding the type of binary that is
- generated (COFF, ELF, etc), and where and how it can run. All of this
- could stand further clarification by SCO experts.
-
-3.6.3. Unixware
-
- [ [396]Top ] [ [397]Contents ] [ [398]Section Contents ] [ [399]Next ]
- [ [400]Previous ]
-
- Unixware changed hands several times before landing at SCO, and so has
- its [401]own section in this document. (Briefly: AT&T UNIX Systems
- Laboratories sold the rights to the UNIX name and to System V R4 (or
- R5?) to Novell; later Novell spun its UNIX division off into a new
- company called Univel, which eventually was bought by SCO, which later
- was bought by Caldera, which later sort of semi-spun-off SCO...)
-
-3.6.4. Open UNIX 8
-
- [ [402]Top ] [ [403]Contents ] [ [404]Section Contents ] [
- [405]Previous ]
-
- SCO was bought by Caldera in 2000 or 2001 and evolved Unixware 7.1 into
- Caldera Open UNIX 8.00. It's just like Unixware 7.1 as far as Kermit is
- concerned (the Unixware 7.1 makefile target works for Open UNIX 8.00,
- and in fact a Unixware 7.1 Kermit binary built on Unixware 7.1 runs
- under OU8; a separate OU8 makefile target exists simply to generate an
- appropriate program startup herald). Open Unix is now defunct;
- subsequent releases are called UnixWare again (e.g. UnixWare 7.1.3).
-
-3.7. C-KERMIT AND SOLARIS
-
- [ [406]Top ] [ [407]Contents ] [ [408]Section Contents ] [ [409]Next ]
- [ [410]Previous ]
-
- SECTION CONTENTS
-
-3.7.1. [411]Serial Port Configuration
-3.7.2. [412]Serial Port Problems
-3.7.3. [413]SunLink X.25
-3.7.4. [414]Sun Workstation Keyboard Mapping
-3.7.5. [415]Solaris 2.4 and Earlier
-
- REFERENCES
-
- * The [416]comp.unix.solaris newsgroup
- * [417]http://access1.sun.com/
- * [418]http://docs.sun.com/
- * [419]http://www.sunhelp.com/
- * [420]http://www.wins.uva.nl/pub/solaris/solaris2/
- * [421]http://www.wins.uva.nl/cgi-bin/sfaq.cgi
- * [422]ftp://ftp.wins.uva.nl/pub/solaris
- * [423]http://www.science.uva.nl/pub/solaris/solaris2.html
-
- And about serial communications in particular, see "Celeste's Tutorial
- on Solaris 2.x Modems and Terminals":
-
- [424]http://www.stokely.com/
-
- In particular:
-
- [425]http://www.stokely.com/unix.sysadm.resources/faqs.sun.html
-
- For PC-based Solaris, also see general comments on PC-based Unixes in
- [426]Section 3.0. Don't expect Solaris or any other kind of Unix to
- work right on a PC until you resolve all interrupt conflicts. Don't
- expect to be able to use COM3 or COM4 (or even COM2) until you have
- configured their addresses and interrupts.
-
-3.7.1. Serial Port Configuration
-
- [ [427]Top ] [ [428]Contents ] [ [429]Section Contents ] [ [430]Section
- Contents ] [ [431]Next ]
-
- Your serial port can't be used -- or at least won't work right -- until
- it is enabled in Solaris. For example, you get a message like "SERIAL:
- Operation would block" when attempting to dial. This probably indicates
- that the serial port has not been enabled for use with modems. You'll
- need to follow the instructions in your system setup or management
- manual, such as (e.g.) the Desktop SPARC Sun System & Network Manager's
- Guide, which should contain a section "Setting up Modem Software"; read
- it and follow the instructions. These might (or might not) include
- running a program called "eeprom", editing some system configuration
- file (such as, for example:
-
- /platform/i86pc/kernel/drv/asy.conf
-
- and then doing a configuration reboot, or running some other programs
- like drvconfig and devlinks. "man eeprom" for details.
-
- Also, on certain Sun models like IPC, the serial port hardware might
- need to have a jumper changed to make it an RS-232 port rather than
- RS-423.
-
- eeprom applies only to real serial ports, not to "Spiff" devices
- (serial port expander), in which case setup with Solaris' admintool is
- required.
-
- Another command you might need to use is pmadm, e.g.:
-
- pmadm -d -p zsmon -s tty3
- pmadm -e -p zsmon -s tty3
-
- You can use the following command to check if a process has the device
- open:
-
- fuser -f /dev/term/3
-
- In some cases, however (according to Sun support, May 2001) "It is
- still possible that a zombie process has hold of the port EVEN IF there
- is no lock file and the fuser command comes up empty. In that case, the
- only way to resolve the problem is by rebooting."
-
- If you can't establish communication through a serial port to a device
- that is not asserting CD (Carrier Detect), try setting the environment
- variable "ttya-ignore-cd" to "true" (replace "ttya" with the port
- name).
-
-3.7.2. Serial Port Problems
-
- [ [432]Top ] [ [433]Contents ] [ [434]Section Contents ] [ [435]Next ]
- [ [436]Previous ]
-
- Current advice from Sun is to always the /dev/cua/x devices for dialing
- out, rather than the /dev/term/x. Nevertheless, if you have trouble
- dialing out with one, try the other.
-
- Reportedly, if you start C-Kermit and "set line" to a port that has a
- modem connected to it that is not turned on, and then "set flow
- rts/cts", there might be some (unspecified) difficulties closing the
- device because the CTS signal is not coming in from the modem.
-
-3.7.3. SunLink X.25
-
- [ [437]Top ] [ [438]Contents ] [ [439]Section Contents ] [ [440]Next ]
- [ [441]Previous ]
-
- The built-in SunLink X.25 support for Solaris 2.3/2.4./25 and SunLink
- 8.01 or 9.00 works OK provided the X.25 system has been installed and
- initialized properly. Packet sizes might need to be reduced to 256,
- maybe even less, depending on the configuration of the X.25
- installation. On one connection where C-Kermit 6.0 was tested, very
- large packets and window sizes could be used in one direction, but only
- very small ones would work in the other.
-
- In any case, according to Sun, C-Kermit's X.25 support is superfluous
- with SunLink 8.x / Solaris 2.3. Quoting an anonymous Sun engineer:
-
- ... there is now no need to include any X.25 code within kermit. As
- of X.25 8.0.1 we support the use of kermit, uucp and similar
- protocols over devices of type /dev/xty. This facility was there in
- 8.0, and should also work on the 8.0 release if patch 101524 is
- applied, but I'm not 100% sure it will work in all cases, which is
- why we only claim support from 8.0.1 onwards.
-
- When configuring X.25, on the "Advanced Configuration->Parameters"
- screen of the x25tool you can select a number of XTY devices. If you
- set this to be > 1, press Apply, and reboot, you will get a number
- of /dev/xty entries created.
-
- Ignore /dev/xty0, it is a special case. All the others can be used
- exactly as if they were a serial line (e.g. /dev/tty) connected to a
- modem, except that instead of using Hayes-style commands, you use
- PAD commands.
-
- From kermit you can do a 'set line' command to, say, /dev/xty1, then
- set your dialing command to be "CALL 12345678", etc. All the usual
- PAD commands will work (SET, PAR, etc).
-
- I know of one customer in Australia who is successfully using this,
- with kermit scripts, to manage some X.25-connected switches. He used
- standard kermit, compiled for Solaris 2, with X.25 8.0 xty devices.
-
-3.7.4. Sun Workstation Keyboard Mapping
-
- [ [442]Top ] [ [443]Contents ] [ [444]Section Contents ] [ [445]Next ]
- [ [446]Previous ]
-
- Hints for using a Sun workstation keyboard for VT emulation when
- accessing VMS, from the [447]comp.os.vms newsgroup:
-
- From: Jerry Leichter <leichter@smarts.com>
- Newsgroups: comp.os.vms
- Subject: Re: VT100 keyboard mapping to Sun X server
- Date: Mon, 19 Aug 1996 12:44:21 -0400
-
- > I am stuck right now using a Sun keyboard (type 5) on systems
- running SunOS
- > and Solaris. I would like to use EVE on an OpenVMS box with
- display back to
- > the Sun. Does anyone know of a keyboard mapping (or some other
- procedure)
- > which will allow the Sun keyboard to approximate a VT100/VT220?
-
- You can't get it exactly - because the keypad has one fewer key -
- but you can come pretty close. Here's a set of keydefs I use:
-
- keycode 101=KP_0
- keycode 119=KP_1
- keycode 120=KP_2
- keycode 121=KP_3
- keycode 98=KP_4
- keycode 99=KP_5
- keycode 100=KP_6
- keycode 75=KP_7
- keycode 76=KP_8
- keycode 77=KP_9
- keycode 52=KP_F1
- keycode 53=KP_F2
- keycode 54=KP_F3
- keycode 57=KP_Decimal
- keycode 28=Left
- keycode 29=Right
- keycode 30=KP_Separator
- keycode 105=KP_F4
- keycode 78=KP_Subtract
- keycode 8=Left
- keycode 10=Right
- keycode 32=Up
- keycode 33=Down
- keycode 97=KP_Enter
-
- Put this in a file - I use "keydefs" in my home directory and feed
- it into xmodmap:
-
- xmodmap - <$HOME/keydefs
-
- This takes care of the arrow keys and the "calculator" key cluster.
- The "+" key will play the role of the DEC "," key. The Sun "-" key
- will be like the DEC "-" key, though it's in a physically different
- position - where the DEC PF4 key is. The PF4 key is ... damn, I'm
- not sure where "key 105" is. I *think* it may be on the leftmost key
- of the group of four just above the "calculator" key cluster.
-
- I also execute the following (this is all in my xinitrc file):
-
- xmodmap -e 'keysym KP_Decimal = KP_Decimal'
- xmodmap -e 'keysym BackSpace = Delete BackSpace' \
- -e 'keysym Delete = BackSpace Delete'
- xmodmap -e 'keysym KP_Decimal = Delete Delete KP_Decimal'
- xmodmap -e 'add mod1 = Meta_R'
- xmodmap -e 'add mod1 = Meta_L'
-
- Beware of one thing about xmodmap: Keymap changes are applied to the
- *whole workstation*, not just to individual windows. There is, in
- fact, no way I know of to apply them to individual windows. These
- definitions *may* confuse some Unix programs (and/or some Unix
- users).
-
- If you're using Motif, you may also need to apply bindings at the
- Motif level. If just using xmodmap doesn't work, I can try and dig
- that stuff up for you.
-
-3.7.5. Solaris PPP Connections
-
- [ [448]Top ] [ [449]Contents ] [ [450]Section Contents ] [ [451]Next ]
- [ [452]Previous ]
-
- The following is a report from a user of C-Kermit 8.0 on Solaris 8 and
- 9, who had complained that while Kermit file transfers worked perfectly
- on direct (non-PPP) dialout connections, they failed miserably on PPP
- connections. We suggested that the PPP dialer probably was not setting
- the port and/or modem up in the same way that Kermit did:
-
- I want to get back on this and tell you what the resolution was. You
- pointed me in the direction of flow control, which turned out to be
- the key.
-
- Some discussion on the comp.unix.solaris newsgroup led to some
- comments from Greg Andrews about the need to use the uucp driver to
- talk to the modem (/dev/cua/a). I had to remind Greg that no matter
- what the manpages for the zs and se drivers say, the ppp that Sun
- released with Solaris 8 7/01, and has in Solaris 9, is a setuid root
- program, and simply trying to make a pppd call from user space
- specifying /dev/cua/a would fail because of permissions. Greg
- finally put the question to the ppp people, who came back with
- information that is not laid out anywhere in the docs available for
- Solaris users. Namely, put /dev/cua/a in one of the privileged
- options files in the /etc/ppp directory. That, plus resetting the
- OBP ttya-ignore-cd flag (this is Sun hardware) to false, seems to
- have solved the problems.
-
- While I note that I had installed Kermit suid to uucp to use
- /dev/cua/a on this particular box, it seems to run fine through
- /dev/term/a. Not so with pppd.
-
- With this change in place, I seem to be able to upload and download
- through telnet run on Kermit with the maximum length packets. I note
- that the window allocation display does show STREAMING, using
- telnet. Running ssh on Kermit, I see the standard 1 of 30 windows
- display, and note that there appears to be a buffer length limit
- between 1000 and 2000 bytes. Run with 1000, and it's tick-tock,
- solid as a rock. With 2000 I see timeout errors and RTS/CTS action
- on the modem.
-
- Kermit's packet-length and other controls let you make adjustments like
- this to get around whatever obstacles might be thrown up -- in this
- case (running Kermit over ssh), the underling Solaris PTY driver.
-
-3.7.6. Solaris 2.4 and Earlier
-
- [ [453]Top ] [ [454]Contents ] [ [455]Section Contents ] [
- [456]Previous ]
-
- C-Kermit can't be compiled successfully under Solaris 2.3 using
- SUNWspro cc 2.0.1 unless at least some of the following patches are
- applied to cc (it is not known which one(s), if any, fix the problem):
-
- * 100935-01 SparcCompiler C 2.0.1: bad code generated when addresses
- of two double arguments are involved
- * 100961-05 SPARCcompilers C 2.0.1: conditional expression with
- function returning structure gives wrong value
- * 100974-01 SparcWorks 2.0.1: dbx jumbo patch
- * 101424-01 SPARCworks 2.0.1 maketool SEGV's instantly on Solaris 2.3
-
- With unpatched cc 2.0.1, the symptom is that certain modules generate
- truncated object files, resulting in many unresolved references at link
- time.
-
- The rest of the problems in this section have to do with
- bidirectional terminal ports and the Solaris Port Monitor. A bug in
- C-Kermit 5A ticked a bug in Solaris. The C-Kermit bug was fixed in
- version 6.0, and the Solaris bug was fixed in 2.4 (I think, or maybe
- 2.5).
-
- Reportedly, "C-Kermit ... causes a SPARCstation running Solaris 2.3 to
- panic after the modem connects. I have tried compiling C-Kermit with
- Sun's unbundled C compiler, with GCC Versions 2.4.5 and 2.5.3, with
- make targets 'sunos51', 'sunos51tcp', 'sunos51gcc', and even 'sys5r4',
- and each time it compiles and starts up cleanly, but without fail, as
- soon as I dial the number and get a 'CONNECT' message from the modem, I
- get:
-
- BAD TRAP
- kermit: Data fault
- kernel read fault at addr=0x45c, pme=0x0
- Sync Error Reg 80 <INVALID>
- ...
- panic: Data Fault.
- ...
- Rebooting...
-
- The same modem works fine for UUCP/tip calling." Also (reportedly),
- this only happens if the dialout port is configured as in/out via
- admintool. If it is configured as out-only, no problem. This is the
- same dialing code that works on hundreds of other System-V based Unix
- OS's. Since it should be impossible for a user program to crash the
- operating system, this problem must be chalked up to a Solaris bug.
- Even if you SET CARRIER OFF, CONNECT, and dial manually by typing
- ATDTnnnnnnn, the system panics as soon as the modem issues its CONNECT
- message. (Clearly, when you are dialing manually, C-Kermit does not
- know a thing about the CONNECT message, and so the panic is almost
- certainly caused by the transition of the Carrier Detect (CD) line from
- off to on.) This problem was reported by many users, all of whom say
- that C-Kermit worked fine on Solaris 2.1 and 2.2. If the speculation
- about CD is true, then a possible workaround might be to configure the
- modem to leave CD on (or off) all the time. Perhaps by the time you
- read this, a patch will have been issued for Solaris 2.3.
-
- The following is from Karl S. Marsh, Systems & Networks Administrator,
- AMBIX Systems Corp, Rochester, NY:
-
- Environment: Solaris 2.3 Patch 101318-45 C-Kermit 5A(189) (and
- presumably this applies to 188 and 190 also). eeprom setting:
-
- ttya-rts-dtr-off=false
- ttya-ignore-cd=false
- ttya-mode=19200,8,n,8,-
-
- To use C-Kermit on a bidirectional port in this environment, do not
- use admintool to configure the port. Use admintool to delete any
- services running on the port and then quit admintool and issue the
- following command:
-
- pmadm -a -p zsmon -s ttyb -i root -fu -v 1 -m "`ttyadm -b -d /dev/term/b \
- -l conttyH -m ldterm,ttcompat -s /usr/bin/login -S n`"
-
- [NOTE: This was copied from a blurry fax, so please check it
- carefully] where:
-
- -a = Add service
- -p = pmtag (zsmon)
- -s = service tag (ttyb)
- -i = id to be associated with service tag (root)
- -fu = create utmp entry
- -v = version of ttyadm
- -m = port monitor-specific portion of the port monitor administrative file
- entry for the service
- -b = set up port for bidirectional use
- -d = full path name of device
- -l = which ttylabel in the /etc/ttydefs file to use
- -m = a list of pushable STREAMS modules
- -s = pathname of service to be invoked when connection request received
- -S = software carrier detect on or off (n = off)
-
- "This is exactly how I was able to get Kermit to work on a
- bi-directional port without crashing the system."
-
- On the Solaris problem, also see SunSolve Bug ID 1150457 ("Using
- C-Kermit, get Bad Trap on receiving prompt from remote system").
- Another user reported "So, I have communicated with the Sun tech
- support person that submitted this bug report [1150457]. Apparently,
- this bug was fixed under one of the jumbo kernel patches. It would seem
- that the fix did not live on into 101318-45, as this is EXACTLY the
- error that I see when I attempt to use kermit on my system."
-
- Later (Aug 94)... C-Kermit dialout successfully tested on a Sun4m with
- a heavily patched Solaris 2.3. The patches most likely to have been
- relevant:
-
- * 101318-50: SunOS 5.3: Jumbo patch for kernel (includes libc, lockd)
- * 101720-01: SunOS 5.3: ttymon - prompt not always visible on a modem
- connection
- * 101815-01: SunOS 5.3: Data fault in put() NULL queue passed from
- ttycommon_qfull()
- * 101328-01: SunOS 5.3: Automation script to properly setup tty ports
- prior to PCTS execution
-
- Still later (Nov 94): another user (Bo Kullmar in Sweden) reports that
- after using C-Kermit to dial out on a bidirectional port, the port
- might not answer subsequent incoming calls, and says "the problem is
- easy enough to fix with the Serial Port Manager; I just delete the
- service and install it again using the graphical interface, which
- underneath uses commands like sacadm and pmadm." Later Bo reports, "I
- have found that if I run Kermit with the following script then it
- works. This script is for /dev/cua/a, "-s a" is the last a in
- /dev/cua/a:
-
- #! /bin/sh
- kermit
- sleep 2
- surun pmadm -e -p zsmon -s a
-
-3.8. C-KERMIT AND SUNOS
-
- [ [457]Top ] [ [458]Contents ] [ [459]Section Contents ] [ [460]Next ]
- [ [461]Previous ]
-
- For additional information, see "Celeste's Tutorial on SunOS 4.1.3+
- Modems and Terminals":
-
- [462]http://www.stokely.com/
-
- For FAQs, etc, from Sun, see:
- * [463]http://access1.sun.com/
-
- For history of Sun models and SunOS versions, see (should be all the
- same):
- * [464]http://www.ludd.luth.se/~bear/project/sun/sun.hardware.txt
- * [465]ftp://ftp.netcom.com/pub/ru/rubicon/sun.hdwr.ref
- * [466]ftp://ftp.intnet.net/pub/SUN/Sun-Hardware-Ref
-
- Sun SPARCstation users should read the section "Setting up Modem
- Software" in the Desktop SPARC Sun System & Network Manager's Guide. If
- you don't set up your serial ports correctly, Kermit (and other
- communications software) won't work right.
-
- Also, on certain Sun models like IPC, the serial port hardware might
- need to have a jumper changed to make it an RS-232 port rather than
- RS-423.
-
- Reportedly, C-Kermit does not work correctly on a Sun SPARCstation in
- an Open Windows window with scrolling enabled. Disable scrolling, or
- else invoke Kermit in a terminal emulation window (xterm, crttool,
- vttool) under SunView (this might be fixed in later SunOS releases).
-
- On the Sun with Open Windows, an additional symptom has been reported:
- outbound SunLink X.25 connections "magically" translate CR typed at the
- keyboard into LF before transmission to the remote host. This doesn't
- happen under SunView.
-
- SET CARRIER ON, when used on the SunOS 4.1 version of C-Kermit
- (compiled in the BSD universe), causes the program to hang
- uninterruptibly when SET LINE is issued for a device that is not
- asserting carrier. When Kermit is built in the Sys V universe on the
- same computer, there is no problem (it can be interrupted with Ctrl-C).
- This is apparently a limitation of the BSD-style tty driver.
-
- SunOS 4.1 C-Kermit has been observed to dump core when running a
- complicated script program under cron. The dump invariably occurs in
- ttoc(), while trying to output a character to a TCP/IP TELNET
- connection. ttoc() contains a write() call, and when the system or the
- network is very busy, the write() call can get stuck for long periods
- of time. To break out of deadlocks caused by stuck write() calls, there
- is an alarm around the write(). It is possible that the core dump
- occurs when this alarm signal is caught. (This one has not been
- observed recently -- possibly fixed in edit 190.)
-
- On Sun computers with SunOS 4.0 or 4.1, SET FLOW RTS/CTS works only if
- the carrier signal is present from the communication device at the time
- when C-Kermit enters packet mode or CONNECT mode. If carrier is not
- sensed (e.g. when dialing), C-Kermit does not attempt to turn on
- RTS/CTS flow control. This is because the SunOS serial device driver
- does not allow characters to be output if RTS/CTS is set (CRTSCTS) but
- carrier (and DSR) are not present. Workaround (maybe): SET CARRIER OFF
- before giving the SET LINE command, establish the connection, then SET
- FLOW RTS/CTS
-
- It has also been reported that RTS/CTS flow control under SunOS 4.1
- through 4.1.3 works only on INPUT, not on output, and that there is a
- patch from Sun to correct this problem: Patch-ID# T100513-04, 20 July
- 1993 (this patch might apply only to SunOS 4.1.3). It might also be
- necessary to configure the eeprom parameters of the serial port; e.g.
- do the following as root at the shell prompt:
-
- eeprom ttya-ignore-cd=false
- eeprom ttya-rts-dtr-off=true
-
- There have been reports of file transfer failures on Sun-3 systems when
- using long packets and/or large window sizes. One user says that when
- this happens, the console issues many copies of this message:
-
- chaos vmunix: zs1: ring buffer overflow
-
- This means that SunOS is not scheduling Kermit frequently enough to
- service interrupts from the zs serial device (Zilog 8350 SCC serial
- communication port) before its input silo overflows. Workaround: use
- smaller packets and/or a smaller window size, or use "nice" to increase
- Kermit's priority. Use hardware flow control if available, or remove
- other active processes before running Kermit.
-
- SunLink X.25 support in C-Kermit 5A(190) was built and tested
- successfully under SunOS 4.1.3b and SunLink X.25 7.00.
-
-3.9. C-KERMIT AND ULTRIX
-
- [ [467]Top ] [ [468]Contents ] [ [469]Section Contents ] [ [470]Next ]
- [ [471]Previous ]
-
- See also: The [472]comp.unix.ultrix and [473]comp.sys.dec newsgroups.
-
- There is no hardware flow control in Ultrix. That's not a Kermit
- deficiency, but an Ultrix one.
-
- When sending files to C-Kermit on a Telnet connection to a remote
- Ultrix system, you must SET PREFIXING ALL (or at least prefix more
- control characters than are selected by SET PREFIXING CAUTIOUS).
-
- Reportedly, DEC ULTRIX 4.3 is immune to C-Kermit's disabling of
- SIGQUIT, which is the signal that is generated when the user types
- Ctrl-\, which kills the current process (i.e. C-Kermit) and dumps core.
- Diagnosis and cure unknown. Workaround: before starting C-Kermit -- or
- for that matter, when you first log in because this applies to all
- processes, not just Kermit -- give the following Unix command:
-
- stty quit undef
-
- Certain operations driven by RS-232 modem signal do not work on
- DECstations or other DEC platforms whose serial interfaces use MMP
- connectors (DEC version of RJ45 telephone jack with offset tab). These
- connectors convey only the DSR and DTR modem signals, but not carrier
- (CD), RTS, CTS, or RI. Use SET CARRIER OFF to enable communication, or
- "hotwire" DSR to CD.
-
- The maximum serial speed on the DECstation 5000 is normally 19200, but
- various tricks are available (outside Kermit) to enable higher rates.
- For example, on the 5000/200, 19200 can be remapped (somehow, something
- to do with "a bit in the SIR", whatever that is) to 38400, but in
- software you must still refer to this speed as 19200; you can't have
- 19200 and 38400 available at the same time.
-
- 19200, reportedly, is also the highest speed supported by Ultrix, but
- NetBSD reportedly supports speeds up to 57600 on the DECstation,
- although whether and how well this works is another question.
-
- In any case, given the lack of hardware flow control in Ultrix, high
- serial speeds are problematic at best.
-
-3.10. C-KERMIT AND UNIXWARE
-
- [ [474]Top ] [ [475]Contents ] [ [476]Section Contents ] [ [477]Next ]
- [ [478]Previous ]
-
- See also:
- * The Freebird Project (Unixware software repository)
- [479]http://www.freebird.org/
- * The UnixWare FAQ: [480]http://www.freebird.org/faq/
- * The following newsgroups:
- + [481]comp.unix.unixware.misc
- + [482]comp.unix.sco.misc.
-
- Also see general comments on PC-based Unixes in [483]Section 3.0. By
- the way, this section is separate from the SCO (Caldera) section
- because at the time this section was started, Unixware was owned by a
- company called Univel. Later it was sold to Novell, and then to SCO.
- Still later, SCO was sold to Caldera.
-
- In Unixware 2.0 and later, the preferred serial device names (drivers)
- are /dev/term/00 (etc), rather than /dev/tty00 (etc). Note the
- following correspondence of device names and driver characteristics:
-
- New name Old name Description
- /dev/term/00 /dev/tty00 ???
- /dev/term/00h /dev/tty00h Modem signals and hardware flow control
- /dev/term/00m /dev/tty00m Modem signals(?)
- /dev/term/00s /dev/tty00s Modem signals and software flow control
- /dev/term/00t /dev/tty00t ???
-
- Lockfile names use device.major.minor numbers, e.g.:
-
- /var/spool/locks/LK.7679.003.005
-
- The minor number varies according to the device name suffix (none, h,
- m, s, or t). Only the device and major number are compared, and thus
- all of the different names for the same physical device (e.g. all of
- those shown in the table above) interlock effectively.
-
- Prior to UnixWare 7, serial speeds higher than 38400 are not supported.
- In UnixWare 7, we also support 57600 and 115200, plus some unexpected
- ones like 14400, 28800, and 76800, by virtue of a strange new
- interface, evidently peculiar to UnixWare 7, discovered while digging
- through the header files: tcsetspeed(). Access to this interface is
- allowed only in POSIX builds, and thus the UnixWare 7 version of
- C-Kermit is POSIX-based, unlike C-Kermit for Unixware 1.x and 2.x
- (since the earlier UnixWare versions did not support high serial
- speeds, period).
-
- HOWEVER, turning on POSIX features engages all of the "#if
- (!_POSIX_SOURCE)" clauses in the UnixWare header files, which in turn
- prevent us from having modem signals, access to the hardware flow
- control APIs, select(), etc -- in short, all the other things we need
- in communications software, especially when high speeds are used. Oh
- the irony. And so C-Kermit must be shamelessly butchered -- as it has
- been so many times before -- to allow us to have the needed features
- from the POSIX and non-POSIX worlds. See the UNIXWAREPOSIX sections of
- [484]ckutio.c.
-
- After the butchery, we wind up with Unixware 2.x having full
- modem-signal capability, but politically-correct Unixware 7.x lacking
- the ability to automatically detect a broken connection when carrier
- drops.
-
- Meanwhile the Unixware tcsetspeed() function allows any number at all
- (any long, 0 or positive) as an argument and succeeds if the number is
- a legal bit rate for the serial device, and fails otherwise. There is
- no list anywhere of legal speeds. Thus the SET SPEED keyword table
- ("set speed ?" to see it) is hardwired based on trial and error with
- all known serial speeds, the maximum being 115200. However, to allow
- for the possibility that other speeds might be allowed in the future
- (or with different port drivers), the SET SPEED command for UnixWare 7
- only allows you to specify any number at all; a warning is printed if
- the number is not in the list, but the number is accepted anyway; the
- command succeeds if tcsetspeed() accepts the number, and fails
- otherwise.
-
- In C-Kermit 8.0 testing, it was noticed that the POSIX method for
- hanging up the phone by dropping DTR (set speed 0, pause, restore
- speed) did not actually drop DTR. The APIs do not return any error
- indication, but nothing happens. I changed tthang() to skip the special
- case I had made for Unixware and instead follow the normal path: if
- TIOCSDTR is defined use that, otherwise blah blah... It turns out
- TIOCSDTR *is* defined, and it works.
-
- So in Unixware (at least in 2.1.3) we can read modem signals, hangup by
- toggling DTR, and so on, BUT... But once the remote hangs up and
- Carrier drops, the API for reading modem signals ceases to function;
- although the device is still open, the TIOCMGET ioctl always raises
- errno 6 = ENXIO, "No such device or address".
-
- Old business:
-
- Using C-Kermit 6.0 on the UnixWare 1.1 Application Server, one user
- reported a system panic when the following script program is executed:
-
- set line /dev/tty4
- set speed 9600
- output \13
- connect
-
- The panic does not happen if a PAUSE is inserted:
-
- set line /dev/tty4
- set speed 9600
- pause 1
- output \13
- connect
-
- This is using a Stallion EasyIO card installed as board 0 on IRQ 12 on
- a Gateway 386 with the Stallion-supplied driver. The problem was
- reported to Novell and Stallion and (reportedly) is now fixed.
-
-3.11. C-KERMIT AND APOLLO SR10
-
- [ [485]Top ] [ [486]Contents ] [ [487]Section Contents ] [ [488]Next ]
- [ [489]Previous ]
-
- Reportedly, version 5A(190), when built under Apollo SR10 using "make
- sr10-bsd", compiles, links, and executes OK, but leaves the terminal
- unusable after it exits -- the "cs7" or "cs8" (character size)
- parameter has become cs5. The terminal must be reset from another
- terminal. Cause and cure unknown. Suggested workaround: Wrap Kermit in
- a shell script something like:
-
- kermit @*
- stty sane
-
-3.12. C-KERMIT AND TANDY XENIX 3.0
-
- [ [490]Top ] [ [491]Contents ] [ [492]Section Contents ] [ [493]Next ]
- [ [494]Previous ]
-
- C-Kermit 7.0 was too big to be built on Tandy Xenix, even in a minimum
- configuration; version 6.0 is the last one that fits.
-
- Reportedly, in C-Kermit 6.0, if you type lots of Ctrl-C's during
- execution of the initialization file, ghost Kermit processes will be
- created, and will compete for the keyboard. They can only be removed
- via "kill -9" from another terminal, or by rebooting. Diagnosis --
- something strange happening with the SIGINT handler while the process
- is reading the directory (it seems to occur during the SET PROMPT
- [\v(dir)] ... sequence). Cure: unknown. Workaround: don't interrupt
- C-Kermit while it is executing its init file on the Tandy 16/6000.
-
-3.13. C-KERMIT AND OSF/1 (DIGITAL UNIX) (TRU64 UNIX)
-
- [ [495]Top ] [ [496]Contents ] [ [497]Section Contents ] [ [498]Next ]
- [ [499]Previous ]
-
- While putting together and testing C-Kermit 8.0, it was discovered that
- binaries built for one version of Tru64 Unix (e.g. 4.0G) might exhibit
- very strange behavior if run on a different version of Tru64 Unix (e.g.
- 5.1A). The typical symptom was that a section of the initialization
- file would be skipped, notably locating the dialing and/or network
- directory as well as finding and executing the customization file,
- ~/.mykermrc. This problem also is reported to occur on Tru64 Unix 5.0
- (Rev 732) even when running a C-Kermit binary that was built there.
- However, the Tru64 5.1A binary works correctly on 5.0. Go figure.
-
- When making Telnet connections to a Digital Unix or Tru64 system, and
- your Telnet client forwards your user name, the Telnet server evidently
- stuffs the username into login's standard input, and you see:
-
- login: ivan
- Password:
-
- This is clearly going to play havoc with scripts that look for
- "login:". Workaround (when Kermit is your Telnet client): SET LOGIN
- USER to nothing, to prevent Kermit from sending your user ID.
-
- Before you can use a serial port on a new Digital Unix system, you must
- run uucpsetup to enable or configure the port. Evidently the /dev/tty00
- and 01 devices that appear in the configuration are not usable;
- uucpsetup turns them into /dev/ttyd00 and 01, which are. Note that
- uucpsetup and other uucp-family programs are quite primitive -- they
- only know about speeds up to 9600 bps and their selection of modems
- dates from the early 1980s. None of this affects Kermit, though -- with
- C-Kermit, you can use speeds up to 115200 bps (at least in DU4.0 and
- later) and modern modems with hardware flow control and all the rest.
-
- Reportedly, if a modem is set for &S0 (assert DSR at all times), the
- system resets or drops DTR every 30 seconds; reportedly DEC says to set
- &S1.
-
- Digital Unix 3.2 evidently wants to believe your terminal is one line
- longer than you say it is, e.g. when a "more" or "man" command is
- given. This is has nothing to do with C-Kermit, but tends to annoy
- those who use Kermit or other terminal emulators to access Digital Unix
- systems. Workaround: tell Unix to "stty rows 23" (or whatever).
-
- Reportedly, there is some bizarre behavior when trying to use a version
- of C-Kermit built on one Digital Unix 4.0 system on another one,
- possibly due to differing OS or library revision levels; for example,
- the inability to connect to certain TCP/IP hosts. Solution: rebuild
- C-Kermit from source code on the system where you will be using it.
-
- Digital Unix tgetstr() causes a segmentation fault. C-Kermit 7.0 added
- #ifdefs to avoid calling this routine in Digital Unix. As a result, the
- SCREEN commands always send ANSI escape sequences -- even though curses
- knows your actual terminal type.
-
- Reportedly the Tru64 Unix 4.0E 1091 Telnet server does not tolerate
- streaming transfers into itself, at least not when the sending Kermit
- is on the same local network. Solution: tell one Kermit or the other
- (or both) to "set streaming off". This might or might be the case with
- earlier and/or later Tru64, Digital Unix, and OSF/1 releases.
-
-3.14. C-KERMIT AND SGI IRIX
-
- [ [500]Top ] [ [501]Contents ] [ [502]Section Contents ] [ [503]Next ]
- [ [504]Previous ]
-
- See also:
- * The [505]comp.sys.sgi.misc and [506]comp.sys.sgi.admin newsgroups.
- [507]The SGI website
- * The SGI FAQ:
- + [508]http://www-viz.tamu.edu/~sgi-faq/
- + [509]ftp://viz.tamu.edu/pub/sgi/faq/
-
- About IRIX version numbers: "uname -a" tells the "two-digit" version
- number, such as "5.3" or "6.5". The three-digit form can be seen with
- "uname -R". (this information is unavailable at the simple API level).
- Supposedly all three-digit versions within the same two-digit version
- (e.g. 6.5.2, 6.5.3) are binary compatible; i.e. a binary built on any
- one of them should run on all others. The "m" suffix denotes just
- patches; the "f" suffix indicates that features were added.
-
- An IRIX binary built on lower MIPS model (Instruction Set Architecture,
- ISA) can run on higher models, but not vice versa:
-
- MIPS1 R3000 and below
- MIPS2 R4000
- MIPS3 R4x00
- MIPS4 R5000 and above
-
- Furthermore, there are different Application Binary Interfaces (ABIs):
-
- COFF 32 bits, IRIX 5.3, 5.2, 5.1, 4.x and below
- o32 ELF 32 bits, IRIX 5.3, 6.0 - 6.5
- N32 ELF 32 bits, IRIX 6.2 - 6.5
- N64 ELF 64 bits, IRIX 6.2 - 6.5
-
- Thus a prebuilt IRIX binary works on a particular machine only if (a)
- the machine's IRIX version (to one decimal place) is equal to or
- greater than the version under which the binary was built; (b) the
- machine's MIPS level is greater or equal to that of the binary; and (c)
- the machine supports the ABI of the binary. If all three conditions are
- not satisfied, of course, you can build a binary yourself from source
- code since, unlike some other Unix vendors, SGI does supply a C
- compiler and libraries.
-
- SGI did not supply an API for hardware flow control prior to IRIX 5.2.
- C-Kermit 6.1 and higher for IRIX 5.2 and higher supports hardware flow
- control in the normal way, via "set flow rts/cts".
-
- For hardware flow control on earlier IRIX and/or C-Kermit versions, use
- the ttyf* (modem control AND hardware flow control) devices and not the
- ttyd* (direct) or ttym* (modem control but no hardware flow control)
- ones, and obtain the proper "hardware handshaking" cable from SGI,
- which is incompatible with the ones for the Macintosh and NeXT even
- though they look the same ("man serial" for further info) and tell
- Kermit to "set flow keep" and "set modem flow rts/cts".
-
- Serial speeds higher than 38400 are available in IRIX 6.2 and later, on
- O-class machines (e.g. Origin, Octane) only, and are supported by
- C-Kermit 7.0 and later. Commands such as "set speed 115200" may be
- given on other models (e.g. Iris, Indy, Indigo) but will fail because
- the OS reports an invalid speed for the device.
-
- Experimentation with both IRIX 5.3 and 6.2 shows that when logged in to
- IRIX via Telnet, that remote-mode C-Kermit can't send files if the
- packet length is greater than 4096; the Telnet server evidently has
- this restriction (or bug), since there is no problem sending long
- packets on serial or rlogin connections. However, it can receive files
- with no problem if the packet length is greater than 4096. As a
- workaround, the FAST macro for IRIX includes "set send packet-length
- 4000". IRIX 6.5.1 does not have this problem, so evidently it was fixed
- some time after IRIX 6.2. Tests show file-transfer speeds are better
- (not worse) with 8K packets than with 4K packets from IRIX 6.5.1.
-
- Reportedly some Indys have bad serial port hardware. IRIX 5.2, for
- example, needs patch 151 to work around this; or upgrade to a later
- release. Similarly, IRIX 5.2 has several problems with serial i/o, flow
- control, etc. Again, patch or upgrade.
-
- Reportedly on machines with IRIX 4.0, Kermit cannot be suspended by
- typing the suspend ("swtch") character if it was started from csh, even
- though other programs can be suspended this way, and even though the Z
- and SUSPEND commands still work correctly. This is evidently because
- IRIX's csh does not deliver the SIGTSTP signal to Kermit. The reason
- other programs can be suspended in the same environment is probably
- that they do not trap SIGTSTP themselves, so the shell is doing the
- suspending rather than the application.
-
- Also see notes about IRIX 3.x in the [510]C-Kermit for Unix
- Installation Instructions.
-
- If you have problems making TCP/IP connections in versions of IRIX
- built with GCC 2.95.2, see the bugs section of:
-
- [511]http://freeware.sgi.com/Installable/gcc-2.95.2.html.
-
- Reportedly, if you allow gcc to compile C-Kermit on Irix you should be
- aware that there might be problems with some of the network code. The
- specifics are at
- [512]http://freeware.sgi.com/Installable/gcc-2.95.2.html; scroll down
- to the "known bugs" section at the end of the document.
-
-3.15. C-KERMIT AND THE BEBOX
-
- [ [513]Top ] [ [514]Contents ] [ [515]Section Contents ] [ [516]Next ]
- [ [517]Previous ]
-
- See also: The [518]comp.sys.be newsgroup.
-
- The BeBox has been discontinued and BeOS repositioned for PC platforms.
- The POSIX parts of BeOS are not finished, nor is the sockets library,
- therefore a fully functional version of C-Kermit is not possible. In
- version 6.0 of C-Kermit, written for BeOS DR7, it was possible to:
-
- * set line /dev/serial2 (and probably the other serial ports)
- * set speed 115200 (and at least some of the lower baud rates)
- * connect
- * set modem type hayes (and likely others, too)
- * dial phone-number
- * set send packet-length 2048 (other lengths for both send and
- receive)
- * set receive packet length 2048
- * set file type binary (text mode works, too) (with remote kermit
- session in server mode)
- * put bedrop.jpg
- * get bedrop.jpg
- * get bedrop.jpg bedrop.jpg2
- * finish, bye
-
- The following do not work:
- * kermit does not detect modem hangup
- * !/RUN/PUSH [commandline command]
- * Running kermit in remote mode
- * Using other protocols (x/y/zmodem)
- * TCP networking interface (Be's TCP/IP API has a ways to go, still)
-
- C-Kermit does not work on BeOS DR8 because of changes in the underlying
- APIs. Unfortunately not enough changes were made to allow the regular
- POSIX-based C-Kermit to work either. Note: the lack of a fork() service
- requires the select()-based CONNECT module, but there is no select().
- There is a select() in DR8, but it doesn't work.
-
- C-Kermit 7.0 was built for BeOS 4.5 and works in remote mode. It does
- not include networking support since the APIs are still not there. It
- is not known if dialing out works, but probably not. Be experts are
- welcome to lend a hand.
-
-3.16. C-KERMIT AND DG/UX
-
- [ [519]Top ] [ [520]Contents ] [ [521]Section Contents ] [ [522]Next ]
- [ [523]Previous ]
-
- Somebody downloaded the C-Kermit 6.0 binary built under DG/UX 5.40 and
- ran it under DG/UX 5.4R3.10 -- it worked OK except that file dates for
- incoming files were all written as 1 Jan 1970. Cause and cure unknown.
- Workaround: SET ATTRIBUTE DATE OFF. Better: Use a version of C-Kermit
- built under and for DG/UX 5.4R3.10.
-
-3.17. C-KERMIT AND SEQUENT DYNIX
-
- [ [524]Top ] [ [525]Contents ] [ [526]Section Contents ] [ [527]Next ]
- [ [528]Previous ]
-
- Reportedly, when coming into a Sequent Unix (DYNIX) system through an
- X.25 connection, Kermit doesn't work right because the Sequent's
- FIONREAD ioctl returns incorrect data. To work around, use the
- 1-character-at-a-time version of myread() in ckutio.c (i.e. undefine
- MYREAD in ckutio.c and rebuild the program). This is unsatisfying
- because two versions of the program would be needed -- one for use over
- X.25, and the other for serial and TCP/IP connections.
-
-3.18. C-KERMIT AND FREEBSD, OPENBSD, and NETBSD
-
- [ [529]Top ] [ [530]Contents ] [ [531]Section Contents ] [ [532]Next ]
- [ [533]Previous ]
-
- Some NebBSD users have reported difficulty escaping back from CONNECT
- mode, usually when running NetBSD on non-PC hardware. Probably a
- keyboard issue.
-
- NetBSD users have also reported that C-Kermit doesn't pop back to the
- prompt if the modem drops carrier. This needs to be checked out & fixed
- if possible.
-
- (All the above seems to work properly in C-Kermit 7.0 and later.)
-
-3.19. C-KERMIT AND MAC OS X
-
- [ [534]Top ] [ [535]Contents ] [ [536]Section Contents ] [ [537]Next ]
- [ [538]Previous ]
-
- Mac OS X is Apple's 4.4BSD Unix variety, closely related to FreeBSD,
- but different. "uname -a" is singularly uninformative, as in Linux,
- giving only the Darwin kernel version number. The way to find out the
- actual Mac OS X version is with
-
- /usr/bin/sw_vers -productName
- /usr/bin/sw_vers -productVersion
-
- or:
-
- fgrep -A 1 'ProductVersion'
- /System/Library/CoreServices/SystemVersion.plist
-
- Here are some points to be aware of:
-
- * A big gotcha for Kermit users is that Mac OS X does not support
- serial ports and, as far as I can tell, doesn't support its
- built-in modem either, for anything other than making Internet
- connections. Macintoshes capable of running Mac OS X, such as the
- G5 and later, come without serial ports and without any APIs to
- support them, and also without the UUCP family of programs
- (including cu), nor any standard for serial-port lockfile
- directory.
- * Early versions of Mac OS X came without Curses, Termlib, or
- Terminfo libraries. Later versions seem to have ncurses (it would
- seem that Mac OS X 10.3.9 was the first mature and complete version
- of Mac OS X). Kermit uses curses for its file-transfer display. See
- elsewhere about curses-vs-ncurses confusion.
- * In the HFS+ file system, filenames are case-folded. Thus "makefile"
- and "Makefile" are the same file. So, for example, suppose you are
- sending two distinct files, Foo and FOO, from (say) Linux to Mac OS
- X. This will produce a file collision that will be handled
- according to Mac OS X C-Kermit's FILE COLLISION setting, which by
- default is BACKUP, so the Mac will wind up with files called FOO
- and Foo.~1~.
- * HSF+ files that are composed of a resource fork and a data fork...
- I doubt that C-Kermit does anything useful with them. There is no
- code in C-Kermit for traditional two-forked Macintosh files, but it
- could be added if there is any demand (code for this existed in
- [539]Mac Kermit, the old pre-Mac-OS-X Macintosh version of
- C-Kermit).
- * In case you want to transfer a traditional Macintosh text file (or
- data fork of a file that is plain text), you can use these C-Kermit
- commands:
-
-set file eol cr
-set file character-set apple-quickdraw
-send /text filename
-
- * File or pathnames that include spaces must be enclosed in either
- doublequotes or curly braces in C-Kermit commands.
- * Mac OS X can use a third-party package manager called "fink".
- Various fink packages for C-Kermit are floating around that are not
- standard releases. For example, there's a C-Kermit 8.0.201 package
- in which C-Kermit was modified (at least) to use a UUCP lockfile
- directory that does not exist on vanilla Mac OS X systems.
-
-Mac OS X and Serial Ports
-
- Apple is in the forefront of companies that believe serial ports have
- no use in the modern world and so has simply eliminated all traces of
- them from its machines and OS. But of course serial ports are still
- needed to connect not only to external modems, but also to the control
- ports of hubs, routers, terminal servers, PBXs, and similar devices,
- not to mention barcode readers, POS systems and components, speaking
- devices, hand calculators such as the HP48, automated factory-floor
- equipment, and scientific, medical, and lab equipment (to name a few).
- Among workers in these areas, there is a need to add serial ports back
- onto this platform, which is being filled by third-party products such
- as the [540]Keyspan High Speed USB Serial Adapter USA-19HS, which has a
- DB-9 male connector. To use the Keyspan device, you must install the
- accompanying device drivers, which winds up giving you serial ports
- with names like /dev/cu.USA19H3b1P1.1, /dev/cu.KeySerial1,
- /dev/tty.KeySerial1.
-
- C-Kermit 9.0 works "out of the box" with third-party serial ports on
- Mac OS X, because it is built by default ("make macosx") without the
- "UUCP lockfile" feature. If you have C-Kermit 9.0 on a personal
- Macintosh, you can skip the next section.
-
-Mac OS X Serial Ports with C-Kermit 8.0 and earlier
-
- In earlier versions of C-Kermit, you'll need to either build a special
- -DNOUUCP version, or deal with the UUCP port contention sytem in
- [541]all its glory (this is usually an exercise in futility because any
- other applications on your Mac that use the serial port will not
- necessarily follow the same conventions):
-
- 1. su (or sudo -s)
- chgrp xxxx /var/spool/lock
- chmod g+w /var/spool/lock
- chgrp xxxx /dev/cu.*
- (where xxxx is the name of the group for users to whom serial-port
- access is to be granted). Use "admin" or other existing group, or
- create a new group if desired. NB:
-
- In the absence of official guidance from Apple or anyone else, we
- choose /var/spool/lock as the lockfile directory because this
- directory (a) already exists on vanilla Mac OS X installations, and
- (b) it is the directory used for serial-port lockfiles on many other
- platforms.
- 2. Put all users who need access to the serial port in the same group.
- 3. Make sure the serial device files that are to be used by C-Kermit
- have group read-write permission and (if you care) lack world
- read-write permission, e.g.:
-
- chmod g+rw,o-rw /dev/cu.*
-
- If you do the above, then there's no need to become root to use Kermit,
- or to make Kermit suid or sgid. Just do this:
-
-chmod 775 wermit
-mv wermit /usr/local/kermit
-
- (or whatever spot is more appropriate, e.g. /usr/bin/). For greater
- detail about installation, [542]CLICK HERE.
-
- Alternatively, to build a pre-9.0 version of C-Kermit without UUCP
- lockfile support, set the NOUUCP flag; e.g. (for Mac OS 10.4):
-
- make macosx10.4 KFLAGS=-DNOUUCP
-
- This circumvents the SET PORT failure "?Access to lockfile directory
- denied". But it also sacrifices Kermit's ability to ensure that only
- one copy of Kermit can have the device open at a time, since Mac OS X
- is the same as all other varieties of Unix in that exclusive access to
- serial ports is not enforced in any way. But if it's for your own
- desktop machine that nobody else uses, a -DNOUUCP version might be
- adequate and preferable to the alternatives.
-
- To build C-Kermit 9.0 with UUCP support, do:
-
- make macosx KFLAGS=-UNOUUCP
-
- (note: "-U", not "-D).
-
-RS-232 versus RS-422
-
- Meanwhile, back when Macs had serial ports, they were not RS-232 (the
- standard for connecting computers with nearby modems) but rather RS-422
- or -423 (a standard for connecting serial devices over longer
- distances). Macintosh serial ports do not support modems well because
- they do not have enough wires (or more properly in the case RS-422/423,
- wire pairs) to convey a useful subset of modem signals.
-
- Keyspan also sells a [543]USB Twin Serial Adapter that gives you two
- Mini-Din8 RS-422 ports, that are no better (or worse) for communicating
- with modems or serial devices than a real Mac Din-8 port was. In
- essence, you get Data In, Data Out, and two modem signals. It looks to
- me as if the signals chosen by Keyspan are RTS and CTS. This gives you
- hardware flow control, but at the expense of Carrier Detect. Thus to
- use C-Kermit with a Keyspan USB serial port, you must tell C-Kermit to:
-
-set modem type none ; (don't expect a modem)
-set carrier-watch off ; (ignore carrier signal)
-set port /dev/cu.USA19H3b1P1.1 ; (open the port)
-set flow rts/cts ; (this is the default)
-set speed 57600 ; (or whatever)
-connect ; (or DIAL or whatever)
-
- Use Ctrl-\C in the normal manner to escape back to the C-Kermit>
- prompt. Kermit can't pop back to its prompt automatically when Carrier
- drops because there is no Carrier signal in the physical interface.
-
- Here's a typical sequence for connecting to Cisco devices (using a
- mixture of command-line options and interactive commands at the
- prompt):
-
-$ ckermit -l /dev/cu.USA19H3b1P1.1 -b 9600
-C-Kermit> set carrier-watch off
-C-Kermit> connect
-
- Instructions for the built-in modem (if any) remain to be written due
- to lack of knowledge. If you can contribute instructions, hints, or
- tips, please [544]send them in.
-
-3.20. C-KERMIT AND COHERENT
-
- [ [545]Top ] [ [546]Contents ] [ [547]Section Contents ] [
- [548]Previous ]
-
- Also see:
-
- [549]http://www.uni-giessen.de/faq/archiv/coherent-faq.general/msg000
- 00.html
-
- Mark Williams COHERENT was perhaps the first commercial Unix-based
- operating system for PCs, first appearing about 1983 or -84 for the
- PC/XT (?), and popular until about 1993, when Linux took over.
- C-Kermit, as of version 8.0, is still current for COHERENT 386 4.2
- (i.e. only for i386 and above). Curses is included, but lots of other
- features are omitted due to lack of the appropriate OS features, APIs,
- libraries, hardware, or just space: e.g. TCP/IP, floating-point
- arithmetic, learned scripts. Earlier versions of COHERENT ran on 8086
- and 80286, but these are to small to build or run C-Kermit, but
- G-Kermit should be OK (as might be ancient versions of C-Kermit).
-
- You can actually build a version with floating point support -- just
- take -DNOFLOAT out of CFLAGS and add -lm to LIBS; NOFLOAT is the
- default because COHERENT tends to run on old PCs that don't have
- floating-point hardware. You can also add "-f" to CFLAGS to have it
- link in the floating-point emulation library. Also I'm not sure why
- -DNOLEARN is included, since it depends on select(), which COHERENT
- has.
-
-4. GENERAL UNIX-SPECIFIC HINTS, LIMITATIONS, AND BUGS
-
- [ [550]Top ] [ [551]Contents ] [ [552]Next ] [ [553]Previous ]
-
-4.1. Modem Signals
-
- There seems to be an escalating demand for the ability to control "dumb
- serial devices" (such as "smartcard readers", barcode readers, etc) by
- explicitly manipulating modem signals, particularly RTS. This might
- have been easy to do in DOS, where there is no operating system
- standing between the application and the serial device, but it is
- problematic in Unix, where modem signals are controlled by the serial
- device driver. If the driver does not provide an API for doing this,
- then the application can't do it. If it does provide an API, expect it
- to be totally different on each Unix platform, since there is no
- standard for this.
-
-4.2. NFS Troubles
-
- Beginning with C-Kermit 6.0, the default C-Kermit prompt includes your
- current (working) directory; for example:
-
- [/usr/olga] C-Kermit>
-
- (In C-Kermit 7.0 the square braces were replaced by round parentheses
- to avoid conflicts with ISO 646 national character sets.)
-
- If that directory is on an NFS-mounted disk, and NFS stops working or
- the disk becomes unavailable, C-Kermit will hang waiting for NFS and/or
- the disk to come back. Whether you can interrupt C-Kermit when it is
- hung this way depends on the specific OS. Kermit has called the
- operating systems's getcwd() function, and is waiting for it to return.
- Some versions of Unix (e.g. HP-UX 9.x) allow this function to be
- interrupted with SIGINT (Ctrl-C), others (such as HP-UX 8.x) do not. To
- avoid this effect, you can always use SET PROMPT to change your prompt
- to something that does not involve calling getcwd(), but if NFS is not
- responding, C-Kermit will still hang any time you give a command that
- refers to an NFS-mounted directory. Also note that in some cases, the
- uninterruptibility of NFS-dependent system or library calls is
- considered a bug, and sometimes there are patches. For HP-UX, for
- example:
-
- replaced by:
- HP-UX 10.20 libc PHCO_8764 PHCO_14891/PHCO_16723
- HP-UX 10.10 libc PHCO_8763 PHCO_14254/PHCO_16722
- HP-UX 9.x libc PHCO_7747 S700 PHCO_13095
- HP-UX 9.x libc PHCO_6779 S800 PHCO_11162
-
-4.3. C-Kermit as Login Shell
-
- You might have reason to make C-Kermit the login shell for a specific
- user, by entering the pathname of Kermit (possibly with command-line
- switches, such as -x to put it in server mode) into the shell field of
- the /etc/passwd file. This works pretty well. In some cases, for
- "ultimate security", you might want to use a version built with
- -DNOPUSH (see the [554]Configurations Options document for this, but
- even if you don't, then PUSHing or shelling out from C-Kermit just
- brings up a new copy of C-Kermit (but warning: this does not prevent
- the user from explicitly running a shell; e.g. "run /bin/sh"; use
- NOPUSH to prevent this).
-
-4.4. C-Kermit versus screen and splitvt
-
- C-Kermit file transfers will probably not work if attempted through the
- "splitvt" or GNU "screen" programs because the screen optimization (or
- at least, line wrapping, control-character absorption) done by this
- package interferes with Kermit's packets.
-
- The same can apply to any other environment in which the user's session
- is captured, monitored, recorded, or manipulated. Examples include the
- 'script' program (for making a typescript of a session), the
- Computronics PEEK package and pksh (at least versions of it prior to
- 1.9K), and so on.
-
- You might try the following -- what we call "doomsday Kermit" --
- settings to push packets through even the densest and most obstructive
- connections, such as "screen" and "splitvt" (and certain kinds of 3270
- protocol emulators): Give these commands to BOTH Kermit programs:
-
- SET FLOW NONE
- SET CONTROL PREFIX ALL
- SET RECEIVE PACKET-LENGTH 70
- SET RECEIVE START 62
- SET SEND START 62
- SET SEND PAUSE 100
- SET BLOCK B
-
- If it works, it will be slow.
-
-4.5. C-Kermit versus DOS Emulators
-
- On Unix workstations equipped with DOS emulators like SoftPC, watch out
- for what these emulators do to the serial port drivers. After using a
- DOS emulator, particularly if you use it to run DOS communications
- software, you might have to reconfigure the serial ports for use by
- Unix.
-
-4.6. C-Kermit versus Job Control
-
- Interruption by Ctrl-Z makes Unix C-Kermit try to suspend itself with
- kill(0,SIGTSTP), but only on platforms that support job control, as
- determined by whether the symbol SIGTSTP is defined (or on POSIX or
- SVR4 systems, if syconf(_SC_JOB_CONTROL) or _POSIX_JOB_CONTROL in
- addition to SIGTSTP). However, if Kermit is running under a login shell
- (such as the original Bourne shell) that does not support job control,
- the user's session hangs and must be logged out from another terminal,
- or hung up on. There is no way Kermit can defend itself against this.
- If you use a non-job control shell on a computer that supports job
- control, give a command like "stty susp undef" to fix it so the suspend
- signal is not attached to any particular key, or give the command SET
- SUSPEND OFF to C-Kermit, or build C-Kermit with -DNOJC.
-
-4.7. Dates and Times
-
- Unix time conversion functions typically apply locale rules to return
- local time in terms of any seasonal time zone change in effect for the
- given date. The diffdate function assumes that the same timezone rules
- are in effect for both dates, but a date with timezone information will
- be converted to the local time zone in effect at the given time, e.g.,
- a GMT specification will produce either a Standard Time or Daylight
- Savings Time, depending on which applies at the given time. An example
- using the 2001 seasonal change from EDT (-0400) to EST (-0500):
-
- C-Kermit> DATE 20011028 05:01:02 GMT ; EDT
- 20011028 01:01:02
- C-Kermit> DATE 20011028 06:01:02 GMT ; EST
- 20011028 01:01:02
- C-Kermit>
-
- but the implicit change in timezone offset is not recognized:
-
- C-Kermit> echo \fdiffdate(20011028 05:01:02 GMT, 20011028 06:01:02 GMT)
- +0:00
- C-Kermit>
-
- Date/time arithmetic, offsets, delta times, and timezone support are
- new to C-Kermit 8.0, and might be expected to evolve and improve in
- subsequent releases.
-
- On some platforms, files downloaded with HTTP receive the current
- timestamp, rather than the HTTP "Last Modified" time (this can be fixed
- by including utime.h, e.g. in SunOS and Tru64...).
-
-4.8. Pseudoterminals
-
- The SSH and PTY commands work by assigning a pseudoterminal and reading
- and writing from it. Performance varies according to the specific
- platform ranging from very fast to very flow.
-
- SSH and PTY commands can fail if (a) all pseudoterminals are in use; or
- (b) you do not have read/write access to the pseudoterminal that was
- assigned. An example of (b) was reported with the Zipslack Slackware
- Linux distribution, in which the pseudoterminals were created with
- crw-r--r-- permission, instead of crw-rw-rw-.
-
-4.9. Miscellaneous
-
- * Reportedly, the Unix C-Kermit server, under some conditions, on
- certain particular systems, fails to log out its login session upon
- receipt of a BYE command. Before relying on the BYE command
- working, test it a few times to make sure it works on your system:
- there might be system configuration or security mechanisms to
- prevent an inferior process (like Kermit) from killing a superior
- one (like the login shell).
- * On AT&T 7300 (3B1) machines, you might have to "stty nl1" before
- starting C-Kermit. Do this if characters are lost during
- communications operations.
- * Under the bash shell (versions prior to 1.07 from CWRU), "pushing"
- to an inferior shell and then exiting back to Kermit leaves Kermit
- in the background such that it must be explicitly fg'd. This is
- reportedly fixed in version 1.07 of bash (and definitely in modern
- bash versions).
-
-5. INITIALIZATION AND COMMAND FILES
-
- [ [555]Top ] [ [556]Contents ] [ [557]Next ] [ [558]Previous ]
-
- C-Kermit's initialization file for Unix is .kermrc (lowercase, starts
- with period) in your home directory, unless Kermit was built with the
- system-wide initialization-file option (see the [559]C-Kermit for Unix
- Installation Instructions).
-
- C-Kermit identifies your home directory based on the environment
- variable, HOME. Most Unix systems set this variable automatically when
- you log in. If C-Kermit can't find your initialization file, check your
- HOME variable:
-
- echo $HOME (at the Unix prompt)
-
- or:
-
- echo \$(HOME) (at the C-Kermit prompt)
-
- If HOME is not defined, or is defined incorrectly, add the appropriate
- definition to your Unix .profile or .login file, depending on your
- shell:
-
- setenv HOME full-pathname-of-your-home-directory (C-Shell, .login file)
-
- or:
-
- HOME=full-pathname-of-your-home-directory (sh, ksh, .profile file)
- export HOME
-
- NOTE: Various other operations depend on the correct definition of
- HOME. These include the "tilde-expansion" feature, which allows you to
- refer to your home directory as "~" in filenames used in C-Kermit
- commands, e.g.:
-
- send ~/.kermrc
-
- as well as the \v(home) variable.
-
- Prior to version 5A(190), C-Kermit would look for its initialization
- file in the current directory if it was not found in the home
- directory. This feature was removed from 5A(190) because it was a
- security risk. Some people, however, liked this behavior and had
- .kermrc files in all their directories that would set up things
- appropriately for the files therein. If you want this behavior, you can
- accomplish it in various ways, for example:
-
- * Create a shell alias, for example:
- alias kd="kermit -Y ./.kermrc"
-
- * Create a .kermrc file in your home directory, whose contents are:
- take ./.kermrc
-
- Suppose you need to pass a password from the Unix command line to a
- C-Kermit script program, in such a way that it does not show up in "ps"
- or "w" listings. Here is a method (not guaranteed to be 100% secure,
- but definitely more secure than the more obvious methods):
-
- echo mypassword | kermit myscript
-
- The "myscript" file contains all the commands that need to be executed
- during the Kermit session, up to and including EXIT, and also includes
- an ASK or ASKQ command to read the password from standard input, which
- has been piped in from the Unix 'echo' command, but it must not include
- a CONNECT command. Only "kermit myscript" shows up in the ps listing.
-
-6. COMMUNICATION SPEED SELECTION
-
- [ [560]Top ] [ [561]Contents ] [ [562]Next ] [ [563]Previous ]
-
- Version-7 based Unix implementations, including 4.3 BSD and earlier and
- Unix systems based upon BSD, use a 4-bit field to record a serial
- device's terminal speed. This leaves room for 16 speeds, of which the
- first 14 are normally:
-
- 0, 50, 75, 110, 134.5, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- and 9600
-
- The remaining two are usually called EXTA and EXTB, and are defined by
- the particular Unix implementation. C-Kermit determines which speeds
- are available on your system based on whether symbols for them are
- defined in your terminal device header files. EXTA is generally assumed
- to be 19200 and EXTB 38400, but these assumptions might be wrong, or
- they might not apply to a particular device that does not support these
- speeds. Presumably, if you try to set a speed that is not legal on a
- particular device, the driver will return an error, but this can not be
- guaranteed.
-
- On these systems, it is usually not possible to select a speed of 14400
- bps for use with V.32bis modems. In that case, use 19200 or 38400 bps,
- configure your modem to lock its interface speed and to use RTS/CTS
- flow control, and tell C-Kermit to SET FLOW RTS/CTS and SET DIAL
- SPEED-MATCHING OFF.
-
- The situation is similar, but different, in System V. SVID Third
- Edition lists the same speeds, 0 through 38400.
-
- Some versions of Unix, and/or terminal device drivers that come with
- certain third-party add-in high-speed serial communication interfaces,
- use the low "baud rates" to stand for higher ones. For example, SET
- SPEED 50 gets you 57600 bps; SET SPEED 75 gets you 76800; SET SPEED 110
- gets 115200.
-
- SCO ODT 3.0 is an example where a "baud-rate-table patch" can be
- applied that can rotate the tty driver baud rate table such that
- 600=57600 and 1800=115k baud. Similarly for Digiboard
- multiport/portservers, which have a "fastbaud" setting that does this.
- Linux has a "setserial" command that can do it, etc.
-
- More modern Unixes support POSIX-based speed setting, in which the
- selection of speeds is not limited by a 4-bit field. C-Kermit 6.1
- incorporates a new mechanism for finding out (at compile time) which
- serial speeds are supported by the operating system that does not
- involve editing of source code by hand; on systems like Solaris 5.1,
- IRIX 6.2, and SCO OSR5.0.4, "set speed ?" will list speeds up to 460800
- or 921600. In C-Kermit 7.0 and later:
-
- 1. If a symbol for a particular speed (say B230400 for 230400 bps)
- appears in whatever header file defines acceptable serial speeds
- (e.g. <termbits.h> or <sys/termios.h> or <sys/ttydev.h>, etc), the
- corresponding speed will appear in C-Kermit's "set speed ?" list.
- 2. The fact that a given speed is listed in the header files and
- appears in C-Kermit's list does not mean the driver will accept it.
- For example, a computer might have some standard serial ports plus
- some add-on ones with different drivers that accept a different
- repertoire of speeds.
- 3. The fact that a given speed is accepted by the driver does not
- guarantee the underlying hardware can accept it.
-
- When Kermit is given a "set speed" command for a particular device, the
- underlying system service is called to set the speed; its return code
- is checked and the SET SPEED command fails if the return code indicates
- failure. Regardless of the system service return status, the device's
- speed is then read back and if it does not match the speed that was
- requested, an error message is printed and the command fails.
-
- Even when the command succeeds, this does not guarantee successful
- operation at a particular speed, especially a high one. That depends on
- electricity, information theory, etc. How long is the cable, what is
- its capacitance, how well is it shielded, etc, not to mention that
- every connection has two ends and its success depends on both of them.
- (With the obvious caveats about internal modems, is the cable really
- connected, interrupt conflicts, etc etc etc).
-
- Note, in particular, that there is a certain threshold above which
- modems can not "autobaud" -- i.e. detect the serial interface speed
- when you type AT (or whatever else the modem's recognition sequence
- might be). Such modems need to be engaged at a lower speed (say 2400 or
- 9600 or even 115200 -- any speed below their autobaud threshold) and
- then must be given a modem-specific command (which can be found in the
- modem manual) to change their interface speed to the desired higher
- speed, and then the software must also be told to change to the new,
- higher speed.
-
- For additional information, read [564]Section 9.5 of the Installation
- Instructions, plus any platform-specific notes in [565]Section 3 above.
-
-7. COMMUNICATIONS AND DIALING
-
- [ [566]Top ] [ [567]Contents ] [ [568]Next ] [ [569]Previous ]
-
-7.1. Serial Ports and Modems
-
- If you SET LINE to a serial port modem-control device that has nothing
- plugged in to it, or has a modem connected that is powered off, and you
- have not given a prior SET MODEM TYPE or SET CARRIER-WATCH OFF command,
- the SET LINE command is likely to hang. In most cases, you can Ctrl-C
- out. If not, you'll have to kill C-Kermit from another terminal.
-
- Similarly, if you give a SET MODEM TYPE HAYES (or USR, or any other
- modem type besides DIRECT, NONE, or UNKNOWN) and then SET LINE to an
- empty port, the subsequent close (implicit or explicit) is liable to
- hang or even crash (through no fault of Kermit's -- the hanging or
- crashing is inside a system call such as cfsetospeed() or close()).
-
- The SET CARRIER-WATCH command works as advertised only if the
- underlying operating system and device drivers support this feature; in
- particular only if a read() operation returns immediately with an error
- code if the carrier signal goes away or, failing that, if C-Kermit can
- obtain the modem signals from the device driver (you can tell by giving
- a "set line" command to a serial device, and then a "show
- communications" command -- if modem signals are not listed, C-Kermit
- won't be able to detect carrier loss, the WAIT command will not work,
- etc). Of course, the device itself (e.g. modem) must be configured
- appropriately and the cables convey the carrier and other needed
- signals, etc.
-
- If you dial out from Unix system, but then notice a lot of weird
- character strings being stuck into your session at random times
- (especially if they look like +++ATQ0H0 or login banners or prompts),
- that means that getty is also trying to control the same device. You'll
- need to dial out on a device that is not waiting for a login, or else
- disable getty on the device.
-
- As of version 7.0, C-Kermit makes explicit checks for the Carrier
- Detect signal, and so catches hung-up connections much better than 6.0
- and earlier. However, it still can not be guaranteed to catch every
- ever CD on-to-off transition. For example, when the HP-UX version of
- C-Kermit is in CONNECT mode on a dialed connection and CARRIER-WATCH ON
- or AUTO, and you turn off the modem, HP-UX is stuck in a read() that
- never returns. (C-Kermit does not pop back to its prompt automatically,
- but you can still escape back.)
-
- If, on the other hand, you log out from the remote system, and it hangs
- up, and CD drops on the local modem, C-Kermit detects this and pops
- back to the prompt as it should. (Evidently there can be a difference
- between CD and DSR turning off at the same time, versus CD turning off
- while DSR stays on; experimentation with &S0/&S1/&S2 on your modem
- might produce the desired results).
-
- When Unix C-Kermit exits, it closes (and must close) the communications
- device. If you were dialed out, this will most likely hang up the
- connection. If you want to get out of Kermit and still use Kermit's
- communication device, you have several choices:
-
- 1. Shell out from Kermit or suspend Kermit, and refer to the device
- literally (as in "term -blah -blah < /dev/cua > /dev/cua").
- 2. Shell out from Kermit and use the device's file descriptor which
- Kermit makes available to you in the \v(ttyfd) variable.
- 3. Use C-Kermit's REDIRECT command.
- 4. Use C-Kermit new EXEC /REDIRECT command.
-
- If you are having trouble dialing:
-
- 1. Make sure the dialout line is configured correctly. More about this
- below.
- 2. Make sure all necessary patches are installed for your operating
- system.
- 3. If you can't dial on a "bidirectional" line, then configure it for
- outbound-only (remove the getty) and try again. (The mechanisms --
- if any -- for grabbing bidirectional lines for dialout vary wildly
- among Unix implementations and releases, and C-Kermit -- which runs
- on well over 300 different Unix variations -- makes no effort to
- keep up with them; the recommended method for coping with this
- situation is to wrap C-Kermit in a shell script that takes the
- appropriate actions.)
- 4. Make sure C-Kermit's SET DIAL and SET MODEM parameters agree with
- the modem you are actually using -- pay particular attention to SET
- DIAL SPEED-MATCHING.
- 5. If MODEM HANGUP-METHOD is set to RS232-SIGNAL, change it to
- MODEM-COMMAND. Or vice-versa.
- 6. Try SET DIAL HANGUP OFF before the DIAL command. Also, SET DIAL
- DISPLAY ON to watch what's happening. See [570]Section 8 of the
- [571]Installation Instructions.
- 7. Read pages 50-67 of [572]Using C-Kermit.
- 8. As a last resort, don't use the DIAL command at all; SET CARRIER
- OFF and CONNECT to the modem and dial interactively, or write a
- script program to dial the modem.
-
- Make sure your dialout line is correctly configured for dialing out (as
- opposed to login). The method for doing this is different for each kind
- of Unix system. Consult your system documentation for configuring lines
- for dialing out (for example, Sun SparcStation IPC users should read
- the section "Setting up Modem Software" in the Desktop SPARC Sun System
- & Network Manager's Guide; HP-9000 workstation users should consult the
- manual Configuring HP-UX for Peripherals, etc).
-
- Symptom: DIAL works, but a subsequent CONNECT command does not.
- Diagnosis: the modem is not asserting Carrier Detect (CD) after the
- connection is made, or the cable does not convey the CD signal. Cure:
- Reconfigure the modem, replace the cable. Workaround: SET CARRIER OFF
- (at least in System-V based Unix versions).
-
- For Berkeley-Unix-based systems (4.3BSD and earlier), Kermit includes
- code to use LPASS8 mode when parity is none, which is supposed to allow
- 8-bit data and Xon/Xoff flow control at the same time. However, as of
- edit 174, this code is entirely disabled because it is unreliable: even
- though the host operating system might (or might not) support LPASS8
- mode correctly, the host access protocols (terminal servers, telnet,
- rlogin, etc) generally have no way of finding out about it and
- therefore render it ineffective, causing file transfer failures. So as
- of edit 174, Kermit once again uses rawmode for 8-bit data, and so
- there is no Xon/Xoff flow control during file transfer or terminal
- emulation in the Berkeley-based versions (4.3 and earlier, not 4.4).
-
- Also on Berkeley-based systems (4.3 and earlier), there is apparently
- no way to configure a dialout line for proper carrier handling, i.e.
- ignore carrier during dialing, require carrier thereafter, get a fatal
- error on any attempt to read from the device after carrier drops (this
- is handled nicely in System V by manipulation of the CLOCAL flag). The
- symptom is that carrier loss does not make C-Kermit pop back to the
- prompt automatically. This is evident on the NeXT, for example, but not
- on SunOS, which supports the CLOCAL flag. This is not a Kermit problem,
- but a limitation of the underlying operating system. For example, the
- cu program on the NeXT doesn't notice carrier loss either, whereas cu
- on the Sun does.
-
- On certain AT&T Unix systems equipped with AT&T modems, DIAL and HANGUP
- don't work right. Workarounds: (1) SET DIAL HANGUP OFF before
- attempting to dial; (2) If HANGUP doesn't work, SET LINE, and then SET
- LINE <device> to totally close and reopen the device. If all else
- fails, SET CARRIER OFF.
-
- C-Kermit does not contain any particular support for AT&T DataKit
- devices. You can use Kermit software to dial in to a DataKit line, but
- C-Kermit does not contain the specialized code required to dial out
- from a DataKit line. If the Unix system is connected to DataKit via
- serial ports, dialout should work normally (e.g. set line /dev/ttym1,
- set speed 19200, connect, and then see the DESTINATION: prompt, from
- which you can connect to another computer on the DataKit network or to
- an outgoing modem pool, etc). But if the Unix system is connected to
- the DataKit network through the special DataKit interface board, then
- SET LINE to a DataKit pseudodevice (such as /dev/dk031t) will not work
- (you must use the DataKit "dk" or "dkcu" program instead). In C-Kermit
- 7.0 and later, you can make Kermit connections "though" dk or dkcu
- using "set line /pty".
-
- In some BSD-based Unix C-Kermit versions, SET LINE to a port that has
- nothing plugged in to it with SET CARRIER ON will hang the program (as
- it should), but it can't be interrupted with Ctrl-C. The interrupt trap
- is correctly armed, but apparently the Unix open() call cannot be
- interrupted in this case. When SET CARRIER is OFF or AUTO, the SET LINE
- will eventually return, but then the program hangs (uninterruptibly)
- when the EXIT or QUIT command (or, presumably, another SET LINE
- command) is given. The latter is probably because of the attempt to
- hang up the modem. (In edit 169, a timeout alarm was placed around this
- operation.)
-
- With SET DIAL HANGUP OFF in effect, the DIAL command might work only
- once, but not again on the same device. In that case, give a CLOSE
- command to close the device, and then another SET LINE command to
- re-open the same device. Or rebuild your version of Kermit with the
- -DCLSOPN compile-time switch.
-
- The DIAL command says "To cancel: Type your interrupt character
- (normally Ctrl-C)." This is just one example of where program messages
- and documentation assume your interrupt character is Ctrl-C. But it
- might be something else. In most (but not necessarily all) cases, the
- character referred to is the one that generates the SIGINT signal. If
- Ctrl-C doesn't act as an interrupt character for you, type the Unix
- command "stty -a" or "stty all" or "stty everything" to see what your
- interrupt character is. (Kermit could be made to find out what the
- interrupt character is, but this would require a lot of
- platform-dependent coding and #ifdefs, and a new routine and interface
- between the platform-dependent and platform-independent parts of the
- program.)
-
- In general, the hangup operation on a serial communication device is
- prone to failure. C-Kermit tries to support many, many different kinds
- of computers, and there seems to be no portable method for hanging up a
- modem connection (i.e. turning off the RS-232 DTR signal and then
- turning it back on again). If HANGUP, DIAL, and/or Ctrl-\H do not work
- for you, and you are a programmer, look at the tthang() function in
- ckutio.c and see if you can add code to make it work correctly for your
- system, and send the code to the address above. (NOTE: This problem has
- been largely sidestepped as of edit 188, in which Kermit first attempts
- to hang up the modem by "escaping back" via +++ and then giving the
- modem's hangup command, e.g. ATH0, when DIAL MODEM-HANGUP is ON, which
- is the default setting.)
-
- Even when Kermit's modem-control software is configured correctly for
- your computer, it can only work right if your modem is also configured
- to assert the CD signal when it is connected to the remote modem and to
- hang up the connection when your computer drops the DTR signal. So
- before deciding Kermit doesn't work with your modem, check your modem
- configuration AND the cable (if any) connecting your modem to the
- computer -- it should be a straight-through [573]modem cable conducting
- the signals FG, SG, TD, RD, RTS, CTS, DSR, DTR, CD, and RI.
-
- Many Unix systems keep aliases for dialout devices; for example,
- /dev/acu might be an alias for /dev/tty00. But most of these Unix
- systems also use UUCP lockfile conventions that do not take this
- aliasing into account, so if one user assigns (e.g.) /dev/acu, then
- another user can still assign the same device by referring to its other
- name. This is not a Kermit problem -- Kermit must follow the lockfile
- conventions used by the vendor-supplied software (cu, tip, uucp).
-
- The SET FLOW-CONTROL KEEP option should be given *before* any
- communication (dialing, terminal emulation, file transfer,
- INPUT/OUTPUT/TRANSMIT, etc) is attempted, if you want C-Kermit to use
- all of the device's preexisting flow-control related settings. The
- default flow-control setting is XON/XOFF, and it will take effect when
- the first communication-related command is given, and a subsequent SET
- FLOW KEEP command will not necessarily know how to restore *all* of the
- device's original flow-control settings.
-
-7.2. Network Connections
-
- C-Kermit tries to use the 8th bit for data when parity is NONE, and
- this generally works on real Unix terminal (tty) devices, but it often
- does not work when the Unix system is accessed over a network via
- telnet or rlogin protocols, including (in many cases) through terminal
- servers. For example, an Encore computer with Annex terminal servers
- only gives a 7-bit path if the rlogin protocol is selected in the
- terminal server but it gives the full 8 bits if the proprietary RDP
- protocol is used.
-
- If file transfer does not work through a host to which you have
- rlogin'd, use "rlogin -8" rather than "rlogin". If that doesn't work,
- tell both Kermit programs to "set parity space".
-
- The Encore TELNET server does not allow long bursts of input. When you
- have a TELNET connection to an Encore, tell C-Kermit on the Encore to
- SET RECEIVE PACKET-LENGTH 200 or thereabouts.
-
-8. HARDWARE FLOW CONTROL
-
- [ [574]Top ] [ [575]Contents ] [ [576]Next ] [ [577]Previous ]
-
- SET FLOW RTS/CTS is available in Unix C-Kermit only when the underlying
- operating system provides an Application Program Interface (API) for
- turning this feature on and off under program control, which turns out
- to be a rather rare feature among Unix systems. To see if your Unix
- C-Kermit version supports hardware flow control, type "set flow ?" at
- the C-Kermit prompt, and look for "rts/cts" among the options. Other
- common situations include:
-
- 1. The API is available, so "set flow rts/cts" appears as a valid
- C-Kermit command, but it doesn't do anything because the device
- driver (part of the operating system) was never coded to do
- hardware flow control. This is common among System V R4
- implementations (details below).
- 2. The API is not available, so "set flow rts/cts" does NOT appear as
- a valid C-Kermit command, but you can still get RTS/CTS flow
- control by selecting a specially named device in your SET LINE
- command. Examples:
- + NeXTSTEP: /dev/cufa instead of /dev/cua, /dev/cufb instead of
- /dev/cub (68040 only; "man zs" for further info).
- + IRIX: /dev/ttyf2 instead of /dev/ttyd2 or /dev/ttym2 ("man 7
- serial").
- 3. The API is available, doesn't work, but a workaround as in (2) can
- be used.
- 4. The API is available, but Kermit doesn't know about it. In these
- cases, you can usually use an stty command to enable RTS/CTS on the
- device, e.g. "stty crtscts" or "stty ctsflow", "stty rtsflow",
- before starting Kermit, and then tell Kermit to SET FLOW KEEP.
- 5. No API and no special device drivers. Hardware flow control is
- completely unavailable.
-
- System V R4 based Unixes are supposed to supply a <termiox.h> file,
- which gives Kermit the necessary interface to command the terminal
- driver to enable/disable hardware flow control. Unfortunately, but
- predictably, many implementations of SVR4 whimsically place this file
- in /usr/include/sys rather than /usr/include (where SVID clearly
- specifies it should be; see SVID, Third Edition, V1, termiox(BA_DEV).
- Thus if you build C-Kermit with any of the makefile entries that
- contain -DTERMIOX or -DSTERMIOX (the latter to select <sys/termiox.h>),
- C-Kermit will have "set flow rts/cts" and possibly other hardware
- flow-control related commands. BUT... That does not necessarily mean
- that they will work. In some cases, the underlying functions are simply
- not coded into the operating system.
-
- WARNING: When hardware flow control is available, and you enable in
- Kermit on a device that is not receiving the CTS signal, Kermit can
- hang waiting for CTS to come up. This is most easily seen when the
- local serial port has nothing plugged in to it, or is connected to an
- external modem that is powered off.
-
-9. TERMINAL CONNECTION AND KEY MAPPING
-
- [ [578]Top ] [ [579]Contents ] [ [580]Next ] [ [581]Previous ]
-
- C-Kermit is not a terminal emulator. Refer to page 147 of [582]Using
- C-Kermit, 2nd Edition: "Most versions of C-Kermit -- Unix, VMS, AOS/VS,
- VOS, etc -- provide terminal connection without emulation. These
- versions act as a 'semitransparent pipe' between the remote computer
- and your terminal, terminal emulator, console driver, or window, which
- in turn emulates (or is) a specific kind of terminal." The environment
- in which you run C-Kermit is up to you.
-
- If you are an X Windows user, you should be aware of an alternative to
- xterm that supports VT220 emulation, from Thomas E. Dickey:
-
- [583]http://dickey.his.com/xterm/xterm.html
-
- Unix C-Kermit's SET KEY command currently can not be used with keys
- that generate "wide" scan codes or multibyte sequences, such as
- workstation function or arrow keys, because Unix C-Kermit does not have
- direct access to the keyboard.
-
- However, many Unix workstations and/or console drivers provide their
- own key mapping feature. With xterm, for example, you can use 'xmodmap'
- ("man xmodmap" for details); here is an xterm mapping to map the Sun
- keyboard to DEC VT200 values for use with VT-terminal oriented
- applications like VMS EVE:
-
- keycode 101=KP_0
- keycode 119=KP_1
- keycode 120=KP_2
- keycode 121=KP_3
- keycode 98=KP_4
- keycode 99=KP_5
- keycode 100=KP_6
- keycode 75=KP_7
- keycode 76=KP_8
- keycode 77=KP_9
- keycode 52=KP_F1
- keycode 53=KP_F2
- keycode 54=KP_F3
- keycode 57=KP_Decimal
- keycode 28=Left
- keycode 29=Right
- keycode 30=KP_Separator
- keycode 105=KP_F4
- keycode 78=KP_Subtract
- keycode 8=Left
- keycode 10=Right
- keycode 32=Up
- keycode 33=Down
- keycode 97=KP_Enter
-
- Users of Linux consoles can use loadkeys ("man dumpkeys loadkeys
- keytables" for details. The format used by loadkeys is compatible with
- that used by Xmodmap, although it is not definitely certain that the
- keycodes are compatible for different keyboard types (e.g. Sun vs HP vs
- PC, etc).
-
-10. FILE TRANSFER
-
- [ [584]Top ] [ [585]Contents ] [ [586]Next ] [ [587]Previous ]
-
- On most platforms, C-Kermit can not handle files longer than 2^31 or
- 2^32 bytes long, because it uses the traditional file i/o APIs that use
- 32-bit words to represent the file size. To accommodate longer files,
- we would have to switch to a new and different API. Unfortunately, each
- platform has a different one, a nightmare to handle in portable code.
- The C-Kermit file code was written in the days long before files longer
- than 2GB were supported or even contemplated in the operating systems
- where C-Kermit ran.
-
- If uploads (or downloads) fail immediately, give the CAUTIOUS command
- to Kermit and try again. If they still fail, then try SET PREFIXING
- ALL. If they still fail, try SET PARITY SPACE. If they still fail, try
- ROBUST.
-
- If reception (particularly of large files and/or binary files) begins
- successfully but then fail consistently after a certain amount of bytes
- have been sent, check:
-
- * Your ulimit ("ulimit -a")
- * The amount of available space on the target disk ("df ." or "df -k
- .")
- * Your personal disk quota (platform- and site-dependent)
- * The maximum file size on the receiver's file system (e.g. 2GB in
- old versions the Linux VFS file system, and/or in applications that
- have not been recoded to use new "large file" APIs).
- * If it's an NFS-mounted disk (if so, try uploading to a local disk)
- * Is there an "idle limit" on the receiving end?
-
- If none of these seem to explain it, then the problem is not size
- related, but reflects some clash between the file contents and the
- characteristics of the connection, in which case follow the
- instructions in the first paragraph of this section.
-
- Suppose two copies of Kermit are receiving files into the same
- directory, and the files have the same name, e.g. "foo.bar". Whichever
- one starts first opens an output file called "foo.bar". The second one
- sees there is already a foo.bar file, and so renames the existing
- foo.bar to foo.bar.~1~ (or whatever). When the first file has been
- received completely, Kermit goes to change its modification time and
- permissions to those given by the file sender in the Attribute packet.
- But in Unix, the APIs for doing this take a filename, not a file
- descriptor. Since the first Kermit's file has been renamed, and the
- second Kermit is using the original name, the first Kermit changes the
- modtime and permissions of the second Kermit's file, not its own.
- Although there might be a way to work around this in the code, e.g.
- using inode numbers to keep track of which file is which, this would be
- tricky and most likely not very portable. It's better to set up your
- application to prevent such things from happening, which is easy enough
- using the script language, filename templates, etc.
-
- Suppose you start C-Kermit with a command-line argument to send or
- receive a file (e.g. "kermit -r") and then type Ctrl-\c immediately
- afterwards to escape back and initiate the other end of the transfer,
- BUT your local Kermit's escape character is not Ctrl-\. In this case,
- the local Kermit passes the Ctrl-\ to the remote system, and if this is
- Unix, Ctrl-\ is likely to be its SIGQUIT character, which causes the
- current program to halt and dump core. Well, just about the first thing
- C-Kermit does when it starts is to disable the SIGQUIT signal. However,
- it is still possible for SIGQUIT to cause Kermit to quit and dump core
- if it is delivered while Kermit is being loaded or started, before the
- signal can be disabled. There's nothing Kermit itself can do about
- this, but you can prevent it from happening by disabling SIGQUIT in
- your Unix session. The command is usually something like:
-
- stty quit undef
-
- Unix C-Kermit does not reject incoming files on the basis of size.
- There appears to be no good (reliable, portable) way to determine in
- advance how much disk space is available, either on the device, or
- (when quotas or other limits are involved) to the user.
-
- Unix C-Kermit discards all carriage returns from incoming files when in
- text mode.
-
- If C-Kermit has problems creating files in writable directories when it
- is installed setuid or setgid on BSD-based versions of Unix such as
- NeXTSTEP 3.0, it probably needs to be rebuilt with the -DSW_ACC_ID
- compilation switch.
-
- If you SET FILE DISPLAY FULLSCREEN, and C-Kermit complains "Sorry,
- terminal type not supported", it means that the terminal library
- (termcap or termlib) that C-Kermit was built with does not know about a
- terminal whose name is the current value of your TERM environment
- variable. If this happens, but you want to have the fullscreen file
- transfer display, EXIT from C-Kermit and set a Unix terminal type from
- among the supported values that is also supported by your terminal
- emulator, or else have an entry for your terminal type added to the
- system termcap and/or terminfo database.
-
- If you attempt to suspend C-Kermit during local-mode file transfer and
- then continue it in the background (via bg), it will block for "tty
- output" if you are using the FULLSCREEN file transfer display. This is
- apparently a problem with curses. Moving a local-mode file transfer
- back and forth between foreground and background works correctly,
- however, with the SERIAL, CRT, BRIEF, or NONE file transfer displays.
-
- If C-Kermit's command parser no longer echoes, or otherwise acts
- strangely, after returning from a file transfer with the fullscreen
- (curses) display, and the curses library for your version of Unix
- includes the newterm() function, then try rebuilding your version of
- C-Kermit with -DCK_NEWTERM. Similarly if it echoes doubly, which might
- even happen during a subsequent CONNECT session. If rebuilding with
- -DCK_NEWTERM doesn't fix it, then there is something very strange about
- your system's curses library, and you should probably not use it. Tell
- C-Kermit to SET FILE DISPLAY CRT, BRIEF, or anything else other than
- FULLSCREEN, and/or rebuild without -DCK_CURSES, and without linking
- with (termlib and) curses. Note: This problem seemed to have escalated
- in C-Kermit 7.0, and -DCK_NEWTERM had to be added to many builds that
- previously worked without it: Linux, AIX 4.1, DG/UX, etc. In the Linux
- case, it is obviously because of changes in the (n)curses library; the
- cause in the other cases is not known.
-
- C-Kermit creates backup-file names (such as "oofa.txt.~1~") based on
- its knowledge of the maximum filename length on the platform where it
- is running, which is learned at compile time, based on MAXNAMLEN or
- equivalent symbols from the system header files. But suppose C-Kermit
- is receiving files on a Unix platform that supports long filenames, but
- the incoming files are being stored on an NFS-mounted file system that
- supports only short names. NFS maps the external system to the local
- APIs, so C-Kermit has no way of knowing that long names will be
- truncated. Or that C-Kermit is running on a version of Unix that
- supports both long-name and short-name file systems simultaneously
- (such as HP-UX 7.00). This can cause unexpected behavior when creating
- backup files, or worse. For example, you are sending a group of files
- whose names are differentiated only by characters past the point at
- which they would be truncated, each file will overwrite the previous
- one upon arrival.
-
-11. EXTERNAL FILE TRANSFER PROTOCOLS
-
- [ [588]Top ] [ [589]Contents ] [ [590]Next ] [ [591]Previous ]
-
- SECTION CONTENTS
-
- 11.1. [592]C-Kermit as an External Protocol
- 11.2. [593]Invoking External Protocols from C-Kermit
-
- Unix C-Kermit can be used in conjunction with other communications
- software in various ways. C-Kermit can be invoked from another
- communications program as an "external protocol", and C-Kermit can also
- invoke other communication software to perform external protocols.
-
- This sort of operation makes sense only when you are dialing out from
- your Unix system (or making a network connection from it). If the Unix
- system is the one you have dialed in to, you don't need any of these
- tricks. Just run the desired software on your Unix system instead of
- Kermit. When dialing out from a Unix system, the difficulty is getting
- two programs to share the same communication device in spite of the
- Unix UUCP lockfile mechanism, which would normally prevent any sharing,
- and preventing the external protocol from closing (and therefore
- hanging up) the device when it exits back to the program that invoked
- it.
-
-11.1. C-KERMIT AS AN EXTERNAL PROTOCOL
-
- [ [594]Top ] [ [595]Contents ] [ [596]Section Contents ] [ [597]Next ]
-
- (This section deleted; see [598]Using C-Kermit, 2nd Ed, Chapter 14.)
-
- "pcomm" is a general-purpose terminal program that provides file
- transfer capabilities itself (X- and YMODEM variations) and the ability
- to call on external programs to do file transfers (ZMODEM and Kermit,
- for example). You can tell pcomm the command to send or receive a file
- with an external protocol:
- Send Receive
- ZMODEM sz filename rz
- Kermit kermit -s filename kermit -r
-
- pcomm runs external programs for file transfer by making stdin and
- stdout point to the modem port, and then exec-ing "/bin/sh -c xxx"
- (where xxx is the appropriate command). However, C-Kermit does not
- treat stdin and stdout as the communication device unless you instruct
- it:
-
-
- Send Receive
- Kermit kermit -l 0 -s filename kermit -l 0 -r
-
- The "-l 0" option means to use file descriptor 0 for the communication
- device.
-
- In general, any program can pass any open file descriptor to C-Kermit
- for the communication device in the "-l" command-line option. When
- Kermit is given a number as the argument to the "-l" option, it simply
- uses it as a file descriptor, and it does not attempt to close it upon
- exit.
-
- Here's another example, for Seyon (a Linux communication program).
- First try the technique above. If that works, fine; otherwise... If
- Seyon does not give you a way to access and pass along the file
- descriptor, but it starts up the Kermit program with its standard i/o
- redirected to its (Seyon's) communications file descriptor, you can
- also experiment with the following method, which worked here in brief
- tests on SunOS. Instead of having Seyon use "kermit -r" or "kermit -s
- filename" as its Kermit protocol commands, use something like this
- (examples assume C-Kermit 6.0):
-
- For serial connections:
-
- kermit -YqQl 0 -r <-- to receive
- kermit -YqQl 0 -s filename(s) <-- to send one or more files
-
- For Telnet connections:
-
- kermit -YqQF 0 -r <-- to receive
- kermit -YqQF 0 -s filename(s) <-- to send one or more files
-
- Command line options:
-
- Y - skip executing the init file
- Q - use fast file transfer settings (default in 8.0)
- l 0 - transfer files using file descriptor 0 for a serial connection
- F 0 - transfer files using file descriptor 0 for a Telnet connection
- q - quiet - no messages
- r - receive
- s - send
-
-11.2. INVOKING EXTERNAL PROTOCOLS FROM C-KERMIT
-
- [ [599]Top ] [ [600]Contents ] [ [601]Section Contents ] [
- [602]Previous ]
-
- (This section is obsolete, but not totally useless. See Chapter 14
- of [603]Using C-Kermit, 2nd Edition).
-
- After you have opened a communication link with C-Kermit's SET LINE
- (SET PORT) or SET HOST (TELNET) command, C-Kermit makes its file
- descriptor available to you in the \v(ttyfd) variable so you can pass
- it along to other programs that you RUN from C-Kermit. Here, for
- example, C-Kermit runs itself as an external protocol:
-
- C-Kermit>set modem type hayes
- C-Kermit>set line /dev/acu
- C-Kermit>set speed 2400
- C-Kermit>dial 7654321
- Call complete.
- C-Kermit>echo \v(ttyfd)
- 3
- C-Kermit>run kermit -l \v(ttyfd)
-
- Other programs that accept open file descriptors on the command line
- can be started in the same way.
-
- You can also use your shell's i/o redirection facilities to assign
- C-Kermit's open file descriptor (ttyfd) to stdin or stdout. For
- example, old versions of the Unix ZMODEM programs, sz and rz, when
- invoked as external protocols, expect to find the communication device
- assigned to stdin and stdout with no option for specifying any other
- file descriptor on the sz or rz command line. However, you can still
- invoke sz and rz as exterior protocols from C-Kermit if your current
- shell ($SHELL variable) is ksh (the Korn shell) or bash (the
- Bourne-Again shell), which allows assignment of arbitrary file
- descriptors to stdin and stdout:
-
- C-Kermit> run rz <&\v(ttyfd) >&\v(ttyfd)
-
- or:
-
- C-Kermit> run sz oofa.zip <&\v(ttyfd) >&\v(ttyfd)
-
- In version 5A(190) and later, you can use C-Kermit's REDIRECT command,
- if it is available in your version of C-Kermit, to accomplish the same
- thing without going through the shell:
-
- C-Kermit> redirect rz
-
- or:
-
- C-Kermit> redirect sz oofa.zip
-
- A complete set of rz,sz,rb,sb,rx,sx macros for Unix C-Kermit is defined
- in the file ckurzsz.ini. It automatically chooses the best redirection
- method (but is redundant since C-Kermit 6.0, which now has built-in
- support for external protocols via its SET PROTOCOL command).
-
- Note that external protocols can be used on C-Kermit SET LINE or SET
- HOST connections only if they operate through standard input and
- standard output. If they open their own connections, Kermit can't
- redirect them over its own connection.
-
-12. SECURITY
-
- [ [604]Top ] [ [605]Contents ] [ [606]Next ] [ [607]Previous ]
-
- As of version 7.0, C-Kermit supports a wide range of security options
- for authentication and encryption: Kerberos 4, Kerberos 5 / GSSAPI,
- SSL/TLS, and SRP. See the separate [608]security document for details.
-
-13. MISCELLANEOUS USER REPORTS
-
- [ [609]Top ] [ [610]Contents ] [ [611]Next ] [ [612]Previous ]
-
-Date: Thu, 12 Mar 92 1:59:25 MEZ
-From: Walter Mecky <walter@rent-a-guru.de>
-Subject: Help.Unix.sw
-To: svr4@pcsbst.pcs.com, source@usl.com
-
-PRODUCT: Unix
-RELEASE: Dell SVR4 V2.1 (is USL V3.0)
-MACHINE: AT-386
-PATHNAME: /usr/lib/libc.so.1
- /usr/ccs/lib/libc.a
-ABSTRACT: Function ttyname() does not close its file descriptor
-DESCRIPTION:
- ttyname(3C) opens /dev but never closes it. So if it is called
- often enough the open(2) in ttyname() fails. Because the broken
- ttyname() is in the shared lib too all programs using it can
- fail if they call it often enough. One important program is
- uucico which calls ttyname for every file it transfers.
-
-
- Here is a little test program if your system has the bug:
-
-#include <stdlib.h>
-#include <stdio.h>
-main() {
- int i = 0;
- while (ttyname(0) != NULL)
- i++;
- perror("ttyname");
- printf("i=%d\n", i);
-}
-
- If this program runs longer than some seconds you don't have the bug.
-
- WORKAROUND: None FIX: Very easy if you have source code.
-
- Another user reports some more explicit symptoms and recoveries:
-
-> What happens is when invoking ckermit we get one of the following
-> error messages:
-> You must set line
-> Not a tty
-> No more processes.
-> One of the following three actions clears the problem:
-> shutdown -y -g0 -i6
-> kill -9 the ttymon with the highest PID
-> Invoke sysadm and disable then enable the line you want to use.
-> Turning off respawn of sac -t 300 and going to getty's and uugetty's
-> does not help.
->
-> Also C-Kermit reports "?timed out closing /dev/ttyxx".
-> If this happens all is well.
-
-------------------------------
-
- (Note: the following problem also occurs on SGI and probably many other
- Unix systems):
-
- From: James Spath <spath@jhunix.hcf.jhu.edu>
- To: Info-Kermit-Request@cunixf.cc.columbia.edu
- Date: Wed, 9 Sep 1992 20:20:28 -0400
- Subject: C-Kermit vs uugetty (or init) on Sperry 5000
-
- We have successfully compiled the above release on a Unisys/Sperry
- 5000/95. We used the sys5r3 option, rather than sys5r2 since we have
- VR3 running on our system. In order to allow dialout access to
- non-superusers, we had to do "chmod 666 /dev/tty###, where it had been
- -rw--w--w- (owned by uucp), and to do "chmod +w /usr/spool/locks". We
- have done text and binary file transfers through local and remote
- connections.
-
- The problem concerning uucp ownership and permissions is worse than I
- thought at first. Apparently init or uugetty changes the file
- permissions after each session. So I wrote the following C program to
- open a set of requested tty lines. I run this for any required outgoing
- line prior to a Kermit session.
-
- ------ cut here -------
-/* opentty.c -- force allow read on tty lines for modem i/o */
-/* idea from: restrict.c -- System 5 Admin book Thomas/Farrow p. 605 */
-/* /jes jim spath {spath@jhunix.hcj.jhu.edu } */
-/* 08-Sep-92 NO COPYRIGHT. */
-/* this must be suid to open other tty lines */
-
-/* #define DEBUG */
-#define TTY "/dev/tty"
-#define LOK "/usr/spool/locks/LCK..tty"
-#include <stdio.h>
-
-/* allowable lines: */
-#define TOTAL_LINES 3
-static char allowable[TOTAL_LINES][4] = { "200", "201", "300" };
-static int total=TOTAL_LINES;
-int allow;
-
-/* states: */
-#define TTY_UNDEF 0
-#define TTY_LOCK 1
-#define TTY_OKAY 2
-
-main(argc, argv)
-int argc; char *argv[]; {
- char device[512];
- char lockdev[512];
- int i;
- if (argc == 1) {
- fprintf(stderr, "usage: open 200 [...]\n");
- }
- while (--argc > 0 && (*++argv) != NULL ) {
-#ifdef DEBUG
- fprintf(stderr, "TRYING: %s%s\n", TTY, *argv);
-#endif
- sprintf(device, "%s%s", TTY, *argv);
- sprintf(lockdev, "%s%s", LOK, *argv);
- allow = TTY_UNDEF; i = 0;
- while (i <= total) { /* look at all defined lines */
-#ifdef DEBUG
- fprintf(stderr, "LOCKFILE? %s?\n", lockdev);
-#endif
- if (access(lockdev, 00) == 0) {
- allow=TTY_LOCK;
- break;
- }
-#ifdef DEBUG
- fprintf(stderr, "DOES:%s==%s?\n", allowable[i], *argv);
-#endif
- if (strcmp(allowable[i], *argv) == 0)
- allow=TTY_OKAY;
- i++;
- }
-#ifdef DEBUG
- fprintf(stderr, "allow=%d\n", allow);
-#endif
- switch (allow) {
- case TTY_UNDEF:
- fprintf (stderr, "open: not allowed on %s\n", *argv);
- break;
- case TTY_LOCK:
- fprintf (stderr, "open: device locked: %s\n", lockdev);
- break;
- case TTY_OKAY:
- /* attempt to change mode on device */
- if (chmod (device, 00666) < 0)
- fprintf (stderr, "open: cannot chmod on %s\n", device);
- break;
- default:
- fprintf (stderr, "open: FAULT\n");
- }
- }
- exit (0);
-}
-
-14. THIRD-PARTY DRIVERS
-
- [ [613]Top ] [ [614]Contents ] [ [615]Next ] [ [616]Previous ]
-
- Unix versions, especially those for PCs (SCO, Unixware, etc) might be
- augmented by third-party communication-board drivers from Digiboard,
- Stallion, etc. These can sometimes complicate matters for Kermit
- considerably since Kermit has no way of knowing that it is going
- through a possibly nonstandard driver. Various examples are listed in
- the earlier sections of this document; search for Stallion, Digiboard,
- etc. Additionally:
-
- * The Stallion Technologies EasyConnection serial board driver does
- not always report the state of DSR as low. From Stallion (October
- 1997): "Unfortunately, this is a bug in our driver. We have
- implemented all of the other TIOMC functions, eg DTR, DCD, RTS and
- CTS, but not DSR. Our driver should report the actual state of DSR
- on those of our cards that have a DSR signal. That the driver
- always reports DSR as not asserted (0), is a bug in the driver. The
- driver should be either reporting the state of DSR correctly on
- those cards that support DSR or as always asserted (1) on those
- cards that do not have a DSR signal. This will be fixed in a future
- version of our drivers; at this time I cannot say when this will
- be." And later, "As far as I can tell, we don't support the
- termios/termiox ioctls that relate specifically to DSR and RI; all
- the rest are supported. This will, as I mentioned earlier, be fixed
- in the next release of our ATA software."
- - World Wide Escalation Support, Stallion Technologies, Toowong
- QLD, [617]support@stallion.oz.au.
-
- Later (December 1997, from the same source):
-
- * We have now released a new version of the ATA software, version
- 5.4.0. This version fixes the problem with the states of the DSR
- and RI signals and how they were being reported by the driver. This
- is the problem that you reported in October. The DSR signal is
- reported correctly on those cards that support the DSR signal, such
- as the early revision of the EasyIO card and the EasyConnection 8D4
- panel, and as always asserted on those cards that do not support
- the DSR signal in the hardware. The new driver is available from
- our Web site, [618]www.stallion.com, in the /drivers/ata5/UnixWare
- directory.
-
- [ [619]Top ] [ [620]Contents ] [ [621]C-Kermit Home ] [ [622]C-Kermit
- 8.0 Overview ] [ [623]Kermit Home ]
- __________________________________________________________________
-
- C-Kermit 8.0 Unix Hints and Tips / [624]The Kermit Project /
- [625]Columbia University / [626]kermit@columbia.edu
-
-References
-
- 1. http://www.columbia.edu/
- 2. mailto:kermit@columbia.edu
- 3. http://www.columbia.edu/kermit/index.html
- 4. http://www.columbia.edu/kermit/k95.html
- 5. http://www.columbia.edu/kermit/ckermit.html
- 6. http://www.columbia.edu/kermit/ckscripts.html
- 7. http://www.columbia.edu/kermit/current.html
- 8. http://www.columbia.edu/kermit/whatsnew.html
- 9. http://www.columbia.edu/kermit/faq.html
- 10. http://www.columbia.edu/kermit/support.html
- 11. http://www.columbia.edu/kermit/
- 12. http://www.columbia.edu/
- 13. http://www.columbia.edu/kermit/ckubwr.html
- 14. http://www.columbia.edu/kermit/ckdaily.html
- 15. http://www.columbia.edu/kermit/ckdaily.html
- 16. http://www.columbia.edu/kermit/ckdaily.html
- 17. http://www.columbia.edu/kermit/ckermit.html
- 18. http://www.columbia.edu/kermit/ckuins.html
- 19. http://www.columbia.edu/kermit/ckututor.html
- 20. http://www.columbia.edu/kermit/ckubwr.html#x1
- 21. http://www.columbia.edu/kermit/ckubwr.html#x2
- 22. http://www.columbia.edu/kermit/ckubwr.html#x3
- 23. http://www.columbia.edu/kermit/ckubwr.html#x4
- 24. http://www.columbia.edu/kermit/ckubwr.html#x5
- 25. http://www.columbia.edu/kermit/ckubwr.html#x6
- 26. http://www.columbia.edu/kermit/ckubwr.html#x7
- 27. http://www.columbia.edu/kermit/ckubwr.html#x8
- 28. http://www.columbia.edu/kermit/ckubwr.html#x9
- 29. http://www.columbia.edu/kermit/ckubwr.html#x10
- 30. http://www.columbia.edu/kermit/ckubwr.html#x11
- 31. http://www.columbia.edu/kermit/ckubwr.html#x12
- 32. http://www.columbia.edu/kermit/ckubwr.html#x13
- 33. http://www.columbia.edu/kermit/ckubwr.html#x14
- 34. http://www.columbia.edu/kermit/ckubwr.html#x3.3
- 35. http://www.columbia.edu/kermit/ckubwr.html#x3.18
- 36. http://www.columbia.edu/kermit/ckubwr.html#x3.19
- 37. http://www.columbia.edu/kermit/ckubwr.html#x3.1
- 38. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 39. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 40. http://www.columbia.edu/kermit/ckubwr.html#x3.6
- 41. http://www.columbia.edu/kermit/ckubwr.html#top
- 42. http://www.columbia.edu/kermit/ckubwr.html#contents
- 43. http://www.columbia.edu/kermit/ckubwr.html#x2
- 44. http://www.columbia.edu/kermit/ckubwr.html#x1.1
- 45. http://www.columbia.edu/kermit/ckubwr.html#x1.2
- 46. http://www.columbia.edu/kermit/ckubwr.html#x1.3
- 47. http://www.columbia.edu/kermit/ckubwr.html#x1.4
- 48. http://www.columbia.edu/kermit/ckubwr.html#x3.3
- 49. http://www.columbia.edu/kermit/ckubwr.html#x3.1
- 50. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 51. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 52. http://www.columbia.edu/kermit/ckcbwr.html
- 53. mailto:kermit-support@columbia.edu
- 54. http://www.columbia.edu/kermit/ckubwr.html#top
- 55. http://www.columbia.edu/kermit/ckubwr.html#contents
- 56. http://www.columbia.edu/kermit/ckubwr.html#x1.2
- 57. http://www.columbia.edu/kermit/ck60manual.html
- 58. http://www.columbia.edu/kermit/ckermit70.html
- 59. http://www.columbia.edu/kermit/ckermit80.html
- 60. http://www.columbia.edu/kermit/ckermit90.html
- 61. http://www.columbia.edu/kermit/ckubwr.html#top
- 62. http://www.columbia.edu/kermit/ckubwr.html#contents
- 63. http://www.columbia.edu/kermit/ckubwr.html#x1
- 64. http://www.columbia.edu/kermit/ckubwr.html#x1.3
- 65. http://www.columbia.edu/kermit/ckubwr.html#x1.1
- 66. http://www.columbia.edu/kermit/support.html
- 67. http://www.columbia.edu/kermit/ckubwr.html#top
- 68. http://www.columbia.edu/kermit/ckubwr.html#contents
- 69. http://www.columbia.edu/kermit/ckubwr.html#x1
- 70. http://www.columbia.edu/kermit/ckubwr.html#x1.4
- 71. http://www.columbia.edu/kermit/ckubwr.html#x1.2
- 72. http://www.columbia.edu/kermit/ckubwr.html#top
- 73. http://www.columbia.edu/kermit/ckubwr.html#contents
- 74. http://www.columbia.edu/kermit/ckubwr.html#x1
- 75. http://www.columbia.edu/kermit/ckubwr.html#x1.3
- 76. http://www.columbia.edu/kermit/ckubwr.html#top
- 77. http://www.columbia.edu/kermit/ckubwr.html#contents
- 78. http://www.columbia.edu/kermit/ckubwr.html#x3
- 79. http://www.columbia.edu/kermit/ckubwr.html#x1
- 80. http://www.columbia.edu/kermit/ckubwr.html#top
- 81. http://www.columbia.edu/kermit/ckubwr.html#contents
- 82. http://www.columbia.edu/kermit/ckubwr.html#x4
- 83. http://www.columbia.edu/kermit/ckubwr.html#x2
- 84. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 85. http://www.columbia.edu/kermit/ckubwr.html#x3.1
- 86. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 87. http://www.columbia.edu/kermit/ckubwr.html#x3.3
- 88. http://www.columbia.edu/kermit/ckubwr.html#x3.4
- 89. http://www.columbia.edu/kermit/ckubwr.html#x3.5
- 90. http://www.columbia.edu/kermit/ckubwr.html#x3.6
- 91. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 92. http://www.columbia.edu/kermit/ckubwr.html#x3.8
- 93. http://www.columbia.edu/kermit/ckubwr.html#x3.9
- 94. http://www.columbia.edu/kermit/ckubwr.html#x3.10
- 95. http://www.columbia.edu/kermit/ckubwr.html#x3.11
- 96. http://www.columbia.edu/kermit/ckubwr.html#x3.12
- 97. http://www.columbia.edu/kermit/ckubwr.html#x3.13
- 98. http://www.columbia.edu/kermit/ckubwr.html#x3.14
- 99. http://www.columbia.edu/kermit/ckubwr.html#x3.15
- 100. http://www.columbia.edu/kermit/ckubwr.html#x3.16
- 101. http://www.columbia.edu/kermit/ckubwr.html#x3.17
- 102. http://www.columbia.edu/kermit/ckubwr.html#x3.18
- 103. http://www.columbia.edu/kermit/ckubwr.html#x3.19
- 104. http://www.columbia.edu/kermit/ckubwr.html#x3.20
- 105. http://www.faqs.org/
- 106. http://aplawrence.com/Unixart/newtounix.html
- 107. http://www.columbia.edu/kermit/ckubwr.html#x3
- 108. mailto:kermit-support@columbia.edu
- 109. http://www.columbia.edu/kermit/support.html
- 110. http://www.columbia.edu/kermit/ckubwr.html#top
- 111. http://www.columbia.edu/kermit/ckubwr.html#contents
- 112. http://www.columbia.edu/kermit/ckubwr.html#x3
- 113. http://www.columbia.edu/kermit/ckubwr.html#x3.1
- 114. http://www.pcunix.com/
- 115. http://www.columbia.edu/kermit/ckubwr.html#x3.0.1
- 116. http://www.columbia.edu/kermit/ckubwr.html#x3.0.2
- 117. http://www.columbia.edu/kermit/ckubwr.html#x3.0.3
- 118. http://www.columbia.edu/kermit/ckubwr.html#x3.0.4
- 119. http://www.columbia.edu/kermit/ckubwr.html#x3.0.5
- 120. http://www.columbia.edu/kermit/ckubwr.html#x3.0.6
- 121. http://www.columbia.edu/kermit/ckubwr.html#top
- 122. http://www.columbia.edu/kermit/ckubwr.html#contents
- 123. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 124. http://www.columbia.edu/kermit/ckubwr.html#x3.0.2
- 125. http://www.columbia.edu/kermit/ckubwr.html#top
- 126. http://www.columbia.edu/kermit/ckubwr.html#contents
- 127. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 128. http://www.columbia.edu/kermit/ckubwr.html#x3.0.3
- 129. http://www.columbia.edu/kermit/ckubwr.html#x3.0.1
- 130. http://www.linmodems.org/
- 131. http://www.microsoft.com/hwdev/platform/PCdesign/LR/default.asp
- 132. http://www.columbia.edu/kermit/ckubwr.html#top
- 133. http://www.columbia.edu/kermit/ckubwr.html#contents
- 134. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 135. http://www.columbia.edu/kermit/ckubwr.html#x3.0.4
- 136. http://www.columbia.edu/kermit/ckubwr.html#x3.0.2
- 137. http://www.idir.net/~gromitkc/winmodem.html
- 138. http://www.digi.com/
- 139. http://www.columbia.edu/kermit/ckubwr.html#top
- 140. http://www.columbia.edu/kermit/ckubwr.html#contents
- 141. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 142. http://www.columbia.edu/kermit/ckubwr.html#x3.0.5
- 143. http://www.columbia.edu/kermit/ckubwr.html#x3.0.3
- 144. http://www.columbia.edu/kermit/ckubwr.html#top
- 145. http://www.columbia.edu/kermit/ckubwr.html#contents
- 146. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 147. http://www.columbia.edu/kermit/ckubwr.html#x3.0.6
- 148. http://www.columbia.edu/kermit/ckubwr.html#x3.0.4
- 149. http://www.columbia.edu/kermit/ckubwr.html#top
- 150. http://www.columbia.edu/kermit/ckubwr.html#contents
- 151. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 152. http://www.columbia.edu/kermit/ckubwr.html#x3.0.5
- 153. http://www.columbia.edu/kermit/ckubwr.html#top
- 154. http://www.columbia.edu/kermit/ckubwr.html#contents
- 155. http://www.columbia.edu/kermit/ckubwr.html#x3
- 156. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 157. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 158. http://www.columbia.edu/kermit/ckubwr.html#x3.1.1
- 159. http://www.columbia.edu/kermit/ckubwr.html#x3.1.2
- 160. http://www.columbia.edu/kermit/ckubwr.html#x3.1.3
- 161. http://www.columbia.edu/kermit/ckubwr.html#x3.1.4
- 162. http://www.columbia.edu/kermit/ckubwr.html#x3.1.5
- 163. http://www.emerson.emory.edu/services/aix-faq/
- 164. http://www.faqs.org/faqs/by-newsgroup/comp/comp.unix.aix.html
- 165. http://www.cis.ohio-state.edu/hypertext/faq/usenet/aix-faq/top.html
- 166. http://aixpdslib.seas.ucla.edu/
- 167. http://www.rootvg.net(AIXhistory)/
- 168. ftp://rtfm.mit.edu/pub/usenet/news.answers/aix-faq/part1
- 169. ftp://mirrors.aol.com/pub/rtfm/usenet-by-hierarchy/comp/unix/aix
- 170. news:comp.unix.aix
- 171. http://www.columbia.edu/kermit/ckubwr.html#top
- 172. http://www.columbia.edu/kermit/ckubwr.html#contents
- 173. http://www.columbia.edu/kermit/ckubwr.html#x3.1
- 174. http://www.columbia.edu/kermit/ckubwr.html#x3.1.2
- 175. http://www.columbia.edu/kermit/ckubwr.html#top
- 176. http://www.columbia.edu/kermit/ckubwr.html#contents
- 177. http://www.columbia.edu/kermit/ckubwr.html#x3.1
- 178. http://www.columbia.edu/kermit/ckubwr.html#x3.1.3
- 179. http://www.columbia.edu/kermit/ckubwr.html#x3.1.1
- 180. http://www.columbia.edu/kermit/security.html#servers
- 181. http://www.columbia.edu/kermit/ckubwr.html#top
- 182. http://www.columbia.edu/kermit/ckubwr.html#contents
- 183. http://www.columbia.edu/kermit/ckubwr.html#x3.1
- 184. http://www.columbia.edu/kermit/ckubwr.html#x3.1.4
- 185. http://www.columbia.edu/kermit/ckubwr.html#x3.1.2
- 186. http://service.software.ibm.com/rs6000/
- 187. http://www.columbia.edu/kermit/ckubwr.html#top
- 188. http://www.columbia.edu/kermit/ckubwr.html#contents
- 189. http://www.columbia.edu/kermit/ckubwr.html#x3.1
- 190. http://www.columbia.edu/kermit/ckubwr.html#x3.1.5
- 191. http://www.columbia.edu/kermit/ckubwr.html#x3.1.3
- 192. http://www.columbia.edu/kermit/ckubwr.html#top
- 193. http://www.columbia.edu/kermit/ckubwr.html#contents
- 194. http://www.columbia.edu/kermit/ckubwr.html#x3.1
- 195. http://www.columbia.edu/kermit/ckubwr.html#x3.1.4
- 196. http://www.columbia.edu/kermit/ckubwr.html#top
- 197. http://www.columbia.edu/kermit/ckubwr.html#contents
- 198. http://www.columbia.edu/kermit/ckubwr.html#x3
- 199. http://www.columbia.edu/kermit/ckubwr.html#x3.3
- 200. http://www.columbia.edu/kermit/ckubwr.html#x3.1
- 201. http://www.columbia.edu/kermit/ckubwr.html#x3.2.0
- 202. http://www.columbia.edu/kermit/ckubwr.html#x3.2.1
- 203. http://www.columbia.edu/kermit/ckubwr.html#x3.2.2
- 204. http://www.columbia.edu/kermit/ckubwr.html#x3.2.3
- 205. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4
- 206. http://www.columbia.edu/kermit/ckubwr.html#x3.2.5
- 207. news:comp.sys.hp.hpux
- 208. http://www.columbia.edu/kermit/ckubwr.html#top
- 209. http://www.columbia.edu/kermit/ckubwr.html#contents
- 210. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 211. http://www.columbia.edu/kermit/ckubwr.html#x3.2.1
- 212. http://www.columbia.edu/kermit/ckubwr.html#top
- 213. http://www.columbia.edu/kermit/ckubwr.html#contents
- 214. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 215. http://www.columbia.edu/kermit/ckubwr.html#x3.2.2
- 216. http://www.columbia.edu/kermit/ckubwr.html#x3.2.0
- 217. ftp://kermit.columbia.edu/kermit/f/makefile
- 218. http://www.columbia.edu/kermit/ckubwr.html#top
- 219. http://www.columbia.edu/kermit/ckubwr.html#contents
- 220. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 221. http://www.columbia.edu/kermit/ckubwr.html#x3.2.3
- 222. http://www.columbia.edu/kermit/ckubwr.html#x3.2.1
- 223. http://www.columbia.edu/kermit/ckubwr.html#top
- 224. http://www.columbia.edu/kermit/ckubwr.html#contents
- 225. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 226. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4
- 227. http://www.columbia.edu/kermit/ckubwr.html#x3.2.2
- 228. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.1
- 229. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.2
- 230. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.3
- 231. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.4
- 232. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.5
- 233. http://www.columbia.edu/kermit/ckubwr.html#top
- 234. http://www.columbia.edu/kermit/ckubwr.html#contents
- 235. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 236. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.2
- 237. http://www.columbia.edu/kermit/ckubwr.html#x3.2.2
- 238. http://www.columbia.edu/kermit/ckubwr.html#top
- 239. http://www.columbia.edu/kermit/ckubwr.html#contents
- 240. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4
- 241. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.3
- 242. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.1
- 243. http://www.columbia.edu/kermit/ckubwr.html#top
- 244. http://www.columbia.edu/kermit/ckubwr.html#contents
- 245. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4
- 246. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.4
- 247. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.2
- 248. http://www.columbia.edu/kermit/ckubwr.html#top
- 249. http://www.columbia.edu/kermit/ckubwr.html#contents
- 250. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4
- 251. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.5
- 252. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.3
- 253. http://www.columbia.edu/kermit/ckubwr.html#top
- 254. http://www.columbia.edu/kermit/ckubwr.html#contents
- 255. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4
- 256. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4.4
- 257. http://www.columbia.edu/kermit/ckubwr.html#top
- 258. http://www.columbia.edu/kermit/ckubwr.html#contents
- 259. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 260. http://www.columbia.edu/kermit/ckubwr.html#x3.2.4
- 261. http://www.columbia.edu/kermit/ckubwr.html#top
- 262. http://www.columbia.edu/kermit/ckubwr.html#contents
- 263. http://www.columbia.edu/kermit/ckubwr.html#x3
- 264. http://www.columbia.edu/kermit/ckubwr.html#x3.4
- 265. http://www.columbia.edu/kermit/ckubwr.html#x3.2
- 266. http://www.columbia.edu/kermit/ckubwr.html#x3.3.1
- 267. http://www.columbia.edu/kermit/ckubwr.html#x3.3.2
- 268. http://www.columbia.edu/kermit/ckubwr.html#x3.3.3
- 269. http://www.columbia.edu/kermit/ckubwr.html#x3.3.4
- 270. http://www.columbia.edu/kermit/ckubwr.html#x3.3.5
- 271. http://www.columbia.edu/kermit/ckubwr.html#x3.3.6
- 272. http://en.wikipedia.org/wiki/Avahi_(software)
- 273. news:comp.os.linux.misc
- 274. news:comp.os.linux.answers
- 275. http://www.tldp.org/
- 276. http://www.tldp.org/FAQ/Linux-FAQ.html
- 277. http://www.tldp.org/HOWTO/Serial-HOWTO.html
- 278. http://tldp.org/HOWTO/Modem-HOWTO.html
- 279. ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO
- 280. ftp://tsx-11.mit.edu/pub/linux/docs/HOWTO
- 281. http://www.tldp.org/HOWTO/
- 282. http://www.tldp.org/hmirrors.html
- 283. http://www.redhat.com/apps/support/
- 284. http://www.debian.org/support
- 285. http://www.slackware.com/support/
- 286. http://www.caldera.com/support/
- 287. http://www.novell.com/support/microsites/microsite.do
- 288. http://www.mandrake.com/support/
- 289. http://www.turbolinux.com/support/
- 290. http://www.linmodems.org/
- 291. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 292. http://linux.dreamtime.org/decnet/
- 293. mailto:kermit-support@columbia.edu
- 294. http://www.linmodems.org/
- 295. http://www.columbia.edu/kermit/ckubwr.html#x3.0.2
- 296. http://www.columbia.edu/kermit/security.html#servers
- 297. http://www.columbia.edu/kermit/sshclient.html
- 298. http://www.columbia.edu/kermit/ckubwr.html#top
- 299. http://www.columbia.edu/kermit/ckubwr.html#contents
- 300. http://www.columbia.edu/kermit/ckubwr.html#x3
- 301. http://www.columbia.edu/kermit/ckubwr.html#x3.3.2
- 302. http://www.columbia.edu/kermit/ckubwr.html#top
- 303. http://www.columbia.edu/kermit/ckubwr.html#contents
- 304. http://www.columbia.edu/kermit/ckubwr.html#x3.3
- 305. http://www.columbia.edu/kermit/ckubwr.html#x3.3.3
- 306. http://www.columbia.edu/kermit/ckubwr.html#x3.3.1
- 307. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 308. http://www.columbia.edu/kermit/ckubwr.html#x6
- 309. http://www.columbia.edu/kermit/ckubwr.html#x7
- 310. http://www.columbia.edu/kermit/ckubwr.html#x8
- 311. http://www.columbia.edu/kermit/ckuins.html#x10
- 312. http://www.columbia.edu/kermit/ckuins.html#x11
- 313. http://www.columbia.edu/kermit/ckuins.html
- 314. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 315. http://linuxwww.db.erau.edu/mail_archives/linux-kernel/Mar_98/1441.html
- 316. http://www.columbia.edu/kermit/ckubwr.html#top
- 317. http://www.columbia.edu/kermit/ckubwr.html#contents
- 318. http://www.columbia.edu/kermit/ckubwr.html#x3.3
- 319. http://www.columbia.edu/kermit/ckubwr.html#x3.3.4
- 320. http://www.columbia.edu/kermit/ckubwr.html#x3.3.2
- 321. http://www.columbia.edu/kermit/ckubwr.html#x3.0.5
- 322. http://www.columbia.edu/kermit/ckfaq.html#term
- 323. http://dickey.his.com/xterm/xterm.html
- 324. http://dickey.his.com/xterm/xterm.html
- 325. ftp://kermit.columbia.edu/kermit/f/xmodmap.txt
- 326. http://www.columbia.edu/kermit/ckubwr.html#top
- 327. http://www.columbia.edu/kermit/ckubwr.html#contents
- 328. http://www.columbia.edu/kermit/ckubwr.html#x3.3
- 329. http://www.columbia.edu/kermit/ckubwr.html#x3.3.5
- 330. http://www.columbia.edu/kermit/ckubwr.html#x3.3.3
- 331. http://www.columbia.edu/kermit/ckubwr.html#top
- 332. http://www.columbia.edu/kermit/ckubwr.html#contents
- 333. http://www.columbia.edu/kermit/ckubwr.html#x3.3
- 334. http://www.columbia.edu/kermit/ckubwr.html#x3.3.6
- 335. http://www.columbia.edu/kermit/ckubwr.html#x3.3.4
- 336. http://www.columbia.edu/kermit/ckermit.html
- 337. mailto:kermit-support@columbia.edu
- 338. http://www.redhat.com/support/errata/RHBA-2001-153.html
- 339. news:comp.protocols.kermit.misc
- 340. http://www.columbia.edu/kermit/ckubwr.html#top
- 341. http://www.columbia.edu/kermit/ckubwr.html#contents
- 342. http://www.columbia.edu/kermit/ckubwr.html#x3.3
- 343. http://www.columbia.edu/kermit/ckubwr.html#x3.3.5
- 344. http://www.columbia.edu/kermit/ckubwr.html#top
- 345. http://www.columbia.edu/kermit/ckubwr.html#contents
- 346. http://www.columbia.edu/kermit/ckubwr.html#x3
- 347. http://www.columbia.edu/kermit/ckubwr.html#x3.5
- 348. http://www.columbia.edu/kermit/ckubwr.html#x3.3
- 349. http://www.columbia.edu/kermit/ckubwr.html#top
- 350. http://www.columbia.edu/kermit/ckubwr.html#contents
- 351. http://www.columbia.edu/kermit/ckubwr.html#x3
- 352. http://www.columbia.edu/kermit/ckubwr.html#x3.6
- 353. http://www.columbia.edu/kermit/ckubwr.html#x3.4
- 354. news:comp.os.qnx
- 355. http://www.columbia.edu/kermit/gkermit.html
- 356. http://www.columbia.edu/kermit/ckuins.html#x10
- 357. http://www.columbia.edu/kermit/ckuins.html
- 358. http://www.columbia.edu/kermit/ckubwr.html#top
- 359. http://www.columbia.edu/kermit/ckubwr.html#contents
- 360. http://www.columbia.edu/kermit/ckubwr.html#x3
- 361. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 362. http://www.columbia.edu/kermit/ckubwr.html#x3.5
- 363. http://www.columbia.edu/kermit/ckubwr.html#x3.6.1
- 364. http://www.columbia.edu/kermit/ckubwr.html#x3.6.2
- 365. http://www.columbia.edu/kermit/ckubwr.html#x3.6.3
- 366. http://www.columbia.edu/kermit/ckubwr.html#x3.6.4
- 367. http://www.columbia.edu/kermit/ckubwr.html#x3.10
- 368. http://aplawrence.com/SCOFAQ/
- 369. http://www.zenez.com/cgi-bin/scoprogfaq/faq.pl
- 370. http://www.zenez.com/cgi-bin/scouw7faq/faq.pl
- 371. http://zenez.pcunix.com/cgi-bin/scouw7faq/faq.pl
- 372. http://pcunix.com/Unixart/modems.html
- 373. http://www.freebird.org/faq/
- 374. http://www.freebird.org/faq/developer.html
- 375. http://support.caldera.com/caldera
- 376. http://stage.caldera.com/ta/
- 377. http://aplawrence.com/newtosco.html
- 378. http://www.columbia.edu/kermit/ckubwr.html#x3.0.5
- 379. http://www.columbia.edu/kermit/ckfaq.html#term
- 380. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 381. http://www.columbia.edu/kermit/ckubwr.html#top
- 382. http://www.columbia.edu/kermit/ckubwr.html#contents
- 383. http://www.columbia.edu/kermit/ckubwr.html#x3.6
- 384. http://www.columbia.edu/kermit/ckubwr.html#x3.6.1
- 385. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 386. http://www.columbia.edu/kermit/ckubwr.html#top
- 387. http://www.columbia.edu/kermit/ckubwr.html#contents
- 388. http://www.columbia.edu/kermit/ckubwr.html#x3.6
- 389. http://www.columbia.edu/kermit/ckubwr.html#x3.6.3
- 390. http://www.columbia.edu/kermit/ckubwr.html#x3.6.1
- 391. http://www.digi.com/
- 392. ftp://ftp.fu-berlin.de/pub/unix/driver/fas
- 393. http://www.columbia.edu/kermit/ckubwr.html#x14
- 394. http://www.sco.com/
- 395. ftp://ftp.sco.com/
- 396. http://www.columbia.edu/kermit/ckubwr.html#top
- 397. http://www.columbia.edu/kermit/ckubwr.html#contents
- 398. http://www.columbia.edu/kermit/ckubwr.html#x3.6
- 399. http://www.columbia.edu/kermit/ckubwr.html#x3.6.4
- 400. http://www.columbia.edu/kermit/ckubwr.html#x3.6.2
- 401. http://www.columbia.edu/kermit/ckubwr.html#x3.10
- 402. http://www.columbia.edu/kermit/ckubwr.html#top
- 403. http://www.columbia.edu/kermit/ckubwr.html#contents
- 404. http://www.columbia.edu/kermit/ckubwr.html#x3.6
- 405. http://www.columbia.edu/kermit/ckubwr.html#x3.6.3
- 406. http://www.columbia.edu/kermit/ckubwr.html#top
- 407. http://www.columbia.edu/kermit/ckubwr.html#contents
- 408. http://www.columbia.edu/kermit/ckubwr.html#x3
- 409. http://www.columbia.edu/kermit/ckubwr.html#x3.8
- 410. http://www.columbia.edu/kermit/ckubwr.html#x3.6
- 411. http://www.columbia.edu/kermit/ckubwr.html#x3.7.1
- 412. http://www.columbia.edu/kermit/ckubwr.html#x3.7.2
- 413. http://www.columbia.edu/kermit/ckubwr.html#x3.7.3
- 414. http://www.columbia.edu/kermit/ckubwr.html#x3.7.4
- 415. http://www.columbia.edu/kermit/ckubwr.html#x3.7.5
- 416. news:comp.unix.solaris
- 417. http://access1.sun.com/
- 418. http://docs.sun.com/
- 419. http://www.sunhelp.com/
- 420. http://www.wins.uva.nl/pub/solaris/solaris2/
- 421. http://www.wins.uva.nl/cgi-bin/sfaq.cgi
- 422. ftp://ftp.wins.uva.nl/pub/solaris
- 423. http://www.science.uva.nl/pub/solaris/solaris2.html
- 424. http://www.stokely.com/
- 425. http://www.stokely.com/unix.sysadm.resources/faqs.sun.html
- 426. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 427. http://www.columbia.edu/kermit/ckubwr.html#top
- 428. http://www.columbia.edu/kermit/ckubwr.html#contents
- 429. http://www.columbia.edu/kermit/ckubwr.html#x3
- 430. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 431. http://www.columbia.edu/kermit/ckubwr.html#x3.7.2
- 432. http://www.columbia.edu/kermit/ckubwr.html#top
- 433. http://www.columbia.edu/kermit/ckubwr.html#contents
- 434. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 435. http://www.columbia.edu/kermit/ckubwr.html#x3.7.3
- 436. http://www.columbia.edu/kermit/ckubwr.html#x3.7.1
- 437. http://www.columbia.edu/kermit/ckubwr.html#top
- 438. http://www.columbia.edu/kermit/ckubwr.html#contents
- 439. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 440. http://www.columbia.edu/kermit/ckubwr.html#x3.7.4
- 441. http://www.columbia.edu/kermit/ckubwr.html#x3.7.2
- 442. http://www.columbia.edu/kermit/ckubwr.html#top
- 443. http://www.columbia.edu/kermit/ckubwr.html#contents
- 444. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 445. http://www.columbia.edu/kermit/ckubwr.html#x3.7.5
- 446. http://www.columbia.edu/kermit/ckubwr.html#x3.7.3
- 447. news:comp.os.vms
- 448. http://www.columbia.edu/kermit/ckubwr.html#top
- 449. http://www.columbia.edu/kermit/ckubwr.html#contents
- 450. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 451. http://www.columbia.edu/kermit/ckubwr.html#x3.7.6
- 452. http://www.columbia.edu/kermit/ckubwr.html#x3.7.4
- 453. http://www.columbia.edu/kermit/ckubwr.html#top
- 454. http://www.columbia.edu/kermit/ckubwr.html#contents
- 455. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 456. http://www.columbia.edu/kermit/ckubwr.html#x3.7.5
- 457. http://www.columbia.edu/kermit/ckubwr.html#top
- 458. http://www.columbia.edu/kermit/ckubwr.html#contents
- 459. http://www.columbia.edu/kermit/ckubwr.html#x3
- 460. http://www.columbia.edu/kermit/ckubwr.html#x3.9
- 461. http://www.columbia.edu/kermit/ckubwr.html#x3.7
- 462. http://www.stokely.com/
- 463. http://access1.sun.com/
- 464. http://www.ludd.luth.se/~bear/project/sun/sun.hardware.txt
- 465. ftp://ftp.netcom.com/pub/ru/rubicon/sun.hdwr.ref
- 466. ftp://ftp.intnet.net/pub/SUN/Sun-Hardware-Ref
- 467. http://www.columbia.edu/kermit/ckubwr.html#top
- 468. http://www.columbia.edu/kermit/ckubwr.html#contents
- 469. http://www.columbia.edu/kermit/ckubwr.html#x3
- 470. http://www.columbia.edu/kermit/ckubwr.html#x3.10
- 471. http://www.columbia.edu/kermit/ckubwr.html#x3.8
- 472. news:comp.unix.ultrix
- 473. news:comp.sys.dec
- 474. http://www.columbia.edu/kermit/ckubwr.html#top
- 475. http://www.columbia.edu/kermit/ckubwr.html#contents
- 476. http://www.columbia.edu/kermit/ckubwr.html#x3
- 477. http://www.columbia.edu/kermit/ckubwr.html#x3.11
- 478. http://www.columbia.edu/kermit/ckubwr.html#x3.9
- 479. http://www.freebird.org/
- 480. http://www.freebird.org/faq/
- 481. news:comp.unix.unixware.misc
- 482. news:comp.unix.sco.misc
- 483. http://www.columbia.edu/kermit/ckubwr.html#x3.0
- 484. ftp://kermit.columbia.edu/kermit/f/ckutio.c
- 485. http://www.columbia.edu/kermit/ckubwr.html#top
- 486. http://www.columbia.edu/kermit/ckubwr.html#contents
- 487. http://www.columbia.edu/kermit/ckubwr.html#x3
- 488. http://www.columbia.edu/kermit/ckubwr.html#x3.12
- 489. http://www.columbia.edu/kermit/ckubwr.html#x3.10
- 490. http://www.columbia.edu/kermit/ckubwr.html#top
- 491. http://www.columbia.edu/kermit/ckubwr.html#contents
- 492. http://www.columbia.edu/kermit/ckubwr.html#x3
- 493. http://www.columbia.edu/kermit/ckubwr.html#x3.13
- 494. http://www.columbia.edu/kermit/ckubwr.html#x3.11
- 495. http://www.columbia.edu/kermit/ckubwr.html#top
- 496. http://www.columbia.edu/kermit/ckubwr.html#contents
- 497. http://www.columbia.edu/kermit/ckubwr.html#x3
- 498. http://www.columbia.edu/kermit/ckubwr.html#x3.14
- 499. http://www.columbia.edu/kermit/ckubwr.html#x3.12
- 500. http://www.columbia.edu/kermit/ckubwr.html#top
- 501. http://www.columbia.edu/kermit/ckubwr.html#contents
- 502. http://www.columbia.edu/kermit/ckubwr.html#x3
- 503. http://www.columbia.edu/kermit/ckubwr.html#x3.15
- 504. http://www.columbia.edu/kermit/ckubwr.html#x3.13
- 505. news:comp.sys.sgi.misc
- 506. news:comp.sys.sgi.admin
- 507. http://www.sgi.com/
- 508. http://www-viz.tamu.edu/~sgi-faq/
- 509. ftp://viz.tamu.edu/pub/sgi/faq/
- 510. http://www.columbia.edu/kermit/ckuins.html
- 511. http://freeware.sgi.com/Installable/gcc-2.95.2.html
- 512. http://freeware.sgi.com/Installable/gcc-2.95.2.html
- 513. http://www.columbia.edu/kermit/ckubwr.html#top
- 514. http://www.columbia.edu/kermit/ckubwr.html#contents
- 515. http://www.columbia.edu/kermit/ckubwr.html#x3
- 516. http://www.columbia.edu/kermit/ckubwr.html#x3.16
- 517. http://www.columbia.edu/kermit/ckubwr.html#x3.14
- 518. news:comp.sys.be
- 519. http://www.columbia.edu/kermit/ckubwr.html#top
- 520. http://www.columbia.edu/kermit/ckubwr.html#contents
- 521. http://www.columbia.edu/kermit/ckubwr.html#x3
- 522. http://www.columbia.edu/kermit/ckubwr.html#x3.17
- 523. http://www.columbia.edu/kermit/ckubwr.html#x3.15
- 524. http://www.columbia.edu/kermit/ckubwr.html#top
- 525. http://www.columbia.edu/kermit/ckubwr.html#contents
- 526. http://www.columbia.edu/kermit/ckubwr.html#x3
- 527. http://www.columbia.edu/kermit/ckubwr.html#x3.18
- 528. http://www.columbia.edu/kermit/ckubwr.html#x3.16
- 529. http://www.columbia.edu/kermit/ckubwr.html#top
- 530. http://www.columbia.edu/kermit/ckubwr.html#contents
- 531. http://www.columbia.edu/kermit/ckubwr.html#x3
- 532. http://www.columbia.edu/kermit/ckubwr.html#x3.19
- 533. http://www.columbia.edu/kermit/ckubwr.html#x3.17
- 534. http://www.columbia.edu/kermit/ckubwr.html#top
- 535. http://www.columbia.edu/kermit/ckubwr.html#contents
- 536. http://www.columbia.edu/kermit/ckubwr.html#x3
- 537. http://www.columbia.edu/kermit/ckubwr.html#x3.20
- 538. http://www.columbia.edu/kermit/ckubwr.html#x3.18
- 539. http://www.columbia.edu/kermit/mac.html
- 540. http://www.amazon.com/gp/product/B0000VYJRY?ie=UTF8&tag=aleidmoreldom-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=B0000VYJRY
- 541. http://www.columbia.edu/kermit/ckuins.html#x10
- 542. http://www.columbia.edu/kermit/ckuins.html
- 543. http://www.amazon.com/gp/product/B000FX61MS?ie=UTF8&tag=aleidmoreldom-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=B000FX61MS
- 544. mailto:kermit@columbia.edu
- 545. http://www.columbia.edu/kermit/ckubwr.html#top
- 546. http://www.columbia.edu/kermit/ckubwr.html#contents
- 547. http://www.columbia.edu/kermit/ckubwr.html#x3
- 548. http://www.columbia.edu/kermit/ckubwr.html#x3.19
- 549. http://www.uni-giessen.de/faq/archiv/coherent-faq.general/msg00000.html
- 550. http://www.columbia.edu/kermit/ckubwr.html#top
- 551. http://www.columbia.edu/kermit/ckubwr.html#contents
- 552. http://www.columbia.edu/kermit/ckubwr.html#x5
- 553. http://www.columbia.edu/kermit/ckubwr.html#x3
- 554. http://www.columbia.edu/kermit/ckccfg.html
- 555. http://www.columbia.edu/kermit/ckubwr.html#top
- 556. http://www.columbia.edu/kermit/ckubwr.html#contents
- 557. http://www.columbia.edu/kermit/ckubwr.html#x6
- 558. http://www.columbia.edu/kermit/ckubwr.html#x4
- 559. http://www.columbia.edu/kermit/ckuins.html
- 560. http://www.columbia.edu/kermit/ckubwr.html#top
- 561. http://www.columbia.edu/kermit/ckubwr.html#contents
- 562. http://www.columbia.edu/kermit/ckubwr.html#x7
- 563. http://www.columbia.edu/kermit/ckubwr.html#x5
- 564. http://www.columbia.edu/kermit/ckuins.html#9.5
- 565. http://www.columbia.edu/kermit/ckubwr.html#x3
- 566. http://www.columbia.edu/kermit/ckubwr.html#top
- 567. http://www.columbia.edu/kermit/ckubwr.html#contents
- 568. http://www.columbia.edu/kermit/ckubwr.html#x8
- 569. http://www.columbia.edu/kermit/ckubwr.html#x6
- 570. http://www.columbia.edu/kermit/ckuins.html#x8
- 571. http://www.columbia.edu/kermit/ckuins.html
- 572. http://www.columbia.edu/kermit/ck60manual.html
- 573. http://www.columbia.edu/kermit/cable.html
- 574. http://www.columbia.edu/kermit/ckubwr.html#top
- 575. http://www.columbia.edu/kermit/ckubwr.html#contents
- 576. http://www.columbia.edu/kermit/ckubwr.html#x9
- 577. http://www.columbia.edu/kermit/ckubwr.html#x7
- 578. http://www.columbia.edu/kermit/ckubwr.html#top
- 579. http://www.columbia.edu/kermit/ckubwr.html#contents
- 580. http://www.columbia.edu/kermit/ckubwr.html#x10
- 581. http://www.columbia.edu/kermit/ckubwr.html#x8
- 582. http://www.columbia.edu/kermit/ck60manual.html
- 583. http://dickey.his.com/xterm/xterm.html
- 584. http://www.columbia.edu/kermit/ckubwr.html#top
- 585. http://www.columbia.edu/kermit/ckubwr.html#contents
- 586. http://www.columbia.edu/kermit/ckubwr.html#x11
- 587. http://www.columbia.edu/kermit/ckubwr.html#x9
- 588. http://www.columbia.edu/kermit/ckubwr.html#top
- 589. http://www.columbia.edu/kermit/ckubwr.html#contents
- 590. http://www.columbia.edu/kermit/ckubwr.html#x12
- 591. http://www.columbia.edu/kermit/ckubwr.html#x10
- 592. http://www.columbia.edu/kermit/ckubwr.html#x11.1
- 593. http://www.columbia.edu/kermit/ckubwr.html#x11.2
- 594. http://www.columbia.edu/kermit/ckubwr.html#top
- 595. http://www.columbia.edu/kermit/ckubwr.html#contents
- 596. http://www.columbia.edu/kermit/ckubwr.html#x11
- 597. http://www.columbia.edu/kermit/ckubwr.html#x11.2
- 598. http://www.columbia.edu/kermit/ck60manual.html
- 599. http://www.columbia.edu/kermit/ckubwr.html#top
- 600. http://www.columbia.edu/kermit/ckubwr.html#contents
- 601. http://www.columbia.edu/kermit/ckubwr.html#x11
- 602. http://www.columbia.edu/kermit/ckubwr.html#x11.1
- 603. http://www.columbia.edu/kermit/ck60manual.html
- 604. http://www.columbia.edu/kermit/ckubwr.html#top
- 605. http://www.columbia.edu/kermit/ckubwr.html#contents
- 606. http://www.columbia.edu/kermit/ckubwr.html#x13
- 607. http://www.columbia.edu/kermit/ckubwr.html#x11
- 608. http://www.columbia.edu/kermit/security.html
- 609. http://www.columbia.edu/kermit/ckubwr.html#top
- 610. http://www.columbia.edu/kermit/ckubwr.html#contents
- 611. http://www.columbia.edu/kermit/ckubwr.html#x14
- 612. http://www.columbia.edu/kermit/ckubwr.html#x12
- 613. http://www.columbia.edu/kermit/ckubwr.html#top
- 614. http://www.columbia.edu/kermit/ckubwr.html#contents
- 615. http://www.columbia.edu/kermit/ckubwr.html#x15
- 616. http://www.columbia.edu/kermit/ckubwr.html#x14
- 617. mailto:support@stallion.oz.au
- 618. http://www.stallion.com/
- 619. http://www.columbia.edu/kermit/ckubwr.html#top
- 620. http://www.columbia.edu/kermit/ckubwr.html#contents
- 621. http://www.columbia.edu/kermit/ckermit.html
- 622. http://www.columbia.edu/kermit/ck80.html
- 623. http://www.columbia.edu/kermit/index.html
- 624. http://www.columbia.edu/kermit/index.html
- 625. http://www.columbia.edu/
- 626. mailto:kermit@columbia.edu
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckucmd.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckucmd.c
deleted file mode 100644
index d70770e..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckucmd.c
+++ /dev/null
@@ -1,7919 +0,0 @@
-#include "ckcsym.h"
-
-char *cmdv = "Command package 9.0.168, 12 March 2010";
-
-/* C K U C M D -- Interactive command package for Unix */
-
-/* (In reality, it's for all platforms, not just Unix) */
-
-/*
- Author: Frank da Cruz (fdc@columbia.edu),
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-#define TOKPRECHECK
-
-#define DOCHKVAR
-
-/* Command-terminal-to-C-Kermit character mask */
-
-#ifdef OS2 /* K95 */
-int cmdmsk = 255; /* (always was 255) */
-#else /* All others... */
-int cmdmsk = 255; /* 31 Dec 2000 (was 127) */
-#endif /* OS2 */
-
-#ifdef BS_DIRSEP /* Directory separator is backslash */
-#undef BS_DIRSEP
-#endif /* BS_DIRSEP */
-
-#ifdef OS2
-#define BS_DIRSEP
-#endif /* BS_DIRSEP */
-
-#define CKUCMD_C
-
-#include "ckcdeb.h" /* Formats for debug(), etc. */
-#include "ckcker.h" /* Needed for BIGBUFOK definition */
-#include "ckcnet.h" /* Needed for server-side Telnet */
-#include "ckucmd.h" /* Needed for everything */
-#include "ckuusr.h" /* Needed for prompt length */
-
-#ifndef NOARROWKEYS
-#ifndef NOESCSEQ
-#ifdef VMSORUNIX
-#define USE_ARROWKEYS /* Use arrow keys for command recall */
-#endif /* VMSORUNIX */
-#endif /* NOESCSEQ */
-#endif /* NOARROWKEYS */
-
-#undef CKUCMD_C
-
-_PROTOTYP( int unhex, (char) );
-_PROTOTYP( static VOID cmdclrscn, (void) );
-
-#ifdef CKLEARN
-_PROTOTYP( VOID learncmd, (char *) );
-#endif /* CKLEARN */
-
-static char *moname[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-struct keytab cmonths[] = {
- { "april", 4, 0 },
- { "august", 8, 0 },
- { "december", 12, 0 },
- { "february", 2, 0 },
- { "january", 1, 0 },
- { "july", 7, 0 },
- { "june", 6, 0 },
- { "march", 3, 0 },
- { "may", 5, 0 },
- { "november", 11, 0 },
- { "october", 10, 0 },
- { "september", 9, 0 }
-};
-
-#ifndef NOICP /* The rest only if interactive command parsing selected */
-
-#ifndef NOSPL
-_PROTOTYP( int chkvar, (char *) );
-extern int askflag, echostars;
-#endif /* NOSPL */
-
-#ifdef CKROOT
-extern int ckrooterr;
-#endif /* CKROOT */
-
-#ifdef IKSD
-extern int inserver;
-#endif /* IKSD */
-
-int cmfldflgs = 0; /* Flags for cmfld() */
-int cmkwflgs = 0; /* Flags from last keyword parse */
-static int nomsg = 0;
-static int blocklvl = 0; /* Block nesting level */
-static int linebegin = 0; /* Flag for at start of a line */
-static int quoting = 1; /* Quoting is allowed */
-static int swarg = 0; /* Parsing a switch argument */
-static int xcmfdb = 0; /* Flag for parsing chained fdbs... */
-static int chsrc = 0; /* Source of character, 1 = tty */
-static int newcmd = 0; /* See addcmd() */
-
-#ifdef BS_DIRSEP
-static int dirnamflg = 0;
-#endif /* BS_DIRSEP */
-
-/*
-Modeled after the DECSYSTEM-20 command parser (the COMND JSYS), RIP. Features:
-
- . parses and verifies keywords, filenames, text strings, numbers, other data
- . displays appropriate menu or help message when user types "?"
- . does keyword and filename completion when user types ESC or TAB
- . does partial keyword and filename completion
- . accepts any unique abbreviation for a keyword
- . allows keywords to have attributes, like "invisible" and "abbreviation"
- . can supply defaults for fields omitted by user
- . provides command retry and recall
- . provides character, word, and line deletion (but only from the end)
- . accepts input from keyboard, command files, macros, or redirected stdin
- . allows for full or half duplex operation, character or line input
- . allows \-escapes for special characters
- . allows specification of a user exit to expand variables, etc.
- . settable prompt, protected from deletion, dynamically re-evaluated each time
- . allows chained parse functions.
-
-Functions:
- cmsetp - Set prompt (cmprom is prompt string)
- cmsavp - Save current prompt
- cmgetp = Get current prompt
- prompt - Issue prompt
- cmini - Clear the command buffer (before parsing a new command)
- cmres - Reset command buffer pointers (before reparsing)
- cmkey - Parse a keyword or token (also cmkey2)
- cmswi - Parse a switch
- cmnum - Parse a number
- cmifi - Parse an input file name
- cmofi - Parse an output file name (also cmifip, cmifi2, ...)
- cmdir - Parse a directory name (also cmdirp)
- cmfld - Parse an arbitrary field
- cmtxt - Parse a text string
- cmdate - Parse a date-time string
- cmcfm - Parse command confirmation (end of line)
- cmfdb - Parse any of a list of the foregoing (chained parse functions)
-
-Return codes:
- -9: like -2 except this module already printed the error message
- -3: no input provided when required
- -2: input was invalid (e.g. not a number when a number was required)
- -1: reparse required (user deleted into a preceding field)
- 0 or greater: success
-See individual functions for greater detail.
-
-Before using these routines, the caller should #include "ckucmd.h" and set the
-program's prompt by calling cmsetp(). If the file parsing functions cmifi,
-cmofi, or cmdir are to be used, this module must be linked with a ck?fio file
-system support module for the appropriate system, e.g. ckufio for Unix. If
-the caller puts the terminal in character wakeup ("cbreak") mode with no echo,
-then these functions will provide line editing -- character, word, and line
-deletion, as well as keyword and filename completion upon ESC and help
-strings, keyword, or file menus upon '?'. If the caller puts the terminal
-into character wakeup/noecho mode, care should be taken to restore it before
-exit from or interruption of the program. If the character wakeup mode is not
-set, the system's own line editor may be used.
-
-NOTE: Contrary to expectations, many #ifdef's have been added to this module.
-Any operation requiring an #ifdef (like clear screen, get character from
-keyboard, erase character from screen, etc) should eventually be turned into a
-call to a function that is defined in ck?tio.c, but then all the ck?tio.c
-modules would have to be changed...
-*/
-
-/* Includes */
-
-#include "ckcker.h"
-#include "ckcasc.h" /* ASCII character symbols */
-#include "ckucmd.h" /* Command parsing definitions */
-
-#ifdef OSF13
-#ifdef CK_ANSIC
-#ifdef _NO_PROTO
-#undef _NO_PROTO
-#endif /* _NO_PROTO */
-#endif /* CK_ANSIC */
-#endif /* OSF13 */
-
-#ifndef HPUXPRE65
-#include <errno.h> /* Error number symbols */
-#else
-#ifndef ERRNO_INCLUDED
-#include <errno.h> /* Error number symbols */
-#endif /* ERRNO_INCLUDED */
-#endif /* HPUXPRE65 */
-
-#ifdef OS2
-#ifndef NT
-#define INCL_NOPM
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#else
-#define APIRET ULONG
-#include <windows.h>
-#endif /* NT */
-#include "ckocon.h"
-#include <io.h>
-#endif /* OS2 */
-
-#ifdef OSK
-#define cc ccount /* OS-9/68K compiler bug */
-#endif /* OSK */
-
-#ifdef GEMDOS /* Atari ST */
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) conoc(x)
-#endif /* GEMDOS */
-
-#ifdef CK_AUTODL
-extern int cmdadl, justone;
-#endif /* CK_AUTODL */
-
-extern int timelimit, nzxopts, nopush, nolocal, xcmdsrc, keepallchars;
-
-#ifdef CKSYSLOG
-#ifdef UNIX
-#ifdef CKXPRINTF /* Our printf macro conflicts with */
-#undef printf /* use of "printf" in syslog.h */
-#endif /* CKXPRINTF */
-#ifdef RTAIX
-#include <sys/syslog.h>
-#else /* RTAIX */
-#include <syslog.h>
-#endif /* RTAIX */
-#ifdef CKXPRINTF
-#define printf ckxprintf
-#endif /* CKXPRINTF */
-#endif /* UNIX */
-#endif /* CKSYSLOG */
-
-/* Local variables */
-
-static
-int psetf = 0, /* Flag that prompt has been set */
- cc = 0, /* Character count */
- dpx = 0, /* Duplex (0 = full) */
- inword = 0; /* In the middle of getting a word */
-
-char *dfprom = "Command? "; /* Default prompt */
-#ifndef NOLASTFILE
-char *lastfile = NULL; /* Last filespec */
-static char *tmplastfile = NULL; /* Last filespec candidate */
-#endif /* NOLASTFILE */
-
-int cmflgs; /* Command flags */
-int cmfsav; /* A saved version of them */
-
-static char pushc = NUL;
-static char brkchar = NUL;
-
-#define CMDEFAULT 1023
-static char cmdefault[CMDEFAULT+1];
-
-#ifdef DCMDBUF
-char *cmdbuf = NULL; /* Command buffer */
-char *savbuf = NULL; /* Buffer to save copy of command */
-char *atmbuf = NULL; /* Atom buffer - for current field */
-char *atxbuf = NULL; /* For expanding the atom buffer */
-char *prevcmd = NULL;
-static char *atybuf = NULL; /* For copying atom buffer */
-static char *filbuf = NULL; /* File name buffer */
-static char *cmprom = NULL; /* Program's prompt */
-static char *cmprxx = NULL; /* Program's prompt, unevaluated */
-
-#ifdef CK_RECALL
-/*
- Command recall is available only if we can make profligate use of malloc().
-*/
-#define R_MAX 10 /* How many commands to save */
-int cm_recall = R_MAX; /* Size of command recall buffer */
-int on_recall = 1; /* Recall feature is ON */
-static int no_recall = 0; /* Recall OFF for this cmd only */
-static int force_add = 0; /* Force cmd into recall buffer */
-static int last_recall = -1; /* Last recall-related action */
-/*
- -1 = none
- 0 = CR (a command was entered)
- 1 = Up
- 2 = Down
-*/
-int in_recall = 0; /* Recall buffers are init'd */
-static int
- current = -1, /* Pointer to current command */
- rlast = -1; /* Index of last command in buffer */
-static char **recall = NULL; /* Array of recall buffer pointers */
-#endif /* CK_RECALL */
-#else /* !DCMDBUF */
-char cmdbuf[CMDBL+4]; /* Command buffer */
-char savbuf[CMDBL+4]; /* Buffer to save copy of command */
-char atmbuf[ATMBL+4]; /* Atom buffer */
-char atxbuf[CMDBL+4]; /* For expanding the atom buffer */
-char prevcmd[CMDBL+4]; /* For displaying the last command */
-static char atybuf[ATMBL+4]; /* For copying atom buffer */
-static char filbuf[ATMBL+4]; /* File name buffer */
-static char cmprom[PROMPTL+1]; /* Program's prompt */
-static char cmprxx[PROMPTL+1]; /* Program's prompt, unevaluated */
-#endif /* DCMDBUF */
-
-/* Command buffer pointers */
-
-#define PPVLEN VNAML /* 20080305 Wolfram Sang (was 24) */
-char ppvnambuf[PPVLEN+1] = { NUL, NUL };
-
-char * cmbptr = NULL; /* Current position (for export) */
-
-static char *bp, /* Current command buffer position */
- *pp, /* Start of current field */
- *np; /* Start of next field */
-
-static int ungw, /* For ungetting words */
- atxn; /* Expansion buffer (atxbuf) length */
-
-#ifdef OS2
-extern int wideresult;
-#endif /* OS2 */
-
-extern int cmd_cols, cmd_rows, local, quiet;
-
-#ifdef TNCODE
-#ifdef IAC
-#undef IAC
-#endif /* IAC */
-#define IAC 255
-#endif /* TNCODE */
-
-_PROTOTYP( static int gtword, (int) );
-_PROTOTYP( static int addbuf, (char *) );
-_PROTOTYP( static int setatm, (char *, int) );
-_PROTOTYP( static VOID cmdnewl, (char) );
-_PROTOTYP( static VOID cmdchardel, (void) );
-_PROTOTYP( static VOID cmdecho, (char, int) );
-_PROTOTYP( static int test, (int, int) );
-#ifdef GEMDOS
-_PROTOTYP( extern char *strchr, (char *, int) );
-#endif /* GEMDOS */
-
-extern char * dftty;
-
-/* The following are for use with chained FDB's */
-
-static int crflag = 0; /* Carriage return was typed */
-static int qmflag = 0; /* Question mark was typed */
-static int esflag = 0; /* Escape was typed */
-
-/* Directory separator */
-
-#ifdef GEMDOS
-static char dirsep = '\\';
-#else
-#ifdef datageneral
-static char dirsep = ':';
-#else
-#ifdef MAC
-static char dirsep = ':';
-#else
-#ifdef VMS
-static char dirsep = '.';
-#else
-#ifdef STRATUS
-static char dirsep = '>';
-#else
-static char dirsep = '/'; /* UNIX, OS/2, OS-9, Amiga, etc. */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* MAC */
-#endif /* datageneral */
-#endif /* GEMDOS */
-
-/* H A S N O P A T H */
-
-/* Returns 0 if filespec s includes any path segments; 1 if it doesn't. */
-
-int
-hasnopath(s) char * s; {
- char * p = NULL;
- if (!s) return(0);
- if (!*s) return(0);
- zstrip(s,&p);
- return(ckstrcmp(s,p,CKMAXPATH,filecase) == 0 ? 1 : 0);
-}
-
-/* C K S P R E A D -- Print string double-spaced */
-
-static char * sprptr = NULL;
-
-static char *
-ckspread(s) char * s; {
- int n = 0;
- char * p;
- n = strlen(s);
- if (sprptr)
- free(sprptr);
- sprptr = malloc(n + n + 3);
- if (sprptr) {
- p = sprptr;
- while (*s) {
- *p++ = *s++;
- *p++ = SP;
- }
- *p = NUL;
- }
- return(sprptr ? sprptr : "");
-}
-
-/* T E S T -- Bit test */
-
-static int
-test(x,m) int x, m; { /* Returns 1 if any bits from m are on in x, else 0 */
- return((x & m) ? 1 : 0);
-}
-
-/* K W D H E L P -- Given a keyword table, print keywords in columns. */
-/*
- Call with:
- s - keyword table
- n - number of entries
- pat - pattern (left substring) that must match for each keyword
- pre - prefix to add to each keyword
- post - suffix to add to each keyword
- off - offset on first screenful, allowing room for introductory text
- xhlp - 1 to print any CM_INV keywords that are not also abbreviations.
- 2 to print CM_INV keywords if CM_HLP also set
- 4 if it's a switch table (to show ':' if CM_ARG)
-
- Arranges keywords in columns with width based on longest keyword.
- Does "more?" prompting at end of screen.
- Uses global cmd_rows and cmd_cols for screen size.
-*/
-VOID
-kwdhelp(s,n,pat,pre,post,off,xhlp)
- struct keytab s[]; int n, off, xhlp; char *pat, *pre, *post;
-/* kwdhelp */ {
-
- int width = 0;
- int cc;
- int cols, height, i, j, k, lc, n2 = 0;
- char *b = NULL, *p, *q;
- char *pa, *px;
- char **s2 = NULL;
- char *tmpbuf = NULL;
-
- cc = strlen(pat);
-
- if (!s) return; /* Nothing to do */
- if (n < 1) return; /* Ditto */
- if (off < 0) off = 0; /* Offset for first page */
- if (!pre) pre = ""; /* Handle null string pointers */
- if (!post) post = "";
- lc = off; /* Screen-line counter */
-
- if (xhlp & 4) /* For switches */
- tmpbuf = (char *)malloc(TMPBUFSIZ+1);
-
- if ((s2 = (char **) malloc(n * sizeof(char *)))) {
- for (i = 0; i < n; i++) { /* Find longest keyword */
- s2[i] = NULL;
- if (ckstrcmp(s[i].kwd,pat,cc,0))
- continue;
-
- if (s[i].flgs & CM_PSH /* NOPUSH or nopush screening */
-#ifndef NOPUSH
- && nopush
-#endif /* NOPUSH */
- )
- continue;
- if (s[i].flgs & CM_LOC /* NOLOCAL or nolocal screening */
-#ifndef NOLOCAL
- && nolocal
-#endif /* NOLOCAL */
- )
- continue;
-
- if (s[i].flgs & CM_INV) {
-#ifdef COMMENT
-/* This code does not show invisible keywords at all except for "help ?" */
-/* and then only help topics (CM_HLP) in the top-level keyword list. */
-
- if ((xhlp & 2) == 0)
- continue;
- else if ((s[i].flgs & CM_HLP) == 0)
- continue;
-#else
-/* This code shows invisible keywords that are not also abbreviations when */
-/* ? was typed AFTER the beginning of the field so the user can find out */
-/* what they are and (for example) why completion doesn't work at this point */
-
- if (s[i].flgs & CM_ABR)
- continue;
- else if ((xhlp & 3) == 0)
- continue;
- else if ((xhlp & 2) && ((s[i].flgs & CM_HLP) == 0))
- continue;
-#endif /* COMMENT */
- }
- j = strlen(s[i].kwd);
- if (!(xhlp & 4) || !tmpbuf) { /* Regular keyword table */
- s2[n2++] = s[i].kwd; /* Copy pointers to visible ones */
- } else { /* Switches */
- ckmakmsg(tmpbuf, /* Make a copy that shows ":" if */
- TMPBUFSIZ, /* the switch takes an argument. */
- s[i].kwd,
- (s[i].flgs & CM_ARG) ? ":" : "",
- NULL,
- NULL
- );
- makestr(&(s2[n2]),tmpbuf);
- if (s[i].flgs & CM_ARG) j++;
- n2++;
- }
- if (j > width)
- width = j;
- }
- /* Column width */
- n = n2;
- }
- if (s2 && (b = (char *) malloc(cmd_cols + 1))) { /* Make a line buffer */
- char * bx;
- bx = b + cmd_cols;
- width += (int)strlen(pre) + (int)strlen(post) + 2;
- cols = cmd_cols / width; /* How many columns? */
- if (cols < 1) cols = 1;
- height = n / cols; /* How long is each column? */
- if (n % cols) height++; /* Add one for remainder, if any */
-
- for (i = 0; i < height; i++) { /* Loop for each row */
- for (j = 0; j < cmd_cols; j++) /* First fill row with blanks */
- b[j] = SP;
- for (j = 0; j < cols; j++) { /* Loop for each column in row */
- k = i + (j * height); /* Index of next keyword */
- if (k < n) { /* In range? */
- pa = pre;
- px = post;
- p = s2[k]; /* Point to verb name */
- q = b + (j * width) + 1; /* Where to copy it to */
- while ((q < bx) && (*q++ = *pa++)) ; /* Copy prefix */
- q--; /* Back up over NUL */
- while ((q < bx) && (*q++ = *p++)) ; /* Copy filename */
- q--; /* Back up over NUL */
- while ((q < bx) && (*q++ = *px++)) ; /* Copy suffix */
- if (j < cols - 1) {
- q--;
- *q = SP; /* Replace the space */
- }
- }
- }
- p = b + cmd_cols - 1; /* Last char in line */
- while (*p-- == SP) ; /* Trim */
- *(p+2) = NUL;
- printf("%s\n",b); /* Print the line */
- if (++lc > (cmd_rows - 2)) { /* Screen full? */
- if (!askmore()) /* Do more-prompting... */
- goto xkwdhelp;
- else
- lc = 0;
- }
- }
- /* printf("\n"); */ /* Blank line at end of report */
- } else { /* Malloc failure, no columns */
- for (i = 0; i < n; i++) {
- if (s[i].flgs & CM_INV) /* Use original keyword table */
- continue; /* skipping invisible entries */
- printf("%s%s%s\n",pre,s[i].kwd,post);
- if (++lc > (cmd_rows - 2)) { /* Screen full? */
- if (!askmore()) /* Do more-prompting... */
- goto xkwdhelp;
- else
- lc = 0;
- }
- }
- }
- xkwdhelp:
- if (xhlp & 4) {
- if (tmpbuf) free((char *)tmpbuf);
- for (i = 0; i < n; i++)
- if (s2[i]) free(s2[i]);
- }
- if (s2) free(s2); /* Free array copy */
- if (b) free(b); /* Free line buffer */
- return;
-}
-
-/* X F I L H E L P -- Given a file list, print names in columns. */
-/*
- Call with:
- n - number of entries
- pre - prefix to add to each filename
- post - suffix to add to each filename
- off - offset on first screenful, allowing room for introductory text
- cmdirflg - 1 if only directory names should be listed, 0 to list all files
- fs - call fileselect() to decide whether to include each file.
- The rest of the args are the same as for fileselect().
-
- Arranges filenames in columns with width based on longest filename.
- Does "more?" prompting at end of screen.
- Uses global cmd_rows and cmd_cols for screen size.
-*/
-
-int
-#ifdef CK_ANSIC
-xfilhelp(
- int n, char *pre, char *post, int off, int cmdirflag,
- int fs, char *sa, char *sb, char *sna, char *snb,
- CK_OFF_T minsiz, CK_OFF_T maxsiz,
- int nbu, int nxlist,
- char ** xlist
-)
-#else
-xfilhelp(n,pre,post,off,cmdirflg,
- fs,sa,sb,sna,snb,minsiz,maxsiz,nbu,nxlist,xlist)
- int n, off; char *pre, *post; int cmdirflg;
- int fs; char *sa,*sb,*sna,*snb; CK_OFF_T minsiz,maxsiz;
- int nbu,nxlist; char ** xlist;
-#endif /* CK_ANSIC */
- {
- char filbuf[CKMAXPATH + 1]; /* Temp buffer for one filename */
- int width = 0;
- int cols, height, i, j, k, lc, n2 = 0, rc = 0, itsadir = 0;
- char *b = NULL, *p, *q;
- char *pa, *px;
- char **s2 = NULL;
-#ifdef VMS
- char * cdp = zgtdir();
-#endif /* VMS */
-
- if (n < 1) return(0);
- if (off < 0) off = 0; /* Offset for first page */
- if (!pre) pre = ""; /* Handle null string pointers */
- if (!post) post = "";
-
- lc = off; /* Screen-line counter */
-
- if ((s2 = (char **) malloc(n * sizeof(char *)))) {
- for (i = 0; i < n; i++) { /* Loop through filenames */
- itsadir = 0;
- s2[i] = NULL; /* Initialize each pointer to NULL */
- znext(filbuf); /* Get next filename */
- if (!filbuf[0]) /* Shouldn't happen */
- break;
-#ifdef COMMENT
- itsadir = isdir(filbuf); /* Is it a directory? */
- if (cmdirflg && !itsadir) /* No, listing directories only? */
- continue; /* So skip this one. */
-#endif /* COMMENT */
- if (fs) if (fileselect(filbuf,
- sa,sb,sna,snb,
- minsiz,maxsiz,nbu,nxlist,xlist) < 1) {
- continue;
- }
-#ifdef VMS
- ckstrncpy(filbuf,zrelname(filbuf,cdp),CKMAXPATH);
-#endif /* VMS */
- j = strlen(filbuf);
-#ifndef VMS
- if (itsadir && j < CKMAXPATH - 1 && j > 0) {
- if (filbuf[j-1] != dirsep) {
- filbuf[j++] = dirsep;
- filbuf[j] = NUL;
- }
- }
-#endif /* VMS */
- if (!(s2[n2] = malloc(j+1))) {
- printf("?Memory allocation failure\n");
- rc = -9;
- goto xfilhelp;
- }
- if (j <= CKMAXPATH) {
- strcpy(s2[n2],filbuf);
- n2++;
- } else {
- printf("?Name too long - %s\n", filbuf);
- rc = -9;
- goto xfilhelp;
- }
- if (j > width) /* Get width of widest one */
- width = j;
- }
- n = n2; /* How many we actually got */
- }
- sh_sort(s2,NULL,n,0,0,filecase); /* Alphabetize the list */
-
- rc = 1;
- if (s2 && (b = (char *) malloc(cmd_cols + 1))) { /* Make a line buffer */
- char * bx;
- bx = b + cmd_cols;
- width += (int)strlen(pre) + (int)strlen(post) + 2;
- cols = cmd_cols / width; /* How many columns? */
- if (cols < 1) cols = 1;
- height = n / cols; /* How long is each column? */
- if (n % cols) height++; /* Add one for remainder, if any */
-
- for (i = 0; i < height; i++) { /* Loop for each row */
- for (j = 0; j < cmd_cols; j++) /* First fill row with blanks */
- b[j] = SP;
- for (j = 0; j < cols; j++) { /* Loop for each column in row */
- k = i + (j * height); /* Index of next filename */
- if (k < n) { /* In range? */
- pa = pre;
- px = post;
- p = s2[k]; /* Point to filename */
- q = b + (j * width) + 1; /* and destination */
- while ((q < bx) && (*q++ = *pa++)) ; /* Copy prefix */
- q--; /* Back up over NUL */
- while ((q < bx) && (*q++ = *p++)) ; /* Copy filename */
- q--; /* Back up over NUL */
- while ((q < bx) && (*q++ = *px++)) ; /* Copy suffix */
- if (j < cols - 1) {
- q--;
- *q = SP; /* Replace the space */
- }
- }
- }
- p = b + cmd_cols - 1; /* Last char in line */
- while (*p-- == SP) ; /* Trim */
- *(p+2) = NUL;
- printf("%s\n",b); /* Print the line */
- if (++lc > (cmd_rows - 2)) { /* Screen full? */
- if (!askmore()) { /* Do more-prompting... */
- rc = 0;
- goto xfilhelp;
- } else
- lc = 0;
- }
- }
- printf("\n"); /* Blank line at end of report */
- goto xfilhelp;
- } else { /* Malloc failure, no columns */
- for (i = 0; i < n; i++) {
- znext(filbuf);
- if (!filbuf[0]) break;
- printf("%s%s%s\n",pre,filbuf,post);
- if (++lc > (cmd_rows - 2)) { /* Screen full? */
- if (!askmore()) { /* Do more-prompting... */
- rc = 0;
- goto xfilhelp;
- } else lc = 0;
- }
- }
-xfilhelp:
- if (b) free(b);
- for (i = 0; i < n2; i++)
- if (s2[i]) free(s2[i]);
- if (s2) free((char *)s2);
- return(rc);
- }
-}
-
-/*
- Simpler front end for xfilhelp() with shorter arg list when no
- file selection is needed.
-*/
-int
-filhelp(n,pre,post,off,cmdirflg) int n, off; char *pre, *post; int cmdirflg; {
- return(xfilhelp(n,pre,post,off,cmdirflg,
- 0,NULL,NULL,NULL,NULL,
- (CK_OFF_T)0,(CK_OFF_T)0,0,0,(char **)NULL));
-}
-
-/* C M S E T U P -- Set up command buffers */
-
-#ifdef DCMDBUF
-int
-cmsetup() {
- if (!(cmdbuf = malloc(CMDBL + 4))) return(-1);
- if (!(savbuf = malloc(CMDBL + 4))) return(-1);
- savbuf[0] = '\0';
- if (!(prevcmd = malloc(CMDBL + 4))) return(-1);
- prevcmd[0] = '\0';
- if (!(atmbuf = malloc(ATMBL + 4))) return(-1);
- if (!(atxbuf = malloc(CMDBL + 4))) return(-1);
- if (!(atybuf = malloc(ATMBL + 4))) return(-1);
- if (!(filbuf = malloc(ATMBL + 4))) return(-1);
- if (!(cmprom = malloc(PROMPTL + 4))) return(-1);
- if (!(cmprxx = malloc(PROMPTL + 4))) return(-1);
-#ifdef CK_RECALL
- cmrini(cm_recall);
-#endif /* CK_RECALL */
- return(0);
-}
-#endif /* DCMDBUF */
-
-/* C M S E T P -- Set the program prompt. */
-
-VOID
-cmsetp(s) char *s; {
- if (!s) s = "";
- ckstrncpy(cmprxx,s,PROMPTL);
- psetf = 1; /* Flag that prompt has been set. */
-}
-
-/* C M S A V P -- Save a copy of the current prompt. */
-
-VOID
-#ifdef CK_ANSIC
-cmsavp(char s[], int n)
-#else
-cmsavp(s,n) char s[]; int n;
-#endif /* CK_ANSIC */
-/* cmsavp */ {
- if (psetf) /* But not if no prompt is set. */
- ckstrncpy(s,cmprxx,n);
-}
-
-char *
-cmgetp() {
- return(cmprxx);
-}
-
-int
-cmgbrk() {
- return(brkchar);
-}
-
-int
-cmgkwflgs() {
- return(cmkwflgs);
-}
-
-/* P R O M P T -- Issue the program prompt. */
-
-VOID
-prompt(f) xx_strp f; {
- char *sx, *sy; int n;
-#ifdef CK_SSL
- extern int ssl_active_flag, tls_active_flag;
-#endif /* CK_SSL */
-#ifdef OS2
- extern int display_demo;
-
- /* If there is a demo screen to be displayed, display it */
- if (display_demo && xcmdsrc == 0) {
- demoscrn(VCMD);
- display_demo = 0;
- }
-#endif /* OS2 */
-
- if (psetf == 0) /* If no prompt set, set default. */
- cmsetp(dfprom);
-
- sx = cmprxx; /* Unevaluated copy */
- if (f) { /* If conversion function given */
- sy = cmprom; /* Evaluate it */
-#ifdef COMMENT
- debug(F101,"prompt sx","",sx);
- debug(F101,"prompt sy","",sy);
-#endif /* COMMENT */
- n = PROMPTL;
- if ((*f)(sx,&sy,&n) < 0) /* If evaluation failed */
- sx = cmprxx; /* revert to unevaluated copy */
- else if (!*cmprom) /* ditto if it came up empty */
- sx = cmprxx;
- else
- sx = cmprom;
- } else
- ckstrncpy(cmprom,sx,PROMPTL);
- cmprom[PROMPTL-1] = NUL;
- if (!*sx) /* Don't print if empty */
- return;
-
-#ifdef OSK
- fputs(sx, stdout);
-#else
-#ifdef MAC
- printf("%s", sx);
-#else
-#ifdef IKSD
- if (inserver) { /* Print the prompt. */
- ttoc(CR); /* If TELNET Server */
- ttoc(NUL); /* must folloW CR by NUL */
- printf("%s",sx);
- } else
-#endif /* IKSD */
- printf("\r%s",sx);
-#ifdef CK_SSL
- if (!(ssl_active_flag || tls_active_flag))
-#endif /* CK_SSL */
- fflush(stdout); /* Now! */
-#endif /* MAC */
-#endif /* OSK */
-}
-
-#ifndef NOSPL
-VOID
-pushcmd(s) char * s; { /* For use with IF command. */
- if (!s) s = np;
- ckstrncpy(savbuf,s,CMDBL); /* Save the dependent clause, */
- cmres(); /* and clear the command buffer. */
- debug(F110, "pushcmd savbuf", savbuf, 0);
-}
-
-VOID
-pushqcmd(s) char * s; { /* For use with ELSE command. */
- char c, * p = savbuf; /* Dest */
- if (!s) s = np; /* Source */
- while (*s) { /* Get first nonwhitespace char */
- if (*s != SP)
- break;
- else
- s++;
- }
- if (*s != '{') { /* If it's not "{" */
- pushcmd(s); /* do regular pushcmd */
- return;
- }
- while ((c = *s++)) { /* Otherwise insert quotes */
- if (c == CMDQ)
- *p++ = CMDQ;
- *p++ = c;
- }
- cmres(); /* and clear the command buffer. */
- debug(F110, "pushqcmd savbuf", savbuf, 0);
-}
-#endif /* NOSPL */
-
-#ifdef COMMENT
-/* no longer used... */
-VOID
-popcmd() {
- ckstrncpy(cmdbuf,savbuf,CMDBL); /* Put back the saved material */
- *savbuf = '\0'; /* and clear the save buffer */
- cmres();
-}
-#endif /* COMMENT */
-
-/* C M R E S -- Reset pointers to beginning of command buffer. */
-
-VOID
-cmres() {
- inword = 0; /* We're not in a word */
- cc = 0; /* Character count is zero */
-
-/* Initialize pointers */
-
- pp = cmdbuf; /* Beginning of current field */
- bp = cmdbuf; /* Current position within buffer */
- np = cmdbuf; /* Where to start next field */
-
- cmfldflgs = 0;
- cmflgs = -5; /* Parse not yet started. */
- ungw = 0; /* Don't need to unget a word. */
-}
-
-/* C M I N I -- Clear the command and atom buffers, reset pointers. */
-
-/*
-The argument specifies who is to echo the user's typein --
- 1 means the cmd package echoes
- 0 somebody else (system, front end, terminal) echoes
-*/
-VOID
-cmini(d) int d; {
-#ifdef DCMDBUF
- if (!atmbuf)
- if (cmsetup()<0)
- fatal("fatal error: unable to allocate command buffers");
-#endif /* DCMDBUF */
-#ifdef USE_MEMCPY
- memset(cmdbuf,0,CMDBL);
- memset(atmbuf,0,ATMBL);
-#else
- for (bp = cmdbuf; bp < cmdbuf+CMDBL; bp++) *bp = NUL;
- for (bp = atmbuf; bp < atmbuf+ATMBL; bp++) *bp = NUL;
-#endif /* USE_MEMCPY */
-
- *atmbuf = *savbuf = *atxbuf = *atybuf = *filbuf = NUL;
- blocklvl = 0; /* Block level is 0 */
- linebegin = 1; /* At the beginning of a line */
- dpx = d; /* Global copy of the echo flag */
- debug(F101,"cmini dpx","",dpx);
- crflag = 0; /* Reset flags */
- qmflag = 0;
- esflag = 0;
-#ifdef CK_RECALL
- no_recall = 0; /* Start out with recall enabled */
-#endif /* CK_RECALL */
- cmres(); /* Sets bp etc */
- newcmd = 1; /* See addcmd() */
-}
-
-#ifndef NOSPL
-/*
- The following bits are to allow the command package to call itself
- in the middle of a parse. To do this, begin by calling cmpush, and
- end by calling cmpop. As you can see, this is rather expensive.
-*/
-#ifdef DCMDBUF
-struct cmp {
- int i[5]; /* stack for integers */
- char *c[3]; /* stack for pointers */
- char *b[8]; /* stack for buffer contents */
-};
-struct cmp *cmp = 0;
-#else
-int cmp_i[CMDDEP+1][5]; /* Stack for integers */
-char *cmp_c[CMDDEP+1][5]; /* for misc pointers */
-char *cmp_b[CMDDEP+1][7]; /* for buffer contents pointers */
-#endif /* DCMDBUF */
-
-int cmddep = -1; /* Current stack depth */
-
-int
-cmpush() { /* Save the command environment */
- char *cp; /* Character pointer */
-
- if (cmddep >= CMDDEP) /* Enter a new command depth */
- return(-1);
- cmddep++;
- debug(F101,"&cmpush to depth","",cmddep);
-
-#ifdef DCMDBUF
- /* allocate memory for cmp if not already done */
- if (!cmp && !(cmp = (struct cmp *) malloc(sizeof(struct cmp)*(CMDDEP+1))))
- fatal("cmpush: no memory for cmp");
- cmp[cmddep].i[0] = cmflgs; /* First do the global ints */
- cmp[cmddep].i[1] = cmfsav;
- cmp[cmddep].i[2] = atxn;
- cmp[cmddep].i[3] = ungw;
-
- cmp[cmddep].c[0] = bp; /* Then the global pointers */
- cmp[cmddep].c[1] = pp;
- cmp[cmddep].c[2] = np;
-#else
- cmp_i[cmddep][0] = cmflgs; /* First do the global ints */
- cmp_i[cmddep][1] = cmfsav;
- cmp_i[cmddep][2] = atxn;
- cmp_i[cmddep][3] = ungw;
-
- cmp_c[cmddep][0] = bp; /* Then the global pointers */
- cmp_c[cmddep][1] = pp;
- cmp_c[cmddep][2] = np;
-#endif /* DCMDBUF */
-
- /* Now the buffers themselves. A lot of repititious code... */
-
-#ifdef DCMDBUF
- cp = malloc((int)strlen(cmdbuf)+1); /* 0: Command buffer */
- if (cp) strcpy(cp,cmdbuf);
- cmp[cmddep].b[0] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(savbuf)+1); /* 1: Save buffer */
- if (cp) strcpy(cp,savbuf);
- cmp[cmddep].b[1] = cp;
- if (cp == NULL) return(-1);
-
- cmp[cmddep].b[2] = NULL;
-
- cp = malloc((int)strlen(atmbuf)+1); /* 3: Atom buffer */
- if (cp) strcpy(cp,atmbuf);
- cmp[cmddep].b[3] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(atxbuf)+1); /* 4: Expansion buffer */
- if (cp) strcpy(cp,atxbuf);
- cmp[cmddep].b[4] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(atybuf)+1); /* 5: Atom buffer copy */
- if (cp) strcpy(cp,atybuf);
- cmp[cmddep].b[5] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(filbuf)+1); /* 6: File name buffer */
- if (cp) strcpy(cp,filbuf);
- cmp[cmddep].b[6] = cp;
- if (cp == NULL) return(-1);
-#else
- cp = malloc((int)strlen(cmdbuf)+1); /* 0: Command buffer */
- if (cp) strcpy(cp,cmdbuf);
- cmp_b[cmddep][0] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(savbuf)+1); /* 1: Save buffer */
- if (cp) strcpy(cp,savbuf);
- cmp_b[cmddep][1] = cp;
- if (cp == NULL) return(-1);
-
- cmp_b[cmddep][2] = NULL;
-
- cp = malloc((int)strlen(atmbuf)+1); /* 3: Atom buffer */
- if (cp) strcpy(cp,atmbuf);
- cmp_b[cmddep][3] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(atxbuf)+1); /* 4: Expansion buffer */
- if (cp) strcpy(cp,atxbuf);
- cmp_b[cmddep][4] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(atybuf)+1); /* 5: Atom buffer copy */
- if (cp) strcpy(cp,atybuf);
- cmp_b[cmddep][5] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(filbuf)+1); /* 6: File name buffer */
- if (cp) strcpy(cp,filbuf);
- cmp_b[cmddep][6] = cp;
- if (cp == NULL) return(-1);
-#endif /* DCMDBUF */
-
- cmini(dpx); /* Initize the command parser */
- return(0);
-}
-
-int
-cmpop() { /* Restore the command environment */
- if (cmddep < 0) {
- debug(F100,"&cmpop called from top level","",0);
- return(-1); /* Don't pop too much! */
- }
-#ifdef DCMDBUF
- cmflgs = cmp[cmddep].i[0]; /* First do the global ints */
- cmfsav = cmp[cmddep].i[1];
- atxn = cmp[cmddep].i[2];
- ungw = cmp[cmddep].i[3];
-
- bp = cmp[cmddep].c[0]; /* Then the global pointers */
- pp = cmp[cmddep].c[1];
- np = cmp[cmddep].c[2];
-#else
- cmflgs = cmp_i[cmddep][0]; /* First do the global ints */
- cmfsav = cmp_i[cmddep][1];
- atxn = cmp_i[cmddep][2];
- ungw = cmp_i[cmddep][3];
-
- bp = cmp_c[cmddep][0]; /* Then the global pointers */
- pp = cmp_c[cmddep][1];
- np = cmp_c[cmddep][2];
-#endif /* DCMDBUF */
-
- /* Now the buffers themselves. */
- /* Note: strncpy(), not ckstrncpy() -- Here we WANT the NUL padding... */
-
-#ifdef DCMDBUF
- if (cmp[cmddep].b[0]) {
-
- strncpy(cmdbuf,cmp[cmddep].b[0],CMDBL); /* 0: Command buffer */
- free(cmp[cmddep].b[0]);
- cmp[cmddep].b[0] = NULL;
- }
- if (cmp[cmddep].b[1]) {
- strncpy(savbuf,cmp[cmddep].b[1],CMDBL); /* 1: Save buffer */
- free(cmp[cmddep].b[1]);
- cmp[cmddep].b[1] = NULL;
- }
- if (cmp[cmddep].b[3]) {
- strncpy(atmbuf,cmp[cmddep].b[3],ATMBL); /* 3: Atomic buffer! */
- free(cmp[cmddep].b[3]);
- cmp[cmddep].b[3] = NULL;
- }
- if (cmp[cmddep].b[4]) {
- strncpy(atxbuf,cmp[cmddep].b[4],ATMBL); /* 4: eXpansion buffer */
- free(cmp[cmddep].b[4]);
- cmp[cmddep].b[4] = NULL;
- }
- if (cmp[cmddep].b[5]) {
- strncpy(atybuf,cmp[cmddep].b[5],ATMBL); /* 5: Atom buffer copY */
- free(cmp[cmddep].b[5]);
- cmp[cmddep].b[5] = NULL;
- }
- if (cmp[cmddep].b[6]) {
- strncpy(filbuf,cmp[cmddep].b[6],ATMBL); /* 6: Filename buffer */
- free(cmp[cmddep].b[6]);
- cmp[cmddep].b[6] = NULL;
- }
-#else
- if (cmp_b[cmddep][0]) {
- strncpy(cmdbuf,cmp_b[cmddep][0],CMDBL); /* 0: Command buffer */
- free(cmp_b[cmddep][0]);
- cmp_b[cmddep][0] = NULL;
- }
- if (cmp_b[cmddep][1]) {
- strncpy(savbuf,cmp_b[cmddep][1],CMDBL); /* 1: Save buffer */
- free(cmp_b[cmddep][1]);
- cmp_b[cmddep][1] = NULL;
- }
- if (cmp_b[cmddep][3]) {
- strncpy(atmbuf,cmp_b[cmddep][3],ATMBL); /* 3: Atomic buffer! */
- free(cmp_b[cmddep][3]);
- cmp_b[cmddep][3] = NULL;
- }
- if (cmp_b[cmddep][4]) {
- strncpy(atxbuf,cmp_b[cmddep][4],ATMBL); /* 4: eXpansion buffer */
- free(cmp_b[cmddep][4]);
- cmp_b[cmddep][4] = NULL;
- }
- if (cmp_b[cmddep][5]) {
- strncpy(atybuf,cmp_b[cmddep][5],ATMBL); /* 5: Atom buffer copY */
- free(cmp_b[cmddep][5]);
- cmp_b[cmddep][5] = NULL;
- }
- if (cmp_b[cmddep][6]) {
- strncpy(filbuf,cmp_b[cmddep][6],ATMBL); /* 6: Filename buffer */
- free(cmp_b[cmddep][6]);
- cmp_b[cmddep][6] = NULL;
- }
-#endif /* DCMDBUF */
-
- cmddep--; /* Rise, rise */
- debug(F101,"&cmpop to depth","",cmddep);
- return(cmddep);
-}
-#endif /* NOSPL */
-
-#ifdef COMMENT
-VOID /* Not used */
-stripq(s) char *s; { /* Function to strip '\' quotes */
- char *t;
- while (*s) {
- if (*s == CMDQ) {
- for (t = s; *t != '\0'; t++) *t = *(t+1);
- }
- s++;
- }
-}
-#endif /* COMMENT */
-
-/* Convert tabs to spaces, one for one */
-VOID
-untab(s) char *s; {
- while (*s) {
- if (*s == HT) *s = SP;
- s++;
- }
-}
-
-/* C M N U M -- Parse a number in the indicated radix */
-
-/*
- The radix is specified in the arg list.
- Parses unquoted numeric strings in the given radix.
- Parses backslash-quoted numbers in the radix indicated by the quote:
- \nnn = \dnnn = decimal, \onnn = octal, \xnn = Hexadecimal.
- If these fail, then if a preprocessing function is supplied, that is applied
- and then a second attempt is made to parse an unquoted decimal string.
- And if that fails, the preprocessed string is passed to an arithmetic
- expression evaluator.
-
- Returns:
- -3 if no input present when required,
- -2 if user typed an illegal number,
- -1 if reparse needed,
- 0 otherwise, with argument n set to the number that was parsed
-*/
-/* This is the traditional cmnum() that gets an int */
-int
-cmnum(xhlp,xdef,radix,n,f) char *xhlp, *xdef; int radix, *n; xx_strp f; {
- CK_OFF_T z = (CK_OFF_T)0, check;
- int x;
- x = cmnumw(xhlp,xdef,radix,&z,f);
- *n = z;
- check = *n;
- if (check != z) {
- printf("?Magnitude of result too large for integer - %s\n",ckfstoa(z));
- return(-9);
- }
- return(x);
-}
-
-/*
- This is the new cmnum() that gets a "wide" result, whatever CK_OFF_T
- is defined to be, normally 32 or 64 bits, depending on the platform.
- fdc, 24 Dec 2005.
-*/
-int
-cmnumw(xhlp,xdef,radix,n,f)
- char *xhlp, *xdef; int radix; CK_OFF_T *n; xx_strp f; {
- int x; char *s, *zp, *zq;
-#ifdef COMMENT
- char lbrace, rbrace;
-#endif /* COMMENT */
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
-
-#ifdef COMMENT
- if (cmfldflgs & 1) {
- lbrace = '(';
- rbrace = ')';
- } else {
- lbrace = '{';
- rbrace = '}';
- }
-#endif /* COMMENT */
-
- if (radix != 10 && radix != 8) { /* Just do bases 8 and 10 */
- printf("cmnum: illegal radix - %d\n",radix);
- return(-2);
- } /* Easy to add others but there has never been a need for it. */
- x = cmfld(xhlp,xdef,&s,(xx_strp)0);
- debug(F101,"cmnum: cmfld","",x);
- if (x < 0) return(x); /* Parse a field */
- zp = atmbuf;
-/*
- Edit 192 - Allow any number field to be braced. This lets us include
- spaces in expressions, but perhaps more important lets us have user-defined
- functions in numeric fields.
-*/
- zp = brstrip(zp); /* Strip braces */
- if (cmfldflgs & 1 && *zp == '(') { /* Parens too.. */
- x = (int) strlen(atmbuf);
- if (x > 0) {
- if (*(atmbuf+x-1) == ')') {
- *(atmbuf+x-1) = NUL;
- zp++;
- }
- }
- }
- if (chknum(zp)) { /* Check for number */
- if (radix == 8) { /* If it's supposed to be octal */
- zp = ckradix(zp,8,10); /* convert to decimal */
- if (!zp) return(-2);
- if (!strcmp(zp,"-1")) return(-2);
- }
- errno = 0; /* Got one, we're done. */
- *n = ckatofs(zp);
- if (errno) {
- perror(zp);
- return(-9);
- }
- debug(F101,"cmnum 1st chknum ok","",*n);
- return(0);
- } else if ((x = xxesc(&zp)) > -1) { /* Check for backslash escape */
-
-#ifndef OS2
- *n = x;
-#else
- *n = wideresult;
-#endif /* OS2 */
-
- debug(F101,"cmnum xxesc ok","",*n);
- return(*zp ? -2 : 0);
- } else if (f) { /* If conversion function given */
- zq = atxbuf; /* Try that */
- atxn = CMDBL;
- if ((*f)(zp,&zq,&atxn) < 0) /* Convert */
- return(-2);
- zp = atxbuf;
- }
- debug(F110,"cmnum zp 1",zp,0);
- if (!*zp) zp = xdef; /* Result empty, substitute default */
- debug(F110,"cmnum zp 2",zp,0);
- if (chknum(zp)) { /* Check again for decimal number */
- if (radix == 8) { /* If it's supposed to be octal */
- zp = ckradix(zp,8,10); /* convert to decimal */
- if (!zp) return(-2);
- if (!strcmp(zp,"-1")) return(-2);
- }
- errno = 0;
- *n = ckatofs(zp);
- if (errno) {
- perror(zp);
- return(-9);
- }
- debug(F101,"cmnum 2nd chknum ok","",*n);
- return(0);
-#ifndef NOSPL
- } else if ((x = xxesc(&zp)) > -1) { /* Check for backslash escape */
-#ifndef OS2
- *n = x;
-#else
- *n = wideresult;
-#endif /* OS2 */
- debug(F101,"cmnum xxesc 2 ok","",*n);
- return(*zp ? -2 : 0);
- } else if (f) { /* Not numeric, maybe an expression */
- char * p;
- p = evala(zp);
- if (chknum(p)) {
- if (radix == 8) { /* If it's supposed to be octal */
- zp = ckradix(zp,8,10); /* convert to decimal */
- if (!zp) return(-2);
- if (!strcmp(zp,"-1")) return(-2);
- }
- errno = 0;
- *n = ckatofs(p);
- if (errno) {
- perror(p);
- return(-9);
- }
- debug(F101,"cmnum exp eval ok","",*n);
- return(0);
- } else return(-2);
-#endif /* NOSPL */
- } else { /* Not numeric */
- return(-2);
- }
-}
-
-#ifdef CKCHANNELIO
-extern int z_error;
-#endif /* CKCHANNELIO */
-
-/* C M O F I -- Parse the name of an output file */
-
-/*
- Depends on the external function zchko(); if zchko() not available, use
- cmfld() to parse output file names.
-
- Returns:
- -9 like -2, except message already printed,
- -3 if no input present when required,
- -2 if permission would be denied to create the file,
- -1 if reparse needed,
- 0 or 1 if file can be created, with xp pointing to name.
- 2 if given the name of an existing directory.
-*/
-int
-cmofi(xhlp,xdef,xp,f) char *xhlp, *xdef, **xp; xx_strp f; {
- int x; char *s, *zq;
-#ifdef DOCHKVAR
- int tries;
-#endif /* DOCHKVAR */
-#ifdef DTILDE
- char *dirp;
-#endif /* DTILDE */
-
- cmfldflgs = 0;
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
-
- if (*xhlp == NUL) xhlp = "Output file";
- *xp = "";
-
- debug(F110,"cmofi xdef",xdef,0);
- x = cmfld(xhlp,xdef,&s,(xx_strp)0);
- debug(F111,"cmofi cmfld returns",s,x);
- if (x < 0)
- return(x);
-
- s = brstrip(s); /* Strip enclosing braces */
- debug(F110,"cmofi 1.5",s,0);
-
-#ifdef DOCHKVAR
- tries = 0;
- {
- char *p = s;
- /*
- This is really ugly. If we skip conversion the first time through,
- then variable names like \%a will be used as filenames (e.g. creating
- a file called %A in the root directory). If we DON'T skip conversion
- the first time through, then single backslashes used as directory
- separators in filenames will be misinterpreted as variable lead-ins.
- So we prescan to see if it has any variable references. But this
- module is not supposed to know anything about variables, functions,
- etc, so this code does not really belong here, but rather it should
- be at the same level as zzstring().
- */
-/*
- Hmmm, this looks a lot like chkvar() except it that includes \nnn number
- escapes. But why? This makes commands like "mkdir c:\123" impossible.
- And in fact, "mkdir c:\123" creates a directory called "c:{". What's worse,
- rmdir(), which *does* call chkvar(), won't let us remove it. So let's at
- least try making cmofi() symmetrical with cmifi()...
-*/
-#ifdef COMMENT
- char * q;
- while ( (tries == 0) && (p = strchr(p,CMDQ)) ) {
- q = *(p+1); /* Char after backslash */
- if (!q) /* None, quit */
- break;
- if (isupper(q)) /* If letter, convert to lowercase */
- q = tolower(q);
- if (isdigit(q)) { /* If it's a digit, */
- tries = 1; /* assume it's a backslash code */
- break;
- }
- switch (q) {
- case CMDQ: /* Double backslash */
- tries = 1; /* so call the conversion function */
- break;
- case '%': /* Variable or array reference */
- case '&': /* must be followed by letter */
- if (isalpha(*(p+2)) || (*(p+2) >= '0' && *(p+2) <= '9'))
- tries = 1;
- break;
- case 'm': case 'v': case '$': /* \m(), \v(), \$() */
- if (*(p+2) == '(')
- if (strchr(p+2,')'))
- tries = 1;
- break;
- case 'f': /* \Fname() */
- if (strchr(p+2,'('))
- if (strchr(p+2,')'))
- tries = 1;
- break;
- case '{': /* \{...} */
- if (strchr(p+2,'}'))
- tries = 1;
- break;
- case 'd': case 'o': /* Decimal or Octal number */
- if (isdigit(*(p+2)))
- tries = 1;
- break;
- case 'x': /* Hex number */
- if (isdigit(*(p+2)) ||
- ((*(p+2) >= 'a' && *(p+2) <= 'f') ||
- ((*(p+2) >= 'A' && *(p+2) <= 'F'))))
- tries = 1;
- default:
- break;
- }
- p++;
- }
-#else
-#ifndef NOSPL
- if (f) { /* If a conversion function is given */
- char *s = p; /* See if there are any variables in */
- while (*s) { /* the string and if so, expand them */
- if (chkvar(s)) {
- tries = 1;
- break;
- }
- s++;
- }
- }
-#endif /* NOSPL */
-#endif /* COMMENT */
- }
-#ifdef OS2
-o_again:
-#endif /* OS2 */
- if (tries == 1)
-#endif /* DOCHKVAR */
- if (f) { /* If a conversion function is given */
- zq = atxbuf; /* do the conversion. */
- atxn = CMDBL;
- if ((x = (*f)(s,&zq,&atxn)) < 0)
- return(-2);
- s = atxbuf;
- if (!*s) /* Result empty, substitute default */
- s = xdef;
- }
- debug(F111,"cmofi 2",s,x);
-
-#ifdef DTILDE
- dirp = tilde_expand(s); /* Expand tilde, if any, */
- if (*dirp != '\0') { /* right in the atom buffer. */
- if (setatm(dirp,1) < 0) {
- printf("?Name too long\n");
- return(-9);
- }
- }
- s = atmbuf;
- debug(F110,"cmofi 3",s,0);
-#endif /* DTILDE */
-
- if (iswild(s)) {
- printf("?Wildcards not allowed - %s\n",s);
- return(-2);
- }
- debug(F110,"cmofi 4",s,0);
-
-#ifdef CK_TMPDIR
- /* isdir() function required for this! */
- if (isdir(s)) {
- debug(F110,"cmofi 5: is directory",s,0);
- *xp = s;
- return(2);
- }
-#endif /* CK_TMPDIR */
-
- if (strcmp(s,CTTNAM) && (zchko(s) < 0)) { /* OK to write to console */
-#ifdef COMMENT
-#ifdef OS2
-/*
- We don't try again because we already prescanned the string to see if
- if it contained anything that could be used by zzstring().
-*/
- if (tries++ < 1)
- goto o_again;
-#endif /* OS2 */
-#endif /* COMMENT */
-/*
- Note: there are certain circumstances where zchko() can give a false
- positive, so don't rely on it to catch every conceivable situation in
- which the given output file can't be created. In other words, we print
- a message and fail here if we KNOW the file can't be created. If we
- succeed but the file can't be opened, the code that tries to open the file
- has to print a message.
-*/
- debug(F110,"cmofi 6: failure",s,0);
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",s);
- else
-#endif /* CKROOT */
- printf("?Write permission denied - %s\n",s);
-#ifdef CKCHANNELIO
- z_error = FX_ACC;
-#endif /* CKCHANNELIO */
- return(-9);
- } else {
- debug(F110,"cmofi 7: ok",s,0);
- *xp = s;
- return(x);
- }
-}
-
-/* C M I F I -- Parse the name of an existing file */
-
-/*
- This function depends on the external functions:
- zchki() - Check if input file exists and is readable.
- zxpand() - Expand a wild file specification into a list.
- znext() - Return next file name from list.
- If these functions aren't available, then use cmfld() to parse filenames.
-*/
-/*
- Returns
- -4 EOF
- -3 if no input present when required,
- -2 if file does not exist or is not readable,
- -1 if reparse needed,
- 0 or 1 otherwise, with:
- xp pointing to name,
- wild = 1 if name contains '*' or '?', 0 otherwise.
-*/
-
-#ifdef COMMENT /* This horrible hack has been replaced - see further down */
-/*
- C M I O F I -- Parse an input file OR the name of a nonexistent file.
-
- Use this when an existing file is wanted (so we get help, completion, etc),
- but if a file of the given name does not exist, the name of a new file is
- accepted. For example, with the EDIT command (edit an existing file, or
- create a new file). Returns -9 if file does not exist. It is up to the
- caller to check creatability.
-*/
-static int nomsg = 0;
-int
-cmiofi(xhlp,xdef,xp,wild,f) char *xhlp, *xdef, **xp; int *wild; xx_strp f; {
- int msgsave, x;
- msgsave = nomsg;
- nomsg = 1;
- x = cmifi2(xhlp,xdef,xp,wild,0,NULL,f,0);
- nomsg = msgsave;
- return(x);
-}
-#endif /* COMMENT */
-
-int
-cmifi(xhlp,xdef,xp,wild,f) char *xhlp, *xdef, **xp; int *wild; xx_strp f; {
- return(cmifi2(xhlp,xdef,xp,wild,0,NULL,f,0));
-}
-/*
- cmifip() is called when we want to supply a path or path list to search
- in case the filename that the user gives is (a) not absolute, and (b) can't
- be found as given. The path string can be the name of a single directory,
- or a list of directories separated by the PATHSEP character, defined in
- ckucmd.h. Look in ckuusr.c and ckuus3.c for examples of usage.
-*/
-int
-cmifip(xhlp,xdef,xp,wild,d,path,f)
- char *xhlp,*xdef,**xp; int *wild, d; char * path; xx_strp f; {
- return(cmifi2(xhlp,xdef,xp,wild,0,path,f,0));
-}
-
-/* C M D I R -- Parse a directory name */
-
-/*
- This function depends on the external functions:
- isdir(s) - Check if string s is the name of a directory
- zchki(s) - Check if input file s exists and what type it is.
- If these functions aren't available, then use cmfld() to parse dir names.
-
- Returns
- -9 For all sorts of reasons, after printing appropriate error message.
- -4 EOF
- -3 if no input present when required,
- -2 if out of space or other internal error,
- -1 if reparse needed,
- 0 or 1, with xp pointing to name, if directory specified,
-*/
-int
-cmdir(xhlp,xdef,xp,f) char *xhlp, *xdef, **xp; xx_strp f; {
- int wild;
- return(cmifi2(xhlp,xdef,xp,&wild,0,NULL,f,1));
-}
-
-/* Like CMDIR but includes PATH search */
-
-int
-cmdirp(xhlp,xdef,xp,path,f) char *xhlp, *xdef, **xp; char * path; xx_strp f; {
- int wild;
- return(cmifi2(xhlp,xdef,xp,&wild,0,path,f,1));
-}
-
-/*
- cmifi2() is the base filename parser called by cmifi, cmifip, cmdir, etc.
- Use it directly when you also want to parse a directory or device
- name as an input file, as in the DIRECTORY command. Call with:
- xhlp -- help message on ?
- xdef -- default response
- xp -- pointer to result (in our space, must be copied from here)
- wild -- flag set upon return to indicate if filespec was wild
- d -- 0 to parse files, 1 to parse files or directories
- Add 2 to inhibit following of symlinks.
- path -- search path for files
- f -- pointer to string processing function (e.g. to evaluate variables)
- dirflg -- 1 to parse *only* directories, 0 otherwise
-*/
-int
-cmifi2(xhlp,xdef,xp,wild,d,path,f,dirflg)
- char *xhlp,*xdef,**xp; int *wild, d; char * path; xx_strp f; int dirflg; {
- extern int recursive, diractive, cdactive, dblquo;
- int i, x, itsadir, xc, expanded = 0, nfiles = 0, children = -1;
- int qflag = 0;
- long y;
- CK_OFF_T filesize;
- char *sp = NULL, *zq, *np = NULL;
- char *sv = NULL, *p = NULL;
-#ifdef DTILDE
- char *dirp;
-#endif /* DTILDE */
-
-#ifndef NOPARTIAL
-#ifndef OS2
-#ifdef OSK
- /* This large array is dynamic for OS-9 -- should do for others too... */
- extern char **mtchs;
-#else
-#ifdef UNIX
- /* OK, for UNIX too */
- extern char **mtchs;
-#else
-#ifdef VMS
- extern char **mtchs;
-#else
- extern char *mtchs[];
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* NOPARTIAL */
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
-
-#ifndef NOLASTFILE
- makestr(&tmplastfile,NULL);
-#endif /* NOLASTFILE */
- nzxopts = 0; /* zxpand() options */
- debug(F101,"cmifi d","",d);
- if (d & 2) { /* d & 2 means don't follow symlinks */
- d ^= 2;
- nzxopts = ZX_NOLINKS;
- }
- debug(F101,"cmifi nzxopts","",nzxopts);
- cmfldflgs = 0;
- if (path)
- if (!*path)
- path = NULL;
- if (path) { /* Make a copy we can poke */
- x = strlen(path);
- np = (char *) malloc(x + 1);
- if (np) {
- strcpy(np, path);
- path = sp = np;
- }
- }
- debug(F110,"cmifi2 path",path,0);
-
- ckstrncpy(cmdefault,xdef,CMDEFAULT); /* Copy default */
- xdef = cmdefault;
-
- inword = 0; /* Initialize counts & pointers */
- cc = 0;
- xc = 0;
- *xp = ""; /* Pointer to result string */
- if ((x = cmflgs) != 1) { /* Already confirmed? */
-#ifdef BS_DIRSEP
- dirnamflg = 1;
- x = gtword(0); /* No, get a word */
- dirnamflg = 0;
-#else
- x = gtword(0); /* No, get a word */
-#endif /* BS_DIRSEP */
- } else { /* If so, use default, if any. */
- if (setatm(xdef,1) < 0) {
- printf("?Default name too long\n");
- if (np) free(np);
- return(-9);
- }
- }
- i_path:
- *xp = atmbuf; /* Point to result. */
-
- while (1) {
- xc += cc; /* Count this character. */
- debug(F111,"cmifi gtword",atmbuf,xc);
- debug(F101,"cmifi switch x","",x);
- switch (x) { /* x = gtword() return code */
- case -10:
- if (gtimer() > timelimit) {
-#ifdef IKSD
- if (inserver) {
- printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", timelimit);
- doexit(GOOD_EXIT,0);
- }
-#endif /* IKSD */
- /* if (!quiet) printf("?Timed out\n"); */
- return(-10);
- } else {
- x = gtword(0);
- continue;
- }
- case -9:
- printf("Command or field too long\n");
- case -4: /* EOF */
- case -2: /* Out of space. */
- case -1: /* Reparse needed */
- if (np) free(np);
- return(x);
- case 1: /* CR */
- case 0: /* SP */
- if (xc == 0) /* If no input... */
- *xp = xdef; /* substitute the default */
-#ifndef NOLASTFILE
- makestr(&tmplastfile,*xp); /* Make a copy before bstripping */
-#endif /* #ifndef NOLASTFILE */
- *xp = brstrip(*xp); /* Strip braces */
- if (**xp == NUL) { /* 12 mar 2001 */
- if (np) free(np);
- return(-3);
- }
- debug(F110,"cmifi brstrip",*xp,0);
-#ifndef NOSPL
- if (f) { /* If a conversion function is given */
-#ifdef DOCHKVAR
- char *s = *xp; /* See if there are any variables in */
- int x;
- while (*s) { /* the string and if so, expand them */
- x = chkvar(s);
- /* debug(F111,"cmifi chkvar",*xp,x); */
- if (x) {
-#endif /* DOCHKVAR */
- zq = atxbuf;
- atxn = CMDBL;
- if ((*f)(*xp,&zq,&atxn) < 0) {
- if (np) free(np);
- return(-2);
- }
- *xp = atxbuf;
- if (!atxbuf[0])
- *xp = xdef;
-#ifdef DOCHKVAR
- break;
- }
- s++;
- }
-#endif /* DOCHKVAR */
- }
-#endif /* NOSPL */
- if (**xp == NUL) { /* 12 mar 2001 */
- if (np) free(np);
- return(-3);
- }
-#ifdef DTILDE
- if (dirflg) {
- dirp = tilde_expand(*xp); /* Expand tilde, if any, */
- if (*dirp != '\0') { /* in the atom buffer. */
- if (setatm(dirp,1) < 0) {
- printf("Expanded name too long\n");
- if (np) free(np);
- return(-9);
- }
- }
- *xp = atmbuf;
- debug(F110,"cmifi tilde_expand",*xp,0);
- }
-#endif /* DTILDE */
- if (!sv) { /* Only do this once */
- sv = malloc((int)strlen(*xp)+1); /* Make a safe copy */
- if (!sv) {
- printf("?cmifi: malloc error\n");
- if (np) free(np);
- return(-9);
- }
- strcpy(sv,*xp);
- debug(F110,"cmifi sv",sv,0);
- }
-
-/* This is to get around "cd /" failing because "too many directories match" */
-
- expanded = 0; /* Didn't call zxpand */
-#ifdef datageneral
- debug(F110,"cmifi isdir 1",*xp,0);
- {
- int y; char *s;
- s = *xp;
- y = strlen(s);
- if (y > 1 &&
- (s[y-1] == ':' ||
- s[y-1] == '^' ||
- s[y-1] == '=')
- )
- s[y-1] = NUL;
- }
- debug(F110,"cmifi isdir 2",*xp,0);
-#endif /* datageneral */
-
-#ifdef VMS
- if (dirflg) {
- if (!strcmp(*xp,"..")) { /* For UNIXers... */
- setatm("-",0);
- *xp = atmbuf;
- } else if (!strcmp(*xp,".")) {
- setatm("[]",0);
- *xp = atmbuf;
- }
- }
-#endif /* VMS */
- itsadir = isdir(*xp); /* Is it a directory? */
- debug(F111,"cmifi itsadir",*xp,itsadir);
-#ifdef VMS
- /* If they said "blah" where "blah.dir" is a directory... */
- /* change it to [.blah]. */
- if (!itsadir) {
- char tmpbuf[600];
- int flag = 0; char c, * p;
- p = *xp;
- while ((c = *p++) && !flag)
- if (ckstrchr(".[]:*?<>",c))
- flag = 1;
- debug(F111,"cmifi VMS dirname flag",*xp,flag);
- if (!flag) {
- ckmakmsg(tmpbuf,TMPBUFSIZ,"[.",*xp,"]",NULL);
- itsadir = isdir(tmpbuf);
- if (itsadir) {
- setatm(tmpbuf,0);
- *xp = atmbuf;
- }
- debug(F111,"cmifi VMS dirname flag itsadir",*xp,itsadir);
- }
- } else if (itsadir == 1 && *(xp[0]) == '.' && *(xp[1])) {
- char *p;
- if (p = malloc(cc + 4)) {
- ckmakmsg(p,cc+4,"[",*xp,"]",NULL);
- setatm(p,0);
- *xp = atmbuf;
- debug(F110,"cmdir .foo",*xp,0);
- free(p);
- }
- } else if (itsadir == 2 && !diractive) {
- int x; /* [FOO]BAR.DIR instead of [FOO.BAR] */
- char *p;
- p = malloc(cc + 4);
- if (p) {
- x = cvtdir(*xp,p,ATMBL); /* Convert to [FOO.BAR] */
- if (x > 0) {
- setatm(p,0);
- *xp = atmbuf;
- debug(F110,"cmdir cvtdir",*xp,0);
- }
- free(p);
- }
- }
-#endif /* VMS */
-
- debug(F101,"cmifi dirflg","",dirflg);
- if (dirflg) { /* Parsing a directory name? */
- /* Yes, does it contain wildcards? */
- if (iswild(*xp) ||
- (diractive && (!strcmp(*xp,".") || !strcmp(*xp,"..")))
- ) {
- nzxopts |= ZX_DIRONLY; /* Match only directory names */
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- debug(F111,"cmifi nzxopts 2",*xp,nzxopts);
- y = nzxpand(*xp,nzxopts);
- debug(F111,"cmifi nzxpand 2",*xp,y);
- nfiles = y;
- expanded = 1;
- } else {
-#ifdef VMS
-/*
- This is to allow (e.g.) "cd foo", where FOO.DIR;1 is in the
- current directory.
-*/
- debug(F111,"cmdir itsadir",*xp,itsadir);
- if (!itsadir) {
- char *s;
- int n;
- s = *xp;
- n = strlen(s);
- if (n > 0 &&
-#ifdef COMMENT
- *s != '[' && s[n-1] != ']' &&
- *s != '<' && s[n-1] != '>' &&
-#else
- ckindex("[",s,0,0,1) == 0 &&
- ckindex("<",s,0,0,1) == 0 &&
-#endif /* COMMENT */
- s[n-1] != ':') {
- char * dirbuf = NULL;
- dirbuf = (char *)malloc(n+4);
- if (dirbuf) {
- if (*s == '.')
- ckmakmsg(dirbuf,n+4,"[",s,"]",NULL);
- else
- ckmakmsg(dirbuf,n+4,"[.",s,"]",NULL);
- itsadir = isdir(dirbuf);
- debug(F111,"cmdir dirbuf",dirbuf,itsadir);
- if (itsadir) {
- setatm(dirbuf,0);
- *xp = atmbuf;
- debug(F110,"cmdir new *xp",*xp,0);
- }
- free(dirbuf);
- }
-
-/* This is to allow CDPATH to work in VMS... */
-
- } else if (n > 0) {
- char * p; int i, j, k, d;
- char rb[2] = "]";
- if (p = malloc(x + 8)) {
- ckstrncpy(p,*xp,x+8);
- i = ckindex(".",p,-1,1,1);
- d = ckindex(".dir",p,0,0,0);
- j = ckindex("]",p,-1,1,1);
- if (j == 0) {
- j = ckindex(">",p,-1,1,1);
- rb[0] = '>';
- }
- k = ckindex(":",p,-1,1,1);
- if (i < j || i < k) i = 0;
- if (d < j || d < k) d = 0;
- /* Change [FOO]BAR or [FOO]BAR.DIR */
- /* to [FOO.BAR] */
- if (j > 0 && j < n) {
- p[j-1] = '.';
- if (d > 0) p[d-1] = NUL;
- ckstrncat(p,rb,x+8);
- debug(F110,"cmdir xxx",p,0);
- }
- itsadir = isdir(p);
- debug(F111,"cmdir p",p,itsadir);
- if (itsadir) {
- setatm(p,0);
- *xp = atmbuf;
- debug(F110,"cmdir new *xp",*xp,0);
- }
- free(p);
- }
- }
- }
-#endif /* VMS */
- y = (!itsadir) ? 0 : 1;
- debug(F111,"cmifi y itsadir",*xp,y);
- }
- } else { /* Parsing a filename. */
- debug(F110,"cmifi *xp pre-zxpand",*xp,0);
-#ifndef COMMENT
- nzxopts |= (d == 0) ? ZX_FILONLY : 0; /* So always expand. */
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- y = nzxpand(*xp,nzxopts);
-#else
-/* Here we're trying to fix a problem in which a directory name is accepted */
-/* as a filename, but this breaks too many other things. */
- /* nzxopts = 0; */
- if (!d) {
- if (itsadir & !iswild(*xp)) {
- debug(F100,"cmifi dir when filonly","",0);
- printf("?Not a regular file: \"%s\"\n",*xp);
- if (sv) free(sv);
- if (np) free(np);
- return(-9);
- } else {
- nzxopts |= ZX_FILONLY;
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- y = nzxpand(*xp,nzxopts);
- }
- }
-#endif /* COMMENT */
- nfiles = y;
- debug(F111,"cmifi y nzxpand",*xp,y);
- debug(F111,"cmifi y atmbuf",atmbuf,itsadir);
- expanded = 1;
- }
- /* domydir() calls zxrewind() so we MUST call nzxpand() here */
- if (!expanded && diractive) {
- debug(F110,"cmifi diractive catch-all zxpand",*xp,0);
- nzxopts |= (d == 0) ? ZX_FILONLY : (dirflg ? ZX_DIRONLY : 0);
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- y = nzxpand(*xp,nzxopts);
- debug(F111,"cmifi diractive nzxpand",*xp,y);
- nfiles = y;
- expanded = 1;
- }
- *wild = (iswild(sv) || (y > 1)) && (itsadir == 0);
-
-#ifdef RECURSIVE
- if (!*wild) *wild = recursive;
-#endif /* RECURSIVE */
-
- debug(F111,"cmifi sv wild",sv,*wild);
- debug(F101,"cmifi y","",y);
- if (dirflg && *wild && cdactive) {
- if (y > 1) {
- printf("?Wildcard matches more than one directory\n");
- if (sv) free(sv);
- if (np) free(np);
- return(-9);
- } else {
- znext(*xp);
- }
- }
- if (itsadir && d && !dirflg) { /* It's a directory and not wild */
- if (sv) free(sv); /* and it's ok to parse directories */
- if (np) free(np);
-#ifndef NOLASTFILE
- makestr(&lastfile,tmplastfile);
-#endif /* NOLASTFILE */
- return(x);
- }
- if (y == 0) { /* File was not found */
- int dosearch = 0;
- dosearch = (path != NULL); /* A search path was given */
- if (dosearch) {
- dosearch = hasnopath(sv); /* Filename includes no path */
- debug(F111,"cmifip hasnopath",sv,dosearch);
- }
- if (dosearch) { /* Search the path... */
- char * ptr = path;
- char c;
- while (1) {
- c = *ptr;
- if (c == PATHSEP || c == NUL) {
- if (!*path) {
- path = NULL;
- break;
- }
- *ptr = NUL;
-#ifdef UNIX
-/* By definition of CDPATH, an empty member denotes the current directory */
- if (!*path)
- ckstrncpy(atmbuf,".",ATMBL);
- else
-#endif /* UNIX */
- ckstrncpy(atmbuf,path,ATMBL);
-#ifdef VMS
- atmbuf[ATMBL] = NUL;
-/* If we have a logical name, evaluate it recursively */
- if (*(ptr-1) == ':') { /* Logical name ends in : */
- char *p; int n;
- while (((n = strlen(atmbuf)) > 0) &&
- atmbuf[n-1] == ':') {
- atmbuf[n-1] = NUL;
- for (p = atmbuf; *p; p++)
- if (islower(*p)) *p = toupper(*p);
- debug(F111,"cmdir CDPATH LN 1",atmbuf,n);
- p = getenv(atmbuf);
- debug(F110,"cmdir CDPATH LN 2",p,0);
- if (!p)
- break;
- strncpy(atmbuf,p,ATMBL);
- atmbuf[ATMBL] = NUL;
- }
- }
-#else
-#ifdef OS2
- if (*(ptr-1) != '\\' && *(ptr-1) != '/')
- ckstrncat(atmbuf,"\\",ATMBL);
-#else
-#ifdef UNIX
- if (*(ptr-1) != '/')
- ckstrncat(atmbuf,"/",ATMBL);
-#else
-#ifdef datageneral
- if (*(ptr-1) != ':')
- ckstrncat(atmbuf,":",ATMBL);
-#endif /* datageneral */
-#endif /* UNIX */
-#endif /* OS2 */
-#endif /* VMS */
- ckstrncat(atmbuf,sv,ATMBL);
- debug(F110,"cmifip add path",atmbuf,0);
- if (c == PATHSEP) ptr++;
- path = ptr;
- break;
- }
- ptr++;
- }
- x = 1;
- inword = 0;
- cc = 0;
- xc = (int) strlen(atmbuf);
- *xp = "";
- goto i_path;
- }
- if (d) {
- if (sv) free(sv);
- if (np) free(np);
- return(-2);
- } else {
- if (!nomsg) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",sv);
- else
-#endif /* CKROOT */
- if (!quiet)
- printf("?No %s match - %s\n",
- dirflg ? "directories" : "files", sv);
- }
- if (sv) free(sv);
- if (np) free(np);
- return(-9);
- }
- } else if (y < 0) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",sv);
- else
-#endif /* CKROOT */
- printf("?Too many %s match - %s\n",
- dirflg ? "directories" : "files", sv);
- if (sv) free(sv);
- if (np) free(np);
- return(-9);
- } else if (*wild || y > 1) {
- if (sv) free(sv);
- if (np) free(np);
-#ifndef NOLASTFILE
- makestr(&lastfile,tmplastfile);
-#endif /* NOLASTFILE */
- return(x);
- }
-
- /* If not wild, see if it exists and is readable. */
-
- debug(F111,"cmifi sv not wild",sv,*wild);
- if (expanded)
- znext(*xp); /* Get first (only?) matching file */
- if (dirflg) /* Maybe wild and expanded */
- itsadir = isdir(*xp); /* so do this again. */
- filesize = dirflg ? itsadir : zchki(*xp); /* Check accessibility */
- if (expanded) {
-#ifdef ZXREWIND
- nfiles = zxrewind(); /* Rewind so next znext() gets 1st */
-#else
-
- nzxopts |= dirflg ? ZX_DIRONLY : 0;
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- nfiles = nzxpand(*xp,nzxopts);
-#endif /* ZXREWIND */
- }
- debug(F111,"cmifi nfiles",*xp,nfiles);
- debug(F101,"cmifi filesize","",filesize);
- free(sv); /* done with this */
- sv = NULL;
- if (dirflg && !filesize) {
- printf("?Not a directory - %s\n",*xp);
-#ifdef CKCHANNELIO
- z_error = FX_ACC;
-#endif /* CKCHANNELIO */
- return(-9);
- } else if (filesize == (CK_OFF_T)-3) {
- if (!xcmfdb) {
- if (diractive)
- /* Don't show filename if we're not allowed to see it */
- printf("?Read permission denied\n");
- else
- printf("?Read permission denied - %s\n",*xp);
- }
- if (np) free(np);
-#ifdef CKCHANNELIO
- z_error = FX_ACC;
-#endif /* CKCHANNELIO */
- return(xcmfdb ? -6 : -9);
- } else if (filesize == (CK_OFF_T)-2) {
- if (!recursive) {
- if (np) free(np);
- if (d) {
-#ifndef NOLASTFILE
- makestr(&lastfile,tmplastfile);
-#endif /* NOLASTFILE */
- return(0);
- }
- if (!xcmfdb)
- printf("?File not readable - %s\n",*xp);
-#ifdef CKCHANNELIO
- z_error = FX_ACC;
-#endif /* CKCHANNELIO */
- return(xcmfdb ? -6 : -9);
- }
- } else if (filesize < (CK_OFF_T)0) {
- if (np) free(np);
- if (!nomsg && !xcmfdb)
- printf("?File not found - %s\n",*xp);
-#ifdef CKCHANNELIO
- z_error = FX_FNF;
-#endif /* CKCHANNELIO */
- return(xcmfdb ? -6 : -9);
- }
- if (np) free(np);
-#ifndef NOLASTFILE
- makestr(&lastfile,tmplastfile);
-#endif /* NOLASTFILE */
- return(x);
-
-#ifndef MAC
- case 2: /* ESC */
- debug(F101,"cmifi esc, xc","",xc);
- if (xc == 0) {
- if (*xdef) {
- printf("%s ",xdef); /* If at beginning of field */
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- inword = cmflgs = 0;
- addbuf(xdef); /* Supply default. */
- if (setatm(xdef,0) < 0) {
- printf("Default name too long\n");
- if (np) free(np);
- return(-9);
- }
- } else { /* No default */
- bleep(BP_WARN);
- }
- break;
- }
- if (**xp == '{') { /* Did user type opening brace... */
- *xp = *xp + 1;
- xc--;
- cc--;
- qflag = '}';
- } else if (dblquo && **xp == '"') { /* or doublequote? */
- *xp = *xp + 1; /* If so ignore it and space past it */
- xc--;
- cc--;
- qflag = '"';
- }
-#ifndef NOSPL
- if (f) { /* If a conversion function is given */
-#ifdef DOCHKVAR
- char *s = *xp; /* See if there are any variables in */
- while (*s) { /* the string and if so, expand it. */
- if (chkvar(s)) {
-#endif /* DOCHKVAR */
- zq = atxbuf;
- atxn = CMDBL;
- if ((x = (*f)(*xp,&zq,&atxn)) < 0) {
- if (np) free(np);
- return(-2);
- }
-#ifdef DOCHKVAR
- /* reduce cc by number of \\ consumed by conversion */
- /* function (needed for OS/2, where \ is path separator) */
- cc -= (strlen(*xp) - strlen(atxbuf));
-#endif /* DOCHKVAR */
- *xp = atxbuf;
- if (!atxbuf[0]) { /* Result empty, use default */
- *xp = xdef;
- cc = strlen(xdef);
- }
-#ifdef DOCHKVAR
- break;
- }
- s++;
- }
-#endif /* DOCHKVAR */
- }
-#endif /* NOSPL */
-
-#ifdef DTILDE
- if (dirflg && *(*xp) == '~') {
- debug(F111,"cmifi tilde_expand A",*xp,cc);
- dirp = tilde_expand(*xp); /* Expand tilde, if any... */
- if (!dirp) dirp = "";
- if (*dirp) {
- int i, xx;
- char * sp;
- xc = cc; /* Length of ~thing */
- xx = setatm(dirp,0); /* Copy expansion to atom buffer */
- debug(F111,"cmifi tilde_expand B",atmbuf,cc);
- if (xx < 0) {
- printf("Expanded name too long\n");
- if (np) free(np);
- return(-9);
- }
- debug(F111,"cmifi tilde_expand xc","",xc);
- for (i = 0; i < xc; i++) {
- cmdchardel(); /* Back up over ~thing */
- bp--;
- }
- xc = cc; /* How many new ones we just got */
- sp = atmbuf;
- printf("%s",sp); /* Print them */
- while ((*bp++ = *sp++)) ; /* Copy to command buffer */
- bp--; /* Back up over NUL */
- }
- *xp = atmbuf;
- }
-#endif /* DTILDE */
-
- sp = *xp + cc;
-
-#ifdef UNIXOROSK
- if (!strcmp(atmbuf,"..")) {
- printf(" ");
- ckstrncat(cmdbuf," ",CMDBL);
- cc++;
- bp++;
- *wild = 0;
- *xp = atmbuf;
- break;
- } else if (!strcmp(atmbuf,".")) {
- bleep(BP_WARN);
- if (np) free(np);
- return(-1);
- } else {
- /* This patches a glitch when user types "./foo<ESC>" */
- /* in which the next two chars are omitted from the */
- /* expansion. There should be a better fix, however, */
- /* since there is no problem with "../foo<ESC>". */
- char *p = *xp;
- if (*p == '.' && *(p+1) == '/')
- cc -= 2;
- }
-#endif /* UNIXOROSK */
-
-#ifdef datageneral
- *sp++ = '+'; /* Data General AOS wildcard */
-#else
- *sp++ = '*'; /* Others */
-#endif /* datageneral */
- *sp-- = '\0';
-#ifdef GEMDOS
- if (!strchr(*xp, '.')) /* abde.e -> abcde.e* */
- strcat(*xp, ".*"); /* abc -> abc*.* */
-#endif /* GEMDOS */
- /* Add wildcard and expand list. */
-#ifdef COMMENT
- /* This kills partial completion when ESC given in path segment */
- nzxopts |= dirflg ? ZX_DIRONLY : (d ? 0 : ZX_FILONLY);
-#else
- /* nzxopts = 0; */
-#endif /* COMMENT */
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- y = nzxpand(*xp,nzxopts);
- nfiles = y;
- debug(F111,"cmifi nzxpand",*xp,y);
- if (y > 0) {
-#ifdef OS2
- znext(filbuf); /* Get first */
-#ifdef ZXREWIND
- zxrewind(); /* Must "rewind" */
-#else
- nzxpand(*xp,nxzopts);
-#endif /* ZXREWIND */
-#else /* Not OS2 */
- ckstrncpy(filbuf,mtchs[0],CKMAXPATH);
-#endif /* OS2 */
- } else
- *filbuf = '\0';
- filbuf[CKMAXPATH] = NUL;
- *sp = '\0'; /* Remove wildcard. */
- debug(F111,"cmifi filbuf",filbuf,y);
- debug(F111,"cmifi *xp",*xp,cc);
-
- *wild = (y > 1);
- if (y == 0) {
- if (!nomsg) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",atmbuf);
- else
-#endif /* CKROOT */
- printf("?No %s match - %s\n",
- dirflg ? "directories" : "files", atmbuf);
- if (np) free(np);
- return(-9);
- } else {
- bleep(BP_WARN);
- if (np) free(np);
- return(-1);
- }
- } else if (y < 0) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",atmbuf);
- else
-#endif /* CKROOT */
- printf("?Too many %s match - %s\n",
- dirflg ? "directories" : "files", atmbuf);
- if (np) free(np);
- return(-9);
- } else if (y > 1 /* Not unique */
-#ifndef VMS
- || (y == 1 && isdir(filbuf)) /* Unique directory */
-#endif /* VMS */
- ) {
-#ifndef NOPARTIAL
-/* Partial filename completion */
- int j, k; char c;
- k = 0;
- debug(F111,"cmifi partial",filbuf,cc);
-#ifdef OS2
- {
- int cur = 0,
- len = 0,
- len2 = 0,
- min = strlen(filbuf),
- found = 0;
- char localfn[CKMAXPATH+1];
-
- len = min;
- for (j = 1; j <= y; j++) {
- znext(localfn);
- if (dirflg && !isdir(localfn))
- continue;
- found = 1;
- len2 = strlen(localfn);
- for (cur = cc;
- cur < len && cur < len2 && cur <= min;
- cur++
- ) {
- /* OS/2 or Windows, case doesn't matter */
- if (tolower(filbuf[cur]) != tolower(localfn[cur]))
- break;
- }
- if (cur < min)
- min = cur;
- }
- if (!found)
- min = cc;
- filbuf[min] = NUL;
- if (min > cc)
- k++;
- }
-#else /* OS2 */
- for (i = cc; (c = filbuf[i]); i++) {
- for (j = 1; j < y; j++)
- if (mtchs[j][i] != c) break;
- if (j == y) k++;
- else filbuf[i] = filbuf[i+1] = NUL;
- }
-#endif /* OS2 */
-
-
-#ifndef VMS
- /* isdir() function required for this! */
- if (y == 1 && isdir(filbuf)) { /* Dont we already know this? */
- int len;
- len = strlen(filbuf);
- if (len > 0 && len < ATMBL - 1) {
- if (filbuf[len-1] != dirsep) {
- filbuf[len] = dirsep;
- filbuf[len+1] = NUL;
- }
- }
-/*
- At this point, before just doing partial completion, we should look first to
- see if the given directory does indeed have any subdirectories (dirflg) or
- files (!dirflg); if it doesn't we should do full completion. Otherwise, the
- result looks funny to the user and "?" blows up the command for no good
- reason.
-*/
- {
- int flags = 0;
- filbuf[len+1] = '*';
- filbuf[len+2] = NUL;
- if (dirflg) flags = ZX_DIRONLY;
- children = nzxpand(filbuf,flags);
- debug(F111,"cmifi children",filbuf,children);
- filbuf[len+1] = NUL;
- nzxpand(filbuf,flags); /* Restore previous list */
- if (children == 0)
- goto NOSUBDIRS;
- }
- if (len + 1 > cc)
- k++;
- }
- /* Add doublequotes if there are spaces in the name */
- {
- int x;
- if (qflag) {
- x = (qflag == '}'); /* (or braces) */
- } else {
- x = !dblquo;
- }
- if (filbuf[0] != '"' && filbuf[0] != '{')
- k = dquote(filbuf,ATMBL,x);
- }
-#endif /* VMS */
- debug(F111,"cmifi REPAINT filbuf",filbuf,k);
- if (k > 0) { /* Got more characters */
- debug(F101,"cmifi REPAINT cc","",cc);
- debug(F101,"cmifi REPAINT xc","",xc);
- debug(F110,"cmifi REPAINT bp-cc",bp-cc,0);
- debug(F110,"cmifi REPAINT bp-xc",bp-xc,0);
- sp = filbuf + cc; /* Point to new ones */
- if (qflag || strncmp(filbuf,bp-cc,cc)) { /* Repaint? */
- int x;
- x = cc;
- if (qflag) x++;
- for (i = 0; i < x; i++) {
- cmdchardel(); /* Back up over old partial spec */
- bp--;
- }
- sp = filbuf; /* Point to new word start */
- debug(F110,"cmifi erase ok",sp,0);
- }
- cc = k; /* How many new ones we just got */
- printf("%s",sp); /* Print them */
- while ((*bp++ = *sp++)) ; /* Copy to command buffer */
- bp--; /* Back up over NUL */
- debug(F110,"cmifi partial cmdbuf",cmdbuf,0);
- if (setatm(filbuf,0) < 0) {
- printf("?Partial name too long\n");
- if (np) free(np);
- return(-9);
- }
- debug(F111,"cmifi partial atmbuf",atmbuf,cc);
- *xp = atmbuf;
- }
-#endif /* NOPARTIAL */
- bleep(BP_WARN);
- } else { /* Unique, complete it. */
-#ifndef VMS
-#ifdef CK_TMPDIR
- /* isdir() function required for this! */
- NOSUBDIRS:
- debug(F111,"cmifi unique",filbuf,children);
- if (isdir(filbuf) && children > 0) {
- int len;
- len = strlen(filbuf);
- if (len > 0 && len < ATMBL - 1) {
- if (filbuf[len-1] != dirsep) {
- filbuf[len] = dirsep;
- filbuf[len+1] = NUL;
- }
- }
- sp = filbuf + cc;
- bleep(BP_WARN);
- printf("%s",sp);
- cc++;
- while ((*bp++ = *sp++)) ;
- bp--;
- if (setatm(filbuf,0) < 0) {
- printf("?Directory name too long\n");
- if (np) free(np);
- return(-9);
- }
- debug(F111,"cmifi directory atmbuf",atmbuf,cc);
- *xp = atmbuf;
- } else { /* Not a directory or dirflg */
-#endif /* CK_TMPDIR */
-#endif /* VMS */
-#ifndef VMS /* VMS dir names are special */
-#ifndef datageneral /* VS dirnames must not end in ":" */
- if (dirflg) {
- int len;
- len = strlen(filbuf);
- if (len > 0 && len < ATMBL - 1) {
- if (filbuf[len-1] != dirsep) {
- filbuf[len] = dirsep;
- filbuf[len+1] = NUL;
- }
- }
- }
-#endif /* datageneral */
-#endif /* VMS */
- sp = filbuf + cc; /* Point past what user typed. */
- {
- int x;
- if (qflag) {
- x = (qflag == '}');
- } else {
- x = !dblquo;
- }
- if (filbuf[0] != '"' && filbuf[0] != '{')
- dquote(filbuf,ATMBL,x);
- }
- if (qflag || strncmp(filbuf,bp-cc,cc)) { /* Repaint? */
- int x;
- x = cc;
- if (qflag) x++;
- for (i = 0; i < x; i++) {
- cmdchardel(); /* Back up over old partial spec */
- bp--;
- }
- sp = filbuf; /* Point to new word start */
- debug(F111,"cmifi after erase sp=",sp,cc);
- }
- printf("%s ",sp); /* Print the completed name. */
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- addbuf(sp); /* Add the characters to cmdbuf. */
- if (setatm(filbuf,0) < 0) { /* And to atmbuf. */
- printf("?Completed name too long\n");
- if (np) free(np);
- return(-9);
- }
- inword = cmflgs = 0;
- *xp = brstrip(atmbuf); /* Return pointer to atmbuf. */
- if (dirflg && !isdir(*xp)) {
- printf("?Not a directory - %s\n", filbuf);
- if (np) free(np);
- return(-9);
- }
- if (np) free(np);
-#ifndef NOLASTFILE
- makestr(&lastfile,tmplastfile);
-#endif /* NOLASTFILE */
- return(0);
-#ifndef VMS
-#ifdef CK_TMPDIR
- }
-#endif /* CK_TMPDIR */
-#endif /* VMS */
- }
- break;
-
- case 3: /* Question mark - file menu wanted */
- if (*xhlp == NUL)
- printf(dirflg ? " Directory name" : " Input file specification");
- else
- printf(" %s",xhlp);
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- /* If user typed an opening quote or brace, just skip past it */
-
- if (**xp == '"' || **xp == '{') {
- *xp = *xp + 1;
- xc--;
- cc--;
- }
-#ifndef NOSPL
- if (f) { /* If a conversion function is given */
-#ifdef DOCHKVAR
- char *s = *xp; /* See if there are any variables in */
- while (*s) { /* the string and if so, expand them */
- if (chkvar(s)) {
-#endif /* DOCHKVAR */
- zq = atxbuf;
- atxn = CMDBL;
- if ((x = (*f)(*xp,&zq,&atxn)) < 0) {
- if (np) free(np);
- return(-2);
- }
-#ifdef DOCHKVAR
- /* reduce cc by number of \\ consumed by conversion */
- /* function (needed for OS/2, where \ is path separator) */
- cc -= (strlen(*xp) - strlen(atxbuf));
-#endif /* DOCHKVAR */
- *xp = atxbuf;
-#ifdef DOCHKVAR
- break;
- }
- s++;
- }
-#endif /* DOCHKVAR */
- }
-#endif /* NOSPL */
- debug(F111,"cmifi ? *xp, cc",*xp,cc);
- sp = *xp + cc; /* Insert "*" at end */
-#ifdef datageneral
- *sp++ = '+'; /* Insert +, the DG wild card */
-#else
- *sp++ = '*';
-#endif /* datageneral */
- *sp-- = '\0';
-#ifdef GEMDOS
- if (! strchr(*xp, '.')) /* abde.e -> abcde.e* */
- strcat(*xp, ".*"); /* abc -> abc*.* */
-#endif /* GEMDOS */
- debug(F110,"cmifi ? wild",*xp,0);
-
- nzxopts |= dirflg ? ZX_DIRONLY : (d ? 0 : ZX_FILONLY);
-
- debug(F101,"cmifi matchdot","",matchdot);
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- y = nzxpand(*xp,nzxopts);
- nfiles = y;
- *sp = '\0';
- if (y == 0) {
- if (nomsg) {
- printf(": %s\n",atmbuf);
- printf("%s%s",cmprom,cmdbuf);
- fflush(stdout);
- if (np) free(np);
- return(-1);
- } else {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",atmbuf);
- else
-#endif /* CKROOT */
- printf("?No %s match - %s\n",
- dirflg ? "directories" : "files", atmbuf);
- if (np) free(np);
- return(-9);
- }
- } else if (y < 0) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",atmbuf);
- else
-#endif /* CKROOT */
- printf("?Too many %s match - %s\n",
- dirflg ? "directories" : "files", atmbuf);
- if (np) free(np);
- return(-9);
- } else {
- printf(", one of the following:\n");
- if (filhelp((int)y,"","",1,dirflg) < 0) {
- if (np) free(np);
- return(-9);
- }
- }
- printf("%s%s",cmprom,cmdbuf);
- fflush(stdout);
- break;
-#endif /* MAC */
- }
-#ifdef BS_DIRSEP
- dirnamflg = 1;
- x = gtword(0); /* No, get a word */
- dirnamflg = 0;
-#else
- x = gtword(0); /* No, get a word */
-#endif /* BS_DIRSEP */
- *xp = atmbuf;
- }
-}
-
-/* C M F L D -- Parse an arbitrary field */
-/*
- Returns:
- -3 if no input present when required,
- -2 if field too big for buffer,
- -1 if reparse needed,
- 0 otherwise, xp pointing to string result.
-
- NOTE: Global flag keepallchars says whether this routine should break on CR
- or LF: needed for MINPUT targets and DECLARE initializers, where we want to
- keep control characters if the user specifies them (March 2003). It might
- have been better to change the calling sequence but that was not practical.
-*/
-int
-cmfld(xhlp,xdef,xp,f) char *xhlp, *xdef, **xp; xx_strp f; {
- int x, xc;
- char *zq;
-
- inword = 0; /* Initialize counts & pointers */
- cc = 0;
- xc = 0;
- *xp = "";
-
- debug(F110,"cmfld xdef 1",xdef,0);
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
- ckstrncpy(cmdefault,xdef,CMDEFAULT); /* Copy default */
- xdef = cmdefault;
-
- debug(F111,"cmfld xdef 2",xdef,cmflgs);
- debug(F111,"cmfld atmbuf 1",atmbuf,xc);
-
- if ((x = cmflgs) != 1) { /* Already confirmed? */
- x = gtword(0); /* No, get a word */
- } else {
- if (setatm(xdef,0) < 0) { /* If so, use default, if any. */
- printf("?Default too long\n");
- return(-9);
- }
- }
- *xp = atmbuf; /* Point to result. */
- debug(F111,"cmfld atmbuf 2",atmbuf,cmflgs);
-
- while (1) {
- xc += cc; /* Count the characters. */
- debug(F111,"cmfld gtword",atmbuf,xc);
- debug(F101,"cmfld x","",x);
- switch (x) {
- case -9:
- printf("Command or field too long\n");
- case -4: /* EOF */
- case -3: /* Empty. */
- case -2: /* Out of space. */
- case -1: /* Reparse needed */
- return(x);
- case 1: /* CR */
- case 0: /* SP */
- debug(F111,"cmfld 1",atmbuf,xc);
- if (xc == 0) { /* If no input, return default. */
- if (setatm(xdef,0) < 0) {
- printf("?Default too long\n");
- return(-9);
- }
- }
- *xp = atmbuf; /* Point to what we got. */
- debug(F111,"cmfld 2",atmbuf,((f) ? 1 : 0));
- if (f) { /* If a conversion function is given */
- zq = atxbuf; /* employ it now. */
- atxn = CMDBL;
- if ((*f)(*xp,&zq,&atxn) < 0)
- return(-2);
- debug(F111,"cmfld 3",atxbuf,xc);
- /* Replace by new value -- for MINPUT only keep all chars */
- if (setatm(atxbuf,keepallchars ? 3:1) < 0) { /* 16 Mar 2003 */
- printf("Value too long\n");
- return(-9);
- }
- *xp = atmbuf;
- }
- debug(F111,"cmfld 4",atmbuf,xc);
- if (**xp == NUL) { /* If variable evaluates to null */
- if (setatm(xdef,0) < 0) {
- printf("?Default too long\n");
- return(-9);
- }
- if (**xp == NUL) x = -3; /* If still empty, return -3. */
- }
- debug(F111,"cmfld returns",*xp,x);
- return(x);
- case 2: /* ESC */
- if (xc == 0 && *xdef) {
- printf("%s ",xdef); /* If at beginning of field, */
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- addbuf(xdef); /* Supply default. */
- inword = cmflgs = 0;
- if (setatm(xdef,0) < 0) {
- printf("?Default too long\n");
- return(-9);
- } else /* Return as if whole field */
- return(0); /* typed, followed by space. */
- } else {
- bleep(BP_WARN);
- }
- break;
- case 3: /* Question mark */
- debug(F110,"cmfld QUESTIONMARK",cmdbuf,0);
- if (*xhlp == NUL)
- printf(" Please complete this field");
- else
- printf(" %s",xhlp);
- printf("\n%s%s",cmprom,cmdbuf);
- fflush(stdout);
- break;
- }
- debug(F111,"cmfld gtword A x",cmdbuf,x);
- x = gtword(0);
- debug(F111,"cmfld gtword B x",cmdbuf,x);
- }
-}
-
-
-/* C M T X T -- Get a text string, including confirmation */
-
-/*
- Print help message 'xhlp' if ? typed, supply default 'xdef' if null
- string typed. Returns:
-
- -1 if reparse needed or buffer overflows.
- 1 otherwise.
-
- with cmflgs set to return code, and xp pointing to result string.
-*/
-int
-cmtxt(xhlp,xdef,xp,f) char *xhlp; char *xdef; char **xp; xx_strp f; {
-
- int x, i;
- char *xx, *zq;
- static int xc;
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
-
- cmfldflgs = 0;
-
- cmdefault[0] = NUL;
- if (*xdef)
- ckstrncpy(cmdefault,xdef,CMDEFAULT); /* Copy default */
- xdef = cmdefault;
-
- debug(F101,"cmtxt cmflgs","",cmflgs);
- inword = 0; /* Start atmbuf counter off at 0 */
- cc = 0;
- if (cmflgs == -1) { /* If reparsing, */
- *xp = pp;
- xc = (int)strlen(*xp); /* get back the total text length, */
- bp = *xp; /* and back up the pointers. */
- np = *xp;
- pp = *xp;
- } else { /* otherwise, */
- /* debug(F100,"cmtxt: fresh start","",0); */
- *xp = ""; /* start fresh. */
- xc = 0;
- }
- *atmbuf = NUL; /* And empty the atom buffer. */
- rtimer(); /* Reset timer */
- if ((x = cmflgs) != 1) {
- int done = 0;
- while (!done) {
- x = gtword(0); /* Get first word. */
- *xp = pp; /* Save pointer to it. */
- /* debug(F111,"cmtxt:",*xp,cc); */
- if (x == -10) {
- if (gtimer() > timelimit) {
- /* if (!quiet) printf("?Timed out\n"); */
- return(x);
- }
- } else
- done = 1;
- }
- }
- while (1) { /* Loop for each word in text. */
- xc += cc; /* Char count for all words. */
- /* debug(F111,"cmtxt gtword",atmbuf,xc); */
- /* debug(F101,"cmtxt x","",x); */
- switch (x) {
- case -10:
- if (gtimer() > timelimit) {
-#ifdef IKSD
- extern int inserver;
- if (inserver) {
- printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", timelimit);
- doexit(GOOD_EXIT,0);
- }
-#endif /* IKSD */
- /* if (!quiet) printf("?Timed out\n"); */
- return(-10);
- } else {
- x = gtword(0);
- continue;
- }
- case -9: /* Buffer overflow */
- printf("Command or field too long\n");
- case -4: /* EOF */
-#ifdef MAC
- case -3: /* Quit/Timeout */
-#endif /* MAC */
- case -2: /* Overflow */
- case -1: /* Deletion */
- return(x);
- case 0: /* Space */
- xc++; /* Just count it */
- break;
- case 1: /* CR or LF */
- if (xc == 0) *xp = xdef;
- if (f) { /* If a conversion function is given */
- char * sx = atxbuf;
- zq = atxbuf; /* Point to the expansion buffer */
- atxn = CMDBL; /* specify its length */
- /* debug(F111,"cmtxt calling (*f)",*xp,atxbuf); */
- if ((x = (*f)(*xp,&zq,&atxn)) < 0) return(-2);
- sx = atxbuf;
-#ifndef COMMENT
- cc = 0;
- while (*sx++) cc++; /* (faster than calling strlen) */
-#else
- cc = (int)strlen(atxbuf);
-#endif /* COMMENT */
- /* Should be equal to (CMDBL - atxn) but isn't always. */
- /* Why not? */
- if (cc < 1) { /* Nothing in expansion buffer? */
- *xp = xdef; /* Point to default string instead. */
-#ifndef COMMENT
- sx = xdef;
- while (*sx++) cc++; /* (faster than calling strlen) */
-#else
- cc = strlen(xdef);
-#endif /* COMMENT */
- } else { /* Expansion function got something */
- *xp = atxbuf; /* return pointer to it. */
- }
- debug(F111,"cmtxt (*f)",*xp,cc);
- } else { /* No expansion function */
-#ifndef COMMENT
- /* Avoid a strlen() call */
- xx = *xp;
- cc = 0;
- while (*xx++) cc++;
-#else
- /* NO! xc is apparently not always set appropriately */
- cc = xc;
-#endif /* COMMENT */
- }
- xx = *xp;
-#ifdef COMMENT
- /* strlen() no longer needed */
- for (i = (int)strlen(xx) - 1; i > 0; i--)
-#else
- for (i = cc - 1; i > 0; i--)
-#endif /* COMMENT */
- if (xx[i] != SP) /* Trim trailing blanks */
- break;
- else
- xx[i] = NUL;
- return(x);
- case 2: /* ESC */
- if (xc == 0) { /* Nothing typed yet */
- if (*xdef) { /* Have a default for this field? */
- printf("%s ",xdef); /* Yes, supply it */
- inword = cmflgs = 0;
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- cc = addbuf(xdef);
- } else bleep(BP_WARN); /* No default */
- } else { /* Already in field */
- int x; char *p;
- x = strlen(atmbuf);
- if (ckstrcmp(atmbuf,xdef,x,0)) { /* Matches default? */
- bleep(BP_WARN); /* No */
- } else if ((int)strlen(xdef) > x) { /* Yes */
- p = xdef + x;
- printf("%s ", p);
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- addbuf(p);
- inword = cmflgs = 0;
- debug(F110,"cmtxt: addbuf",cmdbuf,0);
- } else {
- bleep(BP_WARN);
- }
- }
- break;
- case 3: /* Question Mark */
- if (*xhlp == NUL)
- printf(" Text string");
- else
- printf(" %s",xhlp);
- printf("\n%s%s",cmprom,cmdbuf);
- fflush(stdout);
- break;
- default:
- printf("?Unexpected return code from gtword() - %d\n",x);
- return(-2);
- }
- x = gtword(0);
- }
-}
-
-/* C M K E Y -- Parse a keyword */
-
-/*
- Call with:
- table -- keyword table, in 'struct keytab' format;
- n -- number of entries in table;
- xhlp -- pointer to help string;
- xdef -- pointer to default keyword;
- f -- string preprocessing function (e.g. to evaluate variables)
- pmsg -- 0 = don't print error messages
- 1 = print error messages
- 2 = include CM_HLP keywords even if invisible
- 3 = 1+2
- 4 = parse a switch (keyword possibly ending in : or =)
- 8 = don't strip comments (used, e.g., for "help #")
- Returns:
- -3 -- no input supplied and no default available
- -2 -- input doesn't uniquely match a keyword in the table
- -1 -- user deleted too much, command reparse required
- n >= 0 -- value associated with keyword
-*/
-
-/*
- Front ends for cmkey2():
- cmkey() - The normal keyword parser
- cmkeyx() - Like cmkey() but suppresses error messages
- cmswi() - Switch parser
-*/
-int
-cmkey(table,n,xhlp,xdef,f)
-/* cmkey */ struct keytab table[]; int n; char *xhlp, *xdef; xx_strp f; {
- return(cmkey2(table,n,xhlp,xdef,"",f,1));
-}
-int
-cmkeyx(table,n,xhlp,xdef,f)
-/* cmkeyx */ struct keytab table[]; int n; char *xhlp, *xdef; xx_strp f; {
- return(cmkey2(table,n,xhlp,xdef,"",f,0));
-}
-int
-cmswi(table,n,xhlp,xdef,f)
-/* cmswi */ struct keytab table[]; int n; char *xhlp, *xdef; xx_strp f; {
- return(cmkey2(table,n,xhlp,xdef,"",f,4));
-}
-
-int
-cmkey2(table,n,xhlp,xdef,tok,f,pmsg)
- struct keytab table[];
- int n;
- char *xhlp, *xdef;
- char *tok;
- xx_strp f;
- int pmsg;
-{ /* cmkey2 */
- extern int havetoken;
- int i, tl, y, z = 0, zz, xc, wordlen = 0, cmswitch;
- char *xp, *zq;
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
-
- cmfldflgs = 0;
- if (!table) {
- printf("?Keyword table missing\n");
- return(-9);
- }
- tl = (int)strlen(tok);
-
- inword = xc = cc = 0; /* Clear character counters. */
- cmswitch = pmsg & 4; /* Flag for parsing a switch */
-
- debug(F101,"cmkey: pmsg","",pmsg);
- debug(F101,"cmkey: cmflgs","",cmflgs);
- debug(F101,"cmkey: cmswitch","",cmswitch);
- /* debug(F101,"cmkey: cmdbuf","",cmdbuf);*/
-
- ppvnambuf[0] = NUL;
-
- if ((zz = cmflgs) == 1) { /* Command already entered? */
- if (setatm(xdef,0) < 0) { /* Yes, copy default into atom buf */
- printf("?Default too long\n");
- return(-9);
- }
- rtimer(); /* Reset timer */
- } else { /* Otherwise get a command word */
- rtimer(); /* Reset timer */
- if (pmsg & 8) /* 8 is for parsing HELP tokens */
- zz = gtword(4);
- else
- zz = gtword((pmsg == 4) ? 1 : 0);
- }
-
- debug(F101,"cmkey table length","",n);
- debug(F101,"cmkey cmflgs","",cmflgs);
- debug(F101,"cmkey cc","",cc);
-
- while (1) {
- xc += cc;
- debug(F111,"cmkey gtword xc",atmbuf,xc);
- debug(F101,"cmkey gtword zz","",zz);
-
- switch (zz) {
- case -10: /* Timeout */
- if (gtimer() < timelimit) {
- if (pmsg & 8) /* 8 is for parsing HELP tokens */
- zz = gtword(4);
- else
- zz = gtword((pmsg == 4) ? 1 : 0);
- continue;
- } else {
-#ifdef IKSD
- extern int inserver;
- if (inserver) {
- printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", timelimit);
- doexit(GOOD_EXIT,0);
- }
-#endif /* IKSD */
- return(-10);
- }
- case -5:
- return(cmflgs = 0);
- case -9:
- printf("Command or field too long\n");
- case -4: /* EOF */
- case -3: /* Null Command/Quit/Timeout */
- case -2: /* Buffer overflow */
- case -1: /* Or user did some deleting. */
- return(cmflgs = zz);
-
-
- case 1: /* CR */
- case 0: /* User terminated word with space */
- case 4: /* or switch ending in : or = */
- wordlen = cc; /* Length if no conversion */
- if (cc == 0) { /* Supply default if we got nothing */
- if ((wordlen = setatm(xdef,(zz == 4) ? 2 : 0)) < 0) {
- printf("?Default too long\n");
- return(-9);
- }
- }
- if (zz == 1 && cc == 0) /* Required field missing */
- return(-3);
-
- if (f) { /* If a conversion function is given */
- char * p2;
- zq = atxbuf; /* apply it */
- p2 = atxbuf;
- atxn = CMDBL;
- if ((*f)(atmbuf,&zq,&atxn) < 0) return(-2);
- debug(F110,"cmkey atxbuf after *f",atxbuf,0);
- if (!*p2) /* Supply default if we got nothing */
- p2 = xdef;
- ckstrncpy(ppvnambuf,atmbuf,PPVLEN);
- if ((wordlen = setatm(p2,(zz == 4) ? 2 : 0)) < 0) {
- printf("Evaluated keyword too long\n");
- return(-9);
- }
-#ifdef M_UNGW
- /*
- This bit lets us save more than one "word".
- For example, "define \%x echo one two three", "\%x".
- It works too, but it breaks labels, and therefore
- WHILE and FOR loops, etc.
- */
- if (p2[wordlen] >= SP) {
- p2 += wordlen;
- while (*p2 == SP) p2++;
- if (*p2) {
- ungword();
- pp = p2;
- }
- }
-#endif /* M_UNGW */
- }
-#ifdef COMMENT /* ^^^ */
- if (cmswitch && *atmbuf != '/') {
- if (pmsg & 1) {
- bleep(BP_FAIL);
- printf("?Not a switch - %s\n",atmbuf);
- }
- cmflgs = -2;
- return(-6);
- }
-#endif /* COMMENT */
- if (cmswitch) {
- int i;
- for (i = 0; i < wordlen; i++) {
- if (atmbuf[i] == ':' || atmbuf[i] == '=') {
- brkchar = atmbuf[i];
- atmbuf[i] = NUL;
- break;
- }
- }
- }
-
-#ifdef TOKPRECHECK
-/* This was an effective optimization but it breaks sometimes on labels. */
- if (tl && !isalpha(atmbuf[0])) { /* Precheck for token */
- for (i = 0; i < tl; i++) { /* Save function call to ckstrchr */
- if (tok[i] == atmbuf[0]) {
- debug(F000,"cmkey token:",atmbuf,*atmbuf);
- ungword(); /* Put back the following word */
- return(-5); /* Special return code for token */
- }
- }
- }
-#endif /* TOKPRECHECK */
-
- y = lookup(table,atmbuf,n,&z); /* Look up word in the table */
- debug(F111,"cmkey lookup",atmbuf,y);
- debug(F101,"cmkey zz","",zz);
- debug(F101,"cmkey cmflgs","",cmflgs);
- debug(F101,"cmkey crflag","",crflag);
- switch (y) {
- case -3: /* Nothing to look up */
- break;
- case -2: /* Ambiguous */
- cmflgs = -2;
- if (pmsg & 1) {
- bleep(BP_FAIL);
- printf("?Ambiguous - %s\n",atmbuf);
- return(-9);
- }
- return(-2);
- case -1: /* Not found at all */
-#ifndef TOKPRECHECK
- if (tl) {
- for (i = 0; i < tl; i++) /* Check for token */
- if (tok[i] == *atmbuf) { /* Got one */
- debug(F000,"cmkey token:",atmbuf,*atmbuf);
- ungword(); /* Put back the following word */
- return(-5); /* Special return code for token */
- }
- }
-#endif /* TOKPRECHECK */
-
- if (tl == 0) { /* No tokens were included */
-#ifdef OS2
- /* In OS/2 and Windows, allow for a disk letter like DOS */
- if (isalpha(*atmbuf) && *(atmbuf+1) == ':')
- return(-7);
-#endif /* OS2 */
- if ((pmsg & 1) && !quiet) {
- bleep(BP_FAIL);
- printf("?No keywords match - %s\n",atmbuf); /* cmkey */
- }
- return(cmflgs = -9);
- } else {
- if (cmflgs == 1 || cmswitch) /* cmkey2 or cmswi */
- return(cmflgs = -6);
- else
- return(cmflgs = -2);
- /* The -6 code is to let caller try another table */
- }
- break;
- default:
-#ifdef CK_RECALL
- if (test(table[z].flgs,CM_NOR)) no_recall = 1;
-#endif /* CK_RECALL */
- if (zz == 4)
- swarg = 1;
- cmkwflgs = table[z].flgs;
- break;
- }
- return(y);
-
- case 2: /* User terminated word with ESC */
- debug(F101,"cmkey Esc cc","",cc);
- if (cc == 0) {
- if (*xdef != NUL) { /* Nothing in atmbuf */
- printf("%s ",xdef); /* Supply default if any */
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- addbuf(xdef);
- if (setatm(xdef,0) < 0) {
- printf("?Default too long\n");
- return(-9);
- }
- inword = cmflgs = 0;
- debug(F111,"cmkey: default",atmbuf,cc);
- } else {
- debug(F101,"cmkey Esc pmsg","",0);
-#ifdef COMMENT
-/*
- Chained FDBs... The idea is that this function might not have a default,
- but the next one might. But if it doesn't, there is no way to come back to
- this one. To be revisited later...
-*/
- if (xcmfdb) /* Chained fdb -- try next one */
- return(-3);
-#endif /* COMMENT */
- if (pmsg & (1|4)) { /* So for now just beep */
- bleep(BP_WARN);
- }
- break;
- }
- }
- if (f) { /* If a conversion function is given */
- char * pp;
- zq = atxbuf; /* apply it */
- pp = atxbuf;
- atxn = CMDBL;
- if ((*f)(atmbuf,&zq,&atxn) < 0)
- return(-2);
- if (!*pp)
- pp = xdef;
- if (setatm(pp,0) < 0) {
- printf("Evaluated keyword too long\n");
- return(-9);
- }
- }
- y = lookup(table,atmbuf,n,&z); /* Something in atmbuf */
- debug(F111,"cmkey lookup y",atmbuf,y);
- debug(F111,"cmkey lookup z",atmbuf,z);
- if (y == -2 && z >= 0 && z < n) { /* Ambiguous */
-#ifndef NOPARTIAL
- int j, k, len = 9999; /* Do partial completion */
- /* Skip past any abbreviations in the table */
- for ( ; z < n; z++) {
- if ((table[z].flgs & CM_ABR) == 0)
- break;
- if (!(table[z].flgs & CM_HLP) || (pmsg & 2))
- break;
- }
- debug(F111,"cmkey partial z",atmbuf,z);
- debug(F111,"cmkey partial n",atmbuf,n);
- for (j = z+1; j < n; j++) {
- debug(F111,"cmkey partial j",table[j].kwd,j);
- if (ckstrcmp(atmbuf,table[j].kwd,cc,0))
- break;
- if (table[j].flgs & CM_ABR)
- continue;
- if ((table[j].flgs & CM_HLP) && !(pmsg & 2))
- continue;
- k = ckstrpre(table[z].kwd,table[j].kwd);
- debug(F111,"cmkey partial k",table[z].kwd,k);
- if (k < len)
- len = k; /* Length of longest common prefix */
- }
- debug(F111,"cmkey partial len",table[z].kwd,len);
- if (len != 9999 && len > cc) {
- ckstrncat(atmbuf,table[z].kwd+cc,ATMBL);
- atmbuf[len] = NUL;
- printf("%s",atmbuf+cc);
- ckstrncat(cmdbuf,atmbuf+cc,CMDBL);
- xc += (len - cc);
- cc = len;
- }
-#endif /* NOPARTIAL */
- bleep(BP_WARN);
- break;
- } else if (y == -3) {
- bleep(BP_WARN);
- break;
- } else if (y == -1) { /* Not found */
- if ((pmsg & 1) && !quiet) {
- bleep(BP_FAIL);
- printf("?No keywords match - \"%s\"\n",atmbuf);
- }
- cmflgs = -2;
- return(-9);
- }
-/*
- If we found it, but it's a help-only keyword and the "help" bit is not
- set in pmsg, then not found.
-*/
- debug(F101,"cmkey flgs","",table[z].flgs);
- if (test(table[z].flgs,CM_HLP) && ((pmsg & 2) == 0)) {
- if ((pmsg & 1) && !quiet) {
- bleep(BP_FAIL);
- printf("?No keywords match - %s\n",atmbuf);
- }
- cmflgs = -2;
- return(-9);
- }
-/*
- See if the keyword just found has the CM_ABR bit set in its flgs field, and
- if so, search forwards in the table for a keyword that has the same kwval
- but does not have CM_ABR (or CM_INV?) set, and then expand using the full
- keyword. WARNING: This assumes that (a) keywords are in alphabetical order,
- and (b) the CM_ABR bit is set only if the the abbreviated keyword is a true
- abbreviation (left substring) of the full keyword.
-*/
- if (test(table[z].flgs,CM_ABR)) {
- int zz;
- for (zz = z+1; zz < n; zz++)
- if ((table[zz].kwval == table[z].kwval) &&
- (!test(table[zz].flgs,CM_ABR)) &&
- (!test(table[zz].flgs,CM_INV))) {
- z = zz;
- break;
- }
- }
- xp = table[z].kwd + cc;
- if (cmswitch && test(table[z].flgs,CM_ARG)) {
-#ifdef VMS
- printf("%s=",xp);
- brkchar = '=';
-#else
- printf("%s:",xp);
- brkchar = ':';
-#endif /* VMS */
- } else {
- printf("%s ",xp);
- brkchar = SP;
- }
-#ifdef CK_RECALL
- if (test(table[z].flgs,CM_NOR)) no_recall = 1;
-#endif /* CK_RECALL */
- cmkwflgs = table[z].flgs;
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- addbuf(xp);
- if (cmswitch && test(table[z].flgs,CM_ARG)) {
- bp--; /* Replace trailing space with : */
-#ifdef VMS
- *bp++ = '=';
-#else
- *bp++ = ':';
-#endif /* VMS */
- *bp = NUL;
- np = bp;
- swarg = 1;
- }
- inword = 0;
- cmflgs = 0;
- debug(F110,"cmkey: addbuf",cmdbuf,0);
- return(y);
-
- case 3: /* User typed "?" */
- if (f) { /* If a conversion function is given */
- char * pp;
- zq = atxbuf; /* do the conversion now. */
- pp = atxbuf;
- atxn = CMDBL;
- if ((*f)(atmbuf,&zq,&atxn) < 0) return(-2);
- if (setatm(pp,0) < 0) {
- printf("?Evaluated keyword too long\n");
- return(-9);
- }
- }
- y = lookup(table,atmbuf,n,&z); /* Look up what we have so far. */
- if (y == -1) {
- /*
- Strictly speaking if the main keyword table search fails,
- then we should look in the token table if one is given.
- But in practice, tokens are also included in the main
- keyword table.
- */
- cmflgs = -2;
- if ((pmsg & 1) && !quiet) {
- bleep(BP_FAIL);
- printf(" No keywords match\n");
- return(-9);
- }
- return(-2);
- }
-#ifndef COMMENT
- /* This is to allow ?-help to work immediately after a token */
- /* without having to type an intermediate space */
- if (tl) {
- for (i = 0; i < tl; i++) /* Check for token */
- if (tok[i] == *atmbuf) { /* Got one */
- debug(F000,"cmkey token:",atmbuf,*atmbuf);
- ungword(); /* Put back the following word */
- cmflgs = 3; /* Force help next time around */
- return(-5); /* Special return code for token */
- }
- }
-#endif /* COMMENT */
-
- if (*xhlp == NUL)
- printf(" One of the following:\n");
- else
- printf(" %s, one of the following:\n",xhlp);
- {
- int x;
- x = pmsg & (2|4); /* See kwdhelp() comments */
- if (atmbuf[0]) /* If not at beginning of field */
- x |= 1; /* also show invisibles */
- kwdhelp(table,n,atmbuf,"","",1,x);
- }
-#ifndef NOSPL
- if (!havetoken) {
- extern int topcmd;
- if (tl > 0 && topcmd != XXHLP) /* This is bad... */
- printf("or a macro name (\"do ?\" for a list) ");
- }
-#endif /* NOSPL */
- if (*atmbuf == NUL && !havetoken) {
- if (tl == 1)
- printf("or the token %c\n",*tok);
- else if (tl > 1)
- printf("or one of the tokens: %s\n",ckspread(tok));
- }
- printf("%s%s", cmprom, cmdbuf);
- fflush(stdout);
- break;
-
- default:
- printf("\n%d - Unexpected return code from gtword\n",zz);
- return(cmflgs = -2);
- }
- zz = (pmsg & 8) ? gtword(4) : gtword((pmsg == 4) ? 1 : 0);
- debug(F111,"cmkey gtword zz",atmbuf,zz);
- }
-}
-
-int
-chktok(tlist) char *tlist; {
- char *p;
- p = tlist;
- while (*p != NUL && *p != *atmbuf) p++;
- return((*p) ? (int) *p : 0);
-}
-
-/* Routines for parsing and converting dates and times */
-
-#define isdatesep(c) (ckstrchr(" -/._",c))
-
-#define CMDATEBUF 1024
-char cmdatebuf[CMDATEBUF+4] = { NUL, NUL };
-static char * cmdatebp = cmdatebuf;
-char * cmdatemsg = NULL;
-
-static struct keytab timeunits[] = {
- { "days", TU_DAYS, 0 },
- { "months", TU_MONTHS, 0 },
- { "weeks", TU_WEEKS, 0 },
- { "wks", TU_WEEKS, 0 },
- { "years", TU_YEARS, 0 },
- { "yrs", TU_YEARS, 0 }
-};
-static int nunits = (sizeof(timeunits) / sizeof(struct keytab));
-
-#define SYM_NOW 0
-#define SYM_TODA 1
-#define SYM_TOMO 2
-#define SYM_YEST 3
-
-static struct keytab symdaytab[] = {
- { "now", SYM_NOW, 0 },
- { "today", SYM_TODA, 0 },
- { "tomorrow", SYM_TOMO, 0 },
- { "yesterday", SYM_YEST, 0 }
-};
-static int nsymdays = (sizeof(symdaytab) / sizeof(struct keytab));
-
-static struct keytab daysofweek[] = {
- { "Friday", 5, 0 },
- { "Monday", 1, 0 },
- { "Saturday", 6, 0 },
- { "Sunday", 0, 0 },
- { "Thursday", 4, 0 },
- { "Tuesday", 2, 0 },
- { "Wednesday", 3, 0 }
-};
-
-static struct keytab usatz[] = { /* RFC 822 timezones */
- { "cdt", 5, 0 }, /* Values are GMT offsets */
- { "cst", 6, 0 },
- { "edt", 4, 0 },
- { "est", 5, 0 },
- { "gmt", 0, 0 },
- { "mdt", 6, 0 },
- { "mst", 7, 0 },
- { "pdt", 7, 0 },
- { "pst", 8, 0 },
- { "utc", 0, 0 },
- { "zulu", 0, 0 }
-};
-static int nusatz = (sizeof(usatz) / sizeof(struct keytab));
-
-
-/* C M C V T D A T E -- Converts free-form date to standard form. */
-
-/*
- Call with
- s = pointer to free-format date, time, or date and time.
- t = 0: return time only if time was given in s.
- t = 1: always return time (00:00:00 if no time given in s).
- t = 2: allow time to be > 24:00:00.
- Returns:
- NULL on failure;
- Pointer to "yyyymmdd hh:mm:ss" (local date-time) on success.
-*/
-
-/*
- Before final release the following long lines should be wrapped.
- Until then we leave them long since wrapping them wrecks EMACS's
- C indentation.
-*/
-
-/* asctime pattern */
-static char * atp1 = "[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9][0-9][0-9]";
-
-/* asctime pattern with timezone */
-static char * atp2 = "[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [A-Z][A-Z][A-Z] [0-9][0-9][0-9][0-9]";
-
-#define DATEBUFLEN 127
-#define YYYYMMDD 12
-
-#define isleap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
-static int mdays[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-#define NEED_DAYS 1
-#define NEED_HRS 2
-#define NEED_MINS 3
-#define NEED_SECS 4
-#define NEED_FRAC 5
-
-#define DELTABUF 256
-static char deltabuf[DELTABUF];
-static char * deltabp = deltabuf;
-
-char *
-cmdelta(yy, mo, dd, hh, mm, ss, sign, dyy, dmo, ddd, dhh, dmm, dss)
- int yy, mo, dd, hh, mm, ss, sign, dyy, dmo, ddd, dhh, dmm, dss;
-/* cmdelta */ {
- int zyy, zmo, zdd, zhh, zmm, zss;
- long t1, t2, t3, t4;
- long d1 = 0, d2, d3;
- char datebuf[DATEBUFLEN+1];
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"cmdelta yy","",yy);
- debug(F101,"cmdelta mo","",mo);
- debug(F101,"cmdelta dd","",dd);
- debug(F101,"cmdelta hh","",hh);
- debug(F101,"cmdelta mm","",mm);
- debug(F101,"cmdelta ss","",ss);
- debug(F101,"cmdelta sign","",sign);
- debug(F101,"cmdelta dyy","",dyy);
- debug(F101,"cmdelta dmo","",dmo);
- debug(F101,"cmdelta ddd","",ddd);
- debug(F101,"cmdelta dhh","",dhh);
- debug(F101,"cmdelta dmm","",dmm);
- debug(F101,"cmdelta dss","",dss);
- }
-#endif /* DEBLOG */
-
- if (yy < 0 || yy > 9999) {
- makestr(&cmdatemsg,"Base year out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- if (mo < 1 || mo > 12) {
- makestr(&cmdatemsg,"Base month out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- if (dd < 1 || dd > mdays[mo]) {
- makestr(&cmdatemsg,"Base day out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- if (hh < 0 || hh > 23) {
- makestr(&cmdatemsg,"Base hour out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- if (mm < 0 || mm > 59) {
- makestr(&cmdatemsg,"Base minute out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- if (ss < 0 || ss > 60) {
- makestr(&cmdatemsg,"Base second out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- sign = (sign < 0) ? -1 : 1;
- if (dmo != 0) {
- if (sign > 0) {
- mo += (sign * dmo);
- if (mo > 12) {
- yy += mo / 12;
- mo = mo % 12;
- }
- } else if (sign < 0) {
- while (dmo > 12) {
- yy--;
- dmo -= 12;
- }
- if (dmo < mo) {
- mo -= dmo;
- } else {
- yy--;
- mo = 12 - (dmo - mo);
- }
- }
- }
- if (dyy != 0) {
- yy += (sign * dyy);
- if (yy > 9999 || yy < 0) {
- makestr(&cmdatemsg,"Result year out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- }
- sprintf(datebuf,"%04d%02d%02d %02d:%02d:%02d",yy,mo,dd,hh,mm,ss);
- d1 = mjd(datebuf);
- debug(F111,"cmdelta mjd",datebuf,d1);
-
- t1 = hh * 3600 + mm * 60 + ss; /* Base time to secs since midnight */
- t2 = dhh * 3600 + dmm * 60 + dss; /* Delta time, ditto */
- t3 = t1 + (sign * t2); /* Get sum (or difference) */
-
- d2 = (sign * ddd); /* Delta days */
- d2 += t3 / 86400L;
-
- t4 = t3 % 86400L; /* Fractional part of day */
- if (t4 < 0) { /* If negative */
- d2--; /* one less delta day */
- t4 += 86400L; /* get positive seconds */
- }
- hh = (int) (t4 / 3600L);
- mm = (int) (t4 % 3600L) / 60;
- ss = (int) (t4 % 3600L) % 60;
-
- sprintf(datebuf,"%s %02d:%02d:%02d", mjd2date(d1+d2),hh,mm,ss);
- {
- int len, k, n;
- char * p;
- len = strlen(datebuf);
- k = deltabp - (char *)deltabuf; /* Space used */
- n = DELTABUF - k - 1; /* Space left */
- if (n < len) { /* Not enough? */
- deltabp = deltabuf; /* Wrap around */
- n = DELTABUF;
- }
- ckstrncpy(deltabp,datebuf,n);
- p = deltabp;
- deltabp += len + 1;
- return(p);
- }
-}
-
-
-/* Convert Delta Time to Seconds */
-
-int
-delta2sec(s,result) char * s; long * result; {
- long ddays = 0L, zz;
- int dsign = 1, dhours = 0, dmins = 0, dsecs = 0, units;
- int state = NEED_DAYS;
- char *p, *p2, *p3, c = 0;
- char buf[64];
-
- if (!s) s = "";
- if (!*s)
- return(-1);
- if ((int)strlen(s) > 63)
- return(-1);
- ckstrncpy(buf,s,64);
- p = buf;
-
- if (*p != '+' && *p != '-')
- return(-1);
-
- if (*p++ == '-')
- dsign = -1;
- while (*p == SP) /* Skip intervening spaces */
- p++;
-
- while (state) { /* FSA to parse delta time */
- if (state < 0 || !isdigit(*p))
- return(-1);
- p2 = p; /* Get next numeric field */
- while (isdigit(*p2))
- p2++;
- c = *p2; /* And break character */
- *p2 = NUL; /* Terminate the number */
- switch (state) { /* Interpret according to state */
- case NEED_DAYS: /* Initial */
- if ((c == '-') || /* VMS format */
- ((c == 'd' || c == 'D')
- && !isalpha(*(p2+1)))) { /* Days */
- ddays = atol(p);
- if (!*(p2+1))
- state = 0;
- else /* if anything is left */
- state = NEED_HRS; /* now we want hours. */
- } else if (c == ':') { /* delimiter is colon */
- dhours = atoi(p); /* so it's hours */
- state = NEED_MINS; /* now we want minutes */
- } else if (!c) { /* end of string */
- dhours = atoi(p); /* it's still hours */
- state = 0; /* and we're done */
- } else if (isalpha(c) || c == SP) {
- if (c == SP) { /* It's a keyword? */
- p2++; /* Skip spaces */
- while (*p2 == SP)
- p2++;
- } else { /* or replace first letter */
- *p2 = c;
- }
- p3 = p2; /* p2 points to beginning of keyword */
- while (isalpha(*p3)) /* Find end of keyword */
- p3++;
- c = *p3; /* NUL it out so we can look it up */
- if (*p3) /* p3 points to keyword terminator */
- *p3 = NUL;
- if ((units = lookup(timeunits,p2,nunits,NULL)) < 0)
- return(-1);
- *p2 = NUL; /* Re-terminate the number */
- *p3 = c;
- while (*p3 == SP) /* Point at field after units */
- p3++;
- p2 = p3;
- switch (units) {
- case TU_DAYS:
- ddays = atol(p);
- break;
- default:
- return(-1);
- }
- if (*p2) {
- state = NEED_HRS;
- p2--;
- } else
- state = 0;
- } else { /* Anything else */
- state = -1; /* is an error */
- }
- break;
- case NEED_HRS: /* Looking for hours */
- if (c == ':') {
- dhours = atoi(p);
- state = NEED_MINS;
- } else if (!c) {
- dhours = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_MINS: /* Looking for minutes */
- if (c == ':') {
- dmins = atoi(p);
- state = NEED_SECS;
- } else if (!c) {
- dmins = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_SECS: /* Looking for seconds */
- if (c == '.') {
- dsecs = atoi(p);
- state = NEED_FRAC;
- } else if (!c) {
- dsecs = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_FRAC: /* Fraction of second */
- if (!c && rdigits(p)) {
- if (*p > '4')
- dsecs++;
- state = 0;
- } else {
- state = -1;
- }
- break;
- }
- if (c) /* next field if any */
- p = p2 + 1;
- }
- if (state < 0)
- return(-1);
-
- /* if days > 24854 and sizeof(long) == 32 we overflow */
-
- zz = ddays * 86400L;
- if (zz < 0L) /* This catches it */
- return(-2);
- zz += dhours * 3600L + dmins * 60L + dsecs;
- zz *= dsign;
- *result = zz;
- return(0);
-}
-
-
-char *
-cmcvtdate(s,t) char * s; int t; {
- int x, i, j, k, hh, mm, ss, ff, pmflag = 0, nodate = 0, len, dow;
- int units, isgmt = 0, gmtsign = 0, d = 0, state = 0, nday;
- int kn = 0, ft[8], isletter = 0, f2len = 0;
-
- int zhh = 0; /* Timezone adjustments */
- int zmm = 0;
- int zdd = 0;
-
- int dsign = 1; /* Delta-time adjustments */
- int ddays = 0;
- int dmonths = 0;
- int dyears = 0;
- int dhours = 0;
- int dmins = 0;
- int dsecs = 0;
- int havedelta = 0;
-
- char * fld[8], * p = "", * p2, * p3; /* Assorted buffers and pointers */
- char * s2, * s3;
- char * year = NULL, * month = NULL, * day = NULL;
- char * hour = "00", * min = "00", * sec = "00";
- char datesep = 0;
- char tmpbuf[8];
- char xbuf[DATEBUFLEN+1];
- char ybuf[DATEBUFLEN+1];
- char zbuf[DATEBUFLEN+1];
- char yyyymmdd[YYYYMMDD];
- char dbuf[26];
- char daybuf[3];
- char monbuf[3];
- char yearbuf[5];
- char timbuf[16], *tb, cc;
- char * dp = NULL; /* Result pointer */
-
- if (!s) s = "";
- tmpbuf[0] = NUL;
-
- while (*s == SP) s++; /* Gobble any leading blanks */
- if (isalpha(*s)) /* Remember if 1st char is a letter */
- isletter = 1;
-
- len = strlen(s);
- debug(F110,"cmcvtdate",s,len);
- if (len == 0) { /* No arg - return current date-time */
- dp = ckdate();
- goto xcvtdate;
- }
- if (len > DATEBUFLEN) { /* Check length of arg */
- makestr(&cmdatemsg,"Date-time string too long");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- hh = 0; /* Init time to 00:00:00.0 */
- mm = 0;
- ss = 0;
- ff = 0;
- ztime(&p);
- if (!p)
- p = "";
- if (*p) { /* Init time to current time */
- x = ckstrncpy(dbuf,p,26);
- if (x > 17) {
- hh = atoi(&dbuf[11]);
- mm = atoi(&dbuf[14]);
- ss = atoi(&dbuf[17]);
- }
- }
- ckstrncpy(yyyymmdd,zzndate(),YYYYMMDD); /* Init date to current date */
- ckstrncpy(yearbuf,yyyymmdd,5);
- ckstrncpy(monbuf,&yyyymmdd[4],3);
- ckstrncpy(daybuf,&yyyymmdd[6],3);
- year = yearbuf;
- month = monbuf;
- day = daybuf;
- nday = atoi(daybuf);
- ckstrncpy(xbuf,s,DATEBUFLEN); /* Make a local copy we can poke */
- s = xbuf; /* Point to it */
- s[len] = NUL;
- if (s[0] == ':') {
- p = s;
- goto dotime;
- }
- /* Special preset formats... */
-
- if (len >= 14) { /* FTP MDTM all-numeric date */
- char c;
- c = s[14]; /* e.g. 19980615100045.014 */
- s[14] = NUL;
- x = rdigits(s);
- s[14] = c;
- if (x) {
- ckstrncpy(yyyymmdd,s,8+1);
- year = NULL;
- p = &s[8];
- goto dotime;
- }
- }
- x = 0; /* Becomes > 0 for asctime format */
- if (isalpha(s[0])) {
- if (len == 24) { /* Asctime format? */
- /* Sat Jul 14 15:57:32 2001 */
- x = ckmatch(atp1,s,0,0);
- debug(F111,"cmcvtdate asctime",s,x);
- } else if (len == 28) { /* Or Asctime plus timezone? */
- /* Sat Jul 14 15:15:39 EDT 2001 */
- x = ckmatch(atp2,s,0,0);
- debug(F111,"cmcvtdate asctime+timezone",s,x);
- }
- }
- if (x > 0) { /* Asctime format */
- int xx;
- strncpy(yearbuf,s + len - 4,4);
- yearbuf[4] = NUL;
- for (i = 0; i < 3; i++)
- tmpbuf[i] = s[i+4];
- tmpbuf[3] = NUL;
- if ((xx = lookup(cmonths,tmpbuf,12,NULL)) < 0) {
- makestr(&cmdatemsg,"Invalid month");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- debug(F101,"cmcvtdate asctime month","",xx);
- monbuf[0] = (xx / 10) + '0';
- monbuf[1] = (xx % 10) + '0';
- monbuf[2] = NUL;
- daybuf[0] = (s[8] == ' ' ? '0' : s[8]);
- daybuf[1] = s[9];
- daybuf[2] = NUL;
- xbuf[0] = SP;
- for (i = 11; i < 19; i++)
- xbuf[i-10] = s[i];
- xbuf[9] = NUL;
- ckmakmsg(zbuf,18,yearbuf,monbuf,daybuf,xbuf);
- debug(F110,"cmcvtdate asctime ok",zbuf,0);
- if (len == 24) {
- dp = zbuf;
- goto xcvtdate;
- } else {
- int n;
- n = ckmakmsg(ybuf,DATEBUFLEN-4,zbuf," ",NULL,NULL);
- ybuf[n++] = s[20];
- ybuf[n++] = s[21];
- ybuf[n++] = s[22];
- ybuf[n++] = NUL;
- ckstrncpy(xbuf,ybuf,DATEBUFLEN);
- s = xbuf;
- isletter = 0;
- }
- }
-
-/* Check for day of week */
-
- p = s;
- while (*p == SP) p++;
- dow = -1;
- if (*p) {
- p2 = p;
- cc = NUL;
- while (1) {
- if (*p2 == ',' || *p2 == SP || !*p2) {
- cc = *p2; /* Save break char */
- *p2 = NUL; /* NUL it out */
- p3 = p2; /* Remember this spot */
- if ((dow = lookup(daysofweek,p,7,NULL)) > -1) {
- debug(F111,"cmcvtdate dow",p,dow);
- s = p2;
- if (cc == ',' || cc == SP) { /* Point to next field */
- s++;
- while (*s == SP) s++;
- }
- p = s;
- debug(F111,"cmcvtdate dow new p",p,dow);
- break;
- } else if (isalpha(*p) && cc == ',') {
- makestr(&cmdatemsg,"Unrecognized day of week");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- } else {
- *p3 = cc;
- break;
- }
- }
- p2++;
- }
- }
- len = strlen(s); /* Update length */
- debug(F111,"cmcvtdate s",s,len);
-
- debug(F111,"cmcvtdate dow",s,dow);
- if (dow > -1) { /* Have a day-of-week number */
- long zz; int n, j;
- zz = mjd(zzndate()); /* Get today's MJD */
- debug(F111,"cmcvtdate zz","",zz);
- j = (((int)(zz % 7L)) + 3) % 7; /* Today's day-of-week number */
- debug(F111,"cmcvtdate j","",j);
- hh = 0; /* Init time to midnight */
- mm = 0;
- ss = 0;
- if (j == dow) {
- ckstrncpy(yyyymmdd,zzndate(),YYYYMMDD);
- year = NULL;
- } else {
- n = dow - j; /* Days from now */
- if (dow < j)
- n += 7;
- if (n < 0) n += 7; /* Add to MJD */
- zz += n;
- ckstrncpy(yyyymmdd,mjd2date(zz),YYYYMMDD); /* New date */
- year = NULL;
- }
- debug(F111,"cmcvtdate A",yyyymmdd,len);
- if (len == 0) { /* No more fields after this */
- ckmakmsg(zbuf,18,yyyymmdd," 00:00:00",NULL,NULL);
- dp = zbuf;
- goto xcvtdate;
- }
- isletter = 0;
- if (rdigits(p) && len < 8) /* Next field is time? */
- goto dotime; /* If so go straight to time section */
- if (isdigit(*p)) {
- if (*(p+1) == ':')
- goto dotime;
- else if (isdigit(*(p+1)) && (*(p+2) == ':'))
- goto dotime;
- }
- }
- debug(F111,"cmcvtdate B s",s,dow);
- debug(F111,"cmcvtdate B p",p,dow);
-
- if (*s == '+' || *s == '-') { /* Delta time only - skip ahead. */
- p = s;
- goto delta;
- }
-#ifdef COMMENT
-/*
- What is the purpose of this? It breaks parsing of email dates like
- "Wed, 13 Feb 2002 17:43:02 -0800 (PST)". Removing this code fixes the
- problem and Kermit still passes the 'dates' script.
- - fdc, Sat Nov 26 10:52:45 2005.
-*/
- if (dow > -1) {
- /* Day of week given followed by something that is not a time */
- /* or a delta so it can't be valid */
- makestr(&cmdatemsg,"Invalid tokens after day of week");
- debug(F111,"cmcvtdate fail",cmdatemsg,-1);
- return(NULL);
- }
-#endif /* COMMENT */
-
- /* Handle "today", "yesterday", "tomorrow", and +/- n units */
-
- if (ckstrchr("TtYyNn",s[0])) {
- int i, k, n, minus = 0;
- char c;
- long jd;
- jd = mjd(ckdate());
- debug(F111,"cmcvtdate mjd",s,jd);
-
- /* Symbolic date: TODAY, TOMORROW, etc...? */
-
- s2 = s; /* Find end of keyword */
- i = 0;
- while (isalpha(*s2)) { /* and get its length */
- i++;
- s2++;
- }
- c = *s2; /* Zap but save delimiter */
- *s2 = NUL;
- k = lookup(symdaytab,s,nsymdays,NULL); /* Look up keyword */
- *s2 = c; /* Replace delimiter */
- if (k < 0) /* Keyword not found */
- goto normal;
- s3 = &s[i];
- while (*s3 == SP) /* Skip whitespace */
- s3++;
- if (*s3 == '_' || *s3 == ':')
- s3++;
-
- switch (k) { /* Have keyword */
- case SYM_NOW: /* NOW */
- ckstrncpy(ybuf,ckdate(),DATEBUFLEN);
- ckstrncpy(yyyymmdd,ybuf,YYYYMMDD);
- year = NULL;
- if (*s3) { /* No overwriting current time. */
- ckstrncat(ybuf," ",DATEBUFLEN);
- ckstrncat(ybuf,s3,DATEBUFLEN);
- }
- break;
- default: /* Yesterday, Today, and Tomorrow */
- if (k == SYM_TOMO) { /* TOMORROW */
- strncpy(ybuf,mjd2date(jd+1),8);
- } else if (k == SYM_YEST) { /* YESTERDAY */
- strncpy(ybuf,mjd2date(jd-1),8);
- } else { /* TODAY */
- strncpy(ybuf,ckdate(),8);
- }
- strncpy(ybuf+8," 00:00:00",DATEBUFLEN-8); /* Default time is 0 */
- ckstrncpy(yyyymmdd,ybuf,YYYYMMDD);
- year = NULL;
- if (*s3) { /* If something follows keyword... */
- if (isdigit(*s3)) { /* Time - overwrite default time */
- strncpy(ybuf+8,s+i,DATEBUFLEN-8);
- } else { /* Something else, keep default time */
- ckstrncat(ybuf," ",DATEBUFLEN); /* and append */
- ckstrncat(ybuf,s3,DATEBUFLEN); /* whatever we have */
- }
- }
- }
- s = ybuf; /* Point to rewritten date-time */
- len = strlen(s); /* Update length */
- isletter = 0; /* Cancel this */
- }
-
-/* Regular free-format non-symbolic date */
-
- normal:
-
- debug(F111,"cmcvtdate NORMAL",s,len);
- debug(F111,"cmcvtdate dow",s,dow);
- if (yyyymmdd[0] && !year) {
- ckstrncpy(yearbuf,yyyymmdd,5);
- ckstrncpy(monbuf,&yyyymmdd[4],3);
- ckstrncpy(daybuf,&yyyymmdd[6],3);
- year = yearbuf;
- month = monbuf;
- day = daybuf;
- nday = atoi(daybuf);
- }
- if (isdigit(s[0])) { /* Time without date? */
- p = s;
- if (s[1] == ':') {
- debug(F111,"cmcvtdate NORMAL X1",s,len);
- goto dotime;
- } else if (len > 1 && isdigit(s[1]) && s[2] == ':') {
- debug(F111,"cmcvtdate NORMAL X2",s,len);
- goto dotime;
- } else if (rdigits(s) && len < 8) {
- debug(F111,"cmcvtdate NORMAL X3",s,len);
- goto dotime;
- }
- }
- if (len >= 8 && isdigit(*s)) { /* Check first for yyyymmdd* */
- debug(F111,"cmcvtdate NORMAL A",s,len);
- cc = s[8];
- s[8] = NUL; /* Isolate first 8 characters */
- if (rdigits(s)) {
- /* Have valid time separator? */
- p2 = cc ? ckstrchr(" Tt_-:",cc) : NULL;
- if (!cc || p2) {
- ckstrncpy(yyyymmdd,s,YYYYMMDD); /* Valid separator */
- year = NULL;
- s += 8; /* or time not given */
- if (cc) s++; /* Keep date */
- p = s; /* and go handle time */
- goto dotime;
- } else if (!p2) {
- if (isdigit(cc))
- makestr(&cmdatemsg,"Numeric date too long");
- else
- makestr(&cmdatemsg,"Invalid date-time separator");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- }
- s[8] = cc; /* Put this back! */
- }
- debug(F111,"cmcvtdate NORMAL non-yyyymmdd",s,len);
-
- /* Free-format date -- figure it out */
-
-#ifdef COMMENT
- if (*s && !isdigit(*s)) {
- makestr(&cmdatemsg,"Unrecognized word in date");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
-#endif /* COMMENT */
- for (i = 0; i < 8; i++) /* Field types */
- ft[i] = -1;
- fld[i = 0] = (p = s); /* First field */
- while (*p) { /* Get next two fields */
- if (isdatesep(*p)) { /* Have a date separator */
- if (i == 0) {
- datesep = *p;
- } else if (i == 1 && *p != datesep) {
- makestr(&cmdatemsg,"Inconsistent date separators");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- *p++ = NUL; /* Replace by NUL */
- if (*p) { /* Now we're at the next field */
- while (*p == SP) p++; /* Skip leading spaces */
- if (!*p) break; /* Make sure we still have something */
- if (i == 2) /* Last one? */
- break;
- fld[++i] = p; /* No, record pointer to this one */
- } else {
- break;
- }
- } else if ((*p == 'T' || *p == 't') && isdigit(*(p+1))) { /* Time */
- *p++ = NUL;
- break;
- } else if (*p == ':') {
- if (i == 0 && p == s) {
- nodate = 1;
- break;
- } else if (i != 0) { /* After a date */
- if (i == 2) { /* OK as date-time separator (VMS) */
- *p++ = NUL;
- break;
- }
- if (i < 2)
- makestr(&cmdatemsg,"Too few fields in date");
- else
- makestr(&cmdatemsg,"Misplaced time separator");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- nodate = 1; /* Or without a date */
- break;
- }
- p++;
- }
- if (p > s && i == 0) /* Make sure we have a date */
- nodate = 1; /* No date. */
-
- if (nodate && dow > -1) { /* Have implied date from DOW? */
- goto dotime; /* Use, use that, go do time. */
-
- } else if (nodate) { /* No date and no implied date */
- char *tmp = NULL; /* Substitute today's date */
- ztime(&tmp);
- if (!tmp)
- tmp = "";
- if (!*tmp) {
- makestr(&cmdatemsg,"Problem supplying current date");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- ckstrncpy(dbuf,tmp,26); /* Reformat */
- if (dbuf[8] == SP) dbuf[8] = '0';
- fld[0] = dbuf+8; /* dd */
- dbuf[10] = NUL;
- fld[1] = dbuf+4; /* mmm */
- dbuf[7] = NUL;
- fld[2] = dbuf+20; /* yyyy */
- dbuf[24] = NUL;
- hh = atoi(&dbuf[11]);
- mm = atoi(&dbuf[14]);
- ss = atoi(&dbuf[17]);
- p = s; /* Back up source pointer to reparse */
- } else if (i < 2) {
- makestr(&cmdatemsg,"Too few fields in date");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- /* Have three date fields - see what they are */
-
- for (k = 0, j = 0; j < 3; j++) { /* Get number of non-numeric fields */
- ft[j] = rdigits(fld[j]);
- debug(F111,"cmcvtdate fld",fld[j],j);
- if (ft[j] == 0)
- k++;
- }
- kn = k; /* How many numeric fields */
- month = NULL; /* Strike out default values */
- year = NULL;
- day = NULL;
-
- if (k == 2 && ft[2] > 0) { /* Jul 20, 2001 */
- int xx;
- xx = strlen(fld[1]);
- p3 = fld[1];
- if (xx > 0) if (p3[xx-1] == ',') {
- p3[xx-1] = NUL;
- if (rdigits(p3)) {
- k = 1;
- ft[1] = 1;
- } else p3[xx-1] = ',';
- }
- }
- if (k > 1) { /* We can have only one non-numeric */
- if (nodate)
- makestr(&cmdatemsg,"Unrecognized word in date");
- else if (!ft[2] && isdigit(*(fld[2])))
- makestr(&cmdatemsg,"Invalid date-time separator");
- else
- makestr(&cmdatemsg,"Too many non-numeric fields in date");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- if (!ft[0]) {
- k = 0;
- } else if (!ft[1]) {
- k = 1;
- } else if (!ft[2]) {
- makestr(&cmdatemsg,"Non-digit in third date field");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- } else
- k = -1;
-
- if (k > -1) {
- if ((x = lookup(cmonths,fld[k],12,NULL)) < 0) {
- makestr(&cmdatemsg,"Unknown month");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- sprintf(tmpbuf,"%02d",x);
- month = tmpbuf;
- }
- f2len = strlen(fld[2]); /* Length of 3rd field */
-
- if (k == 0) { /* monthname dd, yyyy */
- day = fld[1];
- year = fld[2];
- } else if (((int)strlen(fld[0]) == 4)) { /* yyyy-xx-dd */
- year = fld[0];
- day = fld[2];
- if (!month)
- month = fld[1]; /* yyyy-mm-dd */
- } else if (f2len == 4) { /* xx-xx-yyyy */
- year = fld[2];
- if (month) { /* dd-name-yyyy */
- day = fld[0];
- } else { /* xx-xx-yyyy */
- int f0, f1;
- f0 = atoi(fld[0]);
- f1 = atoi(fld[1]);
- if (((f0 > 12) && (f1 <= 12)) || (f1 <= 12 && f0 == f1)) {
- day = fld[0]; /* mm-dd-yyyy */
- month = fld[1];
- } else if ((f0 <= 12) && (f1 > 12)) {
- if (!rdigits(fld[1])) {
- makestr(&cmdatemsg,"Day not numeric");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- } else {
- day = fld[1]; /* dd-mm-yyyy */
- }
- month = fld[0];
- } else {
- if (!f0 || !f1)
- makestr(&cmdatemsg,"Day or month out of range");
- else
- makestr(&cmdatemsg,"Day and month are ambiguous");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- }
- } else if ((f2len < 4) && /* dd mmm yy (RFC822) */
- !rdigits(fld[1]) && /* middle field is monthname */
- rdigits(fld[2])) {
- int tmpyear;
- day = fld[0];
- if (!fld[2][1]) {
- makestr(&cmdatemsg,"Too few digits in year");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- tmpyear = atoi(fld[2]);
- if (tmpyear < 50) /* RFC 2822 windowing */
- tmpyear += 2000;
- else /* This includes 3-digit years. */
- tmpyear += 1900;
- year = ckitoa(tmpyear);
-
- } else if ((f2len < 4) && (k < 0) && ((int)strlen(fld[0]) < 4)) {
- makestr(&cmdatemsg,"Ambiguous numeric date");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- } else if ((f2len > 4) && ft[2]) {
- makestr(&cmdatemsg,"Too many digits in year");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- } else {
- makestr(&cmdatemsg,"Unexpected date format");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- x = atoi(month);
- sprintf(tmpbuf,"%02d",x); /* 2-digit numeric month */
-
-/*
- state = 1 = hours
- state = 2 = minutes
- state = 3 = seconds
- state = 4 = fractions of seconds
-*/
-
- dotime:
- if (isletter && (s == p)) {
- makestr(&cmdatemsg,"Unknown date-time word");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- if (!year && yyyymmdd[0]) {
- debug(F110,"cmcvtdate dotime yyyymmdd",yyyymmdd,0);
- for (i = 0; i < 4; i++)
- yearbuf[i] = yyyymmdd[i];
- yearbuf[4] = NUL;
- monbuf[0] = yyyymmdd[4];
- monbuf[1] = yyyymmdd[5];
- monbuf[2] = NUL;
- daybuf[0] = yyyymmdd[6];
- daybuf[1] = yyyymmdd[7];
- daybuf[2] = NUL;
- day = daybuf;
- nday = atoi(daybuf);
- month = monbuf;
- year = yearbuf;
- }
- if (!year) {
- makestr(&cmdatemsg,"Internal error - date not defaulted");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- /* Get here with day, month, and year set */
- debug(F110,"cmcvtdate dotime day",day,0);
- debug(F110,"cmcvtdate dotime month",month,0);
- debug(F110,"cmcvtdate dotime year",year,0);
- debug(F110,"cmcvtdate dotime s",s,0);
- debug(F110,"cmcvtdate dotime p",p,0);
- x = atoi(month);
- if (x > 12 || x < 1) {
- makestr(&cmdatemsg,"Month out of range");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- nday = atoi(day);
- i = mdays[x];
- if (x == 2) if (isleap(atoi(year))) i++;
- if (nday > i || nday < 1) {
- makestr(&cmdatemsg,"Day out of range");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- if (!*p && t == 0) {
- sprintf(zbuf,"%04d%02d%02d",atoi(year),atoi(month),nday);
- dp = zbuf;
- goto xcvtdate;
- }
- if (*p == '+' || *p == '-') { /* GMT offset without a time */
- hh = 0; /* so default time to 00:00:00 */
- mm = 0;
- ss = 0;
- goto cmtimezone; /* and go do timezone */
- }
- if (*p && !isdigit(*p) && *p != ':') {
- makestr(&cmdatemsg,"Invalid time");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- sprintf(yyyymmdd,"%s%s%02d",year,month,nday); /* for tz calculations... */
-
- state = 1; /* Initialize time-parsing FSA */
- hh = 0; /* hours */
- mm = 0; /* minutes */
- ss = 0; /* seconds */
- ff = -1; /* fraction */
- d = 0; /* Digit counter */
- p2 = p; /* Preliminary digit count... */
- while (isdigit(*p2)) {
- d++;
- p2++;
- }
- if (d > 6) {
- makestr(&cmdatemsg,"Too many time digits");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- d = (d & 1 && *p2 != ':') ? 1 : 0; /* Odd implies leading '0' */
-
- while (*p) { /* Get the time, if any */
- if (isdigit(*p)) { /* digit */
- if (d++ > 1) {
- state++;
- d = 1;
- }
- switch (state) {
- case 1: /* Hours */
- hh = hh * 10 + (*p - '0');
- break;
- case 2: /* Minutes */
- mm = mm * 10 + (*p - '0');
- break;
- case 3: /* Seconds */
- ss = ss * 10 + (*p - '0');
- break;
- case 4: /* Fraction of second */
- if (ff < 0)
- ff = (*p > '4') ? 1 : 0;
- break;
- }
- } else if (*p == ':') { /* Colon */
- state++;
- d = 0;
- if (state > 3) {
- makestr(&cmdatemsg,"Too many time fields");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- } else if (*p == '.') {
- if (state == 3) {
- state = 4;
- d = 0;
- } else {
- makestr(&cmdatemsg,"Improper fraction");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- } else if (*p == SP) { /* Space */
- while (*p && (*p == SP)) /* position to first nonspace */
- p++;
- break;
- } else if (isalpha(*p)) { /* AM/PM/Z or timezone */
- break;
- } else if (*p == '+' || *p == '-') { /* GMT offset */
- break;
- } else {
- makestr(&cmdatemsg,"Invalid time characters");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- p++;
- }
- if (!*p) /* If nothing left */
- goto xcmdate; /* go finish up */
-
- /* At this point we have HH, MM, SS, and FF */
- /* Now handle the rest: AM, PM, and/or timezone info */
-
- if (!ckstrcmp(p,"am",2,0)) { /* AM/PM... */
- pmflag = 0;
- p += 2;
- } else if (!ckstrcmp(p,"a.m.",4,0)) {
- pmflag = 0;
- p += 4;
- } else if (!ckstrcmp(p,"pm",2,0)) {
- pmflag = 1;
- p += 2;
- } else if (!ckstrcmp(p,"p.m.",4,0)) {
- pmflag = 1;
- p += 4;
- }
- if (pmflag && hh < 12) /* If PM was given */
- hh += 12; /* add 12 to the hour */
-
- /* Now handle timezone */
-
- cmtimezone:
- debug(F110,"cmcvtdate timezone",p,0);
-
- zhh = 0; /* GMT offset HH */
- zmm = 0; /* GMT offset MM */
- gmtsign = 0; /* Sign of GMT offset */
- isgmt = 0; /* 1 if time is GMT */
-
- while (*p && *p == SP) /* Gobble spaces */
- p++;
- if (!*p) /* If nothing left */
- goto xcmdate; /* we're done */
-
- if (isalpha(*p)) { /* Something left */
- int zone = 0; /* Alphabetic must be timezone */
- p2 = p; /* Isolate timezone */
- p++;
- while (isalpha(*p))
- p++;
- p3 = p;
- cc = *p;
- *p = NUL;
- p = p2; /* Have timezone, look it up */
- zone = lookup(usatz,p,nusatz,NULL);
- debug(F111,"cmcvtdate timezone alpha",p,zone);
-
- if (zone < 0) { /* Not found */
- makestr(&cmdatemsg,"Unknown timezone");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- isgmt++; /* All dates are GMT from here down */
- if (zone != 0) { /* But not this one so make it GMT */
- hh += zone; /* RFC 822 timezone: EST etc */
- debug(F101,"cmcvtdate hh + zone","",hh);
- if (hh > 23) { /* Offset crosses date boundary */
- int i;
- long jd;
- jd = mjd(yyyymmdd); /* Get MJD */
- jd += hh / 24; /* Add new day(s) */
- hh = hh % 24; /* and convert back to yyyymmdd */
- ckstrncpy(yyyymmdd,mjd2date(jd),YYYYMMDD);
- debug(F111,"cmcvtdate zone-adjusted date",yyyymmdd,hh);
- for (i = 0; i < 4; i++)
- yearbuf[i] = yyyymmdd[i];
- yearbuf[4] = NUL;
- monbuf[0] = yyyymmdd[4];
- monbuf[1] = yyyymmdd[5];
- monbuf[2] = NUL;
- daybuf[0] = yyyymmdd[6];
- daybuf[1] = yyyymmdd[7];
- daybuf[2] = NUL;
- day = daybuf;
- nday = atoi(daybuf);
- month = monbuf;
- year = yearbuf;
- }
- }
- p = p3; /* Put back whatever we poked above */
- *p = cc;
-
- } else if (*p == '+' || *p == '-') { /* GMT/UTC offset */
- p3 = p;
- debug(F110,"cmcvtdate timezone GMT offset",p,0);
- gmtsign = (*p == '+') ? -1 : 1;
- isgmt++;
- p++;
- while (*p == SP) p++;
- d = 0;
- p2 = p;
- while (isdigit(*p)) { /* Count digits */
- d++;
- p++;
- }
- if (d != 4) { /* Strict RFC [2]822 */
- isgmt = 0; /* If not exactly 4 digits */
- p = p3; /* it's not a GMT offset. */
- goto delta; /* So treat it as a delta time. */
- }
- d = (d & 1 && *p != ':') ? 1 : 0; /* Odd implies leading '0' */
- p = p2;
- debug(F111,"cmcvtdate GMT offset sign",p,gmtsign);
- debug(F101,"cmcvtdate GMT offset d","",d);
- state = 1;
- while (*p) {
- if (isdigit(*p)) { /* digit */
- if (d++ > 1) {
- state++;
- d = 1;
- }
- switch (state) {
- case 1:
- zhh = zhh * 10 + (*p - '0');
- break;
- case 2:
- zmm = zmm * 10 + (*p - '0');
- break;
- default: /* Ignore seconds or fractions */
- break;
- }
- } else if (*p == ':') { /* Colon */
- state++;
- d = 0;
- } else if (*p == SP || *p == '(') {
- break;
- } else {
- p = p3; /* Maybe it's not a GMT offset. */
- goto delta; /* So treat it as a delta time. */
- }
- p++;
- }
- }
- debug(F110,"cmcvtdate source string after timezone",p,0);
-
- if (*p) { /* Anything left? */
- p2 = p;
- while (*p2 == SP) /* Skip past spaces */
- p2++;
- if (*p2 == '(') { /* RFC-822 comment? */
- int pc = 1; /* paren counter */
- p2++;
- while (*p2) {
- if (*p2 == ')') {
- if (--pc == 0) {
- p2++;
- break;
- }
- } else if (*p2 == ')') {
- pc++;
- }
- p2++;
- }
- while (*p2 == SP) /* Skip past spaces */
- p2++;
- if (!*p2) /* Anything left? */
- *p = NUL; /* No, erase comment */
- }
- if (!*p2) /* Anything left? */
- goto xcmdate; /* No, done. */
- p = p2;
-
- delta:
- debug(F110,"cmcvtdate delta yyyymmdd",yyyymmdd,0);
- debug(F110,"cmcvtdate delta year",year,0);
- debug(F110,"cmcvtdate delta p",p,0);
-
- if (*p == '+' || *p == '-') { /* Delta time */
- int state = NEED_DAYS; /* Start off looking for days */
- char c = 0;
- dsign = 1; /* Get sign */
- if (*p++ == '-')
- dsign = -1;
- while (*p == SP) /* Skip intervening spaces */
- p++;
- while (state) { /* FSA to parse delta time */
- if (state < 0 || !isdigit(*p)) {
- makestr(&cmdatemsg,"Invalid delta time");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- p2 = p; /* Get next numeric field */
- while (isdigit(*p2))
- p2++;
- c = *p2; /* And break character */
- *p2 = NUL; /* Terminate the number */
-
- switch (state) { /* Interpret according to state */
- case NEED_DAYS: /* Initial */
- if ((c == '-') || /* VMS format */
- ((c == 'd' || c == 'D')
- && !isalpha(*(p2+1)))) { /* Days */
- ddays = atoi(p);
- if (!*(p2+1))
- state = 0;
- else /* if anything is left */
- state = NEED_HRS; /* now we want hours. */
- } else if ((c == 'W' || c == 'w') && !isalpha(*(p2+1))) {
- ddays = atoi(p) * 7; /* weeks... */
- if (!*(p2+1))
- state = 0;
- else
- state = NEED_HRS;
- } else if ((c == 'M' || c == 'm') && !isalpha(*(p2+1))) {
- dmonths = atoi(p); /* months... */
- if (!*(p2+1))
- state = 0;
- else
- state = NEED_HRS;
- } else if ((c == 'Y' || c == 'y') && !isalpha(*(p2+1))) {
- dyears = atoi(p); /* years... */
- if (!*(p2+1))
- state = 0;
- else
- state = NEED_HRS;
- } else if (c == ':') { /* delimiter is colon */
- dhours = atoi(p); /* so it's hours */
- state = NEED_MINS; /* now we want minutes */
- } else if (!c) { /* end of string */
- dhours = atoi(p); /* it's still hours */
- state = 0; /* and we're done */
- } else if (isalpha(c) || c == SP) {
- if (c == SP) { /* It's a keyword? */
- p2++; /* Skip spaces */
- while (*p2 == SP)
- p2++;
- } else { /* or replace first letter */
- *p2 = c;
- }
- p3 = p2; /* p2 points to beginning of keyword */
- while (isalpha(*p3)) /* Find end of keyword */
- p3++;
- c = *p3; /* NUL it out so we can look it up */
- if (*p3) /* p3 points to keyword terminator */
- *p3 = NUL;
- units = lookup(timeunits,p2,nunits,NULL);
- if (units < 0) {
- makestr(&cmdatemsg,"Invalid units in delta time");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- *p2 = NUL; /* Re-terminate the number */
- *p3 = c;
- while (*p3 == SP) /* Point at field after units */
- p3++;
- p2 = p3;
- switch (units) {
- case TU_DAYS:
- ddays = atoi(p);
- break;
- case TU_WEEKS:
- ddays = atoi(p) * 7;
- break;
- case TU_MONTHS:
- dmonths = atoi(p);
- break;
- case TU_YEARS:
- dyears = atoi(p);
- break;
- }
- if (*p2) {
- state = NEED_HRS;
- p2--;
- } else
- state = 0;
-
- } else { /* Anything else */
- state = -1; /* is an error */
- }
- break;
- case NEED_HRS: /* Looking for hours */
- debug(F000,"cmcvtdate NEED_HRS",p,c);
- if (c == ':') {
- dhours = atoi(p);
- state = NEED_MINS;
- } else if (!c) {
- dhours = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_MINS: /* Looking for minutes */
- if (c == ':') {
- dmins = atoi(p);
- state = NEED_SECS;
- } else if (!c) {
- dmins = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_SECS: /* Looking for seconds */
- if (c == '.') {
- dsecs = atoi(p);
- state = NEED_FRAC;
- } else if (!c) {
- dsecs = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_FRAC: /* Fraction of second */
- if (!c && rdigits(p)) {
- if (*p > '4')
- dsecs++;
- state = 0;
- } else {
- state = -1;
- }
- break;
- }
- if (c) /* next field if any */
- p = p2 + 1;
- }
- havedelta = 1;
-
- } else {
- makestr(&cmdatemsg,"Extraneous material at end");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- }
-
- xcmdate:
-
- if ((t != 2 && hh > 24) || hh < 0) { /* Hour range check */
- makestr(&cmdatemsg,"Invalid hours");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- if (mm > 59) { /* Minute range check */
- makestr(&cmdatemsg,"Invalid minutes");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- if (ff > 0) { /* Fraction of second? */
- if (ss < 59) {
- ss++;
- ff = 0;
- } else if (mm < 59) {
- ss = 0;
- mm++;
- ff = 0;
- } else if (hh < 24) {
- ss = 0;
- mm = 0;
- hh++;
- ff = 0;
- }
- /* Must add a day -- leave ff at 1... */
- /* (DO SOMETHING ABOUT THIS LATER) */
- }
- if (ss > 60) { /* Seconds range check */
- makestr(&cmdatemsg,"Invalid seconds"); /* 60 is ok because of */
- debug(F111,"cmcvtdate",cmdatemsg,-1); /* Leap Second. */
- return(NULL);
- }
- if ((mm < 0 || ss < 0) ||
- (t != 2 && (ss > 0 || mm > 0) && hh > 23)) {
- makestr(&cmdatemsg,"Invalid minutes or seconds");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- debug(F110,"cmcvtdate year",year,0);
- debug(F110,"cmcvtdate month",month,0);
- debug(F101,"cmcvtdate nday","",nday);
- debug(F101,"cmcvtdate hh","",hh);
- debug(F101,"cmcvtdate mm","",mm);
- debug(F101,"cmcvtdate ss","",ss);
- debug(F101,"cmcvtdate gmtsign","",gmtsign);
- debug(F101,"cmcvtdate zhh","",zhh);
- debug(F101,"cmcvtdate zmm","",zmm);
- debug(F101,"cmcvtdate isgmt","",isgmt);
-
-#ifdef ZLOCALTIME
-/* Handle timezone -- first convert to GMT */
-
- zdd = 0; /* Days changed */
- if (isgmt && (zmm || zhh)) { /* If GMT offset given */
- long sec1, sec2, zz;
- sec1 = ss + 60 * mm + 3600 * hh;
- sec2 = gmtsign * (60 * zmm + 3600 * zhh);
- sec1 += sec2;
- if (sec1 < 0) {
- sec1 = 0 - sec1;
- zdd = 0L - (sec1 / 86400L);
- sec1 = sec1 % 86400L;
- } else if (sec1 > 86400L) {
- zdd = sec1 / 86400L;
- sec1 = sec1 % 86400L;
- }
- ss = sec1 % 60;
- zz = sec1 / 60;
- mm = zz % 60;
- hh = zz / 60;
- debug(F101,"cmcvtdate NEW hh","",hh);
- debug(F101,"cmcvtdate NEW mm","",mm);
- debug(F101,"cmcvtdate NEW dd","",zdd);
-
-/* At this point hh:mm:ss is in GMT and zdd is the calendar adjustment */
-
- }
-#endif /* ZLOCALTIME */
-
- if (yyyymmdd[0] && !year) {
- ckstrncpy(yearbuf,yyyymmdd,5);
- ckstrncpy(monbuf,&yyyymmdd[4],3);
- ckstrncpy(daybuf,&yyyymmdd[6],3);
- year = yearbuf;
- month = monbuf;
- day = daybuf;
- nday = atoi(daybuf);
- }
- sprintf(zbuf,"%04d%02d%02d %02d:%02d:%02d", /* SAFE */
- atoi(year),atoi(month),nday,hh,mm,ss
- );
- dp = zbuf;
-
-#ifdef ZLOCALTIME
- /* Now convert from GMT to local time */
-
- if (isgmt) { /* If GMT convert to local time */
- debug(F110,"cmcvtdate GMT 1",dp,0);
- if (zdd) { /* Apply any calendar adjustment */
- long zz;
- zz = mjd(dp) + zdd;
- sprintf(zbuf,"%s %02d:%02d:%02d",mjd2date(zz),hh,mm,ss);
- }
- debug(F110,"cmcvtdate GMT 2",dp,0);
- if ((p = zlocaltime(dp))) {
- debug(F110,"cmcvtdate asctime zlocaltime",p,0);
- if (p) ckstrncpy(zbuf,p,18);
- }
- debug(F110,"cmcvtdate GMT 3",dp,0);
- for (i = 0; i < 4; i++)
- yearbuf[i] = dp[i];
- yearbuf[4] = NUL;
- monbuf[0] = dp[4];
- monbuf[1] = dp[5];
- monbuf[2] = NUL;
- daybuf[0] = dp[6];
- daybuf[1] = dp[7];
- daybuf[2] = NUL;
- day = daybuf;
- nday = atoi(daybuf);
- month = monbuf;
- year = yearbuf;
- hh = atoi(&dp[9]);
- mm = atoi(&dp[12]);
- ss = atoi(&dp[15]);
- }
-#endif /* ZLOCALTIME */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"cmcvtdate hour","",hh);
- debug(F101,"cmcvtdate minute","",mm);
- debug(F101,"cmcvtdate second","",ss);
- }
-#endif /* DEBLOG */
-
- makestr(&cmdatemsg,NULL);
- if (havedelta) {
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"cmcvtdate base ",dp,0);
- debug(F101,"cmcvtdate delta sign","",dsign);
- debug(F101,"cmcvtdate delta yrs ","",dyears);
- debug(F101,"cmcvtdate delta mos ","",dmonths);
- debug(F101,"cmcvtdate delta days","",ddays);
- debug(F101,"cmcvtdate delta hrs ","",dhours);
- debug(F101,"cmcvtdate delta mins","",dmins);
- debug(F101,"cmcvtdate delta secs","",dsecs);
- }
-#endif /* DEBLOG */
- if (!(dp = cmdelta(atoi(year),
- atoi(month),
- nday, hh, mm, ss,
- dsign, dyears, dmonths, ddays, dhours, dmins, dsecs))) {
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- }
-
- xcvtdate: /* Exit point for success */
- {
- int len, k, n;
- char * p;
- debug(F110,"cmcvtdate xcvtdate dp",dp,0);
- if (!dp) dp = ""; /* Shouldn't happen */
- if (!*dp) return(NULL); /* ... */
- len = strlen(dp);
- debug(F111,"cmcvtdate result",dp,len);
- k = cmdatebp - (char *)cmdatebuf; /* Space used */
- n = CMDATEBUF - k - 1; /* Space left */
- if (n < len) { /* Not enough? */
- cmdatebp = cmdatebuf; /* Wrap around */
- n = CMDATEBUF;
- }
- ckstrncpy(cmdatebp,dp,n);
- p = cmdatebp;
- cmdatebp += len + 1;
- return(p);
- }
-}
-
-int
-cmvdate(d) char * d; { /* Verify date-time */
- int i;
- if (!d) return(0);
- if ((int)strlen(d) != 17) return(0);
- for (i = 0; i < 8; i++) { if (!isdigit(d[i])) return(0); }
- if (!isdigit(d[9]) || !isdigit(d[10]) ||
- !isdigit(d[12]) || !isdigit(d[13]) ||
- !isdigit(d[15]) || !isdigit(d[16]))
- return(0);
- if (!ckstrchr(" Tt_-:",d[8])) return(0);
- if (d[11] != ':' && d[14] != ':') return(0);
- return(1);
-}
-
-/* c m d i f f d a t e -- Get difference between two date-times */
-
-char *
-cmdiffdate(d1,d2) char * d1, * d2; {
- char d1buf[9], d2buf[9];
- char x1buf[18], x2buf[18];
- char * p;
-
- int hh1 = 0, mm1 = 0, ss1 = 0;
- int hh2 = 0, mm2 = 0, ss2 = 0;
- int hh, mm, ss;
- int sign;
- long jd1, jd2, jd, f1, f2, fx;
- static char result[24], *rp;
-
- debug(F110,"cmdiffdate d1 A",d1,0);
- debug(F110,"cmdiffdate d2 A",d2,0);
-
- if (!(p = cmcvtdate(d1,1))) /* Convert dates to standard format */
- return(NULL);
- ckstrncpy(x1buf,p,18);
- d1 = x1buf;
-
- if (!(p = cmcvtdate(d2,1)))
- return(NULL);
- ckstrncpy(x2buf,p,18);
- d2 = x2buf;
-
- debug(F110,"cmdiffdate d1 B",d1,0);
- debug(F110,"cmdiffdate d2 B",d2,0);
- if (!cmvdate(d1) || !cmvdate(d2))
- return(NULL);
-
- hh1 = atoi(&d1[9]); /* Get hours, minutes, and seconds */
- mm1 = atoi(&d1[12]); /* for first date */
- ss1 = atoi(&d1[15]);
- ckstrncpy(d1buf,d1,9);
-
- hh2 = atoi(&d2[9]); /* ditto for second date */
- mm2 = atoi(&d2[12]);
- ss2 = atoi(&d2[15]);
- ckstrncpy(d2buf,d2,9);
-
- jd1 = mjd(d1buf); /* Get the two Julian dates */
- jd2 = mjd(d2buf);
- f1 = ss1 + 60 * mm1 + 3600 * hh1; /* Convert first time to seconds */
-
- f2 = ss2 + 60 * mm2 + 3600 * hh2; /* Ditto for second time */
- debug(F101,"cmdiffdate jd1","",jd1);
- debug(F101,"cmdiffdate f1","",f1);
- debug(F101,"cmdiffdate jd2","",jd2);
- debug(F101,"cmdiffdate f2","",f2);
-
- if (jd2 > jd1 || (jd1 == jd2 && f2 > f1)) {
- sign = -1;
- if (f1 > f2) {jd2--; f2 += 86400L;}
- jd = jd2 - jd1;
- fx = f2 - f1;
- } else {
- sign = 1;
- if (f2 > f1) {jd1--; f1 += 86400L;}
- jd = jd1 - jd2;
- fx = f1 - f2;
- }
- debug(F111,"cmdiffdate sign jd",sign<0?"-":"+",jd);
- debug(F101,"cmdiffdate fx","",fx);
-
- hh = (int) (fx / 3600L); /* Convert seconds to hh:mm:ss */
-
- mm = (int) (fx % 3600L) / 60L;
- ss = (int) (fx % 3600L) % 60L;
-
- rp = result; /* Format the result */
- *rp++ = (sign < 0) ? '-' : '+';
- if (jd != 0 && hh+mm+ss == 0) {
- sprintf(rp,"%ldd",jd);
- } else if (jd == 0) {
- if (ss == 0)
- sprintf(rp,"%d:%02d",hh,mm);
- else
- sprintf(rp,"%d:%02d:%02d",hh,mm,ss);
- } else {
- if (ss == 0)
- sprintf(rp,"%ldd%d:%02d",jd,hh,mm);
- else
- sprintf(rp,"%ldd%d:%02d:%02d",jd,hh,mm,ss);
- }
- debug(F110,"cmdiffdate result",result,0);
- return((char *)result);
-}
-
-#ifndef NOSPL
-/* s h u f f l e d a t e -- Rearrange date string */
-
-/*
- Call with:
- A date string in standard format: yyyymmdd hh:mm:ss (time optional).
- Options:
- 1: Reformat date to yyyy-mmm-dd (mmm = English month abbreviation).
- 2: Reformat date to dd-mmm-yyyy (mmm = English month abbreviation).
- 3: Reformat as numeric yyyymmddhhmmss.
- 4: Reformat in asctime() format Sat Nov 26 11:10:34 2005
- Returns:
- Pointer to result if args valid, otherwise original arg pointer.
-*/
-char *
-shuffledate(p,opt) char * p; int opt; {
- extern char * wkdays[];
- int len;
- char ibuf[32];
- static char obuf[48];
- char c;
- int yy, dd, mm;
-
- if (!p) p = "";
- if (!*p) p = ckdate();
- if (opt < 1 || opt > 4)
- return(p);
- len = strlen(p);
- if (len < 8 || len > 31) return(p);
- if (opt == 4) { /* Asctime format (26 Nov 2005) */
- char c, * s;
- long z; int k;
- ckstrncpy(ibuf,p,31);
- k = len;
- while (k >= 0 && ibuf[k] == CR || ibuf[k] == LF)
- ibuf[k--] = NUL;
- while (k >= 0 && ibuf[k] == SP || ibuf[k] == HT)
- ibuf[k--] = NUL;
- if (k < 9) ckstrncpy(&ibuf[8]," 00:00:00",9);
- p = ibuf;
- z = mjd(p); /* Convert to modified Julian date */
- z = z % 7L;
- if (z < 0) {
- z = 0 - z;
- k = 6 - ((int)z + 3) % 7;
- } else {
- k = ((int)z + 3) % 7; /* Day of week */
- }
- s = wkdays[k];
- obuf[0] = s[0]; /* Day of week */
- obuf[1] = s[1];
- obuf[2] = s[2];
- obuf[3] = SP; /* Space */
- c = p[6];
- p[6] = NUL;
- mm = atoi(&ibuf[4]); /* Month */
- s = moname[mm-1]; /* Name of month */
- p[6] = c;
-
- obuf[4] = s[0]; /* Month */
- obuf[5] = s[1];
- obuf[6] = s[2];
- obuf[7] = SP; /* Space */
- if (p[6] == '0') /* Date of month */
- obuf[8] = SP;
- else
- obuf[8] = p[6];
- obuf[9] = p[7];
- ckstrncpy(&obuf[10],&p[8],10); /* Time */
- obuf[19] = SP; /* Space */
- obuf[20] = p[0]; /* Year */
- obuf[21] = p[1];
- obuf[22] = p[2];
- obuf[23] = p[3];
- obuf[24] = NUL;
- return((char *)obuf);
- }
- if (opt == 3) {
- ckstrncpy(obuf,p,48);
- /* yyyymmdd hh:mm:ss */
- /* 01234567890123456 */
- /* yyyymmddhhmmss */
- obuf[8] = obuf[9];
- obuf[9] = obuf[10];
- obuf[10] = obuf[12];
- obuf[11] = obuf[13];
- obuf[12] = obuf[15];
- obuf[13] = obuf[16];
- obuf[14] = NUL;
- return((char *)obuf);
- }
- ckstrncpy(ibuf,p,32);
- c = ibuf[4]; /* Warning: not Y10K compliant */
- ibuf[4] = NUL;
- if (!rdigits(ibuf))
- return(p);
- yy = atoi(ibuf);
- if (yy < 1 || yy > 9999)
- return(p);
- ibuf[4] = c;
- c = ibuf[6];
- ibuf[6] = NUL;
- if (!rdigits(&ibuf[4]))
- return(p);
- mm = atoi(&ibuf[4]);
- if (mm < 1 || mm > 12)
- return(p);
- ibuf[6] = c;
- c = ibuf[8];
- ibuf[8] = NUL;
- if (!rdigits(&ibuf[6]))
- return(p);
- dd = atoi(&ibuf[6]);
- ibuf[8] = c;
- if (dd < 1 || mm > 31)
- return(p);
- /* IGNORE WARNINGS ABOUT moname[] REFS OUT OF RANGE - it's prechecked. */
- switch (opt) {
- case 1:
- sprintf(obuf,"%04d-%s-%02d%s",yy,moname[mm-1],dd,&ibuf[8]);
- break;
- case 2:
- sprintf(obuf,"%02d-%s-%04d%s",dd,moname[mm-1],yy,&ibuf[8]);
- }
- return((char *)obuf);
-}
-#endif /* NOSPL */
-
-/* C K C V T D A T E -- Like cmcvtdate(), but returns string. */
-/* For use by date-related functions */
-/* See calling conventions for cmcvtdate() above. */
-
-char *
-ckcvtdate(p,t) char * p; int t; {
- char * s;
- if (!(s = cmcvtdate(p,t)))
- return("<BAD_DATE_OR_TIME>"); /* \fblah() error message */
- else
- return(s);
-}
-
-
-/* C M D A T E -- Parse a date and/or time */
-
-/*
- Accepts date in various formats. If the date is recognized,
- this routine returns 0 or greater with the result string pointer
- pointing to a buffer containing the date as "yyyymmdd hh:mm:ss".
-*/
-int
-cmdate(xhlp,xdef,xp,quiet,f) char *xhlp, *xdef, **xp; int quiet; xx_strp f; {
- int x, rc;
- char *o, *s, *zq, *dp;
-
- cmfldflgs = 0;
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
- if (!*xhlp) xhlp = "Date and/or time";
- *xp = "";
-
- rc = cmfld(xhlp,xdef,&s,(xx_strp)0);
- debug(F101,"cmdate cmfld rc","",rc);
- if (rc < 0)
- return(rc);
- debug(F110,"cmdate 1",s,0);
- o = s; /* Remember what they typed. */
- s = brstrip(s);
- debug(F110,"cmdate 2",s,0);
-
- x = 0;
- if (f) { /* If a conversion function is given */
- char * pp;
- zq = atxbuf; /* do the conversion. */
- pp = atxbuf;
- atxn = CMDBL;
- if ((x = (*f)(s,&zq,&atxn)) < 0) return(-2);
- if (!*pp)
- pp = xdef;
- if (setatm(pp,0) < 0) {
- if (!quiet) printf("?Evaluated date too long\n");
- return(-9);
- }
- s = atxbuf;
- }
- dp = cmcvtdate(s,1);
- if (!dp) {
- if (!quiet) printf("?%s\n",cmdatemsg);
- return(-9);
- }
- *xp = dp;
- return(0);
-}
-
-#ifdef CK_RECALL /* Command-recall functions */
-
-/* C M R I N I -- Initialize or change size of command recall buffer */
-
-int
-cmrini(n) int n; {
- int i;
- if (recall && in_recall) { /* Free old storage, if any */
- for (i = 0; i < cm_recall; i++) {
- if (recall[i]) {
- free(recall[i]);
- recall[i] = NULL;
- }
- }
- free(recall);
- recall = NULL;
- }
- cm_recall = n; /* Set new size */
- rlast = current = -1; /* Initialize pointers */
- if (n > 0) {
- recall = (char **)malloc((cm_recall + 1) * sizeof(char *));
- if (!recall)
- return(1);
- for (i = 0; i < cm_recall; i++) {
- recall[i] = NULL;
- }
- in_recall = 1; /* Recall buffers init'd */
- }
- return(0);
-}
-
-/* C M A D D N E X T -- Force addition of next command */
-
-VOID
-cmaddnext() {
- if (on_recall && in_recall) { /* Even if it doesn't come */
- force_add = 1; /* from the keyboard */
- newcmd = 1;
- no_recall = 0;
- }
-}
-
-/* C M G E T C M D -- Find most recent matching command */
-
-char *
-cmgetcmd(s) char * s; {
- int i;
- for (i = current; i >= 0; i--) { /* Search backward thru history list */
- if (!recall[i]) continue; /* This one's null, skip it */
- if (ckmatch(s,recall[i],0,1)) /* Match? */
- return(recall[i]); /* Yes, return pointer */
- }
- return(NULL); /* No match, return NULL pointer */
-}
-#endif /* CK_RECALL */
-
-/* A D D C M D -- Add a command to the recall buffer */
-
-VOID
-addcmd(s) char * s; {
- int len = 0, nq = 0;
- char * p;
-#ifdef CKLEARN
- extern int learning;
-#endif /* CKLEARN */
-
- if (xcmdsrc) /* Only for interactive commands */
- return;
-
- if (!newcmd) /* The command has been here already */
- return; /* so ignore it. */
- newcmd = 0; /* It's new but do this only once. */
-
- if (!s) s = cmdbuf;
- if (s[0])
- len = strlen(s);
-
- if (len < 1) /* Don't save empty commands */
- return;
-
- p = s;
- while (*p) { if (*p++ == '?') nq++; } /* Count question marks */
-
-#ifdef CKLEARN
- if (learning) /* If a learned script is active */
- learncmd(s); /* record this command. */
-#endif /* CKLEARN */
-
- debug(F010,"CMD(P)",s,0); /* Maybe record it in the debug log */
-
-#ifdef CKSYSLOG
- if (ckxlogging) { /* Maybe record it in syslog */
- if (ckxsyslog >= SYSLG_CX || ckxsyslog >= SYSLG_CM)
- cksyslog(SYSLG_CX, 1, "command", s, NULL);
- }
-#endif /* CKSYSLOG */
-
-#ifdef CK_RECALL
- last_recall = 0;
-
- if (on_recall && /* Command recall is on? */
- cm_recall > 0 && /* Recall buffer size is > 0? */
- !no_recall) { /* Not not saving this command? */
-
- if (!force_add && rlast > -1) /* If previous command was identical */
- if (!strcmp(s,recall[rlast])) /* don't add another copy */
- return;
-
- force_add = 0; /* Reset now in case it was set */
-
- if (rlast >= cm_recall - 1) { /* Recall buffer full? */
- int i;
- if (recall[0]) { /* Discard oldest command */
- free(recall[0]);
- recall[0] = NULL;
- }
- for (i = 0; i < rlast; i++) { /* The rest */
- recall[i] = recall[i+1]; /* move back */
- }
- rlast--; /* Now we have one less */
- }
- rlast++; /* Index of last command in buffer */
- current = rlast; /* Also now the current command */
- if (current >= cm_recall) { /* Shouldn't happen */
- printf("?Command history error\n"); /* but if it does */
- on_recall = 0; /* turn off command saving */
-#ifdef COMMENT
- } else if (nq > 0) { /* Have at least one question mark */
- recall[current] = malloc(len+nq+1);
- if (recall[current]) {
- p = recall[current];
- while (*s) {
- if (*s == '?')
- *p++ = '\\';
- *p++ = *s++;
- }
- *p = NUL;
- }
-#endif /* COMMENT */
- } else { /* Normal case, just copy */
- recall[current] = malloc(len+1);
- if (recall[current])
- ckstrncpy(recall[current],s,len+1);
- }
- }
-#endif /* CK_RECALL */
-}
-
-
-#ifdef CK_RECALL
-
-/* C M H I S T O R Y */
-
-VOID
-cmhistory() {
- int i, lc = 1;
- for (i = 0; i <= current; i++) {
- printf(" %s\n", recall[i]);
- if (++lc > (cmd_rows - 2)) { /* Screen full? */
- if (!askmore()) /* Do more-prompting... */
- break;
- else
- lc = 0;
- }
- }
-}
-
-int
-savhistory(s,disp) char *s; int disp; {
- FILE * fp;
- int i;
-
- fp = fopen(s, disp ? "a" : "w");
- if (!fp) {
- perror(s);
- return(0);
- }
- for (i = 0; i <= current; i++)
- fprintf(fp,"%s\n", recall[i]);
- fclose(fp);
- return(1);
-}
-#endif /* CK_RECALL */
-
-#ifdef COMMENT
-/* apparently not used */
-int
-cmgetlc(s) char * s; { /* Get leading char */
- char c;
- while ((c = *s++) <= SP) {
- if (!c)
- break;
- }
- return(c);
-}
-#endif /* COMMENT */
-
-
-/* C M C F M -- Parse command confirmation (end of line) */
-
-/*
- Returns
- -2: User typed anything but whitespace or newline
- -1: Reparse needed
- 0: Confirmation was received
-*/
-int
-cmcfm() {
- int x, xc;
- debug(F101,"cmcfm: cmflgs","",cmflgs);
- debug(F110,"cmcfm: atmbuf",atmbuf,0);
- inword = xc = cc = 0;
-
- setatm("",0); /* (Probably unnecessary) */
-
- while (cmflgs != 1) {
- x = gtword(0);
- xc += cc;
-
- switch (x) {
- case -9:
- printf("Command or field too long\n");
- case -4: /* EOF */
- case -2:
- case -1:
- return(x);
- case 1: /* End of line */
- if (xc > 0) {
- if (xcmfdb) {
- return(-6);
- } else {
- printf("?Not confirmed - %s\n",atmbuf);
- return(-9);
- }
- } else
- break; /* Finish up below */
- case 2: /* ESC */
- if (xc == 0) {
- bleep(BP_WARN);
- continue; /* or fall thru. */
- }
- case 0: /* Space */
- if (xc == 0) /* If no chars typed, continue, */
- continue; /* else fall thru. */
- /* else fall thru... */
-
- case 3: /* Question mark */
- if (xc > 0) {
- if (xcmfdb) {
- return(-6);
- } else {
- printf("?Not confirmed - %s\n",atmbuf);
- return(-9);
- }
- }
- printf(
- "\n Press the Return or Enter key to confirm the command\n");
- printf("%s%s",cmprom,cmdbuf);
- fflush(stdout);
- continue;
- }
- }
- debok = 1;
- return(0);
-}
-
-
-/* The following material supports chained parsing functions. */
-/* See ckucmd.h for FDB and OFDB definitions. */
-
-struct OFDB cmresult = { /* Universal cmfdb result holder */
- NULL, /* Address of succeeding FDB struct */
- 0, /* Function code */
- NULL, /* String result */
- 0, /* Integer result */
- (CK_OFF_T)0 /* Wide result */
-};
-
-VOID
-cmfdbi(p,fc,s1,s2,s3,n1,n2,f,k,nxt) /* Initialize an FDB */
- struct FDB * p;
- int fc;
- char * s1, * s2, * s3;
- int n1, n2;
- xx_strp f;
- struct keytab * k;
- struct FDB * nxt; {
-
- p->fcode = fc;
- p->hlpmsg = s1;
- p->dflt = s2;
- p->sdata = s3;
- p->ndata1 = n1;
- p->ndata2 = n2;
- p->spf = f;
- p->kwdtbl = k;
- p->nxtfdb = nxt;
-}
-
-/* C M F D B -- Parse a field with several possible functions */
-
-int
-cmfdb(fdbin) struct FDB * fdbin; {
-#ifndef NOSPL
- extern int x_ifnum; /* IF NUMERIC - disables warnings */
-#endif /* NOSPL */
- struct FDB * in = fdbin;
- struct OFDB * out = &cmresult;
- int x = 0, n, r;
- CK_OFF_T w = (CK_OFF_T)0;
- char *s, *xp, *m = NULL;
- int errbits = 0;
-
- xp = bp;
-
- out->fcode = -1; /* Initialize output struct */
- out->fdbaddr = NULL;
- out->sresult = NULL;
- out->nresult = 0;
-/*
- Currently we make one trip through the FDBs. So if the user types Esc or
- Tab at the beginning of a field, only the first FDB is examined for a
- default. If the user types ?, help is given only for one FDB. We should
- search through the FDBs for all matching possibilities -- and in particular
- display the pertinent context-sensitive help for each function, rather than
- the only the first one that works, and then rewind the FDB pointer so we
- are not locked out of the earlier ones.
-*/
- cmfldflgs = 0;
- while (1) { /* Loop through the chain of FDBs */
- nomsg = 1;
- xcmfdb = 1;
- s = NULL;
- n = 0;
- debug(F101,"cmfdb in->fcode","",in->fcode);
- switch (in->fcode) { /* Current parsing function code */
- case _CMNUM:
- r = in->ndata1;
- if (r != 10 && r != 8) r = 10;
-#ifndef NOSPL
- x_ifnum = 1; /* Disables warning messages */
-#endif /* NOSPL */
- x = cmnum(in->hlpmsg,in->dflt,r,&n,in->spf);
-#ifndef NOSPL
- x_ifnum = 0;
-#endif /* NOSPL */
- debug(F101,"cmfdb cmnum","",x);
- if (x < 0) errbits |= 1;
- break;
- case _CMNUW: /* Wide cmnum - 24 Dec 2005 */
- r = in->ndata1;
- if (r != 10 && r != 8) r = 10;
-#ifndef NOSPL
- x_ifnum = 1; /* Disables warning messages */
-#endif /* NOSPL */
- x = cmnumw(in->hlpmsg,in->dflt,r,&w,in->spf);
-#ifndef NOSPL
- x_ifnum = 0;
-#endif /* NOSPL */
- debug(F101,"cmfdb cmnumw","",w);
- if (x < 0) errbits |= 1;
- break;
- case _CMOFI:
- x = cmofi(in->hlpmsg,in->dflt,&s,in->spf);
- debug(F101,"cmfdb cmofi","",x);
- if (x < 0) errbits |= 2;
- break;
- case _CMIFI:
- x = cmifi2(in->hlpmsg,
- in->dflt,
- &s,
- &n,
- in->ndata1,
- in->sdata,
- in->spf,
- in->ndata2
- );
- debug(F101,"cmfdb cmifi2 x","",x);
- debug(F101,"cmfdb cmifi2 n","",n);
- if (x < 0) errbits |= 4;
- break;
- case _CMFLD:
- cmfldflgs = in->ndata1;
- x = cmfld(in->hlpmsg,in->dflt,&s,in->spf);
- debug(F101,"cmfdb cmfld","",x);
- if (x < 0) errbits |= 8;
- break;
- case _CMTXT:
- x = cmtxt(in->hlpmsg,in->dflt,&s,in->spf);
- debug(F101,"cmfdb cmtxt","",x);
- if (x < 0) errbits |= 16;
- break;
- case _CMKEY:
- x = cmkey2(in->kwdtbl,
- in->ndata1,
- in->hlpmsg,in->dflt,in->sdata,in->spf,in->ndata2);
- debug(F101,"cmfdb cmkey","",x);
- if (x < 0) errbits |= ((in->ndata2 & 4) ? 32 : 64);
- break;
- case _CMCFM:
- x = cmcfm();
- debug(F101,"cmfdb cmcfm","",x);
- if (x < 0) errbits |= 128;
- break;
- default:
- debug(F101,"cmfdb - unexpected function code","",in->fcode);
- printf("?cmfdb - unexpected function code: %d\n",in->fcode);
- }
- debug(F101,"cmfdb x","",x);
- debug(F101,"cmfdb cmflgs","",cmflgs);
- debug(F101,"cmfdb crflag","",crflag);
- debug(F101,"cmfdb qmflag","",qmflag);
- debug(F101,"cmfdb esflag","",esflag);
-
- if (x > -1) { /* Success */
- out->fcode = in->fcode; /* Fill in output struct */
- out->fdbaddr = in;
- out->sresult = s;
- out->nresult = (in->fcode == _CMKEY) ? x : n;
- out->wresult = w;
- out->kflags = (in->fcode == _CMKEY) ? cmkwflgs : 0;
- debug(F111,"cmfdb out->nresult",out->sresult,out->nresult);
- debug(F111,"cmfdb out->wresult",out->sresult,out->wresult);
- nomsg = 0;
- xcmfdb = 0;
- /* debug(F111,"cmfdb cmdbuf & crflag",cmdbuf,crflag); */
- if (crflag) {
- cmflgs = 1;
- }
- return(x); /* and return */
- }
- in = in->nxtfdb; /* Failed, get next parsing function */
- nomsg = 0;
- xcmfdb = 0;
- if (!in) { /* No more */
- debug(F101,"cmfdb failure x","",x);
- debug(F101,"cmfdb failure errbits","",errbits);
- if (x == -6)
- x = -9;
- if (x == -9) {
-#ifdef CKROOT
- if (ckrooterr)
- m = "Off Limits";
- else
-#endif /* CKROOT */
- /* Make informative messages for a few common cases */
- switch (errbits) {
- case 4+32: m = "Does not match filename or switch"; break;
- case 4+64: m = "Does not match filename or keyword"; break;
- case 1+32: m = "Not a number or valid keyword"; break;
- case 1+64: m = "Not a number or valid switch"; break;
- default: m = "Not valid in this position";
- }
- printf("?%s: \"%s\"\n",m, atmbuf);
- }
- return(x);
- }
- if (x != -2 && x != -6 && x != -9 && x != -3) /* Editing or somesuch */
- return(x); /* Go back and reparse */
- pp = np = bp = xp; /* Back up pointers */
- cmflgs = -1; /* Force a reparse */
-
-#ifndef NOSPL
- if (!askflag) { /* If not executing ASK-class cmd... */
-#endif /* NOSPL */
- if (crflag) { /* If CR was typed, put it back */
- pushc = LF; /* But as a linefeed */
- } else if (qmflag) { /* Ditto for Question mark */
- pushc = '?';
- } else if (esflag) { /* and Escape or Tab */
- pushc = ESC;
- }
-#ifndef NOSPL
- }
-#endif /* NOSPL */
- }
-}
-
-/*
- C M I O F I -- Parse an input file OR the name of a nonexistent file.
-
- Replaces the commented-out version above. This one actually works and
- has the expected straightforward interface.
-*/
-int
-cmiofi(xhlp,xdef,xp,wild,f) char *xhlp, *xdef, **xp; int *wild; xx_strp f; {
- int x;
- struct FDB f1, f2;
- cmfdbi(&f1,_CMIFI,xhlp,xdef,"",0,0,f,NULL,&f2);
- cmfdbi(&f2,_CMOFI,"","","",0,0,f,NULL,NULL);
- x = cmfdb(&f1);
- if (x < 0) {
- if (x == -3) {
- x = -9;
- printf("?Filename required\n");
- }
- }
- *wild = cmresult.nresult;
- *xp = cmresult.sresult;
- return(x);
-}
-
-/* G T W O R D -- Gets a "word" from the command input stream */
-
-/*
-Usage: retcode = gtword(brk);
- brk = 0 for normal word breaks (space, CR, Esc, ?)
- brk = 1 to add ':' and '=' (for parsing switches). These characters
- act as break characters only if the first character of the field
- is slash ('/'), i.e. switch introducer.
- brk = 4 to not strip comments (used only for "help #" and "help ;").
-
-Returns:
--10 Timelimit set and timed out
- -9 if input was too long
- -4 if end of file (e.g. pipe broken)
- -3 if null field
- -2 if command buffer overflows
- -1 if user did some deleting
- 0 if word terminates with SP or tab
- 1 if ... CR
- 2 if ... ESC
- 3 if ... ? (question mark)
- 4 if ... : or = and called with brk != 0
-
-With:
- pp pointing to beginning of word in buffer
- bp pointing to after current position
- atmbuf containing a copy of the word
- cc containing the number of characters in the word copied to atmbuf
-*/
-
-int
-ungword() { /* Unget a word */
- debug(F101,"ungword cmflgs","",cmflgs);
- if (ungw) return(0);
- cmfsav = cmflgs;
- ungw = 1;
- cmflgs = 0;
- return(0);
-}
-
-/* Un-un-get word. Undo ungword() if it has been done. */
-
-VOID
-unungw() {
- debug(F010,"unungw atmbuf",atmbuf,0);
- if (ungw) {
- ungw = 0;
- cmflgs = cmfsav;
- atmbuf[0] = NUL;
- }
-}
-
-static int
-gtword(brk) int brk; {
- int c; /* Current char */
- int quote = 0; /* Flag for quote character */
- int echof = 0; /* Flag for whether to echo */
- int comment = 0; /* Flag for in comment */
- char *cp = NULL; /* Comment pointer */
- int eintr = 0; /* Flag for syscall interrupted */
- int bracelvl = 0; /* nested brace counter [jrs] */
- int iscontd = 0; /* Flag for continuation */
- int realtty = 0; /* Stdin is really a tty */
- char firstnb = NUL;
- char lastchar = NUL;
- char prevchar = NUL;
- char lbrace, rbrace;
- int dq = 0; /* Doublequote flag */
- int dqn = 0; /* and count */
- int isesc = 0;
-
-#ifdef RTU
- extern int rtu_bug;
-#endif /* RTU */
-
-#ifdef IKSD
- extern int inserver;
-#endif /* IKSD */
- extern int kstartactive;
-
-#ifdef datageneral
- extern int termtype; /* DG terminal type flag */
- extern int con_reads_mt; /* Console read asynch is active */
- if (con_reads_mt) connoi_mt(); /* Task would interfere w/cons read */
-#endif /* datageneral */
-
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"gtword brk","",brk);
- debug(F101,"gtword cmfldflgs","",cmfldflgs);
- debug(F101,"gtword swarg","",swarg);
- debug(F101,"gtword dpx","",dpx);
- debug(F101,"gtword echof","",echof);
-#ifndef NOSPL
- debug(F101,"gtword askflag","",askflag);
- debug(F101,"gtword timelimit","",timelimit);
-#ifndef NOLOCAL
-#ifndef NOXFER
-#ifdef CK_AUTODL
- debug(F101,"gtword cmdadl","",cmdadl);
-#endif /* CK_AUTODL */
-#endif /* NOXFER */
-#endif /* NOLOCAL */
-#endif /* NOSPL */
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
-
- realtty = is_a_tty(0); /* Stdin is really a tty? */
-
- if (cmfldflgs & 1) {
- lbrace = '(';
- rbrace = ')';
- } else {
- lbrace = '{';
- rbrace = '}';
- }
- crflag = 0;
- qmflag = 0;
- esflag = 0;
-
- if (swarg) { /* No leading space for switch args */
- inword = 1;
- swarg = 0;
- }
- if (ungw) { /* Have a word saved? */
-#ifdef M_UNGW
- /* Experimental code to allow ungetting multiple words. */
- /* See comments in ckmkey2() above. */
- int x;
- if (np > pp) pp = np;
- while (*pp == SP) pp++;
- if (!*pp) {
- ungw = 0;
- cmflgs = cmfsav;
- } else {
- if ((x = setatm(pp,2)) < 0) {
- printf("?Saved word too long\n");
- return(-9);
- }
- if (pp[x] >= SP) {
- char *p2;
- p2 = pp;
- p2 += x;
- while (*p2 == SP) p2++;
- if (*p2) {
- np = p2;
- ungword();
- }
- } else {
- ungw = 0;
- cmflgs = cmfsav;
- debug(F010,"gtword ungw return atmbuf",atmbuf,0);
- }
- }
- return(cmflgs);
-#else
- /*
- You would think the following should be:
- while (*pp == SP) pp++;
- but you would be wrong -- making this change breaks GOTO.
- */
- while (*pp++ == SP) ;
- if (setatm(pp,2) < 0) {
- printf("?Saved word too long\n");
- return(-9);
- }
- ungw = 0;
- cmflgs = cmfsav;
- debug(F010,"gtword ungw return atmbuf",atmbuf,0);
- return(cmflgs);
-#endif /* M_UNGW */
- }
- pp = np; /* Start of current field */
-
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"gtword cmdbuf",cmdbuf,0);
- debug(F110,"gtword bp",bp,0);
- debug(F110,"gtword pp",pp,0);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- {
- /* If we are reparsing we have to recount any braces or doublequotes */
- char * p = pp;
- char c;
- if (*p == '"')
- dq++;
- while ((c = *p++))
- if (c == lbrace)
- bracelvl++;
- else if (c == rbrace)
- bracelvl--;
- else if (dq && c == '"')
- dqn++;
- }
- while (bp < cmdbuf+CMDBL) { /* Big get-a-character loop */
- echof = 0; /* Assume we don't echo because */
- chsrc = 0; /* character came from reparse buf. */
-#ifdef BS_DIRSEP
-CMDIRPARSE:
-#endif /* BS_DIRSEP */
-
- c = *bp;
- if (!c) { /* If no char waiting in reparse buf */
- if ((dpx
-#ifndef NOSPL
- || echostars
-#endif /* NOSPL */
- ) && (!pushc
-#ifndef NOSPL
- || askflag
-#endif /* NOSPL */
- )) /* Get from tty, set echo flag */
- echof = 1;
- c = cmdgetc(timelimit); /* Read a command character. */
-#ifdef DEBUG
- debug(F101,"gtword c","",c);
-#endif /* DEBUG */
-
- if (timelimit && c < -1) { /* Timed out */
- return(-10);
- }
-
-#ifndef NOXFER
-/*
- The following allows packet recognition in the command parser.
- Presently it works only for Kermit packets, and if our current protocol
- happens to be anything besides Kermit, we simply force it to Kermit.
- We don't use the APC mechanism here for mechanical reasons, and also
- because this way, it works even with minimally configured interactive
- versions. Add Zmodem later...
-*/
-#ifdef CK_AUTODL
- if ((!local && cmdadl) /* Autodownload enabled? */
-#ifdef IKS_OPTION
- || TELOPT_SB(TELOPT_KERMIT).kermit.me_start
-#endif /* IKS_OPTION */
- ) {
- int k;
- k = kstart((CHAR)c); /* Kermit S or I packet? */
- if (k) {
- int ksign = 0;
- if (k < 0) { /* Minus-Protocol? */
-#ifdef NOSERVER
- goto noserver; /* Need server mode for this */
-#else
- ksign = 1; /* Remember */
- k = 0 - k; /* Convert to actual protocol */
- justone = 1; /* Flag for protocol module */
-#endif /* NOSERVER */
- } else
- justone = 0;
- k--; /* Adjust kstart's return value */
- if (k == PROTO_K) {
- extern int protocol, g_proto;
- extern CHAR sstate;
- g_proto = protocol;
- protocol = PROTO_K; /* Crude... */
- sstate = ksign ? 'x' : 'v';
- cmdbuf[0] = NUL;
- return(-3);
- }
- }
- }
-#ifdef NOSERVER
- noserver:
-#endif /* NOSERVER */
-#endif /* CK_AUTODL */
-#endif /* NOXFER */
-
- chsrc = 1; /* Remember character source is tty. */
- brkchar = c;
-
-#ifdef IKSD
- if (inserver && c < 0) { /* End of session? */
- debug(F111,"gtword c < 0","exiting",c);
- return(-4); /* Cleanup and terminate */
- }
-#endif /* IKSD */
-
-#ifdef OS2
- if (c < 0) { /* Error */
- if (c == -3) { /* Empty word? */
- if (blocklvl > 0) /* In a block */
- continue; /* so keep looking for block end */
- else
- return(-3); /* Otherwise say we got nothing */
- } else { /* Not empty word */
- return(-4); /* So some kind of i/o error */
- }
- }
-#else
-#ifdef MAC
- if (c == -3) /* Empty word... */
- if (blocklvl > 0)
- continue;
- else
- return(-3);
-#endif /* MAC */
-#endif /* OS2 */
- if (c == EOF) { /* This can happen if stdin not tty. */
-#ifdef EINTR
-/*
- Some operating and/or C runtime systems return EINTR for no good reason,
- when the end of the standard input "file" is encountered. In cases like
- this, we get into an infinite loop; hence the eintr counter, which is reset
- to 0 upon each call to this routine.
-*/
- debug(F101,"gtword EOF","",errno);
- if (errno == EINTR && ++eintr < 4) /* When bg'd process is */
- continue; /* fg'd again. */
-#endif /* EINTR */
- return(-4);
- }
- c &= cmdmsk; /* Strip any parity bit */
- } /* if desired. */
-
-/* Now we have the next character */
-
- isesc = (c == ESC); /* A real ESC? */
-
- if (!firstnb && c > SP) { /* First nonblank */
- firstnb = c;
- if (c == '"') /* Starts with doublequote */
- dq = 1;
- }
- if (c == '"') /* Count doublequotes */
- dqn++;
-
- if (quote && (c == CR || c == LF)) { /* Enter key following quote */
- *bp++ = CMDQ; /* Double it */
- *bp = NUL;
- quote = 0;
- }
- if (quote == 0) { /* If this is not a quoted character */
- switch (c) {
- case CMDQ: /* Got the quote character itself */
- if (!comment && quoting)
- quote = 1; /* Flag it if not in a comment */
- break;
- case FF: /* Formfeed. */
- c = NL; /* Replace with newline */
- cmdclrscn(); /* Clear the screen */
- break;
- case HT: /* Horizontal Tab */
- if (comment) /* If in comment, */
- c = SP; /* substitute space */
- else /* otherwise */
- c = ESC; /* substitute ESC (for completion) */
- break;
- case ';': /* Trailing comment */
- case '#':
- if (! (brk & 4) ) { /* If not keeping comments */
- if (inword == 0 && quoting) { /* If not in a word */
- comment = 1; /* start a comment. */
- cp = bp; /* remember where it starts. */
- }
- }
- break;
- }
- if (!kstartactive && /* Not in possible Kermit packet */
- !comment && c == SP) { /* Space not in comment */
- *bp++ = (char) c; /* deposit in buffer if not already */
- /* debug(F101,"gtword echof 2","",echof); */
-#ifdef BEBOX
- if (echof) {
- cmdecho((char) c, 0); /* Echo what was typed. */
- fflush(stdout);
- fflush(stderr);
- }
-#else
- if (echof) {
- cmdecho((char) c, 0); /* Echo what was typed. */
- if (timelimit)
- fflush(stdout);
- }
-#endif /* BEBOX */
- if (inword == 0) { /* If leading, gobble it. */
- pp++;
- continue;
- } else { /* If terminating, return. */
- if ((!dq && ((*pp != lbrace) || (bracelvl == 0))) ||
- (dq && dqn > 1 && *(bp-2) == '"')) {
- np = bp;
- cmbptr = np;
- if (setatm(pp,0) < 0) {
- printf("?Field too long error 1\n");
- debug(F111,"gtword too long #1",pp,strlen(pp));
- return(-9);
- }
- brkchar = c;
- inword = cmflgs = 0;
- return(0);
- }
- continue;
- }
- }
- if (c == lbrace) {
- bracelvl++;
- /* debug(F101,"gtword bracelvl++","",bracelvl); */
- }
- if (c == rbrace && bracelvl > 0) {
- bracelvl--;
- /* debug(F101,"gtword bracelvl--","",bracelvl); */
- if (linebegin)
- blocklvl--;
- }
- if ((c == '=' || c == ':') &&
- /* ^^^ */
- !kstartactive && !comment && brk /* && (firstnb == '/') */
- ) {
- *bp++ = (char) c; /* Switch argument separator */
- /* debug(F111,"gtword switch argsep",cmdbuf,brk); */
-#ifdef BEBOX
- if (echof) {
- cmdecho((char) c, 0); /* Echo what was typed. */
- fflush(stdout);
- fflush(stderr);
- }
-#else
- if (echof) {
- cmdecho((char) c, 0); /* Echo what was typed. */
- if (timelimit)
- fflush(stdout);
- }
-#endif /* BEBOX */
- if ((*pp != lbrace) || (bracelvl == 0)) {
- np = bp;
- cmbptr = np;
- if (setatm(pp,2) < 0) { /* ^^^ */
- printf("?Field too long error 1\n");
- debug(F111,"gtword too long #1",pp,strlen(pp));
- return(-9);
- }
- inword = cmflgs = 0;
- brkchar = c;
- return(4);
- }
- }
- if (c == LF || c == CR) { /* CR or LF. */
- if (echof) {
- cmdnewl((char)c); /* echo it. */
-#ifdef BEBOX
- fflush(stdout);
- fflush(stderr);
-#endif /* BEBOX */
- }
- {
- /* Trim trailing comment and whitespace */
- char *qq;
- if (comment) { /* Erase comment */
- while (bp >= cp) /* Back to comment pointer */
- *bp-- = NUL;
- bp++;
- pp = bp; /* Adjust other pointers */
- inword = 0; /* and flags */
- comment = 0;
- cp = NULL;
- }
- qq = inword ? pp : (char *)cmdbuf;
- /* Erase trailing whitespace */
- while (bp > qq && (*(bp-1) == SP || *(bp-1) == HT)) {
- bp--;
- /* debug(F000,"erasing","",*bp); */
- *bp = NUL;
- }
- lastchar = (bp > qq) ? *(bp-1) : NUL;
- prevchar = (bp > qq+1) ? *(bp-2) : NUL;
- }
- if (linebegin && blocklvl > 0) /* Blank line in {...} block */
- continue;
-
- linebegin = 1; /* At beginning of next line */
- iscontd = prevchar != CMDQ &&
- (lastchar == '-' || lastchar == lbrace);
- debug(F101,"gtword iscontd","",iscontd);
-
- if (iscontd) { /* If line is continued... */
- if (chsrc) { /* If reading from tty, */
- if (*(bp-1) == lbrace) { /* Check for "begin block" */
- *bp++ = SP; /* Insert a space for neatness */
- blocklvl++; /* Count block nesting level */
- } else { /* Or hyphen */
- bp--; /* Overwrite the hyphen */
- }
- *bp = NUL; /* erase the dash, */
- continue; /* and go back for next char now. */
- }
- } else if (blocklvl > 0) { /* No continuation character */
- if (chsrc) { /* But we're in a "block" */
- *bp++ = ','; /* Add comma */
- *bp = NUL;
- continue;
- }
- } else { /* No continuation, end of command. */
- *bp = NUL; /* Terminate the command string. */
- if (comment) { /* If we're in a comment, */
- comment = 0; /* Say we're not any more, */
- *cp = NUL; /* cut it off. */
- }
- np = bp; /* Where to start next field. */
- cmbptr = np;
- if (setatm(pp,0) < 0) { /* Copy field to atom buffer */
- debug(F111,"gtword too long #2",pp,strlen(pp));
- printf("?Field too long error 2\n");
- return(-9);
- }
- inword = 0; /* Not in a word any more. */
- crflag = 1;
- /* debug(F110,"gtword","crflag is set",0); */
-#ifdef CK_RECALL
- current = rlast;
-#endif /* CK_RECALL */
- cmflgs = 1;
- if (!xcmdsrc
-#ifdef CK_RECALL
- || force_add
-#endif /* CK_RECALL */
- )
- addcmd(cmdbuf);
- return(cmflgs);
- }
- }
-/*
- This section handles interactive help, completion, editing, and history.
- Rearranged as a switch statement executed only if we're at top level since
- there is no need for any of this within command files and macros: Aug 2000.
- Jun 2001: Even if at top level, skip this if the character was fetched from
- the reparse or recall buffer, or if stdin is redirected.
-*/
- if ((xcmdsrc == 0 /* Only at top level */
-#ifndef NOSPL
- || askflag /* or user is typing ASK response */
-#endif /* NOSPL */
- ) && chsrc != 0 && realtty) { /* from the real keyboard */
-
-/* Use ANSI / VT100 up and down arrow keys for command recall. */
-
- if (isesc && (
-#ifdef IKSD
- inserver
-#else
- 0
-#endif /* IKSD */
-#ifdef USE_ARROWKEYS
- || 1
-#endif /* USE_ARROWKEYS */
- )
- ) { /* A real ESC was typed */
- int x;
- msleep(200); /* Wait 1/5 sec */
- x = cmdconchk(); /* Was it followed by anything? */
- debug(F101,"Arrowkey ESC cmdconchk","",x);
-
- if (x > 1) { /* If followed by at least 2 chars */
- int c2;
- c2 = cmdgetc(0); /* Get the first one */
- debug(F101,"Arrowkey ESC c2","",c2);
-
- if (c2 != '[' && c2 != 'O') { /* If not [ or O */
- pushc = c2; /* Push it and take the ESC solo */
- } else {
- c2 = cmdgetc(0); /* Get the second one */
- debug(F101,"Arrowkey ESC c3","",c2);
- switch (c2) {
-#ifndef NORECALL
- case 'A': /* Up */
- c = BEL;
- c = C_UP;
- break;
- case 'B': /* Down */
- c = BEL;
- c = C_DN;
- break;
- case 'C': /* Right */
- case 'D': /* Left */
-#else
- default:
-#endif /* NORECALL */
- c = BEL; /* We don't use these yet */
- break;
- }
- }
- }
- }
-
- switch (c) {
- case '?': /* ?-Help */
-#ifndef NOSPL
- if (askflag) /* No help in ASK response */
- break;
-#endif /* NOSPL */
- if (quoting
- && !kstartactive
- && !comment
- ) {
- cmdecho((char) c, 0);
- *bp = NUL;
- if (setatm(pp,0) < 0) {
- debug(F111,"gtword too long ?",pp,strlen(pp));
- printf("?Too long\n");
- return(-9);
- }
- qmflag = 1;
- return(cmflgs = 3);
- }
-
- case ESC: /* Esc or Tab completion */
- if (!comment) {
- *bp = NUL;
- if (setatm(pp,0) < 0) {
- debug(F111,"gtword too long Esc",pp,strlen(pp));
- printf("?Too long\n");
- return(-9);
- }
- esflag = 1;
- return(cmflgs = 2);
- } else {
- bleep(BP_WARN);
- continue;
- }
-
- case BS: /* Character deletion */
- case RUB:
- if (bp > cmdbuf) { /* If still in buffer... */
- cmdchardel(); /* erase it. */
- bp--; /* point behind it, */
- if (*bp == lbrace) bracelvl--; /* Adjust brace count */
- if (*bp == rbrace) bracelvl++;
- if ((*bp == SP) && /* Flag if current field gone */
- (*pp != lbrace || bracelvl == 0))
- inword = 0;
- *bp = NUL; /* Erase character from buffer. */
- } else { /* Otherwise, */
- bleep(BP_WARN);
- cmres(); /* and start parsing a new command. */
- *bp = *atmbuf = NUL;
- }
- if (pp < bp)
- continue;
- else
- return(cmflgs = -1);
-
- case LDEL: /* ^U, line deletion */
- while ((bp--) > cmdbuf) {
- cmdchardel();
- *bp = NUL;
- }
- cmres(); /* Restart the command. */
- *bp = *atmbuf = NUL;
- inword = 0;
- return(cmflgs = -1);
-
- case WDEL: /* ^W, word deletion */
- if (bp <= cmdbuf) { /* Beep if nothing to delete */
- bleep(BP_WARN);
- cmres();
- *bp = *atmbuf = NUL;
- return(cmflgs = -1);
- }
- bp--;
- /* Back up over any trailing nonalphanums */
- /* This is dependent on ASCII collating sequence */
- /* but isalphanum() is not available everywhere. */
- for ( ;
- (bp >= cmdbuf) &&
- ((*bp < '0') ||
- ((*bp > '9') && (*bp < '@')) ||
- ((*bp > 'Z') && (*bp < 'a')) ||
- (*bp > 'z'));
- bp--
- ) {
- cmdchardel();
- *bp = NUL;
- }
- /* Now delete back to rightmost remaining nonalphanum */
- for ( ; (bp >= cmdbuf) && (*bp) ; bp--) {
- if ((*bp < '0') ||
- (*bp > '9' && *bp < '@') ||
- (*bp > 'Z' && *bp < 'a') ||
- (*bp > 'z'))
- break;
- cmdchardel();
- *bp = NUL;
- }
- bp++;
- inword = 0;
- return(cmflgs = -1);
-
- case RDIS: { /* ^R, redisplay */
- char *cpx; char cx;
- *bp = NUL;
- printf("\n%s",cmprom);
- cpx = cmdbuf;
- while ((cx = *cpx++)) {
- cmdecho(cx,0);
- }
- fflush(stdout);
- continue;
- }
-#ifndef NOLASTFILE
- case VT:
- if (lastfile) {
- printf("%s ",lastfile);
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- inword = cmflgs = 0;
- addbuf(lastfile); /* Supply default. */
- if (setatm(lastfile,0) < 0) {
- printf("Last name too long\n");
- if (np) free(np);
- return(-9);
- }
- } else { /* No default */
- bleep(BP_WARN);
- }
- return(0);
-#endif /* NOLASTFILE */
- }
-
-#ifdef CK_RECALL
- if (on_recall && /* Reading commands from keyboard? */
- (cm_recall > 0) && /* Saving commands? */
- (c == C_UP || c == C_UP2)) { /* Go up one */
- if (last_recall == 2 && current > 0)
- current--;
- if (current < 0) { /* Nowhere to go, */
- bleep(BP_WARN);
- continue;
- }
- if (recall[current]) { /* We have a previous command */
- while ((bp--) > cmdbuf) { /* Erase current line */
- cmdchardel();
- *bp = NUL;
- }
- ckstrncpy(cmdbuf,recall[current],CMDBL);
-#ifdef OSK
- fflush(stdout);
- write(fileno(stdout), "\r", 1);
- printf("%s%s",cmprom,cmdbuf);
-#else
- printf("\r%s%s",cmprom,cmdbuf);
-#endif /* OSK */
- current--;
- }
- last_recall = 1;
- return(cmflgs = -1); /* Force a reparse */
- }
- if (on_recall && /* Reading commands from keyboard? */
- (cm_recall > 0) && /* Saving commands? */
- (c == C_DN)) { /* Down one */
- int x = 1;
- if (last_recall == 1)
- x++;
- if (current + x > rlast) { /* Already at bottom, beep */
- bleep(BP_WARN);
- continue;
- }
- current += x; /* OK to go down */
- if (recall[current]) {
- while ((bp--) > cmdbuf) { /* Erase current line */
- cmdchardel();
- *bp = NUL;
- }
- ckstrncpy(cmdbuf,recall[current],CMDBL);
-#ifdef OSK
- fflush(stdout);
- write(fileno(stdout), "\r", 1);
- printf("%s%s",cmprom,cmdbuf);
-#else
- printf("\r%s%s",cmprom,cmdbuf);
-#endif /* OSK */
- last_recall = 2;
- return(cmflgs = -1); /* Force reparse */
- }
- }
-#endif /* CK_RECALL */
- }
-
- if (c < SP && quote == 0) { /* Any other unquoted control char */
- if (!chsrc) { /* If cmd file, point past it */
- bp++;
- } else {
- bleep(BP_WARN);
- }
- continue; /* continue, don't put in buffer */
- }
- linebegin = 0; /* Not at beginning of line */
-#ifdef BEBOX
- if (echof) {
- cmdecho((char) c, 0); /* Echo what was typed. */
- fflush (stdout);
- fflush(stderr);
- }
-#else
-#ifdef NOSPL
- if (echof || chsrc)
-#else
- if (echof || (echostars && chsrc))
-#endif /* NOSPL */
- cmdecho((char) c, 0); /* Echo what was typed. */
-#endif /* BEBOX */
- } else { /* This character was quoted. */
- int qf = 1;
- quote = 0; /* Unset the quote flag. */
- /* debug(F000,"gtword quote 0","",c); */
- /* Quote character at this level is only for SP, ?, and controls */
- /* If anything else was quoted, leave quote in, and let */
- /* the command-specific parsing routines handle it, e.g. \007 */
- if (c > 32 && c != '?' && c != RUB && chsrc != 0) {
- /* debug(F000,"gtword quote 1","",c); */
- *bp++ = CMDQ; /* Deposit \ if it came from tty */
- qf = 0; /* and don't erase it from screen */
- linebegin = 0; /* Not at beginning of line */
-#ifdef BS_DIRSEP
-/*
- This is a hack to handle "cd \" or "cd foo\" on OS/2 and similar systems.
- If we were called from cmdir() and the previous character was the quote
- character, i.e. backslash, and this character is the command terminator,
- then we stuff an extra backslash into the buffer without echoing, then
- we stuff the carriage return back in again, and go back and process it,
- this time with the quote flag off.
-*/
- } else if (dirnamflg && (c == CR || c == LF || c == SP)) {
- /* debug(F000,"gtword quote 2","",c); */
- *bp++ = CMDQ;
- linebegin = 0; /* Not at beginning of line */
- *bp = (c == SP ? SP : CR);
- goto CMDIRPARSE;
-#endif /* BS_DIRSEP */
- }
-#ifdef BEBOX
- if (echof) {
- cmdecho((char) c, qf); /* Echo what was typed. */
- fflush (stdout);
- fflush(stderr);
- }
-#else
- if (echof) cmdecho((char) c, qf); /* Now echo quoted character */
-#endif /* BEBOX */
- /* debug(F111,"gtword quote",cmdbuf,c); */
- }
-#ifdef COMMENT
- if (echof) cmdecho((char) c,quote); /* Echo what was typed. */
-#endif /* COMMENT */
- if (!comment) inword = 1; /* Flag we're in a word. */
- if (quote) continue; /* Don't deposit quote character. */
- if (c != NL) { /* Deposit command character. */
- *bp++ = (char) c; /* and make sure there is a NUL */
-#ifdef COMMENT
- *bp = NUL; /* after it */
-#endif /* COMMENT */
- }
- } /* End of big while */
- bleep(BP_WARN);
- printf("?Command too long, maximum length: %d.\n",CMDBL);
- cmflgs = -2;
- return(-9);
-}
-
-/* Utility functions */
-
-/* A D D B U F -- Add the string pointed to by cp to the command buffer */
-
-static int
-addbuf(cp) char *cp; {
- int len = 0;
- while ((*cp != NUL) && (bp < cmdbuf+CMDBL)) {
- *bp++ = *cp++; /* Copy and */
- len++; /* count the characters. */
- }
- *bp++ = SP; /* Put a space at the end */
- *bp = NUL; /* Terminate with a null */
- np = bp; /* Update the next-field pointer */
- cmbptr = np;
- return(len); /* Return the length */
-}
-
-/* S E T A T M -- Deposit a token in the atom buffer. */
-/*
- Break on space, newline, carriage return, or NUL.
- Call with:
- cp = Pointer to string to copy to atom buffer.
- fcode = 0 means break on whitespace or EOL.
- fcode = 1 means don't break on space.
- fcode = 2 means break on space, ':', or '='.
- fcode = 3 means copy the whole string.
- Null-terminate the result.
- Return length of token, and also set global "cc" to this length.
- Return -1 if token was too long.
-*/
-static int
-setatm(cp,fcode) char *cp; int fcode; {
- char *ap, *xp, *dqp = NULL, lbrace, rbrace;
- int bracelvl = 0, dq = 0;
-
- register char * s;
- register int n = 0;
-
- if (cmfldflgs & 1) { /* Handle grouping */
- lbrace = '(';
- rbrace = ')';
- } else {
- lbrace = '{';
- rbrace = '}';
- }
- cc = 0; /* Character counter */
- ap = atmbuf; /* Address of atom buffer */
-
- s = cp;
-
- while (*s++) n++; /* Save a call to strlen */
-
- if (n > ATMBL) {
- printf("?Command buffer overflow\n");
- return(-1);
- }
- /* debug(F111,"setatm",cp,n); */
- if (cp == ap) { /* In case source is atom buffer */
- xp = atybuf; /* make a copy */
-#ifdef COMMENT
- strncpy(xp,ap,ATMBL); /* so we can copy it back, edited. */
- cp = xp;
-#else
- s = ap;
- while ((*xp++ = *s++)) ; /* We already know it's big enough */
- cp = xp = atybuf;
-#endif /* COMMENT */
- }
- *ap = NUL; /* Zero the atom buffer */
- if (fcode == 1) { /* Trim trailing blanks */
- while (--n >= 0 && cp[n] == SP)
- ;
- cp[n+1] = NUL;
- }
- while (*cp == SP) { /* Trim leading spaces */
- cp++;
- n--;
- }
- if (*cp == '"') { /* Starts with doublequote? */
- dq = 1;
- dqp = cp;
- }
- while (*cp) {
- if (*cp == lbrace)
- bracelvl++;
- else if (*cp == rbrace)
- bracelvl--;
- if (bracelvl < 0)
- bracelvl = 0;
- if (bracelvl == 0) {
- if (dq) {
- if (*cp == SP || *cp == HT) {
- if (cp > dqp+1) {
- if (*(cp-1) == '"' && *(cp-2) != CMDQ) {
- break;
- }
- }
- }
- } else if ((*cp == SP || *cp == HT) && fcode != 1 && fcode != 3)
- break;
- if ((fcode == 2) && (*cp == '=' || *cp == ':')) break;
- if ((fcode != 3) && (*cp == LF || *cp == CR)) break;
- }
- *ap++ = *cp++;
- cc++;
- }
- *ap = NUL; /* Terminate the string. */
- /* debug(F111,"setatm result",atmbuf,cc); */
- return(cc); /* Return length. */
-}
-
-/*
- These functions attempt to hide system dependencies from the mainline
- code in gtword(). Dummy arg for cmdgetc() needed for compatibility with
- coninc(), ttinc(), etc, since a pointer to this routine can be passed in
- place of those to tn_doop().
-
- No longer static. Used by askmore(). Fri Aug 20 15:03:34 1999.
-*/
-#define CMD_CONINC /* How we get keyboard chars */
-
-int
-cmdgetc(timelimit) int timelimit; { /* Get a character from the tty. */
- int c;
-#ifdef IKSD
- extern int inserver;
-#endif /* IKSD */
-#ifdef CK_LOGIN
- extern int x_logged;
-#endif /* CK_LOGIN */
-#ifdef TNCODE
- static int got_cr = 0;
- extern int ckxech;
- int tx = 0, is_tn = 0;
-#endif /* TNCODE */
-
- if (pushc
-#ifndef NOSPL
- && !askflag
-#endif /* NOSPL */
- ) {
- debug(F111,"cmdgetc()","pushc",pushc);
- c = pushc;
- pushc = NUL;
- if (xcmfdb && c == '?') /* Don't echo ? twice if chaining. */
- cmdchardel();
- return(c);
- }
-#ifdef datageneral
- {
- char ch;
- c = dgncinb(0,&ch,1); /* -1 is EOF, -2 TO,
- * -c is AOS/VS error */
- if (c == -2) { /* timeout was enabled? */
- resto(channel(0)); /* reset timeouts */
- c = dgncinb(0,&ch,1); /* retry this now! */
- }
- if (c < 0) return(-4); /* EOF or some error */
- else c = (int) ch & 0177; /* Get char without parity */
-/* echof = 1; */
- }
-#else /* Not datageneral */
-#ifndef MINIX2
- if (
-#ifdef IKSD
- (!local && inserver) ||
-#endif /* IKSD */
- timelimit > 0) {
-#ifdef TNCODE
- GETNEXTCH:
- is_tn = !pushc && !local && sstelnet;
-#endif /* TNCODE */
-#ifdef COMMENT
- c = coninc(timelimit > 0 ? 1 : 0);
-#else /* COMMENT */
- /* This is likely to break the asktimeout... */
- c = coninc(timelimit);
-#endif /* COMMENT */
- /* debug(F101,"cmdgetc coninc","",c); */
-#ifdef TNCODE
- if (c >= 0 && is_tn) { /* Server-side Telnet */
- switch (c) {
- case IAC:
- /* debug(F111,"gtword IAC","c",c); */
- got_cr = 0;
- if ((tx = tn_doop((CHAR)(c & 0xff),ckxech,coninc)) == 0) {
- goto GETNEXTCH;
- } else if (tx <= -1) { /* I/O error */
- /* If there was a fatal I/O error then ttclos() */
- /* has been called and the next GETNEXTCH attempt */
- /* will be !is_tn since ttclos() sets sstelnet = 0 */
- doexit(BAD_EXIT,-1); /* (or return(-4)? */
- } else if (tx == 1) { /* ECHO change */
- ckxech = dpx = 1; /* Get next char */
- goto GETNEXTCH;
- } else if (tx == 2) { /* ECHO change */
- ckxech = dpx = 0; /* Get next char */
- goto GETNEXTCH;
- } else if (tx == 3) { /* Quoted IAC */
- c = 255; /* proceeed with it. */
- }
-#ifdef IKS_OPTION
- else if (tx == 4) { /* IKS State Change */
- goto GETNEXTCH;
- }
-#endif /* IKS_OPTION */
- else if (tx == 6) { /* Remote Logout */
- doexit(GOOD_EXIT,0);
- } else {
- goto GETNEXTCH; /* Unknown, get next char */
- }
- break;
-#ifdef COMMENT
- case CR:
- if (!TELOPT_U(TELOPT_BINARY)) {
- if (got_cr) {
- /* This means the sender is violating Telnet */
- /* protocol because we received two CRs in a */
- /* row without getting either LF or NUL. */
- /* This will not solve the problem but it */
- /* will at least allow two CRs to do something */
- /* whereas before the user would have to guess */
- /* to send LF or NUL after the CR. */
- debug(F100,"gtword CR telnet error","",0);
- c = LF;
- } else {
- debug(F100,"gtword skipping CR","",0);
- got_cr = 1; /* Remember a CR was received */
- goto GETNEXTCH;
- }
- } else {
- debug(F100,"gtword CR to LF","",0);
- c = LF;
- }
- break;
- case LF:
- if (!TELOPT_U(TELOPT_BINARY)) {
- got_cr = 0;
- debug(F100,"gtword LF","",0);
- } else {
- if (got_cr) {
- got_cr = 0;
- debug(F100,"gtword skipping LF","",0);
- goto GETNEXTCH;
- }
- }
- break;
- case NUL:
- if (!TELOPT_U(TELOPT_BINARY) && got_cr) {
- c = LF;
- debug(F100,"gtword NUL to LF","",0);
- } else {
- debug(F100,"gtword NUL","",0);
- }
- got_cr = 0;
- break;
-#else /* COMMENT */
- case CR:
- if ( !TELOPT_U(TELOPT_BINARY) && got_cr ) {
- /* This means the sender is violating Telnet */
- /* protocol because we received two CRs in a */
- /* row without getting either LF or NUL. */
- /* This will not solve the problem but it */
- /* will at least allow two CRs to do something */
- /* whereas before the user would have to guess */
- /* to send LF or NUL after the CR. */
- debug(F100,"gtword CR telnet error","",0);
- } else {
- got_cr = 1; /* Remember a CR was received */
- }
- /* debug(F100,"gtword CR to LF","",0); */
- c = LF;
- break;
- case LF:
- if (got_cr) {
- got_cr = 0;
- /* debug(F100,"gtword skipping LF","",0); */
- goto GETNEXTCH;
- }
- break;
- case NUL:
- if (got_cr) {
- got_cr = 0;
- /* debug(F100,"gtword skipping NUL","",0); */
- goto GETNEXTCH;
-#ifdef COMMENT
- } else {
- debug(F100,"gtword NUL","",0);
-#endif /* COMMENT */
- }
- break;
-#endif /* COMMENT */
-#ifdef IKSD
- case ETX: /* Ctrl-C... */
- case EOT: /* EOT = EOF */
- if (inserver
-#ifdef CK_LOGIN
- && !x_logged
-#endif /* CK_LOGIN */
- )
- return(-4);
- break;
-#endif /* IKSD */
- default:
- got_cr = 0;
- }
- }
-#endif /* TNCODE */
- } else {
-#ifdef OS2
- c = coninc(0);
-#else /* OS2 */
-#ifdef CMD_CONINC
-#undef CMD_CONINC
-#endif /* CMD_CONINC */
- c = getchar();
-#endif /* OS2 */
- }
-#else /* MINIX2 */
-#undef getc
-#ifdef CMD_CONINC
-#undef CMD_CONINC
-#endif /* CMD_CONINC */
- c = getc(stdin);
- /* debug(F101,"cmdgetc getc","",c); */
-#endif /* MINIX2 */
-#ifdef RTU
- if (rtu_bug) {
-#ifdef CMD_CONINC
-#undef CMD_CONINC
-#endif /* CMD_CONINC */
- c = getchar(); /* RTU doesn't discard the ^Z */
- rtu_bug = 0;
- }
-#endif /* RTU */
-#endif /* datageneral */
- return(c); /* Return what we got */
-}
-
-/* #ifdef USE_ARROWKEYS */
-
-/* Mechanism to use for peeking into stdin buffer */
-
-#ifndef USE_FILE_CNT /* stdin->__cnt */
-#ifndef USE_FILE__CNT /* Note: two underscores */
-#ifdef HPUX /* HPUX 7-11 */
-#ifndef HPUX5
-#ifndef HPUX6
-#define USE_FILE__CNT
-#endif /* HPUX6 */
-#endif /* HPUX5 */
-#else
-#ifdef ANYSCO /* SCO UNIX, OSR5, Unixware, etc */
-#ifndef OLD_UNIXWARE /* But not Unixware 1.x or 2.0 */
-#ifndef UNIXWARE2 /* or 2.1.0 */
-#define USE_FILE__CNT
-#endif /* UNIXWARE2 */
-#endif /* OLD_UNIXWARE */
-#endif /* ANYSCO */
-#endif /* HPUX */
-#endif /* USE_FILE__CNT */
-#endif /* USE_FILE_CNT */
-
-#ifndef USE_FILE_R /* stdin->_r */
-#ifndef USE_FILE_CNT
-#ifndef USE_FILE__CNT
-#ifdef BSD44 /* {Free,Open,Net}BSD, BSDI */
-#define USE_FILE_R
-#endif /* BSD44 */
-#endif /* USE_FILE__CNT */
-#endif /* USE_FILE_CNT */
-#endif /* USE_FILE_R */
-
-#ifndef USE_FILE_R /* stdin->_cnt */
-#ifndef USE_FILE_CNT
-#ifndef USE_FILE__CNT
-#define USE_FILE_CNT /* Everybody else (but Linux) */
-#endif /* USE_FILE__CNT */
-#endif /* USE_FILE_CNT */
-#endif /* USE_FILE_R */
-
-
-/*
- c m d c o n c h k
-
- How many characters are waiting to be read at the console? Normally
- conchk() would tell us, but in Unix and VMS cmdgetc() uses stdio getchar(),
- thus bypassing coninc()/conchk(), so we have to peek into the stdin buffer,
- which is totally nonportable. Which is why this routine is, at least for
- now, used only for checking for arrow-key sequences from the keyboard after
- an ESC was read. Wouldn't it be nice if the stdio package had a function
- that returned the number of bytes waiting to be read from its buffer?
- Returns 0 or greater always.
-*/
-int
-cmdconchk() {
- int x = 0, y;
- y = pushc ? 1 : 0; /* Have command character pushed? */
-#ifdef OS2
- x = conchk(); /* Check device-driver buffer */
- if (x < 0) x = 0;
-#else /* OS2 */
-#ifdef CMD_CONINC /* See cmdgetc() */
- x = conchk(); /* Check device-driver buffer */
- if (x < 0) x = 0;
-#else /* CMD_CONINC */
-
-/* Here we must look inside the stdin buffer - highly platform dependent */
-
-#ifdef _IO_EOF_SEEN /* Linux */
- x = (int) ((stdin->_IO_read_end) - (stdin->_IO_read_ptr));
- debug(F101,"cmdconchk _IO_file_flags","",x);
-#else /* _IO_file_flags */
-#ifdef USE_FILE_CNT /* Traditional */
-#ifdef VMS
- debug(F101,"cmdconchk (*stdin)->_cnt","",(*stdin)->_cnt);
- x = (*stdin)->_cnt;
-#else
-#ifdef NOARROWKEYS
- debug(F101,"cmdconchk NOARROWKEYS x","",0);
-#else
- debug(F101,"cmdconchk stdin->_cnt","",stdin->_cnt);
- x = stdin->_cnt;
-#endif /* NOARROWKEYS */
-#endif /* VMS */
- if (x == 0) x = conchk();
- if (x < 0) x = 0;
-#else /* USE_FILE_CNT */
-#ifdef USE_FILE__CNT /* HP-UX */
- debug(F101,"cmdconchk stdin->__cnt","",stdin->__cnt);
- x = stdin->__cnt;
- if (x == 0) x = conchk();
- if (x < 0) x = 0;
-#else /* USE_FILE_CNT */
-#ifdef USE_FILE_R /* FreeBSD, OpenBSD, etc */
- debug(F101,"cmdconchk stdin->_r","",stdin->_r);
- x = stdin->_r;
- if (x == 0) x = conchk();
- if (x < 0) x = 0;
-
- /* Fill in any others here... */
-
-#endif /* USE_FILE_R */
-#endif /* USE_FILE__CNT */
-#endif /* USE_FILE_CNT */
-#endif /* _IO_file_flags */
-#endif /* CMD_CONINC */
-#endif /* OS2 */
- return(x + y);
-}
-/* #endif */ /* USE_ARROWKEYS */
-
-
-static VOID
-cmdclrscn() { /* Clear the screen */
- ck_cls();
-}
-
-static VOID /* What to echo at end of command */
-#ifdef CK_ANSIC
-cmdnewl(char c)
-#else
-cmdnewl(c) char c;
-#endif /* CK_ANSIC */
-/* cmdnewl */ {
-#ifdef OS2
-#ifdef IKSD
- extern int inserver;
- if (inserver && c == LF)
- putchar(CR);
-#endif /* IKSD */
-#endif /* OS2 */
-
- putchar(c); /* c is the terminating character */
-
-#ifdef WINTCP /* what is this doing here? */
- if (c == CR) putchar(NL);
-#endif /* WINTCP */
-
-/*
- A.A. Chernov, who sent in changes for FreeBSD, said we also needed this
- for SVORPOSIX because "setup terminal by termios and curses does
- not convert \r to \n, so additional \n needed in newline function." But
- it is also very likely to result in unwanted blank lines.
-*/
-#ifdef BSD44
- if (c == CR) putchar(NL);
-#endif /* BSD44 */
-
-#ifdef COMMENT
- /* OS2 no longer needs this as all CR are converted to NL in coninc() */
- /* This eliminates the ugly extra blank lines discussed above. */
-#ifdef OS2
- if (c == CR) putchar(NL);
-#endif /* OS2 */
-#endif /* COMMENT */
-#ifdef aegis
- if (c == CR) putchar(NL);
-#endif /* aegis */
-#ifdef AMIGA
- if (c == CR) putchar(NL);
-#endif /* AMIGA */
-#ifdef datageneral
- if (c == CR) putchar(NL);
-#endif /* datageneral */
-#ifdef GEMDOS
- if (c == CR) putchar(NL);
-#endif /* GEMDOS */
-#ifdef STRATUS
- if (c == CR) putchar(NL);
-#endif /* STRATUS */
-}
-
-static VOID
-cmdchardel() { /* Erase a character from the screen */
-#ifndef NOSPL
- if (!echostars)
-#endif /* NOSPL */
- if (!dpx) return;
-#ifdef datageneral
- /* DG '\b' is EM (^y or \031) */
- if (termtype == 1)
- /* Erase a character from non-DG screen, */
- dgncoub(1,"\010 \010",3);
- else
-#endif /* datageneral */
- printf("\b \b");
-#ifdef GEMDOS
- fflush(stdout);
-#else
-#ifdef BEBOX
- fflush(stdout);
-#endif /* BEBOX */
-#endif /* GEMDOS */
-}
-
-static VOID
-#ifdef CK_ANSIC
-cmdecho(char c, int quote)
-#else
-cmdecho(c,quote) char c; int quote;
-#endif /* CK_ANSIC */
-{ /* cmdecho */
-#ifdef NOSPL
- if (!dpx) return;
-#else
- if (!echostars) {
- if (!dpx) return;
- } else {
- c = (char)echostars;
- }
-#endif /* NOSPL */
- /* Echo tty input character c */
- if (quote) {
- putchar(BS);
- putchar(SP);
- putchar(BS);
-#ifdef isprint
- putchar((CHAR) (isprint(c) ? c : '^' ));
-#else
- putchar((CHAR) ((c >= SP && c < DEL) ? c : '^'));
-#endif /* isprint */
- } else {
- putchar(c);
- }
-#ifdef OS2
- if (quote==1 && c==CR) putchar((CHAR) NL);
-#endif /* OS2 */
- if (timelimit)
- fflush(stdout);
-}
-
-/* Return pointer to current position in command buffer. */
-
-char *
-cmpeek() {
- return(np);
-}
-#endif /* NOICP */
-
-
-#ifdef NOICP
-#include "ckcdeb.h"
-#include "ckucmd.h"
-#include "ckcasc.h"
-#endif /* NOICP */
-
-/* X X E S C -- Interprets backslash codes */
-/* Returns the int value of the backslash code if it is > -1 and < 256 */
-/* and updates the string pointer to first character after backslash code. */
-/* If the argument is invalid, leaves pointer unchanged and returns -1. */
-
-int
-xxesc(s) char **s; { /* Expand backslash escapes */
- int x, y, brace, radix; /* Returns the int value */
- char hd = '9'; /* Highest digit in radix */
- char *p;
-
- p = *s; /* pointer to beginning */
- if (!p) return(-1); /* watch out for null pointer */
- x = *p++; /* character at beginning */
- if (x != CMDQ) return(-1); /* make sure it's a backslash code */
-
- x = *p; /* it is, get the next character */
- if (x == '{') { /* bracketed quantity? */
- p++; /* begin past bracket */
- x = *p;
- brace = 1;
- } else brace = 0;
- switch (x) { /* Start interpreting */
- case 'd': /* Decimal radix indicator */
- case 'D':
- p++; /* Just point past it and fall thru */
- case '0': /* Starts with digit */
- case '1':
- case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- radix = 10; /* Decimal */
- hd = '9'; /* highest valid digit */
- break;
- case 'o': /* Starts with o or O */
- case 'O':
- radix = 8; /* Octal */
- hd = '7'; /* highest valid digit */
- p++; /* point past radix indicator */
- break;
- case 'x': /* Starts with x or X */
- case 'X':
- radix = 16; /* Hexadecimal */
- p++; /* point past radix indicator */
- break;
- default: /* All others */
-#ifdef COMMENT
- *s = p+1; /* Treat as quote of next char */
- return(*p);
-#else
- return(-1);
-#endif /* COMMENT */
- }
- /* For OS/2, there are "wide" characters required for the keyboard
- * binding, i.e \644 and similar codes larger than 255 (byte).
- * For this purpose, give up checking for < 256. If someone means
- * \266 should result in \26 followed by a "6" character, he should
- * always write \{26}6 anyway. Now, return only the lower byte of
- * the result, i.e. 10, but eat up the whole \266 sequence and
- * put the wide result 266 into a global variable. Yes, that's not
- * the most beautiful programming style but requires the least
- * amount of changes to other routines.
- */
- if (*p == '{') { /* Sun May 11 20:00:40 2003 */
- brace = 1; /* Allow {} after radix indicator */
- p++;
- }
- if (radix <= 10) { /* Number in radix 8 or 10 */
- for ( x = y = 0;
- (*p) && (*p >= '0') && (*p <= hd)
-#ifdef OS2
- && (y < 5) && (x*radix < KMSIZE);
- /* the maximum needed value \8196 is 4 digits long */
- /* while as octal it requires \1377, i.e. 5 digits */
-#else
- && (y < 3) && (x*radix < 256);
-#endif /* OS2 */
- p++,y++) {
- x = x * radix + (int) *p - 48;
- }
-#ifdef OS2
- wideresult = x; /* Remember wide result */
- x &= 255;
-#endif /* OS2 */
- if (y == 0 || x > 255) { /* No valid digits? */
- *s = p; /* point after it */
- return(-1); /* return failure. */
- }
- } else if (radix == 16) { /* Special case for hex */
- if ((x = unhex(*p++)) < 0) { *s = p - 1; return(-1); }
- if ((y = unhex(*p++)) < 0) { *s = p - 2; return(-1); }
- x = ((x << 4) & 0xF0) | (y & 0x0F);
-#ifdef OS2
- wideresult = x;
- if ((y = unhex(*p)) >= 0) {
- p++;
- wideresult = ((x << 4) & 0xFF0) | (y & 0x0F);
- x = wideresult & 255;
- }
-#endif /* OS2 */
- } else x = -1;
- if (brace && *p == '}' && x > -1) /* Point past closing brace, if any */
- p++;
- *s = p; /* Point to next char after sequence */
- return(x); /* Return value of sequence */
-}
-
-int /* Convert hex string to int */
-#ifdef CK_ANSIC
-unhex(char x)
-#else
-unhex(x) char x;
-#endif /* CK_ANSIC */
-/* unhex */ {
-
- if (x >= '0' && x <= '9') /* 0-9 is offset by hex 30 */
- return(x - 0x30);
- else if (x >= 'A' && x <= 'F') /* A-F offset by hex 37 */
- return(x - 0x37);
- else if (x >= 'a' && x <= 'f') /* a-f offset by hex 57 */
- return(x - 0x57); /* (obviously ASCII dependent) */
- else return(-1);
-}
-
-/* L O O K U P -- Lookup the string in the given array of strings */
-
-/*
- Call this way: v = lookup(table,word,n,&x);
-
- table - a 'struct keytab' table.
- word - the target string to look up in the table.
- n - the number of elements in the table.
- x - address of an integer for returning the table array index,
- or NULL if you don't need a table index.
-
- The keyword table must be arranged in ascending alphabetical order;
- alphabetic case doesn't matter but letters are treated as lowercase
- for purposes of ordering; thus "^" and "_" come *before* the letters,
- not after them.
-
- Returns the keyword's associated value (zero or greater) if found,
- with the variable x set to the keyword-table index. If is lookup()
- is not successful, it returns:
-
- -3 if nothing to look up (target was null),
- -2 if ambiguous,
- -1 if not found.
-
- A match is successful if the target matches a keyword exactly, or if
- the target is a prefix of exactly one keyword. It is ambiguous if the
- target matches two or more keywords from the table.
-
- Lookup() is the critical routine in scripts and so is optimized with a
- simple static cache plus some other tricks. Maybe it could be improved
- further with binary search or hash techniques but I doubt it since most
- keyword tables are fairly short.
-*/
-
-#ifdef USE_LUCACHE /* Lookup cache */
-extern int lusize; /* (initialized in ckuus5.c) */
-extern char * lucmd[];
-extern int luval[];
-extern int luidx[];
-extern struct keytab * lutab[];
-long luhits = 0L;
-long lucalls = 0L;
-long xxhits = 0L;
-long luloop = 0L;
-#endif /* USE_LUCACHE */
-
-int
-lookup(table,cmd,n,x) char *cmd; struct keytab table[]; int n, *x; {
-
- register int i, m;
- int v, len, cmdlen = 0;
- char c = NUL, c1, *s;
-
-/* Get 1st char of search object, if it's null return -3. */
-
- if (!cmd || n < 1) /* Defense de nullarg */
- return(-3);
- c1 = *cmd; /* First character */
- if (!c1) /* Make sure there is one */
- return(-3);
- if (isupper(c1)) /* If letter make it lowercase */
- c1 = tolower(c1);
-
-#ifdef USE_LUCACHE /* lookup() cache */
- m = lusize;
- lucalls++; /* Count this lookup() call */
- for (i = 0; i < m; i++) { /* Loop thru cache */
- if (*(lucmd[i]) == c1) { /* Same as 1st char of search item? */
- if (lutab[i] == table) { /* Yes - same table too? */
- if (!strcmp(cmd,lucmd[i])) { /* Yes - compare */
- if (x) *x = luidx[i]; /* Match - return index */
- luhits++; /* Count cache hit */
- return(luval[i]); /* Return associated value */
- }
- }
- }
- }
-#endif /* USE_LUCACHE */
-
-/* Not null, not in cache, look it up */
-
- s = cmd;
- while (*s++) cmdlen++; /* Length of target */
-/*
- Quick binary search to find last table entry whose first character is
- lexically less than the first character of the search object. This is
- the starting point of the next loop, which must go in sequence since it
- compares adjacent table entries.
-*/
- if (n < 5) { /* Not worth it for small tables */
- i = 0;
- } else {
- int lo = 0;
- int hi = n;
- int count = 0;
- while (lo+2 < hi && ++count < 12) {
- i = lo + ((hi - lo) / 2);
- c = *(table[i].kwd);
- if (isupper(c)) c = tolower(c);
- if (c < c1) {
- lo = i;
- } else {
- hi = i;
- }
- }
- i = (c < c1) ? lo+1 : lo;
-#ifdef USE_LUCACHE
- if (i > 0) xxhits++;
-#endif /* USE_LUCACHE */
- }
- for ( ; i < n-1; i++) {
-#ifdef USE_LUCACHE
- luloop++;
-#endif /* USE_LUCACHE */
- v = 0;
- c = *(table[i].kwd);
- if (c) {
- if (isupper(c)) c = tolower(c);
-
- /* The following is a big performance booster but makes it */
- /* absolutely essential that all lookup() tables are in order. */
-
- if (c > c1) /* Leave early if past our mark */
- return(-1);
-
-#ifdef DEBUG
- /* Use LOG DEBUG to check */
-
- if (deblog) {
- if (ckstrcmp(table[i].kwd,table[i+1].kwd,0,0) > 0) {
- printf("TABLE OUT OF ORDER [%s] [%s]\n",
- table[i].kwd,table[i+1].kwd);
-
- }
- }
-#endif /* DEBUG */
-
- if (c == c1) {
- len = 0;
- s = table[i].kwd;
- while (*s++) len++;
- if ((len == cmdlen && !ckstrcmp(table[i].kwd,cmd,len,0)) ||
- ((v = !ckstrcmp(table[i].kwd,cmd,cmdlen,0)) &&
- ckstrcmp(table[i+1].kwd,cmd,cmdlen,0))) {
- if (x) *x = i;
- return(table[i].kwval);
- }
- } else v = 0;
- }
- if (v) { /* Ambiguous */
- if (x) *x = i; /* Set index of first match */
- return(-2);
- }
- }
-
-/* Last (or only) element */
-
- if (!ckstrcmp(table[n-1].kwd,cmd,cmdlen,0)) {
- if (x) *x = n-1;
- /* debug(F111,"lookup",table[i].kwd,table); */
- return(table[n-1].kwval);
- } else return(-1);
-}
-
-/*
- x l o o k u p
-
- Like lookup, but requires a full (but case-independent) match
- and does NOT require the table to be in order.
-*/
-int
-xlookup(table,cmd,n,x) struct keytab table[]; char *cmd; int n, *x; {
- register int i;
- int len, cmdlen, one = 0;
- register char c, c2, * s, * s2;
-
- if (!cmd) cmd = ""; /* Check args */
- if (!*cmd || n < 1) return(-3);
-
- c = *cmd; /* First char of string to look up */
- if (!*(cmd+1)) { /* Special handling for 1-char names */
- cmdlen = 1;
- if (isupper(c))
- c = tolower(c);
- one = 1;
- } else {
- cmdlen = 0;
- s = cmd;
- while (*s++) cmdlen++;
- c = *cmd;
- if (isupper(c))
- c = tolower(c);
- }
- if (cmdlen < 1)
- return(-3);
-
- for (i = 0; i < n; i++) {
- s = table[i].kwd; /* This entry */
- if (!s) s = "";
- if (!*s) continue; /* Empty table entry */
- c2 = *s;
- if (isupper(c2)) c2 = tolower(c2);
- if (c != c2) continue; /* First char doesn't match */
- if (one) { /* Name is one char long */
- if (!*(s+1)) {
- if (x) *x = i;
- *cmd = c;
- return(table[i].kwval); /* So is table entry */
- }
- } else { /* Otherwise do string comparison */
- s2 = s;
- len = 0;
- while (*s2++) len++;
- if (len == cmdlen && !ckstrcmp(s,cmd,-1,0)) {
- if (x) *x = i;
- return(table[i].kwval);
- }
- }
- }
- return(-1);
-}
-
-/* Reverse lookup */
-
-char *
-rlookup(table,n,x) struct keytab table[]; int n, x; {
- int i;
- for (i = 0; i < n; i++) {
- if (table[i].kwval == x)
- return(table[i].kwd);
- }
- return(NULL);
-}
-
-#ifndef NOICP
-int
-cmdsquo(x) int x; {
- quoting = x;
- return(1);
-}
-
-int
-cmdgquo() {
- return(quoting);
-}
-#endif /* NOICP */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckucmd.c.glibc2_28 b/ckermit-9.0.302-build/ckermit-9.0.302/ckucmd.c.glibc2_28
deleted file mode 100644
index 274dc2d..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckucmd.c.glibc2_28
+++ /dev/null
@@ -1,7919 +0,0 @@
-#include "ckcsym.h"
-
-char *cmdv = "Command package 9.0.168, 12 March 2010";
-
-/* C K U C M D -- Interactive command package for Unix */
-
-/* (In reality, it's for all platforms, not just Unix) */
-
-/*
- Author: Frank da Cruz (fdc@columbia.edu),
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-#define TOKPRECHECK
-
-#define DOCHKVAR
-
-/* Command-terminal-to-C-Kermit character mask */
-
-#ifdef OS2 /* K95 */
-int cmdmsk = 255; /* (always was 255) */
-#else /* All others... */
-int cmdmsk = 255; /* 31 Dec 2000 (was 127) */
-#endif /* OS2 */
-
-#ifdef BS_DIRSEP /* Directory separator is backslash */
-#undef BS_DIRSEP
-#endif /* BS_DIRSEP */
-
-#ifdef OS2
-#define BS_DIRSEP
-#endif /* BS_DIRSEP */
-
-#define CKUCMD_C
-
-#include "ckcdeb.h" /* Formats for debug(), etc. */
-#include "ckcker.h" /* Needed for BIGBUFOK definition */
-#include "ckcnet.h" /* Needed for server-side Telnet */
-#include "ckucmd.h" /* Needed for everything */
-#include "ckuusr.h" /* Needed for prompt length */
-
-#ifndef NOARROWKEYS
-#ifndef NOESCSEQ
-#ifdef VMSORUNIX
-#define USE_ARROWKEYS /* Use arrow keys for command recall */
-#endif /* VMSORUNIX */
-#endif /* NOESCSEQ */
-#endif /* NOARROWKEYS */
-
-#undef CKUCMD_C
-
-_PROTOTYP( int unhex, (char) );
-_PROTOTYP( static VOID cmdclrscn, (void) );
-
-#ifdef CKLEARN
-_PROTOTYP( VOID learncmd, (char *) );
-#endif /* CKLEARN */
-
-static char *moname[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-struct keytab cmonths[] = {
- { "april", 4, 0 },
- { "august", 8, 0 },
- { "december", 12, 0 },
- { "february", 2, 0 },
- { "january", 1, 0 },
- { "july", 7, 0 },
- { "june", 6, 0 },
- { "march", 3, 0 },
- { "may", 5, 0 },
- { "november", 11, 0 },
- { "october", 10, 0 },
- { "september", 9, 0 }
-};
-
-#ifndef NOICP /* The rest only if interactive command parsing selected */
-
-#ifndef NOSPL
-_PROTOTYP( int chkvar, (char *) );
-extern int askflag, echostars;
-#endif /* NOSPL */
-
-#ifdef CKROOT
-extern int ckrooterr;
-#endif /* CKROOT */
-
-#ifdef IKSD
-extern int inserver;
-#endif /* IKSD */
-
-int cmfldflgs = 0; /* Flags for cmfld() */
-int cmkwflgs = 0; /* Flags from last keyword parse */
-static int nomsg = 0;
-static int blocklvl = 0; /* Block nesting level */
-static int linebegin = 0; /* Flag for at start of a line */
-static int quoting = 1; /* Quoting is allowed */
-static int swarg = 0; /* Parsing a switch argument */
-static int xcmfdb = 0; /* Flag for parsing chained fdbs... */
-static int chsrc = 0; /* Source of character, 1 = tty */
-static int newcmd = 0; /* See addcmd() */
-
-#ifdef BS_DIRSEP
-static int dirnamflg = 0;
-#endif /* BS_DIRSEP */
-
-/*
-Modeled after the DECSYSTEM-20 command parser (the COMND JSYS), RIP. Features:
-
- . parses and verifies keywords, filenames, text strings, numbers, other data
- . displays appropriate menu or help message when user types "?"
- . does keyword and filename completion when user types ESC or TAB
- . does partial keyword and filename completion
- . accepts any unique abbreviation for a keyword
- . allows keywords to have attributes, like "invisible" and "abbreviation"
- . can supply defaults for fields omitted by user
- . provides command retry and recall
- . provides character, word, and line deletion (but only from the end)
- . accepts input from keyboard, command files, macros, or redirected stdin
- . allows for full or half duplex operation, character or line input
- . allows \-escapes for special characters
- . allows specification of a user exit to expand variables, etc.
- . settable prompt, protected from deletion, dynamically re-evaluated each time
- . allows chained parse functions.
-
-Functions:
- cmsetp - Set prompt (cmprom is prompt string)
- cmsavp - Save current prompt
- cmgetp = Get current prompt
- prompt - Issue prompt
- cmini - Clear the command buffer (before parsing a new command)
- cmres - Reset command buffer pointers (before reparsing)
- cmkey - Parse a keyword or token (also cmkey2)
- cmswi - Parse a switch
- cmnum - Parse a number
- cmifi - Parse an input file name
- cmofi - Parse an output file name (also cmifip, cmifi2, ...)
- cmdir - Parse a directory name (also cmdirp)
- cmfld - Parse an arbitrary field
- cmtxt - Parse a text string
- cmdate - Parse a date-time string
- cmcfm - Parse command confirmation (end of line)
- cmfdb - Parse any of a list of the foregoing (chained parse functions)
-
-Return codes:
- -9: like -2 except this module already printed the error message
- -3: no input provided when required
- -2: input was invalid (e.g. not a number when a number was required)
- -1: reparse required (user deleted into a preceding field)
- 0 or greater: success
-See individual functions for greater detail.
-
-Before using these routines, the caller should #include "ckucmd.h" and set the
-program's prompt by calling cmsetp(). If the file parsing functions cmifi,
-cmofi, or cmdir are to be used, this module must be linked with a ck?fio file
-system support module for the appropriate system, e.g. ckufio for Unix. If
-the caller puts the terminal in character wakeup ("cbreak") mode with no echo,
-then these functions will provide line editing -- character, word, and line
-deletion, as well as keyword and filename completion upon ESC and help
-strings, keyword, or file menus upon '?'. If the caller puts the terminal
-into character wakeup/noecho mode, care should be taken to restore it before
-exit from or interruption of the program. If the character wakeup mode is not
-set, the system's own line editor may be used.
-
-NOTE: Contrary to expectations, many #ifdef's have been added to this module.
-Any operation requiring an #ifdef (like clear screen, get character from
-keyboard, erase character from screen, etc) should eventually be turned into a
-call to a function that is defined in ck?tio.c, but then all the ck?tio.c
-modules would have to be changed...
-*/
-
-/* Includes */
-
-#include "ckcker.h"
-#include "ckcasc.h" /* ASCII character symbols */
-#include "ckucmd.h" /* Command parsing definitions */
-
-#ifdef OSF13
-#ifdef CK_ANSIC
-#ifdef _NO_PROTO
-#undef _NO_PROTO
-#endif /* _NO_PROTO */
-#endif /* CK_ANSIC */
-#endif /* OSF13 */
-
-#ifndef HPUXPRE65
-#include <errno.h> /* Error number symbols */
-#else
-#ifndef ERRNO_INCLUDED
-#include <errno.h> /* Error number symbols */
-#endif /* ERRNO_INCLUDED */
-#endif /* HPUXPRE65 */
-
-#ifdef OS2
-#ifndef NT
-#define INCL_NOPM
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#else
-#define APIRET ULONG
-#include <windows.h>
-#endif /* NT */
-#include "ckocon.h"
-#include <io.h>
-#endif /* OS2 */
-
-#ifdef OSK
-#define cc ccount /* OS-9/68K compiler bug */
-#endif /* OSK */
-
-#ifdef GEMDOS /* Atari ST */
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) conoc(x)
-#endif /* GEMDOS */
-
-#ifdef CK_AUTODL
-extern int cmdadl, justone;
-#endif /* CK_AUTODL */
-
-extern int timelimit, nzxopts, nopush, nolocal, xcmdsrc, keepallchars;
-
-#ifdef CKSYSLOG
-#ifdef UNIX
-#ifdef CKXPRINTF /* Our printf macro conflicts with */
-#undef printf /* use of "printf" in syslog.h */
-#endif /* CKXPRINTF */
-#ifdef RTAIX
-#include <sys/syslog.h>
-#else /* RTAIX */
-#include <syslog.h>
-#endif /* RTAIX */
-#ifdef CKXPRINTF
-#define printf ckxprintf
-#endif /* CKXPRINTF */
-#endif /* UNIX */
-#endif /* CKSYSLOG */
-
-/* Local variables */
-
-static
-int psetf = 0, /* Flag that prompt has been set */
- cc = 0, /* Character count */
- dpx = 0, /* Duplex (0 = full) */
- inword = 0; /* In the middle of getting a word */
-
-char *dfprom = "Command? "; /* Default prompt */
-#ifndef NOLASTFILE
-char *lastfile = NULL; /* Last filespec */
-static char *tmplastfile = NULL; /* Last filespec candidate */
-#endif /* NOLASTFILE */
-
-int cmflgs; /* Command flags */
-int cmfsav; /* A saved version of them */
-
-static char pushc = NUL;
-static char brkchar = NUL;
-
-#define CMDEFAULT 1023
-static char cmdefault[CMDEFAULT+1];
-
-#ifdef DCMDBUF
-char *cmdbuf = NULL; /* Command buffer */
-char *savbuf = NULL; /* Buffer to save copy of command */
-char *atmbuf = NULL; /* Atom buffer - for current field */
-char *atxbuf = NULL; /* For expanding the atom buffer */
-char *prevcmd = NULL;
-static char *atybuf = NULL; /* For copying atom buffer */
-static char *filbuf = NULL; /* File name buffer */
-static char *cmprom = NULL; /* Program's prompt */
-static char *cmprxx = NULL; /* Program's prompt, unevaluated */
-
-#ifdef CK_RECALL
-/*
- Command recall is available only if we can make profligate use of malloc().
-*/
-#define R_MAX 10 /* How many commands to save */
-int cm_recall = R_MAX; /* Size of command recall buffer */
-int on_recall = 1; /* Recall feature is ON */
-static int no_recall = 0; /* Recall OFF for this cmd only */
-static int force_add = 0; /* Force cmd into recall buffer */
-static int last_recall = -1; /* Last recall-related action */
-/*
- -1 = none
- 0 = CR (a command was entered)
- 1 = Up
- 2 = Down
-*/
-int in_recall = 0; /* Recall buffers are init'd */
-static int
- current = -1, /* Pointer to current command */
- rlast = -1; /* Index of last command in buffer */
-static char **recall = NULL; /* Array of recall buffer pointers */
-#endif /* CK_RECALL */
-#else /* !DCMDBUF */
-char cmdbuf[CMDBL+4]; /* Command buffer */
-char savbuf[CMDBL+4]; /* Buffer to save copy of command */
-char atmbuf[ATMBL+4]; /* Atom buffer */
-char atxbuf[CMDBL+4]; /* For expanding the atom buffer */
-char prevcmd[CMDBL+4]; /* For displaying the last command */
-static char atybuf[ATMBL+4]; /* For copying atom buffer */
-static char filbuf[ATMBL+4]; /* File name buffer */
-static char cmprom[PROMPTL+1]; /* Program's prompt */
-static char cmprxx[PROMPTL+1]; /* Program's prompt, unevaluated */
-#endif /* DCMDBUF */
-
-/* Command buffer pointers */
-
-#define PPVLEN VNAML /* 20080305 Wolfram Sang (was 24) */
-char ppvnambuf[PPVLEN+1] = { NUL, NUL };
-
-char * cmbptr = NULL; /* Current position (for export) */
-
-static char *bp, /* Current command buffer position */
- *pp, /* Start of current field */
- *np; /* Start of next field */
-
-static int ungw, /* For ungetting words */
- atxn; /* Expansion buffer (atxbuf) length */
-
-#ifdef OS2
-extern int wideresult;
-#endif /* OS2 */
-
-extern int cmd_cols, cmd_rows, local, quiet;
-
-#ifdef TNCODE
-#ifdef IAC
-#undef IAC
-#endif /* IAC */
-#define IAC 255
-#endif /* TNCODE */
-
-_PROTOTYP( static int gtword, (int) );
-_PROTOTYP( static int addbuf, (char *) );
-_PROTOTYP( static int setatm, (char *, int) );
-_PROTOTYP( static VOID cmdnewl, (char) );
-_PROTOTYP( static VOID cmdchardel, (void) );
-_PROTOTYP( static VOID cmdecho, (char, int) );
-_PROTOTYP( static int test, (int, int) );
-#ifdef GEMDOS
-_PROTOTYP( extern char *strchr, (char *, int) );
-#endif /* GEMDOS */
-
-extern char * dftty;
-
-/* The following are for use with chained FDB's */
-
-static int crflag = 0; /* Carriage return was typed */
-static int qmflag = 0; /* Question mark was typed */
-static int esflag = 0; /* Escape was typed */
-
-/* Directory separator */
-
-#ifdef GEMDOS
-static char dirsep = '\\';
-#else
-#ifdef datageneral
-static char dirsep = ':';
-#else
-#ifdef MAC
-static char dirsep = ':';
-#else
-#ifdef VMS
-static char dirsep = '.';
-#else
-#ifdef STRATUS
-static char dirsep = '>';
-#else
-static char dirsep = '/'; /* UNIX, OS/2, OS-9, Amiga, etc. */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* MAC */
-#endif /* datageneral */
-#endif /* GEMDOS */
-
-/* H A S N O P A T H */
-
-/* Returns 0 if filespec s includes any path segments; 1 if it doesn't. */
-
-int
-hasnopath(s) char * s; {
- char * p = NULL;
- if (!s) return(0);
- if (!*s) return(0);
- zstrip(s,&p);
- return(ckstrcmp(s,p,CKMAXPATH,filecase) == 0 ? 1 : 0);
-}
-
-/* C K S P R E A D -- Print string double-spaced */
-
-static char * sprptr = NULL;
-
-static char *
-ckspread(s) char * s; {
- int n = 0;
- char * p;
- n = strlen(s);
- if (sprptr)
- free(sprptr);
- sprptr = malloc(n + n + 3);
- if (sprptr) {
- p = sprptr;
- while (*s) {
- *p++ = *s++;
- *p++ = SP;
- }
- *p = NUL;
- }
- return(sprptr ? sprptr : "");
-}
-
-/* T E S T -- Bit test */
-
-static int
-test(x,m) int x, m; { /* Returns 1 if any bits from m are on in x, else 0 */
- return((x & m) ? 1 : 0);
-}
-
-/* K W D H E L P -- Given a keyword table, print keywords in columns. */
-/*
- Call with:
- s - keyword table
- n - number of entries
- pat - pattern (left substring) that must match for each keyword
- pre - prefix to add to each keyword
- post - suffix to add to each keyword
- off - offset on first screenful, allowing room for introductory text
- xhlp - 1 to print any CM_INV keywords that are not also abbreviations.
- 2 to print CM_INV keywords if CM_HLP also set
- 4 if it's a switch table (to show ':' if CM_ARG)
-
- Arranges keywords in columns with width based on longest keyword.
- Does "more?" prompting at end of screen.
- Uses global cmd_rows and cmd_cols for screen size.
-*/
-VOID
-kwdhelp(s,n,pat,pre,post,off,xhlp)
- struct keytab s[]; int n, off, xhlp; char *pat, *pre, *post;
-/* kwdhelp */ {
-
- int width = 0;
- int cc;
- int cols, height, i, j, k, lc, n2 = 0;
- char *b = NULL, *p, *q;
- char *pa, *px;
- char **s2 = NULL;
- char *tmpbuf = NULL;
-
- cc = strlen(pat);
-
- if (!s) return; /* Nothing to do */
- if (n < 1) return; /* Ditto */
- if (off < 0) off = 0; /* Offset for first page */
- if (!pre) pre = ""; /* Handle null string pointers */
- if (!post) post = "";
- lc = off; /* Screen-line counter */
-
- if (xhlp & 4) /* For switches */
- tmpbuf = (char *)malloc(TMPBUFSIZ+1);
-
- if ((s2 = (char **) malloc(n * sizeof(char *)))) {
- for (i = 0; i < n; i++) { /* Find longest keyword */
- s2[i] = NULL;
- if (ckstrcmp(s[i].kwd,pat,cc,0))
- continue;
-
- if (s[i].flgs & CM_PSH /* NOPUSH or nopush screening */
-#ifndef NOPUSH
- && nopush
-#endif /* NOPUSH */
- )
- continue;
- if (s[i].flgs & CM_LOC /* NOLOCAL or nolocal screening */
-#ifndef NOLOCAL
- && nolocal
-#endif /* NOLOCAL */
- )
- continue;
-
- if (s[i].flgs & CM_INV) {
-#ifdef COMMENT
-/* This code does not show invisible keywords at all except for "help ?" */
-/* and then only help topics (CM_HLP) in the top-level keyword list. */
-
- if ((xhlp & 2) == 0)
- continue;
- else if ((s[i].flgs & CM_HLP) == 0)
- continue;
-#else
-/* This code shows invisible keywords that are not also abbreviations when */
-/* ? was typed AFTER the beginning of the field so the user can find out */
-/* what they are and (for example) why completion doesn't work at this point */
-
- if (s[i].flgs & CM_ABR)
- continue;
- else if ((xhlp & 3) == 0)
- continue;
- else if ((xhlp & 2) && ((s[i].flgs & CM_HLP) == 0))
- continue;
-#endif /* COMMENT */
- }
- j = strlen(s[i].kwd);
- if (!(xhlp & 4) || !tmpbuf) { /* Regular keyword table */
- s2[n2++] = s[i].kwd; /* Copy pointers to visible ones */
- } else { /* Switches */
- ckmakmsg(tmpbuf, /* Make a copy that shows ":" if */
- TMPBUFSIZ, /* the switch takes an argument. */
- s[i].kwd,
- (s[i].flgs & CM_ARG) ? ":" : "",
- NULL,
- NULL
- );
- makestr(&(s2[n2]),tmpbuf);
- if (s[i].flgs & CM_ARG) j++;
- n2++;
- }
- if (j > width)
- width = j;
- }
- /* Column width */
- n = n2;
- }
- if (s2 && (b = (char *) malloc(cmd_cols + 1))) { /* Make a line buffer */
- char * bx;
- bx = b + cmd_cols;
- width += (int)strlen(pre) + (int)strlen(post) + 2;
- cols = cmd_cols / width; /* How many columns? */
- if (cols < 1) cols = 1;
- height = n / cols; /* How long is each column? */
- if (n % cols) height++; /* Add one for remainder, if any */
-
- for (i = 0; i < height; i++) { /* Loop for each row */
- for (j = 0; j < cmd_cols; j++) /* First fill row with blanks */
- b[j] = SP;
- for (j = 0; j < cols; j++) { /* Loop for each column in row */
- k = i + (j * height); /* Index of next keyword */
- if (k < n) { /* In range? */
- pa = pre;
- px = post;
- p = s2[k]; /* Point to verb name */
- q = b + (j * width) + 1; /* Where to copy it to */
- while ((q < bx) && (*q++ = *pa++)) ; /* Copy prefix */
- q--; /* Back up over NUL */
- while ((q < bx) && (*q++ = *p++)) ; /* Copy filename */
- q--; /* Back up over NUL */
- while ((q < bx) && (*q++ = *px++)) ; /* Copy suffix */
- if (j < cols - 1) {
- q--;
- *q = SP; /* Replace the space */
- }
- }
- }
- p = b + cmd_cols - 1; /* Last char in line */
- while (*p-- == SP) ; /* Trim */
- *(p+2) = NUL;
- printf("%s\n",b); /* Print the line */
- if (++lc > (cmd_rows - 2)) { /* Screen full? */
- if (!askmore()) /* Do more-prompting... */
- goto xkwdhelp;
- else
- lc = 0;
- }
- }
- /* printf("\n"); */ /* Blank line at end of report */
- } else { /* Malloc failure, no columns */
- for (i = 0; i < n; i++) {
- if (s[i].flgs & CM_INV) /* Use original keyword table */
- continue; /* skipping invisible entries */
- printf("%s%s%s\n",pre,s[i].kwd,post);
- if (++lc > (cmd_rows - 2)) { /* Screen full? */
- if (!askmore()) /* Do more-prompting... */
- goto xkwdhelp;
- else
- lc = 0;
- }
- }
- }
- xkwdhelp:
- if (xhlp & 4) {
- if (tmpbuf) free((char *)tmpbuf);
- for (i = 0; i < n; i++)
- if (s2[i]) free(s2[i]);
- }
- if (s2) free(s2); /* Free array copy */
- if (b) free(b); /* Free line buffer */
- return;
-}
-
-/* X F I L H E L P -- Given a file list, print names in columns. */
-/*
- Call with:
- n - number of entries
- pre - prefix to add to each filename
- post - suffix to add to each filename
- off - offset on first screenful, allowing room for introductory text
- cmdirflg - 1 if only directory names should be listed, 0 to list all files
- fs - call fileselect() to decide whether to include each file.
- The rest of the args are the same as for fileselect().
-
- Arranges filenames in columns with width based on longest filename.
- Does "more?" prompting at end of screen.
- Uses global cmd_rows and cmd_cols for screen size.
-*/
-
-int
-#ifdef CK_ANSIC
-xfilhelp(
- int n, char *pre, char *post, int off, int cmdirflag,
- int fs, char *sa, char *sb, char *sna, char *snb,
- CK_OFF_T minsiz, CK_OFF_T maxsiz,
- int nbu, int nxlist,
- char ** xlist
-)
-#else
-xfilhelp(n,pre,post,off,cmdirflg,
- fs,sa,sb,sna,snb,minsiz,maxsiz,nbu,nxlist,xlist)
- int n, off; char *pre, *post; int cmdirflg;
- int fs; char *sa,*sb,*sna,*snb; CK_OFF_T minsiz,maxsiz;
- int nbu,nxlist; char ** xlist;
-#endif /* CK_ANSIC */
- {
- char filbuf[CKMAXPATH + 1]; /* Temp buffer for one filename */
- int width = 0;
- int cols, height, i, j, k, lc, n2 = 0, rc = 0, itsadir = 0;
- char *b = NULL, *p, *q;
- char *pa, *px;
- char **s2 = NULL;
-#ifdef VMS
- char * cdp = zgtdir();
-#endif /* VMS */
-
- if (n < 1) return(0);
- if (off < 0) off = 0; /* Offset for first page */
- if (!pre) pre = ""; /* Handle null string pointers */
- if (!post) post = "";
-
- lc = off; /* Screen-line counter */
-
- if ((s2 = (char **) malloc(n * sizeof(char *)))) {
- for (i = 0; i < n; i++) { /* Loop through filenames */
- itsadir = 0;
- s2[i] = NULL; /* Initialize each pointer to NULL */
- znext(filbuf); /* Get next filename */
- if (!filbuf[0]) /* Shouldn't happen */
- break;
-#ifdef COMMENT
- itsadir = isdir(filbuf); /* Is it a directory? */
- if (cmdirflg && !itsadir) /* No, listing directories only? */
- continue; /* So skip this one. */
-#endif /* COMMENT */
- if (fs) if (fileselect(filbuf,
- sa,sb,sna,snb,
- minsiz,maxsiz,nbu,nxlist,xlist) < 1) {
- continue;
- }
-#ifdef VMS
- ckstrncpy(filbuf,zrelname(filbuf,cdp),CKMAXPATH);
-#endif /* VMS */
- j = strlen(filbuf);
-#ifndef VMS
- if (itsadir && j < CKMAXPATH - 1 && j > 0) {
- if (filbuf[j-1] != dirsep) {
- filbuf[j++] = dirsep;
- filbuf[j] = NUL;
- }
- }
-#endif /* VMS */
- if (!(s2[n2] = malloc(j+1))) {
- printf("?Memory allocation failure\n");
- rc = -9;
- goto xfilhelp;
- }
- if (j <= CKMAXPATH) {
- strcpy(s2[n2],filbuf);
- n2++;
- } else {
- printf("?Name too long - %s\n", filbuf);
- rc = -9;
- goto xfilhelp;
- }
- if (j > width) /* Get width of widest one */
- width = j;
- }
- n = n2; /* How many we actually got */
- }
- sh_sort(s2,NULL,n,0,0,filecase); /* Alphabetize the list */
-
- rc = 1;
- if (s2 && (b = (char *) malloc(cmd_cols + 1))) { /* Make a line buffer */
- char * bx;
- bx = b + cmd_cols;
- width += (int)strlen(pre) + (int)strlen(post) + 2;
- cols = cmd_cols / width; /* How many columns? */
- if (cols < 1) cols = 1;
- height = n / cols; /* How long is each column? */
- if (n % cols) height++; /* Add one for remainder, if any */
-
- for (i = 0; i < height; i++) { /* Loop for each row */
- for (j = 0; j < cmd_cols; j++) /* First fill row with blanks */
- b[j] = SP;
- for (j = 0; j < cols; j++) { /* Loop for each column in row */
- k = i + (j * height); /* Index of next filename */
- if (k < n) { /* In range? */
- pa = pre;
- px = post;
- p = s2[k]; /* Point to filename */
- q = b + (j * width) + 1; /* and destination */
- while ((q < bx) && (*q++ = *pa++)) ; /* Copy prefix */
- q--; /* Back up over NUL */
- while ((q < bx) && (*q++ = *p++)) ; /* Copy filename */
- q--; /* Back up over NUL */
- while ((q < bx) && (*q++ = *px++)) ; /* Copy suffix */
- if (j < cols - 1) {
- q--;
- *q = SP; /* Replace the space */
- }
- }
- }
- p = b + cmd_cols - 1; /* Last char in line */
- while (*p-- == SP) ; /* Trim */
- *(p+2) = NUL;
- printf("%s\n",b); /* Print the line */
- if (++lc > (cmd_rows - 2)) { /* Screen full? */
- if (!askmore()) { /* Do more-prompting... */
- rc = 0;
- goto xfilhelp;
- } else
- lc = 0;
- }
- }
- printf("\n"); /* Blank line at end of report */
- goto xfilhelp;
- } else { /* Malloc failure, no columns */
- for (i = 0; i < n; i++) {
- znext(filbuf);
- if (!filbuf[0]) break;
- printf("%s%s%s\n",pre,filbuf,post);
- if (++lc > (cmd_rows - 2)) { /* Screen full? */
- if (!askmore()) { /* Do more-prompting... */
- rc = 0;
- goto xfilhelp;
- } else lc = 0;
- }
- }
-xfilhelp:
- if (b) free(b);
- for (i = 0; i < n2; i++)
- if (s2[i]) free(s2[i]);
- if (s2) free((char *)s2);
- return(rc);
- }
-}
-
-/*
- Simpler front end for xfilhelp() with shorter arg list when no
- file selection is needed.
-*/
-int
-filhelp(n,pre,post,off,cmdirflg) int n, off; char *pre, *post; int cmdirflg; {
- return(xfilhelp(n,pre,post,off,cmdirflg,
- 0,NULL,NULL,NULL,NULL,
- (CK_OFF_T)0,(CK_OFF_T)0,0,0,(char **)NULL));
-}
-
-/* C M S E T U P -- Set up command buffers */
-
-#ifdef DCMDBUF
-int
-cmsetup() {
- if (!(cmdbuf = malloc(CMDBL + 4))) return(-1);
- if (!(savbuf = malloc(CMDBL + 4))) return(-1);
- savbuf[0] = '\0';
- if (!(prevcmd = malloc(CMDBL + 4))) return(-1);
- prevcmd[0] = '\0';
- if (!(atmbuf = malloc(ATMBL + 4))) return(-1);
- if (!(atxbuf = malloc(CMDBL + 4))) return(-1);
- if (!(atybuf = malloc(ATMBL + 4))) return(-1);
- if (!(filbuf = malloc(ATMBL + 4))) return(-1);
- if (!(cmprom = malloc(PROMPTL + 4))) return(-1);
- if (!(cmprxx = malloc(PROMPTL + 4))) return(-1);
-#ifdef CK_RECALL
- cmrini(cm_recall);
-#endif /* CK_RECALL */
- return(0);
-}
-#endif /* DCMDBUF */
-
-/* C M S E T P -- Set the program prompt. */
-
-VOID
-cmsetp(s) char *s; {
- if (!s) s = "";
- ckstrncpy(cmprxx,s,PROMPTL);
- psetf = 1; /* Flag that prompt has been set. */
-}
-
-/* C M S A V P -- Save a copy of the current prompt. */
-
-VOID
-#ifdef CK_ANSIC
-cmsavp(char s[], int n)
-#else
-cmsavp(s,n) char s[]; int n;
-#endif /* CK_ANSIC */
-/* cmsavp */ {
- if (psetf) /* But not if no prompt is set. */
- ckstrncpy(s,cmprxx,n);
-}
-
-char *
-cmgetp() {
- return(cmprxx);
-}
-
-int
-cmgbrk() {
- return(brkchar);
-}
-
-int
-cmgkwflgs() {
- return(cmkwflgs);
-}
-
-/* P R O M P T -- Issue the program prompt. */
-
-VOID
-prompt(f) xx_strp f; {
- char *sx, *sy; int n;
-#ifdef CK_SSL
- extern int ssl_active_flag, tls_active_flag;
-#endif /* CK_SSL */
-#ifdef OS2
- extern int display_demo;
-
- /* If there is a demo screen to be displayed, display it */
- if (display_demo && xcmdsrc == 0) {
- demoscrn(VCMD);
- display_demo = 0;
- }
-#endif /* OS2 */
-
- if (psetf == 0) /* If no prompt set, set default. */
- cmsetp(dfprom);
-
- sx = cmprxx; /* Unevaluated copy */
- if (f) { /* If conversion function given */
- sy = cmprom; /* Evaluate it */
-#ifdef COMMENT
- debug(F101,"prompt sx","",sx);
- debug(F101,"prompt sy","",sy);
-#endif /* COMMENT */
- n = PROMPTL;
- if ((*f)(sx,&sy,&n) < 0) /* If evaluation failed */
- sx = cmprxx; /* revert to unevaluated copy */
- else if (!*cmprom) /* ditto if it came up empty */
- sx = cmprxx;
- else
- sx = cmprom;
- } else
- ckstrncpy(cmprom,sx,PROMPTL);
- cmprom[PROMPTL-1] = NUL;
- if (!*sx) /* Don't print if empty */
- return;
-
-#ifdef OSK
- fputs(sx, stdout);
-#else
-#ifdef MAC
- printf("%s", sx);
-#else
-#ifdef IKSD
- if (inserver) { /* Print the prompt. */
- ttoc(CR); /* If TELNET Server */
- ttoc(NUL); /* must folloW CR by NUL */
- printf("%s",sx);
- } else
-#endif /* IKSD */
- printf("\r%s",sx);
-#ifdef CK_SSL
- if (!(ssl_active_flag || tls_active_flag))
-#endif /* CK_SSL */
- fflush(stdout); /* Now! */
-#endif /* MAC */
-#endif /* OSK */
-}
-
-#ifndef NOSPL
-VOID
-pushcmd(s) char * s; { /* For use with IF command. */
- if (!s) s = np;
- ckstrncpy(savbuf,s,CMDBL); /* Save the dependent clause, */
- cmres(); /* and clear the command buffer. */
- debug(F110, "pushcmd savbuf", savbuf, 0);
-}
-
-VOID
-pushqcmd(s) char * s; { /* For use with ELSE command. */
- char c, * p = savbuf; /* Dest */
- if (!s) s = np; /* Source */
- while (*s) { /* Get first nonwhitespace char */
- if (*s != SP)
- break;
- else
- s++;
- }
- if (*s != '{') { /* If it's not "{" */
- pushcmd(s); /* do regular pushcmd */
- return;
- }
- while ((c = *s++)) { /* Otherwise insert quotes */
- if (c == CMDQ)
- *p++ = CMDQ;
- *p++ = c;
- }
- cmres(); /* and clear the command buffer. */
- debug(F110, "pushqcmd savbuf", savbuf, 0);
-}
-#endif /* NOSPL */
-
-#ifdef COMMENT
-/* no longer used... */
-VOID
-popcmd() {
- ckstrncpy(cmdbuf,savbuf,CMDBL); /* Put back the saved material */
- *savbuf = '\0'; /* and clear the save buffer */
- cmres();
-}
-#endif /* COMMENT */
-
-/* C M R E S -- Reset pointers to beginning of command buffer. */
-
-VOID
-cmres() {
- inword = 0; /* We're not in a word */
- cc = 0; /* Character count is zero */
-
-/* Initialize pointers */
-
- pp = cmdbuf; /* Beginning of current field */
- bp = cmdbuf; /* Current position within buffer */
- np = cmdbuf; /* Where to start next field */
-
- cmfldflgs = 0;
- cmflgs = -5; /* Parse not yet started. */
- ungw = 0; /* Don't need to unget a word. */
-}
-
-/* C M I N I -- Clear the command and atom buffers, reset pointers. */
-
-/*
-The argument specifies who is to echo the user's typein --
- 1 means the cmd package echoes
- 0 somebody else (system, front end, terminal) echoes
-*/
-VOID
-cmini(d) int d; {
-#ifdef DCMDBUF
- if (!atmbuf)
- if (cmsetup()<0)
- fatal("fatal error: unable to allocate command buffers");
-#endif /* DCMDBUF */
-#ifdef USE_MEMCPY
- memset(cmdbuf,0,CMDBL);
- memset(atmbuf,0,ATMBL);
-#else
- for (bp = cmdbuf; bp < cmdbuf+CMDBL; bp++) *bp = NUL;
- for (bp = atmbuf; bp < atmbuf+ATMBL; bp++) *bp = NUL;
-#endif /* USE_MEMCPY */
-
- *atmbuf = *savbuf = *atxbuf = *atybuf = *filbuf = NUL;
- blocklvl = 0; /* Block level is 0 */
- linebegin = 1; /* At the beginning of a line */
- dpx = d; /* Global copy of the echo flag */
- debug(F101,"cmini dpx","",dpx);
- crflag = 0; /* Reset flags */
- qmflag = 0;
- esflag = 0;
-#ifdef CK_RECALL
- no_recall = 0; /* Start out with recall enabled */
-#endif /* CK_RECALL */
- cmres(); /* Sets bp etc */
- newcmd = 1; /* See addcmd() */
-}
-
-#ifndef NOSPL
-/*
- The following bits are to allow the command package to call itself
- in the middle of a parse. To do this, begin by calling cmpush, and
- end by calling cmpop. As you can see, this is rather expensive.
-*/
-#ifdef DCMDBUF
-struct cmp {
- int i[5]; /* stack for integers */
- char *c[3]; /* stack for pointers */
- char *b[8]; /* stack for buffer contents */
-};
-struct cmp *cmp = 0;
-#else
-int cmp_i[CMDDEP+1][5]; /* Stack for integers */
-char *cmp_c[CMDDEP+1][5]; /* for misc pointers */
-char *cmp_b[CMDDEP+1][7]; /* for buffer contents pointers */
-#endif /* DCMDBUF */
-
-int cmddep = -1; /* Current stack depth */
-
-int
-cmpush() { /* Save the command environment */
- char *cp; /* Character pointer */
-
- if (cmddep >= CMDDEP) /* Enter a new command depth */
- return(-1);
- cmddep++;
- debug(F101,"&cmpush to depth","",cmddep);
-
-#ifdef DCMDBUF
- /* allocate memory for cmp if not already done */
- if (!cmp && !(cmp = (struct cmp *) malloc(sizeof(struct cmp)*(CMDDEP+1))))
- fatal("cmpush: no memory for cmp");
- cmp[cmddep].i[0] = cmflgs; /* First do the global ints */
- cmp[cmddep].i[1] = cmfsav;
- cmp[cmddep].i[2] = atxn;
- cmp[cmddep].i[3] = ungw;
-
- cmp[cmddep].c[0] = bp; /* Then the global pointers */
- cmp[cmddep].c[1] = pp;
- cmp[cmddep].c[2] = np;
-#else
- cmp_i[cmddep][0] = cmflgs; /* First do the global ints */
- cmp_i[cmddep][1] = cmfsav;
- cmp_i[cmddep][2] = atxn;
- cmp_i[cmddep][3] = ungw;
-
- cmp_c[cmddep][0] = bp; /* Then the global pointers */
- cmp_c[cmddep][1] = pp;
- cmp_c[cmddep][2] = np;
-#endif /* DCMDBUF */
-
- /* Now the buffers themselves. A lot of repititious code... */
-
-#ifdef DCMDBUF
- cp = malloc((int)strlen(cmdbuf)+1); /* 0: Command buffer */
- if (cp) strcpy(cp,cmdbuf);
- cmp[cmddep].b[0] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(savbuf)+1); /* 1: Save buffer */
- if (cp) strcpy(cp,savbuf);
- cmp[cmddep].b[1] = cp;
- if (cp == NULL) return(-1);
-
- cmp[cmddep].b[2] = NULL;
-
- cp = malloc((int)strlen(atmbuf)+1); /* 3: Atom buffer */
- if (cp) strcpy(cp,atmbuf);
- cmp[cmddep].b[3] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(atxbuf)+1); /* 4: Expansion buffer */
- if (cp) strcpy(cp,atxbuf);
- cmp[cmddep].b[4] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(atybuf)+1); /* 5: Atom buffer copy */
- if (cp) strcpy(cp,atybuf);
- cmp[cmddep].b[5] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(filbuf)+1); /* 6: File name buffer */
- if (cp) strcpy(cp,filbuf);
- cmp[cmddep].b[6] = cp;
- if (cp == NULL) return(-1);
-#else
- cp = malloc((int)strlen(cmdbuf)+1); /* 0: Command buffer */
- if (cp) strcpy(cp,cmdbuf);
- cmp_b[cmddep][0] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(savbuf)+1); /* 1: Save buffer */
- if (cp) strcpy(cp,savbuf);
- cmp_b[cmddep][1] = cp;
- if (cp == NULL) return(-1);
-
- cmp_b[cmddep][2] = NULL;
-
- cp = malloc((int)strlen(atmbuf)+1); /* 3: Atom buffer */
- if (cp) strcpy(cp,atmbuf);
- cmp_b[cmddep][3] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(atxbuf)+1); /* 4: Expansion buffer */
- if (cp) strcpy(cp,atxbuf);
- cmp_b[cmddep][4] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(atybuf)+1); /* 5: Atom buffer copy */
- if (cp) strcpy(cp,atybuf);
- cmp_b[cmddep][5] = cp;
- if (cp == NULL) return(-1);
-
- cp = malloc((int)strlen(filbuf)+1); /* 6: File name buffer */
- if (cp) strcpy(cp,filbuf);
- cmp_b[cmddep][6] = cp;
- if (cp == NULL) return(-1);
-#endif /* DCMDBUF */
-
- cmini(dpx); /* Initize the command parser */
- return(0);
-}
-
-int
-cmpop() { /* Restore the command environment */
- if (cmddep < 0) {
- debug(F100,"&cmpop called from top level","",0);
- return(-1); /* Don't pop too much! */
- }
-#ifdef DCMDBUF
- cmflgs = cmp[cmddep].i[0]; /* First do the global ints */
- cmfsav = cmp[cmddep].i[1];
- atxn = cmp[cmddep].i[2];
- ungw = cmp[cmddep].i[3];
-
- bp = cmp[cmddep].c[0]; /* Then the global pointers */
- pp = cmp[cmddep].c[1];
- np = cmp[cmddep].c[2];
-#else
- cmflgs = cmp_i[cmddep][0]; /* First do the global ints */
- cmfsav = cmp_i[cmddep][1];
- atxn = cmp_i[cmddep][2];
- ungw = cmp_i[cmddep][3];
-
- bp = cmp_c[cmddep][0]; /* Then the global pointers */
- pp = cmp_c[cmddep][1];
- np = cmp_c[cmddep][2];
-#endif /* DCMDBUF */
-
- /* Now the buffers themselves. */
- /* Note: strncpy(), not ckstrncpy() -- Here we WANT the NUL padding... */
-
-#ifdef DCMDBUF
- if (cmp[cmddep].b[0]) {
-
- strncpy(cmdbuf,cmp[cmddep].b[0],CMDBL); /* 0: Command buffer */
- free(cmp[cmddep].b[0]);
- cmp[cmddep].b[0] = NULL;
- }
- if (cmp[cmddep].b[1]) {
- strncpy(savbuf,cmp[cmddep].b[1],CMDBL); /* 1: Save buffer */
- free(cmp[cmddep].b[1]);
- cmp[cmddep].b[1] = NULL;
- }
- if (cmp[cmddep].b[3]) {
- strncpy(atmbuf,cmp[cmddep].b[3],ATMBL); /* 3: Atomic buffer! */
- free(cmp[cmddep].b[3]);
- cmp[cmddep].b[3] = NULL;
- }
- if (cmp[cmddep].b[4]) {
- strncpy(atxbuf,cmp[cmddep].b[4],ATMBL); /* 4: eXpansion buffer */
- free(cmp[cmddep].b[4]);
- cmp[cmddep].b[4] = NULL;
- }
- if (cmp[cmddep].b[5]) {
- strncpy(atybuf,cmp[cmddep].b[5],ATMBL); /* 5: Atom buffer copY */
- free(cmp[cmddep].b[5]);
- cmp[cmddep].b[5] = NULL;
- }
- if (cmp[cmddep].b[6]) {
- strncpy(filbuf,cmp[cmddep].b[6],ATMBL); /* 6: Filename buffer */
- free(cmp[cmddep].b[6]);
- cmp[cmddep].b[6] = NULL;
- }
-#else
- if (cmp_b[cmddep][0]) {
- strncpy(cmdbuf,cmp_b[cmddep][0],CMDBL); /* 0: Command buffer */
- free(cmp_b[cmddep][0]);
- cmp_b[cmddep][0] = NULL;
- }
- if (cmp_b[cmddep][1]) {
- strncpy(savbuf,cmp_b[cmddep][1],CMDBL); /* 1: Save buffer */
- free(cmp_b[cmddep][1]);
- cmp_b[cmddep][1] = NULL;
- }
- if (cmp_b[cmddep][3]) {
- strncpy(atmbuf,cmp_b[cmddep][3],ATMBL); /* 3: Atomic buffer! */
- free(cmp_b[cmddep][3]);
- cmp_b[cmddep][3] = NULL;
- }
- if (cmp_b[cmddep][4]) {
- strncpy(atxbuf,cmp_b[cmddep][4],ATMBL); /* 4: eXpansion buffer */
- free(cmp_b[cmddep][4]);
- cmp_b[cmddep][4] = NULL;
- }
- if (cmp_b[cmddep][5]) {
- strncpy(atybuf,cmp_b[cmddep][5],ATMBL); /* 5: Atom buffer copY */
- free(cmp_b[cmddep][5]);
- cmp_b[cmddep][5] = NULL;
- }
- if (cmp_b[cmddep][6]) {
- strncpy(filbuf,cmp_b[cmddep][6],ATMBL); /* 6: Filename buffer */
- free(cmp_b[cmddep][6]);
- cmp_b[cmddep][6] = NULL;
- }
-#endif /* DCMDBUF */
-
- cmddep--; /* Rise, rise */
- debug(F101,"&cmpop to depth","",cmddep);
- return(cmddep);
-}
-#endif /* NOSPL */
-
-#ifdef COMMENT
-VOID /* Not used */
-stripq(s) char *s; { /* Function to strip '\' quotes */
- char *t;
- while (*s) {
- if (*s == CMDQ) {
- for (t = s; *t != '\0'; t++) *t = *(t+1);
- }
- s++;
- }
-}
-#endif /* COMMENT */
-
-/* Convert tabs to spaces, one for one */
-VOID
-untab(s) char *s; {
- while (*s) {
- if (*s == HT) *s = SP;
- s++;
- }
-}
-
-/* C M N U M -- Parse a number in the indicated radix */
-
-/*
- The radix is specified in the arg list.
- Parses unquoted numeric strings in the given radix.
- Parses backslash-quoted numbers in the radix indicated by the quote:
- \nnn = \dnnn = decimal, \onnn = octal, \xnn = Hexadecimal.
- If these fail, then if a preprocessing function is supplied, that is applied
- and then a second attempt is made to parse an unquoted decimal string.
- And if that fails, the preprocessed string is passed to an arithmetic
- expression evaluator.
-
- Returns:
- -3 if no input present when required,
- -2 if user typed an illegal number,
- -1 if reparse needed,
- 0 otherwise, with argument n set to the number that was parsed
-*/
-/* This is the traditional cmnum() that gets an int */
-int
-cmnum(xhlp,xdef,radix,n,f) char *xhlp, *xdef; int radix, *n; xx_strp f; {
- CK_OFF_T z = (CK_OFF_T)0, check;
- int x;
- x = cmnumw(xhlp,xdef,radix,&z,f);
- *n = z;
- check = *n;
- if (check != z) {
- printf("?Magnitude of result too large for integer - %s\n",ckfstoa(z));
- return(-9);
- }
- return(x);
-}
-
-/*
- This is the new cmnum() that gets a "wide" result, whatever CK_OFF_T
- is defined to be, normally 32 or 64 bits, depending on the platform.
- fdc, 24 Dec 2005.
-*/
-int
-cmnumw(xhlp,xdef,radix,n,f)
- char *xhlp, *xdef; int radix; CK_OFF_T *n; xx_strp f; {
- int x; char *s, *zp, *zq;
-#ifdef COMMENT
- char lbrace, rbrace;
-#endif /* COMMENT */
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
-
-#ifdef COMMENT
- if (cmfldflgs & 1) {
- lbrace = '(';
- rbrace = ')';
- } else {
- lbrace = '{';
- rbrace = '}';
- }
-#endif /* COMMENT */
-
- if (radix != 10 && radix != 8) { /* Just do bases 8 and 10 */
- printf("cmnum: illegal radix - %d\n",radix);
- return(-2);
- } /* Easy to add others but there has never been a need for it. */
- x = cmfld(xhlp,xdef,&s,(xx_strp)0);
- debug(F101,"cmnum: cmfld","",x);
- if (x < 0) return(x); /* Parse a field */
- zp = atmbuf;
-/*
- Edit 192 - Allow any number field to be braced. This lets us include
- spaces in expressions, but perhaps more important lets us have user-defined
- functions in numeric fields.
-*/
- zp = brstrip(zp); /* Strip braces */
- if (cmfldflgs & 1 && *zp == '(') { /* Parens too.. */
- x = (int) strlen(atmbuf);
- if (x > 0) {
- if (*(atmbuf+x-1) == ')') {
- *(atmbuf+x-1) = NUL;
- zp++;
- }
- }
- }
- if (chknum(zp)) { /* Check for number */
- if (radix == 8) { /* If it's supposed to be octal */
- zp = ckradix(zp,8,10); /* convert to decimal */
- if (!zp) return(-2);
- if (!strcmp(zp,"-1")) return(-2);
- }
- errno = 0; /* Got one, we're done. */
- *n = ckatofs(zp);
- if (errno) {
- perror(zp);
- return(-9);
- }
- debug(F101,"cmnum 1st chknum ok","",*n);
- return(0);
- } else if ((x = xxesc(&zp)) > -1) { /* Check for backslash escape */
-
-#ifndef OS2
- *n = x;
-#else
- *n = wideresult;
-#endif /* OS2 */
-
- debug(F101,"cmnum xxesc ok","",*n);
- return(*zp ? -2 : 0);
- } else if (f) { /* If conversion function given */
- zq = atxbuf; /* Try that */
- atxn = CMDBL;
- if ((*f)(zp,&zq,&atxn) < 0) /* Convert */
- return(-2);
- zp = atxbuf;
- }
- debug(F110,"cmnum zp 1",zp,0);
- if (!*zp) zp = xdef; /* Result empty, substitute default */
- debug(F110,"cmnum zp 2",zp,0);
- if (chknum(zp)) { /* Check again for decimal number */
- if (radix == 8) { /* If it's supposed to be octal */
- zp = ckradix(zp,8,10); /* convert to decimal */
- if (!zp) return(-2);
- if (!strcmp(zp,"-1")) return(-2);
- }
- errno = 0;
- *n = ckatofs(zp);
- if (errno) {
- perror(zp);
- return(-9);
- }
- debug(F101,"cmnum 2nd chknum ok","",*n);
- return(0);
-#ifndef NOSPL
- } else if ((x = xxesc(&zp)) > -1) { /* Check for backslash escape */
-#ifndef OS2
- *n = x;
-#else
- *n = wideresult;
-#endif /* OS2 */
- debug(F101,"cmnum xxesc 2 ok","",*n);
- return(*zp ? -2 : 0);
- } else if (f) { /* Not numeric, maybe an expression */
- char * p;
- p = evala(zp);
- if (chknum(p)) {
- if (radix == 8) { /* If it's supposed to be octal */
- zp = ckradix(zp,8,10); /* convert to decimal */
- if (!zp) return(-2);
- if (!strcmp(zp,"-1")) return(-2);
- }
- errno = 0;
- *n = ckatofs(p);
- if (errno) {
- perror(p);
- return(-9);
- }
- debug(F101,"cmnum exp eval ok","",*n);
- return(0);
- } else return(-2);
-#endif /* NOSPL */
- } else { /* Not numeric */
- return(-2);
- }
-}
-
-#ifdef CKCHANNELIO
-extern int z_error;
-#endif /* CKCHANNELIO */
-
-/* C M O F I -- Parse the name of an output file */
-
-/*
- Depends on the external function zchko(); if zchko() not available, use
- cmfld() to parse output file names.
-
- Returns:
- -9 like -2, except message already printed,
- -3 if no input present when required,
- -2 if permission would be denied to create the file,
- -1 if reparse needed,
- 0 or 1 if file can be created, with xp pointing to name.
- 2 if given the name of an existing directory.
-*/
-int
-cmofi(xhlp,xdef,xp,f) char *xhlp, *xdef, **xp; xx_strp f; {
- int x; char *s, *zq;
-#ifdef DOCHKVAR
- int tries;
-#endif /* DOCHKVAR */
-#ifdef DTILDE
- char *dirp;
-#endif /* DTILDE */
-
- cmfldflgs = 0;
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
-
- if (*xhlp == NUL) xhlp = "Output file";
- *xp = "";
-
- debug(F110,"cmofi xdef",xdef,0);
- x = cmfld(xhlp,xdef,&s,(xx_strp)0);
- debug(F111,"cmofi cmfld returns",s,x);
- if (x < 0)
- return(x);
-
- s = brstrip(s); /* Strip enclosing braces */
- debug(F110,"cmofi 1.5",s,0);
-
-#ifdef DOCHKVAR
- tries = 0;
- {
- char *p = s;
- /*
- This is really ugly. If we skip conversion the first time through,
- then variable names like \%a will be used as filenames (e.g. creating
- a file called %A in the root directory). If we DON'T skip conversion
- the first time through, then single backslashes used as directory
- separators in filenames will be misinterpreted as variable lead-ins.
- So we prescan to see if it has any variable references. But this
- module is not supposed to know anything about variables, functions,
- etc, so this code does not really belong here, but rather it should
- be at the same level as zzstring().
- */
-/*
- Hmmm, this looks a lot like chkvar() except it that includes \nnn number
- escapes. But why? This makes commands like "mkdir c:\123" impossible.
- And in fact, "mkdir c:\123" creates a directory called "c:{". What's worse,
- rmdir(), which *does* call chkvar(), won't let us remove it. So let's at
- least try making cmofi() symmetrical with cmifi()...
-*/
-#ifdef COMMENT
- char * q;
- while ( (tries == 0) && (p = strchr(p,CMDQ)) ) {
- q = *(p+1); /* Char after backslash */
- if (!q) /* None, quit */
- break;
- if (isupper(q)) /* If letter, convert to lowercase */
- q = tolower(q);
- if (isdigit(q)) { /* If it's a digit, */
- tries = 1; /* assume it's a backslash code */
- break;
- }
- switch (q) {
- case CMDQ: /* Double backslash */
- tries = 1; /* so call the conversion function */
- break;
- case '%': /* Variable or array reference */
- case '&': /* must be followed by letter */
- if (isalpha(*(p+2)) || (*(p+2) >= '0' && *(p+2) <= '9'))
- tries = 1;
- break;
- case 'm': case 'v': case '$': /* \m(), \v(), \$() */
- if (*(p+2) == '(')
- if (strchr(p+2,')'))
- tries = 1;
- break;
- case 'f': /* \Fname() */
- if (strchr(p+2,'('))
- if (strchr(p+2,')'))
- tries = 1;
- break;
- case '{': /* \{...} */
- if (strchr(p+2,'}'))
- tries = 1;
- break;
- case 'd': case 'o': /* Decimal or Octal number */
- if (isdigit(*(p+2)))
- tries = 1;
- break;
- case 'x': /* Hex number */
- if (isdigit(*(p+2)) ||
- ((*(p+2) >= 'a' && *(p+2) <= 'f') ||
- ((*(p+2) >= 'A' && *(p+2) <= 'F'))))
- tries = 1;
- default:
- break;
- }
- p++;
- }
-#else
-#ifndef NOSPL
- if (f) { /* If a conversion function is given */
- char *s = p; /* See if there are any variables in */
- while (*s) { /* the string and if so, expand them */
- if (chkvar(s)) {
- tries = 1;
- break;
- }
- s++;
- }
- }
-#endif /* NOSPL */
-#endif /* COMMENT */
- }
-#ifdef OS2
-o_again:
-#endif /* OS2 */
- if (tries == 1)
-#endif /* DOCHKVAR */
- if (f) { /* If a conversion function is given */
- zq = atxbuf; /* do the conversion. */
- atxn = CMDBL;
- if ((x = (*f)(s,&zq,&atxn)) < 0)
- return(-2);
- s = atxbuf;
- if (!*s) /* Result empty, substitute default */
- s = xdef;
- }
- debug(F111,"cmofi 2",s,x);
-
-#ifdef DTILDE
- dirp = tilde_expand(s); /* Expand tilde, if any, */
- if (*dirp != '\0') { /* right in the atom buffer. */
- if (setatm(dirp,1) < 0) {
- printf("?Name too long\n");
- return(-9);
- }
- }
- s = atmbuf;
- debug(F110,"cmofi 3",s,0);
-#endif /* DTILDE */
-
- if (iswild(s)) {
- printf("?Wildcards not allowed - %s\n",s);
- return(-2);
- }
- debug(F110,"cmofi 4",s,0);
-
-#ifdef CK_TMPDIR
- /* isdir() function required for this! */
- if (isdir(s)) {
- debug(F110,"cmofi 5: is directory",s,0);
- *xp = s;
- return(2);
- }
-#endif /* CK_TMPDIR */
-
- if (strcmp(s,CTTNAM) && (zchko(s) < 0)) { /* OK to write to console */
-#ifdef COMMENT
-#ifdef OS2
-/*
- We don't try again because we already prescanned the string to see if
- if it contained anything that could be used by zzstring().
-*/
- if (tries++ < 1)
- goto o_again;
-#endif /* OS2 */
-#endif /* COMMENT */
-/*
- Note: there are certain circumstances where zchko() can give a false
- positive, so don't rely on it to catch every conceivable situation in
- which the given output file can't be created. In other words, we print
- a message and fail here if we KNOW the file can't be created. If we
- succeed but the file can't be opened, the code that tries to open the file
- has to print a message.
-*/
- debug(F110,"cmofi 6: failure",s,0);
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",s);
- else
-#endif /* CKROOT */
- printf("?Write permission denied - %s\n",s);
-#ifdef CKCHANNELIO
- z_error = FX_ACC;
-#endif /* CKCHANNELIO */
- return(-9);
- } else {
- debug(F110,"cmofi 7: ok",s,0);
- *xp = s;
- return(x);
- }
-}
-
-/* C M I F I -- Parse the name of an existing file */
-
-/*
- This function depends on the external functions:
- zchki() - Check if input file exists and is readable.
- zxpand() - Expand a wild file specification into a list.
- znext() - Return next file name from list.
- If these functions aren't available, then use cmfld() to parse filenames.
-*/
-/*
- Returns
- -4 EOF
- -3 if no input present when required,
- -2 if file does not exist or is not readable,
- -1 if reparse needed,
- 0 or 1 otherwise, with:
- xp pointing to name,
- wild = 1 if name contains '*' or '?', 0 otherwise.
-*/
-
-#ifdef COMMENT /* This horrible hack has been replaced - see further down */
-/*
- C M I O F I -- Parse an input file OR the name of a nonexistent file.
-
- Use this when an existing file is wanted (so we get help, completion, etc),
- but if a file of the given name does not exist, the name of a new file is
- accepted. For example, with the EDIT command (edit an existing file, or
- create a new file). Returns -9 if file does not exist. It is up to the
- caller to check creatability.
-*/
-static int nomsg = 0;
-int
-cmiofi(xhlp,xdef,xp,wild,f) char *xhlp, *xdef, **xp; int *wild; xx_strp f; {
- int msgsave, x;
- msgsave = nomsg;
- nomsg = 1;
- x = cmifi2(xhlp,xdef,xp,wild,0,NULL,f,0);
- nomsg = msgsave;
- return(x);
-}
-#endif /* COMMENT */
-
-int
-cmifi(xhlp,xdef,xp,wild,f) char *xhlp, *xdef, **xp; int *wild; xx_strp f; {
- return(cmifi2(xhlp,xdef,xp,wild,0,NULL,f,0));
-}
-/*
- cmifip() is called when we want to supply a path or path list to search
- in case the filename that the user gives is (a) not absolute, and (b) can't
- be found as given. The path string can be the name of a single directory,
- or a list of directories separated by the PATHSEP character, defined in
- ckucmd.h. Look in ckuusr.c and ckuus3.c for examples of usage.
-*/
-int
-cmifip(xhlp,xdef,xp,wild,d,path,f)
- char *xhlp,*xdef,**xp; int *wild, d; char * path; xx_strp f; {
- return(cmifi2(xhlp,xdef,xp,wild,0,path,f,0));
-}
-
-/* C M D I R -- Parse a directory name */
-
-/*
- This function depends on the external functions:
- isdir(s) - Check if string s is the name of a directory
- zchki(s) - Check if input file s exists and what type it is.
- If these functions aren't available, then use cmfld() to parse dir names.
-
- Returns
- -9 For all sorts of reasons, after printing appropriate error message.
- -4 EOF
- -3 if no input present when required,
- -2 if out of space or other internal error,
- -1 if reparse needed,
- 0 or 1, with xp pointing to name, if directory specified,
-*/
-int
-cmdir(xhlp,xdef,xp,f) char *xhlp, *xdef, **xp; xx_strp f; {
- int wild;
- return(cmifi2(xhlp,xdef,xp,&wild,0,NULL,f,1));
-}
-
-/* Like CMDIR but includes PATH search */
-
-int
-cmdirp(xhlp,xdef,xp,path,f) char *xhlp, *xdef, **xp; char * path; xx_strp f; {
- int wild;
- return(cmifi2(xhlp,xdef,xp,&wild,0,path,f,1));
-}
-
-/*
- cmifi2() is the base filename parser called by cmifi, cmifip, cmdir, etc.
- Use it directly when you also want to parse a directory or device
- name as an input file, as in the DIRECTORY command. Call with:
- xhlp -- help message on ?
- xdef -- default response
- xp -- pointer to result (in our space, must be copied from here)
- wild -- flag set upon return to indicate if filespec was wild
- d -- 0 to parse files, 1 to parse files or directories
- Add 2 to inhibit following of symlinks.
- path -- search path for files
- f -- pointer to string processing function (e.g. to evaluate variables)
- dirflg -- 1 to parse *only* directories, 0 otherwise
-*/
-int
-cmifi2(xhlp,xdef,xp,wild,d,path,f,dirflg)
- char *xhlp,*xdef,**xp; int *wild, d; char * path; xx_strp f; int dirflg; {
- extern int recursive, diractive, cdactive, dblquo;
- int i, x, itsadir, xc, expanded = 0, nfiles = 0, children = -1;
- int qflag = 0;
- long y;
- CK_OFF_T filesize;
- char *sp = NULL, *zq, *np = NULL;
- char *sv = NULL, *p = NULL;
-#ifdef DTILDE
- char *dirp;
-#endif /* DTILDE */
-
-#ifndef NOPARTIAL
-#ifndef OS2
-#ifdef OSK
- /* This large array is dynamic for OS-9 -- should do for others too... */
- extern char **mtchs;
-#else
-#ifdef UNIX
- /* OK, for UNIX too */
- extern char **mtchs;
-#else
-#ifdef VMS
- extern char **mtchs;
-#else
- extern char *mtchs[];
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* NOPARTIAL */
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
-
-#ifndef NOLASTFILE
- makestr(&tmplastfile,NULL);
-#endif /* NOLASTFILE */
- nzxopts = 0; /* zxpand() options */
- debug(F101,"cmifi d","",d);
- if (d & 2) { /* d & 2 means don't follow symlinks */
- d ^= 2;
- nzxopts = ZX_NOLINKS;
- }
- debug(F101,"cmifi nzxopts","",nzxopts);
- cmfldflgs = 0;
- if (path)
- if (!*path)
- path = NULL;
- if (path) { /* Make a copy we can poke */
- x = strlen(path);
- np = (char *) malloc(x + 1);
- if (np) {
- strcpy(np, path);
- path = sp = np;
- }
- }
- debug(F110,"cmifi2 path",path,0);
-
- ckstrncpy(cmdefault,xdef,CMDEFAULT); /* Copy default */
- xdef = cmdefault;
-
- inword = 0; /* Initialize counts & pointers */
- cc = 0;
- xc = 0;
- *xp = ""; /* Pointer to result string */
- if ((x = cmflgs) != 1) { /* Already confirmed? */
-#ifdef BS_DIRSEP
- dirnamflg = 1;
- x = gtword(0); /* No, get a word */
- dirnamflg = 0;
-#else
- x = gtword(0); /* No, get a word */
-#endif /* BS_DIRSEP */
- } else { /* If so, use default, if any. */
- if (setatm(xdef,1) < 0) {
- printf("?Default name too long\n");
- if (np) free(np);
- return(-9);
- }
- }
- i_path:
- *xp = atmbuf; /* Point to result. */
-
- while (1) {
- xc += cc; /* Count this character. */
- debug(F111,"cmifi gtword",atmbuf,xc);
- debug(F101,"cmifi switch x","",x);
- switch (x) { /* x = gtword() return code */
- case -10:
- if (gtimer() > timelimit) {
-#ifdef IKSD
- if (inserver) {
- printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", timelimit);
- doexit(GOOD_EXIT,0);
- }
-#endif /* IKSD */
- /* if (!quiet) printf("?Timed out\n"); */
- return(-10);
- } else {
- x = gtword(0);
- continue;
- }
- case -9:
- printf("Command or field too long\n");
- case -4: /* EOF */
- case -2: /* Out of space. */
- case -1: /* Reparse needed */
- if (np) free(np);
- return(x);
- case 1: /* CR */
- case 0: /* SP */
- if (xc == 0) /* If no input... */
- *xp = xdef; /* substitute the default */
-#ifndef NOLASTFILE
- makestr(&tmplastfile,*xp); /* Make a copy before bstripping */
-#endif /* #ifndef NOLASTFILE */
- *xp = brstrip(*xp); /* Strip braces */
- if (**xp == NUL) { /* 12 mar 2001 */
- if (np) free(np);
- return(-3);
- }
- debug(F110,"cmifi brstrip",*xp,0);
-#ifndef NOSPL
- if (f) { /* If a conversion function is given */
-#ifdef DOCHKVAR
- char *s = *xp; /* See if there are any variables in */
- int x;
- while (*s) { /* the string and if so, expand them */
- x = chkvar(s);
- /* debug(F111,"cmifi chkvar",*xp,x); */
- if (x) {
-#endif /* DOCHKVAR */
- zq = atxbuf;
- atxn = CMDBL;
- if ((*f)(*xp,&zq,&atxn) < 0) {
- if (np) free(np);
- return(-2);
- }
- *xp = atxbuf;
- if (!atxbuf[0])
- *xp = xdef;
-#ifdef DOCHKVAR
- break;
- }
- s++;
- }
-#endif /* DOCHKVAR */
- }
-#endif /* NOSPL */
- if (**xp == NUL) { /* 12 mar 2001 */
- if (np) free(np);
- return(-3);
- }
-#ifdef DTILDE
- if (dirflg) {
- dirp = tilde_expand(*xp); /* Expand tilde, if any, */
- if (*dirp != '\0') { /* in the atom buffer. */
- if (setatm(dirp,1) < 0) {
- printf("Expanded name too long\n");
- if (np) free(np);
- return(-9);
- }
- }
- *xp = atmbuf;
- debug(F110,"cmifi tilde_expand",*xp,0);
- }
-#endif /* DTILDE */
- if (!sv) { /* Only do this once */
- sv = malloc((int)strlen(*xp)+1); /* Make a safe copy */
- if (!sv) {
- printf("?cmifi: malloc error\n");
- if (np) free(np);
- return(-9);
- }
- strcpy(sv,*xp);
- debug(F110,"cmifi sv",sv,0);
- }
-
-/* This is to get around "cd /" failing because "too many directories match" */
-
- expanded = 0; /* Didn't call zxpand */
-#ifdef datageneral
- debug(F110,"cmifi isdir 1",*xp,0);
- {
- int y; char *s;
- s = *xp;
- y = strlen(s);
- if (y > 1 &&
- (s[y-1] == ':' ||
- s[y-1] == '^' ||
- s[y-1] == '=')
- )
- s[y-1] = NUL;
- }
- debug(F110,"cmifi isdir 2",*xp,0);
-#endif /* datageneral */
-
-#ifdef VMS
- if (dirflg) {
- if (!strcmp(*xp,"..")) { /* For UNIXers... */
- setatm("-",0);
- *xp = atmbuf;
- } else if (!strcmp(*xp,".")) {
- setatm("[]",0);
- *xp = atmbuf;
- }
- }
-#endif /* VMS */
- itsadir = isdir(*xp); /* Is it a directory? */
- debug(F111,"cmifi itsadir",*xp,itsadir);
-#ifdef VMS
- /* If they said "blah" where "blah.dir" is a directory... */
- /* change it to [.blah]. */
- if (!itsadir) {
- char tmpbuf[600];
- int flag = 0; char c, * p;
- p = *xp;
- while ((c = *p++) && !flag)
- if (ckstrchr(".[]:*?<>",c))
- flag = 1;
- debug(F111,"cmifi VMS dirname flag",*xp,flag);
- if (!flag) {
- ckmakmsg(tmpbuf,TMPBUFSIZ,"[.",*xp,"]",NULL);
- itsadir = isdir(tmpbuf);
- if (itsadir) {
- setatm(tmpbuf,0);
- *xp = atmbuf;
- }
- debug(F111,"cmifi VMS dirname flag itsadir",*xp,itsadir);
- }
- } else if (itsadir == 1 && *(xp[0]) == '.' && *(xp[1])) {
- char *p;
- if (p = malloc(cc + 4)) {
- ckmakmsg(p,cc+4,"[",*xp,"]",NULL);
- setatm(p,0);
- *xp = atmbuf;
- debug(F110,"cmdir .foo",*xp,0);
- free(p);
- }
- } else if (itsadir == 2 && !diractive) {
- int x; /* [FOO]BAR.DIR instead of [FOO.BAR] */
- char *p;
- p = malloc(cc + 4);
- if (p) {
- x = cvtdir(*xp,p,ATMBL); /* Convert to [FOO.BAR] */
- if (x > 0) {
- setatm(p,0);
- *xp = atmbuf;
- debug(F110,"cmdir cvtdir",*xp,0);
- }
- free(p);
- }
- }
-#endif /* VMS */
-
- debug(F101,"cmifi dirflg","",dirflg);
- if (dirflg) { /* Parsing a directory name? */
- /* Yes, does it contain wildcards? */
- if (iswild(*xp) ||
- (diractive && (!strcmp(*xp,".") || !strcmp(*xp,"..")))
- ) {
- nzxopts |= ZX_DIRONLY; /* Match only directory names */
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- debug(F111,"cmifi nzxopts 2",*xp,nzxopts);
- y = nzxpand(*xp,nzxopts);
- debug(F111,"cmifi nzxpand 2",*xp,y);
- nfiles = y;
- expanded = 1;
- } else {
-#ifdef VMS
-/*
- This is to allow (e.g.) "cd foo", where FOO.DIR;1 is in the
- current directory.
-*/
- debug(F111,"cmdir itsadir",*xp,itsadir);
- if (!itsadir) {
- char *s;
- int n;
- s = *xp;
- n = strlen(s);
- if (n > 0 &&
-#ifdef COMMENT
- *s != '[' && s[n-1] != ']' &&
- *s != '<' && s[n-1] != '>' &&
-#else
- ckindex("[",s,0,0,1) == 0 &&
- ckindex("<",s,0,0,1) == 0 &&
-#endif /* COMMENT */
- s[n-1] != ':') {
- char * dirbuf = NULL;
- dirbuf = (char *)malloc(n+4);
- if (dirbuf) {
- if (*s == '.')
- ckmakmsg(dirbuf,n+4,"[",s,"]",NULL);
- else
- ckmakmsg(dirbuf,n+4,"[.",s,"]",NULL);
- itsadir = isdir(dirbuf);
- debug(F111,"cmdir dirbuf",dirbuf,itsadir);
- if (itsadir) {
- setatm(dirbuf,0);
- *xp = atmbuf;
- debug(F110,"cmdir new *xp",*xp,0);
- }
- free(dirbuf);
- }
-
-/* This is to allow CDPATH to work in VMS... */
-
- } else if (n > 0) {
- char * p; int i, j, k, d;
- char rb[2] = "]";
- if (p = malloc(x + 8)) {
- ckstrncpy(p,*xp,x+8);
- i = ckindex(".",p,-1,1,1);
- d = ckindex(".dir",p,0,0,0);
- j = ckindex("]",p,-1,1,1);
- if (j == 0) {
- j = ckindex(">",p,-1,1,1);
- rb[0] = '>';
- }
- k = ckindex(":",p,-1,1,1);
- if (i < j || i < k) i = 0;
- if (d < j || d < k) d = 0;
- /* Change [FOO]BAR or [FOO]BAR.DIR */
- /* to [FOO.BAR] */
- if (j > 0 && j < n) {
- p[j-1] = '.';
- if (d > 0) p[d-1] = NUL;
- ckstrncat(p,rb,x+8);
- debug(F110,"cmdir xxx",p,0);
- }
- itsadir = isdir(p);
- debug(F111,"cmdir p",p,itsadir);
- if (itsadir) {
- setatm(p,0);
- *xp = atmbuf;
- debug(F110,"cmdir new *xp",*xp,0);
- }
- free(p);
- }
- }
- }
-#endif /* VMS */
- y = (!itsadir) ? 0 : 1;
- debug(F111,"cmifi y itsadir",*xp,y);
- }
- } else { /* Parsing a filename. */
- debug(F110,"cmifi *xp pre-zxpand",*xp,0);
-#ifndef COMMENT
- nzxopts |= (d == 0) ? ZX_FILONLY : 0; /* So always expand. */
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- y = nzxpand(*xp,nzxopts);
-#else
-/* Here we're trying to fix a problem in which a directory name is accepted */
-/* as a filename, but this breaks too many other things. */
- /* nzxopts = 0; */
- if (!d) {
- if (itsadir & !iswild(*xp)) {
- debug(F100,"cmifi dir when filonly","",0);
- printf("?Not a regular file: \"%s\"\n",*xp);
- if (sv) free(sv);
- if (np) free(np);
- return(-9);
- } else {
- nzxopts |= ZX_FILONLY;
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- y = nzxpand(*xp,nzxopts);
- }
- }
-#endif /* COMMENT */
- nfiles = y;
- debug(F111,"cmifi y nzxpand",*xp,y);
- debug(F111,"cmifi y atmbuf",atmbuf,itsadir);
- expanded = 1;
- }
- /* domydir() calls zxrewind() so we MUST call nzxpand() here */
- if (!expanded && diractive) {
- debug(F110,"cmifi diractive catch-all zxpand",*xp,0);
- nzxopts |= (d == 0) ? ZX_FILONLY : (dirflg ? ZX_DIRONLY : 0);
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- y = nzxpand(*xp,nzxopts);
- debug(F111,"cmifi diractive nzxpand",*xp,y);
- nfiles = y;
- expanded = 1;
- }
- *wild = (iswild(sv) || (y > 1)) && (itsadir == 0);
-
-#ifdef RECURSIVE
- if (!*wild) *wild = recursive;
-#endif /* RECURSIVE */
-
- debug(F111,"cmifi sv wild",sv,*wild);
- debug(F101,"cmifi y","",y);
- if (dirflg && *wild && cdactive) {
- if (y > 1) {
- printf("?Wildcard matches more than one directory\n");
- if (sv) free(sv);
- if (np) free(np);
- return(-9);
- } else {
- znext(*xp);
- }
- }
- if (itsadir && d && !dirflg) { /* It's a directory and not wild */
- if (sv) free(sv); /* and it's ok to parse directories */
- if (np) free(np);
-#ifndef NOLASTFILE
- makestr(&lastfile,tmplastfile);
-#endif /* NOLASTFILE */
- return(x);
- }
- if (y == 0) { /* File was not found */
- int dosearch = 0;
- dosearch = (path != NULL); /* A search path was given */
- if (dosearch) {
- dosearch = hasnopath(sv); /* Filename includes no path */
- debug(F111,"cmifip hasnopath",sv,dosearch);
- }
- if (dosearch) { /* Search the path... */
- char * ptr = path;
- char c;
- while (1) {
- c = *ptr;
- if (c == PATHSEP || c == NUL) {
- if (!*path) {
- path = NULL;
- break;
- }
- *ptr = NUL;
-#ifdef UNIX
-/* By definition of CDPATH, an empty member denotes the current directory */
- if (!*path)
- ckstrncpy(atmbuf,".",ATMBL);
- else
-#endif /* UNIX */
- ckstrncpy(atmbuf,path,ATMBL);
-#ifdef VMS
- atmbuf[ATMBL] = NUL;
-/* If we have a logical name, evaluate it recursively */
- if (*(ptr-1) == ':') { /* Logical name ends in : */
- char *p; int n;
- while (((n = strlen(atmbuf)) > 0) &&
- atmbuf[n-1] == ':') {
- atmbuf[n-1] = NUL;
- for (p = atmbuf; *p; p++)
- if (islower(*p)) *p = toupper(*p);
- debug(F111,"cmdir CDPATH LN 1",atmbuf,n);
- p = getenv(atmbuf);
- debug(F110,"cmdir CDPATH LN 2",p,0);
- if (!p)
- break;
- strncpy(atmbuf,p,ATMBL);
- atmbuf[ATMBL] = NUL;
- }
- }
-#else
-#ifdef OS2
- if (*(ptr-1) != '\\' && *(ptr-1) != '/')
- ckstrncat(atmbuf,"\\",ATMBL);
-#else
-#ifdef UNIX
- if (*(ptr-1) != '/')
- ckstrncat(atmbuf,"/",ATMBL);
-#else
-#ifdef datageneral
- if (*(ptr-1) != ':')
- ckstrncat(atmbuf,":",ATMBL);
-#endif /* datageneral */
-#endif /* UNIX */
-#endif /* OS2 */
-#endif /* VMS */
- ckstrncat(atmbuf,sv,ATMBL);
- debug(F110,"cmifip add path",atmbuf,0);
- if (c == PATHSEP) ptr++;
- path = ptr;
- break;
- }
- ptr++;
- }
- x = 1;
- inword = 0;
- cc = 0;
- xc = (int) strlen(atmbuf);
- *xp = "";
- goto i_path;
- }
- if (d) {
- if (sv) free(sv);
- if (np) free(np);
- return(-2);
- } else {
- if (!nomsg) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",sv);
- else
-#endif /* CKROOT */
- if (!quiet)
- printf("?No %s match - %s\n",
- dirflg ? "directories" : "files", sv);
- }
- if (sv) free(sv);
- if (np) free(np);
- return(-9);
- }
- } else if (y < 0) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",sv);
- else
-#endif /* CKROOT */
- printf("?Too many %s match - %s\n",
- dirflg ? "directories" : "files", sv);
- if (sv) free(sv);
- if (np) free(np);
- return(-9);
- } else if (*wild || y > 1) {
- if (sv) free(sv);
- if (np) free(np);
-#ifndef NOLASTFILE
- makestr(&lastfile,tmplastfile);
-#endif /* NOLASTFILE */
- return(x);
- }
-
- /* If not wild, see if it exists and is readable. */
-
- debug(F111,"cmifi sv not wild",sv,*wild);
- if (expanded)
- znext(*xp); /* Get first (only?) matching file */
- if (dirflg) /* Maybe wild and expanded */
- itsadir = isdir(*xp); /* so do this again. */
- filesize = dirflg ? itsadir : zchki(*xp); /* Check accessibility */
- if (expanded) {
-#ifdef ZXREWIND
- nfiles = zxrewind(); /* Rewind so next znext() gets 1st */
-#else
-
- nzxopts |= dirflg ? ZX_DIRONLY : 0;
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- nfiles = nzxpand(*xp,nzxopts);
-#endif /* ZXREWIND */
- }
- debug(F111,"cmifi nfiles",*xp,nfiles);
- debug(F101,"cmifi filesize","",filesize);
- free(sv); /* done with this */
- sv = NULL;
- if (dirflg && !filesize) {
- printf("?Not a directory - %s\n",*xp);
-#ifdef CKCHANNELIO
- z_error = FX_ACC;
-#endif /* CKCHANNELIO */
- return(-9);
- } else if (filesize == (CK_OFF_T)-3) {
- if (!xcmfdb) {
- if (diractive)
- /* Don't show filename if we're not allowed to see it */
- printf("?Read permission denied\n");
- else
- printf("?Read permission denied - %s\n",*xp);
- }
- if (np) free(np);
-#ifdef CKCHANNELIO
- z_error = FX_ACC;
-#endif /* CKCHANNELIO */
- return(xcmfdb ? -6 : -9);
- } else if (filesize == (CK_OFF_T)-2) {
- if (!recursive) {
- if (np) free(np);
- if (d) {
-#ifndef NOLASTFILE
- makestr(&lastfile,tmplastfile);
-#endif /* NOLASTFILE */
- return(0);
- }
- if (!xcmfdb)
- printf("?File not readable - %s\n",*xp);
-#ifdef CKCHANNELIO
- z_error = FX_ACC;
-#endif /* CKCHANNELIO */
- return(xcmfdb ? -6 : -9);
- }
- } else if (filesize < (CK_OFF_T)0) {
- if (np) free(np);
- if (!nomsg && !xcmfdb)
- printf("?File not found - %s\n",*xp);
-#ifdef CKCHANNELIO
- z_error = FX_FNF;
-#endif /* CKCHANNELIO */
- return(xcmfdb ? -6 : -9);
- }
- if (np) free(np);
-#ifndef NOLASTFILE
- makestr(&lastfile,tmplastfile);
-#endif /* NOLASTFILE */
- return(x);
-
-#ifndef MAC
- case 2: /* ESC */
- debug(F101,"cmifi esc, xc","",xc);
- if (xc == 0) {
- if (*xdef) {
- printf("%s ",xdef); /* If at beginning of field */
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- inword = cmflgs = 0;
- addbuf(xdef); /* Supply default. */
- if (setatm(xdef,0) < 0) {
- printf("Default name too long\n");
- if (np) free(np);
- return(-9);
- }
- } else { /* No default */
- bleep(BP_WARN);
- }
- break;
- }
- if (**xp == '{') { /* Did user type opening brace... */
- *xp = *xp + 1;
- xc--;
- cc--;
- qflag = '}';
- } else if (dblquo && **xp == '"') { /* or doublequote? */
- *xp = *xp + 1; /* If so ignore it and space past it */
- xc--;
- cc--;
- qflag = '"';
- }
-#ifndef NOSPL
- if (f) { /* If a conversion function is given */
-#ifdef DOCHKVAR
- char *s = *xp; /* See if there are any variables in */
- while (*s) { /* the string and if so, expand it. */
- if (chkvar(s)) {
-#endif /* DOCHKVAR */
- zq = atxbuf;
- atxn = CMDBL;
- if ((x = (*f)(*xp,&zq,&atxn)) < 0) {
- if (np) free(np);
- return(-2);
- }
-#ifdef DOCHKVAR
- /* reduce cc by number of \\ consumed by conversion */
- /* function (needed for OS/2, where \ is path separator) */
- cc -= (strlen(*xp) - strlen(atxbuf));
-#endif /* DOCHKVAR */
- *xp = atxbuf;
- if (!atxbuf[0]) { /* Result empty, use default */
- *xp = xdef;
- cc = strlen(xdef);
- }
-#ifdef DOCHKVAR
- break;
- }
- s++;
- }
-#endif /* DOCHKVAR */
- }
-#endif /* NOSPL */
-
-#ifdef DTILDE
- if (dirflg && *(*xp) == '~') {
- debug(F111,"cmifi tilde_expand A",*xp,cc);
- dirp = tilde_expand(*xp); /* Expand tilde, if any... */
- if (!dirp) dirp = "";
- if (*dirp) {
- int i, xx;
- char * sp;
- xc = cc; /* Length of ~thing */
- xx = setatm(dirp,0); /* Copy expansion to atom buffer */
- debug(F111,"cmifi tilde_expand B",atmbuf,cc);
- if (xx < 0) {
- printf("Expanded name too long\n");
- if (np) free(np);
- return(-9);
- }
- debug(F111,"cmifi tilde_expand xc","",xc);
- for (i = 0; i < xc; i++) {
- cmdchardel(); /* Back up over ~thing */
- bp--;
- }
- xc = cc; /* How many new ones we just got */
- sp = atmbuf;
- printf("%s",sp); /* Print them */
- while ((*bp++ = *sp++)) ; /* Copy to command buffer */
- bp--; /* Back up over NUL */
- }
- *xp = atmbuf;
- }
-#endif /* DTILDE */
-
- sp = *xp + cc;
-
-#ifdef UNIXOROSK
- if (!strcmp(atmbuf,"..")) {
- printf(" ");
- ckstrncat(cmdbuf," ",CMDBL);
- cc++;
- bp++;
- *wild = 0;
- *xp = atmbuf;
- break;
- } else if (!strcmp(atmbuf,".")) {
- bleep(BP_WARN);
- if (np) free(np);
- return(-1);
- } else {
- /* This patches a glitch when user types "./foo<ESC>" */
- /* in which the next two chars are omitted from the */
- /* expansion. There should be a better fix, however, */
- /* since there is no problem with "../foo<ESC>". */
- char *p = *xp;
- if (*p == '.' && *(p+1) == '/')
- cc -= 2;
- }
-#endif /* UNIXOROSK */
-
-#ifdef datageneral
- *sp++ = '+'; /* Data General AOS wildcard */
-#else
- *sp++ = '*'; /* Others */
-#endif /* datageneral */
- *sp-- = '\0';
-#ifdef GEMDOS
- if (!strchr(*xp, '.')) /* abde.e -> abcde.e* */
- strcat(*xp, ".*"); /* abc -> abc*.* */
-#endif /* GEMDOS */
- /* Add wildcard and expand list. */
-#ifdef COMMENT
- /* This kills partial completion when ESC given in path segment */
- nzxopts |= dirflg ? ZX_DIRONLY : (d ? 0 : ZX_FILONLY);
-#else
- /* nzxopts = 0; */
-#endif /* COMMENT */
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- y = nzxpand(*xp,nzxopts);
- nfiles = y;
- debug(F111,"cmifi nzxpand",*xp,y);
- if (y > 0) {
-#ifdef OS2
- znext(filbuf); /* Get first */
-#ifdef ZXREWIND
- zxrewind(); /* Must "rewind" */
-#else
- nzxpand(*xp,nxzopts);
-#endif /* ZXREWIND */
-#else /* Not OS2 */
- ckstrncpy(filbuf,mtchs[0],CKMAXPATH);
-#endif /* OS2 */
- } else
- *filbuf = '\0';
- filbuf[CKMAXPATH] = NUL;
- *sp = '\0'; /* Remove wildcard. */
- debug(F111,"cmifi filbuf",filbuf,y);
- debug(F111,"cmifi *xp",*xp,cc);
-
- *wild = (y > 1);
- if (y == 0) {
- if (!nomsg) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",atmbuf);
- else
-#endif /* CKROOT */
- printf("?No %s match - %s\n",
- dirflg ? "directories" : "files", atmbuf);
- if (np) free(np);
- return(-9);
- } else {
- bleep(BP_WARN);
- if (np) free(np);
- return(-1);
- }
- } else if (y < 0) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",atmbuf);
- else
-#endif /* CKROOT */
- printf("?Too many %s match - %s\n",
- dirflg ? "directories" : "files", atmbuf);
- if (np) free(np);
- return(-9);
- } else if (y > 1 /* Not unique */
-#ifndef VMS
- || (y == 1 && isdir(filbuf)) /* Unique directory */
-#endif /* VMS */
- ) {
-#ifndef NOPARTIAL
-/* Partial filename completion */
- int j, k; char c;
- k = 0;
- debug(F111,"cmifi partial",filbuf,cc);
-#ifdef OS2
- {
- int cur = 0,
- len = 0,
- len2 = 0,
- min = strlen(filbuf),
- found = 0;
- char localfn[CKMAXPATH+1];
-
- len = min;
- for (j = 1; j <= y; j++) {
- znext(localfn);
- if (dirflg && !isdir(localfn))
- continue;
- found = 1;
- len2 = strlen(localfn);
- for (cur = cc;
- cur < len && cur < len2 && cur <= min;
- cur++
- ) {
- /* OS/2 or Windows, case doesn't matter */
- if (tolower(filbuf[cur]) != tolower(localfn[cur]))
- break;
- }
- if (cur < min)
- min = cur;
- }
- if (!found)
- min = cc;
- filbuf[min] = NUL;
- if (min > cc)
- k++;
- }
-#else /* OS2 */
- for (i = cc; (c = filbuf[i]); i++) {
- for (j = 1; j < y; j++)
- if (mtchs[j][i] != c) break;
- if (j == y) k++;
- else filbuf[i] = filbuf[i+1] = NUL;
- }
-#endif /* OS2 */
-
-
-#ifndef VMS
- /* isdir() function required for this! */
- if (y == 1 && isdir(filbuf)) { /* Dont we already know this? */
- int len;
- len = strlen(filbuf);
- if (len > 0 && len < ATMBL - 1) {
- if (filbuf[len-1] != dirsep) {
- filbuf[len] = dirsep;
- filbuf[len+1] = NUL;
- }
- }
-/*
- At this point, before just doing partial completion, we should look first to
- see if the given directory does indeed have any subdirectories (dirflg) or
- files (!dirflg); if it doesn't we should do full completion. Otherwise, the
- result looks funny to the user and "?" blows up the command for no good
- reason.
-*/
- {
- int flags = 0;
- filbuf[len+1] = '*';
- filbuf[len+2] = NUL;
- if (dirflg) flags = ZX_DIRONLY;
- children = nzxpand(filbuf,flags);
- debug(F111,"cmifi children",filbuf,children);
- filbuf[len+1] = NUL;
- nzxpand(filbuf,flags); /* Restore previous list */
- if (children == 0)
- goto NOSUBDIRS;
- }
- if (len + 1 > cc)
- k++;
- }
- /* Add doublequotes if there are spaces in the name */
- {
- int x;
- if (qflag) {
- x = (qflag == '}'); /* (or braces) */
- } else {
- x = !dblquo;
- }
- if (filbuf[0] != '"' && filbuf[0] != '{')
- k = dquote(filbuf,ATMBL,x);
- }
-#endif /* VMS */
- debug(F111,"cmifi REPAINT filbuf",filbuf,k);
- if (k > 0) { /* Got more characters */
- debug(F101,"cmifi REPAINT cc","",cc);
- debug(F101,"cmifi REPAINT xc","",xc);
- debug(F110,"cmifi REPAINT bp-cc",bp-cc,0);
- debug(F110,"cmifi REPAINT bp-xc",bp-xc,0);
- sp = filbuf + cc; /* Point to new ones */
- if (qflag || strncmp(filbuf,bp-cc,cc)) { /* Repaint? */
- int x;
- x = cc;
- if (qflag) x++;
- for (i = 0; i < x; i++) {
- cmdchardel(); /* Back up over old partial spec */
- bp--;
- }
- sp = filbuf; /* Point to new word start */
- debug(F110,"cmifi erase ok",sp,0);
- }
- cc = k; /* How many new ones we just got */
- printf("%s",sp); /* Print them */
- while ((*bp++ = *sp++)) ; /* Copy to command buffer */
- bp--; /* Back up over NUL */
- debug(F110,"cmifi partial cmdbuf",cmdbuf,0);
- if (setatm(filbuf,0) < 0) {
- printf("?Partial name too long\n");
- if (np) free(np);
- return(-9);
- }
- debug(F111,"cmifi partial atmbuf",atmbuf,cc);
- *xp = atmbuf;
- }
-#endif /* NOPARTIAL */
- bleep(BP_WARN);
- } else { /* Unique, complete it. */
-#ifndef VMS
-#ifdef CK_TMPDIR
- /* isdir() function required for this! */
- NOSUBDIRS:
- debug(F111,"cmifi unique",filbuf,children);
- if (isdir(filbuf) && children > 0) {
- int len;
- len = strlen(filbuf);
- if (len > 0 && len < ATMBL - 1) {
- if (filbuf[len-1] != dirsep) {
- filbuf[len] = dirsep;
- filbuf[len+1] = NUL;
- }
- }
- sp = filbuf + cc;
- bleep(BP_WARN);
- printf("%s",sp);
- cc++;
- while ((*bp++ = *sp++)) ;
- bp--;
- if (setatm(filbuf,0) < 0) {
- printf("?Directory name too long\n");
- if (np) free(np);
- return(-9);
- }
- debug(F111,"cmifi directory atmbuf",atmbuf,cc);
- *xp = atmbuf;
- } else { /* Not a directory or dirflg */
-#endif /* CK_TMPDIR */
-#endif /* VMS */
-#ifndef VMS /* VMS dir names are special */
-#ifndef datageneral /* VS dirnames must not end in ":" */
- if (dirflg) {
- int len;
- len = strlen(filbuf);
- if (len > 0 && len < ATMBL - 1) {
- if (filbuf[len-1] != dirsep) {
- filbuf[len] = dirsep;
- filbuf[len+1] = NUL;
- }
- }
- }
-#endif /* datageneral */
-#endif /* VMS */
- sp = filbuf + cc; /* Point past what user typed. */
- {
- int x;
- if (qflag) {
- x = (qflag == '}');
- } else {
- x = !dblquo;
- }
- if (filbuf[0] != '"' && filbuf[0] != '{')
- dquote(filbuf,ATMBL,x);
- }
- if (qflag || strncmp(filbuf,bp-cc,cc)) { /* Repaint? */
- int x;
- x = cc;
- if (qflag) x++;
- for (i = 0; i < x; i++) {
- cmdchardel(); /* Back up over old partial spec */
- bp--;
- }
- sp = filbuf; /* Point to new word start */
- debug(F111,"cmifi after erase sp=",sp,cc);
- }
- printf("%s ",sp); /* Print the completed name. */
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- addbuf(sp); /* Add the characters to cmdbuf. */
- if (setatm(filbuf,0) < 0) { /* And to atmbuf. */
- printf("?Completed name too long\n");
- if (np) free(np);
- return(-9);
- }
- inword = cmflgs = 0;
- *xp = brstrip(atmbuf); /* Return pointer to atmbuf. */
- if (dirflg && !isdir(*xp)) {
- printf("?Not a directory - %s\n", filbuf);
- if (np) free(np);
- return(-9);
- }
- if (np) free(np);
-#ifndef NOLASTFILE
- makestr(&lastfile,tmplastfile);
-#endif /* NOLASTFILE */
- return(0);
-#ifndef VMS
-#ifdef CK_TMPDIR
- }
-#endif /* CK_TMPDIR */
-#endif /* VMS */
- }
- break;
-
- case 3: /* Question mark - file menu wanted */
- if (*xhlp == NUL)
- printf(dirflg ? " Directory name" : " Input file specification");
- else
- printf(" %s",xhlp);
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- /* If user typed an opening quote or brace, just skip past it */
-
- if (**xp == '"' || **xp == '{') {
- *xp = *xp + 1;
- xc--;
- cc--;
- }
-#ifndef NOSPL
- if (f) { /* If a conversion function is given */
-#ifdef DOCHKVAR
- char *s = *xp; /* See if there are any variables in */
- while (*s) { /* the string and if so, expand them */
- if (chkvar(s)) {
-#endif /* DOCHKVAR */
- zq = atxbuf;
- atxn = CMDBL;
- if ((x = (*f)(*xp,&zq,&atxn)) < 0) {
- if (np) free(np);
- return(-2);
- }
-#ifdef DOCHKVAR
- /* reduce cc by number of \\ consumed by conversion */
- /* function (needed for OS/2, where \ is path separator) */
- cc -= (strlen(*xp) - strlen(atxbuf));
-#endif /* DOCHKVAR */
- *xp = atxbuf;
-#ifdef DOCHKVAR
- break;
- }
- s++;
- }
-#endif /* DOCHKVAR */
- }
-#endif /* NOSPL */
- debug(F111,"cmifi ? *xp, cc",*xp,cc);
- sp = *xp + cc; /* Insert "*" at end */
-#ifdef datageneral
- *sp++ = '+'; /* Insert +, the DG wild card */
-#else
- *sp++ = '*';
-#endif /* datageneral */
- *sp-- = '\0';
-#ifdef GEMDOS
- if (! strchr(*xp, '.')) /* abde.e -> abcde.e* */
- strcat(*xp, ".*"); /* abc -> abc*.* */
-#endif /* GEMDOS */
- debug(F110,"cmifi ? wild",*xp,0);
-
- nzxopts |= dirflg ? ZX_DIRONLY : (d ? 0 : ZX_FILONLY);
-
- debug(F101,"cmifi matchdot","",matchdot);
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- y = nzxpand(*xp,nzxopts);
- nfiles = y;
- *sp = '\0';
- if (y == 0) {
- if (nomsg) {
- printf(": %s\n",atmbuf);
- printf("%s%s",cmprom,cmdbuf);
- fflush(stdout);
- if (np) free(np);
- return(-1);
- } else {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",atmbuf);
- else
-#endif /* CKROOT */
- printf("?No %s match - %s\n",
- dirflg ? "directories" : "files", atmbuf);
- if (np) free(np);
- return(-9);
- }
- } else if (y < 0) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off Limits: %s\n",atmbuf);
- else
-#endif /* CKROOT */
- printf("?Too many %s match - %s\n",
- dirflg ? "directories" : "files", atmbuf);
- if (np) free(np);
- return(-9);
- } else {
- printf(", one of the following:\n");
- if (filhelp((int)y,"","",1,dirflg) < 0) {
- if (np) free(np);
- return(-9);
- }
- }
- printf("%s%s",cmprom,cmdbuf);
- fflush(stdout);
- break;
-#endif /* MAC */
- }
-#ifdef BS_DIRSEP
- dirnamflg = 1;
- x = gtword(0); /* No, get a word */
- dirnamflg = 0;
-#else
- x = gtword(0); /* No, get a word */
-#endif /* BS_DIRSEP */
- *xp = atmbuf;
- }
-}
-
-/* C M F L D -- Parse an arbitrary field */
-/*
- Returns:
- -3 if no input present when required,
- -2 if field too big for buffer,
- -1 if reparse needed,
- 0 otherwise, xp pointing to string result.
-
- NOTE: Global flag keepallchars says whether this routine should break on CR
- or LF: needed for MINPUT targets and DECLARE initializers, where we want to
- keep control characters if the user specifies them (March 2003). It might
- have been better to change the calling sequence but that was not practical.
-*/
-int
-cmfld(xhlp,xdef,xp,f) char *xhlp, *xdef, **xp; xx_strp f; {
- int x, xc;
- char *zq;
-
- inword = 0; /* Initialize counts & pointers */
- cc = 0;
- xc = 0;
- *xp = "";
-
- debug(F110,"cmfld xdef 1",xdef,0);
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
- ckstrncpy(cmdefault,xdef,CMDEFAULT); /* Copy default */
- xdef = cmdefault;
-
- debug(F111,"cmfld xdef 2",xdef,cmflgs);
- debug(F111,"cmfld atmbuf 1",atmbuf,xc);
-
- if ((x = cmflgs) != 1) { /* Already confirmed? */
- x = gtword(0); /* No, get a word */
- } else {
- if (setatm(xdef,0) < 0) { /* If so, use default, if any. */
- printf("?Default too long\n");
- return(-9);
- }
- }
- *xp = atmbuf; /* Point to result. */
- debug(F111,"cmfld atmbuf 2",atmbuf,cmflgs);
-
- while (1) {
- xc += cc; /* Count the characters. */
- debug(F111,"cmfld gtword",atmbuf,xc);
- debug(F101,"cmfld x","",x);
- switch (x) {
- case -9:
- printf("Command or field too long\n");
- case -4: /* EOF */
- case -3: /* Empty. */
- case -2: /* Out of space. */
- case -1: /* Reparse needed */
- return(x);
- case 1: /* CR */
- case 0: /* SP */
- debug(F111,"cmfld 1",atmbuf,xc);
- if (xc == 0) { /* If no input, return default. */
- if (setatm(xdef,0) < 0) {
- printf("?Default too long\n");
- return(-9);
- }
- }
- *xp = atmbuf; /* Point to what we got. */
- debug(F111,"cmfld 2",atmbuf,((f) ? 1 : 0));
- if (f) { /* If a conversion function is given */
- zq = atxbuf; /* employ it now. */
- atxn = CMDBL;
- if ((*f)(*xp,&zq,&atxn) < 0)
- return(-2);
- debug(F111,"cmfld 3",atxbuf,xc);
- /* Replace by new value -- for MINPUT only keep all chars */
- if (setatm(atxbuf,keepallchars ? 3:1) < 0) { /* 16 Mar 2003 */
- printf("Value too long\n");
- return(-9);
- }
- *xp = atmbuf;
- }
- debug(F111,"cmfld 4",atmbuf,xc);
- if (**xp == NUL) { /* If variable evaluates to null */
- if (setatm(xdef,0) < 0) {
- printf("?Default too long\n");
- return(-9);
- }
- if (**xp == NUL) x = -3; /* If still empty, return -3. */
- }
- debug(F111,"cmfld returns",*xp,x);
- return(x);
- case 2: /* ESC */
- if (xc == 0 && *xdef) {
- printf("%s ",xdef); /* If at beginning of field, */
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- addbuf(xdef); /* Supply default. */
- inword = cmflgs = 0;
- if (setatm(xdef,0) < 0) {
- printf("?Default too long\n");
- return(-9);
- } else /* Return as if whole field */
- return(0); /* typed, followed by space. */
- } else {
- bleep(BP_WARN);
- }
- break;
- case 3: /* Question mark */
- debug(F110,"cmfld QUESTIONMARK",cmdbuf,0);
- if (*xhlp == NUL)
- printf(" Please complete this field");
- else
- printf(" %s",xhlp);
- printf("\n%s%s",cmprom,cmdbuf);
- fflush(stdout);
- break;
- }
- debug(F111,"cmfld gtword A x",cmdbuf,x);
- x = gtword(0);
- debug(F111,"cmfld gtword B x",cmdbuf,x);
- }
-}
-
-
-/* C M T X T -- Get a text string, including confirmation */
-
-/*
- Print help message 'xhlp' if ? typed, supply default 'xdef' if null
- string typed. Returns:
-
- -1 if reparse needed or buffer overflows.
- 1 otherwise.
-
- with cmflgs set to return code, and xp pointing to result string.
-*/
-int
-cmtxt(xhlp,xdef,xp,f) char *xhlp; char *xdef; char **xp; xx_strp f; {
-
- int x, i;
- char *xx, *zq;
- static int xc;
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
-
- cmfldflgs = 0;
-
- cmdefault[0] = NUL;
- if (*xdef)
- ckstrncpy(cmdefault,xdef,CMDEFAULT); /* Copy default */
- xdef = cmdefault;
-
- debug(F101,"cmtxt cmflgs","",cmflgs);
- inword = 0; /* Start atmbuf counter off at 0 */
- cc = 0;
- if (cmflgs == -1) { /* If reparsing, */
- *xp = pp;
- xc = (int)strlen(*xp); /* get back the total text length, */
- bp = *xp; /* and back up the pointers. */
- np = *xp;
- pp = *xp;
- } else { /* otherwise, */
- /* debug(F100,"cmtxt: fresh start","",0); */
- *xp = ""; /* start fresh. */
- xc = 0;
- }
- *atmbuf = NUL; /* And empty the atom buffer. */
- rtimer(); /* Reset timer */
- if ((x = cmflgs) != 1) {
- int done = 0;
- while (!done) {
- x = gtword(0); /* Get first word. */
- *xp = pp; /* Save pointer to it. */
- /* debug(F111,"cmtxt:",*xp,cc); */
- if (x == -10) {
- if (gtimer() > timelimit) {
- /* if (!quiet) printf("?Timed out\n"); */
- return(x);
- }
- } else
- done = 1;
- }
- }
- while (1) { /* Loop for each word in text. */
- xc += cc; /* Char count for all words. */
- /* debug(F111,"cmtxt gtword",atmbuf,xc); */
- /* debug(F101,"cmtxt x","",x); */
- switch (x) {
- case -10:
- if (gtimer() > timelimit) {
-#ifdef IKSD
- extern int inserver;
- if (inserver) {
- printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", timelimit);
- doexit(GOOD_EXIT,0);
- }
-#endif /* IKSD */
- /* if (!quiet) printf("?Timed out\n"); */
- return(-10);
- } else {
- x = gtword(0);
- continue;
- }
- case -9: /* Buffer overflow */
- printf("Command or field too long\n");
- case -4: /* EOF */
-#ifdef MAC
- case -3: /* Quit/Timeout */
-#endif /* MAC */
- case -2: /* Overflow */
- case -1: /* Deletion */
- return(x);
- case 0: /* Space */
- xc++; /* Just count it */
- break;
- case 1: /* CR or LF */
- if (xc == 0) *xp = xdef;
- if (f) { /* If a conversion function is given */
- char * sx = atxbuf;
- zq = atxbuf; /* Point to the expansion buffer */
- atxn = CMDBL; /* specify its length */
- /* debug(F111,"cmtxt calling (*f)",*xp,atxbuf); */
- if ((x = (*f)(*xp,&zq,&atxn)) < 0) return(-2);
- sx = atxbuf;
-#ifndef COMMENT
- cc = 0;
- while (*sx++) cc++; /* (faster than calling strlen) */
-#else
- cc = (int)strlen(atxbuf);
-#endif /* COMMENT */
- /* Should be equal to (CMDBL - atxn) but isn't always. */
- /* Why not? */
- if (cc < 1) { /* Nothing in expansion buffer? */
- *xp = xdef; /* Point to default string instead. */
-#ifndef COMMENT
- sx = xdef;
- while (*sx++) cc++; /* (faster than calling strlen) */
-#else
- cc = strlen(xdef);
-#endif /* COMMENT */
- } else { /* Expansion function got something */
- *xp = atxbuf; /* return pointer to it. */
- }
- debug(F111,"cmtxt (*f)",*xp,cc);
- } else { /* No expansion function */
-#ifndef COMMENT
- /* Avoid a strlen() call */
- xx = *xp;
- cc = 0;
- while (*xx++) cc++;
-#else
- /* NO! xc is apparently not always set appropriately */
- cc = xc;
-#endif /* COMMENT */
- }
- xx = *xp;
-#ifdef COMMENT
- /* strlen() no longer needed */
- for (i = (int)strlen(xx) - 1; i > 0; i--)
-#else
- for (i = cc - 1; i > 0; i--)
-#endif /* COMMENT */
- if (xx[i] != SP) /* Trim trailing blanks */
- break;
- else
- xx[i] = NUL;
- return(x);
- case 2: /* ESC */
- if (xc == 0) { /* Nothing typed yet */
- if (*xdef) { /* Have a default for this field? */
- printf("%s ",xdef); /* Yes, supply it */
- inword = cmflgs = 0;
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- cc = addbuf(xdef);
- } else bleep(BP_WARN); /* No default */
- } else { /* Already in field */
- int x; char *p;
- x = strlen(atmbuf);
- if (ckstrcmp(atmbuf,xdef,x,0)) { /* Matches default? */
- bleep(BP_WARN); /* No */
- } else if ((int)strlen(xdef) > x) { /* Yes */
- p = xdef + x;
- printf("%s ", p);
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- addbuf(p);
- inword = cmflgs = 0;
- debug(F110,"cmtxt: addbuf",cmdbuf,0);
- } else {
- bleep(BP_WARN);
- }
- }
- break;
- case 3: /* Question Mark */
- if (*xhlp == NUL)
- printf(" Text string");
- else
- printf(" %s",xhlp);
- printf("\n%s%s",cmprom,cmdbuf);
- fflush(stdout);
- break;
- default:
- printf("?Unexpected return code from gtword() - %d\n",x);
- return(-2);
- }
- x = gtword(0);
- }
-}
-
-/* C M K E Y -- Parse a keyword */
-
-/*
- Call with:
- table -- keyword table, in 'struct keytab' format;
- n -- number of entries in table;
- xhlp -- pointer to help string;
- xdef -- pointer to default keyword;
- f -- string preprocessing function (e.g. to evaluate variables)
- pmsg -- 0 = don't print error messages
- 1 = print error messages
- 2 = include CM_HLP keywords even if invisible
- 3 = 1+2
- 4 = parse a switch (keyword possibly ending in : or =)
- 8 = don't strip comments (used, e.g., for "help #")
- Returns:
- -3 -- no input supplied and no default available
- -2 -- input doesn't uniquely match a keyword in the table
- -1 -- user deleted too much, command reparse required
- n >= 0 -- value associated with keyword
-*/
-
-/*
- Front ends for cmkey2():
- cmkey() - The normal keyword parser
- cmkeyx() - Like cmkey() but suppresses error messages
- cmswi() - Switch parser
-*/
-int
-cmkey(table,n,xhlp,xdef,f)
-/* cmkey */ struct keytab table[]; int n; char *xhlp, *xdef; xx_strp f; {
- return(cmkey2(table,n,xhlp,xdef,"",f,1));
-}
-int
-cmkeyx(table,n,xhlp,xdef,f)
-/* cmkeyx */ struct keytab table[]; int n; char *xhlp, *xdef; xx_strp f; {
- return(cmkey2(table,n,xhlp,xdef,"",f,0));
-}
-int
-cmswi(table,n,xhlp,xdef,f)
-/* cmswi */ struct keytab table[]; int n; char *xhlp, *xdef; xx_strp f; {
- return(cmkey2(table,n,xhlp,xdef,"",f,4));
-}
-
-int
-cmkey2(table,n,xhlp,xdef,tok,f,pmsg)
- struct keytab table[];
- int n;
- char *xhlp, *xdef;
- char *tok;
- xx_strp f;
- int pmsg;
-{ /* cmkey2 */
- extern int havetoken;
- int i, tl, y, z = 0, zz, xc, wordlen = 0, cmswitch;
- char *xp, *zq;
-
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
-
- cmfldflgs = 0;
- if (!table) {
- printf("?Keyword table missing\n");
- return(-9);
- }
- tl = (int)strlen(tok);
-
- inword = xc = cc = 0; /* Clear character counters. */
- cmswitch = pmsg & 4; /* Flag for parsing a switch */
-
- debug(F101,"cmkey: pmsg","",pmsg);
- debug(F101,"cmkey: cmflgs","",cmflgs);
- debug(F101,"cmkey: cmswitch","",cmswitch);
- /* debug(F101,"cmkey: cmdbuf","",cmdbuf);*/
-
- ppvnambuf[0] = NUL;
-
- if ((zz = cmflgs) == 1) { /* Command already entered? */
- if (setatm(xdef,0) < 0) { /* Yes, copy default into atom buf */
- printf("?Default too long\n");
- return(-9);
- }
- rtimer(); /* Reset timer */
- } else { /* Otherwise get a command word */
- rtimer(); /* Reset timer */
- if (pmsg & 8) /* 8 is for parsing HELP tokens */
- zz = gtword(4);
- else
- zz = gtword((pmsg == 4) ? 1 : 0);
- }
-
- debug(F101,"cmkey table length","",n);
- debug(F101,"cmkey cmflgs","",cmflgs);
- debug(F101,"cmkey cc","",cc);
-
- while (1) {
- xc += cc;
- debug(F111,"cmkey gtword xc",atmbuf,xc);
- debug(F101,"cmkey gtword zz","",zz);
-
- switch (zz) {
- case -10: /* Timeout */
- if (gtimer() < timelimit) {
- if (pmsg & 8) /* 8 is for parsing HELP tokens */
- zz = gtword(4);
- else
- zz = gtword((pmsg == 4) ? 1 : 0);
- continue;
- } else {
-#ifdef IKSD
- extern int inserver;
- if (inserver) {
- printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", timelimit);
- doexit(GOOD_EXIT,0);
- }
-#endif /* IKSD */
- return(-10);
- }
- case -5:
- return(cmflgs = 0);
- case -9:
- printf("Command or field too long\n");
- case -4: /* EOF */
- case -3: /* Null Command/Quit/Timeout */
- case -2: /* Buffer overflow */
- case -1: /* Or user did some deleting. */
- return(cmflgs = zz);
-
-
- case 1: /* CR */
- case 0: /* User terminated word with space */
- case 4: /* or switch ending in : or = */
- wordlen = cc; /* Length if no conversion */
- if (cc == 0) { /* Supply default if we got nothing */
- if ((wordlen = setatm(xdef,(zz == 4) ? 2 : 0)) < 0) {
- printf("?Default too long\n");
- return(-9);
- }
- }
- if (zz == 1 && cc == 0) /* Required field missing */
- return(-3);
-
- if (f) { /* If a conversion function is given */
- char * p2;
- zq = atxbuf; /* apply it */
- p2 = atxbuf;
- atxn = CMDBL;
- if ((*f)(atmbuf,&zq,&atxn) < 0) return(-2);
- debug(F110,"cmkey atxbuf after *f",atxbuf,0);
- if (!*p2) /* Supply default if we got nothing */
- p2 = xdef;
- ckstrncpy(ppvnambuf,atmbuf,PPVLEN);
- if ((wordlen = setatm(p2,(zz == 4) ? 2 : 0)) < 0) {
- printf("Evaluated keyword too long\n");
- return(-9);
- }
-#ifdef M_UNGW
- /*
- This bit lets us save more than one "word".
- For example, "define \%x echo one two three", "\%x".
- It works too, but it breaks labels, and therefore
- WHILE and FOR loops, etc.
- */
- if (p2[wordlen] >= SP) {
- p2 += wordlen;
- while (*p2 == SP) p2++;
- if (*p2) {
- ungword();
- pp = p2;
- }
- }
-#endif /* M_UNGW */
- }
-#ifdef COMMENT /* ^^^ */
- if (cmswitch && *atmbuf != '/') {
- if (pmsg & 1) {
- bleep(BP_FAIL);
- printf("?Not a switch - %s\n",atmbuf);
- }
- cmflgs = -2;
- return(-6);
- }
-#endif /* COMMENT */
- if (cmswitch) {
- int i;
- for (i = 0; i < wordlen; i++) {
- if (atmbuf[i] == ':' || atmbuf[i] == '=') {
- brkchar = atmbuf[i];
- atmbuf[i] = NUL;
- break;
- }
- }
- }
-
-#ifdef TOKPRECHECK
-/* This was an effective optimization but it breaks sometimes on labels. */
- if (tl && !isalpha(atmbuf[0])) { /* Precheck for token */
- for (i = 0; i < tl; i++) { /* Save function call to ckstrchr */
- if (tok[i] == atmbuf[0]) {
- debug(F000,"cmkey token:",atmbuf,*atmbuf);
- ungword(); /* Put back the following word */
- return(-5); /* Special return code for token */
- }
- }
- }
-#endif /* TOKPRECHECK */
-
- y = lookup(table,atmbuf,n,&z); /* Look up word in the table */
- debug(F111,"cmkey lookup",atmbuf,y);
- debug(F101,"cmkey zz","",zz);
- debug(F101,"cmkey cmflgs","",cmflgs);
- debug(F101,"cmkey crflag","",crflag);
- switch (y) {
- case -3: /* Nothing to look up */
- break;
- case -2: /* Ambiguous */
- cmflgs = -2;
- if (pmsg & 1) {
- bleep(BP_FAIL);
- printf("?Ambiguous - %s\n",atmbuf);
- return(-9);
- }
- return(-2);
- case -1: /* Not found at all */
-#ifndef TOKPRECHECK
- if (tl) {
- for (i = 0; i < tl; i++) /* Check for token */
- if (tok[i] == *atmbuf) { /* Got one */
- debug(F000,"cmkey token:",atmbuf,*atmbuf);
- ungword(); /* Put back the following word */
- return(-5); /* Special return code for token */
- }
- }
-#endif /* TOKPRECHECK */
-
- if (tl == 0) { /* No tokens were included */
-#ifdef OS2
- /* In OS/2 and Windows, allow for a disk letter like DOS */
- if (isalpha(*atmbuf) && *(atmbuf+1) == ':')
- return(-7);
-#endif /* OS2 */
- if ((pmsg & 1) && !quiet) {
- bleep(BP_FAIL);
- printf("?No keywords match - %s\n",atmbuf); /* cmkey */
- }
- return(cmflgs = -9);
- } else {
- if (cmflgs == 1 || cmswitch) /* cmkey2 or cmswi */
- return(cmflgs = -6);
- else
- return(cmflgs = -2);
- /* The -6 code is to let caller try another table */
- }
- break;
- default:
-#ifdef CK_RECALL
- if (test(table[z].flgs,CM_NOR)) no_recall = 1;
-#endif /* CK_RECALL */
- if (zz == 4)
- swarg = 1;
- cmkwflgs = table[z].flgs;
- break;
- }
- return(y);
-
- case 2: /* User terminated word with ESC */
- debug(F101,"cmkey Esc cc","",cc);
- if (cc == 0) {
- if (*xdef != NUL) { /* Nothing in atmbuf */
- printf("%s ",xdef); /* Supply default if any */
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- addbuf(xdef);
- if (setatm(xdef,0) < 0) {
- printf("?Default too long\n");
- return(-9);
- }
- inword = cmflgs = 0;
- debug(F111,"cmkey: default",atmbuf,cc);
- } else {
- debug(F101,"cmkey Esc pmsg","",0);
-#ifdef COMMENT
-/*
- Chained FDBs... The idea is that this function might not have a default,
- but the next one might. But if it doesn't, there is no way to come back to
- this one. To be revisited later...
-*/
- if (xcmfdb) /* Chained fdb -- try next one */
- return(-3);
-#endif /* COMMENT */
- if (pmsg & (1|4)) { /* So for now just beep */
- bleep(BP_WARN);
- }
- break;
- }
- }
- if (f) { /* If a conversion function is given */
- char * pp;
- zq = atxbuf; /* apply it */
- pp = atxbuf;
- atxn = CMDBL;
- if ((*f)(atmbuf,&zq,&atxn) < 0)
- return(-2);
- if (!*pp)
- pp = xdef;
- if (setatm(pp,0) < 0) {
- printf("Evaluated keyword too long\n");
- return(-9);
- }
- }
- y = lookup(table,atmbuf,n,&z); /* Something in atmbuf */
- debug(F111,"cmkey lookup y",atmbuf,y);
- debug(F111,"cmkey lookup z",atmbuf,z);
- if (y == -2 && z >= 0 && z < n) { /* Ambiguous */
-#ifndef NOPARTIAL
- int j, k, len = 9999; /* Do partial completion */
- /* Skip past any abbreviations in the table */
- for ( ; z < n; z++) {
- if ((table[z].flgs & CM_ABR) == 0)
- break;
- if (!(table[z].flgs & CM_HLP) || (pmsg & 2))
- break;
- }
- debug(F111,"cmkey partial z",atmbuf,z);
- debug(F111,"cmkey partial n",atmbuf,n);
- for (j = z+1; j < n; j++) {
- debug(F111,"cmkey partial j",table[j].kwd,j);
- if (ckstrcmp(atmbuf,table[j].kwd,cc,0))
- break;
- if (table[j].flgs & CM_ABR)
- continue;
- if ((table[j].flgs & CM_HLP) && !(pmsg & 2))
- continue;
- k = ckstrpre(table[z].kwd,table[j].kwd);
- debug(F111,"cmkey partial k",table[z].kwd,k);
- if (k < len)
- len = k; /* Length of longest common prefix */
- }
- debug(F111,"cmkey partial len",table[z].kwd,len);
- if (len != 9999 && len > cc) {
- ckstrncat(atmbuf,table[z].kwd+cc,ATMBL);
- atmbuf[len] = NUL;
- printf("%s",atmbuf+cc);
- ckstrncat(cmdbuf,atmbuf+cc,CMDBL);
- xc += (len - cc);
- cc = len;
- }
-#endif /* NOPARTIAL */
- bleep(BP_WARN);
- break;
- } else if (y == -3) {
- bleep(BP_WARN);
- break;
- } else if (y == -1) { /* Not found */
- if ((pmsg & 1) && !quiet) {
- bleep(BP_FAIL);
- printf("?No keywords match - \"%s\"\n",atmbuf);
- }
- cmflgs = -2;
- return(-9);
- }
-/*
- If we found it, but it's a help-only keyword and the "help" bit is not
- set in pmsg, then not found.
-*/
- debug(F101,"cmkey flgs","",table[z].flgs);
- if (test(table[z].flgs,CM_HLP) && ((pmsg & 2) == 0)) {
- if ((pmsg & 1) && !quiet) {
- bleep(BP_FAIL);
- printf("?No keywords match - %s\n",atmbuf);
- }
- cmflgs = -2;
- return(-9);
- }
-/*
- See if the keyword just found has the CM_ABR bit set in its flgs field, and
- if so, search forwards in the table for a keyword that has the same kwval
- but does not have CM_ABR (or CM_INV?) set, and then expand using the full
- keyword. WARNING: This assumes that (a) keywords are in alphabetical order,
- and (b) the CM_ABR bit is set only if the the abbreviated keyword is a true
- abbreviation (left substring) of the full keyword.
-*/
- if (test(table[z].flgs,CM_ABR)) {
- int zz;
- for (zz = z+1; zz < n; zz++)
- if ((table[zz].kwval == table[z].kwval) &&
- (!test(table[zz].flgs,CM_ABR)) &&
- (!test(table[zz].flgs,CM_INV))) {
- z = zz;
- break;
- }
- }
- xp = table[z].kwd + cc;
- if (cmswitch && test(table[z].flgs,CM_ARG)) {
-#ifdef VMS
- printf("%s=",xp);
- brkchar = '=';
-#else
- printf("%s:",xp);
- brkchar = ':';
-#endif /* VMS */
- } else {
- printf("%s ",xp);
- brkchar = SP;
- }
-#ifdef CK_RECALL
- if (test(table[z].flgs,CM_NOR)) no_recall = 1;
-#endif /* CK_RECALL */
- cmkwflgs = table[z].flgs;
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- addbuf(xp);
- if (cmswitch && test(table[z].flgs,CM_ARG)) {
- bp--; /* Replace trailing space with : */
-#ifdef VMS
- *bp++ = '=';
-#else
- *bp++ = ':';
-#endif /* VMS */
- *bp = NUL;
- np = bp;
- swarg = 1;
- }
- inword = 0;
- cmflgs = 0;
- debug(F110,"cmkey: addbuf",cmdbuf,0);
- return(y);
-
- case 3: /* User typed "?" */
- if (f) { /* If a conversion function is given */
- char * pp;
- zq = atxbuf; /* do the conversion now. */
- pp = atxbuf;
- atxn = CMDBL;
- if ((*f)(atmbuf,&zq,&atxn) < 0) return(-2);
- if (setatm(pp,0) < 0) {
- printf("?Evaluated keyword too long\n");
- return(-9);
- }
- }
- y = lookup(table,atmbuf,n,&z); /* Look up what we have so far. */
- if (y == -1) {
- /*
- Strictly speaking if the main keyword table search fails,
- then we should look in the token table if one is given.
- But in practice, tokens are also included in the main
- keyword table.
- */
- cmflgs = -2;
- if ((pmsg & 1) && !quiet) {
- bleep(BP_FAIL);
- printf(" No keywords match\n");
- return(-9);
- }
- return(-2);
- }
-#ifndef COMMENT
- /* This is to allow ?-help to work immediately after a token */
- /* without having to type an intermediate space */
- if (tl) {
- for (i = 0; i < tl; i++) /* Check for token */
- if (tok[i] == *atmbuf) { /* Got one */
- debug(F000,"cmkey token:",atmbuf,*atmbuf);
- ungword(); /* Put back the following word */
- cmflgs = 3; /* Force help next time around */
- return(-5); /* Special return code for token */
- }
- }
-#endif /* COMMENT */
-
- if (*xhlp == NUL)
- printf(" One of the following:\n");
- else
- printf(" %s, one of the following:\n",xhlp);
- {
- int x;
- x = pmsg & (2|4); /* See kwdhelp() comments */
- if (atmbuf[0]) /* If not at beginning of field */
- x |= 1; /* also show invisibles */
- kwdhelp(table,n,atmbuf,"","",1,x);
- }
-#ifndef NOSPL
- if (!havetoken) {
- extern int topcmd;
- if (tl > 0 && topcmd != XXHLP) /* This is bad... */
- printf("or a macro name (\"do ?\" for a list) ");
- }
-#endif /* NOSPL */
- if (*atmbuf == NUL && !havetoken) {
- if (tl == 1)
- printf("or the token %c\n",*tok);
- else if (tl > 1)
- printf("or one of the tokens: %s\n",ckspread(tok));
- }
- printf("%s%s", cmprom, cmdbuf);
- fflush(stdout);
- break;
-
- default:
- printf("\n%d - Unexpected return code from gtword\n",zz);
- return(cmflgs = -2);
- }
- zz = (pmsg & 8) ? gtword(4) : gtword((pmsg == 4) ? 1 : 0);
- debug(F111,"cmkey gtword zz",atmbuf,zz);
- }
-}
-
-int
-chktok(tlist) char *tlist; {
- char *p;
- p = tlist;
- while (*p != NUL && *p != *atmbuf) p++;
- return((*p) ? (int) *p : 0);
-}
-
-/* Routines for parsing and converting dates and times */
-
-#define isdatesep(c) (ckstrchr(" -/._",c))
-
-#define CMDATEBUF 1024
-char cmdatebuf[CMDATEBUF+4] = { NUL, NUL };
-static char * cmdatebp = cmdatebuf;
-char * cmdatemsg = NULL;
-
-static struct keytab timeunits[] = {
- { "days", TU_DAYS, 0 },
- { "months", TU_MONTHS, 0 },
- { "weeks", TU_WEEKS, 0 },
- { "wks", TU_WEEKS, 0 },
- { "years", TU_YEARS, 0 },
- { "yrs", TU_YEARS, 0 }
-};
-static int nunits = (sizeof(timeunits) / sizeof(struct keytab));
-
-#define SYM_NOW 0
-#define SYM_TODA 1
-#define SYM_TOMO 2
-#define SYM_YEST 3
-
-static struct keytab symdaytab[] = {
- { "now", SYM_NOW, 0 },
- { "today", SYM_TODA, 0 },
- { "tomorrow", SYM_TOMO, 0 },
- { "yesterday", SYM_YEST, 0 }
-};
-static int nsymdays = (sizeof(symdaytab) / sizeof(struct keytab));
-
-static struct keytab daysofweek[] = {
- { "Friday", 5, 0 },
- { "Monday", 1, 0 },
- { "Saturday", 6, 0 },
- { "Sunday", 0, 0 },
- { "Thursday", 4, 0 },
- { "Tuesday", 2, 0 },
- { "Wednesday", 3, 0 }
-};
-
-static struct keytab usatz[] = { /* RFC 822 timezones */
- { "cdt", 5, 0 }, /* Values are GMT offsets */
- { "cst", 6, 0 },
- { "edt", 4, 0 },
- { "est", 5, 0 },
- { "gmt", 0, 0 },
- { "mdt", 6, 0 },
- { "mst", 7, 0 },
- { "pdt", 7, 0 },
- { "pst", 8, 0 },
- { "utc", 0, 0 },
- { "zulu", 0, 0 }
-};
-static int nusatz = (sizeof(usatz) / sizeof(struct keytab));
-
-
-/* C M C V T D A T E -- Converts free-form date to standard form. */
-
-/*
- Call with
- s = pointer to free-format date, time, or date and time.
- t = 0: return time only if time was given in s.
- t = 1: always return time (00:00:00 if no time given in s).
- t = 2: allow time to be > 24:00:00.
- Returns:
- NULL on failure;
- Pointer to "yyyymmdd hh:mm:ss" (local date-time) on success.
-*/
-
-/*
- Before final release the following long lines should be wrapped.
- Until then we leave them long since wrapping them wrecks EMACS's
- C indentation.
-*/
-
-/* asctime pattern */
-static char * atp1 = "[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9][0-9][0-9]";
-
-/* asctime pattern with timezone */
-static char * atp2 = "[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [A-Z][A-Z][A-Z] [0-9][0-9][0-9][0-9]";
-
-#define DATEBUFLEN 127
-#define YYYYMMDD 12
-
-#define isleap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
-static int mdays[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-#define NEED_DAYS 1
-#define NEED_HRS 2
-#define NEED_MINS 3
-#define NEED_SECS 4
-#define NEED_FRAC 5
-
-#define DELTABUF 256
-static char deltabuf[DELTABUF];
-static char * deltabp = deltabuf;
-
-char *
-cmdelta(yy, mo, dd, hh, mm, ss, sign, dyy, dmo, ddd, dhh, dmm, dss)
- int yy, mo, dd, hh, mm, ss, sign, dyy, dmo, ddd, dhh, dmm, dss;
-/* cmdelta */ {
- int zyy, zmo, zdd, zhh, zmm, zss;
- long t1, t2, t3, t4;
- long d1 = 0, d2, d3;
- char datebuf[DATEBUFLEN+1];
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"cmdelta yy","",yy);
- debug(F101,"cmdelta mo","",mo);
- debug(F101,"cmdelta dd","",dd);
- debug(F101,"cmdelta hh","",hh);
- debug(F101,"cmdelta mm","",mm);
- debug(F101,"cmdelta ss","",ss);
- debug(F101,"cmdelta sign","",sign);
- debug(F101,"cmdelta dyy","",dyy);
- debug(F101,"cmdelta dmo","",dmo);
- debug(F101,"cmdelta ddd","",ddd);
- debug(F101,"cmdelta dhh","",dhh);
- debug(F101,"cmdelta dmm","",dmm);
- debug(F101,"cmdelta dss","",dss);
- }
-#endif /* DEBLOG */
-
- if (yy < 0 || yy > 9999) {
- makestr(&cmdatemsg,"Base year out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- if (mo < 1 || mo > 12) {
- makestr(&cmdatemsg,"Base month out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- if (dd < 1 || dd > mdays[mo]) {
- makestr(&cmdatemsg,"Base day out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- if (hh < 0 || hh > 23) {
- makestr(&cmdatemsg,"Base hour out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- if (mm < 0 || mm > 59) {
- makestr(&cmdatemsg,"Base minute out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- if (ss < 0 || ss > 60) {
- makestr(&cmdatemsg,"Base second out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- sign = (sign < 0) ? -1 : 1;
- if (dmo != 0) {
- if (sign > 0) {
- mo += (sign * dmo);
- if (mo > 12) {
- yy += mo / 12;
- mo = mo % 12;
- }
- } else if (sign < 0) {
- while (dmo > 12) {
- yy--;
- dmo -= 12;
- }
- if (dmo < mo) {
- mo -= dmo;
- } else {
- yy--;
- mo = 12 - (dmo - mo);
- }
- }
- }
- if (dyy != 0) {
- yy += (sign * dyy);
- if (yy > 9999 || yy < 0) {
- makestr(&cmdatemsg,"Result year out of range");
- debug(F111,"cmdelta",cmdatemsg,-1);
- return(NULL);
- }
- }
- sprintf(datebuf,"%04d%02d%02d %02d:%02d:%02d",yy,mo,dd,hh,mm,ss);
- d1 = mjd(datebuf);
- debug(F111,"cmdelta mjd",datebuf,d1);
-
- t1 = hh * 3600 + mm * 60 + ss; /* Base time to secs since midnight */
- t2 = dhh * 3600 + dmm * 60 + dss; /* Delta time, ditto */
- t3 = t1 + (sign * t2); /* Get sum (or difference) */
-
- d2 = (sign * ddd); /* Delta days */
- d2 += t3 / 86400L;
-
- t4 = t3 % 86400L; /* Fractional part of day */
- if (t4 < 0) { /* If negative */
- d2--; /* one less delta day */
- t4 += 86400L; /* get positive seconds */
- }
- hh = (int) (t4 / 3600L);
- mm = (int) (t4 % 3600L) / 60;
- ss = (int) (t4 % 3600L) % 60;
-
- sprintf(datebuf,"%s %02d:%02d:%02d", mjd2date(d1+d2),hh,mm,ss);
- {
- int len, k, n;
- char * p;
- len = strlen(datebuf);
- k = deltabp - (char *)deltabuf; /* Space used */
- n = DELTABUF - k - 1; /* Space left */
- if (n < len) { /* Not enough? */
- deltabp = deltabuf; /* Wrap around */
- n = DELTABUF;
- }
- ckstrncpy(deltabp,datebuf,n);
- p = deltabp;
- deltabp += len + 1;
- return(p);
- }
-}
-
-
-/* Convert Delta Time to Seconds */
-
-int
-delta2sec(s,result) char * s; long * result; {
- long ddays = 0L, zz;
- int dsign = 1, dhours = 0, dmins = 0, dsecs = 0, units;
- int state = NEED_DAYS;
- char *p, *p2, *p3, c = 0;
- char buf[64];
-
- if (!s) s = "";
- if (!*s)
- return(-1);
- if ((int)strlen(s) > 63)
- return(-1);
- ckstrncpy(buf,s,64);
- p = buf;
-
- if (*p != '+' && *p != '-')
- return(-1);
-
- if (*p++ == '-')
- dsign = -1;
- while (*p == SP) /* Skip intervening spaces */
- p++;
-
- while (state) { /* FSA to parse delta time */
- if (state < 0 || !isdigit(*p))
- return(-1);
- p2 = p; /* Get next numeric field */
- while (isdigit(*p2))
- p2++;
- c = *p2; /* And break character */
- *p2 = NUL; /* Terminate the number */
- switch (state) { /* Interpret according to state */
- case NEED_DAYS: /* Initial */
- if ((c == '-') || /* VMS format */
- ((c == 'd' || c == 'D')
- && !isalpha(*(p2+1)))) { /* Days */
- ddays = atol(p);
- if (!*(p2+1))
- state = 0;
- else /* if anything is left */
- state = NEED_HRS; /* now we want hours. */
- } else if (c == ':') { /* delimiter is colon */
- dhours = atoi(p); /* so it's hours */
- state = NEED_MINS; /* now we want minutes */
- } else if (!c) { /* end of string */
- dhours = atoi(p); /* it's still hours */
- state = 0; /* and we're done */
- } else if (isalpha(c) || c == SP) {
- if (c == SP) { /* It's a keyword? */
- p2++; /* Skip spaces */
- while (*p2 == SP)
- p2++;
- } else { /* or replace first letter */
- *p2 = c;
- }
- p3 = p2; /* p2 points to beginning of keyword */
- while (isalpha(*p3)) /* Find end of keyword */
- p3++;
- c = *p3; /* NUL it out so we can look it up */
- if (*p3) /* p3 points to keyword terminator */
- *p3 = NUL;
- if ((units = lookup(timeunits,p2,nunits,NULL)) < 0)
- return(-1);
- *p2 = NUL; /* Re-terminate the number */
- *p3 = c;
- while (*p3 == SP) /* Point at field after units */
- p3++;
- p2 = p3;
- switch (units) {
- case TU_DAYS:
- ddays = atol(p);
- break;
- default:
- return(-1);
- }
- if (*p2) {
- state = NEED_HRS;
- p2--;
- } else
- state = 0;
- } else { /* Anything else */
- state = -1; /* is an error */
- }
- break;
- case NEED_HRS: /* Looking for hours */
- if (c == ':') {
- dhours = atoi(p);
- state = NEED_MINS;
- } else if (!c) {
- dhours = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_MINS: /* Looking for minutes */
- if (c == ':') {
- dmins = atoi(p);
- state = NEED_SECS;
- } else if (!c) {
- dmins = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_SECS: /* Looking for seconds */
- if (c == '.') {
- dsecs = atoi(p);
- state = NEED_FRAC;
- } else if (!c) {
- dsecs = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_FRAC: /* Fraction of second */
- if (!c && rdigits(p)) {
- if (*p > '4')
- dsecs++;
- state = 0;
- } else {
- state = -1;
- }
- break;
- }
- if (c) /* next field if any */
- p = p2 + 1;
- }
- if (state < 0)
- return(-1);
-
- /* if days > 24854 and sizeof(long) == 32 we overflow */
-
- zz = ddays * 86400L;
- if (zz < 0L) /* This catches it */
- return(-2);
- zz += dhours * 3600L + dmins * 60L + dsecs;
- zz *= dsign;
- *result = zz;
- return(0);
-}
-
-
-char *
-cmcvtdate(s,t) char * s; int t; {
- int x, i, j, k, hh, mm, ss, ff, pmflag = 0, nodate = 0, len, dow;
- int units, isgmt = 0, gmtsign = 0, d = 0, state = 0, nday;
- int kn = 0, ft[8], isletter = 0, f2len = 0;
-
- int zhh = 0; /* Timezone adjustments */
- int zmm = 0;
- int zdd = 0;
-
- int dsign = 1; /* Delta-time adjustments */
- int ddays = 0;
- int dmonths = 0;
- int dyears = 0;
- int dhours = 0;
- int dmins = 0;
- int dsecs = 0;
- int havedelta = 0;
-
- char * fld[8], * p = "", * p2, * p3; /* Assorted buffers and pointers */
- char * s2, * s3;
- char * year = NULL, * month = NULL, * day = NULL;
- char * hour = "00", * min = "00", * sec = "00";
- char datesep = 0;
- char tmpbuf[8];
- char xbuf[DATEBUFLEN+1];
- char ybuf[DATEBUFLEN+1];
- char zbuf[DATEBUFLEN+1];
- char yyyymmdd[YYYYMMDD];
- char dbuf[26];
- char daybuf[3];
- char monbuf[3];
- char yearbuf[5];
- char timbuf[16], *tb, cc;
- char * dp = NULL; /* Result pointer */
-
- if (!s) s = "";
- tmpbuf[0] = NUL;
-
- while (*s == SP) s++; /* Gobble any leading blanks */
- if (isalpha(*s)) /* Remember if 1st char is a letter */
- isletter = 1;
-
- len = strlen(s);
- debug(F110,"cmcvtdate",s,len);
- if (len == 0) { /* No arg - return current date-time */
- dp = ckdate();
- goto xcvtdate;
- }
- if (len > DATEBUFLEN) { /* Check length of arg */
- makestr(&cmdatemsg,"Date-time string too long");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- hh = 0; /* Init time to 00:00:00.0 */
- mm = 0;
- ss = 0;
- ff = 0;
- ztime(&p);
- if (!p)
- p = "";
- if (*p) { /* Init time to current time */
- x = ckstrncpy(dbuf,p,26);
- if (x > 17) {
- hh = atoi(&dbuf[11]);
- mm = atoi(&dbuf[14]);
- ss = atoi(&dbuf[17]);
- }
- }
- ckstrncpy(yyyymmdd,zzndate(),YYYYMMDD); /* Init date to current date */
- ckstrncpy(yearbuf,yyyymmdd,5);
- ckstrncpy(monbuf,&yyyymmdd[4],3);
- ckstrncpy(daybuf,&yyyymmdd[6],3);
- year = yearbuf;
- month = monbuf;
- day = daybuf;
- nday = atoi(daybuf);
- ckstrncpy(xbuf,s,DATEBUFLEN); /* Make a local copy we can poke */
- s = xbuf; /* Point to it */
- s[len] = NUL;
- if (s[0] == ':') {
- p = s;
- goto dotime;
- }
- /* Special preset formats... */
-
- if (len >= 14) { /* FTP MDTM all-numeric date */
- char c;
- c = s[14]; /* e.g. 19980615100045.014 */
- s[14] = NUL;
- x = rdigits(s);
- s[14] = c;
- if (x) {
- ckstrncpy(yyyymmdd,s,8+1);
- year = NULL;
- p = &s[8];
- goto dotime;
- }
- }
- x = 0; /* Becomes > 0 for asctime format */
- if (isalpha(s[0])) {
- if (len == 24) { /* Asctime format? */
- /* Sat Jul 14 15:57:32 2001 */
- x = ckmatch(atp1,s,0,0);
- debug(F111,"cmcvtdate asctime",s,x);
- } else if (len == 28) { /* Or Asctime plus timezone? */
- /* Sat Jul 14 15:15:39 EDT 2001 */
- x = ckmatch(atp2,s,0,0);
- debug(F111,"cmcvtdate asctime+timezone",s,x);
- }
- }
- if (x > 0) { /* Asctime format */
- int xx;
- strncpy(yearbuf,s + len - 4,4);
- yearbuf[4] = NUL;
- for (i = 0; i < 3; i++)
- tmpbuf[i] = s[i+4];
- tmpbuf[3] = NUL;
- if ((xx = lookup(cmonths,tmpbuf,12,NULL)) < 0) {
- makestr(&cmdatemsg,"Invalid month");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- debug(F101,"cmcvtdate asctime month","",xx);
- monbuf[0] = (xx / 10) + '0';
- monbuf[1] = (xx % 10) + '0';
- monbuf[2] = NUL;
- daybuf[0] = (s[8] == ' ' ? '0' : s[8]);
- daybuf[1] = s[9];
- daybuf[2] = NUL;
- xbuf[0] = SP;
- for (i = 11; i < 19; i++)
- xbuf[i-10] = s[i];
- xbuf[9] = NUL;
- ckmakmsg(zbuf,18,yearbuf,monbuf,daybuf,xbuf);
- debug(F110,"cmcvtdate asctime ok",zbuf,0);
- if (len == 24) {
- dp = zbuf;
- goto xcvtdate;
- } else {
- int n;
- n = ckmakmsg(ybuf,DATEBUFLEN-4,zbuf," ",NULL,NULL);
- ybuf[n++] = s[20];
- ybuf[n++] = s[21];
- ybuf[n++] = s[22];
- ybuf[n++] = NUL;
- ckstrncpy(xbuf,ybuf,DATEBUFLEN);
- s = xbuf;
- isletter = 0;
- }
- }
-
-/* Check for day of week */
-
- p = s;
- while (*p == SP) p++;
- dow = -1;
- if (*p) {
- p2 = p;
- cc = NUL;
- while (1) {
- if (*p2 == ',' || *p2 == SP || !*p2) {
- cc = *p2; /* Save break char */
- *p2 = NUL; /* NUL it out */
- p3 = p2; /* Remember this spot */
- if ((dow = lookup(daysofweek,p,7,NULL)) > -1) {
- debug(F111,"cmcvtdate dow",p,dow);
- s = p2;
- if (cc == ',' || cc == SP) { /* Point to next field */
- s++;
- while (*s == SP) s++;
- }
- p = s;
- debug(F111,"cmcvtdate dow new p",p,dow);
- break;
- } else if (isalpha(*p) && cc == ',') {
- makestr(&cmdatemsg,"Unrecognized day of week");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- } else {
- *p3 = cc;
- break;
- }
- }
- p2++;
- }
- }
- len = strlen(s); /* Update length */
- debug(F111,"cmcvtdate s",s,len);
-
- debug(F111,"cmcvtdate dow",s,dow);
- if (dow > -1) { /* Have a day-of-week number */
- long zz; int n, j;
- zz = mjd(zzndate()); /* Get today's MJD */
- debug(F111,"cmcvtdate zz","",zz);
- j = (((int)(zz % 7L)) + 3) % 7; /* Today's day-of-week number */
- debug(F111,"cmcvtdate j","",j);
- hh = 0; /* Init time to midnight */
- mm = 0;
- ss = 0;
- if (j == dow) {
- ckstrncpy(yyyymmdd,zzndate(),YYYYMMDD);
- year = NULL;
- } else {
- n = dow - j; /* Days from now */
- if (dow < j)
- n += 7;
- if (n < 0) n += 7; /* Add to MJD */
- zz += n;
- ckstrncpy(yyyymmdd,mjd2date(zz),YYYYMMDD); /* New date */
- year = NULL;
- }
- debug(F111,"cmcvtdate A",yyyymmdd,len);
- if (len == 0) { /* No more fields after this */
- ckmakmsg(zbuf,18,yyyymmdd," 00:00:00",NULL,NULL);
- dp = zbuf;
- goto xcvtdate;
- }
- isletter = 0;
- if (rdigits(p) && len < 8) /* Next field is time? */
- goto dotime; /* If so go straight to time section */
- if (isdigit(*p)) {
- if (*(p+1) == ':')
- goto dotime;
- else if (isdigit(*(p+1)) && (*(p+2) == ':'))
- goto dotime;
- }
- }
- debug(F111,"cmcvtdate B s",s,dow);
- debug(F111,"cmcvtdate B p",p,dow);
-
- if (*s == '+' || *s == '-') { /* Delta time only - skip ahead. */
- p = s;
- goto delta;
- }
-#ifdef COMMENT
-/*
- What is the purpose of this? It breaks parsing of email dates like
- "Wed, 13 Feb 2002 17:43:02 -0800 (PST)". Removing this code fixes the
- problem and Kermit still passes the 'dates' script.
- - fdc, Sat Nov 26 10:52:45 2005.
-*/
- if (dow > -1) {
- /* Day of week given followed by something that is not a time */
- /* or a delta so it can't be valid */
- makestr(&cmdatemsg,"Invalid tokens after day of week");
- debug(F111,"cmcvtdate fail",cmdatemsg,-1);
- return(NULL);
- }
-#endif /* COMMENT */
-
- /* Handle "today", "yesterday", "tomorrow", and +/- n units */
-
- if (ckstrchr("TtYyNn",s[0])) {
- int i, k, n, minus = 0;
- char c;
- long jd;
- jd = mjd(ckdate());
- debug(F111,"cmcvtdate mjd",s,jd);
-
- /* Symbolic date: TODAY, TOMORROW, etc...? */
-
- s2 = s; /* Find end of keyword */
- i = 0;
- while (isalpha(*s2)) { /* and get its length */
- i++;
- s2++;
- }
- c = *s2; /* Zap but save delimiter */
- *s2 = NUL;
- k = lookup(symdaytab,s,nsymdays,NULL); /* Look up keyword */
- *s2 = c; /* Replace delimiter */
- if (k < 0) /* Keyword not found */
- goto normal;
- s3 = &s[i];
- while (*s3 == SP) /* Skip whitespace */
- s3++;
- if (*s3 == '_' || *s3 == ':')
- s3++;
-
- switch (k) { /* Have keyword */
- case SYM_NOW: /* NOW */
- ckstrncpy(ybuf,ckdate(),DATEBUFLEN);
- ckstrncpy(yyyymmdd,ybuf,YYYYMMDD);
- year = NULL;
- if (*s3) { /* No overwriting current time. */
- ckstrncat(ybuf," ",DATEBUFLEN);
- ckstrncat(ybuf,s3,DATEBUFLEN);
- }
- break;
- default: /* Yesterday, Today, and Tomorrow */
- if (k == SYM_TOMO) { /* TOMORROW */
- strncpy(ybuf,mjd2date(jd+1),8);
- } else if (k == SYM_YEST) { /* YESTERDAY */
- strncpy(ybuf,mjd2date(jd-1),8);
- } else { /* TODAY */
- strncpy(ybuf,ckdate(),8);
- }
- strncpy(ybuf+8," 00:00:00",DATEBUFLEN-8); /* Default time is 0 */
- ckstrncpy(yyyymmdd,ybuf,YYYYMMDD);
- year = NULL;
- if (*s3) { /* If something follows keyword... */
- if (isdigit(*s3)) { /* Time - overwrite default time */
- strncpy(ybuf+8,s+i,DATEBUFLEN-8);
- } else { /* Something else, keep default time */
- ckstrncat(ybuf," ",DATEBUFLEN); /* and append */
- ckstrncat(ybuf,s3,DATEBUFLEN); /* whatever we have */
- }
- }
- }
- s = ybuf; /* Point to rewritten date-time */
- len = strlen(s); /* Update length */
- isletter = 0; /* Cancel this */
- }
-
-/* Regular free-format non-symbolic date */
-
- normal:
-
- debug(F111,"cmcvtdate NORMAL",s,len);
- debug(F111,"cmcvtdate dow",s,dow);
- if (yyyymmdd[0] && !year) {
- ckstrncpy(yearbuf,yyyymmdd,5);
- ckstrncpy(monbuf,&yyyymmdd[4],3);
- ckstrncpy(daybuf,&yyyymmdd[6],3);
- year = yearbuf;
- month = monbuf;
- day = daybuf;
- nday = atoi(daybuf);
- }
- if (isdigit(s[0])) { /* Time without date? */
- p = s;
- if (s[1] == ':') {
- debug(F111,"cmcvtdate NORMAL X1",s,len);
- goto dotime;
- } else if (len > 1 && isdigit(s[1]) && s[2] == ':') {
- debug(F111,"cmcvtdate NORMAL X2",s,len);
- goto dotime;
- } else if (rdigits(s) && len < 8) {
- debug(F111,"cmcvtdate NORMAL X3",s,len);
- goto dotime;
- }
- }
- if (len >= 8 && isdigit(*s)) { /* Check first for yyyymmdd* */
- debug(F111,"cmcvtdate NORMAL A",s,len);
- cc = s[8];
- s[8] = NUL; /* Isolate first 8 characters */
- if (rdigits(s)) {
- /* Have valid time separator? */
- p2 = cc ? ckstrchr(" Tt_-:",cc) : NULL;
- if (!cc || p2) {
- ckstrncpy(yyyymmdd,s,YYYYMMDD); /* Valid separator */
- year = NULL;
- s += 8; /* or time not given */
- if (cc) s++; /* Keep date */
- p = s; /* and go handle time */
- goto dotime;
- } else if (!p2) {
- if (isdigit(cc))
- makestr(&cmdatemsg,"Numeric date too long");
- else
- makestr(&cmdatemsg,"Invalid date-time separator");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- }
- s[8] = cc; /* Put this back! */
- }
- debug(F111,"cmcvtdate NORMAL non-yyyymmdd",s,len);
-
- /* Free-format date -- figure it out */
-
-#ifdef COMMENT
- if (*s && !isdigit(*s)) {
- makestr(&cmdatemsg,"Unrecognized word in date");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
-#endif /* COMMENT */
- for (i = 0; i < 8; i++) /* Field types */
- ft[i] = -1;
- fld[i = 0] = (p = s); /* First field */
- while (*p) { /* Get next two fields */
- if (isdatesep(*p)) { /* Have a date separator */
- if (i == 0) {
- datesep = *p;
- } else if (i == 1 && *p != datesep) {
- makestr(&cmdatemsg,"Inconsistent date separators");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- *p++ = NUL; /* Replace by NUL */
- if (*p) { /* Now we're at the next field */
- while (*p == SP) p++; /* Skip leading spaces */
- if (!*p) break; /* Make sure we still have something */
- if (i == 2) /* Last one? */
- break;
- fld[++i] = p; /* No, record pointer to this one */
- } else {
- break;
- }
- } else if ((*p == 'T' || *p == 't') && isdigit(*(p+1))) { /* Time */
- *p++ = NUL;
- break;
- } else if (*p == ':') {
- if (i == 0 && p == s) {
- nodate = 1;
- break;
- } else if (i != 0) { /* After a date */
- if (i == 2) { /* OK as date-time separator (VMS) */
- *p++ = NUL;
- break;
- }
- if (i < 2)
- makestr(&cmdatemsg,"Too few fields in date");
- else
- makestr(&cmdatemsg,"Misplaced time separator");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- nodate = 1; /* Or without a date */
- break;
- }
- p++;
- }
- if (p > s && i == 0) /* Make sure we have a date */
- nodate = 1; /* No date. */
-
- if (nodate && dow > -1) { /* Have implied date from DOW? */
- goto dotime; /* Use, use that, go do time. */
-
- } else if (nodate) { /* No date and no implied date */
- char *tmp = NULL; /* Substitute today's date */
- ztime(&tmp);
- if (!tmp)
- tmp = "";
- if (!*tmp) {
- makestr(&cmdatemsg,"Problem supplying current date");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- ckstrncpy(dbuf,tmp,26); /* Reformat */
- if (dbuf[8] == SP) dbuf[8] = '0';
- fld[0] = dbuf+8; /* dd */
- dbuf[10] = NUL;
- fld[1] = dbuf+4; /* mmm */
- dbuf[7] = NUL;
- fld[2] = dbuf+20; /* yyyy */
- dbuf[24] = NUL;
- hh = atoi(&dbuf[11]);
- mm = atoi(&dbuf[14]);
- ss = atoi(&dbuf[17]);
- p = s; /* Back up source pointer to reparse */
- } else if (i < 2) {
- makestr(&cmdatemsg,"Too few fields in date");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- /* Have three date fields - see what they are */
-
- for (k = 0, j = 0; j < 3; j++) { /* Get number of non-numeric fields */
- ft[j] = rdigits(fld[j]);
- debug(F111,"cmcvtdate fld",fld[j],j);
- if (ft[j] == 0)
- k++;
- }
- kn = k; /* How many numeric fields */
- month = NULL; /* Strike out default values */
- year = NULL;
- day = NULL;
-
- if (k == 2 && ft[2] > 0) { /* Jul 20, 2001 */
- int xx;
- xx = strlen(fld[1]);
- p3 = fld[1];
- if (xx > 0) if (p3[xx-1] == ',') {
- p3[xx-1] = NUL;
- if (rdigits(p3)) {
- k = 1;
- ft[1] = 1;
- } else p3[xx-1] = ',';
- }
- }
- if (k > 1) { /* We can have only one non-numeric */
- if (nodate)
- makestr(&cmdatemsg,"Unrecognized word in date");
- else if (!ft[2] && isdigit(*(fld[2])))
- makestr(&cmdatemsg,"Invalid date-time separator");
- else
- makestr(&cmdatemsg,"Too many non-numeric fields in date");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- if (!ft[0]) {
- k = 0;
- } else if (!ft[1]) {
- k = 1;
- } else if (!ft[2]) {
- makestr(&cmdatemsg,"Non-digit in third date field");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- } else
- k = -1;
-
- if (k > -1) {
- if ((x = lookup(cmonths,fld[k],12,NULL)) < 0) {
- makestr(&cmdatemsg,"Unknown month");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- sprintf(tmpbuf,"%02d",x);
- month = tmpbuf;
- }
- f2len = strlen(fld[2]); /* Length of 3rd field */
-
- if (k == 0) { /* monthname dd, yyyy */
- day = fld[1];
- year = fld[2];
- } else if (((int)strlen(fld[0]) == 4)) { /* yyyy-xx-dd */
- year = fld[0];
- day = fld[2];
- if (!month)
- month = fld[1]; /* yyyy-mm-dd */
- } else if (f2len == 4) { /* xx-xx-yyyy */
- year = fld[2];
- if (month) { /* dd-name-yyyy */
- day = fld[0];
- } else { /* xx-xx-yyyy */
- int f0, f1;
- f0 = atoi(fld[0]);
- f1 = atoi(fld[1]);
- if (((f0 > 12) && (f1 <= 12)) || (f1 <= 12 && f0 == f1)) {
- day = fld[0]; /* mm-dd-yyyy */
- month = fld[1];
- } else if ((f0 <= 12) && (f1 > 12)) {
- if (!rdigits(fld[1])) {
- makestr(&cmdatemsg,"Day not numeric");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- } else {
- day = fld[1]; /* dd-mm-yyyy */
- }
- month = fld[0];
- } else {
- if (!f0 || !f1)
- makestr(&cmdatemsg,"Day or month out of range");
- else
- makestr(&cmdatemsg,"Day and month are ambiguous");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- }
- } else if ((f2len < 4) && /* dd mmm yy (RFC822) */
- !rdigits(fld[1]) && /* middle field is monthname */
- rdigits(fld[2])) {
- int tmpyear;
- day = fld[0];
- if (!fld[2][1]) {
- makestr(&cmdatemsg,"Too few digits in year");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- tmpyear = atoi(fld[2]);
- if (tmpyear < 50) /* RFC 2822 windowing */
- tmpyear += 2000;
- else /* This includes 3-digit years. */
- tmpyear += 1900;
- year = ckitoa(tmpyear);
-
- } else if ((f2len < 4) && (k < 0) && ((int)strlen(fld[0]) < 4)) {
- makestr(&cmdatemsg,"Ambiguous numeric date");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- } else if ((f2len > 4) && ft[2]) {
- makestr(&cmdatemsg,"Too many digits in year");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- } else {
- makestr(&cmdatemsg,"Unexpected date format");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- x = atoi(month);
- sprintf(tmpbuf,"%02d",x); /* 2-digit numeric month */
-
-/*
- state = 1 = hours
- state = 2 = minutes
- state = 3 = seconds
- state = 4 = fractions of seconds
-*/
-
- dotime:
- if (isletter && (s == p)) {
- makestr(&cmdatemsg,"Unknown date-time word");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- if (!year && yyyymmdd[0]) {
- debug(F110,"cmcvtdate dotime yyyymmdd",yyyymmdd,0);
- for (i = 0; i < 4; i++)
- yearbuf[i] = yyyymmdd[i];
- yearbuf[4] = NUL;
- monbuf[0] = yyyymmdd[4];
- monbuf[1] = yyyymmdd[5];
- monbuf[2] = NUL;
- daybuf[0] = yyyymmdd[6];
- daybuf[1] = yyyymmdd[7];
- daybuf[2] = NUL;
- day = daybuf;
- nday = atoi(daybuf);
- month = monbuf;
- year = yearbuf;
- }
- if (!year) {
- makestr(&cmdatemsg,"Internal error - date not defaulted");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- /* Get here with day, month, and year set */
- debug(F110,"cmcvtdate dotime day",day,0);
- debug(F110,"cmcvtdate dotime month",month,0);
- debug(F110,"cmcvtdate dotime year",year,0);
- debug(F110,"cmcvtdate dotime s",s,0);
- debug(F110,"cmcvtdate dotime p",p,0);
- x = atoi(month);
- if (x > 12 || x < 1) {
- makestr(&cmdatemsg,"Month out of range");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- nday = atoi(day);
- i = mdays[x];
- if (x == 2) if (isleap(atoi(year))) i++;
- if (nday > i || nday < 1) {
- makestr(&cmdatemsg,"Day out of range");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- if (!*p && t == 0) {
- sprintf(zbuf,"%04d%02d%02d",atoi(year),atoi(month),nday);
- dp = zbuf;
- goto xcvtdate;
- }
- if (*p == '+' || *p == '-') { /* GMT offset without a time */
- hh = 0; /* so default time to 00:00:00 */
- mm = 0;
- ss = 0;
- goto cmtimezone; /* and go do timezone */
- }
- if (*p && !isdigit(*p) && *p != ':') {
- makestr(&cmdatemsg,"Invalid time");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- sprintf(yyyymmdd,"%s%s%02d",year,month,nday); /* for tz calculations... */
-
- state = 1; /* Initialize time-parsing FSA */
- hh = 0; /* hours */
- mm = 0; /* minutes */
- ss = 0; /* seconds */
- ff = -1; /* fraction */
- d = 0; /* Digit counter */
- p2 = p; /* Preliminary digit count... */
- while (isdigit(*p2)) {
- d++;
- p2++;
- }
- if (d > 6) {
- makestr(&cmdatemsg,"Too many time digits");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- d = (d & 1 && *p2 != ':') ? 1 : 0; /* Odd implies leading '0' */
-
- while (*p) { /* Get the time, if any */
- if (isdigit(*p)) { /* digit */
- if (d++ > 1) {
- state++;
- d = 1;
- }
- switch (state) {
- case 1: /* Hours */
- hh = hh * 10 + (*p - '0');
- break;
- case 2: /* Minutes */
- mm = mm * 10 + (*p - '0');
- break;
- case 3: /* Seconds */
- ss = ss * 10 + (*p - '0');
- break;
- case 4: /* Fraction of second */
- if (ff < 0)
- ff = (*p > '4') ? 1 : 0;
- break;
- }
- } else if (*p == ':') { /* Colon */
- state++;
- d = 0;
- if (state > 3) {
- makestr(&cmdatemsg,"Too many time fields");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- } else if (*p == '.') {
- if (state == 3) {
- state = 4;
- d = 0;
- } else {
- makestr(&cmdatemsg,"Improper fraction");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- } else if (*p == SP) { /* Space */
- while (*p && (*p == SP)) /* position to first nonspace */
- p++;
- break;
- } else if (isalpha(*p)) { /* AM/PM/Z or timezone */
- break;
- } else if (*p == '+' || *p == '-') { /* GMT offset */
- break;
- } else {
- makestr(&cmdatemsg,"Invalid time characters");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- p++;
- }
- if (!*p) /* If nothing left */
- goto xcmdate; /* go finish up */
-
- /* At this point we have HH, MM, SS, and FF */
- /* Now handle the rest: AM, PM, and/or timezone info */
-
- if (!ckstrcmp(p,"am",2,0)) { /* AM/PM... */
- pmflag = 0;
- p += 2;
- } else if (!ckstrcmp(p,"a.m.",4,0)) {
- pmflag = 0;
- p += 4;
- } else if (!ckstrcmp(p,"pm",2,0)) {
- pmflag = 1;
- p += 2;
- } else if (!ckstrcmp(p,"p.m.",4,0)) {
- pmflag = 1;
- p += 4;
- }
- if (pmflag && hh < 12) /* If PM was given */
- hh += 12; /* add 12 to the hour */
-
- /* Now handle timezone */
-
- cmtimezone:
- debug(F110,"cmcvtdate timezone",p,0);
-
- zhh = 0; /* GMT offset HH */
- zmm = 0; /* GMT offset MM */
- gmtsign = 0; /* Sign of GMT offset */
- isgmt = 0; /* 1 if time is GMT */
-
- while (*p && *p == SP) /* Gobble spaces */
- p++;
- if (!*p) /* If nothing left */
- goto xcmdate; /* we're done */
-
- if (isalpha(*p)) { /* Something left */
- int zone = 0; /* Alphabetic must be timezone */
- p2 = p; /* Isolate timezone */
- p++;
- while (isalpha(*p))
- p++;
- p3 = p;
- cc = *p;
- *p = NUL;
- p = p2; /* Have timezone, look it up */
- zone = lookup(usatz,p,nusatz,NULL);
- debug(F111,"cmcvtdate timezone alpha",p,zone);
-
- if (zone < 0) { /* Not found */
- makestr(&cmdatemsg,"Unknown timezone");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- isgmt++; /* All dates are GMT from here down */
- if (zone != 0) { /* But not this one so make it GMT */
- hh += zone; /* RFC 822 timezone: EST etc */
- debug(F101,"cmcvtdate hh + zone","",hh);
- if (hh > 23) { /* Offset crosses date boundary */
- int i;
- long jd;
- jd = mjd(yyyymmdd); /* Get MJD */
- jd += hh / 24; /* Add new day(s) */
- hh = hh % 24; /* and convert back to yyyymmdd */
- ckstrncpy(yyyymmdd,mjd2date(jd),YYYYMMDD);
- debug(F111,"cmcvtdate zone-adjusted date",yyyymmdd,hh);
- for (i = 0; i < 4; i++)
- yearbuf[i] = yyyymmdd[i];
- yearbuf[4] = NUL;
- monbuf[0] = yyyymmdd[4];
- monbuf[1] = yyyymmdd[5];
- monbuf[2] = NUL;
- daybuf[0] = yyyymmdd[6];
- daybuf[1] = yyyymmdd[7];
- daybuf[2] = NUL;
- day = daybuf;
- nday = atoi(daybuf);
- month = monbuf;
- year = yearbuf;
- }
- }
- p = p3; /* Put back whatever we poked above */
- *p = cc;
-
- } else if (*p == '+' || *p == '-') { /* GMT/UTC offset */
- p3 = p;
- debug(F110,"cmcvtdate timezone GMT offset",p,0);
- gmtsign = (*p == '+') ? -1 : 1;
- isgmt++;
- p++;
- while (*p == SP) p++;
- d = 0;
- p2 = p;
- while (isdigit(*p)) { /* Count digits */
- d++;
- p++;
- }
- if (d != 4) { /* Strict RFC [2]822 */
- isgmt = 0; /* If not exactly 4 digits */
- p = p3; /* it's not a GMT offset. */
- goto delta; /* So treat it as a delta time. */
- }
- d = (d & 1 && *p != ':') ? 1 : 0; /* Odd implies leading '0' */
- p = p2;
- debug(F111,"cmcvtdate GMT offset sign",p,gmtsign);
- debug(F101,"cmcvtdate GMT offset d","",d);
- state = 1;
- while (*p) {
- if (isdigit(*p)) { /* digit */
- if (d++ > 1) {
- state++;
- d = 1;
- }
- switch (state) {
- case 1:
- zhh = zhh * 10 + (*p - '0');
- break;
- case 2:
- zmm = zmm * 10 + (*p - '0');
- break;
- default: /* Ignore seconds or fractions */
- break;
- }
- } else if (*p == ':') { /* Colon */
- state++;
- d = 0;
- } else if (*p == SP || *p == '(') {
- break;
- } else {
- p = p3; /* Maybe it's not a GMT offset. */
- goto delta; /* So treat it as a delta time. */
- }
- p++;
- }
- }
- debug(F110,"cmcvtdate source string after timezone",p,0);
-
- if (*p) { /* Anything left? */
- p2 = p;
- while (*p2 == SP) /* Skip past spaces */
- p2++;
- if (*p2 == '(') { /* RFC-822 comment? */
- int pc = 1; /* paren counter */
- p2++;
- while (*p2) {
- if (*p2 == ')') {
- if (--pc == 0) {
- p2++;
- break;
- }
- } else if (*p2 == ')') {
- pc++;
- }
- p2++;
- }
- while (*p2 == SP) /* Skip past spaces */
- p2++;
- if (!*p2) /* Anything left? */
- *p = NUL; /* No, erase comment */
- }
- if (!*p2) /* Anything left? */
- goto xcmdate; /* No, done. */
- p = p2;
-
- delta:
- debug(F110,"cmcvtdate delta yyyymmdd",yyyymmdd,0);
- debug(F110,"cmcvtdate delta year",year,0);
- debug(F110,"cmcvtdate delta p",p,0);
-
- if (*p == '+' || *p == '-') { /* Delta time */
- int state = NEED_DAYS; /* Start off looking for days */
- char c = 0;
- dsign = 1; /* Get sign */
- if (*p++ == '-')
- dsign = -1;
- while (*p == SP) /* Skip intervening spaces */
- p++;
- while (state) { /* FSA to parse delta time */
- if (state < 0 || !isdigit(*p)) {
- makestr(&cmdatemsg,"Invalid delta time");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- p2 = p; /* Get next numeric field */
- while (isdigit(*p2))
- p2++;
- c = *p2; /* And break character */
- *p2 = NUL; /* Terminate the number */
-
- switch (state) { /* Interpret according to state */
- case NEED_DAYS: /* Initial */
- if ((c == '-') || /* VMS format */
- ((c == 'd' || c == 'D')
- && !isalpha(*(p2+1)))) { /* Days */
- ddays = atoi(p);
- if (!*(p2+1))
- state = 0;
- else /* if anything is left */
- state = NEED_HRS; /* now we want hours. */
- } else if ((c == 'W' || c == 'w') && !isalpha(*(p2+1))) {
- ddays = atoi(p) * 7; /* weeks... */
- if (!*(p2+1))
- state = 0;
- else
- state = NEED_HRS;
- } else if ((c == 'M' || c == 'm') && !isalpha(*(p2+1))) {
- dmonths = atoi(p); /* months... */
- if (!*(p2+1))
- state = 0;
- else
- state = NEED_HRS;
- } else if ((c == 'Y' || c == 'y') && !isalpha(*(p2+1))) {
- dyears = atoi(p); /* years... */
- if (!*(p2+1))
- state = 0;
- else
- state = NEED_HRS;
- } else if (c == ':') { /* delimiter is colon */
- dhours = atoi(p); /* so it's hours */
- state = NEED_MINS; /* now we want minutes */
- } else if (!c) { /* end of string */
- dhours = atoi(p); /* it's still hours */
- state = 0; /* and we're done */
- } else if (isalpha(c) || c == SP) {
- if (c == SP) { /* It's a keyword? */
- p2++; /* Skip spaces */
- while (*p2 == SP)
- p2++;
- } else { /* or replace first letter */
- *p2 = c;
- }
- p3 = p2; /* p2 points to beginning of keyword */
- while (isalpha(*p3)) /* Find end of keyword */
- p3++;
- c = *p3; /* NUL it out so we can look it up */
- if (*p3) /* p3 points to keyword terminator */
- *p3 = NUL;
- units = lookup(timeunits,p2,nunits,NULL);
- if (units < 0) {
- makestr(&cmdatemsg,"Invalid units in delta time");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- *p2 = NUL; /* Re-terminate the number */
- *p3 = c;
- while (*p3 == SP) /* Point at field after units */
- p3++;
- p2 = p3;
- switch (units) {
- case TU_DAYS:
- ddays = atoi(p);
- break;
- case TU_WEEKS:
- ddays = atoi(p) * 7;
- break;
- case TU_MONTHS:
- dmonths = atoi(p);
- break;
- case TU_YEARS:
- dyears = atoi(p);
- break;
- }
- if (*p2) {
- state = NEED_HRS;
- p2--;
- } else
- state = 0;
-
- } else { /* Anything else */
- state = -1; /* is an error */
- }
- break;
- case NEED_HRS: /* Looking for hours */
- debug(F000,"cmcvtdate NEED_HRS",p,c);
- if (c == ':') {
- dhours = atoi(p);
- state = NEED_MINS;
- } else if (!c) {
- dhours = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_MINS: /* Looking for minutes */
- if (c == ':') {
- dmins = atoi(p);
- state = NEED_SECS;
- } else if (!c) {
- dmins = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_SECS: /* Looking for seconds */
- if (c == '.') {
- dsecs = atoi(p);
- state = NEED_FRAC;
- } else if (!c) {
- dsecs = atoi(p);
- state = 0;
- } else {
- state = -1;
- }
- break;
- case NEED_FRAC: /* Fraction of second */
- if (!c && rdigits(p)) {
- if (*p > '4')
- dsecs++;
- state = 0;
- } else {
- state = -1;
- }
- break;
- }
- if (c) /* next field if any */
- p = p2 + 1;
- }
- havedelta = 1;
-
- } else {
- makestr(&cmdatemsg,"Extraneous material at end");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- }
-
- xcmdate:
-
- if ((t != 2 && hh > 24) || hh < 0) { /* Hour range check */
- makestr(&cmdatemsg,"Invalid hours");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- if (mm > 59) { /* Minute range check */
- makestr(&cmdatemsg,"Invalid minutes");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- if (ff > 0) { /* Fraction of second? */
- if (ss < 59) {
- ss++;
- ff = 0;
- } else if (mm < 59) {
- ss = 0;
- mm++;
- ff = 0;
- } else if (hh < 24) {
- ss = 0;
- mm = 0;
- hh++;
- ff = 0;
- }
- /* Must add a day -- leave ff at 1... */
- /* (DO SOMETHING ABOUT THIS LATER) */
- }
- if (ss > 60) { /* Seconds range check */
- makestr(&cmdatemsg,"Invalid seconds"); /* 60 is ok because of */
- debug(F111,"cmcvtdate",cmdatemsg,-1); /* Leap Second. */
- return(NULL);
- }
- if ((mm < 0 || ss < 0) ||
- (t != 2 && (ss > 0 || mm > 0) && hh > 23)) {
- makestr(&cmdatemsg,"Invalid minutes or seconds");
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- debug(F110,"cmcvtdate year",year,0);
- debug(F110,"cmcvtdate month",month,0);
- debug(F101,"cmcvtdate nday","",nday);
- debug(F101,"cmcvtdate hh","",hh);
- debug(F101,"cmcvtdate mm","",mm);
- debug(F101,"cmcvtdate ss","",ss);
- debug(F101,"cmcvtdate gmtsign","",gmtsign);
- debug(F101,"cmcvtdate zhh","",zhh);
- debug(F101,"cmcvtdate zmm","",zmm);
- debug(F101,"cmcvtdate isgmt","",isgmt);
-
-#ifdef ZLOCALTIME
-/* Handle timezone -- first convert to GMT */
-
- zdd = 0; /* Days changed */
- if (isgmt && (zmm || zhh)) { /* If GMT offset given */
- long sec1, sec2, zz;
- sec1 = ss + 60 * mm + 3600 * hh;
- sec2 = gmtsign * (60 * zmm + 3600 * zhh);
- sec1 += sec2;
- if (sec1 < 0) {
- sec1 = 0 - sec1;
- zdd = 0L - (sec1 / 86400L);
- sec1 = sec1 % 86400L;
- } else if (sec1 > 86400L) {
- zdd = sec1 / 86400L;
- sec1 = sec1 % 86400L;
- }
- ss = sec1 % 60;
- zz = sec1 / 60;
- mm = zz % 60;
- hh = zz / 60;
- debug(F101,"cmcvtdate NEW hh","",hh);
- debug(F101,"cmcvtdate NEW mm","",mm);
- debug(F101,"cmcvtdate NEW dd","",zdd);
-
-/* At this point hh:mm:ss is in GMT and zdd is the calendar adjustment */
-
- }
-#endif /* ZLOCALTIME */
-
- if (yyyymmdd[0] && !year) {
- ckstrncpy(yearbuf,yyyymmdd,5);
- ckstrncpy(monbuf,&yyyymmdd[4],3);
- ckstrncpy(daybuf,&yyyymmdd[6],3);
- year = yearbuf;
- month = monbuf;
- day = daybuf;
- nday = atoi(daybuf);
- }
- sprintf(zbuf,"%04d%02d%02d %02d:%02d:%02d", /* SAFE */
- atoi(year),atoi(month),nday,hh,mm,ss
- );
- dp = zbuf;
-
-#ifdef ZLOCALTIME
- /* Now convert from GMT to local time */
-
- if (isgmt) { /* If GMT convert to local time */
- debug(F110,"cmcvtdate GMT 1",dp,0);
- if (zdd) { /* Apply any calendar adjustment */
- long zz;
- zz = mjd(dp) + zdd;
- sprintf(zbuf,"%s %02d:%02d:%02d",mjd2date(zz),hh,mm,ss);
- }
- debug(F110,"cmcvtdate GMT 2",dp,0);
- if ((p = zlocaltime(dp))) {
- debug(F110,"cmcvtdate asctime zlocaltime",p,0);
- if (p) ckstrncpy(zbuf,p,18);
- }
- debug(F110,"cmcvtdate GMT 3",dp,0);
- for (i = 0; i < 4; i++)
- yearbuf[i] = dp[i];
- yearbuf[4] = NUL;
- monbuf[0] = dp[4];
- monbuf[1] = dp[5];
- monbuf[2] = NUL;
- daybuf[0] = dp[6];
- daybuf[1] = dp[7];
- daybuf[2] = NUL;
- day = daybuf;
- nday = atoi(daybuf);
- month = monbuf;
- year = yearbuf;
- hh = atoi(&dp[9]);
- mm = atoi(&dp[12]);
- ss = atoi(&dp[15]);
- }
-#endif /* ZLOCALTIME */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"cmcvtdate hour","",hh);
- debug(F101,"cmcvtdate minute","",mm);
- debug(F101,"cmcvtdate second","",ss);
- }
-#endif /* DEBLOG */
-
- makestr(&cmdatemsg,NULL);
- if (havedelta) {
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"cmcvtdate base ",dp,0);
- debug(F101,"cmcvtdate delta sign","",dsign);
- debug(F101,"cmcvtdate delta yrs ","",dyears);
- debug(F101,"cmcvtdate delta mos ","",dmonths);
- debug(F101,"cmcvtdate delta days","",ddays);
- debug(F101,"cmcvtdate delta hrs ","",dhours);
- debug(F101,"cmcvtdate delta mins","",dmins);
- debug(F101,"cmcvtdate delta secs","",dsecs);
- }
-#endif /* DEBLOG */
- if (!(dp = cmdelta(atoi(year),
- atoi(month),
- nday, hh, mm, ss,
- dsign, dyears, dmonths, ddays, dhours, dmins, dsecs))) {
- debug(F111,"cmcvtdate",cmdatemsg,-1);
- return(NULL);
- }
- }
-
- xcvtdate: /* Exit point for success */
- {
- int len, k, n;
- char * p;
- debug(F110,"cmcvtdate xcvtdate dp",dp,0);
- if (!dp) dp = ""; /* Shouldn't happen */
- if (!*dp) return(NULL); /* ... */
- len = strlen(dp);
- debug(F111,"cmcvtdate result",dp,len);
- k = cmdatebp - (char *)cmdatebuf; /* Space used */
- n = CMDATEBUF - k - 1; /* Space left */
- if (n < len) { /* Not enough? */
- cmdatebp = cmdatebuf; /* Wrap around */
- n = CMDATEBUF;
- }
- ckstrncpy(cmdatebp,dp,n);
- p = cmdatebp;
- cmdatebp += len + 1;
- return(p);
- }
-}
-
-int
-cmvdate(d) char * d; { /* Verify date-time */
- int i;
- if (!d) return(0);
- if ((int)strlen(d) != 17) return(0);
- for (i = 0; i < 8; i++) { if (!isdigit(d[i])) return(0); }
- if (!isdigit(d[9]) || !isdigit(d[10]) ||
- !isdigit(d[12]) || !isdigit(d[13]) ||
- !isdigit(d[15]) || !isdigit(d[16]))
- return(0);
- if (!ckstrchr(" Tt_-:",d[8])) return(0);
- if (d[11] != ':' && d[14] != ':') return(0);
- return(1);
-}
-
-/* c m d i f f d a t e -- Get difference between two date-times */
-
-char *
-cmdiffdate(d1,d2) char * d1, * d2; {
- char d1buf[9], d2buf[9];
- char x1buf[18], x2buf[18];
- char * p;
-
- int hh1 = 0, mm1 = 0, ss1 = 0;
- int hh2 = 0, mm2 = 0, ss2 = 0;
- int hh, mm, ss;
- int sign;
- long jd1, jd2, jd, f1, f2, fx;
- static char result[24], *rp;
-
- debug(F110,"cmdiffdate d1 A",d1,0);
- debug(F110,"cmdiffdate d2 A",d2,0);
-
- if (!(p = cmcvtdate(d1,1))) /* Convert dates to standard format */
- return(NULL);
- ckstrncpy(x1buf,p,18);
- d1 = x1buf;
-
- if (!(p = cmcvtdate(d2,1)))
- return(NULL);
- ckstrncpy(x2buf,p,18);
- d2 = x2buf;
-
- debug(F110,"cmdiffdate d1 B",d1,0);
- debug(F110,"cmdiffdate d2 B",d2,0);
- if (!cmvdate(d1) || !cmvdate(d2))
- return(NULL);
-
- hh1 = atoi(&d1[9]); /* Get hours, minutes, and seconds */
- mm1 = atoi(&d1[12]); /* for first date */
- ss1 = atoi(&d1[15]);
- ckstrncpy(d1buf,d1,9);
-
- hh2 = atoi(&d2[9]); /* ditto for second date */
- mm2 = atoi(&d2[12]);
- ss2 = atoi(&d2[15]);
- ckstrncpy(d2buf,d2,9);
-
- jd1 = mjd(d1buf); /* Get the two Julian dates */
- jd2 = mjd(d2buf);
- f1 = ss1 + 60 * mm1 + 3600 * hh1; /* Convert first time to seconds */
-
- f2 = ss2 + 60 * mm2 + 3600 * hh2; /* Ditto for second time */
- debug(F101,"cmdiffdate jd1","",jd1);
- debug(F101,"cmdiffdate f1","",f1);
- debug(F101,"cmdiffdate jd2","",jd2);
- debug(F101,"cmdiffdate f2","",f2);
-
- if (jd2 > jd1 || (jd1 == jd2 && f2 > f1)) {
- sign = -1;
- if (f1 > f2) {jd2--; f2 += 86400L;}
- jd = jd2 - jd1;
- fx = f2 - f1;
- } else {
- sign = 1;
- if (f2 > f1) {jd1--; f1 += 86400L;}
- jd = jd1 - jd2;
- fx = f1 - f2;
- }
- debug(F111,"cmdiffdate sign jd",sign<0?"-":"+",jd);
- debug(F101,"cmdiffdate fx","",fx);
-
- hh = (int) (fx / 3600L); /* Convert seconds to hh:mm:ss */
-
- mm = (int) (fx % 3600L) / 60L;
- ss = (int) (fx % 3600L) % 60L;
-
- rp = result; /* Format the result */
- *rp++ = (sign < 0) ? '-' : '+';
- if (jd != 0 && hh+mm+ss == 0) {
- sprintf(rp,"%ldd",jd);
- } else if (jd == 0) {
- if (ss == 0)
- sprintf(rp,"%d:%02d",hh,mm);
- else
- sprintf(rp,"%d:%02d:%02d",hh,mm,ss);
- } else {
- if (ss == 0)
- sprintf(rp,"%ldd%d:%02d",jd,hh,mm);
- else
- sprintf(rp,"%ldd%d:%02d:%02d",jd,hh,mm,ss);
- }
- debug(F110,"cmdiffdate result",result,0);
- return((char *)result);
-}
-
-#ifndef NOSPL
-/* s h u f f l e d a t e -- Rearrange date string */
-
-/*
- Call with:
- A date string in standard format: yyyymmdd hh:mm:ss (time optional).
- Options:
- 1: Reformat date to yyyy-mmm-dd (mmm = English month abbreviation).
- 2: Reformat date to dd-mmm-yyyy (mmm = English month abbreviation).
- 3: Reformat as numeric yyyymmddhhmmss.
- 4: Reformat in asctime() format Sat Nov 26 11:10:34 2005
- Returns:
- Pointer to result if args valid, otherwise original arg pointer.
-*/
-char *
-shuffledate(p,opt) char * p; int opt; {
- extern char * wkdays[];
- int len;
- char ibuf[32];
- static char obuf[48];
- char c;
- int yy, dd, mm;
-
- if (!p) p = "";
- if (!*p) p = ckdate();
- if (opt < 1 || opt > 4)
- return(p);
- len = strlen(p);
- if (len < 8 || len > 31) return(p);
- if (opt == 4) { /* Asctime format (26 Nov 2005) */
- char c, * s;
- long z; int k;
- ckstrncpy(ibuf,p,31);
- k = len;
- while (k >= 0 && ibuf[k] == CR || ibuf[k] == LF)
- ibuf[k--] = NUL;
- while (k >= 0 && ibuf[k] == SP || ibuf[k] == HT)
- ibuf[k--] = NUL;
- if (k < 9) ckstrncpy(&ibuf[8]," 00:00:00",9);
- p = ibuf;
- z = mjd(p); /* Convert to modified Julian date */
- z = z % 7L;
- if (z < 0) {
- z = 0 - z;
- k = 6 - ((int)z + 3) % 7;
- } else {
- k = ((int)z + 3) % 7; /* Day of week */
- }
- s = wkdays[k];
- obuf[0] = s[0]; /* Day of week */
- obuf[1] = s[1];
- obuf[2] = s[2];
- obuf[3] = SP; /* Space */
- c = p[6];
- p[6] = NUL;
- mm = atoi(&ibuf[4]); /* Month */
- s = moname[mm-1]; /* Name of month */
- p[6] = c;
-
- obuf[4] = s[0]; /* Month */
- obuf[5] = s[1];
- obuf[6] = s[2];
- obuf[7] = SP; /* Space */
- if (p[6] == '0') /* Date of month */
- obuf[8] = SP;
- else
- obuf[8] = p[6];
- obuf[9] = p[7];
- ckstrncpy(&obuf[10],&p[8],10); /* Time */
- obuf[19] = SP; /* Space */
- obuf[20] = p[0]; /* Year */
- obuf[21] = p[1];
- obuf[22] = p[2];
- obuf[23] = p[3];
- obuf[24] = NUL;
- return((char *)obuf);
- }
- if (opt == 3) {
- ckstrncpy(obuf,p,48);
- /* yyyymmdd hh:mm:ss */
- /* 01234567890123456 */
- /* yyyymmddhhmmss */
- obuf[8] = obuf[9];
- obuf[9] = obuf[10];
- obuf[10] = obuf[12];
- obuf[11] = obuf[13];
- obuf[12] = obuf[15];
- obuf[13] = obuf[16];
- obuf[14] = NUL;
- return((char *)obuf);
- }
- ckstrncpy(ibuf,p,32);
- c = ibuf[4]; /* Warning: not Y10K compliant */
- ibuf[4] = NUL;
- if (!rdigits(ibuf))
- return(p);
- yy = atoi(ibuf);
- if (yy < 1 || yy > 9999)
- return(p);
- ibuf[4] = c;
- c = ibuf[6];
- ibuf[6] = NUL;
- if (!rdigits(&ibuf[4]))
- return(p);
- mm = atoi(&ibuf[4]);
- if (mm < 1 || mm > 12)
- return(p);
- ibuf[6] = c;
- c = ibuf[8];
- ibuf[8] = NUL;
- if (!rdigits(&ibuf[6]))
- return(p);
- dd = atoi(&ibuf[6]);
- ibuf[8] = c;
- if (dd < 1 || mm > 31)
- return(p);
- /* IGNORE WARNINGS ABOUT moname[] REFS OUT OF RANGE - it's prechecked. */
- switch (opt) {
- case 1:
- sprintf(obuf,"%04d-%s-%02d%s",yy,moname[mm-1],dd,&ibuf[8]);
- break;
- case 2:
- sprintf(obuf,"%02d-%s-%04d%s",dd,moname[mm-1],yy,&ibuf[8]);
- }
- return((char *)obuf);
-}
-#endif /* NOSPL */
-
-/* C K C V T D A T E -- Like cmcvtdate(), but returns string. */
-/* For use by date-related functions */
-/* See calling conventions for cmcvtdate() above. */
-
-char *
-ckcvtdate(p,t) char * p; int t; {
- char * s;
- if (!(s = cmcvtdate(p,t)))
- return("<BAD_DATE_OR_TIME>"); /* \fblah() error message */
- else
- return(s);
-}
-
-
-/* C M D A T E -- Parse a date and/or time */
-
-/*
- Accepts date in various formats. If the date is recognized,
- this routine returns 0 or greater with the result string pointer
- pointing to a buffer containing the date as "yyyymmdd hh:mm:ss".
-*/
-int
-cmdate(xhlp,xdef,xp,quiet,f) char *xhlp, *xdef, **xp; int quiet; xx_strp f; {
- int x, rc;
- char *o, *s, *zq, *dp;
-
- cmfldflgs = 0;
- if (!xhlp) xhlp = "";
- if (!xdef) xdef = "";
- if (!*xhlp) xhlp = "Date and/or time";
- *xp = "";
-
- rc = cmfld(xhlp,xdef,&s,(xx_strp)0);
- debug(F101,"cmdate cmfld rc","",rc);
- if (rc < 0)
- return(rc);
- debug(F110,"cmdate 1",s,0);
- o = s; /* Remember what they typed. */
- s = brstrip(s);
- debug(F110,"cmdate 2",s,0);
-
- x = 0;
- if (f) { /* If a conversion function is given */
- char * pp;
- zq = atxbuf; /* do the conversion. */
- pp = atxbuf;
- atxn = CMDBL;
- if ((x = (*f)(s,&zq,&atxn)) < 0) return(-2);
- if (!*pp)
- pp = xdef;
- if (setatm(pp,0) < 0) {
- if (!quiet) printf("?Evaluated date too long\n");
- return(-9);
- }
- s = atxbuf;
- }
- dp = cmcvtdate(s,1);
- if (!dp) {
- if (!quiet) printf("?%s\n",cmdatemsg);
- return(-9);
- }
- *xp = dp;
- return(0);
-}
-
-#ifdef CK_RECALL /* Command-recall functions */
-
-/* C M R I N I -- Initialize or change size of command recall buffer */
-
-int
-cmrini(n) int n; {
- int i;
- if (recall && in_recall) { /* Free old storage, if any */
- for (i = 0; i < cm_recall; i++) {
- if (recall[i]) {
- free(recall[i]);
- recall[i] = NULL;
- }
- }
- free(recall);
- recall = NULL;
- }
- cm_recall = n; /* Set new size */
- rlast = current = -1; /* Initialize pointers */
- if (n > 0) {
- recall = (char **)malloc((cm_recall + 1) * sizeof(char *));
- if (!recall)
- return(1);
- for (i = 0; i < cm_recall; i++) {
- recall[i] = NULL;
- }
- in_recall = 1; /* Recall buffers init'd */
- }
- return(0);
-}
-
-/* C M A D D N E X T -- Force addition of next command */
-
-VOID
-cmaddnext() {
- if (on_recall && in_recall) { /* Even if it doesn't come */
- force_add = 1; /* from the keyboard */
- newcmd = 1;
- no_recall = 0;
- }
-}
-
-/* C M G E T C M D -- Find most recent matching command */
-
-char *
-cmgetcmd(s) char * s; {
- int i;
- for (i = current; i >= 0; i--) { /* Search backward thru history list */
- if (!recall[i]) continue; /* This one's null, skip it */
- if (ckmatch(s,recall[i],0,1)) /* Match? */
- return(recall[i]); /* Yes, return pointer */
- }
- return(NULL); /* No match, return NULL pointer */
-}
-#endif /* CK_RECALL */
-
-/* A D D C M D -- Add a command to the recall buffer */
-
-VOID
-addcmd(s) char * s; {
- int len = 0, nq = 0;
- char * p;
-#ifdef CKLEARN
- extern int learning;
-#endif /* CKLEARN */
-
- if (xcmdsrc) /* Only for interactive commands */
- return;
-
- if (!newcmd) /* The command has been here already */
- return; /* so ignore it. */
- newcmd = 0; /* It's new but do this only once. */
-
- if (!s) s = cmdbuf;
- if (s[0])
- len = strlen(s);
-
- if (len < 1) /* Don't save empty commands */
- return;
-
- p = s;
- while (*p) { if (*p++ == '?') nq++; } /* Count question marks */
-
-#ifdef CKLEARN
- if (learning) /* If a learned script is active */
- learncmd(s); /* record this command. */
-#endif /* CKLEARN */
-
- debug(F010,"CMD(P)",s,0); /* Maybe record it in the debug log */
-
-#ifdef CKSYSLOG
- if (ckxlogging) { /* Maybe record it in syslog */
- if (ckxsyslog >= SYSLG_CX || ckxsyslog >= SYSLG_CM)
- cksyslog(SYSLG_CX, 1, "command", s, NULL);
- }
-#endif /* CKSYSLOG */
-
-#ifdef CK_RECALL
- last_recall = 0;
-
- if (on_recall && /* Command recall is on? */
- cm_recall > 0 && /* Recall buffer size is > 0? */
- !no_recall) { /* Not not saving this command? */
-
- if (!force_add && rlast > -1) /* If previous command was identical */
- if (!strcmp(s,recall[rlast])) /* don't add another copy */
- return;
-
- force_add = 0; /* Reset now in case it was set */
-
- if (rlast >= cm_recall - 1) { /* Recall buffer full? */
- int i;
- if (recall[0]) { /* Discard oldest command */
- free(recall[0]);
- recall[0] = NULL;
- }
- for (i = 0; i < rlast; i++) { /* The rest */
- recall[i] = recall[i+1]; /* move back */
- }
- rlast--; /* Now we have one less */
- }
- rlast++; /* Index of last command in buffer */
- current = rlast; /* Also now the current command */
- if (current >= cm_recall) { /* Shouldn't happen */
- printf("?Command history error\n"); /* but if it does */
- on_recall = 0; /* turn off command saving */
-#ifdef COMMENT
- } else if (nq > 0) { /* Have at least one question mark */
- recall[current] = malloc(len+nq+1);
- if (recall[current]) {
- p = recall[current];
- while (*s) {
- if (*s == '?')
- *p++ = '\\';
- *p++ = *s++;
- }
- *p = NUL;
- }
-#endif /* COMMENT */
- } else { /* Normal case, just copy */
- recall[current] = malloc(len+1);
- if (recall[current])
- ckstrncpy(recall[current],s,len+1);
- }
- }
-#endif /* CK_RECALL */
-}
-
-
-#ifdef CK_RECALL
-
-/* C M H I S T O R Y */
-
-VOID
-cmhistory() {
- int i, lc = 1;
- for (i = 0; i <= current; i++) {
- printf(" %s\n", recall[i]);
- if (++lc > (cmd_rows - 2)) { /* Screen full? */
- if (!askmore()) /* Do more-prompting... */
- break;
- else
- lc = 0;
- }
- }
-}
-
-int
-savhistory(s,disp) char *s; int disp; {
- FILE * fp;
- int i;
-
- fp = fopen(s, disp ? "a" : "w");
- if (!fp) {
- perror(s);
- return(0);
- }
- for (i = 0; i <= current; i++)
- fprintf(fp,"%s\n", recall[i]);
- fclose(fp);
- return(1);
-}
-#endif /* CK_RECALL */
-
-#ifdef COMMENT
-/* apparently not used */
-int
-cmgetlc(s) char * s; { /* Get leading char */
- char c;
- while ((c = *s++) <= SP) {
- if (!c)
- break;
- }
- return(c);
-}
-#endif /* COMMENT */
-
-
-/* C M C F M -- Parse command confirmation (end of line) */
-
-/*
- Returns
- -2: User typed anything but whitespace or newline
- -1: Reparse needed
- 0: Confirmation was received
-*/
-int
-cmcfm() {
- int x, xc;
- debug(F101,"cmcfm: cmflgs","",cmflgs);
- debug(F110,"cmcfm: atmbuf",atmbuf,0);
- inword = xc = cc = 0;
-
- setatm("",0); /* (Probably unnecessary) */
-
- while (cmflgs != 1) {
- x = gtword(0);
- xc += cc;
-
- switch (x) {
- case -9:
- printf("Command or field too long\n");
- case -4: /* EOF */
- case -2:
- case -1:
- return(x);
- case 1: /* End of line */
- if (xc > 0) {
- if (xcmfdb) {
- return(-6);
- } else {
- printf("?Not confirmed - %s\n",atmbuf);
- return(-9);
- }
- } else
- break; /* Finish up below */
- case 2: /* ESC */
- if (xc == 0) {
- bleep(BP_WARN);
- continue; /* or fall thru. */
- }
- case 0: /* Space */
- if (xc == 0) /* If no chars typed, continue, */
- continue; /* else fall thru. */
- /* else fall thru... */
-
- case 3: /* Question mark */
- if (xc > 0) {
- if (xcmfdb) {
- return(-6);
- } else {
- printf("?Not confirmed - %s\n",atmbuf);
- return(-9);
- }
- }
- printf(
- "\n Press the Return or Enter key to confirm the command\n");
- printf("%s%s",cmprom,cmdbuf);
- fflush(stdout);
- continue;
- }
- }
- debok = 1;
- return(0);
-}
-
-
-/* The following material supports chained parsing functions. */
-/* See ckucmd.h for FDB and OFDB definitions. */
-
-struct OFDB cmresult = { /* Universal cmfdb result holder */
- NULL, /* Address of succeeding FDB struct */
- 0, /* Function code */
- NULL, /* String result */
- 0, /* Integer result */
- (CK_OFF_T)0 /* Wide result */
-};
-
-VOID
-cmfdbi(p,fc,s1,s2,s3,n1,n2,f,k,nxt) /* Initialize an FDB */
- struct FDB * p;
- int fc;
- char * s1, * s2, * s3;
- int n1, n2;
- xx_strp f;
- struct keytab * k;
- struct FDB * nxt; {
-
- p->fcode = fc;
- p->hlpmsg = s1;
- p->dflt = s2;
- p->sdata = s3;
- p->ndata1 = n1;
- p->ndata2 = n2;
- p->spf = f;
- p->kwdtbl = k;
- p->nxtfdb = nxt;
-}
-
-/* C M F D B -- Parse a field with several possible functions */
-
-int
-cmfdb(fdbin) struct FDB * fdbin; {
-#ifndef NOSPL
- extern int x_ifnum; /* IF NUMERIC - disables warnings */
-#endif /* NOSPL */
- struct FDB * in = fdbin;
- struct OFDB * out = &cmresult;
- int x = 0, n, r;
- CK_OFF_T w = (CK_OFF_T)0;
- char *s, *xp, *m = NULL;
- int errbits = 0;
-
- xp = bp;
-
- out->fcode = -1; /* Initialize output struct */
- out->fdbaddr = NULL;
- out->sresult = NULL;
- out->nresult = 0;
-/*
- Currently we make one trip through the FDBs. So if the user types Esc or
- Tab at the beginning of a field, only the first FDB is examined for a
- default. If the user types ?, help is given only for one FDB. We should
- search through the FDBs for all matching possibilities -- and in particular
- display the pertinent context-sensitive help for each function, rather than
- the only the first one that works, and then rewind the FDB pointer so we
- are not locked out of the earlier ones.
-*/
- cmfldflgs = 0;
- while (1) { /* Loop through the chain of FDBs */
- nomsg = 1;
- xcmfdb = 1;
- s = NULL;
- n = 0;
- debug(F101,"cmfdb in->fcode","",in->fcode);
- switch (in->fcode) { /* Current parsing function code */
- case _CMNUM:
- r = in->ndata1;
- if (r != 10 && r != 8) r = 10;
-#ifndef NOSPL
- x_ifnum = 1; /* Disables warning messages */
-#endif /* NOSPL */
- x = cmnum(in->hlpmsg,in->dflt,r,&n,in->spf);
-#ifndef NOSPL
- x_ifnum = 0;
-#endif /* NOSPL */
- debug(F101,"cmfdb cmnum","",x);
- if (x < 0) errbits |= 1;
- break;
- case _CMNUW: /* Wide cmnum - 24 Dec 2005 */
- r = in->ndata1;
- if (r != 10 && r != 8) r = 10;
-#ifndef NOSPL
- x_ifnum = 1; /* Disables warning messages */
-#endif /* NOSPL */
- x = cmnumw(in->hlpmsg,in->dflt,r,&w,in->spf);
-#ifndef NOSPL
- x_ifnum = 0;
-#endif /* NOSPL */
- debug(F101,"cmfdb cmnumw","",w);
- if (x < 0) errbits |= 1;
- break;
- case _CMOFI:
- x = cmofi(in->hlpmsg,in->dflt,&s,in->spf);
- debug(F101,"cmfdb cmofi","",x);
- if (x < 0) errbits |= 2;
- break;
- case _CMIFI:
- x = cmifi2(in->hlpmsg,
- in->dflt,
- &s,
- &n,
- in->ndata1,
- in->sdata,
- in->spf,
- in->ndata2
- );
- debug(F101,"cmfdb cmifi2 x","",x);
- debug(F101,"cmfdb cmifi2 n","",n);
- if (x < 0) errbits |= 4;
- break;
- case _CMFLD:
- cmfldflgs = in->ndata1;
- x = cmfld(in->hlpmsg,in->dflt,&s,in->spf);
- debug(F101,"cmfdb cmfld","",x);
- if (x < 0) errbits |= 8;
- break;
- case _CMTXT:
- x = cmtxt(in->hlpmsg,in->dflt,&s,in->spf);
- debug(F101,"cmfdb cmtxt","",x);
- if (x < 0) errbits |= 16;
- break;
- case _CMKEY:
- x = cmkey2(in->kwdtbl,
- in->ndata1,
- in->hlpmsg,in->dflt,in->sdata,in->spf,in->ndata2);
- debug(F101,"cmfdb cmkey","",x);
- if (x < 0) errbits |= ((in->ndata2 & 4) ? 32 : 64);
- break;
- case _CMCFM:
- x = cmcfm();
- debug(F101,"cmfdb cmcfm","",x);
- if (x < 0) errbits |= 128;
- break;
- default:
- debug(F101,"cmfdb - unexpected function code","",in->fcode);
- printf("?cmfdb - unexpected function code: %d\n",in->fcode);
- }
- debug(F101,"cmfdb x","",x);
- debug(F101,"cmfdb cmflgs","",cmflgs);
- debug(F101,"cmfdb crflag","",crflag);
- debug(F101,"cmfdb qmflag","",qmflag);
- debug(F101,"cmfdb esflag","",esflag);
-
- if (x > -1) { /* Success */
- out->fcode = in->fcode; /* Fill in output struct */
- out->fdbaddr = in;
- out->sresult = s;
- out->nresult = (in->fcode == _CMKEY) ? x : n;
- out->wresult = w;
- out->kflags = (in->fcode == _CMKEY) ? cmkwflgs : 0;
- debug(F111,"cmfdb out->nresult",out->sresult,out->nresult);
- debug(F111,"cmfdb out->wresult",out->sresult,out->wresult);
- nomsg = 0;
- xcmfdb = 0;
- /* debug(F111,"cmfdb cmdbuf & crflag",cmdbuf,crflag); */
- if (crflag) {
- cmflgs = 1;
- }
- return(x); /* and return */
- }
- in = in->nxtfdb; /* Failed, get next parsing function */
- nomsg = 0;
- xcmfdb = 0;
- if (!in) { /* No more */
- debug(F101,"cmfdb failure x","",x);
- debug(F101,"cmfdb failure errbits","",errbits);
- if (x == -6)
- x = -9;
- if (x == -9) {
-#ifdef CKROOT
- if (ckrooterr)
- m = "Off Limits";
- else
-#endif /* CKROOT */
- /* Make informative messages for a few common cases */
- switch (errbits) {
- case 4+32: m = "Does not match filename or switch"; break;
- case 4+64: m = "Does not match filename or keyword"; break;
- case 1+32: m = "Not a number or valid keyword"; break;
- case 1+64: m = "Not a number or valid switch"; break;
- default: m = "Not valid in this position";
- }
- printf("?%s: \"%s\"\n",m, atmbuf);
- }
- return(x);
- }
- if (x != -2 && x != -6 && x != -9 && x != -3) /* Editing or somesuch */
- return(x); /* Go back and reparse */
- pp = np = bp = xp; /* Back up pointers */
- cmflgs = -1; /* Force a reparse */
-
-#ifndef NOSPL
- if (!askflag) { /* If not executing ASK-class cmd... */
-#endif /* NOSPL */
- if (crflag) { /* If CR was typed, put it back */
- pushc = LF; /* But as a linefeed */
- } else if (qmflag) { /* Ditto for Question mark */
- pushc = '?';
- } else if (esflag) { /* and Escape or Tab */
- pushc = ESC;
- }
-#ifndef NOSPL
- }
-#endif /* NOSPL */
- }
-}
-
-/*
- C M I O F I -- Parse an input file OR the name of a nonexistent file.
-
- Replaces the commented-out version above. This one actually works and
- has the expected straightforward interface.
-*/
-int
-cmiofi(xhlp,xdef,xp,wild,f) char *xhlp, *xdef, **xp; int *wild; xx_strp f; {
- int x;
- struct FDB f1, f2;
- cmfdbi(&f1,_CMIFI,xhlp,xdef,"",0,0,f,NULL,&f2);
- cmfdbi(&f2,_CMOFI,"","","",0,0,f,NULL,NULL);
- x = cmfdb(&f1);
- if (x < 0) {
- if (x == -3) {
- x = -9;
- printf("?Filename required\n");
- }
- }
- *wild = cmresult.nresult;
- *xp = cmresult.sresult;
- return(x);
-}
-
-/* G T W O R D -- Gets a "word" from the command input stream */
-
-/*
-Usage: retcode = gtword(brk);
- brk = 0 for normal word breaks (space, CR, Esc, ?)
- brk = 1 to add ':' and '=' (for parsing switches). These characters
- act as break characters only if the first character of the field
- is slash ('/'), i.e. switch introducer.
- brk = 4 to not strip comments (used only for "help #" and "help ;").
-
-Returns:
--10 Timelimit set and timed out
- -9 if input was too long
- -4 if end of file (e.g. pipe broken)
- -3 if null field
- -2 if command buffer overflows
- -1 if user did some deleting
- 0 if word terminates with SP or tab
- 1 if ... CR
- 2 if ... ESC
- 3 if ... ? (question mark)
- 4 if ... : or = and called with brk != 0
-
-With:
- pp pointing to beginning of word in buffer
- bp pointing to after current position
- atmbuf containing a copy of the word
- cc containing the number of characters in the word copied to atmbuf
-*/
-
-int
-ungword() { /* Unget a word */
- debug(F101,"ungword cmflgs","",cmflgs);
- if (ungw) return(0);
- cmfsav = cmflgs;
- ungw = 1;
- cmflgs = 0;
- return(0);
-}
-
-/* Un-un-get word. Undo ungword() if it has been done. */
-
-VOID
-unungw() {
- debug(F010,"unungw atmbuf",atmbuf,0);
- if (ungw) {
- ungw = 0;
- cmflgs = cmfsav;
- atmbuf[0] = NUL;
- }
-}
-
-static int
-gtword(brk) int brk; {
- int c; /* Current char */
- int quote = 0; /* Flag for quote character */
- int echof = 0; /* Flag for whether to echo */
- int comment = 0; /* Flag for in comment */
- char *cp = NULL; /* Comment pointer */
- int eintr = 0; /* Flag for syscall interrupted */
- int bracelvl = 0; /* nested brace counter [jrs] */
- int iscontd = 0; /* Flag for continuation */
- int realtty = 0; /* Stdin is really a tty */
- char firstnb = NUL;
- char lastchar = NUL;
- char prevchar = NUL;
- char lbrace, rbrace;
- int dq = 0; /* Doublequote flag */
- int dqn = 0; /* and count */
- int isesc = 0;
-
-#ifdef RTU
- extern int rtu_bug;
-#endif /* RTU */
-
-#ifdef IKSD
- extern int inserver;
-#endif /* IKSD */
- extern int kstartactive;
-
-#ifdef datageneral
- extern int termtype; /* DG terminal type flag */
- extern int con_reads_mt; /* Console read asynch is active */
- if (con_reads_mt) connoi_mt(); /* Task would interfere w/cons read */
-#endif /* datageneral */
-
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"gtword brk","",brk);
- debug(F101,"gtword cmfldflgs","",cmfldflgs);
- debug(F101,"gtword swarg","",swarg);
- debug(F101,"gtword dpx","",dpx);
- debug(F101,"gtword echof","",echof);
-#ifndef NOSPL
- debug(F101,"gtword askflag","",askflag);
- debug(F101,"gtword timelimit","",timelimit);
-#ifndef NOLOCAL
-#ifndef NOXFER
-#ifdef CK_AUTODL
- debug(F101,"gtword cmdadl","",cmdadl);
-#endif /* CK_AUTODL */
-#endif /* NOXFER */
-#endif /* NOLOCAL */
-#endif /* NOSPL */
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
-
- realtty = is_a_tty(0); /* Stdin is really a tty? */
-
- if (cmfldflgs & 1) {
- lbrace = '(';
- rbrace = ')';
- } else {
- lbrace = '{';
- rbrace = '}';
- }
- crflag = 0;
- qmflag = 0;
- esflag = 0;
-
- if (swarg) { /* No leading space for switch args */
- inword = 1;
- swarg = 0;
- }
- if (ungw) { /* Have a word saved? */
-#ifdef M_UNGW
- /* Experimental code to allow ungetting multiple words. */
- /* See comments in ckmkey2() above. */
- int x;
- if (np > pp) pp = np;
- while (*pp == SP) pp++;
- if (!*pp) {
- ungw = 0;
- cmflgs = cmfsav;
- } else {
- if ((x = setatm(pp,2)) < 0) {
- printf("?Saved word too long\n");
- return(-9);
- }
- if (pp[x] >= SP) {
- char *p2;
- p2 = pp;
- p2 += x;
- while (*p2 == SP) p2++;
- if (*p2) {
- np = p2;
- ungword();
- }
- } else {
- ungw = 0;
- cmflgs = cmfsav;
- debug(F010,"gtword ungw return atmbuf",atmbuf,0);
- }
- }
- return(cmflgs);
-#else
- /*
- You would think the following should be:
- while (*pp == SP) pp++;
- but you would be wrong -- making this change breaks GOTO.
- */
- while (*pp++ == SP) ;
- if (setatm(pp,2) < 0) {
- printf("?Saved word too long\n");
- return(-9);
- }
- ungw = 0;
- cmflgs = cmfsav;
- debug(F010,"gtword ungw return atmbuf",atmbuf,0);
- return(cmflgs);
-#endif /* M_UNGW */
- }
- pp = np; /* Start of current field */
-
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"gtword cmdbuf",cmdbuf,0);
- debug(F110,"gtword bp",bp,0);
- debug(F110,"gtword pp",pp,0);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- {
- /* If we are reparsing we have to recount any braces or doublequotes */
- char * p = pp;
- char c;
- if (*p == '"')
- dq++;
- while ((c = *p++))
- if (c == lbrace)
- bracelvl++;
- else if (c == rbrace)
- bracelvl--;
- else if (dq && c == '"')
- dqn++;
- }
- while (bp < cmdbuf+CMDBL) { /* Big get-a-character loop */
- echof = 0; /* Assume we don't echo because */
- chsrc = 0; /* character came from reparse buf. */
-#ifdef BS_DIRSEP
-CMDIRPARSE:
-#endif /* BS_DIRSEP */
-
- c = *bp;
- if (!c) { /* If no char waiting in reparse buf */
- if ((dpx
-#ifndef NOSPL
- || echostars
-#endif /* NOSPL */
- ) && (!pushc
-#ifndef NOSPL
- || askflag
-#endif /* NOSPL */
- )) /* Get from tty, set echo flag */
- echof = 1;
- c = cmdgetc(timelimit); /* Read a command character. */
-#ifdef DEBUG
- debug(F101,"gtword c","",c);
-#endif /* DEBUG */
-
- if (timelimit && c < -1) { /* Timed out */
- return(-10);
- }
-
-#ifndef NOXFER
-/*
- The following allows packet recognition in the command parser.
- Presently it works only for Kermit packets, and if our current protocol
- happens to be anything besides Kermit, we simply force it to Kermit.
- We don't use the APC mechanism here for mechanical reasons, and also
- because this way, it works even with minimally configured interactive
- versions. Add Zmodem later...
-*/
-#ifdef CK_AUTODL
- if ((!local && cmdadl) /* Autodownload enabled? */
-#ifdef IKS_OPTION
- || TELOPT_SB(TELOPT_KERMIT).kermit.me_start
-#endif /* IKS_OPTION */
- ) {
- int k;
- k = kstart((CHAR)c); /* Kermit S or I packet? */
- if (k) {
- int ksign = 0;
- if (k < 0) { /* Minus-Protocol? */
-#ifdef NOSERVER
- goto noserver; /* Need server mode for this */
-#else
- ksign = 1; /* Remember */
- k = 0 - k; /* Convert to actual protocol */
- justone = 1; /* Flag for protocol module */
-#endif /* NOSERVER */
- } else
- justone = 0;
- k--; /* Adjust kstart's return value */
- if (k == PROTO_K) {
- extern int protocol, g_proto;
- extern CHAR sstate;
- g_proto = protocol;
- protocol = PROTO_K; /* Crude... */
- sstate = ksign ? 'x' : 'v';
- cmdbuf[0] = NUL;
- return(-3);
- }
- }
- }
-#ifdef NOSERVER
- noserver:
-#endif /* NOSERVER */
-#endif /* CK_AUTODL */
-#endif /* NOXFER */
-
- chsrc = 1; /* Remember character source is tty. */
- brkchar = c;
-
-#ifdef IKSD
- if (inserver && c < 0) { /* End of session? */
- debug(F111,"gtword c < 0","exiting",c);
- return(-4); /* Cleanup and terminate */
- }
-#endif /* IKSD */
-
-#ifdef OS2
- if (c < 0) { /* Error */
- if (c == -3) { /* Empty word? */
- if (blocklvl > 0) /* In a block */
- continue; /* so keep looking for block end */
- else
- return(-3); /* Otherwise say we got nothing */
- } else { /* Not empty word */
- return(-4); /* So some kind of i/o error */
- }
- }
-#else
-#ifdef MAC
- if (c == -3) /* Empty word... */
- if (blocklvl > 0)
- continue;
- else
- return(-3);
-#endif /* MAC */
-#endif /* OS2 */
- if (c == EOF) { /* This can happen if stdin not tty. */
-#ifdef EINTR
-/*
- Some operating and/or C runtime systems return EINTR for no good reason,
- when the end of the standard input "file" is encountered. In cases like
- this, we get into an infinite loop; hence the eintr counter, which is reset
- to 0 upon each call to this routine.
-*/
- debug(F101,"gtword EOF","",errno);
- if (errno == EINTR && ++eintr < 4) /* When bg'd process is */
- continue; /* fg'd again. */
-#endif /* EINTR */
- return(-4);
- }
- c &= cmdmsk; /* Strip any parity bit */
- } /* if desired. */
-
-/* Now we have the next character */
-
- isesc = (c == ESC); /* A real ESC? */
-
- if (!firstnb && c > SP) { /* First nonblank */
- firstnb = c;
- if (c == '"') /* Starts with doublequote */
- dq = 1;
- }
- if (c == '"') /* Count doublequotes */
- dqn++;
-
- if (quote && (c == CR || c == LF)) { /* Enter key following quote */
- *bp++ = CMDQ; /* Double it */
- *bp = NUL;
- quote = 0;
- }
- if (quote == 0) { /* If this is not a quoted character */
- switch (c) {
- case CMDQ: /* Got the quote character itself */
- if (!comment && quoting)
- quote = 1; /* Flag it if not in a comment */
- break;
- case FF: /* Formfeed. */
- c = NL; /* Replace with newline */
- cmdclrscn(); /* Clear the screen */
- break;
- case HT: /* Horizontal Tab */
- if (comment) /* If in comment, */
- c = SP; /* substitute space */
- else /* otherwise */
- c = ESC; /* substitute ESC (for completion) */
- break;
- case ';': /* Trailing comment */
- case '#':
- if (! (brk & 4) ) { /* If not keeping comments */
- if (inword == 0 && quoting) { /* If not in a word */
- comment = 1; /* start a comment. */
- cp = bp; /* remember where it starts. */
- }
- }
- break;
- }
- if (!kstartactive && /* Not in possible Kermit packet */
- !comment && c == SP) { /* Space not in comment */
- *bp++ = (char) c; /* deposit in buffer if not already */
- /* debug(F101,"gtword echof 2","",echof); */
-#ifdef BEBOX
- if (echof) {
- cmdecho((char) c, 0); /* Echo what was typed. */
- fflush(stdout);
- fflush(stderr);
- }
-#else
- if (echof) {
- cmdecho((char) c, 0); /* Echo what was typed. */
- if (timelimit)
- fflush(stdout);
- }
-#endif /* BEBOX */
- if (inword == 0) { /* If leading, gobble it. */
- pp++;
- continue;
- } else { /* If terminating, return. */
- if ((!dq && ((*pp != lbrace) || (bracelvl == 0))) ||
- (dq && dqn > 1 && *(bp-2) == '"')) {
- np = bp;
- cmbptr = np;
- if (setatm(pp,0) < 0) {
- printf("?Field too long error 1\n");
- debug(F111,"gtword too long #1",pp,strlen(pp));
- return(-9);
- }
- brkchar = c;
- inword = cmflgs = 0;
- return(0);
- }
- continue;
- }
- }
- if (c == lbrace) {
- bracelvl++;
- /* debug(F101,"gtword bracelvl++","",bracelvl); */
- }
- if (c == rbrace && bracelvl > 0) {
- bracelvl--;
- /* debug(F101,"gtword bracelvl--","",bracelvl); */
- if (linebegin)
- blocklvl--;
- }
- if ((c == '=' || c == ':') &&
- /* ^^^ */
- !kstartactive && !comment && brk /* && (firstnb == '/') */
- ) {
- *bp++ = (char) c; /* Switch argument separator */
- /* debug(F111,"gtword switch argsep",cmdbuf,brk); */
-#ifdef BEBOX
- if (echof) {
- cmdecho((char) c, 0); /* Echo what was typed. */
- fflush(stdout);
- fflush(stderr);
- }
-#else
- if (echof) {
- cmdecho((char) c, 0); /* Echo what was typed. */
- if (timelimit)
- fflush(stdout);
- }
-#endif /* BEBOX */
- if ((*pp != lbrace) || (bracelvl == 0)) {
- np = bp;
- cmbptr = np;
- if (setatm(pp,2) < 0) { /* ^^^ */
- printf("?Field too long error 1\n");
- debug(F111,"gtword too long #1",pp,strlen(pp));
- return(-9);
- }
- inword = cmflgs = 0;
- brkchar = c;
- return(4);
- }
- }
- if (c == LF || c == CR) { /* CR or LF. */
- if (echof) {
- cmdnewl((char)c); /* echo it. */
-#ifdef BEBOX
- fflush(stdout);
- fflush(stderr);
-#endif /* BEBOX */
- }
- {
- /* Trim trailing comment and whitespace */
- char *qq;
- if (comment) { /* Erase comment */
- while (bp >= cp) /* Back to comment pointer */
- *bp-- = NUL;
- bp++;
- pp = bp; /* Adjust other pointers */
- inword = 0; /* and flags */
- comment = 0;
- cp = NULL;
- }
- qq = inword ? pp : (char *)cmdbuf;
- /* Erase trailing whitespace */
- while (bp > qq && (*(bp-1) == SP || *(bp-1) == HT)) {
- bp--;
- /* debug(F000,"erasing","",*bp); */
- *bp = NUL;
- }
- lastchar = (bp > qq) ? *(bp-1) : NUL;
- prevchar = (bp > qq+1) ? *(bp-2) : NUL;
- }
- if (linebegin && blocklvl > 0) /* Blank line in {...} block */
- continue;
-
- linebegin = 1; /* At beginning of next line */
- iscontd = prevchar != CMDQ &&
- (lastchar == '-' || lastchar == lbrace);
- debug(F101,"gtword iscontd","",iscontd);
-
- if (iscontd) { /* If line is continued... */
- if (chsrc) { /* If reading from tty, */
- if (*(bp-1) == lbrace) { /* Check for "begin block" */
- *bp++ = SP; /* Insert a space for neatness */
- blocklvl++; /* Count block nesting level */
- } else { /* Or hyphen */
- bp--; /* Overwrite the hyphen */
- }
- *bp = NUL; /* erase the dash, */
- continue; /* and go back for next char now. */
- }
- } else if (blocklvl > 0) { /* No continuation character */
- if (chsrc) { /* But we're in a "block" */
- *bp++ = ','; /* Add comma */
- *bp = NUL;
- continue;
- }
- } else { /* No continuation, end of command. */
- *bp = NUL; /* Terminate the command string. */
- if (comment) { /* If we're in a comment, */
- comment = 0; /* Say we're not any more, */
- *cp = NUL; /* cut it off. */
- }
- np = bp; /* Where to start next field. */
- cmbptr = np;
- if (setatm(pp,0) < 0) { /* Copy field to atom buffer */
- debug(F111,"gtword too long #2",pp,strlen(pp));
- printf("?Field too long error 2\n");
- return(-9);
- }
- inword = 0; /* Not in a word any more. */
- crflag = 1;
- /* debug(F110,"gtword","crflag is set",0); */
-#ifdef CK_RECALL
- current = rlast;
-#endif /* CK_RECALL */
- cmflgs = 1;
- if (!xcmdsrc
-#ifdef CK_RECALL
- || force_add
-#endif /* CK_RECALL */
- )
- addcmd(cmdbuf);
- return(cmflgs);
- }
- }
-/*
- This section handles interactive help, completion, editing, and history.
- Rearranged as a switch statement executed only if we're at top level since
- there is no need for any of this within command files and macros: Aug 2000.
- Jun 2001: Even if at top level, skip this if the character was fetched from
- the reparse or recall buffer, or if stdin is redirected.
-*/
- if ((xcmdsrc == 0 /* Only at top level */
-#ifndef NOSPL
- || askflag /* or user is typing ASK response */
-#endif /* NOSPL */
- ) && chsrc != 0 && realtty) { /* from the real keyboard */
-
-/* Use ANSI / VT100 up and down arrow keys for command recall. */
-
- if (isesc && (
-#ifdef IKSD
- inserver
-#else
- 0
-#endif /* IKSD */
-#ifdef USE_ARROWKEYS
- || 1
-#endif /* USE_ARROWKEYS */
- )
- ) { /* A real ESC was typed */
- int x;
- msleep(200); /* Wait 1/5 sec */
- x = cmdconchk(); /* Was it followed by anything? */
- debug(F101,"Arrowkey ESC cmdconchk","",x);
-
- if (x > 1) { /* If followed by at least 2 chars */
- int c2;
- c2 = cmdgetc(0); /* Get the first one */
- debug(F101,"Arrowkey ESC c2","",c2);
-
- if (c2 != '[' && c2 != 'O') { /* If not [ or O */
- pushc = c2; /* Push it and take the ESC solo */
- } else {
- c2 = cmdgetc(0); /* Get the second one */
- debug(F101,"Arrowkey ESC c3","",c2);
- switch (c2) {
-#ifndef NORECALL
- case 'A': /* Up */
- c = BEL;
- c = C_UP;
- break;
- case 'B': /* Down */
- c = BEL;
- c = C_DN;
- break;
- case 'C': /* Right */
- case 'D': /* Left */
-#else
- default:
-#endif /* NORECALL */
- c = BEL; /* We don't use these yet */
- break;
- }
- }
- }
- }
-
- switch (c) {
- case '?': /* ?-Help */
-#ifndef NOSPL
- if (askflag) /* No help in ASK response */
- break;
-#endif /* NOSPL */
- if (quoting
- && !kstartactive
- && !comment
- ) {
- cmdecho((char) c, 0);
- *bp = NUL;
- if (setatm(pp,0) < 0) {
- debug(F111,"gtword too long ?",pp,strlen(pp));
- printf("?Too long\n");
- return(-9);
- }
- qmflag = 1;
- return(cmflgs = 3);
- }
-
- case ESC: /* Esc or Tab completion */
- if (!comment) {
- *bp = NUL;
- if (setatm(pp,0) < 0) {
- debug(F111,"gtword too long Esc",pp,strlen(pp));
- printf("?Too long\n");
- return(-9);
- }
- esflag = 1;
- return(cmflgs = 2);
- } else {
- bleep(BP_WARN);
- continue;
- }
-
- case BS: /* Character deletion */
- case RUB:
- if (bp > cmdbuf) { /* If still in buffer... */
- cmdchardel(); /* erase it. */
- bp--; /* point behind it, */
- if (*bp == lbrace) bracelvl--; /* Adjust brace count */
- if (*bp == rbrace) bracelvl++;
- if ((*bp == SP) && /* Flag if current field gone */
- (*pp != lbrace || bracelvl == 0))
- inword = 0;
- *bp = NUL; /* Erase character from buffer. */
- } else { /* Otherwise, */
- bleep(BP_WARN);
- cmres(); /* and start parsing a new command. */
- *bp = *atmbuf = NUL;
- }
- if (pp < bp)
- continue;
- else
- return(cmflgs = -1);
-
- case LDEL: /* ^U, line deletion */
- while ((bp--) > cmdbuf) {
- cmdchardel();
- *bp = NUL;
- }
- cmres(); /* Restart the command. */
- *bp = *atmbuf = NUL;
- inword = 0;
- return(cmflgs = -1);
-
- case WDEL: /* ^W, word deletion */
- if (bp <= cmdbuf) { /* Beep if nothing to delete */
- bleep(BP_WARN);
- cmres();
- *bp = *atmbuf = NUL;
- return(cmflgs = -1);
- }
- bp--;
- /* Back up over any trailing nonalphanums */
- /* This is dependent on ASCII collating sequence */
- /* but isalphanum() is not available everywhere. */
- for ( ;
- (bp >= cmdbuf) &&
- ((*bp < '0') ||
- ((*bp > '9') && (*bp < '@')) ||
- ((*bp > 'Z') && (*bp < 'a')) ||
- (*bp > 'z'));
- bp--
- ) {
- cmdchardel();
- *bp = NUL;
- }
- /* Now delete back to rightmost remaining nonalphanum */
- for ( ; (bp >= cmdbuf) && (*bp) ; bp--) {
- if ((*bp < '0') ||
- (*bp > '9' && *bp < '@') ||
- (*bp > 'Z' && *bp < 'a') ||
- (*bp > 'z'))
- break;
- cmdchardel();
- *bp = NUL;
- }
- bp++;
- inword = 0;
- return(cmflgs = -1);
-
- case RDIS: { /* ^R, redisplay */
- char *cpx; char cx;
- *bp = NUL;
- printf("\n%s",cmprom);
- cpx = cmdbuf;
- while ((cx = *cpx++)) {
- cmdecho(cx,0);
- }
- fflush(stdout);
- continue;
- }
-#ifndef NOLASTFILE
- case VT:
- if (lastfile) {
- printf("%s ",lastfile);
-#ifdef GEMDOS
- fflush(stdout);
-#endif /* GEMDOS */
- inword = cmflgs = 0;
- addbuf(lastfile); /* Supply default. */
- if (setatm(lastfile,0) < 0) {
- printf("Last name too long\n");
- if (np) free(np);
- return(-9);
- }
- } else { /* No default */
- bleep(BP_WARN);
- }
- return(0);
-#endif /* NOLASTFILE */
- }
-
-#ifdef CK_RECALL
- if (on_recall && /* Reading commands from keyboard? */
- (cm_recall > 0) && /* Saving commands? */
- (c == C_UP || c == C_UP2)) { /* Go up one */
- if (last_recall == 2 && current > 0)
- current--;
- if (current < 0) { /* Nowhere to go, */
- bleep(BP_WARN);
- continue;
- }
- if (recall[current]) { /* We have a previous command */
- while ((bp--) > cmdbuf) { /* Erase current line */
- cmdchardel();
- *bp = NUL;
- }
- ckstrncpy(cmdbuf,recall[current],CMDBL);
-#ifdef OSK
- fflush(stdout);
- write(fileno(stdout), "\r", 1);
- printf("%s%s",cmprom,cmdbuf);
-#else
- printf("\r%s%s",cmprom,cmdbuf);
-#endif /* OSK */
- current--;
- }
- last_recall = 1;
- return(cmflgs = -1); /* Force a reparse */
- }
- if (on_recall && /* Reading commands from keyboard? */
- (cm_recall > 0) && /* Saving commands? */
- (c == C_DN)) { /* Down one */
- int x = 1;
- if (last_recall == 1)
- x++;
- if (current + x > rlast) { /* Already at bottom, beep */
- bleep(BP_WARN);
- continue;
- }
- current += x; /* OK to go down */
- if (recall[current]) {
- while ((bp--) > cmdbuf) { /* Erase current line */
- cmdchardel();
- *bp = NUL;
- }
- ckstrncpy(cmdbuf,recall[current],CMDBL);
-#ifdef OSK
- fflush(stdout);
- write(fileno(stdout), "\r", 1);
- printf("%s%s",cmprom,cmdbuf);
-#else
- printf("\r%s%s",cmprom,cmdbuf);
-#endif /* OSK */
- last_recall = 2;
- return(cmflgs = -1); /* Force reparse */
- }
- }
-#endif /* CK_RECALL */
- }
-
- if (c < SP && quote == 0) { /* Any other unquoted control char */
- if (!chsrc) { /* If cmd file, point past it */
- bp++;
- } else {
- bleep(BP_WARN);
- }
- continue; /* continue, don't put in buffer */
- }
- linebegin = 0; /* Not at beginning of line */
-#ifdef BEBOX
- if (echof) {
- cmdecho((char) c, 0); /* Echo what was typed. */
- fflush (stdout);
- fflush(stderr);
- }
-#else
-#ifdef NOSPL
- if (echof || chsrc)
-#else
- if (echof || (echostars && chsrc))
-#endif /* NOSPL */
- cmdecho((char) c, 0); /* Echo what was typed. */
-#endif /* BEBOX */
- } else { /* This character was quoted. */
- int qf = 1;
- quote = 0; /* Unset the quote flag. */
- /* debug(F000,"gtword quote 0","",c); */
- /* Quote character at this level is only for SP, ?, and controls */
- /* If anything else was quoted, leave quote in, and let */
- /* the command-specific parsing routines handle it, e.g. \007 */
- if (c > 32 && c != '?' && c != RUB && chsrc != 0) {
- /* debug(F000,"gtword quote 1","",c); */
- *bp++ = CMDQ; /* Deposit \ if it came from tty */
- qf = 0; /* and don't erase it from screen */
- linebegin = 0; /* Not at beginning of line */
-#ifdef BS_DIRSEP
-/*
- This is a hack to handle "cd \" or "cd foo\" on OS/2 and similar systems.
- If we were called from cmdir() and the previous character was the quote
- character, i.e. backslash, and this character is the command terminator,
- then we stuff an extra backslash into the buffer without echoing, then
- we stuff the carriage return back in again, and go back and process it,
- this time with the quote flag off.
-*/
- } else if (dirnamflg && (c == CR || c == LF || c == SP)) {
- /* debug(F000,"gtword quote 2","",c); */
- *bp++ = CMDQ;
- linebegin = 0; /* Not at beginning of line */
- *bp = (c == SP ? SP : CR);
- goto CMDIRPARSE;
-#endif /* BS_DIRSEP */
- }
-#ifdef BEBOX
- if (echof) {
- cmdecho((char) c, qf); /* Echo what was typed. */
- fflush (stdout);
- fflush(stderr);
- }
-#else
- if (echof) cmdecho((char) c, qf); /* Now echo quoted character */
-#endif /* BEBOX */
- /* debug(F111,"gtword quote",cmdbuf,c); */
- }
-#ifdef COMMENT
- if (echof) cmdecho((char) c,quote); /* Echo what was typed. */
-#endif /* COMMENT */
- if (!comment) inword = 1; /* Flag we're in a word. */
- if (quote) continue; /* Don't deposit quote character. */
- if (c != NL) { /* Deposit command character. */
- *bp++ = (char) c; /* and make sure there is a NUL */
-#ifdef COMMENT
- *bp = NUL; /* after it */
-#endif /* COMMENT */
- }
- } /* End of big while */
- bleep(BP_WARN);
- printf("?Command too long, maximum length: %d.\n",CMDBL);
- cmflgs = -2;
- return(-9);
-}
-
-/* Utility functions */
-
-/* A D D B U F -- Add the string pointed to by cp to the command buffer */
-
-static int
-addbuf(cp) char *cp; {
- int len = 0;
- while ((*cp != NUL) && (bp < cmdbuf+CMDBL)) {
- *bp++ = *cp++; /* Copy and */
- len++; /* count the characters. */
- }
- *bp++ = SP; /* Put a space at the end */
- *bp = NUL; /* Terminate with a null */
- np = bp; /* Update the next-field pointer */
- cmbptr = np;
- return(len); /* Return the length */
-}
-
-/* S E T A T M -- Deposit a token in the atom buffer. */
-/*
- Break on space, newline, carriage return, or NUL.
- Call with:
- cp = Pointer to string to copy to atom buffer.
- fcode = 0 means break on whitespace or EOL.
- fcode = 1 means don't break on space.
- fcode = 2 means break on space, ':', or '='.
- fcode = 3 means copy the whole string.
- Null-terminate the result.
- Return length of token, and also set global "cc" to this length.
- Return -1 if token was too long.
-*/
-static int
-setatm(cp,fcode) char *cp; int fcode; {
- char *ap, *xp, *dqp = NULL, lbrace, rbrace;
- int bracelvl = 0, dq = 0;
-
- register char * s;
- register int n = 0;
-
- if (cmfldflgs & 1) { /* Handle grouping */
- lbrace = '(';
- rbrace = ')';
- } else {
- lbrace = '{';
- rbrace = '}';
- }
- cc = 0; /* Character counter */
- ap = atmbuf; /* Address of atom buffer */
-
- s = cp;
-
- while (*s++) n++; /* Save a call to strlen */
-
- if (n > ATMBL) {
- printf("?Command buffer overflow\n");
- return(-1);
- }
- /* debug(F111,"setatm",cp,n); */
- if (cp == ap) { /* In case source is atom buffer */
- xp = atybuf; /* make a copy */
-#ifdef COMMENT
- strncpy(xp,ap,ATMBL); /* so we can copy it back, edited. */
- cp = xp;
-#else
- s = ap;
- while ((*xp++ = *s++)) ; /* We already know it's big enough */
- cp = xp = atybuf;
-#endif /* COMMENT */
- }
- *ap = NUL; /* Zero the atom buffer */
- if (fcode == 1) { /* Trim trailing blanks */
- while (--n >= 0 && cp[n] == SP)
- ;
- cp[n+1] = NUL;
- }
- while (*cp == SP) { /* Trim leading spaces */
- cp++;
- n--;
- }
- if (*cp == '"') { /* Starts with doublequote? */
- dq = 1;
- dqp = cp;
- }
- while (*cp) {
- if (*cp == lbrace)
- bracelvl++;
- else if (*cp == rbrace)
- bracelvl--;
- if (bracelvl < 0)
- bracelvl = 0;
- if (bracelvl == 0) {
- if (dq) {
- if (*cp == SP || *cp == HT) {
- if (cp > dqp+1) {
- if (*(cp-1) == '"' && *(cp-2) != CMDQ) {
- break;
- }
- }
- }
- } else if ((*cp == SP || *cp == HT) && fcode != 1 && fcode != 3)
- break;
- if ((fcode == 2) && (*cp == '=' || *cp == ':')) break;
- if ((fcode != 3) && (*cp == LF || *cp == CR)) break;
- }
- *ap++ = *cp++;
- cc++;
- }
- *ap = NUL; /* Terminate the string. */
- /* debug(F111,"setatm result",atmbuf,cc); */
- return(cc); /* Return length. */
-}
-
-/*
- These functions attempt to hide system dependencies from the mainline
- code in gtword(). Dummy arg for cmdgetc() needed for compatibility with
- coninc(), ttinc(), etc, since a pointer to this routine can be passed in
- place of those to tn_doop().
-
- No longer static. Used by askmore(). Fri Aug 20 15:03:34 1999.
-*/
-#define CMD_CONINC /* How we get keyboard chars */
-
-int
-cmdgetc(timelimit) int timelimit; { /* Get a character from the tty. */
- int c;
-#ifdef IKSD
- extern int inserver;
-#endif /* IKSD */
-#ifdef CK_LOGIN
- extern int x_logged;
-#endif /* CK_LOGIN */
-#ifdef TNCODE
- static int got_cr = 0;
- extern int ckxech;
- int tx = 0, is_tn = 0;
-#endif /* TNCODE */
-
- if (pushc
-#ifndef NOSPL
- && !askflag
-#endif /* NOSPL */
- ) {
- debug(F111,"cmdgetc()","pushc",pushc);
- c = pushc;
- pushc = NUL;
- if (xcmfdb && c == '?') /* Don't echo ? twice if chaining. */
- cmdchardel();
- return(c);
- }
-#ifdef datageneral
- {
- char ch;
- c = dgncinb(0,&ch,1); /* -1 is EOF, -2 TO,
- * -c is AOS/VS error */
- if (c == -2) { /* timeout was enabled? */
- resto(channel(0)); /* reset timeouts */
- c = dgncinb(0,&ch,1); /* retry this now! */
- }
- if (c < 0) return(-4); /* EOF or some error */
- else c = (int) ch & 0177; /* Get char without parity */
-/* echof = 1; */
- }
-#else /* Not datageneral */
-#ifndef MINIX2
- if (
-#ifdef IKSD
- (!local && inserver) ||
-#endif /* IKSD */
- timelimit > 0) {
-#ifdef TNCODE
- GETNEXTCH:
- is_tn = !pushc && !local && sstelnet;
-#endif /* TNCODE */
-#ifdef COMMENT
- c = coninc(timelimit > 0 ? 1 : 0);
-#else /* COMMENT */
- /* This is likely to break the asktimeout... */
- c = coninc(timelimit);
-#endif /* COMMENT */
- /* debug(F101,"cmdgetc coninc","",c); */
-#ifdef TNCODE
- if (c >= 0 && is_tn) { /* Server-side Telnet */
- switch (c) {
- case IAC:
- /* debug(F111,"gtword IAC","c",c); */
- got_cr = 0;
- if ((tx = tn_doop((CHAR)(c & 0xff),ckxech,coninc)) == 0) {
- goto GETNEXTCH;
- } else if (tx <= -1) { /* I/O error */
- /* If there was a fatal I/O error then ttclos() */
- /* has been called and the next GETNEXTCH attempt */
- /* will be !is_tn since ttclos() sets sstelnet = 0 */
- doexit(BAD_EXIT,-1); /* (or return(-4)? */
- } else if (tx == 1) { /* ECHO change */
- ckxech = dpx = 1; /* Get next char */
- goto GETNEXTCH;
- } else if (tx == 2) { /* ECHO change */
- ckxech = dpx = 0; /* Get next char */
- goto GETNEXTCH;
- } else if (tx == 3) { /* Quoted IAC */
- c = 255; /* proceeed with it. */
- }
-#ifdef IKS_OPTION
- else if (tx == 4) { /* IKS State Change */
- goto GETNEXTCH;
- }
-#endif /* IKS_OPTION */
- else if (tx == 6) { /* Remote Logout */
- doexit(GOOD_EXIT,0);
- } else {
- goto GETNEXTCH; /* Unknown, get next char */
- }
- break;
-#ifdef COMMENT
- case CR:
- if (!TELOPT_U(TELOPT_BINARY)) {
- if (got_cr) {
- /* This means the sender is violating Telnet */
- /* protocol because we received two CRs in a */
- /* row without getting either LF or NUL. */
- /* This will not solve the problem but it */
- /* will at least allow two CRs to do something */
- /* whereas before the user would have to guess */
- /* to send LF or NUL after the CR. */
- debug(F100,"gtword CR telnet error","",0);
- c = LF;
- } else {
- debug(F100,"gtword skipping CR","",0);
- got_cr = 1; /* Remember a CR was received */
- goto GETNEXTCH;
- }
- } else {
- debug(F100,"gtword CR to LF","",0);
- c = LF;
- }
- break;
- case LF:
- if (!TELOPT_U(TELOPT_BINARY)) {
- got_cr = 0;
- debug(F100,"gtword LF","",0);
- } else {
- if (got_cr) {
- got_cr = 0;
- debug(F100,"gtword skipping LF","",0);
- goto GETNEXTCH;
- }
- }
- break;
- case NUL:
- if (!TELOPT_U(TELOPT_BINARY) && got_cr) {
- c = LF;
- debug(F100,"gtword NUL to LF","",0);
- } else {
- debug(F100,"gtword NUL","",0);
- }
- got_cr = 0;
- break;
-#else /* COMMENT */
- case CR:
- if ( !TELOPT_U(TELOPT_BINARY) && got_cr ) {
- /* This means the sender is violating Telnet */
- /* protocol because we received two CRs in a */
- /* row without getting either LF or NUL. */
- /* This will not solve the problem but it */
- /* will at least allow two CRs to do something */
- /* whereas before the user would have to guess */
- /* to send LF or NUL after the CR. */
- debug(F100,"gtword CR telnet error","",0);
- } else {
- got_cr = 1; /* Remember a CR was received */
- }
- /* debug(F100,"gtword CR to LF","",0); */
- c = LF;
- break;
- case LF:
- if (got_cr) {
- got_cr = 0;
- /* debug(F100,"gtword skipping LF","",0); */
- goto GETNEXTCH;
- }
- break;
- case NUL:
- if (got_cr) {
- got_cr = 0;
- /* debug(F100,"gtword skipping NUL","",0); */
- goto GETNEXTCH;
-#ifdef COMMENT
- } else {
- debug(F100,"gtword NUL","",0);
-#endif /* COMMENT */
- }
- break;
-#endif /* COMMENT */
-#ifdef IKSD
- case ETX: /* Ctrl-C... */
- case EOT: /* EOT = EOF */
- if (inserver
-#ifdef CK_LOGIN
- && !x_logged
-#endif /* CK_LOGIN */
- )
- return(-4);
- break;
-#endif /* IKSD */
- default:
- got_cr = 0;
- }
- }
-#endif /* TNCODE */
- } else {
-#ifdef OS2
- c = coninc(0);
-#else /* OS2 */
-#ifdef CMD_CONINC
-#undef CMD_CONINC
-#endif /* CMD_CONINC */
- c = getchar();
-#endif /* OS2 */
- }
-#else /* MINIX2 */
-#undef getc
-#ifdef CMD_CONINC
-#undef CMD_CONINC
-#endif /* CMD_CONINC */
- c = getc(stdin);
- /* debug(F101,"cmdgetc getc","",c); */
-#endif /* MINIX2 */
-#ifdef RTU
- if (rtu_bug) {
-#ifdef CMD_CONINC
-#undef CMD_CONINC
-#endif /* CMD_CONINC */
- c = getchar(); /* RTU doesn't discard the ^Z */
- rtu_bug = 0;
- }
-#endif /* RTU */
-#endif /* datageneral */
- return(c); /* Return what we got */
-}
-
-/* #ifdef USE_ARROWKEYS */
-
-/* Mechanism to use for peeking into stdin buffer */
-
-#ifndef USE_FILE_CNT /* stdin->__cnt */
-#ifndef USE_FILE__CNT /* Note: two underscores */
-#ifdef HPUX /* HPUX 7-11 */
-#ifndef HPUX5
-#ifndef HPUX6
-#define USE_FILE__CNT
-#endif /* HPUX6 */
-#endif /* HPUX5 */
-#else
-#ifdef ANYSCO /* SCO UNIX, OSR5, Unixware, etc */
-#ifndef OLD_UNIXWARE /* But not Unixware 1.x or 2.0 */
-#ifndef UNIXWARE2 /* or 2.1.0 */
-#define USE_FILE__CNT
-#endif /* UNIXWARE2 */
-#endif /* OLD_UNIXWARE */
-#endif /* ANYSCO */
-#endif /* HPUX */
-#endif /* USE_FILE__CNT */
-#endif /* USE_FILE_CNT */
-
-#ifndef USE_FILE_R /* stdin->_r */
-#ifndef USE_FILE_CNT
-#ifndef USE_FILE__CNT
-#ifdef BSD44 /* {Free,Open,Net}BSD, BSDI */
-#define USE_FILE_R
-#endif /* BSD44 */
-#endif /* USE_FILE__CNT */
-#endif /* USE_FILE_CNT */
-#endif /* USE_FILE_R */
-
-#ifndef USE_FILE_R /* stdin->_cnt */
-#ifndef USE_FILE_CNT
-#ifndef USE_FILE__CNT
-#define USE_FILE_CNT /* Everybody else (but Linux) */
-#endif /* USE_FILE__CNT */
-#endif /* USE_FILE_CNT */
-#endif /* USE_FILE_R */
-
-
-/*
- c m d c o n c h k
-
- How many characters are waiting to be read at the console? Normally
- conchk() would tell us, but in Unix and VMS cmdgetc() uses stdio getchar(),
- thus bypassing coninc()/conchk(), so we have to peek into the stdin buffer,
- which is totally nonportable. Which is why this routine is, at least for
- now, used only for checking for arrow-key sequences from the keyboard after
- an ESC was read. Wouldn't it be nice if the stdio package had a function
- that returned the number of bytes waiting to be read from its buffer?
- Returns 0 or greater always.
-*/
-int
-cmdconchk() {
- int x = 0, y;
- y = pushc ? 1 : 0; /* Have command character pushed? */
-#ifdef OS2
- x = conchk(); /* Check device-driver buffer */
- if (x < 0) x = 0;
-#else /* OS2 */
-#ifdef CMD_CONINC /* See cmdgetc() */
- x = conchk(); /* Check device-driver buffer */
- if (x < 0) x = 0;
-#else /* CMD_CONINC */
-
-/* Here we must look inside the stdin buffer - highly platform dependent */
-
-#ifdef _IO_file_flags /* Linux */
- x = (int) ((stdin->_IO_read_end) - (stdin->_IO_read_ptr));
- debug(F101,"cmdconchk _IO_file_flags","",x);
-#else /* _IO_file_flags */
-#ifdef USE_FILE_CNT /* Traditional */
-#ifdef VMS
- debug(F101,"cmdconchk (*stdin)->_cnt","",(*stdin)->_cnt);
- x = (*stdin)->_cnt;
-#else
-#ifdef NOARROWKEYS
- debug(F101,"cmdconchk NOARROWKEYS x","",0);
-#else
- debug(F101,"cmdconchk stdin->_cnt","",stdin->_cnt);
- x = stdin->_cnt;
-#endif /* NOARROWKEYS */
-#endif /* VMS */
- if (x == 0) x = conchk();
- if (x < 0) x = 0;
-#else /* USE_FILE_CNT */
-#ifdef USE_FILE__CNT /* HP-UX */
- debug(F101,"cmdconchk stdin->__cnt","",stdin->__cnt);
- x = stdin->__cnt;
- if (x == 0) x = conchk();
- if (x < 0) x = 0;
-#else /* USE_FILE_CNT */
-#ifdef USE_FILE_R /* FreeBSD, OpenBSD, etc */
- debug(F101,"cmdconchk stdin->_r","",stdin->_r);
- x = stdin->_r;
- if (x == 0) x = conchk();
- if (x < 0) x = 0;
-
- /* Fill in any others here... */
-
-#endif /* USE_FILE_R */
-#endif /* USE_FILE__CNT */
-#endif /* USE_FILE_CNT */
-#endif /* _IO_file_flags */
-#endif /* CMD_CONINC */
-#endif /* OS2 */
- return(x + y);
-}
-/* #endif */ /* USE_ARROWKEYS */
-
-
-static VOID
-cmdclrscn() { /* Clear the screen */
- ck_cls();
-}
-
-static VOID /* What to echo at end of command */
-#ifdef CK_ANSIC
-cmdnewl(char c)
-#else
-cmdnewl(c) char c;
-#endif /* CK_ANSIC */
-/* cmdnewl */ {
-#ifdef OS2
-#ifdef IKSD
- extern int inserver;
- if (inserver && c == LF)
- putchar(CR);
-#endif /* IKSD */
-#endif /* OS2 */
-
- putchar(c); /* c is the terminating character */
-
-#ifdef WINTCP /* what is this doing here? */
- if (c == CR) putchar(NL);
-#endif /* WINTCP */
-
-/*
- A.A. Chernov, who sent in changes for FreeBSD, said we also needed this
- for SVORPOSIX because "setup terminal by termios and curses does
- not convert \r to \n, so additional \n needed in newline function." But
- it is also very likely to result in unwanted blank lines.
-*/
-#ifdef BSD44
- if (c == CR) putchar(NL);
-#endif /* BSD44 */
-
-#ifdef COMMENT
- /* OS2 no longer needs this as all CR are converted to NL in coninc() */
- /* This eliminates the ugly extra blank lines discussed above. */
-#ifdef OS2
- if (c == CR) putchar(NL);
-#endif /* OS2 */
-#endif /* COMMENT */
-#ifdef aegis
- if (c == CR) putchar(NL);
-#endif /* aegis */
-#ifdef AMIGA
- if (c == CR) putchar(NL);
-#endif /* AMIGA */
-#ifdef datageneral
- if (c == CR) putchar(NL);
-#endif /* datageneral */
-#ifdef GEMDOS
- if (c == CR) putchar(NL);
-#endif /* GEMDOS */
-#ifdef STRATUS
- if (c == CR) putchar(NL);
-#endif /* STRATUS */
-}
-
-static VOID
-cmdchardel() { /* Erase a character from the screen */
-#ifndef NOSPL
- if (!echostars)
-#endif /* NOSPL */
- if (!dpx) return;
-#ifdef datageneral
- /* DG '\b' is EM (^y or \031) */
- if (termtype == 1)
- /* Erase a character from non-DG screen, */
- dgncoub(1,"\010 \010",3);
- else
-#endif /* datageneral */
- printf("\b \b");
-#ifdef GEMDOS
- fflush(stdout);
-#else
-#ifdef BEBOX
- fflush(stdout);
-#endif /* BEBOX */
-#endif /* GEMDOS */
-}
-
-static VOID
-#ifdef CK_ANSIC
-cmdecho(char c, int quote)
-#else
-cmdecho(c,quote) char c; int quote;
-#endif /* CK_ANSIC */
-{ /* cmdecho */
-#ifdef NOSPL
- if (!dpx) return;
-#else
- if (!echostars) {
- if (!dpx) return;
- } else {
- c = (char)echostars;
- }
-#endif /* NOSPL */
- /* Echo tty input character c */
- if (quote) {
- putchar(BS);
- putchar(SP);
- putchar(BS);
-#ifdef isprint
- putchar((CHAR) (isprint(c) ? c : '^' ));
-#else
- putchar((CHAR) ((c >= SP && c < DEL) ? c : '^'));
-#endif /* isprint */
- } else {
- putchar(c);
- }
-#ifdef OS2
- if (quote==1 && c==CR) putchar((CHAR) NL);
-#endif /* OS2 */
- if (timelimit)
- fflush(stdout);
-}
-
-/* Return pointer to current position in command buffer. */
-
-char *
-cmpeek() {
- return(np);
-}
-#endif /* NOICP */
-
-
-#ifdef NOICP
-#include "ckcdeb.h"
-#include "ckucmd.h"
-#include "ckcasc.h"
-#endif /* NOICP */
-
-/* X X E S C -- Interprets backslash codes */
-/* Returns the int value of the backslash code if it is > -1 and < 256 */
-/* and updates the string pointer to first character after backslash code. */
-/* If the argument is invalid, leaves pointer unchanged and returns -1. */
-
-int
-xxesc(s) char **s; { /* Expand backslash escapes */
- int x, y, brace, radix; /* Returns the int value */
- char hd = '9'; /* Highest digit in radix */
- char *p;
-
- p = *s; /* pointer to beginning */
- if (!p) return(-1); /* watch out for null pointer */
- x = *p++; /* character at beginning */
- if (x != CMDQ) return(-1); /* make sure it's a backslash code */
-
- x = *p; /* it is, get the next character */
- if (x == '{') { /* bracketed quantity? */
- p++; /* begin past bracket */
- x = *p;
- brace = 1;
- } else brace = 0;
- switch (x) { /* Start interpreting */
- case 'd': /* Decimal radix indicator */
- case 'D':
- p++; /* Just point past it and fall thru */
- case '0': /* Starts with digit */
- case '1':
- case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- radix = 10; /* Decimal */
- hd = '9'; /* highest valid digit */
- break;
- case 'o': /* Starts with o or O */
- case 'O':
- radix = 8; /* Octal */
- hd = '7'; /* highest valid digit */
- p++; /* point past radix indicator */
- break;
- case 'x': /* Starts with x or X */
- case 'X':
- radix = 16; /* Hexadecimal */
- p++; /* point past radix indicator */
- break;
- default: /* All others */
-#ifdef COMMENT
- *s = p+1; /* Treat as quote of next char */
- return(*p);
-#else
- return(-1);
-#endif /* COMMENT */
- }
- /* For OS/2, there are "wide" characters required for the keyboard
- * binding, i.e \644 and similar codes larger than 255 (byte).
- * For this purpose, give up checking for < 256. If someone means
- * \266 should result in \26 followed by a "6" character, he should
- * always write \{26}6 anyway. Now, return only the lower byte of
- * the result, i.e. 10, but eat up the whole \266 sequence and
- * put the wide result 266 into a global variable. Yes, that's not
- * the most beautiful programming style but requires the least
- * amount of changes to other routines.
- */
- if (*p == '{') { /* Sun May 11 20:00:40 2003 */
- brace = 1; /* Allow {} after radix indicator */
- p++;
- }
- if (radix <= 10) { /* Number in radix 8 or 10 */
- for ( x = y = 0;
- (*p) && (*p >= '0') && (*p <= hd)
-#ifdef OS2
- && (y < 5) && (x*radix < KMSIZE);
- /* the maximum needed value \8196 is 4 digits long */
- /* while as octal it requires \1377, i.e. 5 digits */
-#else
- && (y < 3) && (x*radix < 256);
-#endif /* OS2 */
- p++,y++) {
- x = x * radix + (int) *p - 48;
- }
-#ifdef OS2
- wideresult = x; /* Remember wide result */
- x &= 255;
-#endif /* OS2 */
- if (y == 0 || x > 255) { /* No valid digits? */
- *s = p; /* point after it */
- return(-1); /* return failure. */
- }
- } else if (radix == 16) { /* Special case for hex */
- if ((x = unhex(*p++)) < 0) { *s = p - 1; return(-1); }
- if ((y = unhex(*p++)) < 0) { *s = p - 2; return(-1); }
- x = ((x << 4) & 0xF0) | (y & 0x0F);
-#ifdef OS2
- wideresult = x;
- if ((y = unhex(*p)) >= 0) {
- p++;
- wideresult = ((x << 4) & 0xFF0) | (y & 0x0F);
- x = wideresult & 255;
- }
-#endif /* OS2 */
- } else x = -1;
- if (brace && *p == '}' && x > -1) /* Point past closing brace, if any */
- p++;
- *s = p; /* Point to next char after sequence */
- return(x); /* Return value of sequence */
-}
-
-int /* Convert hex string to int */
-#ifdef CK_ANSIC
-unhex(char x)
-#else
-unhex(x) char x;
-#endif /* CK_ANSIC */
-/* unhex */ {
-
- if (x >= '0' && x <= '9') /* 0-9 is offset by hex 30 */
- return(x - 0x30);
- else if (x >= 'A' && x <= 'F') /* A-F offset by hex 37 */
- return(x - 0x37);
- else if (x >= 'a' && x <= 'f') /* a-f offset by hex 57 */
- return(x - 0x57); /* (obviously ASCII dependent) */
- else return(-1);
-}
-
-/* L O O K U P -- Lookup the string in the given array of strings */
-
-/*
- Call this way: v = lookup(table,word,n,&x);
-
- table - a 'struct keytab' table.
- word - the target string to look up in the table.
- n - the number of elements in the table.
- x - address of an integer for returning the table array index,
- or NULL if you don't need a table index.
-
- The keyword table must be arranged in ascending alphabetical order;
- alphabetic case doesn't matter but letters are treated as lowercase
- for purposes of ordering; thus "^" and "_" come *before* the letters,
- not after them.
-
- Returns the keyword's associated value (zero or greater) if found,
- with the variable x set to the keyword-table index. If is lookup()
- is not successful, it returns:
-
- -3 if nothing to look up (target was null),
- -2 if ambiguous,
- -1 if not found.
-
- A match is successful if the target matches a keyword exactly, or if
- the target is a prefix of exactly one keyword. It is ambiguous if the
- target matches two or more keywords from the table.
-
- Lookup() is the critical routine in scripts and so is optimized with a
- simple static cache plus some other tricks. Maybe it could be improved
- further with binary search or hash techniques but I doubt it since most
- keyword tables are fairly short.
-*/
-
-#ifdef USE_LUCACHE /* Lookup cache */
-extern int lusize; /* (initialized in ckuus5.c) */
-extern char * lucmd[];
-extern int luval[];
-extern int luidx[];
-extern struct keytab * lutab[];
-long luhits = 0L;
-long lucalls = 0L;
-long xxhits = 0L;
-long luloop = 0L;
-#endif /* USE_LUCACHE */
-
-int
-lookup(table,cmd,n,x) char *cmd; struct keytab table[]; int n, *x; {
-
- register int i, m;
- int v, len, cmdlen = 0;
- char c = NUL, c1, *s;
-
-/* Get 1st char of search object, if it's null return -3. */
-
- if (!cmd || n < 1) /* Defense de nullarg */
- return(-3);
- c1 = *cmd; /* First character */
- if (!c1) /* Make sure there is one */
- return(-3);
- if (isupper(c1)) /* If letter make it lowercase */
- c1 = tolower(c1);
-
-#ifdef USE_LUCACHE /* lookup() cache */
- m = lusize;
- lucalls++; /* Count this lookup() call */
- for (i = 0; i < m; i++) { /* Loop thru cache */
- if (*(lucmd[i]) == c1) { /* Same as 1st char of search item? */
- if (lutab[i] == table) { /* Yes - same table too? */
- if (!strcmp(cmd,lucmd[i])) { /* Yes - compare */
- if (x) *x = luidx[i]; /* Match - return index */
- luhits++; /* Count cache hit */
- return(luval[i]); /* Return associated value */
- }
- }
- }
- }
-#endif /* USE_LUCACHE */
-
-/* Not null, not in cache, look it up */
-
- s = cmd;
- while (*s++) cmdlen++; /* Length of target */
-/*
- Quick binary search to find last table entry whose first character is
- lexically less than the first character of the search object. This is
- the starting point of the next loop, which must go in sequence since it
- compares adjacent table entries.
-*/
- if (n < 5) { /* Not worth it for small tables */
- i = 0;
- } else {
- int lo = 0;
- int hi = n;
- int count = 0;
- while (lo+2 < hi && ++count < 12) {
- i = lo + ((hi - lo) / 2);
- c = *(table[i].kwd);
- if (isupper(c)) c = tolower(c);
- if (c < c1) {
- lo = i;
- } else {
- hi = i;
- }
- }
- i = (c < c1) ? lo+1 : lo;
-#ifdef USE_LUCACHE
- if (i > 0) xxhits++;
-#endif /* USE_LUCACHE */
- }
- for ( ; i < n-1; i++) {
-#ifdef USE_LUCACHE
- luloop++;
-#endif /* USE_LUCACHE */
- v = 0;
- c = *(table[i].kwd);
- if (c) {
- if (isupper(c)) c = tolower(c);
-
- /* The following is a big performance booster but makes it */
- /* absolutely essential that all lookup() tables are in order. */
-
- if (c > c1) /* Leave early if past our mark */
- return(-1);
-
-#ifdef DEBUG
- /* Use LOG DEBUG to check */
-
- if (deblog) {
- if (ckstrcmp(table[i].kwd,table[i+1].kwd,0,0) > 0) {
- printf("TABLE OUT OF ORDER [%s] [%s]\n",
- table[i].kwd,table[i+1].kwd);
-
- }
- }
-#endif /* DEBUG */
-
- if (c == c1) {
- len = 0;
- s = table[i].kwd;
- while (*s++) len++;
- if ((len == cmdlen && !ckstrcmp(table[i].kwd,cmd,len,0)) ||
- ((v = !ckstrcmp(table[i].kwd,cmd,cmdlen,0)) &&
- ckstrcmp(table[i+1].kwd,cmd,cmdlen,0))) {
- if (x) *x = i;
- return(table[i].kwval);
- }
- } else v = 0;
- }
- if (v) { /* Ambiguous */
- if (x) *x = i; /* Set index of first match */
- return(-2);
- }
- }
-
-/* Last (or only) element */
-
- if (!ckstrcmp(table[n-1].kwd,cmd,cmdlen,0)) {
- if (x) *x = n-1;
- /* debug(F111,"lookup",table[i].kwd,table); */
- return(table[n-1].kwval);
- } else return(-1);
-}
-
-/*
- x l o o k u p
-
- Like lookup, but requires a full (but case-independent) match
- and does NOT require the table to be in order.
-*/
-int
-xlookup(table,cmd,n,x) struct keytab table[]; char *cmd; int n, *x; {
- register int i;
- int len, cmdlen, one = 0;
- register char c, c2, * s, * s2;
-
- if (!cmd) cmd = ""; /* Check args */
- if (!*cmd || n < 1) return(-3);
-
- c = *cmd; /* First char of string to look up */
- if (!*(cmd+1)) { /* Special handling for 1-char names */
- cmdlen = 1;
- if (isupper(c))
- c = tolower(c);
- one = 1;
- } else {
- cmdlen = 0;
- s = cmd;
- while (*s++) cmdlen++;
- c = *cmd;
- if (isupper(c))
- c = tolower(c);
- }
- if (cmdlen < 1)
- return(-3);
-
- for (i = 0; i < n; i++) {
- s = table[i].kwd; /* This entry */
- if (!s) s = "";
- if (!*s) continue; /* Empty table entry */
- c2 = *s;
- if (isupper(c2)) c2 = tolower(c2);
- if (c != c2) continue; /* First char doesn't match */
- if (one) { /* Name is one char long */
- if (!*(s+1)) {
- if (x) *x = i;
- *cmd = c;
- return(table[i].kwval); /* So is table entry */
- }
- } else { /* Otherwise do string comparison */
- s2 = s;
- len = 0;
- while (*s2++) len++;
- if (len == cmdlen && !ckstrcmp(s,cmd,-1,0)) {
- if (x) *x = i;
- return(table[i].kwval);
- }
- }
- }
- return(-1);
-}
-
-/* Reverse lookup */
-
-char *
-rlookup(table,n,x) struct keytab table[]; int n, x; {
- int i;
- for (i = 0; i < n; i++) {
- if (table[i].kwval == x)
- return(table[i].kwd);
- }
- return(NULL);
-}
-
-#ifndef NOICP
-int
-cmdsquo(x) int x; {
- quoting = x;
- return(1);
-}
-
-int
-cmdgquo() {
- return(quoting);
-}
-#endif /* NOICP */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckucmd.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckucmd.h
deleted file mode 100644
index 7cd4ced..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckucmd.h
+++ /dev/null
@@ -1,312 +0,0 @@
-/* C K U C M D . H -- Header file for Unix cmd package */
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>
- Columbia University Kermit Project, New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-#ifndef CKUCMD_H
-#define CKUCMD_H
-
-/* Command recall */
-
-#ifdef pdp11 /* Not enough room for this */
-#ifndef NORECALL
-#define NORECALL
-#endif /* NORECALL */
-#endif /* pdp11 */
-
-#ifdef DYNAMIC /* Dynamic command buffers */
-/*
- Use malloc() to allocate the many command-related buffers in ckucmd.c.
-*/
-#ifndef DCMDBUF
-#ifndef NORECALL
-#define NORECALL
-#endif /* NORECALL */
-#endif /* DCMDBUF */
-
-#ifndef NORECALL
-#define CK_RECALL
-#else
-#ifdef CK_RECALL
-#undef CK_RECALL
-#endif /* CK_RECALL */
-#endif /* NORECALL */
-#else
-#ifndef NORECALL
-#define NORECALL
-#endif /* NORECALL */
-#endif /* DYNAMIC */
-
-#ifdef NORECALL
-#ifdef CK_RECALL
-#undef CK_RECALL
-#endif /* CK_RECALL */
-#endif /* NORECALL */
-
-#ifdef NORECALL
-#ifndef NOARROWKEYS
-#define NOARROWKEYS
-#endif /* NOARROWKEYS */
-#endif /* NORECALL */
-
-/* Special getchars */
-
-#ifdef VMS
-#ifdef getchar /* This is for VMS GCC */
-#undef getchar
-#endif /* getchar */
-#define getchar() vms_getchar()
-int vms_getchar(void);
-#endif /* VMS */
-
-#ifdef aegis
-#undef getchar
-#define getchar() coninc(0)
-#endif /* aegis */
-
-#ifdef AMIGA
-#undef getchar
-#define getchar() coninc(0)
-#endif /* AMIGA */
-
-#ifdef Plan9
-#undef getchar
-#define getchar() coninc(0)
-#undef putchar
-#define putchar(c) conoc(c)
-#undef printf
-#define printf conprint
-#endif /* Plan9 */
-
-/* Sizes of things */
-
-#ifndef CMDDEP
-#ifdef BIGBUFOK
-#define CMDDEP 64 /* Maximum command recursion depth */
-#else
-#define CMDDEP 20
-#endif /* BIGBUFOK */
-#endif /* CMDDEP */
-#define HLPLW 78 /* Width of ?-help line */
-#define HLPCW 19 /* Width of ?-help column */
-#define HLPBL 100 /* Help string buffer length */
-#ifdef BIGBUFOK
-#define ATMBL 10238 /* Command atom buffer length*/
-#else
-#ifdef NOSPL
-#define ATMBL 256
-#else
-#define ATMBL 1024
-#endif /* NOSPL */
-#endif /* BIGBUFOK */
-
-#ifndef CMDBL
-#ifdef NOSPL
-/* No script programming language, save some space */
-#define CMDBL 608 /* Command buffer length */
-#else
-#ifdef BIGBUFOK
-#define CMDBL 32763
-#else
-#define CMDBL 4092
-#endif /* OS2 */
-#endif /* NOSPL */
-#endif /* CMDBL */
-
-/* Special characters */
-
-#define RDIS 0022 /* Redisplay (^R) */
-#define LDEL 0025 /* Delete line (^U) */
-#define WDEL 0027 /* Delete word (^W) */
-#ifdef CK_RECALL
-#define C_UP 0020 /* Go Up in recall buffer (^P) */
-#define C_UP2 0002 /* Alternate Go Up (^B) for VMS */
-#define C_DN 0016 /* Go Down in recall buffer (^N) */
-#endif /* CK_RECALL */
-
-/* Keyword flags (bits, powers of 2) */
-
-#define CM_INV 1 /* Invisible keyword */
-#define CM_ABR 2 /* Abbreviation for another keyword */
-#define CM_HLP 4 /* Help-only keyword */
-#define CM_ARG 8 /* An argument is required */
-#define CM_NOR 16 /* No recall for this command */
-#define CM_PRE 32 /* Long-form cmdline arg for prescan */
-#define CM_PSH 64 /* Command disabled if nopush */
-#define CM_LOC 128 /* Command disabled if nolocal */
-
-/*
- A long-form command line option is a keyword using the regular struct keytab
- and lookup mechanisms. Flags that make sense in this context are CM_ARG,
- indicating this option requires an argument (operand), and CM_PRE, which
- means this option must be processed before the initialization file. The
- absence of CM_PRE means the option is to be processed after the
- initialization file in the normal manner.
-*/
-
-/* Token flags (numbers) */
-
-#define CMT_COM 0 /* Comment (; or #) */
-#define CMT_SHE 1 /* Shell escape (!) */
-#define CMT_LBL 2 /* Label (:) */
-#define CMT_FIL 3 /* Indirect filespec (@) (not used) */
-
-/* Path separator for path searches */
-
-#ifdef OS2
-#define PATHSEP ';'
-#else
-#ifdef UNIX
-#define PATHSEP ':'
-#else
-#define PATHSEP ','
-#endif /* UNIX */
-#endif /* OS2 */
-
-#ifndef CK_KEYTAB
-#define CK_KEYTAB
-
-/* Keyword Table Template perhaps already defined in ckcdeb.h */
-
-struct keytab { /* Keyword table */
- char *kwd; /* Pointer to keyword string */
- int kwval; /* Associated value */
- int flgs; /* Flags (as defined above) */
-};
-#endif /* CK_KEYTAB */
-
-/* String preprocessing function */
-
-#ifdef CK_ANSIC /* ANSI C */
-#ifdef M_SYSV /* SCO Microsoft C wants no args */
-typedef int (*xx_strp)();
-#else
-typedef int (*xx_strp)(char *, char **, int *);
-#endif /* M_SYSV */
-#else /* Not ANSI C */
-typedef int (*xx_strp)();
-#endif /* CK_ANSIC */
-
-/* FLDDB struct */
-
-typedef struct FDB {
- int fcode; /* Function code */
- char * hlpmsg; /* Help message */
- char * dflt; /* Default */
- char * sdata; /* Additional string data */
- int ndata1; /* Additional numeric data 1 */
- int ndata2; /* Additional numeric data 2 */
- xx_strp spf; /* String processing function */
- struct keytab * kwdtbl; /* Keyword table */
- struct FDB * nxtfdb; /* Pointer to next alternative */
-} fdb;
-
-typedef struct OFDB {
- struct FDB * fdbaddr; /* Address of succeeding FDB struct */
- int fcode; /* Function code */
- char * sresult; /* String result */
- int nresult; /* Integer result */
- int kflags; /* Keyword flags if any */
- CK_OFF_T wresult; /* Long integer ("wide") result */
-} ofdb;
-
-#ifndef CKUCMD_C
-extern struct OFDB cmresult;
-#endif /* CKUCMD_C */
-
-/* Codes for primary parsing function */
-
-#define _CMNUM 0 /* Number */
-#define _CMOFI 1 /* Output file */
-#define _CMIFI 2 /* Input file */
-#define _CMFLD 3 /* Arbitrary field */
-#define _CMTXT 4 /* Text string */
-#define _CMKEY 5 /* Keyword */
-#define _CMCFM 6 /* Confirmation */
-#define _CMDAT 7 /* Date/time */
-#define _CMNUW 8 /* Wide version of cmnum */
-
-/* Function prototypes */
-
-_PROTOTYP( int xxesc, (char **) );
-_PROTOTYP( int cmrini, (int) );
-_PROTOTYP( VOID cmsetp, (char *) );
-_PROTOTYP( VOID cmsavp, (char [], int) );
-_PROTOTYP( char * cmgetp, (void) );
-_PROTOTYP( VOID prompt, (xx_strp) );
-_PROTOTYP( VOID pushcmd, (char *) );
-_PROTOTYP( VOID cmres, (void) );
-_PROTOTYP( VOID cmini, (int) );
-_PROTOTYP( int cmgbrk, (void) );
-_PROTOTYP( int cmgkwflgs, (void) );
-_PROTOTYP( int cmpush, (void) );
-_PROTOTYP( int cmpop, (void) );
-_PROTOTYP( VOID untab, (char *) );
-_PROTOTYP( int cmnum, (char *, char *, int, int *, xx_strp ) );
-_PROTOTYP( int cmnumw, (char *, char *, int, CK_OFF_T *, xx_strp ) );
-_PROTOTYP( int cmofi, (char *, char *, char **, xx_strp ) );
-_PROTOTYP( int cmifi, (char *, char *, char **, int *, xx_strp ) );
-_PROTOTYP( int cmiofi, (char *, char *, char **, int *, xx_strp ) );
-_PROTOTYP( int cmifip,(char *, char *, char **, int *, int, char *, xx_strp ));
-_PROTOTYP( int cmifi2,(char *,char *,char **,int *,int,char *,xx_strp,int ));
-_PROTOTYP( int cmdir, (char *, char *, char **, xx_strp ) );
-_PROTOTYP( int cmdirp, (char *, char *, char **, char *, xx_strp ) );
-_PROTOTYP( int cmfld, (char *, char *, char **, xx_strp ) );
-_PROTOTYP( int cmtxt, (char *, char *, char **, xx_strp ) );
-_PROTOTYP( int cmkey, (struct keytab [], int, char *, char *, xx_strp) );
-_PROTOTYP( int cmkeyx, (struct keytab [], int, char *, char *, xx_strp) );
-_PROTOTYP( int cmkey2,(struct keytab [],int,char *,char *,char *,xx_strp,int));
-_PROTOTYP( int cmswi, (struct keytab [], int, char *, char *, xx_strp) );
-_PROTOTYP( int cmdate,(char *, char *, char **, int, xx_strp) );
-_PROTOTYP( char * cmpeek, (void) );
-_PROTOTYP( int cmfdb, (struct FDB *) );
-_PROTOTYP( VOID cmfdbi, (struct FDB *,
- int, char *, char *, char *, int, int, xx_strp,
- struct keytab *, struct FDB *) );
-_PROTOTYP( int chktok, (char *) );
-_PROTOTYP( int cmcfm, (void) );
-_PROTOTYP( int lookup, (struct keytab [], char *, int, int *) );
-_PROTOTYP( VOID kwdhelp, (struct keytab[],int,char *,char *,char *,int,int) );
-_PROTOTYP( int ungword, (void) );
-_PROTOTYP( VOID unungw, (void) );
-_PROTOTYP( int cmdsquo, (int) );
-_PROTOTYP( int cmdgquo, (void) );
-_PROTOTYP( char * ckcvtdate, (char *, int) );
-_PROTOTYP( int cmdgetc, (int));
-#ifndef NOARROWKEYS
-_PROTOTYP( int cmdconchk, (void) );
-#endif /* NOARROWKEYS */
-
-#ifdef CK_RECALL
-_PROTOTYP( char * cmgetcmd, (char *) );
-_PROTOTYP( VOID addcmd, (char *) );
-_PROTOTYP( VOID cmaddnext, (void) );
-#endif /* CK_RECALL */
-_PROTOTYP( char * cmcvtdate, (char *, int) );
-_PROTOTYP( char * cmdiffdate, (char *, char *) );
-_PROTOTYP( char * cmdelta, (int,
- int,int,int,int,int,int,int,int,int,int,int,int ));
-_PROTOTYP( char * shuffledate, (char *, int) );
-_PROTOTYP( int filhelp, (int, char *, char *, int, int) );
-_PROTOTYP( int xfilhelp, (int, char *, char *, int, int,
- int,
- char *, char *, char *, char *,
- CK_OFF_T, CK_OFF_T,
- int, int,
- char **) );
-_PROTOTYP( int delta2sec, (char *, long *) );
-
-#ifdef DCMDBUF
-_PROTOTYP( int cmsetup, (void) );
-#endif /* DCMDBUF */
-
-#endif /* CKUCMD_H */
-
-/* End of ckucmd.h */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckucns.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckucns.c
deleted file mode 100644
index 337197c..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckucns.c
+++ /dev/null
@@ -1,2720 +0,0 @@
-#include "ckcsym.h"
-char *connv = "CONNECT Command for UNIX:select(), 9.0.139, 1 Mar 2010";
-
-/* C K U C N S -- Terminal connection to remote system, for UNIX */
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- This version of the UNIX CONNECT module uses select(), which is required for
- Kerberos encryption. Thus it can be used only on UNIX systems that support
- select() on both TCP/IP and serial connections. A separate module that uses
- a completely portable fork() structure can be used on systems where select()
- is not available or does not work as required.
-*/
-
-#include "ckcdeb.h" /* Common things first */
-
-#ifndef NOLOCAL
-
-#ifdef OSF13
-#ifdef CK_ANSIC
-#ifdef _NO_PROTO
-#undef _NO_PROTO
-#endif /* _NO_PROTO */
-#endif /* CK_ANSIC */
-#endif /* OSF13 */
-
-#include <errno.h> /* Error numbers */
-
-#ifndef NOTIMEH
-#include <time.h> /* For FD_blah */
-#ifdef SYSTIMEH /* (IRIX 5.3) */
-#include <sys/time.h>
-#endif /* SYSTIMEH */
-#endif /* NOTIMEH */
-
-#ifdef BSD42HACK /* Why is this necessary? */
-#ifndef DCLTIMEVAL
-#define DCLTIMEVAL
-#endif /* DCLTIMEVAL */
-#endif /* BSD42HACK */
-
-/* Kermit-specific includes */
-
-#include "ckcasc.h" /* ASCII characters */
-#include "ckcker.h" /* Kermit things */
-#include "ckucmd.h" /* For xxesc() prototype */
-#include "ckcnet.h" /* Network symbols */
-#ifndef NOCSETS
-#include "ckcxla.h" /* Character set translation */
-#endif /* NOCSETS */
-
-#ifdef BEBOX
-#include <kernel/OS.h>
-#include <socket.h>
-#include <stdio.h>
-#endif /* BEBOX */
-
-#include <signal.h> /* Signals */
-
-/* All the following is for select()... */
-
-#ifdef CKTIDLE /* Timeouts only for SET TERM IDLE */
-
-#ifndef DCLTIMEVAL
-#ifdef UNIXWARE
-#ifndef UW7
-#define DCLTIMEVAL
-#endif /* UW7 */
-#endif /* UNIXWARE */
-#endif /* DCLTIMEVAL */
-
-#ifdef DCLTIMEVAL /* Declare timeval ourselves */
-struct timeval {
- long tv_sec;
- long tv_usec;
-};
-#else /* !DCLTIMEVAL */
-#ifndef NOSYSTIMEBH
-#ifdef SYSTIMEBH
-#include <sys/timeb.h>
-#endif /* SYSTIMEBH */
-#endif /* NOSYSTIMEBH */
-#endif /* DCLTIMEVAL */
-#endif /* CKTIDLE */
-
-#ifndef SCO_OSR504
-#ifdef SELECT_H
-#include <sys/select.h>
-#endif /* SELECT_H */
-#endif /* SCO_OSR504 */
-
-#ifndef FD_SETSIZE
-#ifdef CK_FORWARD_X
-#define FD_SETSIZE 256
-#else
-#define FD_SETSIZE 32
-#endif /* CK_FORWARD_X */
-#endif /* FD_SETSIZE */
-
-#ifdef HPUX
-#ifndef HPUX10
-#ifndef HPUX1100
-/* The three interior args to select() are (int *) rather than (fd_set *) */
-#ifndef INTSELECT
-#define INTSELECT
-#endif /* INTSELECT */
-#endif /* HPUX1100 */
-#endif /* HPUX10 */
-#endif /* HPUX */
-
-/* Internal function prototypes */
-
-#ifdef NEWFTP
-#endif /* NEWFTP */
-_PROTOTYP( VOID ttflux, (void) );
-_PROTOTYP( VOID doesc, (char) );
-_PROTOTYP( int hconne, (void) );
-#ifndef NOSHOW
-_PROTOTYP( VOID shomdm, (void) );
-#endif /* NOSHOW */
-_PROTOTYP( static int kbget, (void) );
-_PROTOTYP( static int ckcputf, (void) );
-
-/* External variables */
-
-extern struct ck_p ptab[];
-
-extern int local, escape, duplex, parity, flow, seslog, sessft, debses,
- mdmtyp, ttnproto, cmask, cmdmsk, network, nettype, sosi, tnlm,
- xitsta, what, ttyfd, ttpipe, quiet, backgrd, pflag, tt_crd, tt_lfd,
- tn_nlm, ttfdflg,
- tt_escape, justone, carrier, ttpty, hwparity;
-
-#ifndef NODIAL
-extern int dialmhu, dialsta;
-#endif /* NODIAL */
-
-#ifdef CKLEARN
-extern FILE * learnfp;
-extern int learning;
-static ULONG learnt1;
-static char learnbuf[LEARNBUFSIZ] = { NUL, NUL };
-static int learnbc = 0;
-static int learnbp = 0;
-static int learnst = 0;
-#endif /* CKLEARN */
-
-extern long speed;
-extern char ttname[], sesfil[], myhost[], *ccntab[];
-#ifdef TNCODE
-extern int tn_b_nlm, tn_rem_echo;
-#endif /* TNCODE */
-
-#ifdef CK_TRIGGER
-extern char * tt_trigger[], * triggerval;
-#endif /* CK_TRIGGER */
-
-#ifdef CKTIDLE
-extern int tt_idlelimit, tt_idleact;
-extern char * tt_idlestr;
-static int idlelimit = 0;
-#endif /* CKTIDLE */
-extern int cx_status; /* CONNECT status code */
-
-extern int nopush;
-
-#ifdef CK_APC
-extern int apcactive; /* Application Program Command (APC) */
-extern int apcstatus; /* items ... */
-static int apclength = 0;
-#ifdef DCMDBUF
-extern char *apcbuf;
-#else
-extern char apcbuf[];
-#endif /* DCMDBUF */
-static int apcbuflen = APCBUFLEN - 2;
-extern int protocol;
-#endif /* CK_APC */
-#ifndef NOXFER
-extern int autodl; /* Auto download */
-#endif /* NOXFER */
-
-#ifdef CK_AUTODL
-extern CHAR ksbuf[];
-extern CHAR stchr;
-extern int kstartactive;
-#endif /* CK_AUTODL */
-
-#ifdef CK_ENCRYPTION
-extern int me_auth;
-#endif /* CK_ENCRYPTION */
-
-#ifdef CK_XYZ
-#ifdef XYZ_INTERNAL
-static int zmdlok = 1; /* Zmodem autodownloads available */
-#else
-static int zmdlok = 0; /* Depends on external protocol def */
-#endif /* XYZ_INTERNAL */
-#else
-static int zmdlok = 0; /* Not available at all */
-#endif /* CK_XYZ */
-
-#ifndef NOSETKEY /* Keyboard mapping */
-extern KEY *keymap; /* Single-character key map */
-extern MACRO *macrotab; /* Key macro pointer table */
-static MACRO kmptr = NULL; /* Pointer to current key macro */
-#endif /* NOSETKEY */
-
-/* Global variables local to this module */
-
-static int
- active = 0,
- quitnow = 0, /* <esc-char>Q was typed */
- dohangup = 0, /* <esc-char>H was typed */
- inshift = 0, /* SO/SI shift states */
- outshift = 0;
-
-static char ecbuf[10], *ecbp; /* Escape char buffer & pointer */
-
-#ifdef CK_SMALL
-#define IBUFL 1536 /* Input buffer length */
-#else
-#define IBUFL 4096
-#endif /* CK_SMALL */
-
-static int obc = 0; /* Output buffer count */
-
-#ifndef OXOS
-#define OBUFL 1024 /* Output buffer length */
-#else
-#define OBUFL IBUFL
-#endif /* OXOS */
-
-#ifdef BIGBUFOK
-#define TMPLEN 4096 /* Temporary message buffer length */
-#else
-#define TMPLEN 200
-#endif /* BIGBUFOK */
-
-#ifdef DYNAMIC
-static char *ibuf = NULL, *obuf = NULL, *temp = NULL; /* Buffers */
-#else
-static char ibuf[IBUFL], obuf[OBUFL], temp[TMPLEN];
-#endif /* DYNAMIC */
-
-#ifdef TNCODE
-static char tnopt[4];
-#endif /* TNCODE */
-
-#ifdef DYNAMIC
-static char *ibp; /* Input buffer pointer */
-#else
-static char *ibp = ibuf; /* Input buffer pointer */
-#endif /*DYNAMIC */
-static int ibc = 0; /* Input buffer count */
-
-#ifdef DYNAMIC
-static char *obp; /* Output buffer pointer */
-#else
-static char *obp = obuf; /* Output buffer pointer */
-#endif /* DYNAMIC */
-
-/* Character-set items */
-
-static int unicode = 0;
-
-#ifndef NOCSETS
-#ifdef CK_ANSIC /* ANSI C prototypes... */
-extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* Character set */
-extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* translation functions */
-static CHAR (*sxo)(CHAR); /* Local translation functions */
-static CHAR (*rxo)(CHAR); /* for output (sending) terminal chars */
-static CHAR (*sxi)(CHAR); /* and for input (receiving) terminal chars. */
-static CHAR (*rxi)(CHAR);
-#else /* Not ANSI C... */
-extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(); /* Character set */
-extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(); /* translation functions. */
-static CHAR (*sxo)(); /* Local translation functions */
-static CHAR (*rxo)(); /* for output (sending) terminal chars */
-static CHAR (*sxi)(); /* and for input (receiving) terminal chars. */
-static CHAR (*rxi)();
-#endif /* CK_ANSIC */
-extern int language; /* Current language. */
-static int langsv; /* For remembering language setting. */
-extern struct csinfo fcsinfo[]; /* File character set info. */
-extern int tcsr, tcsl; /* Terminal character sets, remote & local. */
-static int tcs; /* Intermediate ("transfer") character set. */
-static int tcssize = 0; /* Size of tcs */
-#ifdef UNICODE /* UTF-8 support */
-#ifdef CK_ANSIC
-extern int (*xl_ufc[MAXFCSETS+1])(USHORT); /* Unicode to FCS */
-extern USHORT (*xl_fcu[MAXFCSETS+1])(CHAR); /* FCS to Unicode */
-extern int (*xuf)(USHORT); /* Translation function UCS to FCS */
-extern USHORT (*xfu)(CHAR); /* Translation function FCS to UCS */
-#else
-extern int (*xl_ufc[MAXFCSETS+1])();
-extern USHORT (*xl_fcu[MAXFCSETS+1])();
-extern int (*xuf)();
-extern USHORT (*xfu)();
-#endif /* CK_ANSIC */
-#endif /* UNICODE */
-#endif /* NOCSETS */
-
-static int printing = 0;
-
-/*
- We do not need to parse and recognize escape sequences if we are being built
- without character-set support AND without APC support.
-*/
-#ifdef NOESCSEQ
-#ifdef XPRINT
-#undef XPRINT
-#endif /* XPRINT */
-
-#else /* NOESCSEQ not defined from outside */
-
-#ifdef NOCSETS /* No character sets */
-#ifndef CK_APC /* No APC */
-#ifndef XPRINT /* No transparent printing */
-#define NOESCSEQ /* So no escape sequence recognizer */
-#endif /* XPRINT */
-#endif /* CK_APC */
-#endif /* NOCSETS */
-#endif /* NOESCSEQ */
-
-/* inesc[] and oldesc[] made global 2010/03/01 for INPUT command */
-
-static int escseq = 0; /* 1 = Recognizer is active */
-/* static */ int inesc[2] = { 0, 0 }; /* State of sequence recognizer */
-/* static */ int oldesc[2] = { -1, -1 }; /* Previous state of recognizer */
-
-#ifdef NOESCSEQ
-#define ES_NORMAL 0 /* Normal, not in an escape sequence */
-#define chkaes(x,y) 0
-#else
-/*
- As of C-Kermit 5A(178), the CONNECT command skips past ANSI escape sequences
- to avoid translating the characters within them. This allows the CONNECT
- command to work correctly with a host that uses a 7-bit ISO 646 national
- character set, in which characters like '[' would normally be converted to
- accented letters, ruining the terminal's interpretation (and generation)
- of escape sequences.
-
- As of 5A(190), the CONNECT command responds to APC escape sequences
- (ESC _ text ESC \) if the user SETs TERMINAL APC ON or UNCHECKED, and the
- program was built with CK_APC defined.
-
- Non-ANSI/ISO-compliant escape sequences are not handled. */
-
-/* States for the escape-sequence recognizer. */
-
-#define ES_NORMAL 0 /* Normal, not in an escape sequence */
-#define ES_GOTESC 1 /* Current character is ESC */
-#define ES_ESCSEQ 2 /* Inside an escape sequence */
-#define ES_GOTCSI 3 /* Inside a control sequence */
-#define ES_STRING 4 /* Inside DCS,OSC,PM, or APC string */
-#define ES_TERMIN 5 /* 1st char of string terminator */
-
-/*
- ANSI escape sequence handling. Only the 7-bit form is treated, because
- translation is not a problem in the 8-bit environment, in which all GL
- characters are ASCII and no translation takes place. So we don't check
- for the 8-bit single-character versions of CSI, DCS, OSC, APC, or ST.
- Here is the ANSI sequence recognizer state table, followed by the code
- that implements it.
-
- Definitions:
- CAN = Cancel 01/08 Ctrl-X
- SUB = Substitute 01/10 Ctrl-Z
- DCS = Device Control Sequence 01/11 05/00 ESC P
- CSI = Control Sequence Introducer 01/11 05/11 ESC [
- ST = String Terminator 01/11 05/12 ESC \
- OSC = Operating System Command 01/11 05/13 ESC ]
- PM = Privacy Message 01/11 05/14 ESC ^
- APC = Application Program Command 01/11 05/15 ESC _
-
- ANSI escape sequence recognizer:
-
- State Input New State ; Commentary
-
- NORMAL (start) ; Start in NORMAL state
-
- (any) CAN NORMAL ; ^X cancels
- (any) SUB NORMAL ; ^Z cancels
-
- NORMAL ESC GOTESC ; Begin escape sequence
- NORMAL other ; NORMAL control or graphic character
-
- GOTESC ESC ; Start again
- GOTESC [ GOTCSI ; CSI
- GOTESC P STRING ; DCS introducer, consume through ST
- GOTESC ] STRING ; OSC introducer, consume through ST
- GOTESC ^ STRING ; PM introducer, consume through ST
- GOTESC _ STRING ; APC introducer, consume through ST
- GOTESC 0..~ NORMAL ; 03/00 through 17/14 = Final character
- GOTESC other ESCSEQ ; Intermediate or ignored control character
-
- ESCSEQ ESC GOTESC ; Start again
- ESCSEQ 0..~ NORMAL ; 03/00 through 17/14 = Final character
- ESCSEQ other ; Intermediate or ignored control character
-
- GOTCSI ESC GOTESC ; Start again
- GOTCSI @..~ NORMAL ; 04/00 through 17/14 = Final character
- GOTCSI other ; Intermediate char or ignored control char
-
- STRING ESC TERMIN ; Maybe have ST
- STRING other ; Consume all else
-
- TERMIN \ NORMAL ; End of string
- TERMIN other STRING ; Still in string
-*/
-
-#ifdef XPRINT /* Transparent print support */
-/*
- We can't just print each byte as it comes in because then the printer-off
- sequence would be sent to the printer. Thus we have to buffer up escape
- sequences and print them only when they are complete AND we know they are
- not the printer-off sequence. All printing is done via zsoutx(ZMFILE,s,n).
- This allows for strings that contain NULs. Don't mix calls to zsoutx() with
- calls to zchout(), or the output will be scrambled. Also note that when
- printing a saved-up escape sequence, we never print its final character
- because that will be printed in the mainline code, upon return from
- chkaes(). Note that the printer-on sequence is passed to the screen; this
- is unavoidable, since we don't know what it is until after we get to the
- end, and for screen display purposes we can't buffer up escape sequences
- for numerous reasons. Therefore we also must output the printer-off
- sequence, otherwise a real terminal or emulator will be stuck in print mode.
-*/
-extern int tt_print;
-#define ESCBUFLEN 63
-static char escbuf[ESCBUFLEN+1] = { NUL, NUL };
-static int escbufc = 0;
-static int dontprint = 0;
-
-VOID
-printon() { /* Turn printing on */
- int x, pp;
- char * p;
- extern int printpipe, noprinter;
- extern char * printername;
-
- if (noprinter) {
- debug(F110,"PRINTER ON NOPRINTER","",0);
- return;
- }
- p = printername;
- pp = printpipe;
- if (!p) p = "";
- if (!*p) {
-#ifdef ANYBSD
- p = "lpr";
-#else
- p = "lp";
-#endif /* ANYBSD */
- pp = 1;
- debug(F110,"PRINTER DEFAULT",p,0);
- }
- debug(F111,"PRINTER ON",p,pp);
- if (pp) { /* Printing to pipe */
- x = zxcmd(ZMFILE,p);
- } else { /* Append to file */
- struct filinfo xx;
- xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
- xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = NUL;
- xx.lblopts = 0;
- x = zopeno(ZMFILE,p,NULL,&xx);
- }
- debug(F101,"PRINTER OPEN","",x);
- printing = 1;
-}
-
-VOID
-printoff() { /* Turn printing off */
- int x;
- extern int noprinter;
- if (noprinter) {
- printing = 0;
- debug(F100,"PRINTER OFF NOPRINTER","",0);
- return;
- }
- debug(F100,"PRINTER OFF","",0);
- if (printing) {
- x = zclose(ZMFILE);
- debug(F101,"PRINTER CLOSE","",x);
- printing = 0;
- }
-}
-#endif /* XPRINT */
-
-/*
- C H K A E S -- Check ANSI Escape Sequence.
-
- Call with EACH character in input stream.
- src = 0 means c is incoming from remote; 1 = char from keyboard.
- Sets global inesc[src] variable according to escape sequence state.
- Returns 0 normally, 1 if an APC sequence is to be executed.
- Handles transparent printing internally.
-*/
-int
-#ifdef CK_ANSIC
-chkaes(char c, int src)
-#else
-chkaes(c,src) char c; int src;
-#endif /* CK_ANSIC */
-/* chkaes */ {
-
- debug(F111,"chkaes entry inesc",ckitoa(src),inesc[src]);
- debug(F101,"chkaes c","",c);
-
- if (src < 0 || src > 1) /* Don't allow bad args. */
- return(0);
-
- oldesc[src] = inesc[src]; /* Remember previous state */
-
-#ifdef XPRINT
- if (inesc[src] && !src) { /* Save up escape seq for printing */
- if (!c) return(0); /* Ignore NULs */
- if (escbufc < ESCBUFLEN) {
- escbuf[escbufc++] = c;
- escbuf[escbufc] = NUL;
- debug(F111,"ESCBUF 1",escbuf,escbufc);
- } else { /* Buffer overrun */
- if (printing && escbufc) /* Print what's there so far */
- zsoutx(ZMFILE,escbuf,escbufc);
- escbufc = 1; /* clear it out */
- escbuf[0] = c; /* and start off fresh buffer */
- escbuf[1] = NUL; /* with this character. */
- }
- }
-#endif /* XPRINT */
-
- if (c == CAN || c == SUB) { /* CAN and SUB cancel any sequence */
-#ifdef XPRINT
- if (!src) {
- if (printing && escbufc > 1)
- zsoutx(ZMFILE,escbuf,escbufc-1);
- escbufc = 0; /* Clear buffer */
- escbuf[0] = NUL;
- }
-#endif /* XPRINT */
- inesc[src] = ES_NORMAL;
- } else /* Otherwise */
-
- switch (inesc[src]) { /* enter state switcher */
- case ES_NORMAL: /* NORMAL state */
- if (c == ESC) { /* Got an ESC */
- inesc[src] = ES_GOTESC; /* Change state to GOTESC */
-#ifdef XPRINT
- if (!src) {
- escbufc = 1; /* Clear escape sequence buffer */
- escbuf[0] = c; /* and deposit the ESC */
- escbuf[1] = NUL;
- debug(F111,"ESCBUF 2",escbuf,escbufc);
- }
-#endif /* XPRINT */
- }
- break; /* Otherwise stay in NORMAL state */
-
- case ES_GOTESC: /* GOTESC state - prev char was ESC*/
- if (c == '[') { /* Left bracket after ESC is CSI */
- inesc[src] = ES_GOTCSI; /* Change to GOTCSI state */
- } else if (c == 'P' || (c > 0134 && c < 0140)) { /* P, ], ^, or _ */
- inesc[src] = ES_STRING; /* Switch to STRING-absorption state */
-#ifdef XPRINT
- debug(F111,"ESCBUF STRING",escbuf,escbufc);
-#endif /* XPRINT */
-#ifdef CK_APC
- /* If APC not disabled */
- if (!src && c == '_' && (apcstatus & APC_ON)) {
- debug(F100,"CONNECT APC begin","",0);
- apcactive = APC_REMOTE; /* Set APC-Active flag */
- apclength = 0; /* and reset APC buffer pointer */
- }
-#endif /* CK_APC */
- } else if (c > 057 && c < 0177) { /* Final character '0' thru '~' */
- inesc[src] = ES_NORMAL; /* Back to normal */
-#ifdef XPRINT
- if (!src) {
- if (printing && escbufc > 1) {
- /* Dump esc seq buf to printer */
- zsoutx(ZMFILE,escbuf,escbufc-1);
- debug(F111,"ESCBUF PRINT 1",escbuf,escbufc);
- }
-
- escbufc = 0; /* Clear parameter buffer */
- escbuf[0] = NUL;
- }
-#endif /* XPRINT */
- } else if (c != ESC) { /* ESC in an escape sequence... */
- inesc[src] = ES_ESCSEQ; /* starts a new escape sequence */
- }
- break; /* Intermediate or ignored ctrl char */
-
- case ES_ESCSEQ: /* ESCSEQ -- in an escape sequence */
- if (c > 057 && c < 0177) { /* Final character '0' thru '~' */
- inesc[src] = ES_NORMAL; /* Return to NORMAL state. */
-#ifdef XPRINT
- if (!src) {
- if (printing && escbufc > 1) {
- zsoutx(ZMFILE,escbuf,escbufc-1);
- debug(F111,"ESCBUF PRINT 2",escbuf,escbufc);
- }
- escbufc = 0; /* Clear escseq buffer */
- escbuf[0] = NUL;
- }
-#endif /* XPRINT */
- } else if (c == ESC) { /* ESC ... */
- inesc[src] = ES_GOTESC; /* starts a new escape sequence */
- }
- break; /* Intermediate or ignored ctrl char */
-
- case ES_GOTCSI: /* GOTCSI -- In a control sequence */
- if (c > 077 && c < 0177) { /* Final character '@' thru '~' */
-#ifdef XPRINT
- if (!src && tt_print) { /* Printer enabled? */
- if (c == 'i') { /* Final char is "i"? */
- char * p = (char *) (escbuf + escbufc - 4);
- if (!strncmp(p, "\033[5i", 4)) { /* Turn printer on */
- printon();
- } else if (!strncmp(p, "\033[4i", 4)) { /* Or off... */
- int i;
- printoff(); /* Turn off printer. */
- dontprint = 1;
- for (i = 0; i < escbufc; i++) /* And output the */
- ckcputc(escbuf[i]); /* sequence. */
- } else if (printing && escbufc > 1) {
- zsoutx(ZMFILE,escbuf,escbufc-1);
- debug(F011,"ESCBUF PRINT 3",escbuf,escbufc);
- }
- } else if (printing && escbufc > 1) {
- zsoutx(ZMFILE,escbuf,escbufc-1);
- debug(F111,"ESCBUF PRINT 4",escbuf,escbufc);
- }
- }
- if (!src) {
- escbufc = 0; /* Clear esc sequence buffer */
- escbuf[0] = NUL;
- }
-#endif /* XPRINT */
- inesc[src] = ES_NORMAL; /* Return to NORMAL. */
- } else if (c == ESC) { /* ESC ... */
- inesc[src] = ES_GOTESC; /* starts over. */
- }
- break;
-
- case ES_STRING: /* Inside a string */
- if (c == ESC) /* ESC may be 1st char of terminator */
- inesc[src] = ES_TERMIN; /* Go see. */
-#ifdef CK_APC
- else if (apcactive) { /* If in APC */
- if (apclength < apcbuflen) { /* and there is room... */
- apcbuf[apclength++] = c; /* deposit this character. */
- } else { /* Buffer overrun */
- apcactive = 0; /* Discard what we got */
- apclength = 0; /* and go back to normal */
- apcbuf[0] = 0; /* Not pretty, but what else */
- inesc[src] = ES_NORMAL; /* can we do? (ST might not come) */
- }
- }
-#endif /* CK_APC */
- break; /* Absorb all other characters. */
-
- case ES_TERMIN: /* Maybe a string terminator */
- if (c == '\\') { /* which must be backslash */
- inesc[src] = ES_NORMAL; /* If so, back to NORMAL */
-#ifdef XPRINT
- if (!src) {
- if (printing && escbufc > 1) { /* If printing... */
- /* Print esc seq buffer */
- zsoutx(ZMFILE,escbuf,escbufc-1);
- debug(F111,"ESCBUF PRINT 5",escbuf,escbufc);
- }
- escbufc = 0; /* Clear escseq buffer */
- escbuf[0] = NUL;
- }
-#endif /* XPRINT */
-#ifdef CK_APC
- if (!src && apcactive) { /* If it was an APC string, */
- debug(F101,"CONNECT APC terminated","",c);
- apcbuf[apclength] = NUL; /* terminate it and then ... */
- return(1);
- }
-#endif /* CK_APC */
- } else { /* It's not a backslash so... */
- inesc[src] = ES_STRING; /* back to string absorption. */
-#ifdef CK_APC
- if (apcactive) { /* In APC string */
- if (apclength+1 < apcbuflen) { /* If enough room */
- apcbuf[apclength++] = ESC; /* deposit the Esc */
- apcbuf[apclength++] = c; /* and this character too. */
- } else { /* Buffer overrun */
- apcactive = 0;
- apclength = 0;
- apcbuf[0] = 0;
- inesc[src] = ES_NORMAL;
- }
- }
-#endif /* CK_APC */
- }
- } /* switch() */
- debug(F111,"chkaes exit inesc",ckitoa(src),inesc[src]);
- return(0);
-}
-#endif /* NOESCSEQ */
-
-VOID
-#ifdef CK_ANSIC
-LOGCHAR(char c)
-#else
-LOGCHAR(c) char c;
-#endif /* CK_ANSIC */
-/* LOGCHAR */ { /* Log character c to session log */
- /* but skip over escape sequences if session log is text */
- if (escseq) {
- if ((sessft == XYFT_T) && (debses == 0) &&
- (inesc[0] != ES_NORMAL || oldesc[0] != ES_NORMAL))
- return;
- }
- logchar(c);
-}
-
-/* C K C P U T C -- C-Kermit CONNECT Put Character to Screen */
-/*
- Output is buffered to avoid slow screen writes on fast connections.
-*/
-static int
-ckcputf() { /* Dump the console output buffer */
- int x = 0;
- if (obc > 0) /* If we have any characters, */
- x = conxo(obc,obuf); /* dump them, */
- obp = obuf; /* reset the pointer */
- obc = 0; /* and the counter. */
- return(x); /* Return conxo's return code */
-}
-
-/*
- NOTE: This is probably the right place for character-set translation,
- rather than down below in the mainline code. ckcputc() would act like
- xpnbyte() in ckcfns.c, and ckcgetc() would act like xgnbyte(). This
- would shield the rest of the code from all the complexities of many-to-one
- and one-to-many conversions, and would allow handling of Kanji and other
- CJK sets along with UTF-8 and the rest.
-*/
-int
-ckcputc(c) int c; {
- int x;
-
- *obp++ = c & 0xff; /* Deposit the character */
- obc++; /* Count it */
- if (ibc == 0 || /* If input buffer about empty */
- obc == OBUFL) { /* or output buffer full */
- debug(F101,"CONNECT CKCPUTC obc","",obc);
- x = conxo(obc,obuf); /* dump the buffer, */
- obp = obuf; /* reset the pointer */
- obc = 0; /* and the counter. */
- return(x); /* Return conxo's return code */
- } else return(0);
-}
-
-/* C K C G E T C -- C-Kermit CONNECT Get Character */
-/*
- Buffered read from communication device.
- Returns the next character, refilling the buffer if necessary.
- On error, returns ttinc's return code (see ttinc() description).
- Dummy argument for compatible calling conventions with ttinc()
- so a pointer to this function can be passed to tn_doop().
-*/
-int
-ckcgetc(dummy) int dummy; {
- int c, n;
-#ifdef CK_SSL
- extern int ssl_active_flag, tls_active_flag;
-#endif /* CK_SSL */
-
-#ifdef CK_ENCRYPTION
- /* No buffering for possibly encrypted connections */
- if (network && IS_TELNET() && TELOPT_ME(TELOPT_AUTHENTICATION))
- return(ttinc(0));
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag)
- return(ttinc(0));
-#endif /* CK_SSL */
-
- if (ibc < 1) { /* Need to refill buffer? */
- ibc = 0; /* Yes, reset count */
- ibp = ibuf; /* and buffer pointer */
- c = ttinc(0); /* Read one character, blocking */
- if (c < 0) { /* If error, return error code */
- return(c);
- } else { /* Otherwise, got one character */
- *ibp++ = c; /* Advance buffer pointer */
- ibc++; /* and count. */
- }
- if ((n = ttchk()) > 0) { /* Any more waiting? */
- if (n > (IBUFL - ibc)) /* Get them all at once. */
- n = IBUFL - ibc; /* Don't overflow buffer */
- if ((n = ttxin(n,(CHAR *)ibp)) > 0) {
- ibc += n; /* Advance counter */
- }
- } else if (n < 0) { /* Error? */
- return(n); /* Return the error code */
- }
- ibp = ibuf; /* Point to beginning of buffer */
- }
- c = *ibp++ & 0xff; /* Get next character from buffer */
- ibc--; /* Reduce buffer count */
- /* debug(F000,"CKCGETC","",c); */
- return(c); /* Return the character */
-}
-
-/*
- Keyboard handling, buffered for speed, which is needed when C-Kermit is
- in CONNECT mode between two other computers that are transferring data.
-*/
-static char *kbp; /* Keyboard input buffer pointer */
-static int kbc; /* Keyboard input buffer count */
-
-#ifdef CK_SMALL /* Keyboard input buffer length */
-#define KBUFL 32 /* Small for PDP-11 UNIX */
-#else
-#define KBUFL 257 /* Regular kernel size for others */
-#endif /* CK_SMALL */
-
-#ifdef DYNAMIC
-static char *kbuf = NULL;
-#else
-static char kbuf[KBUFL];
-#endif /* DYNAMIC */
-
-/* Macro for reading keystrokes. */
-
-#define CONGKS() (((--kbc)>=0) ? ((int)(*kbp++) & 0377) : kbget())
-
-/*
- Note that we call read() directly here, normally a no-no, but in this case
- we know it's UNIX and we're only doing what coninc(0) would have done,
- except we're reading a block of characters rather than just one. There is,
- at present, no conxin() analog to ttxin() for chunk reads, and instituting
- one would only add function-call overhead as it would only be a wrapper for
- a read() call anyway.
-
- Another note: We stick in this read() till the user types something.
- But we know they already did, since select() said so. Therefore something
- would need to be mighty wrong before we get stuck here.
-*/
-static int /* Keyboard buffer filler */
-kbget() {
-#ifdef EINTR
- int tries = 10; /* If read() is interrupted, */
- int ok = 0;
- while (tries-- > 0) { /* try a few times... */
-#endif /* EINTR */
- kbc = conchk(); /* How many chars waiting? */
- debug(F101,"kbget kbc","",kbc);
- if (kbc < 1)
- kbc = 1; /* If none or dunno, wait for one. */
- else if (kbc > KBUFL) /* If too many, */
- kbc = KBUFL; /* only read this many. */
- if ((kbc = read(0, kbuf, kbc)) < 1) { /* Now read it/them. */
- debug(F101,"CONNECT kbget errno","",errno); /* Got an error. */
-#ifdef EINTR
- if (errno == EINTR) /* Interrupted system call. */
- continue; /* Try again, up to limit. */
- else /* Something else. */
-#endif /* EINTR */
- return(-1); /* Pass along read() error. */
- }
-#ifdef EINTR
- else { ok = 1; break; }
- }
- if (!ok) return(-1);
-#endif /* EINTR */
- kbp = kbuf; /* Adjust buffer pointer, */
- kbc--; /* count, */
- return((int)(*kbp++) & 0377); /* and return first character. */
-}
-
-#ifdef BEBOX
-/*
- * CreateSocketPair --
- *
- * This procedure creates a connected socket pair
- *
- * Results:
- * 0 if OK, the error if not OK.
- *
- * Side effects:
- * None
- */
-int
-socketpair(int *pair) {
- int servsock;
- int val;
- struct sockaddr_in serv_addr, cli_addr;
- extern char myipaddr[];
-
- debug(F110,"socketpair",myipaddr,0);
-
- if (myipaddr[0] == 0)
- getlocalipaddr();
-
- servsock = socket(AF_INET, SOCK_STREAM, 0);
- if (servsock == 0) {
- return h_errno;
- }
- debug(F111,"socketpair","socket",servsock);
-
- memset(&serv_addr, 0, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- serv_addr.sin_port = htons(0);
-
- val = sizeof(serv_addr);
- if (bind(servsock, (struct sockaddr *) &serv_addr, val) < 0) {
- closesocket(servsock);
- return h_errno;
- }
- debug(F111,"socketpair","bind",0);
-
- listen(servsock, 1);
- debug(F111,"socketpair","listen",0);
-
- if (getsockname(servsock, (struct sockaddr *) &serv_addr, &val) < 0) {
- closesocket(servsock);
- return h_errno;
- }
- debug(F111,"socketpair","getsockname",0);
-
- pair[0] = socket(AF_INET, SOCK_STREAM, 0);
- if (pair[0] == 0) {
- closesocket(servsock);
- return h_errno;
- }
- debug(F111,"socketpair","socket",pair[0]);
-
- memset(&cli_addr, 0, sizeof(cli_addr));
- cli_addr.sin_family = AF_INET;
- cli_addr.sin_addr.s_addr = inet_addr(myipaddr[0]?myipaddr:"127.0.0.1");
- cli_addr.sin_port = serv_addr.sin_port;
-
- if (connect(pair[0],(struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0) {
- closesocket(pair[0]);
- closesocket(servsock);
- return h_errno;
- }
- debug(F111,"socketpair","connect",0);
-
- pair[1] = accept(servsock, (struct sockaddr *) &serv_addr, &val);
- if (pair[1] == 0) {
- closesocket(pair[0]);
- closesocket(servsock);
- return h_errno;
- }
- debug(F111,"socketpair","accept",pair[1]);
-
- closesocket(servsock);
- debug(F111,"socketpair","closesocket",0);
- return 0;
-}
-
-long
-kbdread(void * param) {
- int sock = (int) param;
- char ch;
- int rc = 0;
-
- debug(F111,"kbdread","sock",sock);
-
- while (rc >= 0) {
- rc = read(fileno(stdin), &ch, 1); /* Read a character. */
- if (rc > 0) {
- rc = send(sock,&ch,1,0);
- /* debug(F000,"kbdread","send()",ch); */
- printf("\r\ngot: %c rc = %d\r\n",ch,rc);
- } else
- msleep(100);
- }
- debug(F110,"kbdread","terminating",0);
- return(rc);
-}
-#endif /* BEBOX */
-
-#ifdef CKLEARN
-static VOID
-learnchar(c) int c; { /* Learned script keyboard character */
- int cc;
- char xbuf[8];
-
- if (!learning || !learnfp)
- return;
-
- switch (learnst) { /* Learn state... */
- case 0: /* Neutral */
- case 1: /* Net */
- if (learnbc > 0) { /* Have net characters? */
- char buf[LEARNBUFSIZ];
- int i, j, n;
- ULONG t;
-
- t = (ULONG) time(0); /* Calculate INPUT timeout */
- j = t - learnt1;
- j += (j / 4) > 0 ? (j / 4) : 1; /* Add some slop */
- if (j < 2) j = 2; /* 2 seconds minimum */
-
- fputs("\nINPUT ",learnfp); /* Give INPUT command for them */
- fputs(ckitoa(j),learnfp);
- fputs(" {",learnfp);
- learnt1 = t;
-
- n = LEARNBUFSIZ;
- if (learnbc < LEARNBUFSIZ) { /* Circular buffer */
- n = learnbc; /* hasn't wrapped yet. */
- learnbp = 0;
- }
- j = 0; /* Copy to linear buffer */
- for (i = 0; i < n; i++) { /* Number of chars in circular buf */
-
- cc = learnbuf[(learnbp + i) % LEARNBUFSIZ];
-
- /* Later account for prompts that end with a newline? */
-
- if (cc == CR && j > 0) {
- if (buf[j-1] != LF)
- j = 0;
- }
- buf[j++] = cc;
- }
- for (i = 0; i < j; i++) { /* Now copy out the buffer */
- cc = buf[i]; /* interpreting control chars */
- if (cc == 0) { /* We don't INPUT NULs */
- continue;
- } else if (cc < SP || /* Controls need quoting */
- (cc > 126 && cc < 160)) {
- ckmakmsg(xbuf,8,"\\{",ckitoa((int)cc),"}",NULL);
- fputs(xbuf,learnfp);
- } else { /* Plain character */
- putc(cc,learnfp);
- }
- }
- fputs("}\nIF FAIL STOP 1 INPUT timeout",learnfp);
- learnbc = 0;
- }
- learnbp = 0;
- fputs("\nPAUSE 1\nOUTPUT ",learnfp); /* Emit OUTPUT and fall thru */
-
- case 2: /* Already in Keyboard state */
- if (c == 0) {
- fputs("\\N",learnfp);
- } else if (c == -7) {
- fputs("\\B",learnfp);
- } else if (c == -8) {
- fputs("\\L",learnfp);
- } else if (c < SP || (c > 126 && c < 160)) {
- ckmakmsg(xbuf,8,"\\{",ckitoa((int)c),"}",NULL);
- fputs(xbuf,learnfp);
- } else {
- putc(c,learnfp);
- }
- }
-}
-#endif /* CKLEARN */
-
-static int printbar = 0;
-
-#define OUTXBUFSIZ 15
-static CHAR inxbuf[OUTXBUFSIZ+1]; /* Host-to-screen expansion buffer */
-static int inxcount = 0; /* and count */
-static CHAR outxbuf[OUTXBUFSIZ+1]; /* Keyboard-to-host expansion buf */
-static int outxcount = 0; /* and count */
-
-int
-conect() {
- int rc = 0; /* Return code: 0 = fail, 1 = OK */
- int i, x = 0, prev = -1; /* Reason code in cx_status */
-#ifdef CKLEARN
- int crflag = 0;
-#endif /* CKLEARN */
- register int c = -1, c2, csave; /* Characters */
-#ifdef TNCODE
- int tx; /* For Telnet negotiations */
-#endif /* TNCODE */
- int apcrc = 0; /* For APC and transparent print */
- int n, kbin, scrnout; /* select() items... */
- fd_set in, out, err; /* File descriptor sets */
- int gotnet = 0; /* Flag for net ready to read */
- int gotkbd = 0; /* Flag for keyboard ready to read */
- int oldprt = 0; /* Used with printing */
- int msgflg = 0;
- char cbuf[2]; /* Ditto */
-
-#ifdef BEBOX
- int tid = 0; /* Thread ID */
- int pair[2]; /* Socket Pair */
- CHAR ch;
- CHAR buf[64];
-#endif /* BEBOX */
-
- cx_status = CSX_INTERNAL;
- debok = 1;
-
-#ifdef BEBOX
- {
- /* Create a socket pair to be used for the keyboard input */
- if (socketpair(pair)) {
- debug(F110,"conect","unable to create socket pair",0);
- return(-1);
- }
- debug(F111,"connect","socket pair[0]",pair[0]);
- debug(F111,"connect","socket pair[1]",pair[1]);
-
- /* Assign one end of the socket to kbin */
- kbin = pair[0];
- tid = spawn_thread(kbdread,
- "Kbd to Socket Pair",
- B_NORMAL_PRIORITY,
- (void *)pair[1]
- );
- resume_thread(tid);
- debug(F110,"connect","tid",tid);
- }
-#else /* BEBOX */
- kbin = fileno(stdin); /* stdin file descriptor */
-#endif /* BEBOX */
-
- scrnout = fileno(stdout); /* stdout file descriptor */
-
-#ifdef CK_TRIGGER
- makestr(&triggerval,NULL); /* Reset trigger */
-#endif /* CK_TRIGGER */
-
-#ifdef XPRINT
- escbufc = 0; /* Reset esc-sequence buffer */
- escbuf[0] = NUL;
-#endif /* XPRINT */
- cbuf[1] = NUL;
-
- ttimoff(); /* Turn off any timer interrupts */
- if (!local) { /* Be sure we're not in remote mode */
-#ifdef NETCONN
-#ifdef NEWFTP
- if (ftpisconnected())
- printf("Sorry, you can't CONNECT to an FTP server\n");
- else
-#endif /* NEWFTP */
- printf("Sorry, you must SET LINE or SET HOST first\n");
-#else
- printf("Sorry, you must SET LINE first\n");
-#endif /* NETCONN */
- return(0);
- }
- if (speed < 0L && network == 0 && ttfdflg == 0) {
- printf("Sorry, you must SET SPEED first\n");
- return(0);
- }
-#ifdef TCPSOCKET
- if (network && !ttpipe && (nettype != NET_TCPB && nettype != NET_PTY)) {
- printf("Sorry, network type not supported\n");
- return(0);
- }
-#endif /* TCPSOCKET */
-
-#ifdef DYNAMIC
- if (!ibuf) {
- if (!(ibuf = malloc(IBUFL+1))) { /* Allocate input line buffer */
- printf("Sorry, CONNECT input buffer can't be allocated\n");
- return(0);
- } else {
- ibp = ibuf;
- ibc = 0;
- }
- }
- if (!obuf) {
- if (!(obuf = malloc(OBUFL+1))) { /* Allocate output line buffer */
- printf("Sorry, CONNECT output buffer can't be allocated\n");
- return(0);
- } else {
- obp = obuf;
- obc = 0;
- }
- }
- if (!kbuf) {
- if (!(kbuf = malloc(KBUFL+1))) { /* Allocate keyboard input buffer */
- printf("Sorry, CONNECT keyboard buffer can't be allocated\n");
- return(0);
- }
- }
- if (!temp) {
- if (!(temp = malloc(TMPLEN+1))) { /* Allocate temporary buffer */
- printf("Sorry, CONNECT temporary buffer can't be allocated\n");
- return(0);
- }
- }
-#else
- obp = obuf;
- obc = 0;
-#endif /* DYNAMIC */
-
- kbp = kbuf; /* Always clear these. */
- *kbp = NUL; /* No need to preserve them between */
- kbc = 0; /* CONNECT sessions. */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"CONNECT conect entry ttyfd","",ttyfd);
- debug(F101,"CONNECT conect entry ibc","",ibc);
- debug(F101,"CONNECT conect entry obc","",obc);
- debug(F101,"CONNECT conect entry kbc","",kbc);
-#ifdef CK_TRIGGER
- debug(F110,"CONNECT conect trigger",tt_trigger[0],0);
-#endif /* CK_TRIGGER */
- if (ttyfd > -1) {
- n = ttchk();
- debug(F101,"CONNECT conect entry ttchk","",n);
- }
- }
-#endif /* DEBUG */
-
- if (ttyfd < 0) { /* If communication device not open */
-#ifdef TTLEBUF
- int n = le_inbuf();
- debug(F111,"CONNECT le_inbuf()","ttyfd < 0",n);
- if (n > 0) {
- while (n--) {
- CHAR ch;
- le_getchar(&ch);
- conoc(ch);
- }
- return(0);
- }
-#endif /* TTLEBUF */
-
- debug(F101,"CONNECT ttnproto","",ttnproto);
- debug(F111,"CONNECT opening",ttname,0); /* Open it now */
- if (ttopen(ttname,
- &local,
- network ? -nettype : mdmtyp,
- 0
- ) < 0) {
- ckmakmsg(temp,TMPLEN,"Sorry, can't open ",ttname,NULL,NULL);
- perror(temp);
- debug(F110,"CONNECT open failure",ttname,0);
- return(0);
- }
-
-#ifdef IKS_OPTION
- /* If peer is in Kermit server mode, return now. */
- if (TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- cx_status = CSX_IKSD;
- return(0);
- }
-#endif /* IKS_OPTION */
- }
- dohangup = 0; /* Hangup not requested yet */
-
- msgflg = !quiet
-#ifdef CK_APC
- && !apcactive
-#endif /* CK_APC */
- ;
-
- if (msgflg) {
-#ifdef NETCONN
- if (network) {
-#ifdef CK_ENCRYPTION
- extern int me_encrypt, u_encrypt;
- if (ck_tn_encrypting() && ck_tn_decrypting())
- printf("SECURE connection to host %s",ttname);
- else
-#endif /* CK_ENCRYPTION */
- if (ttpipe || ttpty)
- printf("Connecting via command \"%s\"",ttname);
- else
- printf("Connecting to host %s",ttname);
- } else {
-#endif /* NETCONN */
- printf("Connecting to %s",ttname);
- if (speed > -1L) printf(", speed %ld",speed);
-#ifdef NETCONN
- }
-#endif /* NETCONN */
- if (tt_escape) {
- printf("\r\n");
- shoesc(escape);
- printf("Type the escape character followed by C to get back,\r\n");
- printf("or followed by ? to see other options.\r\n");
- } else {
- printf(".\r\n\nESCAPE CHARACTER IS DISABLED\r\n\n");
- }
- if (seslog) {
- extern int slogts;
- char * s = "";
- switch (sessft) {
- case XYFT_D:
- s = "debug"; break;
- case XYFT_T:
- s = slogts ? "timestamped-text" : "text"; break;
- default:
- s = "binary";
- }
- printf("Session Log: %s, %s (%d) \r\n",sesfil,s,sessft);
- }
- if (debses) printf("Debugging Display...)\r\n");
- }
-
-/* Condition console terminal and communication line */
-
- if (conbin((char)escape) < 0) {
- printf("Sorry, can't condition console terminal\n");
- fflush(stdout);
- return(0);
- }
- debug(F101,"CONNECT cmask","",cmask);
- debug(F101,"CONNECT cmdmsk","",cmdmsk);
- debug(F101,"CONNECT speed before ttvt","",speed);
- if ((n = ttvt(speed,flow)) < 0) { /* Enter "virtual terminal" mode */
- if (!network) {
- debug(F101,"CONNECT ttvt","",n);
- tthang(); /* Hang up and close the device. */
- ttclos(0);
- dologend();
- if (ttopen(ttname, /* Open it again... */
- &local,
- network ? -nettype : mdmtyp,
- 0
- ) < 0) {
- cx_status = CSX_INTERNAL;
- ckmakmsg(temp,TMPLEN,"Sorry, can't reopen ",ttname,NULL,NULL);
- perror(temp);
- return(0);
- }
-#ifdef IKS_OPTION
- if (TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- cx_status = CSX_IKSD;
- return(0);
- }
-#endif /* IKS_OPTION */
-
- if (ttvt(speed,flow) < 0) { /* Try virtual terminal mode again. */
- conres(); /* Failure this time is fatal. */
- printf("Sorry, Can't condition communication line\n");
- cx_status = CSX_INTERNAL;
- return(0);
- }
- }
- }
- debug(F101,"CONNECT ttvt ok, escape","",escape);
-
- /* Despite ttvt() this is still needed in HP-UX */
- /* because of the HP-9000 <RESET> key.*/
-
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
-
- debug(F101,"CONNECT carrier-watch","",carrier);
- if ((!network
-#ifdef TN_COMPORT
- || istncomport()
-#endif /* TN_COMPORT */
- ) && (carrier != CAR_OFF)) {
- int x;
- x = ttgmdm();
- debug(F100,"CONNECT ttgmdm","",x);
- if ((x > -1) && !(x & BM_DCD)) {
-#ifndef NOHINTS
- extern int hints;
-#endif /* NOHINTS */
- debug(F100,"CONNECT ttgmdm CD test fails","",x);
- conres();
- printf("?Carrier required but not detected.\n");
-#ifndef NOHINTS
- cx_status = CSX_CARRIER;
- if (!hints)
- return(0);
- printf("***********************************\n");
- printf(" Hint: To CONNECT to a serial device that\n");
- printf(" is not presenting the Carrier Detect signal,\n");
- printf(" first tell C-Kermit to:\n\n");
- printf(" SET CARRIER-WATCH OFF\n\n");
- printf("***********************************\n\n");
-#endif /* NOHINTS */
- return(0);
- }
- debug(F100,"CONNECT ttgmdm ok","",0);
- }
-
- /* Now we are connected. */
-
- if (msgflg || printbar)
- printf("----------------------------------------------------\r\n");
- fflush(stdout);
-
-#ifndef NOCSETS
-/* Set up character set translations */
-
- unicode = 0; /* Assume Unicode won't be involved */
- tcs = 0; /* "Transfer" or "Other" charset */
- sxo = rxo = NULL; /* Initialize byte-to-byte functions */
- sxi = rxi = NULL;
-
- if (tcsr != tcsl) { /* Remote and local sets differ... */
-#ifdef UNICODE
- if (tcsr == FC_UTF8 || /* Remote charset is UTF-8 */
- tcsl == FC_UTF8) { /* or local one is. */
- xuf = xl_ufc[tcsl]; /* Incoming Unicode to local */
- if (xuf || tcsl == FC_UTF8) {
- tcs = (tcsr == FC_UTF8) ? tcsl : tcsr; /* The "other" set */
- xfu = xl_fcu[tcs]; /* Local byte to remote Unicode */
- if (xfu)
- unicode = (tcsr == FC_UTF8) ? 1 : 2;
- }
- tcssize = fcsinfo[tcs].size; /* Size of other character set. */
- } else {
-#endif /* UNICODE */
- tcs = gettcs(tcsr,tcsl); /* Get intermediate set. */
- sxo = xls[tcs][tcsl]; /* translation function */
- rxo = xlr[tcs][tcsr]; /* pointers for output functions */
- sxi = xls[tcs][tcsr]; /* and for input functions. */
- rxi = xlr[tcs][tcsl];
-#ifdef UNICODE
- }
-#endif /* UNICODE */
- }
-/*
- This is to prevent use of zmstuff() and zdstuff() by translation functions.
- They only work with disk i/o, not with communication i/o. Luckily Russian
- translation functions don't do any stuffing...
-*/
- langsv = language;
-#ifndef NOCYRIL
- if (language != L_RUSSIAN)
-#endif /* NOCYRIL */
- language = L_USASCII;
-
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"CONNECT tcs","",tcs);
- debug(F101,"CONNECT tcsl","",tcsl);
- debug(F101,"CONNECT tcsr","",tcsr);
- debug(F101,"CONNECT fcsinfo[tcsl].size","",fcsinfo[tcsl].size);
- debug(F101,"CONNECT fcsinfo[tcsr].size","",fcsinfo[tcsr].size);
- debug(F101,"CONNECT unicode","",unicode);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
-
-#ifdef CK_XYZ
-#ifndef XYZ_INTERNAL
- {
- extern int binary; /* See about ZMODEM autodownloads */
- char * s;
- s = binary ? ptab[PROTO_Z].p_b_rcmd : ptab[PROTO_Z].p_t_rcmd;
- if (!s) s = "";
- zmdlok = (*s != NUL); /* OK if we have external commands */
- }
-#endif /* XYZ_INTERNAL */
-#endif /* CK_XYZ */
-
-#ifndef NOESCSEQ
-/*
- We need to activate the escape-sequence recognition feature when:
- (a) translation is elected, AND
- (b) the local and/or remote set is a 7-bit set other than US ASCII;
- Or:
- SET SESSION-LOG is TEXT (so we can strip escape sequences out of the log);
- Or:
- SET TERMINAL APC is not OFF (handled in the next statement).
-*/
- escseq = (tcs != TC_TRANSP) && /* Not transparent */
- (fcsinfo[tcsl].size == 128 || fcsinfo[tcsr].size == 128) && /* 7 bits */
- (fcsinfo[tcsl].code != FC_USASCII); /* But not ASCII */
-#endif /* NOESCSEQ */
-#endif /* NOCSETS */
-
-#ifndef NOESCSEQ
- if (!escseq) { /* 2009/10/22 */
- if (seslog && !sessft)
- escseq = 1;
- }
-#ifdef CK_APC
- escseq = escseq || (apcstatus & APC_ON);
- apcactive = 0; /* An APC command is not active */
- apclength = 0; /* ... */
-#endif /* CK_APC */
-#ifdef XPRINT
- escseq |= tt_print;
-#endif /* XPRINT */
- /* Initial state of recognizer */
- inesc[0] = ES_NORMAL; /* Remote to screen */
- inesc[1] = ES_NORMAL; /* Keyboard to remote */
- debug(F101,"CONNECT escseq","",escseq);
-#endif /* NOESCSEQ */
-
- if (ttyfd > -1) { /* (just in case...) */
- what = W_CONNECT; /* Keep track of what we're doing */
- active = 1;
- }
-#ifdef CKLEARN
- if (learning) { /* Learned script active... */
- learnbp = 0; /* INPUT buffer pointer */
- learnbc = 0; /* INPUT buffer count */
- learnst = 0; /* State (0 = neutral, none) */
- learnt1 = (ULONG) time(0);
- }
-#endif /* CKLEARN */
-
-#ifdef CKTIDLE
- idlelimit = tt_idlelimit;
-#endif /* CKTIDLE */
-
- while (active) { /* Big loop... */
- debug(F100,"CONNECT top of loop","",0);
- FD_ZERO(&in); /* Clear select() structs */
- FD_ZERO(&out);
- FD_ZERO(&err);
- gotkbd = 0;
- gotnet = ttpeek(); /* Something sitting in ckutio buf */
- debug(F101,"CONNECT ttpeek","",gotnet);
-
- if (
-#ifndef NOSETKEY
- !kmptr /* Check for key macro active */
-#else
- 1
-#endif /* NOSETKEY */
- ) {
- if (obc) { /* No key macro - set up for select */
- FD_SET(ttyfd, &out); /* Have stuff to send to net */
- } else {
- FD_SET(kbin, &in); /* Need to read stuff from keyboard */
- }
-#ifdef BEBOX
- if (!(ibc || gotnet > 0))
- FD_SET(ttyfd, &in); /* Need to read stuff from net */
-#else /* BEBOX */
- if (ibc || gotnet > 0) {
- FD_SET(scrnout, &out); /* Have stuff to put on screen */
- } else {
- FD_SET(ttyfd, &in); /* Need to read stuff from net */
- }
-#endif /* BEBOX */
- FD_SET(ttyfd, &err);
-#ifdef CK_FORWARD_X
- fwdx_init_fd_set(&in);
-#endif /* CK_FORWARD_X */
-
- /* Wait till the first one of the above is ready for i/o */
- /* or TERM IDLE-SEND is active and we time out. */
-
- errno = 0;
-#ifdef CKTIDLE
- /* This really could be moved out of the loop... */
- if (idlelimit) { /* Idle timeout set */
- struct timeval tv;
- if (idlelimit > 0) { /* Positive = sec */
- tv.tv_sec = (long) idlelimit;
- tv.tv_usec = 0L;
- } else { /* Negative = millisec */
- long u = (0 - idlelimit);
- tv.tv_sec = u / 1000L;
- tv.tv_usec = ((u % 1000L) * 1000L);
- }
-#ifdef INTSELECT
- c = select(FD_SETSIZE,(int *)&in,(int *)&out,(int *)&err, &tv);
-#else
- c = select(FD_SETSIZE, &in, &out, &err, &tv);
-#endif /* INTSELECT */
- } else
-#endif /* CKTIDLE */
-#ifdef INTSELECT
- c = select(FD_SETSIZE, (int *)&in, (int *)&out, (int *)&err, 0);
-#else
- c = select(FD_SETSIZE, &in, &out, &err, 0);
-#endif /* INTSELECT */
- if (c < 1) {
-#ifdef CKTIDLE
- if (c == 0) { /* Timeout */
- debug(F101,"CONNECT select() timeout","",tt_idleact);
- switch (tt_idleact) {
- case IDLE_HANG: { /* Hang up */
- int x = 0;
-#ifndef NODIAL
- if (dialmhu)
- x = mdmhup();
- if (x < 1)
-#endif /* NODIAL */
- tthang(); /* fall thru deliberately... */
- }
- case IDLE_RET: /* Return to command mode */
- cx_status = CSX_IDLE;
- active = 0;
- continue;
- case IDLE_OUT: /* OUTPUT a string */
- if (tt_idlestr) {
- int len = strlen(tt_idlestr);
- if (len > 0)
- ttol((CHAR *)tt_idlestr,len);
- else
- ttoc(NUL); /* No string, send a NUL */
- } else
- ttoc(NUL); /* No string, send a NUL */
- continue;
- case IDLE_EXIT: /* Exit from Kermit */
- doexit(GOOD_EXIT,xitsta);
-#ifdef TNCODE
- case IDLE_TAYT: /* Send Telnet Are You There? */
- if (network && IS_TELNET()) {
- tnopt[0] = (CHAR) IAC;
- tnopt[1] = (CHAR) TN_AYT;
- tnopt[2] = NUL;
- if (ttol((CHAR *)tnopt,2) < 0)
- active = 0;
- }
- continue;
-
- case IDLE_TNOP: /* Send Telnet NOP */
- if (network && IS_TELNET()) {
- tnopt[0] = (CHAR) IAC;
- tnopt[1] = (CHAR) TN_NOP;
- tnopt[2] = NUL;
- if (ttol((CHAR *)tnopt,2) < 0)
- active = 0;
- }
- continue;
-#endif /* TNCODE */
- }
- }
-#endif /* CKTIDLE */
-
- debug(F101,"CONNECT select() errno","",errno);
- /* A too-big first arg to select() gets EBADF */
-#ifdef EINTR
- if (c == -1) {
- if (errno == EINTR) {
- continue;
- }
- }
-#endif /* EINTR */
- sleep(1);
- continue;
- }
-#ifndef BEBOX
-#ifdef DEBUG
- if (FD_ISSET(scrnout, &out)) {
- debug(F100,"CONNECT SELECT scrnout","",0);
- }
-#endif /* DEBUG */
-#endif /* BEBOX */
-
-#ifdef CK_FORWARD_X
- fwdx_check_sockets(&in);
-#endif /* CK_FORWARD_X */
-
- if (FD_ISSET(ttyfd, &in)) { /* Read from net? */
- debug(F110,"CONNECT SELECT ttyfd","in",0);
- FD_CLR(ttyfd, &in);
- gotnet = 1; /* Net is ready */
- }
- if (FD_ISSET(kbin, &in)) { /* Read from keyboard? */
- debug(F100,"CONNECT SELECT kbin","",0);
- FD_CLR(kbin, &in);
- gotkbd = 1; /* Keyboard is ready */
- }
- if (FD_ISSET(ttyfd, &err)) {
- debug(F110,"CONNECT SELECT ttyfd","err",0);
- FD_CLR(ttyfd, &err);
-#ifdef NETPTY
-#ifdef HAVE_PTYTRAP
- /* Special handling for HP-UX pty i/o */
- if (ttpty) {
- if (pty_trap_handler(ttyfd) > 0) {
- ttclos(0);
- goto conret1;
- }
- continue;
- }
-#endif /* HAVE_PTYTRAP */
-#endif /* NETPTY */
- gotnet = 1; /* Net is ready (don't set if pty) */
- }
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"CONNECT gotkbd","",gotkbd);
- debug(F101,"CONNECT kbc","",kbc);
-#ifdef COMMENT
-#ifndef NOSETKEY
- debug(F101,"CONNECT kmptr","",kmptr);
-#endif /* NOSETKEY */
-#endif /* COMMENT */
- }
-#endif /* DEBUG */
-
- while (gotkbd || kbc > 0 /* If we have keyboard chars */
-#ifndef NOSETKEY
- || kmptr
-#endif /* NOSETKEY */
- ) {
-#ifndef NOSETKEY
- if (kmptr) { /* Have current macro? */
- debug(F100,"CONNECT kmptr non NULL","",0);
- if ((c = (CHAR) *kmptr++) == NUL) { /* Get char from it */
- debug(F100,"CONNECT macro empty, continuing","",0);
- kmptr = NULL; /* If no more chars, */
- continue; /* Reset pointer and continue */
- }
- debug(F000,"CONNECT char from macro","",c);
- } else { /* No macro... */
-#endif /* NOSETKEY */
-#ifdef BEBOX
- {
- int rc = 0;
- if ((rc = recv(kbin,buf,1,0)) > 0)
- c = buf[0];
- else
- c = -1;
- debug(F111,"recv","rc",rc);
- printf("\r\nrecv: %c rc=%d\r\n",buf[0],rc);
- }
-#else /* BEBOX */
- c = CONGKS(); /* Yes, read from keyboard */
-#endif /* BEBOX */
- gotkbd = 0; /* Turn off select() result flag */
-#ifndef NOSETKEY
- }
-#endif /* NOSETKEY */
- if (c == -1) {
-#ifdef EINTR
- if (errno == EINTR)
- continue;
-#endif /* EINTR */
- cx_status = CSX_IOERROR;
- conoc(BEL);
- goto conret0;
- }
- c &= cmdmsk; /* Do any requested masking */
-
-#ifndef NOSETKEY
-/*
- Note: kmptr is NULL if we got character c from the keyboard, and it is
- not NULL if it came from a macro. In the latter case, we must avoid
- expanding it again.
-*/
- if (!kmptr && macrotab[c]) { /* Macro definition for c? */
- debug(F000,"CONNECT macro key",macrotab[c],c);
- kmptr = macrotab[c]; /* Yes, set up macro pointer */
- continue; /* and restart the loop, */
- } else c = keymap[c]; /* else use single-char keymap */
-#endif /* NOSETKEY */
- if (
-#ifndef NOSETKEY
- !kmptr &&
-#endif /* NOSETKEY */
- (tt_escape && ((c & 0xff) == escape))) { /* Escape char? */
- debug(F000,"CONNECT got escape","",c);
-#ifdef BEBOX
- if (recv(kbin,buf,1,0)>=0)
- c = buf[0];
- else
- c = -1;
-#else /* BEBOX */
- c = CONGKS() & 0x7f; /* Read argument */
-#endif /* BEBOX */
- doesc((char) c); /* Handle it */
- continue; /* Back to loop */
- }
- csave = c; /* Save it before translation */
- /* for local echoing. */
-#ifdef CKLEARN
- crflag = (c == CR); /* Remember if it was CR. */
-#endif /* CKLEARN */
-
-#ifndef NOCSETS
- if (inesc[1] == ES_NORMAL) { /* If not inside escape seq.. */
- /* Translate character sets */
-#ifdef UNICODE
- int x;
- if (unicode == 1) { /* Remote is UTF-8 */
- outxcount = b_to_u((CHAR)c,outxbuf,OUTXBUFSIZ,tcssize);
- outxbuf[outxcount] = NUL;
- } else if (unicode == 2) { /* Local is UTF-8 */
-
- x = u_to_b((CHAR)c);
- if (x < 0)
- continue;
- outxbuf[0] = (unsigned)(x & 0xff);
- outxcount = 1;
- outxbuf[outxcount] = NUL;
- } else {
-#endif /* UNICODE */
- if (sxo) c = (*sxo)((char)c); /* Local-intermediate */
- if (rxo) c = (*rxo)((char)c); /* Intermediate-remote */
- outxbuf[0] = c;
- outxcount = 1;
- outxbuf[outxcount] = NUL;
-#ifdef UNICODE
- }
-#endif /* UNICODE */
- } else {
- outxbuf[0] = c;
- outxcount = 1;
- outxbuf[outxcount] = NUL;
- }
- if (escseq)
- apcrc = chkaes((char)c,1);
-#else /* NOCSETS */
- outxbuf[0] = c;
- outxcount = 1;
- outxbuf[outxcount] = NUL;
-#endif /* NOCSETS */
-
- debug(F111,"OUTXBUF",outxbuf,outxcount);
-
- for (i = 0; i < outxcount; i++) {
- c = outxbuf[i];
-/*
- If Shift-In/Shift-Out is selected and we have a 7-bit connection,
- handle shifting here.
-*/
- if (sosi) { /* Shift-In/Out selected? */
- if (cmask == 0177) { /* In 7-bit environment? */
- if (c & 0200) { /* 8-bit character? */
- if (outshift == 0) { /* If not shifted, */
- ttoc(dopar(SO)); /* shift. */
- outshift = 1;
- }
- } else {
- if (outshift == 1) { /* 7-bit character */
- ttoc(dopar(SI)); /* If shifted, */
- outshift = 0; /* unshift. */
- }
- }
- }
- if (c == SO) outshift = 1; /* User typed SO */
- if (c == SI) outshift = 0; /* User typed SI */
- }
- c &= cmask; /* Apply Kermit-to-host mask now. */
- if (c == '\015') { /* Carriage Return */
- int stuff = -1;
- if (tnlm) { /* TERMINAL NEWLINE ON */
- stuff = LF; /* Stuff LF */
-#ifdef TNCODE
- } else if (network && /* TELNET NEWLINE ON/OFF/RAW */
- IS_TELNET()) {
- switch (!TELOPT_ME(TELOPT_BINARY) ? tn_nlm : tn_b_nlm){
- case TNL_CRLF:
- stuff = LF;
- break;
- case TNL_CRNUL:
- stuff = NUL;
- break;
- }
-#endif /* TNCODE */
- }
- if (stuff > -1) {
- ttoc(dopar('\015')); /* Send CR */
- if (duplex) conoc('\015'); /* Maybe echo CR */
- c = stuff; /* Char to stuff */
- csave = c;
- }
- }
-#ifdef TNCODE
-/* If user types the 0xff character (TELNET IAC), it must be doubled. */
- else /* Not CR */
- if ((dopar((CHAR) c) == IAC) && /* IAC (0xff) */
- network && IS_TELNET()) { /* Send one now */
- ttoc((char)IAC); /* and the other one just below. */
- }
-#endif /* TNCODE */
- /* Send the character */
-
- x = ttoc((char)dopar((CHAR) c));
- if (x > -1) {
-#ifdef CKLEARN
- if (learning) { /* Learned script active */
- if (crflag) { /* User typed CR */
- learnchar(CR); /* Handle CR */
- learnst = 0; /* Shift to Neutral */
- } else {
- learnchar(c); /* Not CR */
- learnst = 2; /* Change state to Keyboard */
- }
- }
-#endif /* CKLEARN */
- if (duplex) { /* If half duplex, must echo */
- if (debses)
- conol(dbchr(csave)); /* the original char */
- else /* not the translated one */
- conoc((char)csave);
- if (seslog) { /* And maybe log it too */
- c2 = csave;
- if (sessft == 0 && csave == '\r')
- c2 = '\n';
- LOGCHAR((char)c2);
- }
- }
- } else {
- perror("\r\nCan't send character");
- cx_status = CSX_IOERROR;
- active = 0;
- break;
- }
- }
- }
- if (FD_ISSET(ttyfd, &out)) {
- FD_CLR(ttyfd, &out);
- }
- while (gotnet > 0 || ibc > 0) {
- gotnet = 0;
- prev = c;
- c = ckcgetc(0); /* Get next character */
- if (c < 0) { /* Failed... */
- ckcputf(); /* Flush CONNECT output buffer */
- if (msgflg) {
- printf("\r\nCommunications disconnect ");
-#ifdef COMMENT
- if (c == -3
-#ifdef ultrix
-/* This happens on Ultrix if there's no carrier */
- && errno != EIO
-#endif /* ultrix */
-#ifdef UTEK
-/* This happens on UTEK if there's no carrier */
- && errno != EWOULDBLOCK
-#endif /* UTEK */
- )
- perror("\r\nCan't read character");
-#endif /* COMMENT */
- }
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
- dologend();
- tthang(); /* Hang up the connection */
- debug(F111,"CONNECT i/o error 1",ck_errstr(),errno);
- cx_status = CSX_HOSTDISC;
- goto conret0;
- }
-#ifdef TNCODE
- tx = 0;
- if ((c == NUL) && network && IS_TELNET()) {
- if (prev == CR) { /* Discard <NUL> of <CR><NUL> if peer */
- if (!TELOPT_U(TELOPT_BINARY)) { /* not in binary mode */
- debug(F111,"CONNECT NUL",ckitoa(prev),c);
- ckcputf(); /* Flush screen output buffer */
- break;
- }
- }
- }
- debug(F111,"CONNECT","c",c);
- debug(F111,"CONNECT","network",network);
- debug(F111,"CONNECT","IS_TELNET",IS_TELNET());
- if ((c == IAC) && network && IS_TELNET()) {
-#ifdef CK_ENCRYPTION
- int x_auth = TELOPT_ME(TELOPT_AUTHENTICATION);
-#else
- int x_auth = 0;
-#endif /* CK_ENCRYPTION */
- int me_bin = TELOPT_ME(TELOPT_BINARY);
- int u_bin = TELOPT_U(TELOPT_BINARY);
- debug(F100,"CONNECT got IAC","",0);
- ckcputf(); /* Dump screen-output buffer */
- if ((tx = tn_doop((CHAR)(c & 0xff),duplex,ckcgetc)) == 0) {
- if (me_bin != TELOPT_ME(TELOPT_BINARY)) {
- me_bin = TELOPT_ME(TELOPT_BINARY);
- } else if (u_bin != TELOPT_U(TELOPT_BINARY)) {
- u_bin = TELOPT_U(TELOPT_BINARY);
-#ifdef CK_ENCRYPTION
-/*
- Here we have to push back any bytes we have read using block reads, so we
- can read them again using single-character reads, so they can be decrypted
- in case there was a switch to encryption in the block. Note that we can't
- handle switches in the encryption state itself this way -- which would be
- nice, since it would eliminate the need for single-character reads. Why?
- Because if a series of characters has already been decrypted that shouldn't
- have been, then (a) it's ruined, and (b) so is the state of the decryption
- machine. Too bad.
-*/
- } else if (TELOPT_ME(TELOPT_AUTHENTICATION) != 0 &&
- TELOPT_ME(TELOPT_AUTHENTICATION) != x_auth
- ) {
- if (ttpushback((CHAR *)ibp,ibc) > -1) {
- ibc = 0;
- ibp = ibuf;
- }
-#endif /* CK_ENCRYPTION */
- }
- continue;
- } else if (tx == -1) { /* I/O error */
- if (msgflg)
- printf("\r\nCommunications disconnect ");
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
- dologend();
- debug(F111,"CONNECT i/o error 2",ck_errstr(),errno);
- cx_status = CSX_IOERROR;
- goto conret0;
- } else if (tx == -2) { /* I/O error */
- if (msgflg)
- printf("\r\nConnection closed by peer");
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
- dologend();
- debug(F111,"CONNECT i/o error 3",ck_errstr(),errno);
- cx_status = CSX_IOERROR;
- goto conret0;
- } else if (tx == -3) { /* I/O error */
- if (msgflg)
- printf("\r\nConnection closed due to telnet policy");
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
- dologend();
- debug(F111,"CONNECT i/o error 4",ck_errstr(),errno);
- cx_status = CSX_IOERROR;
- goto conret0;
- } else if ((tx == 1) && (!duplex)) { /* ECHO change */
- duplex = 1; /* Turn on local echo */
- continue;
- } else if ((tx == 2) && (duplex)) { /* ECHO change */
- duplex = 0;
- continue;
- } else if (tx == 3) { /* Quoted IAC */
- c = parity ? 127 : 255;
- }
-#ifdef IKS_OPTION
- else if (tx == 4) { /* IKS State Change */
- if (TELOPT_SB(TELOPT_KERMIT).kermit.u_start &&
- !tcp_incoming
- ) {
- /* here we need to print a msg that the other */
- /* side is in SERVER mode and that REMOTE */
- /* commands should be used. And CONNECT mode */
- /* should be ended. */
- cx_status = CSX_IKSD;
- active = 0;
- }
- }
-#endif /* IKS_OPTION */
- else if (tx == 6) {
- /* DO LOGOUT was received */
- if (msgflg)
- printf("\r\nRemote Logout ");
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
- debug(F100,"CONNECT Remote Logout","",0);
- cx_status = CSX_TRIGGER;
- goto conret0;
- } else
- continue; /* Negotiation OK, get next char. */
- } else if (parity)
- c &= 0x7f;
-
- /* I'm echoing for the remote */
- if (TELOPT_ME(TELOPT_ECHO) && tn_rem_echo)
- ttoc((char)c);
-#endif /* TNCODE */
-
-#ifdef CKLEARN
- /* Learned script: Record incoming chars if not in Keyboard state */
-
- if (learning && learnst != 2) { /* Learned script active */
- learnbuf[learnbp++] = c; /* Save for INPUT command */
- if (learnbp >= LEARNBUFSIZ) /* in circular buffer */
- learnbp = 0; /* wrapping if at end. */
- learnbc++; /* Count this byte. */
- learnst = 1; /* State is Net. */
- }
-#endif /* CKLEARN */
-
- if (debses) { /* Output character to screen */
- char *s; /* Debugging display... */
- s = dbchr(c); /* Make char into string */
- while (*s) { /* Output each char from string */
- ckcputc(*s);
- if (seslog) /* And maybe log it. */
- LOGCHAR((char)*s);
- s++;
- }
- } else { /* Regular display ... */
- c &= cmask; /* Apply Kermit-to-remote mask */
- if (seslog && sessft) /* If binary session log */
- LOGCHAR((char)c); /* log the character now. */
-#ifndef NOXFER
-#ifdef CK_AUTODL
-/*
- Autodownload. Check for Kermit S packet prior to translation, since that
- can change the packet and make it unrecognizable (as when the terminal
- character set is an ISO 646 one)... Ditto for Zmodem start packet.
-*/
- if (autodl /* Autodownload enabled? */
-#ifdef IKS_OPTION
- || TELOPT_SB(TELOPT_KERMIT).kermit.me_start
-#endif /* IKS_OPTION */
- ) {
- int k = 0;
-
- if (kstartactive || c == stchr /* Kermit S or I packet? */
-#ifdef COMMENT
- || adl_kmode == ADLSTR /* Not used in C-Kermit */
-#endif /* COMMENT */
- )
- k = kstart((CHAR)c);
-#ifdef CK_XYZ
- if (!k && zmdlok) /* Or an "sz" start? */
- k = zstart((CHAR)c);
-#endif /* CK_XYZ */
- if (k) {
- int ksign = 0;
- debug(F101,"CONNECT autodownload k","",k);
- if (k < 0) { /* Minus-Protocol? */
-#ifdef NOSERVER
- goto noserver; /* Need server mode for this */
-#else
- ksign = 1; /* Remember */
- k = 0 - k; /* Convert to actual protocol */
- justone = 1; /* Flag for protocol module */
-#endif /* NOSERVER */
- } else
- justone = 0;
- k--; /* Adjust [kz]start's return value */
- if (k == PROTO_K
-#ifdef CK_XYZ
- || k == PROTO_Z
-#endif /* CK_XYZ */
- ) {
- /* Damage the packet so that it doesn't trigger */
- /* autodownload detection downstream. */
- if (k == PROTO_K) {
- int i, len = strlen((char *)ksbuf);
- for (i = 0; i < len; i++)
- ckcputc(BS);
- }
-#ifdef CK_XYZ
- else {
- int i;
- for (i = 0; i < 3; i++)
- ckcputc(CAN);
- }
-#endif /* CK_XYZ */
-
-#ifndef NOICP
- /* sprintf is safe here (builtin keywords) */
- sprintf(apcbuf,
- "set proto %s, %s, set proto %s",
- ptab[k].p_name,
- ksign ? "server" : "receive",
- ptab[protocol].p_name
- );
- apclength = strlen(apcbuf);
- debug(F111,"CONNECT ksbuf",ksbuf,k);
- debug(F110,"CONNECT autodownload",apcbuf,0);
- apcactive = APC_LOCAL;
- ckcputf(); /* Force screen update */
- cx_status = CSX_APC;
- goto conret1;
-#else
-/*
- Here's another way that doesn't require APC, but then we'll have to change
- all the other CONNECT modules, and then the mainline code that calls them.
-*/
- {
- extern char sstate;
- sstate = ksign ? 'x' : 'v';
- proto();
- }
-#endif /* NOICP */
- }
- }
- }
-#ifdef NOSERVER
- noserver:
-#endif /* NOSERVER */
-
-#endif /* CK_AUTODL */
-#endif /* NOXFER */
- if (sosi) { /* Handle SI/SO */
- if (c == SO) { /* Shift Out */
- inshift = 1;
- continue;
- } else if (c == SI) { /* Shift In */
- inshift = 0;
- continue;
- }
- if (inshift) c |= 0200;
- }
- inxbuf[0] = c; /* In case there is no translation */
- inxcount = 1; /* ... */
-#ifndef NOCSETS
- if (inesc[0] == ES_NORMAL /* If not in an escape sequence */
- && !printing /* and not in transparent print */
- ) { /* Translate character sets */
-#ifdef UNICODE
- int x;
- if (unicode == 1) { /* Remote is UTF-8 */
- x = u_to_b((CHAR)c);
- if (x == -1)
- continue;
- else if (x == -2) { /* LS or PS */
- inxbuf[0] = CR;
- inxbuf[1] = LF;
- inxcount = 2;
- } else if (x == -9) { /* UTF-8 error */
- inxbuf[0] = '?';
- inxbuf[1] = u_to_b2();
- inxcount = 2;
- } else {
- inxbuf[0] = (unsigned)(x & 0xff);
- }
- c = inxbuf[0];
- } else if (unicode == 2) { /* Local is UTF-8 */
- inxcount = b_to_u((CHAR)c,inxbuf,OUTXBUFSIZ,tcssize);
- c = inxbuf[0];
- } else {
-#endif /* UNICODE */
- if (sxi) c = (*sxi)((CHAR)c);
- if (rxi) c = (*rxi)((CHAR)c);
- inxbuf[0] = c;
-#ifdef UNICODE
- }
-#endif /* UNICODE */
- }
-#endif /* NOCSETS */
-
-#ifndef NOESCSEQ
- if (escseq) { /* If handling escape sequences */
- oldprt = printing; /* remember printer state */
- apcrc = chkaes((char)c,0); /* and update escseq state. */
- if (printing && !oldprt) /* If printer was turned on */
- continue; /* don't print final char of escseq */
- }
-#ifdef CK_APC
-/*
- If we are handling APCs, we have several possibilities at this point:
- 1. Ordinary character to be written to the screen.
- 2. An Esc; we can't write it because it might be the beginning of an APC.
- 3. The character following an Esc, in which case we write Esc, then char,
- but only if we have not just entered an APC sequence.
-*/
- if (escseq && (apcstatus & APC_ON)) {
- if (inesc[0] == ES_GOTESC) /* Don't write ESC yet */
- continue;
- else if (oldesc[0] == ES_GOTESC && !apcactive) {
- ckcputc(ESC); /* Write saved ESC */
- if (seslog && !sessft) LOGCHAR((char)ESC);
- } else if (apcrc) { /* We have an APC */
- debug(F111,"CONNECT APC complete",apcbuf,apclength);
- ckcputf(); /* Force screen update */
- cx_status = CSX_APC;
- goto conret1;
- }
- }
-#endif /* CK_APC */
-#endif /* NOESCSEQ */
-
- debug(F111,"INXBUF",inxbuf,inxcount);
- for (i = 0; i < inxcount; i++) { /* Loop thru */
- c = inxbuf[i]; /* input expansion buffer... */
- if (
-#ifdef CK_APC
- !apcactive && /* Don't display APC sequences */
-#endif /* CK_APC */
- !printing /* or transparent print material */
-
- ) {
- c &= cmdmsk; /* Apply command mask. */
-
- /* Handle bare carriage returns and linefeeds */
-
- if (c == CR && tt_crd) { /* SET TERM CR-DISPLA CRLF? */
- ckcputc(c); /* Yes, output CR */
- if (seslog && !sessft) LOGCHAR((char)c);
- c = LF; /* and insert a linefeed */
- }
- if (c == LF && tt_lfd) { /* SET TERM CR-DISPLA CRLF? */
- ckcputc(CR); /* Yes, output CR */
- if (seslog && !sessft) LOGCHAR((char)CR);
- }
-#ifndef NOESCSEQ
- if (dontprint) { /* Do transparent printing. */
- dontprint = 0;
- continue;
- } else
-#endif /* NOESCSEQ */
- ckcputc(c); /* Write character to screen */
- }
- if (seslog && !sessft) { /* Handle session log. */
- LOGCHAR((char)c);
- }
-#ifdef XPRINT
- if (printing && !inesc[0]) {
- /* zchout() can't be used because */
- /* it's buffered differently. */
- cbuf[0] = c;
- zsoutx(ZMFILE,(char *)cbuf,1);
- }
-#endif /* XPRINT */
-
-#ifdef CK_TRIGGER
- /* Check for trigger string */
- if (tt_trigger[0]) {
- int i;
- if ((i = autoexitchk((CHAR)c)) > -1) {
- makestr(&triggerval,tt_trigger[i]);
- ckcputf(); /* Force screen update */
-#ifdef NOSETBUF
- fflush(stdout); /* I mean really force it */
-#endif /* NOSETBUF */
- cx_status = CSX_TRIGGER;
- goto conret1;
- }
- }
-#endif /* CK_TRIGGER */
- }
- }
- }
-#ifndef BEBOX
- if (FD_ISSET(scrnout, &out)) {
- FD_CLR(scrnout, &out);
- }
-#endif /* BEBOX */
- } /* End of big loop */
- conret1: /* Come here to succeed */
- rc = 1;
- conret0: /* Common exit point */
-#ifdef BEBOX
- {
- long ret_val;
- closesocket(pair[0]);
- closesocket(pair[1]);
- x = kill(tid,SIGKILLTHR); /* Kill thread */
- wait_for_thread (tid, &ret_val);
- }
-#endif /* BEBOX */
-
-#ifdef CKLEARN
- if (learning && learnfp)
- fputs("\n",learnfp);
-#endif /* CKLEARN */
-
- conres();
- if (dohangup > 0) {
-#ifdef NETCONN
- if (network
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_COMPORT)
-#endif /* TNCODE */
- )
- ttclos(0);
-#endif /* NETCONN */
-
-#ifndef COMMENT
-/*
- This is bad because if they said SET MODEM HANGUP-METHOD MODEM-COMMAND,
- they mean it -- we shouldn't fall back on tthang() if mdmhup() fails,
- because maybe they have some special kind of connection. On the other
- hand, making this change prevents dialing from working at all in some
- cases. Further study needed.
-*/
-#ifndef NODIAL
- if (dohangup > 1) /* User asked for it */
- if (mdmhup() < 1) /* Maybe hang up via modem */
-#endif /* NODIAL */
- tthang(); /* And make sure we don't hang up */
-#else
- if (!network) { /* Serial connection. */
-#ifndef NODIAL
- if (dialmhu) /* Hang up the way they said to. */
- mdmhup();
- else
-#endif /* NODIAL */
- tthang();
- }
-#endif /* COMMENT */
- dologend();
- dohangup = 0; /* again unless requested again. */
- }
- if (quitnow) /* Exit now if requested. */
- doexit(GOOD_EXIT,xitsta);
- if (msgflg
-#ifdef CK_APC
- && !apcactive
-#endif /* CK_APC */
- )
- printf("(Back at %s)", *myhost ? myhost : "local UNIX system");
-#ifdef CK_APC
- if (!apcactive)
-#endif /* CK_APC */
- printf("\n");
- what = W_NOTHING; /* So console modes set right. */
-#ifndef NOCSETS
- language = langsv; /* Restore language */
-#endif /* NOCSETS */
-#ifdef CK_APC
- debug(F101,"CONNECT exit apcactive","",apcactive);
- debug(F101,"CONNECT exit justone","",justone);
-#endif /* CK_APC */
- if (msgflg) {
-#ifdef CK_APC
- if (apcactive == APC_LOCAL)
- printf("\n");
-#endif /* CK_APC */
- printf("----------------------------------------------------\n");
- printbar = 1;
- } else
- printbar = 0;
- fflush(stdout);
- return(rc);
-}
-
-/* H C O N N E -- Give help message for connect. */
-
-#define CXM_SER 1 /* Serial connections only */
-#define CXM_NET 2 /* Network only (but not Telnet) */
-#define CXM_TEL 4 /* Telnet only */
-
-static struct hmsgtab {
- char * hmsg;
- int hflags;
-} hlpmsg[] = {
- {" ? or H for this message", 0},
- {" 0 (zero) to send the NUL (0) character", 0},
- {" B to send a BREAK signal (0.275sec)", CXM_SER},
-#ifdef NETCONN
- {" B to send a network BREAK", CXM_NET},
- {" B to send a Telnet BREAK", CXM_TEL},
-#endif /* NETCONN */
-#ifdef CK_LBRK
- {" L to send a Long BREAK (1.5sec)", CXM_SER},
-#endif /* CK_LBRK */
-#ifdef NETCONN
- {" I to send a network interrupt packet", CXM_NET},
- {" I to send a Telnet Interrupt request", CXM_TEL},
-#ifdef TNCODE
- {" A to send Telnet Are-You-There?", CXM_TEL},
-#endif /* TNCODE */
-#endif /* NETCONN */
- {" U to hangup and close the connection", 0},
- {" Q to hangup and quit Kermit", 0},
- {" S for status", 0},
-#ifdef NOPUSH
- {" ! to push to local shell (disabled)", 0},
- {" Z to suspend (disabled)", 0},
-#else
- {" ! to push to local shell", 0},
-#ifdef NOJC
- {" Z to suspend (disabled)", 0},
-#else
- {" Z to suspend", 0},
-#endif /* NOJC */
-#endif /* NOPUSH */
- {" \\ backslash code:", 0},
- {" \\nnn decimal character code", 0},
- {" \\Onnn octal character code", 0},
- {" \\Xhh hexadecimal character code;", 0},
- {" terminate with Carriage Return.", 0},
- {" Type the escape character again to send the escape character itself,",
- 0},
- {" or press the space-bar to resume the CONNECT session.", 0},
- {NULL, 0}
-};
-
-int
-hconne() {
- int c, i, cxtype;
- if (network)
- cxtype = IS_TELNET() ? CXM_TEL : CXM_NET;
- else
- cxtype = CXM_SER;
-
- conol("\r\n----------------------------------------------------\r\n");
- conoll("Press:");
- conol(" C to return to ");
- conoll(*myhost ? myhost : "the C-Kermit prompt");
- for (i = 0; hlpmsg[i].hmsg; i++) {
- if (!(hlpmsg[i].hflags) || (hlpmsg[i].hflags == cxtype))
- conoll(hlpmsg[i].hmsg);
- }
- conol("Press a key>"); /* Prompt for command. */
- c = CONGKS() & 0177; /* Get character, strip any parity. */
- /* No key mapping or translation here */
- if (c != CMDQ)
- conoll("");
- conoll("----------------------------------------------------");
- return(c); /* Return it. */
-}
-
-
-/* D O E S C -- Process an escape character argument */
-
-VOID
-#ifdef CK_ANSIC
-doesc(char c)
-#else
-doesc(c) char c;
-#endif /* CK_ANSIC */
-/* doesc */ {
- CHAR d;
-
- debug(F101,"CONNECT doesc","",c);
- while (1) {
- if (c == escape) { /* Send escape character */
- d = dopar((CHAR) c); ttoc((char) d); return;
- } else /* Or else look it up below. */
- if (isupper(c)) c = tolower(c);
-
- switch(c) {
-
- case 'c': /* Escape back to prompt */
- case '\03':
- cx_status = CSX_ESCAPE;
-#ifdef NOICP
- conoll("");
- conoll("");
- conoll(
-" WARNING: This version of C-Kermit has no command processor to escape"
- );
- conoll(
-" back to. To return to your local system, log out from the remote and/or"
- );
- conoll(
-" use the escape character followed by the letter U to close (hang Up) the"
- );
- conoll(
-" connection. Resuming your session..."
- );
- conoll("");
- return;
-#else
- active = 0; conol("\r\n"); return;
-#endif /* NOICP */
-
- case 'b': /* Send a BREAK signal */
- case '\02':
-#ifdef CKLEARN
- learnchar(-7);
-#endif /* CKLEARN */
- ttsndb(); return;
-
-#ifdef NETCONN
- case 'i': /* Send Interrupt */
- case '\011':
-#ifdef TCPSOCKET
- if (network && IS_TELNET()) { /* TELNET */
- temp[0] = (CHAR) IAC; /* I Am a Command */
- temp[1] = (CHAR) TN_IP; /* Interrupt Process */
- temp[2] = NUL;
- ttol((CHAR *)temp,2);
- } else
-#endif /* TCPSOCKET */
- conoc(BEL);
- return;
-
-#ifdef TCPSOCKET
- case 'a': /* "Are You There?" */
- case '\01':
- if (network && IS_TELNET()) {
- temp[0] = (CHAR) IAC; /* I Am a Command */
- temp[1] = (CHAR) TN_AYT; /* Are You There? */
- temp[2] = NUL;
- ttol((CHAR *)temp,2);
- } else conoc(BEL);
- return;
-#endif /* TCPSOCKET */
-#endif /* NETCONN */
-
-#ifdef CK_LBRK
- case 'l': /* Send a Long BREAK signal */
-#ifdef CKLEARN
- learnchar(-8);
-#endif /* CKLEARN */
- ttsndlb(); return;
-#endif /* CK_LBRK */
-
- case 'u': /* Hangup */
- /* case '\010': */ /* No, too dangerous */
- cx_status = CSX_USERDISC;
- dohangup = 2; active = 0; conol("\r\nHanging up "); return;
-
- case 'q': /* Quit */
- cx_status = CSX_USERDISC;
- dohangup = 2; quitnow = 1; active = 0; conol("\r\n"); return;
-
- case 's': /* Status */
- conoll("");
- conoll("----------------------------------------------------");
-#ifdef PTYORPIPE
- if (ttpipe)
- ckmakmsg(temp,TMPLEN," Pipe: \"",ttname,"\"",NULL);
- else if (ttpty)
- ckmakmsg(temp,TMPLEN," Pty: \"",ttname,"\"",NULL);
- else
-#endif /* PTYORPIPE */
- ckmakmsg(temp,
- TMPLEN,
- " ",
- (network ? "Host" : "Device"),
- ": ",
- ttname
- );
- conoll(temp);
-
- /* The following sprintf's are safe, temp[] size is at least 200 */
-
- if (!network && speed >= 0L) {
- sprintf(temp,"Speed %ld", speed);
- conoll(temp);
- }
- sprintf(temp," Terminal echo: %s", duplex ? "local" : "remote");
- conoll(temp);
- sprintf(temp," Terminal bytesize: %d", (cmask == 0177) ? 7 : 8);
- conoll(temp);
- sprintf(temp," Command bytesize: %d", (cmdmsk == 0177) ? 7 : 8);
- conoll(temp);
- if (hwparity)
- sprintf(temp," Parity[hardware]: %s",parnam(hwparity));
- else
- sprintf(temp," Parity: %s", parnam(parity));
- conoll(temp);
-#ifndef NOXFER
- sprintf(temp," Autodownload: %s", autodl ? "on" : "off");
- conoll(temp);
-#endif /* NOXFER */
- ckmakmsg(temp, /* (would not be safe for sprintf) */
- TMPLEN,
- " Session log: ",
- *sesfil ? sesfil : "(none)",
- NULL,
- NULL
- );
- conoll(temp);
-#ifndef NOSHOW
- if (!network) shomdm();
-#endif /* NOSHOW */
-#ifdef CKLOGDIAL
- {
- long z;
- z = dologshow(0);
- if (z > -1L) {
- sprintf(temp," Elapsed time: %s",hhmmss(z));
- conoll(temp);
- }
- }
-#endif /* CKLOGDIAL */
- conoll("----------------------------------------------------");
- return;
-
- case 'h': /* Help */
- case '?': /* Help */
- c = hconne(); continue;
-
- case '0': /* Send a null */
- c = '\0'; d = dopar((CHAR) c); ttoc((char) d); return;
-
- case 'z': case '\032': /* Suspend */
-#ifndef NOPUSH
- if (!nopush)
- stptrap(0);
- else
- conoc(BEL);
-#else
- conoc(BEL);
-#endif /* NOPUSH */
- return;
-
- case '@': /* Start inferior command processor */
- case '!':
-#ifndef NOPUSH
- if (!nopush) {
- conres(); /* Put console back to normal */
- zshcmd(""); /* Fork a shell. */
- if (conbin((char)escape) < 0) {
- cx_status = CSX_INTERNAL;
- printf("Error resuming CONNECT session\n");
- active = 0;
- }
- } else conoc(BEL);
-#else
- conoc(BEL);
-#endif /* NOPUSH */
- return;
-
- case SP: /* Space, ignore */
- return;
-
- default: /* Other */
- if (c == CMDQ) { /* Backslash escape */
- int x;
- ecbp = ecbuf;
- *ecbp++ = c;
- while (((c = (CONGKS() & cmdmsk)) != '\r') && (c != '\n'))
- *ecbp++ = c;
- *ecbp = NUL; ecbp = ecbuf;
- x = xxesc(&ecbp); /* Interpret it */
- if (x >= 0) { /* No key mapping here */
- c = dopar((CHAR) x);
- ttoc((char) c);
- return;
- } else { /* Invalid backslash code. */
- conoc(BEL);
- return;
- }
- }
- conoc(BEL); return; /* Invalid esc arg, beep */
- }
- }
-}
-#endif /* NOLOCAL */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckucon.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckucon.c
deleted file mode 100644
index 50ceb7e..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckucon.c
+++ /dev/null
@@ -1,2690 +0,0 @@
-#include "ckcsym.h"
-
-char *connv = "CONNECT Command for UNIX:fork(), 9.0.117, 14 Jul 2011";
-
-/* C K U C O N -- Terminal connection to remote system, for UNIX */
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- NOTE: This module has been superseded on most platforms by ckucns.c, which
- uses select() rather than fork() for multiplexing its i/o. This module
- is still needed for platforms that do not support select(), and also for
- its X.25 support. Although the two modules share large amounts of code,
- their structure is radically different and therefore attempts at merging
- them have so far been unsuccessful. (November 1998.)
-
- Special thanks to Eduard Vopicka, Prague University of Economics,
- Czech Republic, for valuable contributions to this module in July 1994,
- and to Neal P. Murphy of the Motorola Cellular Infrastructure Group in 1996
- for rearranging the code to allow operation on the BeBox, yet still work
- in regular UNIX.
-*/
-#include "ckcdeb.h" /* Common things first */
-
-#ifndef NOLOCAL
-
-#ifdef BEOSORBEBOX
-static double time_started = 0.0;
-#include <kernel/OS.h>
-_PROTOTYP( static long concld, (void *) );
-#else
-_PROTOTYP( static VOID concld, (void) );
-#endif /* BEOSORBEBOX */
-
-#ifdef NEXT
-#undef NSIG
-#include <sys/wait.h> /* For wait() */
-#endif /* NEXT */
-
-#include <signal.h> /* Signals */
-
-#ifndef HPUXPRE65
-#include <errno.h> /* Error number symbols */
-#else
-#ifndef ERRNO_INCLUDED
-#include <errno.h> /* Error number symbols */
-#endif /* ERRNO_INCLUDED */
-#endif /* HPUXPRE65 */
-
-#ifdef ZILOG /* Longjumps */
-#include <setret.h>
-#else
-#include <setjmp.h>
-#endif /* ZILOG */
-#include "ckcsig.h"
-
-/* Kermit-specific includes */
-
-#include "ckcasc.h" /* ASCII characters */
-#include "ckcker.h" /* Kermit things */
-#include "ckucmd.h" /* For xxesc() prototype */
-#include "ckcnet.h" /* Network symbols */
-#ifndef NOCSETS
-#include "ckcxla.h" /* Character set translation */
-#endif /* NOCSETS */
-
-/* Internal function prototypes */
-
-_PROTOTYP( VOID ttflux, (void) );
-_PROTOTYP( VOID doesc, (char) );
-_PROTOTYP( VOID logchar, (char) );
-_PROTOTYP( int hconne, (void) );
-#ifndef NOSHOW
-_PROTOTYP( VOID shomdm, (void) );
-#endif /* NOSHOW */
-_PROTOTYP( static int kbget, (void) );
-_PROTOTYP( static int pipemsg, (int) );
-_PROTOTYP( static int ckcputf, (void) );
-_PROTOTYP( static VOID ck_sndmsg, (void) );
-/*
- For inter-fork signaling. Normally we use SIGUSR1, except on SCO, where
- we use SIGUSR2 because SIGUSR1 is used by the system. You can define
- CK_FORK_SIG to be whatever other signal you might want to use at compile
- time. We don't use SIGUSR2 everywhere because in some systems, like
- UnixWare, the default action for SIGUSR2 is to kill the process that gets it.
-*/
-#ifndef CK_FORK_SIG
-
-#ifndef SIGUSR1 /* User-defined signals */
-#define SIGUSR1 30
-#endif /* SIGUSR1 */
-
-#ifndef SIGUSR2
-#define SIGUSR2 31
-#endif /* SIGUSR2 */
-
-#ifdef M_UNIX
-#define CK_FORK_SIG SIGUSR2 /* SCO - use SIGUSR2 */
-#else
-#define CK_FORK_SIG SIGUSR1 /* Others - use SIGUSR1 */
-#endif /* M_UNIX */
-
-#endif /* CK_FORK_SIG */
-
-/* External variables */
-
-extern struct ck_p ptab[];
-
-extern int local, escape, duplex, parity, flow, seslog, sessft, debses,
- mdmtyp, ttnproto, cmask, cmdmsk, network, nettype, deblog, sosi, tnlm,
- xitsta, what, ttyfd, ttpipe, quiet, backgrd, pflag, tt_crd, tt_lfd,
- tn_nlm, ttfdflg,
- tt_escape, justone, carrier, hwparity;
-
-extern long speed;
-extern char ttname[], sesfil[], myhost[], *ccntab[];
-#ifdef TNCODE
-extern int tn_b_nlm, tn_rem_echo;
-#endif /* TNCODE */
-
-#ifdef CK_TRIGGER
-extern char * tt_trigger[], * triggerval;
-#endif /* CK_TRIGGER */
-
-extern int nopush;
-
-#ifdef CK_APC
-extern int apcactive; /* Application Program Command (APC) */
-extern int apcstatus; /* items ... */
-static int apclength = 0;
-#ifdef DCMDBUF
-extern char *apcbuf;
-#else
-extern char apcbuf[];
-#endif /* DCMDBUF */
-static int apcbuflen = APCBUFLEN - 2;
-extern int protocol; /* Auto download */
-#endif /* CK_APC */
-
-extern int autodl;
-#ifdef CK_AUTODL
-extern CHAR ksbuf[];
-#endif /* CK_AUTODL */
-
-#ifdef CK_XYZ
-#ifdef XYZ_INTERNAL
-static int zmdlok = 1; /* Zmodem autodownloads available */
-#else
-static int zmdlok = 0; /* Depends on external protocol def */
-#endif /* XYZ_INTERNAL */
-#else
-static int zmdlok = 0; /* Not available at all */
-#endif /* CK_XYZ */
-
-#ifndef NOSETKEY /* Keyboard mapping */
-extern KEY *keymap; /* Single-character key map */
-extern MACRO *macrotab; /* Key macro pointer table */
-static MACRO kmptr = NULL; /* Pointer to current key macro */
-#endif /* NOSETKEY */
-
-/* Global variables local to this module */
-
-static int
- quitnow = 0, /* <esc-char>Q was typed */
- jbset = 0, /* Flag whether jmp buf is set. */
- dohangup = 0, /* <esc-char>H was typed */
- sjval, /* Setjump return value */
- goterr = 0, /* Fork/pipe creation error flag */
- inshift = 0, /* SO/SI shift states */
- outshift = 0;
-
-int active = 0; /* Lower fork active flag */
-
-static PID_T parent_id = (PID_T)0; /* Process ID of keyboard fork */
-
-static char ecbuf[10], *ecbp; /* Escape char buffer & pointer */
-
-#ifdef CK_SMALL
-#define IBUFL 1536 /* Input buffer length */
-#else
-#define IBUFL 4096
-#endif /* CK_SMALL */
-
-static int obc = 0; /* Output buffer count */
-
-#ifndef OXOS
-#define OBUFL 1024 /* Output buffer length */
-#else
-#define OBUFL IBUFL
-#endif /* OXOS */
-
-#ifdef BIGBUFOK
-#define TMPLEN 4096 /* Temporary message buffer length */
-#else
-#define TMPLEN 200
-#endif /* BIGBUFOK */
-
-#ifdef DYNAMIC
-static char *ibuf = NULL, *obuf = NULL, *temp = NULL; /* Buffers */
-#else
-static char ibuf[IBUFL], obuf[OBUFL], temp[TMPLEN];
-#endif /* DYNAMIC */
-
-#ifdef DYNAMIC
-static char *ibp; /* Input buffer pointer */
-#else
-static char *ibp = ibuf; /* Input buffer pointer */
-#endif /*DYNAMIC */
-static int ibc = 0; /* Input buffer count */
-
-#ifdef DYNAMIC
-static char *obp; /* Output buffer pointer */
-#else
-static char *obp = obuf; /* Output buffer pointer */
-#endif /* DYNAMIC */
-
-/* X.25 items */
-
-#ifdef ANYX25
-static char *p; /* General purpose pointer */
-char x25ibuf[MAXIX25]; /* Input buffer */
-char x25obuf[MAXOX25]; /* Output buffer */
-int ibufl; /* Length of input buffer */
-int obufl; /* Length of output buffer */
-unsigned char tosend = 0;
-int linkid, lcn;
-static int dox25clr = 0;
-#ifndef IBMX25
-extern CHAR padparms[];
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-static int xpipe[2] = {-1, -1}; /* Pipe descriptor for child-parent messages */
-static PID_T pid = (PID_T) 0; /* Process ID of child */
-
-/* Character-set items */
-
-static int unicode = 0;
-
-static int escseq = 0; /* 1 = Recognizer is active */
-int inesc = 0; /* State of sequence recognizer */
-int oldesc = -1; /* Previous state of recognizer */
-
-#define OUTXBUFSIZ 15
-static CHAR inxbuf[OUTXBUFSIZ+1]; /* Host-to-screen expansion buffer */
-static int inxcount = 0; /* and count */
-static CHAR outxbuf[OUTXBUFSIZ+1]; /* Keyboard-to-host expansion buf */
-static int outxcount = 0; /* and count */
-
-#ifndef NOCSETS
-#ifdef CK_ANSIC /* ANSI C prototypes... */
-extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* Character set */
-extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* translation functions */
-static CHAR (*sxo)(CHAR); /* Local translation functions */
-static CHAR (*rxo)(CHAR); /* for output (sending) terminal chars */
-static CHAR (*sxi)(CHAR); /* and for input (receiving) terminal chars. */
-static CHAR (*rxi)(CHAR);
-#else /* Not ANSI C... */
-extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(); /* Character set */
-extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(); /* translation functions. */
-static CHAR (*sxo)(); /* Local translation functions */
-static CHAR (*rxo)(); /* for output (sending) terminal chars */
-static CHAR (*sxi)(); /* and for input (receiving) terminal chars. */
-static CHAR (*rxi)();
-#endif /* CK_ANSIC */
-extern int language; /* Current language. */
-static int langsv; /* For remembering language setting. */
-extern struct csinfo fcsinfo[]; /* File character set info. */
-extern int tcsr, tcsl; /* Terminal character sets, remote & local. */
-static int tcs; /* Intermediate ("transfer") character set. */
-static int tcssize = 0; /* Size of tcs */
-#ifdef UNICODE /* UTF-8 support */
-#ifdef CK_ANSIC
-extern int (*xl_ufc[MAXFCSETS+1])(USHORT); /* Unicode to FCS */
-extern USHORT (*xl_fcu[MAXFCSETS+1])(CHAR); /* FCS to Unicode */
-extern int (*xuf)(USHORT); /* Translation function UCS to FCS */
-extern USHORT (*xfu)(CHAR); /* Translation function FCS to UCS */
-#else
-extern int (*xl_ufc[MAXFCSETS+1])();
-extern USHORT (*xl_fcu[MAXFCSETS+1])();
-extern int (*xuf)();
-extern USHORT (*xfu)();
-#endif /* CK_ANSIC */
-#endif /* UNICODE */
-#endif /* NOCSETS */
-
-/*
- We do not need to parse and recognize escape sequences if we are being built
- without character-set support AND without APC support.
-*/
-#ifdef NOCSETS /* No character sets */
-#ifndef CK_APC /* No APC */
-#ifndef NOESCSEQ
-#define NOESCSEQ /* So no escape sequence recognizer */
-#endif /* NOESCSEQ */
-#endif /* CK_APC */
-#endif /* NOCSETS */
-
-/* Child process events and messages */
-
-#define CEV_NO 0 /* No event */
-#define CEV_HUP 1 /* Communications hangup */
-#define CEV_PAD 2 /* X.25 - change PAD parameters */
-#define CEV_DUP 3 /* Toggle duplex */
-#define CEV_APC 4 /* Execute APC */
-#ifdef TNCODE
-#define CEV_MEBIN 5 /* Change of me_binary */
-#define CEV_UBIN 6 /* Change of u_binary */
-#endif /* TNCODE */
-#define CEV_ADL 7 /* Autodownload */
-#define CEV_AUL 8 /* Autoupload */
-#define CEV_TRI 9 /* Trigger string */
-
-#ifdef NOESCSEQ
-#define chkaes(x) 0
-#else
-/*
- As of edit 178, the CONNECT command skips past ANSI escape sequences to
- avoid translating the characters within them. This allows the CONNECT
- command to work correctly with a host that uses a 7-bit ISO 646 national
- character set, in which characters like '[' would normally be translated
- into accented characters, ruining the terminal's interpretation (and
- generation) of escape sequences.
-
- As of edit 190, the CONNECT command responds to APC escape sequences
- (ESC _ text ESC \) if the user SETs TERMINAL APC ON or UNCHECKED, and the
- program was built with CK_APC defined.
-
- Non-ANSI/ISO-compliant escape sequences are not handled.
-*/
-
-/* States for the escape-sequence recognizer. */
-
-#define ES_NORMAL 0 /* Normal, not in an escape sequence */
-#define ES_GOTESC 1 /* Current character is ESC */
-#define ES_ESCSEQ 2 /* Inside an escape sequence */
-#define ES_GOTCSI 3 /* Inside a control sequence */
-#define ES_STRING 4 /* Inside DCS,OSC,PM, or APC string */
-#define ES_TERMIN 5 /* 1st char of string terminator */
-
-/*
- ANSI escape sequence handling. Only the 7-bit form is treated, because
- translation is not a problem in the 8-bit environment, in which all GL
- characters are ASCII and no translation takes place. So we don't check
- for the 8-bit single-character versions of CSI, DCS, OSC, APC, or ST.
- Here is the ANSI sequence recognizer state table, followed by the code
- that implements it.
-
- Definitions:
- CAN = Cancel 01/08 Ctrl-X
- SUB = Substitute 01/10 Ctrl-Z
- DCS = Device Control Sequence 01/11 05/00 ESC P
- CSI = Control Sequence Introducer 01/11 05/11 ESC [
- ST = String Terminator 01/11 05/12 ESC \
- OSC = Operating System Command 01/11 05/13 ESC ]
- PM = Privacy Message 01/11 05/14 ESC ^
- APC = Application Program Command 01/11 05/15 ESC _
-
- ANSI escape sequence recognizer:
-
- State Input New State ; Commentary
-
- NORMAL (start) ; Start in NORMAL state
-
- (any) CAN NORMAL ; ^X cancels
- (any) SUB NORMAL ; ^Z cancels
-
- NORMAL ESC GOTESC ; Begin escape sequence
- NORMAL other ; NORMAL control or graphic character
-
- GOTESC ESC ; Start again
- GOTESC [ GOTCSI ; CSI
- GOTESC P STRING ; DCS introducer, consume through ST
- GOTESC ] STRING ; OSC introducer, consume through ST
- GOTESC ^ STRING ; PM introducer, consume through ST
- GOTESC _ STRING ; APC introducer, consume through ST
- GOTESC 0..~ NORMAL ; 03/00 through 17/14 = Final character
- GOTESC other ESCSEQ ; Intermediate or ignored control character
-
- ESCSEQ ESC GOTESC ; Start again
- ESCSEQ 0..~ NORMAL ; 03/00 through 17/14 = Final character
- ESCSEQ other ; Intermediate or ignored control character
-
- GOTCSI ESC GOTESC ; Start again
- GOTCSI @..~ NORMAL ; 04/00 through 17/14 = Final character
- GOTCSI other ; Intermediate char or ignored control char
-
- STRING ESC TERMIN ; Maybe have ST
- STRING other ; Consume all else
-
- TERMIN \ NORMAL ; End of string
- TERMIN other STRING ; Still in string
-*/
-/*
- chkaes() -- Check ANSI Escape Sequence.
- Call with EACH character in input stream.
- Sets global inesc variable according to escape sequence state.
- Returns 0 normally, 1 if an APC sequence is to be executed.
-*/
-int
-#ifdef CK_ANSIC
-chkaes(char c)
-#else
-chkaes(c) char c;
-#endif /* CK_ANSIC */
-/* chkaes */ {
-
- oldesc = inesc; /* Remember previous state */
- if (c == CAN || c == SUB) /* CAN and SUB cancel any sequence */
- inesc = ES_NORMAL;
- else /* Otherwise */
- switch (inesc) { /* enter state switcher */
-
- case ES_NORMAL: /* NORMAL state */
- if (c == ESC) /* Got an ESC */
- inesc = ES_GOTESC; /* Change state to GOTESC */
- break; /* Otherwise stay in NORMAL state */
-
- case ES_GOTESC: /* GOTESC state */
- if (c == '[') /* Left bracket after ESC is CSI */
- inesc = ES_GOTCSI; /* Change to GOTCSI state */
- else if (c == 'P' || (c > 0134 && c < 0140)) { /* P, [, ^, or _ */
- inesc = ES_STRING; /* Switch to STRING-absorption state */
-#ifdef CK_APC
- if (c == '_' && pid == 0 && /* APC handled in child only */
- (apcstatus & APC_ON)) { /* and only if not disabled. */
- debug(F100,"CONNECT APC begin","",0);
- apcactive = APC_REMOTE; /* Set APC-Active flag */
- apclength = 0; /* and reset APC buffer pointer */
- }
-#endif /* CK_APC */
- } else if (c > 057 && c < 0177) /* Final character '0' thru '~' */
- inesc = ES_NORMAL; /* Back to normal */
- else if (c != ESC) /* ESC in an escape sequence... */
- inesc = ES_ESCSEQ; /* starts a new escape sequence */
- break; /* Intermediate or ignored ctrl char */
-
- case ES_ESCSEQ: /* ESCSEQ -- in an escape sequence */
- if (c > 057 && c < 0177) /* Final character '0' thru '~' */
- inesc = ES_NORMAL; /* Return to NORMAL state. */
- else if (c == ESC) /* ESC ... */
- inesc = ES_GOTESC; /* starts a new escape sequence */
- break; /* Intermediate or ignored ctrl char */
-
- case ES_GOTCSI: /* GOTCSI -- In a control sequence */
- if (c > 077 && c < 0177) /* Final character '@' thru '~' */
- inesc = ES_NORMAL; /* Return to NORMAL. */
- else if (c == ESC) /* ESC ... */
- inesc = ES_GOTESC; /* starts over. */
- break; /* Intermediate or ignored ctrl char */
-
- case ES_STRING: /* Inside a string */
- if (c == ESC) /* ESC may be 1st char of terminator */
- inesc = ES_TERMIN; /* Go see. */
-#ifdef CK_APC
- else if (apcactive && (apclength < apcbuflen)) /* If in APC, */
- apcbuf[apclength++] = c; /* deposit this character. */
- else { /* Buffer overrun */
- apcactive = 0; /* Discard what we got */
- apclength = 0; /* and go back to normal */
- apcbuf[0] = 0; /* Not pretty, but what else */
- inesc = ES_NORMAL; /* can we do? (ST might not come) */
- }
-#endif /* CK_APC */
- break; /* Absorb all other characters. */
-
- case ES_TERMIN: /* May have a string terminator */
- if (c == '\\') { /* which must be backslash */
- inesc = ES_NORMAL; /* If so, back to NORMAL */
-#ifdef CK_APC
- if (apcactive) { /* If it was an APC string, */
- debug(F101,"CONNECT APC terminated","",c);
- apcbuf[apclength] = NUL; /* terminate it and then ... */
- return(1);
- }
-#endif /* CK_APC */
- } else { /* Otherwise */
- inesc = ES_STRING; /* Back to string absorption. */
-#ifdef CK_APC
- if (apcactive && (apclength+1 < apcbuflen)) { /* In APC string */
- apcbuf[apclength++] = ESC; /* deposit the Esc character */
- apcbuf[apclength++] = c; /* and this character too */
- }
-#endif /* CK_APC */
- }
- }
- return(0);
-}
-#endif /* NOESCSEQ */
-
-/* Connect state parent/child communication signal handlers */
-
-/* Routines used by the child process */
-
-static int
-pipemsg(n) int n; { /* Send message ID to parent */
- int code = n & 255;
- return(write(xpipe[1], &code, sizeof(code)));
-}
-
-/* Environment pointer for CK_FORK_SIG signal handling in child... */
-
-#ifdef CK_POSIX_SIG
-static sigjmp_buf sig_env;
-#else
-static jmp_buf sig_env;
-#endif /* CK_POSIX_SIG */
-
-static SIGTYP /* CK_FORK_SIG handling in child ... */
-forkint(foo) int foo; {
- /* It is important to disable CK_FORK_SIG before longjmp */
- signal(CK_FORK_SIG, SIG_IGN); /* Set to ignore CK_FORK_SIG */
- debug(F100,"CONNECT forkint - CK_FORK_SIG", "", 0);
- /* Force return from ck_sndmsg() */
- cklongjmp(sig_env, 1);
- /* NOTREACHED */
-}
-
-static VOID
-ck_sndmsg() { /* Executed by child only ... */
- debug(F100,"CONNECT ck_sndmsg, active", "", active);
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sig_env,1)
-#else
- setjmp(sig_env)
-#endif /* CK_POSIX_SIG */
- == 0) {
- debug(F100,"CONNECT ck_sndmsg signaling parent","",0);
- signal(CK_FORK_SIG, forkint); /* Set up signal handler */
- kill(parent_id, CK_FORK_SIG); /* Kick the parent */
- debug(F100,"ck_sndmsg pausing","",0);
- for (;;) pause(); /* Wait for CK_FORK_SIG or SIGKILL */
- /* NOTREACHED */
- }
- /* We come here from forkint() via [sig]cklongjmp(sig_env,1) */
- debug(F100,"CONNECT ck_sndmsg is parent - returning", "", 0);
-}
-
-/* Routines used by the parent process */
-
-#ifdef CK_POSIX_SIG /* Environment pointer for CONNECT errors */
-static sigjmp_buf con_env;
-#else
-static jmp_buf con_env;
-#endif /* CK_POSIX_SIG */
-/*
- pipeint() handles CK_FORK_SIG signals from the lower (port) fork.
- It reads a function code from the pipe that connects the two forks,
- then reads additional data from the pipe, then handles it.
-*/
-static SIGTYP
-pipeint(arg) int arg; { /* Dummy argument */
- int code, cx, x, i /* , n */ ;
-
-#ifndef NOCCTRAP
- extern ckjmpbuf cmjbuf;
-#endif /* NOCCTRAP */
- /*
- IMPORTANT: At this point, the child fork is waiting for CK_FORK_SIG
- (eventually for SIGKILL) inside of ck_sndmsg(). So we can't get any
- subsequent CK_FORK_SIG from child before we send it CK_FORK_SIG.
- */
- signal(CK_FORK_SIG, SIG_IGN); /* Ignore CK_FORK_SIG now */
- debug(F101,"CONNECT pipeint arg","",arg);
-
- read(xpipe[0], &code, sizeof(code)); /* Get function code from pipe */
- debug(F101,"CONNECT pipeint code","",code);
- cx = code & 255; /* 8-bit version of function code */
-
-#ifndef NOCCTRAP
-#ifndef NOICP
-#define USECCJMPBUF
-#endif /* NOICP */
-#endif /* NOCCTRAP */
-/*
- Read info passed back up to us by the lower fork, depending on the function
- requested. The same number of items must be read from the pipe in the same
- order as the lower fork put them there. Trying to read something that's not
- there makes the program hang uninterruptibly. Pay close attention -- notice
- how we fall through some of the cases rather than break; that's deliberate.
-*/
- switch (cx) {
-#ifdef CK_TRIGGER
- case CEV_TRI: /* Trigger string */
- debug(F100,"CONNECT trigger","",0);
- read(xpipe[0], (char *)&i, sizeof(i)); /* Trigger index */
- debug(F101,"CONNECT trigger index","",i);
- makestr(&triggerval,tt_trigger[i]); /* Make a copy of the trigger */
- debug(F110,"CONNECT triggerval",triggerval,0);
- read(xpipe[0], (char *)&ibc, sizeof(ibc)); /* Copy child's */
- debug(F101,"CONNECT trigger ibc (upper)","",ibc); /* input buffer. */
- if (ibc > 0) {
- read(xpipe[0], (char *)&ibp, sizeof(ibp));
- read(xpipe[0], ibp, ibc);
- }
- /* Fall thru... */
-
-#endif /* CK_TRIGGER */
-
- case CEV_HUP:
-/*
- The CEV_HUP case is executed when the other side has hung up on us.
- In some cases, this happens before we have had a chance to execute the
- setjmp(con_env,1) call, and in that case we'd better not take the longjmp!
- A good example is when you TELNET to port 13 on the local host; it prints
- its asctime() string (26 chars) and then closes the connection.
-*/
-#ifdef CK_TRIGGER
- if (cx == CEV_TRI)
- sjval = CEV_TRI; /* Set global variable. */
- else
-#endif /* CK_TRIGGER */
- sjval = CEV_HUP;
- if (jbset) { /* jmp_buf is initialized */
- cklongjmp(con_env,sjval); /* so do the right thing. */
- } else {
- int x = 0;
-#ifdef USECCJMPBUF
- /* jmp_buf not init'd yet a close approximation... */
-#ifdef CK_TRIGGER
- if (cx == CEV_HUP)
-#endif /* CK_TRIGGER */
- ttclos(0); /* Close our end of the connection */
- if (pid) {
- debug(F101,"CONNECT trigger killing pid","",pid);
-#ifdef BEOSORBEBOX
- {
- long ret_val;
- x = kill(pid,SIGKILLTHR); /* Kill lower fork */
- wait_for_thread (pid, &ret_val);
- }
-#else
-#ifdef Plan9
- x = kill(pid, SIGKILL); /* (should always use this really) */
-#else
- x = kill(pid,9); /* Kill lower fork (history) */
-#endif /* Plan9 */
- wait((WAIT_T *)0); /* Wait till gone. */
- if (x < 0) {
- printf("ERROR: Failure to kill pid %ld: %s, errno=%d\n",
- (long) pid, ck_errstr(), errno);
- debug(F111,"CONNECT error killing stale pid",
- ck_errstr(),errno);
- }
- pid = (PID_T) 0;
-#endif /* BEOSORBEBOX */
- }
- conres(); /* Reset the console. */
- if (!quiet) {
- printf("\r\n(Back at %s)\r\n",
- *myhost ? myhost :
-#ifdef UNIX
- "local UNIX system"
-#else
- "local system"
-#endif /* UNIX */
- );
- }
- what = W_NOTHING; /* So console modes are set right. */
- printf("\r\n"); /* prevent prompt-stomping */
- cklongjmp(cmjbuf,0); /* Do what the Ctrl-C handler does */
-#else
- printf("\r\nLongjump failure - fatal\r\n");
- doexit(GOOD_EXIT,-1); /* Better than dumping core... */
-#endif /* USECCJMPBUF */
- }
-#ifdef USECCJMPBUF
-#undef USECCJMPBUF
-#endif /* USECCJMPBUF */
-
- case CEV_DUP: /* Child sends duplex change */
- read(xpipe[0], (char *)&duplex, sizeof(duplex));
- debug(F101,"CONNECT pipeint duplex","",duplex);
- break;
-#ifdef TNCODE
- case CEV_MEBIN: /* Child sends me_binary change */
- read(xpipe[0],
- (char *)&TELOPT_ME(TELOPT_BINARY),
- sizeof(TELOPT_ME(TELOPT_BINARY))
- );
- debug(F101,"CONNECT pipeint me_binary","",TELOPT_ME(TELOPT_BINARY));
- break;
- case CEV_UBIN: /* Child sends u_binary change */
- read(xpipe[0],
- (char *)&TELOPT_U(TELOPT_BINARY),
- sizeof(TELOPT_U(TELOPT_BINARY))
- );
- debug(F101,"CONNECT pipeint u_binary","",TELOPT_U(TELOPT_BINARY));
- break;
-#endif /* TNCODE */
-
-#ifdef CK_APC
- case CEV_AUL: /* Autoupload */
- justone = 1;
- debug(F100,"CONNECT autoupload at parent","",0);
-#ifdef CK_AUTODL
- case CEV_ADL: /* Autodownload */
- apcactive = APC_LOCAL;
- if (!justone) debug(F100,"CONNECT autodownload at parent","",0);
- /* Copy child's Kermit packet if any */
- read(xpipe[0], (char *)&x, sizeof(x));
- debug(F101,"CONNECT trigger ibc (upper)","",ibc);
- if (x > 0)
- read(xpipe[0], (char *)ksbuf, x+1);
-#endif /* CK_AUTODL */
- case CEV_APC: /* Application Program Command */
- read(xpipe[0], (char *)&apclength, sizeof(apclength));
- read(xpipe[0], apcbuf, apclength+1); /* Include trailing zero byte */
- debug(F111,"CONNECT APC at parent",apcbuf,apclength);
- read(xpipe[0], (char *)&ibc, sizeof(ibc)); /* Copy child's */
- if (ibc > 0) { /* input buffer. */
- read(xpipe[0], (char *)&ibp, sizeof(ibp));
- read(xpipe[0], ibp, ibc);
- }
- obc = 0; obp = obuf; *obuf = NUL; /* Because port fork flushed */
- sjval = CEV_APC;
- cklongjmp(con_env,sjval);
- /* NOTREACHED */
-#endif /* CK_APC */
-
-#ifdef SUNX25
- case CEV_PAD: /* X.25 PAD parameter change */
- debug(F100,"CONNECT pipeint PAD change","",0);
- read(xpipe[0],padparms,MAXPADPARMS);
- sjval = CEV_PAD; /* Set global variable. */
-#ifdef COMMENT /* We might not need to do this... */
- cklongjmp(con_env,sjval);
- /* NOTREACHED */
-#else /* COMMENT */
- break;
-#endif /* COMMENT */
-#endif /* SUNX25 */
- }
- signal(CK_FORK_SIG, pipeint); /* Set up signal handler */
- kill(pid, CK_FORK_SIG); /* Signal the port fork ... */
-}
-
-/* C K C P U T C -- C-Kermit CONNECT Put Character to Screen */
-/*
- Output is buffered to avoid slow screen writes on fast connections.
- NOTE: These could (easily?) become macros ...
-*/
-static int
-ckcputf() { /* Dump the output buffer */
- int x = 0;
- if (obc > 0) /* If we have any characters, */
- x = conxo(obc,obuf); /* dump them, */
- obp = obuf; /* reset the pointer */
- obc = 0; /* and the counter. */
- return(x); /* Return conxo's return code */
-}
-
-int
-ckcputc(c) int c; {
- int x;
-
- *obp++ = c & 0xff; /* Deposit the character */
- obc++; /* Count it */
- if (ibc == 0 || /* If input buffer about empty */
- obc == OBUFL) { /* or output buffer full */
- debug(F101,"CONNECT CKCPUTC obc","",obc);
- x = conxo(obc,obuf); /* dump the buffer, */
- obp = obuf; /* reset the pointer */
- obc = 0; /* and the counter. */
- return(x); /* Return conxo's return code */
- } else return(0);
-}
-
-/* C K C G E T C -- C-Kermit CONNECT Get Character */
-/*
- Buffered read from communication device.
- Returns the next character, refilling the buffer if necessary.
- On error, returns ttinc's return code (see ttinc() description).
- Dummy argument for compatible calling conventions with ttinc().
- NOTE: We don't have a macro for this because we have to pass
- a pointer to this function as an argument to tn_doop().
-*/
-int
-ckcgetc(dummy) int dummy; {
- int c, n;
-#ifdef CK_SSL
- extern int ssl_active_flag, tls_active_flag;
-#endif /* CK_SSL */
-
-#ifdef CK_ENCRYPTION
- /* No buffering for possibly encrypted connections */
- if (network && IS_TELNET() && TELOPT_ME(TELOPT_AUTHENTICATION))
- return(ttinc(0));
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag)
- return(ttinc(0));
-#endif /* CK_SSL */
-#ifdef COMMENT
-/* too much */
- debug(F101,"CONNECT CKCGETC 1 ibc","",ibc); /* Log */
-#endif /* COMMENT */
- if (ibc < 1) { /* Need to refill buffer? */
- ibc = 0; /* Yes, reset count */
- ibp = ibuf; /* and buffer pointer */
- /* debug(F100,"CONNECT CKCGETC 1 calling ttinc(0)","",0); */
-#ifdef COMMENT
-/*
- This check is not worth the overhead. Scenario: ttchk() returns 0, so we
- fall through to the blocking ttinc(). While in ttinc(), the connection is
- lost. But the read() that ttinc() calls does not notice, and never returns.
- This happens at least in HP-UX, and can be seen when we turn off the modem.
-*/
- if (!network && (carrier != CAR_OFF))
- if ((n = ttchk()) < 0) /* Make sure connection is not lost */
- return(n);
-#endif /* COMMENT */
- c = ttinc(0); /* Read one character, blocking */
- /* debug(F101,"CONNECT CKCGETC 1 ttinc(0)","",c); */
- if (c < 0) { /* If error, return error code */
- return(c);
- } else { /* Otherwise, got one character */
- *ibp++ = c; /* Advance buffer pointer */
- ibc++; /* and count. */
- }
- if ((n = ttchk()) > 0) { /* Any more waiting? */
- if (n > (IBUFL - ibc)) /* Get them all at once. */
- n = IBUFL - ibc; /* Don't overflow buffer */
- if ((n = ttxin(n,(CHAR *)ibp)) > 0) {
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION))
- ck_tn_decrypt(ibp,n);
-#endif /* CK_ENCRYPTION */
- ibc += n; /* Advance counter */
- }
- } else if (n < 0) { /* Error? */
- return(n); /* Return the error code */
- }
- debug(F101,"CONNECT CKCGETC 2 ibc","",ibc); /* Log how many */
- ibp = ibuf; /* Point to beginning of buffer */
- }
- c = *ibp++ & 0xff; /* Get next character from buffer */
- ibc--; /* Reduce buffer count */
- return(c); /* Return the character */
-}
-
-/*
- Keyboard handling, buffered for speed, which is needed when C-Kermit is
- in CONNECT mode between two other computers that are transferring data.
-*/
-static char *kbp; /* Keyboard input buffer pointer */
-static int kbc; /* Keyboard input buffer count */
-
-#ifdef CK_SMALL /* Keyboard input buffer length */
-#define KBUFL 32 /* Small for PDP-11 UNIX */
-#else
-#define KBUFL 257 /* Regular kernel size for others */
-#endif /* CK_SMALL */
-
-#ifdef DYNAMIC
-static char *kbuf = NULL;
-#else
-static char kbuf[KBUFL];
-#endif /* DYNAMIC */
-
-/* Macro for reading keystrokes. */
-
-#define CONGKS() (((--kbc)>=0) ? ((int)(*kbp++) & 0377) : kbget())
-
-/*
- Note that we call read() directly here, normally a no-no, but in this case
- we know it's UNIX and we're only doing what coninc(0) would have done,
- except we're reading a block of characters rather than just one. There is,
- at present, no conxin() analog to ttxin() for chunk reads, and instituting
- one would only add function-call overhead as it would only be a wrapper for
- a read() call anyway.
-*/
-/*
- Another note: We stick in this read() till the user types something.
- But the other (lower) fork is running too, and on TELNET connections,
- it will signal us to indicate echo-change negotiations, and this can
- interrupt the read(). Some UNIXes automatically restart the interrupted
- system call, others return from it with errno == EINTR.
-*/
-static int /* Keyboard buffer filler */
-kbget() {
-#ifdef EINTR
- int tries = 10; /* If read() is interrupted, */
- int ok = 0;
- while (tries-- > 0) { /* try a few times... */
-#endif /* EINTR */
- if ((kbc = conchk()) < 1) /* How many chars waiting? */
- kbc = 1; /* If none or dunno, wait for one. */
- else if (kbc > KBUFL) /* If too many, */
- kbc = KBUFL; /* only read this many. */
- if ((kbc = read(0, kbuf, kbc)) < 1) { /* Now read it/them. */
- debug(F101,"CONNECT kbget errno","",errno); /* Got an error. */
-#ifdef EINTR
- if (errno == EINTR) /* Interrupted system call. */
- continue; /* Try again, up to limit. */
- else /* Something else. */
-#endif /* EINTR */
- return(-1); /* Pass along read() error. */
- }
-#ifdef EINTR
- else { ok = 1; break; }
- }
- if (!ok) return(-1);
-#endif /* EINTR */
- kbp = kbuf; /* Adjust buffer pointer, */
- kbc--; /* count, */
- return((int)(*kbp++) & 0377); /* and return first character. */
-}
-
-/* C O N C L D -- Interactive terminal connection child function */
-
-static
-#ifdef BEOSORBEBOX
-long
-#else
-VOID
-#endif /* BEOSORBEBOX */
-concld (
-#ifdef BEOSORBEBOX
- void *bevoid
-#endif /* BEOSORBEBOX */
- ) {
- int n; /* General purpose counter */
- int i; /* For loops... */
- int c = -1; /* c is a character, but must be signed
- integer to pass thru -1, which is the
- modem disconnection signal, and is
- different from the character 0377 */
- int prev;
-#ifdef TNCODE
- int tx; /* tn_doop() return code */
-#endif /* TNCODE */
-#ifdef CK_TRIGGER
- int ix; /* Trigger index */
-#endif /* CK_TRIGGER */
-#ifndef NOESCSEQ
- int apcrc;
-#endif /* NOESCSEQ */
-
-#ifdef COMMENT
- int conret = 0; /* Return value from conect() */
- jbchksum = -1L;
-#endif /* COMMENT */
- jbset = 0; /* jmp_buf not set yet, don't use it */
- debug(F101,"CONNECT concld entry","",CK_FORK_SIG);
- /* *** */ /* Inferior reads, prints port input */
-
- if (priv_can()) { /* Cancel all privs */
- printf("?setuid error - fatal\n");
- doexit(BAD_EXIT,-1);
- }
- signal(SIGINT, SIG_IGN); /* In case these haven't been */
- signal(SIGQUIT, SIG_IGN); /* inherited from above... */
- signal(CK_FORK_SIG, SIG_IGN); /* CK_FORK_SIG not expected yet */
-
- inshift = outshift = 0; /* Initial SO/SI shift state. */
- { /* Wait for parent's setup */
- int i;
- while ((i = read(xpipe[0], &c, 1)) <= 0) {
- if (i < 0) {
- debug(F101,"CONNECT concld setup error","",i);
- debug(F111,"CONNECT concld setup error",ck_errstr(),errno);
- pipemsg(CEV_HUP); /* Read error - hangup */
- ck_sndmsg(); /* Send and wait to be killed */
- /* NOTREACHED */
- } /* Restart interrupted read() */
- }
- }
- close(xpipe[0]); xpipe[0] = -1; /* Child - prevent future reads */
-#ifdef DEBUG
- if (deblog) {
- debug(F100,"CONNECT starting port fork","",0);
- debug(F101,"CONNECT port fork ibc","",ibc);
- debug(F101,"CONNECT port fork obc","",obc);
- }
-#endif /* DEBUG */
- what = W_CONNECT;
-
- while (1) { /* Fresh read, wait for a character. */
-#ifdef ANYX25
- if (network && (nettype == NET_SX25)) {
- bzero(x25ibuf,sizeof(x25ibuf)) ;
- if ((ibufl = ttxin(MAXIX25,(CHAR *)x25ibuf)) < 0) {
-#ifndef IBMX25
- if (ibufl == -2) { /* PAD parms changes */
- pipemsg(CEV_PAD);
- write(xpipe[1],padparms,MAXPADPARMS);
- ck_sndmsg();
- } else {
-#endif /* IBMX25 */
- if (!quiet)
- printf("\r\nCommunications disconnect ");
- dologend();
- pipemsg(CEV_HUP);
- ck_sndmsg(); /* Wait to be killed */
- /* NOTREACHED */
-#ifndef IBMX25
- }
-#endif /* IBMX25 */
- /* pause(); <--- SHOULD BE OBSOLETE NOW! */
- /* BECAUSE pause() is done inside of ck_sndmsg() */
- }
- if (debses) { /* Debugging output */
- p = x25ibuf ;
- while (ibufl--) { c = *p++; conol(dbchr(c)); }
- } else {
- if (seslog && sessft) /* Binary session log */
- logchar((char)c); /* Log char before translation */
-
- if (sosi
-#ifndef NOCSETS
- || tcsl != tcsr
-#endif /* NOCSETS */
- ) { /* Character at a time */
- for (i = 1; i < ibufl; i++) {
- c = x25ibuf[i] & cmask;
- if (sosi) { /* Handle SI/SO */
- if (c == SO) {
- inshift = 1;
- continue;
- } else if (c == SI) {
- inshift = 0;
- continue;
- }
- if (inshift)
- c |= 0200;
- }
-#ifndef NOCSETS
- if (inesc == ES_NORMAL) {
-#ifdef UNICODE
- int x;
- if (unicode == 1) { /* Remote is UTF-8 */
- x = u_to_b((CHAR)c);
- if (x == -1)
- continue;
- else if (x == -2) { /* LS or PS */
- inxbuf[0] = CR;
- inxbuf[1] = LF;
- inxcount = 2;
- } else {
- inxbuf[0] = (unsigned)(x & 0xff);
- }
- c = inxbuf[0];
- } else if (unicode == 2) { /* Local is UTF-8 */
- inxcount =
- b_to_u((CHAR)c,inxbuf,OUTXBUFSIZ,tcssize);
- c = inxbuf[0];
- } else {
-#endif /* UNICODE */
- if (sxi) c = (*sxi)((CHAR)c);
- if (rxi) c = (*rxi)((CHAR)c);
- inxbuf[0] = c;
-#ifdef UNICODE
- }
-#endif /* UNICODE */
- }
-#endif /* NOCSETS */
- c &= cmdmsk; /* Apply command mask. */
- conoc(c); /* Output to screen */
- if (seslog && !sessft) /* and session log */
- logchar(c);
- }
- } else { /* All at once */
- for (i = 1; i < ibufl; i++)
- x25ibuf[i] &= (cmask & cmdmsk);
- conxo(ibufl,x25ibuf);
- if (seslog) zsoutx(ZSFILE,x25ibuf,ibufl);
- }
- }
- continue;
-
- } else { /* Not X.25... */
-#endif /* ANYX25 */
-/*
- Get the next communication line character from our internal buffer.
- If the buffer is empty, refill it.
-*/
- prev = c; /* Remember previous character */
- c = ckcgetc(0); /* Get next character */
- /* debug(F101,"CONNECT c","",c); */
- if (c < 0) { /* Failed... */
- debug(F101,"CONNECT disconnect ibc","",ibc);
- debug(F101,"CONNECT disconnect obc","",obc);
- ckcputf(); /* Flush CONNECT output buffer */
- if (!quiet) {
- printf("\r\nCommunications disconnect ");
-#ifdef COMMENT
- if ( c == -3
-#ifdef ultrix
-/* This happens on Ultrix if there's no carrier */
- && errno != EIO
-#endif /* ultrix */
-#ifdef UTEK
-/* This happens on UTEK if there's no carrier */
- && errno != EWOULDBLOCK
-#endif /* UTEK */
- )
- perror("\r\nCan't read character");
-#endif /* COMMENT */
- }
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
- tthang(); /* Hang up the connection */
- debug(F111,"CONNECT concld i/o error",ck_errstr(),errno);
- pipemsg(CEV_HUP);
- ck_sndmsg(); /* Wait to be killed */
- }
-#ifdef COMMENT
-/* too much... */
- debug(F101,"CONNECT ** PORT","",c); /* Got character c OK. */
-#endif /* COMMENT */
-#ifdef TNCODE
- /* Handle TELNET negotiations... */
-
- if ((c == NUL) && network && IS_TELNET()) {
- if (prev == CR) /* Discard <NUL> of <CR><NUL> */
- if (!TELOPT_U(TELOPT_BINARY))
- continue;
- }
- if ((c == IAC) && network && IS_TELNET()) {
- int me_bin = TELOPT_ME(TELOPT_BINARY);
- int u_bin = TELOPT_U(TELOPT_BINARY);
- debug(F100,"CONNECT got IAC","",0);
- ckcputf(); /* Dump screen-output buffer */
- if ((tx = tn_doop((CHAR)(c & 0xff),duplex,ckcgetc)) == 0) {
- if (me_bin != TELOPT_ME(TELOPT_BINARY)) {
- debug(F101,
- "CONNECT TELNET me_bin",
- "",
- TELOPT_ME(TELOPT_BINARY)
- );
- pipemsg(CEV_MEBIN); /* Tell parent */
- write(xpipe[1],
- &TELOPT_ME(TELOPT_BINARY),
- sizeof(TELOPT_ME(TELOPT_BINARY))
- );
- ck_sndmsg(); /* Tell the parent fork */
- } else if (u_bin != TELOPT_U(TELOPT_BINARY)) {
- debug(F101,
- "CONNECT TELNET u_bin",
- "",
- TELOPT_U(TELOPT_BINARY)
- );
- pipemsg(CEV_UBIN); /* Tell parent */
- write(xpipe[1],
- &TELOPT_U(TELOPT_BINARY),
- sizeof(TELOPT_U(TELOPT_BINARY))
- );
- ck_sndmsg(); /* Tell the parent fork */
- }
- continue;
- } else if (tx == -1) { /* I/O error */
- if (!quiet)
- printf("\r\nCommunications disconnect ");
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
- dologend();
- debug(F111,"CONNECT concld i/o error 2",ck_errstr(),errno);
- pipemsg(CEV_HUP);
- ck_sndmsg(); /* Wait to be killed */
- /* NOTREACHED */
- } else if (tx == -3) { /* I/O error */
- if (!quiet)
- printf("\r\nConnection closed due to telnet policy ");
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
- dologend();
- debug(F111,"CONNECT concld i/o error 2",ck_errstr(),errno);
- pipemsg(CEV_HUP);
- ck_sndmsg(); /* Wait to be killed */
- /* NOTREACHED */
- } else if (tx == -2) { /* I/O error */
- if (!quiet)
- printf("\r\nConnection closed by peer ");
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
- dologend();
- debug(F111,"CONNECT concld i/o error 2",ck_errstr(),errno);
- pipemsg(CEV_HUP);
- ck_sndmsg(); /* Wait to be killed */
- /* NOTREACHED */
- } else if ((tx == 1) && (!duplex)) { /* ECHO change */
- duplex = 1; /* Turn on local echo */
- debug(F101,"CONNECT TELNET duplex change","",duplex);
- pipemsg(CEV_DUP); /* Tell parent */
- write(xpipe[1], &duplex, sizeof(duplex));
- ck_sndmsg(); /* Tell the parent fork */
- continue;
- } else if ((tx == 2) && (duplex)) { /* ECHO change */
- duplex = 0;
- debug(F101,"CONNECT TELNET duplex change","",duplex);
- pipemsg(CEV_DUP);
- write(xpipe[1], &duplex, sizeof(duplex));
- ck_sndmsg();
- continue;
- } else if (tx == 3) { /* Quoted IAC */
- c = parity ? 127 : 255;
- }
-#ifdef IKS_OPTION
- else if (tx == 4) { /* IKS State Change */
- if (TELOPT_SB(TELOPT_KERMIT).kermit.u_start &&
- !tcp_incoming
- ) {
- /* here we need to print a msg that the other */
- /* side is in SERVER mode and that REMOTE */
- /* commands should be used. And CONNECT mode */
- /* should be ended. */
- active = 0;
- }
- }
-#endif /* IKS_OPTION */
- else if (tx == 6) {
- /* DO LOGOUT received */
- if (!quiet)
- printf("\r\nRemote Logout ");
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
- debug(F100,"CONNECT Remote Logout","",0);
- pipemsg(CEV_HUP);
- ck_sndmsg(); /* Wait to be killed */
- /* NOTREACHED */
- } else
- continue; /* Negotiation OK, get next char. */
-
- } else if (parity)
- c &= 0x7f;
-
- if (TELOPT_ME(TELOPT_ECHO) && tn_rem_echo)
- ttoc(c); /* I'm echoing for the remote */
-#endif /* TNCODE */
-
- if (debses) { /* Output character to screen */
- char *s; /* Debugging display... */
- s = dbchr(c);
- while (*s)
- ckcputc(*s++);
- } else { /* Regular display ... */
- c &= cmask; /* Apply Kermit-to-remote mask */
-#ifdef CK_AUTODL
-/*
- Autodownload. Check for Kermit S packet prior to translation, since that
- can change the packet and make it unrecognizable (as when the terminal
- character set is an ISO 646 one)... Ditto for Zmodem start packet.
-*/
- if (autodl /* Autodownload enabled? */
-#ifdef IKS_OPTION
- || TELOPT_SB(TELOPT_KERMIT).kermit.me_start
-#endif /* IKS_OPTION */
- ) {
- int k;
- k = kstart((CHAR)c); /* Kermit S or I packet? */
-#ifdef CK_XYZ
- if (!k && zmdlok) /* Or an "sz" start? */
- k = zstart((CHAR)c);
-#endif /* CK_XYZ */
- if (k) {
- int ksign = 0;
- debug(F101,"CONNECT autodownload k","",k);
- if (k < 0) { /* Minus-Protocol? */
-#ifdef NOSERVER
- goto noserver; /* Need server mode for this */
-#else
- ksign = 1; /* Remember */
- k = 0 - k; /* Convert to actual protocol */
- justone = 1; /* Flag for protocol module */
-#endif /* NOSERVER */
- } else
- justone = 0;
- k--; /* Adjust [kz]start's return value */
- if (k == PROTO_K
-#ifdef CK_XYZ
- || k == PROTO_Z
-#endif /* CK_XYZ */
- ) {
-
- /* Now damage the packet so that it does not */
- /* trigger autodownload detection on subsquent */
- /* links. */
-
- if (k == PROTO_K) {
- int i, len = strlen((char*)ksbuf);
- for (i = 0; i < len; i++)
- ckcputc(BS);
- }
-#ifdef CK_XYZ
- else {
- int i;
- for (i = 0; i < 3; i++)
- ckcputc(CAN);
- }
-#endif /* CK_XYZ */
- /* Notify parent */
- pipemsg(justone ? CEV_AUL : CEV_ADL);
-/*
- Send our memory back up to the top fork thru the pipe.
- CAREFUL -- Write this stuff in the same order it is to be read!
-*/
- /* Copy our Kermit packet to the parent fork */
- n = (int) strlen((char *)ksbuf);
- write(xpipe[1], (char *)&n, sizeof(n));
- if (n > 0)
- write(xpipe[1], (char *)ksbuf, n+1);
- debug(F111,"CONNECT autodownload ksbuf",ksbuf,n);
- debug(F101,"CONNECT autodownload justone","",
- justone);
- /* Construct the APC command */
- sprintf(apcbuf,
- "set proto %s, %s, set proto %s",
- ptab[k].p_name,
- ksign ? "server" : "receive",
- ptab[protocol].p_name
- );
- apclength = strlen(apcbuf);
- debug(F111,"CONNECT ksbuf",ksbuf,k);
- debug(F110,"CONNECT autodownload",apcbuf,0);
- apcactive = APC_LOCAL;
- ckcputf(); /* Force screen update */
-
- /* Write buffer including trailing NUL byte */
- debug(F101,"CONNECT write xpipe apclength","",
- apclength);
- write(xpipe[1],
- (char *)&apclength,
- sizeof(apclength)
- );
- debug(F110,"CONNECT write xpipe apcbuf",apcbuf,0);
- write(xpipe[1], apcbuf, apclength+1);
-
- /* Copy our input buffer to the parent fork */
-
- debug(F101,"CONNECT autodownload complete ibc",
- "",ibc);
- debug(F101,"CONNECT autodownload complete obc",
- "",obc);
- write(xpipe[1], (char *)&ibc, sizeof(ibc));
- if (ibc > 0) {
- write(xpipe[1], (char *)&ibp, sizeof(ibp));
- write(xpipe[1], ibp, ibc);
- }
- ck_sndmsg(); /* Wait to be killed */
- /* NOTREACHED */
- }
- }
- }
-#ifdef NOSERVER
- noserver:
-#endif /* NOSERVER */
-#endif /* CK_AUTODL */
- if (sosi) { /* Handle SI/SO */
- if (c == SO) { /* Shift Out */
- inshift = 1;
- continue;
- } else if (c == SI) { /* Shift In */
- inshift = 0;
- continue;
- }
- if (inshift) c |= 0200;
- }
- inxbuf[0] = c; /* In case there is no translation */
- inxcount = 1; /* ... */
-#ifndef NOCSETS
- if (inesc == ES_NORMAL) { /* If not in an escape sequence */
-#ifdef UNICODE
- int x; /* Translate character sets */
- CHAR ch;
- ch = c;
- if (unicode == 1) { /* Remote is UTF-8 */
- x = u_to_b(ch);
- if (x < 0)
- continue;
- inxbuf[0] = (unsigned)(x & 0xff);
- c = inxbuf[0];
- } else if (unicode == 2) { /* Local is UTF-8 */
- inxcount = b_to_u(ch,inxbuf,OUTXBUFSIZ,tcssize);
- c = inxbuf[0];
- } else {
-#endif /* UNICODE */
- if (sxi) c = (*sxi)((CHAR)c);
- if (rxi) c = (*rxi)((CHAR)c);
- inxbuf[0] = c;
-#ifdef UNICODE
- }
-#endif /* UNICODE */
- }
-#endif /* NOCSETS */
-
-#ifndef NOESCSEQ
- if (escseq) /* If handling escape sequences */
- apcrc = chkaes((char)c); /* update our state */
-#ifdef CK_APC
-/*
- If we are handling APCs, we have several possibilities at this point:
- 1. Ordinary character to be written to the screen.
- 2. An Esc; we can't write it because it might be the beginning of an APC.
- 3. The character following an Esc, in which case we write Esc, then char,
- but only if we have not just entered an APC sequence.
-*/
- if (escseq && (apcstatus & APC_ON)) {
- if (inesc == ES_GOTESC) /* Don't write ESC yet */
- continue;
- else if (oldesc == ES_GOTESC && !apcactive) {
- ckcputc(ESC); /* Write saved ESC */
- if (seslog && !sessft)
- logchar((char)ESC);
- } else if (apcrc) { /* We have an APC */
- debug(F111,"CONNECT APC complete",apcbuf,apclength);
- ckcputf(); /* Force screen update */
- pipemsg(CEV_APC); /* Notify parent */
- write(xpipe[1],
- (char *)&apclength,
- sizeof(apclength)
- );
- /* Write buffer including trailing NUL byte */
-
- write(xpipe[1], apcbuf, apclength+1);
-
- /* Copy our input buffer to the parent fork */
-
- debug(F101,"CONNECT APC complete ibc","",ibc);
- debug(F101,"CONNECT APC complete obc","",obc);
- write(xpipe[1], (char *)&ibc, sizeof(ibc));
- if (ibc > 0) {
- write(xpipe[1], (char *)&ibp, sizeof(ibp));
- write(xpipe[1], ibp, ibc);
- }
- ck_sndmsg(); /* Wait to be killed */
- /* NOTREACHED */
- }
- }
-#endif /* CK_APC */
-#endif /* NOESCSEQ */
-
- for (i = 0; i < inxcount; i++) { /* Loop thru */
- c = inxbuf[i]; /* input expansion buffer... */
- if (
-#ifdef CK_APC
- !apcactive /* Ignore APC sequences */
-#else
- 1
-#endif /* CK_APC */
- ) {
- c &= cmdmsk; /* Apply command mask. */
- if (c == CR && tt_crd) { /* SET TERM CR-DISPLA CRLF? */
- ckcputc(c); /* Yes, output CR */
- if (seslog && !sessft)
- logchar((char)c);
- c = LF; /* and insert a linefeed */
- }
- if (c == LF && tt_lfd) { /* SET TERM CR-DISPLA CRLF? */
- ckcputc(CR); /* Yes, output CR */
- if (seslog && !sessft) logchar((char)CR);
- }
- ckcputc(c); /* Write character to screen */
- }
- if (seslog && !sessft) /* Handle session log */
- logchar((char)c);
-#ifdef CK_TRIGGER
- /* Check for trigger string */
- if (tt_trigger[0]) if ((ix = autoexitchk((CHAR)c)) > -1) {
- ckcputf(); /* Force screen update */
-#ifdef NOSETBUF
- fflush(stdout); /* I mean really force it */
-#endif /* NOSETBUF */
- pipemsg(CEV_TRI); /* Send up trigger indication */
- write(xpipe[1], (char *)&ix, sizeof(ix)); /* index */
- write(xpipe[1], (char *)&ibc, sizeof(ibc));
- if (ibc > 0) {
- write(xpipe[1], (char *)&ibp, sizeof(ibp));
- write(xpipe[1], ibp, ibc);
- }
- debug(F100,"CONNECT concld trigger","",0);
- ck_sndmsg(); /* Wait to be killed */
- active = 0; /* Shouldn't be necessary... */
- break;
- }
- /* NOTREACHED */
-#endif /* CK_TRIGGER */
- }
- }
-#ifdef ANYX25
- }
-#endif /* ANYX25 */
- }
-}
-
-
-/* C O N E C T -- Interactive terminal connection */
-
-int
-conect() {
- int n; /* General purpose counter */
- int i; /* For loops... */
- int c; /* c is a character, but must be signed
- integer to pass thru -1, which is the
- modem disconnection signal, and is
- different from the character 0377 */
- int c2; /* A copy of c */
- int csave; /* Another copy of c */
-#ifndef NOESCSEQ
- int apcrc;
-#endif /* NOESCSEQ */
-
- int conret = 0; /* Return value from conect() */
- int msgflg = 0;
- /* jbchksum = -1L; */
- jbset = 0; /* jmp_buf not set yet, don't use it */
- debok = 1;
-
- debug(F101,"CONNECT fork signal","",CK_FORK_SIG);
- debug(F101,"CONNECT entry pid","",pid);
-
- msgflg = !quiet
-#ifdef CK_APC
- && !apcactive
-#endif /* CK_APC */
- ;
-/*
- The following is to handle a fork left behind if we exit CONNECT mode
- without killing it, and then return to CONNECT mode. This happened in
- HP-UX, where the Reset key would raise SIGINT even though SIGINT was set to
- SIG_IGN. The code below fixes the symptom; the real fix is in the main
- SIGINT handler (if SIGINT shows up during CONNECT, just return rather than
- taking the longjmp).
-*/
- if (pid) { /* This should be 0 */
- int x = 0;
- debug(F101,"CONNECT entry killing stale pid","",pid);
- printf("WARNING: Old CONNECT fork seems to be active.\n");
- printf("Attempting to remove it...");
-#ifdef BEOSORBEBOX
- {
- long ret_val;
- x = kill(pid,SIGKILLTHR); /* Kill lower fork */
- wait_for_thread (pid, &ret_val);
- }
-#else
-#ifdef Plan9
- x = kill(pid,SIGKILL); /* Kill lower fork */
-#else
- x = kill(pid,9);
-#endif /* Plan9 */
-#endif /* BEOSORBEBOX */
- wait((WAIT_T *)0); /* Wait till gone. */
- if (x < 0) {
- printf("ERROR: Failure to kill pid %d: %s, errno=%d\n",
- (int) pid, ck_errstr(), errno);
- debug(F111,"CONNECT error killing stale pid",ck_errstr(),pid);
- }
- pid = (PID_T) 0;
- printf("\n");
- }
- signal(CK_FORK_SIG, SIG_IGN); /* Initial CK_FORK_SIG handling, */
-/*
- The following ttimoff() call should not be necessary, but evidently there
- are cases where a timer is left active and then goes off, taking a longjmp
- to nowhere after the program's stack has changed. In any case, this is
- safe because the CONNECT module uses no timer of any kind, and no other timer
- should be armed while Kermit is in CONNECT mode.
-*/
- ttimoff(); /* Turn off any timer interrupts */
-
-#ifdef CK_TRIGGER
- makestr(&triggerval,NULL); /* Reset trigger */
-#endif /* CK_TRIGGER */
-
- if (!local) {
-#ifdef NETCONN
- printf("Sorry, you must SET LINE or SET HOST first\n");
-#else
- printf("Sorry, you must SET LINE first\n");
-#endif /* NETCONN */
- goto conret0;
- }
- if (speed < 0L && network == 0 && ttfdflg == 0) {
- printf("Sorry, you must SET SPEED first\n");
- goto conret0;
- }
-#ifdef TCPSOCKET
- if (network && (nettype != NET_TCPB)
-#ifdef SUNX25
- && (nettype != NET_SX25)
-#endif /* SUNX25 */
-#ifdef IBMX25
- && (nettype != NET_IX25)
-#endif /* IBMX25 */
-#ifdef NETCMD
- && (nettype != NET_CMD)
-#endif /* NETCMD */
-#ifdef NETPTY
- && (nettype != NET_PTY)
-#endif /* NETPTY */
- ) {
- printf("Sorry, network type not supported\n");
- goto conret0;
- }
-#endif /* TCPSOCKET */
-
-#ifdef DYNAMIC
- if (!ibuf) {
- if (!(ibuf = malloc(IBUFL+1))) { /* Allocate input line buffer */
- printf("Sorry, CONNECT input buffer can't be allocated\n");
- goto conret0;
- } else {
- ibp = ibuf;
- ibc = 0;
- }
- }
- if (!obuf) {
- if (!(obuf = malloc(OBUFL+1))) { /* Allocate output line buffer */
- printf("Sorry, CONNECT output buffer can't be allocated\n");
- goto conret0;
- } else {
- obp = obuf;
- obc = 0;
- }
- }
- if (!kbuf) {
- if (!(kbuf = malloc(KBUFL+1))) { /* Allocate keyboard input buffer */
- printf("Sorry, CONNECT keyboard buffer can't be allocated\n");
- goto conret0;
- }
- }
- if (!temp) {
- if (!(temp = malloc(TMPLEN+1))) { /* Allocate temporary buffer */
- printf("Sorry, CONNECT temporary buffer can't be allocated\n");
- goto conret0;
- }
- }
-#else
-#ifdef COMMENT
- ibp = ibuf;
- ibc = 0;
-#endif /* COMMENT */
- obp = obuf;
- obc = 0;
-#endif /* DYNAMIC */
-
- kbp = kbuf; /* Always clear these. */
- *kbp = NUL; /* No need to preserve them between */
- kbc = 0; /* CONNECT sessions. */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"CONNECT conect entry ttyfd","",ttyfd);
- debug(F101,"CONNECT conect entry ibc","",ibc);
- debug(F101,"CONNECT conect entry obc","",obc);
- debug(F101,"CONNECT conect entry kbc","",kbc);
-#ifdef CK_TRIGGER
- debug(F110,"CONNECT conect trigger",tt_trigger[0],0);
-#endif /* CK_TRIGGER */
- if (ttyfd > -1) {
- n = ttchk();
- debug(F101,"CONNECT conect entry ttchk","",n);
- }
- }
-#endif /* DEBUG */
-
- if (ttyfd < 0) { /* If communication device not open */
- debug(F101,"CONNECT ttnproto","",ttnproto);
- debug(F111,"CONNECT opening",ttname,0); /* Open it now */
- if (ttopen(ttname,
- &local,
- network ? -nettype : mdmtyp,
- 0
- ) < 0) {
- ckmakmsg(temp,TMPLEN,"Sorry, can't open ",ttname,NULL,NULL);
- perror(temp);
- debug(F110,"CONNECT open failure",ttname,0);
- goto conret0;
- }
-#ifdef IKS_OPTION
- /* If peer is in Kermit server mode, return now. */
- if (TELOPT_SB(TELOPT_KERMIT).kermit.u_start)
- return(0);
-#endif /* IKS_OPTION */
- }
- dohangup = 0; /* Hangup not requested yet */
-#ifdef ANYX25
- dox25clr = 0; /* X.25 clear not requested yet */
-#endif /* ANYX25 */
-
- if (msgflg) {
-#ifdef NETCONN
- if (network) {
- if (ttpipe)
- printf("Connecting via command \"%s\"",ttname);
- else
- printf("Connecting to host %s",ttname);
-#ifdef ANYX25
- if (nettype == NET_SX25 || nettype == NET_IX25)
- printf(", Link ID %d, LCN %d",linkid,lcn);
-#endif /* ANYX25 */
- } else {
-#endif /* NETCONN */
- printf("Connecting to %s",ttname);
- if (speed > -1L) printf(", speed %ld",speed);
-#ifdef NETCONN
- }
-#endif /* NETCONN */
- if (tt_escape) {
- printf("\r\n");
- shoesc(escape);
- printf("Type the escape character followed by C to get back,\r\n");
- printf("or followed by ? to see other options.\r\n");
- } else {
- printf(".\r\n\nESCAPE CHARACTER IS DISABLED\r\n\n");
- }
- if (seslog) {
- extern int slogts;
- char * s = "";
- switch (sessft) {
- case XYFT_D:
- s = "debug"; break;
- case XYFT_T:
- s = slogts ? "timestamped-text" : "text"; break;
- default:
- s = "binary";
- }
- printf("Session Log: %s, %s\r\n",sesfil,s);
- }
- if (debses) printf("Debugging Display...)\r\n");
- printf("----------------------------------------------------\r\n");
- fflush(stdout);
- }
-
-/* Condition console terminal and communication line */
-
- if (conbin((char)escape) < 0) {
- printf("Sorry, can't condition console terminal\n");
- goto conret0;
- }
- debug(F101,"CONNECT cmask","",cmask);
- debug(F101,"CONNECT cmdmsk","",cmdmsk);
- debug(F101,"CONNECT speed before ttvt","",speed);
- if ((n = ttvt(speed,flow)) < 0) { /* Enter "virtual terminal" mode */
- if (!network) {
- debug(F101,"CONNECT ttvt","",n);
- tthang(); /* Hang up and close the device. */
- ttclos(0);
- dologend();
- if (ttopen(ttname, /* Open it again... */
- &local,
- network ? -nettype : mdmtyp,
- 0
- ) < 0) {
- ckmakmsg(temp,TMPLEN,"Sorry, can't reopen ",ttname,NULL,NULL);
- perror(temp);
- goto conret0;
- }
-#ifdef IKS_OPTION
- if (TELOPT_SB(TELOPT_KERMIT).kermit.u_start)
- return(0);
-#endif /* IKS_OPTION */
- if (ttvt(speed,flow) < 0) { /* Try virtual terminal mode again. */
- conres(); /* Failure this time is fatal. */
- printf("Sorry, Can't condition communication line\n");
- goto conret0;
- }
- }
- }
- debug(F101,"CONNECT ttvt ok, escape","",escape);
-
- debug(F101,"CONNECT carrier-watch","",carrier);
- if ((!network
-#ifdef TN_COMPORT
- || istncomport()
-#endif /* TN_COMPORT */
- ) && (carrier != CAR_OFF)) {
- int x;
- x = ttgmdm();
- debug(F100,"CONNECT ttgmdm","",x);
- if ((x > -1) && !(x & BM_DCD)) {
-#ifndef NOHINTS
- extern int hints;
-#endif /* NOHINTS */
- debug(F100,"CONNECT ttgmdm CD test fails","",x);
- conres();
- printf("?Carrier required but not detected.\n");
-#ifndef NOHINTS
- if (!hints)
- return(0);
- printf("***********************************\n");
- printf(" Hint: To CONNECT to a serial device that\n");
- printf(" is not presenting the Carrier Detect signal,\n");
- printf(" first tell C-Kermit to:\n\n");
- printf(" SET CARRIER-WATCH OFF\n\n");
- printf("***********************************\n\n");
-#endif /* NOHINTS */
- goto conret0;
- }
- debug(F100,"CONNECT ttgmdm ok","",0);
- }
-#ifndef NOCSETS
-/* Set up character set translations */
-
- unicode = 0; /* Assume Unicode won't be involved */
- tcs = 0; /* "Transfer" or "Other" charset */
- sxo = rxo = NULL; /* Initialize byte-to-byte functions */
- sxi = rxi = NULL;
- if (tcsr != tcsl) { /* Remote and local sets differ... */
-#ifdef UNICODE
- if (tcsr == FC_UTF8 || /* Remote charset is UTF-8 */
- tcsl == FC_UTF8) { /* or local one is. */
- xuf = xl_ufc[tcsl]; /* Incoming Unicode to local */
- if (xuf || tcsl == FC_UTF8) {
- tcs = (tcsr == FC_UTF8) ? tcsl : tcsr; /* The "other" set */
- xfu = xl_fcu[tcs]; /* Local byte to remote Unicode */
- if (xfu)
- unicode = (tcsr == FC_UTF8) ? 1 : 2;
- }
- tcssize = fcsinfo[tcs].size; /* Size of other character set. */
- } else {
-#endif /* UNICODE */
- tcs = gettcs(tcsr,tcsl); /* Get intermediate set. */
- sxo = xls[tcs][tcsl]; /* translation function */
- rxo = xlr[tcs][tcsr]; /* pointers for output functions */
- sxi = xls[tcs][tcsr]; /* and for input functions. */
- rxi = xlr[tcs][tcsl];
-#ifdef UNICODE
- }
-#endif /* UNICODE */
- }
-/*
- This is to prevent use of zmstuff() and zdstuff() by translation functions.
- They only work with disk i/o, not with communication i/o. Luckily Russian
- translation functions don't do any stuffing...
-*/
- langsv = language;
-#ifndef NOCYRIL
- if (language != L_RUSSIAN)
-#endif /* NOCYRIL */
- language = L_USASCII;
-
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"CONNECT tcs","",tcs);
- debug(F101,"CONNECT tcsl","",tcsl);
- debug(F101,"CONNECT tcsr","",tcsr);
- debug(F101,"CONNECT fcsinfo[tcsl].size","",fcsinfo[tcsl].size);
- debug(F101,"CONNECT fcsinfo[tcsr].size","",fcsinfo[tcsr].size);
- debug(F101,"CONNECT unicode","",unicode);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
-
-#ifdef CK_XYZ
-#ifndef XYZ_INTERNAL
- {
- extern int binary; /* See about ZMODEM autodownloads */
- char * s;
- s = binary ? ptab[PROTO_Z].p_b_rcmd : ptab[PROTO_Z].p_t_rcmd;
- if (!s) s = "";
- zmdlok = (*s != NUL); /* OK if we have external commands */
- }
-#endif /* XYZ_INTERNAL */
-#endif /* CK_XYZ */
-
-#ifndef NOESCSEQ
-/*
- We need to activate the escape-sequence recognition feature when:
- (a) translation is elected, AND
- (b) the local and/or remote set is a 7-bit set other than US ASCII.
- Or:
- SET TERMINAL APC is not OFF (handled in the next statement).
-*/
- escseq = (tcs != TC_TRANSP) && /* Not transparent */
- (fcsinfo[tcsl].size == 128 || fcsinfo[tcsr].size == 128) && /* 7 bits */
- (fcsinfo[tcsl].code != FC_USASCII); /* But not ASCII */
-#endif /* NOESCSEQ */
-#endif /* NOCSETS */
-
-#ifndef NOESCSEQ
-#ifdef CK_APC
- escseq = escseq || (apcstatus & APC_ON);
- apcactive = 0; /* An APC command is not active */
- apclength = 0; /* ... */
-#endif /* CK_APC */
- inesc = ES_NORMAL; /* Initial state of recognizer */
- debug(F101,"CONNECT escseq","",escseq);
-#endif /* NOESCSEQ */
-
- parent_id = getpid(); /* Get parent's pid for signalling */
- debug(F101,"CONNECT parent pid","",parent_id);
-
- if (xpipe[0] > -1) /* If old pipe hanging around, close */
- close(xpipe[0]);
- xpipe[0] = -1;
- if (xpipe[1] > -1)
- close(xpipe[1]);
- xpipe[1] = -1;
- goterr = 0; /* Error flag for pipe & fork */
- if (pipe(xpipe) != 0) { /* Create new pipe to pass info */
- perror("Can't make pipe"); /* between forks. */
- debug(F101,"CONNECT pipe error","",errno);
- goterr = 1;
- } else
-#ifdef BEOSORBEBOX
- {
- pid = spawn_thread(concld, "Lower Fork", B_NORMAL_PRIORITY, NULL);
- resume_thread(pid);
- }
-#else
- if ((pid = fork()) == (PID_T) -1) { /* Pipe OK, make port fork. */
- perror("Can't make port fork");
- debug(F101,"CONNECT fork error","",errno);
- goterr = 1;
- }
-#endif /* BEOSORBEBOX */
- debug(F101,"CONNECT created fork, pid","",pid);
- if (goterr) { /* Failed to make pipe or fork */
- conres(); /* Reset the console. */
- if (msgflg) {
- printf("\r\nCommunications disconnect (Back at %s)\r\n",
- *myhost ?
- myhost :
-#ifdef UNIX
- "local UNIX system"
-#else
- "local system"
-#endif /* UNIX */
- );
- }
- printf("\n");
- what = W_NOTHING; /* So console modes are set right. */
-#ifndef NOCSETS
- language = langsv; /* Restore language */
-#endif /* NOCSETS */
- parent_id = (PID_T) 0; /* Clean up */
- goto conret1;
- }
- debug(F101,"CONNECT fork pid","",pid);
-
-/* Upper fork (KEYB fork) reads keystrokes and sends them out. */
-
- if (pid) { /* pid != 0, so I am the upper fork. */
-/*
- Before doing anything significant, the child fork must wait for a go-ahead
- character from xpipe[0]. Before starting to wait, we have enough time to
- clear buffers and set up the signal handler. When done with this, we will
- allow the child to continue by satisfying its pending read.
-
- Remember the child and parent have separate address space. The child has
- its own copy of input buffers, so we must clear the input buffers in the
- parent. Otherwise strange effects may occur, like chunks of characters
- repeatedly echoed on terminal screen. The child process is designed to
- empty its input buffers by reading all available characters and either
- echoing them on the terminal screen or saving them for future use in the
- parent. The latter case happens during APC processing - see the code around
- CEV_APC occurrences to see how the child passes its ibuf etc to parent via
- xpipe, for preservation until the next entry to this module, to ensure that
- no characters are lost between CONNECT sessions.
-*/
-
-/*
- This one needs a bit of extra explanation... In addition to the CONNECT
- module's own buffers, which are communicated and synchronized via xpipe,
- the low-level UNIX communication routines (ttinc, ttxin, etc) are also
- buffered, statically, in the ckutio.c module. But when the two CONNECT
- forks split off, the lower fork is updating this buffer's pointers and
- counts, but the upper fork never finds out about it and still has the old
- ones. The following UNIX-specific call to the ckutio.c module takes care
- of this... Without it, we get dual echoing of incoming characters.
-*/
- ttflux();
-/*
- At this point, perhaps you are wondering why we use forks at all. It is
- simply because there is no other method portable among all UNIX variations.
- Not threads, not select(), ... (Yes, select() is more common now; it might
- actually be worth writing a variation of this module that works like BSD
- Telnet, one fork, driven by select()).
-*/
- ibp = ibuf; /* Clear ibuf[]. */
- ibc = 0; /* Child now has its own copy */
- signal(CK_FORK_SIG, pipeint); /* Handler for messages from child. */
- write(xpipe[1], ibuf, 1); /* Allow child to proceed */
- close(xpipe[1]); xpipe[1] = -1; /* Parent - prevent future writes */
-
- what = W_CONNECT; /* Keep track of what we're doing */
- active = 1;
- debug(F101,"CONNECT keyboard fork duplex","",duplex);
-/*
- Catch communication errors or mode changes in lower fork.
-
- Note: Some C compilers (e.g. Cray UNICOS) interpret the ANSI C standard
- about setjmp() in a way that disallows constructions like:
-
- if ((var = [sig]setjmp(env)) == 0) ...
-
- which prevents the value returned by cklongjmp() from being used at all.
- So the signal handlers set a global variable, sjval, instead.
-*/
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(con_env,1)
-#else
- setjmp(con_env)
-#endif /* CK_POSIX_SIG */
- == 0) { /* Normal entry... */
- jbset = 1; /* Now we have a longjmp buffer */
- sjval = CEV_NO; /* Initialize setjmp return code. */
-
- debug(F101,"CONNECT setjmp normal entry","",sjval);
-
-#ifdef ANYX25
- if (network && (nettype == NET_SX25 || nettype == NET_IX25)) {
- obufl = 0;
- bzero (x25obuf,sizeof(x25obuf));
- }
-#endif /* ANYX25 */
-/*
- Here is the big loop that gets characters from the keyboard and sends them
- out the communication device. There are two components to the communication
- path: the connection from the keyboard to C-Kermit, and from C-Kermit to
- the remote computer. The treatment of the 8th bit of keyboard characters
- is governed by SET COMMAND BYTESIZE (cmdmsk). The treatment of the 8th bit
- of characters sent to the remote is governed by SET TERMINAL BYTESIZE
- (cmask). This distinction was introduced in edit 5A(164).
-*/
- while (active) {
-#ifndef NOSETKEY
- if (kmptr) { /* Have current macro? */
- debug(F100,"CONNECT kmptr non NULL","",0);
- if ((c = (CHAR) *kmptr++) == NUL) { /* Get char from it */
- kmptr = NULL; /* If no more chars, */
- debug(F100,"CONNECT macro empty, continuing","",0);
- continue; /* reset pointer and continue */
- }
- debug(F000,"CONNECT char from macro","",c);
- } else /* No macro... */
-#endif /* NOSETKEY */
- c = CONGKS(); /* Read from keyboard */
-
-#ifdef COMMENT
-/* too much... */
- debug(F101,"CONNECT ** KEYB","",c);
-#endif /* COMMENT */
- if (c == -1) { /* If read() got an error... */
- debug(F101,"CONNECT keyboard read errno","",errno);
-#ifdef COMMENT
-/*
- This seems to cause problems. If read() returns -1, the signal has already
- been delivered, and nothing will wake up the pause().
-*/
- pause(); /* Wait for transmitter to finish. */
-#else
-#ifdef A986
-/*
- On Altos machines with Xenix 3.0, pressing DEL in connect mode brings us
- here (reason unknown). The console line discipline at this point has
- intr = ^C. The communications tty has intr = DEL but we get here after
- pressing DEL on the keyboard, even when the remote system has been set not
- to echo. With A986 defined, we stay in the read loop and beep only if the
- offending character is not DEL.
-*/
- if ((c & 127) != 127) conoc(BEL);
-#else
-#ifdef EINTR
-/*
- This can be caused by the other fork signalling this one about
- an echoing change during TELNET negotiations.
-*/
- if (errno == EINTR)
- continue;
-#endif /* EINTR */
- conoc(BEL); /* Otherwise, beep */
- active = 0; /* and terminate the read loop */
- continue;
-#endif /* A986 */
-#endif /* COMMENT */
- }
- c &= cmdmsk; /* Do any requested masking */
-#ifndef NOSETKEY
-/*
- Note: kmptr is NULL if we got character c from the keyboard, and it is
- not NULL if it came from a macro. In the latter case, we must avoid
- expanding it again.
-*/
- if (!kmptr && macrotab[c]) { /* Macro definition for c? */
- kmptr = macrotab[c]; /* Yes, set up macro pointer */
- continue; /* and restart the loop, */
- } else c = keymap[c]; /* else use single-char keymap */
-#endif /* NOSETKEY */
- if (
-#ifndef NOSETKEY
- !kmptr &&
-#endif /* NOSETKEY */
- (tt_escape && (c & 0xff) == escape)) { /* Escape char? */
- debug(F000,"CONNECT got escape","",c);
- c = CONGKS() & 0177; /* Got esc, get its arg */
- /* No key mapping here */
- doesc((char) c); /* Now process it */
-
- } else { /* It's not the escape character */
- csave = c; /* Save it before translation */
- /* for local echoing. */
-#ifndef NOCSETS
- if (inesc == ES_NORMAL) { /* If not inside escape seq.. */
- /* Translate character sets */
-#ifdef UNICODE
- int x;
- CHAR ch;
- ch = c;
- if (unicode == 1) { /* Remote is UTF-8 */
- outxcount = b_to_u(ch,outxbuf,OUTXBUFSIZ,tcssize);
- outxbuf[outxcount] = NUL;
- } else if (unicode == 2) { /* Local is UTF-8 */
- x = u_to_b(ch); /* So translate to remote byte */
- if (x < 0)
- continue;
- outxbuf[0] = (unsigned)(x & 0xff);
- outxcount = 1;
- outxbuf[outxcount] = NUL;
- } else {
-#endif /* UNICODE */
- /* Local-to-intermediate */
- if (sxo) c = (*sxo)((char)c);
- /* Intermediate-to-remote */
- if (rxo) c = (*rxo)((char)c);
- outxbuf[0] = c;
- outxcount = 1;
- outxbuf[outxcount] = NUL;
-#ifdef UNICODE
- }
-#endif /* UNICODE */
- }
- if (escseq)
- apcrc = chkaes((char)c);
-#else
- outxbuf[0] = c;
- outxcount = 1;
- outxbuf[outxcount] = NUL;
-#endif /* NOCSETS */
- for (i = 0; i < outxcount; i++) {
- c = outxbuf[i];
-/*
- If Shift-In/Shift-Out is selected and we have a 7-bit connection,
- handle shifting here.
-*/
- if (sosi) { /* Shift-In/Out selected? */
- if (cmask == 0177) { /* In 7-bit environment? */
- if (c & 0200) { /* 8-bit character? */
- if (outshift == 0) { /* If not shifted, */
- ttoc(dopar(SO)); /* shift. */
- outshift = 1;
- }
- } else {
- if (outshift == 1) { /* 7-bit character */
- ttoc(dopar(SI)); /* If shifted, */
- outshift = 0; /* unshift. */
- }
- }
- }
- if (c == SO) outshift = 1; /* User typed SO */
- if (c == SI) outshift = 0; /* User typed SI */
- }
- c &= cmask; /* Apply Kermit-to-host mask now. */
-#ifdef SUNX25
- if (network && nettype == NET_SX25) {
- if (padparms[PAD_ECHO]) {
- if (debses)
- conol(dbchr(c)) ;
- else
- if ((c != padparms[PAD_CHAR_DELETE_CHAR]) &&
- (c != padparms[PAD_BUFFER_DELETE_CHAR]) &&
- (c != padparms[PAD_BUFFER_DISPLAY_CHAR]))
- conoc(c) ;
- if (seslog && !sessft)
- logchar(c);
- }
- if (c == CR && (padparms[PAD_LF_AFTER_CR] == 4 ||
- padparms[PAD_LF_AFTER_CR] == 5)) {
- if (debses)
- conol(dbchr(LF)) ;
- else
- conoc(LF) ;
- if (seslog && !sessft)
- logchar(LF);
- }
- if (c == padparms[PAD_BREAK_CHARACTER]) {
- breakact();
- } else if (padparms[PAD_DATA_FORWARD_TIMEOUT]) {
- tosend = 1;
- x25obuf [obufl++] = c;
- } else if (((c == padparms[PAD_CHAR_DELETE_CHAR])||
- (c == padparms[PAD_BUFFER_DELETE_CHAR]) ||
- (c == padparms[PAD_BUFFER_DISPLAY_CHAR]))
- && (padparms[PAD_EDITING])) {
- if (c == padparms[PAD_CHAR_DELETE_CHAR]) {
- if (obufl > 0) {
- conol("\b \b"); obufl--;
- } else {}
- } else if
- (c == padparms[PAD_BUFFER_DELETE_CHAR]) {
- conol ("\r\nPAD Buffer Deleted\r\n");
- obufl = 0;
- } else if
- (c==padparms[PAD_BUFFER_DISPLAY_CHAR]) {
- conol("\r\n");
- conol(x25obuf);
- conol("\r\n");
- } else {}
- } else {
- x25obuf [obufl++] = c;
- if (obufl == MAXOX25) tosend = 1;
- else if (c == CR) tosend = 1;
- }
- if (tosend) {
- if (ttol((CHAR *)x25obuf,obufl) < 0) {
- perror ("\r\nCan't send characters");
- active = 0;
- } else {
- bzero (x25obuf,sizeof(x25obuf));
- obufl = 0;
- tosend = 0;
- }
- } else {};
- } else {
-#endif /* SUNX25 */
- if (c == '\015') { /* Carriage Return */
- int stuff = -1;
- if (tnlm) { /* TERMINAL NEWLINE ON */
- stuff = LF; /* Stuff LF */
-#ifdef TNCODE
- } else if (network && /* TELNET NEWLINE */
- IS_TELNET()) {
- switch (!TELOPT_ME(TELOPT_BINARY) ?
- tn_nlm :
- tn_b_nlm
- ) {
- case TNL_CRLF:
- stuff = LF;
- break;
- case TNL_CRNUL:
- stuff = NUL;
- break;
- }
-#endif /* TNCODE */
- }
- if (stuff > -1) {
- ttoc(dopar('\015')); /* Send CR */
- if (duplex) conoc('\015'); /* Echo CR */
- c = stuff; /* Char to stuff */
- csave = c;
- }
- }
-#ifdef TNCODE
-/* If user types the 0xff character (TELNET IAC), it must be doubled. */
- else /* Not CR */
- if ((dopar((CHAR) c) == IAC) && /* IAC (0xff) */
- network && IS_TELNET()) {
- /* Send one copy now */
- /* and the other one just below. */
- ttoc((char)IAC);
- }
-#endif /* TNCODE */
- /* Send the character */
-
- if (ttoc((char)dopar((CHAR) c)) > -1) {
- if (duplex) { /* If half duplex, must echo */
- if (debses)
- conol(dbchr(csave)); /* original char */
- else /* not the translated one */
- conoc((char)csave);
- if (seslog) { /* And maybe log it too */
- c2 = csave;
- if (sessft == 0 && csave == '\r')
- c2 = '\n';
- logchar((char)c2);
- }
- }
- } else {
- perror("\r\nCan't send character");
- active = 0;
- }
-#ifdef SUNX25
- }
-#endif /* SUNX25 */
- } /* for... */
- }
- }
-
- /* now active == 0 */
- signal(CK_FORK_SIG, SIG_IGN); /* Turn off CK_FORK_SIG */
- sjval = CEV_NO; /* Set to hangup */
- } /* Come here on termination of child */
-
-/* cklongjmp() executed in pipeint() (parent only!) comes here */
-
-/*
- Now the child fork is gone or is waiting for CK_FORK_SIG in ck_sndmsg().
- So we can't get (in the parent) any subsequent CK_FORK_SIG signals until
- we signal the child with CK_FORK_SIG.
-*/
- debug(F100,"CONNECT signaling port fork","",0);
- signal(CK_FORK_SIG, SIG_IGN); /* Turn this off */
- debug(F101,"CONNECT killing port fork","",pid);
- if (pid) {
- int x = 0;
-#ifdef BEOSORBEBOX
- {
- long ret_val;
- x = kill(pid,SIGKILLTHR); /* Kill lower fork */
- wait_for_thread(pid, &ret_val);
- }
-#else
-#ifdef Plan9
- x = kill(pid,SIGKILL); /* Kill lower fork */
-#else
- x = kill(pid,9);
-#endif /* Plan9 */
-#endif /* BEOSORBEBOX */
- wait((WAIT_T *)0); /* Wait till gone. */
- if (x < 0) {
- printf("WARNING: Failure to kill fork, pid %d: %s, errno=%d\n",
- (int) pid, ck_errstr(), errno);
- debug(F111,"CONNECT error killing pid",ck_errstr(),errno);
- }
- debug(F101,"CONNECT killed port fork","",pid);
- pid = (PID_T) 0;
- }
- if (sjval == CEV_HUP) { /* Read error on comm device */
- dohangup = 1; /* so we want to hang up our side */
-#ifdef NETCONN
- if (network) { /* and/or close network connection */
- ttclos(0);
- dologend();
-#ifdef SUNX25
- if (nettype == NET_SX25) /* If X.25, restore the PAD params */
- initpad();
-#endif /* SUNX25 */
- }
-#endif /* NETCONN */
- }
-#ifdef CK_APC
- if (sjval == CEV_APC) { /* Application Program Command rec'd */
- apcactive = APC_REMOTE; /* Flag APC as active */
- active = 0; /* Flag CONNECT as inactive */
- }
-#endif /* CK_APC */
- conres(); /* Reset the console. */
- if (dohangup > 0) { /* If hangup requested, do that. */
-#ifndef NODIAL
- if (dohangup > 1) /* User asked for it */
- if (mdmhup() < 1) /* Maybe hang up via modem */
-#endif /* NODIAL */
- tthang(); /* And make sure we don't hang up */
- dohangup = 0; /* again unless requested again. */
- }
-
-#ifdef COMMENT
-#ifdef NETCONN
-#ifdef SIGPIPE
- if (network && sigpiph) /* Restore previous SIGPIPE handler */
- (VOID) signal(SIGPIPE, sigpiph);
-#endif /* SIGPIPE */
-#endif /* NETCONN */
-#endif /* COMMENT */
-
-#ifdef ANYX25
- if (dox25clr) { /* If X.25 Clear requested */
- x25clear(); /* do that. */
-#ifndef IBMX25
- initpad();
-#endif /* IBMX25 */
- dox25clr = 0; /* But only once. */
- }
-#endif /* ANYX25 */
-
- if (quitnow) doexit(GOOD_EXIT,xitsta); /* Exit now if requested. */
- if (msgflg)
- printf("(Back at %s)", *myhost ? myhost : "local UNIX system");
-#ifdef CK_APC
- if (!apcactive)
-#endif /* CK_APC */
- printf("\n");
- what = W_NOTHING; /* So console modes set right. */
-#ifndef NOCSETS
- language = langsv; /* Restore language */
-#endif /* NOCSETS */
- parent_id = (PID_T) 0;
- goto conret1;
-
- }
-#ifndef BEOSORBEBOX
- else { /* *** */ /* Inferior reads, prints port input */
- concld(/* (void *)&pid */);
- }
-#endif /* BEOSORBEBOX */
-
-conret1:
- conret = 1;
-conret0:
- signal(CK_FORK_SIG, SIG_IGN); /* In case this wasn't done already */
- debug(F101,"CONNECT conect exit ibc","",ibc);
- debug(F101,"CONNECT conect exit obc","",obc);
- close(xpipe[0]); xpipe[0] = -1; /* Close the pipe */
- close(xpipe[1]); xpipe[1] = -1;
- if (msgflg) {
-#ifdef CK_APC
- if (apcactive == APC_LOCAL)
- printf("\n");
-#endif /* CK_APC */
- printf("----------------------------------------------------\r\n");
- }
- fflush(stdout);
- return(conret);
-}
-
-
-/* H C O N N E -- Give help message for connect. */
-
-int
-hconne() {
- int c;
- static char *hlpmsg[] = {
-"\r\n ? for this message",
-"\r\n 0 (zero) to send a null",
-"\r\n B to send a BREAK",
-#ifdef CK_LBRK
-"\r\n L to send a Long BREAK",
-#endif /* CK_LBRK */
-#ifdef NETCONN
-"\r\n I to send a network interrupt packet",
-#ifdef TCPSOCKET
-"\r\n A to send Are You There?",
-#endif /* TCPSOCKET */
-#ifdef ANYX25
-"\r\n R to reset X.25 virtual circuit",
-#endif /* ANYX25 */
-#endif /* NETCONN */
-"\r\n U to hangup and close the connection",
-"\r\n Q to hangup and quit Kermit",
-"\r\n S for status",
-#ifdef NOPUSH
-"\r\n ! to push to local shell (disabled)",
-"\r\n Z to suspend (disabled)",
-#else
-"\r\n ! to push to local shell",
-#ifdef NOJC
-"\r\n Z to suspend (disabled)",
-#else
-"\r\n Z to suspend",
-#endif /* NOJC */
-#endif /* NOPUSH */
-"\r\n \\ backslash code:",
-"\r\n \\nnn decimal character code",
-"\r\n \\Onnn octal character code",
-"\r\n \\Xhh hexadecimal character code",
-"\r\n terminate with carriage return.",
-"\r\n Type the escape character again to send the escape character, or",
-"\r\n press the space-bar to resume the CONNECT command.\r\n",
-"" };
-
- conol("\r\n----------------------------------------------------");
- conol("\r\nPress C to return to ");
- conol(*myhost ? myhost : "the C-Kermit prompt");
- conol(", or:");
- conola(hlpmsg); /* Print the help message. */
- conol("Command>"); /* Prompt for command. */
- c = CONGKS() & 0177; /* Get character, strip any parity. */
- /* No key mapping or translation here */
- if (c != CMDQ)
- conoll("");
- conoll("----------------------------------------------------");
- return(c); /* Return it. */
-}
-
-
-/* D O E S C -- Process an escape character argument */
-
-VOID
-#ifdef CK_ANSIC
-doesc(char c)
-#else
-doesc(c) char c;
-#endif /* CK_ANSIC */
-/* doesc */ {
- CHAR d;
-
- debug(F101,"CONNECT doesc","",c);
- while (1) {
- if (c == escape) { /* Send escape character */
- d = dopar((CHAR) c); ttoc((char) d); return;
- } else /* Or else look it up below. */
- if (isupper(c)) c = tolower(c);
-
- switch(c) {
-
- case 'c': /* Escape back to prompt */
- case '\03':
- active = 0; conol("\r\n"); return;
-
- case 'b': /* Send a BREAK signal */
- case '\02':
- ttsndb(); return;
-
-#ifdef NETCONN
- case 'i': /* Send Interrupt */
- case '\011':
-#ifdef TCPSOCKET
-#ifndef IP
-#define IP 244
-#endif /* IP */
- if (network && IS_TELNET()) { /* TELNET */
- temp[0] = (CHAR) IAC; /* I Am a Command */
- temp[1] = (CHAR) IP; /* Interrupt Process */
- temp[2] = NUL;
- ttol((CHAR *)temp,2);
- } else
-#endif /* TCPSOCKET */
-#ifdef SUNX25
- if (network && (nettype == NET_SX25)) {
- (VOID) x25intr(0); /* X.25 interrupt packet */
- conol("\r\n");
- } else
-#endif /* SUNX25 */
- conoc(BEL);
- return;
-
-#ifdef TCPSOCKET
- case 'a': /* "Are You There?" */
- case '\01':
-#ifndef AYT
-#define AYT 246
-#endif /* AYT */
- if (network && IS_TELNET()) {
- temp[0] = (CHAR) IAC; /* I Am a Command */
- temp[1] = (CHAR) AYT; /* Are You There? */
- temp[2] = NUL;
- ttol((CHAR *)temp,2);
- } else conoc(BEL);
- return;
-#endif /* TCPSOCKET */
-#endif /* NETCONN */
-
-#ifdef CK_LBRK
- case 'l': /* Send a Long BREAK signal */
- ttsndlb(); return;
-#endif /* CK_LBRK */
-
- case 'u': /* Hangup */
- /* case '\010': */ /* No, too dangerous */
-#ifdef ANYX25
- if (network && (nettype == NET_SX25 || nettype == NET_IX25))
- dox25clr = 1;
- else
-#endif /* ANYX25 */
- dohangup = 2; active = 0; conol("\r\nHanging up "); return;
-
-#ifdef ANYX25
- case 'r': /* Reset the X.25 virtual circuit */
- case '\022':
- if (network && (nettype == NET_SX25 || nettype == NET_IX25))
- (VOID) x25reset(0,0);
- conol("\r\n");
- return;
-#endif /* ANYX25 */
-
- case 'q': /* Quit */
- dohangup = 2; quitnow = 1; active = 0; conol("\r\n"); return;
-
- case 's': /* Status */
- conoll("");
- conoll("----------------------------------------------------");
-#ifdef NETCMD
- if (ttpipe)
- ckmakmsg(temp,TMPLEN," Pipe: \"",ttname,"\"",NULL);
- else
-#endif /* NETCMD */
- ckmakmsg(temp,
- TMPLEN,
- " ",
- (network ? "Host" : "Device"),
- ": ",
- ttname
- );
- conoll(temp);
- if (!network && speed >= 0L) {
- sprintf(temp,"Speed %ld", speed);
- conoll(temp);
- }
- sprintf(temp," Terminal echo: %s", duplex ? "local" : "remote");
- conoll(temp);
- sprintf(temp," Terminal bytesize: %d", (cmask == 0177) ? 7 : 8);
- conoll(temp);
- sprintf(temp," Command bytesize: %d", (cmdmsk == 0177) ? 7 : 8 );
- conoll(temp);
- if (hwparity)
- sprintf(temp," Parity[hardware]: %s",parnam((char)hwparity));
- else
- sprintf(temp," Parity: %s", parnam((char)parity));
- conoll(temp);
- sprintf(temp," Autodownload: %s", autodl ? "on" : "off");
- conoll(temp);
- ckmakmsg(temp, /* (would not be safe for sprintf) */
- TMPLEN,
- " Session log: ",
- *sesfil ? sesfil : "(none)",
- NULL,
- NULL
- );
- conoll(temp);
-#ifndef NOSHOW
- if (!network) shomdm();
-#endif /* NOSHOW */
-#ifdef CKLOGDIAL
- {
- long z;
- z = dologshow(0);
- if (z > -1L) {
- sprintf(temp," Elapsed time: %s",hhmmss(z));
- conoll(temp);
- }
- }
-#endif /* CKLOGDIAL */
- conoll("----------------------------------------------------");
- return;
-
- case 'h': /* Help */
- case '?': /* Help */
- c = hconne(); continue;
-
- case '0': /* Send a null */
- c = '\0'; d = dopar((CHAR) c); ttoc((char) d); return;
-
- case 'z': case '\032': /* Suspend */
-#ifndef NOPUSH
- if (!nopush)
- stptrap(0);
- else
- conoc(BEL);
-#else
- conoc(BEL);
-#endif /* NOPUSH */
- return;
-
- case '@': /* Start inferior command processor */
- case '!':
-#ifndef NOPUSH
- if (!nopush) {
- conres(); /* Put console back to normal */
- zshcmd(""); /* Fork a shell. */
- if (conbin((char)escape) < 0) {
- printf("Error resuming CONNECT session\n");
- active = 0;
- }
- } else conoc(BEL);
-#else
- conoc(BEL);
-#endif /* NOPUSH */
- return;
-
- case SP: /* Space, ignore */
- return;
-
- default: /* Other */
- if (c == CMDQ) { /* Backslash escape */
- int x;
- ecbp = ecbuf;
- *ecbp++ = c;
- while (((c = (CONGKS() & cmdmsk)) != '\r') && (c != '\n'))
- *ecbp++ = c;
- *ecbp = NUL; ecbp = ecbuf;
- x = xxesc(&ecbp); /* Interpret it */
- if (x >= 0) { /* No key mapping here */
- c = dopar((CHAR) x);
- ttoc((char) c);
- return;
- } else { /* Invalid backslash code. */
- conoc(BEL);
- return;
- }
- }
- conoc(BEL); return; /* Invalid esc arg, beep */
- }
- }
-}
-#endif /* NOLOCAL */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckudia.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckudia.c
deleted file mode 100644
index 587a0d1..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckudia.c
+++ /dev/null
@@ -1,8249 +0,0 @@
-#include "ckcsym.h"
-char *dialv = "Dial Command, 9.0.160, 16 Oct 2009";
-
-/* C K U D I A -- Module for automatic modem dialing. */
-
-/*
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- Authors:
-
- Original (version 1, 1985) author: Herm Fischer, Encino, CA.
- Contributed to Columbia University in 1985 for inclusion in C-Kermit 4.0.
- Author and maintainer since 1985: Frank da Cruz, Columbia University,
- fdc@columbia.edu.
-
- Contributions by many others throughout the years, including: Jeffrey
- Altman, Mark Berryman, Fernando Cabral, John Chmielewski, Joe Doupnik,
- Richard Hill, Larry Jacobs, Eric Jones, Tom Kloos, Bob Larson, Peter Mauzey,
- Joe Orost, Kevin O'Gorman, Kai Uwe Rommel, Dan Schullman, Warren Tucker, and
- many others.
-*/
-
-/*
- Entry points:
- ckdial(char * number) Dial a number or answer a call
- dialhup() Hang up a dialed connection
- mdmhup() Use modem commands to hang up
-
- All other routines are static.
- Don't call dialhup() or mdmhup() without first calling ckdial().
-*/
-
-/*
- This module calls externally defined system-dependent functions for
- communications i/o, as described in CKCPLM.DOC, the C-Kermit Program Logic
- Manual, and thus should be portable to all systems that implement those
- functions, and where alarm() and signal() work.
-
- HOW TO ADD SUPPORT FOR ANOTHER MODEM:
-
- 1. In ckuusr.h, define a modem-type number symbol (n_XXX) for the new modem,
- the next highest one.
-
- 2. In ckuusr.h, adjust MAX_MDM to the new number of modem types.
-
-The remaining steps are in this module:
-
- 3. Create a MDMINF structure for it. NOTE: The wake_str should include
- all invariant setup info, e.g. enable result codes, BREAK transparency,
- modulation negotiation, etc. See ckcker.h for MDMINF struct definition.
-
- 4. Add the address of the MDMINF structure to the modemp[] array,
- according to the numerical value of the modem-type number.
-
- 5. Add the user-visible (SET MODEM) name and corresponding modem number
- to the mdmtab[] array, in alphabetical order by modem-name string.
-
- 6. If this falls into a class like is_rockwell, is_supra, etc, add the new
- one to the definition of the class.
-
- 7. Adjust the gethrn() routine to account for any special numeric result
- codes (if it's a Hayes compatible modem).
-
- 8. Read through the code and add any modem-specific sections as necessary.
- For most modern Hayes-compatible modems, no specific code will be
- needed.
-
- NOTE: The MINIDIAL symbol is used to build this module to include support
- for only a minimum number of standard and/or generally useful modem types,
- namely Hayes 1200 and 2400, ITU-T (CCITT) V.25bis and V.25ter (V.250),
- Generic-High-Speed, "Unknown", and None. When adding support for a new
- modem type, keep it outside of the MINIDIAL sections unless it deserves to
- be in it.
-*/
-
-#include "ckcdeb.h"
-#ifndef NOLOCAL
-#ifndef NODIAL
-#ifndef NOICP
-
-#ifndef CK_ATDT
-#define CK_ATDT
-#endif /* CK_ATDT */
-
-#ifndef NOOLDMODEMS /* Unless instructed otherwise, */
-#define OLDMODEMS /* keep support for old modems. */
-#endif /* NOOLDMODEMS */
-
-#ifndef M_OLD /* Hide old modem keywords in SET MODEM table. */
-#define M_OLD 0 /* Define as CM_INV to make them invisible. */
-#endif /* M_OLD */
-
-#ifndef M_ALIAS
-#define M_ALIAS 64
-#endif /* M_ALIAS */
-
-#ifndef MAC
-#include <signal.h>
-#endif /* MAC */
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckucmd.h"
-#include "ckcnet.h"
-#include "ckuusr.h"
-
-#ifdef OS2ONLY
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#include "ckocon.h"
-#endif /* OS2ONLY */
-
-#ifdef NT
-#include <windows.h>
-#include <tapi.h>
-#include "cknwin.h"
-#include "ckntap.h"
-#endif /* NT */
-#ifdef OS2
-#include "ckowin.h"
-#endif /* OS2 */
-
-#ifndef ZILOG
-#ifdef NT
-#include <setjmpex.h>
-#else /* NT */
-#include <setjmp.h>
-#endif /* NT */
-#else
-#include <setret.h>
-#endif /* ZILOG */
-
-#include "ckcsig.h" /* C-Kermit signal processing */
-
-#ifdef MAC
-#define signal msignal
-#define SIGTYP long
-#define alarm malarm
-#define SIG_IGN 0
-#define SIGALRM 1
-#define SIGINT 2
-SIGTYP (*msignal(int type, SIGTYP (*func)(int)))(int);
-#endif /* MAC */
-
-#ifdef AMIGA
-#define signal asignal
-#define alarm aalarm
-#define SIGALRM (_NUMSIG+1)
-#define SIGTYP void
-SIGTYP (*asignal(int type, SIGTYP (*func)(int)))(int);
-unsigned aalarm(unsigned);
-#endif /* AMIGA */
-
-#ifdef STRATUS
-/*
- VOS doesn't have alarm(), but it does have some things we can work with.
- However, we have to catch all the signals in one place to do this, so
- we intercept the signal() routine and call it from our own replacement.
-*/
-#define signal vsignal
-#define alarm valarm
-SIGTYP (*vsignal(int type, SIGTYP (*func)(int)))(int);
-int valarm(int interval);
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) conoc(x)
-#ifdef getchar
-#undef getchar
-#endif /* getchar */
-#define getchar(x) coninc(0)
-#endif /* STRATUS */
-
-#ifdef OS2
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) conoc(x)
-#endif /* OS2 */
-
-#ifndef NOHINTS
-extern int hints;
-#endif /* NOHINTS */
-
-#ifdef CK_TAPI
-extern int tttapi;
-extern int tapipass;
-#endif /* CK_TAPI */
-
-#ifdef CKLOGDIAL
-extern int dialog;
-#endif /* CKLOGDIAL */
-
-char * dialmsg[] = { /* DIAL status strings */
-
- /* Keyed to numbers defined in ckcker.h -- keep in sync! */
-
- "DIAL succeeded", /* 0 DIA_OK */
- "Modem type not specified", /* 1 DIA_NOMO */
- "Communication device not specified", /* 2 DIA_NOLI */
- "Communication device can't be opened", /* 3 DIA_OPEN */
- "Speed not specified", /* 4 DIA_NOSP */
- "Pre-DIAL hangup failed", /* 5 DIA_HANG */
- "Internal error", /* 6 DIA_IE */
- "Device input/output error", /* 7 DIA_IO */
- "DIAL TIMEOUT expired", /* 8 DIA_TIMO */
- "Interrupted by user", /* 9 DIA_INTR */
- "Modem not ready", /* 10 DIA_NRDY */
- "Partial dial OK", /* 11 DIA_PART */
- "Dial directory lookup error", /* 12 DIA_DIR */
- "Hangup OK", /* 13 DIA_HUP */
- NULL, /* 14 (undef) */
- NULL, /* 15 (undef) */
- NULL, /* 16 (undef) */
- NULL, /* 17 (undef) */
- NULL, /* 18 (undef) */
- "No response from modem", /* 19 DIA_NRSP */
- "Modem command error", /* 20 DIA_ERR */
- "Failure to initialize modem", /* 21 DIA_NOIN */
- "Phone busy", /* 22 DIA_BUSY */
- "No carrier", /* 23 DIA_NOCA */
- "No dialtone", /* 24 DIA_NODT */
- "Incoming call", /* 25 DIA_RING */
- "No answer", /* 26 DIA_NOAN */
- "Disconnected", /* 27 DIA_DISC */
- "Answered by voice", /* 28 DIA_VOIC */
- "Access denied / forbidden call", /* 29 DIA_NOAC */
- "Blacklisted", /* 30 DIA_BLCK */
- "Delayed", /* 31 DIA_DELA */
- "Fax connection", /* 32 DIA_FAX */
- "Digital line", /* 33 DIA_DIGI */
- "TAPI dialing failure", /* 34 DIA_TAPI */
- NULL /* 34 */
-};
-
-#ifdef COMMENT
-#ifdef NOSPL
-static
-#endif /* NOSPL */
-char modemmsg[128] = { NUL, NUL }; /* DIAL response from modem */
-#endif /* COMMENT */
-
-#ifdef NTSIG
-extern int TlsIndex;
-#endif /* NTSIG */
-
-int mdmtyp = n_GENERIC; /* Default modem type */
-int mdmset = 0; /* User explicitly set a modem type */
-
-int /* SET DIAL parameters */
- dialhng = 1, /* DIAL HANGUP, default is ON */
- dialdpy = 0, /* DIAL DISPLAY, default is OFF */
- mdmspd = 0, /* DIAL SPEED-MATCHING (0 = OFF) */
- mdmspk = 1, /* MODEM SPEAKER */
- mdmvol = 2, /* MODEM VOLUME */
- dialtmo = 0, /* DIAL TIMEOUT */
- dialatmo = -1, /* ANSWER TIMEOUT */
- dialksp = 0, /* DIAL KERMIT-SPOOF, 0 = OFF */
- dialidt = 0, /* DIAL IGNORE-DIALTONE */
-#ifndef CK_RTSCTS
- /* If we can't do RTS/CTS then there's no flow control at first. */
- /* So we might easily lose the echo to the init string and the OK */
- /* and then give "No response from modem" errors. */
- dialpace = 150, /* DIAL PACING */
-#else
- dialpace = -1,
-#endif /* CK_RTSCTS */
-
- /* 0 = RS232 (drop DTR); 1 = MODEM-COMMAND (e.g. <sec>+++<sec>ATH0) */
- dialmhu = DEFMDMHUP; /* MODEM HANGUP-METHOD */
-
-int
- dialec = 1, /* DIAL ERROR-CORRECTION */
- dialdc = 1, /* DIAL COMPRESSION */
-#ifdef VMS
- /* VMS can only use Xon/Xoff */
- dialfc = FLO_XONX, /* DIAL FLOW-CONTROL */
-#else
- dialfc = FLO_AUTO,
-#endif /* VMS */
- dialmth = XYDM_D, /* DIAL METHOD (Tone, Pulse, Defalt) */
- dialmauto = 1, /* DIAL METHOD is AUTO */
- dialesc = 0; /* DIAL ESCAPE */
-
-int telephony = 0; /* Command-line '-T' option */
-
-long dialmax = 0L, /* Modem's max interface speed */
- dialcapas = 0L; /* Modem's capabilities */
-
-int dialsta = DIA_UNK; /* Detailed return code (ckuusr.h) */
-
-#ifdef COMMENT
-int ans_cid = 0; /* SET ANSWER parameters */
-int ans_rings = 0; /* (not used yet...) */
-#endif /* COMMENT */
-
-int is_rockwell = 0;
-int is_motorola = 0;
-int is_supra = 0;
-int is_hayeshispd = 0;
-
-/* Dialing directory list */
-
-char *dialdir[MAXDDIR]; /* DIAL DIRECTORY filename array */
-int ndialdir = 0; /* How many dial directories */
-
-/* User overrides for built-in modem commands */
-
-char *dialini = NULL; /* MODEM INIT-STRING none */
-char *dialmstr = NULL; /* MODEM DIALMODE-STRING */
-char *dialmprmt = NULL; /* MODEM DIALMODE-PROMPT */
-char *dialcmd = NULL; /* MODEM DIAL-COMMAND, default none */
-char *dialname = NULL; /* Descriptive name for modem */
-char *dialdcon = NULL; /* DC ON command */
-char *dialdcoff = NULL; /* DC OFF command */
-char *dialecon = NULL; /* EC ON command */
-char *dialecoff = NULL; /* EC OFF command */
-char *dialaaon = NULL; /* Autoanswer ON command */
-char *dialaaoff = NULL; /* Autoanswer OFF command */
-char *dialhcmd = NULL; /* Hangup command */
-char *dialhwfc = NULL; /* Hardware flow control command */
-char *dialswfc = NULL; /* (Local) software f.c. command */
-char *dialnofc = NULL; /* No (Local) flow control command */
-char *dialtone = NULL; /* Command to force tone dialing */
-char *dialpulse = NULL; /* ..to force pulse dialing */
-char *dialx3 = NULL; /* Ignore dialtone */
-char *mdmname = NULL;
-char *dialspon = NULL; /* Speaker On command */
-char *dialspoff = NULL; /* Speaker Off command */
-char *dialvol1 = NULL; /* Volume Low command */
-char *dialvol2 = NULL; /* Volume Medium command */
-char *dialvol3 = NULL; /* Volume High command */
-char *dialini2 = NULL; /* Second init string */
-
-/* Phone number options */
-
-char *dialnpr = NULL; /* DIAL PREFIX, ditto */
-char *diallac = NULL; /* DIAL LOCAL-AREA-CODE, ditto */
-char *diallcc = NULL; /* DIAL LOCAL-COUNTRY-CODE, ditto */
-char *dialixp = NULL; /* DIAL INTL-PREFIX */
-char *dialixs = NULL; /* DIAL INTL-SUFFIX */
-char *dialldp = NULL; /* DIAL LD-PREFIX */
-char *diallds = NULL; /* DIAL LD-SUFFIX */
-char *diallcp = NULL; /* DIAL LOCAL-PREFIX */
-char *diallcs = NULL; /* DIAL LOCAL-SUFFIX */
-char *dialpxi = NULL; /* DIAL PBX-INTERNAL-PREFIX */
-char *dialpxo = NULL; /* DIAL PBX-OUTSIDE-PREFIX */
-char *dialsfx = NULL; /* DIAL SUFFIX */
-char *dialtfp = NULL; /* DIAL TOLL-FREE-PREFIX */
-
-char *callid_date = NULL; /* Caller ID strings */
-char *callid_time = NULL;
-char *callid_name = NULL;
-char *callid_nmbr = NULL;
-char *callid_mesg = NULL;
-
-extern char * d_name;
-extern char * dialtfc[]; /* DIAL TOLL-FREE-AREA-CODE */
-extern char * dialpxx[]; /* DIAL PBX-EXCHANGE */
-extern int ntollfree;
-extern int ndialpxx;
-
-extern char * dialpucc[]; /* DIAL Pulse countries */
-extern int ndialpucc;
-extern char * dialtocc[]; /* DIAL Tone countries */
-extern int ndialtocc;
-
-char *dialmac = NULL; /* DIAL macro */
-
-/* Countries where pulse dialing must be used (tone is not available) */
-static char * pulsecc[] = { NULL }; /* (Unknown at present) */
-
-/* Countries where tone dialing may safely be the default. */
-/* "+" marks countries where pulse is also allowed. */
-/* Both Pulse and Tone are allowed in Austria & Switzerland but it is not */
-/* yet known if Tone is universally in those countries. */
-static char * tonecc[] = {
- "1", /* + North American Numbering Plan */
- "31", /* Netherlands */
- "32", /* Belgium */
- "33", /* France */
- "352", /* Luxembourg */
- "353", /* Ireland */
- "354", /* Iceland */
- "358", /* Finland */
- "39", /* Italy */
- "44", /* + UK */
- "45", /* Denmark */
- "46", /* Sweden */
- "47", /* Norway */
- "49", /* + Germany */
- NULL
-};
-
-#ifndef MINIDIAL
-/*
- Telebit model codes:
-
- ATI Model Numbers Examples
- --- ------------- --------
- 123 Telebit in "total Hayes-1200" emulation mode
- 960 Telebit in Conventional Command (Hayes) mode
- 961 RA12C IBM PC internal original Trailblazer
- 962 RA12E External original Trailblazer
- 963 RM12C Rackmount original Trailblazer
- 964 T18PC IBM PC internal Trailblazer-Plus (TB+)
- 965 T18SA, T2SAA, T2SAS External TB+, T1600, T2000, T3000, WB, and later
- 966 T18RMM Rackmount TB+
- 967 T2MC IBM PS/2 internal TB+
- 968 T1000 External T1000
- 969 ? Qblazer
- 970 Qblazer Plus
- 971 T2500 External T2500
- 972 T2500 Rackmount T2500
-*/
-
-/* Telebit model codes */
-
-#define TB_UNK 0 /* Unknown Telebit model */
-#define TB_BLAZ 1 /* Original TrailBlazer */
-#define TB_PLUS 2 /* TrailBlazer Plus */
-#define TB_1000 3 /* T1000 */
-#define TB_1500 4 /* T1500 */
-#define TB_1600 5 /* T1600 */
-#define TB_2000 6 /* T2000 */
-#define TB_2500 7 /* T2500 */
-#define TB_3000 8 /* T3000 */
-#define TB_QBLA 9 /* Qblazer */
-#define TB_WBLA 10 /* WorldBlazer */
-#define TB__MAX 10 /* Highest number */
-
-char *tb_name[] = { /* Array of model names */
- "Unknown", /* TB_UNK */
- "TrailBlazer", /* TB_BLAZ */
- "TrailBlazer-Plus", /* TB_PLUS */
- "T1000", /* TB_1000 */
- "T1500", /* TB_1500 */
- "T1600", /* TB_1600 */
- "T2000", /* TB_2000 */
- "T2500", /* TB_2500 */
- "T3000", /* TB_3000 */
- "Qblazer", /* TB_QBLA */
- "WorldBlazer", /* TB_WBLA */
- ""
-};
-#endif /* MINIDIAL */
-
-extern int flow, local, mdmtyp, quiet, backgrd, parity, seslog, network;
-extern int carrier, duplex, mdmsav, reliable, setreliable;
-extern int ttnproto, nettype;
-extern long speed;
-extern char ttname[], sesfil[];
-#ifndef NOXFER
-extern CHAR stchr;
-extern int interrupted;
-#endif /* NOXFER */
-
-/* Failure codes */
-
-#define F_TIME 1 /* timeout */
-#define F_INT 2 /* interrupt */
-#define F_MODEM 3 /* modem-detected failure */
-#define F_MINIT 4 /* cannot initialize modem */
-
-#ifndef CK_TAPI
-static
-#endif /* CK_TAPI */
-#ifdef OS2
- volatile
-#endif /* OS2 */
- int fail_code = 0; /* Default failure reason. */
-
-static int xredial = 0;
-static int func_code; /* 0 = dialing, nonzero = answering */
-static int partial;
-static int mymdmtyp = 0;
-
-#define DW_NOTHING 0 /* What we are doing */
-#define DW_INIT 1
-#define DW_DIAL 2
-
-static int dial_what = DW_NOTHING; /* Nothing at first. */
-static int nonverbal = 0; /* Hayes in numeric response mode */
-static MDMINF * mp;
-static CHAR escbuf[6];
-static long mdmcapas;
-
-_PROTOTYP (static VOID dreset, (void) );
-_PROTOTYP (static int (*xx_ok), (int,int) );
-_PROTOTYP (static int ddinc, (int) );
-_PROTOTYP (int dialhup, (void) );
-_PROTOTYP (int getok, (int,int) );
-_PROTOTYP (char * ck_time, (void) );
-_PROTOTYP (static VOID ttslow, (char *, int) );
-#ifdef COMMENT
-_PROTOTYP (static VOID xcpy, (char *, char *, unsigned int) );
-#endif /* COMMENT */
-_PROTOTYP (static VOID waitfor, (char *) );
-_PROTOTYP (static VOID dialoc, (char) );
-_PROTOTYP (static int didweget, (char *, char *) );
-_PROTOTYP (static VOID spdchg, (long) );
-_PROTOTYP (static int dialfail, (int) );
-_PROTOTYP (static VOID gethrw, (void) );
-_PROTOTYP (static VOID gethrn, (void) );
-
-int dialudt = n_UDEF; /* Number of user-defined type */
-
-/* BEGIN MDMINF STRUCT DEFINITIONS */
-
-/*
- Declare structures containing modem-specific information.
- REMEMBER that only the first SEVEN characters of these names are
- guaranteed to be unique.
-
- First declare the three types that are allowed for MINIDIAL versions.
-*/
-static
-MDMINF CCITT = /* CCITT / ITU-T V.25bis autodialer */
-/*
- According to V.25bis:
- . Even parity is required for giving commands to the modem.
- . Commands might or might not echo.
- . Responses ("Indications") from the modem are terminated by CR and LF.
- . Call setup is accomplished by:
- - DTE raises DTR (V.24 circuit 108) [ttopen() does this]
- - Modem raises CTS (V.24 circuit 106) [C-Kermit ignores this]
- - DTE issues a call request command ("CRN")
- - Modem responds with "VAL" ("command accepted")
- - If the call is completed:
- modem responds with "CNX" ("call connected");
- modem turns CTS (106) OFF;
- modem turns DSR (107) ON;
- else:
- modem responds with "CFI <parameter>" ("call failure indication").
- . To clear a call, the DTE turns DTR (108) OFF.
- . There is no mention of the Carrier Detect circuit (109) in the standard.
- . There is no provision for "escaping back" to the modem's command mode.
-
- It is not known whether there exists in real life a pure V.25bis modem.
- If there is, this code has never been tested on it. See the Digitel entry.
-*/
- {
- "Any CCITT / ITU-T V.25bis conformant modem",
- "", /* pulse command */
- "", /* tone command */
- 40, /* dial_time -- programmable -- */
- ",:", /* pause_chars -- "," waits for programmable time */
- /* ":" waits for dial tone */
- 10, /* pause_time (seconds, just a guess) */
- "", /* wake_str (none) */
- 200, /* wake_rate (msec) */
- "VAL", /* wake_prompt */
- "", /* dmode_str (none) */
- "", /* dmode_prompt (none) */
- "CRN%s\015", /* dial_str */
- 200, /* dial_rate (msec) */
- 0, /* No esc_time */
- 0, /* No esc_char */
- "", /* No hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "CIC\015", /* aa_on_str */
- "DIC\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- CKD_V25, /* capas */
- NULL /* No ok_fn */
-};
-
-static
-MDMINF HAYES = /* Hayes 2400 and compatible modems */
- {
- "Hayes Smartmodem 2400 and compatibles",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1&S0&C1&D2\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0&S1\015", /* wake_str */
-#else
- "ATQ0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str, user supplies D or T */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 2400L, /* max_speed */
- CKD_AT, /* capas */
- getok /* ok_fn */
-};
-
-/*
- The intent of the "unknown" modem is to allow KERMIT to support
- unknown modems by having the user type the entire autodial sequence
- (possibly including control characters, etc.) as the "phone number".
- The protocol and other characteristics of this modem are unknown, with
- some "reasonable" values being chosen for some of them. The only way to
- detect if a connection is made is to look for carrier.
-*/
-static
-MDMINF UNKNOWN = /* Information for "Unknown" modem */
- {
- "Unknown", /* name */
- "", /* pulse command */
- "", /* tone command */
- 30, /* dial_time */
- "", /* pause_chars */
- 0, /* pause_time */
- "", /* wake_str */
- 0, /* wake_rate */
- "", /* wake_prompt */
- "", /* dmode_str */
- NULL, /* dmode_prompt */
- "%s\015", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-#ifndef MINIDIAL
-static
-MDMINF ATTISN = /* AT&T ISN Network */
- {
- "", /* pulse command */
- "", /* tone command */
- "AT&T ISN Network",
- 30, /* Dial time */
- "", /* Pause characters */
- 0, /* Pause time */
- "\015\015\015\015", /* Wake string */
- 900, /* Wake rate */
- "DIAL", /* Wake prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "%s\015", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF ATTMODEM = /* information for AT&T switched-network modems */
- /* "Number" following "dial" can include: p's and
- * t's to indicate pulse or tone (default) dialing,
- * + for wait for dial tone, , for pause, r for
- * last number dialed, and, except for 2224B, some
- * comma-delimited options like o12=y, before number.
-
- * "Important" options for the modems:
- *
- * All: Except for 2224B, enable option 12 for "transparent
- * data," o12=y. If a computer port used for both
- * incoming and outgoing calls is connected to the
- * modem, disable "enter interactive mode on carriage
- * return," EICR. The Kermit "dial" command can
- * function with EIA leads standard, EIAS.
- *
- * 2212C: Internal hardware switches at their default
- * positions (four rockers down away from numbers)
- * unless EICR is not wanted (rocker down at the 4).
- * For EIAS, rocker down at the 1.
- *
- * 2224B: Front-panel switch position 1 must be up (at the 1,
- * closed). Disable EICR with position 2 down.
- * For EIAS, position 4 down.
- * All switches on the back panel down.
- *
- * 2224CEO: All front-panel switches down except either 5 or 6.
- * Enable interactive flow control with o16=y.
- * Select normal asynchronous mode with o34=0 (zero).
- * Disable EICR with position 3 up. For EIAS, 1 up.
- * Reset the modem after changing switches.
- *
- * 2296A: If option 00 (zeros) is present, use o00=0.
- * Enable interactive flow control with o16=y.
- * Select normal asynchronous mode with o34=0 (zero).
- * (available in Microcom Networking version, but
- * not necessarily other models of the 2296A).
- * Enable modem-port flow control (if available) with
- * o42=y. Enable asynchronous operation with o50=y.
- * Disable EICR with o69=n. For EIAS, o66=n, using
- * front panel.
- */
- {
- "AT&T switched-network modems",
- "", /* pulse command */
- "", /* tone command */
- 20, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
- "+", /* wake_str */
- 0, /* wake_rate */
- "", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "at%s\015", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- CKD_AT, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF ATTDTDM = /* AT&T Digital Terminal Data Module */
- /* For dialing: KYBD switch down, others usually up. */
- {
- "AT&T Digital Terminal Data Module",
- "", /* pulse command */
- "", /* tone command */
- 20, /* dial_time */
- "", /* pause_chars */
- 0, /* pause_time */
- "", /* wake_str */
- 0, /* wake_rate */
- "", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "%s\015", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF DIGITEL = /* Digitel DT-22 CCITT variant used in Brazil */
-/*
- Attempts to adhere strictly to the V.25bis specification do not produce good
- results in real life. The modem for which this code was developed: (a)
- ignores parity; (b) sometimes terminates responses with LF CR instead of CR
- LF; (c) has a Hayes-like escape sequence; (d) supports a hangup ("HUP")
- command. Information from Fernando Cabral in Brasilia.
-*/
- {
- "Digitel DT-22 CCITT dialer",
- "", /* pulse command */
- "", /* tone command */
- 40, /* dial_time -- programmable -- */
- ",:", /* pause_chars -- "," waits for programmable time */
- /* ":" waits for dial tone */
- 10, /* pause_time (seconds, just a guess) */
- "HUP\015", /* wake_str (Not Standard CCITT) */
- 200, /* wake_rate (msec) */
- "VAL", /* wake_prompt */
- "", /* dmode_str (none) */
- "", /* dmode_prompt (none) */
- "CRN%s\015", /* dial_str */
- 200, /* dial_rate (msec) */
- 1100, /* esc_time (Not Standard CCITT) */
- 43, /* esc_char (Not Standard CCITT) */
- "HUP\015", /* hup_str (Not Standard CCITT) */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "CIC\015", /* aa_on_str */
- "DIC\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- CKD_V25, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF H_1200 = /* Hayes 1200 and compatible modems */
- {
- "Hayes Smartmodem 1200 and compatibles",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1\015", /* wake_str */
-#else
- "ATQ0\015", /* wake_str */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 1200L, /* max_speed */
- CKD_AT, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF H_ULTRA = /* Hayes high-speed */
- {
- "Hayes Ultra/Optima/Accura 96/144/288", /* U,O,A */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1X4N1Y0&S0&C1&D2S37=0S82=128\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4N1Y0&S1S37=0S82=128\015", /* wake_str */
-#else
- "ATQ0X4N1Y0S37=0S82=128\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */ /* OK for U,O */
- "AT&K4\015", /* swfc_str */ /* OK for U,O */
- "AT&K0\015", /* nofc_str */ /* OK for U,O */
- "AT&Q5S36=7S48=7\015", /* ec_on_str */ /* OK for U,O */
- "AT&Q0\015", /* ec_off_str */ /* OK for U,O */
- "ATS46=2\015", /* dc_on_str */
- "ATS46=0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */ /* (varies) */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF H_ACCURA = /* Hayes Accura */
- { /* GUESSING IT'S LIKE ULTRA & OPTIMA */
- "Hayes Accura",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1X4N1Y0&S0&C1&D2S37=0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4N1Y0&S1S37=0\015", /* wake_str */
-#else
- "ATQ0X4N1Y0S37=0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5S36=7S48=7\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "ATS46=2\015", /* dc_on_str */
- "ATS46=0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */ /* (varies) */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF PPI = /* Practical Peripherals */
- {
- "Practical Peripherals V.22bis or higher with V.42 and V.42bis",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef COMMENT
-/* In newer models S82 (BREAK handling) was eliminated, causing an error. */
-#ifdef OS2
- "ATQ0X4N1&S0&C1&D2S37=0S82=128\015", /* wake_str */
-#else
- "ATQ0X4N1S37=0S82=128\015", /* wake_str */
-#endif /* OS2 */
-#else /* So now we use Y0 instead */
-#ifdef OS2
- "ATE1Q0V1X4N1&S0&C1&D2Y0S37=0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4N1Y0&S1S37=0\015", /* wake_str */
-#else
- "ATQ0X4N1Y0S37=0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* COMMENT */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5S36=7S48=7\015", /* ec_on_str */
- "AT&Q0S36=0S48=128\015", /* ec_off_str */
- "ATS46=2\015", /* dc_on_str */
- "ATS46=0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF DATAPORT = /* AT&T Dataport */
- {
- "AT&T / Paradyne DataPort V.32 or higher",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
- /*
- Note: S41=0 (use highest modulation) omitted, since it is not
- supported on the V.32 and lower models. So let's not touch it.
- */
-#ifdef OS2
- "ATQ0E1V1X6&S0&C1&D2&Q0Y0\\K5S78=0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1X6&S1&Q0Y0\\K5S78=0\015", /* wake_str */
-#else
- "ATQ0E1X6&Q0Y0\\K5S78=0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT\\Q3\015", /* hwfc_str */
- "AT\\Q1\\X0\015", /* swfc_str */
- "AT\\Q0\015", /* nofc_str */
- "AT\\N7\015", /* ec_on_str */
- "AT\\N0\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF UCOM_AT = /* Microcom DeskPorte FAST ES 28.8 */
- {
- "Microcom DeskPorte FAST 28.8",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1X4\\N0F0&S0&C1&D2\\K5\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4F0&S1\\K5\015", /* wake_str */
-#else
- "ATQ0X4F0\\K5\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT\\Q3\015", /* hwfc_str */
- "AT\\Q1\015", /* swfc_str */
- "AT\\H0\\Q0\015", /* nofc_str */
- "AT\\N3\015", /* ec_on_str */
- "AT\\N0\015", /* ec_off_str */
- "AT%C3\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT-J0\015", /* sb_on_str */
- "AT-J1\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ZOOM = /* Zoom Telephonics V.32bis */
- {
- "Zoom Telephonics V.32bis",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1N1W1X4&S0&C1&D2S82=128S95=47\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1N1W1X4&S1S82=128S95=47\015", /* wake_str */
-#else
- "ATQ0E1N1W1X4S82=128S95=47\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5S36=7S48=7\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "ATS46=138\015", /* dc_on_str */
- "ATS46=136\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ZYXEL = /* ZyXEL U-Series */
- {
- "ZyXEL U-Series V.32bis or higher",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1&S0&C1&D2&N0X5&Y1\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1&S1&N0X5&Y1\015", /* wake_str */
-#else
- "ATQ0E1&N0X5&Y1\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&H3\015", /* hwfc_str */
- "AT&H4\015", /* swfc_str */
- "AT&H0\015", /* nofc_str */
- "AT&K3\015", /* ec_on_str */
- "AT&K0\015", /* ec_off_str */
- "AT&K4\015", /* dc_on_str */
- "AT&K3\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ZOLTRIX = /* Zoltrix */
- {
- "Zoltrix V.32bis and V.34 modems with Rockwell ACI chipset",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1F0W1X4Y0&S0&C1&D2\\K5S82=128S95=41\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1F0W1X4Y0&S1\\K5S82=128S95=41\015", /* wake_str */
-#else
- "ATQ0E1F0W1X4Y0\\K5S82=128S95=41\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT\\N3\015", /* ec_on_str */
- "AT\\N1\015", /* ec_off_str */
- "ATS46=138%C3\015", /* dc_on_str */
- "ATS46=136%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT\\N0\015", /* sb_on_str */
- "AT&Q0\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF MOTOROLA = { /* Motorola FasTalk II or Lifestyle */
-/*
- "\E" and "\X" commands removed - Motorola Lifestyle doesn't have them.
- \E0 = Don't echo while online
- \X0 = Process Xon/Xoff but don't pass through
-*/
- "Motorola FasTalk II or Lifestyle", /* Name */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1X4&S0&C1&D2\\K5\\V1\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1X4&S1\\K5\\V1\015", /* wake_str */
-#else
- "ATQ0E1X4\\K5\\V1\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT\\Q3\015", /* hwfc_str */
- "AT\\Q1\015", /* swfc_str */
- "AT\\Q0\015", /* nofc_str */
- "AT\\N6\015", /* ec_on_str */
- "AT\\N1\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT\\J0\015", /* sb_on_str */
- "AT\\J1\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF BOCA = /* Boca */
- {
- "BOCA 14.4 Faxmodem",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1F1N1W1&S0&C1&D2\\K5S37=11S82=128S95=47X4\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1F1N1W1&S1\\K5S37=11S82=128S95=47X4\015", /* wake_str */
-#else
- "ATQ0E1F1N1W1\\K5S37=11S82=128S95=47X4\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT\\N3S36=7S48=7\015", /* ec_on_str */
- "AT\\N1\015", /* ec_off_str */
- "ATS46=138\015", /* dc_on_str */
- "ATS46=136\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF INTEL = /* Intel */
- {
- "Intel High-Speed Faxmodem",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1Y0X4&S0&C1&D2\\K1\\V2S25=50\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1Y0X4&S1\\K1\\V2S25=50\015", /* wake_str */
-#else
- "ATQ0E1Y0X4\\K1\\V2S25=50\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "ATB1+FCLASS=0\015", /* dmode_str */
- "OK\015", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT\\G1\\Q3\015", /* hwfc_str */
- "AT\\G1\\Q1\\X0\015", /* swfc_str */
- "AT\\G0\015", /* nofc_str */
- "AT\\J0\\N3\"H3\015", /* ec_on_str */
- "AT\\N1\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF MULTITECH = /* Multitech */
- {
- "Multitech MT1432 or MT2834 Series",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-/* #P0 (= no parity) is not listed in the manual for newer models */
-/* so it has been removed from all three copies of the Multitech wake_str */
-#ifdef OS2
- "ATE1Q0V1X4&S0&C1&D2&E8&Q0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1X4&S1&E8&Q0\015", /* wake_str */
-#else
- "ATQ0E1X4&E8&Q0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&E4&E7&E8&E11&E13\015", /* hwfc_str */
- "AT&E5&E6&E8&E11&E13\015", /* swfc_str */
- "AT&E3&E7&E8&E10&E12\015", /* nofc_str */
- "AT&E1\015", /* ec_on_str */
- "AT&E0\015", /* ec_off_str */
- "AT&E15\015", /* dc_on_str */
- "AT&E14\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT$BA0\015", /* sb_on_str (= "baud adjust off") */
- "AT$BA1\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF SUPRA = /* Supra */
- {
- "SupraFAXModem 144 or 288",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1N1W0X4Y0&S0&C1&D2\\K5S82=128\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1N1W0X4Y0&S1\\K5S82=128\015", /* wake_str */
-#else
- "ATQ0E1N1W0X4Y0\\K5S82=128\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5\\N3S48=7\015", /* ec_on_str */
- "AT&Q0\\N1\015", /* ec_off_str */
- "AT%C1S46=138\015", /* dc_on_str */
- "AT%C0S46=136\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM\015", /* sp_off_str */
- "ATL\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF SUPRAX = /* Supra Express */
- {
- "Diamond Supra Express V.90",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1W0X4&C1&D2&S0\\K5\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1W0X4&S1\\K5\015", /* wake_str */
-#else
- "ATQ0E1W0X4\\K5\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT\\N3\015", /* ec_on_str */
- "AT\\N1\015", /* ec_off_str */
- "AT%C2\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM\015", /* sp_off_str */
- "ATL\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 230400L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF MAXTECH = /* MaxTech */
- {
- "MaxTech XM288EA or GVC FAXModem",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4Y0&S0&C1&D2&L0&M0\\K5\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1X4Y0&L0&M0&S1\\K5\015", /* wake_str */
-#else
- "ATQ0E1X4Y0&L0&M0\\K5\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT\\Q3\015", /* hwfc_str */
- "AT\\Q1\\X0\015", /* swfc_str */
- "AT\\Q0\015", /* nofc_str */
- "AT\\N6\015", /* ec_on_str */
- "AT\\N0\015", /* ec_off_str */
- "AT\\N6%C1\015", /* dc_on_str */
- "AT\\N6%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ROLM = /* IBM / Siemens / Rolm 8000, 9000, 9751 CBX DCM */
- {
- "IBM/Siemens/Rolm CBX Data Communications Module",
- "", /* pulse command */
- "", /* tone command */
- 60, /* dial_time */
- "", /* pause_chars */
- 0, /* pause_time */
- "\015\015", /* wake_str */
- 50, /* wake_rate */
- "MODIFY?", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "CALL %s\015", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 19200L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF USR = /* USR Courier and Sportster modems */
- {
- "US Robotics Courier, Sportster, or compatible",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4&A3&S0&C1&D2&N0&Y3S14=0\015", /* wake_str */
-#else
-#ifdef SUNOS4
- "ATQ0X4&A3&S0&N0&Y3S14=0\015", /* wake_str -- needs &S0 in SunOS */
-#else
-#ifdef VMS
- "ATQ0X4&A3&S1&N0&Y3S14=0\015", /* wake_str -- needs &S1 in VMS */
-#else
- "ATQ0X4&A3&N0&Y3S14=0\015", /* wake_str */
-#endif /* VMS */
-#endif /* SUNOS4 */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&H1&R2&I0\015", /* hwfc_str */
- "AT&H2&R1&I2\015", /* swfc_str */
- "AT&H0&R1&I0\015", /* nofc_str */
- "AT&M4&B1\015", /* ec_on_str */
- "AT&M0\015", /* ec_off_str */
- "AT&K1\015", /* dc_on_str */
- "AT&K0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-
-static
-MDMINF USRX2 = /* USR XJ-CC1560 X2 56K */
- {
- "US Robotics / Megahertz CC/XJ-CC1560 X2",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4&A3&S0&B2&C1&D2&N0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4&A3&B2&N0&S1\015", /* wake_str */
-#else
- "ATQ0X4&A3&B2&N0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&H1&I0\015", /* hwfc_str */
- "AT&H2&I2\015", /* swfc_str */
- "AT&H0&I0\015", /* nofc_str */
- "AT&M4\015", /* ec_on_str */
- "AT&M0\015", /* ec_off_str */
- "AT&K1\015", /* dc_on_str */
- "AT&K0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT&B1\015", /* sb_on_str */
- "AT&B0\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF OLDTB = /* Old Telebits */
- {
- "Telebit TrailBlazer, T1000, T1500, T2000, T2500",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 60, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "\021AAAAATQ0E1V1X1&S0&C1&D2S12=50S50=0S54=3\015", /* wake_str. */
-#else
-#ifdef VMS
- "\021AAAAATQ0X1S12=50S50=0S54=3\015", /* wake_str. */
-#else
- "\021AAAAATQ0X1&S1S12=50S50=0S54=3\015", /* wake_str. */
-#endif /* VMS */
-#endif /* OS2 */
- 100, /* wake_rate = 100 msec */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str, Note: no T or P */
- 80, /* dial_rate */
- 1100, /* esc_time (guard time) */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "ATS58=2S68=2\015", /* hwfc_str */
- "ATS58=3S68=3S69=0\015", /* swfc_str */
- "ATS58=0S68=0\015", /* nofc_str */
- "ATS66=1S95=2\015", /* ec_on_str */
- "ATS95=0\015", /* ec_off_str */
- "ATS110=1S96=1\015", /* dc_on_str */
- "ATS110=0S96=0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 19200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW|CKD_TB|CKD_KS, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF NEWTB = /* New Telebits */
- {
- "Telebit T1600, T3000, QBlazer, WorldBlazer, etc.",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 60, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "\021AAAAATQ0E1V1X2&S0&C1&D2S12=50S50=0S61=0S63=0\015", /* wake_str. */
-#else
-#ifdef VMS
- "\021AAAAATQ0X2&S1S12=50S50=0S61=0S63=0\015", /* wake_str. */
-#else
- "\021AAAAATQ0X2S12=50S50=0S61=0S63=0\015", /* wake_str. */
-#endif /* VMS */
-#endif /* OS2 */
- 100, /* wake_rate = 100 msec */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str, Note: no T or P */
- 80, /* dial_rate */
- 1100, /* esc_time (guard time) */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "ATS58=2S68=2\015", /* hwfc_str */
- "ATS58=3S68=3\015", /* swfc_str */
- "ATS58=0S68=0\015", /* nofc_str */
- "ATS180=3\015", /* ec_on_str */
- "ATS180=0\015", /* ec_off_str */
- "ATS190=1\015", /* dc_on_str */
- "ATS190=0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 38400L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW|CKD_TB|CKD_KS, /* capas */
- getok /* ok_fn */
-};
-#endif /* MINIDIAL */
-
-static
-MDMINF DUMMY = /* dummy information for modems that are handled elsewhere */
- {
- "(dummy)",
- "", /* pulse command */
- "", /* tone command */
- 30, /* dial_time */
- "", /* pause_chars */
- 0, /* pause_time */
- "", /* wake_str */
- 0, /* wake_rate */
- "", /* wake_prompt */
- "", /* dmode_str */
- NULL, /* dmode_prompt */
- "%s\015", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-#ifndef MINIDIAL
-static
-MDMINF RWV32 = /* Generic Rockwell V.32 */
- {
- "Generic Rockwell V.32 modem", /* ATI3, ATI4, and ATI6 for details */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4Y0&S0&C1&D2%E2\\K5+FCLASS=0N1S37=0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4Y0&S1%E2\\K5+FCLASS=0N1S37=0\015", /* wake_str */
-#else
- "ATQ0X4Y0%E2\\K5+FCLASS=0N1S37=0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q6\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF RWV32B = /* Generic Rockwell V.32bis */
- {
- "Generic Rockwell V.32bis modem", /* ATI3, ATI4, and ATI6 for details */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4Y0&S0&C1&D2%E2\\K5+FCLASS=0N1S37=0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4Y0&S1%E2\\K5+FCLASS=0N1S37=0\015", /* wake_str */
-#else
- "ATQ0X4Y0%E2\\K5+FCLASS=0N1S37=0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "ATS%C1\015", /* dc_on_str */
- "ATS%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF RWV34 = /* Generic Rockwell V.34 Data/Fax */
- {
- "Generic Rockwell V.34 modem", /* ATI3, ATI4, and ATI6 for details */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0V1X4Y0&C1&D2&S0%E2\\K5+FCLASS=0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0V1X4Y0&C1&D2&S1%E2\\K5+FCLASS=0\015", /* wake_str */
-#else
- "ATQ0V1X4Y0&C1&D2%E2\\K5+FCLASS=0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "ATS%C3\015", /* dc_on_str */
- "ATS%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF RWV90 = /* Generic Rockwell V.90 Data/Fax */
- {
- "Generic Rockwell V.90 56K modem", /* ATI3, ATI4, and ATI6 for details */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0V1N1X4Y0&C1&D2&S0%E2\\K5+FCLASS=0S37=0\015", /* K95 */
-#else
-#ifdef VMS
- "ATQ0V1N1X4Y0&C1&D2&S1%E2\\K5+FCLASS=0S37=0\015", /* wake_str */
-#else
- "ATQ0V1N1X4Y0&C1&D2%E2\\K5+FCLASS=0S37=0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "AT%C3\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF MWAVE = /* IBM Mwave */
- {
- "IBM Mwave Adapter",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4Y0&S0&C1&D2&M0&Q0&N1\\K3\\T0%E2S28=0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4Y0&M0&S1&Q0&N1&S0\\K3\\T0%E2S28=0\015", /* wake_str */
-#else
- "ATQ0X4Y0&M0&Q0&N1&S0\\K3\\T0%E2S28=0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT\\Q3\015", /* hwfc_str */
- "", /* swfc_str (it doesn't!) */
- "AT\\Q0\015", /* nofc_str */
- "AT\\N7\015", /* ec_on_str */
- "AT\\N0\015", /* ec_off_str */
- "AT%C1\"H3\015", /* dc_on_str */
- "AT%C0\"H0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF TELEPATH = /* Gateway 2000 Telepath */
- {
- "Gateway 2000 Telepath II 28.8",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4&S0&C1&D2&N0&Y2#CLS=0S13=0S15=0S19=0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4&N0&S1&Y1#CLS=0S13=0S15=0S19=0\015", /* wake_str */
-#else
- "ATQ0X4&N0&Y1#CLS=0S13=0S15=0S19=0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&H1&R2\015", /* hwfc_str */
- "AT&H2&I2S22=17S23=19\015", /* swfc_str */
- "AT&H0&I0&R1\015", /* nofc_str */
- "AT&M4&B1\015", /* ec_on_str -- also fixes speed */
- "AT&M0\015", /* ec_off_str */
- "AT&K1\015", /* dc_on_str */
- "AT&K0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF CARDINAL = /* Cardinal - based on Rockwell V.34 */
- {
- "Cardinal MVP288X Series", /* ATI3, ATI4, and ATI6 for details */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4W1Y0%E2&S0&C1&D2\\K5+FCLASS=0+MS=11,1\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4W1Y0&S1%E2\\K5+FCLASS=0+MS=11,1\015", /* wake_str */
-#else
- "ATQ0X4W1Y0%E2\\K5+FCLASS=0+MS=11,1\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5S36=7S48=7\\N3\015", /* ec_on_str */
- "AT&Q0S48=128\\N1\015", /* ec_off_str */
- "ATS46=138%C1\015", /* dc_on_str */
- "ATS46=136%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF LUCENT = /* Lucent Venus or Data/Fax modem */
- {
- "Lucent Venus chipset",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0V1N1X4Y0&C1&D2&S0%E2\\K5+FCLASS=0S37=0\015", /* K95 */
-#else
-#ifdef VMS
- "ATQ0V1N1X4Y0&C1&D2&S1%E2\\K5+FCLASS=0S37=0\015", /* VMS */
-#else
- "ATQ0V1N1X4Y0&C1&D2%E2\\K5+FCLASS=0S37=0\015", /* All others */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF CONEXANT = /* Conexant family */
- {
- "Conexant family of modems",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0V1X4&C1&D2&S0%E1+FCLASS=0\015", /* K95 */
-#else
-#ifdef VMS
- "ATQ0V1X4&C1&D2&S1%E1+FCLASS=0\015", /* VMS */
-#else
- "ATQ0V1X4&C1&D2%E1+FCLASS=0\015", /* UNIX etc */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "AT%C3\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF PCTEL = /* PCTel chipset */
- {
- "PCTel chipset",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0V1N1X4Y0&C1&D2&S0%E2\\K5S37=0\015", /* K95 */
-#else
-#ifdef VMS
- "ATQ0V1N1X4Y0&C1&D2&S1%E2\\K5S37=0\015", /* VMS */
-#else
- "ATQ0V1N1X4Y0&C1&D2%E2\\K5S37=0\015", /* UNIX etc */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT\\N3\015", /* ec_on_str */
- "AT\\N0\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ZOOMV34 = /* Zoom Telephonics V.34 */
- {
- "Zoom Telephonics V.34",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0V1N1W1X4&S0&C1&D2S82=128\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0V1N1W1X4&S1S82=128\015", /* wake_str */
-#else
- "ATQ0V1N1W1X4S82=128S015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015S32=17S33=19", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "ATS%C3\015", /* dc_on_str */
- "ATS%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ZOOMV90 = /* ZOOM V.90 */
- {
- "Zoom V.90 56K",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0V1N1X4Y0&C1&D2&S0%E2\\K5+FCLASS=0S37=0\015", /* K95 */
-#else
-#ifdef VMS
- "ATQ0V1N1X4Y0&C1&D2&S1%E2\\K5+FCLASS=0S37=0\015", /* VMS */
-#else
- "ATQ0V1N1X4Y0&C1&D2%E2\\K5+FCLASS=0S37=0\015", /* All others */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ZOOMV92 = /* ZOOM V.92 */
- {
- "Zoom V.92 with V.44 compression",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0V1N1X4Y0&C1&D2&S0%E2\\K5+FCLASS=0S37=0+MS=V92\015", /* K95 */
-#else
-#ifdef VMS
- "ATQ0V1N1X4Y0&C1&D2&S1%E2\\K5+FCLASS=0S37=0+MS=V92\015", /* VMS */
-#else
- "ATQ0V1N1X4Y0&C1&D2%E2\\K5+FCLASS=0S37=0+MS=V92\015", /* All others */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4S32=17S33=19\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT&Q5\015", /* ec_on_str */
- "AT&Q0\015", /* ec_off_str */
- "AT%C1+DCS=1,1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-
-/*
- Now the "old" modems, all grouped together, and also within
- "if not defined MINIDIAL"...
-*/
-#ifdef OLDMODEMS
-
-static
-MDMINF CERMETEK = /* Information for "Cermetek Info-Mate 212 A" modem */
- {
- "Cermetek Info-Mate 212 A",
- "", /* pulse command */
- "", /* tone command */
- 20, /* dial_time */
- "BbPpTt", /* pause_chars */
- 0, /* pause_time */
- " XY\016R\015", /* wake_str */
- 200, /* wake_rate */
- "", /* wake_prompt */
- "", /* dmode_str */
- NULL, /* dmode_prompt */
- "\016D '%s'\015", /* dial_str */
- 200, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 1200L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF DF03 = /* information for "DEC DF03-AC" modem */
- {
- "Digital DF03-AC",
- "", /* pulse command */
- "", /* tone command */
- 27, /* dial_time */
- "=", /* pause_chars */
- 15, /* pause_time */
- "\001\002", /* wake_str */
- 0, /* wake_rate */
- "", /* wake_prompt */
- "", /* dmode_str */
- NULL, /* dmode_prompt */
- "%s", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF DF100 = /* information for "DEC DF100-series" modem */
- /*
- * The telephone "number" can include "P"s and/or "T"s
- * within it to indicate that subsequent digits are
- * to be dialed using pulse or tone dialing. The
- * modem defaults to pulse dialing. You may modify
- * the dial string below to explicitly default all
- * dialing to pulse or tone, but doing so prevents
- * the use of phone numbers that you may have stored
- * in the modem's memory.
- */
- {
- "Digital DF-100",
- "", /* pulse command */
- "", /* tone command */
- 30, /* dial_time */
- "=", /* pause_chars */
- 15, /* pause_time */
- "\001", /* wake_str */
- 0, /* wake_rate */
- "", /* wake_prompt */
- "", /* dmode_str */
- NULL, /* dmode_prompt */
- "%s#", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF DF200 = /* information for "DEC DF200-series" modem */
- /*
- * The telephone "number" can include "P"s and/or "T"s
- * within it to indicate that subsequent digits are
- * to be dialed using pulse or tone dialing. The
- * modem defaults to pulse dialing. You may modify
- * the dial string below to explicitly default all
- * dialing to pulse or tone, but doing so prevents
- * the use of phone numbers that you may have stored
- * in the modem's memory.
- */
- {
- "Digital DF-200",
- "", /* pulse command */
- "", /* tone command */
- 30, /* dial_time */
- "=W", /* pause_chars */ /* =: second tone; W: 5 secs */
- 15, /* pause_time */ /* worst case */
- "\002", /* wake_str */ /* allow stored number usage */
- 0, /* wake_rate */
- "", /* wake_prompt */
- "", /* dmode_str */
- NULL, /* dmode_prompt */
-#ifdef COMMENT
- "%s!", /* dial_str */
-#else
- " d %s\015",
-#endif /* COMMENT */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF GDC = /* information for "GeneralDataComm 212A/ED" modem */
- {
- "GeneralDataComm 212A/ED",
- "", /* pulse command */
- "", /* tone command */
- 32, /* dial_time */
- "%", /* pause_chars */
- 3, /* pause_time */
- "\015\015", /* wake_str */
- 500, /* wake_rate */
- "$", /* wake_prompt */
- "D\015", /* dmode_str */
- ":", /* dmode_prompt */
- "T%s\015", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 1200L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF PENRIL = /* information for "Penril" modem */
- {
- "Penril modem",
- "", /* pulse command */
- "", /* tone command */
- 50, /* dial_time */
- "", /* pause_chars */
- 0, /* pause_time */
- "\015\015", /* wake_str */
- 300, /* wake_rate */
- ">", /* wake_prompt */
- "k\015", /* dmode_str */
- ":", /* dmode_prompt */
- "%s\015", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF RACAL = /* Racal Vadic VA4492E */
- {
- "Racal Vadic VA4492E",
- "", /* pulse command */
- "", /* tone command */
- 35, /* dial_time (manual says modem is hardwired to 60) */
- "Kk", /* pause_chars */
- 5, /* pause_time */
- "\005\015", /* wake_str, ^E^M */
- 50, /* wake_rate */
- "*", /* wake_prompt */
- "D\015", /* dmode_str */
- "?", /* dmode_prompt */
- "%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 5, /* esc_char, ^E */
- "\003\004", /* hup_str, ^C^D */
- 0, /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF VENTEL = /* Information for Ven-Tel modem */
- {
- "Ven-Tel",
- "", /* pulse command */
- "", /* tone command */
- 20, /* dial_time */
- "%", /* pause_chars */
- 5, /* pause_time */
- "\015\015\015", /* wake_str */
- 300, /* wake_rate */
- "$", /* wake_prompt */
- "K\015", /* dmode_str (was "") */
- "Number to call: ", /* dmode_prompt (was NULL) */
- "%s\015", /* dial_str (was "<K%s\r>") */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-
-static
-MDMINF CONCORD = /* Info for Condor CDS 220 2400b modem */
- {
- "Concord Condor CDS 220 2400b",
- "", /* pulse command */
- "", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
- "\015\015", /* wake_str */
- 20, /* wake_rate */
- "CDS >", /* wake_prompt */
- "", /* dmode_str */
- NULL, /* dmode_prompt */
- "<D M%s\015>", /* dial_str */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char */
- "", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_off_str */
- "", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 2400L, /* max_speed */
- 0, /* capas */
- NULL /* ok_fn */
-};
-#endif /* OLDMODEMS */
-
-static
-MDMINF MICROCOM = /* Microcom modems in native SX mode */
- /* (long answer only) */
-{
- "Microcom MNP modems in SX command mode",
- "DP\015", /* pulse command */
- "DT\015", /* tone command */
- 35, /* dial_time */
- ",!@", /* pause_chars (! and @ aren't pure pauses) */
- 3, /* pause_time */
-/*
- The following sets 8 bits, no parity, BREAK passthru, and SE0 disables the
- escape character, which is a single character with no guard time, totally
- unsafe, so we have no choice but to disable it. Especially since, by
- default, it is Ctrl-A, which is Kermit's packet-start character. We would
- change it to something else, which would enable "mdmhup()", but the user
- wouldn't know about it. Very bad. Note: SE1 sets it to Ctrl-A, SE2
- sets it to Ctrl-B, etc (1..31 allowed). Also SE/Q sets it to "Q".
-*/
- "SE0;S1P4;SBRK5\015", /* wake_str */
- 100, /* wake_rate */
- "!", /* wake_prompt */
- "", /* dmode_str */
- NULL, /* dmode_prompt */
- "D%s\015", /* dial_str - number up to 39 chars */
- 0, /* dial_rate */
- 0, /* esc_time */
- 0, /* esc_char - we can't use this */
- "", /* hup_str - it's "H" but can't use */
- "SF13\015", /* hwfc_str */
- "SF11\015", /* swfc_str */
- "SF10\015", /* nofc_str */
- "BAOFF;SMAUT\015", /* ec_on_str */
- "BAON;SMDIR\015", /* ec_off_str */
- "COMP1\015", /* dc_on_str */
- "COMP0\015", /* dc_off_str */
- "AA", /* aa_on_str */
- "", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "SA2", /* sp_off_str */
- "SA0", /* sp_on_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 0L, /* max_speed */
- CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW|CKD_KS, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF MICROLINK = /* MicroLink ... */
- { /* 14.4TQ,TL,PC;28.8TQ,TQV;2440T/TR */
- "ELSA MicroLink 14.4, 28.8, 33.6 or 56K", /* ELSA GmbH, Aachen */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4&S0\\D0&C1&D2\\K5\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4&S1\\K5\015", /* wake_str */
-#else
- "ATQ0X4\\K5\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H\015", /* hup_str */
- "AT\\Q3\015", /* hwfc_str */
- "AT\\Q1\\X0\015", /* swfc_str */
- "AT\\Q0\015", /* nofc_str */
- "AT\\N3\015", /* ec_on_str */
- "AT\\N0\015", /* ec_off_str */
- "AT%C3\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "\\J0", /* sb_on_str (?) */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ULINKV250 = /* MicroLink V.250 */
- { /* 56Kflex, V.90; V.250 command set */
- "ELSA MicroLink 56K V.250", /* ELSA GmbH, Aachen */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- /* \D0 = DSR & CTS always on but hwfc overrides on CTS. */
- "ATQ0E1V1X4&S0\\D0&C1&D2\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0X4&S1\015", /* wake_str */
-#else
- "ATQ0X4\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT+IFC=2,2\015", /* hwfc_str */
- "AT+IFC=1,1\015", /* swfc_str */
- "AT+IFC=0,0\015", /* nofc_str */
- "AT+ES=3,0\015", /* ec_on_str */
- "AT+ES=1,0\015", /* ec_off_str */
- "AT+DS=3,0,2048,32\015", /* dc_on_str */
- "AT+DS=0,0\015", /* dc_off_str */
-
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str (?) */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-#endif /* MINIDIAL */
-
-static
-MDMINF ITUTV250 = /* ITU-T V.250 conforming modem */
-{
- "Any ITU-T V.25ter/V.250 conformant modem",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
- "ATQ0E1V1X4&C1&D2\015", /* wake_str (no &Sn in V.25) */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT+IFC=2,2\015", /* hwfc_str */
- "AT+IFC=1,1\015", /* swfc_str */
- "AT+IFC=0,0\015", /* nofc_str */
- "AT+ES=3,0,2;+EB=1,0,30\015", /* ec_on_str */
- "AT+ES=0\015", /* ec_off_str */
- "AT+DS=3,0\015", /* dc_on_str */
- "AT+DS=0,0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-#ifndef CK_TAPI
-static
-#endif /* CK_TAPI */
-MDMINF GENERIC = /* Generic high speed ... */
- {
- "Generic high-speed AT command set",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
- "", /* wake_str */
- 0, /* wake_rate */
- "", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_on_str */
- "", /* sp_off_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW, /* capas */
- getok /* ok_fn */
-};
-
-#ifndef MINIDIAL
-static
-MDMINF XJACK = /* Megahertz X-Jack */
- {
- "Megahertz X-Jack XJ3144 / CC6144",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4N1&C1&D2\\K5\015", /* wake_str */
-#else
- "ATQ0X4N1\\K5\015", /* wake_str */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT\\N3&Q5\015", /* ec_on_str */
- "AT\\N1&Q0\015", /* ec_off_str */
- "AT%C3\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF SPIRITII = /* QuickComm Spirit II */
- {
- "QuickComm Spirit II",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
- "AT&F\015", /* wake_str */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H\015", /* hup_str */
- "AT*F3\015", /* hwfc_str */
- "AT*F2\015", /* swfc_str */
- "AT*F0\015", /* nofc_str */
- "AT*E6\015", /* ec_on_str */
- "AT*E0\015", /* ec_off_str */
- "AT*E9\015", /* dc_on_str */
- "AT*E0\015", /* dc_off_str */
- "ATS0=2\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF MONTANA = { /* Motorola Montana */
- "Motorola Montana", /* Name */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4&S0&C1&D2\\K5\\V1\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1X4&S1\\K5\\V1\015", /* wake_str */
-#else
- "ATQ0E1X4\\K5\\V1\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT\\Q3\015", /* hwfc_str */
- "AT\\Q1\015", /* swfc_str */
- "AT\\Q0\015", /* nofc_str */
- "AT\\N4\015", /* ec_on_str */
- "AT\\N1\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT\\J0\015", /* sb_on_str */
- "AT\\J1\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF COMPAQ = { /* Compaq Data+Fax Modem */
- "Compaq Data+Fax Modem", /* Name */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4&S0&C1&D2\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1X4&S1\015", /* wake_str */
-#else
- "ATQ0E1X4\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT\\Q3\015", /* hwfc_str (same as &K3) */
- "AT\\Q1\015", /* swfc_str (same as &K4) */
- "AT\\Q0\015", /* nofc_str (same as &K0) */
- "AT\\N3\015", /* ec_on_str */
- "AT\\N0\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT\\N3\015", /* sb_on_str */
- "AT\\N1\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL0\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-
-static
-MDMINF FUJITSU = { /* Fujitsu */
- "Fujitsu Fax/Modem Adapter", /* Name */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4&S0&C1&D2\\K5\\N3\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1X4&S1\\K5\\N3\015", /* wake_str */
-#else
- "ATQ0E1X4\\K5\\N3\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\\Q3\015", /* hwfc_str */
- "AT&K4\\Q1\015", /* swfc_str */
- "AT&K0\\Q0\015", /* nofc_str */
- "AT\\N3\015", /* ec_on_str */
- "AT\\N0\015", /* ec_off_str */
- "AT%C1", /* dc_on_str */
- "AT%C0", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT\\J0\015", /* sb_on_str */
- "AT\\J1\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF MHZATT = /* Megahertz AT&T V.34 */
- {
- "Megahertz AT&T V.34",
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4N1&C1&D2\\K5\015", /* wake_str */
-#else
- "ATQ0X4N1\\K5\015", /* wake_str */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT\\N3\015", /* ec_on_str */
- "AT\\N0\015", /* ec_off_str */
- "AT%C1\"H3\015", /* dc_on_str */
- "AT%C0\"H0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT\\J0\015", /* sb_on_str */
- "AT\\J1\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF SUPRASON = /* SupraSonic */
- {
- "Diamond SupraSonic 288V+", /* Diamond Multimedia Systems Inc */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1N1W0X4Y0&S0&C1&D2\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1N1W0X4Y0&S1\015", /* wake_str */
-#else
- "ATQ0E1N1W0X4Y0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K\015", /* nofc_str */
- "AT&Q5\\N3S48=7\015", /* ec_on_str */
- "AT&Q0\\N1\015", /* ec_off_str */
- "AT%C3S46=138\015", /* dc_on_str */
- "AT%C0S46=136\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM\015", /* sp_off_str */
- "ATL\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF BESTDATA = /* Best Data */
- {
- "Best Data Fax Modem", /* Best Data Fax Modem */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1N1W0X4Y0&S0&C1&D2\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1N1W0X4Y0&S1\015", /* wake_str */
-#else
- "ATQ0E1N1W0X4Y0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K\015", /* nofc_str */
- "AT&Q6\\N3\015", /* ec_on_str */
- "AT&Q0\\N1\015", /* ec_off_str */
- "AT%C3\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT\\N3\015", /* sb_on_str */
- "AT\\N0\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ATT1900 = /* AT&T Secure Data STU III 1900 */
- {
- "AT&T Secure Data STU III Model 1900", /* name */
- "", /* pulse command */
- "", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4\015", /* wake_str */
-#else
- "ATQ0E1X4\015", /* wake_str */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_on_str */
- "", /* sp_off_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 9600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_HW, /* capas */
- getok /* ok_fn */
-};
-
-/*
- Experimentation showed that hardly any of the documented commands did
- anything other that print ERROR. At first there was no communication at
- all at 9600 bps -- turns out the interface speed was stuck at 2400.
- ATS28=130 (given at 2400 bps) allowed it to work at 9600.
-*/
-static
-MDMINF ATT1910 = /* AT&T Secure Data STU III 1910 */
- { /* Adds V.32bis, V.42, V.42bis */
- "AT&T Secure Data STU III Model 1910", /* name */
-
-/* Believe it or not, "ATT" and "ATP" result in ERROR */
-
- "", /* pulse command */
- "", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0E1V1X4\015", /* wake_str */
-#else
- "ATQ0E1X4\015", /* wake_str */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
-#ifdef COMMENT
-/* These are evidently read-only registers */
- "ATS46=138S47=0\015", /* ec_on_str */
- "ATS46=138S47=128\015", /* ec_off_str */
- "ATS46=138S47=0\015", /* dc_on_str */
- "ATS46=138S47=128\015", /* dc_off_str */
-#else
- "",
- "",
- "",
- "",
-#endif /* COMMENT */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_on_str */
- "", /* sp_off_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 9600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF KEEPINTOUCH = /* AT&T KeepinTouch Card Modem */
- {
- "AT&T KeepinTouch V.32bis Card Modem", /* Name */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
-/* This used to include &C1&S0&D2+Q0 but that gives ERROR */
- "ATQ0E1V1X4&S0&C1&D2\\K5\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1X4&S1\\K5\015", /* wake_str */
-#else
- "ATQ0E1X4\\K5\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT\\Q3\015", /* hwfc_str */
- "AT\\Q1\\X0\015", /* swfc_str */
- "AT\\Q0\015", /* nofc_str */
- "AT\\N3-J1\015", /* ec_on_str */
- "AT\\N1\015", /* ec_off_str */
- "AT%C3\"H3\015", /* dc_on_str */
- "AT%C0\"H0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "ATN0\\J0\015", /* sb_on_str */
- "ATN1\\J1\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 57600L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ROLM_AT = /* Rolm data phone with AT command set */
- {
- "Rolm 244PC or 600 Series with AT Command Set",
- "", /* pulse command */
- "", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1\015", /* wake_str */
-#else
- "ATQ0\015", /* wake_str */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATDT%s\015", /* dial_str -- always Tone */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "", /* hwfc_str */
- "", /* swfc_str */
- "", /* nofc_str */
- "", /* ec_on_str */
- "", /* ec_off_str */
- "", /* dc_on_str */
- "", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "", /* sb_on_str */
- "", /* sb_off_str */
- "", /* sp_on_str */
- "", /* sp_off_str */
- "", /* vol1_str */
- "", /* vol2_str */
- "", /* vol3_str */
- "", /* ignoredt */
- "", /* ini2 */
- 19200L, /* max_speed */
- CKD_AT, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF ATLAS = /* Atlas / Newcom ixfC 33.6 */
- {
- "Atlas / Newcom 33600ixfC Data/Fax Modem", /* Name */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATZ0&FQ0V1&C1&D2\015", /* wake_str */
-#else
- "ATZ0&FQ0V1\015", /* wake_str */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT\"H3\015", /* ec_on_str */
- "AT\"H0\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "ATN0\\J0\015", /* sb_on_str */
- "ATN1\\J1\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF CODEX = { /* Motorola Codex */
- "Motorola Codex 326X Series", /* Name - AT&V to see settings */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- /* &M0=Async (not sync) */
- /* *MM0=Automatic modulation negotiation */
- /* *DE22=Automatic data rate */
- "ATZQ0E1V1X4Y0*DE22*MM0&C1&M0&S0&D2\015", /* wake_str */
-#else
-#ifdef VMS
- "ATZQ0E1V1X4Y0*DE22*MM0&C1&M0&S1\015", /* wake_str */
-#else
- "ATZQ0E1V1X4Y0*DE22*MM0&C1&M0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT*MF1*FL3\015", /* hwfc_str */
- "AT*MF1*FL1\015", /* swfc_str */
- "AT*MF0*FL0\015", /* nofc_str */
- "AT*EC0*SM3*SC0\015", /* ec_on_str */
- "AT*SM0\015", /* ec_off_str */
- "AT*DC1\015", /* dc_on_str */
- "AT*DC0\015", /* dc_off_str */
- "AT*AA5S0=1\015", /* aa_on_str */
- "AT*AA5S0=0\015", /* aa_off_str */
- "AT*SC1\015", /* sb_on_str */
- "AT*SC0\015", /* sb_off_str */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3*BD2\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF MT5634ZPX = /* Multitech */
- {
- "Multitech MT5634ZPX", /* name */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATE1Q0V1X4&S0&C1&D2&Q0\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0E1X4&S1&Q0\015", /* wake_str */
-#else
- "ATQ0E1X4&Q0\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT&K3\015", /* hwfc_str */
- "AT&K4\015", /* swfc_str */
- "AT&K0\015", /* nofc_str */
- "AT\\N3\015", /* ec_on_str */
- "AT\\N1\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT\\J0\015", /* sb_on_str */
- "AT\\J1\015", /* sb_off_str (NOT SUPPORTED) */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-
-static
-MDMINF MOTSM56 = /* Motorola SM56 Chipset */
- {
- "Motorola SM56 V.90 chipset", /* name */
- "ATP\015", /* pulse command */
- "ATT\015", /* tone command */
- 35, /* dial_time */
- ",", /* pause_chars */
- 2, /* pause_time */
-#ifdef OS2
- "ATQ0V1X4&S0&C1&D2*MM16\015", /* wake_str */
-#else
-#ifdef VMS
- "ATQ0V1X4&S1&C1&D2*MM16\015", /* wake_str */
-#else
- "ATQ0V1X4&C1&D2*MM16\015", /* wake_str */
-#endif /* VMS */
-#endif /* OS2 */
- 0, /* wake_rate */
- "OK\015", /* wake_prompt */
- "", /* dmode_str */
- "", /* dmode_prompt */
- "ATD%s\015", /* dial_str */
- 0, /* dial_rate */
- 1100, /* esc_time */
- 43, /* esc_char */
- "ATQ0H0\015", /* hup_str */
- "AT\\Q3\015", /* hwfc_str */
- "AT\\Q1\015", /* swfc_str */
- "AT\\Q0\015", /* nofc_str */
- "AT\\N7\015", /* ec_on_str */
- "AT\\N1\015", /* ec_off_str */
- "AT%C1\015", /* dc_on_str */
- "AT%C0\015", /* dc_off_str */
- "ATS0=1\015", /* aa_on_str */
- "ATS0=0\015", /* aa_off_str */
- "AT\\J0\015", /* sb_on_str */
- "AT\\J1\015", /* sb_off_str (NOT SUPPORTED) */
- "ATM1\015", /* sp_on_str */
- "ATM0\015", /* sp_off_str */
- "ATL1\015", /* vol1_str */
- "ATL2\015", /* vol2_str */
- "ATL3\015", /* vol3_str */
- "ATX3\015", /* ignoredt */
- "", /* ini2 */
- 115200L, /* max_speed */
- CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
- getok /* ok_fn */
-};
-#endif /* MINIDIAL */
-
-/* END MDMINF STRUCT DEFINITIONS */
-
-/*
- Table to convert modem numbers to MDMINF struct pointers.
- The entries MUST be in ascending order by modem number, without any
- "gaps" in the numbers, and starting from one (1).
-*/
-
-MDMINF *modemp[] = {
-#ifdef MINIDIAL
- NULL, /* 0 */
- &CCITT, /* 1 */
- &HAYES, /* 2 */
- &UNKNOWN, /* 3 */
- &DUMMY, /* 4 */
- &GENERIC, /* 5 */
- &ITUTV250 /* 6 */
-#else /* Not MINIDIAL */
- NULL, /* 0 */
- &ATTDTDM, /* 1 */
- &ATTISN, /* 2 */
- &ATTMODEM, /* 3 */
- &CCITT, /* 4 */
-#ifdef OLDMODEMS
- &CERMETEK, /* 5 */
- &DF03, /* 6 */
- &DF100, /* 7 */
- &DF200, /* 8 */
- &GDC, /* 9 */
-#else
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
-#endif /* OLDMODEMS */
- &HAYES, /* 10 */
-#ifdef OLDMODEMS
- &PENRIL, /* 11 */
- &RACAL, /* 12 */
-#else
- NULL,
- NULL,
-#endif /* OLDMODEMS */
- &UNKNOWN, /* 13 */
-#ifdef OLDMODEMS
- &VENTEL, /* 14 */
- &CONCORD, /* 15 */
-#else
- NULL,
- NULL,
-#endif /* OLDMODEMS */
- &DUMMY, /* 16 */
- &ROLM, /* 17 */
-#ifdef OLDMODEMS
- &MICROCOM, /* 18 */
-#else
- NULL,
-#endif /* OLDMODEMS */
- &USR, /* 19 USR Courier and Sportster */
- &OLDTB, /* 20 Old Telebits */
- &DIGITEL, /* 21 Digitel CCITT */
- &H_1200, /* 22 Hayes 1200 */
- &H_ULTRA, /* 23 Hayes Ultra */
- &H_ACCURA, /* 24 Hayes Optima */
- &PPI, /* 25 PPI */
- &DATAPORT, /* 26 Dataport */
- &BOCA, /* 27 Boca */
- &MOTOROLA, /* 28 Motorola UDS MOTOROLA */
- NULL, /* 29 Digicomm */
- NULL, /* 30 Dynalink */
- &INTEL, /* 31 Intel */
- &UCOM_AT, /* 32 Microcom in AT mode */
- &MULTITECH, /* 33 Multitech */
- &SUPRA, /* 34 Supra */
- &ZOLTRIX, /* 35 Zoltrix */
- &ZOOM, /* 36 Zoom */
- &ZYXEL, /* 37 ZyXEL */
- &DUMMY, /* 38 TAPI */
- &NEWTB, /* 39 New-Telebit */
- &MAXTECH, /* 40 MaxTech */
- &DUMMY, /* 41 User-defined */
- &RWV32, /* 42 Rockwell V.32 */
- &RWV32B, /* 43 Rockwell V.32bis */
- &RWV34, /* 44 Rockwell V.34 */
- &MWAVE, /* 45 IBM Mwave */
- &TELEPATH, /* 46 Gateway 2000 Telepath II 28.8 */
- &MICROLINK, /* 47 MicroLink modems */
- &CARDINAL, /* 48 Cardinal */
- &GENERIC, /* 49 Generic high-speed */
- &XJACK, /* 50 Megahertz-Xjack */
- &SPIRITII, /* 51 QuickComm Spirit II */
- &MONTANA, /* 52 Motorola Montana */
- &COMPAQ, /* 53 Compaq Data+Fax */
- &FUJITSU, /* 54 Fujitsu */
- &MHZATT, /* 55 Megahertz AT&T V.34 */
- &SUPRASON, /* 56 Suprasonic */
- &BESTDATA, /* 57 Best Data */
- &ATT1900, /* 58 AT&T Secure Data STU III 1900 */
- &ATT1910, /* 59 AT&T Secure Data STU III 1910 */
- &KEEPINTOUCH, /* 60 AT&T KeepinTouch */
- &USRX2, /* 61 USR XJ-1560 X2 */
- &ROLM_AT, /* 62 Rolm with AT command set */
- &ATLAS, /* 63 Atlas / Newcom */
- &CODEX, /* 64 Motorola Codex */
- &MT5634ZPX, /* 65 Multitech MT5634ZPX */
- &ULINKV250, /* 66 Microlink V.250 56K */
- &ITUTV250, /* 67 Generic ITU-T V.250 */
- &RWV90, /* 68 Rockwell V.90 56K */
- &SUPRAX, /* 69 Diamond Supra Express V.90 */
- &LUCENT, /* 70 Lucent Venus chipset */
- &PCTEL, /* 71 PCTel */
- &CONEXANT, /* 72 Conexant */
- &ZOOMV34, /* 73 Zoom V.34 */
- &ZOOMV90, /* 74 Zoom V.90 */
- &ZOOMV92, /* 75 Zoom V.92 */
- &MOTSM56 /* 76 Motorola SM56 chipset */
-#endif /* MINIDIAL */
-};
-/*
- * Declare modem names and associated numbers for command parsing,
- * and also for doing number-to-name translation.
- *
- * The entries must be in alphabetical order by modem name.
- */
-struct keytab mdmtab[] = {
-#ifndef MINIDIAL
- "3com-usr-megahertz-56k", n_USRX2, CM_INV,
- "acer-v90", n_RWV90, M_ALIAS,
- "atlas-newcom-33600ifxC", n_ATLAS, 0,
- "att-1900-stu-iii", n_ATT1900, 0,
- "att-1910-stu-iii", n_ATT1910, 0,
- "att-7300", n_ATTUPC, 0,
- "att-dataport", n_DATAPORT, 0,
- "att-dtdm", n_ATTDTDM, 0,
- "att-isn", n_ATTISN, 0,
- "att-keepintouch", n_KEEPINTOUCH, 0,
- "att-switched-net", n_ATTMODEM, 0,
-
- "att7300", n_ATTUPC, CM_INV, /* old name */
- "attdtdm", n_ATTDTDM, CM_INV, /* old name */
- "attisn", n_ATTISN, CM_INV, /* old name */
- "attmodem", n_ATTMODEM, CM_INV, /* old name */
-
- "bestdata", n_BESTDATA, 0,
- "boca", n_BOCA, 0,
- "cardinal", n_CARDINAL, 0,
-#endif /* MINIDIAL */
- "ccitt-v25bis", n_CCITT, CM_INV, /* Name changed to ITU-T */
-#ifndef MINIDIAL
-#ifdef OLDMODEMS
- "cermetek", n_CERMETEK, M_OLD,
-#endif /* OLDMODEMS */
- "compaq", n_COMPAQ, 0,
-#ifdef OLDMODEMS
- "concord", n_CONCORD, M_OLD,
-#endif /* OLDMODEMS */
- "conexant", n_CONEXANT, 0,
- "courier", n_USR, CM_INV,
- "dataport", n_DATAPORT, CM_INV, /* == att-dataport */
-#ifdef OLDMODEMS
- "df03-ac", n_DF03, M_OLD,
- "df100-series", n_DF100, M_OLD,
- "df200-series", n_DF200, M_OLD,
-#endif /* OLDMODEMS */
- "digitel-dt22", n_DIGITEL, 0,
-#endif /* MINIDIAL */
- "direct", 0, CM_INV, /* Synonym for NONE */
-#ifndef MINIDIAL
- "fujitsu", n_FUJITSU, 0,
- "gateway-telepath", n_TELEPATH, 0,
-#ifdef OLDMODEMS
- "gdc-212a/ed", n_GDC, M_OLD,
- "ge", n_GENERIC, CM_INV|CM_ABR,
- "gen", n_GENERIC, CM_INV|CM_ABR,
- "gendatacomm", n_GDC, CM_INV, /* Synonym for GDC */
-#endif /* OLDMODEMS */
-#endif /* MINIDIAL */
- "gene", n_GENERIC, CM_INV|CM_ABR,
- "generic", n_GENERIC, 0,
- "generic-high-speed",n_GENERIC, CM_INV,
- "h", n_HAYES, CM_INV|CM_ABR,
- "ha", n_HAYES, CM_INV|CM_ABR,
- "hay", n_HAYES, CM_INV|CM_ABR,
- "haye", n_HAYES, CM_INV|CM_ABR,
- "hayes", n_HAYES, CM_INV|CM_ABR, /* Hayes 2400 */
-#ifndef MINIDIAL
- "hayes-1200", n_H_1200, 0,
-#endif /* MINIDIAL */
- "hayes-2400", n_HAYES, 0,
-#ifndef MINIDIAL
- "hayes-high-speed", n_H_ACCURA, 0,
- "hayes-accura", n_H_ACCURA, CM_INV,
- "hayes-optima", n_H_ACCURA, CM_INV,
- "hayes-ultra", n_H_ULTRA, CM_INV,
- "hst-courier", n_USR, CM_INV, /* Synonym for COURIER */
- "intel", n_INTEL, 0,
-#endif /* MINIDIAL */
-
- "itu-t-v250", n_ITUTV250, 0,
- "itu-t-v25bis", n_CCITT, 0, /* New name for CCITT */
- "itu-t-v25ter/v250",n_ITUTV250, CM_INV,
-
-#ifndef MINIDIAL
- "lucent", n_LUCENT, 0,
- "maxtech", n_MAXTECH, 0,
-
- "megahertz-att-v34", n_MHZATT, 0, /* Megahertzes */
- "megahertz-xjack", n_XJACK, CM_INV|CM_ABR,
- "megahertz-xjack-33.6", n_XJACK, 0,
- "megahertz-xjack-56k", n_USRX2, 0, /* 3COM/USR/Megahertz 33.6 PC Card */
-
- "mi", n_MICROCOM, CM_INV|CM_ABR,
- "mic", n_MICROCOM, CM_INV|CM_ABR,
- "micr", n_MICROCOM, CM_INV|CM_ABR,
- "micro", n_MICROCOM, CM_INV|CM_ABR,
- "microc", n_MICROCOM, CM_INV|CM_ABR,
- "microco", n_MICROCOM, CM_INV|CM_ABR,
- "microcom", n_MICROCOM, CM_INV|CM_ABR,
- "microcom-at-mode", n_UCOM_AT, 0, /* Microcom DeskPorte, etc */
- "microcom-sx-mode", n_MICROCOM, 0, /* Microcom AX,QX,SX, native mode */
- "microlink", n_MICROLINK, 0,
- "microlink-v250", n_ULINKV250, 0,
- "motorola-codex", n_CODEX, 0,
- "motorola-fastalk", n_MOTOROLA, 0,
- "motorola-lifestyle",n_MOTOROLA, 0,
- "motorola-montana", n_MONTANA, 0,
- "motorola-sm56-v90",n_MOTSM56, 0,
- "mt5634zpx", n_MT5634ZPX, 0,
- "multitech", n_MULTI, 0,
- "mwave", n_MWAVE, 0,
-#endif /* MINIDIAL */
- "none", 0, 0,
-#ifndef MINIDIAL
-#ifndef OLDTBCODE
- "old-telebit", n_TELEBIT, 0,
-#endif /* OLDTBCODE */
- "pctel", n_PCTEL, 0,
-#ifdef OLDMODEMS
- "penril", n_PENRIL, M_OLD,
-#endif /* OLDMODEMS */
- "ppi", n_PPI, 0,
-#ifdef OLDMODEMS
- "racalvadic", n_RACAL, M_OLD,
-#endif /* OLDMODEMS */
- "rockwell-v32", n_RWV32, 0,
- "rockwell-v32bis", n_RWV32B, 0,
- "rockwell-v34", n_RWV34, 0,
- "rockwell-v90", n_RWV90, 0,
- "rolm", n_ROLM, CM_INV|CM_ABR,
- "rolm-244pc", n_ROLMAT, 0,
- "rolm-600-series", n_ROLMAT, 0,
- "rolm-dcm", n_ROLM, 0,
- "smartlink-v90", n_USR, M_ALIAS,
- "spirit-ii", n_SPIRITII, 0,
- "sportster", n_USR, M_ALIAS,
- "sup", n_SUPRA, CM_INV|CM_ABR,
- "supr", n_SUPRA, CM_INV|CM_ABR,
- "supra", n_SUPRA, CM_INV|CM_ABR,
- "supra-express-v90",n_SUPRAX, 0,
- "suprafaxmodem", n_SUPRA, 0,
- "suprasonic", n_SUPRASON, 0,
-#ifdef CK_TAPI
- "tapi", n_TAPI, 0,
-#endif /* CK_TAPI */
- "te", n_TBNEW, CM_INV|CM_ABR,
- "tel", n_TBNEW, CM_INV|CM_ABR,
- "telebit", n_TBNEW, 0,
- "telepath", n_TELEPATH, CM_INV,
-#endif /* MINIDIAL */
- "unknown", n_UNKNOWN, 0,
- "user-defined", n_UDEF, 0,
-#ifndef MINIDIAL
-
- "usr", n_USR, CM_INV|CM_ABR,
- "usr-212a", n_HAYES, CM_INV|M_ALIAS,
- "usr-courier", n_USR, CM_INV,
- "usr-megahertz-56k", n_USRX2, 0,
- "usr-sportster", n_USR, CM_INV,
- "usr-xj1560-x2", n_USRX2, CM_INV,
- "usrobotics", n_USR, 0,
-
- "v25bis", n_CCITT, CM_INV, /* Name changed to ITU-T */
-#ifdef OLDMODEMS
- "ventel", n_VENTEL, M_OLD,
-#endif /* OLDMODEMS */
- "zoltrix-v34", n_ZOLTRIX, 0,
- "zoltrix-hsp-v90", n_PCTEL, M_ALIAS,
- "zoltrix-hcf-v90", n_ITUTV250, 0,
- "zoo", n_ZOOM, CM_INV|CM_ABR,
- "zoom", n_ZOOM, CM_INV|CM_ABR,
- "zoom-v32bis", n_ZOOM, 0,
- "zoom-v34", n_ZOOMV34, 0,
- "zoom-v90", n_ZOOMV90, 0,
- "zoom-v92", n_ZOOMV92, 0,
- "zyxel", n_ZYXEL, 0,
-#endif /* MINIDIAL */
- "", 0, 0
-};
-int nmdm = (sizeof(mdmtab) / sizeof(struct keytab)) - 1; /* Number of modems */
-
-#define CONNECTED 1 /* For completion status */
-#define D_FAILED 2
-#define D_PARTIAL 3
-
-static int tries = 0;
-static int mdmecho = 0; /* Assume modem does not echo */
-
-static char *p; /* For command strings & messages */
-
-#define LBUFL 200
-static char lbuf[LBUFL+4];
-char modemmsg[LBUFL+4] = { NUL, NUL }; /* DIAL response from modem */
-
-#ifdef DYNAMIC
-#define RBUFL 256
-static char *rbuf = NULL;
-#else
-#define RBUFL 63
-static char rbuf[RBUFL+1];
-#endif /* DYNAMIC */
-
-#ifdef DYNAMIC
-#define FULLNUML 256
-char *fbuf = NULL; /* For full (prefixed) phone number */
-#else
-#define FULLNUML 100
-char fbuf[FULLNUML];
-#endif /* DYNAMIC */
-
-static ckjmpbuf sjbuf;
-
-#ifdef CK_ANSIC
-static SIGTYP (*savalrm)(int); /* For saving alarm handler */
-static SIGTYP (*savint)(int); /* For saving interrupt handler */
-#else
-static SIGTYP (*savalrm)(); /* For saving alarm handler */
-static SIGTYP (*savint)(); /* For saving interrupt handler */
-#endif /* CK_ANSIC */
-
-#ifdef CKLOGDIAL
-static VOID
-dologdial(s) char *s; {
- char buf2[16];
- char * r = NULL;
- int x, m, n;
- extern char cxlogbuf[], uidbuf[], myhost[];
-
- if (!s) s = "";
- if ((x = strlen(s)) > 0) { /* Replace spaces by underscores */
- r = (char *)malloc(x+1);
- if (r) {
- int i;
- for (i = 0; i <= x; i++) {
- if (s[i] != 0 && s[i] <= SP)
- r[i] = '_';
- else
- r[i] = s[i];
- }
- s = r;
- }
- }
- p = ckdate();
- n = ckstrncpy(cxlogbuf,p,CXLOGBUFL);
- if (!uidbuf[0]) {
- debug(F100,"dologdial uidbuf empty","",0);
- ckstrncpy(uidbuf,(char *)whoami(),UIDBUFLEN);
- }
- m = strlen(uidbuf)+strlen(myhost)+strlen(ttname)+strlen(s)+strlen(buf2)+32;
- if (n+m < CXLOGBUFL-1) {
- p = cxlogbuf+n;
- if (diallcc && diallac) {
- buf2[0] = '+';
- ckmakmsg(&buf2[1],15,diallcc,"(",diallac,")");
- } else {
- ckstrncpy(buf2,"Unknown",16);
- }
- sprintf(p," %s %s T=DIAL H=%s D=%s N=%s O=%s ", /* safe (prechecked) */
- uidbuf,
- ckgetpid(),
- myhost,
- ttname,
- s,
- buf2
- );
- debug(F110,"dologdial cxlogbuf",cxlogbuf,0);
- } else
- sprintf(p,"LOGDIAL BUFFER OVERFLOW");
- if (r) free(r);
-}
-#endif /* CKLOGDIAL */
-
-#ifndef MINIDIAL
-
-#ifdef COMMENT
-static VOID
-xcpy(to,from,len) /* Copy the given number of bytes */
- register char *to, *from;
- register unsigned int len; {
- while (len--) *to++ = *from++;
-}
-#endif /* COMMENT */
-#endif /* MINIDIAL */
-
-static SIGTYP
-#ifdef CK_ANSIC
-dialtime(int foo) /* Timer interrupt handler */
-#else
-dialtime(foo) int foo; /* Timer interrupt handler */
-#endif /* CK_ANSIC */
-/* dialtime */ {
-
- fail_code = F_TIME; /* Failure reason = timeout */
- debug(F100,"dialtime caught SIGALRM","",0);
-#ifdef BEBOX
-#ifdef BE_DR_7
- alarm_expired();
-#endif /* BE_DR_7 */
-#endif /* BEBOX */
-#ifdef OS2
- signal(SIGALRM, dialtime);
-#endif /* OS2 */
-#ifdef __EMX__
- signal(SIGALRM, SIG_ACK); /* Needed for OS/2 */
-#endif /* __EMX__ */
-
-#ifdef OSK /* OS-9 */
-/*
- We are in an intercept routine but do not perform a F$RTE (done implicitly
- by RTS), so we have to decrement the sigmask as F$RTE does. Warning:
- longjump only restores the CPU registers, NOT the FPU registers. So, don't
- use FPU at all or at least don't use common FPU (double or float) register
- variables.
-*/
- sigmask(-1);
-#endif /* OSK */
-
-#ifdef NTSIG
- if (foo == SIGALRM)
- PostAlarmSigSem();
- else
- PostCtrlCSem();
-#else /* NTSIG */
-#ifdef NT
- cklongjmp(ckjaddr(sjbuf),1);
-#else /* NT */
- cklongjmp(sjbuf,1);
-#endif /* NT */
-#endif /* NTSIG */
- /* NOTREACHED */
- SIGRETURN;
-}
-
-static SIGTYP
-#ifdef CK_ANSIC
-dialint(int foo) /* Keyboard interrupt handler */
-#else
-dialint(foo) int foo;
-#endif /* CK_ANSIC */
-/* dialint */ {
- fail_code = F_INT;
- debug(F100,"dialint caught SIGINT","",0);
-#ifdef OS2
- signal(SIGINT, dialint);
- debug(F100,"dialint() SIGINT caught -- dialint restored","",0) ;
-#endif /* OS2 */
-#ifdef __EMX__
- signal(SIGINT, SIG_ACK); /* Needed for OS/2 */
-#endif /* __EMX__ */
-#ifdef OSK /* OS-9, see comment in dialtime() */
- sigmask(-1);
-#endif /* OSK */
-#ifdef NTSIG
- PostCtrlCSem() ;
-#ifdef CK_TAPI
- PostTAPIConnectSem();
- PostTAPIAnswerSem();
-#endif /* CK_TAPI */
-#else /* NTSIG */
-#ifdef NT
- cklongjmp(ckjaddr(sjbuf),1);
-#else /* NT */
- cklongjmp(sjbuf,1);
-#endif /* NT */
-#endif /* NT */
- SIGRETURN;
-}
-
-/*
- Routine to read a character from communication device, handling TELNET
- protocol negotiations in case we're connected to the modem through a
- TCP/IP TELNET modem server.
-*/
-static int
-ddinc(n) int n; {
-#ifdef TNCODE
- int c = 0;
- int done = 0;
- debug(F101,"ddinc entry n","",n);
- while (!done) {
- c = ttinc(n);
- /* debug(F000,"ddinc","",c); */
- if (c < 0) return(c);
-#ifndef OS2
- if ((c == IAC) && network && IS_TELNET()) {
- switch (tn_doop((CHAR)(c & 0xff),duplex,ttinc)) {
- case 2: duplex = 0; continue;
- case 1: duplex = 1;
- default: continue;
- }
- } else done = 1;
-#else /* OS2 */
- done = !(c == IAC && network && IS_TELNET());
- scriptwrtbuf(c); /* TELNET negotiations handled by emulator */
-#endif /* OS2 */
- }
- return(c & 0xff);
-#else /* TNCODE */
- return(ttinc(n));
-#endif /* TNCODE */
-}
-
-static VOID
-ttslow(s,millisec) char *s; int millisec; { /* Output s-l-o-w-l-y */
-#ifdef TCPSOCKET
- extern int tn_nlm, tn_b_nlm;
-#endif /* TCPSOCKET */
- debug(F111,"ttslow",s,millisec);
- if (dialdpy && (duplex || !mdmecho)) { /* Echo the command in case modem */
- printf("%s\n",s); /* isn't echoing commands. */
-#ifdef OS2
- {
- char *s2 = s; /* Echo to emulator */
- while (*s2) {
- scriptwrtbuf((USHORT)*s2++);
- }
- scriptwrtbuf((USHORT)CR);
- scriptwrtbuf((USHORT)LF);
- }
-#endif /* OS2 */
- }
- for (; *s; s++) {
- ttoc(*s);
-#ifdef TCPSOCKET
- if (*s == CR && network && IS_TELNET()) {
- if (!TELOPT_ME(TELOPT_BINARY) && tn_nlm != TNL_CR)
- ttoc((char)((tn_nlm == TNL_CRLF) ? LF : NUL));
- else if (TELOPT_ME(TELOPT_BINARY) &&
- (tn_b_nlm == TNL_CRLF || tn_b_nlm == TNL_CRNUL))
- ttoc((char)((tn_b_nlm == TNL_CRLF) ? LF : NUL));
- }
-#endif /* TCPSOCKET */
- if (millisec > 0)
- msleep(millisec);
- }
-}
-
-/*
- * Wait for a string of characters.
- *
- * The characters are waited for individually, and other characters may
- * be received "in between". This merely guarantees that the characters
- * ARE received, and in the order specified.
- */
-static VOID
-waitfor(s) char *s; {
- CHAR c, x;
- while ((c = *s++)) { /* while more characters remain... */
- do { /* wait for the character */
- x = (CHAR) (ddinc(0) & 0177);
- debug(F000,"dial waitfor got","",x);
- if (dialdpy) {
- if (x != LF) conoc(x);
- if (x == CR) conoc(LF);
- }
- } while (x != c);
- }
-}
-
-static int
-didweget(s,r) char *s, *r; { /* Looks in string s for response r */
- int lr = (int)strlen(r); /* 0 means not found, 1 means found it */
- int i;
- debug(F110,"didweget",r,0);
- debug(F110," in",s,0);
- for (i = (int)strlen(s)-lr; i >= 0; i--)
- if ( s[i] == r[0] ) if ( !strncmp(s+i,r,lr) ) return( 1 );
- return( 0 );
-}
-
-
-/* R E S E T -- Reset alarms, etc. on exit. */
-
-static VOID
-dreset() {
- debug(F100,"dreset resetting alarm and signal handlers","",0);
- alarm(0);
- signal(SIGALRM,savalrm); /* restore alarm handler */
- signal(SIGINT,savint); /* restore interrupt handler */
- debug(F100,"dreset alarm and signal handlers reset","",0);
-}
-
-/*
- Call this routine when the modem reports that it has connected at a certain
- speed, giving that speed as the argument. If the connection speed is not
- the same as Kermit's current communication speed, AND the modem interface
- speed is not locked (i.e. DIAL SPEED-MATCHING is not ON), then change the
- device speed to the one given.
-*/
-static VOID
-#ifdef CK_ANSIC
-spdchg(long s)
-#else
-spdchg(s) long s;
-#endif /* CK_ANSIC */
-/* spdchg */ {
- int s2;
- if (!mdmspd) /* If modem interface speed locked, */
- return; /* don't do this. */
- if (speed != s) { /* Speeds differ? */
- s2 = s / 10L; /* Convert to cps expressed as int */
- if (ttsspd(s2) < 0) { /* Change speed. */
- printf(" WARNING - speed change to %ld failed.\r\n",s);
- } else {
- printf(" Speed changed to %ld.\r\n",s);
- speed = s; /* Update global speed variable */
- }
- }
-}
-
-/*
- Display all characters received from modem dialer through this routine,
- for consistent handling of carriage returns and linefeeds.
-*/
-static VOID
-#ifdef CK_ANSIC
-dialoc(char c)
-#else
-dialoc(c) char c;
-#endif /* CK_ANSIC */
-{ /* dialoc */ /* Dial Output Character */
- if (dialdpy) {
- if (c != LF) conoc(c); /* Don't echo LF */
- if (c == CR) conoc(LF); /* Echo CR as CRLF */
- }
-}
-
-#ifndef NOSPL
-char *
-getdm(x) int x; { /* Return dial modifier */
- MDMINF * mp;
- int m;
- int ishayes = 0;
- m = mdmtyp;
- if (m < 1)
- if (mdmsav > -1)
- m = mdmsav;
- if (m < 1)
- return("");
-#ifndef MINIDIAL
- if (m == n_TAPI)
- m = n_HAYES;
-#endif /* MINIDIAL */
- mp = modemp[m];
- ishayes = (dialcapas ? dialcapas : mp->capas) & CKD_AT;
- switch (x) {
- case VN_DM_LP:
- return(ishayes ? "," : "");
- case VN_DM_SP:
-#ifdef MINIDIAL
- return("");
-#else
- return(m == n_USR ? "/" : "");
-#endif /* MINIDIAL */
- case VN_DM_PD:
- return(ishayes ? "P" : "");
- case VN_DM_TD:
- return(ishayes ? "T" : "");
- case VN_DM_WA:
- return(ishayes ? "@" : "");
- case VN_DM_WD:
- return(ishayes ? "W" : "");
- case VN_DM_RC:
- return(ishayes ? ";" : "");
- case VN_DM_HF:
- return(ishayes ? "!" : "");
- case VN_DM_WB:
- return(ishayes ? "$" : "");
- }
- return("");
-}
-#endif /* NOSPL */
-
-static VOID
-getdialmth() {
- if (dialmauto && diallcc) { /* If DIAL METHOD AUTO... */
- int i; /* and we know our area code... */
- for (i = 0; i < ndialtocc; i++) { /* First check Tone countries list */
- if (!strcmp(dialtocc[i],diallcc)) {
- dialmth = XYDM_T;
- break;
- }
- }
- for (i = 0; i < ndialpucc; i++) { /* Then Pulse countries list */
- if (!strcmp(dialpucc[i],diallcc)) {
- dialmth = XYDM_P;
- break;
- }
- }
- }
-}
-
-VOID /* Get dialing defaults from environment */
-getdialenv() {
- char *p = NULL;
- int i, x;
-
- makestr(&p,getenv("K_DIAL_DIRECTORY"));
- if (p) {
- int i;
- xwords(p,(MAXDDIR - 2),dialdir,0);
- for (i = 0; i < (MAXDDIR - 1); i++) {
- if (!dialdir[i+1])
- break;
- else
- dialdir[i] = dialdir[i+1];
- }
- ndialdir = i;
- }
- xmakestr(&diallcc,getenv("K_COUNTRYCODE")); /* My country code */
- xmakestr(&dialixp,getenv("K_LD_PREFIX")); /* My long-distance prefix */
- xmakestr(&dialldp,getenv("K_INTL_PREFIX")); /* My international prefix */
- xmakestr(&dialldp,getenv("K_TF_PREFIX")); /* Ny Toll-free prefix */
-
-#ifndef NOICP
- p = getenv("K_DIAL_METHOD"); /* Local dial method */
- if (p) if (*p) {
- extern struct keytab dial_m[];
- extern int ndial_m;
- i = lookup(dial_m,p,ndial_m,&x);
- if (i > -1) {
- if (i == XYDM_A) {
- dialmauto = 1;
- dialmth = XYDM_D;
- } else {
- dialmauto = 0;
- dialmth = i;
- }
- }
- }
-#endif /* NOICP */
-
- p = NULL;
- xmakestr(&p,getenv("K_TF_AREACODE")); /* Toll-free areacodes */
- if (p) {
- int i;
- xwords(p,7,dialtfc,0);
- for (i = 0; i < 8; i++) {
- if (!dialtfc[i+1])
- break;
- else
- dialtfc[i] = dialtfc[i+1];
- }
- ntollfree = i;
- free(p);
- }
- for (i = 0; i < MAXTPCC; i++) { /* Clear Tone/Pulse country lists */
- dialtocc[i] = NULL;
- dialpucc[i] = NULL;
- }
- for (i = 0; i < MAXTPCC; i++) { /* Init Tone country list */
- if (tonecc[i])
- makestr(&(dialtocc[i]),tonecc[i]);
- else
- break;
- }
- ndialtocc = i;
- for (i = 0; i < MAXTPCC; i++) { /* Init Pulse country list */
- if (pulsecc[i])
- makestr(&(dialpucc[i]),pulsecc[i]);
- else
- break;
- }
- ndialpucc = i;
-
- if (diallcc) { /* Have country code */
- if (!strcmp(diallcc,"1")) { /* If it's 1 */
- if (!dialldp) /* Set these prefixes... */
- makestr(&dialldp,"1");
- if (!dialtfp)
- makestr(&dialtfp,"1");
- if (!dialixp)
- makestr(&dialixp,"011");
- if (ntollfree == 0) { /* Toll-free area codes */
- if ((dialtfc[0] = malloc(4))) {
- ckstrncpy(dialtfc[0],"800",4); /* 1970-something */
- ntollfree++;
- if ((dialtfc[1] = malloc(4))) {
- ckstrncpy(dialtfc[1],"888",4); /* 1996 */
- ntollfree++;
- if ((dialtfc[2] = malloc(4))) {
- ckstrncpy(dialtfc[2],"877",4); /* 5 April 1998 */
- ntollfree++;
- if ((dialtfc[3] = malloc(4))) {
- ckstrncpy(dialtfc[3],"866",4); /* 2000? */
- ntollfree++;
- }
- }
- }
- }
- }
- } else if (!strcmp(diallcc,"358") &&
- ((int) strcmp(zzndate(),"19961011") > 0)
- ) { /* Finland */
- if (!dialldp) /* Long-distance prefix */
- makestr(&dialldp,"9");
- if (!dialixp) /* International dialing prefix */
- makestr(&dialixp,"990");
- } else { /* Not NANP or Finland */
- if (!dialldp)
- makestr(&dialldp,"0");
- if (!dialixp)
- makestr(&dialixp,"00");
- }
- }
- xmakestr(&diallac,getenv("K_AREACODE"));
- xmakestr(&dialpxo,getenv("K_PBX_OCP"));
- xmakestr(&dialpxi,getenv("K_PBX_ICP"));
- p = getenv("K_PBX_XCH");
-#ifdef COMMENT
- xmakestr(&dialpxx,p);
-#else
- if (p) if (*p) {
- char * s = NULL;
- char * pp[MAXPBXEXCH+2];
- makestr(&s,p); /* Make a copy for poking */
- if (s) {
- xwords(s,MAXPBXEXCH+1,pp,0); /* Note: pp[] is 1-based. */
- for (i = 0; i <= MAXPBXEXCH; i++) {
- if (!pp[i+1]) break;
- makestr(&(dialpxx[i]),pp[i+1]);
- ndialpxx++;
- }
- makestr(&s,NULL); /* Free poked copy */
- }
- }
-#endif /* COMMENT */
-}
-
-static int
-dialfail(x) int x; {
- char * s;
-
- fail_code = x;
- debug(F101,"ckudial dialfail","",x);
- dreset(); /* Reset alarm and signal handlers */
-
- printf("%s Failure: ", func_code == 0 ? "DIAL" : "ANSWER");
- if (dialdpy) { /* If showing progress */
- debug(F100,"dial display is on","",0);
- p = ck_time(); /* get current time; */
- if (*p) printf("%s: ",p);
- }
- switch (fail_code) { /* Type of failure */
- case F_TIME: /* Timeout */
- if (dial_what == DW_INIT)
- printf ("Timed out while trying to initialize modem.\n");
- else if (dial_what == DW_DIAL)
- printf ("%s interval expired.\n",
- func_code == 0 ? "DIAL TIMEOUT" : "ANSWER timeout");
- else
- printf("Timeout.\n");
- fflush(stdout);
- if (mdmcapas & CKD_AT)
- ttoc('\015'); /* Send CR to interrupt dialing */
- /* Some Hayes modems don't fail with BUSY on busy lines */
- dialsta = DIA_TIMO;
- debug(F110,"dial","timeout",0);
- break;
-
- case F_INT: /* Dialing interrupted */
- printf ("Interrupted.\n");
- fflush(stdout);
-#ifndef NOXFER
- interrupted = 1;
-#endif /* NOXFER */
- debug(F111,"dial","interrupted",mdmcapas & CKD_AT);
- if (mdmcapas & CKD_AT)
- ttoc('\015'); /* Send CR to interrupt dialing */
- dialsta = DIA_INTR;
- break;
-
- case F_MODEM: /* Modem detected a failure */
- debug(F111,"dialfail()","lbuf",lbuf);
- if (lbuf && *lbuf) {
- printf(" \"");
- for (s = lbuf; *s; s++)
- if (isprint(*s))
- putchar(*s); /* Display printable reason */
- printf ("\"");
- } else printf(func_code == 0 ?
- " Call not completed." :
- " Call did not come in."
- );
- printf("\n");
- debug(F110,"dial",lbuf,0);
- if (dialsta < 0) dialsta = DIA_UNSP;
- break;
-
- case F_MINIT: /* Failure to initialize modem */
- printf ("Error initializing modem.\n");
- debug(F110,"dial","modem init",0);
- dialsta = DIA_NOIN;
- break;
-
- default:
- printf("unknown\n");
- debug(F110,"dial","unknown",0);
- fflush(stdout);
- if (mdmcapas & CKD_AT)
- ttoc('\015'); /* Send CR to interrupt dialing */
- dialsta = DIA_INTR;
- }
-
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
-
- if (dialsta < 0) dialsta = DIA_UERR; /* Set failure code */
- return(0); /* Return zero (important) */
-}
-
-/* C K D I A L -- Dial up the remote system */
-
-/* Returns 1 if call completed, 0 otherwise */
-
-static int mdmwait, mdmstat = 0;
-#ifndef CK_TAPI
-static
-#endif /* CK_TAPI */
-int waitct;
-int mdmwaitd = 10 ; /* dialtmo / mdmwait difference */
-static char c;
-static char *telnbr;
-
-static int wr = 0; /* wr = wake rate */
-static char * ws; /* ws = wake string */
-static char * xnum = NULL;
-static int inited = 0;
-
-static SIGTYP
-#ifdef CK_ANSIC
-_dodial(void * threadinfo)
-#else /* CK_ANSIC */
-_dodial(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* _dodial */ {
- char c2;
- char *dcmd, *s, *flocmd = NULL;
- int x = 0, n = F_TIME;
-
-#ifdef NTSIG
- signal( SIGINT, dialint );
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- }
-#endif /* NTSIG */
-
- dcmd = dialcmd ? dialcmd : mp->dial_str;
- if ((int)strlen(dcmd) + (int)strlen(telnbr) > (LBUFL - 2)) {
- printf("DIAL command + phone number too long!\n");
- dreset();
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN; /* No conversation with modem to complete dialing */
- }
- makestr(&xnum,telnbr);
-
- getdialmth(); /* Get dial method */
-
-#ifdef CK_ATDT
- /* Combine the SET DIAL METHOD command with the DIAL command string */
- if (!dialcmd && /* Using default DIAL command */
- (mdmcapas & CKD_AT) && /* AT command set only */
- ((dialmth == XYDM_T && !dialtone) || /* and using default */
- (dialmth == XYDM_P && !dialpulse))) { /* modem commands... */
- char c;
- debug(F110,"dial atdt xnum 1",xnum,0);
- s = dcmd;
- debug(F110,"dial atdt s",s,0);
- if (*telnbr != 'T' &&
- *telnbr != 'P' &&
- *telnbr != 't' &&
- *telnbr != 'p' &&
- !ckstrcmp(s,"atd",3,0) &&
- s[3] != 'T' &&
- s[3] != 'P' &&
- s[3] != 't' &&
- s[3] != 'p') {
- char xbuf[200];
- c = (dialmth == XYDM_T) ? 'T' : 'P';
- if (islower(s[0]))
- c = tolower(c);
- if ((int)strlen(telnbr) < 199) {
- sprintf(xbuf,"%c%s",c,telnbr);
- makestr(&xnum,xbuf);
- }
- }
- }
-#endif /* CK_ATDT */
- debug(F111,"_dodial",xnum,xredial);
-
- /* Hang up the modem (in case it wasn't "on hook") */
- /* But only if SET DIAL HANGUP ON... */
-
- if (!xredial) { /* Modem not initalized yet. */
- inited = 0;
- }
- if (!xredial || !inited) {
- if (dialhup() < 0) { /* Hangup first */
- debug(F100,"_dodial dialhup failed","",0);
-#ifndef MINIDIAL
- if (mdmcapas & CKD_TB) /* Telebits might need a BREAK */
- ttsndb(); /* first. */
-#endif /* MINIDIAL */
- if (dialhng && dialsta != DIA_PART) { /* If hangup failed, */
- ttclos(0); /* close and reopen the device. */
- if (ttopen(ttname,&local,mymdmtyp,0) < 0) {
- printf("Sorry, Can't hang up communication device.\n");
- printf("Try 'set line %s' again.\n",ttname);
- dialsta = DIA_HANG;
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
- dreset();
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
- }
- }
- }
- inited = 0; /* We hung up so must reinit */
- }
-#ifndef MINIDIAL
- /* Don't start talking to Rolm too soon */
- if (mymdmtyp == n_ROLM && dialsta != DIA_PART)
- msleep(500);
-#endif /* MINIDIAL */
-
- if (dialsta != DIA_PART /* Some initial setups. */
-#ifndef MINIDIAL
- && mymdmtyp != n_ATTUPC
-#endif /* MINIDIAL */
- ) {
- fail_code = F_MINIT; /* Default failure code */
- dial_what = DW_INIT; /* What I'm Doing Now */
- if (dialdpy) { /* If showing progress, */
- p = ck_time(); /* get timestamp. */
- if (!inited)
- if (*p)
- printf(" Initializing: %s...\n",p);
- }
- }
-#ifndef MINIDIAL
-#ifdef ATT7300
- if (mymdmtyp == n_ATTUPC) {
-/*
- For ATT7300/Unix PC's with their special internal modem. Whole dialing
- process is handled right here, an exception to the normal structure.
- Timeout and user interrupts are enabled during dialing. attdial() is in
- file ckutio.c. - jrd
-*/
- _PROTOTYP( int attdial, (char *, long, char *) );
- fail_code = F_MODEM; /* Default failure code */
- dial_what = DW_DIAL;
- if (dialdpy) { /* If showing progress */
- p = ck_time(); /* get current time; */
- if (*p)
- printf(" Dialing: %s...\n",p);
- }
- alarm(waitct); /* Set alarm */
- if (attdial(ttname,speed,telnbr)) { /* dial internal modem */
- dreset(); /* reset alarms, etc. */
- printf(" Call failed.\r\n");
- dialhup(); /* Hangup the call */
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
- dialsta = DIA_UERR;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN; /* return failure */
- }
- dreset(); /* reset alarms, etc. */
- ttpkt(speed,FLO_DIAX,parity); /* cancel dialing ioctl */
- if (!quiet && !backgrd) {
- if (dialdpy) {
- printf("\n");
- printf(" Call complete.\r\n");
- } else if (modemmsg[0])
- printf(" Call complete: \"%s\".\r\n",(char *)modemmsg);
- else
- printf(" Call complete.\r\n");
- }
-#ifdef CKLOGDIAL
- dologdial(telnbr);
-#endif /* CKLOGDIAL */
-
- dialsta = DIA_OK;
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN; /* No conversation with modem to complete dialing */
- } else
-#endif /* ATT7300 */
-#ifdef CK_TAPI
- if (tttapi && !tapipass) { /* TAPI Dialing */
- switch (func_code) {
- case 0: /* Dial */
- if (cktapidial(telnbr)) {
- fail_code = 0;
- if (partial) {
- dialsta = DIA_PART;
- } else {
- dialsta = DIA_OK;
- speed = ttgspd();
- }
- } else {
- if (dialsta == DIA_PART)
- cktapihangup();
- if (!fail_code)
- fail_code = F_MODEM;
- dialsta = DIA_TAPI;
- }
- break;
- case 1: { /* Answer */
- long strttime = time((long *)NULL);
- long diff = 0;
- do {
- if (dialatmo > 0) {
- strttime += diff;
- waitct -= diff;
- }
- fail_code = 0;
- if (cktapianswer()) { /* SUCCESS */
- dialsta = DIA_OK;
- speed = ttgspd();
- break;
- } else { /* FAILURE */
- if (fail_code) {
- dialsta = DIA_TAPI;
- break;
- } else {
- fail_code = F_MODEM;
- dialsta = DIA_TAPI;
- }
- }
- if (dialatmo > 0) {
- diff = time((long *)NULL) - strttime;
- }
- } while ((dialatmo > 0) ? (diff < waitct) : 1);
- break;
- }
- }
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
- } else
-#endif /* CK_TAPI */
-#endif /* MINIDIAL */
-
-/* Modems with AT command set... */
-
- if ((mdmcapas & CKD_AT) && dialsta != DIA_PART) {
-
- if (dialpace > -1) /* Set intercharacter pacing */
- wr = dialpace;
- else
- wr = mp->wake_rate;
-
- if (dialini) /* Get wakeup/init string */
- ws = dialini;
- else
- ws = mp->wake_str;
-#ifdef COMMENT
- if (!ws) ws = "\015"; /* If none, use CR */
-#endif /* COMMENT */
-
- /* First get the modem's attention and enable result codes */
-
- for (tries = 0; tries < 5; tries++) { /* Send short command */
- if (tries > 0) {
- ttoc('\015'); /* AT must go first for speed */
- msleep(wr); /* detection. */
- }
- if (mymdmtyp == n_GENERIC) /* Force word result codes */
- ttslow("ATQ0V1\015",wr); /* for generic modem type */
- else
- ttslow("ATQ0\015",wr);
- mdmstat = getok(tries < 2 ? 2 : tries, 1); /* Get response */
- if (mdmstat > 0) break; /* OK - done */
- if (dialdpy && tries > 0) {
- printf("\r\n No response from modem");
- if (tries == 4) {
- printf(".\r\n");
- dialsta = DIA_NRSP;
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN; /* return failure */
- }
- printf(", retrying%s...\r\n",
- (tries > 1) ? " again" : "");
- fflush(stdout);
- }
- ttflui();
- switch (tries) {
- case 0: msleep(100); break;
- case 1: ttsndb(); break;
- default:
- if (network) {
- ttsndb();
- } else {
- if (tries == 2) {
- tthang();
- ttflui();
- } else {
- mdmhup();
- }
- inited = 0;
- }
- }
- fflush(stdout);
- }
- debug(F101,"_dodial ATQ0 mdmstat","",mdmstat);
-
- if (xredial && inited) { /* Redialing... */
- ttoc('\015'); /* Cancel previous */
- msleep(250); /* Wait a bit */
-#ifdef COMMENT
-/* This wasn't the problem... */
- ttflui(); /* Clear out stuff from modem setup */
- ttslow("ATS7=60\015",wr); /* Redo carrier wait */
- getok(4,1); /* Get response */
-#endif /* COMMENT */
- alarm(0); /* Just in case... */
- ttflui(); /* Clear out stuff from modem setup */
- goto REDIAL; /* Skip setup - we already did it */
- }
-/*
- Do flow control next because a long init string echoing back could
- cause data overruns, causing us to miss the OK, or (worse) to get out
- of sync entirely.
-*/
- x = 0; /* User said SET DIAL FLOW RTS/CTS */
- if (dialfc == FLO_RTSC || /* Even if Kermit's FLOW isn't... */
- (dialfc == FLO_AUTO && flow == FLO_RTSC)) {
- if (dialhwfc) { /* User-defined HWFC string */
- if (*dialhwfc) {
- x = 1;
- flocmd = dialhwfc;
- }
- } else if ((mdmcapas & CKD_HW) && *(mp->hwfc_str)) {
- x = 1;
- flocmd = mp->hwfc_str;
- }
- } else if (dialfc == FLO_XONX || /* User said SET DIAL FLOW SOFT */
- (dialfc == FLO_AUTO && flow == FLO_XONX)) {
- if (dialswfc) {
- if (*dialswfc) {
- x = 1;
- flocmd = dialswfc;
- }
- } else if ((mdmcapas & CKD_SW) && *(mp->swfc_str)) {
- x = 1;
- flocmd = mp->swfc_str;
- }
- } else if (dialfc == FLO_NONE) { /* User said SET DIAL FLOW NONE */
- if (dialnofc) {
- if (*dialnofc) {
- x = 1;
- flocmd = dialnofc;
- }
- } else if (mp->nofc_str && *(mp->nofc_str)) {
- x = 1;
- flocmd = mp->nofc_str;
- }
- }
- if (x) { /* Send the flow control command */
- debug(F110,"_dodial flocmd",flocmd,0);
- for (tries = 4; tries > 0; tries--) { /* Send the command */
- ttslow(flocmd,wr);
- mdmstat = getok(5,1);
- if (mdmstat > 0) break;
- if (dialdpy && tries > 1)
- printf(" No response from modem, retrying%s...\n",
- (tries < 4) ? " again" : "");
- }
-
-#ifdef CK_TTSETFLOW
-#ifdef CK_RTSCTS
-/*
- So far only ckutio.c has ttsetflow().
- We have just told the modem to turn on RTS/CTS flow control and the modem
- has said OK. But we ourselves have not turned it on yet because of the
- disgusting ttpkt(...FLO_DIAL...) hack. So now, if the computer does not
- happen to be asserting RTS, the modem will no longer send characters to it.
- So at EXACTLY THIS POINT, we must enable RTS/CTS in the device driver.
-*/
- if (dialfc == FLO_RTSC ||
- (dialfc == FLO_AUTO && flow == FLO_RTSC)) {
- ttsetflow(FLO_RTSC);
- }
-#endif /* CK_RTSCTS */
-#endif /* CK_TTSETFLOW */
- }
- ttflui(); /* Clear out stuff from modem setup */
- msleep(250);
-
- if (!ws) goto xdialec; /* No init string */
- if (!*ws) goto xdialec;
-
- for (tries = 4; tries > 0; tries--) { /* Send init string */
- ttslow(ws,wr);
- mdmstat = getok(4,1); /* Get response */
- if (mdmstat > 0) break;
- if (dialdpy && tries > 1)
- printf(" No response from modem, retrying%s...\n",
- (tries < 4) ? " again" : "");
- }
- debug(F101,"_dodial wake_str mdmstat","",mdmstat);
-
- if (mdmstat < 1) { /* Initialized OK? */
- dialfail(F_MINIT); /* No, fail. */
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
- }
-
-#ifndef MINIDIAL
- } else if (mymdmtyp == n_ATTDTDM && dialsta != DIA_PART) { /* AT&T ... */
- ttsndb(); /* Send BREAK */
-#endif /* MINIDIAL */
-
- } else if (dialsta != DIA_PART) { /* All others */
-
- /* Place modem into command mode */
-
- ws = dialini ? dialini : mp->wake_str;
- if (ws && (int)strlen(ws) > 0) {
- debug(F111,"_dodial default, wake string", ws, wr);
- ttslow(ws, wr);
- } else debug(F100,"_dodial no wake_str","",0);
- if (mp->wake_prompt && (int)strlen(mp->wake_prompt) > 0) {
- debug(F110,"_dodial default, waiting for wake_prompt",
- mp->wake_prompt,0);
- alarm(10);
- waitfor(mp->wake_prompt);
- alarm(0);
- } else debug(F100,"_dodial no wake_prompt","",0);
- }
-
-/* Handle error correction, data compression, and flow control... */
-
- xdialec:
-
- if (dialsta != DIA_PART) {
- alarm(0); /* Turn off alarm */
- debug(F100,"_dodial got wake prompt","",0);
- msleep(500); /* Allow settling time */
-
- /* Enable/disable error-correction */
-
- x = 0;
- if (dialec) { /* DIAL ERROR-CORRECTION is ON */
- if (dialecon) { /* SET DIAL STRING ERROR-CORRECTION */
- if (*dialecon) {
- x = 1;
- ttslow(dialecon, wr);
- }
- } else if ((mdmcapas & CKD_EC) && *(mp->ec_on_str)) {
- x = 1;
- ttslow(mp->ec_on_str, wr);
- }
-#ifdef COMMENT
- else printf(
- "WARNING - I don't know how to turn on EC for this modem\n"
- );
-#endif /* COMMENT */
- } else {
- if (dialecoff) { /* DIAL ERROR-CORRECTION OFF */
- if (*dialecoff) {
- x = 1;
- ttslow(dialecoff, wr);
- }
- } else if ((mdmcapas & CKD_EC) && *(mp->ec_off_str)) {
- x = 1;
- ttslow(mp->ec_off_str, wr);
- }
-#ifdef COMMENT
- else printf(
- "WARNING - I don't know how to turn off EC for this modem\n"
- );
-#endif /* COMMENT */
- }
- /* debug(F101,"ckudia xx_ok","",xx_ok); */
- if (x && xx_ok) { /* Look for OK response */
- debug(F100,"ckudia calling xx_ok for EC","",0);
- x = (*xx_ok)(5,1);
- debug(F101,"ckudia xx_ok","",x);
- if (x < 0) {
- printf("WARNING - Trouble enabling error-correction.\n");
- printf(
-" Likely cause: Your modem is an RPI model, which does not have built-in\n");
- printf(" error correction and data compression.");
- }
- }
-
- /* Enable/disable data compression */
-
- if (x > 0) x = 0;
- if (dialdc) {
- if (x < 0 || !dialec) {
- printf(
-"WARNING - You can't have compression without error correction.\n");
- } else if (dialdcon) { /* SET DIAL STRING ... */
- if (*dialdcon) {
- x = 1;
- ttslow(dialdcon, wr);
- }
- } else if ((mdmcapas & CKD_DC) && *(mp->dc_on_str)) {
- x = 1;
- ttslow(mp->dc_on_str, wr);
- }
-#ifdef COMMENT
- else printf(
- "WARNING - I don't know how to turn on DC for this modem\n"
- );
-#endif /* COMMENT */
- } else {
- if (dialdcoff) {
- if (*dialdcoff) {
- x = 1;
- ttslow(dialdcoff, wr);
- }
- } else if ((mdmcapas & CKD_DC) && *(mp->dc_off_str)) {
- x = 1;
- ttslow(mp->dc_off_str, wr);
- }
-#ifdef COMMENT
- else printf(
-"WARNING - I don't know how to turn off compression for this modem\n"
- );
-#endif /* COMMENT */
- }
- if (x && xx_ok) { /* Look for OK response */
- x = (*xx_ok)(5,1);
- if (x < 0) printf("WARNING - Trouble enabling compression\n");
- }
- }
-
-#ifndef NOXFER
-#ifndef MINIDIAL
- if (mdmcapas & CKD_KS && dialsta != DIA_PART) { /* Kermit spoof */
- int r; /* Register */
- char tbcmdbuf[64]; /* Command buffer */
- switch (mymdmtyp) {
-
- case n_MICROCOM: /* Microcoms in SX mode */
- if (dialksp)
- sprintf(tbcmdbuf,"APM1;KMC%d\015",stchr); /* safe */
- else
- sprintf(tbcmdbuf,"APM0\015"); /* safe */
- ttslow(tbcmdbuf, MICROCOM.wake_rate);
- alarm(3);
- waitfor(mp->wake_prompt);
- alarm(0);
- break;
-
- case n_TELEBIT: /* Old and new Telebits */
- case n_TBNEW:
- if (!dialksp) {
- sprintf(tbcmdbuf,"ATS111=0\015"); /* safe */
- } else {
- switch (parity) { /* S111 value depends on parity */
- case 'e': r = 12; break;
- case 'm': r = 13; break;
- case 'o': r = 11; break;
- case 's': r = 14; break;
- case 0:
- default: r = 10; break;
- }
- sprintf(tbcmdbuf,"ATS111=%d S112=%d\015",r,stchr); /* safe */
- }
- ttslow(tbcmdbuf, wr);
-
-/* Not all Telebit models have the Kermit spoof, so ignore response. */
-
- if (xx_ok) { /* Get modem's response */
- x = (*xx_ok)(5,1);
- }
- }
- }
-#endif /* MINIDIAL */
-#endif /* NOXFER */
-
- /* Speaker */
-
- if (mymdmtyp != n_GENERIC &&
- (mdmcapas & CKD_AT) && (dialsta != DIA_PART) &&
- !dialspon && !dialspoff &&
- !dialvol1 && !dialvol2 &&!dialvol3) {
- /* AT command set and commands have not been customized */
- /* so combine speaker and volume commands. */
- if (mdmspk)
- sprintf(lbuf,"ATM1L%d%c",mdmvol,13); /* safe */
- else
- sprintf(lbuf,"ATM0%c",13); /* safe */
- ttslow(lbuf,wr); /* Send command */
- getok(5,1); /* Get but ignore response */
- } else if (dialsta != DIA_PART) { /* Customized or not AT commands */
- x = 0; /* Do it the hard way */
- if (mdmspk) {
- if (dialspon) {
- if (*dialspon) {
- x = 1;
- ttslow(dialspon,wr);
- }
- } else {
- if (mp->sp_on_str[0]) {
- x = 1;
- ttslow(mp->sp_on_str,wr);
- }
- }
- } else {
- /* s = dialspoff ? dialspoff : mp->sp_off_str; */
- if (dialspoff) {
- if (*dialspoff) {
- x = 1;
- ttslow(dialspoff,wr);
- }
- } else {
- if (mp->sp_off_str[0]) {
- x = 1;
- ttslow(mp->sp_off_str,wr);
- }
- }
- }
- if (x) {
- if (xx_ok) /* Get response */
- x = (*xx_ok)(5,1);
- if (x && mdmspk) { /* Good response and speaker on? */
- switch (mdmvol) { /* Yes, send volume command. */
- case 0:
- case 1:
- s = dialvol1 ? dialvol1 : mp->vol1_str; break;
- case 2:
- s = dialvol2 ? dialvol2 : mp->vol2_str; break;
- case 3:
- s = dialvol3 ? dialvol3 : mp->vol3_str; break;
- default:
- s = NULL;
- }
- if (s) if (*s) { /* Send volume command. */
- ttslow(s, wr);
- if (xx_ok) /* Get response but ignore it */
- (*xx_ok)(5,1);
- }
- }
- }
- }
-
-#ifndef CK_ATDT
- /* Dialing Method */
-
- if (dialmth && dialsta != DIA_PART) { /* If dialing method specified... */
- char *s = ""; /* Do it here... */
-
- if (dialmth == XYDM_T && dialtone) /* Tone */
- s = dialtone;
- else if (dialmth == XYDM_P && dialpulse) /* Pulse */
- s = dialpulse;
- if (s) if (*s) {
- ttslow(s, wr);
- if (xx_ok) /* Get modem's response */
- (*xx_ok)(5,1); /* (but ignore it...) */
- }
- }
-#endif /* CK_ATDT */
-
- if (dialidt) { /* Ignore dialtone? */
- char *s = "";
- s = dialx3 ? dialx3 : mp->ignoredt;
- if (s) if (*s) {
- ttslow(s, wr);
- if (xx_ok) /* Get modem's response */
- (*xx_ok)(5,1); /* (but ignore it...) */
- }
- }
- {
- char *s = ""; /* Last-minute init string? */
- s = dialini2 ? dialini2 : mp->ini2;
- if (s) if (*s) {
- ttslow(s, wr);
- if (xx_ok) /* Get modem's response */
- (*xx_ok)(5,1); /* (but ignore it...) */
- }
- }
- if (func_code == 1) { /* ANSWER (not DIAL) */
- char *s;
- s = dialaaon ? dialaaon : mp->aa_on_str;
- if (!s) s = "";
- if (*s) {
- /* Here we would handle caller ID */
- ttslow(s, (dialpace > -1) ? wr : mp->dial_rate);
- if (xx_ok) /* Get modem's response */
- (*xx_ok)(5,1); /* (but ignore it...) */
- } else {
- printf(
-"WARNING - I don't know how to enable autoanswer for this modem.\n"
- );
- } /* And skip all the phone-number & dialing stuff... */
- alarm(waitct); /* This much time allowed. */
- debug(F101,"_dodial ANSWER waitct","",waitct);
-
- } else { /* DIAL (not ANSWER) */
-
- if (dialsta != DIA_PART) { /* Last dial was not partial */
-
- char *s = "";
-#ifdef COMMENT
- s = dialaaoff ? dialaaoff : mp->aa_off_str;
-#endif /* COMMENT */
- if (s) if (*s) {
- ttslow(s, (dialpace > -1) ? wr : mp->dial_rate);
- if (xx_ok) /* Get modem's response */
- (*xx_ok)(5,1); /* (but ignore it...) */
- }
-
- /* Put modem into dialing mode, if the modem requires it. */
-
- if (mp->dmode_str && *(mp->dmode_str)) {
- ttslow(mp->dmode_str, (dialpace > -1) ? wr : mp->dial_rate);
- savalrm = signal(SIGALRM,dialtime);
- alarm(10);
- /* Wait for prompt, if any expected */
- if (mp->dmode_prompt && *(mp->dmode_prompt)) {
- waitfor(mp->dmode_prompt);
- msleep(300);
- }
- alarm(0); /* Turn off alarm on dialing prompts */
- signal(SIGALRM,savalrm); /* Restore alarm */
- }
- }
- /* AT-Command-Set non-Generic modem */
- if (mdmcapas & CKD_AT && mymdmtyp != n_GENERIC &&
- dialsta != DIA_PART) {
- if (mdmwait > 255) /* If larger than maximum, */
- mdmwait = 255; /* make it maximum. */
- if (dialesc > 0 && /* Modem escape character is set */
- dialmhu > 0) { /* Hangup method is modem command */
- int x = dialesc;
- if (dialesc < 0 || dialesc > 127)
- x = 128;
- sprintf(lbuf,
- "ATS2=%dS7=%d\015",
- dialesc ? x : mp->esc_char, mdmwait); /* safe */
- } else
- sprintf(lbuf,"ATS7=%d%c",mdmwait,13); /* safe */
- ttslow(lbuf,wr); /* Set it. */
- mdmstat = getok(5,1); /* Get response from modem */
- /* If it gets an error, go ahead anyway */
- debug(F101,"_dodial S7 mdmstat","",mdmstat);
- }
- ttflui(); /* Clear out stuff from modem setup */
- inited = 1; /* Remember modem is initialized */
-
- REDIAL:
- if ((int)strlen(dcmd) + (int)strlen(xnum) > LBUFL)
- ckstrncpy(lbuf,"NUMBER TOO LONG!",LBUFL);
- else
- sprintf(lbuf, dcmd, xnum); /* safe (prechecked) */
- debug(F110,"dialing",lbuf,0);
- /* Send the dialing string */
- ttslow(lbuf,dialpace > -1 ? wr : mp->dial_rate);
-
- fail_code = F_MODEM; /* New default failure code changes */
- dial_what = DW_DIAL; /* and our state, too. */
- if (dialdpy) { /* If showing progress */
- p = ck_time(); /* get current time; */
- if (*p) printf(" Dialing: %s...\n",p);
-#ifdef VMS
- printf(" \n");
- fflush(stdout);
-#endif /* VMS */
- }
- alarm(waitct); /* This much time allowed. */
- debug(F101,"_dodial waitct","",waitct);
-
-#ifndef MINIDIAL
-#ifdef OLDMODEMS
- switch (mymdmtyp) {
- case n_RACAL: /* Acknowledge dialing string */
- sleep(3);
- ttflui();
- ttoc('\015');
- break;
- case n_VENTEL:
- waitfor("\012\012"); /* Ignore the first two strings */
- break;
- default:
- break;
- }
-#endif /* OLDMODEMS */
-#endif /* MINIDIAL */
- }
-
-/* Check for connection */
-
- mdmstat = 0; /* No status yet */
- lbuf[0] = NUL; /* Default reason for failure */
- debug(F101,"dial awaiting response, mymdmtyp","",mymdmtyp);
-
-#ifndef NOSPL
- modemmsg[0] = NUL;
-#endif /* NOSPL */
- while (mdmstat == 0) { /* Till we get a result or time out */
-
- if ((mdmcapas & CKD_AT) && nonverbal) { /* AT command set */
- gethrn(); /* In digit result mode */
- if (partial && dialsta == DIA_ERR) {
- /*
- If we get an error here, the phone is still
- off hook so we have to hang it up.
- */
- dialhup();
- dialsta = DIA_ERR; /* (because dialhup() changes it) */
- }
- continue;
-
- } else if (mymdmtyp == n_UNKNOWN) { /* Unknown modem type */
- int x, y = waitct;
- mdmstat = D_FAILED; /* Assume failure. */
- while (y-- > -1) {
- x = ttchk();
- if (x > 0) {
- if (x > LBUFL) x = LBUFL;
- x = ttxin(x,(CHAR *)lbuf);
- if ((x > 0) && dialdpy) conol(lbuf);
- } else if (network
-#ifdef TN_COMPORT
- && !istncomport()
-#endif /* TN_COMPORT */
- && x < 0) { /* Connection dropped */
- inited = 0;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- dialsta = DIA_IO; /* Call it an I/O error */
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
- SIGRETURN;
- }
- x = ttgmdm(); /* Try to read modem signals */
- if (x < 0) break; /* Can't, fail. */
- if (x & BM_DCD) { /* Got signals OK. Carrier present? */
- mdmstat = CONNECTED; /* Yes, done. */
- break;
- } /* No, keep waiting. */
- sleep(1);
- }
- continue;
- }
-
- for (n = -1; n < LBUFL-1; ) { /* Accumulate modem response */
- int xx;
- c2 = (char) (xx = ddinc(0)); /* Read a character, blocking */
- if (xx < 1) /* Ignore NULs and errors */
- continue; /* (Timeout will handle errors) */
- else /* Real character, keep it */
- lbuf[++n] = (char) (c2 & 0177);
- dialoc(lbuf[n]); /* Maybe echo it */
- if (mdmcapas & CKD_V25) { /* V.25bis dialing... */
-/*
- This assumes that V.25bis indications are all at least 3 characters long
- and are terminated by either CRLF or LFCR.
-*/
- if (mymdmtyp == n_CCITT) {
- if (n < 3) continue;
- if ((lbuf[n] == CR) && (lbuf[n-1] == LF)) break;
- if ((lbuf[n] == LF) && (lbuf[n-1] == CR)) break;
- }
-#ifndef MINIDIAL
- else if (mymdmtyp == n_DIGITEL) {
- if (((lbuf[n] == CR) && (lbuf[n-1] == LF)) ||
- ((lbuf[n] == LF) && (lbuf[n-1] == CR)))
- break;
- else
- continue;
- }
-#endif /* MINIDIAL */
- } else { /* All others, break on CR or LF */
- if ( lbuf[n] == CR || lbuf[n] == LF ) break;
- }
- }
- lbuf[++n] = '\0'; /* Terminate response from modem */
- debug(F111,"_dodial modem response",lbuf,n);
-#ifndef NOSPL
- ckstrncpy(modemmsg,lbuf,LBUFL); /* Call result message */
- lbuf[79] = NUL;
- {
- int x; /* Strip junk from end */
- x = (int)strlen(modemmsg) - 1;
- while (x > -1) {
- if (modemmsg[x] < (char) 33)
- modemmsg[x] = NUL;
- else
- break;
- x--;
- }
- }
-#endif /* NOSPL */
- if (mdmcapas & CKD_AT) { /* Hayes AT command set */
- gethrw(); /* in word result mode */
- if (partial && dialsta == DIA_ERR) {
- dialhup();
- dialsta = DIA_ERR; /* (because dialhup() changes it) */
- }
- continue;
- } else if (mdmcapas & CKD_V25) { /* CCITT command set */
- if (didweget(lbuf,"VAL")) { /* Dial command confirmation */
-#ifndef MINIDIAL
- if (mymdmtyp == n_CCITT)
-#endif /* MINIDIAL */
- continue; /* Go back and read more */
-#ifndef MINIDIAL
-/* Digitel doesn't give an explicit connect confirmation message */
- else {
- int n;
- for (n = -1; n < LBUFL-1; ) {
- lbuf[++n] = c2 = (char) (ddinc(0) & 0177);
- dialoc(lbuf[n]);
- if (((lbuf[n] == CR) && (lbuf[n-1] == LF)) ||
- ((lbuf[n] == LF) && (lbuf[n-1] == CR)))
- break;
- }
- mdmstat = CONNECTED; /* Assume we're connected */
- if (dialdpy && carrier != CAR_OFF) {
-#ifdef TN_COMPORT
- if (istncomport()) {
- int i;
- for (i = 0; i < 5; i++) {
- debug(F100,"TN Com Port DCD wait...","",0);
- if ((n = ttgmdm()) >= 0) {
- if ((n & BM_DCD))
- break;
- msleep(500);
- tnc_wait(
- (CHAR *)"_dodial waiting for DCD",1);
- }
- }
- } else
-#endif /* TN_COMPORT */
- sleep(1); /* Wait a second */
- n = ttgmdm(); /* Try to read modem signals */
- if ((n > -1) && ((n & BM_DCD) == 0))
- printf("WARNING - no carrier\n");
- }
- }
-#endif /* MINIDIAL */
-
- /* Standard V.25bis stuff */
-
- } else if (didweget(lbuf,"CNX")) { /* Connected */
- mdmstat = CONNECTED;
- } else if (didweget(lbuf, "INV")) {
- mdmstat = D_FAILED; /* Command error */
- dialsta = DIA_ERR;
- ckstrncpy(lbuf,"INV",LBUFL);
-
- } else if (didweget(lbuf,"CFI")) { /* Call Failure */
-
- if (didweget(lbuf,"AB")) { /* Interpret reason code */
- ckstrncpy(lbuf,"AB: Timed out",LBUFL);
- dialsta = DIA_TIMO;
- } else if (didweget(lbuf,"CB")) {
- ckstrncpy(lbuf,"CB: Local DCE Busy",LBUFL);
- dialsta = DIA_NRDY;
- } else if (didweget(lbuf,"ET")) {
- ckstrncpy(lbuf,"ET: Busy",LBUFL);
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf, "NS")) {
- ckstrncpy(lbuf,"NS: Number not stored",LBUFL);
- dialsta = DIA_ERR;
- } else if (didweget(lbuf,"NT")) {
- ckstrncpy(lbuf,"NT: No answer",LBUFL);
- dialsta = DIA_NOAN;
- } else if (didweget(lbuf,"RT")) {
- ckstrncpy(lbuf,"RT: Ring tone",LBUFL);
- dialsta = DIA_RING;
- } else if (didweget(lbuf,"PV")) {
- ckstrncpy(lbuf,"PV: Parameter value error",LBUFL);
- dialsta = DIA_ERR;
- } else if (didweget(lbuf,"PS")) {
- ckstrncpy(lbuf,"PS: Parameter syntax error",LBUFL);
- dialsta = DIA_ERR;
- } else if (didweget(lbuf,"MS")) {
- ckstrncpy(lbuf,"MS: Message syntax error",LBUFL);
- dialsta = DIA_ERR;
- } else if (didweget(lbuf,"CU")) {
- ckstrncpy(lbuf,"CU: Command unknown",LBUFL);
- dialsta = DIA_ERR;
- } else if (didweget(lbuf,"FC")) {
- ckstrncpy(lbuf,"FC: Forbidden call",LBUFL);
- dialsta = DIA_NOAC;
- }
- mdmstat = D_FAILED;
- } else if (didweget(lbuf,"INC")) { /* Incoming Call */
- ckstrncpy(lbuf,"INC: Incoming call",LBUFL);
- dialsta = DIA_RING;
- mdmstat = D_FAILED;
- } else if (didweget(lbuf,"DLC")) { /* Delayed Call */
- ckstrncpy(lbuf,"DLC: Delayed call",LBUFL);
- dialsta = DIA_NOAN;
- mdmstat = D_FAILED;
- } else /* Response was probably an echo. */
-#ifndef MINIDIAL
- if (mymdmtyp == n_CCITT)
-#endif /* MINIDIAL */
- continue;
-#ifndef MINIDIAL
- else /* Digitel: If no error, connect. */
- mdmstat = CONNECTED;
-#endif /* MINIDIAL */
- break;
-
- } else if (n) { /* Non-Hayes-compatibles... */
- switch (mymdmtyp) {
-#ifndef MINIDIAL
- case n_ATTMODEM:
- /* Careful - "Connected" / "Not Connected" */
- if (didweget(lbuf,"Busy")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf,"Not connected") ||
- didweget(lbuf,"Not Connected")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOCA;
- } else if (didweget(lbuf,"No dial tone") ||
- didweget(lbuf,"No Dial Tone")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NODT;
- } else if (didweget(lbuf,"No answer") ||
- didweget(lbuf,"No Answer")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOAN;
- } else if (didweget(lbuf,"Answered") ||
- didweget(lbuf,"Connected")) {
- mdmstat = CONNECTED;
- dialsta = DIA_OK;
- }
- break;
-
- case n_ATTISN:
- if (didweget(lbuf,"ANSWERED")) {
- mdmstat = CONNECTED;
- dialsta = DIA_OK;
- } else if (didweget(lbuf,"BUSY")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf,"DISCONNECT")) {
- mdmstat = D_FAILED;
- dialsta = DIA_DISC;
- } else if (didweget(lbuf,"NO ANSWER")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOAN;
- } else if (didweget(lbuf,"WRONG ADDRESS")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOAC;
- }
- break;
-
- case n_ATTDTDM:
- if (didweget(lbuf,"ANSWERED")) {
- mdmstat = CONNECTED;
- } else if (didweget(lbuf,"BUSY")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf,"CHECK OPTIONS")) {
- mdmstat = D_FAILED;
- dialsta = DIA_ERR;
- } else if (didweget(lbuf,"DISCONNECTED")) {
- mdmstat = D_FAILED;
- dialsta = DIA_DISC;
- } else if (didweget(lbuf,"DENIED")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOAC;
- }
-#ifdef DEBUG
-#ifdef ATT6300
- /* Horrible hack lost in history. */
- else if (deblog && didweget(lbuf,"~~"))
- mdmstat = CONNECTED;
-#endif /* ATT6300 */
-#endif /* DEBUG */
- break;
-
-#ifdef OLDMODEMS
- case n_CERMETEK:
- if (didweget(lbuf,"\016A")) {
- mdmstat = CONNECTED;
- ttslow("\016U 1\015",200); /* Make transparent*/
- }
- break;
-
- case n_DF03:
- /* Because response lacks CR or NL . . . */
- c = (char) (ddinc(0) & 0177);
- dialoc(c);
- debug(F000,"dial df03 got","",c);
- if ( c == 'A' ) mdmstat = CONNECTED;
- if ( c == 'B' ) mdmstat = D_FAILED;
- break;
-
- case n_DF100: /* DF100 has short response codes */
- if (strcmp(lbuf,"A") == 0) {
- mdmstat = CONNECTED; /* Attached */
- dialsta = DIA_OK;
- } else if (strcmp(lbuf,"N") == 0) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOAN; /* No answer or no dialtone */
- } else if (strcmp(lbuf,"E") == 0 || /* Error */
- strcmp(lbuf,"R") == 0) { /* "Ready" (?) */
- mdmstat = D_FAILED;
- dialsta = DIA_ERR; /* Command error */
- }
- /* otherwise fall thru... */
-
- case n_DF200:
- if (didweget(lbuf,"Attached")) {
- mdmstat = CONNECTED;
- dialsta = DIA_OK;
- /*
- * The DF100 will respond with "Attached" even if DTR
- * and/or carrier are not present. Another reason to
- * (also) wait for carrier?
- */
- } else if (didweget(lbuf,"Busy")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf,"Disconnected")) {
- mdmstat = D_FAILED;
- dialsta = DIA_DISC;
- } else if (didweget(lbuf,"Error")) {
- mdmstat = D_FAILED;
- dialsta = DIA_ERR;
- } else if (didweget(lbuf,"No answer")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOAN;
- } else if (didweget(lbuf,"No dial tone")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NODT;
- } else if (didweget(lbuf,"Speed:)")) {
- mdmstat = D_FAILED;
- dialsta = DIA_ERR;
- }
- /*
- * It appears that the "Speed:..." response comes after an
- * "Attached" response, so this is never seen. HOWEVER,
- * it would be very handy to detect this and temporarily
- * reset the speed, since it's a nuisance otherwise.
- * If we wait for some more input from the modem, how do
- * we know if it's from the remote host or the modem?
- * Carrier reportedly doesn't get set until after the
- * "Speed:..." response (if any) is sent. Another reason
- * to (also) wait for carrier.
- */
- break;
-
- case n_GDC:
- if (didweget(lbuf,"ON LINE"))
- mdmstat = CONNECTED;
- else if (didweget(lbuf,"NO CONNECT"))
- mdmstat = D_FAILED;
- break;
-
- case n_PENRIL:
- if (didweget(lbuf,"OK")) {
- mdmstat = CONNECTED;
- } else if (didweget(lbuf,"BUSY")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf,"NO RING")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOCA;
- }
- break;
-
- case n_RACAL:
- if (didweget(lbuf,"ON LINE"))
- mdmstat = CONNECTED;
- else if (didweget(lbuf,"FAILED CALL"))
- mdmstat = D_FAILED;
- break;
-#endif /* OLDMODEMS */
-
- case n_ROLM:
- if (didweget(lbuf,"CALLING"))
- mdmstat = 0;
- else if (didweget(lbuf,"COMPLETE"))
- mdmstat = CONNECTED;
- else if (didweget(lbuf,"FAILED") ||
- didweget(lbuf,"ABANDONDED")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOCA;
- } else if (didweget(lbuf,"NOT AVAILABLE") ||
- didweget(lbuf,"LACKS PERMISSION") ||
- didweget(lbuf,"NOT A DATALINE") ||
- didweget(lbuf,"INVALID DATA LINE NUMBER") ||
- didweget(lbuf,"INVALID GROUP NAME")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOAC;
- } else if (didweget(lbuf,"BUSY")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf,"DOES NOT ANSWER")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOAN;
- }
- break;
-
-#ifdef OLDMODEMS
- case n_VENTEL:
- if (didweget(lbuf,"ONLINE!") ||
- didweget(lbuf,"Online!")) {
- mdmstat = CONNECTED;
- } else if (didweget(lbuf,"BUSY") ||
- didweget(lbuf,"Busy")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf,"DEAD PHONE")) {
- mdmstat = D_FAILED;
- dialsta = DIA_DISC;
- }
- break;
-
- case n_CONCORD:
- if (didweget(lbuf,"INITIATING"))
- mdmstat = CONNECTED;
- else if (didweget(lbuf,"BUSY")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf,"CALL FAILED")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOCA;
- }
- break;
-#endif /* OLDMODEMS */
-
- case n_MICROCOM:
- /* "RINGBACK" means phone line ringing, continue */
- if (didweget(lbuf,"NO CONNECT")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOCA;
- } else if (didweget(lbuf,"BUSY")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf,"NO DIALTONE")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NODT;
- } else if (didweget(lbuf,"COMMAND ERROR")) {
- mdmstat = D_FAILED;
- dialsta = DIA_ERR;
- } else if (didweget(lbuf,"IN USE")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOAC;
- } else if (didweget(lbuf,"CONNECT")) {
- mdmstat = CONNECTED;
- /* trailing speed ignored */
- }
- break;
-
-#endif /* MINIDIAL */
- default:
- printf(
- "PROGRAM ERROR - No response handler for modem type %d\n",
- mymdmtyp);
- mdmstat = D_FAILED;
- dialsta = DIA_ERR;
- }
- }
- } /* while (mdmstat == 0) */
-
- debug(F101,"_dodial alarm off","",x);
- alarm(0);
- if (mdmstat == D_FAILED) { /* Failure detected by modem */
- dialfail(F_MODEM);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
- } else if (mdmstat == D_PARTIAL ) { /* Partial dial command OK */
- msleep(500);
- debug(F100,"dial partial","",0);
- } else { /* Call was completed */
- int x;
- msleep(700); /* In case modem signals blink */
- debug(F100,"dial succeeded","",0);
- if (
-#ifndef MINIDIAL
- mymdmtyp != n_ROLM /* Rolm has weird modem signaling */
-#else
- 1
-#endif /* MINIDIAL */
- ) {
- alarm(3); /* In case ttpkt() gets stuck... */
- ttpkt(speed,FLO_DIAX,parity); /* Cancel dialing state ioctl */
- alarm(0);
- }
-/*
- In case CD went off in the interval between call completion and return
- from ttpkt()...
-*/
- if (carrier != CAR_OFF) {
- if ((x = ttgmdm()) >= 0) {
-#ifdef TN_COMPORT
- if (istncomport() && !(x & BM_DCD)) {
- int i;
- for (i = 0; i < 5; i++) {
- msleep(500);
- tnc_wait((CHAR *)"_dodial waiting for DCD",1);
- if ((x = ttgmdm()) >= 0) {
- if ((x & BM_DCD))
- break;
- }
- }
- }
-#endif /* TN_COMPORT */
- if (!(x & BM_DCD))
- printf("WARNING: Carrier seems to have dropped...\n");
- }
- }
- }
- dreset(); /* Reset alarms and signals. */
- if (!quiet && !backgrd) {
- if (dialdpy && (p = ck_time())) { /* If DIAL DISPLAY ON, */
- printf(" %sall complete: %s.\n", /* include timestamp. */
- (mdmstat == D_PARTIAL) ?
- "Partial c" :
- "C",
- p );
- } else if (modemmsg[0]) {
- printf (" %sall complete: \"%s\".\n",
- (mdmstat == D_PARTIAL) ? "Partial c" : "C",
- (char *)modemmsg
- );
- } else {
- printf (" %sall complete.\n",
- (mdmstat == D_PARTIAL) ?
- "Partial c" :
- "C"
- );
- }
- }
-#ifdef CKLOGDIAL
- dologdial(telnbr);
-#endif /* CKLOGDIAL */
-
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
- dialsta = (mdmstat == D_PARTIAL) ? DIA_PART : DIA_OK;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
-}
-
-static SIGTYP
-#ifdef CK_ANSIC
-faildial(void * threadinfo)
-#else /* Not CK_ANSIC */
-faildial(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* faildial */ {
- debug(F100,"longjmp returns to dial routine","",0);
- dialfail(fail_code);
- SIGRETURN;
-}
-
-/*
- nbr = number to dial (string)
- x1 = Retry counter
- x2 = Number counter
- fc = Function code:
- 0 == DIAL
- 1 == ANSWER
- 2 == INIT/CONFIG
- 3 == PARTIAL DIAL
-*/
-
-int
-#ifdef OLD_DIAL
-ckdial(nbr) char *nbr;
-#else
-ckdial(nbr, x1, x2, fc, redial) char *nbr; int x1, x2, fc, redial;
-#endif /* OLD_DIAL */
-/* ckdial */ {
-#define ERMSGL 50
- char errmsg[ERMSGL], *erp; /* For error messages */
- int n = F_TIME;
- char *s;
- long spdmax;
-#ifdef OS2
- extern int term_io;
- int term_io_sav = term_io;
-#endif /* OS2 */
-
- char *mmsg = "Sorry, DIAL memory buffer can't be allocated\n";
- /*
- A DIAL command implies a SET MODEM TYPE command and therefore enables
- hanging up by modem commands rather than dropping DTR.
- */
- mdmset = 1; /* See mdmhup() */
-
- partial = 0;
- if (fc == 3) { /* Partial dial requested */
- partial = 1; /* Set flag */
- fc = 0; /* Treat like regular dialing */
- }
- func_code = fc; /* Make global to this module */
- telnbr = nbr;
- xredial = redial;
- debug(F111,"ckdial entry partial",ckitoa(fc),partial);
- debug(F111,"ckdial entry number",nbr,redial);
-
- if (fc == 1) { /* ANSWER command? */
- /* Reset caller ID strings */
- if (callid_date) makestr(&callid_date,NULL);
- if (callid_time) makestr(&callid_time,NULL);
- if (callid_name) makestr(&callid_name,NULL);
- if (callid_nmbr) makestr(&callid_nmbr,NULL);
- if (callid_mesg) makestr(&callid_mesg,NULL);
- }
-
-#ifdef CK_TAPI_X
- if (tttapi && tapipass) {
- if (modemp[n_TAPI] = cktapiGetModemInf()) {
- mymdmtyp = n_TAPI;
- } else {
- mymdmtyp = mdmtyp;
- modemp[n_TAPI] = &GENERIC;
- }
- } else
-#endif /* CK_TAPI */
- mymdmtyp = mdmtyp;
- if (mymdmtyp < 0) { /* Whoa, network dialing... */
- if (mdmsav > -1)
- mymdmtyp = mdmsav;
- }
- if (mymdmtyp < 0) {
- printf("Invalid modem type %d - internal error.\n",mymdmtyp);
- dialsta = DIA_NOMO;
- return(0);
- }
- dial_what = DW_NOTHING; /* Doing nothing at first. */
- nonverbal = 0;
-
-/* These are ONLY for the purpose of interpreting numeric result codes. */
-
- is_motorola =
-#ifdef MINIDIAL
- 0
-#else
- mymdmtyp == n_SUPRA || mymdmtyp == n_SUPRASON;
-#endif /* MINIDIAL */
- ;
-
- is_motorola =
-#ifdef MINIDIAL
- 0
-#else
- mymdmtyp == n_MOTOROLA || mymdmtyp == n_MONTANA;
-#endif /* MINIDIAL */
- ;
-
- is_rockwell =
-#ifdef MINIDIAL
- 0
-#else
- mymdmtyp == n_RWV32 || mymdmtyp == n_RWV32B ||
- mymdmtyp == n_RWV34 || mymdmtyp == n_RWV90 ||
- mymdmtyp == n_BOCA || mymdmtyp == n_TELEPATH ||
- mymdmtyp == n_CARDINAL || mymdmtyp == n_BESTDATA ||
- mymdmtyp == n_CONEXANT || mymdmtyp == n_PCTEL
-#endif /* MINIDIAL */
- ;
-
- is_hayeshispd =
-#ifdef MINIDIAL
- 0
-#else
- mymdmtyp == n_H_ULTRA || mymdmtyp == n_H_ACCURA || n_PPI
-#endif /* MINIDIAL */
- ;
-
- is_supra =
-#ifdef MINIDIAL
- 0
-#else
- mymdmtyp == n_SUPRA || mymdmtyp == n_SUPRAX || n_SUPRASON
-#endif /* MINIDIAL */
- ;
-
- mp = modemp[mymdmtyp]; /* Set pointer to modem info */
- if (!mp) {
- printf("Sorry, handler for this modem type not yet filled in.\n");
- dialsta = DIA_NOMO;
- return 0;
- }
- debug(F110,"dial number",telnbr,0);
-#ifdef COMMENT
- debug(F110,"dial prefix",(dialnpr ? dialnpr : ""), 0);
-#endif /* COMMENT */
-
-#ifdef DYNAMIC
- *lbuf = NUL;
- debug(F101,"DIAL lbuf malloc ok","",LBUFL+1);
-
- if (!rbuf) { /* This one might already have been allocated by getok() */
- if (!(rbuf = malloc(RBUFL+1))) { /* Allocate input line buffer */
- printf("%s", mmsg);
- dialsta = DIA_IE;
- return 0;
- } else
- debug(F101,"DIAL rbuf malloc ok","",RBUFL+1);
- }
- if (!(fbuf = malloc(FULLNUML+1))) { /* Allocate input line buffer */
- printf("%s", mmsg);
- dialsta = DIA_IE;
- if (rbuf) free(rbuf); rbuf = NULL;
- return 0;
- }
- debug(F101,"DIAL fbuf malloc ok","",FULLNUML+1);
-#endif /* DYNAMIC */
-
- /* NOTE: mdmtyp, not mymdmtyp */
-
- if (ttopen(ttname,&local,mdmtyp,0) < 0) { /* Open, no carrier wait */
- erp = errmsg;
- if ((int)strlen(ttname) < (ERMSGL - 18)) /* safe, checked */
- sprintf(erp,"Sorry, can't open %s",ttname);
- else
- sprintf(erp,"Sorry, can't open device");
- perror(errmsg);
- dialsta = DIA_OPEN;
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
- return 0;
- }
-
-#ifdef CK_TAPI
- if (!tttapi) {
-#endif /* CK_TAPI */
-
-/* Condition console terminal and communication line */
-
- /* Place line into "clocal" dialing state, */
- /* important mainly for System V UNIX. */
-
- if (ttpkt(speed,FLO_DIAL,parity) < 0) {
- ttclos(0); /* If ttpkt fails do all this... */
- if (ttopen(ttname,&local,mymdmtyp,0) < 0) {
- erp = errmsg;
- if ((int)strlen(ttname) < (ERMSGL - 18)) /* safe, checked */
- sprintf(erp,"Sorry, can't reopen %s",ttname);
- else
- sprintf(erp,"Sorry, can't reopen device");
- perror(errmsg);
- dialsta = DIA_OPEN;
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
- return 0;
- } /* And try again. */
- if ((ttpkt(speed,FLO_DIAL,parity) < 0)
-#ifdef UNIX
- && (strcmp(ttname,"/dev/null"))
-#else
-#ifdef OSK
- && (strcmp(ttname,"/nil"))
-#endif /* OSK */
-#endif /* UNIX */
-#ifdef CK_TAPI
- && !tttapi
-#endif /* CK_TAPI */
- ) {
- printf("Sorry, Can't condition communication line\n");
- printf("Try 'set line %s' again\n",ttname);
- dialsta = DIA_OPEN;
-#ifdef DYNAMIC
- if (rbuf) free(rbuf); rbuf = NULL;
- if (fbuf) free(fbuf); fbuf = NULL;
-#endif /* DYNAMIC */
- return 0;
- }
- }
-#ifdef CK_TAPI
- }
-#endif /* CK_TAPI */
-
- /* Modem's escape sequence... */
-
- if (dialesc < 0 || dialesc > 127)
- c = NUL;
- else
- c = (char) (dialesc ? dialesc : mp->esc_char);
- mdmcapas = dialcapas ? dialcapas : mp->capas;
-
- xx_ok = mp->ok_fn; /* Pointer to response reader */
-
- if (mdmcapas & CKD_AT) { /* Hayes compatible */
- escbuf[0] = c;
- escbuf[1] = c;
- escbuf[2] = c;
- escbuf[3] = NUL;
- /* In case this modem type is user-defined */
- if (!xx_ok) xx_ok = getok;
- } else { /* Other */
- escbuf[0] = c;
- escbuf[1] = NUL;
- /* In case user-defined */
- if (mdmcapas & CKD_V25) if (!xx_ok) xx_ok = getok;
- }
-
- /* Partial dialing */
-
- if (mdmcapas & CKD_AT
-#ifndef MINIDIAL
- || mymdmtyp == n_MICROCOM
-#endif /* MINIDIAL */
- ) {
- int x;
- x = (int) strlen(telnbr);
- if (x > 0) {
- if (telnbr[x-1] == ';') {
- partial = 1;
- debug(F110,"ckdial sets partial=1:",telnbr,0);
- } else if (partial) {
- ckmakmsg(fbuf,FULLNUML,telnbr,";",NULL,NULL); /* add one */
- telnbr = fbuf;
- }
- }
- }
- msleep(500);
-
- debug(F101,"ckdial dialtmo","",dialtmo); /* Timeout */
-
- if (fc == 1) { /* ANSWER */
- waitct = (dialatmo > -1) ? dialatmo : 0;
- } else { /* DIAL */
- if (dialtmo < 1) { /* Automatic computation. */
-#ifdef CK_TAPI
- if (tttapi && !tapipass) {
- waitct = 1 * (int)strlen(telnbr) ; /* Worst case dial time */
- waitct += 60; /* dialtone + completion wait times */
- for (s = telnbr; *s; s++) { /* add in pause characters time */
- if (*s == ',') {
- waitct += 2; /* unless it was changed in the modem */
- } else if (*s == 'W' ||
- *s == 'w' ||
- *s == '$' ||
- *s == '@'
- ) {
- waitct += 8;
- }
- }
- } else {
-#endif /* CK_TAPI */
- waitct = 1 * (int)strlen(telnbr) ;
- /* dialtone + completion wait times */
- waitct += mp->dial_time;
- for (s = telnbr; *s; s++) {
- for (p = mp->pause_chars; *p; p++)
- if (*s == *p) {
- waitct += mp->pause_time;
- break;
- }
- }
-#ifdef CK_TAPI
- }
-#endif /* CK_TAPI */
- } else {
- waitct = dialtmo; /* User-specified timeout */
- }
- debug(F101,"ckdial waitct A","",waitct);
- }
-
-/*
- waitct is our alarm() timer.
- mdmwait is how long we tell the modem to wait for carrier.
- We set mdmwait to be 5 seconds less than waitct, to increase the
- chance that we get a response from the modem before timing out.
-*/
- if (waitct <= 0) { /* 0 or negative means wait forever */
-#ifdef COMMENT
- waitct = 254; /* These were backwards in 7.0.196 */
- mdmwait = 0;
-#else
- waitct = 0; /* Fixed in 7.0.198. */
- mdmwait = 254;
-#endif /* COMMENT */
- } else {
- if (dialtmo < 1) { /* Automatic computation. */
-#ifdef XWAITCT
- /* Addtl wait slop can be defined at compile time */
- waitct += XWAITCT;
-#endif /* XWAITCT */
- if (waitct < 60 + mdmwaitd)
- waitct = 60 + mdmwaitd;
- }
- if (mdmcapas & CKD_AT) { /* AT command-set modems */
- mdmwait = waitct; /* S7 timeout = what user asked for */
- waitct += mdmwaitd; /* Kermit timeout a bit later */
- } else { /* Non-AT */
- mdmwait = waitct; /* no difference */
- }
- }
- debug(F101,"ckdial waitct B","",waitct);
- if (fc == 1) { /* ANSWER */
-#ifdef COMMENT
-/*
- This is wrong. mdmwait is the value given to S7 in Hayeslike modems.
- When in autoanswer mode, this is the amount of time the modem waits for
- carrier once ringing starts. Whereas waitct is the timeout given to the
- ANSWER command, which is an entirely different thing. Since the default
- ANSWER timeout is 0 (meaning "wait forever"), the following statement sets
- S7 to 0, which, on some modems (like the USR Sportster) makes it hang up
- and report NO CARRIER the instant the phone rings.
-*/
- mdmwait = waitct;
-#else
- if (mdmwait <= 0)
- mdmwait = 60; /* Always wait 60 seconds. */
-#endif /* COMMENT */
-
- }
- if (!quiet && !backgrd) { /* Print information messages. */
-#ifdef VMS
- printf(" \n");
- fflush(stdout);
-#endif /* VMS */
- if (fc == 1)
- printf(" Waiting for phone call...\n");
- else
- printf(" %srying: %s...\n", x1 > 0 ? "Ret" : "T", telnbr);
- if (x1 == 0 && x2 == 0 && dialsta != DIA_PART) {
- if (network) {
- printf(" Via modem server: %s, modem: %s\n",
- ttname, gmdmtyp() );
- } else {
-#ifdef CK_TAPI
- if (tttapi && !tapipass)
- printf(" Device: %s, modem: %s", ttname, "TAPI" );
- else
-#endif /* CK_TAPI */
- printf(" Device: %s, modem: %s",
- ttname, gmdmtyp() );
- if (speed > -1L)
- printf(", speed: %ld\n", speed);
- else
- printf(", speed: (unknown)\n");
- }
- spdmax = dialmax > 0L ? dialmax : mp->max_speed;
-
-#ifndef NOHINTS
- if (hints && !quiet &&
- !network && spdmax > 0L && speed > spdmax
-#ifdef CK_TAPI
- && (!tttapi || tapipass)
-#endif /* CK_TAPI */
- ) {
- printf("\n*************************\n");
- printf(
- "Interface speed %ld might be too high for this modem type.\n",
- speed
- );
- printf(
- "If dialing fails, SET SPEED to %ld or less and try again.\n",
- spdmax
- );
- printf("(Use SET HINTS OFF to suppress future hints.)\n");
- printf("*************************\n");
- printf("\n");
- }
-#endif /* NOHINTS */
- printf(" %s timeout: ", fc == 0 ? "Dial" : "Answer");
- if (waitct > 0)
- printf("%d seconds\n",mdmwait);
- else
- printf(" (none)\n");
- printf(
-#ifdef MAC
- " Type Command-. to cancel.\n"
-#else
-#ifdef UNIX
- " To cancel: type your interrupt character (normally Ctrl-C).\n"
-#else
- " To cancel: type Ctrl-C (hold down Ctrl, press C).\n"
-#endif /* UNIX */
-#endif /* MAC */
- );
- }
- }
- debug(F111,"ckdial",ttname,(int) (speed / 10L));
- debug(F101,"ckdial timeout","",waitct);
-#ifdef OS2
- term_io = 0;
-#endif /* OS2 */
-
-/* Set timer and interrupt handlers. */
- savint = signal( SIGINT, dialint ) ; /* And terminal interrupt handler. */
- cc_alrm_execute(ckjaddr(sjbuf), 0, dialtime, _dodial, faildial);
-
- signal(SIGINT, savint);
-#ifdef OS2
- if (dialsta == DIA_OK) /* Dialing is completed */
- DialerSend(OPT_KERMIT_CONNECT, 0);
- term_io = term_io_sav;
-#endif /* OS2 */
- if (dialsta == DIA_PART || dialsta == DIA_OK) {
- /* This is needed, e.g., for Telnet modem servers */
- if (reliable != SET_OFF || !setreliable) {
- reliable = SET_OFF; /* Transport is not reliable */
- debug(F101,"ckdial reliable","",reliable);
- }
- return(1); /* Dial attempt succeeded */
- } else {
- return(0); /* Dial attempt failed */
- }
-} /* ckdial */
-
-/*
- getok() - wait up to n seconds for OK (0) or ERROR (4) response from modem.
- Use with Hayeslike or CCITT modems for reading the reply to a nondialing
- command.
-
- Second argument says whether to be strict about numeric result codes, i.e.
- to require they be preceded by CR or else be the first character in the
- response, e.g. to prevent the ATH0<CR> echo from looking like a valid
- response. Strict == 0 is needed for ATI on Telebit, which can return the
- model number concatenated with the numeric response code, e.g. "9620"
- ("962" is the model number, "0" is the response code). getok() Returns:
-
- 0 if it timed out,
- 1 if it succeeded,
- -1 on modem command, i/o, or other error.
-*/
-static ckjmpbuf okbuf;
-
-static SIGTYP
-#ifdef CK_ANSIC
-oktimo(int foo) /* Alarm handler for getok(). */
-#else
-oktimo(foo) int foo; /* Alarm handler for getok(). */
-#endif /* CK_ANSIC */
-/* oktimo */ {
-
-#ifdef OS2
- alarm(0);
- /* signal(SIGALRM,SIG_IGN); */
- debug(F100,"oktimo() SIGALRM caught -- SIG_IGN set","",0) ;
-#endif /* OS2 */
-
-#ifdef OSK /* OS-9, see comment in dialtime(). */
- sigmask(-1);
-#endif /* OSK */
-#ifdef NTSIG
- if ( foo == SIGALRM )
- PostAlarmSigSem();
- else
- PostCtrlCSem();
-#else /* NTSIG */
-#ifdef NT
- cklongjmp(ckjaddr(okbuf),1);
-#else /* NT */
- cklongjmp(okbuf,1);
-#endif /* NTSIG */
-#endif /* NT */
- /* NOTREACHED */
- SIGRETURN;
-}
-
-static int okstatus, okn, okstrict;
-
-static SIGTYP
-#ifdef CK_ANSIC
-dook(void * threadinfo)
-#else /* CK_ANSIC */
-dook(threadinfo) VOID * threadinfo ;
-#endif /* CK_ANSIC */
-/* dook */ {
- CHAR c;
-#ifdef DEBUG
- char * mdmmsg = "";
-#endif /* DEBUG */
-
- int i, x;
-#ifdef IKSD
- extern int inserver;
-#endif /* IKSD */
-#ifdef NTSIG
- signal(SIGINT,oktimo);
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- }
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef NT
-#ifdef IKSD
- if (inserver)
- setntcreds();
-#endif /* IKSD */
-#endif /* NT */
-#endif /* CK_LOGIN */
-
- if (mdmcapas & CKD_V25) { /* CCITT, easy... */
- waitfor("VAL");
- okstatus = 1;
- debug(F111,"Modem_Response(V25)","VAL",okstatus);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
-#ifndef MINIDIAL
- } else if (mymdmtyp == n_MICROCOM) { /* Microcom in SX mode, also easy */
- waitfor(MICROCOM.wake_prompt); /* (I think...) */
- debug(F111,"Modem_Response(Microcom)",MICROCOM.wake_prompt,okstatus);
- okstatus = 1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
-#endif /* MINIDIAL */
- } else { /* Hayes & friends, start here... */
- okstatus = 0; /* No status yet. */
- for (x = 0; x < RBUFL; x++) /* Initialize response buffer */
- rbuf[x] = SP; /* to all spaces */
- rbuf[RBUFL] = NUL; /* and terminate with NUL. */
- while (okstatus == 0) { /* While no status... */
- x = ddinc(okn); /* Read a character */
- if (x < 0) { /* I/O error */
- okstatus = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
- }
-#ifdef COMMENT
- /* too much */
- debug(F101,"getok ddinc","",x); /* Got a character. */
-#endif /* COMMENT */
- c = (char) (x & 0x7f); /* Get low order 7 bits */
- if (!c) /* Don't deposit NULs */
- continue; /* or else didweget() won't work */
- if (dialdpy) conoc((char)c); /* Echo it if requested */
- for (i = 0; i < RBUFL-1; i++) /* Rotate buffer */
- rbuf[i] = rbuf[i+1];
- rbuf[RBUFL-1] = c; /* Deposit character at end */
-#ifdef COMMENT
- /* too much */
- debug(F000,"getok:",rbuf,(int) c); /* Log it */
-#endif /* COMMENT */
- switch (c) { /* Interpret it. */
- case CR: /* Got a carriage return. */
- switch(rbuf[RBUFL-2]) { /* Look at character before it. */
- case '0': /* 0 = OK numeric response */
- if (!okstrict ||
- rbuf[RBUFL-3] == CR || rbuf[RBUFL-3] == SP) {
- nonverbal = 1;
- okstatus = 1; /* Good response */
- }
- debug(F111,"Modem_Response(Hayes)","0",okstatus);
- break;
- case '4': /* 4 = ERROR numeric response */
-#ifndef MINIDIAL
- /* Or Telebit model number 964! */
- if (mymdmtyp == n_TELEBIT &&
- isdigit(rbuf[RBUFL-3]) &&
- isdigit(rbuf[RBUFL-4]))
- break;
- else
-#endif /* MINIDIAL */
- if (!okstrict ||
- rbuf[RBUFL-3] == CR || rbuf[RBUFL-3] == SP) {
- nonverbal = 1;
- okstatus = -1; /* Bad command */
- }
- debug(F111,"Modem_Response(Hayes)","4",okstatus);
- break;
- }
- if (dialdpy && nonverbal) /* If numeric results, */
- conoc(LF); /* echo a linefeed too. */
- break;
- case LF: /* Got a linefeed. */
- /*
- Note use of explicit octal codes in the string for
- CR and LF. We want real CR and LF here, not whatever
- the compiler happens to replace \r and \n with...
- */
- if (!strcmp(rbuf+RBUFL-4,"OK\015\012")) { /* Good response */
- okstatus = 1;
- debug(F111,"Modem_Response(Hayes)","OK",okstatus);
- }
- if (!strcmp(rbuf+RBUFL-3,"OK\012")) { /* Good response */
- okstatus = 1;
- debug(F111,"Modem_Response(Hayes)","OK",okstatus);
- } else if (!strcmp(rbuf+RBUFL-7,"ERROR\015\012")) { /* Error */
- okstatus = -1;
- debug(F111,"Modem_Response(Hayes)","ERROR",okstatus);
- } else if (!strcmp(rbuf+RBUFL-6,"ERROR\012")) { /* Error */
- okstatus = -1;
- debug(F111,"Modem_Response(Hayes)","ERROR",okstatus);
- }
- break;
- /* Check whether modem echoes its commands... */
- case 't': /* Got little t */
- if (!strcmp(rbuf+RBUFL-3,"\015at") || /* See if it's "at" */
- !strcmp(rbuf+RBUFL-3," at"))
- mdmecho = 1;
- /* debug(F111,"MDMECHO-t",rbuf+RBUFL-2,mdmecho); */
- break;
- case 'T': /* Got Big T */
- if (!strcmp(rbuf+RBUFL-3,"\015AT") || /* See if it's "AT" */
- !strcmp(rbuf+RBUFL-3," AT"))
- mdmecho = 1;
- /* debug(F111,"MDMECHO-T",rbuf+RBUFL-3,mdmecho); */
- break;
- default: /* Other characters, accumulate. */
- okstatus = 0;
- break;
- }
- }
- }
- debug(F101,"getok","",okstatus); /* <-- It's a lie (why?) */
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
-}
-
-static SIGTYP
-#ifdef CK_ANSIC
-failok(void * threadinfo)
-#else /* CK_ANSIC */
-failok(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* failok */ {
- debug(F100,"longjmp returned to getok()","",0);
- debug(F100,"getok timeout","",0);
- SIGRETURN;
-}
-
-int
-getok(n, strict) int n, strict; {
- debug(F101,"getok entry n","",n);
- okstatus = 0;
- okn = n;
- okstrict = strict;
-
-#ifdef DYNAMIC
- if (!rbuf) {
- if (!(rbuf = malloc(RBUFL+1))) { /* Allocate input line buffer */
- dialsta = DIA_IE;
- return(-1);
- }
- debug(F101,"GETOK rbuf malloc ok","",RBUFL+1);
- }
-#endif /* DYNAMIC */
-
- mdmecho = 0; /* Assume no echoing of commands */
-
- debug(F100,"about to alrm_execute dook()","",0);
- alrm_execute( ckjaddr(okbuf), n, oktimo, dook, failok ) ;
- debug(F100,"returning from alrm_execute dook()","",0);
-
- ttflui(); /* Flush input buffer */
- return(okstatus); /* Return status */
-}
-
-/* G E T H R N -- Get Hayes Result Numeric */
-
-static VOID
-gethrn() {
- char c;
- int x;
-/*
- Hayes numeric result codes (Hayes 1200 and higher):
- 0 = OK
- 1 = CONNECT at 300 bps (or 1200 bps on Hayes 1200 with basic code set)
- 2 = RING
- 3 = NO CARRIER
- 4 = ERROR (in command line)
- 5 = CONNECT 1200 (extended code set)
- Hayes 2400 and higher:
- 6 = NO DIALTONE
- 7 = BUSY
- 8 = NO ANSWER
- 9 = (there is no 9)
- 10 = CONNECT 2400
- Reportedly, the codes for Hayes V.32 modems are:
- 1x = CONNECT <suffix>
- 5x = CONNECT 1200 <suffix>
- 9x = CONNECT 2400 <suffix>
- 11x = CONNECT 4800 <suffix>
- 12x = CONNECT 9600 <suffix>
- Where:
- x: suffix:
- R = RELIABLE
- RC = RELIABLE COMPRESSED
- L = LAPM
- LC = LAPM COMPRESSED
- And for Telebits, all the above, except no suffix in numeric mode, plus:
- 11 = CONNECT 4800
- 12 = CONNECT 9600
- 13 = CONNECT 14400
- 14 = CONNECT 19200
- 15 = CONNECT 38400
- 16 = CONNECT 57600
- 20 = CONNECT 300/REL (= MNP)
- 22 = CONNECT 1200/REL (= MNP)
- 23 = CONNECT 2400/REL (= MNP)
- 46 = CONNECT 7512 (i.e. 75/1200)
- 47 = CONNECT 1275 (i.e. 1200/75)
- 48 = CONNECT 7200
- 49 = CONNECT 12000
- 50 = CONNECT FAST (not on T1600/3000)
- 52 = RRING
- 53 = DIALING
- 54 = NO PROMPTTONE
- 61 = CONNECT FAST/KERM (Kermit spoof)
- 70 = CONNECT FAST/COMP (PEP + compression)
- 71 = CONNECT FAST/KERM/COMP (PEP + compression + Kermit spoof)
-
- And for others, lots of special cases below...
-*/
-#define NBUFL 8
- char nbuf[NBUFL+1]; /* Response buffer */
- int i = 0, j = 0; /* Buffer pointers */
-
- debug(F101,"RESPONSE mdmecho","",mdmecho);
- if (mdmecho) { /* Sponge up dialing string echo. */
- while (1) {
- c = (char) (ddinc(0) & 0x7f);
- debug(F000,"SPONGE","",c);
- dialoc(c);
- if (c == CR) break;
- }
- }
- while (mdmstat == 0) { /* Read response */
- for (i = 0; i < NBUFL; i++) /* Clear the buffer */
- nbuf[i] = '\0';
- i = 0; /* Reset the buffer pointer. */
- c = (char) (ddinc(0) & 0177); /* Get first digit of response. */
- /* using an untimed, blocking read. */
- debug(F000,"RESPONSE-A","",c);
- dialoc(c); /* Echo it if requested. */
- if (!isdigit(c)) /* If not a digit, keep looking. */
- continue;
- nbuf[i++] = c; /* Got first digit, save it. */
- while (c != CR && i < 8) { /* Read chars up to CR */
- x = ddinc(0) & 0177; /* Get a character. */
- c = (char) x; /* Got it OK. */
- debug(F000,"RESPONSE-C","",c);
- if (c != CR) /* If it's not a carriage return, */
- nbuf[i++] = c; /* save it. */
- dialoc(c); /* Echo it. */
- }
- nbuf[i] = '\0'; /* Done, terminate the buffer. */
- debug(F110,"dial hayesnv lbuf",lbuf,0);
- debug(F111,"dial hayesnv got",nbuf,i);
- /*
- Separate any non-numeric suffix from the numeric
- result code with a null.
- */
- for (j = i-1; (j > -1) && !isdigit(nbuf[j]); j--)
- nbuf[j+1] = nbuf[j];
- j++;
- nbuf[j++] = '\0';
- debug(F110,"dial hayesnv numeric",nbuf,0);
- debug(F111,"dial hayesnv suffix ",nbuf+j,j);
- /* Probably phone number echoing. */
- if ((int)strlen(nbuf) > 3)
- continue;
-
- /* Now read and interpret the results... */
-
- i = atoi(nbuf); /* Convert to integer */
- switch (i) {
- case 0:
- mdmstat = D_PARTIAL; /* OK response */
- break;
- case 1: /* CONNECT */
- mdmstat = CONNECTED; /* Could be any speed */
- break;
- case 2: /* RING */
- if (dialdpy)
- printf("\r\n Local phone is ringing!\r\n");
- mdmstat = D_FAILED;
- dialsta = DIA_RING;
- break;
- case 3: /* NO CARRIER */
- if (dialdpy) printf("\r\n No Carrier.\r\n");
- mdmstat = D_FAILED;
- dialsta = DIA_NOCA;
- break;
- case 4: /* ERROR */
- if (dialdpy)
- printf("\r\n Modem Command Error.\r\n");
- mdmstat = D_FAILED;
- dialsta = DIA_ERR;
- break;
- case 5: /* CONNECT 1200 */
- spdchg(1200L); /* Change speed if necessary. */
- mdmstat = CONNECTED;
- break;
- case 6: /* NO DIALTONE */
-#ifndef MINIDIAL
- if (mymdmtyp == n_MICROLINK && atoi(diallcc) == 49 && dialdpy)
- printf("\r\n Dial Locked.\r\n"); /* Germany */
- else
-#endif /* MINIDIAL */
- if (dialdpy)
- printf("\r\n No Dialtone.\r\n");
- mdmstat = D_FAILED;
- dialsta = DIA_NODT;
- break;
- case 7: /* BUSY */
- if (dialdpy) printf("\r\n Busy.\r\n");
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- break;
- case 8: /* NO ANSWER */
-#ifndef MINIDIAL
- if (mymdmtyp == n_MICROLINK && atoi(diallcc) == 41 && dialdpy)
- printf("\r\n Dial Locked.\r\n"); /* Switzerland */
- else
-#endif /* MINIDIAL */
- if (dialdpy)
- printf("\r\n No Answer.\r\n");
- mdmstat = D_FAILED;
- dialsta = DIA_NOAN;
- break;
-
- case 9:
-#ifndef MINIDIAL
- if (mymdmtyp == n_XJACK || mymdmtyp == n_SUPRAX) {
- spdchg(600);
- break;
- } /* fall thru */
-#endif /* MINIDIAL */
- case 10: /* CONNECT 2400 */
- spdchg(2400L); /* Change speed if necessary. */
- mdmstat = CONNECTED;
- break;
-
-#ifndef MINIDIAL
-
-/* Starting here, we get different meanings from different manufacturers */
-
- case 11:
- if (mymdmtyp == n_USR) {
- if (dialdpy) printf(" Ringing...\r\n");
- } else {
- spdchg(4800L); /* CONNECT 4800 */
- mdmstat = CONNECTED;
- }
- break;
- case 12:
- if (mymdmtyp == n_USR) {
- if (dialdpy)
- printf("\r\n Answered by voice.\r\n");
- mdmstat = D_FAILED;
- dialsta = DIA_VOIC;
- } else if (mymdmtyp == n_KEEPINTOUCH) {
- spdchg(7200L);
- mdmstat = CONNECTED;
- } else {
- spdchg(9600L);
- mdmstat = CONNECTED;
- }
- break;
- case 13:
- if (mymdmtyp == n_ATT1900 || mymdmtyp == n_ATT1910) {
- if (dialdpy) printf(" Wait...\r\n");
- break;
- } else if (mymdmtyp == n_USR || mymdmtyp == n_USRX2)
- spdchg(9600L);
- else if (is_rockwell || is_supra ||
- mymdmtyp == n_ZOLTRIX || mymdmtyp == n_XJACK)
- spdchg(7200L);
- else if (mymdmtyp != n_MICROLINK)
- spdchg(14400L);
- mdmstat = CONNECTED;
- break;
- case 14:
- if (is_rockwell || is_supra || mymdmtyp == n_XJACK)
- spdchg(12000L);
- else if (mymdmtyp == n_DATAPORT || mymdmtyp == n_MICROLINK)
- spdchg(14400L);
- else if (mymdmtyp == n_KEEPINTOUCH)
- spdchg(9600L);
- else if (mymdmtyp != n_USR && mymdmtyp != n_ZOLTRIX)
- spdchg(19200L);
- mdmstat = CONNECTED;
- break;
- case 15:
- if (is_rockwell || is_supra ||
- mymdmtyp == n_ZOLTRIX || mymdmtyp == n_XJACK)
- spdchg(14400L);
- else if (mymdmtyp == n_USR)
- spdchg(1200L);
- else if (mymdmtyp == n_ZYXEL || mymdmtyp == n_INTEL)
- spdchg(7200L);
- else if (mymdmtyp == n_DATAPORT)
- spdchg(19200L);
- else
- spdchg(38400L);
- mdmstat = CONNECTED;
- break;
- case 16:
- if (is_rockwell || is_supra ||
- mymdmtyp == n_ZOLTRIX || mymdmtyp == n_XJACK)
- spdchg(19200L);
- else if (mymdmtyp == n_USR)
- spdchg(2400L);
- else if (mymdmtyp == n_DATAPORT)
- spdchg(7200L);
- else if (mymdmtyp != n_ZYXEL && mymdmtyp != n_INTEL) /* 12000 */
- spdchg(57600L);
- mdmstat = CONNECTED;
- break;
- case 17:
- if (mymdmtyp != n_DATAPORT || mymdmtyp == n_XJACK) /* 16800 */
- spdchg(38400L);
- else if (mymdmtyp == n_ZYXEL || mymdmtyp == n_INTEL)
- spdchg(14400L);
- else if (mymdmtyp == n_KEEPINTOUCH)
- spdchg(14400L);
- else if (mymdmtyp == n_USR)
- spdchg(9600L);
- mdmstat = CONNECTED;
- break;
- case 18:
- if (is_rockwell || is_supra ||
- mymdmtyp == n_ZOLTRIX || mymdmtyp == n_XJACK ||
- mymdmtyp == n_MHZATT || mymdmtyp == n_LUCENT)
- spdchg(57600L);
- else if (mymdmtyp == n_INTEL)
- spdchg(19200L);
- else if (mymdmtyp == n_USR || mymdmtyp == n_USRX2)
- spdchg(4800L);
- mdmstat = CONNECTED;
- break;
- case 19:
- if (mymdmtyp == n_DATAPORT)
- spdchg(300L);
- else if (mymdmtyp == n_ZYXEL || mymdmtyp == n_INTEL)
- spdchg(38400L);
- else
- spdchg(115200L);
- mdmstat = CONNECTED;
- break;
- case 20:
- if (mymdmtyp == n_USR || mymdmtyp == n_USRX2)
- spdchg(7200L);
- else if (mymdmtyp == n_DATAPORT)
- spdchg(2400L);
- else if (mymdmtyp == n_ZYXEL || mymdmtyp == n_INTEL)
- spdchg(57600L);
- else
- spdchg(300L);
- mdmstat = CONNECTED;
- break;
- case 21:
- if (mymdmtyp == n_DATAPORT)
- spdchg(4800L);
- mdmstat = CONNECTED;
- break;
- case 22:
- if (is_rockwell || is_supra || mymdmtyp == n_XJACK)
- spdchg(8880L);
- else if (mymdmtyp == n_DATAPORT)
- spdchg(9600L);
- else if (mymdmtyp == n_KEEPINTOUCH)
- spdchg(300L);
- else if (!is_hayeshispd)
- spdchg(1200L);
- mdmstat = CONNECTED;
- break;
- case 23:
- if (is_hayeshispd || is_supra ||
- mymdmtyp == n_MULTI || mymdmtyp == n_XJACK)
- spdchg(8880L);
- else if (mymdmtyp != n_DATAPORT && !is_rockwell) /* 12000 */
- spdchg(2400L);
- mdmstat = CONNECTED;
- break;
- case 24:
- if (is_rockwell || is_supra || mymdmtyp == n_XJACK) {
- mdmstat = D_FAILED;
- dialsta = DIA_DELA; /* Delayed */
- break;
- } else if (is_hayeshispd || mymdmtyp == n_LUCENT)
- spdchg(7200L);
- else if (mymdmtyp == n_DATAPORT)
- spdchg(14400L);
- else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH)
- spdchg(1200L);
- mdmstat = CONNECTED;
- break;
- case 25:
- if (mymdmtyp == n_USR || mymdmtyp == n_USRX2)
- spdchg(14400L);
- else if (mymdmtyp == n_LUCENT)
- spdchg(12000L);
- else if (is_motorola)
- spdchg(9600L);
- else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH)
- spdchg(2400L);
- mdmstat = CONNECTED;
- break;
- case 26:
- if (mymdmtyp == n_DATAPORT)
- spdchg(19200L);
- else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH)
- spdchg(4800L);
- mdmstat = CONNECTED;
- break;
- case 27:
- if (mymdmtyp == n_DATAPORT)
- spdchg(38400L);
- else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH)
- spdchg(7200L);
- else if (mymdmtyp == n_MHZATT)
- spdchg(8880L);
- mdmstat = CONNECTED;
- break;
- case 28:
- if (mymdmtyp == n_DATAPORT)
- spdchg(7200L);
- else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH)
- spdchg(9600L);
- else if (mymdmtyp == n_MHZATT || mymdmtyp == n_LUCENT)
- spdchg(38400L);
- mdmstat = CONNECTED;
- break;
- case 29:
- if (is_motorola)
- spdchg(4800L);
- else if (mymdmtyp == n_DATAPORT)
- spdchg(19200L);
- mdmstat = CONNECTED;
- break;
- case 30:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(14400L);
- mdmstat = CONNECTED;
- } /* fall thru on purpose... */
- case 31:
- if (mymdmtyp == n_UCOM_AT || mymdmtyp == n_MICROLINK) {
- spdchg(4800L);
- mdmstat = CONNECTED;
- } else if (is_motorola) {
- spdchg(57600L);
- mdmstat = CONNECTED;
- }
- break;
- case 32:
- if (is_rockwell || is_supra || mymdmtyp == n_XJACK) {
- mdmstat = D_FAILED;
- dialsta = DIA_BLCK; /* Blacklisted */
- } else if (mymdmtyp == n_UCOM_AT || mymdmtyp == n_MICROLINK) {
- spdchg(9600L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_KEEPINTOUCH) {
- spdchg(300L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_INTEL) {
- spdchg(2400L);
- mdmstat = CONNECTED;
- }
- break;
- case 33: /* FAX connection */
- if (is_rockwell || is_supra ||
- mymdmtyp == n_ZOLTRIX || mymdmtyp == n_XJACK) {
- mdmstat = D_FAILED;
- dialsta = DIA_FAX;
- } else if (mymdmtyp == n_UCOM_AT ||
- is_motorola ||
- mymdmtyp == n_MICROLINK
- ) {
- spdchg(9600L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_MHZATT) {
- spdchg(115200L);
- mdmstat = CONNECTED;
- }
- break;
- case 34:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(1200L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_MICROLINK) {
- spdchg(7200L);
- mdmstat = CONNECTED;
- }
- break;
- case 35:
- if (is_rockwell) {
- spdchg(300L);
- dialsta = CONNECTED;
- } else if (is_motorola) {
- spdchg(14400L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(2400L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_MICROLINK) {
- spdchg(7200L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_ZOLTRIX || mymdmtyp == n_XJACK) /* DATA */
- mdmstat = CONNECTED;
- break;
- case 36:
- if (mymdmtyp == n_UCOM_AT) {
- spdchg(19200L);
- mdmstat = CONNECTED;
- } else if (is_motorola) {
- spdchg(1200L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(4800L);
- mdmstat = CONNECTED;
- }
- break;
- case 37:
- if (mymdmtyp == n_UCOM_AT) {
- spdchg(19200L);
- mdmstat = CONNECTED;
- } else if (is_motorola) {
- spdchg(2400L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(7200L);
- mdmstat = CONNECTED;
- }
- break;
- case 38:
- if (is_motorola) {
- spdchg(4800L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(9600L);
- mdmstat = CONNECTED;
- } /* fall thru on purpose... */
- case 39:
- if (mymdmtyp == n_UCOM_AT) {
- spdchg(38400L);
- mdmstat = CONNECTED;
- } else if (is_motorola) {
- spdchg(9600L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_MICROLINK) {
- spdchg(14400L);
- mdmstat = CONNECTED;
- }
- break;
- case 40:
- if (mymdmtyp == n_UCOM_AT) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOCA;
- } else if (is_motorola || mymdmtyp == n_INTEL ||
- mymdmtyp == n_KEEPINTOUCH) {
- spdchg(14400L);
- mdmstat = CONNECTED;
- }
- break;
- case 41:
- if (is_motorola) {
- spdchg(19200L);
- mdmstat = CONNECTED;
- }
- break;
- case 42:
- if (mymdmtyp == n_KEEPINTOUCH) {
- spdchg(300L);
- mdmstat = CONNECTED;
- } else if (is_motorola) {
- spdchg(38400L);
- mdmstat = CONNECTED;
- } /* fall thru on purpose... */
- case 43:
- if (mymdmtyp == n_UCOM_AT) {
- spdchg(57600L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_USRX2)
- mdmstat = CONNECTED; /* 168000 */
- break;
- case 44:
- if (is_rockwell) {
- spdchg(8800L);
- dialsta = CONNECTED;
- } else if (is_motorola) {
- spdchg(7200L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(1200L);
- mdmstat = CONNECTED;
- }
- break;
- case 45:
- if (is_motorola) {
- spdchg(57600L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(2400L);
- mdmstat = CONNECTED;
- } else if (n_USR) {
- spdchg(14400L);
- mdmstat = CONNECTED;
- }
- break;
- case 46:
- if (is_rockwell)
- spdchg(1200L);
- else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH)
- spdchg(4800L);
- else
- spdchg(8880L); /* 75/1200 split speed */
- mdmstat = CONNECTED;
- break;
- case 47:
- if (is_rockwell)
- spdchg(2400L);
- else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH)
- spdchg(7200L);
- else
- printf("CONNECT 1200/75 - Not supported by C-Kermit\r\n");
- mdmstat = CONNECTED;
- break;
- case 48:
- if (is_rockwell)
- spdchg(4800L);
- else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH)
- spdchg(9600L);
- else
- spdchg(7200L);
- mdmstat = CONNECTED;
- break;
- case 49:
- if (is_rockwell)
- spdchg(7200L);
- mdmstat = CONNECTED;
- break;
- case 50: /* CONNECT FAST */
- if (is_rockwell)
- spdchg(9600L);
- else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH)
- spdchg(14400L);
- mdmstat = CONNECTED;
- break;
- case 51:
- if (mymdmtyp == n_UCOM_AT) {
- mdmstat = D_FAILED;
- dialsta = DIA_NODT;
- }
- break;
- case 52: /* RRING */
- if (mymdmtyp == n_TELEBIT)
- if (dialdpy) printf(" Ringing...\r\n");
- break;
- case 53: /* DIALING */
- if (mymdmtyp == n_TELEBIT)
- if (dialdpy) printf(" Dialing...\r\n");
- break;
- case 54:
- if (is_rockwell) {
- spdchg(19200L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(1200L);
- mdmstat = CONNECTED;
- } else if (mymdmtyp == n_TELEBIT) {
- if (dialdpy) printf("\r\n No Prompttone.\r\n");
- mdmstat = D_FAILED;
- dialsta = DIA_NODT;
- }
- break;
- case 55:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(2400L);
- mdmstat = CONNECTED;
- }
- break;
- case 56:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(4800L);
- mdmstat = CONNECTED;
- }
- break;
- case 57:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(7200L);
- mdmstat = CONNECTED;
- }
- break;
- case 58:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(9600L);
- mdmstat = CONNECTED;
- }
- break;
- case 59:
- if (mymdmtyp == n_INTEL) /* 12000 */
- mdmstat = CONNECTED;
- break;
- case 60:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(14400L);
- mdmstat = CONNECTED;
- }
- break;
- case 64:
- if (mymdmtyp == n_INTEL) {
- spdchg(1200L);
- mdmstat = CONNECTED;
- } else if (is_supra) {
- spdchg(28800L);
- mdmstat = CONNECTED;
- }
- break;
- case 65:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(2400L);
- mdmstat = CONNECTED;
- }
- break;
- case 66:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(4800L);
- mdmstat = CONNECTED;
- }
- break;
- case 67:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(7200L);
- mdmstat = CONNECTED;
- }
- break;
- case 68:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(9600L);
- mdmstat = CONNECTED;
- }
- break;
- case 69:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) /* 12000 */
- mdmstat = CONNECTED;
- break;
- case 70:
- if (mymdmtyp == n_INTEL || mymdmtyp == n_KEEPINTOUCH) {
- spdchg(14400L);
- mdmstat = CONNECTED;
- }
- break;
- case 73:
- if (mymdmtyp == n_UCOM_AT) {
- spdchg(115200L);
- mdmstat = CONNECTED;
- break;
- } /* else fall thru */
- if (mymdmtyp == n_TELEBIT) /* Early models only */
- mdmstat = CONNECTED;
- break;
- case 85:
- if (mymdmtyp == n_USR || mymdmtyp == n_USRX2)
- spdchg(19200L);
- mdmstat = CONNECTED;
- break;
- case 91: /* 21600 */
- case 99: /* 24000 */
- case 103: /* 26400 */
- if (mymdmtyp == n_USRX2)
- mdmstat = CONNECTED;
- break;
- case 107:
- if (mymdmtyp == n_USR || mymdmtyp == n_USRX2) {
- spdchg(28800L);
- mdmstat = CONNECTED;
- }
- break;
- case 151: /* 312000 */
- case 155: /* 336000 */
- if (mymdmtyp == n_USRX2)
- mdmstat = CONNECTED;
- break;
-
-#endif /* MINIDIAL */
- default:
-#ifndef MINIDIAL
- if (mymdmtyp == n_USR || mymdmtyp == n_USRX2 ||
- is_hayeshispd || is_rockwell)
-#endif /* MINIDIAL */
- if (i > 12) /* There are hundreds of them... */
- mdmstat = CONNECTED;
- break;
- }
- }
- if (mdmstat == CONNECTED && nbuf[j] != '\0') {
- if (dialdpy) {
- printf("\r\n");
- if (nbuf[j] == 'R') printf(" RELIABLE");
- if (nbuf[j] == 'L') printf(" LAPM");
- if (nbuf[j+1] == 'C') printf(" COMPRESSED");
- printf("\r\n");
- }
- ckstrncpy(lbuf,nbuf,LBUFL); /* (for messages...) */
- }
-}
-
-static VOID /* Get Hayes Result in Word mode */
-gethrw() {
- char *cptr, *s;
- long conspd;
-
- if (mdmspd && !network) {
- s = lbuf;
- while (*s != '\0' && *s != 'C') s++;
- cptr = (*s == 'C') ? s : NULL;
- conspd = 0L;
- if ((cptr != NULL) && !strncmp(cptr,"CONNECT ",8)) {
- if ((int)strlen(cptr) < 9) /* Just CONNECT, */
- conspd = 300L; /* use 300 bps */
- else if (isdigit(*(cptr+8))) /* not CONNECT FAST */
- conspd = atol(cptr + 8); /* CONNECT nnnn */
- if (conspd != speed) {
- if ((conspd / 10L) > 0) {
- if (ttsspd((int) (conspd / 10L)) < 0) {
- printf(" Can't change speed to %ld\r\n",
- conspd);
- } else {
- speed = conspd;
- mdmstat = CONNECTED;
- if ( !quiet && !backgrd )
- printf(" Speed changed to %ld\r\n",
- conspd);
- }
- }
- } /* Expanded to handle any conceivable speed */
- }
- }
-#ifndef MINIDIAL
- if (mymdmtyp == n_TELEBIT) {
- if (didweget(lbuf,"CONNECT FAST/KERM")) {
- mdmstat = CONNECTED;
- if (dialdpy) printf("FAST/KERM ");
- return;
- }
- }
-#endif /* MINIDIAL */
- if (didweget(lbuf,"RRING") ||
- didweget(lbuf,"RINGING") ||
- didweget(lbuf,"DIALING")) {
- mdmstat = 0;
- } else if (didweget(lbuf,"CONNECT")) {
- mdmstat = CONNECTED;
- } else if (didweget(lbuf,"OK")) {
- if (partial) {
- mdmstat = D_PARTIAL;
- } else {
- mdmstat = D_FAILED;
- dialsta = DIA_ERR;
- }
- } else if (didweget(lbuf,"NO CARRIER")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOCA;
- } else if (didweget(lbuf,"NO DIALTONE")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NODT;
- } else if (didweget(lbuf,"NO DIAL TONE")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NODT;
- } else if (didweget(lbuf,"BUSY")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BUSY;
- } else if (didweget(lbuf,"NO ANSWER")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOAN;
- } else if (didweget(lbuf,"VOICE")) {
- mdmstat = D_FAILED;
- dialsta = DIA_VOIC;
- } else if (didweget(lbuf,"VCON")) {
- mdmstat = D_FAILED;
- dialsta = DIA_VOIC;
- } else if (didweget(lbuf,"NO PROMPT TONE")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NODT;
- } else if (didweget(lbuf,"REMOTE ACCESS FAILED")) {
- mdmstat = D_FAILED;
- dialsta = DIA_NOCA;
- } else if (didweget(lbuf,"FAX")) {
- mdmstat = D_FAILED;
- dialsta = DIA_FAX;
- } else if (didweget(lbuf,"WAIT - CONNECTING") ||
- didweget(lbuf,"WAIT-CONNECTING")) { /* AT&T STU-III 19xx */
- mdmstat = 0;
- } else if (didweget(lbuf,"DELAYED")) {
- mdmstat = D_FAILED;
- dialsta = DIA_DELA;
- } else if (didweget(lbuf,"BLACKLISTED")) {
- mdmstat = D_FAILED;
- dialsta = DIA_BLCK;
- } else if (didweget(lbuf,"COMPRESSION")) {
- mdmstat = 0;
- } else if (didweget(lbuf,"PROTOCOL")) {
- mdmstat = 0;
- } else if (didweget(lbuf,"DIAL LOCKED")) { /* Germany, Austria, Schweiz */
- mdmstat = D_FAILED;
- dialsta = DIA_BLCK;
- } else if ( didweget(lbuf,"RING") ||
- didweget(lbuf,"RING1") || /* Distinctive Ring 1 */
- didweget(lbuf,"RING2") || /* Distinctive Ring 2 */
- didweget(lbuf,"RING3") ) {
- mdmstat = (func_code == 0) ? D_FAILED : 0;
- dialsta = DIA_RING;
- } else if (didweget(lbuf,"ERROR")) {
- mdmstat = D_FAILED;
- dialsta = DIA_ERR;
- } else if (didweget(lbuf,"CARRIER")) { /* Boca / Rockwell family */
-#ifdef COMMENT
- if (is_rockwell)
-#endif /* COMMENT */
- mdmstat = 0;
-#ifdef COMMENT
- /* Does CARRIER ever mean the same as CONNECT? */
- else
- mdmstat = CONNECTED;
-#endif /* COMMENT */
- } else if (didweget(lbuf,"DATA")) { /* Boca / Rockwell family */
- /* This message is sent when the modem is in FAX mode */
- /* So setting this to CONNECTED may not be appropriate */
- /* We must send ATO\015 to the modem in response */
- /* Then we will get a CONNECTED message */
- mdmstat = CONNECTED;
- } else if (didweget(lbuf,"DIGITAL LINE")) {
- mdmstat = D_FAILED;
- dialsta = DIA_DIGI;
- } else if (didweget(lbuf,"DATE")) { /* Caller ID Date */
- debug(F110,"CALLID DATE",lbuf,0);
- /* Format is "DATE = MMDD" */
- makestr(&callid_date,lbuf);
- } else if (didweget(lbuf,"TIME")) { /* Caller ID Time */
- /* Format is "TIME = HHMM" */
- debug(F110,"CALLID TIME",lbuf,0);
- makestr(&callid_time,lbuf);
- } else if (didweget(lbuf,"NAME")) { /* Caller ID Name */
- /* Format is "NAME = <listing name>" */
- debug(F110,"CALLID NAME",lbuf,0);
- makestr(&callid_name,lbuf);
- } else if (didweget(lbuf,"NMBR")) { /* Caller ID Number */
- /* Format is "NMBR = <number>, 'P' or 'O'" */
- /* 'P' means Privacy Requested */
- /* 'O' means Out of Service or Not available */
- debug(F110,"CALLID NMBR",lbuf,0);
- makestr(&callid_nmbr,lbuf);
- } else if (didweget(lbuf,"MESG")) { /* Caller ID Unrecognized Message */
- /* Format is "MESG = <tag><length><data><checksum>" */
- debug(F110,"CALLID MESG",lbuf,0);
- makestr(&callid_mesg,lbuf);
- }
-}
-
-/* Maybe hang up the phone, depending on various SET DIAL parameters. */
-
-int
-dialhup() {
- int x = 0;
- if (dialhng && dialsta != DIA_PART) { /* DIAL HANGUP ON? */
- x = mdmhup(); /* Try modem-specific method first */
- debug(F101,"dialhup mdmhup","",x);
- if (x > 0) { /* If it worked, */
- dialsta = DIA_HUP;
- if (dialdpy)
- printf(" Modem hangup OK\r\n"); /* fine. */
- } else if (network /* If we're telnetted to */
-#ifdef TN_COMPORT
- && !istncomport() /* (without RFC 2217) */
-#endif /* TN_COMPORT */
- ) {
- dialsta = DIA_HANG;
- if (dialdpy) /* a modem server, just print a msg */
- printf(" WARNING - modem hangup failed\r\n"); /* don't hangup! */
- return(0);
- } else { /* Otherwise */
- x = tthang(); /* Tell the OS to turn off DTR. */
- if (x > 0) { /* Yes, tell results from tthang() */
- dialsta = DIA_HUP;
- if (dialdpy) printf(" Hangup OK\r\n");
- } else if (x == 0) {
- if (dialdpy) printf(" Hangup skipped\r\n");
- } else {
- dialsta = DIA_HANG;
- if (dialdpy) perror(" Hangup error");
- }
- ttflui();
- }
- } else if (dialdpy) printf(" Hangup skipped\r\n"); /* DIAL HANGUP OFF */
- return(x);
-}
-
-/*
- M D M H U P --
-
- Sends escape sequence to modem, then sends its hangup command. Returns:
- 0: If modem type is 0 (direct serial connection),
- or if modem type is < 0 (network connection),
- or if no action taken because DIAL MODEM-HANGUP is OFF)
- or because no hangup string for current modem type,
- or C-Kermit is in remote mode,
- or if action taken but there was no positive response from modem;
- 1: Success: modem is in command state and acknowledged the hangup command;
- -1: On modem command error.
-*/
-int
-mdmhup() {
-#ifdef MDMHUP
- int m, x = 0;
- int xparity;
- int savcarr;
- extern int ttcarr;
- char *s, *p, c;
- MDMINF * mp = NULL;
-
- debug(F101,"mdmhup dialmhu","",dialmhu); /* MODEM-HANGUP METHOD */
- debug(F101,"mdmhup local","",local);
-
- if (dialmhu == 0 || local == 0) /* If DIAL MODEM-HANGUP is OFF, */
- return(0); /* or not in local mode, fail. */
-
- debug(F101,"mdmhup dialsta","",dialsta);
- debug(F101,"mdmhup mdmset","",mdmset);
-
- if (dialsta != DIA_OK && !mdmset) /* It's not a dialed connection */
- return(0);
-
-#ifdef CK_TAPI
- if (tttapi && !tapipass) /* Don't hangup if using TAPI */
- return(0);
-#endif /* CK_TAPI */
-
-#ifdef COMMENT
- /* No, we still need this for modems that ignore DTR */
- if (mymdmtyp == n_GENERIC && !network)
- return(0);
-#endif /* COMMENT */
-
- debug(F101,"mdmhup dialesc","",dialesc);
- if (dialesc < 0)
- return(0); /* No modem escape-character, fail. */
-
- savcarr = ttcarr;
- ttcarr = CAR_OFF;
- x = ttchk();
- ttcarr = savcarr;
- debug(F101,"mdmhup ttchk","",x);
- if (x < 0) /* There appears to be no connection */
- return(0);
- x = 0;
-
-#ifdef OS2
-/*
- In OS/2, if CARRIER is OFF, and there is indeed no carrier signal, any
- attempt to do i/o at this point can hang the program. This might be true
- for other operating systems too.
-*/
- if (!network /* Not a network connection */
-#ifdef TN_COMPORT
- || istncomport()
-#endif /* TN_COMPORT */
- ) {
- m = ttgmdm(); /* Get modem signals */
- if ((m > -1) && (m & BM_DCD == 0)) /* Check for carrier */
- return(0); /* No carrier, skip the rest */
- }
-#endif /* OS2 */
-
- debug(F111,"mdmhup network",ttname,network);
- debug(F101,"mdmhup mymdmtyp","",mymdmtyp);
- debug(F101,"mdmhup mdmtyp","",mdmtyp);
- /* In case of HANGUP before DIAL */
- if (network && mdmtyp < 1) /* SET HOST but no subsequent */
- return(0); /* SET MODEM TYPE... */
- if (mymdmtyp == 0 && mdmtyp > 0)
- mymdmtyp = mdmtyp;
- if (mymdmtyp < 1) /* Not using a modem */
- return(0);
- if (mymdmtyp > 0) /* An actual modem... */
- mp = modemp[mymdmtyp];
- if (!mp) { /* Get pointer to its MDMINF struct */
- debug(F100,"mdmhup no MDMINF","",0);
- return(0);
- }
- mdmcapas = dialcapas ? dialcapas : mp->capas;
- xx_ok = mp->ok_fn; /* Pointer to response reader */
-
- s = dialhcmd ? dialhcmd : mp->hup_str; /* Get hangup command */
- if (!s) s = "";
- debug(F110,"mdmhup hup_str",s,0);
- if (!*s) return(0); /* If none, fail. */
-
- if (ttpkt(speed,FLO_DIAL,parity) < 0) /* Condition line for dialing */
- return(-1);
-
- xparity = parity; /* Set PARITY to NONE temporarily */
- parity = 0;
-
- /* In case they gave a SET MODEM ESCAPE command recently... */
-
- if (dialesc < 0 || dialesc > 127)
- c = NUL;
- else
- c = (char) (dialesc ? dialesc : mp->esc_char);
-
- if (mdmcapas & CKD_AT) { /* Hayes compatible */
- escbuf[0] = c;
- escbuf[1] = c;
- escbuf[2] = c;
- escbuf[3] = NUL;
- } else { /* Other */
- escbuf[0] = c;
- escbuf[1] = NUL;
- }
- debug(F110,"mdmhup escbuf",escbuf,0);
- if (escbuf[0]) { /* Have escape sequence? */
- debug(F101,"mdmhup esc_time",0,mp->esc_time);
- if (mp->esc_time) /* If we have a guard time */
- msleep(mp->esc_time); /* Pause for guard time */
- debug(F100,"mdmhup pause 1 OK","",0);
-
-#ifdef NETCONN /* Send modem's escape sequence */
- if (network) { /* Must catch errors here. */
- if (ttol((CHAR *)escbuf,(int)strlen((char *)escbuf)) < 0) {
- parity = xparity;
- return(-1);
- }
- debug(F110,"mdmhup ttslow net ok",escbuf,0);
- } else {
-#endif /* NETCONN */
- ttslow((char *)escbuf,wr); /* Send escape sequence */
- debug(F110,"mdmhup ttslow ok",escbuf,0);
-#ifdef NETCONN
- }
-#endif /* NETCONN */
-
- if (mp->esc_time) /* Pause for guard time again */
- msleep(mp->esc_time);
- else
- msleep(500); /* Wait half a sec for echoes. */
- debug(F100,"mdmhup pause 1 OK","",0);
-#ifdef COMMENT
- ttflui(); /* Flush response or echo, if any */
- debug(F100,"mdmhup ttflui OK","",0);
-#endif /* COMMENT */
- }
- ttslow(s,wr); /* Now Send hangup string */
- debug(F110,"mdmhup ttslow ok",s,0);
-/*
- This is not exactly right, but it works.
- If we are online:
- the modem says OK when it gets the escape sequence,
- and it says NO CARRIER when it gets the hangup command.
- If we are offline:
- the modem does NOT say OK (or anything else) when it gets the esc sequence,
- but it DOES say OK (and not NO CARRIER) when it gets the hangup command.
- So the following function should read the OK in both cases.
- Of course, this is somewhat Hayes-specific...
-*/
- if (xx_ok) { /* Look for OK response */
- debug(F100,"mdmhup calling response function","",0);
- x = (*xx_ok)(3,1); /* Give it 3 seconds, be strict. */
- debug(F101,"mdmhup hangup response","",x);
- msleep(500); /* Wait half a sec */
- ttflui(); /* Get rid of NO CARRIER, if any */
- } else { /* No OK function, */
- x = 1; /* so assume it worked */
- debug(F101,"mdmhup no ok_fn","",x);
- }
- parity = xparity; /* Restore prevailing parity */
- return(x); /* Return OK function's return code. */
-
-#else /* MDMHUP not defined. */
-
- debug(F100,"mdmhup MDMHUP not defined","",0);
- return(0); /* Always fail. */
-
-#endif /* MDMHUP */
-}
-
-#endif /* NOICP */
-#else /* NODIAL */
-
-int mdmtyp = 0; /* Default modem type */
-
-int /* To allow NODIAL versions to */
-mdmhup() { /* call mdmhup(), so calls to */
- return(0); /* mdmhup() need not be within */
-} /* #ifndef NODIAL conditionals */
-#endif /* NODIAL */
-#else
-int mdmtyp = 0; /* Default modem type */
-#endif /* NOLOCAL */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckufio.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckufio.c
deleted file mode 100644
index b5bfaae..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckufio.c
+++ /dev/null
@@ -1,8545 +0,0 @@
-/* C K U F I O -- Kermit file system support for UNIX, Aegis, and Plan 9 */
-
-#define CK_NONBLOCK /* See zoutdump() */
-
-#ifdef aegis
-char *ckzv = "Aegis File support, 9.0.216, 20 Aug 2011";
-#else
-#ifdef Plan9
-char *ckzv = "Plan 9 File support, 9.0.216, 20 Aug 2011";
-#else
-char *ckzv = "UNIX File support, 9.0.216, 20 Aug 2011";
-#endif /* Plan9 */
-#endif /* aegis */
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City,
- and others noted in the comments below. Note: CUCCA = Previous name of
- Columbia University Academic Information Systems. Note: AcIS = Previous
- of Columbia University Information Technology.
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- NOTE TO CONTRIBUTORS: This file, and all the other C-Kermit files, must be
- compatible with C preprocessors that support only #ifdef, #else, #endif,
- #define, and #undef. Please do not use #if, logical operators, or other
- preprocessor features in any of the portable C-Kermit modules. You can,
- of course, use these constructions in platform-specific modules where you
- know they are supported.
-*/
-/* Include Files */
-
-#ifdef MINIX2
-#define _MINIX
-#endif /* MINIX2 */
-
-#include "ckcsym.h"
-#include "ckcdeb.h"
-#include "ckcasc.h"
-
-#ifndef NOCSETS
-#include "ckcxla.h"
-#endif /* NOCSETS */
-
-/* To avoid pulling in all of ckuusr.h so we copy the few needed prototypes */
-
-struct mtab { /* Macro table, like keyword table */
- char *kwd; /* But with pointers for vals */
- char *mval; /* instead of ints. */
- short flgs;
-};
-_PROTOTYP( int mlook, (struct mtab [], char *, int) );
-_PROTOTYP( int dodo, (int, char *, int) );
-_PROTOTYP( int parser, ( int ) );
-
-#ifdef COMMENT
-/* This causes trouble in C-Kermit 8.0. I don't remember the original */
-/* reason for this being here but it must have been needed at the time... */
-#ifdef OSF13
-#ifdef CK_ANSIC
-#ifdef _NO_PROTO
-#undef _NO_PROTO
-#endif /* _NO_PROTO */
-#endif /* CK_ANSIC */
-#endif /* OSF13 */
-#endif /* COMMENT */
-
-#ifndef HPUXPRE65
-#include <errno.h> /* Error number symbols */
-#else
-#ifndef ERRNO_INCLUDED
-#include <errno.h> /* Error number symbols */
-#endif /* ERRNO_INCLUDED */
-#endif /* HPUXPRE65 */
-
-#include <signal.h>
-
-#ifdef MINIX2
-#undef MINIX
-#undef CKSYSLOG
-#include <limits.h>
-#include <time.h>
-#define NOFILEH
-#endif /* MINIX2 */
-
-#ifdef MINIX
-#include <limits.h>
-#include <sys/types.h>
-#include <time.h>
-#else
-#ifdef POSIX
-#include <limits.h>
-#else
-#ifdef SVR3
-#include <limits.h>
-#endif /* SVR3 */
-#endif /* POSIX */
-#endif /* MINIX */
-/*
- Directory Separator macros, to allow this module to work with both UNIX and
- OS/2: Because of ambiguity with the command line editor escape \ character,
- the directory separator is currently left as / for OS/2 too, because the
- OS/2 kernel also accepts / as directory separator. But this is subject to
- change in future versions to conform to the normal OS/2 style.
-*/
-#ifndef DIRSEP
-#define DIRSEP '/'
-#endif /* DIRSEP */
-#ifndef ISDIRSEP
-#define ISDIRSEP(c) ((c)=='/')
-#endif /* ISDIRSEP */
-
-#ifdef SDIRENT
-#define DIRENT
-#endif /* SDIRENT */
-
-#ifdef XNDIR
-#include <sys/ndir.h>
-#else /* !XNDIR */
-#ifdef NDIR
-#include <ndir.h>
-#else /* !NDIR, !XNDIR */
-#ifdef RTU
-#include "/usr/lib/ndir.h"
-#else /* !RTU, !NDIR, !XNDIR */
-#ifdef DIRENT
-#ifdef SDIRENT
-#include <sys/dirent.h>
-#else
-#include <dirent.h>
-#endif /* SDIRENT */
-#else
-#include <sys/dir.h>
-#endif /* DIRENT */
-#endif /* RTU */
-#endif /* NDIR */
-#endif /* XNDIR */
-
-#ifdef UNIX /* Pointer arg to wait() allowed */
-#define CK_CHILD /* Assume this is safe in all UNIX */
-#endif /* UNIX */
-
-extern int binary, recursive, stathack;
-#ifdef CK_CTRLZ
-extern int eofmethod;
-#endif /* CK_CTRLZ */
-
-#include <pwd.h> /* Password file for shell name */
-#ifdef CK_SRP
-#include <t_pwd.h> /* SRP Password file */
-#endif /* CK_SRP */
-
-#ifdef HPUX10_TRUSTED
-#include <hpsecurity.h>
-#include <prot.h>
-#endif /* HPUX10_TRUSTED */
-
-#ifdef COMMENT
-/* Moved to ckcdeb.h */
-#ifdef POSIX
-#define UTIMEH
-#else
-#ifdef HPUX9
-#define UTIMEH
-#endif /* HPUX9 */
-#endif /* POSIX */
-#endif /* COMMENT */
-
-#ifdef SYSUTIMEH /* <sys/utime.h> if requested, */
-#include <sys/utime.h> /* for extra fields required by */
-#else /* 88Open spec. */
-#ifdef UTIMEH /* or <utime.h> if requested */
-#include <utime.h> /* (SVR4, POSIX) */
-#ifndef BSD44
-#ifndef V7
-/* Not sure why this is here. What it implies is that the code bracketed
- by SYSUTIMEH is valid on all platforms on which we support time
- functionality. But we know that is not true because the BSD44 and V7
- platforms do not support sys/utime.h and the data structures which
- are defined in them. Now this worked before because prior to today's
- changes the UTIMEH definition for BSD44 and V7 did not take place
- until after SYSUTIMEH was defined. It also would not have been a
- problem if the ordering of all the time blocks was consistent. All but
- one of the blocks were BSD44, V7, SYSUTIMEH, <OTHER>. That one case
- is where this problem was triggered.
-*/
-#define SYSUTIMEH /* Use this for both cases. */
-#endif /* V7 */
-#endif /* BSD44 */
-#endif /* UTIMEH */
-#endif /* SYSUTIMEH */
-
-#ifndef NOTIMESTAMP
-#ifdef POSIX
-#ifndef AS400
-#define TIMESTAMP
-#endif /* AS400 */
-#endif /* POSIX */
-
-#ifdef BSD44 /* BSD 4.4 */
-#ifndef TIMESTAMP
-#define TIMESTAMP /* Can do file dates */
-#endif /* TIMESTAMP */
-#include <sys/time.h>
-#include <sys/timeb.h>
-
-#else /* Not BSD44 */
-
-#ifdef BSD4 /* BSD 4.3 and below */
-#define TIMESTAMP /* Can do file dates */
-#include <time.h> /* Need this */
-#include <sys/timeb.h> /* Need this if really BSD */
-
-#else /* Not BSD 4.3 and below */
-
-#ifdef SVORPOSIX /* System V or POSIX */
-#ifndef TIMESTAMP
-#define TIMESTAMP
-#endif /* TIMESTAMP */
-#include <time.h>
-
-/* void tzset(); (the "void" type upsets some compilers) */
-#ifndef IRIX60
-#ifndef ultrix
-#ifndef CONVEX9
-/* ConvexOS 9.0, supposedly POSIX, has extern char *timezone(int,int) */
-#ifndef Plan9
-extern long timezone;
-#endif /* Plan9 */
-#endif /* CONVEX9 */
-#endif /* ultrix */
-#endif /* IRIX60 */
-#endif /* SVORPOSIX */
-#endif /* BSD4 */
-#endif /* BSD44 */
-
-#ifdef COHERENT
-#include <time.h>
-#endif /* COHERENT */
-
-/* Is `y' a leap year? */
-#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
-
-/* Number of leap years from 1970 to `y' (not including `y' itself). */
-#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)
-
-#endif /* NOTIMESTAMP */
-
-#ifdef CIE
-#include <stat.h> /* File status */
-#else
-#include <sys/stat.h>
-#endif /* CIE */
-
-
-
-/* Macro to alleviate isdir() calls internal to this module */
-
-static struct stat STATBUF;
-#define xisdir(a) ((stat(a,&STATBUF)==-1)?0:(S_ISDIR(STATBUF.st_mode)?1:0))
-
-extern char uidbuf[];
-extern int xferlog;
-extern char * xferfile;
-int iklogopen = 0;
-static time_t timenow;
-
-#define IKSDMSGLEN CKMAXPATH+512
-
-static char iksdmsg[IKSDMSGLEN];
-
-extern int local;
-
-extern int server, en_mkd, en_cwd, en_del;
-
-/*
- Functions (n is one of the predefined file numbers from ckcker.h):
-
- zopeni(n,name) -- Opens an existing file for input.
- zopeno(n,name,attr,fcb) -- Opens a new file for output.
- zclose(n) -- Closes a file.
- zchin(n,&c) -- Gets the next character from an input file.
- zsinl(n,&s,x) -- Read a line from file n, max len x, into address s.
- zsout(n,s) -- Write a null-terminated string to output file, buffered.
- zsoutl(n,s) -- Like zsout, but appends a line terminator.
- zsoutx(n,s,x) -- Write x characters to output file, unbuffered.
- zchout(n,c) -- Add a character to an output file, unbuffered.
- zchki(name) -- Check if named file exists and is readable, return size.
- zchko(name) -- Check if named file can be created.
- zchkspa(name,n) -- Check if n bytes available to create new file, name.
- znewn(name,s) -- Make a new unique file name based on the given name.
- zdelet(name) -- Delete the named file.
- zxpand(string) -- Expands the given wildcard string into a list of files.
- znext(string) -- Returns the next file from the list in "string".
- zxrewind() -- Rewind zxpand list.
- zxcmd(n,cmd) -- Execute the command in a lower fork on file number n.
- zclosf() -- Close input file associated with zxcmd()'s lower fork.
- zrtol(n1,n2) -- Convert remote filename into local form.
- zltor(n1,n2) -- Convert local filename into remote form.
- zchdir(dirnam) -- Change working directory.
- zhome() -- Return pointer to home directory name string.
- zkself() -- Kill self, log out own job.
- zsattr(struct zattr *) -- Return attributes for file which is being sent.
- zstime(f, struct zattr *, x) - Set file creation date from attribute packet.
- zrename(old, new) -- Rename a file.
- zcopy(source,destination) -- Copy a file.
- zmkdir(path) -- Create the directory path if possible
- zfnqfp(fname,len,fullpath) - Determine full path for file name.
- zgetfs(name) -- return file size regardless of accessibility
- zchkpid(pid) -- tell if PID is valid and active
-*/
-
-/* Kermit-specific includes */
-/*
- Definitions here supersede those from system include files.
- ckcdeb.h is included above.
-*/
-#include "ckcker.h" /* Kermit definitions */
-#include "ckucmd.h" /* For keyword tables */
-#include "ckuver.h" /* Version herald */
-
-char *ckzsys = HERALD;
-
-/*
- File access checking ... There are two calls to access() in this module.
- If this program is installed setuid or setgid on a Berkeley-based UNIX
- system that does NOT incorporate the saved-original-effective-uid/gid
- feature, then, when we have swapped the effective and original uid/gid,
- access() fails because it uses what it thinks are the REAL ids, but we have
- swapped them. This occurs on systems where ANYBSD is defined, NOSETREU
- is NOT defined, and SAVEDUID is NOT defined. So, in theory, we should take
- care of this situation like so:
-
- ifdef ANYBSD
- ifndef NOSETREU
- ifndef SAVEDUID
- define SW_ACC_ID
- endif
- endif
- endif
-
- But we can't test such a general scheme everywhere, so let's only do this
- when we know we have to...
-*/
-#ifdef NEXT /* NeXTSTEP 1.0-3.0 */
-#define SW_ACC_ID
-#endif /* NEXT */
-
-/* Support for tilde-expansion in file and directory names */
-
-#ifdef POSIX
-#define NAMEENV "LOGNAME"
-#else
-#ifdef BSD4
-#define NAMEENV "USER"
-#else
-#ifdef ATTSV
-#define NAMEENV "LOGNAME"
-#endif /* ATTSV */
-#endif /* BSD4 */
-#endif /* POSIX */
-
-/* Berkeley Unix Version 4.x */
-/* 4.1bsd support from Charles E Brooks, EDN-VAX */
-
-#ifdef BSD4
-#ifdef MAXNAMLEN
-#define BSD42
-#endif /* MAXNAMLEN */
-#endif /* BSD4 */
-
-/* Definitions of some system commands */
-
-char *DELCMD = "rm -f "; /* For file deletion */
-char *CPYCMD = "cp "; /* For file copy */
-char *RENCMD = "mv "; /* For file rename */
-char *PWDCMD = "pwd "; /* For saying where I am */
-
-#ifdef COMMENT
-#ifdef HPUX10
-char *DIRCMD = "/usr/bin/ls -l "; /* For directory listing */
-char *DIRCM2 = "/usr/bin/ls -l "; /* For directory listing, no args */
-#else
-char *DIRCMD = "/bin/ls -l "; /* For directory listing */
-char *DIRCM2 = "/bin/ls -l "; /* For directory listing, no args */
-#endif /* HPUX10 */
-#else
-char *DIRCMD = "ls -l "; /* For directory listing */
-char *DIRCM2 = "ls -l "; /* For directory listing, no args */
-#endif /* COMMENT */
-
-char *TYPCMD = "cat "; /* For typing a file */
-
-#ifdef HPUX
-char *MAILCMD = "mailx"; /* For sending mail */
-#else
-#ifdef DGUX540
-char *MAILCMD = "mailx";
-#else
-#ifdef UNIX
-#ifdef CK_MAILCMD
-char *MAILCMD = CK_MAILCMD; /* CFLAGS override */
-#else
-char *MAILCMD = "Mail"; /* Default */
-#endif /* CK_MAILCMD */
-#else
-char *MAILCMD = "";
-#endif /* UNIX */
-#endif /* HPUX */
-#endif /* DGUX40 */
-
-#ifdef UNIX
-#ifdef ANYBSD /* BSD uses lpr to spool */
-#ifdef DGUX540 /* And DG/UX */
-char * PRINTCMD = "lp";
-#else
-char * PRINTCMD = "lpr";
-#endif /* DGUX540 */
-#else /* Sys V uses lp */
-#ifdef TRS16 /* except for Tandy-16/6000... */
-char * PRINTCMD = "lpr";
-#else
-char * PRINTCMD = "lp";
-#endif /* TRS16 */
-#endif /* ANYBSD */
-#else /* Not UNIX */
-#define PRINTCMD ""
-#endif /* UNIX */
-
-#ifdef FT18 /* Fortune For:Pro 1.8 */
-#undef BSD4
-#endif /* FT18 */
-
-#ifdef BSD4
-char *SPACMD = "pwd ; df ."; /* Space in current directory */
-#else
-#ifdef FT18
-char *SPACMD = "pwd ; du ; df .";
-#else
-char *SPACMD = "df ";
-#endif /* FT18 */
-#endif /* BSD4 */
-
-char *SPACM2 = "df "; /* For space in specified directory */
-
-#ifdef FT18
-#define BSD4
-#endif /* FT18 */
-
-#ifdef BSD4
-char *WHOCMD = "finger ";
-#else
-char *WHOCMD = "who ";
-#endif /* BSD4 */
-
-/* More system-dependent includes, which depend on symbols defined */
-/* in the Kermit-specific includes. Oh what a tangled web we weave... */
-
-#ifdef COHERENT /* <sys/file.h> */
-#define NOFILEH
-#endif /* COHERENT */
-
-#ifdef MINIX
-#define NOFILEH
-#endif /* MINIX */
-
-#ifdef aegis
-#define NOFILEH
-#endif /* aegis */
-
-#ifdef unos
-#define NOFILEH
-#endif /* unos */
-
-#ifndef NOFILEH
-#include <sys/file.h>
-#endif /* NOFILEH */
-
-#ifndef is68k /* Whether to include <fcntl.h> */
-#ifndef BSD41 /* All but a couple UNIXes have it. */
-#ifndef FT18
-#ifndef COHERENT
-#include <fcntl.h>
-#endif /* COHERENT */
-#endif /* FT18 */
-#endif /* BSD41 */
-#endif /* is68k */
-
-#ifdef COHERENT
-#ifdef _I386
-#include <fcntl.h>
-#else
-#include <sys/fcntl.h>
-#endif /* _I386 */
-#endif /* COHERENT */
-
-extern int inserver; /* I am IKSD */
-int guest = 0; /* Anonymous user */
-
-#ifdef IKSD
-extern int isguest;
-extern char * anonroot;
-#endif /* IKSD */
-
-#ifdef CK_LOGIN
-#define GUESTPASS 256
-static char guestpass[GUESTPASS] = { NUL, NUL }; /* Anonymous "password" */
-static int logged_in = 0; /* Set when user is logged in */
-static int askpasswd = 0; /* Have OK user, must ask for passwd */
-#ifdef CK_PAM
-extern int gotemptypasswd;
-#endif /* CK_PAM */
-#endif /* CK_LOGIN */
-
-#ifdef CKROOT
-static char ckroot[CKMAXPATH+1] = { NUL, NUL };
-static int ckrootset = 0;
-int ckrooterr = 0;
-#endif /* CKROOT */
-
-_PROTOTYP( VOID ignorsigs, (void) );
-_PROTOTYP( VOID restorsigs, (void) );
-#ifdef SELECT
-_PROTOTYP( int ttwait, (int, int) ); /* ckutio.c */
-#endif /* SELECT */
-
-/*
- Change argument to "(const char *)" if this causes trouble.
- Or... if it causes trouble, then maybe it was already declared
- in a header file after all, so you can remove this prototype.
-*/
-#ifndef NDGPWNAM /* If not defined No Declare getpwnam... */
-#ifndef _POSIX_SOURCE
-#ifndef NEXT
-#ifndef SVR4
-/* POSIX <pwd.h> already gave prototypes for these. */
-#ifdef IRIX40
-_PROTOTYP( struct passwd * getpwnam, (const char *) );
-#else
-#ifdef IRIX51
-_PROTOTYP( struct passwd * getpwnam, (const char *) );
-#else
-#ifdef M_UNIX
-_PROTOTYP( struct passwd * getpwnam, (const char *) );
-#else
-#ifdef HPUX9
-_PROTOTYP( struct passwd * getpwnam, (const char *) );
-#else
-#ifdef HPUX10
-_PROTOTYP( struct passwd * getpwnam, (const char *) );
-#else
-#ifdef DCGPWNAM
-_PROTOTYP( struct passwd * getpwnam, (const char *) );
-#else
-_PROTOTYP( struct passwd * getpwnam, (char *) );
-#endif /* DCGPWNAM */
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* M_UNIX */
-#endif /* IRIX51 */
-#endif /* IRIX40 */
-#ifndef SUNOS4
-#ifndef HPUX9
-#ifndef HPUX10
-#ifndef _SCO_DS
-_PROTOTYP( struct passwd * getpwuid, (PWID_T) );
-#endif /* _SCO_DS */
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* SUNOS4 */
-_PROTOTYP( struct passwd * getpwent, (void) );
-#endif /* SVR4 */
-#endif /* NEXT */
-#endif /* _POSIX_SOURCE */
-#endif /* NDGPWNAM */
-
-#ifdef CK_SHADOW /* Shadow Passwords... */
-#include <shadow.h>
-#endif /* CK_SHADOW */
-#ifdef CK_PAM /* PAM... */
-#ifdef MACOSX
-#include <pam/pam_appl.h>
-#else /* MACOSX */
-#include <security/pam_appl.h>
-#endif /* MACOSX */
-#ifndef PAM_SERVICE_TYPE /* Defines which PAM service we are */
-#define PAM_SERVICE_TYPE "kermit"
-#endif /* PAM_SERVICE_TYPE */
-
-#ifdef SOLARIS
-#define PAM_CONST
-#else /* SOLARIS */
-#define PAM_CONST CONST
-#endif
-
-static char * pam_pw = NULL;
-
-int
-#ifdef CK_ANSIC
-pam_cb(int num_msg,
- PAM_CONST struct pam_message **msg,
- struct pam_response **resp,
- void *appdata_ptr
- )
-#else /* CK_ANSIC */
-pam_cb(num_msg, msg, resp, appdata_ptr)
- int num_msg;
- PAM_CONST struct pam_message **msg;
- struct pam_response **resp;
- void *appdata_ptr;
-#endif /* CK_ANSIC */
-{
- int i;
-
- debug(F111,"pam_cb","num_msg",num_msg);
-
- for (i = 0; i < num_msg; i++) {
- char message[PAM_MAX_MSG_SIZE];
-
- /* Issue prompt and get response */
- debug(F111,"pam_cb","Message",i);
- debug(F111,"pam_cb",msg[i]->msg,msg[i]->msg_style);
- if (msg[i]->msg_style == PAM_ERROR_MSG) {
- debug(F111,"pam_cb","PAM ERROR",0);
- fprintf(stdout,"%s\n", msg[i]->msg);
- return(0);
- } else if (msg[i]->msg_style == PAM_TEXT_INFO) {
- debug(F111,"pam_cb","PAM TEXT INFO",0);
- fprintf(stdout,"%s\n", msg[i]->msg);
- return(0);
- } else if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) {
- debug(F111,"pam_cb","Reading response, no echo",0);
- /* Ugly hack. We check to see if a password has been pushed */
- /* into zvpasswd(). This would be true if the password was */
- /* received by REMOTE LOGIN. */
- if (pam_pw) {
- ckstrncpy(message,pam_pw,PAM_MAX_MSG_SIZE);
- } else
- readpass((char *)msg[i]->msg,message,PAM_MAX_MSG_SIZE);
- } else if (msg[i]->msg_style == PAM_PROMPT_ECHO_ON) {
- debug(F111,"pam_cb","Reading response, with echo",0);
- readtext((char *)msg[i]->msg,message,PAM_MAX_MSG_SIZE);
- } else {
- debug(F111,"pam_cb","unknown style",0);
- return(0);
- }
-
- /* Allocate space for this message's response structure */
- resp[i] = (struct pam_response *) malloc(sizeof (struct pam_response));
- if (!resp[i]) {
- int j;
- debug(F110,"pam_cb","malloc failure",0);
- for (j = 0; j < i; j++) {
- free(resp[j]->resp);
- free(resp[j]);
- }
- return(0);
- }
-
- /* Allocate a buffer for the response */
- resp[i]->resp = (char *) malloc((int)strlen(message) + 1);
- if (!resp[i]->resp) {
- int j;
- debug(F110,"pam_cb","malloc failure",0);
- for (j = 0; j < i; j++) {
- free(resp[j]->resp);
- free(resp[j]);
- }
- free(resp[i]);
- return(0);
- }
- /* Return the results back to PAM */
- strcpy(resp[i]->resp, message); /* safe (prechecked) */
- resp[i]->resp_retcode = 0;
- }
- debug(F110,"pam_cb","Exiting",0);
- return(0);
-}
-#endif /* CK_PAM */
-
-/* Define macros for getting file type */
-
-#ifdef OXOS
-/*
- Olivetti X/OS 2.3 has S_ISREG and S_ISDIR defined
- incorrectly, so we force their redefinition.
-*/
-#undef S_ISREG
-#undef S_ISDIR
-#endif /* OXOS */
-
-#ifdef UTSV /* Same deal for Amdahl UTSV */
-#undef S_ISREG
-#undef S_ISDIR
-#endif /* UTSV */
-
-#ifdef UNISYS52 /* And for UNISYS UTS V 5.2 */
-#undef S_ISREG
-#undef S_ISDIR
-#endif /* UNISYS52 */
-
-#ifdef ICLSVR3 /* And for old ICL versions */
-#undef S_ISREG
-#undef S_ISDIR
-#endif /* ICLSVR3 */
-
-#ifdef ISDIRBUG /* Also allow this from command line */
-#ifdef S_ISREG
-#undef S_ISREG
-#endif /* S_ISREG */
-#ifdef S_ISDIR
-#undef S_ISDIR
-#endif /* S_ISDIR */
-#endif /* ISDIRBUG */
-
-#ifndef _IFMT
-#ifdef S_IFMT
-#define _IFMT S_IFMT
-#else
-#define _IFMT 0170000
-#endif /* S_IFMT */
-#endif /* _IFMT */
-
-#ifndef S_ISREG
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif /* S_ISREG */
-#ifndef S_ISDIR
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif /* S_ISDIR */
-
-/* The following mainly for NeXTSTEP... */
-
-#ifndef S_IWUSR
-#define S_IWUSR 0000200
-#endif /* S_IWUSR */
-
-#ifndef S_IRGRP
-#define S_IRGRP 0000040
-#endif /* S_IRGRP */
-
-#ifndef S_IWGRP
-#define S_IWGRP 0000020
-#endif /* S_IWGRP */
-
-#ifndef S_IXGRP
-#define S_IXGRP 0000010
-#endif /* S_IXGRP */
-
-#ifndef S_IROTH
-#define S_IROTH 0000004
-#endif /* S_IROTH */
-
-#ifndef S_IWOTH
-#define S_IWOTH 0000002
-#endif /* S_IWOTH */
-
-#ifndef S_IXOTH
-#define S_IXOTH 0000001
-#endif /* S_IXOTH */
-/*
- Define maximum length for a file name if not already defined.
- NOTE: This applies to a path segment (directory or file name),
- not the entire path string, which can be CKMAXPATH bytes long.
-*/
-#ifdef QNX
-#ifdef _MAX_FNAME
-#define MAXNAMLEN _MAX_FNAME
-#else
-#define MAXNAMLEN 48
-#endif /* _MAX_FNAME */
-#else
-#ifndef MAXNAMLEN
-#ifdef sun
-#define MAXNAMLEN 255
-#else
-#ifdef FILENAME_MAX
-#define MAXNAMLEN FILENAME_MAX
-#else
-#ifdef NAME_MAX
-#define MAXNAMLEN NAME_MAX
-#else
-#ifdef _POSIX_NAME_MAX
-#define MAXNAMLEN _POSIX_NAME_MAX
-#else
-#ifdef _D_NAME_MAX
-#define MAXNAMLEN _D_NAME_MAX
-#else
-#ifdef DIRSIZ
-#define MAXNAMLEN DIRSIZ
-#else
-#define MAXNAMLEN 14
-#endif /* DIRSIZ */
-#endif /* _D_NAME_MAX */
-#endif /* _POSIX_NAME_MAX */
-#endif /* NAME_MAX */
-#endif /* FILENAME_MAX */
-#endif /* sun */
-#endif /* MAXNAMLEN */
-#endif /* QNX */
-
-#ifdef COMMENT
-/* As of 2001-11-03 this is handled in ckcdeb.h */
-/* Longest pathname ... */
-/*
- Beware: MAXPATHLEN is one of UNIX's dirty little secrets. Where is it
- defined? Who knows... <param.h>, <mod.h>, <unistd.h>, <limits.h>, ...
- There is not necessarily even a definition for it anywhere, or it might have
- another name. If you get it wrong, bad things happen with getcwd() and/or
- getwd(). If you allocate a buffer that is too short, getwd() might write
- over memory and getcwd() will fail with ERANGE. The definitions of these
- functions (e.g. in SVID or POSIX.1) do not tell you how to determine the
- maximum path length in order to allocate a buffer that is the right size.
-*/
-#ifdef BSD44
-#include <sys/param.h> /* For MAXPATHLEN */
-#endif /* BSD44 */
-#ifdef COHERENT
-#include <sys/param.h> /* for MAXPATHLEN, needed for -DDIRENT */
-#endif /* COHERENT */
-#endif /* COMMENT */
-
-#ifdef MAXPATHLEN
-#ifdef MAXPATH
-#undef MAXPATH
-#endif /* MAXPATH */
-#define MAXPATH MAXPATHLEN
-#else
-#ifdef PATH_MAX
-#define MAXPATH PATH_MAX
-#else
-#ifdef _POSIX_PATH_MAX
-#define MAXPATH _POSIX_PATH_MAX
-#else
-#ifdef BSD42
-#define MAXPATH 1024
-#else
-#ifdef SVR4
-#define MAXPATH 1024
-#else
-#define MAXPATH 255
-#endif /* SVR4 */
-#endif /* BSD42 */
-#endif /* _POSIX_PATH_MAX */
-#endif /* PATH_MAX */
-#endif /* MAXPATHLEN */
-
-/* Maximum number of filenames for wildcard expansion */
-
-#ifndef MAXWLD
-/* Already defined in ckcdeb.h so the following is superfluous. */
-/* Don't expect changing them to have any effect. */
-#ifdef CK_SMALL
-#define MAXWLD 50
-#else
-#ifdef BIGBUFOK
-#define MAXWLD 102400
-#else
-#define MAXWLD 8192
-#endif /* BIGBUFOK */
-#endif /* CK_SMALL */
-#endif /* MAXWLD */
-
-static int maxnames = MAXWLD;
-
-/* Define the size of the string space for filename expansion. */
-
-#ifndef DYNAMIC
-#ifdef PROVX1
-#define SSPACE 500
-#else
-#ifdef BSD29
-#define SSPACE 500
-#else
-#ifdef pdp11
-#define SSPACE 500
-#else
-#ifdef aegis
-#define SSPACE 10000 /* Size of string-generating buffer */
-#else /* Default static buffer size */
-#ifdef BIGBUFOK
-#define SSPACE 65000 /* Size of string-generating buffer */
-#else
-#define SSPACE 2000 /* size of string-generating buffer */
-#endif /* BIGBUFOK */
-#endif /* aegis */
-#endif /* pdp11 */
-#endif /* BSD29 */
-#endif /* PROVX1 */
-static char sspace[SSPACE]; /* Buffer for generating filenames */
-#else /* is DYNAMIC */
-#ifdef CK_64BIT
-#define SSPACE 2000000000 /* Two billion bytes */
-#else
-#ifdef BIGBUFOK
-#define SSPACE 10000000 /* Ten million */
-#else
-#define SSPACE 10000 /* Ten thousand */
-#endif /* BIGBUFOK */
-#endif /* CK_64BIT */
-char *sspace = (char *)0;
-#endif /* DYNAMIC */
-static int ssplen = SSPACE; /* Length of string space buffer */
-
-#ifdef DCLFDOPEN
-/* fdopen() needs declaring because it's not declared in <stdio.h> */
-_PROTOTYP( FILE * fdopen, (int, char *) );
-#endif /* DCLFDOPEN */
-
-#ifdef DCLPOPEN
-/* popen() needs declaring because it's not declared in <stdio.h> */
-_PROTOTYP( FILE * popen, (char *, char *) );
-#endif /* DCLPOPEN */
-
-extern int nopush;
-
-/* More internal function prototypes */
-/*
- * The path structure is used to represent the name to match.
- * Each slash-separated segment of the name is kept in one
- * such structure, and they are linked together, to make
- * traversing the name easier.
- */
-struct path {
- char npart[MAXNAMLEN+4]; /* name part of path segment */
- struct path *fwd; /* forward ptr */
-};
-#ifndef NOPUSH
-_PROTOTYP( int shxpand, (char *, char *[], int ) );
-#endif /* NOPUSH */
-_PROTOTYP( static int fgen, (char *, char *[], int ) );
-_PROTOTYP( static VOID traverse, (struct path *, char *, char *) );
-_PROTOTYP( static VOID addresult, (char *, int) );
-#ifdef COMMENT
-/* Replaced by ckmatch() */
-_PROTOTYP( static int match, (char *, char *) );
-#endif /* COMMENT */
-_PROTOTYP( char * whoami, (void) );
-_PROTOTYP( UID_T real_uid, (void) );
-_PROTOTYP( static struct path *splitpath, (char *p) );
-_PROTOTYP( char * zdtstr, (time_t) );
-_PROTOTYP( time_t zstrdt, (char *, int) );
-
-/* Some systems define these symbols in include files, others don't... */
-
-#ifndef R_OK
-#define R_OK 4 /* For access */
-#endif /* R_OK */
-
-#ifndef W_OK
-#define W_OK 2
-#endif /* W_OK */
-
-#ifndef X_OK
-#define X_OK 1
-#endif /* X_OK */
-
-#ifndef O_RDONLY
-#define O_RDONLY 000
-#endif /* O_RDONLY */
-
-/* syslog and wtmp items for Internet Kermit Service */
-
-extern char * clienthost; /* From ckcmai.c. */
-
-static char fullname[CKMAXPATH+1];
-static char tmp2[CKMAXPATH+1];
-
-extern int ckxlogging;
-
-#ifdef CKXPRINTF /* Our printf macro conflicts with */
-#undef printf /* use of "printf" in syslog.h */
-#endif /* CKXPRINTF */
-#ifdef CKSYSLOG
-#ifdef RTAIX
-#include <sys/syslog.h>
-#else /* RTAIX */
-#include <syslog.h>
-#endif /* RTAIX */
-#endif /* CKSYSLOG */
-#ifdef CKXPRINTF
-#define printf ckxprintf
-#endif /* CKXPRINTF */
-
-int ckxanon = 1; /* Anonymous login ok */
-int ckxperms = 0040; /* Anonymous file permissions */
-int ckxpriv = 1; /* Priv'd login ok */
-
-#ifndef XFERFILE
-#define XFERFILE "/var/log/iksd.log"
-#endif /* XFERFILE */
-
-/* wtmp logging for IKSD... */
-
-#ifndef CKWTMP /* wtmp logging not selected */
-int ckxwtmp = 0; /* Know this at runtime */
-#else /* wtmp file details */
-int ckxwtmp = 1;
-#ifdef UTMPBUG /* Unfortunately... */
-/*
- Some versions of Linux have a <utmp.h> file that contains
- "enum utlogin { local, telnet, rlogin, screen, ... };" This clobbers
- any program that uses any of these words as variable names, function
- names, macro names, etc. (Other versions of Linux have this declaration
- within #if 0 ... #endif.) There is nothing we can do about this other
- than to not include the stupid file. But we need stuff from it, so...
-*/
-#include <features.h>
-#include <sys/types.h>
-#define UT_LINESIZE 32
-#define UT_NAMESIZE 32
-#define UT_HOSTSIZE 256
-
-struct timeval {
- time_t tv_sec;
- time_t tv_usec;
-};
-
-struct exit_status {
- short int e_termination; /* Process termination status. */
- short int e_exit; /* Process exit status. */
-};
-
-struct utmp {
- short int ut_type; /* Type of login */
- pid_t ut_pid; /* Pid of login process */
- char ut_line[UT_LINESIZE]; /* NUL-terminated devicename of tty */
- char ut_id[4]; /* Inittab id */
- char ut_user[UT_NAMESIZE]; /* Username (not NUL terminated) */
-
- char ut_host[UT_HOSTSIZE]; /* Hostname for remote login */
- struct exit_status ut_exit; /* Exit status */
- long ut_session; /* Session ID, used for windowing */
- struct timeval ut_tv; /* Time entry was made */
- int32_t ut_addr_v6[4]; /* Internet address of remote host */
- char pad[20]; /* Reserved */
-};
-
-#define ut_time ut_tv.tv_sec /* Why should Linux be like anything else? */
-#define ut_name ut_user /* ... */
-
-extern void
-logwtmp __P ((__const char *__ut_line, __const char *__ut_name,
- __const char *__ut_host));
-
-#else /* Not UTMPBUG */
-
-#ifndef HAVEUTMPX /* Who has <utmpx.h> */
-#ifdef SOLARIS
-#define HAVEUTMPX
-#else
-#ifdef IRIX60
-#define HAVEUTMPX
-#else
-#ifdef CK_SCOV5
-#define HAVEUTMPX
-#else
-#ifdef HPUX100
-#define HAVEUTMPX
-#else
-#ifdef UNIXWARE
-#define HAVEUTMPX
-#endif /* UNIXWARE */
-#endif /* HPUX100 */
-#endif /* CK_SCOV5 */
-#endif /* IRIX60 */
-#endif /* SOLARIS */
-#endif /* HAVEUTMPX */
-
-#ifdef HAVEUTMPX
-#include <utmpx.h>
-#else
-#ifdef OSF50
-/* Because the time_t in the utmp struct is 64 bits but time() wants 32 */
-#define __V40_OBJ_COMPAT 1
-#endif /* OSF50 */
-#include <utmp.h>
-#ifdef OSF50
-#undef __V40_OBJ_COMPAT
-#endif /* OSF50 */
-#endif /* HAVEUTMPX */
-#endif /* UTMPBUG */
-
-#ifdef HAVEUTMPX
-#define UTMPSTRUCT utmpx
-#else
-#define UTMPSTRUCT utmp
-#endif /* HAVEUTMPX */
-
-#ifndef WTMPFILE
-#ifdef QNX
-#define WTMPFILE "/usr/adm/wtmp.1"
-#else
-#ifdef LINUX
-#define WTMPFILE "/var/log/wtmp"
-#else
-#define WTMPFILE "/usr/adm/wtmp"
-#endif /* QNX */
-#endif /* LINUX */
-#endif /* WTMPFILE */
-char * wtmpfile = NULL;
-
-static int wtmpfd = 0;
-static char cksysline[32] = { NUL, NUL };
-
-#ifndef HAVEUTHOST /* Does utmp include ut_host[]? */
-#ifdef HAVEUTMPX /* utmpx always does */
-#define HAVEUTHOST
-#else
-#ifdef LINUX /* Linux does */
-#define HAVEUTHOST
-#else
-#ifdef SUNOS4 /* SunOS does */
-#define HAVEUTHOST
-#else
-#ifdef AIX41 /* AIX 4.1 and later do */
-#define HAVEUTHOST
-#endif /* AIX41 */
-#endif /* SUNOS4 */
-#endif /* LINUX */
-#endif /* HAVEUTMPX */
-#endif /* HAVEUTHOST */
-
-#ifdef UW200
-PID_T _vfork() { /* To satisfy a library foulup */
- return(fork()); /* in Unixware 2.0.x */
-}
-#endif /* UW200 */
-
-VOID
-#ifdef CK_ANSIC
-logwtmp(const char * line, const char * name, const char * host)
-#else
-logwtmp(line, name, host) char *line, *name, *host;
-#endif /* CK_ANSIC */
-/* logwtmp */ {
- struct UTMPSTRUCT ut;
- struct stat buf;
- /* time_t time(); */
-
- if (!ckxwtmp)
- return;
-
- if (!wtmpfile)
- makestr(&wtmpfile,WTMPFILE);
-
- if (!line) line = "";
- if (!name) name = "";
- if (!host) host = "";
-
- if (!wtmpfd && (wtmpfd = open(wtmpfile, O_WRONLY|O_APPEND, 0)) < 0) {
- ckxwtmp = 0;
- debug(F110,"WTMP open failed",line,0);
- return;
- }
- if (!fstat(wtmpfd, &buf)) {
- ckstrncpy(ut.ut_line, line, sizeof(ut.ut_line));
-#ifdef FREEBSD9
- ckstrncpy(ut.ut_user, name, sizeof(ut.ut_user));
-#else
- ckstrncpy(ut.ut_name, name, sizeof(ut.ut_name));
-#endif /* FREEBSD9 */
-#ifdef HAVEUTHOST
- /* Not portable */
- ckstrncpy(ut.ut_host, host, sizeof(ut.ut_host));
-#endif /* HAVEUTHOST */
-#ifdef HAVEUTMPX
- time(&ut.ut_tv.tv_sec);
-#else
-#ifdef LINUX
-/* In light of the following comment perhaps the previous line should */
-/* be "#ifndef COMMENT". */
- {
- /*
- * On 64-bit platforms sizeof(time_t) and sizeof(ut.ut_time)
- * are not the same and attempt to use an address of
- * ut.ut_time as an argument to time() call may cause
- * "unaligned access" trap.
- */
- time_t zz;
- time(&zz);
- ut.ut_time = zz;
- }
-#else
-#ifdef CK_64BIT
- {
- /* Now (Jan 2006) we can do this for any 64-bit build */
- time_t zz;
- time(&zz);
- ut.ut_time = zz;
- }
-#else
- time(&ut.ut_time);
-#endif /* CK_64BIT */
-#endif /* LINUX */
-#endif /* HAVEUTMPX */
- if (write(wtmpfd, (char *)&ut, sizeof(struct UTMPSTRUCT)) !=
- sizeof(struct UTMPSTRUCT)) {
-#ifndef NOFTRUNCATE
-#ifndef COHERENT
- ftruncate(wtmpfd, buf.st_size); /* Error, undo any partial write */
-#else
- chsize(wtmpfd, buf.st_size); /* Error, undo any partial write */
-#endif /* COHERENT */
-#endif /* NOFTRUNCATE */
- debug(F110,"WTMP write error",line,0);
- } else {
- debug(F110,"WTMP record OK",line,0);
- return;
- }
- }
-}
-#endif /* CKWTMP */
-
-#ifdef CKSYSLOG
-/*
- C K S Y S L O G -- C-Kermit system logging function,
-
- For use by other modules.
- This module can, but doesn't have to, use it.
- Call with:
- n = SYSLG_xx values defined in ckcdeb.h
- s1, s2, s3: strings.
-*/
-VOID
-cksyslog(n, m, s1, s2, s3) int n, m; char * s1, * s2, * s3; {
- int level;
-
- if (!ckxlogging) /* syslogging */
- return;
- if (!s1) s1 = ""; /* Fix null args */
- if (!s2) s2 = "";
- if (!s3) s3 = "";
- switch (n) { /* Translate Kermit level */
- case SYSLG_DB: /* to syslog level */
- level = LOG_DEBUG;
- break;
- default:
- level = m ? LOG_INFO : LOG_ERR;
- }
- debug(F110,"cksyslog s1",s1,0);
- debug(F110,"cksyslog s2",s2,0);
- debug(F110,"cksyslog s3",s3,0);
- errno = 0;
- syslog(level, "%s: %s %s", s1, s2, s3); /* Write syslog record */
- debug(F101,"cksyslog errno","",errno);
-}
-#endif /* CKSYSLOG */
-
-
-/* Declarations */
-
-int maxnam = MAXNAMLEN; /* Available to the outside */
-int maxpath = MAXPATH;
-int ck_znewn = -1;
-
-#ifdef UNIX
-char startupdir[MAXPATH+1];
-#endif /* UNIX */
-
-int pexitstat = -2; /* Process exit status */
-
-FILE *fp[ZNFILS] = { /* File pointers */
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-
-/* Flags for each file indicating whether it was opened with popen() */
-int ispipe[ZNFILS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-/* Buffers and pointers used in buffered file input and output. */
-#ifdef DYNAMIC
-extern char *zinbuffer, *zoutbuffer;
-#else
-extern char zinbuffer[], zoutbuffer[];
-#endif /* DYNAMIC */
-extern char *zinptr, *zoutptr;
-extern int zincnt, zoutcnt;
-extern int wildxpand, wildena; /* Wildcard handling */
-
-static CK_OFF_T iflen = (CK_OFF_T)-1; /* Input file length */
-
-static PID_T pid = 0; /* pid of child fork */
-static int fcount = 0; /* Number of files in wild group */
-static int nxpand = 0; /* Copy of fcount */
-static char nambuf[CKMAXPATH+4]; /* Buffer for a pathname */
-
-#ifndef NOFRILLS
-#define ZMBUFLEN 200
-static char zmbuf[ZMBUFLEN]; /* For mail, remote print strings */
-#endif /* NOFRILLS */
-
-char **mtchs = NULL; /* Matches found for filename */
-char **mtchptr = NULL; /* Pointer to current match */
-
-/* Z K S E L F -- Kill Self: log out own job, if possible. */
-
-/* Note, should get current pid, but if your system doesn't have */
-/* getppid(), then just kill(0,9)... */
-
-#ifndef SVR3
-#ifndef POSIX
-#ifndef OSFPC
-/* Already declared in unistd.h for SVR3 and POSIX */
-#ifdef CK_ANSIC
-extern PID_T getppid(void);
-#else
-#ifndef PS2AIX10
-#ifndef COHERENT
-extern PID_T getppid();
-#endif /* COHERENT */
-#endif /* PS2AIX10 */
-#endif /* CK_ANSIC */
-#endif /* OSFPC */
-#endif /* POSIX */
-#endif /* SVR3 */
-
-int
-zkself() { /* For "bye", but no guarantee! */
-#ifdef PROVX1
- return(kill(0,9));
-#else
-#ifdef V7
- return(kill(0,9));
-#else
-#ifdef TOWER1
- return(kill(0,9));
-#else
-#ifdef FT18
- return(kill(0,9));
-#else
-#ifdef aegis
- return(kill(0,9));
-#else
-#ifdef COHERENT
- return(kill((PID_T)getpid(),1));
-#else
-#ifdef PID_T
- exit(kill((PID_T)getppid(),1));
- return(0);
-#else
- exit(kill(getppid(),1));
- return(0);
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-}
-
-static VOID
-getfullname(name) char * name; {
- char *p = (char *)fullname;
- int len = 0;
- fullname[0] = '\0';
- /* If necessary we could also chase down symlinks here... */
-#ifdef COMMENT
- /* This works but is incompatible with wuftpd */
- if (isguest && anonroot) {
- ckstrncpy(fullname,anonroot,CKMAXPATH);
- len = strlen(fullname);
- if (len > 0)
- if (fullname[len-1] == '/')
- len--;
- }
- p += len;
-#endif /* COMMENT */
- zfnqfp(name, CKMAXPATH - len, p);
- while (*p) {
- if (*p < '!') *p = '_';
- p++;
- }
-}
-
-/* D O I K L O G -- Open Kermit-specific ftp-like transfer log. */
-
-VOID /* Called in ckcmai.c */
-doiklog() {
- if (iklogopen) /* Already open? */
- return;
- if (xferlog) { /* Open iksd log if requested */
- if (!xferfile) /* If no pathname given */
- makestr(&xferfile,XFERFILE); /* use this default */
- if (*xferfile) {
- xferlog = open(xferfile, O_WRONLY | O_APPEND | O_CREAT, 0660);
- debug(F101,"doiklog open","",xferlog);
- if (xferlog < 0) {
-#ifdef CKSYSLOG
- syslog(LOG_ERR, "xferlog open failure %s: %m", xferfile);
-#endif /* CKSYSLOG */
- debug(F101,"doiklog open errno","",errno);
- xferlog = 0;
- } else
- iklogopen = 1;
- } else
- xferlog = 0;
-#ifdef CKSYSLOG
- if (xferlog && ckxlogging)
- syslog(LOG_INFO, "xferlog: %s open ok", xferfile);
-#endif /* CKSYSLOG */
- }
-}
-
-/* Z O P E N I -- Open an existing file for input. */
-
-/* Returns 1 on success, 0 on failure */
-
-int
-zopeni(n,name) int n; char *name; {
- int x;
-
- debug(F111,"zopeni",name,n);
- if ((x = chkfn(n)) != 0) {
- debug(F111,"zopeni chkfn",ckitoa(n),x);
- return(0);
- }
- zincnt = 0; /* Reset input buffer */
- if (n == ZSYSFN) { /* Input from a system function? */
-#ifdef COMMENT
-/*** Note, this function should not be called with ZSYSFN ***/
-/*** Always call zxcmd() directly, and give it the real file number ***/
-/*** you want to use. ***/
- return(zxcmd(n,name)); /* Try to fork the command */
-#else
- debug(F110,"zopeni called with ZSYSFN, failing!",name,0);
- *nambuf = '\0'; /* No filename. */
- return(0); /* fail. */
-#endif /* COMMENT */
- }
- if (n == ZSTDIO) { /* Standard input? */
- if (is_a_tty(0)) {
- fprintf(stderr,"Terminal input not allowed");
- debug(F110,"zopeni: attempts input from unredirected stdin","",0);
- return(0);
- }
- fp[ZIFILE] = stdin;
- ispipe[ZIFILE] = 0;
- return(1);
- }
-#ifdef CKROOT
- debug(F111,"zopeni setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(name)) {
- debug(F110,"zopeni setroot violation",name,0);
- return(0);
- }
-#endif /* CKROOT */
- fp[n] = fopen(name,"r"); /* Real file, open it. */
- /* debug(F111,"zopeni fopen", name, fp[n]); */
-#ifdef ZDEBUG
- /* printf("ZOPENI fp[%d]=%ld\n",n,fp[n]); */
-#endif /* ZDEBUG */
- ispipe[n] = 0;
-
- if (xferlog
-#ifdef CKSYSLOG
- || ((ckxsyslog >= SYSLG_FA) && ckxlogging)
-#endif /* CKSYSLOG */
- ) {
- getfullname(name);
- debug(F110,"zopeni fullname",fullname,0);
- }
- if (fp[n] == NULL) {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_FA && ckxlogging) {
- syslog(LOG_INFO, "file[%d] %s: open failed (%m)", n, fullname);
- perror(fullname);
- } else
-#endif /* CKSYSLOG */
- perror(name);
- return(0);
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_FA && ckxlogging)
- syslog(LOG_INFO, "file[%d] %s: open read ok", n, fullname);
-#endif /* CKSYSLOG */
- clearerr(fp[n]);
- return(1);
- }
-}
-
-#ifdef QNX
-#define DONDELAY
-#else
-#ifdef O_NDELAY
-#define DONDELAY
-#endif /* O_NDELAY */
-#endif /* QNX */
-
-/* Z O P E N O -- Open a new file for output. */
-
-/*ARGSUSED*/ /* zz not used */
-int
-zopeno(n,name,zz,fcb)
-/* zopeno */ int n; char *name; struct zattr *zz; struct filinfo *fcb; {
-
- char p[8];
- int append = 0;
- int istty = 0, filefd = 0;
-
-/* As of Version 5A, the attribute structure and the file information */
-/* structure are included in the arglist. */
-
-#ifdef DEBUG
- debug(F111,"zopeno",name,n);
- if (fcb) {
- debug(F101,"zopeno fcb disp","",fcb->dsp);
- debug(F101,"zopeno fcb type","",fcb->typ);
- debug(F101,"zopeno fcb char","",fcb->cs);
- } else {
- debug(F100,"zopeno fcb is NULL","",0);
- }
-#endif /* DEBUG */
-
- if (chkfn(n) != 0) /* Already open? */
- return(0); /* Nothing to do. */
-
- if ((n == ZCTERM) || (n == ZSTDIO)) { /* Terminal or standard output */
- fp[ZOFILE] = stdout;
- ispipe[ZOFILE] = 0;
-#ifdef COMMENT
- /* This seems right but it breaks client server ops */
- fp[n] = stdout;
- ispipe[n] = 0;
-#endif /* COMMENT */
-#ifdef COMMENT
-#ifdef DEBUG
- if (n != ZDFILE)
- debug(F101,"zopeno fp[n]=stdout","",fp[n]);
-#endif /* DEBUG */
-#endif /* COMMENT */
- zoutcnt = 0;
- zoutptr = zoutbuffer;
- return(1);
- }
-
-/* A real file. Open it in desired mode (create or append). */
-
-#ifdef CKROOT
- debug(F111,"zopeno setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(name)) {
- debug(F110,"zopeno setroot violation",name,0);
- return(0);
- }
-#endif /* CKROOT */
-
- ckstrncpy(p,"w",8); /* Assume write/create mode */
- if (fcb) { /* If called with an FCB... */
- if (fcb->dsp == XYFZ_A) { /* Does it say Append? */
- ckstrncpy(p,"a",8); /* Yes. */
- debug(F100,"zopeno append","",0);
- append = 1;
- }
- }
- if (xferlog
-#ifdef CKSYSLOG
- || ((ckxsyslog >= SYSLG_FC) && ckxlogging)
-#endif /* CKSYSLOG */
- ) {
- getfullname(name);
- debug(F110,"zopeno fullname",fullname,0);
- }
- {
- /* Allow tty devices to opened as output files 2009/10/20 */
- int fd, mode = 0;
- debug(F110,"zopeno attempting to open",name,0);
-#ifdef O_NONBLOCK
- mode = O_NONBLOCK;
-#else
-#ifdef O_NDELAY
- mode = O_NDELAY;
-#else
-#ifdef FNDELAY
- mode = FNDELAY;
-#endif /* FNDELAY */
-#endif /* O_NDELAY */
-#endif /* O_NONBLOCK */
- debug(F111,"zopeno open mode",name,mode);
- fd = open(name,O_WRONLY,mode);
- debug(F111,"zopeno open",name,fd);
- if (fd > -1) {
- if (isatty(fd)) {
- filefd = fd;
- istty++;
- }
- }
- }
- debug(F111,"zopeno istty",name,istty);
- debug(F110,"zopeno fopen arg",p,0);
- if (istty)
- fp[n] = fdopen(filefd,p);
- else
- fp[n] = fopen(name,p); /* Try to open the file */
- ispipe[ZIFILE] = 0;
-
-#ifdef ZDEBUG
- printf("ZOPENO fp[%d]=%ld\n",n,fp[n]);
-#endif /* ZDEBUG */
-
- if (fp[n] == NULL) { /* Failed */
- debug(F101,"zopeno failed errno","",errno);
- if (istty) close(filefd);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_FC && ckxlogging)
- syslog(LOG_INFO, "file[%d] %s: %s failed (%m)",
- n,
- fullname,
- append ? "append" : "create"
- );
-#endif /* CKSYSLOG */
-#ifdef COMMENT /* Let upper levels print message. */
- perror("Can't open output file");
-#endif /* COMMENT */
- } else { /* Succeeded */
- extern int zofbuffer, zofblock, zobufsize;
- debug(F101, "zopeno zobufsize", "", zobufsize);
- if (n == ZDFILE || n == ZTFILE) { /* If debug or transaction log */
- setbuf(fp[n],NULL); /* make it unbuffered. */
-#ifdef DONDELAY
- } else if (n == ZOFILE && !zofblock) { /* blocking or nonblocking */
- int flags;
- if ((flags = fcntl(fileno(fp[n]),F_GETFL,0)) > -1)
- fcntl(fileno(fp[n]),F_SETFL, flags |
-#ifdef QNX
- O_NONBLOCK
-#else
- O_NDELAY
-#endif /* QNX */
- );
- debug(F100,"zopeno ZOFILE nonblocking","",0);
-#endif /* DONDELAY */
- } else if (n == ZOFILE && !zofbuffer) { /* buffered or unbuffered */
- setbuf(fp[n],NULL);
- debug(F100,"zopeno ZOFILE unbuffered","",0);
- }
-
-#ifdef CK_LOGIN
- /* Enforce anonymous file-creation permission */
- if (isguest)
- if (n == ZWFILE || n == ZMFILE ||
- n == ZOFILE || n == ZDFILE ||
- n == ZTFILE || n == ZPFILE ||
- n == ZSFILE)
- chmod(name,ckxperms);
-#endif /* CK_LOGIN */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_FC && ckxlogging)
- syslog(LOG_INFO, "file[%d] %s: %s ok",
- n,
- fullname,
- append ? "append" : "create"
- );
-#endif /* CKSYSLOG */
- debug(F100, "zopeno ok", "", 0);
- }
- zoutcnt = 0; /* (PWP) reset output buffer */
- zoutptr = zoutbuffer;
- return((fp[n] != NULL) ? 1 : 0);
-}
-
-/* Z C L O S E -- Close the given file. */
-
-/* Returns 0 if arg out of range, 1 if successful, -1 if close failed. */
-
-int
-zclose(n) int n; {
- int x = 0, x2 = 0;
- extern CK_OFF_T ffc;
-
- debug(F101,"zclose file number","",n);
- if (chkfn(n) < 1) return(0); /* Check range of n */
- if ((n == ZOFILE) && (zoutcnt > 0)) /* (PWP) output leftovers */
- x2 = zoutdump();
-
- if (fp[ZSYSFN] || ispipe[n]) { /* If file is really pipe */
-#ifndef NOPUSH
- x = zclosf(n); /* do it specially */
-#else
- x = EOF;
-#endif /* NOPUSH */
- debug(F101,"zclose zclosf","",x);
- /* debug(F101,"zclose zclosf fp[n]","",fp[n]); */
- } else {
- if ((fp[n] != stdout) && (fp[n] != stdin))
- x = fclose(fp[n]);
- fp[n] = NULL;
-#ifdef COMMENT
- if (n == ZCTERM || n == ZSTDIO) /* See zopeno() */
- if (fp[ZOFILE] == stdout)
- fp[ZOFILE] = NULL;
-#endif /* COMMENT */
- }
- iflen = -1L; /* Invalidate file length */
- if (x == EOF) { /* if we got a close error */
- debug(F101,"zclose fclose fails","",x);
- return(-1);
- } else if (x2 < 0) { /* or error flushing last buffer */
- debug(F101,"zclose error flushing last buffer","",x2);
- return(-1); /* then return an error */
- } else {
- /* Print log record compatible with wu-ftpd */
- if (xferlog && (n == ZIFILE || n == ZOFILE)) {
- char * s, *p;
- extern char ttname[];
- if (!iklogopen) (VOID) doiklog(); /* Open log if necessary */
- debug(F101,"zclose iklogopen","",iklogopen);
- if (iklogopen) {
- int len;
- char * fnam;
-
- timenow = time(NULL);
-#ifdef CK_LOGIN
- if (logged_in)
- s = clienthost;
- else
-#endif /* CK_LOGIN */
- s = (char *)ttname;
- if (!s) s = "";
- if (!*s) s = "*";
-#ifdef CK_LOGIN
- if (logged_in) {
- p = guestpass;
- if (!*p) p = "*";
- } else
-#endif /* CK_LOGIN */
- p = whoami();
-
- len = 24 + 12 + (int)strlen(s) + 16
- + (int)strlen(fullname) + 1 + 1 + 1 + 1
- + (int)strlen(p) + 6 + 2 + 12;
- fnam = fullname;
- if (!*fnam) fnam = "(pipe)";
-
- if (len > IKSDMSGLEN)
- sprintf(iksdmsg, /* SAFE */
- "%.24s [BUFFER WOULD OVERFLOW]\n",ctime(&timenow));
- else
- sprintf(iksdmsg, /* SAFE */
- "%.24s %d %s %s %s %c %s %c %c %s %s %d %s\n",
- ctime(&timenow), /* date/time */
- gtimer(), /* elapsed secs */
- s, /* peer name */
- ckfstoa(ffc), /* byte count */
- fnam, /* full pathname of file */
- (binary ? 'b' : 'a'), /* binary or ascii */
- "_", /* options = none */
- n == ZIFILE ? 'o' : 'i', /* in/out */
-#ifdef CK_LOGIN
- (isguest ? 'a' : 'r'), /* User type */
-#else
- 'r',
-#endif /* CK_LOGIN */
- p, /* Username or guest passwd */
-#ifdef CK_LOGIN
- logged_in ? "iks" : "kermit", /* Record ID */
-#else
- "kermit",
-#endif /* CK_LOGIN */
- 0, /* User ID on client system unknown */
- "*" /* Ditto */
- );
- debug(F110,"zclose iksdmsg",iksdmsg,0);
- write(xferlog, iksdmsg, (int)strlen(iksdmsg));
- }
- }
- debug(F101,"zclose returns","",1);
- return(1);
- }
-}
-
-/* Z C H I N -- Get a character from the input file. */
-
-/* Returns -1 if EOF, 0 otherwise with character returned in argument */
-
-int
-zchin(n,c) int n; int *c; {
- int a;
-
-#ifdef IKSD
- if (inserver && !local && (n == ZCTERM || n == ZSTDIO)) {
- a = coninc(0);
- if (*c < 0)
- return(-1);
- } else
-#endif /* IKSD */
- /* (PWP) Just in case this gets called when it shouldn't. */
- if (n == ZIFILE) {
- a = zminchar(); /* Note: this catches Ctrl-Z */
- if (a < 0) /* (See zinfill()...) */
- return(-1);
- } else {
- a = getc(fp[n]);
- if (a == EOF) return(-1);
-#ifdef CK_CTRLZ
- /* If SET FILE EOF CTRL-Z, first Ctrl-Z marks EOF */
- if (!binary && a == 0x1A && eofmethod == XYEOF_Z)
- return(-1);
-#endif /* CK_CTRLZ */
- }
- *c = (CHAR) a & 0377;
- return(0);
-}
-
-/* Z S I N L -- Read a line from a file */
-
-/*
- Writes the line into the address provided by the caller.
- n is the Kermit "channel number".
- Writing terminates when newline is encountered, newline is not copied.
- Writing also terminates upon EOF or if length x is exhausted.
- Returns 0 on success, -1 on EOF or error.
-*/
-int
-zsinl(n,s,x) int n, x; char *s; {
- int a, z = 0; /* z is return code. */
- int count = 0;
- int len = 0;
- char *buf;
- extern CHAR feol; /* Line terminator */
-
- if (!s || chkfn(n) < 1) /* Make sure file is open, etc */
- return(-1);
- buf = s;
- s[0] = '\0'; /* Don't return junk */
-
- a = -1; /* Current character, none yet. */
- while (x--) { /* Up to given length */
- int old = 0;
- if (feol) /* Previous character */
- old = a;
- if (zchin(n,&a) < 0) { /* Read a character from the file */
- debug(F101,"zsinl zchin fail","",count);
- if (count == 0)
- z = -1; /* EOF or other error */
- break;
- } else
- count++;
- if (feol) { /* Single-character line terminator */
- if (a == feol)
- break;
- } else { /* CRLF line terminator */
- if (a == '\015') /* CR, get next character */
- continue;
- if (old == '\015') { /* Previous character was CR */
- if (a == '\012') { /* This one is LF, so we have a line */
- break;
- } else { /* Not LF, deposit CR */
- *s++ = '\015';
- x--;
- len++;
- }
- }
- }
- *s = a; /* Deposit character */
- s++;
- len++;
- }
- *s = '\0'; /* Terminate the string */
- debug(F011,"zsinl",buf,len);
- return(z);
-}
-
-/* Z X I N -- Read x bytes from a file */
-
-/*
- Reads x bytes (or less) from channel n and writes them
- to the address provided by the caller.
- Returns number of bytes read on success, 0 on EOF or error.
-*/
-int
-zxin(n,s,x) int n, x; char *s; {
-#ifdef IKSD
- if (inserver && !local && (n == ZCTERM || n == ZSTDIO)) {
- int a, i;
- a = ttchk();
- if (a < 1) return(0);
- for (i = 0; i < a && i < x; i++)
- s[i] = coninc(0);
- return(i);
- }
-#endif /* IKSD */
-
- return(fread(s, sizeof (char), x, fp[n]));
-}
-
-/*
- Z I N F I L L -- Buffered file input.
-
- (re)fill the file input buffer with data. All file input
- should go through this routine, usually by calling the zminchar()
- macro defined in ckcker.h. Returns:
-
- Value 0..255 on success, the character that was read.
- -1 on end of file.
- -2 on any kind of error other than end of file.
- -3 timeout when reading from pipe (Kermit packet mode only).
-*/
-int
-zinfill() {
- extern int kactive, srvping;
- errno = 0;
-
-#ifdef ZDEBUG
- printf("ZINFILL fp[%d]=%ld\n",ZIFILE,fp[ZIFILE]);
-#endif /* ZDEBUG */
-
-#ifdef IKSD
- if (inserver && !local && fp[ZIFILE] == stdin) {
- int a, i;
- a = ttchk();
- if (a < 0) return(-2);
- for (i = 0; i < a && i < INBUFSIZE; i++) {
- zinbuffer[i] = coninc(0);
- }
- zincnt = i;
- /* set pointer to beginning, (== &zinbuffer[0]) */
- zinptr = zinbuffer;
- if (zincnt == 0) return(-1);
- zincnt--; /* One less char in buffer */
- return((int)(*zinptr++) & 0377); /* because we return the first */
- }
-#endif /* IKSD */
-
- debug(F101,"zinfill kactive","",kactive);
-
- if (!(kactive && ispipe[ZIFILE])) {
- if (feof(fp[ZIFILE])) {
- debug(F100,"ZINFILL feof","",0);
-#ifdef ZDEBUG
- printf("ZINFILL EOF\n");
-#endif /* ZDEBUG */
- return(-1);
- }
- }
- clearerr(fp[ZIFILE]);
-
-#ifdef SELECT
- /* Here we can call select() to get a timeout... */
- if (kactive && ispipe[ZIFILE]) {
- int secs, z = 0;
-#ifndef NOXFER
- if (srvping) {
- secs = 1;
- debug(F101,"zinfill calling ttwait","",secs);
- z = ttwait(fileno(fp[ZIFILE]),secs);
- debug(F101,"zinfill ttwait","",z);
- }
-#endif /* NOXFER */
- if (z == 0)
- return(-3);
- }
-#endif /* SELECT */
-
-#ifdef DEBUG
- if (deblog) {
- int i;
- debug(F101,"ZINFILL INBUFSIZE","",INBUFSIZE);
-#ifdef USE_MEMCPY
- memset(zinbuffer, 0xFF, INBUFSIZE);
-#else
- for (i = 0; i < INBUFSIZE; i++) {
- zinbuffer[i] = 0xFF;
-#ifdef COMMENT /* Too much! */
- debug(F101,"ZINFILL zinbuffer[i]","",i);
-#endif /* COMMENT */
- }
-#endif /* USE_MEMCPY */
- ckstrncpy(zinbuffer,"zinbuffer is a valid buffer",INBUFSIZE);
- /* debug(F111,"ZINFILL about to call fread",zinbuffer,zinbuffer); */
- }
-#endif /* DEBUG */
-
-/*
- Note: The following read MUST be nonblocking when reading from a pipe
- and we want timeouts to work. See zxcmd().
-*/
- zincnt = fread(zinbuffer, sizeof (char), INBUFSIZE, fp[ZIFILE]);
- debug(F101,"ZINFILL fread","",zincnt); /* Just the size */
-#ifdef ZDEBUG
- printf("FREAD=%d\n",zincnt);
-#endif /* ZDEBUG */
-#ifdef CK_CTRLZ
- /* If SET FILE EOF CTRL-Z, first Ctrl-Z marks EOF */
- if (zincnt > 0 && !binary && eofmethod == XYEOF_Z) {
- register int i;
- for (i = 0; i < zincnt; i++) {
- if (zinbuffer[i] == SUB) {
- zincnt = i; /* Stop at first Ctrl-Z */
- if (i == 0)
- return(-1);
- break;
- }
- }
- }
-#endif /* CK_CTRLZ */
-
- if (zincnt == 0) { /* Got nothing? */
- if (ferror(fp[ZIFILE])) {
- debug(F100,"ZINFILL ferror","",0);
- debug(F101,"ZINFILL errno","",errno);
-#ifdef ZDEBUG
- printf("ZINFILL errno=%d\n",errno);
-#endif /* ZDEBUG */
-#ifdef EWOULDBLOCK
- return((errno == EWOULDBLOCK) ? -3 : -2);
-#else
- return(-2);
-#endif /* EWOULDBLOCK */
- }
-
- /* In case feof() didn't work just above -- sometimes it doesn't... */
-
- if (feof(fp[ZIFILE]) ) {
- debug(F100,"ZINFILL count 0 EOF return -1","",0);
- return (-1);
- } else {
- debug(F100,"ZINFILL count 0 not EOF return -2","",0);
- return(-2);
- }
- }
- zinptr = zinbuffer; /* set pointer to beginning, (== &zinbuffer[0]) */
- zincnt--; /* One less char in buffer */
- return((int)(*zinptr++) & 0377); /* because we return the first */
-}
-
-/* Z S O U T -- Write a string out to the given file, buffered. */
-
-/* Returns 0 on success, -1 on failure */
-
-int
-zsout(n,s) int n; char *s; {
- int rc = 0;
- rc = chkfn(n);
- if (rc < 1) return(-1); /* Keep this, prevents memory faults */
- if (!s) return(0); /* Null pointer, do nothing, succeed */
- if (!*s) return(0); /* empty string, ditto */
-
-#ifdef IKSD
- /*
- This happens with client-side Kermit server when a REMOTE command
- was sent from the server to the client and the server is supposed to
- display the text, but of course there is no place to display it
- since it is in remote mode executing Kermit protocol.
- */
- if (inserver && !local && (n == ZCTERM || n == ZSTDIO)) {
-#ifdef COMMENT
- return(ttol(s,((int)strlen(s)) < 0) ? -1 : 0);
-#else
- return(0);
-#endif /* COMMENT */
- }
-#endif /* IKSD */
-
- if (n == ZSFILE) {
- int k;
- k = strlen(s);
- rc = write(fileno(fp[n]),s,k);
- return((rc == k) ? 0 : -1);
- }
- rc = fputs(s,fp[n]) == EOF ? -1 : 0;
- if (n == ZWFILE)
- fflush(fp[n]);
- return(rc);
-}
-
-/* Z S O U T L -- Write string to file, with line terminator, buffered */
-
-/* Returns 0 on success, -1 on failure */
-
-int
-zsoutl(n,s) int n; char *s; {
- if (zsout(n,s) < 0)
- return(-1);
-
-#ifdef IKSD
- if (inserver && !local && (n == ZCTERM || n == ZSTDIO)) {
-#ifdef COMMENT
- return(ttoc(LF));
-#else
- return(0); /* See comments in zsout() */
-#endif /* COMMENT */
- }
-#endif /* IKSD */
-
- if (n == ZSFILE) /* Session log is unbuffered */
- return(write(fileno(fp[n]),"\n",1) == 1 ? 0 : -1);
- else if (fputs("\n",fp[n]) == EOF)
- return(-1);
- if (n == ZDIFIL || n == ZWFILE) /* Flush connection log records */
- fflush(fp[n]);
- return(0);
-}
-
-/* Z S O U T X -- Write x characters to file, unbuffered. */
-
-/* Returns number of characters written on success, -1 on failure */
-
-int
-zsoutx(n,s,x) int n, x; char *s; {
- int k;
- if (!s) return(0);
- if (!*s) return(0);
-
-#ifdef IKSD
- if (inserver && !local && (n == ZCTERM || n == ZSTDIO)) {
-#ifdef COMMENT
- return(ttol(s,x)); /* See comments in zsout() */
-#else
- return(x);
-#endif /* COMMENT */
- }
-#endif /* IKSD */
-
- if ((k = (int)strlen(s)) > x) x = k; /* Nothing else would make sense */
-#ifdef COMMENT
- if (chkfn(n) < 1) return(-1);
- return(write(fp[n]->_file,s,x));
-#endif /* COMMENT */
- return(write(fileno(fp[n]),s,x) == x ? x : -1);
-}
-
-/* Z C H O U T -- Add a character to the given file. */
-
-/* Should return 0 or greater on success, -1 on failure (e.g. disk full) */
-
-int
-#ifdef CK_ANSIC
-zchout(register int n, char c)
-#else
-zchout(n,c) register int n; char c;
-#endif /* CK_ANSIC */
-/* zchout() */ {
- /* if (chkfn(n) < 1) return(-1); */
-
-#ifdef IKSD
- if (inserver && !local && (n == ZCTERM || n == ZSTDIO)) {
-#ifdef COMMENT
- return(ttoc(c));
-#else
- return(0); /* See comments in zsout() */
-#endif /* COMMENT */
- }
-#endif /* IKSD */
-
- if (n == ZSFILE) /* Use unbuffered for session log */
- return(write(fileno(fp[n]),&c,1) == 1 ? 0 : -1);
- /* Buffered for everything else */
- if (putc(c,fp[n]) == EOF) /* If true, maybe there was an error */
- return(ferror(fp[n])?-1:0); /* Check to make sure */
- else /* Otherwise... */
- return(0); /* There was no error. */
-}
-
-/* (PWP) buffered character output routine to speed up file IO */
-
-int
-zoutdump() {
- int x;
- char * zp;
- zoutptr = zoutbuffer; /* Reset buffer pointer in all cases */
-#ifdef DEBUG
- if (deblog)
- debug(F101,"zoutdump zoutcnt","",zoutcnt);
-#endif /* DEBUG */
- if (zoutcnt == 0) { /* Nothing to output */
- return(0);
- } else if (zoutcnt < 0) { /* Unexpected negative argument */
- zoutcnt = 0; /* Reset output buffer count */
- return(-1); /* and fail. */
- }
-
-#ifdef IKSD
- if (inserver && !local && fp[ZOFILE] == stdout) {
-#ifdef COMMENT
- x = ttol(zoutbuffer,zoutcnt);
-#else
- x = 1; /* See comments in zsout() */
-#endif /* COMMENT */
- zoutcnt = 0;
- return(x > 0 ? 0 : -1);
- }
-#endif /* IKSD */
-
-/*
- Frank Prindle suggested that replacing this fwrite() by an fflush()
- followed by a write() would improve the efficiency, especially when
- writing to stdout. Subsequent tests showed a 5-fold improvement.
-*/
-#ifdef COMMENT
- if (x = fwrite(zoutbuffer, 1, zoutcnt, fp[ZOFILE])) ...
-#endif /* COMMENT */
-
-#ifndef CK_NONBLOCK
- fflush(fp[ZOFILE]);
-#endif /* CK_NONBLOCK */
- zp = zoutbuffer;
- while (zoutcnt > 0) {
- if ((x = write(fileno(fp[ZOFILE]),zp,zoutcnt)) > -1) {
-#ifdef DEBUG
- if (deblog) /* Save a function call... */
- debug(F101,"zoutdump wrote","",x);
-#endif /* DEBUG */
- zoutcnt -= x; /* Adjust output buffer count */
- zp += x; /* and pointer */
- } else {
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"zoutdump write error","",errno);
- debug(F101,"zoutdump write returns","",x);
- }
-#endif /* DEBUG */
- zoutcnt = 0; /* Reset output buffer count */
- return(-1); /* write() failed */
- }
- }
- return(0);
-}
-
-/* C H K F N -- Internal function to verify file number is ok */
-
-/*
- Returns:
- -1: File number n is out of range
- 0: n is in range, but file is not open
- 1: n in range and file is open
-*/
-int
-chkfn(n) int n; {
- /* if (n != ZDFILE) debug(F101,"chkfn","",n); */
- if (n < 0 || n >= ZNFILS) {
- if (n != ZDFILE) debug(F101,"chkfn out of range","",n);
- return(-1);
- } else {
- /* if (n != ZDFILE) debug(F101,"chkfn fp[n]","",fp[n]); */
- return((fp[n] == NULL) ? 0 : 1);
- }
-}
-
-/* Z G E T F S -- Return file size regardless of accessibility */
-/*
- Used for directory listings, etc.
- Returns:
- The size of the file in bytes, 0 or greater, if the size can be learned.
- -1 if the file size can not be obtained.
- Also (and this is a hack just for UNIX):
- If the argument is the name of a symbolic link,
- the global variable issymlink is set to 1,
- and the global buffer linkname[] gets the link value.
- And it sets zgfs_dir to 1 if it's a directory, otherwise 0.
- This lets us avoid numerous redundant calls to stat().
-*/
-int zgfs_link = 0;
-int zgfs_dir = 0;
-time_t zgfs_mtime = 0;
-unsigned int zgfs_mode = 0;
-
-#ifdef CKSYMLINK
-char linkname[CKMAXPATH+1];
-#ifndef _IFLNK
-#define _IFLNK 0120000
-#endif /* _IFLNK */
-#endif /* CKSYMLINK */
-
-CK_OFF_T
-zgetfs(name) char *name; {
- struct stat buf;
- char fnam[CKMAXPATH+4];
- CK_OFF_T size = (CK_OFF_T)-1;
- int x;
- int needrlink = 0;
- char * s;
-
- if (!name) name = "";
- if (!*name) return(-1);
-
-#ifdef UNIX
- x = strlen(name);
- if (x == 9 && !strcmp(name,"/dev/null"))
- return(0);
-#endif /* UNIX */
-
- s = name;
-#ifdef DTILDE
- if (*s == '~') {
- s = tilde_expand(s);
- if (!s) s = "";
- if (!*s) s = name;
- }
-#endif /* DTILDE */
- x = ckstrncpy(fnam,s,CKMAXPATH);
- s = fnam;
- debug(F111,"zgetfs fnam",s,x);
- if (x > 0 && s[x-1] == '/')
- s[x-1] = '\0';
-
- zgfs_dir = 0; /* Assume it's not a directory */
- zgfs_link = 0; /* Assume it's not a symlink */
- zgfs_mtime = 0; /* No time yet */
- zgfs_mode = 0; /* No permission bits yet */
-
-#ifdef CKSYMLINK /* We're doing symlinks? */
-#ifdef USE_LSTAT /* OK to use lstat()? */
- x = lstat(s,&buf);
- debug(F101,"STAT","",1);
- if (x < 0) /* stat() failed */
- return(-1);
- if ( /* Now see if it's a symlink */
-#ifdef S_ISLNK
- S_ISLNK(buf.st_mode)
-#else
-#ifdef _IFLNK
- ((_IFMT & buf.st_mode) == _IFLNK)
-#endif /* _IFLNK */
-#endif /* S_ISLNK */
- ) {
- zgfs_link = 1; /* It's a symlink */
- linkname[0] = '\0'; /* Get the name */
- x = readlink(s,linkname,CKMAXPATH);
- debug(F101,"zgetfs readlink",s,x);
- if (x > -1 && x < CKMAXPATH) { /* It's a link */
- linkname[x] = '\0';
- size = buf.st_size; /* Remember size of link */
- x = stat(s,&buf); /* Now stat the linked-to file */
- debug(F101,"STAT","",2);
- if (x < 0) /* so we can see if it's a directory */
- return(-1);
- } else {
- ckstrncpy(linkname,"(lookup failed)",CKMAXPATH);
- }
- }
-#else /* !USE_LSTAT */
- x = stat(s,&buf); /* No lstat(), use stat() instead */
- debug(F101,"STAT","",3);
- if (x < 0)
- return(-1);
-#endif /* USE_LSTAT */
-
- /* Do we need to call readlink()? */
-
-#ifdef NOLINKBITS
-/*
- lstat() does not work in SCO operating systems. From "man NS lstat":
-
- lstat obtains information about the file named by path. In the case of a
- symbolic link, lstat returns information about the link, and not the file
- named by the link. It is only used by the NFS automount daemon and should
- not be utilized by users.
-*/
- needrlink = 1;
- debug(F101,"zgetfs forced needrlink","",needrlink);
-#else
-#ifdef S_ISLNK
- needrlink = S_ISLNK(buf.st_mode);
- debug(F101,"zgetfs S_ISLNK needrlink","",needrlink);
-#else
-#ifdef _IFLNK
- needrlink = (_IFMT & buf.st_mode) == _IFLNK;
- debug(F101,"zgetfs _IFLNK needrlink","",needrlink);
-#else
- needrlink = 1;
- debug(F101,"zgetfs default needrlink","",needrlink);
-#endif /* _IFLNK */
-#endif /* S_ISLNK */
-#endif /* NOLINKBITS */
-
- if (needrlink) {
- linkname[0] = '\0';
- errno = 0;
- x = readlink(s,linkname,CKMAXPATH);
-#ifdef DEBUG
- debug(F111,"zgetfs readlink",s,x);
- if (x < 0)
- debug(F101,"zgetfs readlink errno","",errno);
- else
- debug(F110,"zgetfs readlink result",linkname,0);
-#endif /* DEBUG */
- if (x > -1 && x < CKMAXPATH) {
- zgfs_link = 1;
- linkname[x] = '\0';
- }
- }
-#else /* !CKSYMLINK */
- x = stat(s,&buf); /* Just stat the file */
- debug(F111,"zgetfs stat",s,x);
- if (x < 0) /* and get the size */
- return(-1);
-#endif /* CKSYMLINK */
-
- zgfs_mtime = buf.st_mtime;
- zgfs_mode = buf.st_mode;
- zgfs_dir = (S_ISDIR(buf.st_mode)) ? 1 : 0; /* Set "is directory" flag */
- debug(F111,"zgetfs size",s,size);
- debug(F111,"zgetfs st_size",s,buf.st_size);
- return((size < 0L) ? buf.st_size : size); /* Return the size */
-}
-
-
-/* Z C H K I -- Check if input file exists and is readable */
-
-/*
- Returns:
- >= 0 if the file can be read (returns the size).
- -1 if file doesn't exist or can't be accessed,
- -2 if file exists but is not readable (e.g. a directory file).
- -3 if file exists but protected against read access.
-
- For Berkeley Unix, a file must be of type "regular" to be readable.
- Directory files, special files, and symbolic links are not readable.
-*/
-CK_OFF_T
-zchki(name) char *name; {
- struct stat buf;
- char * s;
- int x, itsadir = 0;
- extern int zchkid, diractive, matchfifo;
-
- if (!name)
- return(-1);
- x = strlen(name);
- if (x < 1)
- return(-1);
- s = name;
-
-#ifdef UNIX
- if (x == 9 && !strcmp(s,"/dev/null"))
- return(0);
- if (x == 8 && !strcmp(s,"/dev/tty"))
- return(0);
-#endif /* UNIX */
-
-#ifdef DTILDE
- if (*s == '~') {
- s = tilde_expand(s);
- if (!s) s = "";
- if (!*s) s = name;
- }
-#endif /* DTILDE */
-
-#ifdef CKROOT
- debug(F111,"zchki setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(name)) {
- debug(F110,"zchki setroot violation",name,0);
- return(-1);
- }
-#endif /* CKROOT */
-
- x = stat(s,&buf);
- debug(F101,"STAT","",5);
- if (x < 0) {
- debug(F111,"zchki stat fails",s,errno);
- return(-1);
- }
- if (S_ISDIR (buf.st_mode))
- itsadir = 1;
-
- if (!(itsadir && zchkid)) { /* Unless this... */
- if (!S_ISREG (buf.st_mode) /* Must be regular file */
-#ifdef S_ISFIFO
- && (!matchfifo || !S_ISFIFO (buf.st_mode)) /* or FIFO */
-#endif /* S_ISFIFO */
- ) {
- debug(F111,"zchki not regular file (or fifo)",s,matchfifo);
- return(-2);
- }
- }
- debug(F111,"zchki stat ok:",s,x);
-
- if (diractive) { /* If listing don't check access */
- x = 1;
- } else {
-#ifdef SW_ACC_ID
- debug(F100,"zchki swapping ids for access()","",0);
- priv_on();
-#endif /* SW_ACC_ID */
- if ((x = access(s,R_OK)) < 0)
- x = access(s,X_OK); /* For RUN-class commands */
-#ifdef SW_ACC_ID
- priv_off();
- debug(F100,"zchki swapped ids restored","",0);
-#endif /* SW_ACC_ID */
- }
- if (x < 0) { /* Is the file accessible? */
- debug(F111,"zchki access failed:",s,x); /* No */
- return(-3);
- } else {
- iflen = buf.st_size; /* Yes, remember size */
- ckstrncpy(nambuf,s,CKMAXPATH); /* and name globally. */
- debug(F111,"zchki access ok:",s,iflen);
- return((iflen > -1L) ? iflen : 0L);
- }
-}
-
-/* Z C H K O -- Check if output file can be created */
-
-/*
- Returns -1 if write permission for the file would be denied, 0 otherwise.
-
- NOTE: The design is flawed. There is no distinction among:
- . Can I overwrite an existing file?
- . Can I create a file (or directory) in an existing directory?
- . Can I create a file (or directory) and its parent(s)?
-*/
-int
-zchko(name) char *name; {
- int i, x, itsadir = 0;
- char *s = NULL;
- char * oname;
- extern int zchkod; /* Used by IF WRITEABLE */
-
- debug(F110,"zchko entry",name,0);
-
- if (!name) return(-1); /* Watch out for null pointer. */
-
- oname = name;
-
-#ifdef CKROOT
- debug(F111,"zchko setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(name)) {
- debug(F110,"zchko setroot violation",name,0);
- errno = EACCES;
- return(-1);
- }
-#endif /* CKROOT */
-
- x = (int)strlen(name); /* Get length of filename */
- debug(F111,"zchko len",name,x);
- debug(F111,"zchko zchkod",name,zchkod);
-
-#ifdef UNIX
-/*
- Writing to null device is OK.
-*/
- if (x == 9 && !strcmp(name,"/dev/null"))
- return(0);
- if (x == 8 && !strcmp(name,"/dev/tty"))
- return(0);
-#endif /* UNIX */
-
- s = name;
-#ifdef DTILDE
- if (*s == '~') {
- s = tilde_expand(s);
- if (!s) s = "";
- if (!*s) s = name;
- x = strlen(s);
- }
-#endif /* DTILDE */
- name = s;
- s = NULL;
-/*
- zchkod is a global flag meaning we're checking not to see if the directory
- file is writeable, but if it's OK to create files IN the directory.
-*/
- if (!zchkod && isdir(name)) { /* Directories are not writeable */
- debug(F111,"zchko isdir",name,1);
- return(-1);
- }
- s = malloc(x+3); /* Must copy because we can't */
- if (!s) { /* write into our argument. */
- fprintf(stderr,"zchko: Malloc error 46\n");
- return(-1);
- }
- ckstrncpy(s,name,x+3);
-#ifdef UNIX
-#ifdef NOUUCP
- { /* 2009/10/20 */
- /* Allow tty devices to opened as output files */
- int fd, istty = 0, mode = 0;
- debug(F110,"zchko attempting to open",name,0);
- /* Don't block on lack of Carrier or other modem signals */
-#ifdef O_NONBLOCK
- mode = O_NONBLOCK;
-#else
-#ifdef O_NDELAY
- mode = O_NDELAY;
-#else
-#ifdef FNDELAY
- mode = FNDELAY;
-#endif /* FNDELAY */
-#endif /* O_NDELAY */
-#endif /* O_NONBLOCK */
- debug(F111,"zchko open mode",name,mode);
- fd = open(name,O_WRONLY,mode); /* Must attempt to open it */
- debug(F111,"zchko open",name,fd);
- if (fd > -1) { /* to get a file descriptor */
- if (isatty(fd)) /* for isatty() */
- istty++;
- debug(F111,"zchko isatty",name,istty);
- fd = close(fd);
- if (istty) {
- goto doaccess;
- }
- } else {
- debug(F101,"zchko open errno","",errno);
- x = -1;
- }
- }
-#endif /* NOUUCP */
-#endif /* UNIX */
- for (i = x; i > 0; i--) { /* Strip filename from right. */
- if (ISDIRSEP(s[i-1])) {
- itsadir = 1;
- break;
- }
- }
- debug(F101,"zchko i","",i);
- debug(F101,"zchko itsadir","",itsadir);
-
-#ifdef COMMENT
-/* X/OPEN XPG3-compliant systems fail if argument ends with "/"... */
- if (i == 0) /* If no path, use current directory */
- strcpy(s,"./");
- else /* Otherwise, use given one. */
- s[i] = '\0';
-#else
-#ifdef COMMENT
-/*
- The following does not work for "foo/bar" where the foo directory does
- not exist even though we could create it: access("foo/.") fails, but
- access("foo") works OK.
-*/
-/* So now we use "path/." if path given, or "." if no path given. */
- s[i++] = '.'; /* Append "." to path. */
- s[i] = '\0';
-#else
-/* So NOW we strip path segments from the right as long as they don't */
-/* exist -- we only call access() for path segments that *do* exist.. */
-/* (But this isn't quite right either since now zchko(/foo/bar/baz/xxx) */
-/* succeeds when I have write access to foo and bar but baz doesn't exit.) */
-
- if (itsadir && i > 0) {
- s[i-1] = '\0';
- while (s[0] && !isdir(s)) {
- for (i = (int)strlen(s); i > 0; i--) {
- if (ISDIRSEP(s[i-1])) {
- s[i-1] = '\0';
- break;
- }
- }
- if (i == 0)
- s[0] = '\0';
- }
- } else {
- s[i++] = '.'; /* Append "." to path. */
- s[i] = '\0';
- }
-#endif /* COMMENT */
-#endif /* COMMENT */
-
- if (!s[0])
- ckstrncpy(s,".",x+3);
-
- doaccess:
-
-#ifdef SW_ACC_ID
- debug(F100,"zchko swapping ids for access()","",0);
- priv_on();
-#endif /* SW_ACC_ID */
-
- x = access(s,W_OK); /* Check access of path. */
-
-#ifdef SW_ACC_ID
- priv_off();
- debug(F100,"zchko swapped ids restored","",0);
-#endif /* SW_ACC_ID */
-
- if (x < 0)
- debug(F111,"zchko access failed:",s,errno);
- else
- debug(F111,"zchko access ok:",s,x);
- if (s) free(s); /* Free temporary storage */
-
- return((x < 0) ? -1 : 0); /* and return. */
-}
-
-/* Z D E L E T -- Delete the named file. */
-
-/* Returns: -1 on error, 0 on success */
-
-int
-zdelet(name) char *name; {
- int x;
-#ifdef CK_LOGIN
- if (isguest)
- return(-1);
-#endif /* CK_LOGIN */
-
-#ifdef CKROOT
- debug(F111,"zdelet setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(name)) {
- debug(F110,"zdelet setroot violation",name,0);
- return(-1);
- }
-#endif /* CKROOT */
-
- x = unlink(name);
- debug(F111,"zdelet",name,x);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_FC && ckxlogging) {
- fullname[0] = '\0';
- zfnqfp(name,CKMAXPATH,fullname);
- debug(F110,"zdelet fullname",fullname,0);
- if (x < 0)
- syslog(LOG_INFO, "file[] %s: delete failed (%m)", fullname);
- else
- syslog(LOG_INFO, "file[] %s: delete ok", fullname);
- }
-#endif /* CKSYSLOG */
- return(x);
-}
-
-/* Z R T O L -- Convert remote filename into local form */
-
-VOID
-zrtol(name,name2) char *name, *name2; {
- nzrtol(name,name2,1,0,CKMAXPATH);
-}
-
-VOID
-nzrtol(name,name2,fncnv,fnrpath,max)
- char *name, *name2; int fncnv, fnrpath, max;
-{ /* nzrtol */
- char *s, *p;
- int flag = 0, n = 0;
- char fullname[CKMAXPATH+1];
- int devnull = 0;
- int acase = 0;
- if (!name2) return;
- if (!name) name = "";
-
- debug(F111,"nzrtol name",name,fncnv);
-
-#ifdef DTILDE
- s = name;
- if (*s == '~') {
- s = tilde_expand(s);
- if (!s) s = "";
- if (*s) name = s;
- }
-#endif /* DTILDE */
-
- /* Handle the path -- we don't have to convert its format, since */
- /* the standard path format and our (UNIX) format are the same. */
-
- fullname[0] = NUL;
- devnull = !strcmp(name,"/dev/null");
-
- if (!devnull && fnrpath == PATH_OFF) { /* RECEIVE PATHNAMES OFF */
- zstrip(name,&p);
- strncpy(fullname,p,CKMAXPATH);
- } else if (!devnull && fnrpath == PATH_ABS) { /* REC PATHNAMES ABSOLUTE */
- strncpy(fullname,name,CKMAXPATH);
- } else if (!devnull && isabsolute(name)) { /* RECEIVE PATHNAMES RELATIVE */
- ckmakmsg(fullname,CKMAXPATH,".",name,NULL,NULL);
- } else { /* Ditto */
- ckstrncpy(fullname,name,CKMAXPATH);
- }
- fullname[CKMAXPATH] = NUL;
- debug(F110,"nzrtol fullname",fullname,0);
-
-#ifndef NOTRUNCATE
-/*
- The maximum length for any segment of a filename is MAXNAMLEN, defined
- above. On some platforms (at least QNX) if a segment exceeds this limit,
- the open fails with ENAMETOOLONG, so we must prevent it by truncating each
- overlong name segment to the maximum segment length before passing the
- name to open(). This must be done even when file names are literal, so as
- not to halt a file transfer unnecessarily.
-*/
- {
- char buf[CKMAXPATH+1]; /* New temporary buffer on stack */
- char *p = fullname; /* Source and */
- char *s = buf; /* destination pointers */
- int i = 0, n = 0;
- debug(F101,"nzrtol sizing MAXNAMLEN","",MAXNAMLEN);
- while (*p && n < CKMAXPATH) { /* Copy name to new buffer */
- if (++i > MAXNAMLEN) { /* If this segment too long */
- while (*p && *p != '/') /* skip past the rest... */
- p++;
- i = 0; /* and reset counter. */
- } else if (*p == '/') { /* End of this segment. */
- i = 0; /* Reset counter. */
- }
- *s++ = *p++; /* Copy this character. */
- n++;
- }
- *s = NUL;
- ckstrncpy(fullname,buf,CKMAXPATH); /* Copy back to original buffer. */
- debug(F111,"nzrtol sizing",fullname,n);
- }
-#endif /* NOTRUNCATE */
-
- if (!fncnv || devnull) { /* Not converting */
- ckstrncpy(name2,fullname,max); /* We're done. */
- return;
- }
- name = fullname; /* Converting */
-
- p = name2;
- for (; *name != '\0' && n < maxnam; name++) {
- if (*name > SP) flag = 1; /* Strip leading blanks and controls */
- if (flag == 0 && *name < '!')
- continue;
- if (fncnv > 0) {
- if (*name == SP) {
- *p++ = '_';
- n++;
- continue;
- }
- if (isupper(*name)) /* Check for mixed case */
- acase |= 1;
- else if (islower(*name))
- acase |= 2;
- }
- *p++ = *name;
- n++;
- }
- *p-- = '\0'; /* Terminate */
- while (*p < '!' && p > name2) /* Strip trailing blanks & controls */
- *p-- = '\0';
-
- if (*name2 == '\0') { /* Nothing left? */
- ckstrncpy(name2,"NONAME",max); /* do this... */
- } else if (acase == 1) { /* All uppercase? */
- p = name2; /* So convert all letters to lower */
- while (*p) {
- if (isupper(*p))
- *p = tolower(*p);
- p++;
- }
- }
- debug(F110,"nzrtol new name",name2,0);
-}
-
-
-/* Z S T R I P -- Strip device & directory name from file specification */
-
-/* Strip pathname from filename "name", return pointer to result in name2 */
-
-static char work[CKMAXPATH+1];
-
-VOID
-zstrip(name,name2) char *name, **name2; {
- char *cp, *pp;
- int n = 0;
-
- debug(F110,"zstrip before",name,0);
- if (!name) { *name2 = ""; return; }
- pp = work;
-#ifdef DTILDE
- /* Strip leading tilde */
- if (*name == '~') name++;
- debug(F110,"zstrip after tilde-stripping",name,0);
-#endif /* DTILDE */
- for (cp = name; *cp; cp++) {
- if (ISDIRSEP(*cp)) {
- pp = work;
- n = 0;
- } else {
- *pp++ = *cp;
- if (n++ >= CKMAXPATH)
- break;
- }
- }
- *pp = '\0'; /* Terminate the string */
- *name2 = work;
- debug(F110,"zstrip after",*name2,0);
-}
-
-/* Z L T O R -- Local TO Remote */
-
-VOID
-zltor(name,name2) char *name, *name2; {
- nzltor(name,name2,1,0,CKMAXPATH);
-}
-
-/* N Z L T O R -- New Local TO Remote */
-
-/*
- fncnv = 0 for no conversion, > 0 for regular conversion, < 0 for minimal.
-*/
-VOID
-nzltor(name,name2,fncnv,fnspath,max)
- char *name, *name2; int fncnv, fnspath, max;
-{ /* nzltor */
- char *cp, *pp;
-#ifdef COMMENT
- int dc = 0;
-#endif /* COMMENT */
- int n = 0;
- char *dotp = NULL;
- char *dirp = NULL;
- char fullname[CKMAXPATH+1];
- char *p;
- CHAR c;
-
-#ifndef NOCSETS
- extern int fcharset, /* tcharset, */ language;
- int langsv;
- _PROTOTYP ( CHAR (*sxo), (CHAR) ) = NULL; /* Translation functions */
-#ifdef CK_ANSIC
- extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(CHAR);
-#else
- extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])();
-#endif /* CK_ANSIC */
- langsv = language;
- language = L_USASCII;
-#ifdef COMMENT
- /* Proper translation of filenames must be done elsewhere */
- n = tcharset ? tcharset : TC_USASCII;
- sxo = xls[n][fcharset];
-#else
- sxo = xls[TC_USASCII][fcharset];
-#endif /* COMMENT */
-#endif /* NOCSETS */
-
- debug(F110,"nzltor name",name,0);
-
- /* Handle pathname */
-
- fullname[0] = NUL;
- if (fnspath == PATH_OFF) { /* PATHNAMES OFF */
- zstrip(name,&p);
- ckstrncpy(fullname,p,CKMAXPATH);
- } else { /* PATHNAMES RELATIVE or ABSOLUTE */
- char * p = name;
- while (1) {
- if (!strncmp(p,"../",3))
- p += 3;
- else if (!strncmp(p,"./",2))
- p += 2;
- else
- break;
- }
- if (fnspath == PATH_ABS) { /* ABSOLUTE */
- zfnqfp(p,CKMAXPATH,fullname);
- } else { /* RELATIVE */
- ckstrncpy(fullname,p,CKMAXPATH);
- }
- }
- debug(F110,"nzltor fullname",fullname,0);
-
- if (!fncnv) { /* Not converting */
- ckstrncpy(name2,fullname,max); /* We're done. */
-#ifndef NOCSETS
- langsv = language;
-#endif /* NOCSETS */
- return;
- }
- name = fullname; /* Converting */
-
-#ifdef aegis
- char *namechars;
- int tilde = 0, bslash = 0;
-
- if ((namechars = getenv("NAMECHARS")) != NULL) {
- if (ckstrchr(namechars, '~' ) != NULL) tilde = '~';
- if (ckstrchr(namechars, '\\') != NULL) bslash = '\\';
- } else {
- tilde = '~';
- bslash = '\\';
- }
-#endif /* aegis */
-
- pp = work; /* Output buffer */
- for (cp = name, n = 0; *cp && n < max; cp++,n++) { /* Convert name chars */
- c = *cp;
-#ifndef NOCSETS
- if (sxo) c = (*sxo)(c); /* Convert to ASCII */
-#endif /* NOCSETS */
- if (fncnv > 0 && islower(c)) /* Uppercase letters */
- *pp++ = toupper(c); /* Change tilde to hyphen */
- else if (c == '~')
- *pp++ = '-';
- else if (fncnv > 0 && c == '#') /* Change number sign to 'X' */
- *pp++ = 'X';
- else if (c == '*' || c == '?') /* Change wildcard chars to 'X' */
- *pp++ = 'X';
- else if (c == ' ') /* Change space to underscore */
- *pp++ = '_';
- else if (c < ' ') /* Change controls to 'X' */
- *pp++ = 'X';
- else if (fncnv > 0 && c == '.') { /* Change dot to underscore */
- dotp = pp; /* Remember where we last did this */
- *pp++ = '_';
- } else {
- if (c == '/')
- dirp = pp;
- *pp++ = c;
- }
- }
- *pp = NUL; /* Tie it off. */
-#ifdef COMMENT
- if (dotp) *dotp = '.'; /* Restore last dot (if any) */
-#else
- if (dotp > dirp) *dotp = '.'; /* Restore last dot in file name */
-#endif /* COMMENT */
- cp = name2; /* If nothing before dot, */
- if (*work == '.') *cp++ = 'X'; /* insert 'X' */
- ckstrncpy(cp,work,max);
-#ifndef NOCSETS
- language = langsv;
-#endif /* NOCSETS */
- debug(F110,"nzltor name2",name2,0);
-}
-
-
-/* Z C H D I R -- Change directory */
-/*
- Call with:
- dirnam = pointer to name of directory to change to,
- which may be "" or NULL to indicate user's home directory.
- Returns:
- 0 on failure
- 1 on success
-*/
-int
-zchdir(dirnam) char *dirnam; {
- char *hd, *sp;
-#ifdef IKSDB
- _PROTOTYP (int slotdir,(char *,char *));
-#endif /* IKSDB */
-#ifndef NOSPL
- extern struct mtab *mactab; /* Main macro table */
- extern int nmac; /* Number of macros */
-#endif /* NOSPL */
-
- debug(F110,"zchdir",dirnam,0);
- if (!dirnam) dirnam = "";
- if (!*dirnam) /* If argument is null or empty, */
- dirnam = zhome(); /* use user's home directory. */
- sp = dirnam;
- debug(F110,"zchdir 2",dirnam,0);
-
-#ifdef DTILDE
- hd = tilde_expand(dirnam); /* Attempt to expand tilde */
- if (!hd) hd = "";
- if (*hd == '\0') hd = dirnam; /* in directory name. */
-#else
- hd = dirnam;
-#endif /* DTILDE */
- debug(F110,"zchdir 3",hd,0);
-
-#ifdef CKROOT
- debug(F111,"zchdir setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(hd)) {
- debug(F110,"zchdir setroot violation",hd,0);
- return(0);
- }
-#endif /* CKROOT */
-
-#ifdef pdp11
- /* Just to save some space */
- return((chdir(hd) == 0) ? 1 : 0);
-#else
- if (chdir(hd) == 0) { /* Try to cd */
-#ifdef IKSDB
-#ifdef CK_LOGIN
- if (inserver && ikdbopen)
- slotdir(isguest ? anonroot : "", zgtdir());
-#endif /* CK_LOGIN */
-#endif /* IKSDB */
-
-#ifndef NOSPL
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- static int on_cd = 0;
- if (!on_cd) {
- on_cd = 1;
- k = mlook(mactab,"on_cd",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,zgtdir(),0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- on_cd = 0;
- }
- }
-#endif /* NOSPL */
- return(1);
- }
- return(0);
-#endif /* pdp11 */
-}
-
-int
-#ifdef CK_ANSIC
-zchkpid(unsigned long xpid)
-#else
-zchkpid(xpid) unsigned long xpid;
-#endif /* CK_ANSIC */
-{
- return((kill((PID_T)xpid,0) < 0) ? 0 : 1);
-}
-
-
-/* Z H O M E -- Return pointer to user's home directory */
-
-static char * zhomdir = NULL;
-
-char *
-zhome() {
- char * home;
-
-#ifdef CKROOT
- if (ckrootset)
- return((char *)ckroot);
-#endif /* CKROOT */
-
-#ifdef Plan9
- home = getenv("home");
-#else
- home = getenv("HOME");
-#endif /* Plan9 */
- makestr(&zhomdir,home);
- return(home ? zhomdir : ".");
-}
-
-/* Z G T D I R -- Returns a pointer to the current directory */
-
-/*
- The "preferred" interface for getting the current directory in modern UNIX
- is getcwd() [POSIX 1003.1 5.2.2]. However, on certain platforms (such as
- SunOS), it is implemented by forking a shell, feeding it the pwd command,
- and returning the result, which is not only inefficient but also can result
- in stray messages to the terminal. In such cases -- as well as when
- getcwd() is not available at all -- getwd() can be used instead by defining
- USE_GETWD. However, note that getwd() provides no buffer-length argument
- and therefore no safeguard against memory leaks.
-*/
-#ifndef USE_GETWD
-#ifdef BSD42
-#define USE_GETWD
-#else
-#ifdef SUNOS4
-#define USE_GETWD
-#endif /* SUNOS4 */
-#endif /* BSD42 */
-#endif /* USE_GETWD */
-
-#ifdef pdp11
-#define CWDBL 80 /* Save every byte we can... */
-#else
-#define CWDBL CKMAXPATH
-#endif /* pdp11 */
-static char cwdbuf[CWDBL+2];
-/*
- NOTE: The getcwd() prototypes are commented out on purpose. If you get
- compile-time warnings, search through your system's header files to see
- which one has the needed prototype, and #include it. Usually it is
- <unistd.h>. See the section for including <unistd.h> in ckcdeb.h and
- make any needed adjustments there (and report them).
-*/
-char *
-zgtdir() {
- char * buf = cwdbuf;
- char * s;
-
-#ifdef USE_GETWD
- extern char *getwd();
- s = getwd(buf);
- debug(F110,"zgtdir BSD4 getwd()",s,0);
- if (!s) s = "./";
- return(s);
-#else
-#ifdef BSD44
-#ifdef DCLGETCWD
-_PROTOTYP( char * getcwd, (char *, SIZE_T) );
-#endif /* DCLGETCWD */
- debug(F101,"zgtdir BSD44 CWDBL","",CWDBL);
- s = getcwd(buf,CWDBL);
- if (!s) s = "./";
- return(s);
-#else
-#ifdef MINIX2
-#ifdef DCLGETCWD
- _PROTOTYP( char * getcwd, (char *, SIZE_T) );
-#endif /* DCLGETCWD */
- debug(F101,"zgtdir MINIX2 CWDBL","",CWDBL);
- s = getcwd(buf,CWDBL);
- if (!s) s = "./";
- return(s);
-#else
-#ifdef SVORPOSIX
-#ifdef COMMENT
-/* This non-ANSI prototype can be fatal at runtime! (e.g. in SCO3.2v5.0.5). */
-/* Anyway it's already prototyped in some header file that we have included. */
- extern char *getcwd();
-#else
-#ifdef DCLGETCWD
- _PROTOTYP( char * getcwd, (char *, SIZE_T) );
-#endif /* DCLGETCWD */
-#endif /* COMMENT */
- debug(F101,"zgtdir SVORPOSIX CWDBL","",CWDBL);
- s = getcwd(buf,CWDBL);
- if (!s) s = "./";
- return(s);
-#else
-#ifdef COHERENT
-#ifdef _I386
-#ifdef DCLGETCWD
- extern char *getcwd();
-#endif /* DCLGETCWD */
- debug(F101,"zgtdir COHERENT _I386 CWDBL","",CWDBL);
- s = getcwd(buf,CWDBL);
- if (!s) s = "./";
- return(s);
-#else
- extern char *getwd();
- debug(F101,"zgtdir COHERENT CWDBL","",CWDBL);
- s = getwd(buf);
- if (!s) s = "./";
- return(s);
-#endif /* _I386 */
-#else
-#ifdef SUNOS4
- debug(F101,"zgtdir SUNOS CWDBL","",CWDBL);
- s = getcwd(buf,CWDBL);
- if (!s) s = "./";
- return(s);
-#else
- return("./");
-#endif /* SUNOS4 */
-#endif /* COHERENT */
-#endif /* SYSVORPOSIX */
-#endif /* MINIX2 */
-#endif /* BSD44 */
-#endif /* USE_GETWD */
-}
-
-/* Z X C M D -- Run a system command so its output can be read like a file */
-
-#ifndef NOPUSH
-int
-zxcmd(filnum,comand) int filnum; char *comand; {
- int out;
- int pipes[2];
- extern int kactive; /* From ckcpro.w and ckcmai.c */
-
- if (nopush) {
- debug(F100,"zxcmd fails: nopush","",0);
- return(-1);
- }
- debug(F111,"zxcmd",comand,filnum);
- if (chkfn(filnum) < 0) return(-1); /* Need a valid Kermit file number. */
- if (filnum == ZSTDIO || filnum == ZCTERM) /* But not one of these. */
- return(0);
-
- out = (filnum == ZIFILE || filnum == ZRFILE) ? 0 : 1 ;
- debug(F101,"zxcmd out",comand,out);
-
-/* Output to a command */
-
- if (out) { /* Need popen() to do this. */
- ckstrncpy(fullname,"(pipe)",CKMAXPATH);
-#ifdef NOPOPEN
- return(0); /* no popen(), fail. */
-#else
-/* Use popen() to run the command. */
-
-#ifdef _POSIX_SOURCE
-/* Strictly speaking, popen() is not available in POSIX.1 */
-#define DCLPOPEN
-#endif /* _POSIX_SOURCE */
-
- debug(F110,"zxcmd out",comand,0);
-
- if (priv_chk()) {
- debug(F100,"zxcmd priv_chk failed","",0);
- return(0);
- }
- errno = 0;
- fp[filnum] = popen(comand,"w");
- debug(F111,"zxcmd popen",fp[filnum] ? "OK" : "Failed", errno);
- if (fp[filnum] == NULL)
- return(0);
-#ifdef COMMENT
-/* I wonder what this is all about... */
- close(pipes[0]); /* Don't need the input side */
- fp[filnum] = fdopen(pipes[1],"w"); /* Open output stream. */
- fp[ZSYSFN] = fp[filnum]; /* Remember. */
-#endif /* COMMENT */
- ispipe[filnum] = 1;
- zoutcnt = 0; /* (PWP) reset input buffer */
- zoutptr = zoutbuffer;
- return(1);
-#endif /* NOPOPEN */
- }
-
-/* Input from a command */
-
-#ifdef SNI541
- /* SINIX-L 5.41 does not like fdopen() */
- return(0);
-#else
- if (pipe(pipes) != 0) {
- debug(F100,"zxcmd pipe failure","",0);
- return(0); /* can't make pipe, fail */
- }
-
-/* Create a fork in which to run the named process */
-
- if ((
-#ifdef aegis
- pid = vfork() /* child */
-#else
- pid = fork() /* child */
-#endif /* aegis */
- ) == 0) {
-
-/* We're in the fork. */
-
- char *shpath, *shname, *shptr; /* Find user's preferred shell */
-#ifndef aegis
- struct passwd *p;
- char *defshell;
-#ifdef HPUX10 /* Default shell */
- defshell = "/usr/bin/sh";
-#else
-#ifdef Plan9
- defshell = "/bin/rc";
-#else
- defshell = "/bin/sh";
-#endif /* Plan9 */
-#endif /* HPUX10 */
-#endif /* aegis */
- if (priv_can()) exit(1); /* Turn off any privileges! */
- debug(F101,"zxcmd pid","",pid);
- close(pipes[0]); /* close input side of pipe */
- close(0); /* close stdin */
- if (open("/dev/null",0) < 0) return(0); /* replace input by null */
-#ifndef OXOS
-#ifndef SVORPOSIX
- dup2(pipes[1],1); /* BSD: replace stdout & stderr */
- dup2(pipes[1],2); /* by the pipe */
-#else
- close(1); /* AT&T: close stdout */
- if (dup(pipes[1]) != 1) /* Send stdout to the pipe */
- return(0);
- close(2); /* Send stderr to the pipe */
- if (dup(pipes[1]) != 2)
- return(0);
-#endif /* SVORPOSIX */
-#else /* OXOS */
- dup2(pipes[1],1);
- dup2(pipes[1],2);
-#endif /* OXOS */
- close(pipes[1]); /* Don't need this any more. */
-
-#ifdef aegis
- if ((shpath = getenv("SERVERSHELL")) == NULL)
- shpath = "/bin/sh";
-#else
- shpath = getenv("SHELL"); /* What shell? */
- if (shpath == NULL) {
- p = getpwuid( real_uid() ); /* Get login data */
- /* debug(F111,"zxcmd shpath","getpwuid()",p); */
- if (p == (struct passwd *)NULL || !*(p->pw_shell))
- shpath = defshell;
- else shpath = p->pw_shell;
- }
-#endif /* aegis */
- shptr = shname = shpath;
- while (*shptr != '\0')
- if (*shptr++ == '/')
- shname = shptr;
- debug(F110,shpath,shname,0);
- restorsigs(); /* Restore ignored signals */
- execl(shpath,shname,"-c",comand,(char *)NULL); /* Execute the cmd */
- exit(0); /* just punt if it failed. */
- } else if (pid == (PID_T) -1) {
- debug(F100,"zxcmd fork failure","",0);
- return(0);
- }
- debug(F101,"zxcmd pid","",pid);
- close(pipes[1]); /* Don't need the output side */
- ispipe[filnum] = 1; /* Remember it's a pipe */
- fp[filnum] = fdopen(pipes[0],"r"); /* Open a stream for input. */
-
-#ifdef DONDELAY
-#ifdef SELECT
- if (filnum == ZIFILE && kactive) { /* Make pipe reads nonblocking */
- int flags, x;
- if ((flags = fcntl(fileno(fp[filnum]),F_GETFL,0)) > -1) {
- debug(F101,"zxcmd fcntl 1 pipe flags","",flags);
- x = fcntl(fileno(fp[filnum]),F_SETFL, flags |
-#ifdef QNX
- O_NONBLOCK
-#else
- O_NDELAY
-#endif /* QNX */
- );
- debug(F101,"zxcmd fcntl 2 result","",x);
- }
- }
-#endif /* SELECT */
-#endif /* DONDELAY */
-#endif /* SNI541 */
- fp[ZSYSFN] = fp[filnum]; /* Remember. */
- zincnt = 0; /* (PWP) reset input buffer */
- zinptr = zinbuffer;
- fullname[0] = '\0';
- return(1);
-} /* zxcmd */
-
-/* Z C L O S F - wait for the child fork to terminate and close the pipe. */
-
-/* Used internally by zclose - returns -1 on failure, 1 on success. */
-
-int
-zclosf(filnum) int filnum; {
- int wstat, out;
- int statusp;
-
- debug(F101,"zclosf filnum","",filnum);
- out = (filnum == ZIFILE || filnum == ZRFILE) ? 0 : 1 ;
- debug(F101,"zclosf out","",out);
-
-#ifndef NOPOPEN
- if (ispipe[filnum]
- /* In UNIX we use popen() only for output files */
- && out
- ) {
- int x;
- x = pclose(fp[filnum]);
- pexitstat = x >> 8;
- debug(F101,"zclosf pclose","",x);
- debug(F101,"zclosf pexitstat","",pexitstat);
- fp[filnum] = fp[ZSYSFN] = NULL;
- ispipe[filnum] = 0;
- return((x != 0) ? -1 : 1);
- }
-#endif /* NOPOPEN */
- /* debug(F101,"zclosf fp[filnum]","", fp[filnum]); */
- /* debug(F101,"zclosf fp[ZSYSFN]","", fp[ZSYSFN]); */
-
- if (pid != (PID_T) 0) {
- debug(F101,"zclosf killing pid","",pid);
-#ifdef Plan9
- kill(pid, SIGKILL);
-#else
- kill(pid,9);
-#endif /* Plan9 */
-
-#ifndef CK_CHILD
-/*
- This is the original code (before 20 April 1997) and has proven totally
- portable. But it does not give us the process's return code.
-*/
- while ((wstat = wait((WAIT_T *)0)) != pid && wstat != -1) ;
-#else
-/* Here we try to get the return code. Let's hope this is portable too. */
- while ((wstat = wait(&statusp)) != pid && wstat != -1) ;
- pexitstat = (statusp & 0xff) ? statusp : statusp >> 8;
- debug(F101,"zclosf wait statusp","",statusp);
- debug(F101,"zclosf wait pexitstat","",pexitstat);
-#endif /* CK_CHILD */
- pid = 0;
- }
- fclose(fp[filnum]);
- fp[filnum] = fp[ZSYSFN] = NULL;
-
- ispipe[filnum] = 0;
- /* debug(F101,"zclosf fp[filnum]","",fp[filnum]); */
-#ifdef CK_CHILD
- return(pexitstat == 0 ? 1 : -1);
-#else
- return(1);
-#endif /* CK_CHILD */
-}
-
-#else /* NOPUSH */
-
-int
-zxcmd(filnum,comand) int filnum; char *comand; {
- return(0);
-}
-int
-zclosf(filnum) int filnum; {
- return(EOF);
-}
-#endif /* NOPUSH */
-
-
-/* Z X P A N D -- Expand a wildcard string into an array of strings */
-/*
- As of C-Kermit 7.0, this API is obsolete, replaced by nzxpand(), and this
- function is only used internally. See nzxpand() below.
-
- Returns the number of files that match fnarg, with data structures set up
- so that first file (if any) will be returned by the next znext() call.
-
- Depends on external variable wildxpand: 0 means we expand wildcards
- internally, nonzero means we call the shell to do it.
-
- AND in C-Kermit 8.0.212 and later, on extern wildena: 1 means wildcards
- are enabled, 0 means disabled, the characters are taken literally.
-*/
-static int xdironly = 0;
-static int xfilonly = 0;
-static int xmatchdot = 0;
-static int xrecursive = 0;
-static int xnobackup = 0;
-static int xnolinks = 0;
-
-static char *freeptr = NULL, **resptr = NULL; /* Copies of caller's args */
-static int remlen; /* Remaining space in caller's array */
-static int numfnd = 0; /* Number of matches found */
-
-#define MINSPACE 1024
-
-static int
-initspace(resarry,len) char * resarry[]; int len; {
-#ifdef DYNAMIC
- if (len < MINSPACE) len = MINSPACE;
- if (!sspace) { /* Need to allocate string space? */
- while (len >= MINSPACE) {
- if ((sspace = malloc(len+2))) { /* Got it. */
- debug(F101,"fgen string space","",len);
- break;
- }
- len = (len / 2) + (len / 4); /* Didn't, reduce by 3/4 */
- }
- if (len <= MINSPACE) { /* Did we get it? */
- fprintf(stderr,"fgen can't malloc string space\n");
- return(-1);
- }
- ssplen = len;
- }
-#endif /* DYNAMIC */
-
- freeptr = sspace; /* This is where matches are copied. */
- resptr = resarry; /* Static copies of these so */
- remlen = len; /* recursive calls can alter them. */
- debug(F101,"initspace ssplen","",ssplen);
- return(0);
-}
-
-/*
- Z S E T F I L -- Query or change the size of file list buffers.
-
- fc = 1: Change current string space to n, return new size.
- fc = 2: Return current string space size.
- fc = 3: Change current maxnames to n, return new maxnames.
- fc = 4: Return current maxnames.
- Returns < 0 on error.
-*/
-int
-zsetfil(n, fc) int n, fc; {
-#ifdef DYNAMIC
- switch (fc) {
- case 1: /* Stringspace */
- if (sspace) {
- free(sspace);
- sspace = NULL;
- }
- if (initspace(mtchs,n) < 0)
- return(-1);
- case 2: /* Fall thru deliberately */
- return(ssplen);
- case 3: /* Listsize */
- if (mtchs) {
- free((char *)mtchs);
- mtchs = NULL;
- }
- mtchs = (char **)malloc(n * sizeof(char *));
- if (!mtchs)
- return(-1);
- maxnames = n;
- case 4: /* Fall thru deliberately */
- return(maxnames);
- }
-#endif /* DYNAMIC */
- return(-1);
-}
-
-
-
-#ifndef NONZXPAND
-#ifndef pdp11
-static
-#endif /* pdp11 */
-#endif /* NONZXPAND */
-int
-zxpand(fnarg) char *fnarg; {
- extern int diractive;
- char fnbuf[CKMAXPATH+8], * fn, * p;
-
-#ifdef DTILDE /* Built with tilde-expansion? */
- char *tnam;
-#endif /* DTILDE */
- int x;
- int haveonedir = 0;
-
- if (!fnarg) { /* If no argument provided */
- nxpand = fcount = 0;
- return(0); /* Return zero files found */
- }
- debug(F110,"zxpand entry",fnarg,0);
- debug(F101,"zxpand xdironly","",xdironly);
- debug(F101,"zxpand xfilonly","",xfilonly);
-
- if (!*fnarg) { /* If no argument provided */
- nxpand = fcount = 0;
- return(0); /* Return zero files found */
- }
-
-#ifdef CKROOT
- debug(F111,"zxpand setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(fnarg)) {
- debug(F110,"zxpand setroot violation",fnarg,0);
- nxpand = fcount = 0;
- return(0);
- }
-#endif /* CKROOT */
-
-#ifdef COMMENT
-/*
- This would have been perfect, except it makes us return fully qualified
- pathnames for all files.
-*/
- zfnqfp(fnarg,CKMAXPATH,fnbuf);
- debug(F110,"zxpand zfnqfp",fnbuf,0);
- s = zgtdir();
- debug(F110,"zxpand zgtdir",s,0);
- p = fnbuf;
- while (*p && *s) /* Make it relative */
- if (*s++ != *p++)
- break;
- fn = (*s) ? fnbuf : p;
- debug(F110,"zxpand fn 0",fn,0);
- if (!*fn) {
- fn = fnbuf;
- fnbuf[0] = '*';
- fnbuf[1] = '\0';
- }
- debug(F110,"zxpand fn 0.5",fn,0);
-#else
-#ifdef DTILDE /* Built with tilde-expansion? */
- if (*fnarg == '~') { /* Starts with tilde? */
- tnam = tilde_expand(fnarg); /* Try to expand it. */
- ckstrncpy(fnbuf,tnam,CKMAXPATH);
- } else
-#endif /* DTILDE */
- ckstrncpy(fnbuf,fnarg,CKMAXPATH);
- fn = fnbuf; /* Point to what we'll work with */
-#endif /* COMMENT */
- debug(F110,"zxpand fn 1",fn,0);
-
- if (!*fn) /* But make sure something is there */
- return(0);
-
- p = fn + (int)strlen(fn) - 1;
- if (*p == '/') { /* If last char = / it must be a dir */
- if (!xfilonly && !iswild(p)) haveonedir++;
- ckstrncat(fn, "*", CKMAXPATH+8); /* so append '*' */
- } else if (p > fn) { /* If ends in "/." */
- if (*(p-1) == '/' && *p == '.') /* change '.' to '*' */
- *p = '*';
- } else if (p == fn) { /* If it's '.' alone */
- if (*p == '.') /* change '.' to '*' */
- *p = '*';
- }
- debug(F110,"zxpand fn 2",fn,0);
- x = isdir(fn); /* Is it a directory? */
- debug(F111,"zxpand isdir 1",fn,x);
- if (x) { /* If so, make it into a wildcard */
- if (!xfilonly && !iswild(p))
- haveonedir++;
- if ((x = strlen(fn)) > 0) {
- if (!ISDIRSEP(fn[x-1]))
- fn[x++] = DIRSEP;
- fn[x++] = '*';
- fn[x] = '\0';
- }
- }
- debug(F111,"zxpand fn 3 haveonedir",fn,haveonedir);
-/*
- The following allows us to parse a single directory name without opening
- the directory and looking at its contents. The diractive flag is a horrible
- hack (especially since DIR /NORECURSIVE turns it off), but otherwise we'd
- have to change the API.
-*/
- debug(F111,"zxpand fn 3 diractive",fn,diractive);
- if (!diractive && haveonedir) {
- fcount = 0;
- if (!mtchs) {
- mtchs = (char **)malloc(maxnames * sizeof(*mtchs));
- if (!mtchs)
- return(nxpand = fcount);
- }
- fcount = 1;
- debug(F110,"zxpand haveonedir A1",fnarg,0);
- initspace(mtchs,ssplen);
- addresult(fnarg,1);
- if (numfnd < 0) return(-1);
- mtchptr = mtchs; /* Save pointer for next. */
- debug(F111,"zxpand haveonedir A2",*mtchptr,numfnd);
- return(nxpand = fcount);
- }
-
-#ifndef NOPUSH
- if (!nopush && wildxpand) /* Who is expanding wildcards? */
- fcount = (mtchs == NULL && /* Shell */
- (mtchs = (char **)malloc(maxnames * sizeof(*mtchs))) == NULL)
- ? 0
- : shxpand(fn,mtchs,maxnames);
- else
-#endif /* NOPUSH */
- fcount = (mtchs == NULL && /* Kermit */
- (mtchs = (char **)malloc(maxnames * sizeof(*mtchs))) == NULL)
- ? 0
- : fgen(fn,mtchs,maxnames); /* Look up the file. */
-
- if (fcount == 0 && haveonedir) {
- fcount = 1;
- debug(F110,"zxpand haveonedir B",fnarg,0);
- addresult(fnarg,1);
- if (numfnd < 0) return(-1);
- }
- mtchptr = mtchs; /* Save pointer for next. */
- nxpand = fcount;
-
-#ifdef DEBUG
- if (deblog) {
- if (fcount > 1)
- debug(F111,"zxpand ok",mtchs[0],fcount);
- else
- debug(F101,"zxpand fcount","",fcount);
- }
-#endif /* DEBUG */
- return(fcount);
-}
-
-#ifndef NONZXPAND
-/* N Z X P A N D -- Expand a file list, with options. */
-/*
- Call with:
- s = pointer to filename or pattern.
- flags = option bits:
-
- flags & ZX_FILONLY Match regular files
- flags & ZX_DIRONLY Match directories
- flags & ZX_RECURSE Descend through directory tree
- flags & ZX_MATCHDOT Match "dot files"
- flags & ZX_NOBACKUP Don't match "backup files"
- flags & ZX_NOLINKS Don't follow symlinks.
-
- Returns the number of files that match s, with data structures set up
- so that first file (if any) will be returned by the next znext() call.
-*/
-int
-nzxpand(s,flags) char * s; int flags; {
- char * p;
- int x;
-
- debug(F111,"nzxpand",s,flags);
- x = flags & (ZX_DIRONLY|ZX_FILONLY);
- xdironly = (x == ZX_DIRONLY);
- xfilonly = (x == ZX_FILONLY);
- if (xdironly && xfilonly) {
- xdironly = 0;
- xfilonly = 0;
- }
- xmatchdot = (flags & ZX_MATCHDOT);
- debug(F111,"nzxpand xmatchdot 1",s,xmatchdot);
- /* If xmatchdot not set by caller but pattern implies it, set it anyway */
- if (!xmatchdot && ((p = ckstrchr(s,'.')))) {
- if (p == s && p[1] != '/') {
- xmatchdot = 1;
- debug(F111,"nzxpand xmatchdot 2",s,xmatchdot);
- } else if (p > s) {
- xmatchdot = (*(p-1) == ',') || (*(p-1) == '{') || (*(p-1) == '/');
- debug(F111,"nzxpand xmatchdot 3",s,xmatchdot);
- }
- }
- xrecursive = (flags & ZX_RECURSE);
- xnobackup = (flags & ZX_NOBACKUP);
- xnolinks = (flags & ZX_NOLINKS);
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"nzxpand xdironly","",xdironly);
- debug(F101,"nzxpand xfilonly","",xfilonly);
- debug(F101,"nzxpand xmatchdot","",xmatchdot);
- debug(F101,"nzxpand xrecursive","",xrecursive);
- debug(F101,"nzxpand xnobackup","",xnobackup);
- debug(F101,"nzxpand xnolinks","",xnolinks);
- }
-#endif /* DEBUG */
-
- x = zxpand(s);
- if (x > 1)
- sh_sort(mtchs,NULL,x,0,0,1); /* Alphabetize the list */
- xdironly = 0;
- xfilonly = 0;
- xmatchdot = 0;
- xrecursive = 0;
- xnobackup = 0;
- xnolinks = 0;
- return(x);
-}
-#endif /* NONZXPAND */
-
-#ifndef NOZXREWIND
-/* Z X R E W I N D -- Rewinds the zxpand() list */
-
-int
-zxrewind() {
- /* if (!mtchs) return(-1); */
- fcount = nxpand;
- mtchptr = mtchs;
- return(nxpand);
-}
-#endif /* NOZXREWIND */
-
-/* Z N E X T -- Get name of next file from list created by zxpand(). */
-/*
- Returns >0 if there's another file, with its name copied into the arg string,
- or 0 if no more files in list.
-*/
-int
-znext(fn) char *fn; {
- if (fcount-- > 0) {
- ckstrncpy(fn,*mtchptr++,CKMAXPATH);
- } else {
- fn[0] = '\0';
- }
-#ifndef COMMENT
- debug(F111,"znext",fn,fcount+1);
- return(fcount+1);
-#else
- debug(F111,"znext",fn,fcount); /* Return 0 if no filename to return */
- return(fcount);
-#endif /* COMMENT */
-}
-
-/* Z C H K S P A -- Check if there is enough space to store the file */
-
-/*
- Call with file specification f, size n in bytes.
- Returns -1 on error, 0 if not enough space, 1 if enough space.
-*/
-/*ARGSUSED*/
-int
-#ifdef CK_ANSIC
-zchkspa(char *f, CK_OFF_T n)
-#else
-zchkspa(f,n) char *f; CK_OFF_T n;
-#endif /* CK_ANSIC */
-/* zchkspa() */ {
- /* In UNIX there is no good (and portable) way. */
- return(1); /* Always say OK. */
-}
-
-#ifdef COMMENT /* (not used) */
-
-/* I S B A C K U P -- Tells if given file has a backup suffix */
-/*
- Returns:
- -1: Invalid argument
- 0: File does not have a backup suffix
- >0: Backup suffix number
-*/
-int
-isbackup(fn) char * fn; { /* Get backup suffix number */
- int i, j, k, x, state, flag;
-
- if (!fn) /* Watch out for null pointers. */
- return(-1);
- if (!*fn) /* And empty names. */
- return(-1);
-
- flag = state = 0;
- for (i = (int)strlen(fn) - 1; (!flag && (i > 0)); i--) {
- switch (state) {
- case 0: /* State 0 - final char */
- if (fn[i] == '~') /* Is tilde */
- state = 1; /* Switch to next state */
- else /* Otherwise */
- flag = 1; /* Quit - no backup suffix. */
- break;
- case 1: /* State 1 - digits */
- if (fn[i] == '~' && fn[i-1] == '.') { /* Have suffix */
- return(atoi(&fn[i+1]));
- } else if (fn[i] >= '0' && fn[i] <= '9') { /* In number part */
- continue; /* Keep going */
- } else { /* Something else */
- flag = 1; /* Not a backup suffix - quit. */
- }
- break;
- }
- }
- return(0);
-}
-#endif /* COMMENT */
-
-
-/* Z N E W N -- Make a new name for the given file */
-
-/*
- Given the name, fn, of a file that already exists, this function builds a
- new name of the form "<oldname>.~<n>~", where <oldname> is argument name
- (fn), and <n> is a version number, one higher than any existing version
- number for that file, up to 99999. This format is consistent with that used
- by GNU EMACS. If the constructed name is too long for the system's maximum,
- enough characters are truncated from the end of <fn> to allow the version
- number to fit. If no free version numbers exist between 1 and 99999, a
- version number of "xxxx" is used. Returns a pointer to the new name in
- argument s.
-*/
-#ifdef pdp11
-#define ZNEWNBL 63 /* Name buffer length */
-#define ZNEWNMD 3 /* Max digits for version number */
-#else
-#define ZNEWNBL CKMAXPATH
-#define ZNEWNMD 4
-#endif /* pdp11 */
-
-#define MAXBUDIGITS 5
-
-static char znewbuf[ZNEWNBL+12];
-
-VOID
-znewn(fn,s) char *fn, **s; {
- char * buf; /* Pointer to buffer for new name */
- char * xp, * namepart = NULL; /* Pointer to filename part */
- struct zfnfp * fnfp; /* znfqfp() result struct pointer */
- int d = 0, t, fnlen, buflen;
- int n, i, k, flag, state;
- int max = MAXNAMLEN; /* Maximum name length */
- char * dname = NULL;
-
- buf = znewbuf;
- *s = NULL; /* Initialize return value */
- if (!fn) fn = ""; /* Check filename argument */
- i = strlen(fn);
-
-/* If incoming file already has a backup suffix, remove it. */
-/* Then we'll tack a new on later, which will be the highest for this file. */
-
- if (i <= max && i > 0 && fn[i-1] == '~') {
- char * p;
- i--;
- debug(F111,"znewn suffix removal",fn,i);
- if ((dname = (char *)malloc(i+1))) {
- ckstrncpy(dname,fn,i+1);
- p = dname;
- for (flag = state = 0; (!flag && (i > 0)); i--) {
- switch (state) {
- case 0: /* State 0 - final char */
- if (p[i] == '~') /* Is tilde */
- state = 1; /* Switch to next state */
- else /* Otherwise */
- flag = 1; /* Quit - no backup suffix. */
- break;
- case 1: /* State 1 - digits */
- if (p[i] == '~' && p[i-1] == '.') { /* Have suffix */
- p[i-1] = NUL; /* Trim it */
- fn = dname;
- debug(F111,"znewn suffix removal 2",fn,i);
- flag = 1; /* done */
- } else if (p[i] >= '0' && p[i] <= '9') { /* Number part */
- continue; /* Keep going */
- } else { /* Something else */
- flag = 1; /* Not a backup suffix - quit. */
- }
- break;
- }
- }
- }
- }
- if ((fnlen = strlen(fn)) < 1) { /* Get length */
- if (dname) free(dname);
- return;
- }
- debug(F111,"znewn",fn,fnlen);
-
- debug(F101,"znewn max 1","",max);
- if (max < 14) max = 14; /* Make max reasonable for any UNIX */
- if (max > ZNEWNBL) max = ZNEWNBL;
- debug(F101,"znewn max 2","",max);
-
- if ((fnfp = zfnqfp(fn, ZNEWNBL, buf))) { /* Get fully qualified name */
- namepart = fnfp->fname; /* Isolate the filename */
- k = strlen(fn); /* Length of name part */
- debug(F111,"znewn namepart",namepart,k);
- } else {
- if (dname) free(dname);
- return;
- }
- buflen = fnfp->len; /* Length of fully qualified name */
- debug(F111,"znewn len",buf,buflen);
-
- if (k + MAXBUDIGITS + 3 < max) { /* Backup name fits - no overflow */
- /* Make pattern for backup names */
- ckstrncpy(buf+buflen,".~*~",ZNEWNBL+12-buflen);
- n = nzxpand(buf,ZX_FILONLY); /* Expand the pattern */
- debug(F111,"znewn A matches",buf,n);
- while (n-- > 0) { /* Find any existing name.~n~ files */
- xp = *mtchptr++; /* Point at matching name */
- t = atoi(xp+buflen+2); /* Get number */
- if (t > d) d = t; /* Save d = highest version number */
- }
- sprintf(buf+buflen,".~%d~",d+1); /* Yes, make "name.~<d+1>~" */
- debug(F110,"znewn A newname",buf,0);
- } else { /* Backup name would be too long */
- int xlen; /* So we have to eat back into it */
- int delta;
- char buf2[ZNEWNBL+12];
-
- delta = max - k;
- debug(F101,"znewn B delta","",delta);
-
- for (i = MAXBUDIGITS; i > 0; i--) { /* In this case the format of */
- ckstrncpy(buf2,buf,ZNEWNBL+12); /* the backup name depends on */
- xlen = buflen - i - 3 + delta; /* how many digits are in the */
- ckstrncpy(buf2+xlen,".~*~",ZNEWNBL+12-xlen); /* backup number */
- n = nzxpand(buf2,ZX_FILONLY);
- debug(F111,"znewn B matches",buf2,n);
- if (n > 0)
- break;
- }
- while (n-- > 0) { /* Find any existing name.~n~ files */
- xp = *mtchptr++; /* Point at matching name */
- t = atoi(xp+xlen+2); /* Get number */
- if (t > d) d = t; /* Save d = highest version number */
- }
- if (d > 0) /* If the odometer turned over... */
- if ((d % 10) == 9) /* back up one space. */
- xlen--;
- sprintf(buf2+xlen,".~%d~",d+1); /* This just fits */
- ckstrncpy(buf,buf2,ZNEWNBL+12); /* (we could be more clever here...) */
- debug(F110,"znewn B new name",buf,0);
- }
- *s = buf; /* Point to new name */
- ck_znewn = d+1; /* Also make it available globally */
- if (dname) free(dname);
- return;
-}
-
-/* Z R E N A M E -- Rename a file */
-/*
- Call with old and new names.
- If new name is the name of a directory, the 'old' file is moved to
- that directory.
- Returns 0 on success, -1 on failure.
-*/
-int
-zrename(old,new) char *old, *new; {
- char *p, *s;
- int x;
-
- if (!old) old = "";
- if (!new) new = "";
- debug(F110,"zrename old",old,0);
- debug(F110,"zrename new",new,0);
- if (!*old) return(-1);
- if (!*new) return(-1);
-
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest)
- return(-1);
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-
-#ifdef CKROOT
- debug(F111,"zrename setroot",ckroot,ckrootset);
- if (ckrootset) {
- if (!zinroot(old)) {
- debug(F110,"zrename old: setroot violation",old,0);
- return(-1);
- }
- if (!zinroot(new)) {
- debug(F110,"zrename new: setroot violation",new,0);
- return(-1);
- }
- }
-#endif /* CKROOT */
-
- p = NULL;
- s = new;
-
- if (isdir(new)) {
- char *q = NULL;
- x = strlen(new);
- if (!(p = malloc(strlen(new) + strlen(old) + 2)))
- return(-1);
- strcpy(p,new); /* (safe) Directory part */
- if (!ISDIRSEP(*(new+x-1))) /* Separator, if needed */
- strcat(p,"/"); /* (safe) */
- zstrip(old,&q); /* Strip path part from old name */
- strcat(p,q); /* cat to new directory (safe) */
- s = p;
- debug(F110,"zrename dir",s,0);
- }
-#ifdef DEBUG
- else debug(F110,"zrename no dir",s,0);
-#endif /* DEBUG */
-
-#ifdef IKSD
- if (inserver && (!ENABLED(en_del))) {
- if (zchki(s) > -1) /* Destination file exists? */
- return(-1);
- }
-#endif /* IKSD */
-
- x = -1; /* Return code. */
-#ifdef RENAME
-/* Atomic, preferred, uses a single system call, rename(), if available. */
- x = rename(old,s);
- debug(F111,"zrename rename()",old,x);
- if (x) x = -1;
-#endif /* RENAME */
-
- /* If rename() failed or not available try link()/unlink() */
-
- if (x < 0) {
- if (zchko(old) > -1) { /* Requires write access to orignal */
- x = link(old,s);
- debug(F111,"zrename link()",old,x);
- if (x > -1) { /* Make a link with the new name. */
- x = unlink(old);
- debug(F111,"zrename unlink()",old,x);
- }
- /* If link/unlink failed copy and delete */
- if (x < 0) {
- x = zcopy(old,s);
- debug(F111,"zrename zcopy()",old,x);
- if (x > -1) {
- x = zdelet(old);
- debug(F111,"zrename zdelet()",old,x);
- }
- }
- }
- }
- fullname[0] = '\0'; /* Clear this out for next time. */
-
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_FC && ckxlogging) {
- zfnqfp(old,CKMAXPATH,fullname);
- tmp2[0] = '\0';
- zfnqfp(s,CKMAXPATH,tmp2);
- if (x > -1)
- syslog(LOG_INFO,"file[] %s: renamed to %s ok", fullname, tmp2);
- else
- syslog(LOG_INFO,"file[] %s: rename to %s failed (%m)",fullname,tmp2);
- }
-#endif /* CKSYSLOG */
-
- if (p) free(p);
- return(x);
-}
-
-/* Z C O P Y -- Copy a single file. */
-/*
- Call with source and destination names.
- If destination is a directory, the source file is
- copied to that directory with its original name.
- Returns:
- 0 on success.
- <0 on failure:
- -2 = source file is not a regular file.
- -3 = source file not found.
- -4 = permission denied.
- -5 = source and destination are the same file.
- -6 = i/o error.
- -1 = other error.
-*/
-int
-zcopy(source,destination) char *source, *destination; {
- char *src, *dst; /* Local pointers to filenames */
- int x, y, rc; /* Workers */
- int in = -1, out = -1; /* i/o file descriptors */
- struct stat srcbuf; /* Source file info buffer */
- int perms; /* Output file permissions */
- char buf[1024]; /* File copying buffer */
-
- if (!source) source = "";
- if (!destination) destination = "";
-
- debug(F110,"zcopy src arg",source,0);
- debug(F110,"zcopy dst arg",destination,0);
-
- if (!*source) return(-1);
- if (!*destination) return(-1);
-
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest)
- return(-4);
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-
-#ifdef CKROOT
- debug(F111,"zcopy setroot",ckroot,ckrootset);
- if (ckrootset) {
- if (!zinroot(source)) {
- debug(F110,"zcopy source: setroot violation",source,0);
- return(-1);
- }
- if (!zinroot(destination)) {
- debug(F110,"zcopy destination: setroot violation",destination,0);
- return(-1);
- }
- }
-#endif /* CKROOT */
-
- src = source;
- dst = destination;
-
- if (stat(src,&srcbuf) == 0) { /* Get source file info */
- struct stat dstbuf; /* Destination file info buffer */
- debug(F101,"STAT","",6);
- if (stat(dst,&dstbuf) == 0) {
- debug(F101,"STAT","",7);
- if (srcbuf.st_dev == dstbuf.st_dev)
- if (srcbuf.st_ino == dstbuf.st_ino) {
- debug(F100,"zcopy files identical: stat()","",0);
- return(-5);
- }
- }
- } else { /* stat() failed... */
- debug(F101,"STAT","",8);
- debug(F111,"source file not found",src,errno);
- return(-3);
- }
- fullname[0] = '\0'; /* Get full pathnames */
- if (zfnqfp(source,CKMAXPATH,fullname))
- src = fullname;
- debug(F110,"zcopy src",src,0);
- tmp2[0] = '\0';
- if (zfnqfp(destination,CKMAXPATH,tmp2))
- dst = tmp2;
- debug(F110,"zcopy dst 1",dst,0);
- if (!strcmp(src,dst)) { /* Src and dst are same file? */
- debug(F100,"zcopy files identical: strcmp()","",0); /* This... */
- return(-5); /* should not happen. */
- }
- if (isdir(src)) { /* Source file is a directory? */
- debug(F110,"zcopy source is directory",src,0);
- return(-2); /* Fail */
- }
- if (isdir(dst)) { /* Destination is a directory? */
- char *q = NULL; /* Yes, add filename to it. */
- x = strlen(dst);
- if (x < 1) return(-1);
- if (!ISDIRSEP(*(dst+x-1))) { /* Add separator if needed */
- tmp2[x++] = '/';
- tmp2[x] = '\0';
- }
- debug(F111,"zcopy dst 2",dst,x);
- zstrip(src,&q); /* Strip path part from old name */
- ckstrncpy(tmp2+x,q,CKMAXPATH-x); /* Concatenate it to new name */
- }
- debug(F110,"zcopy dst 3",dst,0);
-
-#ifdef IKSD
- if (inserver && (!ENABLED(en_del))) {
- if (zchki(dst) > -1) /* Destination file exists? */
- return(-4);
- }
-#endif /* IKSD */
-
- perms = umask(0); /* Get user's umask */
- umask(perms); /* Put it back! */
- perms ^= 0777; /* Flip the bits */
- perms &= 0666; /* Zero execute bits from umask */
- perms |= (srcbuf.st_mode & 0111); /* OR in source file's execute bits */
- rc = -1; /* Default return code */
- errno = 0; /* Reset errno */
- in = open(src, O_RDONLY, 0); /* Open source file */
- debug(F111,"zcopy open source",src,in);
- if (in > -1) { /* If open... */
- /* Open destination file */
-#ifdef O_TRUNC
- out = open(dst, O_WRONLY|O_CREAT|O_TRUNC, perms);
-#else
- out = open(dst, O_WRONLY|O_CREAT, perms);
-#endif /* O_TRUNC */
- debug(F111,"zcopy open dest",dst,out);
- if (out > -1) { /* If open... */
- while ((x = read(in,buf,1024)) > 0) { /* Copy in 1K blocks */
- y = write(out,buf,x);
- if (y < 0) { /* On write failure */
- x = -1;
- rc = -6; /* Indicate i/o error */
- break;
- }
- }
- debug(F101,"zcopy final read","",x);
- debug(F101,"zcopy errno","",errno);
- rc = (x == 0) ? 0 : -6; /* In case of read failure */
- }
- }
- if (in > -1) close(in); /* Close files */
- if (out > -1) close(out);
- if (rc == -1) { /* Set return code */
- switch (errno) {
- case ENOENT: rc = -3; break;
- case EACCES: rc = -4; break;
- case EIO: rc = -6;
- }
- }
-
-#ifdef CKSYSLOG
- if (rc > -1 && ckxsyslog >= SYSLG_FC && ckxlogging) {
- if (rc)
- syslog(LOG_INFO,"file[] %s: copy to %s failed (%m)", fullname, tmp2);
- else
- syslog(LOG_INFO,"file[] %s: copy to %s ok", fullname, tmp2);
- }
-#endif /* CKSYSLOG */
-
- return(rc);
-}
-
-/* Z S A T T R */
-/*
- Fills in a Kermit file attribute structure for the file which is to be sent.
- Returns 0 on success with the structure filled in, or -1 on failure.
- If any string member is null, then it should be ignored.
- If any numeric member is -1, then it should be ignored.
-*/
-#ifdef CK_PERMS
-
-#ifdef CK_GPERMS
-#undef CK_GPERMS
-#endif /* CK_GPERMS */
-
-#ifdef UNIX
-#ifndef S_IRUSR
-#define S_IRUSR 0400
-#endif /* S_IRUSR */
-#ifndef S_IWUSR
-#define S_IXUSR 0200
-#endif /* S_IWUSR */
-#ifndef S_IXUSR
-#define S_IXUSR 0100
-#endif /* S_IXUSR */
-#endif /* UNIX */
-
-#ifdef S_IRUSR
-#ifdef S_IWUSR
-#ifdef S_IXUSR
-#define CK_GPERMS
-#endif /* S_IXUSR */
-#endif /* S_IWUSR */
-#endif /* S_IRUSR */
-
-static char gperms[2];
-
-#endif /* CK_GPERMS */
-
-static char lperms[24];
-
-#ifdef CK_PERMS
-static char xlperms[24];
-
-/* Z S E T P E R M -- Set permissions of a file */
-
-int
-zsetperm(f,code) char * f; int code; {
- int x;
-#ifdef CK_SCO32V4
- mode_t mask;
-#else
- int mask;
-#endif /* CK_SCO32V4 */
- mask = code;
- if (inserver && guest) {
- debug(F110,"zsetperm guest",f,0);
- return(0);
- }
- x = chmod(f,mask);
- if (x < 0) {
- debug(F111,"zsetperm error",f,errno);
- return(0);
- }
- debug(F111,"zsetperm ok",f,mask);
- return(1);
-}
-
-/* Z G P E R M -- Get permissions of a file as an octal string */
-
-char *
-zgperm(f) char *f; {
- extern int diractive;
- int x; char *s = (char *)xlperms;
- struct stat buf;
- debug(F110,"zgperm",f,0);
- if (!f) return("----------");
- if (!*f) return("----------");
-
-#ifdef CKROOT
- debug(F111,"zgperm setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(f)) {
- debug(F110,"zgperm setroot violation",f,0);
- return("----------");
- }
-#endif /* CKROOT */
-
-#ifdef USE_LSTAT
- if (diractive)
- x = lstat(f,&buf);
- else
-#endif /* USE_LSTAT */
- x = stat(f,&buf);
- debug(F101,"STAT","",9);
- if (x < 0)
- return("----------");
- sprintf(s,"%o",buf.st_mode);
- debug(F110,"zgperm",s,0);
- return(s);
-}
-
-/* Like zgperm() but returns permissions in "ls -l" string format */
-
-static char xsperms[24];
-
-char *
-ziperm(f) char * f; {
- extern int diractive;
- int x; char *s = (char *)xsperms;
- struct stat buf;
- unsigned int perms = 0;
-
- debug(F110,"ziperm",f,0);
-
- if (!f) return(NULL);
- if (!*f) return(NULL);
-
- if (diractive && zgfs_mode != 0) {
- perms = zgfs_mode; /* zgetfs() already got them */
- } else {
-#ifdef USE_LSTAT
- if (diractive)
- x = lstat(f,&buf);
- else
-#endif /* USE_LSTAT */
- x = stat(f,&buf);
- debug(F101,"STAT","",10);
- if (x < 0)
- return("----------");
- perms = buf.st_mode;
- }
- switch (perms & S_IFMT) {
- case S_IFDIR:
- *s++ = 'd';
- break;
- case S_IFCHR: /* Character special */
- *s++ = 'c';
- break;
- case S_IFBLK: /* Block special */
- *s++ = 'b';
- break;
- case S_IFREG: /* Regular */
- *s++ = '-';
- break;
-#ifdef S_IFLNK
- case S_IFLNK: /* Symbolic link */
- *s++ = 'l';
- break;
-#endif /* S_IFLNK */
-#ifdef S_IFSOCK
- case S_IFSOCK: /* Socket */
- *s++ = 's';
- break;
-#endif /* S_IFSOCK */
-#ifdef S_IFIFO
-#ifndef Plan9
-#ifndef COHERENT
- case S_IFIFO: /* FIFO */
- *s++ = 'p';
- break;
-#endif /* COHERENT */
-#endif /* Plan9 */
-#endif /* S_IFIFO */
-#ifdef S_IFWHT
- case S_IFWHT: /* Whiteout */
- *s++ = 'w';
- break;
-#endif /* S_IFWHT */
- default: /* Unknown */
- *s++ = '?';
- break;
- }
- if (perms & S_IRUSR) /* Owner's permissions */
- *s++ = 'r';
- else
- *s++ = '-';
- if (perms & S_IWUSR)
- *s++ = 'w';
- else
- *s++ = '-';
- switch (perms & (S_IXUSR | S_ISUID)) {
- case 0:
- *s++ = '-';
- break;
- case S_IXUSR:
- *s++ = 'x';
- break;
- case S_ISUID:
- *s++ = 'S';
- break;
- case S_IXUSR | S_ISUID:
- *s++ = 's';
- break;
- }
- if (perms & S_IRGRP) /* Group permissions */
- *s++ = 'r';
- else
- *s++ = '-';
- if (perms & S_IWGRP)
- *s++ = 'w';
- else
- *s++ = '-';
- switch (perms & (S_IXGRP | S_ISGID)) {
- case 0:
- *s++ = '-';
- break;
- case S_IXGRP:
- *s++ = 'x';
- break;
- case S_ISGID:
- *s++ = 'S';
- break;
- case S_IXGRP | S_ISGID:
- *s++ = 's';
- break;
- }
- if (perms & S_IROTH) /* World permissions */
- *s++ = 'r';
- else
- *s++ = '-';
- if (perms & S_IWOTH)
- *s++ = 'w';
- else
- *s++ = '-';
- switch (
-#ifdef Plan9
- perms & (S_IXOTH)
-#else
- perms & (S_IXOTH | S_ISVTX)
-#endif
- ) {
- case 0:
- *s++ = '-';
- break;
- case S_IXOTH:
- *s++ = 'x';
- break;
-#ifndef Plan9
- case S_ISVTX:
- *s++ = 'T';
- break;
- case S_IXOTH | S_ISVTX:
- *s++ = 't';
- break;
-#endif /* Plan9 */
- }
- *s = '\0';
- debug(F110,"ziperm",xsperms,0);
- return((char *)xsperms);
-}
-
-#else
-
-char *
-zgperm(f) char *f; {
- return("----------");
-}
-char *
-ziperms(f) char *f; {
- return("----------");
-}
-#endif /* CK_PERMS */
-
-int
-zsattr(xx) struct zattr *xx; {
- CK_OFF_T k; int x;
- struct stat buf;
-
- k = iflen % 1024; /* File length in K */
- if (k) k = 1L;
- xx->lengthk = (iflen / 1024) + k;
- xx->type.len = 0; /* File type can't be filled in here */
- xx->type.val = "";
- if (*nambuf) {
- xx->date.val = zfcdat(nambuf); /* File creation date */
- xx->date.len = (int)strlen(xx->date.val);
- } else {
- xx->date.len = 0;
- xx->date.val = "";
- }
- xx->creator.len = 0; /* File creator */
- xx->creator.val = "";
- xx->account.len = 0; /* File account */
- xx->account.val = "";
- xx->area.len = 0; /* File area */
- xx->area.val = "";
- xx->password.len = 0; /* Area password */
- xx->password.val = "";
- xx->blksize = -1L; /* File blocksize */
- xx->xaccess.len = 0; /* File access */
- xx->xaccess.val = "";
- xx->encoding.len = 0; /* Transfer syntax */
- xx->encoding.val = 0;
- xx->disp.len = 0; /* Disposition upon arrival */
- xx->disp.val = "";
- xx->lprotect.len = 0; /* Local protection */
- xx->lprotect.val = "";
- xx->gprotect.len = 0; /* Generic protection */
- xx->gprotect.val = "";
- x = -1;
- if (*nambuf) x = stat(nambuf,&buf);
- debug(F101,"STAT","",11);
- if (x >= 0) {
- debug(F111,"zsattr buf.st_mode & 0777",nambuf,buf.st_mode & 0777);
- /* UNIX filemode as an octal string without filetype bits */
- sprintf(lperms,"%o",buf.st_mode & 0777);
- xx->lprotect.len = (int)strlen(lperms);
- xx->lprotect.val = (char *)lperms;
- x = 0;
-#ifdef CK_GPERMS
- /* Generic permissions only if we have stat.h symbols defined */
- if (buf.st_mode & S_IRUSR) x |= 1; /* Read */
- if (buf.st_mode & S_IWUSR) x |= (2+16); /* Write and Delete */
- if (buf.st_mode & S_IXUSR) x |= 4; /* Execute */
- gperms[0] = tochar(x);
- gperms[1] = NUL;
- xx->gprotect.len = 1;
- xx->gprotect.val = (char *)gperms;
-#endif /* CK_GPERMS */
- }
- debug(F111,"zsattr lperms",xx->lprotect.val,xx->lprotect.len);
- debug(F111,"zsattr gperms",xx->gprotect.val,xx->gprotect.len);
- xx->systemid.val = "U1"; /* U1 = UNIX */
- xx->systemid.len = 2; /* System ID */
- xx->recfm.len = 0; /* Record format */
- xx->recfm.val = "";
- xx->sysparam.len = 0; /* System-dependent parameters */
- xx->sysparam.val = "";
- xx->length = iflen; /* Length */
- return(0);
-}
-
-/* Z F C D A T -- Get file creation date */
-/*
- Call with pointer to filename.
- On success, returns pointer to modification date in yyyymmdd hh:mm:ss format.
- On failure, returns pointer to null string.
-*/
-static char datbuf[40];
-
-char *
-#ifdef CK_ANSIC
-zdtstr(time_t timearg)
-#else
-zdtstr(timearg) time_t timearg;
-#endif /* CK_ANSIC */
-/* zdtstr */ {
-#ifndef TIMESTAMP
- return("");
-#else
- struct tm * time_stamp;
- struct tm * localtime();
- int yy, ss;
-
- debug(F101,"zdtstr timearg","",timearg);
- if (timearg < 0)
- return("");
- time_stamp = localtime(&(timearg));
- if (!time_stamp) {
- debug(F100,"localtime returns null","",0);
- return("");
- }
-/*
- We assume that tm_year is ALWAYS years since 1900.
- Any platform where this is not the case will have problems
- starting in 2000.
-*/
- yy = time_stamp->tm_year; /* Year - 1900 */
- debug(F101,"zdtstr tm_year","",time_stamp->tm_year);
- if (yy > 1000) {
- debug(F101,"zstrdt YEAR-2000 ALERT 1: localtime year","",yy);
- }
- yy += 1900;
- debug(F101,"zdatstr year","",yy);
-
- if (time_stamp->tm_mon < 0 || time_stamp->tm_mon > 11)
- return("");
- if (time_stamp->tm_mday < 0 || time_stamp->tm_mday > 31)
- return("");
- if (time_stamp->tm_hour < 0 || time_stamp->tm_hour > 23)
- return("");
- if (time_stamp->tm_min < 0 || time_stamp->tm_min > 59)
- return("");
- ss = time_stamp->tm_sec; /* Seconds */
- if (ss < 0 || ss > 59) /* Some systems give a BIG number */
- ss = 0;
- sprintf(datbuf,
-#ifdef pdp11
-/* For some reason, 2.1x BSD sprintf gets the last field wrong. */
- "%04d%02d%02d %02d:%02d:00",
-#else
- "%04d%02d%02d %02d:%02d:%02d",
-#endif /* pdp11 */
- yy,
- time_stamp->tm_mon + 1,
- time_stamp->tm_mday,
- time_stamp->tm_hour,
- time_stamp->tm_min
-#ifndef pdp11
- , ss
-#endif /* pdp11 */
- );
- yy = (int)strlen(datbuf);
- debug(F111,"zdatstr",datbuf,yy);
- if (yy > 17) datbuf[17] = '\0';
- return(datbuf);
-#endif /* TIMESTAMP */
-}
-
-char *
-zfcdat(name) char *name; {
-#ifdef TIMESTAMP
- struct stat buffer;
- extern int diractive;
- unsigned int mtime;
- int x;
- char * s;
-
- if (!name)
- return("");
- s = name;
- if (!*s)
- return("");
-
-#ifdef CKROOT
- debug(F111,"zfcdat setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(name)) {
- debug(F110,"zfcdat setroot violation",name,0);
- return("");
- }
-#endif /* CKROOT */
-
-#ifdef DTILDE
- if (*s == '~') {
- s = tilde_expand(s);
- if (!s) s = "";
- if (!*s) s = name;
- }
-#endif /* DTILDE */
-
- datbuf[0] = '\0';
- x = 0;
- debug(F111,"zfcdat",s,diractive);
-
- if (diractive && zgfs_mtime) {
- mtime = zgfs_mtime;
- } else {
-#ifdef USE_LSTAT
- if (diractive) {
- x = lstat(s,&buffer);
- debug(F101,"STAT","",12);
- debug(F101,"zfcdat lstat","",x);
- } else {
-#endif /* USE_LSTAT */
- x = stat(s,&buffer);
- debug(F101,"STAT","",13);
- debug(F101,"zfcdat stat","",x);
-#ifdef USE_LSTAT
- }
-#endif /* USE_LSTAT */
- if (x != 0) {
-#ifdef USE_LSTAT
- debug(F111,"zfcdat stat failed",s,errno);
-#else
- debug(F111,"zfcdat lstat failed",s,errno);
-#endif /* USE_LSTAT */
- return("");
- }
- debug(F101,"zfcdat buffer.st_mtime","",buffer.st_mtime);
- mtime = buffer.st_mtime;
- }
- return(zdtstr(mtime));
-#else
- return("");
-#endif /* TIMESTAMP */
-}
-
-#ifndef NOTIMESTAMP
-
-/* Z S T R D T -- Converts local date string to internal representation */
-/*
- In our case (UNIX) this is seconds since midnite 1 Jan 1970 UTC,
- suitable for comparison with UNIX file dates. As far as I know, there is
- no library or system call -- at least nothing reasonably portable -- to
- convert local time to UTC.
-*/
-time_t
-zstrdt(date,len) char * date; int len; {
-#ifdef M_UNIX
-/*
- SCO UNIX 3.2v2.0 and ODT 2.0 lack prototypes for ftime().
- ODT 3.0 (3.2v4.2 OS) has a prototype, which may vary in
- dependence on the XPG4 supplement presence. So always use
- what the system header file supplies in ODT 3.0...
-*/
-#ifndef ODT30
-#ifndef _SCO_DS
- extern void ftime(); /* extern void ftime(struct timeb *) */
-#endif /* _SCO_DS */
-#endif /* ODT30 */
-#else
-#ifndef M_XENIX
- extern int ftime();
-#endif /* M_XENIX */
-#endif /* M_UNIX */
- extern struct tm * localtime();
-
- /* And this should have been declared always through a header file */
-#ifdef HPUX10
- time_t tmx;
- long days;
-#else
-#ifdef BSD44
- time_t tmx;
- long days;
-#else
- long tmx, days;
-#endif /* BSD44 */
-#endif /* HPUX10 */
- int i, n, isleapyear;
- /* J F M A M J J A S O N D */
- /* 31 28 31 30 31 30 31 31 30 31 30 31 */
- static
- int monthdays [13] = { 0,0,31,59,90,120,151,181,212,243,273,304,334 };
- char s[5];
- struct tm *time_stamp;
-
-#ifdef BSD44
- struct timeval tp[2];
- long xtimezone = 0L;
-#else
-#ifdef V7
- struct utimbuf {
- time_t timep[2]; /* New access and modificaton time */
- } tp;
- char *tz;
- long timezone; /* In case timezone not defined in .h file */
-#else
-#ifdef SYSUTIMEH
- struct utimbuf tp;
-#else
- struct utimbuf {
- time_t atime;
- time_t mtime;
- } tp;
-#endif /* SYSUTIMEH */
-#endif /* V7 */
-#endif /* BSD44 */
-
-#ifdef ANYBSD
- long timezone = 0L;
- static struct timeb tbp;
-#endif /* ANYBSD */
-
-#ifdef BEBOX
- long timezone = 0L;
-#endif /* BEBOX */
-
- debug(F111,"zstrdt",date,len);
-
- if ((len == 0)
- || (len != 17)
- || (date[8] != ' ')
- || (date[11] != ':')
- || (date[14] != ':') ) {
- debug(F111,"Bad creation date ",date,len);
- return(-1);
- }
- debug(F111,"zstrdt date check 1",date,len);
- for(i = 0; i < 8; i++) {
- if (!isdigit(date[i])) {
- debug(F111,"Bad creation date ",date,len);
- return(-1);
- }
- }
- debug(F111,"zstrdt date check 2",date,len);
- i++;
-
- for (; i < 16; i += 3) {
- if ((!isdigit(date[i])) || (!isdigit(date[i + 1]))) {
- debug(F111,"Bad creation date ",date,len);
- return(-1);
- }
- }
- debug(F111,"zstrdt date check 3",date,len);
-
-
-#ifdef COMMENT /* was BSD44 */
-/*
- man gettimeofday on BSDI 3.1 says:
- "The timezone field is no longer used; timezone information is stored out-
- side the kernel. See ctime(3) for more information." So this chunk of
- code is effectively a no-op, at least in BSDI 3.x.
-*/
- {
- int x;
- struct timezone tzp;
- x = gettimeofday(NULL, &tzp);
- debug(F101,"zstrdt BSD44 gettimeofday","",x);
- if (x > -1)
- xtimezone = tzp.tz_minuteswest * 60L;
- else
- xtimezone = 0L;
- debug(F101,"zstrdt BSD44 timezone","",xtimezone);
- }
-#else
-#ifdef ANYBSD
- debug(F100,"zstrdt BSD calling ftime","",0);
- ftime(&tbp);
- debug(F100,"zstrdt BSD back from ftime","",0);
- timezone = tbp.timezone * 60L;
- debug(F101,"zstrdt BSD timezone","",timezone);
-#else
-#ifdef SVORPOSIX
- tzset(); /* Set timezone */
-#else
-#ifdef V7
- if ((tz = getenv("TZ")) == NULL)
- timezone = 0; /* UTC/GMT */
- else
- timezone = atoi(&tz[3]); /* Set 'timezone'. */
- timezone *= 60L;
-#endif /* V7 */
-#endif /* SVORPOSIX */
-#endif /* ANYBSD */
-#endif /* COMMENT (was BSD44) */
-
- debug(F100,"zstrdt so far so good","",0);
-
- s[4] = '\0';
- for (i = 0; i < 4; i++) /* Fix the year */
- s[i] = date[i];
-
- n = atoi(s);
- debug(F111,"zstrdt year",s,n);
- if (n < 1970) {
- debug(F100,"zstrdt fails - year","",n);
- return(-1);
- }
-
-/* Previous year's leap days. This won't work after year 2100. */
-
- isleapyear = (( n % 4 == 0 && n % 100 !=0) || n % 400 == 0);
- days = (long) (n - 1970) * 365;
- days += (n - 1968 - 1) / 4 - (n - 1900 - 1) / 100 + (n - 1600 - 1) / 400;
-
- s[2] = '\0';
-
- for (i = 4; i < 16; i += 2) {
- s[0] = date[i];
- s[1] = date[i + 1];
- n = atoi(s);
- switch (i) {
- case 4: /* MM: month */
- if ((n < 1 ) || ( n > 12)) {
- debug(F111,"zstrdt 4 bad date ",date,len);
- return(-1);
- }
- days += monthdays [n];
- if (isleapyear && n > 2)
- ++days;
- continue;
-
- case 6: /* DD: day */
- if ((n < 1 ) || ( n > 31)) {
- debug(F111,"zstrdt 6 bad date ",date,len);
- return(-1);
- }
- tmx = (days + n - 1) * 24L * 60L * 60L;
- i++; /* Skip the space */
- continue;
-
- case 9: /* hh: hour */
- if ((n < 0 ) || ( n > 23)) {
- debug(F111,"zstrdt 9 bad date ",date,len);
- return(-1);
- }
- tmx += n * 60L * 60L;
- i++; /* Skip the colon */
- continue;
-
- case 12: /* mm: minute */
- if ((n < 0 ) || ( n > 59)) {
- debug(F111,"zstrdt 12 bad date ",date,len);
- return(-1);
- }
-#ifdef COMMENT /* (was BSD44) */ /* Correct for time zone */
- tmx += xtimezone;
- debug(F101,"zstrdt BSD44 tmx","",tmx);
-#else
-#ifdef ANYBSD
- tmx += timezone;
-#else
-#ifndef CONVEX9 /* Don't yet know how to do this here */
-#ifdef ultrix
- tmx += (long) timezone;
-#else
-#ifdef Plan9
- {
- extern time_t tzoffset;
- tmx += tzoffset;
- }
-#else
-#ifndef BSD44
-#ifndef NOTIMEZONE
- tmx += timezone;
-#endif /* NOTIMEZONE */
-#endif /* BSD44 */
-#endif /* Plan9 */
-#endif /* ultrix */
-#endif /* CONVEX9 */
-#endif /* ANYBSD */
-#endif /* COMMENT (was BSD44) */
- tmx += n * 60L;
- i++; /* Skip the colon */
- continue;
-
- case 15: /* ss: second */
- if ((n < 0 ) || ( n > 59)) {
- debug(F111,"zstrdt 15 bad date ",date,len);
- return(-1);
- }
- tmx += n;
- }
- time_stamp = localtime(&tmx);
- debug(F101,"zstrdt tmx 1","",tmx);
- if (!time_stamp)
- return(-1);
-#ifdef COMMENT
- /* Why was this here? */
- time_stamp = localtime(&tmx);
- debug(F101,"zstrdt tmx 2","",tmx);
-#endif /* COMMENT */
-#ifdef BSD44
- { /* New to 7.0 - Works in at at least BSDI 3.1 and FreeBSD 2.2.7 */
- long zz;
- zz = time_stamp->tm_gmtoff; /* Seconds away from Zero Meridian */
- debug(F101,"zstrdt BSD44 tm_gmtoff","",zz);
- tmx -= zz;
- debug(F101,"zstrdt BSD44 tmx 3 (GMT)","",tmx);
- }
-#else
- /*
- Daylight Savings Time adjustment.
- Do this everywhere BUT in BSD44 because in BSD44,
- tm_gmtoff also includes the DST adjustment.
- */
- if (time_stamp->tm_isdst) {
- tmx -= 60L * 60L;
- debug(F101,"zstrdt tmx 3 (DST)","",tmx);
- }
-#endif /* BSD44 */
- n = time_stamp->tm_year;
- if (n < 300) {
- n += 1900;
- }
- }
- return(tmx);
-}
-
-
-#ifdef ZLOCALTIME
-/* Z L O C A L T I M E -- GMT/UTC time string to local time string */
-
-/*
- Call with: "yyyymmdd hh:mm:ss" GMT/UTC date-time.
- Returns: "yyyymmdd hh:mm:ss" local date-time on success, NULL on failure.
-*/
-static char zltimbuf[64];
-
-char *
-zlocaltime(gmtstring) char * gmtstring; {
-#ifdef M_UNIX
-/*
- SCO UNIX 3.2v2.0 and ODT 2.0 lack prototypes for ftime().
- ODT 3.0 (3.2v4.2 OS) has a prototype, which may vary in
- dependence on the XPG4 supplement presence. So always use
- what the system header file supplies in ODT 3.0...
-*/
-#ifndef ODT30
-#ifndef _SCO_DS
- extern void ftime(); /* extern void ftime(struct timeb *) */
-#endif /* _SCO_DS */
-#endif /* ODT30 */
-#else
-#ifndef M_XENIX
- extern int ftime();
-#endif /* M_XENIX */
-#endif /* M_UNIX */
- extern struct tm * localtime();
-
- /* And this should have been declared always through a header file */
-#ifdef HPUX10
- time_t tmx;
- long days;
-#else
-#ifdef BSD44
- time_t tmx;
- long days;
-#else
- long tmx, days;
-#endif /* BSD44 */
-#endif /* HPUX10 */
- int i, n, x, isleapyear;
- /* J F M A M J J A S O N D */
- /* 31 28 31 30 31 30 31 31 30 31 30 31 */
- static
- int monthdays [13] = { 0,0,31,59,90,120,151,181,212,243,273,304,334 };
- char s[5];
- struct tm *time_stamp;
-
-#ifdef BSD44
- struct timeval tp[2];
-#else
-#ifdef V7
- struct utimbuf {
- time_t timep[2]; /* New access and modificaton time */
- } tp;
-#else
-#ifdef SYSUTIMEH
- struct utimbuf tp;
-#else
- struct utimbuf {
- time_t atime;
- time_t mtime;
- } tp;
-#endif /* SYSUTIMEH */
-#endif /* V7 */
-#endif /* BSD44 */
-
-#ifdef ANYBSD
- static struct timeb tbp;
-#endif /* ANYBSD */
-
- char * date = gmtstring;
- int len;
-
- len = strlen(date);
- debug(F111,"zlocaltime",date,len);
-
- if ((len == 0)
- || (len != 17)
- || (date[8] != ' ')
- || (date[11] != ':')
- || (date[14] != ':') ) {
- debug(F111,"Bad creation date ",date,len);
- return(NULL);
- }
- debug(F111,"zlocaltime date check 1",date,len);
- for(i = 0; i < 8; i++) {
- if (!isdigit(date[i])) {
- debug(F111,"Bad creation date ",date,len);
- return(NULL);
- }
- }
- debug(F111,"zlocaltime date check 2",date,len);
- i++;
-
- for (; i < 16; i += 3) {
- if ((!isdigit(date[i])) || (!isdigit(date[i + 1]))) {
- debug(F111,"Bad creation date ",date,len);
- return(NULL);
- }
- }
- debug(F111,"zlocaltime date check 3",date,len);
-
- debug(F100,"zlocaltime so far so good","",0);
-
- s[4] = '\0';
- for (i = 0; i < 4; i++) /* Fix the year */
- s[i] = date[i];
-
- n = atoi(s);
- debug(F111,"zlocaltime year",s,n);
- if (n < 1970) {
- debug(F100,"zlocaltime fails - year","",n);
- return(NULL);
- }
-
-/* Previous year's leap days. This won't work after year 2100. */
-
- isleapyear = (( n % 4 == 0 && n % 100 !=0) || n % 400 == 0);
- days = (long) (n - 1970) * 365;
- days += (n - 1968 - 1) / 4 - (n - 1900 - 1) / 100 + (n - 1600 - 1) / 400;
-
- s[2] = '\0';
-
- for (i = 4; i < 16; i += 2) {
- s[0] = date[i];
- s[1] = date[i + 1];
- n = atoi(s);
- switch (i) {
- case 4: /* MM: month */
- if ((n < 1 ) || ( n > 12)) {
- debug(F111,"zlocaltime 4 bad date ",date,len);
- return(NULL);
- }
- days += monthdays [n];
- if (isleapyear && n > 2)
- ++days;
- continue;
-
- case 6: /* DD: day */
- if ((n < 1 ) || ( n > 31)) {
- debug(F111,"zlocaltime 6 bad date ",date,len);
- return(NULL);
- }
- tmx = (days + n - 1) * 24L * 60L * 60L;
- i++; /* Skip the space */
- continue;
-
- case 9: /* hh: hour */
- if ((n < 0 ) || ( n > 23)) {
- debug(F111,"zlocaltime 9 bad date ",date,len);
- return(NULL);
- }
- tmx += n * 60L * 60L;
- i++; /* Skip the colon */
- continue;
-
- case 12: /* mm: minute */
- if ((n < 0 ) || ( n > 59)) {
- debug(F111,"zlocaltime 12 bad date ",date,len);
- return(NULL);
- }
- tmx += n * 60L;
- i++; /* Skip the colon */
- continue;
-
- case 15: /* ss: second */
- if ((n < 0 ) || ( n > 59)) {
- debug(F111,"zlocaltime 15 bad date ",date,len);
- return(NULL);
- }
- tmx += n;
- }
-
-/*
- At this point tmx is the time_t representation of the argument date-time
- string without any timezone or DST adjustments. Therefore it should be
- the same as the time_t representation of the GMT/UTC time. Now we should
- be able to feed it to localtime() and have it converted to a struct tm
- representing the local time equivalent of the given UTC time.
-*/
- time_stamp = localtime(&tmx);
- if (!time_stamp)
- return(NULL);
- }
-
-/* Now we simply reformat the struct tm to a string */
-
- x = time_stamp->tm_year;
- if (time_stamp->tm_year < 70 || time_stamp->tm_year > 8099)
- return(NULL);
- if (time_stamp->tm_mon < 0 || time_stamp->tm_mon > 11)
- return(NULL);
- if (time_stamp->tm_mday < 1 || time_stamp->tm_mday > 31)
- return(NULL);
- if (time_stamp->tm_hour < 0 || time_stamp->tm_hour > 24)
- return(NULL);
- if (time_stamp->tm_min < 0 || time_stamp->tm_min > 60)
- return(NULL);
- if (time_stamp->tm_sec < 0 || time_stamp->tm_sec > 60)
- return(NULL);
- sprintf(zltimbuf,"%04d%02d%02d %02d:%02d:%02d",
- time_stamp->tm_year + 1900,
- time_stamp->tm_mon + 1,
- time_stamp->tm_mday,
- time_stamp->tm_hour,
- time_stamp->tm_min,
- time_stamp->tm_sec
- );
- return((char *)zltimbuf);
-}
-#endif /* ZLOCALTIME */
-#endif /* NOTIMESTAMP */
-
-/* Z S T I M E -- Set modification date/time+permissions for incoming file */
-/*
- Call with:
- f = pointer to name of existing file.
- yy = pointer to a Kermit file attribute structure in which yy->date.val
- is a date of the form yyyymmdd hh:mm:ss, e.g. 19900208 13:00:00.
- yy->lprotect.val & yy->gprotect.val are permission/protection values.
- x = is a function code: 0 means to set the file's attributes as given.
- 1 means compare the date in struct yy with the file creation date.
- Returns:
- -1 on any kind of error.
- 0 if x is 0 and the attributes were set successfully.
- 0 if x is 1 and date from attribute structure <= file creation date.
- 1 if x is 1 and date from attribute structure > file creation date.
-*/
-int
-zstime(f,yy,x)
- char *f; struct zattr *yy; int x;
-/* zstime */ {
- int r = -1; /* Return code */
-#ifdef CK_PERMS
- int setperms = 0;
-#endif /* CK_PERMS */
- int setdate = 0;
-
-/* It is ifdef'd TIMESTAMP because it might not work on V7. bk@kullmar.se. */
-
-#ifdef TIMESTAMP
-#ifdef BSD44
- extern int utimes();
-#else
- extern int utime();
-#endif /* BSD44 */
-
- struct stat sb;
-
-/* At least, the declarations for int functions are not needed anyway */
-
-#ifdef BSD44
- struct timeval tp[2];
- long xtimezone;
-#else
-#ifdef V7
- struct utimbuf {
- time_t timep[2]; /* New access and modificaton time */
- } tp;
- char *tz;
- long timezone; /* In case not defined in .h file */
-#else
-#ifdef SYSUTIMEH
- struct utimbuf tp;
-#else
- struct utimbuf {
- time_t atime;
- time_t mtime;
- } tp;
-#endif /* SYSUTIMEH */
-#endif /* V7 */
-#endif /* BSD44 */
-
- long tm = 0L;
-
- if (!f) f = "";
- if (!*f) return(-1);
- if (!yy) return(-1);
-
-#ifdef CKROOT
- debug(F111,"zstime setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(f)) {
- debug(F110,"zstime setroot violation",f,0);
- return(0);
- }
-#endif /* CKROOT */
-
- if (yy->date.len == 0) { /* No date in struct */
- if (yy->lprotect.len != 0) { /* So go do permissions */
- goto zsperms;
- } else {
- debug(F100,"zstime: nothing to do","",0);
- return(0);
- }
- }
- if ((tm = zstrdt(yy->date.val,yy->date.len)) < 0) {
- debug(F101,"zstime: zstrdt fails","",0);
- return(-1);
- }
- debug(F101,"zstime: tm","",tm);
- debug(F111,"zstime: A-pkt date ok ",yy->date.val,yy->date.len);
-
- if (stat(f,&sb)) { /* Get the time for the file */
- debug(F101,"STAT","",14);
- debug(F111,"zstime: Can't stat file:",f,errno);
- return(-1);
- }
- debug(F101,"STAT","",15);
- setdate = 1;
-
- zsperms:
-#ifdef CK_PERMS
- {
- int i, x = 0, xx, flag = 0;
- char * s;
-#ifdef DEBUG
- char obuf[24];
- if (deblog) {
- debug(F111,"zstime lperms",yy->lprotect.val,yy->lprotect.len);
- debug(F111,"zstime gperms",yy->gprotect.val,yy->gprotect.len);
- debug(F110,"zstime system id",yy->systemid.val,0);
- sprintf(obuf,"%o",sb.st_mode);
- debug(F110,"zstime file perms before",obuf,0);
- }
-#endif /* DEBUG */
-
-#ifdef CK_LOGIN
- debug(F101,"zstime isguest","",isguest);
- debug(F101,"zstime ckxperms","",ckxperms);
- if (isguest) {
-#ifdef COMMENT
- /* Clear owner permissions */
- sb.st_mode &= (unsigned) 0177077; /* (16 bits) */
-#else
- /* Set permissions from ckxperms variable */
- sb.st_mode = ckxperms;
-#endif /* COMMENT */
- debug(F101,"zstime isguest sb.st_mode","",sb.st_mode);
-#ifdef COMMENT
- /* We already set them in zopeno() */
- setperms = 1;
-#endif /* COMMENT */
- flag = 0;
- } else
-#endif /* CK_LOGIN */
- if ((yy->lprotect.len > 0 && /* Have local-format permissions */
- yy->systemid.len > 0 && /* from A-packet... */
-#ifdef UNIX
- !strcmp(yy->systemid.val,"U1") /* AND you are same as me */
-#else
- 0
-#endif /* UNIX */
- ) || (yy->lprotect.len < 0) /* OR by inheritance from old file */
- ) {
- flag = 1;
- s = yy->lprotect.val; /* UNIX filemode */
- xx = yy->lprotect.len;
- if (xx < 0) /* len < 0 means inheritance */
- xx = 0 - xx;
- for (i = 0; i < xx; i++) { /* Decode octal string */
- if (*s <= '7' && *s >= '0') {
- x = 8 * x + (int)(*s) - '0';
- } else {
- flag = 0;
- break;
- }
- s++;
- }
-#ifdef DEBUG
- sprintf(obuf,"%o",x);
- debug(F110,"zstime octal lperm",obuf,0);
-#endif /* DEBUG */
- } else if (!flag && yy->gprotect.len > 0) {
- int g;
-#ifdef CK_SCO32V4
- mode_t mask;
-#else
- int mask;
-#endif /* CK_SCO32V4 */
- mask = umask(0); /* Get umask */
- debug(F101,"zstime mask 1","",mask);
- umask(mask); /* Put it back */
- mask ^= 0777; /* Flip the bits */
- debug(F101,"zstime mask 2","",mask);
- g = xunchar(*(yy->gprotect.val)); /* Decode generic protection */
- debug(F101,"zstime gprotect","",g);
-#ifdef S_IRUSR
- debug(F100,"zstime S_IRUSR","",0);
- if (g & 1) x |= S_IRUSR; /* Read permission */
- flag = 1;
-#endif /* S_IRUSR */
-#ifdef S_IWUSR
- debug(F100,"zstime S_IWUSR","",0);
- if (g & 2) x |= S_IWUSR; /* Write permission */
- if (g & 16) x |= S_IWUSR; /* Delete permission */
- flag = 1;
-#endif /* S_IWUSR */
-#ifdef S_IXUSR
- debug(F100,"zstime S_IXUSR","",0);
- if (g & 4) /* Has execute permission bit */
- x |= S_IXUSR;
- else /* Doesn't have it */
- mask &= 0666; /* so also clear it out of mask */
- flag = 1;
-#endif /* S_IXUSR */
- debug(F101,"zstime mask x","",x);
- x |= mask;
- debug(F101,"zstime mask x|mask","",x);
- }
- debug(F101,"zstime flag","",flag);
- if (flag) {
-#ifdef S_IFMT
- debug(F101,"zstime S_IFMT x","",x);
- sb.st_mode = (sb.st_mode & S_IFMT) | x;
- setperms = 1;
-#else
-#ifdef _IFMT
- debug(F101,"zstime _IFMT x","",x);
- sb.st_mode = (sb.st_mode & _IFMT) | x;
- setperms = 1;
-#endif /* _IFMT */
-#endif /* S_IFMT */
- }
-#ifdef DEBUG
- sprintf(obuf,"%04o",sb.st_mode);
- debug(F111,"zstime file perms after",obuf,setperms);
-#endif /* DEBUG */
- }
-#endif /* CK_PERMS */
-
- debug(F101,"zstime: sb.st_atime","",sb.st_atime);
-
-#ifdef BSD44
- tp[0].tv_sec = sb.st_atime; /* Access time first */
- tp[1].tv_sec = tm; /* Update time second */
- debug(F100,"zstime: BSD44 modtime","",0);
-#else
-#ifdef V7
- tp.timep[0] = tm; /* Set modif. time to creation date */
- tp.timep[1] = sb.st_atime; /* Don't change the access time */
- debug(F100,"zstime: V7 modtime","",0);
-#else
-#ifdef SYSUTIMEH
- tp.modtime = tm; /* Set modif. time to creation date */
- tp.actime = sb.st_atime; /* Don't change the access time */
- debug(F100,"zstime: SYSUTIMEH modtime","",0);
-#else
- tp.mtime = tm; /* Set modif. time to creation date */
- tp.atime = sb.st_atime; /* Don't change the access time */
- debug(F100,"zstime: default modtime","",0);
-#endif /* SYSUTIMEH */
-#endif /* V7 */
-#endif /* BSD44 */
-
- switch (x) { /* Execute desired function */
- case 0: /* Set the creation date of the file */
-#ifdef CK_PERMS /* And permissions */
-/*
- NOTE: If we are inheriting permissions from a previous file, and the
- previous file was a directory, this would turn the new file into a directory
- too, but it's not, so we try to unset the right bit. Luckily, this code
- will probably never be executed since the upper level modules do not allow
- reception of a file that has the same name as a directory.
-
- NOTE 2: We change the permissions *before* we change the modification time,
- otherwise changing the permissions would set the mod time to the present
- time.
-*/
- {
- int x;
- debug(F101,"zstime setperms","",setperms);
- if (S_ISDIR(sb.st_mode)) {
- debug(F101,"zstime DIRECTORY bit on","",sb.st_mode);
- sb.st_mode ^= 0040000;
- debug(F101,"zstime DIRECTORY bit off","",sb.st_mode);
- }
- if (setperms) {
- x = chmod(f,sb.st_mode);
- debug(F101,"zstime chmod","",x);
- }
- }
- if (x < 0) return(-1);
-#endif /* CK_PERMS */
-
- if (!setdate) /* We don't have a date */
- return(0); /* so skip the following... */
-
- if (
-#ifdef BSD44
- utimes(f,tp)
-#else
- utime(f,&tp)
-#endif /* BSD44 */
- ) { /* Fix modification time */
- debug(F111,"zstime 0: can't set modtime for file",f,errno);
- r = -1;
- } else {
- /* Including the modtime here is not portable */
- debug(F110,"zstime 0: modtime set for file",f,0);
- r = 0;
- }
- break;
-
- case 1: /* Compare the dates */
-/*
- This was st_atime, which was wrong. We want the file-data modification
- time, st_mtime.
-*/
- debug(F111,"zstime 1: compare",f,sb.st_mtime);
- debug(F111,"zstime 1: compare","packet",tm);
-
- r = (sb.st_mtime < tm) ? 0 : 1;
- break;
-
- default: /* Error */
- r = -1;
- }
-#endif /* TIMESTAMP */
- return(r);
-}
-
-/* Find initialization file. */
-
-#ifdef NOTUSED
-int
-zkermini() {
-/* nothing here for Unix. This function added for benefit of VMS Kermit. */
- return(0);
-}
-#endif /* NOTUSED */
-
-#ifndef UNIX
-/* Historical -- not used in Unix any more (2001-11-03) */
-#ifndef NOFRILLS
-int
-zmail(p,f) char *p; char *f; { /* Send file f as mail to address p */
-/*
- Returns 0 on success
- 2 if mail delivered but temp file can't be deleted
- -2 if mail can't be delivered
- -1 on file access error
- The UNIX version always returns 0 because it can't get a good return
- code from zsyscmd.
-*/
- int n;
-
-#ifdef CK_LOGIN
- if (isguest)
- return(-2);
-#endif /* CK_LOGIN */
-
- if (!f) f = "";
- if (!*f) return(-1);
-
-#ifdef CKROOT
- debug(F111,"zmail setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(f)) {
- debug(F110,"zmail setroot violation",f,0);
- return(-1);
- }
-#endif /* CKROOT */
-
-#ifdef BSD4
-/* The idea is to use /usr/ucb/mail, rather than regular mail, so that */
-/* a subject line can be included with -s. Since we can't depend on the */
-/* user's path, we use the convention that /usr/ucb/Mail = /usr/ucb/mail */
-/* and even if Mail has been moved to somewhere else, this should still */
-/* find it... The search could be made more reliable by actually using */
-/* access() to see if /usr/ucb/Mail exists. */
-
- n = strlen(f);
- n = n + n + 15 + (int)strlen(p);
-
- if (n > ZMBUFLEN)
- return(-2);
-
-#ifdef DGUX540
- sprintf(zmbuf,"mailx -s %c%s%c %s < %s", '"', f, '"', p, f);
-#else
- sprintf(zmbuf,"Mail -s %c%s%c %s < %s", '"', f, '"', p, f);
-#endif /* DGUX540 */
- zsyscmd(zmbuf);
-#else
-#ifdef SVORPOSIX
-#ifndef OXOS
- sprintf(zmbuf,"mail %s < %s", p, f);
-#else /* OXOS */
- sprintf(zmbuf,"mailx -s %c%s%c %s < %s", '"', f, '"', p, f);
-#endif /* OXOS */
- zsyscmd(zmbuf);
-#else
- *zmbuf = '\0';
-#endif
-#endif
- return(0);
-}
-#endif /* NOFRILLS */
-#endif /* UNIX */
-
-#ifndef NOFRILLS
-int
-zprint(p,f) char *p; char *f; { /* Print file f with options p */
- extern char * printername; /* From ckuus3.c */
- extern int printpipe;
- int n;
-
-#ifdef CK_LOGIN
- if (isguest)
- return(-2);
-#endif /* CK_LOGIN */
-
- if (!f) f = "";
- if (!*f) return(-1);
-
-#ifdef CKROOT
- debug(F111,"zprint setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(f)) {
- debug(F110,"zprint setroot violation",f,0);
- return(-1);
- }
-#endif /* CKROOT */
-
- debug(F110,"zprint file",f,0);
- debug(F110,"zprint flags",p,0);
- debug(F110,"zprint printername",printername,0);
- debug(F101,"zprint printpipe","",printpipe);
-
-#ifdef UNIX
-/*
- Note use of standard input redirection. In some systems, lp[r] runs
- setuid to lp (or ...?), so if user has sent a file into a directory
- that lp does not have read access to, it can't be printed unless it is
- fed to lp[r] as standard input.
-*/
- if (printpipe && printername) {
- n = 8 + (int)strlen(f) + (int)strlen(printername);
- if (n > ZMBUFLEN)
- return(-2);
- sprintf(zmbuf,"cat %s | %s", f, printername);
- } else if (printername) {
- n = 8 + (int)strlen(f) + (int)strlen(printername);
- if (n > ZMBUFLEN)
- return(-2);
- sprintf(zmbuf,"cat %s >> %s", f, printername);
- } else {
- n = 4 + (int)strlen(PRINTCMD) + (int)strlen(p) + (int)strlen(f);
- if (n > ZMBUFLEN)
- return(-2);
- sprintf(zmbuf,"%s %s < %s", PRINTCMD, p, f);
- }
- debug(F110,"zprint command",zmbuf,0);
- zsyscmd(zmbuf);
-#else /* Not UNIX */
- *zmbuf = '\0';
-#endif /* UNIX */
- return(0);
-}
-#endif /* NOFRILLS */
-
-/* Wildcard expansion functions... */
-
-static char scratch[MAXPATH+4]; /* Used by both methods */
-
-static int oldmtchs = 0; /* Let shell (ls) expand them. */
-#ifdef COMMENT
-static char *lscmd = "/bin/ls -d"; /* Command to use. */
-#else
-static char *lscmd = "echo"; /* Command to use. */
-#endif /* COMMENT */
-
-#ifndef NOPUSH
-int
-shxpand(pat,namlst,len) char *pat, *namlst[]; int len; {
- char *fgbuf = NULL; /* Buffer for forming ls command */
- char *p, *q; /* Workers */
-
- int i, x, retcode, itsadir;
- char c;
-
- x = (int)strlen(pat) + (int)strlen(lscmd) + 3; /* Length of ls command */
- for (i = 0; i < oldmtchs; i++) { /* Free previous file list */
- if (namlst[i] ) { /* If memory is allocated */
- free(namlst[i]); /* Free the memory */
- namlst[i] = NULL ; /* Remember no memory is allocated */
- }
- }
- oldmtchs = 0 ; /* Remember there are no matches */
- fgbuf = malloc(x); /* Get buffer for command */
- if (!fgbuf) return(-1); /* Fail if cannot */
- ckmakmsg(fgbuf,x,lscmd," ",pat,NULL); /* Form the command */
- zxcmd(ZIFILE,fgbuf); /* Start the command */
- i = 0; /* File counter */
- p = scratch; /* Point to scratch area */
- retcode = -1; /* Assume failure */
- while ((x = zminchar()) != -1) { /* Read characters from command */
- c = (char) x;
- if (c == ' ' || c == '\n') { /* Got newline or space? */
- *p = '\0'; /* Yes, terminate string */
- p = scratch; /* Point back to beginning */
- if (zchki(p) == -1) /* Does file exist? */
- continue; /* No, continue */
- itsadir = isdir(p); /* Yes, is it a directory? */
- if (xdironly && !itsadir) /* Want only dirs but this isn't */
- continue; /* so skip. */
- if (xfilonly && itsadir) /* It's a dir but want only files */
- continue; /* so skip. */
- x = (int)strlen(p); /* Keep - get length of name */
- q = malloc(x+1); /* Allocate space for it */
- if (!q) goto shxfin; /* Fail if space can't be obtained */
- strcpy(q,scratch); /* (safe) Copy name to space */
- namlst[i++] = q; /* Copy pointer to name into array */
- if (i >= len) goto shxfin; /* Fail if too many */
- } else { /* Regular character */
- *p++ = c; /* Copy it into scratch area */
- }
- }
- retcode = i; /* Return number of matching files */
-shxfin: /* Common exit point */
- free(fgbuf); /* Free command buffer */
- fgbuf = NULL;
- zclosf(ZIFILE); /* Delete the command fork. */
- oldmtchs = i; /* Remember how many files */
- return(retcode);
-}
-#endif /* NOPUSH */
-
-/*
- Directory-reading functions for UNIX originally written for C-Kermit 4.0
- by Jeff Damens, CUCCA, 1984.
-*/
-static char * xpat = NULL; /* Global copy of fgen() pattern */
-static char * xpatlast = NULL; /* Rightmost segment of pattern*/
-static int xpatslash = 0; /* Slash count in pattern */
-static int xpatwild = 0; /* Original pattern is wild */
-static int xleafwild = 0; /* Last segment of pattern is wild */
-static int xpatabsolute = 0;
-
-#ifdef aegis
-static char bslash;
-#endif /* aegis */
-
-
-/* S P L I T P A T H */
-
-/*
- Splits the slash-separated portions of the argument string into
- a list of path structures. Returns the head of the list. The
- structures are allocated by malloc, so they must be freed.
- Splitpath is used internally by the filename generator.
-
- Input:
- A path string.
-
- Returns:
- A linked list of the slash-separated segments of the input.
-*/
-static struct path *
-splitpath(p) char *p; {
- struct path *head,*cur,*prv;
- int i;
-
- debug(F111,"splitpath",p,xrecursive);
- head = prv = NULL;
-
- if (!p) return(NULL);
- if (!*p) return(NULL);
-
- if (!strcmp(p,"**")) { /* Fix this */
- p = "*";
- }
- if (ISDIRSEP(*p)) p++; /* Skip leading slash if any */
-
- /* Make linked list of path segments from pattern */
-
- while (*p) {
- cur = (struct path *) malloc(sizeof (struct path));
- /* debug(F101,"splitpath malloc","",cur); */
- if (cur == NULL) {
- debug(F100,"splitpath malloc failure","",0);
- prv -> fwd = NULL;
- return((struct path *)NULL);
- }
- cur -> fwd = NULL;
- if (head == NULL) /* First, make list head */
- head = cur;
- else /* Not first, link into chain */
- prv -> fwd = cur;
- prv = cur; /* Link from previous to this one */
-
-#ifdef aegis
- /* treat backslash as "../" */
- if (bslash && *p == bslash) {
- strcpy(cur->npart, ".."); /* safe */
- ++p;
- } else {
- for (i=0; i < MAXNAMLEN && *p && *p != '/' && *p != bslash; i++)
- cur -> npart[i] = *p++;
- cur -> npart[i] = '\0'; /* end this segment */
- if (i >= MAXNAMLEN)
- while (*p && *p != '/' && *p != bslash)
- p++;
- }
- if (*p == '/') p++;
-#else
- /* General case (UNIX) */
- for (i = 0; i < MAXNAMLEN && !ISDIRSEP(*p) && *p != '\0'; i++) {
- cur -> npart[i] = *p++;
- }
-
- cur -> npart[i] = '\0'; /* End this path segment */
- if (i >= MAXNAMLEN)
- while (!ISDIRSEP(*p) && *p != '\0') p++;
- if (ISDIRSEP(*p))
- p++;
-
-#endif /* aegis */
- }
- if (prv) {
- makestr(&xpatlast,prv -> npart);
- debug(F110,"splitpath xpatlast",xpatlast,0);
- }
-#ifdef DEBUG
- /* Show original path list */
- if (deblog) {
- for (i = 0, cur = head; cur; i++) {
- debug(F111,"SPLITPATH",cur -> npart, i);
- cur = cur -> fwd;
- }
- }
-#endif /* DEBUG */
- return(head);
-}
-
-/* F G E N -- Generate File List */
-
-/*
- File name generator. It is passed a string, possibly containing wildcards,
- and an array of character pointers. It finds all the matching filenames and
- stores pointers to them in the array. The returned strings are allocated
- from a static buffer local to this module (so the caller doesn't have to
- worry about deallocating them); this means that successive calls to fgen
- will wipe out the results of previous calls.
-
- Input:
- A wildcard string, an array to write names to, the length of the array.
-
- Returns:
- The number of matches.
- The array is filled with filenames that matched the pattern.
- If there wasn't enough room in the array, -1 is returned.
-
- Originally by: Jeff Damens, CUCCA, 1984. Many changes since then.
-*/
-static int
-fgen(pat,resarry,len) char *pat,*resarry[]; int len; {
- struct path *head;
- char *sptr, *s;
- int n;
-
-#ifdef aegis
- char *namechars;
- int tilde = 0, bquote = 0;
-
- if ((namechars = getenv("NAMECHARS")) != NULL) {
- if (ckstrchr(namechars, '~' ) != NULL) tilde = '~';
- if (ckstrchr(namechars, '\\') != NULL) bslash = '\\';
- if (ckstrchr(namechars, '`' ) != NULL) bquote = '`';
- } else {
- tilde = '~'; bslash = '\\'; bquote = '`';
- }
- sptr = scratch;
-
- /* copy "`node_data", etc. anchors */
- if (bquote && *pat == bquote)
- while (*pat && *pat != '/' && *pat != bslash)
- *sptr++ = *pat++;
- else if (tilde && *pat == tilde)
- *sptr++ = *pat++;
- while (*pat == '/')
- *sptr++ = *pat++;
- if (sptr == scratch) {
- strcpy(scratch,"./"); /* safe */
- sptr = scratch+2;
- }
- if (!(head = splitpath(pat))) return(-1);
-
-#else /* not aegis */
-
- debug(F111,"fgen pat",pat,len);
- debug(F110,"fgen current directory",zgtdir(),0);
- debug(F101,"fgen stathack","",stathack);
-
- scratch[0] = '\0';
- xpatwild = 0;
- xleafwild = 0;
- xpatabsolute = 0;
-
- if (!(head = splitpath(pat))) /* Make the path segment list */
- return(-1);
-
- sptr = scratch;
-
-#ifdef COMMENT
- if (strncmp(pat,"./",2) && strncmp(pat,"../",3)) {
-#endif /* COMMENT */
- if (!ISDIRSEP(*pat)) /* If name is not absolute */
- *sptr++ = '.'; /* put "./" in front. */
- *sptr++ = DIRSEP;
-#ifdef COMMENT
- }
-#endif /* COMMENT */
- *sptr = '\0';
-#endif /* aegis */
-
- makestr(&xpat,pat); /* Save copy of original pattern */
- debug(F110,"fgen scratch",scratch,0);
-
- for (n = 0, s = xpat; *s; s++) /* How many slashes in the pattern */
- if (*s == DIRSEP) /* since these are fences for */
- n++; /* pattern matching */
- xpatslash = n;
- debug(F101,"fgen xpatslash","",xpatslash);
-
- numfnd = 0; /* None found yet */
-
- if (initspace(resarry,ssplen) < 0)
- return(-1);
-
- xpatwild = iswild(xpat); /* Original pattern is wild? */
- xpatabsolute = isabsolute(xpat);
- xleafwild = iswild(xpatlast);
-
- debug(F111,"fgen xpat",xpat,xpatwild);
- debug(F111,"fgen xpatlast",xpatlast,xleafwild);
- debug(F101,"fgen xpatabsolute","",xpatabsolute);
-
- traverse(head,scratch,sptr); /* Go walk the directory tree. */
- while (head != NULL) { /* Done - free path segment list. */
- struct path *next = head -> fwd;
- free((char *)head);
- head = next;
- }
- debug(F101,"fgen","",numfnd);
- return(numfnd); /* Return the number of matches */
-}
-
-/* Define LONGFN (long file names) automatically for BSD 2.9 and 4.2 */
-/* LONGFN can also be defined on the cc command line. */
-
-#ifdef BSD29
-#ifndef LONGFN
-#define LONGFN
-#endif
-#endif
-
-#ifdef BSD42
-#ifndef LONGFN
-#define LONGFN
-#endif
-#endif
-
-/*
- T R A V E R S E -- Traverse a directory tree.
-
- Walks the directory tree looking for matches to its arguments.
- The algorithm is, briefly:
-
- If the current pattern segment contains no wildcards, that
- segment is added to what we already have. If the name so far
- exists, we call ourselves recursively with the next segment
- in the pattern string; otherwise, we just return.
-
- If the current pattern segment contains wildcards, we open the name
- we've accumulated so far (assuming it is really a directory), then read
- each filename in it, and, if it matches the wildcard pattern segment, add
- that filename to what we have so far and call ourselves recursively on
- the next segment.
-
- Finally, when no more pattern segments remain, we add what's accumulated
- so far to the result array and increment the number of matches.
-
- Inputs:
- A pattern path list (as generated by splitpath), a string pointer that
- points to what we've traversed so far (this can be initialized to "/"
- to start the search at the root directory, or to "./" to start the
- search at the current directory), and a string pointer to the end of
- the string in the previous argument, plus the global "recursive",
- "xmatchdot", and "xdironly" flags.
-
- Returns: void, with:
- mtchs[] containing the array of filename string pointers, and:
- numfnd containing the number of filenames.
-
- Although it might be poor practice, the mtchs[] array is revealed to the
- outside in case it needs it; for example, to be sorted prior to use.
- (It is poor practice because not all platforms implement file lists the
- same way; some don't use an array at all.)
-
- Note that addresult() acts as a second-level filter; due to selection
- criteria outside of the pattern, it might decline to add files that
- this routine asks it to, e.g. because we are collecting only directory
- names but not the names of regular files.
-
- WARNING: In the course of C-Kermit 7.0 development, this routine became
- ridiculously complex, in order to meet approximately sixty specific
- requirements. DON'T EVEN THINK ABOUT MODIFYING THIS ROUTINE! Trust me;
- it is not possible to fix anything in it without breaking something else.
- This routine badly needs a total redesign and rewrite. Note: There may
- be some good applications for realpath() and/or scandir() and/or fts_blah()
- here, on platforms where they are available.
-*/
-static VOID
-traverse(pl,sofar,endcur) struct path *pl; char *sofar, *endcur; {
-
-/* Appropriate declarations for directory routines and structures */
-/* #define OPENDIR means to use opendir(), readdir(), closedir() */
-/* If OPENDIR not defined, we use open(), read(), close() */
-
-#ifdef DIRENT /* New way, <dirent.h> */
-#define OPENDIR
- DIR *fd, *opendir();
- struct dirent *dirbuf;
- struct dirent *readdir();
-#else /* !DIRENT */
-#ifdef LONGFN /* Old way, <dir.h> with opendir() */
-#define OPENDIR
- DIR *fd, *opendir();
- struct direct *dirbuf;
-#else /* !LONGFN */
- int fd; /* Old way, <dir.h> with open() */
- struct direct dir_entry;
- struct direct *dirbuf = &dir_entry;
-#endif /* LONGFN */
-#endif /* DIRENT */
- int mopts = 0; /* ckmatch() opts */
- int depth = 0; /* Directory tree depth */
-
- char nambuf[MAXNAMLEN+4]; /* Buffer for a filename */
- int itsadir = 0, segisdir = 0, itswild = 0, mresult, n, x /* , y */ ;
- struct stat statbuf; /* For file info. */
-
- debug(F101,"STAT","",16);
- if (pl == NULL) { /* End of path-segment list */
- *--endcur = '\0'; /* Terminate string, overwrite trailing slash */
- debug(F110,"traverse add: end of path segment",sofar,0);
- addresult(sofar,-1);
- return;
- }
- if (stathack) {
- /* This speeds up the search a lot and we still get good results */
- /* but it breaks the tagging of directory names done in addresult */
- if (xrecursive || xfilonly || xdironly || xpatslash) {
- itsadir = xisdir(sofar);
- debug(F101,"STAT","",17);
- } else
- itsadir = (strncmp(sofar,"./",2) == 0);
- } else {
- itsadir = xisdir(sofar);
- debug(F101,"STAT","",18);
- }
- debug(F111,"traverse entry sofar",sofar,itsadir);
-
-#ifdef CKSYMLINK /* We're doing symlinks? */
-#ifdef USE_LSTAT /* OK to use lstat()? */
- if (itsadir && xnolinks) { /* If not following symlinks */
- int x;
- struct stat buf;
- x = lstat(sofar,&buf);
- debug(F111,"traverse lstat 1",sofar,x);
- if (x > -1 &&
-#ifdef S_ISLNK
- S_ISLNK(buf.st_mode)
-#else
-#ifdef _IFLNK
- ((_IFMT & buf.st_mode) == _IFLNK)
-#endif /* _IFLNK */
-#endif /* S_ISLNK */
- )
- itsadir = 0;
- }
-#endif /* USE_LSTAT */
-#endif /* CKSYMLINK */
-
- if (!xmatchdot && xpatlast[0] == '.')
- xmatchdot = 1;
- if (!xmatchdot && xpat[0] == '.' && xpat[1] != '/' && xpat[1] != '.')
- xmatchdot = 1;
-
- /* ckmatch() options */
-
- if (xmatchdot) mopts |= 1; /* Match dot */
- if (!xrecursive) mopts |= 2; /* Dirsep is fence */
-
- debug(F111,"traverse entry xpat",xpat,xpatslash);
- debug(F111,"traverse entry xpatlast",xpatlast,xmatchdot);
- debug(F110,"traverse entry pl -> npart",pl -> npart,0);
-
-#ifdef RECURSIVE
- if (xrecursive > 0 && !itsadir) {
- char * s; /* Recursive descent and this is a regular file */
- *--endcur = '\0'; /* Terminate string, overwrite trailing slash */
-
- /* Find the nth slash from the right and match from there... */
- /* (n == the number of slashes in the original pattern - see fgen) */
- if (*sofar == '/') {
- debug(F110,"traverse xpatslash absolute",sofar,0);
- s = sofar;
- } else {
- debug(F111,"traverse xpatslash relative",sofar,xpatslash);
- for (s = endcur - 1, n = 0; s >= sofar; s--) {
- if (*s == '/') {
- if (++n >= xpatslash) {
- s++;
- break;
- }
- }
- }
- }
-#ifndef NOSKIPMATCH
- /* This speeds things up a bit. */
- /* If it causes trouble define NOSKIPMATCH and rebuild. */
- if (xpat[0] == '*' && !xpat[1])
- x = xmatchdot ? 1 : (s[0] != '.');
- else
-#endif /* NOSKIPMATCH */
- x = ckmatch(xpat, s, 1, mopts); /* Match with original pattern */
- debug(F111,"traverse xpatslash ckmatch",s,x);
- if (x > 0) {
- debug(F110,"traverse add: recursive, match, && !isdir",sofar,0);
- addresult(sofar,itsadir);
- }
- return;
- }
-#endif /* RECURSIVE */
-
- debug(F111,"traverse sofar 2",sofar,0);
-
- segisdir = ((pl -> fwd) == NULL) ? 0 : 1;
- itswild = wildena ? (iswild(pl -> npart)) : 0; /* 15 Jun 2005 */
-
- debug(F111,"traverse segisdir",sofar,segisdir);
- debug(F111,"traverse itswild ",pl -> npart,itswild);
-
-#ifdef RECURSIVE
- if (xrecursive > 0) { /* If recursing and... */
- if (segisdir && itswild) /* this is a dir and npart is wild */
- goto blah; /* or... */
- else if (!xpatabsolute && !xpatwild) /* search object is nonwild */
- goto blah; /* then go recurse */
- }
-#endif /* RECURSIVE */
-
- if (!itswild) { /* This path segment not wild? */
-#ifdef COMMENT
- strcpy(endcur,pl -> npart); /* (safe) Append next part. */
- endcur += (int)strlen(pl -> npart); /* Advance end pointer */
-#else
-/*
- strcpy() does not account for quoted metacharacters.
- We must remove the quotes before doing the stat().
-*/
- {
- int quote = 0;
- char c, * s;
- s = pl -> npart;
- while ((c = *s++)) {
- if (!quote) {
- if (c == CMDQ) {
- quote = 1;
- continue;
- }
- }
- *endcur++ = c;
- quote = 0;
- }
- }
-#endif /* COMMENT */
- *endcur = '\0'; /* End new current string. */
-
- if (stat(sofar,&statbuf) == 0) { /* If this piece exists... */
- debug(F110,"traverse exists",sofar,0);
- *endcur++ = DIRSEP; /* add slash to end */
- *endcur = '\0'; /* and end the string again. */
- traverse(pl -> fwd, sofar, endcur);
- }
-#ifdef DEBUG
- else debug(F110,"traverse not found", sofar, 0);
-#endif /* DEBUG */
- return;
- }
-
- *endcur = '\0'; /* End current string */
- debug(F111,"traverse sofar 3",sofar,0);
-
- if (!itsadir)
- return;
-
- /* Search is recursive or ... */
- /* path segment contains wildcards, have to open and search directory. */
-
- blah:
-
- debug(F110,"traverse opening directory", sofar, 0);
-
-#ifdef OPENDIR
- debug(F110,"traverse opendir()",sofar,0);
- if ((fd = opendir(sofar)) == NULL) { /* Can't open, fail. */
- debug(F101,"traverse opendir() failed","",errno);
- return;
- }
- while ((dirbuf = readdir(fd)))
-#else /* !OPENDIR */
- debug(F110,"traverse directory open()",sofar,0);
- if ((fd = open(sofar,O_RDONLY)) < 0) {
- debug(F101,"traverse directory open() failed","",errno);
- return;
- }
- while (read(fd, (char *)dirbuf, sizeof dir_entry) > 0)
-#endif /* OPENDIR */
- { /* Read each entry in this directory */
- int exists;
- char *eos, *s;
- exists = 0;
-
- /* On some platforms, the read[dir]() can return deleted files, */
- /* e.g. HP-UX 5.00. There is no point in grinding through this */
- /* routine when the file doesn't exist... */
-
- if ( /* There actually is an inode... */
-#ifdef BSD42
- dirbuf->d_ino != -1
-#else
-#ifdef unos
- dirbuf->d_ino != -1
-#else
-#ifdef QNX
- dirbuf->d_stat.st_ino != 0
-#else
-#ifdef SOLARIS
- dirbuf->d_ino != 0
-#else
-#ifdef sun
- dirbuf->d_fileno != 0
-#else
-#ifdef bsdi
- dirbuf->d_fileno != 0
-#else
-#ifdef __386BSD__
- dirbuf->d_fileno != 0
-#else
-#ifdef __FreeBSD__
- dirbuf->d_fileno != 0
-#else
-#ifdef ultrix
- dirbuf->gd_ino != 0
-#else
-#ifdef Plan9
- 1
-#else
- dirbuf->d_ino != 0
-#endif /* Plan9 */
-#endif /* ultrix */
-#endif /* __FreeBSD__ */
-#endif /* __386BSD__ */
-#endif /* bsdi */
-#endif /* sun */
-#endif /* SOLARIS */
-#endif /* QNX */
-#endif /* unos */
-#endif /* BSD42 */
- )
- exists = 1;
- if (!exists)
- continue;
-
- ckstrncpy(nambuf, /* Copy the name */
- dirbuf->d_name,
- MAXNAMLEN
- );
- if (nambuf[0] == '.') {
- if (!nambuf[1] || (nambuf[1] == '.' && !nambuf[2])) {
- debug(F110,"traverse skipping",nambuf,0);
- continue; /* skip "." and ".." */
- }
- }
- s = nambuf; /* Copy name to end of sofar */
- eos = endcur;
- while ((*eos = *s)) {
- s++;
- eos++;
- }
-/*
- Now we check the file for (a) whether it is a directory, and (b) whether
- its name matches our pattern. If it is a directory, and if we have been
- told to build a recursive list, then we must descend regardless of whether
- it matches the pattern. If it is not a directory and it does not match
- our pattern, we skip it. Note: sofar is the full pathname, nambuf is
- the name only.
-*/
- /* Do this first to save pointless function calls */
- if (nambuf[0] == '.' && !xmatchdot) /* Dir name starts with '.' */
- continue;
- if (stathack) {
- if (xrecursive || xfilonly || xdironly || xpatslash) {
- itsadir = xisdir(sofar); /* See if it's a directory */
- debug(F101,"STAT","",19);
- } else {
- itsadir = 0;
- }
- } else {
- itsadir = xisdir(sofar);
- debug(F101,"STAT","",20);
- }
-
-#ifdef CKSYMLINK
-#ifdef USE_LSTAT
- if (itsadir && xnolinks) { /* If not following symlinks */
- int x;
- struct stat buf;
- x = lstat(sofar,&buf);
- debug(F111,"traverse lstat 2",sofar,x);
- if (x > -1 &&
-#ifdef S_ISLNK
- S_ISLNK(buf.st_mode)
-#else
-#ifdef _IFLNK
- ((_IFMT & buf.st_mode) == _IFLNK)
-#endif /* _IFLNK */
-#endif /* S_ISLNK */
- )
- itsadir = 0;
- }
-#endif /* USE_LSTAT */
-#endif /* CKSYMLINK */
-
-#ifdef RECURSIVE
- if (xrecursive > 0 && itsadir &&
- (xpatlast[0] == '*') && !xpatlast[1]
- ) {
- debug(F110,
- "traverse add: recursive && isdir && segisdir or match",
- sofar,
- segisdir
- );
- addresult(sofar,itsadir);
- if (numfnd < 0) return;
- }
-#endif /* RECURSIVE */
-
- debug(F111,"traverse mresult xpat",xpat,xrecursive);
- debug(F111,"traverse mresult pl -> npart",
- pl -> npart,
- ((pl -> fwd) ? 9999 : 0)
- );
- debug(F111,"traverse mresult sofar segisdir",sofar,segisdir);
- debug(F111,"traverse mresult sofar itsadir",sofar,itsadir);
- debug(F101,"traverse mresult xmatchdot","",xmatchdot);
-/*
- Match the path so far with the pattern after stripping any leading "./"
- from either or both. The pattern chosen is the full original pattern if
- the match candidate (sofar) is not a directory, or else just the name part
- (pl->npart) if it is.
-*/
- {
- char * s1; /* The pattern */
- char * s2 = sofar; /* The path so far */
- char * s3; /* Worker */
- int opts; /* Match options */
-
- s1 = itsadir ? pl->npart : xpat;
-
-#ifndef COMMENT
- /* I can't explain this but it unbreaks "cd blah/sub<Esc>" */
- if (itsadir && !xrecursive && xpatslash > 0 &&
- segisdir == 0 && itswild) {
- s1 = xpat;
- debug(F110,"traverse mresult s1 kludge",s1,0);
- }
-#endif /* COMMENT */
-
- if (xrecursive && xpatslash == 0)
- s2 = nambuf;
- while ((s1[0] == '.') && (s1[1] == '/')) /* Strip "./" */
- s1 += 2;
- while ((s2[0] == '.') && (s2[1] == '/')) /* Ditto */
- s2 += 2;
- opts = mopts; /* Match options */
- if (itsadir) /* Current segment is a directory */
- opts = mopts & 1; /* No fences */
- s3 = s2; /* Get segment depth */
- depth = 0;
- while (*s3) { if (*s3++ == '/') depth++; }
-#ifndef NOSKIPMATCH
- /* This speeds things up a bit. */
- /* If it causes trouble define NOSKIPMATCH and rebuild. */
- if (depth == 0 && (s1[0] == '*') && !s1[1])
- mresult = xmatchdot ? 1 : (s2[0] != '.');
- else
-#endif /* NOSKIPMATCH */
- mresult = ckmatch(s1,s2,1,opts); /* Match */
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"traverse mresult depth",sofar,depth);
- debug(F101,"traverse mresult xpatslash","",xpatslash);
- debug(F111,"traverse mresult nambuf",nambuf,mresult);
- debug(F111,"traverse mresult itswild",pl -> npart,itswild);
- debug(F111,"traverse mresult segisdir",pl -> npart,segisdir);
- }
-#endif /* DEBUG */
- if (mresult || /* If match succeeded */
- xrecursive || /* Or search is recursive */
- depth < xpatslash /* Or not deep enough to match... */
- ) {
- if ( /* If it's not a directory... */
-/*
- The problem here is that segisdir is apparently not set appropriately.
- If I leave in the !segisdir test, then "dir /recursive blah" (where blah is
- a directory name) misses some regular files because sometimes segisdir
- is set and sometimes it's not. But if I comment it out, then
- "dir <star>/<star>.txt lists every file in * and does not even open up the
- subdirectories. However, "dir /rec <star>/<star>.txt" works right.
-*/
-#ifdef COMMENT
- mresult && (!itsadir && !segisdir)
-#else
- mresult && /* Matched */
- !itsadir && /* sofar is not a directory */
- ((!xrecursive && !segisdir) || xrecursive)
-#endif /* COMMENT */
- ) {
- debug(F110,
- "traverse add: match && !itsadir",sofar,0);
- addresult(sofar,itsadir);
- if (numfnd < 0) return;
- } else if (itsadir && (xrecursive || mresult)) {
- struct path * xx = NULL;
- *eos++ = DIRSEP; /* Add directory separator */
- *eos = '\0'; /* to end of segment */
-#ifdef RECURSIVE
- /* Copy previous pattern segment to this new directory */
-
- if (xrecursive > 0 && !(pl -> fwd)) {
- xx = (struct path *) malloc(sizeof (struct path));
- pl -> fwd = xx;
- if (xx) {
- xx -> fwd = NULL;
- strcpy(xx -> npart, pl -> npart); /* safe */
- }
- }
-#endif /* RECURSIVE */
- traverse(pl -> fwd, sofar, eos); /* Traverse new directory */
- }
- }
- }
-#ifdef OPENDIR
- closedir(fd);
-#else /* !OPENDIR */
- close(fd);
-#endif /* OPENDIR */
-}
-
-/*
- * addresult:
- * Adds a result string to the result array. Increments the number
- * of matches found, copies the found string into our string
- * buffer, and puts a pointer to the buffer into the caller's result
- * array. Our free buffer pointer is updated. If there is no
- * more room in the caller's array, the number of matches is set to -1.
- * Input: a result string.
- * Returns: nothing.
- */
-static VOID
-addresult(str,itsadir) char *str; int itsadir; {
- int len;
-
- if (!freeptr) {
- debug(F100,"addresult string space not init'd","",0);
- initspace(mtchs,ssplen);
- }
- if (!str) str = "";
- debug(F111,"addresult",str,itsadir);
- if (!*str)
- return;
-
- if (itsadir < 0) {
- itsadir = xisdir(str);
- }
- if ((xdironly && !itsadir) || (xfilonly && itsadir)) {
- debug(F111,"addresult skip",str,itsadir);
- return;
- }
- while (str[0] == '.' && ISDIRSEP(str[1])) /* Strip all "./" from front */
- str += 2;
- if (--remlen < 0) { /* Elements left in array of names */
- debug(F111,"addresult ARRAY FULL",str,numfnd);
- numfnd = -1;
- return;
- }
- len = (int)strlen(str); /* Space this will use */
- debug(F111,"addresult len",str,len);
-
- if (len < 1)
- return;
-
- if ((freeptr + len + itsadir + 1) > (sspace + ssplen)) {
- debug(F111,"addresult OUT OF SPACE",str,numfnd);
-#ifdef DYNAMIC
- printf(
-"?String space %d exhausted - use SET FILE STRINGSPACE to increase\n",ssplen);
-#else
- printf("?String space %d exhausted\n",ssplen);
-#endif /* DYNAMIC */
- numfnd = -1; /* Do not record if not enough space */
- return;
- }
- strcpy(freeptr,str); /* safe */
-
- /* Tag directory names by putting '/' at the end */
-
- if (itsadir && (freeptr[len-1] == '/')) {
- freeptr[len++] = DIRSEP;
- freeptr[len] = '\0';
- }
- if (numfnd >= maxnames) {
-#ifdef DYNAMIC
- printf(
-"?Too many files (%d max) - use SET FILE LISTSIZE to increase\n",maxnames);
-#else
- printf("?Too many files - %d max\n",maxnames);
-#endif /* DYNAMIC */
- numfnd = -1;
- return;
- }
- str = freeptr;
- *resptr++ = freeptr;
- freeptr += (len + 1);
- numfnd++;
- debug(F111,"addresult ADD",str,numfnd);
-}
-
-#ifdef COMMENT
-/*
- * match(pattern,string):
- * pattern matcher. Takes a string and a pattern possibly containing
- * the wildcard characters '*' and '?'. Returns true if the pattern
- * matches the string, false otherwise.
- * Orignally by: Jeff Damens, CUCCA, 1984
- * No longer used as of C-Kermit 7.0, now we use ckmatch() instead (ckclib.c).
- *
- * Input: a string and a wildcard pattern.
- * Returns: 1 if match, 0 if no match.
- */
-static int
-match(pattern, string) char *pattern, *string; {
- char *psave = NULL, *ssave = NULL; /* Backup pointers for failure */
- int q = 0; /* Quote flag */
-
- if (*string == '.' && *pattern != '.' && !xmatchdot) {
- debug(F110,"match skip",string,0);
- return(0);
- }
- while (1) {
- for (; *pattern == *string; pattern++,string++) /* Skip first */
- if (*string == '\0') return(1); /* End of strings, succeed */
-
- if (*pattern == '\\' && q == 0) { /* Watch out for quoted */
- q = 1; /* metacharacters */
- pattern++; /* advance past quote */
- if (*pattern != *string) return(0);
- continue;
- } else q = 0;
-
- if (q) {
- return(0);
- } else {
- if (*string != '\0' && *pattern == '?') {
- pattern++; /* '?', let it match */
- string++;
- } else if (*pattern == '*') { /* '*' ... */
- psave = ++pattern; /* remember where we saw it */
- ssave = string; /* let it match 0 chars */
- } else if (ssave != NULL && *ssave != '\0') { /* if not at end */
- /* ...have seen a star */
- string = ++ssave; /* skip 1 char from string */
- pattern = psave; /* and back up pattern */
- } else return(0); /* otherwise just fail */
- }
- }
-}
-#endif /* COMMENT */
-
-/*
- The following two functions are for expanding tilde in filenames
- Contributed by Howie Kaye, CUCCA, developed for CCMD package.
-*/
-
-/* W H O A M I -- Get user's username. */
-
-/*
- 1) Get real uid
- 2) See if the $USER environment variable is set ($LOGNAME on AT&T)
- 3) If $USER's uid is the same as ruid, realname is $USER
- 4) Otherwise get logged in user's name
- 5) If that name has the same uid as the real uid realname is loginname
- 6) Otherwise, get a name for ruid from /etc/passwd
-*/
-char *
-whoami() {
-#ifdef DTILDE
-#ifdef pdp11
-#define WHOLEN 100
-#else
-#define WHOLEN 257
-#endif /* pdp11 */
- static char realname[UIDBUFLEN+1]; /* user's name */
- static int ruid = -1; /* user's real uid */
- char loginname[UIDBUFLEN+1], envname[256]; /* temp storage */
- char *c;
- struct passwd *p;
- _PROTOTYP(extern char * getlogin, (void) );
-
- debug(F111,"whoami ruid A",realname,ruid);
-
- if (ruid != -1)
- return(realname);
-
- ruid = real_uid(); /* get our uid */
- debug(F101,"whoami ruid B","",ruid);
- if (ruid < 0) ruid = getuid();
- debug(F101,"whoami ruid C","",ruid);
-
- /* how about $USER or $LOGNAME? */
- if ((c = getenv(NAMEENV)) != NULL) { /* check the env variable */
- ckstrncpy(envname, c, 255);
- debug(F110,"whoami envname",envname,0);
- if ((p = getpwnam(envname)) != NULL) {
- if (p->pw_uid == ruid) { /* get passwd entry for envname */
- ckstrncpy(realname, envname, UIDBUFLEN); /* uid's are same */
- debug(F110,"whoami realname",realname,0);
- return(realname);
- }
- }
- }
-
- /* can we use loginname() ? */
-
- if ((c = getlogin()) != NULL) { /* name from utmp file */
- ckstrncpy (loginname, c, UIDBUFLEN);
- debug(F110,"whoami loginname",loginname,0);
- if ((p = getpwnam(loginname)) != NULL) /* get passwd entry */
- if (p->pw_uid == ruid) /* for loginname */
- ckstrncpy(realname, envname, UIDBUFLEN); /* if uid's are same */
- }
-
- /* Use first name we get for ruid */
-
- if ((p = getpwuid(ruid)) == NULL) { /* name for uid */
- debug(F101,"whoami no username for ruid","",ruid);
- realname[0] = '\0'; /* no user name */
- ruid = -1;
- return(NULL);
- }
- ckstrncpy(realname, p->pw_name, UIDBUFLEN);
- debug(F110,"whoami realname from getpwuid",realname,0);
- return(realname);
-#else
- return(NULL);
-#endif /* DTILDE */
-}
-
-/* T I L D E _ E X P A N D -- expand ~user to the user's home directory. */
-
-char *
-tilde_expand(dirname) char *dirname; {
-#ifdef DTILDE
-#ifdef pdp11
-#define BUFLEN 100
-#else
-#define BUFLEN 257
-#endif /* pdp11 */
- struct passwd *user;
- static char olddir[BUFLEN+1];
- static char oldrealdir[BUFLEN+1];
- static char temp[BUFLEN+1];
- int i, j;
-
- debug(F111,"tilde_expand",dirname,dirname[0]);
-
- if (dirname[0] != '~') { /* Not a tilde...return param */
- debug(F000,"tilde_expand NOT TILDE","",dirname[0]);
- return(dirname);
- }
- if (!strcmp(olddir,dirname)) { /* Same as last time */
- debug(F110,"tilde_expand same as previous",oldrealdir,0);
- return(oldrealdir); /* so return old answer. */
- } else {
- debug(F110,"tilde_expand working...","",0);
- j = (int)strlen(dirname);
- for (i = 0; i < j; i++) /* find username part of string */
- if (!ISDIRSEP(dirname[i]))
- temp[i] = dirname[i];
- else break;
- temp[i] = '\0'; /* tie off with a NULL */
- debug(F111,"tilde_expand first part",temp,i);
- if (i == 1) { /* if just a "~" */
-#ifdef IKSD
- if (inserver)
- user = getpwnam(uidbuf); /* Get info on current user */
- else
-#endif /* IKSD */
- {
- char * p = whoami();
- debug(F110,"tilde_expand p",p,0);
- if (p) {
- user = getpwnam(p);
- debug(F110,"tilde_expand getpwpam ~",user,0);
- } else {
- user = NULL;
- }
- }
- } else {
- debug(F110,"tilde_expand ~user",&temp[1],0);
- user = getpwnam(&temp[1]); /* otherwise on the specified user */
- debug(F110,"tilde_expand getpwpam user",user,0);
- }
-
- }
- if (user != NULL) { /* valid user? */
- ckstrncpy(olddir, dirname, BUFLEN); /* remember the directory */
- ckstrncpy(oldrealdir,user->pw_dir, BUFLEN); /* and home directory */
- ckstrncat(oldrealdir,&dirname[i], BUFLEN);
- oldrealdir[BUFLEN] = '\0';
- return(oldrealdir);
- } else { /* invalid? */
- ckstrncpy(olddir, dirname, BUFLEN); /* remember for next time */
- ckstrncpy(oldrealdir, dirname, BUFLEN);
- return(oldrealdir);
- }
-#else
- return(NULL);
-#endif /* DTILDE */
-}
-
-/*
- Functions for executing system commands.
- zsyscmd() executes the system command in the normal, default way for
- the system. In UNIX, it does what system() does. Thus, its results
- are always predictable.
- zshcmd() executes the command using the user's preferred shell.
-*/
-int
-zsyscmd(s) char *s; {
-#ifdef aegis
- if (nopush) return(-1);
- if (!priv_chk()) return(system(s));
-#else
- PID_T shpid;
-#ifdef COMMENT
-/* This doesn't work... */
- WAIT_T status;
-#else
- int status;
-#endif /* COMMENT */
-
- if (nopush) return(-1);
- if ((shpid = fork())) {
- if (shpid < (PID_T)0) return(-1); /* Parent */
- while (shpid != (PID_T) wait(&status))
- ;
- return(status);
- }
- if (priv_can()) { /* Child: cancel any priv's */
- printf("?Privilege cancellation failure\n");
- _exit(255);
- }
- restorsigs(); /* Restore ignored signals */
-#ifdef HPUX10
- execl("/usr/bin/sh","sh","-c",s,NULL);
- perror("/usr/bin/sh");
-#else
-#ifdef Plan9
- execl("/bin/rc", "rc", "-c", s, NULL);
- perror("/bin/rc");
-#else
- execl("/bin/sh","sh","-c",s,NULL);
- perror("/bin/sh");
-#endif /* Plan9 */
-#endif /* HPUX10 */
- _exit(255);
- return(0); /* Shut up ANSI compilers. */
-#endif /* aegis */
-}
-
-
-/* Z _ E X E C -- Overlay ourselves with another program */
-
-#ifndef NOZEXEC
-#ifdef HPUX5
-#define NOZEXEC
-#else
-#ifdef ATT7300
-#define NOZEXEC
-#endif /* ATT7300 */
-#endif /* HPUX5 */
-#endif /* NOZEXEC */
-
-VOID
-z_exec(p,s,t) char * p, ** s; int t; { /* Overlay ourselves with "p s..." */
-#ifdef NOZEXEC
- printf("EXEC /REDIRECT NOT IMPLEMENTED IN THIS VERSION OF C-KERMIT\n");
- debug(F110,"z_exec NOT IMPLEMENTED",p,0);
-#else
- int x;
- extern int ttyfd;
- debug(F110,"z_exec command",p,0);
- debug(F110,"z_exec arg 0",s[0],0);
- debug(F110,"z_exec arg 1",s[1],0);
- debug(F101,"z_exec t","",t);
- errno = 0;
- if (t) {
- if (ttyfd > 2) {
- dup2(ttyfd, 0);
- dup2(ttyfd, 1);
- /* dup2(ttyfd, 2); */
- close(ttyfd);
- }
- }
- restorsigs(); /* Restore ignored signals */
- x = execvp(p,s);
- if (x < 0) debug(F101,"z_exec errno","",errno);
-#endif /* NOZEXEC */
-}
-
-/*
- Z S H C M D -- Execute a shell command (or program thru the shell).
-
- Original UNIX code by H. Fischer; copyright rights assigned to Columbia U.
- Adapted to use getpwuid to find login shell because many systems do not
- have SHELL in environment, and to use direct calling of shell rather
- than intermediate system() call. -- H. Fischer (1985); many changes since
- then. Call with s pointing to command to execute. Returns:
- -1 on failure to start the command (can't find, can't fork, can't run).
- 1 if command ran and gave an exit status of 0.
- 0 if command ran and gave a nonzero exit status.
- with pexitstatus containing the command's exit status.
-*/
-int
-zshcmd(s) char *s; {
- PID_T pid;
-
-#ifdef NOPUSH
- return(0);
-#else
- if (nopush) return(-1);
- if (!s) return(-1);
- while (*s == ' ') s++;
-
- debug(F110,"zshcmd command",s,0);
-
-#ifdef aegis
- if ((pid = vfork()) == 0) { /* Make child quickly */
- char *shpath, *shname, *shptr; /* For finding desired shell */
-
- if (priv_can()) exit(1); /* Turn off privs. */
- if ((shpath = getenv("SHELL")) == NULL) shpath = "/com/sh";
-
-#else /* All Unix systems */
- if ((pid = fork()) == 0) { /* Make child */
- char *shpath, *shname, *shptr; /* For finding desired shell */
- struct passwd *p;
-#ifdef HPUX10 /* Default */
- char *defshell = "/usr/bin/sh";
-#else
-#ifdef Plan9
- char *defshell = "/bin/rc";
-#else
- char *defshell = "/bin/sh";
-#endif /* Plan9 */
-#endif /* HPUX10 */
- if (priv_can()) exit(1); /* Turn off privs. */
-#ifdef COMMENT
-/* Old way always used /etc/passwd shell */
- p = getpwuid(real_uid()); /* Get login data */
- if (p == (struct passwd *) NULL || !*(p->pw_shell))
- shpath = defshell;
- else
- shpath = p->pw_shell;
-#else
-/* New way lets user override with SHELL variable, but does not rely on it. */
-/* This allows user to specify a different shell. */
- shpath = getenv("SHELL"); /* What shell? */
- debug(F110,"zshcmd SHELL",shpath,0);
- {
- int x = 0;
- if (!shpath) {
- x++;
- } else if (!*shpath) {
- x++;
- }
- if (x) {
- debug(F100,"zshcmd SHELL not defined","",0);
- p = getpwuid( real_uid() ); /* Get login data */
- if (p == (struct passwd *)NULL || !*(p->pw_shell)) {
- shpath = defshell;
- } else {
- shpath = p->pw_shell;
- }
- debug(F110,"zshcmd shpath from getpwuid",shpath,0);
- }
- }
-#endif /* COMMENT */
-#endif /* aegis */
- shptr = shname = shpath;
- while (*shptr != '\0')
- if (*shptr++ == DIRSEP)
- shname = shptr;
- restorsigs(); /* Restore ignored signals */
- debug(F110,"zshcmd execl shpath",shpath,0);
- debug(F110,"zshcmd execl shname",shname,0);
- if (s == NULL || *s == '\0') { /* Interactive shell requested? */
- debug(F100,"zshcmd execl interactive","",0);
- execl(shpath,shname,"-i",NULL); /* Yes, do that */
- } else { /* Otherwise, */
- debug(F110,"zshcmd execl command",s,0);
- execl(shpath,shname,"-c",s,NULL); /* exec the given command */
- } /* If execl() failed, */
- debug(F101,"zshcmd errno","",errno);
- perror(shpath); /* print reason and */
- exit(BAD_EXIT); /* return bad return code. */
-
- } else { /* Parent */
-
- int wstat; /* ... must wait for child */
-#ifdef CK_CHILD
- int child; /* Child's exit status */
-#endif /* CK_CHILD */
- SIGTYP (*istat)(), (*qstat)();
-
- if (pid == (PID_T) -1) return(-1); /* fork() failed? */
-
- istat = signal(SIGINT,SIG_IGN); /* Let the fork handle keyboard */
- qstat = signal(SIGQUIT,SIG_IGN); /* interrupts itself... */
-
- debug(F110,"zshcmd parent waiting for child",s,0);
-#ifdef CK_CHILD
- while (((wstat = wait(&child)) != pid) && (wstat != -1))
-#else
- while (((wstat = wait((WAIT_T *)0)) != pid) && (wstat != -1))
-#endif /* CK_CHILD */
- ; /* Wait for fork */
- signal(SIGINT,istat); /* Restore interrupts */
- signal(SIGQUIT,qstat);
-#ifdef CK_CHILD
- pexitstat = (child & 0xff) ? child : child >> 8;
- debug(F101,"zshcmd exit status","",pexitstat);
- return(child == 0 ? 1 : 0); /* Return child's status */
-#endif /* CK_CHILD */
- }
- return(1);
-#endif /* NOPUSH */
-}
-
-/* I S W I L D -- Check if filespec is "wild" */
-
-/*
- Returns:
- 0 wildcards disabled or argument is empty or is the name of a single file;
- 1 if it contains wildcard characters.
- Note: must match the algorithm used by match(), hence no [a-z], etc.
-*/
-int
-iswild(filespec) char *filespec; {
- char c, *p, *f; int x;
- int quo = 0;
- if (!filespec) /* Safety */
- return(0);
- if (!wildena) /* Wildcards disabled - 12 Jun 2005 */
- return(0);
- f = filespec;
- if (wildxpand) { /* Shell handles wildcarding */
- if ((x = nzxpand(filespec,0)) > 1)
- return(1);
- if (x == 0) return(0); /* File does not exist */
- p = malloc(MAXNAMLEN + 20);
- znext(p);
- x = (strcmp(filespec,p) != 0);
- free(p);
- p = NULL;
- return(x);
- } else { /* We do it ourselves */
- while ((c = *filespec++) != '\0') {
- if (c == '\\' && quo == 0) {
- quo = 1;
- continue;
- }
- if (!quo && (c == '*' || c == '?'
-#ifdef CKREGEX
-#ifndef VMS
- || c == '['
-#endif /* VMS */
- || c == '{'
-#endif /* CKREGEX */
- )) {
- debug(F111,"iswild",f,1);
- return(1);
- }
- quo = 0;
- }
- debug(F111,"iswild",f,0);
- return(0);
- }
-}
-
-/*
- I S D I R -- Is a Directory.
-
- Tell if string pointer s is the name of an existing directory. Returns 1 if
- directory, 0 if not a directory.
-
- The following no longer applies:
-
- If the file is a symlink, we return 1 if
- it is a directory OR if it is a link to a directory and the "xrecursive" flag
- is NOT set. This is to allow parsing a link to a directory as if it were a
- directory (e.g. in the CD or IF DIRECTORY command) but still prevent
- recursive traversal from visiting the same directory twice.
-*/
-
-#ifdef ISDIRCACHE
-/* This turns out to be unsafe and gives little benefit anyway. */
-/* See notes 28 Sep 2003. Thus ISDIRCACHE is not defined. */
-
-static char prevpath[CKMAXPATH+4] = { '\0', '\0' };
-static int prevstat = -1;
-int
-clrdircache() {
- debug(F100,"CLEAR ISDIR CACHE","",0);
- prevstat = -1;
- prevpath[0] = NUL;
-}
-#endif /* ISDIRCACHE */
-
-int
-isalink(s) char *s; {
-#ifndef CKSYMLINK
- return(0);
-#else
- int r = 0;
- char filbuf[CKMAXPATH+4];
- if (readlink(s,filbuf,CKMAXPATH) > -1)
- r = 1;
- debug(F110,"isalink readlink",s,r);
- return(r);
-#endif /* CKSYMLINK */
-}
-
-int
-isdir(s) char *s; {
- int x, needrlink = 0, islink = 0;
- struct stat statbuf;
- char fnam[CKMAXPATH+4];
-
- if (!s) return(0);
- debug(F110,"isdir entry",s,0);
-#ifdef DTILDE /* 2005-08-13 */
- if (*s == '~') { /* Starts with tilde? */
- s = tilde_expand(s); /* Attempt to expand tilde */
- if (!s) s = "";
- debug(F110,"isdir tilde_expand",s,0);
- }
-#endif /* DTILDE */
- if (!*s) return(0);
-
-#ifdef ISDIRCACHE
- if (prevstat > -1) {
- if (s[0] == prevpath[0]) {
- if (!strcmp(s,prevpath)) {
- debug(F111,"isdir cache hit",s,prevstat);
- return(prevstat);
- }
- }
- }
-#endif /* ISDIRCACHE */
-
-#ifdef CKSYMLINK
-#ifdef COMMENT
-/*
- The following over-clever bit has been commented out because it presumes
- to know when a symlink might be redundant, which it can't possibly know.
- Using plain old stat() gives Kermit the same results as ls and ls -R, which
- is just fine: no surprises.
-*/
-#ifdef USE_LSTAT
- if (xrecursive) {
- x = lstat(s,&statbuf);
- debug(F111,"isdir lstat",s,x);
- } else {
-#endif /* USE_LSTAT */
- x = stat(s,&statbuf);
- debug(F111,"isdir stat",s,x);
-#ifdef USE_LSTAT
- }
-#endif /* USE_LSTAT */
-#else
- x = stat(s,&statbuf);
- debug(F111,"isdir stat",s,x);
-#endif /* COMMENT */
- if (x == -1) {
- debug(F101,"isdir errno","",errno);
- return(0);
- }
- islink = 0;
- if (xrecursive) {
-#ifdef NOLINKBITS
- needrlink = 1;
-#else
-#ifdef S_ISLNK
- islink = S_ISLNK(statbuf.st_mode);
- debug(F101,"isdir S_ISLNK islink","",islink);
-#else
-#ifdef _IFLNK
- islink = (_IFMT & statbuf.st_mode) == _IFLNK;
- debug(F101,"isdir _IFLNK islink","",islink);
-#endif /* _IFLNK */
-#endif /* S_ISLNK */
-#endif /* NOLINKBITS */
- if (needrlink) {
- if (readlink(s,fnam,CKMAXPATH) > -1)
- islink = 1;
- }
- }
-#else
- x = stat(s,&statbuf);
- if (x == -1) {
- debug(F101,"isdir errno","",errno);
- return(0);
- }
- debug(F111,"isdir stat",s,x);
-#endif /* CKSYMLINK */
- debug(F101,"isdir islink","",islink);
- debug(F101,"isdir statbuf.st_mode","",statbuf.st_mode);
- x = islink ? 0 : (S_ISDIR (statbuf.st_mode) ? 1 : 0);
-#ifdef ISDIRCACHE
- prevstat = x;
- ckstrncpy(prevpath,s,CKMAXPATH+1);
-#endif /* ISDIRCACHE */
- return(x);
-}
-
-#ifdef CK_MKDIR
-/* Some systems don't have mkdir(), e.g. Tandy Xenix 3.2.. */
-
-/* Z M K D I R -- Create directory(s) if necessary */
-/*
- Call with:
- A pointer to a file specification that might contain directory
- information. The filename is expected to be included.
- If the file specification does not include any directory separators,
- then it is assumed to be a plain file.
- If one or more directories are included in the file specification,
- this routine tries to create them if they don't already exist.
- Returns:
- 0 or greater on success, i.e. the number of directories created.
- -1 on failure to create the directory
-*/
-int
-zmkdir(path) char *path; {
- char *xp, *tp, c;
- int x, count = 0;
-
- if (!path) path = "";
- if (!*path) return(-1);
-
-#ifdef CKROOT
- debug(F111,"zmkdir setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(path)) {
- debug(F110,"zmkdir setroot violation",path,0);
- return(-1);
- }
-#endif /* CKROOT */
-
- x = strlen(path);
- debug(F111,"zmkdir",path,x);
- if (x < 1 || x > MAXPATH) /* Check length */
- return(-1);
- if (!(tp = malloc(x+1))) /* Make a temporary copy */
- return(-1);
- strcpy(tp,path); /* safe (prechecked) */
-#ifdef DTILDE
- if (*tp == '~') { /* Starts with tilde? */
- xp = tilde_expand(tp); /* Attempt to expand tilde */
- if (!xp) xp = "";
- if (*xp) {
- char *zp;
- debug(F110,"zmkdir tilde_expand",xp,0);
- if (!(zp = malloc(strlen(xp) + 1))) { /* Make a place for it */
- free(tp);
- tp = NULL;
- return(-1);
- }
- free(tp); /* Free previous buffer */
- tp = zp; /* Point to new one */
- strcpy(tp,xp); /* Copy expanded name to new buffer */
- }
- }
-#endif /* DTILDE */
- debug(F110,"zmkdir tp after tilde_expansion",tp,0);
- xp = tp;
- if (ISDIRSEP(*xp)) /* Don't create root directory! */
- xp++;
-
- /* Go thru filespec from left to right... */
-
- for (; *xp; xp++) { /* Create parts that don't exist */
- if (!ISDIRSEP(*xp)) /* Find next directory separator */
- continue;
- c = *xp; /* Got one. */
- *xp = NUL; /* Make this the end of the string. */
- if (!isdir(tp)) { /* This directory exists already? */
-#ifdef CK_LOGIN
- if (isguest) /* Not allowed for guests */
- return(-1);
-#ifndef NOXFER
- /* Nor if MKDIR and/or CD are disabled */
- else
-#endif /* CK_LOGIN */
- if ((server
-#ifdef IKSD
- || inserver
-#endif /* IKSD */
- ) && (!ENABLED(en_mkd) || !ENABLED(en_cwd)))
- return(-1);
-#endif /* IKSD */
-
- debug(F110,"zmkdir making",tp,0);
- x = /* No, try to create it */
-#ifdef NOMKDIR
- -1 /* Systems without mkdir() */
-#else
- mkdir(tp,0777) /* UNIX */
-#endif /* NOMKDIR */
- ;
- if (x < 0) {
- debug(F101,"zmkdir failed, errno","",errno);
- free(tp); /* Free temporary buffer. */
- tp = NULL;
- return(-1); /* Return failure code. */
- } else
- count++;
- }
- *xp = c; /* Replace the separator. */
- }
- free(tp); /* Free temporary buffer. */
- return(count); /* Return success code. */
-}
-#endif /* CK_MKDIR */
-
-int
-zrmdir(path) char *path; {
-#ifdef CK_LOGIN
- if (isguest)
- return(-1);
-#endif /* CK_LOGIN */
-
- if (!path) path = "";
- if (!*path) return(-1);
-
-#ifdef CKROOT
- debug(F111,"zrmdir setroot",ckroot,ckrootset);
- if (ckrootset) if (!zinroot(path)) {
- debug(F110,"zrmdir setroot violation",path,0);
- return(-1);
- }
-#endif /* CKROOT */
-
-#ifndef NOMKDIR
- return(rmdir(path));
-#else
- return(-1);
-#endif /* NOMKDIR */
-}
-
-/* Z F S E E K -- Position input file pointer */
-/*
- Call with:
- CK_OFF_T (32 or 64 bits), 0-based, indicating desired position.
- Returns:
- 0 on success.
- -1 on failure.
-*/
-#ifndef NORESEND
-int
-#ifdef CK_ANSIC
-zfseek(CK_OFF_T pos)
-#else
-zfseek(pos) CK_OFF_T pos;
-#endif /* CK_ANSIC */
-/* zfseek */ {
- zincnt = -1; /* Must empty the input buffer */
- debug(F101,"zfseek","",pos);
- return(CKFSEEK(fp[ZIFILE], pos, 0)?-1:0);
-}
-#endif /* NORESEND */
-
-/* Z F N Q F P -- Convert filename to fully qualified absolute pathname */
-
-/*
- Given a possibly unqualified or relative file specification fn, zfnqfp()
- returns the fully qualified filespec for the same file, returning a struct
- that contains the length (len) of the result, a pointer (fpath) to the
- whole result, and a pointer (fname) to where the filename starts.
-*/
-static struct zfnfp fnfp = { 0, NULL, NULL };
-
-struct zfnfp *
-zfnqfp(fname, buflen, buf) char * fname; int buflen; char * buf; {
- char * s;
- int len;
-#ifdef MAXPATHLEN
- char zfntmp[MAXPATHLEN+4];
-#else
- char zfntmp[CKMAXPATH+4];
-#endif /* MAXPATHLEN */
-
- char sb[32], * tmp;
- int i = 0, j = 0, k = 0, x = 0, y = 0;
- int itsadir = 0;
-
- s = fname;
- if (!s)
- return(NULL);
- if (!*s)
- return(NULL);
- if (!buf)
- return(NULL);
-
- /* Initialize the data structure */
-
- fnfp.len = ckstrncpy(buf,fname,buflen);
- fnfp.fpath = buf;
- fnfp.fname = NULL;
- len = buflen;
- debug(F111,"zfnqfp fname",fname,len);
-
-#ifdef DTILDE
- if (*s == '~') { /* Starts with tilde? */
- char * xp;
- xp = tilde_expand(s); /* Attempt to expand tilde */
- debug(F110,"zfnqfp xp",xp,0); /* (realpath() doesn't do this) */
- if (!xp) xp = "";
- if (*xp)
- s = xp;
- }
-#endif /* DTILDE */
-
-#ifdef CKREALPATH
-
-/* N.B.: The realpath() result buffer MUST be MAXPATHLEN bytes long */
-/* otherwise we write over memory. */
-
- if (!realpath(s,zfntmp)) {
- debug(F111,"zfnqfp realpath fails",s,errno);
-#ifdef COMMENT
- if (errno != ENOENT)
- return(NULL);
-#else
- /* If realpath() fails use the do-it-yourself method */
- /* 16 Jan 2002 */
- goto norealpath;
-#endif /* COMMENT */
- }
- len = strlen(zfntmp);
- if (len > buflen) {
- debug(F111,"zfnqfp result too long",ckitoa(buflen),len);
- return(NULL);
- } else {
- ckstrncpy(buf,zfntmp,buflen);
- }
- if (buf[len-1] != '/') {
- if ((itsadir = isdir(buf)) && len < (buflen - 1)) {
- buf[len++] = '/';
- buf[len] = NUL;
- }
- }
- fnfp.len = len;
- fnfp.fpath = buf;
- debug(F110,"zfnqfp realpath path",fnfp.fpath,0);
- tmp = buf + fnfp.len - 1;
- if (!itsadir) {
- while (tmp >= buf) {
- if (*tmp == '/') {
- fnfp.fname = tmp + 1;
- debug(F110,"zfnqfp realpath name",fnfp.fname,0);
- break;
- }
- tmp--;
- }
- }
- return(&fnfp);
-
-#endif /* CKREALPATH */
-
- norealpath:
-
- tmp = zfntmp;
- while (*s) { /* Remove leading "./" (0 or more) */
- debug(F110,"zfnqfp while *s",s,0);
- if (*s == '.' && *(s+1) == '/') {
- s += 2;
- while (*s == '/') s++;
- } else
- break;
- }
- if (!*s) return(NULL);
- if (*s == '/') { /* Pathname is absolute */
- ckstrncpy(buf,s,len);
- x = strlen(buf);
- y = 0;
- } else { /* Pathname is relative */
- char * p;
- if (p = zgtdir()) { /* So get current directory */
- debug(F110,"zfnqfp zgtdir",p,0);
- x = ckstrncpy(buf,p,len);
- buf[x++] = '/';
- debug(F110,"zfnqfp buf 1",buf,0);
- len -= x; /* How much room left in buffer */
- if ((y = (int)strlen(s)) > len) /* If enough room... */
- return(NULL);
- ckstrncpy(buf+x,s,len); /* ... append the filename */
- debug(F110,"zfnqfp buf 2",buf,0);
- } else {
- return(NULL);
- }
- }
-
- /* Buf now holds full path but maybe containing some . or .. tricks */
-
- j = x + y; /* Length of what's in buf */
- len = j;
- debug(F101,"zfnqfp len","",len);
-
- /* Catch dangling "/." or "/.." */
- if ((j > 1 && buf[j-1] == '.' && buf[j-2] == '/') ||
- (j > 2 && buf[j-1] == '.' && buf[j-2] == '.' && buf[j-3] == '/')) {
- if (j < buflen - 2) {
- buf[j] = '/';
- buf[j+1] = NUL;
- }
- }
- j = -1; /* j = position of rightmost "/" */
- i = 0; /* i = destination index */
- tmp[i] = NUL; /* destination is temporary buffer */
-
- for (x = 0; x < len; x++) { /* x = source index */
- if (buf[x] == '/') {
- for (k = 0; k < 4; k++) {
- sb[k] = buf[x+k];
- sb[k+1] = '\0';
- if (!sb[k]) break;
- }
- if (!strncmp(sb,"/./",3)) { /* Eliminate "./" in "/./" */
- x += 1;
- continue;
- } else if (!strncmp(sb,"//",2)) { /* Change "//" to "/" */
- continue;
- } else if (!strncmp(sb,"/../",4)) { /* ".." in path */
- for (k = i - 1; k >= 0; k--) { /* Back up one level */
- if (tmp[k] == '/') {
- i = k;
- tmp[i] = NUL;
- break;
- }
- }
- x += 2;
- continue;
- }
- }
- if (i >= (buflen - 1)) {
- debug(F111,"zfnqfp overflow",tmp,i);
- return(NULL);
- }
- tmp[i++] = buf[x]; /* Regular character, copy */
- tmp[i] = NUL;
- if (buf[x] == '/') /* Remember rightmost "/" */
- j = i;
- }
- ckstrncpy(buf,tmp,buflen-1); /* Copy the result back */
-
- buf[buflen-1] = NUL;
- if (!buf[0]) { /* If empty, say root */
- buf[0] = '/';
- buf[2] = NUL;
- j = 0;
- i = 1;
- }
- if ((itsadir = isdir(buf))) {
- if (buf[i-1] != '/' && i < (buflen - 1)) {
- buf[i++] = '/';
- buf[i] = NUL;
- }
- }
- if (!itsadir && (j > -1)) { /* Set pointer to basename */
- fnfp.fname = (char *)(buf + j);
- fnfp.fpath = (char *)buf;
- fnfp.len = i;
- debug(F111,"zfnqfp path",fnfp.fpath,i);
- debug(F110,"zfnqfp name",fnfp.fname,0);
- return(&fnfp);
- }
- return(NULL);
-}
-
-/* Z C M P F N -- Compare two filenames */
-
-/* Returns 1 if the two names refer to the same existing file, 0 otherwise. */
-
-int
-zcmpfn(s1,s2) char * s1, * s2; {
- char buf1[CKMAXPATH+1];
- char buf2[CKMAXPATH+1];
-
-#ifdef USE_LSTAT
- char linkname[CKMAXPATH+1];
- struct stat buf;
-#endif /* USE_LSTAT */
- int x, rc = 0;
-
- if (!s1) s1 = "";
- if (!s2) s2 = "";
- if (!*s1 || !*s2) return(0);
-
-#ifdef CKSYMLINK /* We're doing symlinks? */
-#ifdef USE_LSTAT /* OK to use lstat()? */
- x = lstat(s1,&buf);
- if (x > -1 && /* Now see if it's a symlink */
-#ifdef S_ISLNK
- S_ISLNK(buf.st_mode)
-#else
-#ifdef _IFLNK
- ((_IFMT & buf.st_mode) == _IFLNK)
-#endif /* _IFLNK */
-#endif /* S_ISLNK */
- ) {
- linkname[0] = '\0'; /* Get the name */
- x = readlink(s1,linkname,CKMAXPATH);
- if (x > -1 && x < CKMAXPATH) { /* It's a link */
- linkname[x] = '\0';
- s1 = linkname;
- }
- }
-#endif /* USE_LSTAT */
-#endif /* CKSYMLINK */
-
- if (zfnqfp(s1,CKMAXPATH,buf1)) { /* Convert to full pathname */
-
-#ifdef CKSYMLINK /* Same deal for second name... */
-#ifdef USE_LSTAT
- x = lstat(s2,&buf);
- if (x > -1 &&
-#ifdef S_ISLNK
- S_ISLNK(buf.st_mode)
-#else
-#ifdef _IFLNK
- ((_IFMT & buf.st_mode) == _IFLNK)
-#endif /* _IFLNK */
-#endif /* S_ISLNK */
- ) {
- linkname[0] = '\0';
- x = readlink(s2,linkname,CKMAXPATH);
- if (x > -1 && x < CKMAXPATH) {
- linkname[x] = '\0';
- s2 = linkname;
- }
- }
-#endif /* USE_LSTAT */
-#endif /* CKSYMLINK */
- if (zfnqfp(s2,CKMAXPATH,buf2)) {
- debug(F110,"zcmpfn s1",buf1,0);
- debug(F110,"zcmpfn s2",buf2,0);
- if (!strncmp(buf1,buf2,CKMAXPATH))
- rc = 1;
- }
- }
- debug(F101,"zcmpfn result","",rc);
- return(rc);
-}
-
-#ifdef CKROOT
-
-/* User-mode chroot() implementation */
-
-int
-zsetroot(s) char * s; { /* Sets the root */
- char buf[CKMAXPATH+1];
- if (!s) return(-1);
- if (!*s) return(-1);
- debug(F110,"zsetroot",s,0);
- if (!isdir(s)) return(-2);
- if (!zfnqfp(s,CKMAXPATH,buf)) /* Get full, real path */
- return(-3);
- if (access(buf,R_OK) < 0) { /* Check access */
- debug(F110,"zsetroot access denied",buf,0);
- return(-4);
- }
- s = buf;
- if (ckrootset) { /* If root already set */
- if (!zinroot(s)) { /* make sure new root is in it */
- debug(F110,"zsetroot new root not in root",ckroot,0);
- return(-5);
- }
- }
- if (zchdir(buf) < 1) return(-4); /* Change directory to new root */
- ckrootset = ckstrncpy(ckroot,buf,CKMAXPATH); /* Now set the new root */
- if (ckroot[ckrootset-1] != '/') {
- ckroot[ckrootset++] = '/';
- ckroot[ckrootset] = '\0';
- }
- debug(F111,"zsetroot rootset",ckroot,ckrootset);
- ckrooterr = 0; /* Reset error flag */
- return(1);
-}
-
-char *
-zgetroot() { /* Returns the root */
- if (!ckrootset)
- return(NULL);
- return((char *)ckroot);
-}
-
-int
-zinroot(s) char * s; { /* Checks if file s is in the root */
- int x, n;
- struct zfnfp * f = NULL;
- char buf[CKMAXPATH+2];
-
- debug(F111,"zinroot setroot",ckroot,ckrootset);
- ckrooterr = 0; /* Reset global error flag */
- if (!ckrootset) /* Root not set */
- return(1); /* so it's ok - no need to check */
- if (!(f = zfnqfp(s,CKMAXPATH,buf))) /* Get full and real pathname */
- return(0); /* Fail if we can't */
- n = f->len; /* Length of full pathname */
- debug(F111,"zinroot n",buf,n);
- if (n < (ckrootset - 1) || n > CKMAXPATH) { /* Bad length */
- ckrooterr = 1; /* Fail */
- return(0);
- }
- if (isdir(buf) && buf[n-1] != '/') { /* If it's a directory name */
- buf[n++] = '/'; /* make sure it ends with '/' */
- buf[n] = '\0';
- }
- x = strncmp(buf,ckroot,ckrootset); /* Compare, case-sensitive */
- debug(F111,"zinroot checked",buf,x);
- if (x == 0) /* OK */
- return(1);
- ckrooterr = 1; /* Not OK */
- return(0);
-}
-#endif /* CKROOT */
-
-#ifdef CK_LOGIN
-/*
- The following code provides support for user login and logout
- including anonymous accounts. If this feature is to be supported
- outside of UNIX, it should be spread out among the ck?fio.c modules...
-*/
-#ifndef _PATH_BSHELL
-#define _PATH_BSHELL "/usr/bin/bash"
-#endif /* _PATH_BSHELL */
-#ifndef _PATH_FTPUSERS
-#define _PATH_FTPUSERS "/etc/ftpusers"
-#endif /* _PATH_FTPUSERS */
-
-/*
- * Helper function for sgetpwnam().
- */
-char *
-sgetsave(s) char *s; {
- char *new = malloc((unsigned) strlen(s) + 1);
- if (new == NULL) {
- printf("?Local resource failure: malloc\n");
- exit(1);
- /* NOTREACHED */
- }
- (void) strcpy(new, s); /* safe */
- return (new);
-}
-
-/*
- * Save the result of getpwnam(). Used for USER command, since
- * the data returned must not be clobbered by any other command
- * (e.g., globbing).
- */
-struct passwd *
-sgetpwnam(name) char *name; {
- static struct passwd save;
- register struct passwd *p;
-#ifdef CK_SHADOW
- register struct spwd *sp;
-#endif /* CK_SHADOW */
- char *sgetsave();
-
-#ifdef HPUX10_TRUSTED
- struct pr_passwd *pr;
-#endif /* HPUX10_TRUSTED */
-
-#ifdef CK_SHADOW
- sp = getspnam(name);
- if (sp == NULL) {
- debug(F110,"sgetpwnam","getspnam() fails",0);
- return (NULL);
- }
-#endif /* CK_SHADOW */
-
-#ifdef HPUX10_TRUSTED
- if ((pr = getprpwnam(name)) == NULL)
- return(NULL);
-#endif /* HPUX10_TRUSTED */
-
- p = getpwnam(name);
- /* debug(F111,"sgetpwnam","getpwnam()",p); */
- if (p == NULL)
- return(NULL);
- if (save.pw_name) {
- free(save.pw_name);
- free(save.pw_passwd);
- free(save.pw_gecos);
- free(save.pw_dir);
- free(save.pw_shell);
- }
- save = *p;
- save.pw_name = sgetsave(p->pw_name);
-#ifdef CK_SHADOW
- save.pw_passwd = sgetsave(sp->sp_pwdp);
-#else /* CK_SHADOW */
-#ifdef HPUX10_TRUSTED
- if (pr->uflg.fg_encrypt && pr->ufld.fd_encrypt && *pr->ufld.fd_encrypt)
- save.pw_passwd = sgetsave(pr->ufld.fd_encrypt);
- else
- save.pw_passwd = sgetsave("");
-#else /* HPUX10_TRUSTED */
- save.pw_passwd = sgetsave(p->pw_passwd);
-#endif /* HPUX10_TRUSTED */
-#endif /* CK_SHADOW */
- save.pw_gecos = sgetsave(p->pw_gecos);
- save.pw_dir = sgetsave(p->pw_dir);
- save.pw_shell = sgetsave(p->pw_shell);
- return(&save);
-}
-
-#define CKXLOGBSIZ 256
-
-struct passwd * pw = NULL;
-char * home = NULL; /* Home directory pointer for glob */
-#ifdef CMASK
-#undef CMASK
-#endif /* CMASK */
-
-#define CMASK 027
-
-int defumask = CMASK; /* Default umask value */
-
-/* Z V U S E R -- Verify user, Returns 1 if user OK, 0 otherwise. */
-
-/* Sets global passwd pointer pw if named account exists and is acceptable;
- * sets askpasswd if a PASS command is expected. If logged in previously,
- * need to reset state. If name is "ftp" or "anonymous", the name is not in
- * _PATH_FTPUSERS, and ftp account exists, set guest and pw, then just return.
- * If account doesn't exist, ask for passwd anyway. Otherwise, check user
- * requesting login privileges. Disallow anyone who does not have a standard
- * shell as returned by getusershell(). Disallow anyone mentioned in the file
- * _PATH_FTPUSERS to allow people such as root and uucp to be avoided.
- */
-_PROTOTYP(static int checkuser, (char *) );
-
-char zvuname[64] = { NUL, NUL };
-char zvhome[CKMAXPATH+1] = { NUL, NUL };
-#define ZENVUSER 70
-#define ZENVHOME CKMAXPATH+12
-#define ZENVLOGNAME 74
-static char zenvuser[ZENVUSER];
-static char zenvhome[ZENVHOME];
-static char zenvlogname[ZENVLOGNAME];
-
-#ifdef CK_PAM
-static char pam_data[500];
-struct pam_conv pam_conv = {pam_cb, pam_data}; /* PAM structure */
-struct pam_handle * pamh = NULL; /* PAM reference handle */
-#endif /* CK_PAM */
-
-int
-zvuser(name) char *name; {
- register char *cp = NULL;
- int x;
- char *shell;
-#ifdef GETUSERSHELL
-_PROTOTYP(char * getusershell, (void) );
-#endif /* GETUSERSHELL */
-#ifndef NODCLENDUSERSHELL
-_PROTOTYP(VOID endusershell, (void) );
-#endif /* NODCLENDUSERSHELL */
-
-#ifdef CK_PAM
- int pam_status;
- const char * reply = NULL;
-#endif /* CK_PAM */
-
- debug(F111,"user",name,logged_in);
-
- if (!name) name = "";
- zvuname[0] = NUL;
-
- debug(F101,"zvuser ckxsyslog","",ckxsyslog);
-
-#ifdef CKSYSLOG
- debug(F100,"zvuser CKSYSLOG defined","",0);
-#endif /* CKSYSLOG */
-
- if (logged_in) /* Should not be called if logged in */
- return(0);
-
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging) {
- syslog(LOG_INFO,
- "login: user %s",name
- );
- }
-#endif /* CKSYSLOG */
-
- guest = 0; /* Assume not guest */
- askpasswd = 0;
-
- if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
- debug(F101,"zvuser anonymous ckxanon","",ckxanon);
- if (!ckxanon) { /* Anonymous login not allowed */
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging) {
- syslog(LOG_INFO,
- "login: anonymous login not allowed: %s",
- clienthost ? clienthost : "(unknown host)"
- );
- }
-#endif /* CKSYSLOG */
- return(0);
- }
- if (checkuser("ftp") || checkuser("anonymous")) {
- debug(F100,"zvuser anon forbidden by ftpusers file","",0);
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging) {
- syslog(LOG_INFO,
- "login: anonymous login forbidden by ftpusers file: %s",
- clienthost ? clienthost : "(unknown host)"
- );
- }
-#endif /* CKSYSLOG */
- return(0);
- } else if ((pw = sgetpwnam("ftp")) != NULL) {
- debug(F100,"zvuser anon sgetpwnam(ftp) OK","",0);
- guest = 1;
- askpasswd = 1;
- ckstrncpy(zvuname,"anonymous",64);
- return(1);
- } else {
- debug(F100,"zvuser anon sgetpwnam(ftp) FAILED","",0);
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging) {
- syslog(LOG_INFO,
- "login: anonymous getpwnam(ftp) failed: %s",
- clienthost ? clienthost : "(unknown host)"
- );
- }
-#endif /* CKSYSLOG */
- return(0);
- }
- }
- pw = sgetpwnam(name);
- if (pw) {
-/*
- Of course some UNIX platforms (like AIX) don't have getusershell().
- In that case we can't check if the user's account has been "turned off"
- or somesuch, e.g. by setting their shell to "/etc/nologin" or somesuch,
- which runs (usually just printing a message and exiting), but which is
- not listed in /etc/shells. For that matter, if getusershell() is not
- available, then probably neither is /etc/shells.
-*/
- debug(F100,"zvuser sgetpwnam ok","",0);
- shell = pw->pw_shell;
- if (!shell) shell = "";
- if (!*shell)
- shell = _PATH_BSHELL;
- debug(F110,"zvuser shell",shell,0);
-#ifdef GETUSERSHELL
- while ((cp = getusershell()) != NULL) {
- debug(F110,"zvuser getusershell",cp,0);
- if ((int)strcmp(cp, shell) == 0)
- break;
- }
- debug(F100,"zvuser endusershell 1","",0);
-#ifndef NODCLENDUSERSHELL
- (VOID) endusershell();
-#else
- endusershell();
-#endif /* NODCLENDUSERSHELL */
- debug(F100,"zvuser endusershell 2","",0);
-#else /* GETUSERSHELL */
- cp = ""; /* Do not refuse if we cannot check */
-#endif /* GETUSERSHELL */
- x = checkuser(name);
- debug(F101,"zvuser checkuser","",x);
- if (cp == NULL) {
- debug(F100,"zvuser refused 1","",0);
- pw = (struct passwd *) NULL;
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging) {
- syslog(LOG_INFO,
- "login: invalid shell %s for %s %s",shell, name,
- clienthost ? clienthost : "(unknown host)"
- );
- }
-#endif /* CKSYSLOG */
- return(0);
- } else if (x) {
- debug(F100,"zvuser refused 2","",0);
- pw = (struct passwd *) NULL;
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging) {
- syslog(LOG_INFO,
- "login: %s login forbidden by ftpusers file: %s",
- name, clienthost ? clienthost : "(unknown host)"
- );
- }
-#endif /* CKSYSLOG */
- return(0);
- } else {
- x = 0;
-#ifdef CK_PAM
- /* Get PAM authentication details */
- debug(F110,"zvuser","calling pam_start",0);
- if ((pam_status =
- pam_start(PAM_SERVICE_TYPE,name,&pam_conv,&pamh))
- != PAM_SUCCESS) {
- reply = pam_strerror(NULL, pam_status);
- debug(F110,"zvuser PAM failure",reply,0);
- printf("%s\n",reply);
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging) {
- syslog(LOG_INFO,
- "login: %s refused by PAM \"%s\": %s",
- name,reply,
- clienthost ? clienthost : "(unknown host)"
- );
- }
-#endif /* CKSYSLOG */
- return(0);
- }
-#endif /* CK_PAM */
- askpasswd = 1;
- ckstrncpy(zvuname,name,64);
- return(1);
- }
- } else {
- x = 0;
- debug(F100,"zvuser sgetpwnam NULL","",0);
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging) {
- syslog(LOG_INFO,
- "login: getpwnam(%s) failed: %s",name,
- clienthost ? clienthost : "(unknown host)"
- );
- }
-#endif /* CKSYSLOG */
- return(0);
- }
-
-#ifdef FTP_KERBEROS
- if (auth_type && strcmp(auth_type, "KERBEROS_V4") == 0) {
-#ifdef COMMENT
- /* Why sprintf and then printf? */
- /* Also, what is kerb_ok? And is the test on it right? */
- char buf[CKXLOGBSIZ];
- sprintf(buf, "Kerberos user %s%s%s@%s is%s authorized as %s%s",
- kdata.pname, *kdata.pinst ? "." : "",
- kdata.pinst, kdata.prealm,
- (kerb_ok = kuserok(&kdata,name) == 0) ? "" : " not",
- name, kerb_ok ? "" : "; Password required.");
- printf("%s", buf);
-#else
- printf("Kerberos user %s%s%s@%s is%s authorized as %s%s",
- kdata.pname, *kdata.pinst ? "." : "",
- kdata.pinst, kdata.prealm,
- (kerb_ok = kuserok(&kdata,name) == 0) ? "" : " not",
- name, kerb_ok ? "" : "; Password required.");
-#endif /* COMMENT */
- if (kerb_ok) return(1);
- } else
- return(0);
-#endif /* FTP_KERBEROS */
-}
-
-/* Check if the given user is in the forbidden-user file */
-
-static int
-checkuser(name) char *name; {
- extern char * userfile;
- FILE *fd;
- int i;
- char line[CKXLOGBSIZ+1];
-
- if (!name)
- name = "";
- i = strlen(name);
- debug(F111,"checkuser name",name,i);
- if (!*name)
- return(1);
-
- fd = fopen(userfile ? userfile : _PATH_FTPUSERS, "r");
- /* debug(F111,"checkuser userfile",userfile,fd); */
- if (fd) {
- line[0] = '\0';
- while (fgets(line, sizeof(line), fd)) {
- debug(F110,"checkuser line",line,0);
- if (line[0] <= '#')
- continue;
- if (strncmp(line, name, i) == 0) {
- debug(F110,"checkuser REFUSED",name,0);
- return(1);
- }
- line[0] = '\0';
- }
- (VOID) fclose(fd);
- }
- debug(F110,"checkuser OK",name,0);
- return(0);
-}
-
-/* Z V L O G O U T -- Log out from Internet Kermit Service */
-
-VOID
-zvlogout() {
-#ifdef COMMENT
- /* This could be dangerous */
- if (setuid((UID_T)0) < 0) {
- debug(F100,"zvlogout setuid FAILED","",0);
- goto bad;
- }
- debug(F100,"zvlogout setuid OK","",0);
-#endif /* COMMENT */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- cksyslog(SYSLG_LI, 1, "logout",(char *) uidbuf, clienthost);
- }
-#endif /* CKSYSLOG */
-#ifdef CKWTMP
- debug(F110,"WTMP logout",cksysline,logged_in);
- if (logged_in)
- logwtmp(cksysline, "", "");
-#endif /* CKWTMP */
- pw = NULL;
- logged_in = 0;
- guest = 0;
- isguest = 0;
-}
-
-#ifdef FTP_KERBEROS
-kpass(name, p) char *name, *p; {
- char instance[INST_SZ];
- char realm[REALM_SZ];
- char tkt_file[20];
- KTEXT_ST ticket;
- AUTH_DAT authdata;
- unsigned long faddr;
- struct hostent *hp;
-
- if (krb_get_lrealm(realm, 1) != KSUCCESS)
- return(0);
-
- ckstrncpy(tkt_file, TKT_ROOT, 20);
- ckstrncat(tkt_file, "_ftpdXXXXXX", 20);
- krb_set_tkt_string(mktemp(tkt_file));
-
- (VOID) ckstrncpy(instance, krb_get_phost(hostname), sizeof(instance));
-
- if ((hp = gethostbyname(instance)) == NULL)
- return(0);
-
-#ifdef HADDRLIST
- hp = ck_copyhostent(hp); /* safe copy that won't change */
-#endif /* HADDRLIST */
- bcopy((char *)hp->h_addr, (char *) &faddr, sizeof(faddr));
-
- if (krb_get_pw_in_tkt(name, "", realm, "krbtgt", realm, 1, p) ||
- krb_mk_req(&ticket, "rcmd", instance, realm, 33) ||
- krb_rd_req(&ticket, "rcmd", instance, faddr, &authdata, "") ||
- kuserok(&authdata, name)) {
- dest_tkt();
- return(0);
- }
- dest_tkt();
- return(1);
-}
-#endif /* FTP_KERBEROS */
-
-VOID
-zsyslog() {
-#ifdef CKSYSLOG
- if (ckxsyslog && !ckxlogging) {
-#ifdef LOG_DAEMON
- openlog(inserver ? "iksd" : "ckermit", LOG_PID, LOG_DAEMON);
-#else
- openlog(inserver ? "iksd" : "ckermit", LOG_PID);
-#endif /* LOG_DAEMON */
- ckxlogging = 1;
- debug(F100,"zsyslog syslog opened","",0);
- }
-#endif /* CKSYSLOG */
-}
-
-/* Z V P A S S -- Verify password; returns 1 if OK, 0 otherwise */
-
-#ifndef AUTH_USER
-#define AUTH_USER 3
-#endif /* AUTH_USER */
-#ifndef AUTH_VALID
-#define AUTH_VALID 4
-#endif /* AUTH_VALID */
-
-#ifdef __FreeBSD__ /* 299 This was necessary in */
-#ifndef NODCLINITGROUPS /* FreeBSD 4.4, don't know */
-#define NODCLINITGROUPS /* about other versions... */
-#endif /* NODCLINITGROUPS */
-#endif /* __FreeBSD__ */
-
-int
-zvpass(p) char *p; {
-#ifndef NODCLINITGROUPS
-_PROTOTYP(int initgroups, (const char *, gid_t) );
-#endif /* NODCLINITGROUPS */
-
- char *xpasswd, *salt;
- char * dir = NULL;
-#ifdef CK_PAM
- int pam_status;
- const char * reply = NULL;
-#endif /* CK_PAM */
-
- if (logged_in || askpasswd == 0) {
- return(0);
- }
- debug(F111,"zvpass",p ? (guest ? p : "xxxxxx") : "(null)",guest);
- if (!p) p = "";
- askpasswd = 0;
- if (guest && !*p) { /* Guests must specify a password */
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging) {
- syslog(LOG_INFO,
- "login: anonymous guests must specify a password"
- );
- }
-#endif /* CKSYSLOG */
- return(0);
- }
- if (!guest
-#ifdef CK_AUTHENTICATION
- && ck_tn_auth_valid() != AUTH_VALID
-#endif /* CK_AUTHENTICATION */
- ) { /* "ftp" is only account allowed no password */
-#ifdef CK_PAM
- debug(F110,"zvpass","calling pam_set_item(AUTHTOK)",0);
- if ((pam_status = pam_set_item(pamh,PAM_AUTHTOK,p)) != PAM_SUCCESS) {
- reply = pam_strerror(pamh, pam_status);
- debug(F110,"zvpass PAM failure",reply,0);
- /* if no password given treat as non-fatal error */
- /* pam will prompt for password in pam_authenticate() */
- if (!p) {
- printf("%s\n",reply);
- pam_end(pamh, 0);
- debug(F100,"zvpass denied","",0);
- pw = NULL;
- zvuname[0] = NUL;
- return(0);
- }
- }
- debug(F110,"zvpass","calling pam_authenticate",0);
-#ifdef COMMENT
- if (*p)
- pam_pw = p;
-#else
-/*
- Make IKSD authentication (using PAM) ask for a password when an
- invalid username has been given, to avoid disclosing which account
- names are valid. See #417247 (Debian).
-*/
- if (*p
-#ifdef CK_LOGIN
- || gotemptypasswd
-#endif /* CK_LOGIN */
- )
- pam_pw = p;
-#endif /* COMMENT */
- if ((pam_status = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
- reply = pam_strerror(pamh, pam_status);
- debug(F110,"zvpass PAM failure",reply,0);
- printf("%s\n",reply);
- pam_end(pamh, 0);
- debug(F100,"zvpass denied","",0);
- pam_pw = NULL;
- pw = NULL;
- zvuname[0] = NUL;
- return(0);
- }
- pam_pw = NULL;
- debug(F110,"zvpass","calling pam_acct_mgmt",0);
- if ((pam_status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS) {
- reply = pam_strerror(pamh, pam_status);
- debug(F110,"zvpass PAM failure",reply,0);
- printf("%s\n",reply);
- pam_end(pamh, 0);
- debug(F100,"zvpass denied","",0);
- pw = NULL;
- zvuname[0] = NUL;
- return(0);
- }
- debug(F110,"zvpass","PAM validates OK",0);
- pam_end(pamh,0);
-#else /* CK_PAM */
- if (pw == NULL)
- salt = "xx";
- else
- salt = pw->pw_passwd;
-
-#ifdef HPUX10_TRUSTED
- xpasswd = bigcrypt(p, salt);
-#else
-/*
- On 64-bit platforms this can give "cast to pointer from integer of
- different size" warning, but I'm not sure what the effect is at runtime,
- or what to do about it.
- */
- xpasswd = (char *)crypt(p, salt);
-#endif /* HPUX10_TRUSTED */
-
- if (
-#ifdef FTP_KERBEROS
- /* null pw_passwd ok if Kerberos password ok */
- pw == NULL ||
- ((*pw->pw_passwd != '\0' ||
- strcmp(xpasswd, pw->pw_passwd))
- && !kpass(pw->pw_name, p))
-#else
-#ifdef CK_SRP
- /* check with tpasswd first if there */
- pw == NULL || *pw->pw_passwd == '\0' ||
- t_verifypw (pw->pw_name, p) == 0 ||
- (t_verifypw (pw->pw_name, p) < 0 &&
- strcmp (xpasswd, pw->pw_passwd))
-#else /* CK_SRP */
- /* The strcmp does not catch null passwords! */
- (pw == NULL) || (*pw->pw_passwd == '\0') ||
- strcmp(xpasswd, pw->pw_passwd)
-#endif /* CK_SRP */
-#endif /* FTP_KERBEROS */
- ) {
- debug(F100,"zvpass denied","",0);
- pw = NULL;
- zvuname[0] = NUL;
- return(0);
- }
-#endif /* CK_PAM */
- }
-
- (VOID) setgid((GID_T)pw->pw_gid); /* Set group ID */
-
-#ifndef NOINITGROUPS
- (VOID) initgroups(pw->pw_name, pw->pw_gid);
-#endif /* NOINITGROUPS */
-
- logged_in = 1;
- dir = pw->pw_dir;
-
-#ifdef CKWTMP
- /* Open wtmp before chroot */
- if (ckxwtmp) {
- sprintf(cksysline,"iks_%04x", getpid()); /* safe */
- logwtmp(cksysline, pw->pw_name,
- clienthost ? clienthost : "(unknown host)"
- );
- debug(F110,"WTMP login",cksysline,logged_in);
- }
-#endif /* CKWTMP */
-/*
- For anonymous users, we chroot to user ftp's home directory unless
- started with --anonroot:xxx, in which case we chroot to xxx. We must
- immediately chdir() to the same directory we chroot() to or else the
- old current directory remains accessible as "." outside the new root.
-*/
- if (guest) {
- if (anonroot) /* Non-default anonymous root */
- dir = anonroot;
- else
- makestr(&anonroot,dir);
- errno = 0;
- debug(F110,"zvpass anon chroot",dir,0);
- if (chroot(dir) < 0) {
- debug(F111,"zvpass anon chroot FAILED",dir,errno);
- goto bad;
- }
- errno = 0;
- if (chdir("/") < 0) {
- debug(F111,"zvpass anon chdir FAILED",dir,errno);
- goto bad;
- }
- debug(F110,"zvpass anon chroot/chdir OK",dir,0);
- } else if (chdir(dir) < 0) { /* Not guest */
-#ifdef COMMENT
- if (chdir("/") < 0) {
- debug(F110,"Non-guest chdir FAILED",dir,0);
- goto bad;
- } else
- printf("?No directory! Logging in with home=/\n");
-#else
- debug(F110,"zvpass non-guest chdir FAILED",dir,0);
- goto bad; /* Be conservative at first */
-#endif /* COMMENT */
- }
- debug(F110,"zvpass non-guest chdir OK",dir,0);
- if (setuid((UID_T)pw->pw_uid) < 0) {
- debug(F101,"zvpass setuid FAILED","",pw->pw_uid);
- goto bad;
- }
- debug(F101,"zvpass setuid OK","",pw->pw_uid);
-
- guestpass[0] = '\0';
- if (guest) {
- extern int fncact;
- isguest = 1;
- fncact = XYFX_R; /* FILE COLLISION = RENAME */
- debug(F110,"GUEST fncact=R",p,0);
- lset(guestpass,"anonymous:",10,32);
- ckstrncpy(&guestpass[10],p,GUESTPASS-10);
- home = "/";
- printf("Anonymous login.\r\n");
-
-#ifdef SETPROCTITLE
- /* proctitle declared where? Obviously this code is never compiled. */
- sprintf(proctitle, "%s: anonymous/%.*s",
- clienthost ? clienthost : "(unk)",
- sizeof(proctitle) - sizeof(clienthost) -
- sizeof(": anonymous/"), p);
- setproctitle(proctitle);
-#endif /* SETPROCTITLE */
-
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging) {
- syslog(LOG_INFO,
- "login: anonymous %s %s",
- clienthost ? clienthost : "(unknown host)",
- p
- );
- }
-#endif /* CKSYSLOG */
-
- } else { /* Real user */
- isguest = 0;
- home = dir;
- ckstrncpy(guestpass,zvuname,GUESTPASS);
-
- printf("User %s logged in.\r\n", pw->pw_name);
-#ifdef SETPROCTITLE
- /* not used */
- sprintf(proctitle, "%s: %s",
- clienthost ? clienthost : "(unk)",
- pw->pw_name
- );
- setproctitle(proctitle);
-#endif /* SETPROCTITLE */
-
-#ifdef CKSYSLOG
- if (ckxsyslog && ckxlogging)
- syslog(LOG_INFO, "login: %s %s",
- pw->pw_name,
- clienthost ? clienthost : "(unknown host)"
- );
-#endif /* CKSYSLOG */
- }
- ckstrncpy(zvhome,home,CKMAXPATH); /* Set environment variables */
-#ifndef NOPUTENV
-
- ckmakmsg(zenvuser,ZENVUSER,"USER=",zvuname,NULL,NULL);
- putenv((char *)zenvuser);
- ckmakmsg(zenvlogname,ZENVLOGNAME,"LOGNAME=",zvuname,NULL,NULL);
- putenv((char *)zenvlogname);
- ckmakmsg(zenvhome,ZENVHOME,"HOME=",zvhome,NULL,NULL);
- putenv((char *)zenvhome);
-#endif /* NOPUTENV */
- /* homdir = (char *)zvhome; */
- ckstrncpy((char *)uidbuf,(char *)zvuname,64);
- (VOID) umask(defumask);
-#ifdef IKSDB
- if (ikdbopen) {
- char * p2;
- int k;
- extern char dbrec[];
- extern unsigned long myflags;
- extern unsigned int mydbslot;
- extern struct iksdbfld dbfld[];
-#ifdef CK_AUTHENTICATION
- extern unsigned long myamode, myatype;
-#endif /* CK_AUTHENTICATION */
- myflags |= DBF_LOGGED;
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"zvpass guest","",guest);
- debug(F111,"zvpass zvuname",zvuname,0);
- debug(F110,"zvpass guestpass",guestpass,0);
- debug(F110,"zvpass dir",dir,0);
- debug(F110,"zvpass home",home,0);
- debug(F110,"zvpass anonroot",anonroot,0);
- }
-#endif /* DEBUG */
- p2 = guest ? guestpass : zvuname;
- if (guest) {
- p2 = (char *)guestpass;
- myflags &= ~DBF_USER;
- } else {
- p2 = (char *)zvuname;
- myflags |= DBF_USER;
- }
- k = strlen(p2);
- strncpy(&dbrec[DB_ULEN],ulongtohex((unsigned long)k,4),4);
- lset(&dbrec[dbfld[db_USER].off],p2,1024,32);
- strncpy(&dbrec[DB_FLAGS],ulongtohex(myflags,4),4);
-#ifdef CK_AUTHENTICATION
- myamode = ck_tn_auth_valid();
- strncpy(&dbrec[DB_AMODE],ulongtohex(myamode,4),4);
- myatype = ck_tn_authenticated();
- strncpy(&dbrec[DB_ATYPE],ulongtohex(myatype,4),4);
-#endif /* CK_AUTHENTICATION */
- if (guest) {
- p2 = dir;
- } else {
- p2 = zgtdir();
- if (!p2) p2 = "";
- if (!*p2) p2 = home;
- }
- strncpy(&dbrec[DB_DLEN],
- ulongtohex((unsigned long)strlen(p2),4),
- 4
- );
- lset(&dbrec[dbfld[db_DIR].off],p2,1024,32);
- updslot(mydbslot);
- }
-#endif /* IKSDB */
- return(1);
-
-bad: /* Common failure exit */
- zvuname[0] = NUL;
- zvlogout();
- return(0);
-}
-#endif /* CK_LOGIN */
-
-/* Buggy Xenix 2.3.4 cc needs this line after the endif */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuins.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckuins.txt
deleted file mode 100644
index 08cfedb..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuins.txt
+++ /dev/null
@@ -1,3588 +0,0 @@
-
- [1]The Columbia Crown The Kermit Project | Columbia University
- 612 West 115th Street, New York NY 10025 USA o [2]kermit@columbia.edu
- ...since 1981
- [3]Home [4]Kermit 95 [5]C-Kermit [6]Scripts [7]Current [8]New [9]FAQ
- [10]Support
-
-C-Kermit 9.0 Installation Instructions and Options for Unix
-
- [ [11]Contents ] [ [12]C-Kermit ] [ [13]Kermit Home ]
-
- Frank da Cruz
- The Kermit Project
- Columbia University
-
- As of C-Kermit version: 9.0.302, 20 August 2011
- This file last updated: Sun Aug 21 12:08:29 2011 (New York City
- time)
-
- IF YOU ARE READING A PLAIN-TEXT version of this document, it is a
- plain-text copy of a Web page. You can visit the original (and possibly
- more up-to-date) Web page here:
-
-[14]http://www.columbia.edu/kermit/ckuins.html
-
-CONTENTS
-
- [15]OVERVIEW
- 1. [16]INTERNET QUICK START
- 2. [17]INSTALLING FROM PACKAGES
- 3. [18]INSTALLING PREBUILT BINARIES
- 4. [19]BUILDING FROM SOURCE CODE
- 5. [20]INSTALLING THE KERMIT FILES
- 6. [21]INSTALLING UNIX C-KERMIT FROM DOS-FORMAT DISKETTES
- 7. [22]CHECKING THE RESULTS
- 8. [23]REDUCING THE SIZE OF THE EXECUTABLE PROGRAM IMAGE
- 9. [24]UNIX VERSIONS
- 10. [25]DIALING OUT AND COORDINATING WITH UUCP
- 11. [26]RUNNING UNIX C-KERMIT SETUID OR SETGID
- 12. [27]CONFIGURING UNIX WORKSTATIONS
- 13. [28]BIZARRE BEHAVIOR AT RUNTIME
- 14. [29]CRASHES AND CORE DUMPS
- 15. [30]SYSLOGGING
- 16. [31]BUILDING SECURE VERSIONS OF C-KERMIT 9.0
- 17. [32]INSTALLING C-KERMIT AS AN SSH SERVER SUBSYSTEM
-
-OVERVIEW
-
- [ [33]Top ] [ [34]Contents ] [ [35]Next ]
-
- WARNING: This document contains notes that have been accumulating
- since the mid 1980s. Many of the products and Unix versions
- mentioned here have not been heard of in a long while, but that does
- not necessarily mean they are not still running in some obscure
- nook.
-
- This file contains Unix-specific information. A lot of it. Unlike most
- other packages, C-Kermit tries very hard to be portable to every Unix
- variety (and every release of each one) known to exist, including many
- that are quite old, as well as to other platforms like VMS, AOS/VS,
- VOS, OS-9, the BeBox, the Amiga, etc.
-
- Since C-Kermit gets so deeply into the file system, i/o system, and
- other areas that differ radically from one Unix platform to the next,
- this means that a lot can go wrong when you try to install C-Kermit on
- (for example) a new release of a particular variety of Unix, in which
- certain things might have changed that C-Kermit depended upon.
-
- This file concentrates on installation. For a description of general
- configuration options for C-Kermit, please read the [36]Configurations
- Options document. For troubleshooting after installation, see the
- [37]General Hints and Tips and [38]Unix-Specific Hints and Tips
- documents. The latter, in particular, contains lots of information on
- lots of specific Unix platforms. If you want to work on the source
- code, see the [39]C-Kermit Program Logic Manual
-
- You may install C-Kermit:
-
- * From an "[40]install package", if one is available.
- * As a [41]prebuilt binary, if available, plus accompanying text
- files.
- * By building from [42]source code.
-
-1. INTERNET QUICK START
-
- [ [43]Top ] [ [44]Contents ] [ [45]Next ] [ [46]Previous ]
-
- If your Unix computer is on the Internet and it has a C compiler,
- here's how to download, build, and install C-Kermit directly from the
- "tarballs" or Zip archives:
-
- 1. Make a fresh directory and cd to it.
- 2. Download the C-Kermit source code:
- [47]ftp://www.columbia.edu/kermit/archives/cku211.tar.Z (compress
- format) or [48]ftp://www.columbia.edu/kermit/archives/cku211.tar.gz
- (gunzip format). If those links don't work, FTP transfers are being
- blocked; try these HTTP links instead:
- [49]http://kermit.columbia.edu/ftp/archives/cku211.tar.Z (compress
- format) or
- [50]http://kermit.columbia.edu/ftp/archives/cku211.tar.gz (gunzip
- format).
- 3. Uncompress the compressed tar file with "uncompress" or "gunzip",
- according to which type of compressed file you downloaded. (If you
- don't understand this, you could download a (much larger)
- uncompressed tar archive directly:
- [51]ftp://www.columbia.edu/kermit/archives/cku211.tar or
- [52]http://kermit.columbia.edu/ftp/archives/cku211.tar
- 4. Now type "tar xvf cku211.tar" to unpack the individual files from
- the tar archive.
- 5. Type "rm cku211.tar" to get rid of the tar archive, which is no
- longer needed.
- 6. Read the comments at the top of the makefile to find out which
- target to use and then type the appropriate "make" command, such as
- "make linux", "make solaris8", etc.
- 7. This produces a binary in your current directory called "wermit".
- Start it by typing "./wermit" and [53]try it out to make sure it
- works. Then read [54]Section 5 for how to install it, or simply
- copy the wermit binary to the desired public directory, rename it
- to kermit, and give it the needed permissions (and, if it is going
- to be used to dial out, give it the same group and owner and
- permissions as the cu, tip, or minicom program).
-
- For secure installations, see [55]Sections 5 and [56]16.
-
-2. INSTALLING FROM PACKAGES
-
- [ [57]Top ] [ [58]Contents ] [ [59]Next ] [ [60]Previous ]
-
- Various Unix varieties -- Linux, Solaris, AIX, etc -- now incorporate
- the idea of "install packages", and many users expect to find all new
- applications in this format. A selection of install packages might be
- available for any given release of C-Kermit, but there is a tradeoff
- between convenience and safety. Unix presents several notable problems
- to the builder of install packages:
-
- a. Since C-Kermit is portable to many non-Unix platforms (VMS, VOS,
- AOS/VS, etc), some of the files in the C-Kermit distribution do not
- fit into the Unix application model. In particular, C-Kermit
- includes some plain text files (described in [61]Section 5) and
- Unix has no standard place to put such files. Typical Unix package
- managers do not allow for them. Where should they go, and how will
- the user know where to find them?
- b. Installation of any program that will be used to make modem calls
- requires some important decisions from the installer regarding
- security and privilege.
-
- Item (b) is discussed at length in [62]Sections 10 and [63]11 of this
- document, but the package-related aspects are also given here. The
- basic problem is that Unix dialout devices and the UUCP "lock files"
- that regulate contention for them (described in [64]Section 10) are
- usually protected against "world". Therefore, the install procedure
- must either run as root in order to give the Kermit binary the required
- permissions, group, and/or owner, or else the dialout devices and
- associated directories must be open for group or world reading and
- writing. Otherwise, the Kermit program just installed WILL NOT WORK for
- dialing out.
-
- Thus, a well-crafted installation procedure should present the options
- and allow the installer to choose the method, if any, for regulating
- access to the dialout devices:
-
- a. Check the permissions of the lockfile directory and the dialout
- devices. If they do not allow group or world R/W access, then:
- b. "Your UUCP lockfile directory and/or dialout devices require
- privilege to access. You must either change their permissions or
- install Kermit with privileges."
- c. "If you wish to install Kermit with privileges, it will be given
- the same owner, group, and permissions as the cu program so it can
- use the dialout devices." (This is increasingly problematic as some
- newer Unix systems like Mac OS X don't have a cu program, or even a
- serial port!)
- d. If they choose (c) but the user is not root, give a message that
- the install procedure can be run only by root and then quit.
-
- It should go without saying, of course, that any binaries that are to
- be included in an install package should be built fresh on the exact
- platform (e.g. Red Hat 8.0 on Intel) for which the package is targeted;
- prebuilt binaries ([65]next section) from other sites are likely to
- have library mismatches. [66]CLICK HERE for more about building
- C-Kermit install packages.
-
- The Kermit Project does not have the resources or the expertise to make
- install packages for every platform. Most install packages, therefore,
- are contributed by others, and they do not necessarily follow the
- guidelines given above. Pay attention to what they do.
-
- If you are an end user who has obtained a C-Kermit install package for
- a particular platform, you should be aware that some additional steps
- might needed if you want to use Kermit to dial out. Read [67]Section 10
- for details.
-
-3. INSTALLING PREBUILT BINARIES
-
- [ [68]Top ] [ [69]Contents ] [ [70]Next ] [ [71]Previous ]
-
- Hundreds of prebuilt C-Kermit binaries are available on the CDROM in
- the BINARY tree [NOTE: The C-Kermit CDROM is still for version 7.0],
- and at our ftp site in the [72]kermit/bin area (with names starting
- with "ck"), also accessible on the [73]C-Kermit website. To install a
- prebuilt binary:
-
- a. Rename the binary to "wermit".
- b. Make sure it works; some tests are suggested in [74]Section 7.
- c. Follow steps (b) through (e) in [75]Section 4.
- d. Install related files as described in [76]Section 5.
-
- But first... Please heed the following cautions:
-
- a. If you pick the wrong binary, it won't work (or worse).
- b. Even when you pick the appropriate binary, it still might not work
- due to shared-library mismatches, etc. (see [77]Section 4.0).
- c. Don't expect a binary built on or for version n of your OS to work
- on version n - x (where x > 0). However, it is supposed to be safe
- to run a binary built on (or for) an older OS release on a newer
- one (but is [78]increasingly less so as time-honored principles of
- stability and backwards compatibility go fading into obscurity).
-
- Therefore, it is always better to build your own binary from source
- code ([79]next section) if you can. But since it is increasingly common
- for Unix systems (not to mention VMS and other OS's) to be delivered
- without C compilers, it is sometimes not possible. In such cases, try
- the most appropriate prebuilt binary or binaries, and if none of them
- work, [80]contact us and we'll see what we can do to help.
-
-4. BUILDING FROM SOURCE CODE
-
- [ [81]Top ] [ [82]Contents ] [ [83]Next ] [ [84]Previous ]
-
- Also see: [85]Section 8 and [86]Section 9.
-
- C-Kermit is designed to be built and used on as many platforms as
- possible: Unix and non-Unix, old and new (and ancient), ANSI C and K&R.
- The Unix version does not use or depend on any external tools for
- building except the "make" utility, the C compiler, the linker, and the
- shell. It does not use any external automated configuration tools such
- as configure, autoconf, automake, libtool, etc. Everything in C-Kermit
- has been built by hand based on direct experience or reports or
- contributions from users of each platform.
-
- The [87]C-Kermit makefile contains the rules for building the program
- for each of the hundreds of different kinds of Unix systems that
- C-Kermit attempts to support. It covers all Unix variations since about
- 1980 -- pretty much everything after Unix V6. Separate makefiles are
- used for [88]Plan 9 and [89]2.x BSD.
-
- Prerequisites:
-
- * The C compiler, linker, and make program must be installed.
- * The C libraries and header files must be installed (*).
- * The C-Kermit source code and makefile in your current directory.
- * The C-Kermit text files ([90]Section 5) in your current directory.
-
- * This is becoming problematic in this new age of "selective
- installs" e.g. of Linux packages. C-Kermit builds will often fail
- because replying "no" to some obscure Linux installation option
- will result in missing libraries or header files. Ditto on
- platforms like AIX and Solaris that don't come with C compilers,
- and then later have gcc installed, but are still missing crucial
- libraries, like libm (math).
-
- Plus:
-
- * For TCP/IP networking support, the sockets library and related
- header files must be installed.
- * The math library for floating-point arithmetic support (can be
- deselected by adding -DNOFLOAT to CFLAGS and removing -lm from
- LIBS).
- * Many and varied security libraries for building a secure version
- (Kerberos, SSL/TLS, SRP, Zlib,...) These are required only if you
- select a secure target.
- * For the curses-based fullscreen file-transfer display, the curses
- or ncurses header file(s) and library, and probably also the
- termcap and/or termlib library. Note that the names and locations
- of these files and libraries are likely to change capriciously with
- every new release of your Unix product. If you discover that the
- C-Kermit build procedure fails because your curses and/or termxxx
- headers or libraries are not named or located as expected, please
- [91]let us know. In the meantime, work around by installing
- symlinks.
- * IMPORTANT: Modern Linux distributions might give you the choice
- during installation of whether to install the "ncurses development
- package" (perhaps called "ncurses-devel"). If you did not install
- it, you won't be able to build C-Kermit with curses support
- included. In this case, either go back and install ncurses, or else
- choose (or create) a non-curses makefile target for your platform.
- To install the ncurses developers tools in Red Hat Linux, do
- "apt-get install ncurses-developer" or if you have the CD:
-
-mount redhat cdrom
-goto RedHat/RPMS
-rpm -ivh ncurses-devel*.rpm
-or to have the exact name ls ncurse* and load as
-rpm -ivh filename
-then leave the cdrom and unmount it.
-
- * In AIX you might have to go back and install any or all of:
-
-bos.adt.base
-bos.adt.include
-bos.adt.lib
-bos.adt.libm
-bos.adt.utils
-
- from the first installation CD.
-
- Depending on where you got it, the makefile might need to be renamed
- from ckuker.mak to makefile. Directions:
-
- a. Type "make xxx" where xxx is the name of the makefile target most
- appropriate to your platform, e.g. "make linux", "make aix43", etc.
- Read the [92]comments at the top of the makefile for a complete
- list of available targets (it's a long list).
- b. Test the resulting 'wermit' file (see [93]Section 7 for
- suggestions). If it's OK, proceed; otherwise [94]notify us.
-
- NOTE: steps (c) through (e) can be accomplished using the
- [95]makefile 'install' target as described in [96]Section 5.4.
- c. Rename the 'wermit' file to 'kermit', copy it to the desired binary
- directory (such as /usr/local/bin or /opt/something), and if it is
- to be used for dialing out, give it the same owner, group, and
- permissions as the 'cu' program (IMPORTANT: read [97]Sections 10
- and [98]11 for details).
- d. Install the man page, ckuker.nr, with your other man pages.
- e. Install the accompanying text files (see [99]Section 5).
- f. If you want C-Kermit to also offer a Telnet command-line
- personality, make a symbolic link as follows:
-
-cd directory-where-kermit-binary-is
-ln -s kermit telnet
-
- If you want C-Kermit to be the default Telnet client, make sure the
- directory in which you created the symlink is in the PATH ahead of
- the where the regular Telnet client is.
- g. If you want C-Kermit to also offer an FTP command-line personality,
- make a symlink called "ftp" as in (f).
- h. If you want C-Kermit to also offer an FTTP command-line
- personality, make a symlink called "http" as in (f).
- i. If you want to offer an Internet Kermit Service, follow the
- directions in the [100]IKSD Administrator's Guide.
-
-4.0. Special Considerations for C-Kermit 8.0-9.0
-
- [ [101]Top ] [ [102]Contents ] [ [103]Next ]
-
- Also see: [104]C-Kermit Configuration Options
-
- SECTION CONTENTS
-
-4.1. [105]The Unix Makefile
-4.2. [106]The C-Kermit Initialization File
-4.3. [107]The 2.x BSD Makefile
-4.4. [108]The Plan 9 Makefile
-4.5. [109]Makefile Failures
-
- (Also see the [110]Configurations Options document, [111]Section 8).
-
- Lots of new features have been added in versions 7.0 and 8.0 that
- require access to new symbols, APIs, libraries, etc, and this will no
- doubt cause problems in compiling, linking, or execution on platforms
- where 6.0 and earlier built without incident. This section contains
- what we know as of the date of this file.
-
- The first category concerns the new Kermit Service Daemon (IKSD; see
- the [112]IKSD Administrator's Guide for details):
-
- The wtmp File
- When C-Kermit is started as an IKSD (under inetd), it makes
- syslog and wtmp entries, and also keeps its own ftpd-like log.
- The code assumes the wtmp log is /var/log/wtmp on Linux and
- /usr/adm/wtmp elsewhere. No doubt this assumption will need
- adjustment. Use -DWTMPFILE=path to override at compile time
- (there is also a runtime override). See [113]iksd.html for
- details.
-
- UTMP, utsname(), etc
- C-Kermit 7.0 gets as much info as it can about its job -- mainly
- for IKSD logging -- from utmp. But of course utmp formats and
- fields differ, and for that matter, there can be two different
- header files, <utmp.h> and <utmpx.h>. Look for HAVEUTMPX and
- HAVEUTHOST in [114]ckufio.c and let me know of any needed
- adjustments.
-
- Password lookup
- IKSD needs to authenticate incoming users against the password
- list. In some cases, this requires the addition of -lcrypt (e.g.
- in Unixware 2.x). In most others, the crypt functions are in the
- regular C library. If you get "crypt" as an unresolved symbol at
- link time, add -lcrypt to LIBS. If your site has local
- replacement libraries for authentication, you might need a
- special LIBS clause such as "LIBS=-L/usr/local/lib -lpwent".
-
- These days most Unix systems take advantage of shadow password
- files or Pluggable Authentication Modules (PAM). If your system
- uses shadow passwords you must add -DCK_SHADOW to the CFLAGS
- list. If your system requires PAM you must add -DCK_PAM to the
- CFLAGS and -lpam -ldl to LIBS.
-
- getusershell()
- This is called by the IKSD at login time to see if a user has
- been "turned off". But many Unix platforms lack this function.
- In that case, you will get unresolved symbol reports at link
- time for _getusershell, _endusershell; to work around, add
- -DNOGETUSERSHELL.
-
- initgroups()
- This is called by IKSD after successful authentication. But some
- platforms do not have this function, so obviously it can't be
- called there, in which case add -DNOINITGROUPS.
-
- setreuid(), setreuid(), setregid() not found or "deprecated"
- Find out what your Unix variety wants you to use instead, and
- make appropriate substitutions in routine zvpass(), module
- [115]ckufio.c, and [116]let us know.
-
- printf()
- IKSD installs a printf() substitute to allow redirection of
- printf-like output to the connection. However, this can conflict
- with some curses libraries. In this case, separate binaries must
- be built for IKSD and non-IKSD use.
-
- If you encounter difficulties with any of the above, and you are not
- interested in running C-Kermit as an IKSD, then simply add NOIKSD to
- CFLAGS and rebuild. Example:
-
-make sco286
-(get lots of errors)
-make clean
-make sco286 "KFLAGS=-DNOIKSD"
-
- Some non-IKSD things to watch out for:
-
- Return type of main()
- The main() routine is in [117]ckcmai.c. If you get complaints
- about "main: return type is not blah", define MAINTYPE on the CC
- command line, e.g.:
-
-make xxx "KFLAGS=-DMAINTYPE=blah
-
- (where blah is int, long, or whatever). If the complaint is
- "Attempt to return a value from a function of type void" then
- add -DMAINISVOID:
-
-make xxx "KFLAGS=-DMAINISVOID=blah
-
- DNS Service Records
- This feature allows a remote host to redirect C-Kermit to the
- appropriate socket for the requested service; e.g. if C-Kermit
- requests service "telnet" and the host offers Telnet service on
- port 999 rather than the customary port 23. If you get
- compile-time complaints about not being able to find <resolv.h>,
- <netdb.h>, or <arpa/nameser.h>, add -DNO_DNS_SRV to CFLAGS. If
- you get link-time complaints about unresolved symbols res_search
- or dn_expand, try adding -lresolve to LIBS.
-
- \v(ipaddress)
- If "echo \v(ipaddress)" shows an empty string rather than your
- local IP address, add -DCKGHNLHOST to CFLAGS and rebuild.
-
- <sys/wait.h>
- If this file can't be found at compile time, add -DNOREDIRECT to
- CFLAGS. This disables the REDIRECT and PIPE commands and
- anything else that needs the wait() system service.
-
- syslog()
- C-Kermit can now write syslog records. Some older platforms
- might not have the syslog facility. In that case, add
- -DNOSYSLOG. Others might have it, but require addition of
- -lsocket to LIBS (SCO OSR5 is an example). See [118]Section 15.
-
- putenv()
- If "_putenv" comes up as an undefined symbol, add -DNOPUTENV to
- CFLAGS and rebuild.
-
- "Passing arg1 of 'time' from incompatible pointer"
- This is a mess. See the mass of #ifdefs in the appropriate
- module, [119]ckutio.c or [120]ckufio.c.
-
- gettimeofday()
- Wrong number of arguments. On most platforms, gettimeofday()
- takes two arguments, but on a handful of others (e.g. Motorola
- System V/88 V4, SNI Reliant UNIX 5.43, etc) it takes one. If
- your version of gettimeofday() is being called with two args but
- wants one, add -DGTODONEARG.
-
- "Assignment makes pointer from integer without a cast"
- This warning might appear in [121]ckutio.c or [122]ckufio.c. (or
- elsewhere), and usually can be traced to the use of a system or
- library function that returns a pointer but that is not declared
- in the system header files even though it should be. Several
- functions are commonly associated with this error:
-
- + getcwd(): Add -DDCLGETCWD to CFLAGS and rebuild.
- + popen() : Add -DDCLPOPEN to CFLAGS and rebuild.
- + fdopen(): Add -DDCLFDOPEN to CFLAGS and rebuild.
-
- "Operands of = have incompatible types"
- "Incompatible types in assignment"
- If this comes from [123]ckcnet.c and comes from a statement
- involving inet_addr(), try adding -DINADDRX to CFLAGS. If that
- doesn't help, then try adding -DNOMHHOST.
-
- Complaints about args to get/setsockopt(), getpeername(), getsockname()
- These are all in [124]ckcnet.c. Different platforms and OS's and
- versions of the same OS change this all the time: int, size_t,
- unsigned long, etc. All the affected variables are declared
- according to #ifdefs within ckcnet.c, so find the declarations
- and adjust the #ifdefs accordingly.
-
- size_t
- In case of complaints about "unknown type size_t", add
- -DSIZE_T=int (or other appropriate type) to CFLAGS.
-
- 'tz' undefined
- Use of undefined enum/struct/union 'timezone'
- Left of 'tv_sec' specifies undefined struct/union 'timeval' And
- similar complaints in [125]ckutio.c: Add -DNOGFTIMER and/or
- -DNOTIMEVAL.
-
- Symlinks
- The new built-in DIRECTORY command should show symlinks like "ls
- -l" does. If it does not, check to see if your platform has the
- lstat() and readlink() functions. If so, add -DUSE_LSTAT and
- -DCKSYMLINK to CFLAGS and rebuild. On the other hand, if lstat()
- is unresolved at link time, add -DNOLSTAT to CFLAGS. If
- readlink() is also unresolved, add -DNOSYMLINK.
-
- realpath()
- Link-time complains about realpath() -- find the library in
- which it resides and add it to LIBS (example for Unixware 7.1:
- "-lcudk70") or add -DNOREALPATH to CFLAGS and rebuild. If built
- with realpath() but debug log file is truncated or mangled,
- ditto (some realpath() implementations behave differently from
- others). If built with realpath() and seemingly random core
- dumps occur during file path resolution, ditto.
-
- Failure to locate header file <term.h>
- Usually happens on Linux systems that have the C compiler
- installed, but not the ncurses package (see comments about
- selective installs above). Go back and install ncurses, or use
- "make linuxnc" (Linux No Curses).
-
- "Can't find shared library libc.so.2.1"
- "Can't find shared library libncurses.so.3.0", etc...
- You are trying to run a binary that was built on a computer that
- has different library versions than your computer, and your
- computer's loader is picky about library version numbers.
- Rebuild from source on your computer.
-
- Time (struct tm) related difficulties:
- Errors like the following:
-
-"ckutio.c", line 11994: incomplete struct/union/enum tm: _tm
-"ckutio.c", line 11995: error: cannot dereference non-pointer type
-"ckutio.c", line 11995: error: assignment type mismatch
-"ckutio.c", line 11997: warning: using out of scope declaration: localtime
-"ckutio.c", line 11997: error: unknown operand size: op "="
-"ckutio.c", line 11997: error: assignment type mismatch
-"ckutio.c", line 11998: error: undefined struct/union member: tm_year
-"ckutio.c", line 12000: error: undefined struct/union member: tm_mon
-"ckutio.c", line 12001: error: undefined struct/union member: tm_mday
-"ckutio.c", line 12002: error: undefined struct/union member: tm_hour
-"ckutio.c", line 12003: error: undefined struct/union member: tm_min
-"ckutio.c", line 12004: error: undefined struct/union member: tm_sec
-
- are due to failure to include the appropriate time.h header
- files. Unix platforms generally have one or more of the
- following: <time.h>, <sys/time.h>, and <sys/timeb.h>. Any
- combination of these might be required. Defaults are set up for
- each makefile target. The defaults can be corrected on the CC
- command line by adding the appropriate definition from the
- following list to CFLAGS:
-
--DTIMEH Include <time.h>
--DNOTIMEH Don't include <time.h>
--DSYSTIMEH Include <sys/time.h>
--DNOSYSTIMEH Don't include <sys/time.h>
--DSYSTIMEBH Include <sys/timeb.h>
--DNOSYSTIMEBH Don't include <sys/timeb.h>
-
- Note that <sys/timeb.h> is relatively scarce in the System V and
- POSIX environments; the only platform of recent vintage where it
- was/is used is OSF/1 and its derivatives (Digital Unix and Tru64
- Unix).
-
- Struct timeval and/or timezone not declared:
- In some cases, merely including the appropriate time.h header
- files is still not enough. POSIX.1 does not define the timeval
- struct, and so the items we need from the header are protected
- against us by #ifndef _POSIX_SOURCE or somesuch. In this case,
- we have to declare the timeval (and timezone) structs ourselves.
- To force this, include -DDCLTIMEVAL in CFLAGS.
-
- Warnings about dn_expand() Argument #4
- WARNING: argument is incompatible with prototyp. It's the old
- char versus unsigned char stupidity again. Try to find a
- compiler switch like GCC's "-funsigned-char". Failing that, add
- -DCKQUERYTYPE=xxx to CFLAGS, where xxx is whatever 'man
- dn_expand' tells you the type of the 4th argument should be
- (presumably either char or unsigned char; in the latter case use
- CHAR to avoid confusion caused by multiple words.
-
- Switch Table Overflow (in [126]ckcuni.c)
- Add -DNOUNICODE to CFLAGS.
-
- Compile-time warnings about ck_out() or tgetstr() or tputs():
- Easy solution: Add -DNOTERMCAP to CFLAGS. But then you lose the
- SCREEN function. Real solution: Try all different combinations
- of the following CFLAGS:
-
--DTPUTSARGTYPE=char -DTPUTSFNTYPE=int
--DTPUTSARGTYPE=int -DTPUTSFNTYPE=void
-
- Until the warnings go away, except maybe "ck_outc: return with a
- value in a function returning void", and in that case also add
- -DTPUTSISVOID.
-
- "Passing arg 1 of to tputs() makes pointer from integer without a
- cast":
- Add -DTPUTSARG1CONST to CFLAGS.
-
- "Undefined symbol: dup2"
- Add -DNOZEXEC to CFLAGS.
-
- "header file 'termcap.h' not found"
- Add -DNOHTERMCAP to CFLAGS.
-
- Other difficulties are generally of the "where is curses.h and what is
- it called this week?" variety (most easily solved by making symlinks in
- the include and lib directories), or overzealous complaints regarding
- type mismatches in function calls because of the totally needless and
- silly signed versus unsigned char conflict (*), etc. In any case,
- please send any compilation or linking warnings or errors to the
- author, preferably along with fixes.
-
- * C-Kermit does not use the signed property of chars at all anywhere,
- ever. So if all chars and char *'s can be made unsigned at compile
- time, as they can in gcc with "-funsigned-char", they should be.
-
- IMPORTANT: If you find any of these hints necessary for a particular
- make target (or you hit upon others not listed here), PLEASE SEND A
- REPORT TO:
-
-[127]kermit-support@columbia.edu
-
-4.1. The Unix Makefile
-
- [ [128]Top ] [ [129]Contents ] [ [130]Section Contents ] [ [131]Next ]
- [ [132]Previous ]
-
- If your distribution does not contain a file with the name "makefile"
- or "Makefile", then rename the file called ckuker.mak to makefile:
-
-mv ckuker.mak makefile
-
- Then type "make xxx", where xxx is the platform you want to build
- C-Kermit for. These are listed in the [133]comments at the top of the
- makefile. For example, to build C-Kermit for Linux, type:
-
-make linux
-
- Here are some typical examples:
-
- Target Description
- linux Linux, any version on any hardware platform
- openbsd OpenBSD, any version on any hardware platform
- aix43 AIX 4.3
- aix43g AIX 4.3, built with gcc
- solaris9 Solaris 9
- solaris9g Solaris 9 built with gcc
- hpux1100 HP-UX 11-point-anything
-
- The makefile is quite long, and at least two versions of Unix, SCO
- Xenix/286 and 2.x BSD, cannot cope with its length. An attempt to "make
- sco286" gives the message "Make: Cannot alloc mem for env.. Stop".
- Solution: edit away some or all of the nonrelevant material from the
- makefile. (A separate version of the makefile is provided for BSD 2.x:
- ckubs2.mak but C-Kermit 8.0 can't be built for BSD 2.x -- it has simply
- grown too large.)
-
- Some make programs reportedly cannot handle continued lines (lines
- ending in backslash (\)). If you have a problem with the makefile, try
- editing the makefile to join the continued lines (remove the
- backslashes and the following linefeed).
-
- Other makefile troubles may occur because tabs in the makefile have
- somehow been converted to spaces. Spaces and tabs are distinct in Unix
- makefiles.
-
- Similarly, carriage returns might have been added to the end of each
- line, which also proves confusing to most Unix versions of make.
-
- Check to see if there are comments about your particular version in its
- makefile target itself. In a text editor such as EMACS or VI, search
- for the make entry name followed by a colon, e.g. "linux:" (if you
- really are building C-Kermit for Linux, do this now).
-
- Check to see if there are comments about your particular version in the
- [134]ckubwr.txt file ([135]CLICK HERE for the Web version).
-
- If you have trouble with building [136]ckwart.c, or running the
- resulting wart preprocessor program on [137]ckcpro.w:
-
- 1. Just "touch" the [138]ckcpro.c file that comes in the distribution
- and then give the "make" command again, or:
- 2. Compile ckwart.c "by hand": cc -o wart ckwart.c, or:
- 3. Try various other tricks. E.g. one Linux user reported that that
- adding the "static" switch to the rule for building wart fixed
- everything:
-
-wart: ckwart.$(EXT)
- $(CC) -static -o wart ckwart.$(EXT) $(LIBS)
-
- If your compiler supports a compile-time option to treat ALL chars (and
- char *'s, etc) as unsigned, by all means use it -- and send me email to
- let me know what it is (I already know about gcc -funsigned-char).
-
- To add compilation options (which are explained later in this document)
- to your makefile target without editing the makefile, include
- "KFLAGS=..." on the make command line, for example:
-
-make linux KFLAGS=-DNODEBUG
-make bsd "KFLAGS=-DKANJI -DNODEBUG -DNOTLOG -DDYNAMIC -UTCPSOCKET"
-
- Multiple options must be separated by spaces. Quotes are necessary if
- the KFLAGS= clause includes spaces. The KFLAGS are added to the end of
- the CFLAGS that are defined in the selected makefile target. For
- example, the "bsd" entry includes -DBSD4 -DTCPSOCKET, so the second
- example above compiles Kermit with the following options:
-
--DBSD4 -DTCPSOCKET -DKANJI -DNODEBUG -DNOTLOG -DDYNAMIC -UTCPSOCKET
-
- (Notice how "-UTCPSOCKET" is used to negate the effect of the
- "-DTCPSOCKET" option that is included in the makefile target.)
-
- WARNING: Be careful with KFLAGS. If you build C-Kermit, change some
- files, and then run make again using the same make entry but specifying
- different KFLAGS than last time, make won't detect it and you could
- easily wind up with inconsistent object modules, e.g. some of them
- built with a certain option, others not. When in doubt, "make clean"
- first to make sure all your object files are consistent. Similarly, if
- you change CFLAGS, LIBS, or any other items in the makefile, or you
- rebuild using a different makefile target, "make clean" first.
-
- If you create a new makefile target, use static linking if possible.
- Even though this makes your C-Kermit binary bigger, the resulting
- binary will be more portable. Dynamically linked binaries tend to run
- only on the exact configuration and version where they were built; on
- others, invocation tends to fail with a message like:
-
-Can't find shared library "libc.so.2.1"
-
-4.2. The C-Kermit Initialization File
-
- [ [139]Top ] [ [140]Contents ] [ [141]Section Contents ] [ [142]Next ]
- [ [143]Previous ]
-
- (This section is obsolete.) Read [144]Section 5 about the
- initialization file.
-
-4.3. The 2.x BSD Makefile
-
- [ [145]Top ] [ [146]Contents ] [ [147]Section Contents ] [ [148]Next ]
- [ [149]Previous ]
-
- This section is obsolete. C-Kermit 6.0 was the last release that
- could be built on PDP-11 based BSD versions.
-
-4.4. The Plan 9 Makefile
-
- [ [150]Top ] [ [151]Contents ] [ [152]Section Contents ] [ [153]Next ]
- [ [154]Previous ]
-
- Use the separate makefile [155]ckpker.mk. NOTE: The Plan 9 version of
- C-Kermit 8.0 has not yet been built. There should be no impediment to
- building it. However, even when built successfully, certain key
- features are missing, notably TCP/IP networking.
-
-4.5. Makefile Failures
-
- [ [156]Top ] [ [157]Contents ] [ [158]Section Contents ] [
- [159]Previous ]
-
- First, be sure the source files are stored on your current disk and
- directory with the right names (in lowercase). Second, make sure that
- the makefile itself does not contain any lines with leading spaces:
- indented lines must all start with horizontal TAB, and no spaces.
-
- Then make sure that your Unix PATH is defined to find the appropriate
- compiler for your makefile target. For example, on SunOS systems, "make
- sunos41" builds C-Kermit for the BSD environment, and assumes that
- /usr/ucb/cc will be used for compilation and linking. If your PATH has
- /usr/5bin ahead of /usr/ucb, you can have problems at compile or link
- time (a commonly reported symptom is the inability to find "ftime"
- during linking). Fix such problems by redefining your Unix PATH, or by
- specifying the appropriate "cc" in CC= and CC2= statements in your
- makefile target.
-
- During edits 166-167, considerable effort went into making C-Kermit
- compilable by ANSI C compilers. This includes prototyping all of
- C-Kermit's functions, and including the ANSI-defined system header
- files for system and library functions, as defined in K&R, second
- edition: <string.h>, <stdlib.h>, <unistd.h> (except in NeXTSTEP this is
- <libc.h>), and <sys/stdtypes.h>. If you get warnings about any of these
- header files not being found, or about argument mismatches involving
- pid_t, uid_t, or gid_t, look in ckcdeb.h and make amendments. C-Kermit
- assumes it is being compiled by an ANSI-compliant C compiler if
- __STDC__ is defined, normally defined by the compiler itself. You can
- force ANSI compilation without defining __STDC__ (which some compilers
- won't let you define) by including -DCK_ANSIC on the cc command line.
-
- On the other hand, if your compiler defines __STDC__ but still
- complains about the syntax of Kermit's function prototypes, you can
- disable the ANSI-style function prototyping by including -DNOANSI on
- the command line.
-
- For SCO OpenServer, UNIX, ODT, and XENIX compilations, be sure to pick
- the most appropriate [160]makefile target, and be sure you have
- installed an SCO development system that is keyed to your exact SCO
- operating system release, down to the minor version (like 2.3.1).
-
- Also note that SCO distributes some of its libraries in encrypted form,
- and they must be decrypted before C-Kermit can be linked with them. If
- not, you might see a message like:
-
-ld: file /usr/lib/libsocket.a is of unknown type: magic number = 6365
-
- To decrypt, you must supply a key (password) that came with your
- license. Call SCO for further info.
-
- If your compiler uses something other than int for the pid (process id)
- data type, put -DPID_T=pid_t or whatever in your CFLAGS.
-
- If you get complaints about unknown data types uid_t and gid_t, put
- -DUID_T=xxx -DGID_T=yyy in your CFLAGS, where xxx and yyy are the
- appropriate types.
-
- If your compilation fails because of conflicting or duplicate
- declarations for sys_errlist, add -DUSE_STRERROR or -DNDSYSERRLIST to
- CFLAGS.
-
- If your compilation dies because getpwnam() is being redeclared (or
- because of "conflicting types for getwpnam"), add -DNDGPWNAM to your
- CFLAGS. If that doesn't work, then add -DDCGPWNAM to your CFLAGS (see
- ckufio.c around line 440).
-
- If the compiler complains about the declaration of getpwnam() during an
- ANSI C compilation, remove the declaration from ckufio.c or change the
- argument in the prototype from (char *) to (const char *).
-
- If you get complaints that getpwuid() is being called with an improper
- type, put -DPWID_T=xx in your CFLAGS.
-
- If you get compile-time warnings that t_brkc or t_eofc (tchars
- structure members, used in BSD-based versions) are undefined, or
- structure-member- related warnings that might be traced to this fact,
- add -DNOBRKC to CFLAGS.
-
- If you get a linker message to the effect that _setreuid or _setregid
- is not defined, add -DNOSETREU to CFLAGS, or add -DCKTYP_H=blah to
- CFLAGS to make C-Kermit read the right <types.h>-kind-of-file to pick
- up these definitions.
-
- If you get a message that _popen is undefined, add -DNOPOPEN to CFLAGS.
-
- If you get a complaint at compile time about an illegal pointer-integer
- combination in ckufio.c involving popen(), or at link time that _popen
- is an undefined symbol, add the declaration "FILE *popen();" to the
- function zxcmd() in ckufio.c (this declaration is supposed to be in
- <stdio.h>). If making this change does not help, then apparently your
- Unix does not have the popen() function, so you should add -DNOPOPEN to
- your make entry, in which case certain functions involving "file" i/o
- to the standard input and output of subprocesses will not be available.
-
- If your linker complains that _getcwd is undefined, you can add a
- getcwd() function to ckufio.c, or add it to your libc.a library using
- ar:
-
-#include <stdio.h>
-
-char *
-getcwd(buf,size) char *buf; int size; {
-#ifndef NOPOPEN
-#ifdef DCLPOPEN
- FILE *popen();
-#endif
- FILE *pfp;
-
- if (!buf) return(NULL);
- if (!(pfp = popen("pwd","r"))) return(NULL);
- fgets(buf,size-2,pfp);
- pclose(pfp);
- buf[strlen(buf)-1] = '\0';
- return((char *)buf);
-#else
- buf[0] = '\0';
- return(NULL);
-#endif /* NOPOPEN */
-}
-
-#ifdef NOPOPEN
-FILE *popen(s,t) char *s,*t; {
- return(NULL);
-}
-#endif /* NOPOPEN */
-
- If you get complaints about NPROC having an invalid value, add a valid
- definition for it (depends on your system), as in the cray entry.
-
- If you get some symbol that's multiply defined, it probably means that
- a variable name used by Kermit is also used in one of your system
- libraries that Kermit is linked with. For example, under PC/IX some
- library has a variable or function called "data", and the variable
- "data" is also used extensively by Kermit. Rather than edit the Kermit
- source files, just put a -D in the make entry CFLAGS to change the
- Kermit symbol at compile time. In this example, it might be
- -Ddata=xdata.
-
- Some symbol is defined in your system's header files, but it produces
- conflicts with, or undesired results from, Kermit. Try undefining the
- symbol in the makefile target's CFLAGS, for example -UFIONREAD.
-
- Some well-known symbol is missing from your system header files. Try
- defining in the makefile target's CFLAGS, for example -DFREAD=1.
-
- You get many warnings about pointer mismatches. This probably means
- that Kermit is assuming an int type for signal() when it should be
- void, or vice-versa. Try adding -DSIG_I (for integer signal()) or
- -DSIG_V (for void) to CFLAGS. Or just include KFLAGS=-DSIG_V (or
- whatever) in your "make" command, for example:
-
-make bsd KFLAGS=-DSIG_V
-
- You get many messages about variables that are declared and/or set but
- never used. It is difficult to avoid these because of all the
- conditional compilation in the program. Ignore these messages.
-
- Some of C-Kermit's modules are so large, or contain so many character
- string constants, or are so offensive in some other way, that some C
- compilers give up and refuse to compile them. This is usually because
- the -O (optimize) option is included in the make entry. If this happens
- to you, you can (a) remove the -O option from the make entry, which
- will turn off the optimizer for ALL modules; or (b) compile the
- offending module(s) by hand, including all the switches from make entry
- except for -O, and then give the appropriate "make" command again; or
- (c) increase the value of the -Olimit option, if your compiler supports
- this option; or (d) change the [161]makefile target to first compile
- each offending module explicitly without optimization, then compile the
- others normally (with optimization), for example:
-
-#Fortune 32:16, For:Pro 2.1 (mostly like 4.1bsd)
-ft21:
- @echo 'Making C-Kermit $(CKVER) for Fortune 32:16 For:Pro 2.1...'
- $(MAKE) ckuusx.$(EXT) "CFLAGS= -DNODEBUG -DBSD4 -DFT21 -DNOFILEH \
- -SYM 800 \ -DDYNAMIC -DNOSETBUF -DCK_CURSES $(KFLAGS) -DPID_T=short"
- $(MAKE) ckuxla.$(EXT) "CFLAGS= -DNODEBUG -DBSD4 -DFT21 -DNOFILEH \
- -SYM 800 \ -DDYNAMIC -DNOSETBUF -DCK_CURSES $(KFLAGS) -DPID_T=short"
- $(MAKE) ckudia.$(EXT) "CFLAGS= -DNODEBUG -DBSD4 -DFT21 -DNOFILEH \
- -SYM 800 \ -DDYNAMIC -DNOSETBUF -DCK_CURSES $(KFLAGS) -DPID_T=short"
- $(MAKE) wermit "CFLAGS= -O -DNODEBUG -DBSD4 -DFT21 -DNOFILEH -SYM 800 \
- -DDYNAMIC -DNOSETBUF -DCK_CURSES $(KFLAGS) -DPID_T=short" \
- "LNKFLAGS= -n -s" "LIBS= -lcurses -ltermcap -lv -lnet"
-
- As an extreme example, some compilers (e.g. gcc on the DG AViiON) have
- been known to dump core when trying to compile ckwart.c with
- optimization. So just do this one "by hand":
-
-cc -o wart ckwart.c
-
- or:
-
-touch ckcpro.c
-
- and then give the "make" command again.
-
- Speaking of wart, it is unavoidable that some picky compilers might
- generate "statement unreachable" messages when compiling ckcpro.c.
- Unreachable statements can be generated by the wart program, which
- generates ckcpro.c automatically from [162]ckcpro.w, which translates
- lex-like state/input constructions into a big switch/case construction.
-
- Some function in Kermit wreaks havoc when it is called. Change all
- invocations of the function into a macro that evaluates to the
- appropriate return code that would have been returned by the function
- had it been called and failed, for example: -Dzkself()=0. Obviously not
- a good idea if the function is really needed.
-
- If you have just installed SunOS 4.1.2 or 4.1.3, you might find that
- C-Kermit (and any other C program) fails to link because of unresolved
- references from within libc. This is because of a mistake in Sun's
- /usr/lib/shlib.etc files for building the new libc. Change the libc
- Makefile so that the "ld" lines have "-ldl" at the end. Change the
- README file to say "mv xccs.multibyte. xccs.multibyte.o" and follow
- that instruction.
-
-5. INSTALLING THE KERMIT FILES
-
- [ [163]Top ] [ [164]Contents ] [ [165]Next ] [ [166]Previous ]
-
- SECTION CONTENTS
-
-5.1. [167]The C-Kermit Initialization File
-5.2. [168]Text Files
-5.3. [169]Installing the Kermit Files
-5.4. [170]The Makefile Install Target
-
- The C-Kermit executable does not need any external files to run.
- Unlike, say, the cu program, which on most platforms is useless unless
- you (as root) edit the /usr/spool/uucp/Systems and
- /usr/spool/uucp/Devices files to supply whatever obscure and
- undocumented syntax is required to match some supposedly user-friendly
- mnemonic to the real pathname of whatever device you want to use,
- Kermit runs on its own without needing any external configuration
- files, and lets you refer to device (and network hosts and services) by
- their own natural undisguised names.
-
- Nevertheless, a number of external files can be installed along with
- the C-Kermit executable if you wish. These include configuration and
- customization files that are read by Kermit as well as documentation
- files to be read by people. All of this material is (a) optional, and
- (b) available on the Kermit website:
-
-[171]http://www.columbia.edu/kermit/
-
- and usually in a more pleasant form, perhaps also with updated content.
- So if your computer is on the Internet, there is no need to install
- anything but the Kermit executable if users know how to find the Kermit
- website (and if they don't, Kermit's "help" command tells them).
-
-5.1. The C-Kermit Initialization File
-
- In C-Kermit 7.0 and earlier, the standard initialization file was a key
- C-Kermit component because:
-
- a. It "loaded" the dialing and network directories.
- b. It defined all the macros and variables for the services directory.
- c. It defined macros for quickly changing Kermit's file-transfer
- performance tuning.
-
- The standard initialization file is quite long (more than 600 lines)
- and requires noticeable processing time (the slower the computer, the
- more noticeable), yet few people actually use the services directory,
- whose definition takes up most of its bulk. Meanwhile, in C-Kermit 8.0,
- many of the remaining functions of the standard initialization file are
- now built in; for example, the FAST, CAUTIOUS, and ROBUST commands.
-
- More to the point, many of the settings that could be made only in the
- initialization and customization files can now be picked up from
- environment variables. The first group identifies initialization and
- directory files:
-
- CKERMIT_INI
- The path of your Kermit initialization file, if any. This
- overrides the built-in search for $HOME/.kermrc.
-
- K_CHARSET
- The character set used for encoding local text files. Equivalent
- to SET FILE CHARACTER-SET.
-
- K_DIAL_DIRECTORY
- The full pathname of one or more Kermit dialing directory files.
- Equivalent to SET DIAL DIRECTORY.
-
- K_NET_DIRECTORY
- The full pathname of one or more Kermit network directory files.
- Equivalent to SET NETWORK DIRECTORY.
-
- K_INFO_DIRECTORY
- K_INFO_DIR
- The full pathname of a directory containing Kermit (if any)
- containing ckubwr.txt and other Kermit text files. Overrides
- Kermit's built-in search for this directory.
-
- The next group is related to dialing modems:
-
- K_COUNTRYCODE
- The telephonic numeric country code for this location, e.g. 1
- for North America or 39 for Italy. It is recommended that this
- one be set for all users, system-wide. Not only is it used to
- process portable-format dialing directory entries, but it is
- also compared against Kermit's built-in list of "tone countries"
- to see if tone dialing can be used. Equivalent to Kermit's SET
- DIAL COUNTRY-CODE command.
-
- K_AREACODE
- The telephonic numeric area code for this location, e.g. 212 for
- Manhattan, New York, USA. Recommend this one also be set
- system-wide, so shared portable-format dialing directories will
- work automatically for everybody. Equivalent to Kermit's SET
- DIAL AREA-CODE command.
-
- K_DIAL_METHOD
- TONE or PULSE. Equivalent to Kermit's SET DIAL METHOD command.
- If a dial method is not set explicitly (or implicitly from the
- country code), Kermit does not specify a dialing method, and
- uses the modem's default method, which tends to be pulse.
-
- K_INTL_PREFIX
- The telephonic numeric international dialing prefix for this
- location. Equivalent to Kermit's SET DIAL INTL-PREFIX command.
-
- K_LD_PREFIX
- The telephonic numeric long-distance dialing prefix for this
- location. Equivalent to Kermit's SET DIAL LD-PREFIX command.
-
- K_PBX_ICP
- The telephonic numeric PBX internal call prefix for this
- location. Equivalent to Kermit's SET DIAL PBX-INSIDE-PREFIX
- command.
-
- K_PBX_OCP
- The telephonic numeric PBX external call prefix for this
- location. Equivalent to Kermit's SET DIAL PBX-OUTSIDE-PREFIX
- command.
-
- K_PBX_XCH
- The telephonic numeric PBX exchange (first part of the
- subscriber number). Equivalent to Kermit's SET DIAL PBX-EXCHANGE
- command.
-
- K_TF_AREACODE
- A list of one or more telephonic numeric toll-free area codes.
-
- K_TF_PREFIX
- The telephonic numeric toll-free dialing prefix, in case it is
- different from the long-distance prefix. Equivalent to Kermit's
- SET DIAL TF-PREFIX command.
-
- The final group includes well-known environment variables that are also
- used by Kermit:
-
- CDPATH
- Where the CD command should look for relative directory names.
-
- SHELL
- The path of your Unix shell. Used by the RUN (!) command to
- choose the shell to execute its arguments.
-
- USER
- Your Unix username.
-
- EDITOR
- The name or path of your preferred editor (used by the EDIT
- command). Equivalent to SET EDITOR.
-
- BROWSER
- The name or path of your preferred web browser (used by the
- BROWSE command). Equivalent to Kermit's SET BROWSER command.
-
- Does this mean the initialization file can be abolished? I think so.
- Here's why:
-
- * Kermit already does everything most people want it to do without
- one.
- * Important site-specific customizations can be done with global
- environment variables.
- * There is no longer any need for everybody to have to use the
- standard initialization file.
- * This means that your initialization file, if you want one, can
- contain your own personal settings, definitions, and preferences,
- rather than 600 lines of "standard" setups.
- * If you still want the services directory, you can either TAKE the
- standard initialization file (which must be named anything other
- than $HOME/.kermrc to avoid being executed automatically every time
- you start Kermit), or you can make it a kerbang script and execute
- it "directly" (the [172]makefile install target does this for you
- by putting ckermit.ini in the same directory as the Kermit binary,
- adding the appropriate Kerbang line to the top, and giving it
- execute permission).
-
- In fact, you can put any number of kerbang scripts in your PATH to
- start up C-Kermit in different ways, to have it adopt certain settings,
- make particular connections, execute complicated scripts, whatever you
- want.
-
- And in C-Kermit 9.0 the initialization has indeed been "retired" by
- renaming it to okermit.ini, and replaced by a stub ckermit.ini that
- doesn't do anything but print a message. Ditto for ckermod.ini.
-
-5.2. Text Files
-
- These are entirely optional. Many of them are to be found at the Kermit
- website in HTML form (i.e. as Web pages with clickable links, etc), and
- very likely also more up to date. Plain-text files that correspond to
- Web pages were simply "dumped" by Lynx from the website to plain ASCII
- text. The format is whatever Lynx uses for this purpose. If you wish,
- you can install them on your computer as described in the [173]next
- section.
-
- [174]COPYING.TXT
- Copyright notice, permissions, and disclaimer.
-
- [175]ckermit.ini
- The standard initialization file, intended more for reference
- (in most cases) than actual use; see [176]Section 5.1.
-
- [177]ckermod.ini
- A sample customization file.
-
- [178]ckermit70.txt
- Supplement to [179]Using C-Kermit for version 7.0. Available on
- the Kermit website as:
- [180]http://www.columbia.edu/kermit/ckermit70.html
-
- [181]ckermit80.txt
- Supplement to [182]Using C-Kermit for version 8.0. Available on
- the Kermit website as:
- [183]http://www.columbia.edu/kermit/ckermit80.html
-
- [184]ckermit90.txt
- Supplement to [185]Using C-Kermit for version 9.0. Available on
- the Kermit website as:
- [186]http://www.columbia.edu/kermit/ckermit90.html
-
- [187]ckcbwr.txt
- The general C-Kermit hints and tips ("beware") file. Available
- on the Kermit website as:
- [188]http://www.columbia.edu/kermit/ckcbwr.html
-
- [189]ckubwr.txt
- The Unix-specific C-Kermit hints and tips file. Available on the
- Kermit website as:
- [190]http://www.columbia.edu/kermit/ckubwr.html
-
- [191]ckuins.txt
- Unix C-Kermit Installation Instructions (this file). Available
- on the Kermit website as:
- [192]http://www.columbia.edu/kermit/ckuins.html
-
- [193]ckccfg.txt
- C-Kermit compile-time configuration options. Available on the
- Kermit website as:
- [194]http://www.columbia.edu/kermit/ckccfg.html
-
- [195]ckcplm.txt
- The C-Kermit program logic manual. Available on the Kermit
- website as:
- [196]http://www.columbia.edu/kermit/ckcplm.html
-
- [197]ca_certs.pem
- Certificate Authority certificates for secure connections (see
- [198]Section 16).
-
-5.3. Installing the Kermit Files
-
- There is an "install" target in the [199]makefile that you can use if
- you wish. However, since every site has its own layout and
- requirements, it is often better to install the Kermit files by hand.
- You don't have to use the makefile install target to install C-Kermit.
- This is especially true since not all sites build C-Kermit from source,
- and therefore might not even have the makefile. But you should read
- this section in any case.
-
- If your computer already has an older version of C-Kermit installed,
- you should rename it (e.g. to "kermit6" or "kermit7") so in case you
- have any trouble with the new version, the old one is still
- available.
-
- In most cases, you need to be root to install C-Kermit, if only to gain
- write access to directories in which the binary and manual page are to
- be copied. The C-Kermit binary should be installed in a directory that
- is in the users' PATH, but that is not likely to be overwritten when
- you install a new version of the operating system. A good candidate
- would be the /usr/local/bin/ directory, but the specific choice is site
- dependent. Example (assuming the appropriate Kermit binary is stored in
- your current directory as "wermit", e.g. because you just built it from
- source and that's the name the makefile gave it):
-
-mv wermit /usr/local/bin/kermit
-chmod 755 /usr/local/bin/kermit
-
- or (only after you finish reading this section!) simply:
-
-make install
-
- IMPORTANT: IF C-KERMIT IS TO BE USED FOR DIALING OUT, you must also do
- something to give it access to the dialout devices and lockfile
- directories. The 'install' target does not attempt to set Kermit's
- owner, group, and permissions to allow dialing out. This requires
- privileges, open eyes, and human decision-making. Please read
- [200]Sections 10 and [201]11 below, make the necessary decisions, and
- then implement them by hand as described in those sections.
-
- You should also install the man page, which is called ckuker.nr, in the
- man page directory for local commands, such as /usr/man/man1/, renamed
- appropriately, e.g. to kermit.1. This is also taken care of by "make
- install".
-
- Optionally, the text files listed in the [202]previous section can be
- placed in a publicly readable directory. Suggested directory names are:
-
-/usr/local/doc/kermit/
-/usr/local/lib/kermit/
-/usr/share/lib/kermit/
-/opt/kermit/doc/
-
- (or any of these without the "/kermit"). Upon startup, C-Kermit checks
- the following environment variables whose purpose is to specify the
- directory where the C-Kermit text files are, in the following order:
-
-K_INFO_DIRECTORY
-K_INFO_DIR
-
- If either of these is defined, C-Kermit checks for the existence of the
- ckubwr.txt file (Unix C-Kermit Hints and Tips). If not found, it checks
- the directories listed above (both with and without the "/kermit") plus
- several others to see if they contain the ckubwr.txt file. If found,
- various C-Kermit messages can refer the user to this directory.
-
- Finally, if you want to put the source code files somewhere for people
- to look at, you can do that too.
-
-5.4. The Makefile Install Target
-
- The makefile "install" target does almost everything for you if you
- give it the information it needs by setting the variables described
- below. You can use this target if:
-
- * You downloaded the [203]complete C-Kermit archive and built
- C-Kermit from source; or:
- * You downloaded an [204]individual C-Kermit binary and the
- [205]C-Kermit text-file archive, and your computer has a "make"
- command.
-
- Here are the parameters you need to know:
-
- BINARY
- Name of the binary you want to install as "kermit". Default:
- "wermit".
-
- prefix
- (lower case) If you define this variable, its value is prepended
- to all the following xxxDIR variables (8.0.211 and later).
-
- DESTDIR
- If you want to install the Kermit files in a directory structure
- like /opt/kermit/bin/, /opt/kermit/doc/, /opt/kermit/src/, then
- define DESTIR as the root of this structure; for example,
- /opt/kermit. The DESTDIR string should not end with a slash. By
- default, DESTDIR is not defined. If it is defined, but the
- directory does not exist, the makefile attempts to create it,
- which might require you to be root. Even so, this can fail if
- any segments in the path except the last one do not already
- exist. WARNING: If the makefile creates any directories, it
- gives them a mode of 755, and the default owner and group.
- Modify these by hand if necessary.
-
- BINDIR
- Directory in which to install the Kermit binary (and the
- standard C-Kermit initialization file, if it is found, as a
- Kerbang script). If DESTDIR is defined, BINDIR must start with a
- slash. BINDIR must not end with a slash. If DESTDIR is defined,
- BINDIR is a subdirectory of DESTDIR. If BINDIR does not exist,
- the makefile attempts to create it as with DESTDIR. Default:
- /usr/local/bin.
-
- MANDIR
- Directory in which to install the C-Kermit manual page as
- "kermit" followed by the manual-chapter extension (next item).
- Default: /usr/man/man1. If MANDIR is defined, the directory must
- already exist.
-
- MANEXT
- Extension for the manual page. Default: 1 (digit one).
-
- SRCDIR
- Directory in which to install the C-Kermit source code. If
- DESTDIR is defined, this is a subdirectory of DESTDIR. Default:
- None.
-
- CERTDIR
- For secure builds only: Directory in which to install the
- ca_certs.pem file. This must be the verification directory used
- by programs that use the SSL libraries at your site. Default:
- none. Possibilities include: /usr/local/ssl, /opt/ssl,
- /usr/lib/ssl, . . . If CERTDIR is defined, the directory
- must already exist.
-
- INFODIR
- Directory in which to install the C-Kermit text files. If
- DESTDIR is defined, this is a subdirectory of DESTDIR. Default:
- None. If INFODIR is defined but does not exist, the makefile
- attempts to create it, as with DESTDIR.
-
- Examples:
-
- make install
- Installs "wermit" as /usr/local/bin/kermit with permissions 755,
- the default owner and group, and no special privileges. The
- manual page is installed as /usr/man/man1/kermit.1. Text files
- are not copied anywhere, nor are the sources.
-
- make MANDIR= install
- Just like "make install" but does not attempt to install the
- manual page.
-
- make DESTDIR=/opt/kermit BINDIR=/bin SRCDIR=/src INFODIR=/doc install
- Installs the Kermit binary "wermit" as /opt/kermit/bin/kermit,
- puts the source code in /opt/kermit/src, and puts the text files
- in /opt/kermit/doc, creating the directories if they don't
- already exist, and puts the man page in the default location.
-
- make BINDIR=/usr/local/bin CERTDIR=/usr/local/ssl install
- Installs the Kerberized Kermit binary "wermit" as
- /usr/local/bin/kermit, puts the CA Certificates file in
- /usr/local/ssl/, and the man page in the normal place.
-
- For definitive information, see the makefile. The following is
- excerpted from the 8.0.211 makefile:
-
-# The following symbols are used to specify library and header file locations
-# Redefine them to the values used on your system by:
-# . editing this file
-# . defining the values on the command line
-# . defining the values in the environment and use the -e option
-#
-prefix = /usr/local
-srproot = $(prefix)
-sslroot = $(prefix)
-manroot = $(prefix)
-
-K4LIB=-L/usr/kerberos/lib
-K4INC=-I/usr/kerberos/include
-K5LIB=-L/usr/kerberos/lib
-K5INC=-I/usr/kerberos/include
-SRPLIB=-L$(srproot)/lib
-SRPINC=-I$(srproot)/include
-SSLLIB=-L$(sslroot)/ssl/lib
-SSLINC=-I$(sslroot)/ssl/include
-...
-WERMIT = makewhat
-BINARY = wermit
-DESTDIR =
-BINDIR = $(prefix)/bin
-MANDIR = $(manroot)/man/man1
-MANEXT = 1
-SRCDIR =
-INFODIR =
-CERTDIR =
-
-6. INSTALLING UNIX C-KERMIT FROM DOS-FORMAT DISKETTES
-
- [ [206]Top ] [ [207]Contents ] [ [208]Next ] [ [209]Previous ]
-
- This section is obsolete. We don't distribute C-Kermit on diskettes
- any more because (a)there is no demand, and (b) it no longer fits.
-
- If you received a DOS-format diskette containing a binary executable
- C-Kermit program plus supporting text files, be sure to chmod +x the
- executable before attempting to run it.
-
- In version 5A(190) and later, all the text files on the C-Kermit
- DOS-format diskettes are in Unix format: LF at the end of each line
- rather than CRLF. This means that no conversions are necessary when
- copying to your Unix file system, and that all the files on the
- diskette, text and binary, can be copied together. The following
- comments apply to the DOS-format diskettes furnished with version
- 5A(189) and earlier or to other DOS-format diskettes you might have
- obtained from other sources.
-
- If you have received C-Kermit on MS-DOS format diskettes (such as those
- distributed by Columbia University), you should make sure that your
- DOS-to-Unix conversion utility (such as "dosread") both: (1) changes
- line terminators in all files from carriage-return linefeed (CRLF) to
- just linefeed (LF) (such as "dosread -a") and remove any Ctrl-Z's, and
- (2) that all filenames are converted from uppercase to lowercase. If
- these conversions were not done, you can use the following shell script
- on your Unix system to do them:
-
----(cut here)---
-#!/bin/sh
-#
-# Shell script to convert C-Kermit DOS-format files into Unix format.
-# Lowercases the filenames, strips out carriage returns and Ctrl-Z's.
-#
-x=$1 # the name of the source directory
-y=$2 # the name of the target directory if [ $# -lt 2 ]; then
- echo "usage: $0 source-directory target-directory"
- exit 1
-fi
-if cd $1 ; then
- echo "Converting files from $1 to $2"
-else
- echo "$0: cannot cd to $1"
- exit 1
-fi
-for i in *; do
- j=`echo $i | tr 'A-Z' 'a-z'`
- echo $x/$i =\> $y/$j
- tr -d '\015\032' < $i > $y/$j
-done
----(cut here)---
-
- Cut out this shell script, save it as "convert.sh" (or any other name
- you prefer), then "chmod +x convert.sh". Then, create a new, empty
- directory to put the converted files in, and then "convert.sh /xxx
- /yyy" where /xxx is the name of the directory where the PC-format files
- are, and /yyy is the name of the new, empty directory. The converted
- files will appear in the new directory.
-
-7. CHECKING THE RESULTS
-
- [ [210]Top ] [ [211]Contents ] [ [212]Next ] [ [213]Previous ]
-
- First some quick checks for problems that can be easily corrected by
- recompiling with different options:
-
- DIRECTORY listing is garbage
- Permissions, size, and date are random garbage (but the
- filenames are correct) in a C-Kermit DIRECTORY listing. On some
- platforms, the lstat() function is present but simply doesn't
- work; try adding -DNOLSTAT to CFLAGS and rebuild. If that
- doesn't fix it, also add -DNOLINKBITS. If it's still not fixed,
- remove -DNOLSTAT and -DNOLINKBITS and add -DNOSYMLINK.
-
- curses
- When you make a connection with C-Kermit and transfer files
- using the fullscreen (curses) file-transfer display, and then
- get the C-Kermit> prompt back afterwards, do characters echo
- when you type them? If not, the curses library has altered the
- buffering of /dev/tty. Try rebuilding with KFLAGS=-DCK_NEWTERM.
- If it already has -DCK_NEWTERM in CFLAGS, try removing it. If
- that doesn't help, then rebuild with -DNONOSETBUF (yes, two
- NO's). If none of this works (and you can't fix the code), then
- either don't use the fullscreen display, or rebuild with
- -DNOCURSES.
-
- Ctrl-L or any SCREEN command crashes C-Kermit:
- Rebuild with -DNOTERMCAP.
-
- No prompt after CONNECT:
- After escaping back from CONNECT mode, does your C-Kermit>
- prompt disappear? (Yet, typing "?" still produces a command
- list, etc) In that case, add -DCKCONINTB4CB to CFLAGS and
- rebuild.
-
- Here is a more thorough checklist can use to tell whether your version
- of C-Kermit was built correctly for your Unix system, with hints on how
- to fix or work around problems:
-
- a. Start C-Kermit (usually by typing "./wermit" in the directory where
- you ran the makefile). Do you see the C-Kermit> prompt? If not,
- C-Kermit incorrectly deduced that it was running in the background.
- The test is in conbgt() in [214]ckutio.c. If you can fix it for
- your system, please send in the fix (Hint: read about "PID_T"
- below). Otherwise, you can force C-Kermit to foreground mode by
- starting it with the -z command line option, as in "kermit -z", or
- giving the interactive command SET BACKGROUND OFF.
- b. When you type characters at the C-Kermit prompt, do they echo
- immediately? If not, something is wrong with concb() and probably
- the other terminal mode settings routines in [215]ckutio.c. Be sure
- you have used the most appropriate make entry.
- c. At the C-Kermit> prompt, type "send ./?". C-Kermit should list all
- the files in the current directory. If not, it was built for the
- wrong type of Unix file system. Details below. In the meantime, try
- SET WILDCARD-EXPANSION SHELL as a workaround.
- d. CD to a directory that contains a variety of files, symlinks, and
- subdirectories and give a DIRECTORY command at the C-Kermit>
- prompt. Do the permissions, size, and date appear correct? If not
- see [216]Section 4.0.
- e. Assuming your platform supports long file names, create a file with
- a long name in your current directory, e.g.:
-
-$ touch thisisafilewithaveryveryveryveryveryveryveryverylooooooooongname
-
- (you might need to make it longer than this, perhaps as long as 257
- or even 1025 characters).
- Check with ls to see if your version of Unix truncated the name.
- Now start C-Kermit and type "send thisis<ESC>". Does Kermit
- complete the name, showing the same name as ls did? If not, wrong
- filesystem. Read on.
- f. Make sure that Kermit has the maximum path length right. Just type
- SHOW FILE and see what it says about this. If it is too short,
- there could be some problems at runtime. To correct, look in
- [217]ckcdeb.h to see how the symbol CKMAXPATH is set and make any
- needed adjustments.
- g. Send a file to your new Kermit program from a different Kermit
- program that is known to work. Is the date/timestamp of the new
- file identical to the original? If not, adjustments are needed in
- zstrdt() in [218]ckufio.c.
- h. Go to another computer (Computer B) from which you can send files
- to C-Kermit. Connect Computer B to the computer (A) where you are
- testing C-Kermit. Then:
- i. Send a file from B to A. Make sure it transferred OK and was
- created with the right name.
- j. Send a file from B to A, specifying an "as-name" that is very, very
- long (longer than the maximum name length on computer A). Check to
- make sure that the file was received OK and that its name was
- truncated to Computer A's maximum length. If not, check the
- MAXNAMLEN definition in [219]ckufio.c.
- k. Tell C-Kermit on Computer A to "set receive pathnames relative" and
- then send it a file from Computer B specifying an as-name that
- contains several directory segments:
-
-send foo dir1/dir2/dir3/foo
-
- Check to make sure that dir1/dir2/dir3/foo was created in Computer
- A's current directory (i.e. that three levels of directories were
- created).
- l. Repeat step k, but make each path segment in the pathname longer
- than Computer A's maximum name length. Make sure each directory
- name, and the final filename, were truncated properly.
- m. Type Ctrl-C (or whatever your Unix interrupt character is) at the
- prompt. Do you get "^C..." and a new prompt? If instead, you get a
- core dump (this shouldn't happen any more) "rm core" and then
- rebuild with -DNOCCTRAP added to your CFLAGS. If it did work, then
- type another Ctrl-C. If this does the same thing as the first one,
- then Ctrl-C handling is OK. Otherwise, the SIGINT signal is either
- not getting re-armed (shouldn't happen) or is being masked off
- after the first time it is caught, in which case, if your Unix is
- POSIX-based, try rebuilding C-Kermit with -DCK_POSIX_SIG.
- n. Type Ctrl-Z (or whatever your Unix suspend character is) to put
- C-Kermit in the background. Did it work? If nothing happened, then
- (a)your version of Unix does not support job control, or (b) your
- version of C-Kermit was probably built with -DNOJC. If your session
- became totally frozen, then you are probably running C-Kermit on a
- Unix version that supports job control, but under a shell that
- doesn't. If that's not the case, look in the congm() and psuspend()
- routines in [220]ckutio.c and see if you can figure out what's
- wrong. If you can't, rebuild with -DNOJC.
- o. Give a SET LINE command for a dialout device, e.g. "set line
- /dev/tty00". If you got some kind of permission or access denied
- message, go read [221]Section 10 and then come back here.
- p. After giving a successful SET LINE command, type "show comm" to see
- the communication parameters. Do they make sense?
- q. Type "set speed ?" and observe the list of available speeds. Is it
- what you expected? If not, see [222]Section 2) of the
- [223]Configurations Options document.
- r. Give a SET SPEED command to change the device's speed. Did it work?
- (Type "show comm" again to check.)
- s. Try dialing out: SET MODEM TYPE , SET LINE , SET SPEED , DIAL . If
- it doesn't work, keep reading. After dialing, can you REDIAL?
- t. If your version was built with TCP/IP network support, try the
- TELNET command.
- u. Transfer some files in remote mode on incoming asynchronous serial
- (direct or modem) connections, and on incoming network (telnet,
- rlogin, terminal server) connections. If you get lots of errors,
- try different SET FLOW settings on the remote Kermit program.
- v. Establish a serial connection from C-Kermit to another computer
- (direct or dialed) and transfer some files. If you have network
- support, do the same with a network connection.
- w. If your version was built with fullscreen file transfer display
- support, check that it works during local-mode file transfer. Also,
- check C-Kermit's operation afterwards: is the echoing funny? etc
- etc. If there are problems, see [224]Section 4.
- x. If your version was built with script programming language support,
- TAKE the ckedemo.ksc file to give it a workout.
- y. Does C-Kermit interlock correctly with UUCP-family programs (cu,
- tip, uucp, etc)? If not, read the section [225]DIALING OUT AND
- COORDINATING WITH UUCP below.
- z. Modem signals... Give a SET LINE command to a serial device and
- then type the SHOW MODEM command. If it says "Modem signals
- unavailable in this version of Kermit", then you might want to look
- at the ttgmdm() routine in [226]ckutio.c and add the needed code --
- if indeed your version of Unix provides a way to get modem signals
- (some don't; e.g. modem signals are a foreign concept to POSIX,
- requiring politically incorrect workarounds).
- aa. If it says "Modem signals unavailable", then it is likely that the
- API for getting modem signals is provided, but it doesn't actually
- do anything (e.g. ioctl(ttyfd,TIOCMGET,&x) returns EINVAL).
- ab. In any case, it still should be able to manipulate the DTR signal.
- To test, SET LINE , SET MODEM NONE, and HANGUP. The DTR light
- should go out momentarily. If it doesn't, see if you can add the
- needed code for your system to the tthang() routine in
- [227]ckutio.c.
- ac. If your version of Kermit has the SET FLOW RTS/CTS command, check
- to see if it works: give Kermit this command, set your modem for
- RTS/CTS, transfer some files (using big packet and window sizes)
- and watch the RTS and CTS lights on the modem. If they go on and
- off (and Kermit does not get packet errors), then it works. If your
- version of Kermit does not have this command, but your version of
- Unix does support hardware flow control, take a look at the
- tthflow() command in [228]ckutio.c and see if you can add the
- needed code (see the section on [229]HARDWARE FLOW CONTROL below).
- (And please [230]send back any added code, so that others can
- benefit from it and it can be carried forward into future
- releases.)
- ad. If C-Kermit starts normally and issues its prompt, echoing is
- normal, etc, but then after returning from a CONNECT session, the
- prompt no longer appears, try rebuilding with -DCKCONINTB4CB.
- ae. (8.0.206 or later) Type some commands at the C-Kermit prompt. Can
- you use the Up-arrow and Down-arrow keys on your keyboard to access
- Kermit's command history? If not, and you're a programmer, take a
- look at the USE_ARROWKEYS sections of ckucmd.c.
-
-8. REDUCING THE SIZE OF THE EXECUTABLE PROGRAM IMAGE
-
- [ [231]Top ] [ [232]Contents ] [ [233]Next ] [ [234]Previous ]
-
- Also see: [235]C-Kermit Configuration Options
-
- a. Many of C-Kermit's options and features can be deselected at
- compile time. The greatest savings at the least sacrifice in
- functionality is to disable the logging of debug information by
- defining NODEBUG during compilation. See the [236]Configurations
- Options document for further information.
- b. Use shared libraries rather than static linking. This is the
- default on many Unix systems anyway. However, executables built for
- dynamic linking with shared libraries are generally not portable
- away from the machine they were built on, so this is recommended if
- the binary is for your use only.
- c. Most Unix systems have a "strip" command to remove symbol table
- information from an executable program image. "man strip" for
- further information. The same effect can be achieved by including
- "-s" among the link flags when building C-Kermit.
- d. SCO, Interactive, and some other Unix versions have an "mcs"
- command. "mcs -d wermit" can be used to delete the contents of the
- ".comment" section from the executable program image.
- e. Many modern optimizers can be instructed to optimize for space
- rather than execution efficiency. Check the CFLAGS in the makefile
- target, adjust as desired.
-
-9. UNIX VERSIONS
-
- [ [237]Top ] [ [238]Contents ] [ [239]Next ] [ [240]Previous ]
-
- SECTION CONTENTS
-
-9.1 [241]Standards
- 9.1.1. [242]POSIX
- 9.1.2. [243]ANSI C
- 9.1.3. [244]Other Standards
-9.2. [245]Library Issues
-9.3. [246]Unix File System Peculiarities
-9.4. [247]Hardware Flow Control
-9.5. [248]Terminal Speeds
-9.6. [249]Millisecond Sleeps
-9.7. [250]Nondestructive Input Buffer Peeking
-9.8. [251]Other System-Dependent Features
-9.9. [252]Terminal Interruption
-
- There are several major varieties of Unix: Bell Laboratories Seventh
- Edition, AT&T System V, Berkeley Standard Distribution (BSD), and
- POSIX. Each has many, many subvarieties and descendents, and there are
- also hybrids that exhibit symptoms of two or more varieties, plus
- special quirks of their own.
-
- Seventh edition versions of C-Kermit include the compile-time option
- -DV7 in the CFLAGS string in the makefile target. Various V7-based
- implementations are also supported: -DCOHERENT, -DMINIX, etc.
-
- AT&T-based versions of Unix Kermit include the compile-time option
- -DATTSV (standing for AT∓T Unix System V). This applies to System
- III and to System V up to and including Release 2. For System V Release
- 3, the flag -DSVR3 should be used instead (which also implies -DATTSV).
- This is because the data type of signal() and several other functions
- was changed between SVR2 and SVR3. For System V Release 4, include
- -DSVR4 because of changes in UUCP lockfile conventions; this also
- implies -DSVR3 and -DATTSV.
-
- For BSD, the flag -BSDxx must be included, where xx is the BSD version
- number, for example BSD4 (for version 4.2 or later, using only 4.2
- features), -DBSD41 (for BSD 4.1 only), -DBSD43 (for 4.3), -DBSD29 (BSD
- 2.9 for DEC PDP-11s). -DBSD44 is for 4.4BSD, which is the basis of
- FreeBSD, NetBSD, OpenBSD, BSDI, and Mac OS X, and which contains many
- POSIX features, and has little relation to 4.3BSD and earlier.
-
- For POSIX, include the flag -DPOSIX. POSIX defines a whole new set of
- terminal i/o functions that are not found in traditional AT&T or
- Berkeley implementations, and also defines the symbol _POSIX_SOURCE,
- which is used in many system and library header files, mainly to
- disable non-POSIX (i.e. useful) features.
-
- Note (circa 1997): In order to enable serial speeds higher than 38400
- bps, it is generally necessary to add -DPOSIX (among other things),
- since the older terminal APIs can not accommodate the new speeds -- out
- o' bits. But this often also means wholesale conversion to POSIX APIs.
- In general, just try adding -DPOSIX and then see what goes wrong. Be
- wary of features disappearing: when _POSIX_SOURCE is defined, all sorts
- of things that were perfectly OK before suddenly become politically
- incorrect -- like reading modem signals, doing hardware flow control,
- etc. POSIX was evidently not designed with serial communication in
- mind!
-
- Case in point: In UnixWare 7.0, #define'ing POSIX causes strictness
- clauses in the header files to take effect. These prevent <sys/time.h>
- from defining the timeval and timezone structs, which are needed for
- all sorts of things (like select()). Thus, if we want the high serial
- speeds, we have to circumvent the POSIX clauses.
-
- Similarly in SCO OpenServer R5.0.4 where, again, we must use the POSIX
- APIs to get at serial speeds higher than 38400, but then doing so
- removes hardware flow control -- just when we need it most! In cases
- like this, dirty tricks are the only recourse (search for SCO_OSR504 in
- [253]ckutio.c for examples).
-
- For reasons like this, Unix implementations tend to be neither pure
- AT&T nor pure BSD nor pure POSIX, but a mixture of two or more of
- these, with "compatibility features" allowing different varieties of
- programs to be built on the same computer. In general, Kermit tries not
- to mix and match but to keep a consistent repertoire throughout.
- However, there are certain Unix implementations that only work when you
- mix and match. For example, the Silicon Graphics IRIX operating system
- (prior to version 3.3) is an AT&T Unix but with a BSD file system. The
- only way you can build Kermit successfully for this configuration is to
- include -DSVR3 plus the special option -DLONGFN, meaning "pretend I was
- built with -DBSDxx when it's time to compile file-related code". See
- the "iris" makefile target.
-
-9.1. Standards
-
- [ [254]Top ] [ [255]Section Contents ] [ [256]Contents ] [ [257]Next ]
-
- SUBSECTION CONTENTS
-
-9.1.1. [258]POSIX
-9.1.2. [259]ANSI C
-9.1.3. [260]Other Standards
-
- In edits 166-167 (1988-89), C-Kermit was heavily modified to try to
- keep abreast of new standards while still remaining compatible with old
- versions of C and Unix. There are two new standards of interest: ANSI C
- (as described in Kernighan and Ritchie, "The C Programming Language",
- Second Edition, Prentice Hall, 1988) and POSIX.1 (IEEE Standard 1003.1
- and ISO/IEC 9945-1, 1990, "Portable Operating System Interface"). These
- two standards have nothing to do with each other: you can build
- C-Kermit with a non-ANSI compiler for a POSIX system, or for a
- non-POSIX system with with an ANSI compiler.
-
-9.1.1. POSIX
-
- POSIX.1 defines a repertoire of system functions and header files for
- use by C language programs. Most notably, the ioctl() function is not
- allowed in POSIX; all ioctl() functions have been replaced by
- device-specific functions like tcsetattr(), tcsendbreak(), etc.
-
- Computer systems that claim some degree of POSIX compliance have made
- some attempt to put their header files in the right places and give
- them the right names, and to provide system library functions with the
- right names and calling conventions. Within the header files,
- POSIX-compliant functions are supposed to be within #ifdef
- _POSIX_SOURCE..#endif conditionals, and non-POSIX items are not within
- these conditionals.
-
- If Kermit is built with neither -D_POSIX_SOURCE nor -DPOSIX, the
- functions and header files of the selected version of Unix (or VMS,
- etc) are used according to the CFLAGS Kermit was built with.
-
- If Kermit is built with -D_POSIX_SOURCE but not -DPOSIX, then one of
- the -DBSD or -DATTSV flags (or one that implies them) must also be
- defined, but it still uses only the POSIX features in the system header
- files. This allows C-Kermit to be built on BSD or AT&T systems that
- have some degree of POSIX compliance, but still use BSD or AT&T
- specific features.
-
- The dilemma is this: it is often necessary to define _POSIX_SOURCE to
- get at new or modern features, such as high serial speeds and the APIs
- to deal with them. But defining _POSIX_SOURCE also hides other APIs
- that Kermit needs, for example the ones dealing with modem signals
- (others are listed just below). Thus all sorts of hideous contortions
- are often required to get a full set of features.
-
- The POSIX standard does not define anything about uucp lockfiles. "make
- posix" uses NO (repeat, NO) lockfile conventions. If your
- POSIX-compliant Unix version uses a lockfile convention such as HDBUUCP
- (see below), use the "posix" entry, but include the appropriate
- lockfile option in your KFLAGS on the "make" command line, for example:
-
-make posix "KFLAGS=-DHDBUUCP"
-
- POSIX.1 also lacks certain other features that Kermit needs. For
- example:
-
- * There is no defined way for an application to do wildcard matching
- of filenames. Kermit uses the inode in the directory structure, but
- POSIX.1 does not include this concept. (Later POSIX revisions
- include functions named (I think) glob() and fnmatch(), but these
- functions are not yet in Kermit, and might not be appropriate in
- any case.)
- * There is no POSIX mechanism for sensing or controlling modem
- signals, nor to enable RTS/CTS or other hardware flow control.
- * There is no select() for multiplexing i/o, and therefore no TCP/IP.
- * There is no way to check if characters are waiting in a
- communications device (or console) input buffer, short of trying to
- read them -- no select(), ioctl(fd,FIONREAD,blah), rdchk(), etc.
- This is bad for CONNECT mode and bad for sliding windows.
- * No way to do a millisecond sleep (no nap(), usleep(), select(),
- etc).
- * There is no popen().
-
- So at this point, there cannot be one single fully functional POSIX
- form of C-Kermit unless it also has "extensions", as do Linux, QNX,
- etc.
-
- More on POSIX (quoting from a newsgroup posting by Dave Butenhof):
-
- Standards tend to look at themselves as "enabling". So POSIX
- standards say that, in order to use POSIX functions, a program must
- define some macro that will put the development environment in
- "POSIX mode". For the ancient POSIX 1003.1-1990, the symbol is
- _POSIX_SOURCE. For recent revisions, it's _POSIX_C_SOURCE with an
- appropriate value. POSIX 1003.1-1996 says that, to use its features
- in a portable manner, you must define _POSIX_C_SOURCE=199506L before
- including any header files.
-
- But for Solaris, or Digital Unix, the picture is different. POSIX is
- one important but small part of the universe. Yet POSIX
- unconditionally and unambiguously REQUIRES that, when
- _POSIX_C_SOURCE=199506L, ALL of the functions and definitions
- required by the standard, and NO others (except in specific
- restricted namespaces, specifically "_" followed by an uppercase
- letter or "__" followed by a lowercase letter) shall be visible.
- That kinda puts a cramp on BSD and SVID support, because those
- require names that are not in the "protected" POSIX namespaces. It's
- ILLEGAL to make those symbols visible, unless you've done something
- else that's beyond the scope of POSIX to allow the system to infer
- that you didn't really mean it.
-
- In most cases, you should just compile, with no standards-related
- macros defined. The system will make available every interface and
- definition that isn't incompatible with the "main stream". There may
- indeed be cases where two standards cross, and you really can't use
- both together. But, in general, they play nicely together as long as
- you don't do anything rash -- like telling the system that it's not
- allowed to let them.
-
- In the area of threads, both Solaris and Digital Unix support
- incompatible thread APIs. We have POSIX and DCE, they have POSIX and
- UI. The nasty areas are in the _r routines and in some aspects of
- signal behavior. You cannot compile a single source file that uses
- both semantics. That's life. It sounds as if Solaris defaults to the
- UI variants, but allows you to define this _POSIX_THREAD_SEMANTICS
- to get around it. We default to POSIX, and allow you to define
- _PTHREAD_USE_D4 (automatically defined by the cc "-threads" switch)
- to select the DCE thread variants. That default, because you're
- operating outside of any individual standard, is really just a
- marketing decision.
-
-9.1.2. ANSI C
-
- [ [261]Top ] [ [262]Contents ] [ [263]Section Contents ] [
- [264]Subsection Contents ] [ [265]Next ] [ [266]Previous ]
-
- The major difference between ANSI C and earlier C compilers is function
- prototyping. ANSI C allows function arguments to be checked for type
- agreement, and (when possible) type coercion in the event of a
- mismatch. For this to work, functions and their arguments must be
- declared before they are called. The form for function declarations is
- different in ANSI C and non-ANSI C (ANSI C also accepts the earlier
- form, but then does not do type checking).
-
- As of edit 167, C-Kermit tries to take full advantage of ANSI C
- features, especially function prototyping. This removes many bugs
- introduced by differing data types used or returned by the same
- functions on different computers. ANSI C features are automatically
- enabled when the symbol __STDC__ is defined. Most ANSI C compilers,
- such as GNU CC and the new DEC C compiler define this symbol
- internally.
-
- On the downside, ANSI C compilation increases the
- administrative/bureaucratic burden, spewing out countless unneeded
- warnings about mismatched types, especially when we are dealing with
- signed and unsigned characters, requiring casts everywhere to shut up
- the mindless complaints -- there is no use for signed chars in Kermit
- (or probably anywhere else). Some compilers, mercifully, include a
- "treat all chars as unsigned" option, and when available it should be
- used -- not only to stop the warnings, but also to avoid unhelpful sign
- extension on high-bit characters.
-
- To force use of ANSI C prototypes, include -DCK_ANSIC on the cc command
- line. To disable the use of ANSI prototypes, include -DNOANSI.
-
-9.1.3. Other Standards
-
- [ [267]Top ] [ [268]Contents ] [ [269]Section Contents ] [
- [270]Subsection Contents ] [ [271]Next ] [ [272]Previous ]
-
- As the years go by, standards with-which-all-must-comply continue to
- pile up: AES, XPG2, XPG3, XPG4, FIPS 151-2, successive generations of
- POSIX, OSF/1, X/Open, Spec 1170, UNIX95, Open Group UNIX98, ISO/IEC
- 9945 parts 1-4, ISO 9899, 88Open, OS 99, Single Unix Specification
- (SUS, [273]IEEE 1003.1-2001, not to mention "mature standards" like V7,
- 4.2/4.3BSD, System V R3 and R4 (SVID2 and SVID3), 4.4BSD (the basis for
- BSDI, OpenBSD, NetBSD, FreeBSD, Mac OS X etc), /usr/group, plus
- assorted seismic pronouncements of the neverending series of ephemeral
- corporate consortia, not to mention the libc-vs-glibc turmoil in the
- Linux arena and who knows what else.
-
- None of these standards simplifies life for portable applications like
- C-Kermit -- each one is simply one more environment to support (or
- circumvent, as in many cases these standards do more harm than good by
- denying access to facilities we need, e.g. as noted in above in
- [274]9.1.1).
-
-9.2. Library Issues
-
- [ [275]Top ] [ [276]Contents ] [ [277]Section Contents ] [
- [278]Subsection Contents ] [ [279]Next ] [ [280]Previous ]
-
- On most modern platforms, applications are -- and often must be --
- dynamically linked. This has numerous advantages (smaller executables,
- ability to patch a library and thereby patch all applications that use
- it, etc), but also causes some headaches: most commonly, the library ID
- built into the executable at link time does not match the ID of the
- corresponding library on the target system, and so the loader refuses
- to let the application run.
-
- This problem only gets worse over time. In the Linux and *BSD world, we
- also have totally different libraries (each with their own names and
- numbering systems) that cover the same territory; for example, curses
- vs ncurses, libc versus glibc. Combinations proliferate and any given
- Unix computer might have any combination. For this reason it is
- becoming increasingly difficult to produce a "Linux binary" for a given
- architecture (e.g. PC or Alpha). There has to be a separate binary for
- (at least) every combination of curses vs ncurses and libc vs glibc.
-
- In such cases, the best advice is for every user to build C-Kermit from
- source code on the system where it will run. Too bad most commercial
- Unix vendors have stopped including C compilers with the operating
- system!
-
-9.3. Unix File System Peculiarities
-
- [ [281]Top ] [ [282]Contents ] [ [283]Section Contents ] [ [284]Next ]
- [ [285]Previous ]
-
- Normally, including a BSD, System-V, POSIX, or DIRENT flag in the make
- entry selects the right file system code. But some versions of Unix are
- inconsistent in this regard, and building in the normal way either
- gives compiler or linker errors, or results in problems at runtime,
- typically failure to properly expand wildcard file specifications when
- you do something like "send *.*", or failure to recognize long
- filenames, as in "send filewithaveryveryveryveryverylongname".
-
- C-Kermit is supposed to know about all the various styles of Unix file
- systems, but it has to be told which one to use when you build it,
- usually in the makefile target CFLAGS as shown below, but you might
- also have to add something like -I/usr/include/bsd to CFLAGS, or
- something like -lbsd to LIBS.
-
- C-Kermit gives you the following CFLAGS switches to adapt to your file
- system's peculiarities:
-
--DDIRENT - #include <dirent.h>
--DSDIRENT - #include <sys/dirent.h>
--DNDIR - #include <ndir.h>
--DXNDIR - #include <sys/ndir.h>
--DRTU - #include "/usr/lib/ndir.h", only if NDIR and XNDIR not defined.
--DSYSUTIMH - #include <sys/utime.h> for setting file creation dates.
--DUTIMEH - #include <utime.h> for setting file creation dates.
-
- (Note, RTU should only be used for Masscomp RTU systems, because it
- also selects certain other RTU-specific features.)
-
- If none of these is defined, then <sys/dir.h> is used. IMPORTANT: If
- your system has the file /usr/include/dirent.h then be sure to add
- -DDIRENT to your makefile target's CFLAGS. "dirent" should be used in
- preference to any of the others, because it supports all the features
- of your file system, and the others probably don't.
-
- Having selected the appropriate directory header file, you might also
- need to tell Kermit how to declare the routines and variables it needs
- to read the directory. This happens most commonly on AT&T System-V
- based UNIXes, particularly System V R3 and earlier, that provide long
- file and directory names (longer than 14 characters). Examples include
- certain releases of HP-UX, DIAB DNIX, older versions of Silicon
- Graphics IRIX, and perhaps also MIPS. In this case, try adding -DLONGFN
- to your makefile target.
-
- Another problem child is <sys/file.h>. Most Unix C-Kermit versions need
- to #include this file from within [286]ckufio.c and [287]ckutio.c, but
- some not only do not need to include it, but MUST not include it
- because (a) it doesn't exist, or (b) it has already been included by
- some other header file and it doesn't protect itself against multiple
- inclusion, or (c) some other reason that prevents successful
- compilation. If you have compilation problems that seem to stem from
- including this file, then add the following switch to CFLAGS in your
- makefile target:
-
--DNOFILEH
-
- There are a few odd cases where <sys/file.h> must be included in one of
- the cku[ft]io.c files, but not the other. In that case, add the
- aforementioned switch, but go into the file that needs <sys/file.h> and
- add something like this:
-
-#ifdef XXX /* (where XXX is a symbol unique to your system) */
-#undef NOFILEH
-#endif /* XXX */
-
- before the section that includes <sys/file.h>.
-
- Kermit's SEND command expands wildcard characters "?" and "*" itself.
- Before version 5A, commands like "send *" would send all regular
- (non-directory) files, including "hidden files" (whose names start with
- "."). In version 5A, the default behavior is to match like the Bourne
- shell or the ls command, and not include files whose names start with
- dot. Such files can still be sent if the dot is included explicitly in
- the SEND command: "send .oofa, send .*". To change back to the old way
- and let leading wildcard characters match dot files, include the
- following in your CFLAGS:
-
--DMATCHDOT
-
- (In C-Kermit 6.0, there is also a command to control this at runtime.)
-
- Complaints about data-type mismatches:
-
- * If you get compile-time complaints about data type mismatches for
- process-ID related functions like getpid(), add -DPID_T=pid_t.
- * If you get compile-time complaints about data type mismatches for
- user ID related functions like getuid(), add -DUID_T=uid_t.
- * If you get compile-time complaints about data type mismatches for
- user-ID related functions like getgid(), add -DGID_T=gid_t.
- * If you get compile-time complaints about data type mismatches for
- getpwuid(), add -DPWID_T=uid_t (or whatever it should be).
-
- File creation dates: C-Kermit attempts to set the creation date/time of
- an incoming file according to the date/time given in the file's
- attribute packet, if any. If you find that the dates are set
- incorrectly, you might need to build Kermit with the -DSYSUTIMEH flag,
- to tell it to include <sys/utime.h>. If that doesn't help, look at the
- code in zstrdt() in [288]ckufio.c.
-
-9.4. Hardware Flow Control
-
- [ [289]Top ] [ [290]Contents ] [ [291]Section Contents ] [ [292]Next ]
- [ [293]Previous ]
-
- Hardware flow control is a problematic concept in many popular Unix
- implementations. Often it is lacking altogether, and when available,
- the application program interface (API) to it is inconsistent from
- system to system. Here are some examples:
-
- a. POSIX does not support hardware flow control.
- b. RTS/CTS flow control support MIGHT be available for System V R3 and
- later if /usr/include/termiox.h exists (its successful operation
- also depends on the device driver, and the device itself, not to
- mention the [294]cable, etc, actually supporting it). If your
- SVR3-or-later Unix system does have this file, add:
-
--DTERMIOX
-
- to your CFLAGS. If the file is in /usr/include/sys instead, add:
-
--DSTERMIOX
-
- Note that the presence of this file does not guarantee that RTS/CTS
- will actually work -- that depends on the device-driver
- implementation (reportedly, many Unix versions treat
- hardware-flow-control related ioctl's as no-ops).
- c. Search ("grep -i") through /usr/include/*.h and
- /usr/include/sys/*.h for RTS or CTS and see what turns up. For
- example, in SunOS 4.x we find "CRTSCTS". Figuring out how to use it
- is another question entirely! In IBM AIX RS/6000 3.x, we have to
- "add" a new "line discipline" (and you won't find uppercase RTS or
- CTS symbols in the header files).
- d. NeXTSTEP and IRIX, and possibly others, support hardware flow
- control, but do not furnish an API to control it, and thus on these
- systems Kermit has no command to select it -- instead, a special
- device name must be used. (NeXTSTEP: /dev/cufa instead of /dev/cua;
- IRIX: /dev/ttyf00)
-
- See the routine tthflow() in [295]ckutio.c for details. If you find
- that your system offers hardware flow control selection under program
- control, you can add this capability to C-Kermit as follows:
-
- a. See if it agrees with one of the methods already used in tthflow().
- if not, add new code, appropriately #ifdef'd.
- b. Add -DCK_RTSCTS to the compiler CFLAGS in your makefile target or
- define this symbol within the appropriate #ifdefs in [296]ckcdeb.h.
-
- To illustrate the difficulties with RTS/CTS, here is a tale from Jamie
- Watson <jw@adasoft.ch>, who added the RTS/CTS code for the RS/6000,
- about his attempts to do the same for DEC ULTRIX:
-
- "The number and type of hardware signals available to/from a serial
- port vary between different machines and different types of serial
- interfaces on each machine. This means that, for example, there are
- virtually no hardware signals in or out available on the DECsystem
- 3000/3100 series; on the DECsystem 5000/2xx series all modem signals
- in/out are present on both built-in serial ports; on the DECsystem
- 5100 some ports have all signals and some only have some; and so
- on... It looks to me as if this pretty well rules out any attempt to
- use hardware flow control on these platforms, even if we could
- figure out how to do it. The confusion on the user level about
- whether or not it should work for any given platform or port would
- be tremendous. And then it isn't clear how to use the hardware
- signals even in the cases where the device supports them."
-
- 9.5. Terminal Speeds
-
- [ [297]Top ] [ [298]Contents ] [ [299]Section Contents ] [ [300]Next ]
- [ [301]Previous ]
-
- The allowable speeds for the SET SPEED command are defined in
- [302]ckcdeb.h. If your system supports speeds that are not listed in
- "set speed ?", you can add definitions for them to ckcdeb.h.
-
- Then if the speed you are adding is one that was never used before in
- Kermit, such as 921600, you'll also need to add the appropriate
- keywords to spdtab[] in [303]ckuus3.c, and the corresponding case to
- ttsspd() in [304]ckutio.c.
-
- 9.6. Millisecond Sleeps
-
- [ [305]Top ] [ [306]Contents ] [ [307]Section Contents ] [ [308]Next ]
- [ [309]Previous ]
-
- There is no standard for millisecond sleeps, but at least five
- different functions have appeared in various Unix versions that can be
- used for this purpose: nap() (mostly in System V), usleep() (found at
- least in SunOS and NeXT OS), select() (found in 4.2BSD and later, and
- part of any TCP/IP sockets library), nanosleep(), and sginap(). If you
- have any of these available, pick one (in this order of preference, if
- you have more than one):
-
--DSELECT: Include this in CFLAGS if your system has the select() function.
--DNAP: Include this in CFLAGS if your system has the nap() function.
--USLEEP: Include this in CFLAGS if your system has the usleep() function.
-
- NOTE: The nap() function is assumed to be a function that puts the
- process to sleep for the given number of milliseconds. If your system's
- nap() function does something else or uses some other units of time
- (like the NCR Tower 32, which uses clock-ticks), do not include -DNAP.
-
- Reportedly, all versions of System V R4 for Intel-based computers, and
- possibly also SVR3.2, include nap() as a kernel call, but it's not in
- the library. To include code to use it via syscall(3112,x), without
- having to include Xenix compatibility features, include the following
- compile-time option:
-
--DNAPHACK
-
- 9.7. Nondestructive Input Buffer Peeking
-
- [ [310]Top ] [ [311]Contents ] [ [312]Section Contents ] [ [313]Next ]
- [ [314]Previous ]
-
- Some AT&T Unix versions have no way to check if input is waiting on a
- tty device, but this is a very important feature for Kermit. Without
- it, sliding windows might not work very well (or at all), and you also
- have to type your escape character to get Kermit's attention in order
- to interrupt a local-mode file transfer. If your system offers an
- FIONREAD ioctl, the build procedure should pick that up automatically
- and use it, which is ideal.
-
- If your system lacks FIONREAD but has a select() function, this can be
- used instead. If the build procedure fails to include it (SHOW FEATURES
- will list SELECT), then you can add it to your CFLAGS:
-
--DSELECT
-
- Conversely, if the build procedure tries to use select() when it really
- is not there, add:
-
--DNOSELECT
-
- Note: select() is not part of System V nor of POSIX, but it has been
- added to various System-V- and POSIX-based systems as an extension.
-
- Some System-V variations (SCO Xenix/UNIX/ODT and DIAB DNIX) include a
- rdchk() function that can be used for buffer peeking. It returns 0 if
- no characters are waiting and 1 if characters are waiting (but unlike
- FIONREAD, it does not tell the actual number). If your system has
- rdchk(), add:
-
--DRDCHK: Include this in CFLAGS if your system has the rdchk() function.
-
- Otherwise, if your version of Unix has the poll() function (and the
- /usr/include/poll.h file) -- which appears to be a standard part of
- System V going back to at least SVR3, include:
-
--DCK_POLL
-
- 9.8. Other System-Dependent Features
-
- [ [315]Top ] [ [316]Contents ] [ [317]Section Contents ] [ [318]Next ]
- [ [319]Previous ]
-
- Systems with <termios.h> might have the symbol IEXTEN defined. This is
- used to turn "extended features" in the tty device driver on and off,
- such as Ctrl-O to toggle output flushing, Ctrl-V to quote input
- characters, etc.
-
- In most Unix implementations, it should be turned off during Kermit
- operation, so if [320]ckutio.c finds this symbol, it uses it. This is
- necessary, at least, on BSDI. On some systems, however, IEXTEN is
- either misdefined or misimplemented. The symptom is that CR, when typed
- to the command processor, is echoed as LF, rather than CRLF. This
- happens (at least) on Convex/OS 9.1. The solution is to add the
- following symbol to the makefile target's CFLACS:
-
--DNOIEXTEN
-
- However, in at least one Unix implementation, QNX 4.21, IEXTEN must be
- set before hardware flow control can be used.
-
- In edits 177 and earlier, workstation users noticed a "slow screen
- writing" phenomenon during interactive command parsing. This was traced
- to a setbuf() call in [321]ckutio.c that made console (stdout) writes
- unbuffered. This setbuf() call has been there forever, and could not be
- removed without some risk. Kermit's operation was tested on the NeXT in
- edit 178 with the setbuf() call removed, and the slow-writing symptom
- was cured, and everything else (command parsing, proper wakeup on ?,
- ESC, Ctrl-U, and other editing characters, terminal emulation,
- remote-mode and local-mode file transfer, etc) seemed to work as well
- as or better than before. In subsequent edits, this change was made to
- many other versions too, with no apparent ill effects. To remove the
- setbuf() call for your version of Kermit, add:
-
--DNOSETBUF
-
- Later reports indicate that adding -DNOSETBUF has other beneficial
- effects, like cutting down on swapping when Kermit is run on
- workstations with small memories. But BEWARE: on certain small Unix
- systems, notably the AT&T 6300 and 3B1 (the very same ones that benefit
- from NOSETBUF), NOSETBUF seems to conflict with CK_CURSES. The program
- builds and runs OK, but after once using the curses display, echoing is
- messed up. In this case, we use a System-V specific variation in the
- curses code, using newterm() to prevent System V from altering the
- buffering. See makefile entries for AT&T 6300 and 3B1.
-
- The Unix version of C-Kermit includes code to switch to file descriptor
- zero (stdin) for remote-mode file transfer. This code is necessary to
- prevent Kermit from giving the impression that it is "idle" during file
- transfers, which, at some sites, can result in the job being logged out
- in the middle of an active file transfer by idle-job monitors.
-
- However, this feature can interfere with certain setups; for example,
- there is a package which substitutes a pty/tty pair for /dev/tty and
- sets file descriptor 0 to be read-only, preventing Kermit from sending
- packets. Or... When a Unix shell is invoked under the PICK environment,
- file descriptor 0 is inoperative.
-
- To remove this feature and allow Kermit to work in such environments,
- add the compile-time option:
-
--DNOFDZERO
-
- On some versions of Unix, earlier releases of C-Kermit were reported to
- render a tty device unusable after a hangup operation. Examples include
- IBM AIX on the RT PC and RS/6000. A typical symptom of this phenomenon
- is that the DIAL command doesn't work, but CONNECTing to the device and
- dialing manually do work. A further test is to SET DIAL HANGUP OFF,
- which should make dialing work once by skipping the pre-dial hangup.
- However, after the connection is broken, it can't be used any more:
- subsequent attempts to DIAL the same device don't work. The cure is
- usually to close and reopen the device as part of the hangup operation.
- To do this, include the following compile-time option:
-
--DCLSOPN
-
- Similarly, there is a section of code in ttopen(), which does another
- close(open()) to force the O_NDELAY mode change. On some systems, the
- close(open()) is required to make the mode change take effect, and
- apparently on most others it does no harm. But reportedly on at least
- one System V R4 implementation, and on SCO Xenix 3.2, the close(open())
- operation hangs if the device lacks carrier, EVEN THOUGH the CLOCAL
- characteristic has just been set to avoid this very problem. If this
- happens to you, add this to your CFLAGS:
-
--DNOCOTFMC
-
- or, equivalently, in your KFLAGS on the make command line. It stands
- for NO Close(Open()) To Force Mode Change.
-
- C-Kermit renames files when you give a RENAME command and also
- according to the current SET FILE COLLISION option when receiving
- files. The normal Unix way to rename a file is via two system calls:
- link() and unlink(). But this leaves open a window of vulnerability.
- Some Unix systems also offer an atomic rename(oldname,newname)
- function. If your version of Unix has this function, add the following
- to your CFLAGS:
-
--DRENAME
-
- C-Kermit predefines the RENAME for several Unix versions in
- [322]ckcdeb.h (SVR4, SUNOS41, BSD44, AIXRS, etc). You can tell if
- rename() is being used if the SHOW FEATURES command includes RENAME in
- the compiler options list. If the predefined RENAME symbol causes
- trouble, then add NORENAME to your CFLAGS. Trouble includes:
-
- a. Linker complains that _rename is an unresolved symbol.
- b. Linking works, but Kermit's RENAME command doesn't work (which
- happens because older versions of rename() might have their
- arguments reversed).
-
- If rename() is not used, then Kermit uses link()/unlink(), which is
- equivalent except it is not atomic: there is a tiny interval in which
- some other process might "do something" to one of the files or links.
-
- Some Unix systems (Olivetti X/OS, Amdahl UTS/V, ICL SVR3, etc) define
- the S_ISREG and S_ISDIR macros incorrectly. This is compensated for
- automatically in [323]ckufio.c. Other systems might have this same
- problem. If you get a compile-time error message regarding S_ISREG
- and/or S_ISDIR, add the following to your CFLAGS:
-
--DISDIRBUG
-
- Finally, here's a symbol you should NEVER define:
-
--DCOMMENT
-
- It's used for commenting out blocks of code. If for some reason you
- find that your compiler has COMMENT defined, then add -UCOMMENT to
- CFLAGS or KFLAGS! Similarly, some header files have been known to
- define COMMENT, in which case you must add "#undef COMMENT" to each
- C-Kermit source module, after all the #includes.
-
- 9.9. Terminal Interruption
-
- [ [324]Top ] [ [325]Contents ] [ [326]Section Contents ] [ [327]Next ]
- [ [328]Previous ]
-
- When C-Kermit enters interactive command mode, it sets a Control-C
- (terminal keyboard interrupt = SIGINT) trap to allow it to return to
- the command prompt whenever the user types Control-C (or whatever is
- assigned to be the interrupt character). This is implemented using
- setjmp() and longjmp(). On some systems, depending on the machine
- architecture and C compiler and who knows what else, you might get
- "Memory fault (coredump)" or "longjmp botch" instead of the desired
- effect (this should not happen in 5A(190) and later). In that case, add
- -DNOCCTRAP to your CFLAGS and rebuild the program.
-
- Job control -- the ability to "suspend" C-Kermit on a Unix system by
- typing the "susp" character (normally Ctrl-Z) and then resume execution
- later (with the "fg" command) -- is a tricky business. C-Kermit must
- trap suspend signals so it can put the terminal back into normal mode
- when you suspend it (Kermit puts the terminal into various strange
- modes during interactive command parsing, CONNECT, and file transfer).
- Supporting code is compiled into C-Kermit automatically if <signal.h>
- includes a definition for the SIGTSTP signal. HOWEVER... some systems
- define this signal without supporting job control correctly. You can
- build Kermit to ignore SIGTSTP signals by including the -DNOJC option
- in CFLAGS. (You can also do this at runtime by giving the command SET
- SUSPEND OFF.)
-
- NOTE: As of version 5A(190), C-Kermit makes another safety check.
- Even if job control is available in the operating system (according
- to the numerous checks made in congm()), it will still disable the
- catching of SIGTSTP signals if SIGTSTP was set to SIG_IGN at the
- time C-Kermit was started.
-
- System V R3 and earlier systems normally do not support job control. If
- you have an SVR3 system that does, include the following option in your
- CFLAGS:
-
--DSVR3JC
-
- On systems that correctly implement POSIX signal handling, signals can
- be handled more reliably than in Bell, Berkeley, or AT&T Unixes. On
- systems (such as QNX) that are "strictly POSIX", POSIX signal handling
- *must* be used, otherwise no signal will work more than once. If you
- have POSIX-based system and you find that your version of Kermit
- responds to Ctrl-C (SIGINT) or Ctrl-Z (SIGTSTP) only once, then you
- should add the following option to your CFLAGS:
-
--DCK_POSIX_SIG
-
- But be careful; some POSIX implementations, notably 4.4BSD, include
- POSIX signal handling symbols and functions as "stubs" only, which do
- nothing. Look in <signal.h> for sigsetjmp and siglongjmp and read the
- comments.
-
-10. DIALING OUT AND COORDINATING WITH UUCP
-
- [ [329]Top ] [ [330]Contents ] [ [331]Next ] [ [332]Previous ]
-
- The short version (general):
-
- In order for C-Kermit to be able to dial out from your Unix
- computer, you need to give it the same owner, group, and permissions
- as your other dialout programs, such as cu, tip, minicom, uucp,
- seyon, etc.
-
- The short version for Linux only:
-
- Since Red Hat 7.2, about 2002, Linux does not leave the lockfile
- handling to each application, but instead provides an external
- application, /usr/sbin/lockdev, that all applications should invoke
- when they need to access a serial port; lockdev locks and unlocks
- the port without requiring the application to have privileges, since
- the privileges on the lockfile directory are assigned to lockdev.
- C-Kermit 8.0.211 and later support this method. But C-Kermit still
- needs to be able to open the port itself, and therefore if the
- port's permissions do not allow read/write access to the general
- public, the general rule must still be followed: in the most common
- case, it must be SETGID to the group uucp (explained below). If a
- pre-8.0.211 version of C-Kermit is to be installed for use with
- serial ports on any version of Linux, it must still be installed as
- described in the following sections.
-
- The long version:
-
- Make sure your dialout line is correctly configured for dialing out (as
- opposed to login). The method for doing this is different for each kind
- of Unix. Consult your system documentation for configuring lines for
- dialing out (for example, Sun SPARCstation IPC users should read the
- section "Setting up Modem Software" in the Desktop SPARC Sun System and
- Network Manager's Guide, or the Terminals and Modems section of the HP
- manual, "Configuring HP-UX for Peripherals" (e.g. /usr/sbin/sam =>
- Peripheral Devices => Terminals and Modems => Add Modem).
-
- Unlike most other multiuser, multitasking operating systems, Unix
- allows multiple users to access the same serial device at the same
- time, even though there is no earthly reason why two users should do
- this. When they do, user A will read some of the incoming characters,
- and user B will read the others. In all likelihood, neither user will
- see them all. Furthermore, User B can hang up User A's call, and so
- one.
-
- Rather than change Unix to enforce exclusive access to serial devices
- such as ttys, when it might still have been possible, Unix developers
- opted for a "lock file" mechanism. Any process that wants to open a tty
- device should first check to see if a file of a certain name exists,
- and if so, not to open the device. If the file does not exist, the
- process creates the file and then opens the device. When the process
- closes the device, it destroys the lockfile. This procedure was
- originated for use with Unix's UUCP, CU, and TIP programs, and so these
- lockfiles are commonly called "UUCP lockfiles" (UUCP = Unix-to-Unix
- Copy Program).
-
- As you can imagine, this method is riddled with pitfalls:
-
- * If a process does not observe the prevailing lockfile convention,
- then it can interfere with other "polite" processes. And in fact,
- very few Unix applications or commands handle lockfiles at all; an
- original design goal of Unix was that "everything is a file", and
- countless utilities operate on files directly (by opening them) or
- indirectly through redirection of standard i/o, without creating or
- looking for lockfiles.
- * If a process crashes while it has the device open, the lockfile is
- left behind, preventing further processes from using the device.
- * Various versions of Unix use different names for the lockfiles, put
- them in different directories, with different owners and groups and
- permissions, and specify their contents differently.
- * On a given platform, the lockfile conventions may change from one
- Unix release to the next (for example, SunOS 4.0 to 4.1) or, in the
- case of Linux, across different distributions.
- * The same tty device might have more than one name, and most
- lockfile conventions don't allow for this. Similarly for symbolic
- links.
-
- In an attempt to address the problem of "stale" lockfiles, most UUCP
- implementations put the PID (Process ID) of the creating process in the
- lockfile. Thus, another process that wants to open the corresponding
- device can check not only for the lockfile itself, but also can check
- the PID for validity. But this doesn't work well either:
-
- * PIDs are stored in diverse formats that change with every new
- release (short, integer, long, or string in any of various
- formats). If the reading program does not follow the same
- convention as the writing program, it can diagnose a valid PID to
- be invalid, and therefore not honor the lock.
- * PIDs recycle. If the lockfile was created by PID 1234, which later
- crashed without removing the lockfile, and then a new process 1234
- exists a the time the lockfile is checked, the lockfile will be
- improperly taken as valid, and access to the device denied
- unnecessarily.
-
- Several techniques address the problem of multiple names for the same
- device:
-
- * Multiple lockfiles. For example, if the user opens a device through
- a symlink, a lockfile is created for both the symlink name and the
- true name (obtained from readlink()). However, when multiple
- drivers are installed for the same device (e.g. /dev/cua,
- /dev/cufa, etc), this approach won't work unless all applications
- *know* all the different names for the same device and make
- lockfiles for all of them, which is obviously not practical.
- * Lockfiles whose names are not based on the device name. These
- lockfiles generally have names like LK.inode/major/minor, where
- inode, major, and minor are numbers, which will always be the same
- for any physical device, no matter what its name. This form of
- lockfile is used in System V R4 and its derivatives, such as
- Solaris, UnixWare, etc. If lockfiles must be used (as opposed to,
- say, kernel-based locks), this would seem to be the most effective
- form.
-
- Most versions of Unix were not designed to accommodate third-party
- communications software; thus vendors of these Unix products feel no
- compunction about changing lockfile conventions from release to
- release, since they also change their versions of the cu, uucp, tip,
- etc, programs at the same time to match. And since the source code to
- these programs might not be published, it is difficult for makers of
- third-party products like C-Kermit to find out what the new conventions
- are. It also forces release of new versions of C-Kermit whenever the OS
- vendor makes a change like this.
-
- Some Unix vendors have taken a small step to simplify communications
- application development for their products: the inclusion of lockfile
- routines in the standard system C runtime libraries to shield the
- application from the details of lockfile management (IBM AIX is an
- example). When such routines are used, communications applications do
- not need modification when lockfile conventions change (although they
- will need recompiling if the routines are statically linked into the
- application). In the AIX example, the simple function calls ttylock(),
- ttyunlock(), and ttylocked() replace hundreds of lines of ugly code in
- C-Kermit that attempts to keep pace with every release of every Unix
- product over the last 20 years. Inclusion of ttylock() code occurs
- when:
-
--DUSETTYLOCK
-
- is included in the CFLAGS.
-
- If such routines are available, they should be used. The rest of this
- section applies when they are not.
-
- To fit in with UUCP and other Unix-based serial-port communication
- software, C-Kermit must have the same idea as your system's uucp, cu,
- and tip programs about what the UUCP lock directory is called, what the
- lockfile itself is called, and what its contents should be. In most
- cases, C-Kermit preprocessor flags create the appropriate configuration
- at compile time if the appropriate makefile target was used (see
- [333]ckutio.c). The following CFLAGS options can be used to override
- the built-in configuration:
-
- -DLCKDIR
- Tells Kermit that the UUCP lock directory is
- /usr/spool/uucp/LCK.
-
- -DACUCNTRL
- Tells Kermit to use the BSD 4.3 acucntrl() program to turn off
- getty (login) on the line before using it, and restore getty
- when done.
-
- -DHDBUUCP
- Include this if your system uses Honey DanBer UUCP, in which the
- lockfile directory and format are relatively standardized.
-
- -DLOCK_DIR=\\\"/xxx/yyy\\\"
- Gives the lock directory name explicitly. The triple quoting is
- necessary. For example:
-
-CFLAGS= -DBSD4 -DLOCK_DIR=\\\"/usr/local/locks\\\" -DNODEBUG
-
- (NOTE: The triple quoting assumes this is a "top-level" make
- entry, and not a make entry that calls another one.)
-
- -DLFDEVNO The lockfile name uses the tty device inode and major and
- minor
- numbers: LK.dev.maj.min, as in Sys V R4, e.g. LK.035.044.008.
-
- When the LK.inode.major.minor form is used, a single lockfile is
- enough. Otherwise, a single lockfile rarely suffices. For example, in
- Linux, it is common to have a /dev/modem symbolic link to an actual
- dialout device, like /dev/cua0 or /dev/ttyS0, whose purpose is to hide
- the details of the actual driver from the user. So if one user opens
- /dev/modem, a lockfile called LCK..modem is created, which does not
- prevent another user from simultaneously opening the same device by its
- real name.
-
- On SCO Unix platforms, we have a slightly different problem: the same
- device is, by convention, known by "lowercase" and "uppercase" names,
- depending on whether it has modem control. So by convention,
- communications programs are supposed to create the lockfiles based on
- the lowercase name. But some programs don't follow this convention. In
- HP-UX, we have several different names for each serial device. And so
- on.
-
- For this reason, on platforms where the LK.inode.major.minor form is
- not used, C-Kermit also creates a secondary lockfile (which is simply a
- link to the first) if:
-
- a. The given device name is a symbolic link. The secondary link is
- based on the device's real name.
- b. On SCO: The device name is not a symbolic link, but it contains
- uppercase letters. The primary link is based on the lowercase name;
- the secondary link is based on the name that was given.
- c. On HP-UX: The device name starts with "cu". The primary link is
- based on the name that was given; the secondary link is based on
- the corresponding "ttyd" device, e.g. "LCK..cua0p0" and
- "LCK..ttyd0p0".
-
- NOTE: symlinks are not handled in HP-UX.
-
- Honey DanBer (HDB) UUCP, the basis of many UUCP implementations, has
- two characteristics:
-
- a. Lockfiles are kept in /usr/spool/locks/ (usually).
- b. A lockfile contains the process id (pid) in ASCII, rather than as
- an int.
-
- Non-HDB selections assume the lockfile contains the pid in int form
- (or, more precisely, in PID_T form, where PID_T is either int or pid_t,
- depending on your system's C library and header files). (b), by the
- way, is subject to interpretation: the numeric ASCII string may or may
- not be terminated by a newline, it may or may not have leading spaces
- (or zeros), and the number of leading spaces or zeros can differ, and
- the differences can be significant.
-
- Even if you build the program with the right lockfile option, you can
- still have problems when you try to open the device. Here are the error
- messages you can get from SET LINE, and what they mean:
-
- a. "Timed out, no carrier." This one is not related to lockfiles. It
- means that you have SET CARRIER ON xx, where xx is the number of
- seconds to wait for carrier, and carrier did not appear within xx
- seconds. Solution: SET CARRIER AUTO or OFF.
- b. "Sorry, access to lock denied." Kermit has been configured to use
- lockfiles, but (a)the lockfile directory is write-protected against
- you, or (b) it does not exist. The "access to lock denied" message
- will tell you the reason. If the directory does not exist, check to
- make sure Kermit is using the right name. Just because version n of
- your Unix used a certain lockfile directory is no guarantee that
- version n.1 does not use a different one. Workaround: ask the
- system administrator to install a symbolic link from the old name
- to the new name. Other solutions: (see below)
- c. "Sorry, access to tty device denied." The tty device that you
- specified in your SET LINE command is read/write protected against
- you. Solution: (see below)
- d. "Sorry, device is in use." The tty device you have specified is
- currently being used by another user. A prefatory message gives you
- an "ls -l" listing of the lockfile, which should show the username
- of the person who created it, plus a message "pid = nnn" to show
- you the process id of the user's program. Solutions: try another
- device, wait until the other user is finished, ask the other user
- to hurry up, or ask the system manager for help.
- e. "Sorry, can't open connection: reason". The device cannot be opened
- for some other reason, which is listed.
- f. "sh: /usr/lib/uucp/acucntrl: not found". This means your Kermit
- program was built with the -DACUCNTRL switch, but your computer
- system does not have the BSD 4.3 acucntrl program. Solution:
- install the acucntrl program if you have it, or rebuild Kermit
- without the -DACUCNTRL switch.
-
- There are two solutions for problems (b) and (c), both of which involve
- intervention by your Unix system administrator (superuser):
-
- a. Have the superuser change the permission of the lockfile directory
- and to the tty devices so that everyone on the system has
- read/write permission.
-
-su% chmod 777 /usr/spool/locks (or whatever the path is)
-su% chmod 666 /dev/ttyXX
-
- One risk here is that people can write lots of junk into the
- lockfile directory, delete other people's files in the lockfile
- directory, and intercept other people's data as it goes in and out
- of the tty device. The major danger here would be intercepting a
- privileged password. Of course, any user could write a short,
- ordinary, unprivileged program to do exactly the same thing if the
- tty device was world read/writeable. The other risk as that
- telephone calls are not controlled -- anybody on your system can
- make them, without having to belong to any particular group, and
- this could run up your phone bill.
- b. Use groups to regulate access. Normally the lockfile directory and
- and the dialout devices will have the same group (such as uucp). If
- so, then put everybody who's allowed to dial out into that group,
- and make sure that the lockfile directory and the tty devices have
- group read AND write permission. Example:
-
-su% chmod 770 /usr/spool/locks (or whatever the path is)
-su% chmod 660 /dev/ttyXX
-
- User whatever tool is available on your platform to add users to
- the appropriate group (e.g. edit the /etc/group file).
- c. Have the superuser change Kermit to run setuid and/or setgid to the
- owner and/or group of the lockfile directory and the tty devices if
- necessary), typically uucp (see [334]next section), but NOT root.
- Example:
-
-su% chown uucp kermit - or - chgrp uucp kermit
-su% chmod u+s kermit (setuid) - or - chmod g+s kermit (setgid)
-
- and then make sure the lockfile directory, and the tty devices,
- have owner (setuid) and/or group (setgid) write permission. For
- example:
-
-su% chmod o+rwx /usr/spool/uucp
-su% chown uucp /dev/ttyXX ; chmod 600 /dev/ttyXX
-
- In some cases, the owner and group must be distinct; the key point
- is that read/write access is required to both the UUCP lockfile
- directory and the tty itself.
-
- If you make C-Kermit setuid or setgid to root, it refuses to run:
-
-Fatal: C-Kermit setuid to root!
-
- Example:
-
-crw-r----- 1 uucp uucp 5, 67 Feb 11 06:23 /dev/cua3
-drwxrwxr-x 3 root uucp 1024 Feb 11 06:22 /var/lock
-
- requires suid uucp to get read/write access on /dev/cua3 and sgid to
- get read/write access on /var/lock (since you can't set Kermit's uid or
- gid to root).
-
- The reason Kermit can't be setuid or setgid to root has to do with
- the fact that some Unix OS's can't switch user or group IDs in that
- case. Unfortunately, the prohibition against making Kermit setuid or
- setgid to root means that Unix C-Kermit can't be used to make rlogin
- connections by non-root users. (The rlogin port is privileged, which
- is why the regular rlogin command is setuid root -- which is safe
- because the rlogin program never has to create or access files like
- Kermit does.)
-
- For the lockfile mechanism to achieve its desired purpose -- prevention
- of access to the same tty device by more than one process at a time --
- ALL programs on a given computer that open, read or write, and close
- tty devices must use the SAME lockfile conventions. Unfortunately, this
- is often not the case. Here is a typical example of how this can go
- wrong: In SunOS 4.0 and earler, the lockfile directory was
- /usr/spool/uucp; in 4.1 it was changed to /var/spool/locks in the quest
- for political correctness. Consequently, any third-party programs (such
- as C-Kermit) that were not modified to account for this change,
- recompiled, and reinstalled, did not use the same lockfiles as uucp,
- tip, etc, and so the entire purpose of the lockfile is defeated.
-
- What if your Unix system does not have UUCP installed? For example, you
- have a Unix workstation, and you do not use uucp, cu, or tip, or UUCP
- was not even supplied with your version of Unix (QNX is an example). In
- this case, you have two choices:
-
- a. If there may be more than one person running Kermit at the same
- time, competing for the same tty device, then create a special
- lockfile directory just for Kermit, for example, /usr/spool/kermit,
- and make sure you have read/write access to it. Then add the
- following to your makefile target CFLAGS, as shown earlier:
-
--DLOCK_DIR=\\\"/usr/spool/kermit\\\"
-
- b. If you are the only user on your workstation, and no other
- processes will ever be competing with Kermit for the dialout tty
- device, then add -DNOUUCP to your makefile target's CFLAGS and
- rebuild Kermit.
-
-11. RUNNING UNIX C-KERMIT SETUID OR SETGID
-
- [ [335]Top ] [ [336]Contents ] [ [337]Next ] [ [338]Previous ]
-
- Even if you don't intend to run C-Kermit setuid, somebody else might
- come along and chown and chmod it after it has been built. You should
- be sure that it is built correctly to run setuid on your system. For
- POSIX and AT&T Unix based versions, you don't have to do anything
- special.
-
- For 4.2 and 4.3 BSD-based Unix versions, you normally need not add
- anything special to the makefile. The program assumes that the
- setreuid() and setregid() functions are available, without which we
- cannot switch back and forth between real and effective uids. If "make"
- complains that _setreuid or _setregid is/are not defined, add
- -DNOSETREU to CFLAGS. In this case it is very likely (but not certain)
- that you cannot protect ttys and lockfiles against people and have them
- run Kermit setuid.
-
- If make does not complain about this, you should find out whether your
- BSD version (4.3 or other systems like SunOS 4.x that claim to include
- BSD 4.3 compatibility) includes the saved-setuid feature (see long
- notes under edit 146 in ckc178.upd). If it does, then add -DSAVEDUID to
- CFLAGS.
-
- IMPORTANT NOTE: Most Unix system documentation will not give you the
- required information. To determine whether your Unix system supplies
- the saved-original-effective-user/group-id feature, use the ckuuid.c
- program. Read and follow the instructions in the comments at the
- beginning.
-
- C-Kermit for 4.4BSD-based systems automatically use sete[ug]id(). See
- [339]ckutio.c.
-
- If you have a version of Unix that is not BSD-based, but which supplies
- the setreuid() and setregid() functions, and these are the only way to
- switch between real and effective uid, add -DSETREUID to your makefile
- target.
-
- WARNING: There are two calls to access() in [340]ckufio.c, by which
- Kermit checks to see if it can create an output file. These calls
- will not work correctly when (a)you have installed C-Kermit setuid
- or setgid on a BSD-based Unix system, and (b) the
- saved-original-effective-uid/gid feature is not present, and (c) the
- access() function always checks what it believes to be the real ID
- rather than the effective ID. This is the case, for example, in
- Olivetti X/OS and in NeXTSTEP. In such cases, you can force correct
- operation of access() calls by defining the symbol SW_ACC_ID at
- compile time in CFLAGS.
-
- If you have a version of Unix that does not allow a process to switch
- back and forth between its effective and real user and group ids
- multiple times, you probably should not attempt to run Kermit setuid,
- because once having given up its effective uid or gid (which it must do
- in order to transfer files, fork a shell, etc) it can never get it
- back, and so it can not use the original effective uid or gid to create
- or delete uucp lockfiles. In this case, you'll either have to set the
- permissions on your lockfile directory to make them publicly
- read/writable, or dispense with locking altogether.
-
- MORAL: Are you thoroughly sickened and/or frightened by all that you
- have just read? You should be. What is the real answer? Simple. Serial
- devices -- such as ttys and magnetic tapes -- in Unix should be opened
- with exclusive access only, enforced by the Unix kernel. Shared access
- has no conceivable purpose, legitimate or otherwise, except by
- privileged system programs such as getty. The original design dates
- from the late 1960s, when Unix was developed for laboratory use under a
- philosophy of trust by people within shouting distance of each other --
- but even then, no useful purpose was served by this particular form of
- openness; it was probably more of a political statement. Since the
- emergence of Unix from the laboratory into the commercial market, we
- have seen every vestige of openness -- but this one -- stripped away.
- I'd like to see some influential Unix maker take the bold step of
- making the simple kernel change required to enforce exclusive access to
- serial devices. (Well, perhaps not so simple when bidirectionality must
- also be a goal -- but then other OS's like VMS solved this problem
- decades ago.)
-
-12. CONFIGURING UNIX WORKSTATIONS
-
- [ [341]Top ] [ [342]Contents ] [ [343]Next ] [ [344]Previous ]
-
- On desktop workstations that are used by only the user at the console
- keyboard, C-Kermit is always used in local mode. But as delivered,
- C-Kermit runs in remote mode by default. To put it in local mode at
- startup, you can put a SET LINE command in your .mykermrc.
-
- You can also build C-Kermit to start up in local mode by default. To do
- this, include the following in the CFLAGS in your makefile target:
-
--DDFTTY=\\\"/dev/ttyxx\\\"
-
- where ttyxx is the name of the device you will be using for
- communications. Presently there is no way of setting the default modem
- type at compile time, so use this option only for direct lines.
-
- C-Kermit does not work well on certain workstations if it is not run
- from within a terminal window. For example, you cannot start C-Kermit
- on a NeXT by launching it directly from NeXTstep. Similarly for Sun
- workstations in the Open Windows environment. Run Kermit in a terminal
- window.
-
-13. BIZARRE BEHAVIOR AT RUNTIME
-
- [ [345]Top ] [ [346]Contents ] [ [347]Next ] [ [348]Previous ]
-
- See the "beware file",
-
- [349]ckubwr.txt, for hints about runtime misbehavior. This section
- lists some runtime problems that can be cured by rebuilding C-Kermit.
-
- The program starts, but there is no prompt, and certain operations
- don't work (you see error messages like "Kermit command error in
- background execution"). This is because Kermit thinks it is running in
- the background. See conbgt() in [350]ckutio.c. Try rebuilding Kermit
- with:
-
- -DPID_T=pid_t
-
- added to your CFLAGS. If that doesn't help, find out the actual data
- type for pids (look in types.h or similar file) and use it in place of
- "pid_t", for example:
-
- -DPID_T=short
-
- Unexplainable and inappropriate error messages ("Sockets not supported
- on this device", etc) have been traced in at least one case to a lack
- of agreement between the system header files and the actual kernel.
- This happened because the GNU C compiler (gcc) was being used. gcc
- wants to have ANSI-C-compliant header files, and so part of the
- installation procedure for gcc is (or was) to run a shell script called
- "fixincludes", which translates the system's header files into a
- separate set of headers that gcc likes. So far so good. Later, a new
- version of the operating system is installed and nobody remembers to
- run fixincludes again. From that point, any program compiled with gcc
- that makes use of header files (particularly ioctl.h) is very likely to
- misbehave. Solution: run fixincludes again, or use your system's
- regular C compiler, libraries, and header files instead of gcc.
-
-14. CRASHES AND CORE DUMPS
-
- [ [351]Top ] [ [352]Contents ] [ [353]Next ] [ [354]Previous ]
-
- If C-Kermit consistently dumps core at the beginning of a file
- transfer, look in SHOW FEATURES for CKREALPATH. If found, rebuild with
- -DNOREALPATH and see if that fixes the problem (some UNIXes have
- realpath() but it doesn't work).
-
- Total failure of the Kermit program can occur because of bad memory
- references, bad system calls, or problems with dynamic memory
- allocation. First, try to reproduce the problem with debugging turned
- on: run Kermit with the -d command-line option (for example, "wermit
- -d") and then examine the resulting debug.log file. The last entry
- should be in the vicinity of the crash. In VMS, a crash automatically
- produces a "stack dump" which shows the routine where the crash occurs.
- In some versions of Unix, you can get a stack dump with "adb" -- just
- type "adb wermit core" and then give the command "$c", then Ctrl-D to
- quit (note: replace "wermit" by "kermit" or by the full pathname of the
- executable that crashed if it is not in the current directory). Or use
- gdb to get a backtrace, etc.
-
- In edit 186, one implementation, UNISYS 5000/95 built with "make
- sys5r3", has been reported to run out of memory very quickly (e.g.
- while executing a short initialization file that contains a SET DIAL
- DIRECTORY command). Debug logs show that malloc calls are failing,
- reason unknown. For this and any other implementation that gives error
- messages about "malloc failure" or "memory allocation failure", rebuild
- the program *without* the -DDYNAMIC CFLAGS definition, for example:
-
-make sys5r3 KFLAGS=-UDYNAMIC
-
- As of edit 169, C-Kermit includes a malloc() debugging package which
- you may link with the Kermit program to catch runtime malloc errors.
- See the makefile entries for sunos41md and nextmd for examples of how
- to select malloc debugging. Once you have linked Kermit with the malloc
- debugger, it will halt with an informative message if a malloc-related
- error occurs and, if possible, dump core. For this reason,
- malloc-debugging versions of Kermit should be built without the "-s"
- link option (which removes symbols, preventing analysis of the core
- dump). You have several ways to track down the malloc error: Analyze
- the core dump with adb. Or reproduce the problem with "log debug" and
- then look at the code around the last debug.log entry. If you have gcc,
- build the program with "-g" added to CFLAGS and then debug it with gdb,
- e.g.
-
-gdb wermit
-break main
-run
-.. set other breakpoints or watchpoints
-continue
-
- Watchpoints are especially useful for finding memory leaks, but they
- make the program run about a thousand times slower than usual, so don't
- set them until the last possible moment. When a watchpoint is hit, you
- can use the "where" command to find out which C-Kermit source statement
- triggered it.
-
- If you have the Pure Software Inc "Purify" product, see the sunos41cp
- makefile entry for an example of how to use it to debug C-Kermit.
-
-15. SYSLOGGING
-
- [ [355]Top ] [ [356]Contents ] [ [357]Next ] [ [358]Previous ]
-
- "Syslogging" means recording selected information in the system log via
- the Unix syslog() facility, which is available in most Unix versions.
- Syslogging is not done unless C-Kermit is started with:
-
---syslog:n
-
- on the command-line, where n is a number greater than 0 to indicate the
- level of syslogging. See [359]Section 4.2 of the [360]IKSD
- Administrator's Guide for details.
-
- Obviously you can't depend on users to include --syslog:3 (or whatever)
- on the command line every time they start C-Kermit, so if you want
- certain kinds of records to be recorded in the system log, you can
- build C-Kermit with forced syslogging at the desired level; for
- example, to record logins and dialouts:
-
-make linux KFLAGS=-DSYSLOGLEVEL=2
-
- Levels 2 and 3 are the most likely candidates for this treatment. Level
- 2 forces logging of all successful dialout calls (e.g. for checking
- against or phone bills), and level 3 records all connections (SET LINE
- or SET HOST / TELNET / RLOGIN, etc) so you can see who is connecting
- out from your system, and to where, e.g. for security auditing.
-
- Level 2 and 3 records are equivalent to those in the connection log;
- see the [361]C-Kermit 7.0 Supplement) for a detailed description of the
- connection log.
-
-16. BUILDING SECURE VERSIONS OF C-KERMIT 8.0
-
- [ [362]Top ] [ [363]Contents ] [ [364]Next ] [ [365]Previous ]
-
- C-Kermit 7.0 and later may be built with Kerberos(TM) and/or SRP(TM)
- (Secure Remote Password) and/or SSL/TLS security for strong
- authentication and encryption of Internet connections. These security
- methods require external libraries that, in their binary forms, are
- restricted from export by USA law. See the [366]Kermit Security
- Reference) for details. C-Kermit binaries themselves are likewise
- restricted; the C-Kermit binaries that are available for public
- download on the Internet are not allowed to contain the security
- options.
-
- Sample makefile entries are provided for Linux and many other operating
- systems. A list of secure makefile entries is included in the Makefile.
- Complete instructions on building C-Kermit 8.0 with MIT Kerberos;
- Secure Remote Password; and/or OpenSSL can be found in the [367]Kermit
- Security Reference.
-
- SSL/TLS and Kerberos builds are increasingly problematic with the
- "deprecation" of DES. There is code to detect the presence or absence
- of DES in the OpenSSL builds, but it doesn't always work because
- sometimes the SSL libraries are present but routines are missing from
- them.
-
- * First of all remember that if your SSL and/or Kerberos header files
- and libraries are not in the default place, you'll need to override
- the assumed paths. To find out what the default places are type
- "make show", e.g.:
-
-[~/kermit] make show
-prefix=/usr/local
-srproot=/usr/local
-sslroot=/usr/local
-manroot=/usr/local
-K4LIB=-L/usr/kerberos/lib
-K4INC=-I/usr/kerberos/include
-K5LIB=-L/usr/kerberos/lib
-K5INC=-I/usr/kerberos/include
-SRPLIB=-L/usr/local/lib
-SRPINC=-I/usr/local/include
-SSLLIB=-L/usr/local/ssl/lib
-SSLINC=-I/usr/local/ssl/include
-[~/kermit]
-
- * You can override any or all of these by putting assignments on the
- 'make' command line; examples:
-
-make linux+krb5 \
- "K5INC=-I/usr/include/" \
- "K5LIB=-L/usr/lib64/"
-
-make solaris9g+ssl \
- "SSLLIB=-L/opt/openssl-0.9.8q/lib" \
- "SSLINC=-I/opt/openssl-0.9.8q/include"
-
- Or by setting and exporting environment variables prior to giving
- the 'make' command, as in this example in which (after Beta.01 was
- uploaded) C-Kermit was successfully linked with OpenSSL 1.0.0d,
- which was installed alongside OpenSSL 0.9.8r on the same computer.
- Note the use of the '-i' option instead of '-I' to force gcc to
- include the right header files (thanks to Nelson Beebe for this):
-
-export PATH=/usr/bin:$PATH
-export SSLINC=-isystem/usr/include
-export "SSLLIB=-L/usr/lib -Wl,-rpath,/usr/lib"
-make linux+ssl
-
- -i is explained in 'man gcc'; there is a change in what -I does
- that could have ramifications for many makefile targets, not just
- Kermit. And -Wl and -rpath are explained in 'man ld'; the idea is
- build a binary from which useful reports can be obtained with ldd.
- * Building with OpenSSL versions prior to 0.9.7 doesn't work, even
- though C-Kermit is designed to work with both the old and new
- versions. This could probably be fixed if anybody cares.
- * If a Kerberos or SSL build fails at link time because
- des_ecb3_encrypt, des_random_seed, and/or des_set_odd_parity come
- up missing, redo the build with -UCK_DES:
-
-make netbsd+krb5+ssl \
- "K5INC=-I/usr/local/include" \
- "K5LIB=-L/usr/local/kerblib" KFLAGS=-UCK_DES
-
- I suppose all the SSL and Kerberos targets could be recoded to
- figure this out automatically (i.e. that DES is installed but with
- some entry points missing), but it wouldn't be pretty.
- * Different Kerberos and OpenSSL distributions can be installed with
- different options; certain libraries might be missing or named
- differently (for example, libgssapi vs libgssapi_krb5). Some, but
- not all, of the C-Kermit makefile targets have been fixed to take
- some of these variations into account by testing for them, most
- notably the linux ones, linux+ssl, linux+krb5, and linux+krb5+ssl.
- Probably every target that builds with OpenSSL or Kerberos needs
- the same treatment but I won't have time.
- * Why doesn't C-Kermit just use Autoconf? Mainly because the makefile
- is full of targets for platforms that don't have Autoconf or any
- other tool like it. (Another reason is that I've always preferred
- that Kermit have the least dependencies possible on external
- toolsets.) Perhaps certain targets could be converted to use them,
- especially Linux because there are so many variations among
- distributions and versions. Anybody who wants to make, say, an
- Autoconf-based Linux target, be my guest, but bear in mind that one
- Linux target is supposed to work for all versions and distributions
- of Linux on all platforms. Well, one target for Linux by itself,
- another for Linux with OpenSSL, another for Linux with Kerberos 5,
- and another for Linux with Kerberos 5 and OpenSSL. Each of these is
- supposed to work on any Linux version with any version of
- Kerberos 5 or OpenSSL.
-
- Also note that Kerberos support is for the MIT version only, Heimdal
- and others are not supported (never have been). Of course anybody can
- pitch in and add or improve support for whatever they want.
-
-17. INSTALLING C-KERMIT AS AN SSH SERVER SUBSYSTEM
-
- [ [368]Top ] [ [369]Contents ] [ [370]Previous ]
-
- This requires C-Kermit 8.0.206 or later and an SSH v2 server. If you
- list C-Kermit as a Subsystem in the SSH v2 server configuration file
- (as, for example, SFTP is listed), users can make SSH connections
- direct to a Kermit server as explained here:
-
-[371]http://www.columbia.edu/kermit/skermit.html
-
- The name and location of the SSH server configuration file depends on
- your platform, which SSH product(s) you have, etc. C-Kermit itself must
- be referred to in this file as "kermit-sshsub". On the host, install
- the C-Kermit 8.0.211 binary in the normal way. Then, in the same
- directory as the C-Kermit binary, make a symbolic link:
-
-ln -s kermit kermit-sshsub
-
- (Note: the "make install" makefile target does this for you.) Then in
- the sshd configuration file, add a line:
-
-Subsystem kermit /some/path/kermit-sshsub
-
- (where /some/path is the fully specified directory where the symlink
- is.) This is similar to the line that sets up the SFTP subsystem.
- Example:
-
-Subsystem sftp /usr/local/libexec/sftp-server
-Subsystem kermit /usr/local/bin/kermit-sshsub
-
- The mechanics might vary for other SSH servers; "man sshd" for details.
- The method shown here is used because the OpenSSH server does not
- permit the subsystem invocation to include command-line options.
- C-Kermit would have no way of knowing that it should enter Server mode
- if it were not called by a special name.
-
- [ [372]Top ] [ [373]Contents ] [ [374]C-Kermit Home ] [ [375]C-Kermit
- 9.0 Overview ] [ [376]Kermit Home ]
- __________________________________________________________________
-
-
- C-Kermit 9.0 Unix Installation Instructions / The Kermit Project /
- Columbia University / 30 June 2011
-
-References
-
- 1. http://www.columbia.edu/
- 2. mailto:kermit@columbia.edu
- 3. http://www.columbia.edu/kermit/index.html
- 4. http://www.columbia.edu/kermit/k95.html
- 5. http://www.columbia.edu/kermit/ckermit.html
- 6. http://www.columbia.edu/kermit/ckscripts.html
- 7. http://www.columbia.edu/kermit/current.html
- 8. http://www.columbia.edu/kermit/whatsnew.html
- 9. http://www.columbia.edu/kermit/faq.html
- 10. http://www.columbia.edu/kermit/support.html
- 11. http://www.columbia.edu/kermit/ckuins.html#contents
- 12. http://www.columbia.edu/kermit/ckermit.html
- 13. http://www.columbia.edu/kermit/index.html
- 14. http://www.columbia.edu/kermit/ckuins.html
- 15. http://www.columbia.edu/kermit/ckuins.html#x0
- 16. http://www.columbia.edu/kermit/ckuins.html#x1
- 17. http://www.columbia.edu/kermit/ckuins.html#x2
- 18. http://www.columbia.edu/kermit/ckuins.html#x3
- 19. http://www.columbia.edu/kermit/ckuins.html#x4
- 20. http://www.columbia.edu/kermit/ckuins.html#x5
- 21. http://www.columbia.edu/kermit/ckuins.html#x6
- 22. http://www.columbia.edu/kermit/ckuins.html#x7
- 23. http://www.columbia.edu/kermit/ckuins.html#x8
- 24. http://www.columbia.edu/kermit/ckuins.html#x9
- 25. http://www.columbia.edu/kermit/ckuins.html#x10
- 26. http://www.columbia.edu/kermit/ckuins.html#x11
- 27. http://www.columbia.edu/kermit/ckuins.html#x12
- 28. http://www.columbia.edu/kermit/ckuins.html#x13
- 29. http://www.columbia.edu/kermit/ckuins.html#x14
- 30. http://www.columbia.edu/kermit/ckuins.html#x15
- 31. http://www.columbia.edu/kermit/ckuins.html#x16
- 32. http://www.columbia.edu/kermit/ckuins.html#x17
- 33. http://www.columbia.edu/kermit/ckuins.html#top
- 34. http://www.columbia.edu/kermit/ckuins.html#contents
- 35. http://www.columbia.edu/kermit/ckuins.html#x1
- 36. http://www.columbia.edu/kermit/ckccfg.html
- 37. http://www.columbia.edu/kermit/ckcbwr.html
- 38. http://www.columbia.edu/kermit/ckubwr.html
- 39. http://www.columbia.edu/kermit/ckcplm.html
- 40. http://www.columbia.edu/kermit/ckuins.html#x2
- 41. http://www.columbia.edu/kermit/ckuins.html#x3
- 42. http://www.columbia.edu/kermit/ckuins.html#x4
- 43. http://www.columbia.edu/kermit/ckuins.html#top
- 44. http://www.columbia.edu/kermit/ckuins.html#contents
- 45. http://www.columbia.edu/kermit/ckuins.html#x2
- 46. http://www.columbia.edu/kermit/ckuins.html#x0
- 47. ftp://www.columbia.edu/kermit/archives/cku211.tar.Z
- 48. ftp://www.columbia.edu/kermit/archives/cku211.tar.gz
- 49. http://kermit.columbia.edu/ftp/archives/cku211.tar.Z
- 50. http://kermit.columbia.edu/ftp/archives/cku211.tar.gz
- 51. ftp://www.columbia.edu/kermit/archives/cku211.tar
- 52. http://kermit.columbia.edu/ftp/archives/cku211.tar
- 53. http://www.columbia.edu/kermit/ckuins.html#x7
- 54. http://www.columbia.edu/kermit/ckuins.html#x5
- 55. http://www.columbia.edu/kermit/ckuins.html#x5
- 56. http://www.columbia.edu/kermit/ckuins.html#x16
- 57. http://www.columbia.edu/kermit/ckuins.html#top
- 58. http://www.columbia.edu/kermit/ckuins.html#contents
- 59. http://www.columbia.edu/kermit/ckuins.html#x3
- 60. http://www.columbia.edu/kermit/ckuins.html#x1
- 61. http://www.columbia.edu/kermit/ckuins.html#x5
- 62. http://www.columbia.edu/kermit/ckuins.html#X10
- 63. http://www.columbia.edu/kermit/ckuins.html#x11
- 64. http://www.columbia.edu/kermit/ckuins.html#x10
- 65. http://www.columbia.edu/kermit/ckuins.html#x3
- 66. http://www.columbia.edu/kermit/ck80packages.html
- 67. http://www.columbia.edu/kermit/ckuins.html#x10
- 68. http://www.columbia.edu/kermit/ckuins.html#top
- 69. http://www.columbia.edu/kermit/ckuins.html#contents
- 70. http://www.columbia.edu/kermit/ckuins.html#x4
- 71. http://www.columbia.edu/kermit/ckuins.html#x2
- 72. ftp://www.columbia.edu/kermit/bin/
- 73. http://www.columbia.edu/kermit/ck80binaries.html
- 74. http://www.columbia.edu/kermit/ckuins.html#x7
- 75. http://www.columbia.edu/kermit/ckuins.html#build
- 76. http://www.columbia.edu/kermit/ckuins.html#x5
- 77. http://www.columbia.edu/kermit/ckuins.html#x4
- 78. http://www.columbia.edu/kermit/ckfaq.html#version
- 79. http://www.columbia.edu/kermit/ckuins.html#x4
- 80. mailto:kermit@columbia.edu
- 81. http://www.columbia.edu/kermit/ckuins.html#top
- 82. http://www.columbia.edu/kermit/ckuins.html#contents
- 83. http://www.columbia.edu/kermit/ckuins.html#x5
- 84. http://www.columbia.edu/kermit/ckuins.html#x3
- 85. http://www.columbia.edu/kermit/ckuins.html#x8
- 86. http://www.columbia.edu/kermit/ckuins.html#x9
- 87. ftp://kermit.columbia.edu/kermit/c-kermit/makefile
- 88. ftp://kermit.columbia.edu/kermit/c-kermit/ckpker.mk
- 89. ftp://kermit.columbia.edu/kermit/c-kermit/ckubsd.mak
- 90. http://www.columbia.edu/kermit/ckuins.html#x5
- 91. mailto:kermit-support@columbia.edu
- 92. ftp://kermit.columbia.edu/kermit/c-kermit/makefile
- 93. http://www.columbia.edu/kermit/ckuins.html#x7
- 94. mailto:kermit-support@columbia.edu
- 95. ftp://kermit.columbia.edu/kermit/c-kermit/makefile
- 96. http://www.columbia.edu/kermit/ckuins.html#x5.4
- 97. http://www.columbia.edu/kermit/ckuins.html#x10
- 98. http://www.columbia.edu/kermit/ckuins.html#x11
- 99. http://www.columbia.edu/kermit/ckuins.html#x5
- 100. http://www.columbia.edu/kermit/iksd.html
- 101. http://www.columbia.edu/kermit/ckuins.html#top
- 102. http://www.columbia.edu/kermit/ckuins.html#contents
- 103. http://www.columbia.edu/kermit/ckuins.html#x4.1
- 104. http://www.columbia.edu/kermit/ckccfg.html
- 105. http://www.columbia.edu/kermit/ckuins.html#x4.1
- 106. http://www.columbia.edu/kermit/ckuins.html#x4.2
- 107. http://www.columbia.edu/kermit/ckuins.html#x4.3
- 108. http://www.columbia.edu/kermit/ckuins.html#x4.4
- 109. http://www.columbia.edu/kermit/ckuins.html#x4.5
- 110. http://www.columbia.edu/kermit/ckccfg.html
- 111. http://www.columbia.edu/kermit/ckccfg.html#x8
- 112. http://www.columbia.edu/kermit/iksd.html
- 113. http://www.columbia.edu/kermit/iksd.html
- 114. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 115. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 116. mailto:kermit-support@columbia.edu
- 117. ftp://kermit.columbia.edu/kermit/c-kermit/ckcmai.c
- 118. http://www.columbia.edu/kermit/ckuins.html#x15
- 119. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 120. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 121. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 122. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 123. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.c
- 124. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.c
- 125. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 126. ftp://kermit.columbia.edu/kermit/c-kermit/ckcuni.c
- 127. mailto:kermit-support@columbia.edu
- 128. http://www.columbia.edu/kermit/ckuins.html#top
- 129. http://www.columbia.edu/kermit/ckuins.html#contents
- 130. http://www.columbia.edu/kermit/ckuins.html#x4
- 131. http://www.columbia.edu/kermit/ckuins.html#x4.2
- 132. http://www.columbia.edu/kermit/ckuins.html#x4.0
- 133. ftp://kermit.columbia.edu/kermit/c-kermit/makefile
- 134. ftp://kermit.columbia.edu/kermit/c-kermit/ckubwr.txt
- 135. http://www.columbia.edu/kermit/ckubwr.html
- 136. ftp://kermit.columbia.edu/kermit/c-kermit/ckwart.c
- 137. ftp://kermit.columbia.edu/kermit/c-kermit/ckcpro.w
- 138. ftp://kermit.columbia.edu/kermit/c-kermit/ckcpro.c
- 139. http://www.columbia.edu/kermit/ckuins.html#top
- 140. http://www.columbia.edu/kermit/ckuins.html#contents
- 141. http://www.columbia.edu/kermit/ckuins.html#x4
- 142. http://www.columbia.edu/kermit/ckuins.html#x4.3
- 143. http://www.columbia.edu/kermit/ckuins.html#x4.1
- 144. http://www.columbia.edu/kermit/ckuins.html#x5
- 145. http://www.columbia.edu/kermit/ckuins.html#top
- 146. http://www.columbia.edu/kermit/ckuins.html#contents
- 147. http://www.columbia.edu/kermit/ckuins.html#x4
- 148. http://www.columbia.edu/kermit/ckuins.html#x4.4
- 149. http://www.columbia.edu/kermit/ckuins.html#x4.2
- 150. http://www.columbia.edu/kermit/ckuins.html#top
- 151. http://www.columbia.edu/kermit/ckuins.html#contents
- 152. http://www.columbia.edu/kermit/ckuins.html#x4
- 153. http://www.columbia.edu/kermit/ckuins.html#x4.5
- 154. http://www.columbia.edu/kermit/ckuins.html#x4.3
- 155. ftp://kermit.columbia.edu/kermit/c-kermit/ckpker.mk
- 156. http://www.columbia.edu/kermit/ckuins.html#top
- 157. http://www.columbia.edu/kermit/ckuins.html#contents
- 158. http://www.columbia.edu/kermit/ckuins.html#x4
- 159. http://www.columbia.edu/kermit/ckuins.html#x4.4
- 160. ftp://kermit.columbia.edu/kermit/c-kermit/makefile
- 161. ftp://kermit.columbia.edu/kermit/c-kermit/makefile
- 162. ftp://kermit.columbia.edu/kermit/c-kermit/ckcpro.w
- 163. http://www.columbia.edu/kermit/ckuins.html#top
- 164. http://www.columbia.edu/kermit/ckuins.html#contents
- 165. http://www.columbia.edu/kermit/ckuins.html#x6
- 166. http://www.columbia.edu/kermit/ckuins.html#x4
- 167. http://www.columbia.edu/kermit/ckuins.html#x5.1
- 168. http://www.columbia.edu/kermit/ckuins.html#x5.2
- 169. http://www.columbia.edu/kermit/ckuins.html#x5.3
- 170. http://www.columbia.edu/kermit/ckuins.html#x5.4
- 171. http://www.columbia.edu/kermit/
- 172. http://www.columbia.edu/kermit/ckuins.html#x5.4
- 173. http://www.columbia.edu/kermit/ckuins.html#x5.3
- 174. ftp://kermit.columbia.edu/kermit/c-kermit/COPYING.TXT
- 175. ftp://kermit.columbia.edu/kermit/c-kermit/ckermit.ini
- 176. http://www.columbia.edu/kermit/ckuins.html#x5.1
- 177. ftp://kermit.columbia.edu/kermit/c-kermit/ckermod.ini
- 178. ftp://kermit.columbia.edu/kermit/c-kermit/ckermit70.txt
- 179. http://www.columbia.edu/kermit/ck60manual.html
- 180. http://www.columbia.edu/kermit/ckermit70.html
- 181. ftp://kermit.columbia.edu/kermit/c-kermit/ckermit80.txt
- 182. http://www.columbia.edu/kermit/ck60manual.html
- 183. http://www.columbia.edu/kermit/ckermit80.html
- 184. ftp://kermit.columbia.edu/kermit/c-kermit/ckermit90.txt
- 185. http://www.columbia.edu/kermit/ck60manual.html
- 186. http://www.columbia.edu/kermit/ckermit90.html
- 187. ftp://kermit.columbia.edu/kermit/c-kermit/ckcbwr.txt
- 188. http://www.columbia.edu/kermit/ckcbwr.html
- 189. ftp://kermit.columbia.edu/kermit/c-kermit/ckubwr.txt
- 190. http://www.columbia.edu/kermit/ckubwr.html
- 191. ftp://kermit.columbia.edu/kermit/c-kermit/ckuins.txt
- 192. http://www.columbia.edu/kermit/ckuins.html
- 193. ftp://kermit.columbia.edu/kermit/c-kermit/ckccfg.txt
- 194. http://www.columbia.edu/kermit/ckccfg.html
- 195. ftp://kermit.columbia.edu/kermit/c-kermit/ckcplm.txt
- 196. http://www.columbia.edu/kermit/ckcplm.html
- 197. ftp://kermit.columbia.edu/kermit/c-kermit/ca_certs.pem
- 198. http://www.columbia.edu/kermit/ckuins.html#x16"
- 199. ftp://kermit.columbia.edu/kermit/c-kermit/makefile
- 200. http://www.columbia.edu/kermit/ckuins.html#x?
- 201. http://www.columbia.edu/kermit/ckuins.html#x11
- 202. http://www.columbia.edu/kermit/ckuins.html#x5.2
- 203. http://www.columbia.edu/kermit/ckermit.html#download
- 204. http://www.columbia.edu/kermit/ckbinaries.html
- 205. http://www.columbia.edu/kermit/ckermit.html#download
- 206. http://www.columbia.edu/kermit/ckuins.html#top
- 207. http://www.columbia.edu/kermit/ckuins.html#contents
- 208. http://www.columbia.edu/kermit/ckuins.html#x7
- 209. http://www.columbia.edu/kermit/ckuins.html#x5
- 210. http://www.columbia.edu/kermit/ckuins.html#top
- 211. http://www.columbia.edu/kermit/ckuins.html#contents
- 212. http://www.columbia.edu/kermit/ckuins.html#x8
- 213. http://www.columbia.edu/kermit/ckuins.html#x6
- 214. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 215. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 216. http://www.columbia.edu/kermit/ckuins.html#x4.0
- 217. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h
- 218. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 219. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 220. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 221. http://www.columbia.edu/kermit/ckuins.html#x10
- 222. http://www.columbia.edu/kermit/ckccfg.html#x2
- 223. http://www.columbia.edu/kermit/ckccfg.html
- 224. http://www.columbia.edu/kermit/ckuins.html#x4
- 225. http://www.columbia.edu/kermit/ckuins.html#x10
- 226. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 227. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 228. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 229. http://www.columbia.edu/kermit/ckuins.html#x9.4
- 230. mailto:kermit-support@columbia.edu
- 231. http://www.columbia.edu/kermit/ckuins.html#top
- 232. http://www.columbia.edu/kermit/ckuins.html#contents
- 233. http://www.columbia.edu/kermit/ckuins.html#x9
- 234. http://www.columbia.edu/kermit/ckuins.html#x7
- 235. http://www.columbia.edu/kermit/ckccfg.html
- 236. http://www.columbia.edu/kermit/ckccfg.html
- 237. http://www.columbia.edu/kermit/ckuins.html#top
- 238. http://www.columbia.edu/kermit/ckuins.html#contents
- 239. http://www.columbia.edu/kermit/ckuins.html#x10
- 240. http://www.columbia.edu/kermit/ckuins.html#x8
- 241. http://www.columbia.edu/kermit/ckuins.html#x9.1
- 242. http://www.columbia.edu/kermit/ckuins.html#x9.1.1
- 243. http://www.columbia.edu/kermit/ckuins.html#x9.1.2
- 244. http://www.columbia.edu/kermit/ckuins.html#x9.1.3
- 245. http://www.columbia.edu/kermit/ckuins.html#x9.2
- 246. http://www.columbia.edu/kermit/ckuins.html#x9.3
- 247. http://www.columbia.edu/kermit/ckuins.html#x9.4
- 248. http://www.columbia.edu/kermit/ckuins.html#x9.5
- 249. http://www.columbia.edu/kermit/ckuins.html#x9.6
- 250. http://www.columbia.edu/kermit/ckuins.html#x9.7
- 251. http://www.columbia.edu/kermit/ckuins.html#x9.8
- 252. http://www.columbia.edu/kermit/ckuins.html#x9.9
- 253. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 254. http://www.columbia.edu/kermit/ckuins.html#top
- 255. http://www.columbia.edu/kermit/ckuins.html#x9
- 256. http://www.columbia.edu/kermit/ckuins.html#contents
- 257. http://www.columbia.edu/kermit/ckuins.html#x9.2
- 258. http://www.columbia.edu/kermit/ckuins.html#x9.1.1
- 259. http://www.columbia.edu/kermit/ckuins.html#x9.1.2
- 260. http://www.columbia.edu/kermit/ckuins.html#x9.1.3
- 261. http://www.columbia.edu/kermit/ckuins.html#top
- 262. http://www.columbia.edu/kermit/ckuins.html#contents
- 263. http://www.columbia.edu/kermit/ckuins.html#x9
- 264. http://www.columbia.edu/kermit/ckuins.html#x9.1
- 265. http://www.columbia.edu/kermit/ckuins.html#x9.1.3
- 266. http://www.columbia.edu/kermit/ckuins.html#x9.1.1
- 267. http://www.columbia.edu/kermit/ckuins.html#top
- 268. http://www.columbia.edu/kermit/ckuins.html#contents
- 269. http://www.columbia.edu/kermit/ckuins.html#x9
- 270. http://www.columbia.edu/kermit/ckuins.html#x9.1
- 271. http://www.columbia.edu/kermit/ckuins.html#x9.2
- 272. http://www.columbia.edu/kermit/ckuins.html#x9.1.2
- 273. http://www.opengroup.org/onlinepubs/007904975/
- 274. http://www.columbia.edu/kermit/ckuins.html#x9.1.1
- 275. http://www.columbia.edu/kermit/ckuins.html#top
- 276. http://www.columbia.edu/kermit/ckuins.html#contents
- 277. http://www.columbia.edu/kermit/ckuins.html#x9
- 278. http://www.columbia.edu/kermit/ckuins.html#x9.1
- 279. http://www.columbia.edu/kermit/ckuins.html#x9.3
- 280. http://www.columbia.edu/kermit/ckuins.html#x9.1
- 281. http://www.columbia.edu/kermit/ckuins.html#top
- 282. http://www.columbia.edu/kermit/ckuins.html#contents
- 283. http://www.columbia.edu/kermit/ckuins.html#x9
- 284. http://www.columbia.edu/kermit/ckuins.html#x9.4
- 285. http://www.columbia.edu/kermit/ckuins.html#x9.2
- 286. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 287. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 288. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 289. http://www.columbia.edu/kermit/ckuins.html#top
- 290. http://www.columbia.edu/kermit/ckuins.html#contents
- 291. http://www.columbia.edu/kermit/ckuins.html#x9
- 292. http://www.columbia.edu/kermit/ckuins.html#x9.5
- 293. http://www.columbia.edu/kermit/ckuins.html#x9.3
- 294. http://www.columbia.edu/kermit/cable.html
- 295. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 296. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h
- 297. http://www.columbia.edu/kermit/ckuins.html#top
- 298. http://www.columbia.edu/kermit/ckuins.html#contents
- 299. http://www.columbia.edu/kermit/ckuins.html#x9
- 300. http://www.columbia.edu/kermit/ckuins.html#x9.6
- 301. http://www.columbia.edu/kermit/ckuins.html#x9.4
- 302. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h
- 303. ftp://kermit.columbia.edu/kermit/c-kermit/ckuus3.c
- 304. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 305. http://www.columbia.edu/kermit/ckuins.html#top
- 306. http://www.columbia.edu/kermit/ckuins.html#contents
- 307. http://www.columbia.edu/kermit/ckuins.html#x9
- 308. http://www.columbia.edu/kermit/ckuins.html#x9.7
- 309. http://www.columbia.edu/kermit/ckuins.html#x9.5
- 310. http://www.columbia.edu/kermit/ckuins.html#top
- 311. http://www.columbia.edu/kermit/ckuins.html#contents
- 312. http://www.columbia.edu/kermit/ckuins.html#x9
- 313. http://www.columbia.edu/kermit/ckuins.html#x9.8
- 314. http://www.columbia.edu/kermit/ckuins.html#x9.6
- 315. http://www.columbia.edu/kermit/ckuins.html#top
- 316. http://www.columbia.edu/kermit/ckuins.html#contents
- 317. http://www.columbia.edu/kermit/ckuins.html#x9
- 318. http://www.columbia.edu/kermit/ckuins.html#x9.9
- 319. http://www.columbia.edu/kermit/ckuins.html#x9.7
- 320. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 321. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 322. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h
- 323. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 324. http://www.columbia.edu/kermit/ckuins.html#top
- 325. http://www.columbia.edu/kermit/ckuins.html#contents
- 326. http://www.columbia.edu/kermit/ckuins.html#x9
- 327. http://www.columbia.edu/kermit/ckuins.html#x10
- 328. http://www.columbia.edu/kermit/ckuins.html#x9.8
- 329. http://www.columbia.edu/kermit/ckuins.html#top
- 330. http://www.columbia.edu/kermit/ckuins.html#contents
- 331. http://www.columbia.edu/kermit/ckuins.html#x11
- 332. http://www.columbia.edu/kermit/ckuins.html#x9
- 333. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 334. http://www.columbia.edu/kermit/ckuins.html#x11
- 335. http://www.columbia.edu/kermit/ckuins.html#top
- 336. http://www.columbia.edu/kermit/ckuins.html#contents
- 337. http://www.columbia.edu/kermit/ckuins.html#x12
- 338. http://www.columbia.edu/kermit/ckuins.html#x10
- 339. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 340. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c
- 341. http://www.columbia.edu/kermit/ckuins.html#top
- 342. http://www.columbia.edu/kermit/ckuins.html#contents
- 343. http://www.columbia.edu/kermit/ckuins.html#x13
- 344. http://www.columbia.edu/kermit/ckuins.html#x11
- 345. http://www.columbia.edu/kermit/ckuins.html#top
- 346. http://www.columbia.edu/kermit/ckuins.html#contents
- 347. http://www.columbia.edu/kermit/ckuins.html#x14
- 348. http://www.columbia.edu/kermit/ckuins.html#x12
- 349. ftp://kermit.columbia.edu/kermit/c-kermit/ckubwr.txt
- 350. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c
- 351. http://www.columbia.edu/kermit/ckuins.html#top
- 352. http://www.columbia.edu/kermit/ckuins.html#contents
- 353. http://www.columbia.edu/kermit/ckuins.html#x15
- 354. http://www.columbia.edu/kermit/ckuins.html#x13
- 355. http://www.columbia.edu/kermit/ckuins.html#top
- 356. http://www.columbia.edu/kermit/ckuins.html#contents
- 357. http://www.columbia.edu/kermit/ckuins.html#x16
- 358. http://www.columbia.edu/kermit/ckuins.html#x14
- 359. http://www.columbia.edu/kermit/uiksd.html#x4.2
- 360. http://www.columbia.edu/kermit/uiksd.html
- 361. http://www.columbia.edu/kermit/ckermit2.html
- 362. http://www.columbia.edu/kermit/ckuins.html#top
- 363. http://www.columbia.edu/kermit/ckuins.html#contents
- 364. http://www.columbia.edu/kermit/ckuins.html#x17
- 365. http://www.columbia.edu/kermit/ckuins.html#x15
- 366. http://www.columbia.edu/kermit/security.html
- 367. http://www.columbia.edu/kermit/security80.html
- 368. http://www.columbia.edu/kermit/ckuins.html#top
- 369. http://www.columbia.edu/kermit/ckuins.html#contents
- 370. http://www.columbia.edu/kermit/ckuins.html#x16
- 371. http://www.columbia.edu/kermit/skermit.html
- 372. http://www.columbia.edu/kermit/ckuins.html#top
- 373. http://www.columbia.edu/kermit/ckuins.html#contents
- 374. http://www.columbia.edu/kermit/ckermit.html
- 375. http://www.columbia.edu/kermit/ck90updates.html
- 376. http://www.columbia.edu/kermit/index.html
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuker.nr b/ckermit-9.0.302-build/ckermit-9.0.302/ckuker.nr
deleted file mode 100644
index 03b30e7..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuker.nr
+++ /dev/null
@@ -1,1831 +0,0 @@
-.\" @(#) kermit.1 9.0.302 2011/08/20 Columbia University
-.TH KERMIT 1 "JULY 2011" "User Manuals"
-.na
-.SH NAME
-kermit \-
-.B C\(hyKermit 9.0:
-transport\(hy and platform\(hyindependent
-interactive and scriptable communications software.
-.IP
-
-This document is intended to give the beginner sufficient information to
-make basic (if not advanced) use of C\(hyKermit 9.0. Although it might be
-rather long for a Unix manual page, it's still far shorter than the
-C\(hyKermit manual, which should be consulted for advanced topics such as
-customization, character\(hysets, scripting, etc. We also attempt to provide
-a clear structural overview of C\(hyKermit's many capabilities, functional
-areas, states, and modes and their interrelation, that should be helpful to
-beginners and veterans alike, as well as to those upgrading to version 9.0
-from earlier releases.
-.PP
-This document is also available as a Web page at:
-.IP
-http://www.columbia.edu/kermit/ckututor.html
-.SH DESCRIPTION
-C\(hyKermit is an all\(hypurpose communications software package from the Kermit
-Project at Columbia University that:
-.PP
-.nf
-\(bu Is portable to many platforms, Unix and non\(hyUnix alike.
-.br
-\(bu Can make both serial and network connections.
-.br
-\(bu Can conduct interactive terminal sessions over its connection.
-.br
-\(bu Can transfer text or binary files over the same connection.
-.br
-\(bu Can convert character sets in the terminal session.
-.br
-\(bu Can convert character sets during text\(hyfile file transfer.
-.br
-\(bu Is customizable in every aspect of its operation.
-.fi
-.PP
-C\(hyKermit is a modem program, a Telnet client, an Rlogin client, an FTP
-client, an HTTP client, and on selected platforms, also an X.25 client. It
-can make its own secure Internet connections using IETF\(hyapproved security
-methods including Kerberos IV, Kerberos V, SSL/TLS, and SRP and it can also
-make SSH connections through your external SSH client application. It can
-be the far\(hyend file\(hytransfer or client/server partner of your desktop
-Kermit client. It can also accept incoming dialed and network connections.
-It can even be installed as an Internet service on its own standard TCP
-socket, 1649 [RFC2839, RFC2840].
-.PP
-And perhaps most important, everything you can do "by hand" (interactively)
-with C\(hyKermit, can be "scripted" (automated) using its built\(hyin
-cross\(hyplatform transport\(hyindependent script programming language, which
-happens to be identical to its interactive command language.
-.PP
-This manual page offers an overview of C\(hyKermit 9.0 for Unix ("Unix" is an
-operating system family that includes AIX, DG/UX, FreeBSD, HP\(hyUX, IRIX,
-Linux, Mac OS X, NetBSD, OpenBSD, Open Server, Open Unix, QNX, Solaris,
-SunOS, System V R3, System V R4, Tru64 Unix, Unixware, Xenix, and many
-others). For thorough coverage, please consult the published C\(hyKermit
-manual and supplements (see DOCUMENTATION below). For further information
-about C\(hyKermit, Kermit software for other platforms, and Kermit manuals,
-visit the Kermit Project website:
-.PP
- http://www.columbia.edu/kermit/
-.PP
-This is a longer\(hythan\(hyaverage manual page, and yet it barely scratches the
-surface. Don't be daunted. C\(hyKermit is a large and complex package,
-evolving over decades of practice and experience, but that doesn't mean
-it's hard to learn or use. Its most commonly used functions are explained
-here with pointers to additional information elsewhere.
-.SH SYNOPSIS
-.B kermit [
-.I filename
-.B ] [
-.I options
-.B ] [ {=,\-\-,+}
-.I text
-.B ] ]
-.PP
-or:
-.PP
-.B kermit
-.I URL
-.PP
-If the first command\(hyline argument is the name of a file, interactive\(hymode
-commands are executed from the file. The '=' (or "\-\-") argument tells
-Kermit not to parse the remainder of the command line, but to make the
-words following '=' available as \e%1, \e%2, ... \e%9. The "+" argument is
-like "=" but for use in "kerbang scripts" (explained below). A second
-command\(hyline format allows the one and only argument to be a Telnet, FTP,
-HTTP, or IKSD URL.
-.PP
-Order of execution:
-.TP
- 1.
-The command file (if any).
-.TP
-.nf
- 2.
-The initialization file, if any, unless suppressed with \-Y.
-.fi
-.TP
- 3.
-The customization file (if it is executed by the initialization file).
-.TP
- 4.
-The command\(hyline URL (if any, and if so, execution stops here).
-.TP
- 5.
-Command\(hyline options (if any).
-.TP
- 6.
-Interactive commands.
-.PP
-Some command\(hyline options can cause actions (such as \-s to send a file);
-others just set parameters. If any action options are included on the
-command line, Kermit exits when finished unless also given the \-S ("stay")
-option. If no action options are given, no initialization or command files
-contained an EXIT or QUIT command, and no fatal errors occurred, Kermit
-issues its prompt and waits for you to type commands.
-.IP
-Bear in mind that C\(hyKermit can be built with selected features
-disabled, and also that certain features are not available on all
-platforms. For example, C\(hyKermit can't be built with TCP/IP
-support on a platform that does not have TCP/IP header files and
-libraries (and even if Kermit does include TCP/IP support, it
-can't be used to make TCP/IP connections on a computer that does
-not have a TCP/IP stack installed). If your version of
-C\(hyKermit lacks a feature mentioned here, use its SHOW FEATURES command to
-see what might have been excluded.
-.PP
-C\(hyKermit has three kinds of commands: regular single\(hyletter command\(hyline
-options, extended\(hyformat command\(hyline options, and interactive commands.
-.PP
-Like most Unix commands, C\(hyKermit can be be given options on the command
-line. But C\(hyKermit also can be used interactively by giving it commands
-composed of words, which are more intuitive than cryptic command\(hyline
-options, and more flexible too. In other words, you don't have to use
-C\(hyKermit's command\(hyline options, but they are available if you want to. (By
-the same token, you don't have to use its interactive commands either \(hy\(hy
-you can use either or both in any combination.)
-.PP
-C\(hyKermit is generally installed in the PATH as "kermit", and therefore is
-invoked by typing the word "kermit" (lowercase) at the shell prompt, and
-then pressing the Return or Enter key. If you wish to include command\(hyline
-options, put them after the word "kermit" but before pressing Return or
-Enter, separated by spaces, for example:
-.PP
- $ kermit \-s ckermit.tar.gz
-.PP
-('$' is the shell prompt; "kermit \-s ckermit.tar.gz" is what you type,
-followed by Return or Enter.)
-.SH OPTIONS
-Here is a list of C\(hyKermit's single\(hyletter command\(hyline options, which
-start with a single dash (\-), in ASCII ("alphabetical") order. Alphabetic
-case is significant (\-A is not the same as \-a). Action options are
-tagged "ACTION".
-.TP
-\-0
-(digit zero) 100% transparent Connect state for
-"in\(hythe\(hymiddle" operation: 8 bits, no parity, no
-escape character, everything passes through.
-.TP
-\-8
-(digit eight) Connection is 8\(hybit clean (this is the
-default in C\(hyKermit 8.0 and later). Equivalent to the EIGHTBIT
-command, which in turn is a shortcut for SET TERMINAL
-BYTESIZE 8, SET COMMAND BYTESIZE 8, SET PARITY NONE.
-.TP
-\-9 arg
-(digit nine) Make a connection to an FTP server.
-Equivalent to the FTP OPEN command.
-Argument: IP\(hyaddress\(hyor\(hyhostname[:optional\(hyTCP\(hyport].
-NOTE: C\(hyKermit also has a separate FTP command\(hyline
-personality, with regular FTP\(hylike command\(hyline
-syntax. More about this below.
-.TP
-\-A
-Kermit is to be started as an Internet service (IKSD)
-(only from inetd.conf).
-.TP
-\-B
-Kermit is running in Batch or Background (no
-controlling terminal). To be used in case Kermit
-doesn't automatically sense its background status.
-Equivalent to the SET BACKGROUND ON command.
-.TP
-\-C arg
-Interactive\(hymode Commands to be executed.
-Argument: Commands separated by commas, list in
-doublequotes.
-.TP
-\-D arg
-Delay before starting to send in Remote mode.
-Equivalent to the SET DELAY command.
-Argument: Number of seconds.
-.TP
-\-E
-Exit automatically when connection closes. Equivalent
-to SET EXIT ON\-DISCONNECT ON.
-.TP
-\-F arg
-Use an open TCP connection.
-Argument: Numeric file descriptor of open TCP
-connection.
-Also see: \-j, \-J.
-.TP
-\-G arg
-(ACTION) Get file(s) from server, send contents to standard
-output, which normally would be piped to another
-process.
-Argument: Remote file specification, in quotes if it
-contains metacharacters.
-Also see: \-g, \-k.
-.TP
-\-H
-Suppress program startup Herald and greeting.
-.TP
-\-I
-Tell Kermit it has a reliable connection, to force streaming to be used where
-it normally would not be. Equivalent to the SET RELIABLE ON command.
-.TP
-\-J arg
-(ACTION) "Be like Telnet." Like \-j but implies \-E. Argument: IP
-hostname/address optionally followed by service. NOTE: C\(hyKermit also has a
-separate Telnet command\(hyline personality, with regular Telnet\(hylike
-command\(hyline syntax. More about this below.
-.TP
-\-L
-Recursive directory descent for files in \-s option.
-.TP
-\-M arg
-My user name (for use with Telnet, Rlogin, FTP, etc).
-Equivalent to the SET LOGIN USER command.
-Argument: Username string.
-.TP
-\-O
-(ACTION) (Uppercase letter O) Be a server for One command only.
-Also see: \-x.
-.TP
-\-P
-Don't convert file (Path) names of transferred files.
-Equivalent to SET FILE NAMES LITERAL.
-.TP
-\-Q
-Quick Kermit protocol settings. Equivalent to the FAST
-command. This is the default in C\(hyKermit 7.0 and later.
-.TP
-\-R
-Remote\(hyonly (this just makes IF REMOTE true).
-.TP
-\-S
-Stay (enter command parser after action options).
-.TP
-\-T
-Force Text mode for file transfer; implies \-V.
-Equivalent to SET TRANSFER MODE MANUAL, SET FILE TYPE TEXT.
-.TP
-\-V
-Disable automatic per\(hyfile text/binary switching.
-Equivalent to SET TRANSFER MODE MANUAL.
-.TP
-\-Y
-Skip (don't execute) the initialization file.
-.TP
-\-a arg
-As\(hyname for file(s) in \-s, \-r, or \-g.
-Argument: As\(hyname string (alternative filename). When
-receiving files, this can be a directory name.
-.TP
-\-b arg
-Speed for serial device. Equivalent to SET SPEED.
-Argument: Numeric Bits per second for serial
-connections.
-.TP
-\-c
-(ACTION) Enter Connect state before transferring files.
-.TP
-\-d
-Create a debug.log file with detailed debugging
-information (a second \-d adds timestamps). Equivalent
-to LOG DEBUG but takes effect sooner.
-.TP
-\-e arg
-Maximum length for incoming Kermit file\(hytransfer
-packets. Equivalent to SET RECEIVE PACKET\-LENGTH.
-Argument: Length in bytes.
-.TP
-\-f
-(ACTION) Send a FINISH command to a Kermit server.
-.TP
-\-g arg
-Get file(s) from a Kermit server.
-Argument: File specification on other computer, in
-quotes if it contains metacharacters. Equivalent to
-GET. Also see: \-a, \-G, \-r.
-.TP
-\-h
-(ACTION) Print Help text for single\(hyletter command\(hyline options
-(pipe thru 'more' to prevent scrolling).
-.TP
-\-i
-Force binary (Image) mode for file transfer; implies
-\-V. Equivalent to SET TRANSFER MODE MANUAL, SET FILE
-TYPE BINARY.
-.TP
-\-j arg
-Make a TCP/IP connection.
-Argument: IP host name/address and optional service
-name or number. Equivalent to the TELNET command.
-Also see: \-J, \-F.
-.TP
-\-k
-(ACTION) Receive file(s) to standard output, which normally
-would be piped to another process.
-Also see: \-r, \-G.
-.TP
-\-l arg
-(Lowercase letter L) Make a connection on the given
-serial communications device. Equivalent to the SET
-LINE (SET PORT) command.
-Argument: Serial device name, e.g. /dev/ttyS0.
-.TP
-\-m arg
-Modem type for use with the \-l device. Equivalent to
-the SET MODEM TYPE command.
-Argument: Modem name as in SET MODEM TYPE command,
-e.g. "usrobotics".
-.TP
-\-n
-(ACTION) Enter Connect state after transferring files (historical).
-.TP
-\-p arg
-Parity. Equivalent to the SET PARITY command.
-Argument: One of the following: e(ven), o(dd), m(ark),
-n(one), s(pace).
-.TP
-\-q
-Quiet (suppress most messages). Equivalent to SET QUIET ON.
-.TP
-\-r
-(ACTION) Receive file(s). Equivalent to the RECEIVE command.
-Argument: (none, but see \-a)
-.TP
-\-s arg
-Send file(s).
-Argument: One or more local file specifications.
-Equivalent to the SEND command.
-Also see: \-a.
-.TP
-\-t
-(Historical) Xon (Ctrl\-Q) Turnaround character for
-half\(hyduplex connections (used on serial linemode
-connections to old mainframes). Equivalent to SET
-DUPLEX HALF, SET HANDSHAKE XON.
-.TP
-\-v arg
-Window size for Kermit protocol (ignored when
-streaming). Equivalanet to SET WINDOW\-SIZE.
-Argument: Number, 1 to 32.
-.TP
-\-w
-Incoming files Write over existing files. Equivalent
-to SET FILE COLLISION OVERWRITE.
-.TP
-\-x
-(ACTION) Enter server mode. Equivalent to the SERVER command.
-Also see: \-O.
-.TP
-\-y arg
-Alternative initialization file.
-Argument: Filename.
-.TP
-\-z
-Force foreground behavior. To be used in case Kermit
-doesn't automatically sense its foreground status.
-Equivalent to the SET BACKGROUND OFF command.
-.PP
-Extended command\(hyline options (necessary because single\(hyletter ones are
-about used up) start with two dashes (\-\-), with words rather than single
-letters as option names. If an extended option takes an argument, it is
-separated from the option word by a colon (:). Extended options include:
-
-.TP
- \-\-bannerfile:filename
-File to display upon startup or IKSD login.
-.TP
- \-\-cdfile:filename
-File to be sent for display to the client when
-server changes directory (filename is relative to
-the changed\(hyto directory).
-.TP
- \-\-cdmessage:{on,off}
-Enable/disable the server CD message feature.
-.TP
- \-\-help
-Prints usage message for extended options.
-.TP
- \-\-helpfile:filename
-Designates a file containing custom text to
-replace the top\(hylevel HELP command.
-.TP
- \-\-nointerrupts
-Disables keyboard interrupts.
-.TP
- \-\-noperms
-Disables the Kermit protocol file Permissions
-attribute, to prevent transmission of file
-permissions (protection) from sender to receiver.
-.TP
- \-\-version
-(ACTION) C\(hyKermit prints its version number.
-.PP
-Plus several other IKSD\(hyOnly options described at:
-.PP
- http://www.columbia.edu/kermit/iksd.html
-.PP
-See the file\(hytransfer section for examples of command\(hyline invocation.
-.SH COMMAND LANGUAGE
-C\(hyKermit's interactive command language is the subject of a 622\(hypage book
-and another several hundred pages of updates, far too much for a manual
-page. But it's not hard to get started. At the shell prompt, just type
-"kermit" to get C\(hyKermit's interactive command prompt:
-.PP
-.nf
- $ kermit
- (/current/directory) C\-Kermit>
-.fi
-.PP
-Begin by typing "help" (and then press the Return or Enter key) for a
-top\(hylevel overview, read it, and go from there. Your second command should
-probably be "intro" (introduction). Note the prompt shows your current
-directory (unless you tell Kermit to prompt you with something else).
-.PP
-Interactive commands are composed mainly of regular English words, usually
-in the form of imperative sentences, such as:
-.PP
- send oofa.txt
-.PP
-which tells Kermit to send (transfer) the file whose name is oofa.txt, or:
-.PP
- set transfer mode automatic
-.PP
-which sets Kermit's "transfer mode" to "automatic" (whatever that means).
-.PP
-While typing commands, you can abbreviate, ask for help (by pressing the
-"?" key anywhere in a command), complete keywords or filenames (with the
-Tab or Esc key), and edit your typing with Backspace or Delete, Ctrl\-W,
-Ctrl\-U, etc. You can also recall previous commands, save your command
-history, and who knows what else. Give the INTRO command for details.
-.PP
-C\(hyKermit has hundreds of commands, and they can be issued in infinite
-variety and combinations, including commands for:
-.nf
-.PP
-\(bu Making connections (SET LINE, DIAL, TELNET, SSH, FTP, ...)
-.br
-\(bu Breaking connections (HANGUP, CLOSE)
-.br
-\(bu Transferring files (SEND, GET, RECEIVE, MOVE, RESEND, ...)
-.br
-\(bu Establishing preferences (SET)
-.br
-\(bu Displaying preferences (SHOW)
-.br
-\(bu Managing local files (CD, DELETE, MKDIR, DIR, RENAME, TYPE, ...)
-.br
-\(bu Managing remote files (RCD, RDEL, RMKDIR, RDIR, ...)
-.br
-\(bu Using local files (FOPEN, FCLOSE, FREAD, FWRITE)
-.br
-\(bu Programming (TAKE, DEFINE, IF, FOR, WHILE, SWITCH, DECLARE, ...)
-.br
-\(bu Interacting with the user (ECHO, ASK, ...)
-.br
-\(bu Interacting with a remote computer (INPUT, OUTPUT, ...)
-.br
-\(bu Interacting with local programs (RUN, EXEC, PTY, ...)
-.br
-\(bu Logging things (LOG SESSION, LOG PACKETS, LOG DEBUG, ...)
-.PP
-.fi
-And of course QUIT or EXIT to get out and HELP to get help, and for
-programmers: loops, decision making, variables, arrays, associative arrays,
-integer and floating point arithmetic, macros, built\(hyin and user\(hydefined
-functions, string manipulation, pattern matching, block structure, scoping,
-recursion, and all the rest. To get a list of all C\(hyKermit's commands, type
-a question mark (?) at the prompt. To get a description of any command,
-type HELP followed by the name of the command, for example:
-.PP
- help send
-.PP
-The command interruption character is Ctrl\-C (hold down the Ctrl key and
-press the C key).
-.PP
-The command language "escape character", used to introduce variable names,
-function invocations, and so on, is backslash (\). If you need to include a
-literal backslash in a command, type two of them, e.g.:
-.PP
- get c:\ek95\ek95custom.ini
-.SS Command Files, Macros, and Scripts
-A file containing Kermit commands is called a Kermit command file or Kermit
-script. It can be executed with Kermit's TAKE command:
-.PP
- (/current/dir) C\-Kermit> take commandfile
-.PP
-(where "commandfile" is the name of the command file). Please don't pipe a
-command file into Kermit's standard input (which might or might not work);
-if you have Kermit commands in a file, tell Kermit to TAKE the file.
-.PP
-In Unix only, a Kermit command file can also be executed directly by
-including a "kerbang" line as the first line of the file:
-.PP
- #!/usr/local/bin/kermit +
-.PP
-That is, a top line that starts with "#!", followed immediately by the full
-path of the Kermit executable, and then, if the Kermit script is to be
-given arguments on the command line, a space and a plus sign. The script
-file must also have execute permission:
-.PP
- chmod +x commandfile
-.PP
-Except for the " +" part, this is exactly the same as you would do for a
-shell script, a Perl script, etc. Here's a simple but useless example
-script that regurgitates its arguments (up to three of them):
-.PP
- #!/usr/local/bin/kermit +
- if defined \e%1 echo "Argument 1: \e%1"
- if defined \e%2 echo "Argument 2: \e%2"
- if defined \e%3 echo "Argument 3: \e%3"
- if defined \e%4 echo "etc..."
- exit
-.PP
-If this file is stored in your current directory as "commandfile", then:
-.PP
- ./commandfile one two three four five
-.PP
-prints:
-.PP
- Argument 1: one
- Argument 2: two
- Argument 3: three
- etc...
-.PP
-This illustrates the basic structure of a standalone Kermit script: the
-"kerbang line", then some commands. It should end with "exit" unless you
-want the Kermit prompt to appear when it is finished. \e%1 is the first
-argument, \e%2 the second, and so on.
-.PP
-You can also create your own commands by defining named macros composed of
-other Kermit commands (or macros). For example:
-.PP
-.nf
- define mydelete {
- local trash
- assign trash \ev(home)trashcan/
- if not defined \e%1 end 1 "Delete what?"
- if wild \e%1 {
- end 1 "Deleting multiple files is too scary"
- }
- if not exist \e%1 end 1 "I can't find \e%1"
- if not directory \em(trash) {
- mkdir \em(trash)
- if fail end 1 "No trash can"
- }
- rename /list \e%1 \em(trash)
- }
- define myundelete {
- local trash
- assign trash \ev(home)trashcan/
- if not defined \e%1 end 1 "Undelete what?"
- if wild \e%1 {
- end 1 "Undeleting multiple files is too hard"
- }
- if not directory \em(trash) end 1 "No trash can"
- if not exist \em(trash)\e%1 {
- end 1 "I can't find \e%1 in trash can"
- }
- rename /list \em(trash)\e%1 .
- }
-.PP
-.fi
-These sample macros are not exactly production quality (they don't handle
-filenames that include path segments, they don't handle multiple files,
-etc), but you get the idea: you can pass arguments to macros, and they can
-check them and make other kinds of decisions. If you put the above lines
-into your initialization or customization file (explained below), you'll
-have MYDELETE and MYUNDELETE commands available every time you start
-Kermit, at least as long as you don't suppress execution of the
-initialization file. (Exercise for the reader: Make these macros generally
-useful: remove limitations, add trashcan display, browsing, emptying, etc.)
-.PP
-Kerbang scripts execute without the initialization file. This to keep them
-portable and also to make them start faster. If you want to write Kerbang
-scripts that depend on the initialization file, include the command
-.PP
- take \ev(home).kermrc
-.PP
-at the desired spot in the script. By the way, \ev(xxx) is a built\(hyin
-variable (xxx is the variable name, "home" in this case). To see what
-built\(hyin variables are available, type "show variables" at the C\(hyKermit
-prompt. To see what else you can show, type "show ?". \em(xxx) is a user
-defined variable (strictly speaking, it is a macro used as a variable).
-.SS Command List
-C\(hyKermit has more than 200 top\(hylevel commands, and some of these, such as
-SET, branch off into hundreds of subcommands of their own, so it's not
-practical to describe them all here. Instead, here's a concise list of the
-most commonly used top\(hylevel commands, grouped by category. To learn about
-each command, type "help" followed by the command name, e.g. "help set".
-Terms such as Command state and Connect state are explained in subsequent
-sections.
-.PP
-Optional fields are shown in [ brackets ]. "filename" means the
-name of a single file. filespec means a file specification that is allowed
-to contain wildcard characters like '*' to match groups of files. options
-are (optional) switches like /PAGE, /NOPAGE, /QUIET, etc, listed in the
-HELP text for each command. Example:
-.PP
-.nf
- send /recursive /larger:10000 /after:\-1week /except:*.txt *
-.fi
-.PP
-which can be read as "send all the files in this directory and all the ones
-underneath it that are larger than 10000 bytes, no more than one week old,
-and whose names don't end with ".txt".
-.SS
-Basic Commands
-.RS
-.TP
-HELP
-Requests top\(hylevel help.
-.TP
-HELP command
-Requests help about the given command.
-.TP
-INTRODUCTION
-Requests a brief introduction to C\(hyKermit.
-.TP
-LICENSE
-Displays the C\(hyKermit software copyright and license.
-.TP
-VERSION
-Displays C\(hyKermit's version number.
-.TP
-EXIT [ number ]
-Exits from Kermit with the given
-status code. Synonyms: QUIT, E, Q.
-.TP
-TAKE filename [ parameters... ]
-Executes commands from the given
-.TP
-LOG item [ filename ]
-Keeps a log of the given item in the given file.
-.TP
-[ DO ] macro [ parameters... ]
-Executes commands from the given macro.
-.TP
-SET parameter value
-Sets the given parameter to the given value.
-.TP
-SHOW category
-Shows settings in a given category.
-.TP
-STATUS
-Tells whether previous command succeeded or failed.
-.TP
-DATE [ date\(hyand/or\(hytime ]
-Shows current date\(hytime or interprets given date\(hytime.
-.TP
-RUN [ extern\(hycommand [ parameters... ]
-Runs the given external command. Synonym: !.
-.TP
-EXEC [ extern\(hycommand [ params... ]
-Kermit overlays itself with the given command.
-.TP
-SUSPEND
-Stops Kermit and puts it in the background. Synonym: Z.
-.RE
-.SS
-Local File Management
-.RS
-.TP
-TYPE [ options ] filename
-Displays the contents of the given file.
-.TP
-MORE [ options ] filename
-Equivalent to TYPE /PAGE (pause after each screenful).
-.TP
-CAT [ options ] filename
-Equivalent to TYPE /NOPAGE.
-.TP
-HEAD [ options ] filename
-Displays the first few lines of a given file.
-.TP
-TAIL [ options ] filename
-Displays the last few lines of a given file.
-.TP
-GREP [ options ] pattern filespec
-Displays lines from files that match
-the pattern. Synonym: FIND.
-.TP
-DIRECTORY [ options ] [filespec ]
-Lists files (built\(hyin, many options).
-.TP
-LS [ options ] [ filespec ]
-Lists files (runs external "ls" command).
-.TP
-DELETE [ options ] [ filespec ]
-Deletes files. Synonym: RM.
-.TP
-PURGE [ options ] [ filespec ]
-Removes backup (*.~n~) files.
-.TP
-COPY [ options ] [ filespecs... ]
-Copies files. Synonym: CP.
-.TP
-RENAME [ options ] [ filespecs... ]
-Renames files. Synonym: MV.
-.TP
-CHMOD [ options ] [ filespecs... ]
-Changes permissions of files.
-.TP
-TRANSLATE filename charsets [ filename ]
-Converts file's character set. Synonym: XLATE.
-.TP
-CD
-Changes your working directory to your home directory.
-.TP
-CD directory
-Changes your working directory to the one given.
-.TP
-CDUP
-Changes your working directory one level up.
-.TP
-PWD
-Displays your working directory.
-.TP
-BACK
-Returns to your previous working directory.
-.TP
-MKDIR [ directory ]
-Creates a directory.
-.TP
-RMDIR [ directory ]
-Removes a directory.
-.RE
-.SS
-Making Connections
-.RS
-.TP
-SET LINE [ options ] devicename
-Opens the named serial port. Synonym: SET PORT.
-.TP
-OPEN LINE [ options ] devicename
-Same as SET LINE. Synonym: OPEN PORT.
-.TP
-SET MODEM TYPE [ name ]
-Tells Kermit what kind of modem is on the port.
-.TP
-DIAL [ number ]
-Tells Kermit to dial the given phone number with the modem.
-.TP
-REDIAL
-Redials the most recently dialed phone number.
-.TP
-ANSWER
-Waits for and answers an incoming call on the modem.
-.TP
-AUTHENTICATE [ parameters... ]
-Performs secure authentication on a TCP/IP connection.
-.TP
-SET NETWORK TYPE { TCP/IP, X.25, ... }
-Selects network type for subsequent SET HOST commands.
-.TP
-SET HOST [ options ] host [ port ]
-Opens a network connection to the given host and port.
-.TP
-SET HOST * port
-Waits for an incoming TCP/IP connection on the given port.
-.TP
-TELNET [ options ] host
-Opens a Telnet connection to the host and enters Connect state.
-.TP
-RLOGIN [ options ] host
-Opens an Rlogin connection to the host and enters Connect state.
-.TP
-IKSD [ options ] host
-Opens a connection to an Internet Kermit Service.
-.TP
-SSH [ options ] host
-Opens an SSH connection to the host and enters Connect state.
-.TP
-FTP OPEN host [ options ]
-Opens an FTP connection to the host.
-.TP
-HTTP [ options ] OPEN host
-Opens an HTTP connection to the host.
-.TP
-PTY external\(hycommand
-Runs the command on a pseudoterminal as if it were a connection.
-.TP
-PIPE external\(hycommand
-Runs the command through a pipe as if it were a connection.
-.RE
-.SS
-Using Connections
-.RS
-.TP
-CONNECT [ options ]
-Enters Connect (terminal) state. Synonym: C.
-.TP
-REDIRECT command
-Redirects the given external command over the connection.
-.TP
-TELOPT command
-Sends a Telnet protocol command (Telnet connections only).
-.TP
-Ctrl\-\eC
-"Escapes back" from Connect state to Command state.
-.TP
-Ctrl\-\eB
-(In Connect state) Sends a BREAK signal (serial or Telnet).
-.TP
-Ctrl\-\e!
-(In Connect state) Enters inferior shell; "exit" to return.
-.TP
-Ctrl\-\e?
-(In Connect state) Shows a menu of other escape\(hylevel options.
-.TP
-Ctrl\-\eCtrl\-\e
-(In Connect state) Type two
-Ctrl\-Backslashes to send one of them.
-.TP
-SET ESCAPE [ character ]
-Changes Kermit's Connect\(hystate escape character.
-.RE
-.SS
-Closing Connections
-.RS
-.TP
-HANGUP
-Hangs up the currently open
-serial\(hyport or network connection.
-.TP
-CLOSE
-Closes the currently open
-serial\(hyport or network connection.
-.TP
-SET LINE (with no devicename)
-Closes the currently open
-serial\(hyport or network connection.
-.TP
-SET HOST (with no hostname)
-Closes the currently open serial\(hyport or network connection.
-.TP
-FTP CLOSE
-Closes the currently open FTP connection.
-.TP
-HTTP CLOSE
-Closes the currently open HTTP connection.
-.TP
-EXIT
-Also closes all connections. Synonym: QUIT.
-.TP
-SET EXIT WARNING OFF
-Suppresses warning about open connections on exit or close.
-.RE
-.SS
-File Transfer
-.RS
-.TP
-SEND [ options ] filename [ as\(hyname ]
-Sends the given file. Synonym: S.
-.TP
-SEND [ options ] filespec
-Sends all files that match.
-.TP
-RESEND [ options ] filespec
-Resumes an interrupted SEND from the point of failure.
-.TP
-RECEIVE [ options ] [ as\(hyname ]
-Waits passively for files to arrive. Synonym: R.
-.TP
-LOG TRANSACTIONS [ filename ]
-Keeps a record of file transfers.
-.TP
-FAST
-Use fast file\(hytransfer settings (default).
-.TP
-CAUTIOUS
-Use cautious and less fast file\(hytransfer settings.
-.TP
-ROBUST
-Use ultra\(hyconservative and slow file\(hytransfer settings.
-.TP
-STATISTICS [ options ]
-Gives statistics about the most recent file transfer.
-.TP
-WHERE
-After transfer: "Where did my files go?".
-.TP
-TRANSMIT [ options ] [ofilename ]
-Sends file without protocol. Synonym: XMIT.
-.TP
-LOG SESSION [ filename ]
-Captures remote text or files without protocol.
-.TP
-SET PROTOCOL [ name... ]
-Tells Kermit to use an external file\(hytransfer protocol.
-.TP
-FTP { PUT, MPUT, GET, MGET, ... }
-FTP client commands.
-.TP
-HTTP { PUT, GET, HEAD, POST, ... }
-HTTP client commands.
-.RE
-.SS
-Kermit Server
-.RS
-.TP
-ENABLE, DISABLE
-Controls which server features can be used by clients.
-.TP
-SET SERVER
-Sets parameters prior to entering Server state.
-.TP
-SERVER
-Enters Server state.
-.RE
-.SS
-Client of Kermit or FTP Server
-.RS
-.TP
-[ REMOTE ] LOGIN [ user password ]
-Logs in to a Kermit server or IKSD that requires it.
-.TP
-[ REMOTE ] LOGOUT
-Logs out from a Kermit server or IKSD.
-.TP
-SEND [ options ] filename [ as\(hyname ]
-Sends the given file to the server. Synonyms: S, PUT.
-.TP
-SEND [ options ] filespec
-Sends all files that match.
-.TP
-RESEND [ options ] filespec
-Resumes an interrupted SEND from the point of failure.
-.TP
-GET [ options ] remote\(hyfilespec
-Asks the server to send the given files. Synonym: G.
-.TP
-REGET [ options ] remote\(hyfilespec
-Resumes an interrupted GET from the point of failure.
-.TP
-REMOTE CD [ directory ]
-Asks server to change its working
-directory. Synonym: RCD.
-.TP
-REMOTE PWD [ directory ]
-Asks server to display its working directory. Synonym: RPWD.
-.TP
-REMOTE DIRECTORY [ filespec... ]
-Asks server to send a directory listing. Synonym: RDIR.
-.TP
-REMOTE DELETE [ filespec... ]
-Asks server to delete files. Synonym: RDEL.
-.TP
-REMOTE [ command... ]
-(Many other commands: "remote ?" for a list).
-.TP
-MAIL [ options ] filespec
-Sends file(s) to be delivered as e\(hymail (Kermit only).
-.TP
-FINISH
-Asks the server to exit server state (Kermit only).
-.TP
-BYE
-Asks the server to log out and close the connection.
-.RE
-.SS
-Script Programming
-.PP
-.RS
-DEFINE, DECLARE, UNDEFINE, UNDECLARE, ASSIGN, EVALUATE, SEXPRESSION,
-ARRAY, SORT, INPUT, OUTPUT, IF, FOR, WHILE, SWITCH, GOTO, ECHO, ASK,
-GETC, GETOK, ASSERT, WAIT, SLEEP, FOPEN, FREAD, FWRITE, FCLOSE, STOP,
-END, RETURN, LEARN, SHIFT, TRACE, VOID, INCREMENT, DECREMENT, ... For
-these and many more you'll need to consult the manual and supplements,
-and/or visit the Kermit Script Library, which also includes a brief
-tutorial. Hint: HELP LEARN to find out how to get Kermit to write
-simple scripts for you.
-.RE
-.PP
-Many of Kermit's commands have synonyms, variants, relatives, and so on.
-For example, MSEND is a version of SEND that accepts a list of file
-specifications to be sent, rather than just one file specification, and
-MPUT is a synonym of MSEND. MOVE means to SEND and then DELETE the source
-file if successful. MMOVE is like MOVE, but accepts a list of filespecs,
-and so on. These are described in the full documentation.
-.PP
-Use question mark to feel your way through an unfamiliar command, as in
-this example:
-.PP
-.nf
- C\-Kermit> remote ? One of the following:
- assign directory kermit print rmdir
- cd exit login pwd set
- copy help logout query space
- delete host mkdir rename type
- C\-Kermit> remote set ? One of the following:
- attributes file retry transfer
- block\-check receive server window
- C\-Kermit> remote set file ? One of the following:
- character\-set incomplete record\-length
- collision names type
- C\-Kermit> remote set file names ? One of the following:
- converted literal
- C\-Kermit> remote set file names literal
- C\-Kermit>
-.PP
-.fi
-This is called menu on demand: you get a menu when you want one, but menus
-are not forced on you even when know what you're doing. Note that you can
-also abbreviate most keywords, and you can complete them with the Tab or
-Esc key. Also note that ? works for filenames too, and that you can use it
-in the middle of a keyword or filename, not just at the beginning. For
-example, "send x?" lists all the files in the current directory whose names
-start with 'x'.
-.SH INITIALIZATION FILE
-In its default configuration, C\(hyKermit executes commands from a file
-called .kermrc in your home directory when it starts, unless it is given the
-\-Y or \-y command\(hyline option. Custom configurations might substitute a shared
-system\(hywide initialization file. The SHOW FILE command tells what
-initialization file, if any, was used. The standard initialization file
-"chains" to an individual customization file, .mykermc, in the home directory,
-in which each user can establish her/his own preferences, define macros, and
-so on.
-.PP
-Since execution of the initialization file (at least the standard one)
-makes C\(hyKermit take longer to start, it might be better not to have an
-initialization file, especially now that Kermit's default startup
-configuration is well attuned to modern computing and networking \(hy\(hy in
-other words, you no longer have do anything special to make Kermit
-transfers go fast. So instead of having an initialization file that is
-executed every time Kermit starts, you might consider making one or more
-kerbang scripts (with names other that .kermrc) that do NOT include an
-"exit" command, and invoke those when you need the settings, macro
-definitions, and/or scripted actions they contain, and invoke C\(hyKermit
-directly when you don't.
-.PP
-To put it another way... We still distribute the standard initialization
-file since it's featured in the manual and backwards compatibility is
-important to us. But there's no harm in not using it if you don't need the
-stuff that's in it (services directory, dialing directory, network
-directory, and associated macro definitions). On the other hand, if there
-are settings or macros you want in effect EVERY time you use Kermit, the
-initialization file (or the customization file it chains to) is the place
-to put them, because that's the only place Kermit looks for them
-automatically each time you start it.
-.SH MODES OF OPERATION
-Kermit is said to be in Local mode if it has made a connection to another
-computer, e.g. by dialing it or establishing a Telnet connection to it. The
-other computer is remote, so if you start another copy of Kermit on the
-remote computer, it is said to be in Remote mode (as long as it has not
-made any connections of its own). The local Kermit communicates over the
-communications device or network connection, acting as a conduit between
-the the remote computer and your keyboard and screen. The remote Kermit is
-the file\(hytransfer partner to the local Kermit and communicates only through
-its standard input and output.
-.PP
-At any moment, a Kermit program can be in any of the following states. It's
-important to know what they are and how to change from one to the other.
-.TP
-Command state
-In this state, Kermit reads commands from:
-.sp
-\(bu Your keyboard; or:
-.br
-\(bu A file, or:
-.br
-\(bu A macro definition.
-.sp
-You can exit from Command state back to Unix with the EXIT or QUIT
-command (same thing). You can enter Connect state with any of various
-commands (CONNECT, DIAL, TELNET, etc). You can enter file transfer
-state with commands like SEND, RECEIVE, and GET. You can enter Server
-state with the SERVER command. The TAKE command tells Kermit to read
-and execute commands from a file. The (perhaps implied) DO command
-tells Kermit to read and execute commands from a macro definition.
-While in Command state, you can interrupt any command, macro, or
-command file by typing Ctrl\-C (hold down the Ctrl key and press the C
-key); this normally brings you back to the prompt.
-.TP
-Shell state
-You can invoke an inferior shell or external command from the Kermit
-command prompt by using the PUSH, RUN (!), EDIT, or BROWSE command.
-While the inferior shell or command is active, Kermit is suspended and
-does nothing. Return to Kermit Command state by exiting from the
-inferior shell or application.
-.TP
-Connect state
-In this state, which can be entered only when in Local mode (i.e. when
-Kermit has made a connection to another computer), Kermit is acting as
-a terminal to the remote computer. Your keystrokes are sent to the
-remote computer and characters that arrive over the communication
-connection are displayed on your screen. This state is entered when
-you give a CONNECT, DIAL, TELNET, RLOGIN, or IKSD command. You can
-return to command state by logging out of the remote computer, or by
-typing:
-.sp
- Ctrl\-\ec
-.sp
-That is: Hold down the Ctrl key and press the backslash key, then let
-go of the Ctrl key and press the C key. This is called escaping back.
-Certain other escape\(hylevel commands are also provided; type Ctrl\-\e?
-for a list. For example, you can enter Shell state with:
-.sp
- Ctrl\-\e!
-.sp
-To send a Ctrl\-\e to the host while in Connect state, type two of them
-in a row. See HELP CONNECT and HELP SET ESCAPE for more info.
-.TP
-Local file\(hytransfer state
-In this state, Kermit is sending packets back and forth with the other
-computer in order to transfer a file or accomplish some other
-file\(hyrelated task. And at the same time, it is displaying its progress
-on your screen and watching your keyboard for interruptions. In this
-state, the following single\(hykeystroke commands are accepted:
-.sp
-.RS
-.TP
-X
-Interrupt the current file and go on to the next (if any).
-.TP
-Z
-Interrupt the current file and skip all the rest.
-.TP
-E
-Like Z but uses a "stronger" protocol (use if X or Z don't work).
-.TP
-Ctrl\-C
-Interrupt file\(hytransfer mode (use if Z or E don't work).
-.sp
-.RE
-Kermit returns to its previous state (Command or Connect) when the
-transfer is complete or when interrupted successfully by X, Z, E, or
-Ctrl\-C (hold down the Ctrl key and press the C key).
-.TP
-Remote file\(hytransfer state
-In this state, Kermit is exchanging file\(hytransfer packets with its
-local partner over its standard i/o. It leaves this state
-automatically when the transfer is complete. In case you find your
-local Kermit in Connect state and the remote one in File\(hytransfer
-state (in which it seems to ignore your keystrokes), you can usually
-return it to command state by typing three Ctrl\-C's in a row. If that
-doesn't work, return your local Kermit to Command state (Ctrl\-\e C) and
-type "e\(hypacket" and then press the Return or Enter key; this forces a
-fatal Kermit protocol error.
-.TP
-Remote Server state
-This is like Remote File\(hytransfer state, except it never returns
-automatically to Command state. Rather, it awaits further instructions
-from the client program; that is, from your Local Kermit program. You
-can return the Remote Server to its previous state by issuing a
-"finish" command to the client, or if you are in Connect state, by
-typing three Ctrl\-C's in a row. You can tell the server job to log out
-and break the connection by issuing a "bye" command to the client.
-.TP
-Local Server state
-Like Remote\(hyServer state, but in local mode, and therefore with its
-file\(hytransfer display showing, and listening for single\(hykey commands,
-as in Local File\(hytransfer state. Usually this state is entered
-automatically when a remote Kermit program gives a GET command.
-.sp
-C\(hyKermit, Kermit 95, and MS\(hyDOS Kermit all can switch automatically from
-Connect state to Local File\(hytransfer state when you initiate a file
-transfer from the remote computer by starting Kermit and telling it to send
-or get a file, in which case, Connect state is automatically resumed after
-the file transfer is finished.
-.sp
-Note that C\(hyKermit is not a terminal emulator. It is a communications
-application that you run in a terminal window (e.g. console or Xterm). The
-specific emulation, such as VT100, VT220, Linux Console, or Xterm, is
-provided by the terminal window in which you are running C\(hyKermit. Kermit
-95 and MS\(hyDOS Kermit, on the other hand, are true terminal emulators. Why
-is C\(hyKermit not a terminal emulator? CLICK HERE to read about it.
-.SH MAKING CONNECTIONS
-Here is how to make different kinds of connections using interactive Kermit
-commands (as noted above, you can also make connections with command\(hyline
-options). Note that you don't have to make connections with Kermit. It can
-also be used on the far end of a connection as the remote file transfer and
-management partner of your local communications software.
-.TP
-Making a Telnet Connection
-At the C\(hyKermit command prompt, simply type:
-.sp
-.nf
- telnet foo.bar.com
-.fi
-.sp
-(substituting desired hostname or address).
-You can also include a port number:
-.sp
-.nf
- telnet xyzcorp.com 3000 ;
-.fi
-.sp
-If the connection is successful, Kermit automically enters Connect
-state. When you logout from the remote host, Kermit automatically
-returns to its prompt. More info: HELP TELNET, HELP SET TELNET, HELP
-SET TELOPT. Also see the IKSD section below.
-.TP
-Making an Rlogin connection
-This is just like Telnet, except you have to be root to do it because
-Rlogin uses a privileged TCP port:
-.sp
-.nf
- rlogin foo.bar.com
-.fi
-.sp
-More info: HELP RLOGIN.
-.TP
-Making an SSH Connection
-Unlike Telnet and Rlogin, SSH connections are not built\(hyin, but
-handled by running your external SSH client through a pseudoterminal.
-Using C\(hyKermit to control the SSH client gives you all of Kermit's
-features (file transfer, character\(hyset conversion, scripting, etc)
-over SSH.
-.sp
- ssh foo.bar.com
-.sp
-More info: HELP SSH, HELP SET SSH.
-.TP
-Dialing with a Modem
-If it's an external modem, make sure it is connected to a usable
-serial port on your computer with a regular (straight\(hythrough) modem
-cable, and to the telephone jack with a telephone cable, and that it's
-turned on. Then use these commands:
-.sp
-.nf
- set modem type usrobotics ; Or other supported type
- set line /dev/ttyS0 ; Specify device name
- set speed 57600 ; Or other desired speed
- set flow rts/cts ; Most modern modems support this
- set dial method tone ; (or pulse)
- dial 7654321 ; Dial the desired number
-.fi
-.sp
-Type "set modem type ?" for a list of supported modem types. If you
-omit the SET MODEM TYPE command, the default type is
-"generic\(hyhigh\(hyspeed", which should work for most modern AT\(hycommand\(hyset
-modems. If the line is busy, Kermit redials automatically. If the call
-does not succeed, use "set dial display on" and try it again to watch
-what happens. If the call succeeds, Kermit enters Connect state
-automatically and returns to its prompt automatically when you log out
-from the remote computer or the connection is otherwise lost.
-.sp
-You can also dial from a modem that is accessible by Telnet, e.g. to a
-reverse terminal server. In this case the command sequence is:
-.sp
-.nf
- set host ts.xxx.com 2000 ; Terminal\(hyserver and port
- set modem type usrobotics ; Or other supported type
- set dial method tone ; (or pulse)
- dial 7654321 ; Dial the desired number
-.fi
-.sp
-If the terminal server supports the Telnet Com Port Option, RFC 2217,
-you can also give serial\(hyport related commands such as SET SPEED, SET
-PARITY, and so on, and Kermit relays them to the terminal server using
-the protocol specified in the RFC.
-.sp
-More info: HELP SET MODEM, HELP SET LINE, HELP SET SPEED, HELP SET
-FLOW, HELP DIAL, HELP SET DIAL, HELP SET MODEM, HELP SET
-CARRIER\-WATCH, SHOW COMMUNICATIONS, SHOW MODEM, SHOW DIAL.
-.TP
-Direct Serial Port
-Connect the two computers, A and B, with a null modem cable (or two
-modem cables interconnected with a null\(hymodem adapter or modem
-eliminator). From Computer A:
-.sp
-.nf
- set modem type none ; There is no modem
- set line /dev/ttyS0 ; Specify device name
- set carrier\-watch off ; If DTR CD are not cross\(hyconnected
- set speed 57600 ; Or other desired speed
- set flow rts/cts ; If RTS and CTS are cross\(hyconnected
- set parity even ; (or "mark" or "space", if necessary)
- set stop\-bits 2 ; (rarely necessary)
- set flow xon/xoff ; If you can't use RTS/CTS
- connect ; Enter Connect (terminal) state
-.fi
-.sp
-This assumes Computer B is set up to let you log in. If it isn't, you
-can run a copy of Kermit on Computer B and follow approximately the
-same directions. More info: As above plus HELP CONNECT.
-.PP
-With modems or direct serial connections, you might also have to "set
-parity even" (or "mark" or "space") if it's a 7\(hybit connection.
-.PP
-Of the connection types listed above, only one can be open at a time.
-However, any one of these can be open concurrently with an FTP or HTTP
-session. Each connection type can be customized to any desired degree,
-scripted, logged, you name it. See the manual.
-.PP
-NOTE: On selected platforms, C\(hyKermit also can make X.25 connections. See
-the manual for details.
-.SH TRANSFERRING FILES WITH KERMIT
-There is a widespread and persistent belief that Kermit is a slow protocol.
-This is because, until recently, it used conservative tuning by default to
-make sure file transfers succeeded, rather than failing because they
-overloaded the connection. Some extra commands (or command\(hyline options,
-like \-Q) were needed to make it go fast, but nobody bothered to find out
-about them. Also, it takes two to tango: most non\(hyKermit\(hyProject Kermit
-protocol implementations really ARE slow. The best file\(hytransfer partners
-for C\(hyKermit are: another copy of C\(hyKermit (7.0 or later) and Kermit 95.
-These combinations work well and they work fast by default. MS\(hyDOS Kermit
-is good too, but you have to tell it to go fast (by giving it the FAST
-command).
-.PP
-Furthermore, all three of these Kermit programs support "autodownload" and
-"autoupload", meaning that when they are in Connect state and a Kermit
-packet comes in from the remote, they automatically switch into file
-transfer mode.
-.PP
-And plus, C\(hyKermit and K95 also switch automatically between text and
-binary mode for each file, so there is no need to "set file type binary" or
-"set file type text", or to worry about files being corrupted because they
-were transferred in the wrong mode.
-.PP
-What all of these words add up to is that now, when you use up\(hyto\(hydate
-Kermit software from the Kermit Project, file transfer is not only fast,
-it's ridiculously easy. You barely have to give any commands at all.
-.TP
-Downloading Files
-Let's say you have Kermit 95, C\(hyKermit, or MS\(hyDOS Kermit on your
-desktop computer, with a connection to a Unix computer that has
-C\(hyKermit installed as "kermit". To download a file (send it from Unix
-to your desktop computer), just type the following command at your
-Unix shell prompt:
-.sp
- kermit \-s oofa.txt
-.sp
-(where oofa.txt is the filename). If you want to send more than one
-file, you can put as many filenames as you want on the command line,
-and they can be any combination of text and binary:
-.sp
- kermit \-s oofa.txt oofa.zip oofa.html oofa.tar.gz
-.sp
-and/or you can use wildcards to send groups of files:
-.sp
- kermit \-s oofa.*
-.sp
-If you want to send a file under an assumed name, use:
-.sp
- kermit \-s friday.txt \-a today.txt
-.sp
-This sends the file friday.txt but tells the receiving Kermit that its
-name is today.txt. In all cases, as noted, when the file transfer is
-finished, your desktop Kermit returns automatically to Connect state.
-No worries about escaping back, re\(hyconnecting, text/binary mode
-switching. Almost too easy, right?
-.TP
-Uploading Files
-To upload files (send them from your desktop computer to the remote
-Unix computer) do the same thing, but use the \-g (GET) option instead
-of \-s:
-.sp
- kermit \-g oofa.txt
-.sp
-This causes your local Kermit to enter server mode; then the remote
-Kermit program requests the named file and the local Kermit sends it
-and returns automatically to Connect state when done.
-.sp
-If you want to upload multiple files, you have have use shell quoting
-rules, since these aren't local files:
-.sp
-.nf
- kermit \-g "oofa.txt oofa.zip oofa.html oofa.tar.gz"
- kermit \-g "oofa.*"
-.fi
-.sp
-If you want to upload a file but store it under a different name, use:
-.sp
- kermit \-g friday.txt \-a today.txt
-.TP
-Kermit Transfers the Old\(hyFashioned Way
-If your desktop communications software does not support autoupload or
-autodownload, or it does not include Kermit server mode, the procedure
-requires more steps.
-.sp
-To download a file, type:
-.sp
- kermit \-s filename
-.sp
-on the host as before, but if nothing happens automatically in
-response to this command, you have to switch your desktop
-communications software into Kermit Receive state. This might be done
-by escaping back using keyboard characters or hot keys (Alt\-x is
-typical) and/or with a command (like RECEIVE) or a menu. When the file
-transfer is complete, you have to go back to Connect state, Terminal
-emulation, or whatever terminology applies to your desktop
-communications software.
-.sp
-To upload a file, type:
-.sp
- kermit \-r
-.sp
-on the host (rather than "kermit \-g"). This tells C\(hyKermit to wait
-passively for a file to start arriving. Then regain the attention of
-your desktop software (Alt\-x or whatever) and instruct it to send the
-desired file(s) with Kermit protocol. When the transfer is finished,
-return to the Connect or Terminal screen.
-.TP
-If File Transfer Fails
-Although every aspect of Kermit's operation can be finely tuned, there
-are also three short and simple "omnibus tuning" commands you can use
-for troubleshooting:
-.RS
-.TP
-FAST
-Use fast file\(hytransfer settings. This has been the default since
-C\(hyKermit 7.0 now that most modern computers and connections
-support it. If transfers fail with fast settings, try . . .
-.TP
-CAUTIOUS
-Use cautious but not paranoid settings. File transfers, if they
-work, will go at medium speed. If not, try . . .
-.TP
-ROBUST
-Use the most robust, resilient, conservative, safe, and reliable
-settings. File transfers will almost certainly work, but they
-will be quite slow (of course this is a classic tradeoff; ROBUST
-was C\(hyKermit's default tuning in versions 6.0 and earlier, which
-made everybody think Kermit protocol was slow). If ROBUST doesn't
-do the trick, try again with SET PARITY SPACE first in case it's
-not an 8\(hybit connection.
-.RE
-.sp
-Obviously the success and performance of a file transfer also depends
-on C\(hyKermit's file transfer partner. Up\(hyto\(hydate, real Kermit Project
-partners are recommended because they contain the best Kermit protocol
-implementations and because we can support them in case of trouble.
-.sp
-If you still have trouble, consult Chapter 10 of Using C\(hyKermit, or
-send email to kermit\(hysupport@columbia.edu.
-.TP
-Advanced Kermit File\(hyTransfer Features
-Obviously there is a lot more to Kermit file transfer, including all
-sorts of interactive commands, preferences, options, logging,
-debugging, troubleshooting, and anything else you can imagine but
-that's what the manual and updates are for. Here are a few topics you
-can explore if you're interested by Typing HELP for the listed
-commands:
-.RS
-.TP
-Logging transfers:
-LOG TRANSACTIONS (HELP LOG)
-.TP
-Automatic per\(hyfile text/binary mode switching:
-SET TRANSFER MODE { AUTOMATIC, MANUAL } (HELP SET TRANSFER).
-.TP
-Cross\(hyplatform recursive directory tree transfer:
-SEND /RECURSIVE, GET /RECURSIVE (HELP SEND, HELP GET).
-.TP
-File collision options:
-SET FILE COLLISION { OVERWRITE, BACKUP, DISCARD, ... } (HELP SET FILE).
-.TP
-Update: Transfer only files that changed since last time:
-SET FILE COLLISION UPDATE (HELP SET FILE).
-.TP
-Filename selection patterns:
-(HELP WILDCARD).
-.TP
-Flexible file selection:
-SEND (or GET) /BEFORE /AFTER /LARGER /SMALLER /TYPE /EXCEPT, ...
-.TP
-Character\(hyset conversion:
-SET { FILE, TRANSFER } CHARACTER\-SET, ASSOCIATE, ...
-.TP
-File/Pathname control:
-SET { SEND, RECEIVE } PATHNAMES, SET FILE NAMES.
-.TP
-Atomic file movement:
-SEND (or GET) /DELETE /RENAME /MOVE\-TO
-.TP
-Transferring to/from standard i/o of other commands:
-SEND (or GET) /COMMAND
-.TP
-Recovery of interrupted transfer from point of failure:
-RESEND, REGET (HELP RESEND, HELP REGET).
-.RE
-.TP
-Non\(hyKermit File Transfer
-You can also use C\(hyKermit to transfer files with FTP or HTTP Internet
-protocols; see below.
-.sp
-On a regular serial or Telnet connection where the other computer
-doesn't support Kermit protocol at all, you have several options. For
-example, if your desktop communications software supports Zmodem, use
-"rz" and "sz" on the host rather than Kermit. But if Kermit is your
-desktop software, and you are using it to make calls or network
-connections to other computers that don't support Kermit protocol (or
-that don't have a good implementation of it), then if your computer
-also has external X, Y, or Zmodem programs that are redirectable,
-Kermit can use them as external protocols. HELP SET PROTOCOL for
-details.
-.sp
-You can also capture "raw" data streams from the other computer with
-LOG SESSION (HELP LOG and HELP SET SESSION\-LOG for details), and you
-can upload files without any protocol at all with TRANSMIT (HELP
-TRANSMIT, HELP SET TRANSMIT).
-.SH KERMIT'S BUILT\(hyIN FTP AND HTTP CLIENTS
-Kermit's FTP client is like the regular Unix FTP client that you're used
-to, but with some differences:
-.TP
-\(bu
-It has lots more commands and features.
-.TP
-\(bu
-Each FTP command must be prefixed with "ftp", for example "ftp open",
-"ftp get", "ftp bye", etc (this is not strictly true, but until you're
-more familiar with it, it's best to follow this rule).
-.TP
-\(bu
-Commands like "cd", "directory", etc, execute locally, not on the
-server. Use "ftp cd", "ftp dir", etc, to have them act on the server.
-.TP
-\(bu
-You can have an FTP session and a regular Kermit serial or Telnet
-session open at the same time.
-.TP
-\(bu
-FTP sessions can be fully automated.
-.PP
-Pending publication of the next edition of the manual, the Kermit FTP
-client is thoroughly documented at the Kermit Project website:
-.sp
- http://www.columbia.edu/kermit/ftpclient.html
-.sp
-You also can use HELP FTP and HELP SET FTP to get descriptions of Kermit's
-FTP\(hyrelated commands.
-.PP
-The HTTP client is similar to the FTP one, except you prefix each command
-with HTTP instead of FTP: HTTP OPEN, HTTP GET, HTTP PUT, HTTP CLOSE, etc.
-Type HELP HTTP for details, or visit the to view the manual supplements.
-HTTP connections can be open at the same time as regular serial or Telnet
-connections and FTP connections. So Kermit can manage up to three types
-connections simultaneously.
-.SH INTERNET KERMIT SERVICE
-C\(hyKermit can be configured and run as an Internet service (called IKSD),
-similar to an FTP server (FTPD) except you can (but need not) interact with
-it directly, plus it does a lot more than an FTP server can do. The TCP
-port for IKSD is 1649. It uses Telnet protocol. C\(hyKermit can be an Internet
-Kermit Server, or it can be a client of an IKSD. You can make connections
-from C\(hyKermit to an IKSD with any of the following commands:
-.sp
-.nf
- telnet foo.bar.edu 1649
- telnet foo.bar.edu kermit ; if "kermit" is listed in /etc/services
- iksd foo.bar.edu
-.fi
-.sp
-The IKSD command is equivalent to a TELNET command specifying port 1649.
-For more information about making and using connections to an IKSD, see:
-.sp
- http://www.columbia.edu/kermit/cuiksd.html
-.sp
-You can run an Internet Kermit Service on your own computer too (if you are
-the system administrator). For instructions, see:
-.sp
- http://www.columbia.edu/kermit/iksd.html
-.SH SECURITY
-All of C\(hyKermit's built\(hyin TCP/IP networking methods (Telnet, Rlogin, IKSD,
-FTP, and HTTP) can be secured by one or more of the following IETF\(hyapproved
-methods:
-.PP
-\(bu MIT Kerberos IV
-.br
-\(bu MIT Kerberos V
-.br
-\(bu SSL/TLS
-.br
-\(bu Stanford SRP
-.PP
-For complete instructions see:
-.PP
- http://www.columbia.edu/kermit/security.html
-.PP
-And as noted previously, you can also make SSH connections with C\(hyKermit if
-you already have an SSH client installed.
-.SH ALTERNATIVE COMMAND\(hyLINE PERSONALITIES
-When invoked as "kermit" or any other name besides "ftp" or "telnet",
-C\(hyKermit has the command\(hyline options described above in the OPTIONS
-section. However, if you invoke C\(hyKermit as "telnet" or "ftp", it changes
-its command\(hyline personality to match. This can be done (among other ways)
-with symbolic links (symlinks). For example, if you want C\(hyKermit to be
-your regular Telnet client, or the Telnet helper of your Web browser, you
-can create a link like the following in a directory that lies in your PATH
-ahead of the regular telnet program:
-.sp
- ln \-s /usr/local/bin/kermit telnet
-.sp
-Now when you give a "telnet" command, you are invoking Kermit instead, but
-with its Telnet command\(hyline personality so, for example:
-.sp
- telnet xyzcorp.com
-.sp
-Makes a Telnet connection to xyzcorp.com, and Kermit exits automatically
-when the connection is closed (just like the regular Telnet client). Type
-"telnet \-h" to get a list of Kermit's Telnet\(hypersonality command\(hyline
-options, which are intended to be as compatible as possible with the
-regular Telnet client.
-.PP
-Similarly for FTP:
-.sp
- ln \-s /usr/local/bin/kermit ftp
-.sp
-And now type "ftp \-h" to see its command\(hyline options, and command lines
-just like you would give your regular FTP client:
-.sp
- ftp xyzcorp.com
-.sp
-but with additional options allowing an entire session to be specified on
-the command line. Finally, if Kermit's
-first command\(hyline option is a Telnet, FTP, IKSD, or HTTP URL, Kermit
-automatically makes the appropriate kind of connection and, if indicated by
-the URL, takes the desired action:
-.TP
-kermit telnet:xyzcorp.com
-Opens a Telnet session
-.TP
-kermit telnet://olga@xyzcorp.com
-Ditto for user olga
-.TP
-kermit ftp://olga@xyzcorp.com/public/oofa.zip
-Downloads a file
-.TP
-kermit kermit://kermit.columbia.edu/kermit/f/READ.ME
-Ditto for IKSD
-.TP
-kermit iksd://kermit.columbia.edu/kermit/f/READ.ME
-(This works too)
-.TP
-kermit http://www.columbia.edu/kermit/index.html
-Grabs a web page
-.fi
-.SH LICENSE
-C\(hyKermit has an unusual license, but a fair and sensible one since the
-Kermit Project must support itself out of revenue: it's not a BSD license,
-not GPL, not Artistic, not commercial, not shareware, not freeware. It can
-be summed up like this: if you want C\(hyKermit for your own use, you can
-download and use it without cost or license (but we'd appreciate it if you
-would purchase the manual). But if you want to sell C\(hyKermit or bundle it
-with a product or otherwise distribute it in a commercial setting EXCEPT
-WITH AN OPEN\(hySOURCE OPERATING SYSTEM DISTRIBUTION such as Linux, FreeBSD,
-NetBSD, or OpenBSD, you must license it. To see the complete license, give
-the LICENSE command at the prompt, or see the COPYING.TXT file distributed
-with C\(hyKermit 7.0 or later, or download it from
-.sp
- ftp://kermit.columbia.edu/kermit/c\-kermit/COPYING.TXT
-.sp
-Send licensing inquiries to kermit@columbia.edu.
-.SH BUGS
-See the following files for listings of known bugs, limitations,
-workarounds, hints and tips:
-.TP
-ckcbwr.txt
-General C\(hyKermit bugs, hints, tips.
-.TP
-ckubwr.txt
-Unix\(hyspecific C\(hyKermit bugs, hints, tips.
-.PP
-Report bugs and problems by email to:
-.sp
- kermit\-support@columbia.edu.
-.sp
-Before requesting technical support, please read the hints here:
-.sp
- http://www.columbia.edu/kermit/support.html
-.sp
-and also read the C\(hyKermit Frequently Asked Questions:
-.sp
- http://www.columbia.edu/kermit/ckfaq.html
-.SH OTHER TOPICS
-There's way more to C\(hyKermit than we've touched on here \(hy\(hy troubleshooting,
-customization, character sets, dialing directories, sending pages, script
-writing, and on and on, all of which are covered in the manual and updates
-and supplements. For the most up\(hyto\(hydate information on documentation (or
-updated documentation itself) visit the Kermit Project website:
-.sp
- http://www.columbia.edu/kermit/
-.PP
-There you will also find Kermit software packages for other platforms:
-different Unix varieties, Windows, DOS, VMS, IBM mainframes, and many
-others: 20+ years' worth.
-.SH DOCUMENTATION AND UPDATES
-The manual for C\(hyKermit is:
-.TP
-.I
-Using C\(hyKermit
-Frank da Cruz and Christine M. Gianone,
-Second Edition, Digital Press / Butterworth\(hyHeinemann, Woburn, MA, 1997, 622
-pages, ISBN 1\-55558\-164\-1. This is a printed book. It covers C\(hyKermit 6.0.
-.TP
-The C\(hyKermit 7.0 Supplement
-http://www.columbia.edu/kermit/ckermit70.html
-.TP
-The C\(hyKermit 8.0 Supplement
-http://www.columbia.edu/kermit/ckermit80.html
-.TP
-The C\(hyKermit 9.0 Supplement
-http://www.columbia.edu/kermit/ckermit90.html
-.PP
-Visit C\(hyKermit home page:
-.sp
- http://www.columbia.edu/kermit/ckermit.html
-.sp
-to learn about new versions, Beta tests, and other news; to
-read case studies and tutorials; to download source code, install packages,
-and prebuilt binaries for many platforms. Also visit:
-.TP
-http://www.columbia.edu/kermit/scriptlib.html
-The Kermit script library and tutorial
-.TP
-http://www.columbia.edu/kermit/newfaq.html
-The Kermit FAQ (Frequently Asked Questions about Kermit)
-.TP
-http://www.columbia.edu/kermit/ckfaq.html
-The C\(hyKermit FAQ (Frequently Asked Questions about C\(hyKermit)
-.TP
-http://www.columbia.edu/kermit/telnet.html
-C\(hyKermit Telnet client documentation
-.TP
-http://www.columbia.edu/kermit/security.html
-C\(hyKermit security documentation (Kerberos, SSL/TLS, etc)
-.TP
-http://www.columbia.edu/kermit/cuiksd.html
-Internet Kermit Service user documentation
-.TP
-http://www.columbia.edu/kermit/iksd.html
-Internet Kermit Service administrator documentation
-.TP
-http://www.columbia.edu/kermit/studies.html
-Case studies.
-.TP
-http://www.columbia.edu/kermit/support.html
-Technical support.
-.TP
-http://www.columbia.edu/kermit/k95tutorial.html
-Kermit 95 tutorial.
-.TP
-comp.protocols.kermit.misc
-The Kermit newsgroup (unmoderated).
-.SH FILES
-.TP
-COPYING.TXT
-C\(hyKermit license.
-.TP
-~/.kermrc
-Initialization file.
-.TP
-~/.mykermrc
-Customization file.
-.TP
-~/.kdd
-Kermit dialing directory (see manual).
-.TP
-~/.knd
-Kermit network directory (see manual).
-.TP
-~/.ksd
-Kermit services directory (see manual).
-.TP
-ca_certs.pem
-Certificate Authority certifcates used for SSL connections.
-.TP
-ckuins.txt
-Installation instructions for Unix. Also at
-http://www.columbia.edu/kermit/ckuins.html.
-.TP
-ckcbwr.txt
-General C\(hyKermit bugs, hints, tips.
-.TP
-ckubwr.txt
-Unix\(hyspecific C\(hyKermit bugs, hints, tips.
-.TP
-ckcplm.txt
-C\(hyKermit program logic manual.
-.TP
-ckccfg.txt
-C\(hyKermit compile\(hytime configuration options.
-.TP
-ssh
-(in your PATH) SSH connection helper.
-.TP
-rz, sz, etc.
-(in your PATH) external protocols for XYZmodem.
-.TP
-/var/spool/locks (or whatever)
-UUCP lockfile for dialing out (see installation instructions).
-.SH AUTHORS
-.TP
-Software
-Frank da Cruz and Jeffrey E Altman,
-.br
-1985\(hypresent, with contributions from hundreds of others all over the
-world.
-.TP
-Documentation
-Frank da Cruz
-.TP
-Address
-.nf
-The Kermit Project \(hy Columbia Univerity
-612 West 115th Street
-New York NY 10025\-7799
-USA
-.fi
-.TP
-E\(hyMail
-kermit@columbia.edu
-.TP
-Web
-http://www.columbia.edu/kermit/
-.fi
-.br
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckupty.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckupty.c
deleted file mode 100644
index 8e0476b..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckupty.c
+++ /dev/null
@@ -1,1983 +0,0 @@
-char *ckptyv = "Pseudoterminal support, 9.0.101, 13 Jun 2011";
-
-/* C K U P T Y -- C-Kermit pseudoterminal control functions for UNIX */
-
-/* Last update: Mon Jun 13 11:32:52 2011 */
-
-/*
- Copyright 1995 by the Massachusetts Institute of Technology.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted, provided
- that the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation, and that the name of M.I.T. not be used in advertising or
- publicity pertaining to distribution of the software without specific,
- written prior permission. Furthermore if you modify this software you must
- label your software as modified software and not distribute it in such a
- fashion that it might be confused with the original M.I.T. software.
- M.I.T. makes no representations about the suitability of this software for
- any purpose. It is provided "as is" without express or implied warranty.
-
- Modified for use in C-Kermit, and new material added, by:
-
- Jeffrey Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
- November 1999
-
- Parameterized for pty file descriptor and function code,
- Frank da Cruz, Columbia University, New York City
- Dec 2006 - Sep 2009
-*/
-
-/*
- Built and tested successully on:
- . 4.4BSD, including BSDI/OS, NetBSD, FreeBSD, OpenBSD, Mac OS X
- . AIX 4.1 and later
- . DG/UX 5.4R4.11
- . Digital UNIX 3.2 and 4.0
- . HP-UX 9.00 and later
- . IRIX 6.0 and later
- . Linux
- . Mac OS X 10.4
- . NeXTSTEP 3.x
- . OpenBSD
- . QNX 4.25 (except PTY process termination not detected)
- . SCO OSR5.0.5
- . SCO Unixware 7
- . SINIX 5.42
- . Solaris 2.x and 7
- . SunOS 4.1.3
-
- Failures include:
- . SCO UNIX 3.2v4.2 (compile fails with syntax error in <memory.h>)
- . HP-UX 8.00 and earlier (no vhangup or ptsname routines)
-*/
-
-#include "ckcsym.h"
-#include "ckcdeb.h" /* To pick up NETPTY definition */
-
-#ifndef NETPTY /* Selector for PTY support */
-
-char * ptyver = "No PTY support";
-
-#else /* (rest of this module...) */
-
-char * ptyver = "PTY support 8.0.016, 22 Aug 2007";
-
-/* These will no doubt need adjustment... */
-
-#ifndef NEXT
-#define HAVE_SETSID
-#endif /* NEXT */
-#define HAVE_KILLPG
-#define HAVE_TTYNAME
-#define HAVE_WAITPID
-
-#ifdef SUNOS41
-#define BSD44ORPOSIX
-#endif /* SUNOS41 */
-
-#ifndef USE_TERMIO
-#ifdef LINUX
-#define USE_TERMIO
-#else
-#ifdef ATTSV
-#define USE_TERMIO
-#else
-#ifdef HPUX
-#define USE_TERMIO
-#else
-#ifdef AIX
-#define USE_TERMIO
-#else
-#ifdef BSD44ORPOSIX
-#define USE_TERMIO
-#else
-#ifdef IRIX60
-#define USE_TERMIO
-#else
-#ifdef QNX
-#define USE_TERMIO
-#endif /* QNX */
-#endif /* IRIX60 */
-#endif /* BSD44ORPOSIX */
-#endif /* AIX */
-#endif /* HPUX */
-#endif /* ATTSV */
-#endif /* LINUX */
-#endif /* USE_TERMIO */
-
-#ifdef QNX
-#include <fcntl.h>
-#endif /* QNX */
-
-#ifdef USE_TERMIO
-#define POSIX_TERMIOS /* Seems to be a misnomer */
-#endif /* USE_TERMIO */
-
-#ifdef NEXT
-#ifndef GETPGRP_ONEARG
-#define GETPGRP_ONEARG
-#endif /* GETPGRP_ONEARG */
-#endif /* NEXT */
-
-#ifdef WANT_UTMP /* See ckupty.h */
-/*
- WANT_UTMP is not defined because (a) the utmp/wtmp junk is the most
- nonportable part of this module, and (b) we're not logging anybody
- in, we're just running a process, and don't need to write utmp/wtmp records.
-*/
-#ifndef HAVE_SETUTXENT /* Who has <utmpx.h> */
-#ifdef SOLARIS
-#define HAVE_SETUTXENT
-#else
-#ifdef IRIX60
-#define HAVE_SETUTXENT
-#else
-#ifdef CK_SCOV5
-#define HAVE_SETUTXENT
-#else
-#ifdef HPUX10
-#define HAVE_SETUTXENT
-#else
-#ifdef UNIXWARE
-#define HAVE_SETUTXENT
-#else
-#ifdef IRIX60
-#define HAVE_SETUTXENT
-#endif /* IRIX60 */
-#endif /* UNIXWARE */
-#endif /* HPUX10 */
-#endif /* CK_SCOV5 */
-#endif /* IRIX60 */
-#endif /* SOLARIS */
-#endif /* HAVE_SETUTXENT */
-
-#ifndef HAVE_UTHOST /* Does utmp include ut_host[]? */
-#ifdef HAVE_SETUTXENT /* utmpx always does */
-#define HAVE_UTHOST
-#else
-#ifdef LINUX /* Linux does */
-#define HAVE_UTHOST
-#else
-#ifdef SUNOS4 /* SunOS does */
-#define HAVE_UTHOST
-#else
-#ifdef AIX41 /* AIX 4.1 and later do */
-#define HAVE_UTHOST
-#endif /* AIX41 */
-#endif /* SUNOS4 */
-#endif /* LINUX */
-#endif /* HAVE_SETUTXENT */
-#endif /* HAVE_UTHOST */
-
-#ifndef HAVE_UT_HOST
-#ifndef NO_UT_HOST
-#define NO_UT_HOST
-#endif /* NO_UT_HOST */
-#endif /* HAVE_UT_HOST */
-
-#endif /* WANT_UTMP */
-
-#ifdef LINUX
-#define CK_VHANGUP
-#define HAVE_SYS_SELECT_H
-#define HAVE_GETUTENT
-#define HAVE_SETUTENT
-#define HAVE_UPDWTMP
-#endif /* LINUX */
-
-#ifdef HPUX10
-#define CK_VHANGUP
-#define VHANG_FIRST
-#define HAVE_PTSNAME
-#ifndef HAVE_PTYTRAP
-#define HAVE_PTYTRAP
-#endif /* HAVE_PTYTRAP */
-#else
-#ifdef HPUX9
-#define CK_VHANGUP
-#define VHANG_FIRST
-#define HAVE_PTSNAME
-#ifndef HAVE_PTYTRAP
-#define HAVE_PTYTRAP
-#endif /* HAVE_PTYTRAP */
-#endif /* HPUX9 */
-#endif /* HPUX10 */
-
-#ifdef SUNOS4
-#define CK_VHANGUP
-#define NO_UT_PID
-#define VHANG_FIRST
-#endif /* SUNOS4 */
-
-#ifdef IRIX60
-#define CK_VHANGUP
-#define HAVE__GETPTY
-#endif /* IRIX60 */
-
-#ifdef SINIX
-#define HAVE_STREAMS
-#define HAVE_GRANTPT
-#define HAVE_PTSNAME
-#define PUSH_PTEM
-#define PUSH_LDTERM
-#define PUSH_TTCOMPAT
-#endif /* SINIX */
-
-#ifdef ultrix
-#define MUST_SETPGRP
-#endif /* ultrix */
-
-#ifdef QNX
-#define MUST_SETPGRP
-#define NO_DEVTTY
-#define INIT_SPTY
-#endif /* QNX */
-
-#ifdef LINUX
-#ifdef HAVE_PTMX
-#define HAVE_GRANTPT
-#define HAVE_PTSNAME
-#endif /* HAVE_PTMX */
-#else
-#ifdef HAVE_STREAMS
-#define HAVE_PTMX
-#endif /* HAVE_STREAMS */
-#endif /* LINUX */
-
-#include "ckupty.h"
-
-#ifdef PTYNOBLOCK
-#ifndef O_NDELAY
-#ifdef O_NONBLOCK
-#define O_NDELAY O_NONBLOCK
-#endif /* O_NONBLOCK */
-#endif /* O_NDELAY */
-#else /* PTYNOBLOCK */
-#ifdef O_NDELAY
-#undef O_NDELAY
-#endif /* O_NDELAY */
-#define O_NDELAY 0
-#endif /* PTYNOBLOCK */
-
-#ifndef ONLCR
-#define ONLCR 0
-#endif /* ONLCR */
-
-#ifdef CK_WAIT_H
-#include <sys/wait.h>
-#endif /* CK_WAIT_H */
-
-#ifdef STREAMSPTY
-#ifndef INIT_SPTY
-#define INIT_SPTY
-#endif /* INIT_SPTY */
-
-#include <sys/stream.h>
-#include <stropts.h>
-#include <termio.h>
-
-/* Make sure we don't get the BSD version */
-
-#ifdef HAVE_SYS_TTY_H
-#include "/usr/include/sys/tty.h"
-#endif /* HAVE_SYS_TTY_H */
-
-#ifdef HAS_PTYVAR /* Where is this set? */
-
-#include <sys/ptyvar.h>
-
-#else /* HAS_PTYVAR */
-
-#ifndef TIOCPKT_FLUSHWRITE
-#define TIOCPKT_FLUSHWRITE 0x02
-#define TIOCPKT_NOSTOP 0x10
-#define TIOCPKT_DOSTOP 0x20
-#define TIOCPKT_IOCTL 0x40
-#endif /* TIOCPKT_FLUSHWRITE */
-
-#endif /* HAS_PTYVAR */
-
-#ifdef HAVE_TTY_H
-#include <tty.h>
-#endif /* HAVE_TTY_H */
-
-/*
- Because of the way ptyibuf is used with streams messages, we need
- ptyibuf+1 to be on a full-word boundary. The following weirdness
- is simply to make that happen.
-*/
-long ptyibufbuf[BUFSIZ/sizeof(long)+1];
-char *ptyibuf = ((char *)&ptyibufbuf[1])-1;
-char *ptyip = ((char *)&ptyibufbuf[1])-1;
-char ptyibuf2[BUFSIZ];
-unsigned char ctlbuf[BUFSIZ];
-struct strbuf strbufc, strbufd;
-
-int readstream();
-
-#else /* ! STREAMSPTY */
-
-/* I/O data buffers, pointers, and counters. */
-
-char ptyibuf[BUFSIZ], *ptyip = ptyibuf;
-char ptyibuf2[BUFSIZ];
-
-#endif /* ! STREAMSPTY */
-
-#ifndef USE_TERMIO
-struct termbuf {
- struct sgttyb sg;
- struct tchars tc;
- struct ltchars ltc;
- int state;
- int lflags;
-} termbuf, termbuf2;
-
-#define cfsetospeed(tp,val) (tp)->sg.sg_ospeed = (val)
-#define cfsetispeed(tp,val) (tp)->sg.sg_ispeed = (val)
-#define cfgetospeed(tp) (tp)->sg.sg_ospeed
-#define cfgetispeed(tp) (tp)->sg.sg_ispeed
-
-#else /* USE_TERMIO */
-
-#ifdef SYSV_TERMIO
-#define termios termio
-#endif /* SYSV_TERMIO */
-
-#ifndef TCSANOW
-
-#ifdef TCSETS
-
-#define TCSANOW TCSETS
-#define TCSADRAIN TCSETSW
-#define tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
-
-#else /* TCSETS */
-
-#ifdef TCSETA
-#define TCSANOW TCSETA
-#define TCSADRAIN TCSETAW
-#define tcgetattr(f,t) ioctl(f,TCGETA,(char *)t)
-#else /* TCSETA */
-#define TCSANOW TIOCSETA
-#define TCSADRAIN TIOCSETAW
-#define tcgetattr(f,t) ioctl(f,TIOCGETA,(char *)t)
-#endif /* TCSETA */
-
-#endif /* TCSETS */
-
-#define tcsetattr(f,a,t) ioctl(f,a,t)
-#define cfsetospeed(tp,val) (tp)->c_cflag &= ~CBAUD;(tp)->c_cflag|=(val)
-#define cfgetospeed(tp) ((tp)->c_cflag & CBAUD)
-
-#ifdef CIBAUD
-#define cfsetispeed(tp,val) \
- (tp)->c_cflag &= ~CIBAUD; (tp)->c_cflag |= ((val)<<IBSHIFT)
-#define cfgetispeed(tp) (((tp)->c_cflag & CIBAUD)>>IBSHIFT)
-#else /* CIBAUD */
-#define cfsetispeed(tp,val) (tp)->c_cflag &= ~CBAUD; (tp)->c_cflag|=(val)
-#define cfgetispeed(tp) ((tp)->c_cflag & CBAUD)
-#endif /* CIBAUD */
-
-#endif /* TCSANOW */
-
-#ifdef HAVE_OPENPTY
-#include <pty.h>
-#endif
-
-struct termios termbuf, termbuf2; /* pty control structure */
-
-#ifdef INIT_SPTY
-static int spty = -1;
-#endif /* INIT_SPTY */
-
-#endif /* USE_TERMIO */
-
-#ifdef QNX /* 299 */
-#ifndef IXANY
-#define IXANY 0
-#endif /* IXANY */
-#endif /* QNX */
-
-static int msg = 0;
-
-/* Variables available to other modules */
-
-int pty_fork_active = 0; /* pty fork is active */
-PID_T pty_fork_pid = -1; /* pty fork pid */
-int pty_slave_fd = -1; /* pty slave file descriptor */
-int pty_master_fd = -1; /* pty master file descriptor */
-
-/* termbuf routines (begin) */
-/*
- init_termbuf()
- copy_termbuf(cp)
- set_termbuf()
-
- These three routines are used to get and set the "termbuf" structure
- to and from the kernel. init_termbuf() gets the current settings.
- copy_termbuf() hands in a new "termbuf" to write to the kernel, and
- set_termbuf() writes the structure into the kernel.
-*/
-VOID
-init_termbuf(fd) int fd; {
- int ttyfd;
- int rc = 0;
-
- ttyfd = fd;
-
-#ifdef HAVE_STREAMS
- debug(F100,"init_termbuf HAVE_STREAMS","",0);
-#else
- debug(F100,"init_termbuf HAVE_STREAMS NOT DEFINED","",0);
-#endif /* HAVE_STREAMS */
-#ifdef STREAMSPTY
- debug(F100,"init_termbuf STREAMSPTY","",0);
-#else
- debug(F100,"init_termbuf STREAMSPTY NOT DEFINED","",0);
-#endif /* STREAMSPTY */
-#ifdef INIT_SPTY
- debug(F100,"init_termbuf INIT_SPTY","",0);
-#else
- debug(F100,"init_termbuf INIT_SPTY NOT DEFINED","",0);
-#endif /* INIT_SPTY */
-
- debug(F101,"init_termbuf ttyfd","",ttyfd);
-#ifdef INIT_SPTY
- debug(F101,"init_termbuf spty","",spty);
-#endif /* INIT_SPTY */
-
- memset(&termbuf,0,sizeof(termbuf));
- memset(&termbuf2,0,sizeof(termbuf2));
-#ifndef USE_TERMIO
- rc = ioctl(ttyfd, TIOCGETP, (char *)&termbuf.sg);
- rc |= ioctl(ttyfd, TIOCGETC, (char *)&termbuf.tc);
- rc |= ioctl(ttyfd, TIOCGLTC, (char *)&termbuf.ltc);
-#ifdef TIOCGSTATE
- rc |= ioctl(ttyfd, TIOCGSTATE, (char *)&termbuf.state);
-#endif /* TIOCGSTATE */
-#else /* USE_TERMIO */
- errno = 0;
-#ifdef INIT_SPTY
- rc = tcgetattr(spty, &termbuf);
- debug(F111,"init_termbuf() tcgetattr(spty)",ckitoa(rc),errno);
-#else
- rc = tcgetattr(ttyfd, &termbuf);
- debug(F111,"init_termbuf() tcgetattr(ttyfd)",ckitoa(rc),errno);
-#endif /* INIT_SPTY */
-#endif /* USE_TERMIO */
- if (!rc)
- termbuf2 = termbuf;
-}
-
-#ifdef TIOCPKT_IOCTL
-VOID
-copy_termbuf(cp, len) char *cp; int len; {
- if (len > sizeof(termbuf))
- len = sizeof(termbuf);
- memcpy((char *)&termbuf, cp, len);
- termbuf2 = termbuf;
-}
-#endif /* TIOCPKT_IOCTL */
-
-VOID
-set_termbuf(fd) int fd; { /* Only make the necessary changes. */
- int x;
- int ttyfd;
- ttyfd = fd;
-
- debug(F101,"set_termbuf ttyfd","",ttyfd);
-#ifdef INIT_SPTY
- debug(F101,"set_termbuf spty","",spty);
-#endif /* INIT_SPTY */
-
-#ifndef USE_TERMIO
- debug(F100,"set_termbuf USE_TERMIO","",0);
- if (memcmp((char *)&termbuf.sg, (char *)&termbuf2.sg, sizeof(termbuf.sg)))
- ioctl(ttyfd, TIOCSETN, (char *)&termbuf.sg);
- if (memcmp((char *)&termbuf.tc, (char *)&termbuf2.tc, sizeof(termbuf.tc)))
- ioctl(ttyfd, TIOCSETC, (char *)&termbuf.tc);
- if (memcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc,
- sizeof(termbuf.ltc)))
- ioctl(ttyfd, TIOCSLTC, (char *)&termbuf.ltc);
- if (termbuf.lflags != termbuf2.lflags)
- ioctl(ttyfd, TIOCLSET, (char *)&termbuf.lflags);
-#else /* USE_TERMIO */
- x = memcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf));
- debug(F101,"set_termbuf !USE_TERMIO memcmp","",x);
- x = 1; /* Force this */
- if (x) {
- int x;
- errno = 0;
-#ifdef INIT_SPTY
- debug(F100,"set_termbuf INIT_SPTY","",0);
- x = tcsetattr(spty, TCSANOW, &termbuf);
- debug(F111,"set_termbuf tcsetattr(spty)",ckitoa(x),errno);
-#else
- debug(F100,"set_termbuf !INIT_SPTY","",0);
- x = tcsetattr(ttyfd, TCSANOW, &termbuf);
- debug(F111,"set_termbuf tcsetattr(ttyfd)",ckitoa(x),errno);
-#endif /* INIT_SPTY */
- }
-#endif /* USE_TERMIO */
-}
-/* termbuf routines (end) */
-
-VOID
-ptyint_vhangup() {
-#ifdef CK_VHANGUP
-#ifdef CK_POSIX_SIG
- struct sigaction sa;
- /* Initialize "sa" structure. */
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- sigaction(SIGHUP, &sa, (struct sigaction *)0);
- vhangup();
- sa.sa_handler = SIG_DFL;
- sigaction(SIGHUP, &sa, (struct sigaction *)0);
-#else /* CK_POSIX_SIG */
- signal(SIGHUP,SIG_IGN);
- vhangup();
- signal(SIGHUP,SIG_DFL);
-#endif /* CK_POSIX_SIG */
-#endif /* CK_VHANGUP */
-}
-
-/*
- This routine is called twice. It's not particularly important that the
- setsid() or TIOCSCTTY ioctls succeed (they may not the second time), but
- rather that we have a controlling terminal at the end. It is assumed that
- vhangup doesn't exist and confuse the process's notion of controlling
- terminal on any system without TIOCNOTTY. That is, either vhangup() leaves
- the controlling terminal in tact, breaks the association completely, or the
- system provides TIOCNOTTY to get things back into a reasonable state. In
- practice, vhangup() either breaks the association completely or doesn't
- effect controlling terminals, so this condition is met.
-*/
-long
-ptyint_void_association() {
- int con_fd;
-#ifdef HAVE_SETSID
- debug(F110,
- "ptyint_void_association()",
- "setsid()",
- 0
- );
- setsid();
-#endif /* HAVE_SETSID */
-
-#ifndef NO_DEVTTY
- /* Void tty association first */
-#ifdef TIOCNOTTY
- con_fd = open("/dev/tty", O_RDWR);
- debug(F111,
- "ptyint_void_association() open(/dev/tty,O_RDWR)",
- "/dev/tty",
- con_fd);
- if (con_fd >= 0) {
- ioctl(con_fd, TIOCNOTTY, 0);
- close(con_fd);
- }
-#ifdef DEBUG
- else debug(F101, "ptyint_void_association() open() errno","",errno);
-#endif /* DEBUG */
-#endif /* TIOCNOTTY */
-#endif /* NO_DEVTTY */
- return(0);
-}
-
-/* PID may be zero for unknown.*/
-
-long
-pty_cleanup(slave, pid, update_utmp) char *slave; int pid; int update_utmp; {
-#ifdef VHANG_LAST
- int retval, fd;
-#endif /* VHANG_LAST */
-
- debug(F111,"pty_cleanup()",slave,pid);
-#ifdef WANT_UTMP
- if (update_utmp)
- pty_update_utmp(PTY_DEAD_PROCESS,
- 0,
- "",
- slave,
- (char *)0,
- PTY_UTMP_USERNAME_VALID
- );
-#endif /* WANT_UTMP */
-
-#ifdef SETUID
- chmod(slave, 0666);
- chown(slave, 0, 0);
-#endif /* SETUID */
-
-#ifdef HAVE_REVOKE
- revoke(slave);
- /*
- Revoke isn't guaranteed to send a SIGHUP to the processes it
- dissociates from the terminal. The best solution without a Posix
- mechanism for forcing a hangup is to killpg() the process group of the
- pty. This will at least kill the shell and hopefully, the child
- processes. This is not always the case, however. If the shell puts
- each job in a process group and doesn't pass along SIGHUP, all
- processes may not die.
- */
- if (pid > 0) {
-#ifdef HAVE_KILLPG
- killpg(pid, SIGHUP);
-#else
- kill(-(pid), SIGHUP);
-#endif /*HAVE_KILLPG*/
- }
-#else /* HAVE_REVOKE*/
-#ifdef VHANG_LAST
- {
- int status;
-#ifdef CK_POSIX_SIG
- sigset_t old, new;
- sigemptyset(&new);
- sigaddset(&new, SIGCHLD);
- sigprocmask(SIG_BLOCK, &new, &old);
-#else /*CK_POSIX_SIG*/
- int mask = sigblock(sigmask(SIGCHLD));
-#endif /*CK_POSIX_SIG*/
- switch (retval = fork()) {
- case -1:
-#ifdef CK_POSIX_SIG
- sigprocmask(SIG_SETMASK, &old, 0);
-#else /*CK_POSIX_SIG*/
- sigsetmask(mask);
-#endif /*CK_POSIX_SIG*/
- return errno;
- case 0:
- ptyint_void_association();
- if (retval = (pty_open_ctty(slave, &fd, -1)))
- exit(retval);
- ptyint_vhangup();
- exit(0);
- break;
- default:
-#ifdef HAVE_WAITPID
- waitpid(retval, &status, 0);
-#else /*HAVE_WAITPID*/
- wait(&status);
-#endif /* HAVE_WAITPID */
-#ifdef CK_POSIX_SIG
- sigprocmask(SIG_SETMASK, &old, 0);
-#else /*CK_POSIX_SIG*/
- sigsetmask(mask);
-#endif /*CK_POSIX_SIG*/
- break;
- }
- }
-#endif /*VHANG_LAST*/
-#endif /* HAVE_REVOKE*/
-#ifndef HAVE_STREAMS
- slave[strlen("/dev/")] = 'p';
-#ifdef SETUID
- chmod(slave, 0666);
- chown(slave, 0, 0);
-#endif /* SETUID */
-#endif /* HAVE_STREAMS */
- return(0);
-}
-
-long
-pty_getpty(fd, slave, slavelength) int slavelength; int *fd; char *slave; {
- char *cp;
- char *p;
- int i, ptynum;
- struct stat stb;
-#ifndef HAVE_OPENPTY
-#ifndef HAVE__GETPTY
- char slavebuf[1024];
-#endif /* HAVE__GETPTY */
-#endif /* HAVE_OPENPTY */
-#ifdef HAVE__GETPTY
- char *slaveret; /* Temp to hold pointer to slave */
-#endif /*HAVE__GETPTY*/
-
-#ifdef HAVE_OPENPTY
- int slavefd;
-
- pty_master_fd = -1;
- debug(F100,"HAVE_OPENPTY","",0);
- if (openpty(fd,
- &slavefd,
- slave,
- (struct termios *)0,
- (struct winsize *)0
- )
- ) {
- pty_master_fd = *fd;
- return(1);
- }
- close(slavefd);
- return(0);
-
-#else /* HAVE_OPENPTY */
-
-#ifdef HAVE__GETPTY
-/*
- This code is included for Irix; as of version 5.3, Irix has /dev/ptmx, but
- it fails to work properly; even after calling unlockpt, root gets permission
- denied opening the pty. The code to support _getpty should be removed if
- Irix gets working streams ptys in favor of maintaining the least needed code
- paths.
-*/
- debug(F100,"HAVE__GETPTY","",0);
- if ((slaveret = _getpty(fd, O_RDWR | O_NDELAY, 0600, 0)) == 0) {
- *fd = -1;
- return(PTY_GETPTY_NOPTY);
- }
- if (strlen(slaveret) > slavelength - 1) {
- close(*fd);
- *fd = -1;
- return(PTY_GETPTY_SLAVE_TOOLONG);
- } else {
- ckstrncpy(slave, slaveret, slavelength);
- }
- return(0);
-
-#else /* HAVE__GETPTY */
-
- *fd = open("/dev/ptym/clone", O_RDWR|O_NDELAY); /* HPUX */
- if (*fd >= 0) {
- debug(F110,"pty_getpty()","open(/dev/ptym/clone) success",0);
- goto have_fd;
- }
-
-#ifdef HAVE_PTMX
- debug(F100,"HAVE_PTMX","",0);
- *fd = open("/dev/ptmx",O_RDWR|O_NDELAY);
- if (*fd >= 0) {
- debug(F110,"pty_getpty()","open(/dev/ptmx) success",0);
- goto have_fd;
- }
-#endif /* HAVE_PTMX */
-
- *fd = open("/dev/ptc", O_RDWR|O_NDELAY); /* AIX */
- if (*fd >= 0) {
- debug(F110,"pty_getpty()","open(/dev/ptc) success",0);
- goto have_fd;
- }
- *fd = open("/dev/pty", O_RDWR|O_NDELAY); /* sysvimp */
- if (*fd >= 0)
- debug(F110,"pty_getpty()","open(/dev/pty) success",0);
-
- have_fd:
- /* This would be the pty master */
- debug(F101,"pty_getpty fd(A)","",*fd);
- if (*fd >= 0) {
- pty_master_fd = *fd;
-
-#ifdef HAVE_GRANTPT
-#ifdef HAVE_PTMX
- debug(F100,"HAVE_GRANTPT","",0);
- if (grantpt(*fd) || unlockpt(*fd))
- return(PTY_GETPTY_STREAMS);
-#endif /* HAVE_PTMX */
-#endif /* HAVE_GRANTPT */
-
-#ifdef HAVE_PTSNAME
- debug(F100,"HAVE_PTSNAME","",0);
- p = (char *)ptsname(*fd);
- debug(F110,"pty_getpty() ptsname()",p,0);
-#else
-#ifdef HAVE_TTYNAME
- debug(F100,"HAVE_TTYNAME","",0);
- p = ttyname(*fd);
- debug(F110,"pty_getpty() ttyname()",p,0);
-#else
- /* If we don't have either what do we do? */
- return(PTY_GETPTY_NOPTY); /* punt */
-#endif /* HAVE_TTYNAME */
-#endif /* HAVE_PTSNAME */
- if (p) {
- if (strlen(p) > slavelength - 1) {
- close (*fd);
- *fd = -1;
- return(PTY_GETPTY_SLAVE_TOOLONG);
- }
- ckstrncpy(slave, p, slavelength);
- return(0);
- }
- if (fstat(*fd, &stb) < 0) {
- close(*fd);
- return(PTY_GETPTY_FSTAT);
- }
- ptynum = (int)(stb.st_rdev&0xFF);
- sprintf(slavebuf, "/dev/ttyp%x", ptynum); /* safe */
- if (strlen(slavebuf) > slavelength - 1) {
- close(*fd);
- *fd = -1;
- return(PTY_GETPTY_SLAVE_TOOLONG);
- }
- debug(F110,"pty_getpty() slavebuf",slavebuf,0);
- ckstrncpy(slave, slavebuf, slavelength);
- return(0);
- } else {
- for (cp = "pqrstuvwxyzPQRST";*cp; cp++) {
- sprintf(slavebuf,"/dev/ptyXX"); /* safe */
- slavebuf[sizeof("/dev/pty") - 1] = *cp;
- slavebuf[sizeof("/dev/ptyp") - 1] = '0';
- if (stat(slavebuf, &stb) < 0)
- break;
- for (i = 0; i < 16; i++) {
- slavebuf[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i];
- errno = 0;
- *fd = open(slavebuf, O_RDWR|O_NDELAY);
- if (*fd < 0) {
- debug(F111,"pty_getpty() pty master open error",
- slavebuf,errno);
- continue;
- }
- debug(F111,"pty_getpty() found pty master",slavebuf,*fd);
- slavebuf[sizeof("/dev/") - 1] = 't'; /* got pty */
- if (strlen(slavebuf) > slavelength -1) {
- close(*fd);
- *fd = -1;
- return(PTY_GETPTY_SLAVE_TOOLONG);
- }
- ckstrncpy(slave, slavebuf, slavelength);
- debug(F110,"pty_getpty slave name",slave,0);
- pty_master_fd = *fd;
- return(0);
- }
- }
- return(PTY_GETPTY_NOPTY);
- }
-#endif /*HAVE__GETPTY*/
-#endif /* HAVE_OPENPTY */
-}
-
-long
-pty_init() {
-#ifdef HAVE_PTYM
- static char dummy;
- debug(F100,"HAVE_PTYM","",0);
- tty_bank = &master_name[strlen("/dev/ptym/pty")];
- tty_num = &master_name[strlen("/dev/ptym/ptyX")];
- slave_bank = &slave_name[strlen("/dev/pty/tty")];
- slave_num = &slave_name[strlen("/dev/pty/ttyX")];
-#endif
- return(0L);
-}
-
-/*
- The following is an array of modules that should be pushed on the stream.
- See configure.in for caviats and notes about when this array is used and not
- used.
-*/
-#ifdef HAVE_STREAMS
-#ifndef HAVE_LINE_PUSH
-static char *push_list[] = {
-#ifdef PUSH_PTEM
- "ptem",
-#endif
-#ifdef PUSH_LDTERM
- "ldterm",
-#endif
-#ifdef PUSH_TTCOMPAT
- "ttcompat",
-#endif
- 0
-};
-#endif /* HAVE_LINE_PUSH */
-#endif /* HAVE_STREAMS */
-
-long
-pty_initialize_slave (fd) int fd; {
-#ifdef POSIX_TERMIOS
-#ifndef ultrix
- struct termios new_termio;
-#else
- struct sgttyb b;
-#endif /* ultrix */
-#else
- struct sgttyb b;
-#endif /* POSIX_TERMIOS */
- int pid;
-#ifdef POSIX_TERMIOS
-#ifndef ultrix
- int rc;
-#endif /* ultrix */
-#endif /* POSIX_TERMIOS */
-
- debug(F111,"pty_initialize_slave()","fd",fd);
-
-#ifdef HAVE_STREAMS
-#ifdef HAVE_LINE_PUSH
- while (ioctl(fd,I_POP,0) == 0) ; /* Clear out any old lined's */
-
- if (line_push(fd) < 0) {
- debug(F110,"pty_initialize_slave()","line_push() failed",0);
- close(fd);
- fd = -1;
- return(PTY_OPEN_SLAVE_LINE_PUSHFAIL);
- }
-#else /*No line_push */
- {
- char **module = &push_list[0];
- while (*module) {
- if (ioctl(fd, I_PUSH, *(module++)) < 0) {
- debug(F110,"pty_initialize_slave()","ioctl(I_PUSH) failed",0);
- return(PTY_OPEN_SLAVE_PUSH_FAIL);
- }
- }
- }
-#endif /*LINE_PUSH*/
-#endif /*HAVE_STREAMS*/
-/*
- Under Ultrix 3.0, the pgrp of the slave pty terminal needs to be set
- explicitly. Why rlogind works at all without this on 4.3BSD is a mystery.
-*/
-#ifdef GETPGRP_ONEARG
- pid = getpgrp(getpid());
-#else
- pid = getpgrp();
-#endif /* GETPGRP_ONEARG */
-
- debug(F111,"pty_initialize_slave()","pid",pid);
-
-#ifdef TIOCSPGRP
- ioctl(fd, TIOCSPGRP, &pid);
-#endif /* TIOCSPGRP */
-
-#ifdef POSIX_TERMIOS
-#ifndef ultrix
- tcsetpgrp(fd, pid);
- errno = 0;
- rc = tcgetattr(fd,&new_termio);
- debug(F111,"pty_initialize_slave tcgetattr(fd)",ckitoa(rc),errno);
- if (rc == 0) {
- new_termio.c_cc[VMIN] = 1;
- new_termio.c_cc[VTIME] = 0;
- rc = tcsetattr(fd,TCSANOW,&new_termio);
- debug(F111,"pty_initialize_slave tcsetattr(fd)",ckitoa(rc),errno);
- }
-#endif /* ultrix */
-#endif /* POSIX_TERMIOS */
- return(0L);
-}
-
-#ifdef WANT_UTMP
-long
-pty_logwtmp (tty, user, host) char *user, *tty, *host; {
-#ifdef HAVE_LOGWTMP
- logwtmp(tty,user,host);
- return(0);
-#else
- struct utmp ut;
- char *tmpx;
- char utmp_id[5];
- int loggingin = user[0]; /* Will be empty for logout */
-
-#ifndef NO_UT_HOST
- strncpy(ut.ut_host, host, sizeof(ut.ut_host));
-#endif /* NO_UT_HOST */
-
- strncpy(ut.ut_line, tty, sizeof(ut.ut_line));
- ut.ut_time = time(0);
-
-#ifndef NO_UT_PID
- ut.ut_pid = getpid();
- strncpy(ut.ut_user, user, sizeof(ut.ut_user));
-
- tmpx = tty + strlen(tty) - 2;
- ckmakmsg(utmp_id,5,"kr",tmpx,NULL,NULL);
- strncpy(ut.ut_id, utmp_id, sizeof(ut.ut_id));
- ut.ut_pid = (loggingin ? getpid() : 0);
- ut.ut_type = (loggingin ? USER_PROCESS : DEAD_PROCESS);
-#else
- strncpy(ut.ut_name, user, sizeof(ut.ut_name));
-#endif /* NO_UT_PID */
-
- return(ptyint_update_wtmp(&ut, host, user));
-
-#endif /* HAVE_LOGWTMP */
-}
-#endif /* WANT_UTMP */
-
-/*
- This routine is called twice. It's not particularly important that the
- setsid() or TIOCSCTTY ioctls succeed (they may not the second time), but
- rather that we have a controlling terminal at the end. It is assumed that
- vhangup doesn't exist and confuse the process's notion of controlling
- terminal on any system without TIOCNOTTY. That is, either vhangup() leaves
- the controlling terminal in tact, breaks the association completely, or the
- system provides TIOCNOTTY to get things back into a reasonable state. In
- practice, vhangup() either breaks the association completely or doesn't
- effect controlling terminals, so this condition is met.
-*/
-long
-pty_open_ctty(slave, fd, fc) char * slave; int *fd; int fc; {
- int retval;
-
- debug(F110,"pty_open_ctty() slave",slave,0);
-
-/* First, dissociate from previous terminal */
-
- if ((retval = ptyint_void_association()) != 0) {
- debug(F111,
- "pty_open_ctty()",
- "ptyint_void_association() failed",
- retval
- );
- return(retval);
- }
-#ifdef MUST_SETPGRP
-/*
- The Ultrix (and other BSD tty drivers) require the process group
- to be zero in order to acquire the new tty as a controlling tty.
-*/
- setpgrp(0,0);
- debug(F101,"pty_open_ctty MUST_SETPGRP setpgrp(0,0)","",errno);
-#endif /* MUST_SETPGRP */
-
- errno = 0;
- *fd = open(slave, O_RDWR);
- debug(F111,"pty_open_ctty open(slave) fd",slave,*fd);
- if (*fd < 0) {
- debug(F111,"pty_open_ctty() open failure", slave, errno);
- return(PTY_OPEN_SLAVE_OPENFAIL);
- }
-#ifdef SOLARIS
- /* This forces the job to have a controlling terminal. */
- close(*fd);
- *fd = open(slave, O_RDWR);
- debug(F111,"pty_open_ctty close/open(slave) fd",slave,*fd);
-#ifdef DEBUG
- /* This shows that /dev/tty exists */
-if (deblog) {
- int x;
- x = open("/dev/tty", O_RDWR);
- debug(F111,"pty_open_ctty open(/dev/tty) fd",slave,x);
- if (x < 0) debug(F111,"pty_open_ctty open(/dev/tty) errno","",errno);
- debug(F110,"pty_open_ctty ttyname(/dev/tty)",ttyname(x),0);
- if (x > -1) close(x);
- }
-#endif /* DEBUG */
-#endif /* SOLARIS */
-
-#ifdef MUST_SETPGRP
- setpgrp(0, getpid());
-#endif /* MUST_SETPGRP */
-
-#ifdef TIOCSCTTY
- if (
-#ifdef COMMENT
- fc == 0
-#else
- 1
-#endif /* COMMENT */
- ) {
- /* TIOCSCTTY = Make this the job's controlling terminal */
- errno = 0;
- retval = ioctl(*fd, TIOCSCTTY, 0); /* Don't check return.*/
- debug(F111,"pty_open_ctty() ioctl TIOCSCTTY",ckitoa(retval),errno);
- }
-#endif /* TIOCSCTTY */
- return(0L);
-}
-
-long
-pty_open_slave(slave, fd, fc) char *slave; int *fd; int fc; {
- int vfd, testfd;
- long retval;
-#ifdef CK_POSIX_SIG
- struct sigaction sa;
-
- sigemptyset(&sa.sa_mask); /* Initialize "sa" structure. */
- sa.sa_flags = 0;
-#endif /* CK_POSIX_SIG */
-
-/*
- First, chmod and chown the slave. If we have vhangup then we really need
- pty_open_ctty to make sure our controlling terminal is the pty we're
- opening. However, if we are using revoke or nothing then we just need a
- file descriiptor for the pty. Considering some OSes in this category break
- on the second call to open_ctty (currently OSF but others may), we simply
- use a descriptor if we can.
-*/
-#ifdef VHANG_FIRST
- if ((retval = pty_open_ctty(slave, &vfd, fc)) != 0) {
- debug(F111,
- "pty_open_slave() VHANG_FIRST",
- "pty_open_ctty() failed",
- retval
- );
- return(retval);
- }
- if (vfd < 0) {
- debug(F111,
- "pty_open_slave() VHANG_FIRST",
- "PTY_OPEN_SLAVE_OPENFAIL",
- vfd
- );
- return(PTY_OPEN_SLAVE_OPENFAIL);
- }
-#endif /* VHANG_FIRST */
-
- if (slave == NULL || *slave == '\0') {
- debug(F110,"pty_open_slave()","PTY_OPEN_SLAVE_TOOSHORT",0);
- return(PTY_OPEN_SLAVE_TOOSHORT);
- }
-
-#ifdef SETUID
- if (chmod(slave, 0)) {
- debug(F110,"pty_open_slave()","PTY_OPEN_SLAVE_CHMODFAIL",0);
- return(PTY_OPEN_SLAVE_CHMODFAIL);
- }
- if (chown(slave, 0, 0 ) == -1 ) {
- debug(F110,"pty_open_slave()","PTY_OPEN_SLAVE_CHOWNFAIL",0);
- return(PTY_OPEN_SLAVE_CHOWNFAIL);
- }
-#endif /* SETUID */
-#ifdef VHANG_FIRST
- ptyint_vhangup();
- close(vfd);
-#endif /* VHANG_FIRST */
-
- if ((retval = ptyint_void_association()) != 0) {
- debug(F111,
- "pty_open_slave()",
- "ptyint_void_association() failed",
- retval
- );
- return(retval);
- }
-
-#ifdef HAVE_REVOKE
- if (revoke (slave) < 0 ) {
- debug(F110,"pty_open_slave()","PTY_OPEN_SLAVE_REVOKEFAIL",0);
- return(PTY_OPEN_SLAVE_REVOKEFAIL);
- }
-#endif /* HAVE_REVOKE */
-
-/* Open the pty for real. */
-
- retval = pty_open_ctty(slave, fd, fc);
- debug(F111,"pty_open_slave retval",slave,retval);
- debug(F111,"pty_open_slave fd",slave,*fd);
- if (retval != 0) {
- debug(F111,"pty_open_slave()","pty_open_ctty() failed",retval);
- return(PTY_OPEN_SLAVE_OPENFAIL);
- }
- pty_slave_fd = *fd; /* This is not visible to the upper fork */
- debug(F111,"pty_open_slave fd ctty'd",slave,pty_slave_fd);
- retval = pty_initialize_slave(*fd);
- debug(F111,"pty_open_slave fd init'd",slave,pty_slave_fd);
- if (retval) {
- debug(F111,"pty_open_slave()","pty_initialize_slave() failed",retval);
- return(retval);
- }
- /* (VOID)pty_make_raw(*fd); */
-
- debug(F100,"pty_open_slave OK","",*fd);
- return(0L);
-}
-
-#ifdef WANT_UTMP
-
-#ifndef UTMP_FILE
-#ifdef _PATH_UTMP
-#define UTMP_FILE _PATH_UTMP
-#endif /* _PATH_UTMP */
-#endif /* UTMP_FILE */
-
-/* If it is *still* missing, assume /etc/utmp */
-
-#ifndef UTMP_FILE
-#define UTMP_FILE "/etc/utmp"
-#endif /* UTMP_FILE */
-
-#ifndef NO_UT_PID
-#define WTMP_REQUIRES_USERNAME
-#endif /* NO_UT_PID */
-
-long
-pty_update_utmp(process_type, pid, username, line, host, flags)
- int process_type;
- int pid;
- char *username, *line, *host;
- int flags;
-/* pty_update_utmp */ {
- struct utmp ent, ut;
-#ifndef HAVE_SETUTENT
- struct stat statb;
- int tty;
-#endif /* HAVE_SETUTENT */
-#ifdef HAVE_SETUTXENT
- struct utmpx utx;
-#endif /* HAVE_SETUTXENT */
-#ifndef NO_UT_PID
- char *tmpx;
- char utmp_id[5];
-#endif /* NO_UT_PID */
- char userbuf[32];
- int fd;
-
- debug(F100,"pty_update_utmp()","",0);
- strncpy(ent.ut_line, line+sizeof("/dev/")-1, sizeof(ent.ut_line));
- ent.ut_time = time(0);
-
-#ifdef NO_UT_PID
- if (process_type == PTY_LOGIN_PROCESS)
- return(0L);
-#else /* NO_UT_PID */
-
- ent.ut_pid = pid;
-
- switch (process_type) {
- case PTY_LOGIN_PROCESS:
- ent.ut_type = LOGIN_PROCESS;
- break;
- case PTY_USER_PROCESS:
- ent.ut_type = USER_PROCESS;
- break;
- case PTY_DEAD_PROCESS:
- ent.ut_type = DEAD_PROCESS;
- break;
- default:
- return(PTY_UPDATE_UTMP_PROCTYPE_INVALID);
- }
-#endif /*NO_UT_PID*/
-
-#ifndef NO_UT_HOST
- if (host)
- strncpy(ent.ut_host, host, sizeof(ent.ut_host));
- else
- ent.ut_host[0] = '\0';
-#endif /* NO_UT_HOST */
-
-#ifndef NO_UT_PID
- if (!strcmp (line, "/dev/console")) {
- char * s = NULL;
-
-#ifdef sun
-#ifdef __SVR4
- s = "co";
-#else
- s = "cons";
-#endif /* __SVR4 */
-#else
- s = "cons";
-#endif /* sun */
-
- strncpy(ent.ut_id, s, 4);
-
- } else {
-
- tmpx = line + strlen(line)-1;
- if (*(tmpx-1) != '/') tmpx--; /* last 2 chars unless it's a '/' */
-#ifdef __hpux
- ckstrncpy(utmp_id, tmpx, 5);
-#else
- ckmakmsg(utmp_id,5,"kl",tmpx,NULL,NULL);
-#endif /* __hpux */
- strncpy(ent.ut_id, utmp_id, sizeof(ent.ut_id));
- }
- strncpy(ent.ut_user, username, sizeof(ent.ut_user));
-
-#else
-
- strncpy(ent.ut_name, username, sizeof(ent.ut_name));
-
-#endif /* NO_UT_PID */
-
- if (username[0])
- strncpy(userbuf, username, sizeof(userbuf));
- else
- userbuf[0] = '\0';
-
-#ifdef HAVE_SETUTENT
-
- utmpname(UTMP_FILE);
- setutent();
-/*
- If we need to preserve the user name in the wtmp structure and Our flags
- tell us we can obtain it from the utmp and we succeed in obtaining it, we
- then save the utmp structure we obtain, write out the utmp structure and
- change the username pointer so it is used by update_wtmp.
-*/
-
-#ifdef WTMP_REQUIRES_USERNAME
- if ((!username[0]) && (flags&PTY_UTMP_USERNAME_VALID) &&line) {
- struct utmp *utptr;
- strncpy(ut.ut_line, line, sizeof(ut.ut_line));
- utptr = getutline(&ut);
- if (utptr)
- strncpy(userbuf,utptr->ut_user,sizeof(ut.ut_user));
- }
-#endif /* WTMP_REQUIRES_USERNAME */
-
- pututline(&ent);
- endutent();
-
-#ifdef HAVE_SETUTXENT
- setutxent();
-#ifdef HAVE_GETUTMPX
- getutmpx(&ent, &utx);
-#else /* HAVE_GETUTMPX */
- /* For platforms like HPUX and Dec Unix which don't have getutmpx */
- strncpy(utx.ut_user, ent.ut_user, sizeof(ent.ut_user));
- strncpy(utx.ut_id, ent.ut_id, sizeof(ent.ut_id));
- strncpy(utx.ut_line, ent.ut_line, sizeof(ent.ut_line));
- utx.ut_pid = pid; /* kludge for Irix, etc. to avoid trunc. */
- utx.ut_type = ent.ut_type;
-#ifdef UT_EXIT_STRUCTURE_DIFFER
- utx.ut_exit.ut_exit = ent.ut_exit.e_exit;
-#else /* UT_EXIT_STRUCTURE_DIFFER */
-/* KLUDGE for now; eventually this will be a feature test... See PR#[40] */
-#ifdef __hpux
- utx.ut_exit.__e_termination = ent.ut_exit.e_termination;
- utx.ut_exit.__e_exit = ent.ut_exit.e_exit;
-#else /* __hpux */
- /* XXX do nothing for now; we don't even know the struct member exists */
-#endif /* __hpux */
-#endif /* UT_EXIT_STRUCTURE_DIFFER */
- utx.ut_tv.tv_sec = ent.ut_time;
- utx.ut_tv.tv_usec = 0;
-#endif /* HAVE_GETUTMPX */
- if (host)
- strncpy(utx.ut_host, host, sizeof(utx.ut_host));
- else
- utx.ut_host[0] = 0;
- pututxline(&utx);
- endutxent();
-#endif /* HAVE_SETUTXENT */
-
-#else /* HAVE_SETUTENT */
- if (flags&PTY_TTYSLOT_USABLE) {
- tty = ttyslot();
- } else {
- int lc;
- tty = -1;
- if ((fd = open(UTMP_FILE, O_RDWR)) < 0)
- return(errno);
- for (lc = 0;
- lseek(fd, (off_t)(lc * sizeof(struct utmp)), SEEK_SET) != -1;
- lc++
- ) {
- if (read(fd,
- (char *)&ut,
- sizeof(struct utmp)
- ) != sizeof(struct utmp)
- )
- break;
- if (strncmp(ut.ut_line, ent.ut_line, sizeof(ut.ut_line)) == 0) {
- tty = lc;
-#ifdef WTMP_REQUIRES_USERNAME
- if (!username&&(flags&PTY_UTMP_USERNAME_VALID))
- strncpy(userbuf, ut.ut_user, sizeof(ut.ut_user));
-#endif /* WTMP_REQUIRES_USERNAME */
- break;
- }
- }
- close(fd);
- }
- if (tty > 0 && (fd = open(UTMP_FILE, O_WRONLY, 0)) >= 0) {
- lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
- write(fd, (char *)&ent, sizeof(struct utmp));
- close(fd);
- }
-#endif /* HAVE_SETUTENT */
-
- /* Don't record LOGIN_PROCESS entries. */
- if (process_type == PTY_LOGIN_PROCESS)
- return(0);
- else
- return(ptyint_update_wtmp(&ent, host, userbuf));
-}
-#ifndef WTMP_FILE
-#ifdef _PATH_WTMP
-#define WTMP_FILE _PATH_WTMP
-#endif /* _PATH_WTMP */
-#endif /* WTMP_FILE */
-
-#ifndef WTMPX_FILE
-#ifdef _PATH_WTMPX
-#ifdef HAVE_UPDWTMPX
-#define WTMPX_FILE _PATH_WTMPX
-#endif /* HAVE_UPDWTMPX */
-#endif /* _PATH_WTMPX */
-#endif /* WTMPX_FILE */
-
-/* If it is *still* missing, assume /usr/adm/wtmp */
-
-#ifndef WTMP_FILE
-#define WTMP_FILE "/usr/adm/wtmp"
-#endif /* WTMP_FILE */
-
-#ifdef COMMENT
-/* The following test can not be made portably */
-
-/* #if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) */
-/*
- This is ugly, but the lack of standardization in the utmp/utmpx space, and
- what glibc implements and doesn't make available, is even worse.
-*/
-/* #undef HAVE_UPDWTMPX */ /* Don't use updwtmpx for glibc 2.1 */
-/* #endif */ /* __GLIBC__ etc */
-
-#else /* COMMENT */
-
-#ifdef __GLIBC__
-#undef HAVE_UPDWTMPX /* Don't use updwtmpx for glibc period */
-#endif /* __GLIBC__ */
-#endif /* COMMENT */
-
-long
-ptyint_update_wtmp(ent,host,user) struct utmp *ent; char *host; char *user; {
- struct utmp ut;
- struct stat statb;
- int fd;
- time_t uttime;
-#ifdef HAVE_UPDWTMPX
- struct utmpx utx;
-
- getutmpx(ent, &utx);
- if (host)
- strncpy(utx.ut_host, host, sizeof(utx.ut_host) );
- else
- utx.ut_host[0] = 0;
- if (user)
- strncpy(utx.ut_user, user, sizeof(utx.ut_user));
- updwtmpx(WTMPX_FILE, &utx);
-#endif /* HAVE_UPDWTMPX */
-
-#ifdef HAVE_UPDWTMP
-#ifndef HAVE_UPDWTMPX
- /* This is already performed byupdwtmpx if present.*/
- updwtmp(WTMP_FILE, ent);
-#endif /* HAVE_UPDWTMPX*/
-#else /* HAVE_UPDWTMP */
-
- if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) >= 0) {
- if (!fstat(fd, &statb)) {
- memset((char *)&ut, 0, sizeof(ut));
-#ifdef __hpux
- strncpy(ut.ut_id, ent->ut_id, sizeof (ut.ut_id));
-#endif /* __hpux */
- strncpy(ut.ut_line, ent->ut_line, sizeof(ut.ut_line));
- strncpy(ut.ut_name, ent->ut_name, sizeof(ut.ut_name));
-#ifndef NO_UT_HOST
- strncpy(ut.ut_host, ent->ut_host, sizeof(ut.ut_host));
-#endif /* NO_UT_HOST */
-
- time(&uttime);
- ut.ut_time = uttime;
-
-#ifdef HAVE_GETUTENT
-#ifdef USER_PROCESS
- if (ent->ut_name) {
- if (!ut.ut_pid)
- ut.ut_pid = getpid();
-#ifndef __hpux
- ut.ut_type = USER_PROCESS;
-#else /* __hpux */
- ut.ut_type = ent->ut_type;
-#endif /* __hpux */
-
- } else {
-
-#ifdef EMPTY
- ut.ut_type = EMPTY;
-#else
- ut.ut_type = DEAD_PROCESS; /* For Linux brokenness*/
-#endif /* EMPTY */
-
- }
-#endif /* USER_PROCESS */
-#endif /* HAVE_GETUTENT */
-
- if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
- sizeof(struct utmp))
-#ifndef COHERENT
- ftruncate(fd, statb.st_size);
-#else
- chsize(fd, statb.st_size);
-#endif /* COHERENT */
- }
- close(fd);
- }
-#endif /* HAVE_UPDWTMP */
- return(0); /* no current failure cases; file not found is not failure! */
-}
-#endif /* WANT_UTMP */
-
-/* This is for ancient Unixes that don't have these tty symbols defined. */
-
-#ifndef PENDIN
-#define PENDIN ICANON
-#endif /* PENDIN */
-#ifndef FLUSHO
-#define FLUSHO ICANON
-#endif /* FLUSHO */
-#ifndef IMAXBEL
-#define IMAXBEL ICANON
-#endif /* IMAXBEL */
-#ifndef EXTPROC
-#define EXTPROC ICANON
-#endif /* EXTPROC */
-
-static char Xline[17] = { 0, 0 };
-/*
- getptyslave()
- Open the slave side of the pty, and do any initialization that is necessary.
- The return value fd is a file descriptor for the slave side.
- fc = function code from do_pty() (q.v.)
-*/
-int
-getptyslave(fd, fc) int * fd, fc; {
- int ttyfd;
- int t = -1;
- long retval;
-#ifdef TIOCGWINSZ
- struct winsize ws;
- extern int cmd_rows, cmd_cols;
-#endif /* TIOCGWINSZ */
-
- ttyfd = *fd;
- debug(F111,"getptyslave()","ttyfd",ttyfd);
- /*
- * Opening the slave side may cause initilization of the
- * kernel tty structure. We need remember the state of:
- * if linemode was turned on
- * terminal window size
- * terminal speed
- * so that we can reset them if we need to.
- */
- if ((retval = pty_open_slave(Xline, &t, fc)) != 0) {
- perror(Xline);
- msg++;
- debug(F111,"getptyslave()","Unable to open slave",retval);
- return(-1);
- }
- debug(F111,"getptyslave","t",t);
-#ifdef INIT_SPTY
- spty = t;
- debug(F111,"getptyslave","spty",spty);
-#endif /* INIT_SPTY */
-#ifdef STREAMSPTY
- if (ioctl(t,I_PUSH,"pckt") < 0) {
- debug(F111,"getptyslave()","ioctl(I_PUSH) failed",errno);
-#ifndef _AIX
- fatal("I_PUSH pckt");
-#endif /* _AIX */
- }
-#endif /* STREAMSPTY */
-
- /* Set up the tty modes as we like them to be. */
-#ifdef COMMENT
- /* Originally like this... But this is the master - we want the slave */
- /* Anyway, this fails on Solaris and probably other System V OS's */
- init_termbuf(ttyfd);
-#else
- init_termbuf(t);
-#endif /* COMMENT */
-#ifdef TIOCGWINSZ
- if (cmd_rows || cmd_cols) {
- memset((char *)&ws, 0, sizeof(ws));
- ws.ws_col = cmd_cols;
- ws.ws_row = cmd_rows;
- debug(F101,"getptyslave() doing TIOCSWINSZ...","",t);
- ioctl(t, TIOCSWINSZ, (char *)&ws);
- }
-#endif /* TIOCGWINSZ */
-
- /* For external protocols, put the pty in no-echo mode */
- if (fc == 1) {
- debug(F100,"getptyslave() setting rawmode","",0);
- /* iflags */
- termbuf.c_iflag &= ~(PARMRK|ISTRIP|BRKINT|INLCR|IGNCR|ICRNL);
- termbuf.c_iflag &= ~(INPCK|IGNPAR|IMAXBEL|IXANY|IXON|IXOFF);
- termbuf.c_iflag |= IGNBRK;
-#ifdef IUCLC
- termbuf.c_iflag &= ~IUCLC;
-#endif /* IUCLC */
-
- /* oflags */
- termbuf.c_oflag &= ~OPOST;
-#ifdef OXTABS
- termbuf.c_oflag &= ~OXTABS;
-#endif /* OXTABS */
-#ifdef ONOCR
- termbuf.c_oflag &= ~ONOCR;
-#endif /* ONOCR */
-#ifdef ONLRET
- termbuf.c_oflag &= ~ONLRET;
-#endif /* ONLRET */
-#ifdef ONLCR
- termbuf.c_oflag &= ~ONLCR;
-#endif /* ONLCR */
-
- /* lflags */
- termbuf.c_lflag &= ~ECHO;
-#ifdef ECHOE
- termbuf.c_lflag &= ~ECHOE;
-#endif /* ECHOE */
-#ifdef ECHONL
- termbuf.c_lflag &= ~ECHONL;
-#endif /* ECHONL */
-#ifdef ECHOPRT
- termbuf.c_lflag &= ~ECHOPRT;
-#endif /* ECHOPRT */
-#ifdef ECHOKE
- termbuf.c_lflag &= ~ECHOKE;
-#endif /* ECHOKE */
-#ifdef ECHOCTL
- termbuf.c_lflag &= ~ECHOCTL;
-#endif /* ECHOCTL */
-#ifdef ALTWERASE
- termbuf.c_lflag &= ~ALTWERASE;
-#endif /* ALTWERASE */
-#ifdef EXTPROC
- termbuf.c_lflag &= ~EXTPROC;
-#endif /* EXTPROC */
- termbuf.c_lflag &= ~(ICANON|ISIG|IEXTEN|TOSTOP|FLUSHO|PENDIN);
-
-#ifdef NOKERNINFO
- termbuf.c_lflag |= NOKERNINFO;
-#endif /* NOKERNINFO */
- /* termbuf.c_lflag |= NOFLSH; */
- termbuf.c_lflag &= ~NOFLSH;
-
- /* cflags */
- termbuf.c_cflag &= ~(CSIZE|PARENB|PARODD);
- termbuf.c_cflag |= CS8|CREAD;
-#ifdef VMIN
- termbuf.c_cc[VMIN] = 1;
-#endif /* VMIN */
- } else { /* Regular interactive use */
- debug(F100,"getptyslave() setting cooked mode","",0);
-
- /* Settings for sgtty based systems */
-
-#ifndef USE_TERMIO
- termbuf.sg.sg_flags |= CRMOD|ANYP|ECHO|XTABS;
-#endif /* USE_TERMIO */
-
-#ifndef OXTABS
-#define OXTABS 0
-#endif /* OXTABS */
-
- /* Settings for UNICOS and HPUX */
-
-#ifdef CRAY
- termbuf.c_oflag = OPOST|ONLCR|TAB3;
- termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
- termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
- termbuf.c_cflag = EXTB|HUPCL|CS8;
-#else /* CRAY */
-#ifdef HPUX
- termbuf.c_oflag = OPOST|ONLCR|TAB3;
- termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
- termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
- termbuf.c_cflag = EXTB|HUPCL|CS8;
-#else /* HPUX */
-#ifdef USE_TERMIO
- /*
- Settings for all other termios/termio based systems, other than
- 4.4BSD. In 4.4BSD the kernel does the initial terminal setup.
- */
-#ifdef BSD42
-#ifndef BSD44
- termbuf.c_lflag |= ECHO|ICANON|IEXTEN|ISIG;
- termbuf.c_oflag |= ONLCR|OXTABS|OPOST;
- termbuf.c_iflag |= ICRNL|IGNPAR;
- termbuf.c_cflag |= HUPCL;
- termbuf.c_iflag &= ~IXOFF;
-#endif /* BSD44 */
-#else /* BSD42 */
- termbuf.c_lflag |= ECHO|ICANON|IEXTEN|ISIG;
- termbuf.c_oflag |= ONLCR|OXTABS|OPOST;
- termbuf.c_iflag |= ICRNL|IGNPAR;
- termbuf.c_cflag |= HUPCL;
- termbuf.c_iflag &= ~IXOFF;
-#endif /* BSD42 */
-#endif /* USE_TERMIO */
-#endif /* HPUX */
-#endif /* CRAY */
- }
-
- /* Set the tty modes, and make this our controlling tty. */
-#ifdef COMMENT
- /* But this is the master - we want the slave */
- set_termbuf(ttyfd);
-#else
- set_termbuf(t);
-#endif /* COMMENT */
-
- if (t != 0)
- dup2(t, 0);
- if (t != 1)
- dup2(t, 1);
- if (t != 2) {
- if (fc == 0) {
- dup2(t, 2);
- } else if (fc == 1) {
- /* For external protocols, send stderr to /dev/null */
-#ifdef COMMENT
- int xx;
-#ifndef COMMENT
- char * s = "/dev/null";
- errno = 0;
- xx = open(s, O_WRONLY);
-#else
- char * s = "pty.log";
- errno = 0;
- xx = open(s, O_CREAT, 0644);
-#endif /* COMMENT */
- debug(F111,"getptyslave redirect stderr",s,errno);
- dup2(xx,2);
-#endif /* COMMENT */
- }
- }
- if (t > 2)
- close(t);
-
- if (ttyfd > 2) {
- close(ttyfd);
- ttyfd = -1;
- *fd = ttyfd;
- }
- return(0);
-}
-
-#ifdef HAVE_PTYTRAP
-/*
- To be called to determine if a trap is pending on a pty
- if and only if select() cannot be used.
-*/
-int
-pty_trap_pending(fd) int fd; {
- int pending;
- int rc;
-
- rc = ioctl(fd, TIOCTRAPSTATUS, (char *)&pending, sizeof(pending));
- if (rc == 0) {
- debug(F101,"pty_trap_pending()","",pending);
- return(pending);
- } else {
- debug(F111,"pty_trap_pending()","ioctl() failed",rc);
- return(-1);
- }
-}
-
-/*
- To be called after select() has returned indicating that an exception is
- waiting on a pty. It should be called with the file descriptor of the pty.
- Returns -1 on error; 0 if pty is still open; 1 if pty has closed.
-*/
-int
-pty_trap_handler(fd) int fd; {
- struct request_info ri;
-
- memset(&ri,0,sizeof(ri));
- if (ioctl(fd,TIOCREQCHECK,(char *)&ri, sizeof(ri)) != 0) {
- debug(F111,"pty_trap_handler()","ioctl(TIOCREQCHECK) failed",errno);
- return(-1);
- }
- switch (ri.request) {
- case TIOCOPEN:
- debug(F110,"pty_trap_handler()","an open() call",0);
- break;
- case TIOCCLOSE:
- debug(F110,"pty_trap_handler()","a close() call",0);
- break;
- default:
- debug(F110,"pty_trap_handler()","an ioctl() call",0);
- ri.errno_error = EINVAL;
- }
- if (ioctl(fd, TIOCREQSET, (char *)&ri,sizeof(ri)) != 0) {
- debug(F111,"pty_trap_handler()","ioctl(TIOCREQSET) failed",errno);
- return(-1);
- }
- if (ri.request == TIOCCLOSE)
- return(1);
- else
- return(0);
-}
-#endif /* HAVE_PTYTRAP */
-
-VOID
-exec_cmd(s) char * s; {
- struct stringarray * q;
- char ** args = NULL;
-
- if (!s) return;
- if (!*s) return;
-
- q = cksplit(1,0,s,NULL,"\\%[]&$+-/=*^_@!{}/<>|.#~'`:;?",7,0,0);
- if (!q) return;
-
- args = q->a_head + 1;
-
-#ifdef DEBUG
- {
- int i, n;
- n = q->a_size;
- for (i = 0; i <= n; i++) {
- if (!args[i]) {
- debug(F111,"exec_cmd arg","NULL",i);
- break;
- } else {
- debug(F111,"exec_cmd arg",args[i],i);
- if (i == n && args[i]) {
- debug(F101,"exec_cmd SUBSTITUTING NULL","",i);
- if (strlen(args[i]) == 0)
- makestr(&(args[i]),NULL);
- }
-
- }
- }
- }
-#endif /* DEBUG */
-
- execvp(args[0],args);
-}
-
-/* Get a pty, scan input lines. */
-/* fc = 0 for interactive access; fc = 1 for running external protocols */
-
-static int pty_fc = -1; /* Global copy of fc */
-
-int
-do_pty(fd, cmd, fc) int * fd; char * cmd; int fc; {
- long retval;
- int syncpipe[2];
- int i, ttyfd;
-#ifdef HAVE_PTYTRAP
- int x;
-#endif /* HAVE_PTYTRAP */
-
- debug(F101,"CKUPTY.C do_pty fc","",fc);
-
- ttyfd = *fd;
-
- pty_master_fd = -2;
- pty_slave_fd = -2;
- pty_fork_pid = -2;
-
- msg = 0; /* Message counter */
- pty_init(); /* Find an available pty to use. */
- errno = 0;
-
- if ((retval = pty_getpty(&ttyfd, Xline, 20)) != 0) {
- if (msg++ == 0)
- perror(Xline);
- debug(F111,"do_pty()","pty_getpty() fails",retval);
- *fd = ttyfd;
- return(-1);
- }
- *fd = ttyfd;
- debug(F111,"do_pty() Xline",Xline,ttyfd);
-
-#ifdef SIGTTOU
-/*
- Ignoring SIGTTOU keeps the kernel from blocking us. we tweak the tty with
- an ioctl() (in ttioct() in /sys/tty.c in a BSD kernel)
-*/
- signal(SIGTTOU, SIG_IGN);
-#endif /* SIGTTOU */
-
-/* Start up the command on the slave side of the terminal */
-
- if (pipe(syncpipe) < 0) {
- debug(F110,"do_pty()","pipe() fails",0);
- perror("pipe() failed");
- msg++;
- debug(F111,"do_pty()","pipe fails",errno);
- return(-1);
- }
- if ((i = fork()) < 0) {
- /* XXX - need to clean up the allocated pty */
- perror("fork() failed");
- msg++;
- debug(F111,"do_pty()","fork fails",errno);
- return(-1);
- }
- if (i) { /* Wait for child before writing to parent side of pty. */
- char c;
-#ifdef HAVE_PTYTRAP
- int on = 1;
-#endif /* HAVE_PTYTRAP */
- close(syncpipe[1]);
- errno = 0;
- if (read(syncpipe[0], &c, 1) == 0) { /* Slave side died */
- perror("Pipe read() failed");
- msg++;
- debug(F110,"do_pty()","Slave fails to initialize",0);
- close(syncpipe[0]);
- return(-1);
- }
- pty_fork_pid = i; /* So we can clean it up later */
- pty_fork_active = 1;
- debug(F101,"do_pty pty_fork_pid","",pty_fork_pid);
-#ifdef HAVE_PTYTRAP
- /* HPUX does not allow the master to read end of file. */
- /* Therefore, we must determine that the slave has been */
- /* closed by trapping the call to close(). */
- errno = 0;
- x = ioctl(ttyfd, TIOCTRAP, (char *)&on);
- debug(F111,"do_pty ioctl(TIOCTRAP)",ckitoa(x),errno);
-#endif /* HAVE_PTYTRAP */
- debug(F111,"do_pty()","synchronized - pty_fork_pid",pty_fork_pid);
- close(syncpipe[0]);
- } else {
- int x;
- debug(F101,"do_pty getptyslave ttyfd A","",ttyfd);
- debug(F110,"do_pty()","Slave starts",0);
- x = getptyslave(&ttyfd,fc);
- debug(F101,"do_pty getptyslave","",x);
- if (x == 0) {
- debug(F101,"do_pty getptyslave ttyfd B","",ttyfd);
-#ifdef WANT_UTMP
- pty_update_utmp(PTY_USER_PROCESS,
- getpid(),
- "KERMIT",
- Xline,
- cmd,
- PTY_TTYSLOT_USABLE
- );
-#endif /* WANT_UTMP */
- /* Notify our parent we're ready to continue.*/
- debug(F110,"do_pty()","slave synchronizing",0);
- write(syncpipe[1],"y",1);
- close(syncpipe[0]);
- close(syncpipe[1]);
-
- debug(F110,"do_pty cmd",cmd,"");
- exec_cmd(cmd);
- debug(F111,"do_pty()","exec_cmd() returns - why?",errno);
- }
- *fd = ttyfd;
- debug(F110,"do_pty()","getptyslave() fails - exiting",0);
- exit(1);
- }
- *fd = ttyfd;
- pty_fc = fc;
- return(getpid());
-} /* end of do_pty() */
-
-
-VOID
-end_pty() {
- msg = 0; /* Message counter */
- debug(F101,"end_pty pty_fork_pid","",pty_fork_pid);
- if (Xline[0] && pty_fork_pid >= 0) {
- pty_cleanup(Xline,pty_fork_pid,1);
- Xline[0] = '\0';
- pty_fork_pid = -1;
- pty_fork_active = 0;
- debug(F101,"end_pty pty_fork_active","",pty_fork_active);
- }
- pty_fc = -1;
-}
-#endif /* NETPTY */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckupty.c.c99 b/ckermit-9.0.302-build/ckermit-9.0.302/ckupty.c.c99
deleted file mode 100644
index 9906555..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckupty.c.c99
+++ /dev/null
@@ -1,1979 +0,0 @@
-char *ckptyv = "Pseudoterminal support, 9.0.101, 13 Jun 2011";
-
-/* C K U P T Y -- C-Kermit pseudoterminal control functions for UNIX */
-
-/* Last update: Mon Jun 13 11:32:52 2011 */
-
-/*
- Copyright 1995 by the Massachusetts Institute of Technology.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted, provided
- that the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation, and that the name of M.I.T. not be used in advertising or
- publicity pertaining to distribution of the software without specific,
- written prior permission. Furthermore if you modify this software you must
- label your software as modified software and not distribute it in such a
- fashion that it might be confused with the original M.I.T. software.
- M.I.T. makes no representations about the suitability of this software for
- any purpose. It is provided "as is" without express or implied warranty.
-
- Modified for use in C-Kermit, and new material added, by:
-
- Jeffrey Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
- November 1999
-
- Parameterized for pty file descriptor and function code,
- Frank da Cruz, Columbia University, New York City
- Dec 2006 - Sep 2009
-*/
-
-/*
- Built and tested successully on:
- . 4.4BSD, including BSDI/OS, NetBSD, FreeBSD, OpenBSD, Mac OS X
- . AIX 4.1 and later
- . DG/UX 5.4R4.11
- . Digital UNIX 3.2 and 4.0
- . HP-UX 9.00 and later
- . IRIX 6.0 and later
- . Linux
- . Mac OS X 10.4
- . NeXTSTEP 3.x
- . OpenBSD
- . QNX 4.25 (except PTY process termination not detected)
- . SCO OSR5.0.5
- . SCO Unixware 7
- . SINIX 5.42
- . Solaris 2.x and 7
- . SunOS 4.1.3
-
- Failures include:
- . SCO UNIX 3.2v4.2 (compile fails with syntax error in <memory.h>)
- . HP-UX 8.00 and earlier (no vhangup or ptsname routines)
-*/
-
-#include "ckcsym.h"
-#include "ckcdeb.h" /* To pick up NETPTY definition */
-
-#ifndef NETPTY /* Selector for PTY support */
-
-char * ptyver = "No PTY support";
-
-#else /* (rest of this module...) */
-
-char * ptyver = "PTY support 8.0.016, 22 Aug 2007";
-
-/* These will no doubt need adjustment... */
-
-#ifndef NEXT
-#define HAVE_SETSID
-#endif /* NEXT */
-#define HAVE_KILLPG
-#define HAVE_TTYNAME
-#define HAVE_WAITPID
-
-#ifdef SUNOS41
-#define BSD44ORPOSIX
-#endif /* SUNOS41 */
-
-#ifndef USE_TERMIO
-#ifdef LINUX
-#define USE_TERMIO
-#else
-#ifdef ATTSV
-#define USE_TERMIO
-#else
-#ifdef HPUX
-#define USE_TERMIO
-#else
-#ifdef AIX
-#define USE_TERMIO
-#else
-#ifdef BSD44ORPOSIX
-#define USE_TERMIO
-#else
-#ifdef IRIX60
-#define USE_TERMIO
-#else
-#ifdef QNX
-#define USE_TERMIO
-#endif /* QNX */
-#endif /* IRIX60 */
-#endif /* BSD44ORPOSIX */
-#endif /* AIX */
-#endif /* HPUX */
-#endif /* ATTSV */
-#endif /* LINUX */
-#endif /* USE_TERMIO */
-
-#ifdef QNX
-#include <fcntl.h>
-#endif /* QNX */
-
-#ifdef USE_TERMIO
-#define POSIX_TERMIOS /* Seems to be a misnomer */
-#endif /* USE_TERMIO */
-
-#ifdef NEXT
-#ifndef GETPGRP_ONEARG
-#define GETPGRP_ONEARG
-#endif /* GETPGRP_ONEARG */
-#endif /* NEXT */
-
-#ifdef WANT_UTMP /* See ckupty.h */
-/*
- WANT_UTMP is not defined because (a) the utmp/wtmp junk is the most
- nonportable part of this module, and (b) we're not logging anybody
- in, we're just running a process, and don't need to write utmp/wtmp records.
-*/
-#ifndef HAVE_SETUTXENT /* Who has <utmpx.h> */
-#ifdef SOLARIS
-#define HAVE_SETUTXENT
-#else
-#ifdef IRIX60
-#define HAVE_SETUTXENT
-#else
-#ifdef CK_SCOV5
-#define HAVE_SETUTXENT
-#else
-#ifdef HPUX10
-#define HAVE_SETUTXENT
-#else
-#ifdef UNIXWARE
-#define HAVE_SETUTXENT
-#else
-#ifdef IRIX60
-#define HAVE_SETUTXENT
-#endif /* IRIX60 */
-#endif /* UNIXWARE */
-#endif /* HPUX10 */
-#endif /* CK_SCOV5 */
-#endif /* IRIX60 */
-#endif /* SOLARIS */
-#endif /* HAVE_SETUTXENT */
-
-#ifndef HAVE_UTHOST /* Does utmp include ut_host[]? */
-#ifdef HAVE_SETUTXENT /* utmpx always does */
-#define HAVE_UTHOST
-#else
-#ifdef LINUX /* Linux does */
-#define HAVE_UTHOST
-#else
-#ifdef SUNOS4 /* SunOS does */
-#define HAVE_UTHOST
-#else
-#ifdef AIX41 /* AIX 4.1 and later do */
-#define HAVE_UTHOST
-#endif /* AIX41 */
-#endif /* SUNOS4 */
-#endif /* LINUX */
-#endif /* HAVE_SETUTXENT */
-#endif /* HAVE_UTHOST */
-
-#ifndef HAVE_UT_HOST
-#ifndef NO_UT_HOST
-#define NO_UT_HOST
-#endif /* NO_UT_HOST */
-#endif /* HAVE_UT_HOST */
-
-#endif /* WANT_UTMP */
-
-#ifdef LINUX
-#define CK_VHANGUP
-#define HAVE_SYS_SELECT_H
-#define HAVE_GETUTENT
-#define HAVE_SETUTENT
-#define HAVE_UPDWTMP
-#endif /* LINUX */
-
-#ifdef HPUX10
-#define CK_VHANGUP
-#define VHANG_FIRST
-#define HAVE_PTSNAME
-#ifndef HAVE_PTYTRAP
-#define HAVE_PTYTRAP
-#endif /* HAVE_PTYTRAP */
-#else
-#ifdef HPUX9
-#define CK_VHANGUP
-#define VHANG_FIRST
-#define HAVE_PTSNAME
-#ifndef HAVE_PTYTRAP
-#define HAVE_PTYTRAP
-#endif /* HAVE_PTYTRAP */
-#endif /* HPUX9 */
-#endif /* HPUX10 */
-
-#ifdef SUNOS4
-#define CK_VHANGUP
-#define NO_UT_PID
-#define VHANG_FIRST
-#endif /* SUNOS4 */
-
-#ifdef IRIX60
-#define CK_VHANGUP
-#define HAVE__GETPTY
-#endif /* IRIX60 */
-
-#ifdef SINIX
-#define HAVE_STREAMS
-#define HAVE_GRANTPT
-#define HAVE_PTSNAME
-#define PUSH_PTEM
-#define PUSH_LDTERM
-#define PUSH_TTCOMPAT
-#endif /* SINIX */
-
-#ifdef ultrix
-#define MUST_SETPGRP
-#endif /* ultrix */
-
-#ifdef QNX
-#define MUST_SETPGRP
-#define NO_DEVTTY
-#define INIT_SPTY
-#endif /* QNX */
-
-#ifdef LINUX
-#ifdef HAVE_PTMX
-#define HAVE_GRANTPT
-#define HAVE_PTSNAME
-#endif /* HAVE_PTMX */
-#else
-#ifdef HAVE_STREAMS
-#define HAVE_PTMX
-#endif /* HAVE_STREAMS */
-#endif /* LINUX */
-
-#include "ckupty.h"
-
-#ifdef PTYNOBLOCK
-#ifndef O_NDELAY
-#ifdef O_NONBLOCK
-#define O_NDELAY O_NONBLOCK
-#endif /* O_NONBLOCK */
-#endif /* O_NDELAY */
-#else /* PTYNOBLOCK */
-#ifdef O_NDELAY
-#undef O_NDELAY
-#endif /* O_NDELAY */
-#define O_NDELAY 0
-#endif /* PTYNOBLOCK */
-
-#ifndef ONLCR
-#define ONLCR 0
-#endif /* ONLCR */
-
-#ifdef CK_WAIT_H
-#include <sys/wait.h>
-#endif /* CK_WAIT_H */
-
-#ifdef STREAMSPTY
-#ifndef INIT_SPTY
-#define INIT_SPTY
-#endif /* INIT_SPTY */
-
-#include <sys/stream.h>
-#include <stropts.h>
-#include <termio.h>
-
-/* Make sure we don't get the BSD version */
-
-#ifdef HAVE_SYS_TTY_H
-#include "/usr/include/sys/tty.h"
-#endif /* HAVE_SYS_TTY_H */
-
-#ifdef HAS_PTYVAR /* Where is this set? */
-
-#include <sys/ptyvar.h>
-
-#else /* HAS_PTYVAR */
-
-#ifndef TIOCPKT_FLUSHWRITE
-#define TIOCPKT_FLUSHWRITE 0x02
-#define TIOCPKT_NOSTOP 0x10
-#define TIOCPKT_DOSTOP 0x20
-#define TIOCPKT_IOCTL 0x40
-#endif /* TIOCPKT_FLUSHWRITE */
-
-#endif /* HAS_PTYVAR */
-
-#ifdef HAVE_TTY_H
-#include <tty.h>
-#endif /* HAVE_TTY_H */
-
-/*
- Because of the way ptyibuf is used with streams messages, we need
- ptyibuf+1 to be on a full-word boundary. The following weirdness
- is simply to make that happen.
-*/
-long ptyibufbuf[BUFSIZ/sizeof(long)+1];
-char *ptyibuf = ((char *)&ptyibufbuf[1])-1;
-char *ptyip = ((char *)&ptyibufbuf[1])-1;
-char ptyibuf2[BUFSIZ];
-unsigned char ctlbuf[BUFSIZ];
-struct strbuf strbufc, strbufd;
-
-int readstream();
-
-#else /* ! STREAMSPTY */
-
-/* I/O data buffers, pointers, and counters. */
-
-char ptyibuf[BUFSIZ], *ptyip = ptyibuf;
-char ptyibuf2[BUFSIZ];
-
-#endif /* ! STREAMSPTY */
-
-#ifndef USE_TERMIO
-struct termbuf {
- struct sgttyb sg;
- struct tchars tc;
- struct ltchars ltc;
- int state;
- int lflags;
-} termbuf, termbuf2;
-
-#define cfsetospeed(tp,val) (tp)->sg.sg_ospeed = (val)
-#define cfsetispeed(tp,val) (tp)->sg.sg_ispeed = (val)
-#define cfgetospeed(tp) (tp)->sg.sg_ospeed
-#define cfgetispeed(tp) (tp)->sg.sg_ispeed
-
-#else /* USE_TERMIO */
-
-#ifdef SYSV_TERMIO
-#define termios termio
-#endif /* SYSV_TERMIO */
-
-#ifndef TCSANOW
-
-#ifdef TCSETS
-
-#define TCSANOW TCSETS
-#define TCSADRAIN TCSETSW
-#define tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
-
-#else /* TCSETS */
-
-#ifdef TCSETA
-#define TCSANOW TCSETA
-#define TCSADRAIN TCSETAW
-#define tcgetattr(f,t) ioctl(f,TCGETA,(char *)t)
-#else /* TCSETA */
-#define TCSANOW TIOCSETA
-#define TCSADRAIN TIOCSETAW
-#define tcgetattr(f,t) ioctl(f,TIOCGETA,(char *)t)
-#endif /* TCSETA */
-
-#endif /* TCSETS */
-
-#define tcsetattr(f,a,t) ioctl(f,a,t)
-#define cfsetospeed(tp,val) (tp)->c_cflag &= ~CBAUD;(tp)->c_cflag|=(val)
-#define cfgetospeed(tp) ((tp)->c_cflag & CBAUD)
-
-#ifdef CIBAUD
-#define cfsetispeed(tp,val) \
- (tp)->c_cflag &= ~CIBAUD; (tp)->c_cflag |= ((val)<<IBSHIFT)
-#define cfgetispeed(tp) (((tp)->c_cflag & CIBAUD)>>IBSHIFT)
-#else /* CIBAUD */
-#define cfsetispeed(tp,val) (tp)->c_cflag &= ~CBAUD; (tp)->c_cflag|=(val)
-#define cfgetispeed(tp) ((tp)->c_cflag & CBAUD)
-#endif /* CIBAUD */
-
-#endif /* TCSANOW */
-
-struct termios termbuf, termbuf2; /* pty control structure */
-
-#ifdef INIT_SPTY
-static int spty = -1;
-#endif /* INIT_SPTY */
-
-#endif /* USE_TERMIO */
-
-#ifdef QNX /* 299 */
-#ifndef IXANY
-#define IXANY 0
-#endif /* IXANY */
-#endif /* QNX */
-
-static int msg = 0;
-
-/* Variables available to other modules */
-
-int pty_fork_active = 0; /* pty fork is active */
-PID_T pty_fork_pid = -1; /* pty fork pid */
-int pty_slave_fd = -1; /* pty slave file descriptor */
-int pty_master_fd = -1; /* pty master file descriptor */
-
-/* termbuf routines (begin) */
-/*
- init_termbuf()
- copy_termbuf(cp)
- set_termbuf()
-
- These three routines are used to get and set the "termbuf" structure
- to and from the kernel. init_termbuf() gets the current settings.
- copy_termbuf() hands in a new "termbuf" to write to the kernel, and
- set_termbuf() writes the structure into the kernel.
-*/
-VOID
-init_termbuf(fd) int fd; {
- int ttyfd;
- int rc = 0;
-
- ttyfd = fd;
-
-#ifdef HAVE_STREAMS
- debug(F100,"init_termbuf HAVE_STREAMS","",0);
-#else
- debug(F100,"init_termbuf HAVE_STREAMS NOT DEFINED","",0);
-#endif /* HAVE_STREAMS */
-#ifdef STREAMSPTY
- debug(F100,"init_termbuf STREAMSPTY","",0);
-#else
- debug(F100,"init_termbuf STREAMSPTY NOT DEFINED","",0);
-#endif /* STREAMSPTY */
-#ifdef INIT_SPTY
- debug(F100,"init_termbuf INIT_SPTY","",0);
-#else
- debug(F100,"init_termbuf INIT_SPTY NOT DEFINED","",0);
-#endif /* INIT_SPTY */
-
- debug(F101,"init_termbuf ttyfd","",ttyfd);
-#ifdef INIT_SPTY
- debug(F101,"init_termbuf spty","",spty);
-#endif /* INIT_SPTY */
-
- memset(&termbuf,0,sizeof(termbuf));
- memset(&termbuf2,0,sizeof(termbuf2));
-#ifndef USE_TERMIO
- rc = ioctl(ttyfd, TIOCGETP, (char *)&termbuf.sg);
- rc |= ioctl(ttyfd, TIOCGETC, (char *)&termbuf.tc);
- rc |= ioctl(ttyfd, TIOCGLTC, (char *)&termbuf.ltc);
-#ifdef TIOCGSTATE
- rc |= ioctl(ttyfd, TIOCGSTATE, (char *)&termbuf.state);
-#endif /* TIOCGSTATE */
-#else /* USE_TERMIO */
- errno = 0;
-#ifdef INIT_SPTY
- rc = tcgetattr(spty, &termbuf);
- debug(F111,"init_termbuf() tcgetattr(spty)",ckitoa(rc),errno);
-#else
- rc = tcgetattr(ttyfd, &termbuf);
- debug(F111,"init_termbuf() tcgetattr(ttyfd)",ckitoa(rc),errno);
-#endif /* INIT_SPTY */
-#endif /* USE_TERMIO */
- if (!rc)
- termbuf2 = termbuf;
-}
-
-#ifdef TIOCPKT_IOCTL
-VOID
-copy_termbuf(cp, len) char *cp; int len; {
- if (len > sizeof(termbuf))
- len = sizeof(termbuf);
- memcpy((char *)&termbuf, cp, len);
- termbuf2 = termbuf;
-}
-#endif /* TIOCPKT_IOCTL */
-
-VOID
-set_termbuf(fd) int fd; { /* Only make the necessary changes. */
- int x;
- int ttyfd;
- ttyfd = fd;
-
- debug(F101,"set_termbuf ttyfd","",ttyfd);
-#ifdef INIT_SPTY
- debug(F101,"set_termbuf spty","",spty);
-#endif /* INIT_SPTY */
-
-#ifndef USE_TERMIO
- debug(F100,"set_termbuf USE_TERMIO","",0);
- if (memcmp((char *)&termbuf.sg, (char *)&termbuf2.sg, sizeof(termbuf.sg)))
- ioctl(ttyfd, TIOCSETN, (char *)&termbuf.sg);
- if (memcmp((char *)&termbuf.tc, (char *)&termbuf2.tc, sizeof(termbuf.tc)))
- ioctl(ttyfd, TIOCSETC, (char *)&termbuf.tc);
- if (memcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc,
- sizeof(termbuf.ltc)))
- ioctl(ttyfd, TIOCSLTC, (char *)&termbuf.ltc);
- if (termbuf.lflags != termbuf2.lflags)
- ioctl(ttyfd, TIOCLSET, (char *)&termbuf.lflags);
-#else /* USE_TERMIO */
- x = memcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf));
- debug(F101,"set_termbuf !USE_TERMIO memcmp","",x);
- x = 1; /* Force this */
- if (x) {
- int x;
- errno = 0;
-#ifdef INIT_SPTY
- debug(F100,"set_termbuf INIT_SPTY","",0);
- x = tcsetattr(spty, TCSANOW, &termbuf);
- debug(F111,"set_termbuf tcsetattr(spty)",ckitoa(x),errno);
-#else
- debug(F100,"set_termbuf !INIT_SPTY","",0);
- x = tcsetattr(ttyfd, TCSANOW, &termbuf);
- debug(F111,"set_termbuf tcsetattr(ttyfd)",ckitoa(x),errno);
-#endif /* INIT_SPTY */
- }
-#endif /* USE_TERMIO */
-}
-/* termbuf routines (end) */
-
-VOID
-ptyint_vhangup() {
-#ifdef CK_VHANGUP
-#ifdef CK_POSIX_SIG
- struct sigaction sa;
- /* Initialize "sa" structure. */
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- sigaction(SIGHUP, &sa, (struct sigaction *)0);
- vhangup();
- sa.sa_handler = SIG_DFL;
- sigaction(SIGHUP, &sa, (struct sigaction *)0);
-#else /* CK_POSIX_SIG */
- signal(SIGHUP,SIG_IGN);
- vhangup();
- signal(SIGHUP,SIG_DFL);
-#endif /* CK_POSIX_SIG */
-#endif /* CK_VHANGUP */
-}
-
-/*
- This routine is called twice. It's not particularly important that the
- setsid() or TIOCSCTTY ioctls succeed (they may not the second time), but
- rather that we have a controlling terminal at the end. It is assumed that
- vhangup doesn't exist and confuse the process's notion of controlling
- terminal on any system without TIOCNOTTY. That is, either vhangup() leaves
- the controlling terminal in tact, breaks the association completely, or the
- system provides TIOCNOTTY to get things back into a reasonable state. In
- practice, vhangup() either breaks the association completely or doesn't
- effect controlling terminals, so this condition is met.
-*/
-long
-ptyint_void_association() {
- int con_fd;
-#ifdef HAVE_SETSID
- debug(F110,
- "ptyint_void_association()",
- "setsid()",
- 0
- );
- setsid();
-#endif /* HAVE_SETSID */
-
-#ifndef NO_DEVTTY
- /* Void tty association first */
-#ifdef TIOCNOTTY
- con_fd = open("/dev/tty", O_RDWR);
- debug(F111,
- "ptyint_void_association() open(/dev/tty,O_RDWR)",
- "/dev/tty",
- con_fd);
- if (con_fd >= 0) {
- ioctl(con_fd, TIOCNOTTY, 0);
- close(con_fd);
- }
-#ifdef DEBUG
- else debug(F101, "ptyint_void_association() open() errno","",errno);
-#endif /* DEBUG */
-#endif /* TIOCNOTTY */
-#endif /* NO_DEVTTY */
- return(0);
-}
-
-/* PID may be zero for unknown.*/
-
-long
-pty_cleanup(slave, pid, update_utmp) char *slave; int pid; int update_utmp; {
-#ifdef VHANG_LAST
- int retval, fd;
-#endif /* VHANG_LAST */
-
- debug(F111,"pty_cleanup()",slave,pid);
-#ifdef WANT_UTMP
- if (update_utmp)
- pty_update_utmp(PTY_DEAD_PROCESS,
- 0,
- "",
- slave,
- (char *)0,
- PTY_UTMP_USERNAME_VALID
- );
-#endif /* WANT_UTMP */
-
-#ifdef SETUID
- chmod(slave, 0666);
- chown(slave, 0, 0);
-#endif /* SETUID */
-
-#ifdef HAVE_REVOKE
- revoke(slave);
- /*
- Revoke isn't guaranteed to send a SIGHUP to the processes it
- dissociates from the terminal. The best solution without a Posix
- mechanism for forcing a hangup is to killpg() the process group of the
- pty. This will at least kill the shell and hopefully, the child
- processes. This is not always the case, however. If the shell puts
- each job in a process group and doesn't pass along SIGHUP, all
- processes may not die.
- */
- if (pid > 0) {
-#ifdef HAVE_KILLPG
- killpg(pid, SIGHUP);
-#else
- kill(-(pid), SIGHUP);
-#endif /*HAVE_KILLPG*/
- }
-#else /* HAVE_REVOKE*/
-#ifdef VHANG_LAST
- {
- int status;
-#ifdef CK_POSIX_SIG
- sigset_t old, new;
- sigemptyset(&new);
- sigaddset(&new, SIGCHLD);
- sigprocmask(SIG_BLOCK, &new, &old);
-#else /*CK_POSIX_SIG*/
- int mask = sigblock(sigmask(SIGCHLD));
-#endif /*CK_POSIX_SIG*/
- switch (retval = fork()) {
- case -1:
-#ifdef CK_POSIX_SIG
- sigprocmask(SIG_SETMASK, &old, 0);
-#else /*CK_POSIX_SIG*/
- sigsetmask(mask);
-#endif /*CK_POSIX_SIG*/
- return errno;
- case 0:
- ptyint_void_association();
- if (retval = (pty_open_ctty(slave, &fd, -1)))
- exit(retval);
- ptyint_vhangup();
- exit(0);
- break;
- default:
-#ifdef HAVE_WAITPID
- waitpid(retval, &status, 0);
-#else /*HAVE_WAITPID*/
- wait(&status);
-#endif /* HAVE_WAITPID */
-#ifdef CK_POSIX_SIG
- sigprocmask(SIG_SETMASK, &old, 0);
-#else /*CK_POSIX_SIG*/
- sigsetmask(mask);
-#endif /*CK_POSIX_SIG*/
- break;
- }
- }
-#endif /*VHANG_LAST*/
-#endif /* HAVE_REVOKE*/
-#ifndef HAVE_STREAMS
- slave[strlen("/dev/")] = 'p';
-#ifdef SETUID
- chmod(slave, 0666);
- chown(slave, 0, 0);
-#endif /* SETUID */
-#endif /* HAVE_STREAMS */
- return(0);
-}
-
-long
-pty_getpty(fd, slave, slavelength) int slavelength; int *fd; char *slave; {
- char *cp;
- char *p;
- int i, ptynum;
- struct stat stb;
-#ifndef HAVE_OPENPTY
-#ifndef HAVE__GETPTY
- char slavebuf[1024];
-#endif /* HAVE__GETPTY */
-#endif /* HAVE_OPENPTY */
-#ifdef HAVE__GETPTY
- char *slaveret; /* Temp to hold pointer to slave */
-#endif /*HAVE__GETPTY*/
-
-#ifdef HAVE_OPENPTY
- int slavefd;
-
- pty_master_fd = -1;
- debug(F100,"HAVE_OPENPTY","",0);
- if (openpty(fd,
- &slavefd,
- slave,
- (struct termios *)0,
- (struct winsize *)0
- )
- ) {
- pty_master_fd = *fd;
- return(1);
- }
- close(slavefd);
- return(0);
-
-#else /* HAVE_OPENPTY */
-
-#ifdef HAVE__GETPTY
-/*
- This code is included for Irix; as of version 5.3, Irix has /dev/ptmx, but
- it fails to work properly; even after calling unlockpt, root gets permission
- denied opening the pty. The code to support _getpty should be removed if
- Irix gets working streams ptys in favor of maintaining the least needed code
- paths.
-*/
- debug(F100,"HAVE__GETPTY","",0);
- if ((slaveret = _getpty(fd, O_RDWR | O_NDELAY, 0600, 0)) == 0) {
- *fd = -1;
- return(PTY_GETPTY_NOPTY);
- }
- if (strlen(slaveret) > slavelength - 1) {
- close(*fd);
- *fd = -1;
- return(PTY_GETPTY_SLAVE_TOOLONG);
- } else {
- ckstrncpy(slave, slaveret, slavelength);
- }
- return(0);
-
-#else /* HAVE__GETPTY */
-
- *fd = open("/dev/ptym/clone", O_RDWR|O_NDELAY); /* HPUX */
- if (*fd >= 0) {
- debug(F110,"pty_getpty()","open(/dev/ptym/clone) success",0);
- goto have_fd;
- }
-
-#ifdef HAVE_PTMX
- debug(F100,"HAVE_PTMX","",0);
- *fd = open("/dev/ptmx",O_RDWR|O_NDELAY);
- if (*fd >= 0) {
- debug(F110,"pty_getpty()","open(/dev/ptmx) success",0);
- goto have_fd;
- }
-#endif /* HAVE_PTMX */
-
- *fd = open("/dev/ptc", O_RDWR|O_NDELAY); /* AIX */
- if (*fd >= 0) {
- debug(F110,"pty_getpty()","open(/dev/ptc) success",0);
- goto have_fd;
- }
- *fd = open("/dev/pty", O_RDWR|O_NDELAY); /* sysvimp */
- if (*fd >= 0)
- debug(F110,"pty_getpty()","open(/dev/pty) success",0);
-
- have_fd:
- /* This would be the pty master */
- debug(F101,"pty_getpty fd(A)","",*fd);
- if (*fd >= 0) {
- pty_master_fd = *fd;
-
-#ifdef HAVE_GRANTPT
-#ifdef HAVE_PTMX
- debug(F100,"HAVE_GRANTPT","",0);
- if (grantpt(*fd) || unlockpt(*fd))
- return(PTY_GETPTY_STREAMS);
-#endif /* HAVE_PTMX */
-#endif /* HAVE_GRANTPT */
-
-#ifdef HAVE_PTSNAME
- debug(F100,"HAVE_PTSNAME","",0);
- p = (char *)ptsname(*fd);
- debug(F110,"pty_getpty() ptsname()",p,0);
-#else
-#ifdef HAVE_TTYNAME
- debug(F100,"HAVE_TTYNAME","",0);
- p = ttyname(*fd);
- debug(F110,"pty_getpty() ttyname()",p,0);
-#else
- /* If we don't have either what do we do? */
- return(PTY_GETPTY_NOPTY); /* punt */
-#endif /* HAVE_TTYNAME */
-#endif /* HAVE_PTSNAME */
- if (p) {
- if (strlen(p) > slavelength - 1) {
- close (*fd);
- *fd = -1;
- return(PTY_GETPTY_SLAVE_TOOLONG);
- }
- ckstrncpy(slave, p, slavelength);
- return(0);
- }
- if (fstat(*fd, &stb) < 0) {
- close(*fd);
- return(PTY_GETPTY_FSTAT);
- }
- ptynum = (int)(stb.st_rdev&0xFF);
- sprintf(slavebuf, "/dev/ttyp%x", ptynum); /* safe */
- if (strlen(slavebuf) > slavelength - 1) {
- close(*fd);
- *fd = -1;
- return(PTY_GETPTY_SLAVE_TOOLONG);
- }
- debug(F110,"pty_getpty() slavebuf",slavebuf,0);
- ckstrncpy(slave, slavebuf, slavelength);
- return(0);
- } else {
- for (cp = "pqrstuvwxyzPQRST";*cp; cp++) {
- sprintf(slavebuf,"/dev/ptyXX"); /* safe */
- slavebuf[sizeof("/dev/pty") - 1] = *cp;
- slavebuf[sizeof("/dev/ptyp") - 1] = '0';
- if (stat(slavebuf, &stb) < 0)
- break;
- for (i = 0; i < 16; i++) {
- slavebuf[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i];
- errno = 0;
- *fd = open(slavebuf, O_RDWR|O_NDELAY);
- if (*fd < 0) {
- debug(F111,"pty_getpty() pty master open error",
- slavebuf,errno);
- continue;
- }
- debug(F111,"pty_getpty() found pty master",slavebuf,*fd);
- slavebuf[sizeof("/dev/") - 1] = 't'; /* got pty */
- if (strlen(slavebuf) > slavelength -1) {
- close(*fd);
- *fd = -1;
- return(PTY_GETPTY_SLAVE_TOOLONG);
- }
- ckstrncpy(slave, slavebuf, slavelength);
- debug(F110,"pty_getpty slave name",slave,0);
- pty_master_fd = *fd;
- return(0);
- }
- }
- return(PTY_GETPTY_NOPTY);
- }
-#endif /*HAVE__GETPTY*/
-#endif /* HAVE_OPENPTY */
-}
-
-long
-pty_init() {
-#ifdef HAVE_PTYM
- static char dummy;
- debug(F100,"HAVE_PTYM","",0);
- tty_bank = &master_name[strlen("/dev/ptym/pty")];
- tty_num = &master_name[strlen("/dev/ptym/ptyX")];
- slave_bank = &slave_name[strlen("/dev/pty/tty")];
- slave_num = &slave_name[strlen("/dev/pty/ttyX")];
-#endif
- return(0L);
-}
-
-/*
- The following is an array of modules that should be pushed on the stream.
- See configure.in for caviats and notes about when this array is used and not
- used.
-*/
-#ifdef HAVE_STREAMS
-#ifndef HAVE_LINE_PUSH
-static char *push_list[] = {
-#ifdef PUSH_PTEM
- "ptem",
-#endif
-#ifdef PUSH_LDTERM
- "ldterm",
-#endif
-#ifdef PUSH_TTCOMPAT
- "ttcompat",
-#endif
- 0
-};
-#endif /* HAVE_LINE_PUSH */
-#endif /* HAVE_STREAMS */
-
-long
-pty_initialize_slave (fd) int fd; {
-#ifdef POSIX_TERMIOS
-#ifndef ultrix
- struct termios new_termio;
-#else
- struct sgttyb b;
-#endif /* ultrix */
-#else
- struct sgttyb b;
-#endif /* POSIX_TERMIOS */
- int pid;
-#ifdef POSIX_TERMIOS
-#ifndef ultrix
- int rc;
-#endif /* ultrix */
-#endif /* POSIX_TERMIOS */
-
- debug(F111,"pty_initialize_slave()","fd",fd);
-
-#ifdef HAVE_STREAMS
-#ifdef HAVE_LINE_PUSH
- while (ioctl(fd,I_POP,0) == 0) ; /* Clear out any old lined's */
-
- if (line_push(fd) < 0) {
- debug(F110,"pty_initialize_slave()","line_push() failed",0);
- close(fd);
- fd = -1;
- return(PTY_OPEN_SLAVE_LINE_PUSHFAIL);
- }
-#else /*No line_push */
- {
- char **module = &push_list[0];
- while (*module) {
- if (ioctl(fd, I_PUSH, *(module++)) < 0) {
- debug(F110,"pty_initialize_slave()","ioctl(I_PUSH) failed",0);
- return(PTY_OPEN_SLAVE_PUSH_FAIL);
- }
- }
- }
-#endif /*LINE_PUSH*/
-#endif /*HAVE_STREAMS*/
-/*
- Under Ultrix 3.0, the pgrp of the slave pty terminal needs to be set
- explicitly. Why rlogind works at all without this on 4.3BSD is a mystery.
-*/
-#ifdef GETPGRP_ONEARG
- pid = getpgrp(getpid());
-#else
- pid = getpgrp();
-#endif /* GETPGRP_ONEARG */
-
- debug(F111,"pty_initialize_slave()","pid",pid);
-
-#ifdef TIOCSPGRP
- ioctl(fd, TIOCSPGRP, &pid);
-#endif /* TIOCSPGRP */
-
-#ifdef POSIX_TERMIOS
-#ifndef ultrix
- tcsetpgrp(fd, pid);
- errno = 0;
- rc = tcgetattr(fd,&new_termio);
- debug(F111,"pty_initialize_slave tcgetattr(fd)",ckitoa(rc),errno);
- if (rc == 0) {
- new_termio.c_cc[VMIN] = 1;
- new_termio.c_cc[VTIME] = 0;
- rc = tcsetattr(fd,TCSANOW,&new_termio);
- debug(F111,"pty_initialize_slave tcsetattr(fd)",ckitoa(rc),errno);
- }
-#endif /* ultrix */
-#endif /* POSIX_TERMIOS */
- return(0L);
-}
-
-#ifdef WANT_UTMP
-long
-pty_logwtmp (tty, user, host) char *user, *tty, *host; {
-#ifdef HAVE_LOGWTMP
- logwtmp(tty,user,host);
- return(0);
-#else
- struct utmp ut;
- char *tmpx;
- char utmp_id[5];
- int loggingin = user[0]; /* Will be empty for logout */
-
-#ifndef NO_UT_HOST
- strncpy(ut.ut_host, host, sizeof(ut.ut_host));
-#endif /* NO_UT_HOST */
-
- strncpy(ut.ut_line, tty, sizeof(ut.ut_line));
- ut.ut_time = time(0);
-
-#ifndef NO_UT_PID
- ut.ut_pid = getpid();
- strncpy(ut.ut_user, user, sizeof(ut.ut_user));
-
- tmpx = tty + strlen(tty) - 2;
- ckmakmsg(utmp_id,5,"kr",tmpx,NULL,NULL);
- strncpy(ut.ut_id, utmp_id, sizeof(ut.ut_id));
- ut.ut_pid = (loggingin ? getpid() : 0);
- ut.ut_type = (loggingin ? USER_PROCESS : DEAD_PROCESS);
-#else
- strncpy(ut.ut_name, user, sizeof(ut.ut_name));
-#endif /* NO_UT_PID */
-
- return(ptyint_update_wtmp(&ut, host, user));
-
-#endif /* HAVE_LOGWTMP */
-}
-#endif /* WANT_UTMP */
-
-/*
- This routine is called twice. It's not particularly important that the
- setsid() or TIOCSCTTY ioctls succeed (they may not the second time), but
- rather that we have a controlling terminal at the end. It is assumed that
- vhangup doesn't exist and confuse the process's notion of controlling
- terminal on any system without TIOCNOTTY. That is, either vhangup() leaves
- the controlling terminal in tact, breaks the association completely, or the
- system provides TIOCNOTTY to get things back into a reasonable state. In
- practice, vhangup() either breaks the association completely or doesn't
- effect controlling terminals, so this condition is met.
-*/
-long
-pty_open_ctty(slave, fd, fc) char * slave; int *fd; int fc; {
- int retval;
-
- debug(F110,"pty_open_ctty() slave",slave,0);
-
-/* First, dissociate from previous terminal */
-
- if ((retval = ptyint_void_association()) != 0) {
- debug(F111,
- "pty_open_ctty()",
- "ptyint_void_association() failed",
- retval
- );
- return(retval);
- }
-#ifdef MUST_SETPGRP
-/*
- The Ultrix (and other BSD tty drivers) require the process group
- to be zero in order to acquire the new tty as a controlling tty.
-*/
- setpgrp(0,0);
- debug(F101,"pty_open_ctty MUST_SETPGRP setpgrp(0,0)","",errno);
-#endif /* MUST_SETPGRP */
-
- errno = 0;
- *fd = open(slave, O_RDWR);
- debug(F111,"pty_open_ctty open(slave) fd",slave,*fd);
- if (*fd < 0) {
- debug(F111,"pty_open_ctty() open failure", slave, errno);
- return(PTY_OPEN_SLAVE_OPENFAIL);
- }
-#ifdef SOLARIS
- /* This forces the job to have a controlling terminal. */
- close(*fd);
- *fd = open(slave, O_RDWR);
- debug(F111,"pty_open_ctty close/open(slave) fd",slave,*fd);
-#ifdef DEBUG
- /* This shows that /dev/tty exists */
-if (deblog) {
- int x;
- x = open("/dev/tty", O_RDWR);
- debug(F111,"pty_open_ctty open(/dev/tty) fd",slave,x);
- if (x < 0) debug(F111,"pty_open_ctty open(/dev/tty) errno","",errno);
- debug(F110,"pty_open_ctty ttyname(/dev/tty)",ttyname(x),0);
- if (x > -1) close(x);
- }
-#endif /* DEBUG */
-#endif /* SOLARIS */
-
-#ifdef MUST_SETPGRP
- setpgrp(0, getpid());
-#endif /* MUST_SETPGRP */
-
-#ifdef TIOCSCTTY
- if (
-#ifdef COMMENT
- fc == 0
-#else
- 1
-#endif /* COMMENT */
- ) {
- /* TIOCSCTTY = Make this the job's controlling terminal */
- errno = 0;
- retval = ioctl(*fd, TIOCSCTTY, 0); /* Don't check return.*/
- debug(F111,"pty_open_ctty() ioctl TIOCSCTTY",ckitoa(retval),errno);
- }
-#endif /* TIOCSCTTY */
- return(0L);
-}
-
-long
-pty_open_slave(slave, fd, fc) char *slave; int *fd; int fc; {
- int vfd, testfd;
- long retval;
-#ifdef CK_POSIX_SIG
- struct sigaction sa;
-
- sigemptyset(&sa.sa_mask); /* Initialize "sa" structure. */
- sa.sa_flags = 0;
-#endif /* CK_POSIX_SIG */
-
-/*
- First, chmod and chown the slave. If we have vhangup then we really need
- pty_open_ctty to make sure our controlling terminal is the pty we're
- opening. However, if we are using revoke or nothing then we just need a
- file descriiptor for the pty. Considering some OSes in this category break
- on the second call to open_ctty (currently OSF but others may), we simply
- use a descriptor if we can.
-*/
-#ifdef VHANG_FIRST
- if ((retval = pty_open_ctty(slave, &vfd, fc)) != 0) {
- debug(F111,
- "pty_open_slave() VHANG_FIRST",
- "pty_open_ctty() failed",
- retval
- );
- return(retval);
- }
- if (vfd < 0) {
- debug(F111,
- "pty_open_slave() VHANG_FIRST",
- "PTY_OPEN_SLAVE_OPENFAIL",
- vfd
- );
- return(PTY_OPEN_SLAVE_OPENFAIL);
- }
-#endif /* VHANG_FIRST */
-
- if (slave == NULL || *slave == '\0') {
- debug(F110,"pty_open_slave()","PTY_OPEN_SLAVE_TOOSHORT",0);
- return(PTY_OPEN_SLAVE_TOOSHORT);
- }
-
-#ifdef SETUID
- if (chmod(slave, 0)) {
- debug(F110,"pty_open_slave()","PTY_OPEN_SLAVE_CHMODFAIL",0);
- return(PTY_OPEN_SLAVE_CHMODFAIL);
- }
- if (chown(slave, 0, 0 ) == -1 ) {
- debug(F110,"pty_open_slave()","PTY_OPEN_SLAVE_CHOWNFAIL",0);
- return(PTY_OPEN_SLAVE_CHOWNFAIL);
- }
-#endif /* SETUID */
-#ifdef VHANG_FIRST
- ptyint_vhangup();
- close(vfd);
-#endif /* VHANG_FIRST */
-
- if ((retval = ptyint_void_association()) != 0) {
- debug(F111,
- "pty_open_slave()",
- "ptyint_void_association() failed",
- retval
- );
- return(retval);
- }
-
-#ifdef HAVE_REVOKE
- if (revoke (slave) < 0 ) {
- debug(F110,"pty_open_slave()","PTY_OPEN_SLAVE_REVOKEFAIL",0);
- return(PTY_OPEN_SLAVE_REVOKEFAIL);
- }
-#endif /* HAVE_REVOKE */
-
-/* Open the pty for real. */
-
- retval = pty_open_ctty(slave, fd, fc);
- debug(F111,"pty_open_slave retval",slave,retval);
- debug(F111,"pty_open_slave fd",slave,*fd);
- if (retval != 0) {
- debug(F111,"pty_open_slave()","pty_open_ctty() failed",retval);
- return(PTY_OPEN_SLAVE_OPENFAIL);
- }
- pty_slave_fd = *fd; /* This is not visible to the upper fork */
- debug(F111,"pty_open_slave fd ctty'd",slave,pty_slave_fd);
- retval = pty_initialize_slave(*fd);
- debug(F111,"pty_open_slave fd init'd",slave,pty_slave_fd);
- if (retval) {
- debug(F111,"pty_open_slave()","pty_initialize_slave() failed",retval);
- return(retval);
- }
- /* (VOID)pty_make_raw(*fd); */
-
- debug(F100,"pty_open_slave OK","",*fd);
- return(0L);
-}
-
-#ifdef WANT_UTMP
-
-#ifndef UTMP_FILE
-#ifdef _PATH_UTMP
-#define UTMP_FILE _PATH_UTMP
-#endif /* _PATH_UTMP */
-#endif /* UTMP_FILE */
-
-/* If it is *still* missing, assume /etc/utmp */
-
-#ifndef UTMP_FILE
-#define UTMP_FILE "/etc/utmp"
-#endif /* UTMP_FILE */
-
-#ifndef NO_UT_PID
-#define WTMP_REQUIRES_USERNAME
-#endif /* NO_UT_PID */
-
-long
-pty_update_utmp(process_type, pid, username, line, host, flags)
- int process_type;
- int pid;
- char *username, *line, *host;
- int flags;
-/* pty_update_utmp */ {
- struct utmp ent, ut;
-#ifndef HAVE_SETUTENT
- struct stat statb;
- int tty;
-#endif /* HAVE_SETUTENT */
-#ifdef HAVE_SETUTXENT
- struct utmpx utx;
-#endif /* HAVE_SETUTXENT */
-#ifndef NO_UT_PID
- char *tmpx;
- char utmp_id[5];
-#endif /* NO_UT_PID */
- char userbuf[32];
- int fd;
-
- debug(F100,"pty_update_utmp()","",0);
- strncpy(ent.ut_line, line+sizeof("/dev/")-1, sizeof(ent.ut_line));
- ent.ut_time = time(0);
-
-#ifdef NO_UT_PID
- if (process_type == PTY_LOGIN_PROCESS)
- return(0L);
-#else /* NO_UT_PID */
-
- ent.ut_pid = pid;
-
- switch (process_type) {
- case PTY_LOGIN_PROCESS:
- ent.ut_type = LOGIN_PROCESS;
- break;
- case PTY_USER_PROCESS:
- ent.ut_type = USER_PROCESS;
- break;
- case PTY_DEAD_PROCESS:
- ent.ut_type = DEAD_PROCESS;
- break;
- default:
- return(PTY_UPDATE_UTMP_PROCTYPE_INVALID);
- }
-#endif /*NO_UT_PID*/
-
-#ifndef NO_UT_HOST
- if (host)
- strncpy(ent.ut_host, host, sizeof(ent.ut_host));
- else
- ent.ut_host[0] = '\0';
-#endif /* NO_UT_HOST */
-
-#ifndef NO_UT_PID
- if (!strcmp (line, "/dev/console")) {
- char * s = NULL;
-
-#ifdef sun
-#ifdef __SVR4
- s = "co";
-#else
- s = "cons";
-#endif /* __SVR4 */
-#else
- s = "cons";
-#endif /* sun */
-
- strncpy(ent.ut_id, s, 4);
-
- } else {
-
- tmpx = line + strlen(line)-1;
- if (*(tmpx-1) != '/') tmpx--; /* last 2 chars unless it's a '/' */
-#ifdef __hpux
- ckstrncpy(utmp_id, tmpx, 5);
-#else
- ckmakmsg(utmp_id,5,"kl",tmpx,NULL,NULL);
-#endif /* __hpux */
- strncpy(ent.ut_id, utmp_id, sizeof(ent.ut_id));
- }
- strncpy(ent.ut_user, username, sizeof(ent.ut_user));
-
-#else
-
- strncpy(ent.ut_name, username, sizeof(ent.ut_name));
-
-#endif /* NO_UT_PID */
-
- if (username[0])
- strncpy(userbuf, username, sizeof(userbuf));
- else
- userbuf[0] = '\0';
-
-#ifdef HAVE_SETUTENT
-
- utmpname(UTMP_FILE);
- setutent();
-/*
- If we need to preserve the user name in the wtmp structure and Our flags
- tell us we can obtain it from the utmp and we succeed in obtaining it, we
- then save the utmp structure we obtain, write out the utmp structure and
- change the username pointer so it is used by update_wtmp.
-*/
-
-#ifdef WTMP_REQUIRES_USERNAME
- if ((!username[0]) && (flags&PTY_UTMP_USERNAME_VALID) &&line) {
- struct utmp *utptr;
- strncpy(ut.ut_line, line, sizeof(ut.ut_line));
- utptr = getutline(&ut);
- if (utptr)
- strncpy(userbuf,utptr->ut_user,sizeof(ut.ut_user));
- }
-#endif /* WTMP_REQUIRES_USERNAME */
-
- pututline(&ent);
- endutent();
-
-#ifdef HAVE_SETUTXENT
- setutxent();
-#ifdef HAVE_GETUTMPX
- getutmpx(&ent, &utx);
-#else /* HAVE_GETUTMPX */
- /* For platforms like HPUX and Dec Unix which don't have getutmpx */
- strncpy(utx.ut_user, ent.ut_user, sizeof(ent.ut_user));
- strncpy(utx.ut_id, ent.ut_id, sizeof(ent.ut_id));
- strncpy(utx.ut_line, ent.ut_line, sizeof(ent.ut_line));
- utx.ut_pid = pid; /* kludge for Irix, etc. to avoid trunc. */
- utx.ut_type = ent.ut_type;
-#ifdef UT_EXIT_STRUCTURE_DIFFER
- utx.ut_exit.ut_exit = ent.ut_exit.e_exit;
-#else /* UT_EXIT_STRUCTURE_DIFFER */
-/* KLUDGE for now; eventually this will be a feature test... See PR#[40] */
-#ifdef __hpux
- utx.ut_exit.__e_termination = ent.ut_exit.e_termination;
- utx.ut_exit.__e_exit = ent.ut_exit.e_exit;
-#else /* __hpux */
- /* XXX do nothing for now; we don't even know the struct member exists */
-#endif /* __hpux */
-#endif /* UT_EXIT_STRUCTURE_DIFFER */
- utx.ut_tv.tv_sec = ent.ut_time;
- utx.ut_tv.tv_usec = 0;
-#endif /* HAVE_GETUTMPX */
- if (host)
- strncpy(utx.ut_host, host, sizeof(utx.ut_host));
- else
- utx.ut_host[0] = 0;
- pututxline(&utx);
- endutxent();
-#endif /* HAVE_SETUTXENT */
-
-#else /* HAVE_SETUTENT */
- if (flags&PTY_TTYSLOT_USABLE) {
- tty = ttyslot();
- } else {
- int lc;
- tty = -1;
- if ((fd = open(UTMP_FILE, O_RDWR)) < 0)
- return(errno);
- for (lc = 0;
- lseek(fd, (off_t)(lc * sizeof(struct utmp)), SEEK_SET) != -1;
- lc++
- ) {
- if (read(fd,
- (char *)&ut,
- sizeof(struct utmp)
- ) != sizeof(struct utmp)
- )
- break;
- if (strncmp(ut.ut_line, ent.ut_line, sizeof(ut.ut_line)) == 0) {
- tty = lc;
-#ifdef WTMP_REQUIRES_USERNAME
- if (!username&&(flags&PTY_UTMP_USERNAME_VALID))
- strncpy(userbuf, ut.ut_user, sizeof(ut.ut_user));
-#endif /* WTMP_REQUIRES_USERNAME */
- break;
- }
- }
- close(fd);
- }
- if (tty > 0 && (fd = open(UTMP_FILE, O_WRONLY, 0)) >= 0) {
- lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
- write(fd, (char *)&ent, sizeof(struct utmp));
- close(fd);
- }
-#endif /* HAVE_SETUTENT */
-
- /* Don't record LOGIN_PROCESS entries. */
- if (process_type == PTY_LOGIN_PROCESS)
- return(0);
- else
- return(ptyint_update_wtmp(&ent, host, userbuf));
-}
-#ifndef WTMP_FILE
-#ifdef _PATH_WTMP
-#define WTMP_FILE _PATH_WTMP
-#endif /* _PATH_WTMP */
-#endif /* WTMP_FILE */
-
-#ifndef WTMPX_FILE
-#ifdef _PATH_WTMPX
-#ifdef HAVE_UPDWTMPX
-#define WTMPX_FILE _PATH_WTMPX
-#endif /* HAVE_UPDWTMPX */
-#endif /* _PATH_WTMPX */
-#endif /* WTMPX_FILE */
-
-/* If it is *still* missing, assume /usr/adm/wtmp */
-
-#ifndef WTMP_FILE
-#define WTMP_FILE "/usr/adm/wtmp"
-#endif /* WTMP_FILE */
-
-#ifdef COMMENT
-/* The following test can not be made portably */
-
-/* #if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) */
-/*
- This is ugly, but the lack of standardization in the utmp/utmpx space, and
- what glibc implements and doesn't make available, is even worse.
-*/
-/* #undef HAVE_UPDWTMPX */ /* Don't use updwtmpx for glibc 2.1 */
-/* #endif */ /* __GLIBC__ etc */
-
-#else /* COMMENT */
-
-#ifdef __GLIBC__
-#undef HAVE_UPDWTMPX /* Don't use updwtmpx for glibc period */
-#endif /* __GLIBC__ */
-#endif /* COMMENT */
-
-long
-ptyint_update_wtmp(ent,host,user) struct utmp *ent; char *host; char *user; {
- struct utmp ut;
- struct stat statb;
- int fd;
- time_t uttime;
-#ifdef HAVE_UPDWTMPX
- struct utmpx utx;
-
- getutmpx(ent, &utx);
- if (host)
- strncpy(utx.ut_host, host, sizeof(utx.ut_host) );
- else
- utx.ut_host[0] = 0;
- if (user)
- strncpy(utx.ut_user, user, sizeof(utx.ut_user));
- updwtmpx(WTMPX_FILE, &utx);
-#endif /* HAVE_UPDWTMPX */
-
-#ifdef HAVE_UPDWTMP
-#ifndef HAVE_UPDWTMPX
- /* This is already performed byupdwtmpx if present.*/
- updwtmp(WTMP_FILE, ent);
-#endif /* HAVE_UPDWTMPX*/
-#else /* HAVE_UPDWTMP */
-
- if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) >= 0) {
- if (!fstat(fd, &statb)) {
- memset((char *)&ut, 0, sizeof(ut));
-#ifdef __hpux
- strncpy(ut.ut_id, ent->ut_id, sizeof (ut.ut_id));
-#endif /* __hpux */
- strncpy(ut.ut_line, ent->ut_line, sizeof(ut.ut_line));
- strncpy(ut.ut_name, ent->ut_name, sizeof(ut.ut_name));
-#ifndef NO_UT_HOST
- strncpy(ut.ut_host, ent->ut_host, sizeof(ut.ut_host));
-#endif /* NO_UT_HOST */
-
- time(&uttime);
- ut.ut_time = uttime;
-
-#ifdef HAVE_GETUTENT
-#ifdef USER_PROCESS
- if (ent->ut_name) {
- if (!ut.ut_pid)
- ut.ut_pid = getpid();
-#ifndef __hpux
- ut.ut_type = USER_PROCESS;
-#else /* __hpux */
- ut.ut_type = ent->ut_type;
-#endif /* __hpux */
-
- } else {
-
-#ifdef EMPTY
- ut.ut_type = EMPTY;
-#else
- ut.ut_type = DEAD_PROCESS; /* For Linux brokenness*/
-#endif /* EMPTY */
-
- }
-#endif /* USER_PROCESS */
-#endif /* HAVE_GETUTENT */
-
- if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
- sizeof(struct utmp))
-#ifndef COHERENT
- ftruncate(fd, statb.st_size);
-#else
- chsize(fd, statb.st_size);
-#endif /* COHERENT */
- }
- close(fd);
- }
-#endif /* HAVE_UPDWTMP */
- return(0); /* no current failure cases; file not found is not failure! */
-}
-#endif /* WANT_UTMP */
-
-/* This is for ancient Unixes that don't have these tty symbols defined. */
-
-#ifndef PENDIN
-#define PENDIN ICANON
-#endif /* PENDIN */
-#ifndef FLUSHO
-#define FLUSHO ICANON
-#endif /* FLUSHO */
-#ifndef IMAXBEL
-#define IMAXBEL ICANON
-#endif /* IMAXBEL */
-#ifndef EXTPROC
-#define EXTPROC ICANON
-#endif /* EXTPROC */
-
-static char Xline[17] = { 0, 0 };
-/*
- getptyslave()
- Open the slave side of the pty, and do any initialization that is necessary.
- The return value fd is a file descriptor for the slave side.
- fc = function code from do_pty() (q.v.)
-*/
-int
-getptyslave(fd, fc) int * fd, fc; {
- int ttyfd;
- int t = -1;
- long retval;
-#ifdef TIOCGWINSZ
- struct winsize ws;
- extern int cmd_rows, cmd_cols;
-#endif /* TIOCGWINSZ */
-
- ttyfd = *fd;
- debug(F111,"getptyslave()","ttyfd",ttyfd);
- /*
- * Opening the slave side may cause initilization of the
- * kernel tty structure. We need remember the state of:
- * if linemode was turned on
- * terminal window size
- * terminal speed
- * so that we can reset them if we need to.
- */
- if ((retval = pty_open_slave(Xline, &t, fc)) != 0) {
- perror(Xline);
- msg++;
- debug(F111,"getptyslave()","Unable to open slave",retval);
- return(-1);
- }
- debug(F111,"getptyslave","t",t);
-#ifdef INIT_SPTY
- spty = t;
- debug(F111,"getptyslave","spty",spty);
-#endif /* INIT_SPTY */
-#ifdef STREAMSPTY
- if (ioctl(t,I_PUSH,"pckt") < 0) {
- debug(F111,"getptyslave()","ioctl(I_PUSH) failed",errno);
-#ifndef _AIX
- fatal("I_PUSH pckt");
-#endif /* _AIX */
- }
-#endif /* STREAMSPTY */
-
- /* Set up the tty modes as we like them to be. */
-#ifdef COMMENT
- /* Originally like this... But this is the master - we want the slave */
- /* Anyway, this fails on Solaris and probably other System V OS's */
- init_termbuf(ttyfd);
-#else
- init_termbuf(t);
-#endif /* COMMENT */
-#ifdef TIOCGWINSZ
- if (cmd_rows || cmd_cols) {
- memset((char *)&ws, 0, sizeof(ws));
- ws.ws_col = cmd_cols;
- ws.ws_row = cmd_rows;
- debug(F101,"getptyslave() doing TIOCSWINSZ...","",t);
- ioctl(t, TIOCSWINSZ, (char *)&ws);
- }
-#endif /* TIOCGWINSZ */
-
- /* For external protocols, put the pty in no-echo mode */
- if (fc == 1) {
- debug(F100,"getptyslave() setting rawmode","",0);
- /* iflags */
- termbuf.c_iflag &= ~(PARMRK|ISTRIP|BRKINT|INLCR|IGNCR|ICRNL);
- termbuf.c_iflag &= ~(INPCK|IGNPAR|IMAXBEL|IXANY|IXON|IXOFF);
- termbuf.c_iflag |= IGNBRK;
-#ifdef IUCLC
- termbuf.c_iflag &= ~IUCLC;
-#endif /* IUCLC */
-
- /* oflags */
- termbuf.c_oflag &= ~OPOST;
-#ifdef OXTABS
- termbuf.c_oflag &= ~OXTABS;
-#endif /* OXTABS */
-#ifdef ONOCR
- termbuf.c_oflag &= ~ONOCR;
-#endif /* ONOCR */
-#ifdef ONLRET
- termbuf.c_oflag &= ~ONLRET;
-#endif /* ONLRET */
-#ifdef ONLCR
- termbuf.c_oflag &= ~ONLCR;
-#endif /* ONLCR */
-
- /* lflags */
- termbuf.c_lflag &= ~ECHO;
-#ifdef ECHOE
- termbuf.c_lflag &= ~ECHOE;
-#endif /* ECHOE */
-#ifdef ECHONL
- termbuf.c_lflag &= ~ECHONL;
-#endif /* ECHONL */
-#ifdef ECHOPRT
- termbuf.c_lflag &= ~ECHOPRT;
-#endif /* ECHOPRT */
-#ifdef ECHOKE
- termbuf.c_lflag &= ~ECHOKE;
-#endif /* ECHOKE */
-#ifdef ECHOCTL
- termbuf.c_lflag &= ~ECHOCTL;
-#endif /* ECHOCTL */
-#ifdef ALTWERASE
- termbuf.c_lflag &= ~ALTWERASE;
-#endif /* ALTWERASE */
-#ifdef EXTPROC
- termbuf.c_lflag &= ~EXTPROC;
-#endif /* EXTPROC */
- termbuf.c_lflag &= ~(ICANON|ISIG|IEXTEN|TOSTOP|FLUSHO|PENDIN);
-
-#ifdef NOKERNINFO
- termbuf.c_lflag |= NOKERNINFO;
-#endif /* NOKERNINFO */
- /* termbuf.c_lflag |= NOFLSH; */
- termbuf.c_lflag &= ~NOFLSH;
-
- /* cflags */
- termbuf.c_cflag &= ~(CSIZE|PARENB|PARODD);
- termbuf.c_cflag |= CS8|CREAD;
-#ifdef VMIN
- termbuf.c_cc[VMIN] = 1;
-#endif /* VMIN */
- } else { /* Regular interactive use */
- debug(F100,"getptyslave() setting cooked mode","",0);
-
- /* Settings for sgtty based systems */
-
-#ifndef USE_TERMIO
- termbuf.sg.sg_flags |= CRMOD|ANYP|ECHO|XTABS;
-#endif /* USE_TERMIO */
-
-#ifndef OXTABS
-#define OXTABS 0
-#endif /* OXTABS */
-
- /* Settings for UNICOS and HPUX */
-
-#ifdef CRAY
- termbuf.c_oflag = OPOST|ONLCR|TAB3;
- termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
- termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
- termbuf.c_cflag = EXTB|HUPCL|CS8;
-#else /* CRAY */
-#ifdef HPUX
- termbuf.c_oflag = OPOST|ONLCR|TAB3;
- termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
- termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
- termbuf.c_cflag = EXTB|HUPCL|CS8;
-#else /* HPUX */
-#ifdef USE_TERMIO
- /*
- Settings for all other termios/termio based systems, other than
- 4.4BSD. In 4.4BSD the kernel does the initial terminal setup.
- */
-#ifdef BSD42
-#ifndef BSD44
- termbuf.c_lflag |= ECHO|ICANON|IEXTEN|ISIG;
- termbuf.c_oflag |= ONLCR|OXTABS|OPOST;
- termbuf.c_iflag |= ICRNL|IGNPAR;
- termbuf.c_cflag |= HUPCL;
- termbuf.c_iflag &= ~IXOFF;
-#endif /* BSD44 */
-#else /* BSD42 */
- termbuf.c_lflag |= ECHO|ICANON|IEXTEN|ISIG;
- termbuf.c_oflag |= ONLCR|OXTABS|OPOST;
- termbuf.c_iflag |= ICRNL|IGNPAR;
- termbuf.c_cflag |= HUPCL;
- termbuf.c_iflag &= ~IXOFF;
-#endif /* BSD42 */
-#endif /* USE_TERMIO */
-#endif /* HPUX */
-#endif /* CRAY */
- }
-
- /* Set the tty modes, and make this our controlling tty. */
-#ifdef COMMENT
- /* But this is the master - we want the slave */
- set_termbuf(ttyfd);
-#else
- set_termbuf(t);
-#endif /* COMMENT */
-
- if (t != 0)
- dup2(t, 0);
- if (t != 1)
- dup2(t, 1);
- if (t != 2) {
- if (fc == 0) {
- dup2(t, 2);
- } else if (fc == 1) {
- /* For external protocols, send stderr to /dev/null */
-#ifdef COMMENT
- int xx;
-#ifndef COMMENT
- char * s = "/dev/null";
- errno = 0;
- xx = open(s, O_WRONLY);
-#else
- char * s = "pty.log";
- errno = 0;
- xx = open(s, O_CREAT, 0644);
-#endif /* COMMENT */
- debug(F111,"getptyslave redirect stderr",s,errno);
- dup2(xx,2);
-#endif /* COMMENT */
- }
- }
- if (t > 2)
- close(t);
-
- if (ttyfd > 2) {
- close(ttyfd);
- ttyfd = -1;
- *fd = ttyfd;
- }
- return(0);
-}
-
-#ifdef HAVE_PTYTRAP
-/*
- To be called to determine if a trap is pending on a pty
- if and only if select() cannot be used.
-*/
-int
-pty_trap_pending(fd) int fd; {
- int pending;
- int rc;
-
- rc = ioctl(fd, TIOCTRAPSTATUS, (char *)&pending, sizeof(pending));
- if (rc == 0) {
- debug(F101,"pty_trap_pending()","",pending);
- return(pending);
- } else {
- debug(F111,"pty_trap_pending()","ioctl() failed",rc);
- return(-1);
- }
-}
-
-/*
- To be called after select() has returned indicating that an exception is
- waiting on a pty. It should be called with the file descriptor of the pty.
- Returns -1 on error; 0 if pty is still open; 1 if pty has closed.
-*/
-int
-pty_trap_handler(fd) int fd; {
- struct request_info ri;
-
- memset(&ri,0,sizeof(ri));
- if (ioctl(fd,TIOCREQCHECK,(char *)&ri, sizeof(ri)) != 0) {
- debug(F111,"pty_trap_handler()","ioctl(TIOCREQCHECK) failed",errno);
- return(-1);
- }
- switch (ri.request) {
- case TIOCOPEN:
- debug(F110,"pty_trap_handler()","an open() call",0);
- break;
- case TIOCCLOSE:
- debug(F110,"pty_trap_handler()","a close() call",0);
- break;
- default:
- debug(F110,"pty_trap_handler()","an ioctl() call",0);
- ri.errno_error = EINVAL;
- }
- if (ioctl(fd, TIOCREQSET, (char *)&ri,sizeof(ri)) != 0) {
- debug(F111,"pty_trap_handler()","ioctl(TIOCREQSET) failed",errno);
- return(-1);
- }
- if (ri.request == TIOCCLOSE)
- return(1);
- else
- return(0);
-}
-#endif /* HAVE_PTYTRAP */
-
-VOID
-exec_cmd(s) char * s; {
- struct stringarray * q;
- char ** args = NULL;
-
- if (!s) return;
- if (!*s) return;
-
- q = cksplit(1,0,s,NULL,"\\%[]&$+-/=*^_@!{}/<>|.#~'`:;?",7,0,0);
- if (!q) return;
-
- args = q->a_head + 1;
-
-#ifdef DEBUG
- {
- int i, n;
- n = q->a_size;
- for (i = 0; i <= n; i++) {
- if (!args[i]) {
- debug(F111,"exec_cmd arg","NULL",i);
- break;
- } else {
- debug(F111,"exec_cmd arg",args[i],i);
- if (i == n && args[i]) {
- debug(F101,"exec_cmd SUBSTITUTING NULL","",i);
- if (strlen(args[i]) == 0)
- makestr(&(args[i]),NULL);
- }
-
- }
- }
- }
-#endif /* DEBUG */
-
- execvp(args[0],args);
-}
-
-/* Get a pty, scan input lines. */
-/* fc = 0 for interactive access; fc = 1 for running external protocols */
-
-static int pty_fc = -1; /* Global copy of fc */
-
-int
-do_pty(fd, cmd, fc) int * fd; char * cmd; int fc; {
- long retval;
- int syncpipe[2];
- int i, ttyfd;
-#ifdef HAVE_PTYTRAP
- int x;
-#endif /* HAVE_PTYTRAP */
-
- debug(F101,"CKUPTY.C do_pty fc","",fc);
-
- ttyfd = *fd;
-
- pty_master_fd = -2;
- pty_slave_fd = -2;
- pty_fork_pid = -2;
-
- msg = 0; /* Message counter */
- pty_init(); /* Find an available pty to use. */
- errno = 0;
-
- if ((retval = pty_getpty(&ttyfd, Xline, 20)) != 0) {
- if (msg++ == 0)
- perror(Xline);
- debug(F111,"do_pty()","pty_getpty() fails",retval);
- *fd = ttyfd;
- return(-1);
- }
- *fd = ttyfd;
- debug(F111,"do_pty() Xline",Xline,ttyfd);
-
-#ifdef SIGTTOU
-/*
- Ignoring SIGTTOU keeps the kernel from blocking us. we tweak the tty with
- an ioctl() (in ttioct() in /sys/tty.c in a BSD kernel)
-*/
- signal(SIGTTOU, SIG_IGN);
-#endif /* SIGTTOU */
-
-/* Start up the command on the slave side of the terminal */
-
- if (pipe(syncpipe) < 0) {
- debug(F110,"do_pty()","pipe() fails",0);
- perror("pipe() failed");
- msg++;
- debug(F111,"do_pty()","pipe fails",errno);
- return(-1);
- }
- if ((i = fork()) < 0) {
- /* XXX - need to clean up the allocated pty */
- perror("fork() failed");
- msg++;
- debug(F111,"do_pty()","fork fails",errno);
- return(-1);
- }
- if (i) { /* Wait for child before writing to parent side of pty. */
- char c;
-#ifdef HAVE_PTYTRAP
- int on = 1;
-#endif /* HAVE_PTYTRAP */
- close(syncpipe[1]);
- errno = 0;
- if (read(syncpipe[0], &c, 1) == 0) { /* Slave side died */
- perror("Pipe read() failed");
- msg++;
- debug(F110,"do_pty()","Slave fails to initialize",0);
- close(syncpipe[0]);
- return(-1);
- }
- pty_fork_pid = i; /* So we can clean it up later */
- pty_fork_active = 1;
- debug(F101,"do_pty pty_fork_pid","",pty_fork_pid);
-#ifdef HAVE_PTYTRAP
- /* HPUX does not allow the master to read end of file. */
- /* Therefore, we must determine that the slave has been */
- /* closed by trapping the call to close(). */
- errno = 0;
- x = ioctl(ttyfd, TIOCTRAP, (char *)&on);
- debug(F111,"do_pty ioctl(TIOCTRAP)",ckitoa(x),errno);
-#endif /* HAVE_PTYTRAP */
- debug(F111,"do_pty()","synchronized - pty_fork_pid",pty_fork_pid);
- close(syncpipe[0]);
- } else {
- int x;
- debug(F101,"do_pty getptyslave ttyfd A","",ttyfd);
- debug(F110,"do_pty()","Slave starts",0);
- x = getptyslave(&ttyfd,fc);
- debug(F101,"do_pty getptyslave","",x);
- if (x == 0) {
- debug(F101,"do_pty getptyslave ttyfd B","",ttyfd);
-#ifdef WANT_UTMP
- pty_update_utmp(PTY_USER_PROCESS,
- getpid(),
- "KERMIT",
- Xline,
- cmd,
- PTY_TTYSLOT_USABLE
- );
-#endif /* WANT_UTMP */
- /* Notify our parent we're ready to continue.*/
- debug(F110,"do_pty()","slave synchronizing",0);
- write(syncpipe[1],"y",1);
- close(syncpipe[0]);
- close(syncpipe[1]);
-
- debug(F110,"do_pty cmd",cmd,"");
- exec_cmd(cmd);
- debug(F111,"do_pty()","exec_cmd() returns - why?",errno);
- }
- *fd = ttyfd;
- debug(F110,"do_pty()","getptyslave() fails - exiting",0);
- exit(1);
- }
- *fd = ttyfd;
- pty_fc = fc;
- return(getpid());
-} /* end of do_pty() */
-
-
-VOID
-end_pty() {
- msg = 0; /* Message counter */
- debug(F101,"end_pty pty_fork_pid","",pty_fork_pid);
- if (Xline[0] && pty_fork_pid >= 0) {
- pty_cleanup(Xline,pty_fork_pid,1);
- Xline[0] = '\0';
- pty_fork_pid = -1;
- pty_fork_active = 0;
- debug(F101,"end_pty pty_fork_active","",pty_fork_active);
- }
- pty_fc = -1;
-}
-#endif /* NETPTY */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckupty.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckupty.h
deleted file mode 100644
index 374c508..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckupty.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* C K U P T Y . H -- Includes and definitions for ckupty.c */
-
-/*
- Copyright 1995 by the Massachusetts Institute of Technology.
-
- Modified for use in C-Kermit by:
-
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
- November 1999
-*/
-#ifndef __PTY_INT_H__
-#include <sys/types.h>
-
-/* #define WANT_UTMP */
-/* We don't want all the utmp/wtmp stuff */
-
-#ifdef WANT_UTMP
-#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#endif /* HAVE_UTMP_H */
-#ifdef HAVE_UTMPX_H
-#include <utmpx.h>
-#endif /* HAVE_UTMPX_H */
-#endif /* WANT_UTMP */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#ifdef __SCO__
-#include <sys/unistd.h>
-#endif /* __SCO__ */
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-#include <sys/stat.h>
-#ifndef SUNOS41
-#include <sys/ioctl.h>
-#endif /* SUNOS41 */
-#include <sys/file.h>
-#include <sys/time.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <pwd.h>
-
-#ifdef HAVE_SYS_LABEL_H
-/* only SunOS 4? */
-#include <sys/label.h>
-#include <sys/audit.h>
-#include <pwdadj.h>
-#endif /* HAVE_SYS_LABEL_H */
-
-#include <signal.h>
-
-#ifdef HPUX
-#include <sys/ptyio.h>
-#endif /* HPUX */
-#ifdef sysvimp
-#include <compat.h>
-#endif /* sysvimp */
-
-#ifdef COMMENT
-/* I don't think we actually use this for anything */
-/* and it kills Slackware builds, where there is no select.h. */
-#ifndef NO_SYS_SELECT_H
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif /* HAVE_SYS_SELECT_H */
-#endif /* NO_SYS_SELECT_H */
-#endif /* COMMENT */
-
-#ifdef HAVE_STREAMS
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#endif /* HAVE_STREAMS */
-
-#ifdef POSIX_TERMIOS
-#ifndef ultrix
-#include <termios.h>
-#else
-#include <sgtty.h>
-#endif /* ultrix */
-#else /* POSIX_TERMIOS */
-#include <sgtty.h>
-#endif /* POSIX_TERMIOS */
-
-#include <netdb.h>
-/* #include <syslog.h> */
-#ifndef ultrix
-#include <string.h>
-#endif /* ultrix */
-/* #include <sys/param.h> */ /* (now done in ckcdeb.h) */
-
-#ifdef HAVE_STREAMS
-/* krlogin doesn't test sys/tty... */
-#ifdef HAVE_SYS_TTY_H
-#include <sys/tty.h>
-#endif /* HAVE_SYS_TTY_H */
-
-#ifdef HAVE_SYS_PTYVAR_H
-/* Solaris actually uses packet mode, so the real macros are needed too */
-#include <sys/ptyvar.h>
-#endif /* HAVE_SYS_PTYVAR_H */
-#endif /* HAVE_STREAMS */
-
-#ifdef COMMENT
-/* This block moved to ckcdeb.h */
-#ifndef NO_OPENPTY
-/* For NetBSD, see makefile */
-#ifndef HAVE_OPENPTY
-#ifdef __FreeBSD__
-#define HAVE_OPENPTY
-#else
-#ifdef MACOSX10
-#define HAVE_OPENPTY
-#endif /* MACOSX10 */
-#endif /* __FreeBSD__ */
-#endif /* HAVE_OPENPTY */
-#endif /* NO_OPENPTY */
-#endif /* COMMENT */
-
-#ifdef HAVE_VHANGUP
-#ifndef OPEN_CTTY_ONLY_ONCE
-/*
- Breaks under Ultrix and others where you cannot get controlling
- terminal twice.
-*/
-#define VHANG_first
-#define VHANG_LAST
-#endif /* OPEN_CTTY_ONLY_ONCE */
-#endif /* HAVE_VHANGUP */
-
-/* Internal functions */
-_PROTOTYP(long ptyint_void_association,(void));
-_PROTOTYP(long ptyint_open_ctty ,(char *, int *));
-_PROTOTYP(VOID ptyint_vhangup, (void));
-
-#ifdef WANT_UTMP
-_PROTOTYP(long ptyint_update_wtmp, (struct utmp *, char *, char *));
-#endif /* WANT_UTMP */
-
-#define __PTY_INT_H__
-#endif /* __PTY_INT_H__ */
-
-#ifndef __LIBPTY_H__
-
-#ifdef WANT_UTMP
-/* Constants for pty_update_utmp */
-#define PTY_LOGIN_PROCESS 0
-#define PTY_USER_PROCESS 1
-#define PTY_DEAD_PROCESS 2
-#define PTY_TTYSLOT_USABLE (0x1) /* flags to update_utmp*/
-#define PTY_UTMP_USERNAME_VALID (0x2)
-#endif /* WANT_UTMP */
-
-_PROTOTYP(long pty_init,(void));
-_PROTOTYP(long pty_getpty, ( int *, char *, int));
-_PROTOTYP(long pty_open_slave, (char *, int *, int));
-_PROTOTYP(long pty_open_ctty, (char *, int *, int));
-_PROTOTYP(long pty_initialize_slave, (int));
-#ifdef WANT_UTMP
-_PROTOTYP(long pty_update_utmp, (int, int, char *, char *, char *, int));
-_PROTOTYP(long pty_logwtmp, (char *, char *, char *));
-#endif /* WANT_UTMP */
-_PROTOTYP(long pty_cleanup, (char *, int, int));
-
-#define PTY_GETPTY_STREAMS (44806912L)
-#define PTY_GETPTY_FSTAT (44806913L)
-#define PTY_GETPTY_NOPTY (44806914L)
-#define PTY_GETPTY_SLAVE_TOOLONG (44806915L)
-#define PTY_OPEN_SLAVE_OPENFAIL (44806916L)
-#define PTY_OPEN_SLAVE_CHMODFAIL (44806917L)
-#define PTY_OPEN_SLAVE_NOCTTY (44806918L)
-#define PTY_OPEN_SLAVE_CHOWNFAIL (44806919L)
-#define PTY_OPEN_SLAVE_LINE_PUSHFAIL (44806920L)
-#define PTY_OPEN_SLAVE_PUSH_FAIL (44806921L)
-#define PTY_OPEN_SLAVE_REVOKEFAIL (44806922L)
-#ifdef WANT_UTMP
-#define PTY_UPDATE_UTMP_PROCTYPE_INVALID (44806923L)
-#endif /* WANT_UTMP */
-#define PTY_OPEN_SLAVE_TOOSHORT (44806924L)
-#define ERROR_TABLE_BASE_pty (44806912L)
-
-extern struct error_table et_pty_error_table;
-
-#define __LIBPTY_H__
-#endif /* __LIBPTY_H__ */
-
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuscr.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuscr.c
deleted file mode 100644
index 7a2d9b7..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuscr.c
+++ /dev/null
@@ -1,688 +0,0 @@
-#include "ckcsym.h"
-
-#ifndef NOICP
-#ifndef NOSCRIPT
-char *loginv = "Script Command, 9.0.032, 16 Oct 2009";
-
-/* C K U S C R -- expect-send script implementation */
-
-/*
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Original (version 1, 1985) author: Herm Fischer, Encino, CA.
- Contributed to Columbia University in 1985 for inclusion in C-Kermit 4.0.
- Maintained since 1985 by Frank da Cruz, Columbia University,
- fdc@columbia.edu.
-
- The module takes a UUCP-style script of the "expect send [expect send] ..."
- format. It is intended to operate similarly to the way the common
- UUCP L.sys login entries work. Conditional responses are supported:
- expect[-send-expect[...]], as with UUCP. The send keyword EOT sends a
- Control-d, and the keyword BREAK sends a break. Letters prefixed
- by '~' are '~b' backspace, '~s' space, '~n' linefeed, '~r' return, '~x' xon,
- '~t' tab, '~q' ? (not allowed on kermit command lines), '~' ~, '~'',
- '~"', '~c' don't append return, '~o[o[o]]' octal character. As with
- some uucp systems, sent strings are followed by ~r (not ~n) unless they
- end with ~c. Null expect strings (e.g., ~0 or --) cause a short
- delay, and are useful for sending sequences requiring slight pauses.
-
- This module calls externally defined system-dependent functions for
- communications i/o, as defined in ckcplm.txt, the C-Kermit Program Logic
- Manual, and thus should be portable to all systems that implement those
- functions, and where alarm() and signal() work as they do in UNIX.
-*/
-#include "ckcdeb.h"
-#include <signal.h>
-#ifdef NT
-#include <setjmpex.h>
-#else /* NT */
-#include <setjmp.h>
-#endif /* NT */
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckuusr.h"
-#include "ckcnet.h"
-#include "ckcsig.h"
-
-_PROTOTYP( VOID flushi, (void) );
-_PROTOTYP( static VOID myflsh, (void) );
-_PROTOTYP( static int sequenc, (void) );
-_PROTOTYP( static VOID recvseq, (void) );
-_PROTOTYP( static int outseq, (void) );
-
-#ifdef MAC
-#define signal msignal
-#define SIGTYP long
-#define alarm malarm
-#define SIG_IGN 0
-#define SIGALRM 1
-#define SIGINT 2
-SIGTYP (*msignal(int type, SIGTYP (*func)(int)))(int);
-#endif /* MAC */
-
-#ifdef AMIGA
-#define signal asignal
-#define alarm aalarm
-#define SIGALRM (_NUMSIG+1)
-#define SIGTYP void
-SIGTYP (*asignal(int type, SIGTYP (*func)(int)))(int);
-unsigned aalarm(unsigned);
-#endif /* AMIGA */
-
-#ifdef STRATUS
-/* VOS doesn't have alarm(), but it does have some things we can work with. */
-/* however, we have to catch all the signals in one place to do this, so */
-/* we intercept the signal() routine and call it from our own replacement. */
-#define signal vsignal
-#define alarm valarm
-SIGTYP (*vsignal(int type, SIGTYP (*func)(int)))(int);
-int valarm(int interval);
-#endif /* STRATUS */
-
-extern int sessft;
-extern int local, flow, seslog, mdmtyp, msgflg, duplex, backgrd, secho, quiet;
-extern int network, nettype, ttnproto;
-extern long speed;
-extern char ttname[];
-
-#ifdef NTSIG
-extern int TlsIndex;
-#endif /* NTSIG */
-#ifdef IKSD
-extern int inserver;
-#endif /* IKSD */
-
-static int is_tn = 0; /* Do Telnet negotiations */
-
-#ifndef NOSPL
-#ifdef DCMDBUF
-extern struct cmdptr *cmdstk;
-#else
-extern struct cmdptr cmdstk[];
-#endif /* DCMDBUF */
-extern int techo, cmdlvl;
-extern int mecho;
-#endif /* NOSPL */
-
-static int scr_echo; /* Whether to echo script commands */
-
-static int exp_alrm = 15; /* Time to wait for expect string */
-#define SND_ALRM 15 /* Time to allow for sending string */
-#define NULL_EXP 2 /* Time to pause on null expect strg*/
-#define DEL_MSEC 300 /* Milliseconds to pause on ~d */
-
-#define SBUFL 512
-static char seq_buf[SBUFL+2], *s; /* expect-send sequence buffer */
-static int got_it, no_cr;
-
-/* Connect state parent/child communication signal handlers */
-
-#ifdef COMMENT
-#ifdef CK_POSIX_SIG
-static sigjmp_buf alrmrng;
-#else
-static jmp_buf alrmrng;
-#endif /* CK_POSIX_SIG */
-#else
-static ckjmpbuf alrmrng;
-#endif /* COMMENT */
-
-static SIGTYP
-#ifdef CK_ANSIC
-scrtime(int foo) /* modem read failure handler, */
-#else
-scrtime(foo) int foo; /* Alarm handler */
-#endif /* CK_ANSIC */
-/* scrtime */ {
-
-#ifdef BEBOX
-#ifdef BE_DR_7
- alarm_expired();
-#endif /* BE_DR_7 */
-#endif /* BEBOX */
-#ifdef NTSIG
- if (foo == SIGALRM)
- PostAlarmSigSem();
- else
- PostCtrlCSem();
-#else /* NTSIG */
-#ifdef NT
- cklongjmp(ckjaddr(alrmrng),1);
-#else /* NT */
- cklongjmp(alrmrng,1);
-#endif /* NT */
-#endif /* NTSIG */
- SIGRETURN;
-}
-
-/*
- Sequence interpreter -- pick up next sequence from command string,
- decode escapes and place into seq_buf.
-
- If string contains a ~d (delay) then sequenc() returns a 1 expecting
- to be called again after the ~d executes.
-*/
-static int
-sequenc() {
- int i;
- char c, oct_char;
-
- no_cr = 0; /* output needs cr appended */
- for (i = 0; i < SBUFL; ) {
- if (*s == '\0' || *s == '-' || isspace(*s) ) { /* done */
- seq_buf[i] = '\0';
- return(0) ;
- }
- if (*s == '~') { /* escape character */
- s++;
- switch (c = *s) {
- case 'n': seq_buf[i++] = LF; break;
- case 'r': seq_buf[i++] = CR; break;
- case 't': seq_buf[i++] = '\t'; break;
- case 'b': seq_buf[i++] = '\b'; break;
- case 'q': seq_buf[i++] = '?'; break;
-#ifdef COMMENT
-/* The default case should catch these now... */
- case '~': seq_buf[i++] = '~'; break;
- case '-': seq_buf[i++] = '-'; break;
-#endif /* COMMENT */
- case '\'': seq_buf[i++] = '\''; break;
- case '\"': seq_buf[i++] = '\"'; break;
- case 's': seq_buf[i++] = ' '; break;
- case 'x': seq_buf[i++] = '\021'; break;
- case 'c': no_cr = 1; break;
- case 'd': { /* send what we have & then */
- seq_buf[i] = '\0'; /* expect to send rest after */
- no_cr = 1; /* sender delays a little */
- s++;
- return(1);
- }
- case 'w': { /* wait count */
- exp_alrm = 15; /* default to 15 sec */
- if (isdigit(*(s+1))) {
- s++;
- exp_alrm = *s & 15;
- if (isdigit(*(s+1)) ) {
- s++;
- exp_alrm = exp_alrm * 10 + (*s & 15);
- }
- }
- break;
- }
- default:
- if ( isdigit(c) ) { /* octal character */
- oct_char = (char) (c & 7); /* most significant digit */
- if (isdigit( *(s+1) ) ) {
- s++;
- oct_char = (char) ((oct_char<<3) | ( *s & 7 ));
- if (isdigit( *(s+1) ) ) {
- s++;
- oct_char = (char) ((oct_char<<3) | ( *s & 7 ));
- }
- }
- seq_buf[i++] = oct_char;
- break;
- } else seq_buf[i++] = *s; /* Treat ~ as quote */
- }
- } else seq_buf[i++] = *s; /* Plain old character */
- s++;
- }
- seq_buf[i] = '\0';
- return(0); /* end of space, return anyway */
-}
-
-
-/* Output buffering for "recvseq" and "flushi" */
-
-#define MAXBURST 256 /* maximum size of input burst */
-static CHAR conbuf[MAXBURST]; /* buffer to hold output for console */
-static int concnt = 0; /* number of characters buffered */
-static CHAR sesbuf[MAXBURST]; /* buffer to hold output for session log */
-static int sescnt = 0; /* number of characters buffered */
-
-static VOID
-myflsh() {
- if (concnt > 0) {
- conxo(concnt, (char *) conbuf);
- concnt = 0;
- }
- if (sescnt > 0) {
- logstr((char *) sesbuf, sescnt);
- sescnt = 0;
- }
-}
-
-/* these variables are used to pass data between the recvseq() */
-/* and the dorseq(). They are necessary because in some versions */
-/* dorseq() is executed in a separate thread and data cannot be */
-/* passed by parameter. */
-
-static char *rseqe, * rseqgot, * rseqtrace ;
-static int rseql;
-
-static SIGTYP
-#ifdef CK_ANSIC
-dorseq(void * threadinfo)
-#else /* CK_ANSIC */
-dorseq(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* dorseq */ {
- int i, x;
- int burst = 0; /* chars remaining in input burst */
-
-#ifdef NTSIG
- setint();
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- }
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef NT
-#ifdef IKSD
- if (inserver)
- setntcreds();
-#endif /* IKSD */
-#endif /* NT */
-#endif /* CK_LOGIN */
-
- while (!got_it) {
- for (i = 0; i < rseql-1; i++) rseqgot[i] = rseqgot[i+1];
- x = ttinc(0); /* Read a character */
- debug(F101,"recvseq","",x);
- if (x < 0) {
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN; /* Check for error */
- }
-#ifdef NETCONN
-#ifdef TNCODE
-/* Check for telnet protocol negotiation */
- if (((x & 0xff) == IAC) && is_tn) { /* Telnet negotiation */
- myflsh();
- burst = 0;
- switch (tn_doop((CHAR)(x & 0xff),duplex,ttinc)) {
- case 2: duplex = 0; continue;
- case 1: duplex = 1;
- default: continue;
- }
- }
-#endif /* TNCODE */
-#endif /* NETCONN */
- rseqgot[rseql-1] = (char) (x & 0x7f); /* Got a character */
- burst--; /* One less waiting */
- if (scr_echo) conbuf[concnt++] = rseqgot[rseql-1]; /* Buffer it */
- if (seslog) /* Log it in session log */
-#ifdef UNIX
- if (sessft != 0 || rseqgot[rseql-1] != '\r')
-#else
-#ifdef OSK
- if (sessft != 0 || rseqgot[rseql-1] != '\012')
-#endif /* OSK */
-#endif /* UNIX */
- if (rseqgot[rseql-1]) /* Filter out NULs */
- sesbuf[sescnt++] = rseqgot[rseql-1];
- if ((int)strlen(rseqtrace) < SBUFL-2 )
- strcat(rseqtrace,dbchr(rseqgot[rseql-1]));
- got_it = (!strncmp(rseqe, rseqgot, rseql));
- if (burst <= 0) { /* Flush buffered output */
- myflsh();
- if ((burst = ttchk()) < 0) { /* Get size of next input burst */
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
- }
- /* prevent overflow of "conbuf" and "sesbuf" */
- if (burst > MAXBURST)
- burst = MAXBURST;
- }
- }
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
-}
-
-static SIGTYP
-#ifdef CK_ANSIC
-failrseq(void * threadinfo)
-#else /* CK_ANSIC */
-failrseq(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* failrseq */ {
- got_it = 0; /* Timed out here */
- SIGRETURN;
-}
-
-/*
- Receive sequence -- see if expected response comes,
- return success (or failure) in got_it.
-*/
-static VOID
-recvseq() {
- char *e, got[7], trace[SBUFL];
- int i, l;
-
- sequenc();
- l = (int)strlen(e=seq_buf); /* no more than 7 chars allowed */
- if (l > 7) {
- e += l-7;
- l = 7;
- }
- tlog(F111,"expecting sequence",e,(long) l);
- if (l == 0) { /* null sequence, delay a little */
- sleep (NULL_EXP);
- got_it = 1;
- tlog(F100,"got it (null sequence)","",0L);
- return;
- }
- *trace = '\0';
- for (i = 0; i < 7; i++) got[i]='\0';
-
- rseqtrace = trace;
- rseqe = e;
- rseqgot = got;
- rseql = l;
-
- alrm_execute(ckjaddr(alrmrng), exp_alrm, scrtime, dorseq, failrseq);
-
- tlog(F110,"received sequence: ",trace,0L);
- tlog(F101,"returning with got-it code","",(long) got_it);
- myflsh(); /* Flush buffered output */
- return;
-}
-
-/*
- Output A Sequence starting at pointer s,
- return 0 if okay,
- 1 if failed to read (modem hangup or whatever)
-*/
-static int oseqret = 0; /* Return code for outseq */
- /* Out here to prevent clobbering */
- /* by longjmp. */
-
-static SIGTYP
-#ifdef CK_ANSIC
-dooseq(void * threadinfo)
-#else /* CK_ANSIC */
-dooseq(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
- int l;
- char *sb;
-#ifdef TCPSOCKET
- extern int tn_nlm, tn_b_nlm;
-#endif /* TCPSOCKET */
-
-#ifdef NTSIG
- setint();
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- }
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef NT
-#ifdef IKSD
- if (inserver)
- setntcreds();
-#endif /* IKSD */
-#endif /* NT */
-#endif /* CK_LOGIN */
-
- l = (int)strlen(seq_buf);
- tlog(F111,"sending sequence ",seq_buf,(long) l);
-
- if (!strcmp(seq_buf,"EOT")) {
- ttoc(dopar('\004'));
- if (scr_echo) conol("<EOT>");
- if (seslog && duplex)
- logstr("<EOT>",5);
- } else if (!strcmp(seq_buf,"BREAK") ||
- !strcmp(seq_buf,"\\b") ||
- !strcmp(seq_buf,"\\B")) {
- ttsndb();
- if (scr_echo) conol("<BREAK>");
- if (seslog)
- logstr("{BREAK}",7);
- } else {
- if (l > 0) {
- for ( sb = seq_buf; *sb; sb++)
- *sb = dopar(*sb); /* add parity */
- ttol((CHAR *)seq_buf,l); /* send it */
- if (scr_echo && duplex) {
-#ifndef NOLOCAL
-#ifdef OS2
- { /* Echo to emulator */
- char *s = seq_buf;
- while (*s) {
- scriptwrtbuf((USHORT)*s);
- }
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
- conxo(l,seq_buf);
- }
- if (seslog && duplex) /* log it */
- logstr(seq_buf,strlen(seq_buf));
- }
- if (!no_cr) {
- ttoc( dopar(CR) );
-#ifdef TCPSOCKET
- if (is_tn) {
- if (!TELOPT_ME(TELOPT_BINARY) && tn_nlm != TNL_CR)
- ttoc((char)((tn_nlm == TNL_CRLF) ?
- dopar(LF) : dopar(NUL)));
- else if (TELOPT_ME(TELOPT_BINARY) &&
- (tn_b_nlm == TNL_CRLF || tn_b_nlm == TNL_CRNUL))
- ttoc((char)((tn_b_nlm == TNL_CRLF) ?
- dopar(LF) : dopar(NUL)));
- }
-#endif /* TCPSOCKET */
- if (seslog && duplex)
- logchar(dopar(CR));
- }
- }
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- SIGRETURN;
-}
-
-SIGTYP
-#ifdef CK_ANSIC
-failoseq(void * threadinfo)
-#else /* CK_ANSIC */
-failoseq(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-/* failoseq */ {
- oseqret = -1; /* else -- alarm rang */
- SIGRETURN;
-}
-
-static int
-outseq() {
- int delay;
-
- oseqret = 0; /* Initialize return code */
- while(1) {
- delay = sequenc();
- alrm_execute( ckjaddr(alrmrng), SND_ALRM, scrtime, dooseq, failoseq ) ;
-
- if (!delay)
- return(oseqret);
-#ifndef MAC
- msleep(DEL_MSEC); /* delay, loop to next send */
-#endif /* MAC */
- }
-}
-
-
-/* L O G I N -- (historical misnomer) Execute the SCRIPT command */
-
-int
-dologin(cmdstr) char *cmdstr; {
-
-#ifdef OS2
-#ifdef NT
- SIGTYP (* savealm)(int); /* Save incoming alarm function */
-#else /* NT */
- SIGTYP (* volatile savealm)(int); /* Save incoming alarm function */
-#endif /* NT */
-#else /* OS2 */
- SIGTYP (*savealm)(); /* Save incoming alarm function */
-#endif /* OS2 */
- char *e;
-
- s = cmdstr; /* Make global to this module */
-
- tlog(F100,loginv,"",0L);
-
- if (speed < 0L) speed = ttgspd();
- if (ttopen(ttname,&local,mdmtyp,0) < 0) {
- ckmakmsg(seq_buf,SBUFL,"Sorry, can't open ",ttname,NULL,NULL);
- perror(seq_buf);
- return(0);
- }
- /* Whether to echo script commands ... */
- scr_echo = (!quiet && !backgrd && secho);
-#ifndef NOSPL
- if (scr_echo && cmdlvl > 1) {
- if (cmdstk[cmdlvl].src == CMD_TF)
- scr_echo = techo;
- if (cmdstk[cmdlvl].src == CMD_MD)
- scr_echo = mecho;
- }
-#endif /* NOSPL */
- if (scr_echo) {
-#ifdef NETCONN
- if (network)
- printf("Executing SCRIPT to host %s.\n",ttname);
- else
-#endif /* NETCONN */
- printf("Executing SCRIPT through %s, speed %ld.\n",ttname,speed);
- }
-#ifdef TNCODE
- /* TELNET input must be scanned for IAC */
- is_tn = (local && network && IS_TELNET()) ||
- (!local && sstelnet);
-#endif /* TNCODE */
-
- *seq_buf = 0;
- for (e = s; *e; e++) ckstrncat(seq_buf,dbchr(*e),SBUFL);
-#ifdef COMMENT
-/* Skip this because it tends to contain a password... */
- if (scr_echo) printf("SCRIPT string: %s\n",seq_buf);
-#endif /* COMMENT */
- tlog(F110,"SCRIPT string: ",seq_buf, 0L);
-
-/* Condition console terminal and communication line... */
-
- if (ttvt(speed,flow) < 0) {
- printf("Sorry, Can't condition communication line\n");
- return(0);
- }
- /* Save initial timer interrupt value */
- savealm = signal(SIGALRM,SIG_IGN);
-
- flushi(); /* Flush stale input */
-
-/* start expect - send sequence */
-
- while (*s) { /* While not done with buffer */
-
- while (*s && isspace(*s)) s++; /* Skip over separating whitespaces */
- /* Gather up expect sequence */
- got_it = 0;
- recvseq();
-
- while (!got_it) { /* Have it yet? */
- if (*s++ != '-') /* No, is there a conditional send? */
- goto failret; /* No, return failure */
- flushi(); /* Yes, flush out input buffer */
- if (outseq()) /* If unable to send, */
- goto failret; /* return failure. */
- if (*s++ != '-') /* If no conditional response here, */
- goto failret; /* return failure. */
- recvseq(); /* All OK, read response from host. */
- } /* Loop back and check got_it */
-
- while (*s && !isspace(*s++) ) ; /* Skip over conditionals */
- while (*s && isspace(*s)) s++; /* Skip over separating whitespaces */
- flushi(); /* Flush */
- if (*s) if (outseq()) goto failret; /* If any */
- }
- signal(SIGALRM,savealm);
- if (scr_echo) printf("Script successful.\n");
- tlog(F100,"Script successful.","",0L);
- return(1);
-
-failret:
- signal(SIGALRM,savealm);
- if (scr_echo) printf("Sorry, script failed\n");
- tlog(F100,"Script failed","",0L);
- return(0);
-}
-
-/* F L U S H I -- Flush, but log, SCRIPT input buffer */
-
-VOID
-flushi() {
- int n, x;
- if (
- seslog /* Logging session? */
- || scr_echo /* Or console echoing? */
-#ifdef NETCONN
-#ifdef TNCODE
- /* TELNET input must be scanned for IAC */
- || is_tn
-#endif /* TNCODE */
-#endif /* NETCONN */
- ) {
- if ((n = ttchk()) < 0) /* Yes, anything in buffer? */
- return;
- if (n > MAXBURST) n = MAXBURST; /* Make sure not too much, */
- myflsh(); /* and that buffers are empty. */
- while (n-- > 0) {
- x = ttinc(0); /* Collect a character */
-#ifdef NETCONN
-#ifdef TNCODE
-/* Check for telnet protocol negotiation */
- if (is_tn && ((x & 0xff) == IAC) ) {
- myflsh(); /* Sync output */
- switch (tn_doop((CHAR)(x & 0xff),duplex,ttinc)) {
- case 2: duplex = 0; break;
- case 1: duplex = 1;
- default: break;
- }
-
- /* Recalculate flush count */
- if ((n = ttchk()) < 0)
- return;
- if (n > MAXBURST) n = MAXBURST;
- continue;
- }
-#endif /* TNCODE */
-#endif /* NETCONN */
- if (scr_echo) conbuf[concnt++] = (CHAR) x; /* buffer for console */
- if (seslog)
-#ifdef UNIX
- if (sessft != 0 || x != '\r')
-#else
-#ifdef OSK
- if (sessft != 0 || x != '\012')
-#endif /* OSK */
-#endif /* UNIX */
- sesbuf[sescnt++] = (CHAR) x; /* buffer for session log */
- }
- myflsh();
- } else ttflui(); /* Otherwise just flush. */
-}
-
-#else /* NOSCRIPT */
-char *loginv = "Script Command Disabled";
-#endif /* NOSCRIPT */
-#endif /* NOICP */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckusig.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckusig.c
deleted file mode 100644
index e4556e5..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckusig.c
+++ /dev/null
@@ -1,354 +0,0 @@
-char *ckusigv = "Signal support, 9.0.100, 16 Oct 2009";
-
-/* C K U S I G -- Kermit signal handling for Unix and OS/2 systems */
-
-/*
- Author: Jeffrey Altman (jaltman@secure-endpoints.com),
- Secure Endpoints Inc., New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#include "ckcsym.h"
-#include "ckcasc.h" /* ASCII character symbols */
-#include "ckcdeb.h" /* Debug & other symbols */
-#include "ckcker.h" /* Kermit symbols */
-#include "ckcnet.h" /* Network symbols */
-#ifndef NOSPL
-#include "ckuusr.h"
-#endif /* NOSPL */
-
-#include <signal.h>
-#ifdef NT
-#include <setjmpex.h>
-#include <excpt.h>
-#else /* NT */
-#include <setjmp.h>
-#endif /* NT */
-#include "ckcsig.h"
-
-#ifdef NOCCTRAP
-extern ckjmpbuf cmjbuf;
-#endif /* NOCCTRAP */
-
-#ifdef MAC
-#define signal msignal
-#define SIGTYP long
-#define alarm malarm
-#define SIG_IGN 0
-#define SIGALRM 1
-#define SIGINT 2
-SIGTYP (*msignal(int type, SIGTYP (*func)(int)))(int);
-#endif /* MAC */
-
-#ifdef STRATUS
-/* We know these are set here. MUST unset them before the definitions. */
-#define signal vsignal
-#define alarm valarm
-SIGTYP (*vsignal(int type, SIGTYP (*func)(int)))(int);
-int valarm(int interval);
-#endif /* STRATUS */
-
-#ifdef AMIGA
-#define signal asignal
-#define alarm aalarm
-#define SIGALRM (_NUMSIG+1)
-#define SIGTYP void
-SIGTYP (*asignal(int type, SIGTYP (*func)(int)))(int);
-unsigned aalarm(unsigned);
-#endif /* AMIGA */
-
-#ifdef NTASM
-DWORD
-ckgetIP(void)
-{
- __asm
- {
- mov eax, dword ptr [esp+0x10]
- jmp ckgetIP + 0x18
- }
- return 1;
-
-}
-#endif /* NTASM */
-
-#ifdef NT
-DWORD
-exception_filter( void )
-{
- GetExceptionInformation ;
- return( EXCEPTION_EXECUTE_HANDLER ) ;
-}
-void
-crash( void )
-{
- int x = 0, y = 0 ;
- x / y ;
-}
-#endif /* NT */
-
-#ifndef NOCCTRAP
-int
-#ifdef CK_ANSIC
-cc_execute( ckjptr(sj_buf), ck_sigfunc dofunc, ck_sigfunc failfunc )
-#else
-cc_execute( sj_buf, dofunc, failfunc)
- ckjptr(sj_buf);
- ck_sigfunc dofunc;
- ck_sigfunc failfunc;
-#endif /* CK_ANSIC */
-/* cc_execute */ {
- int rc = 0 ;
-#ifdef NTASM
- DWORD Eip, Esp ;
- isinterrupted = 0;
- sj_buf->retcode = 0 ;
- sj_buf->Id = GetCurrentThreadId() ;
- memset( &sj_buf->context, 0, sizeof(CONTEXT) );
- sj_buf->context.ContextFlags = CONTEXT_FULL ;
-#ifndef COMMENT
- GetThreadContext(GetCurrentThread(), &(sj_buf->context) ) ;
- __asm
- {
- mov ecx,dword ptr [sj_buf]
- mov dword ptr [ecx+0xc4],esp
- }
- sj_buf->context.EFlags = 530 ;
- sj_buf->context.Eip = ckgetIP()+0x0C ;
-#else /* COMMENT */
- __asm
- {
- mov eax, dword ptr [sj_buf]
- push eax
- mov eax, 0xfffffffe
- push eax
- mov eax, 0x00000039
- mov edx,esp
- int 0x2e
- pop eax
- pop eax
- }
-#endif /* COMMENT */
-#endif /* NTASM */
- if (
-#ifdef NTASM
- isinterrupted
-#else
- cksetjmp(ckjdref(sj_buf))
-#endif /* NTASM */
- ) {
-#ifdef NTASM
- __asm
- {
- mov esp, ESPToRestore
- }
- isinterrupted = 0 ;
-#endif /* NTASM */
- (*failfunc)(NULL) ;
-#ifdef NTASM
- rc = sj_buf->retcode ;
-#else /* NTASM */
- rc = -1 ;
-#endif /* NTASM */
- } else {
-#ifdef NT
- __try {
- (*dofunc)(NULL);
- }
- __except(exception_filter())
- {
- debug(F100,"cc_execute __except","",0);
- debug(F111,
- "exception_filter",
- "_exception_code",
- etExceptionCode()
- );
- longjmp(ckjdref(sj_buf),SIGINT);
- }
-#else /* NT */
- (*dofunc)(NULL);
-#endif /* NT */
- }
- return rc ;
-}
-#endif /* NOCCTRAP */
-
-int
-#ifdef CK_ANSIC /* ANSIC C declaration... */
-alrm_execute(ckjptr(sj_buf),
- int timo,
- ck_sighand handler,
- ck_sigfunc dofunc,
- ck_sigfunc failfunc
- )
-
-#else /* Not ANSIC C ... */
-
-alrm_execute(sj_buf,
- timo,
- handler,
- dofunc,
- failfunc
- )
- ckjptr(sj_buf);
- int timo;
- ck_sighand handler;
- ck_sigfunc dofunc;
- ck_sigfunc failfunc;
-#endif /* CK_ANSIC */
-
-/* alrm_execute */ {
-
- int rc = 0;
- int savalrm = 0;
-_PROTOTYP(SIGTYP (*savhandler), (int));
-
- savalrm = alarm(timo);
- savhandler = signal(SIGALRM, handler);
-
-#ifdef NTASM
- sj_buf->retcode = 0 ;
- sj_buf->Id = GetCurrentThreadId();
- memset(&sj_buf->context, 0, sizeof(CONTEXT));
- sj_buf->context.ContextFlags = CONTEXT_FULL;
-#ifndef COMMENT
- GetThreadContext(GetCurrentThread(), &(sj_buf->context));
-#else
- __asm
- {
- mov eax, dword ptr [sj_buf]
- push eax
- mov eax, 0xfffffffe
- push eax
- mov eax, 0x00000039
- mov edx,esp
- int 0x2e
- pop eax
- pop eax
- }
-#endif
- isinterrupted = 0;
-#endif /* NTASM */
- if (
-#ifdef NTASM
- sj_buf->retcode
-#else
- cksetjmp(ckjdref(sj_buf))
-#endif /* NTASM */
- ) {
- (*failfunc)(NULL) ;
- rc = -1 ;
- } else {
-#ifdef NT
- __try {
- (*dofunc)(NULL) ;
- }
- __except( exception_filter() )
- {
- debug(F100,"alrm_execute __except","",0);
- debug(F111,"exception_filter",
- "_exception_code",
- GetExceptionCode()
- );
- longjmp(ckjdref(sj_buf),SIGINT);
- }
-#else /* NT */
- (*dofunc)(NULL) ;
-#endif /* NT */
- }
- alarm(savalrm) ;
- if ( savhandler )
- signal( SIGALRM, savhandler ) ;
- return rc ;
-}
-
-int
-#ifdef CK_ANSIC /* ANSIC C declaration... */
-cc_alrm_execute(ckjptr(sj_buf),
- int timo,
- ck_sighand handler,
- ck_sigfunc dofunc,
- ck_sigfunc failfunc
- )
-
-#else /* Not ANSIC C ... */
-
-cc_alrm_execute(sj_buf,
- timo,
- handler,
- dofunc,
- failfunc
- )
- ckjptr(sj_buf);
- int timo;
- ck_sighand handler;
- ck_sigfunc dofunc;
- ck_sigfunc failfunc;
-#endif /* CK_ANSIC */
-
-/* cc_alrm_execute */ {
-
- int rc = 0;
- int savalrm = 0;
-_PROTOTYP(SIGTYP (*savhandler), (int));
- savalrm = alarm(timo);
- savhandler = signal( SIGALRM, handler );
-
-#ifdef NTASM
- sj_buf->retcode = 0 ;
- sj_buf->Id = GetCurrentThreadId() ;
- memset( &sj_buf->context, 0, sizeof(CONTEXT) );
- sj_buf->context.ContextFlags = CONTEXT_FULL ;
-#ifndef COMMENT
- GetThreadContext( GetCurrentThread(), &(sj_buf->context) ) ;
-#else
- __asm
- {
- mov eax, dword ptr [sj_buf]
- push eax
- mov eax, 0xfffffffe
- push eax
- mov eax, 0x00000039
- mov edx,esp
- int 0x2e
- pop eax
- pop eax
- }
-#endif
- isinterrupted = 0;
-#endif /* NTASM */
- if (
-#ifdef NTASM
- sj_buf->retcode
-#else
- cksetjmp(ckjdref(sj_buf))
-#endif /* NTASM */
- ) {
- (*failfunc)(NULL) ;
- rc = -1 ;
- } else {
-#ifdef NT
- __try {
- (*dofunc)(NULL) ;
- }
- __except( exception_filter() )
- {
- debug(F100,"cc_alrm_execute __except","",0);
- debug(F111,
- "exception_filter",
- "_exception_code",
- GetExceptionCode()
- );
- longjmp(ckjdref(sj_buf),SIGINT) ;
- }
-#else /* NT */
- (*dofunc)(NULL) ;
-#endif /* NT */
- }
- alarm(savalrm);
- if (savhandler)
- signal(SIGALRM,savhandler);
- return(rc);
-}
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckusig.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckusig.h
deleted file mode 100644
index 3482900..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckusig.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* C K U S I G . H */
-
-/* Definitions and prototypes for signal handling */
-
-/*
- Author: Jeffrey E Altman (jaltman@secure-endpoints.com),
- Secure Endpoints Inc., New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-#ifdef CK_ANSIC
-typedef void (*ck_sigfunc)(void *);
-typedef void (*ck_sighand)(int);
-#else
-typedef VOID (*ck_sigfunc)();
-typedef VOID (*ck_sighand)();
-#endif /* CK_ANSIC */
-
-/* Macros for POSIX vs old-style signal handling. */
-
-#ifdef CK_POSIX_SIG
-typedef sigjmp_buf ckjmpbuf;
-#else
-typedef jmp_buf ckjmpbuf;
-#endif /* CK_POSIX_SIG */
-/*
- Suppose you want to pass the address of a jmp_buf bar to a function foo.
- Since jmp_buf is normally defined (typedef'd) as an array, you would do
- it like this: foo(bar), where foo = foo(jmp_buf bar). But suppose a
- jmp_buf is (say) a struct rather than an array. Then you must do
- foo(&bar) where foo is foo(jmp_buf * bar). This is controlled here in
- the traditional fashion, by ifdefs. By default, we assume that jmp_buf
- is an array. Define the symbol JBNOTARRAY if jmp_buf is not an array.
-*/
-#ifndef JBNOTARRAY
-#ifdef NT
-#define JBNOTARRAY
-#endif /* NT */
-#endif /* JBNOTARRAY */
-
-#ifdef JBNOTARRAY
-typedef ckjmpbuf * ckjptr;
-#define ckjaddr(x) & x
-#define ckjdref(x) * x
-#ifdef CK_POSIX_SIG
-#define cksetjmp(x) sigsetjmp(x,1)
-#else
-#define cksetjmp(x) setjmp(x,1)
-#endif /* CK_POSIX_SIG */
-#else /* jmp_buf is an array */
-typedef ckjmpbuf ckjptr;
-#define ckjaddr(x) x
-#define ckjdref(x) x
-#ifdef CK_POSIX_SIG
-#define cksetjmp sigsetjmp
-#else
-#define cksetjmp setjmp
-#endif /* CK_POSIX_SIG */
-#endif /* JBNOTARRAY */
-
-_PROTOTYP( int cc_execute, (ckjptr, ck_sigfunc, ck_sigfunc) );
-_PROTOTYP( int alrm_execute,
- (ckjptr,
- int timo,
- ck_sighand handler,
- ck_sigfunc, ck_sigfunc) );
-_PROTOTYP( int cc_alrm_execute,
- (ckjptr,
- int timo,
- ck_sighand handler,
- ck_sigfunc,
- ck_sigfunc) );
-
-/* End of ckusig.h */
-
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckutio.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckutio.c
deleted file mode 100644
index 0d79e0c..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckutio.c
+++ /dev/null
@@ -1,16054 +0,0 @@
-#define CKUTIO_C
-
-#ifdef aegis
-char *ckxv = "Aegis Communications support, 9.0.326, 20 August 2011";
-#else
-#ifdef Plan9
-char *ckxv = "Plan 9 Communications support, 9.0.326, 20 August 2011";
-#else
-char *ckxv = "UNIX Communications support, 9.0.326, 20 August 2011";
-#endif /* Plan9 */
-#endif /* aegis */
-
-/* C K U T I O */
-
-/* C-Kermit interrupt, communications control and I/O functions for UNIX */
-
-/*
- Author: Frank da Cruz (fdc@columbia.edu),
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- NOTE TO CONTRIBUTORS: This file, and all the other C-Kermit files, must be
- compatible with C preprocessors that support only #ifdef, #else, #endif,
- #define, and #undef. Please do not use #if, logical operators, or other
- preprocessor features in any of the portable C-Kermit modules. You can,
- of course, use these constructions in platform-specific modules when they
- are supported by all compilers/preprocessors that could be used on that
- platform.
-*/
-
-extern int nettype; /* Defined in ckcmai.c */
-extern int duplex;
-
-/* Includes */
-
-#include "ckcsym.h" /* This must go first */
-#include "ckcdeb.h" /* This must go second */
-
-#ifdef OSF13
-#ifdef CK_ANSIC
-#ifdef _NO_PROTO
-#undef _NO_PROTO
-#endif /* _NO_PROTO */
-#endif /* CK_ANSIC */
-#endif /* OSF13 */
-
-#ifndef HPUXPRE65
-#include <errno.h> /* Error number symbols */
-#else
-#ifndef ERRNO_INCLUDED
-#include <errno.h> /* Error number symbols */
-#endif /* ERRNO_INCLUDED */
-#endif /* HPUXPRE65 */
-
-#ifdef __386BSD__
-#define ENOTCONN 57
-#else
-#ifdef __bsdi__
-#define ENOTCONN 57
-#else
-#ifdef __FreeBSD__
-#define ENOTCONN 57
-#endif /* __FreeBSD__ */
-#endif /* __bsdi__ */
-#endif /* __386BSD__ */
-
-#ifdef SCO_OSR504
-#define NBBY 8
-#endif /* SCO_OSR504 */
-
-#ifdef Plan9
-#define SELECT
-#include <sys/time.h>
-#include <select.h>
-#define FD_SETSIZE (3 * sizeof(long) * 8)
-static struct timeval tv;
-#endif /* Plan9 */
-
-#ifdef CLIX
-#include <sys/time.h>
-#endif /* CLIX */
-
-#include "ckcnet.h" /* Symbols for network types. */
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-
-/*
- The directory-related includes are here because we need to test some
- file-system-related symbols to find out which system we're being compiled
- under. For example, MAXNAMLEN is defined in BSD4.2 but not 4.1.
-*/
-#ifdef SDIRENT /* Directory bits... */
-#define DIRENT
-#endif /* SDIRENT */
-
-#ifdef XNDIR
-#include <sys/ndir.h>
-#else /* !XNDIR */
-#ifdef NDIR
-#include <ndir.h>
-#else /* !NDIR, !XNDIR */
-#ifdef RTU
-#include "/usr/lib/ndir.h"
-#else /* !RTU, !NDIR, !XNDIR */
-#ifdef DIRENT
-#ifdef SDIRENT
-#include <sys/dirent.h>
-#else
-#include <dirent.h>
-#endif /* SDIRENT */
-#else /* !RTU, !NDIR, !XNDIR, !DIRENT, i.e. all others */
-#include <sys/dir.h>
-#endif /* DIRENT */
-#endif /* RTU */
-#endif /* NDIR */
-#endif /* XNDIR */
-
-#ifdef QNX
-#include <sys/dev.h>
-#endif /* QNX */
-
-#ifdef HPUX5
-#ifndef TCPSOCKET
-/* I don't know why this is needed here since we never reference bzero(). */
-/* But without it C-Kermit won't link in an HP-UX 5.xx non-TCP build. */
-void
-bzero(s,n) char *s; int n; {
- extern char * memset();
- memset(s,0,n);
-}
-#endif /* TCPSOCKET */
-#endif /* HPUX5 */
-
-/* Definition of HZ, used in msleep() */
-
-#ifdef MIPS
-#define HZ ( 1000 / CLOCK_TICK )
-#else /* MIPS */
-#ifdef ATTSV
-#ifndef NAP
-#ifdef TRS16
-#define HZ ( 1000 / CLOCK_TICK )
-#endif /* TRS16 */
-#ifdef NAPHACK
-#define nap(x) (void)syscall(3112, (x))
-#define NAP
-#endif /* NAPHACK */
-#endif /* NAP */
-#endif /* ATTSV */
-#endif /* MIPS */
-
-#ifdef M_UNIX
-#undef NGROUPS_MAX /* Prevent multiple definition warnings */
-#endif /* M_UNIX */
-
-/*
- NOTE: HP-UX 8.0 has a <sys/poll.h>, but there is no corresponding
- library routine, so _poll comes up undefined at link time.
-*/
-#ifdef CK_POLL
-#ifndef AIXRS /* IBM AIX needs special handling */
-#include <poll.h> /* "standard" (SVID) i/o multiplexing, etc */
-#else /* AIXRS */
-#ifdef SVR4 /* AIX 3.2 is like SVID... */
-#include <poll.h>
-#else /* But AIX 3.1 is not ... */
-#include <sys/poll.h> /* The include file is in include/sys */
-#define events reqevents /* And it does not map IBM-specific member */
-#define revents rtnevents /* names to the System V equivalents */
-#endif /* SVR4 */
-#endif /* AIXRS */
-#endif /* CK_POLL */
-
-#include <signal.h> /* Signals */
-
-/* For setjmp and longjmp */
-
-#ifndef ZILOG
-#include <setjmp.h>
-#else
-#include <setret.h>
-#endif /* ZILOG */
-
-/*
- The following test differentiates between 4.1 BSD and 4.2 & later.
- If you have a 4.1BSD system with the DIRENT library, this test could
- mistakenly diagnose 4.2BSD and then later enable the use of system calls
- that aren't defined. If indeed there are such systems, we can use some
- other way of testing for 4.1BSD, or add yet another compile-time switch.
-*/
-#ifdef BSD4
-#ifdef MAXNAMLEN
-#ifndef FT21 /* Except for Fortune. */
-#ifndef FT18
-#ifndef BELLV10 /* And Bell Labs Research UNIX V10 */
-#define BSD42
-#endif /* BELLV10 */
-#endif /* FT18 */
-#endif /* FT21 */
-#endif /* MAXNAMLEN */
-#endif /* BSD4 */
-
-#ifdef SUNOS41 /* From Christian Corti */
-#define BSD44ORPOSIX /* Uni Stuttgart */
-#define SVORPOSIX /* February 2010 */
-#include <termios.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <limits.h>
-#endif /* SUNOS41 */
-
-#ifdef SNI542
-#include <sys/filio.h> /* 299 for FIONREAD */
-#endif /* SNI542 */
-
-/*
- Minix 2.0 support added by Terry McConnell,
- Syracuse University <tmc@barnyard.syr.edu>
- No more sgtty interface, posix compliant.
-*/
-#ifdef MINIX2
-#define _MINIX /* Needed for some Minix header files */
-#define BSD44ORPOSIX
-#define SVORPOSIX
-#ifndef MINIX3
-#define DCLTIMEVAL
-#endif /* MINIX3 */
-#define NOFILEH
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <limits.h>
-#undef TIOCGETC /* defined in sys/ioctl.h, but not really supported */
-#define TANDEM 0
-#endif /* MINIX2 */
-
-/*
- MINIX 1.0 support added by Charles Hedrick,
- Rutgers University <hedrick@aramis.rutgers.edu>.
- MINIX also has V7 enabled.
-*/
-#ifdef MINIX
-#define TANDEM 0
-#define MYREAD
-#define NOSYSIOCTLH
-#include <limits.h>
-#endif /* MINIX */
-
-#ifdef CK_REDIR /* <sys/wait.h> needed only for REDIRECT command. */
-/*
- If anybody can figure out how to make this work with NeXTSTEP, be
- my guest! (NeXTBlah/NeXTBlah/bsd/sys/wait.h does not define WEXITSTATUS)
-*/
-#ifndef CK_WAIT_H /* If wait.h not already included... */
-#ifdef OSF /* force OSF to select POSIX wait */
-#ifdef _BSD /* instead of BSD (see ckcdeb.h) */
-#define CK_OSF_BSD
-#undef _BSD
-#endif /* _BSD */
-#endif /* OSF */
-#include <sys/wait.h> /* Include it */
-#ifdef OSF
-#ifdef CK_OSF_BSD
-#define _BSD /* Restore it */
-#undef CK_OSF_BSD
-#endif /* CK_OSF_BSD */
-#endif /* OSF */
-#endif /* CK_WAIT_H */
-#endif /* CK_REDIR */
-
-#include "ckuver.h" /* Version herald */
-char *ckxsys = HERALD;
-
-#ifdef CK_UTSNAME
-#include <sys/utsname.h>
-
-#ifdef TRU64 /* Tru64 UNIX 4.0 and later */
-/* Verified on Tru64 4.0F - might break on 4.0E or earlier */
-#include <sys/sysinfo.h> /* (don't know about OSF/1 or DU) */
-#include <machine/hal_sysinfo.h>
-#endif /* TRU64 */
-
-#ifdef SOLARIS25 /* Solaris 2.5 and later */
-#include <sys/systeminfo.h> /* (don't know about earlier ones) */
-#endif /* SOLARIS25 */
-
-#ifdef UW7
-#ifndef SYS_NMLN
-#define SYS_NMLN 257
-#endif /* NMLN */
-#endif /* UW7 */
-#ifdef HPUX9PLUS
-static int hpis800 = 0;
-#endif /* HPUX9PLUS */
-#ifdef SYS_NMLN
-#define CK_SYSNMLN SYS_NMLN
-#else
-#ifdef _SYS_NMLN
-#define CK_SYSNMLN _SYS_NMLN
-#else
-#ifdef UTSLEN
-#define CK_SYSNMLN UTSLEN
-#else
-#define CK_SYSNMLN 31
-#endif /* UTSLEN */
-#endif /* _SYS_NMLN */
-#endif /* SYS_NMLN */
-char unm_mch[CK_SYSNMLN+1] = { '\0', '\0' };
-char unm_mod[CK_SYSNMLN+1] = { '\0', '\0' };
-char unm_nam[CK_SYSNMLN+1] = { '\0', '\0' };
-char unm_rel[CK_SYSNMLN+1] = { '\0', '\0' };
-char unm_ver[CK_SYSNMLN+1] = { '\0', '\0' };
-#endif /* CK_UTSNAME */
-
-#ifdef CIE
-#include <stat.h> /* For chasing symlinks, etc. */
-#else
-#include <sys/stat.h>
-#endif /* CIE */
-
-#ifdef QNX /* 299 */
-#ifndef IXANY
-#define IXANY 0
-#endif /* IXANY */
-#endif /* QNX */
-
-/* UUCP lockfile material... */
-
-#ifndef NOUUCP
-#ifdef USETTYLOCK
-#ifdef HAVE_LOCKDEV /* Red Hat baudboy/lockdev */
-/*
- Watch out: baudboy.h references open() without making sure it has been
- declared, resulting in warnings on at least Red Hat 7.3. It's declared in
- fcntl.h, but we don't include that until later. In this case only, we
- include it here, and then the second include is harmless because in Red Hat
- Linux (the only place where you find baudboy.h) fcntl.h is protected from
- multiple inclusion by _FCNTL_H. - fdc, 10 May 2004.
-
- NOTE: Although Linux /usr/sbin/lockdev obviates the need for setuid or
- setgid bits to access the lockfile, C-Kermit will still need them to access
- the serial port itself unless the port is open for world read/write.
- Normally setgid uucp does the trick.
-
- Extra: HAVE_LOCKDEV has been added als openSuSE >= 11.3 doesn't use baudboy
- but ttylock. - jb, 26 Jul 2010
-*/
-#include <fcntl.h> /* This has to come before baudboy */
-#ifdef HAVE_BAUDBOY /* Red Hat baudboy/lockdev */
-#include <baudboy.h>
-#else /* !HAVE_BAUDBOY */ /* openSuSE lock via ttylock */
-#include <ttylock.h>
-#endif /* HAVE_BAUDBOY */
-#define LOCK_DIR "/var/lock" /* (even though we don't care) */
-
-#else /* !HAVE_LOCKDEV */
-
-#ifdef USE_UU_LOCK
-#ifdef __FreeBSD__
-#include <libutil.h> /* FreeBSD */
-#else
-#include <util.h> /* OpenBSD */
-#endif /* HAVE_LOCKDEV */
-#endif /* __FreeBSD */
-#endif /* USE_UU_LOCK */
-#else /* USETTYLOCK */
-
-/* Name of UUCP tty device lockfile */
-
-#ifdef LINUXFSSTND
-#ifndef HDBUUCP
-#define HDBUUCP
-#endif /* HDBUUCP */
-#endif /* LINUXFSSTND */
-
-#ifdef ACUCNTRL
-#define LCKDIR
-#endif /* ACUCNTRL */
-
-/*
- PIDSTRING means use ASCII string to represent pid in lockfile.
-*/
-#ifndef PIDSTRING
-#ifdef HDBUUCP
-#define PIDSTRING
-#else
-#ifdef BSD44
-#define PIDSTRING
-#else
-#ifdef RTAIX
-#define PIDSTRING
-#else
-#ifdef AIXRS
-#define PIDSTRING
-#else
-#ifdef COHERENT
-#define PIDSTRING
-#endif /* COHERENT */
-#endif /* AIXRS */
-#endif /* RTAIX */
-#endif /* BSD44 */
-#endif /* HDBUUCP */
-#endif /* PIDSTRING */
-
-/* Now the PIDSTRING exceptions... */
-
-#ifdef PIDSTRING
-#ifdef HPUX
-#undef PIDSTRING
-#endif /* HPUX */
-#endif /* PIDSTRING */
-
-#ifdef __bsdi__ /* BSDI (at least thru 1.1) */
-#ifdef PIDSTRING
-#undef PIDSTRING
-#endif /* PIDSTRING */
-#endif /* __bsdi__ */
-
-#ifdef OSF32 /* Digital UNIX (OSF/1) 3.2 */
-#ifdef PIDSTRING
-#undef PIDSTRING
-#endif /* PIDSTRING */
-#endif /* OSF32 */
-
-/*
- LOCK_DIR is the name of the lockfile directory.
- If LOCK_DIR is already defined (e.g. on command line), we don't change it.
-*/
-
-#ifndef LOCK_DIR
-#ifdef MACOSX
-#define LOCK_DIR "/var/spool/lock"
-#endif /* MACOSX */
-#endif/* LOCK_DIR */
-
-#ifndef LOCK_DIR
-#ifdef BSD44
-#ifdef __386BSD__
-#define LOCK_DIR "/var/spool/lock"
-#else
-#ifdef __FreeBSD__
-#define LOCK_DIR "/var/spool/lock"
-#else
-#ifdef __NetBSD__
-#define LOCK_DIR "/var/spool/lock"
-#else
-#ifdef __OpenBSD__
-#define LOCK_DIR "/var/spool/lock"
-#else
-/* So which ones is this for? */
-/* Probably original 4.4BSD on Vangogh */
-/* Plus who knows about Mac OS X... It doesn't even have a cu program */
-#define LOCK_DIR "/var/spool/uucp"
-#endif /* __OpenBSD__ */
-#endif /* __NetBSD__ */
-#endif /* __FreeBSD__ */
-#endif /* __386BSD__ */
-#else
-#ifdef DGUX430
-#define LOCK_DIR "/var/spool/locks"
-#else
-#ifdef HPUX10
-#define LOCK_DIR "/var/spool/locks"
-#else
-#ifdef RTAIX /* IBM RT PC AIX 2.2.1 */
-#define LOCK_DIR "/etc/locks"
-#else
-#ifdef AIXRS
-#define LOCK_DIR "/etc/locks"
-#else
-#ifdef ISIII
-#define LOCK_DIR "/etc/locks"
-#else
-#ifdef HDBUUCP
-#ifdef M_SYS5
-#define LOCK_DIR "/usr/spool/uucp"
-#else
-#ifdef M_UNIX
-#define LOCK_DIR "/usr/spool/uucp"
-#else
-#ifdef SVR4
-#define LOCK_DIR "/var/spool/locks"
-#else
-#ifdef SUNOS4
-#define LOCK_DIR "/var/spool/locks"
-#else
-#ifdef LINUXFSSTND
-#define LOCK_DIR "/var/lock";
-#else
-#define LOCK_DIR "/usr/spool/locks"
-#endif /* LINUXFSSTND */
-#endif /* SUNOS4 */
-#endif /* SVR4 */
-#endif /* M_UNIX */
-#endif /* M_SYS5 */
-#else
-#ifdef LCKDIR
-#define LOCK_DIR "/usr/spool/uucp/LCK"
-#else
-#ifdef COHERENT
-#define LOCK_DIR "/usr/spool/uucp"
-#else
-#define LOCK_DIR "/usr/spool/uucp"
-#endif /* COHERENT */
-#endif /* LCKDIR */
-#endif /* HDBUUCP */
-#endif /* ISIII */
-#endif /* AIXRS */
-#endif /* RTAIX */
-#endif /* HPUX10 */
-#endif /* DGUX430 */
-#endif /* BSD44 */
-#endif /* !LOCK_DIR (outside ifndef) */
-
-#ifdef OSF2 /* OSF/1 2.0 or later */
-#ifdef LOCK_DIR /* (maybe 1.x too, who knows...) */
-#undef LOCK_DIR
-#define LOCK_DIR "/var/spool/locks"
-#endif /* LOCK_DIR */
-#endif /* OSF2 */
-
-#ifdef COMMENT
-/* Sorry no more lockf() -- we lock first and THEN open the device. */
-#ifdef SVR4
-#ifndef BSD44
-#ifndef LOCKF
-#define LOCKF /* Use lockf() on tty device in SVR4 */
-#endif /* LOCKF */
-#endif /* BSD44 */
-#endif /* SVR4 */
-#endif /* COMMENT */
-
-#ifdef NOLOCKF /* But NOLOCKF cancels LOCKF */
-#ifdef LOCKF
-#undef LOCKF
-#endif /* LOCKF */
-#endif /* NOLOCKF */
-
-/* More about this below... */
-
-#endif /* USETTYLOCK */
-#endif /* NOUUCP */
-
-/*
- MYREAD means use our internally defined nonblocking buffered read routine.
-*/
-#ifdef ATTSV
-#define MYREAD
-#endif /* ATTSV */
-
-#ifdef ATT7300
-#ifndef MYREAD
-#define MYREAD
-#endif /* MYREAD */
-/* bits for attmodem: internal modem in use, restart getty */
-#define ISMODEM 1
-#define DOGETY 512
-#endif /* ATT7300 */
-
-#ifdef BSD42
-#define MYREAD
-#endif /* BSD42 */
-
-#ifdef POSIX
-#define MYREAD
-#endif /* POSIX */
-#ifdef __bsdi__
-#ifndef O_NDELAY
-#define O_NDELAY O_NONBLOCK
-#endif /* O_NDELAY */
-#endif /* __bsdi__ */
-
-/*
- Variables available to outside world:
-
- dftty -- Pointer to default tty name string, like "/dev/tty".
- dfloc -- 0 if dftty is console, 1 if external line.
- dfprty -- Default parity
- dfflow -- Default flow control
- ckxech -- Flag for who echoes console typein:
- 1 - The program (system echo is turned off)
- 0 - The system (or front end, or terminal).
- functions that want to do their own echoing should check this flag
- before doing so.
-
- flfnam -- Name of lock file, including its path, e.g.,
- "/usr/spool/uucp/LCK..cul0" or "/etc/locks/tty77"
- lkflfn -- Name of link to lock file, including its paths
- haslock -- Flag set if this kermit established a uucp lock.
- lockpid -- PID of other process that has desired line open, as string.
- backgrd -- Flag indicating program executing in background ( & on
- end of shell command). Used to ignore INT and QUIT signals.
- rtu_bug -- Set by stptrap(). RTU treats ^Z as EOF (but only when we handle
- SIGTSTP)
-
- Functions for assigned communication line (either external or console tty):
-
- sysinit() -- System dependent program initialization
- syscleanup() -- System dependent program shutdown
- ttopen(ttname,local,mdmtyp,timo) -- Open the named tty for exclusive access.
- ttclos() -- Close & reset the tty, releasing any access lock.
- ttsspd(cps) -- Set the transmission speed of the tty.
- ttgspd() -- Get (read) the the transmission speed of the tty.
- ttpkt(speed,flow,parity) -- Put the tty in packet mode and set the speed.
- ttvt(speed,flow) -- Put the tty in virtual terminal mode.
- or in DIALING or CONNECTED modem control state.
- ttres() -- Restore original tty modes.
- ttscarr(carrier) -- Set carrier control mode, on/off/auto.
- ttinl(dest,max,timo) -- Timed read line from the tty.
- ttinc(timo) -- Timed read character from tty.
- myread() -- Raw mode bulk buffer read, gives subsequent
- chars one at a time and simulates FIONREAD.
- myunrd(c) -- Places c back in buffer to be read (one only)
- ttchk() -- See how many characters in tty input buffer.
- ttxin(n,buf) -- Read n characters from tty (untimed).
- ttol(string,length) -- Write a string to the tty.
- ttoc(c) -- Write a character to the tty.
- ttflui() -- Flush tty input buffer.
- ttsndb() -- Send BREAK signal.
- ttsndlb() -- Send Long BREAK signal.
-
- ttlock(ttname) -- "Lock" tty device against uucp collisions.
- ttunlck() -- Unlock tty device.
-
- For ATT7300/Unix PC, System V:
- attdial(ttname,speed,telnbr) -- dials ATT7300/Unix PC internal modem
- offgetty(ttname) -- Turns off getty(1m) for comms line
- ongetty(ttname) -- Restores getty() to comms line
-*/
-
-/*
-Functions for console terminal:
-
- congm() -- Get console terminal modes.
- concb(esc) -- Put the console in single-character wakeup mode with no echo.
- conbin(esc) -- Put the console in binary (raw) mode.
- conres() -- Restore the console to mode obtained by congm().
- conoc(c) -- Unbuffered output, one character to console.
- conol(s) -- Unbuffered output, null-terminated string to the console.
- conola(s) -- Unbuffered output, array of strings to the console.
- conxo(n,s) -- Unbuffered output, n characters to the console.
- conchk() -- Check if characters available at console (bsd 4.2).
- Check if escape char (^\) typed at console (System III/V).
- coninc(timo) -- Timed get a character from the console.
- congks(timo) -- Timed get keyboard scan code.
- conint() -- Enable terminal interrupts on the console if not background.
- connoi() -- Disable terminal interrupts on the console if not background.
-
-Time functions
-
- msleep(m) -- Millisecond sleep
- ztime(&s) -- Return pointer to date/time string
- rtimer() -- Reset timer
- gtimer() -- Get elapsed time since last call to rtimer()
-*/
-
-/* Conditional Includes */
-
-/* Whether to include <sys/file.h> */
-
-#ifdef RTU /* RTU doesn't */
-#define NOFILEH
-#endif /* RTU */
-
-#ifdef CIE /* CIE does. */
-#undef NOFILEH
-#endif /* CIE */
-
-#ifdef BSD41 /* 4.1 BSD doesn't */
-#define NOFILEH
-#endif /* BSD41 */
-
-#ifdef is68k /* Integrated Solutions 68000 UNIX */
-#define NOFILEH /* e.g. on Plexux P60 and Sun-1 */
-#endif /* is68k */
-
-#ifdef MINIX /* MINIX */
-#define NOFILEH
-#endif /* MINIX */
-
-#ifdef COHERENT /* Coherent */
-#define NOFILEH
-#endif /* COHERENT */
-
-#ifndef NOFILEH /* Now include if selected. */
-#include <sys/file.h>
-#endif /* NOFILEH */
-
-/* POSIX */
-
-#ifdef BSD44ORPOSIX /* POSIX uses termios.h */
-#define TERMIOS
-#ifdef __bsdi__
-#ifdef POSIX
-#undef _POSIX_SOURCE /* Get extra stuff from termios.h */
-#endif /* POSIX */
-#endif /* __bsdi__ */
-#include <termios.h>
-#ifdef LINUX
-#include <sys/ioctl.h>
-#endif /* LINUX */
-#ifdef QNX16
-#include <ioctl.h>
-#else
-#ifdef QNX6
-#include <ioctl.h>
-#endif /* QNX6 */
-#endif /* QNX16 */
-#ifdef __bsdi__
-#ifdef POSIX
-#define _POSIX_SOURCE
-#endif /* POSIX */
-#endif /* __bsdi__ */
-#ifndef BSD44 /* Really POSIX */
-#ifndef CK_QNX32 /* was CK_QNX32 */
-#define NOSYSIOCTLH /* No ioctl's allowed. */
-#undef ultrix /* Turn off any ultrix features. */
-#endif /* CK_QNX32 */
-#endif /* BSD44 */
-#endif /* POSIX */
-
-/* System III, System V */
-
-#ifdef ATTSV
-#ifndef BSD44
-#ifndef POSIX
-#include <termio.h>
-#endif /* POSIX */
-#endif /* BSD44 */
-#ifdef TERMIOX
-/* Need this for termiox structure, RTS/CTS and DTR/CD flow control */
-#include <termiox.h>
- struct termiox rctsx;
-#else
-#ifdef STERMIOX
-#ifdef SCO_OSR504
-/* Sorry, this is truly disgusting but it's SCO's fault. */
-#ifndef _SVID3
-#define _CK_SVID3_X
-#define _SVID3
-#endif /* _SVID3 */
-#endif /* SCO_OSR504 */
-#include <sys/termiox.h>
- struct termiox rctsx;
-#ifdef CK_SVID3_X
-#undef _SVID3
-#undef CK_SVID3_X
-#endif /* CK_SVID3_X */
-#endif /* STERMIOX */
-#endif /* TERMIOX */
-#endif /* ATTSV */
-
-#ifdef COHERENT /* Use termio.h, not sgtty.h for Coherent */
-#include <termio.h>
-#endif /* COHERENT */
-
-#ifdef MINIX /* MINIX uses ioctl's */
-#define NOSYSIOCTLH /* but has no <sys/ioctl.h> */
-#endif /* MINIX */
-
-/* Others */
-
-#ifndef NOSYSIOCTLH /* Others use ioctl() */
-#ifdef SUN4S5
-/*
- This is to get rid of cpp warning messages that occur because all of
- these symbols are defined by both termios.h and ioctl.h on the SUN.
-*/
-#undef ECHO
-#undef NL0
-#undef NL1
-#undef TAB0
-#undef TAB1
-#undef TAB2
-#undef XTABS
-#undef CR0
-#undef CR1
-#undef CR2
-#undef CR3
-#undef FF0
-#undef FF1
-#undef BS0
-#undef BS1
-#undef TOSTOP
-#undef FLUSHO
-#undef PENDIN
-#undef NOFLSH
-#endif /* SUN4S5 */
-#include <sys/ioctl.h>
-#endif /* NOSYSIOCTLH */
-/*
- We really, really, REALLY want FIONREAD, because it is the only way to find
- out not just *if* stuff is waiting to be read, but how much, which is
- critical to our sliding-window and streaming procedures, not to mention
- efficiency of CONNECT, etc.
-*/
-#ifdef BELLV10
-#include <sys/filio.h> /* For FIONREAD */
-#ifdef FIONREAD
-#define MYREAD
-#endif /* MYREAD */
-#endif /* BELLV10 */
-
-#ifndef FIONREAD
-/* It wasn't found in ioctl.h or term*.h - try these places: */
-#ifdef UNIXWARE
-#include <sys/filio.h>
-#else
-#ifdef SOLARIS
-#include <sys/filio.h>
-#endif /* SOLARIS */
-#endif /* UNIXWARE */
-#endif /* FIONREAD */
-
-#ifdef XENIX /* Was M_UNIX but XENIX implies M_UNIX and applies to XENIX too */
-/*
- <sys/socket.h> included above via "ckcnet.h" defines FIONREAD as
- something. Due to this, in_chk() uses the FIONREAD instead of RDCHK
- and the hot keys during file transfer (X to cancel file etc) do not
- work because FIONREAD doesn't work even though it is defined.
-
- NOTE: This might also be true elsewhere.
-*/
-#ifdef FIONREAD
-#undef FIONREAD
-#endif /* FIONREAD */
-#endif /* XENIX */
-
-#ifdef CK_SCOV5 /* Ditto for SCO OpenServer 5.0 */
-#ifndef SCO_OSR507 /* 299 */
-#ifdef FIONREAD
-#undef FIONREAD
-#endif /* FIONREAD */
-#endif /* SCO_OSR507 */
-#endif /* CK_SCOV5 */
-
-#ifdef SCO_OSR507 /* 299 */
-#ifdef RDCHK
-#undef RDCHK
-#endif /* RDCHK */
-#endif /* SCO_OSR507 */
-
-/* Whether to include <fcntl.h> */
-
-#ifndef is68k /* Only a few don't have this one. */
-#ifndef BSD41
-#ifndef FT21
-#ifndef FT18
-#ifndef COHERENT
-#include <fcntl.h>
-#endif /* COHERENT */
-#endif /* FT18 */
-#endif /* FT21 */
-#endif /* BSD41 */
-#endif /* not is68k */
-
-#ifdef COHERENT
-#ifdef _I386
-#include <fcntl.h>
-#else
-#include <sys/fcntl.h>
-#endif /* _I386 */
-#endif /* COHERENT */
-
-#ifdef ATT7300 /* Unix PC, internal modem dialer */
-#include <sys/phone.h>
-#endif /* ATT7300 */
-
-#ifdef HPUX /* HP-UX variations. */
-#define HPUXJOBCTL
-#include <sys/modem.h> /* HP-UX modem signals */
-#ifdef hp9000s500 /* Model 500 */
-#undef HPUXJOBCTL
-#endif /* hp9000s500 */
-#ifdef HPUXPRE65
-#undef HPUXJOBCTL
-typedef long mflag;
-#endif /* HPUXPRE65 */
-#ifdef HPUXJOBCTL
-#include <sys/bsdtty.h> /* HP-UX Berkeley tty support */
-#endif /* HPUXJOBCTL */
-#endif /* HPUX */
-
-/*
- Which time.h files to include... See ckcdeb.h for defaults.
- Note that 0, 1, 2, or all 3 of these can be included according to
- the symbol definitions.
-*/
-#ifndef NOTIMEH
-#ifdef TIMEH
-#include <time.h>
-#endif /* TIMEH */
-#endif /* NOTIMEH */
-
-#ifndef NOSYSTIMEH
-#ifdef SYSTIMEH
-#include <sys/time.h>
-#endif /* SYSTIMEH */
-#endif /* NOSYSTIMEH */
-
-#ifndef NOSYSTIMEBH
-#ifdef SYSTIMEBH
-#include <sys/timeb.h>
-#endif /* SYSTIMEBH */
-#endif /* NOSYSTIMEBH */
-
-#ifndef NODCLTIMEVAL
-#ifdef DCLTIMEVAL
-/*
- In certain POSIX builds (like Unixware 7), <[sys/]time.h> refuses to
- define the structs we need to access the higher speeds, so we have to
- do it ourselves.
-*/
-struct timeval {
- long tv_sec;
- long tv_usec;
-};
-struct timezone {
- int tz_minuteswest;
- int tz_dsttime;
-};
-#endif /* DCLTIMEVAL */
-#endif /* NODCLTIMEVAL */
-
-#ifdef __linux__
-/* THIS IS OBSOLETE since about Linux 0.92 */
-#ifdef OLINUXHISPEED
-#include <linux/serial.h>
-#endif /* OLINUXHISPEED */
-#ifdef __alpha__ /* Linux on DEC Alpha */
-#ifndef __GLIBC__ /* But not with glibc */
-#include <asm/termios.h>
-#endif /* __GLIBC__ */
-#endif /* __alpha__ */
-#endif /* __linux__ */
-
-#ifdef NOIEXTEN /* This is broken on some systems */
-#undef IEXTEN /* like Convex/OS 9.1 */
-#endif /* NOIEXTEN */
-#ifndef IEXTEN /* Turn off ^O/^V processing. */
-#define IEXTEN 0 /* Needed, at least, on BSDI. */
-#endif /* IEXTEN */
-/*
- Pick up definitions needed for select() if we don't have them already.
- Normally they come from <sys/types.h> but some systems get them from
- <sys/select.h>... Rather than hardwire all of them into the source, we
- include it if SELECT_H is defined in compile-time CFLAGS.
-*/
-#ifndef SCO_OSR504
-#ifdef SELECT_H
-#include <sys/select.h>
-#endif /* SELECT_H */
-#endif /* SCO_OSR504 */
-
-#ifdef aegis
-#include "/sys/ins/base.ins.c"
-#include "/sys/ins/error.ins.c"
-#include "/sys/ins/ios.ins.c"
-#include "/sys/ins/sio.ins.c"
-#include "/sys/ins/pad.ins.c"
-#include "/sys/ins/time.ins.c"
-#include "/sys/ins/pfm.ins.c"
-#include "/sys/ins/pgm.ins.c"
-#include "/sys/ins/ec2.ins.c"
-#include "/sys/ins/type_uids.ins.c"
-#include <default_acl.h>
-#undef TIOCEXCL
-#undef FIONREAD
-#endif /* aegis */
-
-#ifdef sxaE50 /* PFU Compact A SX/A TISP V10/L50 */
-#undef FIONREAD
-#endif /* sxaE50 */
-
-/* The following #defines are catch-alls for those systems */
-/* that didn't have or couldn't find <file.h>... */
-
-#ifndef FREAD
-#define FREAD 0x01
-#endif /* FREAD */
-
-#ifndef FWRITE
-#define FWRITE 0x10
-#endif /* FWRITE */
-
-#ifndef O_RDONLY
-#define O_RDONLY 000
-#endif /* O_RDONLY */
-
-/* This is for ancient Unixes that don't have these tty symbols defined. */
-
-#ifndef PENDIN
-#define PENDIN ICANON
-#endif /* PENDIN */
-#ifndef FLUSHO
-#define FLUSHO ICANON
-#endif /* FLUSHO */
-#ifndef EXTPROC
-#define EXTPROC ICANON
-#endif /* EXTPROC */
-
-#ifdef SVORPOSIX
-/*
- Modem signals are also forbidden in the POSIX world. But some POSIX-based
- platforms let us at them anyway if we know where to look.
-*/
-#ifndef NEEDMDMDEFS
-/* Doesn't work for Linux */
-#ifdef UNIXWARE7
-#define NEEDMDMDEFS
-#endif /* UNIXWARE7 */
-#endif /* NEEDMDMDEFS */
-
-#ifdef NEEDMDMDEFS
-#ifndef TIOCMGET
-#define TIOCMGET (('t'<<8)|29)
-#endif /* TIOCMGET */
-
-#ifndef TIOCM_DTR
-#define TIOCM_DTR 0x0002
-#endif /* TIOCM_DTR */
-#ifndef TIOCM_RTS
-#define TIOCM_RTS 0x0004
-#endif /* TIOCM_RTS */
-#ifndef TIOCM_CTS
-#define TIOCM_CTS 0x0020
-#endif /* TIOCM_CTS */
-#ifndef TIOCM_CAR
-#define TIOCM_CAR 0x0040
-#endif /* TIOCM_CAR */
-#ifndef TIOCM_RNG
-#define TIOCM_RNG 0x0080
-#endif /* TIOCM_RNG */
-#ifndef TIOCM_DSR
-#define TIOCM_DSR 0x0100
-#endif /* TIOCM_DSR */
-#endif /* NEEDMDMDEFS */
-#endif /* SVORPOSIX */
-
-/* Declarations */
-
-#ifdef OXOS
-#undef TCGETA
-#undef TCSETA
-#undef TCSETAW
-#undef TCSETAF
-#define TCGETA TCGETS
-#define TCSETA TCSETS
-#define TCSETAW TCSETSW
-#define TCSETAF TCSETSF
-#define termio termios
-#endif /* OXOS */
-
-#ifdef SVORPOSIX /* AT&T Sys V or POSIX */
-#ifdef UNIXWAREPOSIX /* UnixWare 7 POSIX build */
-/*
- In Unixware POSIX builds, <[sys/]time.h> refuses to define the
- structs we need to access the higher speeds, so we have to do it
- ourselves.
-*/
-struct timeval {
- long tv_sec;
- long tv_usec;
-};
-struct timezone {
- int tz_minuteswest;
- int tz_dsttime;
-};
-#endif /* UNIXWAREPOSIX */
-#endif /* SVORPOSIX */
-
-#ifdef __GNUC__
-#ifdef XENIX
-/*
- Because Xenix <time.h> doesn't declare time() if we're using gcc.
-*/
-time_t time();
-#endif /* XENIX */
-#endif /* __GNUC__ */
-
-/* Special stuff for V7 input buffer peeking */
-
-#ifdef V7
-int kmem[2] = { -1, -1};
-char *initrawq(), *qaddr[2]={0,0};
-#define CON 0
-#define TTY 1
-#endif /* V7 */
-
-/* dftty is the device name of the default device for file transfer */
-/* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */
-
-#ifdef BEOS
- char * dftty = NULL;
- char * dfmdm = "none";
- int dfloc = 0; /* that goes in local mode by default */
-#else
-#ifndef DFTTY
-#ifdef PROVX1
- char *dftty = "/dev/com1.dout"; /* Only example so far of a system */
- char *dfmdm = "none";
- int dfloc = 1; /* that goes in local mode by default */
-#else
- char *dftty = CTTNAM; /* Remote by default, use normal */
- char *dfmdm = "none";
- int dfloc = 0; /* controlling terminal name. */
-#endif /* PROVX1 */
-#else
- char *dftty = DFTTY; /* Default location specified on */
- char *dfmdm = "none"; /* command line. */
- int dfloc = 1; /* controlling terminal name. */
-#endif /* DFTTY */
-#endif /* BEOS */
-
-#define CON_RES 0 /* Console state is "reset" */
-#define CON_CB 1 /* Console state is CBREAK */
-#define CON_BIN 2 /* Console state is binary */
- static int constate = CON_RES;
-
-#define CONI_RES 0 /* Console interrupts are "reset" */
-#define CONI_INT 1 /* Console intterupts are set */
-#define CONI_NOI 2 /* Console intterupts are disabled */
- static int conistate = CONI_RES;
-
-#ifdef CK_SMALL
-#define CONBUFSIZ 15
-#else
-#define CONBUFSIZ 255
-#endif /* CK_SMALL */
- static char conbuf[CONBUFSIZ]; /* Console readahead buffer */
- static int conbufn = 0; /* Chars in readahead buffer */
- static char *conbufp = conbuf; /* Next char in readahead buffer */
-
- char cttnam[DEVNAMLEN+1] = { '\0', '\0' }; /* Determined at runtime */
-
-#ifdef RTU
- int rtu_bug = 0; /* set to 1 when returning from SIGTSTP */
-#endif /* RTU */
-
- int dfprty = DEFPAR; /* Default parity (0 = none) */
- int ttprty = 0; /* The parity that is in use. */
- static int ttpmsk = 0xff; /* Parity stripping mask. */
- int ttmdm = 0; /* Modem in use. */
- int ttcarr = CAR_AUT; /* Carrier handling mode. */
- int dfflow = FLO_NONE; /* Default flow control is NONE */
- int backgrd = 0; /* Assume in foreground (no '&' ) */
-#ifdef F_SETFL
- int iniflags = -1; /* fcntl flags for ttyfd */
-#endif /* F_SETFL */
- int fdflag = 0; /* Flag for redirected stdio */
- int ttfdflg = 0; /* Open File descriptor was given */
- int tvtflg = 0; /* Flag that ttvt has been called */
- long ttspeed = -1L; /* For saving speed */
- int ttflow = -9; /* For saving flow */
- int ttld = -1; /* Line discipline */
-
-#ifdef sony_news
- static int km_con = -1; /* Kanji mode for console tty */
- static int km_ext = -1; /* Kanji mode for external device */
-#endif /* sony_news */
-
-#ifdef PARSENSE
- static int needpchk = 1; /* Need parity check */
-#else
- static int needpchk = 0;
-#endif /* PARSENSE */
-
- extern int stopbits; /* Stop bits */
-#ifdef HWPARITY
-/*
- Unfortunately we must do this with global variables rather than through the
- tt...() APIs to avoid changing the APIs and the many modules that use them.
- If hwparity != 0, this indicates 8 data bits + parity, rather than 7 data
- bits + parity or 8 data bits and no parity, and overrides the regular parity
- variable, which is communicated to this module thru ttpkt(), and represented
- locally by the ttprty variable.
-*/
- extern int hwparity; /* Hardware parity */
-#endif /* HWPARITY */
-
-#ifdef TCPSOCKET
-#ifdef TCP_NODELAY
-static int nodelay_sav = -1;
-#endif /* TCP_NODELAY */
-#endif /* TCPSOCKET */
-
-static int sigint_ign = 0; /* SIGINT is ignored */
-
-/*
- Having this module rely on external globals is bad, but fixing this
- requires overhaul of the ck*tio.c modules for all the different operating
- systems supported by C-Kermit. Left for a future release.
-*/
-extern int ttnproto; /* Defined in ckcnet.c */
-extern int ttnet; /* Defined in ckcnet.c */
-extern int nopush, xfrcan, xfrchr, xfrnum; /* Defined in ckcmai.c */
-extern int xsuspend, wasclosed;
-extern int inserver, local;
-
-int ckxech = 0; /* 0 if system normally echoes console characters, else 1 */
-
-int ckmaxfiles = 0; /* Max number of open files */
-
-#ifdef CK_ENCRYPTION /* Kerberos */
-#include "ckuath.h"
-extern int me_encrypt, u_encrypt;
-#endif /* CK_ENCRYPTION */
-
-/* Declarations of variables global within this module */
-
-#ifdef TTLEBUF /* See ckcnet.h */
-int ttpush = -1;
-#define LEBUFSIZ 4096
-static CHAR le_buf[LEBUFSIZ];
-static int le_start = 0, le_end = 0, le_data = 0;
-#endif /* TTLEBUF */
-
-#define MSGBUF_SIZE 1024 /* For debugging */
-static char msgbuf[MSGBUF_SIZE];
-
-static int gotsigs = 0;
-
-static time_t tcount = (time_t)0; /* Elapsed time counter */
-
-static SIGTYP (*saval)() = NULL; /* For saving alarm() handler */
-static SIGTYP (*savquit)() = NULL; /* and other signal handlers */
-#ifdef SIGUSR1
-static SIGTYP (*savusr1)() = NULL;
-#endif /* SIGUSR1 */
-#ifdef SIGUSR2
-static SIGTYP (*savusr2)() = NULL;
-#endif /* SIGUSR2 */
-#ifdef SIGPIPE
-static SIGTYP (*savpipe)() = NULL;
-#endif /* SIGPIPE */
-#ifdef SIGDANGER
-static SIGTYP (*savdanger)() = NULL;
-#endif /* SIGDANGER */
-
-#ifndef NOJC
-static SIGTYP (*jchdlr)() = NULL; /* For checking suspend handler */
-#endif /* NOJC */
-static int jcshell = -1; /* And flag for result */
-
-/*
- BREAKNULS is defined for systems that simulate sending a BREAK signal
- by sending a bunch of NUL characters at low speed.
-*/
-#ifdef PROVX1
-#ifndef BREAKNULS
-#define BREAKNULS
-#endif /* BREAKNULS */
-#endif /* PROVX1 */
-
-#ifdef V7
-#ifndef BREAKNULS
-#define BREAKNULS
-#endif /* BREAKNULS */
-#endif /* V7 */
-
-#ifdef BREAKNULS
-static char /* A string of nulls */
-*brnuls = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-#endif /* BREAKNULS */
-
-#ifdef CK_POSIX_SIG /* Longjump buffers */
-static sigjmp_buf sjbuf; /* POSIX signal handling */
-#else
-static jmp_buf sjbuf;
-#endif /* CK_POSIX_SIG */
-
-#ifdef V7
-static jmp_buf jjbuf;
-#endif /* V7 */
-
-/* static */ /* (Not static any more) */
-int ttyfd = -1; /* TTY file descriptor */
-
-int ttpipe = 0; /* NETCMD: Use pipe instead of ttyfd */
-int ttpty = 0; /* NETPTY: Use pty instead of ttfyd */
-
-#ifdef NETPTY /* These are in ckupty.c */
-extern PID_T pty_fork_pid;
-extern int pty_master_fd, pty_slave_fd;
-#endif /* NETPTY */
-
-#ifdef NETCMD
-#ifdef NETCONN
-static int pipe0[2], pipe1[2]; /* Pipes for net i/o */
-#endif /* NETCONN */
-static PID_T ttpid = 0; /* Process ID for fork */
-static int fdin, fdout; /* File descriptors for pipe */
-static FILE * ttout = NULL; /* File pointer for output pipe */
-#ifdef DCLFDOPEN
-/* fdopen() needs declaring because it's not declared in <stdio.h> */
-_PROTOTYP( FILE * fdopen, (int, char *) );
-#endif /* DCLFDOPEN */
-#endif /* NETCMD */
-
-extern int pexitstat, quiet;
-
-#ifdef Plan9
-int ttyctlfd = -1; /* TTY control channel - What? UNIX doesn't have one? */
-int consctlfd = -1; /* Console control channel */
-int noisefd = -1; /* tone channel */
-static int ttylastspeed = -1; /* So we can lie about the speed */
-#endif /* Plan9 */
-
-int telnetfd = 0; /* File descriptor is for telnet */
-#ifdef NETCONN
-int x25fd = 0; /* File descriptor is for X.25 */
-#endif /* NETCONN */
-
-char lockpid[16] = { '\0', '\0' }; /* PID stored in lockfile, as string */
-
-static int lkf = 0, /* Line lock flag */
- cgmf = 0, /* Flag that console modes saved */
- xlocal = 0, /* Flag for tty local or remote */
- curcarr = 0; /* Carrier mode: require/ignore. */
-
-static int netconn = 0; /* 1 if network connection active */
-
-static char escchr; /* Escape or attn character */
-
-#ifdef CK_SCO32V4
-#include <sys/time.h>
-#endif /* CK_SCO32V4 */
-
-#ifdef HAVE_TV
- static struct timeval tv; /* For getting time, from sys/time.h */
-#endif /* HAVE_TV */
-#ifdef HAVE_TZ
- static struct timezone tz;
-#endif /* HAVE_TZ */
-
-#ifdef OSF
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* OSF */
-
-#ifdef BSD29
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* BSD29 */
-
-#ifdef BSD41
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* BSD41 */
-
-#ifdef BELLV10
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* BELLV10 */
-
-#ifdef FT21
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* FT21 */
-
-#ifdef TOWER1
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* TOWER1 */
-
-#ifdef COHERENT
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* COHERENT */
-
-#ifdef V7
- static long xclock;
-#endif /* V7 */
-
-/* sgtty/termio information... */
-
-#ifdef BSD44ORPOSIX /* POSIX or BSD44 */
- static struct termios
- ttold, ttraw, tttvt, ttcur,
- ccold, ccraw, cccbrk;
-#else /* BSD, V7, etc */
-
-#ifdef COHERENT /* Hack alert... */
-#define ATTSV
-#endif /* COHERENT */
-
-#ifdef ATTSV
- static struct termio ttold = {0}; /* Init'd for word alignment, */
- static struct termio ttraw = {0}; /* which is important for some */
- static struct termio tttvt = {0}; /* systems, like Zilog... */
- static struct termio ttcur = {0};
- static struct termio ccold = {0};
- static struct termio ccraw = {0};
- static struct termio cccbrk = {0};
-#else
- static struct sgttyb /* sgtty info... */
- ttold, ttraw, tttvt, ttcur, /* for communication line */
- ccold, ccraw, cccbrk; /* and for console */
-#ifdef BELLV10
- static struct ttydevb /* Device info... */
- tdold, tdcur; /* for communication device */
-#endif /* BELLV10 */
-#ifdef TIOCGETC
- static struct tchars tchold, tchnoi;
-
- static int tcharf;
-#endif /* TIOCGETC */
-#ifdef TIOCGLTC
- static struct ltchars ltchold, ltchnoi;
- static int ltcharf;
-#endif /* TIOCGLTC */
- int lmodef = 0; /* Local modes */
- int lmode = 0;
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-
-#ifdef COMMENT
-/* It picks up the speeds but they don't work */
-#ifdef UNIXWARE /* For higher serial speeds */
-#ifdef UW7 /* in Unixware 7.0 */
-#include <sys/asyc.h> /* This picks up 57600 and 115200 */
-#endif /* UW7 */
-#endif /* UNIXWARE */
-#endif /* COMMENT */
-
-#ifdef PROVX1
- static struct sgttyb ttbuf;
-#endif /* PROVX1 */
-
-#ifdef ultrix
-/* do we really need this? */
- static struct sgttyb vanilla;
-#endif /* ultrix */
-
-#ifdef ATT7300
-static int attmodem = 0; /* ATT7300 internal-modem status */
-struct updata dialer = {0}; /* Condition dialer for data call */
-#endif /* ATT7300 */
-
-#ifndef NOUUCP
-#define FLFNAML 128
-#ifndef USETTYLOCK
-#ifdef RTAIX
-char lkflfn[FLFNAML] = { '\0', '\0' }; /* and possible link to it */
-#endif /* RTAIX */
-char lock2[FLFNAML] = { '\0', '\0' }; /* Name of second lockfile */
-#endif /* USETTYLOCK */
-#else
-#define FLFNAML 7
-#endif /* NOUUCP */
-char flfnam[FLFNAML+1] = { '\0', '\0' }; /* UUCP lock file path name */
-
-int haslock = 0; /* =1 if this kermit locked uucp */
-
-#ifndef OXOS
-#ifdef SVORPOSIX
-static int conesc = 0; /* set to 1 if esc char (^\) typed */
-#else
-#ifdef V7
-static int conesc = 0;
-#else
-#ifdef C70
-static int conesc = 0;
-#endif /* C70 */
-#endif /* V7 */
-#endif /* SVORPOSIX */
-#endif /* OXOS */
-
-/* Local copy of comm device name or network host */
-static char ttnmsv[DEVNAMLEN+1] = { '\0', '\0' };
-#ifdef USETTYLOCK
-static char lockname[DEVNAMLEN+1]; /* Ditto, the part after "/dev/". */
-#endif /* USETTYLOCK */
-
-#ifdef aegis
-static status_$t st; /* error status return value */
-static short concrp = 0; /* true if console is CRP pad */
-static uid_$t ttyuid; /* tty type uid */
-static uid_$t conuid; /* stdout type uid */
-
-/* APOLLO Aegis main()
- * establish acl usage and cleanup handling
- * this makes sure that CRP pads
- * get restored to a usable mode
- */
-main(argc,argv) int argc; char **argv; {
- status_$t status;
- pfm_$cleanup_rec dirty;
-
- PID_T pid = getpid();
-
- /* acl usage according to invoking environment */
- default_acl(USE_DEFENV);
-
- /* establish a cleanup continuation */
- status = pfm_$cleanup(dirty);
- if (status.all != pfm_$cleanup_set) {
- /* only handle faults for the original process */
- if (pid == getpid() && status.all > pgm_$max_severity) {
- /* blew up in main process */
- status_$t quo;
- pfm_$cleanup_rec clean;
-
- /* restore the console in any case */
- conres();
-
- /* attempt a clean exit */
- debug(F101, "cleanup fault status", "", status.all);
-
- /* doexit(), then send status to continuation */
- quo = pfm_$cleanup(clean);
- if (quo.all == pfm_$cleanup_set)
- doexit(pgm_$program_faulted,-1);
- else if (quo.all > pgm_$max_severity)
- pfm_$signal(quo); /* blew up in doexit() */
- }
- /* send to the original continuation */
- pfm_$signal(status);
- /*NOTREACHED*/
- }
- return(ckcmai(argc, argv));
-}
-#endif /* aegis */
-
-/* ANSI-style prototypes for internal functions. */
-/* Functions used outside this module are prototyped in ckcker.h. */
-
-#ifdef apollo
-_PROTOTYP( SIGTYP timerh, () );
-_PROTOTYP( SIGTYP cctrap, () );
-_PROTOTYP( SIGTYP esctrp, () );
-_PROTOTYP( SIGTYP sig_ign, () );
-#else
-_PROTOTYP( SIGTYP timerh, (int) );
-_PROTOTYP( SIGTYP cctrap, (int) );
-_PROTOTYP( SIGTYP esctrp, (int) );
-#endif /* apollo */
-_PROTOTYP( int do_open, (char *) );
-_PROTOTYP( static int in_chk, (int, int) );
-_PROTOTYP( static int ttrpid, (char *) );
-_PROTOTYP( static int ttchkpid, (char *) );
-_PROTOTYP( static int ttlock, (char *) );
-_PROTOTYP( static int ttunlck, (void) );
-_PROTOTYP( static VOID sigchld_handler, (int) );
-_PROTOTYP( int mygetbuf, (void) );
-_PROTOTYP( int myfillbuf, (void) );
-_PROTOTYP( VOID conbgt, (int) );
-#ifdef ACUCNTRL
-_PROTOTYP( VOID acucntrl, (char *, char *) );
-#endif /* ACUCNTRL */
-
-#ifdef BSD44ORPOSIX
-_PROTOTYP( int carrctl, (struct termios *, int) );
-#else
-#ifdef ATTSV
-_PROTOTYP( int carrctl, (struct termio *, int) );
-#else
-_PROTOTYP( int carrctl, (struct sgttyb *, int) );
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-
-#ifdef ATT7300
-_PROTOTYP( int attdial, (char *, long, char *) );
-_PROTOTYP( int offgetty, (char *) );
-_PROTOTYP( int ongetty, (char *) );
-#endif /* ATT7300 */
-
-#ifdef BEOSORBEBOX
-#ifdef SELECT
- /* BeOS is not capable of using SELECT on anything but sockets */
-#undef SELECT
-#endif /* SELECT */
-#include <kernel/OS.h>
-/* #ifdef BE_DR_7 */
-static double time_started = 0.0;
-struct ALARM_STRUCT {
- thread_id thread;
- int time;
-};
-static thread_id alarm_thread = -1;
-static struct ALARM_STRUCT alarm_struct;
-_PROTOTYP( long do_alarm, (void *) );
-_PROTOTYP( unsigned int alarm, (unsigned int) );
-_PROTOTYP( void alarm_expired, (void) );
-/* #endif */ /* BE_DR_7 */
-#endif /* BEOSORBEBOX */
-
-#ifndef xunchar
-#define xunchar(ch) (((ch) - 32 ) & 0xFF ) /* Character to number */
-#endif /* xunchar */
-
-#ifdef CK_ANSIC
-static char *
-xxlast(char *s, char c)
-#else
-static char *
-xxlast(s,c) char *s; char c;
-#endif /* CK_ANSIC */
-/* xxlast */ { /* Last occurrence of character c in string s. */
- int i;
- for (i = (int)strlen(s); i > 0; i--)
- if (s[i-1] == c ) return(s + (i - 1));
- return(NULL);
-}
-
-/* Timeout handler for communication line input functions */
-
-/*ARGSUSED*/
-SIGTYP
-timerh(foo) int foo; {
- ttimoff();
-#ifdef BEOSORBEBOX
-/* #ifdef BE_DR_7 */
- alarm_expired();
-/* #endif */ /* BE_DR_7 */
-#endif /* BEOSORBEBOX */
-#ifdef CK_POSIX_SIG
- siglongjmp(sjbuf,1);
-#else
- longjmp(sjbuf,1);
-#endif /* CK_POSIX_SIG */
-}
-
-/*ARGSUSED*/
-SIGTYP
-xtimerh(foo) int foo; { /* Like timerh() but does */
-#ifdef BEOSORBEBOX /* not reset the timer itself */
-/* #ifdef BE_DR_7 */
- alarm_expired();
-/* #endif */ /* BE_DR_7 */
-#endif /* BEOSORBEBOX */
-#ifdef CK_POSIX_SIG
- siglongjmp(sjbuf,1);
-#else
- longjmp(sjbuf,1);
-#endif /* CK_POSIX_SIG */
-}
-
-
-/* Control-C trap for communication line input functions */
-
-int cc_int; /* Flag */
-SIGTYP (* occt)(); /* For saving old SIGINT handler */
-
-/*ARGSUSED*/
-SIGTYP
-cctrap(foo) int foo; { /* Needs arg for ANSI C */
- cc_int = 1; /* signal() prototype. */
- return;
-}
-
-/* S Y S I N I T -- System-dependent program initialization. */
-
-/*
- * ttgwsiz() returns:
- * 1 tt_rows and tt_cols are known, both altered, both > 0
- * 0 tt_rows and/or tt_cols are known, both altered, one or both <= 0
- * -1 tt_rows and tt_cols are unknown and unaltered
- */
-
-extern int tt_rows, tt_cols;
-
-static int
-xttgwsiz() {
- char *p;
- int rows = 0, cols = 0;
- p = getenv("LINES");
- debug(F110,"xttgwsiz LINES",p,0);
- if (p) {
- rows = atol(p);
- if (rows > 0) {
- p = getenv("COLUMNS");
- debug(F110,"xttgwsiz COLUMNS",p,0);
- if (p) {
- cols = atol(p);
- if (cols > 0) {
- tt_rows = rows;
- tt_cols = cols;
- return(1);
- }
- return(0);
- }
- }
- }
- return(-1);
-}
-
-#ifdef TTLEBUF
-VOID
-le_init() { /* LocalEchoInit() */
- int i;
- for (i = 0; i < LEBUFSIZ; i++)
- le_buf[i] = '\0';
- le_start = 0;
- le_end = 0;
- le_data = 0;
-}
-
-VOID
-le_clean() { /* LocalEchoCleanup() */
- le_init();
- return;
-}
-
-int
-le_inbuf() {
- int rc = 0;
- if (le_start != le_end) {
- rc = (le_end -
- le_start +
- LEBUFSIZ) % LEBUFSIZ;
- }
- debug(F111,"le_inbuf","chars waiting",rc);
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-le_putchar(CHAR ch)
-#else
-le_putchar(ch) CHAR ch;
-#endif /* CK_ANSIC */
-/* le_putchar */ {
-#ifdef COMMENT
- /* In UNIX we do not have another thread taking chars out of the buffer */
- while ((le_start - le_end == 1) ||
- (le_start == 0 && le_end == LEBUFSIZ - 1)) {
- /* Buffer is full */
- debug(F111,"le_putchar","Buffer is Full",ch);
- ReleaseLocalEchoMutex() ;
- msleep(250);
- RequestLocalEchoMutex( SEM_INDEFINITE_WAIT ) ;
- }
-#else
- if ((le_start - le_end + LEBUFSIZ)%LEBUFSIZ == 1) {
- debug(F110,"le_putchar","buffer is full",0);
- return(-1);
- }
-#endif /* COMMENT */
- le_buf[le_end++] = ch;
- if (le_end == LEBUFSIZ)
- le_end = 0;
- le_data = 1;
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-le_puts(CHAR * s, int n)
-#else
-le_puts(s,n) CHAR * s; int n;
-#endif /* CK_ANSIC */
-/* le_puts */ {
- int rc = 0;
- int i = 0;
- CHAR * p = (CHAR *)"le_puts";
- ckhexdump(p,s,n);
- for (i = 0; i < n; i++)
- rc = le_putchar((char)s[i]);
- debug(F101,"le_puts","",rc);
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-le_putstr(CHAR * s)
-#else
-le_putstr(s) CHAR * s;
-#endif /* CK_ANSIC */
-/* le_puts */ {
- CHAR * p;
- int rc = 0;
- p = (CHAR *)"le_putstr";
- ckhexdump(p,s,(int)strlen((char *)s));
- for (p = s; *p && !rc; p++)
- rc = le_putchar(*p);
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-le_getchar(CHAR * pch)
-#else /* CK_ANSIC */
-le_getchar(pch) CHAR * pch;
-#endif /* CK_ANSIC */
-/* le_gatchar */ {
- int rc = 0;
- if (le_start != le_end) {
- *pch = le_buf[le_start];
- le_buf[le_start] = 0;
- le_start++;
-
- if (le_start == LEBUFSIZ)
- le_start = 0;
-
- if (le_start == le_end) {
- le_data = 0;
- }
- rc++;
- } else {
- *pch = 0;
- }
- return(rc);
-}
-#endif /* TTLEBUF */
-
-#ifdef COMMENT
-/*
- Some systems like OSF/1 use TIOCGSIZE instead of TIOCGWINSZ.
- But as far as I know, whenever TIOCGSIZE is defined, it is
- equated to TIOCGWINSZ. For cases where this is not done, try this:
-*/
-#ifndef TIOCGWINSZ
-#ifdef TIOCGSIZE
-#define TIOCGWINSZ TIOCGSIZE
-#endif /* TIOCGSIZE */
-#endif /* TIOCGWINSZ */
-#endif /* COMMENT */
-
-static int tt_xpixel = 0, tt_ypixel = 0;
-
-int
-ttgwsiz() {
- int x = 0;
-#ifndef NONAWS
-#ifdef QNX
-/*
- NOTE: TIOCGWSIZ works here too, but only in the 32-bit version.
- This code works for both the 16- and 32-bit versions.
-*/
- extern int dev_size(int, int, int, int *, int *);
- int r, c;
-
- if (dev_size(0, -1, -1, &r, &c) == 0) {
- debug(F101,"ttgwsiz QNX r","",r);
- debug(F101,"ttgwsiz QNX c","",c);
- tt_rows = r;
- tt_cols = c;
- return ((r > 0 && c > 0) ? 1 : 0);
- } else return(xttgwsiz());
-#else /* QNX */
-#ifdef TIOCGWINSZ
-
-/* Note, this was M_UNIX, changed to XENIX to allow cross compilation... */
-#ifdef XENIX /* SCO UNIX 3.2v4.0 */
-#include <sys/stream.h> /* typedef mblk_t needed by ptem.h */
-#include <sys/ptem.h> /* for ttgwsiz() */
-#endif /* XENIX */
-
-#ifdef I386IX /* Ditto for Interactive */
-#include <sys/stream.h>
-#include <sys/ptem.h>
-#endif /* I386IX */
-
-/* Note, the above might be needed for some other older SVR3 Intel makes... */
-
- struct winsize w;
- tt_xpixel = 0;
- tt_ypixel = 0;
-
-#ifdef IKSD
- if (inserver)
- return(xttgwsiz());
-#endif /* IKSD */
- x = ioctl(0, (int)TIOCGWINSZ, (char *)&w);
- debug(F101,"ttgwsiz TIOCGWINSZ","",x);
- if (x < 0) {
- return(xttgwsiz());
- } else if (w.ws_row > 0 && w.ws_col > 0) {
- tt_rows = w.ws_row;
- tt_cols = w.ws_col;
- tt_xpixel = w.ws_xpixel;
- tt_ypixel = w.ws_ypixel;
- debug(F101,"ttgwsiz tt_rows","",tt_rows);
- debug(F101,"ttgwsiz tt_cols","",tt_cols);
- return(1);
- } else {
- debug(F100,"ttgwsiz TIOCGWINSZ 00","",0);
- return(xttgwsiz());
- }
-#else
- return(xttgwsiz());
-#endif /* TIOCGWINSZ */
-#endif /* QNX */
-#endif /* NONAWS */
-}
-
-
-#ifdef RLOGCODE
-_PROTOTYP( int rlog_naws, (void) );
-#endif /* RLOGCODE */
-
-#ifndef NOSIGWINCH
-#ifdef SIGWINCH
-SIGTYP
-winchh(foo) int foo; { /* SIGWINCH handler */
- int x = 0;
-#ifdef CK_TTYFD
-#ifndef VMS
- extern int ttyfd;
-#endif /* VMS */
-#endif /* CK_TTYFD */
- extern int tt_rows, tt_cols, cmd_rows, cmd_cols;
-#ifdef DEBUG
- if (deblog) {
- debug(F100,"***************","",0);
- debug(F100,"SIGWINCH caught","",0);
- debug(F100,"***************","",0);
-#ifdef NETPTY
- debug(F101,"SIGWINCH pty_fork_pid","",pty_fork_pid);
-#endif /* NETPTY */
- }
-#endif /* DEUB */
- signal(SIGWINCH,winchh); /* Re-arm the signal */
- x = ttgwsiz(); /* Get new window size */
- cmd_rows = tt_rows; /* Adjust command screen too */
- cmd_cols = tt_cols;
-
-#ifdef CK_TTYFD
- if /* If we don't have a connection */
-#ifdef VMS /* we're done. */
- (vmsttyfd() == -1)
-#else
- (ttyfd == -1)
-#endif /* VMS */
-#else
- (!local)
-#endif /* CK_TTYFD */
- return;
-
-#ifdef NETPTY
- if (pty_fork_pid > -1) { /* "set host" to a PTY? */
- int x;
-
-#ifdef TIOCSWINSZ
- struct winsize w; /* Resize the PTY */
- errno = 0;
- w.ws_col = tt_cols;
- w.ws_row = tt_rows;
- w.ws_xpixel = tt_xpixel;
- w.ws_ypixel = tt_ypixel;
- x = ioctl(ttyfd,TIOCSWINSZ,&w);
- debug(F101,"winchh TIOCSWINSZ","",x);
- debug(F101,"winchh TIOCSWINSZ errno","",errno);
-#endif /* TIOCSWINSZ */
-
- errno = 0;
- x = kill(pty_fork_pid,SIGWINCH);
- debug(F101,"winchh kill","",x);
- debug(F101,"winchh kill errno","",errno);
- }
-#endif /* NETPTY */
-
-/*
- This should be OK. It might seem that sending this from
- interrupt level could interfere with another TELNET IAC string
- that was in the process of being sent. But we always send
- TELNET strings with a single write(), which should prevent mixups.
- blah_snaws() should protect themselves from being called on the
- wrong kind of connection.
-*/
-#ifdef TCPSOCKET
-#ifndef NOTTGWSIZ
- if (x > 0 && tt_rows > 0 && tt_cols > 0) {
- tn_snaws();
-#ifdef RLOGCODE
- rlog_naws();
-#endif /* RLOGCODE */
- }
-#endif /* NOTTGWSIZ */
-#endif /* TCPSOCKET */
- SIGRETURN;
-}
-#endif /* SIGWINCH */
-#endif /* NOSIGWINCH */
-
-SIGTYP
-sighup(foo) int foo; { /* SIGHUP handler */
- backgrd = 1;
- debug(F100,"***************","",0);
- debug(F100,"SIGHUP received","",0);
- debug(F100,"***************","",0);
- doexit(BAD_EXIT,-1);
- /*NOTREACHED*/
- SIGRETURN; /* Shut picky compilers up... */
-}
-
-#ifdef CK_SCO32V4
-/* Exists but there is no prototype in the header files */
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef SV68R3V6
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef ultrix
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef HPUX6
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef HPUX5
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef PS2AIX10
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef BSD42
-_PROTOTYP( char * ttyname, (int) );
-#endif /* BSD42 */
-#endif /* PS2AIX10 */
-#endif /* HPUX5 */
-#endif /* HPUX6 */
-#endif /* ultrix */
-#endif /* SV68R3V6 */
-#endif /* CK_SCO32V4 */
-
-#ifndef SIGUSR1 /* User-defined signals */
-#define SIGUSR1 30
-#endif /* SIGUSR1 */
-
-#ifndef SIGUSR2
-#define SIGUSR2 31
-#endif /* SIGUSR2 */
-
-/*
- ignorsigs() sets certain signals to SIG_IGN. But when a signal is
- ignored, it remains ignored across exec(), so we have to restore these
- signals before exec(), which is the purpose of restorsigs().
-*/
-static VOID
-ignorsigs() { /* Ignore these signals */
- savquit = signal(SIGQUIT,SIG_IGN); /* Ignore Quit signal */
-
-#ifdef SIGDANGER /* Ignore danger signals */
-/*
- This signal is sent when the system is low on swap space. Processes
- that don't handle it are candidates for termination. If swap space doesn't
- clear out enough, we still might be terminated via kill() -- nothing we can
- do about that! Conceivably, this could be improved by installing a real
- signal handler that warns the user, but that would be pretty complicated,
- since we are not always in control of the screen -- e.g. during remote-mode
- file transfer.
-*/
- savdanger = signal(SIGDANGER,SIG_IGN); /* e.g. in AIX */
-#endif /* SIGDANGER */
-#ifdef SIGPIPE
-/*
- This one comes when a TCP/IP connection is broken by the remote.
- We prefer to catch this situation by examining error codes from write().
-*/
- savpipe = signal(SIGPIPE,SIG_IGN);
-#endif /* SIGPIPE */
- savusr1 = signal(SIGUSR1,SIG_IGN); /* Ignore user-defined signals */
- savusr2 = signal(SIGUSR2,SIG_IGN);
-}
-
-VOID
-restorsigs() { /* Restore these signals */
- (VOID) signal(SIGQUIT,savquit); /* (used in ckufio.c) */
-#ifdef SIGDANGER
- (VOID) signal(SIGDANGER,savdanger);
-#endif /* SIGDANGER */
-#ifdef SIGPIPE
- (VOID) signal(SIGPIPE,savpipe);
-#endif /* SIGPIPE */
- (VOID) signal(SIGUSR1,savusr1);
- (VOID) signal(SIGUSR2,savusr2);
-}
-
-int
-sysinit() {
- int x;
- char * s;
-#ifdef CK_UTSNAME
- struct utsname name;
-#endif /* CK_UTSNAME */
-
- extern char startupdir[];
-/*
- BEFORE ANYTHING ELSE: Initialize the setuid package.
- Change to the user's real user and group ID.
- If this can't be done, don't run at all.
-*/
- x = priv_ini();
-#ifdef SUIDDEBUG
- fprintf(stderr,"PRIV_INI=%d\n",x);
-#endif /* SUIDDEBUG */
- if (x) {
- if (x & 1) fprintf(stderr,"Fatal: setuid failure.\n");
- if (x & 2) fprintf(stderr,"Fatal: setgid failure.\n");
- if (x & 4) fprintf(stderr,"Fatal: C-Kermit setuid to root!\n");
- exit(1);
- }
- signal(SIGINT,SIG_IGN); /* Ignore interrupts at first */
- signal(SIGFPE,SIG_IGN); /* Ignore floating-point exceptions */
- signal(SIGHUP,sighup); /* Catch SIGHUP */
-#ifndef NOSIGWINCH
-#ifdef SIGWINCH
- signal(SIGWINCH,winchh); /* Catch window-size change */
-#endif /* SIGWINCH */
-#endif /* NOSIGWINCH */
-
-#ifdef SIGXFSZ
- signal(SIGXFSZ,SIG_IGN); /* Ignore writing past file limit */
-#endif /* SIGXFSZ */
-
-#ifndef NOJC
-/*
- Get the initial job control state.
- If it is SIG_IGN, that means the shell does not support job control,
- and so we'd better not suspend ourselves.
-*/
-#ifdef SIGTSTP
- jchdlr = signal(SIGTSTP,SIG_IGN);
- if (jchdlr == SIG_IGN) {
- jcshell = 0;
- debug(F100,"sysinit jchdlr: SIG_IGN","",0);
- } else if (jchdlr == SIG_DFL) {
- debug(F100,"sysinit jchdlr: SIG_DFL","",0);
- jcshell = 1;
- } else {
- debug(F100,"sysinit jchdlr: other","",0);
- jcshell = 3;
- }
- (VOID) signal(SIGTSTP,jchdlr); /* Put it back... */
-#endif /* SIGTSTP */
-#endif /* NOJC */
-
- conbgt(0); /* See if we're in the background */
- congm(); /* Get console modes */
-
- (VOID) signal(SIGALRM,SIG_IGN); /* Ignore alarms */
-
- ignorsigs(); /* Ignore some other signals */
-
-#ifdef F_SETFL
- iniflags = fcntl(0,F_GETFL,0); /* Get stdin flags */
-#endif /* F_SETFL */
-
-#ifdef ultrix
- gtty(0,&vanilla); /* Get sgtty info */
-#else
-#ifdef AUX
- set42sig(); /* Don't ask! (hakanson@cs.orst.edu) */
-#endif /* AUX */
-#endif /* ultrix */
-/*
- Warning: on some UNIX systems (SVR4?), ttyname() reportedly opens /dev but
- never closes it. If it is called often enough, we run out of file
- descriptors and subsequent open()'s of other devices or files can fail.
-*/
- s = NULL;
-#ifndef MINIX
- if (isatty(0)) /* Name of controlling terminal */
- s = ttyname(0);
- else if (isatty(1))
- s = ttyname(1);
- else if (isatty(2))
- s = ttyname(2);
- debug(F110,"sysinit ttyname(0)",s,0);
-#endif /* MINIX */
-
-#ifdef BEOS
- if (!dftty)
- makestr(&dftty,s);
-#endif /* BEOS */
-
- if (s)
- ckstrncpy((char *)cttnam,s,DEVNAMLEN+1);
-#ifdef SVORPOSIX
- if (!cttnam[0])
- ctermid(cttnam);
-#endif /* SVORPOSIX */
- if (!cttnam[0])
- ckstrncpy((char *)cttnam,dftty,DEVNAMLEN+1);
- debug(F110,"sysinit CTTNAM",CTTNAM,0);
- debug(F110,"sysinit cttnam",cttnam,0);
-
- ttgwsiz(); /* Get window (screen) dimensions. */
-
-#ifndef NOSYSCONF
-#ifdef _SC_OPEN_MAX
- ckmaxfiles = sysconf(_SC_OPEN_MAX);
-#endif /* _SC_OPEN_MAX */
-#endif /* NOSYSCONF */
-
-#ifdef Plan9
- if (!backgrd) {
- consctlfd = open("/dev/consctl", O_WRONLY);
- /*noisefd = open("/dev/noise", O_WRONLY)*/
- }
- ckxech = 1;
-#endif /* Plan9 */
-
-#ifdef CK_UTSNAME
- if (uname(&name) > -1) {
- ckstrncpy(unm_mch,name.machine,CK_SYSNMLN);
- ckstrncpy(unm_nam,name.sysname,CK_SYSNMLN);
- ckstrncpy(unm_rel,name.release,CK_SYSNMLN);
- ckstrncpy(unm_ver,name.version,CK_SYSNMLN);
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"sysinit uname machine",unm_mch,0);
- debug(F110,"sysinit uname sysname",unm_nam,0);
- debug(F110,"sysinit uname release",unm_rel,0);
- debug(F110,"sysinit uname version",unm_ver,0);
- }
-#endif /* DEBUG */
-
-#ifdef HPUX9PLUS
- if (name.machine[5] == '8')
- hpis800 = 1;
- else
- hpis800 = 0;
- debug(F101,"sysinit hpis800","",hpis800);
-#endif /* HPUX9PLUS */
-#ifdef TRU64
- getsysinfo(GSI_PLATFORM_NAME, unm_mod, CK_SYSNMLN, 0, 0);
- debug(F110,"sysinit getsysinfo model",unm_mod,0);
-#endif /* TRU64 */
-#ifdef SOLARIS25
- sysinfo(SI_PLATFORM, unm_mod, CK_SYSNMLN);
- debug(F110,"sysinit sysinfo model",unm_mod,0);
-#endif /* SOLARIS25 */
- }
-#endif /* CK_UTSNAME */
-
-#ifdef CK_ENVIRONMENT
- {
-#ifdef TNCODE
- extern char tn_env_acct[], tn_env_disp[], tn_env_job[],
- tn_env_prnt[], tn_env_sys[];
-#endif /* TNCODE */
- extern char uidbuf[];
- extern char * whoami();
- char *p;
-#ifdef CKSENDUID
- uidbuf[0] = '\0';
-#ifdef IKSD
- if (!inserver) {
-#endif /* IKSD */
- p = getenv("USER");
- debug(F110,"sysinit uidbuf from USER",uidbuf,0);
- if (!p) p = "";
- if (!*p) {
- p = getenv("LOGNAME");
- debug(F110,"sysinit uidbuf from LOGNAME",uidbuf,0);
- }
- if (!p) p = "";
- if (!*p) {
- p = whoami();
- debug(F110,"sysinit uidbuf from whoami()",uidbuf,0);
- }
- if (!p) p = "";
- ckstrncpy(uidbuf, *p ? p : "UNKNOWN", UIDBUFLEN);
-#ifdef IKSD
- }
-#endif /* IKSD */
- debug(F110,"sysinit final uidbuf",uidbuf,0);
-#endif /* CKSENDUID */
-
-#ifdef TNCODE
- if ((p = getenv("JOB"))) ckstrncpy(tn_env_job,p,63);
- if ((p = getenv("ACCT"))) ckstrncpy(tn_env_acct,p,63);
- if ((p = getenv("PRINTER"))) ckstrncpy(tn_env_prnt,p,63);
- if ((p = getenv("DISPLAY"))) ckstrncpy(tn_env_disp,p,63);
-#ifdef aegis
- ckstrncpy(tn_env_sys,"Aegis",64);
-#else
-#ifdef Plan9
- ckstrncpy(tn_env_sys,"Plan9",64);
-#else
- ckstrncpy(tn_env_sys,"UNIX",64);
-#endif /* Plan9 */
-#endif /* aegis */
-#endif /* TNCODE */
- }
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_SNDLOC
- {
- extern char * tn_loc;
- char *p;
- if (p = getenv("LOCATION"))
- if (tn_loc = (char *)malloc((int)strlen(p)+1))
- strcpy(tn_loc,p); /* safe */
- }
-#endif /* CK_SNDLOC */
-
- ckstrncpy(startupdir, zgtdir(), CKMAXPATH);
- startupdir[CKMAXPATH] = '\0';
- x = strlen(startupdir);
- if (x <= 0) {
- startupdir[0] = '/';
- startupdir[1] = '\0';
- } else if (startupdir[x-1] != '/') {
- startupdir[x] = '/';
- startupdir[x+1] = '\0';
- }
- debug(F110,"sysinit startupdir",startupdir,0);
-#ifdef TTLEBUF
- le_init();
-#endif /* TTLEBUF */
-#ifdef BSD44ORPOSIX
- /* This should catch the ncurses platforms */
- /* Some platforms don't have putenv(), like NeXTSTEP */
- putenv("NCURSES_NO_SETBUF=1");
-#endif /* BSD44ORPOSIX */
- return(0);
-}
-
-/* S Y S C L E A N U P -- System-dependent program cleanup. */
-
-int
-syscleanup() {
-#ifdef F_SETFL
- if (iniflags > -1)
- fcntl(0,F_SETFL,iniflags); /* Restore stdin flags */
-#endif /* F_SETFL */
-#ifdef ultrix
- stty(0,&vanilla); /* Get sgtty info */
-#endif /* ultrix */
-#ifdef NETCMD
- if (ttpid) kill(ttpid,9);
-#endif /* NETCMD */
- return(0);
-}
-
-/* T T O P E N -- Open a tty for exclusive access. */
-
-/*
- Call with:
- ttname: character string - device name or network host name.
- lcl:
- If called with lcl < 0, sets value of lcl as follows:
- 0: the terminal named by ttname is the job's controlling terminal.
- 1: the terminal named by ttname is not the job's controlling terminal.
- But watch out: if a line is already open, or if requested line can't
- be opened, then lcl remains (and is returned as) -1.
- modem:
- Less than zero: ttname is a network host name.
- Zero or greater: ttname is a terminal device name.
- Zero means a local connection (don't use modem signals).
- Positive means use modem signals.
- timo:
- 0 = no timer.
- nonzero = number of seconds to wait for open() to return before timing out.
-
- Returns:
- 0 on success
- -5 if device is in use
- -4 if access to device is denied
- -3 if access to lock directory denied
- -2 upon timeout waiting for device to open
- -1 on other error
-*/
-static int ttotmo = 0; /* Timeout flag */
-/* Flag kept here to avoid being clobbered by longjmp. */
-
-int
-ttopen(ttname,lcl,modem,timo) char *ttname; int *lcl, modem, timo; {
-
-#ifdef BSD44
-#define ctermid(x) strcpy(x,"")
-#else
-#ifdef SVORPOSIX
-#ifndef CIE
- extern char *ctermid(); /* Wish they all had this! */
-#else /* CIE Regulus */
-#define ctermid(x) strcpy(x,"")
-#endif /* CIE */
-#endif /* SVORPOSIX */
-#endif /* BSD44 */
-
-#ifdef ultrix
- int temp = 0;
-#endif /* ultrix */
-
-#ifndef OPENFIRST
- char fullname[DEVNAMLEN+1];
-#endif /* OPENFIRST */
-
- char * fnam; /* Full name after expansion */
-
- int y;
-
-#ifndef pdp11
-#define NAMEFD /* Feature to allow name to be an open file descriptor */
-#endif /* pdp11 */
-
-#ifdef NAMEFD
- char *p;
- debug(F101,"ttopen telnetfd","",telnetfd);
-#endif /* NAMEFD */
-
- debug(F110,"ttopen ttname",ttname,0);
- debug(F110,"ttopen ttnmsv",ttnmsv,0);
- debug(F101,"ttopen modem","",modem);
- debug(F101,"ttopen netconn","",netconn);
- debug(F101,"ttopen ttyfd","",ttyfd);
- debug(F101,"ttopen *lcl","",*lcl);
- debug(F101,"ttopen ttmdm","",ttmdm);
- debug(F101,"ttopen ttnet","",ttnet);
-
- ttpmsk = 0xff;
- lockpid[0] = '\0';
-
- if (ttyfd > -1) { /* If device already opened */
- if (!strncmp(ttname,ttnmsv,DEVNAMLEN)) /* are new & old names equal? */
- return(0); /* Yes, nothing to do - just return */
- ttnmsv[0] = '\0'; /* No, clear out old name */
- ttclos(ttyfd); /* close old connection. */
- }
- wasclosed = 0; /* New connection, not closed yet. */
- ttpipe = 0; /* Assume it's not a pipe */
- ttpty = 0; /* or a pty... */
-
-#ifdef NETCONN
-/*
- This is a bit tricky... Suppose that previously Kermit had dialed a telnet
- modem server ("set host xxx:2001, set modem type usr, dial ..."). Then the
- connection was closed (ttyfd = -1), and then a REDIAL command was given. At
- this point we've obliterated the negative modem type hack, and so would
- treat the IP hostname as a device name, and would then fail because of "No
- such device or directory". But the previous connection has left behind some
- clues, so let's use them...
-*/
- if (ttyfd < 0) { /* Connection is not open */
- if (!strcmp(ttname,ttnmsv)) { /* Old and new names the same? */
- if (((netconn > 0) && (ttmdm < 0)) ||
- ((ttnet > 0) &&
- (!ckstrchr(ttname,'/')) && (ckstrchr(ttname,':')))
- ) {
- int x, rc;
- x = (ttmdm < 0) ? -ttmdm : ttnet;
- rc = netopen(ttname, lcl, x);
- debug(F111,"ttopen REOPEN netopen",ttname,rc);
- if (rc > -1) {
- netconn = 1;
- xlocal = *lcl = 1;
- } else {
- netconn = 0;
- }
- gotsigs = 0;
- return(rc);
- }
- }
- }
-#endif /* NETCONN */
-
-#ifdef MAXNAMLEN
- debug(F100,"ttopen MAXNAMLEN defined","",0);
-#else
- debug(F100,"ttopen MAXNAMLEN *NOT* defined","",0);
-#endif
-
-#ifdef BSD4
- debug(F100,"ttopen BSD4 defined","",0);
-#else
- debug(F100,"ttopen BSD4 *NOT* defined","",0);
-#endif /* BSD4 */
-
-#ifdef BSD42
- debug(F100,"ttopen BSD42 defined","",0);
-#else
- debug(F100,"ttopen BSD42 *NOT* defined","",0);
-#endif /* BSD42 */
-
-#ifdef MYREAD
- debug(F100,"ttopen MYREAD defined","",0);
-#else
- debug(F100,"ttopen MYREAD *NOT* defined","",0);
-#endif /* MYREAD */
-
-#ifdef NETCONN
- if (modem < 0) { /* modem < 0 = code for network */
- int x;
- ttmdm = modem;
- modem = -modem; /* Positive network type number */
- fdflag = 0; /* Stdio not redirected. */
- netconn = 1; /* And it's a network connection */
- debug(F111,"ttopen net",ttname,modem);
-#ifdef NAMEFD
- for (p = ttname; isdigit(*p); p++) ; /* Check for all digits */
- if (*p == '\0' && (telnetfd || x25fd)) { /* Avoid X.121 addresses */
- ttyfd = atoi(ttname); /* Is there a way to test it's open? */
- ttfdflg = 1; /* We got an open file descriptor */
- debug(F111,"ttopen net ttfdflg",ttname,ttfdflg);
- debug(F101,"ttopen net ttyfd","",ttyfd);
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */
- x = 1; /* Return code is "good". */
- if (telnetfd) {
- ttnet = NET_TCPB;
- if (ttnproto != NP_TCPRAW)
- ttnproto = NP_TELNET;
-#ifdef SUNX25
- } else if (x25fd) {
- ttnet = NET_SX25;
- ttnproto = NP_NONE;
-#endif /* SUNX25 */
- }
- } else { /* Host name or address given */
-#ifdef NETPTY
- if (modem == NET_PTY) {
- int x;
- if (nopush) {
- debug(F100,"ttopen PTY: nopush","",0);
- return(-1);
- }
- ttnet = NET_PTY;
- ttnproto = NP_NONE;
- netconn = 1; /* but we don't use network i/o */
- ttpty = 1;
- debug(F110,"ttopen PTY",ttname,0);
- x = do_pty(&ttyfd,ttname,0);
- if (x > -1) {
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN);
- xlocal = *lcl = 1; /* It's local */
- } else {
- ttpty = 0;
- netconn = 0;
- }
- gotsigs = 0;
- return(x);
- }
-#endif /* NETPTY */
-#ifdef NETCMD
-/*
- dup2() is not available on older System V platforms like AT&T 3Bx. For
- those systems we punt by not defining NETCMD, but we might be able to do
- better -- see workarounds for this problem in ckufio.c (search for dup2).
-*/
- if (modem == NET_CMD) {
- if (nopush) {
- debug(F100,"ttopen pipe: nopush","",0);
- return(-1);
- }
- if (pipe(pipe0) || pipe(pipe1)) {
- perror("Pipe error");
- return(-1);
- }
- ttpid = fork(); /* Make a fork */
-
- switch (ttpid) {
- case -1: /* Error making fork */
- close(pipe0[0]);
- close(pipe0[1]);
- close(pipe1[0]);
- close(pipe1[1]);
- perror("Fork error");
- return(-1);
- case 0: /* Child. */
- close(pipe0[0]);
- close(pipe1[1]);
- dup2(pipe0[1], 1);
- close(pipe0[1]);
- dup2(pipe1[0], 0);
- close(pipe1[0]);
- system(ttname);
- _exit(0);
- default: /* Parent */
- close(pipe0[1]);
- close(pipe1[0]);
- fdin = pipe0[0]; /* Read from pipe */
- fdout = pipe1[1]; /* Write to pipe */
- ttout = fdopen(fdout,"w"); /* Get stream so we can */
- if (!ttout) { /* make it unbuffered. */
- perror("fdopen failure");
- return(-1);
- }
- setbuf(ttout,NULL);
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN);
- xlocal = *lcl = 1; /* It's local */
- netconn = 1; /* Call it a network connection */
- ttmdm = modem; /* Remember network type */
- ttyfd = fdin;
- ttpipe = 1;
- gotsigs = 0;
- return(0);
- }
- }
-#endif /* NETCMD */
-#endif /* NAMEFD */
- x = netopen(ttname, lcl, modem); /* (see ckcnet.h) */
- if (x > -1) {
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN);
- } else netconn = 0;
-#ifdef NAMEFD
- }
-#endif /* NAMEFD */
-
-#ifdef sony_news /* Sony NEWS */
- if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get Kanji mode */
- perror("ttopen error getting Kanji mode (network)");
- debug(F111,"ttopen error getting Kanji mode","network",0);
- km_ext = -1; /* Make sure this stays undefined. */
- }
-#endif /* sony_news */
-
- xlocal = *lcl = 1; /* Network connections are local. */
- debug(F101,"ttopen net x","",x);
-#ifdef COMMENT
-/* Let netopen() do this */
- if (x > -1 && !x25fd)
- x = tn_ini(); /* Initialize TELNET protocol */
-#endif /* COMMENT */
- gotsigs = 0;
- return(x);
- } else { /* Terminal device */
-#endif /* NETCONN */
-
-#ifdef NAMEFD
-/*
- This code lets you give Kermit an open file descriptor for a serial
- communication device, rather than a device name. Kermit assumes that the
- line is already open, locked, conditioned with the right parameters, etc.
-*/
- for (p = ttname; isdigit(*p); p++) ; /* Check for all-digits */
- if (*p == '\0') {
- ttyfd = atoi(ttname); /* Is there a way to test it's open? */
- debug(F111,"ttopen got open fd",ttname,ttyfd);
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */
- if (ttyfd >= 0 && ttyfd < 3) /* If it's stdio... */
- xlocal = *lcl = 0; /* we're in remote mode */
- else /* otherwise */
- xlocal = *lcl = 1; /* local mode. */
- netconn = 0; /* Assume it's not a network. */
- tvtflg = 0; /* Might need to initialize modes. */
- ttmdm = modem; /* Remember modem type. */
- fdflag = 0; /* Stdio not redirected. */
- ttfdflg = 1; /* Flag we were opened this way. */
- debug(F111,"ttopen non-net ttfdflg",ttname,ttfdflg);
- debug(F101,"ttopen non-net ttyfd","",ttyfd);
-
-#ifdef sony_news /* Sony NEWS */
- /* Get device Kanji mode */
- if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) {
- perror("ttopen error getting Kanji mode");
- debug(F101,"ttopen error getting Kanji mode","",0);
- km_ext = -1; /* Make sure this stays undefined. */
- }
-#endif /* sony_news */
- gotsigs = 0;
- return(0); /* Return success */
- }
-#endif /* NAMEFD */
-#ifdef NETCONN
- }
-#endif /* NETCONN */
-
-/* Here we have to open a serial device of the given name. */
-
- netconn = 0; /* So it's not a network connection */
- occt = signal(SIGINT, cctrap); /* Set Control-C trap, save old one */
- sigint_ign = 0;
-
- tvtflg = 0; /* Flag for use by ttvt(). */
- /* 0 = ttvt not called yet for this device */
-
- fdflag = (!isatty(0) || !isatty(1)); /* Flag for stdio redirected */
- debug(F101,"ttopen fdflag","",fdflag);
-
- ttmdm = modem; /* Make this available to other fns */
- xlocal = *lcl; /* Make this available to other fns */
-
-/* Code for handling bidirectional tty lines goes here. */
-/* Use specified method for turning off logins and suppressing getty. */
-
-#ifdef ACUCNTRL
- /* Should put call to priv_on() here, but that would be very risky! */
- acucntrl("disable",ttname); /* acucntrl() program. */
- /* and priv_off() here... */
-#else
-#ifdef ATT7300
- if ((attmodem & DOGETY) == 0) /* offgetty() program. */
- attmodem |= offgetty(ttname); /* Remember response. */
-#endif /* ATT7300 */
-#endif /* ACUCNTRL */
-
-#ifdef OPENFIRST
-/*
- 1985-2001: opens device first then gets lock; reason:
- Kermit usually has to run setuid or setgid in order to create a lockfile.
- If you give a SET LINE command for a device that happens to be your job's
- controlling terminal, Kermit doesn't have to create a lockfile, and in fact
- should not create one, and would fail if it tried to if it did not have the
- required privileges. But you can't find out if two tty device names are
- equivalent until you have a file descriptor that you can give to ttyname().
- But this can cause a race condition between Kermit and [m]getty. So see
- the [#]else part...
-*/
-
-/*
- In the following section, we open the tty device for read/write.
- If a modem has been specified via "set modem" prior to "set line"
- then the O_NDELAY parameter is used in the open, provided this symbol
- is defined (e.g. in fcntl.h), so that the program does not hang waiting
- for carrier (which in most cases won't be present because a connection
- has not been dialed yet). O_NDELAY is removed later on in ttopen(). It
- would make more sense to first determine if the line is local before
- doing this, but because ttyname() requires a file descriptor, we have
- to open it first. See do_open().
-
- Now open the device using the desired treatment of carrier.
- If carrier is REQUIRED, then open could hang forever, so an optional
- timer is provided. If carrier is not required, the timer should never
- go off, and should do no harm...
-*/
- ttotmo = 0; /* Flag no timeout */
- debug(F101,"ttopen timo","",timo);
- debug(F101,"ttopen xlocal","",xlocal);
- if (timo > 0) {
- int xx;
- saval = signal(SIGALRM,timerh); /* Timed, set up timer. */
- xx = alarm(timo); /* Timed open() */
- debug(F101,"ttopen alarm","",xx);
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) {
- ttotmo = 1; /* Flag timeout. */
- } else ttyfd = do_open(ttname);
- ttimoff();
- debug(F111,"ttopen","modem",modem);
- debug(F101,"ttopen ttyfd","",ttyfd);
- debug(F101,"ttopen alarm return","",ttotmo);
- } else {
- errno = 0;
- ttyfd = do_open(ttname);
- }
- debug(F111,"ttopen ttyfd",ttname,ttyfd);
- if (ttyfd < 0) { /* If couldn't open, fail. */
- debug(F101,"ttopen errno","",errno);
- if (errno > 0 && !quiet)
- perror(ttname); /* Print message */
-
-#ifdef ATT7300
- if (attmodem & DOGETY) /* was getty(1m) running before us? */
- ongetty(ttnmsv); /* yes, restart on tty line */
- attmodem &= ~DOGETY; /* no phone in use, getty restored */
-#else
-#ifdef ACUCNTRL
- /* Should put call to priv_on() here, but that would be risky! */
- acucntrl("enable",ttname); /* acucntrl() program. */
- /* and priv_off() here... */
-#endif /* ACUNTRL */
-#endif /* ATT7300 */
-
- signal(SIGINT,occt); /* Put old Ctrl-C trap back. */
- if (errno == EACCES) { /* Device is protected against user */
- debug(F110,"ttopen EACCESS",ttname,0); /* Return -4 */
- return(-4);
- } else return(ttotmo ? -2 : -1); /* Otherwise -2 if timeout, or -1 */
- }
-
-#ifdef QNX
- {
- extern int qnxportlock;
- x = qnxopencount();
- debug(F101,"ttopen qnxopencount","",x);
- debug(F101,"ttopen qnxportlock","",qnxportlock);
- if (x < 0 && qnxportlock) {
- ttclos(0);
- printf("?Can't get port open count\n");
- printf("(Try again with SET QNX-PORT-LOCK OFF)\n");
- return(-1); /* Indicate device is in use */
- }
- if (x > 1) { /* 1 == me */
- if (qnxportlock)
- ttclos(0);
- return(-2); /* Indicate device is in use */
- else if (!quiet)
- printf("WARNING: \"%s\" looks busy...\n",ttdev);
- }
- }
-#endif /* QNX */
-
-#ifdef Plan9
- /* take this opportunity to open the control channel */
- if (p9openttyctl(ttname) < 0)
-#else
- /* Make sure it's a real tty. */
- if (!ttfdflg && !isatty(ttyfd) && strcmp(ttname,"/dev/null"))
-#endif /* Plan9 */
- {
- fprintf(stderr,"%s is not a terminal device\n",ttname);
- debug(F111,"ttopen not a tty",ttname,errno);
- close(ttyfd);
- ttyfd = -1;
- wasclosed = 1;
- signal(SIGINT,occt);
- return(-1);
- }
-
-#ifdef aegis
- /* Apollo C runtime claims that console pads are tty devices, which
- * is reasonable, but they aren't any good for packet transfer. */
- ios_$inq_type_uid((short)ttyfd, ttyuid, st);
- if (st.all != status_$ok) {
- fprintf(stderr, "problem getting tty object type: ");
- error_$print(st);
- } else if (ttyuid != sio_$uid) { /* reject non-SIO lines */
- close(ttyfd); ttyfd = -1;
- wasclosed = 1;
- errno = ENOTTY; perror(ttname);
- signal(SIGINT,occt);
- return(-1);
- }
-#endif /* aegis */
-
- sigint_ign = (occt == SIG_IGN) ? 1 : 0;
-
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Keep copy of name locally. */
-
-/* Caller wants us to figure out if line is controlling tty */
-
- if (*lcl < 0) {
- if (strcmp(ttname,CTTNAM) == 0) { /* "/dev/tty" always remote */
- xlocal = 0;
- debug(F111,"ttopen ttname=CTTNAM",ttname,xlocal);
- } else if (strcmp(ttname,cttnam) == 0) {
- xlocal = 0;
- debug(F111,"ttopen ttname=cttnam",ttname,xlocal);
- } else if (cttnam[0]) {
-#ifdef BEBOX_DR7
- x = ttnmsv; /* ttyname() is broken */
-#else
- x = ttyname(ttyfd); /* Get real name of ttname. */
-#endif /* BEBOX_DR7 */
- if (!x) x = "";
- if (*x)
- xlocal = ((strncmp(x,cttnam,DEVNAMLEN) == 0) ? 0 : 1);
- else
- xlocal = 1;
- debug(F111,"ttopen ttyname(ttyfd) xlocal",x,xlocal);
- }
- }
-
-#ifndef NOFDZERO
-/* Note, the following code was added so that Unix "idle-line" snoopers */
-/* would not think Kermit was idle when it was transferring files, and */
-/* maybe log people out. */
- if (xlocal == 0) { /* Remote mode */
- if (fdflag == 0) { /* Standard i/o is not redirected */
- debug(F100,"ttopen setting ttyfd = 0","",0);
-#ifdef LYNXOS
- /* On Lynx OS, fd 0 is open for read only. */
- dup2(ttyfd,0);
-#endif /* LYNXOS */
- close(ttyfd); /* Use file descriptor 0 */
- ttyfd = 0;
- } else { /* Standard i/o is redirected */
- debug(F101,"ttopen stdio redirected","",ttyfd);
- }
- }
-#endif /* NOFDZERO */
-
-/* Now check if line is locked -- if so fail, else lock for ourselves */
-/* Note: After having done this, don't forget to delete the lock if you */
-/* leave ttopen() with an error condition. */
-
- lkf = 0; /* Check lock */
- if (xlocal > 0) {
- int xx; int xpid;
- if ((xx = ttlock(ttname)) < 0) { /* Can't lock it. */
- debug(F111,"ttopen ttlock fails",ttname,xx);
- /* WARNING - This close() can hang if tty is an empty socket... */
- close(ttyfd); /* Close the device. */
- ttyfd = -1; /* Erase its file descriptor. */
- wasclosed = 1;
- signal(SIGINT,occt); /* Put old SIGINT back. */
- sigint_ign = (occt == SIG_IGN) ? 1 : 0;
- if (xx == -2) { /* If lockfile says device in use, */
-#ifndef NOUUCP
- debug(F111,"ttopen reading lockfile pid",flfnam,xx);
- xpid = ttrpid(flfnam); /* Try to read pid from lockfile */
- if (xpid > -1) { /* If we got a pid */
- if (!quiet)
- printf("Locked by process %d\n",xpid); /* tell them. */
- sprintf(lockpid,"%d",xpid); /* Record it too */
- debug(F110,"ttopen lockpid",lockpid,0);
- } else if (*flfnam) {
- extern char *DIRCMD;
- char *p = NULL;
- int x;
- x = (int)strlen(flfnam) + (int)strlen(DIRCMD) + 2;
- p = malloc(x); /* Print a directory listing. */
-/*
- Note: priv_on() won't help here, because we do not pass privs along to
- to inferior processes, in this case ls. So if the real user does not have
- directory-listing access to the lockfile directory, this will result in
- something like "not found". That's why we try this only as a last resort.
-*/
- if (p) { /* If we got the space... */
- ckmakmsg(p,x,DIRCMD," ",flfnam,NULL);
- zsyscmd(p); /* Get listing. */
- if (p) { /* free the space */
- free(p);
- p = NULL;
- }
- }
- }
-#endif /* NOUUCP */
- return(-5); /* Code for device in use */
- } else return(-3); /* Access denied */
- } else lkf = 1;
- }
-#else /* OPENFIRST */
-
-/*
- 27 Oct 2001: New simpler code that gets the lock first and then opens the
- device, which eliminates the race condition. The downside is you can no
- longer say "set line /dev/ttyp0" or whatever, where /dev/ttyp0 is your login
- terminal, without trying to create a lockfile, which fails if C-Kermit lacks
- privs, and if it succeeds, it has created a lockfile where it didn't create
- one before.
-*/
- xlocal = *lcl; /* Is the device my login terminal? */
- debug(F111,"ttopen xlocal","A",xlocal);
- fnam = ttname;
- if (strcmp(ttname,CTTNAM) && netconn == 0) {
- if (zfnqfp(ttname,DEVNAMLEN+1,fullname)) {
- if ((int)strlen(fullname) > 0)
- fnam = fullname;
- }
- }
- debug(F110,"ttopen fnam",fnam,0);
- if (xlocal < 0) {
- xlocal = (strcmp(fnam,CTTNAM) != 0);
- }
- debug(F111,"ttopen xlocal","B",xlocal);
-
- lkf = 0; /* No lock yet */
- if (xlocal > 0) { /* If not... */
- int xx; int xpid;
- xx = ttlock(fnam); /* Try to lock it. */
- debug(F101,"ttopen ttlock","",xx);
- if (xx < 0) { /* Can't lock it. */
- debug(F111,"ttopen ttlock fails",fnam,xx);
- if (xx == -2) { /* If lockfile says device in use, */
-#ifndef NOUUCP
- debug(F111,"ttopen reading lockfile pid",flfnam,xx);
- xpid = ttrpid(flfnam); /* Try to read pid from lockfile */
- if (xpid > -1) { /* If we got a pid */
- if (!quiet)
- printf("Locked by process %d\n",xpid); /* tell them. */
- ckstrncpy(lockpid,ckitoa(xpid),16);
- debug(F110,"ttopen lockpid",lockpid,0);
-#ifndef NOPUSH
- } else if (flfnam[0] && !nopush) {
- extern char *DIRCMD;
- char *p = NULL;
- int x;
- x = (int)strlen(flfnam) + (int)strlen(DIRCMD) + 2;
- p = malloc(x); /* Print a directory listing. */
-/*
- Note: priv_on() won't help here, because we do not pass privs along to
- to inferior processes, in this case ls. So if the real user does not have
- directory-listing access to the lockfile directory, this will result in
- something like "not found". That's why we try this only as a last resort.
-*/
- if (p) { /* If we got the space... */
- ckmakmsg(p,x,DIRCMD," ",flfnam,NULL);
- zsyscmd(p); /* Get listing. */
- if (p) { /* free the space */
- free(p);
- p = NULL;
- }
- }
-#endif /* NOPUSH */
- }
-#endif /* NOUUCP */
- return(-5); /* Code for device in use */
- } else return(-3); /* Access denied */
- } else lkf = 1;
- }
- /* Have lock -- now it's safe to open the device */
-
- debug(F101,"ttopen lkf","",lkf);
- debug(F101,"ttopen timo","",timo);
-
- ttotmo = 0; /* Flag no timeout */
- if (timo > 0) {
- int xx;
- saval = signal(SIGALRM,timerh); /* Timed, set up timer. */
- xx = alarm(timo); /* Timed open() */
- debug(F101,"ttopen alarm","",xx);
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) {
- ttotmo = 1; /* Flag timeout. */
- } else {
- ttyfd = do_open(fnam);
- }
- ttimoff();
- debug(F111,"ttopen timed ttyfd",fnam,ttyfd);
- } else {
- errno = 0;
- ttyfd = do_open(fnam);
- debug(F111,"ttopen untimed ttyfd",fnam,ttyfd);
- }
- if (ttyfd < 0) { /* If couldn't open, fail. */
- debug(F111,"ttopen errno",fnam,errno);
- debug(F111,"ttopen xlocal","C",xlocal);
- if (xlocal == 0) {
- debug(F100,"ttopen substituting 0","",0);
- ttyfd = 0;
- } else {
- if (errno > 0 && !quiet) {
- debug(F111,"ttopen perror",fnam,errno);
- perror(fnam); /* Print message */
- }
- if (ttunlck()) /* Release the lock file */
- fprintf(stderr,"Warning, problem releasing lock\r\n");
- }
- }
-
- if (ttyfd < 0) { /* ttyfd is still < 0? */
-#ifdef ATT7300
- if (attmodem & DOGETY) /* was getty(1m) running before us? */
- ongetty(ttnmsv); /* yes, restart on tty line */
- attmodem &= ~DOGETY; /* no phone in use, getty restored */
-#else
-#ifdef ACUCNTRL
- /* Should put call to priv_on() here, but that would be risky! */
- acucntrl("enable",fnam); /* acucntrl() program. */
- /* and priv_off() here... */
-#endif /* ACUNTRL */
-#endif /* ATT7300 */
-
- signal(SIGINT,occt); /* Put old Ctrl-C trap back. */
- if (errno == EACCES) { /* Device is protected against user */
- debug(F110,"ttopen EACCESS",fnam,0); /* Return -4 */
- return(-4);
- } else return(ttotmo ? -2 : -1); /* Otherwise -2 if timeout, or -1 */
- }
-
-/* Make sure it's a real tty. */
-
-#ifdef Plan9
- /* take this opportunity to open the control channel */
- if (p9openttyctl(fnam) < 0)
-#else
- if (!ttfdflg && !isatty(ttyfd) && strcmp(fnam,"/dev/null"))
-#endif /* Plan9 */
- {
- fprintf(stderr,"%s is not a terminal device\n",fnam);
- debug(F111,"ttopen not a tty",fnam,errno);
- if (ttunlck()) /* Release the lock file */
- fprintf(stderr,"Warning, problem releasing lock\r\n");
- close(ttyfd);
- ttyfd = -1;
- wasclosed = 1;
- signal(SIGINT,occt);
- return(-1);
- }
-
-#ifdef aegis
- /*
- Apollo C runtime claims that console pads are tty devices, which
- is reasonable, but they aren't any good for packet transfer.
- */
- ios_$inq_type_uid((short)ttyfd, ttyuid, st);
- if (st.all != status_$ok) {
- fprintf(stderr, "problem getting tty object type: ");
- error_$print(st);
- } else if (ttyuid != sio_$uid) { /* Reject non-SIO lines */
- close(ttyfd); ttyfd = -1;
- wasclosed = 1;
- errno = ENOTTY; perror(fnam);
- signal(SIGINT,occt);
- return(-1);
- }
-#endif /* aegis */
-
- sigint_ign = (occt == SIG_IGN) ? 1 : 0;
-
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Keep copy of name locally. */
-
-/* Caller wants us to figure out if line is controlling tty */
-
- if (*lcl < 0) {
- char * s;
- if (strcmp(fnam,CTTNAM) == 0) { /* "/dev/tty" always remote */
- xlocal = 0;
- debug(F111,"ttopen fnam=CTTNAM",fnam,xlocal);
- } else if (strcmp(fnam,cttnam) == 0) {
- xlocal = 0;
- debug(F111,"ttopen fnam=cttnam",fnam,xlocal);
- } else if (cttnam[0]) {
-#ifdef BEBOX_DR7
- s = ttnmsv; /* ttyname() is broken */
-#else
- s = ttyname(ttyfd); /* Get real name of ttname. */
-#endif /* BEBOX_DR7 */
- if (!s) s = "";
- if (*s)
- xlocal = ((strncmp(s,cttnam,DEVNAMLEN) == 0) ? 0 : 1);
- else
- xlocal = 1;
- debug(F111,"ttopen ttyname(ttyfd) xlocal",s,xlocal);
- }
- }
-
-#ifndef NOFDZERO
-/* Note, the following code was added so that Unix "idle-line" snoopers */
-/* would not think Kermit was idle when it was transferring files, and */
-/* maybe log people out. */
- if (xlocal == 0) { /* Remote mode */
- if (fdflag == 0) { /* Standard i/o is not redirected */
- debug(F100,"ttopen setting ttyfd = 0","",0);
-#ifdef LYNXOS
- /* On Lynx OS, fd 0 is open for read only. */
- dup2(ttyfd,0);
-#endif /* LYNXOS */
- close(ttyfd); /* Use file descriptor 0 */
- ttyfd = 0;
- } else { /* Standard i/o is redirected */
- debug(F101,"ttopen stdio redirected","",ttyfd);
- }
- }
-#endif /* NOFDZERO */
-#endif /* OPENFIRST */
-
-/* Got the line, now set the desired value for local. */
-
- if (*lcl != 0) *lcl = xlocal;
-
-/* Some special stuff for v7... */
-
-#ifdef V7
-#ifndef MINIX
- if (kmem[TTY] < 0) { /* If open, then skip this. */
- qaddr[TTY] = initrawq(ttyfd); /* Init the queue. */
- if ((kmem[TTY] = open("/dev/kmem", 0)) < 0) {
- fprintf(stderr, "Can't read /dev/kmem in ttopen.\n");
- perror("/dev/kmem");
- exit(1);
- }
- }
-#endif /* !MINIX */
-#endif /* V7 */
-
-/* No failure returns after this point */
-
-#ifdef ultrix
- ioctl(ttyfd, TIOCMODEM, &temp);
-#ifdef TIOCSINUSE
- if (xlocal && ioctl(ttyfd, TIOCSINUSE, NULL) < 0) {
- if (!quiet)
- perror(fnam);
- }
-#endif /* TIOCSINUSE */
-#endif /* ultrix */
-
-/* Get tty device settings */
-
-#ifdef BSD44ORPOSIX /* POSIX */
- tcgetattr(ttyfd,&ttold);
- debug(F101,"ttopen tcgetattr ttold.c_lflag","",ttold.c_lflag);
- tcgetattr(ttyfd,&ttraw);
- debug(F101,"ttopen tcgetattr ttraw.c_lflag","",ttraw.c_lflag);
- tcgetattr(ttyfd,&tttvt);
- debug(F101,"ttopen tcgetattr tttvt.c_lflag","",tttvt.c_lflag);
-#else /* BSD, V7, and all others */
-#ifdef ATTSV /* AT&T UNIX */
- ioctl(ttyfd,TCGETA,&ttold);
- debug(F101,"ttopen ioctl TCGETA ttold.c_lflag","",ttold.c_lflag);
- ioctl(ttyfd,TCGETA,&ttraw);
- ioctl(ttyfd,TCGETA,&tttvt);
-#else
-#ifdef BELLV10
- ioctl(ttyfd,TIOCGETP,&ttold);
- debug(F101,"ttopen BELLV10 ttold.sg_flags","",ttold.sg_flags);
- ioctl(ttyfd,TIOCGDEV,&tdold);
- debug(F101,"ttopen BELLV10 tdold.flags","",tdold.flags);
-#else
- gtty(ttyfd,&ttold);
- debug(F101,"ttopen gtty ttold.sg_flags","",ttold.sg_flags);
-#endif /* BELLV10 */
-
-#ifdef sony_news /* Sony NEWS */
- if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get console Kanji mode */
- perror("ttopen error getting Kanji mode");
- debug(F101,"ttopen error getting Kanji mode","",0);
- km_ext = -1; /* Make sure this stays undefined. */
- }
-#endif /* sony_news */
-
-#ifdef TIOCGETC
- debug(F100,"ttopen TIOCGETC","",0);
- tcharf = 0; /* In remote mode, also get */
- if (xlocal == 0) { /* special characters */
- if (ioctl(ttyfd,TIOCGETC,&tchold) < 0) {
- debug(F100,"ttopen TIOCGETC failed","",0);
- } else {
- tcharf = 1; /* It worked. */
- ioctl(ttyfd,TIOCGETC,&tchnoi); /* Get another copy */
- debug(F100,"ttopen TIOCGETC ok","",0);
- }
- }
-#else
- debug(F100,"ttopen TIOCGETC not defined","",0);
-#endif /* TIOCGETC */
-
-#ifdef TIOCGLTC
- debug(F100,"ttopen TIOCGLTC","",0);
- ltcharf = 0; /* In remote mode, also get */
- if (xlocal == 0) { /* local special characters */
- if (ioctl(ttyfd,TIOCGLTC,<chold) < 0) {
- debug(F100,"ttopen TIOCGLTC failed","",0);
- } else {
- ltcharf = 1; /* It worked. */
- ioctl(ttyfd,TIOCGLTC,<chnoi); /* Get another copy */
- debug(F100,"ttopen TIOCGLTC ok","",0);
- }
- }
-#else
- debug(F100,"ttopen TIOCGLTC not defined","",0);
-#endif /* TIOCGLTC */
-
-#ifdef TIOCLGET
- debug(F100,"ttopen TIOCLGET","",0);
- lmodef = 0;
- if (ioctl(ttyfd,TIOCLGET,&lmode) < 0) {
- debug(F100,"ttopen TIOCLGET failed","",0);
- } else {
- lmodef = 1;
- debug(F100,"ttopen TIOCLGET ok","",0);
- }
-#endif /* TIOCLGET */
-
-#ifdef BELLV10
- ioctl(ttyfd,TIOCGETP,&ttraw);
- ioctl(ttyfd,TIOCGETP,&tttvt);
-#else
- gtty(ttyfd,&ttraw); /* And a copy of it for packets*/
- gtty(ttyfd,&tttvt); /* And one for virtual tty service */
-#endif /* BELLV10 */
-
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-
-/* Section for changing line discipline. It's restored in ttres(). */
-
-#ifdef AIXRS
-#ifndef AIX41
- { union txname ld_name; int ld_idx = 0;
- ttld = 0;
- do {
- ld_name.tx_which = ld_idx++;
- ioctl(ttyfd, TXGETCD, &ld_name);
- if (!strncmp(ld_name.tx_name, "rts", 3))
- ttld |= 1;
- } while (*ld_name.tx_name);
- debug(F101,"AIX line discipline","",ttld);
- }
-#endif /* AIX41 */
-#endif /* AIXRS */
-
-#ifdef BSD41
-/* For 4.1BSD only, force "old" tty driver, new one botches TANDEM. */
- { int k;
- ioctl(ttyfd, TIOCGETD, &ttld); /* Get and save line discipline */
- debug(F101,"4.1bsd line discipline","",ttld);
- k = OTTYDISC; /* Switch to "old" discipline */
- k = ioctl(ttyfd, TIOCSETD, &k);
- debug(F101,"4.1bsd tiocsetd","",k);
- }
-#endif /* BSD41 */
-
-#ifdef aegis
- /* This was previously done before the last two TCGETA or gtty above,
- * in both the ATTSV and not-ATTSV case. If it is not okay to have only
- * one copy if it here instead, give us a shout!
- */
- sio_$control((short)ttyfd, sio_$raw_nl, false, st);
- if (xlocal) { /* ignore breaks from local line */
- sio_$control((short)ttyfd, sio_$int_enable, false, st);
- sio_$control((short)ttyfd, sio_$quit_enable, false, st);
- }
-#endif /* aegis */
-
-#ifdef VXVE
- ttraw.c_line = 0; /* STTY line 0 for VX/VE */
- tttvt.c_line = 0; /* STTY line 0 for VX/VE */
- ioctl(ttyfd,TCSETA,&ttraw);
-#endif /* vxve */
-
-/* If O_NDELAY was used during open(), then remove it now. */
-
-#ifdef O_NDELAY
- debug(F100,"ttopen O_NDELAY","",0);
- if (xlocal > 0) {
- if (fcntl(ttyfd, F_GETFL, 0) & O_NDELAY) {
- debug(F100,"ttopen fcntl O_NDELAY","",0);
-#ifndef aegis
- if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0) {
- debug(F100,"ttopen fcntl failure to unset O_NDELAY","",0);
- perror("Can't unset O_NDELAY");
- }
-#endif /* aegis */
- /* Some systems, notably Xenix (don't know how common this is in
- * other systems), need special treatment to get rid of the O_NDELAY
- * behaviour on read() with respect to carrier presence (i.e. read()
- * returning 0 when carrier absent), even though the above fcntl()
- * is enough to make read() wait for input when carrier is present.
- * This magic, in turn, requires CLOCAL for working when the carrier
- * is absent. But if xlocal == 0, presumably you already have CLOCAL
- * or you have a carrier, otherwise you wouldn't be running this.
- */
- debug(F101,"ttopen xlocal","",xlocal);
-#ifdef ATTSV
-#ifdef BSD44ORPOSIX
-#ifdef COMMENT /* 12 Aug 1997 */
-#ifdef __bsdi__
- if (xlocal)
- ttraw.c_cflag |= CLOCAL;
-#else
-#ifdef __FreeBSD__
- if (xlocal)
- ttraw.c_cflag |= CLOCAL;
-#endif /* __FreeBSD__ */
-#endif /* __bsdi__ */
-#else /* Not COMMENT */
-#ifdef CLOCAL
- if (xlocal) /* Unset this if it's defined. */
- ttraw.c_cflag |= CLOCAL;
-#endif /* CLOCAL */
-#endif /* COMMENT */
- debug(F101,"ttopen BSD44ORPOSIX calling tcsetattr","",TCSADRAIN);
- if (tcsetattr(ttyfd, TCSADRAIN, &ttraw) < 0) {
- debug(F100,"ttopen POSIX tcseattr fails","",0);
- perror("tcsetattr");
- }
-#else /* !BSD44ORPOSIX */
- if (xlocal) {
- ttraw.c_cflag |= CLOCAL;
- debug(F100,"ttopen calling ioctl(TCSETA)","",0);
- errno = 0;
- if (ioctl(ttyfd, TCSETA, &ttraw) < 0) {
- debug(F101,"ttopen ioctl(TCSETA) fails","",errno);
- perror("ioctl(TCSETA)");
- }
- }
-#endif /* BSD44ORPOSIX */
-#endif /* ATTSV */
-#ifndef NOCOTFMC /* = NO Close(Open()) To Force Mode Change */
-/* Reportedly lets uugetty grab the device in SCO UNIX 3.2 / XENIX 2.3 */
- debug(F100,"ttopen executing close/open","",0);
- close( priv_opn(fnam, O_RDWR) ); /* Magic to force change. */
-#endif /* NOCOTFMC */
- }
- }
-#endif /* O_NDELAY */
-
-/* Instruct the system how to treat the carrier, and set a few other tty
- * parameters.
- *
- * This also undoes the temporary setting of CLOCAL that may have been done
- * for the close(open()) above (except in Xenix). Also throw in ~ECHO, to
- * prevent the other end of the line from sitting there talking to itself,
- * producing garbage when the user performs a connect.
- *
- * SCO Xenix unfortunately seems to ignore the actual state of CLOCAL.
- * Now it thinks CLOCAL is always on. It seems the only real solution for
- * Xenix is to switch between the lower and upper case device names.
- *
- * This section may at some future time expand into setting a complete
- * collection of tty parameters, or call a function shared with ttpkt()/
- * ttvt() that does so. On the other hand, the initial parameters are not
- * that important, since ttpkt() or ttvt() should always fix that before
- * any communication is done. Well, we'll see...
- */
- if (xlocal) {
- curcarr = -2;
- debug(F100,"ttopen calling carrctl","",0);
- carrctl(&ttraw, ttcarr == CAR_ON);
- debug(F100,"ttopen carrctl ok","",0);
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifdef SVORPOSIX
- ttraw.c_lflag &= ~ECHO;
- ttold.c_lflag &= ~ECHO;
-#ifdef BSD44ORPOSIX
- y = tcsetattr(ttyfd, TCSADRAIN, &ttraw);
- debug(F101,"ttopen tcsetattr","",y);
-#else
- y = ioctl(ttyfd, TCSETA, &ttraw);
- debug(F100,"ttopen ioctl","",y);
-#endif /* BSD44ORPOSIX */
-
-#else /* BSD, etc */
- ttraw.sg_flags &= ~ECHO;
- ttold.sg_flags &= ~ECHO;
-#ifdef BELLV10
- y = ioctl(ttyfd,TIOCSETP,&ttraw);
- debug(F100,"ttopen ioctl","",y);
-#else
- y = stty(ttyfd,&ttraw);
- debug(F100,"ttopen stty","",y);
-#endif /* BELLV10 */
-#endif /* SVORPOSIX */
-
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
- /* ttflui(); */ /* This fails for some reason. */
- }
-
- /* Get current speed */
-
-#ifndef BEBOX
- ttspeed = ttgspd();
-#else
- ttspeed = 19200;
-#endif /* !BEBOX */
- debug(F101,"ttopen ttspeed","",ttspeed);
-
- /* Done, make entries in debug log, restore Ctrl-C trap, and return. */
-
- debug(F101,"ttopen ttyfd","",ttyfd);
- debug(F101,"ttopen *lcl","",*lcl);
- debug(F111,"ttopen lock file",flfnam,lkf);
- signal(SIGINT,occt);
- sigint_ign = (occt == SIG_IGN) ? 1 : 0;
- gotsigs = 0;
- return(0);
-}
-
-
-/* D O _ O P E N -- Do the right kind of open() call for the tty. */
-
-int
-do_open(ttname) char *ttname; {
- int flags;
-
-#ifdef QNX6
- /* O_NONBLOCK on /dev/tty makes open() fail */
- return(priv_opn(ttname, O_RDWR |
- (
- ((int)strcmp(ttname,"/dev/tty") == 0) ?
- 0 :
- (ttcarr != CAR_ON) ? O_NONBLOCK : 0)
- )
- );
-#else /* !QNX6 */
-
-#ifndef O_NDELAY /* O_NDELAY not defined */
- return(priv_opn(ttname,2));
-#else /* O_NDELAY defined */
-
-#ifdef ATT7300
-/*
- Open comms line without waiting for carrier so initial call does not hang
- because state of "modem" is likely unknown at the initial call -jrd.
- If this is needed for the getty stuff to work, and the open would not work
- without O_NDELAY when getty is still on, then this special case is ok.
- Otherwise, get rid of it. -ske
-*/
- return(priv_opn(ttname, O_RDWR | O_NDELAY));
-
-#else /* !ATT7300 */
-
- /* Normal case. Use O_NDELAY according to SET CARRIER. See ttscarr(). */
- flags = O_RDWR;
- debug(F101,"do_open xlocal","",xlocal);
- debug(F111,"do_open flags A",ttname,flags);
- if (xlocal && (ttcarr != CAR_ON))
- flags |= O_NDELAY;
- debug(F111,"do_open flags B",ttname,flags);
- return(priv_opn(ttname, flags));
-#endif /* !ATT7300 */
-#endif /* O_NDELAY */
-#endif /* QNX6 */
-}
-
-/* T T C L O S -- Close the TTY, releasing any lock. */
-
-static int ttc_state = 0; /* ttclose() state */
-static char * ttc_nam[] = { "setup", "hangup", "reset", "close" };
-
-int
-ttclos(foo) int foo; { /* Arg req'd for signal() prototype */
- int xx, x = 0;
- extern int exithangup;
-
- debug(F101,"ttclos ttyfd","",ttyfd);
- debug(F101,"ttclos netconn","",netconn);
- debug(F101,"ttclos xlocal","",xlocal);
-#ifdef NOFDZERO
- debug(F100,"ttclos NOFDZERO","",0);
-#endif /* NOFDZERO */
-
-#ifdef COMMENT
-#ifdef TTLEBUF
- le_init(); /* No need for any of this */
-#endif /* TTLEBUF */
-#endif /* COMMENT */
-
- if (ttyfd < 0) /* Wasn't open. */
- return(0);
-
- if (ttfdflg) /* If we inherited ttyfd from */
- return(0); /* another process, don't close it. */
-
- tvtflg = 0; /* (some day get rid of this...) */
- gotsigs = 0;
-
-#ifdef IKSD
- if (inserver) {
-#ifdef TNCODE
- tn_push(); /* Place any waiting data into input*/
- tn_sopt(DO,TELOPT_LOGOUT); /* Send LOGOUT option before close */
- TELOPT_UNANSWERED_DO(TELOPT_LOGOUT) = 1;
- tn_reset(); /* The Reset Telnet Option table. */
-#endif /* TNCODE */
-#ifdef CK_SSL
- if (ssl_active_flag) {
- if (ssl_debug_flag)
- BIO_printf(bio_err,"calling SSL_shutdown(ssl)\n");
- SSL_shutdown(ssl_con);
- SSL_free(ssl_con);
- ssl_con = NULL;
- ssl_active_flag = 0;
- }
- if (tls_active_flag) {
- if (ssl_debug_flag)
- BIO_printf(bio_err,"calling SSL_shutdown(tls)\n");
- SSL_shutdown(tls_con);
- SSL_free(tls_con);
- tls_con = NULL;
- tls_active_flag = 0;
- }
-#endif /* CK_SSL */
- }
-#endif /* IKSD */
-#ifdef NETCMD
- if (ttpipe) { /* We've been using a pipe */
- /* ttpipe = 0; */
- if (ttpid > 0) {
- int wstat;
- int statusp;
- close(fdin); /* Close these. */
- close(fdout);
- fdin = fdout = -1;
- kill(ttpid,1); /* Kill fork with SIGHUP */
- while (1) {
- wstat = wait(&statusp);
- if (wstat == ttpid || wstat == -1)
- break;
- pexitstat = (statusp & 0xff) ? statusp : statusp >> 8;
- }
- ttpid = 0;
- }
- netconn = 0;
- wasclosed = 1;
- ttyfd = -1;
- return(0);
- }
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) {
-#ifndef NODOPTY
- end_pty();
-#endif /* NODOPTY */
- close(ttyfd);
- netconn = 0;
- wasclosed = 1;
- ttpty = 0;
- ttyfd = -1;
- return(0);
- }
-#endif /* NETPTY */
-
-#ifdef NETCONN
- if (netconn) { /* If it's a network connection. */
- debug(F100,"ttclos closing net","",0);
- netclos(); /* Let the network module close it. */
- netconn = 0; /* No more network connection. */
- debug(F101,"ttclos ttyfd after netclos","",ttyfd); /* Should be -1 */
- return(0);
- }
-#endif /* NETCONN */
-
- if (xlocal) { /* We're closing a SET LINE device */
-#ifdef FT21 /* Fortune 2.1-specific items ... */
- ioctl(ttyfd,TIOCHPCL, NULL);
-#endif /* FT21 */
-#ifdef ultrix /* Ultrix-specific items ... */
-#ifdef TIOCSINUSE
- /* Unset the INUSE flag that we set in ttopen() */
- ioctl(ttyfd, TIOCSINUSE, NULL);
-#endif /* TIOCSINUSE */
- ioctl(ttyfd, TIOCNMODEM, &x);
-#ifdef COMMENT
- /* What was this? */
- ioctl(ttyfd, TIOCNCAR, NULL);
-#endif /* COMMENT */
-#endif /* ultrix */
- }
-
- /* This is to prevent us from sticking in tthang() or close(). */
-
-#ifdef O_NDELAY
-#ifndef aegis
- if (ttyfd > 0) { /* But skip it on stdin. */
- debug(F100,"ttclos setting O_NDELAY","",0);
- x = fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL, 0)|O_NDELAY);
-#ifdef DEBUG
- if (deblog && x == -1) {
- perror("Warning - Can't set O_NDELAY");
- debug(F101,"ttclos fcntl failure to set O_NDELAY","",x);
- }
-#endif /* DEBUG */
- }
-#endif /* aegis */
-#endif /* O_NDELAY */
-
- x = 0;
- ttc_state = 0;
- if (xlocal
-#ifdef NOFDZERO
- || ttyfd > 0
-#endif /* NOFDZERO */
- ) {
- saval = signal(SIGALRM,xtimerh); /* Enable timer interrupt. */
- xx = alarm(8); /* Allow 8 seconds. */
- debug(F101,"ttclos alarm","",xx);
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) { /* Timer went off? */
- x = -1;
-#ifdef DEBUG
- debug(F111,"ttclos ALARM TRAP errno",ckitoa(ttc_state),errno);
- printf("ttclos() timeout: %s\n", ttc_nam[ttc_state]);
-#endif /* DEBUG */
- }
- /* Hang up the device (drop DTR) */
-
- errno = 0;
- debug(F111,"ttclos A",ckitoa(x),ttc_state);
- if (ttc_state < 1) {
- ttc_state = 1;
- debug(F101,"ttclos exithangup","",exithangup);
- if (exithangup) {
- alarm(8); /* Re-arm the timer */
- debug(F101,"ttclos calling tthang()","",x);
- x = tthang(); /* Hang up first, then... */
- debug(F101,"ttclos tthang()","",x);
- }
-#ifndef CK_NOHUPCL
-/*
- Oct 2006 - Leave DTR on if SET EXIT HANGUP OFF.
- Suggested by Soewono Effendi.
-*/
-#ifdef HUPCL
- else {
- ttold.c_cflag &= ~HUPCL; /* Let's see how this travels */
-#ifdef BSD44ORPOSIX
- tcsetattr(ttyfd,TCSANOW,&ttold);
-#else /* !BSD44ORPOSIX */
-#ifdef ATTSV
- ioctl(ttyfd,TCSETAW,&ttold);
-#else /* !ATTSV */
- stty(ttyfd,&ttold);
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
- }
-#endif /* HUPCL */
-#endif /* CK_NOHUPCL */
- }
- /* Put back device modes as we found them */
-
- errno = 0;
- debug(F111,"ttclos B",ckitoa(x),ttc_state);
- if (ttc_state < 2) {
- ttc_state = 2;
- /* Don't try to mess with tty modes if tthang failed() */
- /* since it probably won't work. */
- if (x > -1) {
- debug(F101,"ttclos calling ttres()","",x);
- signal(SIGALRM,xtimerh); /* Re-enable the alarm. */
- alarm(8); /* Re-arm the timer */
- x = ttres(); /* Reset device modes. */
- debug(F101,"ttclos ttres()","",x);
- alarm(0);
- }
- }
- /* Close the device */
-
- errno = 0;
- debug(F101,"ttclos C","",ttc_state);
- if (ttc_state < 3) {
- ttc_state = 3;
- errno = 0;
- debug(F101,"ttclos calling close","",x);
- signal(SIGALRM,xtimerh); /* Re-enable alarm. */
- alarm(8); /* Re-arm the timer */
- x = close(ttyfd); /* Close the device. */
- debug(F101,"ttclos close()","",x);
- if (x > -1)
- ttc_state = 3;
- }
- debug(F101,"ttclos D","",ttc_state);
- ttimoff(); /* Turn off timer. */
- if (x < 0) {
- printf("?WARNING - close failed: %s\n",ttnmsv);
-#ifdef DEBUG
- if (deblog) {
- printf("errno = %d\n", errno);
- debug(F101,"ttclos failed","",errno);
- }
-#endif /* DEBUG */
- }
- /* Unlock after closing but before any getty mumbo jumbo */
-
- debug(F100,"ttclos about to call ttunlck","",0);
- if (ttunlck()) /* Release uucp-style lock */
- fprintf(stderr,"Warning, problem releasing lock\r\n");
- }
-
-/* For bidirectional lines, restore getty if it was there before. */
-
-#ifdef ACUCNTRL /* 4.3BSD acucntrl() method. */
- if (xlocal) {
- debug(F100,"ttclos ACUCNTRL","",0);
- acucntrl("enable",ttnmsv); /* Enable getty on the device. */
- }
-#else
-#ifdef ATT7300 /* ATT UNIX PC (3B1, 7300) method. */
- if (xlocal) {
- debug(F100,"ttclos ATT7300 ongetty","",0);
- if (attmodem & DOGETY) /* Was getty(1m) running before us? */
- ongetty(ttnmsv); /* Yes, restart getty on tty line */
- attmodem &= ~DOGETY; /* No phone in use, getty restored */
- }
-#endif /* ATT7300 */
-#endif /* System-dependent getty-restoring methods */
-
-#ifdef sony_news
- km_ext = -1; /* Invalidate device's Kanji-mode */
-#endif /* sony_news */
-
- ttyfd = -1; /* Invalidate the file descriptor. */
- wasclosed = 1;
- debug(F100,"ttclos done","",0);
- return(0);
-}
-
-/* T T H A N G -- Hangup phone line or network connection. */
-/*
- Returns:
- 0 if it does nothing.
- 1 if it believes that it hung up successfully.
- -1 if it believes that the hangup attempt failed.
-*/
-
-#define HUPTIME 500 /* Milliseconds for hangup */
-
-#ifdef COMMENT
-/* The following didn't work but TIOCSDTR does work */
-#ifdef UNIXWARE
-/* Define HUP_POSIX to force non-POSIX builds to use the POSIX hangup method */
-#ifndef POSIX /* Such as Unixware 1.x, 2.x */
-#ifndef HUP_POSIX
-#define HUP_POSIX
-#endif /* HUP_POSIX */
-#endif /* POSIX */
-#endif /* UNIXWARE */
-#endif /* COMMENT */
-
-#ifndef USE_TIOCSDTR
-#ifdef __NetBSD__
-/* Because the POSIX method (set output speed to 0) doesn't work in NetBSD */
-#ifdef TIOCSDTR
-#ifdef TIOCCDTR
-#define USE_TIOCSDTR
-#endif /* TIOCCDTR */
-#endif /* TIOCSDTR */
-#endif /* __NetBSD__ */
-#endif /* USE_TIOCSDTR */
-
-#ifndef HUP_CLOSE_POSIX
-#ifdef OU8
-#define HUP_CLOSE_POSIX
-#else
-#ifdef CK_SCOV5
-#define HUP_CLOSE_POSIX
-#endif /* CK_SCOV5 */
-#endif /* OU8 */
-#endif /* HUP_CLOSE_POSIX */
-
-#ifdef NO_HUP_CLOSE_POSIX
-#ifdef HUP_CLOSE_POSIX
-#undef HUP_CLOSE_POSIX
-#endif /* HUP_CLOSE_POSIX */
-#endif /* NO_HUP_CLOSE_POSIX */
-
-int
-tthang() {
-#ifdef NOLOCAL
- return(0);
-#else
- int x = 0; /* Sometimes used as return code. */
-#ifndef POSIX
- int z; /* worker */
-#endif /* POSIX */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifdef SVORPOSIX /* AT&T, POSIX, HPUX declarations. */
- int spdsav; /* for saving speed */
-#ifdef HUP_POSIX
- int spdsavi;
-#else
-#ifdef BSD44ORPOSIX
- int spdsavi;
-#endif /* BSD44ORPOSIX */
-#endif /* HUP_POSIX */
-#ifdef HPUX
-/*
- Early versions of HP-UX omitted the mflag typedef. If you get complaints
- about it, just change it to long (or better still, unsigned long).
-*/
- mflag
- dtr_down = 00000000000,
- modem_rtn,
- modem_sav;
- char modem_state[64];
-#endif /* HPUX */
- int flags; /* fcntl flags */
- unsigned short ttc_save;
-#endif /* SVORPOSIX */
-
- if (ttyfd < 0) return(0); /* Don't do this if not open */
- if (xlocal < 1) return(0); /* Don't do this if not local */
-
-#ifdef NETCMD
- if (ttpipe)
- return((ttclos(0) < 0) ? -1 : 1);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty)
- return((ttclos(0) < 0) ? -1 : 1);
-#endif /* NETPTY */
-#ifdef NETCONN
- if (netconn) { /* Network connection. */
-#ifdef TN_COMPORT
- if (istncomport()) {
- int rc = tnc_set_dtr_state(0);
- if (rc >= 0) {
- msleep(HUPTIME);
- rc = tnc_set_dtr_state(1);
- }
- return(rc >= 0 ? 1 : -1);
- } else
-#endif /* TN_COMPORT */
- return((netclos() < 0) ? -1 : 1); /* Just close it. */
- }
-#endif /* NETCONN */
-
-/* From here down, we handle real tty devices. */
-#ifdef HUP_POSIX
-/*
- e.g. for Unixware 2, where we don't have a full POSIX build, we
- still have to use POSIX-style hangup. Thus the duplication of this
- and the next case, the only difference being we use a local termios
- struct here, since a different model is used elsewhere.
-
- NO LONGER USED as of C-Kermit 8.0 -- it turns out that this method,
- even though it compiles and executes without error, doesn't actually
- work (i.e. DTR does not drop), whereas the TIOCSDTR method works just fine,
-*/
- {
- struct termios ttcur;
- int x;
- debug(F100,"tthang HUP_POSIX style","",0);
- x = tcgetattr(ttyfd, &ttcur); /* Get current attributes */
- debug(F111,"tthang tcgetattr",ckitoa(errno),x);
- if (x < 0) return(-1);
- spdsav = cfgetospeed(&ttcur); /* Get current speed */
- debug(F111,"tthang cfgetospeed",ckitoa(errno),spdsav);
- spdsavi = cfgetispeed(&ttcur); /* Get current speed */
- debug(F111,"tthang cfgetispeed",ckitoa(errno),spdsavi);
- x = cfsetospeed(&ttcur,B0); /* Replace by 0 */
- debug(F111,"tthang cfsetospeed",ckitoa(errno),x);
- if (x < 0) return(-1);
- x = cfsetispeed(&ttcur,B0);
- debug(F111,"tthang cfsetispeed",ckitoa(errno),x);
- if (x < 0) return(-1);
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F111,"tthang tcsetattr B0",ckitoa(errno),x);
- if (x < 0) return(-1);
- msleep(HUPTIME); /* Sleep 0.5 sec */
- x = cfsetospeed(&ttcur,spdsav); /* Restore prev speed */
- if (x < 0) return(-1);
- debug(F111,"tthang cfsetospeed prev",ckitoa(errno),x);
- x = cfsetispeed(&ttcur,spdsavi);
- debug(F111,"tthang cfsetispeed prev",ckitoa(errno),x);
- if (x < 0) return(-1);
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F111,"tthang tcsetattr restore",ckitoa(errno),x);
- if (x < 0) return(-1);
- return(1);
- }
-#else
-#ifdef BSD44ORPOSIX
-#ifdef QNX
- {
- int x;
- x = tcdropline(ttyfd,500);
- debug(F101,"tthang QNX tcdropline","",x);
- ttcur.c_cflag |= CLOCAL;
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F101,"tthang QNX tcsetattr restore","",x);
- if (x < 0) {
- debug(F101,"tthang QNX tcsetattr restore errno","",errno);
- return(-1);
- }
- /* Fix flags - ensure O_NONBLOCK is off */
-
- errno = 0;
- debug(F101,"tthang QNX iniflags","",iniflags);
- if (fcntl(ttyfd, F_SETFL, iniflags) == -1) {
- debug(F101,"tthang QNX F_SETFL errno","",errno);
- return(-1);
- }
- return(x);
- }
-#else /* QNX */
- {
- int x;
-#ifdef USE_TIOCSDTR
- debug(F100,"tthang BSD44ORPOSIX USE_TIOCSDTR","",0);
- errno = 0;
- x = ioctl(ttyfd, TIOCCDTR, NULL);
- debug(F111,"tthang BSD44ORPOSIX ioctl TIOCCDTR",ckitoa(errno),x);
- if (x < 0) return(-1);
- msleep(HUPTIME); /* Sleep 0.5 sec */
- errno = 0;
- x = ioctl(ttyfd, TIOCSDTR, NULL);
- debug(F111,"tthang BSD44ORPOSIX ioctl TIOCSDTR",ckitoa(errno),x);
- if (x < 0) return(-1);
-#else /* USE_TIOCSDTR */
-
-#ifdef HUP_CLOSE_POSIX
-/*
- In OSR5 versions where TIOCSDTR is not defined (up to and including at
- least 5.0.6a) the POSIX APIs in the "#else" part below are available but
- don't work, and no other APIs are available that do work. In this case
- we have to drop DTR by brute force: close and reopen the port. This
- code actually works, but all the steps are crucial: setting CLOCAL, the
- O_NDELAY manipulations, etc.
-*/
- debug(F100,"tthang HUP_CLOSE_POSIX close/open","",0);
- debug(F101,"tthang HUP_CLOSE_POSIX O_NONBLOCK","",O_NONBLOCK);
- debug(F101,"tthang HUP_CLOSE_POSIX O_NDELAY","",O_NDELAY);
- errno = 0;
- x = tcgetattr(ttyfd, &ttcur); /* Get current attributes */
- debug(F101,"tthang HUP_CLOSE_POSIX tcgetattr","",x);
- if (x < 0) {
- debug(F101,"tthang HUP_CLOSE_POSIX tcgetattr errno","",errno);
- return(-1);
- }
- errno = 0;
-
- x = close(ttyfd); /* Close without releasing lock */
- if (x < 0) {
- debug(F101,"tthang HUP_CLOSE_POSIX close errno","",errno);
- return(-1);
- }
- errno = 0;
- x = msleep(500); /* Pause half a second */
- if (x < 0) { /* Or if that doesn't work, 1 sec */
- debug(F101,"tthang HUP_CLOSE_POSIX msleep errno","",errno);
- sleep(1);
- }
- errno = 0;
- ttyfd = priv_opn(ttnmsv, (O_RDWR|O_NDELAY)); /* Reopen the device */
- debug(F111,"tthang HUP_CLOSE_POSIX reopen",ttnmsv,ttyfd);
- if (ttyfd < 0) {
- debug(F101,"tthang HUP_CLOSE_POSIX reopen errno","",errno);
- return(-1);
- }
- debug(F101,"tthang HUP_CLOSE_POSIX re-ttopen ttyfd","",ttyfd);
-
- /* Restore previous attributes */
-
- errno = 0;
- tvtflg = 0;
- ttcur.c_cflag |= CLOCAL;
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F101,"tthang HUP_CLOSE_POSIX tcsetattr restore","",x);
- if (x < 0) {
- debug(F101,"tthang HUP_CLOSE_POSIX tcsetattr restore errno",
- "",errno);
- return(-1);
- }
- /* Fix flags - ensure O_NDELAY and O_NONBLOCK are off */
-
- errno = 0;
- if ((x = fcntl(ttyfd, F_GETFL, 0)) == -1) {
- debug(F101,"tthang HUP_CLOSE_POSIX F_GETFL errno","",errno);
- return(-1);
- }
- debug(F101,"tthang HUP_CLOSE_POSIX flags","",x);
- errno = 0;
- x &= ~(O_NONBLOCK|O_NDELAY);
- debug(F101,"tthang HUP_CLOSE_POSIX flags to set","",x);
- debug(F101,"tthang HUP_CLOSE_POSIX iniflags","",iniflags);
- if (fcntl(ttyfd, F_SETFL, x) == -1) {
- debug(F101,"tthang HUP_CLOSE_POSIX F_SETFL errno","",errno);
- return(-1);
- }
-#ifdef DEBUG
- if (deblog) {
- if ((x = fcntl(ttyfd, F_GETFL, 0)) > -1) {
- debug(F101,"tthang HUP_CLOSE_POSIX flags","",x);
- debug(F101,"tthang HUP_CLOSE_POSIX flags & O_NONBLOCK",
- "",x&O_NONBLOCK);
- debug(F101,"tthang HUP_CLOSE_POSIX flags & O_NDELAY",
- "",x&O_NDELAY);
- }
- }
-#endif /* DEBUG */
-
-#else /* HUP_CLOSE_POSIX */
-
- /* General BSD44ORPOSIX case (Linux, BSDI, FreeBSD, etc) */
-
- debug(F100,"tthang BSD44ORPOSIX B0","",0);
- x = tcgetattr(ttyfd, &ttcur); /* Get current attributes */
- debug(F111,"tthang BSD44ORPOSIX tcgetattr",ckitoa(errno),x);
- if (x < 0) return(-1);
- spdsav = cfgetospeed(&ttcur); /* Get current speed */
- debug(F111,"tthang BSD44ORPOSIX cfgetospeed",ckitoa(errno),spdsav);
- spdsavi = cfgetispeed(&ttcur); /* Get current speed */
- debug(F111,"tthang BSD44ORPOSIX cfgetispeed",ckitoa(errno),spdsavi);
- x = cfsetospeed(&ttcur,B0); /* Replace by 0 */
- debug(F111,"tthang BSD44ORPOSIX cfsetospeed",ckitoa(errno),x);
- if (x < 0) return(-1);
- x = cfsetispeed(&ttcur,B0);
- debug(F111,"tthang BSD44ORPOSIX cfsetispeed",ckitoa(errno),x);
- if (x < 0) return(-1);
- /* This gets EINVAL on NetBSD 1.4.1 because of B0... */
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F111,"tthang BSD44ORPOSIX tcsetattr B0",ckitoa(errno),x);
- if (x < 0) return(-1);
- msleep(HUPTIME); /* Sleep 0.5 sec */
- debug(F101,"tthang BSD44ORPOSIX restore output speed","",spdsav);
- x = cfsetospeed(&ttcur,spdsav); /* Restore prev speed */
- debug(F111,"tthang BSD44ORPOSIX cfsetospeed prev",ckitoa(errno),x);
- if (x < 0) return(-1);
- debug(F101,"tthang BSD44ORPOSIX restore input speed","",spdsavi);
- x = cfsetispeed(&ttcur,spdsavi);
- debug(F111,"tthang BSD44ORPOSIX cfsetispeed prev",ckitoa(errno),x);
- if (x < 0) return(-1);
- ttcur.c_cflag |= CLOCAL; /* Don't expect CD after hangup */
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F111,"tthang BSD44ORPOSIX tcsetattr restore",ckitoa(errno),x);
- if (x < 0) return(-1);
-
-#endif /* HUP_CLOSE_POSIX */
-#endif /* USE_TIOCSDTR */
-
- return(1);
- }
-
-#endif /* QNX */
-#else /* BSD44ORPOSIX */
-
-#ifdef aegis /* Apollo Aegis */
- sio_$control((short)ttyfd, sio_$dtr, false, st); /* DTR down */
- msleep(HUPTIME); /* pause */
- sio_$control((short)ttyfd, sio_$dtr, true, st); /* DTR up */
- return(1);
-#endif /* aegis */
-
-#ifdef ANYBSD /* Any BSD version. */
-#ifdef TIOCCDTR /* Except those that don't have this */
- debug(F100,"tthang BSD style","",0);
- if (ioctl(ttyfd,TIOCCDTR,0) < 0) { /* Clear DTR. */
- debug(F101,"tthang TIOCCDTR fails","",errno);
- return(-1);
- }
- msleep(HUPTIME); /* For about 1/2 sec */
- errno = 0;
- x = ioctl(ttyfd,TIOCSDTR,0); /* Restore DTR */
- if (x < 0) {
- /*
- For some reason, this tends to fail with "no such device or address"
- but the operation still works, probably because of the close/open
- later on. So let's not scare the user unnecessarily here.
- */
- debug(F101,"tthang TIOCSDTR errno","",errno); /* Log the error */
- x = 1; /* Pretend we succeeded */
- } else if (x == 0) x = 1; /* Success */
-#ifdef COMMENT
-#ifdef FT21
- ioctl(ttyfd, TIOCSAVEMODES, 0);
- ioctl(ttyfd, TIOCHPCL, 0);
- close(ttyfd); /* Yes, must do this twice */
- if ((ttyfd = open(ttnmsv,2)) < 0) /* on Fortune computers... */
- return(-1); /* (but why?) */
- else x = 1;
-#endif /* FT21 */
-#endif /* COMMENT */
-#endif /* TIOCCDTR */
- close(do_open(ttnmsv)); /* Clear i/o error condition */
- errno = 0;
-#ifdef COMMENT
-/* This is definitely dangerous. Why was it here? */
- z = ttvt(ttspeed,ttflow); /* Restore modes. */
- debug(F101,"tthang ttvt returns","",z);
- return(z < 0 ? -1 : 1);
-#else
- return(x);
-#endif /* COMMENT */
-#endif /* ANYBSD */
-
-#ifdef ATTSV
-/* AT&T UNIX section, includes HP-UX and generic AT&T System III/V... */
-
-#ifdef HPUX
-/* Hewlett Packard allows explicit manipulation of modem signals. */
-
-#ifdef COMMENT
-/* Old way... */
- debug(F100,"tthang HP-UX style","",0);
- if (ioctl(ttyfd,MCSETAF,&dtr_down) < 0) /* lower DTR */
- return(-1); /* oops, can't. */
- msleep(HUPTIME); /* Pause half a second. */
- x = 1; /* Set return code */
- if (ioctl(ttyfd,MCGETA,&modem_rtn) > -1) { /* Get line status. */
- if ((modem_rtn & MDCD) != 0) /* Check if CD is low. */
- x = -1; /* CD didn't drop, fail. */
- } else x = -1;
-
- /* Even if above calls fail, RTS & DTR should be turned back on. */
- modem_rtn = MRTS | MDTR;
- if (ioctl(ttyfd,MCSETAF,&modem_rtn) < 0) x = -1;
- return(x);
-#else
-/* New way, from Hellmuth Michaelis */
- debug(F100,"tthang HP-UX style, HPUXDEBUG","",0);
- if (ioctl(ttyfd,MCGETA,&modem_rtn) == -1) { /* Get current status. */
- debug(F100,"tthang HP-UX: can't get modem lines, NO HANGUP!","",0);
- return(-1);
- }
- sprintf(modem_state,"%#lx",modem_rtn);
- debug(F110,"tthang HP-UX: modem lines = ",modem_state,0);
- modem_sav = modem_rtn; /* Save current modem signals */
- modem_rtn &= ~MDTR; /* Turn DTR bit off */
- sprintf(modem_state,"%#lx",modem_rtn);
- debug(F110,"tthang HP-UX: DTR down = ",modem_state,0);
- if (ioctl(ttyfd,MCSETAF,&modem_rtn) < 0) { /* lower DTR */
- debug(F100,"tthang HP-UX: can't lower DTR!","",0);
- return(-1); /* oops, can't. */
- }
- msleep(HUPTIME); /* Pause half a second. */
- x = 1; /* Set return code */
- if (ioctl(ttyfd,MCGETA,&modem_rtn) > -1) { /* Get line status. */
- sprintf(modem_state,"%#lx",modem_rtn);
- debug(F110,"tthang HP-UX: modem lines got = ",modem_state,0);
- if ((modem_rtn & MDCD) != 0) { /* Check if CD is low. */
- debug(F100,"tthang HP-UX: DCD not down","",0);
- x = -1; /* CD didn't drop, fail. */
- } else {
- debug(F100,"tthang HP-UX: DCD down","",0);
- }
- } else {
- x = -1;
- debug(F100,"tthang HP-UX: can't get DCD status !","",0);
- }
-
- /* Even if above calls fail, DTR should be turned back on. */
-
- modem_sav |= MDTR;
- if (ioctl(ttyfd,MCSETAF,&modem_sav) < 0) {
- x = -1;
- debug(F100,"tthang HP-UX: can't set saved state","",0);
- } else {
- sprintf(modem_state,"%#lx",modem_sav);
- debug(F110,"tthang HP-UX: final modem lines = ",modem_state,0);
- }
- return(x);
-#endif /* COMMENT */
-
-#else /* AT&T but not HP-UX */
-
-/* SVID for AT&T System V R3 defines ioctl's for handling modem signals. */
-/* It is not known how many, if any, systems actually implement them, */
-/* so we include them here in ifdef's. */
-
-/*
- Unixware has the TIOCMxxx symbols defined, but calling ioctl() with them
- gives error 22 (invalid argument).
-*/
-#ifndef _IBMR2
-/*
- No modem-signal twiddling for IBM RT PC or RS/6000.
- In AIX 3.1 and earlier, the ioctl() call is broken.
- This code could be activated for AIX 3.1 with PTF 2006 or later
- (e.g. AIX 3.2), but close/open does the job too, so why bother.
-*/
-#ifdef TIOCMBIS /* Bit Set */
-#ifdef TIOCMBIC /* Bit Clear */
-#ifdef TIOCM_DTR /* DTR */
-
-/* Clear DTR, sleep 300 msec, turn it back on. */
-/* If any of the ioctl's return failure, go on to the next section. */
-
- z = TIOCM_DTR; /* Code for DTR. */
-#ifdef COMMENT
-/*
- This was the cause of the troubles with the Solaris Port Monitor.
- The problem is: RTS never comes back on. Moral: Don't do it!
- (But why doesn't it come back on? See the TIOCMBIS call...)
-*/
-#ifdef TIOCM_RTS /* Lower RTS too if symbol is known. */
- z |= TIOCM_RTS;
-#endif /* TIOCM_RTS */
-#endif /* COMMENT */
-
- debug(F101,"tthang TIOCM signal mask","",z);
- if (ioctl(ttyfd,TIOCMBIC,&z) > -1) { /* Try to lower DTR. */
- debug(F100,"tthang TIOCMBIC ok","",0);
- msleep(HUPTIME); /* Pause half a second. */
- if (ioctl(ttyfd,TIOCMBIS,&z) > -1) { /* Try to turn it back on. */
- debug(F100,"tthang TIOCMBIS ok","",0);
-#ifndef CLSOPN
- return(1); /* Success, done. */
-#endif /* CLSOPN */
- } else { /* Couldn't raise, continue. */
- debug(F101,"tthang TIOCMBIS errno","",errno);
- }
- } else { /* Couldn't lower, continue. */
- debug(F101,"tthang TIOCMBIC errno","",errno);
- }
-#endif /* TIOCM_DTR */
-#endif /* TIOCMBIC */
-#endif /* TIOCMBIS */
-#endif /* _IBMR2 */
-
-/*
- General AT&T UNIX case, not HPUX. The following code is highly suspect. No
- two AT&T-based systems seem to do this the same way. The object is simply
- to turn off DTR and then turn it back on. SVID says the universal method
- for turning off DTR is to set the speed to zero, and this does seem to do
- the trick in all cases. But neither SVID nor any known man pages say how to
- turn DTR back on again. Some variants, like most Xenix implementations,
- raise DTR again when the speed is restored to a nonzero value. Others
- require the device to be closed and opened again, but this is risky because
- getty could seize the device during the instant it is closed.
-*/
-
-/* Return code for ioctl failures... */
-#ifdef ATT6300
- x = 1; /* ATT6300 doesn't want to fail... */
-#else
- x = -1;
-#endif /* ATT6300 */
-
- debug(F100,"tthang get settings","",0);
- if (ioctl(ttyfd,TCGETA,&ttcur) < 0) /* Get current settings. */
- return(x); /* Fail if this doesn't work. */
- if ((flags = fcntl(ttyfd,F_GETFL,0)) < 0) /* Get device flags. */
- return(x);
- ttc_save = ttcur.c_cflag; /* Remember current speed. */
- spdsav = ttc_save & CBAUD;
- debug(F101,"tthang speed","",spdsav);
-
-#ifdef O_NDELAY
- debug(F100,"tthang turning O_NDELAY on","",0);
- fcntl(ttyfd, F_SETFL, flags | O_NDELAY); /* Activate O_NDELAY */
-#endif /* O_NDELAY */
-
-#ifdef ATT7300 /* This is the way it is SUPPOSED to work */
- ttcur.c_cflag &= ~CBAUD; /* Change the speed to zero. */
-#else
-#ifdef RTAIX
- ttcur.c_cflag &= ~CBAUD; /* Change the speed to zero. */
-#else /* This way really works but may be dangerous */
-#ifdef u3b2
- ttcur.c_cflag = ~(CBAUD|CLOCAL); /* Special for AT&T 3B2s */
- /* (CLOCAL must be OFF) */
-#else
-#ifdef SCO3R2 /* SCO UNIX 3.2 */
-/*
- This is complete nonsense, but an SCO user claimed this change made
- hanging up work. Comments from other SCO UNIX 3.2 users would be
- appreciated.
-*/
- ttcur.c_cflag = CBAUD|B0;
-#else
-#ifdef AIXRS /* AIX on RS/6000 */
-/*
- Can't set speed to zero on AIX 3.1 on RS/6000 64-port adapter,
- even though you can do it on the built-in port and the 8- and 16-port
- adapters. (Untested on 128-port adapter.)
-*/
- ttcur.c_cflag = CLOCAL|HUPCL|spdsav; /* Speed 0 causes EINVAL */
-#else /* None of the above */
-/*
- Set everything, including the speed, to zero, except for the CLOCAL
- and HUPCL bits.
-*/
- ttcur.c_cflag = CLOCAL|HUPCL;
-#endif /* AIXRS */
-#endif /* SCO3R2 */
-#endif /* u3b2 */
-#endif /* RTAIX */
-#endif /* ATT7300 */
-
-#ifdef COMMENT
- /* and if none of those work, try one of these... */
- ttcur.c_cflag = 0;
- ttcur.c_cflag = CLOCAL;
- ttcur.c_cflag &= ~(CBAUD|HUPCL);
- ttcur.c_cflag &= ~(CBAUD|CREAD);
- ttcur.c_cflag &= ~(CBAUD|CREAD|HUPCL);
- /* or other combinations */
-#endif /* COMMENT */
-
-#ifdef TCXONC
- debug(F100,"tthang TCXONC","",0);
- if (ioctl(ttyfd, TCXONC, 1) < 0) {
- debug(F101,"tthang TCXONC failed","",errno);
- }
-#endif /* TCXONC */
-
-#ifdef TIOCSTART
- debug(F100,"tthang TIOCSTART","",0);
- if (ioctl(ttyfd, TIOCSTART, 0) < 0) {
- debug(F101,"tthang TIOCSTART failed","",errno);
- }
-#endif /* TIOCSTART */
-
- if (ioctl(ttyfd,TCSETAF,&ttcur) < 0) { /* Fail if we can't. */
- debug(F101,"tthang TCSETAF failed","",errno);
- fcntl(ttyfd, F_SETFL, flags); /* Restore flags */
- return(-1); /* before returning. */
- }
- msleep(300); /* Give modem time to notice. */
-
-#ifndef NOCOTFMC
-
-/* Now, even though it doesn't say this in SVID or any man page, we have */
-/* to close and reopen the device. This is not necessary for all systems, */
-/* but it's impossible to predict which ones need it and which ones don't. */
-
-#ifdef ATT7300
-/*
- Special handling for ATT 7300 UNIX PC and 3B1, which have "phone"
- related ioctl's for their internal modems. attmodem has getty status and
- modem-in-use bit. Reportedly the ATT7300/3B1 PIOCDISC call is necessary,
- but also ruins the file descriptor, and no other phone(7) ioctl call can fix
- it. Whatever it does, it seems to escape detection with PIOCGETA and TCGETA.
- The only way to undo the damage is to close the fd and then reopen it.
-*/
- if (attmodem & ISMODEM) {
- debug(F100,"tthang attmodem close/open","",0);
- ioctl(ttyfd,PIOCUNHOLD,&dialer); /* Return call to handset. */
- ioctl(ttyfd,PIOCDISC,&dialer); /* Disconnect phone. */
- close(ttyfd); /* Close and reopen the fd. */
- ttyfd = priv_opn(ttnmsv, O_RDWR | O_NDELAY);
- attmodem &= ~ISMODEM; /* Phone no longer in use. */
- }
-#else /* !ATT7300 */
-/* It seems we have to close and open the device for other AT&T systems */
-/* too, and this is the place to do it. The following code does the */
-/* famous close(open(...)) magic by default. If that doesn't work for you, */
-/* then try uncommenting the following statement or putting -DCLSOPN in */
-/* the makefile CFLAGS. */
-
-/* #define CLSOPN */
-
-#ifndef SCO32 /* Not needed by, and harmful to, SCO UNIX 3.2 / Xenix 2.3 */
-
-#ifdef O_NDELAY
-#define OPENFLGS O_RDWR | O_NDELAY
-#else
-#define OPENFLGS O_RDWR
-#endif
-
-#ifndef CLSOPN
-/* This method is used by default, i.e. unless CLSOPN is defined. */
-/* It is thought to be safer because there is no window where getty */
-/* can seize control of the device. The drawback is that it might not work. */
-
- debug(F101,"tthang close(open()), OPENFLGS","",OPENFLGS);
- close(priv_opn(ttnmsv, OPENFLGS));
-
-#else
-/* This method is used if you #define CLSOPN. It is more likely to work */
-/* than the previous method, but it's also more dangerous. */
-
- debug(F101,"tthang close/open, OPENFLGS","",OPENFLGS);
- close(ttyfd);
- msleep(10);
- ttyfd = priv_opn(ttnmsv, OPENFLGS); /* Open it again */
-#endif /* CLSOPN */
-#undef OPENFLGS
-
-#endif /* SCO32 */
-#endif /* ATT7300 */
-
-#endif /* NOCOTFMC */
-
-/* Now put all flags & modes back the way we found them. */
-/* (Does the order of ioctl & fcntl matter ? ) */
-
- debug(F100,"tthang restore settings","",0);
- ttcur.c_cflag = ttc_save; /* Get old speed back. */
- if (ioctl(ttyfd,TCSETAF,&ttcur) < 0) /* ioctl parameters. */
- return(-1);
-#ifdef O_NDELAY
-/*
- This is required for IBM RT and RS/6000, probably helps elsewhere too (?).
- After closing a modem line, the modem will probably not be asserting
- carrier any more, so we should not require carrier any more. If this
- causes trouble on non-IBM UNIXes, change the #ifdef to use _IBMR2 rather
- than O_NDELAY.
-*/
- flags &= ~O_NDELAY; /* Don't require carrier on reopen */
-#endif /* O_NDELAY */
- if (fcntl(ttyfd,F_SETFL,flags) < 0) /* fcntl parameters */
- return(-1);
-
- return(1);
-#endif /* not HPUX */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-#endif /* HUP_POSIX */
-#endif /* NOLOCAL */
-}
-
-/*
- Major change in 5A(174). We used to use LPASS8, if it was defined, to
- allow 8-bit data and Xon/Xoff flow control at the same time. But this
- LPASS8 business seems to have been causing trouble for everybody but me!
- For example, Annex terminal servers, commonly used with Encore computers,
- do not support LPASS8 even though the Encore itself does. Ditto for many
- other terminal servers, TELNET connections, rlogin connections, etc etc.
- Now, reportedly, even vanilla 4.3 BSD systems can't do this right on their
- serial lines, even though LPASS8 is a feature of 4.3BSD. So let's turn it
- off for everybody. That means we goes back to using raw mode, with no
- flow control. Phooey.
-
- NOTE: This must be done before the first reference to LPASS8 in this file,
- and after the last #include statment.
-*/
-#ifdef LPASS8
-#undef LPASS8
-#endif /* LPASS8 */
-
-/* T T R E S -- Restore terminal to "normal" mode. */
-
-/* ske@pkmab.se: There are two choices for what this function should do.
- * (1) Restore the tty to current "normal" mode, with carrier treatment
- * according to ttcarr, to be used after every kermit command. (2) Restore
- * the tty to the state it was in before kermit opened it. These choices
- * conflict, since ttold can't hold both choices of tty parameters. ttres()
- * is currently being called as in choice (1), but ttold basically holds
- * the initial parameters, as in (2), and the description at the beginning
- * of this file says (2).
- *
- * I don't think restoring tty parameters after all kermit commands makes
- * much of a difference. Restoring them upon exit from kermit may be of
- * some use in some cases (when the line is not restored automatically on
- * close, by the operating system).
- *
- * I can't choose which one it should be, so I haven't changed it. It
- * probably works as it is, too. It would probably even work even with
- * ttres() entirely deleted...
- *
- * (from fdc: Actually, this function operates in remote mode too, so
- * it restores the console (command) terminal to whatever mode it was
- * in before packet operations began, so that commands work right again.)
- */
-int
-ttres() { /* Restore the tty to normal. */
- int x;
-
- if (ttyfd < 0) return(-1); /* Not open. */
-
- if (ttfdflg) return(0); /* Don't mess with terminal modes if */
- /* we got ttyfd from another process */
-#ifdef NETCONN
- if (netconn) { /* Network connection */
- tvtflg = 0;
-#ifdef TCPSOCKET
-#ifdef TCP_NODELAY
- {
- extern int tcp_nodelay; /* Just put this back if necessary */
- if (ttnet == NET_TCPB) {
- if (nodelay_sav > -1) {
- no_delay(ttyfd,nodelay_sav);
- nodelay_sav = -1;
- }
- }
- }
-#endif /* TCP_NODELAY */
-#ifdef TN_COMPORT
- if (istncomport()) {
- int rc = -1;
- if ((rc = tnsetflow(ttflow)) < 0)
- return(rc);
- if (ttspeed <= 0)
- ttspeed = tnc_get_baud();
- else if ((rc = tnc_set_baud(ttspeed)) < 0)
- return(rc);
- tnc_set_datasize(8);
- tnc_set_stopsize(stopbits);
-
-#ifdef HWPARITY
- if (hwparity) {
- switch (hwparity) {
- case 'e': /* Even */
- debug(F100,"ttres 8 bits + even parity","",0);
- tnc_set_parity(3);
- break;
- case 'o': /* Odd */
- debug(F100,"ttres 8 bits + odd parity","",0);
- tnc_set_parity(2);
- break;
- case 'm': /* Mark */
- debug(F100,"ttres 8 bits + invalid parity: mark","",0);
- tnc_set_parity(4);
- break;
- case 's': /* Space */
- debug(F100,"ttres 8 bits + invalid parity: space","",0);
- tnc_set_parity(5);
- break;
- }
- } else
-#endif /* HWPARITY */
- {
- tnc_set_parity(1); /* None */
- }
- tvtflg = 0;
- return(0);
- }
-#endif /* TN_COMPORT */
-#endif /* TCPSOCKET */
- return(0);
- }
-#endif /* NETCONN */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-
-/* Real terminal device, so restore its original modes */
-
-#ifdef BSD44ORPOSIX /* For POSIX like this */
- debug(F100,"ttres BSD44ORPOSIX","",0);
- x = tcsetattr(ttyfd,TCSADRAIN,&ttold);
-#else /* For all others... */
-#ifdef ATTSV /* For AT&T versions... */
- debug(F100,"ttres ATTSV","",0);
- x = ioctl(ttyfd,TCSETAW,&ttold); /* Restore tty modes this way. */
-#else
-/* Here we restore the modes for BSD */
-
-#ifdef LPASS8 /* Undo "pass8" if it were done */
- if (lmodef) {
- if (ioctl(ttyfd,TIOCLSET,&lmode) < 0)
- debug(F100,"ttres TIOCLSET failed","",0);
- else
- debug(F100,"ttres TIOCLSET ok","",0);
- }
-#endif /* LPASS8 */
-
-#ifdef CK_DTRCTS /* Undo hardware flow if it were done */
- if (lmodef) {
- if (ioctl(ttyfd,TIOCLSET,&lmode) < 0)
- debug(F100,"ttres TIOCLSET failed","",0);
- else
- debug(F100,"ttres TIOCLSET ok","",0);
- }
-#endif /* CK_DTRCTS */
-
-#ifdef TIOCGETC /* Put back special characters */
- if (tcharf && (xlocal == 0)) {
- if (ioctl(ttyfd,TIOCSETC,&tchold) < 0)
- debug(F100,"ttres TIOCSETC failed","",0);
- else
- debug(F100,"ttres TIOCSETC ok","",0);
- }
-#endif /* TIOCGETC */
-
-#ifdef TIOCGLTC /* Put back local special characters */
- if (ltcharf && (xlocal == 0)) {
- if (ioctl(ttyfd,TIOCSLTC,<chold) < 0)
- debug(F100,"ttres TIOCSLTC failed","",0);
- else
- debug(F100,"ttres TIOCSLTC ok","",0);
- }
-#endif /* TIOCGLTC */
-
-#ifdef BELLV10
- debug(F100,"ttres BELLV10","",0);
- x = ioctl(ttyfd,TIOCSETP,&ttold); /* Restore both structs */
- x = ioctl(ttyfd,TIOCSDEV,&tdold);
-#else
- debug(F100,"ttres stty","",0);
- x = stty(ttyfd,&ttold); /* Restore tty modes the old way. */
-#endif /* BELLV10 */
-
- if (!xlocal)
- msleep(100); /* This replaces sleep(1)... */
- /* Put back sleep(1) if tty is */
- /* messed up after close. */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-
- debug(F101,"ttres result","",x);
-#ifndef QNX
- if (x < 0) debug(F101,"ttres errno","",errno);
-#endif /* QNX */
-
-#ifdef AIXRS
-#ifndef AIX41
- x = ioctl(ttyfd, ttld & 1 ? TXADDCD : TXDELCD, "rts");
- debug(F101,"ttres AIX line discipline rts restore","",x);
-#endif /* AIX41 */
-#endif /* AIXRS */
-
-#ifdef BSD41
- if (ttld > -1) { /* Put back line discipline */
- x = ioctl(ttyfd, TIOCSETD, &ttld);
- debug(F101,"ttres BSD41 line discipline restore","",x);
- if (x < 0) debug(F101,"...ioctl errno","",errno);
- ttld = -1;
- }
-#endif /* BSD41 */
-
-#ifdef sony_news
- x = xlocal ? km_ext : km_con; /* Restore Kanji mode. */
- if (x != -1) { /* Make sure we know original modes. */
- if (ioctl(ttyfd,TIOCKSET, &x) < 0) {
- perror("ttres can't set Kanji mode");
- debug(F101,"ttres error setting Kanji mode","",x);
- return(-1);
- }
- }
- debug(F100,"ttres set Kanji mode ok","",0);
-#endif /* sony_news */
-
- tvtflg = 0; /* Invalidate terminal mode settings */
- debug(F101,"ttres return code","",x);
- return(x);
-}
-
-#ifndef NOUUCP
-
-/* T T C H K P I D -- Check lockfile pid */
-/*
- Read pid from lockfile named f, check that it's still valid.
- If so, return 1.
- On failure to read pid, return 1.
- Otherwise, try to delete lockfile f and return 0 if successful, else 1.
-*/
-static int
-ttchkpid(f) char *f; {
- int pid, mypid, x;
- pid = ttrpid(f); /* Read pid from file. */
- if (pid > -1) { /* If we were able to read the pid.. */
- debug(F101,"ttchkpid lock pid","",pid);
- errno = 0; /* See if process still exists. */
- mypid = (int)getpid(); /* Get my own pid. */
- debug(F101,"ttchkpid my pid","",mypid);
- if (pid == mypid) { /* It's me! */
- x = -1; /* So I can delete it */
- errno = ESRCH; /* pretend it's invalid */
- } else { /* It's not me */
- x = kill((PID_T)pid, 0); /* See if it's a live process */
- debug(F101,"ttchkpid kill errno","",errno);
- }
- debug(F101,"ttchkpid pid test","",x);
- if (x < 0 && errno == ESRCH) { /* pid is invalid */
- debug(F111,"removing stale lock",f,pid);
- if (!backgrd)
- printf("Removing stale lock %s (pid %d terminated)\n", f, pid);
- priv_on();
- x = unlink(f); /* Remove the lockfile. */
- priv_off();
- debug(F111,"ttchkpid unlink",f,x);
- if (x > -1)
- return(0); /* Device is not locked after all */
- else if (!backgrd)
- perror(f);
- }
- return(1);
- }
- return(1); /* Failure to read pid */
-}
-
-#ifdef HPUX
-
-/* Aliases (different drivers) for HP-UX dialout devices: */
-
-static char *devprefix[] = { "tty", "ttyd", "cul", "cua", "cuad", "culd", "" };
-static int ttydexists = 0;
-
-#endif /* HPUX */
-
-/* T T R P I D -- Read pid from lockfile "name" */
-
-static int
-ttrpid(name) char *name; {
- long len;
- int x, fd, pid;
- short spid;
- char buf[32];
-
- debug(F110,"ttrpid",name,0);
- if (!name) return(-1);
- if (!*name) return(-1);
- priv_on();
- len = zchki(name); /* Get file length */
- priv_off();
- debug(F101,"ttrpid zchki","",len);
- if (len < 0)
- return(-1);
- if (len > 31)
- return(-1);
- priv_on();
- fd = open(name,O_RDONLY); /* Try to open lockfile. */
- priv_off();
- debug(F101,"ttrpid fd","",fd);
- if (fd <= 0)
- return(-1);
-/*
- Here we try to be flexible and allow for all different binary and string
- formats at runtime, rather than a specific format for each configuration
- hardwired at compile time.
-*/
- pid = -1;
-#ifndef COHERENT
-/*
- COHERENT uses a string PID but without leading spaces or 0's, so there is
- no way to tell from the file's length whether it contains a string or binary
- pid. So for COHERENT only, we only allow string pids. For all others, we
- decide based on the size of the lockfile.
-*/
- if (len > 4) { /* If file > 4 bytes it's a string */
-#endif /* COHERENT */
- x = read(fd,buf,(int)len);
- debug(F111,"ttrpid string read",buf,x);
- if (x < 0) {
- pid = -1;
- } else {
- buf[31] = '\0';
- x = sscanf(buf,"%d",&pid); /* Get the integer pid from it. */
- }
-#ifndef COHERENT
- } else if (len == 4) { /* 4 bytes so binary */
- x = read(fd, (char *)&pid, 4); /* Read the bytes into an int */
- debug(F101,"ttrpid integer read","",x);
- if (x < 4)
- pid = -1;
- } else if (len == 2) { /* 2 bytes binary */
- x = read(fd, (char *)&spid, 2); /* Read the bytes into a short */
- debug(F101,"ttrpid short read","",x);
- if (x < 2)
- pid = -1;
- else
- pid = spid;
- } else
- pid = -1;
-#endif /* COHERENT */
- close(fd); /* Close the lockfile */
- debug(F101,"ttrpid pid","",pid);
- return(pid);
-}
-#endif /* NOUUCP */
-
-/* T T L O C K */
-
-/*
- This function attempts to coordinate use of the communication device with
- other copies of Kermit and any other program that follows the UUCP
- device-locking conventions, which, unfortunately, vary among different UNIX
- implementations. The idea is to look for a file of a certain name, the
- "lockfile", in a certain directory. If such a file is found, then the line
- is presumed to be in use, and Kermit should not use it. If no such file is
- found, Kermit attempts to create one so that other programs will not use the
- same line at the same time. Because the lockfile and/or the directory it's
- in might lack write permission for the person running Kermit, Kermit could
- find itself running setuid to uucp or other user that does have the
- necessary permissions. At startup, Kermit has changed its effective uid to
- the user's real uid, and so ttlock() must switch back to the original
- effective uid in order to create the lockfile, and then back again to the
- real uid to prevent unauthorized access to other directories or files owned
- by the user the program is setuid to.
-
- Totally rewritten for C-Kermit 5A to eliminate windows of vulnerability,
- based on suggestions from Warren Tucker. Call with pointer to name of
- tty device. Returns:
-
- 0 on success
- -1 on failure
-
- Note: Once privileges are turned on using priv_on(), it is essential that
- they are turned off again before this function returns.
-*/
-#ifdef SVR4 /* Lockfile uses device numbers. */
-/*
- Although I can't find this in writing anywhere (e.g. in SVID for SVR4),
- it is the behavior of the "reference version" of SVR4, i.e. the Intel
- port from UNIX Systems Laboratories, then called Univel UnixWare,
- then called Novell UnixWare, then called SCO Unixware, then called Caldera
- Open UNIX... It also makes much more sense than device-name-based lockfiles
- since there can be multiple names for the same device, symlinks, etc.
-*/
-#ifndef NOLFDEVNO
-#ifndef LFDEVNO /* Define this for SVR4 */
-#ifndef AIXRS /* But not for RS/6000 AIX 3.2, etc. */
-#ifndef BSD44 /* If anybody else needs it... */
-#ifndef __386BSD__
-#ifndef __FreeBSD__
-#ifndef HPUX10
-#ifndef IRIX51 /* SGI IRIX 5.1 or later */
-#ifndef CK_SCOV5 /* SCO Open Server 5.0 */
-#define LFDEVNO
-#endif /* CK_SCOV5 */
-#endif /* IRIX51 */
-#endif /* HPUX10 */
-#endif /* __FreeBSD__ */
-#endif /* __386BSD__ */
-#endif /* BSD44 */
-#endif /* AIXRS */
-#endif /* LFDEVNO */ /* ... define it here or on CC */
-#endif /* NOLFDEVNO */
-#endif /* SVR4 */ /* command line. */
-
-#ifdef COHERENT
-#define LFDEVNO
-#endif /* COHERENT */
-
-/*
- For platforms where the lockfile name is made from device/major/minor
- device number, as in SVR4. Which, if we must have lockfiles at all, is
- by far the best format, since it eliminates all the confusion that stems
- from multiple names (or drivers) for the same port, not to mention
- symlinks. It might even be a good idea to start using this form even
- on platforms where it's not supported, alongside the normal forms for those
- platforms, in order to get people used to it...
-*/
-#ifdef LFDEVNO
-#ifndef major /* If we didn't find it */
-#ifdef SVR4 /* then for Sys V R4 */
-#include <sys/mkdev.h> /* look here */
-#else /* or for SunOS versions */
-#ifdef SUNOS4 /* ... */
-#include <sys/sysmacros.h> /* look here */
-#else /* Otherwise take a chance: */
-#define major(dev) ( (int) ( ((unsigned)(dev) >> 8) & 0xff))
-#define minor(dev) ( (int) ( (dev) & 0xff))
-#endif /* SUNOS4 */
-#endif /* SVR4 */
-#endif /* major */
-#endif /* LFDEVNO */
-
-/* No advisory locks if F_TLOCK and F_ULOCK are not defined at this point */
-
-#ifdef LOCKF
-#ifndef F_TLOCK
-#undef LOCKF
-#ifndef NOLOCKF
-#define NOLOCKF
-#endif /* NOLOCKF */
-#endif /* F_TLOCK */
-#endif /* LOCKF */
-
-#ifdef LOCKF
-#ifndef F_ULOCK
-#undef LOCKF
-#ifndef NOLOCKF
-#define NOLOCKF
-#endif /* NOLOCKF */
-#endif /* F_ULOCK */
-#endif /* LOCKF */
-
-static char linkto[DEVNAMLEN+1];
-static char * linkdev = NULL;
-
-#ifndef NOUUCP
-#ifdef USETTYLOCK
-#ifdef LOCK_DIR
-char * uucplockdir = LOCK_DIR;
-#else
-char * uucplockdir = "";
-#endif /* LOCK_DIR */
-#else
-#ifdef LOCK_DIR
-char * uucplockdir = LOCK_DIR;
-#else
-char * uucplockdir = "";
-#endif /* LOCK_DIR */
-#endif /* USETTYLOCK */
-#else
-char * uucplockdir = "";
-#endif /* NOUUCP */
-
-#ifdef QNX /* Only for QNX4 */
-int /* Visible to outside world */
-qnxopencount() { /* Get QNX device open count */
- struct _dev_info_entry info;
- int x;
-
- x = -1; /* Unknown */
- if (ttyfd > -1) {
- if (!dev_info(ttyfd, &info)) {
- debug(F101,"ttlock QNX open_count","",info.open_count);
- x = info.open_count;
- }
- }
- return(x);
-}
-#endif /* QNX */
-
-char *
-ttglckdir() { /* Get Lockfile directory name */
-#ifdef __OpenBSD__
- return("/var/spool/lock");
-#else /* __OpenBSD__ */
-#ifdef __FreeBSD__
- return("/var/spool/lock");
-#else /* __FreeBSD__ */
-#ifdef LOCK_DIR
- char * s = LOCK_DIR;
-#endif /* LOCK_DIR */
-#ifdef NOUUCP
- return("");
-#else /* NOUUCP */
-#ifdef LOCK_DIR
- return(s);
-#else /* LOCK_DIR */
- return("");
-#endif /* LOCK_DIR */
-#endif /* NOUUCP */
-#endif /* __FreeBSD__ */
-#endif /* __OpenBSD__ */
-}
-
-static int
-ttlock(ttdev) char *ttdev; {
-
- int x, n;
- int islink = 0;
-#ifdef __FreeBSD__
- char *devname;
-#endif /* __FreeBSD__ */
-
-#ifdef NOUUCP
- debug(F100,"ttlock NOUUCP","",0);
- ckstrncpy(flfnam,"NOLOCK",FLFNAML);
- haslock = 1;
- return(0);
-#else /* !NOUUCP */
-
-#ifdef USETTYLOCK
- haslock = 0; /* Not locked yet. */
- *flfnam = '\0'; /* Lockfile name is empty. */
-#ifdef __FreeBSD__
- if ((devname = xxlast(ttdev,'/')) != NULL)
-#ifdef FREEBSD8
- ckstrncat(lockname,devname+1,DEVNAMLEN-ckstrncpy(lockname,"pts",4));
-#else
- ckstrncpy(lockname,devname+1,DEVNAMLEN);
-#endif /* FREEBSD8 */
-#else
- if (!strncmp(ttdev,"/dev/",5) && ttdev[5])
- ckstrncpy(lockname,ttdev+5,DEVNAMLEN);
-#endif /* __FreeBSD__ */
- else
- ckstrncpy(lockname,ttdev,DEVNAMLEN);
-/*
- This might be overkill, but it's not clear from the man pages whether
- ttylock() can be called without calling ttylocked() first, since the doc
- says that ttylocked() removes any stale lockfiles, but it does not say this
- about ttylock(). Also the docs don't say what ttylocked() returns in the
- case when it finds and removes a stale lockfile. So one or both calls to
- to ttylocked() might be superfluous, but they should do no harm. Also I'm
- assuming that we have to do all the same ID swapping, etc, with these
- routines as we do without them. Thus the priv_on/off() sandwich.
-*/
-#ifdef USE_UU_LOCK
- priv_on(); /* Turn on privs */
- x = uu_lock(lockname); /* Try to set the lock */
- priv_off(); /* Turn privs off */
- debug(F111,"ttlock uu_lock",lockname,x);
- switch (x) {
- case UU_LOCK_INUSE:
- return(-2);
- case UU_LOCK_OK:
-#ifdef BSD44
- ckmakmsg(flfnam,FLFNAML,"/var/spool/lock/LCK..",lockname,NULL,NULL);
-#endif /* BSD44 */
- haslock = 1;
- return(0);
- default:
- return(-1);
- }
-#else /* USE_UU_LOCK */
- priv_on(); /* Turn on privs */
- if (ttylocked(lockname)) { /* This should remove any stale lock */
- if (ttylocked(lockname)) { /* so check again. */
- priv_off();
- return(-5); /* Still locked, fail. */
- }
- }
- x = ttylock(lockname); /* Lock it. */
- priv_off(); /* Turn off privs */
-
- debug(F111,"ttlock lockname",lockname,x);
- if (x > -1) {
- /*
- We don't really know the name of the lockfile, but
- this is what the man page says it is. In USETTYLOCK
- builds, it is used only for display by SHOW COMM.
- */
- ckmakmsg(flfnam,FLFNAML,"/etc/locks/LCK..",lockname,NULL,NULL);
- haslock = 1;
- }
- return(x);
-#endif /* USE_UU_LOCK */
-#else /* Systems that don't have ttylock()... */
-
-#ifndef HPUX
-
- int lockfd; /* File descriptor for lock file. */
- PID_T pid; /* Process id of this process. */
- int tries; /* How many times we've tried... */
- struct stat devbuf; /* For device numbers (SVR4). */
-
-#ifdef PIDSTRING
- char pid_str[32]; /* My pid in string format. */
-#endif /* PIDSTRING */
-
- char *device, *devname;
-
-#define LFNAML 256 /* Max length for lock file name. */
- char lockfil[LFNAML]; /* Lock file name */
-#ifdef RTAIX
- char lklockf[LFNAML]; /* Name for link to lock file */
-#endif /* RTAIX */
-#ifdef CKSYMLINK
- char symlock[LFNAML]; /* Name for symlink lockfile name */
-#endif /* CKSYMLINK */
- char tmpnam[LFNAML+30]; /* Temporary lockfile name. */
- char *lockdir = LOCK_DIR; /* Defined near top of this file, */
- /* or on cc command line. */
- haslock = 0; /* Not locked yet. */
- *flfnam = '\0'; /* Lockfile name is empty. */
- lock2[0] = '\0'; /* Clear secondary lockfile name. */
- pid = getpid(); /* Get id of this process. */
-
-/* Construct name of lockfile and temporary file */
-
-/* device = name of tty device without the path, e.g. "ttyh8" */
-/* lockfil = name of lock file, without path, e.g. "LCK..ttyh8" */
-
- device = ((devname = xxlast(ttdev,'/')) != NULL ? devname+1 : ttdev);
-
- if (stat(ttdev,&devbuf) < 0)
- return(-1);
-
-#ifdef CKSYMLINK
- islink = 1; /* Assume it's a symlink */
- linkto[0] = '\0'; /* But we don't know to what */
-#ifdef COMMENT
-/*
- This is undependable. If it worked it would save the readlink call if
- we knew the device name was not a link.
-*/
-#ifdef S_ISLNK
- islink = S_ISLNK(devbuf.st_mode);
- debug(F101,"ttlock stat S_ISLNK","",islink);
-#endif /* S_ISLNK */
-#endif /* COMMENT */
- if (islink) {
- n = readlink(ttdev,linkto,DEVNAMLEN); /* See if it's a link */
- debug(F111,"ttlock readlink",ttdev,n);
- if (n > -1) /* It is */
- linkto[n] = '\0';
- else /* It's not */
- islink = 0;
- debug(F111,"ttlock link",linkto,islink);
- }
- if (islink) {
- linkdev = (devname = xxlast(linkto,'/')) ? devname + 1 : linkto;
- debug(F110,"ttlock linkdev",linkdev,0);
- }
-#endif /* CKSYMLINK */
-
-/*
- On SCO platforms, if we don't have a symlink, then let's pretend the
- name given for the device is a symlink, because later we will change
- the name if it contains any uppercase characters.
-*/
-#ifdef CK_SCOV5 /* SCO Open Server 5.0 */
- if (!islink) {
- islink = 1;
- ckstrncpy(linkto,ttdev,DEVNAMLEN);
- linkdev = (devname = xxlast(linkto,'/')) ? devname + 1 : linkto;
- debug(F110,"ttlock linkdev",linkdev,0);
- }
-#else
-#ifdef M_XENIX /* SCO Xenix or UNIX */
- if (!islink) {
- islink = 1;
- ckstrncpy(linkto,ttdev,DEVNAMLEN);
- linkdev = (devname = xxlast(linkto,'/')) ? devname + 1 : linkto;
- debug(F110,"ttlock linkdev",linkdev,0);
- }
-#endif /* M_XENIX */
-#endif /* CK_SCOV5 */
-
-#ifdef ISIII /* Interactive System III, PC/IX */
- ckstrncpy(lockfil, device, DEVNAMLEN);
-#else /* not ISIII */
-#ifdef LFDEVNO /* Lockfilename has device numbers. */
-#ifdef COHERENT
- sprintf(lockfil,"LCK..%d.%d", /* SAFE */
- major(devbuf.st_rdev), /* major device number */
- 0x1f & minor(devbuf.st_rdev)); /* minor device number */
-#else
- /* Note: %d changed to %u in 8.0 -- %u is part of SVID for SVR4 */
- /* Lockfile name format verified to agree with Solaris cu, Dec 2001 */
- sprintf(lockfil,"LK.%03u.%03u.%03u", /* SAFE */
- major(devbuf.st_dev), /* device */
- major(devbuf.st_rdev), /* major device number */
- minor(devbuf.st_rdev)); /* minor device number */
-#endif /* COHERENT */
-#else /* Not LFDEVNO */
-#ifdef PTX /* Dynix PTX */
- if ((device != &ttdev[5]) && (strncmp(ttdev,"/dev/",5) == 0)) {
- if ((int)strlen(device) + 8 < LFNAML)
- sprintf(lockfil,"LCK..%.3s%s", &ttdev[5], device);
- else
- ckstrncpy(lockfil,"LOCKFILE_NAME_TOO_LONG",LFNAML);
- } else
-#endif /* PTX */
- if ((int)strlen(device) + 5 < LFNAML)
- sprintf(lockfil,"LCK..%s", device);
- else
- ckstrncpy(lockfil,"LOCKFILE_NAME_TOO_LONG",LFNAML);
-#ifdef RTAIX
- ckstrncpy(lklockf,device,DEVNAMLEN);
-#endif /* RTAIX */
-#ifdef CKSYMLINK
- symlock[0] = '\0';
- if (islink)
- ckmakmsg(symlock,LFNAML, "LCK..", linkdev, NULL, NULL);
-#endif /* CKSYMLINK */
-#endif /* LFDEVNO */
-#endif /* ISIII */
-
-#ifdef CK_SCOV5 /* SCO Open Server 5.0 */
- {
- /* Lowercase the entire filename. */
- /* SCO says we must do this in V5.0 and later. */
- /* BUT... watch out for devices -- like Digiboard Portserver */
- /* That can have hundreds of ports... */
- char *p = (char *)(lockfil + 5);
- while (*p) { if (isupper(*p)) *p = (char) tolower(*p); p++; }
- }
-#ifdef CKSYMLINK
- if (islink) { /* If no change */
- if (!strcmp(lockfil,symlock)) { /* then no second lockfile needed */
- islink = 0;
- symlock[0] = '\0';
- }
- }
-#endif /* CKSYMLINK */
-#else
-#ifdef M_XENIX /* SCO Xenix or UNIX */
- {
- int x; char c;
- x = (int)strlen(lockfil) - 1; /* Get last letter of device name. */
- if (x > 0) { /* If it's uppercase, lower it. */
- c = lockfil[x];
- if (c >= 'A' && c <= 'Z') lockfil[x] += ('a' - 'A');
- }
- }
-#ifdef CKSYMLINK
- if (islink) {
- if (!strcmp(lockfil,symlock)) { /* No change */
- islink = 0; /* so no second lockfile */
- symlock[0] = '\0';
- }
- }
-#endif /* CKSYMLINK */
-#endif /* M_XENIX */
-#endif /* CK_SCOV5 */
-
-/* flfnam = full lockfile pathname, e.g. "/usr/spool/uucp/LCK..ttyh8" */
-/* tmpnam = temporary unique, e.g. "/usr/spool/uucp/LTMP..pid" */
-
- ckmakmsg(flfnam,LFNAML,lockdir,"/",lockfil,NULL);
-
-#ifdef RTAIX
- ckmakmsg(lkflfn,FLFNAML,lockdir,"/",lklockf,NULL);
-#endif /* RTAIX */
-
-#ifndef LFDEVNO
-#ifdef CKSYMLINK
- /* If it's a link then also make a lockfile for the real name */
- debug(F111,"ttlock link symlock",symlock,islink);
- if (islink && symlock[0]) {
- /* But only if the lockfile names would be different. */
- /* WARNING: They won't be, e.g. for /dev/ttyd2 => /hw/ttys/ttyd2 */
- ckmakmsg(lock2,FLFNAML,lockdir,"/",symlock,NULL);
- debug(F110,"ttlock lock2",lock2,0);
- if (!strcmp(lock2,flfnam)) { /* Are lockfile names the same? */
- debug(F100,"ttlock lock2 cleared","",0);
- lock2[0] = '\0'; /* Clear secondary lockfile name. */
- }
- }
-#endif /* CKSYMLINK */
-#endif /* LFDEVNO */
-
- sprintf(tmpnam,"%s/LTMP.%05d",lockdir,(int) pid); /* safe */
- debug(F110,"ttlock flfnam",flfnam,0);
- debug(F110,"ttlock tmpnam",tmpnam,0);
-
- priv_on(); /* Turn on privileges if possible. */
- lockfd = creat(tmpnam, 0444); /* Try to create temp lock file. */
- if (lockfd < 0) { /* Create failed. */
- debug(F111,"ttlock creat failed",tmpnam,errno);
- if (errno == ENOENT) {
- perror(lockdir);
- printf("UUCP not installed or Kermit misconfigured\n");
- } else {
- if (!quiet)
- perror(lockdir);
- unlink(tmpnam); /* Get rid of the temporary file. */
- }
- priv_off(); /* Turn off privileges!!! */
- return(-1); /* Return failure code. */
- }
-/* Now write the pid into the temp lockfile in the appropriate format */
-
-#ifdef PIDSTRING /* For Honey DanBer UUCP, */
- sprintf( /* write PID as decimal string */
- pid_str,
-#ifdef LINUXFSSTND /* The "Linux File System Standard" */
-#ifdef FSSTND10 /* Version 1.0 calls for */
- "%010d\n", /* leading zeros */
-#else /* while version 1.2 calls for */
- "%10d\n", /* leading spaces */
-#endif /* FSSTND10 */
-#else
-#ifdef COHERENT
- "%d\n", /* with leading nothing */
-#else
- "%10d\n", /* with leading blanks */
-#endif /* COHERENT */
-#endif /* LINUXFSSTND */
- (int) pid
- ); /* safe */
- write(lockfd, pid_str, 11);
- debug(F111,"ttlock hdb pid string",pid_str,(int) pid);
-
-#else /* Not PIDSTRING, use integer PID */
-
- write(lockfd, (char *)&pid, sizeof(pid) );
- debug(F101,"ttlock pid","",(int) pid);
-
-#endif /* PIDSTRING */
-
-/* Now try to rename the temp file to the real lock file name. */
-/* This will fail if a lock file of that name already exists. */
-
- close(lockfd); /* Close the temp lockfile. */
- chmod(tmpnam,0444); /* Permission for a valid lock. */
- tries = 0;
- while (!haslock && tries++ < 2) {
- haslock = (link(tmpnam,flfnam) == 0); /* Create a link to it. */
- if (haslock) { /* If we got the lockfile */
-#ifdef RTAIX
- link(flfnam,lkflfn);
-#endif /* RTAIX */
-#ifdef CKSYMLINK
-#ifndef LFDEVNO
- if (islink && lock2[0])
- link(flfnam,lock2);
-#endif /* LFDEVNO */
-#endif /* CKSYMLINK */
-
-#ifdef COMMENT
-/* Can't do this any more because device is not open yet so no ttyfd. */
-#ifdef LOCKF
-/*
- Advisory file locking works on SVR4, so we use it. In fact, it is
- necessary in some cases, e.g. when SLIP is involved. But it still doesn't
- seem to prevent multiple users accessing the same device by different names.
-*/
- while (lockf(ttyfd, F_TLOCK, 0L) != 0) {
- debug(F111, "ttlock lockf returns errno", "", errno);
- if ((++tries >= 3) || (errno != EAGAIN)) {
- x = unlink(flfnam); /* remove the lockfile */
-#ifdef RTAIX
- unlink(lkflfn); /* And any links to it... */
-#endif /* RTAIX */
-#ifdef CKSYMLINK
-#ifndef LFDEVNO
- if (islink && lock2[0])
- unlink(lock2); /* ditto... */
-#endif /* LFDEVNO */
-#endif /* CKSYMLINK */
- debug(F111,"ttlock unlink",flfnam,x);
- haslock = 0;
- break;
- }
- sleep(2);
- }
- if (haslock) /* If we got an advisory lock */
-#endif /* LOCKF */
-#endif /* COMMENT */
- break; /* We're done. */
-
- } else { /* We didn't create a new lockfile. */
- priv_off();
- if (ttchkpid(flfnam)) { /* Check existing lockfile */
- priv_on(); /* cause ttchkpid turns priv_off... */
- unlink(tmpnam); /* Delete the tempfile */
- debug(F100,"ttlock found tty locked","",0);
- priv_off(); /* Turn off privs */
- return(-2); /* Code for device is in use. */
- }
- priv_on();
- }
- }
- unlink(tmpnam); /* Unlink (remove) the temp file. */
- priv_off(); /* Turn off privs */
- return(haslock ? 0 : -1); /* Return link's return code. */
-
-#else /* HPUX */
-
-/*
- HP-UX gets its own copy of this routine, modeled after the observed behavior
- of the HP-UX 'cu' program. HP-UX serial device names consist of a base name
- such as "tty", "ttyd", "cua", "cul", "cuad", or "culd", followed by a unit
- designator which is a string of digits, possibly containing an imbedded
- letter "p". Examples (for base name "tty"):
-
- /dev/tty0, /dev/tty00, dev/ttyd00, /dev/tty0p0
-
- According to the HP-UX UUCP manual of 1988, the "0p0" notation has been
- used on Series 800 since HP-UX 2.00, and the "non-p" notation was used
- on other models. In HP-UX 10.00, "0p0" notation was adopted for all models.
- However, we make and enforce no such distinctions; either notation is
- accepted on any model or HP-UX version as a valid unit designator.
-
- If a valid unit is specified (as opposed to a designer name or symlink), we
- check for all aliases of the given unit according to the devprefix[] array.
- If no lockfiles are found for the given unit, we can have the device; we
- create a lockfile LCK..name in the lockfile directory appropriate for the
- HP-UX version (/var/spool/locks for 10.00 and later, /usr/spool/uucp for
- 9.xx and earlier). If it is a "cua" or "cul" device, a second lockfile is
- created with the "ttyd" prefix. This is exactly what cu does.
-
- If the "set line" device does not have a valid unit designator, then it is
- used literally and no synomyms are searched for and only one lockfile is
- created.
-
- -fdc, March 1998.
-*/
-#define LFNAML 80 /* Max length for lock file name. */
-
- int lockfd; /* File descriptor for lock file. */
- PID_T pid; /* Process ID of this process. */
- int fpid; /* pid found in existing lockfile. */
- int tries; /* How many times we've tried... */
- int i, k; /* Workers */
-
- char *device, *devname; /* "/dev/xxx", "xxx" */
- char *unit, *p; /* <instance>p<port> part of xxx */
-
- char lockfil[LFNAML]; /* Lockfile name (no path) */
- char tmpnam[LFNAML]; /* Temporary lockfile name. */
-
-#ifdef HPUX10 /* Lockfile directory */
- char *lockdir = "/var/spool/locks"; /* Always this for 10.00 and higher */
-#else /* HP-UX 9.xx and below */
-#ifdef LOCK_DIR
- char *lockdir = LOCK_DIR; /* Defined near top of this file */
-#else
- char *lockdir = "/usr/spool/uucp"; /* or not... */
-#endif /* LOCK_DIR */
-#endif /* HPUX10 */
-
- haslock = 0; /* Not locked yet. */
- *flfnam = '\0'; /* Lockfile name is empty. */
- lock2[0] = '\0'; /* Second one too. */
- pid = getpid(); /* Get my process ID */
-/*
- Construct name of lockfile and temporary file...
- device = name of tty device without the path, e.g. "tty0p0"
- lockfil = name of lock file, without path, e.g. "LCK..tty0p0"
-*/
- device = ((devname = xxlast(ttdev,'/')) != NULL ? devname+1 : ttdev);
- debug(F110,"TTLOCK device",device,0);
- ckmakmsg(lockfil,LFNAML,"LCK..",device,NULL,NULL);
-
- k = 0; /* Assume device is not locked */
- n = 0; /* Digit counter */
- unit = device; /* Unit = <instance>p<port> */
- while (*unit && !isdigit(*unit)) /* Search for digit... */
- unit++;
- p = unit; /* Verify <num>p<num> format... */
- debug(F110,"TTLOCK unit 1",unit,0);
-/*
- The unit number is recognized as:
- (a) any sequence of digits that runs to the end of the string.
- (b) any (a) that includes one and only one letter "p", with at least
- one digit before and after it.
-*/
- while (isdigit(*p)) p++, n++; /* Get a run of digits */
- if (*p && n > 0) { /* Have a "p"? */
- if (*p == 'p' && isdigit(*(p+1))) {
- p++;
- n = 0;
- while (isdigit(*p)) p++, n++;
- }
- }
- if (n == 0 || *p) unit = "";
- debug(F110,"TTLOCK unit 2",unit,0);
-
- if (*unit) { /* Device name has unit number. */
- /* The following loop not only searches for the various lockfile */
- /* synonyms, but also removes all -- not just one -- stale lockfile */
- /* for the device, should there be more than one. See ttchkpid(). */
- ttydexists = 0;
- for (i = 0; *devprefix[i]; i++) { /* For each driver... */
- /* Make device name */
- ckmakmsg(lock2,FLFNAML,"/dev/",devprefix[i],unit,NULL);
- priv_on(); /* Privs on */
- k = zchki(lock2) != -1; /* See if device exists */
- priv_off(); /* Privs off */
- debug(F111,"TTLOCK exist",lock2,k);
- if (k) {
- if (!strcmp(devprefix[i],"ttyd")) /* ttyd device exists */
- ttydexists = 1;
- /* Make lockfile name */
- ckmakmsg(lock2,FLFNAML,lockdir,"/LCK..",devprefix[i],unit);
- debug(F110,"TTLOCK checking",lock2,0);
- priv_on(); /* Privs on */
- k = zchki(lock2) != -1; /* See if lockfile exists */
- priv_off(); /* Privs off */
- debug(F111,"TTLOCK check for lock A",lock2,k);
- if (k) if (ttchkpid(lock2)) { /* If pid still active, fail. */
- ckstrncpy(flfnam,lock2,FLFNAML);
- return(-2);
- }
- }
- }
- } else { /* Some other device-name format */
- /* This takes care of symbolic links, etc... */
- /* But does not chase them down! */
- ckmakmsg(lock2,FLFNAML,lockdir,"/LCK..",device,NULL);
- priv_on();
- k = zchki(lock2) != -1; /* Check for existing lockfile */
- priv_off();
- debug(F111,"TTLOCK check for lock B",lock2,k);
- if (k) if (ttchkpid(lock2)) { /* Check pid from lockfile */
- ckstrncpy(flfnam,lock2,FLFNAML);
- debug(F110,"TTLOCK in use",device,0);
- debug(F101,"TTLOCK returns","",-2);
- return(-2);
- }
- }
-/*
- Get here only if there is no (more) lockfile, so now we make one (or two)...
- flfnam = full lockfile pathname, e.g. "/usr/spool/uucp/LCK..cul0p0".
- tmpnam = unique temporary filname, e.g. "/usr/spool/uucp/LTMP..pid".
-*/
- ckmakmsg(flfnam,FLFNAML,lockdir,"/",lockfil,NULL); /* SET LINE device */
-
- /* If dialout device, also make one for corresponding dialin device */
- lock2[0] = '\0';
- if (!strncmp(device,"cu",2) && *unit && ttydexists)
- ckmakmsg(lock2,FLFNAML,lockdir,"/LCK..ttyd",unit,NULL);
-
- if ((int)strlen(lockdir)+12 < LFNAML)
- sprintf(tmpnam,"%s/LTMP.%05d",lockdir,(int) pid); /* Make temp name */
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"TTLOCK flfnam",flfnam,0);
- debug(F110,"TTLOCK lock2",lock2,0);
- debug(F110,"TTLOCK tmpnam",tmpnam,0);
- }
-#endif /* DEBUG */
-/*
- Lockfile permissions...
- 444 is standard, HP-UX 10.00 uses 664. It doesn't matter.
- Kermit uses 444; the difference lets us tell whether Kermit created
- the lock file.
-*/
- priv_on(); /* Turn on privileges. */
- lockfd = creat(tmpnam, 0444); /* Try to create temporary file. */
- if (lockfd < 0) { /* Create failed. */
- debug(F111,"TTLOCK creat failed",tmpnam,errno);
- if (errno == ENOENT) {
- perror(lockdir);
- printf("UUCP not installed or Kermit misconfigured\n");
- } else {
- if (!quiet)
- perror(lockdir);
- unlink(tmpnam); /* Get rid of the temporary file. */
- }
- priv_off(); /* Turn off privileges!!! */
- debug(F101,"TTLOCK returns","",-1);
- return(-1); /* Return failure code. */
- }
- debug(F110,"TTLOCK temp ok",tmpnam,0);
-
-/* Now write our pid into the temp lockfile in integer format. */
-
- i = write(lockfd, (char *)&pid, sizeof(pid));
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"TTLOCK pid","",pid);
- debug(F101,"TTLOCK sizeof pid","",sizeof(pid));
- debug(F101,"TTLOCK write pid returns","",i);
- }
-#endif /* DEBUG */
-
-/*
- Now try to rename the temporary file to the real lockfile name.
- This will fail if a lock file of that name already exists, which
- will catch race conditions with other users.
-*/
- close(lockfd); /* Close the temp lockfile. */
- chmod(tmpnam,0444);
-
- tries = 0;
- while (!haslock && tries++ < 2) {
- haslock = (link(tmpnam,flfnam) == 0); /* Create a link to it. */
- debug(F101,"TTLOCK link","",haslock);
- if (haslock) { /* If we made the lockfile... */
-
-#ifdef COMMENT
-/* We can't do this any more because we don't have a file descriptor yet. */
-#ifdef LOCKF /* Can be canceled with -DNOLOCKF */
-/*
- Create an advisory lock on the device through its file descriptor.
- This code actually seems to work. If it is executed, and then another
- process tries to open the same device under a different name to circumvent
- the lockfile, they get a "device busy" error.
-*/
- debug(F100,"TTLOCK LOCKF code...","",0);
- while ( lockf(ttyfd, F_TLOCK, 0L) != 0 ) {
- debug(F111, "TTLOCK lockf error", "", errno);
- if ((++tries >= 3) || (errno != EAGAIN)) {
- x = unlink(flfnam); /* Remove the lockfile */
- if (errno == EACCES && !quiet)
- printf("Device already locked by another process\n");
- haslock = 0;
- break;
- }
- sleep(2);
- }
-#endif /* LOCKF */
-#endif /* COMMENT */
-
- if (haslock) { /* If we made the lockfile ... */
- if (lock2[0]) { /* if there is to be a 2nd lockfile */
- lockfd = creat(lock2, 0444); /* Create it */
- debug(F111,"TTLOCK lock2 creat", lock2, lockfd);
- if (lockfd > -1) { /* Created OK, write pid. */
- write(lockfd, (char *)&pid, sizeof(pid) );
- close(lockfd); /* Close and */
- chmod(lock2, 0444); /* set permissions. */
- } else { /* Not OK, but don't fail. */
- lock2[0] = '\0'; /* Just remember it's not there. */
- }
- }
- break; /* and we're done. */
- }
- }
- }
- unlink(tmpnam); /* Unlink (remove) the temp file. */
- priv_off(); /* Turn off privs */
- i = haslock ? 0 : -1; /* Our return value */
- debug(F101,"TTLOCK returns","",i);
- return(i);
-#endif /* HPUX */
-#endif /* USETTYLOCK */
-#endif /* !NOUUCP */
-}
-
-/* T T U N L O C K */
-
-static int
-ttunlck() { /* Remove UUCP lockfile(s). */
-#ifndef NOUUCP
- int x;
-
- debug(F111,"ttunlck",flfnam,haslock);
-
-#ifdef USETTYLOCK
-
- if (haslock && *flfnam) {
- int x;
- priv_on(); /* Turn on privs */
-#ifdef USE_UU_LOCK
- x = uu_unlock(lockname);
-#else /* USE_UU_LOCK */
- x = ttyunlock(lockname); /* Try to unlock */
-#endif /* USE_UU_LOCK */
- priv_off(); /* Turn off privs */
- if (x < 0 && !quiet)
- printf("Warning - Can't remove lockfile: %s\n", flfnam);
-
- *flfnam = '\0'; /* Erase the name. */
- haslock = 0;
- return(0);
- }
-
-#else /* No ttylock()... */
-
- if (haslock && *flfnam) {
- /* Don't remove lockfile if we didn't make it ourselves */
- if ((x = ttrpid(flfnam)) != (int)getpid()) {
- debug(F111,"ttunlck lockfile seized",flfnam,x);
- printf("Warning - Lockfile %s seized by pid %d\n",
- flfnam,
- x
- );
- return(0);
- }
- priv_on(); /* Turn privileges on. */
- errno = 0;
- x = unlink(flfnam); /* Remove the lockfile. */
- debug(F111,"ttunlck unlink",flfnam,x);
- if (x < 0) {
- if (errno && !quiet)
- perror(ttnmsv);
- printf("Warning - Can't remove lockfile: %s\n", flfnam);
- }
- haslock = 0;
- *flfnam = '\0'; /* Erase the name. */
-
-#ifdef RTAIX
- errno = 0;
- x = unlink(lkflfn); /* Remove link to lockfile */
- debug(F111,"ttunlck AIX link unlink",lkflfn,x);
- if (x < 0) {
- if (errno && !quiet)
- perror(ttnmsv);
- printf("Warning - Can't remove link to lockfile: %s\n", lkflfn);
- }
- *lkflfn = '\0';
-#else
- if (lock2[0]) { /* If there is a second lockfile, */
- errno = 0;
- x = unlink(lock2); /* remove it too. */
- debug(F111,"ttunlck lock2 unlink",lock2,x);
- if (x < 0) {
- if (errno && !quiet)
- perror(ttnmsv);
- printf("Warning - Can't remove secondary lockfile: %s\n",
- lock2
- );
- }
- lock2[0] = '\0'; /* Forget its name. */
- }
-#endif /* RTAIX */
-
-#ifdef COMMENT
-#ifdef LOCKF
- (VOID) lockf(ttyfd, F_ULOCK, 0L); /* Remove advisory lock */
-#endif /* LOCKF */
-#endif /* COMMENT */
-
- priv_off(); /* Turn privileges off. */
- }
-#endif /* USETTYLOCK */
-#endif /* !NOUUCP */
- return(0);
-}
-
-/*
- 4.3BSD-style UUCP line direction control.
- (Stan Barber, Rice U, 1980-something...)
-*/
-#ifndef NOUUCP
-#ifdef ACUCNTRL
-VOID
-acucntrl(flag,ttname) char *flag, *ttname; {
- char x[DEVNAMLEN+32], *device, *devname;
-
- if (strcmp(ttname,CTTNAM) == 0 || xlocal == 0) /* If not local, */
- return; /* just return. */
- device = ((devname = xxlast(ttname,'/')) != NULL ? devname+1 : ttname);
- if (strncmp(device,"LCK..",4) == 0) device += 5;
- ckmakmsg(x,DEVNAMLEN+32,"/usr/lib/uucp/acucntrl ",flag," ",device);
- debug(F110,"called ",x,0);
- zsyscmd(x);
-}
-#endif /* ACUCNTRL */
-#endif /* NOUUCP */
-
-/*
- T T H F L O W -- Set or Reset hardware flow control.
-
- This is an attempt to collect all hardware-flow-control related code
- into a single module. Thanks to Rick Sladkey and John Kohl for lots of
- help here. Overview:
-
- Hardware flow control is not supported in many UNIX implementions. Even
- when it is supported, there is no (ha ha) "standard" for the programming
- interface. In general, 4.3BSD and earlier (sometimes), 4.4BSD, System V,
- SunOS, AIX, etc, have totally different methods. (And, not strictly
- relevant here, the programming interface often brings one only to a no-op
- in the device driver!)
-
- Among all these, we have two major types of APIs: those in which hardware
- flow control is determined by bits in the same termio/termios/sgtty mode
- word(s) that are used for controlling such items as CBREAK vs RAW mode, and
- which are also used by the ttvt(), ttpkt(), conbin(), and concb() routines
- for changing terminal modes. And those that use entirely different
- mechanisms.
-
- In the first category, it is important that any change in the mode bits be
- reflected in the relevant termio(s)/sgtty structure, so that subsequent
- changes to that structure do not wipe out the effects of this routine. That
- is why a pointer, attrs, to the appropriate structure is passed as a
- parameter to this routine.
-
- The second category should give us no worries, since any changes to hardware
- flow control accomplished by this routine should not affect the termio(s)/
- sgtty structures, and therefore will not be undone by later changes to them.
-
- The second argument, status, means to turn on hardware flow control if
- nonzero, and to turn it off if zero.
-
- Returns: 0 on apparent success, -1 on probable failure.
-*/
-
-/*
- The following business is for BSDI, where it was discovered that two
- separate bits, CCTS_OFLOW and CRTS_IFLOW, are used in hardware flow control,
- but CTRSCTS is defined (in <termios.h>) to be just CCTS_OFLOW rather both
- bits, so hwfc only works in one direction if you use CRTSCTS to control it.
- Other 4.4BSD-based Unixes such as FreeBSD 4.1, which use these two bits,
- define CRTSCTS correctly.
-*/
-#ifdef FIXCRTSCTS
-#ifdef CRTSCTS
-#ifdef CCTS_OFLOW
-#ifdef CRTS_IFLOW
-#undef CRTSCTS
-#define CRTSCTS (CRTS_IFLOW|CCTS_OFLOW)
-#endif /* CRTS_IFLOW */
-#endif /* CCTS_OFLOW */
-#endif /* CRTSCTS */
-#endif /* FIXCRTSCTS */
-
-static int
-tthflow(flow, status, attrs)
- int flow, /* Type of flow control (ckcdeb.h) */
- status; /* Nonzero = turn it on */
- /* Zero = turn it off */
-#ifdef BSD44ORPOSIX /* POSIX or BSD44 */
- struct termios *attrs;
-#else /* System V */
-#ifdef ATTSV
-#ifdef ATT7300
-#ifdef UNIX351M
-/* AT&T UNIX 3.51m can set but not test for hardware flow control */
-#define RTSFLOW CTSCD
-#define CTSFLOW CTSCD
-#endif /* ATT7300 */
-#endif /* UNIX351M */
- struct termio *attrs;
-#else /* BSD, V7, etc */
- struct sgttyb *attrs; /* sgtty info... */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-/* tthflow */ {
-
- int x = 0; /* tthflow() return code */
-
-#ifdef Plan9
- return p9tthflow(flow, status);
-#else
-
-#ifndef OXOS /* NOT Olivetti X/OS... */
-/*
- For SunOS 4.0 and later in the BSD environment ...
-
- The declarations are copied and interpreted from the System V header files,
- so we don't actually have to pull in all the System V junk when building
- C-Kermit for SunOS in the BSD environment, which would be dangerous because
- having those symbols defined would cause us to take the wrong paths through
- the code. The code in this section is used in both the BSD and Sys V SunOS
- versions.
-*/
-#ifdef SUNOS41
-/*
- In SunOS 4.1 and later, we use the POSIX calls rather than ioctl calls
- because GNU CC uses different formats for the _IOxxx macros than regular CC;
- the POSIX forms work for both. But the POSIX calls are not available in
- SunOS 4.0.
-*/
-#define CRTSCTS 0x80000000 /* RTS/CTS flow control */
-#define TCSANOW 0 /* Do it now */
-
- struct termios {
- unsigned long c_iflag; /* Input modes */
- unsigned long c_oflag; /* Output modes */
- unsigned long c_cflag; /* Control modes */
- unsigned long c_lflag; /* Line discipline modes */
- char c_line;
- CHAR c_cc[17];
- };
- struct termios temp;
-
-_PROTOTYP( int tcgetattr, (int, struct termios *) );
-_PROTOTYP( int tcsetattr, (int, int, struct termios *) );
-/*
- When CRTSCTS is set, SunOS won't do output unless both CTS and CD are
- asserted. So we don't set CRTSCTS unless CD is up. This should be OK,
- since we don't need RTS/CTS during dialing, and after dialing is complete,
- we should have CD. If not, we still communicate, but without RTS/CTS.
-*/
- int mflags; /* Modem signal flags */
-
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-
- debug(F101,"tthflow SUNOS41 entry status","",status);
- if (!status) { /* Turn hard flow off */
- if (tcgetattr(ttyfd, &temp) > -1 && /* Get device attributes */
- (temp.c_cflag & CRTSCTS)) { /* Check for RTS/CTS */
- temp.c_cflag &= ~CRTSCTS; /* It's there, remove it */
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- }
- } else { /* Turn hard flow on */
- if (ioctl(ttyfd,TIOCMGET,&mflags) > -1 && /* Get modem signals */
- (mflags & TIOCM_CAR)) { /* Check for CD */
- debug(F100,"tthflow SunOS has CD","",0);
- if (tcgetattr(ttyfd, &temp) > -1 && /* Get device attributes */
- !(temp.c_cflag & CRTSCTS)) { /* Check for RTS/CTS */
- temp.c_cflag |= CRTSCTS; /* Not there, add it */
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- }
- } else {
- x = -1;
- debug(F100,"tthflow SunOS no CD","",0);
- }
- }
-#else
-#ifdef QNX
- struct termios temp;
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- debug(F101,"tthflow QNX entry status","",status);
- if (tcgetattr(ttyfd, &temp) > -1) { /* Get device attributes */
- if (!status) { /* Turn hard flow off */
- if ((temp.c_cflag & (IHFLOW|OHFLOW)) == (IHFLOW|OHFLOW)) {
- temp.c_cflag &= ~(IHFLOW|OHFLOW); /* It's there, remove it */
- attrs->c_cflag &= ~(IHFLOW|OHFLOW);
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- }
- } else { /* Turn hard flow on */
- if ((temp.c_cflag & (IHFLOW|OHFLOW)) != (IHFLOW|OHFLOW)) {
- temp.c_cflag |= (IHFLOW|OHFLOW); /* Not there, add it */
- temp.c_iflag &= ~(IXON|IXOFF); /* Bye to IXON/IXOFF */
- ttraw.c_lflag |= IEXTEN; /* Must be on */
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- attrs->c_cflag |= (IHFLOW|OHFLOW);
- attrs->c_iflag &= ~(IXON|IXOFF);
- }
- }
- } else {
- x = -1;
- debug(F100, "tthflow QNX getattr fails", "", 0);
- }
-#else
-#ifdef POSIX_CRTSCTS
-/*
- POSIX_CRTSCTS is defined in ckcdeb.h or on CC command line.
- Note: Do not assume CRTSCTS is a one-bit field!
-*/
- struct termios temp;
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- debug(F101,"tthflow POSIX_CRTSCTS entry status","",status);
- errno = 0;
- x = tcgetattr(ttyfd, &temp);
- debug(F111,"tthflow POSIX_CRTSCTS tcgetattr",ckitoa(x),errno);
- errno = 0;
- if (x < 0) {
- x = -1;
- } else {
- if (!status) { /* Turn hard flow off */
- if (
-#ifdef COMMENT
- /* This can fail because of sign extension */
- /* e.g. in Linux where it's Bit 31 */
- (temp.c_cflag & CRTSCTS) == CRTSCTS
-#else
- (temp.c_cflag & CRTSCTS) != 0
-#endif /* COMMENT */
- ) {
- temp.c_cflag &= ~CRTSCTS; /* It's there, remove it */
- attrs->c_cflag &= ~CRTSCTS;
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- debug(F111,"tthflow POSIX_CRTSCTS OFF tcsetattr",
- ckitoa(x),errno);
- } else { /* John Dunlap 2010-01-26 */
- debug(F001,
- "tthflow before forcing off attrs CRTSCTS",
- "",
- attrs->c_cflag&CRTSCTS
- );
- attrs->c_cflag &= ~CRTSCTS; /* force it off if !status */
- debug(F001,
- "tthflow after forcing off attrs CRTSCTS",
- "",
- attrs->c_cflag&CRTSCTS
- );
- }
- } else { /* Turn hard flow on */
- if (
-#ifdef COMMENT
- /* This can fail because of sign extension */
- (temp.c_cflag & CRTSCTS) != CRTSCTS
-#else
- (temp.c_cflag & CRTSCTS) == 0
-#endif /* COMMENT */
- ) {
- temp.c_cflag |= CRTSCTS; /* Not there, add it */
- temp.c_iflag &= ~(IXON|IXOFF|IXANY); /* Bye to IXON/IXOFF */
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- debug(F111,"tthflow POSIX_CRTSCTS ON tcsetattr",
- ckitoa(x),errno);
- attrs->c_cflag |= CRTSCTS;
- attrs->c_iflag &= ~(IXON|IXOFF|IXANY);
- }
- }
- }
-#else
-#ifdef SUNOS4
-/*
- SunOS 4.0 (and maybe earlier?). This code is dangerous because it
- prevents compilation with GNU gcc, which uses different formats for the
- _IORxxx macros than regular cc. SunOS 4.1 and later can use the POSIX
- routines above, which work for both cc and gcc.
-*/
-#define TCGETS _IOR(T, 8, struct termios) /* Get modes into termios struct */
-#define TCSETS _IOW(T, 9, struct termios) /* Set modes from termios struct */
-#define CRTSCTS 0x80000000 /* RTS/CTS flow control */
-
- struct termios {
- unsigned long c_iflag; /* Input modes */
- unsigned long c_oflag; /* Output modes */
- unsigned long c_cflag; /* Control modes */
- unsigned long c_lflag; /* Line discipline modes */
- char c_line;
- CHAR c_cc[17];
- };
- struct termios temp;
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- debug(F101,"tthflow entry status","",status);
- if (ioctl(ttyfd,TCGETS,&temp) > -1) { /* Get terminal modes. */
- if (status) { /* Turn hard flow on */
- temp.c_cflag |= CRTSCTS; /* Add RTS/CTS to them. */
- x = ioctl(ttyfd,TCSETS,&temp); /* Set them again. */
- attrs->c_cflag |= CRTSCTS; /* Add to global info. */
- } else { /* Turn hard flow off */
- temp.c_cflag &= ~CRTSCTS;
- x = ioctl(ttyfd,TCSETS,&temp);
- attrs->c_cflag &= ~CRTSCTS;
- }
- }
-#else /* Not SunOS 4.0 or later */
-#ifdef AIXRS /* IBM AIX RS/6000 */
-#ifndef AIX41 /* But only pre-4.x == SVR4 */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- if (status) {
- if ((x = ioctl(ttyfd, TXADDCD, "rts")) < 0 && errno != EBUSY)
- debug(F100,"hardflow TXADDCD (rts) error", "", 0);
- } else {
- if ((x = ioctl(ttyfd, TXDELCD, "rts")) < 0 && errno != EINVAL)
- debug(F100,"hardflow TXDELCD (rts) error", "", 0);
- }
-#endif /* AIX41 */
-#else /* Not AIX RS/6000 */
-
-#ifdef ATTSV /* System V... */
-
-#ifdef CK_SCOV5 /* SCO Open Server 5.0 */
-#define CK_SCOUNIX
-#else
-#ifdef M_UNIX /* SCO UNIX 3.2v4.x or earlier */
-#define CK_SCOUNIX
-#endif /* M_UNIX */
-#endif /* CK_SCOV5 */
-
-#ifdef SCO_FORCE_RTSXOFF
-#ifdef CK_SCOUNIX /* But not SCO OpenServer 5.0.4 */
-#ifdef SCO_OSR504 /* or later... */
-#undef CK_SCOUNIX
-#endif /* SCO_OSR504 */
-#endif /* CK_SCOUNIX */
-#endif /* SCO_FORCE_RTSXOFF */
-
-#ifdef CK_SCOUNIX
-#ifdef POSIX
- struct termios temp;
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- debug(F101,"tthflow SCOUNIX POSIX entry status","",status);
- errno = 0;
- x = tcgetattr(ttyfd, &temp);
- debug(F111,"tthflow SCO UNIX POSIX tcgetattr",ckitoa(x),errno);
-#else /* POSIX */
- struct termio temp;
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- debug(F101,"tthflow SCOUNIX non-POSIX entry status","",status);
- x = ioctl(ttyfd, TCGETA, &temp);
- debug(F111,"tthflow SCO UNIX non-POSIX TCGETA",ckitoa(x),errno);
-#endif /* POSIX */
-/*
- This is not really POSIX, since POSIX does not deal with hardware flow
- control, but we are using the POSIX APIs. In fact, RTSFLOW and CTSFLOW
- are defined in termio.h, but within #ifndef _POSIX_SOURCE..#endif. So
- let's try forcing their definitions here.
-*/
-#ifndef CTSFLOW
-#define CTSFLOW 0020000
- debug(F101,"tthflow SCO defining CTSFLOW","",CTSFLOW);
-#else
- debug(F101,"tthflow SCO CTSFLOW","",CTSFLOW);
-#endif /* CTSFLOW */
-#ifndef RTSFLOW
-#define RTSFLOW 0040000
- debug(F101,"tthflow SCO defining RTSFLOW","",RTSFLOW);
-#else
- debug(F101,"tthflow SCO RTSFLOW","",RTSFLOW);
-#endif /* RTSFLOW */
-#ifndef ORTSFL
-#define ORTSFL 0100000
- debug(F101,"tthflow SCO defining ORTSFL","",ORTSFL);
-#else
- debug(F101,"tthflow SCO ORTSFL","",ORTSFL);
-#endif /* ORTSFL */
-
- if (x != -1) {
- if (status) { /* Turn it ON */
- temp.c_cflag |= RTSFLOW|CTSFLOW;
- attrs->c_cflag |= RTSFLOW|CTSFLOW;
-#ifdef ORTSFL
- temp.c_cflag &= ~ORTSFL;
- attrs->c_cflag &= ~ORTSFL;
-#endif /* ORTSFL */
- temp.c_iflag &= ~(IXON|IXOFF|IXANY);
- attrs->c_iflag &= ~(IXON|IXOFF|IXANY);
- } else { /* Turn it OFF */
-#ifdef ORTSFL
- temp.c_cflag &= ~(RTSFLOW|CTSFLOW|ORTSFL);
- attrs->c_cflag &= ~(RTSFLOW|CTSFLOW|ORTSFL);
-#else /* ORTSFL */
- temp.c_cflag &= ~(RTSFLOW|CTSFLOW);
- attrs->c_cflag &= ~(RTSFLOW|CTSFLOW);
-#endif /* ORTSFL */
- }
-#ifdef POSIX
- x = tcsetattr(ttyfd, TCSADRAIN, &temp);
-#else
- x = ioctl(ttyfd, TCSETA, &temp);
-#endif /* POSIX */
- debug(F101,"tthflow SCO set modes","",x);
- }
-#else /* Not SCO UNIX */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- if (!status) { /* Turn it OFF */
-#ifdef RTSXOFF
- debug(F100,"tthflow ATTSV RTS/CTS OFF","",0);
- rctsx.x_hflag &= ~(RTSXOFF|CTSXON);
-#ifdef TCSETX
- x = ioctl(ttyfd,TCSETX,&rctsx);
- debug(F101,"tthflow ATTSV TCSETX OFF","",x);
-#else
- x = -1
- debug(F100,"tthflow TCSETX not defined","",0);
-#endif /* TCSETX */
-#else
- debug(F100,"tthflow ATTSV RTSXOFF not defined","",0);
-#endif /* RTSXOFF */
-#ifdef DTRXOFF
- debug(F100,"tthflow ATTSV DTR/CD OFF","",0);
- rctsx.x_hflag &= ~(DTRXOFF|CDXON);
- x = ioctl(ttyfd,TCSETX,&rctsx);
- debug(F101,"tthflow ATTSV DTRXOFF OFF","",x);
-#else
- debug(F100,"tthflow ATTSV DTRXOFF not defined","",0);
-#endif /* DTRXOFF */
- } else { /* Turn it ON. */
- if (flow == FLO_RTSC) { /* RTS/CTS Flow control... */
- debug(F100,"tthflow ATTSV RTS/CTS ON","",0);
-#ifdef RTSXOFF
- /* This is the preferred way, according to SVID3 */
-#ifdef TCGETX
- x = ioctl(ttyfd,TCGETX,&rctsx);
- debug(F101,"tthflow TCGETX","",x);
- if (x > -1) {
- rctsx.x_hflag |= RTSXOFF | CTSXON;
- x = ioctl(ttyfd,TCSETX,&rctsx);
- debug(F100,"tthflow ATTSV ioctl","",x);
- }
-#else
- debug(F100,"tthflow TCGETX not defined","",0);
- x = -1
-#endif /* TCGETX */
-#else
- debug(F100,"tthflow RTSXOFF not defined","",0);
- x = -1;
-#endif /* RTSXOFF */
- } else if (flow == FLO_DTRC) { /* DTR/CD Flow control... */
- debug(F100,"tthflow ATTSV DTR/CD ON","",0);
-#ifdef DTRXOFF
- /* This is straight out of SVID R4 */
- if (ioctl(ttyfd,TCGETX,&rctsx) > -1) {
- rctsx.x_hflag &= ~(DTRXOFF|CDXON);
- x = ioctl(ttyfd,TCSETX,&rctsx);
- }
-#else
- debug(F100,"tthflow ATTSV DTRXOFF not defined","",0);
- x = -1;
-#endif /* DTRXOFF */
- }
- }
-#endif /* CK_SCOUNIX */
-
-#else /* not System V... */
-
-#ifdef CK_DTRCTS
-#ifdef LDODTR
-#ifdef LDOCTS
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- x = LDODTR | LDOCTS; /* Found only on UTEK? */
- if (flow == FLO_DTRT && status) { /* Use hardware flow control */
- if (lmodef) {
- x = ioctl(ttyfd,TIOCLBIS,&x);
- if (x < 0) {
- debug(F100,"hardflow TIOCLBIS error","",0);
- } else {
- lmodef++;
- debug(F100,"hardflow TIOCLBIS ok","",0);
- }
- }
- } else {
- if (lmodef) {
- x = ioctl(ttyfd,TIOCLBIC,&x);
- if (x < 0) {
- debug(F100,"hardflow TIOCLBIC error","",0);
- } else {
- lmodef++;
- debug(F100,"hardflow TIOCLBIC ok","",0);
- }
- }
- }
-#endif /* LDODTR */
-#endif /* LDOCTS */
-#endif /* CK_DTRCTS */
-#endif /* ATTSV */
-#endif /* AIXRS */
-#endif /* SUNOS4 */
-#endif /* QNX */
-#endif /* POSIX_CRTSCTS */
-#endif /* SUNOS41 */
-
-#else /* OXOS */
-
- struct termios temp; /* Olivetti X/OS ... */
-
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- x = ioctl(ttyfd,TCGETS,&temp);
- if (x == 0) {
- temp.c_cflag &= ~(CRTSCTS|CDTRCTS|CBRKFLOW|CDTRDSR|CRTSDSR);
- if (status) {
- switch (flow) {
- case FLO_RTSC: temp.c_cflag |= CRTSCTS; /* RTS/CTS (hard) */
- break;
- case FLO_DTRT: temp.c_cflag |= CDTRCTS; /* DTR/CTS (hard) */
- break;
- }
- }
- x = ioctl(ttyfd,TCSETS,&temp);
- }
-#endif /* OXOS */
- return(x);
-
-#endif /* Plan9 */
-}
-
-/* T T P K T -- Condition the communication line for packets */
-/* or for modem dialing */
-
-/*
- If called with speed > -1, also set the speed.
- Returns 0 on success, -1 on failure.
-
- NOTE: the "xflow" parameter is supposed to be the currently selected
- type of flow control, but for historical reasons, this parameter is also
- used to indicate that we are dialing. Therefore, when the true flow
- control setting is needed, we access the external variable "flow", rather
- than trusting our "xflow" argument.
-*/
-int
-#ifdef CK_ANSIC
-ttpkt(long speed, int xflow, int parity)
-#else
-ttpkt(speed,xflow,parity) long speed; int xflow, parity;
-#endif /* CK_ANSIC */
-/* ttpkt */ {
-#ifndef NOLOCAL
- int s2;
- int s = -1;
-#endif /* NOLOCAL */
- int x;
- extern int flow; /* REAL flow-control setting */
-
- if (ttyfd < 0) return(-1); /* Not open. */
-
- debug(F101,"ttpkt parity","",parity);
- debug(F101,"ttpkt xflow","",xflow);
- debug(F101,"ttpkt speed","",(int) speed);
-
- ttprty = parity; /* Let other tt functions see these. */
- ttspeed = speed; /* Make global copy for this module */
- ttpmsk = ttprty ? 0177 : 0377; /* Parity stripping mask */
-#ifdef PARSENSE
- needpchk = ttprty ? 0 : 1; /* Parity check needed? */
-#else
- needpchk = 0;
-#endif /* PARSENSE */
-
- debug(F101,"ttpkt ttpmsk","",ttpmsk);
- debug(F101,"ttpkt netconn","",netconn);
-
-#ifdef NETCONN /* No mode-changing for telnet */
- if (netconn) {
-#ifdef TCPSOCKET
-#ifdef TCP_NODELAY
- if (ttnet == NET_TCPB) { /* But turn off Nagle */
- extern int tcp_nodelay;
- nodelay_sav = tcp_nodelay;
- no_delay(ttyfd,1);
- }
-#endif /* TCP_NODELAY */
-#ifdef TN_COMPORT
- if (istncomport()) {
- int rc = -1;
- if (tvtflg == 0 && speed == ttspeed && flow == ttflow
- /* && ttcarr == curcarr */ ) {
- debug(F100,"ttpkt modes already set, skipping...","",0);
- return(0); /* Already been called. */
- }
- if (flow != ttflow) {
- if ((rc = tnsetflow(flow)) < 0)
- return(rc);
- ttflow = flow;
- }
- if (speed != ttspeed) {
- if (speed <= 0)
- speed = tnc_get_baud();
- else if ((rc = tnc_set_baud(speed)) < 0)
- return(rc);
- ttspeed = speed;
- }
- tnc_set_datasize(8);
- tnc_set_stopsize(stopbits);
-
-#ifdef HWPARITY
- if (hwparity) {
- switch (hwparity) {
- case 'e': /* Even */
- debug(F100,"ttres 8 bits + even parity","",0);
- tnc_set_parity(3);
- break;
- case 'o': /* Odd */
- debug(F100,"ttres 8 bits + odd parity","",0);
- tnc_set_parity(2);
- break;
- case 'm': /* Mark */
- debug(F100,"ttres 8 bits + invalid parity: mark","",0);
- tnc_set_parity(4);
- break;
- case 's': /* Space */
- debug(F100,"ttres 8 bits + invalid parity: space","",0);
- tnc_set_parity(5);
- break;
- }
- } else
-#endif /* HWPARITY */
- {
- tnc_set_parity(1); /* None */
- }
- tvtflg = 0;
- return(0);
- }
-#endif /* TN_COMPORT */
-#endif /* TCPSOCKET */
- tvtflg = 0;
- return(0);
- }
-#endif /* NETCONN */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-
-#ifndef Plan9
- if (ttfdflg && !isatty(ttyfd)) return(0);
-#endif /* Plan9 */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifndef SVORPOSIX /* Berkeley, V7, etc. */
-#ifdef LPASS8
-/*
- For some reason, with BSD terminal drivers, you can't set FLOW to XON/XOFF
- after having previously set it to NONE without closing and reopening the
- device. Unless there's something I overlooked below...
-*/
- if (ttflow == FLO_NONE && flow == FLO_XONX && xlocal == 0) {
- debug(F101,"ttpkt executing horrible flow kludge","",0);
- ttclos(0); /* Close it */
- x = 0;
- ttopen(ttnmsv,&x,ttmdm,0); /* Open it again */
- }
-#endif /* LPASS8 */
-#endif /* SVORPOSIX */
-
-#ifdef COHERENT /* This must be vestigial since we */
-#undef SVORPOSIX /* reverse it a few lines below... */
-#endif /* COHERENT */
-
- if (xflow != FLO_DIAL && xflow != FLO_DIAX)
- ttflow = xflow; /* Now make this available too. */
-
-#ifndef NOLOCAL
- if (xlocal) {
- s2 = (int) (speed / 10L); /* Convert bps to cps */
- debug(F101,"ttpkt calling ttsspd","",s2);
- s = ttsspd(s2); /* Check and set the speed */
- debug(F101,"ttpkt ttsspd result","",s);
- carrctl(&ttraw, xflow != FLO_DIAL /* Carrier control */
- && (ttcarr == CAR_ON || (ttcarr == CAR_AUT && ttmdm != 0)));
- tvtflg = 0; /* So ttvt() will work next time */
- }
-#endif /* NOLOCAL */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifndef SVORPOSIX /* BSD section */
- if (flow == FLO_RTSC || /* Hardware flow control */
- flow == FLO_DTRC ||
- flow == FLO_DTRT) {
- tthflow(flow, 1, &ttraw);
- debug(F100,"ttpkt hard flow, TANDEM off, RAW on","",0);
- ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
- ttraw.sg_flags |= RAW; /* Enter raw mode */
- } else if (flow == FLO_NONE) { /* No flow control */
- debug(F100,"ttpkt no flow, TANDEM off, RAW on","",0);
- ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
- tthflow(flow, 0, &ttraw); /* Turn off any hardware f/c too */
- ttraw.sg_flags |= RAW; /* Enter raw mode */
- } else if (flow == FLO_KEEP) { /* Keep device's original setting */
- debug(F100,"ttpkt keeping original TANDEM","",0);
- ttraw.sg_flags &= ~TANDEM;
- ttraw.sg_flags |= (ttold.sg_flags & TANDEM);
- /* NOTE: We should also handle hardware flow control here! */
- }
-
-/* SET FLOW XON/XOFF is in effect, or SET FLOW KEEP resulted in Xon/Xoff */
-
- if ((flow == FLO_XONX) || (ttraw.sg_flags & TANDEM)) {
- debug(F100,"ttpkt turning on TANDEM","",0);
- ttraw.sg_flags |= TANDEM; /* So ask for it. */
-
-#ifdef LPASS8 /* Can pass 8-bit data through? */
-/* If the LPASS8 local mode is available, then flow control can always */
-/* be used, even if parity is none and we are transferring 8-bit data. */
-/* But we only need to do all this if Xon/Xoff is requested. */
-/* BUT... this tends not to work through IP or LAT connections, terminal */
-/* servers, telnet, rlogin, etc, so it is currently disabled. */
- x = LPASS8; /* If LPASS8 defined, then */
- debug(F100,"ttpkt executing LPASS8 code","",0);
- if (lmodef) { /* TIOCLBIS must be too. */
- x = ioctl(ttyfd,TIOCLBIS,&x); /* Try to set LPASS8. */
- if (x < 0) {
- debug(F100,"ttpkt TIOCLBIS error","",0);
- } else {
- lmodef++;
- debug(F100,"ttpkt TIOCLBIS ok","",0);
- }
- }
-/*
- But if we use LPASS8 mode, we must explicitly turn off
- terminal interrupts of all kinds.
-*/
-#ifdef TIOCGETC /* Not rawmode, */
- if (tcharf && (xlocal == 0)) { /* must turn off */
- tchnoi.t_intrc = -1; /* interrupt character */
- tchnoi.t_quitc = -1; /* and quit character. */
- tchnoi.t_startc = 17; /* Make sure xon */
- tchnoi.t_stopc = 19; /* and xoff not ignored. */
-#ifndef NOBRKC
- tchnoi.t_eofc = -1; /* eof character. */
- tchnoi.t_brkc = -1; /* brk character. */
-#endif /* NOBRKC */
- if (ioctl(ttyfd,TIOCSETC,&tchnoi) < 0) {
- debug(F100,"ttpkt TIOCSETC failed","",0);
- } else {
- tcharf = 1;
- debug(F100,"ttpkt TIOCSETC ok","",0);
- }
-#ifdef COMMENT
-/* only for paranoid debugging */
- if (tcharf) {
- struct tchars foo;
- char tchbuf[100];
- ioctl(0,TIOCGETC,&foo);
- sprintf(tchbuf,
- "intr=%d,quit=%d, start=%d, stop=%d, eof=%d, brk=%d",
- foo.t_intrc, foo.t_quitc, foo.t_startc,
- foo.t_stopc, foo.t_eofc, foo.t_brkc);
- debug(F110,"ttpkt chars",tchbuf,0);
- }
-#endif /* COMMENT */
- }
- ttraw.sg_flags |= CBREAK; /* Needed for unknown reason */
-#endif /* TIOCGETC */
-
-/* Prevent suspend during packet mode */
-#ifdef TIOCGLTC /* Not rawmode, */
- if (ltcharf && (xlocal == 0)) { /* must turn off */
- ltchnoi.t_suspc = -1; /* suspend character */
- ltchnoi.t_dsuspc = -1; /* and delayed suspend character */
- if (ioctl(ttyfd,TIOCSLTC,&tchnoi) < 0) {
- debug(F100,"ttpkt TIOCSLTC failed","",0);
- } else {
- ltcharf = 1;
- debug(F100,"ttpkt TIOCSLTC ok","",0);
- }
- }
-#endif /* TIOCGLTC */
-
-#else /* LPASS8 not defined */
-
-/* Previously, BSD-based implementations always */
-/* used rawmode for packets. Now, we use rawmode only if parity is NONE. */
-/* This allows the flow control requested above to actually work, but only */
-/* if the user asks for parity (which also means they get 8th-bit quoting). */
-
- if (parity) { /* If parity, */
- ttraw.sg_flags &= ~RAW; /* use cooked mode */
-#ifdef COMMENT
-/* WHY??? */
- if (xlocal)
-#endif /* COMMENT */
- ttraw.sg_flags |= CBREAK;
- debug(F101,"ttpkt cooked, cbreak, parity","",parity);
-#ifdef TIOCGETC /* Not rawmode, */
- if (tcharf && (xlocal == 0)) { /* must turn off */
- tchnoi.t_intrc = -1; /* interrupt character */
- tchnoi.t_quitc = -1; /* and quit character. */
- tchnoi.t_startc = 17; /* Make sure xon */
- tchnoi.t_stopc = 19; /* and xoff not ignored. */
-#ifndef NOBRKC
- tchnoi.t_eofc = -1; /* eof character. */
- tchnoi.t_brkc = -1; /* brk character. */
-#endif /* NOBRKC */
- if (ioctl(ttyfd,TIOCSETC,&tchnoi) < 0) {
- debug(F100,"ttpkt TIOCSETC failed","",0);
- } else {
- tcharf = 1;
- debug(F100,"ttpkt TIOCSETC ok","",0);
- }
- }
-#endif /* TIOCGETC */
-#ifdef TIOCGLTC /* Not rawmode, */
-/* Prevent suspend during packet mode */
- if (ltcharf && (xlocal == 0)) { /* must turn off */
- ltchnoi.t_suspc = -1; /* suspend character */
- ltchnoi.t_dsuspc = -1; /* and delayed suspend character */
- if (ioctl(ttyfd,TIOCSLTC,&tchnoi) < 0) {
- debug(F100,"ttpkt TIOCSLTC failed","",0);
- } else {
- ltcharf = 1;
- debug(F100,"ttpkt TIOCSLTC ok","",0);
- }
- }
-#endif /* TIOCGLTC */
- } else { /* If no parity, */
- ttraw.sg_flags |= RAW; /* must use 8-bit raw mode. */
- debug(F101,"ttpkt setting rawmode, parity","",parity);
- }
-#endif /* LPASS8 */
- } /* End of Xon/Xoff section */
-
- /* Don't echo, don't map CR to CRLF on output, don't fool with case */
-#ifdef LCASE
- ttraw.sg_flags &= ~(ECHO|CRMOD|LCASE);
-#else
- ttraw.sg_flags &= ~(ECHO|CRMOD);
-#endif /* LCASE */
-
-#ifdef TOWER1
- ttraw.sg_flags &= ~ANYP; /* Must set this on old Towers */
-#endif /* TOWER1 */
-
-#ifdef BELLV10
- if (ioctl(ttyfd,TIOCSETP,&ttraw) < 0) /* Set the new modes. */
- return(-1);
-#else
- errno = 0;
- if (stty(ttyfd,&ttraw) < 0) { /* Set the new modes. */
- debug(F101,"ttpkt stty failed","",errno);
- return(-1);
- }
-#endif /* BELLV10 */
- debug(F100,"ttpkt stty ok","",0);
-
-#ifdef sony_news
- x = xlocal ? km_ext : km_con; /* Put line in ASCII mode. */
- if (x != -1) { /* Make sure we know original modes. */
- x &= ~KM_TTYPE;
- x |= KM_ASCII;
- if (ioctl(ttyfd,TIOCKSET, &x) < 0) {
- perror("ttpkt can't set ASCII mode");
- debug(F101,"ttpkt error setting ASCII mode","",x);
- return(-1);
- }
- }
- debug(F100,"ttpkt set ASCII mode ok","",0);
-#endif /* sony_news */
-
- if (xlocal == 0) { /* Turn this off so we can read */
- signal(SIGINT,SIG_IGN); /* Ctrl-C chars typed at console */
- sigint_ign = 1;
- }
- tvtflg = 0; /* So ttvt() will work next time */
- debug(F100,"ttpkt success","",0);
- return(0);
-
-#endif /* Not ATTSV or POSIX */
-
-/* AT&T UNIX and POSIX */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifdef SVORPOSIX
- if (flow == FLO_XONX) { /* Xon/Xoff */
- ttraw.c_iflag |= (IXON|IXOFF);
- tthflow(flow, 0, &ttraw);
- } else if (flow == FLO_NONE) { /* None */
- /* NOTE: We should also turn off hardware flow control here! */
- ttraw.c_iflag &= ~(IXON|IXOFF);
- tthflow(flow, 0, &ttraw);
- } else if (flow == FLO_KEEP) { /* Keep */
- ttraw.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff flags */
- ttraw.c_iflag |= (ttold.c_iflag & (IXON|IXOFF)); /* OR in old ones */
- /* NOTE: We should also handle hardware flow control here! */
-#ifdef POSIX_CRTSCTS
-/* In Linux case, we do this, which is unlikely to be portable */
- ttraw.c_cflag &= ~CRTSCTS; /* Turn off RTS/CTS flag */
- ttraw.c_cflag |= (ttold.c_cflag & CRTSCTS); /* OR in old one */
-#endif /* POSIX_CRTSCTS */
- } else if (flow == FLO_RTSC || /* Hardware */
- flow == FLO_DTRC ||
- flow == FLO_DTRT) {
- ttraw.c_iflag &= ~(IXON|IXOFF); /* (190) */
- tthflow(flow, 1, &ttraw);
- }
- ttraw.c_lflag &= ~(ICANON|ECHO);
- ttraw.c_lflag &= ~ISIG; /* Do NOT check for interrupt chars */
-
-#ifndef OXOS
-#ifdef QNX
- if (flow != FLO_RTSC && flow != FLO_DTRC && flow != FLO_DTRT)
-#endif /* QNX */
-#ifndef COHERENT
- ttraw.c_lflag &= ~IEXTEN; /* Turn off ^O/^V processing */
-#endif /* COHERENT */
-#else /* OXOS */
- ttraw.c_cc[VDISCARD] = ttraw.c_cc[VLNEXT] = CDISABLE;
-#endif /* OXOS */
- ttraw.c_lflag |= NOFLSH; /* Don't flush */
- ttraw.c_iflag |= IGNPAR; /* Ignore parity errors */
-#ifdef ATTSV
-#ifdef BSD44
- ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|INPCK|ISTRIP|IXANY);
-#else
- ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
-#endif /* BSD44 */
-#else /* POSIX */
- ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|INPCK|ISTRIP);
-#endif /* ATTSV */
- ttraw.c_oflag &= ~OPOST;
- ttraw.c_cflag &= ~(CSIZE);
- ttraw.c_cflag |= (CS8|CREAD|HUPCL);
-
-#ifdef CSTOPB
- if (xlocal) {
- if (stopbits == 2) {
- ttraw.c_cflag |= CSTOPB; /* 2 stop bits */
- debug(F100,"ttpkt 2 stopbits","",0);
- } else if (stopbits == 1) {
- ttraw.c_cflag &= ~(CSTOPB); /* 1 stop bit */
- debug(F100,"ttpkt 1 stopbit","",0);
- }
- }
-#endif /* CSTOPB */
-
-#ifdef HWPARITY
- if (hwparity && xlocal) { /* Hardware parity */
- ttraw.c_cflag |= PARENB; /* Enable parity */
-#ifdef COMMENT
-/* Uncomment this only if needed -- I don't think it is */
- ttraw.c_cflag &= ~(CSIZE); /* Clear out character-size mask */
- ttraw.c_cflag |= CS8; /* And set it to 8 */
-#endif /* COMMENT */
-#ifdef IGNPAR
- ttraw.c_iflag |= IGNPAR; /* Don't discard incoming bytes */
- debug(F100,"ttpkt IGNPAR","",0); /* that have parity errors */
-#endif /* IGNPAR */
- switch (hwparity) {
- case 'e': /* Even */
- ttraw.c_cflag &= ~(PARODD);
- debug(F100,"ttpkt 8 bits + even parity","",0);
- break;
- case 'o': /* Odd */
- ttraw.c_cflag |= PARODD;
- debug(F100,"ttpkt 8 bits + odd parity","",0);
- break;
- case 'm': /* Mark */
- case 's': /* Space */
- /* PAREXT is mentioned in SVID but the details are not given. */
- /* PAREXT is not included in POSIX ISO/IEC 9945-1. */
- debug(F100,"ttpkt 8 bits + invalid parity","",0);
- break;
- }
- } else { /* We handle parity ourselves */
-#endif /* HWPARITY */
- ttraw.c_cflag &= ~(PARENB); /* Don't enable parity */
-#ifdef HWPARITY
- }
-#endif /* HWPARITY */
-
-#ifdef IX370
- ttraw.c_cc[4] = 48; /* So Series/1 doesn't interrupt on every char */
- ttraw.c_cc[5] = 1;
-#else
-#ifndef VEOF /* for DGUX this is VEOF, not VMIN */
- ttraw.c_cc[4] = 1; /* [VMIN] return max of this many characters or */
-#else
-#ifndef OXOS
-#ifdef VMIN
- ttraw.c_cc[VMIN] = 1;
-#endif /* VMIN */
-#else /* OXOS */
- ttraw.c_min = 1;
-#endif /* OXOS */
-#endif /* VEOF */
-#ifndef VEOL /* for DGUX this is VEOL, not VTIME */
- ttraw.c_cc[5] = 0; /* [VTIME] when this many secs/10 expire w/no input */
-#else
-#ifndef OXOS
-#ifdef VTIME
- ttraw.c_cc[VTIME] = 0;
-#endif /* VTIME */
-#else /* OXOS */
- ttraw.c_time = 0;
-#endif /* OXOS */
-#endif /* VEOL */
-#endif /* IX370 */
-
-#ifdef VINTR /* Turn off interrupt character */
- if (xlocal == 0) /* so ^C^C can break us out of */
- ttraw.c_cc[VINTR] = 0; /* packet mode. */
-#endif /* VINTR */
-
-#ifdef Plan9
- if (p9ttyparity('n') < 0)
- return -1;
-#else
-#ifdef BSD44ORPOSIX
- errno = 0;
-#ifdef BEOSORBEBOX
- ttraw.c_cc[VMIN] = 0; /* DR7 can only poll. */
-#endif /* BEOSORBEBOX */
-
-#define TESTING234
-#ifdef TESTING234
- if (1) {
- debug(F100,"ttpkt TESTING234 rawmode","",0);
-
- /* iflags */
- ttraw.c_iflag &= ~(PARMRK|ISTRIP|BRKINT|INLCR|IGNCR|ICRNL);
- ttraw.c_iflag &= ~(INPCK|IGNPAR|IXON|IXOFF);
- ttraw.c_iflag |= IGNBRK;
-#ifdef IMAXBEL
- ttraw.c_iflag &= ~IMAXBEL;
-#endif /* IMAXBEL */
-#ifdef IXANY
- ttraw.c_iflag &= ~IXANY;
-#endif /* IXANY */
-#ifdef IUCLC
- ttraw.c_iflag &= ~IUCLC;
-#endif /* IUCLC */
-
- /* oflags */
- ttraw.c_oflag &= ~OPOST;
-#ifdef OXTABS
- ttraw.c_oflag &= ~OXTABS;
-#endif /* OXTABS */
-#ifdef ONOCR
- ttraw.c_oflag &= ~ONOCR;
-#endif /* ONOCR */
-#ifdef ONLRET
- ttraw.c_oflag &= ~ONLRET;
-#endif /* ONLRET */
-#ifdef ONLCR
- ttraw.c_oflag &= ~ONLCR;
-#endif /* ONLCR */
-
- /* lflags */
- ttraw.c_lflag &= ~ECHO;
-#ifdef ECHOE
- ttraw.c_lflag &= ~ECHOE;
-#endif /* ECHOE */
-#ifdef ECHONL
- ttraw.c_lflag &= ~ECHONL;
-#endif /* ECHONL */
-#ifdef ECHOPRT
- ttraw.c_lflag &= ~ECHOPRT;
-#endif /* ECHOPRT */
-#ifdef ECHOKE
- ttraw.c_lflag &= ~ECHOKE;
-#endif /* ECHOKE */
-#ifdef ECHOCTL
- ttraw.c_lflag &= ~ECHOCTL;
-#endif /* ECHOCTL */
-#ifdef ALTWERASE
- ttraw.c_lflag &= ~ALTWERASE;
-#endif /* ALTWERASE */
-#ifdef EXTPROC
- ttraw.c_lflag &= ~EXTPROC;
-#endif /* EXTPROC */
- ttraw.c_lflag &= ~(ICANON|ISIG|IEXTEN|TOSTOP|FLUSHO|PENDIN);
-#ifdef NOKERNINFO
- ttraw.c_lflag |= NOKERNINFO;
-#endif /* NOKERNINFO */
- /* ttraw.c_lflag |= NOFLSH; */
- ttraw.c_lflag &= ~NOFLSH;
-
- /* cflags */
- ttraw.c_cflag &= ~(CSIZE|PARENB|PARODD);
- ttraw.c_cflag |= CS8|CREAD;
-#ifdef VMIN
- ttraw.c_cc[VMIN] = 1; /* Supposedly needed for AIX */
-#endif /* VMIN */
-
- }
-#endif /* TESTING234 */
-
- debug(F100,"ttpkt calling tcsetattr(TCSETAW)","",0);
- x = tcsetattr(ttyfd,TCSADRAIN,&ttraw);
- debug(F101,"ttpkt BSD44ORPOSIX tcsetattr","",x);
- if (x < 0) {
- debug(F101,"ttpkt BSD44ORPOSIX tcsetattr errno","",errno);
- return(-1);
- }
-#else /* BSD44ORPOSIX */
- x = ioctl(ttyfd,TCSETAW,&ttraw);
- debug(F101,"ttpkt ATTSV ioctl TCSETAW","",x);
- if (x < 0) { /* set new modes . */
- debug(F101,"ttpkt ATTSV ioctl TCSETAW errno","",errno);
- return(-1);
- }
-#endif /* BSD44ORPOSIX */
-#endif /* Plan9 */
- tvtflg = 0;
- debug(F100,"ttpkt ok","",0);
- return(0);
-#endif /* ATTSV */
-
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
-}
-
-/* T T S E T F L O W -- Set flow control immediately. */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-int
-ttsetflow(flow) int flow; {
- if (ttyfd < 0) /* A channel must be open */
- return(-1);
-
- debug(F101,"ttsetflow flow","",flow);
-
-#ifdef TN_COMPORT
- if (netconn && istncomport()) {
- debug(F101,"ttsetflow net modem","",ttmdm);
- return(tnsetflow(flow));
- }
-#endif /* TN_COMPORT */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-
-#ifdef COMMENT
- /* This seems to hurt... */
- if (flow == FLO_KEEP)
- return(0);
-#endif /* COMMENT */
-
- if (flow == FLO_RTSC || /* Hardware flow control... */
- flow == FLO_DTRC ||
- flow == FLO_DTRT) {
- tthflow(flow, 1, &ttraw);
-#ifndef SVORPOSIX
- ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
-#else
- ttraw.c_iflag &= ~(IXON|IXOFF);
-#endif /* SVORPOSIX */
-
- } else if (flow == FLO_XONX) { /* Xon/Xoff... */
-
-#ifndef SVORPOSIX
- ttraw.sg_flags |= TANDEM;
-#else
- ttraw.c_iflag |= (IXON|IXOFF);
-#endif /* SVORPOSIX */
- tthflow(FLO_RTSC, 0, &ttraw); /* Turn off hardware flow control */
-
- } else if (flow == FLO_NONE) { /* No flow control */
-
-#ifndef SVORPOSIX
- ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
-#else
- ttraw.c_iflag &= ~(IXON|IXOFF);
-#endif /* SVORPOSIX */
- tthflow(FLO_RTSC, 0, &ttraw); /* Turn off any hardware f/c too */
- }
-
-/* Set the new modes... */
-
-#ifndef SVORPOSIX /* BSD and friends */
-#ifdef BELLV10
- if (ioctl(ttyfd,TIOCSETP,&ttraw) < 0)
- return(-1);
-#else
-#ifndef MINIX2
- if (stty(ttyfd,&ttraw) < 0)
- return(-1);
-#endif /* MINIX2 */
-#endif /* BELLV10 */
-#else
-#ifdef BSD44ORPOSIX /* POSIX */
- if (tcsetattr(ttyfd,TCSADRAIN,&ttraw) < 0)
- return(-1);
-#else /* System V */
- if (ioctl(ttyfd,TCSETAW,&ttraw) < 0)
- return(-1);
-#endif /* BSD44ORPOSIX */
-#endif /* SVORPOSIX */
- return(0);
-}
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
-/* T T V T -- Condition communication device for use as virtual terminal. */
-
-int
-#ifdef CK_ANSIC
-ttvt(long speed, int flow)
-#else
-ttvt(speed,flow) long speed; int flow;
-#endif /* CK_ANSIC */
-/* ttvt */ {
- int s, s2, x;
-
- debug(F101,"ttvt ttyfd","",ttyfd);
- debug(F101,"ttvt tvtflg","",tvtflg);
- debug(F111,"ttvt speed",ckitoa(ttspeed),speed);
- debug(F111,"ttvt flow",ckitoa(ttflow),flow);
- debug(F111,"ttvt curcarr",ckitoa(ttcarr),curcarr);
-
-/* Note: NetBSD and maybe other BSD44s have cfmakeraw() */
-/* Maybe it would be simpler to use it... */
-
- ttpmsk = 0xff;
-#ifdef NOLOCAL
- return(conbin((char)escchr));
-#else
- if (ttyfd < 0) { /* Not open. */
- if (ttchk() < 0)
- return(-1);
- else /* But maybe something buffered. */
- return(0);
- }
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-#ifdef NETCONN
- if (netconn) {
-#ifdef TCPSOCKET
-#ifdef TCP_NODELAY
- {
- extern int tcp_nodelay;
- if (ttnet == NET_TCPB) {
- if (nodelay_sav > -1) {
- no_delay(ttyfd,nodelay_sav);
- nodelay_sav = -1;
- }
- }
- }
-#endif /* TCP_NODELAY */
-#ifdef TN_COMPORT
- if (istncomport()) {
- int rc = -1;
- if (tvtflg != 0 && speed == ttspeed && flow == ttflow
- /* && ttcarr == curcarr */ ) {
- debug(F100,"ttvt modes already set, skipping...","",0);
- return(0); /* Already been called. */
- }
- if (flow != ttflow) {
- if ((rc = tnsetflow(flow)) < 0)
- return(rc);
- ttflow = flow;
- }
- if (speed != ttspeed) {
- if (speed <= 0)
- speed = tnc_get_baud();
- else if ((rc = tnc_set_baud(speed)) < 0)
- return(rc);
- ttspeed = speed;
- }
- tnc_set_datasize(8);
- tnc_set_stopsize(stopbits);
-
-#ifdef HWPARITY
- if (hwparity) {
- switch (hwparity) {
- case 'e': /* Even */
- debug(F100,"ttres 8 bits + even parity","",0);
- tnc_set_parity(3);
- break;
- case 'o': /* Odd */
- debug(F100,"ttres 8 bits + odd parity","",0);
- tnc_set_parity(2);
- break;
- case 'm': /* Mark */
- debug(F100,"ttres 8 bits + invalid parity: mark","",0);
- tnc_set_parity(4);
- break;
- case 's': /* Space */
- debug(F100,"ttres 8 bits + invalid parity: space","",0);
- tnc_set_parity(5);
- break;
- }
- } else
-#endif /* HWPARITY */
- {
- tnc_set_parity(1); /* None */
- }
- tvtflg = 1;
- return(0);
- }
-#endif /* TN_COMPORT */
-#endif /* TCPSOCKET */
- tvtflg = 1; /* Network connections... */
- debug(F100,"ttvt network connection, skipping...","",0);
- return(0); /* ... require no special setup */
- }
-#endif /* NETCONN */
-
- if (tvtflg != 0 && speed == ttspeed && flow == ttflow
- /* && ttcarr == curcarr */ )
- {
- debug(F100,"ttvt modes already set, skipping...","",0);
- return(0); /* Already been called. */
- }
-
- if (ttfdflg
-#ifndef Plan9
- && !isatty(ttyfd)
-#endif /* Plan9 */
- ) {
- debug(F100,"ttvt using external fd, skipping...","",0);
- return(0);
- }
-
- debug(F100,"ttvt setting modes...","",0);
-
- if (xlocal) { /* For external lines... */
- s2 = (int) (speed / 10L);
- s = ttsspd(s2); /* Check/set the speed */
- carrctl(&tttvt, flow != FLO_DIAL /* Do carrier control */
- && (ttcarr == CAR_ON || (ttcarr == CAR_AUT && ttmdm != 0)));
- } else
- s = s2 = -1;
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifndef SVORPOSIX
- /* Berkeley, V7, etc */
- if (flow == FLO_RTSC || /* Hardware flow control */
- flow == FLO_DTRC ||
- flow == FLO_DTRT) {
- tthflow(flow, 1, &tttvt);
- debug(F100,"ttvt hard flow, TANDEM off","",0);
- tttvt.sg_flags &= ~TANDEM; /* Turn off software flow control */
- } else if (flow == FLO_XONX) { /* Xon/Xoff flow control */
- debug(F100,"ttvt TANDEM on","",0);
- tttvt.sg_flags |= TANDEM; /* Ask for it. */
- tthflow(flow, 0, &tttvt); /* Turn off hardware f/c */
- } else if (flow == FLO_NONE) {
- debug(F100,"ttvt no flow, TANDEM off, RAW on","",0);
- tttvt.sg_flags &= ~TANDEM; /* Turn off software flow control */
- tthflow(flow, 0, &tttvt); /* Turn off any hardware f/c too */
- tttvt.sg_flags |= RAW; /* Enter raw mode */
- } else if (flow == FLO_KEEP) { /* Keep device's original setting */
- debug(F100,"ttvt keeping original TANDEM","",0);
- tttvt.sg_flags &= ~TANDEM;
- tttvt.sg_flags |= (ttold.sg_flags & TANDEM);
- /* NOTE: We should also handle hardware flow control here! */
- }
- tttvt.sg_flags |= RAW; /* Raw mode in all cases */
-#ifdef TOWER1
- tttvt.sg_flags &= ~(ECHO|ANYP); /* No echo or parity */
-#else
- tttvt.sg_flags &= ~ECHO; /* No echo */
-#endif /* TOWER1 */
-
-#ifdef BELLV10
- if (ioctl(ttyfd,TIOCSETP,&tttvt) < 0) /* Set the new modes */
- return(-1);
-#else
- if (stty(ttyfd,&tttvt) < 0) /* Set the new modes */
- return(-1);
-#endif /* BELLV10 */
-
-#else /* It is ATTSV or POSIX */
-
- if (flow == FLO_XONX) { /* Software flow control */
- tttvt.c_iflag |= (IXON|IXOFF); /* On if requested. */
- tthflow(flow, 0, &tttvt); /* Turn off hardware f/c */
- debug(F100,"ttvt SVORPOSIX flow XON/XOFF","",0);
- } else if (flow == FLO_NONE) { /* NONE */
- tttvt.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff */
- tthflow(flow, 0, &tttvt); /* Turn off hardware f/c */
- debug(F100,"ttvt SVORPOSIX flow NONE","",0);
- } else if (flow == FLO_KEEP) {
- tttvt.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff flags */
- tttvt.c_iflag |= (ttold.c_iflag & (IXON|IXOFF)); /* OR in old ones */
-#ifdef POSIX_CRTSCTS
- tttvt.c_cflag &= ~CRTSCTS; /* Turn off RTS/CTS flag */
- tttvt.c_cflag |= (ttold.c_cflag & CRTSCTS); /* OR in old one */
-#endif /* POSIX_CRTSCTS */
- debug(F100,"ttvt SVORPOSIX flow KEEP","",0);
- } else if (flow == FLO_RTSC || /* Hardware flow control */
- flow == FLO_DTRC ||
- flow == FLO_DTRT) {
- tttvt.c_iflag &= ~(IXON|IXOFF); /* (196) */
- tthflow(flow, 1, &tttvt);
- debug(F100,"ttvt SVORPOSIX flow HARD","",0);
- }
-#ifndef OXOS
-#ifdef COHERENT
- tttvt.c_lflag &= ~(ISIG|ICANON|ECHO);
-#else
- tttvt.c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
-#endif /* COHERENT */
-#ifdef QNX
- /* Needed for hwfc */
- if (flow == FLO_RTSC || flow == FLO_DTRC || flow == FLO_DTRT)
- tttvt.c_lflag |= IEXTEN;
-#endif /* QNX */
-#else /* OXOS */
- tttvt.c_lflag &= ~(ISIG|ICANON|ECHO);
- tttvt.c_cc[VDISCARD] = tttvt.c_cc[VLNEXT] = CDISABLE;
-#endif /* OXOS */
-
- tttvt.c_iflag |= (IGNBRK|IGNPAR);
-
-/* Stop bits */
-
-#ifdef CSTOPB
- if (xlocal) {
- if (stopbits == 2) {
- tttvt.c_cflag |= CSTOPB; /* 2 stop bits */
- debug(F100,"ttvt 2 stopbits","",0);
- } else if (stopbits == 1) {
- tttvt.c_cflag &= ~(CSTOPB); /* 1 stop bit */
- debug(F100,"ttvt 1 stopbit","",0);
- }
- }
-#endif /* CSTOPB */
-
-/* Parity */
-
-#ifdef HWPARITY
- if (hwparity && xlocal) { /* Hardware parity */
-#ifdef COMMENT
-/* Uncomment this only if needed -- I don't think it is */
- ttraw.c_cflag &= ~(CSIZE); /* Clear out character-size mask */
- ttraw.c_cflag |= CS8; /* And set it to 8 */
-#endif /* COMMENT */
-#ifdef IGNPAR
- debug(F101,"ttvt hwparity IGNPAR","",IGNPAR);
- tttvt.c_iflag |= IGNPAR; /* Don't discard incoming bytes */
-#endif /* IGNPAR */
- tttvt.c_cflag |= PARENB; /* Enable parity */
-
- switch (hwparity) {
- case 'e': /* Even */
- tttvt.c_cflag &= ~(PARODD);
- debug(F100,"ttvt 8 bits + even parity","",0);
- break;
- case 'o': /* Odd */
- tttvt.c_cflag |= PARODD;
- debug(F100,"ttvt 8 bits + odd parity","",0);
- break;
- case 'm': /* Mark */
- case 's': /* Space */
- /* PAREXT is mentioned in SVID but the details are not given. */
- /* PAREXT is not included in POSIX ISO/IEC 9945-1. */
- debug(F100,"ttvt 8 bits + invalid parity","",0);
- break;
- }
- } else { /* We handle parity ourselves */
-#endif /* HWPARITY */
- tttvt.c_cflag &= ~(PARENB); /* Don't enable parity */
-#ifdef HWPARITY
- }
-#endif /* HWPARITY */
-
-#ifdef ATTSV
-#ifdef BSD44
- /* Things not to do... */
- tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|INPCK|ISTRIP|IXANY);
-#else
- tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
-#endif /* BSD44 */
-#else /* POSIX */
- tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|INPCK|ISTRIP);
-#endif /* ATTSV */
- tttvt.c_cflag &= ~(CSIZE); /* Zero out the char size field */
- tttvt.c_cflag |= (CS8|CREAD|HUPCL); /* Char size 8, enable receiver, hup */
- tttvt.c_oflag &= ~OPOST; /* Don't postprocess output */
-#ifndef VEOF /* DGUX termio has VEOF at entry 4, see comment above */
- tttvt.c_cc[4] = 1;
-#else
-#ifndef OXOS
-#ifdef VMIN
- tttvt.c_cc[VMIN] = 1;
-#endif /* VMIN */
-#else /* OXOS */
- tttvt.c_min = 1;
-#endif /* OXOS */
-#endif /* VEOF */
-#ifndef VEOL /* DGUX termio has VEOL at entry 5, see comment above */
- tttvt.c_cc[5] = 0;
-#else
-#ifndef OXOS
-#ifdef VTIME
- tttvt.c_cc[VTIME] = 0;
-#endif /* VTIME */
-#else /* OXOS */
- tttvt.c_time = 0;
-#endif /* OXOS */
-#endif /* VEOL */
-
-#ifdef Plan9
- if (p9ttyparity('n') < 0)
- return -1;
-#else
-#ifdef BSD44ORPOSIX
- errno = 0;
-#ifdef BEOSORBEBOX
- tttvt.c_cc[VMIN] = 0; /* DR7 can only poll. */
-#endif /* BEOSORBEBOX */
-
- x = tcsetattr(ttyfd,TCSADRAIN,&tttvt);
- debug(F101,"ttvt BSD44ORPOSIX tcsetattr","",x);
- if (x < 0) {
- debug(F101,"ttvt BSD44ORPOSIX tcsetattr errno","",errno);
- return(-1);
- }
-#else /* ATTSV */
- x = ioctl(ttyfd,TCSETAW,&tttvt);
- debug(F101,"ttvt ATTSV ioctl TCSETAW","",x);
- if (x < 0) { /* set new modes . */
- debug(F101,"ttvt ATTSV ioctl TCSETAW errno","",errno);
- return(-1);
- }
-#endif /* BSD44ORPOSIX */
-#endif /* Plan9 */
-#endif /* ATTSV */
-
- ttspeed = speed; /* Done, remember how we were */
- ttflow = flow; /* called, so we can decide how to */
- tvtflg = 1; /* respond next time. */
- debug(F100,"ttvt ok","",0);
- return(0);
-
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
-#endif /* NOLOCAL */
-}
-
-#ifndef NOLOCAL
-
-/* Serial speed department . . . */
-
-/*
- SCO OSR5.0.x might or might not support high speeds. Sometimes they are not
- defined in the header files but they are supported (e.g. when building with
- UDK compiler rather than /bin/cc), sometimes vice versa. Even though 5.0.4
- was the first release that came with high serial speeds standard, releases
- back to 5.0.0 could use them if certain patches (or "supplements") were
- applied to the SIO driver. Plus a lot of SCO installations run third-party
- drivers.
-*/
-#ifdef CK_SCOV5
-#ifndef B38400
-#define B38400 0000017
-#endif /* B38400 */
-#ifndef B57600
-#define B57600 0000021
-#endif /* B57600 */
-#ifndef B76800
-#define B76800 0000022
-#endif /* B76800 */
-#ifndef B115200
-#define B115200 0000023
-#endif /* B115200 */
-#ifndef B230400
-#define B230400 0000024
-#endif /* B230400 */
-#ifndef B460800
-#define B460800 0000025
-#endif /* B460800 */
-#ifndef B921600
-#define B921600 0000026
-#endif /* B921600 */
-#endif /* CK_SCOV5 */
-/*
- Plan 9's native speed setting interface lets you set anything you like,
- but will fail if the hardware doesn't like it, so we allow all the common
- speeds.
-*/
-#ifdef Plan9
-#ifndef B50
-#define B50 50
-#endif /* B50 */
-#ifndef B75
-#define B75 75
-#endif /* B75 */
-#ifndef B110
-#define B110 110
-#endif /* B110 */
-#ifndef B134
-#define B134 134
-#endif /* B134 */
-#ifndef B200
-#define B200 200
-#endif /* B200 */
-#ifndef B300
-#define B300 300
-#endif /* B300 */
-#ifndef B1200
-#define B1200 1200
-#endif /* B1200 */
-#ifndef B1800
-#define B1800 1800
-#endif /* B1800 */
-#ifndef B2400
-#define B2400 2400
-#endif /* B2400 */
-#ifndef B4800
-#define B4800 4800
-#endif /* B4800 */
-#ifndef B9600
-#define B9600 9600
-#endif /* B9600 */
-#ifndef B14400
-#define B14400 14400
-#endif /* B14400 */
-#ifndef B19200
-#define B19200 19200
-#endif /* B19200 */
-#ifndef B28800
-#define B28800 28800
-#endif /* B28800 */
-#ifndef B38400
-#define B38400 38400
-#endif /* B38400 */
-#ifndef B57600
-#define B57600 57600
-#endif /* B57600 */
-#ifndef B76800
-#define B76800 76800
-#endif /* B76800 */
-#ifndef B115200
-#define B115200 115200
-#endif /* B115200 */
-#ifndef B230400
-#define B230400 230400
-#endif /* B230400 */
-#ifndef B460800
-#define B460800 460800
-#endif /* B460800 */
-#ifndef B921600
-#define B921600 921600
-#endif /* B921600 */
-#endif /* Plan9 */
-
-/* T T S S P D -- Checks and sets transmission rate. */
-
-/* Call with speed in characters (not bits!) per second. */
-/* Returns -1 on failure, 0 if it did nothing, 1 if it changed the speed. */
-
-#ifdef USETCSETSPEED
-/*
- The tcsetspeed() / tcgetspeed() interface lets you pass any number at all
- to be used as a speed to be set, rather than forcing a choice from a
- predefined list. It seems to be peculiar to UnixWare 7.
-
- These are the function codes to be passed to tc[gs]etspeed(),
- but for some reason they don't seem to be picked up from termios.h.
-*/
-#ifndef TCS_ALL
-#define TCS_ALL 0
-#endif /* TCS_ALL */
-#ifndef TCS_IN
-#define TCS_IN 1
-#endif /* TCS_IN */
-#ifndef TCS_OUT
-#define TCS_OUT 2
-#endif /* TCS_OUT */
-#endif /* USETCSETSPEED */
-
-int
-ttsspd(cps) int cps; {
- int x;
-#ifdef POSIX
-/* Watch out, speed_t should be unsigned, so don't compare with -1, etc... */
- speed_t
-#else
- int
-#endif /* POSIX */
- s, s2;
- int ok = 1; /* Speed check result, assume ok */
-
-#ifdef OLINUXHISPEED
- unsigned int spd_flags = 0;
- struct serial_struct serinfo;
-#endif /* OLINUXHISPEED */
-
- debug(F101,"ttsspd cps","",cps);
- debug(F101,"ttsspd ttyfd","",ttyfd);
- debug(F101,"ttsspd xlocal","",xlocal);
-
- if (ttyfd < 0 || xlocal == 0) /* Don't set speed on console */
- return(0);
-
-#ifdef NETCONN
- if (netconn) {
-#ifdef TN_COMPORT
- if (istncomport())
- return(tnc_set_baud(cps * 10));
- else
-#endif /* TN_COMPORT */
- return(0);
- }
-#endif /* NETCONN */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-
- if (cps < 0) return(-1);
- s = s2 = 0; /* NB: s and s2 might be unsigned */
-
-#ifdef USETCSETSPEED
-
- s = cps * 10L;
-
- x = tcgetattr(ttyfd,&ttcur); /* Get current speed */
- debug(F101,"ttsspd tcgetattr","",x);
- if (x < 0)
- return(-1);
- debug(F101,"ttsspd TCSETSPEED speed","",s);
-
- errno = 0;
- if (s == 8880L) { /* 75/1200 split speed requested */
- tcsetspeed(TCS_IN, &ttcur, 1200L);
- tcsetspeed(TCS_OUT, &ttcur, 75L);
- } else
- tcsetspeed(TCS_ALL, &ttcur, s); /* Put new speed in structs */
-#ifdef DEBUG
- if (errno & deblog) {
- debug(F101,"ttsspd TCSETSPEED errno","",errno);
- }
-#endif /* DEBUG */
-
-#ifdef COMMENT
- tcsetspeed(TCS_ALL, &ttraw, s);
- tcsetspeed(TCS_ALL, &tttvt, s);
- tcsetspeed(TCS_ALL, &ttold, s);
-#else
- if (s == 8880L) { /* 75/1200 split speed requested */
- tcsetspeed(TCS_IN, &ttraw, 1200L);
- tcsetspeed(TCS_OUT, &ttraw, 75L);
- tcsetspeed(TCS_IN, &tttvt, 1200L);
- tcsetspeed(TCS_OUT, &tttvt, 75L);
- tcsetspeed(TCS_IN, &ttold, 1200L);
- tcsetspeed(TCS_OUT, &ttold, 75L);
- } else {
- tcsetspeed(TCS_ALL, &ttraw, s);
- tcsetspeed(TCS_ALL, &tttvt, s);
- tcsetspeed(TCS_ALL, &ttold, s);
- }
-#endif /* COMMENT */
-
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur); /* Set the speed */
- debug(F101,"ttsspd tcsetattr","",x);
- if (x < 0)
- return(-1);
-
-#else /* Not USETCSETSPEED */
-
- /* First check that the given speed is valid. */
-
- switch (cps) {
-#ifndef MINIX
- case 0: s = B0; break;
- case 5: s = B50; break;
- case 7: s = B75; break;
-#endif /* MINIX */
- case 11: s = B110; break;
-#ifndef MINIX
- case 13: s = B134; break;
- case 15: s = B150; break;
- case 20: s = B200; break;
-#endif /* MINIX */
- case 30: s = B300; break;
-#ifndef MINIX
- case 60: s = B600; break;
-#endif /* MINIX */
- case 120: s = B1200; break;
-#ifndef MINIX
- case 180: s = B1800; break;
-#endif /* MINIX */
- case 240: s = B2400; break;
- case 480: s = B4800; break;
-#ifndef MINIX
- case 888: s = B75; s2 = B1200; break; /* 888 = 75/1200 split speed */
-#endif /* MINIX */
-#ifdef B7200
- case 720: s = B7200; break;
-#endif /* B7200 */
- case 960: s = B9600; break;
-#ifdef B14400
- case 1440: s = B14400; break;
-#endif /* B14400 */
-#ifdef B19200
- case 1920: s = B19200; break;
-#else
-#ifdef EXTA
- case 1920: s = EXTA; break;
-#endif /* EXTA */
-#endif /* B19200 */
-#ifdef B28800
- case 2880: s = B28800; break;
-#endif /* B28800 */
-#ifdef B38400
- case 3840: s = B38400;
-#ifdef OLINUXHISPEED
- spd_flags = ~ASYNC_SPD_MASK; /* Nonzero, but zero flags */
-#endif /* OLINUXHISPEED */
- break;
-#else /* B38400 not defined... */
-#ifdef EXTB
- case 3840: s = EXTB; break;
-#endif /* EXTB */
-#endif /* B38400 */
-
-#ifdef HPUX
-#ifdef _B57600
- case 5760: s = _B57600; break;
-#endif /* _B57600 */
-#ifdef _B115200
- case 11520: s = _B115200; break;
-#endif /* _B115200 */
-#else
-#ifdef OLINUXHISPEED
-/*
- This bit from <carlo@sg.tn.tudelft.nl>:
- "Only note to make is maybe this: When the ASYNC_SPD_CUST flags are set then
- setting the speed to 38400 will set the custom speed (and ttgspd returns
- 38400), but speeds 57600 and 115200 won't work any more because I didn't
- want to mess up the speed flags when someone is doing sophisticated stuff
- like custom speeds..."
-*/
- case 5760: s = B38400; spd_flags = ASYNC_SPD_HI; break;
- case 11520: s = B38400; spd_flags = ASYNC_SPD_VHI; break;
-#else
-#ifdef B57600
- case 5760: s = B57600; break;
-#endif /* B57600 */
-#ifdef B76800
- case 7680: s = B76800; break;
-#endif /* B76800 */
-#ifdef B115200
- case 11520: s = B115200; break;
-#endif /* B115200 */
-#endif /* OLINUXHISPEED */
-#ifdef B153600
- case 15360: s = B153600; break;
-#endif /* B153600 */
-#ifdef B230400
- case 23040: s = B230400; break;
-#endif /* B230400 */
-#ifdef B307200
- case 30720: s = B307200; break;
-#endif /* B307200 */
-#ifdef B460800
- case 46080: s = B460800; break;
-#endif /* 460800 */
-#ifdef B921600
- case 92160: s = B921600; break;
-#endif /* B921600 */
-#endif /* HPUX */
- default:
- ok = 0; /* Good speed not found, so not ok */
- break;
- }
- debug(F101,"ttsspd ok","",ok);
- debug(F101,"ttsspd s","",s);
-
- if (!ok) {
- debug(F100,"ttsspd fails","",0);
- return(-1);
- } else {
- if (!s2) s2 = s; /* Set input speed */
-#ifdef Plan9
- if (p9ttsspd(cps) < 0)
- return(-1);
-#else
-#ifdef BSD44ORPOSIX
- x = tcgetattr(ttyfd,&ttcur); /* Get current speed */
- debug(F101,"ttsspd tcgetattr","",x);
- if (x < 0)
- return(-1);
-#ifdef OLINUXHISPEED
- debug(F101,"ttsspd spd_flags","",spd_flags);
- if (spd_flags && spd_flags != ASYNC_SPD_CUST) {
- if (ioctl(ttyfd, TIOCGSERIAL, &serinfo) < 0) {
- debug(F100,"ttsspd: TIOCGSERIAL failed","",0);
- return(-1);
- } else debug(F100,"ttsspd: TIOCGSERIAL ok","",0);
- serinfo.flags &= ~ASYNC_SPD_MASK;
- serinfo.flags |= (spd_flags & ASYNC_SPD_MASK);
- if (ioctl(ttyfd, TIOCSSERIAL, &serinfo) < 0)
- return(-1);
- }
-#endif /* OLINUXHISPEED */
- cfsetospeed(&ttcur,s);
- cfsetispeed(&ttcur,s2);
- cfsetospeed(&ttraw,s);
- cfsetispeed(&ttraw,s2);
- cfsetospeed(&tttvt,s);
- cfsetispeed(&tttvt,s2);
- cfsetospeed(&ttold,s);
- cfsetispeed(&ttold,s2);
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F101,"ttsspd tcsetattr","",x);
- if (x < 0) return(-1);
-#else
-#ifdef ATTSV
- if (cps == 888) return(-1); /* No split speeds, sorry. */
- x = ioctl(ttyfd,TCGETA,&ttcur);
- debug(F101,"ttsspd TCGETA ioctl","",x);
- if (x < 0) return(-1);
- ttcur.c_cflag &= ~CBAUD;
- ttcur.c_cflag |= s;
- tttvt.c_cflag &= ~CBAUD;
- tttvt.c_cflag |= s;
- ttraw.c_cflag &= ~CBAUD;
- ttraw.c_cflag |= s;
- ttold.c_cflag &= ~CBAUD;
- ttold.c_cflag |= s;
- x = ioctl(ttyfd,TCSETAW,&ttcur);
- debug(F101,"ttsspd TCSETAW ioctl","",x);
- if (x < 0) return(-1);
-#else
-#ifdef BELLV10
- x = ioctl(ttyfd,TIOCGDEV,&tdcur);
- debug(F101,"ttsspd TIOCGDEV ioctl","",x);
- if (x < 0) return(-1);
- tdcur.ispeed = s2;
- tdcur.ospeed = s;
- errno = 0;
- ok = ioctl(ttyfd,TIOCSDEV,&tdcur);
- debug(F101,"ttsspd BELLV10 ioctl","",ok);
- if (ok < 0) {
- perror(ttnmsv);
- debug(F101,"ttsspd BELLV10 errno","",ok);
- return(-1);
- }
-#else
- x = gtty(ttyfd,&ttcur);
- debug(F101,"ttsspd gtty","",x);
- if (x < 0) return(-1);
- ttcur.sg_ospeed = s; ttcur.sg_ispeed = s2;
- tttvt.sg_ospeed = s; tttvt.sg_ispeed = s2;
- ttraw.sg_ospeed = s; ttraw.sg_ispeed = s2;
- ttold.sg_ospeed = s; ttold.sg_ispeed = s2;
- x = stty(ttyfd,&ttcur);
- debug(F101,"ttsspd stty","",x);
- if (x < 0) return(-1);
-#endif /* BELLV10 */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-#endif /* Plan9 */
- }
- return(1); /* Return 1 = success. */
-#endif /* USETCSETSPEED */
-}
-
-#endif /* NOLOCAL */
-
-/* C O N G S P D - Get speed of console terminal */
-
-long
-congspd() {
-/*
- This is a disgusting hack. The right way to do this would be to pass an
- argument to ttgspd(), but then we'd need to change the Kermit API and
- all of the ck?tio.c modules. (Currently used only for rlogin.)
-*/
- int t1;
- long spd;
-#ifdef NETCONN
- int t2 = netconn;
- netconn = 0;
-#endif /* NETCONN */
- t1 = ttyfd;
- ttyfd = -1;
- spd = ttgspd();
- debug(F101,"congspd","",spd);
-#ifdef NETCONN
- netconn = t2;
-#endif /* NETCONN */
- ttyfd = t1;
- return(spd);
-}
-
-/* T T S P D L I S T -- Get list of serial speeds allowed on this platform */
-
-#define NSPDLIST 64
-static long spdlist[NSPDLIST];
-/*
- As written, this picks up the speeds known at compile time, and thus
- apply to the system where C-Kermit was built, rather than to the one where
- it is running. Suggestions for improvement are always welcome.
-*/
-long *
-ttspdlist() {
- int i;
- for (i = 0; i < NSPDLIST; i++) /* Initialize the list */
- spdlist[i] = -1L;
- i = 1;
-
-#ifdef USETCSETSPEED /* No way to find out what's legal */
- debug(F100,"ttspdlist USETCSETSPEED","",0);
- spdlist[i++] = 50L;
-#ifndef UW7
- spdlist[i++] = 75L;
-#endif /* UW7 */
- spdlist[i++] = 110L;
-#ifndef UW7
- spdlist[i++] = 134L;
-#endif /* UW7 */
- spdlist[i++] = 150L;
- spdlist[i++] = 200L;
- spdlist[i++] = 300L;
- spdlist[i++] = 600L;
- spdlist[i++] = 1200L;
- spdlist[i++] = 1800L;
- spdlist[i++] = 2400L;
- spdlist[i++] = 4800L;
- spdlist[i++] = 8880L;
- spdlist[i++] = 9600L;
- spdlist[i++] = 14400L;
- spdlist[i++] = 19200L;
- spdlist[i++] = 28800L;
-#ifndef UW7
- spdlist[i++] = 33600L;
-#endif /* UW7 */
- spdlist[i++] = 38400L;
- spdlist[i++] = 57600L;
- spdlist[i++] = 76800L;
- spdlist[i++] = 115200L;
-#ifndef UW7
- spdlist[i++] = 153600L;
- spdlist[i++] = 230400L;
- spdlist[i++] = 307200L;
- spdlist[i++] = 460800L;
- spdlist[i++] = 921600L;
-#endif /* UW7 */
-
-#else /* USETCSETSPEED */
-
- debug(F100,"ttspdlist no USETCSETSPEED","",0);
-
-#ifdef B50
- debug(F101,"ttspdlist B50","",B50);
- spdlist[i++] = 50L;
-#endif /* B50 */
-#ifdef B75
- debug(F101,"ttspdlist B75","",B75);
- spdlist[i++] = 75L;
-#endif /* B75 */
-#ifdef B110
- debug(F101,"ttspdlist B110","",B110);
- spdlist[i++] = 110L;
-#endif /* B110 */
-#ifdef B134
- debug(F101,"ttspdlist B134","",B134);
- spdlist[i++] = 134L;
-#endif /* B134 */
-#ifdef B150
- debug(F101,"ttspdlist B150","",B150);
- spdlist[i++] = 150L;
-#endif /* B150 */
-#ifdef B200
- debug(F101,"ttspdlist B200","",B200);
- spdlist[i++] = 200L;
-#endif /* B200 */
-#ifdef B300
- debug(F101,"ttspdlist B300","",B300);
- spdlist[i++] = 300L;
-#endif /* B300 */
-#ifdef B600
- debug(F101,"ttspdlist B600","",B600);
- spdlist[i++] = 600L;
-#endif /* B600 */
-#ifdef B1200
- debug(F101,"ttspdlist B1200","",B1200);
- spdlist[i++] = 1200L;
-#endif /* B1200 */
-#ifdef B1800
- debug(F101,"ttspdlist B1800","",B1800);
- spdlist[i++] = 1800L;
-#endif /* B1800 */
-#ifdef B2400
- debug(F101,"ttspdlist B2400","",B2400);
- spdlist[i++] = 2400L;
-#endif /* B2400 */
-#ifdef B4800
- debug(F101,"ttspdlist B4800","",B4800);
- spdlist[i++] = 4800L;
-#endif /* B4800 */
-#ifdef B9600
- debug(F101,"ttspdlist B9600","",B9600);
- spdlist[i++] = 9600L;
-#endif /* B9600 */
-#ifdef B14400
- debug(F101,"ttspdlist B14400","",B14400);
- spdlist[i++] = 14400L;
-#endif /* B14400 */
-#ifdef B19200
- debug(F101,"ttspdlist B19200","",B19200);
- spdlist[i++] = 19200L;
-#else
-#ifdef EXTA
- debug(F101,"ttspdlist EXTA","",EXTA);
- spdlist[i++] = 19200L;
-#endif /* EXTA */
-#endif /* B19200 */
-#ifdef B28800
- debug(F101,"ttspdlist B28800","",B28800);
- spdlist[i++] = 28800L;
-#endif /* B28800 */
-#ifdef B33600
- debug(F101,"ttspdlist B33600","",B33600);
- spdlist[i++] = 33600L;
-#endif /* B33600 */
-#ifdef B38400
- debug(F101,"ttspdlist B38400","",B38400);
- spdlist[i++] = 38400L;
-#else
-#ifdef EXTB
- debug(F101,"ttspdlist EXTB","",EXTB);
- spdlist[i++] = 38400L;
-#endif /* EXTB */
-#endif /* B38400 */
-#ifdef _B57600
- debug(F101,"ttspdlist _B57600","",_B57600);
- spdlist[i++] = 57600L;
-#else
-#ifdef B57600
- debug(F101,"ttspdlist B57600","",B57600);
- spdlist[i++] = 57600L;
-#endif /* B57600 */
-#endif /* _B57600 */
-#ifdef B76800
- debug(F101,"ttspdlist B76800","",B76800);
- spdlist[i++] = 76800L;
-#endif /* B76800 */
-#ifdef _B115200
- debug(F101,"ttspdlist _B115200","",_B115200);
- spdlist[i++] = 115200L;
-#else
-#ifdef B115200
- debug(F101,"ttspdlist B115200","",B115200);
- spdlist[i++] = 115200L;
-#endif /* B115200 */
-#endif /* _B115200 */
-#ifdef B153600
- debug(F101,"ttspdlist B153600","",B153600);
- spdlist[i++] = 153600L;
-#endif /* B153600 */
-#ifdef B230400
- debug(F101,"ttspdlist B230400","",B230400);
- spdlist[i++] = 230400L;
-#endif /* B230400 */
-#ifdef B307200
- debug(F101,"ttspdlist B307200","",B307200);
- spdlist[i++] = 307200L;
-#endif /* B307200 */
-#ifdef B460800
- debug(F101,"ttspdlist B460800","",B460800);
- spdlist[i++] = 460800L;
-#endif /* B460800 */
-#ifdef B921600
- debug(F101,"ttspdlist B921600","",B921600);
- spdlist[i++] = 921600L;
-#endif /* B921600 */
-#endif /* USETCSETSPEED */
- spdlist[0] = i - 1; /* Return count in 0th element */
- debug(F111,"ttspdlist spdlist","0",spdlist[0]);
- return((long *)spdlist);
-}
-
-/* T T G S P D - Get speed of currently selected tty line */
-
-/*
- Unreliable. After SET LINE, it returns an actual speed, but not necessarily
- the real speed. On some systems, it returns the line's nominal speed, from
- /etc/ttytab. Even if you SET SPEED to something else, this function might
- not notice.
-*/
-long
-ttgspd() { /* Get current serial device speed */
-#ifdef NOLOCAL
- return(-1L);
-#else
-#ifdef POSIX
- speed_t /* Should be unsigned */
-#else
- int /* Isn't unsigned */
-#endif /* POSIX */
- s;
- int x;
- long ss;
-#ifdef OLINUXHISPEED
- unsigned int spd_flags = 0;
- struct serial_struct serinfo;
-#endif /* OLINUXHISPEED */
-
-#ifdef NETCONN
- if (netconn) {
-#ifdef TN_COMPORT
- if (istncomport())
- return(tnc_get_baud());
- else
-#endif /* TN_COMPORT */
- return(-1); /* -1 if network connection */
- }
-#endif /* NETCONN */
-#ifdef NETCMD
- if (ttpipe) return(-1);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(-1);
-#endif /* NETPTY */
-
- debug(F101,"ttgspd ttyfd","",ttyfd);
-
-#ifdef USETCSETSPEED
-
- x = tcgetattr(ttyfd,&ttcur); /* Get current speed */
- debug(F101,"ttgspd tcgetattr","",x);
- if (x < 0)
- return(-1);
- errno = 0;
- s = tcgetspeed(TCS_ALL, &ttcur);
- debug(F101,"ttsspd TCGETSPEED speed","",s);
- if (s == 0) {
- long s1, s2;
- s1 = tcgetspeed(TCS_IN, &ttcur);
- s2 = tcgetspeed(TCS_OUT, &ttcur);
- if (s1 == 1200L && s2 == 75L)
- return(8880L);
- }
-#ifdef DEBUG
- if (errno & deblog) {
- debug(F101,"ttsspd TCGETSPEED errno","",errno);
- }
-#endif /* DEBUG */
- return(s);
-
-#else /* Not USETCSETSPEED */
-
-#ifdef Plan9
- if (ttyfd < 0)
- ss = -1;
- else
- ss = ttylastspeed;
-#else
-#ifdef OLINUXHISPEED
- debug(F100,"ttgspd Linux OLINUXHISPEED","",0);
-#endif /* OLINUXHISPEED */
-
- if (ttyfd < 0) {
-#ifdef BSD44ORPOSIX
- s = cfgetospeed(&ccold);
- debug(F101,"ttgspd cfgetospeed 1 POSIX","",s);
-#else
-#ifdef ATTSV
- s = ccold.c_cflag & CBAUD;
- debug(F101,"ttgspd c_cflag CBAUD 1 ATTSV","",s);
-#else
- s = ccold.sg_ospeed; /* (obtained by congm()) */
- debug(F101,"ttgspd sg_ospeed 1","",s);
-#endif /* ATTSV */
-#endif /* BSD44POSIX */
-
- } else {
-#ifdef BSD44ORPOSIX
- if (tcgetattr(ttyfd,&ttcur) < 0) return(-1);
- s = cfgetospeed(&ttcur);
- debug(F101,"ttgspd cfgetospeed 2 BSDORPOSIX","",s);
-#ifdef OLINUXHISPEED
- if (ioctl(ttyfd,TIOCGSERIAL,&serinfo) > -1)
- spd_flags = serinfo.flags & ASYNC_SPD_MASK;
- debug(F101,"ttgspd spd_flags","",spd_flags);
-#endif /* OLINUXHISPEED */
-#else
-#ifdef ATTSV
- x = ioctl(ttyfd,TCGETA,&ttcur);
- debug(F101,"ttgspd ioctl 2 ATTSV x","",x);
- debug(F101,"ttgspd ioctl 2 ATTSV errno","",errno);
- if (x < 0) return(-1);
- s = ttcur.c_cflag & CBAUD;
- debug(F101,"ttgspd ioctl 2 ATTSV speed","",s);
-#else
-#ifdef BELLV10
- x = ioctl(ttyfd,TIOCGDEV,&tdcur);
- debug(F101,"ttgspd ioctl 2 BELLV10 x","",x);
- if (x < 0) return(-1);
- s = tdcur.ospeed;
- debug(F101,"ttgspd ioctl 2 BELLV10 speed","",s);
-#else
- x = gtty(ttyfd,&ttcur);
- debug(F101,"ttgspd gtty 2 x","",x);
- debug(F101,"ttgspd gtty 2 errno","",errno);
- if (x < 0) return(-1);
- s = ttcur.sg_ospeed;
- debug(F101,"ttgspd gtty 2 speed","",s);
-#endif /* BELLV10 */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
- }
- debug(F101,"ttgspd code","",s);
-#ifdef OLINUXHISPEED
- debug(F101,"ttgspd spd_flags","",spd_flags);
-#endif /* OLINUXHISPEED */
- switch (s) {
-#ifdef B0
- case B0: ss = 0L; break;
-#endif /* B0 */
-
-#ifndef MINIX
-/*
- MINIX defines the Bxx symbols to be bps/100, so B50==B75, B110==B134==B150,
- etc, making for many "duplicate case in switch" errors, which are fatal.
-*/
-#ifdef B50
- case B50: ss = 50L; break;
-#endif /* B50 */
-#ifdef B75
- case B75: ss = 75L; break;
-#endif /* B75 */
-#endif /* MINIX */
-
-#ifdef B110
- case B110: ss = 110L; break;
-#endif /* B110 */
-
-#ifndef MINIX
-#ifdef B134
- case B134: ss = 134L; break;
-#endif /* B134 */
-#ifdef B150
- case B150: ss = 150L; break;
-#endif /* B150 */
-#endif /* MINIX */
-
-#ifdef B200
- case B200: ss = 200L; break;
-#endif /* B200 */
-
-#ifdef B300
- case B300: ss = 300L; break;
-#endif /* B300 */
-
-#ifdef B600
- case B600: ss = 600L; break;
-#endif /* B600 */
-
-#ifdef B1200
- case B1200: ss = 1200L; break;
-#endif /* B1200 */
-
-#ifdef B1800
- case B1800: ss = 1800L; break;
-#endif /* B1800 */
-
-#ifdef B2400
- case B2400: ss = 2400L; break;
-#endif /* B2400 */
-
-#ifdef B4800
- case B4800: ss = 4800L; break;
-#endif /* B4800 */
-
-#ifdef B7200
- case B7200: ss = 7200L; break;
-#endif /* B7200 */
-
-#ifdef B9600
- case B9600: ss = 9600L; break;
-#endif /* B9600 */
-
-#ifdef B19200
- case B19200: ss = 19200L; break;
-#else
-#ifdef EXTA
- case EXTA: ss = 19200L; break;
-#endif /* EXTA */
-#endif /* B19200 */
-
-#ifndef MINIX
-#ifdef B38400
- case B38400:
- ss = 38400L;
-#ifdef OLINUXHISPEED
- switch(spd_flags) {
- case ASYNC_SPD_HI: ss = 57600L; break;
- case ASYNC_SPD_VHI: ss = 115200L; break;
- }
-#endif /* OLINUXHISPEED */
- break;
-#else
-#ifdef EXTB
- case EXTB: ss = 38400L; break;
-#endif /* EXTB */
-#endif /* B38400 */
-#endif /* MINIX */
-
-#ifdef HPUX
-#ifdef _B57600
- case _B57600: ss = 57600L; break;
-#endif /* _B57600 */
-#ifdef _B115200
- case _B115200: ss = 115200L; break;
-#endif /* _B115200 */
-#else
-#ifdef B57600
- case B57600: ss = 57600L; break;
-#endif /* B57600 */
-#ifdef B76800
- case B76800: ss = 76800L; break;
-#endif /* B76800 */
-#ifdef B115200
- case B115200: ss = 115200L; break;
-#endif /* B115200 */
-#ifdef B153600
- case B153600: ss = 153600L; break;
-#endif /* B153600 */
-#ifdef B230400
- case B230400: ss = 230400L; break;
-#endif /* B230400 */
-#ifdef B307200
- case B307200: ss = 307200L; break;
-#endif /* B307200 */
-#ifdef B460800
- case B460800: ss = 460800L; break;
-#endif /* B460800 */
-#endif /* HPUX */
-#ifdef B921600
- case B921600: ss = 921600L; break;
-#endif /* B921600 */
- default:
- ss = -1; break;
- }
-#endif /* Plan9 */
- debug(F101,"ttgspd speed","",ss);
- return(ss);
-
-#endif /* USETCSETSPEED */
-#endif /* NOLOCAL */
-}
-#ifdef MINIX2 /* Another hack alert */
-#define MINIX
-#endif /* MINIX2 */
-
-/*
- FIONREAD data type... This has been defined as "long" for many, many
- years, and it worked OK until 64-bit platforms appeared. Thus we use
- int for 64-bit platforms, but keep long for the others. If we changed
- the default PEEKTYPE to int, this would probably break 16-bit builds
- (note that sizeof(long) == sizeof(int) on most 32-bit platforms), many
- of which we have no way of testing any more. Therefore, do not change
- the default definition of PEEKTYPE -- only add exceptions to it as needed.
-*/
-#ifdef COHERENT
-#ifdef FIONREAD
-#undef FIONREAD
-#endif /* FIONREAD */
-/* #define FIONREAD TIOCQUERY */
-/* #define PEEKTYPE int */
-#else /* Not COHERENT... */
-
-#ifdef OSF32 /* Digital UNIX 3.2 or higher */
-#define PEEKTYPE int
-#else
-#define PEEKTYPE long /* Elsewhere (see notes above) */
-#endif /* OSF32 */
-#endif /* COHERENT */
-
-/* ckumyr.c by Kristoffer Eriksson, ske@pkmab.se, 15 Mar 1990. */
-
-#ifdef MYREAD
-
-/* Private buffer for myread() and its companions. Not for use by anything
- * else. ttflui() is allowed to reset them to initial values. ttchk() is
- * allowed to read my_count.
- *
- * my_item is an index into mybuf[]. Increment it *before* reading mybuf[].
- *
- * A global parity mask variable could be useful too. We could use it to
- * let myread() strip the parity on its own, instead of stripping sign
- * bits as it does now.
- */
-#ifdef BIGBUFOK
-#define MYBUFLEN 32768
-#else
-#ifdef pdp11
-#define MYBUFLEN 256
-#else
-#define MYBUFLEN 1024
-#endif /* pdp11 */
-#endif /* BIGBUFOK */
-
-#ifdef ANYX25
-#undef MYBUFLEN
-#define MYBUFLEN 256
-/*
- On X.25 connections, there is an extra control byte at the beginning.
-*/
-static CHAR x25buf[MYBUFLEN+1]; /* Communication device input buffer */
-static CHAR *mybuf = x25buf+1;
-#else
-static CHAR mybuf[MYBUFLEN];
-#endif /* ANYX25 */
-
-static int my_count = 0; /* Number of chars still in mybuf */
-static int my_item = -1; /* Last index read from mybuf[] */
-
-/* T T P E E K -- Peek into our internal communications input buffers. */
-
-/*
- NOTE: This routine is peculiar to UNIX, and is used only by the
- select()-based CONNECT module, ckucns.c. It need not be replicated in
- the ck?tio.c of other platforms.
-*/
-int
-ttpeek() {
-#ifdef TTLEBUF
- int rc = 0;
- if (ttpush >= 0)
- rc++;
- rc += le_inbuf();
- if (rc > 0)
- return(rc);
- else
-#endif /* TTLEBUF */
-
-#ifdef MYREAD
- return(my_count);
-#else
- return(0);
-#endif /* MYREAD */
-}
-
-/* myread() -- Efficient read of one character from communications line.
- *
- * NOTE: myread() and its helpers mygetbuf() and myfillbuf() return raw
- * bytes from connection, so when the connection is encrypted, these bytes
- * must be decrypted.
- *
- * Uses a private buffer to minimize the number of expensive read() system
- * calls. Essentially performs the equivalent of read() of 1 character, which
- * is then returned. By reading all available input from the system buffers
- * to the private buffer in one chunk, and then working from this buffer, the
- * number of system calls is reduced in any case where more than one character
- * arrives during the processing of the previous chunk, for instance high
- * baud rates or network type connections where input arrives in packets.
- * If the time needed for a read() system call approaches the time for more
- * than one character to arrive, then this mechanism automatically compensates
- * for that by performing bigger read()s less frequently. If the system load
- * is high, the same mechanism compensates for that too.
- *
- * myread() is a macro that returns the next character from the buffer. If the
- * buffer is empty, mygetbuf() is called. See mygetbuf() for possible error
- * returns.
- *
- * This should be efficient enough for any one-character-at-a-time loops.
- * For even better efficiency you might use memcpy()/bcopy() or such between
- * buffers (since they are often better optimized for copying), but it may not
- * be worth it if you have to take an extra pass over the buffer to strip
- * parity and check for CTRL-C anyway.
- *
- * Note that if you have been using myread() from another program module, you
- * may have some trouble accessing this macro version and the private variables
- * it uses. In that case, just add a function in this module, that invokes the
- * macro.
- */
-#define myread() (--my_count < 0 ? mygetbuf() : 255 & (int)mybuf[++my_item])
-
-/* Specification: Push back up to one character onto myread()'s queue.
- *
- * This implementation: Push back characters into mybuf. At least one character
- * must have been read through myread() before myunrd() may be used. After
- * EOF or read error, again, myunrd() can not be used. Sometimes more than
- * one character can be pushed back, but only one character is guaranteed.
- * Since a previous myread() must have read its character out of mybuf[],
- * that guarantees that there is space for at least one character. If push
- * back was really needed after EOF, a small addition could provide that.
- *
- * As of 02/2007 myunrd() is used by ttinl().
- */
-VOID
-#ifdef CK_ANSIC
-myunrd(CHAR ch)
-#else
-myunrd(ch) CHAR ch;
-#endif /* CK_ANSIC */
-{
- if (my_item >= 0) {
- mybuf[my_item--] = ch;
- ++my_count;
- }
-}
-
-/* T T P U S H B A C K -- Put n bytes back into the myread buffer */
-
-static CHAR * pushbuf = NULL;
-/* static int pushed = 0; */
-
-int
-ttpushback(s,n) CHAR * s; int n; {
- debug(F101,"ttpushback n","",n);
- if (pushbuf || n > MYBUFLEN || n < 1)
- return(-1);
- debug(F101,"ttpushback my_count","",my_count);
- if (my_count > 0) {
- if (!(pushbuf = (CHAR *)malloc(n+1)))
- return(-1);
- memcpy(pushbuf,mybuf,my_count);
- /* pushed = my_count; */ /* (set but never used) */
- }
- memcpy(mybuf,s,n);
- my_count = n;
- my_item = -1;
- return(0);
-}
-
-/* mygetbuf() -- Fill buffer for myread() and return first character.
- *
- * This function is what myread() uses when it can't get the next character
- * directly from its buffer. First, it calls a system dependent myfillbuf()
- * to read at least one new character into the buffer, and then it returns
- * the first character just as myread() would have done. This function also
- * is responsible for all error conditions that myread() can indicate.
- *
- * Returns: When OK => a positive character, 0 or greater.
- * When EOF => -2.
- * When error => -3, error code in errno.
- *
- * Older myread()s additionally returned -1 to indicate that there was nothing
- * to read, upon which the caller would call myread() again until it got
- * something. The new myread()/mygetbuf() always gets something. If it
- * doesn't, then make it do so! Any program that actually depends on the old
- * behaviour will break.
- *
- * The older version also used to return -2 both for EOF and other errors,
- * and used to set errno to 9999 on EOF. The errno stuff is gone, EOF and
- * other errors now return different results, although Kermit currently never
- * checks to see which it was. It just disconnects in both cases.
- *
- * Kermit lets the user use the quit key to perform some special commands
- * during file transfer. This causes read(), and thus also mygetbuf(), to
- * finish without reading anything and return the EINTR error. This should
- * be checked by the caller. Mygetbuf() could retry the read() on EINTR,
- * but if there is nothing to read, this could delay Kermit's reaction to
- * the command, and make Kermit appear unresponsive.
- *
- * The debug() call should be removed for optimum performance.
- */
-int
-mygetbuf() {
- int x;
- errno = 0;
-#ifdef DEBUG
- if (deblog && my_count > 0)
- debug(F101,"mygetbuf IMPROPERLY CALLED with my_count","",my_count);
-#endif /* DEBUG */
- if (my_count <= 0)
- my_count = myfillbuf();
-
-#ifdef DEBUG
-#ifdef COMMENT
- if (deblog) debug(F101, "mygetbuf read", "", my_count);
-#else /* COMMENT */
- ckhexdump("mygetbuf read", mybuf, my_count);
-#endif /* COMMENT */
-#endif /* DEBUG */
- x = my_count;
- if (my_count <= 0) {
- my_count = 0;
- my_item = -1;
- debug(F101,"mygetbuf errno","",errno);
-#ifdef TCPSOCKET
- if (netconn && ttnet == NET_TCPB && errno != 0) {
- if (errno != EINTR) {
- debug(F101,"mygetbuf TCP error","",errno);
- ttclos(0); /* Close the connection. */
- }
- return(-3);
- }
-#endif /* TCPSOCKET */
- if (!netconn && xlocal && errno) {
- if (errno != EINTR) {
- debug(F101,"mygetbuf SERIAL error","",errno);
- x = -3;
- ttclos(0); /* Close the connection. */
- }
- }
- return((x < 0) ? -3 : -2);
- }
- --my_count;
- return((unsigned)(0xff & mybuf[my_item = 0]));
-}
-
-/* myfillbuf():
- * System-dependent read() into mybuf[], as many characters as possible.
- *
- * Returns: OK => number of characters read, always more than zero.
- * EOF => 0
- * Error => -1, error code in errno.
- *
- * If there is input available in the system's buffers, all of it should be
- * read into mybuf[] and the function return immediately. If no input is
- * available, it should wait for a character to arrive, and return with that
- * one in mybuf[] as soon as possible. It may wait somewhat past the first
- * character, but be aware that any such delay lengthens the packet turnaround
- * time during kermit file transfers. Should never return with zero characters
- * unless EOF or irrecoverable read error.
- *
- * Correct functioning depends on the correct tty parameters being used.
- * Better control of current parameters is required than may have been the
- * case in older Kermit releases. For instance, O_NDELAY (or equivalent) can
- * no longer be sometimes off and sometimes on like it used to, unless a
- * special myfillbuf() is written to handle that. Otherwise the ordinary
- * myfillbuf()s may think they have come to EOF.
- *
- * If your system has a facility to directly perform the functioning of
- * myfillbuf(), then use it. If the system can tell you how many characters
- * are available in its buffers, then read that amount (but not less than 1).
- * If the system can return a special indication when you try to read without
- * anything to read, while allowing you to read all there is when there is
- * something, you may loop until there is something to read, but probably that
- * is not good for the system load.
- */
-
-#ifdef SVORPOSIX
- /* This is for System III/V with VMIN>0, VTIME=0 and O_NDELAY off,
- * and CLOCAL set any way you like. This way, read() will do exactly
- * what is required by myfillbuf(): If there is data in the buffers
- * of the O.S., all available data is read into mybuf, up to the size
- * of mybuf. If there is none, the first character to arrive is
- * awaited and returned.
- */
-int
-myfillbuf() {
- int fd, n;
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef sxaE50
- /* From S. Dezawa at Fujifilm in Japan. I don't know why this is */
- /* necessary for the sxa E50, but it is. */
- return read(fd, mybuf, 255);
-#else
-#ifdef BEOSORBEBOX
- while (1) {
-#ifdef NETCONN
- if (netconn) {
- n = netxin(sizeof(mybuf), (char *)mybuf);
- debug(F101,"BEBOX SVORPOSIX network myfillbuf","",n);
- }
- else
-#endif /* NETCONN */
- n = read(fd, mybuf, sizeof(mybuf));
- debug(F101,"BEBOX SVORPOSIX notnet myfillbuf","",n);
- if (n > 0)
- return(n);
- snooze(1000.0);
- }
-#else /* BEOSORBEBOX */
- errno = 0;
- /* debug(F101,"SVORPOSIX myfillbuf calling read() fd","",fd); */
-#ifdef IBMX25
- if (netconn && (nettype == NET_IX25)) {
- /* can't use sizeof because mybuf is a pointer, and not an array! */
- n = x25xin( MYBUFLEN, mybuf );
- } else
-#endif /* IBMX25 */
-
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error, n = 0;
- debug(F100,"myfillbuf calling SSL_read() fd","",0);
- while (n == 0) {
- if (ssl_active_flag)
- n = SSL_read(ssl_con, (char *)mybuf, sizeof(mybuf));
- else if (tls_active_flag)
- n = SSL_read(tls_con, (char *)mybuf, sizeof(mybuf));
- else
- break;
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,n)) {
- case SSL_ERROR_NONE:
- if (n > 0)
- return(n);
- if (n < 0)
- return(-2);
- msleep(50);
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(-1);
- case SSL_ERROR_SYSCALL:
- if (n != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- ttclos(0);
- return(-3);
- }
- }
- }
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- debug(F101,"myfillbuf calling krb4_des_read() fd","",ttyfd);
- if ((n = krb4_des_read(ttyfd,(char *)mybuf,sizeof(mybuf))) < 0)
- return(-3);
- else
- return(n);
- }
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- debug(F101,"myfillbuf calling krb5_des_read() fd","",ttyfd);
- if ((n = krb5_des_read(ttyfd,(char *)mybuf,sizeof(mybuf),0)) < 0)
- return(-3);
- else
- return(n);
- }
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- debug(F101,"myfillbuf calling krb5_u2u_read() fd","",ttyfd);
- if ((n = krb5_u2u_read(ttyfd,(char *)mybuf,sizeof(mybuf))) < 0)
- return(-3);
- else
- return(n);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef NETPTY
-#ifdef HAVE_PTYTRAP
- /* Special handling for HP-UX pty i/o */
- ptyread:
- if (ttpty && pty_trap_pending(ttyfd) > 0) {
- debug(F101,"myfillbuf calling pty_trap_handler() fd","",ttyfd);
- if (pty_trap_handler(ttyfd) > 0) {
- ttclos(0);
- return(-3);
- }
- }
-#endif /* HAVE_PTYTRAP */
-#endif /* NETPTY */
- debug(F101,"myfillbuf calling read() fd","",ttyfd);
- n = read(fd, mybuf, sizeof(mybuf));
- debug(F101,"SVORPOSIX myfillbuf read","",n);
- debug(F101,"SVORPOSIX myfillbuf errno","",errno);
- debug(F101,"SVORPOSIX myfillbuf ttcarr","",ttcarr);
- if (n < 1) {
-#ifdef NETPTY
-#ifdef HAVE_PTYTRAP
- /* When we have a PTY trap in place the connection cannot */
- /* be closed until the trap receives a close indication. */
- if (n == 0 && ttpty)
- goto ptyread;
-#endif /* HAVE_PTYTRAP */
-#endif /* NETPTY */
- return(-3);
- }
- return(n);
-#endif /* BEOSORBEBOX */
-#endif /* sxaE50 */
-}
-
-#else /* not AT&T or POSIX */
-
-#ifdef aegis
- /* This is quoted from the old myread(). The semantics seem to be
- * alright, but maybe errno would not need to be set even when
- * there is no error? I don't know aegis.
- */
-int
-myfillbuf() {
- int count;
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
- count = ios_$get((short)fd, ios_$cond_opt, mybuf, 256L, st);
- errno = EIO;
- if (st.all == ios_$get_conditional_failed) /* get at least one */
- count = ios_$get((short)fd, 0, mybuf, 1L, st);
- if (st.all == ios_$end_of_file)
- return(-3);
- else if (st.all != status_$ok) {
- errno = EIO;
- return(-1);
- }
- return(count > 0 ? count : -3);
-}
-#else /* !aegis */
-
-#ifdef FIONREAD
- /* This is for systems with FIONREAD. FIONREAD returns the number
- * of characters available for reading. If none are available, wait
- * until something arrives, otherwise return all there is.
- */
-int
-myfillbuf() {
- PEEKTYPE avail = 0;
- int x, fd;
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef SUNX25
-/*
- SunLink X.25 support in this routine from Stefaan A. Eeckels, Eurostat (CEC).
- Depends on SunOS having FIONREAD, not because we use it, but just so this
- code is grouped correctly within the #ifdefs. Let's hope Solaris keeps it.
-
- We call x25xin() instead of read() so that Q-Bit packets, which contain
- X.25 service-level information (e.g. PAD parameter changes), can be processed
- transparently to the upper-level code. This is a blocking read, and so
- we depend on higher-level code (such as ttinc()) to set any necessary alarms.
-*/
- extern int nettype;
- if (netconn && nettype == NET_SX25) {
- while ((x = x25xin(sizeof(x25buf), x25buf)) < 1) ;
- return(x - 1); /* "-1" compensates for extra status byte */
- }
-#endif /* SUNX25 */
-
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error, n = 0;
- while (n == 0) {
- if (ssl_active_flag)
- n = SSL_read(ssl_con, (char *)mybuf, sizeof(mybuf));
- else
- n = SSL_read(tls_con, (char *)mybuf, sizeof(mybuf));
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,n)) {
- case SSL_ERROR_NONE:
- if (n > 0)
- return(n);
- if (n < 0)
- return(-2);
- msleep(50);
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(-1);
- case SSL_ERROR_SYSCALL:
- if (n != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- ttclos(0);
- return(-2);
- }
- }
- }
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- if ((x = krb4_des_read(ttyfd,mybuf,sizeof(mybuf))) < 0)
- return(-1);
- else
- return(x);
- }
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- if ((x = krb5_des_read(ttyfd,mybuf,sizeof(mybuf),0)) < 0)
- return(-1);
- else
- return(x);
- }
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- if ((x = krb5_u2u_read(ttyfd,mybuf,sizeof(mybuf))) < 0)
- return(-1);
- else
- return(x);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
- errno = 0;
- debug(F101,"myfillbuf calling FIONREAD ioctl","",xlocal);
- x = ioctl(fd, FIONREAD, &avail);
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"myfillbuf FIONREAD","",x);
- debug(F101,"myfillbuf FIONREAD avail","",avail);
- debug(F101,"myfillbuf FIONREAD errno","",errno);
- }
-#endif /* DEBUG */
- if (x < 0 || avail == 0)
- avail = 1;
-
- if (avail > MYBUFLEN)
- avail = MYBUFLEN;
-
- errno = 0;
-
- x = read(fd, mybuf, (int) avail);
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"myfillbuf avail","",avail);
- debug(F101,"myfillbuf read","",x);
- debug(F101,"myfillbuf read errno","",errno);
- if (x > 0)
- ckhexdump("myfillbuf mybuf",mybuf,x);
- }
-#endif /* DEBUG */
- if (x < 1) x = -3; /* read 0 == connection loss */
- return(x);
-}
-
-#else /* !FIONREAD */
-/* Add other systems here, between #ifdef and #else, e.g. NETCONN. */
-/* When there is no other possibility, read 1 character at a time. */
-int
-myfillbuf() {
- int x;
-
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error, n = 0;
- while (n == 0) {
- if (ssl_active_flag)
- n = SSL_read(ssl_con, (char *)mybuf, sizeof(mybuf));
- else
- count = SSL_read(tls_con, (char *)mybuf, sizeof(mybuf));
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,n)) {
- case SSL_ERROR_NONE:
- if (n > 0)
- return(n);
- if (n < 0)
- return(-2);
- msleep(50);
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(-1);
- case SSL_ERROR_SYSCALL:
- if (n != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- ttclos(0);
- return(-2);
- }
- }
- }
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- if ((len = krb4_des_read(ttyfd,mybuf,sizeof(mybuf))) < 0)
- return(-1);
- else
- return(len);
- }
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- if ((len = krb5_des_read(ttyfd,mybuf,sizeof(mybuf),0)) < 0)
- return(-1);
- else
- return(len);
- }
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- if ((len = krb5_u2u_read(ttyfd,mybuf,sizeof(mybuf))) < 0)
- return(-1);
- else
- return(len);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
- x = read(fd, mybuf, 1);
- return(x > 0 ? x : -3);
-}
-
-#endif /* !FIONREAD */
-#endif /* !aegis */
-#endif /* !ATTSV */
-
-#endif /* MYREAD */
-
-/* T T _ T N O P T -- Handle Telnet negotions in incoming data */
-/*
- Call with the IAC that was encountered.
- Returns:
- -3: If connection has dropped or gone bad.
- -2: On Telnet protocol error resulting in inconsistent states.
- 0: If negotiation OK and caller has nothing to do.
- 1: If packet start character has changed (new value is in global stchr).
- 255: If there was a quoted IAC as data.
- or: Not at all if we got a legitimate Telnet Logout request.
-*/
-#ifdef TCPSOCKET
-static int
-tt_tnopt(n) int n; { /* Handle Telnet options */
- /* In case caller did not already check these conditions... */
- if (n == IAC &&
- ((xlocal && netconn && IS_TELNET()) ||
- (!xlocal && sstelnet))) {
- extern int server;
- int tx = 0;
- debug(F100,"ttinl calling tn_doop()","",0);
- tx = tn_doop((CHAR)(n & 0xff),duplex,ttinc);
- debug(F111,"ttinl tn_doop() returned","tx",tx);
- switch (tx) {
- case 0:
- return(0);
- case -1: /* I/O error */
- ttimoff(); /* Turn off timer */
- return(-3);
- case -2: /* Connection failed. */
- case -3:
- ttimoff(); /* Turn off timer */
- ttclos(0);
- return(-3);
- case 1: /* ECHO change */
- duplex = 1;
- return(0);
- case 2: /* ECHO change */
- duplex = 0;
- return(0);
- case 3: /* Quoted IAC */
- n = 255;
- return((unsigned)255);
-#ifdef IKS_OPTION
- case 4: {
- if (TELOPT_SB(TELOPT_KERMIT).kermit.u_start && server
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- ) { /* Remote in Server mode */
- ttimoff(); /* Turn off timer */
- debug(F100,"u_start and !inserver","",0);
- return(-2); /* End server mode */
- } else if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start &&
- server
- ) { /* I'm no longer in Server Mode */
- debug(F100,"me_start and server","",0);
- ttimoff();
- return(-2);
- }
- return(0);
- }
- case 5: { /* Start character change */
- /* extern CHAR stchr; */
- /* start = stchr; */
- return(1);
- }
-#endif /* IKS_OPTION */
- case 6: /* Remote Logout */
- ttimoff();
- ttclos(0);
-#ifdef IKSD
- if (inserver && !local)
- doexit(GOOD_EXIT,0);
- else
-#endif /* IKSD */
- return(-2);
- default:
- return(0);
- }
- } else
- return(0);
-}
-#endif /* TCPSOCKET */
-
-/* T T F L U I -- Flush tty input buffer */
-
-void
-ttflux() { /* But first... */
-#ifdef MYREAD
-/*
- Flush internal MYREAD buffer.
-*/
-#ifdef TCPSOCKET
- int dotnopts, x;
- dotnopts = (((xlocal && netconn && IS_TELNET()) ||
- (!xlocal && sstelnet)));
-#endif /* TCPSOCKET */
- debug(F101,"ttflux my_count","",my_count);
-#ifdef TCPSOCKET
- if (dotnopts) {
- CHAR ch = '\0';
- while (my_count > 0) {
- ch = myread();
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION))
- ck_tn_decrypt((char *)&ch,1);
-#endif /* CK_ENCRYPTION */
- if (ch == IAC)
- x = tt_tnopt(ch);
- }
- } else
-#endif /* TCPSOCKET */
-#ifdef COMMENT
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION) && my_count > 0)
- ck_tn_decrypt(&mybuf[my_item+1],my_count);
-#endif /* CK_ENCRYPTION */
-#endif /* COMMENT */
- my_count = 0; /* Reset count to zero */
- my_item = -1; /* And buffer index to -1 */
-#endif /* MYREAD */
-}
-
-int
-ttflui() {
- int n, fd;
-#ifdef TCPSOCKET
- int dotnopts;
- dotnopts = (((xlocal && netconn && IS_TELNET()) ||
- (!xlocal && sstelnet)));
-#endif /* TCPSOCKET */
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef TTLEBUF
- ttpush = -1; /* Clear the peek-ahead char */
- while (le_data && (le_inbuf() > 0)) {
- CHAR ch = '\0';
- if (le_getchar(&ch) > 0) { /* Clear any more... */
- debug(F101,"ttflui le_inbuf ch","",ch);
- }
- }
-#endif /* TTLEBUF */
- debug(F101,"ttflui ttpipe","",ttpipe);
-
-#ifdef MYREAD
-/*
- Flush internal MYREAD buffer *NEXT*, in all cases.
-*/
- ttflux();
-#endif /* MYREAD */
-
-#ifdef NETCONN
-/* Network flush is done specially, in the network support module. */
- if ((netconn || sstelnet) && !ttpipe && !ttpty) {
- debug(F100,"ttflui netflui","",0);
-#ifdef COMMENT
-#ifdef TN_COMPORT
- if (istncomport())
- tnc_send_purge_data(TNC_PURGE_RECEIVE);
-#endif /* TN_COMPORT */
-#endif /* COMMENT */
- return(netflui());
- }
-#endif /* NETCONN */
-
- debug(F101,"ttflui ttyfd","",ttyfd); /* Not network */
- if (ttyfd < 0)
- return(-1);
-
-#ifdef aegis
- sio_$control((short)yfd, sio_$flush_in, true, st);
- if (st.all != status_$ok) {
- fprintf(stderr, "flush failed: "); error_$print(st);
- } else { /* sometimes the flush doesn't work */
- for (;;) {
- char buf[256];
- /* eat all the characters that shouldn't be available */
- ios_$get((short)fd, ios_$cond_opt, buf, 256L, st); /* (void) */
- if (st.all == ios_$get_conditional_failed) break;
- fprintf(stderr, "flush failed(2): "); error_$print(st);
- }
- }
-#else
-#ifdef BSD44 /* 4.4 BSD */
- n = FREAD; /* Specify read queue */
- debug(F100,"ttflui BSD44","",0);
- ioctl(fd,TIOCFLUSH,&n);
-#else
-#ifdef Plan9
-#undef POSIX /* Uh oh... */
-#endif /* Plan9 */
-#ifdef POSIX /* POSIX */
- debug(F100,"ttflui POSIX","",0);
- tcflush(fd,TCIFLUSH);
-#else
-#ifdef ATTSV /* System V */
-#ifndef VXVE
- debug(F100,"ttflui ATTSV","",0);
- ioctl(fd,TCFLSH,0);
-#endif /* VXVE */
-#else /* Not BSD44, POSIX, or Sys V */
-#ifdef TIOCFLUSH /* Those with TIOCFLUSH defined */
-#ifdef ANYBSD /* Berkeley */
- n = FREAD; /* Specify read queue */
- debug(F100,"ttflui TIOCFLUSH ANYBSD","",0);
- ioctl(fd,TIOCFLUSH,&n);
-#else /* Others (V7, etc) */
- debug(F100,"ttflui TIOCFLUSH","",0);
- ioctl(fd,TIOCFLUSH,0);
-#endif /* ANYBSD */
-#else /* All others... */
-/*
- No system call (that we know about) for input buffer flushing.
- So see how many there are and read them in a loop, using ttinc().
- ttinc() is buffered, so we're not getting charged with a system call
- per character, just a function call.
-*/
- if ((n = ttchk()) > 0) {
- debug(F101,"ttflui read loop","",n);
- while ((n--) && ttinc(0) > 0) ;
- }
-#endif /* TIOCFLUSH */
-#endif /* ATTSV */
-#endif /* POSIX */
-#ifdef Plan9
-#define POSIX
-#endif /* Plan9 */
-#endif /* BSD44 */
-#endif /* aegis */
- return(0);
-}
-
-int
-ttfluo() { /* Flush output buffer */
- int fd;
-#ifdef NETCMD
- if (ttpipe)
- fd = fdout;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef Plan9
- return 0;
-#else
-#ifdef POSIX
- return(tcflush(fd,TCOFLUSH));
-#else
-#ifdef OXOS
- return(ioctl(fd,TCFLSH,1));
-#else
- return(0); /* All others, nothing */
-#endif /* OXOS */
-#endif /* POSIX */
-#endif /* Plan9 */
-}
-
-/* Interrupt Functions */
-
-/* Set up terminal interrupts on console terminal */
-
-#ifndef FIONREAD /* We don't need esctrp() */
-#ifndef SELECT /* if we have any of these... */
-#ifndef CK_POLL
-#ifndef RDCHK
-
-#ifndef OXOS
-#ifdef SVORPOSIX
-SIGTYP
-esctrp(foo) int foo; { /* trap console escapes (^\) */
- signal(SIGQUIT,SIG_IGN); /* ignore until trapped */
- conesc = 1;
- debug(F101,"esctrp caught SIGQUIT","",conesc);
-}
-#endif /* SVORPOSIX */
-#endif /* OXOS */
-
-#ifdef V7
-#ifndef MINIX2
-SIGTYP
-esctrp(foo) int foo; { /* trap console escapes (^\) */
- signal(SIGQUIT,SIG_IGN); /* ignore until trapped */
- conesc = 1;
- debug(F101,"esctrp caught SIGQUIT","",conesc);
-}
-#endif /* MINIX2 */
-#endif /* V7 */
-
-#ifdef C70
-SIGTYP
-esctrp(foo) int foo; { /* trap console escapes (^\) */
- conesc = 1;
- signal(SIGQUIT,SIG_IGN); /* ignore until trapped */
-}
-#endif /* C70 */
-
-#endif /* RDCHK */
-#endif /* CK_POLL */
-#endif /* SELECT */
-#endif /* FIONREAD */
-
-/* C O N B G T -- Background Test */
-
-static int jc = 0; /* 0 = no job control */
-
-/*
- Call with flag == 1 to prevent signal test, which can not be expected
- to work during file transfer, when SIGINT probably *is* set to SIG_IGN.
-
- Call with flag == 0 to use the signal test, but only if the process-group
- test fails, as it does on some UNIX systems, where getpgrp() is buggy,
- requires an argument when the man page says it doesn't, or vice versa.
-
- If flag == 0 and the process-group test fails, then we determine background
- status simply (but not necessarily reliably) from isatty().
-
- conbgt() sets the global backgrd = 1 if we appear to be in the background,
- and to 0 if we seem to be in the foreground. conbgt() is highly prone to
- misbehavior.
-*/
-VOID
-conbgt(flag) int flag; {
- int x = -1, /* process group or SIGINT test */
- y = 0; /* isatty() test */
-/*
- Check for background operation, even if not running on real tty, so that
- background flag can be set correctly. If background status is detected,
- then Kermit will not issue its interactive prompt or most messages.
- If your prompt goes away, you can blame (and fix?) this function.
-*/
-
-/* Use process-group test if possible. */
-
-#ifdef POSIX /* We can do it in POSIX */
-#define PGROUP_T
-#else
-#ifdef BSD4 /* and in BSD 4.x. */
-#define PGROUP_T
-#else
-#ifdef HPUXJOBCTL /* and in most HP-UX's */
-#define PGROUP_T
-#else
-#ifdef TIOCGPGRP /* and anyplace that has this ioctl. */
-#define PGROUP_T
-#endif /* TIOCGPGRP */
-#endif /* HPUXJOBCTL */
-#endif /* BSD4 */
-#endif /* POSIX */
-
-#ifdef MIPS /* Except if it doesn't work... */
-#undef PGROUP_T
-#endif /* MIPS */
-
-#ifdef MINIX
-#undef PGROUP_T
-#endif /* MINIX */
-
-#ifdef PGROUP_T
-/*
- Semi-reliable process-group test. Check whether this process's group is
- the same as the controlling terminal's process group. This works if the
- getpgrp() call doesn't lie (as it does in the SUNOS System V environment).
-*/
- PID_T mypgrp = (PID_T)0; /* Kermit's process group */
- PID_T ctpgrp = (PID_T)0; /* The terminal's process group */
-#ifndef _POSIX_SOURCE
-/*
- The getpgrp() prototype is obtained from system header files for POSIX
- and Sys V R4 compilations. Other systems, who knows. Some complain about
- a duplicate declaration here, others don't, so it's safer to leave it in
- if we don't know for certain.
-*/
-#ifndef SVR4
-#ifndef PS2AIX10
-#ifndef HPUX9
- extern PID_T getpgrp();
-#endif /* HPUX9 */
-#endif /* PS2AIX10 */
-#endif /* SVR4 */
-#endif /* _POSIX_SOURCE */
-
-/* Get my process group. */
-
-#ifdef SVR3 /* Maybe this should be ATTSV? */
-/* This function is not described in SVID R2 */
- mypgrp = getpgrp();
- /* debug(F101,"ATTSV conbgt process group","",(int) mypgrp); */
-#else
-#ifdef POSIX
- mypgrp = getpgrp();
- /* debug(F101,"POSIX conbgt process group","",(int) mypgrp); */
-#else
-#ifdef OSFPC
- mypgrp = getpgrp();
- /* debug(F101,"OSF conbgt process group","",(int) mypgrp); */
-#else
-#ifdef QNX
- mypgrp = getpgrp();
- /* debug(F101,"QNX conbgt process group","",(int) mypgrp); */
-#else
-#ifdef OSF32 /* (was OSF40) */
- mypgrp = getpgrp();
- /* debug(F101,"Digital UNIX conbgt process group","",(int) mypgrp); */
-#else /* BSD, V7, etc */
-#ifdef MINIX2
- mypgrp = getpgrp();
-#else
- mypgrp = getpgrp(0);
-#endif /* MINIX2 */
- /* debug(F101,"BSD conbgt process group","",(int) mypgrp); */
-#endif /* OSF32 */
-#endif /* QNX */
-#endif /* OSFPC */
-#endif /* POSIX */
-#endif /* SVR3 */
-
-#ifdef MINIX
- /* MINIX does not support job control so Kermit is always in foreground */
- x = 0;
-
-#else /* Not MINIX */
-
-/* Now get controlling tty's process group */
-#ifdef BSD44ORPOSIX
- ctpgrp = tcgetpgrp(1); /* The POSIX way */
- /* debug(F101,"POSIX conbgt terminal process group","",(int) ctpgrp); */
-#else
- ioctl(1, TIOCGPGRP, &ctpgrp); /* Or the BSD way */
- /* debug(F101,"non-POSIX conbgt terminal process group","",(int) ctpgrp); */
-#endif /* BSD44ORPOSIX */
-
- if ((mypgrp > (PID_T) 0) && (ctpgrp > (PID_T) 0))
- x = (mypgrp == ctpgrp) ? 0 : 1; /* If they differ, then background. */
- else x = -1; /* If error, remember. */
- debug(F101,"conbgt process group test","",x);
-#endif /* PGROUP_T */
-#endif /* MINIX */
-
-/* Try to see if job control is available */
-
-#ifdef NOJC /* User override */
- jc = 0; /* No job control allowed */
- debug(F111,"NOJC","jc",jc);
-#else
-#ifdef BSD44
- jc = 1;
-#else
-#ifdef SVR4ORPOSIX /* POSIX actually tells us */
- debug(F100,"SVR4ORPOSIX jc test...","",0);
-#ifdef _SC_JOB_CONTROL
-#ifdef __bsdi__
- jc = 1;
-#else
-#ifdef __386BSD__
- jc = 1;
-#else
- jc = sysconf(_SC_JOB_CONTROL); /* Whatever system says */
- if (jc < 0) {
- debug(F101,"sysconf fails, jcshell","",jcshell);
- jc = (jchdlr == SIG_DFL) ? 1 : 0;
- } else
- debug(F111,"sysconf(_SC_JOB_CONTROL)","jc",jc);
-#endif /* __386BSD__ */
-#endif /* __bsdi__ */
-#else
-#ifdef _POSIX_JOB_CONTROL
- jc = 1; /* By definition */
- debug(F111,"_POSIX_JOB_CONTROL is defined","jc",jc);
-#else
- jc = 0; /* Assume job control not allowed */
- debug(F111,"SVR4ORPOSIX _SC/POSIX_JOB_CONTROL not defined","jc",jc);
-#endif /* _POSIX_JOB_CONTROL */
-#endif /* _SC_JOB_CONTROL */
-#else
-#ifdef BSD4
- jc = 1; /* Job control allowed */
- debug(F111,"BSD job control","jc",jc);
-#else
-#ifdef SVR3JC
- jc = 1; /* JC allowed */
- debug(F111,"SVR3 job control","jc",jc);
-#else
-#ifdef OXOS
- jc = 1; /* JC allowed */
- debug(F111,"X/OS job control","jc",jc);
-#else
-#ifdef HPUX9
- jc = 1; /* JC allowed */
- debug(F111,"HP-UX 9.0 job control","jc",jc);
-#else
-#ifdef HPUX10
- jc = 1; /* JC allowed */
- debug(F111,"HP-UX 10.0 job control","jc",jc);
-#else
- jc = 0; /* JC not allowed */
- debug(F111,"job control catch-all","jc",jc);
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* OXOS */
-#endif /* SVR3JC */
-#endif /* BSD4 */
-#endif /* SVR4ORPOSIX */
-#endif /* BSD44 */
-#endif /* NOJC */
- debug(F101,"conbgt jc","",jc);
-#ifndef NOJC
- debug(F101,"conbgt jcshell","",jcshell);
-/*
- At this point, if jc == 1 but jcshell == 0, it means that the OS supports
- job control, but the shell or other process we are running under does not
- (jcshell is set in sysinit()) and so if we suspend ourselves, nothing good
- will come of it. So...
-*/
- if (jc < 0) jc = 0;
- if (jc > 0 && jcshell == 0) jc = 0;
-#endif /* NOJC */
-
-/*
- Another background test.
- Test if SIGINT (terminal interrupt) is set to SIG_IGN (ignore),
- which is done by the shell (sh) if the program is started with '&'.
- Unfortunately, this is NOT done by csh or ksh so watch out!
- Note, it's safe to set SIGINT to SIG_IGN here, because further down
- we always set it to something else.
- Note: as of 16 Jul 1999, we also skip this test if we set SIGINT to
- SIG_IGN ourselves.
-*/
- if (x < 0 && !flag && !sigint_ign) { /* Didn't get good results above... */
-
- SIGTYP (*osigint)();
-
- osigint = signal(SIGINT,SIG_IGN); /* What is SIGINT set to? */
- sigint_ign = 1;
- x = (osigint == SIG_IGN) ? 1 : 0; /* SIG_IGN? */
- /* debug(F101,"conbgt osigint","",osigint); */
- /* debug(F101,"conbgt signal test","",x); */
- }
-
-/* Also check to see if we're running with redirected stdio. */
-/* This is not really background operation, but we want to act as though */
-/* it were. */
-
-#ifdef IKSD
- if (inserver) { /* Internet Kermit Server */
- backgrd = 0; /* is not in the background */
- return;
- }
-#endif /* IKSD */
-
- y = (isatty(0) && isatty(1)) ? 1 : 0;
- debug(F101,"conbgt isatty test","",y);
-
-#ifdef BSD29
-/* The process group and/or signal test doesn't work under these... */
- backgrd = !y;
-#else
-#ifdef sxaE50
- backgrd = !y;
-#else
-#ifdef MINIX
- backgrd = !y;
-#else
-#ifdef MINIX2
- backgrd = !y;
-#else
- if (x > -1)
- backgrd = (x || !y) ? 1 : 0;
- else backgrd = !y;
-#endif /* BSD29 */
-#endif /* sxaE50 */
-#endif /* MINIX */
-#endif /* MINIX2 */
- debug(F101,"conbgt backgrd","",backgrd);
-}
-
-/* C O N I N T -- Console Interrupt setter */
-
-/*
- First arg is pointer to function to handle SIGTERM & SIGINT (like Ctrl-C).
- Second arg is pointer to function to handle SIGTSTP (suspend).
-*/
-
-VOID /* Set terminal interrupt traps. */
-#ifdef CK_ANSIC
-#ifdef apollo
-conint(f,s) SIGTYP (*f)(), (*s)();
-#else
-conint(SIGTYP (*f)(int), SIGTYP (*s)(int))
-#endif /* apollo */
-#else
-conint(f,s) SIGTYP (*f)(), (*s)();
-#endif /* CK_ANSIC */
-/* conint */ {
-
- debug(F101,"conint conistate","",conistate);
-
- conbgt(0); /* Do background test. */
-
-/* Set the desired handlers for hangup and software termination. */
-
-#ifdef SIGTERM
- signal(SIGTERM,f); /* Software termination */
-#endif /* SIGTERM */
-
-/*
- Prior to July 1999 we used to call sighup() here but now it's called in
- sysinit() so SIGHUP can be caught during execution of the init file or
- a kerbang script.
-*/
-
-/* Now handle keyboard stop, quit, and interrupt signals. */
-/* Check if invoked in background -- if so signals set to be ignored. */
-/* However, if running under a job control shell, don't ignore them. */
-/* We won't be getting any, as we aren't in the terminal's process group. */
-
- debug(F101,"conint backgrd","",backgrd);
- debug(F101,"conint jc","",jc);
-
- if (backgrd && !jc) { /* In background, ignore signals */
- debug(F101,"conint background ignoring signals, jc","",jc);
-#ifdef SIGTSTP
- signal(SIGTSTP,SIG_IGN); /* Keyboard stop */
-#endif /* SIGTSTP */
- signal(SIGQUIT,SIG_IGN); /* Keyboard quit */
- signal(SIGINT,SIG_IGN); /* Keyboard interrupt */
- sigint_ign = 1;
- conistate = CONI_NOI;
- } else { /* Else in foreground or suspended */
- debug(F101,"conint foreground catching signals, jc","",jc);
- signal(SIGINT,f); /* Catch terminal interrupt */
- sigint_ign = (f == SIG_IGN) ? 1 : 0;
-
-#ifdef SIGTSTP /* Keyboard stop (suspend) */
- /* debug(F101,"conint SIGSTSTP","",s); */
- if (s == NULL) s = SIG_DFL;
-#ifdef NOJC /* No job control allowed. */
- signal(SIGTSTP,SIG_IGN);
-#else /* Job control allowed */
- if (jc) /* if available. */
- signal(SIGTSTP,s);
- else
- signal(SIGTSTP,SIG_IGN);
-#endif /* NOJC */
-#endif /* SIGTSTP */
-
-#ifndef OXOS
-#ifdef SVORPOSIX
-#ifndef FIONREAD /* Watch out, we don't know this... */
-#ifndef SELECT
-#ifndef CK_POLL
-#ifndef RDCHK
- signal(SIGQUIT,esctrp); /* Quit signal, Sys III/V. */
-#endif /* RDCHK */
-#endif /* CK_POLL */
-#endif /* SELECT */
-#endif /* FIONREAD */
- if (conesc) conesc = 0; /* Clear out pending escapes */
-#else
-#ifdef V7
- signal(SIGQUIT,esctrp); /* V7 like Sys III/V */
- if (conesc) conesc = 0;
-#else
-#ifdef aegis
- signal(SIGQUIT,f); /* Apollo, catch it like others. */
-#else
- signal(SIGQUIT,SIG_IGN); /* Others, ignore like 4D & earlier. */
-#endif /* aegis */
-#endif /* V7 */
-#endif /* SVORPOSIX */
-#endif /* OXOS */
- conistate = CONI_INT;
- }
-}
-
-
-/* C O N N O I -- Reset console terminal interrupts */
-
-VOID
-connoi() { /* Console-no-interrupts */
-
- debug(F101,"connoi conistate","",conistate);
-#ifdef SIGTSTP
- signal(SIGTSTP,SIG_IGN); /* Suspend */
-#endif /* SIGTSTP */
- conint(SIG_IGN,SIG_IGN); /* Interrupt */
- sigint_ign = 1; /* Remember we did this ourselves */
-#ifdef SIGQUIT
- signal(SIGQUIT,SIG_IGN); /* Quit */
-#endif /* SIGQUIT */
-#ifdef SIGTERM
- signal(SIGTERM,SIG_IGN); /* Term */
-#endif /* SIGTERM */
- conistate = CONI_NOI;
-}
-
-/* I N I T R A W Q -- Set up to read /dev/kmem for character count. */
-
-#ifdef V7
-/*
- Used in Version 7 to simulate Berkeley's FIONREAD ioctl call. This
- eliminates blocking on a read, because we can read /dev/kmem to get the
- number of characters available for raw input. If your system can't
- or you won't let the world read /dev/kmem then you must figure out a
- different way to do the counting of characters available, or else replace
- this by a dummy function that always returns 0.
-*/
-/*
- * Call this routine as: initrawq(tty)
- * where tty is the file descriptor of a terminal. It will return
- * (as a char *) the kernel-mode memory address of the rawq character
- * count, which may then be read. It has the side-effect of flushing
- * input on the terminal.
- */
-/*
- * John Mackin, Physiology Dept., University of Sydney (Australia)
- * ...!decvax!mulga!physiol.su.oz!john
- *
- * Permission is hereby granted to do anything with this code, as
- * long as this comment is retained unmodified and no commercial
- * advantage is gained.
- */
-#ifndef MINIX
-#ifndef MINIX2
-#ifndef COHERENT
-#include <a.out.h>
-#include <sys/proc.h>
-#endif /* COHERENT */
-#endif /* MINIX2 */
-#endif /* MINIX */
-
-#ifdef COHERENT
-#include <l.out.h>
-#include <sys/proc.h>
-#endif /* COHERENT */
-
-char *
-initrawq(tty) int tty; {
-#ifdef MINIX
- return(0);
-#else
-#ifdef MINIX2
- return(0);
-#else
-#ifdef UTS24
- return(0);
-#else
-#ifdef BSD29
- return(0);
-#else
- long lseek();
- static struct nlist nl[] = {
- {PROCNAME},
- {NPROCNAME},
- {""}
- };
- static struct proc *pp;
- char *qaddr, *p, c;
- int m;
- PID_T pid, me;
- NPTYPE xproc; /* Its type is defined in makefile. */
- int catch();
-
- me = getpid();
- if ((m = open("/dev/kmem", 0)) < 0) err("kmem");
- nlist(BOOTNAME, nl);
- if (nl[0].n_type == 0) err("proc array");
-
- if (nl[1].n_type == 0) err("nproc");
-
- lseek(m, (long)(nl[1].n_value), 0);
- read (m, &xproc, sizeof(xproc));
- saval = signal(SIGALRM, catch);
- if ((pid = fork()) == 0) {
- while(1)
- read(tty, &c, 1);
- }
- alarm(2);
-
- if(setjmp(jjbuf) == 0) {
- while(1)
- read(tty, &c, 1);
- }
- signal(SIGALRM, SIG_DFL);
-
-#ifdef DIRECT
- pp = (struct proc *) nl[0].n_value;
-#else
- if (lseek(m, (long)(nl[0].n_value), 0) < 0L) err("seek");
- if (read(m, &pp, sizeof(pp)) != sizeof(pp)) err("no read of proc ptr");
-#endif
- lseek(m, (long)(nl[1].n_value), 0);
- read(m, &xproc, sizeof(xproc));
-
- if (lseek(m, (long)pp, 0) < 0L) err("Can't seek to proc");
- if ((p = malloc(xproc * sizeof(struct proc))) == NULL) err("malloc");
- if (read(m,p,xproc * sizeof(struct proc)) != xproc*sizeof(struct proc))
- err("read proc table");
- for (pp = (struct proc *)p; xproc > 0; --xproc, ++pp) {
- if (pp -> p_pid == (short) pid) goto iout;
- }
- err("no such proc");
-
-iout:
- close(m);
- qaddr = (char *)(pp -> p_wchan);
- free (p);
- kill(pid, SIGKILL);
- wait((WAIT_T *)0);
- return (qaddr);
-#endif
-#endif
-#endif
-#endif
-}
-
-/* More V7-support functions... */
-
-static VOID
-err(s) char *s; {
- char buf[200];
-
- ckmakmsg(buf,200,"fatal error in initrawq: ", s, NULL, NULL);
- perror(buf);
- doexit(1,-1);
-}
-
-static VOID
-catch(foo) int foo; {
- longjmp(jjbuf, -1);
-}
-
-
-/* G E N B R K -- Simulate a modem break. */
-
-#ifdef MINIX
-#define BSPEED B110
-#else
-#ifdef MINIX2
-#define BSPEED B110
-#else
-#define BSPEED B150
-#endif /* MINIX2 */
-#endif /* MINIX */
-
-#ifndef MINIX2
-VOID
-genbrk(fn,msec) int fn, msec; {
- struct sgttyb ttbuf;
- int ret, sospeed, x, y;
-
- ret = ioctl(fn, TIOCGETP, &ttbuf);
- sospeed = ttbuf.sg_ospeed;
- ttbuf.sg_ospeed = BSPEED;
- ret = ioctl(fn, TIOCSETP, &ttbuf);
- y = (int)strlen(brnuls);
- x = ( BSPEED * 100 ) / msec;
- if (x > y) x = y;
- ret = write(fn, brnuls, (( BSPEED * 100 ) / msec ));
- ttbuf.sg_ospeed = sospeed;
- ret = ioctl(fn, TIOCSETP, &ttbuf);
- ret = write(fn, "@", 1);
- return;
-}
-#endif /* MINIX2 */
-
-#ifdef MINIX2
-int
-genbrk(fn,msec) int fn, msec; {
- struct termios ttbuf;
- int ret, x, y;
- speed_t sospeed;
-
- ret = tcgetattr(fn, &ttbuf);
- sospeed = ttbuf.c_ospeed;
- ttbuf.c_ospeed = BSPEED;
- ret = tcsetattr(fn,TCSADRAIN, &ttbuf);
- y = (int)strlen(brnuls);
- x = ( BSPEED * 100 ) / msec;
- if (x > y) x = y;
- ret = write(fn, brnuls, (( BSPEED * 100 ) / msec ));
- ttbuf.c_ospeed = sospeed;
- ret = tcsetattr(fn, TCSADRAIN, &ttbuf);
- ret = write(fn, "@", 1);
- return ret;
-}
-#endif /* MINIX2 */
-#endif /* V7 */
-
-/*
- I N C H K -- Check if chars waiting to be read on given file descriptor.
-
- This routine is a merger of ttchk() and conchk().
- Call with:
- channel == 0 to check console.
- channel == 1 to check communications connection.
- and:
- fd = file descriptor.
- Returns:
- >= 0: number of characters waiting, 0 or greater,
- -1: on any kind of error,
- -2: if there is (definitely) no connection.
- Note: In UNIX we don't have to call nettchk() because a socket
- file descriptor works just like in serial i/o, ioctls and all.
- (But this will change if we add non-file-descriptor channels,
- such as IBM X.25 for AIX...)
-*/
-static int
-in_chk(channel, fd) int channel, fd; {
- int x, n = 0; /* Workers, n = return value */
- extern int clsondisc; /* Close on disconnect */
-/*
- The first section checks to make sure we have a connection,
- but only if we're in local mode.
-*/
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"in_chk entry",ckitoa(fd),channel);
- debug(F101,"in_chk ttyfd","",ttyfd);
- debug(F101,"in_chk ttpty","",ttpty);
- }
-#endif /* DEBUG */
-/*
- But don't say connection is gone if we have any buffered-stuff.
-*/
-#ifdef TTLEBUF
- debug(F101,"in_chk ttpush","",ttpush);
- if (channel == 1) {
- if (ttpush >= 0)
- n++;
- n += le_inbuf();
- if (n > 0)
- return(n);
- }
-#endif /* TTLEBUF */
-
-#ifdef NETPTY
-#ifdef HAVE_PTYTRAP
- /* Special handling for HP-UX pty i/o */
- if (ttpty && pty_trap_pending(ttyfd) > 0) {
- if (pty_trap_handler(ttyfd) > 0) {
- ttclos(0);
- return(-2);
- }
- }
-#endif /* HAVE_PTYTRAP */
-#endif /* NETPTY */
-
- if (channel) { /* Checking communications channel */
- if (ttyfd < 0) { /* No connection */
- return(-2); /* That's what this means */
- } else if (xlocal && /* In local mode */
- (!netconn /* Serial connection or */
-#ifdef TN_COMPORT
- || istncomport() /* Telnet Com Port */
-#endif /* TN_COMPORT */
- ) && ttcarr != CAR_OFF /* with CARRIER WATCH ON (or AUTO) */
-#ifdef COMMENT
-#ifdef MYREAD
-/*
- Seems like this would be a good idea but it prevents C-Kermit from
- popping back to the prompt automatically when carrier drops. However,
- commenting this out prevents us from seeing the NO CARRIER message.
- Needs more work...
-*/
- && my_count < 1 /* Nothing in our internal buffer */
-#endif /* MYREAD */
-#endif /* COMMENT */
- ) {
- int x;
- x = ttgmdm(); /* So get modem signals */
- debug(F101,"in_chk close-on-disconnect","",clsondisc);
- if (x > -1) { /* Check for carrier */
- if (!(x & BM_DCD)) { /* No carrier */
- debug(F101,"in_chk carrier lost","",x);
- if (clsondisc) /* If "close-on-disconnect" */
- ttclos(0); /* close device & release lock. */
- return(-2); /* This means "disconnected" */
- }
- /* In case I/O to device after CD dropped always fails */
- /* as in Debian Linux 2.1 and Unixware 2.1... */
- } else {
- debug(F101,"in_chk ttgmdm I/O error","",errno);
- debug(F101,"in_chk ttgmdm gotsigs","",gotsigs);
- if (gotsigs) { /* If we got signals before... */
- if (errno == 5 || errno == 6) { /* I/O error etc */
- if (clsondisc) /* like when modem hangs up */
- ttclos(0);
- return(-2);
- }
- }
- /* If we never got modem signals successfully on this */
- /* connection before, we can't conclude that THIS failure */
- /* means the connection was lost. */
- return(0);
- }
- }
- }
-
-/* We seem to have a connection so now see if any bytes are waiting on it */
-
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- n += SSL_pending(ssl_active_flag?ssl_con:tls_con);
- debug(F101,"in_chk SSL_pending","",n);
- if (n < 0) {
- ttclos(0);
- return(-1);
- } else if (n > 0) {
- return(n);
- }
- }
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
- /* It is not safe to read any data when using encrypted Klogin */
- if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN) {
-#ifdef KRB4
- if (ttnproto == NP_EK4LOGIN) {
- n += krb4_des_avail(ttyfd);
- debug(F101,"in_chk krb4_des_avail","",n);
- }
-#endif /* KRB4 */
-#ifdef KRB5
- if (ttnproto == NP_EK5LOGIN) {
- n += krb5_des_avail(ttyfd);
- debug(F101,"in_chk krb5_des_avail","",n);
- }
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- n += krb5_u2u_avail(ttyfd);
- debug(F101,"in_chk krb5_des_avail","",n);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
- if (n < 0) /* Is this right? */
- return(-1);
- else
- return(n);
- }
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
-
- errno = 0; /* Reset this so we log good info */
-#ifdef FIONREAD
- x = ioctl(fd, FIONREAD, &n); /* BSD and lots of others */
-#ifdef DEBUG /* (the more the better) */
- if (deblog) {
- debug(F101,"in_chk FIONREAD return code","",x);
- debug(F101,"in_chk FIONREAD count","",n);
- debug(F101,"in_chk FIONREAD errno","",errno);
- }
-#endif /* DEBUG */
-#else /* FIONREAD not defined */
-/*
- Here, if (netconn && ttnet == NET_TCPB), we might try calling recvmsg()
- with flags MSG_PEEK|MSG_DONTWAIT on the socket (ttyfd), except this is not
- portable (MSG_DONTWAIT isn't defined in any of the <sys/socket.h> files
- that I looked at, but it is needed to prevent the call from blocking), and
- the msghdr struct differs from place to place, so we would need another
- avalanche of ifdefs. Still, when FIONREAD is not available, this is the
- only other known method of asking the OS for the *number* of characters
- available for reading.
-*/
-#ifdef V7 /* UNIX V7: look in kernel memory */
-#ifdef MINIX
- n = 0; /* But not in MINIX */
-#else
-#ifdef MINIX2
- n = 0;
-#else
- lseek(kmem[TTY], (long) qaddr[TTY], 0); /* 7th Edition Unix */
- x = read(kmem[TTY], &n, sizeof(int));
- if (x != sizeof(int))
- n = 0;
-#endif /* MINIX2 */
-#endif /* MINIX */
-#else /* Not V7 */
-#ifdef PROVX1
- x = ioctl(fd, TIOCQCNT, &ttbuf); /* DEC Pro/3xx Venix V.1 */
- n = ttbuf.sg_ispeed & 0377; /* Circa 1984 */
- if (x < 0) n = 0;
-#else
-#ifdef MYREAD
-/*
- Here we skip all the undependable and expensive calls below if we
- already have something in our internal buffer. This tends to work quite
- nicely, so the only really bad case remaining is the one in which neither
- FIONREAD or MYREAD are defined, which is increasingly rare these days.
-*/
- if (channel != 0 && my_count > 0) {
- debug(F101,"in_chk buf my_count","",my_count);
- n = my_count; /* n was 0 before we got here */
- return(n);
- }
-#endif /* MYREAD */
-/*
- rdchk(), select(), and poll() tell us *if* data is available to be read, but
- not how much, so these should be used only as a final resort. Especially
- since these calls tend to add a lot overhead.
-*/
-#ifdef RDCHK /* This mostly SCO-specific */
- n = rdchk(fd);
- debug(F101,"in_chk rdchk","",n);
-#else /* No RDCHK */
-#ifdef SELECT
-#ifdef Plan9
- /* Only allows select on the console ... don't ask */
- if (channel == 0)
-#endif /* Plan9 */
- {
- fd_set rfds; /* Read file descriptors */
-#ifdef BELLV10
- FD_ZERO(rfds); /* Initialize them */
- FD_SET(fd,rfds); /* We want to look at this fd */
-#else
- FD_ZERO(&rfds); /* Initialize them */
- FD_SET(fd,&rfds); /* We want to look at this fd */
- tv.tv_sec = tv.tv_usec = 0L; /* A 0-valued timeval structure */
-#endif /* BELLV10 */
-#ifdef Plan9
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk Plan 9 select","",n);
-#else
-#ifdef BELLV10
- n = select( 128, rfds, (fd_set *)0, (fd_set *)0, 0 );
- debug(F101,"in_chk BELLV10 select","",n);
-#else
-#ifdef BSD44
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk BSD44 select","",n);
-#else
-#ifdef BSD43
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk BSD43 select","",n);
-#else
-#ifdef SOLARIS
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk SOLARIS select","",n);
-#else
-#ifdef QNX6
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk QNX6 select","",n);
-#else
-#ifdef QNX
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk QNX select","",n);
-#else
-#ifdef COHERENT
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk COHERENT select","",n);
-#else
-#ifdef SVR4
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk SVR4 select","",n);
-#else
-#ifdef __linux__
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk LINUX select","",n);
-#ifdef OSF
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk OSF select","",n);
-#else
- n = select( FD_SETSIZE, &rfds, (int *)0, (int *)0, &tv );
- debug(F101,"in_chk catchall select","",n);
-#endif /* OSF */
-#endif /* __linux__ */
-#endif /* SVR4 */
-#endif /* COHERENT */
-#endif /* QNX */
-#endif /* QNX6 */
-#endif /* SOLARIS */
-#endif /* BSD43 */
-#endif /* BSD44 */
-#endif /* BELLV10 */
-#endif /* Plan9 */
- }
-#else /* Not SELECT */
-#ifdef CK_POLL
- {
- struct pollfd pfd;
-
- pfd.fd = fd;
- pfd.events = POLLIN;
- pfd.revents = 0;
- n = poll(&pfd, 1, 0);
- debug(F101,"in_chk poll","",n);
- if ((n > 0) && (pfd.revents & POLLIN))
- n = 1;
- }
-#endif /* CK_POLL */
-#endif /* SELECT */
-#endif /* RDCHK */
-#endif /* PROVX1 */
-#endif /* V7 */
-#endif /* FIONREAD */
-
-/* From here down, treat console and communication device differently... */
-
- if (channel == 0) { /* Console */
-
-#ifdef SVORPOSIX
-#ifndef FIONREAD
-#ifndef SELECT
-#ifndef CK_POLL
-#ifndef RDCHK
-/*
- This is the hideous hack used in System V and POSIX systems that don't
- support FIONREAD, rdchk(), select(), poll(), etc, in which the user's
- CONNECT-mode escape character is attached to SIGQUIT. Used, obviously,
- only on the console.
-*/
- if (conesc) { /* Escape character typed == SIGQUIT */
- debug(F100,"in_chk conesc","",conesc);
- conesc = 0;
- signal(SIGQUIT,esctrp); /* Restore signal */
- n += 1;
- }
-#endif /* RDCHK */
-#endif /* CK_POLL */
-#endif /* SELECT */
-#endif /* FIONREAD */
-#endif /* SVORPOSIX */
-
- return(n); /* Done with console */
- }
-
- if (channel != 0) { /* Communications connection */
-
-#ifdef MYREAD
-#ifndef FIONREAD
-/*
- select() or rdchk(), etc, has told us that something is waiting, but we
- don't know how much. So we do a read to get it and then we know. Note:
- This read is NOT nonblocking if nothing is there (because of VMIN=1), but
- it should be safe in this case since the OS tells us at least one byte is
- waiting to be read, and MYREAD reads return as much as is there without
- waiting for any more. Controlled tests on Solaris and Unixware (with
- FIONREAD deliberately undefined) show this to be true.
-*/
- debug(F101,"in_chk read my_count","",my_count);
- debug(F101,"in_chk read n","",n);
- if (n > 0 && my_count == 0) {
- /* This also catches disconnects etc */
- /* Do what mygetbuf does except don't grab a character */
- my_count = myfillbuf();
- my_item = -1; /* ^^^ */
- debug(F101,"in_chk myfillbuf my_count","",my_count);
- if (my_count < 0)
- return(-1);
- else
- n = 0; /* NB: n is replaced by my_count */
- }
-#endif /* FIONREAD */
-/*
- Here we add whatever we think is unread to what is still in our
- our internal buffer. Thus the importance of setting n to 0 just above.
-*/
- debug(F101,"in_chk my_count","",my_count);
- debug(F101,"in_chk n","",n);
- if (my_count > 0)
- n += my_count;
-#endif /* MYREAD */
- }
- debug(F101,"in_chk result","",n);
-
- /* Errors here don't prove the connection has dropped so just say 0 */
-
- return(n < 0 ? 0 : n);
-}
-
-
-/* T T C H K -- Tell how many characters are waiting in tty input buffer */
-
-int
-ttchk() {
- int fd;
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
- return(in_chk(1,fd));
-}
-
-/* T T X I N -- Get n characters from tty input buffer */
-
-/* Returns number of characters actually gotten, or -1 on failure */
-
-/* Intended for use only when it is known that n characters are actually */
-/* Available in the input buffer. */
-
-int
-ttxin(n,buf) int n; CHAR *buf; {
- register int x = 0, c = -2;
-#ifdef TTLEBUF
- register int i = 0;
-#endif /* TTLEBUF */
- int fd;
-
- if (n < 1) /* Nothing to do */
- return(0);
-
-#ifdef TTLEBUF
- if (ttpush >= 0) {
- buf[0] = ttpush; /* Put pushed char in buffer*/
- ttpush = -1; /* Clear the push buffer */
- if (ttchk() > 0)
- return(ttxin(n-1, &buf[1]) + 1);
- else
- return(1);
- }
- if (le_data) {
- while (le_inbuf() > 0) {
- if (le_getchar(&buf[i])) {
- i++;
- n--;
- }
- }
- if (ttchk() > 0)
- return(ttxin(n,&buf[i])+i);
- else
- return(i);
- }
-#endif /* TTLEBUF */
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef SUNX25
- if (netconn && (ttnet == NET_SX25)) /* X.25 connection */
- return(x25xin(n,buf));
-#endif /* SUNX25 */
-
-#ifdef IBMX25
- /* riehm: possibly not needed. Test worked with normal reads and writes */
- if (netconn && (ttnet == NET_IX25)) { /* X.25 connection */
- x = x25xin(n,buf);
- if (x > 0) buf[x] = '\0';
- return(x);
- }
-#endif /* IBMX25 */
-
-#ifdef MYREAD
- debug(F101,"ttxin MYREAD","",n);
- while (x < n) {
- c = myread();
- if (c < 0) {
- debug(F101,"ttxin myread returns","",c);
- if (c == -3) x = -1;
- break;
- }
- buf[x++] = c & ttpmsk;
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
- /* It is impossible to know how many characters are waiting */
- /* to be read when you are using Encrypted Rlogin or SSL */
- /* as the transport since the number of real data bytes */
- /* can be greater or less than the number of bytes on the */
- /* wire which is what ttchk() returns. */
- if (netconn && (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN))
- if (ttchk() <= 0)
- break;
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag)
- if (ttchk() <= 0)
- break;
-#endif /* CK_SSL */
- }
-#else
- debug(F101,"ttxin READ","",n);
- x = read(fd,buf,n);
- for (c = 0; c < n; c++) /* Strip any parity */
- buf[c] &= ttpmsk;
-#endif /* MYREAD */
-
- debug(F101,"ttxin x","",x); /* Done */
- if (x > 0) buf[x] = '\0';
- if (x < 0) x = -1;
- return(x);
-}
-
-/* T T O L -- Write string s, length n, to communication device. */
-/*
- Returns:
- >= 0 on success, number of characters actually written.
- -1 on failure.
-*/
-#ifdef CK_ENCRYPTION
-CHAR * xpacket = NULL;
-int nxpacket = 0;
-#endif /* CK_ENCRYPTION */
-
-#define TTOLMAXT 5
-int
-ttol(s,n) int n; CHAR *s; {
- int x, len, tries, fd;
-#ifdef CKXXCHAR
- extern int dblflag; /* For SET SEND DOUBLE-CHARACTER */
- extern short dblt[];
- CHAR *p = NULL, *p2, *s2, c;
- int n2 = 0;
-#endif /* CKXXCHAR */
-
- if (ttyfd < 0) /* Not open? */
- return(-3);
-#ifdef DEBUG
- if (deblog) {
- /* debug(F101,"ttol ttyfd","",ttyfd); */
- ckhexdump("ttol s",s,n);
- }
-#endif /* DEBUG */
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdout;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef CKXXCHAR
-/* Double any characters that must be doubled. */
- debug(F101,"ttol dblflag","",dblflag);
- if (dblflag) {
- p = (CHAR *) malloc(n + n + 1);
- if (p) {
- s2 = s;
- p2 = p;
- n2 = 0;
- while (*s2) {
- c = *s2++;
- *p2++ = c;
- n2++;
- if (dblt[(unsigned) c] & 2) {
- *p2++ = c;
- n2++;
- }
- }
- s = p;
- n = n2;
- s[n] = '\0';
- }
-#ifdef DEBUG
- ckhexdump("ttol doubled s",s,n);
-#endif /* DEBUG */
- }
-#endif /* CKXXCHAR */
-
- tries = TTOLMAXT; /* Allow up to this many tries */
- len = n; /* Remember original length */
-
-#ifdef CK_ENCRYPTION
-/*
- This is to avoid encrypting a packet that is already encrypted, e.g.
- when we resend a packet directly out of the packet buffer, and also to
- avoid encrypting a constant (literal) string, which can cause a memory
- fault.
-*/
- if (TELOPT_ME(TELOPT_ENCRYPTION)) {
- int x;
- if (nxpacket < n) {
- if (xpacket) {
- free(xpacket);
- xpacket = NULL;
- nxpacket = 0;
- }
- x = n > 10240 ? n : 10240;
- xpacket = (CHAR *)malloc(x);
- if (!xpacket) {
- fprintf(stderr,"ttol malloc failure\n");
- return(-1);
- } else
- nxpacket = x;
- }
- memcpy((char *)xpacket,(char *)s,n);
- s = xpacket;
- ck_tn_encrypt((char *)s,n);
- }
-#endif /* CK_ENCRYPTION */
-
- while (n > 0 &&
- (tries-- > 0
-#ifdef CK_ENCRYPTION
- /* keep trying if we are encrypting */
- || TELOPT_ME(TELOPT_ENCRYPTION)
-#endif /* CK_ENCRYPTION */
- )) { /* Be persistent */
- debug(F101,"ttol try","",TTOLMAXT - tries);
-#ifdef BEOSORBEBOX
- if (netconn && !ttpipe && !ttpty)
- x = nettol((char *)s,n); /* Write string to device */
- else
-#endif /* BEOSORBEBOX */
-#ifdef IBMX25
- if (ttnet == NET_IX25)
- /*
- * this is a more controlled way of writing to X25
- * STREAMS, however write should also work!
- */
- x = x25write(ttyfd, s, n);
- else
-#endif /* IBMX25 */
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error;
- /* Write using SSL */
- ssl_retry:
- if (ssl_active_flag)
- x = SSL_write(ssl_con, s, n);
- else
- x = SSL_write(tls_con, s, n);
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,x)) {
- case SSL_ERROR_NONE:
- if (x == n)
- return(len);
- s += x;
- n -= x;
- goto ssl_retry;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- x = 0;
- break;
- case SSL_ERROR_SYSCALL:
- if (x != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- ttclos(0);
- return(-3);
- }
- } else
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- return(krb4_des_write(ttyfd,s,n));
- } else
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- return(krb5_des_write(ttyfd,(char *)s,n,0));
- } else
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- return(krb5_u2u_write(ttyfd,(char *)s,n));
- } else
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
- x = write(fd,s,n); /* Write string to device */
-
- if (x == n) { /* Worked? */
- debug(F101,"ttol ok","",x); /* OK */
-#ifdef CKXXCHAR
- if (p) free(p);
-#endif /* CKXXCHAR */
- return(len); /* Done */
- } else if (x < 0) { /* No, got error? */
- debug(F101,"ttol write error","",errno);
-#ifdef EWOULDBLOCK
- if (errno == EWOULDBLOCK) {
- msleep(10);
- continue;
- } else
-#endif /* EWOULDBLOCK */
-#ifdef TCPSOCKET
- if (netconn && ttnet == NET_TCPB) {
- debug(F101,"ttol TCP error","",errno);
- ttclos(0); /* Close the connection. */
- x = -3;
- }
-#endif /* TCPSOCKET */
-#ifdef CKXXCHAR
- if (p) free(p);
-#endif /* CKXXCHAR */
- return(x);
- } else { /* No error, so partial success */
- debug(F101,"ttol partial","",x); /* This never happens */
- s += x; /* Point to part not written yet */
- n -= x; /* Adjust length */
- if (x > 0) msleep(10); /* Wait 10 msec */
- } /* Go back and try again */
- }
-#ifdef CKXXCHAR
- if (p) free(p);
-#endif /* CKXXCHAR */
- return(n < 1 ? len : -1); /* Return the results */
-}
-
-/* T T O C -- Output a character to the communication line */
-
-/*
- This function should only be used for interactive, character-mode operations,
- like terminal connection, script execution, dialer i/o, where the overhead
- of the signals and alarms does not create a bottleneck.
-*/
-int
-#ifdef CK_ANSIC
-ttoc(char c)
-#else
-ttoc(c) char c;
-#endif /* CK_ANSIC */
-/* ttoc */ {
-#define TTOC_TMO 15 /* Timeout in case we get stuck */
- int xx, fd;
-
- if (ttyfd < 0) /* Check for not open. */
- return(-1);
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdout;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
- c &= 0xff;
- /* debug(F101,"ttoc","",(CHAR) c); */
- saval = signal(SIGALRM,timerh); /* Enable timer interrupt */
- xx = alarm(TTOC_TMO); /* for this many seconds. */
- if (xx < 0) xx = 0; /* Save old alarm value. */
- /* debug(F101,"ttoc alarm","",xx); */
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) { /* Timer went off? */
- ttimoff(); /* Yes, cancel this alarm. */
- if (xx - TTOC_TMO > 0) alarm(xx - TTOC_TMO); /* Restore previous one */
- /* debug(F100,"ttoc timeout","",0); */
-#ifdef NETCONN
- if (!netconn) {
-#endif /* NETCONN */
- debug(F101,"ttoc timeout","",c);
- if (ttflow == FLO_XONX) {
- debug(F101,"ttoc flow","",ttflow); /* Maybe we're xoff'd */
-#ifndef Plan9
-#ifdef POSIX
- /* POSIX way to unstick. */
- debug(F100,"ttoc tcflow","",tcflow(ttyfd,TCOON));
-#else
-#ifdef BSD4 /* Berkeley way to do it. */
-#ifdef TIOCSTART
-/* .... Used to be "ioctl(ttyfd, TIOCSTART, 0);". Who knows? */
- {
- int x = 0;
- debug(F101,"ttoc TIOCSTART","",ioctl(ttyfd, TIOCSTART, &x));
- }
-#endif /* TIOCSTART */
-#endif /* BSD4 */
- /* Is there a Sys V way to do this? */
-#endif /* POSIX */
-#endif /* Plan9 */
- }
-#ifdef NETCONN
- }
-#endif /* NETCONN */
- return(-1); /* Return failure code. */
- } else {
- int rc;
-#ifdef BEOSORBEBOX
-#ifdef NETCONN
- if (netconn && !ttpipe && !ttpty)
- rc = nettoc(c);
- else
-#endif /* BEOSORBEBOX */
-#endif /* NETCONN */
-#ifdef CK_ENCRYPTION
- if (TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(&c,1);
-#endif /* CK_ENCRYPTION */
-#ifdef IBMX25
- /* riehm: maybe this isn't necessary after all. Test program
- * worked fine with data being sent and retrieved with normal
- * read's and writes!
- */
- if (ttnet == NET_IX25)
- rc = x25write(ttyfd,&c,1); /* as above for X25 streams */
- else
-#endif /* IBMX25 */
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error;
- /* Write using SSL */
- if (ssl_active_flag)
- rc = SSL_write(ssl_con, &c, 1);
- else
- rc = SSL_write(tls_con, &c, 1);
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,rc)){
- case SSL_ERROR_NONE:
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- rc = 0;
- break;
- case SSL_ERROR_SYSCALL:
- if (rc != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- ttclos(0);
- return(-1);
- }
- } else
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- rc = (krb4_des_write(ttyfd,(char *)&c,1) == 1);
- } else
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- rc = (krb5_des_write(ttyfd,&c,1,0) == 1);
- } else
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- rc = (krb5_u2u_write(ttyfd,&c,1) == 1);
- } else
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
- rc = write(fd,&c,1); /* Try to write the character. */
- if (rc < 1) { /* Failed */
- ttimoff(); /* Turn off the alarm. */
- alarm(xx); /* Restore previous alarm. */
- debug(F101,"ttoc errno","",errno); /* Log the error, */
- return(-1); /* and return the error code. */
- }
- }
- ttimoff(); /* Success, turn off the alarm. */
- alarm(xx); /* Restore previous alarm. */
- return(0); /* Return good code. */
-}
-
-/* T T I N L -- Read a record (up to break character) from comm line. */
-/*
- Reads up to "max" characters from the connection, terminating on:
- (a) the packet length field if the "turn" argument is zero, or
- (b) on the packet-end character (eol) if the "turn" argument is nonzero
- (c) a certain number of Ctrl-C's in a row
-
- Returns:
- >= 0, the number of characters read upon success;
- -1 if "max" exceeded, timeout, or other correctable error;
- -2 on user interruption (c);
- -3 on fatal error like connection lost.
-
- The name of this routine dates from the early days when Kermit packets
- were, indeed, always lines of text. That was before control-character
- unprefixing and length-driven packet framing were introduced, which this
- version handle. NB: this routine is ONLY for reading incoming Kermit
- packets, nothing else. To read other kinds of incoming material, use
- ttinc() or ttxin().
-
- The bytes that were input are copied into "dest" with their parity bits
- stripped if parity was selected. Returns the number of bytes read.
- Bytes after the eol are available upon the next call to this function.
-
- The idea is to minimize the number of system calls per packet, and also to
- minimize timeouts. This function is the inner loop of the protocol and must
- be as efficient as possible. The current strategy is to use myread(), a
- macro to manage buffered (and generally nonblocking) reads.
-
- WARNING: This function calls parchk(), which is defined in another module.
- Normally, ckutio.c does not depend on code from any other module, but there
- is an exception in this case because all the other ck?tio.c modules also
- need to call parchk(), so it's better to have it defined in a common place.
-*/
-#ifdef CTRLC
-#undef CTRLC
-#endif /* CTRLC */
-#define CTRLC '\03'
-/*
- We have four different declarations here because:
- (a) to allow Kermit to be built without the automatic parity sensing feature
- (b) one of each type for ANSI C, one for non-ANSI.
-*/
-#ifndef NOXFER
-
-static int pushedback = 0;
-
-int
-#ifdef PARSENSE
-#ifdef CK_ANSIC
-ttinl(CHAR *dest, int max,int timo, CHAR eol, CHAR start, int turn)
-#else
-ttinl(dest,max,timo,eol,start,turn) int max,timo,turn; CHAR *dest, eol, start;
-#endif /* CK_ANSIC */
-#else /* not PARSENSE */
-#ifdef CK_ANSIC
-ttinl(CHAR *dest, int max,int timo, CHAR eol)
-#else
-ttinl(dest,max,timo,eol) int max,timo; CHAR *dest, eol;
-#endif /* CK_ANSIC */
-#endif /* PARSENSE */
-/* ttinl */ {
-
-#ifndef MYREAD
- CHAR ch, dum;
-#endif /* MYREAD */
-#ifdef PARSENSE
- int pktlen = -1;
- int lplen = 0;
- int havelen = 0;
-#endif /* PARSENSE */
- int fd;
- int sopmask = 0xff; /* Start-Of-Packet mask */
-#ifdef CKXXCHAR
- extern short dblt[]; /* Ignore-character table */
- extern int ignflag;
-#endif /* CKXXCHAR */
-#ifdef TCPSOCKET
- extern CHAR stchr;
-#endif /* TCPSOCKET */
- int x;
-#ifdef STREAMING
- extern int streaming;
- extern int sndtyp;
-#endif /* STREAMING */
-
- if (ttyfd < 0) return(-3); /* Not open. */
-/*
- In February 2007 I fixed ttinl() to work better under the truly awful
- conditions encountered by the AM-APEX oceanographic floats that gather
- hurricane data and phone home using Iridium satellite modems, which under
- certain conditions, can send two packets back to back after a long pause.
- In this case the second packet would be ignored because the SOH was skipped
- due to the ttflui() call. But the reworked lookahead/pushback logic broke
- Kermit transfers on encrypted connections. This was fixed 12-13 August
- 2007. All of this happened after 8.0.212 Dev.27 was released and before
- Dev.28, so no harm done other than the delay.
-*/
- debug(F101,"ttinl max","",max);
- debug(F101,"ttinl timo","",timo);
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef COMMENT
- if (xlocal && conchk() > 0) /* Allow for console interruptions */
- return(-1);
-#endif /* COMMENT */
-
- *dest = '\0'; /* Clear destination buffer */
- if (timo < 0) timo = 0; /* Safety */
- if (timo) { /* Don't time out if timo == 0 */
- int xx;
- saval = signal(SIGALRM,timerh); /* Enable timer interrupt */
- xx = alarm(timo); /* Set it. */
- debug(F101,"ttinl alarm","",xx);
- }
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) { /* Timer went off? */
- debug(F100,"ttinl timout","",0); /* Get here on timeout. */
- /* debug(F110," with",(char *) dest,0); */
- ttimoff(); /* Turn off timer */
- return(-1); /* and return error code. */
- } else {
- register int i, n = -1; /* local variables */
- int ccn = 0;
-#ifdef PARSENSE
- register int flag = 0;
- debug(F000,"ttinl start","",start);
-#endif /* PARSENSE */
-
- ttpmsk = ttprty ? 0177 : 0377; /* Set parity stripping mask. */
- sopmask = needpchk ? 0177 : ttpmsk; /* And SOP matching mask. */
-
-/* Now read into destination, stripping parity and looking for the */
-/* the packet terminator, and also for several Ctrl-C's typed in a row. */
-
- i = 0; /* Destination index */
- debug(F101,"ttinl eol","",eol);
-
- while (i < max-1) {
-#ifdef MYREAD
- errno = 0;
- /* On encrypted connections myread returns encrypted bytes */
- n = myread();
- debug(F000,"TTINL myread char","",n);
- if (n < 0) { /* Timeout or i/o error? */
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"ttinl myread failure, n","",n);
- debug(F101,"ttinl myread errno","",errno);
- }
-#endif /* DEBUG */
- /* Don't let EINTR break packets. */
- if (n == -3) {
- if (errno == EINTR && i > 0) {
- debug(F111,"ttinl EINTR myread i","continuing",i);
- continue;
- } else {
- debug(F110,"ttinl non-EINTR -3","closing",0);
- wasclosed = 1;
- ttimoff(); /* Turn off timer */
- ttclos(0);
- return(n);
- }
- } else if (n == -2 && netconn /* && timo == 0 */ ) {
- /* Here we try to catch broken network connections */
- /* even when ioctl() and read() do not catch them */
- debug(F111,"ttinl network myread failure","closing",n);
- wasclosed = 1;
- ttimoff();
- ttclos(0);
- return(-3);
- }
-#ifdef STREAMING
- /* Streaming and no data to read */
- else if (n == 0 && streaming && sndtyp == 'D')
- return(0);
-#endif /* STREAMING */
- break; /* Break out of while loop */
- }
-
-#else /* not MYREAD (is this code used anywhere any more?) */
-/*
- The non-MYREAD code dates from the 1980s and was needed on certain platforms
- where there were no nonblocking reads. -fdc, 2007/02/22.
-*/
- if ((n = read(fd, &n, 1)) < 1)
- break; /* Error - break out of while loop */
-
-#endif /* MYREAD */
-
- /* Get here with char in n */
-
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION) && !pushedback) {
- CHAR ch = n;
- ck_tn_decrypt((char *)&ch,1);
- n = ch;
- debug(F000,"TTINL decryp char","",n);
- }
- pushedback = 0;
-#endif /* CK_ENCRYPTION */
-
-#ifdef TCPSOCKET
- if (n == IAC && /* Handle Telnet options */
- ((xlocal && netconn && IS_TELNET()) ||
- (!xlocal && sstelnet))) {
- n = tt_tnopt(n);
- if (n < 0)
- return(n);
-#ifndef NOPARSEN
- else if (n == 1)
- start = stchr;
-#endif /* NOPARSEN */
- if (n != 255) /* No data - go back for next char */
- continue;
- } /* Quoted IAC - keep going */
-#endif /* TCPSOCKET */
-
-#ifdef CKXXCHAR
- if (ignflag)
- if (dblt[(unsigned) n] & 1) /* Character to ignore? */
- continue;
-#endif /* CKXXCHAR */
-/*
- Use parity mask, rather than always stripping parity, to check for
- cancellation. Otherwise, runs like \x03\x83\x03 in a packet could cancel
- the transfer when parity is NONE. (Note that \x03\x03\x03 is extremely
- unlikely due to run-length encoding.)
-*/
- /* Check cancellation */
- if (!xlocal && xfrcan && ((n & ttpmsk) == xfrchr)) {
- if (++ccn >= xfrnum) { /* If xfrnum in a row, bail out. */
- if (timo) { /* Clear timer. */
- ttimoff();
- }
- if (xfrchr < 32)
- printf("^%c...\r\n",(char)(xfrchr+64));
- else
- printf("Canceled...\r\n");
- return(-2);
- }
- } else ccn = 0; /* No cancellation, reset counter, */
-
-#ifdef PARSENSE
-/*
- Restructured code allows for a new packet to appear somewhere in the
- middle of a previous one. -fdc, 24 Feb 2007.
-*/
- if ((n & sopmask) == start) { /* Start of Packet */
- debug(F101,"ttinl SOP i","",i);
- flag = 1; /* Flag that we are in a packet */
- havelen = 0; /* Invalidate previous length */
- pktlen = -1; /* (if any) in case we were */
- lplen = 0; /* alread processand a packet */
- i = 0; /* and reset the dest buffer pointer */
- }
- if (flag == 0) { /* No SOP yet... */
- debug(F000,"ttinl skipping","",n);
- continue;
- }
- dest[i++] = n & ttpmsk;
-/*
- If we have not been instructed to wait for a turnaround character, we can go
- by the packet length field. If turn != 0, we must wait for the end of line
- (eol) character before returning. This is an egregious violation of all
- principles of layering... (Less egregious in C-Kermit 9.0, in which we go
- by the length field but also look for the eol in case it arrives early,
- e.g. if the length field was corrupted upwards.)
-*/
- if (!havelen) {
- if (i == 2) {
- if ((dest[1] & 0x7f) < 32) /* Garbage in length field */
- return(-1); /* fdc - 13 Apr 2010 */
- pktlen = xunchar(dest[1] & 0x7f);
- if (pktlen > 94) /* Rubout in length field */
- return(-1); /* fdc - 13 Apr 2010 */
- if (pktlen > 1) {
- havelen = 1;
- debug(F101,"ttinl pktlen value","",pktlen);
- }
- } else if (i == 5 && pktlen == 0) {
- lplen = xunchar(dest[4] & 0x7f);
- } else if (i == 6 && pktlen == 0) {
- pktlen = lplen * 95 + xunchar(dest[5] & 0x7f) + 5;
- havelen = 1;
- debug(F101,"ttinl extended length","",pktlen);
- }
- }
-
-/*
- Suppose we looked at the sequence number here and found it was out of
- range? This would mean either (a) incoming packets had SOP unprefixed
- and we are out of sync, or (b) the packet is damaged. Since (a) is bad
- practice, let's ignore it. So what should we do here if we know the
- packet is damaged?
-
- 1. Nothing -- keep trying to read the packet till we find what we think
- is the end, or we time out, and let the upper layer decide what to
- do. But since either the packet is corrupt or we are out of sync,
- our criterion for finding the end does not apply and we are likely
- to time out (or swallow a piece of the next packet) if our assumed
- length is too long. (This was the behavior prior to version 7.0.)
-
- 2. set flag = 0 and continue? This would force us to wait for the
- next packet to come in, and therefore (in the nonwindowing case),
- would force a timeout in the other Kermit.
-
- 3. set flag = 0 and continue, but only if the window size is > 1 and
- the window is not blocked? Talk about cheating!
-
- 4. Return a failure code and let the upper layer decide what to do.
- This should be equivalent to 3, but without the cheating. So let's
- do it that way... But note that we must ignore the parity bit
- in case this is the first packet and we have not yet run parchk().
-*/
- if (i == 3) { /* Peek at sequence number */
- x = xunchar((dest[i-1] & 0x7f)); /* If it's not in range... */
- if (x < 0 || x > 63) {
- debug(F111,"ttinl bad seq",dest,x);
- if (timo) ttimoff();
- return(-1); /* return a nonfatal error */
- }
- }
-
-#else /* PARSENSE */
- dest[i++] = n & ttpmsk;
-#endif /* PARSENSE */
-
- /* Check for end of packet */
-
- if (
- ((n & ttpmsk) == eol) /* Always break on the eol char */
-#ifdef PARSENSE
- || /* fdc - see notes of 13 Apr 2010 */
-/*
- Purely length-driven if SET HANDSHAKE NONE (i.e. turn == 0).
- This allows packet terminators and handshake characters to appear
- literally inside a packet data field.
-*/
- (havelen && (i > pktlen+1) &&
- (!turn || (turn && (n & 0x7f) == turn))) /* (turn, not eol) */
-
-#endif /* PARSENSE */
- ) {
-/*
- Here we have either read the last byte of the packet based on its length
- field, or else we have read the packet terminator (eol) or the half-duplex
- line-turnaround char (turn).
-*/
-#ifndef PARSENSE
- debug(F101,"ttinl got eol","",eol); /* (or turn) */
- dest[i] = '\0'; /* Yes, terminate the string, */
- /* debug(F101,"ttinl i","",i); */
-
-#else /* PARSENSE */
-
-#ifdef DEBUG
- if (deblog) {
- if ((n & ttpmsk) != eol) {
- debug(F101,"ttinl EOP length","",pktlen);
- debug(F000,"ttinl EOP current char","",n);
- debug(F101,"ttinl EOP packet buf index","",i);
- } else debug(F101,"ttinl got eol","",eol);
- }
-#endif /* DEBUG */
-
-#ifdef MYREAD
-/*
- The packet was read based on its length. This leaves the packet terminator
- unread, and so ttchk() will always return at least 1 because of this,
- possibly giving a false positive to the "is there another packet waiting?"
- test. But if we know the terminator (or any other interpacket junk) is
- there, we can safely get rid of it.
-
- NOTE: This code reworked to (a) execute even if the debug log isn't active;
- and (b) actually work. -fdc, 2007/02/22. And again 2007/08/12-13 to also
- work on encrypted connections.
-*/
- debug(F101,"TTINL my_count","",my_count);
- if ((n & ttpmsk) != eol) { /* Not the packet terminator */
- int x;
- while (my_count > 0) {
- x = myread(); /* (was ttinc(0) */
- debug(F000,"TTINL lkread char","",x);
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION)) {
- CHAR ch = x;
- ck_tn_decrypt((char *)&ch,1);
- x = ch;
- debug(F000,"TTINL lkdecr char","",x);
- }
-#endif /* CK_ENCRYPTION */
- /*
- Note: while it might seem more elegant to simply
- push back the encrypted byte, that desynchronizes
- the decryption stream; the flag is necessary so we
- don't try to decrypt the same byte twice.
- */
- if ((x & ttpmsk) == start) { /* Start of next packet */
- myunrd(x); /* Push back the decrypted byte */
- pushedback = 1; /* And set flag */
- debug(F000,"TTINL lkpush char","",x);
- break;
- }
- }
- }
-#endif /* MYREAD */
-
- dest[i] = '\0'; /* Terminate the string, */
- if (needpchk) { /* Parity checked yet? */
- if (ttprty == 0) { /* No, check. */
- if ((ttprty = parchk(dest,start,i)) > 0) {
- int j;
- debug(F101,"ttinl senses parity","",ttprty);
- debug(F110,"ttinl packet before",dest,0);
- ttpmsk = 0x7f;
- for (j = 0; j < i; j++)
- dest[j] &= 0x7f; /* Strip parity from packet */
- debug(F110,"ttinl packet after ",dest,0);
- } else ttprty = 0; /* Restore if parchk error */
- }
- sopmask = ttpmsk;
- needpchk = 0;
- }
-#endif /* PARSENSE */
-
- if (timo) /* Turn off timer if it was on */
- ttimoff();
- ckhexdump("ttinl got",dest,i);
-
-#ifdef STREAMING
- /* ttinl() was called because there was non-packet */
- /* data sitting in the back channel. Ignore it. */
- if (streaming && sndtyp == 'D')
- return(-1);
-#endif /* STREAMING */
- return(i);
- }
- } /* End of while() */
- ttimoff();
- return(n);
- }
-}
-#endif /* NOXFER */
-
-/* T T I N C -- Read a character from the communication line */
-/*
- On success, returns the character that was read, >= 0.
- On failure, returns -1 or other negative myread error code,
- or -2 if connection is broken or ttyfd < 0.
- or -3 if session limit has expired,
- or -4 if something or other...
- NOTE: The API does not provide for ttinc() returning a special code
- upon timeout, but we need it. So for this we have a global variable,
- ttinctimo.
-*/
-static int ttinctimo = 0; /* Yuk */
-
-int
-ttinc(timo) int timo; {
-
- int n = 0, fd;
- int is_tn = 0;
- CHAR ch = 0;
-
- ttinctimo = 0;
-
- if (ttyfd < 0) return(-2); /* Not open. */
-
- is_tn = (xlocal && netconn && IS_TELNET()) ||
- (!xlocal && sstelnet);
-
-#ifdef TTLEBUF
- if (ttpush >= 0) {
- debug(F111,"ttinc","ttpush",ttpush);
- ch = ttpush;
- ttpush = -1;
- return(ch);
- }
- if (le_data) {
- if (le_getchar(&ch) > 0) {
- debug(F111,"ttinc le_getchar","ch",ch);
- return(ch);
- }
- }
-#endif /* TTLEBUF */
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
- if ((timo <= 0) /* Untimed. */
-#ifdef MYREAD
- || (my_count > 0) /* Buffered char already waiting. */
-#endif /* MYREAD */
- ) {
-#ifdef MYREAD
- /* Comm line failure returns -1 thru myread, so no &= 0377 */
- n = myread(); /* Wait for a character... */
- /* debug(F000,"ttinc MYREAD n","",n); */
-#ifdef CK_ENCRYPTION
- /* debug(F101,"ttinc u_encrypt","",TELOPT_U(TELOPT_ENCRYPTION)); */
- if (TELOPT_U(TELOPT_ENCRYPTION) && n >= 0) {
- ch = n;
- ck_tn_decrypt((char *)&ch,1);
- n = ch;
- }
-#endif /* CK_ENCRYPTION */
-
-#ifdef NETPTY
- if (ttpty && n < 0) {
- debug(F101,"ttinc error on pty","",n);
- ttclos(0);
- return(n);
- }
-#endif /* NETPTY */
-
-#ifdef TNCODE
- if ((n > -1) && is_tn)
- return((unsigned)(n & 0xff));
- else
-#endif /* TNCODE */
- return(n < 0 ? n : (unsigned)(n & ttpmsk));
-
-#else /* MYREAD */
-
- while ((n = read(fd,&ch,1)) == 0) /* Wait for a character. */
- /* Shouldn't have to loop in ver 5A. */
-#ifdef NETCONN
- if (netconn) { /* Special handling for net */
- netclos(); /* If read() returns 0 it means */
- netconn = 0; /* the connection has dropped. */
- errno = ENOTCONN;
- return(-2);
- }
-#endif /* NETCONN */
- ;
- /* debug(F101,"ttinc","",ch); */
-#ifdef TNCODE
- if ((n > 0) && is_tn) {
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION)) {
- ck_tn_decrypt(&ch,1);
- n = ch;
- }
-#endif /* CK_ENCRYPTION */
- return((unsigned)(ch & 0xff));
- } else
-#endif /* TNCODE */
- return((n < 0) ? -4 : ((n == 0) ? -1 : (unsigned)(ch & ttpmsk)));
-#endif /* MYREAD */
-
- } else { /* Timed read */
-
- int oldalarm;
- saval = signal(SIGALRM,timerh); /* Set up handler, save old one. */
- oldalarm = alarm(timo); /* Set alarm, save old one. */
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) { /* Timer expired */
- ttinctimo = 1;
- n = -1; /* set flag */
- } else {
-#ifdef MYREAD
- n = myread(); /* If managing own buffer... */
- debug(F101,"ttinc myread","",n);
- ch = n;
-#else
- n = read(fd,&ch,1); /* Otherwise call the system. */
- if (n == 0) n = -1;
- debug(F101,"ttinc read","",n);
-#endif /* MYREAD */
-
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION) && n >= 0) {
- ck_tn_decrypt((char *)&ch,1);
- }
-#endif /* CK_ENCRYPTION */
- if (n >= 0)
- n = (unsigned) (ch & 0xff);
- else
- n = (n < 0) ? -4 : -2; /* Special return codes. */
- }
- ttimoff(); /* Turn off the timer */
- if (oldalarm > 0) {
- if (n == -1) /* and restore any previous alarm */
- oldalarm -= timo;
- if (oldalarm < 0) /* adjusted by our timeout interval */
- oldalarm = 0;
- if (oldalarm) {
- debug(F101,"ttinc restoring oldalarm","",oldalarm);
- alarm(oldalarm);
- }
- }
-#ifdef NETCONN
- if (netconn) {
- if (n == -2) { /* read() returns 0 */
- netclos(); /* on network read failure */
- netconn = 0;
- errno = ENOTCONN;
- }
- }
-#endif /* NETCONN */
-#ifdef TNCODE
- if ((n > -1) && is_tn)
- return((unsigned)(n & 0xff));
- else
-#endif /* TNCODE */
- /* Return masked char or neg. */
- return( (n < 0) ? n : (unsigned)(n & ttpmsk) );
- }
-}
-
-/* S N D B R K -- Send a BREAK signal of the given duration */
-
-static int
-#ifdef CK_ANSIC
-sndbrk(int msec) { /* Argument is milliseconds */
-#else
-sndbrk(msec) int msec; {
-#endif /* CK_ANSIC */
-#ifndef POSIX
- int x, n;
-#endif /* POSIX */
-
-#ifdef OXOS
-#define BSDBREAK
-#endif /* OXOS */
-
-#ifdef ANYBSD
-#define BSDBREAK
-#endif /* ANYBSD */
-
-#ifdef BSD44
-#define BSDBREAK
-#endif /* BSD44 */
-
-#ifdef COHERENT
-#ifdef BSDBREAK
-#undef BSDBREAK
-#endif /* BSDBREAK */
-#endif /* COHERENT */
-
-#ifdef BELLV10
-#ifdef BSDBREAK
-#undef BSDBREAK
-#endif /* BSDBREAK */
-#endif /* BELLV10 */
-
-#ifdef PROVX1
- char spd;
-#endif /* PROVX1 */
-
- debug(F101,"ttsndb ttyfd","",ttyfd);
- if (ttyfd < 0) return(-1); /* Not open. */
-
-#ifdef Plan9
- return p9sndbrk(msec);
-#else
-#ifdef NETCONN
-#ifdef NETCMD
- if (ttpipe) /* Pipe */
- return(ttoc('\0'));
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty)
- return(ttoc('\0'));
-#endif /* NETPTY */
- if (netconn) /* Send network BREAK */
- return(netbreak());
-#endif /* NETCONN */
-
- if (msec < 1 || msec > 5000) return(-1); /* Bad argument */
-
-#ifdef POSIX /* Easy in POSIX */
- {
- int x;
- debug(F111,"sndbrk POSIX",ckitoa(msec),(msec/375));
- errno = 0;
- x = tcsendbreak(ttyfd,msec / 375);
- debug(F111,"sndbrk tcsendbreak",ckitoa(errno),x);
- return(x);
- }
-#else
-#ifdef PROVX1
- gtty(ttyfd,&ttbuf); /* Get current tty flags */
- spd = ttbuf.sg_ospeed; /* Save speed */
- ttbuf.sg_ospeed = B50; /* Change to 50 baud */
- stty(ttyfd,&ttbuf); /* ... */
- n = (int)strlen(brnuls); /* Send the right number of nulls */
- x = msec / 91;
- if (x > n) x = n;
- write(ttyfd,brnuls,n);
- ttbuf.sg_ospeed = spd; /* Restore speed */
- stty(ttyfd,&ttbuf); /* ... */
- return(0);
-#else
-#ifdef aegis
- sio_$control((short)ttyfd, sio_$send_break, msec, st);
- return(0);
-#else
-#ifdef BSDBREAK
- n = FWRITE; /* Flush output queue. */
-/* Watch out for int vs long problems in &n arg! */
- debug(F101,"sndbrk BSDBREAK","",msec);
- ioctl(ttyfd,TIOCFLUSH,&n); /* Ignore any errors.. */
- if (ioctl(ttyfd,TIOCSBRK,(char *)0) < 0) { /* Turn on BREAK */
- perror("Can't send BREAK");
- return(-1);
- }
- x = msleep(msec); /* Sleep for so many milliseconds */
- if (ioctl(ttyfd,TIOCCBRK,(char *)0) < 0) { /* Turn off BREAK */
- perror("BREAK stuck!!!");
- doexit(BAD_EXIT,-1); /* Get out, closing the line. */
- /* with bad exit status */
- }
- return(x);
-#else
-#ifdef ATTSV
-/*
- No way to send a long BREAK in Sys V, so send a bunch of regular ones.
- (Actually, Sys V R4 is *supposed* to have the POSIX tcsendbreak() function,
- but there's no way for this code to know for sure.)
-*/
- debug(F101,"sndbrk ATTSV","",msec);
- x = msec / 275;
- for (n = 0; n < x; n++) {
- /* Reportedly the cast breaks this function on some systems */
- /* But then why was it here in the first place? */
- if (ioctl(ttyfd,TCSBRK, /* (char *) */ 0) < 0) {
- perror("Can't send BREAK");
- return(-1);
- }
- }
- return(0);
-#else
-#ifdef V7
- debug(F101,"sndbrk V7","",msec);
- return(genbrk(ttyfd,250)); /* Simulate a BREAK */
-#else
- debug(F101,"sndbrk catchall","",msec);
- ttoc(0);ttoc(0);ttoc(0);ttoc(0);
- return(0);
-#endif /* V7 */
-#endif /* BSDBREAK */
-#endif /* ATTSV */
-#endif /* aegis */
-#endif /* PROVX1 */
-#endif /* POSIX */
-#endif /* Plan9 */
-}
-
-/* T T S N D B -- Send a BREAK signal */
-
-int
-ttsndb() {
-#ifdef TN_COMPORT
- if (netconn && istncomport())
- return((tnsndb(275L) >= 0) ? 0 : -1);
- else
-#endif /* TN_COMPORT */
- return(sndbrk(275));
-}
-
-/* T T S N D L B -- Send a Long BREAK signal */
-
-int
-ttsndlb() {
-#ifdef TN_COMPORT
- if (netconn && istncomport())
- return((tnsndb(1800L) >= 0) ? 0 : -1);
- else
-#endif /* TN_COMPORT */
- return(sndbrk(1500));
-}
-
-/* M S L E E P -- Millisecond version of sleep(). */
-
-/*
- Call with number of milliseconds (thousandths of seconds) to sleep.
- Intended only for small intervals. For big ones, just use sleep().
- Highly system-dependent.
- Returns 0 always, even if it didn't work.
-*/
-
-/* Define MSLFTIME for systems that must use an ftime() loop. */
-#ifdef ANYBSD /* For pre-4.2 BSD versions */
-#ifndef BSD4
-#define MSLFTIME
-#endif /* BSD4 */
-#endif /* ANYBSD */
-
-#ifdef TOWER1 /* NCR Tower OS 1.0 */
-#define MSLFTIME
-#endif /* TOWER1 */
-
-#ifdef COHERENT /* Coherent... */
-#ifndef _I386 /* Maybe Coherent/386 should get this, too */
-#define MSLFTIME /* Opinions are divided */
-#endif /* _I386 */
-#endif /* COHERENT */
-
-#ifdef COMMENT
-#ifdef GETMSEC
-
-/* Millisecond timer */
-
-static long msecbase = 0L; /* Unsigned long not portable */
-
-long
-getmsec() { /* Milliseconds since base time */
- struct timeval xv;
- struct timezone xz;
- long secs, msecs;
- if (
-#ifdef GTODONEARG
- gettimeofday(&tv)
-#else
-#ifdef PTX
- gettimeofday(&tv, NULL)
-#else
- gettimeofday(&tv, &tz)
-#endif /* PTX */
-#endif /* GTODONEARG */
- < 0)
- return(-1);
- if (msecbase == 0L) { /* First call, set base time. */
- msecbase = tv.tv_sec;
- debug(F101,"getmsec base","",msecbase);
- }
- return(((tv.tv_sec - msecbase) * 1000L) + (tv.tv_usec / 1000L));
-}
-#endif /* GETMSEC */
-#endif /* COMMENT */
-
-#ifdef SELECT
-int
-ttwait(fd, secs) int fd, secs; {
- int x;
- fd_set rfds;
- FD_ZERO(&rfds);
- FD_SET(fd,&rfds);
- tv.tv_sec = secs;
- tv.tv_usec = 0L;
- errno = 0;
- if ((x = select(FD_SETSIZE,
-#ifdef HPUX9
- (int *)
-#else
-#ifdef HPUX1000
- (int *)
-#endif /* HPUX1000 */
-#endif /* HPUX9 */
- &rfds,
- 0, 0, &tv)) < 0) {
- debug(F101,"ttwait select errno","",errno);
- return(0);
- } else {
- debug(F101,"ttwait OK","",errno);
- x = FD_ISSET(fd, &rfds);
- debug(F101,"ttwait select x","",x);
- return(x ? 1 : 0);
- }
-}
-#endif /* SELECT */
-
-int
-msleep(m) int m; {
-/*
- Other possibilities here are:
- nanosleep(), reportedly defined in POSIX.4.
- sginap(), IRIX only (back to what IRIX version I don't know).
-*/
-#ifdef Plan9
- return _SLEEP(m);
-#else
-#ifdef BEOSORBEBOX
- snooze(m*1000);
-#else /* BEOSORBEBOX */
-#ifdef SELECT
- int t1, x;
- debug(F101,"msleep SELECT 1","",m);
- if (m <= 0) return(0);
- if (m >= 1000) { /* Catch big arguments. */
- sleep(m/1000);
- m = m % 1000;
- if (m < 10) return(0);
- }
- debug(F101,"msleep SELECT 2","",m);
-#ifdef BELLV10
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, m );
- debug(F101,"msleep BELLV10 select","",x);
-#else /* BELLV10 */
-#ifdef HPUX9
- gettimeofday(&tv, &tz);
-#else
-
-#ifndef COHERENT
-#ifdef GTODONEARG
- if (gettimeofday(&tv) < 0)
-#else
-#ifdef PTX
- if (gettimeofday(&tv,NULL) < 0)
-#else
-#ifdef NOTIMEZONE
- if (gettimeofday(&tv, NULL) < 0) /* wonder what this does... */
-#else
- if (gettimeofday(&tv, &tz) < 0)
-#endif /* NOTIMEZONE */
-#endif /* PTX */
-#endif /* GTODONEARG */
- return(-1);
- t1 = tv.tv_sec; /* Seconds */
-#endif /* COHERENT */
-#endif /* HPUX9 */
- tv.tv_sec = 0; /* Use select() */
- tv.tv_usec = m * 1000L;
-#ifdef BSD44
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep BSD44 select","",x);
-#else /* BSD44 */
-#ifdef __linux__
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep __linux__ select","",x);
-#else /* __linux__ */
-#ifdef BSD43
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep BSD43 select","",x);
-#else /* BSD43 */
-#ifdef QNX6
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep QNX6 select","",x);
-#else /* QNX6 */
-#ifdef QNX
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep QNX select","",x);
-#else /* QNX */
-#ifdef COHERENT
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep COHERENT select","",x);
-#else /* COHERENT */
-#ifdef HPUX1000 /* 10.00 only, not 10.10 or later */
- x = select( 0, (int *)0, (int *)0, (int *)0, &tv );
- debug(F101,"msleep HP-UX 10.00 select","",x);
-#else /* HPUX1000 */
-#ifdef SVR4
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep SVR4 select","",x);
-#else /* SVR4 */
-#ifdef OSF40
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep OSF40 select","",x);
-#else /* OSF40 */
-#ifdef PTX
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep OSF40 select","",x);
-#else
- x = select( 0, (int *)0, (int *)0, (int *)0, &tv );
- debug(F101,"msleep catch-all select","",x);
-#endif /* PTX */
-#endif /* OSF40 */
-#endif /* HP1000 */
-#endif /* SVR4 */
-#endif /* COHERENT */
-#endif /* QNX */
-#endif /* QNX6 */
-#endif /* BSD43 */
-#endif /* __linux__ */
-#endif /* BSD44 */
-#endif /* BELLV10 */
- return(0);
-
-#else /* Not SELECT */
-#ifdef CK_POLL /* We have poll() */
- struct pollfd pfd; /* Supply a valid address for poll() */
-
-#ifdef ODT30 /* But in SCO ODT 3.0 */
-#ifdef NAP /* we should use nap() instead */
- debug(F101,"msleep ODT 3.0 NAP","",m); /* because using poll() here */
- nap((long)m); /* seems to break dialing. */
- return(0);
-#else
- debug(F101,"msleep ODT 3.0 POLL","",m);
- poll(&pfd, 0, m);
- return(0);
-#endif /* NAP */
-#else
- debug(F101,"msleep POLL","",m);
- poll(&pfd, 0, m);
- return(0);
-#endif /* ODT30 */
-
-/*
- We could handle the above more cleanly by just letting nap() always
- take precedence over poll() in this routine, but there is no way to know
- whether that would break something else.
-*/
-
-#else /* Not POLL */
-#ifdef USLEEP
-/*
- "This routine is implemented using setitimer(2); it requires eight
- system calls...". In other words, it might take 5 minutes to sleep
- 10 milliseconds...
-*/
- debug(F101,"msleep USLEEP","",m);
- if (m >= 1000) { /* Catch big arguments. */
- sleep(m/1000);
- m = m % 1000;
- if (m < 10) return(0);
- }
- usleep((unsigned int)(m * 1000));
- return(0);
-#else
-#ifdef aegis
- time_$clock_t dur;
- debug(F101,"msleep aegis","",m);
- dur.c2.high16 = 0;
- dur.c2.low32 = 250 * m; /* one millisecond = 250 four microsecond ticks */
- time_$wait(time_$relative, dur, st);
- return(0);
-#else
-#ifdef PROVX1
- debug(F101,"msleep Venix","",m);
- if (m <= 0) return(0);
- sleep(-((m * 60 + 500) / 1000));
- return(0);
-#else
-#ifdef NAP
- debug(F101,"msleep NAP","",m);
- nap((long)m);
- return(0);
-#else
-#ifdef ATTSV
-#ifndef BSD44
- extern long times(); /* Or #include <times.h> ? */
-#endif /* BSD44 */
- long t1, t2, tarray[4];
- int t3;
- char *cp = getenv("HZ");
- int CLOCK_TICK;
- int hertz;
-
- if (cp && (hertz = atoi(cp))) {
- CLOCK_TICK = 1000 / hertz;
- } else { /* probably single user mode */
-#ifdef HZ
- CLOCK_TICK = 1000 / HZ;
-#else
- static warned = 0;
- /* HZ always exists in, for instance, SCO Xenix, so you don't have to
- * make special #ifdefs for XENIX here, like in ver 4F. Also, if you
- * have Xenix, you have should have nap(), so the best is to use -DNAP
- * in the makefile. Most systems have HZ.
- */
- CLOCK_TICK = 17; /* 1/60 sec */
- if (!warned) {
- printf("warning: environment variable HZ bad... using HZ=%d\r\n",
- 1000 / CLOCK_TICK);
- warned = 1;
- }
-#endif /* !HZ */
- }
- debug(F101,"msleep ATTSV","",m);
- if (m <= 0) return(0);
- if (m >= 1000) { /* Catch big arguments. */
- sleep(m/1000);
- m = m % 1000;
- if (m < 10) return(0);
- }
- if ((t1 = times(tarray)) < 0) return(-1);
- while (1) {
- if ((t2 = times(tarray)) < 0) return(-1);
- t3 = ((int)(t2 - t1)) * CLOCK_TICK;
- if (t3 > m) return(t3);
- }
-#else /* Not ATTSV */
-#ifdef MSLFTIME /* Use ftime() loop... */
- int t1, t3 = 0;
- debug(F101,"msleep MSLFTIME","",m);
- if (m <= 0) return(0);
- if (m >= 1000) { /* Catch big arguments. */
- sleep(m/1000);
- m = m % 1000;
- if (m < 10) return(0);
- }
-#ifdef QNX
- ftime(&ftp); /* void ftime() in QNX */
-#else
- if (ftime(&ftp) < 0) return(-1); /* Get base time. */
-#endif /* QNX */
- t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm;
- while (1) {
- ftime(&ftp); /* Get current time and compare. */
- t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1;
- if (t3 > m) return(0);
- }
-#else
-/* This includes true POSIX, which has no way to do this. */
- debug(F101,"msleep busy loop","",m);
- if (m >= 1000) { /* Catch big arguments. */
- sleep(m/1000);
- m = m % 1000;
- if (m < 10) return(0);
- }
- if (m > 0) while (m > 0) m--; /* Just a dumb busy loop */
- return(0);
-#endif /* MSLFTIME */
-#endif /* ATTSV */
-#endif /* NAP */
-#endif /* PROVX1 */
-#endif /* aegis */
-#endif /* CK_POLL */
-#endif /* SELECT */
-#endif /* BEOSORBEBOX */
-#endif /* USLEEP */
-#endif /* Plan9 */
-}
-
-/* R T I M E R -- Reset elapsed time counter */
-
-VOID
-rtimer() {
- tcount = time( (time_t *) 0 );
-}
-
-
-/* G T I M E R -- Get current value of elapsed time counter in seconds */
-
-int
-gtimer() {
- int x;
- x = (int) (time( (time_t *) 0 ) - tcount);
- debug(F101,"gtimer","",x);
- return( (x < 0) ? 0 : x );
-}
-
-#ifdef GFTIMER
-/*
- Floating-point timers. Require not only floating point support, but
- also gettimeofday().
-*/
-static struct timeval tzero;
-
-VOID
-rftimer() {
-#ifdef GTODONEARG /* Account for Mot's definition */
- (VOID) gettimeofday(&tzero);
-#else
- (VOID) gettimeofday(&tzero, (struct timezone *)0);
-#endif /* GTODONEARG */
-}
-
-CKFLOAT
-gftimer() {
- struct timeval tnow, tdelta;
- CKFLOAT s;
-#ifdef DEBUG
- char fpbuf[64];
-#endif /* DEBUG */
-#ifdef GTODONEARG /* Account for Mot's definition */
- (VOID) gettimeofday(&tnow);
-#else
- (VOID) gettimeofday(&tnow, (struct timezone *)0);
-#endif /* GTODONEARG */
-
- tdelta.tv_sec = tnow.tv_sec - tzero.tv_sec;
- tdelta.tv_usec = tnow.tv_usec - tzero.tv_usec;
-
- if (tdelta.tv_usec < 0) {
- tdelta.tv_sec--;
- tdelta.tv_usec += 1000000;
- }
- s = (CKFLOAT) tdelta.tv_sec + ((CKFLOAT) tdelta.tv_usec / 1000000.0);
- if (s < GFMINTIME)
- s = GFMINTIME;
-#ifdef DEBUG
- if (deblog) {
- sprintf(fpbuf,"%f",s);
- debug(F110,"gftimer",fpbuf,0);
- }
-#endif /* DEBUG */
- return(s);
-}
-#endif /* GFTIMER */
-
-/* Z T I M E -- Return asctime()-format date/time string */
-/*
- NOTE: as a side effect of calling this routine, we can also set the
- following two variables, giving the micro- and milliseconds (fractions of
- seconds) of the clock time. Currently this is done only in BSD-based builds
- that use gettimeofday(). When these variables are not filled in, they are
- left with a value of -1L.
-*/
-static char asctmbuf[64];
-
-VOID
-ztime(s) char **s; {
-
-#ifdef GFTIMER
-/*
- The gettimeofday() method, which also sets ztmsec and ztusec, works for
- all GFTIMER builds. NOTE: ztmsec and ztusec are defined in ckcmai.c,
- and extern declarations for them are in ckcdeb.h; thus they are
- declared in this file by inclusion of ckcdeb.h.
-*/
- char *asctime();
- struct tm *localtime();
- struct tm *tp;
- ztmsec = -1L;
- ztusec = -1L;
-
- if (!s)
- debug(F100,"ztime s==NULL","",0);
-
-#ifdef GTODONEARG
- /* No 2nd arg in Motorola SV88 and some others */
- if (gettimeofday(&tv) > -1)
-#else
-#ifndef COHERENT
-#ifdef PTX
- if (gettimeofday(&tv,NULL) > -1)
-#else
-#ifdef NOTIMEZONE
- if (gettimeofday(&tv, NULL) > -1) /* wonder what this does... */
-#else
- if (gettimeofday(&tv, &tz) > -1)
-#endif /* NOTIMEZONE */
-#endif /* PTX */
-#endif /* COHERENT */
-#endif /* GTODONEARG */
- { /* Fill in tm struct */
- ztusec = tv.tv_usec; /* Microseconds */
- ztmsec = ztusec / 1000L; /* Milliseconds */
-#ifdef HPUX9
- {
- time_t zz;
- zz = tv.tv_sec;
- tp = localtime(&zz); /* Convert to local time */
- }
-#else
-#ifdef HPUX1000
- {
- time_t zz;
- zz = tv.tv_sec;
- tp = localtime(&zz);
- }
-#else
-#ifdef LINUX
- { /* avoid unaligned access trap on 64-bit platforms */
- time_t zz;
- zz = tv.tv_sec;
- tp = localtime(&zz);
- }
-#else
-#ifdef MACOSX
- tp = localtime((time_t *)&tv.tv_sec); /* Convert to local time */
-#else
- tp = localtime(&tv.tv_sec);
-#endif /* MACOSX */
-#endif /* LINUX */
-#endif /* HPUX1000 */
-#endif /* HPUX9 */
- if (s) {
- char * s2;
- s2 = asctime(tp); /* Convert result to ASCII string */
- asctmbuf[0] = '\0';
- if (s2) ckstrncpy(asctmbuf,s2,64);
- *s = asctmbuf;
- debug(F111,"ztime GFTIMER gettimeofday",*s,ztusec);
- }
- }
-#else /* Not GFTIMER */
-
-#undef ZTIMEV7 /* Which systems need to use */
-#ifdef COHERENT /* old UNIX Version 7 way... */
-#define ZTIMEV7
-#endif /* COHERENT */
-#ifdef TOWER1
-#define ZTIMEV7
-#endif /* TOWER1 */
-#ifdef ANYBSD
-#ifndef BSD42
-#define ZTIMEV7
-#endif /* BSD42 */
-#endif /* ANYBSD */
-#ifdef V7
-#ifndef MINIX
-#define ZTIMEV7
-#endif /* MINIX */
-#endif /* V7 */
-#ifdef POSIX
-#define ZTIMEV7
-#endif /* POSIX */
-
-#ifdef HPUX1020
-/*
- Prototypes are in <time.h>, included above.
-*/
- time_t clock_storage;
- clock_storage = time((void *) 0);
- if (s) {
- *s = ctime(&clock_storage);
- debug(F110,"ztime: HPUX 10.20",*s,0);
- }
-#else
-#ifdef ATTSV /* AT&T way */
-/* extern long time(); */ /* Theoretically these should */
- char *ctime(); /* already been dcl'd in <time.h> */
- time_t clock_storage;
- clock_storage = time(
-#ifdef IRIX60
- (time_t *)
-#else
-#ifdef BSD44
- (time_t *)
-#else
- (long *)
-#endif /* BSD44 */
-#endif /* IRIX60 */
- 0 );
- if (s) {
- *s = ctime( &clock_storage );
- debug(F110,"ztime: ATTSV",*s,0);
- }
-#else
-#ifdef PROVX1 /* Venix 1.0 way */
- int utime[2];
- time(utime);
- if (s) {
- *s = ctime(utime);
- debug(F110,"ztime: PROVX1",*s,0);
- }
-#else
-#ifdef BSD42 /* 4.2BSD way */
- char *asctime();
- struct tm *localtime();
- struct tm *tp;
- gettimeofday(&tv, &tz);
- ztusec = tv.tv_usec;
- ztmsec = tv.tv_usec / 1000L;
- tp = localtime(&tv.tv_sec);
- if (s) {
- *s = asctime(tp);
- debug(F111,"ztime: BSD42",*s,ztusec);
- }
-#else
-#ifdef MINIX /* MINIX way */
-#ifdef COMMENT
- extern long time(); /* Already got these from <time.h> */
- extern char *ctime();
-#endif /* COMMENT */
- time_t utime[2];
- time(utime);
- if (s) {
- *s = ctime(utime);
- debug(F110,"ztime: MINIX",*s,0);
- }
-#else
-#ifdef ZTIMEV7 /* The regular way */
- char *asctime();
- struct tm *localtime();
- struct tm *tp;
- long xclock; /* or unsigned long for BeBox? */
- time(&xclock);
- tp = localtime(&xclock);
- if (s) {
- *s = asctime(tp);
- debug(F110,"ztime: ZTIMEV7",*s,0);
- }
-#else /* Catch-all for others... */
- if (s) {
- *s = "Day Mon 00 00:00:00 0000\n"; /* Dummy in asctime() format */
- debug(F110,"ztime: catch-all",*s,0);
- }
-#endif /* ZTIMEV7 */
-#endif /* MINIX */
-#endif /* BSD42 */
-#endif /* PROVX1 */
-#endif /* ATTSV */
-#endif /* HPUX1020 */
-#endif /* GFTIMER */
-}
-
-/* C O N G M -- Get console terminal modes. */
-
-/*
- Saves initial console mode, and establishes variables for switching
- between current (presumably normal) mode and other modes.
- Should be called when program starts, but only after establishing
- whether program is in the foreground or background.
- Returns 1 if it got the modes OK, 0 if it did nothing, -1 on error.
-*/
-int
-congm() {
- int fd;
- if (backgrd || !isatty(0)) { /* If in background. */
- cgmf = -1; /* Don't bother, modes are garbage. */
- return(-1);
- }
- if (cgmf > 0) return(0); /* Already did this. */
- debug(F100,"congm getting modes","",0); /* Need to do it. */
-#ifdef aegis
- ios_$inq_type_uid(ios_$stdin, conuid, st);
- if (st.all != status_$ok) {
- fprintf(stderr, "problem getting stdin objtype: ");
- error_$print(st);
- }
- concrp = (conuid == mbx_$uid);
- conbufn = 0;
-#endif /* aegis */
-
-#ifndef BEBOX
- if ((fd = open(CTTNAM,2)) < 0) { /* Open controlling terminal */
-#ifdef COMMENT
- fprintf(stderr,"Error opening %s\n", CTTNAM);
- perror("congm");
- return(-1);
-#else
- fd = 0;
-#endif /* COMMENT */
- }
-#else
- fd = 0;
-#endif /* !BEBOX */
-#ifdef BSD44ORPOSIX
- if (tcgetattr(fd,&ccold) < 0) return(-1);
- if (tcgetattr(fd,&cccbrk) < 0) return(-1);
- if (tcgetattr(fd,&ccraw) < 0) return(-1);
-#else
-#ifdef ATTSV
- if (ioctl(fd,TCGETA,&ccold) < 0) return(-1);
- if (ioctl(fd,TCGETA,&cccbrk) < 0) return(-1);
- if (ioctl(fd,TCGETA,&ccraw) < 0) return(-1);
-#ifdef VXVE
- cccbrk.c_line = 0; /* STTY line 0 for CDC VX/VE */
- if (ioctl(fd,TCSETA,&cccbrk) < 0) return(-1);
- ccraw.c_line = 0; /* STTY line 0 for CDC VX/VE */
- if (ioctl(fd,TCSETA,&ccraw) < 0) return(-1);
-#endif /* VXVE */
-#else
-#ifdef BELLV10
- if (ioctl(fd,TIOCGETP,&ccold) < 0) return(-1);
- if (ioctl(fd,TIOCGETP,&cccbrk) < 0) return(-1);
- if (ioctl(fd,TIOCGETP,&ccraw) < 0) return(-1);
- debug(F101,"cccbrk.sg_flags orig","", cccbrk.sg_flags);
-#else
- if (gtty(fd,&ccold) < 0) return(-1);
- if (gtty(fd,&cccbrk) < 0) return(-1);
- if (gtty(fd,&ccraw) < 0) return(-1);
-#endif /* BELLV10 */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-#ifdef sony_news /* Sony NEWS */
- if (ioctl(fd,TIOCKGET,&km_con) < 0) { /* Get console Kanji mode */
- perror("congm error getting Kanji mode");
- debug(F101,"congm error getting Kanji mode","",0);
- km_con = -1; /* Make sure this stays undefined. */
- return(-1);
- }
-#endif /* sony_news */
- if (fd > 0)
- close(fd);
- cgmf = 1; /* Flag that we got them. */
- return(1);
-}
-
-
-static VOID
-congetbuf(x) int x; {
- int n;
- n = CONBUFSIZ - (conbufp - conbuf); /* How much room left in buffer? */
- if (x > n) {
- debug(F101,"congetbuf char loss","",x-n);
- x = n;
- }
- x = read(0,conbufp,x);
- conbufn += x;
- debug(F111,"congetbuf readahead",conbuf,x);
-}
-
-
-/* C O N C B -- Put console in cbreak mode. */
-
-/* Returns 0 if ok, -1 if not */
-
-int
-#ifdef CK_ANSIC
-concb(char esc)
-#else
-concb(esc) char esc;
-#endif /* CK_ANSIC */
-/* concb */ {
- int x, y = 0;
- debug(F101,"concb constate","",constate);
- debug(F101,"concb cgmf","",cgmf);
- debug(F101,"concb backgrd","",backgrd);
-
- if (constate == CON_CB)
- return(0);
-
- if (cgmf < 1) /* Did we get console modes yet? */
- if (!backgrd) /* No, in background? */
- congm(); /* No, try to get them now. */
- if (cgmf < 1) /* Still don't have them? */
- return(0); /* Give up. */
- debug(F101,"concb ttyfd","",ttyfd);
- debug(F101,"concb ttfdflg","",ttfdflg);
-#ifdef COMMENT
- /* This breaks returning to prompt after protocol with "-l 0" */
- /* Commented out July 1998 */
- if (ttfdflg && ttyfd >= 0 && ttyfd < 3)
- return(0);
-#endif /* COMMENT */
- x = isatty(0);
- debug(F101,"concb isatty","",x);
- if (!x) return(0); /* Only when running on real ttys */
- debug(F101,"concb xsuspend","",xsuspend);
- if (backgrd) /* Do nothing if in background. */
- return(0);
- escchr = esc; /* Make this available to other fns */
- ckxech = 1; /* Program can echo characters */
-#ifdef aegis
- conbufn = 0;
- if (concrp) return(write(1, "\035\002", 2));
- if (conuid == input_pad_$uid) {pad_$raw(ios_$stdin, st); return(0);}
-#endif /* aegis */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifdef Plan9
- x = p9concb();
-#else
-#ifndef SVORPOSIX /* BSD, V7, etc */
- debug(F101,"cccbrk.sg_flags concb 1","", cccbrk.sg_flags);
- debug(F101,"concb stty CBREAK","",0);
- cccbrk.sg_flags |= (CBREAK|CRMOD); /* Set to character wakeup, */
- cccbrk.sg_flags &= ~ECHO; /* no echo. */
- debug(F101,"cccbrk.sg_flags concb 2","", cccbrk.sg_flags);
- errno = 0;
-/*
- BSD stty() clears the console buffer. So if anything is waiting in it,
- we have to read it now to avoid losing it.
-*/
- x = conchk();
- if (x > 0)
- congetbuf(x);
-
-#ifdef BELLV10
- x = ioctl(0,TIOCSETP,&cccbrk);
-#else
- x = stty(0,&cccbrk);
- debug(F101,"cccbrk.sg_flags concb x","", x);
-#endif /* BELLV10 */
-#else /* Sys V and POSIX */
-#ifndef OXOS
- debug(F101,"concb cccbrk.c_flag","",cccbrk.c_lflag);
-#ifdef QNX
- /* Don't mess with IEXTEN */
- cccbrk.c_lflag &= ~(ICANON|ECHO);
-#else
-#ifdef COHERENT
- cccbrk.c_lflag &= ~(ICANON|ECHO);
-#else
- cccbrk.c_lflag &= ~(ICANON|ECHO|IEXTEN);
-#endif /* COHERENT */
-#endif /* QNX */
- cccbrk.c_lflag |= ISIG; /* Allow signals in command mode. */
- cccbrk.c_iflag |= IGNBRK; /* But ignore BREAK signal */
- cccbrk.c_iflag &= ~BRKINT;
-
-#else /* OXOS */
- debug(F100,"concb OXOS is defined","",0);
- cccbrk.c_lflag &= ~(ICANON|ECHO);
- cccbrk.c_cc[VDISCARD] = cccbrk.c_cc[VLNEXT] = CDISABLE;
-#endif /* OXOS */
-#ifdef COMMENT
-/*
- Believe it or not, in SCO UNIX, VSUSP is greater than NCC, and so this
- array reference is out of bounds. It's only a debug() call so who needs it.
-*/
-#ifdef VSUSP
- debug(F101,"concb c_cc[VSUSP]","",cccbrk.c_cc[VSUSP]);
-#endif /* VSUSP */
-#endif /* COMMENT */
-#ifndef VINTR
- debug(F101,"concb c_cc[0]","",cccbrk.c_cc[0]);
- cccbrk.c_cc[0] = 003; /* Interrupt char is Control-C */
-#else
- debug(F101,"concb c_cc[VINTR]","",cccbrk.c_cc[0]);
- cccbrk.c_cc[VINTR] = 003;
-#endif /* VINTR */
-#ifndef VQUIT
- cccbrk.c_cc[1] = escchr; /* escape during packet modes */
-#else
- cccbrk.c_cc[VQUIT] = escchr;
-#endif /* VQUIT */
-#ifndef VEOF
- cccbrk.c_cc[4] = 1;
-#else
-#ifndef OXOS
-#ifdef VMIN
- cccbrk.c_cc[VMIN] = 1;
-#endif /* VMIN */
-#else /* OXOS */
- cccbrk.c_min = 1;
-#endif /* OXOS */
-#endif /* VEOF */
-#ifdef ZILOG
- cccbrk.c_cc[5] = 0;
-#else
-#ifndef VEOL
- cccbrk.c_cc[5] = 1;
-#else
-#ifndef OXOS
-#ifdef VTIME
- cccbrk.c_cc[VTIME] = 1;
-#endif /* VTIME */
-#else /* OXOS */
- cccbrk.c_time = 1;
-#endif /* OXOS */
-#endif /* VEOL */
-#endif /* ZILOG */
- errno = 0;
-#ifdef BSD44ORPOSIX /* Set new modes */
- x = tcsetattr(0,TCSADRAIN,&cccbrk);
-#else /* ATTSV */ /* or the POSIX way */
- x = ioctl(0,TCSETAW,&cccbrk); /* the Sys V way */
-#endif /* BSD44ORPOSIX */
-#endif /* SVORPOSIX */
-
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
- debug(F101,"concb x","",x);
- debug(F101,"concb errno","",errno);
-
-#ifdef V7
-#ifndef MINIX
- if (kmem[CON] < 0) {
- qaddr[CON] = initrawq(0);
- if((kmem[CON] = open("/dev/kmem", 0)) < 0) {
- fprintf(stderr, "Can't read /dev/kmem in concb.\n");
- perror("/dev/kmem");
- exit(1);
- }
- }
-#endif /* MINIX */
-#endif /* V7 */
-#endif /* Plan9 */
-
- if (x > -1)
- constate = CON_CB;
-
- debug(F101,"concb returns","",x);
- return(x);
-}
-
-/* C O N B I N -- Put console in binary mode */
-
-/* Returns 0 if ok, -1 if not */
-
-int
-#ifdef CK_ANSIC
-conbin(char esc)
-#else
-conbin(esc) char esc;
-#endif /* CK_ANSIC */
-/* conbin */ {
-
- int x;
-
- debug(F101,"conbin constate","",constate);
-
- if (constate == CON_BIN)
- return(0);
-
- if (!isatty(0)) return(0); /* only for real ttys */
- congm(); /* Get modes if necessary. */
- debug(F100,"conbin","",0);
- escchr = esc; /* Make this available to other fns */
- ckxech = 1; /* Program can echo characters */
-#ifdef aegis
- conbufn = 0;
- if (concrp) return(write(1, "\035\002", 2));
- if (conuid == input_pad_$uid) {
- pad_$raw(ios_$stdin, st);
- return(0);
- }
-#endif /* aegis */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifdef Plan9
- return p9conbin();
-#else
-#ifdef SVORPOSIX
-#ifndef OXOS
-#ifdef QNX
- ccraw.c_lflag &= ~(ISIG|ICANON|ECHO);
-#else
-#ifdef COHERENT
- ccraw.c_lflag &= ~(ISIG|ICANON|ECHO);
-#else
- ccraw.c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
-#endif /* COHERENT */
-#endif /* QNX */
-#else /* OXOS */
- ccraw.c_lflag &= ~(ISIG|ICANON|ECHO);
- ccraw.c_cc[VDISCARD] = ccraw.c_cc[VLNEXT] = CDISABLE;
-#endif /* OXOS */
- ccraw.c_iflag |= IGNPAR;
-/*
- Note that for terminal sessions we disable Xon/Xoff flow control to allow
- the passage ^Q and ^S as data characters for EMACS, and to allow XMODEM
- transfers to work when C-Kermit is in the middle, etc. Hardware flow
- control, if in use, is not affected.
-*/
-#ifdef ATTSV
-#ifdef BSD44
- ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF
- |INPCK|ISTRIP);
-#else
- ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXANY|IXOFF
- |INPCK|ISTRIP);
-#endif /* BSD44 */
-#else /* POSIX */
- ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IXON|IXOFF|INPCK|ISTRIP);
-#endif /* ATTSV */
- ccraw.c_oflag &= ~OPOST;
-#ifdef COMMENT
-/*
- WHAT THE HECK WAS THIS FOR?
- The B9600 setting (obviously) prevents CONNECT from working at any
- speed other than 9600 when you are logged in to the 7300 on a serial
- line. Maybe some of the other flags are necessary -- if so, put back
- the ones that are needed. This code is supposed to work the same, no
- matter whether you are logged in to the 7300 on the real console device,
- or through a serial port.
-*/
-#ifdef ATT7300
- ccraw.c_cflag = CLOCAL | B9600 | CS8 | CREAD | HUPCL;
-#endif /* ATT7300 */
-#endif /* COMMENT */
-
-/*** Kermit used to put the console in 8-bit raw mode, but some users have
- *** pointed out that this should not be done, since some sites actually
- *** use terminals with parity settings on their Unix systems, and if we
- *** override the current settings and stop doing parity, then their terminals
- *** will display blotches for characters whose parity is wrong. Therefore,
- *** the following two lines are commented out (Larry Afrin, Clemson U):
- ***
- *** ccraw.c_cflag &= ~(PARENB|CSIZE);
- *** ccraw.c_cflag |= (CS8|CREAD);
- ***
- *** Sys III/V sites that have trouble with this can restore these lines.
- ***/
-#ifndef VINTR
- ccraw.c_cc[0] = 003; /* Interrupt char is Ctrl-C */
-#else
- ccraw.c_cc[VINTR] = 003;
-#endif /* VINTR */
-#ifndef VQUIT
- ccraw.c_cc[1] = escchr; /* Escape during packet mode */
-#else
- ccraw.c_cc[VQUIT] = escchr;
-#endif /* VQUIT */
-#ifndef VEOF
- ccraw.c_cc[4] = 1;
-#else
-#ifndef OXOS
-#ifdef VMIN
- ccraw.c_cc[VMIN] = 1;
-#endif /* VMIN */
-#else /* OXOS */
- ccraw.c_min = 1;
-#endif /* OXOS */
-#endif /* VEOF */
-
-#ifdef ZILOG
- ccraw.c_cc[5] = 0;
-#else
-#ifndef VEOL
- ccraw.c_cc[5] = 1;
-#else
-#ifndef OXOS
-#ifdef VTIME
- ccraw.c_cc[VTIME] = 1;
-#endif /* VTIME */
-#else /* OXOS */
- ccraw.c_time = 1;
-#endif /* OXOS */
-#endif /* VEOL */
-#endif /* ZILOG */
-
-#ifdef BSD44ORPOSIX
- x = tcsetattr(0,TCSADRAIN,&ccraw); /* Set new modes. */
-#else
- x = ioctl(0,TCSETAW,&ccraw);
-#endif /* BSD44ORPOSIX */
-#else /* Berkeley, etc. */
- x = conchk(); /* Because stty() is destructive */
- if (x > 0)
- congetbuf(x);
- ccraw.sg_flags |= (RAW|TANDEM); /* Set rawmode, XON/XOFF (ha) */
- ccraw.sg_flags &= ~(ECHO|CRMOD); /* Set char wakeup, no echo */
-#ifdef BELLV10
- x = ioctl(0,TIOCSETP,&ccraw);
-#else
- x = stty(0,&ccraw);
-#endif /* BELLV10 */
-#endif /* SVORPOSIX */
-#endif /* Plan9 */
-
- if (x > -1)
- constate = CON_BIN;
-
- debug(F101,"conbin returns","",x);
- return(x);
-
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
-}
-
-
-/* C O N R E S -- Restore the console terminal */
-
-int
-conres() {
- int x;
- debug(F101,"conres cgmf","",cgmf);
- debug(F101,"conres constate","",constate);
-
- if (cgmf < 1) /* Do nothing if modes unchanged */
- return(0);
- if (constate == CON_RES)
- return(0);
-
- if (!isatty(0)) return(0); /* only for real ttys */
- debug(F100,"conres isatty ok","",0);
- ckxech = 0; /* System should echo chars */
-
-#ifdef aegis
- conbufn = 0;
- if (concrp) return(write(1, "\035\001", 2));
- if (conuid == input_pad_$uid) {
- pad_$cooked(ios_$stdin, st);
- constate = CON_RES;
- return(0);
- }
-#endif /* aegis */
-
-#ifdef Plan9
- p9conres();
-#else
-#ifdef BSD44ORPOSIX
- debug(F100,"conres restoring tcsetattr","",0);
- x = tcsetattr(0,TCSADRAIN,&ccold);
-#else
-#ifdef ATTSV
- debug(F100,"conres restoring ioctl","",0);
- x = ioctl(0,TCSETAW,&ccold);
-#else /* BSD, V7, and friends */
-#ifdef sony_news /* Sony NEWS */
- if (km_con != -1)
- ioctl(0,TIOCKSET,&km_con); /* Restore console Kanji mode */
-#endif /* sony_news */
- msleep(100);
- debug(F100,"conres restoring stty","",0);
- x = conchk(); /* Because stty() is destructive */
- if (x > 0)
- congetbuf(x);
-#ifdef BELLV10
- x = ioctl(0,TIOCSETP,&ccold);
-#else
- x = stty(0,&ccold);
-#endif /* BELLV10 */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-#endif /* Plan9 */
- if (x > -1)
- constate = CON_RES;
-
- debug(F101,"conres returns","",x);
- return(x);
-}
-
-/* C O N O C -- Output a character to the console terminal */
-
-int
-#ifdef CK_ANSIC
-conoc(char c)
-#else
-conoc(c) char c;
-#endif /* CK_ANSIC */
-/* conoc */ {
-
-#ifdef IKSD
- if (inserver && !local)
- return(ttoc(c));
-
-#ifdef CK_ENCRYPTION
- if (inserver && TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(&c,1);
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
-
-#ifdef Plan9
- return conwrite(&c,1);
-#else
- return(write(1,&c,1));
-#endif /* Plan9 */
-}
-
-/* C O N X O -- Write x characters to the console terminal */
-
-int
-conxo(x,s) int x; char *s; {
-
-#ifdef IKSD
- if (inserver && !local)
- return(ttol((CHAR *)s,x));
-
-#ifdef CK_ENCRYPTION
- if (inserver && TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(s,x);
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
-
-#ifdef Plan9
- return(conwrite(s,x));
-#else
- return(write(1,s,x));
-#endif /* Plan9 */
-}
-
-/* C O N O L -- Write a line to the console terminal */
-
-int
-conol(s) char *s; {
- int len;
- if (!s) s = ""; /* Always do this! */
- len = strlen(s);
- if (len == 0)
- return(0);
-
-#ifdef IKSD
- if (inserver && !local)
- return(ttol((CHAR *)s,len));
-
-#ifdef CK_ENCRYPTION
- if (inserver && TELOPT_ME(TELOPT_ENCRYPTION)) {
- if (nxpacket < len) {
- if (xpacket) {
- free(xpacket);
- xpacket = NULL;
- nxpacket = 0;
- }
- len = len > 10240 ? len : 10240;
- xpacket = (CHAR *)malloc(len);
- if (!xpacket) {
- fprintf(stderr,"ttol malloc failure\n");
- return(-1);
- } else
- nxpacket = len;
- }
- memcpy(xpacket,s,len);
- s = (char *)xpacket;
- ck_tn_encrypt(s,len);
- }
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
-
-#ifdef Plan9
- return(conwrite(s,len));
-#else
- return(write(1,s,len));
-#endif /* Plan9 */
-}
-
-/* C O N O L A -- Write an array of lines to the console terminal */
-
-int
-conola(s) char *s[]; {
- char * p;
- int i, x;
-
-
- if (!s) return(0);
- for (i = 0; ; i++) {
- p = s[i];
- if (!p) p = ""; /* Let's not dump core shall we? */
- if (!*p)
- break;
-#ifdef IKSD
- if (inserver && !local)
- x = ttol((CHAR *)p,(int)strlen(p));
- else
-#endif /* IKSD */
- x = conol(p);
- if (x < 0)
- return(-1);
- }
- return(0);
-}
-
-/* C O N O L L -- Output a string followed by CRLF */
-
-int
-conoll(s) char *s; {
- CHAR buf[3];
- buf[0] = '\r';
- buf[1] = '\n';
- buf[2] = '\0';
- if (!s) s = "";
-
-#ifdef IKSD
- if (inserver && !local) {
- if (*s) ttol((CHAR *)s,(int)strlen(s));
- return(ttol(buf,2));
- }
-#endif /* IKSD */
-
- if (*s) conol(s);
-#ifdef IKSD
-#ifdef CK_ENCRYPTION
- if (inserver && TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt((char *)buf,2);
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
-
-#ifdef Plan9
- return(conwrite(buf, 2));
-#else
- return(write(1,buf,2));
-#endif /* Plan9 */
-}
-
-/* C O N C H K -- Return how many characters available at console */
-/*
- We could also use select() here to cover a few more systems that are not
- covered by any of the following, e.g. HP-UX 9.0x on the model 800.
-*/
-int
-conchk() {
- static int contyp = 0; /* +1 for isatty, -1 otherwise */
-
- if (contyp == 0) /* This prevents unnecessary */
- contyp = (isatty(0) ? 1 : -1); /* duplicated calls to isatty() */
- debug(F101,"conchk contyp","",contyp);
- if (backgrd || (contyp < 0))
- return(0);
-
-#ifdef aegis
- if (conbufn > 0) return(conbufn); /* use old count if nonzero */
-
- /* read in more characters */
- conbufn = ios_$get(ios_$stdin,
- ios_$cond_opt, conbuf, (long)sizeof(conbuf), st);
- if (st.all != status_$ok) conbufn = 0;
- conbufp = conbuf;
- return(conbufn);
-#else
-#ifdef IKSD
- if (inserver && !local)
- return(in_chk(1,ttyfd));
- else
-#endif /* IKSD */
- return(in_chk(0,0));
-#endif /* aegis */
-}
-
-/* C O N I N C -- Get a character from the console */
-/*
- Call with timo > 0 to do a timed read, timo == 0 to do an untimed blocking
- read. Upon success, returns the character. Upon failure, returns -1.
- A timed read that does not complete within the timeout period returns -2.
-*/
-int
-coninc(timo) int timo; {
- int n = 0; CHAR ch;
- int xx;
-
- if (conbufn > 0) { /* If something already buffered */
- --conbufn;
- return((unsigned)(*conbufp++ & 0xff));
- }
-
- errno = 0; /* Clear this */
-#ifdef IKSD
- if (inserver && !local) {
- xx = ttinc(timo);
- if (xx < 0)
- return(ttinctimo ? -2 : -1);
- else
- return(xx);
- }
-#endif /* IKSD */
-
-#ifdef aegis /* Apollo Aegis only... */
- debug(F101,"coninc timo","",timo);
- fflush(stdout);
- if (conchk() > 0) {
- --conbufn;
- return((unsigned)(*conbufp++ & 0xff));
- }
-#endif /* aegis */
-
-#ifdef TTLEBUF
- if (
-#ifdef IKSD
- inserver &&
-#endif /* IKSD */
- !xlocal
- ) {
- if (ttpush >= 0) {
- debug(F111,"ttinc","ttpush",ttpush);
- ch = ttpush;
- ttpush = -1;
- return(ch);
- }
- if (le_data) {
- if (le_getchar(&ch) > 0) {
- debug(F111,"ttinc LocalEchoInBuf","ch",ch);
- return(ch);
- }
- }
- }
-#endif /* TTLEBUF */
-
- if (timo <= 0) { /* Untimed, blocking read. */
- while (1) { /* Keep trying till we get one. */
- n = read(0, &ch, 1); /* Read a character. */
- if (n == 0) continue; /* Shouldn't happen. */
- if (n > 0) { /* If read was successful, */
-#ifdef IKSD
-#ifdef CK_ENCRYPTION
- debug(F100,"coninc decrypt 1","",0);
- if (inserver && !local && TELOPT_U(TELOPT_ENCRYPTION))
- ck_tn_decrypt((char *)&ch,1);
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
- return((unsigned)(ch & 0xff)); /* return the character. */
- }
-
-/* Come here if read() returned an error. */
-
- debug(F101, "coninc(0) errno","",errno); /* Log the error. */
-#ifndef OXOS
-#ifdef SVORPOSIX
-#ifdef CIE /* CIE Regulus has no EINTR symbol? */
-#ifndef EINTR
-#define EINTR 4
-#endif /* EINTR */
-#endif /* CIE */
-/*
- This routine is used for several different purposes. In CONNECT mode, it is
- used to do an untimed, blocking read from the keyboard in the lower CONNECT
- fork. During local-mode file transfer, it reads a character from the
- console to interrupt the file transfer (like A for a status report, X to
- cancel a file, etc). Obviously, we don't want the reads in the latter case
- to be blocking, or the file transfer would stop until the user typed
- something. Unfortunately, System V does not allow the console device input
- buffer to be sampled nondestructively (e.g. by conchk()), so a kludge is
- used instead. During local-mode file transfer, the SIGQUIT signal is armed
- and trapped by esctrp(), and this routine pretends to have read the quit
- character from the keyboard normally. But, kludge or no kludge, the read()
- issued by this command, under System V only, can fail if a signal -- ANY
- signal -- is caught while the read is pending. This can occur not only when
- the user types the quit character, but also during telnet negotiations, when
- the lower CONNECT fork signals the upper one about an echoing mode change.
- When this happens, we have to post the read() again. This is apparently not
- a problem in BSD-based UNIX versions.
-*/
- if (errno == EINTR) /* Read interrupted. */
- if (conesc) { /* If by SIGQUIT, */
- conesc = 0; /* the conesc variable is set, */
- return(escchr); /* so return the escape character. */
- } else continue; /* By other signal, try again. */
-#else
-/*
- This might be dangerous, but let's do this on non-System V versions too,
- since at least one SunOS 4.1.2 user complains of immediate disconnections
- upon first making a TELNET connection.
-*/
- if (errno == EINTR) /* Read interrupted. */
- continue;
-#endif /* SVORPOSIX */
-#else /* OXOS */
- if (errno == EINTR) /* Read interrupted. */
- continue;
-#endif /* OXOS */
- return(-1); /* Error */
- }
- }
-#ifdef DEBUG
- if (deblog && timo <= 0) {
- debug(F100,"coninc timeout logic error","",0);
- timo = 1;
- }
-#endif /* DEBUG */
-
-/* Timed read... */
-
- saval = signal(SIGALRM,timerh); /* Set up timeout handler. */
- xx = alarm(timo); /* Set the alarm. */
- debug(F101,"coninc alarm set","",timo);
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) /* The read() timed out. */
- n = -2; /* Code for timeout. */
- else
- n = read(0, &ch, 1);
- ttimoff(); /* Turn off timer */
- if (n > 0) { /* Got character OK. */
-#ifdef IKSD
-#ifdef CK_ENCRYPTION
- debug(F100,"coninc decrypt 2","",0);
- if (inserver && !local && TELOPT_U(TELOPT_ENCRYPTION))
- ck_tn_decrypt((char *)&ch,1);
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
- return((unsigned)(ch & 0xff)); /* Return it. */
- }
-/*
- read() returned an error. Same deal as above, but without the loop.
-*/
- debug(F101, "coninc(timo) n","",n);
- debug(F101, "coninc(timo) errno","",errno);
-#ifndef OXOS
-#ifdef SVORPOSIX
- if (n == -1 && errno == EINTR && conesc != 0) {
- conesc = 0;
- return(escchr); /* User entered escape character. */
- }
-#endif /* SVORPOSIX */
- if (n == 0 && errno > 0) { /* It's an error */
- return(-1);
- }
-#endif /* ! OXOS */
- return(n);
-}
-
-/* C O N G K S -- Console Get Keyboard Scancode */
-
-#ifndef congks
-/*
- This function needs to be filled in with the various system-dependent
- system calls used by SUNOS, NeXT OS, Xenix, Aviion, etc, to read a full
- keyboard scan code. Unfortunately there aren't any.
-*/
-int
-congks(timo) int timo; {
-
-#ifdef IKSD
- if (inserver && !local)
- return(ttinc(timo));
-#endif /* IKSD */
-
- return(coninc(timo));
-}
-#endif /* congks */
-
-#ifdef ATT7300
-
-/* A T T D I A L -- Dial up the remote system using internal modem
- * Purpose: to open and dial a number on the internal modem available on the
- * ATT7300 UNIX PC. Written by Joe Doupnik. Superceeds version written by
- * Richard E. Hill, Dickinson, TX. which employed dial(3c).
- * Uses information in <sys/phone.h> and our status int attmodem.
- */
-attdial(ttname,speed,telnbr) char *ttname,*telnbr; long speed; {
- char *telnum;
-
- attmodem &= ~ISMODEM; /* modem not in use yet */
- /* Ensure O_NDELAY is set, else i/o traffic hangs */
- /* We turn this flag off once the dial is complete */
- fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) | O_NDELAY);
-
- /* Condition line, check availability & DATA mode, turn on speaker */
- if (ioctl(ttyfd,PIOCOFFHOOK, &dialer) == -1) {
- printf("cannot access phone\n");
- ttclos(0);
- return (-2);
- }
- ioctl(ttyfd,PIOCGETP,&dialer); /* get phone dialer parameters */
-
- if (dialer.c_lineparam & VOICE) { /* phone must be in DATA mode */
- printf(" Should not dial with modem in VOICE mode.\n");
- printf(" Exit Kermit, switch to DATA and retry call.\n");
- ttclos(0);
- return (-2);
- }
-#ifdef ATTTONED /* Old way, tone dialing only. */
- dialer.c_lineparam = DATA | DTMF; /* Dial with tones, */
- dialer.c_lineparam &= ~PULSE; /* not with pulses. */
-#else
- /* Leave current pulse/tone state alone. */
- /* But what about DATA? Add it back if you have trouble. */
- /* sys/phone says you get DATA automatically by opening device RDWR */
-#endif
- dialer.c_waitdialtone = 5; /* wait 5 sec for dialtone */
-#ifdef COMMENT
- dialer.c_feedback = SPEAKERON|NORMSPK|RINGON; /* control speaker */
-#else
- /* sys/phone says RINGON used only for incoming voice calls */
- dialer.c_feedback &= ~(SOFTSPK|LOUDSPK);
- dialer.c_feedback |= SPEAKERON|NORMSPK;
-#endif
- dialer.c_waitflash = 500; /* 0.5 sec flash hook */
- if(ioctl(ttyfd,PIOCSETP,&dialer) == -1) { /* set phone parameters */
- printf("Cannot set modem characteristics\n");
- ttclos(0);
- return (-2);
- }
- ioctl(ttyfd,PIOCRECONN,0); /* Turns on speaker for pulse */
-
-#ifdef COMMENT
- fprintf(stderr,"Phone line status. line_par:%o dialtone_wait:%o \
-line_status:%o feedback:%o\n",
- dialer.c_lineparam, dialer.c_waitdialtone,
- dialer.c_linestatus, dialer.c_feedback);
-#endif
-
- attmodem |= ISMODEM; /* modem is now in-use */
- sleep(1);
- for (telnum = telnbr; *telnum != '\0'; telnum++) /* dial number */
-#ifdef ATTTONED
- /* Tone dialing only */
- if (ioctl(ttyfd,PIOCDIAL,telnum) != 0) {
- perror("Error in dialing");
- ttclos(0);
- return(-2);
- }
-#else /* Allow Pulse or Tone dialing */
- switch (*telnum) {
- case 't': case 'T': case '%': /* Tone dialing requested */
- dialer.c_lineparam |= DTMF;
- dialer.c_lineparam &= ~PULSE;
- if (ioctl(ttyfd,PIOCSETP,&dialer) == -1) {
- printf("Cannot set modem to tone dialing\n");
- ttclos(0);
- return(-2);
- }
- break;
- case 'd': case 'D': case 'p': case 'P': case '^':
- dialer.c_lineparam |= PULSE;
- dialer.c_lineparam &= ~DTMF;
- if (ioctl(ttyfd,PIOCSETP,&dialer) == -1) {
- printf("Cannot set modem to pulse dialing\n");
- ttclos(0);
- return(-2);
- }
- break;
- default:
- if (ioctl(ttyfd,PIOCDIAL,telnum) != 0) {
- perror("Dialing error");
- ttclos(0);
- return(-2);
- }
- break;
- }
-#endif
-
- ioctl(ttyfd,PIOCDIAL,"@"); /* terminator for data call */
- do { /* wait for modems to Connect */
- if (ioctl(ttyfd,PIOCGETP,&dialer) != 0) { /* get params */
- perror("Cannot get modems to connect");
- ttclos(0);
- return(-2);
- }
- } while ((dialer.c_linestatus & MODEMCONNECTED) == 0);
- /* Turn off O_NDELAY flag now. */
- fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY);
- signal(SIGHUP, sighup); /* hangup on loss of carrier */
- return(0); /* return success */
-}
-
-/*
- Offgetty, ongetty functions. These function get the 'getty(1m)' off
- and restore it to the indicated line. Shell's return codes are:
- 0: Can't do it. Probably a user logged on.
- 1: No need. No getty on that line.
- 2: Done, you should restore the getty when you're done.
- DOGETY System(3), however, returns them as 0, 256, 512, respectively.
- Thanks to Kevin O'Gorman, Anarm Software Systems.
-
- getoff.sh looks like: geton.sh looks like:
- setgetty $1 0 setgetty $1 1
- err=$? exit $?
- sleep 2
- exit $err
-*/
-
-/* O F F G E T T Y -- Turn off getty(1m) for the communications tty line
- * and get status so it can be restarted after the line is hung up.
- */
-int
-offgetty(ttname) char *ttname; {
- char temp[30];
- while (*ttname != '\0') ttname++; /* seek terminator of path */
- ttname -= 3; /* get last 3 chars of name */
- sprintf(temp,"/usr/bin/getoff.sh %s",ttname);
- return(zsyscmd(temp));
-}
-
-/* O N G E T T Y -- Turn on getty(1m) for the communications tty line */
-
-int
-ongetty(ttname) char *ttname; {
- char temp[30];
- while (*ttname != '\0') ttname++; /* comms tty path name */
- ttname -= 3;
- sprintf(temp,"/usr/bin/geton.sh %s",ttname);
- return(zsyscmd(temp));
-}
-#endif /* ATT7300 */
-
-/* T T S C A R R -- Set ttcarr variable, controlling carrier handling.
- *
- * 0 = Off: Always ignore carrier. E.g. you can connect without carrier.
- * 1 = On: Heed carrier, except during dialing. Carrier loss gives disconnect.
- * 2 = Auto: For "modem direct": The same as "Off".
- * For real modem types: Heed carrier during connect, but ignore
- * it anytime else. Compatible with pre-5A C-Kermit versions.
- *
- * As you can see, this setting does not affect dialing, which always ignores
- * carrier (unless there is some special exception for some modem type). It
- * does affect ttopen() if it is set before ttopen() is used. This setting
- * takes effect on the next call to ttopen()/ttpkt()/ttvt(). And they are
- * (or should be) always called before any communications is tried, which
- * means that, practically speaking, the effect is immediate.
- *
- * Of course, nothing of this applies to remote mode (xlocal = 0).
- *
- * Someone has yet to uncover how to manipulate the carrier in the BSD
- * environment (or any non-termio using environment). Until that time, this
- * will simply be a no-op for BSD.
- *
- * Note that in previous versions, the carrier was most often left unchanged
- * in ttpkt()/ttvt() unless they were called with FLO_DIAL or FLO_DIAX. This
- * has changed. Now it is controlled by ttcarr in conjunction with these
- * modes.
- */
-int
-ttscarr(carrier) int carrier; {
- ttcarr = carrier;
- debug(F101, "ttscarr","",ttcarr);
- return(ttcarr);
-}
-
-/* C A R R C T L -- Set tty modes for carrier treatment.
- *
- * Sets the appropriate bits in a termio or sgttyb struct for carrier control
- * (actually, there are no bits in sgttyb for that), or performs any other
- * operations needed to control this on the current system. The function does
- * not do the actual TCSETA or stty, since often we want to set other bits too
- * first. Don't call this function when xlocal is 0, or the tty is not opened.
- *
- * We don't know how to do anything like carrier control on non-ATTSV systems,
- * except, apparently, ultrix. See above. It is also known that this doesn't
- * have much effect on a Xenix system. For Xenix, one should switch back and
- * forth between the upper and lower case device files. Maybe later.
- * Presently, Xenix will stick to the mode it was opened with.
- *
- * carrier: 0 = ignore carrier, 1 = require carrier.
- * The current state is saved in curcarr, and checked to save labour.
- */
-#ifdef SVORPOSIX
-int
-#ifdef BSD44ORPOSIX
-carrctl(ttpar, carrier) struct termios *ttpar; int carrier;
-#else /* ATTSV */
-carrctl(ttpar, carrier) struct termio *ttpar; int carrier;
-#endif /* BSD44ORPOSIX */
-/* carrctl */ {
- debug(F101, "carrctl","",carrier);
- if (carrier)
- ttpar->c_cflag &= ~CLOCAL;
- else
- ttpar->c_cflag |= CLOCAL;
- return(0);
-}
-#else /* Berkeley, V7, et al... */
-int
-carrctl(ttpar, carrier) struct sgttyb *ttpar; int carrier; {
- debug(F101, "carrctl","",carrier);
- if (carrier == curcarr)
- return(0);
- curcarr = carrier;
-#ifdef ultrix
-#ifdef COMMENT
-/*
- Old code from somebody at DEC that tends to get stuck, time out, etc.
-*/
- if (carrier) {
- ioctl(ttyfd, TIOCMODEM, &temp);
- ioctl(ttyfd, TIOCHPCL, 0);
- } else {
- /* (According to the manuals, TIOCNCAR should be preferred */
- /* over TIOCNMODEM...) */
- ioctl(ttyfd, TIOCNMODEM, &temp);
- }
-#else
-/*
- New code from Jamie Watson that, he says, eliminates the problems.
-*/
- if (carrier) {
- ioctl(ttyfd, TIOCCAR);
- ioctl(ttyfd, TIOCHPCL);
- } else {
- ioctl(ttyfd, TIOCNCAR);
- }
-#endif /* COMMENT */
-#endif /* ultrix */
- return(0);
-}
-#endif /* SVORPOSIX */
-
-
-/* T T G M D M -- Get modem signals */
-/*
- Looks for RS-232 modem signals, and returns those that are on in as its
- return value, in a bit mask composed of the BM_xxx values defined in ckcdeb.h.
- Returns:
- -3 Not implemented
- -2 if the communication device does not have modem control (e.g. telnet)
- -1 on error.
- >= 0 on success, with a bit mask containing the modem signals that are on.
-*/
-
-/*
- Define the symbol K_MDMCTL if we have Sys V R3 / 4.3 BSD style
- modem control, namely the TIOCMGET ioctl.
-*/
-
-#ifdef BSD43
-#define K_MDMCTL
-#endif /* BSD43 */
-
-#ifdef SUNOS4
-#define K_MDMCTL
-#endif /* SUNOS4 */
-
-/*
- SCO OpenServer R5.0.4. The TIOCMGET definition is hardwired in because it
- is skipped in termio.h when _POSIX_SOURCE is defined. But _POSIX_SOURCE
- must be defined in order to get the high serial speeds that are new to
- 5.0.4. However, the regular SCO drivers do not implement TIOCMGET, so the
- ioctl() returns -1 with errno 22 (invalid function). But third-party
- drivers, e.g. for Digiboard, do implement it, and so it should work on ports
- driven by those drivers.
-*/
-#ifdef SCO_OSR504
-#ifndef TIOCMGET
-#define TIOCMGET (('t'<<8)|29)
-#endif /* TIOCMGET */
-#endif /* SCO_OSR504 */
-
-#ifdef CK_SCOV5
-/* Because POSIX strictness in <sys/termio.h> won't let us see these. */
-#ifndef TIOCM_DTR
-#define TIOCM_DTR 0x0002 /* data terminal ready */
-#define TIOCM_RTS 0x0004 /* request to send */
-#define TIOCM_CTS 0x0020 /* clear to send */
-#define TIOCM_CAR 0x0040 /* carrier detect */
-#define TIOCM_RNG 0x0080 /* ring */
-#define TIOCM_DSR 0x0100 /* data set ready */
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#endif /* TIOCM_DTR */
-#endif /* CK_SCOV5 */
-
-#ifdef QNX
-#define K_MDMCTL
-#else
-#ifdef TIOCMGET
-#define K_MDMCTL
-#endif /* TIOCMGET */
-#endif /* QNX */
-/*
- "A serial communication program that can't read modem signals
- is like a car without windows."
-*/
-int
-ttgmdm() {
-
-#ifdef QNX
-#include <sys/qioctl.h>
-
- unsigned long y, mdmbits[2];
- int x, z = 0;
-
- if (xlocal && ttyfd < 0)
- return(-1);
-
-#ifdef NETCONN
- if (netconn) { /* Network connection */
-#ifdef TN_COMPORT
- if (istncomport()) {
- gotsigs = 1;
- return(tngmdm());
- } else
-#endif /* TN_COMPORT */
- return(-2); /* No modem signals */
- }
-#endif /* NETCONN */
-
-#ifdef NETCMD
- if (ttpipe) return(-2);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(-2);
-#endif /* NETPTY */
-
- mdmbits[0] = 0L;
- mdmbits[1] = 0L;
-/*
- * From <sys/qioctl.h>:
- *
- * SERIAL devices (all Dev.ser versions)
- * 0 : DTR 8 = Data Bits 0 16 - reserved 24 - reserved
- * 1 : RTS 9 = Data Bits 1 17 - reserved 25 - reserved
- * 2 = Out 1 10 = Stop Bits 18 - reserved 26 - reserved
- * 3 = Int Enable 11 = Par Enable 19 - reserved 27 - reserved
- * 4 = Loop 12 = Par Even 20 = CTS 28 - reserved
- * 5 - reserved 13 = Par Stick 21 = DSR 29 - reserved
- * 6 - reserved 14 : Break 22 = RI 30 - reserved
- * 7 - reserved 15 = 0 23 = CD 31 - reserved
- */
- errno = 0;
- x = qnx_ioctl(ttyfd, QCTL_DEV_CTL, &mdmbits[0], 8, &mdmbits[0], 4);
- debug(F101,"ttgmdm qnx_ioctl","",x);
- debug(F101,"ttgmdm qnx_ioctl errno","",errno);
- if (!x) {
- debug(F101,"ttgmdm qnx_ioctl mdmbits[0]","",mdmbits[0]);
- debug(F101,"ttgmdm qnx_ioctl mdmbits[1]","",mdmbits[1]);
- y = mdmbits[0];
- if (y & 0x000001L) z |= BM_DTR; /* Bit 0 */
- if (y & 0x000002L) z |= BM_RTS; /* Bit 1 */
- if (y & 0x100000L) z |= BM_CTS; /* Bit 20 */
- if (y & 0x200000L) z |= BM_DSR; /* Bit 21 */
- if (y & 0x400000L) z |= BM_RNG; /* Bit 22 */
- if (y & 0x800000L) z |= BM_DCD; /* Bit 23 */
- debug(F101,"ttgmdm qnx result","",z);
- debug(F110,"ttgmdm qnx CD = ",(z & BM_DCD) ? "On" : "Off", 0);
- gotsigs = 1;
- return(z);
- } else return(-1);
-#else /* QNX */
-#ifdef HPUX /* HPUX has its own way */
- int x, z;
-
-#ifdef HPUX10 /* Modem flag word */
- mflag y; /* mflag typedef'd in <sys/modem.h> */
-#else
-#ifdef HPUX9
- mflag y;
-#else
-#ifdef HPUX8
- mflag y;
-#else
- unsigned long y; /* Not sure about pre-8.0... */
-#endif /* HPUX8 */
-#endif /* HPUX9 */
-#endif /* HPUX10 */
-
- if (xlocal && ttyfd < 0)
- return(-1);
-
-#ifdef NETCONN
- if (netconn) { /* Network connection */
-#ifdef TN_COMPORT
- if (istncomport()) {
- gotsigs = 1;
- return(tngmdm());
- } else
-#endif /* TN_COMPORT */
- return(-2); /* No modem signals */
- }
-#endif /* NETCONN */
-
-#ifdef NETCMD
- if (ttpipe) return(-2);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(-2);
-#endif /* NETPTY */
-
- if (xlocal) /* Get modem signals */
- x = ioctl(ttyfd,MCGETA,&y);
- else
- x = ioctl(0,MCGETA,&y);
- if (x < 0) return(-1);
- debug(F101,"ttgmdm","",y);
-
- z = 0; /* Initialize return value */
-
-/* Now set bits for each modem signal that is reported to be on. */
-
-#ifdef MCTS
- /* Clear To Send */
- debug(F101,"ttgmdm HPUX CTS","",y & MCTS);
- if (y & MCTS) z |= BM_CTS;
-#endif
-#ifdef MDSR
- /* Data Set Ready */
- debug(F101,"ttgmdm HPUX DSR","",y & MDSR);
- if (y & MDSR) z |= BM_DSR;
-#endif
-#ifdef MDCD
- /* Carrier */
- debug(F101,"ttgmdm HPUX DCD","",y & MDCD);
- if (y & MDCD) z |= BM_DCD;
-#endif
-#ifdef MRI
- /* Ring Indicate */
- debug(F101,"ttgmdm HPUX RI","",y & MRI);
- if (y & MRI) z |= BM_RNG;
-#endif
-#ifdef MDTR
- /* Data Terminal Ready */
- debug(F101,"ttgmdm HPUX DTR","",y & MDTR);
- if (y & MDTR) z |= BM_DTR;
-#endif
-#ifdef MRTS
- /* Request To Send */
- debug(F101,"ttgmdm HPUX RTS","",y & MRTS);
- if (y & MRTS) z |= BM_RTS;
-#endif
- gotsigs = 1;
- return(z);
-
-#else /* ! HPUX */
-
-#ifdef K_MDMCTL
-/*
- Note, TIOCMGET might already have been defined in <sys/ioctl.h> or elsewhere.
- If not, we try including <sys/ttycom.h> -- if this blows up then more ifdefs
- are needed.
-*/
-#ifndef TIOCMGET
-#include <sys/ttycom.h>
-#endif /* TIOCMGET */
-
- int x, y, z;
-
- debug(F100,"ttgmdm K_MDMCTL defined","",0);
-
-#ifdef NETCONN
- if (netconn) { /* Network connection */
-#ifdef TN_COMPORT
- if (istncomport()) {
- gotsigs = 1;
- return(tngmdm());
- } else
-#endif /* TN_COMPORT */
- return(-2); /* No modem signals */
- }
-#endif /* NETCONN */
-
-#ifdef NETCMD
- if (ttpipe) return(-2);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(-2);
-#endif /* NETPTY */
-
- if (xlocal && ttyfd < 0)
- return(-1);
-
- if (xlocal)
- x = ioctl(ttyfd,TIOCMGET,&y); /* Get modem signals. */
- else
- x = ioctl(0,TIOCMGET,&y);
- debug(F101,"ttgmdm TIOCMGET ioctl","",x);
- if (x < 0) {
- debug(F101,"ttgmdm errno","",errno);
- return(-1);
- }
- debug(F101,"ttgmdm bits","",y);
-
- z = 0; /* Initialize return value. */
-#ifdef TIOCM_CTS
- /* Clear To Send */
- if (y & TIOCM_CTS) z |= BM_CTS;
- debug(F101,"ttgmdm TIOCM_CTS defined","",TIOCM_CTS);
-#else
- debug(F100,"ttgmdm TIOCM_CTS not defined","",0);
-#endif
-#ifdef TIOCM_DSR
- /* Data Set Ready */
- if (y & TIOCM_DSR) z |= BM_DSR;
- debug(F101,"ttgmdm TIOCM_DSR defined","",TIOCM_DSR);
-#else
- debug(F100,"ttgmdm TIOCM_DSR not defined","",0);
-#endif
-#ifdef TIOCM_CAR
- /* Carrier */
- if (y & TIOCM_CAR) z |= BM_DCD;
- debug(F101,"ttgmdm TIOCM_CAR defined","",TIOCM_CAR);
-#else
- debug(F100,"ttgmdm TIOCM_CAR not defined","",0);
-#endif
-#ifdef TIOCM_RNG
- /* Ring Indicate */
- if (y & TIOCM_RNG) z |= BM_RNG;
- debug(F101,"ttgmdm TIOCM_RNG defined","",TIOCM_RNG);
-#else
- debug(F100,"ttgmdm TIOCM_RNG not defined","",0);
-#endif
-#ifdef TIOCM_DTR
- /* Data Terminal Ready */
- if (y & TIOCM_DTR) z |= BM_DTR;
- debug(F101,"ttgmdm TIOCM_DTR defined","",TIOCM_DTR);
-#else
- debug(F100,"ttgmdm TIOCM_DTR not defined","",0);
-#endif
-#ifdef TIOCM_RTS
- /* Request To Send */
- if (y & TIOCM_RTS) z |= BM_RTS;
- debug(F101,"ttgmdm TIOCM_RTS defined","",TIOCM_RTS);
-#else
- debug(F100,"ttgmdm TIOCM_RTS not defined","",0);
-#endif
- gotsigs = 1;
- return(z);
-
-#else /* !K_MDMCTL catch-All */
-
- debug(F100,"ttgmdm K_MDMCTL not defined","",0);
-#ifdef TIOCMGET
- debug(F100,"ttgmdm TIOCMGET defined","",0);
-#else
- debug(F100,"ttgmdm TIOCMGET not defined","",0);
-#endif /* TIOCMGET */
-#ifdef _SVID3
- debug(F100,"ttgmdm _SVID3 defined","",0);
-#else
- debug(F100,"ttgmdm _SVID3 not defined","",0);
-#endif /* _SVID3 */
-
-#ifdef NETCONN
- if (netconn) { /* Network connection */
-#ifdef TN_COMPORT
- if (istncomport()) {
- gotsigs = 1;
- return(tngmdm());
- } else
-#endif /* TN_COMPORT */
- return(-2); /* No modem signals */
- }
-#endif /* NETCONN */
-
-#ifdef NETCMD
- if (ttpipe) return(-2);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(-2);
-#endif /* NETPTY */
-
- return(-3); /* Sorry, I don't know how... */
-
-#endif /* K_MDMCTL */
-#endif /* HPUX */
-#endif /* QNX */
-}
-
-/* P S U S P E N D -- Put this process in the background. */
-
-/*
- Call with flag nonzero if suspending is allowed, zero if not allowed.
- Returns 0 on apparent success, -1 on failure (flag was zero, or
- kill() returned an error code.
-*/
-int
-psuspend(flag) int flag; {
-
-#ifdef RTU
- extern int rtu_bug;
-#endif /* RTU */
-
- if (flag == 0) return(-1);
-
-#ifdef NOJC
- return(-1);
-#else
-#ifdef SIGTSTP
-/*
- The big question here is whether job control is *really* supported.
- There's no way Kermit can know for sure. The fact that SIGTSTP is
- defined does not guarantee the Unix kernel supports it, and the fact
- that the Unix kernel supports it doesn't guarantee that the user's
- shell (or other process that invoked Kermit) supports it.
-*/
-#ifdef RTU
- rtu_bug = 1;
-#endif /* RTU */
- if (kill(0,SIGSTOP) < 0
-#ifdef MIPS
-/* Let's try this for MIPS too. */
- && kill(getpid(),SIGSTOP) < 0
-#endif /* MIPS */
- ) { /* If job control, suspend the job */
- perror("suspend");
- debug(F101,"psuspend error","",errno);
- return(-1);
- }
- debug(F100,"psuspend ok","",0);
- return(0);
-#else
- return(-1);
-#endif /* SIGTSTP */
-#endif /* NOJC */
-}
-
-/*
- setuid package, by Kristoffer Eriksson, with contributions from Dean
- Long and fdc.
-*/
-
-/* The following is for SCO when CK_ANSILIBS is defined... */
-#ifdef M_UNIX
-#ifdef CK_ANSILIBS
-#ifndef NOGETID_PROTOS
-#define NOGETID_PROTOS
-#endif /* NOGETID_PROTOS */
-#endif /* CK_ANSILIBS */
-#endif /* M_UNIX */
-
-#ifndef _POSIX_SOURCE
-#ifndef SUNOS4
-#ifndef NEXT
-#ifndef PS2AIX10
-#ifndef sequent
-#ifndef HPUX9
-#ifndef HPUX10
-#ifndef COHERENT
-#ifndef NOGETID_PROTOS
-_PROTOTYP( UID_T getuid, (void) );
-_PROTOTYP( UID_T geteuid, (void) );
-_PROTOTYP( UID_T getreuid, (void) );
-_PROTOTYP( UID_T getgid, (void) );
-_PROTOTYP( UID_T getegid, (void) );
-_PROTOTYP( UID_T getregid, (void) );
-#endif /* NOGETID_PROTOS */
-#else
-_PROTOTYP( UID_T getreuid, (void) );
-_PROTOTYP( UID_T getregid, (void) );
-#endif /* COHERENT */
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* sequent */
-#endif /* PS2AIX10 */
-#endif /* NEXT */
-#endif /* SUNOS4 */
-#endif /* _POSIX_SOURCE */
-
-/*
-Subject: Set-user-id
-To: fdc@watsun.cc.columbia.edu (Frank da Cruz)
-Date: Sat, 21 Apr 90 4:48:25 MES
-From: Kristoffer Eriksson <ske@pkmab.se>
-
-This is a set of functions to be used in programs that may be run set-user-id
-and/or set-group-id. They handle both the case where the program is not run
-with such privileges (nothing special happens then), and the case where one
-or both of these set-id modes are used. The program is made to run with the
-user's real user and group ids most of the time, except for when more
-privileges are needed. Don't set-user-id to "root".
-
-This works on System V and POSIX. In BSD, it depends on the
-"saved-set-user-id" feature.
-*/
-
-#define UID_ROOT 0 /* Root user and group ids */
-#define GID_ROOT 0
-
-/*
- The following code defines the symbol SETEUID for UNIX systems based
- on BSD4.4 (either -Encumbered or -Lite). This program will then use
- seteuid() and setegid() instead of setuid() and setgid(), which still
- don't allow arbitrary switching. It also avoids setreuid() and
- setregid(), which are included in BSD4.4 for compatibility only, are
- insecure, and print warnings to stderr under at least one system (NetBSD
- 1.0). Note that POSIX systems should still use setuid() and setgid();
- the seteuid() and setegid() functions are BSD4.4 extensions to the
- POSIX model. Mike Long <mike.long@analog.com>, 8/94.
-*/
-#ifdef BSD44
-#define SETEUID
-#endif /* BSD44 */
-
-/*
- The following construction automatically defines the symbol SETREUID for
- UNIX versions based on Berkeley Unix 4.2 and 4.3. If this symbol is
- defined, then this program will use getreuid() and getregid() calls in
- preference to getuid() and getgid(), which in Berkeley-based Unixes do
- not allow arbitrary switching back and forth of real & effective uid.
- This construction also allows -DSETREUID to be put on the cc command line
- for any system that has and wants to use setre[ug]id(). It also prevents
- automatic definition of SETREUID if -DNOSETREU is included on the cc
- command line (or otherwise defined).
-*/
-#ifdef FT18 /* None of this for Fortune. */
-#define NOSETREU
-#endif /* FT18 */
-
-#ifdef ANYBSD
-#ifndef BSD29
-#ifndef BSD41
-#ifndef SETREUID
-#ifndef NOSETREU
-#ifndef SETEUID
-#define SETREUID
-#endif /* SETEUID */
-#endif /* NOSETREU */
-#endif /* SETREUID */
-#endif /* !BSD41 */
-#endif /* !BSD29 */
-#endif /* ANYBSD */
-
-/* Variables for user and group IDs. */
-
-static UID_T realuid = (UID_T) -1, privuid = (UID_T) -1;
-static GID_T realgid = (GID_T) -1, privgid = (GID_T) -1;
-
-
-/* P R I V _ I N I -- Initialize privileges package */
-
-/* Called as early as possible in a set-uid or set-gid program to store the
- * set-to uid and/or gid and step down to the users real uid and gid. The
- * stored id's can be temporarily restored (allowed in System V) during
- * operations that require the privilege. Most of the time, the program
- * should execute in unpriviliged state, to not impose any security threat.
- *
- * Note: Don't forget that access() always uses the real id:s to determine
- * file access, even with privileges restored.
- *
- * Returns an error mask, with error values or:ed together:
- * 1 if setuid() fails,
- * 2 if setgid() fails, and
- * 4 if the program is set-user-id to "root", which can't be handled.
- *
- * Only the return value 0 indicates real success. In case of failure,
- * those privileges that could be reduced have been, at least, but the
- * program should be aborted none-the-less.
- *
- * Also note that these functions do not expect the uid or gid to change
- * without their knowing. It may work if it is only done temporarily, but
- * you're on your own.
- */
-int
-priv_ini() {
- int err = 0;
-
-#ifndef HAVE_LOCKDEV
-
- /* Save real ID:s. */
- realuid = getuid();
- realgid = getgid();
-
- /* Save current effective ID:s, those set to at program exec. */
- privuid = geteuid();
- privgid = getegid();
-
- /* If running set-uid, go down to real uid, otherwise remember that
- * no privileged uid is available.
- *
- * Exceptions:
- *
- * 1) If the real uid is already "root" and the set-uid uid (the
- * initial effective uid) is not "root", then we would have trouble
- * if we went "down" to "root" here, and then temporarily back to the
- * set-uid uid (not "root") and then again tried to become "root". I
- * think the "saved set-uid" is lost when changing uid from effective
- * uid "root", which changes all uid, not only the effective uid. But
- * in this situation, we can simply go to "root" and stay there all
- * the time. That should give sufficient privilege (understatement!),
- * and give the right uids for subprocesses.
- *
- * 2) If the set-uid (the initial effective uid) is "root", and we
- * change uid to the real uid, we can't change it back to "root" when
- * we need the privilege, for the same reason as in 1). Thus, we can't
- * handle programs that are set-user-id to "root" at all. The program
- * should be stopped. Use some other uid. "root" is probably too
- * privileged for such things, anyway. (The uid is reverted to the
- * real uid until termination.)
- *
- * These two exceptions have the effect that the "root" uid will never
- * be one of the two uids that are being switched between, which also
- * means we don't have to check for such cases in the switching
- * functions.
- *
- * Note that exception 1) is handled by these routines (by constantly
- * running with uid "root", while exception 2) is a serious error, and
- * is not provided for at all in the switching functions.
- */
- if (realuid == privuid)
- privuid = (UID_T) -1; /* Not running set-user-id. */
-
- /* If running set-gid, go down to real gid, otherwise remember that
- * no privileged gid is available.
- *
- * There are no exception like there is for the user id, since there
- * is no group id that is privileged in the manner of uid "root".
- * There could be equivalent problems for group changing if the
- * program sometimes ran with uid "root" and sometimes not, but
- * that is already avoided as explained above.
- *
- * Thus we can expect always to be able to switch to the "saved set-
- * gid" when we want, and back to the real gid again. You may also
- * draw the conclusion that set-gid provides for fewer hassles than
- * set-uid.
- */
-
-#ifdef SUIDDEBUG
- fprintf(stderr,"UID_ROOT=%d\n",UID_ROOT);
- fprintf(stderr,"realuid=%d\n",realuid);
- fprintf(stderr,"privuid=%d\n",privuid);
-#endif /* SUIDDEBUG */
-
- if (realgid == privgid) /* If not running set-user-id, */
- privgid = (GID_T) -1; /* remember it this way. */
-
- err = priv_off(); /* Turn off setuid privilege. */
-
- if (privuid == UID_ROOT) /* If setuid to root, */
- err |= 4; /* return this error. */
-
- if (realuid == UID_ROOT) { /* If real id is root, */
- privuid = (UID_T) -1; /* stay root at all times. */
-#ifdef ATT7300
- /* If Kermit installed SUID uucp and user is running as root */
- err &= ~1; /* System V R0 does not save UID */
-#endif /* ATT7300 */
- }
-#endif /* HAVE_LOCKDEV */
- return(err);
-}
-
-
-/* Macros for hiding the differences in UID/GID setting between various Unix
- * systems. These macros should always be called with both the privileged ID
- * and the non-privileged ID. The one in the second argument, will become the
- * effective ID. The one in the first argument will be retained for later
- * retrieval.
- */
-#ifdef SETREUID
-#ifdef SAVEDUID
-/* On BSD systems with the saved-UID feature, we just juggle the effective
- * UID back and forth, and leave the real UID at its true value. The kernel
- * allows switching to both the current real UID, the effective UID, and the
- * UID which the program is set-UID to. The saved set-UID always holds the
- * privileged UID for us, and the real UID will always be the non-privileged,
- * and we can freely choose one of them for the effective UID at any time.
- */
-#define switchuid(hidden,active) setreuid( (UID_T) -1, active)
-#define switchgid(hidden,active) setregid( (GID_T) -1, active)
-
-#else /* SETREUID,!SAVEDUID */
-
-/* On systems with setreXid() but without the saved-UID feature, notably
- * BSD 4.2, we swap the real and effective UIDs each time. It's
- * the effective UID that we are interested in, but we have to retain the
- * unused UID somewhere to enable us to restore it later, and we do this
- * in the real UID. The kernel only allows switching to either the current
- * real or the effective UID, unless you're "root".
- */
-#define switchuid(hidden,active) setreuid(hidden,active)
-#define switchgid(hidden,active) setregid(hidden,active)
-#endif
-
-#else /* !SETREUID, !SAVEDUID */
-
-#ifdef SETEUID
-/*
- BSD 4.4 works similarly to System V and POSIX (see below), but uses
- seteXid() instead of setXid() to change effective IDs. In addition, the
- seteXid() functions work the same for "root" as for other users.
-*/
-#define switchuid(hidden,active) seteuid(active)
-#define switchgid(hidden,active) setegid(active)
-
-#else /* !SETEUID */
-
-/* On System V and POSIX, the only thing we can change is the effective UID
- * (unless the current effective UID is "root", but initsuid() avoids that for
- * us). The kernel allows switching to the current real UID or to the saved
- * set-UID. These are always set to the non-privileged UID and the privileged
- * UID, respectively, and we only change the effective UID. This breaks if
- * the current effective UID is "root", though, because for "root" setuid/gid
- * becomes more powerful, which is why initsuid() treats "root" specially.
- * Note: That special treatment maybe could be ignored for BSD? Note: For
- * systems that don't fit any of these four cases, we simply can't support
- * set-UID.
- */
-#define switchuid(hidden,active) setuid(active)
-#define switchgid(hidden,active) setgid(active)
-
-#endif /* SETEUID */
-#endif /* SETREUID */
-
-
-/* P R I V _ O N -- Turn on the setuid and/or setgid */
-
-/* Go to the privileged uid (gid) that the program is set-user-id
- * (set-group-id) to, unless the program is running unprivileged.
- * If setuid() fails, return value will be 1. If getuid() fails it
- * will be 2. Return immediately after first failure, and the function
- * tries to restore any partial work done. Returns 0 on success.
- * Group id is changed first, since it is less serious than user id.
- */
-int
-priv_on() {
-#ifndef HAVE_LOCKDEV
- if (privgid != (GID_T) -1)
- if (switchgid(realgid,privgid))
- return(2);
-
- if (privuid != (UID_T) -1)
- if (switchuid(realuid,privuid)) {
- if (privgid != (GID_T) -1)
- switchgid(privgid,realgid);
- return(1);
- }
-#endif /* HAVE_LOCKDEV */
- return(0);
-}
-
-/* P R I V _ O F F -- Turn on the real uid and gid */
-
-/* Return to the unprivileged uid (gid) after an temporary visit to
- * privileged status, unless the program is running without set-user-id
- * (set-group-id). Returns 1 for failure in setuid() and 2 for failure
- * in setgid() or:ed together. The functions tries to return both uid
- * and gid to unprivileged state, regardless of errors. Returns 0 on
- * success.
- */
-int
-priv_off() {
- int err = 0;
-#ifndef HAVE_LOCKDEV
- if (privuid != (UID_T) -1)
- if (switchuid(privuid,realuid))
- err |= 1;
-
- if (privgid != (GID_T) -1)
- if (switchgid(privgid,realgid))
- err |= 2;
-#endif /* HAVE_LOCKDEV */
- return(err);
-}
-
-/* Turn off privilege permanently. No going back. This is necessary before
- * a fork() on BSD43 machines that don't save the setUID or setGID, because
- * we swap the real and effective ids, and we don't want to let the forked
- * process swap them again and get the privilege back. It will work on other
- * machines too, such that you can rely on its effect always being the same,
- * for instance, even when you're in priv_on() state when this is called.
- * (Well, that part about "permanent" is on System V only true if you follow
- * this with a call to exec(), but that's what we want it for anyway.)
- * Added by Dean Long -- dlong@midgard.ucsc.edu
- */
-int
-priv_can() {
-#ifndef HAVE_LOCKDEV
-#ifdef SETREUID
- int err = 0;
- if (privuid != (UID_T) -1)
- if (setreuid(realuid,realuid))
- err |= 1;
-
- if (privgid != (GID_T) -1)
- if (setregid(realgid,realgid))
- err |= 2;
-
- return(err);
-
-#else
-#ifdef SETEUID
- int err = 0;
- if (privuid != (UID_T) -1)
- if (setuid(realuid)) {
- debug(F101,"setuid failed","",errno);
- err |= 1;
- debug(F101,"ruid","",getuid());
- debug(F101,"euid","",geteuid());
- }
- debug(F101,"setuid","",realuid);
- if (privgid != (GID_T) -1)
- if (setgid(realgid)) {
- debug(F101,"setgid failed","",errno);
- err |= 2;
- debug(F101,"rgid","",getgid());
- debug(F101,"egid","",getegid());
- }
- debug(F101,"setgid","",realgid);
- return(err);
-#else
- /* Easy way of using setuid()/setgid() instead of setreuid()/setregid().*/
- return(priv_off());
-#endif /* SETEUID */
-#endif /* SETREUID */
-#else
- return(0);
-#endif /* HAVE_LOCKDEV */
-}
-
-/* P R I V _ O P N -- For opening protected files or devices. */
-
-int
-priv_opn(name, modes) char *name; int modes; {
- int x;
- priv_on(); /* Turn privileges on */
- debug(F111,"priv_opn",name,modes);
- errno = 0;
- x = open(name, modes); /* Try to open the device */
- debug(F101,"priv_opn result","",x);
- debug(F101,"priv_opn errno","",errno);
- priv_off(); /* Turn privileges off */
- return(x); /* Return open's return code */
-}
-
-/* P R I V _ C H K -- Check privileges. */
-
-/* Try to turn them off. If turning them off did not succeed, cancel them */
-
-int
-priv_chk() {
- int x, y = 0;
- x = priv_off(); /* Turn off privs. */
- if (x != 0 || getuid() == privuid || geteuid() == privuid)
- y = priv_can();
- if (x != 0 || getgid() == privgid || getegid() == privgid)
- y = y | priv_can();
- return(y);
-}
-
-UID_T
-real_uid() {
- return(realuid);
-}
-
-VOID
-ttimoff() { /* Turn off any timer interrupts */
- /* int xx; */
-/*
- As of 5A(183), we set SIGALRM to SIG_IGN (to ignore alarms) rather than to
- SIG_DFL (to catch alarms, or if there is no handler, to exit). This is to
- cure (mask, really) a deeper problem with stray alarms that occurs on some
- systems, possibly having to do with sleep(), that caused core dumps. It
- should be OK to do this, because no code in this module uses nested alarms.
- (But we still have to watch out for SCRIPT and DIAL...)
-*/
- /* xx = */ alarm(0);
- /* debug(F101,"ttimoff alarm","",xx); */
- if (saval) { /* Restore any previous */
- signal(SIGALRM,saval); /* alarm handler. */
- /* debug(F101,"ttimoff alarm restoring saval","",saval); */
- saval = NULL;
- } else {
- signal(SIGALRM,SIG_IGN); /* Used to be SIG_DFL */
- /* debug(F100,"ttimoff alarm SIG_IGN","",0); */
- }
-}
-
-
-int
-tt_is_secure() { /* Tells whether the current connection is secure */
-
- if (ttyfd == -1)
- return(0);
-
- if (0
-#ifdef SSHBUILTIN
- || IS_SSH()
-#endif /* SSHBUILTIN */
-#ifdef CK_ENCRYPTION
- || ck_tn_encrypting() && ck_tn_decrypting()
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- || tls_active_flag || ssl_active_flag
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
-#ifdef CK_ENCRYPTION
- || ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_ENCRYPTION */
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
- )
- return(1);
- return(0);
-}
-
-#ifdef CK_REDIR
-
-/* External protocol handler parameters from ckuus3.c */
-extern int exp_handler, exp_stderr, exp_timo;
-
-#ifdef SELECT
-#ifdef NETPTY
-
-/* The right size is 24576 */
-
-#ifndef PTY_PBUF_SIZE /* Size of buffer to read from pty */
-#define PTY_PBUF_SIZE 24576 /* and write to net. */
-#endif /* PTY_PBUF_SIZE */
-
-#ifndef PTY_TBUF_SIZE /* Size of buffer to read from net */
-#define PTY_TBUF_SIZE 24576 /* and write to pty. */
-#endif /* PTY_TBUF_SIZE */
-
-#ifdef O_NDELAY /* Whether to use nonblocking */
-#ifndef PTY_NO_NDELAY /* reads on the pseudoterminal */
-#ifndef PTY_USE_NDELAY
-#define PTY_USE_NDELAY
-#endif /* PTY_USE_NDELAY */
-#endif /* PTY_NO_NDELAY */
-#endif /* O_NDELAY */
-
-#ifndef HAVE_OPENPTY
-#ifndef USE_CKUPTY_C
-#define USE_CKUPTY_C
-#endif /* USE_CKUPTY_C */
-#endif /* HAVE_OPENPTY */
-
-#ifdef HAVE_OPENPTY
-#include <pty.h>
-#endif
-
-VOID
-pty_make_raw(fd) int fd; {
- int x = -23, i;
-
-#ifdef BSD44ORPOSIX /* POSIX */
- struct termios tp;
-#else
-#ifdef ATTSV /* AT&T UNIX */
-#ifdef CK_ANSIC
- struct termio tp = {0};
-#else
- struct termio tp;
-#endif /* CK_ANSIC */
-#else
- struct sgttyb tp; /* Traditional */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-
- debug(F101,"pty_make_raw fd","",fd);
- errno = 0;
-
-#ifdef BSD44ORPOSIX /* POSIX */
- x = tcgetattr(fd,&tp);
- debug(F101,"pty_make_raw tcgetattr","",x);
-#else
-#ifdef ATTSV /* AT&T UNIX */
- x = ioctl(fd,TCGETA,&tp);
- debug(F101,"pty_make_raw TCGETA ioctl","",x);
-#else
- x = gtty(fd,&tp);
- debug(F101,"pty_make_raw ttty","",x);
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
- debug(F101,"pty_make_raw GET errno","",errno);
-
-#ifdef USE_CFMAKERAW
- errno = 0;
- cfmakeraw(&tp);
- debug(F101,"pty_make_raw cfmakeraw errno","",errno);
-#else /* USE_CFMAKERAW */
-
-#ifdef COMMENT
-
-/* This very simple version recommended by Serg Iakolev doesn't work */
-
- tp.c_lflag &= ~(ECHO|ICANON|IEXTEN|ISIG);
- tp.c_iflag &= ~(BRKINT|ICRNL|INPCK|ISTRIP|IXON);
- tp.c_cflag &= ~(CSIZE|PARENB);
- tp.c_cflag |= CS8;
- tp.c_oflag &= ~(OPOST);
- tp.c_cc[VMIN] = 1;
- tp.c_cc[VTIME] = 0;
-
- debug(F101,"pty_make_raw 1 c_cc[] NCCS","",NCCS);
- debug(F101,"pty_make_raw 1 iflags","",tp.c_iflag);
- debug(F101,"pty_make_raw 1 oflags","",tp.c_oflag);
- debug(F101,"pty_make_raw 1 lflags","",tp.c_lflag);
- debug(F101,"pty_make_raw 1 cflags","",tp.c_cflag);
-
-#else
-#ifdef COMMENT
-/*
- In this version we unset everything and then set only the
- bits we know we need.
-*/
- /* iflags */
- tp.c_iflag = 0L;
- tp.c_iflag |= IGNBRK;
-#ifdef IMAXBEL
- tp.c_iflag |= IMAXBEL;
-#endif /* IMAXBEL */
-
- /* oflags */
- tp.c_oflag = 0L;
-
- /* lflags */
- tp.c_lflag = 0L;
-#ifdef NOKERNINFO
- tp.c_lflag |= NOKERNINFO;
-#endif /* NOKERNINFO */
-
- /* cflags */
- tp.c_cflag = 0L;
- tp.c_cflag |= CS8|CREAD;
-
- for (i = 0; i < NCCS; i++) { /* No special characters */
- tp.c_cc[i] = 0;
- }
-#ifdef VMIN
- tp.c_cc[VMIN] = 1; /* But always wait for input */
-#endif /* VMIN */
- debug(F101,"pty_make_raw 2 c_cc[] NCCS","",NCCS);
- debug(F101,"pty_make_raw 2 iflags","",tp.c_iflag);
- debug(F101,"pty_make_raw 2 oflags","",tp.c_oflag);
- debug(F101,"pty_make_raw 2 lflags","",tp.c_lflag);
- debug(F101,"pty_make_raw 2 cflags","",tp.c_cflag);
-
-#else /* COMMENT */
-/*
- In this version we set or unset every single flag explicitly. It works a
- bit better than the simple version just above, but it's still far from
- adequate.
-*/
- /* iflags */
- tp.c_iflag &= ~(PARMRK|ISTRIP|BRKINT|INLCR|IGNCR|ICRNL);
- tp.c_iflag &= ~(INPCK|IGNPAR|IXANY|IXON|IXOFF);
- tp.c_iflag |= IGNBRK;
-#ifdef IMAXBEL
-#ifdef COMMENT
- tp.c_iflag |= IMAXBEL;
-#else
- tp.c_iflag &= ~IMAXBEL;
-#endif /* COMMENT */
-#endif /* IMAXBEL */
-#ifdef IUCLC
- tp.c_iflag &= ~IUCLC;
-#endif /* IUCLC */
-
- /* oflags */
-#ifdef BSDLY
- tp.c_oflag &= ~BSDLY;
-#endif /* BSDLY */
-#ifdef CRDLY
- tp.c_oflag &= ~CRDLY;
-#endif /* CRDLY */
-#ifdef FFDLY
- tp.c_oflag &= ~FFDLY;
-#endif /* FFDLY */
-#ifdef NLDLY
- tp.c_oflag &= ~NLDLY;
-#endif /* NLDLY */
-#ifdef TABDLY
- tp.c_oflag &= ~TABDLY;
-#endif /* TABDLY */
-#ifdef VTDLY
- tp.c_oflag &= ~VTDLY;
-#endif /* VTDLY */
-#ifdef OFDEL
- tp.c_oflag &= ~OFDEL;
-#endif /* OFDEL */
-#ifdef OFILL
- tp.c_oflag &= ~OFILL;
-#endif /* OFILL */
-#ifdef OLCUC
- tp.c_oflag &= ~OLCUC;
-#endif /* OLCUC */
-#ifdef CMSPAR
- tp.c_oflag &= ~CMSPAR;
-#endif /* CMSPAR */
- tp.c_oflag &= ~OPOST;
-#ifdef OXTABS
- tp.c_oflag &= ~OXTABS;
-#endif /* OXTABS */
-#ifdef COMMENT
-#ifdef ONOCR
- tp.c_oflag &= ~ONOCR; /* Maybe should be |=? */
- tp.c_oflag |= ONOCR; /* makes no difference either way */
-#endif /* ONOCR */
-#endif /* COMMENT */
-#ifdef ONOEOT
- tp.c_oflag &= ~ONOEOT;
-#endif /* ONOEOT */
-#ifdef ONLRET
- tp.c_oflag &= ~ONLRET;
-#endif /* ONLRET */
-#ifdef ONLCR
- tp.c_oflag &= ~ONLCR;
-#endif /* ONLCR */
-#ifdef OCRNL
- tp.c_oflag &= ~OCRNL;
-#endif /* OCRNL */
-
- /* lflags */
- tp.c_lflag &= ~ECHO;
-#ifdef ECHOE
- tp.c_lflag &= ~ECHOE;
-#endif /* ECHOE */
-#ifdef ECHONL
- tp.c_lflag &= ~ECHONL;
-#endif /* ECHONL */
-#ifdef ECHOPRT
- tp.c_lflag &= ~ECHOPRT;
-#endif /* ECHOPRT */
-#ifdef ECHOKE
- tp.c_lflag &= ~ECHOKE;
-#endif /* ECHOKE */
-#ifdef ECHOCTL
- tp.c_lflag &= ~ECHOCTL;
-#endif /* ECHOCTL */
-#ifdef XCASE
- tp.c_lflag &= ~XCASE;
-#endif /* XCASE */
-#ifdef ALTWERASE
- tp.c_lflag &= ~ALTWERASE;
-#endif /* ALTWERASE */
-#ifdef EXTPROC
- tp.c_lflag &= ~(ICANON|ISIG|IEXTEN|TOSTOP|FLUSHO|PENDIN|EXTPROC);
-#else
- tp.c_lflag &= ~(ICANON|ISIG|IEXTEN|TOSTOP|FLUSHO|PENDIN);
-#endif /* EXTPROC */
-#ifdef NOKERNINFO
- tp.c_lflag |= NOKERNINFO;
-#endif /* NOKERNINFO */
-#ifndef COMMENT
- tp.c_lflag &= ~NOFLSH; /* TRY IT THE OTHER WAY? */
-#else
- tp.c_lflag |= NOFLSH; /* No, this way is worse */
-#endif /* COMMENT */
-
- /* cflags */
- tp.c_cflag &= ~(CSIZE|PARENB|PARODD);
- tp.c_cflag |= CS8|CREAD;
-
-#ifdef MDMBUF
- tp.c_cflag &= ~(MDMBUF);
-#else
-#ifdef CCAR_OFLOW
- tp.c_cflag &= ~(CCAR_OFLOW); /* two names for the same thing */
-#endif /* CCAR_OFLOW */
-#endif /* MDMBUF */
-
-#ifdef CCTS_OFLOW
- tp.c_cflag &= ~(CCTS_OFLOW);
-#endif /* CCTS_OFLOW */
-#ifdef CDSR_OFLOW
- tp.c_cflag &= ~(CDSR_OFLOW);
-#endif /* CDSR_OFLOW */
-#ifdef CDTR_IFLOW
- tp.c_cflag &= ~(CDTR_IFLOW);
-#endif /* CDTR_IFLOW */
-#ifdef CRTS_IFLOW
- tp.c_cflag &= ~(CRTS_IFLOW);
-#endif /* CRTS_IFLOW */
-#ifdef CRTSXOFF
- tp.c_cflag &= ~(CRTSXOFF);
-#endif /* CRTSXOFF */
-#ifdef CRTSCTS
- tp.c_cflag &= ~(CRTSCTS);
-#endif /* CRTSCTS */
-#ifdef CLOCAL
- tp.c_cflag &= ~(CLOCAL);
-#endif /* CLOCAL */
-#ifdef CSTOPB
- tp.c_cflag &= ~(CSTOPB);
-#endif /* CSTOPB */
-#ifdef HUPCL
- tp.c_cflag &= ~(HUPCL);
-#endif /* HUPCL */
-
- for (i = 0; i < NCCS; i++) { /* No special characters */
- tp.c_cc[i] = 0;
- }
-#ifdef VMIN
- tp.c_cc[VMIN] = 1; /* But always wait for input */
-#endif /* VMIN */
- debug(F101,"pty_make_raw 3 c_cc[] NCCS","",NCCS);
- debug(F101,"pty_make_raw 3 iflags","",tp.c_iflag);
- debug(F101,"pty_make_raw 3 oflags","",tp.c_oflag);
- debug(F101,"pty_make_raw 3 lflags","",tp.c_lflag);
- debug(F101,"pty_make_raw 3 cflags","",tp.c_cflag);
-#endif /* COMMENT */
-#endif /* COMMENT */
-
- errno = 0;
-#ifdef BSD44ORPOSIX /* POSIX */
- x = tcsetattr(fd,TCSANOW,&tp);
- debug(F101,"pty_make_raw tcsetattr","",x);
-#else
-#ifdef ATTSV /* AT&T UNIX */
- x = ioctl(fd,TCSETA,&tp);
- debug(F101,"pty_make_raw ioctl","",x);
-#else
- x = stty(fd,&tp); /* Traditional */
- debug(F101,"pty_make_raw stty","",x);
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
- debug(F101,"pty_make_raw errno","",errno);
-
-#endif /* __NetBSD__ */
-}
-
-static int
-pty_chk(fd) int fd; {
- int x, n = 0;
- errno = 0;
-#ifdef FIONREAD
- x = ioctl(fd, FIONREAD, &n); /* BSD and most others */
- ckmakmsg(msgbuf,500,
- "pty_chk ioctl FIONREAD errno=",
- ckitoa(errno),
- " count=",
- ckitoa(n));
- debug(F100,msgbuf,"",0);
-#else
-#ifdef RDCHK
- n = rdchk(fd);
- debug(F101,"pty_chk rdchk","",n);
-#else
- n = 1;
-#endif /* RDCHK */
-#endif /* FIONREAD */
- return((n > -1) ? n : 0);
-}
-
-static int
-pty_get_status(fd,pid) int fd; PID_T pid; {
- int x, status = -1;
- PID_T w;
-
- debug(F101,"pty_get_status fd","",fd);
- debug(F101,"pty_get_status pid","",pid);
-
- if (pexitstat > -1)
- return(pexitstat);
-
-#ifdef COMMENT
- /* Not only unnecessary but harmful */
- errno = 0;
- x = kill(pty_fork_pid,0);
- debug(F101,"pty_get_status kill value","",x);
- debug(F101,"pty_get_status kill errno","",errno);
- if (x > -1 && errno != ESRCH)
- return(-1); /* Fork still there */
- /* Fork seems to be gone */
-#endif /* COMMENT */
-
- errno = 0;
- x = waitpid(pty_fork_pid,&status,WNOHANG);
- debug(F111,"pty_get_status waitpid",ckitoa(errno),x);
- if (x <= 0 && errno == 0) {
- debug(F101,"pty_get_status waitpid return","",-1);
- return(-1);
- }
- if (x > 0) {
- if (x != pty_fork_pid)
- debug(F101,
- "pty_get_status waitpid pid doesn't match","",pty_fork_pid);
- debug(F101,"pty_get_status waitpid status","",status);
- debug(F101,"pty_get_status waitpid errno","",errno);
- if (WIFEXITED(status)) {
- debug(F100,"pty_get_status WIFEXITED","",0);
- status = WEXITSTATUS(status);
- debug(F101,"pty_get_status fork exit status","",status);
-#ifdef COMMENT
- end_pty();
-#endif /* COMMENT */
- close(fd);
- pexitstat = status;
- } else {
- debug(F100,"pty_get_status waitpid unexpected status","",0);
- }
- }
- debug(F101,"pty_get_status return status","",status);
- return(status);
-}
-
-/* t t p t y c m d -- Run command on pty and forward to net */
-
-/*
- Needed for running external protocols on secure connections.
- For example, if C-Kermit has made an SSL/TLS or Kerberos Telnet
- connection, and then needs to transfer a file with Zmodem, which is
- an external program, this routine reads Zmodem's output, encrypts it,
- and then forwards it out the connection, and reads the encrypted data
- stream coming in from the connection, decrypts it, and forwards it to
- Zmodem.
-
- Works like a TCP/IP port forwarder except one end is a pty rather
- than a socket, which introduces some complications:
-
- . On most platforms, select() always indicates the output side of
- the pty has characters waiting to be read, even when it doesn't,
- even when the pty process has already exited.
-
- . Nonblocking reads must be used on the pty, because there is no
- way on certain platforms (e.g. NetBSD) to find out how many characters
- are available to be read (the FIONREAD ioctl always says 0). The code
- also allows for blocking reads (if O_NDELAY and O_NONBLOCK are not
- defined, or if PTY_NO_NDELAY is defined), but on some platforms this can
- result in single-byte reads and writes (NetBSD again).
-
- . Testing for "EOF" on the pty is problematic. select() never gives
- any indication. After the pty process has exited and the fork has
- disappeared, read() can still return with 0 bytes read but without an
- error (NetBSD); no known test on the pty file descriptor will indicate
- that it is no longer valid. The process ID of the pty fork can be
- tested on some platforms (NetBSD, luckily) but not others (Solaris,
- Linux).
-
- On the network side, we use ttinc() and ttoc(), which, for network
- connections, handle any active security methods.
-
- Call with s = command.
- Returns 0 on failure, 1 on success.
- fdc - December 2006 - August 2007.
-
- NOTE: This code defaults to nonblocking reads if O_NDELAY or O_NONBLOCK are
- defined in the header files, which should be true of every recent Unix
- platform. If this causes trouble somewhere, define PTY_NO_NDELAY, e.g. when
- building C-Kermit:
-
- touch ckutio.c
- make platformname KFLAGS=-DPTY_NO_NODELAY
-*/
-static int have_pty = 0; /* Do we have a pty? */
-
-static SIGTYP (*save_sigchld)() = NULL; /* For catching SIGCHLD */
-
-static VOID
-sigchld_handler(sig) int sig; {
- have_pty = 0; /* We don't have a pty */
-#ifdef DEBUG
- if (save_sigchld) {
- (VOID) signal(SIGCHLD,save_sigchld);
- save_sigchld = NULL;
- }
- if (deblog) {
- debug(F100,"**************","",0);
- debug(F100,"SIGCHLD caught","",0);
- debug(F100,"**************","",0);
- }
-#endif /* DEBUG */
-}
-#define HAVE_IAC 1
-#define HAVE_CR 2
-
-int
-ttptycmd(s) char *s; {
- CHAR tbuf[PTY_TBUF_SIZE]; /* Read from net, write to pty */
- int tbuf_avail = 0; /* Pointers for tbuf */
- int tbuf_written = 0;
- static int in_state = 0; /* For TELNET IAC and NVT in */
- static int out_prev = 0; /* Simpler scheme for out */
-
- CHAR pbuf[PTY_PBUF_SIZE]; /* Read from pty, write to net */
- CHAR dbuf[PTY_PBUF_SIZE + PTY_PBUF_SIZE + 1]; /* Double-size buffer */
- int pbuf_avail = 0; /* Pointers for pbuf */
- int pbuf_written = 0;
-
- int ptyfd = -1; /* Pty file descriptor */
- int have_net = 0; /* We have a network connection */
- int pty_err = 0; /* Got error on pty */
- int net_err = 0; /* Got error on net */
- int status = -1; /* Pty process exit status */
- int rc = 0; /* Our return code */
-
- int x1 = 0, x2 = 0; /* Workers... */
- int c, n, m, t, x; /* Workers */
-
- long seconds_to_wait = 0L; /* select() timeout */
- struct timeval tv, *tv2; /* For select() */
-#ifdef INTSELECT
- int in, out, err; /* For select() */
-#else
- fd_set in, out, err;
-#endif /* INTSELECT */
- int nfds = 0; /* For select() */
-
- int pset = 0, tset = 0, pnotset = 0, tnotset = 0; /* stats/debuggin only */
- int read_net_bytes = 0; /* Stats */
- int write_net_bytes = 0; /* Stats */
- int read_pty_bytes = 0; /* Stats */
- int write_pty_bytes = 0; /* Stats */
- int is_tn = 0; /* TELNET protocol is active */
-
- int masterfd = -1;
- int slavefd = -1;
-#ifndef USE_CKUPTY_C
- struct termios term;
- struct winsize twin;
- struct stringarray * q;
- char ** args = NULL;
-#endif /* USE_CKUPTY_C */
-
- in_state = 0; /* No previous character yet */
-
- if (ttyfd == -1) {
- printf("?Sorry, communication channel is not open\n");
- return(0);
- } else {
- have_net = 1;
- }
- if (nopush) {
- debug(F100,"ttptycmd fail: nopush","",0);
- return(0);
- }
- if (!s) s = ""; /* Defense de bogus arguments */
- if (!*s) return(0);
- pexitstat = -1; /* Fork process exit status */
-
-#ifdef TNCODE
- is_tn = (xlocal && netconn && IS_TELNET()) || /* Telnet protocol active */
- (!xlocal && sstelnet);
-#endif /* TNCODE */
-
- debug(F110,"ttptycmd command",s,0);
- debug(F101,"ttptycmd ttyfd","",ttyfd);
- debug(F101,"ttptycmd is_tn","",is_tn);
- debug(F101,"ttptycmd ckermit pid","",getpid());
-
-#ifdef USE_CKUPTY_C
- /* Call ckupty.c module to get and set up the pty fork */
- /* fc 1 == "run an external protocol" */
- debug(F100,"ttptycmd using ckupty.c","",0);
- if (do_pty(&ptyfd,s,1) < 0) { /* Start the command on a pty */
- debug(F100,"ttptycmd do_pty fails","",0);
- return(0);
- }
- masterfd = ptyfd;
- pty_master_fd = ptyfd;
-#ifdef COMMENT
- slavefd = pty_slave_fd; /* This is not visible to us */
-#endif /* COMMENT */
- debug(F111,"ttptycmd ptyfd","USE_CKUPTY_C",ptyfd);
- debug(F111,"ttptycmd masterfd","USE_CKUPTY_C",masterfd);
- debug(F111,"ttptycmd fork pid","USE_CKUPTY_C",pty_fork_pid);
-#ifndef SOLARIS
- /* "ioctl inappropriate on device" for pty master */
- pty_make_raw(masterfd);
-#endif /* SOLARIS */
-
-#else /* USE_CKUPTY_C */
-
- debug(F100,"ttptycmd OPENPTY","",0);
- if (tcgetattr(0, &term) == -1) { /* Get controlling terminal's modes */
- perror("tcgetattr");
- return(0);
- }
- if (ioctl(0, TIOCGWINSZ, (char *) &twin) == -1) { /* and window size */
- perror("ioctl TIOCGWINSZ");
- return(0);
- }
- if (openpty(&masterfd, &slavefd, NULL, NULL, NULL) == -1) {
- debug(F101,"ttptycmd openpty failed errno","",errno);
- perror("opentpy");
- return(0);
- }
- debug(F101,"ttptycmd openpty masterfd","",masterfd);
- debug(F101,"ttptycmd openpty slavefd","",slavefd);
- pty_master_fd = masterfd;
- pty_slave_fd = slavefd;
- debug(F101,"ttptycmd openpty pty_master_fd","",pty_master_fd);
-
- /* Put pty master in raw mode but let forked app control the slave */
- pty_make_raw(masterfd);
-
-#ifdef COMMENT
-#ifdef TIOCREMOTE
- /* TIOCREMOTE,0 = disable all termio processing */
- x = ioctl(masterfd, TIOCREMOTE, 1);
- debug(F111,"ttptycmd ioctl TIOCREMOTE",ckitoa(x),errno);
-#endif /* TIOCREMOTE */
-#ifdef TIOCTTY
- /* TIOCTTY,0 = disable all termio processing */
- x = ioctl(masterfd, TIOCTTY, 0);
- debug(F111,"ttptycmd ioctl TIOCTTY",ckitoa(x),errno);
-#endif /* TIOCTTY */
-#endif /* COMMENT */
-
- have_pty = 1; /* We have an open pty */
- save_sigchld = signal(SIGCHLD, sigchld_handler); /* Catch fork quit */
-
- pty_fork_pid = fork(); /* Make fork for external protocol */
- debug(F101,"ttptycmd pty_fork_pid","",pty_fork_pid);
- if (pty_fork_pid == -1) {
- perror("fork");
- return(0);
- } else if (pty_fork_pid == 0) { /* In new fork */
- int x;
- debug(F101,"ttptycmd new fork pid","",getpid());
- close(masterfd); /* Slave quarters no masters allowed */
- x = setsid();
- debug(F101,"ttptycmd new fork setsid","",x);
- if (x == -1) {
- perror("ttptycmd setsid");
- exit(1);
- }
- signal(SIGINT,SIG_IGN); /* Let upper fork catch this */
-
-#ifdef COMMENT
-#ifdef TIOCSCTTY
- /* Make pty the controlling terminal for the process */
- /* THIS CAUSES AN INFINITE SIGWINCH INTERRUPT LOOP */
- x = ioctl(slavefd, TIOCSCTTY, NULL);
- debug(F101,"ttptycmd TIOCSCTTY","",x);
-#endif /* TIOCSCTTY */
-#endif /* COMMENT */
-
- /* Initialize slave pty modes and size to those of our terminal */
- if (tcsetattr(slavefd, TCSANOW, &term) == -1) {
- perror("ttptycmd tcsetattr");
- exit(1);
- }
- if (ioctl(slavefd, TIOCSWINSZ, &twin) == -1) {
- perror("ttptycmd ioctl");
- exit(1);
- }
-#ifdef COMMENT
-#ifdef TIOCNOTTY
- /* Disassociate this process from its terminal */
- /* THIS HAS NO EFFECT */
- x = ioctl(slavefd, TIOCNOTTY, NULL);
- debug(F101,"ttptycmd TIOCNOTTY","",x);
-#endif /* TIOCNOTTY */
-#endif /* COMMENT */
-
-#ifdef COMMENT
-#ifdef SIGTTOU
- /* Ignore terminal output interrupts */
- /* THIS HAS NO EFFECT */
- debug(F100,"ttptycmd ignoring SIGTTOU","",0);
- signal(SIGTTOU, SIG_IGN);
-#endif /* SIGTTOU */
-#ifdef SIGTSTP
- /* Ignore terminal output interrupts */
- /* THIS HAS NO EFFECT */
- debug(F100,"ttptycmd ignoring SIGTSTP","",0);
- signal(SIGTSTP, SIG_IGN);
-#endif /* SIGTSTP */
-#endif /* COMMENT */
-
- pty_make_raw(slavefd); /* Put it in rawmode */
-
- errno = 0;
- if (dup2(slavefd, STDIN_FILENO) != STDIN_FILENO ||
- dup2(slavefd, STDOUT_FILENO) != STDOUT_FILENO) {
- debug(F101,"ttptycmd new fork dup2 error","",errno);
- perror("ttptycmd dup2");
- exit(1);
- }
- debug(F100,"ttptycmd new fork dup2 ok","",0);
-
- /* Parse external protocol command line */
- q = cksplit(1,0,s,NULL,"\\%[]&$+-/=*^_@!{}/<>|.#~'`:;?",7,0,0);
- if (!q) {
- debug(F100,"ttptycmd cksplit failed","",0);
- exit(1);
- } else {
- int i, n;
- debug(F100,"ttptycmd cksplit ok","",0);
- n = q->a_size;
- args = q->a_head + 1;
- for (i = 0; i <= n; i++) {
- if (!args[i]) {
- break;
- } else {
- /* sometimes cksplit() doesn't terminate the list */
- if ((i == n) && args[i]) {
- if ((int)strlen(args[i]) == 0)
- makestr(&(args[i]),NULL);
- }
- }
- }
- }
-#ifdef COMMENT
-/*
- Putting the slave pty in rawmode should not be necessary because the
- external protocol program is supposed to do that itself. Yet doing this
- here cuts down on Zmodem binary-file transmission errors by 30-50% but
- still doesn't eliminate them.
-*/
- pty_make_raw(STDIN_FILENO);
- pty_make_raw(STDOUT_FILENO);
-#endif /* COMMENT */
-
- debug(F100,"ttptycmd execvp'ing external protocol","",0);
- execvp(args[0],args);
- perror("execvp failed");
- debug(F101,"ttptycmd execvp failed","",errno);
- close(slavefd);
- exit(1);
- }
- /* (there are better ways to do this...) */
- msleep(1000); /* Make parent wait for child to be ready */
- ptyfd = masterfd; /* We talk to the master */
-
-#endif /* USE_CKUPTY_C */
-
- debug(F101,"ttptycmd ptyfd","",ptyfd);
- if (ptyfd < 0) {
- printf("?Failure to get pty\n");
- return(-9);
- }
- have_pty = 1; /* We have an open pty or we wouldn't he here */
-
- debug(F101,"ttptycmd PTY_PBUF_SIZE","",PTY_PBUF_SIZE);
- debug(F101,"ttptycmd PTY_TBUF_SIZE","",PTY_TBUF_SIZE);
-
-#ifdef PTY_USE_NDELAY
- /*
- NOTE: If select() and ioctl(ptyfd,FIONREAD,&n) return true indications
- on the pty, we don't need nonblocking reads. Performance of either
- method seems to be about the same, so use whatever works.
- */
- errno = 0;
- x = fcntl(ptyfd,F_SETFL,fcntl(ptyfd,F_GETFL, 0)|O_NDELAY);
- ckmakmsg(msgbuf,500,
- "ttptycmd set O_NDELAY errno=",
- ckitoa(errno),
- " fcntl=",
- ckitoa(x));
- debug(F100,msgbuf,"",0);
-#endif /* PTY_USE_NDELAY */
-
-#ifdef COMMENT
-/* Not necessary, the protocol module already did this */
-
-#ifdef USE_CFMAKERAW
- if (tcgetattr(ttyfd, &term) > -1) {
- cfmakeraw(&term);
- debug(F101,"ttptycmd net cfmakeraw errno","",errno);
- x tcsetattr(ttyfd, TCSANOW, &term);
- debug(F101,"ttptycmd net tcsetattr","",x);
- debug(F101,"ttptycmd net tcsetattr","",errno);
- }
-#else
- if (local) /* Put network connection in */
- ttpkt(ttspeed,ttflow,ttprty); /* "packet mode". */
- else
- conbin((char)escchr); /* OR... pty_make_raw(0) */
-#endif /* USE_CFMAKERAW */
-#endif /* COMMENT */
-
-#ifdef TNCODE
- if (is_tn) {
- debug(F101,"<<< ttptycmd TELOPT_ME_BINARY","",TELOPT_ME(TELOPT_BINARY));
- debug(F101,"<<< ttptycmd TELOPT_U_BINARY","",TELOPT_U(TELOPT_BINARY));
- }
-#endif /* TNCODE */
-
- debug(F101,"ttptycmd entering loop - seconds_to_wait","",seconds_to_wait);
-
- while (have_pty || have_net) {
- FD_ZERO(&in); /* Initialize select() structs */
- FD_ZERO(&out);
- FD_ZERO(&err); /* (not used because useless) */
- nfds = -1;
-
- debug(F101,"ttptycmd loop top have_pty","",have_pty);
- debug(F101,"ttptycmd loop top have_net","",have_net);
-
- /* Pty is open and we have room to read from it? */
- if (have_pty && pbuf_avail < PTY_PBUF_SIZE) {
- debug(F100,"ttptycmd FD_SET ptyfd in","",0);
- FD_SET(ptyfd, &in);
- nfds = ptyfd;
- }
- /* Network is open and we have room to read from it? */
- if (have_net && have_pty && tbuf_avail < PTY_TBUF_SIZE) {
- debug(F100,"ttptycmd FD_SET ttyfd in","",0);
- FD_SET(ttyfd, &in);
- if (ttyfd > nfds) nfds = ttyfd;
- }
- /* Pty is open and we have stuff to write to it? */
- if (have_pty && tbuf_avail - tbuf_written > 0) {
- debug(F100,"ttptycmd FD_SET ptyfd out","",0);
- FD_SET (ptyfd, &out);
- if (ptyfd > nfds) nfds = ptyfd;
- }
- /* Net is open and we have stuff to write to it? */
- debug(F101,"ttptycmd pbuf_avail-pbuf_written","",
- pbuf_avail - pbuf_written);
- if (have_net && pbuf_avail - pbuf_written > 0) {
- debug(F100,"ttptycmd FD_SET ttyfd out","",0);
- FD_SET (ttyfd, &out);
- if (ttyfd > nfds) nfds = ttyfd;
- }
- /* We don't use err because it's not really for errors, */
- /* but for out of band data on the TCP socket, which, if it is */
- /* to be handled at all, is handled in the tt*() routines */
-
- nfds++; /* 0-based to 1-based */
- debug(F101,"ttptycmd nfds","",nfds);
- if (!nfds) {
- debug(F100,"ttptycmd NO FDs set for select","",0);
- if (have_pty) {
- /* This is not right -- sleeping won't accomplish anything */
- debug(F101,"ttptycmd msleep","",100);
- msleep(100);
- } else {
- debug(F100,"ttptycmd no pty - quitting loop","",0);
- break;
- }
- }
- errno = 0;
-
- if (seconds_to_wait > 0L) { /* Timeout in case nothing happens */
- tv.tv_sec = seconds_to_wait; /* for a long time */
- tv.tv_usec = 0L;
- tv2 = &tv;
- } else {
- tv2 = NULL;
- }
- x = select(nfds, &in, &out, NULL, tv2);
- debug(F101,"ttptycmd select","",x);
- if (x < 0) {
- if (errno == EINTR)
- continue;
- debug(F101,"ttptycmd select error","",errno);
- break;
- }
- if (x == 0) {
- debug(F101,"ttptycmd +++ select timeout","",seconds_to_wait);
- if (have_pty) {
- status = pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status A","",status);
- if (status > -1) pexitstat = status;
- have_pty = 0;
- }
- break;
- }
- /* We want to handle any pending writes first to make room */
- /* for new incoming. */
-
- if (FD_ISSET(ttyfd, &out)) { /* Can write to net? */
- CHAR * s;
- s = pbuf + pbuf_written; /* Current spot for sending */
-#ifdef TNCODE
- if (is_tn) { /* ttol() doesn't double IACs */
- CHAR c; /* Rewrite string with IACs doubled */
- int i;
- s = pbuf + pbuf_written; /* Source */
- x = 0; /* Count */
- for (i = 0; i < pbuf_avail - pbuf_written; i++) {
- c = s[i]; /* Next character */
- if (c == IAC) { /* If it's IAC */
- dbuf[x++] = c; /* put another one */
- debug(F000,">>> QUOTED IAC","",c);
- } else if (c != 0x0a && out_prev == 0x0d) { /* Bare CR */
- if (!TELOPT_ME(TELOPT_BINARY)) { /* NVT rule */
- c = 0x00;
- dbuf[x++] = c;
- debug(F000,">>> CR-NUL","",c);
- }
- }
- dbuf[x++] = c; /* Copy and count it */
- debug(F000,">>> char",ckitoa(in_state),c);
- out_prev = c;
- }
- s = dbuf; /* New source */
- } else
-#endif /* TNCODE */
- x = pbuf_avail - pbuf_written; /* How much to send */
-
- debug(F101,"ttptycmd bytes to send","",x);
- x = ttol(s, x);
- debug(F101,">>> ttol","",x);
- if (x < 0) {
- net_err++;
- debug(F111,"ttptycmd ttol error",ckitoa(x),errno);
- x = 0;
- }
- write_net_bytes += x;
- pbuf_written += x;
- }
- if (FD_ISSET(ptyfd, &out)) { /* Can write to pty? */
- debug(F100,"ttptycmd FD_ISSET ptyfd out","",0);
- errno = 0;
-#ifndef COMMENT
- x = write(ptyfd,tbuf + tbuf_written,tbuf_avail - tbuf_written);
-#else
- /* Byte loop to rule out data overruns in the pty */
- /* (it makes no difference) */
- {
- char *p = tbuf+tbuf_written;
- int n = tbuf_avail - tbuf_written;
- for (x = 0; x < n; x++) {
- msleep(10);
- if (write(ptyfd,&(p[x]),1) < 0)
- break;
- }
- }
-#endif /* COMMENT */
- debug(F111,"ttptycmd ptyfd write",ckitoa(errno),x);
- if (x > 0) {
- tbuf_written += x;
- write_pty_bytes += x;
- } else {
- x = 0;
- pty_err++;
- if (pexitstat < 0) {
- status = pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status B","",status);
- if (status > -1) pexitstat = status;
- have_pty = 0;
- }
- debug(F100,"ttptycmd +++ ptyfd write error","",0);
- }
- }
- if (FD_ISSET(ttyfd, &in)) { /* Can read from net? */
- tset++;
- debug(F100,"ttptycmd FD_ISSET ttyfd in","",0);
- n = in_chk(1,ttyfd);
- debug(F101,"ttptycmd in_chk(ttyfd)","",n);
- if (n < 0 || ttyfd == -1) {
- debug(F101,"ttptycmd +++ ttyfd errno","",errno);
- net_err++;
- } else if (n > 0) {
- if (n > PTY_TBUF_SIZE - tbuf_avail)
- n = PTY_TBUF_SIZE - tbuf_avail;
- debug(F101,"ttptycmd net read size adjusted","",n);
- if (xlocal && netconn) {
- /*
- We have to use a byte loop here because ttxin()
- does not decrypt or, for that matter, handle Telnet.
- */
- int c;
- CHAR * p;
- p = tbuf + tbuf_avail;
- for (x = 0; x < n; x++) {
- if ((c = ttinc(0)) < 0)
- break;
- if (!is_tn) { /* Not Telnet - keep all bytes */
- *p++ = (CHAR)c;
- debug(F000,"<<< char","",c);
-#ifdef TNCODE
- } else { /* Telnet - must handle IAC and NVT */
- debug(F000,"<<< char",ckitoa(in_state),c);
- switch (c) {
- case 0x00: /* NUL */
- if (in_state == HAVE_CR) {
- debug(F000,"<<< SKIP","",c);
- } else {
- *p++ = c;
- debug(F000,"<<< Keep","",c);
- }
- in_state = 0;
- break;
- case 0x0d: /* CR */
- if (!TELOPT_U(TELOPT_BINARY))
- in_state = HAVE_CR;
- *p++ = c;
- debug(F000,"<<< Keep","",c);
- break;
-#ifdef COMMENT
- case 0x0f: /* Ctrl-O */
- case 0x16: /* Ctrl-V */
- *p++ = 0x16;
- *p++ = c;
- debug(F000,"<<< QUOT","",c);
- break;
-#endif /* COMMENT */
- case 0xff: /* IAC */
- if (in_state == HAVE_IAC) {
- debug(F000,"<<< KEEP","",c);
- *p++ = c;
- in_state = 0;
- } else {
- debug(F000,"<<< SKIP","",c);
- in_state = HAVE_IAC;
- }
- break;
- default: /* All others */
- if (in_state == HAVE_IAC) {
-#ifdef COMMENT
-/*
- tn_doop() will consume an unknown number of bytes and we'll overshoot
- the for-loop. The only Telnet command I've ever seen arrive here is
- a Data Mark, which comes when the remote protocol exits and the remote
- job returns to its shell prompt. On the assumption it's a 1-byte command,
- we don't write out the IAC or the command, and we clear the state. If
- we called tn_doop() we'd have no way of knowing how many bytes it took
- from the input stream.
-*/
- int xx;
- xx = tn_doop((CHAR)c,duplex,ttinc);
- debug(F111,"<<< DOOP",ckctoa(c),xx);
-#else
- debug(F101,"<<< DOOP","",c);
-#endif /* COMMENT */
- in_state = 0;
- } else {
- *p++ = c;
- debug(F000,"<<< keep","",c);
- in_state = 0;
- }
- }
-#endif /* TNCODE */
- }
- }
- ckmakmsg(msgbuf,500,
- "ttptycmd read net [ttinc loop] errno=",
- ckitoa(errno),
- " count=",
- ckitoa(x));
- debug(F100,msgbuf,"",0);
- } else {
- x = ttxin(n,tbuf+tbuf_avail);
- debug(F101,"ttptycmd ttxin x","",x);
- }
-
- if (x < 0) {
- debug(F101,"ttptycmd read net error","",x);
- net_err++;
- }
- tbuf_avail += x;
- read_net_bytes += x;
- }
-
- } else
- tnotset++;
-
- if (FD_ISSET(ptyfd, &in)) { /* Read from pty? */
- pset++;
- debug(F100,"ttptycmd FD_ISSET ptyfd in","",0);
-#ifdef PTY_USE_NDELAY
- n = PTY_PBUF_SIZE;
-#else
- /*
- This does not work on nonblocking channels
- on certain platforms such as NetBSD.
- */
- n = pty_chk(ptyfd);
-#endif /* PTY_USE_NDELAY */
- debug(F101,"ttptycmd pty_chk() n","",n);
-
- if (n < 0)
- n = 0;
- if (n > 0) {
- if (n > PTY_PBUF_SIZE - pbuf_avail)
- n = PTY_PBUF_SIZE - pbuf_avail;
- debug(F101,"ttptycmd pty read size adjusted","",n);
- errno = 0;
- x = read(ptyfd,pbuf+pbuf_avail,n);
-#ifdef DEBUG
- if (deblog) {
- ckmakmsg(msgbuf,500,
- "ttptycmd read pty errno=",
- ckitoa(errno),
- " count=",
- ckitoa(x));
- debug(F100,msgbuf,"",0);
- }
-#endif /* DEBUG */
-
- if (x < 0 && errno == EAGAIN)
- x = 0;
-
- if (x < 0) { /* This works on Solaris and Linux */
- pty_err++; /* but not NetBSD */
- debug(F100,"TERMINATION TEST A","",0);
-#ifdef COMMENT
- if (errno == EIO)
- rc = 1;
-#endif /* COMMENT */
- if (pexitstat < 0) {
- status = pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status C","",status);
- if (status > -1) pexitstat = status;
- }
- have_pty = 0;
- x = 0;
- }
- if (x == 0 && !pty_err) { /* This works on NetBSD but */
- debug(F100,"TERMINATION TEST B","",0);
- status = pexitstat > -1 ? pexitstat :
- pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status D","",status);
- if (status > -1) {
- pexitstat = status;
- pty_err++;
- have_pty = 0;
- } else { /* Select() lied */
- pty_err = 0; /* pty still there but has nothing */
- msleep(100); /* sleep a bit */
- }
- x = 0;
- }
- /* Hopefully the next two are no longer needed... */
- if (!pty_err && (
-#ifndef PTY_USE_NDELAY
- x < 1 || errno
-#else
- errno != 0 && errno != EAGAIN
-#endif /* PTY_USE_NDELAY */
- )) {
- debug(F100,"TERMINATION TEST C","",0);
- pty_err++;
- debug(F101,"ttptycmd SET pty_err","",pty_err);
- if (errno == EIO) /* errno == EIO is like EOF */
- rc = 1;
- if (x < 0)
- x = 0;
- }
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- pbuf[pbuf_avail + x] = '\0';
- debug(F111,"ttptycmd added to pty buffer",
- pbuf+pbuf_avail,x);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- pbuf_avail += x;
- read_pty_bytes += x;
- } else { /* n == 0 with blocking reads */
- debug(F100,
- "PTY READ RETURNED ZERO BYTES - SHOULD NOT HAPPEN",
- "",0);
- }
- } else
- pnotset++;
-
- /* If writes have caught up to reads, reset the buffers */
-
- if (pbuf_written == pbuf_avail)
- pbuf_written = pbuf_avail = 0;
- if (tbuf_written == tbuf_avail)
- tbuf_written = tbuf_avail = 0;
-
- /* See if we can exit */
-
- x1 = pbuf_avail - pbuf_written;
- x2 = tbuf_avail - tbuf_written;
-
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST pty_err","",pty_err);
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST x1 [write to net]","",x1);
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST x2 [write to pty]","",x2);
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST rc","",rc);
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST status","",status);
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST pexitstat","",pexitstat);
-
- if (net_err) { /* Net error? */
- debug(F101,"ttptycmd net_err LOOP EXIT TEST net_err","",net_err);
- if (have_net) {
- if (local) {
- ttclos(0);
- printf("?Connection closed\n");
- }
- have_net = 0;
- }
- debug(F101,"ttptycmd net_err LOOP EXIT TEST x1","",x1);
- if (x1 == 0)
- break;
- }
- if (pty_err) { /* Pty error? */
- if (have_pty) {
- if (pexitstat < 0) {
- status = pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status E","",status);
- if (status > -1) pexitstat = status;
- }
- have_pty = 0;
- }
- if (x1 == 0 && x2 == 0) { /* If buffers are caught up */
- rc = 1; /* set preliminary return to success */
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST rc 2","",rc);
- break; /* and exit the loop */
- }
- }
- }
- debug(F101,"ttptycmd +++ have_pty","",have_pty);
- if (have_pty) { /* In case select() failed */
-#ifdef USE_CKUPTY_C
- end_pty();
- close(ptyfd);
-#else
- close(slavefd);
- close(masterfd);
-#endif /* USE_CKUPTY_C */
- }
- pty_master_fd = -1;
- debug(F101,"ttptycmd +++ pexitstat","",pexitstat);
- if (pexitstat < 0) { /* Try one last time to get status */
- status = pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status F","",status);
- if (status > -1) pexitstat = status;
- }
- debug(F101,"ttptycmd +++ final pexitstat","",pexitstat);
- if (deblog) { /* Stats for debug log */
- debug(F101,"ttptycmd +++ pset ","",pset);
- debug(F101,"ttptycmd +++ pnotset","",pnotset);
- debug(F101,"ttptycmd +++ tset ","",tset);
- debug(F101,"ttptycmd +++ tnotset","",tnotset);
-
- debug(F101,"ttptycmd +++ read_pty_bytes","",read_pty_bytes);
- debug(F101,"ttptycmd +++ write_net_bytes","",write_net_bytes);
- debug(F101,"ttptycmd +++ read_net_bytes","",read_net_bytes);
- debug(F101,"ttptycmd +++ write_pty_bytes","",write_pty_bytes);
- }
-/*
- If we got the external protocol's exit status from waitpid(), we use that
- to set our return code. If not, we fall back on whatever rc was previously
- set to, namely 1 (success) if the pty fork seemed to terminate, 0 otherwise.
-*/
- if (save_sigchld) { /* Restore this if we changed it */
- (VOID) signal(SIGCHLD,save_sigchld);
- save_sigchld = NULL;
- }
- msleep(500);
- x = kill(pty_fork_pid,SIGHUP); /* In case it's still there */
- pty_fork_pid = -1;
- debug(F101,"ttptycmd fork kill SIGHUP","",x);
- if (pexitstat > -1)
- rc = (pexitstat == 0 ? 1 : 0);
- debug(F101,"ttptycmd +++ rc","",rc);
- if (!local) { /* If in remote mode */
- conres(); /* restore console to CBREAK mode */
- concb((char)escchr);
- }
- return(rc);
-}
-#endif /* NETPTY */
-#endif /* SELECT */
-
-/* T T R U N C M D -- Redirect an external command over the connection. */
-
-/*
- TTRUNCMD is the routine that was originally used for running external
- protocols. It is very simple and works fine provided (a) the connection
- is not encrypted, and (b) the external protocol uses standard i/o
- (file descriptors 0 and 1) for file transfer.
-*/
-
-int
-ttruncmd(s) char *s; {
- PID_T pid; /* pid of lower fork */
- int wstat; /* for wait() */
- int x;
- int statusp;
-
- if (ttyfd == -1) {
- printf("?Sorry, device is not open\n");
- return(0);
- }
- if (nopush) {
- debug(F100,"ttruncmd fail: nopush","",0);
- return(0);
- }
-
-#ifdef NETPTY
-/***************
- It might also be necessary to use the pty routine for other reasons,
- e.g. because the external program does not use stdio.
-*/
-#ifdef NETCONN
-/*
- If we have a network connection we use a different routine because
- (a) if the connection is encrypted, the mechanism used here can't deal
- with it; and (b) it won't handle any network protocols either, e.g.
- Telnet, Rlogin, K5 U-to-U, etc. However, this routine works much
- better (faster, more transparent) on serial connections and when
- C-Kermit is in remote mode (i.e. is on the far end).
-*/
- /* For testing always use this */
- if (netconn)
- return(ttptycmd(s));
-#endif /* NETCONN */
-
-/***************/
-#else /* NETPTY */
- if (tt_is_secure()) {
- printf("?Sorry, \
-external protocols over secure connections not supported in this OS.\n"
- );
- return(0);
- }
-#endif /* NETPTY */
-
- conres(); /* Make console normal */
- pexitstat = -4;
- if ((pid = fork()) == 0) { /* Make a child fork */
- if (priv_can()) /* Child: turn off privs. */
- exit(1);
- dup2(ttyfd, 0); /* Give stdin/out to the line */
- dup2(ttyfd, 1);
- x = system(s);
- debug(F101,"ttruncmd system",s,x);
- _exit(x ? BAD_EXIT : 0);
- } else {
- SIGTYP (*istat)(), (*qstat)();
- if (pid == (PID_T) -1) /* fork() failed? */
- return(0);
- istat = signal(SIGINT,SIG_IGN); /* Let the fork handle keyboard */
- qstat = signal(SIGQUIT,SIG_IGN); /* interrupts itself... */
-
-#ifdef COMMENT
- while (((wstat = wait(&statusp)) != pid) && (wstat != -1)) ;
-#else /* Not COMMENT */
- while (1) {
- wstat = wait(&statusp);
- debug(F101,"ttruncmd wait","",wstat);
- if (wstat == pid || wstat == -1)
- break;
- }
-#endif /* COMMENT */
-
- pexitstat = (statusp & 0xff) ? statusp : statusp >> 8;
- debug(F101,"ttruncmd wait statusp","",statusp);
- debug(F101,"ttruncmd wait pexitstat","",pexitstat);
- signal(SIGINT,istat); /* Restore interrupts */
- signal(SIGQUIT,qstat);
- }
- concb((char)escchr); /* Restore console to CBREAK mode */
- return(statusp == 0 ? 1 : 0);
-}
-#endif /* CK_REDIR */
-
-struct tm *
-#ifdef CK_ANSIC
-cmdate2tm(char * date, int gmt) /* date as "yyyymmdd hh:mm:ss" */
-#else
-cmdate2tm(date,gmt) char * date; int gmt;
-#endif
-{
- /* date as "yyyymmdd hh:mm:ss" */
- static struct tm _tm;
- time_t now;
-
- if (strlen(date) != 17 ||
- date[8] != ' ' ||
- date[11] != ':' ||
- date[14] != ':')
- return(NULL);
-
- time(&now);
- if (gmt)
- _tm = *gmtime(&now);
- else
- _tm = *localtime(&now);
- _tm.tm_year = (date[0]-'0')*1000 + (date[1]-'0')*100 +
- (date[2]-'0')*10 + (date[3]-'0')-1900;
- _tm.tm_mon = (date[4]-'0')*10 + (date[5]-'0')-1;
- _tm.tm_mday = (date[6]-'0')*10 + (date[7]-'0');
- _tm.tm_hour = (date[9]-'0')*10 + (date[10]-'0');
- _tm.tm_min = (date[12]-'0')*10 + (date[13]-'0');
- _tm.tm_sec = (date[15]-'0')*10 + (date[16]-'0');
-
- /* Should we set _tm.tm_isdst to -1 here? */
-
- _tm.tm_wday = 0;
- _tm.tm_yday = 0;
-
- return(&_tm);
-}
-
-#ifdef OXOS
-#undef kill
-#endif /* OXOS */
-
-#ifdef OXOS
-int
-priv_kill(pid, sig) int pid, sig; {
- int i;
-
- if (priv_on())
- debug(F100,"priv_kill priv_on failed","",0);
- i = kill(pid, sig);
- if (priv_off())
- debug(F100,"priv_kill priv_off failed","",0);
- return(i);
-}
-#endif /* OXOS */
-
-#ifdef BEOSORBEBOX
-/* #ifdef BE_DR_7 */
-/*
- alarm() function not supplied with Be OS DR7 - this one contributed by
- Neal P. Murphy.
-*/
-
-/*
- This should mimic the UNIX/POSIX alarm() function well enough, with the
- caveat that one's SIGALRM handler must call alarm_expired() to clean up vars
- and wait for the alarm thread to finish.
-*/
-unsigned int
-alarm(unsigned int seconds) {
- long time_left = 0;
-
-/* If an alarm is active, turn it off, saving the unused time */
- if (alarm_thread != -1) {
- /* We'll be generous and count partial seconds as whole seconds. */
- time_left = alarm_struct.time -
- ((system_time() - time_started) / 1000000.0);
-
- /* Kill the alarm thread */
- kill_thread (alarm_thread);
-
- /* We need to clean up as though the alarm occured. */
- time_started = 0;
- alarm_struct.thread = -1;
- alarm_struct.time = 0;
- alarm_expired();
- }
-
-/* Set a new alarm clock, if requested. */
- if (seconds > 0) {
- alarm_struct.thread = find_thread(NULL);
- alarm_struct.time = seconds;
- time_started = system_time();
- alarm_thread = spawn_thread (do_alarm,
- "alarm_thread",
- B_NORMAL_PRIORITY,
- (void *) &alarm_struct
- );
- resume_thread (alarm_thread);
- }
-
-/* Now return [unused time | 0] */
- return ((unsigned int) time_left);
-}
-
-/*
- This function is the departure from UNIX/POSIX alarm handling. In the case
- of Be's missing alarm() function, this stuff needs to be done in the SIGALRM
- handler. When Be implements alarm(), this function call can be eliminated
- from user's SIGALRM signal handlers.
-*/
-
-void
-alarm_expired(void) {
- long ret_val;
-
- if (alarm_thread != -1) {
- wait_for_thread (alarm_thread, &ret_val);
- alarm_thread = -1;
- }
-}
-
-/*
- This is the function that snoozes the requisite number of seconds and then
- SIGALRMs the calling thread. Note that kill() wants a pid_t arg, whilst Be
- uses thread_id; currently they are both typdef'ed as long, but I'll do the
- cast anyway. This function is run in a separate thread.
-*/
-
-long
-do_alarm (void *alarm_struct) {
- snooze ((double) ((struct ALARM_STRUCT *) alarm_struct)->time * 1000000.0);
- kill ((pid_t)((struct ALARM_STRUCT *) alarm_struct)->thread, SIGALRM);
- time_started = 0;
- ((struct ALARM_STRUCT *) alarm_struct)->thread = -1;
- ((struct ALARM_STRUCT *) alarm_struct)->time = 0;
-}
-/* #endif */ /* BE_DR_7 */
-#endif /* BEOSORBEBOX */
-
-#ifdef Plan9
-
-int
-p9ttyctl(char letter, int num, int param) {
- char cmd[20];
- int len;
-
- if (ttyctlfd < 0)
- return -1;
-
- cmd[0] = letter;
- if (num)
- len = sprintf(cmd + 1, "%d", param) + 1;
- else {
- cmd[1] = param;
- len = 2;
- }
- if (write(ttyctlfd, cmd, len) == len) {
- cmd[len] = 0;
- /* fprintf(stdout, "wrote '%s'\n", cmd); */
- return 0;
- }
- return -1;
-}
-
-int
-p9ttyparity(char l) {
- return p9ttyctl('p', 0, l);
-}
-
-int
-p9tthflow(int flow, int status) {
- return p9ttyctl('m', 1, status);
-}
-
-int
-p9ttsspd(int cps) {
- if (p9ttyctl('b', 1, cps * 10) < 0)
- return -1;
- ttylastspeed = cps * 10;
- return 0;
-}
-
-int
-p9openttyctl(char *ttname) {
- char name[100];
-
- if (ttyctlfd >= 0) {
- close(ttyctlfd);
- ttyctlfd = -1;
- ttylastspeed = -1;
- }
- sprintf(name, "%sctl", ttname);
- ttyctlfd = open(name, 1);
- return ttyctlfd;
-}
-
-int
-p9concb() {
- if (consctlfd >= 0) {
- if (write(consctlfd, "rawon", 5) == 5)
- return 0;
- }
- return -1;
-}
-
-int
-p9conbin() {
- return p9concb();
-}
-
-int
-p9conres() {
- if (consctlfd >= 0) {
- if (write(consctlfd, "rawoff", 6) == 6)
- return 0;
- }
- return -1;
-}
-
-int
-p9sndbrk(int msec) {
- if (ttyctlfd >= 0) {
- char cmd[20];
- int i = sprintf(cmd, "k%d", msec);
- if (write(ttyctlfd, cmd, i) == i)
- return 0;
- }
- return -1;
-}
-
-int
-conwrite(char *buf, int n) {
- int x;
- static int length = 0;
- static int holdingcr = 0;
- int normal = 0;
- for (x = 0; x < n; x++) {
- char c = buf[x];
- if (c == 007) {
- if (normal) {
- write(1, buf + (x - normal), normal);
- length += normal;
- normal = 0;
- }
- /* write(noisefd, "1000 300", 8); */
- holdingcr = 0;
- } else if (c == '\r') {
- if (normal) {
- write(1, buf + (x - normal), normal);
- length += normal;
- normal = 0;
- }
- holdingcr = 1;
- } else if (c == '\n') {
- write(1, buf + (x - normal), normal + 1);
- normal = 0;
- length = 0;
- holdingcr = 0;
- } else if (c == '\b') {
- if (normal) {
- write(1, buf + (x - normal), normal);
- length += normal;
- normal = 0;
- }
- if (length) {
- write(1, &c, 1);
- length--;
- }
- holdingcr = 0;
- } else {
- if (holdingcr) {
- char b = '\b';
- while (length-- > 0)
- write(1, &b, 1);
- length = 0; /* compiler bug */
- }
- holdingcr = 0;
- normal++;
- }
- }
- if (normal) {
- write(1, buf + (x - normal), normal);
- length += normal;
- }
- return n;
-}
-
-void
-conprint(char *fmt, ...) {
- static char buf[1000]; /* not safe if on the stack */
-
- va_list ap;
- int i;
-
- va_start(ap, fmt);
- i = vsprintf(buf, fmt, ap);
- conwrite(buf, i);
-}
-#endif /* Plan9 */
-
-/* fprintf, printf, perror replacements... */
-
-/* f p r i n t f */
-
-#ifdef UNIX
-#ifdef CK_ANSIC
-#include <stdarg.h>
-#else /* CK_ANSIC */
-#ifdef __GNUC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif /* __GNUC__ */
-#endif /* CK_ANSIC */
-#ifdef fprintf
-#undef fprintf
-static char str1[4096];
-static char str2[4096];
-int
-#ifdef CK_ANSIC
-ckxfprintf(FILE * file, const char * format, ...)
-#else /* CK_ANSIC */
-ckxfprintf(va_alist) va_dcl
-#endif /* CK_ANSIC */
-/* ckxfprintf */ {
- int i, j, len, got_cr;
- va_list args;
- int rc = 0;
-
-#ifdef CK_ANSIC
- va_start(args, format);
-#else /* CK_ANSIC */
- char * format;
- FILE * file;
- va_start(args);
- file = va_arg(args,FILE *);
- format = va_arg(args,char *);
-#endif /* CK_ANSIC */
-
- if (!inserver || (file != stdout && file != stderr && file != stdin)) {
- rc = vfprintf(file,format,args);
- } else {
- unsigned int c;
- rc = vsprintf(str1, format, args);
- len = strlen(str1);
- if (len >= sizeof(str1)) {
- debug(F101,"ckxfprintf() buffer overflow","",len);
- doexit(BAD_EXIT,1);
- }
- for (i = 0, j = 0, got_cr = 0;
- i < len && j < sizeof(str1)-2;
- i++, j++ ) {
- /* We can't use 255 as a case label because of signed chars */
- c = (unsigned)(str1[i] & 0xff);
-#ifdef TNCODE
- if (c == 255) {
- if (got_cr && !TELOPT_ME(TELOPT_BINARY))
- str2[j++] = '\0';
- str2[j++] = IAC;
- str2[j] = IAC;
- got_cr = 0;
- } else
-#endif /* TNCODE */
- switch (c) {
- case '\r':
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
- str2[j] = str1[i];
- got_cr = 1;
- break;
- case '\n':
- if (!got_cr)
- str2[j++] = '\r';
- str2[j] = str1[i];
- got_cr = 0;
- break;
- default:
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
- str2[j] = str1[i];
- got_cr = 0;
- }
- }
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
-#ifdef CK_ENCRYPTION
-#ifdef TNCODE
- if (TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(str2,j);
-#endif /* TNCODE */
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if (inserver && (ssl_active_flag || tls_active_flag)) {
- /* Write using SSL */
- char * p = str2;
- ssl_retry:
- if (ssl_active_flag)
- rc = SSL_write(ssl_con, p, j);
- else
- rc = SSL_write(tls_con, p, j);
- debug(F111,"ckxfprintf","SSL_write",rc);
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,rc)) {
- case SSL_ERROR_NONE:
- if (rc == j)
- break;
- p += rc;
- j -= rc;
- goto ssl_retry;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
- if (rc != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- rc = 0;
- }
- } else
-#endif /* CK_SSL */
- fwrite(str2,sizeof(char),j,stdout);
- }
- va_end(args);
- return(rc);
-}
-#endif /* fprintf */
-
-/* p r i n t f */
-
-#ifdef printf
-#undef printf
-int
-#ifdef CK_ANSIC
-ckxprintf(const char * format, ...)
-#else /* CK_ANSIC */
-ckxprintf(va_alist) va_dcl
-#endif /* CK_ANSIC */
-/* ckxprintf */ {
- int i, j, len, got_cr;
- va_list args;
- int rc = 0;
-
-#ifdef CK_ANSIC
- va_start(args, format);
-#else /* CK_ANSIC */
- char * format;
- va_start(args);
- format = va_arg(args,char *);
-#endif /* CK_ANSIC */
-
- if (!inserver) {
- rc = vprintf(format, args);
- } else {
- unsigned int c;
- rc = vsprintf(str1, format, args);
- len = strlen(str1);
- if (len >= sizeof(str1)) {
- debug(F101,"ckxprintf() buffer overflow","",len);
- doexit(BAD_EXIT,1);
- }
- for (i = 0, j = 0, got_cr=0;
- i < len && j < sizeof(str1)-2;
- i++, j++ ) {
- c = (unsigned)(str1[i] & 0xff);
-#ifdef TNCODE
- if (c == 255) {
- if (got_cr && !TELOPT_ME(TELOPT_BINARY))
- str2[j++] = '\0';
- str2[j++] = IAC;
- str2[j] = IAC;
- got_cr = 0;
- } else
-#endif /* TNCODE */
- switch (c) {
- case '\r':
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
- str2[j] = str1[i];
- got_cr = 1;
- break;
- case '\n':
- if (!got_cr)
- str2[j++] = '\r';
- str2[j] = str1[i];
- got_cr = 0;
- break;
- default:
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
- str2[j] = str1[i];
- got_cr = 0;
- break;
- }
- }
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
-#ifdef CK_ENCRYPTION
-#ifdef TNCODE
- if (TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(str2,j);
-#endif /* TNCODE */
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if (inserver && (ssl_active_flag || tls_active_flag)) {
- char * p = str2;
- /* Write using SSL */
- ssl_retry:
- if (ssl_active_flag)
- rc = SSL_write(ssl_con, p, j);
- else
- rc = SSL_write(tls_con, p, j);
- debug(F111,"ckxprintf","SSL_write",rc);
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,rc)) {
- case SSL_ERROR_NONE:
- if (rc == j)
- break;
- p += rc;
- j -= rc;
- goto ssl_retry;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
- if (rc != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- rc = 0;
- }
- } else
-#endif /* CK_SSL */
- rc = fwrite(str2,sizeof(char),j,stdout);
- }
- va_end(args);
- return(rc);
-}
-#endif /* printf */
-
-/* p e r r o r */
-
-#ifdef perror
-#undef perror
-_PROTOTYP(char * ck_errstr,(VOID));
-#ifdef NEXT
-void
-#else
-#ifdef CK_SCOV5
-void
-#else
-int
-#endif /* CK_SCOV5 */
-#endif /* NEXT */
-#ifdef CK_ANSIC
-ckxperror(const char * str)
-#else /* CK_ANSIC */
-ckxperror(str) char * str;
-#endif /* CK_ANSIC */
-/* ckxperror */ {
- char * errstr = ck_errstr();
-#ifndef NEXT
-#ifndef CK_SCOV5
- return
-#endif /* CK_SCOV5 */
-#endif /* NEXT */
- ckxprintf("%s%s %s\n",str,*errstr?":":"",errstr);
-}
-#endif /* perror */
-#endif /* UNIX */
-
-#ifdef MINIX2
-
-/* Minix doesn't have a gettimeofday call (but MINIX3 does).
- * We fake one here using time(2)
- */
-
-#ifndef MINIX3
-int
-gettimeofday(struct timeval *tp, struct timezone *tzp) {
- tp->tv_usec = 0L; /* Close enough for horseshoes */
- if(time(&(tp->tv_sec))==-1)
- return(-1);
- return(0);
-}
-#endif /* MINIX3 */
-
-#ifndef MINIX3
-int
-readlink(const char *path, void *buf, size_t bufsiz) {
- errno = ENOSYS;
- return(-1);
-}
-#endif /* MINIX3 */
-
-#endif /* MINIX2 */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckutio.c.c99 b/ckermit-9.0.302-build/ckermit-9.0.302/ckutio.c.c99
deleted file mode 100644
index 05564de..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckutio.c.c99
+++ /dev/null
@@ -1,16050 +0,0 @@
-#define CKUTIO_C
-
-#ifdef aegis
-char *ckxv = "Aegis Communications support, 9.0.326, 20 August 2011";
-#else
-#ifdef Plan9
-char *ckxv = "Plan 9 Communications support, 9.0.326, 20 August 2011";
-#else
-char *ckxv = "UNIX Communications support, 9.0.326, 20 August 2011";
-#endif /* Plan9 */
-#endif /* aegis */
-
-/* C K U T I O */
-
-/* C-Kermit interrupt, communications control and I/O functions for UNIX */
-
-/*
- Author: Frank da Cruz (fdc@columbia.edu),
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- NOTE TO CONTRIBUTORS: This file, and all the other C-Kermit files, must be
- compatible with C preprocessors that support only #ifdef, #else, #endif,
- #define, and #undef. Please do not use #if, logical operators, or other
- preprocessor features in any of the portable C-Kermit modules. You can,
- of course, use these constructions in platform-specific modules when they
- are supported by all compilers/preprocessors that could be used on that
- platform.
-*/
-
-extern int nettype; /* Defined in ckcmai.c */
-extern int duplex;
-
-/* Includes */
-
-#include "ckcsym.h" /* This must go first */
-#include "ckcdeb.h" /* This must go second */
-
-#ifdef OSF13
-#ifdef CK_ANSIC
-#ifdef _NO_PROTO
-#undef _NO_PROTO
-#endif /* _NO_PROTO */
-#endif /* CK_ANSIC */
-#endif /* OSF13 */
-
-#ifndef HPUXPRE65
-#include <errno.h> /* Error number symbols */
-#else
-#ifndef ERRNO_INCLUDED
-#include <errno.h> /* Error number symbols */
-#endif /* ERRNO_INCLUDED */
-#endif /* HPUXPRE65 */
-
-#ifdef __386BSD__
-#define ENOTCONN 57
-#else
-#ifdef __bsdi__
-#define ENOTCONN 57
-#else
-#ifdef __FreeBSD__
-#define ENOTCONN 57
-#endif /* __FreeBSD__ */
-#endif /* __bsdi__ */
-#endif /* __386BSD__ */
-
-#ifdef SCO_OSR504
-#define NBBY 8
-#endif /* SCO_OSR504 */
-
-#ifdef Plan9
-#define SELECT
-#include <sys/time.h>
-#include <select.h>
-#define FD_SETSIZE (3 * sizeof(long) * 8)
-static struct timeval tv;
-#endif /* Plan9 */
-
-#ifdef CLIX
-#include <sys/time.h>
-#endif /* CLIX */
-
-#include "ckcnet.h" /* Symbols for network types. */
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-
-/*
- The directory-related includes are here because we need to test some
- file-system-related symbols to find out which system we're being compiled
- under. For example, MAXNAMLEN is defined in BSD4.2 but not 4.1.
-*/
-#ifdef SDIRENT /* Directory bits... */
-#define DIRENT
-#endif /* SDIRENT */
-
-#ifdef XNDIR
-#include <sys/ndir.h>
-#else /* !XNDIR */
-#ifdef NDIR
-#include <ndir.h>
-#else /* !NDIR, !XNDIR */
-#ifdef RTU
-#include "/usr/lib/ndir.h"
-#else /* !RTU, !NDIR, !XNDIR */
-#ifdef DIRENT
-#ifdef SDIRENT
-#include <sys/dirent.h>
-#else
-#include <dirent.h>
-#endif /* SDIRENT */
-#else /* !RTU, !NDIR, !XNDIR, !DIRENT, i.e. all others */
-#include <sys/dir.h>
-#endif /* DIRENT */
-#endif /* RTU */
-#endif /* NDIR */
-#endif /* XNDIR */
-
-#ifdef QNX
-#include <sys/dev.h>
-#endif /* QNX */
-
-#ifdef HPUX5
-#ifndef TCPSOCKET
-/* I don't know why this is needed here since we never reference bzero(). */
-/* But without it C-Kermit won't link in an HP-UX 5.xx non-TCP build. */
-void
-bzero(s,n) char *s; int n; {
- extern char * memset();
- memset(s,0,n);
-}
-#endif /* TCPSOCKET */
-#endif /* HPUX5 */
-
-/* Definition of HZ, used in msleep() */
-
-#ifdef MIPS
-#define HZ ( 1000 / CLOCK_TICK )
-#else /* MIPS */
-#ifdef ATTSV
-#ifndef NAP
-#ifdef TRS16
-#define HZ ( 1000 / CLOCK_TICK )
-#endif /* TRS16 */
-#ifdef NAPHACK
-#define nap(x) (void)syscall(3112, (x))
-#define NAP
-#endif /* NAPHACK */
-#endif /* NAP */
-#endif /* ATTSV */
-#endif /* MIPS */
-
-#ifdef M_UNIX
-#undef NGROUPS_MAX /* Prevent multiple definition warnings */
-#endif /* M_UNIX */
-
-/*
- NOTE: HP-UX 8.0 has a <sys/poll.h>, but there is no corresponding
- library routine, so _poll comes up undefined at link time.
-*/
-#ifdef CK_POLL
-#ifndef AIXRS /* IBM AIX needs special handling */
-#include <poll.h> /* "standard" (SVID) i/o multiplexing, etc */
-#else /* AIXRS */
-#ifdef SVR4 /* AIX 3.2 is like SVID... */
-#include <poll.h>
-#else /* But AIX 3.1 is not ... */
-#include <sys/poll.h> /* The include file is in include/sys */
-#define events reqevents /* And it does not map IBM-specific member */
-#define revents rtnevents /* names to the System V equivalents */
-#endif /* SVR4 */
-#endif /* AIXRS */
-#endif /* CK_POLL */
-
-#include <signal.h> /* Signals */
-
-/* For setjmp and longjmp */
-
-#ifndef ZILOG
-#include <setjmp.h>
-#else
-#include <setret.h>
-#endif /* ZILOG */
-
-/*
- The following test differentiates between 4.1 BSD and 4.2 & later.
- If you have a 4.1BSD system with the DIRENT library, this test could
- mistakenly diagnose 4.2BSD and then later enable the use of system calls
- that aren't defined. If indeed there are such systems, we can use some
- other way of testing for 4.1BSD, or add yet another compile-time switch.
-*/
-#ifdef BSD4
-#ifdef MAXNAMLEN
-#ifndef FT21 /* Except for Fortune. */
-#ifndef FT18
-#ifndef BELLV10 /* And Bell Labs Research UNIX V10 */
-#define BSD42
-#endif /* BELLV10 */
-#endif /* FT18 */
-#endif /* FT21 */
-#endif /* MAXNAMLEN */
-#endif /* BSD4 */
-
-#ifdef SUNOS41 /* From Christian Corti */
-#define BSD44ORPOSIX /* Uni Stuttgart */
-#define SVORPOSIX /* February 2010 */
-#include <termios.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <limits.h>
-#endif /* SUNOS41 */
-
-#ifdef SNI542
-#include <sys/filio.h> /* 299 for FIONREAD */
-#endif /* SNI542 */
-
-/*
- Minix 2.0 support added by Terry McConnell,
- Syracuse University <tmc@barnyard.syr.edu>
- No more sgtty interface, posix compliant.
-*/
-#ifdef MINIX2
-#define _MINIX /* Needed for some Minix header files */
-#define BSD44ORPOSIX
-#define SVORPOSIX
-#ifndef MINIX3
-#define DCLTIMEVAL
-#endif /* MINIX3 */
-#define NOFILEH
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <limits.h>
-#undef TIOCGETC /* defined in sys/ioctl.h, but not really supported */
-#define TANDEM 0
-#endif /* MINIX2 */
-
-/*
- MINIX 1.0 support added by Charles Hedrick,
- Rutgers University <hedrick@aramis.rutgers.edu>.
- MINIX also has V7 enabled.
-*/
-#ifdef MINIX
-#define TANDEM 0
-#define MYREAD
-#define NOSYSIOCTLH
-#include <limits.h>
-#endif /* MINIX */
-
-#ifdef CK_REDIR /* <sys/wait.h> needed only for REDIRECT command. */
-/*
- If anybody can figure out how to make this work with NeXTSTEP, be
- my guest! (NeXTBlah/NeXTBlah/bsd/sys/wait.h does not define WEXITSTATUS)
-*/
-#ifndef CK_WAIT_H /* If wait.h not already included... */
-#ifdef OSF /* force OSF to select POSIX wait */
-#ifdef _BSD /* instead of BSD (see ckcdeb.h) */
-#define CK_OSF_BSD
-#undef _BSD
-#endif /* _BSD */
-#endif /* OSF */
-#include <sys/wait.h> /* Include it */
-#ifdef OSF
-#ifdef CK_OSF_BSD
-#define _BSD /* Restore it */
-#undef CK_OSF_BSD
-#endif /* CK_OSF_BSD */
-#endif /* OSF */
-#endif /* CK_WAIT_H */
-#endif /* CK_REDIR */
-
-#include "ckuver.h" /* Version herald */
-char *ckxsys = HERALD;
-
-#ifdef CK_UTSNAME
-#include <sys/utsname.h>
-
-#ifdef TRU64 /* Tru64 UNIX 4.0 and later */
-/* Verified on Tru64 4.0F - might break on 4.0E or earlier */
-#include <sys/sysinfo.h> /* (don't know about OSF/1 or DU) */
-#include <machine/hal_sysinfo.h>
-#endif /* TRU64 */
-
-#ifdef SOLARIS25 /* Solaris 2.5 and later */
-#include <sys/systeminfo.h> /* (don't know about earlier ones) */
-#endif /* SOLARIS25 */
-
-#ifdef UW7
-#ifndef SYS_NMLN
-#define SYS_NMLN 257
-#endif /* NMLN */
-#endif /* UW7 */
-#ifdef HPUX9PLUS
-static int hpis800 = 0;
-#endif /* HPUX9PLUS */
-#ifdef SYS_NMLN
-#define CK_SYSNMLN SYS_NMLN
-#else
-#ifdef _SYS_NMLN
-#define CK_SYSNMLN _SYS_NMLN
-#else
-#ifdef UTSLEN
-#define CK_SYSNMLN UTSLEN
-#else
-#define CK_SYSNMLN 31
-#endif /* UTSLEN */
-#endif /* _SYS_NMLN */
-#endif /* SYS_NMLN */
-char unm_mch[CK_SYSNMLN+1] = { '\0', '\0' };
-char unm_mod[CK_SYSNMLN+1] = { '\0', '\0' };
-char unm_nam[CK_SYSNMLN+1] = { '\0', '\0' };
-char unm_rel[CK_SYSNMLN+1] = { '\0', '\0' };
-char unm_ver[CK_SYSNMLN+1] = { '\0', '\0' };
-#endif /* CK_UTSNAME */
-
-#ifdef CIE
-#include <stat.h> /* For chasing symlinks, etc. */
-#else
-#include <sys/stat.h>
-#endif /* CIE */
-
-#ifdef QNX /* 299 */
-#ifndef IXANY
-#define IXANY 0
-#endif /* IXANY */
-#endif /* QNX */
-
-/* UUCP lockfile material... */
-
-#ifndef NOUUCP
-#ifdef USETTYLOCK
-#ifdef HAVE_LOCKDEV /* Red Hat baudboy/lockdev */
-/*
- Watch out: baudboy.h references open() without making sure it has been
- declared, resulting in warnings on at least Red Hat 7.3. It's declared in
- fcntl.h, but we don't include that until later. In this case only, we
- include it here, and then the second include is harmless because in Red Hat
- Linux (the only place where you find baudboy.h) fcntl.h is protected from
- multiple inclusion by _FCNTL_H. - fdc, 10 May 2004.
-
- NOTE: Although Linux /usr/sbin/lockdev obviates the need for setuid or
- setgid bits to access the lockfile, C-Kermit will still need them to access
- the serial port itself unless the port is open for world read/write.
- Normally setgid uucp does the trick.
-
- Extra: HAVE_LOCKDEV has been added als openSuSE >= 11.3 doesn't use baudboy
- but ttylock. - jb, 26 Jul 2010
-*/
-#include <fcntl.h> /* This has to come before baudboy */
-#ifdef HAVE_BAUDBOY /* Red Hat baudboy/lockdev */
-#include <baudboy.h>
-#else /* !HAVE_BAUDBOY */ /* openSuSE lock via ttylock */
-#include <ttylock.h>
-#endif /* HAVE_BAUDBOY */
-#define LOCK_DIR "/var/lock" /* (even though we don't care) */
-
-#else /* !HAVE_LOCKDEV */
-
-#ifdef USE_UU_LOCK
-#ifdef __FreeBSD__
-#include <libutil.h> /* FreeBSD */
-#else
-#include <util.h> /* OpenBSD */
-#endif /* HAVE_LOCKDEV */
-#endif /* __FreeBSD */
-#endif /* USE_UU_LOCK */
-#else /* USETTYLOCK */
-
-/* Name of UUCP tty device lockfile */
-
-#ifdef LINUXFSSTND
-#ifndef HDBUUCP
-#define HDBUUCP
-#endif /* HDBUUCP */
-#endif /* LINUXFSSTND */
-
-#ifdef ACUCNTRL
-#define LCKDIR
-#endif /* ACUCNTRL */
-
-/*
- PIDSTRING means use ASCII string to represent pid in lockfile.
-*/
-#ifndef PIDSTRING
-#ifdef HDBUUCP
-#define PIDSTRING
-#else
-#ifdef BSD44
-#define PIDSTRING
-#else
-#ifdef RTAIX
-#define PIDSTRING
-#else
-#ifdef AIXRS
-#define PIDSTRING
-#else
-#ifdef COHERENT
-#define PIDSTRING
-#endif /* COHERENT */
-#endif /* AIXRS */
-#endif /* RTAIX */
-#endif /* BSD44 */
-#endif /* HDBUUCP */
-#endif /* PIDSTRING */
-
-/* Now the PIDSTRING exceptions... */
-
-#ifdef PIDSTRING
-#ifdef HPUX
-#undef PIDSTRING
-#endif /* HPUX */
-#endif /* PIDSTRING */
-
-#ifdef __bsdi__ /* BSDI (at least thru 1.1) */
-#ifdef PIDSTRING
-#undef PIDSTRING
-#endif /* PIDSTRING */
-#endif /* __bsdi__ */
-
-#ifdef OSF32 /* Digital UNIX (OSF/1) 3.2 */
-#ifdef PIDSTRING
-#undef PIDSTRING
-#endif /* PIDSTRING */
-#endif /* OSF32 */
-
-/*
- LOCK_DIR is the name of the lockfile directory.
- If LOCK_DIR is already defined (e.g. on command line), we don't change it.
-*/
-
-#ifndef LOCK_DIR
-#ifdef MACOSX
-#define LOCK_DIR "/var/spool/lock"
-#endif /* MACOSX */
-#endif/* LOCK_DIR */
-
-#ifndef LOCK_DIR
-#ifdef BSD44
-#ifdef __386BSD__
-#define LOCK_DIR "/var/spool/lock"
-#else
-#ifdef __FreeBSD__
-#define LOCK_DIR "/var/spool/lock"
-#else
-#ifdef __NetBSD__
-#define LOCK_DIR "/var/spool/lock"
-#else
-#ifdef __OpenBSD__
-#define LOCK_DIR "/var/spool/lock"
-#else
-/* So which ones is this for? */
-/* Probably original 4.4BSD on Vangogh */
-/* Plus who knows about Mac OS X... It doesn't even have a cu program */
-#define LOCK_DIR "/var/spool/uucp"
-#endif /* __OpenBSD__ */
-#endif /* __NetBSD__ */
-#endif /* __FreeBSD__ */
-#endif /* __386BSD__ */
-#else
-#ifdef DGUX430
-#define LOCK_DIR "/var/spool/locks"
-#else
-#ifdef HPUX10
-#define LOCK_DIR "/var/spool/locks"
-#else
-#ifdef RTAIX /* IBM RT PC AIX 2.2.1 */
-#define LOCK_DIR "/etc/locks"
-#else
-#ifdef AIXRS
-#define LOCK_DIR "/etc/locks"
-#else
-#ifdef ISIII
-#define LOCK_DIR "/etc/locks"
-#else
-#ifdef HDBUUCP
-#ifdef M_SYS5
-#define LOCK_DIR "/usr/spool/uucp"
-#else
-#ifdef M_UNIX
-#define LOCK_DIR "/usr/spool/uucp"
-#else
-#ifdef SVR4
-#define LOCK_DIR "/var/spool/locks"
-#else
-#ifdef SUNOS4
-#define LOCK_DIR "/var/spool/locks"
-#else
-#ifdef LINUXFSSTND
-#define LOCK_DIR "/var/lock";
-#else
-#define LOCK_DIR "/usr/spool/locks"
-#endif /* LINUXFSSTND */
-#endif /* SUNOS4 */
-#endif /* SVR4 */
-#endif /* M_UNIX */
-#endif /* M_SYS5 */
-#else
-#ifdef LCKDIR
-#define LOCK_DIR "/usr/spool/uucp/LCK"
-#else
-#ifdef COHERENT
-#define LOCK_DIR "/usr/spool/uucp"
-#else
-#define LOCK_DIR "/usr/spool/uucp"
-#endif /* COHERENT */
-#endif /* LCKDIR */
-#endif /* HDBUUCP */
-#endif /* ISIII */
-#endif /* AIXRS */
-#endif /* RTAIX */
-#endif /* HPUX10 */
-#endif /* DGUX430 */
-#endif /* BSD44 */
-#endif /* !LOCK_DIR (outside ifndef) */
-
-#ifdef OSF2 /* OSF/1 2.0 or later */
-#ifdef LOCK_DIR /* (maybe 1.x too, who knows...) */
-#undef LOCK_DIR
-#define LOCK_DIR "/var/spool/locks"
-#endif /* LOCK_DIR */
-#endif /* OSF2 */
-
-#ifdef COMMENT
-/* Sorry no more lockf() -- we lock first and THEN open the device. */
-#ifdef SVR4
-#ifndef BSD44
-#ifndef LOCKF
-#define LOCKF /* Use lockf() on tty device in SVR4 */
-#endif /* LOCKF */
-#endif /* BSD44 */
-#endif /* SVR4 */
-#endif /* COMMENT */
-
-#ifdef NOLOCKF /* But NOLOCKF cancels LOCKF */
-#ifdef LOCKF
-#undef LOCKF
-#endif /* LOCKF */
-#endif /* NOLOCKF */
-
-/* More about this below... */
-
-#endif /* USETTYLOCK */
-#endif /* NOUUCP */
-
-/*
- MYREAD means use our internally defined nonblocking buffered read routine.
-*/
-#ifdef ATTSV
-#define MYREAD
-#endif /* ATTSV */
-
-#ifdef ATT7300
-#ifndef MYREAD
-#define MYREAD
-#endif /* MYREAD */
-/* bits for attmodem: internal modem in use, restart getty */
-#define ISMODEM 1
-#define DOGETY 512
-#endif /* ATT7300 */
-
-#ifdef BSD42
-#define MYREAD
-#endif /* BSD42 */
-
-#ifdef POSIX
-#define MYREAD
-#endif /* POSIX */
-#ifdef __bsdi__
-#ifndef O_NDELAY
-#define O_NDELAY O_NONBLOCK
-#endif /* O_NDELAY */
-#endif /* __bsdi__ */
-
-/*
- Variables available to outside world:
-
- dftty -- Pointer to default tty name string, like "/dev/tty".
- dfloc -- 0 if dftty is console, 1 if external line.
- dfprty -- Default parity
- dfflow -- Default flow control
- ckxech -- Flag for who echoes console typein:
- 1 - The program (system echo is turned off)
- 0 - The system (or front end, or terminal).
- functions that want to do their own echoing should check this flag
- before doing so.
-
- flfnam -- Name of lock file, including its path, e.g.,
- "/usr/spool/uucp/LCK..cul0" or "/etc/locks/tty77"
- lkflfn -- Name of link to lock file, including its paths
- haslock -- Flag set if this kermit established a uucp lock.
- lockpid -- PID of other process that has desired line open, as string.
- backgrd -- Flag indicating program executing in background ( & on
- end of shell command). Used to ignore INT and QUIT signals.
- rtu_bug -- Set by stptrap(). RTU treats ^Z as EOF (but only when we handle
- SIGTSTP)
-
- Functions for assigned communication line (either external or console tty):
-
- sysinit() -- System dependent program initialization
- syscleanup() -- System dependent program shutdown
- ttopen(ttname,local,mdmtyp,timo) -- Open the named tty for exclusive access.
- ttclos() -- Close & reset the tty, releasing any access lock.
- ttsspd(cps) -- Set the transmission speed of the tty.
- ttgspd() -- Get (read) the the transmission speed of the tty.
- ttpkt(speed,flow,parity) -- Put the tty in packet mode and set the speed.
- ttvt(speed,flow) -- Put the tty in virtual terminal mode.
- or in DIALING or CONNECTED modem control state.
- ttres() -- Restore original tty modes.
- ttscarr(carrier) -- Set carrier control mode, on/off/auto.
- ttinl(dest,max,timo) -- Timed read line from the tty.
- ttinc(timo) -- Timed read character from tty.
- myread() -- Raw mode bulk buffer read, gives subsequent
- chars one at a time and simulates FIONREAD.
- myunrd(c) -- Places c back in buffer to be read (one only)
- ttchk() -- See how many characters in tty input buffer.
- ttxin(n,buf) -- Read n characters from tty (untimed).
- ttol(string,length) -- Write a string to the tty.
- ttoc(c) -- Write a character to the tty.
- ttflui() -- Flush tty input buffer.
- ttsndb() -- Send BREAK signal.
- ttsndlb() -- Send Long BREAK signal.
-
- ttlock(ttname) -- "Lock" tty device against uucp collisions.
- ttunlck() -- Unlock tty device.
-
- For ATT7300/Unix PC, System V:
- attdial(ttname,speed,telnbr) -- dials ATT7300/Unix PC internal modem
- offgetty(ttname) -- Turns off getty(1m) for comms line
- ongetty(ttname) -- Restores getty() to comms line
-*/
-
-/*
-Functions for console terminal:
-
- congm() -- Get console terminal modes.
- concb(esc) -- Put the console in single-character wakeup mode with no echo.
- conbin(esc) -- Put the console in binary (raw) mode.
- conres() -- Restore the console to mode obtained by congm().
- conoc(c) -- Unbuffered output, one character to console.
- conol(s) -- Unbuffered output, null-terminated string to the console.
- conola(s) -- Unbuffered output, array of strings to the console.
- conxo(n,s) -- Unbuffered output, n characters to the console.
- conchk() -- Check if characters available at console (bsd 4.2).
- Check if escape char (^\) typed at console (System III/V).
- coninc(timo) -- Timed get a character from the console.
- congks(timo) -- Timed get keyboard scan code.
- conint() -- Enable terminal interrupts on the console if not background.
- connoi() -- Disable terminal interrupts on the console if not background.
-
-Time functions
-
- msleep(m) -- Millisecond sleep
- ztime(&s) -- Return pointer to date/time string
- rtimer() -- Reset timer
- gtimer() -- Get elapsed time since last call to rtimer()
-*/
-
-/* Conditional Includes */
-
-/* Whether to include <sys/file.h> */
-
-#ifdef RTU /* RTU doesn't */
-#define NOFILEH
-#endif /* RTU */
-
-#ifdef CIE /* CIE does. */
-#undef NOFILEH
-#endif /* CIE */
-
-#ifdef BSD41 /* 4.1 BSD doesn't */
-#define NOFILEH
-#endif /* BSD41 */
-
-#ifdef is68k /* Integrated Solutions 68000 UNIX */
-#define NOFILEH /* e.g. on Plexux P60 and Sun-1 */
-#endif /* is68k */
-
-#ifdef MINIX /* MINIX */
-#define NOFILEH
-#endif /* MINIX */
-
-#ifdef COHERENT /* Coherent */
-#define NOFILEH
-#endif /* COHERENT */
-
-#ifndef NOFILEH /* Now include if selected. */
-#include <sys/file.h>
-#endif /* NOFILEH */
-
-/* POSIX */
-
-#ifdef BSD44ORPOSIX /* POSIX uses termios.h */
-#define TERMIOS
-#ifdef __bsdi__
-#ifdef POSIX
-#undef _POSIX_SOURCE /* Get extra stuff from termios.h */
-#endif /* POSIX */
-#endif /* __bsdi__ */
-#include <termios.h>
-#ifdef LINUX
-#include <sys/ioctl.h>
-#endif /* LINUX */
-#ifdef QNX16
-#include <ioctl.h>
-#else
-#ifdef QNX6
-#include <ioctl.h>
-#endif /* QNX6 */
-#endif /* QNX16 */
-#ifdef __bsdi__
-#ifdef POSIX
-#define _POSIX_SOURCE
-#endif /* POSIX */
-#endif /* __bsdi__ */
-#ifndef BSD44 /* Really POSIX */
-#ifndef CK_QNX32 /* was CK_QNX32 */
-#define NOSYSIOCTLH /* No ioctl's allowed. */
-#undef ultrix /* Turn off any ultrix features. */
-#endif /* CK_QNX32 */
-#endif /* BSD44 */
-#endif /* POSIX */
-
-/* System III, System V */
-
-#ifdef ATTSV
-#ifndef BSD44
-#ifndef POSIX
-#include <termio.h>
-#endif /* POSIX */
-#endif /* BSD44 */
-#ifdef TERMIOX
-/* Need this for termiox structure, RTS/CTS and DTR/CD flow control */
-#include <termiox.h>
- struct termiox rctsx;
-#else
-#ifdef STERMIOX
-#ifdef SCO_OSR504
-/* Sorry, this is truly disgusting but it's SCO's fault. */
-#ifndef _SVID3
-#define _CK_SVID3_X
-#define _SVID3
-#endif /* _SVID3 */
-#endif /* SCO_OSR504 */
-#include <sys/termiox.h>
- struct termiox rctsx;
-#ifdef CK_SVID3_X
-#undef _SVID3
-#undef CK_SVID3_X
-#endif /* CK_SVID3_X */
-#endif /* STERMIOX */
-#endif /* TERMIOX */
-#endif /* ATTSV */
-
-#ifdef COHERENT /* Use termio.h, not sgtty.h for Coherent */
-#include <termio.h>
-#endif /* COHERENT */
-
-#ifdef MINIX /* MINIX uses ioctl's */
-#define NOSYSIOCTLH /* but has no <sys/ioctl.h> */
-#endif /* MINIX */
-
-/* Others */
-
-#ifndef NOSYSIOCTLH /* Others use ioctl() */
-#ifdef SUN4S5
-/*
- This is to get rid of cpp warning messages that occur because all of
- these symbols are defined by both termios.h and ioctl.h on the SUN.
-*/
-#undef ECHO
-#undef NL0
-#undef NL1
-#undef TAB0
-#undef TAB1
-#undef TAB2
-#undef XTABS
-#undef CR0
-#undef CR1
-#undef CR2
-#undef CR3
-#undef FF0
-#undef FF1
-#undef BS0
-#undef BS1
-#undef TOSTOP
-#undef FLUSHO
-#undef PENDIN
-#undef NOFLSH
-#endif /* SUN4S5 */
-#include <sys/ioctl.h>
-#endif /* NOSYSIOCTLH */
-/*
- We really, really, REALLY want FIONREAD, because it is the only way to find
- out not just *if* stuff is waiting to be read, but how much, which is
- critical to our sliding-window and streaming procedures, not to mention
- efficiency of CONNECT, etc.
-*/
-#ifdef BELLV10
-#include <sys/filio.h> /* For FIONREAD */
-#ifdef FIONREAD
-#define MYREAD
-#endif /* MYREAD */
-#endif /* BELLV10 */
-
-#ifndef FIONREAD
-/* It wasn't found in ioctl.h or term*.h - try these places: */
-#ifdef UNIXWARE
-#include <sys/filio.h>
-#else
-#ifdef SOLARIS
-#include <sys/filio.h>
-#endif /* SOLARIS */
-#endif /* UNIXWARE */
-#endif /* FIONREAD */
-
-#ifdef XENIX /* Was M_UNIX but XENIX implies M_UNIX and applies to XENIX too */
-/*
- <sys/socket.h> included above via "ckcnet.h" defines FIONREAD as
- something. Due to this, in_chk() uses the FIONREAD instead of RDCHK
- and the hot keys during file transfer (X to cancel file etc) do not
- work because FIONREAD doesn't work even though it is defined.
-
- NOTE: This might also be true elsewhere.
-*/
-#ifdef FIONREAD
-#undef FIONREAD
-#endif /* FIONREAD */
-#endif /* XENIX */
-
-#ifdef CK_SCOV5 /* Ditto for SCO OpenServer 5.0 */
-#ifndef SCO_OSR507 /* 299 */
-#ifdef FIONREAD
-#undef FIONREAD
-#endif /* FIONREAD */
-#endif /* SCO_OSR507 */
-#endif /* CK_SCOV5 */
-
-#ifdef SCO_OSR507 /* 299 */
-#ifdef RDCHK
-#undef RDCHK
-#endif /* RDCHK */
-#endif /* SCO_OSR507 */
-
-/* Whether to include <fcntl.h> */
-
-#ifndef is68k /* Only a few don't have this one. */
-#ifndef BSD41
-#ifndef FT21
-#ifndef FT18
-#ifndef COHERENT
-#include <fcntl.h>
-#endif /* COHERENT */
-#endif /* FT18 */
-#endif /* FT21 */
-#endif /* BSD41 */
-#endif /* not is68k */
-
-#ifdef COHERENT
-#ifdef _I386
-#include <fcntl.h>
-#else
-#include <sys/fcntl.h>
-#endif /* _I386 */
-#endif /* COHERENT */
-
-#ifdef ATT7300 /* Unix PC, internal modem dialer */
-#include <sys/phone.h>
-#endif /* ATT7300 */
-
-#ifdef HPUX /* HP-UX variations. */
-#define HPUXJOBCTL
-#include <sys/modem.h> /* HP-UX modem signals */
-#ifdef hp9000s500 /* Model 500 */
-#undef HPUXJOBCTL
-#endif /* hp9000s500 */
-#ifdef HPUXPRE65
-#undef HPUXJOBCTL
-typedef long mflag;
-#endif /* HPUXPRE65 */
-#ifdef HPUXJOBCTL
-#include <sys/bsdtty.h> /* HP-UX Berkeley tty support */
-#endif /* HPUXJOBCTL */
-#endif /* HPUX */
-
-/*
- Which time.h files to include... See ckcdeb.h for defaults.
- Note that 0, 1, 2, or all 3 of these can be included according to
- the symbol definitions.
-*/
-#ifndef NOTIMEH
-#ifdef TIMEH
-#include <time.h>
-#endif /* TIMEH */
-#endif /* NOTIMEH */
-
-#ifndef NOSYSTIMEH
-#ifdef SYSTIMEH
-#include <sys/time.h>
-#endif /* SYSTIMEH */
-#endif /* NOSYSTIMEH */
-
-#ifndef NOSYSTIMEBH
-#ifdef SYSTIMEBH
-#include <sys/timeb.h>
-#endif /* SYSTIMEBH */
-#endif /* NOSYSTIMEBH */
-
-#ifndef NODCLTIMEVAL
-#ifdef DCLTIMEVAL
-/*
- In certain POSIX builds (like Unixware 7), <[sys/]time.h> refuses to
- define the structs we need to access the higher speeds, so we have to
- do it ourselves.
-*/
-struct timeval {
- long tv_sec;
- long tv_usec;
-};
-struct timezone {
- int tz_minuteswest;
- int tz_dsttime;
-};
-#endif /* DCLTIMEVAL */
-#endif /* NODCLTIMEVAL */
-
-#ifdef __linux__
-/* THIS IS OBSOLETE since about Linux 0.92 */
-#ifdef OLINUXHISPEED
-#include <linux/serial.h>
-#endif /* OLINUXHISPEED */
-#ifdef __alpha__ /* Linux on DEC Alpha */
-#ifndef __GLIBC__ /* But not with glibc */
-#include <asm/termios.h>
-#endif /* __GLIBC__ */
-#endif /* __alpha__ */
-#endif /* __linux__ */
-
-#ifdef NOIEXTEN /* This is broken on some systems */
-#undef IEXTEN /* like Convex/OS 9.1 */
-#endif /* NOIEXTEN */
-#ifndef IEXTEN /* Turn off ^O/^V processing. */
-#define IEXTEN 0 /* Needed, at least, on BSDI. */
-#endif /* IEXTEN */
-/*
- Pick up definitions needed for select() if we don't have them already.
- Normally they come from <sys/types.h> but some systems get them from
- <sys/select.h>... Rather than hardwire all of them into the source, we
- include it if SELECT_H is defined in compile-time CFLAGS.
-*/
-#ifndef SCO_OSR504
-#ifdef SELECT_H
-#include <sys/select.h>
-#endif /* SELECT_H */
-#endif /* SCO_OSR504 */
-
-#ifdef aegis
-#include "/sys/ins/base.ins.c"
-#include "/sys/ins/error.ins.c"
-#include "/sys/ins/ios.ins.c"
-#include "/sys/ins/sio.ins.c"
-#include "/sys/ins/pad.ins.c"
-#include "/sys/ins/time.ins.c"
-#include "/sys/ins/pfm.ins.c"
-#include "/sys/ins/pgm.ins.c"
-#include "/sys/ins/ec2.ins.c"
-#include "/sys/ins/type_uids.ins.c"
-#include <default_acl.h>
-#undef TIOCEXCL
-#undef FIONREAD
-#endif /* aegis */
-
-#ifdef sxaE50 /* PFU Compact A SX/A TISP V10/L50 */
-#undef FIONREAD
-#endif /* sxaE50 */
-
-/* The following #defines are catch-alls for those systems */
-/* that didn't have or couldn't find <file.h>... */
-
-#ifndef FREAD
-#define FREAD 0x01
-#endif /* FREAD */
-
-#ifndef FWRITE
-#define FWRITE 0x10
-#endif /* FWRITE */
-
-#ifndef O_RDONLY
-#define O_RDONLY 000
-#endif /* O_RDONLY */
-
-/* This is for ancient Unixes that don't have these tty symbols defined. */
-
-#ifndef PENDIN
-#define PENDIN ICANON
-#endif /* PENDIN */
-#ifndef FLUSHO
-#define FLUSHO ICANON
-#endif /* FLUSHO */
-#ifndef EXTPROC
-#define EXTPROC ICANON
-#endif /* EXTPROC */
-
-#ifdef SVORPOSIX
-/*
- Modem signals are also forbidden in the POSIX world. But some POSIX-based
- platforms let us at them anyway if we know where to look.
-*/
-#ifndef NEEDMDMDEFS
-/* Doesn't work for Linux */
-#ifdef UNIXWARE7
-#define NEEDMDMDEFS
-#endif /* UNIXWARE7 */
-#endif /* NEEDMDMDEFS */
-
-#ifdef NEEDMDMDEFS
-#ifndef TIOCMGET
-#define TIOCMGET (('t'<<8)|29)
-#endif /* TIOCMGET */
-
-#ifndef TIOCM_DTR
-#define TIOCM_DTR 0x0002
-#endif /* TIOCM_DTR */
-#ifndef TIOCM_RTS
-#define TIOCM_RTS 0x0004
-#endif /* TIOCM_RTS */
-#ifndef TIOCM_CTS
-#define TIOCM_CTS 0x0020
-#endif /* TIOCM_CTS */
-#ifndef TIOCM_CAR
-#define TIOCM_CAR 0x0040
-#endif /* TIOCM_CAR */
-#ifndef TIOCM_RNG
-#define TIOCM_RNG 0x0080
-#endif /* TIOCM_RNG */
-#ifndef TIOCM_DSR
-#define TIOCM_DSR 0x0100
-#endif /* TIOCM_DSR */
-#endif /* NEEDMDMDEFS */
-#endif /* SVORPOSIX */
-
-/* Declarations */
-
-#ifdef OXOS
-#undef TCGETA
-#undef TCSETA
-#undef TCSETAW
-#undef TCSETAF
-#define TCGETA TCGETS
-#define TCSETA TCSETS
-#define TCSETAW TCSETSW
-#define TCSETAF TCSETSF
-#define termio termios
-#endif /* OXOS */
-
-#ifdef SVORPOSIX /* AT&T Sys V or POSIX */
-#ifdef UNIXWAREPOSIX /* UnixWare 7 POSIX build */
-/*
- In Unixware POSIX builds, <[sys/]time.h> refuses to define the
- structs we need to access the higher speeds, so we have to do it
- ourselves.
-*/
-struct timeval {
- long tv_sec;
- long tv_usec;
-};
-struct timezone {
- int tz_minuteswest;
- int tz_dsttime;
-};
-#endif /* UNIXWAREPOSIX */
-#endif /* SVORPOSIX */
-
-#ifdef __GNUC__
-#ifdef XENIX
-/*
- Because Xenix <time.h> doesn't declare time() if we're using gcc.
-*/
-time_t time();
-#endif /* XENIX */
-#endif /* __GNUC__ */
-
-/* Special stuff for V7 input buffer peeking */
-
-#ifdef V7
-int kmem[2] = { -1, -1};
-char *initrawq(), *qaddr[2]={0,0};
-#define CON 0
-#define TTY 1
-#endif /* V7 */
-
-/* dftty is the device name of the default device for file transfer */
-/* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */
-
-#ifdef BEOS
- char * dftty = NULL;
- char * dfmdm = "none";
- int dfloc = 0; /* that goes in local mode by default */
-#else
-#ifndef DFTTY
-#ifdef PROVX1
- char *dftty = "/dev/com1.dout"; /* Only example so far of a system */
- char *dfmdm = "none";
- int dfloc = 1; /* that goes in local mode by default */
-#else
- char *dftty = CTTNAM; /* Remote by default, use normal */
- char *dfmdm = "none";
- int dfloc = 0; /* controlling terminal name. */
-#endif /* PROVX1 */
-#else
- char *dftty = DFTTY; /* Default location specified on */
- char *dfmdm = "none"; /* command line. */
- int dfloc = 1; /* controlling terminal name. */
-#endif /* DFTTY */
-#endif /* BEOS */
-
-#define CON_RES 0 /* Console state is "reset" */
-#define CON_CB 1 /* Console state is CBREAK */
-#define CON_BIN 2 /* Console state is binary */
- static int constate = CON_RES;
-
-#define CONI_RES 0 /* Console interrupts are "reset" */
-#define CONI_INT 1 /* Console intterupts are set */
-#define CONI_NOI 2 /* Console intterupts are disabled */
- static int conistate = CONI_RES;
-
-#ifdef CK_SMALL
-#define CONBUFSIZ 15
-#else
-#define CONBUFSIZ 255
-#endif /* CK_SMALL */
- static char conbuf[CONBUFSIZ]; /* Console readahead buffer */
- static int conbufn = 0; /* Chars in readahead buffer */
- static char *conbufp = conbuf; /* Next char in readahead buffer */
-
- char cttnam[DEVNAMLEN+1] = { '\0', '\0' }; /* Determined at runtime */
-
-#ifdef RTU
- int rtu_bug = 0; /* set to 1 when returning from SIGTSTP */
-#endif /* RTU */
-
- int dfprty = DEFPAR; /* Default parity (0 = none) */
- int ttprty = 0; /* The parity that is in use. */
- static int ttpmsk = 0xff; /* Parity stripping mask. */
- int ttmdm = 0; /* Modem in use. */
- int ttcarr = CAR_AUT; /* Carrier handling mode. */
- int dfflow = FLO_NONE; /* Default flow control is NONE */
- int backgrd = 0; /* Assume in foreground (no '&' ) */
-#ifdef F_SETFL
- int iniflags = -1; /* fcntl flags for ttyfd */
-#endif /* F_SETFL */
- int fdflag = 0; /* Flag for redirected stdio */
- int ttfdflg = 0; /* Open File descriptor was given */
- int tvtflg = 0; /* Flag that ttvt has been called */
- long ttspeed = -1L; /* For saving speed */
- int ttflow = -9; /* For saving flow */
- int ttld = -1; /* Line discipline */
-
-#ifdef sony_news
- static int km_con = -1; /* Kanji mode for console tty */
- static int km_ext = -1; /* Kanji mode for external device */
-#endif /* sony_news */
-
-#ifdef PARSENSE
- static int needpchk = 1; /* Need parity check */
-#else
- static int needpchk = 0;
-#endif /* PARSENSE */
-
- extern int stopbits; /* Stop bits */
-#ifdef HWPARITY
-/*
- Unfortunately we must do this with global variables rather than through the
- tt...() APIs to avoid changing the APIs and the many modules that use them.
- If hwparity != 0, this indicates 8 data bits + parity, rather than 7 data
- bits + parity or 8 data bits and no parity, and overrides the regular parity
- variable, which is communicated to this module thru ttpkt(), and represented
- locally by the ttprty variable.
-*/
- extern int hwparity; /* Hardware parity */
-#endif /* HWPARITY */
-
-#ifdef TCPSOCKET
-#ifdef TCP_NODELAY
-static int nodelay_sav = -1;
-#endif /* TCP_NODELAY */
-#endif /* TCPSOCKET */
-
-static int sigint_ign = 0; /* SIGINT is ignored */
-
-/*
- Having this module rely on external globals is bad, but fixing this
- requires overhaul of the ck*tio.c modules for all the different operating
- systems supported by C-Kermit. Left for a future release.
-*/
-extern int ttnproto; /* Defined in ckcnet.c */
-extern int ttnet; /* Defined in ckcnet.c */
-extern int nopush, xfrcan, xfrchr, xfrnum; /* Defined in ckcmai.c */
-extern int xsuspend, wasclosed;
-extern int inserver, local;
-
-int ckxech = 0; /* 0 if system normally echoes console characters, else 1 */
-
-int ckmaxfiles = 0; /* Max number of open files */
-
-#ifdef CK_ENCRYPTION /* Kerberos */
-#include "ckuath.h"
-extern int me_encrypt, u_encrypt;
-#endif /* CK_ENCRYPTION */
-
-/* Declarations of variables global within this module */
-
-#ifdef TTLEBUF /* See ckcnet.h */
-int ttpush = -1;
-#define LEBUFSIZ 4096
-static CHAR le_buf[LEBUFSIZ];
-static int le_start = 0, le_end = 0, le_data = 0;
-#endif /* TTLEBUF */
-
-#define MSGBUF_SIZE 1024 /* For debugging */
-static char msgbuf[MSGBUF_SIZE];
-
-static int gotsigs = 0;
-
-static time_t tcount = (time_t)0; /* Elapsed time counter */
-
-static SIGTYP (*saval)() = NULL; /* For saving alarm() handler */
-static SIGTYP (*savquit)() = NULL; /* and other signal handlers */
-#ifdef SIGUSR1
-static SIGTYP (*savusr1)() = NULL;
-#endif /* SIGUSR1 */
-#ifdef SIGUSR2
-static SIGTYP (*savusr2)() = NULL;
-#endif /* SIGUSR2 */
-#ifdef SIGPIPE
-static SIGTYP (*savpipe)() = NULL;
-#endif /* SIGPIPE */
-#ifdef SIGDANGER
-static SIGTYP (*savdanger)() = NULL;
-#endif /* SIGDANGER */
-
-#ifndef NOJC
-static SIGTYP (*jchdlr)() = NULL; /* For checking suspend handler */
-#endif /* NOJC */
-static int jcshell = -1; /* And flag for result */
-
-/*
- BREAKNULS is defined for systems that simulate sending a BREAK signal
- by sending a bunch of NUL characters at low speed.
-*/
-#ifdef PROVX1
-#ifndef BREAKNULS
-#define BREAKNULS
-#endif /* BREAKNULS */
-#endif /* PROVX1 */
-
-#ifdef V7
-#ifndef BREAKNULS
-#define BREAKNULS
-#endif /* BREAKNULS */
-#endif /* V7 */
-
-#ifdef BREAKNULS
-static char /* A string of nulls */
-*brnuls = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-#endif /* BREAKNULS */
-
-#ifdef CK_POSIX_SIG /* Longjump buffers */
-static sigjmp_buf sjbuf; /* POSIX signal handling */
-#else
-static jmp_buf sjbuf;
-#endif /* CK_POSIX_SIG */
-
-#ifdef V7
-static jmp_buf jjbuf;
-#endif /* V7 */
-
-/* static */ /* (Not static any more) */
-int ttyfd = -1; /* TTY file descriptor */
-
-int ttpipe = 0; /* NETCMD: Use pipe instead of ttyfd */
-int ttpty = 0; /* NETPTY: Use pty instead of ttfyd */
-
-#ifdef NETPTY /* These are in ckupty.c */
-extern PID_T pty_fork_pid;
-extern int pty_master_fd, pty_slave_fd;
-#endif /* NETPTY */
-
-#ifdef NETCMD
-#ifdef NETCONN
-static int pipe0[2], pipe1[2]; /* Pipes for net i/o */
-#endif /* NETCONN */
-static PID_T ttpid = 0; /* Process ID for fork */
-static int fdin, fdout; /* File descriptors for pipe */
-static FILE * ttout = NULL; /* File pointer for output pipe */
-#ifdef DCLFDOPEN
-/* fdopen() needs declaring because it's not declared in <stdio.h> */
-_PROTOTYP( FILE * fdopen, (int, char *) );
-#endif /* DCLFDOPEN */
-#endif /* NETCMD */
-
-extern int pexitstat, quiet;
-
-#ifdef Plan9
-int ttyctlfd = -1; /* TTY control channel - What? UNIX doesn't have one? */
-int consctlfd = -1; /* Console control channel */
-int noisefd = -1; /* tone channel */
-static int ttylastspeed = -1; /* So we can lie about the speed */
-#endif /* Plan9 */
-
-int telnetfd = 0; /* File descriptor is for telnet */
-#ifdef NETCONN
-int x25fd = 0; /* File descriptor is for X.25 */
-#endif /* NETCONN */
-
-char lockpid[16] = { '\0', '\0' }; /* PID stored in lockfile, as string */
-
-static int lkf = 0, /* Line lock flag */
- cgmf = 0, /* Flag that console modes saved */
- xlocal = 0, /* Flag for tty local or remote */
- curcarr = 0; /* Carrier mode: require/ignore. */
-
-static int netconn = 0; /* 1 if network connection active */
-
-static char escchr; /* Escape or attn character */
-
-#ifdef CK_SCO32V4
-#include <sys/time.h>
-#endif /* CK_SCO32V4 */
-
-#ifdef HAVE_TV
- static struct timeval tv; /* For getting time, from sys/time.h */
-#endif /* HAVE_TV */
-#ifdef HAVE_TZ
- static struct timezone tz;
-#endif /* HAVE_TZ */
-
-#ifdef OSF
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* OSF */
-
-#ifdef BSD29
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* BSD29 */
-
-#ifdef BSD41
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* BSD41 */
-
-#ifdef BELLV10
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* BELLV10 */
-
-#ifdef FT21
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* FT21 */
-
-#ifdef TOWER1
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* TOWER1 */
-
-#ifdef COHERENT
- static long xclock; /* For getting time from sys/time.h */
- static struct timeb ftp; /* And from sys/timeb.h */
-#endif /* COHERENT */
-
-#ifdef V7
- static long xclock;
-#endif /* V7 */
-
-/* sgtty/termio information... */
-
-#ifdef BSD44ORPOSIX /* POSIX or BSD44 */
- static struct termios
- ttold, ttraw, tttvt, ttcur,
- ccold, ccraw, cccbrk;
-#else /* BSD, V7, etc */
-
-#ifdef COHERENT /* Hack alert... */
-#define ATTSV
-#endif /* COHERENT */
-
-#ifdef ATTSV
- static struct termio ttold = {0}; /* Init'd for word alignment, */
- static struct termio ttraw = {0}; /* which is important for some */
- static struct termio tttvt = {0}; /* systems, like Zilog... */
- static struct termio ttcur = {0};
- static struct termio ccold = {0};
- static struct termio ccraw = {0};
- static struct termio cccbrk = {0};
-#else
- static struct sgttyb /* sgtty info... */
- ttold, ttraw, tttvt, ttcur, /* for communication line */
- ccold, ccraw, cccbrk; /* and for console */
-#ifdef BELLV10
- static struct ttydevb /* Device info... */
- tdold, tdcur; /* for communication device */
-#endif /* BELLV10 */
-#ifdef TIOCGETC
- static struct tchars tchold, tchnoi;
-
- static int tcharf;
-#endif /* TIOCGETC */
-#ifdef TIOCGLTC
- static struct ltchars ltchold, ltchnoi;
- static int ltcharf;
-#endif /* TIOCGLTC */
- int lmodef = 0; /* Local modes */
- int lmode = 0;
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-
-#ifdef COMMENT
-/* It picks up the speeds but they don't work */
-#ifdef UNIXWARE /* For higher serial speeds */
-#ifdef UW7 /* in Unixware 7.0 */
-#include <sys/asyc.h> /* This picks up 57600 and 115200 */
-#endif /* UW7 */
-#endif /* UNIXWARE */
-#endif /* COMMENT */
-
-#ifdef PROVX1
- static struct sgttyb ttbuf;
-#endif /* PROVX1 */
-
-#ifdef ultrix
-/* do we really need this? */
- static struct sgttyb vanilla;
-#endif /* ultrix */
-
-#ifdef ATT7300
-static int attmodem = 0; /* ATT7300 internal-modem status */
-struct updata dialer = {0}; /* Condition dialer for data call */
-#endif /* ATT7300 */
-
-#ifndef NOUUCP
-#define FLFNAML 128
-#ifndef USETTYLOCK
-#ifdef RTAIX
-char lkflfn[FLFNAML] = { '\0', '\0' }; /* and possible link to it */
-#endif /* RTAIX */
-char lock2[FLFNAML] = { '\0', '\0' }; /* Name of second lockfile */
-#endif /* USETTYLOCK */
-#else
-#define FLFNAML 7
-#endif /* NOUUCP */
-char flfnam[FLFNAML+1] = { '\0', '\0' }; /* UUCP lock file path name */
-
-int haslock = 0; /* =1 if this kermit locked uucp */
-
-#ifndef OXOS
-#ifdef SVORPOSIX
-static int conesc = 0; /* set to 1 if esc char (^\) typed */
-#else
-#ifdef V7
-static int conesc = 0;
-#else
-#ifdef C70
-static int conesc = 0;
-#endif /* C70 */
-#endif /* V7 */
-#endif /* SVORPOSIX */
-#endif /* OXOS */
-
-/* Local copy of comm device name or network host */
-static char ttnmsv[DEVNAMLEN+1] = { '\0', '\0' };
-#ifdef USETTYLOCK
-static char lockname[DEVNAMLEN+1]; /* Ditto, the part after "/dev/". */
-#endif /* USETTYLOCK */
-
-#ifdef aegis
-static status_$t st; /* error status return value */
-static short concrp = 0; /* true if console is CRP pad */
-static uid_$t ttyuid; /* tty type uid */
-static uid_$t conuid; /* stdout type uid */
-
-/* APOLLO Aegis main()
- * establish acl usage and cleanup handling
- * this makes sure that CRP pads
- * get restored to a usable mode
- */
-main(argc,argv) int argc; char **argv; {
- status_$t status;
- pfm_$cleanup_rec dirty;
-
- PID_T pid = getpid();
-
- /* acl usage according to invoking environment */
- default_acl(USE_DEFENV);
-
- /* establish a cleanup continuation */
- status = pfm_$cleanup(dirty);
- if (status.all != pfm_$cleanup_set) {
- /* only handle faults for the original process */
- if (pid == getpid() && status.all > pgm_$max_severity) {
- /* blew up in main process */
- status_$t quo;
- pfm_$cleanup_rec clean;
-
- /* restore the console in any case */
- conres();
-
- /* attempt a clean exit */
- debug(F101, "cleanup fault status", "", status.all);
-
- /* doexit(), then send status to continuation */
- quo = pfm_$cleanup(clean);
- if (quo.all == pfm_$cleanup_set)
- doexit(pgm_$program_faulted,-1);
- else if (quo.all > pgm_$max_severity)
- pfm_$signal(quo); /* blew up in doexit() */
- }
- /* send to the original continuation */
- pfm_$signal(status);
- /*NOTREACHED*/
- }
- return(ckcmai(argc, argv));
-}
-#endif /* aegis */
-
-/* ANSI-style prototypes for internal functions. */
-/* Functions used outside this module are prototyped in ckcker.h. */
-
-#ifdef apollo
-_PROTOTYP( SIGTYP timerh, () );
-_PROTOTYP( SIGTYP cctrap, () );
-_PROTOTYP( SIGTYP esctrp, () );
-_PROTOTYP( SIGTYP sig_ign, () );
-#else
-_PROTOTYP( SIGTYP timerh, (int) );
-_PROTOTYP( SIGTYP cctrap, (int) );
-_PROTOTYP( SIGTYP esctrp, (int) );
-#endif /* apollo */
-_PROTOTYP( int do_open, (char *) );
-_PROTOTYP( static int in_chk, (int, int) );
-_PROTOTYP( static int ttrpid, (char *) );
-_PROTOTYP( static int ttchkpid, (char *) );
-_PROTOTYP( static int ttlock, (char *) );
-_PROTOTYP( static int ttunlck, (void) );
-_PROTOTYP( static VOID sigchld_handler, (int) );
-_PROTOTYP( int mygetbuf, (void) );
-_PROTOTYP( int myfillbuf, (void) );
-_PROTOTYP( VOID conbgt, (int) );
-#ifdef ACUCNTRL
-_PROTOTYP( VOID acucntrl, (char *, char *) );
-#endif /* ACUCNTRL */
-
-#ifdef BSD44ORPOSIX
-_PROTOTYP( int carrctl, (struct termios *, int) );
-#else
-#ifdef ATTSV
-_PROTOTYP( int carrctl, (struct termio *, int) );
-#else
-_PROTOTYP( int carrctl, (struct sgttyb *, int) );
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-
-#ifdef ATT7300
-_PROTOTYP( int attdial, (char *, long, char *) );
-_PROTOTYP( int offgetty, (char *) );
-_PROTOTYP( int ongetty, (char *) );
-#endif /* ATT7300 */
-
-#ifdef BEOSORBEBOX
-#ifdef SELECT
- /* BeOS is not capable of using SELECT on anything but sockets */
-#undef SELECT
-#endif /* SELECT */
-#include <kernel/OS.h>
-/* #ifdef BE_DR_7 */
-static double time_started = 0.0;
-struct ALARM_STRUCT {
- thread_id thread;
- int time;
-};
-static thread_id alarm_thread = -1;
-static struct ALARM_STRUCT alarm_struct;
-_PROTOTYP( long do_alarm, (void *) );
-_PROTOTYP( unsigned int alarm, (unsigned int) );
-_PROTOTYP( void alarm_expired, (void) );
-/* #endif */ /* BE_DR_7 */
-#endif /* BEOSORBEBOX */
-
-#ifndef xunchar
-#define xunchar(ch) (((ch) - 32 ) & 0xFF ) /* Character to number */
-#endif /* xunchar */
-
-#ifdef CK_ANSIC
-static char *
-xxlast(char *s, char c)
-#else
-static char *
-xxlast(s,c) char *s; char c;
-#endif /* CK_ANSIC */
-/* xxlast */ { /* Last occurrence of character c in string s. */
- int i;
- for (i = (int)strlen(s); i > 0; i--)
- if (s[i-1] == c ) return(s + (i - 1));
- return(NULL);
-}
-
-/* Timeout handler for communication line input functions */
-
-/*ARGSUSED*/
-SIGTYP
-timerh(foo) int foo; {
- ttimoff();
-#ifdef BEOSORBEBOX
-/* #ifdef BE_DR_7 */
- alarm_expired();
-/* #endif */ /* BE_DR_7 */
-#endif /* BEOSORBEBOX */
-#ifdef CK_POSIX_SIG
- siglongjmp(sjbuf,1);
-#else
- longjmp(sjbuf,1);
-#endif /* CK_POSIX_SIG */
-}
-
-/*ARGSUSED*/
-SIGTYP
-xtimerh(foo) int foo; { /* Like timerh() but does */
-#ifdef BEOSORBEBOX /* not reset the timer itself */
-/* #ifdef BE_DR_7 */
- alarm_expired();
-/* #endif */ /* BE_DR_7 */
-#endif /* BEOSORBEBOX */
-#ifdef CK_POSIX_SIG
- siglongjmp(sjbuf,1);
-#else
- longjmp(sjbuf,1);
-#endif /* CK_POSIX_SIG */
-}
-
-
-/* Control-C trap for communication line input functions */
-
-int cc_int; /* Flag */
-SIGTYP (* occt)(); /* For saving old SIGINT handler */
-
-/*ARGSUSED*/
-SIGTYP
-cctrap(foo) int foo; { /* Needs arg for ANSI C */
- cc_int = 1; /* signal() prototype. */
- return;
-}
-
-/* S Y S I N I T -- System-dependent program initialization. */
-
-/*
- * ttgwsiz() returns:
- * 1 tt_rows and tt_cols are known, both altered, both > 0
- * 0 tt_rows and/or tt_cols are known, both altered, one or both <= 0
- * -1 tt_rows and tt_cols are unknown and unaltered
- */
-
-extern int tt_rows, tt_cols;
-
-static int
-xttgwsiz() {
- char *p;
- int rows = 0, cols = 0;
- p = getenv("LINES");
- debug(F110,"xttgwsiz LINES",p,0);
- if (p) {
- rows = atol(p);
- if (rows > 0) {
- p = getenv("COLUMNS");
- debug(F110,"xttgwsiz COLUMNS",p,0);
- if (p) {
- cols = atol(p);
- if (cols > 0) {
- tt_rows = rows;
- tt_cols = cols;
- return(1);
- }
- return(0);
- }
- }
- }
- return(-1);
-}
-
-#ifdef TTLEBUF
-VOID
-le_init() { /* LocalEchoInit() */
- int i;
- for (i = 0; i < LEBUFSIZ; i++)
- le_buf[i] = '\0';
- le_start = 0;
- le_end = 0;
- le_data = 0;
-}
-
-VOID
-le_clean() { /* LocalEchoCleanup() */
- le_init();
- return;
-}
-
-int
-le_inbuf() {
- int rc = 0;
- if (le_start != le_end) {
- rc = (le_end -
- le_start +
- LEBUFSIZ) % LEBUFSIZ;
- }
- debug(F111,"le_inbuf","chars waiting",rc);
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-le_putchar(CHAR ch)
-#else
-le_putchar(ch) CHAR ch;
-#endif /* CK_ANSIC */
-/* le_putchar */ {
-#ifdef COMMENT
- /* In UNIX we do not have another thread taking chars out of the buffer */
- while ((le_start - le_end == 1) ||
- (le_start == 0 && le_end == LEBUFSIZ - 1)) {
- /* Buffer is full */
- debug(F111,"le_putchar","Buffer is Full",ch);
- ReleaseLocalEchoMutex() ;
- msleep(250);
- RequestLocalEchoMutex( SEM_INDEFINITE_WAIT ) ;
- }
-#else
- if ((le_start - le_end + LEBUFSIZ)%LEBUFSIZ == 1) {
- debug(F110,"le_putchar","buffer is full",0);
- return(-1);
- }
-#endif /* COMMENT */
- le_buf[le_end++] = ch;
- if (le_end == LEBUFSIZ)
- le_end = 0;
- le_data = 1;
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-le_puts(CHAR * s, int n)
-#else
-le_puts(s,n) CHAR * s; int n;
-#endif /* CK_ANSIC */
-/* le_puts */ {
- int rc = 0;
- int i = 0;
- CHAR * p = (CHAR *)"le_puts";
- ckhexdump(p,s,n);
- for (i = 0; i < n; i++)
- rc = le_putchar((char)s[i]);
- debug(F101,"le_puts","",rc);
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-le_putstr(CHAR * s)
-#else
-le_putstr(s) CHAR * s;
-#endif /* CK_ANSIC */
-/* le_puts */ {
- CHAR * p;
- int rc = 0;
- p = (CHAR *)"le_putstr";
- ckhexdump(p,s,(int)strlen((char *)s));
- for (p = s; *p && !rc; p++)
- rc = le_putchar(*p);
- return(rc);
-}
-
-int
-#ifdef CK_ANSIC
-le_getchar(CHAR * pch)
-#else /* CK_ANSIC */
-le_getchar(pch) CHAR * pch;
-#endif /* CK_ANSIC */
-/* le_gatchar */ {
- int rc = 0;
- if (le_start != le_end) {
- *pch = le_buf[le_start];
- le_buf[le_start] = 0;
- le_start++;
-
- if (le_start == LEBUFSIZ)
- le_start = 0;
-
- if (le_start == le_end) {
- le_data = 0;
- }
- rc++;
- } else {
- *pch = 0;
- }
- return(rc);
-}
-#endif /* TTLEBUF */
-
-#ifdef COMMENT
-/*
- Some systems like OSF/1 use TIOCGSIZE instead of TIOCGWINSZ.
- But as far as I know, whenever TIOCGSIZE is defined, it is
- equated to TIOCGWINSZ. For cases where this is not done, try this:
-*/
-#ifndef TIOCGWINSZ
-#ifdef TIOCGSIZE
-#define TIOCGWINSZ TIOCGSIZE
-#endif /* TIOCGSIZE */
-#endif /* TIOCGWINSZ */
-#endif /* COMMENT */
-
-static int tt_xpixel = 0, tt_ypixel = 0;
-
-int
-ttgwsiz() {
- int x = 0;
-#ifndef NONAWS
-#ifdef QNX
-/*
- NOTE: TIOCGWSIZ works here too, but only in the 32-bit version.
- This code works for both the 16- and 32-bit versions.
-*/
- extern int dev_size(int, int, int, int *, int *);
- int r, c;
-
- if (dev_size(0, -1, -1, &r, &c) == 0) {
- debug(F101,"ttgwsiz QNX r","",r);
- debug(F101,"ttgwsiz QNX c","",c);
- tt_rows = r;
- tt_cols = c;
- return ((r > 0 && c > 0) ? 1 : 0);
- } else return(xttgwsiz());
-#else /* QNX */
-#ifdef TIOCGWINSZ
-
-/* Note, this was M_UNIX, changed to XENIX to allow cross compilation... */
-#ifdef XENIX /* SCO UNIX 3.2v4.0 */
-#include <sys/stream.h> /* typedef mblk_t needed by ptem.h */
-#include <sys/ptem.h> /* for ttgwsiz() */
-#endif /* XENIX */
-
-#ifdef I386IX /* Ditto for Interactive */
-#include <sys/stream.h>
-#include <sys/ptem.h>
-#endif /* I386IX */
-
-/* Note, the above might be needed for some other older SVR3 Intel makes... */
-
- struct winsize w;
- tt_xpixel = 0;
- tt_ypixel = 0;
-
-#ifdef IKSD
- if (inserver)
- return(xttgwsiz());
-#endif /* IKSD */
- x = ioctl(0, (int)TIOCGWINSZ, (char *)&w);
- debug(F101,"ttgwsiz TIOCGWINSZ","",x);
- if (x < 0) {
- return(xttgwsiz());
- } else if (w.ws_row > 0 && w.ws_col > 0) {
- tt_rows = w.ws_row;
- tt_cols = w.ws_col;
- tt_xpixel = w.ws_xpixel;
- tt_ypixel = w.ws_ypixel;
- debug(F101,"ttgwsiz tt_rows","",tt_rows);
- debug(F101,"ttgwsiz tt_cols","",tt_cols);
- return(1);
- } else {
- debug(F100,"ttgwsiz TIOCGWINSZ 00","",0);
- return(xttgwsiz());
- }
-#else
- return(xttgwsiz());
-#endif /* TIOCGWINSZ */
-#endif /* QNX */
-#endif /* NONAWS */
-}
-
-
-#ifdef RLOGCODE
-_PROTOTYP( int rlog_naws, (void) );
-#endif /* RLOGCODE */
-
-#ifndef NOSIGWINCH
-#ifdef SIGWINCH
-SIGTYP
-winchh(foo) int foo; { /* SIGWINCH handler */
- int x = 0;
-#ifdef CK_TTYFD
-#ifndef VMS
- extern int ttyfd;
-#endif /* VMS */
-#endif /* CK_TTYFD */
- extern int tt_rows, tt_cols, cmd_rows, cmd_cols;
-#ifdef DEBUG
- if (deblog) {
- debug(F100,"***************","",0);
- debug(F100,"SIGWINCH caught","",0);
- debug(F100,"***************","",0);
-#ifdef NETPTY
- debug(F101,"SIGWINCH pty_fork_pid","",pty_fork_pid);
-#endif /* NETPTY */
- }
-#endif /* DEUB */
- signal(SIGWINCH,winchh); /* Re-arm the signal */
- x = ttgwsiz(); /* Get new window size */
- cmd_rows = tt_rows; /* Adjust command screen too */
- cmd_cols = tt_cols;
-
-#ifdef CK_TTYFD
- if /* If we don't have a connection */
-#ifdef VMS /* we're done. */
- (vmsttyfd() == -1)
-#else
- (ttyfd == -1)
-#endif /* VMS */
-#else
- (!local)
-#endif /* CK_TTYFD */
- return;
-
-#ifdef NETPTY
- if (pty_fork_pid > -1) { /* "set host" to a PTY? */
- int x;
-
-#ifdef TIOCSWINSZ
- struct winsize w; /* Resize the PTY */
- errno = 0;
- w.ws_col = tt_cols;
- w.ws_row = tt_rows;
- w.ws_xpixel = tt_xpixel;
- w.ws_ypixel = tt_ypixel;
- x = ioctl(ttyfd,TIOCSWINSZ,&w);
- debug(F101,"winchh TIOCSWINSZ","",x);
- debug(F101,"winchh TIOCSWINSZ errno","",errno);
-#endif /* TIOCSWINSZ */
-
- errno = 0;
- x = kill(pty_fork_pid,SIGWINCH);
- debug(F101,"winchh kill","",x);
- debug(F101,"winchh kill errno","",errno);
- }
-#endif /* NETPTY */
-
-/*
- This should be OK. It might seem that sending this from
- interrupt level could interfere with another TELNET IAC string
- that was in the process of being sent. But we always send
- TELNET strings with a single write(), which should prevent mixups.
- blah_snaws() should protect themselves from being called on the
- wrong kind of connection.
-*/
-#ifdef TCPSOCKET
-#ifndef NOTTGWSIZ
- if (x > 0 && tt_rows > 0 && tt_cols > 0) {
- tn_snaws();
-#ifdef RLOGCODE
- rlog_naws();
-#endif /* RLOGCODE */
- }
-#endif /* NOTTGWSIZ */
-#endif /* TCPSOCKET */
- SIGRETURN;
-}
-#endif /* SIGWINCH */
-#endif /* NOSIGWINCH */
-
-SIGTYP
-sighup(foo) int foo; { /* SIGHUP handler */
- backgrd = 1;
- debug(F100,"***************","",0);
- debug(F100,"SIGHUP received","",0);
- debug(F100,"***************","",0);
- doexit(BAD_EXIT,-1);
- /*NOTREACHED*/
- SIGRETURN; /* Shut picky compilers up... */
-}
-
-#ifdef CK_SCO32V4
-/* Exists but there is no prototype in the header files */
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef SV68R3V6
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef ultrix
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef HPUX6
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef HPUX5
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef PS2AIX10
-_PROTOTYP( char * ttyname, (int) );
-#else
-#ifdef BSD42
-_PROTOTYP( char * ttyname, (int) );
-#endif /* BSD42 */
-#endif /* PS2AIX10 */
-#endif /* HPUX5 */
-#endif /* HPUX6 */
-#endif /* ultrix */
-#endif /* SV68R3V6 */
-#endif /* CK_SCO32V4 */
-
-#ifndef SIGUSR1 /* User-defined signals */
-#define SIGUSR1 30
-#endif /* SIGUSR1 */
-
-#ifndef SIGUSR2
-#define SIGUSR2 31
-#endif /* SIGUSR2 */
-
-/*
- ignorsigs() sets certain signals to SIG_IGN. But when a signal is
- ignored, it remains ignored across exec(), so we have to restore these
- signals before exec(), which is the purpose of restorsigs().
-*/
-static VOID
-ignorsigs() { /* Ignore these signals */
- savquit = signal(SIGQUIT,SIG_IGN); /* Ignore Quit signal */
-
-#ifdef SIGDANGER /* Ignore danger signals */
-/*
- This signal is sent when the system is low on swap space. Processes
- that don't handle it are candidates for termination. If swap space doesn't
- clear out enough, we still might be terminated via kill() -- nothing we can
- do about that! Conceivably, this could be improved by installing a real
- signal handler that warns the user, but that would be pretty complicated,
- since we are not always in control of the screen -- e.g. during remote-mode
- file transfer.
-*/
- savdanger = signal(SIGDANGER,SIG_IGN); /* e.g. in AIX */
-#endif /* SIGDANGER */
-#ifdef SIGPIPE
-/*
- This one comes when a TCP/IP connection is broken by the remote.
- We prefer to catch this situation by examining error codes from write().
-*/
- savpipe = signal(SIGPIPE,SIG_IGN);
-#endif /* SIGPIPE */
- savusr1 = signal(SIGUSR1,SIG_IGN); /* Ignore user-defined signals */
- savusr2 = signal(SIGUSR2,SIG_IGN);
-}
-
-VOID
-restorsigs() { /* Restore these signals */
- (VOID) signal(SIGQUIT,savquit); /* (used in ckufio.c) */
-#ifdef SIGDANGER
- (VOID) signal(SIGDANGER,savdanger);
-#endif /* SIGDANGER */
-#ifdef SIGPIPE
- (VOID) signal(SIGPIPE,savpipe);
-#endif /* SIGPIPE */
- (VOID) signal(SIGUSR1,savusr1);
- (VOID) signal(SIGUSR2,savusr2);
-}
-
-int
-sysinit() {
- int x;
- char * s;
-#ifdef CK_UTSNAME
- struct utsname name;
-#endif /* CK_UTSNAME */
-
- extern char startupdir[];
-/*
- BEFORE ANYTHING ELSE: Initialize the setuid package.
- Change to the user's real user and group ID.
- If this can't be done, don't run at all.
-*/
- x = priv_ini();
-#ifdef SUIDDEBUG
- fprintf(stderr,"PRIV_INI=%d\n",x);
-#endif /* SUIDDEBUG */
- if (x) {
- if (x & 1) fprintf(stderr,"Fatal: setuid failure.\n");
- if (x & 2) fprintf(stderr,"Fatal: setgid failure.\n");
- if (x & 4) fprintf(stderr,"Fatal: C-Kermit setuid to root!\n");
- exit(1);
- }
- signal(SIGINT,SIG_IGN); /* Ignore interrupts at first */
- signal(SIGFPE,SIG_IGN); /* Ignore floating-point exceptions */
- signal(SIGHUP,sighup); /* Catch SIGHUP */
-#ifndef NOSIGWINCH
-#ifdef SIGWINCH
- signal(SIGWINCH,winchh); /* Catch window-size change */
-#endif /* SIGWINCH */
-#endif /* NOSIGWINCH */
-
-#ifdef SIGXFSZ
- signal(SIGXFSZ,SIG_IGN); /* Ignore writing past file limit */
-#endif /* SIGXFSZ */
-
-#ifndef NOJC
-/*
- Get the initial job control state.
- If it is SIG_IGN, that means the shell does not support job control,
- and so we'd better not suspend ourselves.
-*/
-#ifdef SIGTSTP
- jchdlr = signal(SIGTSTP,SIG_IGN);
- if (jchdlr == SIG_IGN) {
- jcshell = 0;
- debug(F100,"sysinit jchdlr: SIG_IGN","",0);
- } else if (jchdlr == SIG_DFL) {
- debug(F100,"sysinit jchdlr: SIG_DFL","",0);
- jcshell = 1;
- } else {
- debug(F100,"sysinit jchdlr: other","",0);
- jcshell = 3;
- }
- (VOID) signal(SIGTSTP,jchdlr); /* Put it back... */
-#endif /* SIGTSTP */
-#endif /* NOJC */
-
- conbgt(0); /* See if we're in the background */
- congm(); /* Get console modes */
-
- (VOID) signal(SIGALRM,SIG_IGN); /* Ignore alarms */
-
- ignorsigs(); /* Ignore some other signals */
-
-#ifdef F_SETFL
- iniflags = fcntl(0,F_GETFL,0); /* Get stdin flags */
-#endif /* F_SETFL */
-
-#ifdef ultrix
- gtty(0,&vanilla); /* Get sgtty info */
-#else
-#ifdef AUX
- set42sig(); /* Don't ask! (hakanson@cs.orst.edu) */
-#endif /* AUX */
-#endif /* ultrix */
-/*
- Warning: on some UNIX systems (SVR4?), ttyname() reportedly opens /dev but
- never closes it. If it is called often enough, we run out of file
- descriptors and subsequent open()'s of other devices or files can fail.
-*/
- s = NULL;
-#ifndef MINIX
- if (isatty(0)) /* Name of controlling terminal */
- s = ttyname(0);
- else if (isatty(1))
- s = ttyname(1);
- else if (isatty(2))
- s = ttyname(2);
- debug(F110,"sysinit ttyname(0)",s,0);
-#endif /* MINIX */
-
-#ifdef BEOS
- if (!dftty)
- makestr(&dftty,s);
-#endif /* BEOS */
-
- if (s)
- ckstrncpy((char *)cttnam,s,DEVNAMLEN+1);
-#ifdef SVORPOSIX
- if (!cttnam[0])
- ctermid(cttnam);
-#endif /* SVORPOSIX */
- if (!cttnam[0])
- ckstrncpy((char *)cttnam,dftty,DEVNAMLEN+1);
- debug(F110,"sysinit CTTNAM",CTTNAM,0);
- debug(F110,"sysinit cttnam",cttnam,0);
-
- ttgwsiz(); /* Get window (screen) dimensions. */
-
-#ifndef NOSYSCONF
-#ifdef _SC_OPEN_MAX
- ckmaxfiles = sysconf(_SC_OPEN_MAX);
-#endif /* _SC_OPEN_MAX */
-#endif /* NOSYSCONF */
-
-#ifdef Plan9
- if (!backgrd) {
- consctlfd = open("/dev/consctl", O_WRONLY);
- /*noisefd = open("/dev/noise", O_WRONLY)*/
- }
- ckxech = 1;
-#endif /* Plan9 */
-
-#ifdef CK_UTSNAME
- if (uname(&name) > -1) {
- ckstrncpy(unm_mch,name.machine,CK_SYSNMLN);
- ckstrncpy(unm_nam,name.sysname,CK_SYSNMLN);
- ckstrncpy(unm_rel,name.release,CK_SYSNMLN);
- ckstrncpy(unm_ver,name.version,CK_SYSNMLN);
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"sysinit uname machine",unm_mch,0);
- debug(F110,"sysinit uname sysname",unm_nam,0);
- debug(F110,"sysinit uname release",unm_rel,0);
- debug(F110,"sysinit uname version",unm_ver,0);
- }
-#endif /* DEBUG */
-
-#ifdef HPUX9PLUS
- if (name.machine[5] == '8')
- hpis800 = 1;
- else
- hpis800 = 0;
- debug(F101,"sysinit hpis800","",hpis800);
-#endif /* HPUX9PLUS */
-#ifdef TRU64
- getsysinfo(GSI_PLATFORM_NAME, unm_mod, CK_SYSNMLN, 0, 0);
- debug(F110,"sysinit getsysinfo model",unm_mod,0);
-#endif /* TRU64 */
-#ifdef SOLARIS25
- sysinfo(SI_PLATFORM, unm_mod, CK_SYSNMLN);
- debug(F110,"sysinit sysinfo model",unm_mod,0);
-#endif /* SOLARIS25 */
- }
-#endif /* CK_UTSNAME */
-
-#ifdef CK_ENVIRONMENT
- {
-#ifdef TNCODE
- extern char tn_env_acct[], tn_env_disp[], tn_env_job[],
- tn_env_prnt[], tn_env_sys[];
-#endif /* TNCODE */
- extern char uidbuf[];
- extern char * whoami();
- char *p;
-#ifdef CKSENDUID
- uidbuf[0] = '\0';
-#ifdef IKSD
- if (!inserver) {
-#endif /* IKSD */
- p = getenv("USER");
- debug(F110,"sysinit uidbuf from USER",uidbuf,0);
- if (!p) p = "";
- if (!*p) {
- p = getenv("LOGNAME");
- debug(F110,"sysinit uidbuf from LOGNAME",uidbuf,0);
- }
- if (!p) p = "";
- if (!*p) {
- p = whoami();
- debug(F110,"sysinit uidbuf from whoami()",uidbuf,0);
- }
- if (!p) p = "";
- ckstrncpy(uidbuf, *p ? p : "UNKNOWN", UIDBUFLEN);
-#ifdef IKSD
- }
-#endif /* IKSD */
- debug(F110,"sysinit final uidbuf",uidbuf,0);
-#endif /* CKSENDUID */
-
-#ifdef TNCODE
- if ((p = getenv("JOB"))) ckstrncpy(tn_env_job,p,63);
- if ((p = getenv("ACCT"))) ckstrncpy(tn_env_acct,p,63);
- if ((p = getenv("PRINTER"))) ckstrncpy(tn_env_prnt,p,63);
- if ((p = getenv("DISPLAY"))) ckstrncpy(tn_env_disp,p,63);
-#ifdef aegis
- ckstrncpy(tn_env_sys,"Aegis",64);
-#else
-#ifdef Plan9
- ckstrncpy(tn_env_sys,"Plan9",64);
-#else
- ckstrncpy(tn_env_sys,"UNIX",64);
-#endif /* Plan9 */
-#endif /* aegis */
-#endif /* TNCODE */
- }
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_SNDLOC
- {
- extern char * tn_loc;
- char *p;
- if (p = getenv("LOCATION"))
- if (tn_loc = (char *)malloc((int)strlen(p)+1))
- strcpy(tn_loc,p); /* safe */
- }
-#endif /* CK_SNDLOC */
-
- ckstrncpy(startupdir, zgtdir(), CKMAXPATH);
- startupdir[CKMAXPATH] = '\0';
- x = strlen(startupdir);
- if (x <= 0) {
- startupdir[0] = '/';
- startupdir[1] = '\0';
- } else if (startupdir[x-1] != '/') {
- startupdir[x] = '/';
- startupdir[x+1] = '\0';
- }
- debug(F110,"sysinit startupdir",startupdir,0);
-#ifdef TTLEBUF
- le_init();
-#endif /* TTLEBUF */
-#ifdef BSD44ORPOSIX
- /* This should catch the ncurses platforms */
- /* Some platforms don't have putenv(), like NeXTSTEP */
- putenv("NCURSES_NO_SETBUF=1");
-#endif /* BSD44ORPOSIX */
- return(0);
-}
-
-/* S Y S C L E A N U P -- System-dependent program cleanup. */
-
-int
-syscleanup() {
-#ifdef F_SETFL
- if (iniflags > -1)
- fcntl(0,F_SETFL,iniflags); /* Restore stdin flags */
-#endif /* F_SETFL */
-#ifdef ultrix
- stty(0,&vanilla); /* Get sgtty info */
-#endif /* ultrix */
-#ifdef NETCMD
- if (ttpid) kill(ttpid,9);
-#endif /* NETCMD */
- return(0);
-}
-
-/* T T O P E N -- Open a tty for exclusive access. */
-
-/*
- Call with:
- ttname: character string - device name or network host name.
- lcl:
- If called with lcl < 0, sets value of lcl as follows:
- 0: the terminal named by ttname is the job's controlling terminal.
- 1: the terminal named by ttname is not the job's controlling terminal.
- But watch out: if a line is already open, or if requested line can't
- be opened, then lcl remains (and is returned as) -1.
- modem:
- Less than zero: ttname is a network host name.
- Zero or greater: ttname is a terminal device name.
- Zero means a local connection (don't use modem signals).
- Positive means use modem signals.
- timo:
- 0 = no timer.
- nonzero = number of seconds to wait for open() to return before timing out.
-
- Returns:
- 0 on success
- -5 if device is in use
- -4 if access to device is denied
- -3 if access to lock directory denied
- -2 upon timeout waiting for device to open
- -1 on other error
-*/
-static int ttotmo = 0; /* Timeout flag */
-/* Flag kept here to avoid being clobbered by longjmp. */
-
-int
-ttopen(ttname,lcl,modem,timo) char *ttname; int *lcl, modem, timo; {
-
-#ifdef BSD44
-#define ctermid(x) strcpy(x,"")
-#else
-#ifdef SVORPOSIX
-#ifndef CIE
- extern char *ctermid(); /* Wish they all had this! */
-#else /* CIE Regulus */
-#define ctermid(x) strcpy(x,"")
-#endif /* CIE */
-#endif /* SVORPOSIX */
-#endif /* BSD44 */
-
-#ifdef ultrix
- int temp = 0;
-#endif /* ultrix */
-
-#ifndef OPENFIRST
- char fullname[DEVNAMLEN+1];
-#endif /* OPENFIRST */
-
- char * fnam; /* Full name after expansion */
-
- int y;
-
-#ifndef pdp11
-#define NAMEFD /* Feature to allow name to be an open file descriptor */
-#endif /* pdp11 */
-
-#ifdef NAMEFD
- char *p;
- debug(F101,"ttopen telnetfd","",telnetfd);
-#endif /* NAMEFD */
-
- debug(F110,"ttopen ttname",ttname,0);
- debug(F110,"ttopen ttnmsv",ttnmsv,0);
- debug(F101,"ttopen modem","",modem);
- debug(F101,"ttopen netconn","",netconn);
- debug(F101,"ttopen ttyfd","",ttyfd);
- debug(F101,"ttopen *lcl","",*lcl);
- debug(F101,"ttopen ttmdm","",ttmdm);
- debug(F101,"ttopen ttnet","",ttnet);
-
- ttpmsk = 0xff;
- lockpid[0] = '\0';
-
- if (ttyfd > -1) { /* If device already opened */
- if (!strncmp(ttname,ttnmsv,DEVNAMLEN)) /* are new & old names equal? */
- return(0); /* Yes, nothing to do - just return */
- ttnmsv[0] = '\0'; /* No, clear out old name */
- ttclos(ttyfd); /* close old connection. */
- }
- wasclosed = 0; /* New connection, not closed yet. */
- ttpipe = 0; /* Assume it's not a pipe */
- ttpty = 0; /* or a pty... */
-
-#ifdef NETCONN
-/*
- This is a bit tricky... Suppose that previously Kermit had dialed a telnet
- modem server ("set host xxx:2001, set modem type usr, dial ..."). Then the
- connection was closed (ttyfd = -1), and then a REDIAL command was given. At
- this point we've obliterated the negative modem type hack, and so would
- treat the IP hostname as a device name, and would then fail because of "No
- such device or directory". But the previous connection has left behind some
- clues, so let's use them...
-*/
- if (ttyfd < 0) { /* Connection is not open */
- if (!strcmp(ttname,ttnmsv)) { /* Old and new names the same? */
- if (((netconn > 0) && (ttmdm < 0)) ||
- ((ttnet > 0) &&
- (!ckstrchr(ttname,'/')) && (ckstrchr(ttname,':')))
- ) {
- int x, rc;
- x = (ttmdm < 0) ? -ttmdm : ttnet;
- rc = netopen(ttname, lcl, x);
- debug(F111,"ttopen REOPEN netopen",ttname,rc);
- if (rc > -1) {
- netconn = 1;
- xlocal = *lcl = 1;
- } else {
- netconn = 0;
- }
- gotsigs = 0;
- return(rc);
- }
- }
- }
-#endif /* NETCONN */
-
-#ifdef MAXNAMLEN
- debug(F100,"ttopen MAXNAMLEN defined","",0);
-#else
- debug(F100,"ttopen MAXNAMLEN *NOT* defined","",0);
-#endif
-
-#ifdef BSD4
- debug(F100,"ttopen BSD4 defined","",0);
-#else
- debug(F100,"ttopen BSD4 *NOT* defined","",0);
-#endif /* BSD4 */
-
-#ifdef BSD42
- debug(F100,"ttopen BSD42 defined","",0);
-#else
- debug(F100,"ttopen BSD42 *NOT* defined","",0);
-#endif /* BSD42 */
-
-#ifdef MYREAD
- debug(F100,"ttopen MYREAD defined","",0);
-#else
- debug(F100,"ttopen MYREAD *NOT* defined","",0);
-#endif /* MYREAD */
-
-#ifdef NETCONN
- if (modem < 0) { /* modem < 0 = code for network */
- int x;
- ttmdm = modem;
- modem = -modem; /* Positive network type number */
- fdflag = 0; /* Stdio not redirected. */
- netconn = 1; /* And it's a network connection */
- debug(F111,"ttopen net",ttname,modem);
-#ifdef NAMEFD
- for (p = ttname; isdigit(*p); p++) ; /* Check for all digits */
- if (*p == '\0' && (telnetfd || x25fd)) { /* Avoid X.121 addresses */
- ttyfd = atoi(ttname); /* Is there a way to test it's open? */
- ttfdflg = 1; /* We got an open file descriptor */
- debug(F111,"ttopen net ttfdflg",ttname,ttfdflg);
- debug(F101,"ttopen net ttyfd","",ttyfd);
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */
- x = 1; /* Return code is "good". */
- if (telnetfd) {
- ttnet = NET_TCPB;
- if (ttnproto != NP_TCPRAW)
- ttnproto = NP_TELNET;
-#ifdef SUNX25
- } else if (x25fd) {
- ttnet = NET_SX25;
- ttnproto = NP_NONE;
-#endif /* SUNX25 */
- }
- } else { /* Host name or address given */
-#ifdef NETPTY
- if (modem == NET_PTY) {
- int x;
- if (nopush) {
- debug(F100,"ttopen PTY: nopush","",0);
- return(-1);
- }
- ttnet = NET_PTY;
- ttnproto = NP_NONE;
- netconn = 1; /* but we don't use network i/o */
- ttpty = 1;
- debug(F110,"ttopen PTY",ttname,0);
- x = do_pty(&ttyfd,ttname,0);
- if (x > -1) {
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN);
- xlocal = *lcl = 1; /* It's local */
- } else {
- ttpty = 0;
- netconn = 0;
- }
- gotsigs = 0;
- return(x);
- }
-#endif /* NETPTY */
-#ifdef NETCMD
-/*
- dup2() is not available on older System V platforms like AT&T 3Bx. For
- those systems we punt by not defining NETCMD, but we might be able to do
- better -- see workarounds for this problem in ckufio.c (search for dup2).
-*/
- if (modem == NET_CMD) {
- if (nopush) {
- debug(F100,"ttopen pipe: nopush","",0);
- return(-1);
- }
- if (pipe(pipe0) || pipe(pipe1)) {
- perror("Pipe error");
- return(-1);
- }
- ttpid = fork(); /* Make a fork */
-
- switch (ttpid) {
- case -1: /* Error making fork */
- close(pipe0[0]);
- close(pipe0[1]);
- close(pipe1[0]);
- close(pipe1[1]);
- perror("Fork error");
- return(-1);
- case 0: /* Child. */
- close(pipe0[0]);
- close(pipe1[1]);
- dup2(pipe0[1], 1);
- close(pipe0[1]);
- dup2(pipe1[0], 0);
- close(pipe1[0]);
- system(ttname);
- _exit(0);
- default: /* Parent */
- close(pipe0[1]);
- close(pipe1[0]);
- fdin = pipe0[0]; /* Read from pipe */
- fdout = pipe1[1]; /* Write to pipe */
- ttout = fdopen(fdout,"w"); /* Get stream so we can */
- if (!ttout) { /* make it unbuffered. */
- perror("fdopen failure");
- return(-1);
- }
- setbuf(ttout,NULL);
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN);
- xlocal = *lcl = 1; /* It's local */
- netconn = 1; /* Call it a network connection */
- ttmdm = modem; /* Remember network type */
- ttyfd = fdin;
- ttpipe = 1;
- gotsigs = 0;
- return(0);
- }
- }
-#endif /* NETCMD */
-#endif /* NAMEFD */
- x = netopen(ttname, lcl, modem); /* (see ckcnet.h) */
- if (x > -1) {
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN);
- } else netconn = 0;
-#ifdef NAMEFD
- }
-#endif /* NAMEFD */
-
-#ifdef sony_news /* Sony NEWS */
- if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get Kanji mode */
- perror("ttopen error getting Kanji mode (network)");
- debug(F111,"ttopen error getting Kanji mode","network",0);
- km_ext = -1; /* Make sure this stays undefined. */
- }
-#endif /* sony_news */
-
- xlocal = *lcl = 1; /* Network connections are local. */
- debug(F101,"ttopen net x","",x);
-#ifdef COMMENT
-/* Let netopen() do this */
- if (x > -1 && !x25fd)
- x = tn_ini(); /* Initialize TELNET protocol */
-#endif /* COMMENT */
- gotsigs = 0;
- return(x);
- } else { /* Terminal device */
-#endif /* NETCONN */
-
-#ifdef NAMEFD
-/*
- This code lets you give Kermit an open file descriptor for a serial
- communication device, rather than a device name. Kermit assumes that the
- line is already open, locked, conditioned with the right parameters, etc.
-*/
- for (p = ttname; isdigit(*p); p++) ; /* Check for all-digits */
- if (*p == '\0') {
- ttyfd = atoi(ttname); /* Is there a way to test it's open? */
- debug(F111,"ttopen got open fd",ttname,ttyfd);
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */
- if (ttyfd >= 0 && ttyfd < 3) /* If it's stdio... */
- xlocal = *lcl = 0; /* we're in remote mode */
- else /* otherwise */
- xlocal = *lcl = 1; /* local mode. */
- netconn = 0; /* Assume it's not a network. */
- tvtflg = 0; /* Might need to initialize modes. */
- ttmdm = modem; /* Remember modem type. */
- fdflag = 0; /* Stdio not redirected. */
- ttfdflg = 1; /* Flag we were opened this way. */
- debug(F111,"ttopen non-net ttfdflg",ttname,ttfdflg);
- debug(F101,"ttopen non-net ttyfd","",ttyfd);
-
-#ifdef sony_news /* Sony NEWS */
- /* Get device Kanji mode */
- if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) {
- perror("ttopen error getting Kanji mode");
- debug(F101,"ttopen error getting Kanji mode","",0);
- km_ext = -1; /* Make sure this stays undefined. */
- }
-#endif /* sony_news */
- gotsigs = 0;
- return(0); /* Return success */
- }
-#endif /* NAMEFD */
-#ifdef NETCONN
- }
-#endif /* NETCONN */
-
-/* Here we have to open a serial device of the given name. */
-
- netconn = 0; /* So it's not a network connection */
- occt = signal(SIGINT, cctrap); /* Set Control-C trap, save old one */
- sigint_ign = 0;
-
- tvtflg = 0; /* Flag for use by ttvt(). */
- /* 0 = ttvt not called yet for this device */
-
- fdflag = (!isatty(0) || !isatty(1)); /* Flag for stdio redirected */
- debug(F101,"ttopen fdflag","",fdflag);
-
- ttmdm = modem; /* Make this available to other fns */
- xlocal = *lcl; /* Make this available to other fns */
-
-/* Code for handling bidirectional tty lines goes here. */
-/* Use specified method for turning off logins and suppressing getty. */
-
-#ifdef ACUCNTRL
- /* Should put call to priv_on() here, but that would be very risky! */
- acucntrl("disable",ttname); /* acucntrl() program. */
- /* and priv_off() here... */
-#else
-#ifdef ATT7300
- if ((attmodem & DOGETY) == 0) /* offgetty() program. */
- attmodem |= offgetty(ttname); /* Remember response. */
-#endif /* ATT7300 */
-#endif /* ACUCNTRL */
-
-#ifdef OPENFIRST
-/*
- 1985-2001: opens device first then gets lock; reason:
- Kermit usually has to run setuid or setgid in order to create a lockfile.
- If you give a SET LINE command for a device that happens to be your job's
- controlling terminal, Kermit doesn't have to create a lockfile, and in fact
- should not create one, and would fail if it tried to if it did not have the
- required privileges. But you can't find out if two tty device names are
- equivalent until you have a file descriptor that you can give to ttyname().
- But this can cause a race condition between Kermit and [m]getty. So see
- the [#]else part...
-*/
-
-/*
- In the following section, we open the tty device for read/write.
- If a modem has been specified via "set modem" prior to "set line"
- then the O_NDELAY parameter is used in the open, provided this symbol
- is defined (e.g. in fcntl.h), so that the program does not hang waiting
- for carrier (which in most cases won't be present because a connection
- has not been dialed yet). O_NDELAY is removed later on in ttopen(). It
- would make more sense to first determine if the line is local before
- doing this, but because ttyname() requires a file descriptor, we have
- to open it first. See do_open().
-
- Now open the device using the desired treatment of carrier.
- If carrier is REQUIRED, then open could hang forever, so an optional
- timer is provided. If carrier is not required, the timer should never
- go off, and should do no harm...
-*/
- ttotmo = 0; /* Flag no timeout */
- debug(F101,"ttopen timo","",timo);
- debug(F101,"ttopen xlocal","",xlocal);
- if (timo > 0) {
- int xx;
- saval = signal(SIGALRM,timerh); /* Timed, set up timer. */
- xx = alarm(timo); /* Timed open() */
- debug(F101,"ttopen alarm","",xx);
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) {
- ttotmo = 1; /* Flag timeout. */
- } else ttyfd = do_open(ttname);
- ttimoff();
- debug(F111,"ttopen","modem",modem);
- debug(F101,"ttopen ttyfd","",ttyfd);
- debug(F101,"ttopen alarm return","",ttotmo);
- } else {
- errno = 0;
- ttyfd = do_open(ttname);
- }
- debug(F111,"ttopen ttyfd",ttname,ttyfd);
- if (ttyfd < 0) { /* If couldn't open, fail. */
- debug(F101,"ttopen errno","",errno);
- if (errno > 0 && !quiet)
- perror(ttname); /* Print message */
-
-#ifdef ATT7300
- if (attmodem & DOGETY) /* was getty(1m) running before us? */
- ongetty(ttnmsv); /* yes, restart on tty line */
- attmodem &= ~DOGETY; /* no phone in use, getty restored */
-#else
-#ifdef ACUCNTRL
- /* Should put call to priv_on() here, but that would be risky! */
- acucntrl("enable",ttname); /* acucntrl() program. */
- /* and priv_off() here... */
-#endif /* ACUNTRL */
-#endif /* ATT7300 */
-
- signal(SIGINT,occt); /* Put old Ctrl-C trap back. */
- if (errno == EACCES) { /* Device is protected against user */
- debug(F110,"ttopen EACCESS",ttname,0); /* Return -4 */
- return(-4);
- } else return(ttotmo ? -2 : -1); /* Otherwise -2 if timeout, or -1 */
- }
-
-#ifdef QNX
- {
- extern int qnxportlock;
- x = qnxopencount();
- debug(F101,"ttopen qnxopencount","",x);
- debug(F101,"ttopen qnxportlock","",qnxportlock);
- if (x < 0 && qnxportlock) {
- ttclos(0);
- printf("?Can't get port open count\n");
- printf("(Try again with SET QNX-PORT-LOCK OFF)\n");
- return(-1); /* Indicate device is in use */
- }
- if (x > 1) { /* 1 == me */
- if (qnxportlock)
- ttclos(0);
- return(-2); /* Indicate device is in use */
- else if (!quiet)
- printf("WARNING: \"%s\" looks busy...\n",ttdev);
- }
- }
-#endif /* QNX */
-
-#ifdef Plan9
- /* take this opportunity to open the control channel */
- if (p9openttyctl(ttname) < 0)
-#else
- /* Make sure it's a real tty. */
- if (!ttfdflg && !isatty(ttyfd) && strcmp(ttname,"/dev/null"))
-#endif /* Plan9 */
- {
- fprintf(stderr,"%s is not a terminal device\n",ttname);
- debug(F111,"ttopen not a tty",ttname,errno);
- close(ttyfd);
- ttyfd = -1;
- wasclosed = 1;
- signal(SIGINT,occt);
- return(-1);
- }
-
-#ifdef aegis
- /* Apollo C runtime claims that console pads are tty devices, which
- * is reasonable, but they aren't any good for packet transfer. */
- ios_$inq_type_uid((short)ttyfd, ttyuid, st);
- if (st.all != status_$ok) {
- fprintf(stderr, "problem getting tty object type: ");
- error_$print(st);
- } else if (ttyuid != sio_$uid) { /* reject non-SIO lines */
- close(ttyfd); ttyfd = -1;
- wasclosed = 1;
- errno = ENOTTY; perror(ttname);
- signal(SIGINT,occt);
- return(-1);
- }
-#endif /* aegis */
-
- sigint_ign = (occt == SIG_IGN) ? 1 : 0;
-
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Keep copy of name locally. */
-
-/* Caller wants us to figure out if line is controlling tty */
-
- if (*lcl < 0) {
- if (strcmp(ttname,CTTNAM) == 0) { /* "/dev/tty" always remote */
- xlocal = 0;
- debug(F111,"ttopen ttname=CTTNAM",ttname,xlocal);
- } else if (strcmp(ttname,cttnam) == 0) {
- xlocal = 0;
- debug(F111,"ttopen ttname=cttnam",ttname,xlocal);
- } else if (cttnam[0]) {
-#ifdef BEBOX_DR7
- x = ttnmsv; /* ttyname() is broken */
-#else
- x = ttyname(ttyfd); /* Get real name of ttname. */
-#endif /* BEBOX_DR7 */
- if (!x) x = "";
- if (*x)
- xlocal = ((strncmp(x,cttnam,DEVNAMLEN) == 0) ? 0 : 1);
- else
- xlocal = 1;
- debug(F111,"ttopen ttyname(ttyfd) xlocal",x,xlocal);
- }
- }
-
-#ifndef NOFDZERO
-/* Note, the following code was added so that Unix "idle-line" snoopers */
-/* would not think Kermit was idle when it was transferring files, and */
-/* maybe log people out. */
- if (xlocal == 0) { /* Remote mode */
- if (fdflag == 0) { /* Standard i/o is not redirected */
- debug(F100,"ttopen setting ttyfd = 0","",0);
-#ifdef LYNXOS
- /* On Lynx OS, fd 0 is open for read only. */
- dup2(ttyfd,0);
-#endif /* LYNXOS */
- close(ttyfd); /* Use file descriptor 0 */
- ttyfd = 0;
- } else { /* Standard i/o is redirected */
- debug(F101,"ttopen stdio redirected","",ttyfd);
- }
- }
-#endif /* NOFDZERO */
-
-/* Now check if line is locked -- if so fail, else lock for ourselves */
-/* Note: After having done this, don't forget to delete the lock if you */
-/* leave ttopen() with an error condition. */
-
- lkf = 0; /* Check lock */
- if (xlocal > 0) {
- int xx; int xpid;
- if ((xx = ttlock(ttname)) < 0) { /* Can't lock it. */
- debug(F111,"ttopen ttlock fails",ttname,xx);
- /* WARNING - This close() can hang if tty is an empty socket... */
- close(ttyfd); /* Close the device. */
- ttyfd = -1; /* Erase its file descriptor. */
- wasclosed = 1;
- signal(SIGINT,occt); /* Put old SIGINT back. */
- sigint_ign = (occt == SIG_IGN) ? 1 : 0;
- if (xx == -2) { /* If lockfile says device in use, */
-#ifndef NOUUCP
- debug(F111,"ttopen reading lockfile pid",flfnam,xx);
- xpid = ttrpid(flfnam); /* Try to read pid from lockfile */
- if (xpid > -1) { /* If we got a pid */
- if (!quiet)
- printf("Locked by process %d\n",xpid); /* tell them. */
- sprintf(lockpid,"%d",xpid); /* Record it too */
- debug(F110,"ttopen lockpid",lockpid,0);
- } else if (*flfnam) {
- extern char *DIRCMD;
- char *p = NULL;
- int x;
- x = (int)strlen(flfnam) + (int)strlen(DIRCMD) + 2;
- p = malloc(x); /* Print a directory listing. */
-/*
- Note: priv_on() won't help here, because we do not pass privs along to
- to inferior processes, in this case ls. So if the real user does not have
- directory-listing access to the lockfile directory, this will result in
- something like "not found". That's why we try this only as a last resort.
-*/
- if (p) { /* If we got the space... */
- ckmakmsg(p,x,DIRCMD," ",flfnam,NULL);
- zsyscmd(p); /* Get listing. */
- if (p) { /* free the space */
- free(p);
- p = NULL;
- }
- }
- }
-#endif /* NOUUCP */
- return(-5); /* Code for device in use */
- } else return(-3); /* Access denied */
- } else lkf = 1;
- }
-#else /* OPENFIRST */
-
-/*
- 27 Oct 2001: New simpler code that gets the lock first and then opens the
- device, which eliminates the race condition. The downside is you can no
- longer say "set line /dev/ttyp0" or whatever, where /dev/ttyp0 is your login
- terminal, without trying to create a lockfile, which fails if C-Kermit lacks
- privs, and if it succeeds, it has created a lockfile where it didn't create
- one before.
-*/
- xlocal = *lcl; /* Is the device my login terminal? */
- debug(F111,"ttopen xlocal","A",xlocal);
- fnam = ttname;
- if (strcmp(ttname,CTTNAM) && netconn == 0) {
- if (zfnqfp(ttname,DEVNAMLEN+1,fullname)) {
- if ((int)strlen(fullname) > 0)
- fnam = fullname;
- }
- }
- debug(F110,"ttopen fnam",fnam,0);
- if (xlocal < 0) {
- xlocal = (strcmp(fnam,CTTNAM) != 0);
- }
- debug(F111,"ttopen xlocal","B",xlocal);
-
- lkf = 0; /* No lock yet */
- if (xlocal > 0) { /* If not... */
- int xx; int xpid;
- xx = ttlock(fnam); /* Try to lock it. */
- debug(F101,"ttopen ttlock","",xx);
- if (xx < 0) { /* Can't lock it. */
- debug(F111,"ttopen ttlock fails",fnam,xx);
- if (xx == -2) { /* If lockfile says device in use, */
-#ifndef NOUUCP
- debug(F111,"ttopen reading lockfile pid",flfnam,xx);
- xpid = ttrpid(flfnam); /* Try to read pid from lockfile */
- if (xpid > -1) { /* If we got a pid */
- if (!quiet)
- printf("Locked by process %d\n",xpid); /* tell them. */
- ckstrncpy(lockpid,ckitoa(xpid),16);
- debug(F110,"ttopen lockpid",lockpid,0);
-#ifndef NOPUSH
- } else if (flfnam[0] && !nopush) {
- extern char *DIRCMD;
- char *p = NULL;
- int x;
- x = (int)strlen(flfnam) + (int)strlen(DIRCMD) + 2;
- p = malloc(x); /* Print a directory listing. */
-/*
- Note: priv_on() won't help here, because we do not pass privs along to
- to inferior processes, in this case ls. So if the real user does not have
- directory-listing access to the lockfile directory, this will result in
- something like "not found". That's why we try this only as a last resort.
-*/
- if (p) { /* If we got the space... */
- ckmakmsg(p,x,DIRCMD," ",flfnam,NULL);
- zsyscmd(p); /* Get listing. */
- if (p) { /* free the space */
- free(p);
- p = NULL;
- }
- }
-#endif /* NOPUSH */
- }
-#endif /* NOUUCP */
- return(-5); /* Code for device in use */
- } else return(-3); /* Access denied */
- } else lkf = 1;
- }
- /* Have lock -- now it's safe to open the device */
-
- debug(F101,"ttopen lkf","",lkf);
- debug(F101,"ttopen timo","",timo);
-
- ttotmo = 0; /* Flag no timeout */
- if (timo > 0) {
- int xx;
- saval = signal(SIGALRM,timerh); /* Timed, set up timer. */
- xx = alarm(timo); /* Timed open() */
- debug(F101,"ttopen alarm","",xx);
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) {
- ttotmo = 1; /* Flag timeout. */
- } else {
- ttyfd = do_open(fnam);
- }
- ttimoff();
- debug(F111,"ttopen timed ttyfd",fnam,ttyfd);
- } else {
- errno = 0;
- ttyfd = do_open(fnam);
- debug(F111,"ttopen untimed ttyfd",fnam,ttyfd);
- }
- if (ttyfd < 0) { /* If couldn't open, fail. */
- debug(F111,"ttopen errno",fnam,errno);
- debug(F111,"ttopen xlocal","C",xlocal);
- if (xlocal == 0) {
- debug(F100,"ttopen substituting 0","",0);
- ttyfd = 0;
- } else {
- if (errno > 0 && !quiet) {
- debug(F111,"ttopen perror",fnam,errno);
- perror(fnam); /* Print message */
- }
- if (ttunlck()) /* Release the lock file */
- fprintf(stderr,"Warning, problem releasing lock\r\n");
- }
- }
-
- if (ttyfd < 0) { /* ttyfd is still < 0? */
-#ifdef ATT7300
- if (attmodem & DOGETY) /* was getty(1m) running before us? */
- ongetty(ttnmsv); /* yes, restart on tty line */
- attmodem &= ~DOGETY; /* no phone in use, getty restored */
-#else
-#ifdef ACUCNTRL
- /* Should put call to priv_on() here, but that would be risky! */
- acucntrl("enable",fnam); /* acucntrl() program. */
- /* and priv_off() here... */
-#endif /* ACUNTRL */
-#endif /* ATT7300 */
-
- signal(SIGINT,occt); /* Put old Ctrl-C trap back. */
- if (errno == EACCES) { /* Device is protected against user */
- debug(F110,"ttopen EACCESS",fnam,0); /* Return -4 */
- return(-4);
- } else return(ttotmo ? -2 : -1); /* Otherwise -2 if timeout, or -1 */
- }
-
-/* Make sure it's a real tty. */
-
-#ifdef Plan9
- /* take this opportunity to open the control channel */
- if (p9openttyctl(fnam) < 0)
-#else
- if (!ttfdflg && !isatty(ttyfd) && strcmp(fnam,"/dev/null"))
-#endif /* Plan9 */
- {
- fprintf(stderr,"%s is not a terminal device\n",fnam);
- debug(F111,"ttopen not a tty",fnam,errno);
- if (ttunlck()) /* Release the lock file */
- fprintf(stderr,"Warning, problem releasing lock\r\n");
- close(ttyfd);
- ttyfd = -1;
- wasclosed = 1;
- signal(SIGINT,occt);
- return(-1);
- }
-
-#ifdef aegis
- /*
- Apollo C runtime claims that console pads are tty devices, which
- is reasonable, but they aren't any good for packet transfer.
- */
- ios_$inq_type_uid((short)ttyfd, ttyuid, st);
- if (st.all != status_$ok) {
- fprintf(stderr, "problem getting tty object type: ");
- error_$print(st);
- } else if (ttyuid != sio_$uid) { /* Reject non-SIO lines */
- close(ttyfd); ttyfd = -1;
- wasclosed = 1;
- errno = ENOTTY; perror(fnam);
- signal(SIGINT,occt);
- return(-1);
- }
-#endif /* aegis */
-
- sigint_ign = (occt == SIG_IGN) ? 1 : 0;
-
- ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Keep copy of name locally. */
-
-/* Caller wants us to figure out if line is controlling tty */
-
- if (*lcl < 0) {
- char * s;
- if (strcmp(fnam,CTTNAM) == 0) { /* "/dev/tty" always remote */
- xlocal = 0;
- debug(F111,"ttopen fnam=CTTNAM",fnam,xlocal);
- } else if (strcmp(fnam,cttnam) == 0) {
- xlocal = 0;
- debug(F111,"ttopen fnam=cttnam",fnam,xlocal);
- } else if (cttnam[0]) {
-#ifdef BEBOX_DR7
- s = ttnmsv; /* ttyname() is broken */
-#else
- s = ttyname(ttyfd); /* Get real name of ttname. */
-#endif /* BEBOX_DR7 */
- if (!s) s = "";
- if (*s)
- xlocal = ((strncmp(s,cttnam,DEVNAMLEN) == 0) ? 0 : 1);
- else
- xlocal = 1;
- debug(F111,"ttopen ttyname(ttyfd) xlocal",s,xlocal);
- }
- }
-
-#ifndef NOFDZERO
-/* Note, the following code was added so that Unix "idle-line" snoopers */
-/* would not think Kermit was idle when it was transferring files, and */
-/* maybe log people out. */
- if (xlocal == 0) { /* Remote mode */
- if (fdflag == 0) { /* Standard i/o is not redirected */
- debug(F100,"ttopen setting ttyfd = 0","",0);
-#ifdef LYNXOS
- /* On Lynx OS, fd 0 is open for read only. */
- dup2(ttyfd,0);
-#endif /* LYNXOS */
- close(ttyfd); /* Use file descriptor 0 */
- ttyfd = 0;
- } else { /* Standard i/o is redirected */
- debug(F101,"ttopen stdio redirected","",ttyfd);
- }
- }
-#endif /* NOFDZERO */
-#endif /* OPENFIRST */
-
-/* Got the line, now set the desired value for local. */
-
- if (*lcl != 0) *lcl = xlocal;
-
-/* Some special stuff for v7... */
-
-#ifdef V7
-#ifndef MINIX
- if (kmem[TTY] < 0) { /* If open, then skip this. */
- qaddr[TTY] = initrawq(ttyfd); /* Init the queue. */
- if ((kmem[TTY] = open("/dev/kmem", 0)) < 0) {
- fprintf(stderr, "Can't read /dev/kmem in ttopen.\n");
- perror("/dev/kmem");
- exit(1);
- }
- }
-#endif /* !MINIX */
-#endif /* V7 */
-
-/* No failure returns after this point */
-
-#ifdef ultrix
- ioctl(ttyfd, TIOCMODEM, &temp);
-#ifdef TIOCSINUSE
- if (xlocal && ioctl(ttyfd, TIOCSINUSE, NULL) < 0) {
- if (!quiet)
- perror(fnam);
- }
-#endif /* TIOCSINUSE */
-#endif /* ultrix */
-
-/* Get tty device settings */
-
-#ifdef BSD44ORPOSIX /* POSIX */
- tcgetattr(ttyfd,&ttold);
- debug(F101,"ttopen tcgetattr ttold.c_lflag","",ttold.c_lflag);
- tcgetattr(ttyfd,&ttraw);
- debug(F101,"ttopen tcgetattr ttraw.c_lflag","",ttraw.c_lflag);
- tcgetattr(ttyfd,&tttvt);
- debug(F101,"ttopen tcgetattr tttvt.c_lflag","",tttvt.c_lflag);
-#else /* BSD, V7, and all others */
-#ifdef ATTSV /* AT&T UNIX */
- ioctl(ttyfd,TCGETA,&ttold);
- debug(F101,"ttopen ioctl TCGETA ttold.c_lflag","",ttold.c_lflag);
- ioctl(ttyfd,TCGETA,&ttraw);
- ioctl(ttyfd,TCGETA,&tttvt);
-#else
-#ifdef BELLV10
- ioctl(ttyfd,TIOCGETP,&ttold);
- debug(F101,"ttopen BELLV10 ttold.sg_flags","",ttold.sg_flags);
- ioctl(ttyfd,TIOCGDEV,&tdold);
- debug(F101,"ttopen BELLV10 tdold.flags","",tdold.flags);
-#else
- gtty(ttyfd,&ttold);
- debug(F101,"ttopen gtty ttold.sg_flags","",ttold.sg_flags);
-#endif /* BELLV10 */
-
-#ifdef sony_news /* Sony NEWS */
- if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get console Kanji mode */
- perror("ttopen error getting Kanji mode");
- debug(F101,"ttopen error getting Kanji mode","",0);
- km_ext = -1; /* Make sure this stays undefined. */
- }
-#endif /* sony_news */
-
-#ifdef TIOCGETC
- debug(F100,"ttopen TIOCGETC","",0);
- tcharf = 0; /* In remote mode, also get */
- if (xlocal == 0) { /* special characters */
- if (ioctl(ttyfd,TIOCGETC,&tchold) < 0) {
- debug(F100,"ttopen TIOCGETC failed","",0);
- } else {
- tcharf = 1; /* It worked. */
- ioctl(ttyfd,TIOCGETC,&tchnoi); /* Get another copy */
- debug(F100,"ttopen TIOCGETC ok","",0);
- }
- }
-#else
- debug(F100,"ttopen TIOCGETC not defined","",0);
-#endif /* TIOCGETC */
-
-#ifdef TIOCGLTC
- debug(F100,"ttopen TIOCGLTC","",0);
- ltcharf = 0; /* In remote mode, also get */
- if (xlocal == 0) { /* local special characters */
- if (ioctl(ttyfd,TIOCGLTC,<chold) < 0) {
- debug(F100,"ttopen TIOCGLTC failed","",0);
- } else {
- ltcharf = 1; /* It worked. */
- ioctl(ttyfd,TIOCGLTC,<chnoi); /* Get another copy */
- debug(F100,"ttopen TIOCGLTC ok","",0);
- }
- }
-#else
- debug(F100,"ttopen TIOCGLTC not defined","",0);
-#endif /* TIOCGLTC */
-
-#ifdef TIOCLGET
- debug(F100,"ttopen TIOCLGET","",0);
- lmodef = 0;
- if (ioctl(ttyfd,TIOCLGET,&lmode) < 0) {
- debug(F100,"ttopen TIOCLGET failed","",0);
- } else {
- lmodef = 1;
- debug(F100,"ttopen TIOCLGET ok","",0);
- }
-#endif /* TIOCLGET */
-
-#ifdef BELLV10
- ioctl(ttyfd,TIOCGETP,&ttraw);
- ioctl(ttyfd,TIOCGETP,&tttvt);
-#else
- gtty(ttyfd,&ttraw); /* And a copy of it for packets*/
- gtty(ttyfd,&tttvt); /* And one for virtual tty service */
-#endif /* BELLV10 */
-
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-
-/* Section for changing line discipline. It's restored in ttres(). */
-
-#ifdef AIXRS
-#ifndef AIX41
- { union txname ld_name; int ld_idx = 0;
- ttld = 0;
- do {
- ld_name.tx_which = ld_idx++;
- ioctl(ttyfd, TXGETCD, &ld_name);
- if (!strncmp(ld_name.tx_name, "rts", 3))
- ttld |= 1;
- } while (*ld_name.tx_name);
- debug(F101,"AIX line discipline","",ttld);
- }
-#endif /* AIX41 */
-#endif /* AIXRS */
-
-#ifdef BSD41
-/* For 4.1BSD only, force "old" tty driver, new one botches TANDEM. */
- { int k;
- ioctl(ttyfd, TIOCGETD, &ttld); /* Get and save line discipline */
- debug(F101,"4.1bsd line discipline","",ttld);
- k = OTTYDISC; /* Switch to "old" discipline */
- k = ioctl(ttyfd, TIOCSETD, &k);
- debug(F101,"4.1bsd tiocsetd","",k);
- }
-#endif /* BSD41 */
-
-#ifdef aegis
- /* This was previously done before the last two TCGETA or gtty above,
- * in both the ATTSV and not-ATTSV case. If it is not okay to have only
- * one copy if it here instead, give us a shout!
- */
- sio_$control((short)ttyfd, sio_$raw_nl, false, st);
- if (xlocal) { /* ignore breaks from local line */
- sio_$control((short)ttyfd, sio_$int_enable, false, st);
- sio_$control((short)ttyfd, sio_$quit_enable, false, st);
- }
-#endif /* aegis */
-
-#ifdef VXVE
- ttraw.c_line = 0; /* STTY line 0 for VX/VE */
- tttvt.c_line = 0; /* STTY line 0 for VX/VE */
- ioctl(ttyfd,TCSETA,&ttraw);
-#endif /* vxve */
-
-/* If O_NDELAY was used during open(), then remove it now. */
-
-#ifdef O_NDELAY
- debug(F100,"ttopen O_NDELAY","",0);
- if (xlocal > 0) {
- if (fcntl(ttyfd, F_GETFL, 0) & O_NDELAY) {
- debug(F100,"ttopen fcntl O_NDELAY","",0);
-#ifndef aegis
- if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0) {
- debug(F100,"ttopen fcntl failure to unset O_NDELAY","",0);
- perror("Can't unset O_NDELAY");
- }
-#endif /* aegis */
- /* Some systems, notably Xenix (don't know how common this is in
- * other systems), need special treatment to get rid of the O_NDELAY
- * behaviour on read() with respect to carrier presence (i.e. read()
- * returning 0 when carrier absent), even though the above fcntl()
- * is enough to make read() wait for input when carrier is present.
- * This magic, in turn, requires CLOCAL for working when the carrier
- * is absent. But if xlocal == 0, presumably you already have CLOCAL
- * or you have a carrier, otherwise you wouldn't be running this.
- */
- debug(F101,"ttopen xlocal","",xlocal);
-#ifdef ATTSV
-#ifdef BSD44ORPOSIX
-#ifdef COMMENT /* 12 Aug 1997 */
-#ifdef __bsdi__
- if (xlocal)
- ttraw.c_cflag |= CLOCAL;
-#else
-#ifdef __FreeBSD__
- if (xlocal)
- ttraw.c_cflag |= CLOCAL;
-#endif /* __FreeBSD__ */
-#endif /* __bsdi__ */
-#else /* Not COMMENT */
-#ifdef CLOCAL
- if (xlocal) /* Unset this if it's defined. */
- ttraw.c_cflag |= CLOCAL;
-#endif /* CLOCAL */
-#endif /* COMMENT */
- debug(F101,"ttopen BSD44ORPOSIX calling tcsetattr","",TCSADRAIN);
- if (tcsetattr(ttyfd, TCSADRAIN, &ttraw) < 0) {
- debug(F100,"ttopen POSIX tcseattr fails","",0);
- perror("tcsetattr");
- }
-#else /* !BSD44ORPOSIX */
- if (xlocal) {
- ttraw.c_cflag |= CLOCAL;
- debug(F100,"ttopen calling ioctl(TCSETA)","",0);
- errno = 0;
- if (ioctl(ttyfd, TCSETA, &ttraw) < 0) {
- debug(F101,"ttopen ioctl(TCSETA) fails","",errno);
- perror("ioctl(TCSETA)");
- }
- }
-#endif /* BSD44ORPOSIX */
-#endif /* ATTSV */
-#ifndef NOCOTFMC /* = NO Close(Open()) To Force Mode Change */
-/* Reportedly lets uugetty grab the device in SCO UNIX 3.2 / XENIX 2.3 */
- debug(F100,"ttopen executing close/open","",0);
- close( priv_opn(fnam, O_RDWR) ); /* Magic to force change. */
-#endif /* NOCOTFMC */
- }
- }
-#endif /* O_NDELAY */
-
-/* Instruct the system how to treat the carrier, and set a few other tty
- * parameters.
- *
- * This also undoes the temporary setting of CLOCAL that may have been done
- * for the close(open()) above (except in Xenix). Also throw in ~ECHO, to
- * prevent the other end of the line from sitting there talking to itself,
- * producing garbage when the user performs a connect.
- *
- * SCO Xenix unfortunately seems to ignore the actual state of CLOCAL.
- * Now it thinks CLOCAL is always on. It seems the only real solution for
- * Xenix is to switch between the lower and upper case device names.
- *
- * This section may at some future time expand into setting a complete
- * collection of tty parameters, or call a function shared with ttpkt()/
- * ttvt() that does so. On the other hand, the initial parameters are not
- * that important, since ttpkt() or ttvt() should always fix that before
- * any communication is done. Well, we'll see...
- */
- if (xlocal) {
- curcarr = -2;
- debug(F100,"ttopen calling carrctl","",0);
- carrctl(&ttraw, ttcarr == CAR_ON);
- debug(F100,"ttopen carrctl ok","",0);
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifdef SVORPOSIX
- ttraw.c_lflag &= ~ECHO;
- ttold.c_lflag &= ~ECHO;
-#ifdef BSD44ORPOSIX
- y = tcsetattr(ttyfd, TCSADRAIN, &ttraw);
- debug(F101,"ttopen tcsetattr","",y);
-#else
- y = ioctl(ttyfd, TCSETA, &ttraw);
- debug(F100,"ttopen ioctl","",y);
-#endif /* BSD44ORPOSIX */
-
-#else /* BSD, etc */
- ttraw.sg_flags &= ~ECHO;
- ttold.sg_flags &= ~ECHO;
-#ifdef BELLV10
- y = ioctl(ttyfd,TIOCSETP,&ttraw);
- debug(F100,"ttopen ioctl","",y);
-#else
- y = stty(ttyfd,&ttraw);
- debug(F100,"ttopen stty","",y);
-#endif /* BELLV10 */
-#endif /* SVORPOSIX */
-
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
- /* ttflui(); */ /* This fails for some reason. */
- }
-
- /* Get current speed */
-
-#ifndef BEBOX
- ttspeed = ttgspd();
-#else
- ttspeed = 19200;
-#endif /* !BEBOX */
- debug(F101,"ttopen ttspeed","",ttspeed);
-
- /* Done, make entries in debug log, restore Ctrl-C trap, and return. */
-
- debug(F101,"ttopen ttyfd","",ttyfd);
- debug(F101,"ttopen *lcl","",*lcl);
- debug(F111,"ttopen lock file",flfnam,lkf);
- signal(SIGINT,occt);
- sigint_ign = (occt == SIG_IGN) ? 1 : 0;
- gotsigs = 0;
- return(0);
-}
-
-
-/* D O _ O P E N -- Do the right kind of open() call for the tty. */
-
-int
-do_open(ttname) char *ttname; {
- int flags;
-
-#ifdef QNX6
- /* O_NONBLOCK on /dev/tty makes open() fail */
- return(priv_opn(ttname, O_RDWR |
- (
- ((int)strcmp(ttname,"/dev/tty") == 0) ?
- 0 :
- (ttcarr != CAR_ON) ? O_NONBLOCK : 0)
- )
- );
-#else /* !QNX6 */
-
-#ifndef O_NDELAY /* O_NDELAY not defined */
- return(priv_opn(ttname,2));
-#else /* O_NDELAY defined */
-
-#ifdef ATT7300
-/*
- Open comms line without waiting for carrier so initial call does not hang
- because state of "modem" is likely unknown at the initial call -jrd.
- If this is needed for the getty stuff to work, and the open would not work
- without O_NDELAY when getty is still on, then this special case is ok.
- Otherwise, get rid of it. -ske
-*/
- return(priv_opn(ttname, O_RDWR | O_NDELAY));
-
-#else /* !ATT7300 */
-
- /* Normal case. Use O_NDELAY according to SET CARRIER. See ttscarr(). */
- flags = O_RDWR;
- debug(F101,"do_open xlocal","",xlocal);
- debug(F111,"do_open flags A",ttname,flags);
- if (xlocal && (ttcarr != CAR_ON))
- flags |= O_NDELAY;
- debug(F111,"do_open flags B",ttname,flags);
- return(priv_opn(ttname, flags));
-#endif /* !ATT7300 */
-#endif /* O_NDELAY */
-#endif /* QNX6 */
-}
-
-/* T T C L O S -- Close the TTY, releasing any lock. */
-
-static int ttc_state = 0; /* ttclose() state */
-static char * ttc_nam[] = { "setup", "hangup", "reset", "close" };
-
-int
-ttclos(foo) int foo; { /* Arg req'd for signal() prototype */
- int xx, x = 0;
- extern int exithangup;
-
- debug(F101,"ttclos ttyfd","",ttyfd);
- debug(F101,"ttclos netconn","",netconn);
- debug(F101,"ttclos xlocal","",xlocal);
-#ifdef NOFDZERO
- debug(F100,"ttclos NOFDZERO","",0);
-#endif /* NOFDZERO */
-
-#ifdef COMMENT
-#ifdef TTLEBUF
- le_init(); /* No need for any of this */
-#endif /* TTLEBUF */
-#endif /* COMMENT */
-
- if (ttyfd < 0) /* Wasn't open. */
- return(0);
-
- if (ttfdflg) /* If we inherited ttyfd from */
- return(0); /* another process, don't close it. */
-
- tvtflg = 0; /* (some day get rid of this...) */
- gotsigs = 0;
-
-#ifdef IKSD
- if (inserver) {
-#ifdef TNCODE
- tn_push(); /* Place any waiting data into input*/
- tn_sopt(DO,TELOPT_LOGOUT); /* Send LOGOUT option before close */
- TELOPT_UNANSWERED_DO(TELOPT_LOGOUT) = 1;
- tn_reset(); /* The Reset Telnet Option table. */
-#endif /* TNCODE */
-#ifdef CK_SSL
- if (ssl_active_flag) {
- if (ssl_debug_flag)
- BIO_printf(bio_err,"calling SSL_shutdown(ssl)\n");
- SSL_shutdown(ssl_con);
- SSL_free(ssl_con);
- ssl_con = NULL;
- ssl_active_flag = 0;
- }
- if (tls_active_flag) {
- if (ssl_debug_flag)
- BIO_printf(bio_err,"calling SSL_shutdown(tls)\n");
- SSL_shutdown(tls_con);
- SSL_free(tls_con);
- tls_con = NULL;
- tls_active_flag = 0;
- }
-#endif /* CK_SSL */
- }
-#endif /* IKSD */
-#ifdef NETCMD
- if (ttpipe) { /* We've been using a pipe */
- /* ttpipe = 0; */
- if (ttpid > 0) {
- int wstat;
- int statusp;
- close(fdin); /* Close these. */
- close(fdout);
- fdin = fdout = -1;
- kill(ttpid,1); /* Kill fork with SIGHUP */
- while (1) {
- wstat = wait(&statusp);
- if (wstat == ttpid || wstat == -1)
- break;
- pexitstat = (statusp & 0xff) ? statusp : statusp >> 8;
- }
- ttpid = 0;
- }
- netconn = 0;
- wasclosed = 1;
- ttyfd = -1;
- return(0);
- }
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) {
-#ifndef NODOPTY
- end_pty();
-#endif /* NODOPTY */
- close(ttyfd);
- netconn = 0;
- wasclosed = 1;
- ttpty = 0;
- ttyfd = -1;
- return(0);
- }
-#endif /* NETPTY */
-
-#ifdef NETCONN
- if (netconn) { /* If it's a network connection. */
- debug(F100,"ttclos closing net","",0);
- netclos(); /* Let the network module close it. */
- netconn = 0; /* No more network connection. */
- debug(F101,"ttclos ttyfd after netclos","",ttyfd); /* Should be -1 */
- return(0);
- }
-#endif /* NETCONN */
-
- if (xlocal) { /* We're closing a SET LINE device */
-#ifdef FT21 /* Fortune 2.1-specific items ... */
- ioctl(ttyfd,TIOCHPCL, NULL);
-#endif /* FT21 */
-#ifdef ultrix /* Ultrix-specific items ... */
-#ifdef TIOCSINUSE
- /* Unset the INUSE flag that we set in ttopen() */
- ioctl(ttyfd, TIOCSINUSE, NULL);
-#endif /* TIOCSINUSE */
- ioctl(ttyfd, TIOCNMODEM, &x);
-#ifdef COMMENT
- /* What was this? */
- ioctl(ttyfd, TIOCNCAR, NULL);
-#endif /* COMMENT */
-#endif /* ultrix */
- }
-
- /* This is to prevent us from sticking in tthang() or close(). */
-
-#ifdef O_NDELAY
-#ifndef aegis
- if (ttyfd > 0) { /* But skip it on stdin. */
- debug(F100,"ttclos setting O_NDELAY","",0);
- x = fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL, 0)|O_NDELAY);
-#ifdef DEBUG
- if (deblog && x == -1) {
- perror("Warning - Can't set O_NDELAY");
- debug(F101,"ttclos fcntl failure to set O_NDELAY","",x);
- }
-#endif /* DEBUG */
- }
-#endif /* aegis */
-#endif /* O_NDELAY */
-
- x = 0;
- ttc_state = 0;
- if (xlocal
-#ifdef NOFDZERO
- || ttyfd > 0
-#endif /* NOFDZERO */
- ) {
- saval = signal(SIGALRM,xtimerh); /* Enable timer interrupt. */
- xx = alarm(8); /* Allow 8 seconds. */
- debug(F101,"ttclos alarm","",xx);
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) { /* Timer went off? */
- x = -1;
-#ifdef DEBUG
- debug(F111,"ttclos ALARM TRAP errno",ckitoa(ttc_state),errno);
- printf("ttclos() timeout: %s\n", ttc_nam[ttc_state]);
-#endif /* DEBUG */
- }
- /* Hang up the device (drop DTR) */
-
- errno = 0;
- debug(F111,"ttclos A",ckitoa(x),ttc_state);
- if (ttc_state < 1) {
- ttc_state = 1;
- debug(F101,"ttclos exithangup","",exithangup);
- if (exithangup) {
- alarm(8); /* Re-arm the timer */
- debug(F101,"ttclos calling tthang()","",x);
- x = tthang(); /* Hang up first, then... */
- debug(F101,"ttclos tthang()","",x);
- }
-#ifndef CK_NOHUPCL
-/*
- Oct 2006 - Leave DTR on if SET EXIT HANGUP OFF.
- Suggested by Soewono Effendi.
-*/
-#ifdef HUPCL
- else {
- ttold.c_cflag &= ~HUPCL; /* Let's see how this travels */
-#ifdef BSD44ORPOSIX
- tcsetattr(ttyfd,TCSANOW,&ttold);
-#else /* !BSD44ORPOSIX */
-#ifdef ATTSV
- ioctl(ttyfd,TCSETAW,&ttold);
-#else /* !ATTSV */
- stty(ttyfd,&ttold);
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
- }
-#endif /* HUPCL */
-#endif /* CK_NOHUPCL */
- }
- /* Put back device modes as we found them */
-
- errno = 0;
- debug(F111,"ttclos B",ckitoa(x),ttc_state);
- if (ttc_state < 2) {
- ttc_state = 2;
- /* Don't try to mess with tty modes if tthang failed() */
- /* since it probably won't work. */
- if (x > -1) {
- debug(F101,"ttclos calling ttres()","",x);
- signal(SIGALRM,xtimerh); /* Re-enable the alarm. */
- alarm(8); /* Re-arm the timer */
- x = ttres(); /* Reset device modes. */
- debug(F101,"ttclos ttres()","",x);
- alarm(0);
- }
- }
- /* Close the device */
-
- errno = 0;
- debug(F101,"ttclos C","",ttc_state);
- if (ttc_state < 3) {
- ttc_state = 3;
- errno = 0;
- debug(F101,"ttclos calling close","",x);
- signal(SIGALRM,xtimerh); /* Re-enable alarm. */
- alarm(8); /* Re-arm the timer */
- x = close(ttyfd); /* Close the device. */
- debug(F101,"ttclos close()","",x);
- if (x > -1)
- ttc_state = 3;
- }
- debug(F101,"ttclos D","",ttc_state);
- ttimoff(); /* Turn off timer. */
- if (x < 0) {
- printf("?WARNING - close failed: %s\n",ttnmsv);
-#ifdef DEBUG
- if (deblog) {
- printf("errno = %d\n", errno);
- debug(F101,"ttclos failed","",errno);
- }
-#endif /* DEBUG */
- }
- /* Unlock after closing but before any getty mumbo jumbo */
-
- debug(F100,"ttclos about to call ttunlck","",0);
- if (ttunlck()) /* Release uucp-style lock */
- fprintf(stderr,"Warning, problem releasing lock\r\n");
- }
-
-/* For bidirectional lines, restore getty if it was there before. */
-
-#ifdef ACUCNTRL /* 4.3BSD acucntrl() method. */
- if (xlocal) {
- debug(F100,"ttclos ACUCNTRL","",0);
- acucntrl("enable",ttnmsv); /* Enable getty on the device. */
- }
-#else
-#ifdef ATT7300 /* ATT UNIX PC (3B1, 7300) method. */
- if (xlocal) {
- debug(F100,"ttclos ATT7300 ongetty","",0);
- if (attmodem & DOGETY) /* Was getty(1m) running before us? */
- ongetty(ttnmsv); /* Yes, restart getty on tty line */
- attmodem &= ~DOGETY; /* No phone in use, getty restored */
- }
-#endif /* ATT7300 */
-#endif /* System-dependent getty-restoring methods */
-
-#ifdef sony_news
- km_ext = -1; /* Invalidate device's Kanji-mode */
-#endif /* sony_news */
-
- ttyfd = -1; /* Invalidate the file descriptor. */
- wasclosed = 1;
- debug(F100,"ttclos done","",0);
- return(0);
-}
-
-/* T T H A N G -- Hangup phone line or network connection. */
-/*
- Returns:
- 0 if it does nothing.
- 1 if it believes that it hung up successfully.
- -1 if it believes that the hangup attempt failed.
-*/
-
-#define HUPTIME 500 /* Milliseconds for hangup */
-
-#ifdef COMMENT
-/* The following didn't work but TIOCSDTR does work */
-#ifdef UNIXWARE
-/* Define HUP_POSIX to force non-POSIX builds to use the POSIX hangup method */
-#ifndef POSIX /* Such as Unixware 1.x, 2.x */
-#ifndef HUP_POSIX
-#define HUP_POSIX
-#endif /* HUP_POSIX */
-#endif /* POSIX */
-#endif /* UNIXWARE */
-#endif /* COMMENT */
-
-#ifndef USE_TIOCSDTR
-#ifdef __NetBSD__
-/* Because the POSIX method (set output speed to 0) doesn't work in NetBSD */
-#ifdef TIOCSDTR
-#ifdef TIOCCDTR
-#define USE_TIOCSDTR
-#endif /* TIOCCDTR */
-#endif /* TIOCSDTR */
-#endif /* __NetBSD__ */
-#endif /* USE_TIOCSDTR */
-
-#ifndef HUP_CLOSE_POSIX
-#ifdef OU8
-#define HUP_CLOSE_POSIX
-#else
-#ifdef CK_SCOV5
-#define HUP_CLOSE_POSIX
-#endif /* CK_SCOV5 */
-#endif /* OU8 */
-#endif /* HUP_CLOSE_POSIX */
-
-#ifdef NO_HUP_CLOSE_POSIX
-#ifdef HUP_CLOSE_POSIX
-#undef HUP_CLOSE_POSIX
-#endif /* HUP_CLOSE_POSIX */
-#endif /* NO_HUP_CLOSE_POSIX */
-
-int
-tthang() {
-#ifdef NOLOCAL
- return(0);
-#else
- int x = 0; /* Sometimes used as return code. */
-#ifndef POSIX
- int z; /* worker */
-#endif /* POSIX */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifdef SVORPOSIX /* AT&T, POSIX, HPUX declarations. */
- int spdsav; /* for saving speed */
-#ifdef HUP_POSIX
- int spdsavi;
-#else
-#ifdef BSD44ORPOSIX
- int spdsavi;
-#endif /* BSD44ORPOSIX */
-#endif /* HUP_POSIX */
-#ifdef HPUX
-/*
- Early versions of HP-UX omitted the mflag typedef. If you get complaints
- about it, just change it to long (or better still, unsigned long).
-*/
- mflag
- dtr_down = 00000000000,
- modem_rtn,
- modem_sav;
- char modem_state[64];
-#endif /* HPUX */
- int flags; /* fcntl flags */
- unsigned short ttc_save;
-#endif /* SVORPOSIX */
-
- if (ttyfd < 0) return(0); /* Don't do this if not open */
- if (xlocal < 1) return(0); /* Don't do this if not local */
-
-#ifdef NETCMD
- if (ttpipe)
- return((ttclos(0) < 0) ? -1 : 1);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty)
- return((ttclos(0) < 0) ? -1 : 1);
-#endif /* NETPTY */
-#ifdef NETCONN
- if (netconn) { /* Network connection. */
-#ifdef TN_COMPORT
- if (istncomport()) {
- int rc = tnc_set_dtr_state(0);
- if (rc >= 0) {
- msleep(HUPTIME);
- rc = tnc_set_dtr_state(1);
- }
- return(rc >= 0 ? 1 : -1);
- } else
-#endif /* TN_COMPORT */
- return((netclos() < 0) ? -1 : 1); /* Just close it. */
- }
-#endif /* NETCONN */
-
-/* From here down, we handle real tty devices. */
-#ifdef HUP_POSIX
-/*
- e.g. for Unixware 2, where we don't have a full POSIX build, we
- still have to use POSIX-style hangup. Thus the duplication of this
- and the next case, the only difference being we use a local termios
- struct here, since a different model is used elsewhere.
-
- NO LONGER USED as of C-Kermit 8.0 -- it turns out that this method,
- even though it compiles and executes without error, doesn't actually
- work (i.e. DTR does not drop), whereas the TIOCSDTR method works just fine,
-*/
- {
- struct termios ttcur;
- int x;
- debug(F100,"tthang HUP_POSIX style","",0);
- x = tcgetattr(ttyfd, &ttcur); /* Get current attributes */
- debug(F111,"tthang tcgetattr",ckitoa(errno),x);
- if (x < 0) return(-1);
- spdsav = cfgetospeed(&ttcur); /* Get current speed */
- debug(F111,"tthang cfgetospeed",ckitoa(errno),spdsav);
- spdsavi = cfgetispeed(&ttcur); /* Get current speed */
- debug(F111,"tthang cfgetispeed",ckitoa(errno),spdsavi);
- x = cfsetospeed(&ttcur,B0); /* Replace by 0 */
- debug(F111,"tthang cfsetospeed",ckitoa(errno),x);
- if (x < 0) return(-1);
- x = cfsetispeed(&ttcur,B0);
- debug(F111,"tthang cfsetispeed",ckitoa(errno),x);
- if (x < 0) return(-1);
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F111,"tthang tcsetattr B0",ckitoa(errno),x);
- if (x < 0) return(-1);
- msleep(HUPTIME); /* Sleep 0.5 sec */
- x = cfsetospeed(&ttcur,spdsav); /* Restore prev speed */
- if (x < 0) return(-1);
- debug(F111,"tthang cfsetospeed prev",ckitoa(errno),x);
- x = cfsetispeed(&ttcur,spdsavi);
- debug(F111,"tthang cfsetispeed prev",ckitoa(errno),x);
- if (x < 0) return(-1);
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F111,"tthang tcsetattr restore",ckitoa(errno),x);
- if (x < 0) return(-1);
- return(1);
- }
-#else
-#ifdef BSD44ORPOSIX
-#ifdef QNX
- {
- int x;
- x = tcdropline(ttyfd,500);
- debug(F101,"tthang QNX tcdropline","",x);
- ttcur.c_cflag |= CLOCAL;
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F101,"tthang QNX tcsetattr restore","",x);
- if (x < 0) {
- debug(F101,"tthang QNX tcsetattr restore errno","",errno);
- return(-1);
- }
- /* Fix flags - ensure O_NONBLOCK is off */
-
- errno = 0;
- debug(F101,"tthang QNX iniflags","",iniflags);
- if (fcntl(ttyfd, F_SETFL, iniflags) == -1) {
- debug(F101,"tthang QNX F_SETFL errno","",errno);
- return(-1);
- }
- return(x);
- }
-#else /* QNX */
- {
- int x;
-#ifdef USE_TIOCSDTR
- debug(F100,"tthang BSD44ORPOSIX USE_TIOCSDTR","",0);
- errno = 0;
- x = ioctl(ttyfd, TIOCCDTR, NULL);
- debug(F111,"tthang BSD44ORPOSIX ioctl TIOCCDTR",ckitoa(errno),x);
- if (x < 0) return(-1);
- msleep(HUPTIME); /* Sleep 0.5 sec */
- errno = 0;
- x = ioctl(ttyfd, TIOCSDTR, NULL);
- debug(F111,"tthang BSD44ORPOSIX ioctl TIOCSDTR",ckitoa(errno),x);
- if (x < 0) return(-1);
-#else /* USE_TIOCSDTR */
-
-#ifdef HUP_CLOSE_POSIX
-/*
- In OSR5 versions where TIOCSDTR is not defined (up to and including at
- least 5.0.6a) the POSIX APIs in the "#else" part below are available but
- don't work, and no other APIs are available that do work. In this case
- we have to drop DTR by brute force: close and reopen the port. This
- code actually works, but all the steps are crucial: setting CLOCAL, the
- O_NDELAY manipulations, etc.
-*/
- debug(F100,"tthang HUP_CLOSE_POSIX close/open","",0);
- debug(F101,"tthang HUP_CLOSE_POSIX O_NONBLOCK","",O_NONBLOCK);
- debug(F101,"tthang HUP_CLOSE_POSIX O_NDELAY","",O_NDELAY);
- errno = 0;
- x = tcgetattr(ttyfd, &ttcur); /* Get current attributes */
- debug(F101,"tthang HUP_CLOSE_POSIX tcgetattr","",x);
- if (x < 0) {
- debug(F101,"tthang HUP_CLOSE_POSIX tcgetattr errno","",errno);
- return(-1);
- }
- errno = 0;
-
- x = close(ttyfd); /* Close without releasing lock */
- if (x < 0) {
- debug(F101,"tthang HUP_CLOSE_POSIX close errno","",errno);
- return(-1);
- }
- errno = 0;
- x = msleep(500); /* Pause half a second */
- if (x < 0) { /* Or if that doesn't work, 1 sec */
- debug(F101,"tthang HUP_CLOSE_POSIX msleep errno","",errno);
- sleep(1);
- }
- errno = 0;
- ttyfd = priv_opn(ttnmsv, (O_RDWR|O_NDELAY)); /* Reopen the device */
- debug(F111,"tthang HUP_CLOSE_POSIX reopen",ttnmsv,ttyfd);
- if (ttyfd < 0) {
- debug(F101,"tthang HUP_CLOSE_POSIX reopen errno","",errno);
- return(-1);
- }
- debug(F101,"tthang HUP_CLOSE_POSIX re-ttopen ttyfd","",ttyfd);
-
- /* Restore previous attributes */
-
- errno = 0;
- tvtflg = 0;
- ttcur.c_cflag |= CLOCAL;
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F101,"tthang HUP_CLOSE_POSIX tcsetattr restore","",x);
- if (x < 0) {
- debug(F101,"tthang HUP_CLOSE_POSIX tcsetattr restore errno",
- "",errno);
- return(-1);
- }
- /* Fix flags - ensure O_NDELAY and O_NONBLOCK are off */
-
- errno = 0;
- if ((x = fcntl(ttyfd, F_GETFL, 0)) == -1) {
- debug(F101,"tthang HUP_CLOSE_POSIX F_GETFL errno","",errno);
- return(-1);
- }
- debug(F101,"tthang HUP_CLOSE_POSIX flags","",x);
- errno = 0;
- x &= ~(O_NONBLOCK|O_NDELAY);
- debug(F101,"tthang HUP_CLOSE_POSIX flags to set","",x);
- debug(F101,"tthang HUP_CLOSE_POSIX iniflags","",iniflags);
- if (fcntl(ttyfd, F_SETFL, x) == -1) {
- debug(F101,"tthang HUP_CLOSE_POSIX F_SETFL errno","",errno);
- return(-1);
- }
-#ifdef DEBUG
- if (deblog) {
- if ((x = fcntl(ttyfd, F_GETFL, 0)) > -1) {
- debug(F101,"tthang HUP_CLOSE_POSIX flags","",x);
- debug(F101,"tthang HUP_CLOSE_POSIX flags & O_NONBLOCK",
- "",x&O_NONBLOCK);
- debug(F101,"tthang HUP_CLOSE_POSIX flags & O_NDELAY",
- "",x&O_NDELAY);
- }
- }
-#endif /* DEBUG */
-
-#else /* HUP_CLOSE_POSIX */
-
- /* General BSD44ORPOSIX case (Linux, BSDI, FreeBSD, etc) */
-
- debug(F100,"tthang BSD44ORPOSIX B0","",0);
- x = tcgetattr(ttyfd, &ttcur); /* Get current attributes */
- debug(F111,"tthang BSD44ORPOSIX tcgetattr",ckitoa(errno),x);
- if (x < 0) return(-1);
- spdsav = cfgetospeed(&ttcur); /* Get current speed */
- debug(F111,"tthang BSD44ORPOSIX cfgetospeed",ckitoa(errno),spdsav);
- spdsavi = cfgetispeed(&ttcur); /* Get current speed */
- debug(F111,"tthang BSD44ORPOSIX cfgetispeed",ckitoa(errno),spdsavi);
- x = cfsetospeed(&ttcur,B0); /* Replace by 0 */
- debug(F111,"tthang BSD44ORPOSIX cfsetospeed",ckitoa(errno),x);
- if (x < 0) return(-1);
- x = cfsetispeed(&ttcur,B0);
- debug(F111,"tthang BSD44ORPOSIX cfsetispeed",ckitoa(errno),x);
- if (x < 0) return(-1);
- /* This gets EINVAL on NetBSD 1.4.1 because of B0... */
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F111,"tthang BSD44ORPOSIX tcsetattr B0",ckitoa(errno),x);
- if (x < 0) return(-1);
- msleep(HUPTIME); /* Sleep 0.5 sec */
- debug(F101,"tthang BSD44ORPOSIX restore output speed","",spdsav);
- x = cfsetospeed(&ttcur,spdsav); /* Restore prev speed */
- debug(F111,"tthang BSD44ORPOSIX cfsetospeed prev",ckitoa(errno),x);
- if (x < 0) return(-1);
- debug(F101,"tthang BSD44ORPOSIX restore input speed","",spdsavi);
- x = cfsetispeed(&ttcur,spdsavi);
- debug(F111,"tthang BSD44ORPOSIX cfsetispeed prev",ckitoa(errno),x);
- if (x < 0) return(-1);
- ttcur.c_cflag |= CLOCAL; /* Don't expect CD after hangup */
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F111,"tthang BSD44ORPOSIX tcsetattr restore",ckitoa(errno),x);
- if (x < 0) return(-1);
-
-#endif /* HUP_CLOSE_POSIX */
-#endif /* USE_TIOCSDTR */
-
- return(1);
- }
-
-#endif /* QNX */
-#else /* BSD44ORPOSIX */
-
-#ifdef aegis /* Apollo Aegis */
- sio_$control((short)ttyfd, sio_$dtr, false, st); /* DTR down */
- msleep(HUPTIME); /* pause */
- sio_$control((short)ttyfd, sio_$dtr, true, st); /* DTR up */
- return(1);
-#endif /* aegis */
-
-#ifdef ANYBSD /* Any BSD version. */
-#ifdef TIOCCDTR /* Except those that don't have this */
- debug(F100,"tthang BSD style","",0);
- if (ioctl(ttyfd,TIOCCDTR,0) < 0) { /* Clear DTR. */
- debug(F101,"tthang TIOCCDTR fails","",errno);
- return(-1);
- }
- msleep(HUPTIME); /* For about 1/2 sec */
- errno = 0;
- x = ioctl(ttyfd,TIOCSDTR,0); /* Restore DTR */
- if (x < 0) {
- /*
- For some reason, this tends to fail with "no such device or address"
- but the operation still works, probably because of the close/open
- later on. So let's not scare the user unnecessarily here.
- */
- debug(F101,"tthang TIOCSDTR errno","",errno); /* Log the error */
- x = 1; /* Pretend we succeeded */
- } else if (x == 0) x = 1; /* Success */
-#ifdef COMMENT
-#ifdef FT21
- ioctl(ttyfd, TIOCSAVEMODES, 0);
- ioctl(ttyfd, TIOCHPCL, 0);
- close(ttyfd); /* Yes, must do this twice */
- if ((ttyfd = open(ttnmsv,2)) < 0) /* on Fortune computers... */
- return(-1); /* (but why?) */
- else x = 1;
-#endif /* FT21 */
-#endif /* COMMENT */
-#endif /* TIOCCDTR */
- close(do_open(ttnmsv)); /* Clear i/o error condition */
- errno = 0;
-#ifdef COMMENT
-/* This is definitely dangerous. Why was it here? */
- z = ttvt(ttspeed,ttflow); /* Restore modes. */
- debug(F101,"tthang ttvt returns","",z);
- return(z < 0 ? -1 : 1);
-#else
- return(x);
-#endif /* COMMENT */
-#endif /* ANYBSD */
-
-#ifdef ATTSV
-/* AT&T UNIX section, includes HP-UX and generic AT&T System III/V... */
-
-#ifdef HPUX
-/* Hewlett Packard allows explicit manipulation of modem signals. */
-
-#ifdef COMMENT
-/* Old way... */
- debug(F100,"tthang HP-UX style","",0);
- if (ioctl(ttyfd,MCSETAF,&dtr_down) < 0) /* lower DTR */
- return(-1); /* oops, can't. */
- msleep(HUPTIME); /* Pause half a second. */
- x = 1; /* Set return code */
- if (ioctl(ttyfd,MCGETA,&modem_rtn) > -1) { /* Get line status. */
- if ((modem_rtn & MDCD) != 0) /* Check if CD is low. */
- x = -1; /* CD didn't drop, fail. */
- } else x = -1;
-
- /* Even if above calls fail, RTS & DTR should be turned back on. */
- modem_rtn = MRTS | MDTR;
- if (ioctl(ttyfd,MCSETAF,&modem_rtn) < 0) x = -1;
- return(x);
-#else
-/* New way, from Hellmuth Michaelis */
- debug(F100,"tthang HP-UX style, HPUXDEBUG","",0);
- if (ioctl(ttyfd,MCGETA,&modem_rtn) == -1) { /* Get current status. */
- debug(F100,"tthang HP-UX: can't get modem lines, NO HANGUP!","",0);
- return(-1);
- }
- sprintf(modem_state,"%#lx",modem_rtn);
- debug(F110,"tthang HP-UX: modem lines = ",modem_state,0);
- modem_sav = modem_rtn; /* Save current modem signals */
- modem_rtn &= ~MDTR; /* Turn DTR bit off */
- sprintf(modem_state,"%#lx",modem_rtn);
- debug(F110,"tthang HP-UX: DTR down = ",modem_state,0);
- if (ioctl(ttyfd,MCSETAF,&modem_rtn) < 0) { /* lower DTR */
- debug(F100,"tthang HP-UX: can't lower DTR!","",0);
- return(-1); /* oops, can't. */
- }
- msleep(HUPTIME); /* Pause half a second. */
- x = 1; /* Set return code */
- if (ioctl(ttyfd,MCGETA,&modem_rtn) > -1) { /* Get line status. */
- sprintf(modem_state,"%#lx",modem_rtn);
- debug(F110,"tthang HP-UX: modem lines got = ",modem_state,0);
- if ((modem_rtn & MDCD) != 0) { /* Check if CD is low. */
- debug(F100,"tthang HP-UX: DCD not down","",0);
- x = -1; /* CD didn't drop, fail. */
- } else {
- debug(F100,"tthang HP-UX: DCD down","",0);
- }
- } else {
- x = -1;
- debug(F100,"tthang HP-UX: can't get DCD status !","",0);
- }
-
- /* Even if above calls fail, DTR should be turned back on. */
-
- modem_sav |= MDTR;
- if (ioctl(ttyfd,MCSETAF,&modem_sav) < 0) {
- x = -1;
- debug(F100,"tthang HP-UX: can't set saved state","",0);
- } else {
- sprintf(modem_state,"%#lx",modem_sav);
- debug(F110,"tthang HP-UX: final modem lines = ",modem_state,0);
- }
- return(x);
-#endif /* COMMENT */
-
-#else /* AT&T but not HP-UX */
-
-/* SVID for AT&T System V R3 defines ioctl's for handling modem signals. */
-/* It is not known how many, if any, systems actually implement them, */
-/* so we include them here in ifdef's. */
-
-/*
- Unixware has the TIOCMxxx symbols defined, but calling ioctl() with them
- gives error 22 (invalid argument).
-*/
-#ifndef _IBMR2
-/*
- No modem-signal twiddling for IBM RT PC or RS/6000.
- In AIX 3.1 and earlier, the ioctl() call is broken.
- This code could be activated for AIX 3.1 with PTF 2006 or later
- (e.g. AIX 3.2), but close/open does the job too, so why bother.
-*/
-#ifdef TIOCMBIS /* Bit Set */
-#ifdef TIOCMBIC /* Bit Clear */
-#ifdef TIOCM_DTR /* DTR */
-
-/* Clear DTR, sleep 300 msec, turn it back on. */
-/* If any of the ioctl's return failure, go on to the next section. */
-
- z = TIOCM_DTR; /* Code for DTR. */
-#ifdef COMMENT
-/*
- This was the cause of the troubles with the Solaris Port Monitor.
- The problem is: RTS never comes back on. Moral: Don't do it!
- (But why doesn't it come back on? See the TIOCMBIS call...)
-*/
-#ifdef TIOCM_RTS /* Lower RTS too if symbol is known. */
- z |= TIOCM_RTS;
-#endif /* TIOCM_RTS */
-#endif /* COMMENT */
-
- debug(F101,"tthang TIOCM signal mask","",z);
- if (ioctl(ttyfd,TIOCMBIC,&z) > -1) { /* Try to lower DTR. */
- debug(F100,"tthang TIOCMBIC ok","",0);
- msleep(HUPTIME); /* Pause half a second. */
- if (ioctl(ttyfd,TIOCMBIS,&z) > -1) { /* Try to turn it back on. */
- debug(F100,"tthang TIOCMBIS ok","",0);
-#ifndef CLSOPN
- return(1); /* Success, done. */
-#endif /* CLSOPN */
- } else { /* Couldn't raise, continue. */
- debug(F101,"tthang TIOCMBIS errno","",errno);
- }
- } else { /* Couldn't lower, continue. */
- debug(F101,"tthang TIOCMBIC errno","",errno);
- }
-#endif /* TIOCM_DTR */
-#endif /* TIOCMBIC */
-#endif /* TIOCMBIS */
-#endif /* _IBMR2 */
-
-/*
- General AT&T UNIX case, not HPUX. The following code is highly suspect. No
- two AT&T-based systems seem to do this the same way. The object is simply
- to turn off DTR and then turn it back on. SVID says the universal method
- for turning off DTR is to set the speed to zero, and this does seem to do
- the trick in all cases. But neither SVID nor any known man pages say how to
- turn DTR back on again. Some variants, like most Xenix implementations,
- raise DTR again when the speed is restored to a nonzero value. Others
- require the device to be closed and opened again, but this is risky because
- getty could seize the device during the instant it is closed.
-*/
-
-/* Return code for ioctl failures... */
-#ifdef ATT6300
- x = 1; /* ATT6300 doesn't want to fail... */
-#else
- x = -1;
-#endif /* ATT6300 */
-
- debug(F100,"tthang get settings","",0);
- if (ioctl(ttyfd,TCGETA,&ttcur) < 0) /* Get current settings. */
- return(x); /* Fail if this doesn't work. */
- if ((flags = fcntl(ttyfd,F_GETFL,0)) < 0) /* Get device flags. */
- return(x);
- ttc_save = ttcur.c_cflag; /* Remember current speed. */
- spdsav = ttc_save & CBAUD;
- debug(F101,"tthang speed","",spdsav);
-
-#ifdef O_NDELAY
- debug(F100,"tthang turning O_NDELAY on","",0);
- fcntl(ttyfd, F_SETFL, flags | O_NDELAY); /* Activate O_NDELAY */
-#endif /* O_NDELAY */
-
-#ifdef ATT7300 /* This is the way it is SUPPOSED to work */
- ttcur.c_cflag &= ~CBAUD; /* Change the speed to zero. */
-#else
-#ifdef RTAIX
- ttcur.c_cflag &= ~CBAUD; /* Change the speed to zero. */
-#else /* This way really works but may be dangerous */
-#ifdef u3b2
- ttcur.c_cflag = ~(CBAUD|CLOCAL); /* Special for AT&T 3B2s */
- /* (CLOCAL must be OFF) */
-#else
-#ifdef SCO3R2 /* SCO UNIX 3.2 */
-/*
- This is complete nonsense, but an SCO user claimed this change made
- hanging up work. Comments from other SCO UNIX 3.2 users would be
- appreciated.
-*/
- ttcur.c_cflag = CBAUD|B0;
-#else
-#ifdef AIXRS /* AIX on RS/6000 */
-/*
- Can't set speed to zero on AIX 3.1 on RS/6000 64-port adapter,
- even though you can do it on the built-in port and the 8- and 16-port
- adapters. (Untested on 128-port adapter.)
-*/
- ttcur.c_cflag = CLOCAL|HUPCL|spdsav; /* Speed 0 causes EINVAL */
-#else /* None of the above */
-/*
- Set everything, including the speed, to zero, except for the CLOCAL
- and HUPCL bits.
-*/
- ttcur.c_cflag = CLOCAL|HUPCL;
-#endif /* AIXRS */
-#endif /* SCO3R2 */
-#endif /* u3b2 */
-#endif /* RTAIX */
-#endif /* ATT7300 */
-
-#ifdef COMMENT
- /* and if none of those work, try one of these... */
- ttcur.c_cflag = 0;
- ttcur.c_cflag = CLOCAL;
- ttcur.c_cflag &= ~(CBAUD|HUPCL);
- ttcur.c_cflag &= ~(CBAUD|CREAD);
- ttcur.c_cflag &= ~(CBAUD|CREAD|HUPCL);
- /* or other combinations */
-#endif /* COMMENT */
-
-#ifdef TCXONC
- debug(F100,"tthang TCXONC","",0);
- if (ioctl(ttyfd, TCXONC, 1) < 0) {
- debug(F101,"tthang TCXONC failed","",errno);
- }
-#endif /* TCXONC */
-
-#ifdef TIOCSTART
- debug(F100,"tthang TIOCSTART","",0);
- if (ioctl(ttyfd, TIOCSTART, 0) < 0) {
- debug(F101,"tthang TIOCSTART failed","",errno);
- }
-#endif /* TIOCSTART */
-
- if (ioctl(ttyfd,TCSETAF,&ttcur) < 0) { /* Fail if we can't. */
- debug(F101,"tthang TCSETAF failed","",errno);
- fcntl(ttyfd, F_SETFL, flags); /* Restore flags */
- return(-1); /* before returning. */
- }
- msleep(300); /* Give modem time to notice. */
-
-#ifndef NOCOTFMC
-
-/* Now, even though it doesn't say this in SVID or any man page, we have */
-/* to close and reopen the device. This is not necessary for all systems, */
-/* but it's impossible to predict which ones need it and which ones don't. */
-
-#ifdef ATT7300
-/*
- Special handling for ATT 7300 UNIX PC and 3B1, which have "phone"
- related ioctl's for their internal modems. attmodem has getty status and
- modem-in-use bit. Reportedly the ATT7300/3B1 PIOCDISC call is necessary,
- but also ruins the file descriptor, and no other phone(7) ioctl call can fix
- it. Whatever it does, it seems to escape detection with PIOCGETA and TCGETA.
- The only way to undo the damage is to close the fd and then reopen it.
-*/
- if (attmodem & ISMODEM) {
- debug(F100,"tthang attmodem close/open","",0);
- ioctl(ttyfd,PIOCUNHOLD,&dialer); /* Return call to handset. */
- ioctl(ttyfd,PIOCDISC,&dialer); /* Disconnect phone. */
- close(ttyfd); /* Close and reopen the fd. */
- ttyfd = priv_opn(ttnmsv, O_RDWR | O_NDELAY);
- attmodem &= ~ISMODEM; /* Phone no longer in use. */
- }
-#else /* !ATT7300 */
-/* It seems we have to close and open the device for other AT&T systems */
-/* too, and this is the place to do it. The following code does the */
-/* famous close(open(...)) magic by default. If that doesn't work for you, */
-/* then try uncommenting the following statement or putting -DCLSOPN in */
-/* the makefile CFLAGS. */
-
-/* #define CLSOPN */
-
-#ifndef SCO32 /* Not needed by, and harmful to, SCO UNIX 3.2 / Xenix 2.3 */
-
-#ifdef O_NDELAY
-#define OPENFLGS O_RDWR | O_NDELAY
-#else
-#define OPENFLGS O_RDWR
-#endif
-
-#ifndef CLSOPN
-/* This method is used by default, i.e. unless CLSOPN is defined. */
-/* It is thought to be safer because there is no window where getty */
-/* can seize control of the device. The drawback is that it might not work. */
-
- debug(F101,"tthang close(open()), OPENFLGS","",OPENFLGS);
- close(priv_opn(ttnmsv, OPENFLGS));
-
-#else
-/* This method is used if you #define CLSOPN. It is more likely to work */
-/* than the previous method, but it's also more dangerous. */
-
- debug(F101,"tthang close/open, OPENFLGS","",OPENFLGS);
- close(ttyfd);
- msleep(10);
- ttyfd = priv_opn(ttnmsv, OPENFLGS); /* Open it again */
-#endif /* CLSOPN */
-#undef OPENFLGS
-
-#endif /* SCO32 */
-#endif /* ATT7300 */
-
-#endif /* NOCOTFMC */
-
-/* Now put all flags & modes back the way we found them. */
-/* (Does the order of ioctl & fcntl matter ? ) */
-
- debug(F100,"tthang restore settings","",0);
- ttcur.c_cflag = ttc_save; /* Get old speed back. */
- if (ioctl(ttyfd,TCSETAF,&ttcur) < 0) /* ioctl parameters. */
- return(-1);
-#ifdef O_NDELAY
-/*
- This is required for IBM RT and RS/6000, probably helps elsewhere too (?).
- After closing a modem line, the modem will probably not be asserting
- carrier any more, so we should not require carrier any more. If this
- causes trouble on non-IBM UNIXes, change the #ifdef to use _IBMR2 rather
- than O_NDELAY.
-*/
- flags &= ~O_NDELAY; /* Don't require carrier on reopen */
-#endif /* O_NDELAY */
- if (fcntl(ttyfd,F_SETFL,flags) < 0) /* fcntl parameters */
- return(-1);
-
- return(1);
-#endif /* not HPUX */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-#endif /* HUP_POSIX */
-#endif /* NOLOCAL */
-}
-
-/*
- Major change in 5A(174). We used to use LPASS8, if it was defined, to
- allow 8-bit data and Xon/Xoff flow control at the same time. But this
- LPASS8 business seems to have been causing trouble for everybody but me!
- For example, Annex terminal servers, commonly used with Encore computers,
- do not support LPASS8 even though the Encore itself does. Ditto for many
- other terminal servers, TELNET connections, rlogin connections, etc etc.
- Now, reportedly, even vanilla 4.3 BSD systems can't do this right on their
- serial lines, even though LPASS8 is a feature of 4.3BSD. So let's turn it
- off for everybody. That means we goes back to using raw mode, with no
- flow control. Phooey.
-
- NOTE: This must be done before the first reference to LPASS8 in this file,
- and after the last #include statment.
-*/
-#ifdef LPASS8
-#undef LPASS8
-#endif /* LPASS8 */
-
-/* T T R E S -- Restore terminal to "normal" mode. */
-
-/* ske@pkmab.se: There are two choices for what this function should do.
- * (1) Restore the tty to current "normal" mode, with carrier treatment
- * according to ttcarr, to be used after every kermit command. (2) Restore
- * the tty to the state it was in before kermit opened it. These choices
- * conflict, since ttold can't hold both choices of tty parameters. ttres()
- * is currently being called as in choice (1), but ttold basically holds
- * the initial parameters, as in (2), and the description at the beginning
- * of this file says (2).
- *
- * I don't think restoring tty parameters after all kermit commands makes
- * much of a difference. Restoring them upon exit from kermit may be of
- * some use in some cases (when the line is not restored automatically on
- * close, by the operating system).
- *
- * I can't choose which one it should be, so I haven't changed it. It
- * probably works as it is, too. It would probably even work even with
- * ttres() entirely deleted...
- *
- * (from fdc: Actually, this function operates in remote mode too, so
- * it restores the console (command) terminal to whatever mode it was
- * in before packet operations began, so that commands work right again.)
- */
-int
-ttres() { /* Restore the tty to normal. */
- int x;
-
- if (ttyfd < 0) return(-1); /* Not open. */
-
- if (ttfdflg) return(0); /* Don't mess with terminal modes if */
- /* we got ttyfd from another process */
-#ifdef NETCONN
- if (netconn) { /* Network connection */
- tvtflg = 0;
-#ifdef TCPSOCKET
-#ifdef TCP_NODELAY
- {
- extern int tcp_nodelay; /* Just put this back if necessary */
- if (ttnet == NET_TCPB) {
- if (nodelay_sav > -1) {
- no_delay(ttyfd,nodelay_sav);
- nodelay_sav = -1;
- }
- }
- }
-#endif /* TCP_NODELAY */
-#ifdef TN_COMPORT
- if (istncomport()) {
- int rc = -1;
- if ((rc = tnsetflow(ttflow)) < 0)
- return(rc);
- if (ttspeed <= 0)
- ttspeed = tnc_get_baud();
- else if ((rc = tnc_set_baud(ttspeed)) < 0)
- return(rc);
- tnc_set_datasize(8);
- tnc_set_stopsize(stopbits);
-
-#ifdef HWPARITY
- if (hwparity) {
- switch (hwparity) {
- case 'e': /* Even */
- debug(F100,"ttres 8 bits + even parity","",0);
- tnc_set_parity(3);
- break;
- case 'o': /* Odd */
- debug(F100,"ttres 8 bits + odd parity","",0);
- tnc_set_parity(2);
- break;
- case 'm': /* Mark */
- debug(F100,"ttres 8 bits + invalid parity: mark","",0);
- tnc_set_parity(4);
- break;
- case 's': /* Space */
- debug(F100,"ttres 8 bits + invalid parity: space","",0);
- tnc_set_parity(5);
- break;
- }
- } else
-#endif /* HWPARITY */
- {
- tnc_set_parity(1); /* None */
- }
- tvtflg = 0;
- return(0);
- }
-#endif /* TN_COMPORT */
-#endif /* TCPSOCKET */
- return(0);
- }
-#endif /* NETCONN */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-
-/* Real terminal device, so restore its original modes */
-
-#ifdef BSD44ORPOSIX /* For POSIX like this */
- debug(F100,"ttres BSD44ORPOSIX","",0);
- x = tcsetattr(ttyfd,TCSADRAIN,&ttold);
-#else /* For all others... */
-#ifdef ATTSV /* For AT&T versions... */
- debug(F100,"ttres ATTSV","",0);
- x = ioctl(ttyfd,TCSETAW,&ttold); /* Restore tty modes this way. */
-#else
-/* Here we restore the modes for BSD */
-
-#ifdef LPASS8 /* Undo "pass8" if it were done */
- if (lmodef) {
- if (ioctl(ttyfd,TIOCLSET,&lmode) < 0)
- debug(F100,"ttres TIOCLSET failed","",0);
- else
- debug(F100,"ttres TIOCLSET ok","",0);
- }
-#endif /* LPASS8 */
-
-#ifdef CK_DTRCTS /* Undo hardware flow if it were done */
- if (lmodef) {
- if (ioctl(ttyfd,TIOCLSET,&lmode) < 0)
- debug(F100,"ttres TIOCLSET failed","",0);
- else
- debug(F100,"ttres TIOCLSET ok","",0);
- }
-#endif /* CK_DTRCTS */
-
-#ifdef TIOCGETC /* Put back special characters */
- if (tcharf && (xlocal == 0)) {
- if (ioctl(ttyfd,TIOCSETC,&tchold) < 0)
- debug(F100,"ttres TIOCSETC failed","",0);
- else
- debug(F100,"ttres TIOCSETC ok","",0);
- }
-#endif /* TIOCGETC */
-
-#ifdef TIOCGLTC /* Put back local special characters */
- if (ltcharf && (xlocal == 0)) {
- if (ioctl(ttyfd,TIOCSLTC,<chold) < 0)
- debug(F100,"ttres TIOCSLTC failed","",0);
- else
- debug(F100,"ttres TIOCSLTC ok","",0);
- }
-#endif /* TIOCGLTC */
-
-#ifdef BELLV10
- debug(F100,"ttres BELLV10","",0);
- x = ioctl(ttyfd,TIOCSETP,&ttold); /* Restore both structs */
- x = ioctl(ttyfd,TIOCSDEV,&tdold);
-#else
- debug(F100,"ttres stty","",0);
- x = stty(ttyfd,&ttold); /* Restore tty modes the old way. */
-#endif /* BELLV10 */
-
- if (!xlocal)
- msleep(100); /* This replaces sleep(1)... */
- /* Put back sleep(1) if tty is */
- /* messed up after close. */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-
- debug(F101,"ttres result","",x);
-#ifndef QNX
- if (x < 0) debug(F101,"ttres errno","",errno);
-#endif /* QNX */
-
-#ifdef AIXRS
-#ifndef AIX41
- x = ioctl(ttyfd, ttld & 1 ? TXADDCD : TXDELCD, "rts");
- debug(F101,"ttres AIX line discipline rts restore","",x);
-#endif /* AIX41 */
-#endif /* AIXRS */
-
-#ifdef BSD41
- if (ttld > -1) { /* Put back line discipline */
- x = ioctl(ttyfd, TIOCSETD, &ttld);
- debug(F101,"ttres BSD41 line discipline restore","",x);
- if (x < 0) debug(F101,"...ioctl errno","",errno);
- ttld = -1;
- }
-#endif /* BSD41 */
-
-#ifdef sony_news
- x = xlocal ? km_ext : km_con; /* Restore Kanji mode. */
- if (x != -1) { /* Make sure we know original modes. */
- if (ioctl(ttyfd,TIOCKSET, &x) < 0) {
- perror("ttres can't set Kanji mode");
- debug(F101,"ttres error setting Kanji mode","",x);
- return(-1);
- }
- }
- debug(F100,"ttres set Kanji mode ok","",0);
-#endif /* sony_news */
-
- tvtflg = 0; /* Invalidate terminal mode settings */
- debug(F101,"ttres return code","",x);
- return(x);
-}
-
-#ifndef NOUUCP
-
-/* T T C H K P I D -- Check lockfile pid */
-/*
- Read pid from lockfile named f, check that it's still valid.
- If so, return 1.
- On failure to read pid, return 1.
- Otherwise, try to delete lockfile f and return 0 if successful, else 1.
-*/
-static int
-ttchkpid(f) char *f; {
- int pid, mypid, x;
- pid = ttrpid(f); /* Read pid from file. */
- if (pid > -1) { /* If we were able to read the pid.. */
- debug(F101,"ttchkpid lock pid","",pid);
- errno = 0; /* See if process still exists. */
- mypid = (int)getpid(); /* Get my own pid. */
- debug(F101,"ttchkpid my pid","",mypid);
- if (pid == mypid) { /* It's me! */
- x = -1; /* So I can delete it */
- errno = ESRCH; /* pretend it's invalid */
- } else { /* It's not me */
- x = kill((PID_T)pid, 0); /* See if it's a live process */
- debug(F101,"ttchkpid kill errno","",errno);
- }
- debug(F101,"ttchkpid pid test","",x);
- if (x < 0 && errno == ESRCH) { /* pid is invalid */
- debug(F111,"removing stale lock",f,pid);
- if (!backgrd)
- printf("Removing stale lock %s (pid %d terminated)\n", f, pid);
- priv_on();
- x = unlink(f); /* Remove the lockfile. */
- priv_off();
- debug(F111,"ttchkpid unlink",f,x);
- if (x > -1)
- return(0); /* Device is not locked after all */
- else if (!backgrd)
- perror(f);
- }
- return(1);
- }
- return(1); /* Failure to read pid */
-}
-
-#ifdef HPUX
-
-/* Aliases (different drivers) for HP-UX dialout devices: */
-
-static char *devprefix[] = { "tty", "ttyd", "cul", "cua", "cuad", "culd", "" };
-static int ttydexists = 0;
-
-#endif /* HPUX */
-
-/* T T R P I D -- Read pid from lockfile "name" */
-
-static int
-ttrpid(name) char *name; {
- long len;
- int x, fd, pid;
- short spid;
- char buf[32];
-
- debug(F110,"ttrpid",name,0);
- if (!name) return(-1);
- if (!*name) return(-1);
- priv_on();
- len = zchki(name); /* Get file length */
- priv_off();
- debug(F101,"ttrpid zchki","",len);
- if (len < 0)
- return(-1);
- if (len > 31)
- return(-1);
- priv_on();
- fd = open(name,O_RDONLY); /* Try to open lockfile. */
- priv_off();
- debug(F101,"ttrpid fd","",fd);
- if (fd <= 0)
- return(-1);
-/*
- Here we try to be flexible and allow for all different binary and string
- formats at runtime, rather than a specific format for each configuration
- hardwired at compile time.
-*/
- pid = -1;
-#ifndef COHERENT
-/*
- COHERENT uses a string PID but without leading spaces or 0's, so there is
- no way to tell from the file's length whether it contains a string or binary
- pid. So for COHERENT only, we only allow string pids. For all others, we
- decide based on the size of the lockfile.
-*/
- if (len > 4) { /* If file > 4 bytes it's a string */
-#endif /* COHERENT */
- x = read(fd,buf,(int)len);
- debug(F111,"ttrpid string read",buf,x);
- if (x < 0) {
- pid = -1;
- } else {
- buf[31] = '\0';
- x = sscanf(buf,"%d",&pid); /* Get the integer pid from it. */
- }
-#ifndef COHERENT
- } else if (len == 4) { /* 4 bytes so binary */
- x = read(fd, (char *)&pid, 4); /* Read the bytes into an int */
- debug(F101,"ttrpid integer read","",x);
- if (x < 4)
- pid = -1;
- } else if (len == 2) { /* 2 bytes binary */
- x = read(fd, (char *)&spid, 2); /* Read the bytes into a short */
- debug(F101,"ttrpid short read","",x);
- if (x < 2)
- pid = -1;
- else
- pid = spid;
- } else
- pid = -1;
-#endif /* COHERENT */
- close(fd); /* Close the lockfile */
- debug(F101,"ttrpid pid","",pid);
- return(pid);
-}
-#endif /* NOUUCP */
-
-/* T T L O C K */
-
-/*
- This function attempts to coordinate use of the communication device with
- other copies of Kermit and any other program that follows the UUCP
- device-locking conventions, which, unfortunately, vary among different UNIX
- implementations. The idea is to look for a file of a certain name, the
- "lockfile", in a certain directory. If such a file is found, then the line
- is presumed to be in use, and Kermit should not use it. If no such file is
- found, Kermit attempts to create one so that other programs will not use the
- same line at the same time. Because the lockfile and/or the directory it's
- in might lack write permission for the person running Kermit, Kermit could
- find itself running setuid to uucp or other user that does have the
- necessary permissions. At startup, Kermit has changed its effective uid to
- the user's real uid, and so ttlock() must switch back to the original
- effective uid in order to create the lockfile, and then back again to the
- real uid to prevent unauthorized access to other directories or files owned
- by the user the program is setuid to.
-
- Totally rewritten for C-Kermit 5A to eliminate windows of vulnerability,
- based on suggestions from Warren Tucker. Call with pointer to name of
- tty device. Returns:
-
- 0 on success
- -1 on failure
-
- Note: Once privileges are turned on using priv_on(), it is essential that
- they are turned off again before this function returns.
-*/
-#ifdef SVR4 /* Lockfile uses device numbers. */
-/*
- Although I can't find this in writing anywhere (e.g. in SVID for SVR4),
- it is the behavior of the "reference version" of SVR4, i.e. the Intel
- port from UNIX Systems Laboratories, then called Univel UnixWare,
- then called Novell UnixWare, then called SCO Unixware, then called Caldera
- Open UNIX... It also makes much more sense than device-name-based lockfiles
- since there can be multiple names for the same device, symlinks, etc.
-*/
-#ifndef NOLFDEVNO
-#ifndef LFDEVNO /* Define this for SVR4 */
-#ifndef AIXRS /* But not for RS/6000 AIX 3.2, etc. */
-#ifndef BSD44 /* If anybody else needs it... */
-#ifndef __386BSD__
-#ifndef __FreeBSD__
-#ifndef HPUX10
-#ifndef IRIX51 /* SGI IRIX 5.1 or later */
-#ifndef CK_SCOV5 /* SCO Open Server 5.0 */
-#define LFDEVNO
-#endif /* CK_SCOV5 */
-#endif /* IRIX51 */
-#endif /* HPUX10 */
-#endif /* __FreeBSD__ */
-#endif /* __386BSD__ */
-#endif /* BSD44 */
-#endif /* AIXRS */
-#endif /* LFDEVNO */ /* ... define it here or on CC */
-#endif /* NOLFDEVNO */
-#endif /* SVR4 */ /* command line. */
-
-#ifdef COHERENT
-#define LFDEVNO
-#endif /* COHERENT */
-
-/*
- For platforms where the lockfile name is made from device/major/minor
- device number, as in SVR4. Which, if we must have lockfiles at all, is
- by far the best format, since it eliminates all the confusion that stems
- from multiple names (or drivers) for the same port, not to mention
- symlinks. It might even be a good idea to start using this form even
- on platforms where it's not supported, alongside the normal forms for those
- platforms, in order to get people used to it...
-*/
-#ifdef LFDEVNO
-#ifndef major /* If we didn't find it */
-#ifdef SVR4 /* then for Sys V R4 */
-#include <sys/mkdev.h> /* look here */
-#else /* or for SunOS versions */
-#ifdef SUNOS4 /* ... */
-#include <sys/sysmacros.h> /* look here */
-#else /* Otherwise take a chance: */
-#define major(dev) ( (int) ( ((unsigned)(dev) >> 8) & 0xff))
-#define minor(dev) ( (int) ( (dev) & 0xff))
-#endif /* SUNOS4 */
-#endif /* SVR4 */
-#endif /* major */
-#endif /* LFDEVNO */
-
-/* No advisory locks if F_TLOCK and F_ULOCK are not defined at this point */
-
-#ifdef LOCKF
-#ifndef F_TLOCK
-#undef LOCKF
-#ifndef NOLOCKF
-#define NOLOCKF
-#endif /* NOLOCKF */
-#endif /* F_TLOCK */
-#endif /* LOCKF */
-
-#ifdef LOCKF
-#ifndef F_ULOCK
-#undef LOCKF
-#ifndef NOLOCKF
-#define NOLOCKF
-#endif /* NOLOCKF */
-#endif /* F_ULOCK */
-#endif /* LOCKF */
-
-static char linkto[DEVNAMLEN+1];
-static char * linkdev = NULL;
-
-#ifndef NOUUCP
-#ifdef USETTYLOCK
-#ifdef LOCK_DIR
-char * uucplockdir = LOCK_DIR;
-#else
-char * uucplockdir = "";
-#endif /* LOCK_DIR */
-#else
-#ifdef LOCK_DIR
-char * uucplockdir = LOCK_DIR;
-#else
-char * uucplockdir = "";
-#endif /* LOCK_DIR */
-#endif /* USETTYLOCK */
-#else
-char * uucplockdir = "";
-#endif /* NOUUCP */
-
-#ifdef QNX /* Only for QNX4 */
-int /* Visible to outside world */
-qnxopencount() { /* Get QNX device open count */
- struct _dev_info_entry info;
- int x;
-
- x = -1; /* Unknown */
- if (ttyfd > -1) {
- if (!dev_info(ttyfd, &info)) {
- debug(F101,"ttlock QNX open_count","",info.open_count);
- x = info.open_count;
- }
- }
- return(x);
-}
-#endif /* QNX */
-
-char *
-ttglckdir() { /* Get Lockfile directory name */
-#ifdef __OpenBSD__
- return("/var/spool/lock");
-#else /* __OpenBSD__ */
-#ifdef __FreeBSD__
- return("/var/spool/lock");
-#else /* __FreeBSD__ */
-#ifdef LOCK_DIR
- char * s = LOCK_DIR;
-#endif /* LOCK_DIR */
-#ifdef NOUUCP
- return("");
-#else /* NOUUCP */
-#ifdef LOCK_DIR
- return(s);
-#else /* LOCK_DIR */
- return("");
-#endif /* LOCK_DIR */
-#endif /* NOUUCP */
-#endif /* __FreeBSD__ */
-#endif /* __OpenBSD__ */
-}
-
-static int
-ttlock(ttdev) char *ttdev; {
-
- int x, n;
- int islink = 0;
-#ifdef __FreeBSD__
- char *devname;
-#endif /* __FreeBSD__ */
-
-#ifdef NOUUCP
- debug(F100,"ttlock NOUUCP","",0);
- ckstrncpy(flfnam,"NOLOCK",FLFNAML);
- haslock = 1;
- return(0);
-#else /* !NOUUCP */
-
-#ifdef USETTYLOCK
- haslock = 0; /* Not locked yet. */
- *flfnam = '\0'; /* Lockfile name is empty. */
-#ifdef __FreeBSD__
- if ((devname = xxlast(ttdev,'/')) != NULL)
-#ifdef FREEBSD8
- ckstrncat(lockname,devname+1,DEVNAMLEN-ckstrncpy(lockname,"pts",4));
-#else
- ckstrncpy(lockname,devname+1,DEVNAMLEN);
-#endif /* FREEBSD8 */
-#else
- if (!strncmp(ttdev,"/dev/",5) && ttdev[5])
- ckstrncpy(lockname,ttdev+5,DEVNAMLEN);
-#endif /* __FreeBSD__ */
- else
- ckstrncpy(lockname,ttdev,DEVNAMLEN);
-/*
- This might be overkill, but it's not clear from the man pages whether
- ttylock() can be called without calling ttylocked() first, since the doc
- says that ttylocked() removes any stale lockfiles, but it does not say this
- about ttylock(). Also the docs don't say what ttylocked() returns in the
- case when it finds and removes a stale lockfile. So one or both calls to
- to ttylocked() might be superfluous, but they should do no harm. Also I'm
- assuming that we have to do all the same ID swapping, etc, with these
- routines as we do without them. Thus the priv_on/off() sandwich.
-*/
-#ifdef USE_UU_LOCK
- priv_on(); /* Turn on privs */
- x = uu_lock(lockname); /* Try to set the lock */
- priv_off(); /* Turn privs off */
- debug(F111,"ttlock uu_lock",lockname,x);
- switch (x) {
- case UU_LOCK_INUSE:
- return(-2);
- case UU_LOCK_OK:
-#ifdef BSD44
- ckmakmsg(flfnam,FLFNAML,"/var/spool/lock/LCK..",lockname,NULL,NULL);
-#endif /* BSD44 */
- haslock = 1;
- return(0);
- default:
- return(-1);
- }
-#else /* USE_UU_LOCK */
- priv_on(); /* Turn on privs */
- if (ttylocked(lockname)) { /* This should remove any stale lock */
- if (ttylocked(lockname)) { /* so check again. */
- priv_off();
- return(-5); /* Still locked, fail. */
- }
- }
- x = ttylock(lockname); /* Lock it. */
- priv_off(); /* Turn off privs */
-
- debug(F111,"ttlock lockname",lockname,x);
- if (x > -1) {
- /*
- We don't really know the name of the lockfile, but
- this is what the man page says it is. In USETTYLOCK
- builds, it is used only for display by SHOW COMM.
- */
- ckmakmsg(flfnam,FLFNAML,"/etc/locks/LCK..",lockname,NULL,NULL);
- haslock = 1;
- }
- return(x);
-#endif /* USE_UU_LOCK */
-#else /* Systems that don't have ttylock()... */
-
-#ifndef HPUX
-
- int lockfd; /* File descriptor for lock file. */
- PID_T pid; /* Process id of this process. */
- int tries; /* How many times we've tried... */
- struct stat devbuf; /* For device numbers (SVR4). */
-
-#ifdef PIDSTRING
- char pid_str[32]; /* My pid in string format. */
-#endif /* PIDSTRING */
-
- char *device, *devname;
-
-#define LFNAML 256 /* Max length for lock file name. */
- char lockfil[LFNAML]; /* Lock file name */
-#ifdef RTAIX
- char lklockf[LFNAML]; /* Name for link to lock file */
-#endif /* RTAIX */
-#ifdef CKSYMLINK
- char symlock[LFNAML]; /* Name for symlink lockfile name */
-#endif /* CKSYMLINK */
- char tmpnam[LFNAML+30]; /* Temporary lockfile name. */
- char *lockdir = LOCK_DIR; /* Defined near top of this file, */
- /* or on cc command line. */
- haslock = 0; /* Not locked yet. */
- *flfnam = '\0'; /* Lockfile name is empty. */
- lock2[0] = '\0'; /* Clear secondary lockfile name. */
- pid = getpid(); /* Get id of this process. */
-
-/* Construct name of lockfile and temporary file */
-
-/* device = name of tty device without the path, e.g. "ttyh8" */
-/* lockfil = name of lock file, without path, e.g. "LCK..ttyh8" */
-
- device = ((devname = xxlast(ttdev,'/')) != NULL ? devname+1 : ttdev);
-
- if (stat(ttdev,&devbuf) < 0)
- return(-1);
-
-#ifdef CKSYMLINK
- islink = 1; /* Assume it's a symlink */
- linkto[0] = '\0'; /* But we don't know to what */
-#ifdef COMMENT
-/*
- This is undependable. If it worked it would save the readlink call if
- we knew the device name was not a link.
-*/
-#ifdef S_ISLNK
- islink = S_ISLNK(devbuf.st_mode);
- debug(F101,"ttlock stat S_ISLNK","",islink);
-#endif /* S_ISLNK */
-#endif /* COMMENT */
- if (islink) {
- n = readlink(ttdev,linkto,DEVNAMLEN); /* See if it's a link */
- debug(F111,"ttlock readlink",ttdev,n);
- if (n > -1) /* It is */
- linkto[n] = '\0';
- else /* It's not */
- islink = 0;
- debug(F111,"ttlock link",linkto,islink);
- }
- if (islink) {
- linkdev = (devname = xxlast(linkto,'/')) ? devname + 1 : linkto;
- debug(F110,"ttlock linkdev",linkdev,0);
- }
-#endif /* CKSYMLINK */
-
-/*
- On SCO platforms, if we don't have a symlink, then let's pretend the
- name given for the device is a symlink, because later we will change
- the name if it contains any uppercase characters.
-*/
-#ifdef CK_SCOV5 /* SCO Open Server 5.0 */
- if (!islink) {
- islink = 1;
- ckstrncpy(linkto,ttdev,DEVNAMLEN);
- linkdev = (devname = xxlast(linkto,'/')) ? devname + 1 : linkto;
- debug(F110,"ttlock linkdev",linkdev,0);
- }
-#else
-#ifdef M_XENIX /* SCO Xenix or UNIX */
- if (!islink) {
- islink = 1;
- ckstrncpy(linkto,ttdev,DEVNAMLEN);
- linkdev = (devname = xxlast(linkto,'/')) ? devname + 1 : linkto;
- debug(F110,"ttlock linkdev",linkdev,0);
- }
-#endif /* M_XENIX */
-#endif /* CK_SCOV5 */
-
-#ifdef ISIII /* Interactive System III, PC/IX */
- ckstrncpy(lockfil, device, DEVNAMLEN);
-#else /* not ISIII */
-#ifdef LFDEVNO /* Lockfilename has device numbers. */
-#ifdef COHERENT
- sprintf(lockfil,"LCK..%d.%d", /* SAFE */
- major(devbuf.st_rdev), /* major device number */
- 0x1f & minor(devbuf.st_rdev)); /* minor device number */
-#else
- /* Note: %d changed to %u in 8.0 -- %u is part of SVID for SVR4 */
- /* Lockfile name format verified to agree with Solaris cu, Dec 2001 */
- sprintf(lockfil,"LK.%03u.%03u.%03u", /* SAFE */
- major(devbuf.st_dev), /* device */
- major(devbuf.st_rdev), /* major device number */
- minor(devbuf.st_rdev)); /* minor device number */
-#endif /* COHERENT */
-#else /* Not LFDEVNO */
-#ifdef PTX /* Dynix PTX */
- if ((device != &ttdev[5]) && (strncmp(ttdev,"/dev/",5) == 0)) {
- if ((int)strlen(device) + 8 < LFNAML)
- sprintf(lockfil,"LCK..%.3s%s", &ttdev[5], device);
- else
- ckstrncpy(lockfil,"LOCKFILE_NAME_TOO_LONG",LFNAML);
- } else
-#endif /* PTX */
- if ((int)strlen(device) + 5 < LFNAML)
- sprintf(lockfil,"LCK..%s", device);
- else
- ckstrncpy(lockfil,"LOCKFILE_NAME_TOO_LONG",LFNAML);
-#ifdef RTAIX
- ckstrncpy(lklockf,device,DEVNAMLEN);
-#endif /* RTAIX */
-#ifdef CKSYMLINK
- symlock[0] = '\0';
- if (islink)
- ckmakmsg(symlock,LFNAML, "LCK..", linkdev, NULL, NULL);
-#endif /* CKSYMLINK */
-#endif /* LFDEVNO */
-#endif /* ISIII */
-
-#ifdef CK_SCOV5 /* SCO Open Server 5.0 */
- {
- /* Lowercase the entire filename. */
- /* SCO says we must do this in V5.0 and later. */
- /* BUT... watch out for devices -- like Digiboard Portserver */
- /* That can have hundreds of ports... */
- char *p = (char *)(lockfil + 5);
- while (*p) { if (isupper(*p)) *p = (char) tolower(*p); p++; }
- }
-#ifdef CKSYMLINK
- if (islink) { /* If no change */
- if (!strcmp(lockfil,symlock)) { /* then no second lockfile needed */
- islink = 0;
- symlock[0] = '\0';
- }
- }
-#endif /* CKSYMLINK */
-#else
-#ifdef M_XENIX /* SCO Xenix or UNIX */
- {
- int x; char c;
- x = (int)strlen(lockfil) - 1; /* Get last letter of device name. */
- if (x > 0) { /* If it's uppercase, lower it. */
- c = lockfil[x];
- if (c >= 'A' && c <= 'Z') lockfil[x] += ('a' - 'A');
- }
- }
-#ifdef CKSYMLINK
- if (islink) {
- if (!strcmp(lockfil,symlock)) { /* No change */
- islink = 0; /* so no second lockfile */
- symlock[0] = '\0';
- }
- }
-#endif /* CKSYMLINK */
-#endif /* M_XENIX */
-#endif /* CK_SCOV5 */
-
-/* flfnam = full lockfile pathname, e.g. "/usr/spool/uucp/LCK..ttyh8" */
-/* tmpnam = temporary unique, e.g. "/usr/spool/uucp/LTMP..pid" */
-
- ckmakmsg(flfnam,LFNAML,lockdir,"/",lockfil,NULL);
-
-#ifdef RTAIX
- ckmakmsg(lkflfn,FLFNAML,lockdir,"/",lklockf,NULL);
-#endif /* RTAIX */
-
-#ifndef LFDEVNO
-#ifdef CKSYMLINK
- /* If it's a link then also make a lockfile for the real name */
- debug(F111,"ttlock link symlock",symlock,islink);
- if (islink && symlock[0]) {
- /* But only if the lockfile names would be different. */
- /* WARNING: They won't be, e.g. for /dev/ttyd2 => /hw/ttys/ttyd2 */
- ckmakmsg(lock2,FLFNAML,lockdir,"/",symlock,NULL);
- debug(F110,"ttlock lock2",lock2,0);
- if (!strcmp(lock2,flfnam)) { /* Are lockfile names the same? */
- debug(F100,"ttlock lock2 cleared","",0);
- lock2[0] = '\0'; /* Clear secondary lockfile name. */
- }
- }
-#endif /* CKSYMLINK */
-#endif /* LFDEVNO */
-
- sprintf(tmpnam,"%s/LTMP.%05d",lockdir,(int) pid); /* safe */
- debug(F110,"ttlock flfnam",flfnam,0);
- debug(F110,"ttlock tmpnam",tmpnam,0);
-
- priv_on(); /* Turn on privileges if possible. */
- lockfd = creat(tmpnam, 0444); /* Try to create temp lock file. */
- if (lockfd < 0) { /* Create failed. */
- debug(F111,"ttlock creat failed",tmpnam,errno);
- if (errno == ENOENT) {
- perror(lockdir);
- printf("UUCP not installed or Kermit misconfigured\n");
- } else {
- if (!quiet)
- perror(lockdir);
- unlink(tmpnam); /* Get rid of the temporary file. */
- }
- priv_off(); /* Turn off privileges!!! */
- return(-1); /* Return failure code. */
- }
-/* Now write the pid into the temp lockfile in the appropriate format */
-
-#ifdef PIDSTRING /* For Honey DanBer UUCP, */
- sprintf( /* write PID as decimal string */
- pid_str,
-#ifdef LINUXFSSTND /* The "Linux File System Standard" */
-#ifdef FSSTND10 /* Version 1.0 calls for */
- "%010d\n", /* leading zeros */
-#else /* while version 1.2 calls for */
- "%10d\n", /* leading spaces */
-#endif /* FSSTND10 */
-#else
-#ifdef COHERENT
- "%d\n", /* with leading nothing */
-#else
- "%10d\n", /* with leading blanks */
-#endif /* COHERENT */
-#endif /* LINUXFSSTND */
- (int) pid
- ); /* safe */
- write(lockfd, pid_str, 11);
- debug(F111,"ttlock hdb pid string",pid_str,(int) pid);
-
-#else /* Not PIDSTRING, use integer PID */
-
- write(lockfd, (char *)&pid, sizeof(pid) );
- debug(F101,"ttlock pid","",(int) pid);
-
-#endif /* PIDSTRING */
-
-/* Now try to rename the temp file to the real lock file name. */
-/* This will fail if a lock file of that name already exists. */
-
- close(lockfd); /* Close the temp lockfile. */
- chmod(tmpnam,0444); /* Permission for a valid lock. */
- tries = 0;
- while (!haslock && tries++ < 2) {
- haslock = (link(tmpnam,flfnam) == 0); /* Create a link to it. */
- if (haslock) { /* If we got the lockfile */
-#ifdef RTAIX
- link(flfnam,lkflfn);
-#endif /* RTAIX */
-#ifdef CKSYMLINK
-#ifndef LFDEVNO
- if (islink && lock2[0])
- link(flfnam,lock2);
-#endif /* LFDEVNO */
-#endif /* CKSYMLINK */
-
-#ifdef COMMENT
-/* Can't do this any more because device is not open yet so no ttyfd. */
-#ifdef LOCKF
-/*
- Advisory file locking works on SVR4, so we use it. In fact, it is
- necessary in some cases, e.g. when SLIP is involved. But it still doesn't
- seem to prevent multiple users accessing the same device by different names.
-*/
- while (lockf(ttyfd, F_TLOCK, 0L) != 0) {
- debug(F111, "ttlock lockf returns errno", "", errno);
- if ((++tries >= 3) || (errno != EAGAIN)) {
- x = unlink(flfnam); /* remove the lockfile */
-#ifdef RTAIX
- unlink(lkflfn); /* And any links to it... */
-#endif /* RTAIX */
-#ifdef CKSYMLINK
-#ifndef LFDEVNO
- if (islink && lock2[0])
- unlink(lock2); /* ditto... */
-#endif /* LFDEVNO */
-#endif /* CKSYMLINK */
- debug(F111,"ttlock unlink",flfnam,x);
- haslock = 0;
- break;
- }
- sleep(2);
- }
- if (haslock) /* If we got an advisory lock */
-#endif /* LOCKF */
-#endif /* COMMENT */
- break; /* We're done. */
-
- } else { /* We didn't create a new lockfile. */
- priv_off();
- if (ttchkpid(flfnam)) { /* Check existing lockfile */
- priv_on(); /* cause ttchkpid turns priv_off... */
- unlink(tmpnam); /* Delete the tempfile */
- debug(F100,"ttlock found tty locked","",0);
- priv_off(); /* Turn off privs */
- return(-2); /* Code for device is in use. */
- }
- priv_on();
- }
- }
- unlink(tmpnam); /* Unlink (remove) the temp file. */
- priv_off(); /* Turn off privs */
- return(haslock ? 0 : -1); /* Return link's return code. */
-
-#else /* HPUX */
-
-/*
- HP-UX gets its own copy of this routine, modeled after the observed behavior
- of the HP-UX 'cu' program. HP-UX serial device names consist of a base name
- such as "tty", "ttyd", "cua", "cul", "cuad", or "culd", followed by a unit
- designator which is a string of digits, possibly containing an imbedded
- letter "p". Examples (for base name "tty"):
-
- /dev/tty0, /dev/tty00, dev/ttyd00, /dev/tty0p0
-
- According to the HP-UX UUCP manual of 1988, the "0p0" notation has been
- used on Series 800 since HP-UX 2.00, and the "non-p" notation was used
- on other models. In HP-UX 10.00, "0p0" notation was adopted for all models.
- However, we make and enforce no such distinctions; either notation is
- accepted on any model or HP-UX version as a valid unit designator.
-
- If a valid unit is specified (as opposed to a designer name or symlink), we
- check for all aliases of the given unit according to the devprefix[] array.
- If no lockfiles are found for the given unit, we can have the device; we
- create a lockfile LCK..name in the lockfile directory appropriate for the
- HP-UX version (/var/spool/locks for 10.00 and later, /usr/spool/uucp for
- 9.xx and earlier). If it is a "cua" or "cul" device, a second lockfile is
- created with the "ttyd" prefix. This is exactly what cu does.
-
- If the "set line" device does not have a valid unit designator, then it is
- used literally and no synomyms are searched for and only one lockfile is
- created.
-
- -fdc, March 1998.
-*/
-#define LFNAML 80 /* Max length for lock file name. */
-
- int lockfd; /* File descriptor for lock file. */
- PID_T pid; /* Process ID of this process. */
- int fpid; /* pid found in existing lockfile. */
- int tries; /* How many times we've tried... */
- int i, k; /* Workers */
-
- char *device, *devname; /* "/dev/xxx", "xxx" */
- char *unit, *p; /* <instance>p<port> part of xxx */
-
- char lockfil[LFNAML]; /* Lockfile name (no path) */
- char tmpnam[LFNAML]; /* Temporary lockfile name. */
-
-#ifdef HPUX10 /* Lockfile directory */
- char *lockdir = "/var/spool/locks"; /* Always this for 10.00 and higher */
-#else /* HP-UX 9.xx and below */
-#ifdef LOCK_DIR
- char *lockdir = LOCK_DIR; /* Defined near top of this file */
-#else
- char *lockdir = "/usr/spool/uucp"; /* or not... */
-#endif /* LOCK_DIR */
-#endif /* HPUX10 */
-
- haslock = 0; /* Not locked yet. */
- *flfnam = '\0'; /* Lockfile name is empty. */
- lock2[0] = '\0'; /* Second one too. */
- pid = getpid(); /* Get my process ID */
-/*
- Construct name of lockfile and temporary file...
- device = name of tty device without the path, e.g. "tty0p0"
- lockfil = name of lock file, without path, e.g. "LCK..tty0p0"
-*/
- device = ((devname = xxlast(ttdev,'/')) != NULL ? devname+1 : ttdev);
- debug(F110,"TTLOCK device",device,0);
- ckmakmsg(lockfil,LFNAML,"LCK..",device,NULL,NULL);
-
- k = 0; /* Assume device is not locked */
- n = 0; /* Digit counter */
- unit = device; /* Unit = <instance>p<port> */
- while (*unit && !isdigit(*unit)) /* Search for digit... */
- unit++;
- p = unit; /* Verify <num>p<num> format... */
- debug(F110,"TTLOCK unit 1",unit,0);
-/*
- The unit number is recognized as:
- (a) any sequence of digits that runs to the end of the string.
- (b) any (a) that includes one and only one letter "p", with at least
- one digit before and after it.
-*/
- while (isdigit(*p)) p++, n++; /* Get a run of digits */
- if (*p && n > 0) { /* Have a "p"? */
- if (*p == 'p' && isdigit(*(p+1))) {
- p++;
- n = 0;
- while (isdigit(*p)) p++, n++;
- }
- }
- if (n == 0 || *p) unit = "";
- debug(F110,"TTLOCK unit 2",unit,0);
-
- if (*unit) { /* Device name has unit number. */
- /* The following loop not only searches for the various lockfile */
- /* synonyms, but also removes all -- not just one -- stale lockfile */
- /* for the device, should there be more than one. See ttchkpid(). */
- ttydexists = 0;
- for (i = 0; *devprefix[i]; i++) { /* For each driver... */
- /* Make device name */
- ckmakmsg(lock2,FLFNAML,"/dev/",devprefix[i],unit,NULL);
- priv_on(); /* Privs on */
- k = zchki(lock2) != -1; /* See if device exists */
- priv_off(); /* Privs off */
- debug(F111,"TTLOCK exist",lock2,k);
- if (k) {
- if (!strcmp(devprefix[i],"ttyd")) /* ttyd device exists */
- ttydexists = 1;
- /* Make lockfile name */
- ckmakmsg(lock2,FLFNAML,lockdir,"/LCK..",devprefix[i],unit);
- debug(F110,"TTLOCK checking",lock2,0);
- priv_on(); /* Privs on */
- k = zchki(lock2) != -1; /* See if lockfile exists */
- priv_off(); /* Privs off */
- debug(F111,"TTLOCK check for lock A",lock2,k);
- if (k) if (ttchkpid(lock2)) { /* If pid still active, fail. */
- ckstrncpy(flfnam,lock2,FLFNAML);
- return(-2);
- }
- }
- }
- } else { /* Some other device-name format */
- /* This takes care of symbolic links, etc... */
- /* But does not chase them down! */
- ckmakmsg(lock2,FLFNAML,lockdir,"/LCK..",device,NULL);
- priv_on();
- k = zchki(lock2) != -1; /* Check for existing lockfile */
- priv_off();
- debug(F111,"TTLOCK check for lock B",lock2,k);
- if (k) if (ttchkpid(lock2)) { /* Check pid from lockfile */
- ckstrncpy(flfnam,lock2,FLFNAML);
- debug(F110,"TTLOCK in use",device,0);
- debug(F101,"TTLOCK returns","",-2);
- return(-2);
- }
- }
-/*
- Get here only if there is no (more) lockfile, so now we make one (or two)...
- flfnam = full lockfile pathname, e.g. "/usr/spool/uucp/LCK..cul0p0".
- tmpnam = unique temporary filname, e.g. "/usr/spool/uucp/LTMP..pid".
-*/
- ckmakmsg(flfnam,FLFNAML,lockdir,"/",lockfil,NULL); /* SET LINE device */
-
- /* If dialout device, also make one for corresponding dialin device */
- lock2[0] = '\0';
- if (!strncmp(device,"cu",2) && *unit && ttydexists)
- ckmakmsg(lock2,FLFNAML,lockdir,"/LCK..ttyd",unit,NULL);
-
- if ((int)strlen(lockdir)+12 < LFNAML)
- sprintf(tmpnam,"%s/LTMP.%05d",lockdir,(int) pid); /* Make temp name */
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"TTLOCK flfnam",flfnam,0);
- debug(F110,"TTLOCK lock2",lock2,0);
- debug(F110,"TTLOCK tmpnam",tmpnam,0);
- }
-#endif /* DEBUG */
-/*
- Lockfile permissions...
- 444 is standard, HP-UX 10.00 uses 664. It doesn't matter.
- Kermit uses 444; the difference lets us tell whether Kermit created
- the lock file.
-*/
- priv_on(); /* Turn on privileges. */
- lockfd = creat(tmpnam, 0444); /* Try to create temporary file. */
- if (lockfd < 0) { /* Create failed. */
- debug(F111,"TTLOCK creat failed",tmpnam,errno);
- if (errno == ENOENT) {
- perror(lockdir);
- printf("UUCP not installed or Kermit misconfigured\n");
- } else {
- if (!quiet)
- perror(lockdir);
- unlink(tmpnam); /* Get rid of the temporary file. */
- }
- priv_off(); /* Turn off privileges!!! */
- debug(F101,"TTLOCK returns","",-1);
- return(-1); /* Return failure code. */
- }
- debug(F110,"TTLOCK temp ok",tmpnam,0);
-
-/* Now write our pid into the temp lockfile in integer format. */
-
- i = write(lockfd, (char *)&pid, sizeof(pid));
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"TTLOCK pid","",pid);
- debug(F101,"TTLOCK sizeof pid","",sizeof(pid));
- debug(F101,"TTLOCK write pid returns","",i);
- }
-#endif /* DEBUG */
-
-/*
- Now try to rename the temporary file to the real lockfile name.
- This will fail if a lock file of that name already exists, which
- will catch race conditions with other users.
-*/
- close(lockfd); /* Close the temp lockfile. */
- chmod(tmpnam,0444);
-
- tries = 0;
- while (!haslock && tries++ < 2) {
- haslock = (link(tmpnam,flfnam) == 0); /* Create a link to it. */
- debug(F101,"TTLOCK link","",haslock);
- if (haslock) { /* If we made the lockfile... */
-
-#ifdef COMMENT
-/* We can't do this any more because we don't have a file descriptor yet. */
-#ifdef LOCKF /* Can be canceled with -DNOLOCKF */
-/*
- Create an advisory lock on the device through its file descriptor.
- This code actually seems to work. If it is executed, and then another
- process tries to open the same device under a different name to circumvent
- the lockfile, they get a "device busy" error.
-*/
- debug(F100,"TTLOCK LOCKF code...","",0);
- while ( lockf(ttyfd, F_TLOCK, 0L) != 0 ) {
- debug(F111, "TTLOCK lockf error", "", errno);
- if ((++tries >= 3) || (errno != EAGAIN)) {
- x = unlink(flfnam); /* Remove the lockfile */
- if (errno == EACCES && !quiet)
- printf("Device already locked by another process\n");
- haslock = 0;
- break;
- }
- sleep(2);
- }
-#endif /* LOCKF */
-#endif /* COMMENT */
-
- if (haslock) { /* If we made the lockfile ... */
- if (lock2[0]) { /* if there is to be a 2nd lockfile */
- lockfd = creat(lock2, 0444); /* Create it */
- debug(F111,"TTLOCK lock2 creat", lock2, lockfd);
- if (lockfd > -1) { /* Created OK, write pid. */
- write(lockfd, (char *)&pid, sizeof(pid) );
- close(lockfd); /* Close and */
- chmod(lock2, 0444); /* set permissions. */
- } else { /* Not OK, but don't fail. */
- lock2[0] = '\0'; /* Just remember it's not there. */
- }
- }
- break; /* and we're done. */
- }
- }
- }
- unlink(tmpnam); /* Unlink (remove) the temp file. */
- priv_off(); /* Turn off privs */
- i = haslock ? 0 : -1; /* Our return value */
- debug(F101,"TTLOCK returns","",i);
- return(i);
-#endif /* HPUX */
-#endif /* USETTYLOCK */
-#endif /* !NOUUCP */
-}
-
-/* T T U N L O C K */
-
-static int
-ttunlck() { /* Remove UUCP lockfile(s). */
-#ifndef NOUUCP
- int x;
-
- debug(F111,"ttunlck",flfnam,haslock);
-
-#ifdef USETTYLOCK
-
- if (haslock && *flfnam) {
- int x;
- priv_on(); /* Turn on privs */
-#ifdef USE_UU_LOCK
- x = uu_unlock(lockname);
-#else /* USE_UU_LOCK */
- x = ttyunlock(lockname); /* Try to unlock */
-#endif /* USE_UU_LOCK */
- priv_off(); /* Turn off privs */
- if (x < 0 && !quiet)
- printf("Warning - Can't remove lockfile: %s\n", flfnam);
-
- *flfnam = '\0'; /* Erase the name. */
- haslock = 0;
- return(0);
- }
-
-#else /* No ttylock()... */
-
- if (haslock && *flfnam) {
- /* Don't remove lockfile if we didn't make it ourselves */
- if ((x = ttrpid(flfnam)) != (int)getpid()) {
- debug(F111,"ttunlck lockfile seized",flfnam,x);
- printf("Warning - Lockfile %s seized by pid %d\n",
- flfnam,
- x
- );
- return(0);
- }
- priv_on(); /* Turn privileges on. */
- errno = 0;
- x = unlink(flfnam); /* Remove the lockfile. */
- debug(F111,"ttunlck unlink",flfnam,x);
- if (x < 0) {
- if (errno && !quiet)
- perror(ttnmsv);
- printf("Warning - Can't remove lockfile: %s\n", flfnam);
- }
- haslock = 0;
- *flfnam = '\0'; /* Erase the name. */
-
-#ifdef RTAIX
- errno = 0;
- x = unlink(lkflfn); /* Remove link to lockfile */
- debug(F111,"ttunlck AIX link unlink",lkflfn,x);
- if (x < 0) {
- if (errno && !quiet)
- perror(ttnmsv);
- printf("Warning - Can't remove link to lockfile: %s\n", lkflfn);
- }
- *lkflfn = '\0';
-#else
- if (lock2[0]) { /* If there is a second lockfile, */
- errno = 0;
- x = unlink(lock2); /* remove it too. */
- debug(F111,"ttunlck lock2 unlink",lock2,x);
- if (x < 0) {
- if (errno && !quiet)
- perror(ttnmsv);
- printf("Warning - Can't remove secondary lockfile: %s\n",
- lock2
- );
- }
- lock2[0] = '\0'; /* Forget its name. */
- }
-#endif /* RTAIX */
-
-#ifdef COMMENT
-#ifdef LOCKF
- (VOID) lockf(ttyfd, F_ULOCK, 0L); /* Remove advisory lock */
-#endif /* LOCKF */
-#endif /* COMMENT */
-
- priv_off(); /* Turn privileges off. */
- }
-#endif /* USETTYLOCK */
-#endif /* !NOUUCP */
- return(0);
-}
-
-/*
- 4.3BSD-style UUCP line direction control.
- (Stan Barber, Rice U, 1980-something...)
-*/
-#ifndef NOUUCP
-#ifdef ACUCNTRL
-VOID
-acucntrl(flag,ttname) char *flag, *ttname; {
- char x[DEVNAMLEN+32], *device, *devname;
-
- if (strcmp(ttname,CTTNAM) == 0 || xlocal == 0) /* If not local, */
- return; /* just return. */
- device = ((devname = xxlast(ttname,'/')) != NULL ? devname+1 : ttname);
- if (strncmp(device,"LCK..",4) == 0) device += 5;
- ckmakmsg(x,DEVNAMLEN+32,"/usr/lib/uucp/acucntrl ",flag," ",device);
- debug(F110,"called ",x,0);
- zsyscmd(x);
-}
-#endif /* ACUCNTRL */
-#endif /* NOUUCP */
-
-/*
- T T H F L O W -- Set or Reset hardware flow control.
-
- This is an attempt to collect all hardware-flow-control related code
- into a single module. Thanks to Rick Sladkey and John Kohl for lots of
- help here. Overview:
-
- Hardware flow control is not supported in many UNIX implementions. Even
- when it is supported, there is no (ha ha) "standard" for the programming
- interface. In general, 4.3BSD and earlier (sometimes), 4.4BSD, System V,
- SunOS, AIX, etc, have totally different methods. (And, not strictly
- relevant here, the programming interface often brings one only to a no-op
- in the device driver!)
-
- Among all these, we have two major types of APIs: those in which hardware
- flow control is determined by bits in the same termio/termios/sgtty mode
- word(s) that are used for controlling such items as CBREAK vs RAW mode, and
- which are also used by the ttvt(), ttpkt(), conbin(), and concb() routines
- for changing terminal modes. And those that use entirely different
- mechanisms.
-
- In the first category, it is important that any change in the mode bits be
- reflected in the relevant termio(s)/sgtty structure, so that subsequent
- changes to that structure do not wipe out the effects of this routine. That
- is why a pointer, attrs, to the appropriate structure is passed as a
- parameter to this routine.
-
- The second category should give us no worries, since any changes to hardware
- flow control accomplished by this routine should not affect the termio(s)/
- sgtty structures, and therefore will not be undone by later changes to them.
-
- The second argument, status, means to turn on hardware flow control if
- nonzero, and to turn it off if zero.
-
- Returns: 0 on apparent success, -1 on probable failure.
-*/
-
-/*
- The following business is for BSDI, where it was discovered that two
- separate bits, CCTS_OFLOW and CRTS_IFLOW, are used in hardware flow control,
- but CTRSCTS is defined (in <termios.h>) to be just CCTS_OFLOW rather both
- bits, so hwfc only works in one direction if you use CRTSCTS to control it.
- Other 4.4BSD-based Unixes such as FreeBSD 4.1, which use these two bits,
- define CRTSCTS correctly.
-*/
-#ifdef FIXCRTSCTS
-#ifdef CRTSCTS
-#ifdef CCTS_OFLOW
-#ifdef CRTS_IFLOW
-#undef CRTSCTS
-#define CRTSCTS (CRTS_IFLOW|CCTS_OFLOW)
-#endif /* CRTS_IFLOW */
-#endif /* CCTS_OFLOW */
-#endif /* CRTSCTS */
-#endif /* FIXCRTSCTS */
-
-static int
-tthflow(flow, status, attrs)
- int flow, /* Type of flow control (ckcdeb.h) */
- status; /* Nonzero = turn it on */
- /* Zero = turn it off */
-#ifdef BSD44ORPOSIX /* POSIX or BSD44 */
- struct termios *attrs;
-#else /* System V */
-#ifdef ATTSV
-#ifdef ATT7300
-#ifdef UNIX351M
-/* AT&T UNIX 3.51m can set but not test for hardware flow control */
-#define RTSFLOW CTSCD
-#define CTSFLOW CTSCD
-#endif /* ATT7300 */
-#endif /* UNIX351M */
- struct termio *attrs;
-#else /* BSD, V7, etc */
- struct sgttyb *attrs; /* sgtty info... */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-/* tthflow */ {
-
- int x = 0; /* tthflow() return code */
-
-#ifdef Plan9
- return p9tthflow(flow, status);
-#else
-
-#ifndef OXOS /* NOT Olivetti X/OS... */
-/*
- For SunOS 4.0 and later in the BSD environment ...
-
- The declarations are copied and interpreted from the System V header files,
- so we don't actually have to pull in all the System V junk when building
- C-Kermit for SunOS in the BSD environment, which would be dangerous because
- having those symbols defined would cause us to take the wrong paths through
- the code. The code in this section is used in both the BSD and Sys V SunOS
- versions.
-*/
-#ifdef SUNOS41
-/*
- In SunOS 4.1 and later, we use the POSIX calls rather than ioctl calls
- because GNU CC uses different formats for the _IOxxx macros than regular CC;
- the POSIX forms work for both. But the POSIX calls are not available in
- SunOS 4.0.
-*/
-#define CRTSCTS 0x80000000 /* RTS/CTS flow control */
-#define TCSANOW 0 /* Do it now */
-
- struct termios {
- unsigned long c_iflag; /* Input modes */
- unsigned long c_oflag; /* Output modes */
- unsigned long c_cflag; /* Control modes */
- unsigned long c_lflag; /* Line discipline modes */
- char c_line;
- CHAR c_cc[17];
- };
- struct termios temp;
-
-_PROTOTYP( int tcgetattr, (int, struct termios *) );
-_PROTOTYP( int tcsetattr, (int, int, struct termios *) );
-/*
- When CRTSCTS is set, SunOS won't do output unless both CTS and CD are
- asserted. So we don't set CRTSCTS unless CD is up. This should be OK,
- since we don't need RTS/CTS during dialing, and after dialing is complete,
- we should have CD. If not, we still communicate, but without RTS/CTS.
-*/
- int mflags; /* Modem signal flags */
-
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-
- debug(F101,"tthflow SUNOS41 entry status","",status);
- if (!status) { /* Turn hard flow off */
- if (tcgetattr(ttyfd, &temp) > -1 && /* Get device attributes */
- (temp.c_cflag & CRTSCTS)) { /* Check for RTS/CTS */
- temp.c_cflag &= ~CRTSCTS; /* It's there, remove it */
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- }
- } else { /* Turn hard flow on */
- if (ioctl(ttyfd,TIOCMGET,&mflags) > -1 && /* Get modem signals */
- (mflags & TIOCM_CAR)) { /* Check for CD */
- debug(F100,"tthflow SunOS has CD","",0);
- if (tcgetattr(ttyfd, &temp) > -1 && /* Get device attributes */
- !(temp.c_cflag & CRTSCTS)) { /* Check for RTS/CTS */
- temp.c_cflag |= CRTSCTS; /* Not there, add it */
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- }
- } else {
- x = -1;
- debug(F100,"tthflow SunOS no CD","",0);
- }
- }
-#else
-#ifdef QNX
- struct termios temp;
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- debug(F101,"tthflow QNX entry status","",status);
- if (tcgetattr(ttyfd, &temp) > -1) { /* Get device attributes */
- if (!status) { /* Turn hard flow off */
- if ((temp.c_cflag & (IHFLOW|OHFLOW)) == (IHFLOW|OHFLOW)) {
- temp.c_cflag &= ~(IHFLOW|OHFLOW); /* It's there, remove it */
- attrs->c_cflag &= ~(IHFLOW|OHFLOW);
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- }
- } else { /* Turn hard flow on */
- if ((temp.c_cflag & (IHFLOW|OHFLOW)) != (IHFLOW|OHFLOW)) {
- temp.c_cflag |= (IHFLOW|OHFLOW); /* Not there, add it */
- temp.c_iflag &= ~(IXON|IXOFF); /* Bye to IXON/IXOFF */
- ttraw.c_lflag |= IEXTEN; /* Must be on */
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- attrs->c_cflag |= (IHFLOW|OHFLOW);
- attrs->c_iflag &= ~(IXON|IXOFF);
- }
- }
- } else {
- x = -1;
- debug(F100, "tthflow QNX getattr fails", "", 0);
- }
-#else
-#ifdef POSIX_CRTSCTS
-/*
- POSIX_CRTSCTS is defined in ckcdeb.h or on CC command line.
- Note: Do not assume CRTSCTS is a one-bit field!
-*/
- struct termios temp;
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- debug(F101,"tthflow POSIX_CRTSCTS entry status","",status);
- errno = 0;
- x = tcgetattr(ttyfd, &temp);
- debug(F111,"tthflow POSIX_CRTSCTS tcgetattr",ckitoa(x),errno);
- errno = 0;
- if (x < 0) {
- x = -1;
- } else {
- if (!status) { /* Turn hard flow off */
- if (
-#ifdef COMMENT
- /* This can fail because of sign extension */
- /* e.g. in Linux where it's Bit 31 */
- (temp.c_cflag & CRTSCTS) == CRTSCTS
-#else
- (temp.c_cflag & CRTSCTS) != 0
-#endif /* COMMENT */
- ) {
- temp.c_cflag &= ~CRTSCTS; /* It's there, remove it */
- attrs->c_cflag &= ~CRTSCTS;
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- debug(F111,"tthflow POSIX_CRTSCTS OFF tcsetattr",
- ckitoa(x),errno);
- } else { /* John Dunlap 2010-01-26 */
- debug(F001,
- "tthflow before forcing off attrs CRTSCTS",
- "",
- attrs->c_cflag&CRTSCTS
- );
- attrs->c_cflag &= ~CRTSCTS; /* force it off if !status */
- debug(F001,
- "tthflow after forcing off attrs CRTSCTS",
- "",
- attrs->c_cflag&CRTSCTS
- );
- }
- } else { /* Turn hard flow on */
- if (
-#ifdef COMMENT
- /* This can fail because of sign extension */
- (temp.c_cflag & CRTSCTS) != CRTSCTS
-#else
- (temp.c_cflag & CRTSCTS) == 0
-#endif /* COMMENT */
- ) {
- temp.c_cflag |= CRTSCTS; /* Not there, add it */
- temp.c_iflag &= ~(IXON|IXOFF|IXANY); /* Bye to IXON/IXOFF */
- x = tcsetattr(ttyfd,TCSANOW,&temp);
- debug(F111,"tthflow POSIX_CRTSCTS ON tcsetattr",
- ckitoa(x),errno);
- attrs->c_cflag |= CRTSCTS;
- attrs->c_iflag &= ~(IXON|IXOFF|IXANY);
- }
- }
- }
-#else
-#ifdef SUNOS4
-/*
- SunOS 4.0 (and maybe earlier?). This code is dangerous because it
- prevents compilation with GNU gcc, which uses different formats for the
- _IORxxx macros than regular cc. SunOS 4.1 and later can use the POSIX
- routines above, which work for both cc and gcc.
-*/
-#define TCGETS _IOR(T, 8, struct termios) /* Get modes into termios struct */
-#define TCSETS _IOW(T, 9, struct termios) /* Set modes from termios struct */
-#define CRTSCTS 0x80000000 /* RTS/CTS flow control */
-
- struct termios {
- unsigned long c_iflag; /* Input modes */
- unsigned long c_oflag; /* Output modes */
- unsigned long c_cflag; /* Control modes */
- unsigned long c_lflag; /* Line discipline modes */
- char c_line;
- CHAR c_cc[17];
- };
- struct termios temp;
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- debug(F101,"tthflow entry status","",status);
- if (ioctl(ttyfd,TCGETS,&temp) > -1) { /* Get terminal modes. */
- if (status) { /* Turn hard flow on */
- temp.c_cflag |= CRTSCTS; /* Add RTS/CTS to them. */
- x = ioctl(ttyfd,TCSETS,&temp); /* Set them again. */
- attrs->c_cflag |= CRTSCTS; /* Add to global info. */
- } else { /* Turn hard flow off */
- temp.c_cflag &= ~CRTSCTS;
- x = ioctl(ttyfd,TCSETS,&temp);
- attrs->c_cflag &= ~CRTSCTS;
- }
- }
-#else /* Not SunOS 4.0 or later */
-#ifdef AIXRS /* IBM AIX RS/6000 */
-#ifndef AIX41 /* But only pre-4.x == SVR4 */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- if (status) {
- if ((x = ioctl(ttyfd, TXADDCD, "rts")) < 0 && errno != EBUSY)
- debug(F100,"hardflow TXADDCD (rts) error", "", 0);
- } else {
- if ((x = ioctl(ttyfd, TXDELCD, "rts")) < 0 && errno != EINVAL)
- debug(F100,"hardflow TXDELCD (rts) error", "", 0);
- }
-#endif /* AIX41 */
-#else /* Not AIX RS/6000 */
-
-#ifdef ATTSV /* System V... */
-
-#ifdef CK_SCOV5 /* SCO Open Server 5.0 */
-#define CK_SCOUNIX
-#else
-#ifdef M_UNIX /* SCO UNIX 3.2v4.x or earlier */
-#define CK_SCOUNIX
-#endif /* M_UNIX */
-#endif /* CK_SCOV5 */
-
-#ifdef SCO_FORCE_RTSXOFF
-#ifdef CK_SCOUNIX /* But not SCO OpenServer 5.0.4 */
-#ifdef SCO_OSR504 /* or later... */
-#undef CK_SCOUNIX
-#endif /* SCO_OSR504 */
-#endif /* CK_SCOUNIX */
-#endif /* SCO_FORCE_RTSXOFF */
-
-#ifdef CK_SCOUNIX
-#ifdef POSIX
- struct termios temp;
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- debug(F101,"tthflow SCOUNIX POSIX entry status","",status);
- errno = 0;
- x = tcgetattr(ttyfd, &temp);
- debug(F111,"tthflow SCO UNIX POSIX tcgetattr",ckitoa(x),errno);
-#else /* POSIX */
- struct termio temp;
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- debug(F101,"tthflow SCOUNIX non-POSIX entry status","",status);
- x = ioctl(ttyfd, TCGETA, &temp);
- debug(F111,"tthflow SCO UNIX non-POSIX TCGETA",ckitoa(x),errno);
-#endif /* POSIX */
-/*
- This is not really POSIX, since POSIX does not deal with hardware flow
- control, but we are using the POSIX APIs. In fact, RTSFLOW and CTSFLOW
- are defined in termio.h, but within #ifndef _POSIX_SOURCE..#endif. So
- let's try forcing their definitions here.
-*/
-#ifndef CTSFLOW
-#define CTSFLOW 0020000
- debug(F101,"tthflow SCO defining CTSFLOW","",CTSFLOW);
-#else
- debug(F101,"tthflow SCO CTSFLOW","",CTSFLOW);
-#endif /* CTSFLOW */
-#ifndef RTSFLOW
-#define RTSFLOW 0040000
- debug(F101,"tthflow SCO defining RTSFLOW","",RTSFLOW);
-#else
- debug(F101,"tthflow SCO RTSFLOW","",RTSFLOW);
-#endif /* RTSFLOW */
-#ifndef ORTSFL
-#define ORTSFL 0100000
- debug(F101,"tthflow SCO defining ORTSFL","",ORTSFL);
-#else
- debug(F101,"tthflow SCO ORTSFL","",ORTSFL);
-#endif /* ORTSFL */
-
- if (x != -1) {
- if (status) { /* Turn it ON */
- temp.c_cflag |= RTSFLOW|CTSFLOW;
- attrs->c_cflag |= RTSFLOW|CTSFLOW;
-#ifdef ORTSFL
- temp.c_cflag &= ~ORTSFL;
- attrs->c_cflag &= ~ORTSFL;
-#endif /* ORTSFL */
- temp.c_iflag &= ~(IXON|IXOFF|IXANY);
- attrs->c_iflag &= ~(IXON|IXOFF|IXANY);
- } else { /* Turn it OFF */
-#ifdef ORTSFL
- temp.c_cflag &= ~(RTSFLOW|CTSFLOW|ORTSFL);
- attrs->c_cflag &= ~(RTSFLOW|CTSFLOW|ORTSFL);
-#else /* ORTSFL */
- temp.c_cflag &= ~(RTSFLOW|CTSFLOW);
- attrs->c_cflag &= ~(RTSFLOW|CTSFLOW);
-#endif /* ORTSFL */
- }
-#ifdef POSIX
- x = tcsetattr(ttyfd, TCSADRAIN, &temp);
-#else
- x = ioctl(ttyfd, TCSETA, &temp);
-#endif /* POSIX */
- debug(F101,"tthflow SCO set modes","",x);
- }
-#else /* Not SCO UNIX */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- if (!status) { /* Turn it OFF */
-#ifdef RTSXOFF
- debug(F100,"tthflow ATTSV RTS/CTS OFF","",0);
- rctsx.x_hflag &= ~(RTSXOFF|CTSXON);
-#ifdef TCSETX
- x = ioctl(ttyfd,TCSETX,&rctsx);
- debug(F101,"tthflow ATTSV TCSETX OFF","",x);
-#else
- x = -1
- debug(F100,"tthflow TCSETX not defined","",0);
-#endif /* TCSETX */
-#else
- debug(F100,"tthflow ATTSV RTSXOFF not defined","",0);
-#endif /* RTSXOFF */
-#ifdef DTRXOFF
- debug(F100,"tthflow ATTSV DTR/CD OFF","",0);
- rctsx.x_hflag &= ~(DTRXOFF|CDXON);
- x = ioctl(ttyfd,TCSETX,&rctsx);
- debug(F101,"tthflow ATTSV DTRXOFF OFF","",x);
-#else
- debug(F100,"tthflow ATTSV DTRXOFF not defined","",0);
-#endif /* DTRXOFF */
- } else { /* Turn it ON. */
- if (flow == FLO_RTSC) { /* RTS/CTS Flow control... */
- debug(F100,"tthflow ATTSV RTS/CTS ON","",0);
-#ifdef RTSXOFF
- /* This is the preferred way, according to SVID3 */
-#ifdef TCGETX
- x = ioctl(ttyfd,TCGETX,&rctsx);
- debug(F101,"tthflow TCGETX","",x);
- if (x > -1) {
- rctsx.x_hflag |= RTSXOFF | CTSXON;
- x = ioctl(ttyfd,TCSETX,&rctsx);
- debug(F100,"tthflow ATTSV ioctl","",x);
- }
-#else
- debug(F100,"tthflow TCGETX not defined","",0);
- x = -1
-#endif /* TCGETX */
-#else
- debug(F100,"tthflow RTSXOFF not defined","",0);
- x = -1;
-#endif /* RTSXOFF */
- } else if (flow == FLO_DTRC) { /* DTR/CD Flow control... */
- debug(F100,"tthflow ATTSV DTR/CD ON","",0);
-#ifdef DTRXOFF
- /* This is straight out of SVID R4 */
- if (ioctl(ttyfd,TCGETX,&rctsx) > -1) {
- rctsx.x_hflag &= ~(DTRXOFF|CDXON);
- x = ioctl(ttyfd,TCSETX,&rctsx);
- }
-#else
- debug(F100,"tthflow ATTSV DTRXOFF not defined","",0);
- x = -1;
-#endif /* DTRXOFF */
- }
- }
-#endif /* CK_SCOUNIX */
-
-#else /* not System V... */
-
-#ifdef CK_DTRCTS
-#ifdef LDODTR
-#ifdef LDOCTS
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- x = LDODTR | LDOCTS; /* Found only on UTEK? */
- if (flow == FLO_DTRT && status) { /* Use hardware flow control */
- if (lmodef) {
- x = ioctl(ttyfd,TIOCLBIS,&x);
- if (x < 0) {
- debug(F100,"hardflow TIOCLBIS error","",0);
- } else {
- lmodef++;
- debug(F100,"hardflow TIOCLBIS ok","",0);
- }
- }
- } else {
- if (lmodef) {
- x = ioctl(ttyfd,TIOCLBIC,&x);
- if (x < 0) {
- debug(F100,"hardflow TIOCLBIC error","",0);
- } else {
- lmodef++;
- debug(F100,"hardflow TIOCLBIC ok","",0);
- }
- }
- }
-#endif /* LDODTR */
-#endif /* LDOCTS */
-#endif /* CK_DTRCTS */
-#endif /* ATTSV */
-#endif /* AIXRS */
-#endif /* SUNOS4 */
-#endif /* QNX */
-#endif /* POSIX_CRTSCTS */
-#endif /* SUNOS41 */
-
-#else /* OXOS */
-
- struct termios temp; /* Olivetti X/OS ... */
-
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
- x = ioctl(ttyfd,TCGETS,&temp);
- if (x == 0) {
- temp.c_cflag &= ~(CRTSCTS|CDTRCTS|CBRKFLOW|CDTRDSR|CRTSDSR);
- if (status) {
- switch (flow) {
- case FLO_RTSC: temp.c_cflag |= CRTSCTS; /* RTS/CTS (hard) */
- break;
- case FLO_DTRT: temp.c_cflag |= CDTRCTS; /* DTR/CTS (hard) */
- break;
- }
- }
- x = ioctl(ttyfd,TCSETS,&temp);
- }
-#endif /* OXOS */
- return(x);
-
-#endif /* Plan9 */
-}
-
-/* T T P K T -- Condition the communication line for packets */
-/* or for modem dialing */
-
-/*
- If called with speed > -1, also set the speed.
- Returns 0 on success, -1 on failure.
-
- NOTE: the "xflow" parameter is supposed to be the currently selected
- type of flow control, but for historical reasons, this parameter is also
- used to indicate that we are dialing. Therefore, when the true flow
- control setting is needed, we access the external variable "flow", rather
- than trusting our "xflow" argument.
-*/
-int
-#ifdef CK_ANSIC
-ttpkt(long speed, int xflow, int parity)
-#else
-ttpkt(speed,xflow,parity) long speed; int xflow, parity;
-#endif /* CK_ANSIC */
-/* ttpkt */ {
-#ifndef NOLOCAL
- int s2;
- int s = -1;
-#endif /* NOLOCAL */
- int x;
- extern int flow; /* REAL flow-control setting */
-
- if (ttyfd < 0) return(-1); /* Not open. */
-
- debug(F101,"ttpkt parity","",parity);
- debug(F101,"ttpkt xflow","",xflow);
- debug(F101,"ttpkt speed","",(int) speed);
-
- ttprty = parity; /* Let other tt functions see these. */
- ttspeed = speed; /* Make global copy for this module */
- ttpmsk = ttprty ? 0177 : 0377; /* Parity stripping mask */
-#ifdef PARSENSE
- needpchk = ttprty ? 0 : 1; /* Parity check needed? */
-#else
- needpchk = 0;
-#endif /* PARSENSE */
-
- debug(F101,"ttpkt ttpmsk","",ttpmsk);
- debug(F101,"ttpkt netconn","",netconn);
-
-#ifdef NETCONN /* No mode-changing for telnet */
- if (netconn) {
-#ifdef TCPSOCKET
-#ifdef TCP_NODELAY
- if (ttnet == NET_TCPB) { /* But turn off Nagle */
- extern int tcp_nodelay;
- nodelay_sav = tcp_nodelay;
- no_delay(ttyfd,1);
- }
-#endif /* TCP_NODELAY */
-#ifdef TN_COMPORT
- if (istncomport()) {
- int rc = -1;
- if (tvtflg == 0 && speed == ttspeed && flow == ttflow
- /* && ttcarr == curcarr */ ) {
- debug(F100,"ttpkt modes already set, skipping...","",0);
- return(0); /* Already been called. */
- }
- if (flow != ttflow) {
- if ((rc = tnsetflow(flow)) < 0)
- return(rc);
- ttflow = flow;
- }
- if (speed != ttspeed) {
- if (speed <= 0)
- speed = tnc_get_baud();
- else if ((rc = tnc_set_baud(speed)) < 0)
- return(rc);
- ttspeed = speed;
- }
- tnc_set_datasize(8);
- tnc_set_stopsize(stopbits);
-
-#ifdef HWPARITY
- if (hwparity) {
- switch (hwparity) {
- case 'e': /* Even */
- debug(F100,"ttres 8 bits + even parity","",0);
- tnc_set_parity(3);
- break;
- case 'o': /* Odd */
- debug(F100,"ttres 8 bits + odd parity","",0);
- tnc_set_parity(2);
- break;
- case 'm': /* Mark */
- debug(F100,"ttres 8 bits + invalid parity: mark","",0);
- tnc_set_parity(4);
- break;
- case 's': /* Space */
- debug(F100,"ttres 8 bits + invalid parity: space","",0);
- tnc_set_parity(5);
- break;
- }
- } else
-#endif /* HWPARITY */
- {
- tnc_set_parity(1); /* None */
- }
- tvtflg = 0;
- return(0);
- }
-#endif /* TN_COMPORT */
-#endif /* TCPSOCKET */
- tvtflg = 0;
- return(0);
- }
-#endif /* NETCONN */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-
-#ifndef Plan9
- if (ttfdflg && !isatty(ttyfd)) return(0);
-#endif /* Plan9 */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifndef SVORPOSIX /* Berkeley, V7, etc. */
-#ifdef LPASS8
-/*
- For some reason, with BSD terminal drivers, you can't set FLOW to XON/XOFF
- after having previously set it to NONE without closing and reopening the
- device. Unless there's something I overlooked below...
-*/
- if (ttflow == FLO_NONE && flow == FLO_XONX && xlocal == 0) {
- debug(F101,"ttpkt executing horrible flow kludge","",0);
- ttclos(0); /* Close it */
- x = 0;
- ttopen(ttnmsv,&x,ttmdm,0); /* Open it again */
- }
-#endif /* LPASS8 */
-#endif /* SVORPOSIX */
-
-#ifdef COHERENT /* This must be vestigial since we */
-#undef SVORPOSIX /* reverse it a few lines below... */
-#endif /* COHERENT */
-
- if (xflow != FLO_DIAL && xflow != FLO_DIAX)
- ttflow = xflow; /* Now make this available too. */
-
-#ifndef NOLOCAL
- if (xlocal) {
- s2 = (int) (speed / 10L); /* Convert bps to cps */
- debug(F101,"ttpkt calling ttsspd","",s2);
- s = ttsspd(s2); /* Check and set the speed */
- debug(F101,"ttpkt ttsspd result","",s);
- carrctl(&ttraw, xflow != FLO_DIAL /* Carrier control */
- && (ttcarr == CAR_ON || (ttcarr == CAR_AUT && ttmdm != 0)));
- tvtflg = 0; /* So ttvt() will work next time */
- }
-#endif /* NOLOCAL */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifndef SVORPOSIX /* BSD section */
- if (flow == FLO_RTSC || /* Hardware flow control */
- flow == FLO_DTRC ||
- flow == FLO_DTRT) {
- tthflow(flow, 1, &ttraw);
- debug(F100,"ttpkt hard flow, TANDEM off, RAW on","",0);
- ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
- ttraw.sg_flags |= RAW; /* Enter raw mode */
- } else if (flow == FLO_NONE) { /* No flow control */
- debug(F100,"ttpkt no flow, TANDEM off, RAW on","",0);
- ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
- tthflow(flow, 0, &ttraw); /* Turn off any hardware f/c too */
- ttraw.sg_flags |= RAW; /* Enter raw mode */
- } else if (flow == FLO_KEEP) { /* Keep device's original setting */
- debug(F100,"ttpkt keeping original TANDEM","",0);
- ttraw.sg_flags &= ~TANDEM;
- ttraw.sg_flags |= (ttold.sg_flags & TANDEM);
- /* NOTE: We should also handle hardware flow control here! */
- }
-
-/* SET FLOW XON/XOFF is in effect, or SET FLOW KEEP resulted in Xon/Xoff */
-
- if ((flow == FLO_XONX) || (ttraw.sg_flags & TANDEM)) {
- debug(F100,"ttpkt turning on TANDEM","",0);
- ttraw.sg_flags |= TANDEM; /* So ask for it. */
-
-#ifdef LPASS8 /* Can pass 8-bit data through? */
-/* If the LPASS8 local mode is available, then flow control can always */
-/* be used, even if parity is none and we are transferring 8-bit data. */
-/* But we only need to do all this if Xon/Xoff is requested. */
-/* BUT... this tends not to work through IP or LAT connections, terminal */
-/* servers, telnet, rlogin, etc, so it is currently disabled. */
- x = LPASS8; /* If LPASS8 defined, then */
- debug(F100,"ttpkt executing LPASS8 code","",0);
- if (lmodef) { /* TIOCLBIS must be too. */
- x = ioctl(ttyfd,TIOCLBIS,&x); /* Try to set LPASS8. */
- if (x < 0) {
- debug(F100,"ttpkt TIOCLBIS error","",0);
- } else {
- lmodef++;
- debug(F100,"ttpkt TIOCLBIS ok","",0);
- }
- }
-/*
- But if we use LPASS8 mode, we must explicitly turn off
- terminal interrupts of all kinds.
-*/
-#ifdef TIOCGETC /* Not rawmode, */
- if (tcharf && (xlocal == 0)) { /* must turn off */
- tchnoi.t_intrc = -1; /* interrupt character */
- tchnoi.t_quitc = -1; /* and quit character. */
- tchnoi.t_startc = 17; /* Make sure xon */
- tchnoi.t_stopc = 19; /* and xoff not ignored. */
-#ifndef NOBRKC
- tchnoi.t_eofc = -1; /* eof character. */
- tchnoi.t_brkc = -1; /* brk character. */
-#endif /* NOBRKC */
- if (ioctl(ttyfd,TIOCSETC,&tchnoi) < 0) {
- debug(F100,"ttpkt TIOCSETC failed","",0);
- } else {
- tcharf = 1;
- debug(F100,"ttpkt TIOCSETC ok","",0);
- }
-#ifdef COMMENT
-/* only for paranoid debugging */
- if (tcharf) {
- struct tchars foo;
- char tchbuf[100];
- ioctl(0,TIOCGETC,&foo);
- sprintf(tchbuf,
- "intr=%d,quit=%d, start=%d, stop=%d, eof=%d, brk=%d",
- foo.t_intrc, foo.t_quitc, foo.t_startc,
- foo.t_stopc, foo.t_eofc, foo.t_brkc);
- debug(F110,"ttpkt chars",tchbuf,0);
- }
-#endif /* COMMENT */
- }
- ttraw.sg_flags |= CBREAK; /* Needed for unknown reason */
-#endif /* TIOCGETC */
-
-/* Prevent suspend during packet mode */
-#ifdef TIOCGLTC /* Not rawmode, */
- if (ltcharf && (xlocal == 0)) { /* must turn off */
- ltchnoi.t_suspc = -1; /* suspend character */
- ltchnoi.t_dsuspc = -1; /* and delayed suspend character */
- if (ioctl(ttyfd,TIOCSLTC,&tchnoi) < 0) {
- debug(F100,"ttpkt TIOCSLTC failed","",0);
- } else {
- ltcharf = 1;
- debug(F100,"ttpkt TIOCSLTC ok","",0);
- }
- }
-#endif /* TIOCGLTC */
-
-#else /* LPASS8 not defined */
-
-/* Previously, BSD-based implementations always */
-/* used rawmode for packets. Now, we use rawmode only if parity is NONE. */
-/* This allows the flow control requested above to actually work, but only */
-/* if the user asks for parity (which also means they get 8th-bit quoting). */
-
- if (parity) { /* If parity, */
- ttraw.sg_flags &= ~RAW; /* use cooked mode */
-#ifdef COMMENT
-/* WHY??? */
- if (xlocal)
-#endif /* COMMENT */
- ttraw.sg_flags |= CBREAK;
- debug(F101,"ttpkt cooked, cbreak, parity","",parity);
-#ifdef TIOCGETC /* Not rawmode, */
- if (tcharf && (xlocal == 0)) { /* must turn off */
- tchnoi.t_intrc = -1; /* interrupt character */
- tchnoi.t_quitc = -1; /* and quit character. */
- tchnoi.t_startc = 17; /* Make sure xon */
- tchnoi.t_stopc = 19; /* and xoff not ignored. */
-#ifndef NOBRKC
- tchnoi.t_eofc = -1; /* eof character. */
- tchnoi.t_brkc = -1; /* brk character. */
-#endif /* NOBRKC */
- if (ioctl(ttyfd,TIOCSETC,&tchnoi) < 0) {
- debug(F100,"ttpkt TIOCSETC failed","",0);
- } else {
- tcharf = 1;
- debug(F100,"ttpkt TIOCSETC ok","",0);
- }
- }
-#endif /* TIOCGETC */
-#ifdef TIOCGLTC /* Not rawmode, */
-/* Prevent suspend during packet mode */
- if (ltcharf && (xlocal == 0)) { /* must turn off */
- ltchnoi.t_suspc = -1; /* suspend character */
- ltchnoi.t_dsuspc = -1; /* and delayed suspend character */
- if (ioctl(ttyfd,TIOCSLTC,&tchnoi) < 0) {
- debug(F100,"ttpkt TIOCSLTC failed","",0);
- } else {
- ltcharf = 1;
- debug(F100,"ttpkt TIOCSLTC ok","",0);
- }
- }
-#endif /* TIOCGLTC */
- } else { /* If no parity, */
- ttraw.sg_flags |= RAW; /* must use 8-bit raw mode. */
- debug(F101,"ttpkt setting rawmode, parity","",parity);
- }
-#endif /* LPASS8 */
- } /* End of Xon/Xoff section */
-
- /* Don't echo, don't map CR to CRLF on output, don't fool with case */
-#ifdef LCASE
- ttraw.sg_flags &= ~(ECHO|CRMOD|LCASE);
-#else
- ttraw.sg_flags &= ~(ECHO|CRMOD);
-#endif /* LCASE */
-
-#ifdef TOWER1
- ttraw.sg_flags &= ~ANYP; /* Must set this on old Towers */
-#endif /* TOWER1 */
-
-#ifdef BELLV10
- if (ioctl(ttyfd,TIOCSETP,&ttraw) < 0) /* Set the new modes. */
- return(-1);
-#else
- errno = 0;
- if (stty(ttyfd,&ttraw) < 0) { /* Set the new modes. */
- debug(F101,"ttpkt stty failed","",errno);
- return(-1);
- }
-#endif /* BELLV10 */
- debug(F100,"ttpkt stty ok","",0);
-
-#ifdef sony_news
- x = xlocal ? km_ext : km_con; /* Put line in ASCII mode. */
- if (x != -1) { /* Make sure we know original modes. */
- x &= ~KM_TTYPE;
- x |= KM_ASCII;
- if (ioctl(ttyfd,TIOCKSET, &x) < 0) {
- perror("ttpkt can't set ASCII mode");
- debug(F101,"ttpkt error setting ASCII mode","",x);
- return(-1);
- }
- }
- debug(F100,"ttpkt set ASCII mode ok","",0);
-#endif /* sony_news */
-
- if (xlocal == 0) { /* Turn this off so we can read */
- signal(SIGINT,SIG_IGN); /* Ctrl-C chars typed at console */
- sigint_ign = 1;
- }
- tvtflg = 0; /* So ttvt() will work next time */
- debug(F100,"ttpkt success","",0);
- return(0);
-
-#endif /* Not ATTSV or POSIX */
-
-/* AT&T UNIX and POSIX */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifdef SVORPOSIX
- if (flow == FLO_XONX) { /* Xon/Xoff */
- ttraw.c_iflag |= (IXON|IXOFF);
- tthflow(flow, 0, &ttraw);
- } else if (flow == FLO_NONE) { /* None */
- /* NOTE: We should also turn off hardware flow control here! */
- ttraw.c_iflag &= ~(IXON|IXOFF);
- tthflow(flow, 0, &ttraw);
- } else if (flow == FLO_KEEP) { /* Keep */
- ttraw.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff flags */
- ttraw.c_iflag |= (ttold.c_iflag & (IXON|IXOFF)); /* OR in old ones */
- /* NOTE: We should also handle hardware flow control here! */
-#ifdef POSIX_CRTSCTS
-/* In Linux case, we do this, which is unlikely to be portable */
- ttraw.c_cflag &= ~CRTSCTS; /* Turn off RTS/CTS flag */
- ttraw.c_cflag |= (ttold.c_cflag & CRTSCTS); /* OR in old one */
-#endif /* POSIX_CRTSCTS */
- } else if (flow == FLO_RTSC || /* Hardware */
- flow == FLO_DTRC ||
- flow == FLO_DTRT) {
- ttraw.c_iflag &= ~(IXON|IXOFF); /* (190) */
- tthflow(flow, 1, &ttraw);
- }
- ttraw.c_lflag &= ~(ICANON|ECHO);
- ttraw.c_lflag &= ~ISIG; /* Do NOT check for interrupt chars */
-
-#ifndef OXOS
-#ifdef QNX
- if (flow != FLO_RTSC && flow != FLO_DTRC && flow != FLO_DTRT)
-#endif /* QNX */
-#ifndef COHERENT
- ttraw.c_lflag &= ~IEXTEN; /* Turn off ^O/^V processing */
-#endif /* COHERENT */
-#else /* OXOS */
- ttraw.c_cc[VDISCARD] = ttraw.c_cc[VLNEXT] = CDISABLE;
-#endif /* OXOS */
- ttraw.c_lflag |= NOFLSH; /* Don't flush */
- ttraw.c_iflag |= IGNPAR; /* Ignore parity errors */
-#ifdef ATTSV
-#ifdef BSD44
- ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|INPCK|ISTRIP|IXANY);
-#else
- ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
-#endif /* BSD44 */
-#else /* POSIX */
- ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|INPCK|ISTRIP);
-#endif /* ATTSV */
- ttraw.c_oflag &= ~OPOST;
- ttraw.c_cflag &= ~(CSIZE);
- ttraw.c_cflag |= (CS8|CREAD|HUPCL);
-
-#ifdef CSTOPB
- if (xlocal) {
- if (stopbits == 2) {
- ttraw.c_cflag |= CSTOPB; /* 2 stop bits */
- debug(F100,"ttpkt 2 stopbits","",0);
- } else if (stopbits == 1) {
- ttraw.c_cflag &= ~(CSTOPB); /* 1 stop bit */
- debug(F100,"ttpkt 1 stopbit","",0);
- }
- }
-#endif /* CSTOPB */
-
-#ifdef HWPARITY
- if (hwparity && xlocal) { /* Hardware parity */
- ttraw.c_cflag |= PARENB; /* Enable parity */
-#ifdef COMMENT
-/* Uncomment this only if needed -- I don't think it is */
- ttraw.c_cflag &= ~(CSIZE); /* Clear out character-size mask */
- ttraw.c_cflag |= CS8; /* And set it to 8 */
-#endif /* COMMENT */
-#ifdef IGNPAR
- ttraw.c_iflag |= IGNPAR; /* Don't discard incoming bytes */
- debug(F100,"ttpkt IGNPAR","",0); /* that have parity errors */
-#endif /* IGNPAR */
- switch (hwparity) {
- case 'e': /* Even */
- ttraw.c_cflag &= ~(PARODD);
- debug(F100,"ttpkt 8 bits + even parity","",0);
- break;
- case 'o': /* Odd */
- ttraw.c_cflag |= PARODD;
- debug(F100,"ttpkt 8 bits + odd parity","",0);
- break;
- case 'm': /* Mark */
- case 's': /* Space */
- /* PAREXT is mentioned in SVID but the details are not given. */
- /* PAREXT is not included in POSIX ISO/IEC 9945-1. */
- debug(F100,"ttpkt 8 bits + invalid parity","",0);
- break;
- }
- } else { /* We handle parity ourselves */
-#endif /* HWPARITY */
- ttraw.c_cflag &= ~(PARENB); /* Don't enable parity */
-#ifdef HWPARITY
- }
-#endif /* HWPARITY */
-
-#ifdef IX370
- ttraw.c_cc[4] = 48; /* So Series/1 doesn't interrupt on every char */
- ttraw.c_cc[5] = 1;
-#else
-#ifndef VEOF /* for DGUX this is VEOF, not VMIN */
- ttraw.c_cc[4] = 1; /* [VMIN] return max of this many characters or */
-#else
-#ifndef OXOS
-#ifdef VMIN
- ttraw.c_cc[VMIN] = 1;
-#endif /* VMIN */
-#else /* OXOS */
- ttraw.c_min = 1;
-#endif /* OXOS */
-#endif /* VEOF */
-#ifndef VEOL /* for DGUX this is VEOL, not VTIME */
- ttraw.c_cc[5] = 0; /* [VTIME] when this many secs/10 expire w/no input */
-#else
-#ifndef OXOS
-#ifdef VTIME
- ttraw.c_cc[VTIME] = 0;
-#endif /* VTIME */
-#else /* OXOS */
- ttraw.c_time = 0;
-#endif /* OXOS */
-#endif /* VEOL */
-#endif /* IX370 */
-
-#ifdef VINTR /* Turn off interrupt character */
- if (xlocal == 0) /* so ^C^C can break us out of */
- ttraw.c_cc[VINTR] = 0; /* packet mode. */
-#endif /* VINTR */
-
-#ifdef Plan9
- if (p9ttyparity('n') < 0)
- return -1;
-#else
-#ifdef BSD44ORPOSIX
- errno = 0;
-#ifdef BEOSORBEBOX
- ttraw.c_cc[VMIN] = 0; /* DR7 can only poll. */
-#endif /* BEOSORBEBOX */
-
-#define TESTING234
-#ifdef TESTING234
- if (1) {
- debug(F100,"ttpkt TESTING234 rawmode","",0);
-
- /* iflags */
- ttraw.c_iflag &= ~(PARMRK|ISTRIP|BRKINT|INLCR|IGNCR|ICRNL);
- ttraw.c_iflag &= ~(INPCK|IGNPAR|IXON|IXOFF);
- ttraw.c_iflag |= IGNBRK;
-#ifdef IMAXBEL
- ttraw.c_iflag &= ~IMAXBEL;
-#endif /* IMAXBEL */
-#ifdef IXANY
- ttraw.c_iflag &= ~IXANY;
-#endif /* IXANY */
-#ifdef IUCLC
- ttraw.c_iflag &= ~IUCLC;
-#endif /* IUCLC */
-
- /* oflags */
- ttraw.c_oflag &= ~OPOST;
-#ifdef OXTABS
- ttraw.c_oflag &= ~OXTABS;
-#endif /* OXTABS */
-#ifdef ONOCR
- ttraw.c_oflag &= ~ONOCR;
-#endif /* ONOCR */
-#ifdef ONLRET
- ttraw.c_oflag &= ~ONLRET;
-#endif /* ONLRET */
-#ifdef ONLCR
- ttraw.c_oflag &= ~ONLCR;
-#endif /* ONLCR */
-
- /* lflags */
- ttraw.c_lflag &= ~ECHO;
-#ifdef ECHOE
- ttraw.c_lflag &= ~ECHOE;
-#endif /* ECHOE */
-#ifdef ECHONL
- ttraw.c_lflag &= ~ECHONL;
-#endif /* ECHONL */
-#ifdef ECHOPRT
- ttraw.c_lflag &= ~ECHOPRT;
-#endif /* ECHOPRT */
-#ifdef ECHOKE
- ttraw.c_lflag &= ~ECHOKE;
-#endif /* ECHOKE */
-#ifdef ECHOCTL
- ttraw.c_lflag &= ~ECHOCTL;
-#endif /* ECHOCTL */
-#ifdef ALTWERASE
- ttraw.c_lflag &= ~ALTWERASE;
-#endif /* ALTWERASE */
-#ifdef EXTPROC
- ttraw.c_lflag &= ~EXTPROC;
-#endif /* EXTPROC */
- ttraw.c_lflag &= ~(ICANON|ISIG|IEXTEN|TOSTOP|FLUSHO|PENDIN);
-#ifdef NOKERNINFO
- ttraw.c_lflag |= NOKERNINFO;
-#endif /* NOKERNINFO */
- /* ttraw.c_lflag |= NOFLSH; */
- ttraw.c_lflag &= ~NOFLSH;
-
- /* cflags */
- ttraw.c_cflag &= ~(CSIZE|PARENB|PARODD);
- ttraw.c_cflag |= CS8|CREAD;
-#ifdef VMIN
- ttraw.c_cc[VMIN] = 1; /* Supposedly needed for AIX */
-#endif /* VMIN */
-
- }
-#endif /* TESTING234 */
-
- debug(F100,"ttpkt calling tcsetattr(TCSETAW)","",0);
- x = tcsetattr(ttyfd,TCSADRAIN,&ttraw);
- debug(F101,"ttpkt BSD44ORPOSIX tcsetattr","",x);
- if (x < 0) {
- debug(F101,"ttpkt BSD44ORPOSIX tcsetattr errno","",errno);
- return(-1);
- }
-#else /* BSD44ORPOSIX */
- x = ioctl(ttyfd,TCSETAW,&ttraw);
- debug(F101,"ttpkt ATTSV ioctl TCSETAW","",x);
- if (x < 0) { /* set new modes . */
- debug(F101,"ttpkt ATTSV ioctl TCSETAW errno","",errno);
- return(-1);
- }
-#endif /* BSD44ORPOSIX */
-#endif /* Plan9 */
- tvtflg = 0;
- debug(F100,"ttpkt ok","",0);
- return(0);
-#endif /* ATTSV */
-
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
-}
-
-/* T T S E T F L O W -- Set flow control immediately. */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-int
-ttsetflow(flow) int flow; {
- if (ttyfd < 0) /* A channel must be open */
- return(-1);
-
- debug(F101,"ttsetflow flow","",flow);
-
-#ifdef TN_COMPORT
- if (netconn && istncomport()) {
- debug(F101,"ttsetflow net modem","",ttmdm);
- return(tnsetflow(flow));
- }
-#endif /* TN_COMPORT */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-
-#ifdef COMMENT
- /* This seems to hurt... */
- if (flow == FLO_KEEP)
- return(0);
-#endif /* COMMENT */
-
- if (flow == FLO_RTSC || /* Hardware flow control... */
- flow == FLO_DTRC ||
- flow == FLO_DTRT) {
- tthflow(flow, 1, &ttraw);
-#ifndef SVORPOSIX
- ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
-#else
- ttraw.c_iflag &= ~(IXON|IXOFF);
-#endif /* SVORPOSIX */
-
- } else if (flow == FLO_XONX) { /* Xon/Xoff... */
-
-#ifndef SVORPOSIX
- ttraw.sg_flags |= TANDEM;
-#else
- ttraw.c_iflag |= (IXON|IXOFF);
-#endif /* SVORPOSIX */
- tthflow(FLO_RTSC, 0, &ttraw); /* Turn off hardware flow control */
-
- } else if (flow == FLO_NONE) { /* No flow control */
-
-#ifndef SVORPOSIX
- ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
-#else
- ttraw.c_iflag &= ~(IXON|IXOFF);
-#endif /* SVORPOSIX */
- tthflow(FLO_RTSC, 0, &ttraw); /* Turn off any hardware f/c too */
- }
-
-/* Set the new modes... */
-
-#ifndef SVORPOSIX /* BSD and friends */
-#ifdef BELLV10
- if (ioctl(ttyfd,TIOCSETP,&ttraw) < 0)
- return(-1);
-#else
-#ifndef MINIX2
- if (stty(ttyfd,&ttraw) < 0)
- return(-1);
-#endif /* MINIX2 */
-#endif /* BELLV10 */
-#else
-#ifdef BSD44ORPOSIX /* POSIX */
- if (tcsetattr(ttyfd,TCSADRAIN,&ttraw) < 0)
- return(-1);
-#else /* System V */
- if (ioctl(ttyfd,TCSETAW,&ttraw) < 0)
- return(-1);
-#endif /* BSD44ORPOSIX */
-#endif /* SVORPOSIX */
- return(0);
-}
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
-/* T T V T -- Condition communication device for use as virtual terminal. */
-
-int
-#ifdef CK_ANSIC
-ttvt(long speed, int flow)
-#else
-ttvt(speed,flow) long speed; int flow;
-#endif /* CK_ANSIC */
-/* ttvt */ {
- int s, s2, x;
-
- debug(F101,"ttvt ttyfd","",ttyfd);
- debug(F101,"ttvt tvtflg","",tvtflg);
- debug(F111,"ttvt speed",ckitoa(ttspeed),speed);
- debug(F111,"ttvt flow",ckitoa(ttflow),flow);
- debug(F111,"ttvt curcarr",ckitoa(ttcarr),curcarr);
-
-/* Note: NetBSD and maybe other BSD44s have cfmakeraw() */
-/* Maybe it would be simpler to use it... */
-
- ttpmsk = 0xff;
-#ifdef NOLOCAL
- return(conbin((char)escchr));
-#else
- if (ttyfd < 0) { /* Not open. */
- if (ttchk() < 0)
- return(-1);
- else /* But maybe something buffered. */
- return(0);
- }
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-#ifdef NETCONN
- if (netconn) {
-#ifdef TCPSOCKET
-#ifdef TCP_NODELAY
- {
- extern int tcp_nodelay;
- if (ttnet == NET_TCPB) {
- if (nodelay_sav > -1) {
- no_delay(ttyfd,nodelay_sav);
- nodelay_sav = -1;
- }
- }
- }
-#endif /* TCP_NODELAY */
-#ifdef TN_COMPORT
- if (istncomport()) {
- int rc = -1;
- if (tvtflg != 0 && speed == ttspeed && flow == ttflow
- /* && ttcarr == curcarr */ ) {
- debug(F100,"ttvt modes already set, skipping...","",0);
- return(0); /* Already been called. */
- }
- if (flow != ttflow) {
- if ((rc = tnsetflow(flow)) < 0)
- return(rc);
- ttflow = flow;
- }
- if (speed != ttspeed) {
- if (speed <= 0)
- speed = tnc_get_baud();
- else if ((rc = tnc_set_baud(speed)) < 0)
- return(rc);
- ttspeed = speed;
- }
- tnc_set_datasize(8);
- tnc_set_stopsize(stopbits);
-
-#ifdef HWPARITY
- if (hwparity) {
- switch (hwparity) {
- case 'e': /* Even */
- debug(F100,"ttres 8 bits + even parity","",0);
- tnc_set_parity(3);
- break;
- case 'o': /* Odd */
- debug(F100,"ttres 8 bits + odd parity","",0);
- tnc_set_parity(2);
- break;
- case 'm': /* Mark */
- debug(F100,"ttres 8 bits + invalid parity: mark","",0);
- tnc_set_parity(4);
- break;
- case 's': /* Space */
- debug(F100,"ttres 8 bits + invalid parity: space","",0);
- tnc_set_parity(5);
- break;
- }
- } else
-#endif /* HWPARITY */
- {
- tnc_set_parity(1); /* None */
- }
- tvtflg = 1;
- return(0);
- }
-#endif /* TN_COMPORT */
-#endif /* TCPSOCKET */
- tvtflg = 1; /* Network connections... */
- debug(F100,"ttvt network connection, skipping...","",0);
- return(0); /* ... require no special setup */
- }
-#endif /* NETCONN */
-
- if (tvtflg != 0 && speed == ttspeed && flow == ttflow
- /* && ttcarr == curcarr */ )
- {
- debug(F100,"ttvt modes already set, skipping...","",0);
- return(0); /* Already been called. */
- }
-
- if (ttfdflg
-#ifndef Plan9
- && !isatty(ttyfd)
-#endif /* Plan9 */
- ) {
- debug(F100,"ttvt using external fd, skipping...","",0);
- return(0);
- }
-
- debug(F100,"ttvt setting modes...","",0);
-
- if (xlocal) { /* For external lines... */
- s2 = (int) (speed / 10L);
- s = ttsspd(s2); /* Check/set the speed */
- carrctl(&tttvt, flow != FLO_DIAL /* Do carrier control */
- && (ttcarr == CAR_ON || (ttcarr == CAR_AUT && ttmdm != 0)));
- } else
- s = s2 = -1;
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifndef SVORPOSIX
- /* Berkeley, V7, etc */
- if (flow == FLO_RTSC || /* Hardware flow control */
- flow == FLO_DTRC ||
- flow == FLO_DTRT) {
- tthflow(flow, 1, &tttvt);
- debug(F100,"ttvt hard flow, TANDEM off","",0);
- tttvt.sg_flags &= ~TANDEM; /* Turn off software flow control */
- } else if (flow == FLO_XONX) { /* Xon/Xoff flow control */
- debug(F100,"ttvt TANDEM on","",0);
- tttvt.sg_flags |= TANDEM; /* Ask for it. */
- tthflow(flow, 0, &tttvt); /* Turn off hardware f/c */
- } else if (flow == FLO_NONE) {
- debug(F100,"ttvt no flow, TANDEM off, RAW on","",0);
- tttvt.sg_flags &= ~TANDEM; /* Turn off software flow control */
- tthflow(flow, 0, &tttvt); /* Turn off any hardware f/c too */
- tttvt.sg_flags |= RAW; /* Enter raw mode */
- } else if (flow == FLO_KEEP) { /* Keep device's original setting */
- debug(F100,"ttvt keeping original TANDEM","",0);
- tttvt.sg_flags &= ~TANDEM;
- tttvt.sg_flags |= (ttold.sg_flags & TANDEM);
- /* NOTE: We should also handle hardware flow control here! */
- }
- tttvt.sg_flags |= RAW; /* Raw mode in all cases */
-#ifdef TOWER1
- tttvt.sg_flags &= ~(ECHO|ANYP); /* No echo or parity */
-#else
- tttvt.sg_flags &= ~ECHO; /* No echo */
-#endif /* TOWER1 */
-
-#ifdef BELLV10
- if (ioctl(ttyfd,TIOCSETP,&tttvt) < 0) /* Set the new modes */
- return(-1);
-#else
- if (stty(ttyfd,&tttvt) < 0) /* Set the new modes */
- return(-1);
-#endif /* BELLV10 */
-
-#else /* It is ATTSV or POSIX */
-
- if (flow == FLO_XONX) { /* Software flow control */
- tttvt.c_iflag |= (IXON|IXOFF); /* On if requested. */
- tthflow(flow, 0, &tttvt); /* Turn off hardware f/c */
- debug(F100,"ttvt SVORPOSIX flow XON/XOFF","",0);
- } else if (flow == FLO_NONE) { /* NONE */
- tttvt.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff */
- tthflow(flow, 0, &tttvt); /* Turn off hardware f/c */
- debug(F100,"ttvt SVORPOSIX flow NONE","",0);
- } else if (flow == FLO_KEEP) {
- tttvt.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff flags */
- tttvt.c_iflag |= (ttold.c_iflag & (IXON|IXOFF)); /* OR in old ones */
-#ifdef POSIX_CRTSCTS
- tttvt.c_cflag &= ~CRTSCTS; /* Turn off RTS/CTS flag */
- tttvt.c_cflag |= (ttold.c_cflag & CRTSCTS); /* OR in old one */
-#endif /* POSIX_CRTSCTS */
- debug(F100,"ttvt SVORPOSIX flow KEEP","",0);
- } else if (flow == FLO_RTSC || /* Hardware flow control */
- flow == FLO_DTRC ||
- flow == FLO_DTRT) {
- tttvt.c_iflag &= ~(IXON|IXOFF); /* (196) */
- tthflow(flow, 1, &tttvt);
- debug(F100,"ttvt SVORPOSIX flow HARD","",0);
- }
-#ifndef OXOS
-#ifdef COHERENT
- tttvt.c_lflag &= ~(ISIG|ICANON|ECHO);
-#else
- tttvt.c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
-#endif /* COHERENT */
-#ifdef QNX
- /* Needed for hwfc */
- if (flow == FLO_RTSC || flow == FLO_DTRC || flow == FLO_DTRT)
- tttvt.c_lflag |= IEXTEN;
-#endif /* QNX */
-#else /* OXOS */
- tttvt.c_lflag &= ~(ISIG|ICANON|ECHO);
- tttvt.c_cc[VDISCARD] = tttvt.c_cc[VLNEXT] = CDISABLE;
-#endif /* OXOS */
-
- tttvt.c_iflag |= (IGNBRK|IGNPAR);
-
-/* Stop bits */
-
-#ifdef CSTOPB
- if (xlocal) {
- if (stopbits == 2) {
- tttvt.c_cflag |= CSTOPB; /* 2 stop bits */
- debug(F100,"ttvt 2 stopbits","",0);
- } else if (stopbits == 1) {
- tttvt.c_cflag &= ~(CSTOPB); /* 1 stop bit */
- debug(F100,"ttvt 1 stopbit","",0);
- }
- }
-#endif /* CSTOPB */
-
-/* Parity */
-
-#ifdef HWPARITY
- if (hwparity && xlocal) { /* Hardware parity */
-#ifdef COMMENT
-/* Uncomment this only if needed -- I don't think it is */
- ttraw.c_cflag &= ~(CSIZE); /* Clear out character-size mask */
- ttraw.c_cflag |= CS8; /* And set it to 8 */
-#endif /* COMMENT */
-#ifdef IGNPAR
- debug(F101,"ttvt hwparity IGNPAR","",IGNPAR);
- tttvt.c_iflag |= IGNPAR; /* Don't discard incoming bytes */
-#endif /* IGNPAR */
- tttvt.c_cflag |= PARENB; /* Enable parity */
-
- switch (hwparity) {
- case 'e': /* Even */
- tttvt.c_cflag &= ~(PARODD);
- debug(F100,"ttvt 8 bits + even parity","",0);
- break;
- case 'o': /* Odd */
- tttvt.c_cflag |= PARODD;
- debug(F100,"ttvt 8 bits + odd parity","",0);
- break;
- case 'm': /* Mark */
- case 's': /* Space */
- /* PAREXT is mentioned in SVID but the details are not given. */
- /* PAREXT is not included in POSIX ISO/IEC 9945-1. */
- debug(F100,"ttvt 8 bits + invalid parity","",0);
- break;
- }
- } else { /* We handle parity ourselves */
-#endif /* HWPARITY */
- tttvt.c_cflag &= ~(PARENB); /* Don't enable parity */
-#ifdef HWPARITY
- }
-#endif /* HWPARITY */
-
-#ifdef ATTSV
-#ifdef BSD44
- /* Things not to do... */
- tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|INPCK|ISTRIP|IXANY);
-#else
- tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
-#endif /* BSD44 */
-#else /* POSIX */
- tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|INPCK|ISTRIP);
-#endif /* ATTSV */
- tttvt.c_cflag &= ~(CSIZE); /* Zero out the char size field */
- tttvt.c_cflag |= (CS8|CREAD|HUPCL); /* Char size 8, enable receiver, hup */
- tttvt.c_oflag &= ~OPOST; /* Don't postprocess output */
-#ifndef VEOF /* DGUX termio has VEOF at entry 4, see comment above */
- tttvt.c_cc[4] = 1;
-#else
-#ifndef OXOS
-#ifdef VMIN
- tttvt.c_cc[VMIN] = 1;
-#endif /* VMIN */
-#else /* OXOS */
- tttvt.c_min = 1;
-#endif /* OXOS */
-#endif /* VEOF */
-#ifndef VEOL /* DGUX termio has VEOL at entry 5, see comment above */
- tttvt.c_cc[5] = 0;
-#else
-#ifndef OXOS
-#ifdef VTIME
- tttvt.c_cc[VTIME] = 0;
-#endif /* VTIME */
-#else /* OXOS */
- tttvt.c_time = 0;
-#endif /* OXOS */
-#endif /* VEOL */
-
-#ifdef Plan9
- if (p9ttyparity('n') < 0)
- return -1;
-#else
-#ifdef BSD44ORPOSIX
- errno = 0;
-#ifdef BEOSORBEBOX
- tttvt.c_cc[VMIN] = 0; /* DR7 can only poll. */
-#endif /* BEOSORBEBOX */
-
- x = tcsetattr(ttyfd,TCSADRAIN,&tttvt);
- debug(F101,"ttvt BSD44ORPOSIX tcsetattr","",x);
- if (x < 0) {
- debug(F101,"ttvt BSD44ORPOSIX tcsetattr errno","",errno);
- return(-1);
- }
-#else /* ATTSV */
- x = ioctl(ttyfd,TCSETAW,&tttvt);
- debug(F101,"ttvt ATTSV ioctl TCSETAW","",x);
- if (x < 0) { /* set new modes . */
- debug(F101,"ttvt ATTSV ioctl TCSETAW errno","",errno);
- return(-1);
- }
-#endif /* BSD44ORPOSIX */
-#endif /* Plan9 */
-#endif /* ATTSV */
-
- ttspeed = speed; /* Done, remember how we were */
- ttflow = flow; /* called, so we can decide how to */
- tvtflg = 1; /* respond next time. */
- debug(F100,"ttvt ok","",0);
- return(0);
-
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
-#endif /* NOLOCAL */
-}
-
-#ifndef NOLOCAL
-
-/* Serial speed department . . . */
-
-/*
- SCO OSR5.0.x might or might not support high speeds. Sometimes they are not
- defined in the header files but they are supported (e.g. when building with
- UDK compiler rather than /bin/cc), sometimes vice versa. Even though 5.0.4
- was the first release that came with high serial speeds standard, releases
- back to 5.0.0 could use them if certain patches (or "supplements") were
- applied to the SIO driver. Plus a lot of SCO installations run third-party
- drivers.
-*/
-#ifdef CK_SCOV5
-#ifndef B38400
-#define B38400 0000017
-#endif /* B38400 */
-#ifndef B57600
-#define B57600 0000021
-#endif /* B57600 */
-#ifndef B76800
-#define B76800 0000022
-#endif /* B76800 */
-#ifndef B115200
-#define B115200 0000023
-#endif /* B115200 */
-#ifndef B230400
-#define B230400 0000024
-#endif /* B230400 */
-#ifndef B460800
-#define B460800 0000025
-#endif /* B460800 */
-#ifndef B921600
-#define B921600 0000026
-#endif /* B921600 */
-#endif /* CK_SCOV5 */
-/*
- Plan 9's native speed setting interface lets you set anything you like,
- but will fail if the hardware doesn't like it, so we allow all the common
- speeds.
-*/
-#ifdef Plan9
-#ifndef B50
-#define B50 50
-#endif /* B50 */
-#ifndef B75
-#define B75 75
-#endif /* B75 */
-#ifndef B110
-#define B110 110
-#endif /* B110 */
-#ifndef B134
-#define B134 134
-#endif /* B134 */
-#ifndef B200
-#define B200 200
-#endif /* B200 */
-#ifndef B300
-#define B300 300
-#endif /* B300 */
-#ifndef B1200
-#define B1200 1200
-#endif /* B1200 */
-#ifndef B1800
-#define B1800 1800
-#endif /* B1800 */
-#ifndef B2400
-#define B2400 2400
-#endif /* B2400 */
-#ifndef B4800
-#define B4800 4800
-#endif /* B4800 */
-#ifndef B9600
-#define B9600 9600
-#endif /* B9600 */
-#ifndef B14400
-#define B14400 14400
-#endif /* B14400 */
-#ifndef B19200
-#define B19200 19200
-#endif /* B19200 */
-#ifndef B28800
-#define B28800 28800
-#endif /* B28800 */
-#ifndef B38400
-#define B38400 38400
-#endif /* B38400 */
-#ifndef B57600
-#define B57600 57600
-#endif /* B57600 */
-#ifndef B76800
-#define B76800 76800
-#endif /* B76800 */
-#ifndef B115200
-#define B115200 115200
-#endif /* B115200 */
-#ifndef B230400
-#define B230400 230400
-#endif /* B230400 */
-#ifndef B460800
-#define B460800 460800
-#endif /* B460800 */
-#ifndef B921600
-#define B921600 921600
-#endif /* B921600 */
-#endif /* Plan9 */
-
-/* T T S S P D -- Checks and sets transmission rate. */
-
-/* Call with speed in characters (not bits!) per second. */
-/* Returns -1 on failure, 0 if it did nothing, 1 if it changed the speed. */
-
-#ifdef USETCSETSPEED
-/*
- The tcsetspeed() / tcgetspeed() interface lets you pass any number at all
- to be used as a speed to be set, rather than forcing a choice from a
- predefined list. It seems to be peculiar to UnixWare 7.
-
- These are the function codes to be passed to tc[gs]etspeed(),
- but for some reason they don't seem to be picked up from termios.h.
-*/
-#ifndef TCS_ALL
-#define TCS_ALL 0
-#endif /* TCS_ALL */
-#ifndef TCS_IN
-#define TCS_IN 1
-#endif /* TCS_IN */
-#ifndef TCS_OUT
-#define TCS_OUT 2
-#endif /* TCS_OUT */
-#endif /* USETCSETSPEED */
-
-int
-ttsspd(cps) int cps; {
- int x;
-#ifdef POSIX
-/* Watch out, speed_t should be unsigned, so don't compare with -1, etc... */
- speed_t
-#else
- int
-#endif /* POSIX */
- s, s2;
- int ok = 1; /* Speed check result, assume ok */
-
-#ifdef OLINUXHISPEED
- unsigned int spd_flags = 0;
- struct serial_struct serinfo;
-#endif /* OLINUXHISPEED */
-
- debug(F101,"ttsspd cps","",cps);
- debug(F101,"ttsspd ttyfd","",ttyfd);
- debug(F101,"ttsspd xlocal","",xlocal);
-
- if (ttyfd < 0 || xlocal == 0) /* Don't set speed on console */
- return(0);
-
-#ifdef NETCONN
- if (netconn) {
-#ifdef TN_COMPORT
- if (istncomport())
- return(tnc_set_baud(cps * 10));
- else
-#endif /* TN_COMPORT */
- return(0);
- }
-#endif /* NETCONN */
-#ifdef NETCMD
- if (ttpipe) return(0);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(0);
-#endif /* NETPTY */
-
- if (cps < 0) return(-1);
- s = s2 = 0; /* NB: s and s2 might be unsigned */
-
-#ifdef USETCSETSPEED
-
- s = cps * 10L;
-
- x = tcgetattr(ttyfd,&ttcur); /* Get current speed */
- debug(F101,"ttsspd tcgetattr","",x);
- if (x < 0)
- return(-1);
- debug(F101,"ttsspd TCSETSPEED speed","",s);
-
- errno = 0;
- if (s == 8880L) { /* 75/1200 split speed requested */
- tcsetspeed(TCS_IN, &ttcur, 1200L);
- tcsetspeed(TCS_OUT, &ttcur, 75L);
- } else
- tcsetspeed(TCS_ALL, &ttcur, s); /* Put new speed in structs */
-#ifdef DEBUG
- if (errno & deblog) {
- debug(F101,"ttsspd TCSETSPEED errno","",errno);
- }
-#endif /* DEBUG */
-
-#ifdef COMMENT
- tcsetspeed(TCS_ALL, &ttraw, s);
- tcsetspeed(TCS_ALL, &tttvt, s);
- tcsetspeed(TCS_ALL, &ttold, s);
-#else
- if (s == 8880L) { /* 75/1200 split speed requested */
- tcsetspeed(TCS_IN, &ttraw, 1200L);
- tcsetspeed(TCS_OUT, &ttraw, 75L);
- tcsetspeed(TCS_IN, &tttvt, 1200L);
- tcsetspeed(TCS_OUT, &tttvt, 75L);
- tcsetspeed(TCS_IN, &ttold, 1200L);
- tcsetspeed(TCS_OUT, &ttold, 75L);
- } else {
- tcsetspeed(TCS_ALL, &ttraw, s);
- tcsetspeed(TCS_ALL, &tttvt, s);
- tcsetspeed(TCS_ALL, &ttold, s);
- }
-#endif /* COMMENT */
-
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur); /* Set the speed */
- debug(F101,"ttsspd tcsetattr","",x);
- if (x < 0)
- return(-1);
-
-#else /* Not USETCSETSPEED */
-
- /* First check that the given speed is valid. */
-
- switch (cps) {
-#ifndef MINIX
- case 0: s = B0; break;
- case 5: s = B50; break;
- case 7: s = B75; break;
-#endif /* MINIX */
- case 11: s = B110; break;
-#ifndef MINIX
- case 13: s = B134; break;
- case 15: s = B150; break;
- case 20: s = B200; break;
-#endif /* MINIX */
- case 30: s = B300; break;
-#ifndef MINIX
- case 60: s = B600; break;
-#endif /* MINIX */
- case 120: s = B1200; break;
-#ifndef MINIX
- case 180: s = B1800; break;
-#endif /* MINIX */
- case 240: s = B2400; break;
- case 480: s = B4800; break;
-#ifndef MINIX
- case 888: s = B75; s2 = B1200; break; /* 888 = 75/1200 split speed */
-#endif /* MINIX */
-#ifdef B7200
- case 720: s = B7200; break;
-#endif /* B7200 */
- case 960: s = B9600; break;
-#ifdef B14400
- case 1440: s = B14400; break;
-#endif /* B14400 */
-#ifdef B19200
- case 1920: s = B19200; break;
-#else
-#ifdef EXTA
- case 1920: s = EXTA; break;
-#endif /* EXTA */
-#endif /* B19200 */
-#ifdef B28800
- case 2880: s = B28800; break;
-#endif /* B28800 */
-#ifdef B38400
- case 3840: s = B38400;
-#ifdef OLINUXHISPEED
- spd_flags = ~ASYNC_SPD_MASK; /* Nonzero, but zero flags */
-#endif /* OLINUXHISPEED */
- break;
-#else /* B38400 not defined... */
-#ifdef EXTB
- case 3840: s = EXTB; break;
-#endif /* EXTB */
-#endif /* B38400 */
-
-#ifdef HPUX
-#ifdef _B57600
- case 5760: s = _B57600; break;
-#endif /* _B57600 */
-#ifdef _B115200
- case 11520: s = _B115200; break;
-#endif /* _B115200 */
-#else
-#ifdef OLINUXHISPEED
-/*
- This bit from <carlo@sg.tn.tudelft.nl>:
- "Only note to make is maybe this: When the ASYNC_SPD_CUST flags are set then
- setting the speed to 38400 will set the custom speed (and ttgspd returns
- 38400), but speeds 57600 and 115200 won't work any more because I didn't
- want to mess up the speed flags when someone is doing sophisticated stuff
- like custom speeds..."
-*/
- case 5760: s = B38400; spd_flags = ASYNC_SPD_HI; break;
- case 11520: s = B38400; spd_flags = ASYNC_SPD_VHI; break;
-#else
-#ifdef B57600
- case 5760: s = B57600; break;
-#endif /* B57600 */
-#ifdef B76800
- case 7680: s = B76800; break;
-#endif /* B76800 */
-#ifdef B115200
- case 11520: s = B115200; break;
-#endif /* B115200 */
-#endif /* OLINUXHISPEED */
-#ifdef B153600
- case 15360: s = B153600; break;
-#endif /* B153600 */
-#ifdef B230400
- case 23040: s = B230400; break;
-#endif /* B230400 */
-#ifdef B307200
- case 30720: s = B307200; break;
-#endif /* B307200 */
-#ifdef B460800
- case 46080: s = B460800; break;
-#endif /* 460800 */
-#ifdef B921600
- case 92160: s = B921600; break;
-#endif /* B921600 */
-#endif /* HPUX */
- default:
- ok = 0; /* Good speed not found, so not ok */
- break;
- }
- debug(F101,"ttsspd ok","",ok);
- debug(F101,"ttsspd s","",s);
-
- if (!ok) {
- debug(F100,"ttsspd fails","",0);
- return(-1);
- } else {
- if (!s2) s2 = s; /* Set input speed */
-#ifdef Plan9
- if (p9ttsspd(cps) < 0)
- return(-1);
-#else
-#ifdef BSD44ORPOSIX
- x = tcgetattr(ttyfd,&ttcur); /* Get current speed */
- debug(F101,"ttsspd tcgetattr","",x);
- if (x < 0)
- return(-1);
-#ifdef OLINUXHISPEED
- debug(F101,"ttsspd spd_flags","",spd_flags);
- if (spd_flags && spd_flags != ASYNC_SPD_CUST) {
- if (ioctl(ttyfd, TIOCGSERIAL, &serinfo) < 0) {
- debug(F100,"ttsspd: TIOCGSERIAL failed","",0);
- return(-1);
- } else debug(F100,"ttsspd: TIOCGSERIAL ok","",0);
- serinfo.flags &= ~ASYNC_SPD_MASK;
- serinfo.flags |= (spd_flags & ASYNC_SPD_MASK);
- if (ioctl(ttyfd, TIOCSSERIAL, &serinfo) < 0)
- return(-1);
- }
-#endif /* OLINUXHISPEED */
- cfsetospeed(&ttcur,s);
- cfsetispeed(&ttcur,s2);
- cfsetospeed(&ttraw,s);
- cfsetispeed(&ttraw,s2);
- cfsetospeed(&tttvt,s);
- cfsetispeed(&tttvt,s2);
- cfsetospeed(&ttold,s);
- cfsetispeed(&ttold,s2);
- x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
- debug(F101,"ttsspd tcsetattr","",x);
- if (x < 0) return(-1);
-#else
-#ifdef ATTSV
- if (cps == 888) return(-1); /* No split speeds, sorry. */
- x = ioctl(ttyfd,TCGETA,&ttcur);
- debug(F101,"ttsspd TCGETA ioctl","",x);
- if (x < 0) return(-1);
- ttcur.c_cflag &= ~CBAUD;
- ttcur.c_cflag |= s;
- tttvt.c_cflag &= ~CBAUD;
- tttvt.c_cflag |= s;
- ttraw.c_cflag &= ~CBAUD;
- ttraw.c_cflag |= s;
- ttold.c_cflag &= ~CBAUD;
- ttold.c_cflag |= s;
- x = ioctl(ttyfd,TCSETAW,&ttcur);
- debug(F101,"ttsspd TCSETAW ioctl","",x);
- if (x < 0) return(-1);
-#else
-#ifdef BELLV10
- x = ioctl(ttyfd,TIOCGDEV,&tdcur);
- debug(F101,"ttsspd TIOCGDEV ioctl","",x);
- if (x < 0) return(-1);
- tdcur.ispeed = s2;
- tdcur.ospeed = s;
- errno = 0;
- ok = ioctl(ttyfd,TIOCSDEV,&tdcur);
- debug(F101,"ttsspd BELLV10 ioctl","",ok);
- if (ok < 0) {
- perror(ttnmsv);
- debug(F101,"ttsspd BELLV10 errno","",ok);
- return(-1);
- }
-#else
- x = gtty(ttyfd,&ttcur);
- debug(F101,"ttsspd gtty","",x);
- if (x < 0) return(-1);
- ttcur.sg_ospeed = s; ttcur.sg_ispeed = s2;
- tttvt.sg_ospeed = s; tttvt.sg_ispeed = s2;
- ttraw.sg_ospeed = s; ttraw.sg_ispeed = s2;
- ttold.sg_ospeed = s; ttold.sg_ispeed = s2;
- x = stty(ttyfd,&ttcur);
- debug(F101,"ttsspd stty","",x);
- if (x < 0) return(-1);
-#endif /* BELLV10 */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-#endif /* Plan9 */
- }
- return(1); /* Return 1 = success. */
-#endif /* USETCSETSPEED */
-}
-
-#endif /* NOLOCAL */
-
-/* C O N G S P D - Get speed of console terminal */
-
-long
-congspd() {
-/*
- This is a disgusting hack. The right way to do this would be to pass an
- argument to ttgspd(), but then we'd need to change the Kermit API and
- all of the ck?tio.c modules. (Currently used only for rlogin.)
-*/
- int t1;
- long spd;
-#ifdef NETCONN
- int t2 = netconn;
- netconn = 0;
-#endif /* NETCONN */
- t1 = ttyfd;
- ttyfd = -1;
- spd = ttgspd();
- debug(F101,"congspd","",spd);
-#ifdef NETCONN
- netconn = t2;
-#endif /* NETCONN */
- ttyfd = t1;
- return(spd);
-}
-
-/* T T S P D L I S T -- Get list of serial speeds allowed on this platform */
-
-#define NSPDLIST 64
-static long spdlist[NSPDLIST];
-/*
- As written, this picks up the speeds known at compile time, and thus
- apply to the system where C-Kermit was built, rather than to the one where
- it is running. Suggestions for improvement are always welcome.
-*/
-long *
-ttspdlist() {
- int i;
- for (i = 0; i < NSPDLIST; i++) /* Initialize the list */
- spdlist[i] = -1L;
- i = 1;
-
-#ifdef USETCSETSPEED /* No way to find out what's legal */
- debug(F100,"ttspdlist USETCSETSPEED","",0);
- spdlist[i++] = 50L;
-#ifndef UW7
- spdlist[i++] = 75L;
-#endif /* UW7 */
- spdlist[i++] = 110L;
-#ifndef UW7
- spdlist[i++] = 134L;
-#endif /* UW7 */
- spdlist[i++] = 150L;
- spdlist[i++] = 200L;
- spdlist[i++] = 300L;
- spdlist[i++] = 600L;
- spdlist[i++] = 1200L;
- spdlist[i++] = 1800L;
- spdlist[i++] = 2400L;
- spdlist[i++] = 4800L;
- spdlist[i++] = 8880L;
- spdlist[i++] = 9600L;
- spdlist[i++] = 14400L;
- spdlist[i++] = 19200L;
- spdlist[i++] = 28800L;
-#ifndef UW7
- spdlist[i++] = 33600L;
-#endif /* UW7 */
- spdlist[i++] = 38400L;
- spdlist[i++] = 57600L;
- spdlist[i++] = 76800L;
- spdlist[i++] = 115200L;
-#ifndef UW7
- spdlist[i++] = 153600L;
- spdlist[i++] = 230400L;
- spdlist[i++] = 307200L;
- spdlist[i++] = 460800L;
- spdlist[i++] = 921600L;
-#endif /* UW7 */
-
-#else /* USETCSETSPEED */
-
- debug(F100,"ttspdlist no USETCSETSPEED","",0);
-
-#ifdef B50
- debug(F101,"ttspdlist B50","",B50);
- spdlist[i++] = 50L;
-#endif /* B50 */
-#ifdef B75
- debug(F101,"ttspdlist B75","",B75);
- spdlist[i++] = 75L;
-#endif /* B75 */
-#ifdef B110
- debug(F101,"ttspdlist B110","",B110);
- spdlist[i++] = 110L;
-#endif /* B110 */
-#ifdef B134
- debug(F101,"ttspdlist B134","",B134);
- spdlist[i++] = 134L;
-#endif /* B134 */
-#ifdef B150
- debug(F101,"ttspdlist B150","",B150);
- spdlist[i++] = 150L;
-#endif /* B150 */
-#ifdef B200
- debug(F101,"ttspdlist B200","",B200);
- spdlist[i++] = 200L;
-#endif /* B200 */
-#ifdef B300
- debug(F101,"ttspdlist B300","",B300);
- spdlist[i++] = 300L;
-#endif /* B300 */
-#ifdef B600
- debug(F101,"ttspdlist B600","",B600);
- spdlist[i++] = 600L;
-#endif /* B600 */
-#ifdef B1200
- debug(F101,"ttspdlist B1200","",B1200);
- spdlist[i++] = 1200L;
-#endif /* B1200 */
-#ifdef B1800
- debug(F101,"ttspdlist B1800","",B1800);
- spdlist[i++] = 1800L;
-#endif /* B1800 */
-#ifdef B2400
- debug(F101,"ttspdlist B2400","",B2400);
- spdlist[i++] = 2400L;
-#endif /* B2400 */
-#ifdef B4800
- debug(F101,"ttspdlist B4800","",B4800);
- spdlist[i++] = 4800L;
-#endif /* B4800 */
-#ifdef B9600
- debug(F101,"ttspdlist B9600","",B9600);
- spdlist[i++] = 9600L;
-#endif /* B9600 */
-#ifdef B14400
- debug(F101,"ttspdlist B14400","",B14400);
- spdlist[i++] = 14400L;
-#endif /* B14400 */
-#ifdef B19200
- debug(F101,"ttspdlist B19200","",B19200);
- spdlist[i++] = 19200L;
-#else
-#ifdef EXTA
- debug(F101,"ttspdlist EXTA","",EXTA);
- spdlist[i++] = 19200L;
-#endif /* EXTA */
-#endif /* B19200 */
-#ifdef B28800
- debug(F101,"ttspdlist B28800","",B28800);
- spdlist[i++] = 28800L;
-#endif /* B28800 */
-#ifdef B33600
- debug(F101,"ttspdlist B33600","",B33600);
- spdlist[i++] = 33600L;
-#endif /* B33600 */
-#ifdef B38400
- debug(F101,"ttspdlist B38400","",B38400);
- spdlist[i++] = 38400L;
-#else
-#ifdef EXTB
- debug(F101,"ttspdlist EXTB","",EXTB);
- spdlist[i++] = 38400L;
-#endif /* EXTB */
-#endif /* B38400 */
-#ifdef _B57600
- debug(F101,"ttspdlist _B57600","",_B57600);
- spdlist[i++] = 57600L;
-#else
-#ifdef B57600
- debug(F101,"ttspdlist B57600","",B57600);
- spdlist[i++] = 57600L;
-#endif /* B57600 */
-#endif /* _B57600 */
-#ifdef B76800
- debug(F101,"ttspdlist B76800","",B76800);
- spdlist[i++] = 76800L;
-#endif /* B76800 */
-#ifdef _B115200
- debug(F101,"ttspdlist _B115200","",_B115200);
- spdlist[i++] = 115200L;
-#else
-#ifdef B115200
- debug(F101,"ttspdlist B115200","",B115200);
- spdlist[i++] = 115200L;
-#endif /* B115200 */
-#endif /* _B115200 */
-#ifdef B153600
- debug(F101,"ttspdlist B153600","",B153600);
- spdlist[i++] = 153600L;
-#endif /* B153600 */
-#ifdef B230400
- debug(F101,"ttspdlist B230400","",B230400);
- spdlist[i++] = 230400L;
-#endif /* B230400 */
-#ifdef B307200
- debug(F101,"ttspdlist B307200","",B307200);
- spdlist[i++] = 307200L;
-#endif /* B307200 */
-#ifdef B460800
- debug(F101,"ttspdlist B460800","",B460800);
- spdlist[i++] = 460800L;
-#endif /* B460800 */
-#ifdef B921600
- debug(F101,"ttspdlist B921600","",B921600);
- spdlist[i++] = 921600L;
-#endif /* B921600 */
-#endif /* USETCSETSPEED */
- spdlist[0] = i - 1; /* Return count in 0th element */
- debug(F111,"ttspdlist spdlist","0",spdlist[0]);
- return((long *)spdlist);
-}
-
-/* T T G S P D - Get speed of currently selected tty line */
-
-/*
- Unreliable. After SET LINE, it returns an actual speed, but not necessarily
- the real speed. On some systems, it returns the line's nominal speed, from
- /etc/ttytab. Even if you SET SPEED to something else, this function might
- not notice.
-*/
-long
-ttgspd() { /* Get current serial device speed */
-#ifdef NOLOCAL
- return(-1L);
-#else
-#ifdef POSIX
- speed_t /* Should be unsigned */
-#else
- int /* Isn't unsigned */
-#endif /* POSIX */
- s;
- int x;
- long ss;
-#ifdef OLINUXHISPEED
- unsigned int spd_flags = 0;
- struct serial_struct serinfo;
-#endif /* OLINUXHISPEED */
-
-#ifdef NETCONN
- if (netconn) {
-#ifdef TN_COMPORT
- if (istncomport())
- return(tnc_get_baud());
- else
-#endif /* TN_COMPORT */
- return(-1); /* -1 if network connection */
- }
-#endif /* NETCONN */
-#ifdef NETCMD
- if (ttpipe) return(-1);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(-1);
-#endif /* NETPTY */
-
- debug(F101,"ttgspd ttyfd","",ttyfd);
-
-#ifdef USETCSETSPEED
-
- x = tcgetattr(ttyfd,&ttcur); /* Get current speed */
- debug(F101,"ttgspd tcgetattr","",x);
- if (x < 0)
- return(-1);
- errno = 0;
- s = tcgetspeed(TCS_ALL, &ttcur);
- debug(F101,"ttsspd TCGETSPEED speed","",s);
- if (s == 0) {
- long s1, s2;
- s1 = tcgetspeed(TCS_IN, &ttcur);
- s2 = tcgetspeed(TCS_OUT, &ttcur);
- if (s1 == 1200L && s2 == 75L)
- return(8880L);
- }
-#ifdef DEBUG
- if (errno & deblog) {
- debug(F101,"ttsspd TCGETSPEED errno","",errno);
- }
-#endif /* DEBUG */
- return(s);
-
-#else /* Not USETCSETSPEED */
-
-#ifdef Plan9
- if (ttyfd < 0)
- ss = -1;
- else
- ss = ttylastspeed;
-#else
-#ifdef OLINUXHISPEED
- debug(F100,"ttgspd Linux OLINUXHISPEED","",0);
-#endif /* OLINUXHISPEED */
-
- if (ttyfd < 0) {
-#ifdef BSD44ORPOSIX
- s = cfgetospeed(&ccold);
- debug(F101,"ttgspd cfgetospeed 1 POSIX","",s);
-#else
-#ifdef ATTSV
- s = ccold.c_cflag & CBAUD;
- debug(F101,"ttgspd c_cflag CBAUD 1 ATTSV","",s);
-#else
- s = ccold.sg_ospeed; /* (obtained by congm()) */
- debug(F101,"ttgspd sg_ospeed 1","",s);
-#endif /* ATTSV */
-#endif /* BSD44POSIX */
-
- } else {
-#ifdef BSD44ORPOSIX
- if (tcgetattr(ttyfd,&ttcur) < 0) return(-1);
- s = cfgetospeed(&ttcur);
- debug(F101,"ttgspd cfgetospeed 2 BSDORPOSIX","",s);
-#ifdef OLINUXHISPEED
- if (ioctl(ttyfd,TIOCGSERIAL,&serinfo) > -1)
- spd_flags = serinfo.flags & ASYNC_SPD_MASK;
- debug(F101,"ttgspd spd_flags","",spd_flags);
-#endif /* OLINUXHISPEED */
-#else
-#ifdef ATTSV
- x = ioctl(ttyfd,TCGETA,&ttcur);
- debug(F101,"ttgspd ioctl 2 ATTSV x","",x);
- debug(F101,"ttgspd ioctl 2 ATTSV errno","",errno);
- if (x < 0) return(-1);
- s = ttcur.c_cflag & CBAUD;
- debug(F101,"ttgspd ioctl 2 ATTSV speed","",s);
-#else
-#ifdef BELLV10
- x = ioctl(ttyfd,TIOCGDEV,&tdcur);
- debug(F101,"ttgspd ioctl 2 BELLV10 x","",x);
- if (x < 0) return(-1);
- s = tdcur.ospeed;
- debug(F101,"ttgspd ioctl 2 BELLV10 speed","",s);
-#else
- x = gtty(ttyfd,&ttcur);
- debug(F101,"ttgspd gtty 2 x","",x);
- debug(F101,"ttgspd gtty 2 errno","",errno);
- if (x < 0) return(-1);
- s = ttcur.sg_ospeed;
- debug(F101,"ttgspd gtty 2 speed","",s);
-#endif /* BELLV10 */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
- }
- debug(F101,"ttgspd code","",s);
-#ifdef OLINUXHISPEED
- debug(F101,"ttgspd spd_flags","",spd_flags);
-#endif /* OLINUXHISPEED */
- switch (s) {
-#ifdef B0
- case B0: ss = 0L; break;
-#endif /* B0 */
-
-#ifndef MINIX
-/*
- MINIX defines the Bxx symbols to be bps/100, so B50==B75, B110==B134==B150,
- etc, making for many "duplicate case in switch" errors, which are fatal.
-*/
-#ifdef B50
- case B50: ss = 50L; break;
-#endif /* B50 */
-#ifdef B75
- case B75: ss = 75L; break;
-#endif /* B75 */
-#endif /* MINIX */
-
-#ifdef B110
- case B110: ss = 110L; break;
-#endif /* B110 */
-
-#ifndef MINIX
-#ifdef B134
- case B134: ss = 134L; break;
-#endif /* B134 */
-#ifdef B150
- case B150: ss = 150L; break;
-#endif /* B150 */
-#endif /* MINIX */
-
-#ifdef B200
- case B200: ss = 200L; break;
-#endif /* B200 */
-
-#ifdef B300
- case B300: ss = 300L; break;
-#endif /* B300 */
-
-#ifdef B600
- case B600: ss = 600L; break;
-#endif /* B600 */
-
-#ifdef B1200
- case B1200: ss = 1200L; break;
-#endif /* B1200 */
-
-#ifdef B1800
- case B1800: ss = 1800L; break;
-#endif /* B1800 */
-
-#ifdef B2400
- case B2400: ss = 2400L; break;
-#endif /* B2400 */
-
-#ifdef B4800
- case B4800: ss = 4800L; break;
-#endif /* B4800 */
-
-#ifdef B7200
- case B7200: ss = 7200L; break;
-#endif /* B7200 */
-
-#ifdef B9600
- case B9600: ss = 9600L; break;
-#endif /* B9600 */
-
-#ifdef B19200
- case B19200: ss = 19200L; break;
-#else
-#ifdef EXTA
- case EXTA: ss = 19200L; break;
-#endif /* EXTA */
-#endif /* B19200 */
-
-#ifndef MINIX
-#ifdef B38400
- case B38400:
- ss = 38400L;
-#ifdef OLINUXHISPEED
- switch(spd_flags) {
- case ASYNC_SPD_HI: ss = 57600L; break;
- case ASYNC_SPD_VHI: ss = 115200L; break;
- }
-#endif /* OLINUXHISPEED */
- break;
-#else
-#ifdef EXTB
- case EXTB: ss = 38400L; break;
-#endif /* EXTB */
-#endif /* B38400 */
-#endif /* MINIX */
-
-#ifdef HPUX
-#ifdef _B57600
- case _B57600: ss = 57600L; break;
-#endif /* _B57600 */
-#ifdef _B115200
- case _B115200: ss = 115200L; break;
-#endif /* _B115200 */
-#else
-#ifdef B57600
- case B57600: ss = 57600L; break;
-#endif /* B57600 */
-#ifdef B76800
- case B76800: ss = 76800L; break;
-#endif /* B76800 */
-#ifdef B115200
- case B115200: ss = 115200L; break;
-#endif /* B115200 */
-#ifdef B153600
- case B153600: ss = 153600L; break;
-#endif /* B153600 */
-#ifdef B230400
- case B230400: ss = 230400L; break;
-#endif /* B230400 */
-#ifdef B307200
- case B307200: ss = 307200L; break;
-#endif /* B307200 */
-#ifdef B460800
- case B460800: ss = 460800L; break;
-#endif /* B460800 */
-#endif /* HPUX */
-#ifdef B921600
- case B921600: ss = 921600L; break;
-#endif /* B921600 */
- default:
- ss = -1; break;
- }
-#endif /* Plan9 */
- debug(F101,"ttgspd speed","",ss);
- return(ss);
-
-#endif /* USETCSETSPEED */
-#endif /* NOLOCAL */
-}
-#ifdef MINIX2 /* Another hack alert */
-#define MINIX
-#endif /* MINIX2 */
-
-/*
- FIONREAD data type... This has been defined as "long" for many, many
- years, and it worked OK until 64-bit platforms appeared. Thus we use
- int for 64-bit platforms, but keep long for the others. If we changed
- the default PEEKTYPE to int, this would probably break 16-bit builds
- (note that sizeof(long) == sizeof(int) on most 32-bit platforms), many
- of which we have no way of testing any more. Therefore, do not change
- the default definition of PEEKTYPE -- only add exceptions to it as needed.
-*/
-#ifdef COHERENT
-#ifdef FIONREAD
-#undef FIONREAD
-#endif /* FIONREAD */
-/* #define FIONREAD TIOCQUERY */
-/* #define PEEKTYPE int */
-#else /* Not COHERENT... */
-
-#ifdef OSF32 /* Digital UNIX 3.2 or higher */
-#define PEEKTYPE int
-#else
-#define PEEKTYPE long /* Elsewhere (see notes above) */
-#endif /* OSF32 */
-#endif /* COHERENT */
-
-/* ckumyr.c by Kristoffer Eriksson, ske@pkmab.se, 15 Mar 1990. */
-
-#ifdef MYREAD
-
-/* Private buffer for myread() and its companions. Not for use by anything
- * else. ttflui() is allowed to reset them to initial values. ttchk() is
- * allowed to read my_count.
- *
- * my_item is an index into mybuf[]. Increment it *before* reading mybuf[].
- *
- * A global parity mask variable could be useful too. We could use it to
- * let myread() strip the parity on its own, instead of stripping sign
- * bits as it does now.
- */
-#ifdef BIGBUFOK
-#define MYBUFLEN 32768
-#else
-#ifdef pdp11
-#define MYBUFLEN 256
-#else
-#define MYBUFLEN 1024
-#endif /* pdp11 */
-#endif /* BIGBUFOK */
-
-#ifdef ANYX25
-#undef MYBUFLEN
-#define MYBUFLEN 256
-/*
- On X.25 connections, there is an extra control byte at the beginning.
-*/
-static CHAR x25buf[MYBUFLEN+1]; /* Communication device input buffer */
-static CHAR *mybuf = x25buf+1;
-#else
-static CHAR mybuf[MYBUFLEN];
-#endif /* ANYX25 */
-
-static int my_count = 0; /* Number of chars still in mybuf */
-static int my_item = -1; /* Last index read from mybuf[] */
-
-/* T T P E E K -- Peek into our internal communications input buffers. */
-
-/*
- NOTE: This routine is peculiar to UNIX, and is used only by the
- select()-based CONNECT module, ckucns.c. It need not be replicated in
- the ck?tio.c of other platforms.
-*/
-int
-ttpeek() {
-#ifdef TTLEBUF
- int rc = 0;
- if (ttpush >= 0)
- rc++;
- rc += le_inbuf();
- if (rc > 0)
- return(rc);
- else
-#endif /* TTLEBUF */
-
-#ifdef MYREAD
- return(my_count);
-#else
- return(0);
-#endif /* MYREAD */
-}
-
-/* myread() -- Efficient read of one character from communications line.
- *
- * NOTE: myread() and its helpers mygetbuf() and myfillbuf() return raw
- * bytes from connection, so when the connection is encrypted, these bytes
- * must be decrypted.
- *
- * Uses a private buffer to minimize the number of expensive read() system
- * calls. Essentially performs the equivalent of read() of 1 character, which
- * is then returned. By reading all available input from the system buffers
- * to the private buffer in one chunk, and then working from this buffer, the
- * number of system calls is reduced in any case where more than one character
- * arrives during the processing of the previous chunk, for instance high
- * baud rates or network type connections where input arrives in packets.
- * If the time needed for a read() system call approaches the time for more
- * than one character to arrive, then this mechanism automatically compensates
- * for that by performing bigger read()s less frequently. If the system load
- * is high, the same mechanism compensates for that too.
- *
- * myread() is a macro that returns the next character from the buffer. If the
- * buffer is empty, mygetbuf() is called. See mygetbuf() for possible error
- * returns.
- *
- * This should be efficient enough for any one-character-at-a-time loops.
- * For even better efficiency you might use memcpy()/bcopy() or such between
- * buffers (since they are often better optimized for copying), but it may not
- * be worth it if you have to take an extra pass over the buffer to strip
- * parity and check for CTRL-C anyway.
- *
- * Note that if you have been using myread() from another program module, you
- * may have some trouble accessing this macro version and the private variables
- * it uses. In that case, just add a function in this module, that invokes the
- * macro.
- */
-#define myread() (--my_count < 0 ? mygetbuf() : 255 & (int)mybuf[++my_item])
-
-/* Specification: Push back up to one character onto myread()'s queue.
- *
- * This implementation: Push back characters into mybuf. At least one character
- * must have been read through myread() before myunrd() may be used. After
- * EOF or read error, again, myunrd() can not be used. Sometimes more than
- * one character can be pushed back, but only one character is guaranteed.
- * Since a previous myread() must have read its character out of mybuf[],
- * that guarantees that there is space for at least one character. If push
- * back was really needed after EOF, a small addition could provide that.
- *
- * As of 02/2007 myunrd() is used by ttinl().
- */
-VOID
-#ifdef CK_ANSIC
-myunrd(CHAR ch)
-#else
-myunrd(ch) CHAR ch;
-#endif /* CK_ANSIC */
-{
- if (my_item >= 0) {
- mybuf[my_item--] = ch;
- ++my_count;
- }
-}
-
-/* T T P U S H B A C K -- Put n bytes back into the myread buffer */
-
-static CHAR * pushbuf = NULL;
-/* static int pushed = 0; */
-
-int
-ttpushback(s,n) CHAR * s; int n; {
- debug(F101,"ttpushback n","",n);
- if (pushbuf || n > MYBUFLEN || n < 1)
- return(-1);
- debug(F101,"ttpushback my_count","",my_count);
- if (my_count > 0) {
- if (!(pushbuf = (CHAR *)malloc(n+1)))
- return(-1);
- memcpy(pushbuf,mybuf,my_count);
- /* pushed = my_count; */ /* (set but never used) */
- }
- memcpy(mybuf,s,n);
- my_count = n;
- my_item = -1;
- return(0);
-}
-
-/* mygetbuf() -- Fill buffer for myread() and return first character.
- *
- * This function is what myread() uses when it can't get the next character
- * directly from its buffer. First, it calls a system dependent myfillbuf()
- * to read at least one new character into the buffer, and then it returns
- * the first character just as myread() would have done. This function also
- * is responsible for all error conditions that myread() can indicate.
- *
- * Returns: When OK => a positive character, 0 or greater.
- * When EOF => -2.
- * When error => -3, error code in errno.
- *
- * Older myread()s additionally returned -1 to indicate that there was nothing
- * to read, upon which the caller would call myread() again until it got
- * something. The new myread()/mygetbuf() always gets something. If it
- * doesn't, then make it do so! Any program that actually depends on the old
- * behaviour will break.
- *
- * The older version also used to return -2 both for EOF and other errors,
- * and used to set errno to 9999 on EOF. The errno stuff is gone, EOF and
- * other errors now return different results, although Kermit currently never
- * checks to see which it was. It just disconnects in both cases.
- *
- * Kermit lets the user use the quit key to perform some special commands
- * during file transfer. This causes read(), and thus also mygetbuf(), to
- * finish without reading anything and return the EINTR error. This should
- * be checked by the caller. Mygetbuf() could retry the read() on EINTR,
- * but if there is nothing to read, this could delay Kermit's reaction to
- * the command, and make Kermit appear unresponsive.
- *
- * The debug() call should be removed for optimum performance.
- */
-int
-mygetbuf() {
- int x;
- errno = 0;
-#ifdef DEBUG
- if (deblog && my_count > 0)
- debug(F101,"mygetbuf IMPROPERLY CALLED with my_count","",my_count);
-#endif /* DEBUG */
- if (my_count <= 0)
- my_count = myfillbuf();
-
-#ifdef DEBUG
-#ifdef COMMENT
- if (deblog) debug(F101, "mygetbuf read", "", my_count);
-#else /* COMMENT */
- ckhexdump("mygetbuf read", mybuf, my_count);
-#endif /* COMMENT */
-#endif /* DEBUG */
- x = my_count;
- if (my_count <= 0) {
- my_count = 0;
- my_item = -1;
- debug(F101,"mygetbuf errno","",errno);
-#ifdef TCPSOCKET
- if (netconn && ttnet == NET_TCPB && errno != 0) {
- if (errno != EINTR) {
- debug(F101,"mygetbuf TCP error","",errno);
- ttclos(0); /* Close the connection. */
- }
- return(-3);
- }
-#endif /* TCPSOCKET */
- if (!netconn && xlocal && errno) {
- if (errno != EINTR) {
- debug(F101,"mygetbuf SERIAL error","",errno);
- x = -3;
- ttclos(0); /* Close the connection. */
- }
- }
- return((x < 0) ? -3 : -2);
- }
- --my_count;
- return((unsigned)(0xff & mybuf[my_item = 0]));
-}
-
-/* myfillbuf():
- * System-dependent read() into mybuf[], as many characters as possible.
- *
- * Returns: OK => number of characters read, always more than zero.
- * EOF => 0
- * Error => -1, error code in errno.
- *
- * If there is input available in the system's buffers, all of it should be
- * read into mybuf[] and the function return immediately. If no input is
- * available, it should wait for a character to arrive, and return with that
- * one in mybuf[] as soon as possible. It may wait somewhat past the first
- * character, but be aware that any such delay lengthens the packet turnaround
- * time during kermit file transfers. Should never return with zero characters
- * unless EOF or irrecoverable read error.
- *
- * Correct functioning depends on the correct tty parameters being used.
- * Better control of current parameters is required than may have been the
- * case in older Kermit releases. For instance, O_NDELAY (or equivalent) can
- * no longer be sometimes off and sometimes on like it used to, unless a
- * special myfillbuf() is written to handle that. Otherwise the ordinary
- * myfillbuf()s may think they have come to EOF.
- *
- * If your system has a facility to directly perform the functioning of
- * myfillbuf(), then use it. If the system can tell you how many characters
- * are available in its buffers, then read that amount (but not less than 1).
- * If the system can return a special indication when you try to read without
- * anything to read, while allowing you to read all there is when there is
- * something, you may loop until there is something to read, but probably that
- * is not good for the system load.
- */
-
-#ifdef SVORPOSIX
- /* This is for System III/V with VMIN>0, VTIME=0 and O_NDELAY off,
- * and CLOCAL set any way you like. This way, read() will do exactly
- * what is required by myfillbuf(): If there is data in the buffers
- * of the O.S., all available data is read into mybuf, up to the size
- * of mybuf. If there is none, the first character to arrive is
- * awaited and returned.
- */
-int
-myfillbuf() {
- int fd, n;
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef sxaE50
- /* From S. Dezawa at Fujifilm in Japan. I don't know why this is */
- /* necessary for the sxa E50, but it is. */
- return read(fd, mybuf, 255);
-#else
-#ifdef BEOSORBEBOX
- while (1) {
-#ifdef NETCONN
- if (netconn) {
- n = netxin(sizeof(mybuf), (char *)mybuf);
- debug(F101,"BEBOX SVORPOSIX network myfillbuf","",n);
- }
- else
-#endif /* NETCONN */
- n = read(fd, mybuf, sizeof(mybuf));
- debug(F101,"BEBOX SVORPOSIX notnet myfillbuf","",n);
- if (n > 0)
- return(n);
- snooze(1000.0);
- }
-#else /* BEOSORBEBOX */
- errno = 0;
- /* debug(F101,"SVORPOSIX myfillbuf calling read() fd","",fd); */
-#ifdef IBMX25
- if (netconn && (nettype == NET_IX25)) {
- /* can't use sizeof because mybuf is a pointer, and not an array! */
- n = x25xin( MYBUFLEN, mybuf );
- } else
-#endif /* IBMX25 */
-
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error, n = 0;
- debug(F100,"myfillbuf calling SSL_read() fd","",0);
- while (n == 0) {
- if (ssl_active_flag)
- n = SSL_read(ssl_con, (char *)mybuf, sizeof(mybuf));
- else if (tls_active_flag)
- n = SSL_read(tls_con, (char *)mybuf, sizeof(mybuf));
- else
- break;
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,n)) {
- case SSL_ERROR_NONE:
- if (n > 0)
- return(n);
- if (n < 0)
- return(-2);
- msleep(50);
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(-1);
- case SSL_ERROR_SYSCALL:
- if (n != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- ttclos(0);
- return(-3);
- }
- }
- }
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- debug(F101,"myfillbuf calling krb4_des_read() fd","",ttyfd);
- if ((n = krb4_des_read(ttyfd,(char *)mybuf,sizeof(mybuf))) < 0)
- return(-3);
- else
- return(n);
- }
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- debug(F101,"myfillbuf calling krb5_des_read() fd","",ttyfd);
- if ((n = krb5_des_read(ttyfd,(char *)mybuf,sizeof(mybuf),0)) < 0)
- return(-3);
- else
- return(n);
- }
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- debug(F101,"myfillbuf calling krb5_u2u_read() fd","",ttyfd);
- if ((n = krb5_u2u_read(ttyfd,(char *)mybuf,sizeof(mybuf))) < 0)
- return(-3);
- else
- return(n);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef NETPTY
-#ifdef HAVE_PTYTRAP
- /* Special handling for HP-UX pty i/o */
- ptyread:
- if (ttpty && pty_trap_pending(ttyfd) > 0) {
- debug(F101,"myfillbuf calling pty_trap_handler() fd","",ttyfd);
- if (pty_trap_handler(ttyfd) > 0) {
- ttclos(0);
- return(-3);
- }
- }
-#endif /* HAVE_PTYTRAP */
-#endif /* NETPTY */
- debug(F101,"myfillbuf calling read() fd","",ttyfd);
- n = read(fd, mybuf, sizeof(mybuf));
- debug(F101,"SVORPOSIX myfillbuf read","",n);
- debug(F101,"SVORPOSIX myfillbuf errno","",errno);
- debug(F101,"SVORPOSIX myfillbuf ttcarr","",ttcarr);
- if (n < 1) {
-#ifdef NETPTY
-#ifdef HAVE_PTYTRAP
- /* When we have a PTY trap in place the connection cannot */
- /* be closed until the trap receives a close indication. */
- if (n == 0 && ttpty)
- goto ptyread;
-#endif /* HAVE_PTYTRAP */
-#endif /* NETPTY */
- return(-3);
- }
- return(n);
-#endif /* BEOSORBEBOX */
-#endif /* sxaE50 */
-}
-
-#else /* not AT&T or POSIX */
-
-#ifdef aegis
- /* This is quoted from the old myread(). The semantics seem to be
- * alright, but maybe errno would not need to be set even when
- * there is no error? I don't know aegis.
- */
-int
-myfillbuf() {
- int count;
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
- count = ios_$get((short)fd, ios_$cond_opt, mybuf, 256L, st);
- errno = EIO;
- if (st.all == ios_$get_conditional_failed) /* get at least one */
- count = ios_$get((short)fd, 0, mybuf, 1L, st);
- if (st.all == ios_$end_of_file)
- return(-3);
- else if (st.all != status_$ok) {
- errno = EIO;
- return(-1);
- }
- return(count > 0 ? count : -3);
-}
-#else /* !aegis */
-
-#ifdef FIONREAD
- /* This is for systems with FIONREAD. FIONREAD returns the number
- * of characters available for reading. If none are available, wait
- * until something arrives, otherwise return all there is.
- */
-int
-myfillbuf() {
- PEEKTYPE avail = 0;
- int x, fd;
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef SUNX25
-/*
- SunLink X.25 support in this routine from Stefaan A. Eeckels, Eurostat (CEC).
- Depends on SunOS having FIONREAD, not because we use it, but just so this
- code is grouped correctly within the #ifdefs. Let's hope Solaris keeps it.
-
- We call x25xin() instead of read() so that Q-Bit packets, which contain
- X.25 service-level information (e.g. PAD parameter changes), can be processed
- transparently to the upper-level code. This is a blocking read, and so
- we depend on higher-level code (such as ttinc()) to set any necessary alarms.
-*/
- extern int nettype;
- if (netconn && nettype == NET_SX25) {
- while ((x = x25xin(sizeof(x25buf), x25buf)) < 1) ;
- return(x - 1); /* "-1" compensates for extra status byte */
- }
-#endif /* SUNX25 */
-
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error, n = 0;
- while (n == 0) {
- if (ssl_active_flag)
- n = SSL_read(ssl_con, (char *)mybuf, sizeof(mybuf));
- else
- n = SSL_read(tls_con, (char *)mybuf, sizeof(mybuf));
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,n)) {
- case SSL_ERROR_NONE:
- if (n > 0)
- return(n);
- if (n < 0)
- return(-2);
- msleep(50);
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(-1);
- case SSL_ERROR_SYSCALL:
- if (n != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- ttclos(0);
- return(-2);
- }
- }
- }
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- if ((x = krb4_des_read(ttyfd,mybuf,sizeof(mybuf))) < 0)
- return(-1);
- else
- return(x);
- }
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- if ((x = krb5_des_read(ttyfd,mybuf,sizeof(mybuf),0)) < 0)
- return(-1);
- else
- return(x);
- }
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- if ((x = krb5_u2u_read(ttyfd,mybuf,sizeof(mybuf))) < 0)
- return(-1);
- else
- return(x);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
- errno = 0;
- debug(F101,"myfillbuf calling FIONREAD ioctl","",xlocal);
- x = ioctl(fd, FIONREAD, &avail);
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"myfillbuf FIONREAD","",x);
- debug(F101,"myfillbuf FIONREAD avail","",avail);
- debug(F101,"myfillbuf FIONREAD errno","",errno);
- }
-#endif /* DEBUG */
- if (x < 0 || avail == 0)
- avail = 1;
-
- if (avail > MYBUFLEN)
- avail = MYBUFLEN;
-
- errno = 0;
-
- x = read(fd, mybuf, (int) avail);
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"myfillbuf avail","",avail);
- debug(F101,"myfillbuf read","",x);
- debug(F101,"myfillbuf read errno","",errno);
- if (x > 0)
- ckhexdump("myfillbuf mybuf",mybuf,x);
- }
-#endif /* DEBUG */
- if (x < 1) x = -3; /* read 0 == connection loss */
- return(x);
-}
-
-#else /* !FIONREAD */
-/* Add other systems here, between #ifdef and #else, e.g. NETCONN. */
-/* When there is no other possibility, read 1 character at a time. */
-int
-myfillbuf() {
- int x;
-
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error, n = 0;
- while (n == 0) {
- if (ssl_active_flag)
- n = SSL_read(ssl_con, (char *)mybuf, sizeof(mybuf));
- else
- count = SSL_read(tls_con, (char *)mybuf, sizeof(mybuf));
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,n)) {
- case SSL_ERROR_NONE:
- if (n > 0)
- return(n);
- if (n < 0)
- return(-2);
- msleep(50);
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(-1);
- case SSL_ERROR_SYSCALL:
- if (n != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- ttclos(0);
- return(-2);
- }
- }
- }
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- if ((len = krb4_des_read(ttyfd,mybuf,sizeof(mybuf))) < 0)
- return(-1);
- else
- return(len);
- }
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- if ((len = krb5_des_read(ttyfd,mybuf,sizeof(mybuf),0)) < 0)
- return(-1);
- else
- return(len);
- }
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- if ((len = krb5_u2u_read(ttyfd,mybuf,sizeof(mybuf))) < 0)
- return(-1);
- else
- return(len);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
- x = read(fd, mybuf, 1);
- return(x > 0 ? x : -3);
-}
-
-#endif /* !FIONREAD */
-#endif /* !aegis */
-#endif /* !ATTSV */
-
-#endif /* MYREAD */
-
-/* T T _ T N O P T -- Handle Telnet negotions in incoming data */
-/*
- Call with the IAC that was encountered.
- Returns:
- -3: If connection has dropped or gone bad.
- -2: On Telnet protocol error resulting in inconsistent states.
- 0: If negotiation OK and caller has nothing to do.
- 1: If packet start character has changed (new value is in global stchr).
- 255: If there was a quoted IAC as data.
- or: Not at all if we got a legitimate Telnet Logout request.
-*/
-#ifdef TCPSOCKET
-static int
-tt_tnopt(n) int n; { /* Handle Telnet options */
- /* In case caller did not already check these conditions... */
- if (n == IAC &&
- ((xlocal && netconn && IS_TELNET()) ||
- (!xlocal && sstelnet))) {
- extern int server;
- int tx = 0;
- debug(F100,"ttinl calling tn_doop()","",0);
- tx = tn_doop((CHAR)(n & 0xff),duplex,ttinc);
- debug(F111,"ttinl tn_doop() returned","tx",tx);
- switch (tx) {
- case 0:
- return(0);
- case -1: /* I/O error */
- ttimoff(); /* Turn off timer */
- return(-3);
- case -2: /* Connection failed. */
- case -3:
- ttimoff(); /* Turn off timer */
- ttclos(0);
- return(-3);
- case 1: /* ECHO change */
- duplex = 1;
- return(0);
- case 2: /* ECHO change */
- duplex = 0;
- return(0);
- case 3: /* Quoted IAC */
- n = 255;
- return((unsigned)255);
-#ifdef IKS_OPTION
- case 4: {
- if (TELOPT_SB(TELOPT_KERMIT).kermit.u_start && server
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- ) { /* Remote in Server mode */
- ttimoff(); /* Turn off timer */
- debug(F100,"u_start and !inserver","",0);
- return(-2); /* End server mode */
- } else if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start &&
- server
- ) { /* I'm no longer in Server Mode */
- debug(F100,"me_start and server","",0);
- ttimoff();
- return(-2);
- }
- return(0);
- }
- case 5: { /* Start character change */
- /* extern CHAR stchr; */
- /* start = stchr; */
- return(1);
- }
-#endif /* IKS_OPTION */
- case 6: /* Remote Logout */
- ttimoff();
- ttclos(0);
-#ifdef IKSD
- if (inserver && !local)
- doexit(GOOD_EXIT,0);
- else
-#endif /* IKSD */
- return(-2);
- default:
- return(0);
- }
- } else
- return(0);
-}
-#endif /* TCPSOCKET */
-
-/* T T F L U I -- Flush tty input buffer */
-
-void
-ttflux() { /* But first... */
-#ifdef MYREAD
-/*
- Flush internal MYREAD buffer.
-*/
-#ifdef TCPSOCKET
- int dotnopts, x;
- dotnopts = (((xlocal && netconn && IS_TELNET()) ||
- (!xlocal && sstelnet)));
-#endif /* TCPSOCKET */
- debug(F101,"ttflux my_count","",my_count);
-#ifdef TCPSOCKET
- if (dotnopts) {
- CHAR ch = '\0';
- while (my_count > 0) {
- ch = myread();
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION))
- ck_tn_decrypt((char *)&ch,1);
-#endif /* CK_ENCRYPTION */
- if (ch == IAC)
- x = tt_tnopt(ch);
- }
- } else
-#endif /* TCPSOCKET */
-#ifdef COMMENT
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION) && my_count > 0)
- ck_tn_decrypt(&mybuf[my_item+1],my_count);
-#endif /* CK_ENCRYPTION */
-#endif /* COMMENT */
- my_count = 0; /* Reset count to zero */
- my_item = -1; /* And buffer index to -1 */
-#endif /* MYREAD */
-}
-
-int
-ttflui() {
- int n, fd;
-#ifdef TCPSOCKET
- int dotnopts;
- dotnopts = (((xlocal && netconn && IS_TELNET()) ||
- (!xlocal && sstelnet)));
-#endif /* TCPSOCKET */
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef TTLEBUF
- ttpush = -1; /* Clear the peek-ahead char */
- while (le_data && (le_inbuf() > 0)) {
- CHAR ch = '\0';
- if (le_getchar(&ch) > 0) { /* Clear any more... */
- debug(F101,"ttflui le_inbuf ch","",ch);
- }
- }
-#endif /* TTLEBUF */
- debug(F101,"ttflui ttpipe","",ttpipe);
-
-#ifdef MYREAD
-/*
- Flush internal MYREAD buffer *NEXT*, in all cases.
-*/
- ttflux();
-#endif /* MYREAD */
-
-#ifdef NETCONN
-/* Network flush is done specially, in the network support module. */
- if ((netconn || sstelnet) && !ttpipe && !ttpty) {
- debug(F100,"ttflui netflui","",0);
-#ifdef COMMENT
-#ifdef TN_COMPORT
- if (istncomport())
- tnc_send_purge_data(TNC_PURGE_RECEIVE);
-#endif /* TN_COMPORT */
-#endif /* COMMENT */
- return(netflui());
- }
-#endif /* NETCONN */
-
- debug(F101,"ttflui ttyfd","",ttyfd); /* Not network */
- if (ttyfd < 0)
- return(-1);
-
-#ifdef aegis
- sio_$control((short)yfd, sio_$flush_in, true, st);
- if (st.all != status_$ok) {
- fprintf(stderr, "flush failed: "); error_$print(st);
- } else { /* sometimes the flush doesn't work */
- for (;;) {
- char buf[256];
- /* eat all the characters that shouldn't be available */
- ios_$get((short)fd, ios_$cond_opt, buf, 256L, st); /* (void) */
- if (st.all == ios_$get_conditional_failed) break;
- fprintf(stderr, "flush failed(2): "); error_$print(st);
- }
- }
-#else
-#ifdef BSD44 /* 4.4 BSD */
- n = FREAD; /* Specify read queue */
- debug(F100,"ttflui BSD44","",0);
- ioctl(fd,TIOCFLUSH,&n);
-#else
-#ifdef Plan9
-#undef POSIX /* Uh oh... */
-#endif /* Plan9 */
-#ifdef POSIX /* POSIX */
- debug(F100,"ttflui POSIX","",0);
- tcflush(fd,TCIFLUSH);
-#else
-#ifdef ATTSV /* System V */
-#ifndef VXVE
- debug(F100,"ttflui ATTSV","",0);
- ioctl(fd,TCFLSH,0);
-#endif /* VXVE */
-#else /* Not BSD44, POSIX, or Sys V */
-#ifdef TIOCFLUSH /* Those with TIOCFLUSH defined */
-#ifdef ANYBSD /* Berkeley */
- n = FREAD; /* Specify read queue */
- debug(F100,"ttflui TIOCFLUSH ANYBSD","",0);
- ioctl(fd,TIOCFLUSH,&n);
-#else /* Others (V7, etc) */
- debug(F100,"ttflui TIOCFLUSH","",0);
- ioctl(fd,TIOCFLUSH,0);
-#endif /* ANYBSD */
-#else /* All others... */
-/*
- No system call (that we know about) for input buffer flushing.
- So see how many there are and read them in a loop, using ttinc().
- ttinc() is buffered, so we're not getting charged with a system call
- per character, just a function call.
-*/
- if ((n = ttchk()) > 0) {
- debug(F101,"ttflui read loop","",n);
- while ((n--) && ttinc(0) > 0) ;
- }
-#endif /* TIOCFLUSH */
-#endif /* ATTSV */
-#endif /* POSIX */
-#ifdef Plan9
-#define POSIX
-#endif /* Plan9 */
-#endif /* BSD44 */
-#endif /* aegis */
- return(0);
-}
-
-int
-ttfluo() { /* Flush output buffer */
- int fd;
-#ifdef NETCMD
- if (ttpipe)
- fd = fdout;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef Plan9
- return 0;
-#else
-#ifdef POSIX
- return(tcflush(fd,TCOFLUSH));
-#else
-#ifdef OXOS
- return(ioctl(fd,TCFLSH,1));
-#else
- return(0); /* All others, nothing */
-#endif /* OXOS */
-#endif /* POSIX */
-#endif /* Plan9 */
-}
-
-/* Interrupt Functions */
-
-/* Set up terminal interrupts on console terminal */
-
-#ifndef FIONREAD /* We don't need esctrp() */
-#ifndef SELECT /* if we have any of these... */
-#ifndef CK_POLL
-#ifndef RDCHK
-
-#ifndef OXOS
-#ifdef SVORPOSIX
-SIGTYP
-esctrp(foo) int foo; { /* trap console escapes (^\) */
- signal(SIGQUIT,SIG_IGN); /* ignore until trapped */
- conesc = 1;
- debug(F101,"esctrp caught SIGQUIT","",conesc);
-}
-#endif /* SVORPOSIX */
-#endif /* OXOS */
-
-#ifdef V7
-#ifndef MINIX2
-SIGTYP
-esctrp(foo) int foo; { /* trap console escapes (^\) */
- signal(SIGQUIT,SIG_IGN); /* ignore until trapped */
- conesc = 1;
- debug(F101,"esctrp caught SIGQUIT","",conesc);
-}
-#endif /* MINIX2 */
-#endif /* V7 */
-
-#ifdef C70
-SIGTYP
-esctrp(foo) int foo; { /* trap console escapes (^\) */
- conesc = 1;
- signal(SIGQUIT,SIG_IGN); /* ignore until trapped */
-}
-#endif /* C70 */
-
-#endif /* RDCHK */
-#endif /* CK_POLL */
-#endif /* SELECT */
-#endif /* FIONREAD */
-
-/* C O N B G T -- Background Test */
-
-static int jc = 0; /* 0 = no job control */
-
-/*
- Call with flag == 1 to prevent signal test, which can not be expected
- to work during file transfer, when SIGINT probably *is* set to SIG_IGN.
-
- Call with flag == 0 to use the signal test, but only if the process-group
- test fails, as it does on some UNIX systems, where getpgrp() is buggy,
- requires an argument when the man page says it doesn't, or vice versa.
-
- If flag == 0 and the process-group test fails, then we determine background
- status simply (but not necessarily reliably) from isatty().
-
- conbgt() sets the global backgrd = 1 if we appear to be in the background,
- and to 0 if we seem to be in the foreground. conbgt() is highly prone to
- misbehavior.
-*/
-VOID
-conbgt(flag) int flag; {
- int x = -1, /* process group or SIGINT test */
- y = 0; /* isatty() test */
-/*
- Check for background operation, even if not running on real tty, so that
- background flag can be set correctly. If background status is detected,
- then Kermit will not issue its interactive prompt or most messages.
- If your prompt goes away, you can blame (and fix?) this function.
-*/
-
-/* Use process-group test if possible. */
-
-#ifdef POSIX /* We can do it in POSIX */
-#define PGROUP_T
-#else
-#ifdef BSD4 /* and in BSD 4.x. */
-#define PGROUP_T
-#else
-#ifdef HPUXJOBCTL /* and in most HP-UX's */
-#define PGROUP_T
-#else
-#ifdef TIOCGPGRP /* and anyplace that has this ioctl. */
-#define PGROUP_T
-#endif /* TIOCGPGRP */
-#endif /* HPUXJOBCTL */
-#endif /* BSD4 */
-#endif /* POSIX */
-
-#ifdef MIPS /* Except if it doesn't work... */
-#undef PGROUP_T
-#endif /* MIPS */
-
-#ifdef MINIX
-#undef PGROUP_T
-#endif /* MINIX */
-
-#ifdef PGROUP_T
-/*
- Semi-reliable process-group test. Check whether this process's group is
- the same as the controlling terminal's process group. This works if the
- getpgrp() call doesn't lie (as it does in the SUNOS System V environment).
-*/
- PID_T mypgrp = (PID_T)0; /* Kermit's process group */
- PID_T ctpgrp = (PID_T)0; /* The terminal's process group */
-#ifndef _POSIX_SOURCE
-/*
- The getpgrp() prototype is obtained from system header files for POSIX
- and Sys V R4 compilations. Other systems, who knows. Some complain about
- a duplicate declaration here, others don't, so it's safer to leave it in
- if we don't know for certain.
-*/
-#ifndef SVR4
-#ifndef PS2AIX10
-#ifndef HPUX9
- extern PID_T getpgrp();
-#endif /* HPUX9 */
-#endif /* PS2AIX10 */
-#endif /* SVR4 */
-#endif /* _POSIX_SOURCE */
-
-/* Get my process group. */
-
-#ifdef SVR3 /* Maybe this should be ATTSV? */
-/* This function is not described in SVID R2 */
- mypgrp = getpgrp();
- /* debug(F101,"ATTSV conbgt process group","",(int) mypgrp); */
-#else
-#ifdef POSIX
- mypgrp = getpgrp();
- /* debug(F101,"POSIX conbgt process group","",(int) mypgrp); */
-#else
-#ifdef OSFPC
- mypgrp = getpgrp();
- /* debug(F101,"OSF conbgt process group","",(int) mypgrp); */
-#else
-#ifdef QNX
- mypgrp = getpgrp();
- /* debug(F101,"QNX conbgt process group","",(int) mypgrp); */
-#else
-#ifdef OSF32 /* (was OSF40) */
- mypgrp = getpgrp();
- /* debug(F101,"Digital UNIX conbgt process group","",(int) mypgrp); */
-#else /* BSD, V7, etc */
-#ifdef MINIX2
- mypgrp = getpgrp();
-#else
- mypgrp = getpgrp(0);
-#endif /* MINIX2 */
- /* debug(F101,"BSD conbgt process group","",(int) mypgrp); */
-#endif /* OSF32 */
-#endif /* QNX */
-#endif /* OSFPC */
-#endif /* POSIX */
-#endif /* SVR3 */
-
-#ifdef MINIX
- /* MINIX does not support job control so Kermit is always in foreground */
- x = 0;
-
-#else /* Not MINIX */
-
-/* Now get controlling tty's process group */
-#ifdef BSD44ORPOSIX
- ctpgrp = tcgetpgrp(1); /* The POSIX way */
- /* debug(F101,"POSIX conbgt terminal process group","",(int) ctpgrp); */
-#else
- ioctl(1, TIOCGPGRP, &ctpgrp); /* Or the BSD way */
- /* debug(F101,"non-POSIX conbgt terminal process group","",(int) ctpgrp); */
-#endif /* BSD44ORPOSIX */
-
- if ((mypgrp > (PID_T) 0) && (ctpgrp > (PID_T) 0))
- x = (mypgrp == ctpgrp) ? 0 : 1; /* If they differ, then background. */
- else x = -1; /* If error, remember. */
- debug(F101,"conbgt process group test","",x);
-#endif /* PGROUP_T */
-#endif /* MINIX */
-
-/* Try to see if job control is available */
-
-#ifdef NOJC /* User override */
- jc = 0; /* No job control allowed */
- debug(F111,"NOJC","jc",jc);
-#else
-#ifdef BSD44
- jc = 1;
-#else
-#ifdef SVR4ORPOSIX /* POSIX actually tells us */
- debug(F100,"SVR4ORPOSIX jc test...","",0);
-#ifdef _SC_JOB_CONTROL
-#ifdef __bsdi__
- jc = 1;
-#else
-#ifdef __386BSD__
- jc = 1;
-#else
- jc = sysconf(_SC_JOB_CONTROL); /* Whatever system says */
- if (jc < 0) {
- debug(F101,"sysconf fails, jcshell","",jcshell);
- jc = (jchdlr == SIG_DFL) ? 1 : 0;
- } else
- debug(F111,"sysconf(_SC_JOB_CONTROL)","jc",jc);
-#endif /* __386BSD__ */
-#endif /* __bsdi__ */
-#else
-#ifdef _POSIX_JOB_CONTROL
- jc = 1; /* By definition */
- debug(F111,"_POSIX_JOB_CONTROL is defined","jc",jc);
-#else
- jc = 0; /* Assume job control not allowed */
- debug(F111,"SVR4ORPOSIX _SC/POSIX_JOB_CONTROL not defined","jc",jc);
-#endif /* _POSIX_JOB_CONTROL */
-#endif /* _SC_JOB_CONTROL */
-#else
-#ifdef BSD4
- jc = 1; /* Job control allowed */
- debug(F111,"BSD job control","jc",jc);
-#else
-#ifdef SVR3JC
- jc = 1; /* JC allowed */
- debug(F111,"SVR3 job control","jc",jc);
-#else
-#ifdef OXOS
- jc = 1; /* JC allowed */
- debug(F111,"X/OS job control","jc",jc);
-#else
-#ifdef HPUX9
- jc = 1; /* JC allowed */
- debug(F111,"HP-UX 9.0 job control","jc",jc);
-#else
-#ifdef HPUX10
- jc = 1; /* JC allowed */
- debug(F111,"HP-UX 10.0 job control","jc",jc);
-#else
- jc = 0; /* JC not allowed */
- debug(F111,"job control catch-all","jc",jc);
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* OXOS */
-#endif /* SVR3JC */
-#endif /* BSD4 */
-#endif /* SVR4ORPOSIX */
-#endif /* BSD44 */
-#endif /* NOJC */
- debug(F101,"conbgt jc","",jc);
-#ifndef NOJC
- debug(F101,"conbgt jcshell","",jcshell);
-/*
- At this point, if jc == 1 but jcshell == 0, it means that the OS supports
- job control, but the shell or other process we are running under does not
- (jcshell is set in sysinit()) and so if we suspend ourselves, nothing good
- will come of it. So...
-*/
- if (jc < 0) jc = 0;
- if (jc > 0 && jcshell == 0) jc = 0;
-#endif /* NOJC */
-
-/*
- Another background test.
- Test if SIGINT (terminal interrupt) is set to SIG_IGN (ignore),
- which is done by the shell (sh) if the program is started with '&'.
- Unfortunately, this is NOT done by csh or ksh so watch out!
- Note, it's safe to set SIGINT to SIG_IGN here, because further down
- we always set it to something else.
- Note: as of 16 Jul 1999, we also skip this test if we set SIGINT to
- SIG_IGN ourselves.
-*/
- if (x < 0 && !flag && !sigint_ign) { /* Didn't get good results above... */
-
- SIGTYP (*osigint)();
-
- osigint = signal(SIGINT,SIG_IGN); /* What is SIGINT set to? */
- sigint_ign = 1;
- x = (osigint == SIG_IGN) ? 1 : 0; /* SIG_IGN? */
- /* debug(F101,"conbgt osigint","",osigint); */
- /* debug(F101,"conbgt signal test","",x); */
- }
-
-/* Also check to see if we're running with redirected stdio. */
-/* This is not really background operation, but we want to act as though */
-/* it were. */
-
-#ifdef IKSD
- if (inserver) { /* Internet Kermit Server */
- backgrd = 0; /* is not in the background */
- return;
- }
-#endif /* IKSD */
-
- y = (isatty(0) && isatty(1)) ? 1 : 0;
- debug(F101,"conbgt isatty test","",y);
-
-#ifdef BSD29
-/* The process group and/or signal test doesn't work under these... */
- backgrd = !y;
-#else
-#ifdef sxaE50
- backgrd = !y;
-#else
-#ifdef MINIX
- backgrd = !y;
-#else
-#ifdef MINIX2
- backgrd = !y;
-#else
- if (x > -1)
- backgrd = (x || !y) ? 1 : 0;
- else backgrd = !y;
-#endif /* BSD29 */
-#endif /* sxaE50 */
-#endif /* MINIX */
-#endif /* MINIX2 */
- debug(F101,"conbgt backgrd","",backgrd);
-}
-
-/* C O N I N T -- Console Interrupt setter */
-
-/*
- First arg is pointer to function to handle SIGTERM & SIGINT (like Ctrl-C).
- Second arg is pointer to function to handle SIGTSTP (suspend).
-*/
-
-VOID /* Set terminal interrupt traps. */
-#ifdef CK_ANSIC
-#ifdef apollo
-conint(f,s) SIGTYP (*f)(), (*s)();
-#else
-conint(SIGTYP (*f)(int), SIGTYP (*s)(int))
-#endif /* apollo */
-#else
-conint(f,s) SIGTYP (*f)(), (*s)();
-#endif /* CK_ANSIC */
-/* conint */ {
-
- debug(F101,"conint conistate","",conistate);
-
- conbgt(0); /* Do background test. */
-
-/* Set the desired handlers for hangup and software termination. */
-
-#ifdef SIGTERM
- signal(SIGTERM,f); /* Software termination */
-#endif /* SIGTERM */
-
-/*
- Prior to July 1999 we used to call sighup() here but now it's called in
- sysinit() so SIGHUP can be caught during execution of the init file or
- a kerbang script.
-*/
-
-/* Now handle keyboard stop, quit, and interrupt signals. */
-/* Check if invoked in background -- if so signals set to be ignored. */
-/* However, if running under a job control shell, don't ignore them. */
-/* We won't be getting any, as we aren't in the terminal's process group. */
-
- debug(F101,"conint backgrd","",backgrd);
- debug(F101,"conint jc","",jc);
-
- if (backgrd && !jc) { /* In background, ignore signals */
- debug(F101,"conint background ignoring signals, jc","",jc);
-#ifdef SIGTSTP
- signal(SIGTSTP,SIG_IGN); /* Keyboard stop */
-#endif /* SIGTSTP */
- signal(SIGQUIT,SIG_IGN); /* Keyboard quit */
- signal(SIGINT,SIG_IGN); /* Keyboard interrupt */
- sigint_ign = 1;
- conistate = CONI_NOI;
- } else { /* Else in foreground or suspended */
- debug(F101,"conint foreground catching signals, jc","",jc);
- signal(SIGINT,f); /* Catch terminal interrupt */
- sigint_ign = (f == SIG_IGN) ? 1 : 0;
-
-#ifdef SIGTSTP /* Keyboard stop (suspend) */
- /* debug(F101,"conint SIGSTSTP","",s); */
- if (s == NULL) s = SIG_DFL;
-#ifdef NOJC /* No job control allowed. */
- signal(SIGTSTP,SIG_IGN);
-#else /* Job control allowed */
- if (jc) /* if available. */
- signal(SIGTSTP,s);
- else
- signal(SIGTSTP,SIG_IGN);
-#endif /* NOJC */
-#endif /* SIGTSTP */
-
-#ifndef OXOS
-#ifdef SVORPOSIX
-#ifndef FIONREAD /* Watch out, we don't know this... */
-#ifndef SELECT
-#ifndef CK_POLL
-#ifndef RDCHK
- signal(SIGQUIT,esctrp); /* Quit signal, Sys III/V. */
-#endif /* RDCHK */
-#endif /* CK_POLL */
-#endif /* SELECT */
-#endif /* FIONREAD */
- if (conesc) conesc = 0; /* Clear out pending escapes */
-#else
-#ifdef V7
- signal(SIGQUIT,esctrp); /* V7 like Sys III/V */
- if (conesc) conesc = 0;
-#else
-#ifdef aegis
- signal(SIGQUIT,f); /* Apollo, catch it like others. */
-#else
- signal(SIGQUIT,SIG_IGN); /* Others, ignore like 4D & earlier. */
-#endif /* aegis */
-#endif /* V7 */
-#endif /* SVORPOSIX */
-#endif /* OXOS */
- conistate = CONI_INT;
- }
-}
-
-
-/* C O N N O I -- Reset console terminal interrupts */
-
-VOID
-connoi() { /* Console-no-interrupts */
-
- debug(F101,"connoi conistate","",conistate);
-#ifdef SIGTSTP
- signal(SIGTSTP,SIG_IGN); /* Suspend */
-#endif /* SIGTSTP */
- conint(SIG_IGN,SIG_IGN); /* Interrupt */
- sigint_ign = 1; /* Remember we did this ourselves */
-#ifdef SIGQUIT
- signal(SIGQUIT,SIG_IGN); /* Quit */
-#endif /* SIGQUIT */
-#ifdef SIGTERM
- signal(SIGTERM,SIG_IGN); /* Term */
-#endif /* SIGTERM */
- conistate = CONI_NOI;
-}
-
-/* I N I T R A W Q -- Set up to read /dev/kmem for character count. */
-
-#ifdef V7
-/*
- Used in Version 7 to simulate Berkeley's FIONREAD ioctl call. This
- eliminates blocking on a read, because we can read /dev/kmem to get the
- number of characters available for raw input. If your system can't
- or you won't let the world read /dev/kmem then you must figure out a
- different way to do the counting of characters available, or else replace
- this by a dummy function that always returns 0.
-*/
-/*
- * Call this routine as: initrawq(tty)
- * where tty is the file descriptor of a terminal. It will return
- * (as a char *) the kernel-mode memory address of the rawq character
- * count, which may then be read. It has the side-effect of flushing
- * input on the terminal.
- */
-/*
- * John Mackin, Physiology Dept., University of Sydney (Australia)
- * ...!decvax!mulga!physiol.su.oz!john
- *
- * Permission is hereby granted to do anything with this code, as
- * long as this comment is retained unmodified and no commercial
- * advantage is gained.
- */
-#ifndef MINIX
-#ifndef MINIX2
-#ifndef COHERENT
-#include <a.out.h>
-#include <sys/proc.h>
-#endif /* COHERENT */
-#endif /* MINIX2 */
-#endif /* MINIX */
-
-#ifdef COHERENT
-#include <l.out.h>
-#include <sys/proc.h>
-#endif /* COHERENT */
-
-char *
-initrawq(tty) int tty; {
-#ifdef MINIX
- return(0);
-#else
-#ifdef MINIX2
- return(0);
-#else
-#ifdef UTS24
- return(0);
-#else
-#ifdef BSD29
- return(0);
-#else
- long lseek();
- static struct nlist nl[] = {
- {PROCNAME},
- {NPROCNAME},
- {""}
- };
- static struct proc *pp;
- char *qaddr, *p, c;
- int m;
- PID_T pid, me;
- NPTYPE xproc; /* Its type is defined in makefile. */
- int catch();
-
- me = getpid();
- if ((m = open("/dev/kmem", 0)) < 0) err("kmem");
- nlist(BOOTNAME, nl);
- if (nl[0].n_type == 0) err("proc array");
-
- if (nl[1].n_type == 0) err("nproc");
-
- lseek(m, (long)(nl[1].n_value), 0);
- read (m, &xproc, sizeof(xproc));
- saval = signal(SIGALRM, catch);
- if ((pid = fork()) == 0) {
- while(1)
- read(tty, &c, 1);
- }
- alarm(2);
-
- if(setjmp(jjbuf) == 0) {
- while(1)
- read(tty, &c, 1);
- }
- signal(SIGALRM, SIG_DFL);
-
-#ifdef DIRECT
- pp = (struct proc *) nl[0].n_value;
-#else
- if (lseek(m, (long)(nl[0].n_value), 0) < 0L) err("seek");
- if (read(m, &pp, sizeof(pp)) != sizeof(pp)) err("no read of proc ptr");
-#endif
- lseek(m, (long)(nl[1].n_value), 0);
- read(m, &xproc, sizeof(xproc));
-
- if (lseek(m, (long)pp, 0) < 0L) err("Can't seek to proc");
- if ((p = malloc(xproc * sizeof(struct proc))) == NULL) err("malloc");
- if (read(m,p,xproc * sizeof(struct proc)) != xproc*sizeof(struct proc))
- err("read proc table");
- for (pp = (struct proc *)p; xproc > 0; --xproc, ++pp) {
- if (pp -> p_pid == (short) pid) goto iout;
- }
- err("no such proc");
-
-iout:
- close(m);
- qaddr = (char *)(pp -> p_wchan);
- free (p);
- kill(pid, SIGKILL);
- wait((WAIT_T *)0);
- return (qaddr);
-#endif
-#endif
-#endif
-#endif
-}
-
-/* More V7-support functions... */
-
-static VOID
-err(s) char *s; {
- char buf[200];
-
- ckmakmsg(buf,200,"fatal error in initrawq: ", s, NULL, NULL);
- perror(buf);
- doexit(1,-1);
-}
-
-static VOID
-catch(foo) int foo; {
- longjmp(jjbuf, -1);
-}
-
-
-/* G E N B R K -- Simulate a modem break. */
-
-#ifdef MINIX
-#define BSPEED B110
-#else
-#ifdef MINIX2
-#define BSPEED B110
-#else
-#define BSPEED B150
-#endif /* MINIX2 */
-#endif /* MINIX */
-
-#ifndef MINIX2
-VOID
-genbrk(fn,msec) int fn, msec; {
- struct sgttyb ttbuf;
- int ret, sospeed, x, y;
-
- ret = ioctl(fn, TIOCGETP, &ttbuf);
- sospeed = ttbuf.sg_ospeed;
- ttbuf.sg_ospeed = BSPEED;
- ret = ioctl(fn, TIOCSETP, &ttbuf);
- y = (int)strlen(brnuls);
- x = ( BSPEED * 100 ) / msec;
- if (x > y) x = y;
- ret = write(fn, brnuls, (( BSPEED * 100 ) / msec ));
- ttbuf.sg_ospeed = sospeed;
- ret = ioctl(fn, TIOCSETP, &ttbuf);
- ret = write(fn, "@", 1);
- return;
-}
-#endif /* MINIX2 */
-
-#ifdef MINIX2
-int
-genbrk(fn,msec) int fn, msec; {
- struct termios ttbuf;
- int ret, x, y;
- speed_t sospeed;
-
- ret = tcgetattr(fn, &ttbuf);
- sospeed = ttbuf.c_ospeed;
- ttbuf.c_ospeed = BSPEED;
- ret = tcsetattr(fn,TCSADRAIN, &ttbuf);
- y = (int)strlen(brnuls);
- x = ( BSPEED * 100 ) / msec;
- if (x > y) x = y;
- ret = write(fn, brnuls, (( BSPEED * 100 ) / msec ));
- ttbuf.c_ospeed = sospeed;
- ret = tcsetattr(fn, TCSADRAIN, &ttbuf);
- ret = write(fn, "@", 1);
- return ret;
-}
-#endif /* MINIX2 */
-#endif /* V7 */
-
-/*
- I N C H K -- Check if chars waiting to be read on given file descriptor.
-
- This routine is a merger of ttchk() and conchk().
- Call with:
- channel == 0 to check console.
- channel == 1 to check communications connection.
- and:
- fd = file descriptor.
- Returns:
- >= 0: number of characters waiting, 0 or greater,
- -1: on any kind of error,
- -2: if there is (definitely) no connection.
- Note: In UNIX we don't have to call nettchk() because a socket
- file descriptor works just like in serial i/o, ioctls and all.
- (But this will change if we add non-file-descriptor channels,
- such as IBM X.25 for AIX...)
-*/
-static int
-in_chk(channel, fd) int channel, fd; {
- int x, n = 0; /* Workers, n = return value */
- extern int clsondisc; /* Close on disconnect */
-/*
- The first section checks to make sure we have a connection,
- but only if we're in local mode.
-*/
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"in_chk entry",ckitoa(fd),channel);
- debug(F101,"in_chk ttyfd","",ttyfd);
- debug(F101,"in_chk ttpty","",ttpty);
- }
-#endif /* DEBUG */
-/*
- But don't say connection is gone if we have any buffered-stuff.
-*/
-#ifdef TTLEBUF
- debug(F101,"in_chk ttpush","",ttpush);
- if (channel == 1) {
- if (ttpush >= 0)
- n++;
- n += le_inbuf();
- if (n > 0)
- return(n);
- }
-#endif /* TTLEBUF */
-
-#ifdef NETPTY
-#ifdef HAVE_PTYTRAP
- /* Special handling for HP-UX pty i/o */
- if (ttpty && pty_trap_pending(ttyfd) > 0) {
- if (pty_trap_handler(ttyfd) > 0) {
- ttclos(0);
- return(-2);
- }
- }
-#endif /* HAVE_PTYTRAP */
-#endif /* NETPTY */
-
- if (channel) { /* Checking communications channel */
- if (ttyfd < 0) { /* No connection */
- return(-2); /* That's what this means */
- } else if (xlocal && /* In local mode */
- (!netconn /* Serial connection or */
-#ifdef TN_COMPORT
- || istncomport() /* Telnet Com Port */
-#endif /* TN_COMPORT */
- ) && ttcarr != CAR_OFF /* with CARRIER WATCH ON (or AUTO) */
-#ifdef COMMENT
-#ifdef MYREAD
-/*
- Seems like this would be a good idea but it prevents C-Kermit from
- popping back to the prompt automatically when carrier drops. However,
- commenting this out prevents us from seeing the NO CARRIER message.
- Needs more work...
-*/
- && my_count < 1 /* Nothing in our internal buffer */
-#endif /* MYREAD */
-#endif /* COMMENT */
- ) {
- int x;
- x = ttgmdm(); /* So get modem signals */
- debug(F101,"in_chk close-on-disconnect","",clsondisc);
- if (x > -1) { /* Check for carrier */
- if (!(x & BM_DCD)) { /* No carrier */
- debug(F101,"in_chk carrier lost","",x);
- if (clsondisc) /* If "close-on-disconnect" */
- ttclos(0); /* close device & release lock. */
- return(-2); /* This means "disconnected" */
- }
- /* In case I/O to device after CD dropped always fails */
- /* as in Debian Linux 2.1 and Unixware 2.1... */
- } else {
- debug(F101,"in_chk ttgmdm I/O error","",errno);
- debug(F101,"in_chk ttgmdm gotsigs","",gotsigs);
- if (gotsigs) { /* If we got signals before... */
- if (errno == 5 || errno == 6) { /* I/O error etc */
- if (clsondisc) /* like when modem hangs up */
- ttclos(0);
- return(-2);
- }
- }
- /* If we never got modem signals successfully on this */
- /* connection before, we can't conclude that THIS failure */
- /* means the connection was lost. */
- return(0);
- }
- }
- }
-
-/* We seem to have a connection so now see if any bytes are waiting on it */
-
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- n += SSL_pending(ssl_active_flag?ssl_con:tls_con);
- debug(F101,"in_chk SSL_pending","",n);
- if (n < 0) {
- ttclos(0);
- return(-1);
- } else if (n > 0) {
- return(n);
- }
- }
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
- /* It is not safe to read any data when using encrypted Klogin */
- if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN) {
-#ifdef KRB4
- if (ttnproto == NP_EK4LOGIN) {
- n += krb4_des_avail(ttyfd);
- debug(F101,"in_chk krb4_des_avail","",n);
- }
-#endif /* KRB4 */
-#ifdef KRB5
- if (ttnproto == NP_EK5LOGIN) {
- n += krb5_des_avail(ttyfd);
- debug(F101,"in_chk krb5_des_avail","",n);
- }
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- n += krb5_u2u_avail(ttyfd);
- debug(F101,"in_chk krb5_des_avail","",n);
- }
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
- if (n < 0) /* Is this right? */
- return(-1);
- else
- return(n);
- }
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
-
- errno = 0; /* Reset this so we log good info */
-#ifdef FIONREAD
- x = ioctl(fd, FIONREAD, &n); /* BSD and lots of others */
-#ifdef DEBUG /* (the more the better) */
- if (deblog) {
- debug(F101,"in_chk FIONREAD return code","",x);
- debug(F101,"in_chk FIONREAD count","",n);
- debug(F101,"in_chk FIONREAD errno","",errno);
- }
-#endif /* DEBUG */
-#else /* FIONREAD not defined */
-/*
- Here, if (netconn && ttnet == NET_TCPB), we might try calling recvmsg()
- with flags MSG_PEEK|MSG_DONTWAIT on the socket (ttyfd), except this is not
- portable (MSG_DONTWAIT isn't defined in any of the <sys/socket.h> files
- that I looked at, but it is needed to prevent the call from blocking), and
- the msghdr struct differs from place to place, so we would need another
- avalanche of ifdefs. Still, when FIONREAD is not available, this is the
- only other known method of asking the OS for the *number* of characters
- available for reading.
-*/
-#ifdef V7 /* UNIX V7: look in kernel memory */
-#ifdef MINIX
- n = 0; /* But not in MINIX */
-#else
-#ifdef MINIX2
- n = 0;
-#else
- lseek(kmem[TTY], (long) qaddr[TTY], 0); /* 7th Edition Unix */
- x = read(kmem[TTY], &n, sizeof(int));
- if (x != sizeof(int))
- n = 0;
-#endif /* MINIX2 */
-#endif /* MINIX */
-#else /* Not V7 */
-#ifdef PROVX1
- x = ioctl(fd, TIOCQCNT, &ttbuf); /* DEC Pro/3xx Venix V.1 */
- n = ttbuf.sg_ispeed & 0377; /* Circa 1984 */
- if (x < 0) n = 0;
-#else
-#ifdef MYREAD
-/*
- Here we skip all the undependable and expensive calls below if we
- already have something in our internal buffer. This tends to work quite
- nicely, so the only really bad case remaining is the one in which neither
- FIONREAD or MYREAD are defined, which is increasingly rare these days.
-*/
- if (channel != 0 && my_count > 0) {
- debug(F101,"in_chk buf my_count","",my_count);
- n = my_count; /* n was 0 before we got here */
- return(n);
- }
-#endif /* MYREAD */
-/*
- rdchk(), select(), and poll() tell us *if* data is available to be read, but
- not how much, so these should be used only as a final resort. Especially
- since these calls tend to add a lot overhead.
-*/
-#ifdef RDCHK /* This mostly SCO-specific */
- n = rdchk(fd);
- debug(F101,"in_chk rdchk","",n);
-#else /* No RDCHK */
-#ifdef SELECT
-#ifdef Plan9
- /* Only allows select on the console ... don't ask */
- if (channel == 0)
-#endif /* Plan9 */
- {
- fd_set rfds; /* Read file descriptors */
-#ifdef BELLV10
- FD_ZERO(rfds); /* Initialize them */
- FD_SET(fd,rfds); /* We want to look at this fd */
-#else
- FD_ZERO(&rfds); /* Initialize them */
- FD_SET(fd,&rfds); /* We want to look at this fd */
- tv.tv_sec = tv.tv_usec = 0L; /* A 0-valued timeval structure */
-#endif /* BELLV10 */
-#ifdef Plan9
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk Plan 9 select","",n);
-#else
-#ifdef BELLV10
- n = select( 128, rfds, (fd_set *)0, (fd_set *)0, 0 );
- debug(F101,"in_chk BELLV10 select","",n);
-#else
-#ifdef BSD44
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk BSD44 select","",n);
-#else
-#ifdef BSD43
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk BSD43 select","",n);
-#else
-#ifdef SOLARIS
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk SOLARIS select","",n);
-#else
-#ifdef QNX6
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk QNX6 select","",n);
-#else
-#ifdef QNX
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk QNX select","",n);
-#else
-#ifdef COHERENT
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk COHERENT select","",n);
-#else
-#ifdef SVR4
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk SVR4 select","",n);
-#else
-#ifdef __linux__
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk LINUX select","",n);
-#ifdef OSF
- n = select( FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"in_chk OSF select","",n);
-#else
- n = select( FD_SETSIZE, &rfds, (int *)0, (int *)0, &tv );
- debug(F101,"in_chk catchall select","",n);
-#endif /* OSF */
-#endif /* __linux__ */
-#endif /* SVR4 */
-#endif /* COHERENT */
-#endif /* QNX */
-#endif /* QNX6 */
-#endif /* SOLARIS */
-#endif /* BSD43 */
-#endif /* BSD44 */
-#endif /* BELLV10 */
-#endif /* Plan9 */
- }
-#else /* Not SELECT */
-#ifdef CK_POLL
- {
- struct pollfd pfd;
-
- pfd.fd = fd;
- pfd.events = POLLIN;
- pfd.revents = 0;
- n = poll(&pfd, 1, 0);
- debug(F101,"in_chk poll","",n);
- if ((n > 0) && (pfd.revents & POLLIN))
- n = 1;
- }
-#endif /* CK_POLL */
-#endif /* SELECT */
-#endif /* RDCHK */
-#endif /* PROVX1 */
-#endif /* V7 */
-#endif /* FIONREAD */
-
-/* From here down, treat console and communication device differently... */
-
- if (channel == 0) { /* Console */
-
-#ifdef SVORPOSIX
-#ifndef FIONREAD
-#ifndef SELECT
-#ifndef CK_POLL
-#ifndef RDCHK
-/*
- This is the hideous hack used in System V and POSIX systems that don't
- support FIONREAD, rdchk(), select(), poll(), etc, in which the user's
- CONNECT-mode escape character is attached to SIGQUIT. Used, obviously,
- only on the console.
-*/
- if (conesc) { /* Escape character typed == SIGQUIT */
- debug(F100,"in_chk conesc","",conesc);
- conesc = 0;
- signal(SIGQUIT,esctrp); /* Restore signal */
- n += 1;
- }
-#endif /* RDCHK */
-#endif /* CK_POLL */
-#endif /* SELECT */
-#endif /* FIONREAD */
-#endif /* SVORPOSIX */
-
- return(n); /* Done with console */
- }
-
- if (channel != 0) { /* Communications connection */
-
-#ifdef MYREAD
-#ifndef FIONREAD
-/*
- select() or rdchk(), etc, has told us that something is waiting, but we
- don't know how much. So we do a read to get it and then we know. Note:
- This read is NOT nonblocking if nothing is there (because of VMIN=1), but
- it should be safe in this case since the OS tells us at least one byte is
- waiting to be read, and MYREAD reads return as much as is there without
- waiting for any more. Controlled tests on Solaris and Unixware (with
- FIONREAD deliberately undefined) show this to be true.
-*/
- debug(F101,"in_chk read my_count","",my_count);
- debug(F101,"in_chk read n","",n);
- if (n > 0 && my_count == 0) {
- /* This also catches disconnects etc */
- /* Do what mygetbuf does except don't grab a character */
- my_count = myfillbuf();
- my_item = -1; /* ^^^ */
- debug(F101,"in_chk myfillbuf my_count","",my_count);
- if (my_count < 0)
- return(-1);
- else
- n = 0; /* NB: n is replaced by my_count */
- }
-#endif /* FIONREAD */
-/*
- Here we add whatever we think is unread to what is still in our
- our internal buffer. Thus the importance of setting n to 0 just above.
-*/
- debug(F101,"in_chk my_count","",my_count);
- debug(F101,"in_chk n","",n);
- if (my_count > 0)
- n += my_count;
-#endif /* MYREAD */
- }
- debug(F101,"in_chk result","",n);
-
- /* Errors here don't prove the connection has dropped so just say 0 */
-
- return(n < 0 ? 0 : n);
-}
-
-
-/* T T C H K -- Tell how many characters are waiting in tty input buffer */
-
-int
-ttchk() {
- int fd;
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
- return(in_chk(1,fd));
-}
-
-/* T T X I N -- Get n characters from tty input buffer */
-
-/* Returns number of characters actually gotten, or -1 on failure */
-
-/* Intended for use only when it is known that n characters are actually */
-/* Available in the input buffer. */
-
-int
-ttxin(n,buf) int n; CHAR *buf; {
- register int x = 0, c = -2;
-#ifdef TTLEBUF
- register int i = 0;
-#endif /* TTLEBUF */
- int fd;
-
- if (n < 1) /* Nothing to do */
- return(0);
-
-#ifdef TTLEBUF
- if (ttpush >= 0) {
- buf[0] = ttpush; /* Put pushed char in buffer*/
- ttpush = -1; /* Clear the push buffer */
- if (ttchk() > 0)
- return(ttxin(n-1, &buf[1]) + 1);
- else
- return(1);
- }
- if (le_data) {
- while (le_inbuf() > 0) {
- if (le_getchar(&buf[i])) {
- i++;
- n--;
- }
- }
- if (ttchk() > 0)
- return(ttxin(n,&buf[i])+i);
- else
- return(i);
- }
-#endif /* TTLEBUF */
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef SUNX25
- if (netconn && (ttnet == NET_SX25)) /* X.25 connection */
- return(x25xin(n,buf));
-#endif /* SUNX25 */
-
-#ifdef IBMX25
- /* riehm: possibly not needed. Test worked with normal reads and writes */
- if (netconn && (ttnet == NET_IX25)) { /* X.25 connection */
- x = x25xin(n,buf);
- if (x > 0) buf[x] = '\0';
- return(x);
- }
-#endif /* IBMX25 */
-
-#ifdef MYREAD
- debug(F101,"ttxin MYREAD","",n);
- while (x < n) {
- c = myread();
- if (c < 0) {
- debug(F101,"ttxin myread returns","",c);
- if (c == -3) x = -1;
- break;
- }
- buf[x++] = c & ttpmsk;
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
- /* It is impossible to know how many characters are waiting */
- /* to be read when you are using Encrypted Rlogin or SSL */
- /* as the transport since the number of real data bytes */
- /* can be greater or less than the number of bytes on the */
- /* wire which is what ttchk() returns. */
- if (netconn && (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN))
- if (ttchk() <= 0)
- break;
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag)
- if (ttchk() <= 0)
- break;
-#endif /* CK_SSL */
- }
-#else
- debug(F101,"ttxin READ","",n);
- x = read(fd,buf,n);
- for (c = 0; c < n; c++) /* Strip any parity */
- buf[c] &= ttpmsk;
-#endif /* MYREAD */
-
- debug(F101,"ttxin x","",x); /* Done */
- if (x > 0) buf[x] = '\0';
- if (x < 0) x = -1;
- return(x);
-}
-
-/* T T O L -- Write string s, length n, to communication device. */
-/*
- Returns:
- >= 0 on success, number of characters actually written.
- -1 on failure.
-*/
-#ifdef CK_ENCRYPTION
-CHAR * xpacket = NULL;
-int nxpacket = 0;
-#endif /* CK_ENCRYPTION */
-
-#define TTOLMAXT 5
-int
-ttol(s,n) int n; CHAR *s; {
- int x, len, tries, fd;
-#ifdef CKXXCHAR
- extern int dblflag; /* For SET SEND DOUBLE-CHARACTER */
- extern short dblt[];
- CHAR *p = NULL, *p2, *s2, c;
- int n2 = 0;
-#endif /* CKXXCHAR */
-
- if (ttyfd < 0) /* Not open? */
- return(-3);
-#ifdef DEBUG
- if (deblog) {
- /* debug(F101,"ttol ttyfd","",ttyfd); */
- ckhexdump("ttol s",s,n);
- }
-#endif /* DEBUG */
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdout;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef CKXXCHAR
-/* Double any characters that must be doubled. */
- debug(F101,"ttol dblflag","",dblflag);
- if (dblflag) {
- p = (CHAR *) malloc(n + n + 1);
- if (p) {
- s2 = s;
- p2 = p;
- n2 = 0;
- while (*s2) {
- c = *s2++;
- *p2++ = c;
- n2++;
- if (dblt[(unsigned) c] & 2) {
- *p2++ = c;
- n2++;
- }
- }
- s = p;
- n = n2;
- s[n] = '\0';
- }
-#ifdef DEBUG
- ckhexdump("ttol doubled s",s,n);
-#endif /* DEBUG */
- }
-#endif /* CKXXCHAR */
-
- tries = TTOLMAXT; /* Allow up to this many tries */
- len = n; /* Remember original length */
-
-#ifdef CK_ENCRYPTION
-/*
- This is to avoid encrypting a packet that is already encrypted, e.g.
- when we resend a packet directly out of the packet buffer, and also to
- avoid encrypting a constant (literal) string, which can cause a memory
- fault.
-*/
- if (TELOPT_ME(TELOPT_ENCRYPTION)) {
- int x;
- if (nxpacket < n) {
- if (xpacket) {
- free(xpacket);
- xpacket = NULL;
- nxpacket = 0;
- }
- x = n > 10240 ? n : 10240;
- xpacket = (CHAR *)malloc(x);
- if (!xpacket) {
- fprintf(stderr,"ttol malloc failure\n");
- return(-1);
- } else
- nxpacket = x;
- }
- memcpy((char *)xpacket,(char *)s,n);
- s = xpacket;
- ck_tn_encrypt((char *)s,n);
- }
-#endif /* CK_ENCRYPTION */
-
- while (n > 0 &&
- (tries-- > 0
-#ifdef CK_ENCRYPTION
- /* keep trying if we are encrypting */
- || TELOPT_ME(TELOPT_ENCRYPTION)
-#endif /* CK_ENCRYPTION */
- )) { /* Be persistent */
- debug(F101,"ttol try","",TTOLMAXT - tries);
-#ifdef BEOSORBEBOX
- if (netconn && !ttpipe && !ttpty)
- x = nettol((char *)s,n); /* Write string to device */
- else
-#endif /* BEOSORBEBOX */
-#ifdef IBMX25
- if (ttnet == NET_IX25)
- /*
- * this is a more controlled way of writing to X25
- * STREAMS, however write should also work!
- */
- x = x25write(ttyfd, s, n);
- else
-#endif /* IBMX25 */
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error;
- /* Write using SSL */
- ssl_retry:
- if (ssl_active_flag)
- x = SSL_write(ssl_con, s, n);
- else
- x = SSL_write(tls_con, s, n);
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,x)) {
- case SSL_ERROR_NONE:
- if (x == n)
- return(len);
- s += x;
- n -= x;
- goto ssl_retry;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- x = 0;
- break;
- case SSL_ERROR_SYSCALL:
- if (x != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- ttclos(0);
- return(-3);
- }
- } else
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- return(krb4_des_write(ttyfd,s,n));
- } else
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- return(krb5_des_write(ttyfd,(char *)s,n,0));
- } else
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- return(krb5_u2u_write(ttyfd,(char *)s,n));
- } else
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
- x = write(fd,s,n); /* Write string to device */
-
- if (x == n) { /* Worked? */
- debug(F101,"ttol ok","",x); /* OK */
-#ifdef CKXXCHAR
- if (p) free(p);
-#endif /* CKXXCHAR */
- return(len); /* Done */
- } else if (x < 0) { /* No, got error? */
- debug(F101,"ttol write error","",errno);
-#ifdef EWOULDBLOCK
- if (errno == EWOULDBLOCK) {
- msleep(10);
- continue;
- } else
-#endif /* EWOULDBLOCK */
-#ifdef TCPSOCKET
- if (netconn && ttnet == NET_TCPB) {
- debug(F101,"ttol TCP error","",errno);
- ttclos(0); /* Close the connection. */
- x = -3;
- }
-#endif /* TCPSOCKET */
-#ifdef CKXXCHAR
- if (p) free(p);
-#endif /* CKXXCHAR */
- return(x);
- } else { /* No error, so partial success */
- debug(F101,"ttol partial","",x); /* This never happens */
- s += x; /* Point to part not written yet */
- n -= x; /* Adjust length */
- if (x > 0) msleep(10); /* Wait 10 msec */
- } /* Go back and try again */
- }
-#ifdef CKXXCHAR
- if (p) free(p);
-#endif /* CKXXCHAR */
- return(n < 1 ? len : -1); /* Return the results */
-}
-
-/* T T O C -- Output a character to the communication line */
-
-/*
- This function should only be used for interactive, character-mode operations,
- like terminal connection, script execution, dialer i/o, where the overhead
- of the signals and alarms does not create a bottleneck.
-*/
-int
-#ifdef CK_ANSIC
-ttoc(char c)
-#else
-ttoc(c) char c;
-#endif /* CK_ANSIC */
-/* ttoc */ {
-#define TTOC_TMO 15 /* Timeout in case we get stuck */
- int xx, fd;
-
- if (ttyfd < 0) /* Check for not open. */
- return(-1);
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdout;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
- c &= 0xff;
- /* debug(F101,"ttoc","",(CHAR) c); */
- saval = signal(SIGALRM,timerh); /* Enable timer interrupt */
- xx = alarm(TTOC_TMO); /* for this many seconds. */
- if (xx < 0) xx = 0; /* Save old alarm value. */
- /* debug(F101,"ttoc alarm","",xx); */
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) { /* Timer went off? */
- ttimoff(); /* Yes, cancel this alarm. */
- if (xx - TTOC_TMO > 0) alarm(xx - TTOC_TMO); /* Restore previous one */
- /* debug(F100,"ttoc timeout","",0); */
-#ifdef NETCONN
- if (!netconn) {
-#endif /* NETCONN */
- debug(F101,"ttoc timeout","",c);
- if (ttflow == FLO_XONX) {
- debug(F101,"ttoc flow","",ttflow); /* Maybe we're xoff'd */
-#ifndef Plan9
-#ifdef POSIX
- /* POSIX way to unstick. */
- debug(F100,"ttoc tcflow","",tcflow(ttyfd,TCOON));
-#else
-#ifdef BSD4 /* Berkeley way to do it. */
-#ifdef TIOCSTART
-/* .... Used to be "ioctl(ttyfd, TIOCSTART, 0);". Who knows? */
- {
- int x = 0;
- debug(F101,"ttoc TIOCSTART","",ioctl(ttyfd, TIOCSTART, &x));
- }
-#endif /* TIOCSTART */
-#endif /* BSD4 */
- /* Is there a Sys V way to do this? */
-#endif /* POSIX */
-#endif /* Plan9 */
- }
-#ifdef NETCONN
- }
-#endif /* NETCONN */
- return(-1); /* Return failure code. */
- } else {
- int rc;
-#ifdef BEOSORBEBOX
-#ifdef NETCONN
- if (netconn && !ttpipe && !ttpty)
- rc = nettoc(c);
- else
-#endif /* BEOSORBEBOX */
-#endif /* NETCONN */
-#ifdef CK_ENCRYPTION
- if (TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(&c,1);
-#endif /* CK_ENCRYPTION */
-#ifdef IBMX25
- /* riehm: maybe this isn't necessary after all. Test program
- * worked fine with data being sent and retrieved with normal
- * read's and writes!
- */
- if (ttnet == NET_IX25)
- rc = x25write(ttyfd,&c,1); /* as above for X25 streams */
- else
-#endif /* IBMX25 */
-#ifdef CK_SSL
- if (ssl_active_flag || tls_active_flag) {
- int error;
- /* Write using SSL */
- if (ssl_active_flag)
- rc = SSL_write(ssl_con, &c, 1);
- else
- rc = SSL_write(tls_con, &c, 1);
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,rc)){
- case SSL_ERROR_NONE:
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- rc = 0;
- break;
- case SSL_ERROR_SYSCALL:
- if (rc != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- ttclos(0);
- return(-1);
- }
- } else
-#endif /* CK_SSL */
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef RLOGCODE
- if (ttnproto == NP_EK4LOGIN) {
- rc = (krb4_des_write(ttyfd,(char *)&c,1) == 1);
- } else
-#endif /* RLOGCODE */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifdef RLOGCODE
- if (ttnproto == NP_EK5LOGIN) {
- rc = (krb5_des_write(ttyfd,&c,1,0) == 1);
- } else
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- if (ttnproto == NP_K5U2U) {
- rc = (krb5_u2u_write(ttyfd,&c,1) == 1);
- } else
-#endif /* KRB5_U2U */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
- rc = write(fd,&c,1); /* Try to write the character. */
- if (rc < 1) { /* Failed */
- ttimoff(); /* Turn off the alarm. */
- alarm(xx); /* Restore previous alarm. */
- debug(F101,"ttoc errno","",errno); /* Log the error, */
- return(-1); /* and return the error code. */
- }
- }
- ttimoff(); /* Success, turn off the alarm. */
- alarm(xx); /* Restore previous alarm. */
- return(0); /* Return good code. */
-}
-
-/* T T I N L -- Read a record (up to break character) from comm line. */
-/*
- Reads up to "max" characters from the connection, terminating on:
- (a) the packet length field if the "turn" argument is zero, or
- (b) on the packet-end character (eol) if the "turn" argument is nonzero
- (c) a certain number of Ctrl-C's in a row
-
- Returns:
- >= 0, the number of characters read upon success;
- -1 if "max" exceeded, timeout, or other correctable error;
- -2 on user interruption (c);
- -3 on fatal error like connection lost.
-
- The name of this routine dates from the early days when Kermit packets
- were, indeed, always lines of text. That was before control-character
- unprefixing and length-driven packet framing were introduced, which this
- version handle. NB: this routine is ONLY for reading incoming Kermit
- packets, nothing else. To read other kinds of incoming material, use
- ttinc() or ttxin().
-
- The bytes that were input are copied into "dest" with their parity bits
- stripped if parity was selected. Returns the number of bytes read.
- Bytes after the eol are available upon the next call to this function.
-
- The idea is to minimize the number of system calls per packet, and also to
- minimize timeouts. This function is the inner loop of the protocol and must
- be as efficient as possible. The current strategy is to use myread(), a
- macro to manage buffered (and generally nonblocking) reads.
-
- WARNING: This function calls parchk(), which is defined in another module.
- Normally, ckutio.c does not depend on code from any other module, but there
- is an exception in this case because all the other ck?tio.c modules also
- need to call parchk(), so it's better to have it defined in a common place.
-*/
-#ifdef CTRLC
-#undef CTRLC
-#endif /* CTRLC */
-#define CTRLC '\03'
-/*
- We have four different declarations here because:
- (a) to allow Kermit to be built without the automatic parity sensing feature
- (b) one of each type for ANSI C, one for non-ANSI.
-*/
-#ifndef NOXFER
-
-static int pushedback = 0;
-
-int
-#ifdef PARSENSE
-#ifdef CK_ANSIC
-ttinl(CHAR *dest, int max,int timo, CHAR eol, CHAR start, int turn)
-#else
-ttinl(dest,max,timo,eol,start,turn) int max,timo,turn; CHAR *dest, eol, start;
-#endif /* CK_ANSIC */
-#else /* not PARSENSE */
-#ifdef CK_ANSIC
-ttinl(CHAR *dest, int max,int timo, CHAR eol)
-#else
-ttinl(dest,max,timo,eol) int max,timo; CHAR *dest, eol;
-#endif /* CK_ANSIC */
-#endif /* PARSENSE */
-/* ttinl */ {
-
-#ifndef MYREAD
- CHAR ch, dum;
-#endif /* MYREAD */
-#ifdef PARSENSE
- int pktlen = -1;
- int lplen = 0;
- int havelen = 0;
-#endif /* PARSENSE */
- int fd;
- int sopmask = 0xff; /* Start-Of-Packet mask */
-#ifdef CKXXCHAR
- extern short dblt[]; /* Ignore-character table */
- extern int ignflag;
-#endif /* CKXXCHAR */
-#ifdef TCPSOCKET
- extern CHAR stchr;
-#endif /* TCPSOCKET */
- int x;
-#ifdef STREAMING
- extern int streaming;
- extern int sndtyp;
-#endif /* STREAMING */
-
- if (ttyfd < 0) return(-3); /* Not open. */
-/*
- In February 2007 I fixed ttinl() to work better under the truly awful
- conditions encountered by the AM-APEX oceanographic floats that gather
- hurricane data and phone home using Iridium satellite modems, which under
- certain conditions, can send two packets back to back after a long pause.
- In this case the second packet would be ignored because the SOH was skipped
- due to the ttflui() call. But the reworked lookahead/pushback logic broke
- Kermit transfers on encrypted connections. This was fixed 12-13 August
- 2007. All of this happened after 8.0.212 Dev.27 was released and before
- Dev.28, so no harm done other than the delay.
-*/
- debug(F101,"ttinl max","",max);
- debug(F101,"ttinl timo","",timo);
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
-#ifdef COMMENT
- if (xlocal && conchk() > 0) /* Allow for console interruptions */
- return(-1);
-#endif /* COMMENT */
-
- *dest = '\0'; /* Clear destination buffer */
- if (timo < 0) timo = 0; /* Safety */
- if (timo) { /* Don't time out if timo == 0 */
- int xx;
- saval = signal(SIGALRM,timerh); /* Enable timer interrupt */
- xx = alarm(timo); /* Set it. */
- debug(F101,"ttinl alarm","",xx);
- }
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) { /* Timer went off? */
- debug(F100,"ttinl timout","",0); /* Get here on timeout. */
- /* debug(F110," with",(char *) dest,0); */
- ttimoff(); /* Turn off timer */
- return(-1); /* and return error code. */
- } else {
- register int i, n = -1; /* local variables */
- int ccn = 0;
-#ifdef PARSENSE
- register int flag = 0;
- debug(F000,"ttinl start","",start);
-#endif /* PARSENSE */
-
- ttpmsk = ttprty ? 0177 : 0377; /* Set parity stripping mask. */
- sopmask = needpchk ? 0177 : ttpmsk; /* And SOP matching mask. */
-
-/* Now read into destination, stripping parity and looking for the */
-/* the packet terminator, and also for several Ctrl-C's typed in a row. */
-
- i = 0; /* Destination index */
- debug(F101,"ttinl eol","",eol);
-
- while (i < max-1) {
-#ifdef MYREAD
- errno = 0;
- /* On encrypted connections myread returns encrypted bytes */
- n = myread();
- debug(F000,"TTINL myread char","",n);
- if (n < 0) { /* Timeout or i/o error? */
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"ttinl myread failure, n","",n);
- debug(F101,"ttinl myread errno","",errno);
- }
-#endif /* DEBUG */
- /* Don't let EINTR break packets. */
- if (n == -3) {
- if (errno == EINTR && i > 0) {
- debug(F111,"ttinl EINTR myread i","continuing",i);
- continue;
- } else {
- debug(F110,"ttinl non-EINTR -3","closing",0);
- wasclosed = 1;
- ttimoff(); /* Turn off timer */
- ttclos(0);
- return(n);
- }
- } else if (n == -2 && netconn /* && timo == 0 */ ) {
- /* Here we try to catch broken network connections */
- /* even when ioctl() and read() do not catch them */
- debug(F111,"ttinl network myread failure","closing",n);
- wasclosed = 1;
- ttimoff();
- ttclos(0);
- return(-3);
- }
-#ifdef STREAMING
- /* Streaming and no data to read */
- else if (n == 0 && streaming && sndtyp == 'D')
- return(0);
-#endif /* STREAMING */
- break; /* Break out of while loop */
- }
-
-#else /* not MYREAD (is this code used anywhere any more?) */
-/*
- The non-MYREAD code dates from the 1980s and was needed on certain platforms
- where there were no nonblocking reads. -fdc, 2007/02/22.
-*/
- if ((n = read(fd, &n, 1)) < 1)
- break; /* Error - break out of while loop */
-
-#endif /* MYREAD */
-
- /* Get here with char in n */
-
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION) && !pushedback) {
- CHAR ch = n;
- ck_tn_decrypt((char *)&ch,1);
- n = ch;
- debug(F000,"TTINL decryp char","",n);
- }
- pushedback = 0;
-#endif /* CK_ENCRYPTION */
-
-#ifdef TCPSOCKET
- if (n == IAC && /* Handle Telnet options */
- ((xlocal && netconn && IS_TELNET()) ||
- (!xlocal && sstelnet))) {
- n = tt_tnopt(n);
- if (n < 0)
- return(n);
-#ifndef NOPARSEN
- else if (n == 1)
- start = stchr;
-#endif /* NOPARSEN */
- if (n != 255) /* No data - go back for next char */
- continue;
- } /* Quoted IAC - keep going */
-#endif /* TCPSOCKET */
-
-#ifdef CKXXCHAR
- if (ignflag)
- if (dblt[(unsigned) n] & 1) /* Character to ignore? */
- continue;
-#endif /* CKXXCHAR */
-/*
- Use parity mask, rather than always stripping parity, to check for
- cancellation. Otherwise, runs like \x03\x83\x03 in a packet could cancel
- the transfer when parity is NONE. (Note that \x03\x03\x03 is extremely
- unlikely due to run-length encoding.)
-*/
- /* Check cancellation */
- if (!xlocal && xfrcan && ((n & ttpmsk) == xfrchr)) {
- if (++ccn >= xfrnum) { /* If xfrnum in a row, bail out. */
- if (timo) { /* Clear timer. */
- ttimoff();
- }
- if (xfrchr < 32)
- printf("^%c...\r\n",(char)(xfrchr+64));
- else
- printf("Canceled...\r\n");
- return(-2);
- }
- } else ccn = 0; /* No cancellation, reset counter, */
-
-#ifdef PARSENSE
-/*
- Restructured code allows for a new packet to appear somewhere in the
- middle of a previous one. -fdc, 24 Feb 2007.
-*/
- if ((n & sopmask) == start) { /* Start of Packet */
- debug(F101,"ttinl SOP i","",i);
- flag = 1; /* Flag that we are in a packet */
- havelen = 0; /* Invalidate previous length */
- pktlen = -1; /* (if any) in case we were */
- lplen = 0; /* alread processand a packet */
- i = 0; /* and reset the dest buffer pointer */
- }
- if (flag == 0) { /* No SOP yet... */
- debug(F000,"ttinl skipping","",n);
- continue;
- }
- dest[i++] = n & ttpmsk;
-/*
- If we have not been instructed to wait for a turnaround character, we can go
- by the packet length field. If turn != 0, we must wait for the end of line
- (eol) character before returning. This is an egregious violation of all
- principles of layering... (Less egregious in C-Kermit 9.0, in which we go
- by the length field but also look for the eol in case it arrives early,
- e.g. if the length field was corrupted upwards.)
-*/
- if (!havelen) {
- if (i == 2) {
- if ((dest[1] & 0x7f) < 32) /* Garbage in length field */
- return(-1); /* fdc - 13 Apr 2010 */
- pktlen = xunchar(dest[1] & 0x7f);
- if (pktlen > 94) /* Rubout in length field */
- return(-1); /* fdc - 13 Apr 2010 */
- if (pktlen > 1) {
- havelen = 1;
- debug(F101,"ttinl pktlen value","",pktlen);
- }
- } else if (i == 5 && pktlen == 0) {
- lplen = xunchar(dest[4] & 0x7f);
- } else if (i == 6 && pktlen == 0) {
- pktlen = lplen * 95 + xunchar(dest[5] & 0x7f) + 5;
- havelen = 1;
- debug(F101,"ttinl extended length","",pktlen);
- }
- }
-
-/*
- Suppose we looked at the sequence number here and found it was out of
- range? This would mean either (a) incoming packets had SOP unprefixed
- and we are out of sync, or (b) the packet is damaged. Since (a) is bad
- practice, let's ignore it. So what should we do here if we know the
- packet is damaged?
-
- 1. Nothing -- keep trying to read the packet till we find what we think
- is the end, or we time out, and let the upper layer decide what to
- do. But since either the packet is corrupt or we are out of sync,
- our criterion for finding the end does not apply and we are likely
- to time out (or swallow a piece of the next packet) if our assumed
- length is too long. (This was the behavior prior to version 7.0.)
-
- 2. set flag = 0 and continue? This would force us to wait for the
- next packet to come in, and therefore (in the nonwindowing case),
- would force a timeout in the other Kermit.
-
- 3. set flag = 0 and continue, but only if the window size is > 1 and
- the window is not blocked? Talk about cheating!
-
- 4. Return a failure code and let the upper layer decide what to do.
- This should be equivalent to 3, but without the cheating. So let's
- do it that way... But note that we must ignore the parity bit
- in case this is the first packet and we have not yet run parchk().
-*/
- if (i == 3) { /* Peek at sequence number */
- x = xunchar((dest[i-1] & 0x7f)); /* If it's not in range... */
- if (x < 0 || x > 63) {
- debug(F111,"ttinl bad seq",dest,x);
- if (timo) ttimoff();
- return(-1); /* return a nonfatal error */
- }
- }
-
-#else /* PARSENSE */
- dest[i++] = n & ttpmsk;
-#endif /* PARSENSE */
-
- /* Check for end of packet */
-
- if (
- ((n & ttpmsk) == eol) /* Always break on the eol char */
-#ifdef PARSENSE
- || /* fdc - see notes of 13 Apr 2010 */
-/*
- Purely length-driven if SET HANDSHAKE NONE (i.e. turn == 0).
- This allows packet terminators and handshake characters to appear
- literally inside a packet data field.
-*/
- (havelen && (i > pktlen+1) &&
- (!turn || (turn && (n & 0x7f) == turn))) /* (turn, not eol) */
-
-#endif /* PARSENSE */
- ) {
-/*
- Here we have either read the last byte of the packet based on its length
- field, or else we have read the packet terminator (eol) or the half-duplex
- line-turnaround char (turn).
-*/
-#ifndef PARSENSE
- debug(F101,"ttinl got eol","",eol); /* (or turn) */
- dest[i] = '\0'; /* Yes, terminate the string, */
- /* debug(F101,"ttinl i","",i); */
-
-#else /* PARSENSE */
-
-#ifdef DEBUG
- if (deblog) {
- if ((n & ttpmsk) != eol) {
- debug(F101,"ttinl EOP length","",pktlen);
- debug(F000,"ttinl EOP current char","",n);
- debug(F101,"ttinl EOP packet buf index","",i);
- } else debug(F101,"ttinl got eol","",eol);
- }
-#endif /* DEBUG */
-
-#ifdef MYREAD
-/*
- The packet was read based on its length. This leaves the packet terminator
- unread, and so ttchk() will always return at least 1 because of this,
- possibly giving a false positive to the "is there another packet waiting?"
- test. But if we know the terminator (or any other interpacket junk) is
- there, we can safely get rid of it.
-
- NOTE: This code reworked to (a) execute even if the debug log isn't active;
- and (b) actually work. -fdc, 2007/02/22. And again 2007/08/12-13 to also
- work on encrypted connections.
-*/
- debug(F101,"TTINL my_count","",my_count);
- if ((n & ttpmsk) != eol) { /* Not the packet terminator */
- int x;
- while (my_count > 0) {
- x = myread(); /* (was ttinc(0) */
- debug(F000,"TTINL lkread char","",x);
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION)) {
- CHAR ch = x;
- ck_tn_decrypt((char *)&ch,1);
- x = ch;
- debug(F000,"TTINL lkdecr char","",x);
- }
-#endif /* CK_ENCRYPTION */
- /*
- Note: while it might seem more elegant to simply
- push back the encrypted byte, that desynchronizes
- the decryption stream; the flag is necessary so we
- don't try to decrypt the same byte twice.
- */
- if ((x & ttpmsk) == start) { /* Start of next packet */
- myunrd(x); /* Push back the decrypted byte */
- pushedback = 1; /* And set flag */
- debug(F000,"TTINL lkpush char","",x);
- break;
- }
- }
- }
-#endif /* MYREAD */
-
- dest[i] = '\0'; /* Terminate the string, */
- if (needpchk) { /* Parity checked yet? */
- if (ttprty == 0) { /* No, check. */
- if ((ttprty = parchk(dest,start,i)) > 0) {
- int j;
- debug(F101,"ttinl senses parity","",ttprty);
- debug(F110,"ttinl packet before",dest,0);
- ttpmsk = 0x7f;
- for (j = 0; j < i; j++)
- dest[j] &= 0x7f; /* Strip parity from packet */
- debug(F110,"ttinl packet after ",dest,0);
- } else ttprty = 0; /* Restore if parchk error */
- }
- sopmask = ttpmsk;
- needpchk = 0;
- }
-#endif /* PARSENSE */
-
- if (timo) /* Turn off timer if it was on */
- ttimoff();
- ckhexdump("ttinl got",dest,i);
-
-#ifdef STREAMING
- /* ttinl() was called because there was non-packet */
- /* data sitting in the back channel. Ignore it. */
- if (streaming && sndtyp == 'D')
- return(-1);
-#endif /* STREAMING */
- return(i);
- }
- } /* End of while() */
- ttimoff();
- return(n);
- }
-}
-#endif /* NOXFER */
-
-/* T T I N C -- Read a character from the communication line */
-/*
- On success, returns the character that was read, >= 0.
- On failure, returns -1 or other negative myread error code,
- or -2 if connection is broken or ttyfd < 0.
- or -3 if session limit has expired,
- or -4 if something or other...
- NOTE: The API does not provide for ttinc() returning a special code
- upon timeout, but we need it. So for this we have a global variable,
- ttinctimo.
-*/
-static int ttinctimo = 0; /* Yuk */
-
-int
-ttinc(timo) int timo; {
-
- int n = 0, fd;
- int is_tn = 0;
- CHAR ch = 0;
-
- ttinctimo = 0;
-
- if (ttyfd < 0) return(-2); /* Not open. */
-
- is_tn = (xlocal && netconn && IS_TELNET()) ||
- (!xlocal && sstelnet);
-
-#ifdef TTLEBUF
- if (ttpush >= 0) {
- debug(F111,"ttinc","ttpush",ttpush);
- ch = ttpush;
- ttpush = -1;
- return(ch);
- }
- if (le_data) {
- if (le_getchar(&ch) > 0) {
- debug(F111,"ttinc le_getchar","ch",ch);
- return(ch);
- }
- }
-#endif /* TTLEBUF */
-
-#ifdef NETCMD
- if (ttpipe)
- fd = fdin;
- else
-#endif /* NETCMD */
- fd = ttyfd;
-
- if ((timo <= 0) /* Untimed. */
-#ifdef MYREAD
- || (my_count > 0) /* Buffered char already waiting. */
-#endif /* MYREAD */
- ) {
-#ifdef MYREAD
- /* Comm line failure returns -1 thru myread, so no &= 0377 */
- n = myread(); /* Wait for a character... */
- /* debug(F000,"ttinc MYREAD n","",n); */
-#ifdef CK_ENCRYPTION
- /* debug(F101,"ttinc u_encrypt","",TELOPT_U(TELOPT_ENCRYPTION)); */
- if (TELOPT_U(TELOPT_ENCRYPTION) && n >= 0) {
- ch = n;
- ck_tn_decrypt((char *)&ch,1);
- n = ch;
- }
-#endif /* CK_ENCRYPTION */
-
-#ifdef NETPTY
- if (ttpty && n < 0) {
- debug(F101,"ttinc error on pty","",n);
- ttclos(0);
- return(n);
- }
-#endif /* NETPTY */
-
-#ifdef TNCODE
- if ((n > -1) && is_tn)
- return((unsigned)(n & 0xff));
- else
-#endif /* TNCODE */
- return(n < 0 ? n : (unsigned)(n & ttpmsk));
-
-#else /* MYREAD */
-
- while ((n = read(fd,&ch,1)) == 0) /* Wait for a character. */
- /* Shouldn't have to loop in ver 5A. */
-#ifdef NETCONN
- if (netconn) { /* Special handling for net */
- netclos(); /* If read() returns 0 it means */
- netconn = 0; /* the connection has dropped. */
- errno = ENOTCONN;
- return(-2);
- }
-#endif /* NETCONN */
- ;
- /* debug(F101,"ttinc","",ch); */
-#ifdef TNCODE
- if ((n > 0) && is_tn) {
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION)) {
- ck_tn_decrypt(&ch,1);
- n = ch;
- }
-#endif /* CK_ENCRYPTION */
- return((unsigned)(ch & 0xff));
- } else
-#endif /* TNCODE */
- return((n < 0) ? -4 : ((n == 0) ? -1 : (unsigned)(ch & ttpmsk)));
-#endif /* MYREAD */
-
- } else { /* Timed read */
-
- int oldalarm;
- saval = signal(SIGALRM,timerh); /* Set up handler, save old one. */
- oldalarm = alarm(timo); /* Set alarm, save old one. */
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) { /* Timer expired */
- ttinctimo = 1;
- n = -1; /* set flag */
- } else {
-#ifdef MYREAD
- n = myread(); /* If managing own buffer... */
- debug(F101,"ttinc myread","",n);
- ch = n;
-#else
- n = read(fd,&ch,1); /* Otherwise call the system. */
- if (n == 0) n = -1;
- debug(F101,"ttinc read","",n);
-#endif /* MYREAD */
-
-#ifdef CK_ENCRYPTION
- if (TELOPT_U(TELOPT_ENCRYPTION) && n >= 0) {
- ck_tn_decrypt((char *)&ch,1);
- }
-#endif /* CK_ENCRYPTION */
- if (n >= 0)
- n = (unsigned) (ch & 0xff);
- else
- n = (n < 0) ? -4 : -2; /* Special return codes. */
- }
- ttimoff(); /* Turn off the timer */
- if (oldalarm > 0) {
- if (n == -1) /* and restore any previous alarm */
- oldalarm -= timo;
- if (oldalarm < 0) /* adjusted by our timeout interval */
- oldalarm = 0;
- if (oldalarm) {
- debug(F101,"ttinc restoring oldalarm","",oldalarm);
- alarm(oldalarm);
- }
- }
-#ifdef NETCONN
- if (netconn) {
- if (n == -2) { /* read() returns 0 */
- netclos(); /* on network read failure */
- netconn = 0;
- errno = ENOTCONN;
- }
- }
-#endif /* NETCONN */
-#ifdef TNCODE
- if ((n > -1) && is_tn)
- return((unsigned)(n & 0xff));
- else
-#endif /* TNCODE */
- /* Return masked char or neg. */
- return( (n < 0) ? n : (unsigned)(n & ttpmsk) );
- }
-}
-
-/* S N D B R K -- Send a BREAK signal of the given duration */
-
-static int
-#ifdef CK_ANSIC
-sndbrk(int msec) { /* Argument is milliseconds */
-#else
-sndbrk(msec) int msec; {
-#endif /* CK_ANSIC */
-#ifndef POSIX
- int x, n;
-#endif /* POSIX */
-
-#ifdef OXOS
-#define BSDBREAK
-#endif /* OXOS */
-
-#ifdef ANYBSD
-#define BSDBREAK
-#endif /* ANYBSD */
-
-#ifdef BSD44
-#define BSDBREAK
-#endif /* BSD44 */
-
-#ifdef COHERENT
-#ifdef BSDBREAK
-#undef BSDBREAK
-#endif /* BSDBREAK */
-#endif /* COHERENT */
-
-#ifdef BELLV10
-#ifdef BSDBREAK
-#undef BSDBREAK
-#endif /* BSDBREAK */
-#endif /* BELLV10 */
-
-#ifdef PROVX1
- char spd;
-#endif /* PROVX1 */
-
- debug(F101,"ttsndb ttyfd","",ttyfd);
- if (ttyfd < 0) return(-1); /* Not open. */
-
-#ifdef Plan9
- return p9sndbrk(msec);
-#else
-#ifdef NETCONN
-#ifdef NETCMD
- if (ttpipe) /* Pipe */
- return(ttoc('\0'));
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty)
- return(ttoc('\0'));
-#endif /* NETPTY */
- if (netconn) /* Send network BREAK */
- return(netbreak());
-#endif /* NETCONN */
-
- if (msec < 1 || msec > 5000) return(-1); /* Bad argument */
-
-#ifdef POSIX /* Easy in POSIX */
- {
- int x;
- debug(F111,"sndbrk POSIX",ckitoa(msec),(msec/375));
- errno = 0;
- x = tcsendbreak(ttyfd,msec / 375);
- debug(F111,"sndbrk tcsendbreak",ckitoa(errno),x);
- return(x);
- }
-#else
-#ifdef PROVX1
- gtty(ttyfd,&ttbuf); /* Get current tty flags */
- spd = ttbuf.sg_ospeed; /* Save speed */
- ttbuf.sg_ospeed = B50; /* Change to 50 baud */
- stty(ttyfd,&ttbuf); /* ... */
- n = (int)strlen(brnuls); /* Send the right number of nulls */
- x = msec / 91;
- if (x > n) x = n;
- write(ttyfd,brnuls,n);
- ttbuf.sg_ospeed = spd; /* Restore speed */
- stty(ttyfd,&ttbuf); /* ... */
- return(0);
-#else
-#ifdef aegis
- sio_$control((short)ttyfd, sio_$send_break, msec, st);
- return(0);
-#else
-#ifdef BSDBREAK
- n = FWRITE; /* Flush output queue. */
-/* Watch out for int vs long problems in &n arg! */
- debug(F101,"sndbrk BSDBREAK","",msec);
- ioctl(ttyfd,TIOCFLUSH,&n); /* Ignore any errors.. */
- if (ioctl(ttyfd,TIOCSBRK,(char *)0) < 0) { /* Turn on BREAK */
- perror("Can't send BREAK");
- return(-1);
- }
- x = msleep(msec); /* Sleep for so many milliseconds */
- if (ioctl(ttyfd,TIOCCBRK,(char *)0) < 0) { /* Turn off BREAK */
- perror("BREAK stuck!!!");
- doexit(BAD_EXIT,-1); /* Get out, closing the line. */
- /* with bad exit status */
- }
- return(x);
-#else
-#ifdef ATTSV
-/*
- No way to send a long BREAK in Sys V, so send a bunch of regular ones.
- (Actually, Sys V R4 is *supposed* to have the POSIX tcsendbreak() function,
- but there's no way for this code to know for sure.)
-*/
- debug(F101,"sndbrk ATTSV","",msec);
- x = msec / 275;
- for (n = 0; n < x; n++) {
- /* Reportedly the cast breaks this function on some systems */
- /* But then why was it here in the first place? */
- if (ioctl(ttyfd,TCSBRK, /* (char *) */ 0) < 0) {
- perror("Can't send BREAK");
- return(-1);
- }
- }
- return(0);
-#else
-#ifdef V7
- debug(F101,"sndbrk V7","",msec);
- return(genbrk(ttyfd,250)); /* Simulate a BREAK */
-#else
- debug(F101,"sndbrk catchall","",msec);
- ttoc(0);ttoc(0);ttoc(0);ttoc(0);
- return(0);
-#endif /* V7 */
-#endif /* BSDBREAK */
-#endif /* ATTSV */
-#endif /* aegis */
-#endif /* PROVX1 */
-#endif /* POSIX */
-#endif /* Plan9 */
-}
-
-/* T T S N D B -- Send a BREAK signal */
-
-int
-ttsndb() {
-#ifdef TN_COMPORT
- if (netconn && istncomport())
- return((tnsndb(275L) >= 0) ? 0 : -1);
- else
-#endif /* TN_COMPORT */
- return(sndbrk(275));
-}
-
-/* T T S N D L B -- Send a Long BREAK signal */
-
-int
-ttsndlb() {
-#ifdef TN_COMPORT
- if (netconn && istncomport())
- return((tnsndb(1800L) >= 0) ? 0 : -1);
- else
-#endif /* TN_COMPORT */
- return(sndbrk(1500));
-}
-
-/* M S L E E P -- Millisecond version of sleep(). */
-
-/*
- Call with number of milliseconds (thousandths of seconds) to sleep.
- Intended only for small intervals. For big ones, just use sleep().
- Highly system-dependent.
- Returns 0 always, even if it didn't work.
-*/
-
-/* Define MSLFTIME for systems that must use an ftime() loop. */
-#ifdef ANYBSD /* For pre-4.2 BSD versions */
-#ifndef BSD4
-#define MSLFTIME
-#endif /* BSD4 */
-#endif /* ANYBSD */
-
-#ifdef TOWER1 /* NCR Tower OS 1.0 */
-#define MSLFTIME
-#endif /* TOWER1 */
-
-#ifdef COHERENT /* Coherent... */
-#ifndef _I386 /* Maybe Coherent/386 should get this, too */
-#define MSLFTIME /* Opinions are divided */
-#endif /* _I386 */
-#endif /* COHERENT */
-
-#ifdef COMMENT
-#ifdef GETMSEC
-
-/* Millisecond timer */
-
-static long msecbase = 0L; /* Unsigned long not portable */
-
-long
-getmsec() { /* Milliseconds since base time */
- struct timeval xv;
- struct timezone xz;
- long secs, msecs;
- if (
-#ifdef GTODONEARG
- gettimeofday(&tv)
-#else
-#ifdef PTX
- gettimeofday(&tv, NULL)
-#else
- gettimeofday(&tv, &tz)
-#endif /* PTX */
-#endif /* GTODONEARG */
- < 0)
- return(-1);
- if (msecbase == 0L) { /* First call, set base time. */
- msecbase = tv.tv_sec;
- debug(F101,"getmsec base","",msecbase);
- }
- return(((tv.tv_sec - msecbase) * 1000L) + (tv.tv_usec / 1000L));
-}
-#endif /* GETMSEC */
-#endif /* COMMENT */
-
-#ifdef SELECT
-int
-ttwait(fd, secs) int fd, secs; {
- int x;
- fd_set rfds;
- FD_ZERO(&rfds);
- FD_SET(fd,&rfds);
- tv.tv_sec = secs;
- tv.tv_usec = 0L;
- errno = 0;
- if ((x = select(FD_SETSIZE,
-#ifdef HPUX9
- (int *)
-#else
-#ifdef HPUX1000
- (int *)
-#endif /* HPUX1000 */
-#endif /* HPUX9 */
- &rfds,
- 0, 0, &tv)) < 0) {
- debug(F101,"ttwait select errno","",errno);
- return(0);
- } else {
- debug(F101,"ttwait OK","",errno);
- x = FD_ISSET(fd, &rfds);
- debug(F101,"ttwait select x","",x);
- return(x ? 1 : 0);
- }
-}
-#endif /* SELECT */
-
-int
-msleep(m) int m; {
-/*
- Other possibilities here are:
- nanosleep(), reportedly defined in POSIX.4.
- sginap(), IRIX only (back to what IRIX version I don't know).
-*/
-#ifdef Plan9
- return _SLEEP(m);
-#else
-#ifdef BEOSORBEBOX
- snooze(m*1000);
-#else /* BEOSORBEBOX */
-#ifdef SELECT
- int t1, x;
- debug(F101,"msleep SELECT 1","",m);
- if (m <= 0) return(0);
- if (m >= 1000) { /* Catch big arguments. */
- sleep(m/1000);
- m = m % 1000;
- if (m < 10) return(0);
- }
- debug(F101,"msleep SELECT 2","",m);
-#ifdef BELLV10
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, m );
- debug(F101,"msleep BELLV10 select","",x);
-#else /* BELLV10 */
-#ifdef HPUX9
- gettimeofday(&tv, &tz);
-#else
-
-#ifndef COHERENT
-#ifdef GTODONEARG
- if (gettimeofday(&tv) < 0)
-#else
-#ifdef PTX
- if (gettimeofday(&tv,NULL) < 0)
-#else
-#ifdef NOTIMEZONE
- if (gettimeofday(&tv, NULL) < 0) /* wonder what this does... */
-#else
- if (gettimeofday(&tv, &tz) < 0)
-#endif /* NOTIMEZONE */
-#endif /* PTX */
-#endif /* GTODONEARG */
- return(-1);
- t1 = tv.tv_sec; /* Seconds */
-#endif /* COHERENT */
-#endif /* HPUX9 */
- tv.tv_sec = 0; /* Use select() */
- tv.tv_usec = m * 1000L;
-#ifdef BSD44
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep BSD44 select","",x);
-#else /* BSD44 */
-#ifdef __linux__
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep __linux__ select","",x);
-#else /* __linux__ */
-#ifdef BSD43
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep BSD43 select","",x);
-#else /* BSD43 */
-#ifdef QNX6
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep QNX6 select","",x);
-#else /* QNX6 */
-#ifdef QNX
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep QNX select","",x);
-#else /* QNX */
-#ifdef COHERENT
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep COHERENT select","",x);
-#else /* COHERENT */
-#ifdef HPUX1000 /* 10.00 only, not 10.10 or later */
- x = select( 0, (int *)0, (int *)0, (int *)0, &tv );
- debug(F101,"msleep HP-UX 10.00 select","",x);
-#else /* HPUX1000 */
-#ifdef SVR4
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep SVR4 select","",x);
-#else /* SVR4 */
-#ifdef OSF40
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep OSF40 select","",x);
-#else /* OSF40 */
-#ifdef PTX
- x = select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
- debug(F101,"msleep OSF40 select","",x);
-#else
- x = select( 0, (int *)0, (int *)0, (int *)0, &tv );
- debug(F101,"msleep catch-all select","",x);
-#endif /* PTX */
-#endif /* OSF40 */
-#endif /* HP1000 */
-#endif /* SVR4 */
-#endif /* COHERENT */
-#endif /* QNX */
-#endif /* QNX6 */
-#endif /* BSD43 */
-#endif /* __linux__ */
-#endif /* BSD44 */
-#endif /* BELLV10 */
- return(0);
-
-#else /* Not SELECT */
-#ifdef CK_POLL /* We have poll() */
- struct pollfd pfd; /* Supply a valid address for poll() */
-
-#ifdef ODT30 /* But in SCO ODT 3.0 */
-#ifdef NAP /* we should use nap() instead */
- debug(F101,"msleep ODT 3.0 NAP","",m); /* because using poll() here */
- nap((long)m); /* seems to break dialing. */
- return(0);
-#else
- debug(F101,"msleep ODT 3.0 POLL","",m);
- poll(&pfd, 0, m);
- return(0);
-#endif /* NAP */
-#else
- debug(F101,"msleep POLL","",m);
- poll(&pfd, 0, m);
- return(0);
-#endif /* ODT30 */
-
-/*
- We could handle the above more cleanly by just letting nap() always
- take precedence over poll() in this routine, but there is no way to know
- whether that would break something else.
-*/
-
-#else /* Not POLL */
-#ifdef USLEEP
-/*
- "This routine is implemented using setitimer(2); it requires eight
- system calls...". In other words, it might take 5 minutes to sleep
- 10 milliseconds...
-*/
- debug(F101,"msleep USLEEP","",m);
- if (m >= 1000) { /* Catch big arguments. */
- sleep(m/1000);
- m = m % 1000;
- if (m < 10) return(0);
- }
- usleep((unsigned int)(m * 1000));
- return(0);
-#else
-#ifdef aegis
- time_$clock_t dur;
- debug(F101,"msleep aegis","",m);
- dur.c2.high16 = 0;
- dur.c2.low32 = 250 * m; /* one millisecond = 250 four microsecond ticks */
- time_$wait(time_$relative, dur, st);
- return(0);
-#else
-#ifdef PROVX1
- debug(F101,"msleep Venix","",m);
- if (m <= 0) return(0);
- sleep(-((m * 60 + 500) / 1000));
- return(0);
-#else
-#ifdef NAP
- debug(F101,"msleep NAP","",m);
- nap((long)m);
- return(0);
-#else
-#ifdef ATTSV
-#ifndef BSD44
- extern long times(); /* Or #include <times.h> ? */
-#endif /* BSD44 */
- long t1, t2, tarray[4];
- int t3;
- char *cp = getenv("HZ");
- int CLOCK_TICK;
- int hertz;
-
- if (cp && (hertz = atoi(cp))) {
- CLOCK_TICK = 1000 / hertz;
- } else { /* probably single user mode */
-#ifdef HZ
- CLOCK_TICK = 1000 / HZ;
-#else
- static warned = 0;
- /* HZ always exists in, for instance, SCO Xenix, so you don't have to
- * make special #ifdefs for XENIX here, like in ver 4F. Also, if you
- * have Xenix, you have should have nap(), so the best is to use -DNAP
- * in the makefile. Most systems have HZ.
- */
- CLOCK_TICK = 17; /* 1/60 sec */
- if (!warned) {
- printf("warning: environment variable HZ bad... using HZ=%d\r\n",
- 1000 / CLOCK_TICK);
- warned = 1;
- }
-#endif /* !HZ */
- }
- debug(F101,"msleep ATTSV","",m);
- if (m <= 0) return(0);
- if (m >= 1000) { /* Catch big arguments. */
- sleep(m/1000);
- m = m % 1000;
- if (m < 10) return(0);
- }
- if ((t1 = times(tarray)) < 0) return(-1);
- while (1) {
- if ((t2 = times(tarray)) < 0) return(-1);
- t3 = ((int)(t2 - t1)) * CLOCK_TICK;
- if (t3 > m) return(t3);
- }
-#else /* Not ATTSV */
-#ifdef MSLFTIME /* Use ftime() loop... */
- int t1, t3 = 0;
- debug(F101,"msleep MSLFTIME","",m);
- if (m <= 0) return(0);
- if (m >= 1000) { /* Catch big arguments. */
- sleep(m/1000);
- m = m % 1000;
- if (m < 10) return(0);
- }
-#ifdef QNX
- ftime(&ftp); /* void ftime() in QNX */
-#else
- if (ftime(&ftp) < 0) return(-1); /* Get base time. */
-#endif /* QNX */
- t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm;
- while (1) {
- ftime(&ftp); /* Get current time and compare. */
- t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1;
- if (t3 > m) return(0);
- }
-#else
-/* This includes true POSIX, which has no way to do this. */
- debug(F101,"msleep busy loop","",m);
- if (m >= 1000) { /* Catch big arguments. */
- sleep(m/1000);
- m = m % 1000;
- if (m < 10) return(0);
- }
- if (m > 0) while (m > 0) m--; /* Just a dumb busy loop */
- return(0);
-#endif /* MSLFTIME */
-#endif /* ATTSV */
-#endif /* NAP */
-#endif /* PROVX1 */
-#endif /* aegis */
-#endif /* CK_POLL */
-#endif /* SELECT */
-#endif /* BEOSORBEBOX */
-#endif /* USLEEP */
-#endif /* Plan9 */
-}
-
-/* R T I M E R -- Reset elapsed time counter */
-
-VOID
-rtimer() {
- tcount = time( (time_t *) 0 );
-}
-
-
-/* G T I M E R -- Get current value of elapsed time counter in seconds */
-
-int
-gtimer() {
- int x;
- x = (int) (time( (time_t *) 0 ) - tcount);
- debug(F101,"gtimer","",x);
- return( (x < 0) ? 0 : x );
-}
-
-#ifdef GFTIMER
-/*
- Floating-point timers. Require not only floating point support, but
- also gettimeofday().
-*/
-static struct timeval tzero;
-
-VOID
-rftimer() {
-#ifdef GTODONEARG /* Account for Mot's definition */
- (VOID) gettimeofday(&tzero);
-#else
- (VOID) gettimeofday(&tzero, (struct timezone *)0);
-#endif /* GTODONEARG */
-}
-
-CKFLOAT
-gftimer() {
- struct timeval tnow, tdelta;
- CKFLOAT s;
-#ifdef DEBUG
- char fpbuf[64];
-#endif /* DEBUG */
-#ifdef GTODONEARG /* Account for Mot's definition */
- (VOID) gettimeofday(&tnow);
-#else
- (VOID) gettimeofday(&tnow, (struct timezone *)0);
-#endif /* GTODONEARG */
-
- tdelta.tv_sec = tnow.tv_sec - tzero.tv_sec;
- tdelta.tv_usec = tnow.tv_usec - tzero.tv_usec;
-
- if (tdelta.tv_usec < 0) {
- tdelta.tv_sec--;
- tdelta.tv_usec += 1000000;
- }
- s = (CKFLOAT) tdelta.tv_sec + ((CKFLOAT) tdelta.tv_usec / 1000000.0);
- if (s < GFMINTIME)
- s = GFMINTIME;
-#ifdef DEBUG
- if (deblog) {
- sprintf(fpbuf,"%f",s);
- debug(F110,"gftimer",fpbuf,0);
- }
-#endif /* DEBUG */
- return(s);
-}
-#endif /* GFTIMER */
-
-/* Z T I M E -- Return asctime()-format date/time string */
-/*
- NOTE: as a side effect of calling this routine, we can also set the
- following two variables, giving the micro- and milliseconds (fractions of
- seconds) of the clock time. Currently this is done only in BSD-based builds
- that use gettimeofday(). When these variables are not filled in, they are
- left with a value of -1L.
-*/
-static char asctmbuf[64];
-
-VOID
-ztime(s) char **s; {
-
-#ifdef GFTIMER
-/*
- The gettimeofday() method, which also sets ztmsec and ztusec, works for
- all GFTIMER builds. NOTE: ztmsec and ztusec are defined in ckcmai.c,
- and extern declarations for them are in ckcdeb.h; thus they are
- declared in this file by inclusion of ckcdeb.h.
-*/
- char *asctime();
- struct tm *localtime();
- struct tm *tp;
- ztmsec = -1L;
- ztusec = -1L;
-
- if (!s)
- debug(F100,"ztime s==NULL","",0);
-
-#ifdef GTODONEARG
- /* No 2nd arg in Motorola SV88 and some others */
- if (gettimeofday(&tv) > -1)
-#else
-#ifndef COHERENT
-#ifdef PTX
- if (gettimeofday(&tv,NULL) > -1)
-#else
-#ifdef NOTIMEZONE
- if (gettimeofday(&tv, NULL) > -1) /* wonder what this does... */
-#else
- if (gettimeofday(&tv, &tz) > -1)
-#endif /* NOTIMEZONE */
-#endif /* PTX */
-#endif /* COHERENT */
-#endif /* GTODONEARG */
- { /* Fill in tm struct */
- ztusec = tv.tv_usec; /* Microseconds */
- ztmsec = ztusec / 1000L; /* Milliseconds */
-#ifdef HPUX9
- {
- time_t zz;
- zz = tv.tv_sec;
- tp = localtime(&zz); /* Convert to local time */
- }
-#else
-#ifdef HPUX1000
- {
- time_t zz;
- zz = tv.tv_sec;
- tp = localtime(&zz);
- }
-#else
-#ifdef LINUX
- { /* avoid unaligned access trap on 64-bit platforms */
- time_t zz;
- zz = tv.tv_sec;
- tp = localtime(&zz);
- }
-#else
-#ifdef MACOSX
- tp = localtime((time_t *)&tv.tv_sec); /* Convert to local time */
-#else
- tp = localtime(&tv.tv_sec);
-#endif /* MACOSX */
-#endif /* LINUX */
-#endif /* HPUX1000 */
-#endif /* HPUX9 */
- if (s) {
- char * s2;
- s2 = asctime(tp); /* Convert result to ASCII string */
- asctmbuf[0] = '\0';
- if (s2) ckstrncpy(asctmbuf,s2,64);
- *s = asctmbuf;
- debug(F111,"ztime GFTIMER gettimeofday",*s,ztusec);
- }
- }
-#else /* Not GFTIMER */
-
-#undef ZTIMEV7 /* Which systems need to use */
-#ifdef COHERENT /* old UNIX Version 7 way... */
-#define ZTIMEV7
-#endif /* COHERENT */
-#ifdef TOWER1
-#define ZTIMEV7
-#endif /* TOWER1 */
-#ifdef ANYBSD
-#ifndef BSD42
-#define ZTIMEV7
-#endif /* BSD42 */
-#endif /* ANYBSD */
-#ifdef V7
-#ifndef MINIX
-#define ZTIMEV7
-#endif /* MINIX */
-#endif /* V7 */
-#ifdef POSIX
-#define ZTIMEV7
-#endif /* POSIX */
-
-#ifdef HPUX1020
-/*
- Prototypes are in <time.h>, included above.
-*/
- time_t clock_storage;
- clock_storage = time((void *) 0);
- if (s) {
- *s = ctime(&clock_storage);
- debug(F110,"ztime: HPUX 10.20",*s,0);
- }
-#else
-#ifdef ATTSV /* AT&T way */
-/* extern long time(); */ /* Theoretically these should */
- char *ctime(); /* already been dcl'd in <time.h> */
- time_t clock_storage;
- clock_storage = time(
-#ifdef IRIX60
- (time_t *)
-#else
-#ifdef BSD44
- (time_t *)
-#else
- (long *)
-#endif /* BSD44 */
-#endif /* IRIX60 */
- 0 );
- if (s) {
- *s = ctime( &clock_storage );
- debug(F110,"ztime: ATTSV",*s,0);
- }
-#else
-#ifdef PROVX1 /* Venix 1.0 way */
- int utime[2];
- time(utime);
- if (s) {
- *s = ctime(utime);
- debug(F110,"ztime: PROVX1",*s,0);
- }
-#else
-#ifdef BSD42 /* 4.2BSD way */
- char *asctime();
- struct tm *localtime();
- struct tm *tp;
- gettimeofday(&tv, &tz);
- ztusec = tv.tv_usec;
- ztmsec = tv.tv_usec / 1000L;
- tp = localtime(&tv.tv_sec);
- if (s) {
- *s = asctime(tp);
- debug(F111,"ztime: BSD42",*s,ztusec);
- }
-#else
-#ifdef MINIX /* MINIX way */
-#ifdef COMMENT
- extern long time(); /* Already got these from <time.h> */
- extern char *ctime();
-#endif /* COMMENT */
- time_t utime[2];
- time(utime);
- if (s) {
- *s = ctime(utime);
- debug(F110,"ztime: MINIX",*s,0);
- }
-#else
-#ifdef ZTIMEV7 /* The regular way */
- char *asctime();
- struct tm *localtime();
- struct tm *tp;
- long xclock; /* or unsigned long for BeBox? */
- time(&xclock);
- tp = localtime(&xclock);
- if (s) {
- *s = asctime(tp);
- debug(F110,"ztime: ZTIMEV7",*s,0);
- }
-#else /* Catch-all for others... */
- if (s) {
- *s = "Day Mon 00 00:00:00 0000\n"; /* Dummy in asctime() format */
- debug(F110,"ztime: catch-all",*s,0);
- }
-#endif /* ZTIMEV7 */
-#endif /* MINIX */
-#endif /* BSD42 */
-#endif /* PROVX1 */
-#endif /* ATTSV */
-#endif /* HPUX1020 */
-#endif /* GFTIMER */
-}
-
-/* C O N G M -- Get console terminal modes. */
-
-/*
- Saves initial console mode, and establishes variables for switching
- between current (presumably normal) mode and other modes.
- Should be called when program starts, but only after establishing
- whether program is in the foreground or background.
- Returns 1 if it got the modes OK, 0 if it did nothing, -1 on error.
-*/
-int
-congm() {
- int fd;
- if (backgrd || !isatty(0)) { /* If in background. */
- cgmf = -1; /* Don't bother, modes are garbage. */
- return(-1);
- }
- if (cgmf > 0) return(0); /* Already did this. */
- debug(F100,"congm getting modes","",0); /* Need to do it. */
-#ifdef aegis
- ios_$inq_type_uid(ios_$stdin, conuid, st);
- if (st.all != status_$ok) {
- fprintf(stderr, "problem getting stdin objtype: ");
- error_$print(st);
- }
- concrp = (conuid == mbx_$uid);
- conbufn = 0;
-#endif /* aegis */
-
-#ifndef BEBOX
- if ((fd = open(CTTNAM,2)) < 0) { /* Open controlling terminal */
-#ifdef COMMENT
- fprintf(stderr,"Error opening %s\n", CTTNAM);
- perror("congm");
- return(-1);
-#else
- fd = 0;
-#endif /* COMMENT */
- }
-#else
- fd = 0;
-#endif /* !BEBOX */
-#ifdef BSD44ORPOSIX
- if (tcgetattr(fd,&ccold) < 0) return(-1);
- if (tcgetattr(fd,&cccbrk) < 0) return(-1);
- if (tcgetattr(fd,&ccraw) < 0) return(-1);
-#else
-#ifdef ATTSV
- if (ioctl(fd,TCGETA,&ccold) < 0) return(-1);
- if (ioctl(fd,TCGETA,&cccbrk) < 0) return(-1);
- if (ioctl(fd,TCGETA,&ccraw) < 0) return(-1);
-#ifdef VXVE
- cccbrk.c_line = 0; /* STTY line 0 for CDC VX/VE */
- if (ioctl(fd,TCSETA,&cccbrk) < 0) return(-1);
- ccraw.c_line = 0; /* STTY line 0 for CDC VX/VE */
- if (ioctl(fd,TCSETA,&ccraw) < 0) return(-1);
-#endif /* VXVE */
-#else
-#ifdef BELLV10
- if (ioctl(fd,TIOCGETP,&ccold) < 0) return(-1);
- if (ioctl(fd,TIOCGETP,&cccbrk) < 0) return(-1);
- if (ioctl(fd,TIOCGETP,&ccraw) < 0) return(-1);
- debug(F101,"cccbrk.sg_flags orig","", cccbrk.sg_flags);
-#else
- if (gtty(fd,&ccold) < 0) return(-1);
- if (gtty(fd,&cccbrk) < 0) return(-1);
- if (gtty(fd,&ccraw) < 0) return(-1);
-#endif /* BELLV10 */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-#ifdef sony_news /* Sony NEWS */
- if (ioctl(fd,TIOCKGET,&km_con) < 0) { /* Get console Kanji mode */
- perror("congm error getting Kanji mode");
- debug(F101,"congm error getting Kanji mode","",0);
- km_con = -1; /* Make sure this stays undefined. */
- return(-1);
- }
-#endif /* sony_news */
- if (fd > 0)
- close(fd);
- cgmf = 1; /* Flag that we got them. */
- return(1);
-}
-
-
-static VOID
-congetbuf(x) int x; {
- int n;
- n = CONBUFSIZ - (conbufp - conbuf); /* How much room left in buffer? */
- if (x > n) {
- debug(F101,"congetbuf char loss","",x-n);
- x = n;
- }
- x = read(0,conbufp,x);
- conbufn += x;
- debug(F111,"congetbuf readahead",conbuf,x);
-}
-
-
-/* C O N C B -- Put console in cbreak mode. */
-
-/* Returns 0 if ok, -1 if not */
-
-int
-#ifdef CK_ANSIC
-concb(char esc)
-#else
-concb(esc) char esc;
-#endif /* CK_ANSIC */
-/* concb */ {
- int x, y = 0;
- debug(F101,"concb constate","",constate);
- debug(F101,"concb cgmf","",cgmf);
- debug(F101,"concb backgrd","",backgrd);
-
- if (constate == CON_CB)
- return(0);
-
- if (cgmf < 1) /* Did we get console modes yet? */
- if (!backgrd) /* No, in background? */
- congm(); /* No, try to get them now. */
- if (cgmf < 1) /* Still don't have them? */
- return(0); /* Give up. */
- debug(F101,"concb ttyfd","",ttyfd);
- debug(F101,"concb ttfdflg","",ttfdflg);
-#ifdef COMMENT
- /* This breaks returning to prompt after protocol with "-l 0" */
- /* Commented out July 1998 */
- if (ttfdflg && ttyfd >= 0 && ttyfd < 3)
- return(0);
-#endif /* COMMENT */
- x = isatty(0);
- debug(F101,"concb isatty","",x);
- if (!x) return(0); /* Only when running on real ttys */
- debug(F101,"concb xsuspend","",xsuspend);
- if (backgrd) /* Do nothing if in background. */
- return(0);
- escchr = esc; /* Make this available to other fns */
- ckxech = 1; /* Program can echo characters */
-#ifdef aegis
- conbufn = 0;
- if (concrp) return(write(1, "\035\002", 2));
- if (conuid == input_pad_$uid) {pad_$raw(ios_$stdin, st); return(0);}
-#endif /* aegis */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifdef Plan9
- x = p9concb();
-#else
-#ifndef SVORPOSIX /* BSD, V7, etc */
- debug(F101,"cccbrk.sg_flags concb 1","", cccbrk.sg_flags);
- debug(F101,"concb stty CBREAK","",0);
- cccbrk.sg_flags |= (CBREAK|CRMOD); /* Set to character wakeup, */
- cccbrk.sg_flags &= ~ECHO; /* no echo. */
- debug(F101,"cccbrk.sg_flags concb 2","", cccbrk.sg_flags);
- errno = 0;
-/*
- BSD stty() clears the console buffer. So if anything is waiting in it,
- we have to read it now to avoid losing it.
-*/
- x = conchk();
- if (x > 0)
- congetbuf(x);
-
-#ifdef BELLV10
- x = ioctl(0,TIOCSETP,&cccbrk);
-#else
- x = stty(0,&cccbrk);
- debug(F101,"cccbrk.sg_flags concb x","", x);
-#endif /* BELLV10 */
-#else /* Sys V and POSIX */
-#ifndef OXOS
- debug(F101,"concb cccbrk.c_flag","",cccbrk.c_lflag);
-#ifdef QNX
- /* Don't mess with IEXTEN */
- cccbrk.c_lflag &= ~(ICANON|ECHO);
-#else
-#ifdef COHERENT
- cccbrk.c_lflag &= ~(ICANON|ECHO);
-#else
- cccbrk.c_lflag &= ~(ICANON|ECHO|IEXTEN);
-#endif /* COHERENT */
-#endif /* QNX */
- cccbrk.c_lflag |= ISIG; /* Allow signals in command mode. */
- cccbrk.c_iflag |= IGNBRK; /* But ignore BREAK signal */
- cccbrk.c_iflag &= ~BRKINT;
-
-#else /* OXOS */
- debug(F100,"concb OXOS is defined","",0);
- cccbrk.c_lflag &= ~(ICANON|ECHO);
- cccbrk.c_cc[VDISCARD] = cccbrk.c_cc[VLNEXT] = CDISABLE;
-#endif /* OXOS */
-#ifdef COMMENT
-/*
- Believe it or not, in SCO UNIX, VSUSP is greater than NCC, and so this
- array reference is out of bounds. It's only a debug() call so who needs it.
-*/
-#ifdef VSUSP
- debug(F101,"concb c_cc[VSUSP]","",cccbrk.c_cc[VSUSP]);
-#endif /* VSUSP */
-#endif /* COMMENT */
-#ifndef VINTR
- debug(F101,"concb c_cc[0]","",cccbrk.c_cc[0]);
- cccbrk.c_cc[0] = 003; /* Interrupt char is Control-C */
-#else
- debug(F101,"concb c_cc[VINTR]","",cccbrk.c_cc[0]);
- cccbrk.c_cc[VINTR] = 003;
-#endif /* VINTR */
-#ifndef VQUIT
- cccbrk.c_cc[1] = escchr; /* escape during packet modes */
-#else
- cccbrk.c_cc[VQUIT] = escchr;
-#endif /* VQUIT */
-#ifndef VEOF
- cccbrk.c_cc[4] = 1;
-#else
-#ifndef OXOS
-#ifdef VMIN
- cccbrk.c_cc[VMIN] = 1;
-#endif /* VMIN */
-#else /* OXOS */
- cccbrk.c_min = 1;
-#endif /* OXOS */
-#endif /* VEOF */
-#ifdef ZILOG
- cccbrk.c_cc[5] = 0;
-#else
-#ifndef VEOL
- cccbrk.c_cc[5] = 1;
-#else
-#ifndef OXOS
-#ifdef VTIME
- cccbrk.c_cc[VTIME] = 1;
-#endif /* VTIME */
-#else /* OXOS */
- cccbrk.c_time = 1;
-#endif /* OXOS */
-#endif /* VEOL */
-#endif /* ZILOG */
- errno = 0;
-#ifdef BSD44ORPOSIX /* Set new modes */
- x = tcsetattr(0,TCSADRAIN,&cccbrk);
-#else /* ATTSV */ /* or the POSIX way */
- x = ioctl(0,TCSETAW,&cccbrk); /* the Sys V way */
-#endif /* BSD44ORPOSIX */
-#endif /* SVORPOSIX */
-
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
- debug(F101,"concb x","",x);
- debug(F101,"concb errno","",errno);
-
-#ifdef V7
-#ifndef MINIX
- if (kmem[CON] < 0) {
- qaddr[CON] = initrawq(0);
- if((kmem[CON] = open("/dev/kmem", 0)) < 0) {
- fprintf(stderr, "Can't read /dev/kmem in concb.\n");
- perror("/dev/kmem");
- exit(1);
- }
- }
-#endif /* MINIX */
-#endif /* V7 */
-#endif /* Plan9 */
-
- if (x > -1)
- constate = CON_CB;
-
- debug(F101,"concb returns","",x);
- return(x);
-}
-
-/* C O N B I N -- Put console in binary mode */
-
-/* Returns 0 if ok, -1 if not */
-
-int
-#ifdef CK_ANSIC
-conbin(char esc)
-#else
-conbin(esc) char esc;
-#endif /* CK_ANSIC */
-/* conbin */ {
-
- int x;
-
- debug(F101,"conbin constate","",constate);
-
- if (constate == CON_BIN)
- return(0);
-
- if (!isatty(0)) return(0); /* only for real ttys */
- congm(); /* Get modes if necessary. */
- debug(F100,"conbin","",0);
- escchr = esc; /* Make this available to other fns */
- ckxech = 1; /* Program can echo characters */
-#ifdef aegis
- conbufn = 0;
- if (concrp) return(write(1, "\035\002", 2));
- if (conuid == input_pad_$uid) {
- pad_$raw(ios_$stdin, st);
- return(0);
- }
-#endif /* aegis */
-
-#ifdef COHERENT
-#define SVORPOSIX
-#endif /* COHERENT */
-
-#ifdef Plan9
- return p9conbin();
-#else
-#ifdef SVORPOSIX
-#ifndef OXOS
-#ifdef QNX
- ccraw.c_lflag &= ~(ISIG|ICANON|ECHO);
-#else
-#ifdef COHERENT
- ccraw.c_lflag &= ~(ISIG|ICANON|ECHO);
-#else
- ccraw.c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
-#endif /* COHERENT */
-#endif /* QNX */
-#else /* OXOS */
- ccraw.c_lflag &= ~(ISIG|ICANON|ECHO);
- ccraw.c_cc[VDISCARD] = ccraw.c_cc[VLNEXT] = CDISABLE;
-#endif /* OXOS */
- ccraw.c_iflag |= IGNPAR;
-/*
- Note that for terminal sessions we disable Xon/Xoff flow control to allow
- the passage ^Q and ^S as data characters for EMACS, and to allow XMODEM
- transfers to work when C-Kermit is in the middle, etc. Hardware flow
- control, if in use, is not affected.
-*/
-#ifdef ATTSV
-#ifdef BSD44
- ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF
- |INPCK|ISTRIP);
-#else
- ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXANY|IXOFF
- |INPCK|ISTRIP);
-#endif /* BSD44 */
-#else /* POSIX */
- ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IXON|IXOFF|INPCK|ISTRIP);
-#endif /* ATTSV */
- ccraw.c_oflag &= ~OPOST;
-#ifdef COMMENT
-/*
- WHAT THE HECK WAS THIS FOR?
- The B9600 setting (obviously) prevents CONNECT from working at any
- speed other than 9600 when you are logged in to the 7300 on a serial
- line. Maybe some of the other flags are necessary -- if so, put back
- the ones that are needed. This code is supposed to work the same, no
- matter whether you are logged in to the 7300 on the real console device,
- or through a serial port.
-*/
-#ifdef ATT7300
- ccraw.c_cflag = CLOCAL | B9600 | CS8 | CREAD | HUPCL;
-#endif /* ATT7300 */
-#endif /* COMMENT */
-
-/*** Kermit used to put the console in 8-bit raw mode, but some users have
- *** pointed out that this should not be done, since some sites actually
- *** use terminals with parity settings on their Unix systems, and if we
- *** override the current settings and stop doing parity, then their terminals
- *** will display blotches for characters whose parity is wrong. Therefore,
- *** the following two lines are commented out (Larry Afrin, Clemson U):
- ***
- *** ccraw.c_cflag &= ~(PARENB|CSIZE);
- *** ccraw.c_cflag |= (CS8|CREAD);
- ***
- *** Sys III/V sites that have trouble with this can restore these lines.
- ***/
-#ifndef VINTR
- ccraw.c_cc[0] = 003; /* Interrupt char is Ctrl-C */
-#else
- ccraw.c_cc[VINTR] = 003;
-#endif /* VINTR */
-#ifndef VQUIT
- ccraw.c_cc[1] = escchr; /* Escape during packet mode */
-#else
- ccraw.c_cc[VQUIT] = escchr;
-#endif /* VQUIT */
-#ifndef VEOF
- ccraw.c_cc[4] = 1;
-#else
-#ifndef OXOS
-#ifdef VMIN
- ccraw.c_cc[VMIN] = 1;
-#endif /* VMIN */
-#else /* OXOS */
- ccraw.c_min = 1;
-#endif /* OXOS */
-#endif /* VEOF */
-
-#ifdef ZILOG
- ccraw.c_cc[5] = 0;
-#else
-#ifndef VEOL
- ccraw.c_cc[5] = 1;
-#else
-#ifndef OXOS
-#ifdef VTIME
- ccraw.c_cc[VTIME] = 1;
-#endif /* VTIME */
-#else /* OXOS */
- ccraw.c_time = 1;
-#endif /* OXOS */
-#endif /* VEOL */
-#endif /* ZILOG */
-
-#ifdef BSD44ORPOSIX
- x = tcsetattr(0,TCSADRAIN,&ccraw); /* Set new modes. */
-#else
- x = ioctl(0,TCSETAW,&ccraw);
-#endif /* BSD44ORPOSIX */
-#else /* Berkeley, etc. */
- x = conchk(); /* Because stty() is destructive */
- if (x > 0)
- congetbuf(x);
- ccraw.sg_flags |= (RAW|TANDEM); /* Set rawmode, XON/XOFF (ha) */
- ccraw.sg_flags &= ~(ECHO|CRMOD); /* Set char wakeup, no echo */
-#ifdef BELLV10
- x = ioctl(0,TIOCSETP,&ccraw);
-#else
- x = stty(0,&ccraw);
-#endif /* BELLV10 */
-#endif /* SVORPOSIX */
-#endif /* Plan9 */
-
- if (x > -1)
- constate = CON_BIN;
-
- debug(F101,"conbin returns","",x);
- return(x);
-
-#ifdef COHERENT
-#undef SVORPOSIX
-#endif /* COHERENT */
-
-}
-
-
-/* C O N R E S -- Restore the console terminal */
-
-int
-conres() {
- int x;
- debug(F101,"conres cgmf","",cgmf);
- debug(F101,"conres constate","",constate);
-
- if (cgmf < 1) /* Do nothing if modes unchanged */
- return(0);
- if (constate == CON_RES)
- return(0);
-
- if (!isatty(0)) return(0); /* only for real ttys */
- debug(F100,"conres isatty ok","",0);
- ckxech = 0; /* System should echo chars */
-
-#ifdef aegis
- conbufn = 0;
- if (concrp) return(write(1, "\035\001", 2));
- if (conuid == input_pad_$uid) {
- pad_$cooked(ios_$stdin, st);
- constate = CON_RES;
- return(0);
- }
-#endif /* aegis */
-
-#ifdef Plan9
- p9conres();
-#else
-#ifdef BSD44ORPOSIX
- debug(F100,"conres restoring tcsetattr","",0);
- x = tcsetattr(0,TCSADRAIN,&ccold);
-#else
-#ifdef ATTSV
- debug(F100,"conres restoring ioctl","",0);
- x = ioctl(0,TCSETAW,&ccold);
-#else /* BSD, V7, and friends */
-#ifdef sony_news /* Sony NEWS */
- if (km_con != -1)
- ioctl(0,TIOCKSET,&km_con); /* Restore console Kanji mode */
-#endif /* sony_news */
- msleep(100);
- debug(F100,"conres restoring stty","",0);
- x = conchk(); /* Because stty() is destructive */
- if (x > 0)
- congetbuf(x);
-#ifdef BELLV10
- x = ioctl(0,TIOCSETP,&ccold);
-#else
- x = stty(0,&ccold);
-#endif /* BELLV10 */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-#endif /* Plan9 */
- if (x > -1)
- constate = CON_RES;
-
- debug(F101,"conres returns","",x);
- return(x);
-}
-
-/* C O N O C -- Output a character to the console terminal */
-
-int
-#ifdef CK_ANSIC
-conoc(char c)
-#else
-conoc(c) char c;
-#endif /* CK_ANSIC */
-/* conoc */ {
-
-#ifdef IKSD
- if (inserver && !local)
- return(ttoc(c));
-
-#ifdef CK_ENCRYPTION
- if (inserver && TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(&c,1);
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
-
-#ifdef Plan9
- return conwrite(&c,1);
-#else
- return(write(1,&c,1));
-#endif /* Plan9 */
-}
-
-/* C O N X O -- Write x characters to the console terminal */
-
-int
-conxo(x,s) int x; char *s; {
-
-#ifdef IKSD
- if (inserver && !local)
- return(ttol((CHAR *)s,x));
-
-#ifdef CK_ENCRYPTION
- if (inserver && TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(s,x);
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
-
-#ifdef Plan9
- return(conwrite(s,x));
-#else
- return(write(1,s,x));
-#endif /* Plan9 */
-}
-
-/* C O N O L -- Write a line to the console terminal */
-
-int
-conol(s) char *s; {
- int len;
- if (!s) s = ""; /* Always do this! */
- len = strlen(s);
- if (len == 0)
- return(0);
-
-#ifdef IKSD
- if (inserver && !local)
- return(ttol((CHAR *)s,len));
-
-#ifdef CK_ENCRYPTION
- if (inserver && TELOPT_ME(TELOPT_ENCRYPTION)) {
- if (nxpacket < len) {
- if (xpacket) {
- free(xpacket);
- xpacket = NULL;
- nxpacket = 0;
- }
- len = len > 10240 ? len : 10240;
- xpacket = (CHAR *)malloc(len);
- if (!xpacket) {
- fprintf(stderr,"ttol malloc failure\n");
- return(-1);
- } else
- nxpacket = len;
- }
- memcpy(xpacket,s,len);
- s = (char *)xpacket;
- ck_tn_encrypt(s,len);
- }
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
-
-#ifdef Plan9
- return(conwrite(s,len));
-#else
- return(write(1,s,len));
-#endif /* Plan9 */
-}
-
-/* C O N O L A -- Write an array of lines to the console terminal */
-
-int
-conola(s) char *s[]; {
- char * p;
- int i, x;
-
-
- if (!s) return(0);
- for (i = 0; ; i++) {
- p = s[i];
- if (!p) p = ""; /* Let's not dump core shall we? */
- if (!*p)
- break;
-#ifdef IKSD
- if (inserver && !local)
- x = ttol((CHAR *)p,(int)strlen(p));
- else
-#endif /* IKSD */
- x = conol(p);
- if (x < 0)
- return(-1);
- }
- return(0);
-}
-
-/* C O N O L L -- Output a string followed by CRLF */
-
-int
-conoll(s) char *s; {
- CHAR buf[3];
- buf[0] = '\r';
- buf[1] = '\n';
- buf[2] = '\0';
- if (!s) s = "";
-
-#ifdef IKSD
- if (inserver && !local) {
- if (*s) ttol((CHAR *)s,(int)strlen(s));
- return(ttol(buf,2));
- }
-#endif /* IKSD */
-
- if (*s) conol(s);
-#ifdef IKSD
-#ifdef CK_ENCRYPTION
- if (inserver && TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt((char *)buf,2);
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
-
-#ifdef Plan9
- return(conwrite(buf, 2));
-#else
- return(write(1,buf,2));
-#endif /* Plan9 */
-}
-
-/* C O N C H K -- Return how many characters available at console */
-/*
- We could also use select() here to cover a few more systems that are not
- covered by any of the following, e.g. HP-UX 9.0x on the model 800.
-*/
-int
-conchk() {
- static int contyp = 0; /* +1 for isatty, -1 otherwise */
-
- if (contyp == 0) /* This prevents unnecessary */
- contyp = (isatty(0) ? 1 : -1); /* duplicated calls to isatty() */
- debug(F101,"conchk contyp","",contyp);
- if (backgrd || (contyp < 0))
- return(0);
-
-#ifdef aegis
- if (conbufn > 0) return(conbufn); /* use old count if nonzero */
-
- /* read in more characters */
- conbufn = ios_$get(ios_$stdin,
- ios_$cond_opt, conbuf, (long)sizeof(conbuf), st);
- if (st.all != status_$ok) conbufn = 0;
- conbufp = conbuf;
- return(conbufn);
-#else
-#ifdef IKSD
- if (inserver && !local)
- return(in_chk(1,ttyfd));
- else
-#endif /* IKSD */
- return(in_chk(0,0));
-#endif /* aegis */
-}
-
-/* C O N I N C -- Get a character from the console */
-/*
- Call with timo > 0 to do a timed read, timo == 0 to do an untimed blocking
- read. Upon success, returns the character. Upon failure, returns -1.
- A timed read that does not complete within the timeout period returns -2.
-*/
-int
-coninc(timo) int timo; {
- int n = 0; CHAR ch;
- int xx;
-
- if (conbufn > 0) { /* If something already buffered */
- --conbufn;
- return((unsigned)(*conbufp++ & 0xff));
- }
-
- errno = 0; /* Clear this */
-#ifdef IKSD
- if (inserver && !local) {
- xx = ttinc(timo);
- if (xx < 0)
- return(ttinctimo ? -2 : -1);
- else
- return(xx);
- }
-#endif /* IKSD */
-
-#ifdef aegis /* Apollo Aegis only... */
- debug(F101,"coninc timo","",timo);
- fflush(stdout);
- if (conchk() > 0) {
- --conbufn;
- return((unsigned)(*conbufp++ & 0xff));
- }
-#endif /* aegis */
-
-#ifdef TTLEBUF
- if (
-#ifdef IKSD
- inserver &&
-#endif /* IKSD */
- !xlocal
- ) {
- if (ttpush >= 0) {
- debug(F111,"ttinc","ttpush",ttpush);
- ch = ttpush;
- ttpush = -1;
- return(ch);
- }
- if (le_data) {
- if (le_getchar(&ch) > 0) {
- debug(F111,"ttinc LocalEchoInBuf","ch",ch);
- return(ch);
- }
- }
- }
-#endif /* TTLEBUF */
-
- if (timo <= 0) { /* Untimed, blocking read. */
- while (1) { /* Keep trying till we get one. */
- n = read(0, &ch, 1); /* Read a character. */
- if (n == 0) continue; /* Shouldn't happen. */
- if (n > 0) { /* If read was successful, */
-#ifdef IKSD
-#ifdef CK_ENCRYPTION
- debug(F100,"coninc decrypt 1","",0);
- if (inserver && !local && TELOPT_U(TELOPT_ENCRYPTION))
- ck_tn_decrypt((char *)&ch,1);
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
- return((unsigned)(ch & 0xff)); /* return the character. */
- }
-
-/* Come here if read() returned an error. */
-
- debug(F101, "coninc(0) errno","",errno); /* Log the error. */
-#ifndef OXOS
-#ifdef SVORPOSIX
-#ifdef CIE /* CIE Regulus has no EINTR symbol? */
-#ifndef EINTR
-#define EINTR 4
-#endif /* EINTR */
-#endif /* CIE */
-/*
- This routine is used for several different purposes. In CONNECT mode, it is
- used to do an untimed, blocking read from the keyboard in the lower CONNECT
- fork. During local-mode file transfer, it reads a character from the
- console to interrupt the file transfer (like A for a status report, X to
- cancel a file, etc). Obviously, we don't want the reads in the latter case
- to be blocking, or the file transfer would stop until the user typed
- something. Unfortunately, System V does not allow the console device input
- buffer to be sampled nondestructively (e.g. by conchk()), so a kludge is
- used instead. During local-mode file transfer, the SIGQUIT signal is armed
- and trapped by esctrp(), and this routine pretends to have read the quit
- character from the keyboard normally. But, kludge or no kludge, the read()
- issued by this command, under System V only, can fail if a signal -- ANY
- signal -- is caught while the read is pending. This can occur not only when
- the user types the quit character, but also during telnet negotiations, when
- the lower CONNECT fork signals the upper one about an echoing mode change.
- When this happens, we have to post the read() again. This is apparently not
- a problem in BSD-based UNIX versions.
-*/
- if (errno == EINTR) /* Read interrupted. */
- if (conesc) { /* If by SIGQUIT, */
- conesc = 0; /* the conesc variable is set, */
- return(escchr); /* so return the escape character. */
- } else continue; /* By other signal, try again. */
-#else
-/*
- This might be dangerous, but let's do this on non-System V versions too,
- since at least one SunOS 4.1.2 user complains of immediate disconnections
- upon first making a TELNET connection.
-*/
- if (errno == EINTR) /* Read interrupted. */
- continue;
-#endif /* SVORPOSIX */
-#else /* OXOS */
- if (errno == EINTR) /* Read interrupted. */
- continue;
-#endif /* OXOS */
- return(-1); /* Error */
- }
- }
-#ifdef DEBUG
- if (deblog && timo <= 0) {
- debug(F100,"coninc timeout logic error","",0);
- timo = 1;
- }
-#endif /* DEBUG */
-
-/* Timed read... */
-
- saval = signal(SIGALRM,timerh); /* Set up timeout handler. */
- xx = alarm(timo); /* Set the alarm. */
- debug(F101,"coninc alarm set","",timo);
- if (
-#ifdef CK_POSIX_SIG
- sigsetjmp(sjbuf,1)
-#else
- setjmp(sjbuf)
-#endif /* CK_POSIX_SIG */
- ) /* The read() timed out. */
- n = -2; /* Code for timeout. */
- else
- n = read(0, &ch, 1);
- ttimoff(); /* Turn off timer */
- if (n > 0) { /* Got character OK. */
-#ifdef IKSD
-#ifdef CK_ENCRYPTION
- debug(F100,"coninc decrypt 2","",0);
- if (inserver && !local && TELOPT_U(TELOPT_ENCRYPTION))
- ck_tn_decrypt((char *)&ch,1);
-#endif /* CK_ENCRYPTION */
-#endif /* IKSD */
- return((unsigned)(ch & 0xff)); /* Return it. */
- }
-/*
- read() returned an error. Same deal as above, but without the loop.
-*/
- debug(F101, "coninc(timo) n","",n);
- debug(F101, "coninc(timo) errno","",errno);
-#ifndef OXOS
-#ifdef SVORPOSIX
- if (n == -1 && errno == EINTR && conesc != 0) {
- conesc = 0;
- return(escchr); /* User entered escape character. */
- }
-#endif /* SVORPOSIX */
- if (n == 0 && errno > 0) { /* It's an error */
- return(-1);
- }
-#endif /* ! OXOS */
- return(n);
-}
-
-/* C O N G K S -- Console Get Keyboard Scancode */
-
-#ifndef congks
-/*
- This function needs to be filled in with the various system-dependent
- system calls used by SUNOS, NeXT OS, Xenix, Aviion, etc, to read a full
- keyboard scan code. Unfortunately there aren't any.
-*/
-int
-congks(timo) int timo; {
-
-#ifdef IKSD
- if (inserver && !local)
- return(ttinc(timo));
-#endif /* IKSD */
-
- return(coninc(timo));
-}
-#endif /* congks */
-
-#ifdef ATT7300
-
-/* A T T D I A L -- Dial up the remote system using internal modem
- * Purpose: to open and dial a number on the internal modem available on the
- * ATT7300 UNIX PC. Written by Joe Doupnik. Superceeds version written by
- * Richard E. Hill, Dickinson, TX. which employed dial(3c).
- * Uses information in <sys/phone.h> and our status int attmodem.
- */
-attdial(ttname,speed,telnbr) char *ttname,*telnbr; long speed; {
- char *telnum;
-
- attmodem &= ~ISMODEM; /* modem not in use yet */
- /* Ensure O_NDELAY is set, else i/o traffic hangs */
- /* We turn this flag off once the dial is complete */
- fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) | O_NDELAY);
-
- /* Condition line, check availability & DATA mode, turn on speaker */
- if (ioctl(ttyfd,PIOCOFFHOOK, &dialer) == -1) {
- printf("cannot access phone\n");
- ttclos(0);
- return (-2);
- }
- ioctl(ttyfd,PIOCGETP,&dialer); /* get phone dialer parameters */
-
- if (dialer.c_lineparam & VOICE) { /* phone must be in DATA mode */
- printf(" Should not dial with modem in VOICE mode.\n");
- printf(" Exit Kermit, switch to DATA and retry call.\n");
- ttclos(0);
- return (-2);
- }
-#ifdef ATTTONED /* Old way, tone dialing only. */
- dialer.c_lineparam = DATA | DTMF; /* Dial with tones, */
- dialer.c_lineparam &= ~PULSE; /* not with pulses. */
-#else
- /* Leave current pulse/tone state alone. */
- /* But what about DATA? Add it back if you have trouble. */
- /* sys/phone says you get DATA automatically by opening device RDWR */
-#endif
- dialer.c_waitdialtone = 5; /* wait 5 sec for dialtone */
-#ifdef COMMENT
- dialer.c_feedback = SPEAKERON|NORMSPK|RINGON; /* control speaker */
-#else
- /* sys/phone says RINGON used only for incoming voice calls */
- dialer.c_feedback &= ~(SOFTSPK|LOUDSPK);
- dialer.c_feedback |= SPEAKERON|NORMSPK;
-#endif
- dialer.c_waitflash = 500; /* 0.5 sec flash hook */
- if(ioctl(ttyfd,PIOCSETP,&dialer) == -1) { /* set phone parameters */
- printf("Cannot set modem characteristics\n");
- ttclos(0);
- return (-2);
- }
- ioctl(ttyfd,PIOCRECONN,0); /* Turns on speaker for pulse */
-
-#ifdef COMMENT
- fprintf(stderr,"Phone line status. line_par:%o dialtone_wait:%o \
-line_status:%o feedback:%o\n",
- dialer.c_lineparam, dialer.c_waitdialtone,
- dialer.c_linestatus, dialer.c_feedback);
-#endif
-
- attmodem |= ISMODEM; /* modem is now in-use */
- sleep(1);
- for (telnum = telnbr; *telnum != '\0'; telnum++) /* dial number */
-#ifdef ATTTONED
- /* Tone dialing only */
- if (ioctl(ttyfd,PIOCDIAL,telnum) != 0) {
- perror("Error in dialing");
- ttclos(0);
- return(-2);
- }
-#else /* Allow Pulse or Tone dialing */
- switch (*telnum) {
- case 't': case 'T': case '%': /* Tone dialing requested */
- dialer.c_lineparam |= DTMF;
- dialer.c_lineparam &= ~PULSE;
- if (ioctl(ttyfd,PIOCSETP,&dialer) == -1) {
- printf("Cannot set modem to tone dialing\n");
- ttclos(0);
- return(-2);
- }
- break;
- case 'd': case 'D': case 'p': case 'P': case '^':
- dialer.c_lineparam |= PULSE;
- dialer.c_lineparam &= ~DTMF;
- if (ioctl(ttyfd,PIOCSETP,&dialer) == -1) {
- printf("Cannot set modem to pulse dialing\n");
- ttclos(0);
- return(-2);
- }
- break;
- default:
- if (ioctl(ttyfd,PIOCDIAL,telnum) != 0) {
- perror("Dialing error");
- ttclos(0);
- return(-2);
- }
- break;
- }
-#endif
-
- ioctl(ttyfd,PIOCDIAL,"@"); /* terminator for data call */
- do { /* wait for modems to Connect */
- if (ioctl(ttyfd,PIOCGETP,&dialer) != 0) { /* get params */
- perror("Cannot get modems to connect");
- ttclos(0);
- return(-2);
- }
- } while ((dialer.c_linestatus & MODEMCONNECTED) == 0);
- /* Turn off O_NDELAY flag now. */
- fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY);
- signal(SIGHUP, sighup); /* hangup on loss of carrier */
- return(0); /* return success */
-}
-
-/*
- Offgetty, ongetty functions. These function get the 'getty(1m)' off
- and restore it to the indicated line. Shell's return codes are:
- 0: Can't do it. Probably a user logged on.
- 1: No need. No getty on that line.
- 2: Done, you should restore the getty when you're done.
- DOGETY System(3), however, returns them as 0, 256, 512, respectively.
- Thanks to Kevin O'Gorman, Anarm Software Systems.
-
- getoff.sh looks like: geton.sh looks like:
- setgetty $1 0 setgetty $1 1
- err=$? exit $?
- sleep 2
- exit $err
-*/
-
-/* O F F G E T T Y -- Turn off getty(1m) for the communications tty line
- * and get status so it can be restarted after the line is hung up.
- */
-int
-offgetty(ttname) char *ttname; {
- char temp[30];
- while (*ttname != '\0') ttname++; /* seek terminator of path */
- ttname -= 3; /* get last 3 chars of name */
- sprintf(temp,"/usr/bin/getoff.sh %s",ttname);
- return(zsyscmd(temp));
-}
-
-/* O N G E T T Y -- Turn on getty(1m) for the communications tty line */
-
-int
-ongetty(ttname) char *ttname; {
- char temp[30];
- while (*ttname != '\0') ttname++; /* comms tty path name */
- ttname -= 3;
- sprintf(temp,"/usr/bin/geton.sh %s",ttname);
- return(zsyscmd(temp));
-}
-#endif /* ATT7300 */
-
-/* T T S C A R R -- Set ttcarr variable, controlling carrier handling.
- *
- * 0 = Off: Always ignore carrier. E.g. you can connect without carrier.
- * 1 = On: Heed carrier, except during dialing. Carrier loss gives disconnect.
- * 2 = Auto: For "modem direct": The same as "Off".
- * For real modem types: Heed carrier during connect, but ignore
- * it anytime else. Compatible with pre-5A C-Kermit versions.
- *
- * As you can see, this setting does not affect dialing, which always ignores
- * carrier (unless there is some special exception for some modem type). It
- * does affect ttopen() if it is set before ttopen() is used. This setting
- * takes effect on the next call to ttopen()/ttpkt()/ttvt(). And they are
- * (or should be) always called before any communications is tried, which
- * means that, practically speaking, the effect is immediate.
- *
- * Of course, nothing of this applies to remote mode (xlocal = 0).
- *
- * Someone has yet to uncover how to manipulate the carrier in the BSD
- * environment (or any non-termio using environment). Until that time, this
- * will simply be a no-op for BSD.
- *
- * Note that in previous versions, the carrier was most often left unchanged
- * in ttpkt()/ttvt() unless they were called with FLO_DIAL or FLO_DIAX. This
- * has changed. Now it is controlled by ttcarr in conjunction with these
- * modes.
- */
-int
-ttscarr(carrier) int carrier; {
- ttcarr = carrier;
- debug(F101, "ttscarr","",ttcarr);
- return(ttcarr);
-}
-
-/* C A R R C T L -- Set tty modes for carrier treatment.
- *
- * Sets the appropriate bits in a termio or sgttyb struct for carrier control
- * (actually, there are no bits in sgttyb for that), or performs any other
- * operations needed to control this on the current system. The function does
- * not do the actual TCSETA or stty, since often we want to set other bits too
- * first. Don't call this function when xlocal is 0, or the tty is not opened.
- *
- * We don't know how to do anything like carrier control on non-ATTSV systems,
- * except, apparently, ultrix. See above. It is also known that this doesn't
- * have much effect on a Xenix system. For Xenix, one should switch back and
- * forth between the upper and lower case device files. Maybe later.
- * Presently, Xenix will stick to the mode it was opened with.
- *
- * carrier: 0 = ignore carrier, 1 = require carrier.
- * The current state is saved in curcarr, and checked to save labour.
- */
-#ifdef SVORPOSIX
-int
-#ifdef BSD44ORPOSIX
-carrctl(ttpar, carrier) struct termios *ttpar; int carrier;
-#else /* ATTSV */
-carrctl(ttpar, carrier) struct termio *ttpar; int carrier;
-#endif /* BSD44ORPOSIX */
-/* carrctl */ {
- debug(F101, "carrctl","",carrier);
- if (carrier)
- ttpar->c_cflag &= ~CLOCAL;
- else
- ttpar->c_cflag |= CLOCAL;
- return(0);
-}
-#else /* Berkeley, V7, et al... */
-int
-carrctl(ttpar, carrier) struct sgttyb *ttpar; int carrier; {
- debug(F101, "carrctl","",carrier);
- if (carrier == curcarr)
- return(0);
- curcarr = carrier;
-#ifdef ultrix
-#ifdef COMMENT
-/*
- Old code from somebody at DEC that tends to get stuck, time out, etc.
-*/
- if (carrier) {
- ioctl(ttyfd, TIOCMODEM, &temp);
- ioctl(ttyfd, TIOCHPCL, 0);
- } else {
- /* (According to the manuals, TIOCNCAR should be preferred */
- /* over TIOCNMODEM...) */
- ioctl(ttyfd, TIOCNMODEM, &temp);
- }
-#else
-/*
- New code from Jamie Watson that, he says, eliminates the problems.
-*/
- if (carrier) {
- ioctl(ttyfd, TIOCCAR);
- ioctl(ttyfd, TIOCHPCL);
- } else {
- ioctl(ttyfd, TIOCNCAR);
- }
-#endif /* COMMENT */
-#endif /* ultrix */
- return(0);
-}
-#endif /* SVORPOSIX */
-
-
-/* T T G M D M -- Get modem signals */
-/*
- Looks for RS-232 modem signals, and returns those that are on in as its
- return value, in a bit mask composed of the BM_xxx values defined in ckcdeb.h.
- Returns:
- -3 Not implemented
- -2 if the communication device does not have modem control (e.g. telnet)
- -1 on error.
- >= 0 on success, with a bit mask containing the modem signals that are on.
-*/
-
-/*
- Define the symbol K_MDMCTL if we have Sys V R3 / 4.3 BSD style
- modem control, namely the TIOCMGET ioctl.
-*/
-
-#ifdef BSD43
-#define K_MDMCTL
-#endif /* BSD43 */
-
-#ifdef SUNOS4
-#define K_MDMCTL
-#endif /* SUNOS4 */
-
-/*
- SCO OpenServer R5.0.4. The TIOCMGET definition is hardwired in because it
- is skipped in termio.h when _POSIX_SOURCE is defined. But _POSIX_SOURCE
- must be defined in order to get the high serial speeds that are new to
- 5.0.4. However, the regular SCO drivers do not implement TIOCMGET, so the
- ioctl() returns -1 with errno 22 (invalid function). But third-party
- drivers, e.g. for Digiboard, do implement it, and so it should work on ports
- driven by those drivers.
-*/
-#ifdef SCO_OSR504
-#ifndef TIOCMGET
-#define TIOCMGET (('t'<<8)|29)
-#endif /* TIOCMGET */
-#endif /* SCO_OSR504 */
-
-#ifdef CK_SCOV5
-/* Because POSIX strictness in <sys/termio.h> won't let us see these. */
-#ifndef TIOCM_DTR
-#define TIOCM_DTR 0x0002 /* data terminal ready */
-#define TIOCM_RTS 0x0004 /* request to send */
-#define TIOCM_CTS 0x0020 /* clear to send */
-#define TIOCM_CAR 0x0040 /* carrier detect */
-#define TIOCM_RNG 0x0080 /* ring */
-#define TIOCM_DSR 0x0100 /* data set ready */
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#endif /* TIOCM_DTR */
-#endif /* CK_SCOV5 */
-
-#ifdef QNX
-#define K_MDMCTL
-#else
-#ifdef TIOCMGET
-#define K_MDMCTL
-#endif /* TIOCMGET */
-#endif /* QNX */
-/*
- "A serial communication program that can't read modem signals
- is like a car without windows."
-*/
-int
-ttgmdm() {
-
-#ifdef QNX
-#include <sys/qioctl.h>
-
- unsigned long y, mdmbits[2];
- int x, z = 0;
-
- if (xlocal && ttyfd < 0)
- return(-1);
-
-#ifdef NETCONN
- if (netconn) { /* Network connection */
-#ifdef TN_COMPORT
- if (istncomport()) {
- gotsigs = 1;
- return(tngmdm());
- } else
-#endif /* TN_COMPORT */
- return(-2); /* No modem signals */
- }
-#endif /* NETCONN */
-
-#ifdef NETCMD
- if (ttpipe) return(-2);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(-2);
-#endif /* NETPTY */
-
- mdmbits[0] = 0L;
- mdmbits[1] = 0L;
-/*
- * From <sys/qioctl.h>:
- *
- * SERIAL devices (all Dev.ser versions)
- * 0 : DTR 8 = Data Bits 0 16 - reserved 24 - reserved
- * 1 : RTS 9 = Data Bits 1 17 - reserved 25 - reserved
- * 2 = Out 1 10 = Stop Bits 18 - reserved 26 - reserved
- * 3 = Int Enable 11 = Par Enable 19 - reserved 27 - reserved
- * 4 = Loop 12 = Par Even 20 = CTS 28 - reserved
- * 5 - reserved 13 = Par Stick 21 = DSR 29 - reserved
- * 6 - reserved 14 : Break 22 = RI 30 - reserved
- * 7 - reserved 15 = 0 23 = CD 31 - reserved
- */
- errno = 0;
- x = qnx_ioctl(ttyfd, QCTL_DEV_CTL, &mdmbits[0], 8, &mdmbits[0], 4);
- debug(F101,"ttgmdm qnx_ioctl","",x);
- debug(F101,"ttgmdm qnx_ioctl errno","",errno);
- if (!x) {
- debug(F101,"ttgmdm qnx_ioctl mdmbits[0]","",mdmbits[0]);
- debug(F101,"ttgmdm qnx_ioctl mdmbits[1]","",mdmbits[1]);
- y = mdmbits[0];
- if (y & 0x000001L) z |= BM_DTR; /* Bit 0 */
- if (y & 0x000002L) z |= BM_RTS; /* Bit 1 */
- if (y & 0x100000L) z |= BM_CTS; /* Bit 20 */
- if (y & 0x200000L) z |= BM_DSR; /* Bit 21 */
- if (y & 0x400000L) z |= BM_RNG; /* Bit 22 */
- if (y & 0x800000L) z |= BM_DCD; /* Bit 23 */
- debug(F101,"ttgmdm qnx result","",z);
- debug(F110,"ttgmdm qnx CD = ",(z & BM_DCD) ? "On" : "Off", 0);
- gotsigs = 1;
- return(z);
- } else return(-1);
-#else /* QNX */
-#ifdef HPUX /* HPUX has its own way */
- int x, z;
-
-#ifdef HPUX10 /* Modem flag word */
- mflag y; /* mflag typedef'd in <sys/modem.h> */
-#else
-#ifdef HPUX9
- mflag y;
-#else
-#ifdef HPUX8
- mflag y;
-#else
- unsigned long y; /* Not sure about pre-8.0... */
-#endif /* HPUX8 */
-#endif /* HPUX9 */
-#endif /* HPUX10 */
-
- if (xlocal && ttyfd < 0)
- return(-1);
-
-#ifdef NETCONN
- if (netconn) { /* Network connection */
-#ifdef TN_COMPORT
- if (istncomport()) {
- gotsigs = 1;
- return(tngmdm());
- } else
-#endif /* TN_COMPORT */
- return(-2); /* No modem signals */
- }
-#endif /* NETCONN */
-
-#ifdef NETCMD
- if (ttpipe) return(-2);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(-2);
-#endif /* NETPTY */
-
- if (xlocal) /* Get modem signals */
- x = ioctl(ttyfd,MCGETA,&y);
- else
- x = ioctl(0,MCGETA,&y);
- if (x < 0) return(-1);
- debug(F101,"ttgmdm","",y);
-
- z = 0; /* Initialize return value */
-
-/* Now set bits for each modem signal that is reported to be on. */
-
-#ifdef MCTS
- /* Clear To Send */
- debug(F101,"ttgmdm HPUX CTS","",y & MCTS);
- if (y & MCTS) z |= BM_CTS;
-#endif
-#ifdef MDSR
- /* Data Set Ready */
- debug(F101,"ttgmdm HPUX DSR","",y & MDSR);
- if (y & MDSR) z |= BM_DSR;
-#endif
-#ifdef MDCD
- /* Carrier */
- debug(F101,"ttgmdm HPUX DCD","",y & MDCD);
- if (y & MDCD) z |= BM_DCD;
-#endif
-#ifdef MRI
- /* Ring Indicate */
- debug(F101,"ttgmdm HPUX RI","",y & MRI);
- if (y & MRI) z |= BM_RNG;
-#endif
-#ifdef MDTR
- /* Data Terminal Ready */
- debug(F101,"ttgmdm HPUX DTR","",y & MDTR);
- if (y & MDTR) z |= BM_DTR;
-#endif
-#ifdef MRTS
- /* Request To Send */
- debug(F101,"ttgmdm HPUX RTS","",y & MRTS);
- if (y & MRTS) z |= BM_RTS;
-#endif
- gotsigs = 1;
- return(z);
-
-#else /* ! HPUX */
-
-#ifdef K_MDMCTL
-/*
- Note, TIOCMGET might already have been defined in <sys/ioctl.h> or elsewhere.
- If not, we try including <sys/ttycom.h> -- if this blows up then more ifdefs
- are needed.
-*/
-#ifndef TIOCMGET
-#include <sys/ttycom.h>
-#endif /* TIOCMGET */
-
- int x, y, z;
-
- debug(F100,"ttgmdm K_MDMCTL defined","",0);
-
-#ifdef NETCONN
- if (netconn) { /* Network connection */
-#ifdef TN_COMPORT
- if (istncomport()) {
- gotsigs = 1;
- return(tngmdm());
- } else
-#endif /* TN_COMPORT */
- return(-2); /* No modem signals */
- }
-#endif /* NETCONN */
-
-#ifdef NETCMD
- if (ttpipe) return(-2);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(-2);
-#endif /* NETPTY */
-
- if (xlocal && ttyfd < 0)
- return(-1);
-
- if (xlocal)
- x = ioctl(ttyfd,TIOCMGET,&y); /* Get modem signals. */
- else
- x = ioctl(0,TIOCMGET,&y);
- debug(F101,"ttgmdm TIOCMGET ioctl","",x);
- if (x < 0) {
- debug(F101,"ttgmdm errno","",errno);
- return(-1);
- }
- debug(F101,"ttgmdm bits","",y);
-
- z = 0; /* Initialize return value. */
-#ifdef TIOCM_CTS
- /* Clear To Send */
- if (y & TIOCM_CTS) z |= BM_CTS;
- debug(F101,"ttgmdm TIOCM_CTS defined","",TIOCM_CTS);
-#else
- debug(F100,"ttgmdm TIOCM_CTS not defined","",0);
-#endif
-#ifdef TIOCM_DSR
- /* Data Set Ready */
- if (y & TIOCM_DSR) z |= BM_DSR;
- debug(F101,"ttgmdm TIOCM_DSR defined","",TIOCM_DSR);
-#else
- debug(F100,"ttgmdm TIOCM_DSR not defined","",0);
-#endif
-#ifdef TIOCM_CAR
- /* Carrier */
- if (y & TIOCM_CAR) z |= BM_DCD;
- debug(F101,"ttgmdm TIOCM_CAR defined","",TIOCM_CAR);
-#else
- debug(F100,"ttgmdm TIOCM_CAR not defined","",0);
-#endif
-#ifdef TIOCM_RNG
- /* Ring Indicate */
- if (y & TIOCM_RNG) z |= BM_RNG;
- debug(F101,"ttgmdm TIOCM_RNG defined","",TIOCM_RNG);
-#else
- debug(F100,"ttgmdm TIOCM_RNG not defined","",0);
-#endif
-#ifdef TIOCM_DTR
- /* Data Terminal Ready */
- if (y & TIOCM_DTR) z |= BM_DTR;
- debug(F101,"ttgmdm TIOCM_DTR defined","",TIOCM_DTR);
-#else
- debug(F100,"ttgmdm TIOCM_DTR not defined","",0);
-#endif
-#ifdef TIOCM_RTS
- /* Request To Send */
- if (y & TIOCM_RTS) z |= BM_RTS;
- debug(F101,"ttgmdm TIOCM_RTS defined","",TIOCM_RTS);
-#else
- debug(F100,"ttgmdm TIOCM_RTS not defined","",0);
-#endif
- gotsigs = 1;
- return(z);
-
-#else /* !K_MDMCTL catch-All */
-
- debug(F100,"ttgmdm K_MDMCTL not defined","",0);
-#ifdef TIOCMGET
- debug(F100,"ttgmdm TIOCMGET defined","",0);
-#else
- debug(F100,"ttgmdm TIOCMGET not defined","",0);
-#endif /* TIOCMGET */
-#ifdef _SVID3
- debug(F100,"ttgmdm _SVID3 defined","",0);
-#else
- debug(F100,"ttgmdm _SVID3 not defined","",0);
-#endif /* _SVID3 */
-
-#ifdef NETCONN
- if (netconn) { /* Network connection */
-#ifdef TN_COMPORT
- if (istncomport()) {
- gotsigs = 1;
- return(tngmdm());
- } else
-#endif /* TN_COMPORT */
- return(-2); /* No modem signals */
- }
-#endif /* NETCONN */
-
-#ifdef NETCMD
- if (ttpipe) return(-2);
-#endif /* NETCMD */
-#ifdef NETPTY
- if (ttpty) return(-2);
-#endif /* NETPTY */
-
- return(-3); /* Sorry, I don't know how... */
-
-#endif /* K_MDMCTL */
-#endif /* HPUX */
-#endif /* QNX */
-}
-
-/* P S U S P E N D -- Put this process in the background. */
-
-/*
- Call with flag nonzero if suspending is allowed, zero if not allowed.
- Returns 0 on apparent success, -1 on failure (flag was zero, or
- kill() returned an error code.
-*/
-int
-psuspend(flag) int flag; {
-
-#ifdef RTU
- extern int rtu_bug;
-#endif /* RTU */
-
- if (flag == 0) return(-1);
-
-#ifdef NOJC
- return(-1);
-#else
-#ifdef SIGTSTP
-/*
- The big question here is whether job control is *really* supported.
- There's no way Kermit can know for sure. The fact that SIGTSTP is
- defined does not guarantee the Unix kernel supports it, and the fact
- that the Unix kernel supports it doesn't guarantee that the user's
- shell (or other process that invoked Kermit) supports it.
-*/
-#ifdef RTU
- rtu_bug = 1;
-#endif /* RTU */
- if (kill(0,SIGSTOP) < 0
-#ifdef MIPS
-/* Let's try this for MIPS too. */
- && kill(getpid(),SIGSTOP) < 0
-#endif /* MIPS */
- ) { /* If job control, suspend the job */
- perror("suspend");
- debug(F101,"psuspend error","",errno);
- return(-1);
- }
- debug(F100,"psuspend ok","",0);
- return(0);
-#else
- return(-1);
-#endif /* SIGTSTP */
-#endif /* NOJC */
-}
-
-/*
- setuid package, by Kristoffer Eriksson, with contributions from Dean
- Long and fdc.
-*/
-
-/* The following is for SCO when CK_ANSILIBS is defined... */
-#ifdef M_UNIX
-#ifdef CK_ANSILIBS
-#ifndef NOGETID_PROTOS
-#define NOGETID_PROTOS
-#endif /* NOGETID_PROTOS */
-#endif /* CK_ANSILIBS */
-#endif /* M_UNIX */
-
-#ifndef _POSIX_SOURCE
-#ifndef SUNOS4
-#ifndef NEXT
-#ifndef PS2AIX10
-#ifndef sequent
-#ifndef HPUX9
-#ifndef HPUX10
-#ifndef COHERENT
-#ifndef NOGETID_PROTOS
-_PROTOTYP( UID_T getuid, (void) );
-_PROTOTYP( UID_T geteuid, (void) );
-_PROTOTYP( UID_T getreuid, (void) );
-_PROTOTYP( UID_T getgid, (void) );
-_PROTOTYP( UID_T getegid, (void) );
-_PROTOTYP( UID_T getregid, (void) );
-#endif /* NOGETID_PROTOS */
-#else
-_PROTOTYP( UID_T getreuid, (void) );
-_PROTOTYP( UID_T getregid, (void) );
-#endif /* COHERENT */
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* sequent */
-#endif /* PS2AIX10 */
-#endif /* NEXT */
-#endif /* SUNOS4 */
-#endif /* _POSIX_SOURCE */
-
-/*
-Subject: Set-user-id
-To: fdc@watsun.cc.columbia.edu (Frank da Cruz)
-Date: Sat, 21 Apr 90 4:48:25 MES
-From: Kristoffer Eriksson <ske@pkmab.se>
-
-This is a set of functions to be used in programs that may be run set-user-id
-and/or set-group-id. They handle both the case where the program is not run
-with such privileges (nothing special happens then), and the case where one
-or both of these set-id modes are used. The program is made to run with the
-user's real user and group ids most of the time, except for when more
-privileges are needed. Don't set-user-id to "root".
-
-This works on System V and POSIX. In BSD, it depends on the
-"saved-set-user-id" feature.
-*/
-
-#define UID_ROOT 0 /* Root user and group ids */
-#define GID_ROOT 0
-
-/*
- The following code defines the symbol SETEUID for UNIX systems based
- on BSD4.4 (either -Encumbered or -Lite). This program will then use
- seteuid() and setegid() instead of setuid() and setgid(), which still
- don't allow arbitrary switching. It also avoids setreuid() and
- setregid(), which are included in BSD4.4 for compatibility only, are
- insecure, and print warnings to stderr under at least one system (NetBSD
- 1.0). Note that POSIX systems should still use setuid() and setgid();
- the seteuid() and setegid() functions are BSD4.4 extensions to the
- POSIX model. Mike Long <mike.long@analog.com>, 8/94.
-*/
-#ifdef BSD44
-#define SETEUID
-#endif /* BSD44 */
-
-/*
- The following construction automatically defines the symbol SETREUID for
- UNIX versions based on Berkeley Unix 4.2 and 4.3. If this symbol is
- defined, then this program will use getreuid() and getregid() calls in
- preference to getuid() and getgid(), which in Berkeley-based Unixes do
- not allow arbitrary switching back and forth of real & effective uid.
- This construction also allows -DSETREUID to be put on the cc command line
- for any system that has and wants to use setre[ug]id(). It also prevents
- automatic definition of SETREUID if -DNOSETREU is included on the cc
- command line (or otherwise defined).
-*/
-#ifdef FT18 /* None of this for Fortune. */
-#define NOSETREU
-#endif /* FT18 */
-
-#ifdef ANYBSD
-#ifndef BSD29
-#ifndef BSD41
-#ifndef SETREUID
-#ifndef NOSETREU
-#ifndef SETEUID
-#define SETREUID
-#endif /* SETEUID */
-#endif /* NOSETREU */
-#endif /* SETREUID */
-#endif /* !BSD41 */
-#endif /* !BSD29 */
-#endif /* ANYBSD */
-
-/* Variables for user and group IDs. */
-
-static UID_T realuid = (UID_T) -1, privuid = (UID_T) -1;
-static GID_T realgid = (GID_T) -1, privgid = (GID_T) -1;
-
-
-/* P R I V _ I N I -- Initialize privileges package */
-
-/* Called as early as possible in a set-uid or set-gid program to store the
- * set-to uid and/or gid and step down to the users real uid and gid. The
- * stored id's can be temporarily restored (allowed in System V) during
- * operations that require the privilege. Most of the time, the program
- * should execute in unpriviliged state, to not impose any security threat.
- *
- * Note: Don't forget that access() always uses the real id:s to determine
- * file access, even with privileges restored.
- *
- * Returns an error mask, with error values or:ed together:
- * 1 if setuid() fails,
- * 2 if setgid() fails, and
- * 4 if the program is set-user-id to "root", which can't be handled.
- *
- * Only the return value 0 indicates real success. In case of failure,
- * those privileges that could be reduced have been, at least, but the
- * program should be aborted none-the-less.
- *
- * Also note that these functions do not expect the uid or gid to change
- * without their knowing. It may work if it is only done temporarily, but
- * you're on your own.
- */
-int
-priv_ini() {
- int err = 0;
-
-#ifndef HAVE_LOCKDEV
-
- /* Save real ID:s. */
- realuid = getuid();
- realgid = getgid();
-
- /* Save current effective ID:s, those set to at program exec. */
- privuid = geteuid();
- privgid = getegid();
-
- /* If running set-uid, go down to real uid, otherwise remember that
- * no privileged uid is available.
- *
- * Exceptions:
- *
- * 1) If the real uid is already "root" and the set-uid uid (the
- * initial effective uid) is not "root", then we would have trouble
- * if we went "down" to "root" here, and then temporarily back to the
- * set-uid uid (not "root") and then again tried to become "root". I
- * think the "saved set-uid" is lost when changing uid from effective
- * uid "root", which changes all uid, not only the effective uid. But
- * in this situation, we can simply go to "root" and stay there all
- * the time. That should give sufficient privilege (understatement!),
- * and give the right uids for subprocesses.
- *
- * 2) If the set-uid (the initial effective uid) is "root", and we
- * change uid to the real uid, we can't change it back to "root" when
- * we need the privilege, for the same reason as in 1). Thus, we can't
- * handle programs that are set-user-id to "root" at all. The program
- * should be stopped. Use some other uid. "root" is probably too
- * privileged for such things, anyway. (The uid is reverted to the
- * real uid until termination.)
- *
- * These two exceptions have the effect that the "root" uid will never
- * be one of the two uids that are being switched between, which also
- * means we don't have to check for such cases in the switching
- * functions.
- *
- * Note that exception 1) is handled by these routines (by constantly
- * running with uid "root", while exception 2) is a serious error, and
- * is not provided for at all in the switching functions.
- */
- if (realuid == privuid)
- privuid = (UID_T) -1; /* Not running set-user-id. */
-
- /* If running set-gid, go down to real gid, otherwise remember that
- * no privileged gid is available.
- *
- * There are no exception like there is for the user id, since there
- * is no group id that is privileged in the manner of uid "root".
- * There could be equivalent problems for group changing if the
- * program sometimes ran with uid "root" and sometimes not, but
- * that is already avoided as explained above.
- *
- * Thus we can expect always to be able to switch to the "saved set-
- * gid" when we want, and back to the real gid again. You may also
- * draw the conclusion that set-gid provides for fewer hassles than
- * set-uid.
- */
-
-#ifdef SUIDDEBUG
- fprintf(stderr,"UID_ROOT=%d\n",UID_ROOT);
- fprintf(stderr,"realuid=%d\n",realuid);
- fprintf(stderr,"privuid=%d\n",privuid);
-#endif /* SUIDDEBUG */
-
- if (realgid == privgid) /* If not running set-user-id, */
- privgid = (GID_T) -1; /* remember it this way. */
-
- err = priv_off(); /* Turn off setuid privilege. */
-
- if (privuid == UID_ROOT) /* If setuid to root, */
- err |= 4; /* return this error. */
-
- if (realuid == UID_ROOT) { /* If real id is root, */
- privuid = (UID_T) -1; /* stay root at all times. */
-#ifdef ATT7300
- /* If Kermit installed SUID uucp and user is running as root */
- err &= ~1; /* System V R0 does not save UID */
-#endif /* ATT7300 */
- }
-#endif /* HAVE_LOCKDEV */
- return(err);
-}
-
-
-/* Macros for hiding the differences in UID/GID setting between various Unix
- * systems. These macros should always be called with both the privileged ID
- * and the non-privileged ID. The one in the second argument, will become the
- * effective ID. The one in the first argument will be retained for later
- * retrieval.
- */
-#ifdef SETREUID
-#ifdef SAVEDUID
-/* On BSD systems with the saved-UID feature, we just juggle the effective
- * UID back and forth, and leave the real UID at its true value. The kernel
- * allows switching to both the current real UID, the effective UID, and the
- * UID which the program is set-UID to. The saved set-UID always holds the
- * privileged UID for us, and the real UID will always be the non-privileged,
- * and we can freely choose one of them for the effective UID at any time.
- */
-#define switchuid(hidden,active) setreuid( (UID_T) -1, active)
-#define switchgid(hidden,active) setregid( (GID_T) -1, active)
-
-#else /* SETREUID,!SAVEDUID */
-
-/* On systems with setreXid() but without the saved-UID feature, notably
- * BSD 4.2, we swap the real and effective UIDs each time. It's
- * the effective UID that we are interested in, but we have to retain the
- * unused UID somewhere to enable us to restore it later, and we do this
- * in the real UID. The kernel only allows switching to either the current
- * real or the effective UID, unless you're "root".
- */
-#define switchuid(hidden,active) setreuid(hidden,active)
-#define switchgid(hidden,active) setregid(hidden,active)
-#endif
-
-#else /* !SETREUID, !SAVEDUID */
-
-#ifdef SETEUID
-/*
- BSD 4.4 works similarly to System V and POSIX (see below), but uses
- seteXid() instead of setXid() to change effective IDs. In addition, the
- seteXid() functions work the same for "root" as for other users.
-*/
-#define switchuid(hidden,active) seteuid(active)
-#define switchgid(hidden,active) setegid(active)
-
-#else /* !SETEUID */
-
-/* On System V and POSIX, the only thing we can change is the effective UID
- * (unless the current effective UID is "root", but initsuid() avoids that for
- * us). The kernel allows switching to the current real UID or to the saved
- * set-UID. These are always set to the non-privileged UID and the privileged
- * UID, respectively, and we only change the effective UID. This breaks if
- * the current effective UID is "root", though, because for "root" setuid/gid
- * becomes more powerful, which is why initsuid() treats "root" specially.
- * Note: That special treatment maybe could be ignored for BSD? Note: For
- * systems that don't fit any of these four cases, we simply can't support
- * set-UID.
- */
-#define switchuid(hidden,active) setuid(active)
-#define switchgid(hidden,active) setgid(active)
-
-#endif /* SETEUID */
-#endif /* SETREUID */
-
-
-/* P R I V _ O N -- Turn on the setuid and/or setgid */
-
-/* Go to the privileged uid (gid) that the program is set-user-id
- * (set-group-id) to, unless the program is running unprivileged.
- * If setuid() fails, return value will be 1. If getuid() fails it
- * will be 2. Return immediately after first failure, and the function
- * tries to restore any partial work done. Returns 0 on success.
- * Group id is changed first, since it is less serious than user id.
- */
-int
-priv_on() {
-#ifndef HAVE_LOCKDEV
- if (privgid != (GID_T) -1)
- if (switchgid(realgid,privgid))
- return(2);
-
- if (privuid != (UID_T) -1)
- if (switchuid(realuid,privuid)) {
- if (privgid != (GID_T) -1)
- switchgid(privgid,realgid);
- return(1);
- }
-#endif /* HAVE_LOCKDEV */
- return(0);
-}
-
-/* P R I V _ O F F -- Turn on the real uid and gid */
-
-/* Return to the unprivileged uid (gid) after an temporary visit to
- * privileged status, unless the program is running without set-user-id
- * (set-group-id). Returns 1 for failure in setuid() and 2 for failure
- * in setgid() or:ed together. The functions tries to return both uid
- * and gid to unprivileged state, regardless of errors. Returns 0 on
- * success.
- */
-int
-priv_off() {
- int err = 0;
-#ifndef HAVE_LOCKDEV
- if (privuid != (UID_T) -1)
- if (switchuid(privuid,realuid))
- err |= 1;
-
- if (privgid != (GID_T) -1)
- if (switchgid(privgid,realgid))
- err |= 2;
-#endif /* HAVE_LOCKDEV */
- return(err);
-}
-
-/* Turn off privilege permanently. No going back. This is necessary before
- * a fork() on BSD43 machines that don't save the setUID or setGID, because
- * we swap the real and effective ids, and we don't want to let the forked
- * process swap them again and get the privilege back. It will work on other
- * machines too, such that you can rely on its effect always being the same,
- * for instance, even when you're in priv_on() state when this is called.
- * (Well, that part about "permanent" is on System V only true if you follow
- * this with a call to exec(), but that's what we want it for anyway.)
- * Added by Dean Long -- dlong@midgard.ucsc.edu
- */
-int
-priv_can() {
-#ifndef HAVE_LOCKDEV
-#ifdef SETREUID
- int err = 0;
- if (privuid != (UID_T) -1)
- if (setreuid(realuid,realuid))
- err |= 1;
-
- if (privgid != (GID_T) -1)
- if (setregid(realgid,realgid))
- err |= 2;
-
- return(err);
-
-#else
-#ifdef SETEUID
- int err = 0;
- if (privuid != (UID_T) -1)
- if (setuid(realuid)) {
- debug(F101,"setuid failed","",errno);
- err |= 1;
- debug(F101,"ruid","",getuid());
- debug(F101,"euid","",geteuid());
- }
- debug(F101,"setuid","",realuid);
- if (privgid != (GID_T) -1)
- if (setgid(realgid)) {
- debug(F101,"setgid failed","",errno);
- err |= 2;
- debug(F101,"rgid","",getgid());
- debug(F101,"egid","",getegid());
- }
- debug(F101,"setgid","",realgid);
- return(err);
-#else
- /* Easy way of using setuid()/setgid() instead of setreuid()/setregid().*/
- return(priv_off());
-#endif /* SETEUID */
-#endif /* SETREUID */
-#else
- return(0);
-#endif /* HAVE_LOCKDEV */
-}
-
-/* P R I V _ O P N -- For opening protected files or devices. */
-
-int
-priv_opn(name, modes) char *name; int modes; {
- int x;
- priv_on(); /* Turn privileges on */
- debug(F111,"priv_opn",name,modes);
- errno = 0;
- x = open(name, modes); /* Try to open the device */
- debug(F101,"priv_opn result","",x);
- debug(F101,"priv_opn errno","",errno);
- priv_off(); /* Turn privileges off */
- return(x); /* Return open's return code */
-}
-
-/* P R I V _ C H K -- Check privileges. */
-
-/* Try to turn them off. If turning them off did not succeed, cancel them */
-
-int
-priv_chk() {
- int x, y = 0;
- x = priv_off(); /* Turn off privs. */
- if (x != 0 || getuid() == privuid || geteuid() == privuid)
- y = priv_can();
- if (x != 0 || getgid() == privgid || getegid() == privgid)
- y = y | priv_can();
- return(y);
-}
-
-UID_T
-real_uid() {
- return(realuid);
-}
-
-VOID
-ttimoff() { /* Turn off any timer interrupts */
- /* int xx; */
-/*
- As of 5A(183), we set SIGALRM to SIG_IGN (to ignore alarms) rather than to
- SIG_DFL (to catch alarms, or if there is no handler, to exit). This is to
- cure (mask, really) a deeper problem with stray alarms that occurs on some
- systems, possibly having to do with sleep(), that caused core dumps. It
- should be OK to do this, because no code in this module uses nested alarms.
- (But we still have to watch out for SCRIPT and DIAL...)
-*/
- /* xx = */ alarm(0);
- /* debug(F101,"ttimoff alarm","",xx); */
- if (saval) { /* Restore any previous */
- signal(SIGALRM,saval); /* alarm handler. */
- /* debug(F101,"ttimoff alarm restoring saval","",saval); */
- saval = NULL;
- } else {
- signal(SIGALRM,SIG_IGN); /* Used to be SIG_DFL */
- /* debug(F100,"ttimoff alarm SIG_IGN","",0); */
- }
-}
-
-
-int
-tt_is_secure() { /* Tells whether the current connection is secure */
-
- if (ttyfd == -1)
- return(0);
-
- if (0
-#ifdef SSHBUILTIN
- || IS_SSH()
-#endif /* SSHBUILTIN */
-#ifdef CK_ENCRYPTION
- || ck_tn_encrypting() && ck_tn_decrypting()
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- || tls_active_flag || ssl_active_flag
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
-#ifdef CK_ENCRYPTION
- || ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_ENCRYPTION */
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
- )
- return(1);
- return(0);
-}
-
-#ifdef CK_REDIR
-
-/* External protocol handler parameters from ckuus3.c */
-extern int exp_handler, exp_stderr, exp_timo;
-
-#ifdef SELECT
-#ifdef NETPTY
-
-/* The right size is 24576 */
-
-#ifndef PTY_PBUF_SIZE /* Size of buffer to read from pty */
-#define PTY_PBUF_SIZE 24576 /* and write to net. */
-#endif /* PTY_PBUF_SIZE */
-
-#ifndef PTY_TBUF_SIZE /* Size of buffer to read from net */
-#define PTY_TBUF_SIZE 24576 /* and write to pty. */
-#endif /* PTY_TBUF_SIZE */
-
-#ifdef O_NDELAY /* Whether to use nonblocking */
-#ifndef PTY_NO_NDELAY /* reads on the pseudoterminal */
-#ifndef PTY_USE_NDELAY
-#define PTY_USE_NDELAY
-#endif /* PTY_USE_NDELAY */
-#endif /* PTY_NO_NDELAY */
-#endif /* O_NDELAY */
-
-#ifndef HAVE_OPENPTY
-#ifndef USE_CKUPTY_C
-#define USE_CKUPTY_C
-#endif /* USE_CKUPTY_C */
-#endif /* HAVE_OPENPTY */
-
-VOID
-pty_make_raw(fd) int fd; {
- int x = -23, i;
-
-#ifdef BSD44ORPOSIX /* POSIX */
- struct termios tp;
-#else
-#ifdef ATTSV /* AT&T UNIX */
-#ifdef CK_ANSIC
- struct termio tp = {0};
-#else
- struct termio tp;
-#endif /* CK_ANSIC */
-#else
- struct sgttyb tp; /* Traditional */
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
-
- debug(F101,"pty_make_raw fd","",fd);
- errno = 0;
-
-#ifdef BSD44ORPOSIX /* POSIX */
- x = tcgetattr(fd,&tp);
- debug(F101,"pty_make_raw tcgetattr","",x);
-#else
-#ifdef ATTSV /* AT&T UNIX */
- x = ioctl(fd,TCGETA,&tp);
- debug(F101,"pty_make_raw TCGETA ioctl","",x);
-#else
- x = gtty(fd,&tp);
- debug(F101,"pty_make_raw ttty","",x);
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
- debug(F101,"pty_make_raw GET errno","",errno);
-
-#ifdef USE_CFMAKERAW
- errno = 0;
- cfmakeraw(&tp);
- debug(F101,"pty_make_raw cfmakeraw errno","",errno);
-#else /* USE_CFMAKERAW */
-
-#ifdef COMMENT
-
-/* This very simple version recommended by Serg Iakolev doesn't work */
-
- tp.c_lflag &= ~(ECHO|ICANON|IEXTEN|ISIG);
- tp.c_iflag &= ~(BRKINT|ICRNL|INPCK|ISTRIP|IXON);
- tp.c_cflag &= ~(CSIZE|PARENB);
- tp.c_cflag |= CS8;
- tp.c_oflag &= ~(OPOST);
- tp.c_cc[VMIN] = 1;
- tp.c_cc[VTIME] = 0;
-
- debug(F101,"pty_make_raw 1 c_cc[] NCCS","",NCCS);
- debug(F101,"pty_make_raw 1 iflags","",tp.c_iflag);
- debug(F101,"pty_make_raw 1 oflags","",tp.c_oflag);
- debug(F101,"pty_make_raw 1 lflags","",tp.c_lflag);
- debug(F101,"pty_make_raw 1 cflags","",tp.c_cflag);
-
-#else
-#ifdef COMMENT
-/*
- In this version we unset everything and then set only the
- bits we know we need.
-*/
- /* iflags */
- tp.c_iflag = 0L;
- tp.c_iflag |= IGNBRK;
-#ifdef IMAXBEL
- tp.c_iflag |= IMAXBEL;
-#endif /* IMAXBEL */
-
- /* oflags */
- tp.c_oflag = 0L;
-
- /* lflags */
- tp.c_lflag = 0L;
-#ifdef NOKERNINFO
- tp.c_lflag |= NOKERNINFO;
-#endif /* NOKERNINFO */
-
- /* cflags */
- tp.c_cflag = 0L;
- tp.c_cflag |= CS8|CREAD;
-
- for (i = 0; i < NCCS; i++) { /* No special characters */
- tp.c_cc[i] = 0;
- }
-#ifdef VMIN
- tp.c_cc[VMIN] = 1; /* But always wait for input */
-#endif /* VMIN */
- debug(F101,"pty_make_raw 2 c_cc[] NCCS","",NCCS);
- debug(F101,"pty_make_raw 2 iflags","",tp.c_iflag);
- debug(F101,"pty_make_raw 2 oflags","",tp.c_oflag);
- debug(F101,"pty_make_raw 2 lflags","",tp.c_lflag);
- debug(F101,"pty_make_raw 2 cflags","",tp.c_cflag);
-
-#else /* COMMENT */
-/*
- In this version we set or unset every single flag explicitly. It works a
- bit better than the simple version just above, but it's still far from
- adequate.
-*/
- /* iflags */
- tp.c_iflag &= ~(PARMRK|ISTRIP|BRKINT|INLCR|IGNCR|ICRNL);
- tp.c_iflag &= ~(INPCK|IGNPAR|IXANY|IXON|IXOFF);
- tp.c_iflag |= IGNBRK;
-#ifdef IMAXBEL
-#ifdef COMMENT
- tp.c_iflag |= IMAXBEL;
-#else
- tp.c_iflag &= ~IMAXBEL;
-#endif /* COMMENT */
-#endif /* IMAXBEL */
-#ifdef IUCLC
- tp.c_iflag &= ~IUCLC;
-#endif /* IUCLC */
-
- /* oflags */
-#ifdef BSDLY
- tp.c_oflag &= ~BSDLY;
-#endif /* BSDLY */
-#ifdef CRDLY
- tp.c_oflag &= ~CRDLY;
-#endif /* CRDLY */
-#ifdef FFDLY
- tp.c_oflag &= ~FFDLY;
-#endif /* FFDLY */
-#ifdef NLDLY
- tp.c_oflag &= ~NLDLY;
-#endif /* NLDLY */
-#ifdef TABDLY
- tp.c_oflag &= ~TABDLY;
-#endif /* TABDLY */
-#ifdef VTDLY
- tp.c_oflag &= ~VTDLY;
-#endif /* VTDLY */
-#ifdef OFDEL
- tp.c_oflag &= ~OFDEL;
-#endif /* OFDEL */
-#ifdef OFILL
- tp.c_oflag &= ~OFILL;
-#endif /* OFILL */
-#ifdef OLCUC
- tp.c_oflag &= ~OLCUC;
-#endif /* OLCUC */
-#ifdef CMSPAR
- tp.c_oflag &= ~CMSPAR;
-#endif /* CMSPAR */
- tp.c_oflag &= ~OPOST;
-#ifdef OXTABS
- tp.c_oflag &= ~OXTABS;
-#endif /* OXTABS */
-#ifdef COMMENT
-#ifdef ONOCR
- tp.c_oflag &= ~ONOCR; /* Maybe should be |=? */
- tp.c_oflag |= ONOCR; /* makes no difference either way */
-#endif /* ONOCR */
-#endif /* COMMENT */
-#ifdef ONOEOT
- tp.c_oflag &= ~ONOEOT;
-#endif /* ONOEOT */
-#ifdef ONLRET
- tp.c_oflag &= ~ONLRET;
-#endif /* ONLRET */
-#ifdef ONLCR
- tp.c_oflag &= ~ONLCR;
-#endif /* ONLCR */
-#ifdef OCRNL
- tp.c_oflag &= ~OCRNL;
-#endif /* OCRNL */
-
- /* lflags */
- tp.c_lflag &= ~ECHO;
-#ifdef ECHOE
- tp.c_lflag &= ~ECHOE;
-#endif /* ECHOE */
-#ifdef ECHONL
- tp.c_lflag &= ~ECHONL;
-#endif /* ECHONL */
-#ifdef ECHOPRT
- tp.c_lflag &= ~ECHOPRT;
-#endif /* ECHOPRT */
-#ifdef ECHOKE
- tp.c_lflag &= ~ECHOKE;
-#endif /* ECHOKE */
-#ifdef ECHOCTL
- tp.c_lflag &= ~ECHOCTL;
-#endif /* ECHOCTL */
-#ifdef XCASE
- tp.c_lflag &= ~XCASE;
-#endif /* XCASE */
-#ifdef ALTWERASE
- tp.c_lflag &= ~ALTWERASE;
-#endif /* ALTWERASE */
-#ifdef EXTPROC
- tp.c_lflag &= ~(ICANON|ISIG|IEXTEN|TOSTOP|FLUSHO|PENDIN|EXTPROC);
-#else
- tp.c_lflag &= ~(ICANON|ISIG|IEXTEN|TOSTOP|FLUSHO|PENDIN);
-#endif /* EXTPROC */
-#ifdef NOKERNINFO
- tp.c_lflag |= NOKERNINFO;
-#endif /* NOKERNINFO */
-#ifndef COMMENT
- tp.c_lflag &= ~NOFLSH; /* TRY IT THE OTHER WAY? */
-#else
- tp.c_lflag |= NOFLSH; /* No, this way is worse */
-#endif /* COMMENT */
-
- /* cflags */
- tp.c_cflag &= ~(CSIZE|PARENB|PARODD);
- tp.c_cflag |= CS8|CREAD;
-
-#ifdef MDMBUF
- tp.c_cflag &= ~(MDMBUF);
-#else
-#ifdef CCAR_OFLOW
- tp.c_cflag &= ~(CCAR_OFLOW); /* two names for the same thing */
-#endif /* CCAR_OFLOW */
-#endif /* MDMBUF */
-
-#ifdef CCTS_OFLOW
- tp.c_cflag &= ~(CCTS_OFLOW);
-#endif /* CCTS_OFLOW */
-#ifdef CDSR_OFLOW
- tp.c_cflag &= ~(CDSR_OFLOW);
-#endif /* CDSR_OFLOW */
-#ifdef CDTR_IFLOW
- tp.c_cflag &= ~(CDTR_IFLOW);
-#endif /* CDTR_IFLOW */
-#ifdef CRTS_IFLOW
- tp.c_cflag &= ~(CRTS_IFLOW);
-#endif /* CRTS_IFLOW */
-#ifdef CRTSXOFF
- tp.c_cflag &= ~(CRTSXOFF);
-#endif /* CRTSXOFF */
-#ifdef CRTSCTS
- tp.c_cflag &= ~(CRTSCTS);
-#endif /* CRTSCTS */
-#ifdef CLOCAL
- tp.c_cflag &= ~(CLOCAL);
-#endif /* CLOCAL */
-#ifdef CSTOPB
- tp.c_cflag &= ~(CSTOPB);
-#endif /* CSTOPB */
-#ifdef HUPCL
- tp.c_cflag &= ~(HUPCL);
-#endif /* HUPCL */
-
- for (i = 0; i < NCCS; i++) { /* No special characters */
- tp.c_cc[i] = 0;
- }
-#ifdef VMIN
- tp.c_cc[VMIN] = 1; /* But always wait for input */
-#endif /* VMIN */
- debug(F101,"pty_make_raw 3 c_cc[] NCCS","",NCCS);
- debug(F101,"pty_make_raw 3 iflags","",tp.c_iflag);
- debug(F101,"pty_make_raw 3 oflags","",tp.c_oflag);
- debug(F101,"pty_make_raw 3 lflags","",tp.c_lflag);
- debug(F101,"pty_make_raw 3 cflags","",tp.c_cflag);
-#endif /* COMMENT */
-#endif /* COMMENT */
-
- errno = 0;
-#ifdef BSD44ORPOSIX /* POSIX */
- x = tcsetattr(fd,TCSANOW,&tp);
- debug(F101,"pty_make_raw tcsetattr","",x);
-#else
-#ifdef ATTSV /* AT&T UNIX */
- x = ioctl(fd,TCSETA,&tp);
- debug(F101,"pty_make_raw ioctl","",x);
-#else
- x = stty(fd,&tp); /* Traditional */
- debug(F101,"pty_make_raw stty","",x);
-#endif /* ATTSV */
-#endif /* BSD44ORPOSIX */
- debug(F101,"pty_make_raw errno","",errno);
-
-#endif /* __NetBSD__ */
-}
-
-static int
-pty_chk(fd) int fd; {
- int x, n = 0;
- errno = 0;
-#ifdef FIONREAD
- x = ioctl(fd, FIONREAD, &n); /* BSD and most others */
- ckmakmsg(msgbuf,500,
- "pty_chk ioctl FIONREAD errno=",
- ckitoa(errno),
- " count=",
- ckitoa(n));
- debug(F100,msgbuf,"",0);
-#else
-#ifdef RDCHK
- n = rdchk(fd);
- debug(F101,"pty_chk rdchk","",n);
-#else
- n = 1;
-#endif /* RDCHK */
-#endif /* FIONREAD */
- return((n > -1) ? n : 0);
-}
-
-static int
-pty_get_status(fd,pid) int fd; PID_T pid; {
- int x, status = -1;
- PID_T w;
-
- debug(F101,"pty_get_status fd","",fd);
- debug(F101,"pty_get_status pid","",pid);
-
- if (pexitstat > -1)
- return(pexitstat);
-
-#ifdef COMMENT
- /* Not only unnecessary but harmful */
- errno = 0;
- x = kill(pty_fork_pid,0);
- debug(F101,"pty_get_status kill value","",x);
- debug(F101,"pty_get_status kill errno","",errno);
- if (x > -1 && errno != ESRCH)
- return(-1); /* Fork still there */
- /* Fork seems to be gone */
-#endif /* COMMENT */
-
- errno = 0;
- x = waitpid(pty_fork_pid,&status,WNOHANG);
- debug(F111,"pty_get_status waitpid",ckitoa(errno),x);
- if (x <= 0 && errno == 0) {
- debug(F101,"pty_get_status waitpid return","",-1);
- return(-1);
- }
- if (x > 0) {
- if (x != pty_fork_pid)
- debug(F101,
- "pty_get_status waitpid pid doesn't match","",pty_fork_pid);
- debug(F101,"pty_get_status waitpid status","",status);
- debug(F101,"pty_get_status waitpid errno","",errno);
- if (WIFEXITED(status)) {
- debug(F100,"pty_get_status WIFEXITED","",0);
- status = WEXITSTATUS(status);
- debug(F101,"pty_get_status fork exit status","",status);
-#ifdef COMMENT
- end_pty();
-#endif /* COMMENT */
- close(fd);
- pexitstat = status;
- } else {
- debug(F100,"pty_get_status waitpid unexpected status","",0);
- }
- }
- debug(F101,"pty_get_status return status","",status);
- return(status);
-}
-
-/* t t p t y c m d -- Run command on pty and forward to net */
-
-/*
- Needed for running external protocols on secure connections.
- For example, if C-Kermit has made an SSL/TLS or Kerberos Telnet
- connection, and then needs to transfer a file with Zmodem, which is
- an external program, this routine reads Zmodem's output, encrypts it,
- and then forwards it out the connection, and reads the encrypted data
- stream coming in from the connection, decrypts it, and forwards it to
- Zmodem.
-
- Works like a TCP/IP port forwarder except one end is a pty rather
- than a socket, which introduces some complications:
-
- . On most platforms, select() always indicates the output side of
- the pty has characters waiting to be read, even when it doesn't,
- even when the pty process has already exited.
-
- . Nonblocking reads must be used on the pty, because there is no
- way on certain platforms (e.g. NetBSD) to find out how many characters
- are available to be read (the FIONREAD ioctl always says 0). The code
- also allows for blocking reads (if O_NDELAY and O_NONBLOCK are not
- defined, or if PTY_NO_NDELAY is defined), but on some platforms this can
- result in single-byte reads and writes (NetBSD again).
-
- . Testing for "EOF" on the pty is problematic. select() never gives
- any indication. After the pty process has exited and the fork has
- disappeared, read() can still return with 0 bytes read but without an
- error (NetBSD); no known test on the pty file descriptor will indicate
- that it is no longer valid. The process ID of the pty fork can be
- tested on some platforms (NetBSD, luckily) but not others (Solaris,
- Linux).
-
- On the network side, we use ttinc() and ttoc(), which, for network
- connections, handle any active security methods.
-
- Call with s = command.
- Returns 0 on failure, 1 on success.
- fdc - December 2006 - August 2007.
-
- NOTE: This code defaults to nonblocking reads if O_NDELAY or O_NONBLOCK are
- defined in the header files, which should be true of every recent Unix
- platform. If this causes trouble somewhere, define PTY_NO_NDELAY, e.g. when
- building C-Kermit:
-
- touch ckutio.c
- make platformname KFLAGS=-DPTY_NO_NODELAY
-*/
-static int have_pty = 0; /* Do we have a pty? */
-
-static SIGTYP (*save_sigchld)() = NULL; /* For catching SIGCHLD */
-
-static VOID
-sigchld_handler(sig) int sig; {
- have_pty = 0; /* We don't have a pty */
-#ifdef DEBUG
- if (save_sigchld) {
- (VOID) signal(SIGCHLD,save_sigchld);
- save_sigchld = NULL;
- }
- if (deblog) {
- debug(F100,"**************","",0);
- debug(F100,"SIGCHLD caught","",0);
- debug(F100,"**************","",0);
- }
-#endif /* DEBUG */
-}
-#define HAVE_IAC 1
-#define HAVE_CR 2
-
-int
-ttptycmd(s) char *s; {
- CHAR tbuf[PTY_TBUF_SIZE]; /* Read from net, write to pty */
- int tbuf_avail = 0; /* Pointers for tbuf */
- int tbuf_written = 0;
- static int in_state = 0; /* For TELNET IAC and NVT in */
- static int out_prev = 0; /* Simpler scheme for out */
-
- CHAR pbuf[PTY_PBUF_SIZE]; /* Read from pty, write to net */
- CHAR dbuf[PTY_PBUF_SIZE + PTY_PBUF_SIZE + 1]; /* Double-size buffer */
- int pbuf_avail = 0; /* Pointers for pbuf */
- int pbuf_written = 0;
-
- int ptyfd = -1; /* Pty file descriptor */
- int have_net = 0; /* We have a network connection */
- int pty_err = 0; /* Got error on pty */
- int net_err = 0; /* Got error on net */
- int status = -1; /* Pty process exit status */
- int rc = 0; /* Our return code */
-
- int x1 = 0, x2 = 0; /* Workers... */
- int c, n, m, t, x; /* Workers */
-
- long seconds_to_wait = 0L; /* select() timeout */
- struct timeval tv, *tv2; /* For select() */
-#ifdef INTSELECT
- int in, out, err; /* For select() */
-#else
- fd_set in, out, err;
-#endif /* INTSELECT */
- int nfds = 0; /* For select() */
-
- int pset = 0, tset = 0, pnotset = 0, tnotset = 0; /* stats/debuggin only */
- int read_net_bytes = 0; /* Stats */
- int write_net_bytes = 0; /* Stats */
- int read_pty_bytes = 0; /* Stats */
- int write_pty_bytes = 0; /* Stats */
- int is_tn = 0; /* TELNET protocol is active */
-
- int masterfd = -1;
- int slavefd = -1;
-#ifndef USE_CKUPTY_C
- struct termios term;
- struct winsize twin;
- struct stringarray * q;
- char ** args = NULL;
-#endif /* USE_CKUPTY_C */
-
- in_state = 0; /* No previous character yet */
-
- if (ttyfd == -1) {
- printf("?Sorry, communication channel is not open\n");
- return(0);
- } else {
- have_net = 1;
- }
- if (nopush) {
- debug(F100,"ttptycmd fail: nopush","",0);
- return(0);
- }
- if (!s) s = ""; /* Defense de bogus arguments */
- if (!*s) return(0);
- pexitstat = -1; /* Fork process exit status */
-
-#ifdef TNCODE
- is_tn = (xlocal && netconn && IS_TELNET()) || /* Telnet protocol active */
- (!xlocal && sstelnet);
-#endif /* TNCODE */
-
- debug(F110,"ttptycmd command",s,0);
- debug(F101,"ttptycmd ttyfd","",ttyfd);
- debug(F101,"ttptycmd is_tn","",is_tn);
- debug(F101,"ttptycmd ckermit pid","",getpid());
-
-#ifdef USE_CKUPTY_C
- /* Call ckupty.c module to get and set up the pty fork */
- /* fc 1 == "run an external protocol" */
- debug(F100,"ttptycmd using ckupty.c","",0);
- if (do_pty(&ptyfd,s,1) < 0) { /* Start the command on a pty */
- debug(F100,"ttptycmd do_pty fails","",0);
- return(0);
- }
- masterfd = ptyfd;
- pty_master_fd = ptyfd;
-#ifdef COMMENT
- slavefd = pty_slave_fd; /* This is not visible to us */
-#endif /* COMMENT */
- debug(F111,"ttptycmd ptyfd","USE_CKUPTY_C",ptyfd);
- debug(F111,"ttptycmd masterfd","USE_CKUPTY_C",masterfd);
- debug(F111,"ttptycmd fork pid","USE_CKUPTY_C",pty_fork_pid);
-#ifndef SOLARIS
- /* "ioctl inappropriate on device" for pty master */
- pty_make_raw(masterfd);
-#endif /* SOLARIS */
-
-#else /* USE_CKUPTY_C */
-
- debug(F100,"ttptycmd OPENPTY","",0);
- if (tcgetattr(0, &term) == -1) { /* Get controlling terminal's modes */
- perror("tcgetattr");
- return(0);
- }
- if (ioctl(0, TIOCGWINSZ, (char *) &twin) == -1) { /* and window size */
- perror("ioctl TIOCGWINSZ");
- return(0);
- }
- if (openpty(&masterfd, &slavefd, NULL, NULL, NULL) == -1) {
- debug(F101,"ttptycmd openpty failed errno","",errno);
- perror("opentpy");
- return(0);
- }
- debug(F101,"ttptycmd openpty masterfd","",masterfd);
- debug(F101,"ttptycmd openpty slavefd","",slavefd);
- pty_master_fd = masterfd;
- pty_slave_fd = slavefd;
- debug(F101,"ttptycmd openpty pty_master_fd","",pty_master_fd);
-
- /* Put pty master in raw mode but let forked app control the slave */
- pty_make_raw(masterfd);
-
-#ifdef COMMENT
-#ifdef TIOCREMOTE
- /* TIOCREMOTE,0 = disable all termio processing */
- x = ioctl(masterfd, TIOCREMOTE, 1);
- debug(F111,"ttptycmd ioctl TIOCREMOTE",ckitoa(x),errno);
-#endif /* TIOCREMOTE */
-#ifdef TIOCTTY
- /* TIOCTTY,0 = disable all termio processing */
- x = ioctl(masterfd, TIOCTTY, 0);
- debug(F111,"ttptycmd ioctl TIOCTTY",ckitoa(x),errno);
-#endif /* TIOCTTY */
-#endif /* COMMENT */
-
- have_pty = 1; /* We have an open pty */
- save_sigchld = signal(SIGCHLD, sigchld_handler); /* Catch fork quit */
-
- pty_fork_pid = fork(); /* Make fork for external protocol */
- debug(F101,"ttptycmd pty_fork_pid","",pty_fork_pid);
- if (pty_fork_pid == -1) {
- perror("fork");
- return(0);
- } else if (pty_fork_pid == 0) { /* In new fork */
- int x;
- debug(F101,"ttptycmd new fork pid","",getpid());
- close(masterfd); /* Slave quarters no masters allowed */
- x = setsid();
- debug(F101,"ttptycmd new fork setsid","",x);
- if (x == -1) {
- perror("ttptycmd setsid");
- exit(1);
- }
- signal(SIGINT,SIG_IGN); /* Let upper fork catch this */
-
-#ifdef COMMENT
-#ifdef TIOCSCTTY
- /* Make pty the controlling terminal for the process */
- /* THIS CAUSES AN INFINITE SIGWINCH INTERRUPT LOOP */
- x = ioctl(slavefd, TIOCSCTTY, NULL);
- debug(F101,"ttptycmd TIOCSCTTY","",x);
-#endif /* TIOCSCTTY */
-#endif /* COMMENT */
-
- /* Initialize slave pty modes and size to those of our terminal */
- if (tcsetattr(slavefd, TCSANOW, &term) == -1) {
- perror("ttptycmd tcsetattr");
- exit(1);
- }
- if (ioctl(slavefd, TIOCSWINSZ, &twin) == -1) {
- perror("ttptycmd ioctl");
- exit(1);
- }
-#ifdef COMMENT
-#ifdef TIOCNOTTY
- /* Disassociate this process from its terminal */
- /* THIS HAS NO EFFECT */
- x = ioctl(slavefd, TIOCNOTTY, NULL);
- debug(F101,"ttptycmd TIOCNOTTY","",x);
-#endif /* TIOCNOTTY */
-#endif /* COMMENT */
-
-#ifdef COMMENT
-#ifdef SIGTTOU
- /* Ignore terminal output interrupts */
- /* THIS HAS NO EFFECT */
- debug(F100,"ttptycmd ignoring SIGTTOU","",0);
- signal(SIGTTOU, SIG_IGN);
-#endif /* SIGTTOU */
-#ifdef SIGTSTP
- /* Ignore terminal output interrupts */
- /* THIS HAS NO EFFECT */
- debug(F100,"ttptycmd ignoring SIGTSTP","",0);
- signal(SIGTSTP, SIG_IGN);
-#endif /* SIGTSTP */
-#endif /* COMMENT */
-
- pty_make_raw(slavefd); /* Put it in rawmode */
-
- errno = 0;
- if (dup2(slavefd, STDIN_FILENO) != STDIN_FILENO ||
- dup2(slavefd, STDOUT_FILENO) != STDOUT_FILENO) {
- debug(F101,"ttptycmd new fork dup2 error","",errno);
- perror("ttptycmd dup2");
- exit(1);
- }
- debug(F100,"ttptycmd new fork dup2 ok","",0);
-
- /* Parse external protocol command line */
- q = cksplit(1,0,s,NULL,"\\%[]&$+-/=*^_@!{}/<>|.#~'`:;?",7,0,0);
- if (!q) {
- debug(F100,"ttptycmd cksplit failed","",0);
- exit(1);
- } else {
- int i, n;
- debug(F100,"ttptycmd cksplit ok","",0);
- n = q->a_size;
- args = q->a_head + 1;
- for (i = 0; i <= n; i++) {
- if (!args[i]) {
- break;
- } else {
- /* sometimes cksplit() doesn't terminate the list */
- if ((i == n) && args[i]) {
- if ((int)strlen(args[i]) == 0)
- makestr(&(args[i]),NULL);
- }
- }
- }
- }
-#ifdef COMMENT
-/*
- Putting the slave pty in rawmode should not be necessary because the
- external protocol program is supposed to do that itself. Yet doing this
- here cuts down on Zmodem binary-file transmission errors by 30-50% but
- still doesn't eliminate them.
-*/
- pty_make_raw(STDIN_FILENO);
- pty_make_raw(STDOUT_FILENO);
-#endif /* COMMENT */
-
- debug(F100,"ttptycmd execvp'ing external protocol","",0);
- execvp(args[0],args);
- perror("execvp failed");
- debug(F101,"ttptycmd execvp failed","",errno);
- close(slavefd);
- exit(1);
- }
- /* (there are better ways to do this...) */
- msleep(1000); /* Make parent wait for child to be ready */
- ptyfd = masterfd; /* We talk to the master */
-
-#endif /* USE_CKUPTY_C */
-
- debug(F101,"ttptycmd ptyfd","",ptyfd);
- if (ptyfd < 0) {
- printf("?Failure to get pty\n");
- return(-9);
- }
- have_pty = 1; /* We have an open pty or we wouldn't he here */
-
- debug(F101,"ttptycmd PTY_PBUF_SIZE","",PTY_PBUF_SIZE);
- debug(F101,"ttptycmd PTY_TBUF_SIZE","",PTY_TBUF_SIZE);
-
-#ifdef PTY_USE_NDELAY
- /*
- NOTE: If select() and ioctl(ptyfd,FIONREAD,&n) return true indications
- on the pty, we don't need nonblocking reads. Performance of either
- method seems to be about the same, so use whatever works.
- */
- errno = 0;
- x = fcntl(ptyfd,F_SETFL,fcntl(ptyfd,F_GETFL, 0)|O_NDELAY);
- ckmakmsg(msgbuf,500,
- "ttptycmd set O_NDELAY errno=",
- ckitoa(errno),
- " fcntl=",
- ckitoa(x));
- debug(F100,msgbuf,"",0);
-#endif /* PTY_USE_NDELAY */
-
-#ifdef COMMENT
-/* Not necessary, the protocol module already did this */
-
-#ifdef USE_CFMAKERAW
- if (tcgetattr(ttyfd, &term) > -1) {
- cfmakeraw(&term);
- debug(F101,"ttptycmd net cfmakeraw errno","",errno);
- x tcsetattr(ttyfd, TCSANOW, &term);
- debug(F101,"ttptycmd net tcsetattr","",x);
- debug(F101,"ttptycmd net tcsetattr","",errno);
- }
-#else
- if (local) /* Put network connection in */
- ttpkt(ttspeed,ttflow,ttprty); /* "packet mode". */
- else
- conbin((char)escchr); /* OR... pty_make_raw(0) */
-#endif /* USE_CFMAKERAW */
-#endif /* COMMENT */
-
-#ifdef TNCODE
- if (is_tn) {
- debug(F101,"<<< ttptycmd TELOPT_ME_BINARY","",TELOPT_ME(TELOPT_BINARY));
- debug(F101,"<<< ttptycmd TELOPT_U_BINARY","",TELOPT_U(TELOPT_BINARY));
- }
-#endif /* TNCODE */
-
- debug(F101,"ttptycmd entering loop - seconds_to_wait","",seconds_to_wait);
-
- while (have_pty || have_net) {
- FD_ZERO(&in); /* Initialize select() structs */
- FD_ZERO(&out);
- FD_ZERO(&err); /* (not used because useless) */
- nfds = -1;
-
- debug(F101,"ttptycmd loop top have_pty","",have_pty);
- debug(F101,"ttptycmd loop top have_net","",have_net);
-
- /* Pty is open and we have room to read from it? */
- if (have_pty && pbuf_avail < PTY_PBUF_SIZE) {
- debug(F100,"ttptycmd FD_SET ptyfd in","",0);
- FD_SET(ptyfd, &in);
- nfds = ptyfd;
- }
- /* Network is open and we have room to read from it? */
- if (have_net && have_pty && tbuf_avail < PTY_TBUF_SIZE) {
- debug(F100,"ttptycmd FD_SET ttyfd in","",0);
- FD_SET(ttyfd, &in);
- if (ttyfd > nfds) nfds = ttyfd;
- }
- /* Pty is open and we have stuff to write to it? */
- if (have_pty && tbuf_avail - tbuf_written > 0) {
- debug(F100,"ttptycmd FD_SET ptyfd out","",0);
- FD_SET (ptyfd, &out);
- if (ptyfd > nfds) nfds = ptyfd;
- }
- /* Net is open and we have stuff to write to it? */
- debug(F101,"ttptycmd pbuf_avail-pbuf_written","",
- pbuf_avail - pbuf_written);
- if (have_net && pbuf_avail - pbuf_written > 0) {
- debug(F100,"ttptycmd FD_SET ttyfd out","",0);
- FD_SET (ttyfd, &out);
- if (ttyfd > nfds) nfds = ttyfd;
- }
- /* We don't use err because it's not really for errors, */
- /* but for out of band data on the TCP socket, which, if it is */
- /* to be handled at all, is handled in the tt*() routines */
-
- nfds++; /* 0-based to 1-based */
- debug(F101,"ttptycmd nfds","",nfds);
- if (!nfds) {
- debug(F100,"ttptycmd NO FDs set for select","",0);
- if (have_pty) {
- /* This is not right -- sleeping won't accomplish anything */
- debug(F101,"ttptycmd msleep","",100);
- msleep(100);
- } else {
- debug(F100,"ttptycmd no pty - quitting loop","",0);
- break;
- }
- }
- errno = 0;
-
- if (seconds_to_wait > 0L) { /* Timeout in case nothing happens */
- tv.tv_sec = seconds_to_wait; /* for a long time */
- tv.tv_usec = 0L;
- tv2 = &tv;
- } else {
- tv2 = NULL;
- }
- x = select(nfds, &in, &out, NULL, tv2);
- debug(F101,"ttptycmd select","",x);
- if (x < 0) {
- if (errno == EINTR)
- continue;
- debug(F101,"ttptycmd select error","",errno);
- break;
- }
- if (x == 0) {
- debug(F101,"ttptycmd +++ select timeout","",seconds_to_wait);
- if (have_pty) {
- status = pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status A","",status);
- if (status > -1) pexitstat = status;
- have_pty = 0;
- }
- break;
- }
- /* We want to handle any pending writes first to make room */
- /* for new incoming. */
-
- if (FD_ISSET(ttyfd, &out)) { /* Can write to net? */
- CHAR * s;
- s = pbuf + pbuf_written; /* Current spot for sending */
-#ifdef TNCODE
- if (is_tn) { /* ttol() doesn't double IACs */
- CHAR c; /* Rewrite string with IACs doubled */
- int i;
- s = pbuf + pbuf_written; /* Source */
- x = 0; /* Count */
- for (i = 0; i < pbuf_avail - pbuf_written; i++) {
- c = s[i]; /* Next character */
- if (c == IAC) { /* If it's IAC */
- dbuf[x++] = c; /* put another one */
- debug(F000,">>> QUOTED IAC","",c);
- } else if (c != 0x0a && out_prev == 0x0d) { /* Bare CR */
- if (!TELOPT_ME(TELOPT_BINARY)) { /* NVT rule */
- c = 0x00;
- dbuf[x++] = c;
- debug(F000,">>> CR-NUL","",c);
- }
- }
- dbuf[x++] = c; /* Copy and count it */
- debug(F000,">>> char",ckitoa(in_state),c);
- out_prev = c;
- }
- s = dbuf; /* New source */
- } else
-#endif /* TNCODE */
- x = pbuf_avail - pbuf_written; /* How much to send */
-
- debug(F101,"ttptycmd bytes to send","",x);
- x = ttol(s, x);
- debug(F101,">>> ttol","",x);
- if (x < 0) {
- net_err++;
- debug(F111,"ttptycmd ttol error",ckitoa(x),errno);
- x = 0;
- }
- write_net_bytes += x;
- pbuf_written += x;
- }
- if (FD_ISSET(ptyfd, &out)) { /* Can write to pty? */
- debug(F100,"ttptycmd FD_ISSET ptyfd out","",0);
- errno = 0;
-#ifndef COMMENT
- x = write(ptyfd,tbuf + tbuf_written,tbuf_avail - tbuf_written);
-#else
- /* Byte loop to rule out data overruns in the pty */
- /* (it makes no difference) */
- {
- char *p = tbuf+tbuf_written;
- int n = tbuf_avail - tbuf_written;
- for (x = 0; x < n; x++) {
- msleep(10);
- if (write(ptyfd,&(p[x]),1) < 0)
- break;
- }
- }
-#endif /* COMMENT */
- debug(F111,"ttptycmd ptyfd write",ckitoa(errno),x);
- if (x > 0) {
- tbuf_written += x;
- write_pty_bytes += x;
- } else {
- x = 0;
- pty_err++;
- if (pexitstat < 0) {
- status = pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status B","",status);
- if (status > -1) pexitstat = status;
- have_pty = 0;
- }
- debug(F100,"ttptycmd +++ ptyfd write error","",0);
- }
- }
- if (FD_ISSET(ttyfd, &in)) { /* Can read from net? */
- tset++;
- debug(F100,"ttptycmd FD_ISSET ttyfd in","",0);
- n = in_chk(1,ttyfd);
- debug(F101,"ttptycmd in_chk(ttyfd)","",n);
- if (n < 0 || ttyfd == -1) {
- debug(F101,"ttptycmd +++ ttyfd errno","",errno);
- net_err++;
- } else if (n > 0) {
- if (n > PTY_TBUF_SIZE - tbuf_avail)
- n = PTY_TBUF_SIZE - tbuf_avail;
- debug(F101,"ttptycmd net read size adjusted","",n);
- if (xlocal && netconn) {
- /*
- We have to use a byte loop here because ttxin()
- does not decrypt or, for that matter, handle Telnet.
- */
- int c;
- CHAR * p;
- p = tbuf + tbuf_avail;
- for (x = 0; x < n; x++) {
- if ((c = ttinc(0)) < 0)
- break;
- if (!is_tn) { /* Not Telnet - keep all bytes */
- *p++ = (CHAR)c;
- debug(F000,"<<< char","",c);
-#ifdef TNCODE
- } else { /* Telnet - must handle IAC and NVT */
- debug(F000,"<<< char",ckitoa(in_state),c);
- switch (c) {
- case 0x00: /* NUL */
- if (in_state == HAVE_CR) {
- debug(F000,"<<< SKIP","",c);
- } else {
- *p++ = c;
- debug(F000,"<<< Keep","",c);
- }
- in_state = 0;
- break;
- case 0x0d: /* CR */
- if (!TELOPT_U(TELOPT_BINARY))
- in_state = HAVE_CR;
- *p++ = c;
- debug(F000,"<<< Keep","",c);
- break;
-#ifdef COMMENT
- case 0x0f: /* Ctrl-O */
- case 0x16: /* Ctrl-V */
- *p++ = 0x16;
- *p++ = c;
- debug(F000,"<<< QUOT","",c);
- break;
-#endif /* COMMENT */
- case 0xff: /* IAC */
- if (in_state == HAVE_IAC) {
- debug(F000,"<<< KEEP","",c);
- *p++ = c;
- in_state = 0;
- } else {
- debug(F000,"<<< SKIP","",c);
- in_state = HAVE_IAC;
- }
- break;
- default: /* All others */
- if (in_state == HAVE_IAC) {
-#ifdef COMMENT
-/*
- tn_doop() will consume an unknown number of bytes and we'll overshoot
- the for-loop. The only Telnet command I've ever seen arrive here is
- a Data Mark, which comes when the remote protocol exits and the remote
- job returns to its shell prompt. On the assumption it's a 1-byte command,
- we don't write out the IAC or the command, and we clear the state. If
- we called tn_doop() we'd have no way of knowing how many bytes it took
- from the input stream.
-*/
- int xx;
- xx = tn_doop((CHAR)c,duplex,ttinc);
- debug(F111,"<<< DOOP",ckctoa(c),xx);
-#else
- debug(F101,"<<< DOOP","",c);
-#endif /* COMMENT */
- in_state = 0;
- } else {
- *p++ = c;
- debug(F000,"<<< keep","",c);
- in_state = 0;
- }
- }
-#endif /* TNCODE */
- }
- }
- ckmakmsg(msgbuf,500,
- "ttptycmd read net [ttinc loop] errno=",
- ckitoa(errno),
- " count=",
- ckitoa(x));
- debug(F100,msgbuf,"",0);
- } else {
- x = ttxin(n,tbuf+tbuf_avail);
- debug(F101,"ttptycmd ttxin x","",x);
- }
-
- if (x < 0) {
- debug(F101,"ttptycmd read net error","",x);
- net_err++;
- }
- tbuf_avail += x;
- read_net_bytes += x;
- }
-
- } else
- tnotset++;
-
- if (FD_ISSET(ptyfd, &in)) { /* Read from pty? */
- pset++;
- debug(F100,"ttptycmd FD_ISSET ptyfd in","",0);
-#ifdef PTY_USE_NDELAY
- n = PTY_PBUF_SIZE;
-#else
- /*
- This does not work on nonblocking channels
- on certain platforms such as NetBSD.
- */
- n = pty_chk(ptyfd);
-#endif /* PTY_USE_NDELAY */
- debug(F101,"ttptycmd pty_chk() n","",n);
-
- if (n < 0)
- n = 0;
- if (n > 0) {
- if (n > PTY_PBUF_SIZE - pbuf_avail)
- n = PTY_PBUF_SIZE - pbuf_avail;
- debug(F101,"ttptycmd pty read size adjusted","",n);
- errno = 0;
- x = read(ptyfd,pbuf+pbuf_avail,n);
-#ifdef DEBUG
- if (deblog) {
- ckmakmsg(msgbuf,500,
- "ttptycmd read pty errno=",
- ckitoa(errno),
- " count=",
- ckitoa(x));
- debug(F100,msgbuf,"",0);
- }
-#endif /* DEBUG */
-
- if (x < 0 && errno == EAGAIN)
- x = 0;
-
- if (x < 0) { /* This works on Solaris and Linux */
- pty_err++; /* but not NetBSD */
- debug(F100,"TERMINATION TEST A","",0);
-#ifdef COMMENT
- if (errno == EIO)
- rc = 1;
-#endif /* COMMENT */
- if (pexitstat < 0) {
- status = pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status C","",status);
- if (status > -1) pexitstat = status;
- }
- have_pty = 0;
- x = 0;
- }
- if (x == 0 && !pty_err) { /* This works on NetBSD but */
- debug(F100,"TERMINATION TEST B","",0);
- status = pexitstat > -1 ? pexitstat :
- pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status D","",status);
- if (status > -1) {
- pexitstat = status;
- pty_err++;
- have_pty = 0;
- } else { /* Select() lied */
- pty_err = 0; /* pty still there but has nothing */
- msleep(100); /* sleep a bit */
- }
- x = 0;
- }
- /* Hopefully the next two are no longer needed... */
- if (!pty_err && (
-#ifndef PTY_USE_NDELAY
- x < 1 || errno
-#else
- errno != 0 && errno != EAGAIN
-#endif /* PTY_USE_NDELAY */
- )) {
- debug(F100,"TERMINATION TEST C","",0);
- pty_err++;
- debug(F101,"ttptycmd SET pty_err","",pty_err);
- if (errno == EIO) /* errno == EIO is like EOF */
- rc = 1;
- if (x < 0)
- x = 0;
- }
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- pbuf[pbuf_avail + x] = '\0';
- debug(F111,"ttptycmd added to pty buffer",
- pbuf+pbuf_avail,x);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- pbuf_avail += x;
- read_pty_bytes += x;
- } else { /* n == 0 with blocking reads */
- debug(F100,
- "PTY READ RETURNED ZERO BYTES - SHOULD NOT HAPPEN",
- "",0);
- }
- } else
- pnotset++;
-
- /* If writes have caught up to reads, reset the buffers */
-
- if (pbuf_written == pbuf_avail)
- pbuf_written = pbuf_avail = 0;
- if (tbuf_written == tbuf_avail)
- tbuf_written = tbuf_avail = 0;
-
- /* See if we can exit */
-
- x1 = pbuf_avail - pbuf_written;
- x2 = tbuf_avail - tbuf_written;
-
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST pty_err","",pty_err);
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST x1 [write to net]","",x1);
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST x2 [write to pty]","",x2);
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST rc","",rc);
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST status","",status);
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST pexitstat","",pexitstat);
-
- if (net_err) { /* Net error? */
- debug(F101,"ttptycmd net_err LOOP EXIT TEST net_err","",net_err);
- if (have_net) {
- if (local) {
- ttclos(0);
- printf("?Connection closed\n");
- }
- have_net = 0;
- }
- debug(F101,"ttptycmd net_err LOOP EXIT TEST x1","",x1);
- if (x1 == 0)
- break;
- }
- if (pty_err) { /* Pty error? */
- if (have_pty) {
- if (pexitstat < 0) {
- status = pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status E","",status);
- if (status > -1) pexitstat = status;
- }
- have_pty = 0;
- }
- if (x1 == 0 && x2 == 0) { /* If buffers are caught up */
- rc = 1; /* set preliminary return to success */
- debug(F101,"ttptycmd pty_err LOOP EXIT TEST rc 2","",rc);
- break; /* and exit the loop */
- }
- }
- }
- debug(F101,"ttptycmd +++ have_pty","",have_pty);
- if (have_pty) { /* In case select() failed */
-#ifdef USE_CKUPTY_C
- end_pty();
- close(ptyfd);
-#else
- close(slavefd);
- close(masterfd);
-#endif /* USE_CKUPTY_C */
- }
- pty_master_fd = -1;
- debug(F101,"ttptycmd +++ pexitstat","",pexitstat);
- if (pexitstat < 0) { /* Try one last time to get status */
- status = pty_get_status(ptyfd,pty_fork_pid);
- debug(F101,"ttptycmd pty_get_status F","",status);
- if (status > -1) pexitstat = status;
- }
- debug(F101,"ttptycmd +++ final pexitstat","",pexitstat);
- if (deblog) { /* Stats for debug log */
- debug(F101,"ttptycmd +++ pset ","",pset);
- debug(F101,"ttptycmd +++ pnotset","",pnotset);
- debug(F101,"ttptycmd +++ tset ","",tset);
- debug(F101,"ttptycmd +++ tnotset","",tnotset);
-
- debug(F101,"ttptycmd +++ read_pty_bytes","",read_pty_bytes);
- debug(F101,"ttptycmd +++ write_net_bytes","",write_net_bytes);
- debug(F101,"ttptycmd +++ read_net_bytes","",read_net_bytes);
- debug(F101,"ttptycmd +++ write_pty_bytes","",write_pty_bytes);
- }
-/*
- If we got the external protocol's exit status from waitpid(), we use that
- to set our return code. If not, we fall back on whatever rc was previously
- set to, namely 1 (success) if the pty fork seemed to terminate, 0 otherwise.
-*/
- if (save_sigchld) { /* Restore this if we changed it */
- (VOID) signal(SIGCHLD,save_sigchld);
- save_sigchld = NULL;
- }
- msleep(500);
- x = kill(pty_fork_pid,SIGHUP); /* In case it's still there */
- pty_fork_pid = -1;
- debug(F101,"ttptycmd fork kill SIGHUP","",x);
- if (pexitstat > -1)
- rc = (pexitstat == 0 ? 1 : 0);
- debug(F101,"ttptycmd +++ rc","",rc);
- if (!local) { /* If in remote mode */
- conres(); /* restore console to CBREAK mode */
- concb((char)escchr);
- }
- return(rc);
-}
-#endif /* NETPTY */
-#endif /* SELECT */
-
-/* T T R U N C M D -- Redirect an external command over the connection. */
-
-/*
- TTRUNCMD is the routine that was originally used for running external
- protocols. It is very simple and works fine provided (a) the connection
- is not encrypted, and (b) the external protocol uses standard i/o
- (file descriptors 0 and 1) for file transfer.
-*/
-
-int
-ttruncmd(s) char *s; {
- PID_T pid; /* pid of lower fork */
- int wstat; /* for wait() */
- int x;
- int statusp;
-
- if (ttyfd == -1) {
- printf("?Sorry, device is not open\n");
- return(0);
- }
- if (nopush) {
- debug(F100,"ttruncmd fail: nopush","",0);
- return(0);
- }
-
-#ifdef NETPTY
-/***************
- It might also be necessary to use the pty routine for other reasons,
- e.g. because the external program does not use stdio.
-*/
-#ifdef NETCONN
-/*
- If we have a network connection we use a different routine because
- (a) if the connection is encrypted, the mechanism used here can't deal
- with it; and (b) it won't handle any network protocols either, e.g.
- Telnet, Rlogin, K5 U-to-U, etc. However, this routine works much
- better (faster, more transparent) on serial connections and when
- C-Kermit is in remote mode (i.e. is on the far end).
-*/
- /* For testing always use this */
- if (netconn)
- return(ttptycmd(s));
-#endif /* NETCONN */
-
-/***************/
-#else /* NETPTY */
- if (tt_is_secure()) {
- printf("?Sorry, \
-external protocols over secure connections not supported in this OS.\n"
- );
- return(0);
- }
-#endif /* NETPTY */
-
- conres(); /* Make console normal */
- pexitstat = -4;
- if ((pid = fork()) == 0) { /* Make a child fork */
- if (priv_can()) /* Child: turn off privs. */
- exit(1);
- dup2(ttyfd, 0); /* Give stdin/out to the line */
- dup2(ttyfd, 1);
- x = system(s);
- debug(F101,"ttruncmd system",s,x);
- _exit(x ? BAD_EXIT : 0);
- } else {
- SIGTYP (*istat)(), (*qstat)();
- if (pid == (PID_T) -1) /* fork() failed? */
- return(0);
- istat = signal(SIGINT,SIG_IGN); /* Let the fork handle keyboard */
- qstat = signal(SIGQUIT,SIG_IGN); /* interrupts itself... */
-
-#ifdef COMMENT
- while (((wstat = wait(&statusp)) != pid) && (wstat != -1)) ;
-#else /* Not COMMENT */
- while (1) {
- wstat = wait(&statusp);
- debug(F101,"ttruncmd wait","",wstat);
- if (wstat == pid || wstat == -1)
- break;
- }
-#endif /* COMMENT */
-
- pexitstat = (statusp & 0xff) ? statusp : statusp >> 8;
- debug(F101,"ttruncmd wait statusp","",statusp);
- debug(F101,"ttruncmd wait pexitstat","",pexitstat);
- signal(SIGINT,istat); /* Restore interrupts */
- signal(SIGQUIT,qstat);
- }
- concb((char)escchr); /* Restore console to CBREAK mode */
- return(statusp == 0 ? 1 : 0);
-}
-#endif /* CK_REDIR */
-
-struct tm *
-#ifdef CK_ANSIC
-cmdate2tm(char * date, int gmt) /* date as "yyyymmdd hh:mm:ss" */
-#else
-cmdate2tm(date,gmt) char * date; int gmt;
-#endif
-{
- /* date as "yyyymmdd hh:mm:ss" */
- static struct tm _tm;
- time_t now;
-
- if (strlen(date) != 17 ||
- date[8] != ' ' ||
- date[11] != ':' ||
- date[14] != ':')
- return(NULL);
-
- time(&now);
- if (gmt)
- _tm = *gmtime(&now);
- else
- _tm = *localtime(&now);
- _tm.tm_year = (date[0]-'0')*1000 + (date[1]-'0')*100 +
- (date[2]-'0')*10 + (date[3]-'0')-1900;
- _tm.tm_mon = (date[4]-'0')*10 + (date[5]-'0')-1;
- _tm.tm_mday = (date[6]-'0')*10 + (date[7]-'0');
- _tm.tm_hour = (date[9]-'0')*10 + (date[10]-'0');
- _tm.tm_min = (date[12]-'0')*10 + (date[13]-'0');
- _tm.tm_sec = (date[15]-'0')*10 + (date[16]-'0');
-
- /* Should we set _tm.tm_isdst to -1 here? */
-
- _tm.tm_wday = 0;
- _tm.tm_yday = 0;
-
- return(&_tm);
-}
-
-#ifdef OXOS
-#undef kill
-#endif /* OXOS */
-
-#ifdef OXOS
-int
-priv_kill(pid, sig) int pid, sig; {
- int i;
-
- if (priv_on())
- debug(F100,"priv_kill priv_on failed","",0);
- i = kill(pid, sig);
- if (priv_off())
- debug(F100,"priv_kill priv_off failed","",0);
- return(i);
-}
-#endif /* OXOS */
-
-#ifdef BEOSORBEBOX
-/* #ifdef BE_DR_7 */
-/*
- alarm() function not supplied with Be OS DR7 - this one contributed by
- Neal P. Murphy.
-*/
-
-/*
- This should mimic the UNIX/POSIX alarm() function well enough, with the
- caveat that one's SIGALRM handler must call alarm_expired() to clean up vars
- and wait for the alarm thread to finish.
-*/
-unsigned int
-alarm(unsigned int seconds) {
- long time_left = 0;
-
-/* If an alarm is active, turn it off, saving the unused time */
- if (alarm_thread != -1) {
- /* We'll be generous and count partial seconds as whole seconds. */
- time_left = alarm_struct.time -
- ((system_time() - time_started) / 1000000.0);
-
- /* Kill the alarm thread */
- kill_thread (alarm_thread);
-
- /* We need to clean up as though the alarm occured. */
- time_started = 0;
- alarm_struct.thread = -1;
- alarm_struct.time = 0;
- alarm_expired();
- }
-
-/* Set a new alarm clock, if requested. */
- if (seconds > 0) {
- alarm_struct.thread = find_thread(NULL);
- alarm_struct.time = seconds;
- time_started = system_time();
- alarm_thread = spawn_thread (do_alarm,
- "alarm_thread",
- B_NORMAL_PRIORITY,
- (void *) &alarm_struct
- );
- resume_thread (alarm_thread);
- }
-
-/* Now return [unused time | 0] */
- return ((unsigned int) time_left);
-}
-
-/*
- This function is the departure from UNIX/POSIX alarm handling. In the case
- of Be's missing alarm() function, this stuff needs to be done in the SIGALRM
- handler. When Be implements alarm(), this function call can be eliminated
- from user's SIGALRM signal handlers.
-*/
-
-void
-alarm_expired(void) {
- long ret_val;
-
- if (alarm_thread != -1) {
- wait_for_thread (alarm_thread, &ret_val);
- alarm_thread = -1;
- }
-}
-
-/*
- This is the function that snoozes the requisite number of seconds and then
- SIGALRMs the calling thread. Note that kill() wants a pid_t arg, whilst Be
- uses thread_id; currently they are both typdef'ed as long, but I'll do the
- cast anyway. This function is run in a separate thread.
-*/
-
-long
-do_alarm (void *alarm_struct) {
- snooze ((double) ((struct ALARM_STRUCT *) alarm_struct)->time * 1000000.0);
- kill ((pid_t)((struct ALARM_STRUCT *) alarm_struct)->thread, SIGALRM);
- time_started = 0;
- ((struct ALARM_STRUCT *) alarm_struct)->thread = -1;
- ((struct ALARM_STRUCT *) alarm_struct)->time = 0;
-}
-/* #endif */ /* BE_DR_7 */
-#endif /* BEOSORBEBOX */
-
-#ifdef Plan9
-
-int
-p9ttyctl(char letter, int num, int param) {
- char cmd[20];
- int len;
-
- if (ttyctlfd < 0)
- return -1;
-
- cmd[0] = letter;
- if (num)
- len = sprintf(cmd + 1, "%d", param) + 1;
- else {
- cmd[1] = param;
- len = 2;
- }
- if (write(ttyctlfd, cmd, len) == len) {
- cmd[len] = 0;
- /* fprintf(stdout, "wrote '%s'\n", cmd); */
- return 0;
- }
- return -1;
-}
-
-int
-p9ttyparity(char l) {
- return p9ttyctl('p', 0, l);
-}
-
-int
-p9tthflow(int flow, int status) {
- return p9ttyctl('m', 1, status);
-}
-
-int
-p9ttsspd(int cps) {
- if (p9ttyctl('b', 1, cps * 10) < 0)
- return -1;
- ttylastspeed = cps * 10;
- return 0;
-}
-
-int
-p9openttyctl(char *ttname) {
- char name[100];
-
- if (ttyctlfd >= 0) {
- close(ttyctlfd);
- ttyctlfd = -1;
- ttylastspeed = -1;
- }
- sprintf(name, "%sctl", ttname);
- ttyctlfd = open(name, 1);
- return ttyctlfd;
-}
-
-int
-p9concb() {
- if (consctlfd >= 0) {
- if (write(consctlfd, "rawon", 5) == 5)
- return 0;
- }
- return -1;
-}
-
-int
-p9conbin() {
- return p9concb();
-}
-
-int
-p9conres() {
- if (consctlfd >= 0) {
- if (write(consctlfd, "rawoff", 6) == 6)
- return 0;
- }
- return -1;
-}
-
-int
-p9sndbrk(int msec) {
- if (ttyctlfd >= 0) {
- char cmd[20];
- int i = sprintf(cmd, "k%d", msec);
- if (write(ttyctlfd, cmd, i) == i)
- return 0;
- }
- return -1;
-}
-
-int
-conwrite(char *buf, int n) {
- int x;
- static int length = 0;
- static int holdingcr = 0;
- int normal = 0;
- for (x = 0; x < n; x++) {
- char c = buf[x];
- if (c == 007) {
- if (normal) {
- write(1, buf + (x - normal), normal);
- length += normal;
- normal = 0;
- }
- /* write(noisefd, "1000 300", 8); */
- holdingcr = 0;
- } else if (c == '\r') {
- if (normal) {
- write(1, buf + (x - normal), normal);
- length += normal;
- normal = 0;
- }
- holdingcr = 1;
- } else if (c == '\n') {
- write(1, buf + (x - normal), normal + 1);
- normal = 0;
- length = 0;
- holdingcr = 0;
- } else if (c == '\b') {
- if (normal) {
- write(1, buf + (x - normal), normal);
- length += normal;
- normal = 0;
- }
- if (length) {
- write(1, &c, 1);
- length--;
- }
- holdingcr = 0;
- } else {
- if (holdingcr) {
- char b = '\b';
- while (length-- > 0)
- write(1, &b, 1);
- length = 0; /* compiler bug */
- }
- holdingcr = 0;
- normal++;
- }
- }
- if (normal) {
- write(1, buf + (x - normal), normal);
- length += normal;
- }
- return n;
-}
-
-void
-conprint(char *fmt, ...) {
- static char buf[1000]; /* not safe if on the stack */
-
- va_list ap;
- int i;
-
- va_start(ap, fmt);
- i = vsprintf(buf, fmt, ap);
- conwrite(buf, i);
-}
-#endif /* Plan9 */
-
-/* fprintf, printf, perror replacements... */
-
-/* f p r i n t f */
-
-#ifdef UNIX
-#ifdef CK_ANSIC
-#include <stdarg.h>
-#else /* CK_ANSIC */
-#ifdef __GNUC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif /* __GNUC__ */
-#endif /* CK_ANSIC */
-#ifdef fprintf
-#undef fprintf
-static char str1[4096];
-static char str2[4096];
-int
-#ifdef CK_ANSIC
-ckxfprintf(FILE * file, const char * format, ...)
-#else /* CK_ANSIC */
-ckxfprintf(va_alist) va_dcl
-#endif /* CK_ANSIC */
-/* ckxfprintf */ {
- int i, j, len, got_cr;
- va_list args;
- int rc = 0;
-
-#ifdef CK_ANSIC
- va_start(args, format);
-#else /* CK_ANSIC */
- char * format;
- FILE * file;
- va_start(args);
- file = va_arg(args,FILE *);
- format = va_arg(args,char *);
-#endif /* CK_ANSIC */
-
- if (!inserver || (file != stdout && file != stderr && file != stdin)) {
- rc = vfprintf(file,format,args);
- } else {
- unsigned int c;
- rc = vsprintf(str1, format, args);
- len = strlen(str1);
- if (len >= sizeof(str1)) {
- debug(F101,"ckxfprintf() buffer overflow","",len);
- doexit(BAD_EXIT,1);
- }
- for (i = 0, j = 0, got_cr = 0;
- i < len && j < sizeof(str1)-2;
- i++, j++ ) {
- /* We can't use 255 as a case label because of signed chars */
- c = (unsigned)(str1[i] & 0xff);
-#ifdef TNCODE
- if (c == 255) {
- if (got_cr && !TELOPT_ME(TELOPT_BINARY))
- str2[j++] = '\0';
- str2[j++] = IAC;
- str2[j] = IAC;
- got_cr = 0;
- } else
-#endif /* TNCODE */
- switch (c) {
- case '\r':
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
- str2[j] = str1[i];
- got_cr = 1;
- break;
- case '\n':
- if (!got_cr)
- str2[j++] = '\r';
- str2[j] = str1[i];
- got_cr = 0;
- break;
- default:
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
- str2[j] = str1[i];
- got_cr = 0;
- }
- }
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
-#ifdef CK_ENCRYPTION
-#ifdef TNCODE
- if (TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(str2,j);
-#endif /* TNCODE */
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if (inserver && (ssl_active_flag || tls_active_flag)) {
- /* Write using SSL */
- char * p = str2;
- ssl_retry:
- if (ssl_active_flag)
- rc = SSL_write(ssl_con, p, j);
- else
- rc = SSL_write(tls_con, p, j);
- debug(F111,"ckxfprintf","SSL_write",rc);
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,rc)) {
- case SSL_ERROR_NONE:
- if (rc == j)
- break;
- p += rc;
- j -= rc;
- goto ssl_retry;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
- if (rc != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- rc = 0;
- }
- } else
-#endif /* CK_SSL */
- fwrite(str2,sizeof(char),j,stdout);
- }
- va_end(args);
- return(rc);
-}
-#endif /* fprintf */
-
-/* p r i n t f */
-
-#ifdef printf
-#undef printf
-int
-#ifdef CK_ANSIC
-ckxprintf(const char * format, ...)
-#else /* CK_ANSIC */
-ckxprintf(va_alist) va_dcl
-#endif /* CK_ANSIC */
-/* ckxprintf */ {
- int i, j, len, got_cr;
- va_list args;
- int rc = 0;
-
-#ifdef CK_ANSIC
- va_start(args, format);
-#else /* CK_ANSIC */
- char * format;
- va_start(args);
- format = va_arg(args,char *);
-#endif /* CK_ANSIC */
-
- if (!inserver) {
- rc = vprintf(format, args);
- } else {
- unsigned int c;
- rc = vsprintf(str1, format, args);
- len = strlen(str1);
- if (len >= sizeof(str1)) {
- debug(F101,"ckxprintf() buffer overflow","",len);
- doexit(BAD_EXIT,1);
- }
- for (i = 0, j = 0, got_cr=0;
- i < len && j < sizeof(str1)-2;
- i++, j++ ) {
- c = (unsigned)(str1[i] & 0xff);
-#ifdef TNCODE
- if (c == 255) {
- if (got_cr && !TELOPT_ME(TELOPT_BINARY))
- str2[j++] = '\0';
- str2[j++] = IAC;
- str2[j] = IAC;
- got_cr = 0;
- } else
-#endif /* TNCODE */
- switch (c) {
- case '\r':
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
- str2[j] = str1[i];
- got_cr = 1;
- break;
- case '\n':
- if (!got_cr)
- str2[j++] = '\r';
- str2[j] = str1[i];
- got_cr = 0;
- break;
- default:
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
- str2[j] = str1[i];
- got_cr = 0;
- break;
- }
- }
- if (got_cr
-#ifdef TNCODE
- && !TELOPT_ME(TELOPT_BINARY)
-#endif /* TNCODE */
- )
- str2[j++] = '\0';
-#ifdef CK_ENCRYPTION
-#ifdef TNCODE
- if (TELOPT_ME(TELOPT_ENCRYPTION))
- ck_tn_encrypt(str2,j);
-#endif /* TNCODE */
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if (inserver && (ssl_active_flag || tls_active_flag)) {
- char * p = str2;
- /* Write using SSL */
- ssl_retry:
- if (ssl_active_flag)
- rc = SSL_write(ssl_con, p, j);
- else
- rc = SSL_write(tls_con, p, j);
- debug(F111,"ckxprintf","SSL_write",rc);
- switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,rc)) {
- case SSL_ERROR_NONE:
- if (rc == j)
- break;
- p += rc;
- j -= rc;
- goto ssl_retry;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
- if (rc != 0)
- return(-1);
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- rc = 0;
- }
- } else
-#endif /* CK_SSL */
- rc = fwrite(str2,sizeof(char),j,stdout);
- }
- va_end(args);
- return(rc);
-}
-#endif /* printf */
-
-/* p e r r o r */
-
-#ifdef perror
-#undef perror
-_PROTOTYP(char * ck_errstr,(VOID));
-#ifdef NEXT
-void
-#else
-#ifdef CK_SCOV5
-void
-#else
-int
-#endif /* CK_SCOV5 */
-#endif /* NEXT */
-#ifdef CK_ANSIC
-ckxperror(const char * str)
-#else /* CK_ANSIC */
-ckxperror(str) char * str;
-#endif /* CK_ANSIC */
-/* ckxperror */ {
- char * errstr = ck_errstr();
-#ifndef NEXT
-#ifndef CK_SCOV5
- return
-#endif /* CK_SCOV5 */
-#endif /* NEXT */
- ckxprintf("%s%s %s\n",str,*errstr?":":"",errstr);
-}
-#endif /* perror */
-#endif /* UNIX */
-
-#ifdef MINIX2
-
-/* Minix doesn't have a gettimeofday call (but MINIX3 does).
- * We fake one here using time(2)
- */
-
-#ifndef MINIX3
-int
-gettimeofday(struct timeval *tp, struct timezone *tzp) {
- tp->tv_usec = 0L; /* Close enough for horseshoes */
- if(time(&(tp->tv_sec))==-1)
- return(-1);
- return(0);
-}
-#endif /* MINIX3 */
-
-#ifndef MINIX3
-int
-readlink(const char *path, void *buf, size_t bufsiz) {
- errno = ENOSYS;
- return(-1);
-}
-#endif /* MINIX3 */
-
-#endif /* MINIX2 */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckututor.txt b/ckermit-9.0.302-build/ckermit-9.0.302/ckututor.txt
deleted file mode 100644
index ef2aebe..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckututor.txt
+++ /dev/null
@@ -1,1948 +0,0 @@
-
- [1]The Columbia Crown The Kermit Project | Columbia University
- 612 West 115th Street, New York NY 10025 USA o [2]kermit@columbia.edu
- ...since 1981
- [3]Home [4]Kermit 95 [5]C-Kermit [6]Scripts [7]Current [8]New [9]FAQ
- [10]Support
-
- C-KERMIT 9.0 UNIX MANUAL PAGE AND TUTORIAL
-
- Frank da Cruz
- [11]The Kermit Project, [12]Columbia University
-
- [ [13]PDF version ] [ [14]Nroff version ]
-
- This document is intended to give the beginner sufficient
- information to make basic (if not advanced) use of C-Kermit 9.0.
- Although it might be rather long for a Unix manual page (about 1600
- lines), it's still far shorter than the [15]C-Kermit manual, which
- should be consulted for advanced topics such as customization,
- character-sets, scripting, etc. We also attempt to provide a clear
- structural overview of C-Kermit's many capabilities, functional
- areas, states, and modes and their interrelation, that should be
- helpful to beginners and veterans alike, as well as to those
- upgrading to the new release. Thanks to Christine Gianone for her
- work on this document before she was laid off in 2005.
-
- Most recent update: Fri Jul 1 14:12:31 2011
-
-CONTENTS
-
- * [16]DESCRIPTION
- * [17]SYNOPSIS
- * [18]OPTIONS
- * [19]COMMAND LANGUAGE
- * [20]INITIALIZATION FILE
- * [21]MODES OF OPERATION
- * [22]MAKING CONNECTIONS
- * [23]TRANSFERRING FILES WITH KERMIT
- * [24]KERMIT CLIENT/SERVER CONNECTIONS
-
- * [25]KERMIT'S BUILT-IN FTP AND HTTP CLIENTS
- * [26]INTERNET KERMIT SERVICE
- * [27]SECURITY
- * [28]ALTERNATIVE COMMAND-LINE PERSONALITIES
- * [29]LICENSE
- * [30]OTHER TOPICS
- * [31]DOCUMENTATION AND UPDATES
- * [32]FILES
- * [33]AUTHORS
-
-DESCRIPTION
-
- [34]Top [35]Contents [36]Next
-
- [37]C-Kermit is an all-purpose communications software package from the
- [38]Kermit Project at [39]Columbia University that:
-
- * Is portable to many platforms, Unix and non-Unix alike.
- * Can make both serial and network connections.
- * Can conduct interactive terminal sessions over its connection.
- * Can transfer text or binary files over the same connection.
- * Can convert text-file character sets in terminal mode or file
- transfer.
- * Is customizable in every aspect of its operation.
-
- C-Kermit is a modem program, a Telnet client, an Rlogin client, an FTP
- client, an HTTP client, and on selected platforms, also an X.25 client.
- It can make its own secure Internet connections using IETF-approved
- security methods including Kerberos IV, Kerberos V, SSL/TLS, and SRP
- and it can also make SSH (Secure Shell) connections through your
- external SSH client application. It can be the far-end file-transfer or
- client/server partner of your desktop Kermit client. It can also accept
- incoming dialed and network connections. It can even be installed as an
- Internet service on its own standard TCP socket, 1649 [[40]RFC2839,
- [41]RFC2840].
-
- And perhaps most important, everything you can do "by hand"
- (interactively) with C-Kermit, can be "scripted" (automated) using its
- built-in cross-platform transport-independent script programming
- language, which happens to be identical to its interactive command
- language.
-
- This manual page offers an overview of C-Kermit 9.0 for Unix ("Unix" is
- an operating system family that includes AIX, DG/UX, FreeBSD, HP-UX,
- IRIX, Linux, Mac OS X, NetBSD, OpenBSD, Open Server, Open Unix, QNX,
- Solaris, SunOS, System V R3, System V R4, Tru64 Unix, Unixware, Xenix,
- and many others). For thorough coverage, please consult the published
- C-Kermit manual and supplements (see [42]DOCUMENTATION below). For
- further information about C-Kermit, Kermit software for other
- platforms, and Kermit manuals, visit the Kermit Project website:
-
- [43]http://www.columbia.edu/kermit/
-
- This is a longer-than-average manual page, and yet it barely scratches
- the surface. Don't be daunted. C-Kermit is a large and complex package,
- evolving over decades of practice and experience, but that doesn't mean
- it's hard to learn or use. Its most commonly used functions are
- explained here with pointers to additional information elsewhere.
-
- [44]Kermit Home [45]C-Kermit Home [46]C-Kermit FAQ
-
-SYNOPSIS
-
- [47]Top [48]Contents [49]Next [50]Previous
-
- Usage: kermit [filename] [-x arg [-x arg]...[-yyy]..] [ {=,--,+} text
- ] ]
- Or: kermit URL
-
- * -x is an option requiring an argument;
- * -y is an option with no argument.
-
- If the first command-line argument is the name of a file,
- interactive-mode commands are executed from the file. The '=' (or "--")
- argument tells Kermit not to parse the remainder of the command line,
- but to make the words following '=' available as \%1, \%2, ... \%9. The
- "+" argument is like "=" but for use in "kerbang scripts" (explained
- [51]below). A second command-line format allows the one and only
- argument to be a [52]Telnet, FTP, HTTP, or IKSD URL.
-
- Order of execution:
-
- 1. [53]The command file (if any).
- 2. [54]The initialization file, if any, unless suppressed with -Y.
- 3. [55]The customization file (if it is executed by the initialization
- file).
- 4. [56]The command-line URL (if any, and if so, execution stops here).
- 5. [57]Command-line options (if any).
- 6. [58]Interactive commands.
-
- Some command-line options can cause actions (such as -s to send a
- file); others just set parameters. If any action options are included
- on the command line, Kermit exits when finished unless also given the
- -S ("stay") option. If no action options are given, no initialization
- or command files contained an EXIT or QUIT command, and no fatal errors
- occurred, Kermit issues its prompt and waits for you to type commands.
-
- Bear in mind that C-Kermit can be built with selected features
- disabled, and also that certain features are not available on all
- platforms. For example, C-Kermit can't be built with TCP/IP support
- on a platform that does not have TCP/IP header files and libraries
- (and even if Kermit does include TCP/IP support, it can't be used to
- make TCP/IP connections on a computer that does not have a TCP/IP
- stack installed). If your version of C-Kermit lacks a feature
- mentioned here, use its SHOW FEATURES command to see what might have
- been excluded.
-
- C-Kermit has three kinds of commands: regular single-letter
- command-line options, extended-format command-line options, and
- interactive commands.
-
- [59]Kermit Home [60]C-Kermit Home [61]C-Kermit FAQ
-
-OPTIONS
-
- [62]Top [63]Contents [64]Next [65]Previous <- (Most people should
- click Next to skip around this section...)
-
- Like most Unix commands, C-Kermit can be be given options on the
- command line. But C-Kermit also can be used interactively by giving it
- [66]commands composed of words, which are more intuitive than cryptic
- command-line options, and more flexible too. In other words, you don't
- have to use C-Kermit's command-line options, but they are available if
- you want to. (By the same token, you don't have to use its interactive
- commands either -- you can use either or both in any combination.)
-
- C-Kermit is generally installed in the PATH as "kermit", and therefore
- is invoked by typing the word "kermit" (lowercase) at the shell prompt,
- and then pressing the Return or Enter key. If you wish to include
- command-line options, put them after the word "kermit" but before
- pressing Return or Enter, separated by spaces, for example:
-
- $ kermit -s ckermit.tar.gz
-
- ('$' is the shell prompt; "kermit -s ckermit.tar.gz" is what you type,
- followed by Return or Enter.)
-
- Here is a list of C-Kermit's single-letter command-line options, which
- start with a single dash (-), in ASCII ("alphabetical") order.
- Alphabetic case is significant (-A is not the same as -a). The Action?
- column contains Y for action options and N for non-action options.
-
- Option Action? Description
- -0 N (digit zero) 100% transparent Connect state for "in-the-middle"
- operation: 8 bits, no parity, no escape character, everything passes
- through.
- -8 N (digit eight) Connection is 8-bit clean (this is the default in
- C-Kermit 9.0). Equivalent to the EIGHTBIT command, which in turn is a
- shortcut for SET TERMINAL BYTESIZE 8, SET COMMAND BYTESIZE 8, SET
- PARITY NONE.
- -9 arg N (digit nine) Make a connection to an FTP server. Equivalent to
- the FTP OPEN command.
- Argument: IP-address-or-hostname[:optional-TCP-port].
- NOTE: C-Kermit also has a separate FTP command-line personality, with
- regular FTP-like command-line syntax. [67]More about this below.
- -A N Kermit is to be started as an Internet service (IKSD) (only from
- inetd.conf).
- -B N Kermit is running in Batch or Background (no controlling
- terminal). To be used in case Kermit doesn't automatically sense its
- background status. Equivalent to the SET BACKGROUND ON command.
- -C arg N Interactive-mode Commands to be executed.
- Argument: Commands separated by commas, list in doublequotes.
- -D arg N Delay before starting to send in Remote mode. Equivalent to
- the SET DELAY command.
- Argument: Number of seconds.
- -E N Exit automatically when connection closes. Equivalent to SET EXIT
- ON-DISCONNECT ON.
- -F arg N Use an open TCP connection.
- Argument: Numeric file descriptor of open TCP connection.
- Also see: -j, -J.
- -G arg Y Get file(s) from server, send contents to standard output,
- which normally would be piped to another process.
- Argument: Remote file specification, in quotes if it contains
- metacharacters.
- Also see: -g, -k.
- -H N Suppress program startup Herald and greeting.
- -I N Tell Kermit it has a reliable connection, to force streaming to be
- used where it normally would not be. Equivalent to the SET RELIABLE ON
- command.
- -J arg N "Be like Telnet." Like -j but implies -E.
- Argument: IP hostname/address optionally followed by service.
- NOTE: C-Kermit also has a separate Telnet command-line personality,
- with regular Telnet-like command-line syntax. [68]More about this
- below.
- -L N Recursive directory descent for files in -s option.
- -M arg N My user name (for use with Telnet, Rlogin, FTP, etc).
- Equivalent to the SET LOGIN USER command.
- Argument: Username string.
- -O Y (Uppercase letter O) Be a server for One command only. Also see:
- -x.
- -P N Don't convert file (Path) names of transferred files. Equivalent
- to SET FILE NAMES LITERAL.
- -Q N Quick Kermit protocol settings. Equivalent to the FAST command.
- This is the default in C-Kermit 7.0 and later.
- -R N Remote-only (this just makes IF REMOTE true).
- -S N Stay (enter command parser after action options).
- -T N Force Text mode for file transfer; implies -V. Equivalent to SET
- TRANSFER MODE MANUAL, SET FILE TYPE TEXT.
- -V N Disable automatic per-file text/binary switching. Equivalent to
- SET TRANSFER MODE MANUAL.
- -Y N Skip (don't execute) the initialization file.
- -a arg N As-name for file(s) in -s, -r, or -g.
- Argument: As-name string (alternative filename). When receiving files,
- this can be a directory name.
- -b arg N Speed for serial device. Equivalent to SET SPEED.
- Argument: Numeric Bits per second for serial connections.
- -c Y Enter Connect state before transferring files.
- -d N Create a debug.log file with detailed debugging information (a
- second -d adds timestamps). Equivalent to LOG DEBUG but takes effect
- sooner.
- -e arg N Maximum length for incoming Kermit file-transfer packets.
- Equivalent to SET RECEIVE PACKET-LENGTH.
- Argument: Length in bytes.
- -f Y Send a FINISH command to a Kermit server.
- -g arg N Get file(s) from a Kermit server.
- Argument: File specification on other computer, in quotes if it
- contains metacharacters. Equivalent to GET.
- Also see: -a, -G, -r.
- -h Y Print Help text for single-letter command-line options (pipe thru
- 'more' to prevent scrolling).
- -i N Force binary (Image) mode for file transfer; implies -V.
- Equivalent to SET TRANSFER MODE MANUAL, SET FILE TYPE BINARY.
- -j arg N Make a TCP/IP connection.
- Argument: IP host name/address and optional service name or number.
- Equivalent to the TELNET command.
- Also see: -J, -F.
- -k Y Receive file(s) to standard output, which normally would be piped
- to another process.
- Also see: -r, -G.
- -l arg N (Lowercase letter L) Make a connection on the given serial
- communications device. Equivalent to the SET LINE (SET PORT) command.
- Argument: Serial device name, e.g. /dev/ttyS0.
- -m arg N Modem type for use with the -l device. Equivalent to the SET
- MODEM TYPE command.
- Argument: Modem name as in SET MODEM TYPE command, e.g. "usrobotics".
- -n Y Enter Connect state after transferring files (historical).
- -p arg N Parity. Equivalent to the SET PARITY command.
- Argument: One of the following: e(ven), o(dd), m(ark), n(one), s(pace).
- -q N Quiet (suppress most messages). Equivalent to SET QUIET ON.
- -r Y Receive file(s). Equivalent to the RECEIVE command.
- Argument: (none, but see -a)
- -s arg N Send file(s).
- Argument: One or more local file specifications. Equivalent to the SEND
- command.
- Also see: -a.
- -t N (Historical) Xon (Ctrl-Q) Turnaround character for half-duplex
- connections (used on serial linemode connections to old mainframes).
- Equivalent to SET DUPLEX HALF, SET HANDSHAKE XON.
- -v arg N Window size for Kermit protocol (ignored when streaming).
- Equivalent to SET WINDOW-SIZE.
- Argument: Number, 1 to 32.
- -w N Incoming files Write over existing files. Equivalent to SET FILE
- COLLISION OVERWRITE.
- -x Y Enter server mode. Equivalent to the SERVER command. Also see: -O.
- -y arg N Alternative initialization file.
- Argument: Filename.
- -z N Force foreground behavior. To be used in case Kermit doesn't
- automatically sense its foreground status. Equivalent to the SET
- BACKGROUND OFF command.
-
- Extended command-line options (necessary because single-letter ones are
- about used up) start with two dashes (--), with words rather than
- single letters as option names. If an extended option takes an
- argument, it is separated from the option word by a colon (:). Extended
- options include:
-
- Option Description
- --bannerfile:filename File to display upon startup or IKSD login.
- --cdfile:filename File to be sent for display to the client when server
- changes directory (filename is relative to the changed-to directory).
- --cdmessage:{on,off} Enable/disable the server CD message feature.
- --help Prints usage message for extended options.
- --helpfile:filename Designates a file containing custom text to replace
- the top-level HELP command.
- --nointerrupts Disables keyboard interrupts.
- --noperms Disables the Kermit protocol file Permissions attribute, to
- prevent transmission of file permissions (protection) from sender to
- receiver.
-
- Plus several other [69]IKSD-Only options.
-
- See the [70]file-transfer section for examples of command-line
- invocation.
-
-COMMAND LANGUAGE
-
- [71]Top [72]Contents [73]Next [74]Previous
-
- * [75]Command Files, Macros, and Scripts
- * [76]Command List
-
- C-Kermit's interactive command language is the subject of a
- [77]622-page book and another several hundred pages of updates, far too
- much for a manual page. But it's not hard to get started. At the shell
- prompt, just type "kermit" to get C-Kermit's interactive command
- prompt:
-
- $ kermit
- (/current/directory) C-Kermit>
-
- Begin by typing "help" (and then press the Return or Enter key) for a
- top-level overview, read it, and go from there. Your second command
- should probably be "intro" (introduction). Note the prompt shows your
- current directory (unless you tell Kermit to prompt you with something
- else).
-
- Interactive commands are composed mainly of regular English words,
- usually in the form of imperative sentences, such as:
-
- send oofa.txt
-
- which tells Kermit to send (transfer) the file whose name is oofa.txt,
- or:
-
- set transfer mode automatic
-
- which sets Kermit's "transfer mode" to "automatic" (whatever that
- means).
-
- While typing commands, you can abbreviate, ask for help (by pressing
- the "?" key anywhere in a command), complete keywords or filenames
- (with the Tab or Esc key), and edit your typing with Backspace or
- Delete, Ctrl-W, Ctrl-U, etc. You can also recall previous commands,
- save your command history, and who knows what else. Give the INTRO
- command for details.
-
- C-Kermit has hundreds of commands, and they can be issued in infinite
- variety and combinations, including commands for:
-
- * Making connections (SET LINE, DIAL, TELNET, SSH, FTP, CONNECT, ...)
- * Breaking connections (HANGUP, CLOSE)
- * Transferring files (SEND, GET, RECEIVE, MOVE, RESEND, ...)
- * Establishing preferences (SET)
- * Displaying preferences (SHOW)
- * Managing local files (CD, DELETE, MKDIR, DIRECTORY, RENAME, TYPE,
- ...)
- * Managing remote files (RCD, RDEL, RMKDIR, RDIR, ...)
- * Using local files (FOPEN, FCLOSE, FREAD, FWRITE)
- * Programming (TAKE, DEFINE, IF, FOR, WHILE, SWITCH, DECLARE, ...)
- * Interacting with the user (ECHO, ASK, ...)
- * Interacting with a remote computer (INPUT, OUTPUT, ...)
- * Interacting with local programs (RUN, EXEC, PTY, ...)
- * Logging things (LOG SESSION, LOG PACKETS, LOG DEBUG, ...)
-
- And of course QUIT or EXIT to get out and HELP to get help, and for
- programmers: loops, decision making, variables, arrays, associative
- arrays, integer and floating point arithmetic, macros, built-in and
- user-defined functions, string manipulation, pattern matching, block
- structure, scoping, recursion, and all the rest. To get a list of all
- C-Kermit's commands, type a question mark (?) at the prompt. To get a
- description of any command, type HELP followed by the name of the
- command, for example:
-
- help send
-
- The command interruption character is Ctrl-C (hold down the Ctrl key
- and press the C key).
-
- The command language "escape character", used to introduce variable
- names, function invocations, and so on, is backslash (\). If you need
- to include a literal backslash in a command, type two of them, e.g.:
-
- get c:\\k95\\k95custom.ini
-
-Command Files, Macros, and Scripts
-
- A file containing Kermit commands is called a Kermit command file or
- Kermit script. It can be executed with Kermit's TAKE command:
-
- (/current/dir) C-Kermit> take commandfile
-
- (where "commandfile" is the name of the command file). Please don't
- pipe a command file into Kermit's standard input (which might or might
- not work); if you have Kermit commands in a file, tell Kermit to TAKE
- the file.
-
- In Unix only, a Kermit command file can also be executed directly by
- including a "kerbang" line as the first line of the file:
-
- #!/usr/local/bin/kermit +
-
- That is, a top line that starts with "#!", followed immediately by the
- full path of the Kermit executable, and then, if the Kermit script is
- to be given arguments on the command line, a space and a plus sign. The
- script file must also have execute permission:
-
- chmod +x commandfile
-
- Except for the " +" part, this is exactly the same as you would do for
- a shell script, a Perl script, etc. Here's a simple but useless example
- script that regurgitates its arguments (up to three of them):
-
- #!/usr/local/bin/kermit +
- if defined \%1 echo "Argument 1: \%1"
- if defined \%2 echo "Argument 2: \%2"
- if defined \%3 echo "Argument 3: \%3"
- if defined \%4 echo "etc..."
- exit
-
- If this file is stored in your current directory as "commandfile",
- then:
-
- ./commandfile one two three four five
-
- prints:
-
- Argument 1: one
- Argument 2: two
- Argument 3: three
- etc...
-
- This illustrates the basic structure of a standalone Kermit script: the
- "kerbang line", then some commands. It should end with "exit" unless
- you want the Kermit prompt to appear when it is finished. \%1 is the
- first argument, \%2 the second, and so on.
-
- You can also create your own commands by defining named macros composed
- of other Kermit commands (or macros). Here's a simple example:
-
- define mydial {
- set modem type usrobotics
- set port /dev/ttyS0
- if fail end 1
- set speed 57600
- dial \%1
- if success connect
- }
-
- This shows how you can combine many commands into one command, "mydial"
- in this case (you can use any name you like, provided it does not clash
- with the name of a built-in command). When this macro definition is in
- effect, you can type commands like:
-
- mydial 7654321
-
- and it executes all the commands in macro definition, substituting the
- first operand ("7654321") for the formal parameter ("\%1") in the
- definition. This saves you from having to type lots of commands every
- time you want to make a modem call.
-
- One way to have the macro definition in effect is to type the
- definition at the Kermit prompt. Another way is to store the definition
- in a file and TAKE the file. If you want the definition to be in effect
- automatically every time you start Kermit, put the definition in your
- initialization or customization file (explained [78]below).
-
- Here's a somewhat more ambitious example:
-
- define mydelete {
- local trash
- assign trash \v(home)trashcan/
- if not defined \%1 end 1 "Delete what?"
- if wild \%1 end 1 "Deleting multiple files is too scary"
- if not exist \%1 end 1 "I can't find \%1"
- if not directory \m(trash) {
- mkdir \m(trash)
- if fail end 1 "No trash can"
- }
- rename /list \%1 \m(trash)
- }
- define myundelete {
- local trash
- assign trash \v(home)trashcan/
- if not defined \%1 end 1 "Undelete what?"
- if wild \%1 end 1 "Undeleting multiple files is too hard"
- if not directory \m(trash) end 1 "No trash can"
- if not exist \m(trash)\%1 end 1 "I can't find \%1 in trash can"
- rename /list \m(trash)\%1 .
- }
-
- These macros are not exactly production quality (they don't handle
- filenames that include path segments, they don't handle multiple files,
- etc), but you get the idea: you can pass arguments to macros, they can
- check them and make other kinds of decisions, and the commands
- themselves are relatively intuitive and intelligible.
-
- If you put the above lines into your initialization or customization
- file, you'll have MYDELETE and MYUNDELETE commands available every time
- you start Kermit, at least as long as you don't suppress execution of
- the initialization file. (Exercise for the reader: Make these macros
- generally useful: remove limitations, add trashcan display, browsing,
- emptying, etc.)
-
- Kerbang scripts execute without the initialization file. This to keep
- them portable and also to make them start faster. If you want to write
- Kerbang scripts that depend on the initialization file, include the
- command
-
- take \v(home).kermrc
-
- at the desired spot in the script. By the way, \v(xxx) is a built-in
- variable (xxx is the variable name, "home" in this case). To see what
- built-in variables are available, type "show variables" at the C-Kermit
- prompt. To see what else you can show, type "show ?". \m(xxx) is a user
- defined variable (strictly speaking, it is a macro used as a variable).
-
-Command List
-
- C-Kermit has more than 200 top-level commands, and some of these, such
- as SET, branch off into hundreds of subcommands of their own, so it's
- not practical to describe them all here. Instead, here's a concise list
- of the most commonly used top-level commands, grouped by category. To
- learn about each command, type "help" followed by the command name,
- e.g. "help set". Terms such as Command state and Connect state are
- explained in subsequent sections.
-
- Optional fields are shown in [ italicized brackets ]. filename means
- the name of a single file. filespec means a file specification that is
- allowed to contain wildcard characters like '*' to match groups of
- files. options are (optional) switches like /PAGE, /NOPAGE, /QUIET,
- etc, listed in the HELP text for each command. Example:
-
- send /recursive /larger:10000 /after:-1week /except:*.txt *
-
- which can be read as "send all the files in this directory and all the
- ones underneath it that are larger than 10000 bytes, no more than one
- week old, and whose names don't end with ".txt".
-
- Basic Commands
-
- HELP Requests top-level help.
- HELP command Requests help about the given command.
- INTRODUCTION Requests a brief introduction to C-Kermit.
- LICENSE Displays the C-Kermit software copyright and license.
- VERSION Displays C-Kermit's version number.
- EXIT [ number ] Exits from Kermit with the given status code. Synonyms:
- QUIT, E, Q.
- TAKE filename [ parameters... ] Executes commands from the given file.
- LOG item [ filename ] Keeps a log of the given item in the given file.
- [ DO ] macro [ parameters... ] Executes commands from the given
- macro.
- SET parameter value Sets the given parameter to the given value.
- SHOW category Shows settings in a given category.
- STATUS Tells whether previous command succeeded or failed.
- DATE [ date-and/or-time ] Shows current date-time or interprets given
- date-time.
- RUN [ extern-command [ parameters... ] Runs the given external command.
- Synonym: !.
- EXEC [ extern-command [ params... ] Kermit overlays itself with the
- given command.
- SUSPEND Stops Kermit and puts it in the background. Synonym: Z.
-
- Local File Management
-
- TYPE [ options ] filename Displays the contents of the given file.
- MORE [ options ] filename Equivalent to TYPE /PAGE (pause after each
- screenful).
- CAT [ options ] filename Equivalent to TYPE /NOPAGE.
- HEAD [ options ] filename Displays the first few lines of a given file.
- TAIL [ options ] filename Displays the last few lines of a given file.
- GREP [ options ] pattern filespec Displays lines from files that match
- the pattern. Synonym: FIND.
- DIRECTORY [ options ] [ filespec ] Lists files (built-in, many
- options).
- LS [ options ] [ filespec ] Lists files (runs external "ls" command).
- DELETE [ options ] [ filespec ] Deletes files. Synonym: RM.
- PURGE [ options ] [ filespec ] Removes backup (*.~n~) files.
- COPY [ options ] [ filespecs... ] Copies files. Synonym: CP.
- RENAME [ options ] [ filespecs... ] Renames files. Synonym: MV.
- CHMOD [ options ] [ filespecs... ] Changes permissions of files.
- TRANSLATE filename charsets filename ] Converts file's character set.
- Synonym: XLATE.
- CD Changes your working directory to your home directory.
- CD directory Changes your working directory to the one given.
- CDUP Changes your working directory one level up.
- PWD Displays your working directory.
- BACK Returns to your previous working directory.
- MKDIR [ directory ] Creates a directory.
- RMDIR [ directory ] Removes a directory.
-
- Making Connections
-
- SET LINE [ options ] devicename Opens the named serial port.
- Synonym: SET PORT.
- OPEN LINE [ options ] devicename Same as SET LINE. Synonym: OPEN PORT.
- SET MODEM TYPE [ name ] Tells Kermit what kind of modem is on the port.
- DIAL [ number ] Tells Kermit to dial the given phone number with the
- modem.
- REDIAL Redials the most recently dialed phone number.
- ANSWER Waits for and answers an incoming call on the modem.
- AUTHENTICATE [ parameters... ] Performs secure authentication on a
- TCP/IP connection.
- SET NETWORK TYPE { TCP/IP, X.25, ... } Selects network type for
- subsequent SET HOST commands.
- SET HOST [ options ] host [ port ] Opens a network connection to the
- given host and port.
- SET HOST [ options ] * port Waits for an incoming TCP/IP connection on
- the given port.
- TELNET [ options ] host Opens a Telnet connection to the host and
- enters Connect state.
- RLOGIN [ options ] host Opens an Rlogin connection to the host and
- enters Connect state.
- IKSD [ options ] host Opens a connection to an Internet Kermit Service.
- SSH [ options ] host Opens an SSH connection to the host and enters
- Connect state.
- FTP OPEN host [ options ] Opens an FTP connection to the host.
- HTTP [ options ] OPEN host Opens an HTTP connection to the host.
- PTY external-command Runs the command on a pseudoterminal as if it were
- a connection.
- PIPE external-command Runs the command through a pipe as if it were a
- connection.
-
- Using Connections
-
- CONNECT [ options ] Enters Connect (terminal) state.
- Synonym: C.
- REDIRECT command Redirects the given external command over the
- connection.
- TELOPT command Sends a Telnet protocol command (Telnet connections
- only).
- Ctrl-\C "Escapes back" from Connect state to Command state.
- Ctrl-\B (In Connect state) Sends a BREAK signal (serial or Telnet).
- Ctrl-\! (In Connect state) Enters inferior shell; "exit" to return.
- Ctrl-\? (In Connect state) Shows a menu of other escape-level options.
- Ctrl-\Ctrl-\ (In Connect state) Type two Ctrl-Backslashes to send one
- of them.
- SET ESCAPE [ character ] Changes Kermit's Connect-state escape
- character.
-
- Closing Connections
-
- HANGUP Hangs up the currently open serial-port or network connection.
- CLOSE Closes the currently open serial-port or network connection.
- SET LINE (with no devicename) Closes the currently open
- serial-port or network connection.
- SET HOST (with no hostname) Closes the currently open serial-port or
- network connection.
- FTP CLOSE Closes the currently open FTP connection.
- HTTP CLOSE Closes the currently open HTTP connection.
- EXIT Also closes all connections. Synonym: QUIT.
- SET EXIT WARNING OFF Suppresses warning about open connections on exit
- or close.
-
- File Transfer
-
- SEND [ options ] filename [ as-name ] Sends the given file. Synonym:
- S.
- SEND [ options ] filespec Sends all files that match.
- RESEND [ options ] filespec Resumes an interrupted SEND from the point
- of failure.
- RECEIVE [ options ] [ as-name ] Waits passively for files to arrive.
- Synonym: R.
- LOG TRANSACTIONS [ filename ] Keeps a record of file transfers.
- FAST Use fast file-transfer settings (default).
- CAUTIOUS Use cautious and less fast file-transfer settings.
- ROBUST Use ultra-conservative and slow file-transfer settings.
- STATISTICS [ options ] Gives statistics about the most recent file
- transfer.
- WHERE After transfer: "Where did my files go?".
- TRANSMIT [ options ] [ filename ] Sends file without protocol. Synonym:
- XMIT.
- LOG SESSION [ filename ] Captures remote text or files without
- protocol.
- SET PROTOCOL [ name... ] Tells Kermit to use an external file-transfer
- protocol.
- FTP { PUT, MPUT, GET, MGET, ... } FTP client commands.
- HTTP { PUT, GET, HEAD, POST, ... } HTTP client commands.
-
- Kermit Server
-
- ENABLE, DISABLE Controls which features can be
- used by clients.
- SET SERVER Sets parameters prior to entering Server state.
- SERVER Enters Server state.
-
- Client of Kermit or FTP Server
-
- [ REMOTE ] LOGIN [ user password ] Logs in to a Kermit server or IKSD
- that requires it.
- [ REMOTE ] LOGOUT Logs out from a Kermit server or IKSD.
- SEND [ options ] filename [ as-name ] Sends the given file to the
- server. Synonyms: S, PUT.
- SEND [ options ] filespec Sends all files that match.
- RESEND [ options ] filespec Resumes an interrupted SEND from the point
- of failure.
- GET [ options ] remote-filespec Asks the server to send the given
- files. Synonym: G.
- REGET [ options ] remote-filespec Resumes an interrupted GET from the
- point of failure.
- REMOTE CD [ directory ] Asks server to change its working directory.
- Synonym: RCD.
- REMOTE PWD [ directory ] Asks server to display its working directory.
- Synonym: RPWD.
- REMOTE DIRECTORY [ filespec... ] Asks server to send a directory
- listing. Synonym: RDIR.
- REMOTE DELETE [ filespec... ] Asks server to delete files. Synonym:
- RDEL.
- REMOTE [ command... ] (Many other commands: "remote ?" for a list).
- MAIL [ options ] filespec Sends file(s) to be delivered as e-mail
- (Kermit only).
- FINISH Asks the server to exit server state (Kermit only).
- BYE Asks the server to log out and close the connection.
-
- Script Programming
- DEFINE, DECLARE, UNDEFINE, UNDECLARE, ASSIGN, EVALUATE,
- SEXPRESSION, ARRAY, SORT, INPUT, OUTPUT, IF, FOR, WHILE, SWITCH,
- GOTO, ECHO, ASK, GETC, GETOK, ASSERT, WAIT, SLEEP, FOPEN, FREAD,
- FWRITE, FCLOSE, STOP, END, RETURN, LEARN, SHIFT, TRACE, VOID,
- INCREMENT, DECREMENT, ... For these and many more you'll need to
- consult the [79]manual and supplements, and/or visit the
- [80]Kermit Script Library, which also includes a brief tutorial.
- Hint: HELP LEARN to find out how to get Kermit to write simple
- scripts for you.
-
- Many of Kermit's commands have synonyms, variants, relatives, and so
- on. For example, MSEND is a version of SEND that accepts a list of file
- specifications to be sent, rather than just one file specification, and
- MPUT is a synonym of MSEND. MOVE means to SEND and then DELETE the
- source file if successful. MMOVE is like MOVE, but accepts a list of
- filespecs, and so on. These are described in the [81]full
- documentation.
-
- Use question mark to feel your way through an unfamiliar command, as in
- this example (the part you type is underlined):
-
- C-Kermit> remote ? One of the following:
- assign delete help login print rename space
- cd directory host logout pwd rmdir type
- copy exit kermit mkdir query set who
- C-Kermit> remote set ? One of the following:
- attributes file retry transfer
- block-check receive server window
- C-Kermit> remote set file ? One of the following:
- character-set incomplete record-length
- collision names type
- C-Kermit> remote set file names ? One of the following:
- converted literal
- C-Kermit> remote set file names literal
- C-Kermit>
-
- This is called menu on demand: you get a menu when you want one, but
- menus are not forced on you even when know what you're doing. Note that
- you can also abbreviate most keywords, and you can complete them with
- the Tab or Esc key. Also note that ? works for filenames too, and that
- you can use it in the middle of a keyword or filename, not just at the
- beginning. For example, "send x?" lists all the files in the current
- directory whose names start with 'x'.
-
- [82]Kermit Home [83]C-Kermit Home [84]C-Kermit FAQ
-
-INITIALIZATION FILE
-
- [85]Top [86]Contents [87]Next [88]Previous
-
- In its default configuration, C-Kermit executes commands from a file
- called .kermrc in your home directory when it starts, unless it is
- given the -Y or -y command-line option. Custom configurations might
- substitute a shared system-wide initialization file. The SHOW FILE
- command tells what initialization file, if any, was used. The standard
- initialization file "chains" to an individual customization file,
- .mykermc, in the home directory, in which each user can establish
- her/his own preferences, define macros, and so on.
-
- Since execution of the initialization file (at least the standard one)
- makes C-Kermit take longer to start, it might be better not to have an
- initialization file, especially now that Kermit's default startup
- configuration is well attuned to modern computing and networking -- in
- other words, you no longer have do anything special to make Kermit
- transfers go fast. So instead of having an initialization file that is
- executed every time Kermit starts, you might consider making one or
- more kerbang scripts (with names other that .kermrc) that do NOT
- include an "exit" command, and invoke those when you need the settings,
- macro definitions, and/or scripted actions they contain, and invoke
- C-Kermit directly when you don't.
-
- To put it another way... We still distribute the standard
- initialization file since it's featured in the manual and backwards
- compatibility is important to us. But there's no harm in not using it
- if you don't need the stuff that's in it (services directory, dialing
- directory, network directory, and associated macro definitions). On the
- other hand, if there are settings or macros you want in effect EVERY
- time you use Kermit, the initialization file (or the customization file
- it chains to) is the place to put them, because that's the only place
- Kermit looks for them automatically each time you start it.
-
- [89]Kermit Home [90]C-Kermit Home [91]C-Kermit FAQ
-
-MODES OF OPERATION
-
- [92]Top [93]Contents [94]Next [95]Previous
-
- Kermit is said to be in Local mode if it has made a connection to
- another computer, e.g. by dialing it or establishing a Telnet
- connection to it. The other computer is remote, so if you start another
- copy of Kermit on the remote computer, it is said to be in Remote mode
- (as long as it has not made any connections of its own). The local
- Kermit communicates over the communications device or network
- connection, acting as a conduit between the the remote computer and
- your keyboard and screen. The remote Kermit is the file-transfer
- partner to the local Kermit and communicates only through its standard
- input and output.
-
- At any moment, a Kermit program can be in any of the following states.
- It's important to know what they are and how to change from one to the
- other.
-
- Command state
- In this state, Kermit reads commands from:
-
- + Your keyboard; or:
- + A file, or:
- + A macro definition.
-
- You can exit from Command state back to Unix with the EXIT or
- QUIT command (same thing). You can enter Connect state with any
- of various commands (CONNECT, DIAL, TELNET, etc). You can enter
- file transfer state with commands like SEND, RECEIVE, and GET.
- You can enter Server state with the SERVER command. The TAKE
- command tells Kermit to read and execute commands from a file.
- The (perhaps implied) DO command tells Kermit to read and
- execute commands from a macro definition. While in Command
- state, you can interrupt any command, macro, or command file by
- typing Ctrl-C (hold down the Ctrl key and press the C key); this
- normally brings you back to the prompt.
-
- Shell state
- You can invoke an inferior shell or external command from the
- Kermit command prompt by using the PUSH, RUN (!), EDIT, or
- BROWSE command. While the inferior shell or command is active,
- Kermit is suspended and does nothing. Return to Kermit Command
- state by exiting from the inferior shell or application.
-
- Connect state
- In this state, which can be entered only when in Local mode
- (i.e. when Kermit has made a connection to another computer),
- Kermit is acting as a terminal to the remote computer. Your
- keystrokes are sent to the remote computer and characters that
- arrive over the communication connection are displayed on your
- screen. This state is entered when you give a CONNECT, DIAL,
- TELNET, RLOGIN, or IKSD command. You can return to command state
- by logging out of the remote computer, or by typing:
-
- Ctrl-\c
-
- That is: Hold down the Ctrl key and press the backslash key,
- then let go of the Ctrl key and press the C key. This is called
- escaping back. Certain other escape-level commands are also
- provided; type Ctrl-\? for a list. For example, you can enter
- Shell state with:
-
- Ctrl-\!
-
- To send a Ctrl-\ to the host while in Connect state, type two of
- them in a row. See HELP CONNECT and HELP SET ESCAPE for more
- info.
-
- Local file-transfer state
- In this state, Kermit is sending packets back and forth with the
- other computer in order to transfer a file or accomplish some
- other file-related task. And at the same time, it is displaying
- its progress on your screen and watching your keyboard for
- interruptions. In this state, the following single-keystroke
- commands are accepted:
-
- X Interrupt the current file and go on to the next (if any).
- Z Interrupt the current file and skip all the rest.
- E Like Z but uses a "stronger" protocol (use if X or Z don't work).
- Ctrl-C Interrupt file-transfer mode (use if Z or E don't work).
-
- Kermit returns to its previous state (Command or Connect) when
- the transfer is complete or when interrupted successfully by X,
- Z, E, or Ctrl-C (hold down the Ctrl key and press the C key).
-
- Remote file-transfer state
- In this state, Kermit is exchanging file-transfer packets with
- its local partner over its standard i/o. It leaves this state
- automatically when the transfer is complete. In case you find
- your local Kermit in Connect state and the remote one in
- File-transfer state (in which it seems to ignore your
- keystrokes), you can usually return it to command state by
- typing three Ctrl-C's in a row. If that doesn't work, return
- your local Kermit to Command state (Ctrl-\ C) and type
- "e-packet" and then press the Return or Enter key; this forces a
- fatal Kermit protocol error.
-
- Remote Server state
- This is like Remote File-transfer state, except it never returns
- automatically to Command state. Rather, it awaits further
- instructions from the client program; that is, from your Local
- Kermit program. You can return the Remote Server to its previous
- state by issuing a "finish" command to the client, or if you are
- in Connect state, by typing three Ctrl-C's in a row. You can
- tell the server job to log out and break the connection by
- issuing a "bye" command to the client.
-
- Local Server state
- Like Remote-Server state, but in local mode, and therefore with
- its file-transfer display showing, and listening for single-key
- commands, as in Local File-transfer state. Usually this state is
- entered automatically when a remote Kermit program gives a GET
- command.
-
- C-Kermit, Kermit 95, and MS-DOS Kermit all can switch automatically
- from Connect state to Local File-transfer state when you initiate a
- file transfer from the remote computer by starting Kermit and telling
- it to send or get a file, in which case, Connect state is automatically
- resumed after the file transfer is finished.
-
- Note that C-Kermit is not a terminal emulator. It is a communications
- application that you run in a terminal window (e.g. console or Xterm).
- The specific emulation, such as VT100, VT220, Linux Console, or Xterm,
- is provided by the terminal window in which you are running C-Kermit.
- Kermit 95 and MS-DOS Kermit, on the other hand, are true terminal
- emulators. Why is C-Kermit not a terminal emulator? [96]CLICK HERE to
- read about it.
-
- [97]Kermit Home [98]C-Kermit Home [99]C-Kermit FAQ
-
-MAKING CONNECTIONS
-
- [100]Top [101]Contents [102]Next [103]Previous
-
- Here is how to make different kinds of connections using interactive
- Kermit commands (as noted above, you can also make connections with
- command-line options). Note that you don't have to make connections
- with Kermit. It can also be used on the far end of a connection as the
- remote file transfer and management partner of your local
- communications software.
-
- Making a Telnet Connection
- At the C-Kermit command prompt, simply type:
-
- telnet foo.bar.com ; Substitute desired host name or address.
- telnet xyzcorp.com 3000 ; You can also include a port number.
-
- If the connection is successful, Kermit automatically enters
- Connect state. When you logout from the remote host, Kermit
- automatically returns to its prompt. More info: HELP TELNET,
- HELP SET TELNET, HELP SET TELOPT. Also see the [104]IKSD section
- below.
-
- Making an Rlogin connection
- This is just like Telnet, except you have to be root to do it
- because Rlogin uses a privileged TCP port:
-
- rlogin foo.bar.com ; Substitute desired host name or address.
-
- More info: HELP RLOGIN.
-
- Making an SSH Connection
- Unlike Telnet and Rlogin, SSH connections are not built-in, but
- handled by running your external SSH client through a
- pseudoterminal. Using C-Kermit to control the SSH client gives
- you all of Kermit's features (file transfer, character-set
- conversion, scripting, etc) over SSH.
-
- ssh foo.bar.com ; Substitute desired host name or address.
-
- More info: HELP SSH, HELP SET SSH.
-
- Dialing with a Modem
- If it's an external modem, make sure it is connected to a usable
- serial port on your computer with a regular (straight-through)
- [105]modem cable, and to the telephone jack with a telephone
- cable, and that it's turned on. Then use these commands:
-
- set modem type usrobotics ; Or other supported type
- set line /dev/ttyS0 ; Specify device name
- set speed 57600 ; Or other desired speed
- set flow rts/cts ; Most modern modems support this
- set dial method tone ; (or pulse)
- dial 7654321 ; Dial the desired number
-
- Type "set modem type ?" for a list of supported modem types. If
- you omit the SET MODEM TYPE command, the default type is
- "generic-high-speed", which should work for most modern
- AT-command-set modems. If the line is busy, Kermit redials
- automatically. If the call does not succeed, use "set dial
- display on" and try it again to watch what happens. If the call
- succeeds, Kermit enters Connect state automatically and returns
- to its prompt automatically when you log out from the remote
- computer or the connection is otherwise lost.
-
- You can also dial from a modem that is accessible by Telnet,
- e.g. to a reverse terminal server. In this case the command
- sequence is:
-
- set host ts.xxx.com 2000 ; Terminal-server and port
- set modem type usrobotics ; Or other supported type
- set dial method tone ; (or pulse)
- dial 7654321 ; Dial the desired number
-
- If the terminal server supports the Telnet Com Port Option,
- [106]RFC 2217, you can also give serial-port related commands
- such as SET SPEED, SET PARITY, and so on, and Kermit relays them
- to the terminal server using the protocol specified in the RFC.
-
- More info: HELP SET MODEM, HELP SET LINE, HELP SET SPEED, HELP
- SET FLOW, HELP DIAL, HELP SET DIAL, HELP SET MODEM, HELP SET
- CARRIER-WATCH, SHOW COMMUNICATIONS, SHOW MODEM, SHOW DIAL.
-
- Direct Serial Port
- Connect the two computers, A and B, with a [107]null modem cable
- (or two modem cables interconnected with a null-modem adapter or
- modem eliminator). From Computer A:
-
- set modem type none ; There is no modem
- set line /dev/ttyS0 ; Specify device name
- set carrier-watch off ; If DTR and CD are not cross-connected
- set speed 57600 ; Or other desired speed
- set flow rts/cts ; If RTS and CTS are cross-connected
- set flow xon/xoff ; If you can't use RTS/CTS
- set parity even ; (or "mark" or "space", if necessary)
- set stop-bits 2 ; (rarely necessary)
- connect ; Enter Connect (terminal) state
-
- This assumes Computer B is set up to let you log in. If it
- isn't, you can run a copy of Kermit on Computer B and follow
- approximately the same directions. More info: As above plus HELP
- CONNECT.
-
- With modems or direct serial connections, you might also have to "set
- parity even" (or "mark" or "space") if it's a 7-bit connection.
-
- Of the connection types listed above, only one can be open at a time.
- However, any one of these can be open concurrently with an [108]FTP or
- HTTP session. Each connection type can be customized to any desired
- degree, scripted, logged, you name it. See the manual.
-
- NOTE: On selected platforms, C-Kermit also can make X.25 connections.
- See the manual for details.
-
- [109]Kermit Home [110]C-Kermit Home [111]C-Kermit FAQ
-
-TRANSFERRING FILES WITH KERMIT
-
- [112]Top [113]Contents [114]Next [115]Previous
-
- * [116]Downloading Files
- * [117]Uploading Files
- * [118]Kermit Transfers the Old-Fashioned Way
- * [119]If File Transfer Fails
- * [120]Advanced Kermit File Transfer Features
- * [121]Non-Kermit File Transfer
-
- There is a [122]widespread and persistent belief that Kermit is a slow
- protocol. This is because, until recently, it used conservative tuning
- by default to make sure file transfers succeeded, rather than failing
- because they overloaded the connection. Some extra commands (or
- command-line options, like -Q) were needed to make it go fast, but
- nobody bothered to find out about them. Also, it takes two to tango:
- most non-Kermit-Project Kermit protocol implementations really ARE
- slow. The best file-transfer partners for C-Kermit are: another copy of
- [123]C-Kermit (7.0 or later) and [124]Kermit 95. These combinations
- work well and they work fast by default. MS-DOS Kermit is good too, but
- you have to tell it to go fast (by giving it the FAST command).
-
- Furthermore, all three of these Kermit programs support "autodownload"
- and "autoupload", meaning that when they are in Connect state and a
- Kermit packet comes in from the remote, they automatically switch into
- file transfer mode.
-
- And plus, C-Kermit and K95 also switch automatically between text and
- binary mode for each file, so there is no need to "set file type
- binary" or "set file type text", or to worry about files being
- corrupted because they were transferred in the wrong mode.
-
- What all of these words add up to is that now, when you use up-to-date
- Kermit software from the Kermit Project, file transfer is not only
- fast, it's ridiculously easy. You barely have to give any commands at
- all.
-
- Downloading Files
- Let's say you have [125]Kermit 95, [126]C-Kermit, or [127]MS-DOS
- Kermit on your desktop computer, with a connection to a Unix
- computer that has C-Kermit installed as "kermit". To download a
- file (send it from Unix to your desktop computer), just type the
- following command at your Unix shell prompt:
-
- kermit -s oofa.txt
-
- (where oofa.txt is the filename). If you want to send more than
- one file, you can put as many filenames as you want on the
- command line, and they can be any combination of text and
- binary:
-
- kermit -s oofa.txt oofa.zip oofa.html oofa.tar.gz
-
- and/or you can use wildcards to send groups of files:
-
- kermit -s oofa.*
-
- If you want to send a file under an assumed name, use:
-
- kermit -s friday.txt -a today.txt
-
- This sends the file friday.txt but tells the receiving Kermit
- that its name is today.txt. In all cases, as noted, when the
- file transfer is finished, your desktop Kermit returns
- automatically to Connect state. No worries about escaping back,
- re-connecting, text/binary mode switching. Almost too easy,
- right?
-
- Uploading Files
- To upload files (send them from your desktop computer to the
- remote Unix computer) do the same thing, but use the -g (GET)
- option instead of -s:
-
- kermit -g oofa.txt
-
- This causes your local Kermit to enter server mode; then the
- remote Kermit program requests the named file and the local
- Kermit sends it and returns automatically to Connect state when
- done.
-
- If you want to upload multiple files, you have have use shell
- quoting rules, since these aren't local files:
-
- kermit -g "oofa.txt oofa.zip oofa.html oofa.tar.gz"
- kermit -g "oofa.*"
-
- If you want to upload a file but store it under a different
- name, use:
-
- kermit -g friday.txt -a today.txt
-
- Kermit Transfers the Old-Fashioned Way
- If your desktop communications software does not support
- autoupload or autodownload, or it does not include Kermit server
- mode, the procedure requires more steps.
-
- To download a file, type:
-
- kermit -s filename
-
- on the host as before, but if nothing happens automatically in
- response to this command, you have to switch your desktop
- communications software into Kermit Receive state. This might be
- done by escaping back using keyboard characters or hot keys
- (Alt-x is typical) and/or with a command (like RECEIVE) or a
- menu. When the file transfer is complete, you have to go back to
- Connect state, Terminal emulation, or whatever terminology
- applies to your desktop communications software.
-
- To upload a file, type:
-
- kermit -r
-
- on the host (rather than "kermit -g"). This tells C-Kermit to
- wait passively for a file to start arriving. Then regain the
- attention of your desktop software (Alt-x or whatever) and
- instruct it to send the desired file(s) with Kermit protocol.
- When the transfer is finished, return to the Connect or Terminal
- screen.
-
- If File Transfer Fails
- Although every aspect of Kermit's operation can be finely tuned,
- there are also three short and simple "omnibus tuning" commands
- you can use for troubleshooting:
-
- FAST
- Use fast file-transfer settings. This has been the default
- since C-Kermit 7.0 now that most modern computers and
- connections support it. If transfers fail with fast
- settings, try . . .
-
- CAUTIOUS
- Use cautious but not paranoid settings. File transfers, if
- they work, will go at medium speed. If not, try . . .
-
- ROBUST
- Use the most robust, resilient, conservative, safe, and
- reliable settings. File transfers will almost certainly
- work, but they will be quite slow (of course this is a
- classic tradeoff; ROBUST was C-Kermit's default tuning in
- versions 6.0 and earlier, which made everybody think
- Kermit protocol was slow). If ROBUST doesn't do the trick,
- try again with SET PARITY SPACE first in case it's not an
- 8-bit connection.
-
- Obviously the success and performance of a file transfer also
- depends on C-Kermit's file transfer partner. Up-to-date, real
- [128]Kermit Project partners are recommended because they
- contain the best Kermit protocol implementations and because
- [129]we can support them in case of trouble.
-
- If you still have trouble, consult Chapter 10 of [130]Using
- C-Kermit, or send email to [131]kermit-support@columbia.edu.
-
- Advanced Kermit File-Transfer Features
- Obviously there is a lot more to Kermit file transfer, including
- all sorts of interactive commands, preferences, options,
- logging, debugging, troubleshooting, and anything else you can
- imagine but that's what the [132]manual and updates are for.
- Here are a few topics you can explore if you're interested by
- Typing HELP for the listed commands:
-
- Logging transfers:
- LOG TRANSACTIONS (HELP LOG)
-
- Automatic per-file text/binary mode switching:
- SET TRANSFER MODE { AUTOMATIC, MANUAL } (HELP SET
- TRANSFER).
-
- Cross-platform recursive directory tree transfer:
- SEND /RECURSIVE, GET /RECURSIVE (HELP SEND, HELP GET).
-
- File collision options:
- SET FILE COLLISION { OVERWRITE, BACKUP, DISCARD, ... }
- (HELP SET FILE).
-
- Update mode (only transfer files that changed since last time):
- SET FILE COLLISION UPDATE (HELP SET FILE).
-
- Filename selection patterns:
- (HELP WILDCARD).
-
- Flexible file selection:
- SEND (or GET) /BEFORE /AFTER /LARGER /SMALLER /TYPE
- /EXCEPT, ...
-
- Character-set conversion:
- SET { FILE, TRANSFER } CHARACTER-SET, ASSOCIATE, ...
-
- File/Pathname control:
- SET { SEND, RECEIVE } PATHNAMES, SET FILE NAMES.
-
- Atomic file movement:
- SEND (or GET) /DELETE /RENAME /MOVE-TO
-
- Transferring to/from standard i/o of other commands:
- SEND (or GET) /COMMAND
-
- Recovery of interrupted transfer from point of failure:
- RESEND, REGET (HELP RESEND, HELP REGET).
-
- Non-Kermit File Transfer
- You can also use C-Kermit to transfer files with FTP or HTTP
- Internet protocols; [133]see below.
-
- On a regular serial or Telnet connection where the other
- computer doesn't support Kermit protocol at all, you have
- several options. For example, if your desktop communications
- software supports Zmodem, use "rz" and "sz" on the host rather
- than Kermit. But if Kermit is your desktop software, and you are
- using it to make calls or network connections to other computers
- that don't support Kermit protocol (or that don't have a good
- implementation of it), then if your computer also has external
- X, Y, or Zmodem programs that are redirectable, Kermit can use
- them as external protocols. HELP SET PROTOCOL for details.
-
- You can also capture "raw" data streams from the other computer
- with LOG SESSION (HELP LOG and HELP SET SESSION-LOG for
- details), and you can upload files without any protocol at all
- with TRANSMIT (HELP TRANSMIT, HELP SET TRANSMIT).
-
- [134]Kermit Home [135]C-Kermit Home [136]C-Kermit FAQ
-
-KERMIT CLIENT/SERVER CONNECTIONS
-
- [137]Top [138]Contents [139]Next [140]Previous
-
- On any kind of connection you can make with Kermit -- serial, TCP/IP,
- X.25, etc -- you can set up a convenient client/server relationship
- between your Kermit client (the one that made the connection) and the
- Kermit program on the far end of the connection (the remote Kermit) by
- putting the remote Kermit in server mode. This is normally done by
- giving it a SERVER command, or by starting it with the -x command-line
- option. In some cases ([141]Internet Kermit Service, SSH connections to
- a Kermit subsystem, or specially configured hosts), there is already a
- Kermit server waiting on the far end. Here is a quick synopsis of the
- commands you can give to the client for interacting with the server:
-
- SEND [ switches ] filename
- Sends the named file to the server. The filename can include
- wildcards. Lots of switches are available for file selection,
- etc. Type HELP SEND at the client prompt for details.
-
- GET [ switches ] filename
- Asks the server to send the named file. The filename can include
- wildcards. Type HELP GET at the client prompt for details.
-
- BYE
- Terminates the server and closes your connection to it.
-
- FINISH
- Terminates the server. If you started the server yourself, this
- leaves the remote host at its shell prompt. If it was a
- dedicated server (such as IKSD or an SSH subsystem), FINISH is
- equivalent to BYE.
-
- SET LOCUS { LOCAL, REMOTE, AUTO }
- (C-Kermit 8.0.201 and later, K95 1.1.21 and later) This tells
- the client whether file-management commands like CD, PWD,
- DIRECTORY, DELETE, MKDIR, etc, should be executed locally or by
- the server. In this type of connection, the default is LOCAL.
- Use SET LOCUS REMOTE if you want Kermit to behave like an FTP
- client, in which case these commands are executed remotely, and
- their local versions must have an L prefix: LCD, LPWD,
- LDIRECTORY, etc. When LOCUS is LOCAL, then the remote versions
- must have an R prefix: RCD, RPWD, RDIRECTORY, etc. HELP SET
- LOCUS for details. SHOW COMMAND to see current locus.
-
- The following commands are affected by SET LOCUS:
-
- CD, LCD, RCD
- Change (working, current) directory. HELP CD for details.
-
- CDUP, LCDUP, RCDUP
- CD one level up.
-
- DIRECTORY, LDIRECTORY, RDIRECTORY
- Produce a directory listing. Many options are available for
- local listings. HELP DIRECTORY for details.
-
- DELETE, LDELETE, RDELETE
- Deletes files or directories. Many options available, HELP
- DELETE.
-
- RENAME, LRENAME, RRENAME
- Renames files or directories. Many options available, HELP
- RENAME.
-
- MKDIR, LMKDIR, RMKDIR
- Creates a directory. HELP MKDIR.
-
- RMDIR, LRMDIR, RRMDIR
- Removes a directory. HELP RMDIR.
-
- There are dozens -- maybe hundreds -- of other commands, described in
- the built-in help, on the website, and/or in the published or online
- manuals. But even if you don't have access to documentation, you can
- "set locus remote" and then use pretty much the same commands you would
- use with any FTP client.
-
- [142]Kermit Home [143]C-Kermit Home [144]C-Kermit FAQ
-
-KERMIT'S BUILT-IN FTP AND HTTP CLIENTS
-
- [145]Top [146]Contents [147]Next [148]Previous
-
- Kermit's FTP client is like the regular Unix FTP client that you're
- used to, but with some differences:
-
- * It has lots more commands and features.
- * You can have an FTP session and a regular Kermit serial or Telnet
- session open at the same time.
- * FTP sessions can be fully automated.
-
- By default Kermit's FTP client tries its best to present the same user
- interface as a regular FTP client: PUT, GET, DIR, CD, BYE, etc, should
- work the same, even though some of these commands have different
- meaning in Kermit-to-Kermit connections; for example, CD, DIR, RENAME,
- etc, in Kermit act locally, whereas in FTP they are commands for the
- server. This might cause some confusion, but as in all things Kermit,
- you have total control:
-
- * The [149]SET LOCUS command lets you specify where file management
- commands should be executed -- locally or remotely -- for any kind
- of connection.
- * Any FTP command can be prefixed with the word "FTP" to remove any
- ambiguity.
-
- Pending publication of the next edition of the manual, the Kermit FTP
- client is thoroughly documented at the Kermit Project website:
-
- [150]http://www.columbia.edu/kermit/ftpclient.html
-
- You also can use HELP FTP and HELP SET FTP to get descriptions of
- Kermit's FTP-related commands.
-
- The HTTP client is similar to the FTP one, except you prefix each
- command with HTTP instead of FTP: HTTP OPEN, HTTP GET, HTTP PUT, HTTP
- CLOSE, etc. Type HELP HTTP for details, or visit the to view the
- [151]manual supplements. HTTP connections can be open at the same time
- as regular serial or Telnet connections and FTP connections. So Kermit
- can manage up to three types connections simultaneously.
-
- [152]Kermit Home [153]C-Kermit Home [154]C-Kermit FAQ [155]FTP Client
- [156]HTTP Client
-
-INTERNET KERMIT SERVICE
-
- [157]Top [158]Contents [159]Next [160]Previous
-
- C-Kermit can be configured and run as an Internet service (called
- IKSD), similar to an FTP server (FTPD) except you can (but need not)
- interact with it directly, plus it does a lot more than an FTP server
- can do. The TCP port for IKSD is 1649. It uses Telnet protocol.
- C-Kermit can be an Internet Kermit Server, or it can be a client of an
- IKSD. You can make connections from C-Kermit to an IKSD with any of the
- following commands:
-
- telnet foo.bar.edu 1649
- telnet foo.bar.edu kermit ; if "kermit" is listed in /etc/services
- iksd foo.bar.edu
-
- The IKSD command is equivalent to a TELNET command specifying port
- 1649. For more information about making and using connections to an
- IKSD, see:
-
- [161]http://www.columbia.edu/kermit/cuiksd.html
-
- You can run an Internet Kermit Service on your own computer too (if you
- are the system administrator). For instructions, see:
-
- [162]http://www.columbia.edu/kermit/iksd.html
-
- [163]Kermit Home [164]C-Kermit Home [165]C-Kermit FAQ
-
-SECURITY
-
- [166]Top [167]Contents [168]Next [169]Previous
-
- All of C-Kermit's built-in TCP/IP networking methods (Telnet, Rlogin,
- IKSD, FTP, and HTTP) can be secured by one or more of the following
- IETF-approved methods:
-
- * MIT Kerberos IV
- * MIT Kerberos V
- * SSL/TLS
- * Stanford SRP
-
- For complete instructions see:
-
- [170]http://www.columbia.edu/kermit/security.html
-
- And as noted previously, you can also make SSH connections with
- C-Kermit if you already have an SSH client installed.
-
- [171]Kermit Home [172]C-Kermit Home [173]C-Kermit FAQ
-
-ALTERNATIVE COMMAND-LINE PERSONALITIES
-
- [174]Top [175]Contents [176]Next [177]Previous
-
- When invoked as "kermit" or any other name besides any of the special
- ones, C-Kermit has the command-line options described above in the
- [178]OPTIONS section. However, if you invoke C-Kermit using any of the
- following names:
-
- telnet Telnet client
- ftp FTP client
- http HTTP client
- https Secure HTTP client
-
- Kermit's command-line personality changes to match. This can be done
- (among other ways) with symbolic links (symlinks). For example, if you
- want C-Kermit to be your regular Telnet client, or the Telnet helper of
- your Web browser, you can create a link like the following in a
- directory that lies in your PATH ahead of the regular telnet program:
-
- ln -s /usr/local/bin/kermit telnet
-
- Now when you give a "telnet" command, you are invoking Kermit instead,
- but with its Telnet command-line personality so, for example:
-
- telnet xyzcorp.com
-
- Makes a Telnet connection to xyzcorp.com, and Kermit exits
- automatically when the connection is closed (just like the regular
- Telnet client). Type "telnet -h" to get a list of Kermit's
- Telnet-personality command-line options, which are intended to be as
- compatible as possible with the regular Telnet client.
-
- Similarly for FTP:
-
- ln -s /usr/local/bin/kermit ftp
-
- And now type "ftp -h" to see its command-line options, and use command
- lines just like you would give your regular FTP client:
-
- ftp -n xyzcorp.com
-
- but with additional options allowing an entire session to be specified
- on the command line, as explained in the C-Kermit [179]FTP client
- documentation.
-
- And similarly for HTTP:
-
- ln -s /usr/local/bin/kermit http
- ./http -h
- ./http www.columbia.edu -g kermit/index.html
-
- Finally, if Kermit's first command-line option is a Telnet, FTP, IKSD,
- or HTTP URL, Kermit automatically makes the appropriate kind of
- connection and, if indicated by the URL, takes the desired action:
-
- kermit telnet:xyzcorp.com ; Opens a Telnet session
- kermit telnet://olga@xyzcorp.com ; Ditto for user olga
- kermit ftp://olga@xyzcorp.com/public/oofa.zip ; Downloads a file
- kermit kermit://kermit.columbia.edu/kermit/f/READ.ME ; Ditto for IKSD
- kermit iksd://kermit.columbia.edu/kermit/f/READ.ME ; (This works too)
- kermit http://www.columbia.edu/kermit/index.html ; Grabs a web page
- kermit https://wwws.xyzcorp.com/secret/plan.html ; Grabs a secure web page
-
- [180]Kermit Home [181]C-Kermit Home [182]C-Kermit FAQ
-
-LICENSE
-
- [183]Top [184]Contents [185]Next [186]Previous
-
- On or before 30 June 2011, barring unforeseen circumstances,
- [187]C-Kermit 9.0 will be released with the [188]Revised 3-Clause BSD
- License. This is a certified [189]Open Source license, and it means
- that C-Kermit no longer needs to be licensed for commercial
- redistribution. Technical support for Kermit software will not be
- available from Columbia University after June 30th.
-
- [190]Kermit Home [191]C-Kermit Home [192]C-Kermit FAQ
-
-OTHER TOPICS
-
- [193]Top [194]Contents [195]Next [196]Previous
-
- There's way more to C-Kermit than we've touched on here --
- troubleshooting, customization, character sets, dialing directories,
- sending pages, script writing, and on and on, all of which are covered
- in the manual and updates and supplements. For the most up-to-date
- information on documentation (or updated documentation itself) visit
- the Kermit Project website:
-
- [197]http://www.columbia.edu/kermit/
-
- There you will also find [198]Kermit software packages for other
- platforms: different Unix varieties, Windows, DOS, VMS, IBM mainframes,
- and many others: 20+ years' worth.
-
- [199]Kermit Home [200]C-Kermit Home [201]C-Kermit FAQ
-
-DOCUMENTATION AND UPDATES
-
- [202]Top [203]Contents [204]Next [205]Previous
-
- The manual for C-Kermit is:
-
- 1. Frank da Cruz and Christine M. Gianone, [206]Using C-Kermit, Second
- Edition, Digital Press / Butterworth-Heinemann, Woburn, MA, 1997,
- 622 pages, ISBN 1-55558-164-1. This is a printed book, now also
- available as a [207]Kindle E-Book. It covers C-Kermit 6.0.
- 2. The C-Kermit 7.0 Supplement:
- [208]http://www.columbia.edu/kermit/ckermit70.html
- 3. The C-Kermit 8.0 Supplement:
- [209]http://www.columbia.edu/kermit/ckermit80.html
- 4. The C-Kermit 9.0 Supplement:
- [210]http://www.columbia.edu/kermit/ckermit90.html
-
- The C-Kermit home page is here:
-
- [211]http://www.columbia.edu/kermit/ckermit.html
-
- Visit this page to learn about new versions, Beta tests, and other
- news; to read case studies and tutorials; to download source code,
- install packages, and [212]prebuilt binaries for many platforms. Also
- visit:
-
- [213]http://www.columbia.edu/kermit/scriptlib.html
- The Kermit script library and tutorial
-
- [214]http://www.columbia.edu/kermit/newfaq.html
- The Kermit FAQ (Frequently Asked Questions about Kermit)
-
- [215]http://www.columbia.edu/kermit/ckfaq.html
- The C-Kermit FAQ (Frequently Asked Questions about C-Kermit)
-
- [216]http://www.columbia.edu/kermit/security.html
- The Kermit security reference.
-
- [217]http://www.columbia.edu/kermit/telnet.html
- C-Kermit Telnet client documentation.
-
- [218]http://www.columbia.edu/kermit/studies.html
- Case studies.
-
- [219]http://www.columbia.edu/kermit/ckcbwr.html
- General C-Kermit Hints and Tips.
-
- [220]http://www.columbia.edu/kermit/ckubwr.html
- Unix C-Kermit Hints and Tips.
-
- [221]http://www.columbia.edu/kermit/ckvbwr.html
- VMS C-Kermit Hints and Tips.
-
- [222]http://www.columbia.edu/kermit/ckuins.html
- Unix C-Kermit Installation Instructions
-
- [223]http://www.columbia.edu/kermit/ckvins.html
- VMS C-Kermit Installation Instructions
-
- [224]http://www.columbia.edu/kermit/support.html
- Technical support.
-
- [225]http://www.columbia.edu/kermit/k95tutorial.html
- Kermit 95 tutorial (this document).
-
- [226]comp.protocols.kermit.misc
- The Kermit newsgroup (unmoderated).
-
- [227]Kermit Home [228]C-Kermit Home [229]C-Kermit FAQ
-
-FILES
-
- [230]Top [231]Contents [232]Next [233]Previous
-
- [234]The Revised 3-Clause License
- C-Kermit license.
-
- [235]~/.kermrc
- Initialization file.
-
- [236]~/.mykermrc
- Customization file.
-
- ~/.kdd
- Kermit dialing directory (see manual).
-
- ~/.knd
- Kermit network directory (see manual).
-
- ~/.ksd
- Kermit services directory (see manual).
-
- [237]ckuins.html
- Installation instructions for Unix.
-
- [238]ckcbwr.html
- General C-Kermit bugs, hints, tips.
-
- [239]ckubwr.html
- Unix-specific C-Kermit bugs, hints, tips.
-
- [240]ckcplm.html
- C-Kermit program logic manual.
-
- [241]ckccfg.html
- C-Kermit compile-time configuration options.
-
- ssh
- (in your PATH) SSH connection helper.
-
- rz, sz, etc.
- (in your PATH) external protocols for XYZmodem.
-
- /var/spool/locks (or whatever)
- UUCP lockfile for dialing out (see [242]installation
- instructions).
-
- [243]Kermit Home [244]C-Kermit Home [245]C-Kermit FAQ
-
-AUTHORS
-
- [246]Top [247]Contents [248]Previous
-
- Frank da Cruz and Jeffrey E Altman
- The Kermit Project - Columbia Univerity
- 612 West 115th Street
- New York NY 10025-7799
- USA
-
- 1985-present, with contributions from hundreds of others all over the
- world.
- __________________________________________________________________
-
-
- C-Kermit 9.0 Unix Manual Page and Tutorial / [249]kermit@columbia.edu
- / 1 July 2011
-
-References
-
- 1. http://www.columbia.edu/
- 2. mailto:kermit@columbia.edu
- 3. http://www.columbia.edu/kermit/index.html
- 4. http://www.columbia.edu/kermit/k95.html
- 5. http://www.columbia.edu/kermit/ckermit.html
- 6. http://www.columbia.edu/kermit/ckscripts.html
- 7. http://www.columbia.edu/kermit/current.html
- 8. http://www.columbia.edu/kermit/whatsnew.html
- 9. http://www.columbia.edu/kermit/ckfaq.html
- 10. http://www.columbia.edu/kermit/support.html
- 11. http://www.columbia.edu/kermit/
- 12. http://www.columbia.edu/
- 13. http://www.columbia.edu/kermit/ckututor.pdf
- 14. ftp://kermit.columbia.edu/kermit/test/text/ckuker.nr
- 15. http://www.amazon.com/gp/product/1555581641?ie=UTF8&tag=aleidmoreldom-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1555581641
- 16. http://www.columbia.edu/kermit/ckututor.html#description
- 17. http://www.columbia.edu/kermit/ckututor.html#synopsis
- 18. http://www.columbia.edu/kermit/ckututor.html#options
- 19. http://www.columbia.edu/kermit/ckututor.html#commands
- 20. http://www.columbia.edu/kermit/ckututor.html#initfile
- 21. http://www.columbia.edu/kermit/ckututor.html#modes
- 22. http://www.columbia.edu/kermit/ckututor.html#connections
- 23. http://www.columbia.edu/kermit/ckututor.html#transfer
- 24. http://www.columbia.edu/kermit/ckututor.html#server
- 25. http://www.columbia.edu/kermit/ckututor.html#ftp
- 26. http://www.columbia.edu/kermit/ckututor.html#iksd
- 27. http://www.columbia.edu/kermit/ckututor.html#security
- 28. http://www.columbia.edu/kermit/ckututor.html#personae
- 29. http://www.columbia.edu/kermit/ckututor.html#license
- 30. http://www.columbia.edu/kermit/ckututor.html#other
- 31. http://www.columbia.edu/kermit/ckututor.html#documentation
- 32. http://www.columbia.edu/kermit/ckututor.html#files
- 33. http://www.columbia.edu/kermit/ckututor.html#authors
- 34. http://www.columbia.edu/kermit/ckututor.html#top
- 35. http://www.columbia.edu/kermit/ckututor.html#contents
- 36. http://www.columbia.edu/kermit/ckututor.html#synopsis
- 37. http://www.columbia.edu/kermit/ckermit.html
- 38. http://www.columbia.edu/kermit/
- 39. http://www.columbia.edu/
- 40. ftp://ftp.isi.edu/in-notes/rfc2839.txt
- 41. ftp://ftp.isi.edu/in-notes/rfc2840.txt
- 42. http://www.columbia.edu/kermit/ckututor.html#documentation
- 43. http://www.columbia.edu/kermit/
- 44. http://www.columbia.edu/kermit/
- 45. http://www.columbia.edu/kermit/ckermit.html
- 46. http://www.columbia.edu/kermit/ckfaq.html
- 47. http://www.columbia.edu/kermit/ckututor.html#top
- 48. http://www.columbia.edu/kermit/ckututor.html#contents
- 49. http://www.columbia.edu/kermit/ckututor.html#options
- 50. http://www.columbia.edu/kermit/ckututor.html#synopsis
- 51. http://www.columbia.edu/kermit/ckututor.html#kerbang
- 52. http://www.columbia.edu/kermit/ckututor.html#personae
- 53. http://www.columbia.edu/kermit/ckututor.html#kerbang
- 54. http://www.columbia.edu/kermit/ckututor.html#initfile
- 55. http://www.columbia.edu/kermit/ckututor.html#initfile
- 56. http://www.columbia.edu/kermit/ckututor.html#personae
- 57. http://www.columbia.edu/kermit/ckututor.html#options
- 58. http://www.columbia.edu/kermit/ckututor.html#commands
- 59. http://www.columbia.edu/kermit/
- 60. http://www.columbia.edu/kermit/ckermit.html
- 61. http://www.columbia.edu/kermit/ckfaq.html
- 62. http://www.columbia.edu/kermit/ckututor.html#top
- 63. http://www.columbia.edu/kermit/ckututor.html#contents
- 64. http://www.columbia.edu/kermit/ckututor.html#commands
- 65. http://www.columbia.edu/kermit/ckututor.html#description
- 66. http://www.columbia.edu/kermit/ckututor.html#commands
- 67. http://www.columbia.edu/kermit/ckututor.html#personae
- 68. http://www.columbia.edu/kermit/ckututor.html#personae
- 69. http://www.columbia.edu/kermit/ckututor.html#iksd
- 70. http://www.columbia.edu/kermit/ckututor.html#transfer
- 71. http://www.columbia.edu/kermit/ckututor.html#top
- 72. http://www.columbia.edu/kermit/ckututor.html#contents
- 73. http://www.columbia.edu/kermit/ckututor.html#initfile
- 74. http://www.columbia.edu/kermit/ckututor.html#options
- 75. http://www.columbia.edu/kermit/ckututor.html#kerbang
- 76. http://www.columbia.edu/kermit/ckututor.html#cmdlist
- 77. http://www.columbia.edu/kermit/ckututor.html#documentation
- 78. http://www.columbia.edu/kermit/ckututor.html#initfile
- 79. http://www.columbia.edu/kermit/ckututor.html#documentation
- 80. http://www.columbia.edu/kermit/ckscripts.html
- 81. http://www.columbia.edu/kermit/ckututor.html#documentation
- 82. http://www.columbia.edu/kermit/
- 83. http://www.columbia.edu/kermit/ckermit.html
- 84. http://www.columbia.edu/kermit/ckfaq.html
- 85. http://www.columbia.edu/kermit/ckututor.html#top
- 86. http://www.columbia.edu/kermit/ckututor.html#contents
- 87. http://www.columbia.edu/kermit/ckututor.html#modes
- 88. http://www.columbia.edu/kermit/ckututor.html#commands
- 89. http://www.columbia.edu/kermit/
- 90. http://www.columbia.edu/kermit/ckermit.html
- 91. http://www.columbia.edu/kermit/ckfaq.html
- 92. http://www.columbia.edu/kermit/ckututor.html#top
- 93. http://www.columbia.edu/kermit/ckututor.html#contents
- 94. http://www.columbia.edu/kermit/ckututor.html#connections
- 95. http://www.columbia.edu/kermit/ckututor.html#initfile
- 96. http://www.columbia.edu/kermit/ckfaq.html#term
- 97. http://www.columbia.edu/kermit/
- 98. http://www.columbia.edu/kermit/ckermit.html
- 99. http://www.columbia.edu/kermit/ckfaq.html
- 100. http://www.columbia.edu/kermit/ckututor.html#top
- 101. http://www.columbia.edu/kermit/ckututor.html#contents
- 102. http://www.columbia.edu/kermit/ckututor.html#transfer
- 103. http://www.columbia.edu/kermit/ckututor.html#modes
- 104. http://www.columbia.edu/kermit/ckututor.html#iksd
- 105. http://www.columbia.edu/kermit/cable.html
- 106. ftp://ftp.isi.edu/in-notes/rfc2217.txt
- 107. http://www.columbia.edu/kermit/cable.html
- 108. http://www.columbia.edu/kermit/ckututor.html#ftp
- 109. http://www.columbia.edu/kermit/
- 110. http://www.columbia.edu/kermit/ckermit.html
- 111. http://www.columbia.edu/kermit/ckfaq.html
- 112. http://www.columbia.edu/kermit/ckututor.html#top
- 113. http://www.columbia.edu/kermit/ckututor.html#contents
- 114. http://www.columbia.edu/kermit/ckututor.html#server
- 115. http://www.columbia.edu/kermit/ckututor.html#connections
- 116. http://www.columbia.edu/kermit/ckututor.html#download
- 117. http://www.columbia.edu/kermit/ckututor.html#upload
- 118. http://www.columbia.edu/kermit/ckututor.html#oldfashioned
- 119. http://www.columbia.edu/kermit/ckututor.html#trouble
- 120. http://www.columbia.edu/kermit/ckututor.html#advanced
- 121. http://www.columbia.edu/kermit/ckututor.html#nonkermit
- 122. http://www.columbia.edu/kermit/kermit.html#notslow
- 123. http://www.columbia.edu/kermit/ckermit.html
- 124. http://www.columbia.edu/kermit/k95.html
- 125. http://www.columbia.edu/kermit/k95.html
- 126. http://www.columbia.edu/kermit/ckermit.html
- 127. http://www.columbia.edu/kermit/mskermit.html
- 128. http://www.columbia.edu/kermit/
- 129. http://www.columbia.edu/kermit/support.html
- 130. http://www.columbia.edu/kermit/ckmanual.html
- 131. mailto:kermit-support@columbia.edu
- 132. http://www.columbia.edu/kermit/ckututor.html#documentation
- 133. http://www.columbia.edu/kermit/ckututor.html#ftp
- 134. http://www.columbia.edu/kermit/
- 135. http://www.columbia.edu/kermit/ckermit.html
- 136. http://www.columbia.edu/kermit/ckfaq.html
- 137. http://www.columbia.edu/kermit/ckututor.html#top
- 138. http://www.columbia.edu/kermit/ckututor.html#contents
- 139. http://www.columbia.edu/kermit/ckututor.html#ftp
- 140. http://www.columbia.edu/kermit/ckututor.html#transfer
- 141. http://www.columbia.edu/kermit/ckututor.html#iksd
- 142. http://www.columbia.edu/kermit/
- 143. http://www.columbia.edu/kermit/ckermit.html
- 144. http://www.columbia.edu/kermit/ckfaq.html
- 145. http://www.columbia.edu/kermit/ckututor.html#top
- 146. http://www.columbia.edu/kermit/ckututor.html#contents
- 147. http://www.columbia.edu/kermit/ckututor.html#iksd
- 148. http://www.columbia.edu/kermit/ckututor.html#transfer
- 149. http://www.columbia.edu/kermit/ckututor.html#server
- 150. http://www.columbia.edu/kermit/ftpclient.html
- 151. http://www.columbia.edu/kermit/ckututor.html#documentation
- 152. http://www.columbia.edu/kermit/
- 153. http://www.columbia.edu/kermit/ckermit.html
- 154. http://www.columbia.edu/kermit/ckfaq.html
- 155. http://www.columbia.edu/kermit/ckermit3.html#x3
- 156. http://www.columbia.edu/kermit/ckermit3.html#x2.2
- 157. http://www.columbia.edu/kermit/ckututor.html#top
- 158. http://www.columbia.edu/kermit/ckututor.html#contents
- 159. http://www.columbia.edu/kermit/ckututor.html#security
- 160. http://www.columbia.edu/kermit/ckututor.html#ftp
- 161. http://www.columbia.edu/kermit/cuiksd.html
- 162. http://www.columbia.edu/kermit/iksd.html
- 163. http://www.columbia.edu/kermit/
- 164. http://www.columbia.edu/kermit/ckermit.html
- 165. http://www.columbia.edu/kermit/ckfaq.html
- 166. http://www.columbia.edu/kermit/ckututor.html#top
- 167. http://www.columbia.edu/kermit/ckututor.html#contents
- 168. http://www.columbia.edu/kermit/ckututor.html#personae
- 169. http://www.columbia.edu/kermit/ckututor.html#iksd
- 170. http://www.columbia.edu/kermit/security.html
- 171. http://www.columbia.edu/kermit/
- 172. http://www.columbia.edu/kermit/ckermit.html
- 173. http://www.columbia.edu/kermit/ckfaq.html
- 174. http://www.columbia.edu/kermit/ckututor.html#top
- 175. http://www.columbia.edu/kermit/ckututor.html#contents
- 176. http://www.columbia.edu/kermit/ckututor.html#license
- 177. http://www.columbia.edu/kermit/ckututor.html#iksd
- 178. http://www.columbia.edu/kermit/ckututor.html#options
- 179. http://www.columbia.edu/kermit/ckermit3.html#x3.1.2
- 180. http://www.columbia.edu/kermit/
- 181. http://www.columbia.edu/kermit/ckermit.html
- 182. http://www.columbia.edu/kermit/ckfaq.html
- 183. http://www.columbia.edu/kermit/ckututor.html#top
- 184. http://www.columbia.edu/kermit/ckututor.html#contents
- 185. http://www.columbia.edu/kermit/ckututor.html#other
- 186. http://www.columbia.edu/kermit/ckututor.html#personae
- 187. http://www.columbia.edu/kermit/ck90.html
- 188. http://www.columbia.edu/kermit/cu-bsd-license.html
- 189. http://www.opensource.org/
- 190. http://www.columbia.edu/kermit/
- 191. http://www.columbia.edu/kermit/ckermit.html
- 192. http://www.columbia.edu/kermit/ckfaq.html
- 193. http://www.columbia.edu/kermit/ckututor.html#top
- 194. http://www.columbia.edu/kermit/ckututor.html#contents
- 195. http://www.columbia.edu/kermit/ckututor.html#documentation
- 196. http://www.columbia.edu/kermit/ckututor.html#license
- 197. http://www.columbia.edu/kermit/
- 198. http://www.columbia.edu/kermit/howtoget.html
- 199. http://www.columbia.edu/kermit/
- 200. http://www.columbia.edu/kermit/ckermit.html
- 201. http://www.columbia.edu/kermit/ckfaq.html
- 202. http://www.columbia.edu/kermit/ckututor.html#top
- 203. http://www.columbia.edu/kermit/ckututor.html#contents
- 204. http://www.columbia.edu/kermit/ckututor.html#files
- 205. http://www.columbia.edu/kermit/ckututor.html#other
- 206. http://www.columbia.edu/kermit/ckmanual.html
- 207. http://www.amazon.com/gp/product/B002ACPF9M?ie=UTF8&tag=aleidmoreldom-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=B002ACPF9M
- 208. http://www.columbia.edu/kermit/ckermit70.html
- 209. http://www.columbia.edu/kermit/ckermit80.html
- 210. http://www.columbia.edu/kermit/ckermit90.html
- 211. http://www.columbia.edu/kermit/ckermit.html
- 212. http://www.columbia.edu/kermit/ck80binaries.html
- 213. http://www.columbia.edu/kermit/scriptlib.html
- 214. http://www.columbia.edu/kermit/newfaq.html
- 215. http://www.columbia.edu/kermit/ckfaq.html
- 216. http://www.columbia.edu/kermit/security.html
- 217. http://www.columbia.edu/kermit/telnet.html
- 218. http://www.columbia.edu/kermit/studies.html
- 219. http://www.columbia.edu/kermit/ckcbwr.html
- 220. http://www.columbia.edu/kermit/ckubwr.html
- 221. http://www.columbia.edu/kermit/ckvbwr.html
- 222. http://www.columbia.edu/kermit/ckuins.html
- 223. http://www.columbia.edu/kermit/ckvins.html
- 224. http://www.columbia.edu/kermit/support.html
- 225. http://www.columbia.edu/kermit/k95tutorial.html
- 226. news:comp.protocols.kermit.misc
- 227. http://www.columbia.edu/kermit/
- 228. http://www.columbia.edu/kermit/ckermit.html
- 229. http://www.columbia.edu/kermit/ckfaq.html
- 230. http://www.columbia.edu/kermit/ckututor.html#top
- 231. http://www.columbia.edu/kermit/ckututor.html#contents
- 232. http://www.columbia.edu/kermit/ckututor.html#authors
- 233. http://www.columbia.edu/kermit/ckututor.html#documentation
- 234. http://www.columbia.edu/kermit/cu-bsd-license.html
- 235. ftp://kermit.columbia.edu/kermit/c-kermit/ckermit.ini
- 236. ftp://kermit.columbia.edu/kermit/c-kermit/ckermod.ini
- 237. http://www.columbia.edu/kermit/ckuins.html
- 238. http://www.columbia.edu/kermit/ckcbwr.html
- 239. http://www.columbia.edu/kermit/ckubwr.html
- 240. http://www.columbia.edu/kermit/ckcplm.html
- 241. http://www.columbia.edu/kermit/ckccfg.html
- 242. http://www.columbia.edu/kermit/ckuins.html
- 243. http://www.columbia.edu/kermit/
- 244. http://www.columbia.edu/kermit/ckermit.html
- 245. http://www.columbia.edu/kermit/ckfaq.html
- 246. http://www.columbia.edu/kermit/ckututor.html#top
- 247. http://www.columbia.edu/kermit/ckututor.html#contents
- 248. http://www.columbia.edu/kermit/ckututor.html#files
- 249. mailto:kermit@columbia.edu
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus2.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuus2.c
deleted file mode 100644
index db0dfe9..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus2.c
+++ /dev/null
@@ -1,14491 +0,0 @@
-#ifdef SSHTEST
-#define SSHBUILTIN
-#endif /* SSHTEST */
-
-/* C K U U S 2 -- User interface strings & help text module for C-Kermit */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- This module contains HELP command and other long text strings.
-
- IMPORTANT: Character string constants longer than about 250 are not portable.
- Longer strings should be broken up into arrays of strings and accessed with
- hmsga() rather than hmsg(). (This statement was true in the 1980s and
- probably is not a big concern in the 21st Century, but you never know;
- there still might exist some 16-bit platforms and C compilers that have
- restrictions like this.
-*/
-#include "ckcsym.h"
-#include "ckcdeb.h"
-#include "ckcnet.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckuusr.h"
-#include "ckcxla.h"
-#ifdef OS2
-#ifdef NT
-#include <windows.h>
-#else /* not NT */
-#define INCL_KBD
-#ifdef OS2MOUSE
-#define INCL_MOU
-#endif /* OS2MOUSE */
-#define INCL_DOSMISC
-#define INCL_DOSDEVICES
-#include <os2.h> /* This pulls in a whole load of stuff */
-#undef COMMENT
-#endif /* NT */
-#include "ckocon.h"
-#include "ckokvb.h"
-#include "ckokey.h"
-#endif /* OS2 */
-
-extern char * ck_cryear; /* For copyright notice */
-
-extern xx_strp xxstring;
-extern char * ccntab[];
-/*
- hlptok contains the string for which the user requested help. This is
- useful for distinguishing synonyms, in case different help text is needed
- depending on which synonym was given.
-*/
-extern char * hlptok;
-
-#ifndef NOIKSD
- extern int inserver;
-#endif /* IKSD */
-
-#ifndef NOICP
-extern int cmflgs;
-
-#ifdef DCMDBUF
-extern char *cmdbuf, *atmbuf;
-#else
-extern char cmdbuf[], atmbuf[];
-#endif /* DCMDBUF */
-#endif /* NOICP */
-
-extern char *xarg0;
-extern int nrmt, nprm, dfloc, local, parity, escape;
-extern int turn, flow;
-extern int binary, quiet, keep;
-extern int success, xaskmore;
-#ifdef OS2
-extern int tt_rows[], tt_cols[];
-#else /* OS2 */
-extern int tt_rows, tt_cols;
-#endif /* OS2 */
-extern int cmd_rows, cmd_cols;
-
-extern long speed;
-extern char *dftty, *versio, *ckxsys;
-#ifndef NOHELP
-extern char *helpfile;
-#endif /* NOHELP */
-extern struct keytab prmtab[];
-#ifndef NOXFER
-extern struct keytab remcmd[];
-#endif /* NOXFER */
-
-#ifndef NOICP
-
-/* Interactive help strings */
-
-/* Top-level HELP text. IMPORTANT: Also see tophlpi[] for IKSD. */
-
-static char *tophlp[] = {
-"Trustees of Columbia University in the City of New York.\n",
-
-#ifndef NOHELP
-" Type EXIT to exit.",
-#ifdef OS2
-" Type INTRO for a brief introduction to the Kermit Command screen.",
-" Type LICENSE to see the Kermit 95 license.",
-#else
-" Type INTRO for a brief introduction to C-Kermit.",
-" Type LICENSE to see the C-Kermit license.",
-#endif /* OS2 */
-" Type HELP followed by a command name for help about a specific command.",
-#ifndef NOPUSH
-#ifdef UNIX
-" Type MANUAL to access the C-Kermit manual page.",
-#else
-#ifdef VMS
-" Type MANUAL to access the C-Kermit help topic.",
-#else
-#ifdef OS2
-" Type MANUAL to access the K95 manual.",
-#else
-" Type MANUAL to access the C-Kermit manual.",
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* NOPUSH */
-" Type NEWS for news about new features.",
-" Type SUPPORT to learn how to get technical support.",
-" Press ? (question mark) at the prompt, or anywhere within a command,",
-" for a menu (context-sensitive help, menu on demand).",
-#else
-"Press ? for a list of commands; see documentation for detailed descriptions.",
-#endif /* NOHELP */
-
-#ifndef NOCMDL
-#ifndef NOHELP
-" ",
-" Type HELP OPTIONS for help with command-line options.",
-#endif /* NOHELP */
-#endif /* NOCMDL */
-" ",
-#ifndef OS2
-#ifdef MAC
-"Documentation for Command Window: \"Using C-Kermit\" by Frank da Cruz and",
-"Christine M. Gianone, Digital Press, 1997, ISBN: 1-55558-164-1",
-#else
-"DOCUMENTATION: \"Using C-Kermit\" by Frank da Cruz and Christine M. Gianone,",
-"2nd Edition, Digital Press / Butterworth-Heinemann 1997, ISBN 1-55558-164-1,",
-"plus supplements at http://kermit.columbia.edu/ckermit.html#doc.",
-#endif /* MAC */
-#endif /* OS2 */
-#ifdef MAC
-" ",
-"Also see the Mac Kermit Doc and Bwr files on the Mac Kermit diskette.\n",
-#else
-#ifdef HPUX10
-" ",
-"See the files in /usr/share/lib/kermit/ for additional information.",
-#endif /* HPUX10 */
-#endif /* MAC */
-""
-};
-
-#ifndef NOIKSD
-static char *tophlpi[] = { /* Top-level help for IKSD */
-
-"Trustees of Columbia University in the City of New York.\n",
-
-#ifndef NOHELP
-" Type INTRO for a brief introduction to Kermit commands.",
-" Type VERSION for version and copyright information.",
-" Type HELP followed by a command name for help about a specific command.",
-" Type SUPPORT to learn how to get technical support.",
-" Type LOGOUT (or EXIT) to log out.",
-" Press ? (question mark) at the prompt, or anywhere within a command,",
-" for a menu (context-sensitive help, menu on demand).",
-#else
-"Press ? for a list of commands; see documentation for detailed descriptions.",
-#endif /* NOHELP */
-" ",
-"DOCUMENTATION: \"Using C-Kermit\" by Frank da Cruz and Christine M. Gianone,",
-"2nd Edition, Digital Press (1997), ISBN 1-55558-164-1. More info at the",
-"Kermit Project website, http://kermit.columbia.edu/.",
-""
-};
-#endif /* NOIKSD */
-
-#ifndef NOHELP
-char *newstxt[] = {
-#ifdef OS2
-"Welcome to Kermit 95 3.x.x. Major new features since 2.1.3 include:",
-#else
-"Welcome to C-Kermit 9.0.300. New features since 8.0.211 include:",
-#endif /* OS2 */
-" . Open Source Simplified 3-Clause BSD License",
-" . Full 64-bit memory model on platforms that support it",
-" . Large file support (64-bit file size) on most platforms",
-" . Long integer variables and constants in commands and scripts",
-" . Bigger maximum command and macro lengths",
-" . Bigger filename expansion space",
-" . New super-flexible RENAME command",
-" . New COPY and DIRECTORY command options",
-" . New TOUCH command",
-" . Raw SSL/TLS connections for connecting to POP3 and similar services",
-" . At prompt, Ctrl-K recalls most recent filename",
-" . Scripting and performance improvements and bug fixes",
-" ",
-"Documentation:",
-" 1. http://kermit.columbia.edu/usingckermit.html",
-" \"Using C-Kermit\", second edition (1997), current with C-Kermit 6.0.",
-" ",
-" 2. http://kermit.columbia.edu/ckermit70.html",
-" which documents the new features of C-Kermit 7.0.",
-" ",
-" 3. http://kermit.columbia.edu/ckermit80.html",
-" which documents the new features of C-Kermit 8.0.",
-" ",
-" 4. http://kermit.columbia.edu/ckermit90.html",
-" which documents the new features of C-Kermit 9.0.",
-" ",
-"If the release date shown by the VERSION command is long past, be sure to",
-"check with the Kermit website to see if there have been updates:",
-" ",
-#ifdef OS2
-" http://kermit.columbia.edu/k95.html (Kermit 95 home page)",
-#else
-" http://kermit.columbia.edu/ckermit.html (C-Kermit home page)",
-#endif /* OS2 */
-" http://kermit.columbia.edu/ (Kermit Project home page)",
-""
-};
-#endif /* NOHELP */
-
-#ifndef NOHELP
-char *introtxt[] = {
-#ifdef OS2
-"Welcome to K-95, Kermit communications software for:",
-#else
-#ifdef UNIX
-#ifdef HPUX
-"Welcome to HP-UX C-Kermit communications software for:",
-#else
-"Welcome to UNIX C-Kermit communications software for:",
-#endif /* HPUX */
-#else
-#ifdef VMS
-"Welcome to VMS C-Kermit communications software for:",
-#else
-#ifdef VOS
-"Welcome to VOS C-Kermit communications software for:",
-#else
-#ifdef MAC
-"Welcome to Mac Kermit communications software for:",
-#else
-"Welcome to C-Kermit communications software for:",
-#endif /* MAC */
-#endif /* VOS */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* OS2 */
-#ifndef NOXFER
-" . Error-free and efficient file transfer",
-#endif /* NOXFER */
-#ifndef NOLOCAL
-#ifdef OS2
-" . VT320/220/102/100/52, ANSI, Wyse, Linux, Televideo, and other emulations",
-#else
-#ifdef MAC
-" . VT220 terminal emulation",
-#else
-" . Terminal connection",
-#endif /* MAC */
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifndef NOSPL
-" . Script programming",
-#endif /* NOSPL */
-#ifndef NOICS
-" . International character set conversion",
-#endif /* NOICS */
-#ifndef NODIAL
-#ifndef NOSPL
-" . Numeric and alphanumeric paging",
-#endif /* NOSPL */
-#endif /* NODIAL */
-
-#ifndef NOLOCAL
-" ",
-"Supporting:",
-" . Serial connections, direct or dialed.",
-#ifndef NODIAL
-" . Automatic modem dialing",
-#endif /* NODIAL */
-#ifdef TCPSOCKET
-" . TCP/IP network connections:",
-#ifdef TNCODE
-" - Telnet sessions",
-#endif /* TNCODE */
-#ifdef SSHBUILTIN
-" - SSH v1 and v2 connections",
-#else
-#ifdef ANYSSH
-" - SSH connections via external agent",
-#endif /* ANYSSH */
-#endif /* SSHBUILTIN */
-#ifdef RLOGCODE
-" - Rlogin sessions",
-#endif /* RLOGCODE */
-#ifdef NEWFTP
-" - FTP sessions",
-#endif /* NEWFTP */
-#ifdef CKHTTP
-" - HTTP 1.1 sessions",
-#endif /* CKHTTP */
-#ifdef IKSD
-" - Internet Kermit Service",
-#endif /* IKSD */
-#endif /* TCPSOCKET */
-#ifdef ANYX25
-" . X.25 network connections",
-#endif /* ANYX25 */
-#ifdef OS2
-#ifdef DECNET
-" . DECnet/PATHWORKS LAT Ethernet connections",
-#endif /* DECNET */
-#ifdef SUPERLAT
-" . Meridian Technologies' SuperLAT connections",
-#endif /* SUPERLAT */
-#ifdef NPIPE
-" . Named-pipe connections",
-#endif /* NPIPE */
-#ifdef CK_NETBIOS
-" . NETBIOS connections",
-#endif /* CK_NETBIOS */
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-" ",
-"While typing commands, you may use the following special characters:",
-" . DEL, RUBOUT, BACKSPACE, CTRL-H: Delete the most recent character typed.",
-" . CTRL-W: Delete the most recent word typed.",
-" . CTRL-U: Delete the current line.",
-" . CTRL-R: Redisplay the current line.",
-
-#ifdef CK_RECALL
-#ifdef OS2
-" . Uparrow: Command recall - go backwards in command recall buffer.",
-" . Downarrow: Command recall - go forward in command recall buffer.",
-#ifndef NOIKSD
-" (Note: Arrow keys can be used only on the PC's physical keyboard.)",
-#endif /* NOIKSD */
-#endif /* OS2 */
-" . CTRL-P: Command recall - go backwards in command recall buffer.",
-" . CTRL-B: Command recall - same as Ctrl-P.",
-" . CTRL-N: Command recall - go forward in command recall buffer.",
-#endif /* CK_RECALL */
-#ifndef NOLASTFILE
-" . CTRL-K: Insert the most recently entered local file specifiction.",
-#endif /* NOLASTFILE */
-
-" . ? (question mark) Display a menu for the current command field."
-,
-" . ESC (or TAB or Ctrl-I) Attempt to complete the current field.",
-" . \\ (backslash) include the following character literally",
-#ifndef NOSPL
-" or introduce a backslash code, variable, or function.",
-#else
-" or introduce a numeric backslash code.",
-#endif /* NOSPL */
-" ",
-
-"IMPORTANT: Since backslash (\\) is Kermit's command-line escape character,",
-"you must enter DOS, Windows, or OS/2 pathnames using either forward slash (/)"
-,
-"or double backslash (\\\\) as the directory separator in most contexts.",
-"Examples: C:/TMP/README.TXT, C:\\\\TMP\\\\README.TXT.",
-" ",
-
-"Command words other than filenames can be abbreviated in most contexts.",
-" ",
-
-"Basic commands:",
-" EXIT Exit from Kermit",
-" HELP Request general help",
-" HELP command Request help about the given command",
-" TAKE Execute commands from a file",
-" TYPE Display a file on your screen",
-" ORIENTATION Explains directory structure",
-" ",
-
-#ifndef NOXFER
-"Commands for file transfer:",
-" SEND Send files",
-" RECEIVE Receive files",
-" GET Get files from a Kermit server",
-#ifdef CK_RESEND
-" RESEND Recover an interrupted send",
-" REGET Recover an interrupted get from a server",
-#endif /* CK_RESEND */
-#ifndef NOSERVER
-" SERVER Be a Kermit server",
-#endif /* NOSERVER */
-" ",
-"File-transfer speed selection:",
-" FAST Use fast settings -- THIS IS THE DEFAULT",
-" CAUTIOUS Use slower, more cautious settings",
-" ROBUST Use extremely slow and cautious settings",
-" ",
-"File-transfer performance fine tuning:",
-" SET RECEIVE PACKET-LENGTH Kermit packet size",
-" SET WINDOW Number of sliding window slots",
-" SET PREFIXING Amount of control-character prefixing",
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
-" ",
-"To make a direct serial connection:",
-#ifdef OS2
-#ifdef NT
-#ifdef CK_TAPI
-" SET PORT TAPI Select TAPI communication device",
-#endif /* CK_TAPI */
-" SET PORT Select serial communication device",
-#else
-" SET PORT Select serial communication port or server",
-#endif /* NT */
-#else
-" SET LINE Select serial communication device",
-#endif /* OS2 */
-" SET SPEED Select communication speed",
-" SET PARITY Communications parity (if necessary)",
-#ifdef CK_RTSCTS
-" SET FLOW Communications flow control, such as RTS/CTS",
-#else
-" SET FLOW Communications flow control, such as XON/XOFF",
-#endif /* CK_RTSCTS */
-" CONNECT Begin terminal connection",
-
-#ifndef NODIAL
-" ",
-"To dial out with a modem:",
-" SET DIAL DIRECTORY Specify dialing directory file (optional)",
-" SET DIAL COUNTRY-CODE Country you are dialing from (*)",
-" SET DIAL AREA-CODE Area-code you are dialing from (*)",
-" LOOKUP Lookup entries in your dialing directory (*)",
-" SET MODEM TYPE Select modem type",
-#ifdef OS2
-#ifdef NT
-#ifdef CK_TAPI
-" SET PORT TAPI Select TAPI communication device",
-#endif /* CK_TAPI */
-" SET PORT Select serial communication device",
-#else
-" SET PORT Select serial communication port or server",
-#endif /* NT */
-#else
-" SET LINE Select serial communication device",
-#endif /* OS2 */
-" SET SPEED Select communication speed",
-" SET PARITY Communications parity (if necessary)",
-" DIAL Dial the phone number",
-" CONNECT Begin terminal connection",
-" ",
-#ifdef OS2
-"Further info: HELP DIAL, HELP SET MODEM, HELP SET PORT, HELP SET DIAL",
-#else
-"Further info: HELP DIAL, HELP SET MODEM, HELP SET LINE, HELP SET DIAL",
-#endif /* OS2 */
-"(*) (For use with optional dialing directory)",
-#endif /* NODIAL */
-
-#ifdef NETCONN
-" ",
-"To make a network connection:",
-#ifndef NODIAL
-" SET NETWORK DIRECTORY Specify a network services directory (optional)",
-" LOOKUP Lookup entries in your network directory",
-#endif /* NODIAL */
-" SET NETWORK TYPE Select network type (if more than one available)",
-" SET HOST Make a network connection but stay in command mode",
-" CONNECT Begin terminal connection",
-#ifdef TNCODE
-" TELNET Select a Telnet host and CONNECT to it",
-#endif /* TNCODE */
-#ifdef RLOGCODE
-" RLOGIN Select an Rlogin host and CONNECT to it",
-#endif /* RLOGCODE */
-#ifdef ANYSSH
-" SSH [ OPEN ] Select an SSH host and CONNECT to it",
-#endif /* ANYSSH */
-#ifdef NEWFTP
-" FTP [ OPEN ] Make an FTP connection",
-#endif /* NEWFTP */
-#ifdef CKHTTP
-" HTTP OPEN Make an HTTP connection",
-#endif /* CKHTTP */
-#endif /* NETCONN */
-
-#ifdef NT
-" ",
-"To return from the terminal window to the K-95> prompt:",
-#else
-#ifdef OS2
-" ",
-"To return from the terminal window to the K/2> prompt:",
-#else
-" ",
-"To return from a terminal connection to the C-Kermit prompt:",
-#endif /* OS2 */
-#endif /* NT */
-#ifdef OS2
-" \
-Press the key or key-combination shown after \"Command:\" in the status line",
-" (such as Alt-x) or type your escape character followed by the letter C.",
-#else
-" Type your escape character followed by the letter C.",
-#endif /* OS2 */
-" ",
-"To display your escape character:",
-" SHOW ESCAPE",
-" ",
-"To display other settings:",
-" SHOW COMMUNICATIONS, SHOW TERMINAL, SHOW FILE, SHOW PROTOCOL, etc.",
-#else /* !NOLOCAL */
-" ",
-"To display settings:",
-" SHOW COMMUNICATIONS, SHOW FILE, SHOW PROTOCOL, etc.",
-#endif /* NOLOCAL */
-" ",
-"The manual for C-Kermit is the book \"Using C-Kermit\". For information",
-"about the manual, visit:",
-" http://kermit.columbia.edu/usingckermit.html",
-" ",
-#ifdef OS2
-"For a Kermit 95 tutorial, visit:",
-" http://kermit.columbia.edu/k95tutor.html",
-" ",
-#endif /* OS2 */
-"For an online C-Kermit tutorial, visit:",
-" http://kermit.columbia.edu/ckututor.html",
-" ",
-"To learn about script programming and automation:",
-" http://kermit.columbia.edu/ckscripts.html",
-" ",
-"For further information about a particular command, type HELP xxx,",
-"where xxx is the name of the command. For documentation, news of new",
-"releases, and information about other Kermit software, visit the",
-"Kermit Project website:",
-" ",
-" http://kermit.columbia.edu/",
-" ",
-"For information about technical support please visit this page:",
-" ",
-" http://kermit.columbia.edu/support.html",
-""
-};
-
-static char * hmxymatch[] = {
-"SET MATCH { DOTFILE, FIFO } { ON, OFF }",
-" Tells whether wildcards should match dotfiles (files whose names begin",
-" with period) or UNIX FIFO special files. MATCH FIFO default is OFF.",
-" MATCH DOTFILE default is OFF in UNIX, ON elsewhere.",
-""
-};
-
-#ifndef NOSEXP
-static char * hmxysexp[] = {
-"SET SEXPRESSION { DEPTH-LIMIT, ECHO-RESULT, TRUNCATE-ALL-RESULTS }",
-" DEPTH-LIMIT sets a limit on the depth of nesting or recursion in",
-" S-Expressions to prevent the program from crashing from memory exhaustion.",
-" ECHO-RESULT tells whether S-Expression results should be displayed as",
-" a result of evaluating an expression; the default is to display only at",
-" top (interactive) level; OFF means never display; ON means always display.",
-" TRUNCATE-ALL-RESULTS ON means the results of all arithmetic operations",
-" should be forced to integers (whole numbers) by discarding any fractional",
-" part. The default is OFF. SHOW SEXPRESSION displays the current settings."
-,""
-};
-#endif /* NOSEXP */
-
-#ifdef OS2
-#ifdef KUI
-static char * hmxygui[] = {
-"SET GUI CLOSE OFF",
-" Disables the System Menu Close and File->Exit functions which could be",
-" used to exit Kermit. Once disabled these functions cannot be re-enabled",
-" and the only way to exit Kermit is via the Kermit Script EXIT command.",
-" ",
-"SET GUI DIALOGS { ON, OFF }",
-" ON means that popups, alerts, use GUI dialogs; OFF means to use",
-" text-mode popups or prompts. ON by default.",
-" ",
-"SET GUI FONT name size",
-" Chooses the font and size. Type \"set gui font ?\" to see the list of",
-" choices. The size can be a whole number or can contain a decimal point",
-" and a fraction (which is rounded to the nearest half point).",
-" ",
-"SET GUI MENUBAR OFF",
-" Disables menubar functions which could be used to modify the Kermit",
-" session configuration. Once disabled the menubar functions cannot be",
-" re-enabled.",
-" ",
-"SET GUI RGBCOLOR colorname redvalue greenvalue bluevalue",
-" Specifies the red-green-blue mixture to be used to render the given",
-" color name. Type \"set gui rgbcolor\" to see a list of colornames.",
-" the RGB values are whole numbers from 0 to 255.",
-" ",
-"SET GUI TOOLBAR OFF",
-" Disables toolbar functions which could be used to modify the Kermit",
-" session configuration. Once disabled the toolbar functions cannot be",
-" re-enabled.",
-" ",
-"SET GUI WINDOW POSITION x y",
-" Moves the K95 window to the given X,Y coordinates, pixels from top left.",
-" (Not yet implemented -- use command-line options to do this.)",
-" ",
-"SET GUI WINDOW RESIZE-MODE { CHANGE-DIMENSIONS, SCALE-FONT }",
-" Default is CHANGE-DIMENSIONS.",
-"",
-"SET GUI WINDOW RUN-MODE { MAXIMIZE, MINIMIZE, RESTORE }",
-" Changes the run mode state of the GUI window.",
-""
-};
-#endif /* KUI */
-#endif /* OS2 */
-
-#ifdef ANYSSH
-static char * hmxxssh[] = {
-#ifdef SSHBUILTIN
-"Syntax: SSH { ADD, AGENT, CLEAR, KEY, [ OPEN ], V2 } operands...",
-" Performs an SSH-related action, depending on the keyword that follows:",
-" ",
-"SSH ADD LOCAL-PORT-FORWARD local-port host port",
-" Adds a port forwarding triplet to the local port forwarding list.",
-" The triplet specifies a local port to be forwarded and the hostname /",
-" ip-address and port number to which the port should be forwarded from",
-" the remote host. Port forwarding is activated at connection",
-" establishment and continues until the connection is terminated.",
-" ",
-"SSH ADD REMOTE-PORT-FORWARD remote-port host port",
-" Adds a port forwarding triplet to the remote port forwarding list.",
-" The triplet specifies a remote port to be forwarded and the",
-" hostname/ip-address and port number to which the port should be",
-" forwarded from the local machine. Port forwarding is activated at",
-" connection establishment and continues until the connection is",
-" terminated.",
-" ",
-"SSH AGENT ADD [ identity-file ]",
-" Adds the contents of the identity-file (if any) to the SSH AGENT",
-" private key cache. If no identity-file is specified, all files",
-" specified with SET SSH IDENTITY-FILE are added to the cache.",
-" ",
-"SSH AGENT DELETE [ identity-file ]",
-" Deletes the contents of the identity-file (if any) from the SSH AGENT",
-" private key cache. If no identity-file is specified, all files",
-" specified with SET SSH IDENTITY-FILE are deleted from the cache.",
-" ",
-"SSH AGENT LIST [ /FINGERPRINT ]",
-" Lists the contents of the SSH AGENT private key cache. If /FINGERPRINT",
-" is specified, the fingerprint of the private keys are displayed instead",
-" of the keys.",
-" ",
-"SSH CLEAR LOCAL-PORT-FORWARD",
-" Clears the local port forwarding list.",
-" ",
-"SSH CLEAR REMOTE-PORT-FORWARD",
-" Clears the remote port forwarding list.",
-" ",
-"SSH KEY commands:",
-" The SSH KEY commands create and manage public and private key pairs",
-" (identities). There are three forms of SSH keys. Each key pair is",
-" stored in its own set of files:",
-" ",
-" Key Type Private Key File Public Key File",
-" v1 RSA keys \\v(appdata)ssh/identity \\v(appdata)ssh/identity.pub",
-" v2 RSA keys \\v(appdata)ssh/id_rsa \\v(appdata)ssh/id_rsa.pub",
-" v2 DSA keys \\v(appdata)ssh/id_dsa \\v(appdata)ssh/id_dsa.pub",
-" ",
-" Keys are stored using the OpenSSH keyfile format. The private key",
-" files can be (optionally) protected by specifying a passphrase. A",
-" passphrase is a longer version of a password. English text provides",
-" no more than 2 bits of key data per character. 56-bit keys can be",
-" broken by a brute force attack in approximately 24 hours. When used,",
-" private key files should therefore be protected by a passphrase of at",
-" least 40 characters (about 80 bits).",
-" ",
-" To install a public key file on the host, you must transfer the file",
-" to the host and append it to your \"authorized_keys\" file. The file",
-" permissions must be 600 (or equivalent).",
-" ",
-"SSH KEY CHANGE-PASSPHRASE [ /NEW-PASSPHRASE:passphrase",
-" /OLD-PASSPHRASE:passphrase ] filename",
-" This re-encrypts the specified private key file with a new passphrase.",
-" The old passphrase is required. If the passphrases (and filename) are",
-" not provided Kermit prompts your for them.",
-" ",
-"SSH KEY CREATE [ /BITS:bits /PASSPHRASE:passphrase",
-" /TYPE:{ V1-RSA, V2-DSA, V2-RSA } /V1-RSA-COMMENT:comment ] filename",
-" This command creates a new private/public key pair. The defaults are:",
-" BITS:1024 and TYPE:V2-RSA. The filename is the name of the private",
-" key file. The public key is created with the same name with .pub",
-" appended to it. If a filename is not specified Kermit prompts you for",
-" it. V1 RSA key files may have an optional comment, which is ignored",
-" for other key types.",
-" ",
-"SSH KEY DISPLAY [ /FORMAT:{FINGERPRINT,IETF,OPENSSH,SSH.COM} ] filename",
-" This command displays the contents of a public or private key file.",
-" The default format is OPENSSH.",
-" ",
-"SSH KEY V1 SET-COMMENT filename comment",
-" This command replaces the comment associated with a V1 RSA key file.",
-" ",
-"SSH [ OPEN ] host [ port ] [ /COMMAND:command /USER:username",
-" /PASSWORD:pwd /VERSION:{ 1, 2 } /X11-FORWARDING:{ ON, OFF } ]",
-" This command establishes a new connection using SSH version 1 or",
-" version 2 protocol. The connection is made to the specified host on",
-" the SSH port (you can override the port by including a port name or",
-" number after the host name). Once the connection is established the",
-" authentication negotiations begin. If the authentication is accepted,",
-" the local and remote port forwarding lists are used to establish the",
-" desired connections. If X11 Forwarding is active, this results in a",
-" remote port forwarding between the X11 clients on the remote host and",
-" X11 Server on the local machine. If a /COMMAND is provided, the",
-" command is executed on the remote host in place of your default shell.",
-" ",
-" An example of a /COMMAND to execute C-Kermit in SERVER mode is:",
-" SSH OPEN hostname /COMMAND:{kermit -x -l 0}",
-" ",
-"SSH V2 REKEY",
-" Requests that an existing SSH V2 connection generate new session keys.",
-#else /* SSHBUILTIN */
-"Syntax: SSH [ options ] <hostname> [ command ]",
-" Makes an SSH connection using the external ssh program via the SET SSH",
-" COMMAND string, which is \"ssh -e none\" by default. Options for the",
-" external ssh program may be included. If the hostname is followed by a",
-" command, the command is executed on the host instead of an interactive",
-" shell.",
-#endif /* SSHBUILTIN */
-""
-};
-
-static char *hmxyssh[] = {
-#ifdef SSHBUILTIN
-"SET SSH AGENT-FORWARDING { ON, OFF }",
-" If an authentication agent is in use, setting this value to ON",
-" results in the connection to the agent being forwarded to the remote",
-" computer. The default is OFF.",
-" ",
-"SET SSH CHECK-HOST-IP { ON, OFF }",
-" Specifies whether the remote host's ip-address should be checked",
-" against the matching host key in the known_hosts file. This can be",
-" used to determine if the host key changed as a result of DNS spoofing.",
-" The default is ON.",
-" ",
-"SET SSH COMPRESSION { ON, OFF }",
-" Specifies whether compression will be used. The default is ON.",
-" ",
-"SET SSH DYNAMIC-FORWARDING { ON, OFF }",
-" Specifies whether Kermit is to act as a SOCKS4 service on port 1080",
-" when connected to a remote host via SSH. When Kermit acts as a SOCKS4",
-" service, it accepts connection requests and forwards the connections",
-" through the remote host. The default is OFF.",
-" ",
-"SET SSH GATEWAY-PORTS { ON, OFF }",
-" Specifies whether Kermit should act as a gateway for forwarded",
-" connections received from the remote host. The default is OFF.",
-" ",
-"SET SSH GSSAPI DELEGATE-CREDENTIALS { ON, OFF }",
-" Specifies whether Kermit should delegate GSSAPI credentials to ",
-" the remote host after authentication. Delegating credentials allows",
-" the credentials to be used from the remote host. The default is OFF.",
-" ",
-"SET SSH HEARTBEAT-INTERVAL <seconds>",
-" Specifies a number of seconds of idle time after which an IGNORE",
-" message will be sent to the server. This pulse is useful for",
-" maintaining connections through HTTP Proxy servers and Network",
-" Address Translators. The default is OFF (0 seconds).",
-" ",
-"SET SSH IDENTITY-FILE filename [ filename [ ... ] ]",
-" Specifies one or more files from which the user's authorization",
-" identities (private keys) are to be read when using public key",
-" authorization. These are files used in addition to the default files:",
-" ",
-" \\v(appdata)ssh/identity V1 RSA",
-" \\v(appdata)ssh/id_rsa V2 RSA",
-" \\v(appdata)ssh/id_dsa V2 DSA",
-" ",
-"SET SSH KERBEROS4 TGT-PASSING { ON, OFF }",
-" Specifies whether Kermit should forward Kerberos 4 TGTs to the host.",
-" The default is OFF.",
-" ",
-"SET SSH KERBEROS5 TGT-PASSING { ON, OFF }",
-" Specifies whether Kermit should forward Kerberos 5 TGTs to to the",
-" host. The default is OFF.",
-" ",
-"SET SSH PRIVILEGED-PORT { ON, OFF }",
-" Specifies whether a privileged port (less than 1024) should be used",
-" when connecting to the host. Privileged ports are not required except",
-" when using SSH V1 with Rhosts or RhostsRSA authorization. The default",
-" is OFF.",
-" ",
-"SET SSH QUIET { ON, OFF }",
-" Specifies whether all messages generated in conjunction with SSH",
-" protocols should be suppressed. The default is OFF.",
-" ",
-"SET SSH STRICT-HOST-KEY-CHECK { ASK, ON, OFF }",
-" Specifies how Kermit should behave if the the host key check fails.",
-" When strict host key checking is OFF, the new host key is added to the",
-" protocol-version-specific user-known-hosts-file. When strict host key",
-" checking is ON, the new host key is refused and the connection is",
-" dropped. When set to ASK, Kermit prompt you to say whether the new",
-" host key should be accepted. The default is ASK.",
-" ",
-" Strict host key checking protects you against Trojan horse attacks.",
-" It depends on you to maintain the contents of the known-hosts-file",
-" with current and trusted host keys.",
-" ",
-"SET SSH USE-OPENSSH-CONFIG { ON, OFF }",
-" Specifies whether Kermit should parse an OpenSSH configuration file",
-" after applying Kermit's SET SSH commands. The configuration file",
-" would be located at \\v(home)ssh/ssh_config. The default is OFF.",
-" ",
-"SET SSH V1 CIPHER { 3DES, BLOWFISH, DES }",
-" Specifies which cipher should be used to protect SSH version 1",
-" connections. The default is 3DES.",
-" ",
-"SET SSH V1 GLOBAL-KNOWN-HOSTS-FILE filename",
-" Specifies the location of the system-wide known-hosts file. The",
-" default is:",
-" ",
-" \v(common)ssh_known_hosts",
-" ",
-"SET SSH V1 USER-KNOWN-HOSTS-FILE filename",
-" Specifies the location of the user-known-hosts-file. The default",
-" location is:",
-" ",
-" \\v(appdata)ssh/known_hosts",
-" ",
-"SET SSH V2 AUTHENTICATION { EXTERNAL-KEYX, GSSAPI, HOSTBASED, ",
-" KEYBOARD-INTERACTIVE, PASSWORD, PUBKEY, SRP-GEX-SHA1 } [ ... ]",
-" Specifies an ordered list of SSH version 2 authentication methods to",
-" be used when connecting to the remote host. The default list is:",
-" ",
-" external-keyx gssapi hostbased publickey srp-gex-sha1 publickey",
-" keyboard-interactive password none",
-" ",
-"SET SSH V2 AUTO-REKEY { ON, OFF }",
-" Specifies whether Kermit automatically issues rekeying requests",
-" once an hour when SSH version 2 in in use. The default is ON.",
-" ",
-"SET SSH V2 CIPHERS { 3DES-CBC, AES128-CBC AES192-CBC AES256-CBC",
-" ARCFOUR BLOWFISH-CBC CAST128-CBC RIJNDAEL128-CBC RIJNDAEL192-CBC",
-" RIJNDAEL256-CBC }",
-" Specifies an ordered list of SSH version ciphers to be used to encrypt",
-" the established connection. The default list is:",
-" ",
-" aes128-cbc 3des-cbc blowfish-cbc cast128-cbc arcfour aes192-cbc",
-" aes256-cbc",
-" ",
-" \"rijndael\" is an alias for \"aes\".",
-" ",
-"SET SSH V2 GLOBAL-KNOWN-HOSTS-FILE filename",
-" Specifies the location of the system-wide known-hosts file. The default",
-" location is:",
-" ",
-" \\v(common)ssh/known_hosts2",
-" ",
-"SET SSH V2 HOSTKEY-ALGORITHMS { SSH-DSS, SSH-RSA }",
-" Specifies an ordered list of hostkey algorithms to be used to verify",
-" the identity of the host. The default list is",
-" ",
-" ssh-rsa ssh-dss",
-" ",
-"SET SSH V2 MACS { HMAC-MD5 HMAC-MD5-96 HMAC-RIPEMD160 HMAC-SHA1",
-" HMAC-SHA1-96 }",
-" Specifies an ordered list of Message Authentication Code algorithms to",
-" be used for integrity protection of the established connection. The",
-" default list is:",
-" ",
-" hmac-md5 hmac-sha1 hmac-ripemd160 hmac-sha1-96 hmac-md5-96",
-" ",
-"SET SSH V2 USER-KNOWN-HOSTS-FILE filename",
-" Specifies the location of the user-known-hosts file. The default",
-" location is:",
-" ",
-" \\v(appdata)ssh/known_hosts2",
-" ",
-"SET SSH VERBOSE level",
-" Specifies how many messages should be generated by the OpenSSH engine.",
-" The level can range from 0 to 7. The default value is 2.",
-" ",
-"SET SSH VERSION { 1, 2, AUTOMATIC }",
-" Specifies which SSH version should be negotiated. The default is",
-" AUTOMATIC which means use version 2 if supported; otherwise to fall",
-" back to version 1.",
-" ",
-"SET SSH X11-FORWARDING { ON, OFF }",
-" Specifies whether X Windows System Data is to be forwarded across the",
-" established SSH connection. The default is OFF. When ON, the DISPLAY",
-" value is either set using the SET TELNET ENV DISPLAY command or read",
-" from the DISPLAY environment variable.",
-" ",
-"SET SSH XAUTH-LOCATION filename",
-" Specifies the location of the xauth executable (if provided with the",
-" X11 Server software.)",
-#else /* SSHBUILTIN */
-"Syntax: SET SSH COMMAND command",
-" Specifies the external command to be used to make an SSH connection.",
-" By default it is \"ssh -e none\" (ssh with no escape character).",
-#endif /* SSHBUILTIN */
-""
-};
-#endif /* ANYSSH */
-
-#ifdef NEWFTP
-static char *hmxygpr[] = {
-"Syntax: SET GET-PUT-REMOTE { AUTO, FTP, KERMIT}",
-" Tells Kermit whether GET, PUT, and REMOTE commands should be directed",
-" at a Kermit server or an FTP server. The default is AUTO, meaning that",
-" if you have only one active connection, the appropriate action is taken",
-" when you give a GET, PUT, or REMOTE command. SET GET-PUT-REMOTE FTP forces"
-,
-" Kermit to treat GET, PUT, and REMOTE as FTP client commands; setting this",
-" to KERMIT forces these commands to be treated as Kermit client commands.",
-" NOTE: PUT includes SEND, MPUT, MSEND, and all other similar commands.",
-" Also see HELP REMOTE, HELP SET LOCUS, HELP FTP.",
-""
-};
-#endif /* NEWFTP */
-
-#ifdef LOCUS
-static char *hmxylocus[] = {
-#ifdef KUI
-"Syntax: SET LOCUS { ASK, AUTO, LOCAL, REMOTE }",
-#else
-"Syntax: SET LOCUS { AUTO, LOCAL, REMOTE }",
-#endif /* KUI */
-" Specifies whether unprefixed file management commands should operate",
-" locally or (when there is a connection to a remote FTP or Kermit",
-" server) sent to the server. The affected commands are: CD (CWD), PWD,",
-" CDUP, DIRECTORY, DELETE, RENAME, MKDIR, and RMDIR. To force any of",
-" these commands to be executed locally, give it an L-prefix: LCD, LDIR,",
-" etc. To force remote execution, use the R-prefix: RCD, RDIR, and so",
-" on. SHOW COMMAND shows the current Locus.",
-" ",
-" By default, the Locus for file management commands is switched",
-" automatically whenever you make or close a connection: if you make an",
-" FTP connection, the Locus becomes REMOTE; if you close an FTP connection",
-" or make any other kind of connection, the Locus becomes LOCAL.",
-#ifdef KUI
-" ",
-" There are two kinds of automatic switching: ASK (the default) which",
-" asks you if it's OK to switch, and AUTO, which switches without asking.",
-#endif /* KUI */
-" ",
-" If you give a SET LOCUS LOCAL or SET LOCUS REMOTE command, this sets",
-" the locus as indicated and disables automatic switching.",
-#ifdef KUI
-" SET LOCUS AUTO or SET LOCUS ASK restores automatic switching.",
-" You can also change Locus switching and behavior in the Actions menu.",
-#else
-" SET LOCUS AUTO restores automatic switching.",
-#endif /* KUI */
-"",
-};
-#endif /* LOCUS */
-
-#ifdef UNIX
-#ifndef NOPUTENV
-static char *hmxxputenv[] = {
-"Syntax: PUTENV name value",
-" Creates or modifies the environment variable with the given name to have",
-" the given value. Purpose: to pass parameters to subprocesses without",
-" having them appear on the command line. If the value is blank (empty),",
-" the variable is deleted. The result is visible to this instantiation of",
-" C-Kermit via \\$(name) and to any inferior processes by whatever method",
-" they use to access environment variables. The value may be enclosed in",
-" doublequotes or braces, but it need not be; if it is the outermost",
-" doublequotes or braces are removed.",
-" ",
-" Note the syntax:",
-" PUTENV name value",
-" not:",
-" PUTENV name=value",
-" ",
-" There is no equal sign between name and value, and the name itself may",
-" not include an equal sign.",
-"",
-};
-#endif /* NOPUTENV */
-#endif /* UNIX */
-
-static char *hmxxtak[] = {
-"Syntax: TAKE filename [ arguments ]",
-" Tells Kermit to execute commands from the named file. Optional argument",
-" words, are automatically assigned to the macro argument variables \\%1",
-" through \\%9. Kermit command files may themselves contain TAKE commands,",
-" up to any reasonable depth of nesting.",
-""
-};
-
-#ifdef TCPSOCKET
-static char *hmxxfirew[] = {
-#ifdef OS2
-"Firewall Traversal in Kermit 95",
-#else
-"Firewall Traversal in C-Kermit",
-#endif
-" ",
-#ifndef NEWFTP
-#ifndef CKHTTP
-#ifndef CK_SOCKS
-#define NOFIREWALL
-#endif
-#endif
-#endif
-#ifdef NOFIREWALL
-"This version of Kermit was built with no support for firewall traversal",
-"protocols. Kermit can be built with support for HTTP Proxy Servers,",
-"SOCKS authorized firewall traversal, and FTP Passive connection modes.",
-" ",
-#else /* NOFIREWALL */
-#ifdef CKHTTP
-"The simplist form of firewall traversal is the HTTP CONNECT command. The",
-"CONNECT command was implemented to allow a public web server which usually",
-"resides on the boundary between the public and private networks to forward",
-"HTTP requests from clients on the private network to public web sites. To",
-"allow secure web connections, the HTTP CONNECT command authenticates the",
-"client with a username/password and then establishes a tunnel to the",
-"desired host.",
-
-" ",
-
-"Web servers that support the CONNECT command can be configured to allow",
-"outbound connections for authenticated users to any TCP/IP hostname-port",
-"combination accessible to the Web server. HTTP CONNECT can be used only",
-"with TCP-based protocols. Protocols such as Kerberos authentication that",
-"use UDP/IP cannot be tunneled using HTTP CONNECT.",
-
-" ",
-
-"SET TCP HTTP-PROXY [switches] [<hostname or ip-address>[:<port>]]",
-" If a hostname or ip-address is specified, Kermit uses the given",
-" proxy server when attempting outgoing TCP connections. If no hostnamer",
-" or ip-address is specified, any previously specified Proxy server is",
-" removed. If no port number is specified, the \"http\" service is used.",
-" [switches] can be one or more of:",
-" /AGENT:<agent> /USER:<user> /PASSWORD:<password>",
-" Switch parameters are used when connecting to the proxy server and",
-" override any other values associated with the connection.",
-" ",
-
-#endif /* CKHTTP */
-#ifdef CK_SOCKS
-
-"In the early 1990s as firewalls were becoming prevalent, David Koblas",
-"developed the SOCKS protocol for TCP/IP firewall traversal. Two versions",
-"of SOCKS are currently in use: Version 4.2 lets TCP/IP client applications",
-"traverse firewalls, similar to HTTP CONNECT, except that the SOCKS client",
-"is aware of the public source IP address and port, which can be used within",
-"the application protocol to assist in securing the connection (e.g. FTP",
-"sessions secured with GSSAPI Kerberos 5).",
-
-" ",
-
-"In 1995 the IETF issued SOCKS Protocol Version 5 (RFC 1928), which is",
-"significantly more general than version 4. Besides supporting client-",
-"to-server TCP/IP connections, it also includes:",
-
-" ",
-" . Authenticated firewall traversal of UDP/IP packets.",
-" . Authenticated binding of incoming public ports on the firewall.",
-" ",
-
-"This lets a service on the private network offer public services. It also",
-"lets client applications like FTP establish a temporary public presence",
-"that can be used by the FTP server to create a data channel. By allowing",
-"the client to bind to a public port on the firewall and be aware of the",
-"public address, SOCKS 5 lets the application protocol communicate this",
-"information to the server.",
-
-" ",
-
-#ifdef OS2
-#ifdef NT
-"Kermit 95 supports SOCKS 4.2. The SOCKS Server is specified with:",
-" ",
-" SET TCP SOCKS-SERVER hostname/ip-address",
-" ",
-"The SOCKS.CONF file is found by examining the ETC environment variable;",
-"searching in \\WINDOWS on Windows 95/98/ME; or the",
-"\\WINDOWS\\SYSTEM\\DRIVERS\\ETC directory on NT\\2000\\XP systems.",
-
-#else /* NT */
-
-"Kermit/2 provides support for SOCKS 4.2 servers when using IBM TCP/IP 2.0,",
-"IBM OS/2 WARP, or a compatible protocol stack. SOCKS is one popular means",
-"of implementing a firewall between a private network and the Internet.",
-" ",
-"Kermit/2 shares the same SOCKS environment variables as IBM Gopher. It also",
-"supports the use of local SOCKS configuration files.",
-" ",
-"To specify the default SOCKS Server, add SET SOCKS_SERVER= to your",
-"CONFIG.SYS file.",
-" ",
-"If you must use a SOCKS Distributed Name Server, add SET SOCKS_NS= to your",
-"CONFIG.SYS file.",
-" ",
-
-"If you must use a specific with your SOCKS server, be sure to add SET USER=",
-"to your CONFIG.SYS file. Otherwise, \"os2user\" is used by default.",
-
-" ",
-
-"The SOCKS configuration file must be placed in the directory pointed to by",
-"the ETC environment variable as declared in your CONFIG.SYS file. The name",
-"should be SOCKS.CONF. On a FAT file system, use SOCKS.CNF.",
-
-" ",
-"The format of the lines in the SOCKS configuration file are as follows:",
-" ",
-" . # comments",
-" . deny [*=userlist] dst_addr dst_mask [op port]",
-" . direct [*=userlist] dst_addr dst_mask [op port]",
-" . sockd [@=serverlist] [*=userlist] dst_addr dst_mask [op port]",
-" ",
-
-"op must be one of 'eq', 'neq', 'lt', 'gt', 'le', or 'ge'. dst_addr,",
-"dst_mask, and port may be either numeric or name equivalents.",
-
-" ",
-
-"Kermit/2 ignores the [*=userlist] and [@=serverlist] fields. Matches are",
-"determined on a first match not a best match basis. Addresses for which no",
-"match is found default to \"sockd\".",
-
-" ",
-
-"For completeness: Fields in square brackets are optional. The optional",
-"@=serverlist field with a 'sockd' line specifies the list of SOCKS servers",
-"the client should try (in the given order) instead of the default SOCKS",
-"server. If the @=serverlist part is omitted, then the default SOCKS server",
-"is used. Commas are used in the userlist and serverlist as separators, no",
-"white spaces are allowed.",
-
-#endif /* NT */
-
-" ",
-
-#else /* OS2 */
-#ifdef CK_SOCKS5
-"This version of C-Kermit supports SOCKS version 5.",
-#else /* CK_SOCKS5 */
-"This version of C-Kermit supports SOCKS version 4.",
-#endif /* CK_SOCKS5 */
-
-"See the man page (or other system documentation) for information on",
-"configuring the SOCKS library via the /etc/socks.conf file.",
-
-#endif /* OS2 */
-" ",
-#endif /* CK_SOCKS */
-
-#ifdef NEWFTP
-
-"FTP is one of the few well-known Internet services that requires",
-"multiple connections. As described above, FTP originally required the",
-"server to establish the data connection to the client using a destination",
-"address and port provided by the client. This doesn't work with port",
-"filtering firewalls.",
-
-" ",
-
-"Later, FTP protocol added a \"passive\" mode, in which connections for",
-"the data channels are created in the reverse direction. Instead of the",
-"server establishing a connection to the client, the client makes a second",
-"connection with the server as the destination. This works just fine as",
-"long as the client is behind the firewall and the server is in public",
-"address space. If the server is behind a firewall then the traditional",
-"active mode must be used. If both the client and server are behind their",
-"own port filtering firewalls then data channels cannot be established.",
-
-" ",
-
-"In Kermit's FTP client, passive mode is controlled with the command:",
-
-" ",
-" SET FTP PASSIVE-MODE { ON, OFF }",
-" ",
-
-"The default is ON, meaning to use passive mode.",
-
-#endif /* NEWFTP */
-#endif /* NOFIREWALL */
-
-""
-};
-#endif /* TCPSOCKET */
-
-static char *hmxxsave[] = {
-"Syntax: SAVE item filename { NEW, APPEND }",
-" Saves the requested material in the given file. A new file is created",
-" by default; include APPEND at the end of the command to append to an",
-" existing file. Items:",
-#ifndef NOSETKEY
-" KEYMAP Saves the current key settings.",
-#endif /* NOSETKEY */
-#ifdef CK_RECALL
-" COMMAND HISTORY Saves the current command recall (history) buffer",
-#endif /* CK_RECALL */
-#ifdef OS2
-" COMMAND SCROLLBACK Saves the current command-screen scrollback buffer",
-" TERMINAL SCROLLBACK Saves the current terminal-screen scrollback buffer",
-#endif /* OS2 */
-""
-};
-
-#ifdef CKROOT
-static char *hmxxchroot[] = {
-"Syntax: SET ROOT directoryname",
-" Sets the root for file access to the given directory and disables access",
-" to system and shell commands and external programs. Once this command",
-" is given, no files or directories outside the tree rooted by the given",
-" directory can be opened, read, listed, deleted, renamed, or accessed in",
-" any other way. This command can not be undone by a subsequent SET ROOT",
-" command. Primarily for use with server mode, to restrict access of",
-" clients to a particular directory tree. Synonym: CHROOT.",
-""
-};
-#endif /* CKROOT */
-
-static char *hmxxscrn[] = {
-"Syntax: SCREEN { CLEAR, CLEOL, MOVE row column }",
-#ifdef OS2
-" Performs screen-formatting actions.",
-#else
-" Performs screen-formatting actions. Correct operation of these commands",
-" depends on proper terminal setup on both ends of the connection -- mainly",
-" that the host terminal type is set to agree with the kind of terminal or",
-" the emulation you are viewing C-Kermit through.",
-#endif /* OS2 */
-" ",
-"SCREEN CLEAR",
-" Moves the cursor to home position and clears the entire screen.",
-#ifdef OS2
-" Synonyms: CLS, CLEAR SCREEN, CLEAR COMMAND-SCREEN ALL",
-#else
-" Synonyms: CLS, CLEAR SCREEN.",
-#endif /* OS2 */
-" ",
-"SCREEN CLEOL",
-" Clears from the current cursor position to the end of the line.",
-#ifdef OS2
-" Synonym: CLEAR COMMAND-SCREEN EOL",
-#endif /* OS2 */
-" ",
-"SCREEN MOVE row column",
-" Moves the cursor to the indicated row and column. The row and column",
-" numbers are 1-based so on a 24x80 screen, the home position is 1 1 and",
-" the lower right corner is 24 80. If a row or column number is given that",
-" too large for what Kermit or the operating system thinks is your screen",
-" size, the appropriate number is substituted.",
-" ",
-"Also see:",
-#ifdef OS2
-" HELP FUNCTION SCRNCURX, HELP FUNCTION SCRNCURY, HELP FUNCTION SCRSTR,",
-#endif /* OS2 */
-" SHOW VARIABLE TERMINAL, SHOW VARIABLE COLS, SHOW VAR ROWS, SHOW COMMAND.",
-""
-};
-
-#ifndef NOSPL
-static char *hmfword[] = {
-"Function \\fword(s1,n1,s2,s3,n2,n3) - Extracts a word from a string.",
-" s1 = source string.",
-" n1 = word number (1-based) counting from left; if negative, from right.",
-" s2 = optional break set.",
-" s3 = optional include set (or ALL, CSV, or TSV).",
-" n2 = optional grouping mask.",
-" n3 = optional separator flag:",
-" 0 = collapse adjacent separators;",
-" 1 = don't collapse adjacent separators.",
-" ",
-" \\fword() returns the n1th \"word\" of the string s1, according to the",
-" criteria specified by the other parameters.",
-" ",
-" The BREAK SET is the set of all characters that separate words. The",
-" default break set is all characters except ASCII letters and digits.",
-" ASCII (C0) control characters are treated as break characters by default,",
-" as are spacing and punctuation characters, brackets, and so on, and",
-" all 8-bit characters.",
-" ",
-" The INCLUDE SET is the set of characters that are to be treated as ",
-" parts of words even though they normally would be separators. The",
-" default include set is empty. Three special symbolic include sets are",
-" also allowed:",
-" ",
-" ALL (meaning include all bytes that are not in the break set)",
-" CSV (special treatment for Comma-Separated-Value records)",
-" TSV (special treatment for Tab-Separated-Value records)",
-" ",
-" For operating on 8-bit character sets, the include set should be ALL.",
-" ",
-" If the GROUPING MASK is given and is nonzero, words can be grouped by",
-" quotes or brackets selected by the sum of the following:",
-" ",
-" 1 = doublequotes: \"a b c\"",
-" 2 = braces: {a b c}",
-" 4 = apostrophes: 'a b c'",
-" 8 = parentheses: (a b c)",
-" 16 = square brackets: [a b c]",
-" 32 = angle brackets: <a b c>",
-" ",
-" Nesting is possible with {}()[]<> but not with quotes or apostrophes.",
-" ",
-"Returns string:",
-" Word number n1, if there is one, otherwise an empty string.",
-" ",
-"Also see:",
-" HELP FUNCTION SPLIT",
-""
-};
-
-static char *hmxxprompt[] = {
-"Syntax: PROMPT [ text ]",
-" Enters interactive command level from within a script in such a way that",
-" the script can be continued with an END or RETURN command. STOP, EXIT,",
-" SHOW STACK, TRACE, and Ctrl-C all have their normal effects. The PROMPT",
-" command allows variables to be examined or changed, or any other commands",
-" to be given, in any number, prior to returning to the script, allowing",
-" Kermit to serve as its own debugger; adding the PROMPT command to a script",
-" is like setting a breakpoint. If the optional text is included, it is",
-" used as the new prompt for this level, e.g. \"prompt Breakpoint_1>\".",
-""
-};
-
-static char *hxxinp[] = {
-"Syntax: INPUT [ /COUNT:n /CLEAR /NOMATCH /NOWRAP ] \
-{ number-of-seconds, time-of-day } [ text ]",
-" ",
-"Examples:",
-" INPUT 5 Login:",
-" INPUT 23:59:59 RING",
-" INPUT /NOMATCH 10",
-" INPUT /CLEAR 10 \\13\\10",
-" INPUT /CLEAR 10 \\13\\10$\32",
-" INPUT /COUNT:256 10",
-" INPUT 10 \\fpattern(<*@*.*>)",
-" ",
-" Waits up to the given number of seconds, or until the given time of day,",
-" for the given text to arrive on the connection. For use in script programs",
-" with IF FAILURE or IF SUCCESS, which tell whether the desired text arrived",
-" within the given amount of time.",
-" ",
-" The text, if given, can be a regular text or it can be a \\pattern()",
-" invocation, in which case it is treated as a pattern rather than a literal",
-" string (HELP PATTERNS for details).",
-" ",
-" If the /COUNT: switch is included, INPUT waits for the given number of",
-" characters to arrive.",
-" ",
-" If no text is specified, INPUT waits for the first character that arrives",
-" and makes it available in the \\v(inchar) variable. This is equivalent to",
-" including a /COUNT: switch with an argument of 1.",
-" ",
-" If the /NOMATCH switch is included, INPUT does not attempt to match any",
-" characters, but continues reading from the communication connection until",
-" the timeout interval expires. If the timeout interval is 0, the INPUT",
-" command does not wait; i.e. the given text must already be available for",
-" reading for the INPUT command to succeed. If the interval is negative,",
-" the INPUT command waits forever.",
-" ",
-" The INPUT buffer, \\v(input), is normally circular. Incoming material is",
-" appended to it until it reaches the end, and then it wraps around to the",
-" beginning. If the /CLEAR switch is given, INPUT clears its buffer before",
-" reading from the connection.",
-" ",
-" Typical example of use:",
-" ",
-" INPUT 10 login:",
-" IF FAIL EXIT 1 \"Timed out waiting for login prompt\"",
-" LINEOUT myuserid",
-" INPUT 10 Password:",
-" IF FAIL EXIT 1 \"Timed out waiting for Password prompt\"",
-" LINEOUT xxxxxxx",
-" ",
-" The /NOWRAP switch means that INPUT should return with failure status",
-" and with \\v(instatus) set to 6 if its internal buffer fills up before",
-" any of the other completion criteria are met. This allows for capture",
-" of the complete incoming data stream (except NUL bytes, which are",
-" discarded). CAUTION: if the search target (if any) spans the INPUT buffer",
-" boundary, INPUT will not succeed.",
-" ",
-" \
-\\v(instatus) values are: 0 (success), 1 (timed out), 2 (keyboard interrupt),",
-" 3 (internal error), 4 (I/O error or connection lost), 5 (INPUT disabled),",
-" and 6 (buffer filled and /NOWRAP set); these are shown by \\v(inmessage).",
-" ",
-" Also see OUTPUT, MINPUT, REINPUT, SET INPUT and CLEAR. See HELP PAUSE for",
-" details on time-of-day format and HELP PATTERNS for pattern syntax.",
-""};
-
-static char *hxxout[] = {
-"Syntax: OUTPUT text",
-" Sends the text out the communications connection, as if you had typed it",
-" during CONNECT mode. The text may contain backslash codes, variables,",
-" etc, plus the following special codes:",
-" ",
-" \\N - Send a NUL (ASCII 0) character (you can't use \\0 for this).",
-" \\B - Send a BREAK signal.",
-" \\L - Send a Long BREAK signal.",
-" ",
-"Also see SET OUTPUT.",
-"" };
-#endif /* NOSPL */
-
-static char *hxypari[] = {
-"SET PARITY NONE",
-" Chooses 8 data bits and no parity.",
-" ",
-"SET PARITY { EVEN, ODD, MARK, SPACE }",
-" Chooses 7 data bits plus the indicated kind of parity.",
-" Forces 8th-bit prefixing during file transfer.",
-" ",
-#ifdef HWPARITY
-"SET PARITY HARDWARE { EVEN, ODD }",
-" Chooses 8 data bits plus the indicated kind of parity.",
-" ",
-"Also see SET TERMINAL BYTESIZE, SET SERIAL, and SET STOP-BITS.",
-#else
-"Also see SET TERMINAL BYTESIZE and SET SERIAL.",
-#endif /* HWPARITY */
-""};
-
-#ifndef NOLOCAL
-static char *hxyesc[] = {
-#ifdef OS2
-"Syntax: SET ESCAPE number",
-" Decimal ASCII value for escape character during CONNECT, normally 29",
-" (Control-]). Type the escape character followed by C to get back to the",
-" C-Kermit prompt or followed by ? to see other options, or use the \\Kexit",
-" keyboard verb, normally assigned to Alt-x.",
-#else
-#ifdef NEXT
-"Syntax: SET ESCAPE number",
-" Decimal ASCII value for escape character during CONNECT, normally 29",
-" (Control-]). Type the escape character followed by C to get back to the",
-" C-Kermit prompt or followed by ? to see other options.",
-#else
-"Syntax: SET ESCAPE number",
-" Decimal ASCII value for escape character during CONNECT, normally 28",
-" (Control-\\). Type the escape character followed by C to get back to the",
-" C-Kermit prompt or followed by ? to see other options.",
-#endif /* NEXT */
-#endif /* OS2 */
-" ",
-"You may also enter the escape character as ^X (circumflex followed by a",
-"letter or one of: @, ^, _, [, \\, or ], to indicate a control character;",
-"for example, SET ESC ^_ sets your escape character to Ctrl-Underscore.",
-" ",
-"You can also specify an 8-bit character (128-255) as your escape character,",
-"either by typing it literally or by entering its numeric code.",
-"" };
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
-static char *hxyout[] = {
-"SET OUTPUT PACING <number>",
-" How many milliseconds to pause after sending each OUTPUT character,",
-" normally 0.",
-" ",
-"SET OUTPUT SPECIAL-ESCAPES { ON, OFF }",
-" Whether to process the special OUTPUT-only escapes \\B, \\L, and \\N.",
-" Normally ON (they are processed).",
-"" };
-
-static char *hxyinp[] = {
-"Syntax: SET INPUT parameter value",
-" ",
-#ifdef CK_AUTODL
-"SET INPUT AUTODOWNLOAD { ON, OFF }",
-" Controls whether autodownloads are allowed during INPUT command execution.",
-" ",
-#endif /* CK_AUTODL */
-"SET INPUT BUFFER-LENGTH number-of-bytes",
-" Removes the old INPUT buffer and creates a new one with the given length.",
-" ",
-"SET INPUT CANCELLATION { ON, OFF }",
-" Whether an INPUT in progress can be can interrupted from the keyboard.",
-" ",
-"SET INPUT CASE { IGNORE, OBSERVE }",
-" Tells whether alphabetic case is to be significant in string comparisons.",
-" This setting is local to the current macro or command file, and is",
-" inherited by subordinate macros and take files.",
-" ",
-"SET INPUT ECHO { ON, OFF }",
-" Tells whether to display arriving characters read by INPUT on the screen.",
-" ",
-#ifdef CKFLOAT
-"SET INPUT SCALE-FACTOR <number>",
-" A number to multiply all INPUT timeouts by, which may include a fractional",
-" part, e.g. 2.5. All INPUT commands that specify a timeout in seconds",
-" (as opposed to a specific time of day) have their time limit adjusted",
-" automatically by this factor, which is also available in the built-in",
-" read-only variable \\v(inscale). The default value is 1.0.",
-" ",
-
-#endif /* CKFLOAT */
-
-"SET INPUT SILENCE <number>",
-" The maximum number to seconds of silence (no input at all) before the",
-" INPUT command times out, 0 for no maximum.",
-" ",
-#ifdef OS2
-"SET INPUT TERMINAL { ON, OFF }",
-" Determines whether the data received during an INPUT command is displayed",
-" in the terminal window. Default is ON.",
-" ",
-#endif /* OS2 */
-"SET INPUT TIMEOUT-ACTION { PROCEED, QUIT }",
-" Tells whether to proceed or quit from a script program if an INPUT command",
-" fails. PROCEED (default) allows use of IF SUCCESS / IF FAILURE commands.",
-" This setting is local to the current macro or command file, and is",
-" inherited by subordinate macros and take files.",
-"" };
-
-static char *hxyfunc[] = {
-"SET FUNCTION DIAGNOSTICS { ON, OFF }",
-" Whether to issue diagnostic messages for illegal function calls and",
-" references to nonexistent built-in variables. ON by default.",
-" ",
-"SET FUNCTION ERROR { ON, OFF }",
-" Whether an illegal function call or reference to a nonexistent built-in",
-" variable should cause a command to fail. OFF by default.",
-"" };
-#endif /* NOSPL */
-
-static char *hxyxyz[] = {
-#ifdef CK_XYZ
-#ifdef XYZ_INTERNAL
-
-/* This is for built-in protocols */
-
-"Syntax: SET PROTOCOL { KERMIT, XMODEM, YMODEM, ZMODEM } [ s1 s2 [ s3 ] ]",
-" Selects protocol to use for transferring files. String s1 is a command to",
-" send to the remote host prior to SENDing files with this protocol in",
-" binary mode; string s2 is the same thing but for text mode. Use \"%s\" in",
-" any of these strings to represent the filename(s). If the protocol is",
-" KERMIT, you may also specify a string s3, the command to start a Kermit",
-" server on the remote host when you give a GET, REGET, REMOTE, or other",
-" client command. Use { braces } if any command contains spaces. Examples:",
-" ",
-" set proto xmodem {rx %s} {rx -a %s}",
-" set proto kermit {kermit -YQir} {kermit -YQTr} {kermit -YQx}",
-
-#else /* This is for when non-Kermit protocols are external */
-
-"Syntax: \
-SET PROTOCOL { KERMIT, XMODEM, YMODEM, ZMODEM } [ s1 s2 s3 s4 s5 s6 ]",
-" Selects protocol to use for transferring files. s1 and s2 are commands to",
-" output prior to SENDing with this protocol, to automatically start the",
-" RECEIVE process on the other end in binary or text mode, respectively.",
-" If the protocol is KERMIT, s3 is the command to start a Kermit server on",
-" the remote computer, and there are no s4-s6 commands. Otherwise, s3 and",
-" s4 are commands used on this computer for sending files with this protocol",
-" in binary or text mode, respectively; s5 and s6 are the commands for",
-" receiving files with this protocol. Use \"%s\" in any of these strings",
-" to represent the filename(s). Use { braces } if any command contains",
-" spaces. Examples:",
-" ",
-" set proto kermit {kermit -YQir} {kermit -YQTr} {kermit -YQx}",
-" set proto ymodem rb {rb -a} {sb %s} {sb -a %s} rb rb",
-" ",
-"External protocols require REDIRECT and external file transfer programs that",
-"use redirectable standard input/output.",
-#endif /* XYZ_INTERNAL */
-#else
-"Syntax: \
-SET PROTOCOL KERMIT [ s1 [ s2 [ s3 ] ] ]",
-" Lets you specify the autoupload binary, autoupload text, and autoserver",
-" command strings to be sent to the remote system in advance of any SEND",
-" or GET commands. By default these are \"kermit -ir\", \"kermit -r\", and",
-" \"kermit -x\". Use { braces } around any command that contains spaces.",
-" Example:",
-" ",
-" set proto kermit {kermit -Yir} {kermit -YTr} {kermit -Yx}",
-#endif /* CK_XYZ */
-" ",
-" SHOW PROTOCOL displays the current settings.",
-""};
-
-static char *hmxxbye = "Syntax: BYE\n\
- Shut down and log out a remote Kermit server";
-
-#ifdef CK_PERMS
-#ifdef UNIX
-static char *hmxxchmod[] = {
-"Syntax: CHMOD [ switches ] code filespec",
-" UNIX only. Changes permissions of the given file(s) to the given code,",
-" which must be an octal number such as 664 or 775. Optional switches:",
-" ",
-" /FILES Only change permissions of regular files.",
-" /DIRECTORIES Only change permissions of directory files.",
-" /TYPE:BINARY Only change permissions of binary files.",
-" /TYPE:TEXT Only change permissions of text files.",
-" /DOTFILES Include files whose names begin with dot (.).",
-" /RECURSIVE Change permissions in subdirectories too.",
-" /LIST List each file (synonym: /VERBOSE).",
-" /NOLIST Operate silently (synonym: /QUIET).",
-" /PAGE When listing, pause at end of each screen (implies /LIST).",
-" /NOPAGE When listing, don't pause at end of each screen.",
-" /SIMULATE Show what would be done but don't actually do it.",
-""
-};
-#endif /* UNIX */
-#endif /* CK_PERMS */
-
-#ifndef NOSPL
-#ifndef NOSEXP
-static char *hmxxsexp[] = {
-"Syntax: (operation operand [ operand [ ... ] ])",
-" ",
-" C-Kermit includes a simple LISP-like S-Expression parser operating on",
-" numbers only. An S-Expression is always enclosed in parentheses. The",
-" parentheses can contain (a) a number, (b) a variable, (c) a function that",
-" returns a number, or (d) an operator followed by one or more operands.",
-" Operands can be any of (a) through (c) or an S-Expression. Numbers can be",
-" integers or floating-point. Any operand that is not a number and does not",
-" start with backslash (\\) is treated as a Kermit macro name. Operators:",
-" ",
-" Operator Action Example Value",
-" EVAL (.) Returns the contained value (6) 6",
-" QUOTE (') Inhibits evaluation of following value (quote a) a",
-" SETQ Assigns a value to a global variable (setq a 2) 2",
-" LET Assigns a value to a local variable (let b -1.3) -1.3",
-" + Adds all operands (1 or more) (+ a b) 0.7",
-" - Subtracts all operands (1 or more) (- 9 5 2 1) 1",
-" * Multiplies all operands (1 or more) (* a (+ b 1) 3) -1.8",
-" / Divides all operands (1 or more) (/ b a 2) -0.325",
-" ^ Raise given number to given power (^ 3 2) 9",
-" ++ Increments a variable (++ a 1.2) 3.2",
-" -- Decrements a variable (-- a) 1",
-" ABS Absolute value of 1 operand (abs (* a b 3)) 7.8",
-" MAX Maximum of all operands (1 or more) (max 1 2 3 4) 4",
-" MIN Minimum of all operands (1 or more) (min 1 2 3 4) 1",
-" MOD Modulus of all operands (1 or more) (mod 7 4 2) 1",
-" TRUNCATE Integer part of floating-point operand (truncate 1.333) 1",
-" CEILING Ceiling of floating-point operand (ceiling 1.25) 2",
-" FLOOR Floor of floating-point operand (floor 1.25) 1",
-" ROUND Operand rounded to nearest integer (round 1.75) 2",
-" SQRT Square root of 1 operand (sqrt 2) 1.414..",
-" EXP e (2.71828..) to the given power (exp -1) 0.367..",
-" SIN Sine of angle expressed in radians (sin (/ pi 2)) 1.0",
-" COS Cosine of given number (cos pi) -1.0",
-" TAN Tangent of given number (tan pi) 0.0",
-" LOG Natural log (base e) of given number (log 2.7183) 1.000..",
-" LOG10 Log base 10 of given number (log10 1000) 3.0",
-" ",
-"Predicate operators return 0 if false, 1 if true, and if it is the outermost",
-"operator, sets SUCCESS or FAILURE accordingly:",
-" ",
-" < Operands in strictly descending order (< 6 5 4 3 2 1) 1",
-" <= Operands in descending order (<= 6 6 5 4 3 2) 1",
-" != Operands are not equal (!= 1 1 1.0) 0",
-" = (==) All operands are equal (= 3 3 3 3) 1",
-" > Operands in strictly ascending order (> 1 2 3 4 5 6) 1",
-" >= Operands in ascending order (> 1 1 2 3 4 5) 1",
-" AND (&&) Operands are all true (and 1 1 1 1 0) 0",
-" OR (||) At least one operand is true (or 1 1 1 1 0) 1",
-" XOR Logical Exclusive OR (xor 3 1) 0",
-" NOT (!) Reverses truth value of operand (not 3) 0",
-" ",
-"Bit-oriented operators:",
-" ",
-" & Bitwise AND (& 7 2) 2",
-" | Bitwise OR (| 1 2 3 4) 7",
-" # Bitwise Exclusive OR (# 3 1) 2",
-" ~ Reverses all bits (~ 3) -4",
-" ",
-"Operators that work on truth values:",
-" ",
-" IF Conditional evaluation (if (1) 2 3) 2",
-" ",
-"Operators can also be names of Kermit macros that return either numeric",
-"values or no value at all.",
-" ",
-"Built-in constants are:",
-" ",
-" t True (1)",
-" nil False (empty)",
-" pi The value of Pi (3.1415926...)",
-" ",
-"If SET SEXPRESSION TRUNCATE-ALL-RESULTS is ON, all results are trunctated",
-"to integer values by discarding any fractional part. Otherwise results",
-"are floating-point if there fractional part and integer otherwise.",
-"If SET SEXPRESSION ECHO-RESULT is AUTO (the default), the value of the",
-"S-Expression is printed if the S-Expression is given at top level; if ON,",
-"it is printed at any level; if OFF it is not printed. At all levels, the",
-"variable \\v(sexpression) is set to the most recent S-Expression, and",
-"\\v(svalue) is set to its value. You can use the \\fsexpresssion() function",
-"to evaluate an S-Expression anywhere in a Kermit command.",
-""
-};
-#endif /* NOSEXP */
-#endif /* NOSPL */
-
-static char *hmxxgrep[] = {
-#ifdef UNIXOROSK
-"Syntax: GREP [ options ] pattern filespec",
-#else
-"Syntax: FIND [ options ] pattern filespec",
-#endif /* UNIXOROSK */
-" Searches through the given file or files for the given character string",
-" or pattern. In the normal case, all lines containing any text that matches"
-,
-" the pattern are printed. Pattern syntax is as described in HELP PATTERNS",
-" except that '*' is implied at the beginning unless the pattern starts with",
-" '^' and also at the end unless the pattern ends with '$'. Therefore,",
-" \"grep something *.txt\" lists all lines in all *.txt files that contain",
-" the word \"something\", but \"grep ^something *.txt\" lists only the lines",
-" that START with \"something\". The command succeeds if any of the given",
-" files contained any lines that match the pattern, otherwise it fails.",
-#ifdef UNIXOROSK
-" Synonym: FIND.",
-#else
-" Synonym: GREP.",
-#endif /* UNIXOROSK */
-" ",
-"File selection options:",
-" /NOBACKUPFILES",
-" Excludes backup files (like oofa.txt.~3~) from the search.",
-" /DOTFILES",
-" Includes files whose names start with dot (.) in the search.",
-" /NODOTFILES",
-" Excludes files whose names start with dot (.) from the search.",
-#ifdef RECURSIVE
-" /RECURSIVE",
-" Searches through files in subdirectories too.",
-#endif /* RECURSIVE */
-" /TYPE:TEXT",
-" Search only text files (requires FILE SCAN ON).",
-" /TYPE:BINARY",
-" Search only binary files (requires FILE SCAN ON).",
-" ",
-"Pattern-matching options:",
-" /NOCASE",
-" Ignores case of letters (ASCII only) when comparing.",
-" /NOMATCH",
-" Searches for lines that do NOT match the pattern.",
-" /EXCEPT:pattern",
-" Exclude lines that match the main pattern that also match this pattern.",
-" ",
-"Display options:",
-" /COUNT:variable-name",
-" For each file, prints only the filename and a count of matching lines",
-" and assigns the total match count to the variable, if one is given.",
-" /NAMEONLY",
-" Prints the name of each file that contains at least one matching line,",
-" one name per line, rather than showing each matching line.",
-" /NOLIST",
-" Doesn't print anything (but sets SUCCESS or FAILURE appropriately).",
-" /LINENUMBERS",
-" Precedes each file line by its line number within the file.",
-" /PAGE",
-" Pauses after each screenful.",
-" /NOPAGE",
-" Doesn't pause after each screenful.",
-" /OUTPUT:name",
-" Sends results to the given file. If this switch is omitted, the",
-" results appear on your screen. This switch overrides any express or",
-" implied /PAGE switch.",
-""};
-
-static char *hmxxdir[] = {
-#ifdef DOMYDIR
-"Syntax: DIRECTORY [ switches ] [ filespec [ filespec [ ... ] ] ]",
-#ifdef LOCUS
-" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,",
-" this command is equivalent to REMOTE DIRECTORY (RDIR). Otherwise:",
-" ",
-#endif /* LOCUS */
-" Lists local files. The filespec may be a filename, possibly containing",
-" wildcard characters, or a directory name. If no filespec is given, all",
-" files in the current directory are listed. If a directory name is given,",
-" all the files in it are listed. Multiple filespecs can be given.",
-" Optional switches:",
-" ",
-" /BRIEF List filenames only.",
-#ifdef CK_PERMS
-" /VERBOSE + Also list permissions, size, and date.",
-#else
-" /VERBOSE + Also list date and size.",
-#endif /* CK_PERMS */
-" /FILES Show files but not directories.",
-" /DIRECTORIES Show directories but not files.",
-" /ALL + Show both files and directories.",
-" /ARRAY:&a Store file list in specified array (e.g. \\%a[]).",
-" /PAGE Pause after each screenful.",
-" /NOPAGE Don't pause after each screenful.",
-" /TOP:n Only show the top n lines of the directory listing.",
-#ifdef UNIXOROSK
-" /DOTFILES Include files whose names start with dot (period).",
-" /NODOTFILES + Don't include files whose names start with dot.",
-" /FOLLOWLINKS Follow symbolic links.",
-" /NOFOLLOWLINKS + Don't follow symbolic links.",
-" /NOLINKS Don't list symbolic links at all.",
-" /BACKUP + Include backup files (names end with .~n~).",
-" /NOBACKUPFILES Don't include backup files.",
-#endif /* UNIXOROSK */
-" /OUTPUT:file Store directory listing in the given file.",
-" /HEADING Include heading and summary.",
-" /NOHEADING + Don't include heading or summary.",
-" /COUNT:var Put the number of matching files in the given variable.",
-" /SUMMARY Print only count and total size of matching files.",
-" /XFERMODE Show pattern-based transfer mode (T=Text, B=Binary).",
-" /TYPE: Show only files of the specified type (text or binary).",
-" /MESSAGE:text Add brief message to each listing line.",
-" /NOMESSAGE + Don't add message to each listing line.",
-" /NOXFERMODE + Don't show pattern-based transfer mode",
-" /ISODATE + In verbose listings, show date in ISO 8061 format.",
-" /ENGLISHDATE In verbose listings, show date in \"English\" format.",
-#ifdef RECURSIVE
-" /RECURSIVE Descend through subdirectories.",
-" /NORECURSIVE + Don't descend through subdirectories.",
-#endif /* RECURSIVE */
-" /SORT:key Sort by key, NAME, DATE, or SIZE; default key is NAME.",
-" /NOSORT + Don't sort.",
-" /ASCENDING + If sorting, sort in ascending order.",
-" /REVERSE If sorting, sort in reverse order.",
-" ",
-"Factory defaults are marked with +. Default for paging depends on SET",
-"COMMAND MORE-PROMPTING. Use SET OPTIONS DIRECTORY [ switches ] to change",
-"defaults; use SHOW OPTIONS to display customized defaults. Also see",
-"WDIRECTORY.",
-#else
-"Syntax: DIRECTORY [ filespec ]",
-" Lists the specified file or files. If no filespec is given, all files",
-" in the current directory are listed.",
-#endif /* DOMYDIR */
-""};
-
-static char *hmxxtouc[] = {
-"Syntax: TOUCH [ switches ] filespec",
-" Updates the modification time of the given file or files to the current",
-" date and time. If the filespec is the name of a single file that does not",
-" exist, the file is created. The optional switches are the same as for",
-" the DIRECTORY command. TOUCH operates silently unless the /VERBOSE",
-" switch is given, in which case it lists each file it affects.",
-""};
-
-#ifndef NOSPL
-static char *hmxxkcd[] = {
-"Syntax: KCD symbolic-directory-name",
-" Kermit Change Directory: Like CD (q.v.) but (a) always acts locally, and",
-" (b) takes a symbolic directory name rather than an actual directory name.",
-" The symbolic names correspond to Kermit's directory-valued built-in",
-" variables, such as \\v(download), \\v(exedir), and so on. Here's the list:"
-,
-" ",
-#ifdef NT
-" appdata Your personal Kermit 95 application data directory",
-" common Kermit 95's application data directory for all users",
-" desktop Your Windows desktop",
-#endif /* NT */
-" download Your download directory (if any)",
-#ifdef OS2ORUNIX
-" exedir The directory where the Kermit executable resides",
-#endif /* OS2ORUNIX */
-" home Your home, login, or default directory",
-" inidir The directory where Kermit's initialization was found",
-#ifdef UNIX
-" lockdir The UNIX UUCP lockfile directory on this computer",
-#endif /* UNIX */
-#ifdef NT
-" personal Your \"My Documents\" directory",
-#endif /* NT */
-" startup Your current directory at the time Kermit started",
-" textdir The directory where Kermit text files reside, if any",
-" tmpdir Your temporary directory",
-" ",
-" Also see CD, SET FILE DOWNLOAD, SET TEMP-DIRECTORY.",
-""
-};
-#endif /* NOSPL */
-
-static char *hmxxcwd[] = {
-#ifdef LOCUS
-" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,",
-" this command is equivalent to REMOTE CD (RCD). Otherwise:",
-" ",
-#endif /* LOCUS */
-#ifdef vms
-"Syntax: CD [ directory or device:directory ]",
-" Change Working Directory. Equivalent to VMS SET DEFAULT command.",
-#else
-#ifdef datageneral
-"Change Working Directory, equivalent to AOS/VS 'dir' command.",
-#else
-#ifdef OS2
-"Syntax: CD [ disk or directory name ]",
-" Change Disk or Directory. If a disk or directory name is not specified,",
-" your current directory becomes the one specified by HOME environment",
-" variable, if any. A disk letter must be followed by a colon.",
-#else
-"Syntax: CD [ directory name ]",
-" Change Directory. Changes your current, working, default directory to the",
-" one given, so that future non-absolute filename references are relative to",
-" this directory. If the directory name is omitted, your home (login)",
-" directory is supplied.",
-#endif /* OS2 */
-#endif /* datageneral */
-#endif /* vms */
-" C-Kermit's default prompt shows your current directory.",
-" Synonyms: LCD, CWD.",
-#ifdef LOCUS
-" Also see: SET LOCUS, PWD, CDUP, BACK, REMOTE CD (RCD), SET CD, SET PROMPT.",
-#else
-" Also see: PWD, CDUP, BACK, REMOTE CD (RCD), SET CD, SET PROMPT.",
-#endif /* LOCUS */
-#ifndef NOSPL
-" And see: HELP KCD.",
-#endif /* NOSPL */
-" Relevant environment variables: CDPATH, HOME.",
-""};
-
-static char *hmxxdel[] = {
-"Syntax: DELETE [ switches... ] filespec",
-#ifdef LOCUS
-" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,",
-" this command is equivalent to REMOTE DELETE (RDELETE). Otherwise:",
-" ",
-#endif /* LOCUS */
-" Deletes a file or files on the computer where C-Kermit is running.",
-" The filespec may denote a single file or can include wildcard characters",
-" to match multiple files. RM is a synonym for DELETE. Switches include:",
-" ",
-"/AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files created after the given date-time are",
-#else
-" Specifies that only those files modified after the given date-time are",
-#endif /* VMS */
-" to be deleted. HELP DATE for info about date-time formats.",
-" ",
-"/BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified before the given date-time",
-#else
-" Specifies that only those files modified before the given date-time",
-#endif /* VMS */
-" are to be deleted.",
-" ",
-"/NOT-AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or before the given date-time",
-#else
-" Specifies that only those files modified at or before the given date-time",
-#endif /* VMS */
-" are to be deleted.",
-" ",
-"/NOT-BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or after the given date-time",
-#else
-" Specifies that only those files modified at or after the given date-time",
-#endif /* VMS */
-" are to be deleted.",
-" ",
-"/LARGER-THAN:number",
-" Specifies that only those files longer than the given number of bytes are",
-" to be deleted.",
-" ",
-"/SMALLER-THAN:number",
-" Specifies that only those files smaller than the given number of bytes are",
-" to be sent.",
-" ",
-"/EXCEPT:pattern",
-" Specifies that any files whose names match the pattern, which can be a",
-" regular filename or may contain wildcards, are not to be deleted. To",
-" specify multiple patterns (up to 8), use outer braces around the group",
-" and inner braces around each pattern:",
-" ",
-" /EXCEPT:{{pattern1}{pattern2}...}",
-" ",
-#ifdef UNIXOROSK
-"/DOTFILES",
-" Include (delete) files whose names begin with \".\".",
-" ",
-"/NODOTFILES",
-" Skip (don't delete) files whose names begin with \".\".",
-" ",
-#endif /* UNIXOROSK */
-"/TYPE:TEXT",
-" Delete only regular text files (requires FILE SCAN ON)",
-" ",
-"/TYPE:BINARY",
-" Delete only regular binary files (requires FILE SCAN ON)",
-" ",
-"/DIRECTORIES",
-" Include directories. If this switch is not given, only regular files",
-" are deleted. If it is given, Kermit attempts to delete any directories",
-" that match the given file specification, which succeeds only if the",
-" directory is empty.",
-" ",
-#ifdef RECURSIVE
-"/RECURSIVE",
-" The DELETE command applies to the entire directory tree rooted in the",
-" current or specified directory. When the /DIRECTORIES switch is also",
-" given, Kermit deletes all the (matching) files in each directory before",
-" attempting to delete the directory itself.",
-" ",
-#endif /* RECURSIVE */
-#ifdef UNIX
-#ifdef RECURSIVE
-"/ALL",
-" This is a shortcut for /RECURSIVE /DIRECTORIES /DOTFILES.",
-#else
-"/ALL",
-" This is a shortcut for /DIRECTORIES /DOTFILES.",
-#endif /* RECURSIVE */
-#else /* !UNIX */
-#ifdef RECURSIVE
-"/ALL",
-" This is a shortcut for /RECURSIVE /DIRECTORIES.",
-#else
-"/ALL",
-" This is a synonym for /DIRECTORIES.",
-#endif /* RECURSIVE */
-#endif /* UNIX */
-" ",
-"/LIST",
-" List each file and tell whether it was deleted. Synonyms: /LOG, /VERBOSE.",
-" ",
-"/NOLIST",
-" Don't list files while deleting. Synonyms: /NOLOG, /QUIET.",
-" ",
-"/HEADING",
-" Print heading and summary information.",
-" ",
-"/NOHEADING",
-" Don't print heading and summary information.",
-" ",
-"/SUMMARY",
-" Like /HEADING /NOLIST, but only prints the summary line.",
-" ",
-"/PAGE",
-" If listing, pause after each screenful.",
-" ",
-"/NOPAGE",
-" Don't pause after each screenful.",
-" ",
-"/ASK",
-" Interactively ask permission to delete each file. Reply Yes or OK to",
-" delete it, No not to delete it, Quit to cancel the DELETE command, and",
-" Go to go ahead and delete all the rest of the files without asking.",
-" ",
-"/NOASK",
-" Delete files without asking permission.",
-" ",
-"/SIMULATE",
-" Preview files selected for deletion without actually deleting them.",
-" Implies /LIST.",
-" ",
-"Use SET OPTIONS DELETE to make selected switches effective for every DELETE",
-"command \
-unless you override them; use SHOW OPTIONS to see selections currently",
-#ifdef LOCUS
-"in effect. Also see HELP SET LOCUS, HELP PURGE, HELP WILDCARD.",
-#else
-"in effect. Also see HELP PURGE, HELP WILDCARD.",
-#endif /* LOCUS */
-""};
-
-#ifndef NOHTTP
-static char *hmxxhttp[] = {
-"Syntax:",
-#ifdef CK_SSL
-"HTTP [ <switches> ] OPEN [{ /SSL, /TLS }] <hostname> <service/port>",
-#else
-"HTTP [ <switches> ] OPEN <hostname> <service/port>",
-#endif /*CK_SSL */
-" Instructs Kermit to open a new connection for HTTP communication with",
-" the specified host on the specified port. The default port is \"http\".",
-#ifdef CK_SSL
-" If /SSL or /TLS are specified or if the service is \"https\" or port 443,",
-" a secure connection will be established using the current authentication",
-" settings. See HELP SET AUTH for details.",
-#endif /* CK_SSL */
-" If <switches> are specified, they are applied to all subsequent HTTP",
-" actions (GET, PUT, ...) until an HTTP CLOSE command is executed.",
-" A URL can be included in place of the hostname and service or port.",
-" ",
-"HTTP CLOSE",
-" Instructs Kermit to close any open HTTP connection and clear any saved",
-" switch values.",
-" ",
-"HTTP [ <switches> ] CONNECT <host>[:<port>]",
-" Instructs the server to establish a connection with the specified host",
-" and to redirect all data transmitted between Kermit and the host for the",
-" life of the connection.",
-" ",
-"HTTP [ <switches> ] GET <remote-filename> [ <local-filename> ]",
-" Retrieves the named file on the currently open HTTP connection. The",
-" default local filename is the same as the remote filename, but with any",
-" path stripped. If you want the file to be displayed on the screen instead",
-" of stored on disk, include the /TOSCREEN switch and omit the local",
-" filename. If you give a URL instead of a remote filename, this commands",
-" opens the connection, GETs the file, and closes the connection; the same",
-" is true for the remaining HTTP commands for which you can specify a",
-" remote filename, directory name, or path.",
-" ",
-"HTTP [ <switches> ] HEAD <remote-filename> [ <local-filename> ]",
-" Like GET except without actually getting the file; instead it gets only",
-" the headers, storing them into the given file (if a local filename is",
-" specified), one line per header item as shown in the /ARRAY: switch",
-" description.",
-" ",
-"HTTP [ <switches> ] INDEX <remote-directory> [ <local-filename> ]",
-" Retrieves the file listing for the given server directory.",
-" NOTE: This command is not supported by most Web servers, and even when",
-" the server understand it, there is no stardard response format.",
-" ",
-"HTTP [ <switches> ] POST [ /MIME-TYPE:<type> ] <local-file> <remote-path>",
-" [ <dest-file> ]",
-" Used to send a response as if it were sent from a form. The data to be",
-" posted must be read from a file.",
-" ",
-"HTTP [ <switches> ] PUT [ /MIME-TYPE:<type> ] <local-file> <remote-file>",
-" [ <dest-file> ]",
-" Uploads the given local file to server file. If the remote filename is",
-" omitted, the local name is used, but with any path stripped.",
-" ",
-"HTTP [ <switches> ] DELETE <remote-filename>",
-" Instructs the server to delete the specified filename.",
-" ",
-"where <switches> are:",
-"/AGENT:<user-agent>",
-" Identifies the client to the server; \"C-Kermit\" or \"Kermit-95\"",
-" by default.",
-" ",
-"/HEADER:<header-line>",
-" Used for specifying any optional headers. A list of headers is provided",
-" using braces for grouping:",
-" ",
-" /HEADER:{{<tag>:<value>}{<tag>:<value>}...}",
-" ",
-" For a listing of valid <tag> value and <value> formats see RFC 1945:",
-" \"Hypertext Transfer Protocol -- HTTP/1.0\". A maximum of eight headers",
-" may be specified.",
-" ",
-"/TOSCREEN",
-" Display server responses on the screen.",
-" ",
-"/USER:<name>",
-" In case a page requires a username for access.",
-" ",
-"/PASSWORD:<password>",
-" In case a page requires a password for access.",
-" ",
-"/ARRAY:<arrayname>",
-" Tells Kermit to store the response headers in the given array, one line",
-" per element. The array need not be declared in advance. Example:",
-" ",
-" http /array:c get kermit/index.html",
-" show array c",
-" Dimension = 9",
-" 1. Date: Fri, 26 Nov 1999 23:12:22 GMT",
-" 2. Server: Apache/1.3.4 (Unix)",
-" 3. Last-Modified: Mon, 06 Sep 1999 22:35:58 GMT",
-" 4. ETag: \"bc049-f72-37d441ce\"",
-" 5. Accept-Ranges: bytes",
-" 6. Content-Length: 3954",
-" 7. Connection: close ",
-" 8. Content-Type: text/html",
-" ",
-"As you can see, the header lines are like MIME e-mail header lines:",
-"identifier, colon, value. The /ARRAY switch is the only method available",
-"to a script to process the server responses for a POST or PUT command.",
-" ",
-""
-};
-#endif /* NOHTTP */
-
-#ifdef CK_KERBEROS
-static char *hmxxauth[] = {
-"Syntax:",
-"AUTHENTICATE { KERBEROS4, KERBEROS5 [ switches ] } <action> [ switches ]",
-" Obtains or destroys Kerberos tickets and lists information about them.",
-" Actions are INITIALIZE, DESTROY, and LIST-CREDENTIALS. KERBEROS4 can be",
-" abbreviated K4 or KRB4; KERBEROS5 can be abbreviated K5 or KRB5. Use ? to",
-" see which keywords, switches, or other quantities are valid at each point",
-" in the command.",
-" ",
-" The actions are INITIALIZE, DESTROY, and LIST-CREDENTIALS:",
-" ",
-" AUTH { K4, K5 } { INITIALIZE [switches], DESTROY,",
-" LIST-CREDENTIALS [switches] }",
-" ",
-" The INITIALIZE action is the most complex, and its format is different",
-" for Kerberos 4 and Kerberos 5. The format for Kerberos 4 is:",
-" ",
-" AUTH K4 INITIALIZE [ /INSTANCE:<name> /LIFETIME:<minutes> -",
-" /PASSWORD:<password> /PREAUTH /REALM:<name> <principal> ]",
-" ",
-" All switches are optional. Kerberos 4 INITIALIZE switches are:",
-" ",
-" /INSTANCE:<name>",
-" Allows an Instance (such as a hostname) to be specified.",
-" ",
-" /LIFETIME:<number>",
-" Specifies the requested lifetime in minutes for the ticket. If no",
-" lifetime is specified, 600 minutes is used. If the lifetime is greater",
-" than the maximum supported by the ticket granting service, the resulting",
-" lifetime is shortened accordingly.",
-" ",
-" /NOT-PREAUTH",
-" Instructs Kermit to send a ticket getting ticket (TGT) request to the",
-" KDC without any preauthentication data.",
-" ",
-" /PASSWORD:<string>",
-" Allows a password to be included on the command line or in a script",
-" file. If no /PASSWORD switch is included, you are prompted on a separate"
-,
-" line. The password switch is provided on a use-at-your-own-risk basis",
-" for use in automated scripts. WARNING: Passwords should not be stored in"
-,
-" files.",
-" ",
-" /PREAUTH",
-" Instructs Kermit to send a preauthenticated Ticket-Getting Ticket (TGT)",
-" request to the KDC instead of a plaintext request. The default when",
-" supported by the Kerberos libraries.",
-" ",
-" /REALM:<name>",
-" Allows a realm to be specified (overriding the default realm).",
-" ",
-" <principal>",
-" Your identity in the given or default Kerberos realm, of the form:",
-" userid[.instance[.instance]]@[realm] ",
-" Can be omitted if it is the same as your username or SET LOGIN USERID",
-" value on the client system.",
-" ",
-" The format for Kerberos 5 is as follows:",
-" ",
-" AUTH K5 [ /CACHE:<filename> ] { INITIALIZE [ switches ], DESTROY,",
-" LIST-CREDENTIALS ...}",
-" ",
-"The INITIALIZE command for Kerberos 5 can include a number of switches;",
-"all are optional:",
-" ",
-"AUTH K5 [ /CACHE:<filename> ] INITITIALIZE [ /ADDRESSES:<addr-list>",
-" /FORWARDABLE /KERBEROS4 /LIFETIME:<minutes> /PASSWORD:<password>",
-" /POSTDATE:<date-time> /PROXIABLE /REALM:<name> /RENEW /RENEWABLE:<minutes>",
-" /SERVICE:<name> /VALIDATE <principal> ]",
-" ",
-" All Kerberos 5 INITIALIZE switches are optional:",
-" ",
-" /ADDRESSES:{list of ip-addresses}",
-" Specifies a list of IP addresses that should be placed in the Ticket",
-" Getting Ticket in addition to the local machine addresses.",
-" ",
-" /FORWARDABLE",
-" Requests forwardable tickets.",
-" ",
-" /INSTANCE:<name>",
-" Allows an Instance (such as a hostname) to be specified.",
-" ",
-" /KERBEROS4",
-" Instructs Kermit to get Kerberos 4 tickets in addition to Kerberos 5",
-" tickets. If Kerberos 5 tickets are not supported by the server, a",
-" mild warning is printed and Kerberos 4 tickets are requested.",
-" ",
-" /LIFETIME:<number>",
-" Specifies the requested lifetime in minutes for the ticket. If no",
-" lifetime is specified, 600 minutes is used. If the lifetime is greater",
-" than the maximum supported by the ticket granting service, the resulting",
-" lifetime is shortened.",
-" ",
-" /NO-KERBEROS4",
-" Instructs Kermit to not attempt to retrieve Kerberos 4 credentials.",
-" ",
-" /NOT-FORWARDABLE",
-" Requests non-forwardable tickets.",
-" ",
-" /NOT-PROXIABLE",
-" Requests non-proxiable tickets.",
-" ",
-" /PASSWORD:<string>",
-" Allows a password to be included on the command line or in a script",
-" file. If no /PASSWORD switch is included, you are prompted on a separate"
-,
-" line. The password switch is provided on a use-at-your-own-risk basis",
-" for use in automated scripts. WARNING: Passwords should not be stored in"
-,
-" files.",
-" ",
-" /POSTDATE:<date-time>",
-" Requests a postdated ticket, valid starting at <date-time>. Postdated",
-" tickets are issued with the invalid flag set, and need to be fed back to",
-" the KDC before use with the /VALIDATE switch. Type HELP DATE for info",
-" on date-time formats.",
-" ",
-" /PROXIABLE",
-" Requests proxiable tickets.",
-" ",
-" /REALM:<string>",
-" Allows an alternative realm to be specified.",
-" ",
-" /RENEW",
-" Requests renewal of a renewable Ticket-Granting Ticket. Note that ",
-" an expired ticket cannot be renewed even if it is within its renewable ",
-" lifetime.",
-" ",
-" /RENEWABLE:<number>",
-" Requests renewable tickets, with a total lifetime of <number> minutes.",
-" ",
-" /SERVICE:<string>",
-" Allows a service other than the ticket granting service to be specified.",
-" ",
-" /VALIDATE",
-" Requests that the Ticket Granting Ticket in the cache (with the invalid",
-" flag set) be passed to the KDC for validation. If the ticket is within",
-" its requested time range, the cache is replaced with the validated",
-" ticket.",
-" ",
-" <principal>",
-" Your identity in the given or default Kerberos realm, of the form:",
-" userid[/instance][@realm] ",
-" Can be omitted if it is the same as your username or SET LOGIN USERID",
-" value on the client system.",
-" ",
-" Note: Kerberos 5 always attempts to retrieve a Ticket-Getting Ticket (TGT)",
-" using the preauthenticated TGT request.",
-" ",
-" AUTHORIZE K5 LIST-CREDENTIALS [ /ADDRESSES /FLAGS /ENCRYPTION ]",
-" ",
-" Shows start time, expiration time, service or principal name, plus",
-" the following additional information depending the switches:",
-" ",
-" /ADDRESSES displays the hostnames and/or IP addresses embedded within",
-" the tickets.",
-" ",
-" /FLAGS provides the following information (if applicable) for each ticket:",
-" F - Ticket is Forwardable",
-" f - Ticket was Forwarded",
-" P - Ticket is Proxiable",
-" p - Ticket is a Proxy",
-" D - Ticket may be Postdated",
-" d - Ticket has been Postdated",
-" i - Ticket is Invalid",
-" R - Ticket is Renewable",
-" I - Ticket is the Initial Ticket",
-" H - Ticket has been authenticated by Hardware",
-" A - Ticket has been Pre-authenticated",
-" ",
-" /ENCRYPTION displays the encryption used by each ticket (if applicable):",
-" DES-CBC-CRC",
-" DES-CBC-MD4",
-" DES-CBC-MD5",
-" DES3-CBC-SHA",
-""
-};
-#endif /* CK_KERBEROS */
-
-#ifndef NOCSETS
-static char *hmxxassoc[] = {
-"ASSOCIATE FILE-CHARACTER-SET <file-character-set> <transfer-character-set>",
-" Tells C-Kermit that whenever the given file-character set is selected, and",
-" SEND CHARACTER-SET (q.v.) is AUTOMATIC, the given transfer character-set",
-" is selected automatically.",
-" ",
-"ASSOCIATE XFER-CHARACTER-SET <xfer-character-set> <file-character-set>",
-" Tells C-Kermit that whenever the given transfer-character set is selected,",
-" either by command or by an announcer attached to an incoming text file,",
-" and SEND CHARACTER-SET is AUTOMATIC, the specified file character-set is",
-" to be selected automatically. Synonym: ASSOCIATE TRANSFER-CHARACTER-SET.",
-" ",
-"Use SHOW ASSOCIATIONS to list the current character-set associations, and",
-"SHOW CHARACTER-SETS to list the current settings.",
-""
-};
-#endif /* NOCSETS */
-
-static char *hmxxpat[] = {
-"A \"pattern\" is notation used in a search string when searching through",
-"text. C-Kermit uses three kinds of patterns: floating patterns, anchored",
-"patterns, and wildcards. Wildcards are anchored patterns that are used to",
-"match file names; type HELP WILDCARD to learn about them.",
-" ",
-"In a pattern, certain characters are special:",
-" ",
-"* Matches any sequence of zero or more characters. For example, \"k*t\"",
-" matches all strings that start with \"k\" and end with \"t\" including",
-" \"kt\", \"kit\", \"knight\", or \"kermit\".",
-" ",
-#ifdef VMS
-"% Matches any single character. For example, \"k%%%%t\" matches all strings",
-#else
-"? Matches any single character. For example, \"k????t\" matches all strings",
-#endif /* VMS */
-" that are exactly 6 characters long and start with \"k\" and end with",
-#ifdef VMS
-" with \"t\".",
-#else
-" with \"t\". When typing commands at the prompt, you must precede any",
-" question mark to be used for matching by a backslash (\\) to override the",
-" normal function of question mark in interactive commands, which is to",
-" provide menus and file lists.",
-#endif /* VMS */
-" ",
-#ifdef OS2ORUNIX
-#ifdef CKREGEX
-"[abc]",
-" Square brackets enclosing a list of characters matches any character in",
-" the list. Example: h[aou]t matches hat, hot, and hut.",
-" ",
-"[a-z]",
-" Square brackets enclosing a range of characters matches any character in",
-" the range; a hyphen (-) separates the low and high elements of the range.",
-" For example, [a-z] matches any character from a to z.",
-" ",
-"[acdm-z]",
-" Lists and ranges may be combined. This example matches a, c, d, or any",
-" letter from m through z.",
-" ",
-"{string1,string2,...}",
-" Braces enclose a list of strings to be matched. For example:",
-" ker{mit,nel,beros} matches kermit, kernel, and kerberos. The strings",
-" may themselves contain *, ?, [abc], [a-z], or other lists of strings.",
-#endif /* CKREGEX */
-#endif /* OS2ORUNIX */
-#ifndef NOSPL
-" ",
-"To force a special pattern character to be taken literally, precede it with",
-"a backslash, e.g. [a\\-z] matches a, hyphen, or z rather than a through z.",
-" ",
-"A floating pattern can also include the following special characters:",
-" ",
-"^ (First character of pattern) Anchors the pattern at the beginning.",
-"$ (Last character of pattern) Anchors the pattern at the end.",
-" ",
-"If a floating pattern does not start with \"^\", the pattern can match",
-"anywhere in the string instead of only at the beginning; in other words, a",
-"leading \"*\" is assumed. Similarly, if the pattern doesn't end with \"$\",",
-"a trailing \"*\" is assumed.",
-" ",
-"The following commands and functions use floating patterns:",
-" GREP [ <switches> ] <pattern> <filespec>",
-" TYPE /MATCH:<pattern> <file>",
-" \\farraylook(<pattern>,<arrayname>)",
-" \\fsearch(<pattern>,<string>[,<offset>])",
-" \\frsearch(<pattern>,<string>[,<offset>])",
-" The /EXCEPT: clause in SEND, GET, DELETE, etc.",
-" ",
-"Example:",
-" \\fsearch(abc,xxabcxxx) succeeds because xxabcxx contains abc.",
-" \\fsearch(^abc,xxabcxx) fails because xxabcxx does not start with abc.",
-" ",
-
-"All other commands and functions use anchored patterns, meaning that ^ and $",
-"are not treated specially, and * is not assumed at the beginning or end of",
-"the pattern. This is true mainly of filename patterns (wildcards), since",
-"you would not want a command like \"delete x\" to delete all files whose",
-"names contained \"x\"!",
-
-" ",
-"You can use anchored patterns not only in filenames, but also in SWITCH",
-"case labels, in the INPUT and MINPUT commands, and in file binary- and",
-"text-patterns for filenames. The IF MATCH pattern is also anchored.",
-#endif /* NOSPL */
-"" };
-
-static char *hmxxwild[] = {
-
-"A \"wildcard\" is a notation used in a filename to match multiple files.",
-"For example, in \"send *.txt\" the asterisk is a wildcard. Kermit commands",
-"that accept filenames also accepts wildcards, except commands that are",
-"allowed to operate on only one file, such as TRANSMIT.",
-"This version of Kermit accepts the following wildcards:",
-" ",
-"* Matches any sequence of zero or more characters. For example, \"ck*.c\"",
-" matches all files whose names start with \"ck\" and end with \".c\"",
-" including \"ck.c\".",
-" ",
-#ifdef VMS
-"% Matches any single character. For example, \"ck%.c\" matches all files",
-#else
-"? Matches any single character. For example, \"ck?.c\" matches all files",
-#endif /* VMS */
-" whose names are exactly 5 characters long and start with \"ck\" and end",
-#ifdef VMS
-" with \".c\".",
-#else
-" with \".c\". When typing commands at the prompt, you must precede any",
-" question mark to be used for matching by a backslash (\\) to override the",
-" normal function of question mark in interactive commands, which is to",
-" provide menus and file lists. You don't, however, need to quote filename",
-" question marks in command files (script programs).",
-#endif /* VMS */
-" ",
-#ifdef OS2ORUNIX
-#ifdef CKREGEX
-"[abc]",
-" Square brackets enclosing a list of characters matches any character in",
-" the list. Example: ckuusr.[ch] matches ckuusr.c and ckuusr.h.",
-" ",
-"[a-z]",
-" Square brackets enclosing a range of characters matches any character in",
-" the range; a hyphen (-) separates the low and high elements of the range.",
-" For example, [a-z] matches any character from a to z.",
-" ",
-"[acdm-z]",
-" Lists and ranges may be combined. This example matches a, c, d, or any",
-" letter from m through z.",
-" ",
-"{string1,string2,...}",
-" Braces enclose a list of strings to be matched. For example:",
-" ck{ufio,vcon,cmai}.c matches ckufio.c, ckvcon.c, or ckcmai.c. The strings",
-" may themselves contain *, ?, [abc], [a-z], or other lists of strings.",
-#endif /* CKREGEX */
-#endif /* OS2ORUNIX */
-" ",
-"To force a special pattern character to be taken literally, precede it with",
-"a backslash, e.g. [a\\-z] matches a, hyphen, or z rather than a through z.",
-"Or tell Kermit to SET WILDCARD-EXPANSION OFF before entering or referring",
-"to the filename.",
-" ",
-#ifndef NOSPL
-"Similar notation can be used in general-purpose string matching. Type HELP",
-"PATTERNS for details. Also see HELP SET MATCH.",
-#endif /* NOSPL */
-"" };
-
-#ifndef NOXFER
-static char *hmxxfast[] = {
-"FAST, CAUTIOUS, and ROBUST are predefined macros that set several",
-"file-transfer parameters at once to achieve the desired file-transfer goal.",
-"FAST chooses a large packet size, a large window size, and a fair amount of",
-"control-character unprefixing at the risk of possible failure on some",
-"connections. FAST is the default tuning in C-Kermit 7.0 and later. In case",
-"FAST file transfers fail for you on a particular connection, try CAUTIOUS.",
-"If that fails too, try ROBUST. You can also change the definitions of each",
-"macro with the DEFINE command. To see the current definitions, type",
-"\"show macro fast\", \"show macro cautious\", or \"show macro robust\".",
-""
-};
-#endif /* NOXFER */
-
-#ifdef VMS
-static char * hmxxpurge[] = {
-"Syntax: PURGE [ switches ] [ filespec ]",
-" Runs the DCL PURGE command. Switches and filespec are not parsed or",
-" verified by Kermit, but passed directly to DCL.",
-""
-};
-#else
-#ifdef CKPURGE
-static char * hmxxpurge[] = {
-"Syntax: PURGE [ switches ] [ filespec ]",
-" Deletes backup files; that is, files whose names end in \".~n~\", where",
-" n is a number. PURGE by itself deletes all backup files in the current",
-" directory. Switches:",
-
-" ",
-"/AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files created after the given date-time are",
-#else
-" Specifies that only those files modified after the given date-time are",
-#endif /* VMS */
-" to be purged. HELP DATE for info about date-time formats.",
-" ",
-"/BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified before the given date-time",
-#else
-" Specifies that only those files modified before the given date-time",
-#endif /* VMS */
-" are to be purged.",
-" ",
-"/NOT-AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or before the given date-time",
-#else
-" Specifies that only those files modified at or before the given date-time",
-#endif /* VMS */
-" are to be purged.",
-" ",
-"/NOT-BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or after the given date-time",
-#else
-" Specifies that only those files modified at or after the given date-time",
-#endif /* VMS */
-" are to be purged.",
-" ",
-"/LARGER-THAN:number",
-" Specifies that only those files longer than the given number of bytes are",
-" to be purged.",
-" ",
-"/SMALLER-THAN:number",
-" Specifies that only those files smaller than the given number of bytes are",
-" to be purged.",
-" ",
-"/EXCEPT:pattern",
-" Specifies that any files whose names match the pattern, which can be a",
-" regular filename or may contain wildcards, are not to be purged. To",
-" specify multiple patterns (up to 8), use outer braces around the group",
-" and inner braces around each pattern:",
-" ",
-" /EXCEPT:{{pattern1}{pattern2}...}",
-" ",
-#ifdef UNIXOROSK
-"/DOTFILES",
-" Include (purge) files whose names begin with \".\".",
-" ",
-"/NODOTFILES",
-" Skip (don't purge) files whose names begin with \".\".",
-" ",
-#endif /* UNIXOROSK */
-#ifdef RECURSIVE
-"/RECURSIVE",
-" Descends through the current or specified directory tree.",
-" ",
-#endif /* RECURSIVE */
-"/KEEP:n",
-" Retain the 'n' most recent (highest-numbered) backup files for each file.",
-" By default, none are kept. If /KEEP is given without a number, 1 is used.",
-" ",
-"/LIST",
-" Display each file as it is processed and say whether it is purged or kept.",
-" Synonyms: /LOG, /VERBOSE.",
-" ",
-"/NOLIST",
-" The PURGE command should operate silently (default).",
-" Synonyms: /NOLOG, /QUIET.",
-" ",
-"/HEADING",
-" Print heading and summary information.",
-" ",
-"/NOHEADING",
-" Don't print heading and summary information.",
-" ",
-"/PAGE",
-" When /LIST is in effect, pause at the end of each screenful, even if",
-" COMMAND MORE-PROMPTING is OFF.",
-" ",
-"/NOPAGE",
-" Don't pause, even if COMMAND MORE-PROMPTING is ON.",
-" ",
-"/ASK",
-" Interactively ask permission to delete each backup file.",
-" ",
-"/NOASK",
-" Purge backup files without asking permission.",
-" ",
-"/SIMULATE",
-" Inhibits the actual deletion of files; use to preview which files would",
-" actually be deleted. Implies /LIST.",
-" ",
-"Use SET OPTIONS PURGE [ switches ] to change defaults; use SHOW OPTIONS to",
-"display customized defaults. Also see HELP DELETE, HELP WILDCARD.",
-""
-};
-#endif /* CKPURGE */
-#endif /* VMS */
-
-static char *hmxxclo[] = {
-"Syntax: CLOSE [ item ]",
-" Close the indicated item. The default item is CONNECTION, which is the",
-" current SET LINE or SET HOST connection. The other items are:",
-" ",
-#ifdef CKLOGDIAL
-" CX-LOG (connection log, opened with LOG CX)",
-#endif /* CKLOGDIAL */
-#ifndef NOLOCAL
-" SESSION-LOG (opened with LOG SESSION)",
-#endif /* NOLOCAL */
-#ifdef TLOG
-" TRANSACTION-LOG (opened with LOG TRANSACTIONS)",
-#endif /* TLOG */
-" PACKET-LOG (opened with LOG PACKETS)",
-#ifdef DEBUG
-" DEBUG-LOG (opened with LOG DEBUG)",
-#endif /* DEBUG */
-#ifndef NOSPL
-" READ-FILE (opened with OPEN READ)",
-" WRITE-FILE (opened with OPEN WRITE or OPEN APPEND)",
-#endif /* NOSPL */
-" ",
-"Type HELP LOG and HELP OPEN for further info.",
-""
-};
-
-#ifdef CKLEARN
-static char * hmxxlearn[] = {
-"Syntax: LEARN [ /ON /OFF /CLOSE ] [ filename ]",
-" Records a login script. If you give a filename, the file is opened for",
-" subsequent recording. If you don't give any switches, /ON is assumed.",
-" /ON enables recording to the current file (if any); /OFF disables",
-" recording. /CLOSE closes the current file (if any). After LEARN /CLOSE",
-" or exit from Kermit, your script is available for execution by the TAKE",
-" command.",
-""
-};
-#endif /* CKLEARN */
-
-#ifdef CK_MINPUT
-static char *hmxxminp[] = {
-"Syntax: MINPUT [ switches ] n [ string1 [ string2 [ ... ] ] ]",
-"Example: MINPUT 5 Login: {Username: } {NO CARRIER} BUSY RING",
-" For use in script programs. Waits up to n seconds for any one of the",
-" strings to arrive on the communication device. If no strings are given,",
-" the command waits for any character at all to arrive. Strings are",
-" separated by spaces; use {braces} or \"doublequotes\" for grouping. If",
-" any of the strings is encountered within the timeout interval, the command",
-" succeeds and the \\v(minput) variable is set to the number of the string",
-" that was matched: 1, 2, 3, etc. If none of the strings arrives, the",
-" command times out, fails, and \\v(minput) is set to 0. In all other",
-" respects, MINPUT is like INPUT. See HELP INPUT for the available switches",
-" and other details of operation.",
-"" };
-#endif /* CK_MINPUT */
-
-#ifndef NOLOCAL
-static char *hmxxcon[] = {
-"Syntax: CONNECT (or C, or CQ) [ switches ]",
-" Connect to a remote computer via the serial communications device given in",
-#ifdef OS2
-" the most recent SET PORT command, or to the network host named in the most",
-#else
-" the most recent SET LINE command, or to the network host named in the most",
-#endif /* OS2 */
-" recent SET HOST command. Type the escape character followed by C to get",
-" back to the C-Kermit prompt, or followed by ? for a list of CONNECT-mode",
-#ifdef OS2
-" escape commands. You can also assign the \\Kexit verb to the key or",
-" key-combination of your choice; by default it is assigned to Alt-x.",
-#else
-" escape commands.",
-" ",
-"Include the /QUIETLY switch to suppress the informational message that",
-"tells you how to escape back, etc. CQ is a synonym for CONNECT /QUIETLY.",
-#endif /* OS2 */
-" ",
-"Other switches include:",
-#ifdef CK_TRIGGER
-" ",
-"/TRIGGER:string",
-" One or more strings to look for that will cause automatic return to",
-" command mode. To specify one string, just put it right after the",
-" colon, e.g. \"/TRIGGER:Goodbye\". If the string contains any spaces, you",
-" must enclose it in braces, e.g. \"/TRIGGER:{READY TO SEND...}\". To",
-" specify more than one trigger, use the following format:",
-" ",
-" /TRIGGER:{{string1}{string2}...{stringn}}",
-" ",
-" Upon return from CONNECT mode, the variable \\v(trigger) is set to the",
-" trigger string, if any, that was actually encountered. This value, like",
-" all other CONNECT switches applies only to the CONNECT command with which",
-" it is given, and overrides (temporarily) any global SET TERMINAL TRIGGER",
-" string that might be in effect.",
-#endif /* CK_TRIGGER */
-#ifdef OS2
-" ",
-"/IDLE-LIMIT:number",
-" The number of seconds of idle time, after which Kermit returns",
-" automatically to command mode; default 0 (no limit).",
-" ",
-"/IDLE-INTERVAL:number",
-" The number of seconds of idle time, after which Kermit automatically",
-" transmits the idle string.",
-" ",
-"/IDLE-STRING:string",
-" The string to transmit whenever the idle interval has passed.",
-" ",
-"/TIME-LIMIT:number",
-" The maximum number of seconds for which the CONNECT session may last.",
-" The default is 0 (no limit). If a nonzero number is given, Kermit returns",
-" automatically to command mode after this many seconds.",
-#endif /* OS2 */
-"" };
-#endif /* NOLOCAL */
-
-static char *hmxxmget[] = {
-"Syntax: MGET [ switches... ] remote-filespec [ remote-filespec ... ]",
-" ",
-"Just like GET (q.v.) except allows a list of remote file specifications,",
-"separated by spaces.",
-""
-};
-
-static char *hmxxget[] = {
-"Syntax: GET [ switches... ] remote-filespec [ as-name ]",
-" Tells the other Kermit, which must be in (or support autoswitching into)",
-" server mode, to send the named file or files. If the remote-filespec or",
-" the as-name contain spaces, they must be enclosed in braces. If as-name",
-" is the name of an existing local directory, incoming files are placed in",
-" that directory; if it is the name of directory that does not exist, Kermit",
-" tries to create it. Optional switches include:",
-" ",
-"/AS-NAME:text",
-" Specifies \"text\" as the name to store the incoming file under, or",
-" directory to store it in. You can also specify the as-name as the second",
-" filename on the GET command line.",
-" ",
-"/BINARY",
-" Performs this transfer in binary mode without affecting the global",
-" transfer mode.",
-" ",
-"/COMMAND",
-" Receives the file into the standard input of a command, rather than saving",
-" it on disk. The /AS-NAME or the second \"filename\" on the GET command",
-" line is interpreted as the name of a command.",
-" ",
-"/DELETE",
-" Asks the other Kermit to delete the file (or each file in the group)",
-" after it has been transferred successfully.",
-" ",
-"/EXCEPT:pattern",
-" Specifies that any files whose names match the pattern, which can be a",
-" regular filename, or may contain \"*\" and/or \"?\" metacharacters,",
-" are to be refused. To specify multiple patterns (up to 8), use outer",
-" braces around the group, and inner braces around each pattern:",
-" ",
-" /EXCEPT:{{pattern1}{pattern2}...}",
-" ",
-"/FILENAMES:{CONVERTED,LITERAL}",
-" Overrides the global SET FILE NAMES setting for this transfer only.",
-" ",
-"/FILTER:command",
-" Causes the incoming file to passed through the given command (standard",
-" input/output filter) before being written to disk.",
-" ",
-#ifdef VMS
-"/IMAGE",
-" Transfer in image mode.",
-" ",
-#endif /* VMS */
-#ifdef CK_LABELED
-"/LABELED",
-" VMS and OS/2 only: Specifies labeled transfer mode.",
-" ",
-#endif /* CK_LABELED */
-
-"/MOVE-TO:directory-name",
-" Specifies that each file that arrives should be moved to the specified",
-" directory after, and only if, it has been received successfully.",
-" ",
-"/PATHNAMES:{OFF,ABSOLUTE,RELATIVE,AUTO}",
-" Overrides the global SET RECEIVE PATHNAMES setting for this transfer.",
-" ",
-"/PIPES:{ON,OFF}",
-" Overrides the TRANSFER PIPES setting for this command only. ON allows",
-" reception of files with names like \"!tar xf -\" to be automatically",
-" directed to a pipeline.",
-" ",
-"/QUIET",
-" When sending in local mode, this suppresses the file-transfer display.",
-" ",
-"/RECOVER",
-" Used to recover from a previously interrupted transfer; GET /RECOVER",
-" is equivalent REGET. Works only in binary mode.",
-" ",
-"/RECURSIVE",
-" Tells the server to descend through the directory tree when locating",
-" the files to be sent.",
-" ",
-"/RENAME-TO:string",
-" Specifies that each file that arrives should be renamed as specified",
-" after, and only if, it has been received successfully. The string should",
-" normally contain variables like \\v(filename) or \\v(filenum).",
-" ",
-"/TEXT",
-" Performs this transfer in text mode without affecting the global",
-" transfer mode.",
-" ",
-"/TRANSPARENT",
-" Inhibits character-set translation of incoming text files for the duration",
-" of the GET command without affecting subsequent commands.",
-" ",
-"Also see HELP MGET, HELP SEND, HELP RECEIVE, HELP SERVER, HELP REMOTE.",
-""};
-
-static char *hmxxlg[] = {
-"Syntax: LOG (or L) log-type [ filename [ { NEW, APPEND } ] ]",
-" ",
-"Record information in a log file:",
-" ",
-#ifdef CKLOGDIAL
-"CX",
-" Connections made with SET LINE, SET PORT, SET HOST, DIAL, TELNET, etc.",
-" The default filename is CX.LOG in your home directory and APPEND is the",
-" default mode for opening.",
-" ",
-#endif /* CKLOGDIAL */
-#ifdef DEBUG
-"DEBUG",
-" Debugging information, to help track down bugs in the C-Kermit program.",
-" The default log name is debug.log in current directory.",
-" ",
-#endif /* DEBUG */
-"PACKETS",
-" Kermit packets, to help with protocol problems. The default filename is",
-" packet.log in current directory.",
-" ",
-#ifndef NOLOCAL
-"SESSION",
-" Records your CONNECT session (default: session.log in current directory).",
-" ",
-#endif /* NOLOCAL */
-#ifdef TLOG
-"TRANSACTIONS",
-" Names and statistics about files transferred (default: transact.log in",
-" current directory; see HELP SET TRANSACTION-LOG for transaction-log format",
-" options.)",
-" ",
-#endif /* TLOG */
-"If you include the APPEND keyword after the filename, the existing log file,",
-"if any, is appended to; otherwise a new file is created (except APPEND is",
-"the default for the connection log). Use CLOSE <keyword> to stop logging.",
-#ifdef OS2ORUNIX
-" ",
-"Note: The filename can also be a pipe, e.g.:",
-" ",
-" log transactions |lpr",
-" log debug {| grep \"^TELNET\" > debug.log}",
-" ",
-"Braces are required if the pipeline or filename contains spaces.",
-#endif /* OS2ORUNIX */
-"" };
-
-#ifndef NOSCRIPT
-static char *hmxxlogi[] = { "\
-Syntax: SCRIPT text",
-" A limited and cryptic \"login assistant\", carried over from old C-Kermit",
-" releases for comptability, but not recommended for use. Instead, please",
-" use the full script programming language described in chapters 17-19 of",
-" \"Using C-Kermit\".",
-" ",
-" Login to a remote system using the text provided. The login script",
-" is intended to operate similarly to UNIX uucp \"L.sys\" entries.",
-" A login script is a sequence of the form:",
-" ",
-" expect send [expect send] . . .",
-" ",
-" where 'expect' is a prompt or message to be issued by the remote site, and",
-" 'send' is the names, numbers, etc, to return. The send may also be the",
-" keyword EOT to send Control-D, or BREAK (or \\\\b) to send a break signal.",
-" Letters in send may be prefixed by ~ to send special characters:",
-" ",
-" ~b backspace, ~s space, ~q '?', ~n linefeed, ~r return, ~c don\'t",
-" append a return, and ~o[o[o]] for octal of a character. As with some",
-" UUCP systems, sent strings are followed by ~r unless they end with ~c.",
-" ",
-" Only the last 7 characters in each expect are matched. A null expect,",
-" e.g. ~0 or two adjacent dashes, causes a short delay. If you expect",
-" that a sequence might not arrive, as with uucp, conditional sequences",
-" may be expressed in the form:",
-" ",
-" -send-expect[-send-expect[...]]",
-" ",
-" where dashed sequences are followed as long as previous expects fail.",
-"" };
-#endif /* NOSCRIPT */
-
-#ifndef NOFRILLS
-static char * hmxxtyp[] = {
-"Syntax: TYPE [ switches... ] file",
-" Displays a file on the screen. Pauses automatically at end of each",
-" screenful if COMMAND MORE-PROMPTING is ON. Optional switches:",
-" ",
-" /PAGE",
-" Pause at the end of each screenful even if COMMAND MORE-PROMPTING OFF.",
-" Synonym: /MORE",
-" /NOPAGE",
-" Don't pause at the end of each screen even if COMMAND MORE-PROMPTING ON."
-,
-" /HEAD:n",
-" Only type the first 'n' lines of the file.",
-" /TAIL:n",
-" Only type the last 'n' lines of the file.",
-" /MATCH:pattern",
-" Only type lines that match the given pattern. HELP WILDCARDS for info",
-" info about patterns. /HEAD and /TAIL apply after /MATCH.",
-" /PREFIX:string",
-" Print the given string at the beginning of each line.",
-" /NUMBER",
-" Add line numbers (conflicts with /PREFIX)",
-" /WIDTH:number",
-" Truncate each line at the given column number before printing.",
-#ifdef KUI
-" Or when combined with /GUI specifies the width of the dialog box.",
-" /HEIGHT:number",
-" When combined with /GUI specifies the height of the dialog box.",
-" /GUI:string",
-" Specifies the title to use for the dialog box.",
-#endif /* KUI */
-" /COUNT",
-" Count lines (and matches) and print the count(s) but not the lines.",
-#ifdef UNICODE
-" /CHARACTER-SET:name",
-" Translates from the named character set.",
-#ifndef OS2
-" /TRANSLATE-TO:name",
-" Translates to the named character set (default = current file charset).",
-#endif /* OS2 */
-" /TRANSPARENT",
-" Inhibits character-set translation.",
-#endif /* UNICODE */
-" /OUTPUT:name",
-" Sends results to the given file. If this switch is omitted, the",
-" results appear on your screen. This switch overrides any express or",
-" implied /PAGE switch.",
-" ",
-"You can use SET OPTIONS TYPE to set the defaults for /PAGE or /NOPAGE and",
-"/WIDTH. Use SHOW OPTIONS to see current TYPE options.",
-""
-};
-
-static char * hmxxcle[] = {
-"Syntax: CLEAR [ item-name ]",
-" ",
-"Clears the named item. If no item is named, DEVICE-AND-INPUT is assumed.",
-" ",
-" ALARM Clears any pending alarm (see SET ALARM).",
-#ifdef CK_APC
-" APC-STATUS Clears Application Program Command status.",
-#endif /* CK_APC */
-#ifdef PATTERNS
-" BINARY-PATTERNS Clears the file binary-patterns list.",
-#endif /* PATTERNS */
-#ifdef OS2
-" COMMAND-SCREEN Clears the current command screen.",
-#endif /* OS2 */
-" DEVICE Clears the current port or network input buffer.",
-" DEVICE-AND-INPUT Clears both the device and the INPUT buffer.",
-" DIAL-STATUS Clears the \\v(dialstatus) variable.",
-" \
-INPUT Clears the INPUT-command buffer and the \\v(input) variable.",
-" KEYBOARD-BUFFER Clears the command terminal keyboard input buffer.",
-#ifdef OS2
-" \
-SCROLLBACK empties the scrollback buffer including the current screen.",
-#endif /* OS2 */
-" SEND-LIST Clears the current SEND list (see ADD).",
-#ifdef OS2
-" \
-TERMINAL-SCREEN Clears the current screen a places it into the scrollback.",
-" buffer.",
-#endif /* OS2 */
-#ifdef PATTERNS
-" TEXT-PATTERNS Clears the file text-patterns list.",
-#endif /* PATTERNS */
-""};
-#endif /* NOFRILLS */
-
-static char * hmxxdate[] = {
-"Syntax: DATE [ date-time [ timezone ] ] [ delta-time ]",
-" Prints a date-time in standard format: yyyymmdd_hh:mm:ss.",
-" Various date-time formats are accepted:",
-" ",
-" . The date, if given, must precede the time.",
-" . The year must be four digits or else a 2-digit format dd mmm yy,",
-" in which case if (yy < 50) yyyy = yy + 2000; else yyyy = yy + 1900.",
-" . If the year comes first, the second field is the month.",
-" . The day, month, and year may be separated by spaces, /, -, or underscore."
-," . The date and time may be separated by spaces or underscore.",
-" . The month may be numeric (1 = January) or spelled out or abbreviated in",
-" English.",
-" . The time may be in 24-hour format or 12-hour format.",
-" . If the hour is 12 or less, AM is assumed unless AM or PM is included.",
-" . If the date is omitted but a time is given, the current date is supplied."
-,
-" . If the time is given but date omitted, 00:00:00 is supplied.",
-" . If both the date and time are omitted, the current date and time are",
-" supplied.",
-" ",
-" The following shortcuts can also be used in place of dates:",
-" ",
-" NOW",
-" Stands for the current date and time.",
-" ",
-" TODAY",
-" Today's date, optionally followed by a time; 00:00:00 if no time given.",
-" ",
-" YESTERDAY",
-" Yesterday's date, optionally followed by a time (default 00:00:00).",
-" ",
-" TOMORROW",
-" Tomorrows's date, optionally followed by a time (default 00:00:00).",
-" ",
-" Timezone specifications are similar to those used in e-mail and HTTP",
-" headers, either a USA timezone name, e.g. EST, or a signed four-digit",
-" timezone offset, {+,-}hhmm, e.g., -0500; it is used to convert date-time,"
-,
-" a local time in that timezone, to GMT which is then converted to the",
-" local time at the host. If no timezone is given, the date-time is local."
-," To convert local time (or a time in a specified timezone) to UTC (GMT),",
-" use the function \futcdate().",
-" ",
-" Delta times are given as {+,-}[number date-units][hh[:mm[:ss]]]",
-" A date in the future/past relative to the date-time; date-units may be",
-" DAYS, WEEKS, MONTHS, YEARS: +3days, -7weeks, +3:00, +1month 8:00.",
-" ",
-"All the formats shown above are acceptable as arguments to date-time switches"
-,
-"such as /AFTER: or /BEFORE:, and to functions such as \\fcvtdate(),",
-"\\fdiffdate(), and \\futcdate(), that take date-time strings as arguments.",
-""
-};
-
-
-#ifndef NOXFER
-static char * hmxxsen[] = {
-"Syntax: SEND (or S) [ switches...] [ filespec [ as-name ] ]",
-" Sends the file or files specified by filespec. If the filespec is omitted",
-" the SEND-LIST is used (HELP ADD for more info). The filespec may contain",
-" wildcard characters. An 'as-name' may be given to specify the name(s)",
-" the files(s) are sent under; if the as-name is omitted, each file is",
-" sent under its own name. Also see HELP MSEND, HELP WILDCARD.",
-" Optional switches include:",
-" ",
-#ifndef NOSPL
-"/ARRAY:<arrayname>",
-" Specifies that the data to be sent comes from the given array, such as",
-" \\&a[]. A range may be specified, e.g. SEND /ARRAY:&a[100:199]. Leave",
-" the brackets empty or omit them altogether to send the whole 1-based array."
-,
-" Include /TEXT to have Kermit supply a line terminator at the end of each",
-" array element (and translate character sets if character-set translations",
-" are set up), or /BINARY to treat the array as one long string of characters"
-,
-" to be sent as-is. If an as-name is not specified, the array is sent with",
-" the name _ARRAY_X_, where \"X\" is replaced by actual array letter.",
-" ",
-#endif /* NOSPL */
-
-"/AS-NAME:<text>",
-" Specifies <text> as the name to send the file under instead of its real",
-" name. This is equivalent to giving an as-name after the filespec.",
-" ",
-"/BINARY",
-" Performs this transfer in binary mode without affecting the global",
-" transfer mode.",
-" ",
-"/TEXT",
-" Performs this transfer in text mode without affecting the global",
-" transfer mode.",
-" ",
-"/TRANSPARENT",
-" Inhibits character-set translation for text files for the duration of",
-" the SEND command without affecting subsequent commands.",
-" ",
-"/NOBACKUPFILES",
-" Skip (don't send) Kermit or EMACS backup files (files with names that",
-" end with .~n~, where n is a number).",
-" ",
-#ifdef UNIXOROSK
-"/DOTFILES",
-" Include (send) files whose names begin with \".\".",
-" ",
-"/NODOTFILES",
-" Don't send files whose names begin with \".\".",
-" ",
-"/FOLLOWLINKS",
-" Send files that are pointed to by symbolic links.",
-" ",
-"/NOFOLLOWLINKS",
-" Skip over symbolic links (default).",
-" ",
-#endif /* UNIXOROSK */
-
-#ifdef VMS
-"/IMAGE",
-" Performs this transfer in image mode without affecting the global",
-" transfer mode.",
-" ",
-#endif /* VMS */
-#ifdef CK_LABELED
-"/LABELED",
-" Performs this transfer in labeled mode without affecting the global",
-" transfer mode.",
-" ",
-#endif /* CK_LABELED */
-"/COMMAND",
-" Sends the output from a command, rather than the contents of a file.",
-" The first \"filename\" on the SEND command line is interpreted as the name",
-" of a command; the second (if any) is the as-name.",
-" ",
-"/FILENAMES:{CONVERTED,LITERAL}",
-" Overrides the global SET FILE NAMES setting for this transfer only.",
-" ",
-"/PATHNAMES:{OFF,ABSOLUTE,RELATIVE}",
-" Overrides the global SET SEND PATHNAMES setting for this transfer.",
-" ",
-"/FILTER:command",
-" Specifies a command \
-(standard input/output filter) to pass the file through",
-" before sending it.",
-" ",
-"/DELETE",
-" Deletes the file (or each file in the group) after it has been sent",
-" successfully (applies only to real files).",
-" ",
-"/QUIET",
-" When sending in local mode, this suppresses the file-transfer display.",
-" ",
-"/RECOVER",
-" Used to recover from a previously interrupted transfer; SEND /RECOVER",
-" is equivalent RESEND (use in binary mode only).",
-" ",
-"/RECURSIVE",
-" Tells C-Kermit to look not only in the given or current directory for",
-" files that match the filespec, but also in all its subdirectories, and",
-" all their subdirectories, etc.",
-" ",
-"/RENAME-TO:name",
-" Tells C-Kermit to rename each source file that is sent successfully to",
-" the given name (usually you should include \\v(filename) in the new name,",
-" which is replaced by the original filename.",
-" ",
-"/MOVE-TO:directory",
-" Tells C-Kermit to move each source file that is sent successfully to",
-" the given directory.",
-" ",
-"/STARTING:number",
-" Starts sending the file from the given byte position.",
-" SEND /STARTING:n filename is equivalent to PSEND filename n.",
-" ",
-"/SUBJECT:text",
-" Specifies the subject of an email message, to be used with /MAIL. If the",
-" text contains spaces, it must be enclosed in braces.",
-" ",
-"/MAIL:address",
-" Sends the file as e-mail to the given address; use with /SUBJECT:.",
-" ",
-"/PRINT:options",
-" Sends the file to be printed, with optional options for the printer.",
-" ",
-#ifdef CK_XYZ
-"/PROTOCOL:name",
-" Uses the given protocol to send the file (Kermit, Zmodem, etc) for this",
-" transfer without changing global protocol.",
-" ",
-#endif /* CK_XYZ */
-"/AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files created after the given date-time are",
-#else
-" Specifies that only those files modified after the given date-time are",
-#endif /* VMS */
-" to be sent. HELP DATE for info about date-time formats.",
-" ",
-"/BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified before the given date-time",
-#else
-" Specifies that only those files modified before the given date-time",
-#endif /* VMS */
-" are to be sent.",
-" ",
-"/NOT-AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or before the given date-time",
-#else
-" Specifies that only those files modified at or before the given date-time",
-#endif /* VMS */
-" are to be sent.",
-" ",
-"/NOT-BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or after the given date-time",
-#else
-" Specifies that only those files modified at or after the given date-time",
-#endif /* VMS */
-" are to be sent.",
-" ",
-"/LARGER-THAN:number",
-" Specifies that only those files longer than the given number of bytes are",
-" to be sent.",
-" ",
-"/SMALLER-THAN:number",
-" Specifies that only those files smaller than the given number of bytes are",
-" to be sent.",
-" ",
-"/EXCEPT:pattern",
-" Specifies that any files whose names match the pattern, which can be a",
-" regular filename, or may contain \"*\" and/or \"?\" metacharacters,",
-" are not to be sent. To specify multiple patterns (up to 8), use outer",
-" braces around the group, and inner braces around each pattern:",
-" ",
-" /EXCEPT:{{pattern1}{pattern2}...}",
-" ",
-"/TYPE:{ALL,TEXT,BINARY}",
-" Send only files of the given type (see SET FILE SCAN).",
-" ",
-"/LISTFILE:filename",
-" Specifies the name of a file that contains the list of names of files",
-" that are to be sent. The filenames should be listed one name per line",
-" in this file (but a name can contain wildcards).",
-" ",
-"Also see HELP RECEIVE, HELP GET, HELP SERVER, HELP REMOTE.",
-""};
-
-static char *hmxxrc[] = {
-"Syntax: RECEIVE (or R) [ switches... ] [ as-name ]",
-" Wait for a file to arrive from the other Kermit, which must be given a",
-" SEND command. If the optional as-name is given, the incoming file or",
-" files are stored under that name, otherwise it will be stored under",
-#ifndef CK_TMPDIR
-" the name it arrives with.",
-#else
-#ifdef OS2
-" the name it arrives with. If the filespec denotes a disk and/or",
-" directory, the incoming file or files will be stored there.",
-#else
-" the name it arrives with. If the filespec denotes a directory, the",
-" incoming file or files will be placed in that directory.",
-#endif /* OS2 */
-#endif /* CK_TMPDIR */
-" ",
-"Optional switches include:",
-" ",
-"/AS-NAME:text",
-" Specifies \"text\" as the name to store the incoming file under.",
-" You can also specify the as-name as a filename on the command line.",
-" ",
-"/BINARY",
-" Skips text-mode conversions unless the incoming file arrives with binary",
-" attribute",
-" ",
-"/COMMAND",
-" Receives the file into the standard input of a command, rather than saving",
-" it on disk. The /AS-NAME or the \"filename\" on the RECEIVE command line",
-" is interpreted as the name of a command.",
-" ",
-"/EXCEPT:pattern",
-" Specifies that any files whose names match the pattern, which can be a",
-" regular filename, or may contain \"*\" and/or \"?\" metacharacters,",
-" are to be refused. To specify multiple patterns (up to 8), use outer",
-" braces around the group, and inner braces around each pattern:",
-" ",
-" /EXCEPT:{{pattern1}{pattern2}...}",
-" ",
-"/FILENAMES:{CONVERTED,LITERAL}",
-" Overrides the global SET FILE NAMES setting for this transfer only.",
-" ",
-"/FILTER:command",
-" Causes the incoming file to passed through the given command (standard",
-" input/output filter) before being written to disk.",
-" ",
-#ifdef VMS
-"/IMAGE",
-" Receives the file in image mode.",
-" ",
-#endif /* VMS */
-#ifdef CK_LABELED
-"/LABELED",
-" Specifies labeled transfer mode.",
-" ",
-#endif /* CK_LABELED */
-
-"/MOVE-TO:directory-name",
-" Specifies that each file that arrives should be moved to the specified",
-" directory after, and only if, it has been received successfully.",
-" ",
-"/PATHNAMES:{OFF,ABSOLUTE,RELATIVE,AUTO}",
-" Overrides the global SET RECEIVE PATHNAMES setting for this transfer.",
-" ",
-"/PIPES:{ON,OFF}",
-" Overrides the TRANSFER PIPES setting for this command only. ON allows",
-" reception of files with names like \"!tar xf -\" to be automatically",
-" directed to a pipeline.",
-" ",
-"/PROTOCOL:name",
-" Use the given protocol to receive the incoming file(s).",
-" ",
-"/QUIET",
-" When sending in local mode, this suppresses the file-transfer display.",
-" ",
-"/RECURSIVE",
-" Equivalent to /PATHNAMES:RELATIVE.",
-" ",
-"/RENAME-TO:string",
-" Specifies that each file that arrives should be renamed as specified",
-" after, and only if, it has been received successfully. The string should",
-" normally contain variables like \\v(filename) or \\v(filenum).",
-" ",
-"/TEXT",
-" Forces text-mode conversions unless the incoming file has the binary",
-" attribute",
-" ",
-"/TRANSPARENT",
-" Inhibits character-set translation of incoming text files for the duration",
-" of the RECEIVE command without affecting subsequent commands.",
-" ",
-"Also see HELP SEND, HELP GET, HELP SERVER, HELP REMOTE.",
-"" };
-
-#ifndef NORESEND
-static char *hmxxrsen = "\
-Syntax: RESEND filespec [name]\n\n\
- Resends the file or files, whose previous transfer was interrupted.\n\
- Picks up from where previous transfer left off, IF the receiver kept the\n\
- partially received file. Works only for binary-mode transfers.\n\
- Requires file-transfer partner to support recovery. Synonym: REPUT.";
-
-static char *hmxxrget = "\
-Syntax: REGET filespec\n\n\
- Ask a server to RESEND a file to C-Kermit.";
-
-static char *hmxxpsen = "\
-Syntax: PSEND filespec position [name]\n\n\
- Just like SEND, except sends the file starting at the given byte position.";
-#endif /* NORESEND */
-
-#ifndef NOMSEND
-static char *hmxxmse[] = {
-"Syntax: MSEND [ switches... ] filespec [ filespec [ ... ] ]",
-" Sends the files specified by the filespecs. One or more filespecs may be",
-" listed, separated by spaces. Any or all filespecs may contain wildcards",
-" and they may be in different directories. Alternative names cannot be",
-" given. Switches include /BINARY /DELETE /MAIL /PROTOCOL /QUIET /RECOVER",
-" /TEXT /TYPE; see HELP SEND for descriptions.",
-""
-};
-#endif /* NOMSEND */
-
-static char *hmxxadd[] = {
-#ifndef NOMSEND
-"ADD SEND-LIST filespec [ <mode> [ <as-name> ] ]",
-" Adds the specified file or files to the current SEND list. Use SHOW",
-" SEND-LIST and CLEAR SEND-LIST to display and clear the list; use SEND",
-" by itself to send the files from it.",
-" ",
-#endif /* NOMSEND */
-#ifdef PATTERNS
-"ADD BINARY-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Adds the pattern(s), if any, to the SET FILE BINARY-PATTERNS list.",
-" ",
-"ADD TEXT-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Adds the pattern(s), if any, to the SET FILE TEXT-PATTERNS list.",
-" Use SHOW PATTERNS to see the lists. See HELP SET FILE for further info.",
-#endif /* PATTERNS */
-""};
-
-static char *hmxxremv[] = {
-#ifdef PATTERNS
-"REMOVE BINARY-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Removes the pattern(s), if any, from the SET FILE BINARY-PATTERNS list",
-" ",
-"REMOVE TEXT-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Removes the given patterns from the SET FILE TEXT-PATTERNS list.",
-" Use SHOW PATTERNS to see the lists. See HELP SET FILE for further info.",
-#endif /* PATTERNS */
-""};
-#endif /* NOXFER */
-
-#ifndef NOSERVER
-static char *hmxxser = "Syntax: SERVER\n\
- Enter server mode on the current connection. All further commands\n\
- are taken in packet form from the other Kermit program. Use FINISH,\n\
- BYE, or REMOTE EXIT to get C-Kermit out of server mode.";
-#endif /* NOSERVER */
-
-static char *hmhset[] = {
-" The SET command establishes communication, file, scripting, or other",
-" parameters. The SHOW command can be used to display the values of",
-" SET parameters. Help is available for each individual parameter;",
-" type HELP SET ? to see what's available.",
-"" };
-
-#ifndef NOSETKEY
-static char *hmhskey[] = {
-"Syntax: SET KEY k text",
-"Or: SET KEY CLEAR",
-" Configure the key whose \"scan code\" is k to send the given text when",
-" pressed during CONNECT mode. SET KEY CLEAR restores all the default",
-" key mappings. If there is no text, the default key binding is restored",
-#ifndef NOCSETS
-" for the key k. SET KEY mappings take place before terminal character-set",
-" translation.",
-#else
-" the key k.",
-#endif /* NOCSETS */
-#ifdef OS2
-" ",
-" The text may contain \"\\Kverbs\" to denote actions, to stand for DEC",
-" keypad, function, or editing keys, etc. For a list of available keyboard",
-" verbs, type SHOW KVERBS.",
-#endif /* OS2 */
-" ",
-" To find out the scan code and mapping for a particular key, use the",
-" SHOW KEY command.",
-""};
-#endif /* NOSETKEY */
-
-static char *hmxychkt[] = { "Syntax: SET BLOCK-CHECK number",
-" ",
-"Type of block check to be used for error detection on file-transfer",
-"packets: 1, 2, 3, 4, or 5. This command must be given to the file",
-"sender prior to the transfer.",
-" ",
-"Type 1 is standard and supported by all Kermit protocol implementations,",
-" but it's only a 6-bit checksum, represented in a single printable ASCII",
-" character. It's fine for reliable connections (error-correcting modems,",
-" TCP/IP, etc) but type 3 is recommended for connections where errors can",
-" occur.",
-" ",
-"Type 2 is a 12-bit checksum represented in two printable characters.",
-" ",
-"Type 3 is a 16-bit cyclic redundancy check, the strongest error",
-" detection method supported by Kermit protocol, represented in three",
-" printable characters.",
-" ",
-"Type 4 (alias \"BLANK-FREE-2\") is a 12-bit checksum guaranteed to",
-" contain no blanks in its representation; this is needed for connections",
-" where trailing blanks are stripped from incoming lines of text.",
-" ",
-"Type 5 (alias \"FORCE-3\") means to force a Type 3 block check on",
-" every packet, including the first packet, which normally has a type 1",
-" block check. This is for use in critical applications on noisy",
-" connections. As with types 2, 3, and 4, if the Kermit file",
-" transfer partner does not support this type, the transfer fails",
-" immediately at the beginning of the transfer.",
-"" };
-
-static char * hmxydeb[] = {
-"Syntax: SET DEBUG { SESSION, ON, OFF, TIMESTAMP, MESSAGES }",
-" ",
-"SET DEBUG ON",
-#ifdef DEBUG
-" Opens a debug log file named debug.log in the current directory.",
-" Use LOG DEBUG if you want specify a different log file name or path.",
-#else
-" (Has no effect in this version of Kermit.)",
-#endif /* DEBUG */
-" ",
-"SET DEBUG OFF",
-" Stops debug logging and session debugging.",
-" ",
-"SET DEBUG SESSION",
-#ifndef NOLOCAL
-" Displays control and 8-bit characters symbolically during CONNECT mode.",
-" Equivalent to SET TERMINAL DEBUG ON.",
-#else
-" (Has no effect in this version of Kermit.)",
-#endif /* NOLOCAL */
-" ",
-"SET DEBUG TIMESTAMP { ON, OFF }",
-" Enables/Disables timestamps on debug log entries.",
-" ",
-"SET DEBUG MESSAGES { ON, OFF, STDERR } [C-Kermit 9.0]",
-" Enables/Disables messages printed by the DEBUG command.",
-" SET DEBUG OFF causes DEBUG messages not to be printed.",
-" SET DEBUG ON sends DEBUG messages to standard output (stdout);",
-" SET DEBUG STDERR sends DEBUG messages to standard error (stderr);",
-"" };
-
-#ifdef CK_SPEED
-static char *hmxyqctl[] = {
-"Syntax: SET CONTROL-CHARACTER { PREFIXED, UNPREFIXED } { <code>..., ALL }",
-" ",
-" <code> is the numeric ASCII code for a control character 1-31,127-159,255."
-,
-" The word \"ALL\" means all characters in this range.",
-" ",
-" PREFIXED <code> means the given control character must be converted to a",
-" printable character and prefixed, the default for all control characters.",
-" ",
-" UNPREFIXED <code> means you think it is safe to send the given control",
-" character as-is, without a prefix. USE THIS OPTION AT YOUR OWN RISK!",
-" ",
-" SHOW CONTROL to see current settings. SET CONTROL PREFIXED ALL is",
-" recommended for safety. You can include multiple <code> values in one",
-" command, separated by spaces.",
-"" };
-#endif /* CK_SPEED */
-
-#ifndef NODIAL
-static char *hxymodm[] = {
-"Syntax: SET MODEM <parameter> <value> ...",
-" ",
-"Note: Many of the SET MODEM parameters are configured automatically when",
-"you SET MODEM TYPE, according to the modem's capabilities. SHOW MODEM to",
-"see them. Also see HELP DIAL and HELP SET DIAL.",
-" ",
-"SET MODEM TYPE <name>",
-
-" Tells Kermit which kind of modem you have, so it can issue the",
-" appropriate modem-specific commands for configuration, dialing, and",
-" hanging up. For a list of the modem types known to Kermit, type \"set",
-" modem type ?\". The default modem type is GENERIC, which should work",
-" with any AT command-set modem that is configured for error correction,",
-" data compression, and hardware flow control. Use SET MODEM TYPE NONE",
-" for direct serial, connections. Use SET MODEM TYPE USER-DEFINED to use",
-" a type of modem that is not built in to Kermit, and then use SET MODEM",
-" CAPABILITIES, SET MODEM, DIAL-COMMAND, and SET MODEM COMMAND to tell",
-" Kermit how to configure and control it.",
-
-" ",
-
-"SET MODEM CAPABILITIES <list>",
-" Use this command for changing Kermit's idea of your modem's capabilities,",
-" for example, if your modem is supposed to have built-in error correction",
-" but in fact does not. Also use this command to define the capabilities",
-" of a USER-DEFINED modem. Capabilities are:",
-" ",
-" AT AT-commands",
-" DC data-compression",
-" EC error-correction",
-" HWFC hardware-flow",
-" ITU v25bis-commands",
-" SWFC software-flow",
-" KS kermit-spoof",
-" SB speed-buffering",
-" TB Telebit",
-" ",
-"SET MODEM CARRIER-WATCH { AUTO, ON, OFF }",
-" Synonym for SET CARRIER-WATCH (q.v.)",
-" ",
-"SET MODEM COMPRESSION { ON, OFF }",
-" Enables/disables the modem's data compression feature, if any.",
-" ",
-"SET MODEM DIAL-COMMAND <text>",
-" The text replaces Kermit's built-in modem dialing command. It must",
-" include '%s' (percent s) as a place-holder for the telephone numbers",
-" given in your DIAL commands.",
-" ",
-"SET MODEM ERROR-CORRECTION { ON, OFF }",
-" Enables/disables the modem's error-correction feature, if any.",
-" ",
-"SET MODEM ESCAPE-CHARACTER number",
-" Numeric ASCII value of modem's escape character, e.g. 43 for '+'.",
-" For Hayes-compatible modems, Kermit uses three copies, e.g. \"+++\".",
-" ",
-"SET MODEM FLOW-CONTROL {AUTO, NONE, RTS/CTS, XON/XOFF}",
-" Selects the type of local flow control to be used by the modem.",
-" ",
-"SET MODEM HANGUP-METHOD { MODEM-COMMAND, RS232-SIGNAL, DTR }",
-" How hangup operations should be done. MODEM-COMMAND means try to",
-" escape back to the modem's command processor and give a modem-specific",
-" hangup command. RS232-SIGNAL means turn off the DTR signal. DTR is a",
-" synonym for RS232-SIGNAL.",
-" ",
-"SET MODEM KERMIT-SPOOF {ON, OFF}",
-" If the selected modem type supports the Kermit protocol directly,",
-" use this command to turn its Kermit protocol function on or off.",
-" ",
-"SET MODEM MAXIMUM-SPEED <number>",
-" Specify the maximum interface speed for the modem.",
-" ",
-"SET MODEM NAME <text>",
-" Descriptive name for a USER-DEFINED modem.",
-" ",
-"SET MODEM SPEAKER {ON, OFF}",
-" Turns the modem's speaker on or off during dialing.",
-" ",
-"SET MODEM SPEED-MATCHING {ON, OFF}",
-" ON means that C-Kermit changes its serial interface speed to agree with",
-" the speed reported by the modem's CONNECT message, if any. OFF means",
-" Kermit should not change its interface speed.",
-" ",
-"SET MODEM VOLUME {LOW, MEDIUM, HIGH}",
-" Selects the desired modem speaker volume for when the speaker is ON.",
-" ",
-"SET MODEM COMMAND commands are used to override built-in modem commands for",
-"each modem type, or to fill in commands for the USER-DEFINED modem type.",
-"Omitting the optional [ text ] restores the built-in modem-specific command,",
-"if any:",
-" ",
-"SET MODEM COMMAND AUTOANSWER {ON, OFF} [ text ]",
-" Modem commands to turn autoanswer on and off.",
-" ",
-"SET MODEM COMMAND COMPRESSION {ON, OFF} [ text ]",
-" Modem commands to turn data compression on and off.",
-" ",
-"SET MODEM COMMAND ERROR-CORRECTION {ON, OFF} [ text ]",
-" Modem commands to turn error correction on and off.",
-" ",
-"SET MODEM COMMAND HANGUP [ text ]",
-" Command that tells the modem to hang up the connection.",
-" ",
-"SET MODEM COMMAND IGNORE-DIALTONE [ text ]",
-" Command that tells the modem not to wait for dialtone before dialing.",
-" ",
-"SET MODEM COMMAND INIT-STRING [ text ]",
-" The 'text' is a replacement for C-Kermit's built-in initialization command",
-" for the modem.",
-" ",
-"SET MODEM COMMAND PREDIAL-INIT [ text ]",
-" A second INIT-STRING that is to be sent to the modem just prior to \
-dialing.",
-" ",
-"SET MODEM COMMAND HARDWARE-FLOW [ text ]",
-" Modem command to enable hardware flow control (RTS/CTS) in the modem.",
-" ",
-"SET MODEM COMMAND SOFTWARE-FLOW [ text ]",
-" Modem command to enable local software flow control (Xon/Xoff) in modem.",
-" ",
-"SET MODEM COMMAND SPEAKER { ON, OFF } [ text ]",
-" Modem command to turn the modem's speaker on or off.",
-" ",
-"SET MODEM COMMAND NO-FLOW-CONTROL [ text ]",
-" Modem command to disable local flow control in the modem.",
-" ",
-"SET MODEM COMMAND PULSE [ text ]",
-" Modem command to select pulse dialing.",
-" ",
-"SET MODEM COMMAND TONE [ text ]",
-" Modem command to select tone dialing.",
-" ",
-"SET MODEM COMMAND VOLUME { LOW, MEDIUM, HIGH } [ text ]",
-" Modem command to set the modem's speaker volume.",
-""};
-
-static char *hmxydial[] = {
-"The SET DIAL command establishes or changes all parameters related to",
-"dialing the telephone. Also see HELP DIAL and HELP SET MODEM. Use SHOW",
-"DIAL to display all of the SET DIAL values.",
-" ",
-"SET DIAL COUNTRY-CODE <number>",
-" Tells Kermit the telephonic country-code of the country you are dialing",
-" from, so it can tell whether a portable-format phone number from your",
-" dialing directory will result in a national or an international call.",
-" Examples: 1 for USA, Canada, Puerto Rico, etc; 7 for Russia, 39 for Italy,",
-" 351 for Portugal, 47 for Norway, 44 for the UK, 972 for Israel, 81 for",
-" Japan, ...",
-" ",
-" If you have not already set your DIAL INTL-PREFIX and LD-PREFIX, then this",
-" command sets default values for them: 011 and 1, respectively, for country",
-" code 1; 00 and 0, respectively, for all other country codes. If these are",
-" not your true international and long-distance dialing prefixes, then you",
-" should follow this command by DIAL INTL-PREFIX and LD-PREFIX to let Kermit",
-" know what they really are.",
-" ",
-"SET DIAL AREA-CODE [ <number> ]",
-" Tells Kermit the area or city code that you are dialing from, so it can",
-" tell whether a portable-format phone number from the dialing directory is",
-" local or long distance. Be careful not to include your long-distance",
-" dialing prefix as part of your area code; for example, the area code for",
-" central London is 171, not 0171.",
-" ",
-"SET DIAL CONFIRMATION {ON, OFF}",
-" Kermit does various transformations on a telephone number retrieved from",
-" the dialing directory prior to dialing (use LOOKUP <name> to see them).",
-" In case the result might be wrong, you can use SET DIAL CONFIRM ON to have",
-" Kermit ask you if it is OK to dial the number, and if not, to let you type",
-" in a replacement.",
-" ",
-"SET DIAL CONNECT { AUTO, ON, OFF }",
-" Whether to CONNECT (enter terminal mode) automatically after successfully",
-" dialing. ON means to do this; OFF means not to. AUTO (the default) means",
-" do it if the DIAL command was given interactively, but don't do it if the",
-" DIAL command was issued from a macro or command file. If you specify ON",
-" or AUTO, you may follow this by one of the keywords VERBOSE or QUIET, to",
-" indicate whether the verbose 4-line 'Connecting...' message is to be",
-" displayed if DIAL succeeds and Kermit goes into CONNECT mode.",
-" ",
-"SET DIAL CONVERT-DIRECTORY {ASK, ON, OFF}",
-" The format of Kermit's dialing directory changed in version 5A(192). This",
-" command tells Kermit what to do when it encounters an old-style directory:",
-" ASK you whether to convert it, or convert it automatically (ON), or leave",
-" it alone (OFF). Old-style directories can still be used without",
-" conversion, but the parity and speed fields are ignored.",
-" ",
-"SET DIAL DIRECTORY [ filename [ filename [ filename [ ... ] ] ] ]",
-" The name(s) of your dialing directory file(s). If you do not supply any",
-" filenames, the dialing directory feature is disabled and all numbers are",
-" dialed literally as given in the DIAL command. If you supply more than",
-" one directory, all of them are searched.",
-" ",
-"SET DIAL SORT {ON, OFF}",
-" When multiple entries are obtained from your dialing directory, they are",
-" sorted in \"cheapest-first\" order. If this does not produce the desired",
-" effect, SET DIAL SORT OFF to disable sorting, and the numbers will be",
-" dialed in the order in which they were found.",
-" ",
-"SET DIAL DISPLAY {ON, OFF}",
-" Whether to display dialing progress on the screen; default is OFF.",
-" ",
-"SET DIAL HANGUP {ON, OFF}",
-" Whether to hang up the phone prior to dialing; default is ON.",
-" ",
-"SET DIAL IGNORE-DIALTONE {ON, OFF}",
-" Whether to ignore dialtone when dialing; default is OFF.",
-" ",
-#ifndef NOSPL
-"SET DIAL MACRO [ name ]",
-" Specify the name of a macro to execute on every phone number dialed, just",
-" prior to dialing it, in order to perform any last-minute alterations.",
-" ",
-#endif /* NOSPL */
-"SET DIAL METHOD {AUTO, DEFAULT, TONE, PULSE}",
-" Whether to use the modem's DEFAULT dialing method, or to force TONE or",
-" PULSE dialing. AUTO (the default) means to choose tone or pulse dialing",
-" based on the country code. (Also see SET DIAL TONE-COUNTRIES and SET DIAL",
-" PULSE-COUNTRIES.)",
-" ",
-"SET DIAL PACING number",
-" How many milliseconds to pause between sending each character to the modem",
-" dialer. The default is -1, meaning to use the number from the built-in",
-" modem database.",
-" ",
-"SET DIAL PULSE-COUNTRIES [ cc [ cc [ ... ] ] ]",
-" Sets the list of countries in which pulse dialing is required. Each cc",
-" is a country code.",
-" ",
-"SET DIAL TEST { ON, OFF }",
-" OFF for normal dialing. Set to ON to test dialing procedures without",
-" actually dialing.",
-" ",
-"SET DIAL TONE-COUNTRIES [ cc [ cc [ ... ] ] ]",
-" Sets the list of countries in which tone dialing is available. Each cc",
-" is a country code.",
-" ",
-"SET DIAL TIMEOUT number",
-" How many seconds to wait for a dialed call to complete. Use this command",
-" to override the DIAL command's automatic timeout calculation. A value",
-" of 0 turns off this feature and returns to Kermit's automatic dial",
-" timeout calculation.",
-" ",
-"SET DIAL RESTRICT { INTERNATIONAL, LOCAL, LONG-DISTANCE, NONE }",
-" Prevents placing calls of the type indicated, or greater. For example",
-" SET DIAL RESTRICT LONG prevents placing of long-distance and international",
-" calls. If this command is not given, there are no restrictions. Useful",
-" when dialing a list of numbers fetched from a dialing directory.",
-" ",
-"SET DIAL RETRIES <number>",
-" How many times to redial each number if the dialing result is busy or no",
-" no answer, until the call is successfully answered. The default is 0",
-" because automatic redialing is illegal in some countries.",
-" ",
-"SET DIAL INTERVAL <number>",
-" How many seconds to pause between automatic redial attempts; default 10.",
-" ",
-"The following commands apply to all phone numbers, whether given literally",
-"or found in the dialing directory:",
-" ",
-"SET DIAL PREFIX [ text ]",
-" Establish a prefix to be applied to all phone numbers that are dialed,",
-" for example to disable call waiting.",
-" ",
-"SET DIAL SUFFIX [ text ]",
-" Establish a suffix to be added after all phone numbers that are dialed.",
-" ",
-"The following commands apply only to portable-format numbers obtained from",
-"the dialing directory; i.e. numbers that start with a \"+\" sign and",
-"country code, followed by area code in parentheses, followed by the phone",
-"number.",
-" ",
-"SET DIAL LC-AREA-CODES [ <list> ]",
-" Species a list of area codes to which dialing is local, i.e. does not",
-" require the LD-PREFIX. Up to 32 area codes may be listed, separated by",
-" spaces. Any area codes in this list will be included in the final dial",
-" string so do not include your own area code if it should not be dialed.",
-" ",
-"SET DIAL LC-PREFIX [ <text> ]",
-" Specifies a prefix to be applied to local calls made from portable dialing",
-" directory entries. Normally no prefix is used for local calls.",
-" ",
-"SET DIAL LC-SUFFIX [ <text> ]",
-" Specifies a suffix to be applied to local calls made from portable dialing",
-" directory entries. Normally no suffix is used for local calls.",
-" ",
-"SET DIAL LD-PREFIX [ <text> ]",
-" Your long-distance dialing prefix, to be used with portable dialing",
-" directory entries that result in long-distance calls.",
-" ",
-"SET DIAL LD-SUFFIX [ <text> ]",
-" Long-distance dialing suffix, if any, to be used with portable dialing",
-" directory entries that result in long-distance calls. This would normally",
-" be used for appending a calling-card number to the phone number.",
-" ",
-"SET DIAL FORCE-LONG-DISTANCE { ON, OFF }",
-" Whether to force long-distance dialing for calls that normally would be",
-" local. For use (e.g.) in France.",
-" ",
-"SET DIAL TOLL-FREE-AREA-CODE [ <number> [ <number> [ ... ] ] ]",
-" Tells Kermit the toll-free area code(s) in your country.",
-" ",
-"SET DIAL TOLL-FREE-PREFIX [ <text> ]",
-" You toll-free dialing prefix, in case it is different from your long-",
-" distance dialing prefix.",
-" ",
-"SET DIAL INTL-PREFIX <text>",
-" Your international dialing prefix, to be used with portable dialing",
-" directory entries that result in international calls.",
-" ",
-"SET DIAL INTL-SUFFIX <text>",
-" International dialing suffix, if any, to be used with portable dialing",
-" directory entries that result in international calls.",
-" ",
-"SET DIAL PBX-OUTSIDE-PREFIX <text>",
-" Use this to tell Kermit how to get an outside line when dialing from a",
-" Private Branch Exchange (PBX).",
-" ",
-"SET DIAL PBX-EXCHANGE <text> [ <text> [ ... ] ]",
-" If PBX-OUTSIDE-PREFIX is set, then you can use this command to tell Kermit",
-" the leading digits of one or more local phone numbers that identify it as",
-" being on your PBX, so it can make an internal call by deleting those digits"
-,
-" from the phone number.",
-" ",
-"SET DIAL PBX-INTERNAL-PREFIX <text>",
-" If PBX-EXCHANGE is set, and Kermit determines from it that a call is",
-" internal, then this prefix, if any, is added to the number prior to",
-" \
-dialing. Use this if internal calls from your PBX require a special prefix.",
-"" };
-#endif /* NODIAL */
-
-static char *hmxyflo[] = { "Syntax: SET FLOW [ switch ] value",
-" ",
-#ifndef NOLOCAL
-" Selects the type of flow control to use during file transfer, terminal",
-" connection, and script execution.",
-#else
-" Selects the type of flow control to use during file transfer.",
-#endif /* NOLOCAL */
-" ",
-" Switches let you associate a particular kind of flow control with each",
-" kind of connection: /REMOTE, /MODEM, /DIRECT-SERIAL, /TCPIP, etc; type",
-" \"set flow ?\" for a list of available switches. Then whenever you make",
-" a connection, the associated flow-control is chosen automatically.",
-" The flow-control values are NONE, KEEP, XON/XOFF, and possibly RTS/CTS",
-" and some others; again, type \"set flow ?\" for a list. KEEP tells Kermit",
-" not to try to change the current flow-control method for the connection.",
-" ",
-" If you omit the switch and simply supply a value, this value becomes the",
-" current flow control type, overriding any default value that might have",
-" been chosen in your most recent SET LINE, SET PORT, or SET HOST, or other",
-" connection-establishment command.",
-" ",
-" Type SHOW FLOW-CONTROL to see the current defaults for each connection type"
-,
-" as well as the current connection type and flow-control setting. SHOW",
-" COMMUNICATIONS also shows the current flow-control setting.",
-""};
-
-static char *hmxyf[] = {
-"Syntax: SET FILE parameter value",
-" ",
-"Sets file-related parameters. Use SHOW FILE to view them. Also see SET",
-"(and SHOW) TRANSFER and PROTOCOL.",
-" ",
-#ifdef VMS
-"SET FILE TYPE { TEXT, BINARY, IMAGE, LABELED }",
-#else
-#ifdef STRATUS
-"SET FILE TYPE { TEXT, BINARY, LABELED }",
-#else
-#ifdef MAC
-"SET FILE TYPE { TEXT, BINARY, MACBINARY }",
-#else
-"SET FILE TYPE { TEXT, BINARY }",
-#endif /* STRATUS */
-#endif /* MAC */
-#endif /* VMS */
-" How file contents are to be treated during file transfer in the absence",
-" of any other indication. TYPE can be TEXT for conversion of record format",
-" and character set, which is usually needed when transferring text files",
-" between unlike platforms (such as UNIX and Windows), or BINARY for no",
-" conversion if TRANSFER MODE is MANUAL, which is not the default. Use",
-" BINARY with TRANSFER MODE MANUAL for executable programs or binary data or",
-" whenever you wish to duplicate the original contents of the file, byte for"
-,
-" byte. In most modern Kermit programs, the file sender informs the receiver"
-,
-" of the file type automatically. However, when sending files from C-Kermit",
-" to an ancient or non-Columbia Kermit implementation, you might need to set",
-" the corresponding file type at the receiver as well.",
-" ",
-#ifdef VMS
-" FILE TYPE settings of TEXT and BINARY have no effect when sending files,",
-" since VMS C-Kermit determines each file's type automatically from its",
-" record format: binary for fixed, text for others. For incoming files,",
-" these settings are effective only in the absence of a file-type indication",
-" from the sender.",
-" ",
-" You may include an optional record-format after the word BINARY. This may",
-" be FIXED (the default) or UNDEFINED. UNDEFINED is used when you need to",
-" receive binary files in binary mode and have them stored with UNDEFINED",
-" record format, which is required by certain VMS applications.",
-" ",
-" Two additional VMS file types are also supported: IMAGE and LABELED.",
-" IMAGE means raw block i/o, no interference from RMS, applies to file",
-" transmission only, and overrides the normal automatica file type",
-" determination. LABELED means to send or interpret RMS attributes",
-" with the file.",
-" ",
-#else
-" When TRANSFER MODE is AUTOMATIC (as it is by default), various automatic",
-" methods (depending on the platform) are used to determine whether a file",
-" is transferred in text or binary mode; these methods (which might include",
-" content scan (see SET FILE SCAN below), filename pattern matching (SET FILE"
-,
-" PATTERNS), client/server \"kindred-spirit\" recognition, or source file",
-" record format) supersede the FILE TYPE setting but can, themselves, be",
-" superseded by including a /BINARY or /TEXT switch in the SEND, GET, or",
-" RECEIVE command.",
-" ",
-" When TRANSFER MODE is MANUAL, the automatic methods are skipped for sending"
-,
-" files; the FILE TYPE setting is used instead, which can be superseded on",
-" a per-command basis with a /TEXT or /BINARY switch.",
-#endif /* VMS */
-" ",
-
-#ifndef NOXFER
-
-"SET FILE BYTESIZE { 7, 8 }",
-" Normally 8. If 7, Kermit truncates the 8th bit of all file bytes.",
-" ",
-#ifndef NOCSETS
-"SET FILE CHARACTER-SET name",
-" Tells the encoding of the local file, ASCII by default.",
-" The names ITALIAN, PORTUGUESE, NORWEGIAN, etc, refer to 7-bit ISO-646",
-" national character sets. LATIN1 is the 8-bit ISO 8859-1 Latin Alphabet 1",
-" for Western European languages.",
-" NEXT is the 8-bit character set of the NeXT workstation.",
-" The CPnnn sets are for PCs. MACINTOSH-LATIN is for the Macintosh.",
-#ifndef NOLATIN2
-" LATIN2 is ISO 8859-2 for Eastern European languages that are written with",
-" Roman letters. Mazovia is a PC code page used in Poland.",
-#endif /* NOLATIN2 */
-#ifdef CYRILLIC
-" KOI-CYRILLIC, CYRILLIC-ISO, and CP866 are 8-bit Cyrillic character sets.",
-" SHORT-KOI is a 7-bit ASCII coding for Cyrillic. BULGARIA-PC is a PC code",
-" page used in Bulgaria",
-#endif /* CYRILLIC */
-#ifdef HEBREW
-" HEBREW-ISO is ISO 8859-8 Latin/Hebrew. CP862 is the Hebrew PC code page.",
-" HEBREW-7 is like ASCII with the lowercase letters replaced by Hebrew.",
-#endif /* HEBREW */
-#ifdef GREEK
-" GREEK-ISO is ISO 8859-7 Latin/Greek. CP869 is the Greek PC code page.",
-" ELOT-927 is like ASCII with the lowercase letters replaced by Greek.",
-#endif /* GREEK */
-#ifdef KANJI
-" JAPANESE-EUC, JIS7-KANJI, DEC-KANJI, and SHIFT-JIS-KANJI are Japanese",
-" Kanji character sets.",
-#endif /* KANJI */
-#ifdef UNICODE
-" UCS-2 is the 2-byte form of the Universal Character Set.",
-" UTF-8 is the serialized form of the Universal Character Set.",
-#endif /* UNICODE */
-" Type SET FILE CHAR ? for a complete list of file character sets.",
-" ",
-"SET FILE DEFAULT 7BIT-CHARACTER-SET",
-" When automatically switching among different kinds of files while sending",
-" this tells the character set to be used for 7-bit text files.",
-" ",
-"SET FILE DEFAULT 8BIT-CHARACTER-SET",
-" This tells the character set to be used for 8-bit text files when",
-" switching automatically among different kinds of files.",
-" ",
-#endif /* NOCSETS */
-
-"SET FILE COLLISION option",
-" Tells what to do when a file arrives that has the same name as",
-" an existing file. The options are:",
-" BACKUP (default) - Rename the old file to a new, unique name and store",
-" the incoming file under the name it was sent with.",
-" OVERWRITE - Overwrite (replace) the existing file.",
-" APPEND - Append the incoming file to the end of the existing file.",
-" REJECT - Refuse and/or discard the incoming file (= DISCARD).",
-" RENAME - Give the incoming file a unique name.",
-" UPDATE - Accept the incoming file only if newer than the existing file.",
-" ",
-
-"SET FILE DESTINATION { DISK, PRINTER, SCREEN, NOWHERE }",
-" DISK (default): Store incoming files on disk.",
-" PRINTER: Send incoming files to SET PRINTER device.",
-" SCREEN: Display incoming files on screen (local mode only).",
-" NOWHERE: Do not put incoming files anywhere (use for calibration).",
-" ",
-"SET FILE DISPLAY option",
-" Selects the format of the file transfer display for local-mode file",
-" transfer. The choices are:",
-" ",
-" BRIEF A line per file, showing size, mode, status, and throughput.",
-" SERIAL One dot is printed for every K bytes transferred.",
-" CRT Numbers are continuously updated on a single screen line.",
-" This format can be used on any video display terminal.",
-#ifdef CK_CURSES
-" FULLSCREEN A fully formatted 24x80 screen showing lots of information.",
-" This requires a terminal or terminal emulator.",
-#endif /* CK_CURSES */
-" NONE No file transfer display at all.",
-" ",
-
-"SET FILE DOWNLOAD-DIRECTORY [ <directory-name> ]",
-" The directory into which all received files should be placed. By default,",
-" received files go into your current directory.",
-" ",
-#endif /* NOXFER */
-
-#ifdef CK_CTRLZ
-"SET FILE EOF { CTRL-Z, LENGTH }",
-" End-Of-File detection method, normally LENGTH. Applies only to text-mode",
-" transfers. When set to CTRL-Z, this makes the file sender treat the first",
-" Ctrl-Z in the input file as the end of file (EOF), and it makes the file",
-" receiver tack a Ctrl-Z onto the end of the output file if it does not",
-" already end with Ctrl-Z.",
-" ",
-#endif /* CK_CTRLZ */
-
-"SET FILE END-OF-LINE { CR, CRLF, LF }",
-" Use this command to specify nonstandard line terminators for text files.",
-" ",
-
-#ifndef NOXFER
-"SET FILE INCOMPLETE { AUTO, KEEP, DISCARD }",
-" What to do with an incompletely received file: KEEP, DISCARD, or AUTO.",
-" AUTO (the default) means DISCARD if transfer is in text mode, KEEP if it",
-" is in binary mode.",
-" ",
-#ifdef VMS
-"SET FILE LABEL { ACL, BACKUP-DATE, NAME, OWNER, PATH } { ON, OFF }",
-" Tells which items to include (ON) or exclude (OFF) in labeled file",
-" transfers",
-" ",
-#else
-#ifdef OS2
-"SET FILE LABEL { ARCHIVE, READ-ONLY, HIDDEN, SYSTEM, EXTENDED } { ON, OFF }",
-" Tells which items to include (ON) or exclude (OFF) in labeled file",
-" transfers.",
-" ",
-#endif /* OS2 */
-#endif /* VMS */
-
-#ifdef UNIX
-#ifdef DYNAMIC
-"SET FILE LISTSIZE number",
-" Changes the size of the internal wildcard expansion list. Use SHOW FILE",
-" to see the current size. Use this command to increase the size if you get",
-" a \"?Too many files\" error. Also see SET FILE STRINGSPACE.",
-" ",
-#endif /* DYNAMIC */
-#endif /* UNIX */
-
-"SET FILE NAMES { CONVERTED, LITERAL }",
-" File names are normally CONVERTED to \"common form\" during transmission",
-" (e.g. lowercase to uppercase, extra periods changed to underscore, etc).",
-" LITERAL means use filenames literally (useful between like systems). Also",
-" see SET SEND PATHNAMES and SET RECEIVE PATHNAMES.",
-" ",
-
-#ifdef UNIX
-"SET FILE OUTPUT { { BUFFERED, UNBUFFERED } [ size ], BLOCKING, NONBLOCKING }",
-" Lets you control the disk output buffer for incoming files. Buffered",
-" blocking writes are normal. Nonblocking writes might be faster on some",
-" systems but might also be risky, depending on the underlying file service.",
-" Unbuffered writes might be useful in critical applications to ensure that",
-" cached disk writes are not lost in a crash, but will probably also be",
-" slower. The optional size parameter after BUFFERED or UNBUFFERED lets you",
-" change the disk output buffer size; this might make a difference in",
-" performance.",
-" ",
-#endif /* UNIX */
-
-#ifdef PATTERNS
-"SET FILE PATTERNS { ON, OFF, AUTO }",
-" ON means to use filename pattern lists to determine whether to send a file",
-" in text or binary mode. OFF means to send all files in the prevailing",
-" mode. AUTO (the default) is like ON if the other Kermit accepts Attribute",
-" packets and like OFF otherwise. FILE PATTERNS are used only if FILE SCAN",
-" is OFF (see SET FILE SCAN).",
-" ",
-"SET FILE BINARY-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Zero or more filename patterns which, if matched, cause a file to be sent",
-" in binary mode when FILE PATTERNS are ON. HELP WILDCARDS for a description"
-,
-" of pattern syntax. SHOW PATTERNS to see the current file pattern lists.",
-" ",
-"SET FILE TEXT-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Zero or more filename patterns which, if matched, cause a file to be sent",
-" in text mode when FILE PATTERNS is ON; if a file does not match a text or",
-" binary pattern, the prevailing SET FILE TYPE is used.",
-" ",
-#endif /* PATTERNS */
-
-#ifdef VMS
-"SET FILE RECORD-LENGTH number",
-" Sets the record length for received files of type BINARY. Use this to",
-" receive VMS BACKUP savesets or other fixed-format files that do not use",
-" the default record length of 512.",
-" ",
-#endif /* VMS */
-
-"SET FILE SCAN { ON [ size ], OFF }",
-" If TRANSFER MODE is AUTOMATIC and FILE SCAN is ON (as it is by default)",
-" Kermit peeks at the file's contents to see if it's text or binary. Use",
-" SET FILE SCAN OFF to disable file peeking, while still keeping TRANSFER",
-" MODE automatic to allow name patterns and other methods. The optional",
-" size is the number of file bytes to scan, 49152 by default. -1 means to",
-" scan the whole file. Also see SET FILE PATTERNS.",
-" ",
-
-#ifdef UNIX
-#ifdef DYNAMIC
-"SET FILE STRINGSPACE number",
-" Changes the size (in bytes) of the internal buffer that holds lists of",
-" filenames such as wildcard expansion lists. Use SHOW FILE to see the",
-" current size. Use this command to increase the size if you get a",
-" \"?String space exhausted\" error. Also see SET FILE LISTSIZE.",
-" ",
-#endif /* DYNAMIC */
-#endif /* UNIX */
-
-#ifdef UNICODE
-"SET FILE UCS BOM { ON, OFF }",
-" Whether to write a Byte Order Mark when creating a UCS-2 file.",
-" ",
-"SET FILE UCS BYTE-ORDER { BIG-ENDIAN, LITTLE-ENDIAN }",
-" Byte order to use when creating UCS-2 files, and to use when reading UCS-2",
-" files that do not start with a Byte Order Mark.",
-" ",
-#endif /* UNICODE */
-
-"SET FILE WARNING { ON, OFF }",
-" SET FILE WARNING is superseded by the newer command, SET FILE",
-" COLLISION. SET FILE WARNING ON is equivalent to SET FILE COLLISION RENAME",
-" and SET FILE WARNING OFF is equivalent to SET FILE COLLISION OVERWRITE.",
-#endif /* NOXFER */
-"" };
-
-static char *hmxyhsh[] = {
-"Syntax: SET HANDSHAKE { NONE, XON, LF, BELL, ESC, CODE number }",
-" Character to use for half duplex line turnaround handshake during file",
-" transfer. C-Kermit waits for this character from the other computer",
-" before sending its next packet. Default is NONE; you can give one of the",
-" other names like BELL or ESC, or use SET HANDSHAKE CODE to specify the",
-" numeric code value of the handshake character. Type SET HANDSH ? for a",
-" complete list of possibilities.",
-"" };
-
-#ifndef NOSERVER
-static char *hsetsrv[] = {
-"SET SERVER CD-MESSAGE {ON,OFF}",
-" Tells whether the server, after successfully executing a REMOTE CD",
-" command, should send the contents of the new directory's READ.ME",
-" (or similar) file to your screen.",
-" ",
-"SET SERVER CD-MESSAGE FILE name",
-" Tells the name of the file to be displayed as a CD-MESSAGE, such as",
-" READ.ME (SHOW SERVER tells the current CD-MESSAGE FILE name).",
-" To specify more than one filename to look for, use {{name1}{name2}..}.",
-" Synonym: SET CD MESSAGE FILE <list>.",
-" ",
-"SET SERVER DISPLAY {ON,OFF}",
-" Tells whether local-mode C-Kermit during server operation should put a",
-" file transfer display on the screen. Default is OFF.",
-" ",
-"SET SERVER GET-PATH [ directory [ directory [ ... ] ] ]",
-" Tells the C-Kermit server where to look for files whose names it receives",
-" from client GET commands when the names are not fully specified pathnames.",
-" Default is no GET-PATH, so C-Kermit looks only in its current directory.",
-" ",
-"SET SERVER IDLE-TIMEOUT seconds",
-" Idle time limit while in server mode, 0 for no limit.",
-#ifndef OS2
-" NOTE: SERVER IDLE-TIMEOUT and SERVER TIMEOUT are mutually exclusive.",
-#endif /* OS2 */
-" ",
-"SET SERVER KEEPALIVE {ON,OFF}",
-" Tells whether C-Kermit should send \"keepalive\" packets while executing",
-" REMOTE HOST commands, which is useful in case the command takes a long",
-" time to produce any output and therefore might cause the operation to time",
-" out. ON by default; turn it OFF if it causes trouble with the client or",
-" slows down the server too much.",
-" ",
-"SET SERVER LOGIN [ username [ password [ account ] ] ]",
-" Sets up a username and optional password which must be supplied before",
-" the server will respond to any commands other than REMOTE LOGIN. The",
-" account is ignored. If you enter SET SERVER LOGIN by itself, then login",
-" is no longer required. Only one SET SERVER LOGIN command can be in effect",
-" at a time; C-Kermit does not support multiple user/password pairs.",
-" ",
-"SET SERVER TIMEOUT n",
-" Server command wait timeout interval, how often the C-Kermit server issues",
-" a NAK while waiting for a command packet. Specify 0 for no NAKs at all.",
-" Default is 0.",
-""
-};
-#endif /* NOSERVER */
-
-static char *hmhrmt[] = {
-#ifdef NEWFTP
-"The REMOTE command sends file management instructions or other commands",
-"to a Kermit or FTP server. If you have a single connection, the command is",
-"directed to the server you are connected to; if you have multiple connections"
-,
-"the command is directed according to your GET-PUT-REMOTE setting.",
-#else
-"The REMOTE command sends file management instructions or other commands",
-"to a Kermit server. There should already be a Kermit running in server",
-"mode on the other end of the connection.",
-#endif /* NEWFTP */
-"Type REMOTE ? to see a list of available remote commands. Type HELP REMOTE",
-"xxx to get further information about a particular remote command xxx.",
-" ",
-"All REMOTE commands except LOGIN and LOGOUT have R-command shortcuts;",
-"for example, RDIR for REMOTE DIR, RCD for REMOTE CD, etc.",
-" ",
-#ifdef NEWFTP
-#ifdef LOCUS
-"Also see: HELP SET LOCUS, HELP FTP, HELP SET GET-PUT-REMOTE.",
-#else
-"Also see: HELP FTP, HELP SET GET-PUT-REMOTE.",
-#endif /* LOCUS */
-#else
-#ifdef LOCUS
-"Also see: HELP SET LOCUS.",
-#endif /* LOCUS */
-#endif /* NEWFTP */
-"" };
-
-#ifndef NOSPL
-static char *ifhlp[] = { "Syntax: IF [NOT] condition commandlist",
-" ",
-"If the condition is (is not) true, do the commandlist. The commandlist",
-"can be a single command, or a list of commands separated by commas and",
-"enclosed in braces. The condition can be a single condition or a group of",
-"conditions separated by AND (&&) or OR (||) and enclosed in parentheses.",
-"If parentheses are used they must be surrounded by spaces. Examples:",
-" ",
-" IF EXIST oofa.txt <command>",
-" IF ( EXIST oofa.txt || = \\v(nday) 3 ) <command>",
-" IF ( EXIST oofa.txt || = \\v(nday) 3 ) { <command>, <command>, ... }",
-" ",
-"The conditions are:",
-" ",
-" SUCCESS - The previous command succeeded",
-" OK - Synonym for SUCCESS",
-" FAILURE - The previous command failed",
-" ERROR - Synonym for FAILURE",
-" FLAG - Succeeds if SET FLAG ON, fails if SET FLAG OFF",
-" BACKGROUND - C-Kermit is running in the background",
-#ifdef CK_IFRO
-" FOREGROUND - C-Kermit is running in the foreground",
-" REMOTE-ONLY - C-Kermit was started with the -R command-line option",
-#else
-" FOREGROUND - C-Kermit is running in the foreground",
-#endif /* CK_IFRO */
-" KERBANG - A Kerbang script is running",
-" ALARM - SET ALARM time has passed",
-" ASKTIMEOUT - The most recent ASK, ASKQ, GETC, or GETOK timed out",
-" EMULATION - Succeeds if executed while in CONNECT mode",
-#ifdef OS2
-" TAPI - Current connection is via a Microsoft TAPI device",
-#endif /* OS2 */
-" ",
-" MS-KERMIT - Program is MS-DOS Kermit",
-" C-KERMIT - Program is C-Kermit",
-" K-95 - Program is Kermit 95",
-" GUI - Program runs in a GUI window",
-" ",
-" AVAILABLE CRYPTO - Encryption is available",
-" AVAILABLE KERBEROS4 - Kerberos 4 authentication is available",
-" AVAILABLE KERBEROS5 - Kerberos 5 authentication is available",
-" AVAILABLE NTLM - NTLM authentication is available",
-" AVAILABLE SRP - SRP authentication is available",
-" AVAILABLE SSL - SSL/TLS authentication is available",
-" MATCH string pattern - Succeeds if string matches pattern",
-#ifdef CKFLOAT
-" FLOAT number - Succeeds if floating-point number",
-#endif /* CKFLOAT */
-" COMMAND word - Succeeds if word is built-in command",
-" DEFINED variablename or macroname - The named variable or macro is defined",
-" DECLARED arrayname - The named array is declared",
-" NUMERIC variable or constant - The variable or constant is numeric",
-" EXIST filename - The named file exists",
-" ABSOLUTE filename - The filename is absolute, not relative",
-#ifdef CK_TMPDIR
-" DIRECTORY string - The string is the name of a directory",
-#endif /* CK_TMPDIR */
-#ifdef UNIX
-" LINK string - The string is a symbolic link",
-#endif /* UNIX */
-" READABLE filename - Succeeds if the file is readable",
-" WRITEABLE filename - Succeeds if the file is writeable",
-#ifdef ZFCDAT
-" NEWER file1 file2 - The 1st file is newer than the 2nd one",
-#endif /* ZFCDAT */
-" OPEN { READ-FILE,SESSION-LOG,...} - The given file or log is open",
-#ifndef NOLOCAL
-" OPEN CONNECTION - A connection is open",
-#endif /* NOLOCAL */
-" KBHIT - A key has been pressed",
-" ",
-" VERSION - equivalent to \"if >= \\v(version) ...\"",
-" COUNT - subtract one from COUNT, execute the command if the result is",
-" greater than zero (see SET COUNT)",
-" ",
-" EQUAL s1 s2 - s1 and s2 (character strings or variables) are equal",
-" LLT s1 s2 - s1 is lexically (alphabetically) less than s2",
-" LGT s1 s1 - s1 is lexically (alphabetically) greater than s2",
-" ",
-" = n1 n2 - n1 and n2 (numbers or variables containing numbers) are equal",
-" < n1 n2 - n1 is arithmetically less than n2",
-" <= n1 n2 - n1 is arithmetically less than or equal to n2",
-" > n1 n2 - n1 is arithmetically greater than n2",
-" >= n1 n2 - n1 is arithmetically greater than or equal to n2",
-" ",
-" (number by itself) - fails if the number is 0, succeeds otherwise",
-" ",
-" TRUE - always succeeds",
-" FALSE - always fails",
-" ",
-"The IF command may be followed on the next line by an ELSE command. Example:",
-" ",
-" IF < \\%x 10 ECHO It's less",
-" ELSE echo It's not less",
-" ",
-"It can also include an ELSE part on the same line if braces are used:",
-" ",
-" IF < \\%x 10 { ECHO It's less } ELSE { ECHO It's not less }",
-" ",
-"Also see HELP WILDCARD (for IF MATCH pattern syntax).",
-"" };
-
-static char *hmxxeval[] = { "Syntax: EVALUATE variable expression",
-" Evaluates the expression and assigns its value to the given variable.",
-" The expression can contain numbers and/or numeric-valued variables or",
-" functions, combined with mathematical operators and parentheses in",
-" traditional notation. Operators include +-/*(), etc. Example:",
-" EVALUATE \\%n (1+1) * (\\%a / 3).",
-" ",
-" NOTE: Prior to C-Kermit 7.0, the syntax was \"EVALUATE expression\"",
-" (no variable), and the result was printed. Use SET EVAL { OLD, NEW }",
-" to choose the old or new behavior, which is NEW by default.",
-" ",
-"Alse see: HELP FUNCTION EVAL.",
-"" };
-#endif /* NOSPL */
-
-static char *hmxxexit[] = {
-"Syntax: EXIT (or QUIT) [ number [ text ] ]",
-" Exits from the Kermit program, closing all open files and devices.",
-" If a number is given it becomes Kermit's exit status code. If text is",
-" included, it is printed. Also see SET EXIT.",
-"" };
-
-#ifndef NOSPL
-static char *ifxhlp[] = { "\
-Syntax: XIF condition { commandlist } [ ELSE { commandlist } ]",
-" Obsolete. Same as IF (see HELP IF).",
-"" };
-
-static char *forhlp[] = { "\
-Syntax: FOR variablename initial-value final-value increment { commandlist }",
-" FOR loop. Execute the comma-separated commands in the commandlist the",
-" number of times given by the initial value, final value and increment.",
-" Example: FOR \\%i 10 1 -1 { pause 1, echo \\%i }", "" };
-
-static char *whihlp[] = { "\
-Syntax: WHILE condition { commandlist }",
-" WHILE loop. Execute the comma-separated commands in the bracketed",
-" commandlist while the condition is true. Conditions are the same as for",
-" IF commands.",
-"" };
-
-static char *swihlp[] = {
-"Syntax: SWITCH <variable> { case-list }",
-" Selects from a group of commands based on the value of a variable.",
-" The case-list is a series of lines like these:",
-" ",
-" :x, command, command, ..., break",
-" ",
-" where \"x\" is a possible value for the variable. At the end of the",
-" case-list, you can put a \"default\" label to catch when the variable does",
-" not match any of the labels:",
-" ",
-" :default, command, command, ...",
-" ",
-"The case label \"x\" can be a character, a string, a variable, a function",
-"invocation, a pattern, or any combination of these. See HELP WILDCARDS",
-"for information about patterns.",
-""};
-
-static char *openhlp[] = {
-"Syntax: OPEN mode filename",
-" For use with READ and WRITE commands. Open the local file in the",
-" specified mode: READ, WRITE, or APPEND. !READ and !WRITE mean to read",
-" from or write to a system command rather than a file. Examples:",
-" ",
-" OPEN READ oofa.txt",
-" OPEN !READ sort foo.bar",
-"" };
-
-static char *hxxask[] = {
-"Syntax: ASK [ switches ] variablename [ prompt ]",
-"Example: ASK \\%n { What is your name\\? }",
-" Issues the prompt and defines the variable to be whatever is typed in",
-" response, up to the terminating carriage return. Use braces to preserve",
-" leading and/or trailing spaces in the prompt.",
-" ",
-"Syntax: ASKQ [ switches ] variablename [ prompt ]",
-"Example: ASKQ \\%p { Password:}",
-" Like ASK except the response does not echo on the screen or, if specified",
-" it echoes as asterisks or other specified character.",
-" ",
-"Switches:",
-" /DEFAULT:text",
-" Text to supply if the user enters a blank response or the /TIMEOUT",
-" limit expired with no response.",
-" ",
-" /ECHO:char",
-" (ASKQ only) Character to be echoed each time the user presses a key",
-" corresponding to a printable character. This lets users see what they are",
-" doing when they are typing (e.g.) passwords, and makes editing easier.",
-" ",
-#ifdef OS2
-" /POPUP",
-" The prompt and response dialog takes place in a text-mode popup.",
-" K95 only; in C-Kermit this switch is ignored.",
-" ",
-#ifdef KUI
-" /GUI",
-" The prompt and response dialog takes place in a GUI popup.",
-" K95 GUI version only; in C-Kermit and the K95 console version,",
-" this switch is ignored.",
-" ",
-#endif /* KUI */
-#endif /* OS2 */
-" /TIMEOUT:number",
-" If the response is not entered within the given number of seconds, the",
-" command fails. This is equivalent to setting ASK-TIMER to a positive",
-" number, except it applies only to this command. Also see SET ASK-TIMER.",
-" NOTE: If a /DEFAULT: value was also given, it is supplied automatically",
-" upon timeout and the command does NOT fail.",
-
-" ",
-" /QUIET",
-" Suppresses \"?Timed out\" message when /TIMEOUT is given and user doesn't",
-" respond within the time limit.",
-""};
-static char *hxxgetc[] = {
-"Syntax: GETC variablename [ prompt ]",
-"Example: GETC \\%c { Type any character to continue...}",
-" Issues the prompt and sets the variable to the first character you type.",
-" Use braces to preserve leading and/or trailing spaces in the prompt.",
-" ",
-"Also see SET ASK-TIMER.",
-""};
-
-static char *hmxytimer[] = {
-"Syntax: SET ASK-TIMER number",
-" For use with ASK, ASKQ, GETOK, and GETC. If ASK-TIMER is set to a number",
-" greater than 0, these commands will time out after the given number of",
-" seconds with no response. This command is \"sticky\", so to revert to",
-" \
-untimed ASKs after a timed one, use SET ASK-TIMER 0. Also see IF ASKTIMEOUT.",
-""};
-
-static char *hxxdot[] = {
-"Syntax: .<variable-name> <assignment-operator> <value>",
-" Assigns the value to the variable in the manner indicated by the",
-" assignment operator:",
-" = Copies without evaluation (like DEFINE).",
-" := Copies with evaluation (like ASSIGN).",
-" ::= Copies with arithmetic evaluation (like EVALUATE).",
-""};
-
-static char *hxxdef[] = {
-"Syntax: DEFINE name [ definition ]",
-" Defines a macro or variable. Its value is the definition, taken",
-" literally. No expansion or evaluation of the definition is done. Thus",
-" if the definition includes any variable or function references, their",
-" names are included, rather than their values (compare with ASSIGN). If",
-" the definition is omitted, then the named variable or macro is undefined.",
-" ",
-"A typical macro definition looks like this:",
-" ",
-" DEFINE name command, command, command, ...",
-" ",
-"for example:",
-" ",
-" DEFINE vax set parity even, set duplex full, set flow xon/xoff",
-" ",
-"which defines a Kermit command macro called 'vax'. The definition is a",
-"comma-separated list of Kermit commands. Use the DO command to execute",
-"the macro, or just type its name, followed optionally by arguments.",
-" ",
-"The definition of a variable can be anything at all, for example:",
-" ",
-" DEFINE \\%a Monday",
-" DEFINE \\%b 3",
-" ",
-"These variables can be used almost anywhere, for example:",
-" ",
-" ECHO Today is \\%a",
-" SET BLOCK-CHECK \\%b",
-"" };
-
-static char *hxxass[] = {
-"Syntax: ASSIGN variablename string.",
-"Example: ASSIGN \\%a My name is \\%b.",
-" Assigns the current value of the string to the variable (or macro).",
-" The definition string is fully evaluated before it is assigned, so that",
-" the values of any variables that are contained are used, rather than their",
-" names. Compare with DEFINE. To illustrate the difference, try this:",
-" ",
-" DEFINE \\%a hello",
-" DEFINE \\%x \\%a",
-" ASSIGN \\%y \\%a",
-" DEFINE \\%a goodbye",
-" ECHO \\%x \\%y",
-" ",
-" This prints 'goodbye hello'.", "" };
-
-static char *hxxdec[] = {
-"Syntax: DECREMENT variablename [ number ]",
-" Decrement (subtract one from) the value of a variable if the current value",
-" is numeric. If the number argument is given, subtract that number",
-" instead.",
-" ",
-"Examples: DECR \\%a, DECR \\%a 7, DECR \\%a \\%n", "" };
-
-static char *hxxinc[] = {
-"Syntax: INCREMENT variablename [ number ]",
-" Increment (add one to) the value of a variable if the current value is",
-" numeric. If the number argument is given, add that number instead.",
-" ",
-"Examples: INCR \\%a, INCR \\%a 7, INCR \\%a \\%n", "" };
-#endif /* NOSPL */
-
-#ifdef ANYX25
-#ifndef IBMX25
-static char *hxxpad[] = {
-"Syntax: PAD command",
-"X.25 PAD commands:",
-" ",
-" PAD CLEAR - Clear the virtual call",
-" PAD STATUS - Return the status of virtual call",
-" PAD RESET - Send a reset packet",
-" PAD INTERRUPT - Send an interrupt packet",
-""};
-#endif /* IBMX25 */
-
-static char *hxyx25[] = {
-"Syntax: SET X.25 option { ON [ data ], OFF }",
-" ",
-"X.25 call options:",
-" CLOSED-USER-GROUP { ON index, OFF }",
-" Enable or disable closed user group call, where index is the group",
-" index, 0 to 99.",
-" REVERSE-CHARGE { ON, OFF }",
-" Tell whether you want to reverse the charges for the call.",
-" CALL-USER-DATA { ON string, OFF }",
-" Specify call user-data for the X.25 call.",
-""};
-#endif /* ANYX25 */
-
-static char *hxyprtr[] = {
-#ifdef PRINTSWI
-"Syntax: SET PRINTER [ switches ] [ name ]",
-" ",
-" Specifies the printer to be used for transparent-print, autoprint, and",
-" screen-dump material during terminal emulation, as well as for the PRINT",
-" command, plus various options governing print behavior.",
-" ",
-"Switches for specifying the printer by type:",
-" ",
-"/NONE",
-" Include this switch to specify that all printer actions should simply be",
-" skipped. Use this, for example, if you have no printer.",
-" ",
-"/DOS-DEVICE[:name]",
-" Include this to declare a DOS printer and to specify its name, such as",
-" PRN, LPT1, etc.",
-" ",
-#ifdef NT
-"/WINDOWS-QUEUE[:[queue-name]]",
-" Include this to declare a Windows printer and specify its queue name.",
-" Type question mark (?) after the colon (:) to see a list of known queue",
-" names. If the colon is absent, the switch indicates the currently",
-" selected printer is a Windows Print Queue. If the colon is provided",
-" and the name is absent, the Windows Print Queue chosen as the Default",
-" Printer is selected.",
-" ",
-#endif /* NT */
-"/FILE[:name]",
-" Specifies that all printer material is to be appended to the named file,",
-" rather than being sent to a printer. If the file does not exist, it is",
-" created the first time any material is to be printed.",
-" ",
-"/PIPE[:name]",
-" Specifies that all printer material is to be sent as standard input to",
-" the program or command whose name is given. Example:",
-" ",
-" SET PRINTER /PIPE:{textps > lpt1}",
-" ",
-"If you give a printer name without specifying any of these switches, then it",
-"is assumed to be a DOS printer device or filename unless the name given",
-"(after removing enclosing braces, if any) starts with \"|\", \
-in which case it",
-"is a pipe. Examples:",
-" ",
-" SET PRINTER LPT1 <-- DOS device",
-" SET PRINTER {| textps > lpt1} <-- Pipe",
-" ",
-"The next group of switches tells whether the printer is one-way or",
-"bidirectional (two-way):",
-" ",
-"/OUTPUT-ONLY",
-" Include this to declare the printer capable only of receiving material to",
-" be printed, but not sending anything back. This is the normal kind of",
-" printer, Kermit's default kind, and the opposite of /BIDIRECTIONAL.",
-" ",
-"/BIDIRECTIONAL",
-" Include this to declare the printer bidirectional. This is the opposite ",
-" of /OUTPUT-ONLY. You can also use this option with serial printers, even",
-" if they aren't bidirectional, in case you need to specify speed, flow",
-" control, or parity.",
-" ",
-"The next group applies only to bidirectional and/or serial printers:",
-" ",
-"/FLOW-CONTROL:{NONE,XON/XOFF,RTS/CTS,KEEP}",
-" Flow control to use with a serial bidirectional printer, default KEEP;",
-#ifdef NT
-" i.e. use whatever the Windows driver for the port normally uses.",
-#else
-" i.e. use whatever the OS/2 driver for the port normally uses.",
-#endif /* NT */
-" ",
-"/PARITY:{NONE,EVEN,ODD,SPACE,MARK}",
-" Parity to use with a serial printer, default NONE; i.e. use 8 data bits",
-" and no parity. If you omit the colon and the keyword, NONE is selected.",
-" ",
-"/SPEED:number",
-" Interface speed, in bits per second, to use with a serial printer, such as",
-" 2400, 9600, 19200, etc. Type SET PRINTER /SPEED:? for a list of possible",
-" speeds.",
-" ",
-"The next group deals with print jobs -- how to identify them, how to start",
-"them, how to terminate them:",
-" ",
-"/TIMEOUT[:number]",
-" Used with host-directed transparent or auto printing, this is the number",
-" of seconds to wait after the host closes the printer before terminating",
-" the print job if the printer is not opened again during the specified",
-" amount of time.",
-" ",
-"/JOB-HEADER-FILE[:filename]",
-" The name of a file to be sent to the printer at the beginning of each",
-" print job, as a burst page, or to configure the printer. Normally no file",
-" is is sent.",
-" ",
-"/END-OF-JOB-STRING[:string]",
-" String of characters to be sent to the printer at the end of the print",
-" job, usually used to force the last or only page out of the printer. When",
-" such a string is needed, it usually consists of a single formfeed: \"set",
-" printer /end-of-job:{\\12}\". No end-of-job string is sent unless you",
-" specify one with this option. If the string contains any spaces or",
-" control characters (even in backslash notation, as above), enclose it in",
-" braces.",
-" ",
-"The next group is for use with printers that print only PostScript:",
-" ",
-"/POSTSCRIPT or /PS",
-" Indicates that K95 should convert all text to PostScript before sending",
-" it to the printer. The fixed-pitch Courier-11 font is used.",
-" ",
-"/WIDTH:number",
-" Specifies the width of the page in characters. If this switch is not",
-" given, 80 is used.",
-" ",
-"/HEIGHT:number",
-" Specifies the height of the page in lines. If this switch is not given",
-" 66 is used.",
-" ",
-"/NOPOSTSCRIPT or /NOPS",
-" Indicates that K95 should not convert all text to PostScript before",
-" sending it to the printer.",
-" ",
-"The final switch is for use with AutoPrint mode and Screen Dumps",
-" ",
-"/CHARACTER-SET:<character-set>",
-" Specifies the character set used by the printer which may be different",
-" from both the character set used by the host and by the local computer.",
-" The default value is CP437.",
-" ",
-"SHOW PRINTER displays your current printer settings.",
-#else
-#ifdef UNIX
-"Syntax: SET PRINTER [ { |command, filename } ]",
-" Specifies the command (such as \"|lpr\") or filename to be used by the",
-" PRINT command. If a filename is given, each PRINT command appends to the",
-" given file. If the SET PRINTER argument contains spaces, it must be",
-" enclosed in braces, e.g. \"set printer {| lpr -Plaser}\". If the argument",
-" is omitted the default value is restored. SHOW PRINTER lists the current",
-" printer. See HELP PRINT for further info.",
-#else
-"Sorry, SET PRINTER not available yet.",
-#endif /* UNIX */
-#endif /* PRINTSWI */
-""};
-
-#ifdef OS2
-#ifdef BPRINT
-static char *hxybprtr[] = {
-"Syntax: SET BPRINTER [ portname speed [ parity [ flow-control ] ] ]",
-" (Obsolete, replaced by SET PRINTER /BIDIRECTIONAL.)",
-""};
-#endif /* BPRINT */
-#endif /* OS2 */
-
-static char *hxyexit[] = {
-"Syntax: SET EXIT HANGUP { ON, OFF }",
-" When ON (which is the default), C-Kermit executes an implicit HANGUP and",
-" CLOSE command on the communications device or connection when it exits.",
-" When OFF, Kermit skips this sequence.",
-" ",
-"Syntax: SET EXIT ON-DISCONNECT { ON, OFF }",
-" When ON, C-Kermit EXITs automatically when a network connection",
-" is terminated either by the host or by issuing a HANGUP command.",
-" ",
-"Syntax: SET EXIT STATUS number",
-#ifdef NOSPL
-" Set C-Kermit's program return code to the given number.",
-#else
-" Set C-Kermit's program return code to the given number, which can be a",
-" constant, variable, function result, or arithmetic expression.",
-#endif /* NOSPL */
-" ",
-"Syntax: SET EXIT WARNING { ON, OFF, ALWAYS }",
-" When EXIT WARNING is ON, issue a warning message and ask for confirmation",
-" before EXITing if a connection to another computer might still be open.",
-" When EXIT WARNING is ALWAYS, confirmation is always requested. When OFF",
-" it is never requested. The default is ON.",
-"" };
-
-#ifndef NOSPL
-static char *hxxpau[] = {
-"Syntax: PAUSE [ { number-of-seconds, hh:mm:ss } ]",
-"Example: PAUSE 3 or PAUSE 14:52:30",
-" Do nothing for the specified number of seconds or until the given time of",
-" day in 24-hour hh:mm:ss notation. If the time of day is earlier than the",
-" current time, it is assumed to be tomorrow. If no argument given, one",
-" second is used. The pause can be interrupted by typing any character on",
-" the keyboard unless SLEEP CANCELLATION is OFF. If interrupted, PAUSE",
-" fails, otherwise it succeeds. Synonym: SLEEP.",
-"" };
-
-static char *hxxmsl[] = {
-"Syntax: MSLEEP [ number ]",
-"Example: MSLEEP 500",
-" Do nothing for the specified number of milliseconds; if no number given,",
-" 100 milliseconds.","" };
-#endif /* NOSPL */
-
-#ifndef NOPUSH
-extern int nopush;
-static char *hxxshe[] = {
-"Syntax: !, @, RUN, PUSH, or SPAWN, optionally followed by a command.",
-" Gives the command to the local operating system's command processor, and",
-" displays the results on the screen. If the command is omitted, enters the",
-" system's command line interpreter or shell; exit from it (the command for",
-" this is usually EXIT or QUIT or LOGOUT) to return to Kermit.",
-""
-};
-#endif /* NOPUSH */
-
-#ifndef NOXMIT
-static char *hxxxmit[] = {
-"Syntax: TRANSMIT [ switches ] filename",
-" Sends the contents of a file, without any error checking or correction,",
-" to the computer on the other end of your SET LINE or SET HOST connection",
-" (or if C-Kermit is in remote mode, displays it on the screen). The",
-" filename is the name of a single file (no wildcards) to be sent or, if",
-" the /PIPE switch is included, the name of a command whose output is to be",
-" sent.",
-" ",
-" The file is sent according to your current FILE TYPE setting (BINARY or",
-" TEXT), which you can override with a /BINARY or /TEXT switch without",
-" changing the global setting. In text mode, it is sent a line at a time,",
-" with carriage return at the end of each line (as if you were typing it at",
-" your keyboard), and C-Kermit waits for a linefeed to echo before sending",
-" the next line; use /NOWAIT to eliminate the feedback requirement. In",
-" binary mode, it is sent a character at a time, with no feedback required.",
-" ",
-" Normally the transmitted material is echoed to your screen. Use SET",
-" TRANSMIT ECHO OFF or the /NOECHO switch to suppress echoing. Note that",
-" TRANSMIT /NOECHO /NOWAIT /BINARY is a special case, that more or less",
-" blasts the file out at full speed.",
-" ",
-#ifndef NOCSETS
-" Character sets are translated according to your current FILE and TERMINAL",
-" CHARACTER-SET settings when TRANSMIT is in text mode. Include /TRANSPARENT"
-,
-" to disable character-set translation in text mode (/TRANSPARENT implies",
-" /TEXT).",
-" ",
-#endif /* NOCSETS */
-" There can be no guarantee that the other computer will receive the file",
-" correctly and completely. Before you start the TRANSMIT command, you",
-" must put the other computer in data collection mode, for example by",
-" starting a text editor. TRANSMIT may be interrupted by Ctrl-C. Synonym:",
-" XMIT. See HELP SET TRANSMIT for further information.",
-"" };
-#endif /* NOXMIT */
-
-#ifndef NOCSETS
-static char *hxxxla[] = {
-"Syntax: TRANSLATE file1 cs1 cs2 [ file2 ]",
-" Translates file1 from the character set cs1 into the character set cs2",
-" and stores the result in file2. The character sets can be any of",
-" C-Kermit's file character sets. If file2 is omitted, the translation",
-" is displayed on the screen. An appropriate intermediate character-set",
-" is chosen automatically, if necessary. Synonym: XLATE. Example:",
-" ",
-" TRANSLATE lasagna.lat latin1 italian lasagna.nrc",
-" ",
-" Multiple files can be translated if file2 is a directory or device name,",
-" rather than a filename, or if file2 is omitted.",
-"" };
-#endif /* NOCSETS */
-
-#ifndef NOSPL
-static char *hxxwai[] = {
-"Syntax: WAIT { number-of-seconds, hh:mm:ss } [ <what> ]",
-" ",
-"Examples:",
-" wait 5 cd cts",
-" wait 23:59:59 cd",
-" ",
-" Waits up to the given number of seconds or the given time of day for the",
-" specified item or event, which can be FILE, the name(s) of one or more",
-" modem signals, or nothing. If nothing is specified, WAIT acts like SLEEP.",
-" If one or more modem signal names are given, Kermit waits for the specified"
-,
-" modem signals to appear on the serial communication device.",
-" Sets FAILURE if the signals do not appear in the given time or interrupted",
-" from the keyboard during the waiting period.",
-" ",
-"Signals:",
-" cd = Carrier Detect;",
-" dsr = Dataset Ready;",
-" cts = Clear To Send;",
-" ri = Ring Indicate.",
-" ",
-"If you want Kermit to wait for a file event, then the syntax is:",
-" ",
-" WAIT <time> FILE { CREATION, DELETION, MODIFICATION } <filename>",
-" ",
-"where <time> is as above, and <filename> is the name of a single file.",
-"Kermit waits up to the given amount of time for the specified event to occur",
-"with the specified file, succeeds if it does, fails if it doesn't.",
-"" };
-#endif /* NOSPL */
-
-static char *hxxwri[] = {
-"Syntax: WRITE name text",
-" Writes the given text to the named log or file. The text text may include",
-" backslash codes, and is not terminated by a newline unless you include the",
-" appropriate code. The name parameter can be any of the following:",
-" ",
-" DEBUG-LOG",
-" ERROR (standard error)",
-#ifndef NOSPL
-" FILE (the OPEN WRITE, OPEN !WRITE, or OPEN APPEND file, see HELP OPEN)",
-#endif /* NOSPL */
-" PACKET-LOG",
-" SCREEN (compare with ECHO)",
-#ifndef NOLOCAL
-" SESSION-LOG",
-#endif /* NOLOCAL */
-" TRANSACTION-LOG", "" };
-
-#ifndef NODIAL
-static char *hxxlook[] = { "Syntax: LOOKUP name",
-" Looks up the given name in the dialing directory or directories, if any,",
-" specified in the most recent SET DIAL DIRECTORY command. Each matching",
-" entry is shown, along with any transformations that would be applied to",
-" portable-format entries based on your locale. HELP DIAL, HELP SET DIAL",
-" for further info.",
-""
-};
-
-static char *hxxansw[] = { "Syntax: ANSWER [ <seconds> ]",
-#ifdef OS2
-" Waits for a modem call to come in. Prior SET MODEM TYPE and SET PORT",
-#else
-" Waits for a modem call to come in. Prior SET MODEM TYPE and SET LINE",
-#endif /* OS2 */
-" required. If <seconds> is 0 or not specified, Kermit waits forever or",
-" until interrupted, otherwise Kermit waits the given number of seconds.",
-" The ANSWER command puts the modem in autoanswer mode. Subsequent DIAL",
-" commands will automatically put it (back) in originate mode. SHOW MODEM,",
-" HELP SET MODEM for more info.",
-""
-};
-
-static char *hxxdial[] = { "Syntax: DIAL phonenumber",
-"Example: DIAL 7654321",
-" \
-Dials a number using an autodial modem. First you must SET MODEM TYPE, then",
-#ifdef OS2
-" SET PORT (or in Windows only, SET PORT TAPI instead of SET MODEM TYPE and",
-" SET LINE), then SET SPEED. Then give the DIAL command, including the phone",
-#else
-" SET LINE, then SET SPEED. Then give the DIAL command, including the phone",
-#endif /* OS2 */
-" number, for example:",
-" ",
-" DIAL 7654321",
-#ifdef NETCONN
-" ",
-" If the modem is on a network modem server, SET HOST first, then SET MODEM",
-" TYPE, then DIAL.",
-#endif /* NETCONN */
-" ",
-"If you give the DIAL command interactively at the Kermit prompt, and the",
-"call is placed successfully, Kermit automatically enters CONNECT mode.",
-"If the DIAL command is given from a macro or command file, Kermit remains",
-"in command mode after the call is placed, successfully or not. You can",
-"change this behavior with the SET DIAL CONNECT command.",
-" ",
-"If the phonenumber starts with a letter, and if you have used the SET DIAL",
-"DIRECTORY command to specify one or more dialing-directory files, Kermit",
-"looks it up in the given file(s); if it is found, the name is replaced by",
-"the number or numbers associated with the name. If it is not found, the",
-"name is sent to the modem literally.",
-" ",
-"If the phonenumber starts with an equals sign (\"=\"), this forces the part",
-"after the = to be sent literally to the modem, even if it starts with a",
-"letter, without any directory lookup.",
-" ",
-"You can also give a list of phone numbers enclosed in braces, e.g:",
-" ",
-" dial {{7654321}{8765432}{+1 (212 555-1212}}",
-" ",
-"(Each number is enclosed in braces and the entire list is also enclosed in",
-"braces.) In this case, each number is tried until there is an answer. The",
-"phone numbers in this kind of list can not be names of dialing directory",
-"entries.",
-" ",
-"A dialing directory is a plain text file, one entry per line:",
-" ",
-" name phonenumber ; comments",
-" ",
-"for example:",
-" ",
-" work 9876543 ; This is a comment",
-" e-mail +1 (212) 555 4321 ; My electronic mailbox",
-" germany +49 (511) 555 1234 ; Our branch in Hanover",
-" ",
-"If a phone number starts with +, then it must include country code and",
-"area code, and C-Kermit will try to handle these appropriately based on",
-"the current locale (HELP SET DIAL for further info); these are called",
-"PORTABLE entries. If it does not start with +, it is dialed literally.",
-" ",
-"If more than one entry is found with the same name, Kermit dials all of",
-"them until the call is completed; if the entries are in portable format,",
-"Kermit dials them in cheap-to-expensive order: internal, then local, then",
-"long-distance, then international, based on its knowledge of your local",
-"country code and area code (see HELP SET DIAL).",
-" ",
-"Specify your dialing directory file(s) with the SET DIAL DIRECTORY command.",
-" ",
-#ifdef NETCONN
-"See also SET DIAL, SET MODEM, SET LINE, SET HOST, SET SPEED, REDIAL, and",
-"PDIAL.",
-#else
-"See also SET DIAL, SET MODEM, SET LINE, SET SPEED, PDIAL, and REDIAL.",
-#endif /* NETCONN */
-"" };
-
-#ifdef CK_TAPI
-static char *hxxtapi[] = {
-"TAPI CONFIGURE-LINE <tapi-line>",
-" Displays the TAPI Configure Line Dialog box and allows you to",
-" alter the default configuration for the specified <tapi-line>.",
-" ",
-"TAPI DIALING-PROPERTIES",
-" Displays the TAPI Dialing Properties (locations) Dialog box. The",
-" Dialing rules may be changed and locations created and deleted.",
-" When the dialog box is closed, K-95 imports the current Dialing",
-" Properties' Location into the Kermit DIAL command settings.",
-""};
-
-static char *hxytapi[] = {
-"SET TAPI LINE <tapi-line>",
-" Opens a TAPI device for use by Kermit.",
-" ",
-"SET TAPI MODEM-DIALING {ON, [OFF]}",
-" If TAPI MODEM-DIALING is OFF when SET TAPI LINE is issued, Kermit opens",
-" the TAPI device directly as a \"raw port\". The device is unavailable to",
-" other applications and Kermit performs dialing functions using its",
-" built-in dialing and modem databases. If TAPI MODEM-DIALING is ON, TAPI",
-" handles all dialing functions and the port may be shared with other",
-" applications when a call is not active. When TAPI MODEM-DIALING is OFF,",
-" SET MODEM TYPE TAPI Kermit uses the TAPI modem commands imported from the",
-" Windows Registry during the previous SET TAPI LINE call.",
-" ",
-"SET TAPI LOCATION <tapi-location>",
-" Specifies the TAPI location to make current for the entire system. The",
-" <tapi-location>'s dialing properties are imported into Kermit's SET DIAL",
-" command database.",
-" ",
-"SET TAPI PHONE-NUMBER-CONVERSIONS {ON, OFF, [AUTO]}",
-" Controls whether the phone number conversions are performed by TAPI (ON)",
-" or by Kermit (OFF), or according the type of port that was selected",
-" (AUTO); AUTO is the default, and is equivalent to ON if the current",
-" LINE/PORT is a TAPI device and TAPI MODEM-DIALING is ON, OFF otherwise.",
-" ",
-"SET TAPI MODEM-LIGHTS {[ON], OFF}",
-" Displays a modem lights indicator on the Windows 95 Taskbar. Does nothing",
-" in Windows NT 4.0.",
-" ",
-"SET TAPI MANUAL-DIALING {ON, [OFF]}",
-" Displays a dialog box during dialing requesting that you manually dial the",
-" phone before continuing. Applies only when TAPI MODEM-DIALING is ON.",
-" ",
-"SET TAPI WAIT-FOR-CREDIT-CARD-TONE <seconds>",
-" Some modems don't support the '$' (BONG) symbol during dialing, which",
-" means \"wait for credit card tone before continuing.\" If TAPI recognizes",
-" the modem as one that does not support BONG, it replaces the '$' with",
-" <seconds> worth of pauses. The default is 8 seconds. This command",
-" applies only when TAPI MODEM-DIALING is ON",
-" ",
-"SET TAPI PRE-DIAL-TERMINAL {ON, [OFF]}",
-"SET TAPI POST-DIAL-TERMINAL {ON, [OFF]}",
-" Displays a small terminal window that may be used to communicate with the",
-" modem or the host prior to or immediately after dialing; applies only when",
-" TAPI MODEM-DIALING is ON",
-" ",
-"SET TAPI INACTIVITY-TIMEOUT <minutes>",
-" Specifies the number of minutes of inactivity that may go by before TAPI",
-" disconnects the line. The default is 0 which means disable this function.",
-" Applies only when TAPI MODEM-DIALING is ON.",
-" ",
-"SET TAPI USE-WINDOWS-CONFIGURATION {ON, [OFF]}",
-" Specifies whether the TAPI modem values for speed, parity, stop bits, flow",
-" control, etc. are used in preference to the current values specified",
-" within Kermit-95.",
-" ",
-""};
-#endif /* CK_TAPI */
-
-#endif /* NODIAL */
-
-#ifdef TNCODE
-static char *hmxxiks[] = {
-"Syntax: IKS [ switches ] [ host [ service ] ]",
-" Establishes a new connection to an Internet Kermit Service daemon.",
-" Equivalent to SET NETWORK TYPE TCP/IP, SET HOST host KERMIT /TELNET,",
-" IF SUCCESS CONNECT. If host is omitted, the previous connection (if any)",
-" is resumed. Depending on how Kermit has been built switches may be",
-" available to require a secure authentication method and bidirectional",
-" encryption. See HELP SET TELNET for more info.",
-" ",
-#ifdef CK_AUTHENTICATION
-" /AUTH:<type> is equivalent to SET TELNET AUTH TYPE <type> and",
-" SET TELOPT AUTH REQUIRED with the following exceptions. If the type",
-" is AUTO, then SET TELOPT AUTH REQUESTED is executed and if the type",
-" is NONE, then SET TELOPT AUTH REFUSED is executed.",
-" ",
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
-" /ENCRYPT:<type> is equivalent to SET TELNET ENCRYPT TYPE <type>",
-" and SET TELOPT ENCRYPT REQUIRED REQUIRED with the following exceptions.",
-" If the type is AUTO then SET TELOPT AUTH REQUESTED REQUESTED is executed",
-" and if the type is NONE then SET TELOPT ENCRYPT REFUSED REFUSED is",
-" executed.",
-" ",
-#endif /* CK_ENCRYPTION */
-" /USERID:[<name>]",
-" This switch is equivalent to SET LOGIN USERID <name> or SET TELNET",
-" ENVIRONMENT USER <name>. If a string is given, it sent to host during",
-" Telnet negotiations; if this switch is given but the string is omitted,",
-" no user ID is sent to the host. If this switch is not given, your",
-" current USERID value, \\v(userid), is sent. When a userid is sent to the",
-" host it is a request to login as the specified user.",
-" ",
-#ifdef CK_AUTHENTICATION
-" /PASSWORD:[<string>]",
-" This switch is equivalent to SET LOGIN PASSWORD. If a string is given,",
-" it is treated as the password to be used (if required) by any Telnet",
-" Authentication protocol (Kerberos Ticket retrieval, Secure Remote",
-" Password, or X.509 certificate private key decryption.) If no password",
-" switch is specified a prompt is issued to request the password if one",
-" is required for the negotiated authentication method.",
-#endif /* CK_AUTHENTICATION */
-""};
-
-static char *hmxxtel[] = {
-"Syntax: TELNET [ switches ] [ host [ service ] ]",
-" Equivalent to SET NETWORK TYPE TCP/IP, SET HOST host [ service ] /TELNET,",
-" IF SUCCESS CONNECT. If host is omitted, the previous connection (if any)",
-" is resumed. Depending on how Kermit has been built switches may be",
-" available to require a secure authentication method and bidirectional",
-" encryption. See HELP SET TELNET for more info.",
-" ",
-#ifdef CK_AUTHENTICATION
-" /AUTH:<type> is equivalent to SET TELNET AUTH TYPE <type> and",
-" SET TELOPT AUTH REQUIRED with the following exceptions. If the type",
-" is AUTO, then SET TELOPT AUTH REQUESTED is executed and if the type",
-" is NONE, then SET TELOPT AUTH REFUSED is executed.",
-" ",
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
-" /ENCRYPT:<type> is equivalent to SET TELNET ENCRYPT TYPE <type>",
-" and SET TELOPT ENCRYPT REQUIRED REQUIRED with the following exceptions.",
-" If the type is AUTO then SET TELOPT AUTH REQUESTED REQUESTED is executed",
-" and if the type is NONE then SET TELOPT ENCRYPT REFUSED REFUSED is",
-" executed.",
-" ",
-#endif /* CK_ENCRYPTION */
-" /USERID:[<name>]",
-" This switch is equivalent to SET LOGIN USERID <name> or SET TELNET",
-" ENVIRONMENT USER <name>. If a string is given, it sent to host during",
-" Telnet negotiations; if this switch is given but the string is omitted,",
-" no user ID is sent to the host. If this switch is not given, your",
-" current USERID value, \\v(userid), is sent. When a userid is sent to the",
-" host it is a request to login as the specified user.",
-" ",
-#ifdef CK_AUTHENTICATION
-" /PASSWORD:[<string>]",
-" This switch is equivalent to SET LOGIN PASSWORD. If a string is given,",
-" it is treated as the password to be used (if required) by any Telnet",
-" Authentication protocol (Kerberos Ticket retrieval, Secure Remote",
-" Password, or X.509 certificate private key decryption.) If no password",
-" switch is specified a prompt is issued to request the password if one",
-" is required for the negotiated authentication method.",
-#endif /* CK_AUTHENTICATION */
-""};
-
-static char *hxtopt[] = {
-"TELOPT { AO, AYT, BREAK, CANCEL, EC, EL, EOF, EOR, GA, IP, DMARK, NOP, SE,",
-" SUSP, SB [ option ], DO [ option ], DONT [ option ],",
-" WILL [ option ], WONT [option] }",
-" This command lets you send all the Telnet protocol commands. Note that",
-" certain commands do not require a response, and therefore can be used as",
-" nondestructive \"probes\" to see if the Telnet session is still open;",
-" e.g.:",
-" ",
-" set host xyzcorp.com",
-" ...",
-" telopt nop",
-" telopt nop",
-" if fail stop 1 Connection lost",
-" ",
-" TELOPT NOP is sent twice because the failure of the connection will not",
-" be detected until the second send is attempted. This command is meant",
-" primarily as a debugging tool for the expert user.",
-""};
-#endif /* TNCODE */
-
-#endif /* NOHELP */
-
-/* D O H L P -- Give a help message */
-
-_PROTOTYP( int dohset, (int) );
-#ifndef NOCMDL
-_PROTOTYP( int dohopts, (void) );
-#endif /* NOCMDL */
-#ifndef NOSPL
-_PROTOTYP( int dohfunc, (int) );
-extern struct keytab fnctab[];
-extern int nfuncs;
-#endif /* NOSPL */
-#ifdef OS2
-#ifndef NOKVERBS
-_PROTOTYP( int dohkverb, (int) );
-extern struct keytab kverbs[];
-extern int nkverbs;
-#endif /* NOKVERBS */
-#endif /* OS2 */
-
-#ifndef NOSPL
-static char * hxxdcl[] = {
-"Syntax: ARRAY verb operands...",
-" ",
-"Declares arrays and performs various operations on them. Arrays have",
-"the following syntax:",
-" ",
-" \\&a[n]",
-" ",
-"where \"a\" is a letter and n is a number or a variable with a numeric value",
-"or an arithmetic expression. The value of an array element can be anything",
-"at all -- a number, a character, a string, a filename, etc.",
-" ",
-"The following ARRAY verbs are available:",
-" ",
-"[ ARRAY ] DECLARE arrayname[n] [ = initializers... ]",
-" Declares an array of the given size, n. The resulting array has n+1",
-" elements, 0 through n. Array elements can be used just like any other",
-" variables. Initial values can be given for elements 1, 2, ... by",
-" including = followed by one or more values separated by spaces. If you",
-" omit the size, the array is sized according to the number of initializers;",
-" if none are given the array is destroyed and undeclared if it already",
-" existed. The ARRAY keyword is optional. Synonym: [ ARRAY ] DCL.",
-" ",
-"[ ARRAY ] UNDECLARE arrayname",
-" Destroys and undeclares the given array. Synonym: ARRAY DESTROY.",
-" ",
-"ARRAY SHOW [ arrayname ]",
-" Displays the contents of the given array. A range specifier can be",
-" included to display a segment of the array, e.g. \"array show \\&a[1:24].\""
-,
-" If the arrayname is omitted, all declared arrays are listed, but their",
-" contents is not shown. Synonym: SHOW ARRAY.",
-" ",
-"ARRAY CLEAR arrayname",
-" Clears all elements of the array, i.e. sets them to empty values.",
-" You may include a range specifier to clear a segment of the array rather",
-" than the whole array, e.g. \"array clear \\%a[22:38]\"",
-" ",
-"ARRAY SET arrayname value",
-" Sets all elements of the array to the given value. You may specify a",
-" range to set a segment of the array, e.g. \"array set \\%a[2:9] 0\"",
-" ",
-"ARRAY RESIZE arrayname number",
-" Changes the size of the given array, which must already exist, to the",
-" number given. If the number is smaller than the current size, the extra",
-" elements are discarded; if it is larger, new empty elements are added.",
-" ",
-"ARRAY COPY array1 array2",
-" Copies array1 to array2. If array2 has not been declared, it is created",
-" automatically. Range specifiers may be given on one or both arrays.",
-" ",
-"ARRAY LINK array1 arra2",
-" Makes array1 a link to array2.",
-" ",
-"[ ARRAY ] SORT [ switches ] array-name [ array2 ]",
-" Sorts the given array lexically according to the switches. Element 0 of",
-" the array is excluded from sorting by default. The ARRAY keyword is",
-" optional. If a second array name is given, that array is sorted according",
-" to the first one. Switches:",
-" ",
-" /CASE:{ON,OFF}",
-" If ON, alphabetic case matters; if OFF it is ignored. If this switch is",
-" omitted, the current SET CASE setting applies.",
-" ",
-" /KEY:number",
-" \
-Position (1-based column number) at which comparisons begin, 1 by default.",
-" ",
-" /NUMERIC",
-" Specifies a numeric rather than lexical sort.",
-" ",
-" /RANGE:low[:high]",
-" The range of elements, low through high, to be sorted. If this switch",
-" is not given, elements 1 through the dimensioned size are sorted. If",
-" :high is omitted, the dimensioned size is used. To include element 0 in",
-" a sort, use /RANGE:0 (to sort the whole array) or /RANGE:0:n (to sort",
-" elements 0 through n). You can use a range specifier in the array name",
-" instead of the /RANGE switch.",
-" ",
-" /REVERSE",
-" Sort in reverse order. If this switch is not given, the array is sorted",
-" in ascending order.",
-" ",
-"Various functions are available for array operations; see HELP FUNCTION for",
-"details. These include \\fdimension(), \\farraylook(), \\ffiles(), \
-\\fsplit(),",
-"and many more.",
-""};
-#endif /* NOSPL */
-
-#ifdef ZCOPY
-static char * hmxxcpy[] = {
-"Syntax: COPY [ switches ] file1 file2",
-" Copies the source file (file1) to the destination file (file2). If file2",
-" is a directory, file1 can contain wildcards to denote a group of files to",
-" be copied to the given directory. Switches:",
-" ",
-" /LIST",
-" Print the filenames and status while copying. Synonyms: /LOG, /VERBOSE.",
-" ",
-" /NOLIST",
-" Copy silently (default). Synonyms: /NOLOG, /QUIET.",
-" ",
-" /PRESERVE",
-" Copy timestamp and permissions from source file to destination file.",
-" ",
-" /OVERWRITE:{ALWAYS,NEVER,NEWER,OLDER}",
-" When copying from one directory to another, this tells what to do when",
-" the destination file already exists: overwrite it always; never; only if",
-" the source file is newer; or only if the source file is older.",
-" ",
-" /APPEND",
-" Append the source file to the destination file. In this case the source",
-" file specification can contain wildcards, and all the matching source",
-" files are appended, one after the other in alphabetical order by name,",
-" to the destination file.",
-" ",
-" /SWAP-BYTES",
-" Swap bytes while copying (e.g. for converting between Big-Endian and",
-" Little-Endian binary data formats).",
-#ifndef NOSPL
-" ",
-" /FROMB64",
-" Convert from Base64 encoding while copying.",
-" ",
-" /TOB64",
-" Convert to Base64 encoding while copying.",
-#endif /* NOSPL */
-""
-};
-#endif /* ZCOPY */
-
-#ifndef NOFRILLS
-static char * hmxxren[] = {
-#ifdef LOCUS
-" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,",
-" this command is equivalent to REMOTE RENAME (RREN). Otherwise:",
-" ",
-#endif /* LOCUS */
-"Syntax: RENAME [ switches ] name1 [ name2 ]",
-" Renames the source file (name1) to the target name2. If name2 is a",
-" directory, name1 is allowed to contain wildcards, and the file(s) matching",
-" name1 are moved to directory name2, subject to rules of the underlying",
-" operating system regarding renaming across disk boundaries, etc. Switches:",
-" ",
-" /LIST",
-" Print the filenames and status while renaming. Synonyms: /LOG, /VERBOSE",
-" ",
-" /NOLIST",
-" Rename silently (default). Synonyms: /NOLOG, /QUIET",
-" ",
-" /COLLISION:{FAIL,SKIP,OVERWRITE}",
-" Tells what to do if a file with the given (or derived) new name already",
-" exists: fail (and stop without renaming any files); skip this file",
-" without renaming it and go on to the next one, if any; or overwrite (the",
-" existing file). PROCEED is a synonym for SKIP.",
-" ",
-" /SIMULATE",
-" Show what the effects of the RENAME command would be without actually",
-" renaming any files.",
-" ",
-" When any of the following switches is given, name2 must either be the",
-" the name of a directory, or else omitted, and name1 is allowed to contain",
-" contain wildcards, allowing multiple files to be renamed at once. If name2",
-" is given, then all files matching name1 are moved to the name2 directory",
-" after being renamed.",
-" ",
-" /LOWER:{ALL,UPPER}",
-" Converts letters in the filename to lowercase. ALL means to convert",
-" all matching filenames, UPPER means to convert only those filenames",
-" that contain no lowercase letters. The switch argument can be omitted,",
-" in which case ALL filenames are converted.",
-" ",
-" /UPPER:{ALL,LOWER}",
-" Converts letters in the filename to uppercase. ALL means to convert",
-" all matching filenames, LOWER means to convert only those filenames",
-" that contain no uppercase letters. As with /LOWER, ALL is the default",
-" switch argument.",
-" ",
-" /FIXSPACES:s",
-" Replaces all spaces in each matching filename by the string s, which may",
-" be empty, a single character, or a string of characters. The default",
-" replacement (if no argument is given) is underscore (_).",
-" ",
-" /REPLACE:{{string1}{string2}{options}}",
-" Replaces all or selected occurrences of string1 with string2 in the",
-" matching filenames. The braces are part of the command. The options",
-" string can contain the following characters:",
-" A: String matching is case-sensitive.",
-" a: String matching is case-insensitive.",
-" ^: String matching is anchored to the beginning of the filename.",
-" $: String matching is anchored to the end of the filename.",
-" 1: Only the first occurrence of the string (if any) will be changed.",
-" 2: Only the second occurrence, and so on for all digits up to 9.",
-" -: (before a digit) Occurrences are counted from the right.",
-" ~: (before occurrence) All occurences BUT the one given are changed.",
-" ",
-" /CONVERT:cset1:cset1",
-" Converts each matching filename from character-set 1 to character-set 2.",
-" Character sets are the same as for SET FILE CHARACTER-SET.",
-" ",
-" Global values for /LIST and COLLISION can be set with SET RENAME and",
-" displayed with SHOW RENAME.",
-""
-};
-#endif /* NOFRILLS */
-
-static char *
-cmdlhlp[] = {
-"Command-line options are given after the program name in the system",
-"command that you use to start Kermit. Example:",
-" ",
-" kermit -i -s oofa.exe",
-" ",
-"tells Kermit to send (-s) the file oofa.exe in binary (-i) mode.",
-" ",
-"Command-line options are case-sensitive; \"-s\" is different from \"-S\".",
-#ifdef VMS
-"In VMS, uppercase options must be enclosed in doublequotes: ",
-" ",
-" $ kermit \"-Y\" \"-S\" -s oofa.txt ",
-#endif /* VMS */
-" ",
-"If any \"action options\" are included on the command line, Kermit exits",
-"after executing its command-line options. If -S is included, or no action",
-"options were given, Kermit enters its interactive command parser and",
-"issues its prompt.",
-" ",
-"Command-line options are single characters preceded by dash (-). Some",
-"require an \"argument,\" others do not. If an argument contains spaces, it",
-"must be enclosed in doublequotes:",
-" ",
-" kermit -s \"filename with spaces\"",
-" ",
-"\
-An option that does not require an argument can be bundled with other options:"
-,
-" ",
-" kermit -Qis oofa.exe",
-" ",
-"Exceptions to the rules:",
-" ",
-" . If the first command-line option is a filename, Kermit executes commands",
-" from the file. Additional command-line options can follow the filename.",
-" ",
-" . The special option \"=\" (equal sign) or \"--\" (double hyphen) means to",
-" treat the rest of the command line as data, rather than commands; this",
-" data is placed in the argument vector array, \\&@[], along with the other",
-" items on the command line, and also in the top-level \\%1..\\%9 variables."
-,
-" ",
-#ifdef KERBANG
-" . A similar option \"+\" (plus sign) means: the name of a Kermit script",
-" file follows. This file is to be executed, and its name assigned to \\%0",
-" and \\&_[0]. All subsequent command-line arguments are to be ignored by",
-" Kermit but made available to the script as \\%1, \\%2, ..., as well as",
-" in the argument-vector arrays. The initialization file is not executed",
-" automatically in this case.",
-" ",
-#endif /* KERBANG */
-" . The -s option can accept multiple filenames, separated by spaces.",
-" ",
-" . the -j and -J options allow an optional second argument, the TCP port",
-" name or number.",
-" ",
-"Type \"help options all\" to list all the command-line options.",
-"Type \"help option x\" to see the help message for option x.",
-" ",
-"Kermit also offers a selection of \"extended command-line\" options.",
-"These begin with two dashes, followed by a keyword, and then, if the option",
-"has arguments, a colon (:) or equal sign (=) followed by the argument.",
-"Unlike single-letter options, extended option keywords aren't case sensitive",
-"and they can be abbreviated to any length that still distinguishes them from",
-"other extended-option keywords. Example:",
-" ",
-" kermit --banner:oofa.txt",
-" ",
-"which designates the file oofa.txt to be printed upon startup, rather than",
-"the built-in banner (greeting) text. To obtain a list of available",
-"extended options, type \"help extended-options ?\". To get help about all",
-"extended options, type \"help extended-options\". To get help about a",
-"particular extended option, type \"help extended-option xxx\", where \"xxx\"",
-"is the option keyword.",
-#ifdef COMMENT
-#ifndef NOIKSD
-" ",
-"At present, most of the extended options apply only to the Internet Kermit",
-"Service Daemon (IKSD). Type \"help iksd\" for details.",
-#endif /* NOIKSD */
-#endif /* COMMENT */
-""
-};
-
-
-#ifndef NOHELP
-#ifndef NOCMDL
-int
-doxopts() {
- extern char * xopthlp[], * xarghlp[];
- extern struct keytab xargtab[];
- extern int nxargs;
- int i, x, y, n = 0;
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- /* Check whether window size changed */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
- y = cmkey(xargtab,
- nxargs,
- "Extended argument without the \"--\" prefix",
- "",
- xxstring
- );
- if (y == -3) {
- printf("\n");
- if ((x = cmcfm()) < 0)
- return(x);
- for (i = 0; i <= XA_MAX; i++) {
- if (xopthlp[i]) {
- printf("%s\n",xopthlp[i]);
- printf(" %s\n",xarghlp[i]);
- printf("\n");
- n += 3;
- if (n > (cmd_rows - 6)) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- }
- }
- return(1);
- } else if (y < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- printf("\n%s\n",xopthlp[y]);
- printf(" %s\n\n",xarghlp[y]);
- return(1);
-}
-
-int
-dohopts() {
- int i, n, x, y, z, all = 0, msg = 0;
- char *s;
- extern char *opthlp[], *arghlp[];
- extern char * xopthlp[], * xarghlp[];
- extern int optact[];
- if ((x = cmtxt("A command-line option character,\n\
-or the word ALL, or carriage return for an overview",
- "", &s, xxstring)) < 0)
- return(x);
- if (!*s)
- msg = 1;
- else if (!strcmp(s,"all") || (!strcmp(s,"ALL")))
- all = 1;
- else if (*s == '-') /* Be tolerant of leading hyphen */
- s++;
- if (!all && (int)strlen(s) > 1) {
- printf("?A single character, please, or carriage to list them all.\n");
- return(-9);
- }
- if (all) {
- y = 33;
- z = 127;
- } else {
- y = *s;
- z = (y == 0) ? 127 : y;
- if (y == 0) y = 33;
- }
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- /* Check whether window size changed */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
- printf("\n");
- for (i = 0, n = 1; msg != 0 && *cmdlhlp[i]; i++) {
- printf("%s\n",cmdlhlp[i]);
- if (++n > (cmd_rows - 3)) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- }
- if (all) {
- printf("The following command-line options are available:\n\n");
- n += 2;
- }
- for (i = y; msg == 0 && i <= z; i++) {
- if (!opthlp[i])
- continue;
- if (arghlp[i]) { /* Option with arg */
- printf(" -%c <arg>%s\n",(char)i,(optact[i]?" (action option)":""));
-
- printf(" %s\n",opthlp[i]);
- printf(" Argument: %s\n\n",arghlp[i]);
- x = 4;
- } else { /* Option without arg */
- printf(" -%c %s%s\n",
- (char)i, opthlp[i],
- (optact[i]?" (action option)":"")
- );
- printf(" Argument: (none)\n\n");
- x = 3;
- }
- n += x;
- if (n > (cmd_rows - x - 1)) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- }
- if (all) { /* Jeff, Jan 2003 */
- printf("\n");
- if (++n >= cmd_rows) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- printf("The following extended options are available:\n");
- if (++n >= cmd_rows) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- printf("\n");
- if (++n >= cmd_rows) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- for (i = 0; i <= XA_MAX; i++) {
- if (xopthlp[i]) {
- printf("%s\n",xopthlp[i]);
- printf(" %s\n",xarghlp[i]);
- printf("\n");
- n += 3;
- if (n > (cmd_rows - 4)) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- }
- }
- }
- return(1);
-}
-#endif /* NOCMDL */
-#endif /* NOHELP */
-
-#ifdef CKCHANNELIO
-static char * hxxfile[] = {
-"Syntax: FILE <subcommand> [ switches ] <channel> [ <data> ]",
-" Opens, closes, reads, writes, and manages local files.",
-" ",
-"The FILE commands are:",
-" ",
-" FILE OPEN (or FOPEN) -- Open a local file.",
-" FILE CLOSE (or FCLOSE) -- Close an open file.",
-" FILE READ (or FREAD) -- Read data from an open file.",
-" FILE WRITE (or FWRITE) -- Write data to an open file.",
-" FILE LIST (or FLIST) -- List open files.",
-" FILE STATUS (or FSTATUS) -- Show status of a channel.",
-" FILE REWIND (or FREWIND) -- Rewind an open file",
-" FILE COUNT (or FCOUNT) -- Count lines or bytes in an open file",
-" FILE SEEK (or FSEEK) -- Seek to specified spot in an open file.",
-" FILE FLUSH (or FFLUSH) -- Flush output buffers for an open file.",
-" ",
-"Type HELP FILE OPEN or HELP FOPEN for details about FILE OPEN;",
-"type HELP FILE CLOSE or HELP FCLOSE for details about FILE CLOSE, and so on.",
-" ",
-"The following variables are related to the FILE command:",
-" ",
-" \\v(f_max) -- Maximum number of files that can be open at once",
-" \\v(f_error) -- Completion code of most recent FILE command or function",
-" \\v(f_count) -- Result of most recent FILE COUNT command",
-" ",
-"The following functions are related to the FILE command:",
-" ",
-" \\F_eof() -- Check if channel is at EOF",
-" \\F_pos() -- Get channel read/write position (byte number)",
-" \\F_line() -- Get channel read/write position (line number)",
-" \\F_handle() -- Get file handle",
-" \\F_status() -- Get channel status",
-" \\F_getchar() -- Read character",
-" \\F_getline() -- Read line",
-" \\F_getblock() -- Read block",
-" \\F_putchar() -- Write character",
-" \\F_putline() -- Write line",
-" \\F_putblock() -- Write block",
-" \\F_errmsg() -- Error message from most recent FILE command or function",
-" ",
-"Type HELP <function-name> for information about each one.",
-""
-};
-
-static char * hxxf_op[] = {
-"Syntax: FILE OPEN [ switches ] <variable> <filename>",
-" Opens the file indicated by <filename> in the mode indicated by the",
-" switches, if any, or if no switches are included, in read-only mode, and",
-" assigns a channel number for the file to the given variable.",
-" Synonym: FOPEN. Switches:",
-" ",
-"/READ",
-" Open the file for reading.",
-" ",
-"/WRITE",
-" Open the file for writing. If /READ was not also specified, this creates",
-" a new file. If /READ was specified, the existing file is preserved, but",
-" writing is allowed. In both cases, the read/write pointer is initially",
-" at the beginning of the file.",
-" ",
-"/APPEND",
-" If the file does not exist, create a new file and open it for writing.",
-" If the file exists, open it for writing, but with the write pointer",
-" positioned at the end.",
-" ",
-"/BINARY",
-#ifdef VMS
-" Opens the file in binary mode to inhibit end-of-line conversions.",
-#else
-#ifdef OS2
-" Opens the file in binary mode to inhibit end-of-line conversions.",
-#else
-#ifdef UNIX
-" This option is ignored in UNIX.",
-#else
-" This option is ignored on this platform.",
-#endif /* UNIX */
-#endif /* OS2 */
-#endif /* VMS */
-" ",
-"Switches can be combined in an way that makes sense and is supported by the",
-"underlying operating system.",
-""
-};
-
-static char * hxxf_cl[] = {
-"Syntax: FILE CLOSE <channel>",
-" Closes the file on the given channel if it was open.",
-" Also see HELP FILE OPEN. Synonym: FCLOSE.",
-""
-};
-
-static char * hxxf_fl[] = {
-"Syntax: FILE FLUSH <channel>",
-" Flushes output buffers on the given channel if it was open, forcing",
-" all material previously written to be committed to disk. Synonym: FFLUSH.",
-" Also available as \\F_flush().",
-""
-};
-
-static char * hxxf_li[] = {
-"Syntax: FILE LIST",
-" Lists the channel number, name, modes, and position of each file opened",
-" with FILE OPEN. Synonym: FLIST.",
-""
-};
-
-static char * hxxf_re[] = {
-"Syntax: FILE READ [ switches ] <channel> [ <variable> ]",
-" Reads data from the file on the given channel number into the <variable>,",
-" if one was given; if no variable was given, the result is printed on",
-" the screen. The variable should be a macro name rather than a \\%x",
-" variable or array element if you want backslash characters in the file to",
-" be taken literally. Synonym: FREAD. Switches:",
-" ",
-"/LINE",
-" Specifies that a line of text is to be read. A line is defined according",
-" to the underlying operating system's text-file format. For example, in",
-" UNIX a line is a sequence of characters up to and including a linefeed.",
-" The line terminator (if any) is removed before assigning the text to the",
-" variable. If no switches are included with the FILE READ command, /LINE",
-" is assumed.",
-" ",
-"/SIZE:number",
-" Specifies that the given number of bytes (characters) is to be read.",
-" This gives a semblance of \"record i/o\" for files that do not necessarily",
-" contain lines. The resulting block of characters is assigned to the",
-" variable without any editing.",
-" ",
-"/CHARACTER",
-" Equivalent to /SIZE:1. If FILE READ /CHAR succeeds but the <variable> is",
-" empty, this indicates a NUL byte was read.",
-" ",
-"/TRIM",
-" Tells Kermit to trim trailing whitespace when used with /LINE. Ignored",
-" if used with /CHAR or /SIZE.",
-" ",
-"/UNTABIFY",
-" Tells Kermit to convert tabs to spaces (assuming tabs set every 8 spaces)",
-" when used with /LINE. Ignored if used with /CHAR or /SIZE.",
-" ",
-"Synonym: FREAD.",
-"Also available as \\F_getchar(), \\F_getline(), \\F_getblock().",
-""
-};
-
-static char * hxxf_rw[] = {
-"Syntax: FILE REWIND <channel>",
-" If the channel is open, moves the read/write pointer to the beginning of",
-" the file. Equivalent to FILE SEEK <channel> 0. Synonym: FREWIND.",
-" Also available as \\F_rewind().",
-""
-};
-
-static char * hxxf_se[] = {
-"Syntax: FILE SEEK [ switches ] <channel> { [{+,-}]<number>, EOF }",
-" Switches are /BYTE, /LINE, /RELATIVE, /ABSOLUTE, and /FIND:pattern.",
-" Moves the file pointer for this file to the given position in the",
-" file. Subsequent FILE READs or WRITEs will take place at that position.",
-" If neither the /RELATIVE nor /ABSOLUTE switch is given, an unsigned",
-" <number> is absolute; a signed number is relative. EOF means to move to",
-" the end of the file. If a /FIND: switch is included, Kermit seeks to the",
-" specified spot (e.g. 0 for the beginning) and then begins searching line",
-" by line for the first line that matches the given pattern. To start",
-" searching from the current file position specify a line number of +0.",
-" To start searching from the line after the current one, use +1 (etc).",
-" Synonym: FSEEK.",
-""
-};
-
-static char * hxxf_st[] = {
-"Syntax: FILE STATUS <channel>",
-" If the channel is open, this command shows the name of the file, the",
-" switches it was opened with, and the current read/write position.",
-" Synonym: FSTATUS",
-""
-};
-
-static char * hxxf_co[] = {
-"Syntax: FILE COUNT [ { /BYTES, /LINES, /LIST, /NOLIST } ] <channel>",
-" If the channel is open, this command prints the nubmer of bytes (default)",
-" or lines in the file if at top level or if /LIST is included; if /NOLIST",
-" is given, the result is not printed. In all cases the result is assigned",
-" to \\v(f_count). Synonym: FCOUNT",
-""
-};
-
-static char * hxxf_wr[] = {
-"FILE WRITE [ switches ] <channel> <text>",
-" Writes the given text to the file on the given channel number. The <text>",
-" can be literal text or a variable, or any combination. If the text might",
-" contain leading or trailing spaces, it must be enclosed in braces if you",
-" want to preserve them. Synonym: FWRITE. Switches:",
-" ",
-"/LINE",
-" Specifies that an appropriate line terminator is to be added to the",
-" end of the <text>. If no switches are included, /LINE is assumed.",
-" ",
-"/SIZE:number",
-" Specifies that the given number of bytes (characters) is to be written.",
-" If the given <text> is longer than the requested size, it is truncated;",
-" if is shorter, it is padded according /LPAD and /RPAD switches. Synonym:",
-" /BLOCK.",
-" ",
-"/LPAD[:value]",
-" If /SIZE was given, but the <text> is shorter than the requested size,",
-" the text is padded on the left with sufficient copies of the character",
-" whose ASCII value is given to write the given length. If no value is",
-" specified, 32 (the code for Space) is used. The value can also be 0 to",
-" write the indicated number of NUL bytes. If /SIZE was not given, this",
-" switch is ignored.",
-" ",
-"/RPAD[:value]",
-" Like LPAD, but pads on the right.",
-" ",
-"/STRING",
-" Specifies that the <text> is to be written as-is, with no terminator added."
-,
-" ",
-"/CHARACTER",
-" Specifies that one character should be written. If the <text> is empty or",
-" not given, a NUL character is written; otherwise the first character of",
-" <text> is given.",
-" ",
-"Synonym FWRITE.",
-"Also available as \\F_putchar(), \\F_putline(), \\F_putblock().",
-""
-};
-
-static int
-dohfile(cx) int cx; {
- extern struct keytab fctab[];
- extern int nfctab;
- int x;
- if (cx == XXFILE) { /* FILE command was given */
- /* Get subcommand */
- if ((cx = cmkey(fctab,nfctab,"Operation","",xxstring)) < 0) {
- if (cx == -3) {
- if ((x = cmcfm()) < 0)
- return(x);
- cx = XXFILE;
- } else
- return(cx);
- }
- if ((x = cmcfm()) < 0)
- return(x);
- switch (cx) {
- case FIL_CLS: cx = XXF_CL; break;
- case FIL_FLU: cx = XXF_FL; break;
- case FIL_LIS: cx = XXF_LI; break;
- case FIL_OPN: cx = XXF_OP; break;
- case FIL_REA: cx = XXF_RE; break;
- case FIL_REW: cx = XXF_RW; break;
- case FIL_SEE: cx = XXF_SE; break;
- case FIL_STA: cx = XXF_ST; break;
- case FIL_WRI: cx = XXF_WR; break;
- case FIL_COU: cx = XXF_CO; break;
- }
- }
- switch (cx) {
- case XXFILE: return(hmsga(hxxfile));
- case XXF_CL: return(hmsga(hxxf_cl));
- case XXF_FL: return(hmsga(hxxf_fl));
- case XXF_LI: return(hmsga(hxxf_li));
- case XXF_OP: return(hmsga(hxxf_op));
- case XXF_RE: return(hmsga(hxxf_re));
- case XXF_RW: return(hmsga(hxxf_rw));
- case XXF_SE: return(hmsga(hxxf_se));
- case XXF_ST: return(hmsga(hxxf_st));
- case XXF_WR: return(hmsga(hxxf_wr));
- case XXF_CO: return(hmsga(hxxf_co));
- default:
- return(-2);
- }
-}
-#endif /* CKCHANNELIO */
-
-int
-dohlp(xx) int xx; {
- int x,y;
-
- debug(F101,"DOHELP xx","",xx);
- if (xx < 0) return(xx);
-
-#ifdef NOHELP
- if ((x = cmcfm()) < 0)
- return(x);
- printf("\n%s, Copyright (C) 1985, %s,",versio, ck_cryear);
-#ifndef NOIKSD
- if (inserver)
- return(hmsga(tophlpi));
- else
-#endif /* IKSD */
- return(hmsga(tophlp));
-
-#else /* help is available */
-
- if (helpfile)
- return(dotype(helpfile,xaskmore,0,0,NULL,0,NULL,0,0,NULL,0));
-
-#ifdef CKCHANNELIO
- if (xx == XXFILE)
- return(dohfile(xx));
- else if (xx == XXF_RE || xx == XXF_WR || xx == XXF_OP ||
- xx == XXF_CL || xx == XXF_SE || xx == XXF_RW ||
- xx == XXF_FL || xx == XXF_LI || xx == XXF_ST || xx == XXF_CO)
- return(dohfile(xx));
-#endif /* CKCHANNELIO */
-
- switch (xx) {
-
-#ifndef NOSPL
-case XXASS: /* ASSIGN */
- return(hmsga(hxxass));
-
-case XXASK: /* ASK */
-case XXASKQ: /* ASKQ */
- return(hmsga(hxxask));
-
-case XXAPC:
- return(hmsg("Syntax: APC text\n\
- Echoes the text within a VT220/320/420 Application Program Command."));
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
-case XXBUG:
- return(hmsg("Describes how to get technical support."));
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
-case XXBEEP:
-#ifdef OS2
- return(hmsg("Syntax: BEEP [ { ERROR, INFORMATION, WARNING } ]\n\
- Generates a bell according to the current settings. If SET BELL is set to\n\
- \"system-sounds\" then the appropriate System Sound will be generated.\n\
- Default is INFORMATION."));
-#else /* OS2 */
- return(hmsg("Syntax: BEEP\n\
-Sends a BEL character to your terminal."));
-#endif /* OS2 */
-#endif /* NOSPL */
-
-case XXBYE: /* BYE */
- return(hmsg(hmxxbye));
-
-case XXCHK: /* check */
- return(hmsg("\
-Syntax: CHECK name\n\
- Checks\
- to see if the named feature is included in this version of Kermit.\n\
- To list the features you can check, type \"check ?\"."));
-
-#ifndef NOFRILLS
-case XXCLE: /* clear */
- return(hmsga(hmxxcle));
-#endif /* NOFRILLS */
-
-case XXCLO: /* close */
- return(hmsga(hmxxclo));
-
-case XXCOM: /* comment */
-#ifndef STRATUS /* Can't use # for comments in Stratus VOS */
- return(hmsg("\
-Syntax: COMMENT text\n\
-Example: COMMENT - this is a comment.\n\
- Introduces a comment. Beginning of command line only. Commands may also\n\
- have trailing comments, introduced by ; or #."));
-#else
- return(hmsg("\
-Syntax: COMMENT text\n\
-Example: COMMENT - this is a comment.\n\
- Introduces a comment. Beginning of command line only. Commands may also\n\
- have trailing comments, introduced by ; (semicolon)."));
-#endif /* STRATUS */
-
-#ifndef NOLOCAL
-case XXCON: /* CONNECT */
-case XXCQ: /* CQ == CONNECT /QUIETLY */
- hmsga(hmxxcon);
- printf("Your escape character is Ctrl-%c (ASCII %d, %s)\r\n",
- ctl(escape), escape, (escape == 127 ? "DEL" : ccntab[escape]));
- return(0);
-#endif /* NOLOCAL */
-
-#ifdef ZCOPY
-case XXCPY:
- return(hmsga(hmxxcpy));
-#endif /* ZCOPY */
-
-#ifdef NT
-case XXLINK:
-return(hmsg(
-" LINK source destination\n\
- creates a hard link to the file specified by source to the filename\n\
- specified by destination. Hard links are only supported on NTFS.\n\
- destination can either be a filename or a directory. source may\n\
- contain wildcards if destination is a directory."));
-#endif /* NT */
-
-#ifndef NOFRILLS
-case XXLREN: /* LRENAME */
- return(hmsg(
-" LRENAME is an alias for the RENAME command forcing it to execute\n\
- on the local computer. Also see: RENAME, RRENAME, SET LOCUS."));
-
-case XXREN:
- return(hmsga(hmxxren));
-#endif /* NOFRILLS */
-
-case XXCDUP: /* CDUP */
-case XXLCDU:
- return(hmsg(
-"Change working directory to the one just above the current one."));
-
-case XXLCWD:
- return(hmsg(
-" LCD (LCWD) is an alias for the CD (CWD) command forcing it to execute\n\
- on the local computer. Also see: CD, CDUP, RCD, SET LOCUS."));
-
-case XXCWD: /* CD / CWD */
- return(hmsga(hmxxcwd));
-
-#ifndef NOSPL
-case XXKCD:
- return(hmsga(hmxxkcd));
-
-case XXARRAY:
-case XXDCL: /* DECLARE */
-case XXSORT:
- return(hmsga(hxxdcl));
-
-case XXDEF: /* DEFINE */
-#ifndef NOSPL
- if (hlptok) /* What they actually typed... */
- if (hlptok[0] == '.')
- return(hmsga(hxxdot));
-#endif /* NOSPL */
- return(hmsga(hxxdef));
-
-case XXUNDEF: /* UNDEFINE */
- return(hmsg("Syntax: UNDEFINE variable-name\n\
- Undefines a macro or variable."));
-#endif /* NOSPL */
-
-case XXMSG:
- return(hmsg("Syntax: MESSAGE text-to-print-if-debugging\n\
- Prints the given text to stdout if SET DEBUG MESSAGE is ON; prints it\n\
- to stderr if SET DEBUG MESSAGE is STDERR; doesn't print it at all if SET\n\
- DEBUG MESSAGE is OFF. Synonym: MSG."));
-
-#ifndef NOFRILLS
-case XXLDEL:
- return(hmsg(
-" LDELETE is an alias for the DELETE command forcing it to execute\n\
- on the local computer. Also see: DELETE, RDELETE, SET LOCUS."));
-
-case XXDEL: /* delete */
- return(hmsga(hmxxdel));
-#endif /* NOFRILLS */
-
-#ifndef NODIAL
-case XXDIAL: /* DIAL, etc... */
- return(hmsga(hxxdial));
-
-case XXPDIA: /* PDIAL */
- return(hmsg("Syntax: PDIAL phonenumber\n\
- Partially dials a phone number. Like DIAL but does not wait for carrier\n\
- or CONNECT message."));
-
-case XXRED:
- return(hmsg("Redial the number given in the most recent DIAL commnd."));
-
-case XXANSW: /* ANSWER */
- return(hmsga(hxxansw));
-
-case XXLOOK: /* LOOKUP number in directory */
- return(hmsga(hxxlook));
-#endif /* NODIAL */
-
-case XXLDIR: /* LDIRECTORY */
- return(hmsg(
-" LDIRIRECTORY is an alias for the DIRECTORY command forcing it to execute\n\
- on the local computer. Also see: DIRECTORY, SET LOCUS, RDIRECTORY."));
-
-case XXDIR: /* DIRECTORY */
- return(hmsga(hmxxdir));
-
-case XXTOUC: /* TOUCH */
- return(hmsga(hmxxtouc));
-
-case XXWDIR: /* WDIRECTORY */
- return(hmsg(" WDIRECTORY is shorthand for DIRECTORY /SORT:DATE /REVERSE;\n\
- it produces a listing in reverse chronological order. See the DIRECTORY\n\
- command for further information."));
-
-case XXHDIR: /* HDIRECTORY */
- return(hmsg(" HDIRECTORY is shorthand for DIRECTORY /SORT:SIZE /REVERSE;\n\
- it produces a listing showing the biggest files first. See the DIRECTORY\n\
- command for further information."));
-
-case XXLMKD: /* LMKDIR */
- return(hmsg(
-" LMKDIR is an alias for the MKDIR command forcing it to execute\n\
- on the local computer. Also see: MKDIR, RMKDIR, SET LOCUS."));
-
-case XXMKDIR: /* MKDIR */
- return(hmsg("Creates a directory. Also see LRMDIR, RRMDIR, SET LOCUS."));
-
-case XXLRMD: /* LRMDIR */
- return(hmsg(
-" LRMDIR is an alias for the RMDIR command forcing it to execute\n\
- on the local computer. Also see: RMDIR, RRMDIR, SET LOCUS."));
-
-case XXRMDIR: /* RMDIR */
- return(hmsg("Removes a directory. Also see LRMDIR, RRMDIR, SET LOCUS."));
-
-case XXLS:
-#ifdef UNIXOROSK
- return(hmsg("Syntax: LS [ args ]\n\
- Runs \"ls\" with the given arguments."));
-#else
- return(hmsga(hmxxdir));
-#endif /* UNIXOROSK */
-
-#ifndef NOSERVER
-#ifndef NOFRILLS
-case XXDIS:
- return(hmsg("Syntax: DISABLE command\n\
- Security for the Kermit server. Prevents the client Kermit program from\n\
- executing the named REMOTE command, such as CD, DELETE, RECEIVE, etc."));
-#endif /* NOFRILLS */
-#endif /* NOSERVER */
-
-#ifndef NOSPL
-case XXDO: /* do */
- return(hmsg("Syntax: [ DO ] macroname [ arguments ]\n\
- Executes a macro that was defined with the DEFINE command. The word DO\n\
- can be omitted. Trailing argument words, if any, are automatically\n\
- assigned to the macro argument variables \\%1 through \\%9."));
-#endif /* NOSPL */
-
-#ifndef NOSPL
-case XXDEC:
- return(hmsga(hxxdec));
-#endif /* NOSPL */
-
-case XXECH: /* echo */
- return(hmsg("Syntax: ECHO text\n\
- Displays the text on the screen, followed by a line terminator. The ECHO\n\
- text may contain backslash codes. Example: ECHO \\7Wake up!\\7. Also see\n\
- XECHO and WRITE SCREEN."));
-
-case XXXECH: /* xecho */
- return(hmsg("Syntax: XECHO text\n\
- Just like ECHO but does not add a line terminator to the text. See ECHO."));
-
-case XXVOID:
- return(hmsg("Syntax: VOID text\n\
- Like ECHO but doesn't print anything; can be used to invoke functions\n\
- when you don't need to display or use their results."));
-
-#ifndef NOSERVER
-#ifndef NOFRILLS
-case XXENA:
- return(hmsg("Syntax: ENABLE capability\n\
- For use with server mode. Allows the client Kermit program access to the\n\
- named capability, such as CD, DELETE, RECEIVE, etc. Opposite of DISABLE."));
-#endif /* NOFRILLS */
-#endif /* NOSERVER */
-
-#ifndef NOSPL
-case XXEND: /* end */
- return(hmsg("Syntax: END [ number [ message ] ]\n\
- Exits from the current macro or TAKE file, back to wherever invoked from.\n\
- Number is return code. Message, if given, is printed."));
-
-case XXEVAL: /* evaluate */
- return(hmsga(hmxxeval));
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
-case XXERR: /* e-packet */
- return(hmsg("Syntax: E-PACKET\n\
- Sends an Error packet to the other Kermit."));
-#endif /* NOFRILLS */
-
-case XXEXI: /* exit */
-case XXQUI:
- return(hmsga(hmxxexit));
-
-case XXFIN:
- return(hmsg("Syntax: FINISH\n\
- Tells the remote Kermit server to shut down without logging out."));
-
-#ifndef NOSPL
- case XXFOR:
- return(hmsga(forhlp));
-#endif /* NOSPL */
-
- case XXGET:
- return(hmsga(hmxxget));
- case XXMGET:
- return(hmsga(hmxxmget));
-
-#ifndef NOSPL
-#ifndef NOFRILLS
- case XXGOK:
- return(hmsg("Syntax: GETOK [ switches ] prompt\n\
- Prints the prompt, makes user type 'yes', 'no', or 'ok', and sets SUCCESS\n\
- or FAILURE accordingly. The optional switches are the same as for ASK."));
-#endif /* NOFRILLS */
-#endif /* NOSPL */
-
-#ifndef NOSPL
- case XXGOTO:
- return(hmsg("Syntax: GOTO label\n\
- In a TAKE file or macro, go to the given label. A label is a word on the\n\
- left margin that starts with a colon (:). Example:\n\n\
- :oofa\n\
- echo Hello!\n\
- goto oofa"));
-#endif /* NOSPL */
-
- case XXHAN:
- return(hmsg("Syntax: HANGUP\n\
-Hang up the phone or network connection."));
-
- case XXHLP:
-/*
- We get confirmation here, even though we do it again in hmsga(), to prevent
- the Copyright message from being printed prematurely. This doesn't do any
- harm, because the first call to cmcfm() sets cmflgs to 1, making the second
- call return immediately.
-*/
- if ((x = cmcfm()) < 0)
- return(x);
-
- if (helpfile) {
- printf("\n%s, Copyright (C) 1985, %s,\n\
-Trustees of Columbia University in the City of New York.\n\n",
- versio,
- ck_cryear
- );
- return(dotype(helpfile,xaskmore,3,0,NULL,0,NULL,0,0,NULL,0));
- } else {
- printf("\n%s, Copyright (C) 1985, %s,",versio,ck_cryear);
- return(hmsga(tophlp));
- }
-
-case XXINT:
-#ifdef OS2
- return(hmsg("The INTRO command gives a brief introduction to Kermit 95."));
-#else
- return(hmsg("The INTRO command gives a brief introduction to C-Kermit."));
-#endif /* OS2 */
-
-#ifndef NOSPL
-case XXIF:
- return(hmsga(ifhlp));
-
-case XXINC:
- return(hmsga(hxxinc));
-
-case XXINP:
- return(hmsga(hxxinp));
-#endif /* NOSPL */
-
-#ifdef CK_MINPUT
-case XXMINP:
- return(hmsga(hmxxminp));
-#endif /* CK_MINPUT */
-
-#ifndef NOSPL
-case XXREI:
- return(hmsg("Syntax: REINPUT n string\n\
- Looks for the string in the text that has recently been INPUT, set SUCCESS\n\
- or FAILURE accordingly. Timeout, n, must be specified but is ignored."));
-#endif /* NOSPL */
-
-#ifndef NOSPL
-case XXLBL:
- return(hmsg("\
- Introduces a label, like :loop, for use with GOTO in TAKE files or macros.\n\
-See GOTO."));
-#endif /* NOSPL */
-
-case XXLOG:
- return(hmsga(hmxxlg));
-
-#ifndef NOSCRIPT
-case XXLOGI:
- return(hmsga(hmxxlogi));
-#endif
-
-#ifndef NOFRILLS
-case XXMAI:
- return(hmsg("Syntax: MAIL filename address\n\
- Equivalent to SEND /MAIL:address filename."));
-#endif /* NOFRILLS */
-
-#ifndef NOMSEND
-case XXMSE:
- return(hmsga(hmxxmse));
-
-case XXADD:
- return(hmsga(hmxxadd));
-
-case XXMMOVE:
- return(hmsg("MMOVE is exactly like MSEND, except each file that is\n\
-sent successfully is deleted after it is sent."));
-#endif /* NOMSEND */
-
-#ifndef NOSPL
-case XXOPE:
- return(hmsga(openhlp));
-#endif /* NOSPL */
-
-case XXNEW:
- return(hmsg(
-" Prints news of new features since publication of \"Using C-Kermit\"."));
-
-case XXUPD:
- return(hmsg(
-" New features are described in the online Kermit 95 manual,\n\
- accessible via the MANUAL command."));
-
-#ifndef NOSPL
-case XXOUT:
- return(hmsga(hxxout));
-#endif /* NOSPL */
-
-#ifdef ANYX25
-#ifndef IBMX25
-case XXPAD:
- return(hmsga(hxxpad));
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifndef NOSPL
-case XXPAU:
- return(hmsga(hxxpau));
-
-case XXMSL:
- return(hmsga(hxxmsl));
-#endif /* NOSPL */
-
-#ifdef TCPSOCKET
-case XXPNG:
- return(hmsg("Syntax: PING [ IP-hostname-or-number ]\n\
- Checks if the given IP network host is reachable. Default host is from\n\
- most recent SET HOST or TELNET command. Runs system PING program, if any.")
- );
-
-case XXFTP:
-#ifdef SYSFTP
- return(hmsg("Syntax: FTP [ IP-hostname-or-number ]\n\
- Makes an FTP connection to the given IP host or, if no host specified, to\n\
- the current host. Uses the system's FTP program, if any."));
-#else
-#ifndef NOFTP
- return(doftphlp());
-#endif /* NOFTP */
-#endif /* SYSFTP */
-#endif /* TCPSOCKET */
-
-#ifndef NOFRILLS
-case XXPRI:
-#ifdef UNIX
- return(hmsg("Syntax: PRINT file [ options ]\n\
- Prints the local file on a local printer with the given options. Also see\n\
- HELP SET PRINTER."));
-#else
-#ifdef VMS
- return(hmsg("Syntax: PRINT file [ options ]\n\
- Prints the local file on a local printer with the given options. Also see\n\
- HELP SET PRINTER."));
-#else
- return(hmsg("Syntax: PRINT file\n\
- Prints the local file on a local printer. Also see HELP SET PRINTER."));
-#endif /* UNIX */
-#endif /* VMS */
-#endif /* NOFRILLS */
-
-case XXPWD:
-case XXLPWD:
- return(hmsg("Syntax: PWD\n\
-Print the name of the current working directory."));
-
-#ifndef NOSPL
-case XXREA:
- return(hmsg("Syntax: READ variablename\n\
- Reads a line from the currently open READ or !READ file into the variable\n\
- (see OPEN)."));
-#endif /* NOSPL */
-
-#ifndef NOXFER
-case XXREC:
- return(hmsga(hmxxrc));
-
-case XXREM:
- y = cmkey(remcmd,nrmt,"Remote command","",xxstring);
- return(dohrmt(y));
-#endif /* NOXFER */
-
-#ifndef NOSPL
-case XXRET:
- return(hmsg("Syntax: RETURN [ value ]\n\
- Return from a macro. An optional return value can be given for use with\n\
- \\fexecute(macro), which allows macros to be used like functions."));
-#endif /* NOSPL */
-
-#ifndef NOXFER
-case XXSEN:
- return(hmsga(hmxxsen));
-case XXMOVE:
- return(hmsg("MOVE is exactly like SEND, except each file that is\n\
-sent successfully is deleted after it is sent."));
-#ifndef NORESEND
-case XXRSEN:
- return(hmsg(hmxxrsen));
-case XXREGET:
- return(hmsg(hmxxrget));
-case XXPSEN:
- return(hmsg(hmxxpsen));
-#endif /* NORESEND */
-
-#ifndef NOSERVER
-case XXSER:
- return(hmsg(hmxxser));
-#endif /* NOSERVER */
-#endif /* NOXFER */
-
-#ifndef NOJC
-case XXSUS:
- return(hmsg("Syntax: SUSPEND or Z\n\
- Suspends Kermit. Continue Kermit with the appropriate system command,\n\
- such as fg."));
-#endif /* NOJC */
-
-case XXSET:
- y = cmkey(prmtab,nprm,"Parameter","",xxstring);
- debug(F101,"HELP SET y","",y);
- return(dohset(y));
-
-#ifndef NOPUSH
-case XXSHE:
- if (nopush) {
- if ((x = cmcfm()) < 0) return(x);
- printf("Sorry, help not available for \"%s\"\n",cmdbuf);
- break;
- } else
- return(hmsga(hxxshe));
-#ifdef CK_REDIR
-case XXFUN:
- return(hmsg("Syntax: REDIRECT command\n\
- Runs the given local command with its standard input and output redirected\n\
- to the current SET LINE or SET HOST communications path.\n\
- Synonym: < (Left angle bracket)."));
-#endif /* CK_REDIR */
-
-#ifdef CK_REXX
-case XXREXX:
- return(hmsg("Syntax: REXX text\n\
- The text is a Rexx command to be executed. The \\v(rexx) variable is set\n\
- to the Rexx command's return value.\n\
- To execute a rexx program file, use: REXX call <filename>\n\
- Rexx programs may call Kermit functions by placing the Kermit command\n\
- in single quotes. For instance: 'set parity none'."));
-#endif /* CK_REXX */
-#endif /* NOPUSH */
-
-#ifndef NOSHOW
-case XXSHO:
- return(hmsg("\
- Display current values of various items (SET parameters, variables, etc).\n\
- Type SHOW ? for a list of categories."));
-#endif /* NOSHOW */
-
-case XXSPA:
-#ifdef datageneral
- return(hmsg("\
- Display disk usage in current device, directory,\n\
- or return space for a specified device, directory."));
-#else
- return(hmsg("Syntax: SPACE\n\
- Display disk usage in current device and/or directory"));
-#endif
-
-case XXSTA:
- return(hmsg("Syntax: STATISTICS [/BRIEF]\n\
- Display statistics about most recent file transfer"));
-
-#ifndef NOSPL
-case XXSTO:
- return(hmsg("Syntax: STOP [ number [ message ] ]\n\
- Stop executing the current macro or TAKE file and return immediately to\n\
- the Kermit prompt. Number is a return code. Message printed if given."));
-#endif /* NOSPL */
-
-case XXTAK:
- return(hmsga(hmxxtak));
-
-#ifdef TCPSOCKET
-#ifdef TNCODE
-case XXIKSD:
- return(hmsga(hmxxiks));
-
-case XXTEL:
- return(hmsga(hmxxtel));
-
-case XXTELOP:
- return(hmsga(hxtopt));
-#endif /* TNCODE */
-
-#ifdef RLOGCODE
-case XXRLOG:
- return(hmsg("Syntax: RLOGIN [ switches ] [ host [ username ] ]\n\
- Equivalent to SET NETWORK TYPE TCP/IP, SET HOST host [ service ] /RLOGIN,\n\
- IF SUCCESS CONNECT. If host is omitted, the previous connection (if any)\n\
- is resumed. Depending on how Kermit has been built switches may be\n\
- available to require Kerberos authentication and DES encryption."));
-#endif /* RLOGCODE */
-#endif /* TCPSOCKET */
-
-#ifndef NOXMIT
-case XXTRA:
- return(hmsga(hxxxmit));
-#endif /* NOXMIT */
-
-#ifndef NOFRILLS
-case XXTYP:
- return(hmsga(hmxxtyp));
-case XXMORE:
- return(hmsg("Syntax: MORE [ switches ] filename\n\
- Equivalent to TYPE /PAGE filename; see HELP TYPE."));
-case XXCAT:
- return(hmsg("Syntax: MORE [ switches ] filename\n\
- Equivalent to TYPE /NOPAGE filename; see HELP TYPE."));
-case XXHEAD:
- return(hmsg("Syntax: HEAD [ switches ] filename\n\
- Equivalent to TYPE /HEAD filename; see HELP TYPE."));
-case XXTAIL:
- return(hmsg("Syntax: TAIL [ switches ] filename\n\
- Equivalent to TYPE /TAIL filename; see HELP TYPE."));
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
-case XXWHI:
- return(hmsga(whihlp));
-
-case XXSWIT:
- return(hmsga(swihlp));
-#endif /* NOSPL */
-
-#ifndef NOCSETS
-case XXXLA:
- return(hmsga(hxxxla));
-#endif /* NOCSETS */
-
-case XXVER:
- return(hmsg("Syntax: VERSION\nDisplays the program version number."));
-
-#ifndef NOSPL
-case XXWAI:
- return(hmsga(hxxwai));
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
-case XXWHO:
- return(hmsg("Syntax: WHO [ user ]\nDisplays info about the user."));
-
-case XXWRI:
- return(hmsga(hxxwri));
-
-case XXWRL:
- return(hmsg(
-"WRITE-LINE (WRITELN) is just like WRITE, but includes a line terminator\n\
-at the end of text. See WRITE."));
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
-case XXIFX:
- return(hmsga(ifxhlp));
-
-case XXGETC: /* GETC */
- return(hmsga(hxxgetc));
-
-case XXFWD: /* FORWARD */
- return(hmsg(
-"Like GOTO, but searches only forward for the label. See GOTO."));
-
-case XXLOCAL: /* LOCAL */
- return(hmsg(
-"Declares a variable to be local to the current macro or command file."));
-#endif /* NOSPL */
-
-case XXVIEW:
- return(hmsg(
-"View the terminal emulation screen even when there is no connection."));
-
-#ifdef NEWFTP
-case XXASC:
- return(hmsg(
-"Inhibits automatic transfer-mode switching and forces TEXT (ASCII) transfer\n\
-mode for all files in both Kermit and FTP protocols."));
-case XXBIN:
- return(hmsg(
-"Inhibits automatic transfer-mode switching and forces BINARY transfer mode\n\
-for all files in both Kermit and FTP protocols."));
-#else
-case XXASC:
- return(hmsg(
-"Inhibits automatic transfer-mode switching and forces TEXT (ASCII) transfer\n\
-mode for all files."));
-case XXBIN:
- return(hmsg(
-"Inhibits automatic transfer-mode switching and forces BINARY transfer mode\n\
-for all files."));
-#endif /* NEWFTP */
-
-case XXDATE:
- return(hmsga(hmxxdate));
-
-case XXRETR:
- return(hmsg(
-"Just like GET but asks the server to delete each file that has been\n\
-sent successfully."));
-
-case XXEIGHT:
- return(hmsg(
-"Equivalent to SET PARITY NONE, SET COMMAND BYTE 8, SET TERMINAL BYTE 8."));
-
-case XXSAVE:
- return(hmsga(hmxxsave));
-
-#ifndef NOFRILLS
-#ifndef NOPUSH
-case XXEDIT:
- return(hmsg("Syntax: EDIT [ <file> ]\n\
-Starts your preferred editor on the given file, or if none given, the most\n\
-recently edited file, if any. Also see SET EDITOR."));
-#endif /* NOPUSH */
-#endif /* NOFRILLS */
-
-#ifdef BROWSER
-case XXBROWS:
- return(hmsg("Syntax: BROWSE [ <url> ]\n\
-Starts your preferred Web browser on the given URL, or if none given, the\n\
-most recently visited URL, if any. Also see SET BROWSER."));
-#endif /* BROWSER */
-
-#ifdef CK_TAPI
-case XXTAPI:
- return(hmsga(hxxtapi));
-#endif /* CK_TAPI */
-
-#ifdef PIPESEND
-case XXCSEN:
- return(hmsg("Syntax: CSEND [ switches ] <command> [ <as-name> ]\n\
-Sends from the given <command> rather than from a file. Equivalent to\n\
-SEND /COMMAND; see HELP SEND for details."));
-
-case XXCREC:
- return(hmsg("Syntax: CRECEIVE [ switches ] <command>\n\
-Receives to the given <command> rather than to a file. Equivalent to\n\
-RECEIVE /COMMAND; see HELP RECEIVE for details."));
-
-case XXCGET:
- return(hmsg("Syntax: CGET <remote-file-or-command> <local-command>\n\
-Equivalent to GET /COMMAND; see HELP GET for details."));
-#endif /* PIPESEND */
-
-#ifndef NOSPL
-case XXFUNC:
-/*
- Tricky parsing. We want to let them type the function name in any format
- at all: \fblah(), \fblah, \\fblah(), fblah, blah, blah(), etc, but of course
- only one of these is recognized by cmkey(). So we call cmkeyx() (the "no
- complaints" version of cmkey()), and if it fails, we try the other formats
- silently, and still allow for <no-name-given>, editing and reparse, etc.
-*/
- y = cmkeyx(fnctab,nfuncs,"Name of function","",NULL);
- if (y == -1) { /* Reparse needed */
- return(y);
- } else if (y == -3) {
- if ((x = cmcfm()) < 0) /* For recall buffer... */
- return(x);
- return(dohfunc(y)); /* -3 gives general message */
- }
- if (y < 0) { /* Something given but didn't match */
- int dummy;
- char * p;
- for (p = atmbuf; *p; p++) { /* Chop off trailing parens if any */
- if (*p == '(') {
- *p = NUL;
- break;
- }
- }
- /* Chop off leading "\\f" or "\f" or "f" */
- p = atmbuf;
- if (*p == CMDQ) /* Allow for \\f... */
- p++;
- if (*p == CMDQ && (*(p+1) == 'f' || *(p+1) == 'F')) { /* or \f */
- p += 2;
- } else if (*p == 'f' || *p == 'F') { /* or just f */
- p++;
- }
- y = lookup(fnctab,p,nfuncs,&dummy); /* Look up the result */
- }
- if (y < 0) {
- printf("?No such function - \"%s\"\n",atmbuf);
- return(-9);
- }
- x = cmgbrk(); /* Find out how user terminated */
- if (x == LF || x == CR) /* if with CR or LF */
- cmflgs = 1; /* restore cmflgs to say so */
- if ((x = cmcfm()) < 0) /* And THEN confirm so command will */
- return(x); /* get into recall buffer. */
- return(dohfunc(y));
-#endif /* NOSPL */
-
-#ifndef NOCMDL
-case XXOPTS: /* Command-line options */
- return(dohopts());
-
-case XXXOPTS: /* Extended command-line options */
- return(doxopts());
-#endif /* NOCMDL */
-
-#ifdef OS2
-#ifndef NOKVERBS
-case XXKVRB: {
- y = cmkeyx(kverbs,nkverbs,"Name of keyboard verb without \\k","",NULL);
- if (y == -1) { /* Reparse needed */
- return(y);
- } else if (y == -3) {
- if ((x = cmcfm()) < 0) /* For recall buffer... */
- return(x);
- return(dohkverb(y)); /* -3 gives general message */
- }
- if (y < 0) { /* Something given but didn't match */
- int dummy;
- char * p;
- for (p = atmbuf; *p; p++) { /* Chop off trailing parens if any */
- if (*p == '(') {
- *p = NUL;
- break;
- }
- }
- /* Chop off leading "\\k" or "\k" or "k" */
- p = atmbuf;
- if (*p == CMDQ) /* Allow for \\k... */
- p++;
- if (*p == CMDQ && (*(p+1) == 'k' || *(p+1) == 'K')) { /* or \k */
- p += 2;
- } else if (*p == 'k' || *p == 'K') { /* or just k */
- p++;
- }
- y = lookup(kverbs,p,nkverbs,&dummy); /* Look up the result */
- }
- if (y < 0) {
- printf("?No such function - \"%s\"\n",atmbuf);
- return(-9);
- }
- x = cmgbrk(); /* Find out how user terminated */
- if (x == LF || x == CR) /* if with CR or LF */
- cmflgs = 1; /* restore cmflgs to say so */
- if ((x = cmcfm()) < 0) /* And THEN confirm so command will */
- return(x); /* get into recall buffer. */
- return(dohkverb(y));
-}
-#endif /* NOKVERBS */
-#endif /* OS2 */
-
-case XXKERMI:
- return(hmsg("Syntax: KERMIT [command-line-options]\n\
- Lets you give command-line options at the prompt or in a script.\n\
- HELP OPTIONS for more info."));
-
-case XXBACK:
- return(hmsg("Syntax: BACK\n Returns to your previous directory."));
-
-case XXWHERE:
- return(hmsg("Syntax: WHERE\n Tells where your transferred files went."));
-
-#ifndef NOXFER
-case XXREMV:
- return(hmsga(hmxxremv));
-#endif /* NOXFER */
-
-#ifdef CK_KERBEROS
-case XXAUTH:
- return(hmsga(hmxxauth));
-#endif /* CK_KERBEROS */
-
-#ifndef NOHTTP
-case XXHTTP:
- return(hmsga(hmxxhttp));
-#endif /* NOHTTP */
-
-#ifdef NETCMD
-case XXPIPE:
- return(hmsg("Syntax: PIPE [ command ]\n\
-Makes a connection through the program whose command line is given. Example:\n\
-\n pipe rlogin xyzcorp.com"));
-#endif /* NETCMD */
-
-case XXSTATUS:
- return(hmsg(
-"STATUS is the same as SHOW STATUS; prints SUCCESS or FAILURE for the\n\
-previous command."));
-
-#ifndef NOSPL
-case XXASSER:
- return(hmsg("Syntax: ASSERT <condition>\n\
-Succeeds or fails depending on <condition>; see HELP IF for <condition>s."));
-
-case XXFAIL:
- return(hmsg("Always fails."));
-
-case XXSUCC:
- return(hmsg("Always succeeds."));
-#endif /* NOSPL */
-
-#ifdef CK_LOGIN
-case XXLOGOUT:
- return(hmsg(
-"If you haved logged in to Kermit as an Internet Kermit server, the LOGOUT\n\
-command, given at the prompt, logs you out and closes your session."));
-#endif /* CK_LOGIN */
-
-case XXRESET:
- return(hmsg("Closes all open files and logs."));
-
-#ifndef NOCSETS
-case XXASSOC:
- return(hmsga(hmxxassoc));
-#endif /* NOCSETS */
-
-#ifndef NOSPL
-case XXSHIFT:
- return(hmsg("Syntax: SHIFT [ n ]\n\
- Shifts \\%1..9 variables n places to the left; default n = 1."));
-#endif /* NOSPL */
-
-#ifndef NOPUSH
-case XXMAN:
-#ifdef UNIX
- return(hmsg("Syntax: MANUAL [ topic ]\n\
- Runs the \"man\" command on the given topic (default \"kermit\")."));
-#else
-#ifdef OS2
- return(hmsg("Syntax: MANUAL\n\
- Accesses the Kermit 95 HTML manual using the current browser."));
-#else
- return(hmsg("Syntax: MANUAL [ topic ]\n\
- Runs the \"help\" command on the given topic (default \"kermit\")."));
-#endif /* OS2 */
-#endif /* UNIX */
-#endif /* NOPUSH */
-
-case XXWILD:
- return(hmsga(hmxxwild));
-
-#ifdef LOCUS
-case XXLOCU:
- return(hmsga(hmxylocus));
-#endif /* LOCUS */
-
-case XXPAT:
- return(hmsga(hmxxpat));
-
-#ifndef NOXFER
-case XXFAST:
-case XXCAU:
-case XXROB:
- return(hmsga(hmxxfast));
-#endif /* NOXFER */
-
-#ifdef CKPURGE
-case XXPURGE:
- return(hmsga(hmxxpurge));
-#else
-#ifdef VMS
-case XXPURGE:
- return(hmsga(hmxxpurge));
-#endif /* VMS */
-#endif /* CKPURGE */
-
-#ifndef NOXFER
- case XXRASG:
- return(hmsg(" RASG and RASSIGN are short forms of REMOTE ASSIGN."));
- case XXRCWD:
- return(hmsg(" RCD and RCWD are short forms of REMOTE CD."));
- case XXRCPY:
- return(hmsg(" RCOPY is a short form of REMOTE COPY."));
- case XXRDEL:
- return(hmsg(" RDELETE is a short form of REMOTE RELETE."));
- case XXRDIR:
- return(hmsg(" RDIRECTORY is a short form of REMOTE DIRECTORY."));
- case XXRXIT:
- return(hmsg(" REXIT is a short form of REMOTE EXIT."));
- case XXRHLP:
- return(hmsg(" RHELP is a short form of REMOTE HELP."));
- case XXRHOS:
- return(hmsg(" RHOST is a short form of REMOTE HOST."));
- case XXRKER:
- return(hmsg(" RKERMIT is a short form of REMOTE KERMIT."));
- case XXRMKD:
- return(hmsg(" RMKDIR is a short form of REMOTE MKDIR."));
- case XXRMSG:
- return(hmsg(" RMESSAGE and RMSG are short forms of REMOTE MESSAGE."));
- case XXRPRI:
- return(hmsg(" RPRINT is a short form of REMOTE PRINT."));
- case XXRPWD:
- return(hmsg(" RPWD is a short form of REMOTE PWD."));
- case XXRQUE:
- return(hmsg(" QUERY and RQUERY are short forms of REMOTE QUERY."));
- case XXRREN:
- return(hmsg(" RRENAME is a short form of REMOTE RENAME."));
- case XXRRMD:
- return(hmsg(" RRMDIR is a short form of REMOTE RMDIR."));
- case XXRSET:
- return(hmsg(" RSET is a short form of REMOTE SET."));
- case XXRSPA:
- return(hmsg(" RSPACE is a short form of REMOTE SPACE."));
- case XXRTYP:
- return(hmsg(" RTYPE is a short form of REMOTE TYPE."));
- case XXRWHO:
- return(hmsg(" RWHO is a short form of REMOTE WHO."));
-#endif /* NOXFER */
-
- case XXSCRN:
- return(hmsga(hmxxscrn));
-
-#ifdef CKEXEC
- case XXEXEC:
- return(hmsg("Syntax: EXEC <command> [ <arg1> [ <arg2> [ ... ] ]\n\
- C-Kermit overlays itself with the given system command and starts it with\n\
- the given arguments. Upon any error, control returns to C-Kermit."));
-#endif /* CKEXEC */
-
-#ifndef NOSPL
- case XXTRACE:
- return(hmsg(
-"Syntax: TRACE { /ON, /OFF } { ASSIGNMENTS, COMMAND-LEVEL, ALL }\n\
- Turns tracing of the given object on or off."));
-#endif /* NOSPL */
-
-#ifdef CK_PERMS
-#ifdef UNIX
- case XXCHMOD:
- return(hmsga(hmxxchmod));
-#endif /* UNIX */
-#endif /* CK_PERMS */
-
-#ifdef CKROOT
- case XXCHRT:
- return(hmsga(hmxxchroot));
-#endif /* CKROOT */
-
-#ifndef NOSPL
- case XXPROMP:
- return(hmsga(hmxxprompt));
-#endif /* NOSPL */
-
- case XXGREP:
- return(hmsga(hmxxgrep));
-
-#ifndef NOSEXP
-#ifndef NOSPL
- case XXSEXP:
- return(hmsga(hmxxsexp));
-#endif /* NOSPL */
-#endif /* NOSEXP */
-
-#ifdef CKLEARN
- case XXLEARN:
- return(hmsga(hmxxlearn));
-#endif /* CKLEARN */
-
-#ifdef ANYSSH
- case XXSSH:
- return(hmsga(hmxxssh));
-#endif /* ANYSSH */
-
-#ifdef TCPSOCKET
- case XXFIREW:
- return(hmsga(hmxxfirew));
-#endif /* TCPSOCKET */
-
-#ifdef NEWFTP
- case XXUSER:
- return(hmsg(" Equivalent to FTP USER."));
- case XXACCT:
- return(hmsg(" Equivalent to FTP ACCOUNT."));
-#endif /* NEWFTP */
-
- case XXORIE:
- return(hmsg(" Shows the directories important to Kermit."));
-
- case XXCONT:
- return(hmsg(" In a FOR or WHILE loop: continue the loop.\n\
- At the prompt: continue a script that has \"shelled out\" to the prompt."));
-
- case XXREDO:
- return(hmsg(" Syntax: REDO xxx (or) ^xxx\n\
- Re-executes the most recent command starting with xxx."));
-
-#ifdef UNIX
-#ifndef NOPUTENV
- case XXPUTE:
- return(hmsga(hmxxputenv));
-#endif /* NOPUTENV */
-#endif /* UNIX */
-
- case XXNOTAV:
- return(hmsg(" This command is not configured in this version of Kermit."));
-
-default: {
- char *s;
- if ((x = cmcfm()) < 0) return(x);
- s = cmdbuf + (int)strlen(cmdbuf) -1;
- while (s >= cmdbuf && *s == SP)
- *s-- = NUL;
- while (s >= cmdbuf && *s != SP)
- s--;
- while (*s == SP) s++;
- printf("Sorry, help not available for \"%s\"\n",s);
- break;
- }
- } /* switch */
-#endif /* NOHELP */
-
- return(success = 0);
-}
-
-/* H M S G -- Get confirmation, then print the given message */
-
-int
-hmsg(s) char *s; {
- int x;
- if ((x = cmcfm()) < 0) return(x);
- printf("\n%s\n\n",s);
- return(0);
-}
-
-#ifdef NOHELP
-
-int /* Print an array of lines, */
-hmsga(s) char *s[]; { /* cheap version. */
- int i;
- if ((i = cmcfm()) < 0) return(i);
- printf("\n"); /* Start off with a blank line */
- for (i = 0; *s[i]; i++) { /* Print each line. */
- printf("%s\n",s[i]);
- }
- printf("\n");
- return(0);
-}
-
-#else /* NOHELP not defined... */
-
-int /* Print an array of lines, */
-hmsga(s) char *s[]; { /* pausing at end of each screen. */
- extern int hmtopline; /* (This should be a parameter...) */
- int x, y, i, j, k, n;
- if ((x = cmcfm()) < 0) return(x);
-
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- /* Check whether window size changed */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
- printf("\n"); /* Start off with a blank line */
- n = (hmtopline > 0) ? hmtopline : 1; /* Line counter */
- for (i = 0; *s[i]; i++) {
- printf("%s\n",s[i]); /* Print a line. */
- y = (int)strlen(s[i]);
- k = 1;
- for (j = 0; j < y; j++) /* See how many newlines were */
- if (s[i][j] == '\n') k++; /* in the string... */
- n += k;
- if (n > (cmd_rows - 3) && *s[i+1]) /* After a screenful, give them */
- if (!askmore()) return(0); /* a "more?" prompt. */
- else n = 0;
- }
- printf("\n");
- return(0);
-}
-
-#ifndef NOFRILLS
-static char * supporttext[] = {
-
-"Live technical support for Kermit software is no longer available",
-"from Columbia University, as it was from mid-1981 until mid-2011 when",
-
-#ifdef OS2
-
-"the Kermit Project was cancelled. Beginning with version 3.0, Kermit 95",
-
-#else
-
-"the Kermit Project was cancelled. Beginning with version 9.0, C-Kermit",
-
-#endif /* OS2 */
-
-"is Open Source software. The Kermit website is supposed remain open",
-"indefinitely at:",
-" ",
-" http://kermit.columbia.edu/",
-" ",
-
-#ifdef OS2
-
-"The Kermit 95 page is here:",
-" ",
-" http://kermit.columbia.edu/k95.html",
-" ",
-"The Kermit 95 manual is here:",
-" ",
-" http://kermit.columbia.edu/k95manual/",
-" ",
-"The Kermit 95 Frequently Asked Questions page is here:",
-" ",
-" http://kermit.columbia.edu/k95faq.html",
-" ",
-"and many other resources are listed on the Kermit 95 home page.",
-" ",
-
-#else
-
-"The C-Kermit home page is here:",
-" ",
-" http://kermit.columbia.edu/ckermit.html",
-" ",
-"The documentation for C-Kermit is listed here:",
-" ",
-" http://kermit.columbia.edu/ckermit.html#doc",
-" ",
-"The C-Kermit Frequently Asked Questions page is here:",
-" ",
-" http://kermit.columbia.edu/ckfaq.html",
-" ",
-"and many other resources are listed on the C-Kermit home page.",
-" ",
-
-#endif /* OS2 */
-
-"Time will tell what sort of development and support structures arise",
-"in the Open Source community.",
-""
-};
-
-/* Do the BUG command */
-int
-dobug() {
- return(hmsga(supporttext));
-}
-#endif /* NOFRILLS */
-
-#ifndef NOXMIT
-static char *hsetxmit[] = {
-"Syntax: SET TRANSMIT parameter value",
-" ",
-"Controls the behavior of the TRANSMIT command (see HELP TRANSMIT):",
-" ",
-"SET TRANSMIT ECHO { ON, OFF }",
-" Whether to echo text to your screen as it is being transmitted.",
-" ",
-"SET TRANSMIT EOF text",
-" Text to send after end of file is reached, e.g. \\4 for Ctrl-D",
-" ",
-"SET TRANSMIT FILL number",
-" ASCII value of a character to insert into blank lines, 0 for none.",
-" Applies only to text mode. 0 by default.",
-" ",
-"SET TRANSMIT LINEFEED { ON, OFF }",
-" Transmit Linefeed as well as Carriage Return (CR) at the end of each line.",
-" Normally, only CR is sent.",
-" ",
-"SET TRANSMIT LOCKING-SHIFT { ON, OFF }",
-" Whether to use SO/SI for transmitting 8-bit data when PARITY is not NONE.",
-" ",
-"SET TRANSMIT PAUSE number",
-" How many milliseconds to pause after transmitting each line (text mode),",
-" or each character (binary mode).",
-" ",
-"SET TRANSMIT PROMPT number",
-" ASCII value of character to look for from host before sending next line",
-" when TRANSMITting in text mode; normally 10 (Linefeed). 0 means none;",
-" don't wait for a prompt.",
-" ",
-"SET TRANSMIT TIMEOUT number",
-" Number of seconds to wait for each character to echo when TRANSMIT ECHO",
-" is ON or TRANSMIT PROMPT is not 0. If 0 is specified, this means wait",
-" indefinitely for each echo.",
-" ",
-"Synonym: SET XMIT. SHOW TRANSMIT displays current settings.",
-"" };
-#endif /* NOXMIT */
-
-static char *hsetbkg[] = {
-"Syntax: SET BACKGROUND { OFF, ON }",
-" ",
-" SET BACKGROUND OFF forces prompts and messages to appear on your screen",
-" even though Kermit thinks it is running in the background.",
-"" };
-
-#ifdef DYNAMIC
-static char *hsetbuf[] = {
-"Syntax: SET BUFFERS n1 [ n2 ]",
-" ",
-" Changes the overall amount of memory allocated for SEND and RECEIVE packet",
-" buffers, respectively. Bigger numbers let you have longer packets and",
-" more window slots. If n2 is omitted, the same value as n1 is used.",
-#ifdef BIGBUFOK
-" ",
-" NOTE: This command is not needed in this version of Kermit, which is",
-" already configured for maximum-size packet buffers.",
-#endif /* BIGBUFOK */
-"" };
-#endif /* DYNAMIC */
-
-static char *hsetcmd[] = {
-"Syntax: SET COMMAND parameter value",
-" ",
-
-#ifdef CK_AUTODL
-"SET COMMAND AUTODOWNLOAD { ON, OFF }",
-" Enables/Disables automatic recognition of Kermit packets while in",
-" command mode. ON by default.",
-" ",
-#endif /* CK_AUTODL */
-
-"SET COMMAND BYTESIZE { 7, 8 }",
-" Informs Kermit of the bytesize of the communication path between itself",
-" and your keyboard and screen. 8 is assumed. SET COMMAND BYTE 7 only if",
-" 8-bit characters cannot pass.",
-" ",
-
-#ifdef OS2
-"SET COMMAND COLOR <foreground-color> <background-color>",
-" Lets you choose colors for Command screen. Use ? in the color fields to",
-" to get lists of available colors.",
-" ",
-"SET COMMAND CURSOR-POSITION <row> <column>",
-" Moves the command-screen cursor to the given position (1-based). This",
-" command should be used in scripts instead of relying on ANSI.SYS escape",
-" sequences.",
-" ",
-#endif /* OS2 */
-
-"SET COMMAND ERROR { 0,1,2,3 }",
-" Sets the verbosity level of command error messages; the higher the number,",
-" the more verbose the message. The default is 1. Higher values are",
-" useful only for debugging scripts.",
-" ",
-
-#ifdef OS2
-#ifdef NT
-"SET COMMAND HEIGHT <number>",
-" Changes the number of rows (lines) in your command screen, not",
-" counting the status line. Recommended values are 24, 42, and 49 (or 25,",
-" 43, and 50 if SET COMMAND STATUSLINE is OFF.)",
-#else
-"SET COMMAND HEIGHT <number>"
-" Changes the number of rows (lines) in your command screen, not",
-" counting the status line. Windowed sessions can use any value from 8 to",
-" 101. Fullscreen sessions are limited to 24, 42, 49, or 59. Not all"
-" heights are supported by all video adapters.",
-#endif /* NT */
-#else /* OS2 */
-"SET COMMAND HEIGHT <number>",
-" Informs Kermit of the number of rows in your command screen for the",
-" purposes of More?-prompting.",
-#endif /* OS2 */
-" ",
-"SET COMMAND WIDTH <number>",
-" Informs Kermit of the number of characters across your screen for",
-" purposes of screen formatting.",
-" ",
-"SET COMMAND MORE-PROMPTING { ON, OFF }",
-" ON (the default) enables More?-prompting when Kermit needs to display",
-" text that does not fit vertically on your screen. OFF allows the text to",
-" scroll by without intervention. If your command window has scroll bars,",
-" you might prefer OFF.",
-" ",
-
-#ifdef CK_RECALL
-"SET COMMAND RECALL-BUFFER-SIZE number",
-" How big you want Kermit's command recall buffer to be. By default, it",
-" holds 10 commands. You can make it any size you like, subject to memory",
-" constraints of the computer. A size of 0 disables command recall.",
-" Whenever you give this command, previous command history is lost.",
-" ",
-#endif /* CK_RECALL */
-
-"SET COMMAND QUOTING { ON, OFF }",
-" Whether to treat backslash and question mark as special characters (ON),",
-" or as ordinary data characters (OFF) in commands. ON by default.",
-" ",
-#ifdef DOUBLEQUOTING
-"SET COMMAND DOUBLEQUOTING { ON, OFF }",
-" Whether to allow doublequotes (\") to be used to enclose fields,",
-" filenames, directory names, and macro arguments that might contain",
-" spaces. ON by default; use OFF to force compatibility with older",
-" versions.",
-" ",
-#endif /* DOUBLEQUOTING */
-
-#ifdef CK_RECALL
-"SET COMMAND RETRY { ON, OFF }",
-" Whether to reprompt you with the correct but incomplete portion of a",
-" syntactically incorrect command. ON by default.",
-" ",
-#endif /* CK_RECALL */
-
-#ifdef OS2
-"SET COMMAND SCROLLBACK <lines>",
-" Sets size of virtual Command screen buffer to the given number of lines,",
-" which includes the active Command screen. The minimum is 256. The max",
-" is 2 million. The default is 512.",
-" ",
-"SET COMMAND STATUSLINE { ON, OFF }",
-" ON (default) enables the Kermit status line in the command screen.",
-" OFF removes it, making the line available for use by the host.",
-" ",
-#endif /* OS2 */
-
-"Use SHOW COMMAND to display these settings.",
-"" };
-
-#ifndef NOLOCAL
-static char *hsetcar[] = {
-"Syntax: SET CARRIER-WATCH { AUTO, OFF, ON }",
-" ",
-" Attempts to control treatment of carrier (the Data Carrier Detect signal)",
-" on serial communication (SET LINE or SET PORT) devices. ON means that",
-" carrier is required at all times. OFF means carrier is never required.",
-" AUTO (the default) means carrier is required at all times except during",
-" the DIAL command. Correct operation of carrier-watch depends on the",
-" capabilities of the underlying OS, drivers, devices, and cables. If you",
-" need to CONNECT to a serial device that is not asserting carrier, and",
-" Kermit won't let you, use SET CARRIER-WATCH OFF. Use SHOW COMMUNICATIONS",
-" to display the CARRIER-WATCH setting.",
-"" };
-#endif /* NOLOCAL */
-
-static char *hsetat[] = {
-"Syntax: SET ATTRIBUTES name ON or OFF",
-" ",
-" Use this command to enable (ON) or disable (OFF) the transmission of",
-" selected file attributes along with each file, and to handle or ignore",
-" selected incoming file attributes, including:",
-" ",
-#ifndef NOCSETS
-" CHARACTER-SET: The transfer character set for text files",
-#endif /* NOCSETS */
-" DATE: The file's creation date",
-" DISPOSITION: Unusual things to do with the file, like MAIL or PRINT",
-" LENGTH: The file's length",
-" PROTECTION: The file's protection (permissions)",
-" SYSTEM-ID: Machine/Operating system of origin",
-" TYPE: The file's type (text or binary)",
-" ",
-"You can also specify ALL to select all of them. Examples:",
-" ",
-" SET ATTR DATE OFF",
-" SET ATTR LENGTH ON",
-" SET ATTR ALL OFF",
-" ",
-"Also see HELP SET SEND and HELP SET RECEIVE.",
-""
-};
-
-static char *hxytak[] = {
-"Syntax: SET TAKE parameter value",
-" ",
-" Controls behavior of TAKE command:",
-" ",
-"SET TAKE ECHO { ON, OFF }",
-" Tells whether commands read from a TAKE file should be displayed on the",
-" screen (if so, each command is shown at the time it is read, and labeled",
-" with a line number).",
-" ",
-"SET TAKE ERROR { ON, OFF }",
-" Tells whether a TAKE command file should be automatically terminated when",
-" a command fails. This setting is local to the current command file, and",
-" inherited by subordinate command files.",
-"" };
-
-#ifndef NOLOCAL
-#ifdef OS2MOUSE
-static char *hxymouse[] = {
-"Syntax: SET MOUSE ACTIVATE { ON, OFF }",
-" Enables or disables the mouse in Connect mode. Default is ON",
-" ",
-"Syntax: SET MOUSE BUTTON <number> <key-modifier> <action> [ <text> ]",
-" where:",
-" <number> is the mouse button number, 1, 2, or 3;",
-" <key-modifier> denotes modifier keys held down during the mouse event:",
-" ALT, ALT-SHIFT, CTRL, CTRL-ALT CTRL-ALT-SHIFT, CTRL-SHIFT, SHIFT, NONE;",
-" <action> is the mouse action, CLICK, DRAG, or DOUBLE-CLICK.",
-" ",
-" The <text> has exactly the same properties as the <text> from the SET KEY",
-" command -- it can be a character, a string, one or more Kverbs, a macro",
-" invoked as a Kverb, or any combination of these. Thus, anything that can",
-" be assigned to a key can also be assigned to the mouse -- and vice versa.",
-" If the <text> is omitted, the action will be ignored. Examples:",
-" ",
-" SET MOUSE BUTTON 1 NONE DOUBLE \\KmouseCurPos",
-" SET MOU B 2 SHIFT CLICK help\\13",
-" ",
-" DRAG operations perform a \"mark mode\" selection of Text. You should",
-" assign only the following actions to drag operations:",
-" ",
-" \\Kdump - copy marked text to printer (or file)",
-" \\Kmarkcopyclip - copy marked text to PM Clipboard",
-" \\Kmarkcopyhost - copy marked text direct to Host",
-" \\Kmousemark - mark text, no copy operation performed",
-" ",
-" The following Kverb is only for use with the mouse:",
-" ",
-" \\KmouseCurPos",
-" ",
-" which represents the mouse-directed terminal cursor feature.",
-" ",
-"Syntax: SET MOUSE CLEAR",
-" Restores all mouse events to their default definitions",
-" Button 1 Ctrl-Click = Kverb: \\Kmouseurl",
-" Button 1 Double-Click = Kverb: \\Kmousecurpos",
-" Button 1 Drag = Kverb: \\Kmarkcopyclip",
-" Button 1 Alt-Drag = Kverb: \\Kmarkcopyclip_noeol",
-" Button 1 Ctrl-Drag = Kverb: \\Kmarkcopyhost",
-" Button 1 Ctrl-Alt-Drag = Kverb: \\Kmarkcopyhost_noeol",
-" Button 1 Ctrl-Shift-Drag = Kverb: \\Kdump",
-" Button 2 Double-Click = Kverb: \\Kpaste",
-" Button 2 Drag = Kverb: \\Kmarkcopyhost",
-" Button 2 Alt-Drag = Kverb: \\Kmarkcopyhost_noeol ",
-" Button 3 Double-Click = Kverb: \\Kpaste",
-""};
-#endif /* OS2MOUSE */
-
-static char *hxyterm[] = {
-"Syntax: SET TERMINAL parameter value",
-" ",
-#ifdef OS2
-"SET TERMINAL TYPE { ANSI, VT52, VT100, VT102, VT220, VT320, ... }",
-" Selects type type of terminal to emulate. Type SET TERMINAL TYPE ? to",
-" see a complete list.",
-" ",
-"SET TERMINAL ANSWERBACK { OFF, ON }",
-" Disables/enables the ENQ/Answerback sequence (\"K-95 version term-type\").",
-" ",
-"SET TERMINAL ANSWERBACK MESSAGE <extension>",
-" Allows you to specify an extension to the default answerback message.",
-" ",
-#else
-"SET TERMINAL TYPE ...",
-" This command is not available because this version of Kermit does not",
-" include a terminal emulator. Instead, it is a \"semitransparent pipe\"",
-" (or a totally transparent one, if you configure it that way) to the",
-" computer or service you have made a connection to. Your console,",
-" workstation window, or the terminal emulator or terminal from which you",
-" are running Kermit provides the emulation.",
-" ",
-#endif /* OS2 */
-
-#ifdef CK_APC
-"SET TERMINAL APC { ON, OFF, NO-INPUT, NO-INPUT-UNCHECKED, UNCHECKED }",
-#ifdef OS2
-" Controls execution of Application Program Commands sent by the host while",
-" K-95 is either in CONNECT mode or processing INPUT commands. ON allows",
-" execution of \"safe\" commands and disallows potentially dangerous ones",
-" such as DELETE, RENAME, OUTPUT, and RUN. OFF prevents execution of APCs.",
-" UNCHECKED allows execution of all APCs. OFF is the default.",
-#else /* OS2 */
-" Controls execution of Application Program Commands sent by the host while",
-" C-Kermit is in CONNECT mode. ON allows execution of \"safe\" commands and",
-" disallows potentially dangerous commands such as DELETE, RENAME, OUTPUT,",
-" and RUN. OFF prevents execution of APCs. UNCHECKED allows execution of",
-" all APCs. OFF is the default.",
-#endif /* OS2 */
-" ",
-#endif /* CK_APC */
-
-#ifdef OS2
-"SET TERMINAL ARROW-KEYS { APPLICATION, CURSOR }",
-" Sets the mode for the arrow keys during VT terminal emulation.",
-" ",
-"SET TERMINAL ATTRIBUTE { BLINK, DIM, PROTECTED, REVERSE, UNDERLINE }",
-" Determines how attributes are displayed by Kermit-95.",
-" ",
-"SET TERMINAL ATTRIBUTE { BLINK, DIM, REVERSE, UNDERLINE } { ON, OFF }",
-" Determines whether real Blinking, Dim, Reverse, and Underline are used in",
-" the terminal display. When BLINK is turned OFF, reverse background",
-" intensity is used. When DIM is turned OFF, dim characters appear BOLD.",
-" When REVERSE and UNDERLINE are OFF, the colors selected with SET",
-" TERMINAL COLOR { REVERSE,UNDERLINE } are used instead. This command",
-" affects the entire current screen and terminal scrollback buffer.",
-" ",
-"SET TERMINAL ATTRIBUTE PROTECTED [ -",
-" { BOLD, DIM, INVISIBLE, NORMAL, REVERSE, UNDERLINED } ]",
-" Sets the attributes used to represent Protected text in Wyse and Televideo",
-" terminal emulations. Any combination of attributes may be used. The",
-" default is DIM.)",
-" ",
-#endif /* OS2 */
-
-#ifdef OS2
-#ifdef CK_XYZ
-"SET TERMINAL AUTODOWNLOAD { ON, OFF, ERROR { STOP, CONTINUE } }",
-" enables/disables automatic switching into file-transfer mode when a Kermit",
-" or ZMODEM file transfer has been detected during CONNECT mode or while",
-" an INPUT command is active. Default is OFF.",
-#else
-"SET TERMINAL AUTODOWNLOAD { ON, OFF, ERROR { STOP, CONTINUE } }",
-" enables/disables automatic switching into file-transfer mode when a Kermit",
-" file transfer has been detected during CONNECT mode or while an INPUT",
-" command is active. Default is OFF.",
-#endif /* CK_XYZ */
-
-" ",
-" When TERMINAL AUTODOWNLOAD is ON, the TERMINAL AUTODOWNLOAD ERROR setting",
-" tells what to do if an error occurs during a file transfer or other",
-" protocol operation initiated by the terminal emulator: STOP (the default)",
-" means to remain in command mode so you can see what happened; CONTINUE",
-" means to resume the CONNECT session (e.g. so a far-end script can continue",
-" its work).",
-" ",
-
-#ifdef CK_XYZ
-"SET TERM... AUTO... { KERMIT, ZMODEM } C0-CONFLICTS { IGNORED, PROCESSED }",
-" Determines whether the active terminal emulator should process or ignore",
-" C0 control characters which are also used for the specified file transfer",
-" protocol. Kermit by default uses ^A (SOH) and Zmodem uses ^X (CAN).",
-" Default is PROCESSED.",
-" ",
-"SET TERM... AUTO... { KERMIT, ZMODEM } DETECTION-METHOD { PACKET, STRING }",
-" Determines whether the specified file transfer protocol should be detected",
-" by looking for valid packets or by identifying a specified text string.",
-" Default is PACKET.",
-" ",
-"SET TERM... AUTO... { KERMIT, ZMODEM } STRING <text>",
-" Lets you assign an autodownload detection string for use with the",
-" specified file transfer protocol.",
-" Default for Kermit is \"READY TO SEND...\", for Zmodem is \"rz\\{13}\".",
-" ",
-#else /* CK_XYZ */
-"SET TERM... AUTO... KERMIT C0-CONFLICTS { IGNORED, PROCESSED }",
-" Determines whether the active terminal emulator should process or ignore",
-" C0 control characters which are also used for the specified file transfer",
-" protocol. Kermit by default uses ^A <SOH>. Default is PROCESSED.",
-" ",
-"SET TERM... AUTO... KERMIT DETECTION-METHOD { PACKET, STRING }",
-" Determines whether the specified file transfer protocol should be detected",
-" by looking for valid packets or by identifying a specified text string.",
-" Default is PACKET.",
-" ",
-"SET TERM... AUTO... KERMIT STRING <text>",
-" Lets you assign an autodownload detection string for use with the",
-" specified file transfer protocol. Default is \"READY TO SEND...\".",
-" ",
-#endif /* CK_XYZ */
-"SET TERMINAL AUTOPAGE { ON, OFF }",
-" ",
-"SET TERMINAL AUTOSCROLL { ON, OFF }",
-" ",
-#else /* OS2 */
-"SET TERMINAL AUTODOWNLOAD { ON, OFF, ERROR { STOP, CONTINUE } }",
-" Enables/disables automatic switching into file-transfer mode when a valid",
-#ifdef CK_XYZ
-" Kermit or ZMODEM packet of the appropriate type is received during CONNECT",
-" mode. Default is OFF.",
-#else
-" Kermit packet of the appropriate type is received during CONNECT mode.",
-" Default is OFF.",
-#endif /* CK_XYZ */
-
-" ",
-" When TERMINAL AUTODOWNLOAD is ON, the TERMINAL AUTODOWNLOAD ERROR setting",
-" tells what to do if an error occurs during a file transfer or other",
-" protocol operation initiated by the terminal emulator: STOP (the default)",
-" means to remain in command mode so you can see what happened; CONTINUE",
-" means to resume the CONNECT session (e.g. so a far-end script can continue",
-" its work).",
-" ",
-
-#endif /* OS2 */
-
-#ifdef OS2
-"SET TERMINAL BELL { AUDIBLE, VISIBLE, NONE }",
-" Specifies how Control-G (bell) characters are handled. AUDIBLE means",
-" a beep is sounded; VISIBLE means the screen is flashed momentarily.",
-" ",
-" (This command has been superseded by SET BELL.)",
-" ",
-#endif /* OS2 */
-
-"SET TERMINAL BYTESIZE { 7, 8 }",
-" Use 7- or 8-bit characters between Kermit and the remote computer during",
-" terminal sessions. The default is 8.",
-" ",
-
-#ifndef NOCSETS
-#ifdef OS2
-"SET TERMINAL CHARACTER-SET <remote-cs>",
-" Specifies the character set used by the remote host, <remote-cs>.",
-" Equivalent to SET TERM REMOTE-CHARACTER-SET <remote-cs> ALL. For more",
-" control over the details, use SET TERM REMOTE-CHARACTER-SET and (in",
-" non-GUI K95 versions) SET TERM LOCAL-CHARACTER-SET; these are explained",
-" below. The default TERMINAL CHARACTER-SET is LATIN1 (ISO 8859-1).",
-#else /* not OS2 */
-"SET TERMINAL CHARACTER-SET <remote-cs> [ <local-cs> ]",
-" Specifies the character set used by the remote host, <remote-cs>, and the",
-" character set used by C-Kermit locally, <local-cs>. If you don't specify",
-" the local character set, the current FILE CHARACTER-SET is used. When",
-" you specify two different character sets, C-Kermit translates between them",
-" during CONNECT. By default, both character sets are TRANSPARENT, and",
-" no translation is done.",
-#endif /* OS2 */
-" ",
-#endif /* NOCSETS */
-
-#ifdef OS2
-
-"SET TERMINAL CODE-PAGE <number>",
-" Lets you change the PC code page. Only works for code pages that are",
-" successfully prepared in CONFIG.SYS. Use SHOW TERMINAL to list the",
-" current code page and the available code pages.",
-#ifdef OS2ONLY
-" ",
-" Also see SET TERMINAL FONT if the desired code page in not available in",
-" your version of OS/2.",
-#endif /* OS2ONLY */
-" ",
-
-#ifndef NT
-"SET TERMINAL COLOR BORDER <foreground>",
-#endif /* NT */
-"SET TERMINAL COLOR <screenpart> <foreground> <background>",
-" Sets the colors of the terminal emulation screen.",
-" <screenpart> may be any of the following:",
-" DEBUG, HELP-TEXT, REVERSE, SELECTION, STATUS-LINE, TERMINAL-SCREEN, or",
-" UNDERLINED-TEXT.",
-" <foreground> and <background> may be any of:",
-" BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LGRAY, DGRAY, LBLUE,",
-" LGREEN, LCYAN, LRED, LMAGENTA, YELLOW or WHITE.",
-" The L prefix for the color names means Light.",
-" ",
-
-"SET TERMINAL COLOR ERASE { CURRENT-COLOR, DEFAULT-COLOR }",
-" Determines whether the current color as set by the host or the default",
-" color as set by the user (SET TERMINAL COLOR TERMINAL) is used to clear",
-" the screen when erase commands are received from the host.",
-" ",
-
-"SET TERMINAL COLOR RESET-ON-ESC[0m { CURRENT-COLOR, DEFAULT-COLOR }",
-" Determines whether the current color or the default color is used after",
-" <ESC>[0m (\"reset attributes\") command sequence is received from the",
-" host.",
-" ",
-
-"SET TERMINAL CONTROLS { 7, 8 }",
-" Determines whether VT220/320 or Wyse 370 function keys, arrow keys, etc,",
-" that generate ANSI-format escape sequences should send 8-bit control",
-" characters or 7-bit escape sequences.",
-" ",
-#endif /* OS2 */
-
-"SET TERMINAL CR-DISPLAY { CRLF, NORMAL }",
-" Specifies how incoming carriage return characters are to be displayed",
-" on your screen.",
-" ",
-
-#ifdef OS2
-#ifdef KUI
-"SET TERMINAL CURSOR { FULL, HALF, UNDERLINE } {ON, OFF, NOBLINK}",
-" Selects the cursor style and visibility for the terminal screen.",
-#else
-"SET TERMINAL CURSOR { FULL, HALF, UNDERLINE } {ON, OFF}",
-" Selects the cursor style and visibility for the terminal screen.",
-#endif /* KUI */
-" ",
-#endif /* OS2 */
-
-"SET TERMINAL DEBUG { ON, OFF }",
-" Turns terminal session debugging on and off. When ON, incoming control",
-" characters are displayed symbolically, rather than be taken as formatting",
-" commands. SET TERMINAL DEBUG ON implies SET TELNET DEBUG ON.",
-" ",
-#ifdef OS2
-"SET TERMINAL DG-UNIX-MODE { ON, OFF }",
-" Specifies whether the Data General emulations should accept control",
-" sequences in Unix compatible format or in native DG format. The",
-" default is OFF, DG format.",
-" ",
-#endif /* OS2 */
-
-"SET TERMINAL ECHO { LOCAL, REMOTE }",
-" Specifies which side does the echoing during terminal connection.",
-" ",
-
-"SET TERMINAL ESCAPE-CHARACTER { ENABLED, DISABLED }",
-" Turns on/off the ability to escape back from CONNECT mode using the SET",
-#ifdef OS2
-" ESCAPE character. If you disable it you can still get back using Alt-key",
-" combinations as shown in the status line. Also see HELP SET ESCAPE.",
-#else
-" ESCAPE character. If you disable it, Kermit returns to its prompt only",
-" when the connection is closed by the other end. USE WITH EXTREME CAUTION.",
-" Also see HELP SET ESCAPE.",
-#endif /* OS2 */
-" ",
-
-#ifdef OS2
-#ifdef KUI
-"SET TERMINAL FONT <facename> <height>",
-" Specifies the font to be used in the Kermit 95 window. The font is",
-" determined by the choice of a facename and a height measured in Points.",
-" The available facenames are those installed in the Font Control Panel.",
-" ",
-#else /* KUI */
-#ifdef OS2ONLY
-"SET TERMINAL FONT { CP437, CP850, CP852, CP862, CP866, DEFAULT }",
-" CP437 - Original PC code page",
-" CP850 - \"Multilingual\" (West Europe) code page",
-" CP852 - East Europe Roman Alphabet code page (for Czech, Polish, etc)",
-" CP862 - Hebrew code page",
-" CP866 - Cyrillic (Russian, Belorussian, and Ukrainian) code page",
-" ",
-" Loads a soft into the video adapter for use during terminal emulation.",
-" Use this command when your OS/2 system does not have the desired code.",
-" page. Can be used only in full-screen sessions. Also see SET TERMINAL",
-" CODE-PAGE and SET TERMINAL REMOTE-CHARACTER-SET.",
-" ",
-#endif /* OS2ONLY */
-#endif /* KUI */
-
-#ifdef NT
-"SET TERMINAL HEIGHT <number>",
-" Changes the number of rows (lines) to use during terminal emulation, not",
-" counting the status line. Recommended values are 24, 42, and 49 (or 25,",
-" 43, and 50 if SET TERMINAL STATUSLINE is OFF.)",
-#else
-"SET TERMINAL HEIGHT <number>"
-" Changes the number of rows (lines) to use during terminal emulation, not",
-" counting the status line. Windowed sessions can use any value from 8 to",
-" 101. Fullscreen sessions are limited to 24, 42, 49, or 59. Not all"
-" heights are supported by all video adapters.",
-#endif /* NT */
-#else /* OS2 */
-"SET TERMINAL HEIGHT <number>",
-" Tells C-Kermit how many rows (lines) are on your CONNECT-mode screen.",
-#endif /* OS2 */
-" ",
-
-#ifdef CKTIDLE
-"SET TERMINAL IDLE-TIMEOUT <number>",
-" Sets the limit on idle time in CONNECT mode to the given number of",
-" seconds. 0 (the default) means no limit.",
-" ",
-"SET TERMINAL IDLE-ACTION { EXIT, HANGUP, OUTPUT [ text ], RETURN }",
-" Specifies the action to be taken when a CONNECT session is idle for the",
-" number of seconds given by SET TERMINAL IDLE-TIMEOUT. The default action",
-" is to RETURN to command mode. EXIT exits from Kermit; HANGUP hangs up the",
-" connection, and OUTPUT sends the given text to the host without leaving",
-" CONNECT mode; if no text is given a NUL (0) character is sent.",
-#ifdef TNCODE
-" ",
-"SET TERMINAL IDLE-ACTION { TELNET-NOP, TELNET-AYT }",
-" For TELNET connections only: Sends the indicated Telnet protocol message:",
-" No Operation (NOP) or \"Are You There?\" (AYT).",
-#endif /* TNCODE */
-" ",
-#endif /* CKTIDLE */
-
-#ifdef OS2
-
-"SET TERMINAL KDB-FOLLOWS-GL/GR { ON, OFF }",
-" Specifies whether or not the keyboard character set should follow the",
-" active GL and GR character sets. This feature is OFF by default and",
-" should not be used unless it is specificly required by the host",
-" application.",
-" ",
-
-"SET TERMINAL KEY <mode> /LITERAL <keycode> <text>",
-"SET TERMINAL KEY <mode> DEFAULT",
-"SET TERMINAL KEY <mode> CLEAR",
-" Configures the key whose <keycode> is given to send the given text when",
-" pressed while <mode> is active. <mode> may be any of the valid terminal",
-" types or the special modes \"EMACS\", \"HEBREW\" or \"RUSSIAN\". DEFAULT",
-" restores all default key mappings for the specified mode. CLEAR erases",
-" all the key mappings. If there is no text, the default key binding is",
-#ifndef NOCSETS
-" restored for the key k. SET TERMINAL KEY mappings take place before",
-" terminal character-set translation. SET KEY mappings take precedence over",
-" SET TERMINAL KEY <terminal type> settings.",
-#else
-" restored for the key. SET KEY mappings take precedence over SET TERMINAL",
-" KEY <terminal type> settings.",
-#endif /* NOCSETS */
-" The /LITERAL switch may be used to instruct Kermit to ignore character-set",
-" translations when sending this definition to the host.",
-" ",
-" The text may contain \"\\Kverbs\" to denote actions, to stand for DEC",
-" keypad, function, or editing keys, etc. For a list of available keyboard",
-" verbs, type SHOW KVERBS.",
-" ",
-" To find out the keycode and mapping for a particular key, use the SHOW",
-" KEY command. Use the SAVE KEYS command to save all settings to a file.",
-" ",
-"SET TERMINAL KEYBOARD-MODE { NORMAL, EMACS, RUSSIAN, HEBREW }",
-" Select a special keyboard mode for use in the terminal screen.",
-" ",
-
-"SET TERMINAL KEYPAD-MODE { APPLICATION, NUMERIC }",
-" Specifies the \"mode\" of the numeric keypad for VT terminal emulation.",
-" Use this command in case the host or application wants the keypad to be",
-" in a different mode than it's in, but did not send the escape sequence",
-" to put it in the needed mode.",
-" ",
-
-#endif /* OS2 */
-
-"SET TERMINAL LF-DISPLAY { CRLF, NORMAL }",
-" Specifies how incoming linefeed characters are to be displayed",
-" on your screen.",
-" ",
-
-#ifdef OS2
-
-#ifdef KUI
-"SET TERMINAL LINE-SPACING <float>",
-" Specifies the line spacing used when displaying text. The default is 1.0.",
-" Valid values range from 1.0 to 3.0 inclusive.",
-" ",
-#endif /* KUI */
-#endif /* OS2 */
-
-#ifndef NOCSETS
-#ifdef OS2
-"SET TERMINAL LOCAL-CHARACTER-SET <local-cs>",
-" Specifies the character set used by K-95 locally. If you don't specify",
-#ifdef OS2ONLY
-" the local character-set, the current TERMINAL FONT is used if you have",
-" given a SET TERMINAL FONT command; otherwise the current codepage is used.",
-#else
-" the local character-set, the current code page is used.",
-#endif /* OS2ONLY */
-" ",
-" When the local and remote character sets differ, Kermit translates between",
-" them during CONNECT. By default, the remote character set is Latin1 and",
-" the local one is your current code page.",
-#ifdef NT
-" ",
-" In Windows NT, Unicode is used as the local character-set regardless of",
-" this setting.",
-#endif /* NT */
-" ",
-"See also SET TERMINAL REMOTE-CHARACTER-SET",
-" ",
-#endif /* OS2 */
-#endif /* NOCSETS */
-
-#ifdef OS2
-"SET TERMINAL LOCKING-SHIFT { OFF, ON }",
-" Tells whether to send Shift-In/Shift-Out (Ctrl-O and Ctrl-N) to switch",
-" between 7-bit and 8-bit characters sent during terminal emulation over",
-" 7-bit connections. OFF by default.",
-#else
-"SET TERMINAL LOCKING-SHIFT { OFF, ON }",
-" Tells Kermit whether to use Shift-In/Shift-Out (Ctrl-O and Ctrl-N) to",
-" switch between 7-bit and 8-bit characters during CONNECT. OFF by default.",
-#endif /* OS2 */
-" ",
-
-#ifdef OS2
-"SET TERMINAL MARGIN-BELL { ON [column], OFF }",
-" Determines whether the margin-bell is activated and what column it should",
-" ring at. OFF by default.",
-" ",
-#endif /* OS2 */
-
-"SET TERMINAL NEWLINE-MODE { OFF, ON }",
-" Tells whether to send CRLF (Carriage Return and Line Feed) when you type",
-" CR (press the Return or Enter key) in CONNECT mode.",
-" ",
-
-#ifdef OS2
-"SET TERMINAL OUTPUT-PACING <milliseconds>",
-" Tells how long to pause between sending each character to the host during",
-" CONNECT mode. Normally not needed but sometimes required to work around",
-" TRANSMISSION BLOCKED conditions when pasting into the terminal window.",
-" ",
-
-#ifdef PCTERM
-"SET TERMINAL PCTERM { ON, OFF }",
-" Activates or deactivates the PCTERM terminal emulation keyboard mode.",
-" When PCTERM is ON all keystrokes in the terminal screen are sent to the",
-" host as make/break (down/up) codes instead of as characters from the",
-" REMOTE-CHARACTER-SET, and all keyboard mappings, including Kverbs and the",
-" escape character are disabled. To turn off PCTERM keyboard mode while in",
-" CONNECT mode press Control-CapsLock. PCTERM is OFF by default.",
-" ",
-#endif /* PCTERM */
-#endif /* OS2 */
-
-#ifdef OS2
-"SET TERMINAL PRINT { AUTO, COPY, OFF, USER }",
-" Allows selective control of various types of printing from the Terminal",
-" session. AUTO prints a line of text from the terminal screen whenever",
-" the cursor is moved off the line. COPY prints every byte received as",
-" it is received without interpretation. USER prints every byte after",
-" interpretation by the terminal emulator translates character-sets and",
-" construct escape sequences, ... The default is OFF.",
-" ",
-#else
-#ifdef XPRINT
-"SET TERMINAL PRINT { ON, OFF }",
-" Enables and disables host-initiated transparent printing in CONNECT mode.",
-" ",
-#endif /* XPRINT */
-#endif /* OS2 */
-
-#ifdef OS2
-#ifndef NOCSETS
-"SET TERMINAL REMOTE-CHARACTER-SET <remote-cs> [ { G0,G1,G2,G3 }... ]",
-" Specifies the character set used by the remote host, <remote-cs>.",
-" When the local and remote character sets differ, Kermit translates",
-" between them during CONNECT. By default, the remote character set is",
-" Latin1 and the local one is your current code page. Optionally, you can",
-" also designate the character set to the G0..G3 graphic tables.",
-" ",
-#endif /* NOCSETS */
-#endif /* OS2 */
-
-#ifdef OS2
-"SET TERMINAL ROLL-MODE { INSERT, OVERWRITE, KEYSTROKES [ option ] }",
-" Tells whether new data when received from the host is entered into the",
-" scrollback buffer at the current rollback position (OVERWRITE) or at the",
-" end of the buffer (INSERT). The default is INSERT. Typing is allowed",
-" during rollbacks in either mode, according to SET TERM ROLL KEYSTROKES:",
-" SEND (the default) means to process keystrokes normally; IGNORE means to",
-" ignore them when the screen is scrolled back; RESTORE-AND-SEND is like",
-" SEND but restores the screen to its active position first.",
-" ",
-
-"SET TERMINAL SCREEN-MODE { NORMAL, REVERSE }",
-" When set to REVERSE the foreground and background colors are swapped as",
-" well as the application of the foreground and background intensity bits.",
-" The default is NORMAL.",
-" ",
-
-"SET TERMINAL SCREEN-OPTIMIZE { ON, OFF }",
-" When set to ON, the default, Kermit only paints the screen with characters",
-" that have changed since the last screen paint. When OFF, the screen is",
-" completely repainted each time there is a change.",
-" ",
-
-"SET TERMINAL SCREEN-UPDATE { FAST, SMOOTH } [ <milliseconds> ]",
-" Chooses the mechanism used for screen updating and the update frequency.",
-" Defaults are FAST scrolling with updates every 100 milliseconds.",
-" ",
-
-"SET TERMINAL SCROLLBACK <lines>",
-" Sets size of CONNECT virtual screen buffer. <lines> includes the active",
-" terminal screen. The minimum is 256. The maximum is 2 million. The",
-" default is 2000.",
-" ",
-
-"SET TERMINAL SEND-DATA { ON, OFF }",
-" Determines whether ASCII emulations such as WYSE 30,50,60 or TVI 910+,925,",
-" 950 may send their screen contents to the host upon request. Allowing the",
-" screen to be read by the host is a significant security risk. The default",
-" is OFF and should only be changed after a security evaluation of host",
-" environment.",
-" ",
-
-"SET TERMINAL SEND-END-OF-BLOCK { CRLF_ETX, US_CR }",
-" Determines which set of characters should be used as end of line and end",
-" of transmission indicators when sending screen data to the host",
-" ",
-
-"SET TERMINAL SGR-COLORS { ON, OFF }",
-" ON (default) means allow host control of colors; OFF means ignore host",
-" escape sequences to set color.",
-" ",
-
-"SET TERMINAL SNI-CH.CODE { ON, OFF }",
-" This command controls the state of the CH.CODE key. It is the equivalent",
-" to the SNI_CH_CODE Keyboard verb. The SNI terminal uses CH.CODE to",
-" easily switch between the National Language character set and U.S. ASCII.",
-" The default is ON which means to display characters as U.S. ASCII. When",
-" OFF the lanuage specified by SET TERMINAL SNI-LANUAGE is used to display",
-" characters when 7-bit character sets are in use.",
-" ",
-"SET TERMINAL SNI-FIRMWARE-VERSIONS <kbd-version> <terminal-version>",
-" Specifies the Firmware Version number that should be reported to the host",
-" when the terminal is queried. The default is 920031 for the keyboard",
-" and 830851 for the terminal.",
-" ",
-"SET TERMINAL SNI-LANGUAGE <national-language>",
-" An alias for SET TERMINAL VT-LANUAGE, this command specifies the national",
-" language character-set that should be used when the NRC mode is activated",
-" for VT emulations or when CH.CODE is OFF for SNI emulations. The default",
-" language for SET TERMINAL TYPE SNI-97801 is \"German\".",
-" ",
-"SET TERMINAL SNI-PAGEMODE { ON, OFF }",
-" Determines whether or not page mode is active. OFF by default.",
-" ",
-"SET TERMINAL SNI-SCROLLMODE { ON, OFF }",
-" Determines whether or not scroll mode is active. OFF by default.",
-" ",
-"SET TERMINAL STATUSLINE { ON, OFF }",
-" ON (default) enables the Kermit status line in the terminal screen.",
-" OFF removes it, making the line available for use by the host.",
-" ",
-
-"SET TERMINAL TRANSMIT-TIMEOUT <seconds>",
-" Specifies the maximum amount of time K-95 waits before returning to the",
-" prompt if your keystrokes can't be transmitted for some reason, such as a",
-" flow-control deadlock.",
-" ",
-#endif /* OS2 */
-
-#ifdef CK_TRIGGER
-"SET TERMINAL TRIGGER <string>",
-" Specifies a string that, when detected during any subsequent CONNECT",
-" session, is to cause automatic return to command mode. Give this command",
-" without a string to cancel the current trigger. See HELP CONNECT for",
-" additional information.",
-" ",
-#endif /* CK_TRIGGER */
-
-#ifdef OS2
-"SET TERMINAL URL-HIGHLIGHT { ON <attribute>, OFF }",
-" Specifies whether K-95 should highlight URLs and which screen attribute",
-" should be used. The screen attributes can be one of NORMAL, BLINK, BOLD,",
-" DIM, INVISIBLE, REVERSE, or UNDERLINE. The default is ON using the",
-" BOLD screen attribute.",
-" ",
-"SET TERMINAL VIDEO-CHANGE { DISABLED, ENABLED }",
-" Specifies whether K-95 should change video modes automatically in response",
-#ifdef NT
-" to escape sequences from the other computer. ENABLED by default (except",
-" on Windows 95).",
-#else /* NT */
-" to escape sequences from the other computer. ENABLED by default.",
-#endif /* NT */
-" ",
-
-"SET TERMINAL VT-LANGUAGE <language>",
-" Specifies the National Replacement Character Set (NRC) to be used when",
-" NRC mode is activated. The default is \"North American\".",
-" ",
-"SET TERMINAL VT-NRC-MODE { ON, OFF }",
-" OFF (default) chooses VT multinational Character Set mode. OFF chooses",
-" VT National Replacement Character-set mode. The NRC is selected with",
-" SET TERMINAL VT-LANGUAGE",
-" ",
-
-#ifdef NT
-"SET TERMINAL WIDTH <cols>",
-" Tells the number of columns in the terminal screen.",
-" ",
-" The default is 80. You can also use 132. Other widths can be chosen but",
-" are usually not supported by host software.",
-" ",
-#else
-"SET TERMINAL WIDTH <cols>",
-" Tells how many columns define the terminal size.",
-" ",
-"Default is 80. In Windowed OS/2 2.x sessions, this value may not be changed",
-"In Windowed OS/2 WARP 3.x sessions, this value may range from 20 to 255.",
-"In Full screen sessions, values of 40, 80, and 132 are valid. Not all",
-"combinations of height and width are supported on all adapters.",
-" ",
-#endif /* NT */
-"SET TERMINAL WRAP { OFF, ON }",
-" Tells whether the terminal emulator should automatically wrap long lines",
-" on your screen.",
-" ",
-#else
-
-"SET TERMINAL WIDTH <number>",
-" \
-Tells Kermit how many columns (characters) are on your CONNECT-mode screen.",
-" ",
-#endif /* OS2 */
-"Type SHOW TERMINAL to see current terminal settings.",
-"" };
-#endif /* NOLOCAL */
-
-#ifdef NETCONN
-static char *hxyhost[] = {
-"SET HOST [ switches ] hostname-or-address [ service ] [ protocol-switch ]",
-" Establishes a connection to the specified network host on the currently",
-" selected network type. For TCP/IP connections, the default service is",
-" TELNET; specify a different TCP port number or service name to choose a",
-" different service. The first set of switches can be:",
-" ",
-" /NETWORK-TYPE:name",
-" Makes the connection on the given type of network. Equivalent to SET",
-" NETWORK TYPE name prior to SET HOST, except that the selected network",
-" type is used only for this connection. Type \"set host /net:?\" to see",
-#ifdef NETCMD
-" a list. /NETWORK-TYPE:COMMAND means to make the connection through the",
-" given system command, such as \"rlogin\" or \"cu\".",
-#else
-" a list.",
-#endif /* NETCMD */
-" ",
-" /CONNECT",
-" \
-Enter CONNECT (terminal) mode automatically if the connection is successful.",
-" ",
-" /SERVER",
-" Enter server mode automatically if the connection is successful.",
-" ",
-" /USERID:[<name>]",
-" This switch is equivalent to SET LOGIN USERID <name> or SET TELNET",
-" ENVIRONMENT USER <name>. If a string is given, it sent to host during",
-" Telnet negotiations; if this switch is given but the string is omitted,",
-" no user ID is sent to the host. If this switch is not given, your",
-" current USERID value, \\v(userid), is sent. When a userid is sent to the",
-" host it is a request to login as the specified user.",
-" ",
-#ifdef CK_AUTHENTICATION
-" /PASSWORD:[<string>]",
-" This switch is equivalent to SET LOGIN PASSWORD. If a string is given,",
-" it is treated as the password to be used (if required) by any Telnet",
-" Authentication protocol (Kerberos Ticket retrieval, Secure Remote",
-" Password, or X.509 certificate private key decryption.) If no password",
-" switch is specified a prompt is issued to request the password if one",
-" is required for the negotiated authentication method.",
-" ",
-#endif /* CK_AUTHENTICATION */
-"The protocol-switches can be:",
-" ",
-" /NO-TELNET-INIT",
-" Do not send initial Telnet negotiations even if this is a Telnet port.",
-" ",
-" /RAW-SOCKET",
-" This is a connection to a raw TCP socket.",
-" ",
-#ifdef RLOGCODE
-" /RLOGIN",
-" Use Rlogin protocol even if this is not an Rlogin port.",
-" ",
-#endif /* RLOGCODE */
-" /TELNET",
-" Send initial Telnet negotiations even if this is not a Telnet port.",
-" ",
-#ifdef CK_KERBEROS
-#ifdef RLOGCODE
-#ifdef KRB4
-" /K4LOGIN",
-" Use Kerberos IV klogin protocol even if this is not a klogin port.",
-" ",
-#ifdef CK_ENCRYPTION
-" /EK4LOGIN",
-" Use Kerberos IV Encrypted login protocol even if this is not an eklogin",
-" port.",
-" ",
-#endif /* CK_ENCRYPTION */
-#endif /* KRB4 */
-#ifdef KRB5
-" /K5LOGIN",
-" Use Kerberos V klogin protocol even if this is not a klogin port.",
-" ",
-#ifdef CK_ENCRYPTION
-" /EK5LOGIN",
-" Use Kerberos V Encrypted login protocol even if this is not an eklogin",
-" port.",
-" ",
-#endif /* CK_ENCRYPTION */
-#endif /* KRB5 */
-#endif /* RLOGCODE */
-#endif /* CK_KERBEROS */
-#ifdef CK_SSL
-" /SSL",
-" Perform SSL negotiations.",
-" ",
-" /SSL-TELNET",
-" Perform SSL negotiations and if successful start Telnet negotiations.",
-" ",
-" /TLS",
-" Perform TLS negotiations.",
-" ",
-" /TLS-TELNET",
-" Perform TLS negotiations and if successful start Telnet negotiations.",
-" ",
-#endif /* CK_SSL */
-"Examples:",
-" SET HOST kermit.columbia.edu",
-" SET HOST /CONNECT kermit.columbia.edu",
-" SET HOST * 1649",
-" SET HOST /SERVER * 1649",
-" SET HOST 128.59.39.2",
-" SET HOST madlab.sprl.umich.edu 3000",
-" SET HOST xyzcorp.com 2000 /RAW-SOCKET",
-#ifdef SSHBUILTIN
-" SET HOST /NET:SSH kermit.columbia.edu /x11-forwarding:on",
-#endif /* SSHBUILTIN */
-#ifdef NETCMD
-" SET HOST /CONNECT /COMMAND rlogin xyzcorp.com",
-#endif /* NETCMD */
-" ",
-#ifdef SUPERLAT
-"Notes:",
-" ",
-" . The TELNET command is equivalent to SET NETWORK TYPE TCP/IP,",
-" SET HOST name [ port ] /TELNET, IF SUCCESS CONNECT",
-" ",
-" . For SUPERLAT connections, the hostname-or-address may be either a service",
-" name, or a node/port combination, as required by your LAT host.",
-#else
-"The TELNET command is equivalent to SET NETWORK TYPE TCP/IP,",
-"SET HOST name [ port ] /TELNET, IF SUCCESS CONNECT",
-#endif /* SUPERLAT */
-" ",
-"Also see SET NETWORK, TELNET, SET TELNET.",
-"" };
-
-static char *hmxyauth[] = {
-"Synatx: SET AUTHENTICATION <auth_type> <parameter> <value>",
-" Sets defaults for the AUTHENTICATE command:",
-" ",
-#ifdef CK_KERBEROS
-"SET AUTHENTICATION KERBEROS5 ADDRESSES {list of ip-addresses}",
-" Specifies a list of IP addresses that should be placed in the Ticket",
-" Getting Ticket in addition to the local machine addresses.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } AUTODESTROY",
-" { ON-CLOSE, ON-EXIT, NEVER }",
-" When ON, Kermit will destroy all credentials in the default",
-" credentials cache upon Kermit termination. Default is NEVER.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } AUTOGET { ON, OFF }",
-" When ON, if the host offers Kerberos 4 or Kerberos 5 authentication",
-" and Kermit is configured to use that authentication method and there",
-" is no TGT, Kermit will automatically attempt to retrieve one by",
-" prompting for the password (and principal if needed.) Default is ON.",
-" ",
-"SET AUTHENTICATION KERBEROS5 CREDENTIALS-CACHE <filename>",
-" Allows an alternative credentials cache to be specified. This is useful",
-" when you need to maintain two or more sets of credentials for different",
-" realms or roles. The default is specified by the environment variable",
-" KRB5CCNAME or as reported by the Kerberos 5 library.",
-" ",
-"SET AUTHENTICATION KERBEROS5 FORWARDABLE { ON, OFF }",
-" When ON, specifies that Kerberos 5 credentials should be forwardable to",
-" the host. If SET TELNET AUTHENTICATION FORWARDING is ON, forwardable",
-" credentials are sent to the host. The default is OFF.",
-" ",
-"SET AUTHENTICATION KERBEROS5 GET-K4-TGT { ON, OFF }",
-" When ON, specifies that Kerberos 4 credentials should be requested each",
-" time Kerberos 5 credentials are requested with AUTH KERBEROS5 INIT.",
-" Default is OFF.",
-" ",
-"SET AUTHENTICATION KERBEROS4 INSTANCE <instance>",
-" Allows a Kerberos 4 instance to be specified as a default (if needed).",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } KEYTAB <filename>",
-" Specifies the location of the keytab file used to authenticate incoming",
-" connections. The default is none, which means to use the default value",
-" configured in the Kerberos installation.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } LIFETIME <minutes>",
-" Specifies the lifetime of the TGTs requested from the KDC. The default",
-" is 600 minutes (10 hours).",
-" ",
-"SET AUTHENTICATION KERBEROS5 NO-ADDRESSES { ON, OFF }",
-" Specifies whether or not IP addresses will be inserted into the TGT."
-" Default is OFF.",
-" ",
-"SET AUTHENTICATION KERBEROS4 PREAUTH { ON, OFF }",
-" Allows Kerberos 4 preauthenticated TGT requests to be turned off. The",
-" default is ON. Only use if absolutely necessary. We recommend that",
-" preauthenticated requests be required for all tickets returned by a KDC",
-" to a requestor.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } PRINCIPAL <name>",
-" When Kermit starts, it attempts to set the principal name to that stored",
-" in the current credentials cache. If no credential cache exists, the",
-" current SET LOGIN USERID value is used. SET LOGIN USERID is set to the",
-" operating system's current username when Kermit is started. To force",
-" Kermit to prompt the user for the principal name when requesting TGTs,",
-" place:",
-" ",
-" SET AUTH K4 PRINCIPAL {}",
-" SET AUTH K5 PRINCIPAL {}",
-" ",
-" in the Kermit initialization file or connection script.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } PROMPT PASSWORD <prompt>",
-" Specifies a custom prompt to be used when prompting for a password.",
-" The Kerberos prompt strings may contain two %s replacement fields.",
-" The first %s is replaced by the principal name; the second by the realm.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } PROMPT PRINCIPAL <prompt>",
-" Specifies a custom prompt to be used when prompting for the Kerberos",
-" principal name. No %s replacement fields may be used. Kermit prompts",
-" for a principal name when retrieving a TGT if the command:",
-" ",
-" SET AUTHENTICATION { KERBEROS4, KERBEROS5 } PRINCIPAL {}",
-" ",
-" has been issued.",
-" ",
-"SET AUTHENTICATION KERBEROS5 PROXIABLE { ON, OFF }",
-" When ON, specifies that Kerberos 5 credentials should be proxiable.",
-" Default is OFF.",
-" ",
-"SET AUTHENTICATION KERBEROS5 RENEWABLE <minutes>",
-" When <minutes> is greater than the ticket lifetime a TGT may be renewed",
-" with AUTH K5 INIT /RENEW instead of getting a new ticket as long as the",
-" ticket is not expired and its within the renewable lifetime. Default is",
-" 0 (zero) minutes.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } REALM <name>",
-" If no default is set, the default realm configured for the Kerberos",
-" libraries is used. Abbreviations accepted.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } SERVICE-NAME <name>",
-" This command specifies the service ticket name used to authenticate",
-" to the host when Kermit is used as a client; or the service ticket",
-" name accepted by Kermit when it is acting as the host.",
-" If no default is set, the default service name for Kerberos 4 is",
-" \"rcmd\" and for Kerberos 5 is \"host\".",
-" ",
-#endif /* CK_KERBEROS */
-#ifdef CK_SRP
-"SET AUTHENTICATION SRP PROMPT PASSWORD <prompt>",
-" Specifies a custom prompt to be used when prompting for a password.",
-" The SRP prompt string may contain one %s replacement fields which is",
-" replaced by the login userid.",
-" ",
-#endif /* CK_SRP */
-#ifdef CK_SSL
-"In all of the following commands \"SSL\" and \"TLS\" are aliases.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } CIPHER-LIST <list of ciphers>",
-"Applies to both SSL and TLS. A colon separated list of any of the following",
-"(case sensitive) options depending on the options chosen when OpenSSL was ",
-"compiled: ",
-" ",
-" Key Exchange Algorithms:",
-" \"kRSA\" RSA key exchange",
-" \"kDHr\" Diffie-Hellman key exchange (key from RSA cert)",
-" \"kDHd\" Diffie-Hellman key exchange (key from DSA cert)",
-" \"kEDH\" Ephemeral Diffie-Hellman key exchange (temporary key)",
-" \"kKRB5\" Kerberos 5",
-" ",
-" Authentication Algorithm:",
-" \"aNULL\" No authentication",
-" \"aRSA\" RSA authentication",
-" \"aDSS\" DSS authentication",
-" \"aDH\" Diffie-Hellman authentication",
-" \"aKRB5\" Kerberos 5",
-" ",
-" Cipher Encoding Algorithm:",
-" \"eNULL\" No encodiing",
-" \"DES\" DES encoding",
-" \"3DES\" Triple DES encoding",
-" \"RC4\" RC4 encoding",
-" \"RC2\" RC2 encoding",
-" \"IDEA\" IDEA encoding",
-" ",
-" MAC Digest Algorithm:",
-" \"MD5\" MD5 hash function",
-" \"SHA1\" SHA1 hash function",
-" \"SHA\" SHA hash function (should not be used)",
-" ",
-" Aliases:",
-" \"SSLv2\" all SSL version 2.0 ciphers (should not be used)",
-" \"SSLv3\" all SSL version 3.0 ciphers",
-" \"EXP\" all export ciphers (40-bit)",
-" \"EXPORT56\" all export ciphers (56-bit)",
-" \"LOW\" all low strength ciphers (no export)",
-" \"MEDIUM\" all ciphers with 128-bit encryption",
-" \"HIGH\" all ciphers using greater than 128-bit encryption",
-" \"RSA\" all ciphers using RSA key exchange",
-" \"DH\" all ciphers using Diffie-Hellman key exchange",
-" \"EDH\" all ciphers using Ephemeral Diffie-Hellman key exchange",
-" \"ADH\" all ciphers using Anonymous Diffie-Hellman key exchange",
-" \"DSS\" all ciphers using DSS authentication",
-" \"KRB5\" all ciphers using Kerberos 5 authentication",
-" \"NULL\" all ciphers using no encryption",
-" ",
-"Each item in the list may include a prefix modifier:",
-" ",
-" \"+\" move cipher(s) to the current location in the list",
-" \"-\" remove cipher(s) from the list (may be added again by",
-" a subsequent list entry)",
-" \"!\" kill cipher from the list (it may not be added again",
-" by a subsequent list entry)",
-" ",
-"If no modifier is specified the entry is added to the list at the current ",
-"position. \"+\" may also be used to combine tags to specify entries such as "
-,
-"\"RSA+RC4\" describes all ciphers that use both RSA and RC4.",
-" ",
-"For example, all available ciphers not including ADH key exchange:",
-" ",
-" ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP",
-" ",
-"All algorithms including ADH and export but excluding patented algorithms: ",
-" ",
-" HIGH:MEDIUM:LOW:EXPORT56:EXP:ADH:!kRSA:!aRSA:!RC4:!RC2:!IDEA",
-" ",
-"The OpenSSL command ",
-" ",
-" openssl.exe ciphers -v <list of ciphers> ",
-" ",
-"may be used to list all of the ciphers and the order described by a specific",
-"<list of ciphers>.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } CRL-DIR <directory>",
-"specifies a directory that contains certificate revocation files where each",
-"file is named by the hash of the certificate that has been revoked.",
-" ",
-" OpenSSL expects the hash symlinks to be made like this:",
-" ",
-" ln -s crl.pem `openssl crl -hash -noout -in crl.pem`.r0",
-" ",
-" Since not all file systems have symlinks you can use the following command",
-" in Kermit to copy the crl.pem file to the hash file name.",
-" ",
-" copy crl.pem {\\fcommand(openssl.exe crl -hash -noout -in crl.pem).r0}",
-" ",
-" This produces a hash based on the issuer field in the CRL such ",
-" that the issuer field of a Cert may be quickly mapped to the ",
-" correct CRL.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } CRL-FILE <filename>",
-"specifies a file that contains a list of certificate revocations.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } DEBUG { ON, OFF }",
-"specifies whether debug information should be displayed about the SSL/TLS",
-"connection. When DEBUG is ON, the VERIFY command does not terminate",
-"connections when set to FAIL-IF-NO-PEER-CERT when a certificate is",
-"presented that cannot be successfully verified. Instead each error",
-"is displayed but the connection automatically continues.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } DH-PARAM-FILE <filename>",
-" Specifies a file containing DH parameters which are used to generate",
-" temporary DH keys. If a DH parameter file is not provided Kermit uses a",
-" fixed set of parameters depending on the negotiated key length. Kermit",
-" provides DH parameters for key lengths of 512, 768, 1024, 1536, and 2048",
-" bits.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } DSA-CERT-CHAIN-FILE <filename>",
-" Specifies a file containing a DSA certificate chain to be sent along with",
-" the DSA-CERT to the peer. This file must only be specified if Kermit is",
-" being used as a server and the DSA certificate was signed by an",
-" intermediary certificate authority.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } DSA-CERT-FILE <filename>",
-" Specifies a file containing a DSA certificate to be sent to the peer to ",
-" authenticate the host or end user. The file may contain the matching DH ",
-" private key instead of using the DSA-KEY-FILE command.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } DSA-KEY-FILE <filename>",
-"Specifies a file containing the private DH key that matches the DSA ",
-"certificate specified with DSA-CERT-FILE. This command is only necessary if",
-"the private key is not appended to the certificate in the file specified by",
-"DSA-CERT-FILE.",
-" ",
-" Note: When executing a script in the background or when it is",
-" running as an Internet Kermit Service Daemon, Kermit cannot support ",
-" encrypted private keys. When attempting to load a private key that is",
-" encrypted, a prompt will be generated requesting the passphrase necessary",
-" to decrypt the keyfile. To automate access to the private key you must",
-" decrypt the encrypted keyfile and create an unencrypted keyfile for use",
-" by Kermit. This can be accomplished by using the following command and",
-" the passphrase:",
-" ",
-" openssl dsa -in <encrypted-key-file> -out <unencrypted-key-file>",
-" ",
-"SET AUTHENTICATION { SSL, TLS } RANDOM-FILE <filename>",
-" Specifies a file containing random data to be used as seed for the",
-" Pseudo Random Number Generator. The contents of the file are",
-" overwritten with new random data on each use.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } RSA-CERT-CHAIN-FILE <filename>",
-" Specifies a file containing a RSA certificate chain to be sent along with",
-" the RSA-CERT to the peer. This file must only be specified if Kermit is",
-" being used as a server and the RSA certificate was signed by an",
-" intermediary certificate authority.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } RSA-CERT-FILE <filename>",
-" Specifies a file containing a RSA certificate to be sent to the peer to ",
-" authenticate the host or end user. The file may contain the matching RSA ",
-" private key instead of using the RSA-KEY-FILE command.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } RSA-KEY-FILE <filename>",
-" Specifies a file containing the private RSA key that matches the RSA",
-" certificate specified with RSA-CERT-FILE. This command is only necessary",
-" if the private key is not appended to the certificate in the file specified"
-,
-" by RSA-CERT-FILE. ",
-" ",
-" Note: When executing a script in the background or when it is",
-" running as an Internet Kermit Service Daemon, Kermit cannot support ",
-" encrypted private keys. When attempting to load a private key that is",
-" encrypted, a prompt will be generated requesting the passphrase necessary",
-" to decrypt the keyfile. To automate access to the private key you must",
-" decrypt the encrypted keyfile and create an unencrypted keyfile for use",
-" by Kermit. This can be accomplished by using the following command and",
-" the passphrase:",
-" ",
-" openssl rsa -in <encrypted-key-file> -out <unencrypted-key-file>",
-" ",
-"SET AUTHENTICATION { SSL, TLS } VERBOSE { ON, OFF }",
-" Specifies whether information about the authentication (ie, the",
-" certificate chain) should be displayed upon making a connection.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } VERIFY { NO,PEER-CERT,FAIL-IF-NO-PEER-CERT }",
-" Specifies whether certificates should be requested from the peer verified;",
-" whether they should be verified when they are presented; and whether they",
-" should be required. When set to NO (the default for IKSD), Kermit does",
-" not request that the peer send a certificate; if one is presented it is",
-" ignored. When set to PEER-CERT (the default when not IKSD), Kermit",
-" requests a certificate be sent by the peer. If presented, the certificate",
-" is verified. Any errors during the verification process result in",
-" queries to the end user. When set to FAIL-IF-NO-PEER-CERT, Kermit",
-" requests a certificate be sent by the peer. If the certificate is not",
-" presented or fails to verify, the connection is terminated without",
-" querying the user.",
-" ",
-" If an anonymous cipher (i.e., ADH) is desired, the NO setting must be",
-" used. Otherwise, the receipt of the peer certificate request is",
-" interpreted as a protocol error and the negotiation fails.",
-" ",
-" If you wish to allow the peer to authenticate using either an X509",
-" certificate to userid mapping function or via use of a ~/.tlslogin file",
-" you must use either PEER-CERT or FAIL-IF-NO-PEER-CERT. Otherwise, any",
-" certificates that are presented is ignored. In other words, use NO if you",
-" want to disable the ability to use certificates to authenticate a peer.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } VERIFY-DIR <directory>",
-" Specifies a directory that contains root CA certificate files used to",
-" verify the certificate chains presented by the peer. Each file is named",
-" by a hash of the certificate.",
-" ",
-" OpenSSL expects the hash symlinks to be made like this:",
-" ",
-" ln -s cert.pem `openssl x509 -hash -noout -in cert.pem`.0",
-" ",
-" Since not all file systems have symlinks you can use the following command",
-" in Kermit to copy the cert.pem file to the hash file name.",
-" ",
-" copy cert.pem {\\fcommand(openssl.exe x509 -hash -noout -in cert.pem).0}",
-" ",
-" This produces a hash based on the subject field in the cert such that the",
-" certificate may be quickly found.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } VERIFY-FILE <file>",
-" Specifies a file that contains root CA certificates to be used for",
-" verifying certificate chains.",
-" ",
-#endif /* CK_SSL */
-""
-};
-
-static char *hxynet[] = {
-"Syntax: SET NETWORK { TYPE network-type, DIRECTORY [ file(s)... ] }",
-" ",
-"Select the type of network to be used with SET HOST connections:",
-" ",
-#ifdef NETCMD
-" SET NETWORK TYPE COMMAND ; Make a connection through an external command",
-#endif /* NETCMD */
-#ifdef TCPSOCKET
-" SET NETWORK TYPE TCP/IP ; Internet: Telnet, Rlogin, etc.",
-#endif /* TCPSOCKET */
-#ifdef ANYX25
-" SET NETWORK TYPE X.25 ; X.25 peer-to-peer connections.",
-#endif /* ANYX25 */
-#ifdef DECNET
-" SET NETWORK TYPE PATHWORKS { LAT, CTERM } ; DEC LAT or CTERM connections.",
-#endif /* DECNET */
-#ifdef NPIPE
-" SET NETWORK TYPE NAMED-PIPE <pipename> ; OS/2 Named Pipe connections.",
-#endif /* NPIPE */
-#ifdef CK_NETBIOS
-" SET NETWORK TYPE NETBIOS ; NETBIOS peer-to-peer connections",
-#endif /* CK_NETBIOS */
-#ifdef SUPERLAT
-" SET NETWORK TYPE SUPERLAT ; LAT connections (Meridian Technology SuperLAT)",
-#endif /* SUPERLAT */
-" ",
-"If only one network type is listed above, that is the default network for",
-#ifdef RLOGCODE
-"SET HOST commands. Also see SET HOST, TELNET, RLOGIN.",
-#else
-#ifdef TNCODE
-"SET HOST commands. Also see SET HOST, TELNET.",
-#else
-"SET HOST commands. Also see SET HOST.",
-#endif /* TNCODE */
-#endif /* RLOGCODE */
-" ",
-"SET NETWORK DIRECTORY [ file [ file [ ... ] ] ]",
-" Specifies the name(s) of zero or more network directory files, similar to",
-" dialing directories (HELP DIAL for details). The general format of a",
-" network directory entry is:",
-" ",
-" name network-type address [ network-specific-info ] [ ; comment ]",
-" ",
-" For TCP/IP, the format is:",
-" ",
-" name tcp/ip ip-hostname-or-address [ socket ] [ ; comment ]",
-" ",
-"You can have multiple network directories and you can have multiple entries",
-"with the same name. SET HOST <name> and TELNET <name> commands look up the",
-"given <name> in the directory and, if found, fill in the additional items",
-"from the entry, and then try all matching entries until one succeeds.",
-""};
-
-#ifndef NOTCPOPTS
-static char *hxytcp[] = {
-#ifdef SOL_SOCKET
-"SET TCP ADDRESS <ip-address>",
-" This allows a specific IP Address on a multihomed host to be used",
-" instead of allowing the TCP/IP stack to choose. This may be necessary",
-" when using authentication or listening for an incoming connection.",
-" Specify no <ip-address> to remove the preference.",
-" ",
-"SET TCP KEEPALIVE { ON, OFF }",
-" Setting this ON might help to detect broken connections more quickly.",
-" (default is ON.)",
-" ",
-"SET TCP LINGER { ON [timeout], OFF }",
-" Setting this ON ensures that a connection doesn't close before all",
-" outstanding data has been transferred and acknowledged. The timeout is",
-" measured in 10ths of milliseconds. The default is ON with a timeout of 0.",
-" ",
-"SET TCP NODELAY { ON, OFF }",
-" ON means send short TCP packets immediately rather than waiting",
-" to accumulate a bunch of them before transmitting (Nagle Algorithm).",
-" (default is OFF.)",
-" ",
-"SET TCP RECVBUF <number>",
-"SET TCP SENDBUF <number>",
-" TCP receive and send buffer sizes. (default is -1, use system defaults.)",
-" ",
-"These items let you tune TCP networking performance on a per-connection",
-"basis by adjusting parameters you normally would not have access to. You",
-"should use these commands only if you feel that the TCP/IP protocol stack",
-"that Kermit is using is giving you inadequate performance, and then only if",
-"you understand the concepts (see, for example, the Comer TCP/IP books), and",
-"then at your own risk. These settings are displayed by SHOW NETWORK. Not",
-"all options are necessarily available in all Kermit versions; it depends on",
-"the underlying TCP/IP services.",
-" ",
-"The following TCP and/or IP parameter(s) may also be changed:",
-" ",
-#endif /* SOL_SOCKET */
-"SET TCP REVERSE-DNS-LOOKUP { AUTO, ON, OFF }",
-" Tells Kermit whether to perform reverse DNS lookup on TCP/IP connections",
-" so Kermit can determine the actual hostname of the host it is connected",
-" to, which is useful for connections to host pools, and is required for",
-" Kerberos connections to host pools and for incoming connections. If the",
-" other host does not have a DNS entry, the reverse lookup could take a long",
-" time (minutes) to fail, but the connection will still be made. Turn this",
-" option OFF for speedier connections if you do not need to know exactly",
-" which host you are connected to and you are not using Kerberos. AUTO, the",
-" default, means the lookup is done on hostnames, but not on numeric IP",
-" addresses unless Kerberos support is installed.",
-#ifdef CK_DNS_SRV
-" ",
-"SET TCP DNS-SERVICE-RECORDS {ON, OFF}",
-" Tells Kermit whether to try to use DNS SRV records to determine the",
-" host and port number upon which to find an advertised service. For",
-" example, if a host wants regular Telnet connections redirected to some",
-" port other than 23, this feature allows Kermit to ask the host which",
-" port it should use. Since not all domain servers are set up to answer",
-" such requests, this feature is OFF by default.",
-#endif /* CK_DNS_SRV */
-#ifdef NT
-#ifdef CK_SOCKS
-" ",
-"SET TCP SOCKS-SERVER [<hostname or ip-address>]",
-" If a hostname or ip-address is specified, Kermit will use the SOCKS",
-" server when attempting outgoing connections. If no hostname or",
-" ip-address is specified, any previously specified SOCKS server will",
-" be removed.",
-#endif /* CK_SOCKS */
-#endif /* NT */
-#ifndef NOHTTP
-" ",
-"SET TCP HTTP-PROXY [<hostname or ip-address>[:<port>]]",
-" If a hostname or ip-address is specified, Kermit will use the Proxy",
-" server when attempting outgoing connections. If no hostname or",
-" ip-address is specified, any previously specified Proxy server will",
-" be removed. If no port number is specified, the \"http\" service",
-" will be used.",
-#endif /* NOHTTP */
-""};
-#endif /* NOTCPOPTS */
-#endif /* NETCONN */
-
-#ifdef TNCODE
-static char *hxytopt[] = {
-"SET TELOPT [ { /CLIENT, /SERVER } ] <option> -",
-" { ACCEPTED, REFUSED, REQUESTED, REQUIRED } -",
-" [ { ACCEPTED, REFUSED, REQUESTED, REQUIRED } ]",
-" SET TELOPT lets you specify policy requirements for Kermit's handling of",
-" Telnet option negotiations. Setting an option REQUIRED causes Kermit",
-" to offer the option to the peer and disconnect if the option is refused.",
-" REQUESTED causes Kermit to offer an option to the peer. ACCEPTED results",
-" in no offer but Kermit will attempt to negotiate the option if it is",
-" requested. REFUSED instructs Kermit to refuse the option if it is",
-" requested by the peer.",
-" ",
-" Some options are negotiated in two directions and accept separate policies",
-" for each direction; the first keyword applies to Kermit itself, the second",
-" applies to Kermit's Telnet partner; if the second keyword is omitted, an",
-" appropriate (option-specific) default is applied. You can also include a",
-" /CLIENT or /SERVER switch to indicate whether the given policies apply",
-" when Kermit is the Telnet client or the Telnet server; if no switch is",
-" given, the command applies to the client.",
-" ",
-" Note that some of Kermit's Telnet partners fail to refuse options that",
-" they do not recognize and instead do not respond at all. In this case it",
-" is possible to use SET TELOPT to instruct Kermit to REFUSE the option",
-" before connecting to the problem host, thus skipping the problematic",
-" negotiation.",
-" ",
-" Use SHOW TELOPT to view current Telnet Option negotiation settings.",
-" SHOW TELNET displays current Telnet settings.",
-""};
-
-static char *hxytel[] = {
-"Syntax: SET TELNET parameter value",
-" ",
-"For TCP/IP TELNET connections, which are in NVT (ASCII) mode by default:",
-" ",
-#ifdef CK_AUTHENTICATION
-#ifdef COMMENT
-"SET TELNET AUTHENICATION { ACCEPTED, REFUSED, REQUESTED, REQUIRED }",
-" ACCEPT or REFUSE authentication bids, or actively REQUEST authentication.",
-" REQUIRED refuses the connection if authentication is not successfully",
-" negotiated. ACCEPTED by default.",
-" ",
-#endif /* COMMENT */
-"SET TELNET AUTHENTICATION TYPE { AUTOMATIC, KERBEROS_IV, KERBEROS_V, ...",
-#ifdef NT
-" ..., NTLM, SSL, SRP, NONE } [...]",
-#else /* NT */
-" ..., SSL, SRP, NONE } [...]",
-#endif /* NT */
-" AUTOMATIC is the default. Available options can vary depending on the",
-" features Kermit was built to support and the operating system",
-" configuration; type SET TELNET AUTHENTICATION TYPE ? for a list.",
-" ",
-" When Kermit is the Telnet client:",
-" AUTOMATIC allows the host to choose the preferred type of authentication."
-,
-" NONE instructs Kermit to refuse all authentication methods when the",
-" authentication option is negotiated. A list of one or more other values",
-" allow a specific subset of the supported authentication methods to be",
-" used.",
-" ",
-" When Kermit is the Telnet server:",
-" AUTOMATIC results in available authentication methods being offered",
-" to the telnet client in the following order:",
-" ",
-#ifdef NT
-" KERBEROS_V, KERBEROS_IV, SRP, SSL, NTLM",
-#else /* NT */
-" KERBEROS_V, KERBEROS_IV, SRP, SSL, NTLM",
-#endif /* NT */
-" ",
-" NONE results in no authentication methods being offered to the Telnet",
-" server when the authentication option is negotiated. The preferred",
-" method of disabling authentication is:",
-" ",
-" SET TELOPT /SERVER AUTHENTICATION REFUSE",
-" ",
-" A list of one or more authentication methods specifies the order those",
-" methods are to be offered to the telnet client.",
-#ifdef NT
-" ",
-" If you wish to allow NTLM authentication to be used with the Microsoft",
-" Windows 2000 or Services for Unix Telnet client you must specify a list",
-" with NTLM as the first item in the list. By default, NTLM is the last",
-" item in the list because it does not provide any form of data encryption.",
-#endif /* NT */
-" ",
-#ifdef CK_KERBEROS
-"SET TELNET AUTHENTICATION FORWARDING { ON, OFF }",
-" Set this to ON to forward Kerberos V ticket-granting-tickets to the host",
-" after authentication is complete. OFF by default.",
-" ",
-#endif /* CK_KERBEROS */
-"SET TELNET AUTHENTICATION ENCRYPT-FLAG { ANY, NONE, TELOPT }",
-" Use this command to specify which AUTH telopt encryption flags may be",
-" accepted in client mode or offered in server mode. The default is ANY.",
-" ",
-"SET TELNET AUTHENTICATION HOW-FLAG { ANY, ONE-WAY, MUTUAL }",
-" Use this command to specify which AUTH telopt how flags may be",
-" accepted in client mode or offered in server mode. The default is ANY.",
-" ",
-#endif /* CK_AUTHENTICATION */
-#ifdef COMMENT
-"SET TELNET BINARY-MODE { ACCEPTED, REFUSED, REQUESTED, REQUIRED }",
-" ACCEPT or REFUSE binary-mode bids, or actively REQUEST binary mode.",
-" REQUIRED refuses the connection if binary mode is not successfully",
-" negotiated in both directions. ACCEPTED by default.",
-" ",
-#endif /* COMMENT */
-"SET TELNET BINARY-TRANSFER-MODE { ON, OFF }",
-" When ON (OFF by default) and BINARY negotiations are not REFUSED Kermit",
-" will attempt to negotiate BINARY mode in each direction before the start",
-" of each file transfer. After the transfer is complete BINARY mode will",
-" be restored to the pre-transfer state.",
-" ",
-"SET TELNET BINARY-TRANSFER-MODE { ON, OFF }",
-" Set this command to ON if you want to force Kermit to negotiate",
-" Telnet Binary in both directions when performing file transfers.",
-" Default is OFF. Alias SET TELNET BINARY-XFER-MODE.",
-" ",
-"SET TELNET BUG AUTH-KRB5-DES { ON, OFF }",
-" Default is ON. Disable this bug to enable the use of encryption types",
-" other than DES such as 3DES or CAST-128 when the Kerberos 5 session key",
-" is longer than 8 bytes.",
-" ",
-"SET TELNET BUG BINARY-ME-MEANS-U-TOO { ON, OFF }",
-" Set this to ON to try to overcome TELNET binary-mode misnegotiations by",
-" Kermit's TELNET partner.",
-" ",
-"SET TELNET BUG BINARY-U-MEANS-ME-TOO { ON, OFF }",
-" Set this to ON to try to overcome TELNET binary-mode misnegotiations by",
-" Kermit's TELNET partner.",
-" ",
-"SET TELNET BUG INFINITE-LOOP-CHECK { ON, OFF }",
-" Set this to ON to prevent Kermit from responding to a telnet negotiation",
-" sequence that enters an infinite loop. The default is OFF because this",
-" should never occur.",
-" ",
-"SET TELNET BUG SB-IMPLIES-WILL-DO { ON, OFF }",
-" Set this to ON to allow Kermit to respond to telnet sub-negotiations if",
-" the peer forgets to respond to WILL with DO or to DO with WILL.",
-" ",
-"SET TELNET DEBUG { ON, OFF }",
-" Set this to ON to display telnet negotiations as they are sent and",
-" received.",
-" ",
-"SET TELNET DELAY-SB { ON, OFF }",
-" When ON, telnet subnegotiation responses are delayed until after all",
-" authentication and encryption options are either successfully negotiated",
-" or refused. This ensures that private data is protected. When OFF, telnet",
-" subnegotiation responses are sent immediately. The default is ON.",
-" ",
-"SET TELNET ECHO { LOCAL, REMOTE }",
-" Kermit's initial echoing state for TELNET connections, LOCAL by default.",
-" After the connection is made, TELNET negotiations determine the echoing.",
-" ",
-#ifdef CK_ENCRYPTION
-#ifdef COMMENT
-"SET TELNET ENCRYPTION { ACCEPTED, REFUSED, REQUESTED, REQUIRED }",
-" ACCEPT or REFUSE encryption bids, or actively REQUEST encryption in both.",
-" directions. REQUIRED refuses the connection if encryption is not",
-" successfully negotiated in both directions. ACCEPTED by default.",
-" ",
-#endif /* COMMENT */
-"SET TELNET ENCRYPTION TYPE { AUTOMATIC, CAST128_CFB64, CAST128_OFB64, ",
-" CAST5_40_CFB64, CAST5_40_OFB64, DES_CFB64, DES_OFB64, NONE }",
-" AUTOMATIC allows the host to choose the preferred type of encryption.",
-" Other values allow a specific encryption method to be specified.",
-" AUTOMATIC is the default. The list of options will vary depending",
-" on the encryption types selected at compilation time.",
-" ",
-#endif /* CK_ENCRYPTION */
-#ifdef CK_ENVIRONMENT
-#ifdef COMMENT
-"SET TELNET ENVIRONMENT { ON, OFF, variable-name [ value ] }",
-" This feature lets Kermit send the values of certain environment variables",
-" to the other computer if it asks for them. The variable-name can be any",
-" of the \"well-known\" variables \"USER\", \"JOB\", \"ACCT\", \"PRINTER\",",
-" \"SYSTEMTYPE\", or \"DISPLAY\". Some Telnet servers, if given a USER",
-" value in this way, will accept it and therefore not prompt you for user",
-" name when you log in. The default values are taken from your environment;",
-" use this command to change or remove them. See RFC1572 for details. You",
-" may also specify OFF to disable this feature, and ON to re-enable it.",
-" ",
-#else
-"SET TELNET ENVIRONMENT { variable-name [ value ] }",
-" This feature lets Kermit send the values of certain environment variables",
-" to the other computer if it asks for them. The variable-name can be any",
-" of the \"well-known\" variables \"USER\", \"JOB\", \"ACCT\", \"PRINTER\",",
-" \"SYSTEMTYPE\", or \"DISPLAY\". Some Telnet servers, if given a USER",
-" value in this way, will accept it and therefore not prompt you for user",
-" name when you log in. The default values are taken from your environment;",
-" use this command to change or remove them. See RFC1572 for details.",
-" ",
-#endif /* COMMENT */
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_FORWARD_X
-"SET TELNET FORWARD-X XAUTHORITY-FILE <file>",
-" If your X Server requires X authentication and the location of the",
-" .Xauthority file is not defined by the XAUTHORITY environment variable,",
-" use this command to specify the location of the .Xauthority file."
-" ",
-#endif /* CK_FORWARD_X */
-#ifdef CK_SNDLOC
-"SET TELNET LOCATION [ text ]",
-" Location string to send to the Telnet server if it asks. By default this",
-" is picked up from the LOCATION environment variable. Give this command",
-" with no text to disable this feature.",
-" ",
-#endif /* CK_SNDLOC */
-"SET TELNET NEWLINE-MODE { NVT, BINARY-MODE } { OFF, ON, RAW }",
-
-" Determines how carriage returns are handled on TELNET connections. There",
-" are separate settings for NVT (ASCII) mode and binary mode. ON (default",
-" for NVT mode) means CRLF represents CR. OFF means CR followed by NUL",
-" represents CR. RAW (default for BINARY mode) means CR stands for itself.",
-" ",
-#ifdef TCPSOCKET
-"SET TELNET PROMPT-FOR-USERID <prompt>",
-" Specifies a custom prompt to be used when prompting for a userid. Kermit",
-" prompts for a userid if the command:",
-" ",
-" SET LOGIN USERID {}",
-" ",
-" has been issued prior to a Telnet authentication negotiation for an",
-" authentication type that requires the transmission of a name, such as",
-" Secure Remote Password.",
-" ",
-#endif /* TCPSOCKET */
-"SET TELNET REMOTE-ECHO { ON, OFF }",
-" Applies only to incoming connections created with:",
-" SET HOST * <port> /TELNET",
-" This command determines whether Kermit will actually echo characters",
-" received from the remote when it has negotiated to do so. The default",
-" is ON. Remote echoing may be turned off when it is necessary to read",
-" a password with the INPUT command.",
-" ",
-"SET TELNET TERMINAL-TYPE name",
-" The terminal type to send to the remote TELNET host. If none is given,",
-#ifdef OS2
-" your current SET TERMINAL TYPE value is sent, e.g. VT220.",
-" ",
-#else
-" your local terminal type is sent.",
-" ",
-#endif /* OS2 */
-"SET TELNET WAIT-FOR-NEGOTIATIONS { ON, OFF }",
-" Each Telnet option must be fully negotiated either On or Off before the",
-" session can continue. This is especially true with options that require",
-" subnegotiations such as Authentication, Encryption, and Kermit; for",
-" proper support of these options Kermit must wait for the negotiations to",
-" complete. Of course, Kermit has no way of knowing whether a reply is",
-" delayed or not coming at all, and so will wait a minute or more for",
-" required replies before continuing the session. If you know that Kermit's",
-" Telnet partner will not be sending the required replies, you can set this",
-" option of OFF to avoid the long timeouts. Or you can instruct Kermit to",
-" REFUSE specific options with the SET TELOPT command.",
-"",
-"Type SHOW TELNET to see the current values of these parameters.",
-"" };
-#endif /* TNCODE */
-
-#ifndef NOSPL
-static char *hxymacr[] = {
-"Syntax: SET MACRO parameter value",
-" Controls the behavior of macros.",
-" ",
-"SET MACRO ECHO { ON, OFF }",
-" Tells whether commands executed from a macro definition should be",
-" displayed on the screen. OFF by default; use ON for debugging.",
-" ",
-"SET MACRO ERROR { ON, OFF }",
-" Tells whether a macro should be automatically terminated upon a command",
-" error. This setting is local to the current macro, and inherited by",
-" subordinate macros.",
-"" };
-#endif /* NOSPL */
-
-static char *hmxyprm[] = {
-"Syntax: SET PROMPT [ text ]",
-" ",
-#ifdef OS2
-"Prompt text for this program, normally 'K-95>'. May contain backslash",
-#else
-#ifdef MAC
-"Prompt text for this program, normally 'Mac-Kermit>'. May contain backslash",
-#else
-"Prompt text for this program, normally 'C-Kermit>'. May contain backslash",
-#endif /* MAC */
-#endif /* OS2 */
-"codes for special effects. Surround by { } to preserve leading or trailing",
-#ifdef OS2
-"spaces. If text omitted, prompt reverts to K-95>. Prompt can include",
-#else
-#ifdef MAC
-"spaces. If text omitted, prompt reverts to Mac-Kermit>. Prompt can include",
-#else
-"spaces. If text omitted, prompt reverts to C-Kermit>. Prompt can include",
-#endif /* OS2 */
-#endif /* MAC */
-"variables like \\v(dir) or \\v(time) to show current directory or time.",
-"" };
-
-#ifdef UNIX
-static char *hxywild[] = {
-"Syntax: SET WILDCARD-EXPANSION { KERMIT [ switch ], SHELL, ON, OFF }",
-" KERMIT (the default) means C-Kermit expands filename wildcards in SEND and",
-" similar commands itself, and in incoming GET commands. Optional switches",
-" are /NO-MATCH-DOT-FILES (\"*\" and \"?\" should not match an initial",
-" period in a filename; this is the default) and /MATCH-DOT-FILES if you",
-" want files whose names begin with \".\" included. SET WILDCARD SHELL",
-" means that Kermit asks your preferred shell to expand wildcards (this",
-" should not be necessary in C-Kermit 7.0 and later). HELP WILDCARD for",
-" further information.",
-" ",
-" The ON and OFF choices allow you to disable and renable wildcard",
-" processing independent of the KERMIT / SHELL choice. Disabling wildcards",
-" allows you to process an array or list of filenames without having to",
-" consider whether the names might contain literal wildcard characters.",
-" WARNING: SET WILD OFF also disables internal filename pattern-matching,",
-" used (for example) in creating backup files.",
-"" };
-#else
-static char *hxywild[] = {
-"Syntax: SET WILDCARD-EXPANSION { ON, OFF }",
-" ON (the default) means that filenames given to Kermit commands such as",
-" SEND and DIRECTORY are automatically expanded into lists of filenames if",
-" they contain special 'wildcard characters' such as '*'. You can reference",
-" files whose names contains such characters literally by preceding each",
-" such character with a backslash '\\'. When dealing programmatically with",
-" a file list, however, you should SET WILDCARD-EXPANSION OFF to force",
-" treat each name in the list as a literal name. See HELP WILDCARDS for",
-" details about wildcard syntax.",
-"" };
-#endif /* UNIX */
-
-#ifndef NOXFER
-static char *hxywind[] = {
-"Syntax: SET WINDOW-SIZE number",
-" Specifies number of slots for sliding windows, i.e. the number of packets",
-" that can be transmitted before waiting for acknowledgement. The default",
-#ifdef XYZ_INTERNAL
-" for Kermit protocol is one, the maximum is 32; for ZMODEM, the default",
-" is no windowing (0). For ZMODEM, the window size is really the packet",
-" length, and is used only when non-windowed (streaming) transfers fail; the",
-" ZMODEM window size should be a largish number, like 1024, and it should be",
-" a multiple of 64.",
-#else
-" is one, the maximum is 32. Increased window size might result in reduced",
-" maximum packet length. Use sliding windows for improved efficiency on",
-" connections with long delays. A full duplex connection is required, as",
-" well as a cooperating Kermit on the other end.",
-#endif /* XYZ_INTERNAL */
-"" };
-
-static char *hxyrpt[] = {
-"Syntax: SET REPEAT { COUNTS { ON, OFF }, PREFIX <code> }",
-" SET REPEAT COUNTS turns the repeat-count compression mechanism ON and OFF.",
-" The default is ON. SET REPEAT PREFIX <code> sets the repeat-count prefix",
-" character to the given code. The default is 126 (tilde).",
-"" };
-
-static char *hxyrcv[] = {
-"Syntax: SET RECEIVE parameter value",
-" Specifies parameters for inbound packets:",
-" ",
-#ifndef NOCSETS
-"SET RECEIVE CHARACTER-SET { AUTOMATIC, MANUAL }",
-" Whether to automatically switch to an appropriate file-character set based",
-" on the transfer character-set announcer, if any, of an incoming text file.",
-" AUTOMATIC by default. Also see HELP ASSOCIATE.",
-" ",
-#endif /* NOCSETS */
-"SET RECEIVE CONTROL-PREFIX number",
-" ASCII value of prefix character used for quoting control characters in",
-" packets that Kermit receives, normally 35 (number sign). Don't change",
-" this unless something is wrong with the other Kermit program.",
-" ",
-"SET RECEIVE END-OF-PACKET number",
-" ASCII value of control character that terminates incoming packets,",
-" normally 13 (carriage return).",
-" ",
-#ifdef CKXXCHAR
-"SET RECEIVE IGNORE-CHARACTER number",
-" ASCII value of character to be discarded when receiving packets, such as",
-" line folding characters.",
-" ",
-#endif /* CKXXCHAR */
-"SET RECEIVE MOVE-TO [ directory ]",
-" If a directory name is specified, then every file that is received",
-" successfully is moved to the given directory immediately after reception",
-" is complete. Omit the directory name to remove any previously set move-to",
-" directory.",
-" ",
-"SET RECEIVE PACKET-LENGTH number",
-" Maximum length packet the other Kermit should send.",
-" ",
-"SET RECEIVE PADDING number",
-" Number of prepacket padding characters to ask for (normally 0).",
-" ",
-"SET RECEIVE PAD-CHARACTER number",
-" ASCII value of control character to use for padding (normally 0).",
-" ",
-"SET RECEIVE PATHNAMES {OFF, ABSOLUTE, RELATIVE, AUTO}",
-" If a recognizable path (directory, device) specification appears in an",
-" incoming filename, strip it OFF before trying to create the output file.",
-#ifdef CK_MKDIR
-" Otherwise, then if any of the directories in the path don't exist, Kermit",
-" tries to create them, relative to your current or download directory, or",
-" absolutely, as specified. RELATIVE means force all incoming names, even",
-" if they are absolute, to be relative to your current or download directory."
-,
-" AUTO, which is the default, means RELATIVE if the file sender indicates in",
-" advance that this is a recursive transfer, otherwise OFF.",
-#endif /* CK_MKDIR */
-" ",
-"SET RECEIVE PAUSE number",
-" Milliseconds to pause between packets, normally 0.",
-" ",
-
-#ifdef CK_PERMS
-"SET RECEIVE PERMISSIONS { ON, OFF }",
-" Whether to copy file permissions from inbound Attribute packets.",
-" ",
-#endif /* CK_PERMS */
-
-"SET RECEIVE RENAME-TO [ template ]",
-" If a template is specified, then every file that is received successfully",
-" \
-is renamed according to the given template immediately after it is received.",
-" \
-The template should include variables like \\v(filename) or \\v(filenumber).",
-" Omit the template to remove any template previously set.",
-" ",
-"SET RECEIVE START-OF-PACKET number",
-" ASCII value of character that marks start of inbound packet.",
-" ",
-"SET RECEIVE TIMEOUT number",
-" Number of seconds the other Kermit should wait for a packet before sending",
-" a NAK or retransmitting.",
-#ifdef VMS
-" ",
-"SET RECEIVE VERSION-NUMBERS { ON, OFF }",
-" If ON, and in incoming filename includes a VMS version number, use it when",
-" creating the file. If OFF (which is the default), strip any VMS version",
-" number from incoming filenames before attempting to create the file, \
-causing",
-" the new file to receive the next highest version number.",
-#endif /* VMS */
-"" };
-
-static char *hxysnd[] = {
-"Syntax: SET SEND parameter value",
-" Specifies parameters for outbound files or packets.",
-" ",
-"SET SEND BACKUP { ON, OFF }",
-" Tells whether to include backup files when sending file groups. Backup",
-" files are those created by Kermit, EMACS, etc, when creating a new file",
-" that has the same name as an existing file. A backup file has a version",
-" appended to its name, e.g. oofa.txt.~23~. ON is the default, meaning",
-" don't exclude backup files. Use OFF to exclude backup files from group",
-" transfers.",
-" ",
-#ifndef NOCSETS
-"SET SEND CHARACTER-SET { AUTOMATIC, MANUAL }",
-" Whether to automatically switch to an appropriate file-character when a",
-" SET TRANSFER CHARACTER-SET command is given, or vice versa. AUTOMATIC by",
-" default. Also see HELP ASSOCIATE.",
-" ",
-#endif /* NOCSETS */
-
-"SET SEND CONTROL-PREFIX number",
-" ASCII value of prefix character used for quoting control characters in",
-" packets that Kermit sends, normally 35 (number sign).",
-" ",
-#ifdef CKXXCHAR
-"SET SEND DOUBLE-CHARACTER number",
-" ASCII value of character to be doubled when sending packets, such as an",
-" X.25 PAD escape character.",
-" ",
-#endif /* CKXXCHAR */
-"SET SEND END-OF-PACKET number",
-" ASCII value of control character to terminate an outbound packet,",
-" normally 13 (carriage return).",
-" ",
-"SET SEND MOVE-TO [ directory ]",
-" \
-If a directory name is specified, then every file that is sent successfully",
-" is moved to the given directory immediately after it is sent.",
-" Omit the directory name to remove any previously set move-to directory.",
-" ",
-"SET SEND PACKET-LENGTH number",
-" Maximum length packet to send, even if other Kermit asks for longer ones.",
-" This command can not be used to force packets to be sent that are longer",
-" than the length requested by the receiver. Use this command only to",
-" force shorter ones.",
-" ",
-"SET SEND PADDING number",
-" Number of prepacket padding characters to send.",
-" ",
-"SET SEND PAD-CHARACTER number",
-" ASCII value of control character to use for padding.",
-" ",
-"SET SEND PATHNAMES {OFF, ABSOLUTE, RELATIVE}",
-" Include the path (device, directory) portion with the file name when",
-" sending it as specified; ABSOLUTE means to send the whole pathname,",
-" RELATIVE means to include the pathname relative to the current directory.",
-" Applies to the actual filename, not to the \"as-name\". The default is",
-" OFF.",
-" ",
-"SET SEND PAUSE number",
-" Milliseconds to pause between packets, normally 0.",
-" ",
-
-#ifdef CK_PERMS
-"SET SEND PERMISSIONS { ON, OFF }",
-" Whether to include file permissions in outbound Attribute packets.",
-" ",
-#endif /* CK_PERMS */
-
-"SET SEND RENAME-TO [ template ]",
-" If a template is specified, then every file that is sent successfully",
-" is renamed according to the given template immediately after it is sent.",
-" \
-The template should include variables like \\v(filename) or \\v(filenumber).",
-" Omit the template to remove any template previously set.",
-" ",
-"SET SEND START-OF-PACKET number",
-" ASCII value of character to mark start of outbound packet.",
-" ",
-#ifdef CK_TIMERS
-"SET SEND TIMEOUT number [ { DYNAMIC [ min max ] ], FIXED } ]",
-#else
-"SET SEND TIMEOUT number",
-#endif /* CK_TIMERS */
-
-" Number of seconds to wait for a packet before sending NAK or",
-#ifdef CK_TIMERS
-" retransmitting. Include the word DYNAMIC after the number in the",
-" SET SEND TIMEOUT command to have Kermit compute the timeouts dynamically",
-" throughout the transfer based on the packet rate. Include the word FIXED",
-" to use the \"number\" given throughout the transfer. DYNAMIC is the",
-" default. After DYNAMIC you may include minimum and maximum values.",
-" SET SEND TIMEOUT -1 FIXED means no timeouts.",
-#else
-" retransmitting.",
-#endif /* CK_TIMERS */
-#ifdef VMS
-" ",
-"SET SEND VERSION-NUMBERS { ON, OFF }",
-" If ON, include VMS version numbers in outbound filenames. If OFF (which",
-" is the default), strip version numbers.",
-#endif /* VMS */
-"" };
-
-static char *hxyxfer[] = {
-"Syntax: SET TRANSFER (or XFER) parameter value",
-" ",
-"Choices:",
-" ",
-"SET TRANSFER BELL { OFF, ON }",
-" Whether to ring the terminal bell at the end of a file transfer.",
-" ",
-#ifdef XFRCAN
-"SET TRANSFER CANCELLATION { OFF, ON [ <code> [ <number> ] ] }",
-" OFF disables remote-mode packet-mode cancellation from the keyboard.",
-" ON enables it. The optional <code> is the control character to use for",
-" cancellation; the optional <number> is how many consecutive occurrences",
-" of the given control character are required for cancellation.",
-" ",
-#endif /* XFRCAN */
-"SET TRANSFER INTERRUPTION { ON, OFF }",
-" TRANSFER INTERRUPTION is normally ON, allowing for interruption of a file",
-" transfer in progress by typing certain characters while the file-transfer",
-" display is active. SET TRANSFER INTERRUPTION OFF disables interruption",
-" of file transfer from the keyboard in local mode.",
-" ",
-#ifndef NOSPL
-"SET TRANSFER CRC-CALCULATION { OFF, ON }",
-" Tells whether Kermit should accumulate a Cyclic Redundancy Check for ",
-" each file transfer. Normally ON, in which case the CRC value is available",
-" in the \\v(crc16) variable after the transfer. Adds some overhead. Use",
-" SET TRANSFER CRC OFF to disable.",
-" ",
-#endif /* NOSPL */
-#ifndef NOCSETS
-"SET TRANSFER CHARACTER-SET name",
-" Selects the character set used to represent textual data in Kermit",
-" packets. Text characters are translated to/from the FILE CHARACTER-SET.",
-" Choices:",
-" ",
-" TRANSPARENT (no translation, the default)",
-" ASCII",
-" LATIN1 (ISO 8859-1 Latin Alphabet 1)",
-#ifndef NOLATIN2
-" LATIN2 (ISO 8859-2 Latin Alphabet 2)",
-#endif /* NOLATIN2 */
-" LATIN9 (ISO 8859-15 Latin Alphabet 9)",
-#ifdef CYRILLIC
-" CYRILLIC-ISO (ISO 8859-5 Latin/Cyrillic)",
-#endif /* CYRILLIC */
-#ifdef GREEK
-" GREEK-ISO (ISO 8859-7 Latin/Greek)",
-#endif /* GREEK */
-#ifdef HEBREW
-" HEBREW-ISO (ISO 8859-8 Latin/Hebrew)",
-#endif /* HEBREW */
-#ifdef KANJI
-" JAPANESE-EUC (JIS X 0208 Kanji + Roman and Katakana)",
-#endif /* KANJI */
-#ifdef UNICODE
-" UCS-2 (ISO 10646 / Unicode 2-byte form)",
-" UTF-8 (ISO 10646 / Unicode 8-bit serialized transformation format)",
-#endif /* UNICODE */
-" ",
-"SET TRANSFER TRANSLATION { ON, OFF }",
-" Enables and disables file-transfer character-set translation. It's",
-" enabled by default.",
-#endif /* NOCSETS */
-" ",
-#ifdef CK_CURSES
-"SET TRANSFER DISPLAY { BRIEF, CRT, FULLSCREEN, NONE, SERIAL }",
-#else
-"SET TRANSFER DISPLAY { BRIEF, CRT, NONE, SERIAL }",
-#endif /* CK_CURSES */
-" Choose the desired format for the progress report to be displayed on",
-" your screen during file transfers when Kermit is in local mode.",
-#ifdef CK_CURSES
-" FULLSCREEN requires your terminal type be set correctly; the others",
-" are independent of terminal type.",
-#else
-" file transfer.",
-#endif /* CK_CURSES */
-" ",
-"SET TRANSFER LOCKING-SHIFT { OFF, ON, FORCED }",
-" Tell whether locking-shift protocol should be used during file transfer",
-" to achieve 8-bit transparency on a 7-bit connection. ON means to request",
-" its use if PARITY is not NONE and to use it if the other Kermit agrees,",
-" OFF means not to use it, FORCED means to use it even if the other Kermit",
-" does not agree.",
-" ",
-"SET TRANSFER MODE { AUTOMATIC, MANUAL }",
-" Automatic (the default) means Kermit should automatically go into binary",
-" file-transfer mode and use literal filenames if the other Kermit says it",
-" has a compatible file system, e.g. UNIX-to-UNIX, but not UNIX-to-DOS.",
-#ifdef PATTERNS
-" Also, when sending files, Kermit should switch between binary and text",
-" mode automatically per file based on the SET FILE BINARY-PATTERNS and SET",
-" FILE TEXT-PATTERNS.",
-#endif /* PATTERNS */
-" ",
-#ifdef PIPESEND
-"SET TRANSFER PIPES { ON, OFF }",
-" Enables/Disables automatic sending from / reception to command pipes when",
-" the incoming filename starts with '!'. Also see CSEND, CRECEIVE.",
-" ",
-#endif /* PIPESEND */
-#ifdef CK_XYZ
-"SET TRANSFER PROTOCOL { KERMIT, XMODEM, ... }",
-" Synonym for SET PROTOCOL (q.v.).",
-" ",
-#endif /* CK_XYZ */
-"SET TRANSFER REPORT { ON, OFF }",
-" Enables/Disables the automatic post-transfer message telling what files",
-" went where from C-Kermit when it is in remote mode. ON by default.",
-" ",
-"SET TRANSFER SLOW-START { OFF, ON }",
-" ON (the default) tells Kermit, when sending files, to gradually build up",
-" the packet length to the maximum negotiated length. OFF means start",
-" sending the maximum length right away.",
-" ",
-"Synonym: SET XFER. Use SHOW TRANSFER (XFER) to see SET TRANSFER values.",
-"" };
-#endif /* NOXFER */
-
-#ifdef NT
-static char *hxywin95[] = {
-"SET WIN95 8.3-FILENAMES { ON, OFF }",
-" Instructs K-95 to report all filenames using 8.3 notation instead of the",
-" normal long filenames. Default is OFF",
-" ",
-"SET WIN95 ALT-GR { ON, OFF }",
-" Instructs K-95, when used on MS Windows 95, to interpret the Right Alt key",
-" as the Alt-Gr key. This is necessary to work around the failure of",
-" Windows 95 to properly translate non-US keyboards. Default is OFF.",
-" ",
-"SET WIN95 KEYBOARD-TRANSLATION <character-set>",
-" Specifies the character-set that Windows 95 is using to send keystrokes",
-" to Kermit-95 via the keyboard input functions. Default is Latin1-ISO.",
-" ",
-"SET WIN95 OVERLAPPED-IO { ON <requests>, OFF }",
-" Determines whether or not K-95 uses Overlapped-I/O methods for reading",
-" from and writing to serial and TAPI communication devices. <requests>",
-" specifies the maximum number of simultaneous write requests that may be",
-" overlapped, from 1 to 30. Default is ON.",
-" ",
-"SET WIN95 POPUPS { ON, OFF }",
-" Determines whether or not Kermit 95 uses Popups to query the user for",
-" necessary information such as user IDs or passwords. Default is ON.",
-" ",
-"SET WIN95 SELECT-BUG { ON, OFF }"
-" Some TCP/IP (Winsock) implementations for Windows have a defective",
-" select() function. Use this command to avoid the use of select() if",
-" K95 appears to be unable to send data over TCP/IP. Default is OFF.",
-""};
-#endif /* NT */
-
-static char *hmxybel[] = {
-#ifdef OS2
-"Syntax: SET BELL { AUDIBLE [ { BEEP, SYSTEM-SOUNDS } ], VISIBLE, NONE }",
-" Specifies how incoming Ctrl-G (bell) characters are handled in CONNECT",
-" mode and how command warnings are presented in command mode. AUDIBLE",
-" means either a beep or a system-sound is generated; VISIBLE means the",
-" screen is flashed momentarily.",
-#else
-"Syntax: SET BELL { OFF, ON }",
-" ON (the default) enables ringing of the terminal bell (beep) except where",
-" it is disabled in certain circumstances, e.g. by SET TRANSFER BELL. OFF",
-" disables ringing of the bell in all circumstances, overriding any specific",
-" SET xxx BELL selections.",
-#endif /* OS2 */
-""};
-
-#ifdef OS2
-static char *hmxymsk[] = {
-"SET MSKERMIT FILE-RENAMING { ON, OFF }",
-" ON enables the use of MS-DOS Kermit file renaming conventions instead of",
-" C-Kermit conventions. File renaming occurs during file transfers when",
-" there is a file name collision and either BACKUP or RENAME collision",
-" options are active. C-Kermit conventions preserve the original file name",
-" while appending .~num~ to the end. MS-DOS Kermit conventions restrict",
-" filenames to 8.3 notation and preserve the extension. Unique numeric",
-" values overwrite the right most portion of the file name's left hand side.",
-" ",
-"SET MSKERMIT KEYCODES { ON, OFF }",
-" ON enables the use of MS-DOS Kermit compatible keycodes to provide script",
-" portability.",
-""};
-#endif /* OS2 */
-
-static char *hmxycd[] = {
-"Syntax: SET CD { HOME <path>, PATH <path>, MESSAGE { ON, OFF, FILE <list> } }"
-,
-" ",
-"SET CD HOME <path>",
-" Specified which directory to change to if CD or KCD is given without a",
-" pathname. If this command is not given, your login or HOME directory is",
-" used.",
-" ",
-"SET CD PATH <path>",
-" Overrides normal CDPATH environment variable, which tells the CD command",
-" where to look for directories to CD to if you don't specify them fully.",
-" The format is:",
-" ",
-#ifdef UNIXOROSK
-" set cd path :directory:directory:...",
-" ",
-" in other words, a list of directories separated by colons, with a colon",
-" at the beginning, e.g.:",
-" ",
-" set cd path :/usr/olga:/usr/ivan/public:/tmp",
-#else
-#ifdef OS2
-" set cd path disk:directory;disk:directory;...",
-" ",
-" just like the DOS PATH; in other words, a list of disk:directory names",
-" separated by semicolons, e.g.:",
-" ",
-" SET CD PATH C:\\K95;C:\\HOME;C:\\LOCAL;C:\\",
-#else
-#ifdef VMS
-" set cd path directory,directory,...",
-" ",
-" in other words, a list of directory specifications or logical names that",
-" represent them, e.g.:",
-" ",
-" SET CD PATH SYS$LOGIN:,$DISK1:[OLGA],$DISK2[SCRATCH.IVAN].",
-#else
-" (unknown for this platform)",
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIXOROSK */
-" ",
-"SET CD MESSAGE { ON, OFF }",
-" Default is OFF. When ON, this tells Kermit to look for a file with a",
-" certain name in any directory that you CD to, and if it finds one, to",
-" display it on your screen when you give the CD command. The filename,",
-" or list of names, is given in the SET CD MESSAGE FILE command.",
-" ",
-"SET CD MESSAGE FILE name",
-" or:",
-"SET CD MESSAGE FILE {{name1}{name2}...{name8}}",
-" Specify up to 8 filenames to look for when when CDing to a new directory",
-" and CD MESSAGE is ON. The first one found, if any, in the new directory",
-#ifndef DFCDMSG
-" is displayed.",
-#else
-" is displayed. The default list is:",
-" ",
-#ifdef UNIXOROSK
-" {{./.readme}{README.TXT}{READ.ME}}",
-#else
-" {{README.TXT}{READ.ME}}",
-#endif /* UNIXOROSK */
-" ",
-#endif /* DFCDMSG */
-#ifndef NOSERVER
-"Synonym: SET SERVER CD-MESSAGE FILE.",
-#endif /* NOSERVER */
-" ",
-"Type SHOW CD to view current CD settings. Also see HELP SET SERVER.",
-""
-};
-
-#ifndef NOIKSD
-static char * hsetiks[] = {
-#ifdef OS2
-"SET IKS ANONYMOUS ACCOUNT <username>",
-" On Windows NT/2000 this is the account that will be used to allow",
-" anonymous access to the system. This account MUST have no password",
-" and its privileges should be restricted to only allow those operations",
-" which should be permitted to unknown users. In practice this means",
-" List Directories and Read-Execute privileges only. If a directory",
-" is configured for Write privileges then Read privileges should be",
-" denied for that directory. Otherwise, your system will become used",
-" by software pirates. If this command is not specified in the IKSD.KSC",
-" file the username \"GUEST\" is used by default. This command has no",
-" effect on Windows 95/98.",
-" ",
-#endif /* OS2 */
-"SET IKS ANONYMOUS INITFILE filename",
-#ifdef OS2
-" The initialization file to be executed for anonymous logins. By default",
-" it is K95.INI in the home directory associated with the ANNONYMOUS account."
-,
-" Any filename that you specify here must be readable by the ANONYMOUS",
-" account and if a SET IKS ANONYMOUS ROOT command was given, exist within",
-" the restricted directory tree. This option is independent of the SET IKS",
-" INITFILE command which applies only to real users.",
-#else
-" The initialization file to be executed for anonymous logins. By default",
-" it is .kermrc in the anonymous root directory. This option is independent",
-" of the SET IKS INITFILE command which applies only to real users.",
-#endif /* OS2 */
-" ",
-"SET IKS ANONYMOUS LOGIN { ON, OFF }",
-#ifdef OS2
-" Whether anonymous logins are allowed. By default they are NOT allowed,",
-" so this option need be included only to allow them (or for clarity, to",
-" emphasize that they are not allowed). Anonymous login occurs when the",
-" username \"anonymous\" is specified with any password (as with ftpd).",
-" In order for anonymous logins to succeed on Windows NT/2000, the",
-" ANONYMOUS account must be enabled.",
-" ",
-" On Windows NT and 2000, anonymous users have the same access rights as",
-" the ANONYMOUS account. In Windows 95/98, anonymous users, just like any",
-" other users, have full access rights to your entire PC, since Windows 95",
-" and 98 include no security features. For this reason, if you are allowing",
-" anonymous logins, be sure to also SET an IKS ANONYMOUS ROOT directory to",
-" restrict anonymous users' file access.",
-" ",
-" Anonymous user permissions may be restricted via the specification of ",
-" DISABLE commands in the ANONYMOUS initfile. Anonymous users are not ",
-" permitted to execute an ENABLE command. Anonymous users are also prevented"
-,
-" from SHOWing sensitive data about the operating system or the IKS",
-" configuration.",
-#else
-" Whether anonymous logins are allowed. By default they are allowed, so this",
-" option need be included only to disallow them (or for clarity, to emphasize"
-,
-" they are allowed). Anonymous login occurs when the username \"anonymous\"",
-" or \"ftp\" is given, with any password (as with ftpd).",
-#endif /* OS2 */
-" ",
-"SET IKS ANONYMOUS ROOT <directory>",
-" Specifies a directory tree to which anonymous users are restricted after",
-" login.",
-" ",
-"SET IKS BANNERFILE <filename>",
-" The name of a file containing a message to be printed after the user logs",
-" in, in place of the normal message (copyright notice, \"Type HELP or ? for",
-" help\", etc).",
-" ",
-"SET IKS CDFILE <filelist>",
-" When cdmessage is on, this is the name of the \"read me\" file to be shown."
-,
-" Normally you would specify a relative (not absolute) name, since the file",
-" is opened using the literal name you specified, after changing to the new",
-" directory. Example:",
-" ",
-" SET IKS CDFILE READ.ME",
-" ",
-" You can also give a list of up to 8 filenames by (a) enclosing each",
-" filename in braces, and (b) enclosing the entire list in braces. Example:",
-" ",
-" SET IKS CDFILE {{READ.ME}{aareadme.txt}{README}{read-this-first}}",
-" ",
-" When a list is given, it is searched from left to right and the first",
-" file found is displayed.",
-" ",
-"SET IKS CDMESSAGE {ON, OFF, 0, 1, 2}",
-" For use in the Server-Side Server configuration; whenever the client",
-" tells the server to change directory, the server sends the contents of a",
-" \"read me\" file to the client's screen. This feature is ON by default,",
-" and operates in client/server mode only when ON or 1. If set to 2 or",
-" higher, it also operates when the CD command is given at the IKSD> prompt.",
-" Synonym: SET IKS CDMSG.",
-" ",
-"SET IKS DATABASE { ON, OFF }",
-" This command determines whether entries are inserted into the SET IKS",
-" DBFILE (IKSD active sessions database).",
-" ",
-"SET IKS DBFILE <filename>",
-" Specifies the file which should be used for storing runtime status",
-#ifdef OS2
-" information about active connections. The default is a file called",
-" \"iksd.db\" in the WINDOWS directory.",
-#else
-#ifdef UNIX
-" information about active connections. The default is a file called",
-" \"iksd.db\" in the /var/log directory.",
-#else
-" information about active connections.",
-#endif /* UNIX */
-#endif /* OS2 */
-" ",
-#ifdef OS2
-"SET IKS DEFAULT-DOMAIN <domain-name>",
-" A userid on Windows is of the form DOMAIN\\\\userid. This command",
-" determines which domain will be searched for the userid if a domain",
-" is not specified by the user. On Windows 95/98 when User-level",
-" access is activated in the Network Control Panel, the default ",
-" domain will be automatically set. If the default domain is not",
-" specified, accounts on the local machine will take precedence over",
-" accounts in Domains to which the local machine belongs.",
-#endif /* OS2 */
-" ",
-"SET IKS HELPFILE <filename>",
-" Specifies the name of a file to be displayed if the user types HELP",
-" (not followed by a specific command or topic), in place of the built-in",
-" top-level help text. The file need not fit on one screen; more-prompting",
-" is used if the file is more than one screen long if COMMAND MORE-PROMPTING",
-" is ON, as it is by default.",
-" ",
-"SET IKS INITFILE <filename>",
-" Execute <filename> rather than the normal initialization file for real",
-" users; this option does not apply to anonymous users.",
-" ",
-"SET IKS NO-INITFILE { ON, OFF }",
-" Do not execute an initialization file, even if a real user is logging in.",
-" ",
-"SET IKS SERVER-ONLY { ON, OFF }",
-" If this option is included on the IKSD command line, the Client Side Server"
-,
-" configuration is disabled, and the user will not get a Username: or",
-" Password: prompt, and will not be able to access the IKSD command prompt.",
-" A FINISH command sent to the IKSD will log it out and close the",
-" connection, rather than returning it to its prompt.",
-" ",
-"SET IKS TIMEOUT <number>",
-" This sets a limit (in seconds) on the amount of time the client has to log",
-" in once the connection is made. If successful login does not occur within",
-" the given number of seconds, the connection is closed. The default timeout"
-,
-" is 300 seconds (5 minutes). A value of 0 or less indicates there is to be",
-" no limit.",
-" ",
-"SET IKS USERFILE <filename>",
-#ifdef UNIX
-" This file contains a list of local usernames that are to be denied access",
-" to Internet Kermit Service. The default is /etc/ftpusers. This can be the"
-,
-" same file that is used by wuftpd, and the syntax is the same: one username",
-" per line; lines starting with \"#\" are ignored. Use this option to",
-" specify the name of a different forbidden-user file, or use",
-" \"set iks userfile /dev/null\" to disable this feature in case there is a",
-" /etc/ftpusers file but you don't want to use it.",
-#else
-" This file contains a list of local usernames that are to be denied access",
-" to Internet Kermit Service. The syntax is: one username per line; lines",
-" starting with \"#\" are ignored.",
-#endif /* UNIX */
-" ",
-"SET IKS XFERLOG { ON, OFF }",
-#ifdef UNIX
-" Whether a file-transfer log should be kept. Off by default. If \"on\",",
-" but no SET IKSD XFERFILE command is given, /var/log/iksd.log is used.",
-#else
-" Whether a file-transfer log should be kept. Off by default.",
-#endif /* UNIX */
-" ",
-"SET IKS XFERFILE <filename>",
-" Use this option to specify an iksd log file name. If you include this",
-" option, it implies SET IKS XFERFILE ON.",
-""
-};
-#endif /* NOIKSD */
-
-/* D O H S E T -- Give help for SET command */
-
-int
-dohset(xx) int xx; {
- int x;
-
- if (xx == -3) return(hmsga(hmhset));
- if (xx < 0) return(xx);
-
-#ifdef NEWFTP
- if (xx == XYFTPX)
- return(dosetftphlp());
- if (xx == XYGPR)
- return(hmsga(hmxygpr));
-#endif /* NEWFTP */
-
- if ((x = cmcfm()) < 0) return(x);
- switch (xx) {
-#ifndef NOIKSD
- case XYIKS:
- return(hmsga(hsetiks));
-#endif /* NOIKSD */
-
-case XY_REN:
- return(hmsg("SET RENAME LIST { ON, OFF }\n\
- Tells whether the RENAME command should list its results by default.\n\n\
-SET RENAME COLLISION { FAIL, PROCEED, OVERWRITE }\n\
- Establishes the default action when renaming a file would destroy an\n\
- existing file. See HELP RENAME."));
-
-case XYATTR:
- return(hmsga(hsetat));
-
-case XYBACK:
- return(hmsga(hsetbkg));
-
-case XYBELL:
- return(hmsga(hmxybel));
-
-#ifdef OS2
-case XYPRTY:
- return(hmsg("SET PRIORITY { REGULAR, FOREGROUND-SERVER, TIME-CRITICAL }\n\
- Specifies at which priority level the communication and screen update\n\
- threads should operate. The default value is FOREGROUND-SERVER."));
-
-case XYMSK:
- return(hmsga(hmxymsk));
-#endif /* OS2 */
-
-#ifdef DYNAMIC
-case XYBUF:
- return(hmsga(hsetbuf));
-#endif /* DYNAMIC */
-
-#ifndef NOLOCAL
-case XYCARR:
- return(hmsga(hsetcar));
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
-case XYCASE:
- return(hmsg("Syntax: SET CASE { ON, OFF }\n\
- Tells whether alphabetic case is significant in string comparisons\n\
- done by INPUT, IF, and other commands. This setting is local to the\n\
- current macro or command file, and inherited by subordinates."));
-
-#endif /* NOSPL */
-
-case XYCMD:
- return(hmsga(hsetcmd));
-
-case XYIFD:
- return(hmsg("Syntax: SET INCOMPLETE { DISCARD, KEEP }\n\
- Whether to discard or keep incompletely received files, default is KEEP."));
-
-#ifndef NOSPL
-case XYINPU:
- return(hmsga(hxyinp));
-#endif /* NOSPL */
-
-case XYCHKT:
- return(hmsga(hmxychkt));
-
-#ifndef NOSPL
-case XYCOUN:
- return(hmsg("Syntax: SET COUNT number\n\
- Example: SET COUNT 5\n\
- Set up a loop counter, for use with IF COUNT. Local to current macro\n\
- or command file, inherited by subordinate macros and command files."));
-#endif /* NOSPL */
-
-case XYDEBU:
- return(hmsga(hmxydeb));
-
-case XYDFLT:
- return(hmsg("Syntax: SET DEFAULT directory\n\
- Change directory. Equivalent to CD command."));
-
-case XYDELA:
- return(hmsg("Syntax: SET DELAY number\n\
- Number of seconds to wait before sending first packet after SEND command."));
-
-#ifndef NODIAL
-case XYDIAL:
- return(hmsga(hmxydial));
-#endif /* NODIAL */
-
-#ifdef UNIX
-case XYSUSP:
- return(hmsg("Syntax: SET SUSPEND { OFF, ON }\n\
- Disables SUSPEND command, suspend signals, and <esc-char>Z during CONNECT.")
- );
-#endif
-
-#ifndef NOSCRIPT
-case XYSCRI:
- return(hmsg("Syntax: SET SCRIPT ECHO { OFF, ON }\n\
- Disables/Enables echoing of SCRIPT command operation."));
-#endif /* NOSCRIPT */
-
-case XYTAKE:
- return(hmsga(hxytak));
-
-#ifndef NOLOCAL
-case XYTERM:
- return(hmsga(hxyterm));
-
-case XYDUPL:
- return(hmsg("Syntax: SET DUPLEX { FULL, HALF }\n\
- During CONNECT: FULL means remote host echoes, HALF means Kermit\n\
- does its own echoing."));
-
-case XYLCLE:
- return(hmsg("Syntax: SET LOCAL-ECHO { OFF, ON }\n\
- During CONNECT: OFF means remote host echoes, ON means Kermit\n\
- does its own echoing. Synonym for SET DUPLEX { FULL, HALF }."));
-
-case XYESC:
- return(hmsga(hxyesc)); /* SET ESCAPE */
-#endif /* NOLOCAL */
-
-case XYPRTR: /* SET PRINTER */
- return(hmsga(hxyprtr));
-
-#ifdef OS2
-#ifdef BPRINT
-case XYBDCP: /* SET BPRINTER */
- return(hmsga(hxybprtr));
-#endif /* BPRINT */
-#endif /* OS2 */
-
-case XYEXIT:
- return(hmsga(hxyexit));
-
-case XYFILE:
- return(hmsga(hmxyf));
-
-case XYFLOW:
- return(hmsga(hmxyflo));
-
-case XYHAND:
- return(hmsga(hmxyhsh));
-
-#ifdef NETCONN
-
-case XYHOST:
- return(hmsga(hxyhost));
-
-case XYNET:
- return(hmsga(hxynet));
-
-#ifndef NOTCPOPTS
-#ifdef SOL_SOCKET
-case XYTCP:
- return(hmsga(hxytcp));
-#endif /* SOL_SOCKET */
-#endif /* NOTCPOPTS */
-
-#ifdef ANYX25
-case XYX25:
- return(hmsga(hxyx25));
-
-#ifndef IBMX25
-case XYPAD:
- return(hmsg("Syntax: SET PAD name value\n\
-Set a PAD X.3 parameter with a desired value."));
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-#endif /* NETCONN */
-
-#ifndef NOSPL
-case XYOUTP:
- return(hmsga(hxyout));
-#endif /* NOSPL */
-
-#ifndef NOSETKEY
-case XYKEY: /* SET KEY */
- return(hmsga(hmhskey));
-#endif /* NOSETKEY */
-
-#ifndef NOCSETS
-case XYLANG:
- return(hmsg("Syntax: SET LANGUAGE name\n\
- Selects language-specific translation rules for text-mode file transfers.\n\
- Used with SET FILE CHARACTER-SET and SET TRANSFER CHARACTER-SET when one\n\
- of these is ASCII."));
-#endif /* NOCSETS */
-
-case XYLINE:
- printf("\nSyntax: SET LINE (or SET PORT) [ switches ] [ devicename ]\n\
- Selects a serial-port device to use for making connections.\n");
-#ifdef OS2
-#ifdef NT
- printf("\n");
- printf(
-" You may access communication ports by the traditional \"DOS\" port name\n");
- printf(
-" (e.g. SET PORT COM1) or by the Microsoft Telephony modem name from the\n");
- printf(
-" Modems folder of the Control Panel (e.g. SET PORT TAPI). If one method\n");
- printf(" doesn't work, try the other.\n\n");
-#endif /* NT */
-#else /* OS2 */
- printf(" Typical device name for this platform: %s.\n",ttgtpn());
- printf(" The default device name is %s (i.e. none).\n",dftty);
- if (!dfloc) {
- printf(
-" If you do not give a SET LINE command or if you give a SET LINE command\n");
- printf(
-" with no device name, or if you specify %s as the device name,\n",dftty);
- printf(
-" Kermit will be in \"remote mode\", suitable for use on the far end of a\n");
- printf(
-" connection, e.g. as the file-transfer partner of your desktop communication\
-\n");
- printf(
-" software. If you SET LINE to a specific device other than %s,\n", dftty);
- printf(
-" Kermit is in \"local mode\", suitable for making a connection to another\n"
- );
- printf(
-" computer. SET LINE alone resets Kermit to remote mode.\n");
- }
-#endif /* OS2 */
- printf(
-" To use a modem to dial out, first SET MODEM TYPE (e.g., to USR), then\n");
- printf(
-#ifdef OS2
-" SET PORT COMx (or SET PORT TAPI), SET SPEED, then give a DIAL command.\n");
-#else
-" SET LINE xxx, then SET SPEED, then give a DIAL command.\n");
-#endif /* OS2 */
- printf(
-#ifdef OS2
-" For direct null-modem connections use SET MODEM TYPE NONE, SET PORT COMx,\n"
-#else
-" For direct null-modem connections, use SET MODEM TYPE NONE, SET LINE xxx,\n"
-#endif /* OS2 */
- );
- printf(
-" then SET FLOW, SET SPEED, and CONNECT.\n");
- printf(
-"\nOptional switches:\n\
- /CONNECT - Enter CONNECT mode automatically if SET LINE succeeds.\n");
- printf(
-" /SERVER - Enter server mode automatically if SET LINE succeeds.\n");
-#ifdef VMS
- printf(
-" /SHARE - Open the device in shared mode.\n");
- printf(
-" /NOSHARE - Open the device in exclusive mode.\n");
-#endif /* VMS */
- printf("\n");
- printf(
-"Also see HELP SET MODEM, HELP SET DIAL, HELP SET SPEED, HELP SET FLOW.\n");
- return(0);
-
-#ifndef NOSPL
-case XYMACR:
- return(hmsga(hxymacr));
-#endif /* NOSPL */
-
-#ifndef NODIAL
-case XYMODM:
- return(hmsga(hxymodm));
-#endif /* NODIAL */
-
-case XYPARI:
- return(hmsga(hxypari));
-
-case XYPROM:
- return(hmsga(hmxyprm));
-
-case XYQUIE:
- return(hmsg("Syntax: SET QUIET {ON, OFF}\n\
- Normally OFF. ON disables most information messages during interactive\n\
- operation."));
-
-#ifdef CK_SPEED
-case XYQCTL:
- return(hmsga(hmxyqctl));
-#endif /* CK_SPEED */
-
-case XYRETR:
- return(hmsg("Syntax: SET RETRY number\n\
- In Kermit protocol file transfers: How many times to retransmit a\n\
- particular packet before giving up; 0 = no limit."));
-
-#ifndef NOLOCAL
-case XYSESS:
-#ifdef UNIX
- return(hmsg(
-"Syntax:\n\
- SET SESSION-LOG { BINARY, DEBUG, NULL-PADDED, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef datageneral
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef STRATUS
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef AMIGA
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef GEMDOS
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef OS2
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out NUL and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef VMS
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef OSK
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out LF, NUL and XON/XOFF characters."));
-#else
-#ifdef MAC
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out LF, NUL and XON/XOFF characters."));
-#endif /* MAC */
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* GEMDOS */
-#endif /* AMIGA */
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* OS2ORUNIX */
-
-case XYSPEE:
-#ifdef OS2
-
- return(hmsg("Syntax: SET SPEED number\n\
- Speed for serial-port communication device specified in most recent\n\
- SET PORT command, in bits per second. Type SET SPEED ? for a list of\n\
- possible speeds."));
-#else
- return(hmsg("Syntax: SET SPEED number\n\
- Speed for serial-port communication device specified in most recent\n\
- SET LINE command, in bits per second. Type SET SPEED ? for a list of\n\
- possible speeds. Has no effect on job's controlling terminal."));
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
-case XYRECV:
- return(hmsga(hxyrcv));
-case XYSEND:
- return(hmsga(hxysnd));
-case XYREPT:
- return(hmsga(hxyrpt));
-#endif /* NOXFER */
-
-#ifndef NOSERVER
-case XYSERV:
- return(hmsga(hsetsrv));
-#endif /* NOSERVER */
-
-#ifdef TNCODE
-case XYTEL:
- return(hmsga(hxytel));
-
-case XYTELOP:
- return(hmsga(hxytopt));
-#endif /* TNCODE */
-
-#ifndef NOXMIT
-case XYXMIT:
- return(hmsga(hsetxmit));
-#endif /* NOXMIT */
-
-#ifndef NOCSETS
-case XYUNCS:
- return(hmsg("Syntax: SET UNKNOWN-CHAR-SET action\n\
- DISCARD (default) means reject any arriving files encoded in unknown\n\
- character sets. KEEP means to accept them anyway."));
-#endif /* NOCSETS */
-
-#ifdef UNIX
-case XYWILD:
- return(hmsga(hxywild));
-#endif /* UNIX */
-
-#ifndef NOXFER
-case XYWIND:
- return(hmsga(hxywind));
-case XYXFER:
- return(hmsga(hxyxfer));
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
-#ifdef OS2MOUSE
-case XYMOUSE:
- return(hmsga(hxymouse));
-#endif /* OS2MOUSE */
-#endif /* NOLOCAL */
-
-case XYALRM:
- return(hmsg("Syntax: SET ALARM [ { seconds, hh:mm:ss } ]\n\
- Number of seconds from now, or time of day, after which IF ALARM\n\
- will succeed. 0, or no time at all, means no alarm."));
-
-case XYPROTO:
- return(hmsga(hxyxyz));
-
-#ifdef CK_SPEED
-case XYPREFIX:
- return(hmsg("Syntax: SET PREFIXING { ALL, CAUTIOUS, MINIMAL }\n\
- \
-Selects the degree of control-character prefixing. Also see HELP SET CONTROL."
-));
-#endif /* CK_SPEED */
-
-#ifdef OS2
-case XYLOGIN:
- return(hmsg("Syntax: SET LOGIN { USERID, PASSWORD, PROMPT } <text>\n\
- Provides access information for use by login scripts."));
-#endif /* OS2 */
-
-#ifndef NOSPL
-case XYTMPDIR:
- return(hmsg("Syntax: SET TEMP-DIRECTORY [ <directory-name> ]\n\
- Overrides automatic assignment of \\v(tmpdir) variable."));
-#endif /* NOSPL */
-
-#ifdef OS2
-case XYTITLE:
- return(hmsg("Syntax: SET TITLE <text>\n\
- Sets window title to text instead of using current host/port name."));
-#endif /* OS2 */
-
-#ifndef NOPUSH
-#ifndef NOFRILLS
-case XYEDIT:
- return(hmsg("Syntax: SET EDITOR pathname [ options ]\n\
- Specifies the name of your preferred editor, plus any command-line\n\
- options. SHOW EDITOR displays it."));
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-
-#ifdef BROWSER
-case XYBROWSE:
-#ifdef NT
- return(hmsg("Syntax: SET BROWSER [ pathname [ options ] ]\n\
- Specifies the name of your preferred browser plus any command-line\n\
- options. SHOW BROWSER displays it. Omit pathname and options to use\n\
- ShellExecute."));
-#else
- return(hmsg("Syntax: SET BROWSER [ pathname [ options ] ]\n\
- Specifies the name of your preferred browser plus any command-line\n\
- options. SHOW BROWSER displays it."));
-#endif /* NT */
-#endif /* BROWSER */
-
-#ifdef CK_TAPI
-case XYTAPI:
- return(hmsga(hxytapi));
-#endif /* CK_TAPI */
-
-#ifdef NT
-case XYWIN95:
- return(hmsga(hxywin95));
-#endif /* NT */
-
-#ifndef NOSPL
-case XYFUNC:
- return(hmsga(hxyfunc));
-#endif /* NOSPL */
-
-#ifdef CK_AUTHENTICATION
-case XYAUTH:
- return(hmsga(hmxyauth));
-#else /* CK_AUTHENTICATION */
-#ifdef CK_SSL
-case XYAUTH:
- return(hmsga(hmxyauth));
-#endif /* CK_SSL */
-#endif /* CK_AUTHENTICATION */
-
-#ifdef BROWSER
-case XYFTP:
- return(hmsg("Syntax: SET FTP [ pathname [ options ] ]\n\
- Specifies the name of your ftp client, plus any command-line options.\n\
- SHOW FTP displays it."));
-#endif /* BROWSER */
-
-case XYSLEEP:
- return(hmsg("Syntax: SET SLEEP CANCELLATION { ON, OFF }\n\
- Tells whether SLEEP (PAUSE) or WAIT commands can be interrupted from the\n\
- keyboard; ON by default."));
-
-case XYCD:
- return(hmsga(hmxycd));
-
-case XYSERIAL:
- return(hmsg("Syntax: SET SERIAL dps\n\
- d is data length in bits, 7 or 8; p is first letter of parity; s is stop\n\
- bits, 1 or 2. Examples: \"set serial 7e1\", \"set serial 8n1\"."));
-
-#ifdef HWPARITY
-case XYSTOP:
- return(hmsg("Syntax: SET STOP-BITS { 1, 2 }\n\
- Number of stop bits to use on SET LINE connections, normally 1."));
-#endif /* HWPARITY */
-
-#ifndef NOLOCAL
-case XYDISC:
- return(hmsg("Syntax: SET DISCONNECT { ON, OFF }\n\
- Whether to close and release a SET LINE device automatically upon\n\
- disconnection; OFF = keep device open (default); ON = close and release."));
-#endif /* NOLOCAL */
-
-#ifdef STREAMING
-case XYSTREAM:
- return(hmsg("Syntax: SET STREAMING { ON, OFF, AUTO }\n\
- Tells Kermit whether streaming protocol can be used during Kermit file\n\
- transfers. Default is AUTO, meaning use it if connection is reliable."));
-#endif /* STREAMING */
-
-case XYRELY:
- return(hmsg("Syntax: SET RELIABLE { ON, OFF, AUTO }\n\
- Tells Kermit whether its connection is reliable. Default is AUTO,\n\
- meaning Kermit should figure it out for itself."));
-
-case XYCLEAR:
- return(hmsg("Syntax: SET CLEAR-CHANNEL { ON, OFF, AUTO }\n\
- Tells Kermit whether its connection is transparent to all 8-bit bytes.\n\
- Default is AUTO, meaning Kermit figures it out from the connection type.\n\
- When both sender and receiver agree channel is clear, SET PREFIXING NONE\n\
- is used automatically."));
-
-#ifdef TLOG
-case XYTLOG:
- return(hmsg("Syntax: SET TRANSACTION-LOG { BRIEF, FTP, VERBOSE }\n\
- Selects the transaction-log format; BRIEF and FTP have one line per file;\n\
- FTP is compatible with FTP log. VERBOSE (the default) has more info."));
-#endif /* TLOG */
-
-case XYOPTS:
- return(hmsg("Syntax: SET OPTIONS command [ switches... ]\n\
- For use with commands that have switches; sets the default switches for\n\
- the given command. Type SET OPTIONS ? for a list of amenable commands."));
-
-#ifndef NOSPL
-case XYTIMER:
- return(hmsga(hmxytimer));
-#endif /* NOSPL */
-
-#ifdef CKROOT
- case XYROOT:
- return(hmsga(hmxxchroot));
-#endif /* XYROOT */
-
-#ifdef ANYSSH
- case XYSSH:
- return(hmsga(hmxyssh));
-#endif /* ANYCMD */
-
-#ifdef LOCUS
- case XYLOCUS:
- return(hmsga(hmxylocus));
-#endif /* LOCUS */
-
-#ifdef OS2
-#ifdef KUI
- case XYGUI:
- return(hmsga(hmxygui));
-#endif /* KUI */
-#endif /* OS2 */
-
- case XYMATCH:
- return(hmsga(hmxymatch));
-
-#ifndef NOSEXP
- case XYSEXP:
- return(hmsga(hmxysexp));
-#endif /* NOSEXP */
-
-#ifndef NOSPL
- case XYVAREV:
- return(hmsg("Syntax: SET VARIABLE-EVALUATION { RECURSIVE, SIMPLE }\n\
- Tells Kermit weather to evaluate \\%x and \\&x[] variables recursively\n\
- (which is the default for historical reasons) or by simple string\n\
- replacement, which lets you use these variables safely to store strings\n\
- (such as Windows pathnames) that might contain backslashes."));
-#endif /* NOSPL */
-
-default:
- printf("Not available - \"%s\"\n",cmdbuf);
- return(0);
- }
-}
-
-#ifndef NOSPL
-static char * hfsplit[] = {
-"Function \\fsplit(s1,&a,s2,s3,n2,n3) - Assigns string words to an array.",
-" s1 = source string.",
-" &a = array designator.",
-" s2 = optional break set.",
-" s3 = optional include set (or ALL, CSV, or TSV).",
-" n2 = optional grouping mask.",
-" n3 = optional separator flag:",
-" 0 = collapse adjacent separators;",
-" 1 = don't collapse adjacent separators.",
-" ",
-" \\fsplit() breaks the string s1 into \"words\" as indicated by the other",
-" parameters, assigning them to given array, if any. If the specified",
-" already exists, it is recycled; if no array is specified, the count is",
-" returned but no array is created. All arguments are optional",
-" (\\fsplit() with no arguments returns 0).",
-" ",
-" The BREAK SET is the set of all characters that separate words. The",
-" default break set is all characters except ASCII letters and digits.",
-" ASCII (C0) control characters are treated as break characters by default,",
-" as are spacing and punctuation characters, brackets, and so on, and",
-" all 8-bit characters.",
-" ",
-" The INCLUDE SET is the set of characters that are to be treated as ",
-" parts of words even though they normally would be separators. The",
-" default include set is empty. Three special symbolic include sets are",
-" also allowed:",
-" ",
-" ALL (meaning include all bytes that are not in the break set)",
-" CSV (special treatment for Comma-Separated-Value records)",
-" TSV (special treatment for Tab-Separated-Value records)",
-" ",
-" For operating on 8-bit character sets, the include set should be ALL.",
-" ",
-" If the grouping mask is given and is nonzero, words can be grouped by",
-" quotes or brackets selected by the sum of the following:",
-" ",
-" 1 = doublequotes: \"a b c\"",
-" 2 = braces: {a b c}",
-" 4 = apostrophes: 'a b c'",
-" 8 = parentheses: (a b c)",
-" 16 = square brackets: [a b c]",
-" 32 = angle brackets: <a b c>",
-" ",
-" Nesting is possible with {}()[]<> but not with quotes or apostrophes.",
-" ",
-"Returns integer:",
-" Number of words in source string.",
-" ",
-"Also see:",
-" HELP FUNCTION WORD",
-""
-};
-
-/* D O H F U N C -- Give help for a function */
-
-int
-dohfunc(xx) int xx; {
- /* int x; */
- if (xx == -3) {
- printf("\n Type SHOW FUNCTIONS to see a list of available functions.\n"
- );
- printf(
- " Type HELP FUNCTION <name> for help on a particular function.\n");
- printf(
- " For function settings use HELP SET FUNCTION and SHOW SCRIPTS.\n\n");
- return(0);
- }
- if (xx == FN_WORD) /* Long help message */
- return(hmsga(hmfword));
-
- printf("\n");
- switch (xx) {
- case FN_IND: /* Index (of string 1 in string 2) */
- case FN_RIX: /* Rindex (index from right) */
- printf("\\f%sindex(s1,s2,n1,n2)\n\
- s1 = string to look for.\n\
- s2 = string to look in.\n\
- n1 = optional 1-based starting position, default = 1.\n\
- n2 = optional desired occurrence number, default = 1.\n",
- xx == FN_RIX ? "r" : ""
- );
- printf("Returns integer:\n\
- 1-based position of %smost occurrence of s1 in s2, ignoring the %smost\n\
- (n1-1) characters in s2; returns 0 if s1 not found in s2.\n",
- xx == FN_IND ? "left" : "right",
- xx == FN_IND ? "left" : "right"
- );
- break;
- case FN_COUNT: /* Count occurrences of s1 in s2 */
- printf("\\fcount(s1,s2,n1)\n\
- s1 = string or character to look for.\n\
- s2 = string to look in.\n\
- n1 = optional 1-based starting position, default = 1.\n");
- printf("Returns integer:\n\
- Number of occurrences of s1 in s2, 0 or more.\n");
- break;
-
- case FN_SEARCH: /* Search for pattern */
- case FN_RSEARCH: /* Search for pattern from right */
- printf("\\f%ssearch(s1,s2,n1,n2)\n\
- s1 = pattern to look for.\n\
- s2 = string to look in.\n\
- n1 = optional 1-based offset, default = 1.\n\
- n2 = optional desired occurrence of match, default = 1.\n",
- xx == FN_RSEARCH ? "r" : ""
- );
- printf("Returns integer:\n\
- 1-based position of %smost match for s1 in s2, ignoring the %smost\n\
- (n1-1) characters in s2; returns 0 if no match.\n",
- xx == FN_SEARCH ? "left" : "right",
- xx == FN_SEARCH ? "left" : "right"
- );
- printf(" See HELP WILDCARDS for info about patterns.\n");
- break;
- case FN_LEN: /* Length (of string) */
- printf("\\flength(s1)\n\
- s1 = string.\n");
- printf("Returns integer:\n\
- Length of string s1.\n");
- break;
- case FN_LIT: /* Literal (don't expand the string) */
- printf("\\fliteral(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- s1 literally without evaluation.\n");
- break;
- case FN_LOW: /* Lower (convert to lowercase) */
- printf("\\flower(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- s1 with uppercase letters converted to lowercase.\n");
- break;
- case FN_MAX: /* Max (maximum) */
- printf("\\fmaximum(n1,n2)\n\
- n1 = integer.\n\
- n2 = integer.\n");
- printf("Returns integer:\n\
- The greater of n1 and n2.\n");
- break;
- case FN_MIN: /* Min (minimum) */
- printf("\\fminimum(n1,n2)\n\
- n1 = integer.\n\
- n2 = integer.\n");
- printf("Returns integer:\n\
- The lesser of n1 and n2.\n");
- break;
- case FN_MOD: /* Mod (modulus) */
- printf("\\fmodulus(n1,n2)\n\
- n1 = integer.\n\
- n2 = integer.\n");
- printf("Returns integer:\n\
- The remainder after dividing n1 by n2.\n");
- break;
- case FN_EVA: /* Eval (evaluate arith expression) */
- printf("\\fevaluate(e)\n\
- e = arithmetic expression.\n");
- printf("Returns integer:\n\
- The result of evaluating the expression.\n");
- break;
- case FN_SUB: /* Substr (substring) */
- printf("\\fsubstring(s1,n1,n2)\n\
- s1 = string.\n\
- n1 = integer, 1-based starting position, default = 1.\n\
- n2 = integer, length, default = length(s1) - n1 + 1.\n");
- printf("Returns string:\n\
- Substring of s1 starting at n1, length n2.\n");
- break;
- case FN_UPP: /* Upper (convert to uppercase) */
- printf("\\fupper(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- s1 with lowercase letters converted to uppercase.\n");
- break;
- case FN_REV: /* Reverse (a string) */
- printf("\\freverse(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- s1 with its characters in reverse order.\n");
- break;
- case FN_REP: /* Repeat (a string) */
- printf("\\frepeat(s1,n1)\n\
- s1 = string.\n\
- n1 = integer.\n");
- printf("Returns string:\n\
- s1 repeated n1 times.\n");
- break;
- case FN_EXE: /* Execute (a macro) */
- printf("\\fexecute(m1,a1,a2,a3,...)\n\
- m1 = macro name.\n\
- a1 = argument 1.\n\
- a2 = argument 2, etc\n");
- printf("Returns string:\n\
- The return value of the macro (HELP RETURN for further info).\n");
- break;
- case FN_LPA: /* LPAD (left pad) */
- case FN_RPA: /* RPAD (right pad) */
- printf("\\f%cpad(s1,n1,c1)\n\
- s1 = string.\n\
- n1 = integer.\n\
- c1 = character, default = space.\n",
- xx == FN_LPA ? 'l' : 'r');
- printf("Returns string:\n\
- s1 %s-padded with character c1 to length n1.\n",
- xx == FN_LPA ? "left" : "right");
- break;
- case FN_DEF: /* Definition of a macro, unexpanded */
- printf("\\fdefinition(m1)\n\
- m1 = macro name.\n");
- printf("Returns string:\n\
- Literal definition of macro m1.\n");
- break;
- case FN_CON: /* Contents of a variable, ditto */
- printf("\\fcontents(v1)\n\
- v1 = variable name such as \\%%a.\n");
- printf("Returns string:\n\
- Literal definition of variable v1, evaluated one level only.\n");
- break;
- case FN_FIL: /* Next file */
- printf("\\fnextfile()\n");
- printf("Returns string:\n\
- Name of next file from list created by most recent \\f[r]files() or\n\
- \\f[r]dir()invocation, or an empty string if there are no more files in\n\
- the list.\n");
- break;
- case FN_FC: /* File count */
- printf("\\ffiles(f1[,&a]) - File list.\n\
- f1 = file specification, possibly containing wildcards.\n\
- &a = optional name of array to assign file list to.\n");
- printf("Returns integer:\n\
- The number of regular files that match f1. Use with \\fnextfile().\n");
- break;
- case FN_CHR: /* Character (like BASIC CHR$()) */
- printf("\\fcharacter(n1)\n\
- n1 = integer.\n");
- printf("Returns character:\n\
- The character whose numeric code is n1.\n");
- break;
- case FN_RIG: /* Right (like BASIC RIGHT$()) */
- printf("\\fright(s1,n1)\n\
- s1 = string.\n\
- n1 = integer, default = length(s1).\n");
- printf("Returns string:\n\
- The rightmost n1 characters of string s1.\n");
- break;
- case FN_LEF: /* Left (like BASIC LEFT$()) */
- printf("\\fleft(s1,n1)\n\
- s1 = string.\n\
- n1 = integer, default = length(s1).\n");
- printf("Returns string:\n\
- The leftmost n1 characters of string s1.\n");
- break;
- case FN_COD: /* Code value of character */
- printf("\\fcode(s1)\n\
- c1 = character.\n");
- printf("Returns integer:\n\
- The numeric code of the first character in string s1, or 0 if s1 empty.\n");
- break;
- case FN_RPL: /* Replace */
- printf("\\freplace(s1,s2,s3[,n1])\n\
- s1 = original string.\n\
- s2 = match string.\n\
- s3 = replacement string.\n\
- n1 = occurrence.\n");
- printf("Returns string:\n\
- s1 with occurrence number n1 of s2 replaced by s3.\n\
- If n1 = 0 or omitted, all occurrences are replaced.\n\
- If n1 < 0, occurrences are counted from the right.\n");
- break;
-
- case FN_FD: /* File date */
- printf("\\fdate(f1)\n\
- f1 = filename.\n");
-#ifdef VMS
- printf("Returns string:\n\
- Creation date of file f1, format: yyyymmdd hh:mm:ss.\n");
-#else
- printf("Returns string:\n\
- Modification date of file f1, format: yyyymmdd hh:mm:ss.\n");
-#endif /* VMS */
- break;
- case FN_FS: /* File size */
- printf("\\fsize(f1)\n\
- f1 = filename.\n");
- printf("Returns integer:\n\
- Size of file f1.\n");
- break;
- case FN_VER: /* Verify */
- printf("\\fverify(s1,s2,n1)\n\
- s1 = string of characters to look for.\n\
- s2 = string to look in.\n\
- n1 = starting position in s2.\n");
- printf("Returns integer:\n\
- 1-based position of first character in s2 that is not also in s1,\n\
- or -1 if s1 is empty, or 0 if all characters in s2 are also in s1.\n");
- break;
- case FN_IPA: /* Find and return IP address */
- printf("\\fipaddress(s1,n1)\n\
- s1 = string.\n\
- n1 = 1-based integer starting position, default = 1.\n");
- printf("Returns string:\n\
- First IP address in s1, scanning from left starting at position n1.\n");
- break;
- case FN_HEX: /* Hexify */
- printf("\\fhexify(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- The hexadecimal representation of s1. Also see \\fn2hex().\n");
- break;
- case FN_UNH: /* Unhexify */
- printf("\\funhexify(h1)\n\
- h1 = Hexadecimal string.\n");
- printf("Returns string:\n\
- The result of unhexifying s1, or nothing if s1 is not a hex string.\n");
- break;
- case FN_UNTAB: /* Untabify */
- printf("\\funtabify(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- The result of converting tabs in s1 to spaces assuming tab stops every\n\
- 8 spaces.\n");
- break;
- case FN_BRK: /* Break */
- case FN_SPN: /* Span */
- printf("\\f%s(s1,s2,n1)\n\
- s1 = string to look in.\n\
- s2 = string of characters to look for.\n\
- n1 = 1-based integer starting position, default = 1.\n",
- xx == FN_BRK ? "break" : "span"
- );
- printf("Returns string:\n\
- s1 up to the first occurrence of any character%salso in s2,\n\
- scanning from the left starting at position n1.\n",
- xx == FN_SPN ? " not " : " ");
- break;
- case FN_TRM: /* Trim */
- case FN_LTR: /* Left-Trim */
- printf("\\f%s(s1,s2)\n\
- s1 = string to look in.\n\
- s2 = string of characters to look for, default = blanks and tabs.\n",
- xx == FN_TRM ? "trim" : "ltrim");
- printf("Returns string:\n\
- s1 with all characters that are also in s2 trimmed from the %s.\n.",
- xx == FN_TRM ? "right" : "left");
- break;
- case FN_CAP: /* Capitalize */
- printf("\\fcapitalize(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- s1 with its first letter converted to uppercase and the remaining\n\
- letters to lowercase.\n");
- printf("Synonym: \\fcaps(s1)\n");
- break;
- case FN_TOD: /* Time-of-day-to-secs-since-midnite */
- printf("\\ftod2secs(s1)\n\
- s1 = time-of-day string, hh:mm:ss, 24-hour format.\n");
- printf("Returns number:\n\
- Seconds since midnight.\n");
- break;
- case FN_FFN: /* Full file name */
- printf("\\fpathname(f1)\n\
- f1 = filename, possibly wild.\n");
- printf("Returns string:\n\
- Full pathname of f1.\n");
- break;
- case FN_CHK: /* Checksum of text */
- printf("\\fchecksum(s1)\n\
- s1 = string.\n");
- printf("Returns integer:\n\
- 16-bit checksum of string s1.\n");
- break;
- case FN_CRC: /* CRC-16 of text */
- printf("\\fcrc16(s1)\n\
- s1 = string.\n");
- printf("Returns integer:\n\
- 16-bit cyclic redundancy check of string s1.\n");
- break;
- case FN_BSN: /* Basename of file */
- printf("\\fbasename(f1)\n\
- f1 = filename, possibly wild.\n");
- printf("Returns string:\n\
- Filename f1 stripped of all device and directory information.\n");
- break;
- case FN_CMD: /* Output of a command (cooked) */
- printf("\\fcommand(s1)\n\
- s1 = string\n");
- printf("Returns string:\n\
- Output of system command s1, if any, with final line terminator stripped.\n"
- );
- break;
- case FN_RAW: /* Output of a command (raw) */
- printf("\\frawcommand(s1)\n\
- s1 = string\n");
- printf("Returns string:\n\
- Output of system command s1, if any.\n");
- break;
- case FN_STX: /* Strip from right */
- printf("\\fstripx(s1,c1)\n\
- s1 = string to look in.\n\
- c1 = character to look for, default = \".\".\n");
- printf("Returns string:\n\
- s1 up to the rightmost occurrence of character c1.\n"
- );
- break;
-
- case FN_STL: /* Strip from left */
- printf("\\flop(s1[,c1[,n1]])\n\
- s1 = string to look in.\n\
- c1 = character to look for, default = \".\".\n\
- n1 = occurrence of c1, default = 1.\n");
- printf("Returns string:\n\
- The part of s1 after the n1th leftmost occurrence of character c1.\n"
- );
- break;
-
- case FN_LOPX: /* Strip from right */
- printf("\\flopx(s1,c1)\n\
- s1 = string to look in.\n\
- c1 = character to look for, default = \".\".\n\
- n1 = occurrence of c1, default = 1.\n");
- printf("Returns string:\n\
- The part of s1 after the n1th rightmost occurrence of character c1.\n"
- );
- break;
-
- case FN_STN: /* Strip n chars */
- printf("\\fstripn(s1,n1)\n\
- s1 = string to look in.\n\
- n1 = integer, default = 0.\n");
- printf("Returns string:\n\
- s1 with n1 characters removed from the right.\n"
- );
- break;
-
- case FN_STB: /* Strip enclosing brackets */
- printf("\\fstripb(s1[,c1[,c2]])\n\
- s1 = original string.\n\
- c1 = optional first character\n");
- printf("\
- c2 = optional final character.\n");
- printf("Returns string:\n\
- s1 with the indicated enclosing characters removed. If c1 and c2 not\n\
- specified, any matching brackets, braces, parentheses, or quotes are\n");
- printf("\
- assumed. If c1 is given but not c2, the appropriate c2 is assumed.\n\
- if both c1 and c2 are given, they are used as-is.\n"
- );
- printf(
-"Alternative format:\n\
- Include a grouping mask number in place of c1 and omit c2 to specify more\n\
- than one possibility at once; see \\fword() for details.\n"
- );
- break;
-
-#ifdef OS2
- case FN_SCRN_CX: /* Screen Cursor X Pos */
- printf("\\fscrncurx()\n");
- printf("Returns integer:\n\
- The 0-based X coordinate (column) of the Terminal screen cursor.\n");
- break;
- case FN_SCRN_CY: /* Screen Cursor Y Pos */
- printf("\\fscrncury()\n");
- printf("Returns integer:\n\
- The 0-based Y coordinate (row) of the Terminal screen cursor.\n");
- break;
- case FN_SCRN_STR: /* Screen String */
- printf("\\fscrnstr(ny,nx,n1)\n\
- ny = integer.\n\
- nx = integer.\n\
- n1 = integer.\n");
- printf("Returns string:\n\
- The string at Terminal-screen coordinates (nx,ny), length n1,\n\
- blanks included. Coordinates start at 0. Default values are\n\
- 0 for ny and nx, and line width for n1.\n");
- break;
-#endif /* OS2 */
-
- case FN_2HEX: /* Num to hex */
- printf("\\fn2hex(n1) - Number to hex\n n1 = integer.\n");
- printf("Returns string:\n The hexadecimal representation of n1.\n");
- break;
-
- case FN_2OCT: /* Num to hex */
- printf("\\fn2octal(n1) - Number to octal\n n1 = integer.\n");
- printf("Returns string:\n The octal representation of n1.\n");
- break;
-
-#ifdef RECURSIVE
- case FN_DIR: /* Recursive directory count */
- printf("\\fdirectories(f1) - Directory list.\n\
- f1 = directory specification, possibly containing wildcards.\n\
- &a = optional name of array to assign directory list to.\n");
- printf("Returns integer:\n\
- The number of directories that match f1; use with \\fnextfile().\n");
- break;
-
- case FN_RFIL: /* Recursive file count */
- printf("\\frfiles(f1[,&a]) - Recursive file list.\n\
- f1 = file specification, possibly containing wildcards.\n\
- &a = optional name of array to assign file list to.\n");
- printf("Returns integer:\n\
- The number of files whose names match f1 in the current or given\n\
- directory tree; use with \\fnextfile().\n");
- break;
-
- case FN_RDIR: /* Recursive directory count */
- printf("\\frdirectories(f1) - Recursive directory list.\n\
- f1 = directory specification, possibly containing wildcards.\n\
- &a = optional name of array to assign directory list to.\n");
- printf("Returns integer:\n\
- The number of directories that match f1 in the current or given directory\n\
- tree. Use with \\fnextfile().\n");
- break;
-#endif /* RECURSIVE */
-
- case FN_DNAM: /* Directory part of a filename */
- printf("\\fdirname(f) - Directory part of a filename.\n\
- f = a file specification.\n");
- printf("Returns directory name:\n\
- The full name of the directory that the file is in, or if the file is a\n\
- directory, its full name.\n");
- break;
-
-#ifndef NORANDOM
- case FN_RAND: /* Random number */
- printf("\\frandom(n) - Random number.\n\
- n = a positive integer.\n");
- printf("Returns integer:\n\
- A random number between 0 and n-1.\n");
- break;
-#endif /* NORANDOM */
-
- case FN_SPLIT: /* Split */
-#ifdef COMMENT
- printf("\\fsplit(s1,&a,s2,s3,n2,n3) - \
-Assign string words to an array.\n\
- s1 = source string\n &a = array designator\n s2 = optional break set.\n");
- printf(" s3 = optional include set.\n");
- printf(" n2 = optional grouping mask.\n");
- printf(" n3 = optional separator flag.\n");
- printf(" s2, s3, n2, n3 are as in \\fword().\n");
- printf(
-" All arguments are optional; if \\&a[] already exists, it is recycled;\n\
- if array not specified, the count is returned but no array is created.\n");
- printf("Returns integer:\n\
- Number of words in source string.\n");
-#else
- hmsga(hfsplit);
-#endif /* COMMENT */
- break;
-
- case FN_DTIM: /* CVTDATE */
- printf("\\fcvtdate([date-time][,n1]) - Date/time conversion.\n");
- printf(" Converts date and/or time to standard format.\n");
- printf(" If no date/time given, returns current date/time.\n");
- printf(" [date-time], if given, is free-format date and/or time.\n");
- printf(" HELP DATE for info about date-time formats.\n");
- printf("Returns string:\n\
- Standard-format date and time: yyyymmdd hh:mm:ss (numeric)\n");
- printf(" If n1 is given:\n\
- n1 = 1: yyyy-mmm-dd hh:mm:ss (mmm = English 3-letter month abbreviation)\n\
- n1 = 2: dd-mmm-yyyy hh:mm:ss (ditto)\n\
- n1 = 3: yyyymmddhhmmss (all numeric)\n\
- n1 = 4: Day Mon dd hh:mm:ss yyyy (asctime)\n\
- Other: yyyymmdd hh:mm:dd");
- break;
-
- case FN_JDATE: /* DOY */
- printf("\\fdoy([date-time]) - Day of Year.\n");
- printf(" Converts date and/or time to day-of-year (DOY) format.\n");
- printf(" If no date/time given, returns current date.\n");
- printf(" [date-time], if given, is free-format date and/or time.\n");
- printf(" HELP DATE for info about date-time formats.\n");
- printf("Returns numeric string:\n\
- DOY: yyyyddd, where ddd is 1-based day number in year.\n");
- break;
-
- case FN_PNCVT:
- printf("\\fdialconvert(phone-number) - Convert phone number.\n");
- printf(" Converts the given phone number for dialing according\n");
- printf(
-" to the prevailing dialing rules -- country code, area code, etc.\n");
- printf("Returns string:\n\
- The dial string that would be used if the same phone number had been\n\
- given to the DIAL command.\n"
- );
- break;
-
- case FN_DATEJ: /* DOY2DATE */
- printf("\\fdoy2date([doy[ time]]) - Day of Year to Date.\n");
- printf(" Converts yyyymmm to yyyymmdd\n");
- printf(" If time included, it is converted to 24-hour format.");
- printf(
- "Returns standard date or date-time string yyyymmdd hh:mm:ss\n");
- break;
-
- case FN_MJD:
- printf("\\fmjd([[date][ time]]) - Modified Julian Date (MJD).\n");
- printf(
-" Converts date and/or time to MJD, the number of days since 17 Nov 1858.\n");
- printf(" HELP DATE for info about date-time formats.\n");
- printf("Returns: integer.\n");
- break;
-
- case FN_MJD2:
- printf("\\fmjd2date(mjd) - Modified Julian Date (MJD) to Date.\n");
- printf(" Converts MJD to standard-format date.\n");
- printf("Returns: yyyymmdd.\n");
- break;
-
- case FN_DAY:
- printf("\\fday([[date][ time]]) - Day of Week.\n");
- printf("Returns day of week of given date as Mon, Tue, etc.\n");
- printf("HELP DATE for info about date-time formats.\n");
- break;
-
- case FN_NDAY:
- printf("\\fnday([[date][ time]]) - Numeric Day of Week.\n");
- printf(
- "Returns numeric day of week of given date, 0=Sun, 1=Mon, ..., 6=Sat.\n");
- printf("HELP DATE for info about date-time formats.\n");
- break;
-
- case FN_TIME:
- printf("\\ftime([[date][ time]]) - Time.\n");
- printf(
-"Returns time portion of given date and/or time in hh:mm:ss format.\n");
- printf("If no argument given, returns current time.\n");
- printf("HELP DATE for info about date-time formats.\n");
- break;
-
- case FN_NTIM:
- printf("\\fntime([[date][ time]]) - Numeric Time.\n");
- printf(
-"Returns time portion of given date and/or time as seconds since midnight.\n");
- printf("If no argument given, returns current time.\n");
- printf("HELP DATE for info about date-time formats.\n");
- break;
-
- case FN_N2TIM:
- printf("\\fn2time(seconds) - Numeric Time to Time.\n");
- printf(
-"Returns the given number of seconds in hh:mm:ss format.\n");
- break;
-
- case FN_PERM:
- printf("\\fpermissions(file) - Permissions of File.\n");
- printf(
-#ifdef UNIX
-"Returns permissions of given file as they would be shown by \"ls -l\".\n"
-#else
-#ifdef VMS
-"Returns permissions of given file as they would be shown by \"dir /prot\".\n"
-#else
-"Returns the permissions of the given file.\n"
-#endif /* VMS */
-#endif /* UNIX */
- );
- break;
-
- case FN_ALOOK:
- printf("\\farraylook(pattern,&a) - Lookup pattern in array.\n\
- pattern = String or pattern\n");
- printf(" &a = array designator, can include range specifier.\n");
- printf(
-"Returns number:\n\
- The index of the first matching array element or -1 if none.\n");
- printf("More info:\n\
- HELP PATTERN for pattern syntax.\n HELP ARRAY for arrays.\n");
- break;
-
- case FN_TLOOK:
- printf(
-"\\ftablelook(keyword,&a,[c]) - Lookup keyword in keyword table.\n\
- pattern = String\n");
- printf(" keyword = keyword to look up (can be abbreviated).\n");
- printf(" &a = array designator, can include range specifier.\n");
- printf(" This array must be in alphabetical order.\n");
- printf(" c = Optional field delimiter, colon(:) by default.\n");
- printf(
-"Returns number:\n\
- 1 or greater, index of array element that uniquely matches given keyword;\n"
- );
- printf(
-"or -2 if keyword was ambiguous, or -1 if keyword empty or not found.\n"
- );
- printf("Also see:\n\
- HELP FUNC ARRAYLOOK for a similar function.\n HELP ARRAY for arrays.\n");
- break;
-
- case FN_ABS: /* Absolute */
- printf("\\fabsolute(n1)\n\
- n1 = integer.\n");
- printf("Returns integer:\n\
- The absolute (unsigned) value of n1.\n");
- break;
-
-#ifdef FNFLOAT
- case FN_FPABS:
- printf("\\ffpabsolute(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The absolute (unsigned) value of f1 to d decimal places.\n");
- break;
-
- case FN_FPADD:
- printf("\\ffpadd(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The sum of f1 and f2 to d decimal places.\n");
- break;
-
- case FN_FPSUB:
- printf("\\ffpsubtract(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- f1 minus f2 to d decimal places.\n");
- break;
-
- case FN_FPMUL:
- printf("\\ffpmultiply(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The product of f1 and f2 to d decimal places.\n");
- break;
-
- case FN_FPDIV:
- printf("\\ffpdivide(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- f1 divided by f2 to d decimal places.\n");
- break;
-
- case FN_FPMAX:
- printf("\\ffpmaximum(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The maximum of f1 and f2 to d decimal places.\n");
- break;
-
- case FN_FPMIN:
- printf("\\ffpminimum(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The minimum of f1 and f2 to d decimal places.\n");
- break;
-
- case FN_FPMOD:
- printf("\\ffpmodulus(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The modulus of f1 and f2 to d decimal places.\n");
- break;
-
- case FN_FPPOW:
- printf("\\ffpraise(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- f1 raised to the power f2, to d decimal places.\n");
- break;
-
- case FN_FPCOS:
- printf("\\ffpcosine(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The cosine of angle f1 (in radians) to d decimal places.\n");
- break;
-
- case FN_FPSIN:
- printf("\\ffpsine(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The sine of angle f1 (in radians) to d decimal places.\n");
- break;
-
- case FN_FPTAN:
- printf("\\ffptangent(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The tangent of angle f1 (in radians) to d decimal places.\n");
- break;
-
- case FN_FPEXP:
- printf("\\ffpexp(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- e (the base of natural logarithms) raised to the f1 power,\n\
- to d decimal places.\n");
- break;
-
- case FN_FPINT:
- printf("\\ffpint(f1)\n\
- f1 = floating-point number or integer.\n");
- printf("Returns integer:\n\
- The integer part of f1.\n");
- break;
-
- case FN_FPLOG:
- printf("\\ffplog10(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The logarithm, base 10, of f1 to d decimal places.\n");
- break;
-
- case FN_FPLN:
- printf("\\ffplogn(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The natural logarithm of f1 to d decimal places.\n");
- break;
-
- case FN_FPROU:
- printf("\\ffpround(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- f1 rounded to d decimal places.\n");
- break;
-
- case FN_FPSQR:
- printf("\\ffpsqrt(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The square root of f1 to d decimal places.\n");
- break;
-#endif /* FNFLOAT */
-
-#ifdef CKCHANNELIO
- case FN_FEOF:
- printf("\\f_eof(n1)\n\
- n1 = channel number.\n");
- printf("Returns number:\n\
- 1 if channel n1 at end of file, 0 otherwise.\n");
- break;
- case FN_FPOS:
- printf("\\f_pos(n1)\n\
- n1 = channel number.\n");
- printf("Returns number:\n\
- Read/write pointer of channel n1 as byte number.\n");
- break;
- case FN_NLINE:
- printf("\\f_line(n1)\n\
- n1 = channel number.\n");
- printf("Returns number:\n\
- Read/write pointer of channel n1 as line number.\n");
- break;
- case FN_FILNO:
- printf("\\f_handle(n1)\n\
- n1 = channel number.\n");
- printf("Returns number:\n\
- File %s of open file on channel n1.\n",
-#ifdef OS2
- "handle"
-#else
- "descriptor"
-#endif /* OS2 */
- );
- break;
- case FN_FSTAT:
- printf("\\f_status(n1)\n\
- n1 = channel number.\n");
- printf("Returns number:\n\
- Sum of open modes of channel n1: 1 = read; 2 = write; 4 = append, or:\n\
- 0 if not open.\n");
- break;
- case FN_FGCHAR:
- printf("\\f_getchar(n1)\n\
- n1 = channel number.\n");
- printf(" Reads a character from channel n1 and returns it.\n");
- break;
- case FN_FGLINE:
- printf("\\f_getline(n1)\n\
- n1 = channel number.\n");
- printf(" Reads a line from channel n1 and returns it.\n");
- break;
- case FN_FGBLK:
- printf("\\f_getblock(n1,n2)\n\
- n1 = channel number, n2 = size\n");
- printf(
-" Reads a block of n2 characters from channel n1 and returns it.\n");
- break;
- case FN_FPCHAR:
- printf("\\f_putchar(n1,c)\n\
- n1 = channel number, c = character\n");
- printf(" Writes a character to channel n1.\n\
-Returns number:\n\
- 1 if successful, otherwise a negative error code.\n");
- break;
- case FN_FPLINE:
- printf("\\f_putline(n1,s1)\n\
- n1 = channel number, s1 = string\n");
- printf(
-" Writes the string s1 to channel n1 and adds a line terminator.\n\
-Returns number:\n");
- printf(" How many characters written if successful;\n\
- Otherwise a negative error code.\n"
- );
- break;
- case FN_FPBLK:
- printf("\\f_putblock(n1,s1)\n\
- n1 = channel number, s1 = string\n");
- printf(
-" Writes the string s1 to channel n1.\n\
- Returns number:\n");
- printf(" How many characters written if successful;\n\
- Otherwise a negative error code.\n"
- );
- break;
- case FN_FERMSG:
- printf("\\f_errmsg([n1])\n\
- n1 = numeric error code, \\v(f_error) by default.\n");
- printf(" Returns the associated error message string.\n");
- break;
-#endif /* CKCHANNELIO */
-
- case FN_AADUMP:
- printf("\\faaconvert(name,&a[,&b])\n\
- name = name of associative array, &a and &b = names of regular arrays.\n");
- printf(
-" Converts the given associative array into two regular arrays, &a and &b,\n\
- containing the indices and values, respectively:\n");
- printf("Returns number:\n\
- How many elements were converted.\n");
- break;
-
-#ifdef CK_KERBEROS
- case FN_KRB_TK:
- printf("\\fkrbtickets(n)\n\
- n = Kerberos version number (4 or 5).\n\
- Returns string:\n\
- The number of active Kerberos 4 or 5 tickets.\n\
- Resets the ticket list used by \\fkrbnextticket(n).\n");
- break;
-
- case FN_KRB_NX:
- printf("\\fkrbnextticket(n)\n\
- n = Kerberos version number (4 or 5).\n\
- Returns string:\n\
- The next ticket in the Kerberos 4 or 5 ticket list that was set up by\n\
- the most recent invocation of \\fkrbtickets(n).\n");
- break;
-
- case FN_KRB_IV:
- printf("\\fkrbisvalid(n,name)\n\
- n = Kerberos version number (4 or 5).\n\
- name = a ticket name as returned by \\fkrbnextticket(n).\n\
- Returns number:\n\
- 1 if the ticket is valid, 0 if not valid.\n\
- A ticket is valid if all the following conditions are true:\n\n");
- printf("\n\
- (i) it exists in the current cache file;\n\
- (ii) it is not expired;\n\
- (iii) it is not marked invalid (K5 only);\n\
- (iv) it was issued from the current IP address\n");
- printf("\n This value can be used in an IF statement, e.g.:\n\n");
- printf(" if \\fkrbisvalid(4,krbtgt.FOO.BAR.EDU@FOO.BAR.EDU) ...\n");
- break;
-
- case FN_KRB_TT:
- printf("\\fkrbtimeleft(n,name)\n\
- n = Kerberos version number (4 or 5).\n\
- name = a ticket name as returned by \\fkrbnextticket(n).\n\
- Returns string:\n\
- The number of seconds remaining in the ticket's lifetime.\n");
- break;
-
- case FN_KRB_FG:
- printf("\\fkrbflags(n,name)\n\
- n = Kerberos version number (4 or 5).\n\
- name = a ticket name as returned by \\fkrbnextticket(n).\n\
- Returns string:\n");
- printf(
-" The flags string as reported with AUTH K5 LIST /FLAGS. This string can\n\
- be searched for a particular flag using the \\findex() function when\n\
- SET CASE is ON (for case sensitive searches). Flag strings are only\n\
- available for K5 tickets.\n");
- break;
-#endif /* CK_KERBEROS */
-
- case FN_PATTERN:
- printf("\\fpattern(s)\n\
- s = string\n\
- Returns string: s with any variables, etc, evaluated in the normal manner.\n"
- );
- printf("\
- For use with INPUT, MINPUT, and REINPUT to declare that a search target is\n\
- a pattern rather than a literal string.\n");
- break;
-
- case FN_HEX2N:
- printf("\\fhex2n(s)\n\
- s = hexadecimal number\n\
- Returns decimal equivalent.\n");
- break;
-
- case FN_HEX2IP:
- printf("\\fhex2ip(s)\n\
- s = 8-digit hexadecimal number\n\
- Returns the equivalent decimal dotted IP address.\n");
- break;
-
- case FN_IP2HEX:
- printf("\\fip2hex(s)\n\
- s = decimal dotted IP address\n\
- Returns the equivalent 8-digit hexadecimal number.\n");
- break;
-
- case FN_OCT2N:
- printf("\\foct2n(s)\n\
- s = octal number\n\
- Returns decimal equivalent.\n");
- break;
-
- case FN_TOB64:
- printf("\\b64encode(s)\n\
- s = string containing no NUL bytes\n\
- Returns Base-64 encoding of string.\n");
- break;
-
- case FN_FMB64:
- printf("\\b64decode(s)\n\
- s = string in Base-64 notation\n\
- Returns the decoded string or an error code if s not valid.\n");
- break;
-
- case FN_RADIX:
- printf("\\fradix(s,n1,n2)\n\
- s = number in radix n1\n\
- Returns the number's representation in radix n2.\n");
- break;
-
- case FN_JOIN:
- printf("\\fjoin(&a[,s[,n1[,n2]]])\n\
- &a = array designator, can include range specifier.\n\
- s = optional separator.\n");
- printf("\
- n1 = nonzero to put grouping around elements that contain spaces;\n\
- see \\fword() grouping mask for values of n.\n");
- printf("\
- n2 = 0 or omitted to put spaces between elements; nonzero to omit them.\n");
- printf("\
- Returns the (selected) elements of the array joined to together,\n\
- separated by the separator.\n");
- printf("\n\
- If s is CSV (literally), that means the array is to be transformed into a\n\
- comma-separated list. No other arguments are needed. If s is TSV, then\n\
- a tab-separated list is created.\n");
- break;
-
- case FN_SUBST:
- printf("\\fsubstitute(s1,s2,s3)\n\
- s1 = Source string.\n\
- s2 = List of characters to be translated.\n\
- s3 = List of characters to translate them to.\n");
- printf(
-" Returns: s1, with each character that is in s2 replaced by the\n\
- corresponding character in s3. s2 and s3 can contain ASCII ranges,\n\
- like [a-z]. Any characters in s2 that don't have corresponding\n\
- characters in s3 (after range expansion) are removed from the result.\n\
- This function works only with single-byte character-sets\n");
- break;
-
-#ifndef NOSEXP
- case FN_SEXP:
- printf("\\fsexpression(s1)\n\
- s1 = S-Expression.\n");
- printf(" Returns: The result of evaluating s1.\n");
- break;
-
-#endif /* NOSEXP */
-
- case FN_CMDSTK:
- printf("\\fcmdstack(n1,n2)\n\
- n1 = Command-stack level, 0 to \\v(cmdlevel), default \\v(cmdlevel).\n\
- n2 = Function code, 0 or 1.\n");
- printf("Returns:\n");
- printf(" n2 = 0: name of object at stack level n1\n\
- n2 = 1: type of object at stack level n1:\n\
- 0 = interactive prompt\n\
- 1 = command file\n\
- 2 = macro\n"
- );
- break;
-
-#ifdef CKFLOAT
- case FN_DIFDATE:
- printf("\\fdiffdates(d1,d2)\n\
- d1 = free-format date and/or time (default = NOW).\n\
- d2 = ditto.\n");
- printf("Returns:\n");
- printf(" Difference expressed as delta time:\n");
- printf(" Negative if d2 is later than d1, otherwise positive.\n");
- break;
-#endif /* CKFLOAT */
-
- case FN_CMPDATE:
- printf("\\fcmpdates(d1,d2)\n\
- d1 = free-format date and/or time (default = NOW).\n\
- d2 = ditto.\n");
- printf("Returns:\n");
- printf(" 0 if d1 is equal to d2;\n\
- 1 if d1 is later than d2;\n\
- -1 if d1 is earlier than d2.\n");
- break;
-
- case FN_TOGMT:
- printf("\\futcdate(d1)\n\
- d1 = free-format date and/or time (default = NOW).\n");
- printf("Returns:\n");
- printf(" Date-time converted to UTC (GMT) yyyymmdd hh:mm:ss.\n");
- break;
-
-#ifdef TCPSOCKET
- case FN_HSTADD:
- printf("\\faddr2name(s)\n\
- s = numeric IP address.\n");
- printf("Returns:\n");
- printf(" Corresponding IP hostname if found, otherwise null.\n");
- break;
- case FN_HSTNAM:
- printf("\\fname2addr(s)\n\
- s = IP host name.\n");
- printf("Returns:\n");
- printf(" Corresponding numeric IP address if found, else null.\n");
- break;
-#endif /* TCPSOCKET */
-
- case FN_DELSEC:
- printf("\\fdelta2secs(dt)\n\
- dt = Delta time, e.g. +3d14:27:52.\n");
- printf("Returns:\n");
- printf(" The corresponding number of seconds.\n");
- break;
-
- case FN_PC_DU:
- printf("\\fdos2unixpath(p)\n\
- p = string, DOS pathname.\n");
- printf("Returns:\n");
- printf(" The argument converted to a Unix pathname.\n");
- break;
-
- case FN_PC_UD:
- printf("\\funix2dospath(p)\n\
- p = string, Unix pathname.\n");
- printf("Returns:\n");
- printf(" The argument converted to a DOS pathname.\n");
- break;
-
-#ifdef FN_ERRMSG
- case FN_ERRMSG:
- printf("\\ferrstring(n)\n\
- n = platform-dependent numeric error code.\n");
- printf("Returns:\n");
- printf(" The corresponding error string.\n");
- break;
-#endif /* FN_ERRMSG */
-
- case FN_KWVAL:
- printf("\\fkeywordvalue(s1[,s2])\n\
- s1 = string of the form \"name=value\"\n\
- s2 = one more separator characters (default separator is \"=\")\n");
- printf(" Assigns the value, if any, to the named macro and sets\n");
- printf(" the \\v(lastkeywordvalue) to the macro name.\n");
- printf(" If no value is given, the macro is undefined.\n");
- printf("Returns:\n");
- printf(" -1 on error\n");
- printf(" 0 if no keyword or value were found\n");
- printf(" 1 if a keyword was found but no value\n");
- printf(" 2 if a keyword and a value were found\n");
- printf("Synonym: \\kwvalue(s1[,s2])\n");
- break;
-
-#ifdef COMMENT
- case FN_SLEEP:
- printf("\\fsleep(n)\n\
- n = number of seconds\n");
- printf(" Pauses for the given number of seconds.\n");
- printf("Returns: the empty string.\n");
- break;
-
- case FN_MSLEEP:
- printf("\\fmsleep(n)\n\
- n = number of milliseconds\n");
- printf(" Pauses for the given number of milliseconds.\n");
- printf("Returns: the empty string.\n");
- break;
-#endif /* COMMENT */
-
-#ifdef NT
- case FN_SNAME:
- printf("\\fshortpathname(s)\n\
- s = file or directory name string\n");
- printf(" Returns the short path form of the given input.\n");
- break;
-
- case FN_LNAME:
- printf("\\flongpathname(s)\n\
- s = file or directory name string\n");
- printf(" Returns the long path form of the given input.\n");
- break;
-#else
- case FN_SNAME:
- printf("\\fshortpathname(s)\n\
- Synonym for \fpathname()\n");
- break;
-
- case FN_LNAME:
- printf("\\flongpathname(s)\n\
- Synonym for \fpathname()\n");
- break;
-#endif /* NT */
-
- case FN_EMAIL:
- printf("\\femailaddress(s)\n\
- s = From: or Sender: header from an RFC2822-format email message\n");
- printf(" Extracts and returns the email address.\n");
- break;
-
- case FN_PICTURE:
- printf("\\fpictureinfo(s[,&a])\n\
- s = File specification of a JPG or GIF picture file.\n\
- &a = Optional array name.\n\n");
- printf("Returns integer:\n\
- 0 if file not found or not recognized;\n\
- 1 if orientation is landscape;\n\
- 2 if orientation is portrait.\n\n");
- printf(" If an array name is included, element 1 is filled \
-in with the image width\n\
- in pixels, and element 2 the image height.\n");
- break;
-
- case FN_PID:
- printf("\\fgetpidinfo(n1)\n\
- n1 = Numeric process ID\n");
- printf("Returns integer:\n\
- -1 on failure to get information;\n\
- 1 if n1 is the ID of an active process;\n\
- 0 if the process does not exist.\n");
- break;
-
- case FN_FUNC:
- printf("\\ffunction(s1)\n\
- s1 = name of function.\n");
- printf("Returns integer:\n\
- 1 if s1 is the name of an available built-in function;\n\
- 0 otherwise.\n");
- break;
-
- case FN_RECURSE:
- printf("\\frecurse(s1)\n\
- s1 = name of \\&x or \\&x[] type variable\n");
- printf("Returns the result of evaluating the variable recursively.\n");
- break;
-
- case FN_SQUEEZE:
- printf("\\fsqueeze(s)\n\
- s = string\n\
- Returns string with leading and trailing whitespace removed, Tabs\n\
- converted to Spaces, and multiple spaces converted to single spaces.\n");
- break;
-
-#ifndef NOCSETS
- case FN_XLATE:
- printf("\\fcvtcset(s,cset1,cset2)\n\
- s = string\n\
- Returns string converted from character set cset1 to cset2, where cset1\n\
- and cset2 are names of File Character-Sets \
-('set file char ?' for a list).\n");
- break;
-#endif /* NOCSETS */
-
- case FN_UNPCT:
- printf("\\fdecodehex(s1[,s2])\n\
- s1, s2 = strings\n\
- Decodes a string s1 that contains prefixed hex bytes. s2 is the prefix;\n\
- the default is %%%%. You can specify any other prefix one or two bytes\n\
- long. If the prefix contains letters (such as 0x), case is ingored.\n\
- Returns string s1 with hex escapes replaced by the bytes they \
-represent.\n");
- break;
-
- case FN_STRINGT:
- printf("\\fstringtype(s)\n\
- s = string\n\
- Returns a string representing the type of its string argument s1:\n\
- 7BIT, 8BIT, UTF8, TEXT, or BINARY. TEXT means some kind of text\n\
- other than 7BIT, 8BIT, or UTF8 (this probably will never appear).\n");
- break;
-
- case FN_STRCMP:
- printf("\\fstrcmp(s1,s2[,case[,start[,length]]])\n\
- s1, s2 = strings\n\
- case, start, length = numbers or arithmetic expressions.\n\
- case = 0 [default] means to do a case-independent comparison;\n\
- nonzero case requests a case-sensitive comparison.\n\
- The optional start and length arguments apply to both s1 and s2\n\
- and allow specification of substrings if it is not desired to compare\n\
- the whole strings. Results for non-ASCII strings are implentation-\n\
- and locale-dependent.\n\
- Returns a number:\n\
- -1: s1 is lexically less than s2;\n\
- 0: s1 and s2 are lexically equal;\n\
- 2: s1 is lexically greater than s2.\n");
- break;
-
- default:
- printf("Sorry, help not available for \"%s\"\n",cmdbuf);
- }
- printf("\n");
- return(0);
-}
-#endif /* NOSPL */
-
-#ifdef OS2
-#ifndef NOKVERBS
-
-/* D O H K V E R B -- Give help for a Kverb */
-
-int
-dohkverb(xx) int xx; {
- int x,i,found,button,event;
-
- if (xx == -3) {
- printf("\n Type SHOW KVERBS to see a list of available Kverbs.\n"
- );
- printf(
-" Type HELP KVERB <name> to see the current definition of a given Kverb.\n\n"
- );
- return(-9);
- }
- if (xx < 0) return(xx);
- if ((x = cmcfm()) < 0) return(x);
- switch ( xx ) {
- /* DEC VT keyboard key definitions */
-
- case K_COMPOSE : /* Compose key */
- printf("\\Kcompose Compose an accented character\n");
- break;
- case K_C_UNI16 : /* UCS2 key */
- printf("\\Kucs2 Enter a Unicode character\n");
- break;
-
-/* DEC arrow keys */
-
- case K_UPARR : /* DEC Up Arrow key */
- printf("\\Kuparr Transmit Terminal Up Arrow sequence\n");
- break;
- case K_DNARR : /* DEC Down Arrow key */
- printf("\\Kdnarr Transmit Terminal Down Arrow sequence\n");
- break;
- case K_RTARR : /* DEC Right Arrow key */
- printf("\\Krtarr Transmit Terminal Right Arrow sequence\n");
- break;
- case K_LFARR : /* DEC Left Arrow key */
- printf("\\Klfarr Transmit Terminal Left Arrow sequence\n");
- break;
-
- case K_PF1 : /* DEC PF1 key */
- printf("\\Kpf1,\\Kgold Transmit DEC PF1 sequence\n");
- break;
- case K_PF2 : /* DEC PF2 key */
- printf("\\Kpf2 Transmit DEC PF2 sequence\n");
- break;
- case K_PF3 : /* DEC PF3 key */
- printf("\\Kpf3 Transmit DEC PF3 sequence\n");
- break;
- case K_PF4 : /* DEC PF4 key */
- printf("\\Kpf4 Transmit DEC PF4 sequence\n");
- break;
-
- case K_KP0 : /* DEC Keypad 0 */
- printf("\\Kkp0 Transmit DEC Keypad-0 sequence\n");
- break;
- case K_KP1 : /* DEC Keypad 1 */
- printf("\\Kkp1 Transmit DEC Keypad-1 sequence\n");
- break;
- case K_KP2 : /* etc ... through 9 */
- printf("\\Kkp2 Transmit DEC Keypad-2 sequence\n");
- break;
- case K_KP3 :
- printf("\\Kkp3 Transmit DEC Keypad-3 sequence\n");
- break;
- case K_KP4 :
- printf("\\Kkp4 Transmit DEC Keypad-4 sequence\n");
- break;
- case K_KP5 :
- printf("\\Kkp5 Transmit DEC Keypad-5 sequence\n");
- break;
- case K_KP6 :
- printf("\\Kkp6 Transmit DEC Keypad-6 sequence\n");
- break;
- case K_KP7 :
- printf("\\Kkp7 Transmit DEC Keypad-7 sequence\n");
- break;
- case K_KP8 :
- printf("\\Kkp8 Transmit DEC Keypad-8 sequence\n");
- break;
- case K_KP9 :
- printf("\\Kkp9 Transmit DEC Keypad-9 sequence\n");
- break;
- case K_KPCOMA : /* DEC keypad comma */
- printf("\\Kkpcoma Transmit DEC Keypad-Comma sequence\n");
- break;
- case K_KPMINUS : /* DEC keypad minus */
- printf("\\Kkpminus Transmit DEC Keypad-Minus sequence\n");
- break;
- case K_KPDOT : /* DEC keypad period */
- printf("\\Kkpdot Transmit DEC Keypad-Period sequence\n");
- break;
- case K_KPENTER : /* DEC keypad enter */
- printf("\\Kkpenter Transmit DEC Keypad-Enter sequence\n");
- break;
-
-/* DEC Top-Rank F keys */
-
- case K_DECF1 : /* DEC F1 key */
- printf("\\Kdecf1 Transmit DEC F1 sequence for PC keyboard\n");
- break;
- case K_DECF2 : /* DEC F2 key */
- printf("\\Kdecf2 Transmit DEC F2 sequence for PC keyboard\n");
- break;
- case K_DECF3 : /* DEC F3 key */
- printf("\\Kdecf3 Transmit DEC F3 sequence for PC keyboard\n");
- break;
- case K_DECF4 : /* DEC F4 key */
- printf("\\Kdecf4 Transmit DEC F4 sequence for PC keyboard\n");
- break;
- case K_DECF5 : /* DEC F5 key */
- printf("\\Kdecf5 Transmit DEC F5 sequence for PC keyboard\n");
- break;
- case K_DECHOME: /* DEC HOME key */
- printf("\\Kdechome Transmit DEC HOME sequence for PC keyboard\n");
- break;
-
- case K_DECF6 : /* DEC F6 key */
- printf("\\Kdecf6 Transmit DEC F6 sequence\n");
- break;
- case K_DECF7 : /* etc, through F20 */
- printf("\\Kdecf7 Transmit DEC F7 sequence\n");
- break;
- case K_DECF8 :
- printf("\\Kdecf8 Transmit DEC F8 sequence\n");
- break;
- case K_DECF9 :
- printf("\\Kdecf9 Transmit DEC F9 sequence\n");
- break;
- case K_DECF10 :
- printf("\\Kdecf10 Transmit DEC F10 sequence\n");
- break;
- case K_DECF11 :
- printf("\\Kdecf11 Transmit DEC F11 sequence\n");
- break;
- case K_DECF12 :
- printf("\\Kdecf12 Transmit DEC F12 sequence\n");
- break;
- case K_DECF13 :
- printf("\\Kdecf13 Transmit DEC F13 sequence\n");
- break;
- case K_DECF14 :
- printf("\\Kdecf14 Transmit DEC F14 sequence\n");
- break;
- case K_DECHELP : /* DEC Help key */
- printf("\\Kdecf15,\\Kdechelp Transmit DEC HELP sequence\n");
- break;
- case K_DECDO : /* DEC Do key */
- printf("\\Kdecf16,\\Kdecdo Transmit DEC DO sequence\n");
- break;
- case K_DECF17 :
- printf("\\Kdecf17 Transmit DEC F17 sequence\n");
- break;
- case K_DECF18 :
- printf("\\Kdecf18 Transmit DEC F18 sequence\n");
- break;
- case K_DECF19 :
- printf("\\Kdecf19 Transmit DEC F19 sequence\n");
- break;
- case K_DECF20 :
- printf("\\Kdecf20 Transmit DEC F20 sequence\n");
- break;
-
-/* DEC editing keys */
-
- case K_DECFIND : /* DEC Find key */
- printf("\\Kdecfind Transmit DEC FIND sequence\n");
- break;
- case K_DECINSERT : /* DEC Insert key */
- printf("\\Kdecinsert Transmit DEC INSERT HERE sequence\n");
- break;
- case K_DECREMOVE : /* DEC Remove key */
- printf("\\Kdecremove Transmit DEC REMOVE sequence\n");
- break;
- case K_DECSELECT : /* DEC Select key */
- printf("\\Kdecfselect Transmit DEC SELECT sequence\n");
- break;
- case K_DECPREV : /* DEC Previous Screen key */
- printf("\\Kdecprev Transmit DEC PREV SCREEN sequence\n");
- break;
- case K_DECNEXT : /* DEC Next Screen key */
- printf("\\Kdecnext Transmit DEC NEXT SCREEN sequence\n");
- break;
-
-/* DEC User-Defined Keys */
-
- case K_UDKF1 : /* F1 - F5 are XTERM extensions */
- printf("\\Kudkf1 Transmit XTERM F1 User Defined Key sequence\n");
- break;
- case K_UDKF2 :
- printf("\\Kudkf2 Transmit XTERM F2 User Defined Key sequence\n");
- break;
- case K_UDKF3 :
- printf("\\Kudkf3 Transmit XTERM F3 User Defined Key sequence\n");
- break;
- case K_UDKF4 :
- printf("\\Kudkf4 Transmit XTERM F4 User Defined Key sequence\n");
- break;
- case K_UDKF5 :
- printf("\\Kudkf5 Transmit XTERM F5 User Defined Key sequence\n");
- break;
- case K_UDKF6 : /* DEC User Defined Key F6 */
- printf("\\Kudkf6 Transmit DEC F6 User Defined Key sequence\n");
- break;
- case K_UDKF7 : /* DEC User Defined Key F7 */
- printf("\\Kudkf7 Transmit DEC F7 User Defined Key sequence\n");
- break;
- case K_UDKF8 : /* etc ... through F20 */
- printf("\\Kudkf8 Transmit DEC F8 User Defined Key sequence\n");
- break;
- case K_UDKF9 :
- printf("\\Kudkf9 Transmit DEC F9 User Defined Key sequence\n");
- break;
- case K_UDKF10 :
- printf("\\Kudkf10 Transmit DEC F10 User Defined Key sequence\n");
- break;
- case K_UDKF11 :
- printf("\\Kudkf11 Transmit DEC F11 User Defined Key sequence\n");
- break;
- case K_UDKF12 :
- printf("\\Kudkf12 Transmit DEC F12 User Defined Key sequence\n");
- break;
- case K_UDKF13 :
- printf("\\Kudkf13 Transmit DEC F13 User Defined Key sequence\n");
- break;
- case K_UDKF14 :
- printf("\\Kudkf14 Transmit DEC F14 User Defined Key sequence\n");
- break;
- case K_UDKHELP :
- printf(
- "\\Kudkhelp,\\Kudkf15 Transmit DEC HELP User Defined Key sequence\n");
- break;
- case K_UDKDO :
- printf(
- "\\Kudkdo,\\Kudkf16 Transmit DEC DO User Defined Key sequence\n");
- break;
- case K_UDKF17 :
- printf("\\Kudkf17 Transmit DEC F17 User Defined Key sequence\n");
- break;
- case K_UDKF18 :
- printf("\\Kudkf18 Transmit DEC F18 User Defined Key sequence\n");
- break;
- case K_UDKF19 :
- printf("\\Kudkf19 Transmit DEC F19 User Defined Key sequence\n");
- break;
- case K_UDKF20 :
- printf("\\Kudkf20 Transmit DEC F20 User Defined Key sequence\n");
- break;
-
-/* Emacs Keys */
- case K_EMACS_OVER:
- printf(
- "\\Kemacs_overwrite Transmit EMACS Overwrite toggle command sequence\n");
- break;
-
-/* Kermit screen-scrolling keys */
-
- case K_DNONE : /* Screen rollback: down one line */
- printf("\\Kdnone Screen rollback: down one line\n");
- break;
- case K_DNSCN : /* Screen rollback: down one screen */
- printf("\\Kdnscn Screen rollback: down one screen\n");
- break;
- case K_UPONE : /* Screen rollback: Up one line */
- printf("\\Kupone Screen rollback: up one line\n");
- break;
- case K_UPSCN : /* Screen rollback: Up one screen */
- printf("\\Kupscn Screen rollback: up one screen\n");
- break;
- case K_ENDSCN : /* Screen rollback: latest screen */
- printf("\\Kendscn Screen rollback: latest screen\n");
- break;
- case K_HOMSCN : /* Screen rollback: oldest screen */
- printf("\\Khomscn Screen rollback: oldest screen\n");
- break;
- case K_GO_BOOK : /* Scroll to bookmark */
- printf("\\Kgobook Screen rollback: go to bookmark\n");
- break;
- case K_GOTO : /* Scroll to line number */
- printf("\\Kgoto Screen rollback: go to line number\n");
- break;
-
- case K_LFONE : /* Horizontal Scroll: Left one cell */
- printf("\\Klfone Horizontal Scroll: Left one column\n");
- break;
- case K_LFPAGE : /* Horizontal Scroll: Left one page */
- printf("\\Klfpage Horizontal Scroll: Left eight columns\n");
- break;
- case K_LFALL :
- printf("\\Klfall Horizontal Scroll: Left to margin\n");
- break;
- case K_RTONE : /* Horizontal Scroll: Right one cell */
- printf("\\Krtone Horizontal Scroll: Right one column\n");
- break;
- case K_RTPAGE : /* Horizontal Scroll: Right one page */
- printf("\\Krtpage Horizontal Scroll: Right eight columns\n");
- break;
- case K_RTALL :
- printf("\\Krtall Horizontal Scroll: Right to margin\n");
- break;
-
-/* Keyboard language switching verbs */
-
- case K_KB_ENG : /* English keyboard mode */
- printf("\\Kkbenglish Switch to Normal (English) keyboard mode\n");
- break;
- case K_KB_HEB : /* Hebrew keyboard mode */
- printf("\\Kkbhebrew Switch to Hebrew keyboard mode\n");
- break;
- case K_KB_RUS : /* Russian keyboard mode */
- printf("\\Kkbrussian Switch to Russian keyboard mode\n");
- break;
- case K_KB_EMA : /* Emacs keyboard mode */
- printf("\\Kkbemacs Switch to EMACS keyboard mode\n");
- break;
- case K_KB_WP : /* Word Perfect 5.1 mode */
- printf("\\Kkbwp Switch to Word Perfect 5.1 keyboard mode\n");
- break;
-
-/* Mark Mode actions */
-
- case K_MARK_START : /* Enter Mark Mode/Start marking */
- printf("\\Kmarkstart Mark Mode: Enter mode or Start marking\n");
- break;
- case K_MARK_CANCEL : /* Exit Mark Mode - Do Nothing */
- printf("\\Kmarkcancel Mark Mode: Cancel mode\n");
- break;
- case K_MARK_COPYCLIP: /* Exit Mark Mode - Copy data to clipboard */
- printf("\\Kmarkcopyclip Mark Mode: Copy marked text to clipboard\n");
- break;
- case K_MARK_COPYHOST: /* Exit Mark Mode - Copy data to host */
- printf("\\Kmarkcopyhost Mark Mode: Copy marked text to host\n");
- break;
- case K_MARK_SELECT : /* Exit Mark Mode - Select */
- printf(
- "\\Kmarkselect Mark Mode: Place marked text into \\v(select)\n");
- break;
- case K_BACKSRCH : /* Search Backwards for text */
- printf("\\Kbacksearch Search: Begin backward search for text\n");
- break;
- case K_FWDSRCH : /* Search Forwards for text */
- printf("\\Kfwdsearch Search: Begin forward search for text\n");
- break;
- case K_BACKNEXT : /* Search Backwards for next instance of text */
- printf(
- "\\Kbacknext Search: Find next instance of text backwards\n");
- break;
- case K_FWDNEXT : /* Search Forwards for next instance of text */
- printf("\\Kfwdnext Search: Find next instance of text forwards\n");
- break;
-
-/* Miscellaneous Kermit actions */
-
- case K_EXIT : /* Return to command parser */
- printf("\\Kexit Toggle between COMMAND and CONNECT modes\n");
- break;
- case K_BREAK : /* Send a BREAK */
- printf("\\Kbreak Transmit BREAK signal to host\n");
- break;
- case K_RESET : /* Reset emulator */
- printf("\\Kreset Reset Terminal Emulator to user defaults\n");
- break;
- case K_DOS : /* Push to DOS (i.e. OS/2) */
- printf("\\Kdos,\\Kos2 Push to Command Shell\n");
- break;
- case K_HANGUP : /* Hang up the connection */
- printf("\\Khangup Hangup the active connection\n");
- break;
- case K_DUMP : /* Dump/Print current screen */
- printf(
- "\\Kdump Dump/copy current screen to SET PRINTER device/file\n");
- break;
- case K_LBREAK : /* Send a Long BREAK */
- printf("\\Klbreak Transmit LONG BREAK signal to host\n");
- break;
- case K_NULL : /* Send a NUL */
- printf("\\Knull Transmit NULL ('\0') character to host\n");
- break;
- case K_HELP : /* Pop-up help */
- printf("\\Khelp Raise Pop-Up help display\n");
- break;
- case K_HOLDSCRN : /* Hold screen */
- printf("\\Kholdscrn Pause data input during CONNECT mode\n");
- break;
- case K_IGNORE : /* Ignore this key, don't even beep */
- printf("\\Kignore Ignore key\n");
- break;
-
- case K_LOGOFF : /* Turn off session logging */
- printf("\\Klogoff Turn off session logging (see \\Ksession)\n");
- break;
- case K_LOGON : /* Turn on session logging */
- printf("\\Klogon Turn on session logging (see \\Ksession)\n");
- break;
- case K_SESSION:
- printf(
- "\\Ksession Toggle on/off session logging to 'session.log'\n");
- break;
- case K_AUTODOWN:
- printf("\\Kautodown Toggle on/off terminal autodownload.\n");
- break;
- case K_BYTESIZE:
- printf(
- "\\Kbytesize Toggle terminal bytesize between 7 and 8 bits.\n");
- break;
-
-#ifdef COMMENT
- case MODELINE:
- case K_NETHOLD : /* Put network connection on hold */
- case K_NEXTSESS : /* Toggle to next network session */
-#endif /* COMMENT */
-
- case K_CURSOR_URL:
- printf(
- "\\Kurl Treat text under cursor position as a URL\n");
- break;
- case K_STATUS : /* Show status */
- printf(
- "\\Kstatus Toggle statusline (None, Indicator, Host Writeable)\n");
- break;
- case K_TERMTYPE : /* Toggle term type: text/graphics */
- printf("\\Ktermtype Toggle Terminal Type\n");
- break;
- case K_PRTCTRL : /* Print Controller mode */
- printf("\\Kprtctrl Toggle Ctrl-Print (transparent) mode\n");
- break;
- case K_PRINTFF : /* Print formfeed */
- printf("\\Kprintff Output Form Feed to SET PRINTER device\n");
- break;
- case K_FLIPSCN : /* Flip screen */
- printf("\\Kflipscn Reverse foreground and background colors\n");
- break;
- case K_DEBUG : /* Toggle debugging */
- printf("\\Kdebug Toggle Terminal Debug mode\n");
- break;
- case K_TN_SAK : /* TELNET Secure Access Key */
- printf("\\Ktn_sak TELNET: IBM Secure Access Key\n");
- printf(" Used to request a Trusted Shell with AIX\n");
- break;
- case K_TN_AO : /* TELNET Cancel Output */
- printf("\\Ktn_ao TELNET: Transmit Cancel-Output request\n");
- break;
- case K_TN_AYT : /* TELNET Are You There */
- printf("\\Ktnayt TELNET: Transmit Are You There? request\n");
- break;
- case K_TN_EC : /* TELNET Erase Character */
- printf("\\Ktn_ec TELNET: Transmit Erase Character request\n");
- break;
- case K_TN_EL : /* TELNET Erase Line */
- printf("\\Ktn_el TELNET: Transmit Erase Line request\n");
- break;
- case K_TN_GA : /* TELNET Go Ahead */
- printf("\\Ktn_ga TELNET: Transmit Go Ahead request\n");
- break;
- case K_TN_IP : /* TELNET Interrupt Process */
- printf("\\Ktn_ip TELNET: Transmit Interrupt Process request\n");
- break;
- case K_TN_LOGOUT : /* TELNET Logout */
- printf("\\Ktn_logout TELNET: Transmit Do Logout Option\n");
- break;
- case K_TN_NAWS : /* TELNET NAWS */
- printf(
- "\\Ktn_naws TELNET: Transmit Window Size if NAWS is active\n");
- break;
- case K_PASTE : /* Paste data from clipboard */
- printf("\\Kpaste Paste data from clipboard to host\n");
- break;
- case K_CLRSCRN : /* Clear Terminal Screen */
- printf("\\Kclearscreen Clear the Terminal screen\n");
- break;
- case K_PRTAUTO : /* Print Auto mode */
- printf("\\Kprtauto Toggle Auto-Print mode\n");
- break;
- case K_PRTCOPY : /* Print Copy mode */
- printf("\\Kprtcopy Toggle Copy-Print mode\n");
- break;
- case K_ANSWERBACK : /* Transmit Answerback String */
- printf("\\Kanswerback Transmit answerback string to host\n");
- break;
- case K_SET_BOOK : /* Set Bookmark */
- printf("\\Ksetbook Set bookmark\n");
- break;
- case K_QUIT : /* Quit Kermit */
- printf("\\Kquit Hangup connection and quit kermit\n");
- break;
- case K_KEYCLICK : /* Toggle Keyclick */
- printf("\\Kkeyclick Toggle Keyclick mode\n");
- break;
- case K_LOGDEBUG : /* Toggle Debug Log File */
- printf("\\Klogdebug Toggle Debug Logging to File\n");
- break;
- case K_FNKEYS : /* Show Function Key Labels */
- printf("\\Kfnkeys Display Function Key Labels\n");
- break;
-
-#ifdef OS2MOUSE
-/* Mouse only Kverbs */
-
- case K_MOUSE_CURPOS :
- printf("\\Kmousecurpos Mouse: Move host cursor to position\n");
- break;
- case K_MOUSE_MARK :
- printf(
- "\\Kmousemark Mouse: Mark text for selection (drag event only)\n");
- break;
- case K_MOUSE_URL :
- printf("\\Kmouseurl Mouse: Start browser with selected URL\n");
- break;
-#endif /* OS2MOUSE */
-
-/* ANSI Function Key definitions */
- case K_ANSIF01 :
- printf("\\Kansif01 Transmit SCOANSI/AT386: F1 \n");
- break;
- case K_ANSIF02 :
- printf("\\Kansif02 Transmit SCOANSI/AT386: F2 \n");
- break;
- case K_ANSIF03 :
- printf("\\Kansif03 Transmit SCOANSI/AT386: F3 \n");
- break;
- case K_ANSIF04 :
- printf("\\Kansif04 Transmit SCOANSI/AT386: F4 \n");
- break;
- case K_ANSIF05 :
- printf("\\Kansif05 Transmit SCOANSI/AT386: F5 \n");
- break;
- case K_ANSIF06 :
- printf("\\Kansif06 Transmit SCOANSI/AT386: F6 \n");
- break;
- case K_ANSIF07 :
- printf("\\Kansif07 Transmit SCOANSI/AT386: F7 \n");
- break;
- case K_ANSIF08 :
- printf("\\Kansif08 Transmit SCOANSI/AT386: F8 \n");
- break;
- case K_ANSIF09 :
- printf("\\Kansif09 Transmit SCOANSI/AT386: F9 \n");
- break;
- case K_ANSIF10 :
- printf("\\Kansif10 Transmit SCOANSI/AT386: F10\n");
- break;
- case K_ANSIF11 :
- printf("\\Kansif11 Transmit SCOANSI/AT386: F11\n");
- break;
- case K_ANSIF12 :
- printf("\\Kansif12 Transmit SCOANSI/AT386: F12\n");
- break;
- case K_ANSIF13 :
- printf("\\Kansif13 Transmit SCOANSI/AT386: Shift-F1 \n");
- break;
- case K_ANSIF14 :
- printf("\\Kansif14 Transmit SCOANSI/AT386: Shift-F2 \n");
- break;
- case K_ANSIF15 :
- printf("\\Kansif15 Transmit SCOANSI/AT386: Shift-F3 \n");
- break;
- case K_ANSIF16 :
- printf("\\Kansif16 Transmit SCOANSI/AT386: Shift-F4 \n");
- break;
- case K_ANSIF17 :
- printf("\\Kansif17 Transmit SCOANSI/AT386: Shift-F5 \n");
- break;
- case K_ANSIF18 :
- printf("\\Kansif18 Transmit SCOANSI/AT386: Shift-F6 \n");
- break;
- case K_ANSIF19 :
- printf("\\Kansif19 Transmit SCOANSI/AT386: Shift-F7 \n");
- break;
- case K_ANSIF20 :
- printf("\\Kansif20 Transmit SCOANSI/AT386: Shift-F8 \n");
- break;
- case K_ANSIF21 :
- printf("\\Kansif21 Transmit SCOANSI/AT386: Shift-F9 \n");
- break;
- case K_ANSIF22 :
- printf("\\Kansif22 Transmit SCOANSI/AT386: Shift-F10\n");
- break;
- case K_ANSIF23 :
- printf("\\Kansif23 Transmit SCOANSI/AT386: Shift-F11\n");
- break;
- case K_ANSIF24 :
- printf("\\Kansif24 Transmit SCOANSI/AT386: Shift-F12\n");
- break;
- case K_ANSIF25 :
- printf("\\Kansif25 Transmit SCOANSI/AT386: Ctrl-F1 \n");
- break;
- case K_ANSIF26 :
- printf("\\Kansif26 Transmit SCOANSI/AT386: Ctrl-F2 \n");
- break;
- case K_ANSIF27 :
- printf("\\Kansif27 Transmit SCOANSI/AT386: Ctrl-F3 \n");
- break;
- case K_ANSIF28 :
- printf("\\Kansif28 Transmit SCOANSI/AT386: Ctrl-F4 \n");
- break;
- case K_ANSIF29 :
- printf("\\Kansif29 Transmit SCOANSI/AT386: Ctrl-F5 \n");
- break;
- case K_ANSIF30 :
- printf("\\Kansif30 Transmit SCOANSI/AT386: Ctrl-F6 \n");
- break;
- case K_ANSIF31 :
- printf("\\Kansif31 Transmit SCOANSI/AT386: Ctrl-F7 \n");
- break;
- case K_ANSIF32 :
- printf("\\Kansif32 Transmit SCOANSI/AT386: Ctrl-F8 \n");
- break;
- case K_ANSIF33 :
- printf("\\Kansif33 Transmit SCOANSI/AT386: Ctrl-F9 \n");
- break;
- case K_ANSIF34 :
- printf("\\Kansif34 Transmit SCOANSI/AT386: Ctrl-F10\n");
- break;
- case K_ANSIF35 :
- printf("\\Kansif35 Transmit SCOANSI/AT386: Ctrl-F11\n");
- break;
- case K_ANSIF36 :
- printf("\\Kansif36 Transmit SCOANSI/AT386: Ctrl-F12\n");
- break;
- case K_ANSIF37 :
- printf("\\Kansif37 Transmit SCOANSI/AT386: Ctrl-Shift-F1 \n");
- break;
- case K_ANSIF38 :
- printf("\\Kansif38 Transmit SCOANSI/AT386: Ctrl-Shift-F2 \n");
- break;
- case K_ANSIF39 :
- printf("\\Kansif39 Transmit SCOANSI/AT386: Ctrl-Shift-F3 \n");
- break;
- case K_ANSIF40 :
- printf("\\Kansif40 Transmit SCOANSI/AT386: Ctrl-Shift-F4 \n");
- break;
- case K_ANSIF41 :
- printf("\\Kansif41 Transmit SCOANSI/AT386: Ctrl-Shift-F5 \n");
- break;
- case K_ANSIF42 :
- printf("\\Kansif42 Transmit SCOANSI/AT386: Ctrl-Shift-F6 \n");
- break;
- case K_ANSIF43 :
- printf("\\Kansif43 Transmit SCOANSI/AT386: Ctrl-Shift-F7 \n");
- break;
- case K_ANSIF44 :
- printf("\\Kansif44 Transmit SCOANSI/AT386: Ctrl-Shift-F8 \n");
- break;
- case K_ANSIF45 :
- printf("\\Kansif45 Transmit SCOANSI/AT386: Ctrl-Shift-F9 \n");
- break;
- case K_ANSIF46 :
- printf("\\Kansif46 Transmit SCOANSI/AT386: Ctrl-Shift-F10\n");
- break;
- case K_ANSIF47 :
- printf("\\Kansif47 Transmit SCOANSI/AT386: Ctrl-Shift-F11\n");
- break;
- case K_ANSIF48 :
- printf("\\Kansif48 Transmit SCOANSI/AT386: Ctrl-Shift-F12\n");
- break;
- case K_ANSIF49 :
- printf("\\Kansif49 Transmit SCOANSI/AT386: Home\n");
- break;
- case K_ANSIF50 :
- printf("\\Kansif50 Transmit SCOANSI/AT386: Up Arrow\n");
- break;
- case K_ANSIF51 :
- printf("\\Kansif51 Transmit SCOANSI/AT386: PgUp\n");
- break;
- case K_ANSIF52 :
- printf("\\Kansif52 Transmit SCOANSI/AT386: Ctrl-Shift-Subtract\n");
- break;
- case K_ANSIF53 :
- printf("\\Kansif53 Transmit SCOANSI/AT386: Left Arrow\n");
- break;
- case K_ANSIF54 :
- printf("\\Kansif54 Transmit SCOANSI/AT386: Clear\n");
- break;
- case K_ANSIF55 :
- printf("\\Kansif55 Transmit SCOANSI/AT386: Right Arrow\n");
- break;
- case K_ANSIF56 :
- printf("\\Kansif56 Transmit SCOANSI/AT386: Shift-Add\n");
- break;
- case K_ANSIF57 :
- printf("\\Kansif57 Transmit SCOANSI/AT386: End\n");
- break;
- case K_ANSIF58 :
- printf("\\Kansif58 Transmit SCOANSI/AT386: Down Arrow\n");
- break;
- case K_ANSIF59 :
- printf("\\Kansif59 Transmit SCOANSI/AT386: PgDn\n");
- break;
- case K_ANSIF60 :
- printf("\\Kansif60 Transmit SCOANSI/AT386: Insert\n");
- break;
- case K_ANSIF61 :
- printf("\\Kansif61 Transmit SCOANSI/AT386: (not named)\n");
- break;
-
-/* WYSE Function Keys (unshifted) */
- case K_WYF01 :
- printf("\\Kwyf01 Transmit WYSE 30/50/60/160: F1\n");
- break;
- case K_WYF02 :
- printf("\\Kwyf02 Transmit WYSE 30/50/60/160: F2\n");
- break;
- case K_WYF03 :
- printf("\\Kwyf03 Transmit WYSE 30/50/60/160: F3\n");
- break;
- case K_WYF04 :
- printf("\\Kwyf04 Transmit WYSE 30/50/60/160: F4\n");
- break;
- case K_WYF05 :
- printf("\\Kwyf05 Transmit WYSE 30/50/60/160: F5\n");
- break;
- case K_WYF06 :
- printf("\\Kwyf06 Transmit WYSE 30/50/60/160: F6\n");
- break;
- case K_WYF07 :
- printf("\\Kwyf07 Transmit WYSE 30/50/60/160: F7\n");
- break;
- case K_WYF08 :
- printf("\\Kwyf08 Transmit WYSE 30/50/60/160: F8\n");
- break;
- case K_WYF09 :
- printf("\\Kwyf09 Transmit WYSE 30/50/60/160: F9\n");
- break;
- case K_WYF10 :
- printf("\\Kwyf10 Transmit WYSE 30/50/60/160: F10\n");
- break;
- case K_WYF11 :
- printf("\\Kwyf11 Transmit WYSE 30/50/60/160: F11\n");
- break;
- case K_WYF12 :
- printf("\\Kwyf12 Transmit WYSE 30/50/60/160: F12\n");
- break;
- case K_WYF13 :
- printf("\\Kwyf13 Transmit WYSE 30/50/60/160: F13\n");
- break;
- case K_WYF14 :
- printf("\\Kwyf14 Transmit WYSE 30/50/60/160: F14\n");
- break;
- case K_WYF15 :
- printf("\\Kwyf15 Transmit WYSE 30/50/60/160: F15\n");
- break;
- case K_WYF16 :
- printf("\\Kwyf16 Transmit WYSE 30/50/60/160: F16\n");
- break;
- case K_WYF17 :
- printf("\\Kwyf17 Transmit WYSE 30/50/60/160: F17\n");
- break;
- case K_WYF18 :
- printf("\\Kwyf18 Transmit WYSE 30/50/60/160: F18\n");
- break;
- case K_WYF19 :
- printf("\\Kwyf19 Transmit WYSE 30/50/60/160: F19\n");
- break;
- case K_WYF20 :
- printf("\\Kwyf20 Transmit WYSE 30/50/60/160: F20\n");
- break;
-
-/* WYSE Function Keys (shifted) */
- case K_WYSF01 :
- printf("\\Kwysf01 Transmit WYSE 30/50/60/160: Shift-F1\n");
- break;
- case K_WYSF02 :
- printf("\\Kwysf02 Transmit WYSE 30/50/60/160: Shift-F2\n");
- break;
- case K_WYSF03 :
- printf("\\Kwysf03 Transmit WYSE 30/50/60/160: Shift-F3\n");
- break;
- case K_WYSF04 :
- printf("\\Kwysf04 Transmit WYSE 30/50/60/160: Shift-F4\n");
- break;
- case K_WYSF05 :
- printf("\\Kwysf05 Transmit WYSE 30/50/60/160: Shift-F5\n");
- break;
- case K_WYSF06 :
- printf("\\Kwysf06 Transmit WYSE 30/50/60/160: Shift-F6\n");
- break;
- case K_WYSF07 :
- printf("\\Kwysf07 Transmit WYSE 30/50/60/160: Shift-F7\n");
- break;
- case K_WYSF08 :
- printf("\\Kwysf08 Transmit WYSE 30/50/60/160: Shift-F8\n");
- break;
- case K_WYSF09 :
- printf("\\Kwysf09 Transmit WYSE 30/50/60/160: Shift-F9\n");
- break;
- case K_WYSF10 :
- printf("\\Kwysf10 Transmit WYSE 30/50/60/160: Shift-F10\n");
- break;
- case K_WYSF11 :
- printf("\\Kwysf11 Transmit WYSE 30/50/60/160: Shift-F11\n");
- break;
- case K_WYSF12 :
- printf("\\Kwysf12 Transmit WYSE 30/50/60/160: Shift-F12\n");
- break;
- case K_WYSF13 :
- printf("\\Kwysf13 Transmit WYSE 30/50/60/160: Shift-F13\n");
- break;
- case K_WYSF14 :
- printf("\\Kwysf14 Transmit WYSE 30/50/60/160: Shift-F14\n");
- break;
- case K_WYSF15 :
- printf("\\Kwysf15 Transmit WYSE 30/50/60/160: Shift-F15\n");
- break;
- case K_WYSF16 :
- printf("\\Kwysf16 Transmit WYSE 30/50/60/160: Shift-F16\n");
- break;
- case K_WYSF17 :
- printf("\\Kwysf17 Transmit WYSE 30/50/60/160: Shift-F17\n");
- break;
- case K_WYSF18 :
- printf("\\Kwysf18 Transmit WYSE 30/50/60/160: Shift-F18\n");
- break;
- case K_WYSF19 :
- printf("\\Kwysf19 Transmit WYSE 30/50/60/160: Shift-F19\n");
- break;
- case K_WYSF20 :
- printf("\\Kwysf20 Transmit WYSE 30/50/60/160: Shift-F20\n");
- break;
-
-/* WYSE Edit and Special Keys */
- case K_WYBS :
- printf("\\Kwybs Transmit WYSE 30/50/60/160: Backspace\n");
- break;
- case K_WYCLRLN :
- printf("\\Kwyclrln Transmit WYSE 30/50/60/160: Clear Line\n");
- break;
- case K_WYSCLRLN :
- printf("\\Kwysclrln Transmit WYSE 30/50/60/160: Shift-Clear Line\n");
- break;
- case K_WYCLRPG :
- printf("\\Kwyclrpg Transmit WYSE 30/50/60/160: Clear Page\n");
- break;
- case K_WYSCLRPG :
- printf("\\Kwysclrpg Transmit WYSE 30/50/60/160: Shift-Clear Page\n");
- break;
- case K_WYDELCHAR :
- printf("\\Kwydelchar Transmit WYSE 30/50/60/160: Delete Char\n");
- break;
- case K_WYDELLN :
- printf("\\Kwydelln Transmit WYSE 30/50/60/160: Delete Line\n");
- break;
- case K_WYENTER :
- printf("\\Kwyenter Transmit WYSE 30/50/60/160: Enter\n");
- break;
- case K_WYESC :
- printf("\\Kwyesc Transmit WYSE 30/50/60/160: Esc\n");
- break;
- case K_WYHOME :
- printf("\\Kwyhome Transmit WYSE 30/50/60/160: Home\n");
- break;
- case K_WYSHOME :
- printf("\\Kwyshome Transmit WYSE 30/50/60/160: Shift-Home\n");
- break;
- case K_WYINSERT :
- printf("\\Kwyinsert Transmit WYSE 30/50/60/160: Insert\n");
- break;
- case K_WYINSCHAR :
- printf("\\Kwyinschar Transmit WYSE 30/50/60/160: Insert Char\n");
- break;
- case K_WYINSLN :
- printf("\\Kwyinsln Transmit WYSE 30/50/60/160: Insert Line\n");
- break;
- case K_WYPGNEXT :
- printf("\\Kwypgnext Transmit WYSE 30/50/60/160: Page Next\n");
- break;
- case K_WYPGPREV :
- printf("\\Kwypgprev Transmit WYSE 30/50/60/160: Page Previous\n");
- break;
- case K_WYREPLACE :
- printf("\\Kwyreplace Transmit WYSE 30/50/60/160: Replace \n");
- break;
- case K_WYRETURN :
- printf("\\Kwyreturn Transmit WYSE 30/50/60/160: Return \n");
- break;
- case K_WYTAB :
- printf("\\Kwytab Transmit WYSE 30/50/60/160: Tab \n");
- break;
- case K_WYSTAB :
- printf("\\Kwystab Transmit WYSE 30/50/60/160: Shift-Tab \n");
- break;
- case K_WYPRTSCN :
- printf("\\Kwyprtscn Transmit WYSE 30/50/60/160: Print Screen \n");
- break;
- case K_WYSESC :
- printf("\\Kwysesc Transmit WYSE 30/50/60/160: Shift-Esc \n");
- break;
- case K_WYSBS :
- printf("\\Kwysbs Transmit WYSE 30/50/60/160: Shift-Backspace\n");
- break;
- case K_WYSENTER :
- printf("\\Kwysenter Transmit WYSE 30/50/60/160: Shift-Enter\n");
- break;
- case K_WYSRETURN :
- printf("\\Kwysreturn Transmit WYSE 30/50/60/160: Shift-Return\n");
- break;
- case K_WYUPARR :
- printf("\\Kwyuparr Transmit WYSE 30/50/60/160: Up Arrow\n");
- break;
- case K_WYDNARR :
- printf("\\Kwydnarr Transmit WYSE 30/50/60/160: Down Arrow\n");
- break;
- case K_WYLFARR :
- printf("\\Kwylfarr Transmit WYSE 30/50/60/160: Left Arrow\n");
- break;
- case K_WYRTARR :
- printf("\\Kwyrtarr Transmit WYSE 30/50/60/160: Right Arrow\n");
- break;
- case K_WYSUPARR :
- printf("\\Kwysuparr Transmit WYSE 30/50/60/160: Shift-Up Arrow\n");
- break;
- case K_WYSDNARR :
- printf("\\Kwysdnarr Transmit WYSE 30/50/60/160: Shift-Down Arrow\n");
- break;
- case K_WYSLFARR :
- printf("\\Kwyslfarr Transmit WYSE 30/50/60/160: Shift-Left Arrow\n");
- break;
- case K_WYSRTARR :
- printf("\\Kwysrtarr Transmit WYSE 30/50/60/160: Shift-Right Arrow\n");
- break;
- case K_WYSEND:
- printf("\\Kwysend Transmit WYSE 30/50/60/160: Send\n");
- break;
- case K_WYSSEND:
- printf("\\Kwyssend Transmit WYSE 30/50/60/160: Shift-Send\n");
- break;
-
-/* Data General Function Keys (unshifted) */
- case K_DGF01 :
- printf("\\Kdgf01 Transmit Data General: F1 \n");
- break;
- case K_DGF02 :
- printf("\\Kdgf01 Transmit Data General: F2 \n");
- break;
- case K_DGF03 :
- printf("\\Kdgf01 Transmit Data General: F3 \n");
- break;
- case K_DGF04 :
- printf("\\Kdgf01 Transmit Data General: F4 \n");
- break;
- case K_DGF05 :
- printf("\\Kdgf01 Transmit Data General: F5 \n");
- break;
- case K_DGF06 :
- printf("\\Kdgf01 Transmit Data General: F6 \n");
- break;
- case K_DGF07 :
- printf("\\Kdgf01 Transmit Data General: F7 \n");
- break;
- case K_DGF08 :
- printf("\\Kdgf01 Transmit Data General: F8 \n");
- break;
- case K_DGF09 :
- printf("\\Kdgf01 Transmit Data General: F9 \n");
- break;
- case K_DGF10 :
- printf("\\Kdgf01 Transmit Data General: F10 \n");
- break;
- case K_DGF11 :
- printf("\\Kdgf01 Transmit Data General: F11 \n");
- break;
- case K_DGF12 :
- printf("\\Kdgf01 Transmit Data General: F12 \n");
- break;
- case K_DGF13 :
- printf("\\Kdgf01 Transmit Data General: F13 \n");
- break;
- case K_DGF14 :
- printf("\\Kdgf01 Transmit Data General: F14 \n");
- break;
- case K_DGF15 :
- printf("\\Kdgf01 Transmit Data General: F15 \n");
- break;
-
-/* Data General Function Keys (shifted) */
- case K_DGSF01 :
- printf(
- "\\Kdgsf01 Transmit Data General: Shift-F1 \n");
- break;
- case K_DGSF02 :
- printf(
- "\\Kdgsf02 Transmit Data General: Shift-F2 \n");
- break;
- case K_DGSF03 :
- printf(
- "\\Kdgsf03 Transmit Data General: Shift-F3 \n");
- break;
- case K_DGSF04 :
- printf(
- "\\Kdgsf04 Transmit Data General: Shift-F4 \n");
- break;
- case K_DGSF05 :
- printf(
- "\\Kdgsf05 Transmit Data General: Shift-F5 \n");
- break;
- case K_DGSF06 :
- printf(
- "\\Kdgsf06 Transmit Data General: Shift-F6 \n");
- break;
- case K_DGSF07 :
- printf(
- "\\Kdgsf07 Transmit Data General: Shift-F7 \n");
- break;
- case K_DGSF08 :
- printf(
- "\\Kdgsf08 Transmit Data General: Shift-F8 \n");
- break;
- case K_DGSF09 :
- printf(
- "\\Kdgsf09 Transmit Data General: Shift-F9 \n");
- break;
- case K_DGSF10 :
- printf(
- "\\Kdgsf10 Transmit Data General: Shift-F10 \n");
- break;
- case K_DGSF11 :
- printf(
- "\\Kdgsf11 Transmit Data General: Shift-F11 \n");
- break;
- case K_DGSF12 :
- printf(
- "\\Kdgsf12 Transmit Data General: Shift-F12 \n");
- break;
- case K_DGSF13 :
- printf(
- "\\Kdgsf13 Transmit Data General: Shift-F13 \n");
- break;
- case K_DGSF14 :
- printf(
- "\\Kdgsf14 Transmit Data General: Shift-F14 \n");
- break;
- case K_DGSF15 :
- printf(
- "\\Kdgsf15 Transmit Data General: Shift-F15 \n");
- break;
-
-/* Data General Function Keys (control) */
- case K_DGCF01 :
- printf(
- "\\Kdgcf01 Transmit Data General: Ctrl-F1 \n");
- break;
- case K_DGCF02 :
- printf(
- "\\Kdgcf02 Transmit Data General: Ctrl-F2 \n");
- break;
- case K_DGCF03 :
- printf(
- "\\Kdgcf03 Transmit Data General: Ctrl-F3 \n");
- break;
- case K_DGCF04 :
- printf(
- "\\Kdgcf04 Transmit Data General: Ctrl-F4 \n");
- break;
- case K_DGCF05 :
- printf(
- "\\Kdgcf05 Transmit Data General: Ctrl-F5 \n");
- break;
- case K_DGCF06 :
- printf(
- "\\Kdgcf06 Transmit Data General: Ctrl-F6 \n");
- break;
- case K_DGCF07 :
- printf(
- "\\Kdgcf07 Transmit Data General: Ctrl-F7 \n");
- break;
- case K_DGCF08 :
- printf(
- "\\Kdgcf08 Transmit Data General: Ctrl-F8 \n");
- break;
- case K_DGCF09 :
- printf(
- "\\Kdgcf09 Transmit Data General: Ctrl-F9 \n");
- break;
- case K_DGCF10 :
- printf(
- "\\Kdgcf10 Transmit Data General: Ctrl-F10 \n");
- break;
- case K_DGCF11 :
- printf(
- "\\Kdgcf11 Transmit Data General: Ctrl-F11 \n");
- break;
- case K_DGCF12 :
- printf(
- "\\Kdgcf12 Transmit Data General: Ctrl-F12 \n");
- break;
- case K_DGCF13 :
- printf(
- "\\Kdgcf13 Transmit Data General: Ctrl-F13 \n");
- break;
- case K_DGCF14 :
- printf(
- "\\Kdgcf14 Transmit Data General: Ctrl-F14 \n");
- break;
- case K_DGCF15 :
- printf(
- "\\Kdgcf15 Transmit Data General: Ctrl-F15 \n");
- break;
-
-/* Data General Function Keys (control shifted) */
- case K_DGCSF01 :
- printf(
- "\\Kdgcsf01 Transmit Data General: Ctrl-Shift-F1 \n");
- break;
- case K_DGCSF02 :
- printf(
- "\\Kdgcsf02 Transmit Data General: Ctrl-Shift-F2 \n");
- break;
- case K_DGCSF03 :
- printf(
- "\\Kdgcsf03 Transmit Data General: Ctrl-Shift-F3 \n");
- break;
- case K_DGCSF04 :
- printf(
- "\\Kdgcsf04 Transmit Data General: Ctrl-Shift-F4 \n");
- break;
- case K_DGCSF05 :
- printf(
- "\\Kdgcsf05 Transmit Data General: Ctrl-Shift-F5 \n");
- break;
- case K_DGCSF06 :
- printf(
- "\\Kdgcsf06 Transmit Data General: Ctrl-Shift-F6 \n");
- break;
- case K_DGCSF07 :
- printf(
- "\\Kdgcsf07 Transmit Data General: Ctrl-Shift-F7 \n");
- break;
- case K_DGCSF08 :
- printf(
- "\\Kdgcsf08 Transmit Data General: Ctrl-Shift-F8 \n");
- break;
- case K_DGCSF09 :
- printf(
- "\\Kdgcsf09 Transmit Data General: Ctrl-Shift-F9 \n");
- break;
- case K_DGCSF10 :
- printf(
- "\\Kdgcsf10 Transmit Data General: Ctrl-Shift-F10 \n");
- break;
- case K_DGCSF11 :
- printf(
- "\\Kdgcsf11 Transmit Data General: Ctrl-Shift-F11 \n");
- break;
- case K_DGCSF12 :
- printf(
- "\\Kdgcsf12 Transmit Data General: Ctrl-Shift-F12 \n");
- break;
- case K_DGCSF13 :
- printf(
- "\\Kdgcsf13 Transmit Data General: Ctrl-Shift-F13 \n");
- break;
- case K_DGCSF14 :
- printf(
- "\\Kdgcsf14 Transmit Data General: Ctrl-Shift-F14 \n");
- break;
- case K_DGCSF15 :
- printf(
- "\\Kdgcsf15 Transmit Data General: Ctrl-Shift-F15 \n");
- break;
-
- case K_DGUPARR :
- printf("\\Kdguparr Transmit Data General: Up Arrow \n");
- break;
- case K_DGDNARR :
- printf("\\Kdgdnarr Transmit Data General: Down Arrow \n");
- break;
- case K_DGLFARR :
- printf("\\Kdglfarr Transmit Data General: Left Arrow \n");
- break;
- case K_DGRTARR :
- printf("\\Kdgrtarr Transmit Data General: Right Arrow \n");
- break;
- case K_DGSUPARR :
- printf("\\Kdgsuparr Transmit Data General: Shift-Up Arrow \n");
- break;
- case K_DGSDNARR :
- printf("\\Kdgsdnarr Transmit Data General: Shift-Down Arrow \n");
- break;
- case K_DGSLFARR :
- printf("\\Kdgslfarr Transmit Data General: Shift-Left Arrow \n");
- break;
- case K_DGSRTARR :
- printf("\\Kdgsrtarr Transmit Data General: Shift-Right Arrow \n");
- break;
-
- case K_DGERASEPAGE :
- printf("\\Kdgerasepage Transmit Data General: Erase Page \n");
- break;
- case K_DGC1 :
- printf("\\Kdgc1 Transmit Data General: C1 \n");
- break;
- case K_DGC2 :
- printf("\\Kdgc2 Transmit Data General: C2 \n");
- break;
- case K_DGERASEEOL :
- printf("\\Kdgeraseeol Transmit Data General: Erase EOL \n");
- break;
- case K_DGC3 :
- printf("\\Kdgc3 Transmit Data General: C3 \n");
- break;
- case K_DGC4 :
- printf("\\Kdgc4 Transmit Data General: C4 \n");
- break;
- case K_DGCMDPRINT :
- printf("\\Kdgcmdprint Transmit Data General: Command Print \n");
- break;
- case K_DGHOME :
- printf("\\Kdghome Transmit Data General: Home \n");
- break;
- case K_DGSERASEPAGE :
- printf("\\Kdgserasepage Transmit Data General: Erase Page \n");
- break;
- case K_DGSC1 :
- printf("\\Kdgsc1 Transmit Data General: Shift-C1 \n");
- break;
- case K_DGSC2 :
- printf("\\Kdgsc2 Transmit Data General: Shift-C2 \n");
- break;
- case K_DGSERASEEOL :
- printf("\\Kdgseraseeol Transmit Data General: Shift-Erase EOL \n");
- break;
- case K_DGSC3 :
- printf("\\Kdgsc3 Transmit Data General: Shift-C3 \n");
- break;
- case K_DGSC4 :
- printf("\\Kdgsc4 Transmit Data General: Shift-C4 \n");
- break;
- case K_DGSCMDPRINT :
- printf("\\Kdgscmdprint Transmit Data General: Shift-Command Print\n");
- break;
- case K_DGBS :
- printf("\\Kdgbs Transmit Data General: Backspace \n");
- break;
- case K_DGSHOME :
- printf("\\Kdshome Transmit Data General: Shift-Home \n");
- break;
-
-
-/* Televideo Function Keys (unshifted) */
- case K_TVIF01 :
- printf("\\Ktvif01 Transmit Televideo: F1 \n");
- break;
- case K_TVIF02 :
- printf("\\Ktvif02 Transmit Televideo: F2 \n");
- break;
- case K_TVIF03 :
- printf("\\Ktvif03 Transmit Televideo: F3 \n");
- break;
- case K_TVIF04 :
- printf("\\Ktvif04 Transmit Televideo: F4 \n");
- break;
- case K_TVIF05 :
- printf("\\Ktvif05 Transmit Televideo: F5 \n");
- break;
- case K_TVIF06 :
- printf("\\Ktvif06 Transmit Televideo: F6 \n");
- break;
- case K_TVIF07 :
- printf("\\Ktvif07 Transmit Televideo: F7 \n");
- break;
- case K_TVIF08 :
- printf("\\Ktvif08 Transmit Televideo: F8 \n");
- break;
- case K_TVIF09 :
- printf("\\Ktvif09 Transmit Televideo: F9 \n");
- break;
- case K_TVIF10 :
- printf("\\Ktvif10 Transmit Televideo: F10 \n");
- break;
- case K_TVIF11 :
- printf("\\Ktvif11 Transmit Televideo: F11 \n");
- break;
- case K_TVIF12 :
- printf("\\Ktvif12 Transmit Televideo: F12 \n");
- break;
- case K_TVIF13 :
- printf("\\Ktvif13 Transmit Televideo: F13 \n");
- break;
- case K_TVIF14 :
- printf("\\Ktvif14 Transmit Televideo: F14 \n");
- break;
- case K_TVIF15 :
- printf("\\Ktvif15 Transmit Televideo: F15 \n");
- break;
- case K_TVIF16 :
- printf("\\Ktvif16 Transmit Televideo: F16 \n");
- break;
-
-/* Televideo Function Keys (shifted) */
- case K_TVISF01 :
- printf("\\Ktvisf01 Transmit Televideo: Shift-F1 \n");
- break;
- case K_TVISF02 :
- printf("\\Ktvisf02 Transmit Televideo: Shift-F2 \n");
- break;
- case K_TVISF03 :
- printf("\\Ktvisf03 Transmit Televideo: Shift-F3 \n");
- break;
- case K_TVISF04 :
- printf("\\Ktvisf04 Transmit Televideo: Shift-F4 \n");
- break;
- case K_TVISF05 :
- printf("\\Ktvisf05 Transmit Televideo: Shift-F5 \n");
- break;
- case K_TVISF06 :
- printf("\\Ktvisf06 Transmit Televideo: Shift-F6 \n");
- break;
- case K_TVISF07 :
- printf("\\Ktvisf07 Transmit Televideo: Shift-F7 \n");
- break;
- case K_TVISF08 :
- printf("\\Ktvisf08 Transmit Televideo: Shift-F8 \n");
- break;
- case K_TVISF09 :
- printf("\\Ktvisf09 Transmit Televideo: Shift-F9 \n");
- break;
- case K_TVISF10 :
- printf("\\Ktvisf10 Transmit Televideo: Shift-F10\n");
- break;
- case K_TVISF11 :
- printf("\\Ktvisf11 Transmit Televideo: Shift-F11\n");
- break;
- case K_TVISF12 :
- printf("\\Ktvisf12 Transmit Televideo: Shift-F12\n");
- break;
- case K_TVISF13 :
- printf("\\Ktvisf13 Transmit Televideo: Shift-F13\n");
- break;
- case K_TVISF14 :
- printf("\\Ktvisf14 Transmit Televideo: Shift-F14\n");
- break;
- case K_TVISF15 :
- printf("\\Ktvisf15 Transmit Televideo: Shift-F15\n");
- break;
- case K_TVISF16 :
- printf("\\Ktvisf16 Transmit Televideo: Shift-F16\n");
- break;
-
-/* Televideo Edit and Special Keys */
- case K_TVIBS :
- printf("\\Ktvibs Transmit Televideo: Backspace \n");
- break;
- case K_TVICLRLN :
- printf("\\Ktviclrln Transmit Televideo: Clear Line \n");
- break;
- case K_TVISCLRLN :
- printf("\\Ktvisclrln Transmit Televideo: Shift-Clear Line\n");
- break;
- case K_TVICLRPG :
- printf("\\Ktviclrpg Transmit Televideo: Clear Page \n");
- break;
- case K_TVISCLRPG :
- printf("\\Ktvisclrpg Transmit Televideo: Shift-Clear Page\n");
- break;
- case K_TVIDELCHAR :
- printf("\\Ktvidelchar Transmit Televideo: Delete Char \n");
- break;
- case K_TVIDELLN :
- printf("\\Ktvidelln Transmit Televideo: Delete Line \n");
- break;
- case K_TVIENTER :
- printf("\\Ktvienter Transmit Televideo: Enter \n");
- break;
- case K_TVIESC :
- printf("\\Ktviesc Transmit Televideo: Esc \n");
- break;
- case K_TVIHOME :
- printf("\\Ktvihome Transmit Televideo: Home \n");
- break;
- case K_TVISHOME :
- printf("\\Ktvishome Transmit Televideo: Shift-Home \n");
- break;
- case K_TVIINSERT :
- printf("\\Ktviinsert Transmit Televideo: Insert \n");
- break;
- case K_TVIINSCHAR :
- printf("\\Ktviinschar Transmit Televideo: Insert Char \n");
- break;
- case K_TVIINSLN :
- printf("\\Ktviinsln Transmit Televideo: Insert Line \n");
- break;
- case K_TVIPGNEXT :
- printf("\\Ktvipgnext Transmit Televideo: Page Next \n");
- break;
- case K_TVIPGPREV :
- printf("\\Ktvipgprev Transmit Televideo: Page Previous \n");
- break;
- case K_TVIREPLACE :
- printf("\\Ktvireplace Transmit Televideo: Replace \n");
- break;
- case K_TVIRETURN :
- printf("\\Ktvireturn Transmit Televideo: Return \n");
- break;
- case K_TVITAB :
- printf("\\Ktvitab Transmit Televideo: Tab \n");
- break;
- case K_TVISTAB :
- printf("\\Ktvistab Transmit Televideo: Shift-Tab \n");
- break;
- case K_TVIPRTSCN :
- printf("\\Ktviprtscn Transmit Televideo: Print Screen \n");
- break;
- case K_TVISESC :
- printf("\\Ktvisesc Transmit Televideo: Shift-Esc \n");
- break;
- case K_TVISBS :
- printf("\\Ktvisbs Transmit Televideo: Shift-Backspace \n");
- break;
- case K_TVISENTER :
- printf("\\Ktvisenter Transmit Televideo: Shift-Enter \n");
- break;
- case K_TVISRETURN :
- printf("\\Ktvisreturn Transmit Televideo: Shift-Return \n");
- break;
- case K_TVIUPARR :
- printf("\\Ktviuparr Transmit Televideo: Up Arrow \n");
- break;
- case K_TVIDNARR :
- printf("\\Ktvidnarr Transmit Televideo: Down Arrow \n");
- break;
- case K_TVILFARR :
- printf("\\Ktvilfarr Transmit Televideo: Left Arrow \n");
- break;
- case K_TVIRTARR :
- printf("\\Ktvirtarr Transmit Televideo: Right Arrow \n");
- break;
- case K_TVISUPARR :
- printf("\\Ktvisuparr Transmit Televideo: Shift-Up Arrow \n");
- break;
- case K_TVISDNARR :
- printf("\\Ktvisdnarr Transmit Televideo: Shift-Down Arrow\n");
- break;
- case K_TVISLFARR :
- printf("\\Ktvislfarr Transmit Televideo: Shift-Left Arrow\n");
- break;
- case K_TVISRTARR :
- printf("\\Ktvisrtarr Transmit Televideo: Shift-Right Arrow\n");
- break;
- case K_TVISEND:
- printf("\\Ktvisend Transmit Televideo: Send\n");
- break;
- case K_TVISSEND:
- printf("\\Ktvissend Transmit Televideo: Shift-Send\n");
- break;
-
-/* HP Function and Edit keys */
- case K_HPF01 :
- printf("\\Khpf01 Transmit Hewlett-Packard: F1 \n");
- break;
- case K_HPF02 :
- printf("\\Khpf02 Transmit Hewlett-Packard: F2 \n");
- break;
- case K_HPF03 :
- printf("\\Khpf03 Transmit Hewlett-Packard: F3 \n");
- break;
- case K_HPF04 :
- printf("\\Khpf04 Transmit Hewlett-Packard: F4 \n");
- break;
- case K_HPF05 :
- printf("\\Khpf05 Transmit Hewlett-Packard: F5 \n");
- break;
- case K_HPF06 :
- printf("\\Khpf06 Transmit Hewlett-Packard: F6 \n");
- break;
- case K_HPF07 :
- printf("\\Khpf07 Transmit Hewlett-Packard: F7 \n");
- break;
- case K_HPF08 :
- printf("\\Khpf08 Transmit Hewlett-Packard: F8 \n");
- break;
- case K_HPF09 :
- printf("\\Khpf09 Transmit Hewlett-Packard: F9 \n");
- break;
- case K_HPF10 :
- printf("\\Khpf10 Transmit Hewlett-Packard: F10 \n");
- break;
- case K_HPF11 :
- printf("\\Khpf11 Transmit Hewlett-Packard: F11 \n");
- break;
- case K_HPF12 :
- printf("\\Khpf12 Transmit Hewlett-Packard: F12 \n");
- break;
- case K_HPF13 :
- printf("\\Khpf13 Transmit Hewlett-Packard: F13 \n");
- break;
- case K_HPF14 :
- printf("\\Khpf14 Transmit Hewlett-Packard: F14 \n");
- break;
- case K_HPF15 :
- printf("\\Khpf15 Transmit Hewlett-Packard: F15 \n");
- break;
- case K_HPF16 :
- printf("\\Khpf16 Transmit Hewlett-Packard: F16 \n");
- break;
- case K_HPRETURN :
- printf("\\Khpreturn Transmit Hewlett-Packard: Return\n");
- break;
- case K_HPENTER :
- printf("\\Khpenter Transmit Hewlett-Packard: Enter (keypad)\n");
- break;
- case K_HPBACKTAB :
- printf("\\Khpbacktab Transmit Hewlett-Packard: Back Tab\n");
- break;
- /* Siemens Nixdorf International 97801-5xx kverbs */
- case K_SNI_DOUBLE_0 :
- printf("\\Ksni_00 Transmit SNI-97801-5xx: Double-Zero\n");
- break;
- case K_SNI_C_DOUBLE_0 :
- printf(
-"\\Ksni_c_00 Transmit SNI-97801-5xx: Ctrl-Double-Zero\n");
- break;
- case K_SNI_C_CE :
- printf("\\Ksni_c_ce Transmit SNI-97801-5xx: Ctrl-CE\n");
- break;
- case K_SNI_C_COMPOSE :
- printf("\\Ksni_c_compose Transmit SNI-97801-5xx: Ctrl-Compose\n");
- break;
- case K_SNI_C_DELETE_CHAR :
- printf(
-"\\Ksni_c_del_char Transmit SNI-97801-5xx: Ctrl-Delete Char\n");
- break;
- case K_SNI_C_DELETE_LINE :
- printf(
-"\\Ksni_c_del_line Transmit SNI-97801-5xx: Ctrl-Delete Line\n");
- break;
- case K_SNI_C_DELETE_WORD :
- printf(
-"\\Ksni_c_del_word Transmit SNI-97801-5xx: Ctrl-Delete Word\n");
- break;
- case K_SNI_C_CURSOR_DOWN :
- printf(
-"\\Ksni_c_dnarr Transmit SNI-97801-5xx: Ctrl-Cursor Down\n");
- break;
- case K_SNI_C_ENDMARKE :
- printf("\\Ksni_c_endmarke Transmit SNI-97801-5xx: Ctrl-End Marke\n");
- break;
- case K_SNI_C_F01 :
- printf("\\Ksni_c_f01 Transmit SNI-97801-5xx: Ctrl-F1\n");
- break;
- case K_SNI_C_F02 :
- printf("\\Ksni_c_f02 Transmit SNI-97801-5xx: Ctrl-F2\n");
- break;
- case K_SNI_C_F03 :
- printf("\\Ksni_c_f03 Transmit SNI-97801-5xx: Ctrl-F3\n");
- break;
- case K_SNI_C_F04 :
- printf("\\Ksni_c_f04 Transmit SNI-97801-5xx: Ctrl-F4\n");
- break;
- case K_SNI_C_F05 :
- printf("\\Ksni_c_f05 Transmit SNI-97801-5xx: Ctrl-F5\n");
- break;
- case K_SNI_C_F06 :
- printf("\\Ksni_c_f06 Transmit SNI-97801-5xx: Ctrl-F6\n");
- break;
- case K_SNI_C_F07 :
- printf("\\Ksni_c_f07 Transmit SNI-97801-5xx: Ctrl-F7\n");
- break;
- case K_SNI_C_F08 :
- printf("\\Ksni_c_f08 Transmit SNI-97801-5xx: Ctrl-F8\n");
- break;
- case K_SNI_C_F09 :
- printf("\\Ksni_c_f09 Transmit SNI-97801-5xx: Ctrl-F9\n");
- break;
- case K_SNI_C_F10 :
- printf("\\Ksni_c_f10 Transmit SNI-97801-5xx: Ctrl-F10\n");
- break;
- case K_SNI_C_F11 :
- printf("\\Ksni_c_f11 Transmit SNI-97801-5xx: Ctrl-F11\n");
- break;
- case K_SNI_C_F12 :
- printf("\\Ksni_c_f12 Transmit SNI-97801-5xx: Ctrl-F12\n");
- break;
- case K_SNI_C_F13 :
- printf("\\Ksni_c_f13 Transmit SNI-97801-5xx: Ctrl-F13\n");
- break;
- case K_SNI_C_F14 :
- printf("\\Ksni_c_f14 Transmit SNI-97801-5xx: Ctrl-F14\n");
- break;
- case K_SNI_C_F15 :
- printf("\\Ksni_c_f15 Transmit SNI-97801-5xx: Ctrl-F15\n");
- break;
- case K_SNI_C_F16 :
- printf("\\Ksni_c_f16 Transmit SNI-97801-5xx: Ctrl-F16\n");
- break;
- case K_SNI_C_F17 :
- printf("\\Ksni_c_f17 Transmit SNI-97801-5xx: Ctrl-F17\n");
- break;
- case K_SNI_C_F18 :
- printf("\\Ksni_c_f18 Transmit SNI-97801-5xx: Ctrl-F18\n");
- break;
- case K_SNI_C_USER1 :
- printf(
-"\\Ksni_c_user1 Transmit SNI-97801-5xx: Ctrl-Key below F18\n");
- break;
- case K_SNI_C_F19 :
- printf("\\Ksni_c_f19 Transmit SNI-97801-5xx: Ctrl-F19\n");
- break;
- case K_SNI_C_USER2 :
- printf(
-"\\Ksni_c_user2 Transmit SNI-97801-5xx: Ctrl-Key below F19\n");
- break;
- case K_SNI_C_F20 :
- printf("\\Ksni_c_f20 Transmit SNI-97801-5xx: Ctrl-F20\n");
- break;
- case K_SNI_C_USER3 :
- printf(
-"\\Ksni_c_user3 Transmit SNI-97801-5xx: Ctrl-Key below F20\n");
- break;
- case K_SNI_C_F21 :
- printf("\\Ksni_c_f21 Transmit SNI-97801-5xx: Ctrl-F21\n");
- break;
- case K_SNI_C_USER4 :
- printf(
-"\\Ksni_c_user4 Transmit SNI-97801-5xx: Ctrl-Key below F21\n");
- break;
- case K_SNI_C_F22 :
- printf("\\Ksni_c_f22 Transmit SNI-97801-5xx: Ctrl-F22\n");
- break;
- case K_SNI_C_USER5 :
- printf(
-"\\Ksni_c_user5 Transmit SNI-97801-5xx: Ctrl-Key below F22\n");
- break;
- case K_SNI_C_HELP :
- printf("\\Ksni_c_help Transmit SNI-97801-5xx: Ctrl-Help\n");
- break;
- case K_SNI_C_HOME :
- printf("\\Ksni_c_home Transmit SNI-97801-5xx: Ctrl-Home\n");
- break;
- case K_SNI_C_INSERT_CHAR :
- printf(
-"\\Ksni_c_ins_char Transmit SNI-97801-5xx: Ctrl-Insert Char\n");
- break;
- case K_SNI_C_INSERT_LINE :
- printf(
-"\\Ksni_c_ins_line Transmit SNI-97801-5xx: Ctrl-Insert Line\n");
- break;
- case K_SNI_C_INSERT_WORD :
- printf(
-"\\Ksni_c_ins_word Transmit SNI-97801-5xx: Ctrl-Insert Word\n");
- break;
- case K_SNI_C_LEFT_TAB :
- printf("\\Ksni_c_left_tab Transmit SNI-97801-5xx: Ctrl-Left Tab\n");
- break;
- case K_SNI_C_CURSOR_LEFT :
- printf(
-"\\Ksni_c_lfarr Transmit SNI-97801-5xx: Ctrl-Cursor Left\n");
- break;
- case K_SNI_C_MODE :
- printf("\\Ksni_c_mode Transmit SNI-97801-5xx: Ctrl-Mode\n");
- break;
- case K_SNI_C_PAGE :
- printf("\\Ksni_c_page Transmit SNI-97801-5xx: Ctrl-Page\n");
- break;
- case K_SNI_C_PRINT :
- printf("\\Ksni_c_print Transmit SNI-97801-5xx: Ctrl-Print\n");
- break;
- case K_SNI_C_CURSOR_RIGHT:
- printf(
-"\\Ksni_c_rtarr Transmit SNI-97801-5xx: Ctrl-Cursor Right\n");
- break;
- case K_SNI_C_SCROLL_DOWN :
- printf(
-"\\Ksni_c_scroll_dn Transmit SNI-97801-5xx: Ctrl-Scroll Down\n");
- break;
- case K_SNI_C_SCROLL_UP :
- printf("\\Ksni_c_scroll_up Transmit SNI-97801-5xx: Ctrl-Scroll Up\n");
- break;
- case K_SNI_C_START :
- printf("\\Ksni_c_start Transmit SNI-97801-5xx: Ctrl-Start\n");
- break;
- case K_SNI_C_CURSOR_UP :
- printf("\\Ksni_c_uparr Transmit SNI-97801-5xx: Ctrl-Cursor Up\n");
- break;
- case K_SNI_C_TAB :
- printf("\\Ksni_c_tab Transmit SNI-97801-5xx: Ctrl-Tab\n");
- break;
- case K_SNI_CE :
- printf("\\Ksni_ce Transmit SNI-97801-5xx: CE\n");
- break;
- case K_SNI_CH_CODE:
- printf("\\Ksni_ch_code Toggle SNI-97801-5xx: CH.CODE function.\n");
- break;
- case K_SNI_COMPOSE :
- printf("\\Ksni_compose Transmit SNI-97801-5xx: Compose\n");
- break;
- case K_SNI_DELETE_CHAR :
- printf("\\Ksni_del_char Transmit SNI-97801-5xx: Delete Char\n");
- break;
- case K_SNI_DELETE_LINE :
- printf("\\Ksni_del_line Transmit SNI-97801-5xx: Delete Line\n");
- break;
- case K_SNI_DELETE_WORD :
- printf("\\Ksni_del_word Transmit SNI-97801-5xx: Delete Word\n");
- break;
- case K_SNI_CURSOR_DOWN :
- printf("\\Ksni_dnarr Transmit SNI-97801-5xx: Cursor Down\n");
- break;
- case K_SNI_ENDMARKE :
- printf("\\Ksni_endmarke Transmit SNI-97801-5xx: End Marke\n");
- break;
- case K_SNI_F01 :
- printf("\\Ksni_f01 Transmit SNI-97801-5xx: F1\n");
- break;
- case K_SNI_F02 :
- printf("\\Ksni_f02 Transmit SNI-97801-5xx: F2\n");
- break;
- case K_SNI_F03 :
- printf("\\Ksni_f03 Transmit SNI-97801-5xx: F3\n");
- break;
- case K_SNI_F04 :
- printf("\\Ksni_f04 Transmit SNI-97801-5xx: F4\n");
- break;
- case K_SNI_F05 :
- printf("\\Ksni_f05 Transmit SNI-97801-5xx: F5\n");
- break;
- case K_SNI_F06 :
- printf("\\Ksni_f06 Transmit SNI-97801-5xx: F6\n");
- break;
- case K_SNI_F07 :
- printf("\\Ksni_f07 Transmit SNI-97801-5xx: F7\n");
- break;
- case K_SNI_F08 :
- printf("\\Ksni_f08 Transmit SNI-97801-5xx: F8\n");
- break;
- case K_SNI_F09 :
- printf("\\Ksni_f09 Transmit SNI-97801-5xx: F9\n");
- break;
- case K_SNI_F10 :
- printf("\\Ksni_f10 Transmit SNI-97801-5xx: F10\n");
- break;
- case K_SNI_F11 :
- printf("\\Ksni_f11 Transmit SNI-97801-5xx: F11\n");
- break;
- case K_SNI_F12 :
- printf("\\Ksni_f12 Transmit SNI-97801-5xx: F12\n");
- break;
- case K_SNI_F13 :
- printf("\\Ksni_f13 Transmit SNI-97801-5xx: F13\n");
- break;
- case K_SNI_F14 :
- printf("\\Ksni_f14 Transmit SNI-97801-5xx: F14\n");
- break;
- case K_SNI_F15 :
- printf("\\Ksni_f15 Transmit SNI-97801-5xx: F15\n");
- break;
- case K_SNI_F16 :
- printf("\\Ksni_f16 Transmit SNI-97801-5xx: F16\n");
- break;
- case K_SNI_F17 :
- printf("\\Ksni_f17 Transmit SNI-97801-5xx: F17\n");
- break;
- case K_SNI_F18 :
- printf("\\Ksni_f18 Transmit SNI-97801-5xx: F18\n");
- break;
- case K_SNI_USER1 :
- printf("\\Ksni_user1 Transmit SNI-97801-5xx: Key below F18\n");
- break;
- case K_SNI_F19 :
- printf("\\Ksni_f19 Transmit SNI-97801-5xx: F19\n");
- break;
- case K_SNI_USER2 :
- printf("\\Ksni_user2 Transmit SNI-97801-5xx: Key below F19\n");
- break;
- case K_SNI_F20 :
- printf("\\Ksni_f20 Transmit SNI-97801-5xx: F20\n");
- break;
- case K_SNI_USER3 :
- printf("\\Ksni_user3 Transmit SNI-97801-5xx: Key below F20\n");
- break;
- case K_SNI_F21 :
- printf("\\Ksni_f21 Transmit SNI-97801-5xx: F21\n");
- break;
- case K_SNI_USER4 :
- printf("\\Ksni_user4 Transmit SNI-97801-5xx: Key below F21\n");
- break;
- case K_SNI_F22 :
- printf("\\Ksni_f22 Transmit SNI-97801-5xx: F22\n");
- break;
- case K_SNI_USER5 :
- printf("\\Ksni_user5 Transmit SNI-97801-5xx: Key below F22\n");
- break;
- case K_SNI_HELP :
- printf("\\Ksni_help Transmit SNI-97801-5xx: Help\n");
- break;
- case K_SNI_HOME :
- printf("\\Ksni_home Transmit SNI-97801-5xx: Home\n");
- break;
- case K_SNI_INSERT_CHAR :
- printf("\\Ksni_ins_char Transmit SNI-97801-5xx: Insert Char\n");
- break;
- case K_SNI_INSERT_LINE :
- printf("\\Ksni_ins_line Transmit SNI-97801-5xx: Insert Line\n");
- break;
- case K_SNI_INSERT_WORD :
- printf("\\Ksni_ins_word Transmit SNI-97801-5xx: Insert Word\n");
- break;
- case K_SNI_LEFT_TAB :
- printf("\\Ksni_left_tab Transmit SNI-97801-5xx: Left Tab\n");
- break;
- case K_SNI_CURSOR_LEFT :
- printf("\\Ksni_lfarr Transmit SNI-97801-5xx: Cursor Left\n");
- break;
- case K_SNI_MODE :
- printf("\\Ksni_mode Transmit SNI-97801-5xx: Mode\n");
- break;
- case K_SNI_PAGE :
- printf("\\Ksni_page Transmit SNI-97801-5xx: Page\n");
- break;
- case K_SNI_PRINT :
- printf("\\Ksni_print Transmit SNI-97801-5xx: Print\n");
- break;
- case K_SNI_CURSOR_RIGHT :
- printf("\\Ksni_rtarr Transmit SNI-97801-5xx: Cursor Right\n");
- break;
- case K_SNI_S_DOUBLE_0 :
- printf(
-"\\Ksni_s_00 Transmit SNI-97801-5xx: Shift-Double-Zero\n");
- break;
- case K_SNI_S_CE :
- printf("\\Ksni_s_ce Transmit SNI-97801-5xx: Shift-CE\n");
- break;
- case K_SNI_S_COMPOSE :
- printf("\\Ksni_s_compose Transmit SNI-97801-5xx: Shift-Compose\n");
- break;
- case K_SNI_S_DELETE_CHAR :
- printf(
-"\\Ksni_s_del_char Transmit SNI-97801-5xx: Shift-Delete Char\n");
- break;
- case K_SNI_S_DELETE_LINE :
- printf(
-"\\Ksni_s_del_line Transmit SNI-97801-5xx: Shift-Delete Line\n");
- break;
- case K_SNI_S_DELETE_WORD :
- printf(
-"\\Ksni_s_del_word Transmit SNI-97801-5xx: Shift-Delete Word\n");
- break;
- case K_SNI_S_CURSOR_DOWN :
- printf(
-"\\Ksni_s_dnarr Transmit SNI-97801-5xx: Shift-Cursor Down\n");
- break;
- case K_SNI_S_ENDMARKE :
- printf("\\Ksni_s_endmarke Transmit SNI-97801-5xx: Shift-End Marke\n");
- break;
- case K_SNI_S_F01 :
- printf("\\Ksni_s_f01 Transmit SNI-97801-5xx: Shift-F1\n");
- break;
- case K_SNI_S_F02 :
- printf("\\Ksni_s_f02 Transmit SNI-97801-5xx: Shift-F2\n");
- break;
- case K_SNI_S_F03 :
- printf("\\Ksni_s_f03 Transmit SNI-97801-5xx: Shift-F3\n");
- break;
- case K_SNI_S_F04 :
- printf("\\Ksni_s_f04 Transmit SNI-97801-5xx: Shift-F4\n");
- break;
- case K_SNI_S_F05 :
- printf("\\Ksni_s_f05 Transmit SNI-97801-5xx: Shift-F5\n");
- break;
- case K_SNI_S_F06 :
- printf("\\Ksni_s_f06 Transmit SNI-97801-5xx: Shift-F6\n");
- break;
- case K_SNI_S_F07 :
- printf("\\Ksni_s_f07 Transmit SNI-97801-5xx: Shift-F7\n");
- break;
- case K_SNI_S_F08 :
- printf("\\Ksni_s_f08 Transmit SNI-97801-5xx: Shift-F8\n");
- break;
- case K_SNI_S_F09 :
- printf("\\Ksni_s_f09 Transmit SNI-97801-5xx: Shift-F9\n");
- break;
- case K_SNI_S_F10 :
- printf("\\Ksni_s_f10 Transmit SNI-97801-5xx: Shift-F10\n");
- break;
- case K_SNI_S_F11 :
- printf("\\Ksni_s_f11 Transmit SNI-97801-5xx: Shift-F11\n");
- break;
- case K_SNI_S_F12 :
- printf("\\Ksni_s_f12 Transmit SNI-97801-5xx: Shift-F12\n");
- break;
- case K_SNI_S_F13 :
- printf("\\Ksni_s_f13 Transmit SNI-97801-5xx: Shift-F13\n");
- break;
- case K_SNI_S_F14 :
- printf("\\Ksni_s_f14 Transmit SNI-97801-5xx: Shift-F14\n");
- break;
- case K_SNI_S_F15 :
- printf("\\Ksni_s_f15 Transmit SNI-97801-5xx: Shift-F15\n");
- break;
- case K_SNI_S_F16 :
- printf("\\Ksni_s_f16 Transmit SNI-97801-5xx: Shift-F16\n");
- break;
- case K_SNI_S_F17 :
- printf("\\Ksni_s_f17 Transmit SNI-97801-5xx: Shift-F17\n");
- break;
- case K_SNI_S_F18 :
- printf("\\Ksni_s_f18 Transmit SNI-97801-5xx: Shift-F18\n");
- break;
- case K_SNI_S_USER1 :
- printf(
-"\\Ksni_s_user1 Transmit SNI-97801-5xx: Shift-Key below F18\n");
- break;
- case K_SNI_S_F19 :
- printf("\\Ksni_s_f19 Transmit SNI-97801-5xx: Shift-F19\n");
- break;
- case K_SNI_S_USER2 :
- printf(
-"\\Ksni_s_user2 Transmit SNI-97801-5xx: Shift-Key below F19\n");
- break;
- case K_SNI_S_F20 :
- printf("\\Ksni_s_f20 Transmit SNI-97801-5xx: Shift-F20\n");
- break;
- case K_SNI_S_USER3 :
- printf(
-"\\Ksni_s_user3 Transmit SNI-97801-5xx: Shift-Key below F20\n");
- break;
- case K_SNI_S_F21 :
- printf("\\Ksni_s_f21 Transmit SNI-97801-5xx: Shift-F21\n");
- break;
- case K_SNI_S_USER4 :
- printf(
-"\\Ksni_s_user4 Transmit SNI-97801-5xx: Shift-Key below F21\n");
- break;
- case K_SNI_S_F22 :
- printf("\\Ksni_s_f22 Transmit SNI-97801-5xx: Shift-F22\n");
- break;
- case K_SNI_S_USER5 :
- printf(
-"\\Ksni_s_user5 Transmit SNI-97801-5xx: Shift-Key below F22\n");
- break;
- case K_SNI_S_HELP :
- printf("\\Ksni_s_help Transmit SNI-97801-5xx: Shift-Help\n");
- break;
- case K_SNI_S_HOME :
- printf("\\Ksni_s_home Transmit SNI-97801-5xx: Shift-Home\n");
- break;
- case K_SNI_S_INSERT_CHAR :
- printf(
-"\\Ksni_s_ins_char Transmit SNI-97801-5xx: Shift-Insert Char\n");
- break;
- case K_SNI_S_INSERT_LINE :
- printf(
-"\\Ksni_s_ins_line Transmit SNI-97801-5xx: Shift-Insert Line\n");
- break;
- case K_SNI_S_INSERT_WORD :
- printf(
-"\\Ksni_s_ins_word Transmit SNI-97801-5xx: Shift-Insert Word\n");
- break;
- case K_SNI_S_LEFT_TAB :
- printf("\\Ksni_s_left_tab Transmit SNI-97801-5xx: Shift-Left Tab\n");
- break;
- case K_SNI_S_CURSOR_LEFT :
- printf(
-"\\Ksni_s_lfarr Transmit SNI-97801-5xx: Shift-Cursor Left\n");
- break;
- case K_SNI_S_MODE :
- printf("\\Ksni_s_mode Transmit SNI-97801-5xx: Shift-Mode\n");
- break;
- case K_SNI_S_PAGE :
- printf("\\Ksni_s_page Transmit SNI-97801-5xx: Shift-Page\n");
- break;
- case K_SNI_S_PRINT :
- printf("\\Ksni_s_print Transmit SNI-97801-5xx: Shift-Print\n");
- break;
- case K_SNI_S_CURSOR_RIGHT:
- printf(
-"\\Ksni_s_rtarr Transmit SNI-97801-5xx: Shift-Cursor Right\n");
- break;
- case K_SNI_S_SCROLL_DOWN :
- printf(
-"\\Ksni_s_scroll_dn Transmit SNI-97801-5xx: Shift-Scroll Down\n");
- break;
- case K_SNI_S_SCROLL_UP :
- printf("\\Ksni_s_scroll_up Transmit SNI-97801-5xx: Shift-Scroll Up\n");
- break;
- case K_SNI_S_START :
- printf("\\Ksni_s_start Transmit SNI-97801-5xx: Shift-Start\n");
- break;
- case K_SNI_S_CURSOR_UP :
- printf("\\Ksni_s_uparr Transmit SNI-97801-5xx: Shift-Cursor Up\n");
- break;
- case K_SNI_S_TAB :
- printf("\\Ksni_s_tab Transmit SNI-97801-5xx: Shift-Tab\n");
- break;
- case K_SNI_SCROLL_DOWN :
- printf("\\Ksni_scroll_dn Transmit SNI-97801-5xx: Scroll Down\n");
- break;
- case K_SNI_SCROLL_UP :
- printf("\\Ksni_scroll_up Transmit SNI-97801-5xx: Scroll Up\n");
- break;
- case K_SNI_START :
- printf("\\Ksni_start Transmit SNI-97801-5xx: Start\n");
- break;
- case K_SNI_TAB :
- printf("\\Ksni_tab Transmit SNI-97801-5xx: Tab\n");
- break;
- case K_SNI_CURSOR_UP :
- printf("\\Ksni_uparr Transmit SNI-97801-5xx: Cursor Up\n");
- break;
-
- case K_BA80_ATTR:
- printf("\\Kba80_attr Transmit BA80: Attr\n");
- break;
- case K_BA80_C_KEY:
- printf("\\Kba80_c_key Transmit BA80: C\n");
- break;
- case K_BA80_CLEAR:
- printf("\\Kba80_clear Transmit BA80: Clear\n");
- break;
- case K_BA80_CMD:
- printf("\\Kba80_cmd Transmit BA80: Cmd\n");
- break;
- case K_BA80_COPY:
- printf("\\Kba80_copy Transmit BA80: Copy\n");
- break;
- case K_BA80_DEL:
- printf("\\Kba80_del Transmit BA80: Delete\n");
- break;
- case K_BA80_DEL_B:
- printf("\\Kba80_del_b Transmit BA80: Delete B\n");
- break;
- case K_BA80_DO:
- printf("\\Kba80_do Transmit BA80: Do\n");
- break;
- case K_BA80_END:
- printf("\\Kba80_end Transmit BA80: End\n");
- break;
- case K_BA80_ENV:
- printf("\\Kba80_env Transmit BA80: Env\n");
- break;
- case K_BA80_EOP:
- printf("\\Kba80_eop Transmit BA80: EOP\n");
- break;
- case K_BA80_ERASE:
- printf("\\Kba80_erase Transmit BA80: Erase\n");
- break;
- case K_BA80_FMT:
- printf("\\Kba80_fmt Transmit BA80: Format\n");
- break;
- case K_BA80_HELP:
- printf("\\Kba80_help Transmit BA80: Help\n");
- break;
- case K_BA80_HOME:
- printf("\\Kba80_home Transmit BA80: Home\n");
- break;
- case K_BA80_INS:
- printf("\\Kba80_ins Transmit BA80: Insert\n");
- break;
- case K_BA80_INS_B:
- printf("\\Kba80_ins_b Transmit BA80: Insert B\n");
- break;
- case K_BA80_MARK:
- printf("\\Kba80_mark Transmit BA80: Mark\n");
- break;
- case K_BA80_MOVE:
- printf("\\Kba80_move Transmit BA80: Move\n");
- break;
- case K_BA80_PA01:
- printf("\\Kba80_pa01 Transmit BA80: PA1\n");
- break;
- case K_BA80_PA02:
- printf("\\Kba80_pa02 Transmit BA80: PA2\n");
- break;
- case K_BA80_PA03:
- printf("\\Kba80_pa03 Transmit BA80: PA3\n");
- break;
- case K_BA80_PA04:
- printf("\\Kba80_pa04 Transmit BA80: PA4\n");
- break;
- case K_BA80_PA05:
- printf("\\Kba80_pa05 Transmit BA80: PA5\n");
- break;
- case K_BA80_PA06:
- printf("\\Kba80_pa06 Transmit BA80: PA6\n");
- break;
- case K_BA80_PA07:
- printf("\\Kba80_pa07 Transmit BA80: PA7\n");
- break;
- case K_BA80_PA08:
- printf("\\Kba80_pa08 Transmit BA80: PA8\n");
- break;
- case K_BA80_PA09:
- printf("\\Kba80_pa09 Transmit BA80: PA9\n");
- break;
- case K_BA80_PA10:
- printf("\\Kba80_pa10 Transmit BA80: PA10\n");
- break;
- case K_BA80_PA11:
- printf("\\Kba80_pa11 Transmit BA80: PA11\n");
- break;
- case K_BA80_PA12:
- printf("\\Kba80_pa12 Transmit BA80: PA12\n");
- break;
- case K_BA80_PA13:
- printf("\\Kba80_pa13 Transmit BA80: PA13\n");
- break;
- case K_BA80_PA14:
- printf("\\Kba80_pa14 Transmit BA80: PA14\n");
- break;
- case K_BA80_PA15:
- printf("\\Kba80_pa15 Transmit BA80: PA15\n");
- break;
- case K_BA80_PA16:
- printf("\\Kba80_pa16 Transmit BA80: PA16\n");
- break;
- case K_BA80_PA17:
- printf("\\Kba80_pa17 Transmit BA80: PA17\n");
- break;
- case K_BA80_PA18:
- printf("\\Kba80_pa18 Transmit BA80: PA18\n");
- break;
- case K_BA80_PA19:
- printf("\\Kba80_pa19 Transmit BA80: PA19\n");
- break;
- case K_BA80_PA20:
- printf("\\Kba80_pa20 Transmit BA80: PA20\n");
- break;
- case K_BA80_PA21:
- printf("\\Kba80_pa21 Transmit BA80: PA21\n");
- break;
- case K_BA80_PA22:
- printf("\\Kba80_pa22 Transmit BA80: PA22\n");
- break;
- case K_BA80_PA23:
- printf("\\Kba80_pa23 Transmit BA80: PA23\n");
- break;
- case K_BA80_PA24:
- printf("\\Kba80_pa24 Transmit BA80: PA24\n");
- break;
- case K_BA80_PGDN:
- printf("\\Kba80_pgdn Transmit BA80: Page Down\n");
- break;
- case K_BA80_PGUP:
- printf("\\Kba80_pgup Transmit BA80: Page Up\n");
- break;
- case K_BA80_PICK:
- printf("\\Kba80_pick Transmit BA80: Pick\n");
- break;
- case K_BA80_PRINT:
- printf("\\Kba80_print Transmit BA80: Print\n");
- break;
- case K_BA80_PUT:
- printf("\\Kba80_put Transmit BA80: Put\n");
- break;
- case K_BA80_REFRESH:
- printf("\\Kba80_refresh Transmit BA80: Refresh \n");
- break;
- case K_BA80_RESET:
- printf("\\Kba80_reset Transmit BA80: Reset\n");
- break;
- case K_BA80_RUBOUT:
- printf("\\Kba80_rubout Transmit BA80: Rubout\n");
- break;
- case K_BA80_SAVE:
- printf("\\Kba80_save Transmit BA80: Save\n");
- break;
- case K_BA80_SOFTKEY1:
- printf("\\Kba80_softkey1 Transmit BA80: Softkey 1\n");
- break;
- case K_BA80_SOFTKEY2:
- printf("\\Kba80_softkey2 Transmit BA80: Softkey 2\n");
- break;
- case K_BA80_SOFTKEY3:
- printf("\\Kba80_softkey3 Transmit BA80: Softkey 3\n");
- break;
- case K_BA80_SOFTKEY4:
- printf("\\Kba80_softkey4 Transmit BA80: Softkey 4\n");
- break;
- case K_BA80_SOFTKEY5:
- printf("\\Kba80_softkey5 Transmit BA80: Softkey 5\n");
- break;
- case K_BA80_SOFTKEY6:
- printf("\\Kba80_softkey6 Transmit BA80: Softkey 6\n");
- break;
- case K_BA80_SOFTKEY7:
- printf("\\Kba80_softkey7 Transmit BA80: Softkey 7\n");
- break;
- case K_BA80_SOFTKEY8:
- printf("\\Kba80_softkey8 Transmit BA80: Softkey 8\n");
- break;
- case K_BA80_SOFTKEY9:
- printf("\\Kba80_softkey9 Transmit BA80: Softkey 9\n");
- break;
- case K_BA80_UNDO:
- printf("\\Kba80_undo Transmit BA80: Undo\n");
- break;
-
- case K_I31_F01:
- printf("\\Ki31_f01 Transmit IBM 31xx: F1\n");
- break;
- case K_I31_F02:
- printf("\\Ki31_f02 Transmit IBM 31xx: F2\n");
- break;
- case K_I31_F03:
- printf("\\Ki31_f03 Transmit IBM 31xx: F3\n");
- break;
- case K_I31_F04:
- printf("\\Ki31_f04 Transmit IBM 31xx: F4\n");
- break;
- case K_I31_F05:
- printf("\\Ki31_f05 Transmit IBM 31xx: F5\n");
- break;
- case K_I31_F06:
- printf("\\Ki31_f06 Transmit IBM 31xx: F6\n");
- break;
- case K_I31_F07:
- printf("\\Ki31_f07 Transmit IBM 31xx: F7\n");
- break;
- case K_I31_F08:
- printf("\\Ki31_f08 Transmit IBM 31xx: F8\n");
- break;
- case K_I31_F09:
- printf("\\Ki31_f09 Transmit IBM 31xx: F9\n");
- break;
- case K_I31_F10:
- printf("\\Ki31_f10 Transmit IBM 31xx: F10\n");
- break;
- case K_I31_F11:
- printf("\\Ki31_f11 Transmit IBM 31xx: F11\n");
- break;
- case K_I31_F12:
- printf("\\Ki31_f12 Transmit IBM 31xx: F12\n");
- break;
- case K_I31_F13:
- printf("\\Ki31_f13 Transmit IBM 31xx: F13\n");
- break;
- case K_I31_F14:
- printf("\\Ki31_f14 Transmit IBM 31xx: F14\n");
- break;
- case K_I31_F15:
- printf("\\Ki31_f15 Transmit IBM 31xx: F15\n");
- break;
- case K_I31_F16:
- printf("\\Ki31_f16 Transmit IBM 31xx: F16\n");
- break;
- case K_I31_F17:
- printf("\\Ki31_f17 Transmit IBM 31xx: F17\n");
- break;
- case K_I31_F18:
- printf("\\Ki31_f18 Transmit IBM 31xx: F18\n");
- break;
- case K_I31_F19:
- printf("\\Ki31_f19 Transmit IBM 31xx: F19\n");
- break;
- case K_I31_F20:
- printf("\\Ki31_f20 Transmit IBM 31xx: F20\n");
- break;
- case K_I31_F21:
- printf("\\Ki31_f21 Transmit IBM 31xx: F21\n");
- break;
- case K_I31_F22:
- printf("\\Ki31_f22 Transmit IBM 31xx: F22\n");
- break;
- case K_I31_F23:
- printf("\\Ki31_f23 Transmit IBM 31xx: F23\n");
- break;
- case K_I31_F24:
- printf("\\Ki31_f24 Transmit IBM 31xx: F24\n");
- break;
- case K_I31_F25:
- printf("\\Ki31_f25 Transmit IBM 31xx: F25\n");
- break;
- case K_I31_F26:
- printf("\\Ki31_f26 Transmit IBM 31xx: F26\n");
- break;
- case K_I31_F27:
- printf("\\Ki31_f27 Transmit IBM 31xx: F27\n");
- break;
- case K_I31_F28:
- printf("\\Ki31_f28 Transmit IBM 31xx: F28\n");
- break;
- case K_I31_F29:
- printf("\\Ki31_f29 Transmit IBM 31xx: F29\n");
- break;
- case K_I31_F30:
- printf("\\Ki31_f30 Transmit IBM 31xx: F30\n");
- break;
- case K_I31_F31:
- printf("\\Ki31_f31 Transmit IBM 31xx: F31\n");
- break;
- case K_I31_F32:
- printf("\\Ki31_f32 Transmit IBM 31xx: F32\n");
- break;
- case K_I31_F33:
- printf("\\Ki31_f33 Transmit IBM 31xx: F33\n");
- break;
- case K_I31_F34:
- printf("\\Ki31_f34 Transmit IBM 31xx: F34\n");
- break;
- case K_I31_F35:
- printf("\\Ki31_f35 Transmit IBM 31xx: F35\n");
- break;
- case K_I31_F36:
- printf("\\Ki31_f36 Transmit IBM 31xx: F36\n");
- break;
- case K_I31_PA1:
- printf("\\Ki31_pa1 Transmit IBM 31xx: PA1\n");
- break;
- case K_I31_PA2:
- printf("\\Ki31_pa2 Transmit IBM 31xx: PA2\n");
- break;
- case K_I31_PA3:
- printf("\\Ki31_pa3 Transmit IBM 31xx: PA3\n");
- break;
- case K_I31_RESET:
- printf("\\Ki31_reset Transmit IBM 31xx: Reset\n");
- break;
- case K_I31_JUMP:
- printf("\\Ki31_jump Transmit IBM 31xx: Jump\n");
- break;
- case K_I31_CLEAR:
- printf("\\Ki31_clear Transmit IBM 31xx: Clear\n");
- break;
- case K_I31_ERASE_EOF:
- printf("\\Ki31_erase_eof Transmit IBM 31xx: Erase to End of Field\n");
- break;
- case K_I31_ERASE_EOP:
- printf("\\Ki31_eop Transmit IBM 31xx: Erase to End of Page\n");
- break;
- case K_I31_ERASE_INP:
- printf("\\Ki31_inp Transmit IBM 31xx: Erase Input Operation\n");
- break;
- case K_I31_INSERT_CHAR:
- printf("\\Ki31_ins_char Transmit IBM 31xx: Insert Character\n");
- break;
- case K_I31_INSERT_SPACE:
- printf("\\Ki31_ins_space Transmit IBM 31xx: Insert Space\n");
- break;
- case K_I31_DELETE:
- printf("\\Ki31_delete Transmit IBM 31xx: Delete Character\n");
- break;
- case K_I31_INS_LN:
- printf("\\Ki31_ins_line Transmit IBM 31xx: Insert Line\n");
- break;
- case K_I31_DEL_LN:
- printf("\\Ki31_del_ln Transmit IBM 31xx: Delete Line\n");
- break;
- case K_I31_PRINT_LINE:
- printf("\\Ki31_prt_line Transmit IBM 31xx: Print Line\n");
- break;
- case K_I31_PRINT_MSG:
- printf("\\Ki31_prt_msg Transmit IBM 31xx: Print Message\n");
- break;
- case K_I31_PRINT_SHIFT:
- printf("\\Ki31_prt_shift Transmit IBM 31xx: Print Shift\n");
- break;
- case K_I31_CANCEL:
- printf("\\Ki31_cancel Transmit IBM 31xx: Cancel\n");
- break;
- case K_I31_SEND_LINE:
- printf("\\Ki31_send_line Transmit IBM 31xx: Send Line\n");
- break;
- case K_I31_SEND_MSG:
- printf("\\Ki31_send_msg Transmit IBM 31xx: Send Message\n");
- break;
- case K_I31_SEND_PAGE:
- printf("\\Ki31_send_page Transmit IBM 31xx: Send Page\n");
- break;
- case K_I31_HOME:
- printf("\\Ki31_home Transmit IBM 31xx: Home\n");
- break;
- case K_I31_BACK_TAB:
- printf("\\Ki31_back_tab Transmit IBM 31xx: Back Tab\n");
- break;
- case K_SUN_STOP:
- printf("\\Ksunstop Transmit SUN Console: Stop\n");
- break;
- case K_SUN_AGAIN:
- printf("\\Ksunagain Transmit SUN Console: Again\n");
- break;
- case K_SUN_PROPS:
- printf("\\Ksunprops Transmit SUN Console: Props\n");
- break;
- case K_SUN_UNDO:
- printf("\\Ksunundo Transmit SUN Console: Undo\n");
- break;
- case K_SUN_FRONT:
- printf("\\Ksunfront Transmit SUN Console: Front\n");
- break;
- case K_SUN_COPY:
- printf("\\Ksuncopy Transmit SUN Console: Copy\n");
- break;
- case K_SUN_OPEN:
- printf("\\Ksunopen Transmit SUN Console: Open\n");
- break;
- case K_SUN_PASTE:
- printf("\\Ksunpaste Transmit SUN Console: Paste\n");
- break;
- case K_SUN_FIND:
- printf("\\Ksunfind Transmit SUN Console: Find\n");
- break;
- case K_SUN_CUT:
- printf("\\Ksuncut Transmit SUN Console: Cut\n");
- break;
- case K_SUN_HELP:
- printf("\\Ksunhelp Transmit SUN Console: Help\n");
- break;
-
- default:
- printf("No additional help available for this kverb\n");
- }
- printf("\n");
-
- /* This is not the proper way to do it since it doesn't show */
- /* all emulations, nor does it show the special modes, but it */
- /* is better than nothing. */
-
- printf("Current bindings:\n");
- found = 0;
- for (i = 256; i < KMSIZE ; i++) {
- con_event evt = mapkey(i);
- if (evt.type != kverb)
- continue;
- if ((evt.kverb.id & ~F_KVERB) == xx) {
- found = 1;
- printf(" \\%-4d - %s\n",i,keyname(i));
- }
- }
-#ifdef OS2MOUSE
- for ( button = 0 ; button < MMBUTTONMAX ; button++ )
- for ( event = 0 ; event < MMEVENTSIZE ; event++ )
- if ( mousemap[button][event].type == kverb ) {
- if ( (mousemap[button][event].kverb.id & ~F_KVERB) == xx ) {
- found = 1;
- printf(" Mouse - %s\n",mousename(button,event));
- }
- }
-#endif /* OS2MOUSE */
-
- if ( !found ) {
- printf(" (none)\n");
- }
- return(0);
-}
-#endif /* NOKVERBS */
-#endif /* OS2 */
-
-#ifndef NOXFER
-/* D O H R M T -- Give help about REMOTE command */
-
-static char *hrset[] = {
-"Syntax: REMOTE SET parameter value",
-"Example: REMOTE SET FILE TYPE BINARY",
-" Asks the Kermit server to set the named parameter to the given value.",
-" Equivalent to typing the corresponding SET command directly to the other",
-" Kermit if it were in interactive mode.", "" };
-
-int
-dohrmt(xx) int xx; {
- int x;
- if (xx == -3) return(hmsga(hmhrmt));
- if (xx < 0) return(xx);
- if ((x = cmcfm()) < 0) return(x);
- switch (xx) {
-
-case XZCPY:
- return(hmsg("Syntax: REMOTE COPY source destination\n\
- Asks the Kermit server to copy the source file to destination.\n\
- Synonym: RCOPY."));
-
-case XZCWD:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE CD [ name ]\n\
- Asks the Kermit or FTP server to change its working directory or device.\n\
- If the device or directory name is omitted, restore the default.\n\
- Synonym: RCD."));
-#else
- return(hmsg("Syntax: REMOTE CD [ name ]\n\
- Asks the Kermit server to change its working directory or device.\n\
- If the device or directory name is omitted, restore the default.\n\
- Synonym: RCD."));
-#endif /* NEWFTP */
-
-case XZDEL:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE DELETE filespec\n\
- Asks the Kermit or FTP server to delete the named file(s).\n\
- Synonym: RDEL."));
-#else
- return(hmsg("Syntax: REMOTE DELETE filespec\n\
- Asks the Kermit server to delete the named file(s).\n\
- Synonym: RDEL."));
-#endif /* NEWFTP */
-
-case XZMKD:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE MKDIR directory-name\n\
- Asks the Kermit or FTP server to create the named directory.\n\
- Synonym: RMKDIR."));
-#else
- return(hmsg("Syntax: REMOTE MKDIR directory-name\n\
- Asks the Kermit server to create the named directory.\n\
- Synonym: RMKDIR."));
-#endif /* NEWFTP */
-
-case XZRMD:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE RMDIR directory-name\n\
- Asks the Kermit or FTP server to remove the named directory.\n\
- Synonym: RRMDIR."));
-#else
- return(hmsg("Syntax: REMOTE RMDIR directory-name\n\
- Asks the Kermit server to remove the named directory.\n\
- Synonym: RRMDIR."));
-#endif /* NEWFTP */
-
-case XZDIR:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE DIRECTORY [ filespec ]\n\
- Asks the Kermit or FTP server to provide a directory listing of the named\n\
- file(s) or if no file specification is given, of all files in its current\n\
- directory. Synonym: RDIR."));
-#else
- return(hmsg("Syntax: REMOTE DIRECTORY [ filespec ]\n\
- Asks the Kermit server to provide a directory listing of the named\n\
- file(s) or if no file specification is given, of all files in its current\n\
- directory. Synonym: RDIR."));
-#endif /* NEWFTP */
-
-case XZHLP:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE HELP\n\
- Asks the Kermit or FTP server to list the services it provides.\n\
- Synonym: RHELP."));
-#else
- return(hmsg("Syntax: REMOTE HELP\n\
- Asks the Kermit server to list the services it provides.\n\
- Synonym: RHELP."));
-#endif /* NEWFTP */
-
-case XZHOS:
- return(hmsg("Syntax: REMOTE HOST command\n\
- Sends a command to the other computer in its own command language\n\
- through the Kermit server that is running on that host. Synonym: RHOST."));
-
-#ifndef NOFRILLS
-case XZKER:
- return(hmsg("Syntax: REMOTE KERMIT command\n\
- Sends a command to the remote Kermit server in its own command language.\n\
- Synonym: RKERMIT."));
-
-case XZLGI:
- return(hmsg("Syntax: REMOTE LOGIN user password [ account ]\n\
- Logs in to a remote Kermit server that requires you login. Note: RLOGIN\n\
- is NOT a synonym for REMOTE LOGIN."));
-
-case XZLGO:
- return(hmsg("Syntax: REMOTE LOGOUT\n\
- Logs out from a remote Kermit server to which you have previously logged in."
-));
-
-case XZMSG:
- return(hmsg("Syntax: REMOTE MESSAGE text\n\
- Sends a short text message to the remote Kermit server."));
-
-case XZPRI:
- return(hmsg("Syntax: REMOTE PRINT filespec [ options ]\n\
- Sends the specified file(s) to the remote Kermit and ask it to have the\n\
- file printed on the remote system's printer, using any specified options.\n\
- Synonym: RPRINT."));
-#endif /* NOFRILLS */
-
-case XZREN:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE RENAME filespec newname\n\
- Asks the Kermit or FTP server to rename the file. Synonym: RRENAME."));
-#else
- return(hmsg("Syntax: REMOTE RENAME filespec newname\n\
- Asks the Kermit server to rename the file. Synonym: RRENAME."));
-#endif /* NEWFTP */
-
-case XZSET:
- return(hmsga(hrset));
-
-case XZSPA:
- return(hmsg("Syntax: REMOTE SPACE [ name ]\n\
- Asks the Kermit server to tell you about its disk space on the current\n\
- disk or directory, or in the one that you name. Synonym: RSPACE."));
-
-#ifndef NOFRILLS
-case XZTYP:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE TYPE file\n\
- Asks the Kermit or FTP server to send the named file to your screen.\n\
- Synonym: RTYPE."));
-#else
- return(hmsg("Syntax: REMOTE TYPE file\n\
- Asks the Kermit server to send the named file(s) to your screen.\n\
- Synonym: RTYPE."));
-#endif /* NEWFTP */
-
-
-case XZWHO:
- return(hmsg("Syntax: REMOTE WHO [ name ]\n\
- Asks the Kermit server to list who's logged in, or to give information\n\
- about the named user. Synonym: RWHO."));
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
-case XZQUE:
- return(hmsg(
-"Syntax: [ REMOTE ] QUERY { KERMIT, SYSTEM, USER } variable-name\n\
- Asks the Kermit server to send the value of the named variable of the\n\
- given type, and make it available in the \\v(query) variable. When the\n\
- type is KERMIT functions may also be specified as if they were variables."));
-
-case XZASG:
- return(hmsg(
-"Syntax: REMOTE ASSIGN variable-name [ value ]\n\
- Assigns the given value to the named global variable on the server.\n\
- Synonyms: RASG, RASSIGN."));
-#endif /* NOSPL */
-
-case XZPWD:
- return(hmsg(
-#ifdef NEWFTP
-"Syntax: REMOTE PWD\n\
- Asks the Kermit server to display its current working directory.\n\
- Synonym: RPWD."));
-#else
-"Syntax: REMOTE PWD\n\
- Asks the Kermit or FTP server to display its current working directory.\n\
- Synonym: RPWD."));
-#endif /* NEWFTP */
-
-case XZXIT:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE EXIT\n\
- Asks the Kermit server to exit (without disconnecting), or closes an FTP\n\
- connection. Synonym: REXIT, and (for FTP only) BYE, FTP BYE."));
-#else
- return(hmsg("Syntax: REMOTE EXIT\n\
- Asks the Kermit server to exit. Synonym: REXIT."));
-#endif /* NEWFTP */
-
-default:
- if ((x = cmcfm()) < 0) return(x);
- printf("?Sorry, no help available - \"%s\"\n",cmdbuf);
- return(-9);
- }
-}
-#endif /* NOXFER */
-#endif /* NOHELP */
-#endif /* NOICP */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus3.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuus3.c
deleted file mode 100644
index 5887b34..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus3.c
+++ /dev/null
@@ -1,13629 +0,0 @@
-#ifdef SSHTEST
-#define SSHBUILTIN
-#endif /* SSHTEST */
-
-#include "ckcsym.h" /* Symbol definitions */
-
-/* C K U U S 3 -- "User Interface" for C-Kermit, part 3 */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/* SET command (but much material has been split off into ckuus7.c). */
-
-/*
- Kermit-specific includes.
- Definitions here supersede those from system include files.
-*/
-#include "ckcdeb.h" /* Debugging & compiler things */
-#include "ckcasc.h" /* ASCII character symbols */
-#include "ckcker.h" /* Kermit application definitions */
-#include "ckcxla.h" /* Character set translation */
-#include "ckcnet.h" /* Network symbols */
-
-char pwbuf[PWBUFL+1] = { NUL, NUL };
-int pwflg = 0;
-int pwcrypt = 0;
-
-#ifndef NOICP
-
-#ifdef CK_AUTHENTICATION
-#include "ckuath.h"
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-#include "ckuusr.h" /* User interface symbols */
-#ifdef OS2
-#include "ckcuni.h"
-#ifdef SSHBUILTIN
-#include "ckossh.h"
-#endif /* SSHBUILTIN */
-#ifdef CK_NETBIOS
-#include <os2.h>
-#ifdef COMMENT /* Would you believe */
-#undef COMMENT /* <os2.h> defines this ? */
-#endif /* COMMENT */
-#include "ckonbi.h"
-extern UCHAR NetBiosAdapter;
-#endif /* CK_NETBIOS */
-#include "ckocon.h"
-#include "ckokey.h"
-#ifndef NOTERM
-extern unsigned char colorcmd; /* Command-screen colors */
-extern struct keytab ttyclrtab[];
-extern int nclrs;
-extern int tt_cols[], tt_rows[], tt_szchng[], tt_status[];
-#endif /* NOTERM */
-_PROTOTYP(int setprty, (void));
-extern char startupdir[], exedir[];
-extern int tt_modechg;
-#ifdef NT
-#include <windows.h>
-#include <tapi.h>
-#include "ckntap.h" /* Microsoft TAPI */
-#endif /* NT */
-#endif /* OS2 */
-
-#ifndef OS2
-extern char * exedir;
-#endif /* OS2 */
-
-#ifdef CK_RECALL
-extern int cm_retry;
-#endif /* CK_RECALL */
-
-#ifdef NEWFTP
-extern int ftpisopen();
-#endif /* NEWFTP */
-
-extern int cmdint;
-extern int srvidl;
-
-#ifdef CKFLOAT
-extern CKFLOAT floatval; /* (see isfloat()) */
-#endif /* CKFLOAT */
-
-#ifndef NOPUSH
-#ifndef NOFRILLS
-#ifdef VMS
-char editor[CKMAXPATH + 1] = "edit";
-#else
-char editor[CKMAXPATH + 1] = { NUL, NUL };
-#endif /* VMS */
-char editopts[128] = { NUL, NUL };
-char editfile[CKMAXPATH + 1] = { NUL, NUL };
-#ifdef BROWSER
-char browser[CKMAXPATH + 1] = { NUL, NUL };
-char browsopts[128] = { NUL, NUL };
-char browsurl[4096] = { NUL, NUL };
-#endif /* BROWSER */
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-
-#ifndef NOFRILLS
-#ifndef NORENAME
-_PROTOTYP(int setrename, (void));
-#endif /* NORENAME */
-#endif /* NOFRILLS */
-
-/* Variables */
-
-int cmd_quoting = 1;
-int cmd_err = 1;
-extern int hints, xcmdsrc;
-
-#ifdef CK_KERBEROS
-char * k4pwprompt = NULL; /* Kerberos 4 password prompt */
-char * k4prprompt = NULL; /* Kerberos 4 principal prompt */
-char * k5pwprompt = NULL; /* Kerberos 5 password prompt */
-char * k5prprompt = NULL; /* Kerberos 5 principal prompt */
-#endif /* CK_KERBEROS */
-#ifdef CK_SRP
-char * srppwprompt = NULL;
-#endif /* CK_SRP */
-
-extern char * ckprompt, * ikprompt; /* Default prompt */
-extern xx_strp xxstring;
-
-extern char * cdmsgfile[], * cdmsgstr;
-
-extern int
- local, server, success, dest, sleepcan, inserver, flow, autoflow, binary,
- parity, escape, what, turn, duplex, backgrd, hwparity, stopbits, turnch,
- mdmtyp, network, quiet, nettype, carrier, debses, debtim, cdtimo, nlangs,
- bgset, pflag, msgflg, cmdmsk, xsuspend, techo, pacing, xitwarn, xitsta,
- outesc, cmd_cols, cmd_rows, ckxech, xaskmore, haveline, didsetlin, isguest,
- mdmsav, clearrq, saveask, debmsg;
-
-extern int reliable, setreliable, matchdot, matchfifo, dir_dots;
-
-#ifndef NOSERVER
- extern int en_pri;
-#endif /* NOSERVER */
-
-#ifdef IKSDCONF
-extern int iksdcf;
-#endif /* IKSDCONF */
-#ifdef TCPSOCKET
- extern int tn_exit;
-#endif /* TCPSOCKET */
-#ifdef TNCODE
- char * tn_pr_uid = NULL;
-#endif /* TNCODE */
- extern int exitonclose;
-
-#ifndef NOKVERBS
-extern int nkverbs;
-extern struct keytab kverbs[];
-#endif /* NOKVERBS */
-
-extern int ttnproto; /* Network protocol */
-
-extern char *ccntab[]; /* Names of control chars */
-
-#ifdef CK_APC
-extern int apcactive, apcstatus;
-#endif /* CK_APC */
-
-#ifndef NOSCRIPT
-extern int secho; /* Whether SCRIPT cmd should echo */
-#endif /* NOSCRIPT */
-
-#ifdef DCMDBUF
-extern char *atmbuf, *atxbuf;
-#else
-extern char atmbuf[], atxbuf[];
-#endif /* DCMDBUF */
-extern int cmflgs;
-
-extern char psave[];
-extern char uidbuf[];
-extern int sl_uid_saved;
-int DeleteStartupFile = 0;
-
-extern int cmdlvl; /* Overall command level */
-
-#ifndef NOSPL
-_PROTOTYP( static int parsdir, (int) );
-char prmbuf[PWBUFL+1] = { NUL, NUL };
-int fndiags = 1; /* Function diagnostics on/off */
-int fnerror = 1; /* Function error treatment */
-
-#ifdef DCMDBUF
-extern int *count, *takerr, *merror, *inpcas;
-#else
-extern int count[], takerr[], merror[], inpcas[];
-#endif /* DCMDBUF */
-extern int mecho; /* Macro echo */
-extern long ck_alarm;
-extern char alrm_date[], alrm_time[];
-#else
-extern int takerr[];
-#endif /* NOSPL */
-
-extern int x_ifnum;
-extern int bigsbsiz, bigrbsiz; /* Packet buffers */
-
-extern long speed; /* Terminal speed */
-
-extern char ttname[]; /* Communication device name */
-extern char myhost[] ;
-extern char inidir[]; /* Ini File directory */
-
-#ifndef NOSETKEY
-extern KEY *keymap; /* Character map for SET KEY (1:1) */
-extern MACRO *macrotab; /* Macro map for SET KEY (1:string) */
-#endif /* NOSETKEY */
-#ifdef OS2
-int wideresult; /* For wide OS/2 scan codes/cmnum() */
-#endif /* OS2 */
-
-#ifndef NOLOCAL
-#ifdef OS2
-extern int tt_scrsize[]; /* Scrollback buffer Sizes */
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-/* Printer settings */
-
-extern char * printername; /* NULL if printer not redirected */
-extern int printpipe;
-extern int noprinter;
-#ifdef PRINTSWI
-int printtimo = 0;
-char * printterm = NULL;
-char * printsep = NULL;
-int printertype = 0;
-#ifdef BPRINT
-int printbidi = 0; /* SET BPRINTER (bidirectional) */
-long pportspeed = 0L; /* Bidirection printer port speed, */
-int pportparity = 0; /* parity, */
-int pportflow = FLO_KEEP; /* and flow control */
-#endif /* BPRINT */
-#ifdef OS2
-extern int txt2ps; /* Text2PS conversion? */
-extern int ps_width, ps_length; /* Text2PS dimensions */
-#endif /* OS2 */
-#endif /* PRINTSWI */
-
-#ifdef OS2
-extern int tcp_avail; /* Nonzero if TCP/IP is available */
-#ifdef DECNET
-extern int dnet_avail; /* Ditto for DECnet */
-#endif /* DECNET */
-#ifdef SUPERLAT
-extern int slat_avail;
-#endif /* SUPERLAT */
-#endif /* OS2 */
-
-static struct keytab logintab[] = {
- { "password", LOGI_PSW, CM_INV },
- { "prompt", LOGI_PRM, CM_INV },
- { "userid", LOGI_UID, 0 }
-};
-
-#ifndef NOCSETS
-/* system-independent character sets, defined in ckcxla.[ch] */
-extern struct csinfo tcsinfo[];
-extern struct langinfo langs[];
-
-/* Other character-set related variables */
-extern int tcharset, tslevel, language;
-#endif /* NOCSETS */
-
-/* File-transfer variable declarations */
-
-#ifndef NOXFER
-#ifdef CK_AUTODL
-extern int cmdadl;
-#endif /* CK_AUTODL */
-
-#ifndef NOSERVER
-extern int ngetpath;
-extern char * getpath[];
-#endif /* NOSERVER */
-
-extern struct ck_p ptab[];
-
-extern CHAR sstate; /* Protocol start state */
-extern CHAR myctlq; /* Control-character prefix */
-extern CHAR myrptq; /* Repeat-count prefix */
-
-extern int protocol, size, spsiz, spmax, urpsiz, srvtim, srvcdmsg, slostart,
- srvdis, xfermode, ckdelay, keep, maxtry, unkcs, bctr, bctf, ebqflg, swcapr,
- wslotr, lscapr, lscapu, spsizr, rptena, rptmin, docrc, xfrcan, xfrchr,
- xfrnum, xfrbel, xfrint, srvping, g_xfermode, xfrxla;
-
-#ifdef PIPESEND
-extern int usepipes;
-#endif /* PIPESEND */
-
-#ifdef CKXXCHAR /* DOUBLE / IGNORE char table */
-extern int dblflag, ignflag, dblchar;
-extern short dblt[];
-#endif /* CKXXCHAR */
-
-#ifdef CK_SPEED
-extern short ctlp[]; /* Control-prefix table */
-extern int prefixing;
-static struct keytab pfxtab[] = {
- "all", PX_ALL, 0,
- "cautious", PX_CAU, 0,
- "minimal", PX_WIL, 0,
- "none", PX_NON, 0
-};
-#endif /* CK_SPEED */
-#endif /* NOXFER */
-
-/* Declarations from cmd package */
-
-#ifdef DCMDBUF
-extern char *cmdbuf; /* Command buffer */
-extern char *line;
-extern char *tmpbuf;
-#else
-extern char cmdbuf[]; /* Command buffer */
-extern char line[]; /* Character buffer for anything */
-extern char tmpbuf[];
-#endif /* DCMDBUF */
-
-/* From main ckuser module... */
-
-extern char *tp, *lp; /* Temporary buffer */
-
-extern int tlevel; /* Take Command file level */
-
-#ifndef NOLOCAL
-extern int sessft; /* Session-log file type */
-extern int slogts; /* Session-log timestamps on/off */
-extern int slognul; /* Lines null-terminated */
-#endif /* NOLOCAL */
-
-char * tempdir = NULL;
-
-#ifdef VMS
-int vms_msgs = 1; /* SET MESSAGES */
-extern int batch;
-#endif /* VMS */
-
-/* Keyword tables for SET commands */
-
-#ifdef CK_SPEED
-struct keytab ctltab[] = {
- "prefixed", 1, 0, /* Note, the values are important. */
- "unprefixed", 0, 0
-};
-#endif /* CK_SPEED */
-
-static struct keytab oldnew[] = {
- "new", 0, 0,
- "old", 1, 0
-};
-
-#define MCH_FIFO 1
-#define MCH_DOTF 2
-struct keytab matchtab[] = {
- { "dotfile", MCH_DOTF, 0 },
- { "fifo", MCH_FIFO, 0 }
-};
-int nmatchtab = (sizeof(matchtab) / sizeof(struct keytab));
-
-#ifndef NOSPL
-static struct keytab functab[] = {
- "diagnostics", FUNC_DI, 0,
- "error", FUNC_ER, 0
-};
-static int nfunctab = (sizeof(functab) / sizeof(struct keytab));
-
-struct keytab outptab[] = { /* SET OUTPUT parameters */
- "pacing", 0, 0, /* only one so far... */
- "special-escapes", 1, 0
-};
-int noutptab = (sizeof(outptab) / sizeof(struct keytab)); /* How many */
-#endif /* NOSPL */
-
-struct keytab chktab[] = { /* Block check types */
- "1", 1, 0, /* 1 = 6-bit checksum */
- "2", 2, 0, /* 2 = 12-bit checksum */
- "3", 3, 0, /* 3 = 16-bit CRC */
- "4", 4, 0, /* Same as B */
- "5", 5, 0, /* Same as F */
- "blank-free-2", 4, CM_INV, /* B = 12-bit checksum, no blanks */
- "force-3", 5, CM_INV /* F = Force CRC on ALL packets */
-};
-static int nchkt = (sizeof(chktab) / sizeof(struct keytab));
-
-struct keytab rpttab[] = { /* SET REPEAT */
- "counts", 0, 0, /* On or Off */
-#ifdef COMMENT
- "minimum", 1, 0, /* Threshhold */
-#endif /* COMMENT */
- "prefix", 2, 0 /* Repeat-prefix character value */
-};
-
-#ifndef NOLOCAL
-/* For SET [ MODEM ] CARRIER, and also for SET DIAL CONNECT */
-
-struct keytab crrtab[] = {
- "automatic", CAR_AUT, 0, /* 2 */
- "off", CAR_OFF, 0, /* 0 */
- "on", CAR_ON, 0 /* 1 */
-};
-int ncrr = 3;
-#endif /* NOLOCAL */
-
-struct keytab ooatab[] = { /* On/Off/Auto table */
- "automatic", SET_AUTO, 0, /* 2 */
- "off", SET_OFF, 0, /* 0 */
- "on", SET_ON, 0 /* 1 */
-};
-
-struct keytab ooetab[] = { /* On/Off/Stderr table 2010/03/12 */
- "off", SET_OFF, 0, /* for SET DEBUG MESSAGES */
- "on", SET_ON, 0,
- "s", 2, CM_ABR|CM_INV,
- "st", 2, CM_ABR|CM_INV,
- "std", 2, CM_ABR|CM_INV,
- "stderr", 2, 0,
- "stdout", SET_ON, CM_INV
-};
-static int nooetab = (sizeof(ooetab) / sizeof(struct keytab));
-
-struct keytab ooktab[] = { /* On/Off/Ask table */
- "ask", 2, 0, /* 2 */
- "off", SET_OFF, 0, /* 0 */
- "on", SET_ON, 0 /* 1 */
-};
-
-struct keytab qvtab[] = { /* Quiet/Verbose table */
- "quiet", 1, 0,
- "verbose", 0, 0
-};
-int nqvt = 2;
-
-/* For SET DEBUG */
-
-#define DEB_OFF 0
-#define DEB_ON 1
-#define DEB_SES 2
-#define DEB_TIM 3
-#define DEB_LEN 4
-#define DEB_MSG 5
-
-struct keytab dbgtab[] = {
- "linelength", DEB_LEN, CM_INV,
- "m", DEB_MSG, CM_ABR|CM_INV,
- "message", DEB_MSG, 0,
- "msg", DEB_MSG, CM_INV,
- "off", DEB_OFF, 0,
- "on", DEB_ON, 0,
- "session", DEB_SES, 0,
- "timestamps", DEB_TIM, 0
-};
-int ndbg = (sizeof(dbgtab) / sizeof(struct keytab));
-
-#ifndef NOLOCAL
-/* Transmission speeds */
-
-#ifdef TTSPDLIST /* Speed table constructed at runtime . . . */
-
-struct keytab * spdtab = NULL;
-int nspd = 0;
-
-#else
-/*
- Note, the values are encoded in cps rather than bps because 19200 and higher
- are too big for some ints. All but 75bps are multiples of ten. Result of
- lookup in this table must be multiplied by 10 to get actual speed in bps.
- If this number is 70, it must be changed to 75. If it is 888, this means
- 75/1200 split speed.
-
- The values are generic, rather than specific to UNIX. We can't use B75,
- B1200, B9600, etc, because non-UNIX versions of C-Kermit will not
- necessarily have these symbols defined. The BPS_xxx symbols are
- Kermit-specific, and are defined in ckcdeb.h or on the CC command line.
-
- Like all other keytabs, this one must be in "alphabetical" order,
- rather than numeric order.
-*/
-struct keytab spdtab[] = {
- "0", 0, CM_INV,
- "110", 11, 0,
-#ifdef BPS_115K
- "115200",11520, 0,
-#endif /* BPS_115K */
- "1200", 120, 0,
-#ifdef BPS_134
- "134.5", 134, 0,
-#endif /* BPS_134 */
-#ifdef BPS_14K
- "14400", 1440, 0,
-#endif /* BPS_14K */
-#ifdef BPS_150
- "150", 15, 0,
-#endif /* BPS_150 */
-#ifdef BPS_1800
- "1800", 180, 0,
-#endif /* BPS_150 */
-#ifdef BPS_19K
- "19200", 1920, 0,
-#endif /* BPS_19K */
-#ifdef BPS_200
- "200", 20, 0,
-#endif /* BPS_200 */
-#ifdef BPS_230K
- "230400", 23040, 0,
-#endif /* BPS_230K */
- "2400", 240, 0,
-#ifdef BPS_28K
- "28800", 2880, 0,
-#endif /* BPS_28K */
- "300", 30, 0,
-#ifdef BPS_3600
- "3600", 360, 0,
-#endif /* BPS_3600 */
-#ifdef BPS_38K
- "38400", 3840, 0,
-#endif /* BPS_38K */
-#ifdef BPS_460K
- "460800", 46080, 0, /* Need 32 bits for this... */
-#endif /* BPS_460K */
- "4800", 480, 0,
-#ifdef BPS_50
- "50", 5, 0,
-#endif /* BPS_50 */
-#ifdef BPS_57K
- "57600", 5760, 0,
-#endif /* BPS_57K */
- "600", 60, 0,
-#ifdef BPS_7200
- "7200", 720, 0,
-#endif /* BPS_7200 */
-#ifdef BPS_75
- "75", 7, 0,
-#endif /* BPS_75 */
-#ifdef BPS_7512
- "75/1200",888, 0, /* Code "888" for split speed */
-#endif /* BPS_7512 */
-#ifdef BPS_76K
- "76800", 7680, 0,
-#endif /* BPS_76K */
-#ifdef BPS_921K
- "921600", 92160,0, /* Need 32 bits for this... */
-#endif /* BPS_921K */
- "9600", 960, 0
-};
-int nspd = (sizeof(spdtab) / sizeof(struct keytab)); /* How many speeds */
-#endif /* TTSPDLIST */
-
-#ifdef TN_COMPORT
-struct keytab tnspdtab[] = { /* RFC 2217 TELNET COMPORT Option */
- "115200", 11520, 0, /* (add any other defined speeds) */
- "1200", 120, 0,
- "14400", 1440, 0,
- "19200", 1920, 0,
- "230400", 23040, 0,
- "2400", 240, 0,
- "28800", 2880, 0,
- "300", 30, 0,
- "38400", 3840, 0,
- "460800", 46080, 0,
- "4800", 480, 0,
- "57600", 5760, 0,
- "600", 60, 0,
- "9600", 960, 0
-};
-int ntnspd = (sizeof(tnspdtab) / sizeof(struct keytab)); /* How many speeds */
-#endif /* TN_COMPORT */
-#endif /* NOLOCAL */
-
-#ifndef NOCSETS
-extern struct keytab lngtab[]; /* Languages for SET LANGUAGE */
-extern int nlng;
-#endif /* NOCSETS */
-
-#ifndef NOLOCAL
-/* Duplex keyword table */
-
-struct keytab dpxtab[] = {
- "full", 0, 0,
- "half", 1, 0
-};
-#endif /* NOLOCAL */
-
-/* Flow Control */
-
-struct keytab cxtypesw[] = {
-#ifdef DECNET
- "/decnet", CXT_DECNET, 0,
-#endif /* DECNET */
- "/direct-serial", CXT_DIRECT, 0,
-#ifdef DECNET
- "/lat", CXT_LAT, 0,
-#else
-#ifdef SUPERLAT
- "/lat", CXT_LAT, 0,
-#endif /* SUPERLAT */
-#endif /* DECNET */
- "/modem", CXT_MODEM, 0,
-#ifdef NPIPE
- "/named-pipe", CXT_NPIPE, 0,
-#endif /* NPIPE */
-#ifdef NETBIOS
- "/netbios", CXT_NETBIOS, 0,
-#endif /* NETBIOS */
- "/remote", CXT_REMOTE, 0,
-#ifdef TCPSOCKET
- "/tcpip", CXT_TCPIP, 0,
-#endif /* TCPSOCKET */
-#ifdef ANYX25
- "/x.25", CXT_X25, 0,
-#endif /* ANYX25 */
- "", 0, 0
-};
-int ncxtypesw = (sizeof(cxtypesw) / sizeof(struct keytab));
-
-#ifdef TN_COMPORT
-struct keytab tnflotab[] = { /* SET FLOW-CONTROL keyword table */
- "dtr/cd", FLO_DTRC, 0, /* for RFC 2217 Telnet COMPORT */
- "dtr/cts", FLO_DTRT, 0,
- "keep", FLO_KEEP, 0,
- "none", FLO_NONE, 0,
- "rts/cts", FLO_RTSC, 0,
- "xon/xoff", FLO_XONX, 0
-};
-int ntnflo = (sizeof(tnflotab) / sizeof(struct keytab));
-#endif /* TN_COMPORT */
-
-struct keytab flotab[] = { /* SET FLOW-CONTROL keyword table */
- "automatic", FLO_AUTO, CM_INV, /* Not needed any more */
-#ifdef CK_DTRCD
- "dtr/cd", FLO_DTRC, 0,
-#endif /* CK_DTRCD */
-#ifdef CK_DTRCTS
- "dtr/cts", FLO_DTRT, 0,
-#endif /* CK_DTRCTS */
- "keep", FLO_KEEP, 0,
- "none", FLO_NONE, 0,
-#ifdef CK_RTSCTS
- "rts/cts", FLO_RTSC, 0,
-#endif /* CK_RTSCTS */
-#ifndef Plan9
- "xon/xoff", FLO_XONX, 0,
-#endif /* Plan9 */
- "", 0, 0
-};
-int nflo = (sizeof(flotab) / sizeof(struct keytab)) - 1;
-
-/* Handshake characters */
-
-struct keytab hshtab[] = {
- "bell", 007, 0,
- "code", 998, 0,
- "cr", 015, 0,
- "esc", 033, 0,
- "lf", 012, 0,
- "none", 999, 0, /* (can't use negative numbers) */
- "xoff", 023, 0,
- "xon", 021, 0
-};
-int nhsh = (sizeof(hshtab) / sizeof(struct keytab));
-
-#ifndef NOLOCAL
-static struct keytab sfttab[] = { /* File types for SET SESSION-LOG */
- "ascii", XYFT_T, CM_INV,
- "binary", XYFT_B, 0,
- "debug", XYFT_D, 0,
- "null-padded-lines", 998, 0,
- "text", XYFT_T, 0,
- "timestamped-text", 999, 0
-};
-static int nsfttab = (sizeof(sfttab) / sizeof(struct keytab));
-#endif /* NOLOCAL */
-
-#ifndef NODIAL
-
-#ifdef NETCONN /* Networks directory depends */
-int nnetdir = 0; /* on DIAL code -- fix later... */
-char *netdir[MAXDDIR+2];
-#endif /* NETCONN */
-
-_PROTOTYP( static int setdial, (int) );
-_PROTOTYP( static int setdcd, (void) );
-_PROTOTYP( static int cklogin, (void) );
-
-#ifndef MINIDIAL
-#ifdef OLDTBCODE
-extern int tbmodel; /* Telebit model ID */
-#endif /* OLDTBCODE */
-#endif /* MINIDIAL */
-
-extern MDMINF *modemp[]; /* Pointers to modem info structs */
-extern struct keytab mdmtab[]; /* Modem types (in module ckudia.c) */
-extern int nmdm; /* Number of them */
-
-_PROTOTYP(static int dialstr,(char **, char *));
-
-extern int dialhng, dialtmo, dialksp, dialdpy, dialmhu, dialec, dialdc;
-extern int dialrtr, dialint, dialudt, dialsrt, dialrstr, mdmwaitd;
-extern int mdmspd, dialfc, dialmth, dialesc, dialfld, dialidt, dialpace;
-extern int mdmspk, mdmvol, dialtest;
-
-int dialcvt = 2; /* DIAL CONVERT-DIRECTORY */
-int dialcnf = 0; /* DIAL CONFIRMATION */
-int dialcon = 2; /* DIAL CONNECT */
-int dialcq = 0; /* DIAL CONNECT AUTO quiet/verbose */
-extern long dialmax, dialcapas;
-int usermdm = 0;
-extern int ndialdir;
-extern char *dialini, *dialmstr, *dialmprmt, *dialdir[], *dialcmd, *dialnpr,
- *dialdcon, *dialdcoff, *dialecon, *dialecoff, *dialhcmd, *dialx3,
- *dialhwfc, *dialswfc, *dialnofc, *dialtone, *dialpulse, *dialname, *diallac;
-extern char *diallcc, *dialixp, *dialixs, *dialldp, *diallds, *dialtfp,
- *dialpxi, *dialpxo, *dialsfx, *dialaaon, *dialaaoff;
-extern char *diallcp, *diallcs, *dialini2, *dialmac;
-extern char *dialspoff, *dialspon, *dialvol1, *dialvol2, *dialvol3;
-
-char *dialtocc[MAXTPCC] = { NULL, NULL };
-int ndialtocc = 0;
-char *dialpucc[MAXTPCC] = { NULL, NULL };
-int ndialpucc = 0;
-
-char *dialtfc[MAXTOLLFREE] = {
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-int ntollfree = 0;
-
-char *dialpxx[MAXPBXEXCH] = {
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-int ndialpxx = 0;
-
-char *diallcac[MAXLOCALAC] = {
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-int nlocalac = 0;
-
-static struct keytab drstrtab[] = {
- "international", 5, 0,
- "local", 2, 0,
- "long-distance", 4, 0,
- "none", 6, 0
-};
-
-static struct keytab dcnvtab[] = {
- "ask", 2, 0,
- "off", 0, 0,
- "on", 1, 0
-};
-
-struct keytab setmdm[] = {
- "capabilities", XYDCAP, 0,
- "carrier-watch", XYDMCD, 0,
- "command", XYDSTR, 0,
- "compression", XYDDC, CM_INV,
- "data-compression", XYDDC, 0,
- "dial-command", XYDDIA, 0,
- "error-correction", XYDEC, 0,
- "escape-character", XYDESC, 0,
- "flow-control", XYDFC, 0,
- "hangup-method", XYDMHU, 0,
-#ifndef NOXFER
- "kermit-spoof", XYDKSP, 0,
-#endif /* NOXFER */
- "maximum-speed", XYDMAX, 0,
- "name", XYDNAM, 0,
- "speaker", XYDSPK, 0,
- "speed-matching", XYDSPD, 0,
- "type", XYDTYP, 0,
- "volume", XYDVOL, 0
-};
-int nsetmdm = (sizeof(setmdm) / sizeof(struct keytab));
-
-struct keytab voltab[] = {
- "high", 3, 0,
- "low", 1, 0,
- "medium", 2, 0
-};
-
-struct keytab mdmcap[] = {
- "at-commands", CKD_AT, 0,
- "compression", CKD_DC, 0,
- "dc", CKD_DC, CM_INV,
- "ec", CKD_EC, CM_INV,
- "error-correction", CKD_EC, 0,
- "hardware-flow", CKD_HW, 0,
- "hwfc", CKD_HW, CM_INV,
- "itu", CKD_V25, CM_INV,
- "kermit-spoof", CKD_KS, 0,
- "ks", CKD_KS, CM_INV,
- "sb", CKD_SB, CM_INV,
- "software-flow", CKD_SW, 0,
- "speed-buffering", CKD_SB, 0,
- "swfc", CKD_SW, CM_INV,
- "tb", CKD_TB, CM_INV,
- "telebit", CKD_TB, 0,
- "v25bis-commands", CKD_V25, 0
-};
-int nmdmcap = (sizeof(mdmcap) / sizeof(struct keytab));
-
-#ifdef COMMENT /* SET ANSWER not implemented yet */
-static struct keytab answertab[] = {
- { "caller-id", XYA_CID, 0 };
- { "rings", XYA_RNG, 0 };
- { "", 0, 0 }
-};
-static int nanswertab = (sizeof(answertab) / sizeof(struct keytab)) - 1;
-#endif /* COMMENT */
-
-struct keytab dialtab[] = { /* SET DIAL table */
- "area-code", XYDLAC, 0, /* Also still includes items */
- "compression", XYDDC, CM_INV, /* that were moved to SET MODEM, */
- "confirmation", XYDCNF, 0, /* but they are CM_INVisible... */
- "connect", XYDCON, 0,
- "convert-directory",XYDCVT, 0,
- "country-code", XYDLCC, 0,
- "dial-command", XYDDIA, CM_INV,
- "directory", XYDDIR, 0,
- "display", XYDDPY, 0,
- "escape-character", XYDESC, CM_INV,
- "error-correction", XYDEC, CM_INV,
- "flow-control", XYDFC, CM_INV,
- "force-long-distance", XYDFLD, 0,
- "hangup", XYDHUP, 0,
- "ignore-dialtone", XYDIDT, 0,
- "interval", XYDINT, 0,
- "in", XYDINI, CM_INV|CM_ABR,
- "init-string", XYDINI, CM_INV,
- "intl-prefix", XYDIXP, 0,
- "intl-suffix", XYDIXS, 0,
-#ifndef NOXFER
- "kermit-spoof", XYDKSP, CM_INV,
-#endif /* NOXFER */
- "lc-area-codes", XYDLLAC, 0,
- "lc-prefix", XYDLCP, 0,
- "lc-suffix", XYDLCS, 0,
- "ld-prefix", XYDLDP, 0,
- "ld-suffix", XYDLDS, 0,
- "local-area-code", XYDLAC, CM_INV,
- "local-prefix", XYDLCP, CM_INV,
- "local-suffix", XYDLCS, CM_INV,
- "m", XYDMTH, CM_INV|CM_ABR,
-#ifndef NOSPL
- "macro", XYDMAC, 0, /* 195 */
-#endif /* NOSPL */
-#ifdef MDMHUP
- "me", XYDMTH, CM_INV|CM_ABR,
-#endif /* MDMHUP */
- "method", XYDMTH, 0,
- "mnp-enable", XYDMNP, CM_INV, /* obsolete but still accepted */
-#ifdef MDMHUP
- "modem-hangup", XYDMHU, CM_INV,
-#endif /* MDMHUP */
- "pacing", XYDPAC, 0,
- "pbx-exchange", XYDPXX, 0,
- "pbx-inside-prefix",XYDPXI, 0,
- "pbx-outside-prefix",XYDPXO, 0,
- "prefix", XYDNPR, 0,
- "pulse-countries", XYDPUCC, 0,
- "restrict", XYDRSTR, 0,
- "retries", XYDRTM, 0,
- "sort", XYDSRT, 0,
- "speed-matching", XYDSPD, CM_INV,
- "string", XYDSTR, CM_INV,
- "suffix", XYDSFX, 0,
- "test", XYDTEST, 0,
- "timeout", XYDTMO, 0,
- "tf-area-code", XYDTFC, CM_INV,
- "tf-prefix", XYDTFP, CM_INV,
- "toll-free-area-code",XYDTFC,0,
- "toll-free-prefix", XYDTFP, 0,
- "tone-countries", XYDTOCC, 0
-};
-int ndial = (sizeof(dialtab) / sizeof(struct keytab));
-
-#ifdef MDMHUP
-struct keytab mdmhang[] = {
- "dtr", 0, 0,
- "modem-command", 1, 0,
- "rs232-signal", 0, 0,
- "v24-signal", 0, CM_INV
-};
-#endif /* MDMHUP */
-
-static struct keytab mdmcmd[] = {
- "autoanswer", XYDS_AN, 0, /* autoanswer */
- "compression", XYDS_DC, 0, /* data compression */
- "dial-mode-prompt", XYDS_MP, 0, /* dial mode prompt */
- "dial-mode-string", XYDS_MS, 0, /* dial mode string */
- "error-correction", XYDS_EC, 0, /* error correction */
- "hangup-command", XYDS_HU, 0, /* hangup command */
- "hardware-flow", XYDS_HW, 0, /* hwfc */
- "ignore-dialtone", XYDS_ID, 0, /* ignore dialtone */
- "init-string", XYDS_IN, 0, /* init string */
- "no-flow-control", XYDS_NF, 0, /* no flow control */
- "predial-init", XYDS_I2, 0, /* last-minute setup commands */
- "pulse", XYDS_DP, 0, /* pulse */
- "software-flow", XYDS_SW, 0, /* swfc */
- "speaker", XYDS_SP, 0, /* Speaker */
- "tone", XYDS_DT, 0, /* tone */
- "volume", XYDS_VO, 0 /* Volume */
-};
-static int nmdmcmd = (sizeof(mdmcmd) / sizeof(struct keytab));
-
-struct keytab dial_fc[] = {
- "auto", FLO_AUTO, 0,
- "none", FLO_NONE, 0,
- "rts/cts", FLO_RTSC, 0,
- "xon/xoff", FLO_XONX, 0
-};
-
-struct keytab dial_m[] = { /* DIAL METHOD */
- "auto", XYDM_A, 0,
- "default", XYDM_D, 0,
- "pulse", XYDM_P, 0,
- "tone", XYDM_T, 0
-};
-int ndial_m = (sizeof(dial_m)/sizeof(struct keytab));
-#endif /* NODIAL */
-
-#ifdef CK_TAPI
-struct keytab tapitab[] = { /* Top-Level Microsoft TAPI */
- "configure-line", XYTAPI_CFG, 0,
- "dialing-properties", XYTAPI_DIAL, 0
-};
-int ntapitab = (sizeof(tapitab)/sizeof(struct keytab));
-
-struct keytab settapitab[] = { /* SET Microsoft TAPI */
- "inactivity-timeout", XYTAPI_INA, 0,
- "line", XYTAPI_LIN, 0,
- "location", XYTAPI_LOC, 0,
- "manual-dialing", XYTAPI_MAN, 0,
- "modem-dialing", XYTAPI_PASS, 0,
- "modem-lights", XYTAPI_LGHT, 0,
- "phone-number-conversions", XYTAPI_CON, 0,
- "port", XYTAPI_LIN, CM_INV,
- "post-dial-terminal", XYTAPI_PST, 0,
- "pre-dial-terminal", XYTAPI_PRE, 0,
- "use-windows-configuration", XYTAPI_USE, 0,
- "wait-for-credit-card-tone", XYTAPI_BNG, 0
-};
-int nsettapitab = (sizeof(settapitab)/sizeof(struct keytab));
-
-struct keytab * tapiloctab = NULL; /* Microsoft TAPI Locations */
-int ntapiloc = 0;
-extern struct keytab * tapilinetab; /* Microsoft TAPI Line Devices */
-extern int ntapiline;
-extern int tttapi; /* TAPI in use */
-extern int tapipass; /* TAPI Passthrough mode */
-extern int tapiconv; /* TAPI Conversion mode */
-extern int tapilights;
-extern int tapipreterm;
-extern int tapipostterm;
-extern int tapimanual;
-extern int tapiinactivity;
-extern int tapibong;
-extern int tapiusecfg;
-#endif /* CK_TAPI */
-
-#ifndef NOPUSH
-extern int nopush;
-extern int wildena;
-#ifdef UNIX
-struct keytab wildtab[] = { /* SET WILDCARD-EXPANSION */
-#ifdef UNIX
- "kermit", WILD_KER, 0, /* By Kermit */
-#endif /* UNIX */
- "off", WILD_OFF, 0, /* Disabled */
- "on", WILD_ON, 0, /* Enabled */
-#ifdef UNIX
- "shell", WILD_SHE, 0, /* By Shell */
-#endif /* UNIX */
- "", 0, 0
-};
-int nwild = (sizeof(wildtab) / sizeof(struct keytab)) - 1;
-
-struct keytab wdottab[] = { /* cont'd */
- "/match-dot-files", 1, 0,
- "/no-match-dot-files", 0, 0
-};
-extern int wildxpand;
-#endif /* UNIX */
-#endif /* NOPUSH */
-
-#ifdef NETCONN
-extern struct keytab netcmd[], netkey[];
-extern int nnets, nnetkey;
-#ifdef TCPSOCKET
-extern struct keytab tcpopt[];
-extern int ntcpopt;
-#endif /* TCPSOCKET */
-#ifdef NPIPE
-char pipename[PIPENAML+1] = { NUL, NUL };
-#endif /* NPIPE */
-#ifdef CK_NETBIOS
-extern unsigned char NetBiosName[];
-#endif /* CK_NETBIOS */
-#endif /* NETCONN */
-
-#ifdef ANYX25
-struct keytab x25tab[] = {
- "call-user-data", XYUDAT, 0,
- "closed-user-group", XYCLOS, 0,
- "reverse-charge", XYREVC, 0
-};
-int nx25 = (sizeof(x25tab) / sizeof(struct keytab));
-
-#ifndef IBMX25
-struct keytab padx3tab[] = {
- "break-action", PAD_BREAK_ACTION, 0,
- "break-character", PAD_BREAK_CHARACTER, 0,
- "character-delete", PAD_CHAR_DELETE_CHAR, 0,
- "cr-padding", PAD_PADDING_AFTER_CR, 0,
- "discard-output", PAD_SUPPRESSION_OF_DATA, 0,
- "echo", PAD_ECHO, 0,
- "editing", PAD_EDITING, 0,
- "escape", PAD_ESCAPE, 0,
- "forward", PAD_DATA_FORWARD_CHAR, 0,
- "lf-padding", PAD_PADDING_AFTER_LF, 0,
- "lf-insert", PAD_LF_AFTER_CR, 0,
- "line-delete", PAD_BUFFER_DELETE_CHAR, 0,
- "line-display", PAD_BUFFER_DISPLAY_CHAR, 0,
- "line-fold", PAD_LINE_FOLDING, 0,
- "pad-flow-control", PAD_FLOW_CONTROL_BY_PAD, 0,
- "service-signals", PAD_SUPPRESSION_OF_SIGNALS, 0,
- "timeout", PAD_DATA_FORWARD_TIMEOUT, 0,
-/* Speed is read-only */
- "transmission-rate", PAD_LINE_SPEED, 0,
- "user-flow-control", PAD_FLOW_CONTROL_BY_USER, 0
-};
-int npadx3 = (sizeof(padx3tab) / sizeof(struct keytab));
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifdef TLOG
-static struct keytab vbtab[] = {
- "brief", 0, 0,
-#ifdef OS2ORUNIX
- "ftp", 2, 0,
-#else
-#ifdef VMS
- "ftp", 2, 0,
-#endif /* def VMS */
-#endif /* OS2ORUNIX */
- "verbose", 1, 0
-};
-int nvb = (sizeof(vbtab) / sizeof(struct keytab));
-#endif /* TLOG */
-
-#ifdef CKSYSLOG
-static struct keytab syslogtab[] = {
- "all", SYSLG_CX, 0,
- "commands", SYSLG_CM, 0,
- "connection", SYSLG_AC, 0,
- "debug", SYSLG_DB, 0,
- "dial", SYSLG_DI, 0,
- "file-access", SYSLG_FA, 0,
- "file-create", SYSLG_FC, 0,
- "login", SYSLG_LI, 0,
- "none", SYSLG_NO, 0,
- "protocol", SYSLG_PR, 0
-};
-int nsyslog = (sizeof(syslogtab) / sizeof(struct keytab));
-#endif /* CKSYSLOG */
-
-/* Parity keyword table */
-
-struct keytab partbl[] = {
- "even", 'e', 0,
-#ifdef HWPARITY
- "hardware",'H', 0,
-#endif /* HWPARITY */
- "mark", 'm', 0,
- "none", 0 , 0,
- "odd", 'o', 0,
- "space", 's', 0
-};
-int npar = (sizeof(partbl) / sizeof(struct keytab));
-
-#ifdef HWPARITY
-struct keytab hwpartbl[] = {
-/* Add mark and space if needed and possible */
- "even", 'e', 0,
-#ifdef OS2
- "mark", 'm', 0,
-#endif /* OS2 */
- "odd", 'o', 0,
-#ifdef OS2
- "space", 's', 0,
-#endif /* OS2 */
- "", 0, 0
-};
-int nhwpar = (sizeof(hwpartbl) / sizeof(struct keytab)) - 1;
-#endif /* HWPARITY */
-
-/* On/Off table */
-
-struct keytab onoff[] = {
- "off", 0, 0,
- "on", 1, 0
-};
-
-#define XYCD_M 0 /* CD MESSAGE */
-#define XYCD_P 1 /* CD PATH */
-#define XYCD_H 2 /* CD HOME */
-
-struct keytab cdtab[] = {
- "home", XYCD_H, 0,
- "message", XYCD_M, 0,
- "path", XYCD_P, 0
-};
-int ncdtab = (sizeof(cdtab) / sizeof(struct keytab));
-
-struct keytab cdmsg[] = {
- "file", 2, 0,
- "off", 0, 0,
- "on", 1, 0
-};
-int ncdmsg = (sizeof(cdmsg) / sizeof(struct keytab));
-
-static
-struct keytab xittab[] = { /* SET EXIT */
- "hangup", 3, 0, /* ...HANGUP */
- "on-disconnect", 2, 0, /* ...ON-DISCONNECT */
- "status", 0, 0, /* ...STATUS */
- "warning", 1, 0 /* ...WARNING */
-};
-int nexit = (sizeof(xittab) / sizeof(struct keytab));
-
-struct keytab xitwtab[] = { /* SET EXIT WARNING */
- "always", 2, 0, /* even when not connected */
- "off", 0, 0, /* no warning */
- "on", 1, 0 /* when connected */
-};
-int nexitw = (sizeof(xitwtab) / sizeof(struct keytab));
-
-struct keytab rltab[] = {
- "local", 1, 0, /* ECHO values */
- "off", 0, CM_INV,
- "on", 1, CM_INV,
- "remote", 0, 0
-};
-int nrlt = (sizeof(rltab) / sizeof(struct keytab));
-
-/* Incomplete File Disposition table */
-
-struct keytab ifdtab[] = {
- "discard", SET_OFF, 0,
- "keep", SET_ON, 0
-};
-
-struct keytab ifdatab[] = {
- "auto", SET_AUTO, 0,
- "discard", SET_OFF, 0,
- "keep", SET_ON, 0
-};
-
-char * ifdnam[] = { "discard", "keep", "auto" };
-
-/* SET TAKE parameters table */
-static
-struct keytab taktab[] = {
- "echo", 0, 0,
- "error", 1, 0,
- "off", 2, CM_INV, /* For compatibility */
- "on", 3, CM_INV /* with MS-DOS Kermit... */
-};
-
-#ifndef NOSPL
-#ifdef COMMENT
-/* not used */
-static
-struct keytab suftab[] = { /* (what to do with) STARTUP-FILE */
- "delete", 1, 0,
- "keep", 0, 0
-};
-#endif /* COMMENT */
-
-/* SET MACRO parameters table */
-static
-struct keytab smactab[] = {
- "echo", 0, 0,
- "error", 1, 0
-};
-#endif /* NOSPL */
-
-#ifndef NOSCRIPT
-static
-struct keytab scrtab[] = {
- "echo", 0, 0
-};
-#endif /* NOSCRIPT */
-
-/* SET COMMAND table */
-
-/* SET COMMAND items... */
-
-#define SCMD_BSZ 0 /* BYTESIZE */
-#define SCMD_RCL 1 /* RECALL */
-#define SCMD_RTR 2 /* RETRY */
-#define SCMD_QUO 3 /* QUOTING */
-#define SCMD_COL 4 /* COLOR */
-#define SCMD_HIG 5 /* HEIGHT */
-#define SCMD_WID 6 /* WIDTH */
-#define SCMD_CUR 7 /* CURSOR-POSITION */
-#define SCMD_SCR 8 /* SCROLLBACK */
-#define SCMD_MOR 9 /* MORE-PROMPTING */
-#define SCMD_INT 10 /* INTERRUPTION */
-#define SCMD_ADL 11 /* AUTODOWNLOAD */
-#define SCMD_STA 12 /* STATUSLINE */
-#define SCMD_DBQ 13 /* DOUBLEQUOTING */
-#define SCMD_CBR 14 /* CBREAK */
-#define SCMD_BFL 15 /* BUFFER-SIZE (not used) */
-#define SCMD_ERR 16 /* ERROR */
-#define SCMD_VAR 17 /* VARIABLE-EVALUATION */
-
-static struct keytab scmdtab[] = {
-#ifdef CK_AUTODL
- "autodownload", SCMD_ADL, 0,
-#endif /* CK_AUTODL */
-#ifdef COMMENT
-/*
- To implement this requires that we change CMDBL and ATMBL
- from compile-time symbols to runtime variables. Not a big deal,
- but not trivial either.
- */
- "buffer-size", SCMD_BFL, 0,
-#endif /* COMMENT */
- "bytesize", SCMD_BSZ, 0,
- "cbreak", SCMD_CBR, CM_INV,
-#ifdef OS2
- "color", SCMD_COL, 0,
- "cursor-position", SCMD_CUR, 0,
-#endif /* OS2 */
-#ifdef DOUBLEQUOTING
- "doublequoting", SCMD_DBQ, 0,
-#endif /* DOUBLEQUOTING */
- "error-display", SCMD_ERR, 0,
- "height", SCMD_HIG, 0,
- "interruption", SCMD_INT, 0,
- "more-prompting", SCMD_MOR, 0,
- "quoting", SCMD_QUO, 0,
-#ifdef CK_RECALL
- "recall-buffer-size", SCMD_RCL, 0,
-#endif /* CK_RECALL */
-#ifdef CK_RECALL
- "retry", SCMD_RTR, 0,
-#endif /* CK_RECALL */
-#ifdef OS2
-#ifdef ONETERMUPD
- "scrollback", SCMD_SCR, 0,
- "statusline", SCMD_STA, 0,
-#endif /* ONETERMUPD */
-#endif /* OS2 */
- "variable-evaluation", SCMD_VAR,0,
- "width", SCMD_WID, 0
-};
-static int nbytt = (sizeof(scmdtab) / sizeof(struct keytab));
-
-#ifndef NOSERVER
-/* Server parameters table */
-static struct keytab srvtab[] = {
- "cd-message", XYSERC, 0,
- "display", XYSERD, 0,
- "get-path", XYSERP, 0,
- "idle-timeout", XYSERI, 0,
- "keepalive", XYSERK, 0,
- "login", XYSERL, 0,
- "timeout", XYSERT, 0
-};
-static int nsrvt = (sizeof(srvtab) / sizeof(struct keytab));
-#endif /* NOSERVER */
-
-static struct keytab sleeptab[] = { /* SET SLEEP table */
- "cancellation", 0, 0
-};
-
-static struct keytab tstab[] = { /* SET TRANSFER/XFER table */
- "bell", XYX_BEL, 0,
-#ifdef XFRCAN
- "cancellation", XYX_CAN, 0,
-#endif /* XFRCAN */
-#ifndef NOCSETS
- "character-set", XYX_CSE, 0,
-#endif /* NOCSETS */
-#ifndef NOSPL
- "crc-calculation", XYX_CRC, 0,
-#endif /* NOSPL */
- "display", XYX_DIS, 0,
- "interruption", XYX_INT, 0,
- "locking-shift", XYX_LSH, 0,
- "message", XYX_MSG, 0,
- "mode", XYX_MOD, 0,
- "msg", XYX_MSG, CM_INV,
-#ifdef PIPESEND
- "pipes", XYX_PIP, 0,
-#endif /* PIPESEND */
-#ifdef CK_XYZ
- "protocol", XYX_PRO, 0,
-#endif /* CK_XYZ */
- "report", XYX_RPT, 0,
- "slow-start", XYX_SLO, 0,
-#ifndef NOCSETS
- "translation", XYX_XLA, 0,
-#else
- "translation", XYX_XLA, CM_INV,
-#endif /* NOCSETS */
- "xlation", XYX_XLA, CM_INV,
- "", 0, 0
-};
-static int nts = (sizeof(tstab) / sizeof(struct keytab)) - 1;
-
-static struct keytab rtstab[] = { /* REMOTE SET TRANSFER/XFER table */
-#ifndef NOCSETS
- "character-set", XYX_CSE, 0,
-#endif /* NOCSETS */
- "mode", XYX_MOD, 0
-};
-static int nrts = (sizeof(rtstab) / sizeof(struct keytab));
-
-struct keytab xfrmtab[] = { /* TRANSFER MODE table */
- "automatic", XMODE_A, 0,
- "manual", XMODE_M, 0
-};
-
-#ifdef LOCUS
-extern int locus, autolocus;
-
-static struct keytab locustab[] = {
-#ifdef KUI
- { "ask", 3, 0 }, /* Presently implemented in GUI only */
-#endif /* KUI */
- { "auto", 2, 0 },
- { "local", 1, 0 },
- { "remote", 0, 0 }
-};
-static int nlocustab = (sizeof(locustab) / sizeof(struct keytab));
-
-#endif /* LOCUS */
-
-#ifndef NOCSETS
-/* SET TRANSFER CHARACTER-SET table */
-
-extern struct keytab tcstab[];
-extern int ntcs;
-#endif /* NOCSETS */
-
-/* SET TRANSFER LOCKING-SHIFT table */
-struct keytab lstab[] = {
- "forced", 2, 0,
- "off", 0, 0,
- "on", 1, 0
-};
-int nls = (sizeof(lstab) / sizeof(struct keytab));
-
-/* SET TELNET tables */
-#ifdef TNCODE
-extern int tn_nlm, tn_b_nlm, tn_b_meu, tn_b_ume, tn_b_xfer, tn_sb_bug;
-extern int tn_no_encrypt_xfer, tn_auth_krb5_des_bug;
-extern int tn_wait_flg, tn_duplex, tn_delay_sb, tn_sfu;
-extern int sl_tn_saved;
-extern int tn_infinite;
-extern int tn_rem_echo;
-extern int tn_deb;
-extern int tn_auth_how;
-extern int tn_auth_enc;
-#ifdef CK_FORWARD_X
-extern char * tn_fwdx_xauthority;
-#endif /* CK_FORWARD_X */
-#ifdef CK_AUTHENTICATION
-static struct keytab setauth[] = {
-#ifdef CK_KERBEROS
- "k4", AUTH_KRB4, CM_INV,
- "k5", AUTH_KRB5, CM_INV,
- "kerberos4", AUTH_KRB4, 0,
- "kerberos5", AUTH_KRB5, 0,
- "kerberos_iv",AUTH_KRB4, CM_INV,
- "kerberos_v", AUTH_KRB5, CM_INV,
- "krb4", AUTH_KRB4, CM_INV,
- "krb5", AUTH_KRB5, CM_INV,
-#endif /* CK_KERBEROS */
-#ifdef CK_SRP
- "srp", AUTH_SRP, 0,
-#endif /* CK_SRP */
-#ifdef CK_SSL
- "ssl", AUTH_SSL, 0,
- "tls", AUTH_TLS, 0,
-#endif /* CK_SSL */
- "", 0, 0
-};
-static int nsetauth = sizeof(setauth)/sizeof(struct keytab) - 1;
-#ifdef CK_KERBEROS
-extern char * krb5_d_principal; /* Default principal */
-extern char * krb5_d_instance;
-extern char * krb5_d_realm; /* Default realm */
-extern char * krb5_d_cc; /* Default credentials cache */
-extern char * krb5_d_srv; /* Default service name */
-extern int krb5_d_lifetime; /* Default lifetime */
-extern int krb5_d_forwardable;
-extern int krb5_d_proxiable;
-extern int krb5_d_renewable;
-extern int krb5_autoget;
-extern int krb5_autodel;
-extern int krb5_d_getk4;
-extern int krb5_checkaddrs; /* Check TGT Addrs */
-extern int krb5_d_no_addresses;
-extern char * krb5_d_addrs[];
-extern char * k5_keytab; /* Keytab file */
-
-extern struct krb4_init_data krb4_init;
-extern char * krb4_d_principal; /* Default principal */
-extern char * krb4_d_realm; /* Default realm */
-extern char * krb4_d_srv; /* Default service name */
-extern int krb4_d_lifetime; /* Default lifetime */
-extern int krb4_d_preauth;
-extern char * krb4_d_instance;
-extern int krb4_autoget;
-extern int krb4_autodel;
-extern int krb4_checkaddrs; /* Check TGT Addrs */
-extern char * k4_keytab; /* Keytab file */
-#ifdef KRB4
-extern int k4debug;
-#endif /* KRB4 */
-static struct keytab krbver[] = {
- "4", 4, 0,
- "5", 5, 0,
- "iv", 4, CM_INV,
- "v", 5, CM_INV
-};
-static int nkrbver = sizeof(krbver)/sizeof(struct keytab);
-
-static struct keytab kdestab[] = {
- "never", KRB_DEL_NO, 0,
- "no", KRB_DEL_NO, CM_INV,
- "on-close", KRB_DEL_CL, 0,
- "on-exit", KRB_DEL_EX, 0
-};
-static int nkdestab = sizeof(kdestab)/sizeof(struct keytab);
-
-static struct keytab k4tab[] = {
- "autodel", XYKRBDEL, CM_INV,
- "autodestroy", XYKRBDEL, 0,
- "autoget", XYKRBGET, 0,
- "check-address", XYKRBADR, 0,
- "debug", XYKRBDBG, CM_INV,
- "instance", XYKRBINS, 0,
- "keytab", XYKRBKTB, 0,
- "lifetime", XYKRBLIF, 0,
- "preauth", XYKRBPRE, 0,
- "principal", XYKRBPR, 0,
- "prompt", XYKRBPRM, 0,
- "realm", XYKRBRL, 0,
- "service-name", XYKRBSRV, 0
-};
-static int nk4tab = sizeof(k4tab)/sizeof(struct keytab);
-
-static struct keytab k5tab[] = {
- "addresses", XYKRBADD, 0,
- "autodelete", XYKRBDEL, CM_INV,
- "autodestroy", XYKRBDEL, 0,
- "autoget", XYKRBGET, 0,
- "cc", XYKRBCC, CM_INV,
- "check-address", XYKRBADR, 0,
- "credentials-cache", XYKRBCC, 0,
- "forwardable", XYKRBFWD, 0,
- "get-k4-tgt", XYKRBK5K4,0,
- "instance", XYKRBINS, 0,
- "keytab", XYKRBKTB, 0,
- "lifetime", XYKRBLIF, 0,
- "no-addresses", XYKRBNAD, 0,
- "principal", XYKRBPR, 0,
- "prompt", XYKRBPRM, 0,
- "proxiable", XYKRBPRX, 0,
- "realm", XYKRBRL, 0,
- "renewable", XYKRBRNW, 0,
- "service-name", XYKRBSRV, 0
-};
-static int nk5tab = sizeof(k5tab)/sizeof(struct keytab);
-
-#define KRB_PW_PRM 1
-#define KRB_PR_PRM 2
-
-static struct keytab krbprmtab[] = {
- "password", KRB_PW_PRM, 0,
- "principal", KRB_PR_PRM, 0
-};
-
-#endif /* CK_KERBEROS */
-#ifdef CK_SRP
-static struct keytab srptab[] = {
- "prompt", XYSRPPRM, 0
-};
-static int nsrptab = sizeof(srptab)/sizeof(struct keytab);
-#define SRP_PW_PRM 1
-
-static struct keytab srpprmtab[] = {
- "password", SRP_PW_PRM, 0
-};
-#endif /* CK_SRP */
-#ifdef CK_SSL
-static struct keytab ssltab[] = {
- "certs-ok", XYSSLCOK, CM_INV,
- "cipher-list", XYSSLCL, 0,
- "crl-dir", XYSSLCRLD, 0,
- "crl-file", XYSSLCRL, 0,
- "debug", XYSSLDBG, 0,
- "dh-key-file", XYSSLDKFL, CM_INV,
- "dh-param-file", XYSSLDPFL, 0,
- "dsa-cert-chain-file", XYSSLDCCF, 0,
- "dsa-cert-file", XYSSLDCFL, 0,
- "dsa-key-file", XYSSLDKFL, 0,
- "dummy", XYSSLDUM, CM_INV,
- "only", XYSSLON, CM_INV,
- "random-file", XYSSLRND, 0,
- "rsa-cert-chain-file", XYSSLRCCF, 0,
- "rsa-cert-file", XYSSLRCFL, 0,
- "rsa-key-file", XYSSLRKFL, 0,
- "verbose", XYSSLVRB, 0,
- "verify", XYSSLVRF, 0,
- "verify-dir", XYSSLVRFD, 0,
- "verify-file", XYSSLVRFF, 0
-};
-static int nssltab = sizeof(ssltab)/sizeof(struct keytab);
-static struct keytab sslvertab[] = {
- "fail-if-no-peer-cert", SSL_VERIFY_PEER |
- SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0,
- "no", SSL_VERIFY_NONE, 0,
- "none", SSL_VERIFY_NONE, CM_INV,
- "off", SSL_VERIFY_NONE, CM_INV,
- "on", SSL_VERIFY_PEER, CM_INV,
- "peer-cert", SSL_VERIFY_PEER, 0
-};
-static int nsslvertab = sizeof(sslvertab)/sizeof(struct keytab);
-#endif /* CK_SSL */
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
-int cx_type = CX_AUTO;
-extern int sl_cx_type;
-#endif /* CK_ENCRYPTION */
-extern char *tcp_address;
-#ifndef NOHTTP
-extern char * tcp_http_proxy;
-extern char * tcp_http_proxy_user;
-extern char * tcp_http_proxy_pwd;
-extern char * tcp_http_proxy_agent;
-#endif /* NOHTTP */
-#ifdef NT
-#ifdef CK_SOCKS
-extern char *tcp_socks_svr;
-extern char *tcp_socks_user;
-#ifdef CK_SOCKS_NS
-extern char *tcp_socks_ns;
-#endif /* CK_SOCKS_NS */
-#endif /* CK_SOCKS */
-#endif /* NT */
-
-#define UPW_USER 1
-#define UPW_PASS 2
-#define UPW_AGENT 3
-
-static struct keytab userpass[] = {
- { "/agent", UPW_AGENT, CM_ARG },
- { "/password", UPW_PASS, CM_ARG },
- { "/user", UPW_USER, CM_ARG },
-};
-static int nuserpass = sizeof(userpass)/sizeof(struct keytab);
-
-static struct keytab tnnegtab[] = { /* TELNET NEGOTIATION table */
- "accepted", TN_NG_AC, 0,
- "refused", TN_NG_RF, 0,
- "req", TN_NG_RQ, CM_INV|CM_ABR,
- "requ", TN_NG_RQ, CM_INV|CM_ABR,
- "reque", TN_NG_RQ, CM_INV|CM_ABR,
- "reques", TN_NG_RQ, CM_INV|CM_ABR,
- "request", TN_NG_RQ, CM_INV|CM_ABR,
- "requeste", TN_NG_RQ, CM_INV|CM_ABR,
- "requested", TN_NG_RQ, 0,
- "required", TN_NG_MU, 0
-};
-static int ntnnegtab = sizeof(tnnegtab)/sizeof(struct keytab);
-
-#ifdef CK_ENCRYPTION
-static struct keytab typkwd[] = {
- "/type", 0, CM_ARG
-};
-
-static struct keytab tnenctab[] = { /* TELNET ENCRYPTION table */
- "accepted", TN_NG_AC, CM_INV,
- "refused", TN_NG_RF, CM_INV,
- "req", TN_NG_RQ, CM_INV|CM_ABR,
- "requ", TN_NG_RQ, CM_INV|CM_ABR,
- "reque", TN_NG_RQ, CM_INV|CM_ABR,
- "reques", TN_NG_RQ, CM_INV|CM_ABR,
- "request", TN_NG_RQ, CM_INV|CM_ABR,
- "requeste", TN_NG_RQ, CM_INV|CM_ABR,
- "requested", TN_NG_RQ, CM_INV,
- "required", TN_NG_MU, CM_INV,
- "start", TN_EN_START, CM_INV,
- "stop", TN_EN_STOP, CM_INV,
- "type", TN_EN_TYP, 0
-};
-static int ntnenc = sizeof(tnenctab)/sizeof(struct keytab) ;
-#endif /* CK_ENCRYPTION */
-
-#ifdef CK_FORWARD_X
-static struct keytab tnfwdxtab[] = { /* TELNET FORWARD-X table */
- "no-encryption", 1, CM_INV,
- "xauthority-file", 0, 0
-};
-static int ntnfwdx = sizeof(tnfwdxtab)/sizeof(struct keytab) ;
-#endif /* CK_FORWARD_X */
-
-static struct keytab tnbugtab[] = { /* TELNET BUG table */
- "auth-krb5-des", 4, 0,
- "binary-me-means-u-too", 0, 0,
- "binary-u-means-me-too", 1, 0,
- "infinite-loop-check", 2, 0,
- "sb-implies-will-do", 3, 0
-};
-
-#ifdef CK_ENVIRONMENT
-static struct keytab tnenvtab[] = { /* TELNET ENVIRONMENT table */
- "acct", TN_ENV_ACCT, 0,
- "display", TN_ENV_DISP, 0,
- "job", TN_ENV_JOB, 0,
- "location", TN_ENV_LOC, 0,
- "off", TN_ENV_OFF, CM_INV,
- "on", TN_ENV_ON, CM_INV,
- "printer", TN_ENV_PRNT, 0,
- "systemtype",TN_ENV_SYS, 0,
- "user", TN_ENV_USR, 0,
- "uservar", TN_ENV_UVAR, 0,
- "", 0, 0
-};
-static int ntnenv = sizeof(tnenvtab)/sizeof(struct keytab) - 1;
-#endif /* CK_ENVIRONMENT */
-
-#ifdef CK_AUTHENTICATION
-static struct keytab tnauthtab[] = { /* TELNET AUTHENTICATION table */
- "accepted", TN_NG_AC, CM_INV,
- "encrypt-flag", TN_AU_ENC, 0,
- "forwarding", TN_AU_FWD, 0,
- "how-flag", TN_AU_HOW, 0,
- "refused", TN_NG_RF, CM_INV,
- "req", TN_NG_RQ, CM_INV|CM_ABR,
- "requ", TN_NG_RQ, CM_INV|CM_ABR,
- "reque", TN_NG_RQ, CM_INV|CM_ABR,
- "reques", TN_NG_RQ, CM_INV|CM_ABR,
- "request", TN_NG_RQ, CM_INV|CM_ABR,
- "requeste", TN_NG_RQ, CM_INV|CM_ABR,
- "requested", TN_NG_RQ, CM_INV,
- "required", TN_NG_MU, CM_INV,
- "type", TN_AU_TYP, 0
-};
-static int ntnauth = sizeof(tnauthtab)/sizeof(struct keytab) ;
-
-struct keytab autyptab[] = { /* TELNET AUTHENTICATION TYPE table */
- "automatic", AUTH_AUTO, 0,
-#ifdef CK_KERBEROS
- "k4", AUTH_KRB4, CM_INV,
- "k5", AUTH_KRB5, CM_INV,
- "kerberos4", AUTH_KRB4, 0,
- "kerberos5", AUTH_KRB5, 0,
- "kerberos_iv",AUTH_KRB4, CM_INV,
- "kerberos_v", AUTH_KRB5, CM_INV,
- "krb4", AUTH_KRB4, CM_INV,
- "krb5", AUTH_KRB5, CM_INV,
-#endif /* CK_KERBEROS */
- "none", AUTH_NONE, 0,
-#ifdef NT
- "ntlm", AUTH_NTLM, 0,
-#endif /* NT */
-#ifdef CK_SRP
- "srp", AUTH_SRP, 0,
-#endif /* CK_SRP */
-#ifdef CK_SSL
- "ssl", AUTH_SSL, 0,
-#endif /* CK_SSL */
- "", 0, 0
-};
-int nautyp = sizeof(autyptab)/sizeof(struct keytab) - 1;
-
-struct keytab auhowtab[] = { /* TELNET AUTHENTICATION HOW table */
- "any", TN_AUTH_HOW_ANY, 0,
- "mutual", TN_AUTH_HOW_MUTUAL, 0,
- "one-way", TN_AUTH_HOW_ONE_WAY, 0,
- "", 0, 0
-};
-int nauhow = sizeof(auhowtab)/sizeof(struct keytab) - 1;
-
-struct keytab auenctab[] = { /* TELNET AUTHENTICATION ENCRYPT table */
- "any", TN_AUTH_ENC_ANY, 0,
- "none", TN_AUTH_ENC_NONE, 0,
- "telopt", TN_AUTH_ENC_TELOPT, 0,
-#ifdef CK_SSL
- "tls", TN_AUTH_ENC_TLS, 0,
-#endif /* CK_SSL */
- "", 0, 0
-};
-int nauenc = sizeof(auenctab)/sizeof(struct keytab) - 1;
-#endif /* CK_AUTHENTICATION */
-
-#define TN_NL_BIN 3
-#define TN_NL_NVT 4
-static struct keytab tn_nlmtab[] = { /* TELNET NEWLINE-MODE table */
- "binary-mode", TN_NL_BIN, 0, /* Binary mode */
- "nvt", TN_NL_NVT, 0, /* NVT mode */
- "off", TNL_CRNUL, CM_INV, /* CR-NUL (TELNET spec) */
- "on", TNL_CRLF, CM_INV, /* CR-LF (TELNET spec) */
- "raw", TNL_CR, CM_INV /* CR only (out of spec) */
-};
-static int ntn_nlm = (sizeof(tn_nlmtab) / sizeof(struct keytab));
-
-static struct keytab tnlmtab[] = { /* TELNET NEWLINE-MODE table */
- "cr", TNL_CR, CM_INV, /* CR only (out of spec) */
- "cr-lf", TNL_CRLF, CM_INV, /* CR-LF (TELNET spec) */
- "cr-nul", TNL_CRNUL, CM_INV, /* CR-NUL (TELNET spec) */
- "lf", TNL_LF, CM_INV, /* LF instead of CR-LF */
- "off", TNL_CRNUL, 0, /* CR-NUL (TELNET spec) */
- "on", TNL_CRLF, 0, /* CR-LF (TELNET spec) */
- "raw", TNL_CR, 0 /* CR only (out of spec) */
-};
-static int ntnlm = (sizeof(tnlmtab) / sizeof(struct keytab));
-
-struct keytab tntab[] = {
-#ifdef CK_AUTHENTICATION
- "authentication", CK_TN_AU, 0,
-#endif /* CK_AUTHENTICATION */
- "b", CK_TN_BM, CM_INV|CM_ABR,
- "bi", CK_TN_BM, CM_INV|CM_ABR,
- "bin", CK_TN_BM, CM_INV|CM_ABR,
- "bina", CK_TN_BM, CM_INV|CM_ABR,
- "binar", CK_TN_BM, CM_INV|CM_ABR,
- "binary", CK_TN_BM, CM_INV|CM_ABR,
- "binary-", CK_TN_BM, CM_INV|CM_ABR,
- "binary-mode", CK_TN_BM, CM_INV,
- "binary-transfer-mode", CK_TN_XF, 0,
- "binary-xfer-mode", CK_TN_XF, CM_INV,
- "bug", CK_TN_BUG, 0,
- "debug", CK_TN_DB, 0,
- "delay-sb", CK_TN_DL, 0,
- "echo", CK_TN_EC, 0,
-#ifdef CK_ENCRYPTION
- "encryption", CK_TN_ENC, 0,
-#endif /* CK_ENCRYPTION */
-#ifdef CK_ENVIRONMENT
- "environment", CK_TN_ENV, 0,
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_FORWARD_X
- "forward-x", CK_TN_FX, 0,
-#endif /* CK_FORWARD_X */
-#ifdef IKS_OPTION
- "kermit", CK_TN_IKS, CM_INV,
-#endif /* IKS_OPTION */
-#ifdef CK_SNDLOC
- "location", CK_TN_LOC, 0,
-#endif /* CK_SNDLOC */
-#ifdef CK_NAWS
- "naws", CK_TN_NAWS, CM_INV,
-#endif /* CK_NAWS */
- "newline-mode", CK_TN_NL, 0,
- "no-encrypt-during-xfer", CK_TN_NE, CM_INV,
- "prompt-for-userid",CK_TN_PUID,0,
- "remote-echo", CK_TN_RE, 0,
-#ifdef CK_SSL
- "start-tls", CK_TN_TLS, CM_INV,
-#endif /* CK_SSL */
-#ifdef NT
- "sfu-compatibility", CK_TN_SFU, 0,
-#else
- "sfu-compatibility", CK_TN_SFU, CM_INV,
-#endif /* NT */
- "terminal-type", CK_TN_TT, 0,
- "wait-for-negotiations", CK_TN_WAIT, 0,
-#ifdef CK_ENVIRONMENT
- "xdisplay-location",CK_TN_XD, CM_INV,
-#endif /* CK_ENVIRONMENT */
- "", 0, 0
-};
-int ntn = (sizeof(tntab) / sizeof(struct keytab)) - 1;
-
-struct keytab tnopttab[] = {
-#ifdef CK_AUTHENTICATION
- "authentication", CK_TN_AU, 0,
-#else
- "authentication", CK_TN_AU, CM_INV,
-#endif /* CK_AUTHENTICATION */
- "binary-mode", CK_TN_BM, 0,
-#ifdef TN_COMPORT
- "c", CK_TN_CPC, CM_INV|CM_ABR,
- "co", CK_TN_CPC, CM_INV|CM_ABR,
- "com", CK_TN_CPC, CM_INV|CM_ABR,
- "com-port-control",CK_TN_CPC, 0,
- "comport-control", CK_TN_CPC, CM_INV,
-#else /* TN_COMPORT */
- "com-port-control",CK_TN_CPC, CM_INV,
- "comport-control", CK_TN_CPC, CM_INV,
-#endif /* TN_COMPORT */
- "echo", CK_TN_EC, 0,
-#ifdef CK_ENCRYPTION
- "encryption", CK_TN_ENC, 0,
-#else
- "encryption", CK_TN_ENC, CM_INV,
-#endif /* CK_ENCRYPTION */
-#ifdef CK_FORWARD_X
- "forward-x", CK_TN_FX, 0,
-#else /* CK_FORWARD_X */
- "forward-x", CK_TN_FX, CM_INV,
-#endif /* CK_FORWARD_X */
- "ibm-sak", CK_TN_SAK, CM_INV,
-#ifdef IKS_OPTION
- "kermit", CK_TN_IKS, 0,
-#else
- "kermit", CK_TN_IKS, CM_INV,
-#endif /* IKS_OPTION */
- "lflow", CK_TN_FLW, CM_INV,
- "logout", CK_TN_LOG, 0,
-#ifdef CK_NAWS
- "naws", CK_TN_NAWS, 0,
-#else
- "naws", CK_TN_NAWS, CM_INV,
-#endif /* CK_NAWS */
-#ifdef CK_ENVIRONMENT
- "new-environment", CK_TN_ENV, 0,
-#else
- "new-environment", CK_TN_ENV, CM_INV,
-#endif /* CK_ENVIRONMENT */
- "pragma-heartbeat",CK_TN_PHR, CM_INV,
- "pragma-logon", CK_TN_PLG, CM_INV,
- "pragma-sspi", CK_TN_PSP, CM_INV,
- "sak", CK_TN_SAK, CM_INV,
-#ifdef CK_SNDLOC
- "send-location", CK_TN_LOC, 0,
-#else
- "send-location", CK_TN_LOC, CM_INV,
-#endif /* CK_SNDLOC */
- "sga", CK_TN_SGA, CM_INV|CM_ABR,
-#ifdef CK_SSL
- "start-tls", CK_TN_TLS, 0,
-#else
- "start-tls", CK_TN_TLS, CM_INV,
-#endif /* CK_SSL */
- "suppress-go-aheads", CK_TN_SGA, 0,
- "terminal-type", CK_TN_TT, 0,
- "ttype", CK_TN_TT, CM_INV|CM_ABR,
-#ifdef CK_ENVIRONMENT
- "xdisplay-location", CK_TN_XD, 0,
-#else
- "xdisplay-location", CK_TN_XD, CM_INV,
-#endif /* CK_ENVIRONMENT */
- "", 0, 0
-};
-int ntnopt = (sizeof(tnopttab) / sizeof(struct keytab)) - 1;
-
-struct keytab tnoptsw[] = {
- "/client", CK_TN_CLIENT, 0,
- "/server", CK_TN_SERVER, 0
-};
-int ntnoptsw = (sizeof(tnoptsw) / sizeof(struct keytab));
-#endif /* TNCODE */
-
-struct keytab ftrtab[] = { /* Feature table */
-#ifndef NOCSETS /* 0 = we have it, 1 = we don't */
-"character-sets", 0, 0,
-#else
-"character-sets", 1, 0,
-#endif /* NOCSETS */
-#ifndef NOCYRIL
-"cyrillic", 0, 0,
-#else
-"cyrillic", 1, 0,
-#endif /* NOCYRIL */
-
-#ifndef NOLOGDIAL
-"cx-log", 0, 0,
-#else
-"cx-log", 1, 0,
-#endif /* NOLOGDIAL */
-
-#ifndef NODEBUG
-"debug", 0, 0,
-#else
-"debug", 1, 0,
-#endif /* NODEBUG */
-
-#ifndef NODIAL
-"dial", 0, 0,
-#else
-"dial", 1, 0,
-#endif /* NODIAL */
-
-#ifdef DYNAMIC
-"dynamic-memory", 0, 0,
-#else
-"dynamic-memory", 1, 0,
-#endif /* DYNAMIC */
-
-#ifndef NOXFER
-"file-transfer", 0, 0,
-#else
-"file-transfer", 1, 0,
-#endif /* NOXFER */
-
-#ifdef XXFWD
-"forward", 0, 0,
-#else
-"forward", 1, 0,
-#endif /* XXFWD */
-
-#ifdef NEWFTP
-"ftp", 0, 0,
-#else
-"ftp", 1, 0,
-#endif /* NEWFTP */
-
-#ifdef CK_CURSES
-"fullscreen-display", 0, 0,
-#else
-"fullscreen-display", 1, 0,
-#endif /* CK_CURSES */
-#ifdef GREEK
-"greek", 0, 0,
-#else
-"greek", 1, 0,
-#endif /* GREEK */
-#ifdef HEBREW
-"hebrew", 0, 0,
-#else
-"hebrew", 1, 0,
-#endif /* HEBREW */
-#ifndef NOHELP
-"help", 0, 0,
-#else
-"help", 1, 0,
-#endif /* NOHELP */
-
-#ifndef NOIKSD
-"iksd", 0, 0,
-#else
-"iksd", 1, 0,
-#endif /* NOIKSD */
-
-#ifndef NOSPL
-"if-command", 0, 0,
-#else
-"if-command", 1, 0,
-#endif /* NOSPL */
-#ifndef NOJC
-#ifdef UNIX
-"job-control", 0, 0,
-#else
-"job-control", 1, 0,
-#endif /* UNIX */
-#else
-"job-control", 1, 0,
-#endif /* NOJC */
-#ifdef KANJI
-"kanji", 0, 0,
-#else
-"kanji", 1, 0,
-#endif /* KANJI */
-
-#ifndef NOXFER
-"kermit", 0, 0,
-#else
-"kermit", 1, 0,
-#endif /* NOXFER */
-
-#ifdef CK_KERBEROS
-"kerberos", 0, 0,
-#else
-"kerberos", 1, 0,
-#endif /* CK_KERBEROS */
-
-#ifndef NOCSETS
-"latin1", 0, 0,
-#else
-"latin1", 1, 0,
-#endif /* NOCSETS */
-#ifdef LATIN2
-"latin2", 0, 0,
-#else
-"latin2", 1, 0,
-#endif /* LATIN2 */
-
-#ifdef CKLEARN
-"learned-scripts", 0, 0,
-#else
-"learned-scripts", 1, 0,
-#endif /* CKLEARN */
-
-#ifndef NOLOCAL
-"making-connections", 0, 0,
-#else
-"making-connections", 1, 0,
-#endif /* NOLOCAL */
-
-#ifdef NETCONN
-"network", 0, 0,
-#else
-"network", 1, 0,
-#endif /* NETCONN */
-
-#ifdef NT
-#ifdef CK_AUTHENTICATION
-"ntlm", 1, 0,
-#else /* CK_AUTHENTICATION */
-"ntlm", 0, 0,
-#endif /* CK_AUTHENTICATION */
-#else /* NT */
-"ntlm", 0, 0,
-#endif /* NT */
-
-#ifdef PIPESEND
-"pipes", 0, 0,
-#else
-#ifdef NETCMD
-"pipes", 0, 0,
-#endif /* NETCMD */
-#endif /* PIPESEND */
-#ifndef PIPESEND
-#ifndef NETCMD
-"pipes", 1, 0,
-#endif /* PIPESEND */
-#endif /* NETCMD */
-
-#ifdef NETPTY
-"pty", 0, 0,
-#else
-"pty", 1, 0,
-#endif /* NETPTY */
-
-#ifndef NOPUSH
-"push", 0, 0,
-#else
-"push", 1, 0,
-#endif /* PUSH */
-
-#ifdef CK_REDIR
-"redirect", 0, 0,
-#else
-"redirect", 1, 0,
-#endif /* CK_REDIR */
-
-#ifdef CK_RTSCTS
-"rts/cts", 0, 0,
-#else
-"rts/cts", 1, 0,
-#endif /* RTS/CTS */
-
-#ifndef NOSCRIPT
-"script-command", 0, 0,
-#else
-"script-command", 1, 0,
-#endif /* NOSCRIPT */
-#ifndef NOSERVER
-"server-mode", 0, 0,
-#else
-"server-mode", 1, 0,
-#endif /* NOSERVER */
-
-#ifndef NOSEXP
-"sexpression", 0, 0,
-#else
-"sexpression", 1, 0,
-#endif /* NOSEXP */
-
-#ifdef SFTP_BUILTIN
-"sftp", 1, 0,
-#else
-"sftp", 0, 0,
-#endif /* SFTP_BUILTIN */
-
-#ifndef NOSHOW
-"show-command", 0, 0,
-#else
-"show-command", 1, 0,
-#endif /* NOSHOW */
-
-#ifdef CK_SRP
-"srp", 0, 0,
-#else
-"srp", 1, 0,
-#endif /* CK_SRP */
-
-#ifdef SSHBUILTIN
-"ssh", 0, 0,
-#else /* SSHBUILTIN */
-"ssh", 1, 0,
-#endif /* SSHBUILTIN */
-
-#ifdef CK_SSL
-"ssl/tls", 0, 0,
-#else
-"ssl/tls", 1, 0,
-#endif /* CK_SSL */
-
-#ifndef NOXMIT
-"transmit", 0, 0,
-#else
-"transmit", 1, 0,
-#endif /* NOXMIT */
-
-#ifdef UNICODE
-"unicode", 0, 0,
-#else
-"unicode", 1, 0,
-#endif /* UNICODE */
-
-#ifdef CK_XYZ
-"xyzmodem", 0, 0,
-#else
-"xyzmodem", 1, 0,
-#endif /* CK_XYZ */
-
-"", 0, 0
-};
-int nftr = (sizeof(ftrtab) / sizeof(struct keytab)) - 1;
-
-struct keytab desttab[] = { /* SET DESTINATION */
-#ifdef CALIBRATE
- "calibrate", DEST_N, CM_INV,
-#endif /* CALIBRATE */
- "disk", DEST_D, 0,
-#ifdef CALIBRATE
- "nowhere", DEST_N, 0,
-#endif /* CALIBRATE */
- "printer", DEST_P, 0,
- "screen", DEST_S, 0
-};
-int ndests = (sizeof(desttab) / sizeof(struct keytab));
-
-#ifndef NOSPL /* Used only with script programming items... */
-
-#ifndef NOSERVER /* This is just to avoid some */
-#define CK_PARSDIR /* "statement not reached" */
-#else /* complaints... */
-#ifndef NODIAL
-#define CK_PARSDIR
-#endif /* NODIAL */
-#endif /* NOSERVER */
-
-/*
- cx == 0 means dial directory
- cx == 1 means network directory
- cx == 2 means a directory path list
-*/
-static int
-parsdir(cx) int cx; {
- int i, x, y, dd; /* Workers */
- int nxdir;
- char *s;
- char ** xdir;
- char *pp[MAXGETPATH]; /* Temporary name pointers */
-#ifdef ZFNQFP
- struct zfnfp * fnp;
-#ifdef OS2
- char * env;
- char dirpath[4096];
-#else /* OS2 */
- char dirpath[1024]; /* For fully qualified filenames */
-#endif /* OS2 */
-#endif /* ZFNQFP */
-
- int max = 0; /* Maximum number of things to parse */
- char c;
-
-#ifndef NODIAL
- if (cx == 0) { /* Dialing */
- nxdir = ndialdir;
- xdir = dialdir;
- max = MAXDDIR;
- } else
-#ifdef NETCONN
- if (cx == 1) { /* Network */
- nxdir = nnetdir;
- xdir = netdir;
- max = MAXDDIR;
- } else
-#endif /* NETCONN */
-#endif /* NODIAL */
-#ifndef NOSERVER
- if (cx == 2) { /* GET path */
- nxdir = ngetpath;
- xdir = getpath;
- max = MAXGETPATH;
- } else /* Called with invalid function code */
-#endif /* NOSERVER */
- return(-2);
-
- for (i = 0; i < MAXGETPATH; i++) /* Init these. */
- pp[i] = NULL;
-
-#ifdef CK_PARSDIR
- dd = 0; /* Temporary name counter */
- while (1) {
- if (cx != 2) { /* Dialing or Network Directory */
-#ifdef OS2
- int len;
- char * appdata0 = NULL, * appdata1 = NULL;
-#ifdef NT
- env = getenv("K95PHONES");
- makestr(&appdata0,(char *)GetAppData(0));
- makestr(&appdata1,(char *)GetAppData(1));
-#else /* NT */
- env = getenv("K2PHONES");
-#endif /* NT */
- if (!env)
- env = getenv("K95PHONES");
- if (!env)
- env = "";
-
- dirpath[0] = '\0';
- len = strlen(env) + 2*strlen(startupdir) + 2*strlen(inidir)
- + (appdata0?2*strlen(appdata0):0)
- + (appdata1?2*strlen(appdata1):0)
- + 2*strlen(zhome()) + 2*strlen(exedir) + 8*strlen("PHONES/")
- + 12;
- if (len < 4096) /* SAFE */
- sprintf(dirpath,
- "%s%s%s;%s%s;%s%s%s%s%s%s%s%s%s;%s%s;%s;%s%s",
- /* Semicolon-separated path list */
- env,
- (env[0] && env[strlen(env)-1] == ';') ? "" : ";",
- startupdir,
- startupdir, "PHONES/",
- appdata1 ? appdata1 : "",
- appdata1 ? "Kermit 95;" : "",
- appdata1 ? appdata1 : "",
- appdata1 ? "Kermit 95/PHONES/;" : "",
- appdata0 ? appdata0 : "",
- appdata0 ? "Kermit 95;" : "",
- appdata0 ? appdata0 : "",
- appdata0 ? "Kermit 95/PHONES/;" : "",
- inidir,
- inidir, "PHONES/",
- zhome(),
- zhome(), "PHONES/",
- exedir,
- exedir, "PHONES/"
- );
-#ifdef NT
- makestr(&appdata0,NULL);
- makestr(&appdata1,NULL);
-#endif /* NT */
-#else
-#ifdef UNIX
- y = 1024;
- s = dirpath;
- zzstring("\\v(home)",&s,&y);
-#endif /* UNIX */
-#endif /* OS2 */
- y = cmifip(
- "Names of one or more directory files, separated by spaces",
- "",&s,&x,0,
-#ifdef OS2ORUNIX
- dirpath,
-#else
- NULL,
-#endif /* OS2ORUNIX */
- xxstring
- );
- } else { /* List of directory names */
- x = 0;
- y = cmdir("Directory name","",&s,xxstring);
- }
- if (y < 0) {
- if (y == -3) { /* EOL or user typed <CR> */
- if ((y = cmcfm()) < 0) return(y);
- for (i = 0; i < max; i++) { /* Clear these */
- if (i < nxdir && xdir[i]) {
- free(xdir[i]);
- }
- xdir[i] = (i < dd) ? pp[i] : NULL;
- }
-#ifndef NODIAL
- if (cx == 0)
- ndialdir = dd;
-#ifdef NETCONN
- if (cx == 1)
- nnetdir = dd;
-#endif /* NETCONN */
-#endif /* NODIAL */
-#ifndef NOSERVER
- if (cx == 2)
- ngetpath = dd;
-#endif /* NOSERVER */
- return(success = 1);
-
- } else { /* Parse error */
- for (i = 0; i < dd; i++) { /* Free temp storage */
- if (pp[i]) free(pp[i]); /* but don't change */
- pp[i] = NULL; /* anything else */
- }
- return(y);
- }
- }
- if (x) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
-#ifdef CK_TMPDIR
- if (cx == 2 && !isdir(s)) {
- printf("?Not a directory - %s\n", s);
- return(-9);
- }
-#endif /* CK_TMPDIR */
-
-#ifdef ZFNQFP
- if (cx < 2) {
- if (!isabsolute(s)) { /* If not relative get full path */
- if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {
- if (fnp->fpath)
- if ((int) strlen(fnp->fpath) > 0)
- s = fnp->fpath;
- }
- }
- }
-#endif /* ZFNQFP */
- c = NUL;
- x = strlen(s);
- if (x > 0) /* Get last char */
- c = s[x-1];
- debug(F000,"parsdir s",s,c);
- if ((pp[dd] = malloc(strlen(s)+2)) == NULL) {
- printf("?Internal error - malloc\n");
- for (i = 0; i < dd; i++) { /* Free temp storage */
- if (pp[i]) free(pp[i]);
- pp[i] = NULL;
- }
- return(-9);
- } else { /* Have storage for name */
- strcpy(pp[dd],s); /* Copy string into new storage */
- debug(F111,"parsdir pp[dd] 1",pp[dd],dd);
-#ifndef NOXFER
- if (cx == 2) { /* If we are parsing directories */
- char dirsep[2];
- extern int myindex; /* Append directory separator if */
- extern struct sysdata sysidlist[]; /* it is missing... */
- debug(F101,"parsdir myindex","",myindex);
- if (myindex > -1)
- if (sysidlist[myindex].sid_unixlike)
- if (c != sysidlist[myindex].sid_dirsep) {
- dirsep[0] = sysidlist[myindex].sid_dirsep;
- dirsep[1] = NUL;
- strcat(pp[dd], (char *) dirsep); /* safe */
- }
- }
-#endif /* NOXFER */
- debug(F111,"parsdir pp[dd] 2",pp[dd],dd);
- if (++dd > max) {
- printf("?Too many directories - %d max\n", max);
- for (i = 0; i < dd; i++) { /* Free temp storage */
- if (pp[i]) free(pp[i]);
- pp[i] = NULL;
- }
- }
- }
- }
-#endif /* CK_PARSDIR */
-}
-#endif /* NOSPL */
-
-#ifndef NOSERVER
-static int
-cklogin() {
- int x;
- char * s;
- char username[LOGINLEN+1];
- char password[LOGINLEN+1];
- char account[LOGINLEN+1];
- extern char * x_user, * x_passwd, * x_acct;
- extern int x_login, x_logged;
-
- username[0] = NUL;
- password[0] = NUL;
- account[0] = NUL;
-
- x = cmfld("username", "", &s, xxstring);
- if (x != -3) {
- if (x < 0)
- return(x);
- if ((int)strlen(s) > LOGINLEN) {
- printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
- return(-9);
- }
- ckstrncpy(username,s,LOGINLEN+1);
- x = cmfld("password", "", &s, xxstring);
- if (x != -3) {
- if (x < 0)
- return(x);
- if ((int)strlen(s) > LOGINLEN) {
- printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
- return(-9);
- }
- ckstrncpy(password,s,LOGINLEN+1);
- x = cmfld("account", "", &s, xxstring);
- if (x != -3) {
- if (x < 0)
- return(x);
- if ((int)strlen(s) > LOGINLEN) {
- printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
- return(-9);
- }
- ckstrncpy(account,s,LOGINLEN+1);
- if ((x = cmcfm()) < 0)
- return(x);
- }
- }
- }
- makestr(&x_user,username);
- makestr(&x_passwd,password);
- makestr(&x_acct,account);
- x_login = (x_user) ? 1 : 0;
- x_logged = 0;
- return(1);
-}
-#endif /* NOSERVER */
-
-#ifndef NOLOCAL
-static int
-setdcd() {
- int x, y, z = 0;
- if ((y = cmkey(crrtab,ncrr,"","automatic",xxstring)) < 0) return(y);
- if (y == CAR_ON) {
- x = cmnum("Carrier wait timeout, seconds","0",10,&z,xxstring);
- if (x < 0) return(x);
- }
- if ((x = cmcfm()) < 0) return(x);
- carrier = ttscarr(y);
- cdtimo = z;
- return(1);
-}
-#endif /* NOLOCAL */
-
-extern struct keytab yesno[];
-extern int nyesno;
-
-/* g e t y e s n o */
-
-static struct keytab q0yesno[] = { /* Yes/No/Quit keyword table */
- "no", 0, 0,
- "ok", 1, 0,
- "yes", 1, 0
-};
-static int nq0yesno = (sizeof(q0yesno) / sizeof(struct keytab));
-
-static struct keytab q1yesno[] = { /* Yes/No/Quit keyword table */
- "no", 0, 0,
- "ok", 1, 0,
- "quit", 2, 0,
- "yes", 1, 0
-};
-static int nq1yesno = (sizeof(q1yesno) / sizeof(struct keytab));
-
-static struct keytab q2yesno[] = { /* Yes/No/Quit keyword table */
- "go", 3, 0,
- "no", 0, 0,
- "ok", 1, 0,
- "yes", 1, 0
-};
-static int nq2yesno = (sizeof(q2yesno) / sizeof(struct keytab));
-
-static struct keytab q3yesno[] = { /* Yes/No/Quit keyword table */
- "go", 3, 0,
- "no", 0, 0,
- "ok", 1, 0,
- "quit", 2, 0,
- "yes", 1, 0
-};
-static int nq3yesno = (sizeof(q3yesno) / sizeof(struct keytab));
-
-
-/* Ask question, get yes/no answer */
-
-int
-getyesno(msg, flags) char * msg; int flags; {
-#ifdef CK_RECALL
- extern int on_recall; /* around Password prompting */
-#endif /* CK_RECALL */
- int y, z;
-
-#ifndef NOLOCAL
-#ifdef OS2
- extern int vmode, win95_popup, startflags;
- int vmode_sav = vmode;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifdef CK_APC
- if ( apcactive != APC_INACTIVE && (apcstatus & APC_NOINP) ) {
- return(success = 0);
- }
-#endif /* CK_APC */
-
-#ifndef NOLOCAL
-#ifdef OS2
-#ifdef COMMENT
- if (win95_popup && !(startflags & 96)
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- )
- return(popup_readyesno(vmode,NULL,msg,flags));
-#endif /* COMMENT */
- if (vmode == VTERM) {
- vmode = VCMD;
- VscrnIsDirty(VTERM);
- VscrnIsDirty(VCMD);
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef VMS
-/*
- In VMS, whenever a TAKE file or macro is active, we restore the
- original console modes so Ctrl-C/Ctrl-Y can work. But here we
- go interactive again, so we have to temporarily put them back.
-*/
- if (!xcmdsrc)
- concb((char)escape);
-#endif /* VMS */
-
-#ifdef CK_RECALL
- on_recall = 0;
-#endif /* CK_RECALL */
- cmsavp(psave,PROMPTL); /* Save old prompt */
- cmsetp(msg); /* Make new prompt */
- z = 0; /* Initialize answer to No. */
- cmini(ckxech); /* Initialize parser. */
- do {
- prompt(NULL); /* Issue prompt. */
- switch (flags) {
- case 0: y = cmkey(q0yesno,nq0yesno,"","",NULL); break;
- case 1: y = cmkey(q1yesno,nq1yesno,"","",NULL); break;
- case 2: y = cmkey(q2yesno,nq2yesno,"","",NULL); break;
- default: y = cmkey(q3yesno,nq3yesno,"","",NULL);
- }
- if (y < 0) {
- if (y == -4) { /* EOF */
- z = y;
- break;
- } else if (y == -3) /* No answer? */
- printf(" Please respond; type '?' to see valid answers.\n");
- cmini(ckxech);
- } else {
- z = y; /* Save answer */
- y = cmcfm(); /* Get confirmation */
- }
- } while (y < 0); /* Continue till done */
- cmsetp(psave); /* Restore real prompt */
-#ifdef VMS
- if (cmdlvl > 0) /* In VMS and not at top level, */
- conres(); /* restore console again. */
-#endif /* VMS */
-#ifndef NOLOCAL
-#ifdef OS2
- if (vmode != vmode_sav) {
- vmode = VTERM;
- VscrnIsDirty(VCMD);
- VscrnIsDirty(VTERM);
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
- return(z);
-}
-
-#ifdef KUI
-extern HWND hwndConsole;
-_PROTOTYP(int gui_txt_dialog,(char *,char *,int,char *,int,char *,int));
-_PROTOTYP(int gui_mtxt_dialog,(char *,int,struct txtbox []));
-_PROTOTYP(int gui_position,(int, int));
-_PROTOTYP(int gui_resize_mode,(int));
-_PROTOTYP(int gui_win_run_mode,(int));
-_PROTOTYP(int gui_saveas_dialog,(char *,char *, int, char *, char *, int));
-extern int gui_dialog;
-#endif /* KUI */
-
-/* u q _ o k -- User Query, get Yes/No or OK Cancel */
-/*
- Call with:
- preface: Explanatory text to print, or NULL.
- prompt: Prompt.
- mask: Bitmask for legal responses: 1 = OK or Yes; 2 = No or Cancel.
- help: Help text (array of strings or NULL) [not used by parser].
- dflt: Default response (1 or 2) [not used by parser].
- Returns:
- -1: Invalid argument(s).
- 0: User said No or Cancel.
- 1 User said Yes or OK.
- Notes:
- preface and prompt should not include final line terminator but may
- include embedded ones. Help text is in case GUI dialog needs a Help
- button; final element of help-string array is "". dflt is used by GUI
- to highlight the default response button.
-*/
-int
-#ifdef CK_ANSIC
-uq_ok(char * preface, char * prompt, int mask,char ** help, int dflt)
-#else /* CK_ANSIC */
-uq_ok(preface,prompt,mask,help,dflt)
- char * preface, * prompt, ** help;
- int mask, dflt;
-#endif /* CK_ANSIC */
-/* uq_ok */ {
- int rc, len;
- char * text=NULL;
-
- if (!prompt)
- return(-1);
-
- if ((mask & 3) == 1) { /* OK (GUI only) */
-#ifdef KUI
- if ( gui_dialog ) {
- /* This one is for popup help, alerts, etc */
- if (preface) {
- len = strlen(preface) + strlen(prompt) + 4;
- text = (char *)malloc(len);
- ckmakmsg(text,len,preface,"\n",prompt,NULL);
- }
- rc = MessageBox(hwndConsole,
- text ? text : prompt,
- prompt,
- MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
- ShowWindowAsync(hwndConsole,SW_SHOWNORMAL);
- SetForegroundWindow(hwndConsole);
- if (text)
- free(text);
- if (!rc)
- return(-1);
- else
- return(1);
- } else
-#endif /* KUI */
- {
- if (preface) /* Just display the text, if any */
- printf("%s\n",preface);
- if (prompt)
- printf("%s\n",prompt);
- return(1);
- }
- } else if ((mask & 3) == 3) { /* Yes/No or OK/Cancel */
-#ifdef KUI
- if ( gui_dialog ) {
- if (preface) {
- len = strlen(preface) + strlen(prompt) + 4;
- text = (char *)malloc(len);
- ckmakmsg(text,len,preface,"\n",prompt,NULL);
- }
- rc = MessageBox(hwndConsole,
- text ? text : prompt,
- prompt,
- MB_YESNO | MB_ICONINFORMATION | MB_TASKMODAL |
- (dflt == 2 ? MB_DEFBUTTON2 : MB_DEFBUTTON1));
- ShowWindowAsync(hwndConsole,SW_SHOWNORMAL);
- SetForegroundWindow(hwndConsole);
- if (text)
- free(text);
- if (!rc)
- return(-1);
- else if (rc == IDNO || rc == IDCANCEL)
- return(0);
- else
- return(1);
- } else
-#endif /* KUI */
- {
- if (preface)
- printf("%s\n",preface);
- return(getyesno(prompt,0));
- }
- } else {
- printf("?Internal error: uq_ok()\n");
- return(-1);
- }
-}
-
-/* u q _ t x t -- User Query, get single text response */
-/*
- Call with:
- preface: Explanatory text to print, or NULL.
- prompt: Prompt.
- echo: 0 = don't echo; 1 = echo; 2 = echo with asterisks.
- help: Help text (array of strings or NULL) [not used by parser].
- buf: Pointer to result buffer.
- buflen: Length of result buffer.
- dflt: Default response text or NULL [not used by parser].
- timer: Optional Timeout
- Returns:
- 0: User said No or Cancel.
- 1 User said Yes or OK.
- Notes:
- preface, prompt, and help as for uq_ok().
-*/
-int
-#ifdef CK_ANSIC
-uq_txt(char * preface, char * prompt, int echo, char ** help, char * buf,
- int buflen, char *dflt, int timer)
-#else /* CK_ANSIC */
-uq_txt(preface,prompt,echo,help,buf,buflen,dflt,timer)
- char * preface, * prompt, ** help, * buf, * dflt;
- int buflen, echo, timer;
-#endif /* CK_ANSIC */
-{
-#ifndef NOLOCAL
-#ifdef OS2
- extern int vmode;
- extern int startflags;
- extern int win95_popup;
-#endif /* OS2 */
-#endif /* NOLOCAL */
- int rc;
-
- if (buflen < 1 || !buf)
- return(0);
-#ifdef KUI
- if ( gui_dialog ) {
- rc = gui_txt_dialog(preface,prompt,echo,buf,buflen,dflt,timer);
- if ( rc > -1 )
- return(rc);
- /* Otherwise, the dialog could not be created. Fallback to text mode */
- }
-#endif /* KUI */
-#ifndef NOLOCAL
-#ifdef OS2
- if (win95_popup && !(startflags & 96)
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- ) {
- debok = 0; /* Don't log */
- if (echo == 1)
- popup_readtext(vmode,preface,prompt,buf,buflen,0);
- else
- popup_readpass(vmode,preface,prompt,buf,buflen,0);
- debok = 1;
- return(1);
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
- if (preface)
- printf("%s\n",preface);
- if (echo == 1)
- readtext(prompt,buf,buflen);
- else
- readpass(prompt,buf,buflen);
- return(1); /* (no buttons in parser) */
-}
-
-/* u q _ m t x t -- User Query, get multiple text responses */
-/*
- Call with:
- preface: Explanatory text to print, or NULL.
- help: Help text (array of strings or NULL) [not used by parser].
- n: Number of responses wanted.
- field: Array of struct txtbox, one element per field, see ckuusr.h.
- Returns:
- 0: User said No or Cancel.
- 1 User said Yes or OK.
- Notes:
- preface and help as for uq_ok().
-*/
-int
-#ifdef CK_ANSIC
-uq_mtxt(char * preface,char **help, int n, struct txtbox field[])
-#else /* CK_ANSIC */
-uq_mtxt(preface,help,n,field)
- char * preface; char ** help; int n; struct txtbox field[];
-#endif /* CK_ANSIC */
-{
-#ifndef NOLOCAL
-#ifdef OS2
- extern int vmode;
- extern int startflags;
- extern int win95_popup;
-#endif /* OS2 */
-#endif /* NOLOCAL */
- int i, rc;
-
- if (n < 1 || !field)
- return(0);
-#ifdef KUI
- if ( gui_dialog ) {
- rc = gui_mtxt_dialog(preface, n, field);
- if ( rc > -1 )
- return(rc);
- /* Otherwise, the dialog could not be created. Fallback to text mode */
- }
-#endif /* KUI */
-#ifndef NOLOCAL
-#ifdef OS2
- if (win95_popup && !(startflags & 96)
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- ) {
- debok = 0; /* Don't log */
- for (i = 0; i < n; i++) {
- if (field[i].t_echo == 1)
- popup_readtext(vmode,preface,field[i].t_lbl,field[i].t_buf,field[i].t_len,0);
- else
- popup_readpass(vmode,preface,field[i].t_lbl,field[i].t_buf,field[i].t_len,0);
- }
- debok = 1;
- return(1);
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
- if (preface)
- printf("%s\n",preface);
- for (i = 0; i < n; i++) {
- if (field[i].t_echo == 1)
- readtext(field[i].t_lbl,field[i].t_buf,field[i].t_len);
- else
- readpass(field[i].t_lbl,field[i].t_buf,field[i].t_len);
- }
- return(1);
-}
-
-/* u q _ f i l e -- User Query, get file or directory name */
-/*
- Call with:
- preface: Explanatory text to print, or NULL.
- prompt: Prompt string.
- fc: Function code:
- 1 = input (existing) file
- 2 = existing directory
- 3 = create new output file
- 4 = output file allowing append access
- help: Help text (array of strings or NULL) [not used by parser].
- dflt: Default response.
- result: Pointer to result buffer.
- rlength: Length of result buffer.
-
- Returns:
- -1: Invalid argument, result too long, or other error.
- 0: User Canceled.
- 1: OK, with file/pathname copied to result buffer.
- 2: Like 1, but for output file that is to be appended to.
-
- Notes:
- 1. preface and prompt should not include final line terminator but may
- include embedded ones. Help text is in case GUI dialog needs a Help
- button; final element of help-string array is "".
-
- 2. The default might be a filename, a directory name, a relative
- pathname, or an absolute pathname. This routine must convert it into
- into a fully qualified (absolute) pathname so the user knows exactly
- where the file is to be found or stored. In addition, the Windows
- version of this routine must separate the directory part from the
- name part, so it can display the given directory in the file dialog,
- and put name in the filename box to be edited, replaced, or
- accepted.
-
- 3. When called with FC 4, the Windows version should include "New" and
- "Append" buttons in the dialog. so the user can say whether the file
- should overwrite any file of the same name, or be appended to it.
-*/
-
-int
-#ifdef CK_ANSIC
-uq_file(char * preface, char * fprompt, int fc, char ** help,
- char * dflt, char * result, int rlength)
-#else /* CK_ANSIC */
-uq_file(preface,fprompt,fc,help,dflt,result,rlength)
- char * preface, * fprompt, ** help, * dflt, * result;
- int fc, rlength;
-#endif /* CK_ANSIC */
-/* uq_file */ {
-
- int rc = -1, x, y, z;
- char * s, * p, * fullpath;
- char filebuf[CKMAXPATH+1];
-
-#ifdef CK_RECALL
- extern int on_recall;
-#endif /* CK_RECALL */
-
-#ifdef KUI
- if ( gui_dialog ) {
- rc = gui_saveas_dialog(preface,fprompt,fc,dflt,result,rlength);
- return rc;
- }
-#endif /* KUI */
-
-#ifdef CK_RECALL
- on_recall = 0;
-#endif /* CK_RECALL */
-
- if (preface) /* If prefatory text given... */
- printf("%s\n",preface); /* display it. */
-
- cmsavp(psave,PROMPTL); /* Save old prompt */
-
- /* We get the full pathname of the proposed output file just so */
- /* we can show it to the user but we don't use it ourselves. */
-
- p = NULL; /* Build new prompt */
- if (!dflt) dflt = "";
- if (*dflt) /* Have default filename */
- zfnqfp(dflt,CKMAXPATH+1,filebuf); /* Get full path */
- else
- ckmakmsg(filebuf,CKMAXPATH+1,zgtdir(),"newfile",NULL,NULL);
- fullpath = filebuf;
- x = strlen(fullpath);
-
- /* If no prompt given, build one that shows the proposed full pathname. */
-
- if (!fprompt) fprompt = "";
- if (!*fprompt) fprompt = x ? " Filename" : " Filename: ";
- y = strlen(fprompt);
- if (x > 0) { /* Have default pathname? */
- p = (char *)malloc(x + y + 7); /* Get temp storage */
- if (p) { /* Build prompt */
- ckmakmsg(p,x+y+7,fprompt," [",fullpath,"]: ");
- fprompt = p;
- }
- }
- cmsetp(fprompt); /* Make new prompt */
- if (p) free(p); /* Free temp storage */
- cmini(ckxech); /* Initialize parser. */
- x = -1;
- do {
- prompt(NULL); /* Issue prompt. */
- switch (fc) { /* Parse depends on function code */
- case 1: /* Input file */
- x = cmifi("Name of existing file",dflt,&s,&y,xxstring);
- rc = 1;
- break;
- case 2: /* Directory */
- x = cmdir("Directory name",dflt,&s,xxstring);
- rc = 1;
- break;
- case 3: /* New output file */
- /* Fall thru... */
- case 4: /* Output file - Append allowed */
- x = cmofi("Output file specification",dflt,&s,xxstring);
- rc = (fc == 4) ? 1 : 2;
- break;
- default: /* Bad function code */
- goto x_uq_file;
- }
- if (x < 0) { /* Parse error */
- filebuf[0] = NUL;
- if (x == -4) { /* EOF */
- break;
- } else if (x == -3) /* No answer? */
- printf(fc == 2 ?
- " Please enter a directory name.\n" :
- " Please enter a filename.\n"
- );
- cmini(ckxech);
- } else {
- z = strlen(s);
- if (z > rlength || ckstrncpy(filebuf,brstrip(s),CKMAXPATH+1) < z) {
- printf("?Name too long\n");
- x = -9;
- } else
- x = cmcfm(); /* Get confirmation */
- }
- if (fc == 1 && x > -1 && y > 0) {
- printf("?Wildcards not allowed\n");
- x = -9;
- }
- } while (x < 0); /* Continue till done */
-
- x_uq_file:
- if (x < 0)
- rc = -1;
-
- cmsetp(psave); /* Restore real prompt */
-
- if (rc > 0)
- ckstrncpy(result,filebuf,rlength);
- return(rc);
-}
-
-
-#ifdef CK_PERMS
-#ifdef UNIX
-
-_PROTOTYP( int zsetperm, (char *, int));
-
-/* CHMOD command for UNIX only */
-
-#define CHM_DIR 0
-#define CHM_DOT 1
-#define CHM_FIL 2
-#define CHM_LIS 3
-#define CHM_NOL 4
-#define CHM_QUI 5
-#define CHM_REC 6
-#define CHM_VRB 7
-#define CHM_PAG 8
-#define CHM_NOP 9
-#define CHM_TYP 10
-#define CHM_SIM 11
-
-static struct keytab uchmodsw[] = {
- "/directories", CHM_DIR, 0,
- "/dotfiles", CHM_DOT, 0,
- "/files", CHM_FIL, 0,
- "/list", CHM_LIS, 0,
- "/nolist", CHM_NOL, 0,
- "/nopage", CHM_NOP, 0,
- "/page", CHM_PAG, 0,
- "/quiet", CHM_QUI, CM_INV,
- "/recursive", CHM_REC, 0,
- "/simulate", CHM_SIM, 0,
- "/type", CHM_TYP, CM_ARG,
- "/verbose", CHM_VRB, CM_INV,
-};
-static int nchmodsw = (sizeof(uchmodsw) / sizeof(struct keytab));
-
-int
-douchmod() {
- extern int recursive, nscanfile, diractive;
-#ifdef CK_TTGWSIZ
- extern int tt_rows, tt_cols;
- int n = 0;
-#endif /* CK_TTGWSIZ */
- int i, files = 1, t1 = 1, t2 = 0, x, y, z, verbose = 0, rc = 1, paging;
- int xmode = -1, fs = 0, getval = 0, simulate = 0, wild = 0;
- char c, * s;
- struct FDB sw, nu;
-
- if (xaskmore < 0) {
-#ifdef CK_TTGWSIZ
- xaskmore = 1;
-#else
- xaskmore = 0;
-#endif /* CK_TTGWSIZ */
- }
- paging = xaskmore;
-
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Octal file permission code, or switch",
- "", /* default */
- "", /* addtl string data */
- nchmodsw, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- uchmodsw, /* Keyword table */
- &nu /* Pointer to next FDB */
- );
- cmfdbi(&nu,
- _CMNUM, /* Number */
- "", /* Help message */
- "", /* Default */
- "", /* N/A */
- 8, /* Radix = 8 */
- 0, /* N/A */
- xxstring, /* Processing function */
- NULL, /* N/A */
- NULL /* Next */
- );
-
- while (1) {
- if ((x = cmfdb(&sw)) < 0) {
- if (x == -3) {
- x = -9;
- printf("?Filename required\n");
- }
- return(x);
- }
- if (cmresult.fcode != _CMKEY)
- break;
- c = cmgbrk();
- getval = (c == ':' || c == '=');
- if (getval && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (cmresult.nresult) {
- case CHM_DIR:
- t1 = 1;
- t2 = 1;
- break;
- case CHM_DOT:
- matchdot = 1;
- break;
- case CHM_FIL:
- t1 = 0;
- t2 = 0;
- break;
- case CHM_LIS:
- case CHM_VRB:
- verbose = 1;
- break;
- case CHM_NOL:
- case CHM_QUI:
- verbose = 0;
- break;
- case CHM_REC:
- recursive = 1;
- break;
- case CHM_PAG:
- verbose = 1;
- paging = 1;
- break;
- case CHM_NOP:
- paging = 0;
- break;
- case CHM_SIM:
- simulate = 1;
- break;
- case CHM_TYP: {
- extern struct keytab txtbin[];
- if ((x = cmkey(txtbin,3,"","",xxstring)) < 0)
- return(x);
- if (x == 2) { /* ALL */
- xmode = -1;
- } else { /* TEXT or BINARY only */
- xmode = x;
- fs = 1;
- }
- break;
- }
- }
- }
- z = cmresult.nresult;
- x = cmifi2("File specification","",&s,&wild,t1,NULL,xxstring,t2);
- if (x < 0) {
- if (x == -3) {
- printf("?A file specification is required\n");
- return(-9);
- } else
- return(x);
- }
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- s = tmpbuf;
- if ((x = cmcfm()) < 0)
- return(x);
-#ifdef ZXREWIND
- if (wild) files = zxrewind();
-#else
- if (wild) files = nzxpand(s,0);
-#endif /* ZXREWIND */
-
- if (paging > -1)
- xaskmore = paging;
-
-#ifdef CK_TTGWSIZ
- if (verbose && paging) {
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
- }
-#endif /* CK_TTGWSIZ */
-
- for (i = 0; i < files; i++) {
- if (files == 1 && wild == 0) { /* For "chmod 777 ." */
- ckstrncpy(line,s,LINBUFSIZ);
- } else {
- x = znext(line);
- if (x < 1) {
- if (i == 0) {
- printf("?No files match - \"%s\"\n",line);
- return(-9);
- }
- return(1);
- }
- }
- if (fs) {
-#ifdef VMSORUNIX
- /* If /TYPE:TEXT or BINARY given, skip directories and links */
- /* since they are neither text nor binary. */
- extern int zgfs_dir, zgfs_link;
- zgetfs(line);
- if (zgfs_dir || zgfs_link)
- continue;
-#else
- if (zchki(line) < 0)
- continue;
-#endif /* VMSORUNIX */
- /* Regular file, scan it */
- switch (scanfile(line,&y,nscanfile)) {
- case FT_BIN:
- if (xmode != 1)
- continue;
- break;
- case FT_TEXT:
- case FT_7BIT:
- case FT_8BIT:
-#ifdef UNICODE
- case FT_UTF8:
- case FT_UCS2:
-#endif /* UNICODE */
- if (xmode != 0)
- continue;
- }
- }
- if (simulate) {
-#ifdef UNIX
- extern int zchkod; /* Unidentified Flying */
- int xx = zchkod; /* API Extension... */
- zchkod = 1;
-#endif /* UNIX */
- if (zchko(line) < 0)
- printf("%s - Access denied\n",line);
- else
- printf("%s - OK\n",line);
-#ifdef UNIX
- zchkod = xx;
-#endif /* UNIX */
- } else {
- if (zsetperm(line,z) < 1) {
- if (verbose || files < 2) {
- printf("%s: %s\n",line,ck_errstr());
- }
- rc = 0;
- } else if (verbose) {
- printf("%s %s\n",ziperm(line),line);
- }
- }
-#ifdef CK_TTGWSIZ
- if (verbose && paging) { /* Pause at end of screen */
- if (cmd_rows > 0 && cmd_cols > 0) {
- if (++n > cmd_rows - 3) {
- if (!askmore())
- break;
- else
- n = 0;
- }
- }
- }
-#endif /* CK_TTGWSIZ */
-
- }
- return(success = rc);
-}
-#endif /* UNIX */
-#endif /* CK_PERMS */
-
-#ifndef NOSPL /* S-Expressions */
-#ifndef NOSEXP
-
-struct keytab sexptab[] = {
- "depth-limit", 1, 0,
- "echo-result", 0, 0,
- "truncate-all-results", 2
-};
-
-static int sexpmaxdep = 1000; /* Maximum depth */
-
-#define xxfloat(s,x) \
-((isdigit(*s)||(*s=='-')||(*s=='+')||(*s=='.')||(*s=='\040'))?isfloat(s,x):0)
-
-#define SX_ADD 1 /* Symbols for built-in operators */
-#define SX_SUB 2
-#define SX_MUL 3
-#define SX_DIV 4
-#define SX_POW 5
-#define SX_SET 6
-#define SX_MOD 7
-#define SX_EVA 8
-#define SX_EXP 9
-#define SX_AEQ 10
-#define SX_ALT 11
-#define SX_AGT 12
-#define SX_ALE 13
-#define SX_AGE 14
-#define SX_MIN 15
-#define SX_MAX 16
-#define SX_SQR 17
-#define SX_FLR 18
-#define SX_CEI 19
-#define SX_TRU 20
-#define SX_ABS 21
-#define SX_ROU 22
-#define SX_LET 23
-#define SX_LGN 24
-#define SX_LGX 25
-#define SX_FLO 26
-#define SX_IFC 27
-#define SX_NOT 28
-#define SX_NEQ 29
-#define SX_AND 30
-#define SX_LOR 31
-#define SX_SIN 32
-#define SX_COS 33
-#define SX_TAN 34
-#define SX_BWA 35
-#define SX_BWO 36
-#define SX_BWX 37
-#define SX_BWN 38
-#define SX_XOR 39
-#define SX_INC 40
-#define SX_DEC 41
-#define SX_QUO 42
-#define SX_STR 43
-
-/* Operator flags */
-
-#define SXF_PRE 256 /* Predicate */
-#define SXF_ONE 512 /* Requires one arg */
-#define SXF_TWO 1024 /* Requires two args or more */
-#define SXF_FLO 2048 /* Coerce to floating-point */
-
-/* Built-in constants */
-
-#define SXC_NIL 1 /* NIL */
-#define SXC_PI 2 /* PI */
-#define SXC_T 3 /* T */
-
-/*
- This is an xlookup() table and so need not be in "alhabetical" order.
- Therefore entries are arranged to minimize search for most common
- operators.
-*/
-static struct keytab sexpops[] = { /* Built-in operators */
- "setq", SX_SET, 0, /* Global assignment */
- "+", SX_ADD, 0, /* Simple arithmetic */
- "-", SX_SUB, 0,
- "*", SX_MUL, 0,
- "/", SX_DIV, SXF_TWO,
- "^", SX_POW, SXF_TWO,
-
- "if", SX_IFC, SXF_TWO, /* IF */
- "let", SX_LET, 0, /* Local assignment */
- "not", SX_NOT, SXF_ONE, /* NOT */
- "mod", SX_MOD, SXF_TWO, /* Modulus */
-
- "<", SX_ALT, SXF_PRE, /* Comparisons */
- ">", SX_AGT, SXF_PRE,
- "<=", SX_ALE, SXF_PRE,
- "=", SX_AEQ, SXF_PRE,
- ">=", SX_AGE, SXF_PRE,
- "!=", SX_NEQ, SXF_PRE,
-
- "++", SX_INC, SXF_ONE|SXF_TWO, /* Increment */
- "--", SX_DEC, SXF_ONE|SXF_TWO, /* Decrement */
-
- "**", SX_POW, SXF_TWO, /* Common synonyms */
- "==", SX_AEQ, SXF_PRE,
- "!", SX_NOT, SXF_ONE,
- ".", SX_EVA, 0,
-
- "and", SX_AND, 0, /* Logical operators */
- "or", SX_LOR, 0,
- "xor", SX_XOR, SXF_TWO,
-
- "max", SX_MAX, SXF_ONE|SXF_TWO, /* Max and min */
- "min", SX_MIN, SXF_ONE|SXF_TWO,
-
- "%", SX_MOD, SXF_TWO, /* More synonyms */
- "||", SX_LOR, 0,
- "&&", SX_AND, 0,
-
- "quote", SX_QUO, SXF_ONE,
- "string", SX_STR, SXF_ONE,
-
- "eval", SX_EVA, 0, /* Assorted commands */
- "abs", SX_ABS, SXF_ONE,
- "truncate",SX_TRU, SXF_ONE|SXF_FLO,
- "round", SX_ROU, SXF_ONE|SXF_TWO|SXF_FLO,
- "ceiling", SX_CEI, SXF_ONE|SXF_FLO,
- "floor", SX_FLR, SXF_ONE|SXF_FLO,
- "float", SX_FLO, SXF_ONE|SXF_FLO,
-
-#ifdef FNFLOAT
- "sqrt", SX_SQR, SXF_ONE|SXF_FLO, /* Floating point functions */
- "exp", SX_EXP, SXF_ONE|SXF_FLO,
- "sin", SX_SIN, SXF_ONE|SXF_FLO,
- "cos", SX_COS, SXF_ONE|SXF_FLO,
- "tan", SX_TAN, SXF_ONE|SXF_FLO,
- "log", SX_LGN, SXF_ONE|SXF_FLO,
- "log10", SX_LGX, SXF_ONE|SXF_FLO,
-#endif /* FNFLOAT */
-
- "#", SX_BWX, SXF_TWO, /* Bitwise operators */
- "&", SX_BWA, 0,
- "|", SX_BWO, 0,
- "~", SX_BWN, SXF_ONE,
- "", 0, 0 /* (end) */
-};
-static int nsexpops = (sizeof(sexpops) / sizeof(struct keytab)) - 1;
-
-static struct keytab sexpconsts[] = { /* Built-in constants */
- "nil", SXC_NIL, 0, /* NIL (false) */
- "pi", SXC_PI, 0, /* Pi (3.1415926...) */
- "t", SXC_T, 0, /* T (true) */
- "", 0, 0
-};
-static int nsexpconsts = (sizeof(sexpconsts) / sizeof(struct keytab)) - 1;
-
-int sexprc = 0; /* S-Expression error flag */
-int sexppv = -1; /* Predicate value */
-static int sexptrunc = 0; /* Flag to force all results to int */
-
-#define SXMLEN 64 /* Macro arg list initial length */
-#include <math.h> /* Floating-point functions */
-
-_PROTOTYP( char * fpformat, (CKFLOAT, int, int) );
-_PROTOTYP( CKFLOAT ckround, (CKFLOAT, int, char *, int) );
-
-extern char math_pi[]; /* Value of Pi */
-extern int sexpecho; /* SET SEXPRESSION ECHO value */
-extern char * sexpval; /* Last top-level S-Expression value */
-extern char * lastsexp; /* Last S-Expression */
-int sexprmax = 0; /* Longest result (for stats) */
-int sexpdmax = 0; /* Max depth reached (for stats) */
-int sexpdep = 0; /* dosexp() recursion depth */
-static int * sxrlen = NULL; /* Result stack string sizes */
-static char ** sxresult = NULL; /* Result stack */
-
-/* s h o s e x p -- Show S-Expression info */
-
-VOID
-shosexp() {
- printf("\n");
- printf(" sexpression echo-result: %s\n",showooa(sexpecho));
- printf(" sexpression depth-limit: %d\n",sexpmaxdep);
- printf("\n");
- printf(" maximum depth reached: %d\n",sexpdmax);
- printf(" longest result returned: %d\n",sexprmax);
- printf("\n");
- printf(" truncate all results: %s\n",showoff(sexptrunc));
- printf("\n");
- printf(" last sexpression: %s\n",lastsexp ? lastsexp : "(none)");
- printf(" last value: %s\n",sexpval ? sexpval : "(none)");
- printf("\n");
-}
-
-
-static char *
-sexpdebug(s) char * s; {
- /* For debugging -- includes recursion depth in each debug entry */
- static char buf[64];
- ckmakmsg(buf,64,"dosexp[",ckitoa(sexpdep),"] ",s);
- return((char *)buf);
-}
-
-/* d o s e x p -- S-Expression Reader */
-
-/* Returns value as string (empty, numeric, or non-numeric) */
-
-static char sxroundbuf[32]; /* For ROUND result */
-
-char *
-dosexp(s) char *s; { /* s = S-Expression */
- extern struct mtab *mactab; /* Macro table */
- extern int maclvl, nmac;
- extern char *mrval[];
- extern int makestrlen; /* (see makestr()) */
- struct stringarray * q = NULL; /* cksplit() return type */
- char * p[SEXPMAX+1], ** p2; /* List items (must be on stack) */
- char * line = NULL; /* For building macro argument list */
- int nosplit = 0;
- int linelen = 0;
- int linepos = 0;
- int quote = 0; /* LISP quote flag */
- char * s2; /* Workers */
- int kw, kwflags, mx = 0, x = 0;
- int not = 0, truncate = 0, builtin = 0;
- int fpflag = 0, quit = 0, macro = 0;
- CK_OFF_T result = 0, i, j, k, n = 0;
- CKFLOAT fpj, fpresult = 0.0; /* Floating-point results */
- int pflag = 0; /* Have predicate */
- int presult = 0; /* Predicate result */
- int mustfree = 0; /* If we malloc'd we must free */
-
- sexppv = -1; /* Predicate value */
- s2 = ""; /* Default return value */
-
- debug(F111,sexpdebug("entry 1"),s,sexprc);
-
- if (++sexpdep > sexpmaxdep) { /* Keep track of depth */
- printf("?S-Expression depth limit exceeded: %d\n",sexpmaxdep);
- sexprc++;
- debug(F111,sexpdebug("max depth exceeded"),s,sexprc);
- }
- if (sexpdep > sexpdmax) /* For stats */
- sexpdmax = sexpdep;
-
- if (sexprc) /* Error, quit all levels */
- goto xdosexp; /* Always goto common exit point */
-
- debug(F111,sexpdebug("entry 2"),s,sexprc);
-
- if (!s) s = ""; /* Null or empty arg */
-
- while (*s == SP) s++; /* Strip leading spaces */
- if (!*s) /* so empty result */
- goto xdosexp;
-/*
- Allocate result stack upon first use, or after it has been resized with
- SET SEXP DEPTH-LIMIT.
-*/
- if (!sxresult) {
- sxresult = (char **)malloc(sexpmaxdep * sizeof(char *));
- if (!sxresult) {
- printf("?Memory allocation failure - \"%s\"\n", s);
- sexprc++;
- goto xdosexp;
- }
- sxrlen = (int *)malloc(sexpmaxdep * sizeof(int));
- if (!sxrlen) {
- printf("?Memory allocation failure - \"%s\"\n", s);
- sexprc++;
- goto xdosexp;
- }
- for (i = 0; i < sexpmaxdep; i++) {
- sxresult[i] = NULL; /* Result pointers */
- sxrlen[i] = 0; /* Buffer sizes */
- }
- }
- s2 = s; /* s2 is the result pointer */
- k = 0; /* Length accumulator */
- if (s[0] == '(') { /* Starts with open paren? */
- while (*s2++) k++; /* Get length */
- if (s[k-1] == ')') { /* Strip outer parens if any */
- s[k-1] = NUL;
- s++;
- k -= 2;
- while (*s == SP) { /* Strip leading spaces from result */
- s++;
- k--;
- }
- while (k > 0 && s[k-1] == SP) { /* And trailing spaces. */
- s[k-1] = NUL;
- k--;
- }
- }
- if (!*s) { /* If nothing remains */
- s2 = ""; /* return empty result. */
- goto xdosexp;
- }
- }
- /* Break result up into "words" (an SEXP counts as a word) */
-
- for (i = 0; i < SEXPMAX+1; i++ ) { /* Clear the operands */
- p[i] = NULL;
- }
- if (!*(s+1) || !*(s+2)) { /* No need to call cksplit() */
- n = 1; /* if it's one or two chars. */
- p[1] = s; /* No need to malloc this either. */
- nosplit = 1;
- debug(F101,sexpdebug("nosplit"),"",n);
- if (s[0] == '(') { /* () empty */
- s2 = "";
- goto xdosexp;
- }
- } else {
- nosplit = 0;
- q = cksplit(1,SEXPMAX,s,NULL,"\\%[]&$+-/=*^_@!{}/<>|.#~'`:;?",8,39,0);
- if (!q)
- goto xdosexp;
- n = q->a_size; /* Number of items */
- debug(F101,sexpdebug("split"),"",n);
- if (n < 0 || n > SEXPMAX) { /* Check for too many */
- printf("?Too many operands: max = %d\n",SEXPMAX);
- sexprc++;
- goto xdosexp;
- }
- if (n == 0) /* None, result is NULL, done. */
- goto xdosexp;
- if (n == 1 && s[0] == '(') { /* One but it's another SEXP */
- s2 = dosexp(s);
- goto xdosexp;
- }
- p2 = q->a_head; /* Point to result array. */
- for (i = 1; i <= n; i++) { /* We must copy it because */
- p[i] = NULL; /* recursive calls to dosexp() */
- if (p2[i]) /* write over the same array */
- makestr(&(p[i]),p2[i]);
- }
- if (s[0] == '(') { /* Operator is an S-Expression */
- s2 = dosexp(p[1]); /* Replace it by its value */
- makestr(&(p[1]),s2);
- }
- mustfree++; /* Remember to free it */
- }
- debug(F110,sexpdebug("head"),p[1],0);
-
- if (n == 1 && p[1]) {
- if (*(p[1]) == '\047') { /* Apostrophe = LISP quote character */
- s2 = p[1];
- goto xdosexp;
- }
- }
-/*
- This section sidesteps xlookup() of the most common operators.
- It's not necessary but it speeds up SEXP-heavy loops by about 10%.
-*/
- kwflags = 0;
- if (n > 0) { /* Look up the operator */
- s2 = p[1]; /* Prelookup optimization... */
- if (!s2)
- s2 = "";
- if (!*s2)
- goto xdosexp;
- kw = 0;
- x = 0;
- if (isdigit(*s2)) { /* Digit */
- x = -2;
-
- } else if (isalpha(*s2) && !*(s2+1)) { /* Single letter */
- x = -1;
-
- } else if (*s2 == 's' || *s2 == 'S') { /* SETQ */
- s2++;
- if (*s2 == 'e' || *s2 == 'E') {
- s2++;
- if (*s2 == 't' || *s2 == 'T') {
- s2++;
- if (*s2 == 'q' || *s2 == 'Q') {
- if (!*(s2+1)) {
- x = SX_SET;
- kwflags = 0;
- builtin = 1;
- }
- }
- }
- }
- }
- if (!x) {
- if (!*(s2+1)) { /* Common single-character ops */
- if (*s2 == '+') {
- x = SX_ADD;
- kwflags = 0;
- builtin = 1;
- } else if (*s2 == '-') {
- x = SX_SUB;
- kwflags = 0;
- builtin = 1;
- } else if (*s2 == '*') {
- x = SX_MUL;
- kwflags = 0;
- builtin = 1;
- } else if (*s2 == '/') {
- x = SX_DIV;
- kwflags = SXF_TWO;
- builtin = 1;
- }
- }
- if (!x) { /* None of the above, look it up */
- x = xlookup(sexpops,p[1],nsexpops,&kw);
- if (x > 0) {
- kwflags = sexpops[kw].flgs;
- builtin = 1;
- }
- }
- }
- }
- /* If none of the above, check built-in constants */
-
- if (x == -1) {
- x = xlookup(sexpconsts,p[1],nsexpconsts,&kw);
- if (x > 0) {
- switch (x) {
- case SXC_NIL:
- s2 = "";
- goto xdosexp;
- case SXC_PI:
- s2 = math_pi;
- goto xdosexp;
- case SXC_T:
- s2 = "1";
- goto xdosexp;
- }
- }
- }
- if (n == 1) { /* Not an expression */
- if (builtin) { /* Built-in operand? */
- switch (x) { /* Operators with default values */
- case SX_EVA:
- s2 = "";
- goto xdosexp;
- case SX_MUL: /* (*) */
- s2 = sexpval ? sexpval : "1";
- goto xdosexp;
- case SX_AND: /* (AND) */
- case SX_BWA: /* Bitwise (&) */
- result++;
- case SX_LOR: /* (OR) */
- case SX_BWO: /* Bitwise (|) */
- case SX_ADD: /* (+) */
- case SX_SUB: /* (-) */
- s2 = result ? "1" : "0";
- goto xdosexp;
- }
-
- } else { /* Not a built-in operand */
- char * p1;
- p1 = p[1];
- while (*p1 == SP) p1++;
- if (!isalpha(*p1)) {
- if (xxfloat(p1,0) > 0) { /* Is it a number? */
- s2 = p1;
- while (*s2 == '+') s2++;
- } else if (*p1 == '(') { /* An S-Expression? */
-
-#ifdef COMMENT
- s2 = dosexp(s2);
-#else
- s2 = dosexp(p1);
-#endif /* COMMENT */
- }
- goto xdosexp;
- } else if (x < 1) { /* Is it a variable? */
- j = mxlook(mactab,p[1],nmac); /* Look it up */
- debug(F111,sexpdebug("n==1 mxlook"),p[1],j);
- s2 = (j > -1) ? mactab[j].mval : "";
- if (!s2) s2 = "";
- if (xxfloat(s2,0) > 0) /* Macro value is a number */
- goto xdosexp;
- if (j > -1) { /* It's a macro */
- mx = j;
- x = j; /* whose definition is not numeric */
- if (*s2 == '(') { /* Is it an S-Expression? */
- /* We have to allocate memory on the stack */
- /* to call ourselves recursively on it */
- /* otherwise we'll wipe out the macro definition */
- char * s3 = NULL;
- /* int k = 0; */
- s3 = s2;
- while (*s3++) k++;
- s3 = (char *)malloc(k + 4);
- if (s3) {
- strcpy(s3,s2); /* SAFE */
- s2 = dosexp(s3); /* Evaluate it */
- free(s3);
- } else {
- printf("?Memory allocation failure - \"%s\"\n",s2);
- sexprc++;
- }
- goto xdosexp;
- }
- if (*s2 == '\047') {
- s2++;
-#ifdef COMMENT
- /* Dumps core if petty optimization was taken */
- makestr(&(p[1]),s2);
-#else
- if (!nosplit && p[1]) free(p[1]);
- p[1] = (char *)malloc((int)strlen(s2) + 1);
-#endif /* COMMENT */
- s2 = p[1];
- if (!s2) s2 = "";
- if (*s2 == '(') {
- if (s2[makestrlen-1] == ')') {
- s2[makestrlen-1] = NUL;
- s2++;
- }
- }
- debug(F110,sexpdebug("'A"),s2,0);
- goto xdosexp;
- }
- macro++; /* Not an S-Expression */
- } else { /* Not found in macro table */
- printf("?Not defined - \"%s\"\n", p[1]);
- sexprc++;
- goto xdosexp;
- }
- }
- }
- } else if (x < 1 && !macro) { /* n > 1 and not a built-in operator */
- x = mxlook(mactab,p[1],nmac); /* See if it's a macro */
- debug(F111,sexpdebug("n!=1 mxlook"),p[1],x);
- if (x < 0) {
- printf("?Invalid operand - \"%s\"\n",p[1]);
- sexprc++;
- goto xdosexp;
- }
- mx = x;
- macro++;
- }
- if (builtin) { /* Built-in operator... */
- if (kwflags) {
- int flgs;
- if ((flgs = (kwflags & (SXF_ONE|SXF_TWO)))) {
- switch (flgs) {
- case (SXF_ONE|SXF_TWO):
- if (n < 2) {
- printf("?Too few operands - \"%s\"\n",s);
- sexprc++;
- goto xdosexp;
- }
- break;
- case SXF_TWO:
- if (n < 3) {
- printf("?Too few operands - \"%s\"\n",s);
- sexprc++;
- goto xdosexp;
- }
- break;
- case SXF_ONE:
- if (n != 2) {
- printf("?Too %s operands - \"%s\"\n",
- (n > 2) ? "many" : "few", s);
- sexprc++;
- goto xdosexp;
- }
- }
- }
- if (kwflags & SXF_PRE) { /* Predicate? */
- if (n < 2) {
- printf("?Too few operands - \"%s\"\n",s);
- sexprc++;
- goto xdosexp;
- }
- pflag = 1;
- presult = 1;
- }
- if (kwflags & SXF_FLO) /* Operator requires floating point */
- fpflag++; /* Force it */
-
- if (x == SX_ROU) { /* ROUND can have 1 or 2 arguments */
- if (n < 2 || n > 3) {
- printf("?Too %s operands - \"%s\"\n",
- (n > 3) ? "many" : "few", s);
- sexprc++;
- goto xdosexp;
- }
- }
- if (x == SX_ROU) {
- /* But they are not "cumulative" like other SEXP args */
- /* So this case is handled specially */
- char buf1[32], buf2[32];
- float r;
- char * s0, * s1;
- char * q0, * q1;
-
- s0 = p[2];
- if (!s0) s0 = "";
- if (!*s0) s0 = "0";
- q0 = dosexp(s0);
- ckstrncpy(buf1,q0,32);
- q0 = buf1;
-
- s1 = p[3];
- if (!s1) s1 = "";
- if (!*s1) s1 = "0";
- q1 = dosexp(s1);
- if (!q1) q1 = "";
- if (!*q1) q1 = "0";
- ckstrncpy(buf2,q1,32);
- q1 = buf2;
-
- r = ckround(atof(q0),(int)(atof(q1)),sxroundbuf,31);
- s2 = sxroundbuf;
- sexprc = 0;
- goto xdosexp;
- }
- }
- if (x == SX_SET || x == SX_LET || /* Assignment is special */
- x == SX_INC || x == SX_DEC) {
- int rc;
- char c, * m, * s3;
- if (n == 1) {
- s2 = "";
- goto xdosexp;
- }
- s2 = NULL;
- for (i = 1; i < n; i += 2) { /* Loop thru operand pairs */
- rc = 0;
- s3 = p[i+1];
- c = *s3;
- debug(F110,sexpdebug("target p"),s3,0);
-
- /* Make sure target doesn't have multiple words */
- while (*s3) { if (*s3 < '!') { rc = 1; break; }; s3++; }
- s3 = p[i+1];
- if (rc) { /* If it does it must have been */
- char * s4; /* an SEXP so evaluate it */
- s3 = dosexp(s3);
- s4 = s3;
- rc = 0;
- while (*s4) { if (*s4 < '!') { rc = 1; break; }; s4++; }
- if (rc == 0) makestr(&(p[i+1]),s3);
- }
-
- /* And that it's not a number, etc. */
- if (rc > 0 || isdigit(c) || c == '(') {
- printf("?Invalid assignment - \"%s\"\n",s);
- sexprc++;
- goto xdosexp;
- } else if (isalpha(c)) {
- rc = xlookup(sexpconsts,s3,nsexpconsts,NULL);
- if (rc > 0) {
- printf("?Assignment to constant - \"%s\"\n",s);
- sexprc++;
- goto xdosexp;
- }
- }
-
- /* If ++ or --, get current value of variable */
- if (x == SX_INC || x == SX_DEC) {
- int ok = 1;
- char buf[32];
- if (c == CMDQ) { /* A backslash variable */
- int n = 32;
- char * s = buf;
- buf[0] = NUL;
- if (zzstring(s3,&s,&n) < 0 || !buf[0])
- ok = 0;
- s2 = buf;
- } else { /* A macro */
- if ((k = mxlook(mactab,s3,nmac)) < 0)
- ok = 0;
- else
- s2 = mactab[k].mval;
- }
- if (!ok) {
- printf("?Not defined - \"%s\"\n",p[i+1]);
- sexprc++;
- goto xdosexp;
- }
- if (!s2) s2 = "";
- k = xxfloat(s2,0);
- if (k < 1) {
- printf("?Not numeric - \"%s\"\n",p[i+1]);
- sexprc++;
- goto xdosexp;
- }
- while (*s2 == '+') s2++;
- result = ckatofs(s2);
- fpresult = floatval;
- if (k > 1 || fpresult != result)
- fpflag++;
- }
- if (n < i+2) { /* Variable with no value */
- s2 = "";
- if (x == SX_SET || x == SX_LET) {
- delmac(p[i+1],1); /* Delete the variable */
- break;
- } else {
- s2 = "1";
- }
- } else { /* Variable with value */
- k = xxfloat(p[i+2],0); /* Is it a number? */
- if (k > 0) {
- s2 = p[i+2];
- while (*s2 == '+') s2++;
- } else {
- s2 = dosexp(p[i+2]); /* Have value, evaluate it */
- if (sexprc) goto xdosexp;
- if (!s2) s2 = "";
- if (!*s2 && (x == SX_INC || x == SX_DEC))
- continue;
- }
- }
- if (x == SX_INC || x == SX_DEC) {
- k = xxfloat(s2,0);
- if (k < 1) {
- printf("?Not numeric - \"%s\"\n",s2);
- sexprc++;
- goto xdosexp;
- }
- while (*s2 == '+') s2++;
- j = ckatofs(s2);
- if (k > 1) {
- fpj = floatval;
- fpflag++;
- } else {
- fpj = (CKFLOAT)j;
- }
- if (x == SX_INC) {
- result += j;
- fpresult += fpj;
- } else if (x == SX_DEC) {
- result -= j;
- fpresult -= fpj;
- }
-#ifdef FNFLOAT
- if (result != fpresult) fpflag++;
-#endif /* FNFLOAT */
- s2 = (fpflag && !sexptrunc) ?
- fpformat(fpresult,0,0) : ckfstoa(result);
- }
- if (x == SX_LET && cmdlvl > 0) /* LET makes var local */
- addlocal(p[i+1]);
- if ((rc = addmac(p[i+1],s2)) < 0) { /* Add the value */
- switch (rc) {
- case -3: m = "Array not declared"; break;
- case -2: m = "Subscript out of range"; break;
- case -4: m = "Out of memory"; break;
- default: m = "Error creating variable";
- }
- printf("?%s - \"%s\"\n",m,s);
- sexprc++;
- goto xdosexp;
- }
- if (s2) result = ckatofs(s2);
- }
- goto xdosexp;
- } else if (x == SX_IFC) { /* Conditional expression */
- int true = 0;
- if (n > 4) {
- printf("?Too many operands: IF - \"%s\"\n",s);
- sexprc++;
- goto xdosexp;
- }
- s2 = dosexp(p[2]);
- if (sexprc) goto xdosexp;
- if (s2) {
- j = ckatofs(s2);
- if (xxfloat(s2,0) == 2) {
- fpflag++;
- fpresult = (CKFLOAT)result;
- fpj = floatval;
- } else {
- fpj = atof(s2);
- }
- true = ((fpj != 0.0) ? 1 : 0);
- }
- if (!true && n < 4) {
- s2 = NULL;
- } else {
- s2 = dosexp(true ? p[3] : p[4]);
- if (sexprc) goto xdosexp;
- j = s2 ? ckatofs(s2) : 0;
- if (xxfloat(s2,0) == 2) {
- fpflag++;
- fpresult = (CKFLOAT)result;
- fpj = floatval;
- } else {
- fpj = s2 ? atof(s2) : 0.0;
- }
- fpresult = fpj;
- result = j;
- }
- goto xdosexp;
- } else if (x == SX_QUO) {
-#ifndef COMMENT
- int xx;
- xx = strlen(p[2]);
- p[3] = (char *)malloc(xx+4);
- s2 = p[3];
- ckmakmsg(p[3],xx+4,"'(",p[2],")",NULL);
- n++;
-#else
- s2 = p[2];
-#endif /* COMMENT */
- goto xdosexp;
- } else if (x == SX_STR) {
- int xx;
- s2 = dosexp(p[2]);
- if (sexprc) goto xdosexp;
- xx = strlen(s2);
- p[3] = (char *)malloc(xx+4);
- ckmakmsg(p[3],xx+4,"'(",s2,")",NULL);
- s2 = p[3];
- n++;
- goto xdosexp;
- }
- }
- /* Arithmetic operator or macro - Loop thru operands */
-
- quit = 0; /* Short-circuit flag. */
- if (macro && n > 1) { /* If operator is a macro */
- if (!line) { /* allocate local buffer for */
- line = (char *)malloc(SXMLEN); /* the evaluated argument list. */
- if (!line) {
- printf("?Memory allocation failure - \"%s\"\n",p[1]);
- sexprc++;
- goto xdosexp;
- }
- linelen = SXMLEN;
- /* debug(F101,"dosexp macro arg buffer","",linelen); */
- }
- linepos = 0;
- line[linepos] = NUL;
- }
- for (i = 1; ((i < n) && !sexprc && !quit); i++) { /* Loop thru operands */
- quote = 0;
- s2 = p[i+1]; /* Get operand */
- if (!s2) s2 = "";
-
-#ifdef COMMENT
- if (*s2 == '\047') { /* Is it quoted? */
- debug(F110,sexpdebug("'B"),s2,0);
- s2++; /* Space past the quote */
- quote++;
- if (*s2 == '(') { /* Quoted S-Expression? */
- char c4, * s4 = s2+1; /* Strip outer parens */
- while ((c4 = *s4++)) {
- if (c4 == ')' && !*s4) {
- s2++;
- *(s4-1) = NUL;
- break;
- }
- }
- }
- debug(F110,sexpdebug("'C"),s2,0);
-
- } else { /* Not quoted */
- s2 = dosexp(p[i+1]); /* evaluate it */
- if (sexprc) goto xdosexp;
- if (!s2) s2 = "";
- if (!macro && x == SX_EVA)
- continue;
- }
-#else
- if (*s2 != '\047') { /* Is it quoted? */
- s2 = dosexp(p[i+1]); /* No, evaluate it */
- if (sexprc) goto xdosexp;
- if (!s2) s2 = "";
- if (!macro && x == SX_EVA)
- continue;
- }
- if (*s2 == '\047') { /* Is result quoted? */
- debug(F110,sexpdebug("'B"),s2,0);
- s2++; /* Space past the quote */
- quote++;
- if (*s2 == '(') { /* Quoted S-Expression? */
- char c4, * s4 = s2+1; /* Strip outer parens */
- while ((c4 = *s4++)) {
- if (c4 == ')' && !*s4) {
- s2++;
- *(s4-1) = NUL;
- break;
- }
- }
- }
- debug(F110,sexpdebug("'C"),s2,0);
- }
-#endif /* COMMENT */
- if (macro) {
- debug(F111,sexpdebug("macro arg"),s2,i);
- if (!*s2) quote++;
- if (!quote) {
- register char c4, * s4 = s2;
- while ((c4 = *s4++)) if (c4 == SP) { quote++; break; }
- }
- if (quote) line[linepos++] = '{';
- while ((line[linepos++] = *s2++)) {
- if (linepos > linelen - 3) {
- char * tmp = NULL;
- line[linepos] = NUL;
- linelen += SXMLEN;
- tmp = (char *) malloc(linelen);
- if (!tmp) {
- printf("?Memory re-allocation failure - \"%s...\"\n",
- line);
- sexprc++;
- goto xdosexp;
- }
- strcpy(tmp,line);
- free(line);
- line = tmp;
- }
- }
- linepos--; /* Back up over NUL */
- if (quote)
- line[linepos++] = '}'; /* End quote group */
- line[linepos++] = SP; /* add a space */
- line[linepos] = NUL; /* and a NUL */
- continue;
- }
- if (!quote) { /* Built-in operator... */
- s2 = dosexp(s2);
- if (sexprc) goto xdosexp;
- if (!s2) s2 = "";
- }
- if (x == SX_EVA)
- continue;
-
- if (!*s2) {
- /* An empty value is not a legal number */
- /* but it is a legal truth value */
- if (x != SX_AND && x != SX_LOR && x != SX_NOT) {
- printf("?Not Numeric - \"%s\"\n",p[i+1]);
- sexprc++;
- goto xdosexp;
- }
- j = 0;
- fpj = 0.0;
- } else {
- j = ckatofs(s2);
- /* Switch to floating-point upon encountering any f.p. arg */
- /* OR... if integer is too big */
- if (!fpflag) if (xxfloat(s2,0) == 2)
- fpflag++;
- fpj = atof(s2);
- }
- if (i == 1) { /* Initial result is first operand */
- result = (n == 2 && x == SX_SUB) ? 0-j : j;
- fpresult = (n == 2 && x == SX_SUB) ? -fpj : fpj;
- if ((x == SX_AND && result == 0) || /* Short circuit */
- (x == SX_LOR && result != 0))
- quit++;
- if (!(kwflags & SXF_ONE)) /* Command w/single arg */
- continue;
- }
- if (x == SX_MOD || x == SX_DIV) {
- if (!result)
- fpflag++;
- if (!fpj) {
- printf("?Divide by zero - \"%s\"\n",cmdbuf);
- sexprc++;
- goto xdosexp;
- }
- }
- switch (x) { /* Accumulate result */
-
- case SX_EVA: /* EVAL */
- result = j;
- fpresult = fpj;
- break;
-
- case SX_ADD: /* + */
- result += j;
- fpresult += fpj;
-#ifdef FNFLOAT
- if (result != fpresult)
- fpflag++;
-#endif /* FNFLOAT */
- break;
-
- case SX_SUB: /* - */
- result -= j;
- fpresult -= fpj;
-#ifdef FNFLOAT
- if (result != fpresult)
- fpflag++;
-#endif /* FNFLOAT */
- break;
-
- case SX_MUL: /* * */
- result *= j;
- fpresult *= fpj;
-#ifdef FNFLOAT
- if (result != fpresult)
- fpflag++;
-#endif /* FNFLOAT */
- break;
-
- case SX_AND: /* AND */
- result = result && j;
- if (!result) quit++;
- fpresult = fpresult && fpj;
- break;
-
- case SX_LOR: /* OR */
- result = result || j;
- if (!result) quit++;
- fpresult = fpresult || fpj;
- break;
-
- case SX_MOD: /* Modulus */
- result = result % j;
-#ifdef FNFLOAT
- fpresult = (CKFLOAT)fmod(fpresult,fpj);
- if (result != fpresult)
- fpflag++;
-#else
- fpresult = result;
-#endif /* FNFLOAT */
- break;
-
- case SX_DIV: /* / */
- if (j) {
- result /= j;
- fpresult /= fpj;
-#ifdef FNFLOAT
- if (result != fpresult)
- fpflag++;
-#endif /* FNFLOAT */
- } else {
- fpresult /= fpj;
- result = fpj;
-#ifdef FNFLOAT
- fpflag++;
-#endif /* FNFLOAT */
- }
- break;
-
- case SX_AEQ: /* Test for equality */
- if (fpflag) {
- if (fpresult != fpj)
- presult = 0;
- } else {
- if (result != j)
- presult = 0;
- }
- break;
-
- case SX_NEQ: /* Test for ineqality */
- if (fpflag) {
- if (fpresult == fpj)
- presult = 0;
- } else {
- if (result == j)
- presult = 0;
- }
- break;
-
- case SX_ALE: /* Arithmetic less-equal */
- if (fpflag) {
- if (fpj < fpresult)
- presult = 0;
- fpresult = fpj;
- } else {
- if (j < result)
- presult = 0;
- result = j;
- }
- break;
-
- case SX_ALT: /* Arithmetic less-than */
- if (fpflag) {
- if (fpj <= fpresult)
- presult = 0;
- fpresult = fpj;
- } else {
- if (j <= result)
- presult = 0;
- result = j;
- }
- break;
-
- case SX_AGT: /* Arithmetic greater-than */
- if (fpflag) {
- if (fpj >= fpresult)
- presult = 0;
- fpresult = fpj;
- } else {
- if (j >= result)
- presult = 0;
- result = j;
- }
- break;
-
- case SX_AGE: /* Arithmetic greater-equal */
- if (fpflag) {
- if (fpj > fpresult)
- presult = 0;
- fpresult = fpj;
- } else {
- if (j > result)
- presult = 0;
- result = j;
- }
- break;
-
- case SX_POW: /* Raise to power */
-#ifdef FNFLOAT
- {
- double dummy;
- if (!fpj) {
- fpresult = 1.0;
- } else if ((!fpresult && fpj <= 0.0)) {
- printf("?Divide by zero - \"%s\"\n",cmdbuf);
- sexprc++;
- goto xdosexp;
- } else if (fpresult < 0.0 && modf(fpj,&dummy)) {
- printf("?Domain error - \"%s\"\n",cmdbuf);
- sexprc++;
- goto xdosexp;
- } else {
- fpresult = (CKFLOAT)pow(fpresult,fpj);
- }
- }
-#endif /* FNFLOAT */
- if (j == 0) {
- result = 1;
- } else {
- CK_OFF_T z, sign = 0;
- if (j < 0) {
- if (result == 0) {
- printf("?Divide by zero - \"%s\"\n",cmdbuf);
- sexprc++;
- goto xdosexp;
- }
- j = 0 - j;
- sign++;
- }
- z = result;
- while (--j > 0)
- result *= z;
- if (sign)
- result = 1 / result;
- }
-#ifdef FNFLOAT
- if (result != fpresult)
- fpflag++;
-#endif /* FNFLOAT */
- break;
-
-#ifdef FNFLOAT
- case SX_EXP: /* e to the given power */
- fpresult = (CKFLOAT) exp(fpj);
- break;
-
- case SX_LGN: /* Natural log */
- case SX_LGX: /* Log base 10 */
- case SX_SQR: /* Square root */
- if (fpj < 0.0) {
- printf("?Argument out of range - \"%s\"\n",cmdbuf);
- sexprc++;
- goto xdosexp;
- }
- if (x == SX_SQR)
- fpresult = (CKFLOAT) sqrt(fpj);
- else if (x == SX_LGN)
- fpresult = (CKFLOAT) log(fpj);
- else
- fpresult = (CKFLOAT) log10(fpj);
- break;
-
- case SX_SIN: /* sine */
- fpresult = (CKFLOAT) sin(fpj);
- break;
-
- case SX_COS: /* cosine */
- fpresult = (CKFLOAT) cos(fpj);
- break;
-
- case SX_TAN: /* tangent */
- fpresult = (CKFLOAT) tan(fpj);
- break;
-#endif /* FNFLOAT */
-
- case SX_CEI: /* Ceiling */
- if (j != fpj)
- if (fpj > 0.0)
- fpj += 1.0;
- fpresult = fpj;
- fpflag = 1;
- truncate = 1;
- break;
-
- case SX_FLR: /* Floor */
- if (j != fpj)
- if (fpj < 0.0)
- fpj -= 1.0;
- fpresult = fpj;
- fpflag = 1;
- truncate = 1;
- break;
-
- case SX_TRU: /* Truncate */
- fpresult = fpj;
- fpflag = 1;
- truncate = 1;
- break;
-
- case SX_ABS: /* Absolute value */
- result = (j < 0) ? 0 - j : j;
-#ifdef FNFLOAT
- fpresult = (fpj < 0.0) ? 0.0 - fpj : fpj;
- if (result != fpresult)
- fpflag++;
-#endif /* FNFLOAT */
- break;
-
- case SX_MAX: /* Max */
- if (j != fpj)
- fpflag++;
- if (fpflag) {
- if (fpj > fpresult)
- fpresult = fpj;
- } else
- if (j > result)
- result = j;
- break;
-
- case SX_MIN: /* Min */
- if (j != fpj)
- fpflag++;
- if (fpflag) {
- if (fpj < fpresult)
- fpresult = fpj;
- } else
- if (j < result)
- result = j;
- break;
-
- case SX_FLO: /* Float */
- fpflag++;
- fpresult = result;
- fpj = j;
- break;
-
- case SX_NOT: /* NOT (reverse truth value) */
- fpflag = 0;
- not++;
- break;
-
- case SX_BWA: /* Bitwise AND */
- fpflag = 0;
- result &= j;
- break;
-
- case SX_BWO: /* Bitwise OR */
- fpflag = 0;
- result |= j;
- break;
-
- case SX_BWX: /* Bitwise XOR */
- case SX_XOR: /* Logical XOR */
- if (n > 3) {
- printf("?Too many operands - \"%s\"\n",s);
- sexprc++;
- goto xdosexp;
- }
- fpflag = 0;
- if (x == SX_BWX) {
- result ^= j;
- } else {
- result = (result && !j) || (!result && j);
- if (result) result = 1;
- }
- break;
-
- case SX_BWN: /* Bitwise Not */
- fpflag = 0;
- result = ~result;
- break;
-
- default:
- printf("BAD OP [%s]\n",p[1]);
- sexprc++;
- }
- }
- if (!pflag) /* Not a predicate */
- sexppv = -1; /* So unset this */
-
- /* domacro: */
-
- if (macro) { /* User-defined macro */
- extern int fsexpflag; /* (see fneval():ckuus4.c) */
- int lookagain = 0; /* Maybe the macro table changed */
- if (mactab[mx].kwd) { /* Check and see */
- if (ckstrcmp(mactab[mx].kwd,p[1],-1,0))
- lookagain++;
- } else
- lookagain++;
- if (lookagain) { /* The table changed */
- mx = mxlook(mactab,p[1],nmac); /* Get the macro's new index */
- debug(F111,sexpdebug("macro moved"),p[1],mx);
- if (mx < 0) { /* Yikes! */
- printf("?Macro disappeared! - \"%s\"\n",p[1]);
- sexprc++;
- goto xdosexp;
- }
- }
- debug(F111,sexpdebug("macro mx"),mactab[mx].kwd,mx);
- if (fsexpflag) { /* If embedded in a function call */
- if (cmpush() > -1) { /* get a new copy of the parsing */
- extern int ifc; /* environment, */
- int k, ifcsav = ifc; /* save the IF state */
- dodo(mx,line,0); /* Set up the macro */
- k = parser(1); /* Call the parser to execute it */
- cmpop(); /* Pop back to previous level */
- ifc = ifcsav; /* restore IF state */
- if (k == 0) /* If no error */
- s2 = mrval[maclvl+1]; /* get return value, if any */
- if (!s2) s2 = "";
- debug(F110,sexpdebug("macro return"),s2,0);
- } else {
- printf("?Resources exhausted - \"%s\"\n",s);
- sexprc++;
- }
- } else { /* Not embedded in a function call */
- dodo(mx,line,0); /* As above but without cmpush/pop() */
- k = parser(1);
- if (k == 0)
- s2 = mrval[maclvl+1];
- if (!s2) s2 = "";
- }
- } else if (pflag) { /* Predicate */
- if (not) presult = presult ? 0 : 1;
- sexppv = presult; /* So set predicate value (0 or 1) */
- s2 = presult ? "1" : "0";
- } else if (fpflag && !sexptrunc) { /* Result is floating-point */
- if (not) fpresult = fpresult ? 0.0 : 1.0;
- s2 = fpformat(fpresult,0,0);
- } else if (x != SX_EVA) {
- if (not) result = result ? 0 : 1;
- s2 = ckfstoa(result);
- }
-
-/* Common exit point. Always come here to exit. */
-
- xdosexp:
-
- if (!s2) s2 = "";
- if (!sexprc && s2) { /* Have a result */
- char * sx;
- char * q2 = s2; int xx = 0;
- if (*s2) {
- while (*q2++) xx++; /* Get length */
- if (xx > sexprmax) /* (stats) */
- sexprmax = xx;
- } else
- xx = 0;
- if (xx > sxrlen[sexpdep] || !sxresult[sexpdep]) {
- int k;
- k = xx + xx / 4;
- if (k < 32) k = 32;
- if (sxresult[sexpdep])
- free(sxresult[sexpdep]);
- if ((sxresult[sexpdep] = (char *)malloc(k))) {
- sxrlen[sexpdep] = k;
- } else {
- printf("?Memory allocation failure - \"%s\"\n",s2);
- sexprc++;
- }
- }
- sx = sxresult[sexpdep]; /* Point to result buffer */
- while ((*sx++ = *s2++)) ; /* copy result. */
- if (fpflag && truncate) { /* Floating point + truncate */
- sx = sxresult[sexpdep]; /* at decimal point */
- for (i = xx - 1; i >= 0; i--) {
- if (sx[i] == '.') {
- sx[i] = NUL;
- if (i == 0) { /* If nothing left */
- sx[0] = '0'; /* put a zero. */
- sx[1] = NUL;
- }
- }
- }
- }
- }
- if (line) /* If macro arg buffer allocated */
- free(line); /* free it. */
- if (mustfree) { /* And free local copy of split list */
- for (i = 1; i <= n; i++) {
- if (p[i]) free(p[i]);
- }
- }
- debug(F111,sexpdebug("exit"),sxresult[sexpdep],sexprc);
- return(sxresult[sexpdep--]);
-}
-#endif /* NOSEXP */
-#endif /* NOSPL */
-
-int /* CHECK command */
-dochk() {
- int x, y;
- if ((y = cmkey(ftrtab,nftr,"","",xxstring)) < 0)
- return(y);
- ckstrncpy(line,atmbuf,LINBUFSIZ);
- if ((y = cmcfm()) < 0)
- return(y);
-#ifndef NOPUSH
- if (!ckstrcmp(line,"push",(int)strlen(line),0)) {
- if (msgflg) /* If at top level... */
- printf(" push%s available\n", nopush ? " not" : "");
- else if (nopush && !backgrd)
- printf(" CHECK: push not available\n");
- return(success = 1 - nopush);
- }
-#endif /* NOPUSH */
-#ifdef PIPESEND
- if (!ckstrcmp(line,"pipes",(int)strlen(line),0)) {
- if (msgflg) /* If at top level... */
- printf(" pipes%s available\n",
- (nopush || protocol != PROTO_K) ? " not" : "");
- else if ((nopush || protocol != PROTO_K) && !backgrd)
- printf(" CHECK: pipes not available\n");
- return(success = 1 - nopush);
- }
-#endif /* PIPESEND */
- y = lookup(ftrtab,line,nftr,&x); /* Look it up */
- debug(F111,"dochk",ftrtab[x].kwd,y);
- if (msgflg) /* If at top level... */
- printf(" %s%s available\n", ftrtab[x].kwd, y ? " not" : "");
- else if (y && !backgrd)
- printf(" CHECK: %s not available\n", ftrtab[x].kwd);
- return(success = 1 - y);
-}
-
-#ifndef NOLOCAL
-#ifdef CKLOGDIAL
-
-/* Connection log and elapsed-time reporting */
-
-extern char cxlogbuf[]; /* Log record buffer */
-extern char diafil[]; /* Log file name */
-extern int dialog, cx_active; /* Flags */
-static long cx_prev = 0L; /* Elapsed time of previous session */
-
-#endif /* CKLOGDIAL */
-#endif /* NOLOCAL */
-
-VOID
-dologend() { /* Write record to connection log */
-#ifdef LOCUS
- extern int locus, autolocus;
-#endif /* LOCUS */
-
-#ifndef NOLOCAL
-#ifdef CKLOGDIAL
- long d1, d2, t1, t2;
- char buf[32], * p;
-#endif /* CKLOGDIAL */
-#endif /* NOLOCAL */
-
-#ifdef LOCUS
- if (autolocus) {
- int x = locus;
-#ifdef NEWFTP
- debug(F101,"dologend ftpisconnected","",ftpisconnected());
- setlocus(ftpisconnected() ? 0 : 1, 1);
-#else
- setlocus(1,1);
-#endif /* NEWFTP */
- }
-#endif /* LOCUS */
-
-#ifndef NOLOCAL
-#ifdef CKLOGDIAL
- debug(F101,"dologend dialog","",dialog);
- debug(F101,"dologend cxlogbuf[0]","",cxlogbuf[0]);
-#ifdef CKSYSLOG
- debug(F101,"dologend ckxlogging","",ckxlogging);
-#endif /* CKSYSLOG */
-
- if (!cx_active || !cxlogbuf[0]) /* No active record */
- return;
-
- cx_active = 0; /* Record is not active */
- debug(F111,"dologend cxlogbuf 1",cxlogbuf,cx_active);
-
- d1 = mjd((char *)cxlogbuf); /* Get start date of this session */
- ckstrncpy(buf,ckdate(),31); /* Get current date */
- d2 = mjd(buf); /* Convert them to mjds */
- p = cxlogbuf; /* Get start time */
- p[11] = NUL;
- p[14] = NUL; /* Convert to seconds */
- t1 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
- p[11] = ':';
- p[14] = ':';
- p = buf; /* Get end time */
- p[11] = NUL;
- p[14] = NUL;
- t2 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
- t2 = ((d2 - d1) * 86400L) + (t2 - t1); /* Compute elapsed time */
- debug(F101,"dologend t2","",t2);
- if (t2 > -1L) {
- cx_prev = t2;
- p = hhmmss(t2);
- debug(F110,"dologend hhmmss",p,0);
- ckstrncat(cxlogbuf,"E=",CXLOGBUFL); /* Append to log record */
- ckstrncat(cxlogbuf,p,CXLOGBUFL);
- debug(F110,"dologend cxlogbuf 2",cxlogbuf,0);
- } else
- cx_prev = 0L;
- debug(F101,"dologend cx_prev","",cx_prev);
- if (dialog) { /* If logging */
- int x;
- x = diaopn(diafil,1,1); /* Open log in append mode */
- debug(F101,"dologend diaopn","",x);
- x = zsoutl(ZDIFIL,cxlogbuf); /* Write the record */
- debug(F101,"dologend zsoutl","",x);
- x = zclose(ZDIFIL); /* Close the log */
- debug(F101,"dologend zclose","",x);
- }
-#ifdef CKSYSLOG
- debug(F101,"dologend ckxlogging","",ckxlogging);
- if (ckxlogging) {
- int x;
- x = ckindex("T=DIAL",cxlogbuf,0,0,1);
- debug(F111,"dologend ckxsyslog",cxlogbuf,ckxsyslog);
- debug(F111,"dologend ckindex","T=DIAL",x);
- if (x > 0) {
- if (ckxsyslog >= SYSLG_DI) {
- debug(F110,"dologend syslog",cxlogbuf+18,0);
- cksyslog(SYSLG_DI,1,"CONNECTION",(char *)(cxlogbuf+18),"");
- } else if (ckxsyslog >= SYSLG_AC) {
- debug(F110,"dologend syslog",cxlogbuf+18,0);
- cksyslog(SYSLG_AC,1,"CONNECTION",(char *)(cxlogbuf+18),"");
- }
- }
- }
-#endif /* CKSYSLOG */
-#endif /* CKLOGDIAL */
-#endif /* NOLOCAL */
-}
-
-#ifndef NOLOCAL
-#ifdef CKLOGDIAL
-
-/* D O L O G S H O W -- Show session/connection info */
-
-/* Call with fc == 1 to show, fc == 0 to only calculate. */
-/* Returns session elapsed time in seconds. */
-/* If no session active, returns elapsed time of previous session, if any, */
-/* otherwise 0 */
-
-long
-dologshow(fc) int fc; { /* SHOW (current) CONNECTION */
- long d1, d2, t1, t2 = 0, prev;
- char c, buf1[32], buf2[32], * info[32], * p, * s;
- char * xlogbuf, xbuf[CXLOGBUFL+1];
- int i, x = 0, z, ftp = 0, active = 0;
-
-#ifdef NEWFTP
- extern char ftplogbuf[];
- extern long ftplogprev;
- extern int ftplogactive;
- if (fc & W_FTP) {
- fc &= 63;
- ftp = 1;
- xlogbuf = ftplogbuf;
- prev = ftplogprev;
- active = ftplogactive;
- } else {
-#endif /* NEWFTP */
- ftp = 0;
- xlogbuf = cxlogbuf;
- prev = cx_prev;
- active = cx_active;
-#ifdef NEWFTP
- }
-#endif /* NEWFTP */
-
- debug(F101,"dologshow local","",local);
- debug(F101,"dologshow ftp","",ftp);
- debug(F111,"dologshow active",xlogbuf,active);
-
- if (!xlogbuf[0]) {
- if (fc) {
- if (didsetlin || ftp)
- printf(" %s: No record.\n", ftp ? "FTP" : "Kermit");
- else
- printf(" %s: No connection.\n", ftp ? "FTP" : "Kermit");
- }
- return(prev);
- }
-
-#ifdef NEWFTP
- if (ftp) {
- z = ftpisconnected() ? 1 : -1;
- } else {
-#endif /* NEWFTP */
- if (local) { /* See if we have an open connection */
- z = ttchk();
- debug(F101,"dologshow ttchk","",z);
- z = (z > -1) ? 1 : -2;
- } else {
- z = active ? 1 : -2;
- }
-#ifdef NEWFTP
- }
-#endif /* NEWFTP */
- if (z < 0L) {
- if (!fc)
- return(prev);
- else
- t2 = prev;
- }
- /* Note: NOT ckstrncpy! */
- strncpy(buf1,xlogbuf,17); /* Copy of just the timestamp */
- buf1[17] = NUL; /* Terminate it */
- ckstrncpy(xbuf,xlogbuf+18,CXLOGBUFL); /* Copy that can be poked */
- debug(F111,"dologshow prev",xbuf,prev);
-
- xwords(xbuf,31,info,1); /* Break up into fields */
- d1 = mjd(buf1); /* Convert start time to MJD */
- ckstrncpy(buf2,ckdate(),31); /* Current date */
- d2 = mjd(buf2); /* Convert to MJD */
- p = buf1; /* Point to start time */
- p[11] = NUL;
- p[14] = NUL; /* Convert to seconds */
- t1 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
- p[11] = ':';
- p[14] = ':';
- p = buf2; /* Ditto for current time */
- p[11] = NUL;
- p[14] = NUL;
- if (z > -1L) {
- t2 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
- t2 = ((d2 - d1) * 86400L) + (t2 - t1); /* Elapsed time so far */
- }
- if (fc) {
- p = NULL;
- if (t2 > -1L) /* Convert seconds to hh:mm:ss */
- p = hhmmss(t2);
- if (z > -1)
- s = "Active";
- else if (z == -2)
- s = "Closed";
- else
- s = "Unknown";
- printf("\n"); /* Show results */
- printf(" Status: %s\n",s);
- printf(" Opened: %s\n",buf1);
- printf(" User: %s\n",info[1] ? info[1] : "");
- printf(" PID: %s\n",info[2] ? info[2] : "");
- for (i = 3; info[i]; i++) {
- c = info[i][0];
- s = (info[i]) ? info[i]+2 : "";
- switch (c) {
- case 'T': printf(" Type: %s\n", s); break;
- case 'N': printf(" To: %s\n", s); break;
- case 'P': printf(" Port: %s\n", s); break;
- case 'H': printf(" From: %s\n", s); break;
- case 'D': printf(" Device: %s\n", s); break;
- case 'O': printf(" Origin: %s\n", s); break;
- case 'E': break;
- default: printf(" %s\n",info[i] ? info[i] : "");
- }
- }
- if (z < 0L)
- printf(" Elapsed time: %s\n", hhmmss(t2));
- else
- printf(" Elapsed time: %s\n", p ? p : "(unknown)");
- x = 0;
-#ifdef NETCONN
-#ifdef SSHBUILTIN
- if ( IS_SSH() ) x++;
-#endif /* SSHBUILTIN */
-#ifdef CK_ENCRYPTION
- if (ck_tn_encrypting() && ck_tn_decrypting()) x++;
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- if (tls_active_flag || ssl_active_flag) x++;
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
-#ifdef CK_ENCRYPTION
- if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN) x++;
-#endif /* CK_ENCRYPTION */
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
-#endif /* NETCONN */
- if (z > 0)
- printf(" Encrypted: %s\n", x ? "Yes" : "No");
- printf(" Log: %s\n", dialog ? diafil : "(none)");
- printf("\n");
- }
- return(t2 > -1L ? t2 : 0L);
-}
-
-VOID
-dologline() {
- char * p;
- int n, m = 0;
-
- dologend(); /* Previous session not closed out? */
- cx_active = 1; /* Record is active */
- cx_prev = 0L;
- p = ckdate(); /* Get timestamp */
- n = ckstrncpy(cxlogbuf,p,CXLOGBUFL-1); /* Start record off with it */
- if (!uidbuf[0]) {
- debug(F100,"dologline uidbuf empty","",0);
-#ifdef UNIX /* Who has whoami()... */
- ckstrncpy(uidbuf,(char *)whoami(),UIDBUFLEN);
-#else
-#ifdef STRATUS
- ckstrncpy(uidbuf,(char *)whoami(),UIDBUFLEN);
-#else
- ckstrncpy(uidbuf,"UNKNOWN",UIDBUFLEN);
-#endif /* STRATUS */
-#endif /* UNIX */
- }
- m = strlen(uidbuf) + strlen(myhost) + strlen(ttname) + 32;
- if (n+m < CXLOGBUFL-1) { /* Add serial device info */
- p = cxlogbuf+n;
- sprintf(p," %s %s T=SERIAL H=%s D=%s ", /* SAFE */
- uidbuf,
- ckgetpid(),
- myhost,
- ttname
- );
- } else
- ckstrncpy(cxlogbuf,"LOGLINE BUFFER OVERFLOW",CXLOGBUFL);
- debug(F110,"dologline",cxlogbuf,0);
-}
-
-#ifdef NETCONN
-VOID
-dolognet() {
- char * p, * s = "NET", * uu = uidbuf;
- char * port = "";
- int n, m, tcp = 0;
- char * h = NULL;
-
- dologend(); /* Previous session not closed out? */
- cx_prev = 0L;
- cx_active = 1; /* Record is active */
- p = ckdate();
- n = ckstrncpy(cxlogbuf,p,CXLOGBUFL);
-#ifdef TCPSOCKET
- if (nettype == NET_TCPB || nettype == NET_TCPA) {
- tcp++;
- s = "TCP";
- } else if (nettype == NET_SSH) {
- s = "SSH";
- tcp++;
- }
-#endif /* TCPSOCKET */
-#ifdef ANYX25
- if (nettype == NET_SX25 || nettype == NET_VX25 || nettype == NET_IX25)
- s = "X25";
-#endif /* ANYX25 */
-#ifdef DECNET
- if (nettype == NET_DEC)
- s = "DECNET";
-#endif /* DECNET */
-#ifdef SUPERLAT
- if (nettype == NET_SLAT)
- s = "SUPERLAT";
-#endif /* SUPERLAT */
-#ifdef CK_NETBIOS
- if (nettype == NET_BIOS)
- s = "NETBIOS";
-#endif /* CK_NETBIOS */
-
- if (!uu[0]) {
- debug(F100,"dolognet uidbuf empty","",0);
-#ifdef OS2ORUNIX /* Who has whoami()... */
- uu = (char *)whoami();
-#else
-#ifdef STRATUS
- uu = (char *)whoami();
-#else
- uu = "UNKNOWN";
-#endif /* STRATUS */
-#endif /* UNIX */
- }
-#ifdef TCPSOCKET
- if (tcp) {
- int k;
- makestr(&h,myhost);
- if ((k = ckindex(":",h,0,0,0)) > 0) {
- h[k-1] = NUL;
- port = &h[k];
- } else {
- int svcnum = gettcpport();
- if (svcnum > 0)
- port = ckitoa(svcnum);
- else
- port = "unk";
- }
- }
-#endif /* TCPSOCKET */
- m = strlen(uu) + strlen(myhost) + strlen(ttname) + strlen(s) + 32;
- if (n+m < CXLOGBUFL-1) { /* SAFE */
- p = cxlogbuf+n;
- sprintf(p," %s %s T=%s N=%s H=%s P=%s ",
- uu,
- ckgetpid(),
- s,
- ttname,
- myhost,
- port
- );
- } else
- ckstrncpy(cxlogbuf,"LOGNET BUFFER OVERFLOW",CXLOGBUFL);
- debug(F110,"dolognet cxlogbuf",cxlogbuf,0);
- if (h) makestr(&h,NULL);
-}
-#endif /* NETCONN */
-#endif /* CKLOGDIAL */
-
-#ifndef NODIAL
-/*
- Parse a DIAL-related string, stripping enclosing braces, if any.
-*/
-static int
-dialstr(p,msg) char **p; char *msg; {
- int x;
- char *s;
-
- if ((x = cmtxt(msg, "", &s, xxstring)) < 0)
- return(x);
- s = brstrip(s); /* Strip braces around. */
- debug(F110,"dialstr",s,0);
- makestr(p,*s?s:NULL);
- return(success = 1);
-}
-
-VOID
-initmdm(x) int x; {
- MDMINF * p;
- int m;
-
- mdmtyp = x; /* Set global modem type */
- debug(F101,"initmdm mdmtyp","",mdmtyp);
- debug(F101,"initmdm usermdm","",usermdm);
- if (x < 1) return;
-
- m = usermdm ? usermdm : mdmtyp;
-
- p = modemp[m]; /* Point to modem info struct, and */
- /* debug(F101,"initmdm p","",p); */
- if (p) {
- dialec = p->capas & CKD_EC; /* set DIAL ERROR-CORRECTION, */
- dialdc = p->capas & CKD_DC; /* DIAL DATA-COMPRESSION, and */
- mdmspd = p->capas & CKD_SB ? 0 : 1; /* DIAL SPEED-MATCHING from it. */
- dialfc = FLO_AUTO; /* Modem's local flow control.. */
- dialmax = p->max_speed;
- dialcapas = p->capas;
- dialesc = p->esc_char;
- } else if (mdmtyp > 0) {
- printf("WARNING: modem info for \"%s\" not filled in yet\n",
- gmdmtyp()
- );
- }
-
-/* Reset or set the SET DIAL STRING items ... */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"initmdm dialini",dialini,0);
- debug(F110,"initmdm dialmstr ",dialmstr,0);
- debug(F110,"initmdm dialmprmt",dialmprmt,0);
- debug(F110,"initmdm dialcmd",dialcmd,0);
- debug(F110,"initmdm dialdcon",dialdcon,0);
- debug(F110,"initmdm dialdcoff",dialdcoff,0);
- debug(F110,"initmdm dialecon",dialecon,0);
- debug(F110,"initmdm dialecoff",dialecoff,0);
- debug(F110,"initmdm dialhcmd",dialhcmd,0);
- debug(F110,"initmdm dialhwfc",dialhwfc,0);
- debug(F110,"initmdm dialswfc",dialswfc,0);
- debug(F110,"initmdm dialnofc",dialnofc,0);
- debug(F110,"initmdm dialtone",dialtone,0);
- debug(F110,"initmdm dialpulse",dialpulse,0);
- debug(F110,"initmdm dialname",dialname,0);
- debug(F110,"initmdm dialaaon",dialaaon,0);
- debug(F110,"initmdm dialaaoff",dialaaoff,0);
- debug(F110,"initmdm dialx3",dialx3,0);
- debug(F110,"initmdm dialspon",dialspon,0);
- debug(F110,"initmdm dialspoff",dialspoff,0);
- debug(F110,"initmdm dialvol1",dialvol1,0);
- debug(F110,"initmdm dialvol2",dialvol2,0);
- debug(F110,"initmdm dialvol3",dialvol3,0);
- debug(F110,"initmdm dialini2",dialini2,0);
- }
-#endif /* DEBUG */
-
- if (usermdm && p) { /* USER-DEFINED: copy info from specified template */
-
- makestr(&dialini ,p->wake_str);
- makestr(&dialmstr ,p->dmode_str);
- makestr(&dialmprmt,p->dmode_prompt);
- makestr(&dialcmd ,p->dial_str);
- makestr(&dialdcon ,p->dc_on_str);
- makestr(&dialdcoff,p->dc_off_str);
- makestr(&dialecon ,p->ec_on_str);
- makestr(&dialecoff,p->ec_off_str);
- makestr(&dialhcmd ,p->hup_str);
- makestr(&dialhwfc ,p->hwfc_str);
- makestr(&dialswfc ,p->swfc_str);
- makestr(&dialnofc ,p->nofc_str);
- makestr(&dialtone ,p->tone);
- makestr(&dialpulse,p->pulse);
- makestr(&dialname ,"This space available (use SET MODEM NAME)");
- makestr(&dialaaon ,p->aa_on_str);
- makestr(&dialaaoff,p->aa_off_str);
- makestr(&dialx3 ,p->ignoredt);
- makestr(&dialspon ,p->sp_on_str);
- makestr(&dialspoff,p->sp_off_str);
- makestr(&dialvol1 ,p->vol1_str);
- makestr(&dialvol2 ,p->vol2_str);
- makestr(&dialvol3 ,p->vol3_str);
- makestr(&dialini2 ,p->ini2);
-
- } else { /* Not user-defined, so wipe out overrides */
-
- if (dialini) makestr(&dialini,NULL); /* Init-string */
- if (dialmstr) makestr(&dialmstr,NULL); /* Dial-mode-str */
- if (dialmprmt) makestr(&dialmprmt,NULL); /* Dial-mode-pro */
- if (dialcmd) makestr(&dialcmd,NULL); /* Dial-command */
- if (dialdcon) makestr(&dialdcon,NULL); /* DC ON command */
- if (dialdcoff) makestr(&dialdcoff,NULL); /* DC OFF command */
- if (dialecon) makestr(&dialecon,NULL); /* EC ON command */
- if (dialecoff) makestr(&dialecoff,NULL); /* EC OFF command */
- if (dialhcmd) makestr(&dialhcmd,NULL); /* Hangup command */
- if (dialhwfc) makestr(&dialhwfc,NULL); /* Flow control... */
- if (dialswfc) makestr(&dialswfc,NULL); /* */
- if (dialnofc) makestr(&dialnofc,NULL); /* */
- if (dialtone) makestr(&dialtone,NULL); /* Dialing method */
- if (dialpulse) makestr(&dialpulse,NULL); /* */
- if (dialname) makestr(&dialname,NULL); /* Modem name */
- if (dialaaon) makestr(&dialaaon,NULL); /* Autoanswer On */
- if (dialaaoff) makestr(&dialaaoff,NULL); /* Autoanswer Off */
- if (dialx3) makestr(&dialx3,NULL); /* Ignore dialtone */
- if (dialspon) makestr(&dialspon,NULL); /* Speaker On */
- if (dialspoff) makestr(&dialspoff,NULL); /* Speaker Off */
- if (dialvol1) makestr(&dialvol1,NULL); /* Low volume */
- if (dialvol2) makestr(&dialvol2,NULL); /* Medium volume */
- if (dialvol3) makestr(&dialvol3,NULL); /* High volume */
- if (dialini2) makestr(&dialini2,NULL); /* Init string 2 */
- }
- if (autoflow) /* Maybe change flow control */
- setflow();
-
-#ifndef MINIDIAL
-#ifdef OLDTBCODE
- tbmodel = 0; /* If it's a Telebit, we don't know the model yet */
-#endif /* OLDTBCODE */
-#endif /* MINIDIAL */
-}
-
-#ifdef COMMENT
-/* Not implemented yet */
-int
-setanswer() {
- int x, y;
- extern int ans_cid, ans_ring;
- if ((x = cmkey(answertab,nanswertab,"","",xxstring)) < 0)
- return(x);
- switch (x) {
- case XYA_CID:
- return(seton(&ans_cid));
- case XYA_RNG:
- y = cmnum("How many rings before answering","1",10,&x,xxstring);
- y = setnum(&ans_rings,x,y,254);
- return(y);
- }
-}
-#endif /* COMMENT */
-
-int
-setmodem() { /* SET MODEM */
-
- int x, y, z;
- long zz;
- struct FDB k1, k2;
- extern int mdmset;
-
- cmfdbi(&k1,_CMKEY,
- "Modem parameter","","",nsetmdm, 0, xxstring, setmdm, &k2);
- cmfdbi(&k2,_CMKEY,"","","",nmdm,0,xxstring,mdmtab,NULL);
- x = cmfdb(&k1);
- if (x < 0) { /* Error */
- if (x == -2 || x == -9)
- printf("?No keywords match: \"%s\"\n",atmbuf);
- return(x);
- }
- y = cmresult.nresult; /* Keyword value */
- if (cmresult.fdbaddr == &k2) { /* Modem-type keyword table */
- if ((x = cmcfm()) < 0)
- return(x);
- usermdm = 0;
- initmdm(cmresult.nresult); /* Set the modem type. */
- return(success = 1); /* Done */
- }
- switch (cmresult.nresult) { /* SET MODEM keyword table. */
-#ifdef MDMHUP
- case XYDMHU: /* DIAL MODEM-HANGUP */
- if ((y = cmkey(mdmhang,4,"how to hang up modem",
- "modem-command", xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- dialmhu = y;
-#ifdef COMMENT
-/* Nope, I fixed it (2001 11 08) */
-#ifdef CK_SCOV5
- if (dialmhu == 0 && !quiet) {
- printf(
-"\n WARNING: RS-232 signal sampling and manipulation do not work\n"
- );
- printf(
-" in the standard SCO OSR5 serial i/o drivers. SET MODEM HANGUP-METHOD\n"
- );
- printf(
-" MODEM-COMMAND is recommended for OSR5.\n\n"
- );
- }
-#endif /* CK_SCOV5 */
-#endif /* COMMENT */
- return(success = 1);
-#endif /* MDMHUP */
-
- case XYDCAP:
- zz = 0L;
- y = 0;
- while (y != -3) {
- if ((y = cmkey(mdmcap,nmdmcap,
- "capability of modem", "", xxstring)) < 0) {
- if (y == -3)
- break;
- else
- return(y);
- }
- zz |= y;
- }
- if ((x = cmcfm()) < 0)
- return(x);
- dialcapas = zz;
- debug(F101,"setmodem autoflow","",autoflow);
- debug(F101,"setmodem flow 1","",flow);
- if (autoflow) /* Maybe change flow control */
- setflow();
- debug(F101,"setmodem flow 2","",flow);
- mdmspd = zz & CKD_SB ? 0 : 1; /* Set MODEM SPEED-MATCHING from it. */
- return(success = 1);
-
- case XYDMAX:
-#ifdef TN_COMPORT
- if (network && istncomport())
- x = cmkey(tnspdtab,ntnspd,line,"",xxstring);
- else
-#endif /* TN_COMPORT */
- x = cmkey(spdtab,nspd,line,"",xxstring);
- if (x < 0) {
- if (x == -3) printf("?value required\n");
- return(x);
- }
- if ((y = cmcfm()) < 0) return(y);
- dialmax = (long) x * 10L;
- if (dialmax == 70) dialmax = 75;
- return(success = 1);
-
- case XYDSTR: /* These moved from SET DIAL */
- case XYDDC:
- case XYDEC:
- case XYDESC:
- case XYDFC:
- case XYDKSP:
- case XYDSPD:
- case XYDDIA:
- return(setdial(x));
-
- case XYDTYP:
- if ((y = cmkey(mdmtab,nmdm,"modem type","none", xxstring)) < 0)
- return(y);
- if (y == dialudt) { /* User-defined modem type */
- if ((x = cmkey(mdmtab,nmdm,"based on existing modem type",
- "unknown", xxstring)) < 0)
- return(x);
- }
- if ((z = cmcfm()) < 0)
- return(z);
- usermdm = 0;
- usermdm = (y == dialudt) ? x : 0;
- initmdm(y);
- mdmset = (mdmtyp > 0);
- return(success = 1);
-
- case XYDNAM:
- return(dialstr(&dialname,"Descriptive name for modem"));
-
- case XYDMCD: /* SET MODEM CARRIER-WATCH */
- return(setdcd());
-
- case XYDSPK: /* SET MODEM SPEAKER */
- return(seton(&mdmspk));
-
- case XYDVOL: /* SET MODEM VOLUME */
- if ((x = cmkey(voltab,3,"","medium",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- mdmvol = x;
- return(success = 1);
-
- default:
- printf("Unexpected SET MODEM parameter\n");
- return(-9);
- }
-}
-
-static int /* Set DIAL command options */
-setdial(y) int y; {
- int x = 0, z = 0;
- char *s = NULL;
-
- if (y < 0)
- if ((y = cmkey(dialtab,ndial,"","",xxstring)) < 0)
- return(y);
- switch (y) {
- case XYDHUP: /* DIAL HANGUP */
- return(seton(&dialhng));
- case XYDINI: /* DIAL INIT-STRING */
- return(dialstr(&dialini,"Modem initialization string"));
- case XYDNPR: /* DIAL PREFIX */
- return(dialstr(&dialnpr,"Telephone number prefix"));
- case XYDDIA: /* DIAL DIAL-COMMAND */
- x = cmtxt("Dialing command for modem,\n\
- include \"%s\" to stand for phone number,\n\
- for example, \"set dial dial-command ATDT%s\\13\"",
- "",
- &s,
- xxstring);
- if (x < 0 && x != -3) /* Handle parse errors */
- return(x);
- s = brstrip(s); /* Strip braces or quotes */
- y = x = strlen(s); /* Get length of text */
- if (y > 0) { /* If there is any text (left), */
- for (x = 0; x < y; x++) { /* make sure they included "%s" */
- if (s[x] != '%') continue;
- if (s[x+1] == 's') break;
- }
- if (x == y) {
- printf(
-"?Dial-command must contain \"%cs\" for phone number.\n",'%');
- return(-9);
- }
- }
- if (dialcmd) { /* Free any previous string. */
- free(dialcmd);
- dialcmd = (char *) 0;
- }
- if (y > 0) {
- dialcmd = malloc(y + 1); /* Allocate space for it */
- if (dialcmd)
- strcpy(dialcmd,s); /* and make a safe copy. */
- }
- return(success = 1);
-#ifndef NOXFER
- case XYDKSP: /* DIAL KERMIT-SPOOF */
- return(seton(&dialksp));
-#endif /* NOXFER */
- case XYDTMO: /* DIAL TIMEOUT */
- y = cmnum("Seconds to wait for call completion","0",10,&x,xxstring);
- if (y < 0) return(y);
- y = cmnum("Kermit/modem timeout differential","10",10,&z,xxstring);
- if (y < 0) return(y);
- if ((y = cmcfm()) < 0)
- return(y);
- dialtmo = x;
- mdmwaitd = z;
- case XYDESC: /* DIAL ESCAPE-CHARACTER */
- y = cmnum("ASCII value of character to escape back to modem",
- "43",10,&x,xxstring);
- y = setnum(&dialesc,x,y,128);
- if (y > -1 && dialesc < 0) /* No escape character */
- dialmhu = 0; /* So no hangup by modem command */
- return(y);
- case XYDDPY: /* DIAL DISPLAY */
- return(seton(&dialdpy));
- case XYDSPD: /* DIAL SPEED-MATCHING */
- /* used to be speed-changing */
- if ((y = seton(&mdmspd)) < 0) return(y);
-#ifdef COMMENT
- mdmspd = 1 - mdmspd; /* so here we reverse the meaning */
-#endif /* COMMENT */
- return(success = 1);
- case XYDMNP: /* DIAL MNP-ENABLE */
- case XYDEC: /* DIAL ERROR-CORRECTION */
- x = seton(&dialec);
- if (x > 0)
- if (!dialec) dialdc = 0; /* OFF also turns off compression */
- return(x);
-
- case XYDDC: /* DIAL COMPRESSION */
- x = seton(&dialdc);
- if (x > 0)
- if (dialdc) dialec = 1; /* ON also turns on error correction */
- return(x);
-
-#ifdef MDMHUP
- case XYDMHU: /* DIAL MODEM-HANGUP */
- return(seton(&dialmhu));
-#endif /* MDMHUP */
-
-#ifndef NOSPL
- case XYDDIR: /* DIAL DIRECTORY (zero or more) */
- return(parsdir(0)); /* 0 means DIAL */
-#endif /* NOSPL */
-
- case XYDSTR: /* DIAL STRING */
- if ((y = cmkey(mdmcmd,nmdmcmd,"","",xxstring)) < 0) return(y);
- switch (y) {
- case XYDS_AN: /* Autoanswer ON/OFF */
- case XYDS_DC: /* Data compression ON/OFF */
- case XYDS_EC: /* Error correction ON/OFF */
- if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
- return(x);
- sprintf(tmpbuf,"Modem's command to %sable %s", /* SAFE */
- x ? "en" : "dis",
- (y == XYDS_DC) ? "compression" :
- ((y == XYDS_EC) ? "error-correction" :
- "autoanswer")
- );
- if (x) {
- if (y == XYDS_DC)
- return(dialstr(&dialdcon,tmpbuf));
- else if (y == XYDS_EC)
- return(dialstr(&dialecon,tmpbuf));
- else
- return(dialstr(&dialaaon,tmpbuf));
- } else {
- if (y == XYDS_DC)
- return(dialstr(&dialdcoff,tmpbuf));
- else if (y == XYDS_EC)
- return(dialstr(&dialecoff,tmpbuf));
- else
- return(dialstr(&dialaaoff,tmpbuf));
- }
- case XYDS_HU: /* hangup command */
- return(dialstr(&dialhcmd,"Modem's hangup command"));
- case XYDS_HW: /* hwfc */
- return(dialstr(&dialhwfc,
- "Modem's command to enable hardware flow control"));
- case XYDS_IN: /* init */
- return(dialstr(&dialini,"Modem's initialization string"));
- case XYDS_NF: /* no flow control */
- return(dialstr(&dialnofc,
- "Modem's command to disable local flow control"));
- case XYDS_PX: /* prefix */
- return(dialstr(&dialnpr,"Telephone number prefix for dialing"));
- case XYDS_SW: /* swfc */
- return(dialstr(&dialswfc,
- "Modem's command to enable local software flow control"));
- case XYDS_DT: /* tone dialing */
- return(dialstr(&dialtone,
- "Command to configure modem for tone dialing"));
- case XYDS_DP: /* pulse dialing */
- return(dialstr(&dialpulse,
- "Command to configure modem for pulse dialing"));
- case XYDS_MS: /* dial mode string */
- return(dialstr(&dialmstr,
- "Command to enter dial mode"));
- case XYDS_MP: /* dial mode prompt */
- return(dialstr(&dialmprmt,
- "Modem response upon entering dial mode"));
- case XYDS_SP: /* SPEAKER OFF */
- if ((x = cmkey(onoff,2,"","on",xxstring)) < 0) return(x);
- if (x)
- return(dialstr(&dialspon,"Command to turn modem speaker on"));
- else
- return(dialstr(&dialspoff,"Command to turn modem speaker off"));
-
- case XYDS_VO: /* VOLUME LOW */
- if ((x = cmkey(voltab,3,"","medium",xxstring)) < 0) return(x);
- switch (x) {
- case 0:
- case 1:
- return(dialstr(&dialvol1,
- "Command for low modem speaker volume"));
- case 2:
- return(dialstr(&dialvol2,
- "Command for medium modem speaker volume"));
-
- case 3:
- return(dialstr(&dialvol3,
- "Command for high modem speaker volume"));
- default:
- return(-2);
- }
-
- case XYDS_ID: /* IGNORE-DIALTONE */
- return(dialstr(&dialx3,
- "Command to tell modem to ignore dialtone"));
-
- case XYDS_I2: /* PREDIAL-INIT */
- return(dialstr(&dialini2,
- "Command to send to modem just prior to dialing"));
-
- default:
- printf("?Unexpected SET DIAL STRING parameter\n");
- }
-
- case XYDFC: /* DIAL FLOW-CONTROL */
- if ((y = cmkey(dial_fc,4,"","auto",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- dialfc = y;
- return(success = 1);
-
- case XYDMTH: { /* DIAL METHOD */
- extern int dialmauto;
- if ((y = cmkey(dial_m,ndial_m,"","default",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- if (y == XYDM_A) { /* AUTO */
- dialmauto = 1; /* local country code, if known. */
- dialmth = XYDM_D;
- } else {
- dialmauto = 0; /* use the method specified */
- dialmth = y;
- }
- return(success = 1);
- }
- case XYDRTM:
- y = cmnum("Number of times to try dialing a number",
- "1",10,&x,xxstring);
- z = setnum(&dialrtr,x,y,-1);
- if (z > -1 && dialrtr < 0) {
- printf("?Sorry, negative dial retries not valid: %d\n",dialrtr);
- return(-9);
- }
- return(z);
-
- case XYDINT:
- y = cmnum("Seconds to wait between redial attempts",
- "30",10,&x,xxstring);
- z = setnum(&dialint,x,y,-1);
- if (z > -1 && dialint < 0) {
- printf("?Sorry, negative dial interval not valid: %d\n",dialint);
- return(-9);
- }
- return(z);
-
- case XYDLAC: /* DIAL AREA-CODE */
- if ((x = dialstr(&diallac,"Area code you are calling from")) < 0)
- return(x);
- if (diallac) {
- if (!rdigits(diallac)) {
- printf("?Sorry, area code must be numeric\n");
- if (*diallac == '(')
- printf("(please omit the parentheses)\n");
- if (*diallac == '/')
- printf("(no slashes, please)\n");
- if (diallac) free(diallac);
- diallac = NULL;
- return(-9);
- }
- }
- return(x);
-
- case XYDCNF: /* CONFIRMATION */
- return(success = seton(&dialcnf));
-
- case XYDCVT: /* CONVERT-DIRECTORY */
- if ((y = cmkey(dcnvtab,3,"","ask",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- dialcvt = y;
- return(success = 1);
-
- case XYDLCC: /* DIAL COUNTRY-CODE */
- x = dialstr(&diallcc,"Country code you are calling from");
- if (x < 1) return(x);
- if (diallcc) {
- if (!rdigits(diallcc)) {
- printf("?Sorry, country code must be numeric\n");
- if (*diallcc == '+')
- printf("(please omit the plus sign)\n");
- if (diallcc) free(diallcc);
- diallcc = NULL;
- return(-9);
- }
- if (!strcmp(diallcc,"1")) { /* Set defaults for USA and Canada */
- if (!dialldp) /* Long-distance prefix */
- makestr(&dialldp,"1");
- if (!dialixp) /* International dialing prefix */
- makestr(&dialixp,"011");
- if (ntollfree == 0) { /* Toll-free area codes */
- if ((dialtfc[0] = malloc(4))) {
- strcpy(dialtfc[0],"800"); /* 1970-something */
- ntollfree++;
- if ((dialtfc[1] = malloc(4))) {
- strcpy(dialtfc[1],"888"); /* 1996 */
- ntollfree++;
- if ((dialtfc[2] = malloc(4))) {
- strcpy(dialtfc[2],"877"); /* 5 April 1998 */
- ntollfree++;
- if ((dialtfc[3] = malloc(4))) {
- strcpy(dialtfc[3],"866"); /* 2000? */
- ntollfree++;
- }
- }
- }
- }
- }
- if (!dialtfp) /* Toll-free dialing prefix */
- makestr(&dialtfp,"1");
-#ifdef COMMENT
-/* The time for this is past */
- } else if (!strcmp(diallcc,"358") &&
- ((int) strcmp(zzndate(),"19961011") > 0)
- ) { /* Finland */
- if (!dialldp) /* Long-distance prefix */
- makestr(&dialldp,"9");
- if (!dialixp) /* International dialing prefix */
- makestr(&dialixp,"990");
-#endif /* COMMENT */
- } else { /* Everywhere else ... */
- if (!dialldp) {
- if ((dialldp = malloc(4)))
- strcpy(dialldp,"0");
- }
- if (!dialixp) {
- if ((dialixp = malloc(4)))
- strcpy(dialixp,"00");
- }
- }
- if (!strcmp(diallcc,"33")) /* France */
- dialfld = 1; /* Long-distance dialing is forced */
- }
- return(success = 1);
-
- case XYDIXP: /* DIAL INTL-PREFIX */
- return(dialstr(&dialixp,"International dialing prefix"));
-
- case XYDIXS: /* DIAL INTL-SUFFIX */
- return(dialstr(&dialixs,"International dialing suffix"));
-
- case XYDLDP: /* DIAL LD-PREFIX */
- return(dialstr(&dialldp,"Long-distance dialing prefix"));
-
- case XYDLDS: /* DIAL LD-SUFFIX */
- return(dialstr(&diallds,"Long-distance dialing suffix"));
-
- case XYDLCP: /* DIAL LC-PREFIX */
- return(dialstr(&diallcp,"Local dialing prefix"));
-
- case XYDLCS: /* DIAL LC-SUFFIX */
- return(dialstr(&diallcs,"Local dialing suffix"));
-
-#ifdef COMMENT
- case XYDPXX: /* DIAL PBX-EXCHANGE */
- return(dialstr(&dialpxx,"Exchange of PBX you are calling from"));
-#endif /* COMMENT */
-
- case XYDPXI: { /* DIAL PBX-INTERNAL-PREFIX */
-#ifdef COMMENT
- return(dialstr(&dialpxi,
- "Internal-call prefix of PBX you are calling from"));
-#else
- int x;
- if ((x = cmtxt("Internal-call prefix of PBX you are calling from",
- "",&s,NULL)) < 0) /* Don't evaluate */
- return(x);
-#ifndef NOSPL
- if (*s) {
- char c, * p = tmpbuf;
- if (*s == '\\') {
- c = *(s+1);
- if (isupper(c)) c = tolower(c);
- if (c != 'f' &&
- ckstrcmp(s,"\\v(d$px)",8,0) &&
- ckstrcmp(s,"\\v(d$pxx)",9,0) &&
- ckstrcmp(s,"\\v(d$p)",7,0)) {
- x = TMPBUFSIZ;
- zzstring(s,&p,&x);
- s = tmpbuf;
- }
- }
- }
-#endif /* NOSPL */
- makestr(&dialpxi,s);
- return(1);
- }
-#endif /* COMMENT */
-
- case XYDPXO: /* DIAL PBX-OUTSIDE-PREFIX */
- return(dialstr(&dialpxo,
- "Outside-line prefix of PBX you are calling from"));
-
- case XYDSFX: /* DIAL INTL-SUFFIX */
- return(dialstr(&dialsfx," Telephone number suffix for dialing"));
-
- case XYDSRT: /* DIAL SORT */
- return(success = seton(&dialsrt));
-
- case XYDPXX: /* DIAL PBX-EXCHANGE */
- case XYDTFC: { /* DIAL TOLL-FREE-AREA-CODE */
- int n, i; /* (zero or more of them...) */
- char * p[MAXTOLLFREE]; /* Temporary pointers */
- char * m;
- for (n = 0; n < MAXTOLLFREE; n++) {
- if (n == 0) {
- m = (y == XYDTFC) ?
- "Toll-free area code(s) in the country you are calling from"
- : "Exchange(s) of PBX you are calling from";
- } else {
- m = (y == XYDTFC) ?
- "Another toll-free area code"
- : "Another PBX exchange";
- }
- if ((x = cmfld(m,"",&s,xxstring)) < 0)
- break;
- if (s) {
- int k;
- k = (int) strlen(s);
- if (k > 0) {
- if ((p[n] = malloc(k + 1)))
- strcpy(p[n], s); /* safe */
- } else break;
- } else break;
- }
- if (x == -3) { /* Command was successful */
- int m;
- m = (y == XYDTFC) ? ntollfree : ndialpxx;
- if ((x = cmcfm()) < 0)
- return(x);
- x = 1;
- for (i = 0; i < m; i++) { /* Remove old list, if any */
- if (y == XYDTFC)
- makestr(&(dialtfc[i]),NULL);
- else
- makestr(&(dialpxx[i]),NULL);
- }
- if (y == XYDTFC)
- ntollfree = n; /* New count */
- else
- ndialpxx = n;
- for (i = 0; i < n; i++) { /* New list */
- if (y == XYDTFC)
- makestr(&(dialtfc[i]),p[i]);
- else
- makestr(&(dialpxx[i]),p[i]);
- }
- x = 1;
- }
- for (i = 0; i < n; i++)
- if (p[i]) free(p[i]);
- return(x);
- }
-
- case XYDTFP: /* TOLL-FREE-PREFIX */
- return(dialstr(&dialtfp,
- " Long-distance prefix for toll-free dialing"));
-
- case XYDCON: /* CONNECT */
- z = -1;
- if ((y = cmkey(crrtab,ncrr,"","auto",xxstring)) < 0) return(y);
- if (y != CAR_OFF) /* AUTO or ON? */
- if ((z = cmkey(qvtab,nqvt,"","verbose",xxstring)) < 0) return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (z > -1)
- dialcq = z;
- dialcon = y;
- return(success = 1);
-
- case XYDRSTR: /* RESTRICT */
- if ((y = cmkey(drstrtab,4,"","none",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- dialrstr = y;
- return(success = 1);
-
- case XYDLLAC: { /* Local area-code list */
- int n, i; /* (zero or more of them...) */
- char * p[MAXLOCALAC]; /* Temporary pointers */
- for (n = 0; n < MAXLOCALAC; n++) {
- if ((x = cmfld(
- "Area code to which calls from your area are local",
- "",&s,xxstring)) < 0)
- break;
- if (s) {
- int k;
- k = (int) strlen(s);
- if (k > 0) {
- if ((p[n] = malloc(k + 1)))
- strcpy(p[n], s); /* safe */
- } else break;
- } else break;
- }
- if (x == -3) { /* Command was successful */
- if ((x = cmcfm()) < 0)
- return(x);
- for (i = 0; i < nlocalac; i++) /* Remove old list, if any */
- if (diallcac[i]) {
- free(diallcac[i]);
- diallcac[i] = NULL;
- }
- nlocalac = n; /* New count */
- for (i = 0; i < nlocalac; i++) /* New list */
- diallcac[i] = p[i];
- return(success = 1);
- } else { /* Parse error, undo everything */
- for (i = 0; i < n; i++)
- if (p[i]) free(p[i]);
- return(x);
- }
- }
-
- case XYDFLD:
- return(success = seton(&dialfld));
-
- case XYDIDT: /* DIAL IGNORE-DIALTONE */
- return(seton(&dialidt));
-
- case XYDPAC:
- y = cmnum(
- "Milliseconds to pause between each character sent to dialer",
- "",10,&x,xxstring);
- return(setnum(&dialpace,x,y,9999));
-
-#ifndef NOSPL
- case XYDMAC:
- if ((x = cmfld("Name of macro to execute just prior to dialing",
- "",&s,xxstring)) < 0) {
- if (x == -3)
- s = NULL;
- else
- return(x);
- }
- if (s) {
- if (!*s) {
- s = NULL;
- } else {
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- }
- }
- if ((x = cmcfm()) < 0)
- return(x);
- makestr(&dialmac,s);
- return(success = 1);
-#endif /* NOSPL */
-
- case XYDPUCC: /* Pulse country codes */
- case XYDTOCC: { /* Tone country codes */
- int n, i;
- char * p[MAXTPCC];
- char * m;
- for (n = 0; n < MAXTPCC; n++) {
- if (n == 0) {
- m = (y == XYDPUCC) ?
- "Country code where Pulse dialing is required"
- : "Country code where Tone dialing is available";
- } else
- m = "Another country code";
- if ((x = cmfld(m,"",&s,xxstring)) < 0)
- break;
- if (s) {
- int k;
- k = (int) strlen(s);
- if (k > 0) {
- if ((p[n] = malloc(k + 1)))
- strcpy(p[n], s); /* safe */
- } else break;
- } else break;
- }
- if (x == -3) { /* Command was successful */
- int m;
- m = (y == XYDPUCC) ? ndialpucc : ndialtocc;
- if ((x = cmcfm()) < 0)
- return(x);
- x = 1;
- for (i = 0; i < m; i++) { /* Remove old list, if any */
- if (y == XYDPUCC)
- makestr(&(dialpucc[i]),NULL);
- else
- makestr(&(dialtocc[i]),NULL);
- }
- if (y == XYDPUCC) {
- ndialpucc = n; /* New count */
- } else {
- ndialtocc = n;
- }
- for (i = 0; i < n; i++) { /* New list */
- if (y == XYDPUCC) {
- makestr(&(dialpucc[i]),p[i]);
- } else {
- makestr(&(dialtocc[i]),p[i]);
- }
- }
- x = 1;
- }
- for (i = 0; i < n; i++)
- if (p[i]) free(p[i]);
- return(x);
- }
- case XYDTEST:
- return(seton(&dialtest));
-
- default:
- printf("?Unexpected SET DIAL parameter\n");
- return(-9);
- }
-}
-
-#ifndef NOSHOW
-int /* SHOW MODEM */
-shomodem() {
- MDMINF * p;
- int x, n, mdm;
- char c;
- long zz;
-
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-
- shmdmlin();
- printf("\n");
-
- mdm = (mdmtyp > 0) ? mdmtyp : mdmsav;
- p = (mdm > 0) ? modemp[mdm] : NULL;
-
- if (p) {
- printf(" %s\n\n", dialname ? dialname : p->name);
-
- printf(" Modem capabilities: ");
- zz = dialcapas ? dialcapas : p->capas;
- if (!zz) {
- printf(" (none)");
- } else {
- if (zz & CKD_AT) printf(" AT");
- if (zz & CKD_V25) printf(" ITU");
- if (zz & CKD_SB) printf(" SB");
- if (zz & CKD_EC) printf(" EC");
- if (zz & CKD_DC) printf(" DC");
- if (zz & CKD_HW) printf(" HWFC");
- if (zz & CKD_SW) printf(" SWFC");
- if (zz & CKD_KS) printf(" KS");
- if (zz & CKD_TB) printf(" TB");
- }
- printf("\n Modem carrier-watch: ");
- if (carrier == CAR_OFF) printf("off\n");
- else if (carrier == CAR_ON) printf("on\n");
- else if (carrier == CAR_AUT) printf("auto\n");
- else printf("unknown\n");
-
- printf(" Modem maximum-speed: ");
- zz = (dialmax > 0L) ? dialmax : p->max_speed;
- if (zz > 0)
- printf("%ld bps\n", zz);
- else
- printf("(unknown)\n");
- printf(" Modem error-correction: %s\n", dialec ? "on" : "off");
- printf(" Modem compression: %s\n", dialdc ? "on" : "off");
- printf(" Modem speed-matching: %s", mdmspd ? "on" : "off");
- printf(" (interface speed %s)\n", mdmspd ? "changes" : "is locked");
- printf(" Modem flow-control: ");
- if (dialfc == FLO_NONE) printf("none\n");
- else if (dialfc == FLO_XONX) printf("xon/xoff\n");
- else if (dialfc == FLO_RTSC) printf("rts/cts\n");
- else if (dialfc == FLO_AUTO) printf("auto\n");
- printf(" Modem hangup-method: %s\n",
- dialmhu ?
- "modem-command" :
- "rs232-signal"
- );
- printf(" Modem speaker: %s\n", showoff(mdmspk));
- printf(" Modem volume: %s\n",
- (mdmvol == 2) ? "medium" : ((mdmvol <= 1) ? "low" : "high"));
- printf(" Modem kermit-spoof: %s\n", dialksp ? "on" : "off");
- c = (char) (x = (dialesc ? dialesc : p->esc_char));
- printf(" Modem escape-character: %d", x);
- if (isprint(c))
- printf(" (= \"%c\")",c);
- printf(
-"\n\nMODEM COMMANDs (* = set automatically by SET MODEM TYPE):\n\n");
- debug(F110,"show dialini",dialini,0);
- printf(" %c Init-string: ", dialini ? ' ' : '*' );
- shods(dialini ? dialini : p->wake_str);
- printf(" %c Dial-mode-string: ", dialmstr ? ' ' : '*' );
- shods(dialmstr ? dialmstr : p->dmode_str);
- n = local ? 19 : 20;
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Dial-mode-prompt: ", dialmprmt ? ' ' : '*' );
- shods(dialmprmt ? dialmprmt : p->dmode_prompt);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Dial-command: ", dialcmd ? ' ' : '*' );
- shods(dialcmd ? dialcmd : p->dial_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Compression on: ", dialdcon ? ' ' : '*' );
- if (!dialdcon)
- debug(F110,"dialdcon","(null)",0);
- else
- debug(F110,"dialdcon",dialdcon,0);
- shods(dialdcon ? dialdcon : p->dc_on_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Compression off: ", dialdcoff ? ' ' : '*' );
- shods(dialdcoff ? dialdcoff : p->dc_off_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Error-correction on: ", dialecon ? ' ' : '*' );
- shods(dialecon ? dialecon : p->ec_on_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Error-correction off: ", dialecoff ? ' ' : '*' );
- shods(dialecoff ? dialecoff : p->ec_off_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Autoanswer on: ", dialaaon ? ' ' : '*' );
- shods(dialaaon ? dialaaon : p->aa_on_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Autoanswer off: ", dialaaoff ? ' ' : '*' );
- shods(dialaaoff ? dialaaoff : p->aa_off_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
- printf(" %c Speaker on: ", dialspon ? ' ' : '*' );
- shods(dialspon ? dialspon : p->sp_on_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Speaker off: ", dialspoff ? ' ' : '*' );
- shods(dialspoff ? dialspoff : p->sp_off_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Volume low: ", dialvol1 ? ' ' : '*' );
- shods(dialvol1 ? dialvol1 : p->vol1_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Volume medium: ", dialvol2 ? ' ' : '*' );
- shods(dialvol2 ? dialvol2 : p->vol2_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Volume high: ", dialvol3 ? ' ' : '*' );
- shods(dialvol3 ? dialvol3 : p->vol3_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
- printf(" %c Hangup-command: ", dialhcmd ? ' ' : '*' );
- shods(dialhcmd ? dialhcmd : p->hup_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Hardware-flow: ", dialhwfc ? ' ' : '*' );
- shods(dialhwfc ? dialhwfc : p->hwfc_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Software-flow: ", dialswfc ? ' ' : '*' );
- shods(dialswfc ? dialswfc : p->swfc_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c No-flow-control: ", dialnofc ? ' ' : '*' );
- shods(dialnofc ? dialnofc : p->nofc_str);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Pulse: ", dialpulse ? ' ' : '*');
- shods(dialpulse ? dialpulse : p->pulse);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Tone: ", dialtone ? ' ' : '*');
- shods(dialtone ? dialtone : p->tone);
-
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Ignore-dialtone: ", dialx3 ? ' ' : '*');
- shods(dialx3 ? dialx3 : p->ignoredt);
-
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" %c Predial-init: ", dialini2 ? ' ' : '*');
- shods(dialini2 ? dialini2 : p->ini2);
-
- if (++n > cmd_rows - 4) if (!askmore()) return(0); else n = 0;
- printf("\n For more info: SHOW DIAL and SHOW COMMUNICATIONS\n");
-
- } else if (mdm > 0) {
- printf("Modem info for \"%s\" not filled in yet\n", gmdmtyp());
- } else printf(
-" No modem selected, so DIAL and most SET MODEM commands have no effect.\n\
- Use SET MODEM TYPE to select a modem.\n");
- return(success = 1);
-}
-#endif /* NOSHOW */
-#endif /* NODIAL */
-
-#ifdef CK_TAPI
-int /* TAPI action commands */
-dotapi() {
- int x,y;
- char *s;
-
- if (!TAPIAvail) {
- printf("\nTAPI is unavailable on this system.\n");
- return(-9);
- }
- if ((y = cmkey(tapitab,ntapitab,"MS TAPI command","",xxstring)) < 0)
- return(y);
- switch (y) {
- case XYTAPI_CFG: { /* TAPI CONFIGURE-LINE */
- extern struct keytab * tapilinetab;
- extern struct keytab * _tapilinetab;
- extern int ntapiline;
- extern int LineDeviceId;
- int lineID=LineDeviceId;
- if (TAPIAvail)
- cktapiBuildLineTable(&tapilinetab, &_tapilinetab, &ntapiline);
- if (tapilinetab && _tapilinetab && ntapiline > 0) {
- int i=0, j = 9999, k = -1;
-
- if ( LineDeviceId == -1 ) {
- /* Find out what the lowest numbered TAPI device is */
- /* and use it as the default. */
- for (i = 0; i < ntapiline; i++ ) {
- if (tapilinetab[i].kwval < j) {
- k = i;
- }
- }
- } else {
- /* Find the LineDeviceId in the table and use that entry */
- for (i = 0; i < ntapiline; i++ ) {
- if (tapilinetab[i].kwval == LineDeviceId) {
- k = i;
- break;
- }
- }
- }
- if (k >= 0)
- s = _tapilinetab[k].kwd;
- else
- s = "";
-
- if ((y = cmkey(_tapilinetab,ntapiline,
- "TAPI device name",s,xxstring)) < 0)
- return(y);
- lineID = y;
- }
- if ((x = cmcfm()) < 0) return(x);
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled\r\n");
- return(success = 0);
- }
-#endif /* ISKD */
- cktapiConfigureLine(lineID);
- break;
- }
- case XYTAPI_DIAL: /* TAPI DIALING-PROPERTIES */
- if ((x = cmcfm()) < 0)
- return(x);
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled\r\n");
- return(success = 0);
- }
-#endif /* ISKD */
- cktapiDialingProp();
- break;
- }
- return(success = 1);
-}
-
-static int /* SET TAPI command options */
-settapi() {
- int x, y;
- char *s;
-
- if (!TAPIAvail) {
- printf("\nTAPI is unavailable on this system.\n");
- return(-9);
- }
- if ((y = cmkey(settapitab,nsettapitab,"MS TAPI option","",xxstring)) < 0)
- return(y);
- switch (y) {
- case XYTAPI_USE:
- return (success = seton(&tapiusecfg));
- case XYTAPI_LGHT:
- return (success = seton(&tapilights));
- case XYTAPI_PRE:
- return (success = seton(&tapipreterm));
- case XYTAPI_PST:
- return (success = seton(&tapipostterm));
- case XYTAPI_INA:
- y = cmnum("seconds of inactivity before auto-disconnect",
- "0",10,&x,xxstring);
- return(setnum(&tapiinactivity,x,y,65535));
- case XYTAPI_BNG:
- y = cmnum("seconds to wait for credit card tone",
- "8",10,&x,xxstring);
- return(setnum(&tapibong,x,y,90));
- case XYTAPI_MAN:
- return (success = seton(&tapimanual));
- case XYTAPI_CON: /* TAPI CONVERSIONS */
- return (success = setonaut(&tapiconv));
- case XYTAPI_LIN: /* TAPI LINE */
- x = setlin(XYTAPI_LIN,1,0);
- if (x > -1) didsetlin++;
- return(x);
- case XYTAPI_PASS: { /* TAPI PASSTHROUGH */
-#ifdef NODIAL
- printf("\n?Modem-dialing not supported\n");
- return(-9);
-#else /* NODIAL */
- /* Passthrough became Modem-dialing which is an antonym */
- success = seton(&tapipass);
- tapipass = !tapipass;
- return (success);
-#endif /* NODIAL */
- }
- case XYTAPI_LOC: { /* TAPI LOCATION */
- extern char tapiloc[];
- extern int tapilocid;
- int i = 0, j = 9999, k = -1;
-
- cktapiBuildLocationTable(&tapiloctab, &ntapiloc);
- if (!tapiloctab || !ntapiloc) {
- printf("\nNo TAPI Locations are configured for this system\n");
- return(-9);
- }
- if (tapilocid == -1)
- tapilocid = cktapiGetCurrentLocationID();
-
- /* Find the current tapiloc entry */
- /* and use it as the default. */
- for (k = 0; k < ntapiloc; k++) {
- if (tapiloctab[k].kwval == tapilocid)
- break;
- }
- if (k >= 0 && k < ntapiloc)
- s = tapiloctab[k].kwd;
- else
- s = "";
-
- if ((y = cmkey(tapiloctab,ntapiloc, "TAPI location",s,xxstring)) < 0)
- return(y);
-
- if ((x = cmcfm()) < 0)
- return(x);
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- cktapiFetchLocationInfoByID( y );
-#ifndef NODIAL
- CopyTapiLocationInfoToKermitDialCmd();
-#endif /* NODIAL */
- }
- break;
- }
- return(success=1);
-}
-#endif /* CK_TAPI */
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
-/* Method for evaluating \%x and \&x[] variables */
-
-static struct keytab varevaltab[] = {
- { "recursive", 1, 0 },
- { "simple", 0, 0 }
-};
-static int nvarevaltab = (sizeof(varevaltab) / sizeof(struct keytab));
-
-int
-setvareval() {
- int x = 0, y = 0;
- extern int vareval;
-#ifdef DCMDBUF
- extern int * xvarev;
-#else
- extern int xvarev[];
-#endif /* DCMDBUF */
-
- if ((x = cmkey(varevaltab,
- nvarevaltab,
- "Method for evaluating \\%x and \\&x[] variables",
- "",
- xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- xvarev[cmdlvl] = x;
- vareval = x;
- return(success = 1);
-}
-
-#ifdef CK_ANSIC /* SET ALARM */
-int
-setalarm(long xx)
-#else
-int
-setalarm(xx) long xx;
-#endif /* CK_ANSIC */
-/* setalarm */ {
-#ifdef COMMENT
- int yyyy, mm, dd, x;
- char *s;
- long zz;
- char buf[6];
-#endif /* COMMENT */
- long sec, jd;
- char xbuf[20], * p;
-
- debug(F101,"setalarm xx","",xx);
- ck_alarm = 0L; /* 0 = no alarm (in case of error) */
- if (xx < 0L) {
- printf("%ld - illegal value, must be 0 or positive\n", xx);
- return(-9);
- }
- if (xx == 0L) { /* CLEAR ALARM */
- alrm_date[0] = NUL;
- alrm_time[0] = NUL;
- return(1);
- }
-#ifdef COMMENT
- x = 8; /* Get current date */
- s = alrm_date;
- if (zzstring("\\v(ndate)",&s,&x) < 0) {
- printf("Internal date error, sorry.\n");
- alrm_date[0] = SP;
- return(-9);
- }
- x = 5; /* Get current time */
- s = alrm_time;
- if (zzstring("\\v(ntime)",&s,&x) < 0) {
- printf("Internal time error, sorry.\n");
- alrm_time[0] = SP;
- return(-9);
- }
- sprintf(buf,"%05ld",atol(alrm_time)); /* SAFE (20) */
- ckstrncpy(alrm_time,buf,8);
- debug(F110,"SET ALARM date (1)",alrm_date,0);
- debug(F110,"SET ALARM time (1)",alrm_time,0);
-
- if ((zz = atol(alrm_time) + xx) < 0L) {
- printf("Internal time conversion error, sorry.\n");
- return(-9);
- }
- if (zz >= 86400L) { /* Alarm crosses midnight */
- char d[10]; /* Local date buffer */
- int lastday; /* Last day of this month */
-
- ckstrncpy(d,alrm_date,8); /* We'll have to change the date */
-
- x = (zz / 86400L); /* How many days after today */
-
- dd = atoi((char *)(d+6)); /* Parse yyyymmdd */
- d[6] = NUL; /* into yyyy, mm, dd ... */
- mm = atoi((char *)(d+4));
- d[4] = NUL;
- yyyy = atoi((char *)d);
-
- /* How many days in this month */
-
- lastday = mdays[mm];
- if (mm == 2 && yyyy % 4 == 0) /* Works thru 2099 AD... */
- lastday++;
-
- if (dd + x > lastday) { /* Dumb loop */
- int y;
-
- x -= (mdays[mm] - dd); /* Deduct rest of this month's days */
-
- /* There's a more elegant way to do this... */
-
- while (1) {
- mm++; /* Next month */
- if (mm > 12) { /* Wrap around */
- mm = 1; /* Jan, next year */
- yyyy++;
- }
- y = mdays[mm]; /* Days in new month */
- if (mm == 2 && yyyy % 4 == 0) /* Feb in leap year */
- y++; /* Works until 2100 AD */
- if (x - y < 1)
- break;
- x -= y;
- }
- dd = x; /* Day of alarm month */
- } else dd += x;
-
- sprintf(alrm_date,"%04d%02d%02d",yyyy,mm,dd); /* SAFE (24) */
- zz = zz % 86400L;
- }
- sprintf(alrm_time,"%ld",zz); /* SAFE (24) */
- debug(F110,"SET ALARM date (2)",alrm_date,0);
- debug(F110,"SET ALARM time (2)",alrm_time,0);
- ck_alarm = xx;
-#else
- /* Jul 1998 */
- ckstrncpy(xbuf,ckcvtdate("",1),20); /* Get current date and time */
- p = xbuf;
- ckstrncpy(alrm_date,xbuf,10);
- alrm_date[8] = NUL;
- sec = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
- debug(F110,"SET ALARM date (1)",alrm_date,0);
- debug(F101,"SET ALARM time (1)","",sec);
- if ((sec += xx) < 0L) {
- printf("Internal time conversion error, sorry.\n");
- return(-9);
- }
- if (sec >= 86400L) { /* Alarm crosses midnight */
- long days;
- days = sec / 86400L;
- jd = mjd(p) + days; /* Get modified Julian date */
- ckstrncpy(alrm_date,mjd2date(jd),10);
- sec %= 86400L;
- }
- sprintf(alrm_time,"%05ld",sec); /* SAFE (24) */
- debug(F110,"SET ALARM date (2)",alrm_date,0);
- debug(F110,"SET ALARM time (2)",alrm_time,0);
- ck_alarm = 1; /* Alarm is set */
-
-#endif /* COMMENT */
- return(success = 1);
-}
-#endif /* NOSPL */
-
-#ifndef NOSETKEY
-int
-dosetkey() { /* SET KEY */
- int x, y;
- int flag = 0;
- int kc; /* Key code */
- char *s; /* Key binding */
-#ifndef NOKVERBS
- char *p; /* Worker */
-#endif /* NOKVERBS */
-#ifdef OS2
- extern int os2gks;
- extern int mskkeys;
- extern int initvik;
-#endif /* OS2 */
-
- x_ifnum = 1;
- y = cmnum("numeric key code, or the word CLEAR,","",10,&kc,xxstring);
- x_ifnum = 0;
- if (y < 0) {
- debug(F111,"SET KEY",atmbuf,y);
- if (y == -2) { /* Not a valid number */
- if ((y = strlen(atmbuf)) < 0) /* Check for SET KEY CLEAR */
- return(-2);
- if (ckstrcmp(atmbuf,"clear",y,0))
- return(-2);
- if ((x = cmcfm()) < 0)
- return(x);
- for (y = 0; y < KMSIZE; y++) {
- keymap[y] = (KEY) y;
- macrotab[y] = NULL;
- }
-#ifdef OS2
- keymapinit(); /* Special OS/2 initializations */
- initvik = 1; /* Update the VIK table */
-#endif /* OS2 */
- return(1);
- } else if (y == -3) { /* SET KEY <Return> */
- printf(" Press key to be defined: "); /* Prompt for a keystroke */
-#ifdef UNIX
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
-#endif /* UNIX */
- conbin((char)escape); /* Put terminal in binary mode */
-#ifdef OS2
- os2gks = 0; /* Turn off Kverb preprocessing */
-#endif /* OS2 */
- kc = congks(0); /* Get character or scan code */
-#ifdef OS2
- os2gks = 1; /* Turn on Kverb preprocessing */
-#endif /* OS2 */
- concb((char)escape); /* Restore terminal to cbreak mode */
- if (kc < 0) { /* Check for error */
- printf("?Error reading key\n");
- return(0);
- }
-#ifdef OS2
- shokeycode(kc,-1); /* Show current definition */
-#else
- shokeycode(kc); /* Show current definition */
-#endif /* OS2 */
- flag = 1; /* Remember it's a multiline command */
- } else /* Error */
- return(y);
- }
-
- /* Normal SET KEY <scancode> <value> command... */
-
-#ifdef OS2
- if (mskkeys)
- kc = msktock(kc);
-#endif /* OS2 */
-
- if (kc < 0 || kc >= KMSIZE) {
- printf("?key code must be between 0 and %d\n", KMSIZE - 1);
- return(-9);
- }
- if (kc == escape) {
- printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
- return(-9);
- }
-#ifdef OS2
- wideresult = -1;
-#endif /* OS2 */
- if (flag) {
- cmsavp(psave,PROMPTL);
- cmsetp(" Enter new definition: ");
- cmini(ckxech);
- cmflgs = 0;
- prompt(NULL);
- }
- def_again:
- if (flag)
- cmres();
- if ((y = cmtxt("key definition,\n\
-or Ctrl-C to cancel this command,\n\
-or Enter to restore default definition",
- "",&s,NULL)) < 0) {
- if (flag) /* Handle parse errors */
- goto def_again;
- else
- return(y);
- }
- s = brstrip(s);
-#ifndef NOKVERBS
- p = s; /* Save this place */
-#endif /* NOKVERBS */
-/*
- If the definition included any \Kverbs, quote the backslash so the \Kverb
- will still be in the definition when the key is pressed. We don't do this
- in zzstring(), because \Kverbs are valid only in this context and nowhere
- else.
-
- We use this code active for all versions that support SET KEY, even if they
- don't support \Kverbs, because otherwise \K would behave differently for
- different versions.
-*/
- for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
- if ((x > 0) &&
- (s[x] == 'K' || s[x] == 'k')
- ) { /* Have K */
-
- if ((x == 1 && s[x-1] == CMDQ) ||
- (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
- line[y++] = CMDQ; /* Make it \\K */
- }
- if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
- line[y-1] = CMDQ; /* Have \{K */
- line[y++] = '{'; /* Make it \\{K */
- }
- }
- line[y] = s[x];
- }
- line[y++] = NUL; /* Terminate */
- s = line + y + 1; /* Point to after it */
- x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
- if ((x < (LINBUFSIZ / 2)) ||
- (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
- printf("?Key definition too long\n");
- if (flag) cmsetp(psave);
- return(-9);
- }
- s = line + y + 1; /* Point to result. */
-
-#ifndef NOKVERBS
-/*
- Special case: see if the definition starts with a \Kverb.
- If it does, point to it with p, otherwise set p to NULL.
-*/
- p = s;
- if (*p++ == CMDQ) {
- if (*p == '{') p++;
- p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
- }
-#endif /* NOKVERBS */
-
- if (macrotab[kc]) { /* Possibly free old macro from key. */
- free((char *)macrotab[kc]);
- macrotab[kc] = NULL;
- }
- switch (strlen(s)) { /* Action depends on length */
- case 0: /* Reset to default binding */
- keymap[kc] = (KEY) kc;
- break;
- case 1: /* Single character */
- keymap[kc] = (CHAR) *s;
- break;
- default: /* Character string */
-#ifndef NOKVERBS
- if (p) {
- y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
- debug(F101,"set key kverb lookup",0,y); /* exact match required */
- if (y > -1) {
- keymap[kc] = F_KVERB | y;
- break;
- }
- }
-#endif /* NOKVERBS */
- keymap[kc] = (KEY) kc;
- macrotab[kc] = (MACRO) malloc(strlen(s)+1);
- if (macrotab[kc])
- strcpy((char *) macrotab[kc], s); /* safe */
- break;
- }
- if (flag) cmsetp(psave);
-#ifdef OS2
- initvik = 1; /* Update VIK table */
-#endif /* OS2 */
- return(1);
-}
-#endif /* NOSETKEY */
-
-#ifdef STOPBITS
-struct keytab stoptbl[] = {
- { "1", 1, 0 },
- { "2", 2, 0 }
-};
-#endif /* STOPBITS */
-
-static struct keytab sertbl[] = {
- { "7E1", 0, 0 },
- { "7E2", 1, 0 },
- { "7M1", 2, 0 },
- { "7M2", 3, 0 },
- { "7O1", 4, 0 },
- { "7O2", 5, 0 },
- { "7S1", 6, 0 },
- { "7S2", 7, 0 },
-#ifdef HWPARITY
- { "8E1", 9, 0 },
- { "8E2", 10, 0 },
-#endif /* HWPARITY */
- { "8N1", 8, 0 },
-#ifdef HWPARITY
- { "8N2", 11, 0 },
- { "8O1", 12, 0 },
- { "8O2", 13, 0 },
-#endif /* HWPARITY */
- { "", 0, 0 }
-};
-static int nsertbl = (sizeof(sertbl) / sizeof(struct keytab)) - 1;
-
-static char * sernam[] = { /* Keep this in sync with sertbl[] */
- "7E1", "7E2", "7M1", "7M2", "7O1", "7O2", "7S1", "7S2",
- "8N1", "8E1", "8E2", "8N2", "8O1", "8O2"
-};
-
-static struct keytab optstab[] = { /* SET OPTIONS table */
-#ifndef NOFRILLS
- { "delete", XXDEL, 0}, /* DELETE */
-#endif /* NOFRILLS */
- { "directory", XXDIR, 0}, /* DIRECTORY */
-#ifdef CKPURGE
- { "purge", XXPURGE, 0}, /* PURGE */
-#endif /* CKPURGE */
- { "type", XXTYP, 0}, /* TYPE */
- { "", 0, 0}
-};
-static int noptstab = (sizeof(optstab) / sizeof(struct keytab)) - 1;
-
-#ifndef NOXFER
-/*
- PROTOCOL SELECTION. Kermit is always available. If CK_XYZ is defined at
- compile time, then the others become selections also. In OS/2 and
- Windows, they are integrated and the various SET commands (e.g. "set file
- type") affect them as they would Kermit. In other OS's (UNIX, VMS, etc),
- they are external protocols which are run via Kermit's REDIRECT mechanism.
- All we do is collect and verify the filenames and pass them along to the
- external protocol.
-*/
-struct keytab protos[] = {
-#ifdef CK_XYZ
- "g", PROTO_G, CM_INV,
-#endif /* CK_XYZ */
- "kermit", PROTO_K, 0,
-#ifdef CK_XYZ
- "other", PROTO_O, 0,
- "x", PROTO_X, CM_INV|CM_ABR,
- "xmodem", PROTO_X, 0,
- "xmodem-crc", PROTO_XC, 0,
- "y", PROTO_Y, CM_INV|CM_ABR,
- "ymodem", PROTO_Y, 0,
- "ymodem-g", PROTO_G, 0,
- "zmodem", PROTO_Z, 0
-#endif /* CK_XYZ */
-};
-int nprotos = (sizeof(protos) / sizeof(struct keytab));
-
-#ifndef XYZ_INTERNAL
-#ifndef NOPUSH
-#define EXP_HANDLER 1
-#define EXP_STDERR 2
-#define EXP_TIMO 3
-
-static struct keytab extprotab[] = {
- { "handler", EXP_HANDLER, 0 },
- { "redirect-stderr", EXP_STDERR, 0 },
- { "timeout", EXP_TIMO, 0 }
-};
-static int nxtprotab = (sizeof(extprotab) / sizeof(struct keytab));
-#endif /* NOPUSH */
-#endif /* XYZ_INTERNAL */
-
-#define XPCMDLEN 71
-
-_PROTOTYP(static int protofield, (char *, char *, char *));
-_PROTOTYP(static int setproto, (void));
-
-static int
-protofield(current, help, px) char * current, * help, * px; {
-
- char *s, tmpbuf[XPCMDLEN+1];
- int x;
-
- if (current) /* Put braces around default */
- ckmakmsg(tmpbuf,TMPBUFSIZ,"{",current,"}",NULL);
- else
- tmpbuf[0] = NUL;
-
- if ((x = cmfld(help, (char *)tmpbuf, &s, xxstring)) < 0)
- return(x);
- if ((int)strlen(s) > XPCMDLEN) {
- printf("?Sorry - maximum length is %d\n", XPCMDLEN);
- return(-9);
- } else if (*s) {
- strcpy(px,s); /* safe */
- } else {
- px = NULL;
- }
- return(x);
-}
-
-static int
-setproto() { /* Select a file transfer protocol */
- /* char * s = NULL; */
- int x = 0, y;
- char s1[XPCMDLEN+1], s2[XPCMDLEN+1], s3[XPCMDLEN+1];
- char s4[XPCMDLEN+1], s5[XPCMDLEN+1], s6[XPCMDLEN+1], s7[XPCMDLEN+1];
- char * p1 = s1, * p2 = s2, *p3 = s3;
- char * p4 = s4, * p5 = s5, *p6 = s6, *p7 = s7;
-
-#ifdef XYZ_INTERNAL
- extern int p_avail;
-#else
-#ifndef CK_REDIR
- x = 1;
-#endif /* CK_REDIR */
-#endif /* XYZ_INTERNAL */
- s1[0] = NUL;
- s2[0] = NUL;
- s3[0] = NUL;
- s4[0] = NUL;
- s5[0] = NUL;
- s6[0] = NUL;
-
- if ((y = cmkey(protos,nprotos,"","kermit",xxstring)) < 0)
- return(y);
-
- if (x && y != PROTO_K) {
- printf(
- "?Sorry, REDIRECT capability required for external protocols.\n");
- return(-9);
- }
- if ((x = protofield(ptab[y].h_b_init,
- "Optional command to send to host prior to uploading in binary mode",
- p1)) < 0) {
- if (x == -3) {
- protocol = y; /* Set protocol but don't change */
- return(1); /* anything else */
- } else
- return(x);
- }
- if ((x = protofield(ptab[y].h_t_init,
- "Optional command to send to host prior to uploading in text mode",
- p2)) < 0) {
- if (x == -3)
- goto protoexit;
- else
- return(x);
- }
-
- if (y == PROTO_K) {
- if ((x = protofield(ptab[y].h_x_init,
- "Optional command to send to host to start Kermit server",
- p3)) < 0) {
- if (x == -3)
- goto protoexit;
- else
- return(x);
- }
- }
-
-
-#ifndef XYZ_INTERNAL /* If XYZMODEM are external... */
-
- if (y != PROTO_K) {
- if ((x = protofield(ptab[y].p_b_scmd,
- "External command to SEND in BINARY mode with this protocol",
- p4)) < 0) {
- if (x == -3)
- goto protoexit;
- else
- return(x);
- }
- if ((x = protofield(ptab[y].p_t_scmd,
- "External command to SEND in TEXT mode with this protocol",
- p5)) < 0) {
- if (x == -3)
- goto protoexit;
- else
- return(x);
- }
- if ((x = protofield(ptab[y].p_b_rcmd,
- "External command to RECEIVE in BINARY mode with this protocol",
- p6)) < 0) {
- if (x == -3)
- goto protoexit;
- else
- return(x);
- }
- if ((x = protofield(ptab[y].p_t_rcmd,
- "External command to RECEIVE in TEXT mode with this protocol",
- p7)) < 0) {
- if (x == -3)
- goto protoexit;
- else
- return(x);
- }
- }
-#endif /* XYZ_INTERNAL */
-
- if ((x = cmcfm()) < 0) /* Confirm the command */
- return(x);
-
-protoexit: /* Common exit from this routine */
-
-#ifdef XYZ_INTERNAL
- if (!p_avail) {
- bleep(BP_WARN);
- printf("\n?X,Y, and Zmodem are unavailable\n");
- return(success = 0);
- }
-#endif /* XYZ_INTERNAL */
-
- p1 = brstrip(p1);
- p2 = brstrip(p2);
- p3 = brstrip(p3);
- p4 = brstrip(p4);
- p5 = brstrip(p5);
- p6 = brstrip(p6);
- p7 = brstrip(p7);
- initproto(y,p1,p2,p3,p4,p5,p6,p7);
- return(success = 1);
-}
-
-#ifndef NOPUSH
-#ifndef XYZ_INTERNAL
-
-#define DEF_EXP_TIMO 12 /* Default timeout for external protocol (seconds) */
-
-int exp_handler = 0; /* These are exported */
-int exp_timo = DEF_EXP_TIMO;
-int exp_stderr = SET_AUTO;
-
-VOID
-shoextern() { /* Invoked by SHOW PROTOCOL */
- printf("\n External-protocol handler: %s\n",
- exp_handler ? (exp_handler == 1 ? "pty" : "system") : "automatic");
-#ifdef COMMENT
- printf(" External-protocol redirect-stderr: %s\n", showooa(exp_stderr));
-#endif /* COMMENT */
- printf(" External-protocol timeout: %d (sec)\n", exp_timo);
-}
-
-static struct keytab setexternhandler[] = {
- { "automatic", 0, 0 },
- { "pty", 1, 0 },
- { "system", 2, 0 }
-};
-
-int
-setextern() { /* SET EXTERNAL-PROTOCOL */
- int x, y;
- if ((x = cmkey(extprotab,nxtprotab,"","",xxstring)) < 0)
- return(x);
- switch (x) {
- case EXP_HANDLER:
- if ((x = cmkey(setexternhandler,3,"","automatic",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- exp_handler = x;
- break;
-
-#ifdef COMMENT
- case EXP_STDERR:
- if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- exp_stderr = x;
- break;
-#endif /* COMMENT */
-
- case EXP_TIMO:
- y = cmnum("Inactivity timeout, seconds,",ckitoa(DEF_EXP_TIMO),
- 10,&x,xxstring);
- return(setnum(&exp_timo,x,y,-1));
- }
- return(success = 1);
-}
-#endif /* XYZ_INTERNAL */
-#endif /* NOPUSH */
-
-int
-setdest() {
- int x, y;
- if ((y = cmkey(desttab,ndests,"","disk",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- dest = y;
- return(1);
-}
-#endif /* NOXFER */
-
-#ifdef DECNET
-struct keytab dnettab[] = {
-#ifndef OS2ONLY
- "cterm", NP_CTERM, 0,
-#endif /* OS2ONLY */
- "lat", NP_LAT, 0
-};
-int ndnet = (sizeof(dnettab) / sizeof(struct keytab));
-#endif /* DECNET */
-
-/* S E T P R I N T E R -- SET PRINTER command */
-
-#ifdef PRINTSWI
-static struct keytab prntab[] = { /* SET PRINTER switches */
- "/bidirectional", PRN_BID, 0,
-#ifdef OS2
- "/character-set", PRN_CS, CM_ARG,
-#endif /* OS2 */
- "/command", PRN_PIP, CM_ARG,
- "/dos-device", PRN_DOS, CM_ARG,
- "/end-of-job-string",PRN_TRM, CM_ARG,
- "/file", PRN_FIL, CM_ARG,
-#ifdef BPRINT
- "/flow-control", PRN_FLO, CM_ARG,
-#endif /* BPRINT */
- "/job-header-file", PRN_SEP, CM_ARG,
-#ifdef OS2
- "/length", PRN_LEN, CM_ARG,
-#endif /* OS2 */
- "/none", PRN_NON, 0,
-#ifdef OS2
- "/nopostscript", PRN_RAW, 0,
- "/nops", PRN_RAW, CM_INV,
-#endif /* OS2 */
- "/output-only", PRN_OUT, 0,
-#ifdef BPRINT
- "/parity", PRN_PAR, CM_ARG,
-#endif /* BPRINT */
- "/pipe", PRN_PIP, CM_ARG|CM_INV,
-#ifdef OS2
- "/postscript", PRN_PS, 0,
- "/ps", PRN_PS, CM_INV,
-#endif /* OS2 */
- "/separator", PRN_SEP, CM_ARG|CM_INV,
-#ifdef BPRINT
- "/speed", PRN_SPD, CM_ARG,
-#endif /* BPRINT */
- "/timeout", PRN_TMO, CM_ARG,
- "/terminator", PRN_TRM, CM_ARG|CM_INV,
-#ifdef OS2
-#ifdef NT
- "/w", PRN_WIN, CM_ARG|CM_ABR|CM_INV,
- "/wi", PRN_WIN, CM_ARG|CM_ABR|CM_INV,
-#endif /* NT */
- "/width", PRN_WID, CM_ARG,
-#endif /* OS2 */
-#ifdef NT
- "/windows-queue", PRN_WIN, CM_ARG,
-#endif /* NT */
- "", 0, 0
-};
-int nprnswi = (sizeof(prntab) / sizeof(struct keytab)) - 1;
-#endif /* PRINTSWI */
-
-static int
-setprinter(xx) int xx; {
- int x, y;
- char * s;
- char * defname = NULL;
-#ifdef OS2
- extern int prncs;
-#endif /* OS2 */
-
-#ifdef BPRINT
- char portbuf[64];
- long portspeed = 0L;
- int portparity = 0;
- int portflow = 0;
-#endif /* BPRINT */
-
-#ifdef PRINTSWI
- int c, i, n, wild, confirmed = 0; /* Workers */
- int getval = 0; /* Whether to get switch value */
- struct stringint pv[PRN_MAX+1]; /* Temporary array for switch values */
- struct FDB sw, of, cm; /* FDBs for each parse function */
- int haveque = 0;
- int typeset = 0;
-#endif /* PRINTSWI */
-
-#ifdef NT
- struct keytab * printtab = NULL, * _printtab = NULL;
- int nprint = 0, printdef=0;
-#endif /* NT */
-
-#ifdef OS2
- defname = "PRN"; /* default */
-#else
-#ifdef VMS
- defname = "LPT:";
-#else
-#ifdef UNIX
- defname = "|lpr";
-#endif /* UNIX */
-#endif /* VMS */
-#endif /* OS2 */
-
-#ifdef PRINTSWI
-#ifdef NT
- haveque = Win32EnumPrt(&printtab,&_printtab,&nprint,&printdef);
- haveque = haveque && nprint;
-#endif /* NT */
-
- for (i = 0; i <= PRN_MAX; i++) { /* Initialize switch values */
- pv[i].sval = NULL; /* to null pointers */
- pv[i].ival = -1; /* and -1 int values */
- pv[i].wval = (CK_OFF_T)-1; /* and -1 wide values */
- }
- if (xx == XYBDCP) { /* SET BPRINTER == /BIDIRECTIONAL */
- pv[PRN_BID].ival = 1;
- pv[PRN_OUT].ival = 0;
- }
-
- /* Initialize defaults based upon current printer settings */
- if (printername) {
- defname = printername;
- switch (printertype) {
- case PRT_WIN: pv[PRN_WIN].ival = 1; break;
- case PRT_DOS: pv[PRN_DOS].ival = 1; break;
- case PRT_PIP: pv[PRN_PIP].ival = 1; break;
- case PRT_FIL: pv[PRN_FIL].ival = 1; break;
- case PRT_NON: pv[PRN_NON].ival = 1; break;
- }
- }
-#ifdef BPRINT
- /* only set the BIDI flag if we are bidi */
- if (printbidi)
- pv[PRN_BID].ival = 1;
-
- /* serial port parameters may be set for non-bidi devices */
- pv[PRN_SPD].ival = pportspeed / 10L;
- pv[PRN_PAR].ival = pportparity;
- pv[PRN_FLO].ival = pportflow;
-#endif /* BPRINT */
- if (printtimo)
- pv[PRN_TMO].ival = printtimo;
- if (printterm) {
- pv[PRN_TRM].ival = 1;
- makestr(&pv[PRN_TRM].sval,printterm);
- }
- if (printsep) {
- pv[PRN_SEP].ival = 1;
- makestr(&pv[PRN_SEP].sval,printsep);
- }
- if (txt2ps) {
- pv[PRN_PS].ival = 1;
- pv[PRN_WID].ival = ps_width;
- pv[PRN_LEN].ival = ps_length;
- } else {
- pv[PRN_RAW].ival = 1;
- }
-
- /* Set up chained parse functions... */
-
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nprnswi, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- prntab, /* Keyword table */
- &cm /* Pointer to next FDB */
- );
- cmfdbi(&cm, /* Second fdb for confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- &of
- );
- cmfdbi(&of, /* Third FDB for printer name */
- _CMOFI, /* fcode */
- "Printer or file name", /* hlpmsg */
- defname, /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- NULL, /* Nothing */
- NULL
- );
-
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse switch or other thing */
- debug(F101,"setprinter cmfdb","",x);
- if (x < 0) /* Error */
- goto xsetprn; /* or reparse needed */
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- if (cmresult.fdbaddr != &sw) /* Advanced usage :-) */
- break;
- c = cmgbrk(); /* Get break character */
- getval = (c == ':' || c == '='); /* to see how they ended the switch */
- n = cmresult.nresult; /* Numeric result = switch value */
- debug(F101,"setprinter switch","",n);
-
- switch (n) { /* Process the switch */
- case PRN_PS: /* Text to Postscript */
- pv[PRN_PS].ival = 1;
- pv[PRN_BID].ival = 0;
- pv[PRN_OUT].ival = 1;
- pv[PRN_RAW].ival = 0;
- break;
-
- case PRN_RAW: /* Non-Postscript */
- pv[PRN_PS].ival = 0;
- pv[PRN_RAW].ival = 1;
- break;
-
- case PRN_BID: /* Bidirectional */
- pv[PRN_BID].ival = 1;
- pv[PRN_OUT].ival = 0;
- pv[PRN_PS].ival = 0;
- pv[PRN_RAW].ival = 1;
- break;
-
- case PRN_OUT: /* Output-only */
- pv[PRN_OUT].ival = 1;
- pv[PRN_BID].ival = 0;
- pv[PRN_PS].ival = 0;
- pv[PRN_RAW].ival = 1;
- break;
-
- case PRN_NON: /* NONE */
- typeset++;
- pv[n].ival = 1;
- pv[PRN_SPD].ival = 0;
- pv[PRN_PAR].ival = 0;
- pv[PRN_FLO].ival = FLO_KEEP;
- break;
-
-#ifdef UNIX
- case PRN_WIN:
-#endif /* UNIX */
- case PRN_DOS: /* DOS printer name */
- case PRN_FIL: /* Or filename */
- case PRN_PIP:
- typeset++;
- if (pv[n].sval) free(pv[n].sval);
- pv[n].sval = NULL;
- pv[PRN_NON].ival = 0; /* Zero any previous selections */
- pv[PRN_WIN].ival = 0;
- pv[PRN_DOS].ival = 0;
- pv[PRN_FIL].ival = 0;
- pv[PRN_PIP].ival = 0;
- pv[n].ival = 1; /* Flag this one */
- if (!getval) break; /* No value wanted */
-
- if (n == PRN_FIL) { /* File, check accessibility */
- int wild = 0;
- if ((x = cmiofi("Filename","kermit.prn",&s,&wild,xxstring))< 0)
- if (x == -9) {
- if (zchko(s) < 0) {
- printf("Can't create \"%s\"\n",s);
- return(x);
- }
- } else goto xsetprn;
- if (iswild(s)) {
- printf("?A single file please\n");
- return(-9);
- }
- pv[PRN_SPD].ival = 0;
- pv[PRN_PAR].ival = 0;
- pv[PRN_FLO].ival = FLO_KEEP;
- } else if ((x = cmfld(n == PRN_DOS ? /* Value wanted - parse it */
- "DOS printer device name" : /* Help message */
- (n == PRN_PIP ?
- "Program name" :
- "Filename"),
- n == PRN_DOS ?
- "PRN" : /* Default */
- "",
- &s,
- xxstring
- )) < 0)
- goto xsetprn;
- s = brstrip(s); /* Strip enclosing braces */
- while (*s == SP) /* Strip leading blanks */
- s++;
- if (n == PRN_PIP) { /* If /PIPE: */
- if (*s == '|') { /* strip any extraneous pipe sign */
- s++;
- while (*s == SP)
- s++;
- }
- pv[PRN_SPD].ival = 0;
- pv[PRN_PAR].ival = 0;
- pv[PRN_FLO].ival = FLO_KEEP;
- }
- if ((y = strlen(s)) > 0) /* Anything left? */
- if (pv[n].sval = (char *) malloc(y+1)) /* Yes, keep it */
- strcpy(pv[n].sval,s); /* safe */
- break;
-#ifdef NT
- case PRN_WIN: /* Windows queue name */
- typeset++;
- if (pv[n].sval) free(pv[n].sval);
- pv[n].sval = NULL;
- pv[PRN_NON].ival = 0;
- pv[PRN_DOS].ival = 0;
- pv[PRN_FIL].ival = 0;
- pv[n].ival = 1;
- pv[PRN_SPD].ival = 0;
- pv[PRN_PAR].ival = 0;
- pv[PRN_FLO].ival = FLO_KEEP;
-
- if (!getval || !haveque)
- break;
- if ((x = cmkey(_printtab,nprint,"Print queue name",
- _printtab[printdef].kwd,xxstring)) < 0) {
- if (x != -2)
- goto xsetprn;
-
- if (pv[PRN_WIN].sval) free(pv[PRN_WIN].sval);
- s = atmbuf;
- if ((y = strlen(s)) > 0)
- if (pv[n].sval = (char *)malloc(y+1))
- strcpy(pv[n].sval,s); /* safe */
- } else {
- if (pv[PRN_WIN].sval) free(pv[PRN_WIN].sval);
- for (i = 0; i < nprint; i++) {
- if (x == printtab[i].kwval) {
- s = printtab[i].kwd;
- break;
- }
- }
- if ((y = strlen(s)) > 0)
- if (pv[n].sval = (char *)malloc(y+1))
- strcpy(pv[n].sval,s); /* safe */
- }
- break;
-#endif /* NT */
-
- case PRN_SEP: /* /JOB-HEADER (separator) */
- if (pv[n].sval) free(pv[n].sval);
- pv[n].sval = NULL;
- pv[n].ival = 1;
- if (!getval) break;
- if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0)
- goto xsetprn;
- if (y) {
- printf("?Wildcards not allowed\n");
- x = -9;
- goto xsetprn;
- }
- if ((y = strlen(s)) > 0)
- if (pv[n].sval = (char *) malloc(y+1))
- strcpy(pv[n].sval,s); /* safe */
- break;
-
- case PRN_TMO: /* /TIMEOUT:number */
- pv[n].ival = 0;
- if (!getval) break;
- if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0)
- goto xsetprn;
- if (y > 999) {
- printf("?Sorry - 999 is the maximum\n");
- x = -9;
- goto xsetprn;
- } else
- pv[n].ival = y;
- break;
-
- case PRN_TRM: /* /END-OF-JOB:string */
- if (pv[n].sval) free(pv[n].sval);
- pv[n].sval = NULL;
- pv[n].ival = 1;
- if (!getval) break;
- if ((x = cmfld("String (enclose in braces if it contains spaces)",
- "",&s,xxstring)) < 0)
- goto xsetprn;
- s = brstrip(s);
- if ((y = strlen(s)) > 0)
- if (pv[n].sval = (char *) malloc(y+1))
- strcpy(pv[n].sval,s); /* safe */
- break;
-
-#ifdef BPRINT
- case PRN_FLO:
- if (!getval) break;
- if ((x = cmkey(flotab,nflo,
- "Serial printer-port flow control",
- "rts/cts",xxstring)) < 0)
- goto xsetprn;
- pv[n].ival = x;
- break;
-
-#ifndef NOLOCAL
- case PRN_SPD:
- if (!getval) break;
-
- /* TN_COMPORT here too? */
-
- if ((x = cmkey(spdtab, /* Speed (no default) */
- nspd,
- "Serial printer-port interface speed",
- "9600",
- xxstring)
- ) < 0)
- goto xsetprn;
- pv[n].ival = x;
- break;
-#endif /* NOLOCAL */
-
- case PRN_PAR:
- pv[n].ival = 0;
- if (!getval) break;
- if ((x = cmkey(partbl,npar,"Serial printer-port parity",
- "none",xxstring)) < 0)
- goto xsetprn;
- pv[n].ival = x;
- break;
-#endif /* BPRINT */
-
-#ifdef OS2
- case PRN_LEN:
- if (!getval) break;
- if ((x = cmnum("PS page length", "66",10,&y,xxstring)) < 0)
- goto xsetprn;
- pv[n].ival = y;
- break;
-
- case PRN_WID:
- if (!getval) break;
- if ((x = cmnum("PS page width", "80",10,&y,xxstring)) < 0)
- goto xsetprn;
- pv[n].ival = y;
- break;
-
- case PRN_CS:
- pv[n].ival = 0;
- if (!getval) break;
- if ((y = cmkey(
-#ifdef CKOUNI
- txrtab,ntxrtab,
-#else /* CKOUNI */
- ttcstab,ntermc,
-#endif /* CKOUNI */
- "auto-print/printscreen character-set",
- "cp437",xxstring)) < 0)
- goto xsetprn;
- pv[n].ival = y;
- break;
-#endif /* OS2 */
-
- default:
- printf("?Unexpected switch value - %d\n",cmresult.nresult);
- x = -9;
- goto xsetprn;
- }
- }
- line[0] = NUL; /* Initialize printer name value */
- switch (cmresult.fcode) { /* How did we get here? */
- case _CMOFI: /* They typed a filename */
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
- wild = cmresult.nresult; /* Wild flag */
- if (!typeset) { /* A printer name without a type */
- pv[PRN_NON].ival = 0; /* is supposed to be treated as */
- pv[PRN_WIN].ival = 0; /* a DOS or Pipe printer. We */
- pv[PRN_FIL].ival = 0; /* clear all the flags and let */
- pv[PRN_PIP].ival = 0; /* the code below dope out the */
- pv[PRN_DOS].ival = 0; /* type. */
- }
-#ifdef NT
- else if (pv[PRN_WIN].ival && lookup(_printtab,line,nprint,&y)) {
- /* invalid Window Queue name */
- printf("?invalid Windows Printer Queue name: \"%s\"\r\n",line);
- x = -9;
- goto xsetprn;
- }
-#endif /* NT */
- if ((x = cmcfm()) < 0) /* Confirm the command */
- goto xsetprn;
- break;
- case _CMCFM: /* They entered the command */
- if (pv[PRN_DOS].ival > 0)
- ckstrncpy(line,pv[PRN_DOS].sval ? pv[PRN_DOS].sval : "",LINBUFSIZ);
- else if (pv[PRN_WIN].ival > 0)
- ckstrncpy(line,pv[PRN_WIN].sval ? pv[PRN_WIN].sval : "",LINBUFSIZ);
- else if (pv[PRN_FIL].ival > 0)
- ckstrncpy(line,pv[PRN_FIL].sval ? pv[PRN_FIL].sval : "",LINBUFSIZ);
- else if (pv[PRN_PIP].ival > 0)
- ckstrncpy(line,pv[PRN_PIP].sval ? pv[PRN_PIP].sval : "",LINBUFSIZ);
- break;
- default: /* By mistake */
- printf("?Unexpected function code: %d\n",cmresult.fcode);
- x = -9;
- goto xsetprn;
- }
-
-#else /* No PRINTSWI */
-
- if ((x = cmofi("Printer or file name",defname,&s,xxstring)) < 0)
- return(x);
- if (x > 1) {
- printf("?Directory names not allowed\n");
- return(-9);
- }
- while (*s == SP || *s == HT) s++; /* Trim leading whitespace */
- ckstrncpy(line,s,LINBUFSIZ); /* Make a temporary safe copy */
- if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
-#endif /* PRINTSWI */
-
-#ifdef IKSD
- if (inserver && (isguest
-#ifndef NOSERVER
- || !ENABLED(en_pri)
-#endif /* NOSERVER */
- )) {
- printf("Sorry, printing disabled\r\n");
- return(success = 0);
- }
-#endif /* ISKD */
-
-#ifdef PRINTSWI
-#ifdef BPRINT
- if (printbidi) { /* If bidi printing active */
-#ifndef UNIX
- bprtstop(); /* Stop it before proceeding */
-#endif /* UNIX */
- printbidi = 0;
- }
- if (pv[PRN_SPD].ival > 0) {
- portspeed = (long) pv[PRN_SPD].ival * 10L;
- if (portspeed == 70L) portspeed = 75L;
- }
- if (pv[PRN_PAR].ival > 0)
- portparity = pv[PRN_PAR].ival;
- if (pv[PRN_FLO].ival > 0)
- portflow = pv[PRN_FLO].ival;
-#endif /* BPRINT */
-#endif /* PRINTSWI */
-
- s = line; /* Printer name, if given */
-
-#ifdef OS2ORUNIX
-#ifdef PRINTSWI
- if (pv[PRN_PIP].ival > 0) { /* /PIPE was given? */
- printpipe = 1;
- noprinter = 0;
- if (*s == '|') { /* It might still have a pipe sign */
- s++; /* if name give later */
- while (*s == SP) /* so remove it and spaces */
- s++;
- }
- } else
-#endif /* PRINTSWI */
- if (*s == '|') { /* Or pipe implied by name? */
- s++; /* Point past pipe sign */
- while (*s == SP) /* Gobble whitespace */
- s++;
- if (*s) {
- printpipe = 1;
- noprinter = 0;
- }
- } else {
- printpipe = 0;
- }
-
-#ifdef PRINTSWI
-#ifdef BPRINT
- if (printpipe && pv[PRN_BID].ival > 0) {
- printf("?Sorry, pipes not allowed for bidirectional printer\n");
- return(-9);
- }
-#endif /* BPRINT */
-#endif /* PRINTSWI */
-#endif /* OS2ORUNIX */
-
-#ifdef OS2
- if ( pv[PRN_CS].ival > 0 )
- prncs = pv[PRN_CS].ival;
-
- if ( pv[PRN_PS].ival > 0 ) {
- txt2ps = 1;
- ps_width = pv[PRN_WID].ival <= 0 ? 80 : pv[PRN_WID].ival;
- ps_length = pv[PRN_LEN].ival <= 0 ? 66 : pv[PRN_LEN].ival;
- }
-#endif /* OS2 */
-
- y = strlen(s); /* Length of name of new print file */
- if (y > 0
-#ifdef OS2
- && ((y != 3) || (ckstrcmp(s,"PRN",3,0) != 0))
-#endif /* OS2 */
- ) {
- if (printername) { /* Had a print file before? */
- free(printername); /* Remove its name */
- printername = NULL;
- }
- printername = (char *) malloc(y + 1); /* Allocate space for it */
- if (!printername) {
- printf("?Memory allocation failure\n");
- return(-9);
- }
- strcpy(printername,s); /* (safe) Copy new name to new space */
- debug(F110,"printername",printername,0);
- }
-
-#ifdef PRINTSWI
- /* Set printer type from switches that were given explicitly */
-
- if (pv[PRN_NON].ival > 0) { /* No printer */
- printertype = PRT_NON;
- noprinter = 1;
- printpipe = 0;
- } else if (pv[PRN_FIL].ival > 0) { /* File */
- printertype = PRT_FIL;
- noprinter = 0;
- printpipe = 0;
- } else if (pv[PRN_PIP].ival > 0) { /* Pipe */
- printertype = PRT_PIP;
- noprinter = 0;
- printpipe = 1;
- } else if (pv[PRN_WIN].ival > 0) { /* Windows print queue */
- printertype = PRT_WIN;
- noprinter = 0;
- printpipe = 0;
- } else if (pv[PRN_DOS].ival > 0) { /* DOS device */
- printertype = PRT_DOS;
- noprinter = 0;
- printpipe = 0;
- } else if (line[0]) { /* Name given without switches */
- noprinter = 0;
- printertype = printpipe ? PRT_PIP : PRT_DOS;
-#ifdef NT
- /* was the command SET PRINTER windows-queue ? */
- y = lookup(_printtab,line,nprint,&x);
- if (y >= 0) {
- printertype = PRT_WIN;
- if (pv[PRN_WIN].sval) free(pv[PRN_WIN].sval);
- if (printername) { /* Had a print file before? */
- free(printername); /* Remove its name */
- printername = NULL;
- }
- pv[PRN_WIN].sval = NULL;
- pv[PRN_WIN].ival = 1;
- s = printtab[x].kwd; /* Get full new name */
- if ((y = strlen(s)) > 0) {
- makestr(&pv[PRN_WIN].sval,s);
- makestr(&printername,s);
- if (!printername) {
- printf("?Memory allocation failure\n");
- return(-9);
- }
- debug(F110,"printername",printername,0);
- }
- } else if ( y == -2 ) {
- /* Ambiguous Print Queue Name */
- printf("?Ambiguous printer name provided.\n");
- return(-9);
- }
-#endif /* NT */
- }
-
-#ifdef BPRINT
- /* Port parameters may be set for non-bidi mode */
-
- pportspeed = portspeed; /* Set parameters */
- pportparity = portparity;
- pportflow = portflow;
-
- if (pv[PRN_BID].ival > 0) { /* Bidirectional */
-#ifdef UNIX
- printbidi = 1; /* (just to test parsing...) */
-#else
- printbidi = bprtstart(); /* Start bidirectional printer */
-#endif /* UNIX */
- return(success = printbidi);
- } else
- printbidi = 0; /* Not BPRINTER, unset flag */
-#endif /* BPRINT */
-
- if (pv[PRN_TMO].ival > -1) { /* Take care of timeout */
- printtimo = pv[PRN_TMO].ival;
- }
- if (pv[PRN_TRM].ival > 0) { /* Termination string */
- if (printterm) {
- free(printterm);
- printterm = NULL;
- }
- if (pv[PRN_TRM].sval)
- makestr(&printterm,pv[PRN_TRM].sval);
- }
- if (pv[PRN_SEP].ival > 0) { /* and separator file */
- if (printsep) {
- free(printsep);
- printsep = NULL;
- }
- if (pv[PRN_SEP].sval)
- makestr(&printsep,pv[PRN_SEP].sval);
- }
-#endif /* PRINTSWI */
-
-#ifdef UNIXOROSK
- if (!printpipe
-#ifdef PRINTSWI
- && !noprinter
-#endif /* PRINTSWI */
- ) { /* File - check access */
- if (zchko(s) < 0) {
- printf("?Access denied - %s\n",s);
- x = -9;
- goto xsetprn;
- }
- }
-#endif /* UNIXOROSK */
-
- x = 1; /* Return code */
-
- xsetprn: /* Common exit */
-#ifdef PRINTSWI
- for (i = 0; i <= PRN_MAX; i++) { /* Free malloc'd memory */
- if (pv[i].sval)
- free(pv[i].sval);
- }
-#endif /* PRINTSWI */
- success = (x > 0) ? 1 : 0;
- return(x);
-}
-
-#ifdef ANYSSH
-/* The SET SSH command */
-
-#define SSH_CMD 1 /* SET SSH COMMAND */
-
-#ifdef SSHBUILTIN /* Built-in SET SSH options */
-#define SSH_ADD 2 /* Add */
-#define SSH_AFW 3 /* Agent-forwarding */
-#define SSH_CHI 4 /* Check Host IP */
-#define SSH_XFW 5 /* X11-forwarding */
-#define SSH_DYF 6 /* Dynamic forwarding */
-#define SSH_GWP 7 /* Gatewa portgs */
-#define SSH_GSS 8 /* GSSAPI */
-#define SSH_KBD 9 /* KBD Interactive Devices */
-#define SSH_K4 10 /* Kerberos 4 */
-#define SSH_K5 11 /* Kerberos 5 */
-#define SSH_SHK 12 /* Strict Host Key Check */
-#define SSH_V1 13 /* SSH V1 */
-#define SSH_V2 14 /* SSH V2 */
-#define SSH_PRP 15 /* Privd port */
-#define SSH_CMP 16 /* Compression */
-#define SSH_XAL 17 /* X Auth Location */
-#define SSH_SHH 18 /* Quiet */
-#define SSH_VER 19 /* Version */
-#define SSH_VRB 20 /* Verbosity level */
-#define SSH_IDF 21 /* Identity File */
-#define SSH_CFG 22 /* Use OpenSSH Config */
-#define SSH_HBT 23 /* Heartbeat Interval */
-#endif /* SSHBUILTIN */
-
-static struct keytab sshtab[] = { /* SET SSH command table */
-#ifdef SSHBUILTIN
- { "agent-forwarding", SSH_AFW, 0 },
- { "check-host-ip", SSH_CHI, 0 },
- { "compression", SSH_CMP, 0 },
- { "dynamic-forwarding", SSH_DYF, 0 },
- { "gateway-ports", SSH_GWP, 0 },
- { "gssapi", SSH_GSS, 0 },
- { "heartbeat-interval", SSH_HBT, 0 },
- { "identity-file", SSH_IDF, 0 },
-#ifdef COMMENT
- { "kbd-interactive-devices", SSH_KBD, 0 },
-#endif /* COMMENT */
- { "k4", SSH_K4, CM_INV },
- { "k5", SSH_K5, CM_INV },
- { "kerberos4", SSH_K4, 0 },
- { "kerberos5", SSH_K5, 0 },
- { "krb4", SSH_K4, CM_INV },
- { "krb5", SSH_K5, CM_INV },
- { "privileged-port", SSH_PRP, 0 },
- { "quiet", SSH_SHH, 0 },
- { "strict-host-key-check", SSH_SHK, 0 },
- { "use-openssh-config", SSH_CFG, 0 },
- { "v1", SSH_V1, 0 },
- { "v2", SSH_V2, 0 },
- { "verbose", SSH_VRB, 0 },
- { "version", SSH_VER, 0 },
- { "x11-forwarding", SSH_XFW, 0 },
- { "xauth-location", SSH_XAL, 0 },
-#else
-#ifdef SSHCMD
- { "command", SSH_CMD, 0 },
-#endif /* SSHCMD */
-#endif /* SSHBUILTIN */
- { "", 0, 0 }
-};
-static int nsshtab = (sizeof(sshtab) / sizeof(struct keytab)) - 1;
-
-#ifdef SSHBUILTIN
-static struct keytab sshver[] = { /* SET SSH VERSION command table */
- { "1", 1, 0 },
- { "2", 2, 0 },
- { "automatic", 0, 0 }
-};
-
-#define SSHA_CRS 1
-#define SSHA_DSA 2
-#define SSHA_GSS 3
-#define SSHA_HOS 4
-#define SSHA_KBD 5
-#define SSHA_K4 6
-#define SSHA_K5 7
-#define SSHA_PSW 8
-#define SSHA_PK 9
-#define SSHA_SKE 10
-#define SSHA_TIS 11
-#define SSHA_EXT 12
-#define SSHA_SRP 13
-
-static struct keytab ssh2aut[] = { /* SET SSH V2 AUTH command table */
- { "external-keyx", SSHA_EXT, 0 },
- { "gssapi", SSHA_GSS, 0 },
- { "hostbased", SSHA_HOS, 0 },
- { "keyboard-interactive", SSHA_KBD, 0 },
- { "password", SSHA_PSW, 0 },
- { "publickey", SSHA_PK, 0 },
- { "srp-gex-sha1", SSHA_SRP, 0 },
- { "", 0, 0 }
-};
-static int nssh2aut = (sizeof(ssh2aut) / sizeof(struct keytab)) - 1;
-
-#define SSHF_LCL 1
-#define SSHF_RMT 2
-
-static struct keytab addfwd[] = { /* SET SSH ADD command table */
- { "local-port-forward", SSHF_LCL, 0 },
- { "remote-port-forward", SSHF_RMT, 0 },
- { "", 0, 0 }
-};
-static int naddfwd = (sizeof(addfwd) / sizeof(struct keytab)) - 1;
-
-#define SSH1_CIF 1
-#define SSH1_GNH 2
-#define SSH1_UNH 3
-#define SSH1_K54 4
-
-#define SSH2_CIF 1
-#define SSH2_GNH 2
-#define SSH2_UNH 3
-#define SSH2_ARK 4
-#define SSH2_HKA 5
-#define SSH2_MAC 6
-#define SSH2_AUT 7
-
-static struct keytab sshv1tab[] = { /* SET SSH V1 command table */
- { "cipher", SSH1_CIF, 0 },
- { "global-known-hosts-file", SSH1_GNH, 0 },
- { "k5-reuse-k4-messages", SSH1_K54, CM_INV },
- { "user-known-hosts-file", SSH1_UNH, 0 },
- { "", 0, 0 }
-};
-static int nsshv1tab = (sizeof(sshv1tab) / sizeof(struct keytab)) - 1;
-
-static struct keytab sshv2tab[] = { /* SET SSH V2 command table */
- { "authentication", SSH2_AUT, 0 },
- { "auto-rekey", SSH2_ARK, 0 },
- { "ciphers", SSH2_CIF, 0 },
- { "global-known-hosts-file", SSH2_GNH, 0 },
- { "hostkey-algorithms", SSH2_HKA, 0 },
- { "macs", SSH2_MAC, 0 },
- { "user-known-hosts-file", SSH2_UNH, 0 },
- { "", 0, 0 }
-};
-static int nsshv2tab = (sizeof(sshv2tab) / sizeof(struct keytab)) - 1;
-
-#define SSHC_3DES 1 /* 3DES */
-#define SSHC_3CBC 2 /* 3DES-CBC */
-#define SSHC_A128 3 /* AES128-CBC */
-#define SSHC_A192 4 /* AES192-CBC */
-#define SSHC_A256 5 /* AES256-CBC */
-#define SSHC_ARC4 6 /* ARCFOUR */
-#define SSHC_FISH 7 /* BLOWFISH */
-#define SSHC_BCBC 9 /* BLOWFISH-CBC */
-#define SSHC_C128 8 /* CAST128-CBC */
-#define SSHC_1DES 10 /* DES */
-
-static struct keytab ssh1ciphers[] = {
- { "3des", SSHC_3DES, 0 },
- { "blowfish", SSHC_FISH, 0 },
- { "des", SSHC_1DES, 0 },
- { "", 0, 0 }
-};
-static int nssh1ciphers = (sizeof(ssh1ciphers) / sizeof(struct keytab)) - 1;
-
-static struct keytab ssh2ciphers[] = { /* SET SSH V2 CIPHERS command table */
- { "3des-cbc", SSHC_3DES, 0 },
- { "aes128-cbc", SSHC_A128, 0 },
- { "aes192-cbc", SSHC_A192, 0 },
- { "aes256-cbc", SSHC_A256, 0 },
- { "arcfour", SSHC_ARC4, 0 },
- { "blowfish-cbc", SSHC_FISH, 0 },
- { "cast128-cbc", SSHC_C128, 0 },
- { "rijndael128-cbc", SSHC_A128, 0 },
- { "rijndael192-cbc", SSHC_A192, 0 },
- { "rijndael256-cbc", SSHC_A256, 0 },
- { "", 0, 0 }
-};
-static int nssh2ciphers = (sizeof(ssh2ciphers) / sizeof(struct keytab)) - 1;
-
-#define SSHM_SHA 1 /* HMAC-SHA1 */
-#define SSHM_SHA_96 2 /* HMAC-SHA1-96 */
-#define SSHM_MD5 3 /* HMAC-MD5 */
-#define SSHM_MD5_96 4 /* HMAC-MD5-96 */
-#define SSHM_RIPE 5 /* HMAC-RIPEMD160 */
-
-static struct keytab ssh2macs[] = { /* SET SSH V2 MACS command table */
- { "hmac-md5", SSHM_MD5, 0 },
- { "hmac-md5-96", SSHM_MD5_96, 0 },
- { "hmac-ripemd160", SSHM_RIPE, 0 },
- { "hmac-sha1", SSHM_SHA, 0 },
- { "hmac-sha1-96", SSHM_SHA_96, 0 },
- { "", 0, 0 }
-};
-static int nssh2macs = (sizeof(ssh2macs) / sizeof(struct keytab)) - 1;
-
-static struct keytab tgtpass[] = {
- { "tgt-passing", 1, 0, },
- { "", 0, 0 }
-};
-static int ntgtpass = (sizeof(tgtpass) / sizeof(struct keytab)) - 1;
-
-static struct keytab gssapitab[] = {
- { "delegate-credentials", 1, 0, },
- { "key-exchange", 2, CM_INV, },
- { "", 0, 0 }
-};
-static int ngssapitab = (sizeof(gssapitab) / sizeof(struct keytab)) - 1;
-
-#define HKA_RSA 1
-#define HKA_DSS 2
-
-static struct keytab hkatab[] = {
- { "ssh-dss", HKA_DSS, 0, },
- { "ssh-rsa", HKA_RSA, 0, },
- { "", 0, 0 }
-};
-static int nhkatab = (sizeof(hkatab) / sizeof(struct keytab)) - 1;
-
-int /* SET SSH variables */
- ssh_afw = 0, /* agent forwarding */
- ssh_xfw = 0, /* x11 forwarding */
- ssh_prp = SET_OFF, /* privileged ports */
- ssh_cmp = 1, /* compression */
- ssh_shh = 0, /* quiet */
- ssh_ver = 0, /* protocol version (auto,1,2) */
- ssh_vrb = 2, /* Report errors */
- ssh_chkip = 0, /* SSH Check Host IP flag */
- ssh_gwp = 0, /* gateway ports */
- ssh_dyf = 0, /* dynamic forwarding */
- ssh_gsd = 0, /* gssapi delegate credentials */
- ssh_k4tgt = 0, /* k4 tgt passing */
- ssh_k5tgt = 0, /* k5 tgt passing */
- ssh_shk = 2, /* Strict host key (no, yes, ask) */
- ssh2_ark = 1, /* Auto re-key */
- ssh_cas = 0, /* command as subsys */
- ssh_cfg = 0, /* use OpenSSH config? */
- ssh_gkx = 1, /* gssapi key exchange */
- ssh_k5_is_k4 = 1, /* some SSH v1 use same codes */
- ssh_hbt = 0, /* heartbeat (seconds) */
- ssh_dummy = 0; /* bottom of list */
-
-char /* The following are to be malloc'd */
- * ssh1_cif = NULL, /* v1 cipher */
- * ssh2_cif = NULL, /* v2 cipher list */
- * ssh2_mac = NULL, /* v2 mac list */
- * ssh2_auth = NULL, /* v2 authentication list */
- * ssh_hst = NULL, /* hostname */
- * ssh_prt = NULL, /* port/service */
- * ssh_cmd = NULL, /* command to execute */
- * ssh_xal = NULL, /* xauth-location */
- * ssh1_gnh = NULL, /* v1 global known hosts file */
- * ssh1_unh = NULL, /* v1 user known hosts file */
- * ssh2_gnh = NULL, /* v2 global known hosts file */
- * ssh2_unh = NULL, /* v2 user known hosts file */
- * ssh2_hka = NULL, /* Host Key Algorithms */
- * xxx_dummy = NULL;
-
-char * ssh_idf[32] = { /* Identity file list */
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
-};
-char * ssh_tmp[32] = { /* Temp identity file list */
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
-};
-int ssh_idf_n = 0;
-
-extern int ssh_pf_lcl_n,
- ssh_pf_rmt_n;
-extern struct ssh_pf ssh_pf_lcl[32]; /* Port forwarding structs */
-extern struct ssh_pf ssh_pf_rmt[32]; /* (declared in ckuusr.c) */
-#endif /* SSHBUILTIN */
-
-#ifdef SFTP_BUILTIN
-static struct keytab sftptab[] = {
- { "end-of-line", XY_SFTP_EOL, 0, },
- { "remote-character-set", XY_SFTP_RCS, 0, },
- { "", 0, 0 }
-};
-static int nsftptab = (sizeof(sftptab) / sizeof(struct keytab)) - 1;
-#endif /* SFTP_BUILTIN */
-
-VOID
-shossh() {
-#ifdef SSHBUILTIN
- int i, n = 0; /* ADD askmore()! */
-
- printf("\nSSH is built in:\n\n");
-
- printf(" ssh host: %s\n",showstring(ssh_hst));
- printf(" ssh port: %s\n",showstring(ssh_prt));
- printf(" ssh command: %s\n",showstring(ssh_cmd));
- printf(" ssh agent-forwarding: %s\n",showoff(ssh_afw));
- printf(" ssh check-host-ip: %s\n",showoff(ssh_chkip));
- printf(" ssh compression: %s\n",showoff(ssh_cmp));
- printf(" ssh dynamic-forwarding: %s\n",showoff(ssh_dyf));
- if (ssh_pf_lcl[0].p1 && ssh_pf_lcl[0].host && ssh_pf_lcl[0].p2) {
- printf(" ssh forward-local-port: %d %s %d\n",
- ssh_pf_lcl[0].p1, ssh_pf_lcl[0].host, ssh_pf_lcl[0].p2);
- for ( n=1;n<ssh_pf_lcl_n;n++ )
- printf(" : %d %s %d\n",
- ssh_pf_lcl[n].p1, ssh_pf_lcl[n].host, ssh_pf_lcl[n].p2);
- } else
- printf(" ssh forward-local-port: (none)\n");
- if (ssh_pf_rmt[0].p1 && ssh_pf_rmt[0].host && ssh_pf_rmt[0].p2) {
- printf(" ssh forward-remote-port: %d %s %d\n",
- ssh_pf_rmt[0].p1, ssh_pf_rmt[0].host, ssh_pf_rmt[0].p2);
- for ( n=1;n<ssh_pf_rmt_n;n++ )
- printf(" : %d %s %d\n",
- ssh_pf_rmt[n].p1, ssh_pf_rmt[n].host, ssh_pf_rmt[n].p2);
- } else
- printf(" ssh forward-remote-port: (none)\n");
- printf(" ssh gateway-ports: %s\n",showoff(ssh_gwp));
- printf(" ssh gssapi delegate-credentials: %s\n",showoff(ssh_gsd));
- printf(" ssh gssapi key-exchange : %s\n",showoff(ssh_gkx));
- printf(" ssh identity-file: %d\n",ssh_idf_n);
- for (i = 0; i < ssh_idf_n; i++)
- printf(" %2d. %s\n",i+1,showstring(ssh_idf[i]));
- printf(" ssh heartbeat interval: %d\n", ssh_hbt);
- printf(" ssh k4 tgt-passing: %s\n",showoff(ssh_k4tgt));
- printf(" ssh k5 tgt-passing: %s\n",showoff(ssh_k5tgt));
-
- printf(" ssh privileged-port: %s\n",showooa(ssh_prp));
- printf(" ssh quiet: %s\n",showoff(ssh_shh));
- printf(" ssh strict-host-key-check: %d\n",ssh_shk);
- printf(" ssh use-openssh-config: %s\n",showoff(ssh_cfg));
- printf(" ssh verbose: %d\n",ssh_vrb);
- printf(" ssh version: %s\n",
- ssh_ver ? ckitoa(ssh_ver) : "automatic"
- );
- printf(" ssh x11-forwarding: %s\n",showooa(ssh_xfw));
- printf(" ssh xauth-location: %s\n",showstring(ssh_xal));
- printf("\n");
- printf(" ssh v1 cipher: %s\n",showstring(ssh1_cif));
- printf(" ssh v1 global-known-hosts-file: %s\n",showstring(ssh1_gnh));
- printf(" ssh v1 user-known-hosts-file: %s\n",showstring(ssh1_unh));
- printf("\n");
- printf(" ssh v2 authentication: %s\n",showstring(ssh2_auth));
- printf(" ssh v2 auto-rekey: %s\n",showoff(ssh2_ark));
- printf(" ssh v2 ciphers: %s\n",showstring(ssh2_cif));
- printf(" ssh v2 command-as-subsystem: %s\n",showoff(ssh_cas));
- printf(" ssh v2 global-known-hosts-file: %s\n",showstring(ssh2_gnh));
- printf(" ssh v2 hostkey-algorithms: %s\n",showstring(ssh2_hka));
- printf(" ssh v2 mac: %s\n",showstring(ssh2_mac));
- printf(" ssh v2 user-known-hosts-file: %s\n",showstring(ssh2_unh));
-#else
-#ifdef SSHCMD
- extern char * sshcmd, * defsshcmd;
- char * s;
- s = sshcmd ? sshcmd : defsshcmd;
- printf("\n SSH is external.\n\n");
- printf(" ssh command: %s\n",showstring(s));
-#endif /* SSHCMD */
-#endif /* SSHBUILTIN */
- printf("\n");
-}
-
-static int
-dosetssh() {
-#ifdef SSHCMD
- extern char * sshcmd;
-#endif /* SSHCMD */
-#ifdef SSHBUILTIN
-#ifndef SSHTEST
- extern int sl_ssh_xfw_saved, sl_ssh_ver_saved;
-#endif /* SSHTEST */
-#endif /* SSHBUILTIN */
- int cx, x, y, z;
- char * s;
-
- if ((cx = cmkey(sshtab,nsshtab,"","command", xxstring)) < 0)
- return(cx);
- switch (cx) {
-#ifdef SSHCMD
- case SSH_CMD: /* Command */
- if ((x = cmtxt("Command to start ssh","ssh -e none",
- &s,xxstring)) < 0)
- return(x);
- makestr(&sshcmd,s);
- return(success = 1);
-#endif /* SSHCMD */
-
-#ifdef SSHBUILTIN
- case SSH_AFW: /* Agent-forwarding */
- return(success = seton(&ssh_afw));
-
- case SSH_CHI: /* Check Host IP */
- return(success = seton(&ssh_chkip));
- break;
-
- case SSH_CMP: /* Compression */
- return(success = seton(&ssh_cmp));
-
- case SSH_DYF: /* Dynamic Forwarding */
- return(success = seton(&ssh_dyf));
-
- case SSH_GWP: /* Gateway ports */
- return(success = seton(&ssh_gwp));
-
- case SSH_GSS: /* GSSAPI */
- if ((y = cmkey(gssapitab,ngssapitab,"","", xxstring)) < 0)
- return(y);
- switch (y) {
- case 1: /* Delegate credentials */
- return(success = seton(&ssh_gsd));
- case 2: /* key-exchange */
- return(success = seton(&ssh_gkx));
- }
- if ((x = cmcfm()) < 0)
- return(x);
- return(success = 0);
-
-#ifdef COMMENT
- case SSH_KBD: /* Kbd Interactive Devices */
- if ((x = cmcfm()) < 0)
- return(x);
- /* TO BE FILLED IN */
- return(-2);
-#endif /* COMMENT */
-
- case SSH_K4: /* Kerberos IV */
- case SSH_K5: /* Kerberos V */
- if ((y = cmkey(tgtpass,1,"","tgt-passing", xxstring)) < 0)
- return(y);
- switch (y) {
- case 1:
- return(success = (cx == SSH_K4) ?
- seton(&ssh_k4tgt) : seton(&ssh_k5tgt));
- }
- if ((x = cmcfm()) < 0)
- return(x);
- return(success = 0);
-
- case SSH_PRP: /* Privd port */
- return(success = seton(&ssh_prp));
-
- case SSH_SHH: /* Quiet */
- return(success = seton(&ssh_shh));
-
- case SSH_SHK: /* Strict Host Key Check */
- if ((y = cmkey(ooktab,3,"","", xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- ssh_shk = y;
- return(success = 1);
-
- case SSH_HBT:
- x = cmnum("Heartbeat interval, seconds","0",10,&z,xxstring);
- if (x < 0) return(x);
- if ((x = cmcfm()) < 0) return(x);
- ssh_hbt = z;
- return(success = 1);
-
- case SSH_V1: /* SSH V1 */
- if ((y = cmkey(sshv1tab,nsshv1tab,"","", xxstring)) < 0)
- return(y);
- switch (y) {
- case SSH1_K54:
- return(success = seton(&ssh_k5_is_k4));
- case SSH1_CIF: /* Not a list */
- if ((y = cmkey(ssh1ciphers,nssh1ciphers,"","", xxstring)) < 0)
- if (y != -3)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- if (y == -3) {
- makestr(&ssh1_cif,NULL);
- } else {
- for (x = 0; x < nssh1ciphers; x++)
- if (ssh1ciphers[x].kwval == y)
- break;
- makestr(&ssh1_cif,ssh1ciphers[x].kwd);
- }
- return(1);
- case SSH1_GNH:
- case SSH1_UNH:
- if ((x = cmifi("Filename","",&s,&z,xxstring)) < 0) {
- if (x != -3)
- return(x);
- } else {
- ckstrncpy(line,s,LINBUFSIZ);
- if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
- ckstrncpy(line,tmpbuf,LINBUFSIZ);
- }
- s = (x == -3) ? NULL : line;
- if ((x = cmcfm()) < 0)
- return(x);
- switch (y) {
- case SSH1_GNH: makestr(&ssh1_gnh,s); break;
- case SSH1_UNH: makestr(&ssh1_unh,s); break;
- }
- return(1);
- }
-
- case SSH_V2: /* SSH V2 */
- if ((y = cmkey(sshv2tab,nsshv2tab,"","", xxstring)) < 0)
- return(y);
- switch (y) {
- case SSH2_ARK:
- return(success = seton(&ssh2_ark));
- case SSH2_AUT: { /* Authentication */
-#define TMPCNT 12
- int i, j, tmp[TMPCNT];
- for (i = 0; i < TMPCNT; i++)
- tmp[i] = 0;
- for (i = 0; i < TMPCNT; i++) {
- if ((y = cmkey(ssh2aut,nssh2aut,
- "Authentication method","",xxstring)) < 0) {
- if (y == -3)
- break;
- return(y);
- }
- for (j = 0; j < i; j++) {
- if (tmp[j] == y) {
- printf("\r\n?Choice has already been used.\r\n");
- return(-9);
- }
- }
- tmp[i] = y;
- }
- if ((z = cmcfm()) < 0)
- return(z);
-
- if (ssh2_auth) {
- free(ssh2_auth);
- ssh2_auth = NULL;
- }
- if (i > 0) {
- int len = 0;
- for (j = 0; j < i; j++) {
- for (x = 0; x < nssh2aut; x++)
- if (ssh2aut[x].kwval == tmp[j] && !ssh2aut[x].flgs)
- break;
- len += strlen(ssh2aut[x].kwd) + 1;
- }
- ssh2_auth = malloc(len);
- ssh2_auth[0] = '\0';
- for (j = 0; j < i; j++) {
- for (x = 0; x < nssh2aut; x++)
- if (ssh2aut[x].kwval == tmp[j] && !ssh2aut[x].flgs)
- break;
- ckstrncat(ssh2_auth,ssh2aut[x].kwd,len);
- if (j < i - 1)
- ckstrncat(ssh2_auth,",",len);
- }
- }
- return(success = 1);
-#undef TMPCNT
- }
- case SSH2_CIF: {
-#define TMPCNT 12
- int i, j, tmp[TMPCNT];
- for (i = 0; i < TMPCNT; i++)
- tmp[i] = 0;
-
- for (i = 0; i < TMPCNT; i++) {
- if ((y = cmkey(ssh2ciphers,nssh2ciphers,
- "","", xxstring)) < 0) {
- if (y == -3)
- break;
- return(y);
- }
- for (j = 0; j < i; j++) {
- if (tmp[j] == y) {
- printf("\r\n?Choice has already been used.\r\n");
- return(-9);
- }
- }
- tmp[i] = y;
- }
- if ((z = cmcfm()) < 0)
- return(z);
-
- if (ssh2_cif) {
- free(ssh2_cif);
- ssh2_cif = NULL;
- }
- if (i > 0) {
- int len = 0;
- for (j=0; j < i; j++) {
- for (x = 0; x < nssh2ciphers; x++)
- if (ssh2ciphers[x].kwval == tmp[j] &&
- !ssh2ciphers[x].flgs)
- break;
- len += strlen(ssh2ciphers[x].kwd) + 1;
- }
- ssh2_cif = malloc(len);
- ssh2_cif[0] = '\0';
- for (j = 0; j < i; j++) {
- for (x = 0; x < nssh2ciphers; x++)
- if (ssh2ciphers[x].kwval == tmp[j] && !ssh2ciphers[x].flgs)
- break;
- ckstrncat(ssh2_cif,ssh2ciphers[x].kwd,len);
- if (j < i - 1)
- ckstrncat(ssh2_cif,",",len);
- }
- }
- return(success = 1);
-#undef TMPCNT
- }
- case SSH2_MAC: {
-#define TMPCNT 12
- int i, j, tmp[TMPCNT];
- for (i = 0; i < TMPCNT; i++)
- tmp[i] = 0;
-
- for (i = 0; i < TMPCNT; i++) {
- if ((y = cmkey(ssh2macs,nssh2macs,"","", xxstring)) < 0) {
- if (y == -3)
- break;
- return(y);
- }
- for (j = 0; j < i; j++) {
- if (tmp[j] == y) {
- printf("\r\n?Choice has already been used.\r\n");
- return(-9);
- }
- }
- tmp[i] = y;
- }
- if ((z = cmcfm()) < 0)
- return(z);
-
- if (ssh2_mac) {
- free(ssh2_mac);
- ssh2_mac = NULL;
- }
- if (i > 0) {
- int len = 0;
- for (j = 0; j < i; j++) {
- for (x = 0; x < nssh2macs; x++)
- if (ssh2macs[x].kwval == tmp[j] && !ssh2macs[x].flgs)
- break;
- len += strlen(ssh2macs[x].kwd) + 1;
- }
- ssh2_mac = malloc(len);
- ssh2_mac[0] = '\0';
- for (j=0; j < i; j++) {
- for (x = 0; x < nssh2macs; x++)
- if (ssh2macs[x].kwval == tmp[j] && !ssh2macs[x].flgs)
- break;
- ckstrncat(ssh2_mac,ssh2macs[x].kwd,len);
- if (j < i - 1)
- ckstrncat(ssh2_mac,",",len);
- }
- }
- return(success = 1);
-#undef TMPCNT
- }
- case SSH2_HKA: {
-#define TMPCNT 12
- int i, j, tmp[TMPCNT];
- for (i = 0; i < TMPCNT; i++)
- tmp[i] = 0;
-
- for (i = 0; i < TMPCNT; i++) {
- if ((y = cmkey(hkatab,nhkatab,
- "","", xxstring)) < 0) {
- if (y == -3)
- break;
- return(y);
- }
- for (j = 0; j < i; j++) {
- if (tmp[j] == y) {
- printf("\r\n?Choice has already been used.\r\n");
- return(-9);
- }
- }
- tmp[i] = y;
- }
- if ((z = cmcfm()) < 0)
- return(z);
-
- if (ssh2_hka) {
- free(ssh2_hka);
- ssh2_hka = NULL;
- }
- if (i > 0) {
- int len = 0;
- for (j=0; j < i; j++) {
- for (x = 0; x < nhkatab; x++)
- if (hkatab[x].kwval == tmp[j] &&
- !hkatab[x].flgs)
- break;
- len += strlen(hkatab[x].kwd) + 1;
- }
- ssh2_hka = malloc(len);
- ssh2_hka[0] = '\0';
- for (j = 0; j < i; j++) {
- for (x = 0; x < nhkatab; x++)
- if (hkatab[x].kwval == tmp[j] && !hkatab[x].flgs)
- break;
- ckstrncat(ssh2_hka,hkatab[x].kwd,len);
- if (j < i - 1)
- ckstrncat(ssh2_hka,",",len);
- }
- }
- return(success = 1);
-#undef TMPCNT
- }
- case SSH2_GNH:
- case SSH2_UNH:
- if ((x = cmifi("Filename","",&s,&z,xxstring)) < 0) {
- if (x != -3)
- return(x);
- } else {
- ckstrncpy(line,s,LINBUFSIZ);
- if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
- ckstrncpy(line,tmpbuf,LINBUFSIZ);
- }
- s = (x == -3) ? NULL : line;
- if ((x = cmcfm()) < 0)
- return(x);
- switch (y) {
- case SSH2_GNH: makestr(&ssh2_gnh,s); break;
- case SSH2_UNH: makestr(&ssh2_unh,s); break;
- default: return(success = 0);
- }
- return(success = 1);
- }
-
- case SSH_VRB: /* Verbosity level */
- y = cmnum("SSH verbosity level, 0-7","2",10,&x,xxstring);
- return(setnum(&ssh_vrb,x,y,7));
-
- case SSH_VER: /* Version */
- if ((y = cmkey(sshver,3,"","auto", xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- ssh_ver = y; /* 0 == AUTO */
-#ifndef SSHTEST
- sl_ssh_ver_saved = 0;
-#endif /* SSHTEST */
- return(success = 1);
-
- case SSH_IDF: { /* Identity file */
- int i, n;
- for (i = 0; i < 32; i++) {
- if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0) {
- if (x == -3)
- break;
- return(x);
- }
- if (!zfnqfp(s,LINBUFSIZ,line))
- ckstrncpy(line,s,LINBUFSIZ);
- makestr(&ssh_tmp[i],line);
- }
- n = i;
- if ((x = cmcfm()) < 0) {
- for (i = 0; i < n; i++)
- makestr(&(ssh_tmp[i]),NULL);
- return(x);
- }
- for (i = 0; i < 32; i++) {
- makestr(&(ssh_idf[i]),NULL);
- if (i < n) {
- ssh_idf[i] = ssh_tmp[i];
- ssh_tmp[i] = NULL;
- } else {
- makestr(&(ssh_tmp[i]),NULL);
- }
- }
- ssh_idf_n = n;
- return(success = 1);
- }
- case SSH_XFW: /* X11-forwarding */
- success = seton(&ssh_xfw);
-#ifndef SSHTEST
- if (success)
- sl_ssh_xfw_saved = 0;
-#endif /* SSHTEST */
- return(success);
-
- case SSH_XAL: /* SSH Xauth Location */
- if ((x = cmifi("Path to executable", "",&s,&y,xxstring)) < 0) {
- if (x != -3)
- return(x);
- } else {
- ckstrncpy(line,s,LINBUFSIZ);
- if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
- ckstrncpy(line,tmpbuf,LINBUFSIZ);
- }
- s = (x == -3) ? NULL : line;
- if ((x = cmcfm()) < 0) return(x);
- makestr(&ssh_xal,s);
- return(success = 1);
-
- case SSH_CFG: /* Use OpenSSH Config */
- return(success = seton(&ssh_cfg));
-#endif /* SSHBUILTIN */
-
- default:
- return(-2);
- }
-}
-#endif /* ANYSSH */
-
-#ifdef SFTP_BUILTIN
-static int
-dosetsftp() {
- int cx, x, y, z;
- char * s;
-
- if ((cx = cmkey(sftptab,nsftptab,"","", xxstring)) < 0)
- return(cx);
- switch (cx) {
- case XY_SFTP_EOL:
- case XY_SFTP_RCS:
- default:
- return(-2);
- }
-}
-#endif /* SFTP_BUILTIN */
-
-#ifdef KUI
-#include "ikui.h"
-extern ULONG RGBTable[16];
-
-#define GUI_RGB 1
-#define GUI_WIN 2
-#define GUI_FON 3
-#define GUI_DIA 4
-#define GUI_TLB 5
-#define GUI_MNB 6
-#define GUI_CLS 7
-
-#define GUIW_POS 1
-#define GUIW_RES 2
-#define GUIW_RUN 3
-#define GUIWR_NON 0
-#define GUIWR_FON 1
-#define GUIWR_DIM 2
-#define GUIWN_RES 1
-#define GUIWN_MIN 2
-#define GUIWN_MAX 3
-
-static struct keytab guitab[] = {
- { "close", GUI_CLS, 0 },
- { "dialogs", GUI_DIA, 0 },
- { "font", GUI_FON, 0 },
- { "menubar", GUI_MNB, 0 },
- { "rgbcolor", GUI_RGB, 0 },
- { "toolbar", GUI_TLB, 0 },
- { "window", GUI_WIN, 0 },
- { "", 0, 0}
-};
-static int nguitab = (sizeof(guitab) / sizeof(struct keytab));
-
-static struct keytab guiwtab[] = {
- { "position", GUIW_POS, 0 },
- { "resize-mode", GUIW_RES, 0 },
- { "run-mode", GUIW_RUN, 0 },
- { "", 0, 0}
-};
-static int nguiwtab = (sizeof(guiwtab) / sizeof(struct keytab));
-
-static struct keytab guiwrtab[] = {
- { "change-dimensions", GUIWR_DIM, 0 },
- { "none", GUIWR_NON, 0 },
- { "scale-font", GUIWR_FON, 0 },
- { "", 0, 0}
-};
-static int nguiwrtab = (sizeof(guiwrtab) / sizeof(struct keytab));
-
-static struct keytab guiwntab[] = {
- { "maximize", GUIWN_MAX, 0 },
- { "minimize", GUIWN_MIN, 0 },
- { "restore", GUIWN_RES, 0 },
- { "", 0, 0}
-};
-static int nguiwntab = (sizeof(guiwntab) / sizeof(struct keytab));
-
-static struct keytab rgbtab[] = {
- { "black", 0, 0 },
- { "blue", 1, 0 },
- { "brown", 6, 0 },
- { "cyan", 3, 0 },
- { "darkgray", 8, 0 },
- { "dgray", 8, CM_INV },
- { "green", 2, 0 },
- { "lblue", 9, CM_INV },
- { "lcyan", 11, CM_INV },
- { "lgreen", 10, CM_INV },
- { "lgray", 7, CM_INV },
- { "lightblue", 9, 0 },
- { "lightcyan", 11, 0 },
- { "lightgreen", 10, 0 },
- { "lightgray", 7, 0 },
- { "lightmagenta", 13, 0 },
- { "lightred", 12, 0 },
- { "lmagenta", 13, CM_INV },
- { "lred", 12, CM_INV },
- { "magenta", 5, 0 },
- { "red", 4, 0 },
- { "white", 15, 0 },
- { "yellow", 14, 0 },
-
-};
-int nrgb = (sizeof(rgbtab) / sizeof(struct keytab));
-
-VOID
-shogui() {
- extern gui_dialog;
- extern HWND getHwndKUI();
- unsigned char cmdsav = colorcmd;
- int i, red, green, blue, lines=0;
- char * s;
-
-
- printf("GUI paramters:\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" Dialogs: %s\n",showoff(gui_dialog));
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" Position: %d,%d\n",get_gui_window_pos_x(),
- get_gui_window_pos_y());
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" Resolution: %d x %d\n",GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN));
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" Run-mode: %s\n",IsIconic(getHwndKUI()) ? "minimized" :
- IsZoomed(getHwndKUI()) ? "maximized" : "restored");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- switch ( get_gui_resize_mode() ) {
- case GUIWR_NON:
- s = "none";
- break;
- case GUIWR_FON:
- s = "scales font";
- break;
- case GUIWR_DIM:
- s= "changes dimensions";
- break;
- }
- printf(" Resize-mode: %s\n",s);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- printf("RGB Color Table:\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" Color Red Green Blue\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" ------------------------------------------\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- for (i = 0; i < nrgb; i++) {
- if (!rgbtab[i].flgs) {
- blue = (RGBTable[rgbtab[i].kwval] & 0x00FF0000)>>16;
- green = (RGBTable[rgbtab[i].kwval] & 0x0000FF00)>>8;
- red = (RGBTable[rgbtab[i].kwval] & 0x000000FF);
- printf(" %-18s %3d %3d %3d ",rgbtab[i].kwd,red,green,blue);
- colorcmd = rgbtab[i].kwval << 4;
- printf("********");
- colorcmd = cmdsav;
- printf("\n");
- if (++lines > cmd_rows - 3) {
- if (!askmore())
- return;
- else
- lines = 0;
- }
- }
- }
- printf("\n");
-}
-
-int
-setrgb() {
- int cx, red = 0, blue = 0, green = 0, z, x;
-
- if ((cx = cmkey(rgbtab,nrgb,"","",xxstring)) < 0)
- return(cx);
- if ((z = cmnum("Red value, 0-255","",10,&red,xxstring)) < 0)
- return(z);
- if ((z = cmnum("Green value, 0-255","",10,&green,xxstring)) < 0)
- return(z);
- if ((z = cmnum("Blue value, 0-255","",10,&blue,xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (cx > 15 || red > 255 || blue > 255 || green > 255)
- return(-2);
- RGBTable[cx] = (unsigned)(((unsigned)blue << 16) |
- (unsigned)((unsigned)green << 8) |
- (unsigned)red);
- return(success = 1);
-}
-
-/*
- Set GUI window position: XY coordinates of upper left corner,
- expressed as pixel numbers in the current screen resolution.
- (0,0) means put ourselves in the upper left corner.
- Can we check for out of bounds?
-*/
-
-int
-setguiwin() {
- int cx, x, y, z;
- if ((cx = cmkey(guiwtab,nguiwtab,"","",xxstring)) < 0)
- return(cx);
- switch (cx) {
- case GUIW_POS:
- if ((z = cmnum("X coordinate (pixel number)","",10,&x,xxstring)) < 0)
- return(z);
- if ((z = cmnum("Y coordinate (pixel number)","",10,&y,xxstring)) < 0)
- return(z);
- if ((z = cmcfm()) < 0)
- return(z);
- if (x < 0 || y < 0) {
- printf("?Coordinates must be 0 or greater\n");
- return(-9);
- }
- gui_position(x,y);
- return(success = 1);
- case GUIW_RES:
- if ((x = cmkey(guiwrtab,nguiwrtab,"","",xxstring)) < 0)
- return(x);
- if ((z = cmcfm()) < 0)
- return(z);
- gui_resize_mode(x);
- return(success = 1);
- case GUIW_RUN:
- if ((x = cmkey(guiwntab,nguiwntab,"","",xxstring)) < 0)
- return(x);
- if ((z = cmcfm()) < 0)
- return(z);
- gui_win_run_mode(x);
- return(success = 1);
- default:
- return(-2);
- }
-}
-
-int
-setguifont() { /* Assumes that CKFLOAT is defined! */
-
- extern struct keytab * term_font;
- extern struct keytab * _term_font;
- extern int tt_font, tt_font_size, ntermfont;
- int x, y, z;
- char *s;
-
- if (ntermfont == 0)
- BuildFontTable(&term_font, &_term_font, &ntermfont);
- if (!(term_font && _term_font && ntermfont > 0)) {
- printf("?Internal error: Failure to enumerate fonts\n");
- return(-9);
- }
- if ((x = cmkey(_term_font,ntermfont,"","",xxstring)) < 0)
- return(x);
- if ((z = cmfld("Height of font in points","12",&s,xxstring)) < 0)
- return(z);
- if (isfloat(s,0) < 1) { /* (sets floatval) */
- printf("?Integer or floating-point number required\n");
- return(-9);
- }
- if (floatval < 0.5) {
- printf("?Positive number required\n");
- return(-9);
- }
- if ((z = cmcfm()) < 0)
- return(z);
- tt_font = x; /* Font index */
- tt_font_size = (int)(floatval * 2); /* Font size in half points */
- KuiSetProperty(KUI_TERM_FONT, (long)tt_font, (long)tt_font_size);
- return(success = 1);
-}
-
-VOID
-setguidialog(x) int x;
-{
- extern int gui_dialog;
- gui_dialog = x;
- KuiSetProperty(KUI_GUI_DIALOGS, (long)x, 0L);
-}
-
-VOID
-setguimenubar(x) int x;
-{
- KuiSetProperty(KUI_GUI_MENUBAR, (long)x, 0L);
-}
-
-VOID
-setguitoolbar(x) int x;
-{
- KuiSetProperty(KUI_GUI_TOOLBAR, (long)x, 0L);
-}
-
-VOID
-setguiclose(x) int x;
-{
- KuiSetProperty(KUI_GUI_CLOSE, (long)x, 0L);
-}
-
-int
-setgui() {
- int cx, x, rc;
- if ((cx = cmkey(guitab,nguitab,"","",xxstring)) < 0)
- return(cx);
- switch (cx) {
- case GUI_DIA:
- rc = seton(&x);
- if (rc >= 0)
- setguidialog(x);
- return(rc);
- case GUI_FON:
- return(setguifont());
- case GUI_RGB:
- return(setrgb());
- case GUI_WIN:
- return(setguiwin());
- case GUI_TLB:
- rc = seton(&x);
- if (rc >= 0)
- setguitoolbar(x);
- return(rc);
- case GUI_MNB:
- rc = seton(&x);
- if (rc >= 0)
- setguimenubar(x);
- return(rc);
- case GUI_CLS:
- rc = seton(&x);
- if (rc >= 0)
- setguiclose(x);
- return(rc);
- default:
- return(-2);
- }
-}
-#endif /* KUI */
-
-VOID
-setexitwarn(x) int x;
-{
- xitwarn = x;
-#ifdef KUI
- KuiSetProperty(KUI_EXIT_WARNING, (long)x, 0L);
-#endif /* KUI */
-}
-
-#ifndef NOLOCAL
-VOID
-setdebses(x) int x; {
-#ifdef OS2
- if ((debses != 0) && (x == 0)) /* It was on and we turned it off? */
- os2debugoff(); /* Fix OS/2 coloration */
-#endif /* OS2 */
- debses = x;
-#ifdef KUI
- KuiSetProperty(KUI_TERM_DEBUG,x,0);
-#endif /* KUI */
-}
-#endif /* NOLOCAL */
-
-/* D O P R M -- Set a parameter. */
-/*
- Returns:
- -2: illegal input
- -1: reparse needed
- 0: success
-*/
-int
-doprm(xx,rmsflg) int xx, rmsflg; {
- int i = 0, x = 0, y = 0, z = 0;
- long zz = 0L;
- char *s = NULL, *p = NULL;
-#ifdef OS2
- char portbuf[64];
- long portspeed = 0L;
- int portparity = 0;
- int portflow = 0;
-#endif /* OS2 */
-
-#ifndef NOSETKEY
-#ifdef OS2
- if (xx == XYMSK)
- return(setmsk());
-#endif /* OS2 */
-#endif /* NOSETKEY */
-
- if (xx == XYFLAG) { /* SET FLAG */
- extern int ooflag;
- return(success = seton(&ooflag));
- }
- if (xx == XYPRTR /* SET PRINTER (or BPRINTER) */
-#ifdef BPRINT
- || xx == XYBDCP
-#endif /* BPRINT */
- )
- return(setprinter(xx));
-
- switch (xx) {
-
-#ifdef ANYX25 /* SET X25 ... */
-case XYX25:
- return(setx25());
-
-#ifndef IBMX25
-case XYPAD: /* SET PAD ... */
- return(setpadp());
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifndef NOXFER
- case XYEOL: /* These have all been moved to set send/receive... */
- case XYLEN: /* Let the user know what to do. */
- case XYMARK:
- case XYNPAD:
- case XYPADC:
- case XYTIMO:
- printf("...Use SET SEND or SET RECEIVE instead.\n");
- printf("Type HELP SET SEND or HELP SET RECEIVE for more info.\n");
- return(success = 0);
-
- case XYATTR: /* File Attribute packets */
- return(setat(rmsflg));
-
- case XYIFD: /* Incomplete file disposition */
- if ((y = cmkey(ifdatab,3,"","auto",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- if (rmsflg) {
- sstate = setgen('S',
- "310",
- y == 0 ? "0" : (y == 1 ? "1" : "2"),
- ""
- );
- return((int) sstate);
- } else {
- keep = y;
- return(success = 1);
- }
-#endif /* NOXFER */
-
- case XYMATCH: /* [ REMOTE ] SET MATCH... */
-#ifndef NOXFER
- if ((z = cmkey(matchtab,nmatchtab,"","",xxstring)) < 0)
- return(z);
- if (rmsflg) {
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- switch (z) {
- case MCH_DOTF:
- return(sstate = setgen('S',"330", y == 0 ? "0" : "1", ""));
- case MCH_FIFO:
- return(sstate = setgen('S',"331", y == 0 ? "0" : "1", ""));
- default:
- return(-2);
- }
- }
-#endif /* NOXFER */
- switch (z) {
- case MCH_FIFO:
- return(success = seton(&matchfifo));
- case MCH_DOTF:
- x = seton(&matchdot);
- if (x < 0) return(x);
- dir_dots = -1;
- return(success = x);
- default:
- return(-2);
- }
-
-#ifndef NOSPL
- case XYINPU: /* SET INPUT */
- return(setinp());
-#endif /* NOSPL */
-
-#ifdef NETCONN
- case XYNET: { /* SET NETWORK */
-
- struct FDB k1, k2;
-
- cmfdbi(&k1,_CMKEY,"","","",nnetkey, 0, xxstring, netkey, &k2);
- cmfdbi(&k2,_CMKEY,"","","",nnets, 0, xxstring, netcmd, NULL);
-
-#ifdef OS2 /* Hide network-type keywords for networks not installed */
- for (z = 0; z < nnets; z++) {
- if (netcmd[z].kwval == NET_TCPB && tcp_avail == 0)
- netcmd[z].flgs = CM_INV;
-#ifdef SSHBUILTIN
- if (netcmd[z].kwval == NET_SSH &&
- !ck_ssleay_is_installed())
- netcmd[z].flgs = CM_INV;
-#endif /* SSHBUILTIN */
-#ifdef DECNET
- else if (netcmd[z].kwval == NET_DEC && dnet_avail == 0)
- netcmd[z].flgs = CM_INV;
-#endif /* DECNET */
-#ifdef CK_NETBIOS
- else if (netcmd[z].kwval == NET_BIOS && netbiosAvail == 0)
- netcmd[z].flgs = CM_INV;
-#endif /* CK_NETBIOS */
-#ifdef SUPERLAT
- else if (netcmd[z].kwval == NET_SLAT && slat_avail == 0)
- netcmd[z].flgs = CM_INV;
-#endif /* SUPERLAT */
- }
- if (tcp_avail) /* Default network type */
- ckstrncpy(tmpbuf,"tcp/ip",TMPBUFSIZ);
-#ifdef SSHBUILTIN
- else if ( ck_ssleay_is_installed() )
- ckstrncpy(tmpbuf,"ssh",TMPBUFSIZ);
-#endif /* SSHBUILTIN */
-#ifdef DECNET
- else if (dnet_avail)
- ckstrncpy(tmpbuf,"decnet",TMPBUFSIZ);
-#endif /* DECNET */
-#ifdef SUPERLAT
- else if (slat_avail)
- ckstrncpy(tmpbuf,"superlat",TMPBUFSIZ);
-#endif /* SUPERLAT */
-#ifdef CK_NETBIOS
- else if (netbiosAvail)
- ckstrncpy(tmpbuf,"netbios",TMPBUFSIZ);
-#endif /* CK_NETBIOS */
- else ckstrncpy(tmpbuf,"named-pipe",TMPBUFSIZ);
-#else /* OS2 */
-#ifdef TCPSOCKET
- ckstrncpy(tmpbuf,"tcp/ip",TMPBUFSIZ);
-#else
-#ifdef ANYX25
- ckstrncpy(tmpbuf,"x.25",TMPBUFSIZ);
-#else
- ckstrncpy(tmpbuf,"",TMPBUFSIZ);
-#endif /* ANYX25 */
-#endif /* TCPSOCKET */
-#endif /* OS2 */
-
- x = cmfdb(&k1);
- if (x < 0) { /* Error */
- if (x == -2 || x == -9)
- printf("?No keywords match: \"%s\"\n",atmbuf);
- return(x);
- }
- z = cmresult.nresult; /* Keyword value */
- if (cmresult.fdbaddr == &k1) { /* Which table? */
-#ifndef NOSPL
-#ifndef NODIAL
- if (z == XYNET_D)
- return(parsdir(1));
-#endif /* NODIAL */
-#endif /* NOSPL */
- if ((z = cmkey(netcmd,nnets,"",tmpbuf,xxstring)) < 0)
- return(z);
- }
-
-#ifdef NETCMD
- if (z == NET_CMD && nopush) {
- printf("\n?Sorry, access to external commands is disabled\n");
- return(-9);
- }
-#endif /* NETCMD */
-
-#ifndef NOPUSH
-#ifdef NETPTY
- if (z == NET_PTY && nopush) {
- printf("\n?Sorry, access to external commands is disabled\n");
- return(-9);
- }
-#endif /* NETPTY */
-#endif /* NOPUSH */
-
-#ifdef OS2
- if (z == NET_TCPB && tcp_avail == 0) {
- printf(
-"\n?Sorry, either TCP/IP is not available on this system or\n\
-necessary DLLs did not load. Use SHOW NETWORK to check network status.\n");
- return(-9);
-#ifdef SSHBUILTIN
- } else if (z == NET_SSH && !ck_ssleay_is_installed()) {
- printf("\n?Sorry, SSH is not available on this system.\n") ;
- return(-9);
-#endif /* SSHBUILTIN */
-#ifdef CK_NETBIOS
- } else if (z == NET_BIOS && netbiosAvail == 0) {
- printf("\n?Sorry, NETBIOS is not available on this system.\n") ;
- return(-9);
-#endif /* CK_NETBIOS */
-#ifdef DECNET
- } else if (z == NET_DEC && dnet_avail == 0) {
- printf("\n?Sorry, DECnet is not available on this system.\n") ;
- return(-9);
-#endif /* DECNET */
-#ifdef SUPERLAT
- } else if (z == NET_SLAT && slat_avail == 0) {
- printf("\n?Sorry, SuperLAT is not available on this system.\n") ;
- return(-9);
-#endif /* SUPERLAT */
- }
-#endif /* OS2 */
-
-#ifdef NPIPEORBIOS
- if (z == NET_PIPE || /* Named pipe -- also get pipename */
- z == NET_BIOS) { /* NETBIOS -- also get local name */
- char *defnam;
-#ifdef CK_NETBIOS
- char tmpnbnam[NETBIOS_NAME_LEN+1];
-#endif /* CK_NETBIOS */
- /* Construct default name */
- if (z == NET_PIPE) { /* Named pipe */
- defnam = "kermit"; /* Default name is always "kermit" */
- }
-#ifdef CK_NETBIOS
- else { /* NetBIOS */
- if (NetBiosName[0] != SP) { /* If there is already a name, */
- char *p = NULL;
- int n; /* use it as the default. */
- ckstrncpy(tmpnbnam,NetBiosName,NETBIOS_NAME_LEN+1);
- /* convert trailing spaces to NULs */
- p = &tmpnbnam[NETBIOS_NAME_LEN-1];
- while (*p == SP) {
- *p = NUL;
- p--;
- }
- defnam = tmpnbnam;
- } else if (*myhost) /* Otherwise use this PC's host name */
- defnam = (char *) myhost;
- else /* Otherwise use "kermit" */
- defnam = "kermit";
- }
-#endif /* CK_NETBIOS */
- if ((y = cmtxt((z == NET_PIPE) ? "name of named-pipe" :
- "local NETBIOS name",
- defnam, &s, xxstring)) < 0)
- return(y);
-#ifdef NPIPE
- pipename[0] = NUL;
-#endif /* NPIPE */
- if ((y = (int) strlen(s)) < 1) {
- printf("?You must also specify a %s name\n",
- (z == NET_PIPE) ? "pipe" : "local NETBIOS" );
- return(-9);
- }
-#ifdef CK_NETBIOS
- if (z == NET_BIOS) {
- if (!netbiosAvail) {
- printf("?NETBIOS is not available on this system.\n") ;
- return(-9);
- }
- if (y - NETBIOS_NAME_LEN > 0) {
- printf("?NETBIOS name too long, %ld maximum\n",
- NETBIOS_NAME_LEN);
- return(-9);
- } else if ( !strcmp(s,tmpnbnam) ) {
- nettype = z; /* Returning to old connection... */
- return(success = 1); /* Done */
- } else if (strcmp(" ",NetBiosName)) {
- printf("?NETBIOS name already assigned to \"%s\"\n",
- NetBiosName);
- return(-9);
- } else {
- NCB ncb;
- APIRET rc;
- ckstrncpy(NetBiosName,s,16);
- for (x = y; x < NETBIOS_NAME_LEN; x++)
- NetBiosName[x] = SP;
- NetBiosName[NETBIOS_NAME_LEN] = NUL;
- printf("Checking \"%s\" as a unique NetBIOS name...\n",
- NetBiosName);
- rc = NCBAddName( NetbeuiAPI,
- &ncb, NetBiosAdapter, NetBiosName );
- if (rc) {
- printf(
- "?Sorry, \"%s\" is already in use by another NetBIOS node.\n",
- NetBiosName);
- for (x = 0; x < NETBIOS_NAME_LEN; x++)
- NetBiosName[x] = SP;
- return(-9);
- }
- }
- }
-#endif /* CK_NETBIOS */
-#ifdef NPIPE
- if (z == NET_PIPE)
- ckstrncpy(pipename,s,PIPENAML);
-#endif /* NPIPE */
- } else
-#endif /* NPIPEORBIOS */
-#ifdef DECNET
- if (z == NET_DEC) {
- /* Determine if we are using LAT or CTERM */
- if ((y = cmkey(dnettab,
- ndnet,"DECNET protocol","lat",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- ttnproto = y;
- } else
-#endif /* DECNET */
-#ifdef NETDLL
- if (z == NET_DLL) {
- /* Find out which DLL they are using */
- char dllname[256]="";
- char * p=NULL;
- if ((x = cmifi("Dynamic load library",
- "",&p,&y,xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of DLL required\n");
- return(-9);
- }
- return(x);
- }
- ckstrncpy(dllname,p,256);
- if ((x = cmcfm()) < 0) return(x);
-
- if (netdll_load(dllname) < 0) /* Try to load the dll */
- return(success = 0);
- else {
- nettype = z;
- return(success = 1);
- }
- } else
-#endif /* NETDLL */
- if ((x = cmcfm()) < 0) return(x);
- nettype = z;
- if (
-#ifdef DECNET
- (nettype != NET_DEC) &&
-#endif /* DECNET */
-#ifdef NPIPE
- (nettype != NET_PIPE) &&
-#endif /* NPIPE */
-#ifdef CK_NETBIOS
- (nettype != NET_BIOS) &&
-#endif /* CK_NETBIOS */
-#ifdef NETFILE
- (nettype != NET_FILE) &&
-#endif /* NETFILE */
-#ifdef NETCMD
- (nettype != NET_CMD) &&
-#endif /* NETCMD */
-#ifdef NETPTY
- (nettype != NET_PTY) &&
-#endif /* NETPTY */
-#ifdef NETDLL
- (nettype != NET_DLL) &&
-#endif /* NETDLL */
-#ifdef SUPERLAT
- (nettype != NET_SLAT) &&
-#endif /* SUPERLAT */
- (nettype != NET_SX25) &&
- (nettype != NET_VX25) &&
-#ifdef IBMX25
- (nettype != NET_IX25) &&
-#endif /* IBMX25 */
-#ifdef SSHBUILTIN
- (nettype != NET_SSH) &&
-#endif /* SSHBUILTIN */
- (nettype != NET_TCPB)) {
- printf("?Network type not supported\n");
- return(success = 0);
- } else {
- return(success = 1);
- }
- }
-
-#ifndef NOTCPOPTS
-#ifdef TCPSOCKET
- case XYTCP: {
- extern int ttyfd;
-
- if ((z = cmkey(tcpopt,ntcpopt,"TCP option","nodelay",xxstring)) < 0)
- return(z);
-
- switch (z) {
-#ifndef NOHTTP
- case XYTCP_HTTP_PROXY: {
- struct FDB sw, tx;
- int n, x;
- char ubuf[LOGINLEN+1], pbuf[LOGINLEN+1], abuf[256];
- ubuf[0] = pbuf[0] = abuf[0] = 0;
-
- cmfdbi(&sw, /* First FDB - switches */
- _CMKEY, /* fcode */
- "HTTP proxy server host[:port] or switch",
- "", /* default */
- "", /* addtl string data */
- nuserpass, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- userpass, /* Keyword table */
- &tx /* Pointer to next FDB */
- );
- cmfdbi(&tx,
- _CMTXT, /* fcode */
- "HTTP proxy server host[:port]",
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- while (1) {
- if ((x = cmfdb(&sw)) < 0) {
- if (x == -3) {
- x = -9;
- printf("?Hostname required\n");
- }
- return(x);
- }
- if (cmresult.fcode != _CMKEY)
- break;
- n = cmresult.nresult;
- switch (n) {
- case UPW_USER:
- case UPW_PASS:
- case UPW_AGENT:
- if ((x = cmfld((n == UPW_USER) ?
- "Username" :
- ((n == UPW_PASS) ? "Password" : "Agent"),
- "", &s, xxstring)) < 0) {
- if (x != -3)
- return(x);
- }
- ckstrncpy((n == UPW_USER) ? ubuf :
- ((n == UPW_PASS) ? pbuf : abuf), s,
- (n == UPW_AGENT) ? 256 : (LOGINLEN+1));
- }
- }
- if (cmresult.fcode != _CMTXT)
- return(-2);
- s = cmresult.sresult;
- if (s) if (!*s) s = NULL;
-
-#ifdef IKSDCONF
- if (iksdcf)
- return(success = 0);
-#endif /* IKSDCONF */
- makestr(&tcp_http_proxy_user,ubuf[0]?ubuf:NULL);
- makestr(&tcp_http_proxy_pwd,pbuf[0]?pbuf:NULL);
- makestr(&tcp_http_proxy_agent,abuf[0]?abuf:NULL);
- makestr(&tcp_http_proxy,s);
- memset(pbuf,0,sizeof(pbuf));
- return(success = 1);
- }
-#endif /* NOHTTP */
-/*
- It would have been easy to combine XYTCP_SOCKS_SVR with the previous
- one except for the #ifdefs...
-*/
-#ifdef NT
-#ifdef CK_SOCKS
- case XYTCP_SOCKS_SVR: {
- char ubuf[LOGINLEN+1], pbuf[LOGINLEN+1];
- char * p = getenv("SOCKS_SERVER");
- struct FDB sw, tx;
- int n, x;
-
- if (!p) p = "";
-
- cmfdbi(&sw, /* First FDB - switches */
- _CMKEY, /* fcode */
- "SOCKS server host[:port] or switch",
- "", /* default */
- "", /* addtl string data */
- nuserpass, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- userpass, /* Keyword table */
- &tx /* Pointer to next FDB */
- );
- cmfdbi(&tx,
- _CMTXT, /* fcode */
- "SOCKS server host[:port]",
- p, /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- while (1) {
- if ((x = cmfdb(&sw)) < 0) {
- if (x == -3) {
- x = -9;
- printf("?Hostname required\n");
- }
- return(x);
- }
- if (cmresult.fcode != _CMKEY)
- break;
- n = cmresult.nresult;
- switch (n) {
- case UPW_USER:
- case UPW_PASS:
- if ((x = cmfld((n == UPW_USER) ? "Username" : "Password",
- "", &s, xxstring)) < 0) {
- if (x != -3)
- return(x);
- }
- ckstrncpy((n == UPW_USER) ? ubuf : pbuf, s, LOGINLEN+1);
- }
- }
- if (cmresult.fcode != _CMTXT)
- return(-2);
- s = cmresult.sresult;
- if (s) if (!*s) s = NULL;
-
-#ifdef IKSDCONF
- if (iksdcf)
- return(success = 0);
-#endif /* IKSDCONF */
- makestr(&tcp_socks_user,ubuf);
- memset(pbuf,0,sizeof(pbuf));
- makestr(&tcp_socks_svr,s);
- return(success = 1);
- }
-
-#ifdef CK_SOCKS_NS
- case XYTCP_SOCKS_NS: {
- char * p = getenv("SOCKS_NS");
- if (!p) p = "";
- if ((y = cmtxt("hostname or IP of SOCKS Name Server",p,
- &s,xxstring)) < 0)
- return(y);
-#ifdef IKSDCONF
- if (iksdcf) return(success = 0);
-#endif /* IKSDCONF */
- if (tcp_socks_ns) {
- free(tcp_socks_ns); /* Free any previous storage */
- tcp_socks_ns = NULL;
- }
- if (s == NULL || *s == NUL) { /* If none given */
- tcp_socks_ns = NULL; /* remove the override string */
- return(success = 1);
- } else if ((tcp_socks_ns = malloc(strlen(s)+1))) {
- strcpy(tcp_socks_ns,s);
- return(success = 1);
- } else
- return(success = 0);
- }
-#endif /* CK_SOCKS_NS */
-#endif /* CK_SOCKS */
-#endif /* NT */
- case XYTCP_ADDRESS:
- if ((y = cmtxt("preferred IP Address for TCP connections","",
- &s,xxstring)) < 0)
- return(y);
-#ifdef IKSDCONF
- if (iksdcf) return(success = 0);
-#endif /* IKSDCONF */
- if (tcp_address) {
- free(tcp_address); /* Free any previous storage */
- tcp_address = NULL;
- }
- if (s == NULL || *s == NUL) { /* If none given */
- tcp_address = NULL; /* remove the override string */
- return(success = 1);
- } else if ((tcp_address = malloc(strlen(s)+1))) {
- strcpy(tcp_address,s);
- return(success = 1);
- } else
- return(success = 0);
-#ifdef SO_KEEPALIVE
- case XYTCP_KEEPALIVE:
- if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSDCONF
- if (iksdcf) return(success = 0);
-#endif /* IKSDCONF */
-#ifdef SSHBUILTIN
- if (network && nettype == NET_SSH && ssh_sock != -1)
- success = keepalive(ssh_sock,z);
- else
-#endif /* SSHBUILTIN */
- success = keepalive(ttyfd,z);
- return(success);
-#endif /* SO_KEEPALIVE */
-#ifdef SO_DONTROUTE
- case XYTCP_DONTROUTE:
- if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSDCONF
- if (iksdcf) return(success = 0);
-#endif /* IKSDCONF */
-#ifdef SSHBUILTIN
- if (network && nettype == NET_SSH && ssh_sock != -1)
- success = dontroute(ssh_sock,z);
- else
-#endif /* SSHBUILTIN */
- success = dontroute(ttyfd,z);
- return(success);
-#endif /* SO_DONTROUTE */
-#ifdef TCP_NODELAY
- case XYTCP_NODELAY:
- if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSDCONF
- if (iksdcf) return(success = 0);
-#endif /* IKSDCONF */
-#ifdef SSHBUILTIN
- if (network && nettype == NET_SSH && ssh_sock != -1)
- success = no_delay(ssh_sock,z);
- else
-#endif /* SSHBUILTIN */
- success = no_delay(ttyfd,z);
- return(success);
- case XYTCP_NAGLE: /* The inverse of NODELAY */
- if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSDCONF
- if (iksdcf) return(success = 0);
-#endif /* IKSDCONF */
-#ifdef SSHBUILTIN
- if (network && nettype == NET_SSH && ssh_sock != -1)
- success = no_delay(ssh_sock,z);
- else
-#endif /* SSHBUILTIN */
- success = no_delay(ttyfd,!z);
- return(success);
-#endif /* TCP_NODELAY */
-#ifdef SO_LINGER
- case XYTCP_LINGER:
- if ((z = cmkey(onoff,2,"","on",xxstring)) < 0)
- return(z);
- if (z) { /* if on, we need a timeout value */
- if ((x = cmnum("Linger timeout in 10th of a millisecond",
- "0",10,&y,xxstring)) < 0)
- return(x);
- } else
- y = 0;
- if ((x = cmcfm()) < 0)
- return(x);
-#ifdef IKSDCONF
- if (iksdcf) return(success = 0);
-#endif /* IKSDCONF */
-#ifdef SSHBUILTIN
- if (network && nettype == NET_SSH && ssh_sock != -1)
- success = ck_linger(ssh_sock,z,y);
- else
-#endif /* SSHBUILTIN */
- success = ck_linger(ttyfd,z,y);
- return(success);
-#endif /* SO_LINGER */
-#ifdef SO_SNDBUF
- case XYTCP_SENDBUF:
- x = cmnum("Send buffer size, bytes","8192",10,&z,xxstring);
- if (x < 0) return(x);
- if ((x = cmcfm()) < 0) return(x);
-#ifdef IKSDCONF
- if (iksdcf) return(success = 0);
-#endif /* IKSDCONF */
-#ifdef SSHBUILTIN
- if (network && nettype == NET_SSH && ssh_sock != -1)
- success = sendbuf(ssh_sock,z);
- else
-#endif /* SSHBUILTIN */
- success = sendbuf(ttyfd,z);
- return(success);
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
- case XYTCP_RECVBUF:
- x = cmnum("Receive buffer size, bytes","8192",10,&z,xxstring);
- if (x < 0) return(x);
- if ((x = cmcfm()) < 0) return(x);
-#ifdef IKSDCONF
- if (iksdcf) return(success = 0);
-#endif /* IKSDCONF */
-
-/* Note: The following is not 16-bit safe */
-
-#ifndef QNX16
- if (x > 52248) {
- printf("?Warning: receive buffers larger than 52248 bytes\n");
- printf(" may not be understood by all hosts. Performance\n");
- printf(" may suffer.\n");
- return(-9);
- }
-#endif /* QNX16 */
-#ifdef SSHBUILTIN
- if (network && nettype == NET_SSH && ssh_sock != -1)
- success = recvbuf(ssh_sock,z);
- else
-#endif /* SSHBUILTIN */
- success = recvbuf(ttyfd,z);
- return(success);
-#endif /* SO_RCVBUF */
-
-#ifdef VMS
-#ifdef DEC_TCPIP
- case XYTCP_UCX: { /* UCX 2.0 port swabbing bug */
- extern int ucx_port_bug;
- return(success = seton(&ucx_port_bug));
- }
-#endif /* DEC_TCPIP */
-#endif /* VMS */
-
- case XYTCP_RDNS: {
- extern int tcp_rdns;
- return(success = setonaut(&tcp_rdns));
- }
-
-#ifdef CK_DNS_SRV
- case XYTCP_DNS_SRV: {
- extern int tcp_dns_srv;
- return(success = seton(&tcp_dns_srv));
- }
-#endif /* CK_DNS_SRV */
-
- default:
- return(0);
- }
- }
-#endif /* TCPSOCKET */
-#endif /* NOTCPOPTS */
-#endif /* NETCONN */
- }
-
- switch (xx) {
-
-#ifndef NOLOCAL
-#ifdef NETCONN
- case XYHOST: { /* SET HOST */
- z = ttnproto; /* Save protocol in case of failure */
-#ifdef DECNET
- if (nettype != NET_DEC)
-#endif /* DECNET */
- ttnproto = NP_NONE;
- if ((y = setlin(XYHOST,1,0)) <= 0) { /* Sets success to 1 */
- debug(F101,"SET HOST fail mdmtyp","",mdmtyp);
- ttnproto = z; /* Failed, restore protocol */
- success = 0;
- }
- didsetlin++;
- debug(F101,"SET HOST OK mdmtyp","",mdmtyp);
- debug(F101,"SET HOST reliable","",reliable);
- return(y);
- }
-#endif /* NETCONN */
-
- case XYLINE: /* SET LINE (= SET PORT) */
- debug(F101,"setlin flow 1","",flow);
- x = setlin(xx,1,0);
- if (x > -1) didsetlin++;
- debug(F101,"SET LINE setlin","",x);
- debug(F101,"SET LINE flow","",flow);
- debug(F101,"SET LINE local","",local);
- debug(F101,"SET LINE reliable","",reliable);
- return(x);
-#endif /* NOLOCAL */
-
-#ifndef NOSETKEY
- case XYKEY: /* SET KEY */
- return(dosetkey());
-#endif /* NOSETKEY */
-
-#ifndef NOCSETS
- case XYLANG: /* Language */
- if ((y = cmkey(lngtab,nlng,"","none",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
-
- /* Look up language and get associated character sets */
- for (i = 0; (i < nlangs) && (langs[i].id != y); i++) ;
- if (i >= nlangs) {
- printf("?internal error, sorry\n");
- return(success = 0);
- } /* */
- language = i; /* All good, set the language, */
- return(success = 1);
-#endif /* NOCSETS */
-
-#ifndef MAC
- case XYBACK: /* BACKGROUND */
- if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef COMMENT
- bgset = z; /* 0 = off (foreground) */
-#ifdef VMS /* 1 = on (background) */
- if (batch && bgset == 0) /* To enable echoing of commands */
- ckxech = 1; /* in VMS batch logs */
-#endif /* VMS */
-#else /* COMMENT */
- if (z) { /* 1 = Background */
- bgset = 1;
- backgrd = 1;
-#ifdef VMS
- batch = 1;
-#endif /* VMS */
- } else { /* 0 = Foreground */
- bgset = 0;
- backgrd = 0;
-#ifdef VMS
- batch = 0;
-#endif /* VMS */
- }
-#endif /* COMMENT */
- success = 1;
- bgchk();
- return(success);
-#endif /* MAC */
-
- case XYQUIE: { /* QUIET */
-#ifdef DCMDBUF
- extern int * xquiet;
-#else
- extern int xquiet[];
-#endif /* DCMDBUF */
- x = seton(&quiet);
- if (x < 0) return(x);
- xquiet[cmdlvl] = quiet;
- return(success = x);
- }
-
-#ifndef NOXFER
- case XYBUF: { /* BUFFERS */
-#ifdef DYNAMIC
- int sb, rb;
- if ((y = cmnum("Send buffer size","",10,&sb,xxstring)) < 0) {
- if (y == -3) printf("?Buffer size required\n");
- return(y);
- }
- if (sb < 0) {
- if (*atmbuf == '-')
- printf("?Negative numbers can't be used here\n");
- else printf("?Integer overflow, use a smaller number please\n");
- return(-9);
- } else if (sb < 80) {
- printf("?Too small\n");
- return(-9);
- }
- if ((y=cmnum("Receive buffer size",ckitoa(sb),10,&rb,xxstring)) < 0)
- return(y);
- if (rb < 0) {
- if (*atmbuf == '-')
- printf("?Negative numbers can't be used here\n");
- else printf("?Integer overflow, use a smaller number please\n");
- return(-9);
- } else if (rb < 80) {
- printf("?Too small\n");
- return(-9);
- }
- if ((y = cmcfm()) < 0) return(y);
- if ((y = inibufs(sb,rb)) < 0) return(y);
- y = adjpkl(urpsiz,wslotr,bigrbsiz); /* Maybe adjust packet sizes */
- if (y != urpsiz) urpsiz = y;
- y = adjpkl(spsiz,wslotr,bigsbsiz);
- if (y != spsiz) spsiz = spmax = spsizr = y;
- return(success = 1);
-#else
- printf("?Sorry, not available\n");
- return(success = 0);
-#endif /* DYNAMIC */
- }
-
- case XYCHKT: /* BLOCK-CHECK */
- if ((x = cmkey(chktab,nchkt,"","3",xxstring)) < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
- if (x == 5) {
- bctf = 1;
-#ifdef COMMENT
- printf("?5 - Not implemented yet\n");
- return(success = 0);
-#endif /* COMMENT */
- }
- bctr = x; /* Set local too even if REMOTE SET */
-
- if (rmsflg) {
- if (x == 4) {
- tmpbuf[0] = 'B';
- tmpbuf[1] = '\0';
- } else
- ckstrncpy(tmpbuf,ckitoa(x),TMPBUFSIZ);
- sstate = setgen('S', "400", tmpbuf, "");
- return((int) sstate);
- } else {
- return(success = 1);
- }
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
-#ifndef MAC /* The Mac has no RS-232 */
-case XYCARR: /* CARRIER-WATCH */
- return(setdcd());
-#endif /* MAC */
-#endif /* NOLOCAL */
- }
-
-#ifdef TNCODE
- switch (xx) { /* Avoid long switch statements... */
- case XYTELOP: {
- int c, n; /* Workers */
- int getval = 0; /* Whether to get switch value */
- int tnserver = 0; /* Client by default */
- int opt = -1; /* Telnet Option */
- struct FDB sw, op; /* FDBs for each parse function */
-#ifdef CK_AUTHENTICATION
- extern int sl_topt_a_s_saved;
- extern int sl_topt_a_c_saved;
- extern int sl_topt_e_s_saved;
- extern int sl_topt_e_c_saved;
-#endif /* CK_AUTHENTICATION */
-#ifdef IKSD
- if (inserver) /* Server by default when IKSD */
- tnserver = 1;
-#endif /* IKSD */
-
- /* Set up chained parse functions... */
-
- cmfdbi(&op, /* First fdb - telopts*/
- _CMKEY, /* fcode */
- "/client, /server or", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- ntnopt, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- tnopttab,
- &sw
- );
- cmfdbi(&sw, /* Second FDB - command switches */
- _CMKEY, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- ntnoptsw, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- tnoptsw, /* Keyword table */
- NULL /* Pointer to next FDB */
- );
-
- while (opt < 0) { /* Parse 0 or more switches */
- x = cmfdb(&op); /* Parse switch or other thing */
- debug(F101,"XYTELOP cmfdb","",x);
- if (x < 0) /* Error */
- return(x); /* or reparse needed */
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- c = cmgbrk(); /* Get break character */
- getval = (c == ':' || c == '='); /* see how switch ended */
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- return(-9);
- }
- z = cmresult.nresult; /* Numeric result = switch value */
- debug(F101,"XYTELOP switch","",z);
-
- switch (z) { /* Process the switch */
- case CK_TN_CLIENT:
- tnserver = 0;
- break;
- case CK_TN_SERVER:
- tnserver = 1;
- break;
- case CK_TN_EC:
- opt = TELOPT_ECHO;
- break;
- case CK_TN_TT:
- opt = TELOPT_TTYPE;
- break;
- case CK_TN_BM:
- opt = TELOPT_BINARY;
- break;
- case CK_TN_ENV:
- opt = TELOPT_NEWENVIRON;
- break;
- case CK_TN_LOC:
- opt = TELOPT_SNDLOC;
- break;
- case CK_TN_AU:
- opt = TELOPT_AUTHENTICATION;
- break;
- case CK_TN_FX:
- opt = TELOPT_FORWARD_X;
- break;
- case CK_TN_ENC:
- opt = TELOPT_ENCRYPTION;
- break;
- case CK_TN_IKS:
- opt = TELOPT_KERMIT;
- break;
- case CK_TN_TLS:
- opt = TELOPT_START_TLS;
- break;
- case CK_TN_XD:
- opt = TELOPT_XDISPLOC;
- break;
- case CK_TN_NAWS:
- opt = TELOPT_NAWS;
- break;
- case CK_TN_SGA:
- opt = TELOPT_SGA;
- break;
- case CK_TN_PHR:
- opt = TELOPT_PRAGMA_HEARTBEAT;
- break;
- case CK_TN_PSP:
- opt = TELOPT_SSPI_LOGON;
- break;
- case CK_TN_PLG:
- opt = TELOPT_PRAGMA_LOGON;
- break;
- case CK_TN_SAK:
- opt = TELOPT_IBM_SAK;
- break;
- case CK_TN_CPC:
- opt = TELOPT_COMPORT;
- break;
- case CK_TN_LOG:
- opt = TELOPT_LOGOUT;
- break;
- case CK_TN_FLW:
- opt = TELOPT_LFLOW;
- break;
- default:
- printf("?Unexpected value - %d\n",z);
- return(-9);
- }
-#ifdef COMMENT
- if (cmresult.fdbaddr == &op)
- break;
-#endif /* COMMENT */
- }
- switch (opt) {
- case TELOPT_ECHO: /* Options only the Server WILL */
- case TELOPT_FORWARD_X:
- case TELOPT_SEND_URL:
- case TELOPT_IBM_SAK:
- case TELOPT_LOGOUT:
- if ((x = cmkey(tnnegtab,
- ntnnegtab,
- "desired server state",
- TELOPT_MODE(tnserver?TELOPT_DEF_S_ME_MODE(opt):TELOPT_DEF_C_U_MODE(opt)),
- xxstring)
- ) < 0)
- return(x);
- if ((z = cmcfm()) < 0)
- return(z);
- if (tnserver) {
- TELOPT_DEF_S_ME_MODE(opt) = x;
- TELOPT_ME_MODE(opt) = x;
- } else {
- TELOPT_DEF_C_U_MODE(opt) = x;
- TELOPT_U_MODE(opt) = x;
- }
- break;
-
- case TELOPT_TTYPE: /* Options only the Client WILL */
- case TELOPT_NEWENVIRON:
- case TELOPT_SNDLOC:
- case TELOPT_AUTHENTICATION:
- case TELOPT_START_TLS:
- case TELOPT_XDISPLOC:
- case TELOPT_NAWS:
- case TELOPT_LFLOW:
- case TELOPT_COMPORT:
- if ((x = cmkey(tnnegtab,
- ntnnegtab,
- "desired client state",
- TELOPT_MODE(!tnserver?TELOPT_DEF_S_U_MODE(opt):TELOPT_DEF_C_ME_MODE(opt)),
- xxstring)
- ) < 0)
- return(x);
- if ((z = cmcfm()) < 0)
- return(z);
- if (tnserver) {
- TELOPT_DEF_S_U_MODE(opt) = x;
- TELOPT_U_MODE(opt) = x;
-#ifdef CK_AUTHENTICATION
- if (opt == TELOPT_AUTHENTICATION)
- sl_topt_a_s_saved = 0;
-#endif /* CK_AUTHENTICATION */
- } else {
- TELOPT_DEF_C_ME_MODE(opt) = x;
- TELOPT_ME_MODE(opt) = x;
-#ifdef CK_AUTHENTICATION
- if (opt == TELOPT_AUTHENTICATION)
- sl_topt_a_c_saved = 0;
-#endif /* CK_AUTHENTICATION */
- }
- break;
-
- default:
- if ((x = cmkey(tnnegtab,
- ntnnegtab,
- tnserver ?
- "desired server state" :
- "desired client state",
- TELOPT_MODE(tnserver?TELOPT_DEF_S_ME_MODE(opt):TELOPT_DEF_C_ME_MODE(opt)),
- xxstring
- )
- ) < 0)
- return(x);
- if ((y = cmkey(tnnegtab,
- ntnnegtab,
- !tnserver ? "desired server state" :
- "desired client state",
- TELOPT_MODE(!tnserver?TELOPT_DEF_S_U_MODE(opt):TELOPT_DEF_C_U_MODE(opt)),
- xxstring
- )
- ) < 0)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- if (tnserver) {
- TELOPT_DEF_S_ME_MODE(opt) = x;
- TELOPT_ME_MODE(opt) = x;
- TELOPT_DEF_S_U_MODE(opt) = y;
- TELOPT_U_MODE(opt) = y;
-#ifdef CK_ENCRYPTION
- if (opt == TELOPT_ENCRYPTION)
- sl_topt_e_s_saved = 0;
-#endif /* CK_ENCRYPTION */
- } else {
- TELOPT_DEF_C_ME_MODE(opt) = x;
- TELOPT_ME_MODE(opt) = x;
- TELOPT_DEF_C_U_MODE(opt) = y;
- TELOPT_U_MODE(opt) = y;
-#ifdef CK_ENCRYPTION
- if (opt == TELOPT_ENCRYPTION)
- sl_topt_e_c_saved = 0;
-#endif /* CK_ENCRYPTION */
- }
- }
- return(success = 1);
- }
-
- case XYTEL: /* TELNET */
- if ((z = cmkey(tntab,ntn,"parameter for TELNET negotiations", "",
- xxstring)) < 0)
- return(z);
- switch (z) {
- case CK_TN_EC: /* ECHO */
- if ((x = cmkey(rltab,nrlt,
- "initial TELNET echoing state",
- "local",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- tn_duplex = x;
- return(success = 1);
-
- case CK_TN_RE: /* REMOTE-ECHO */
- return(success = seton(&tn_rem_echo));
-
- case CK_TN_DB: /* DEBUG */
- return(success = seton(&tn_deb));
-
- case CK_TN_TT: /* TERMINAL TYPE */
- if ((y = cmtxt("terminal type for TELNET connections","",
- &s,xxstring)) < 0)
- return(y);
- if (tn_term) {
- free(tn_term); /* Free any previous storage */
- tn_term = NULL;
- }
- if (s == NULL || *s == NUL) { /* If none given */
- tn_term = NULL; /* remove the override string */
- return(success = 1);
- } else if ((tn_term = malloc(strlen(s)+1))) {
- strcpy(tn_term,s);
- return(success = 1);
- } else return(success = 0);
-
-#ifdef CK_FORWARD_X
- case CK_TN_FX: /* FORWARD-X */
- if ((x=cmkey(tnfwdxtab,ntnfwdx,"","xauthority-file",xxstring)) < 0)
- return(x);
- switch (x) {
- case 0: { /* Xauthority-File */
- x = cmifi("Full path of .Xauthority file","",&s,&y,xxstring);
- if (x < 0 && x != -3)
- return(x);
- makestr(&tn_fwdx_xauthority,s);
- return(success = 1);
- }
- case 1: { /* No-Encryption */
- extern int fwdx_no_encrypt;
- return(success = seton(&fwdx_no_encrypt));
- }
- }
- return(success = 0);
-#endif /* CK_FORWARD_X */
-
- case CK_TN_NL: /* TELNET NEWLINE-MODE */
- if ((x = cmkey(tn_nlmtab,ntn_nlm,"","nvt",xxstring)) < 0)
- return(x);
- if (x == TN_NL_BIN) {
- if ((x = cmkey(tnlmtab,ntnlm,"","raw",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- tn_b_nlm = x;
- return(success = 1);
- } else if (x == TN_NL_NVT) {
- if ((x = cmkey(tnlmtab,ntnlm,"","on",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- tn_nlm = x;
- return(success = 1);
- } else {
- if ((y = cmcfm()) < 0)
- return(y);
- tn_nlm = x;
- return(success = 1);
- }
-
- case CK_TN_XF: /* BINARY-TRANSFER-MODE */
- if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
- tn_b_xfer = z;
- return(success = 1);
-
- case CK_TN_NE: /* NO-ENCRYPT-DURING-XFER */
- if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef CK_APC
- /* Don't let this be set remotely */
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
- return(success = 0);
-#endif /* CK_APC */
- tn_no_encrypt_xfer = z;
- return(success = 1);
-
- case CK_TN_BM: /* BINARY-MODE */
- if ((x = cmkey(tnnegtab,ntnnegtab,"","refused",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- TELOPT_DEF_S_ME_MODE(TELOPT_BINARY) = x;
- TELOPT_DEF_S_U_MODE(TELOPT_BINARY) = x;
- TELOPT_DEF_C_ME_MODE(TELOPT_BINARY) = x;
- TELOPT_DEF_C_U_MODE(TELOPT_BINARY) = x;
- return(success = 1);
-
-#ifdef IKS_OPTION
- case CK_TN_IKS: /* KERMIT */
- if ((x = cmkey(tnnegtab,ntnnegtab,"DO","accept",xxstring)) < 0)
- return(x);
- if ((y = cmkey(tnnegtab,ntnnegtab,"WILL","accept",xxstring)) < 0)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- TELOPT_DEF_S_ME_MODE(TELOPT_KERMIT) = y;
- TELOPT_DEF_S_U_MODE(TELOPT_KERMIT) = x;
- TELOPT_DEF_C_ME_MODE(TELOPT_KERMIT) = y;
- TELOPT_DEF_C_U_MODE(TELOPT_KERMIT) = x;
- return(success = 1);
-#endif /* IKS_OPTION */
-
-#ifdef CK_SSL
- case CK_TN_TLS: /* START_TLS */
- if ((x = cmkey(tnnegtab,ntnnegtab,"me","accept",xxstring)) < 0)
- return(x);
- if ((y = cmkey(tnnegtab,ntnnegtab,"u","accept",xxstring)) < 0)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = x;
- TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = y;
- TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = x;
- TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = y;
- return(success = 1);
-#endif /* CK_SSL */
-
-#ifdef CK_NAWS
- case CK_TN_NAWS: /* NAWS */
- if ((x = cmkey(tnnegtab,ntnnegtab,"me","accept",xxstring)) < 0)
- return(x);
- if ((y = cmkey(tnnegtab,ntnnegtab,"u","accept",xxstring)) < 0)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- TELOPT_DEF_S_ME_MODE(TELOPT_NAWS) = x;
- TELOPT_DEF_S_U_MODE(TELOPT_NAWS) = y;
- TELOPT_DEF_C_ME_MODE(TELOPT_NAWS) = x;
- TELOPT_DEF_C_U_MODE(TELOPT_NAWS) = y;
- return(success = 1);
-#endif /* CK_NAWS */
-
-#ifdef CK_AUTHENTICATION
- case CK_TN_AU: /* AUTHENTICATION */
- if ((x = cmkey(tnauthtab,ntnauth,"","",xxstring)) < 0)
- return(x);
- if (x == TN_AU_FWD) {
- extern int forward_flag;
- return(success = seton(&forward_flag));
- } else if (x == TN_AU_TYP) {
- extern int auth_type_user[];
- extern int sl_auth_type_user[];
- extern int sl_auth_saved;
- int i, j, atypes[AUTHTYPLSTSZ];
-
- for (i = 0; i < AUTHTYPLSTSZ; i++) {
- if ((y = cmkey(autyptab,nautyp,"",
- i == 0 ? "automatic" : "" ,
- xxstring)) < 0) {
- if (y == -3)
- break;
- return(y);
- }
- if (i > 0 && (y == AUTHTYPE_AUTO || y == AUTHTYPE_NULL)) {
- printf(
- "\r\n?Choice may only be used in first position.\r\n");
- return(-9);
- }
- for (j = 0; j < i; j++) {
- if (atypes[j] == y) {
- printf("\r\n?Choice has already been used.\r\n");
- return(-9);
- }
- }
- atypes[i] = y;
- if (y == AUTHTYPE_NULL || y == AUTHTYPE_AUTO) {
- i++;
- break;
- }
- }
- if (i < AUTHTYPLSTSZ)
- atypes[i] = AUTHTYPE_NULL;
- if ((z = cmcfm()) < 0)
- return(z);
- sl_auth_saved = 0;
- for (i = 0; i < AUTHTYPLSTSZ; i++) {
- auth_type_user[i] = atypes[i];
- sl_auth_type_user[i] = 0;
- }
- } else if (x == TN_AU_HOW) {
- if ((y = cmkey(auhowtab,nauhow,"","any",xxstring)) < 0)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- tn_auth_how = y;
- } else if (x == TN_AU_ENC) {
- if ((y = cmkey(auenctab,nauenc,"","encrypt",xxstring)) < 0)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- tn_auth_enc = y;
- } else {
- if ((y = cmcfm()) < 0)
- return(y);
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = x;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = x;
- }
- return(success = 1);
-#endif /* CK_AUTHENTICATION */
-
-#ifdef CK_ENCRYPTION
- case CK_TN_ENC: { /* ENCRYPTION */
- int c, tmp = -1;
- int getval = 0;
- static struct keytab * tnetbl = NULL;
- static int ntnetbl = 0;
-
- if ((y = cmkey(tnenctab,ntnenc,"","",xxstring)) < 0)
- return(y);
- switch (y) {
- case TN_EN_TYP:
- x = ck_get_crypt_table(&tnetbl,&ntnetbl);
- debug(F101,"ck_get_crypt_table x","",x);
- debug(F101,"ck_get_crypt_table n","",ntnetbl);
- if (x < 1 || !tnetbl || ntnetbl < 1) /* Didn't get it */
- x = 0;
- if (!x) {
- printf("?Oops, types not loaded\n");
- return(-9);
- }
- if ((x = cmkey(tnetbl,ntnetbl,"type of encryption",
- "automatic",xxstring)) < 0)
- return(x);
- if ((z = cmcfm()) < 0)
- return(z);
- cx_type = x;
- sl_cx_type = 0;
- break;
- case TN_EN_START:
- if ((z = cmcfm()) < 0)
- return(z);
-#ifdef CK_APC
- /* Don't let this be set remotely */
- if (apcactive == APC_LOCAL ||
- apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
- return(success = 0);
-#endif /* CK_APC */
- ck_tn_enc_start();
- break;
- case TN_EN_STOP:
- if ((z = cmcfm()) < 0)
- return(z);
-#ifdef CK_APC
- /* Don't let this be set remotely */
- if (apcactive == APC_LOCAL ||
- apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
- return(success = 0);
-#endif /* CK_APC */
- ck_tn_enc_stop();
- break;
- default:
- if ((z = cmcfm()) < 0)
- return(z);
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = y;
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = y;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = y;
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = y;
- }
- return(success = 1);
- }
-#endif /* CK_ENCRYPTION */
-
- case CK_TN_BUG: /* BUG */
- if ((x = cmkey(tnbugtab,4,"",
- "binary-me-means-u-too",xxstring)) < 0)
- return(x);
- if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
- switch (x) {
- case 0:
- tn_b_meu = z;
- break;
- case 1:
- tn_b_ume = z;
- break;
- case 2:
- tn_infinite = z;
- break;
- case 3:
- tn_sb_bug = z;
- break;
- case 4:
- tn_auth_krb5_des_bug = z;
- break;
- }
- return(success = 1);
-
-#ifdef CK_ENVIRONMENT
- case CK_TN_XD: /* XDISPLOC */
- if ((x = cmkey(tnnegtab,ntnnegtab,"me","accept",xxstring)) < 0)
- return(x);
- if ((y = cmkey(tnnegtab,ntnnegtab,"u","accept",xxstring)) < 0)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- TELOPT_DEF_S_ME_MODE(TELOPT_XDISPLOC) = x;
- TELOPT_DEF_S_U_MODE(TELOPT_XDISPLOC) = y;
- TELOPT_DEF_C_ME_MODE(TELOPT_XDISPLOC) = x;
- TELOPT_DEF_C_U_MODE(TELOPT_XDISPLOC) = y;
- return(success = 1);
-
- case CK_TN_ENV: {
- char * msg = "value of telnet environment variable";
- extern int tn_env_flg;
- extern char tn_env_acct[], tn_env_disp[], tn_env_job[],
- tn_env_prnt[], tn_env_sys[];
- extern char * tn_loc;
- if ((x = cmkey(tnenvtab,ntnenv,"","",xxstring)) < 0)
- return(x);
- if (x == TN_ENV_UVAR) { /* User variables */
- char * uvar=NULL;
- char * uval=NULL;
- char * env;
- extern char * tn_env_uservar[8][2];
-
- /* Get the user variable name */
- if ((x = cmfld("Name of Environment Variable","",&s,
- xxstring)) < 0)
- return(x);
- makestr(&uvar,s);
-
- env = getenv(uvar);
- if (!env) env = "";
-
- if ((x = cmtxt("Value of Environment Variable",env,
- &s,xxstring)) < 0)
- return(x);
- if (*s)
- makestr(&uval,s);
-
- /* Now that we have the variable and perhaps a value */
- /* there are three possibilities: (1) new variable */
- /* and associated value; (2) variable already exists */
- /* but we have a new value; (3) variable already */
- /* exists but no new value therefore the user wants */
- /* to clear variable. */
-
- /* Try to find an existing variable */
- for (x = 0; x < 8; x++) {
- if (!ckstrcmp(tn_env_uservar[x][0],uvar,-1,0)) {
- if (uval) {
- free(tn_env_uservar[x][1]);
- tn_env_uservar[x][1] = uval;
- free(uvar);
- return(success = 1);
- } else {
- free(tn_env_uservar[x][0]);
- tn_env_uservar[x][0] = NULL;
- free(tn_env_uservar[x][1]);
- tn_env_uservar[x][1] = NULL;
- free(uvar);
- return(success = 1);
- }
- }
- }
-
- /* Couldn't find one; look for empty location to insert */
- for (x = 0; x < 8; x++) {
- if (!tn_env_uservar[x][0]) {
- tn_env_uservar[x][0] = uvar;
- tn_env_uservar[x][1] = uval;
- return(success = 1);
- }
- }
- printf("?Sorry, no space for variable.\n");
- return(success = 0);
- }
- if (x == TN_ENV_OFF || x == TN_ENV_ON) {
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSD
- if (inserver) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- tn_env_flg = x == TN_ENV_OFF ? 0 : 1;
- return(success = 1);
- }
-
- /* Not ON/OFF - Get the value */
- z = cmdgquo();
- cmdsquo(0);
- if ((y = cmtxt(msg, "", &s, xxstring)) < 0) {
- cmdsquo(z);
- return(y);
- }
- cmdsquo(z);
-#ifdef IKSD
- if (inserver)
- return(success = 0);
-#endif /* IKSD */
- if ((int)strlen(s) > 63) {
- printf("Sorry, too long\n");
- return(-9);
- }
- switch (x) {
- case TN_ENV_USR:
- ckstrncpy(uidbuf,s,UIDBUFLEN);
- sl_uid_saved = 0;
- break;
- case TN_ENV_ACCT:
- ckstrncpy(tn_env_acct,s,64);
- break;
- case TN_ENV_DISP:
- ckstrncpy(tn_env_disp,s,64);
- break;
- case TN_ENV_JOB:
- ckstrncpy(tn_env_job,s,64);
- break;
- case TN_ENV_PRNT:
- ckstrncpy(tn_env_prnt,s,64);
- break;
- case TN_ENV_SYS:
- ckstrncpy(tn_env_sys,s,64);
- break;
- case TN_ENV_LOC:
- if (!*s) s = NULL;
- makestr(&tn_loc,s);
- break;
- case TN_ENV_UVAR:
- printf("\n?Not yet implemented\n");
- break;
- }
- return(success = 1);
- }
-#endif /* CK_ENVIRONMENT */
-
-#ifdef CK_SNDLOC
- case CK_TN_LOC: { /* LOCATION */
- extern char * tn_loc;
- if ((y = cmtxt("Location string","",&s,xxstring)) < 0)
- return(y);
- if (!*s) s = NULL;
- makestr(&tn_loc,s);
- return(success = 1);
- }
-#endif /* CK_SNDLOC */
- case CK_TN_SFU: /* Microsoft SFU compatibility */
- if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
- tn_sfu = z;
- return(success = 1);
- break;
-
- case CK_TN_WAIT: /* WAIT-FOR-NEGOTIATIONS */
- if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSD
- if (inserver &&
-#ifdef IKSDCONF
- iksdcf
-#else
- 1
-#endif /* IKSDCONF */
- ) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- tn_wait_flg = z;
- sl_tn_saved = 0;
- return(success = 1);
-
- case CK_TN_DL: /* DELAY SUBNEGOTIATIONS */
- if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSD
- if (inserver &&
-#ifdef IKSDCONF
- iksdcf
-#else
- 1
-#endif /* IKSDCONF */
- ) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- tn_delay_sb = z;
- return(success = 1);
-
- case CK_TN_PUID: { /* PROMPT-FOR-USERID */
- int i,len;
- if ((y = cmtxt("Prompt string","",&s,xxstring)) < 0)
- return(y);
- s = brstrip(s);
- /* we must check to make sure there are no % fields */
- len = strlen(s);
- for (i = 0; i < len; i++) {
- if (s[i] == '%') {
- if (s[i+1] != '%') {
- printf("%% fields are not used in this command.\n");
- return(-9);
- }
- i++;
- }
- }
- makestr(&tn_pr_uid,s);
- return(success = 1);
- }
- default:
- return(-2);
- }
- }
-#endif /* TNCODE */
-
- switch (xx) {
-#ifndef NOSPL
- case XYCOUN: /* SET COUNT */
- x = cmnum("Positive number","0",10,&z,xxstring);
- if (x < 0) return(x);
- if ((x = cmcfm()) < 0) return(x);
- if (z < 0) {
- printf("?A positive number, please\n");
- return(0);
- }
- debug(F101,"XYCOUN: z","",z);
- return(success = setnum(&count[cmdlvl],z,0,10000));
-#endif /* NOSPL */
-
-#ifndef NOSPL
- case XYCASE:
- return(success = seton(&inpcas[cmdlvl]));
-#endif /* NOSPL */
-
- case XYCMD: /* COMMAND ... */
- if ((y = cmkey(scmdtab,nbytt,"","",xxstring)) < 0)
- return(y);
- switch (y) {
- case SCMD_CBR:
- if ((y = cmcfm()) < 0)
- return(y);
- concb((char)escape);
- return(success = 1);
-
- case SCMD_BSZ:
- if ((y = cmnum("bytesize for command characters, 7 or 8","7",10,&x,
- xxstring)) < 0)
- return(y);
- if (x != 7 && x != 8) {
- printf("\n?The choices are 7 and 8\n");
- return(success = 0);
- }
- if ((y = cmcfm()) < 0) return(y);
- if (x == 7) cmdmsk = 0177;
- else if (x == 8) cmdmsk = 0377;
- return(success = 1);
-#ifdef CK_RECALL
- case SCMD_RCL:
- if ((y = cmnum("maximum number of commands in recall buffer","10",
- 10,&x,xxstring)) < 0)
- return(y);
- if ((y = cmcfm()) < 0) return(y);
- return(success = cmrini(x));
-#endif /* CK_RECALL */
-#ifdef CK_RECALL
- case SCMD_RTR:
- return(success = seton(&cm_retry));
-#endif /* CK_RECALL */
- case SCMD_MOR: /* More-prompting */
- success = seton(&xaskmore);
- if (success)
- saveask = xaskmore;
- return(success);
- case SCMD_QUO:
- if ((x = seton(&y)) < 0) return(x);
- cmdsquo(y); /* Do it the right way */
- cmd_quoting = y; /* Also keep a global copy */
- /* Set string-processing function */
-#ifdef datageneral
- xxstring = y ? zzstring : (xx_strp) NULL;
-#else
-#ifdef CK_ANSIC
- xxstring = y ? zzstring : (xx_strp) NULL;
-#else
- xxstring = y ? zzstring : (xx_strp) NULL;
-#endif /* CK_ANSIC */
-#endif /* datageneral */
- return(success = 1);
-
-#ifdef OS2
-#ifndef NOLOCAL
- case SCMD_COL: { /* Command-screen colors */
- int fg, bg;
- fg = cmkey(ttyclrtab, nclrs,
- "foreground color and then background color",
- "white",
- xxstring);
- if (fg < 0)
- return(fg);
- if ((bg = cmkey(ttyclrtab,nclrs,
- "background color","black",xxstring)) < 0)
- return(bg);
- if ((y = cmcfm()) < 0)
- return(y);
- colorcmd = fg | bg << 4;
- return(success = 1);
- }
- case SCMD_SCR: /* Command Scrollback size */
- if ((y = cmnum("COMMAND scrollback buffer size, lines","512",10,&x,
- xxstring)) < 0)
- return(y);
- /* The max number of lines is the RAM */
- /* we can actually dedicate to a */
- /* scrollback buffer given the maximum */
- /* process memory space of 512MB */
- if (x < 256 || x > 2000000L) {
- printf("\n?The size must be between 256 and 2,000,000.\n");
- return(success = 0);
- }
- if ((y = cmcfm()) < 0) return(y);
- tt_scrsize[VCMD] = x;
- VscrnInit( VCMD );
- return(success = 1);
-
- case SCMD_WID: {
- if ((y = cmnum("Number of columns in display window",
- "80",10,&x,xxstring)) < 0)
- return(y);
- if ((y = cmcfm()) < 0) return(y);
-
- os2_setcmdwidth(x);
- return(success = 1);
- }
- case SCMD_HIG:
- if ((y = cmnum("Number of rows in display window",
- "24",10,&x,xxstring)) < 0)
- return(y);
- if ((y = cmcfm()) < 0) return(y);
- os2_setcmdheight(x);
- return(success = 1);
-
- case SCMD_STA: {
- extern int marginbot;
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- if (y != tt_status[VCMD]) {
- /* Might need to fixup the margins */
- tt_status[VCMD] = y;
- if (y) {
- tt_szchng[VCMD] = 2;
- tt_rows[VCMD]--;
- cmd_rows--;
- VscrnInit(VCMD); /* Height set here */
- printf("\n");
- } else {
- tt_szchng[VCMD] = 1;
- tt_rows[VCMD]++;
- cmd_rows++;
- VscrnInit(VCMD); /* Height set here */
- }
- }
- return(success = 1);
- }
-
- case SCMD_CUR: {
- int row, col;
- position * ppos;
-
- ppos = VscrnGetCurPos(VCMD);
-#ifdef NT
-#define itoa _itoa
-#endif /* NT */
- itoa(ppos->y+1, tmpbuf, 10);
- if ((y = cmnum("row (1-based)",tmpbuf,10,&row,xxstring)) < 0)
- return(y);
-
- itoa(ppos->x+1, tmpbuf, 10);
- if ((y = cmnum("col (1-based)",tmpbuf,10,&col,xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
-
- lgotoxy( VCMD, col, row ) ;
- VscrnIsDirty( VCMD );
- return(success=1);
- }
-#endif /* NOLOCAL */
-#else
- case SCMD_WID:
- y = cmnum("Command screen width, characters","80",10,&x,xxstring);
- return(setnum(&cmd_cols,x,y,1024));
-
- case SCMD_HIG:
- y = cmnum("Command screen height, rows","24",10,&x,xxstring);
- return(setnum(&cmd_rows,x,y,1024));
-#endif /* OS2 */
-
- case SCMD_INT:
- return(seton(&cmdint));
-
-#ifdef CK_AUTODL
- case SCMD_ADL:
- return(seton(&cmdadl));
-#endif /* CK_AUTODL */
-
-#ifdef DOUBLEQUOTING
- case SCMD_DBQ: {
- extern int dblquo;
- return(seton(&dblquo));
- }
-#endif /* DOUBLEQUOTING */
-
- case SCMD_ERR:
- y = cmnum("Error message verbosity level, 0-3","1",10,&x,xxstring);
- return(setnum(&cmd_err,x,y,3));
-
- case SCMD_VAR:
- return(setvareval());
-
- default:
- return(-2);
- }
- }
-
- switch (xx) {
-
- case XYDFLT: /* SET DEFAULT = CD */
- return(success = docd(XXCWD));
-
-case XYDEBU: /* SET DEBUG { on, off, session } */
- if ((y = cmkey(dbgtab,ndbg,"","",xxstring)) < 0)
- return(y);
- if (y == DEB_TIM)
-#ifdef COMMENT
- return(seton(&debtim) < 0 ? x : (success = 1));
-#else
- /* why this change? */
- return(success = seton(&debtim));
-#endif /* COMMENT */
-
-#ifdef IKSD
- if (inserver && isguest) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-
- switch (y) {
- case DEB_LEN:
- y = cmnum("Max length for debug log strings","",10,&x,xxstring);
- if ((z = setnum(&debxlen,x,y,-1)) < 0)
- return(z);
- if ((x = cmcfm()) < 0)
- return(x);
- return(success = 1);
-
- case DEB_OFF:
- if ((x = cmcfm()) < 0)
- return(x);
-#ifndef NOLOCAL
- setdebses(0);
-#endif /* NOLOCAL */
-#ifdef DEBUG
- if (deblog) doclslog(LOGD);
-#endif /* DEBUG */
- return(success = 1);
-
- case DEB_ON:
- if ((x = cmcfm()) < 0)
- return(x);
-#ifdef DEBUG
- deblog = debopn("debug.log", 0);
- return(success = deblog ? 1 : 0);
-#else
- printf("?Sorry, debug log feature not enabled\n");
- return(success = 0);
-#endif /* DEBUG */
- case DEB_SES:
- if ((x = cmcfm()) < 0)
- return(x);
-#ifndef NOLOCAL
- setdebses(1);
-#endif /* NOLOCAL */
- return(success = 1);
-
- case DEB_MSG: /* Debug messages 2010/03/12 */
- if ((y = cmkey(ooetab,nooetab,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- debmsg = y;
- return(1);
- }
- break;
-
-#ifndef NOXFER
- case XYDELA: /* SET DELAY */
- y = cmnum("Number of seconds before starting to send",
- "5",10,&x,xxstring);
- if (x < 0) x = 0;
- return(success = setnum(&ckdelay,x,y,999));
-#endif /* NOXFER */
-
- default:
- break;
- }
-
- switch (xx) {
-#ifdef CK_TAPI
- case XYTAPI:
- return(settapi());
-#endif /* CK_TAPI */
-#ifndef NODIAL
- case XYDIAL: /* SET MODEM or SET DIAL */
- return(setdial(-1));
- case XYMODM:
- return(setmodem());
-#ifdef COMMENT
- /* not implemented yet */
- case XYANSWER: /* SET ANSWER */
- return(setanswer());
-#endif /* COMMENT */
-#endif /* NODIAL */
-
-#ifndef NOLOCAL
- case XYDUPL: /* SET DUPLEX */
- if ((y = cmkey(dpxtab,2,"","full",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- duplex = y;
- return(success = 1);
-
- case XYLCLE: /* LOCAL-ECHO (= DUPLEX) */
- return(success = seton(&duplex));
-
- case XYESC: /* SET ESCAPE */
- return(success = setcc(ckitoa(DFESC),&escape));
-#endif /* NOLOCAL */
-
- case XYEXIT: /* SET EXIT */
- if ((z = cmkey(xittab,nexit,"","",xxstring)) < 0)
- return(z);
- switch (z) {
- case 0: /* STATUS */
- y = cmnum("EXIT status code","",10,&x,xxstring);
- return(success = setnum(&xitsta,x,y,-1));
- case 1: /* WARNING */
- if ((z = cmkey(xitwtab,nexitw,"","",xxstring)) < 0)
- return(z);
- if ((y = cmcfm()) < 0) return(y);
- setexitwarn(z);
- return(success = 1);
- case 2:
- success = seton(&exitonclose);
-#ifdef TCPSOCKET
- if (success) tn_exit = exitonclose;
-#endif /* TCPSOCKET */
- return(success);
- case 3: {
- extern int exithangup;
- return((success = seton(&exithangup)));
- }
- default:
- return(-2);
- } /* End of SET EXIT switch() */
- default:
- break;
- }
-
- switch (xx) {
-
- case XYFILE: /* SET FILE */
- return(setfil(rmsflg));
-
- case XYFLOW: { /* FLOW-CONTROL */
- extern int cxflow[];
- struct FDB k1, k2;
- int tncomport = 0;
- char * m;
-
-#ifdef TN_COMPORT
- if (network && istncomport())
- tncomport = 1;
-#endif /* TN_COMPORT */
-
- if (tncomport) {
- m = "Flow control type, one of the following:\n\
- dtr/cd dtr/cts keep none rts/cts xon/xoff\n\
- or connection type";
- } else {
- /* All this is because chained FDB's don't give chained help yet */
- m =
-#ifdef Plan9
-#ifdef CK_RTSCTS
- "Flow control type, one of the following:\n\
- keep none rts/cts\n\
- or connection type",
-#else
- "Flow control type, one of the following:\n\
- keep none\n\
- or connection type";
-#endif /* CK_RTSCTS */
-#else
-#ifdef CK_RTSCTS
-#ifdef CK_DTRCD
-#ifdef CK_DTRCTS
- "Flow control type, one of the following:\n\
- dtr/cd dtr/cts keep none rts/cts xon/xoff\n\
- or connection type";
-#else /* CK_DTRCTS */
- "Flow control type, one of the following:\n\
- dtr/cd keep none rts/cts xon/xoff\n\
- or connection type";
-#endif /* CK_DTRCTS */
-#else /* CK_DTRCD */
-#ifdef CK_DTRCTS
- "Flow control type, one of the following:\n\
- dtr/cts keep none rts/cts xon/xoff\n\
- or connection type";
-#else /* CK_DTRCTS */
- "Flow control type, one of the following:\n\
- keep none rts/cts xon/xoff\n\
- or connection type";
-#endif /* CK_DTRCTS */
-#endif /* CK_DTRCD */
-#else
- "Flow control type, one of the following:\n\
- keep none xon/xoff\n\
- or connection type";
-#endif /* CK_RTSCTS */
-#endif /* Plan9 */
- }
- cmfdbi(&k1,_CMKEY,m,"","",ncxtypesw, 4, xxstring, cxtypesw, &k2);
- cmfdbi(&k2,
- _CMKEY,
- "",
- "",
- "",
-#ifdef TN_COMPORT
- (tncomport ? ntnflo : nflo),
-#else
- nflo,
-#endif /* TN_COMPORT */
- 0,
- xxstring,
-#ifdef TN_COMPORT
- (tncomport ? tnflotab : flotab),
-#else
- flotab,
-#endif /* TN_COMPORT */
- NULL
- );
- x = cmfdb(&k1);
- if (x < 0) { /* Error */
- if (x == -2 || x == -9)
- printf("?No keywords or switches match: \"%s\"\n",atmbuf);
- return(x);
- }
- z = cmresult.nresult; /* Keyword value */
- if (cmresult.fdbaddr == &k2) { /* Flow-control type keyword table */
- if ((x = cmcfm()) < 0) /* Set it immediately */
- return(x);
- flow = z;
- debug(F101,"set flow","",flow);
-#ifdef CK_SPEED
- if (flow == FLO_XONX) /* Xon/Xoff forces prefixing */
- ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
-#endif /* CK_SPEED */
- autoflow = (flow == FLO_AUTO);
- return(success = 1); /* Done */
- }
- debug(F101,"set flow /blah 1","",z); /* SET FLOW /for-what */
- if ((y = cmkey(flotab,nflo,"Flow control type","none",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- debug(F101,"set flow /blah 2","",y);
- if (y == FLO_AUTO) {
- printf(
- "?Sorry, \"automatic\" can not be assigned to a connection type.\n");
- return(-9);
- } else if (z >= 0 && z <= CXT_MAX)
- cxflow[z] = y;
- debug(F101,"set flow","",flow);
- debug(F101,"set flow autoflow","",autoflow);
- return(success = 1);
- }
-
- case XYHAND: /* HANDSHAKE */
- if ((y = cmkey(hshtab,nhsh,"","none",xxstring)) < 0) return(y);
- if (y == 998) {
- if ((x = cmnum("ASCII value","",10,&y,xxstring)) < 0)
- return(x);
- if ((y < 1) || ((y > 31) && (y != 127))) {
- printf("?Character must be in ASCII control range\n");
- return(-9);
- }
- }
- if ((x = cmcfm()) < 0) return(x);
- turn = (y > 0127) ? 0 : 1;
- turnch = y;
- return(success = 1);
-
-#ifndef NOSPL
- case XYMACR: /* SET MACRO */
- if ((y = cmkey(smactab,2,"","",xxstring)) < 0) return(y);
- switch (y) {
- case 0: return(success = seton(&mecho));
- case 1: return(success = seton(&merror[cmdlvl]));
- default: return(-2);
- }
-#endif /* NOSPL */
-
- case XYMSGS:
-#ifdef VMS
- if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
- if ((y = cmcfm()) < 0) return(y);
- vms_msgs = z;
- printf("Sorry, SET MESSAGES not implemented yet\n");
- return(success = 0);
-#endif /* VMS */
- default:
- break;
- }
-
- switch (xx) {
-
- case XYPARI: /* PARITY */
- if ((y = cmkey(partbl,npar,"","none",xxstring)) < 0)
- return(y);
-
- /* If parity not none, then we also want 8th-bit prefixing */
-
-#ifdef HWPARITY
- if (y == 'H') { /* Hardware */
- if ((x = cmkey(hwpartbl,nhwpar,"","even",xxstring)) < 0)
- return(x);
- }
-#endif /* HWPARITY */
-
- if ((z = cmcfm()) < 0)
- return(z);
-
-#ifdef HWPARITY
- if (y == 'H') { /* 8 data bits plus hardware parity */
- parity = 0;
-#ifndef NOXFER
- ebqflg = 0;
-#endif /* NOXFER */
- hwparity = x;
- } else { /* 7 data bits + software parity */
- hwparity = 0;
-#endif /* HWPARITY */
- parity = y;
-#ifndef NOXFER
- ebqflg = (parity) ? 1 : 0;
-#endif /* NOXFER */
-#ifdef HWPARITY
- }
-#endif /* HWPARITY */
-
-#ifdef TN_COMPORT
- if (network && istncomport())
- tnsettings(parity, 0);
-#endif /* TN_COMPORT */
-
- return(success = 1);
-
-#ifndef NOFRILLS
- case XYPROM: /* SET PROMPT */
-/*
- Note: xxstring not invoked here. Instead, it is invoked every time the
- prompt is issued. This allows the prompt string to contain variables
- that can change, like \v(dir), \v(time), etc.
-*/
- ckmakmsg(line, /* Default might have trailing space */
- LINBUFSIZ,
- "{",
- inserver ? ikprompt : ckprompt,
- "}",
- NULL
- );
- if ((x = cmtxt("Program's command prompt",line,&s,NULL)) < 0)
- return(x);
- s = brstrip(s); /* Remove enclosing braces, if any */
- cmsetp(s); /* Set the prompt */
- return(success = 1);
-#endif /* NOFRILLS */
-
-#ifndef NOXFER
- case XYRETR: /* RETRY: per-packet retry limit */
- y = cmnum("Maximum retries per packet","10",10,&x,xxstring);
- if (x < 0) x = 0;
- if ((x = setnum(&maxtry,x,y,999)) < 0) return(x);
-#ifdef COMMENT
- if (maxtry <= wslotr) {
- printf("?Retry limit must be greater than window size\n");
- return(success = 0);
- }
-#endif /* COMMENT */
- if (rmsflg) {
- sstate = setgen('S', "403", ckitoa(maxtry), "");
- return((int) sstate);
- } else return(success = x);
-#endif /* NOXFER */
-
-#ifndef NOSERVER
- case XYSERV: /* SET SERVER items */
- if ((y = cmkey(srvtab,nsrvt,"","",xxstring)) < 0) return(y);
- switch (y) {
- case XYSERI:
- if ((y = cmnum("Number of seconds, or 0 for no idle timeout",
- "0",10,&x,xxstring)) < 0)
- return(y);
- if (x < 0)
- x = 0;
- if ((y = cmcfm()) < 0)
- return(y);
-#ifndef OS2
- srvtim = 0;
-#endif /* OS2 */
- srvidl = x;
- return(success = 1);
- case XYSERT:
- if ((y = cmnum("Interval for server NAKs, 0 = none",
- ckitoa(DSRVTIM),
- 10,&x, xxstring)) < 0)
- return(y);
- if (x < 0) {
- printf(
- "\n?Specify a positive number, or 0 for no server NAKs\n");
- return(0);
- }
- if ((y = cmcfm()) < 0) return(y);
- if (rmsflg) {
- sstate = setgen('S', "404", ckitoa(x), "");
- return((int) sstate);
- } else {
-#ifndef OS2
- srvidl = 0;
-#endif /* OS2 */
- srvtim = x; /* Set the server timeout variable */
- return(success = 1);
- }
- case XYSERD: /* SERVER DISPLAY */
- return(success = seton(&srvdis)); /* ON or OFF... */
-
-#ifndef NOSPL
- case XYSERP: /* SERVER GET-PATH */
- return(parsdir(2));
-#endif /* NOSPL */
-
- case XYSERL: /* SERVER LOGIN */
- return(cklogin());
-
- case XYSERC: /* SERVER CD-MESSAGE */
- x = rmsflg ?
- cmkey(onoff,2,"","",xxstring) :
- cmkey(cdmsg,3,"","",xxstring);
- if (x < 0)
- return(x);
- if (x == 2) { /* CD-MESSAGE FILE */
- if ((x = cmtxt("Name of file","",&s,NULL)) < 0)
- return(x);
- if (!*s) {
- s = NULL;
- srvcdmsg = 0;
- }
- makestr(&cdmsgstr,s);
- makelist(cdmsgstr,cdmsgfile,8);
- return(success = 1);
- }
- if ((y = cmcfm()) < 0) /* CD-MESSAGE ON/OFF */
- return(y);
- if (rmsflg) {
- sstate = setgen('S', "420", x ? "1" : "0", "");
- return((int) sstate);
- } else {
- if (x > 0)
- srvcdmsg |= 1;
- else
- srvcdmsg &= 2;
- return(success = 1);
- }
- case XYSERK: /* SERVER KEEPALIVE */
- return(success = seton(&srvping)); /* ON or OFF... */
-
- default:
- return(-2);
- }
-#endif /* NOSERVER */
- }
-
- switch (xx) {
-#ifdef UNIX
-#ifndef NOJC
- case XYSUSP: /* SET SUSPEND */
- seton(&xsuspend); /* on or off... */
- return(success = 1);
-#endif /* NOJC */
-#endif /* UNIX */
-
- case XYTAKE: /* SET TAKE */
- if ((y = cmkey(taktab,4,"","",xxstring)) < 0) return(y);
- switch (y) {
- case 0: return(success = seton(&techo));
-#ifndef NOSPL
- case 1: return(success = seton(&takerr[cmdlvl]));
-#else
- case 1: return(success = seton(&takerr[tlevel]));
-#endif /* NOSPL */
- case 2: techo = 0; return(success = 1); /* For compatibility with */
- case 3: techo = 1; return(success = 1); /* MS-DOS Kermit */
- default: return(-2);
- }
-
-#ifndef NOSCRIPT
- case XYSCRI: /* SET SCRIPT */
- if ((y = cmkey(scrtab,1,"","echo",xxstring)) < 0) return(y);
- switch (y) {
- case 0: return(success = seton(&secho));
- default: return(-2);
- }
-#endif /* NOSCRIPT */
-
- default:
- break;
- }
-
-#ifndef NOLOCAL
- switch (xx) {
- case XYTERM: /* SET TERMINAL */
- x = settrm();
- success = (x > 0) ? 1 : 0;
- return(x);
-
-#ifdef NT
- case XYWIN95: /* SET WIN95 workarounds */
- x = setwin95();
- success = (x > 0 ? 1 : 0);
- return(x);
-#endif /* NT */
-
-#ifdef OS2
- case XYDLR: /* SET DIALER workarounds */
- x = setdialer();
- success = (x > 0 ? 1 : 0);
- return(x);
-
- case XYTITLE: /* SET TITLE of window */
- x = settitle();
- success = (x > 0 ? 1 : 0);
- return(x);
-#endif /* OS2 */
-
-#ifdef OS2MOUSE
- case XYMOUSE: /* SET MOUSE */
- return(success = setmou());
-#endif /* OS2MOUSE */
-
- case XYBELL: /* SET BELL */
- return(success = setbell());
-
-#ifdef OS2
- case XYPRTY:
- return(success = setprty() );
-#endif /* OS2 */
-
- default:
- break;
- }
-#endif /* NOLOCAL */
-
- switch (xx) {
-
-/* SET SEND/RECEIVE protocol parameters. */
-
-#ifndef NOXFER
- case XYRECV:
- case XYSEND:
- return(setsr(xx,rmsflg));
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
- case XYSESS: /* SESSION-LOG */
- if ((x = cmkey(sfttab,nsfttab,"type of file",
-#ifdef OS2
- "binary",
-#else /* OS2 */
- "text",
-#endif /* OS2 */
- xxstring
- )
- ) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- if (x == 999) { /* TIMESTAMPED-TEXT */
- sessft = XYFT_T; /* Implies text */
- slogts = 1; /* and timestamps */
- } else if (x == 998) { /* NULL-PADDED-LINES */
- slognul = 1; /* adds NUL after ^J */
- } else { /* A regular type */
- sessft = x; /* The type */
- slogts = 0; /* No timestampes */
- }
- return(success = 1);
-
- case XYSPEE: /* SET SPEED */
- lp = line;
- if (local && !network) {
- ckmakmsg(lp,
- LINBUFSIZ,
- "Transmission rate for ",
- ttname,
- " (bits per second)",
- NULL
- );
- } else {
- ckstrncpy(lp,
- "Serial-port speed (bits per second)",
- LINBUFSIZ
- );
- }
- zz = -1L;
-
-#ifdef TN_COMPORT
- if (network && istncomport())
- x = cmkey(tnspdtab,ntnspd,line,"",xxstring);
- else
-#endif /* TN_COMPORT */
- x = cmkey(spdtab,nspd,line,"",xxstring);
- if (x < 0) {
- if (x == -3) printf("?value required\n");
-#ifdef USETCSETSPEED
- /* In this case, any number can be tried */
- /* There's a parse error message but the request still goes thru */
- if (rdigits(atmbuf))
- zz = atol(atmbuf);
- else
-#endif /* USETCSETSPEED */
- return(x);
- }
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSD
- if (inserver) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- if (!local) {
- printf("?SET SPEED has no effect without prior SET LINE\n");
- return(success = 0);
- } else if (network
-#ifdef TN_COMPORT
- && !istncomport()
-#endif /* TN_COMPORT */
- ) {
- printf("\n?Speed cannot be set for network connections\n");
- return(success = 0);
- }
-
-/*
- Note: This way of handling speeds is not 16-bit safe for speeds greater
- than 230400. The argument to ttsspd() should have been a long.
-*/
-#ifdef USETCSETSPEED
- if (zz > -1L)
- x = zz / 10L;
-#endif /* USETCSETSPEED */
- zz = (long) x * 10L;
- if (zz == 130L) zz = 134L;
- if (zz == 70L) zz = 75L; /* (see spdtab[] definition) */
- if (ttsspd(x) < 0) { /* Call ttsspd with cps, not bps! */
- printf("?Unsupported line speed - %ld\n",zz);
- return(success = 0);
- } else {
-#ifdef CK_TAPI
- if (!tttapi || tapipass)
- speed = ttgspd(); /* Read it back */
- else
- speed = zz;
-#else /* CK_TAPI */
- speed = ttgspd(); /* Read it back */
-#endif /* CK_TAPI */
- if (speed != zz) { /* Call ttsspd with cps, not bps! */
- printf("?SET SPEED fails, speed is %ld\n",speed);
- return(success = 0);
- }
- if (pflag && !xcmdsrc) {
- if (speed == 8880)
- printf("%s, 75/1200 bps\n",ttname);
- else if (speed == 134)
- printf("%s, 134.5 bps\n",ttname);
- else
- printf("%s, %ld bps\n",ttname,speed);
- }
- return(success = 1);
- }
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
- case XYXFER: /* SET TRANSFER */
- if ((y = cmkey(rmsflg ? rtstab : tstab, /* (or REMOTE SET TRANSFER) */
- rmsflg ? nrts : nts,
- "","character-set",xxstring)) < 0) return(y);
- switch (y) {
-#ifdef XFRCAN
- case XYX_CAN: /* CANCELLATION */
- if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
- if (z == 0) { /* OFF */
- if ((y = cmcfm()) < 0) return(y);
- xfrcan = 0;
- } else {
- if ((y = cmnum("ASCII code for cancellation character",
- "3",10,&x,
- xxstring)) < 0)
- return(y);
- if (x > 31 && x != 127) {
- printf("Cancel character must be 0-31 or 127\n");
- return(-9);
- }
- if ((y = cmnum("How many required to cause cancellation",
- "2",10,&z, xxstring)) < 0)
- return(y);
- if (z < 2) {
- printf("Number must be 2 or greater\n");
- return(-9);
- }
- if ((y = cmcfm()) < 0) return(y);
- xfrcan = 1; /* CANCELLATION ON */
- xfrchr = x; /* Using this character */
- xfrnum = z; /* Needing this many of them */
- }
- return(success = 1);
-#endif /* XFRCAN */
-
-#ifndef NOCSETS
- case XYX_CSE: /* CHARACTER-SET */
- if ((y = cmkey(tcstab,ntcs,"","transparent",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- if (rmsflg) {
- sstate = setgen('S', "405", tcsinfo[y].designator, "");
- return((int) sstate);
- } else {
- extern int s_cset, fcharset, axcset[], tcs_save;
- tslevel = (y == TC_TRANSP) ? 0 : 1; /* transfer syntax level */
- xfrxla = tslevel;
- tcharset = y; /* transfer character set */
- /* SEND CHARACTER-SET AUTO */
- if (tslevel > 0 && s_cset == XMODE_A)
- if (y > -1 && y <= MAXTCSETS)
- if (axcset[y] > -1 && axcset[y] > MAXFCSETS)
- fcharset = axcset[y]; /* Auto-pick file charset */
- setxlatype(tcharset,fcharset); /* Translation type */
- tcs_save = -1;
- return(success = 1);
- }
-#endif /* NOCSETS */
-
- case XYX_LSH: /* LOCKING-SHIFT */
- if ((y = cmkey(lstab,nls,"","on",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- lscapr = (y == 1) ? 1 : 0; /* ON: requested = 1 */
- lscapu = (y == 2) ? 2 : 0; /* FORCED: used = 1 */
- return(success = 1);
-
-/* #ifdef CK_XYZ */
- case XYX_PRO: /* Protocol */
-#ifndef OS2
- if (inserver) {
- printf("?Sorry, only Kermit protocol is available\n");
- return(-9);
- }
-#endif /* OS2 */
- return(setproto());
-/* #endif */ /* CK_XYZ */
-
- case XYX_MOD: /* Mode */
- if ((y = cmkey(xfrmtab,2,"","automatic",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- if (rmsflg) {
- sstate = setgen('S', "410", y == XMODE_A ? "0" : "1", "");
- return((int)sstate);
- }
- g_xfermode = y;
- xfermode = y;
-#ifdef NEWFTP
- if (ftpisopen()) { /* If an FTP connection is open */
- extern int ftp_xfermode; /* change its transfer mode too */
- ftp_xfermode = xfermode;
- }
-#endif /* NEWFTP */
- return(success = 1);
-
-#ifndef NOLOCAL
- case XYX_DIS: /* Display */
- return(doxdis(1)); /* 1 == Kermit */
-#endif /* NOLOCAL */
-
- case XYX_SLO: /* Slow-start */
- return(seton(&slostart));
-
-#ifndef NOSPL
- case XYX_CRC: /* CRC */
- return(seton(&docrc));
-#endif /* NOSPL */
-
- case XYX_BEL: /* Bell */
- return(seton(&xfrbel));
-
-#ifdef PIPESEND
- case XYX_PIP: /* Pipes */
-#ifndef NOPUSH
- if (nopush) {
-#endif /* NOPUSH */
- printf("Sorry, access to pipes is disabled\n");
- return(-9);
-#ifndef NOPUSH
- } else
-#endif /* NOPUSH */
- return(seton(&usepipes));
-#endif /* PIPESEND */
-
- case XYX_INT: /* Interruption */
- return(seton(&xfrint));
-
- case XYX_XLA:
- return(seton(&xfrxla)); /* Translation */
-
- case XYX_MSG: {
- extern char * xfrmsg;
- if ((x = cmtxt("Prompt string","",&s,xxstring)) < 0)
- return(x);
- if (!*s) s = NULL;
- makestr(&xfrmsg,s);
- return(success = 1);
-
- }
- case XYX_RPT: {
- extern int whereflg;
- return(seton(&whereflg));
- }
- default:
- return(-2);
- }
-#endif /* NOXFER */
- }
-
- switch (xx) {
-
-#ifndef NOXMIT
- case XYXMIT: /* SET TRANSMIT */
- return(setxmit());
-#endif /* NOXMIT */
-
-#ifndef NOXFER
-#ifndef NOCSETS
- case XYUNCS: /* UNKNOWN-CHARACTER-SET */
- if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- unkcs = y;
- return(success = 1);
-#endif /* NOCSETS */
-#endif /* NOXFER */
-
-#ifndef NOPUSH
-#ifdef UNIX
- case XYWILD: /* WILDCARD-EXPANSION */
- if ((y = cmkey(wildtab,nwild,
- "Wildcard expansion option","on",xxstring)) < 0)
- return(y);
- if ((z = cmkey(wdottab,
- 2,
- "whether to match filenames that start with \".\"",
- "/no-match-dot-files",
- xxstring)
- ) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (nopush) {
- if (y > 0) {
- printf("Shell expansion is disabled\n");
- return(success = 0);
- }
- }
- switch (y) {
- case WILD_ON:
- wildena = 1;
- break;
- case WILD_OFF:
- wildena = 0;
- break;
- case WILD_KER:
- wildxpand = 0; /* These are the previous */
- break; /* hardwired values */
- case WILD_SHE:
- wildxpand = 1;
- break;
- }
- matchdot = z;
- return(success = 1);
-#endif /* UNIX */
-#endif /* NOPUSH */
-
-#ifndef NOXFER
- case XYWIND: /* WINDOW-SLOTS */
- if (protocol == PROTO_K) {
- y = cmnum("Window size for Kermit protocol, 1 to 32",
- "1", 10, &x, xxstring);
- y = setnum(&z,x,y,MAXWS); /* == 32 */
- }
-#ifdef CK_XYZ
- else if (protocol == PROTO_Z) {
- y = cmnum("Window size for ZMODEM protocol, 0 to 65535",
- "0", 10, &x, xxstring);
- y = setnum(&z,x,y,65535);
- }
-#endif /* CK_XYZ */
- else {
- y = cmnum("Window size for current protocol",
- "", 10, &x, xxstring);
- y = setnum(&z,x,y,65472); /* Doesn't matter - we won't use it */
- }
- if (y < 0) return(y);
- if (protocol == PROTO_K) {
- if (z < 1)
- z = 1;
- }
-#ifdef CK_XYZ
- else if (protocol == PROTO_Z) {
- /* Zmodem windowing is closer to Kermit packet length */
- /* than Kermit window size. If Window size is zero */
- /* an end of frame and CRC is sent only at the end of */
- /* the file (default). Otherwise, an End of Frame */
- /* and CRC are sent after Window Size number of bytes */
- if (z < 0) /* Disable windowing */
- z = 0;
- } else {
- printf("?SET WINDOW does not apply to %s protocol\n",
- ptab[protocol].p_name
- );
- }
-#endif /* CK_XYZ */
-
-#ifdef COMMENT
- /* This is taken care of automatically now in protocol negotiation */
- if (maxtry < z) {
- printf("?Window slots must be less than retry limit\n");
- return(success = 0);
- }
-#endif /* COMMENT */
- if (protocol == PROTO_K && rmsflg) { /* Set remote window size */
- wslotr = z; /* Set local window size too */
- ptab[protocol].winsize = wslotr;
- sstate = setgen('S', "406", ckitoa(z), "");
- return((int) sstate);
- }
- wslotr = z; /* Set requested window size here */
- ptab[protocol].winsize = wslotr; /* and in protocol-specific table */
- if (protocol == PROTO_K) { /* And for Kermit only... */
- swcapr = (wslotr > 1) ? 1 : 0; /* set window bit in capas word */
- if (wslotr > 1) { /* Window size > 1? */
- /* Maybe adjust packet size */
- y = adjpkl(urpsiz,wslotr,bigrbsiz);
- if (y != urpsiz) { /* Did it change? */
- urpsiz = y;
- if (msgflg)
- printf(
-" Adjusting receive packet-length to %d for %d window slots\n",
- urpsiz,
- wslotr
- );
- }
- }
- }
- return(success = 1);
-#endif /* NOXFER */
- }
-
- switch (xx) {
-
-#ifndef NOSPL
- case XYOUTP: /* OUTPUT command parameters */
- if ((y = cmkey(outptab,noutptab,"OUTPUT command parameter","pacing",
- xxstring)) < 0)
- return(y);
- switch(y) { /* Which parameter */
- case OUT_PAC: /* PACING */
- y = cmnum("Milliseconds to pause between each OUTPUT character",
- "100", 10,&x,xxstring);
- y = setnum(&z,x,y,16383); /* Verify and get confirmation */
- if (y < 0) return(y);
- if (z < 0) z = 0; /* (save some space) */
- pacing = z;
- return(success = 1);
- case OUT_ESC: /* Special-escapes */
- return(seton(&outesc));
- default: /* (shouldn't happen) */
- return(-2);
- }
-#endif /* NOSPL */
-
-#ifdef CK_SPEED
- case XYQCTL: {
- short *p;
- int zz;
- if ((z = cmkey(ctltab,2, "control-character prefixing option",""
- ,xxstring)) < 0)
- return(z);
- /* Make space for a temporary copy of the prefixing table */
-
- p = (short *)malloc(256 * sizeof(short));
- if (!p) {
- printf("?Internal error - malloc failure\n");
- return(-9);
- }
- for (i = 0; i < 256; i++) p[i] = ctlp[i]; /* Copy current table */
-
- switch (z) {
- case 0: /* UNPREFIXED control character */
- case 1: /* PREFIXED control character */
- while (1) { /* Collect a list of numbers */
-#ifndef NOSPL
- x_ifnum = 1; /* Turn off complaints from eval() */
-#endif /* NOSPL */
- if ((x = cmnum((z == 0) ?
-"\n Numeric ASCII value of control character that needs NO prefix,\n\
- or the word \"all\", or carriage return to complete the list" :
-"\n Numeric ASCII value of control character that MUST BE prefixed,\n\
- or the word \"all\", or carriage return to complete the list",
- "",10,&y,xxstring
- )) < 0) {
-#ifndef NOSPL
- x_ifnum = 0;
-#endif /* NOSPL */
- if (x == -3) {
- if ((x = cmcfm()) < 0) return(x);
- break;
- }
- if (x == -2) {
- if (p) { free((char *)p); p = NULL; }
- debug(F110,"SET CONTROL atmbuf",atmbuf,0);
- if (!ckstrcmp(atmbuf,"all",3,0) || /* "ALL" */
- !ckstrcmp(atmbuf,"al",2,0) ||
- !ckstrcmp(atmbuf,"a",1,0)) {
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
- prefixing = z ? PX_ALL : PX_NON;
- setprefix(prefixing);
- return(success = 1);
- } else { /* Not number, not ALL */
- printf(
- "?Please specify a number or the word ALL\n");
- return(-9);
- }
- } else {
- if (p) free((char *)p);
- return(x);
- }
- }
-#ifndef NOSPL
- x_ifnum = 0;
-#endif /* NOSPL */
-#ifdef UNPREFIXZERO
- zz = 0;
-#else
-#ifndef OS2
- zz = 1 - z;
-#else
- zz = 0; /* Allow 0 (but only for Zmodem) */
-#endif /* OS2 */
-#endif /* UNPREFIXZERO */
-
- /* printf("x = %d, y = %d, z = %d, zz = %d\n", x,y,z,zz); */
-
- if ((y > 31 && y < 127) || /* A specific numeric value */
- (y > 159 && y < 255) || /* Check that it is a valid */
- (y < zz) || /* control code. */
- (y > 255)) {
- printf("?Values allowed are: %d-31, 127-159, 255\n",zz);
- if (p) free((char *)p);
- return(-9);
- }
- x = y & 127; /* Get 7-bit value */
- if (z == 0) { /* If they are saying it is safe... */
- /* If flow control is Xon/Xoff */
- if (((flow == FLO_XONX) &&
- /* XON & XOFF chars not safe. */
- (x == XON || x == XOFF))
- ) {
- if (msgflg)
- printf(
- "Sorry, not while Xon/Xoff is in effect.\n");
- if (p) free((char *)p);
- return(-9);
- }
-#ifdef TNCODE
- else if (network && IS_TELNET()
- && (y == CR ||
- (unsigned) y == (unsigned) 255)) {
- if (msgflg)
- printf("Sorry, not on a TELNET connection.\n");
- if (p) free((char *)p);
- return(-9);
- }
-#endif /* TNCODE */
- }
- p[y] = (char) z; /* All OK, set flag */
- } /* End of while loop */
-/*
- Get here only if they have made no mistakes. Copy temporary table back to
- permanent one, then free temporary table and return successfully.
-*/
- for (i = 0; i < 256; i++) ctlp[i] = p[i];
- if (p) free((char *)p);
- if (z > 0) clearrq = 0; /* 199 (see SET PREFIXING) */
- return(success = 1);
- default:
- return(-2);
- }
- }
-#endif /* CK_SPEED */
- }
-
- switch (xx) {
-
-#ifndef NOXFER
- case XYREPT:
- if ((y = cmkey(rpttab,2,
- "repeat-count compression parameter","",xxstring)) < 0)
- return(y);
- switch(y) {
- case 0:
- return(success = seton(&rptena)); /* REPEAT COUNTS = ON, OFF */
- case 1: /* REPEAT MININUM number */
- printf("(not implemented yet, nothing happens)\n");
- return(-9);
- case 2: /* REPEAT PREFIX char */
- if ((x = cmnum("ASCII value","",10,&z,xxstring)) < 0)
- return(x);
- if ((x = cmcfm()) < 0) return(x);
- if ((z > 32 && z < 63) || (z > 95 && z < 127)) {
- if (y == 1) rptmin = (CHAR) z; else myrptq = (CHAR) z;
- return(success = 1);
- } else {
- printf("?Illegal value for prefix character\n");
- return(-9);
- }
- }
-#endif /* NOXFER */
-
-#ifndef NOSPL
- case XYALRM: {
-#ifndef COMMENT
- int yy;
- long zz;
- zz = -1L;
- yy = x_ifnum;
- x_ifnum = 1; /* Turn off internal complaints */
- y = cmnum("Seconds from now, or time of day as hh:mm:ss",
- "0" ,10, &x, xxstring);
- x_ifnum = yy;
- if (y < 0) {
- if (y == -2) { /* Invalid number or expression */
- zz = tod2sec(atmbuf); /* Convert to secs since midnight */
- if (zz < 0L) {
- printf("?Number, expression, or time of day required\n");
- return(-9);
- } else {
- char now[32]; /* Current time */
- char *p;
- long tnow;
- p = now;
- ztime(&p);
- tnow = atol(p+11) * 3600L +
- atol(p+14) * 60L + atol(p+17);
- if (zz < tnow) /* User's time before now */
- zz += 86400L; /* So make it tomorrow */
- zz -= tnow; /* Seconds from now. */
- }
- } else
- return(y);
- }
- if (x < 0) {
- printf("?Alarm time is in the past.\n");
- return(-9);
- }
- if ((y = cmcfm()) < 0) return(y);
- if (zz > -1L) { /* Time of day given? */
- x = zz;
- if (zz != (long) x) {
- printf(
-"Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
- );
- return(-9);
- }
- }
- return(setalarm((long)x));
- }
-#else
-/*
- This is to allow long values where int and long are not the same, e.g.
- on 16-bit systems. But something is wrong with it.
-*/
- if ((y = cmtxt("seconds from now", "0", &s, xxstring)) < 0)
- return(y);
- if (rdigits(s)) {
- return(setalarm(atol(s)));
- } else {
- printf("%s - not a number\n",s);
- return(-9);
- }
-#endif /* COMMENT */
-#endif /* NOSPL */
-
-#ifndef NOXFER
- case XYPROTO:
- return(setproto());
-#endif /* NOXFER */
-
-/*
- C-Kermit unprefixes control characters automatically on network connections
- if CLEAR-CHANNEL is ON, which it is by default. But not all network
- connections are transparent to all control characters. For example, the
- DEC-20, even when you TELNET to it, is sensitive to Ctrl-O and Ctrl-T.
- If you tell C-Kermit to SET CONTROL PREFIX 15 and/or 20, it doesn't help
- because CLEAR-CHANNEL is still in effect. If the user goes to the trouble
- to set up some prefixing, then Kermit should do what the user said. In
- C-Kermit 7.1 Alpha.03 we change the code to set clearrq to 0 if the user
- gives a SET PREFIXING or SET CONTROL PREFIX command.
-*/
-
-#ifdef CK_SPEED
- case XYPREFIX: {
-#ifdef COMMENT
- extern int clearrq;
-#endif /* COMMENT */
- if ((z = cmkey(pfxtab, 4, "control-character prefixing option",
- "", xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- clearrq = 0; /* 199 */
- setprefix(z);
-#ifdef COMMENT
- if (hints && (z == PX_ALL || z == PX_CAU) && clearrq) {
- printf("Hint: Use SET CLEAR-CHANNEL OFF to disable negotiation of\n");
- printf(" SET PREFIXING NONE during file transfers on reliable\n");
- printf(" connections.\n");
- }
-#endif /* COMMENT */
- return(success = 1);
- }
-#endif /* CK_SPEED */
-
-#ifndef NOSPL
- case XYLOGIN:
- if ((z = cmkey(logintab, 3, "value for login script","userid",
- xxstring)) < 0)
- return(z);
- x = cmdgquo();
- if (z == LOGI_PSW)
- cmdsquo(0);
- if ((y = cmtxt("text","", &s, NULL)) < 0) {
- cmdsquo(x);
- return(y);
- }
- cmdsquo(x);
-#ifdef IKSD
- if (inserver)
- return(success = 0);
-#endif /* IKSD */
- s = brstrip(s);
- if ((int)strlen(s) > 63) {
- printf("Sorry, too long\n");
- return(-9);
- }
- switch(z) {
- case LOGI_UID:
- ckstrncpy(uidbuf,s,UIDBUFLEN);
- sl_uid_saved = 0;
- break;
- case LOGI_PSW:
- ckstrncpy(pwbuf,s,PWBUFL);
- if (pwbuf[0]) {
- pwflg = 1;
-#ifdef OS2
- pwcrypt = 1;
-#else /* OS2 */
- pwcrypt = 0;
-#endif /* OS2 */
- }
- break;
- case LOGI_PRM:
- ckstrncpy(prmbuf,s,PWBUFL);
- }
- return(success = 1);
-#endif /* NOSPL */
- }
-
- switch (xx) {
-
- case XYSTARTUP:
- if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- DeleteStartupFile = (y != 0) ? 0 : 1;
- return(success = 1);
-
- case XYTMPDIR:
- x = cmdir("Name of temporary directory","",&s,xxstring);
- if (x == -3)
- s = "";
- else if (x < 0)
- return(x);
- if ((x = cmcfm()) < 0) return(x);
- makestr(&tempdir,s);
- return(tempdir ? 1 : 0);
-
-#ifndef NOXFER
- case XYDEST: /* DESTINATION */
- return(setdest());
-#endif /* NOXFER */
-
-#ifndef NOPUSH
-#ifndef NOFRILLS
-
-/* Editor, Browser, and FTP Client */
-
- case XYEDIT: /* EDITOR */
-#ifdef IKSD
- if (inserver) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- /* Don't let this be set remotely */
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
- return(success = 0);
-#endif /* CK_APC */
-
-#ifdef OS2ORUNIX
- {
- char *p = getenv("PATH");
- char *e;
- e = editor[0] ? (char *) editor : getenv("EDITOR");
- if (!e) e = "";
- if (p)
- x = cmifip("Name of preferred editor",e,&s,&y,0,p,xxstring);
- else
- x = cmifi("Full path of preferred editor",e,&s,&y,xxstring);
- if (x < 0 && x != -3)
- return(x);
- }
-#else
-#ifdef VMS
- if ((y = cmtxt("DCL command for editing", "edit", &s, NULL)) < 0) {
- if (x != -3)
- return(x);
- }
-#else
- if ((x = cmifi("Full path of preferred editor","",&s,&y,xxstring))<0) {
- if (x != -3)
- return(x);
- }
-#endif /* VMS */
-#endif /* OS2ORUNIX */
-#ifdef VMS
- ckstrncpy(editor,s,CKMAXPATH);
- editopts[0] = NUL;
-#else
- if (y != 0) {
- printf("?A single file please\n");
- return(-2);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmtxt("editor command-line options","",&s,NULL)) < 0)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((z = cmcfm()) < 0) return(z);
- if (line[0]) {
- zfnqfp(line,CKMAXPATH,editor);
- ckstrncpy(editopts,tmpbuf,128);
- } else {
- editor[0] = NUL;
- editopts[0] = NUL;
- }
-#endif /* VMS */
- return(success = 1);
-
-#ifndef NOFTP
-#ifndef SYSFTP
-#ifdef TCPSOCKET
- case XYFTPX:
- return(dosetftp()); /* SET FTP */
-#endif /* TCPSOCKET */
-#endif /* SYSFTP */
-#endif /* NOFTP */
-
-#ifdef BROWSER
-#ifndef NOFTP
-#ifdef SYSFTP
- case XYFTP: /* SET FTP-CLIENT */
-#endif /* SYSFTP */
-#endif /* NOFTP */
- case XYBROWSE: /* SET BROWSER */
- {
- char *p = getenv("PATH");
- char *app = (char *) browser, *opts = (char *) browsopts;
-#ifndef NOFTP
-#ifdef SYSFTP
- extern char ftpapp[], ftpopts[];
- if (xx == XYFTP) {
- app = (char *)ftpapp;
- opts = (char *)ftpopts;
- }
-#endif /* SYSFTP */
-#endif /* NOFTP */
-#ifdef IKSD
- if (inserver) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- /* Don't let this be set remotely */
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
- return(success = 0);
-#endif /* CK_APC */
-#ifdef OS2ORUNIX
- if (p)
- x = cmifip(xx == XYBROWSE ?
- "Name of preferred browser" :
- "Name of preferred ftp client",
-#ifdef OS2
- xx == XYFTP ? "ftp.exe" : ""
-#else
- xx == XYFTP ? "ftp" : ""
-#endif /* OS2 */
- ,&s,&y,0,p,xxstring
- );
- else
- x = cmifi(xx == XYBROWSE ?
- "Full path of preferred browser" :
- "Full path of preferred ftp client",
- "",&s,&y,xxstring
- );
- if (x < 0 && x != -3)
- return(x);
-#else
-#ifdef VMS
- if ((x = cmtxt("DCL command to start your preferred Web browser",
- "", &s, NULL)) < 0) {
- if (x != -3)
- return(x);
- }
-#else
- if ((x = cmifi("Full path of preferred browser","",&s,&y,xxstring)
- ) < 0) {
- if (x != -3)
- return(x);
- }
-#endif /* VMS */
-#endif /* OS2ORUNIX */
-#ifdef VMS
- ckstrncpy(app,s,CKMAXPATH);
- *opts = NUL;
-#else
- if (y != 0) {
- printf("?A single file please\n");
- return(-2);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmtxt(xx == XYBROWSE ?
- "browser command-line options" :
- "ftp client command-line options",
- "",&s,NULL)
- ) < 0)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((z = cmcfm()) < 0) return(z);
- if (line[0]) {
- zfnqfp(line,CKMAXPATH,app);
- ckstrncpy(opts, tmpbuf, 128);
- } else {
- *app = NUL;
- *opts = NUL;
- }
-#endif /* VMS */
- return(success = 1);
- }
-#endif /* BROWSER */
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-
-#ifdef CK_CTRLZ
- case XYEOF: { /* SET EOF */
- extern int eofmethod; extern struct keytab eoftab[];
- if ((x = cmkey(eoftab,3,"end-of-file detection method","",
- xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- eofmethod = x;
- return(success = 1);
- }
-#endif /* CK_CTRLZ */
-
-#ifdef SESLIMIT
- case XYLIMIT: { /* Session-Limit (length of session in seconds) */
- extern int seslimit;
-#ifdef OS2
- extern int downloaded;
-#endif /* OS2 */
- y = cmnum("Maximum length of session, seconds","0",10,&x,xxstring);
- if (inserver &&
-#ifdef IKSDCONF
- iksdcf
-#else
- 1
-#endif /* IKSDCONF */
-#ifdef OS2
- || downloaded
-#endif /* OS2 */
- ) {
- if ((z = cmcfm()) < 0)
- return(z);
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
- return(setnum(&seslimit,x,y,86400));
- }
-#endif /* SESLIMIT */
-
- case XYRELY: { /* SET RELIABLE */
- if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- reliable = x;
- setreliable = (x != SET_AUTO);
- debug(F101,"SET RELIABLE reliable","",reliable);
- return(success = 1);
- }
-
-#ifdef STREAMING
- case XYSTREAM: { /* SET STREAMING */
- extern int streamrq;
- if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- streamrq = x;
- return(success = 1);
- }
-#endif /* STREAMING */
-
-#ifdef CKSYSLOG
- case XYSYSL: {
- if ((x = cmkey(syslogtab,nsyslog,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSD
- if (inserver &&
-#ifdef IKSDCONF
- iksdcf
-#else
- 1
-#endif /* IKSDCONF */
- ) {
- printf("?Sorry, command disabled.\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- /* Don't let this be set remotely */
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
- return(success = 0);
-#endif /* CK_APC */
- ckxsyslog = x;
- return(success = 1);
- }
-#endif /* CKSYSLOG */
-
-#ifdef TLOG
- case XYTLOG: { /* SET TRANSACTION-LOG */
- extern int tlogsep;
- if ((x = cmkey(vbtab,nvb,"","verbose",xxstring)) < 0)
- return(x);
- if (x == 0) {
- if ((y = cmtxt("field separator",",",&s,NULL)) < 0) return(y);
- s = brstrip(s);
- if (*s) {
- if (s[1]) {
- printf("?A single character, please.\n");
- return(-9);
- } else if ((*s >= '0' && *s <= '9') ||
- (*s >= 'A' && *s <= 'Z') ||
- (*s >= 'a' && *s <= 'z')) {
- printf("?A non-alphanumeric character, please.\n");
- return(-9);
- } else
- tlogsep = *s;
- }
- } else {
- if ((y = cmcfm()) < 0) return(y);
- }
-#ifdef IKSD
- if (inserver && isguest) {
- printf("?Sorry, command disabled.\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- /* Don't let this be set remotely */
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
- return(success = 0);
-#endif /* CK_APC */
- tlogfmt = x;
- return(success = 1);
- }
-#endif /* TLOG */
-
- case XYCLEAR: { /* SET CLEARCHANNEL */
- if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- clearrq = x;
- return(success = 1);
- }
-
-#ifdef CK_AUTHENTICATION
- case XYAUTH: { /* SET AUTHENTICATION */
-#ifdef CK_KERBEROS
- int kv = 0;
- extern struct krb_op_data krb_op;
-#endif /* CK_KERBEROS */
- char * p = NULL;
- if ((x =
- cmkey(setauth,nsetauth,"authentication type","",xxstring)) < 0)
- return(x);
- switch (x) {
-#ifdef CK_KERBEROS
- case AUTH_KRB4: kv = 4; break; /* Don't assume values are same */
- case AUTH_KRB5: kv = 5; break;
-#endif /* CK_KERBEROS */
-#ifdef CK_SRP
- case AUTH_SRP: break;
-#endif /* CK_SRP */
-#ifdef CK_SSL
- case AUTH_SSL:
- case AUTH_TLS:
- break;
-#endif /* CK_SSL */
- default:
- printf("?Authorization type not supported yet - \"%s\"\n",
- atmbuf);
- return(-9);
- }
-#ifdef IKSD
- if (inserver &&
-#ifdef IKSDCONF
- iksdcf
-#else
- 1
-#endif /* IKSDCONF */
- ) {
- if ((y = cmcfm()) < 0) return(y);
- printf("?Sorry, command disabled.\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- /* Don't let this be set remotely */
- if (apcactive == APC_LOCAL ||
- apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)) {
- if ((y = cmcfm()) < 0) return(y);
- return(success = 0);
- }
-#endif /* CK_APC */
-
- switch(x) {
-#ifdef CK_KERBEROS
- case AUTH_KRB4:
- case AUTH_KRB5: {
- if ((x = cmkey(kv == 4 ? k4tab : k5tab,
- kv == 4 ? nk4tab : nk5tab,
- "Kerberos parameter","",xxstring)) < 0) {
- return(x);
- }
- s = "";
- switch (x) {
-#ifdef KRB4
- case XYKRBDBG:
- if (kv == 4) {
- if ((y = seton(&k4debug)) < 0)
- return(y);
-#ifdef NT
- ck_krb4_debug(k4debug);
-#endif /* NT */
- } else {
- return(-9);
- }
- break;
-#endif /* KRB4 */
- case XYKRBLIF:
- if ((y = cmnum("TGT lifetime","600",10,&z,xxstring)) < 0)
- return(y);
- break;
- case XYKRBPRE:
- if (kv == 4) {
- if ((y = seton(&krb4_d_preauth)) < 0)
- return(y);
- } else {
- return(-9);
- }
- break;
- case XYKRBINS:
- if ((y = cmtxt("Instance name","",&s,xxstring)) < 0)
- return(y);
- break;
- case XYKRBFWD:
- if (kv == 5) {
- if ((y = seton(&krb5_d_forwardable)) < 0)
- return(y);
- } else {
- return(-9);
- }
- break;
- case XYKRBPRX:
- if (kv == 5) {
- if ((y = seton(&krb5_d_proxiable)) < 0)
- return(y);
- } else {
- return(-9);
- }
- break;
- case XYKRBRNW:
- if ((y = cmnum("TGT renewable lifetime",
- "0",10,&z,xxstring)) < 0)
- return(y);
- break;
- case XYKRBADR:
- if (kv == 5) {
- if ((y = seton(&krb5_checkaddrs)) < 0)
- return(y);
- } else {
- if ((y = seton(&krb4_checkaddrs)) < 0)
- return(y);
- }
- break;
- case XYKRBNAD:
- if (kv == 5) {
- if ((y = seton(&krb5_d_no_addresses)) < 0)
- return(y);
- }
- break;
- case XYKRBADD:
- if (kv == 5) {
- char * tmpaddrs[KRB5_NUM_OF_ADDRS];
- for (i = 0; i < KRB5_NUM_OF_ADDRS; i++)
- tmpaddrs[i] = NULL;
-
- if ((y =
- cmfld("List of IP addresses","",&s,xxstring)) < 0)
- return(y);
- makelist(s,tmpaddrs,KRB5_NUM_OF_ADDRS);
- if ((y = cmcfm()) < 0) {
- for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
- if (tmpaddrs[i] != NULL)
- free(tmpaddrs[i]);
- }
- return(y);
- }
- for (i = 0;
- i < KRB5_NUM_OF_ADDRS && tmpaddrs[i];
- i++) {
- if (inet_addr(tmpaddrs[i]) == 0xffffffff) {
- printf("invalid ip address: %s\n",
- tmpaddrs[i]);
- for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
- if (tmpaddrs[i] != NULL)
- free(tmpaddrs[i]);
- }
- return(-9);
- }
- }
- for (i = 0;
- i < KRB5_NUM_OF_ADDRS && krb5_d_addrs[i];
- i++) {
- if (krb5_d_addrs[i])
- free(krb5_d_addrs[i]);
- krb5_d_addrs[i] = NULL;
- }
- for (i = 0;
- i < KRB5_NUM_OF_ADDRS && tmpaddrs[i];
- i++) {
- krb5_d_addrs[i] = tmpaddrs[i];
- tmpaddrs[i] = NULL;
- }
- krb5_d_addrs[i] = NULL;
- return(success = 1);
- }
- break;
-
- case XYKRBGET:
- if (kv == 5) {
- if ((y = seton(&krb5_autoget)) < 0)
- return(y);
- } else {
- if ((y = seton(&krb4_autoget)) < 0)
- return(y);
- }
- break;
- case XYKRBDEL:
- if ((z = cmkey(kdestab,nkdestab,
- "Auto Destroy Tickets",
- "never",xxstring)) < 0)
- return(z);
- break;
- case XYKRBPR:
- if ((y = cmtxt("User ID",uidbuf,&s,xxstring)) < 0)
- return(y);
- break;
- case XYKRBRL:
- if ((y = cmtxt("Name of realm","",&s,xxstring)) < 0)
- return(y);
- break;
- case XYKRBKTB:
- y = cmifi("Filename","",&s,&z,xxstring);
- if (y != -3) {
- if (y < 0)
- return(y);
- if (z) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
- }
- break;
- case XYKRBCC:
- if ((y = cmofi("Filename","",&s,xxstring)) < 0)
- return(y);
- break;
- case XYKRBSRV:
- if ((y = cmtxt("Name of service to use in ticket",
- (kv == 4 ? "rcmd" : "host"),
- &s,
- xxstring
- )) < 0)
- return(y);
- break;
- case XYKRBK5K4:
- if (kv == 5) {
- if ((y = seton(&krb5_d_getk4)) < 0)
- return(y);
- } else {
- return(-9);
- }
- break;
- case XYKRBPRM: /* Prompt */
- if ((z = cmkey(krbprmtab,2,"","",xxstring)) < 0)
- return(z);
- if ((y = cmtxt((z == KRB_PW_PRM) ?
- "Text of prompt;\nmay contain \"%s\" to be replaced by principal name" :
- "Text of prompt",
- "",
- &s,
- xxstring
- )
- ) < 0)
- return(y);
- break;
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- if ((y = cmcfm()) < 0)
- return(y);
-#ifdef IKSD
- if (inserver &&
-#ifdef IKSDCONF
- iksdcf
-#else /* IKSDCONF */
- 1
-#endif /* IKSDCONF */
- )
- return(success = 0);
-#endif /* IKSD */
-
- switch (x) { /* Copy value to right place */
- case XYKRBLIF: /* Lifetime */
- if (kv == 4)
- krb4_d_lifetime = z;
- else
- krb5_d_lifetime = z;
- break;
- case XYKRBRNW:
- if (kv == 5)
- krb5_d_renewable = z;
- break;
- case XYKRBPR: /* Principal */
- s = brstrip(s); /* Strip braces around. */
- if (kv == 4)
- makestr(&krb4_d_principal,s);
- else
- makestr(&krb5_d_principal,s);
- break;
- case XYKRBINS: /* Instance */
- if (kv == 4)
- makestr(&krb4_d_instance,s);
- else
- makestr(&krb5_d_instance,s);
- break;
- case XYKRBRL: /* Realm */
- if (kv == 4)
- makestr(&krb4_d_realm,s);
- else
- makestr(&krb5_d_realm,s);
- break;
- case XYKRBKTB: /* Key Table */
- if (kv == 4)
- makestr(&k4_keytab,s);
- else
- makestr(&k5_keytab,s);
- break;
- case XYKRBCC: /* Credentials cache */
- makestr(&krb5_d_cc,s);
- break;
- case XYKRBSRV: /* Service Name */
- if (kv == 4)
- makestr(&krb4_d_srv,s);
- else
- makestr(&krb5_d_srv,s);
- break;
- case XYKRBDEL:
- if (kv == 5)
- krb5_autodel = z;
- else
- krb4_autodel = z;
- break;
- case XYKRBPRM: /* Prompt */
- s = brstrip(s);
- switch (z) {
- case KRB_PW_PRM: { /* Password */
- /* Check that there are no more than */
- /* two % fields and % must followed by 's'. */
- int i,n,len;
- len = strlen(s);
- for (i = 0, n = 0; i < len; i++) {
- if (s[i] == '%') {
- if (s[i+1] != '%') {
- if (s[i+1] != 's') {
- printf(
- "Only %%s fields are permitted.\n"
- );
- return(-9);
- }
- if (++n > 2) {
- printf(
- "Only two %%s fields are permitted.\n");
- return(-9);
- }
- }
- i++;
- }
- }
- if (kv == 5)
- makestr(&k5pwprompt,s);
- else
- makestr(&k4pwprompt,s);
- break;
- }
- case KRB_PR_PRM: { /* Principal */
- /* Check to make sure there are no % fields */
- int i,len;
- len = strlen(s);
- for (i = 0; i < len; i++) {
- if (s[i] == '%') {
- if (s[i+1] != '%') {
- printf(
- "%% fields are not used in this command.\n");
- return(-9);
- }
- i++;
- }
- }
- if (kv == 5)
- makestr(&k5prprompt,s);
- else
- makestr(&k4prprompt,s);
- break;
- }
- }
- }
- break;
- }
-#endif /* CK_KERBEROS */
-#ifdef CK_SRP
- case AUTH_SRP: {
- if ((x = cmkey(srptab, nsrptab,
- "SRP parameter","",xxstring)) < 0) {
- return(x);
- }
- s = "";
- switch (x) {
- case XYSRPPRM: /* Prompt */
- if ((z = cmkey(srpprmtab,1,"","",xxstring)) < 0)
- return(z);
- if ((y = cmtxt(
- "Text of prompt;\nmay contain one \"%s\" to be replaced by the username",
- "",
- &s,
- xxstring
- )
- ) < 0)
- return(y);
- break;
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- if ((y = cmcfm()) < 0)
- return(y);
- switch (x) { /* Copy value to right place */
- case XYSRPPRM: /* Prompt */
- s = brstrip(s);
- switch (z) {
- case SRP_PW_PRM: { /* Password */
- /* Check %s fields */
- int i,n,len;
- len = strlen(s);
- for (i = 0, n = 0; i < len; i++) {
- if (s[i] == '%') {
- if (s[i+1] != '%') {
- if (s[i+1] != 's') {
- printf(
- "Only %%s fields are permitted.\n");
- return(-9);
- }
- if (++n > 1) {
- printf(
- "Only one %%s field is permitted.\n");
- return(-9);
- }
- }
- i++;
- }
- }
- makestr(&srppwprompt,s);
- break;
- }
- }
- }
- break;
- }
-#endif /* CK_SRP */
-#ifdef CK_SSL
- case AUTH_SSL:
- case AUTH_TLS: {
- if ((z = cmkey(ssltab, nssltab,
- (x == AUTH_SSL ? "SSL parameter" : "TLS parameter"),
- "",xxstring)) < 0)
- return(z);
- s = "";
- switch (z) {
- case XYSSLRCFL: /* SSL/TLS RSA Certs file */
- case XYSSLRCCF: /* SSL/TLS RSA Certs Chain file */
- case XYSSLRKFL: /* SSL/TLS RSA Key File */
- case XYSSLDCFL: /* SSL/TLS DSA Certs file */
- case XYSSLDCCF: /* SSL/TLS DSA Certs Chain file */
- case XYSSLDKFL: /* SSL/TLS DH Key File */
- case XYSSLDPFL: /* SSL/TLS DH Param File */
- case XYSSLCRL: /* SSL/TLS CRL File */
- case XYSSLVRFF: /* SSL/TLS Verify File */
- case XYSSLRND: /* SSL/TLS Random File */
- y = cmifi("Filename","",&s,&x,xxstring);
- if (y != -3) {
- if (y < 0)
- return(y);
- if (x) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- s = brstrip(s);
- if ((y = cmcfm()) < 0)
- return(y);
- switch (z) {
- case XYSSLRCFL: /* SSL/TLS RSA Certs file */
- if (!s[0] && ssl_rsa_cert_file) {
- free(ssl_rsa_cert_file);
- ssl_rsa_cert_file = NULL;
- } else if (s[0]) {
- makestr(&ssl_rsa_cert_file,s);
- if (!ssl_rsa_key_file)
- makestr(&ssl_rsa_key_file,s);
- }
- break;
- case XYSSLRCCF: /* SSL/TLS RSA Certs Chain file */
- if (!s[0] && ssl_rsa_cert_chain_file) {
- free(ssl_rsa_cert_chain_file);
- ssl_rsa_cert_chain_file = NULL;
- } else if (s[0]) {
- makestr(&ssl_rsa_cert_chain_file,s);
- }
- break;
- case XYSSLRKFL: /* SSL/TLS RSA Key File */
- if (!s[0] && ssl_rsa_key_file) {
- free(ssl_rsa_key_file);
- ssl_rsa_key_file = NULL;
- } else if (s[0]) {
- makestr(&ssl_rsa_key_file,s);
- }
- break;
- case XYSSLDCFL: /* SSL/TLS DSA Certs file */
- if (!s[0] && ssl_dsa_cert_file) {
- free(ssl_dsa_cert_file);
- ssl_dsa_cert_file = NULL;
- } else if (s[0]) {
- makestr(&ssl_dsa_cert_file,s);
- if (!ssl_dh_key_file)
- makestr(&ssl_dh_key_file,s);
- }
- break;
- case XYSSLDCCF: /* SSL/TLS DSA Certs Chain file */
- if (!s[0] && ssl_dsa_cert_chain_file) {
- free(ssl_dsa_cert_chain_file);
- ssl_dsa_cert_chain_file = NULL;
- } else if (s[0]) {
- makestr(&ssl_dsa_cert_chain_file,s);
- }
- break;
- case XYSSLDKFL: /* SSL/TLS DH Key File */
- if (!s[0] && ssl_dh_key_file) {
- free(ssl_dh_key_file);
- ssl_dh_key_file = NULL;
- } else if (s[0]) {
- makestr(&ssl_dh_key_file,s);
- }
- break;
- case XYSSLDPFL: /* SSL/TLS DH Param File */
- if (!s[0] && ssl_dh_param_file) {
- free(ssl_dh_param_file);
- ssl_dh_param_file = NULL;
- } else if (s[0]) {
- makestr(&ssl_dh_param_file,s);
- }
- break;
- case XYSSLCRL: /* SSL/TLS CRL File */
- if (!s[0] && ssl_crl_file) {
- free(ssl_crl_file);
- ssl_crl_file = NULL;
- } else if (s[0]) {
- makestr(&ssl_crl_file,s);
- }
- break;
- case XYSSLVRFF: /* SSL/TLS Verify File */
- if (!s[0] && ssl_verify_file) {
- free(ssl_verify_file);
- ssl_verify_file = NULL;
- } else if (s[0]) {
- makestr(&ssl_verify_file,s);
- }
- break;
- case XYSSLRND: /* SSL/TLS Random File */
- if (!s[0] && ssl_rnd_file) {
- free(ssl_rnd_file);
- ssl_rnd_file = NULL;
- } else if (s[0]) {
- makestr(&ssl_rnd_file,s);
- }
- break;
- }
- break;
-
- case XYSSLCRLD:
- case XYSSLVRFD: {
- char * d = NULL;
- if (z == XYSSLVRFD)
- d= getenv("SSL_CERT_DIR");
- if (d == NULL)
- d = "";
- if ((y = cmdir("Directory",d,&s,xxstring)) < 0)
- if (y != -3)
- return(y);
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- s = brstrip(s);
- if ((y = cmcfm()) < 0)
- return(y);
- switch(z) {
- case XYSSLCRLD:
- if (!s[0] && ssl_crl_dir) {
- free(ssl_crl_dir);
- ssl_crl_dir = NULL;
- } else if (s[0]) {
- makestr(&ssl_crl_dir,s);
- }
- break;
- case XYSSLVRFD:
- if (!s[0] && ssl_verify_dir) {
- free(ssl_verify_dir);
- ssl_verify_dir = NULL;
- } else if (s[0]) {
- makestr(&ssl_verify_dir,s);
- }
- break;
- }
- break;
- }
- case XYSSLCOK: /* SSL/TLS Certs-Ok flag */
- if ((y = seton(&ssl_certsok_flag)) < 0)
- return(y);
- break;
- case XYSSLDBG: /* SSL/TLS Debug flag */
- if ((y = seton(&ssl_debug_flag)) < 0)
- return(y);
- break;
- case XYSSLON: /* SSL/TLS Only flag */
- switch (x) {
- case AUTH_SSL:
- if ((y = seton(&ssl_only_flag)) < 0)
- return(y);
- break;
- case AUTH_TLS:
- if ((y = seton(&tls_only_flag)) < 0)
- return(y);
- break;
- }
- break;
- case XYSSLVRB: /* SSL/TLS Verbose flag */
- if ((y = seton(&ssl_verbose_flag)) < 0)
- return(y);
- break;
- case XYSSLVRF: /* SSL/TLS Verify flag */
- if ((x = cmkey(sslvertab, nsslvertab,
- "SSL/TLS verify mode",
- "peer-cert",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ssl_verify_flag = x;
- break;
- case XYSSLDUM:
- if ((y = seton(&ssl_dummy_flag)) < 0)
- return(y);
- break;
- case XYSSLCL: { /* SSL/TLS Cipher List */
-#ifdef COMMENT
- /* This code is used to generate a colon delimited */
- /* list of the ciphers currently in use to be used */
- /* as the default for cmtxt(). However, a better */
- /* default is simply the magic keyword "ALL". */
- CHAR def[1024] = "";
- if (ssl_con != NULL) {
- CHAR * p = NULL, *q = def;
- int i, len;
-
- for (i = 0; ; i++) {
- p = (CHAR *) SSL_get_cipher_list(ssl_con,i);
- if (p == NULL)
- break;
- len = strlen(p);
- if (q+len+1 >= def+1024)
- break;
- if (i != 0)
- *q++ = ':';
- strcpy(q,p);
- q += len;
- }
- }
-#endif /* COMMENT */
- char * p = getenv("SSL_CIPHER");
- if (!p)
- p = "ALL";
- if ((y = cmtxt(
- "Colon-delimited list of ciphers or ALL (case-sensitive)",
- p,
- &s,
- xxstring
- )
- ) < 0)
- return(y);
- makestr(&ssl_cipher_list,s);
- if (ssl_con == NULL) {
- SSL_library_init();
- ssl_ctx = (SSL_CTX *)
- SSL_CTX_new((SSL_METHOD *)TLSv1_method());
- if (ssl_ctx != NULL)
- ssl_con= (SSL *) SSL_new(ssl_ctx);
- }
- if (ssl_con) {
- SSL_set_cipher_list(ssl_con,ssl_cipher_list);
- }
- break;
- }
- }
- break;
- }
-#endif /* CK_SSL */
- default:
- break;
- }
- return(success = 1);
- }
-#endif /* CK_AUTHENTICATION */
-
-#ifndef NOSPL
- case XYFUNC:
- if ((x = cmkey(functab,nfunctab,"","diagnostics",xxstring)) < 0)
- return(x);
- switch (x) {
- case FUNC_DI: return(seton(&fndiags));
- case FUNC_ER: return(seton(&fnerror));
- default: return(-2);
- }
-#endif /* NOSPL */
-
- case XYSLEEP: /* SET SLEEP / PAUSE */
- if ((x = cmkey(sleeptab,1,"","cancellation",xxstring)) < 0)
- return(x);
- return(seton(&sleepcan));
-
- case XYCD: /* SET CD */
- if ((x = cmkey(cdtab,ncdtab,"","",xxstring)) < 0)
- return(x);
- switch (x) {
- case XYCD_H: { /* SET CD HOME */
- extern char * myhome;
- if ((y = cmdir("Directory name",zhome(),&s,xxstring)) < 0)
- return(y);
- makestr(&myhome,s);
- return(success = 1);
- }
- case XYCD_M: /* SET CD MESSAGE */
- if ((x = cmkey(cdmsg,ncdmsg,"","",xxstring)) < 0)
- return(x);
- if (x == 2) { /* CD MESSAGE FILE */
- if ((x = cmtxt("Name of file","",&s,NULL)) < 0)
- return(x);
- if (!*s) {
- s = NULL;
-#ifndef NOXFER
- srvcdmsg = 0;
-#endif /* NOXFER */
- }
- makestr(&cdmsgstr,s);
- makelist(cdmsgstr,cdmsgfile,8);
- return(success = 1);
- }
-
- if ((y = cmcfm()) < 0) return(y); /* CD-MESSAGE ON/OFF */
-#ifndef NOXFER
- if (x > 0)
- srvcdmsg |= 2;
- else
- srvcdmsg &= 1;
-#endif /* NOXFER */
- return(success = 1);
-
- case XYCD_P: { /* SET CD PATH */
- extern char * ckcdpath;
- if ((x = cmtxt("CD PATH string","",&s,xxstring)) < 0)
- return(x);
- makestr(&ckcdpath,s);
- return(success = 1);
- }
- }
-
-#ifndef NOLOCAL
-#ifdef STOPBITS
- case XYSTOP: /* STOP-BITS */
- if ((x = cmkey(stoptbl,2,"Stop bits for serial device","",
- xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- if (x > 0 && x < 3) {
- stopbits = x;
-#ifdef TN_COMPORT
- if (network && istncomport()) {
- tnsettings(-1, x);
- return(success = 1);
- }
-#endif /* TN_COMPORT */
-#ifdef HWPARITY
- return(success = 1);
-#else /* HWPARITY */
- return(-2);
-#endif /* HWPARITY */
- } else
- return(-2);
-#endif /* STOPBITS */
-
- case XYDISC: {
- extern int clsondisc;
- return(seton(&clsondisc));
- }
-
- case XYSERIAL: {
- /* char c; */
- extern int cmask;
- if ((x = cmkey(sertbl,nsertbl,
- "Serial device character size, parity, and stop bits",
- "8N1", xxstring)) < 0)
- return(x);
- ckstrncpy(line,atmbuf,LINBUFSIZ); /* Associated keyword string */
- s = line;
- if ((y = cmcfm()) < 0)
- return(y);
- ckstrncpy(line,sernam[x],LINBUFSIZ);
- s = line;
- if (s[0] != '8' && s[0] != '7') /* Char size */
- return(-2);
- else
- z = s[0] - '0';
- if (isupper(s[1])) /* Parity */
- s[1] = tolower(s[1]);
- if (s[2] != '1' && s[2] != '2') /* Stop bits */
- return(-2);
- else
- stopbits = s[2] - '0';
- if (z == 8) { /* 8 bits + parity (or not) */
- parity = 0; /* Set parity */
- hwparity = (s[1] == 'n') ? 0 : s[1];
- setcmask(8); /* Also set TERM BYTESIZE to 8 */
- } else { /* 7 bits plus parity */
- parity = (s[1] == 'n') ? 0 : s[1];
- hwparity = 0;
- setcmask(7); /* Also set TERM BYTESIZE to 7 */
- }
-#ifdef TN_COMPORT
- if (network && !istncomport())
- tnsettings(parity, stopbits);
-#endif /* TN_COMPORT */
-
- return(success = 1); /* from SET SERIAL */
- }
-
- case XYOPTS: { /* SET OPTIONS */
- extern int setdiropts();
- extern int settypopts();
-#ifdef CKPURGE
- extern int setpurgopts();
-#endif /* CKPURGE */
- if ((x = cmkey(optstab,noptstab,"for command","", xxstring)) < 0)
- return(x);
- switch (x) {
-#ifndef NOFRILLS
- case XXDEL:
- return(setdelopts());
-#endif /* NOFRILLS */
- case XXDIR:
- return(setdiropts());
- case XXTYP:
- return(settypopts());
-#ifdef CKPURGE
- case XXPURGE:
- return(setpurgopts());
-#endif /* CKPURGE */
- default:
- return(-2);
- }
- }
-#endif /* NOLOCAL */
-#ifndef NOXFER
- case XYQ8FLG: {
- extern int q8flag;
- return(seton(&q8flag));
- }
- case XYTIMER: {
- extern int asktimer;
- y = cmnum("Time limit for ASK command, seconds","0",10,&x,xxstring);
-#ifdef QNX16
- return(setnum(&asktimer,x,y,32767));
-#else
- return(setnum(&asktimer,x,y,86400));
-#endif /* QNX16 */
- }
- case XYFACKB: {
- extern int fackbug;
- return(seton(&fackbug));
- }
-#endif /* NOXFER */
-
- case XYHINTS:
- return(seton(&hints));
-
-#ifndef NOSPL
- case XYEVAL: {
- extern int oldeval;
- if ((x = cmkey(oldnew,2,"","", xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- oldeval = x;
- return(success = 1);
- }
-#endif /* NOSPL */
-
-#ifndef NOXFER
- case XYFACKP: {
- extern int fackpath;
- return(seton(&fackpath));
- }
-#endif /* NOXFER */
-
- case XYQNXPL: {
- extern int qnxportlock;
- return(seton(&qnxportlock));
- }
-
-#ifndef NOCMDL
-#ifdef IKSD
- case XYIKS: {
- int setiks();
- return(setiks());
- }
-#endif /* IKSD */
-#endif /* NOCMDL */
-
-#ifdef CKROOT
- case XYROOT:
- return(dochroot());
-#endif /* CKROOT */
-
-#ifndef NOSPL
-#ifndef NOSEXP
- case XYSEXP: {
- if ((x = cmkey(sexptab,3,"","", xxstring)) < 0)
- return(x);
- switch (x) {
- case 0:
- if ((x = cmkey(ooatab,3,"","automatic", xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- sexpecho = x;
- break;
- case 1: {
- int i, xx;
- xx = sexpmaxdep;
- if ((y = cmnum("Maximum recursion depth",
- "1000",10,&x,xxstring)) < 0)
- return(y);
- z = setnum(&sexpmaxdep,x,y,-1);
- if (z < 0)
- return(z);
- if (sxresult) { /* Free old stack if allocated */
- for (i = 0; i < xx; i++)
- if (sxresult[i]) free(sxresult[i]);
- free((char *)sxresult);
- if (sxrlen) free((char *)sxrlen);
- sxresult = NULL;
- sxrlen = NULL;
- }
- break;
- }
- case 2:
- return(seton(&sexptrunc));
- }
- return(success = 1);
- }
-#endif /* NOSEXPL */
-#endif /* NOSPL */
-
-#ifdef NEWFTP
- case XYGPR: {
- extern struct keytab gprtab[];
- extern int ftpget;
- if ((x = cmkey(gprtab,3,"","kermit", xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ftpget = x;
- return(success = 1);
- }
-#endif /* NEWFTP */
-
-#ifdef ANYSSH
- case XYSSH:
- return(dosetssh());
-#endif /* ANYSHH */
-
-#ifdef SFTP_BUILTIN
- case XYSFTP:
- return(dosetsftp());
-#endif /* SFTP_BUILTIN */
-
-#ifdef LOCUS
- case XYLOCUS:
- if ((x = cmkey(locustab,nlocustab,"",
-#ifdef KUI
- "ask"
-#else
- "auto"
-#endif /* KUI */
- ,xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- if (x == 2 || x == 3) { /* AUTO or ASK */
- setautolocus(x - 1); /* Two forms of automatic locusing */
- /* setlocus(1,0); */ /* we're not changing the locus here */
- } else { /* LOCAL or REMOTE */
- setautolocus(0); /* No automatic Locus changing */
- setlocus(x,0); /* Set Locus as requested */
- }
- return(success = 1);
-#endif /* LOCUS */
-
-#ifdef KUI
- case XYGUI:
- return(setgui());
-#endif /* KUI */
-
-#ifndef NOFRILLS
-#ifndef NORENAME
- case XY_REN: /* SET RENAME */
- return(setrename());
-#endif /* NORENAME */
-#endif /* NOFRILLS */
-
-#ifndef NOPUSH
-#ifdef CK_REDIR
-#ifndef NOXFER
- case XYEXTRN: /* SET EXTERNAL-PROTOCOL */
- return(setextern());
-#endif /* NOXFER */
-#endif /* CK_REDIR */
-#endif /* NOPUSH */
-
-#ifndef NOSPL
- case XYVAREV: /* SET VARIABLE-EVALUATION */
- return(setvareval());
-#endif /* NOSPL */
-
- default:
- if ((x = cmcfm()) < 0) return(x);
- printf("Not implemented - %s\n",cmdbuf);
- return(success = 0);
- }
-}
-
-/*
- H U P O K -- Is Hangup OK?
-
- Issues a warning and gets OK from user depending on whether a connection
- seems to be open and what the SET EXIT WARNING setting is. Returns:
- 0 if not OK to hang up or exit (i.e. user said No);
- nonzero if OK.
- Argument x is used to differentiate the EXIT command from SET LINE / HOST.
-*/
-int
-hupok(x) int x; { /* Returns 1 if OK, 0 if not OK */
- int y, z = 1;
- extern int exithangup;
-#ifdef VMS
- extern int batch;
-
- if (batch) /* No warnings in batch */
- return(1);
-#else
-#ifdef UNIX
- if (backgrd) /* No warnings in background */
- return(1);
-#endif /* UNIX */
-#endif /* VMS */
-
-#ifndef K95G
- debug(F101,"hupok local","",local);
-
- if (!local) /* No warnings in remote mode */
- return(1);
-#endif /* K95G */
-
- if (x == 0 && exithangup == 0) /* EXIT and EXIT HANGUP is OFF */
- return(1);
-
- debug(F101,"hupok x","",x);
- debug(F101,"hupok xitwarn","",xitwarn);
- debug(F101,"hupok network","",network);
- debug(F101,"hupok haveline","",haveline);
-
- if ((local && xitwarn) || /* Is a connection open? */
- (!x && xitwarn == 2)) { /* Or Always give warning on EXIT */
- int needwarn = 0;
- char warning[256];
-
- if (network) {
- if (ttchk() >= 0)
- needwarn = 1;
- /* A connection seems to be open but it can't possibly be */
- if (!haveline)
- needwarn = 0;
- if (needwarn) {
- if (strcmp(ttname,"*"))
- ckmakmsg(warning,256,
- " A network connection to ",ttname,
- " might still be active.\n",NULL);
- else
- ckstrncpy(warning,
- " An incoming network connection might still be active.\n",
- 256);
- }
- } else { /* Serial connection */
- if (carrier == CAR_OFF) /* SET CARRIER OFF */
- needwarn = 0; /* so we don't care about carrier. */
- else if ((y = ttgmdm()) >= 0) /* else, get modem signals */
- needwarn = (y & BM_DCD); /* Check for carrier */
- else /* If we can't get modem signals... */
- needwarn = (ttchk() >= 0);
- /* A connection seems to be open but it can't possibly be */
- if (!haveline || !exithangup)
- needwarn = 0;
- if (needwarn)
- ckmakmsg(warning,256,
- " A serial connection might still be active on ",
- ttname,".\n",NULL);
- }
-
-/* If a warning was issued, get user's permission to EXIT. */
-
- if (needwarn || (!x && xitwarn == 2
-#ifndef K95G
- && local
-#endif /* K95G */
- )) {
- if ( !needwarn )
- ckstrncpy(warning, "No active connections", 256);
-
-#ifdef COMMENT
- printf("%s",warning);
- z = getyesno(x ? "OK to close? " : "OK to exit? ",0);
- debug(F101,"hupok getyesno","",z);
- if (z < -3) z = 0;
-#else
- z = uq_ok(warning,
- x ? "OK to close? " : "OK to exit? ",
- 3,
- NULL,
- 0
- );
- debug(F101,"hupok uq_ok","",z);
- if (z < 0) z = 0;
-#endif /* COMMENT */
- }
- }
- return(z);
-}
-
-#ifndef NOSHOW
-VOID
-shoctl() { /* SHOW CONTROL-PREFIXING */
-#ifdef CK_SPEED
- int i;
-#ifdef OS2
- int zero;
-#endif /* OS2 */
- printf(
-"\ncontrol quote = %d, applied to (0 = unprefixed, 1 = prefixed):\n\n",
- myctlq);
-#ifdef OS2
-#ifndef UNPREFIXZERO
- zero = ctlp[0];
- if (protocol == PROTO_K) /* Zero can't be unprefixed */
- ctlp[0] = 1; /* for Kermit */
-#endif /* UNPREFIXZERO */
-#endif /* OS2 */
- for (i = 0; i < 16; i++) {
- printf(" %3d: %d %3d: %d ",i,ctlp[i], i+16, ctlp[i+16]);
- if (i == 15)
- printf(" 127: %d",ctlp[127]);
- else
- printf(" ");
- printf(" %3d: %d %3d: %d ",i+128,ctlp[i+128], i+144, ctlp[i+144]);
- if (i == 15) printf(" 255: %d",ctlp[255]);
- printf("\n");
- }
- printf("\n");
-#ifndef UNPREFIXZERO
-#ifdef OS2
- ctlp[0] = zero;
-#endif /* OS2 */
-#endif /* UNPREFIXZERO */
-
-#endif /* CK_SPEED */
-}
-
-#ifndef NOXFER
-VOID
-shodbl() { /* SHOW DOUBLE/IGNORE */
-#ifdef CKXXCHAR
- int i, n = 0;
- printf("\nSET SEND DOUBLE characters:\n");
- for (i = 0; i < 255; i++) {
- if (dblt[i] & 2) {
- n++;
- printf(" %d", i);
- }
- }
- if (n == 0)
- printf(" (none)");
- n = 0;
- printf("\nSET RECEIVE IGNORE characters:\n");
- for (i = 0; i < 255; i++) {
- if (dblt[i] & 1) {
- n++;
- printf(" %d", i);
- }
- }
- if (n == 0)
- printf(" (none)");
- printf("\n\n");
-#endif /* CKXXCHAR */
-}
-#endif /* NOXFER */
-#endif /* NOSHOW */
-
-#ifndef NOPUSH
-#ifdef CK_REXX
-/*
- Rexx command. Note, this is not OS/2-specific, because Rexx also runs
- on other systems where C-Kermit also runs, like the Amiga.
-*/
-#define REXBUFL 100 /* Change this if neccessary */
-char rexxbuf[REXBUFL] = { '\0' }; /* Rexx's return value (string) */
-
-int
-dorexx() {
- int x, y;
- char *rexxcmd;
-
- if ((x = cmtxt("Rexx command","",&rexxcmd,xxstring)) < 0)
- return(x);
-
-#ifdef IKSD
- if (inserver) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- /* Don't let this be set remotely */
- if (apcactive == APC_LOCAL ||
- apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
- return(success = 0);
-#endif /* CK_APC */
-
- ckstrncpy(line,rexxcmd,LINBUFSIZ);
- rexxcmd = line;
-#ifdef OS2
- return(os2rexx(rexxcmd,rexxbuf,REXBUFL));
-#else /* !OS2 */
- printf("Sorry, nothing happens.\n");
- return(success = 0);
-#endif /* OS2 */
-}
-#endif /* CK_REXX */
-#endif /* NOPUSH */
-#else /* NOICP */
-VOID
-dologend() {
- /* Dummy write record to connection log */
-}
-#endif /* NOICP */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus4.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuus4.c
deleted file mode 100644
index 946603a..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus4.c
+++ /dev/null
@@ -1,15087 +0,0 @@
-#include "ckcsym.h"
-
-/* C K U U S 4 -- "User Interface" for C-Kermit, part 4 */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- File ckuus4.c -- Functions moved from other ckuus*.c modules to even
- out their sizes.
-*/
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckcnet.h" /* Network symbols */
-#include "ckuusr.h"
-#include "ckuver.h"
-#include "ckcxla.h" /* Character sets */
-
-#ifdef CK_AUTHENTICATION
-#include "ckuath.h"
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-
-#ifdef VMS
-#include <errno.h> /* For \v(errno) */
-extern char * ckvmserrstr(unsigned long);
-#ifndef OLD_VMS
-#include <lib$routines.h> /* Not for VAX C 2.4 */
-#else
-#include <libdef.h>
-#endif /* OLD_VMS */
-_PROTOTYP(int vmsttyfd, (void) );
-#endif /* VMS */
-
-#ifdef OS2
-#ifndef NT
-#define INCL_NOPM
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#else
-#include <windows.h>
-#include <tapi.h>
-#include "ckntap.h"
-#define APIRET ULONG
-#endif /* NT */
-#include "ckocon.h"
-#include "ckoetc.h"
-int StartedFromDialer = 0;
-HWND hwndDialer = 0;
-LONG KermitDialerID = 0;
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) conoc(x)
-#ifdef CK_PID
-#include <process.h>
-#endif /* CK_PID */
-#endif /* OS2 */
-
-#ifdef KUI
-extern struct keytab * term_font;
-extern int ntermfont, tt_font, tt_font_size;
-#endif /* KUI */
-
-extern xx_strp xxstring;
-
-#ifdef DEC_TCPIP
-#include <descrip>
-#include <dvidef>
-#include <dcdef>
-#endif /* DEC_TCPIP */
-
-#ifdef FNFLOAT
-#include <math.h> /* Floating-point functions */
-#endif /* FNFLOAT */
-
-extern int quiet, network, xitsta, escape, nopush, xferstat,
- exitonclose, tn_exit, ttnproto, autodl, flow, byteorder, what, lastxfer;
-
-extern int filepeek, nscanfile, makestrlen;
-extern char * k_info_dir;
-
-#ifndef MAC
-#ifndef AMIGA
-extern int ttyfd;
-#endif /* MAC */
-#endif /* AMIGA */
-
-#ifdef TNCODE
-extern int tn_nlm, tn_b_nlm, tn_b_xfer, tn_sb_bug;
-extern int tn_rem_echo;
-extern int tn_b_meu, tn_b_ume, tn_auth_krb5_des_bug;
-#endif /* TNCODE */
-
-static char * lastkwval = NULL;
-
-char * xferfile = NULL;
-int xferlog = 0;
-
-extern int local, xargc, stayflg, rcflag, bgset, backgrd, cfilef,
- inserver, srvcdmsg, success;
-
-#ifdef VMS
-extern int batch;
-#endif /* VMS */
-
-extern char cmdfil[], *versio, *ckxsys, **xargv;
-#ifdef DEBUG
-extern char debfil[]; /* Debug log file name */
-extern int debtim;
-#endif /* DEBUG */
-
-extern int noinit;
-
-static char ndatbuf[10];
-
-char *months[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-char *
-zzndate() { /* Returns today's date as yyyymmdd */
- char * p = NULL;
- int x;
-
-/* WARNING - This will fail if asctime() returns non-English month names */
-
- ztime(&p); /* Get "asctime" string */
- if (p == NULL || *p == NUL) return("");
- for (x = 20; x < 24; x++) /* yyyy */
- ndatbuf[x - 20] = p[x];
- ndatbuf[6] = (char) ((p[8] == ' ') ? '0' : p[8]);
- ndatbuf[7] = p[9]; /* dd */
- for (x = 0; x < 12; x++) /* mm */
- if (!strncmp(p+4,months[x],3)) break;
- if (x == 12) {
- ndatbuf[4] = ndatbuf[5] = '?';
- } else {
- x++;
- ndatbuf[4] = (char) ((x < 10) ? '0' : '1');
- ndatbuf[5] = (char) ((x % 10) + 48);
- }
- ndatbuf[8] = NUL;
- debug(F110,"zzndate return",ndatbuf,0);
- return((char *)ndatbuf);
-}
-
-#ifdef DCMDBUF
-extern struct cmdptr *cmdstk;
-extern char *line, *tmpbuf;
-#else
-extern struct cmdptr cmdstk[];
-extern char line[], tmpbuf[];
-#endif /* DCMDBUF */
-
-#ifdef OS2
-extern char exedir[];
-#else
-extern char * exedir;
-#endif /* OS2 */
-
-extern int nettype;
-
-#ifndef NOICP /* Most of this file... */
-#ifdef CKLOGDIAL
-extern char diafil[];
-#endif /* CKLOGDIAL */
-
-#ifndef AMIGA
-#ifndef MAC
-#include <signal.h>
-#endif /* MAC */
-#endif /* AMIGA */
-
-#ifdef SV68 /* July 2006 believe it or not */
-#ifndef SEEK_CUR
-#include <unistd.h>
-#endif /* SEEK_CUR */
-#endif /* SV68 */
-
-#ifdef SCO32 /* June 2011 believe it or not... */
-#ifdef XENIX
-#ifndef SEEK_CUR
-#include <unistd.h>
-#endif /* SEEK_CUR */
-#endif /* XENIX */
-#endif /* SCO32 */
-
-#ifdef STRATUS /* Stratus Computer, Inc. VOS */
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) conoc(x)
-#ifdef getchar
-#undef getchar
-#endif /* getchar */
-#define getchar(x) coninc(0)
-#endif /* STRATUS */
-
-
-#ifdef ANYX25
-extern int revcall, closgr, cudata;
-int x25ver;
-extern char udata[];
-#ifndef IBMX25
-extern int npadx3;
-extern CHAR padparms[];
-extern struct keytab padx3tab[];
-#endif /* !IBMX25 */
-#ifdef IBMX25
-/* global variables only available for IBM X.25 - possibly interesting for
- * other implementations
- */
-extern x25addr_t local_nua;
-extern x25addr_t remote_nua;
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifdef NETCONN
-#ifndef NODIAL
-extern int nnetdir;
-extern char *netdir[];
-#endif /* NODIAL */
-extern char ipaddr[];
-
-#ifdef CK_NETBIOS
-extern unsigned short netbiosAvail;
-extern unsigned long NetbeuiAPI;
-extern unsigned char NetBiosName[];
-extern unsigned char NetBiosAdapter;
-extern unsigned char NetBiosLSN;
-#endif /* CK_NETBIOS */
-
-#ifdef TCPSOCKET
-extern char myipaddr[];
-extern int tcp_rdns;
-#ifdef CK_DNS_SRV
-extern int tcp_dns_srv;
-#endif /* CK_DNS_SRV */
-extern char * tcp_address;
-#ifndef NOHTTP
-extern char * tcp_http_proxy;
-#endif /* NOHTTP */
-#ifdef NT
-#ifdef CK_SOCKS
-extern char * tcp_socks_svr;
-#ifdef CK_SOCKS_NS
-extern char * tcp_socks_ns;
-#endif /* CK_SOCKS_NS */
-#endif /* CK_SOCKS */
-#endif /* NT */
-
-#ifndef NOTCPOPTS
-#ifdef SOL_SOCKET
-#ifdef SO_LINGER
-extern int tcp_linger;
-extern int tcp_linger_tmo;
-#endif /* SO_LINGER */
-#ifdef SO_DONTROUTE
-extern int tcp_dontroute;
-#endif /* SO_DONTROUTE */
-#ifdef TCP_NODELAY
-extern int tcp_nodelay;
-#endif /* TCP_NODELAY */
-#ifdef SO_SNDBUF
-extern int tcp_sendbuf;
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
-extern int tcp_recvbuf;
-#endif /* SO_RCVBUF */
-#ifdef SO_KEEPALIVE
-extern int tcp_keepalive;
-#endif /* SO_KEEPALIVE */
-#endif /* SOL_SOCKET */
-#endif /* NOTCPOPTS */
-#endif /* TCPSOCKET */
-#endif /* NETCONN */
-
-extern char * floname[];
-
-#ifndef NOSPL
-extern int vareval; /* Variable evaluation method */
-extern int fndiags; /* Function diagnostics on/off */
-extern int divbyzero;
-int itsapattern = 0;
-int isinbuflen = 0;
-int isjoin = 0;
-#ifdef CK_APC
-extern int apcactive; /* Nonzero = APC command was rec'd */
-extern int apcstatus; /* Are APC commands being processed? */
-#ifdef DCMDBUF
-extern char *apcbuf; /* APC command buffer */
-#else
-extern char apcbuf[];
-#endif /* DCMDBUF */
-#endif /* CK_APC */
-
-extern char evalbuf[]; /* EVALUATE result */
-extern char uidbuf[], pwbuf[], prmbuf[];
-_PROTOTYP( static char * fneval, (char *, char * [], int, char * ) );
-_PROTOTYP( static VOID myflsh, (void) );
-_PROTOTYP( static char * getip, (char *) );
-_PROTOTYP( int delta2sec, (char *, long *) );
-
-#ifdef NEWFTP
-_PROTOTYP( char * ftp_cpl_mode, (void) );
-_PROTOTYP( char * ftp_dpl_mode, (void) );
-_PROTOTYP( char * ftp_authtype, (void) );
-#endif /* NEWFTP */
-
-#ifndef NOHTTP
-_PROTOTYP( char * http_host, (void) );
-_PROTOTYP( int http_isconnected, (void) );
-_PROTOTYP( char * http_security, (void) );
-#endif /* NOHTTP */
-
-#ifndef NOSEXP
-_PROTOTYP( char * dosexp, (char *) );
-int fsexpflag = 0;
-#endif /* NOSEXP */
-
-static char hexdigits[16] = {
- '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
-};
-extern char * tempdir;
-
-#ifdef CK_REXX
-extern char rexxbuf[];
-#endif /* CK_REXX */
-
-extern int tfline[];
-
-char *wkdays[] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-};
-#endif /* NOSPL */
-
-#ifdef OS2
-extern char startupdir[], inidir[];
-#else
-#ifdef VMSORUNIX
-extern char startupdir[];
-#endif /* VMSORUNIX */
-#endif /* OS2 */
-
-#ifdef OS2
-_PROTOTYP (int os2getcp, (void) );
-#ifdef TCPSOCKET
-extern char tcpname[];
-#endif /* TCPSOCKET */
-extern int tcp_avail;
-#ifdef DECNET
-extern int dnet_avail;
-#endif /* DECNET */
-#ifdef SUPERLAT
-extern int slat_avail;
-#endif /* SUPERLAT */
-
-#ifndef NOTERM
-extern int tt_type, max_tt;
-extern struct tt_info_rec tt_info[];
-#endif /* NOTERM */
-extern int tt_rows[], tt_cols[];
-#else /* OS2 */
-extern int tt_rows, tt_cols;
-#endif /* OS2 */
-
-#ifdef CK_TAPI
-extern int tttapi;
-extern int tapipass;
-extern struct keytab * tapilinetab;
-extern struct keytab * _tapilinetab;
-extern int ntapiline;
-#endif /* CK_TAPI */
-
-extern struct keytab colxtab[];
-extern int ncolx;
-
-extern char ttname[], *zinptr, *kermrc;
-extern char inidir[];
-
-extern int activecmd, remonly, cmd_rows, cmd_cols, parity, seslog,
- sessft, sosi, hwparity, tsecs, xargs, zincnt, tlevel, insilence, cmdmsk,
- timint, timef, inbufsize, dialog, binary, carrier, cdtimo, cmask, duplex,
- fmask, inecho, nmac, turnch, turn, kbchar;
-
-#ifndef NOXFER
-extern CHAR eol, mypadc, mystch, padch, seol, stchr, * epktmsg, feol;
-extern char *cksysid;
-extern struct ck_p ptab[];
-extern int
- protocol, prefixing, xfrbel, xfrcan, xfrint, xfrchr, xfrnum, pktpaus,
- lscapr, lscapu, xfermode, dest, slostart, maxrps, maxsps, maxtry, mypadn,
- npad, pkttim, bigrbsiz, bigsbsiz, keep, atcapr, autopar, bctr, bctu,
- crunched, ckdelay, ebq, ebqflg, pktlog, retrans, rpackets, rptflg, rptq,
- rtimo, spackets, spsiz, spsizf, spsizr, timeouts, fncact, fncnv, urpsiz,
- wmax, wslotn, wslotr, fdispla, spmax, fnrpath, fnspath, crc16;
-#endif /* NOXFER */
-
-#ifdef OS2
-extern int zxpn;
-extern int viewonly;
-#endif /* OS2 */
-
-#ifndef NOXFER
-#ifdef GFTIMER
-extern CKFLOAT fptsecs, fpxfsecs;
-#endif /* GFTIMER */
-extern long xfsecs, tfcps;
-
-#ifdef CK_TMPDIR
-extern char *dldir;
-#endif /* CK_TMPDIR */
-#endif /* NOXFER */
-
-#ifdef RECURSIVE
-extern int recursive;
-#endif /* RECURSIVE */
-
-#ifdef VMS
-extern int frecl;
-#endif /* VMS */
-
-extern CK_OFF_T ffc, tfc, tlci, tlco;
-extern long filcnt, rptn, speed, ccu, ccp, vernum, xvernum;
-
-#ifndef NOSPL
-extern char fspec[], myhost[];
-#endif /* NOSPL */
-
-extern char *tfnam[]; /* Command file names */
-
-extern char pktfil[], /* Packet log file name */
-#ifdef TLOG
- trafil[], /* Transaction log file name */
-#endif /* TLOG */
- sesfil[]; /* Session log file name */
-
-#ifndef NOXMIT /* TRANSMIT command variables */
-extern char xmitbuf[];
-extern int xmitf, xmitl, xmitx, xmits, xmitw, xmitt;
-#endif /* NOXMIT */
-
-extern int cmdlvl;
-
-#ifndef NOSPL
-/* Script programming language items */
-extern char **a_ptr[]; /* Arrays */
-extern int a_dim[];
-static char * inpmatch = NULL;
-#ifdef CKFLOAT
-char * inpscale = NULL;
-#endif /* CKFLOAT */
-extern char * inpbuf, inchar[]; /* Buffers for INPUT and REINPUT */
-extern char *inpbp; /* And pointer to same */
-static char *r3 = (char *)0;
-extern int incount; /* INPUT character count */
-extern int m_found; /* MINPUT result */
-extern int maclvl; /* Macro invocation level */
-extern struct mtab *mactab; /* Macro table */
-extern char *mrval[];
-extern int macargc[], topargc;
-
-#ifdef COMMENT
-extern char *m_line[];
-extern char *topline;
-#endif /* COMMENT */
-
-extern char *m_arg[MACLEVEL][10]; /* You have to put in the dimensions */
-extern char *g_var[GVARS]; /* for external 2-dimensional arrays. */
-#ifdef DCMDBUF
-extern int *count, *inpcas;
-#else
-extern int count[], inpcas[];
-#endif /* DCMDBUF */
-#endif /* NOSPL */
-
-#ifdef UNIX
-extern int haslock; /* For UUCP locks */
-extern char flfnam[];
-#ifndef USETTYLOCK
-extern char lock2[];
-#endif /* USETTYLOCK */
-#endif /* UNIX */
-
-#ifdef OS2ORUNIX
-extern int maxnam, maxpath; /* Longest name, path length */
-#endif /* OS2ORUNIX */
-
-extern int mdmtyp, mdmsav;
-
-#ifndef NODIAL
-/* DIAL-related variables */
-extern char modemmsg[];
-extern MDMINF *modemp[]; /* Pointers to modem info structs */
-extern int nmdm, dialhng, dialtmo, dialksp, dialdpy, dialsrt, dialsta;
-extern int dialrtr, dialint, dialrstr, dialcon, dialcq, dialfld;
-extern int mdmspd, dialec, dialdc, dialmth, dialmauto, dialesc;
-extern char *dialnum, *dialini, *dialdir[], *dialcmd, *dialnpr,
- *dialdcon, *dialdcoff, *dialecon, *dialecoff, *dialhcmd, *diallac,
- *dialhwfc, *dialswfc, *dialnofc, *dialpulse, *dialtone, *dialname,
- *dialaaon, *dialaaoff, *dialmac;
-extern char *diallcc, *dialixp, *dialixs, *dialldp, *diallds,
- *dialpxi, *dialpxo, *dialsfx, *dialtfp;
-extern char *diallcp, *diallcs;
-extern int ntollfree, ndialpxx, nlocalac;
-extern char *dialtfc[], *diallcac[], *dialpxx[], *matchpxx;
-extern int ndialpucc, ndialtocc;
-extern char *dialtocc[], *dialpucc[];
-extern int ndialdir, dialcnf, dialcvt, dialidt, dialpace;
-extern long dialmax, dialcapas;
-
-extern struct keytab mdmtab[];
-
-#ifdef BIGBUFOK
-#define ARGBUFSIZ 8191
-#else
-#define ARGBUFSIZ 1023
-#endif /* BIGBUFOK */
-
-#ifdef BIGBUFOK
-extern char * dialmsg[];
-#endif /* BIGBUFOK */
-
-#endif /* NODIAL */
-
-#ifndef NOCSETS
-/* Translation stuff */
-extern int nfilc;
-extern struct keytab fcstab[];
-extern int fcharset, tcharset, tslevel, language, nlng, tcsr, tcsl;
-extern int dcset7, dcset8;
-extern struct keytab lngtab[];
-extern struct csinfo fcsinfo[], tcsinfo[];
-extern struct langinfo langs[];
-#ifdef CK_ANSIC
-extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* Character set */
-extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* translation functions */
-#else
-extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(); /* Character set */
-extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(); /* translation functions. */
-#endif /* CK_ANSIC */
-#ifdef UNICODE
- extern int ucsbom, ucsorder;
-#endif /* UNICODE */
-#endif /* NOCSETS */
-
-#ifndef NOSPL
-/* Built-in variable names, maximum length VNAML (20 characters) */
-
-struct keytab vartab[] = {
- { "_line", VN_TFLN, CM_INV}, /* 192 */
-#ifdef OS2
- { "_regname", VN_REGN, CM_INV}, /* 1.1.12 */
- { "_regorg", VN_REGO, CM_INV}, /* 1.1.12 */
- { "_regnum", VN_REGS, CM_INV}, /* 1.1.12 */
-#endif /* OS2 */
- { "apcactive", VN_APC, CM_INV}, /* 192 */
-#ifdef NT
- { "appdata", VN_APPDATA, 0}, /* 201 */
-#endif /* NT */
- { "argc", VN_ARGC, 0},
- { "args", VN_ARGS, 0},
- { "authname", VN_AUTHN, 0}, /* 196 */
- { "authstate", VN_AUTHS, 0}, /* 195 */
- { "authtype", VN_AUTHT, 0}, /* 195 */
- { "bits", VN_BITS, 0}, /* 212 */
- { "blockcheck",VN_BLK, 0}, /* 195 */
-#ifdef BROWSER
- { "browser", VN_BROWSR,0}, /* 193 */
- { "browsopts", VN_BROPT, 0}, /* 193 */
- { "browsurl", VN_URL, 0}, /* 193 */
- { "buildid", VN_BUILD, 0}, /* 199 */
-#endif /* BROWSER */
- { "byteorder", VN_BYTE, 0}, /* 195 */
-#ifndef NOCSETS
- { "charset", VN_CSET, 0}, /* 192 */
-#endif /* NOCSETS */
- { "cmdbufsize",VN_CMDBL, 0}, /* 195 */
- { "cmdfile", VN_CMDF, 0},
- { "cmdlevel", VN_CMDL, 0},
- { "cmdsource", VN_CMDS, 0},
- { "cols", VN_COLS, 0}, /* 190 */
-#ifdef NT
- { "common", VN_COMMON, 0}, /* 201 */
-#endif /* NT */
- { "connection",VN_CONN, 0}, /* 190 */
- { "count", VN_COUN, 0},
-#ifndef NOXFER
- { "cps", VN_CPS, 0}, /* 190 */
-#endif /* NOXFER */
- { "cpu", VN_CPU, 0},
-#ifndef NOXFER
- { "crc16", VN_CRC16, 0}, /* 192 */
- { "ctty", VN_TTYNAM,0}, /* 196 */
-#endif /* NOXFER */
-#ifndef NOLOGDIAL
-#ifndef NOLOCAL
- { "cx_time", VN_CXTIME,0}, /* 195 */
- { "cx_status", VN_CX_STA,0}, /* 199 */
-#endif /* NOLOCAL */
-#endif /* NOLOGDIAL */
-#ifndef NODIAL
- { "d$ac", VN_D_AC, 0}, /* 192 */
- { "d$cc", VN_D_CC, 0}, /* 192 */
- { "d$ip", VN_D_IP, 0}, /* 192 */
- { "d$lc", VN_D_LCP, 0}, /* 193 */
- { "d$lcp", VN_D_LCP, CM_INV}, /* 193 */
- { "d$lp", VN_D_LP, 0}, /* 192 */
- { "d$px", VN_D_PXX, 0}, /* 195 */
- { "d$pxx", VN_D_PXX, CM_INV}, /* 195 */
-#endif /* NODIAL */
- { "date", VN_DATE, 0},
- { "day", VN_DAY, 0},
-#ifdef NT
- { "desktop", VN_DESKTOP, 0}, /* 201 */
-#endif /* NT */
-#ifndef NODIAL
- { "dialcount", VN_DRTR, 0}, /* 195 */
- { "dialmessage",VN_DMSG, 0}, /* 212 */
- { "dialnumber",VN_DNUM, 0}, /* 192 */
- { "dialresult",VN_MDMSG, 0}, /* 192 */
- { "dialstatus",VN_DIAL, 0}, /* 190 */
- { "dialsuffix",VN_PDSFX, 0}, /* 193 */
- { "dialtype", VN_DTYPE, 0}, /* 193 */
-#endif /* NODIAL */
- { "directory", VN_DIRE, 0},
-#ifndef NODIAL
- { "dm_hf", VN_DM_HF, 0}, /* 199 */
- { "dm_lp", VN_DM_LP, 0}, /* 195 */
- { "dm_sp", VN_DM_SP, 0}, /* 195 */
- { "dm_pd", VN_DM_PD, 0}, /* 195 */
- { "dm_td", VN_DM_TD, 0}, /* 195 */
- { "dm_wa", VN_DM_WA, 0}, /* 195 */
- { "dm_wb", VN_DM_WB, 0}, /* 199 */
- { "dm_wd", VN_DM_WD, 0}, /* 195 */
- { "dm_rc", VN_DM_RC, 0}, /* 195 */
-#endif /* NODIAL */
-#ifndef NOXFER
- { "download", VN_DLDIR, 0}, /* 192 */
-#endif /* NOXFER */
- { "editor", VN_EDITOR,0},
- { "editfile", VN_EDFILE,0},
- { "editopts", VN_EDOPT, 0},
- { "errno", VN_ERRNO, 0}, /* 192 */
- { "errstring", VN_ERSTR, 0}, /* 192 */
- { "escape", VN_ESC, 0}, /* 193 */
- { "evaluate", VN_EVAL, 0}, /* 190 */
-#ifdef OS2ORUNIX
- { "exedir", VN_EXEDIR,0}, /* 192 */
-#endif /* OS2ORUNIX */
- { "exitstatus",VN_EXIT, 0},
-#ifdef CKCHANNELIO
- { "f_count", VN_FCOU, 0}, /* 195 */
- { "f_error", VN_FERR, 0}, /* 195 */
- { "f_max", VN_FMAX, 0}, /* 195 */
- { "fileerror", VN_FERR, CM_INV}, /* 195 */
- { "filemax", VN_FERR, CM_INV}, /* 195 */
-#endif /* CKCHANNELIO */
- { "filename", VN_FNAM, 0}, /* 193 */
- { "filenumber",VN_FNUM, 0}, /* 193 */
- { "filespec", VN_FILE, 0},
- { "fsize", VN_FFC, 0}, /* 190 */
-#ifdef GFTIMER
- { "ftime", VN_FTIME, 0}, /* 199 */
-#else
- { "ftime", VN_NTIM, CM_INV},
-#endif /* GFTIMER */
-#ifndef NOFTP
-#ifndef SYSFTP
- { "ftp_code", VN_FTP_C, 0}, /* 199 */
- { "ftp_cpl", VN_FTP_B, 0}, /* 199 */
- { "ftp_connected", VN_FTP_X, 0}, /* 199 */
- { "ftp_dpl", VN_FTP_D, 0}, /* 199 */
- { "ftp_getputremote", VN_FTP_G, 0}, /* 199 */
- { "ftp_host", VN_FTP_H, 0}, /* 199 */
- { "ftp_loggedin", VN_FTP_L, 0}, /* 199 */
- { "ftp_message", VN_FTP_M, 0}, /* 199 */
- { "ftp_msg", VN_FTP_M, CM_INV}, /* 199 */
- { "ftp_security", VN_FTP_Z, 0}, /* 199 */
- { "ftp_server", VN_FTP_S, 0}, /* 199 */
-#endif /* SYSFTP */
-#endif /* NOFTP */
- { "ftype", VN_MODE, 0}, /* 190 */
-#ifdef KUI
- { "gui_fontname", VN_GUI_FNM, 0}, /* 205 */
- { "gui_fontsize", VN_GUI_FSZ, 0}, /* 205 */
- { "gui_runmode", VN_GUI_RUN, 0}, /* 205 */
- { "gui_xpos", VN_GUI_XP, 0}, /* 205 */
- { "gui_xres", VN_GUI_XR, 0}, /* 205 */
- { "gui_ypos", VN_GUI_YP, 0}, /* 205 */
- { "gui_yres", VN_GUI_YR, 0}, /* 205 */
-#endif /* KUI */
- { "herald", VN_HERALD, 0},
- { "home", VN_HOME, 0},
- { "host", VN_HOST, 0},
- { "hour", VN_HOUR, 0}, /* 200 */
-#ifndef NOHTTP
- { "http_code", VN_HTTP_C, 0}, /* 199 */
- { "http_connected", VN_HTTP_N, 0}, /* 199 */
- { "http_host", VN_HTTP_H, 0}, /* 199 */
- { "http_message", VN_HTTP_M, 0}, /* 199 */
- { "http_security", VN_HTTP_S, 0}, /* 199 */
-#endif /* NOHTTP */
- { "hwparity", VN_HWPAR, 0}, /* 195 */
- { "input", VN_IBUF, 0},
- { "inchar", VN_ICHR, 0},
- { "incount", VN_ICNT, 0},
- { "inidir", VN_INI, 0}, /* 192 */
- { "inmatch", VN_MATCH, 0}, /* 196 */
- { "inmessage", VN_INPMSG,0}, /* 212 */
- { "inscale", VN_ISCALE,0}, /* 210 */
- { "instatus", VN_ISTAT, 0}, /* 192 */
- { "intime", VN_INTIME,0}, /* 193 */
- { "inwait", VN_INTMO, 0}, /* 195 */
- { "ip", VN_IPADDR, CM_ABR|CM_INV},
- { "ipaddress", VN_IPADDR,0}, /* 192 */
- { "iprompt", VN_PROMPT,0}, /* 199 */
- { "kbchar", VN_KBCHAR,0}, /* 196 */
-#ifndef NOLOCAL
-#ifdef OS2
- { "keyboard", VN_KEYB, 0},
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef CK_KERBEROS
- { "krb4errmsg", VN_K4EMSG,0},
- { "krb4errno", VN_K4ENO, 0},
- { "krb4principal", VN_K4PRN, 0},
- { "krb4realm", VN_K4RLM, 0},
- { "krb4service", VN_K4SRV, 0},
- { "krb5cc", VN_K5CC, 0},
- { "krb5errmsg", VN_K5EMSG,0},
- { "krb5errno", VN_K5ENO, 0},
- { "krb5principal", VN_K5PRN, 0},
- { "krb5realm", VN_K5RLM, 0},
- { "krb5service", VN_K5SRV, 0},
-#endif /* CK_KERBEROS */
- { "lastcommand", VN_PREVCMD, 0}, /* 299 */
-#ifndef NOLASTFILE
- { "lastfilespec", VN_LASTFIL, 0}, /* 212 */
-#endif /* NOLASTFILE */
- { "lastkeywordvalue", VN_LASTKWV, 0}, /* 212 */
- { "lastkwvalue", VN_LASTKWV, CM_ABR|CM_INV}, /* 212 */
- { "line", VN_LINE, 0},
- { "local", VN_LCL, 0},
-#ifdef UNIX
- { "lockdir", VN_LCKDIR,0}, /* 195 */
- { "lockpid", VN_LCKPID,0}, /* 195 */
-#endif /* UNIX */
- { "log_connection", VN_LOG_CON, 0}, /* 206 */
- { "log_debug", VN_LOG_DEB, 0}, /* 206 */
- { "log_packet", VN_LOG_PKT, 0}, /* 206 */
- { "log_session", VN_LOG_SES, 0}, /* 206 */
- { "log_transaction", VN_LOG_TRA, 0},/* 206 */
- { "maclevel", VN_MACLVL,0}, /* 195 */
- { "macro", VN_MAC, 0},
-#ifdef FNFLOAT
- { "math_e", VN_MA_E, 0}, /* 195 */
- { "math_pi", VN_MA_PI, 0}, /* 195 */
- { "math_precision", VN_MA_PR, 0}, /* 195 */
-#endif /* FNFLOAT */
- { "minput", VN_MINP, 0}, /* 192 */
- { "model", VN_MODL, 0}, /* 193 */
- { "modem", VN_MDM, 0},
-#ifndef NOLOCAL
-#ifdef OS2
- { "mousecurx", VN_MOU_X, 0}, /* K95 1.1.14 */
- { "mousecury", VN_MOU_Y, 0}, /* K95 1.1.14 */
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifndef NODIAL
- { "m_aa_off", VN_M_AAX, 0}, /* all 192... */
- { "m_aa_on", VN_M_AAO, 0},
- { "m_dc_off", VN_M_DCX, 0},
- { "m_dc_on", VN_M_DCO, 0},
- { "m_dial", VN_M_DCM, 0},
- { "m_ec_off", VN_M_ECX, 0},
- { "m_ec_on", VN_M_ECO, 0},
- { "m_fc_hw", VN_M_HWF, 0},
- { "m_fc_no", VN_M_NFC, 0},
- { "m_fc_sw", VN_M_SWF, 0},
- { "m_hup", VN_M_HUP, 0},
- { "m_init", VN_M_INI, 0},
- { "m_name", VN_M_NAM, 0}, /* 195 */
- { "m_pulse", VN_M_PDM, 0},
- { "m_sig_cd", VN_MS_CD, 0}, /* 195 */
- { "m_sig_cts", VN_MS_CTS,0}, /* 195 */
- { "m_sig_dsr", VN_MS_DSR,0}, /* 195 */
- { "m_sig_dtr", VN_MS_DTR,0}, /* 195 */
- { "m_sig_ri", VN_MS_RI, 0}, /* 195 */
- { "m_sig_rts", VN_MS_RTS,0}, /* 195 */
- { "m_tone", VN_M_TDM, 0},
-#endif /* NODIAL */
- { "name", VN_NAME, 0},
- { "ndate", VN_NDAT, 0},
- { "nday", VN_NDAY, 0},
- { "newline", VN_NEWL, 0},
- { "ntime", VN_NTIM, 0},
- { "osname", VN_OSNAM, 0}, /* 193 */
- { "osrelease", VN_OSREL, 0}, /* 193 */
- { "osversion", VN_OSVER, 0}, /* 193 */
-#ifndef NOXFER
- { "packetlen", VN_RPSIZ, 0}, /* 192 */
-#endif /* NOXFER */
- { "parity", VN_PRTY, 0}, /* 190 */
- { "password", VN_PWD, CM_INV}, /* 192 */
-#ifdef NT
- { "personal", VN_PERSONAL, 0}, /* 201 */
-#endif /* NT */
-#ifdef PEXITSTAT
- { "pexitstat", VN_PEXIT, 0}, /* 193 */
-#endif /* PEXITSTAT */
-#ifdef CK_PID
- { "pid", VN_PID, 0}, /* 193 */
-#endif /* CK_PID */
- { "platform", VN_SYSV, 0},
- { "printer", VN_PRINT, 0}, /* 193 */
- { "program", VN_PROG, 0},
- { "prompt", VN_PRM, CM_INV}, /* 192 */
-#ifndef NOXFER
- { "protocol", VN_PROTO, 0}, /* 192 */
- { "p_8bit", VN_P_8BIT,0}, /* 193 */
- { "p_ctl", VN_P_CTL, 0}, /* 193 */
- { "p_rpt", VN_P_RPT, 0}, /* 193 */
- { "query", VN_QUE, 0}, /* 190 */
-#endif /* NOXFER */
- { "remoteip", VN_HOSTIP,0}, /* 212 */
- { "return", VN_RET, 0},
-#ifdef CK_REXX
- { "rexx", VN_REXX, 0}, /* 190 */
-#endif /* CK_REXX */
-#ifdef TN_COMPORT
- { "rfc2217_signature", VN_TNC_SIG, 0}, /* 201 */
- { "rfc2717_signature", VN_TNC_SIG, CM_INV}, /* 202 */
-#endif /* TN_COMPORT */
- { "rows", VN_ROWS, 0}, /* 190 */
-#ifndef NOSEXP
- { "sdepth", VN_LSEXP,0}, /* 199 */
-#endif /* NOSEXP */
- { "secure", VN_SECURE, 0}, /* 199 */
-#ifndef NOLOCAL
-#ifdef OS2
- { "select", VN_SELCT, 0}, /* 192 */
-#endif /* OS2 */
-#endif /* NOLOCAL */
- { "sendlist", VN_SNDL, 0},
- { "serial", VN_SERIAL,0}, /* 195 */
- { "setlinemsg",VN_SLMSG, 0}, /* 195 */
-#ifndef NOSEXP
- { "sexpression",VN_SEXP, 0}, /* 199 */
-#endif /* NOSEXP */
- { "speed", VN_SPEE, 0},
-#ifdef OS2
- { "space", VN_SPA, 0},
- { "startup", VN_STAR, 0}, /* 190 */
-#else
-#ifdef UNIX
- { "startup", VN_STAR, 0}, /* 193 */
-#else
-#ifdef VMS
- { "startup", VN_STAR, 0}, /* 193 */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* OS2 */
- { "status", VN_SUCC, 0},
-#ifndef NOSEXP
- { "svalue", VN_VSEXP, 0}, /* 199 */
-#endif /* NOSEXP */
-#ifndef NOXFER
- { "sysid", VN_SYSI, 0},
-#endif /* NOXFER */
- { "system", VN_SYST, 0},
- { "terminal", VN_TTYP, 0},
-#ifdef OS2
-#ifndef NOKVERBS
- { "termkey", VN_TRMK, CM_INV}, /* 192 */
-#endif /* NOKVERBS */
-#endif /* OS2 */
- { "test", VN_TEST, 0}, /* 193 */
- { "textdir", VN_TXTDIR,0}, /* 195 */
-#ifndef NOXFER
- { "tfsize", VN_TFC, 0},
- { "tftime", VN_TFTIM, 0}, /* 195 */
-#endif /* NOXFER */
- { "time", VN_TIME, 0},
- { "timestamp", VN_NOW, 0}, /* 200 */
- { "tmpdir", VN_TEMP, 0}, /* 192 */
-#ifdef CK_TRIGGER
- { "trigger", VN_TRIG, 0}, /* 193 */
-#endif /* CK_TRIGGER */
-#ifdef CK_TTYFD
- { "ttyfd", VN_TTYF, 0},
-#endif /* CK_TTYFD */
- { "ty_ln", VN_TY_LN, 0}, /* 195 */
- { "ty_lc", VN_TY_LC, 0}, /* 195 */
- { "ty_lm", VN_TY_LM, 0}, /* 195 */
-#ifdef BROWSER
- { "url", VN_URL, CM_INV}, /* 193 */
-#endif /* BROWSER */
- { "userid", VN_UID, 0}, /* 192 */
- { "vareval", VN_VAREVAL, 0}, /* 212 */
- { "version", VN_VERS, 0},
-#ifndef NOXFER
- { "window", VN_WINDO, 0}, /* 192 */
-#endif /* NOXFER */
-#ifdef IBMX25
- { "x25local_nua", VN_X25LA, 0}, /* 193 */
- { "x25remote_nua", VN_X25RA, 0}, /* 193 */
-#endif /* IBMX25 */
-#ifdef CK_SSL
- { "x509_issuer", VN_X509_I, 0},
- { "x509_subject", VN_X509_S, 0},
-#endif /* CK_SSL */
-#ifndef NOXFER
- { "xferstatus",VN_XFSTAT,0}, /* 193 */
- { "xfermsg", VN_XFMSG, 0}, /* 193 */
- { "xfer_badpackets", VN_XF_BC, 0}, /* 195 */
- { "xfer_timeouts", VN_XF_TM, 0}, /* 195 */
- { "xfer_retransmits",VN_XF_RX, 0}, /* 195 */
-#endif /* NOXFER */
- { "xprogram", VN_XPROG, 0}, /* 193 */
- { "xversion", VN_XVNUM, 0} /* 192 */
-};
-int nvars = (sizeof(vartab) / sizeof(struct keytab));
-#endif /* NOSPL */
-
-#ifndef NOSPL
-struct keytab fnctab[] = { /* Function names */
-#ifdef OS2
- { ".oox", FN_OOX, CM_INV}, /* ... */
-#endif /* OS2 */
-
-#ifdef CKCHANNELIO
- { "_eof", FN_FEOF, 0},
- { "_errmsg", FN_FERMSG, 0},
- { "_getblock", FN_FGBLK, 0},
- { "_getchar", FN_FGCHAR, 0},
- { "_getline", FN_FGLINE, 0},
- { "_handle", FN_FILNO, 0},
- { "_line", FN_NLINE, 0},
- { "_pos", FN_FPOS, 0},
- { "_putblock", FN_FPBLK, 0},
- { "_putchar", FN_FPCHAR, 0},
- { "_putline", FN_FPLINE, 0},
- { "_status", FN_FSTAT, 0},
-#endif /* CKCHANNELIO */
-
- { "aaconvert", FN_AADUMP, 0}, /* Associative Array conversion */
- { "absolute", FN_ABS, 0}, /* Absolute value */
-#ifdef TCPSOCKET
- { "addr2name", FN_HSTADD,CM_INV}, /* IP Address to Hostname */
- { "addrtoname", FN_HSTADD,CM_INV}, /* IP Address to Hostname */
-#endif /* TCPSOCKET */
- { "arraylook", FN_ALOOK,0}, /* Array lookup */
- { "b64decode", FN_FMB64,0}, /* Base-64 conversion */
- { "b64encode", FN_TOB64,0}, /* ... */
- { "basename", FN_BSN, 0}, /* Basename */
- { "break", FN_BRK, 0}, /* Break (as in Snobol) */
- { "ca", FN_CAP, CM_INV|CM_ABR}, /* Abbreviation for capitablize */
- { "cap", FN_CAP, CM_INV|CM_ABR}, /* Abbreviation for capitablize */
- { "capitalize", FN_CAP, 0}, /* First Letter -> uppercase */
- { "caps", FN_CAP, CM_INV}, /* ditto */
- { "character", FN_CHR, 0}, /* Character from code */
- { "checksum", FN_CHK, 0}, /* Checksum */
- { "cmdstack", FN_CMDSTK,0}, /* Command stack */
- { "cmpdates", FN_CMPDATE,0}, /* Compare dates */
- { "code", FN_COD, 0}, /* Code from character */
-#ifndef NOPUSH
- { "command", FN_CMD, 0}, /* Output from a command */
-#endif /* NOPUSH */
- { "contents", FN_CON, 0}, /* Definition (contents) of variable */
- { "count", FN_COUNT, 0}, /* Occurrences of string in string */
- { "crc16", FN_CRC, 0}, /* CRC-16 */
-#ifdef OS2
- { "crypt", FN_CRY, CM_INV},
-#endif /* OS2 */
- { "cvtcset", FN_XLATE, 0}, /* Convert character set */
- { "cvtdate", FN_DTIM, 0}, /* Convert free date/time to std */
-#ifdef ZFCDAT
- { "date", FN_FD, 0}, /* File modification/creation date */
-#endif /* ZFCDAT */
- { "day", FN_DAY, 0}, /* Day of week */
- { "dayofyear", FN_JDATE,0}, /* Date to Day of Year */
- { "decodehex", FN_UNPCT, 0}, /* Decode string with hex escapes */
- { "definition", FN_DEF, 0}, /* Return definition of given macro */
- { "delta2secs", FN_DELSEC, 0}, /* Delta time to seconds */
- { "deltatosecs", FN_DELSEC, CM_INV}, /* Delta time to seconds */
-#ifndef NODIAL
- { "dialconvert",FN_PNCVT,0}, /* Convert portable phone number */
-#endif /* NODIAL */
- { "diffdates", FN_DIFDATE,0}, /* Difference of two date-times */
- { "dimension", FN_DIM, 0}, /* Dimension of array */
- { "dir", FN_DIR, CM_INV|CM_ABR}, /* Abbreviation for direct.. */
- { "dire", FN_DIR, CM_INV|CM_ABR}, /* Abbreviation for direct.. */
- { "direc", FN_DIR, CM_INV|CM_ABR}, /* Abbreviation for direct.. */
- { "direct", FN_DIR, CM_INV|CM_ABR}, /* Abbreviation for direct.. */
- { "directo", FN_DIR, CM_INV|CM_ABR}, /* Abbreviation for direct.. */
- { "director", FN_DIR, CM_INV|CM_ABR}, /* Abbreviation for direct.. */
- { "directories",FN_DIR, 0}, /* List of directories */
- { "directory", FN_DIR, CM_INV}, /* List of directories */
- { "dirname", FN_DNAM, 0}, /* Directory part of filename */
- { "dos2unixpath",FN_PC_DU, }, /* DOS to UNIX path */
- { "dostounixpath",FN_PC_DU, CM_INV}, /* DOS to UNIX path */
- { "doy", FN_JDATE,CM_INV}, /* Date to Day of Year */
- { "doy2date", FN_DATEJ,0}, /* Day of Year to date */
- { "doytodate", FN_DATEJ,CM_INV}, /* Day of Year to date */
- { "emailaddress",FN_EMAIL, 0}, /* Email address */
-#ifdef FN_ERRMSG
- { "errstring", FN_ERRMSG,0}, /* Error code to message */
-#endif /* FN_ERRMSG */
- { "evaluate", FN_EVA, 0}, /* Evaluate given arith expression */
- { "execute", FN_EXE, 0}, /* Execute given macro */
- { "files", FN_FC, 0}, /* File count */
-#ifdef FNFLOAT
- { "fpabsolute", FN_FPABS, 0}, /* Floating-point absolute value */
- { "fpadd", FN_FPADD, 0}, /* FP add */
- { "fpcosine", FN_FPCOS, 0}, /* FP cosine */
- { "fpdivide", FN_FPDIV, 0}, /* FP divide */
- { "fpexp", FN_FPEXP, 0}, /* FP e to the x */
- { "fpint", FN_FPINT, 0}, /* FP to integer */
- { "fplog10", FN_FPLOG, 0}, /* FP base-10 logarithm */
- { "fplogn", FN_FPLN, 0}, /* FP natural logarithm */
- { "fpmaximum", FN_FPMAX, 0}, /* FP maxinum */
- { "fpminimum", FN_FPMIN, 0}, /* FP mininum */
- { "fpmodulus", FN_FPMOD, 0}, /* FP modulus */
- { "fpmultiply", FN_FPMUL, 0}, /* FP multiply */
- { "fpraise", FN_FPPOW, 0}, /* FP raise to a power */
- { "fpround", FN_FPROU, 0}, /* FP round */
- { "fpsine", FN_FPSIN, 0}, /* FP sine */
- { "fpsqrt", FN_FPSQR, 0}, /* FP square root */
- { "fpsubtract", FN_FPSUB, 0}, /* FP subtract */
- { "fptangent", FN_FPTAN, 0}, /* FP tangent */
-#endif /* FNFLOAT */
- { "function", FN_FUNC, 0 }, /* Test for existence of a function */
- { "getpidinfo", FN_PID, 0 }, /* Get PID info */
- { "hex2ip", FN_HEX2IP,0}, /* Hex to IP address */
- { "hextoip", FN_HEX2IP,CM_INV}, /* Hex to IP address */
- { "hex2n", FN_HEX2N, CM_INV}, /* Hex to decimal number */
- { "hexify", FN_HEX, 0}, /* Hexify (string) */
- { "index", FN_IND, 0}, /* Index (string search) */
- { "ip2hex", FN_IP2HEX,0}, /* IP address to hex */
- { "iptohex", FN_IP2HEX,CM_INV}, /* IP address to hex */
- { "ipaddress", FN_IPA, 0}, /* Find and return IP address */
- { "jdate", FN_JDATE, CM_INV}, /* Date to Day of Year */
- { "join", FN_JOIN, 0}, /* Join array elements */
- { "keywordvalue", FN_KWVAL, 0}, /* Keyword=Value */
-#ifdef CK_KERBEROS
- { "krbflags", FN_KRB_FG, 0}, /* Kerberos functions */
- { "krbisvalid", FN_KRB_IV, 0},
- { "krbnextticket", FN_KRB_NX, 0},
- { "krbtickets", FN_KRB_TK, 0},
- { "krbtimeleft", FN_KRB_TT, 0},
-#endif /* CK_KERBEROS */
- { "kwvalue", FN_KWVAL, CM_INV}, /* Keyword=Value */
- { "left", FN_LEF, 0}, /* Leftmost n characters of string */
- { "length", FN_LEN, 0}, /* Return length of argument */
- { "literal", FN_LIT, 0}, /* Return argument literally */
-#ifdef NT
- { "longpathname",FN_LNAME,0}, /* GetLongPathName() */
-#else
- { "longpathname",FN_FFN,CM_INV},
-#endif /* NT */
- { "lop", FN_STL, 0}, /* Lop */
- { "lopx", FN_LOPX, 0}, /* Lopx */
- { "lower", FN_LOW, 0}, /* Return lowercased argument */
- { "lpad", FN_LPA, 0}, /* Return left-padded argument */
- { "ltrim", FN_LTR, 0}, /* Left-Trim */
- { "maximum", FN_MAX, 0}, /* Return maximum of two arguments */
- { "minimum", FN_MIN, 0}, /* Return minimum of two arguments */
- { "mjd", FN_MJD, 0}, /* Date to Modified Julian Date */
- { "mjd2date", FN_MJD2, 0}, /* MJD to Date */
- { "mjdtodate", FN_MJD2, CM_INV}, /* MJD to Date */
- { "modulus", FN_MOD, 0}, /* Return modulus of two arguments */
-#ifdef COMMENT
- { "msleep", FN_MSLEEP,0}, /* Sleep for n milliseconds */
-#endif /* COMMENT */
- { "n2hex", FN_2HEX, CM_INV}, /* Number to hex */
- { "n2octal", FN_2OCT, CM_INV}, /* Number to octal */
- { "n2time", FN_N2TIM,0}, /* Number to hh:mm:ss */
-#ifdef TCPSOCKET
- { "name2addr", FN_HSTNAM,CM_INV}, /* Hostname to IP Address */
-#endif /* TCPSOCKET */
- { "nday", FN_NDAY, 0}, /* Numeric day of week */
- { "nextfile", FN_FIL, 0}, /* Next file in list */
- { "ntime", FN_NTIM, 0}, /* Time to seconds since midnight */
- { "ntohex", FN_2HEX, CM_INV}, /* Number to hex */
- { "ntooctal", FN_2OCT, CM_INV}, /* Number to octal */
- { "ntotime", FN_N2TIM,CM_INV}, /* Number to hh:mm:ss */
- { "oct2n", FN_OCT2N,CM_INV}, /* Octal to decimal number */
- { "octton", FN_OCT2N,CM_INV}, /* Octal to decimal number */
- { "pathname", FN_FFN, 0}, /* Full file name */
- { "pattern", FN_PATTERN, 0}, /* Pattern (for INPUT) */
-#ifdef CK_PERMS
- { "permissions",FN_PERM, 0}, /* Permissions of file */
-#else
- { "permissions",FN_PERM, CM_INV}, /* Permissions of file */
-#endif /* CK_PERMS */
-#ifdef SEEK_CUR
- { "pictureinfo",FN_PICTURE, 0 }, /* Picture orientation/dimensions */
-#endif /* SEEK_CUR */
- { "radix", FN_RADIX, 0 }, /* Radix conversion */
-#ifndef NORANDOM
- { "random", FN_RAND, 0}, /* Random number */
-#endif /* NORANDOM */
-#ifndef NOPUSH
- { "rawcommand", FN_RAW, 0}, /* Output from a command (raw) */
-#endif /* NOPUSH */
-#ifdef RECURSIVE
- { "rdirectories", FN_RDIR, 0}, /* Recursive directory list */
-#endif /* RECURSIVE */
- { "recurse", FN_RECURSE, 0}, /* Recursive variable evaluation */
-#ifdef RECURSIVE
- { "rfiles", FN_RFIL, 0}, /* Recursive file list */
-#endif /* RECURSIVE */
- { "rep", FN_REP, CM_INV|CM_ABR},
- { "repeat", FN_REP, 0}, /* Repeat argument given # of times */
- { "replace", FN_RPL, 0}, /* Replace characters in string */
- { "reverse", FN_REV, 0}, /* Reverse the argument string */
- { "right", FN_RIG, 0}, /* Rightmost n characters of string */
- { "rindex", FN_RIX, 0}, /* Right index */
- { "rpad", FN_RPA, 0}, /* Right-pad the argument */
- { "rsearch", FN_RSEARCH, 0}, /* R-L Search for pattern in string */
-#ifdef OS2
- { "scrncurx", FN_SCRN_CX, 0}, /* Screen Cursor X Pos */
- { "scrncury", FN_SCRN_CY, 0}, /* Screen Cursor Y Pos */
- { "scrnstr", FN_SCRN_STR, 0}, /* Screen String */
-#endif /* OS2 */
- { "search", FN_SEARCH, 0}, /* L-R Search for pattern in string */
-#ifndef NOSEXP
- { "sexpression",FN_SEXP, 0}, /* S-Expression */
-#endif /* NOSEXP */
-#ifdef NT
- { "shortpathname",FN_SNAME,0}, /* GetShortPathName() */
-#else
- { "shortpathname",FN_FFN,CM_INV},
-#endif /* NT */
- { "size", FN_FS, 0}, /* File size */
-#ifdef COMMENT
- { "sleep", FN_SLEEP,0}, /* Sleep for n seconds */
-#endif /* COMMENT */
- { "span", FN_SPN, 0}, /* Span - like Snobol */
- { "split", FN_SPLIT,0}, /* Split string into words */
- { "squeeze", FN_SQUEEZE,0}, /* Squeeze whitespace in string */
- { "strcmp", FN_STRCMP,0}, /* String comparison */
- { "stringtype", FN_STRINGT,0}, /* String type (7-bit, 8-bit, UTF-8) */
- { "stripb", FN_STB, 0}, /* Strip enclosing braces/brackets */
- { "stripn", FN_STN, 0}, /* Strip n chars */
- { "stripx", FN_STX, 0}, /* Strip suffix */
- { "su", FN_SUB, CM_INV|CM_ABR},
- { "sub", FN_SUB, CM_INV|CM_ABR},
- { "subs", FN_SUB, CM_INV|CM_ABR},
- { "subst", FN_SUB, CM_INV|CM_ABR},
- { "substitute", FN_SUBST,0}, /* Substitute chars */
- { "substring", FN_SUB, 0}, /* Extract substring from argument */
- { "tablelook", FN_TLOOK,0}, /* Table lookup */
- { "time", FN_TIME, 0}, /* Free-format time to hh:mm:ss */
- { "tod2secs", FN_NTIM, CM_INV}, /* Time-of-day-to-secs-since-midnite */
- { "todtosecs", FN_NTIM, CM_INV}, /* Time-of-day-to-secs-since-midnite */
- { "trim", FN_TRM, 0}, /* Trim */
- { "unhexify", FN_UNH, 0}, /* Unhexify */
- { "unix2dospath",FN_PC_UD, 0}, /* UNIX to DOS path */
- { "unixtodospath",FN_PC_UD, CM_INV}, /* UNIX to DOS path */
- { "untabify", FN_UNTAB,0}, /* Untabify */
- { "upper", FN_UPP, 0}, /* Return uppercased argument */
- { "utcdate", FN_TOGMT,0}, /* Date-time to UTC (GMT) */
- { "verify", FN_VER, 0}, /* Verify */
- { "word", FN_WORD, 0}, /* Extract a word */
- { "", 0, 0}
-};
-int nfuncs = (sizeof(fnctab) / sizeof(struct keytab)) - 1;
-#endif /* NOSPL */
-
-#ifndef NOSPL /* Buffer for expansion of */
-#ifdef BIGBUFOK /* built-in variables. */
-#define VVBUFL 1024
-#else
-#define VVBUFL 256
-#endif /* BIGBUFOK */
-char vvbuf[VVBUFL+1];
-#endif /* NOSPL */
-
-struct keytab disptb[] = { /* Log file disposition */
- { "append", 1, 0},
- { "new", 0, 0}
-};
-
-#ifdef CKFLOAT
-
-/* I N I T F L O A T -- Deduce floating-point precision by inspection */
-
-int fp_rounding = 0; /* Nonzero if printf("%f") rounds */
-int fp_digits = 0; /* Digits of floating point precision */
-
-#ifdef COMMENT
-/* For looking at internal floating-point representations */
-static char fp_xbuf[128];
-static char *
-tohex(s, n) CHAR * s; int n; {
- int x;
- char * p = fp_xbuf;
- while (n-- > 0) {
- x = (*s >> 4) & 0x0f;
- *p++ = hexdigits[x];
- x = *s++ & 0x0f;
- *p++ = hexdigits[x];
- }
- *p = NUL;
- return((char *)fp_xbuf);
-}
-#endif /* COMMENT */
-
-char math_pi[] = "3.1415926535897932384626433832795";
-char math_e[] = "2.7182818284590452353602874713527";
-
-VOID
-initfloat() {
- char * buf = NULL;
- int i, x, y;
-/*
- We malloc a big temporary buffer for sprintf() to minimize likelihood of
- (and damage from) sprintf buffer overflows. In any case, the only way this
- could happen would be if sprintf() itself had bugs, since the format
- descriptor says to cut it off at 250 decimal places.
-*/
- if ((buf = (char *)malloc(4096))) {
- sprintf(buf,"%0.250f",(10.0 / 3.0));
- for (i = 2; i < 250 && buf[i] == '3'; i++) ;
- x = i - 1;
- debug(F111,"initfloat 10.0/3.0",buf,x);
- sprintf(buf,"%0.250f",(4.0 / 9.0));
- for (i = 2; i < 250 && buf[i] == '4'; i++) ;
- y = i - 1;
- debug(F111,"initfloat 4.0/9.0",buf,y);
- fp_digits = (x < y) ? x : y;
- if (fp_digits < sizeof(math_pi) - 1) {
- math_pi[fp_digits+1] = NUL;
- math_e[fp_digits+1] = NUL;
- }
- sprintf(buf,"%0.6f",(7.0 / 9.0));
- if (buf[7] == '8') fp_rounding = 1;
- debug(F111,"initfloat 7.0/9.0",buf,fp_rounding);
- debug(F101,"initfloat precision","",fp_digits);
- free(buf);
- }
-}
-#endif /* CKFLOAT */
-
-/*
- P R E S C A N -- A quick look through the command-line options for
- items that must be handled before the initialization file is executed.
-*/
-#ifdef NT
-extern int StartedFromDialer;
-#endif /* NT */
-#ifdef OS2
-extern int k95stdio;
-unsigned long startflags = 0L;
-#endif /* OS2 */
-
-static char *
-findinpath(arg) char * arg; {
-#ifdef OS2
- char * scriptenv, * keymapenv;
- int len;
-#endif /* OS2 */
-#ifdef DCMDBUF
- extern char * cmdbuf;
-#else
- extern char cmdbuf[];
-#endif /* DCMDBUF */
- char takepath[4096];
- char * s;
- int x, z;
-
- /* Set up search path... */
-#ifdef OS2
- char * appdata0 = NULL, *appdata1 = NULL;
-#ifdef NT
- scriptenv = getenv("K95SCRIPTS");
- keymapenv = getenv("K95KEYMAPS");
- makestr(&appdata0,(char *)GetAppData(0));
- makestr(&appdata1,(char *)GetAppData(1));
-#else /* NT */
- scriptenv = getenv("K2SCRIPTS");
- keymapenv = getenv("K2KEYMAPS");
-#endif /* NT */
- if (!scriptenv)
- scriptenv = getenv("CK_SCRIPTS");
- if (!scriptenv)
- scriptenv = "";
- if (!keymapenv)
- keymapenv = getenv("CK_KEYMAPS");
- if (!keymapenv)
- keymapenv = "";
-
- debug(F110,"startupdir",startupdir,0);
- debug(F110,"common appdata directory",appdata1,0);
- debug(F110,"appdata directory",appdata0,0);
- debug(F110,"inidir",inidir,0);
- debug(F110,"home",zhome(),0);
- debug(F110,"exedir",exedir,0);
-
- len = strlen(scriptenv) + strlen(keymapenv) + 3*strlen(startupdir)
- + 3*strlen(inidir) + 3*strlen(zhome()) + 3*strlen(exedir)
- + (appdata0 ? 3*strlen(appdata0) : 0)
- + (appdata1 ? 3*strlen(appdata1) : 0)
- + 6*strlen("SCRIPTS/") + 6*strlen("KEYMAPS/") + 16;
-
- if (len >= 4096) { /* SAFE (length is checked) */
- takepath[0] = '\0';
- debug(F111,"findinpath error - path length too long","len",len);
- } else
- sprintf(takepath,
- /* semicolon-separated path list */
- "%s%s%s%s%s;%s%s;%s%s;%s%s%s%s%s%s%s%s%s%s%s%s%s;%s%s;%s%s;%s;%s%s;%s%s",
- scriptenv,
- (scriptenv[0] && scriptenv[strlen(scriptenv)-1]==';')?"":";",
- keymapenv,
- (keymapenv[0] && keymapenv[strlen(keymapenv)-1]==';')?"":";",
- startupdir,
- startupdir, "SCRIPTS/",
- startupdir, "KEYMAPS/",
- appdata1 ? appdata1 : "",
- appdata1 ? "Kermit 95;" : "",
- appdata1 ? appdata1 : "",
- appdata1 ? "Kermit 95/SCRIPTS/;" : "",
- appdata1 ? appdata1 : "",
- appdata1 ? "Kermit 95/KEYMAPS/;" : "",
- appdata0 ? appdata0 : "",
- appdata0 ? "Kermit 95;" : "",
- appdata0 ? appdata0 : "",
- appdata0 ? "Kermit 95/SCRIPTS/;" : "",
- appdata0 ? appdata0 : "",
- appdata0 ? "Kermit 95/KEYMAPS/;" : "",
- inidir,
- inidir, "SCRIPTS/",
- inidir, "KEYMAPS/",
- zhome(),
- zhome(), "SCRIPTS/",
- zhome(), "KEYMAPS/",
- exedir,
- exedir, "SCRIPTS/",
- exedir, "KEYMAPS/"
- );
- debug(F110,"findinpath takepath",takepath,0);
-#ifdef NT
- makestr(&appdata0,NULL);
- makestr(&appdata1,NULL);
-#endif /* NT */
-#else /* not OS2 */
-#ifndef NOSPL
- z = 1024; /* Look in home directory */
- s = takepath;
- zzstring("\\v(home)",&s,&z);
-#else
- takepath[0] = '\0';
-#endif /* NOSPL */
-#endif /* OS2 */
-/*
- All the logic for searching the take path is in the command parser.
- So even though we aren't parsing commands, we initialize and call the
- parser from here, with the purported filename stuffed into the command
- buffer, followed by some carriage returns to make the parser return.
- If the file is not found, or otherwise not accessible, the parser prints
- an appropriate message, and then we just exit.
-*/
- cmdini(); /* Allocate command buffers etc */
- cmini(0); /* Initialize them */
- /* Stuff filename into command buf with braces in case of spaces */
- ckmakmsg(cmdbuf,CMDBL,"{",arg,"}",NULL);
- debug(F110,"findinpath cmdbuf",cmdbuf,0);
- ckstrncat(cmdbuf,"\r\r",CMDBL); /* And some carriage returns */
- if (cmifip("","",&s,&x,0,takepath,xxstring) < 0)
- return(NULL);
- cmres();
- return(s);
-}
-
-static int tr_int; /* Flag if TRANSMIT interrupted */
-
-#ifndef MAC
-SIGTYP
-#ifdef CK_ANSIC
-trtrap(int foo) /* TRANSMIT interrupt trap */
-#else
-trtrap(foo) int foo; /* TRANSMIT interrupt trap */
-#endif /* CK_ANSIC */
-/* trtrap */ {
-#ifdef __EMX__
- signal(SIGINT, SIG_ACK);
-#endif
- tr_int = 1; /* (Need arg for ANSI C) */
- SIGRETURN;
-}
-#endif /* MAC */
-#endif /* NOICP */
-
-#ifdef UNIX
-VOID
-getexedir() {
- extern char * xarg0;
- long xx;
- /*
- Unix provides no standard service for this. We look in argv[0], and if
- we're lucky there's a full pathname. If not we do a PATH search.
- */
- if (ckstrchr(xarg0,'/')) { /* Global copy of argv[0] */
- int i, k;
- char * p = NULL;
- if ((k = ckstrncpy(tmpbuf,xarg0,TMPBUFSIZ-2)) > 0) {
- p = tmpbuf;
- /* Convert to fully qualified pathname */
- if (tmpbuf[0]) if (tmpbuf[0] != '/') {
- line[0] = NUL;
- zfnqfp(tmpbuf,LINBUFSIZ-2,(char *)line);
- if (line[0])
- p = line;
- }
- xx = zchki(p);
- if (xx > -1) { /* Is the result an existing file? */
- k = strlen(p);
- for (i = k-1; i > 0; i--) { /* Yes, strip name part */
- if (p[i] == '/') {
- if (i < k-1)
- p[i+1] = NUL;
- break;
- }
- }
- }
- makestr(&exedir,p); /* Save the result */
- }
- }
- if (!exedir && xarg0) { /* Not found? */
- char * p;
- p = getenv("PATH"); /* Search the PATH */
- if (p) { /* If there is one... */
- char * q, * PATH = NULL;
- int k;
- makestr(&PATH,p); /* Pokeable copy of PATH string */
- if (PATH) { /* If malloc succeeded... */
- p = PATH;
- while (p && *p) { /* Loop through segments */
- q = ckstrchr(p,':'); /* End of this segment */
- if (q == p) { /* Null PATH segment */
- p++; /* Skip over colon */
- continue;
- }
- if (q) /* If not at end of PATH string */
- *q++ = NUL; /* zero out the colon */
- if ((k = ckstrncpy(tmpbuf,p,TMPBUFSIZ)) > 0) {
- if (tmpbuf[k-1] != '/') { /* Copy this PATH segment */
- tmpbuf[k++] = '/'; /* Append '/' if needed */
- tmpbuf[k] = NUL;
- }
- /* Append the argv[0] value */
- if (ckstrncpy(&tmpbuf[k],xarg0,TMPBUFSIZ) > 0) {
- if (zchki(tmpbuf) > -1) { /* File exists? */
- tmpbuf[k] = NUL; /* Yes, we're done */
- zfnqfp(tmpbuf,LINBUFSIZ,(char *)line);
- makestr(&exedir,line);
- break;
- }
- } else break;
- } else break;
- p = q; /* Not found, go to next segment */
- } /* while */
- free(PATH); /* Free PATH copy */
- }
- }
- if (!exedir) { /* Still nothing? */
- if (zchki(xarg0) > -1) { /* Maybe it's in the current dir */
- zfnqfp(zgtdir(),LINBUFSIZ,(char *)line);
- makestr(&exedir,line);
- }
- }
- }
- if (!exedir) { /* Still nothing? */
- makestr(&exedir,"/"); /* Fake it with with root. */
- }
-}
-#endif /* UNIX */
-
-int arg_x = 0;
-static int x_prescan = 0;
-
-/*
- The argument y once meant something but I can't imagine what so now
- it's ignored. (Prior to 22 Aug 98, prescan() was called twice by main(),
- and the arg differentiated the two calls. But this caused all sorts of
- problems & confusion, so I commented out the second call. This issue might
- need to be revisited.)
-*/
-VOID
-prescan(dummy) int dummy; { /* Arg is ignored. */
- extern int howcalled;
- int yargc; char **yargv;
- char x;
- char *yp, *yy;
-#ifdef DEBUG
- int debcount = 0;
-#endif /* DEBUG */
- int z;
-
- if (x_prescan) /* Only run once */
- return;
- x_prescan = 1;
-
- yargc = xargc; /* Make copy of arg vector */
- yargv = xargv;
-
-#ifndef NOICP
-#ifdef DCMDBUF
- if (!kermrc)
- if (!(kermrc = (char *) malloc(KERMRCL+1)))
- fatal("prescan: no memory for kermrc");
-#endif /* DCMDBUF */
- ckstrncpy(kermrc,KERMRC,KERMRCL); /* Default init file name */
-#endif /* NOICP */
-
-#ifdef OS2
- yp = getenv("K95STARTFLAGS");
- if (yp) {
- startflags = atoi(yp);
- }
-#endif /* OS2 */
-
-#ifdef IKSD
- if (howcalled == I_AM_IKSD) /* Internet Kermit Service daemon */
- inserver = 1; /* (See inserver section of ckcmai) */
-#endif /* IKSD */
-
-/* Command line options for Kermit */
-
-#ifndef NOCMDL
- if (yargc > 1
- && *yargv[1] != '-'
- && (yargv[1][0] != '=')
-#ifdef KERBANG
- && (yargv[1][0] != '+')
-#endif /* KERBANG */
-#ifdef IKSD
- && (howcalled != I_AM_IKSD)
-#endif /* IKSD */
- ) { /* Filename as 1st argument */
-#ifndef NOICP
- char *s;
-#endif /* NOICP */
-#ifndef NOURL
- extern int haveurl;
- extern struct urldata g_url;
- if (urlparse(yargv[1],&g_url)) {
- if (!ckstrcmp(g_url.svc,"ftp",-1,0) ||
- !ckstrcmp(g_url.svc,"ftps",-1,0)) {
- haveurl = 1;
- howcalled = I_AM_FTP;
- } else if (!ckstrcmp(g_url.svc,"telnet",-1,0) ||
- !ckstrcmp(g_url.svc,"telnets",-1,0)) {
- haveurl = 1;
- howcalled = I_AM_TELNET;
- } else if (!ckstrcmp(g_url.svc,"ssh",-1,0)) {
- haveurl = 1;
- howcalled = I_AM_SSH;
- } else if (!ckstrcmp(g_url.svc,"iksd",-1,0) ||
- !ckstrcmp(g_url.svc,"kermit",-1,0)) {
- haveurl = 1;
- howcalled = I_AM_KERMIT;
- } else if (!ckstrcmp(g_url.svc,"http",-1,0) ||
- !ckstrcmp(g_url.svc,"https",-1,0)) {
- haveurl = 1;
- howcalled = I_AM_HTTP;
- }
- if (haveurl) {
- while (--yargc > 0) { /* Go through command-line args */
- yargv++; /* looking for -Y and -d */
- yp = *yargv+1;
- if (**yargv == '-') {
- x = *(*yargv+1);
- while (x) {
- switch (x) {
-#ifndef NOICP
- case '+':
- case '-':
- if (doxarg(yargv,1) < 0) {
- fatal("Extended argument error");
- }
- yp = "";
- break;
-#endif /* NOICP */
- case 'Y':
- noinit++;
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'h':
- noinit = 1;
-#ifdef OS2
- startflags |= 2; /* No network DLLs */
- startflags |= 4; /* No TAPI DLLs */
- startflags |= 8; /* No Security DLLs */
- startflags |= 16; /* No Zmodem DLLs */
- startflags |= 32; /* Stdin */
- startflags |= 64; /* Stdout */
-#endif /* OS2 */
- break;
- case 'd': /* = SET DEBUG ON */
-#ifdef DEBUG
- if (debcount++ > 0)
- debtim = 1;
- if (!deblog)
- deblog = debopn("debug.log",0);
-#endif /* DEBUG */
- break;
-#ifdef OS2
- case 'W':
- if (*(yp+1))
- fatal("invalid argument bundling after -W");
- yargv++, yargc--;
- if (yargc < 1)
- fatal("Window handle missing");
- hwndDialer = (HWND) atol(*yargv);
- StartedFromDialer = 1;
- yargv++, yargc--;
- KermitDialerID = atol(*yargv) ;
- break;
- case '#': /* K95 initialization options */
- if (*(yp+1)) {
- fatal("invalid argument bundling");
- }
- yargv++, yargc--;
- if (yargc < 1)
- fatal("-# argument missing");
- startflags |= atol(*yargv);
- break;
-#endif /* OS2 */
- }
- if (!yp)
- break;
- x = *++yp;
- }
- }
- }
- return;
- }
- }
- /* after this point non-Kermit personalities must return */
- switch (howcalled) {
- case I_AM_KERMIT:
- case I_AM_IKSD:
- case I_AM_SSHSUB:
- break;
- default:
- return;
- }
-#endif /* NOURL */
-
-#ifndef NOICP
- /* If it is not a URL that we recognize, try to treat it as a file */
-
- if (!isabsolute(yargv[1])) /* If not absolute */
- s = findinpath(yargv[1]); /* Look in PATH */
- else
- s = yargv[1];
- if (!s)
- doexit(BAD_EXIT,xitsta);
- zfnqfp(s,CKMAXPATH,cmdfil); /* In case of CD in file */
- yargc -= 1; /* Skip past the filename */
- yargv += 1; /* Otherwise we'll get an error */
-#endif /* NOICP */
- }
-
-#ifndef NOCMDL
-#ifdef NEWFTP
- if (howcalled == I_AM_FTP) { /* Kermit's FTP client personality */
- while (--yargc > 0) { /* Go through command-line args */
- yargv++; /* looking for -Y and -d */
- yp = *yargv+1;
- if (**yargv == '-') {
- x = *(*yargv+1);
- while (x) {
- switch (x) {
-#ifndef NOICP
- case '+':
- case '-':
- if (doxarg(yargv,1) < 0) {
- fatal("Extended argument error");
- }
- yp = "";
- break;
-#endif /* NOICP */
- case 'Y':
- noinit++;
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'h':
- noinit = 1;
-#ifdef OS2
- startflags |= 2; /* No network DLLs */
- startflags |= 4; /* No TAPI DLLs */
- startflags |= 8; /* No Security DLLs */
- startflags |= 16; /* No Zmodem DLLs */
- startflags |= 32; /* Stdin */
- startflags |= 64; /* Stdout */
-#endif /* OS2 */
- break;
- case 'd': /* = SET DEBUG ON */
-#ifdef DEBUG
- if (debcount++ > 0)
- debtim = 1;
- if (!deblog)
- deblog = debopn("debug.log",0);
-#endif /* DEBUG */
- break;
-#ifdef OS2
- case 'W':
- if (*(yp+1))
- fatal("invalid argument bundling after -W");
- yargv++, yargc--;
- if (yargc < 1)
- fatal("Window handle missing");
- hwndDialer = (HWND) atol(*yargv);
- StartedFromDialer = 1;
- yargv++, yargc--;
- KermitDialerID = atol(*yargv) ;
- break;
- case '#': /* K95 initialization options */
- if (*(yp+1)) {
- fatal("invalid argument bundling");
- }
- yargv++, yargc--;
- if (yargc < 1)
- fatal("-# argument missing");
- startflags |= atol(*yargv);
- break;
-#endif /* OS2 */
- }
- if (!yp)
- break;
- x = *++yp;
- }
- }
- }
- return;
- }
-#endif /* NEWFTP */
-#endif /* NOCMDL */
-
- while (--yargc > 0) { /* Go through command-line args */
- yargv++;
- yp = *yargv+1; /* Pointer for bundled args */
- if (**yargv == '=') /* Same rules as cmdlin()... */
- return;
- debug(F110,"prescan *yargv",*yargv,0);
-
-#ifndef NOICP
-#ifdef KERBANG
- yy = *yargv;
- if (!strcmp(yy,"+") || (*yy == '+' && *(yy+1) < (char)33)) {
- char * s;
- yargv++;
- noinit = 1;
- if (!*yargv)
- return;
- cfilef = 1;
- s = findinpath(*yargv);
- if (s) {
- zfnqfp(s,CKMAXPATH,cmdfil);
- return;
- } else
- doexit(BAD_EXIT,xitsta);
- }
-#endif /* KERBANG */
-#endif /* NOICP */
- if (!strcmp(*yargv,"--")) /* getopt() conformance */
- return;
-#ifdef VMS
- else if (**yargv == '/')
- continue;
-#endif /* VMS */
- else if (**yargv == '-') { /* Got an option (begins with dash) */
- x = *(*yargv+1); /* Get option letter */
- while (x) { /* Allow for bundled options */
- debug(F000,"prescan arg","",x);
- switch (x) {
-#ifndef NOICP
- case '+':
- case '-':
- if (doxarg(yargv,1) < 0) {
- fatal("Extended argument error");
- }
-#ifndef COMMENT /* Jeff 28 Apr 2003 */
- yp = NULL; /* (not "") */
-#else
- yargv++, yargc--;
- yp = *yargv;
-#endif /* COMMENT */
- break;
-#endif /* NOICP */
-
- case '7': /* Undocumented... */
- sstelnet = 1; /* (because it doesn't work) */
- break;
-#ifdef IKSD
- case 'A': {
- char * p;
- inserver = 1; /* Flag that we are doing this */
- srvcdmsg = 2; /* Preset this */
- /* See inserver section of ckcmai.c for more settings */
-#ifdef OS2
- if (*(yp+1)) {
- fatal("invalid argument bundling after -A");
- }
-#ifdef NT
- /* Support for Pragma Systems Telnet/Terminal Servers */
- p = getenv("PRAGMASYS_INETD_SOCK");
- if (p && atoi(p) != 0) {
- ttname[0] = '$';
- ckstrncpy(&ttname[1],p,TTNAMLEN-1);
- break;
- }
-#endif /* NT */
- yargv++, yargc--;
- if (yargc < 1 || **yargv == '-') {
- fatal("-A argument missing");
- } else {
- ttname[0] = '$';
- ckstrncpy(&ttname[1],*yargv,TTNAMLEN-1);
- }
-#endif /* OS2 */
- break;
- }
-#endif /* IKSD */
-
-#ifdef OS2
- case 'W':
- if (*(yp+1))
- fatal("invalid argument bundling after -W");
- yargv++, yargc--;
- if (yargc < 1)
- fatal("Window handle missing");
-#ifdef COMMENT
- if (dummy) {
- yargv++, yargc--;
- break;
- } else {
-#endif /* COMMENT */
- hwndDialer = (HWND) atol(*yargv);
- StartedFromDialer = 1;
- yargv++, yargc--;
- KermitDialerID = atol(*yargv) ;
-#ifdef COMMENT
- }
-#endif /* COMMENT */
- break;
-
- case '#': /* K95 initialization options */
- if (*(yp+1)) {
- fatal("invalid argument bundling");
- }
- yargv++, yargc--;
- if (yargc < 1)
- fatal("-# argument missing");
- startflags |= atol(*yargv);
- break;
-#endif /* OS2 */
-
-#ifndef NOSPL
- case 'M': /* My User Name */
- if (*(yp+1)) {
- fatal("invalid argument bundling");
- }
- yargv++, yargc--;
- if ((yargc < 1) || (**yargv == '-')) {
- fatal("missing username");
- }
- if ((int)strlen(*yargv) > UIDBUFLEN) {
- fatal("username too long");
- }
-#ifdef COMMENT
-/*
- This can't work. uidbuf is overwritten in sysinit() which has yet to be
- called. This cannot be set in prescan().
-*/
-#ifdef IKSD
- if (!inserver)
-#endif /* IKSD */
- ckstrncpy(uidbuf,*yargv,UIDBUFLEN);
-#endif /* COMMENT */
- break;
-#endif /* NOSPL */
- case 'R': /* Remote-only advisory */
-#ifdef CK_IFRO
- remonly = 1;
-#endif /* CK_IFRO */
- break;
- case 'S': /* STAY */
- stayflg = 1;
- break;
- case 'h':
- noinit = 1;
-#ifdef OS2
- startflags |= 2; /* No network DLLs */
- startflags |= 4; /* No TAPI DLLs */
- startflags |= 8; /* No Security DLLs */
- startflags |= 16; /* No Zmodem DLLs */
- startflags |= 32; /* Stdin */
- startflags |= 64; /* Stdout */
-#endif /* OS2 */
- break;
-#ifndef NOICP
- case 'Y': /* No init file */
- noinit = 1;
- break;
-#endif /* NOICP */
-
- case 'q':
- quiet = 1;
- break;
-
- case 'd': /* = SET DEBUG ON */
-#ifdef DEBUG
- if (debcount++ > 0)
- debtim = 1;
- if (!deblog)
- deblog = debopn("debug.log",0);
-#endif /* DEBUG */
- break;
-
- case 'x': /* Server */
- arg_x = 1; /* Note in advance */
- break;
-#ifndef NOICP
- case 'y': /* Alternative init file */
- noinit = 0;
- yargv++, yargc--;
- if (yargc < 1) fatal("missing name in -y");
- /* Replace init file name */
- ckstrncpy(kermrc,*yargv,KERMRCL);
- rcflag = 1; /* Flag that this has been done */
- debug(F111,"prescan kermrc",kermrc,rcflag);
- break;
-#endif /* NOICP */
- case 'z': /* = SET BACKGROUND OFF */
- bgset = 0;
- backgrd = 0;
-#ifdef VMS
- batch = 0;
-#endif /* VMS */
- break;
-
- case 'B': /* Force background (batch) */
- bgset = 1;
- backgrd = 1;
-#ifdef VMS
- batch = 1;
-#endif /* VMS */
- break;
-
-#ifdef CK_NETBIOS
- case 'N':
- {
- int n ;
- yargv++, yargc--;
-#ifdef COMMENT
- if (y)
- break;
-#endif /* COMMENT */
- if (strlen(*yargv) != 1 || (*yargv)[0] == 'X') {
- NetBiosAdapter = -1;
- } else {
- n = atoi(*yargv);
- if (n >= 0 && n <= 9)
- NetBiosAdapter = n;
- else
- NetBiosAdapter = -1;
- }
- }
- break;
-#endif /* CK_NETBIOS */
- default:
- break;
- }
- if (!yp)
- break;
- x = *++yp; /* See if options are bundled */
- }
- }
- }
-#endif /* NOCMDL */
-}
-
-/* G E T T C S -- Get Transfer (Intermediate) Character Set */
-
-/*
- Given two file character sets, this routine picks out the appropriate
- "transfer" character set to use for translating between them.
- The transfer character set number is returned.
-
- Translation between two file character sets is done, for example,
- by the CONNECT, TRANSMIT, and TRANSLATE commands.
-
- Translation between Kanji character sets is not yet supported.
-*/
-int
-gettcs(cs1,cs2) int cs1, cs2; {
-#ifdef NOCSETS /* No character-set support */
- return(0); /* so no translation */
-#else
- int tcs = TC_TRANSP;
-#ifdef KANJI
-/* Kanji not supported yet */
- if (fcsinfo[cs1].alphabet == AL_JAPAN ||
- fcsinfo[cs2].alphabet == AL_JAPAN )
- tcs = TC_TRANSP;
- else
-#endif /* KANJI */
-#ifdef CYRILLIC
-/*
- I can't remember why we don't test both sets here, but I think there
- must have been a reason...
-*/
- if (fcsinfo[cs2].alphabet == AL_CYRIL)
- tcs = TC_CYRILL;
- else
-#endif /* CYRILLIC */
-#ifdef HEBREW
- if (fcsinfo[cs1].alphabet == AL_HEBREW ||
- fcsinfo[cs2].alphabet == AL_HEBREW )
- tcs = TC_HEBREW;
- else
-#endif /* HEBREW */
-#ifdef GREEK
- if (fcsinfo[cs1].alphabet == AL_GREEK ||
- fcsinfo[cs2].alphabet == AL_GREEK )
- tcs = TC_GREEK;
- else
-#endif /* GREEK */
-
- /* Roman sets ... */
-
-#ifdef LATIN2 /* East European */
- if (cs1 == FC_2LATIN || cs2 == FC_2LATIN || /* Latin-2 */
- cs1 == FC_CP852 || cs2 == FC_CP852 || /* CP852 */
- cs1 == FC_CP1250 || cs2 == FC_CP1250 || /* Windows Latin-2 */
- cs1 == FC_MAZOVIA || cs2 == FC_MAZOVIA) /* Polish Mazovia */
- tcs = TC_2LATIN;
- else
-#endif /* LATIN2 */
- /* West European Euro-aware */
- if (cs1 == FC_CP858 || cs1 == FC_9LATIN ||
- cs2 == FC_CP858 || cs2 == FC_9LATIN)
- tcs = TC_9LATIN;
- else /* Traditional West European */
- tcs = TC_1LATIN;
- return(tcs);
-#endif /* NOCSETS */
-}
-
-#ifndef NOLOCAL
-/* D O C O N E C T -- Do the connect command */
-/*
- q = 0 means issue normal informational message about how to get back, etc.
- q != 0 means to skip the message.
-*/
-
-int
-doconect(q,async) int q, async; {
- int x; /* Return code */
-#ifdef CK_AUTODL
- extern CHAR ksbuf[];
-#endif /* CK_AUTODL */
-#ifndef NOKVERBS /* Keyboard macro material */
- extern int keymac, keymacx;
-#endif /* NOKVERBS */
- extern int justone, adl_err;
- int qsave; /* For remembering "quiet" value */
-#ifdef OS2
- extern int term_io;
- extern int display_demo;
- int term_io_save;
-#ifdef KUI
- extern int kui_async;
-#endif /* KUI */
-#endif /* OS2 */
- int is_tn = 0;
-
-#ifdef IKSD
- if (inserver) {
- if (!quiet)
- printf("?Sorry, IKSD cannot CONNECT.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-
- is_tn =
-#ifdef TNCODE
- (local && network && IS_TELNET()) || (!local && sstelnet)
-#else
- 0
-#endif /* TNCODE */
- ;
-/*
- Saving, changing, and restoring the global "quiet" variable around calls
- to conect() to control whether the verbose CONNECT message is printed is
- obviously less elegant than passing a parameter to conect(), but we do it
- this way to avoid the need to change all of the ck?con.c modules. NOTE:
- it is important to restore the value immediately upon return in case there
- is an autodownload or APC.
-*/
- qsave = quiet; /* Save it */
- if (!quiet && q > -1)
- quiet = q; /* Use argument temporarily */
- conres(); /* Put console back to normal */
- debug(F101,"doconect justone 1","",justone);
-#ifdef CK_AUTODL
- ksbuf[0] = NUL; /* Autodownload packet buffer */
-#endif /* CK_AUTODL */
-#ifdef OS2
- display_demo = 1; /* Remember to display demo */
-#endif /* OS2 */
-
-#ifdef IKS_OPTION
- if (is_tn && TELOPT_U(TELOPT_KERMIT) && ttchk() >= 0
-#ifdef OS2
- && !viewonly
-#endif /* OS2 */
- ) {
- /* If the remote side is in a state of IKS START-SERVER */
- /* we request that the state be changed. We will detect */
- /* a failure to adhere to the request when we call ttinc() */
- if (!iks_wait(KERMIT_REQ_STOP,0) && !tcp_incoming) {
- if (!quiet) {
- printf("\r\nEnter Client/Server Mode... Use:\r\n\r\n");
- printf(
-" REMOTE LOGIN <user> <password> to log in to the server if necessary.\r\n");
- printf(" SEND and GET for file transfer.\r\n");
- printf(" REMOTE commands for file management.\r\n");
- printf(" FINISH to terminate Client/Server mode.\r\n");
- printf(" BYE to terminate and close connection.\r\n");
- printf(" REMOTE HELP for additional information.\r\n\r\n");
- }
- quiet = qsave;
- return(0); /* Failure */
- }
- }
-
- /* Let our peer know our state. */
-#ifdef CK_AUTODL
- if (is_tn && TELOPT_ME(TELOPT_KERMIT)
-#ifdef OS2
- && !viewonly
-#endif /* OS2 */
- ) {
- if (autodl && !TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_START); /* Send Kermit-Server Start */
- } else if (!autodl && TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_STOP);
- }
- }
-#else /* CK_AUTODL */
- if (is_tn && TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
- tn_siks(KERMIT_STOP);
-#endif /* CK_AUTODL */
-#endif /* IKS_OPTION */
-
- debug(F101,"doconect flow","",flow);
-#ifdef OS2
- debug(F101,"doconect async","",async);
-#ifdef KUI
- if (kui_async)
- async = 1;;
-#endif /* KUI */
- x = conect(async); /* Connect the first time */
-#else /* OS2 */
- x = conect();
-#endif /* OS2 */
- debok = 1;
-
-#ifdef IKS_OPTION
- if (TELOPT_U(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start &&
- !tcp_incoming && !quiet && ttchk() >= 0
- ) {
- printf("\r\nEnter Client/Server Mode... Use:\r\n\r\n");
- printf(
-" REMOTE LOGIN <user> <password> to log in to the server if necessary.\r\n");
- printf(" SEND and GET for file transfer.\r\n");
- printf(" REMOTE commands for file management.\r\n");
- printf(" FINISH to terminate Client/Server mode.\r\n");
- printf(" BYE to terminate and close connection.\r\n");
- printf(" REMOTE HELP for additional information.\r\n\r\n");
- }
-#endif /* IKS_OPTION */
-
- quiet = qsave; /* Restore "quiet" value */
- debug(F101,"doconect justone 2","",justone);
-
-#ifdef NETCONN
- if (network && tn_exit && ttchk() < 0)
- doexit(GOOD_EXIT,xitsta); /* Exit with good status */
-#endif /* NETCONN */
-
-#ifdef OS2ORUNIX
- /* Exit on disconnect if the port is not open or carrier detect */
- if (exitonclose && (ttchk() < 0))
- doexit(GOOD_EXIT,xitsta);
-#endif /* OS2ORUNIX */
-
-#ifdef CKCONINTB4CB
- /* The order makes a difference in HP-UX 8.00. */
- /* The other order makes it think it's in the background when it */
- /* returns from CONNECT (Apr 1999). */
- setint();
- concb((char)escape); /* Restore console for commands */
-#else
- /* This is how it has always been so better leave it */
- /* this way for all non-HP-UX-8.00 builds. */
- concb((char)escape); /* Restore console for commands */
- setint();
-#endif /* CKCONINTB4CB */
-
-#ifdef OS2
- if (!async) {
- term_io_save = term_io; /* Disable I/O by emulator */
- term_io = 0;
-#endif /* OS2 */
-
-#ifdef CK_APC
-/*
- If an APC command was received during CONNECT mode, we define it now
- as a macro, execute the macro, and then return to CONNECT mode.
- We do this in a WHILE loop in case additional APCs come during subsequent
- CONNECT sessions.
-*/
- debug(F101,"doconect apcactive","",apcactive);
- debug(F101,"doconect success","",success);
-
- while (x > 0 && (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && apcstatus != APC_OFF))) {
- debug(F101,"doconect justone 3","",justone);
- if (mlook(mactab,"_apc_commands",nmac) == -1) {
- debug(F110,"doconect about to execute APC",apcbuf,0);
- domac("_apc_commands",apcbuf,cmdstk[cmdlvl].ccflgs|CF_APC);
- delmac("_apc_commands",1);
-#ifdef DEBUG
- } else {
- debug(F100,"doconect APC in progress","",0);
-#endif /* DEBUG */
- }
- debug(F101,"doconect apcactive after domac","",apcactive);
- if (!apcactive) { /* In case CLEAR APC was in APC */
- debug(F101,"doconect quit APC loop: apcactive","",apcactive);
- break;
- }
- /* Also don't reconnect if autodownload failed - very confusing! */
- /* Let them view the local screen to see what happened. - fdc */
-
- /* This should be conditional. If someone is relying on the */
- /* connect mode autodownload for the kermit server to use with */
- /* a remotely executed script we should be able to return to */
- /* connect mode on the failure. What we really need to do is */
- /* report the status of the transfer and then return to CONNECT. */
- /* In unix this would simply be a printf(), but in K95 it could */
- /* use a popup dialog to report the status. - Jeff */
-
-#ifndef NOXFER
- debug(F101,"doconect xferstat","",xferstat);
- if (apcactive == APC_LOCAL && !xferstat && adl_err != 0) {
- debug(F101,"doconect quit APC loop: xferstat","",xferstat);
- apcactive = APC_INACTIVE;
- break;
- }
-#endif /* NOXFER */
-#ifdef OS2
- msleep(250);
-#endif /* OS2 */
- debug(F101,"doconect justone 4","",justone);
- qsave = quiet; /* Do this again... */
- if (!quiet && q > -1)
- quiet = q;
-#ifdef CK_AUTODL
- ksbuf[0] = NUL;
-#endif /* CK_AUTODL */
-#ifdef IKS_OPTION
-#ifdef CK_AUTODL
- if (is_tn &&
- TELOPT_ME(TELOPT_KERMIT) &&
- !TELOPT_SB(TELOPT_KERMIT).kermit.me_start &&
- autodl
-#ifdef CK_APC
- && !apcactive
-#endif /* CK_APC */
-#ifdef OS2
- && !viewonly
-#endif /* OS2 */
- ) {
- tn_siks(KERMIT_START); /* Send Kermit-Server Start */
- }
-#endif /* CK_AUTODL */
-#endif /* IKS_OPTION */
-#ifndef OS2
- x = conect(); /* Re-CONNECT. */
-#else /* OS2 */
- x = conect(0);
- term_io = term_io_save;
-#endif /* OS2 */
- debok = 1;
- quiet = qsave;
- debug(F101,"doconect justone 5","",justone);
-#ifdef NETCONN
- if (network && ttchk() < 0) {
- if (tn_exit || exitonclose)
- doexit(GOOD_EXIT,xitsta);
- else
- break;
- }
-#endif /* NETCONN */
-
-#ifdef OS2ORUNIX
- /* If connection dropped */
- if (ttchk() < 0) {
- concb((char)escape); /* Restore console. */
- if (exitonclose)
- doexit(GOOD_EXIT,xitsta);
- else
- break;
- }
-#endif /* OS2ORUNIX */
- } /* Loop back for more. */
-#endif /* CK_APC */
-
-#ifndef NOKVERBS
- if ((keymac > 0) && (keymacx > -1)) { /* Executing a keyboard macro? */
- /* Set up the macro and return */
- /* Do not clear the keymac flag */
-#ifdef OS2
- term_io = term_io_save;
-#endif /* OS2 */
- return(dodo(keymacx,NULL,CF_KMAC|cmdstk[cmdlvl].ccflgs));
- }
-#endif /* NOKVERBS */
-#ifdef OS2
- term_io = term_io_save;
- } /* if (!async) */
-#endif /* OS2 */
-
-#ifdef CKCONINTB4CB
- /* The order makes a difference in HP-UX 8.00. */
- /* The other order makes it think it's in the background when it */
- /* returns from CONNECT (Apr 1999). */
- setint();
- concb((char)escape); /* Restore console for commands */
-#else
- /* This is how it has always been so better leave it */
- /* this way for all non-HP-UX-8.00 builds. */
- concb((char)escape); /* Restore console for commands */
- setint();
-#endif /* CKCONINTB4CB */
-#ifdef OS2
- if (!async)
-#endif /* OS2 */
- what = W_COMMAND; /* Back in command mode. */
- return(x); /* Done. */
-}
-#endif /* NOLOCAL */
-
-#ifndef NOICP
-#ifdef COMMENT
-/*
- It seemed that this was needed for OS/2, in which \v(cmdfile) and other
- file-oriented variables or functions can return filenames containing
- backslashes, which are subsequently interpreted as quotes rather than
- directory separators (e.g. see commented section for VN_CMDF below).
- But the problem can't be cured at this level. Example:
-
- type \v(cmdfile)
-
- Without doubling, the filename is parsed correctly, but then when passed
- to UNIX 'cat' through the shell, the backslash is removed, and then cat
- can't open the file. With doubling, the filename is not parsed correctly
- and the TYPE command fails immediately with a "file not found" error.
-*/
-/*
- Utility routine to double all backslashes in a string.
- s1 is pointer to source string, s2 is pointer to destination string,
- n is length of destination string, both NUL-terminated.
- Returns 0 if OK, -1 if not OK (destination string too short).
-*/
-int
-dblbs(s1,s2,n) char *s1, *s2; int n; {
- int i = 0;
- while (*s1) {
- if (*s1 == '\\') {
- if (++i > n) return(-1);
- *s2++ = '\\';
- }
- if (++i > n) return(-1);
- *s2++ = *s1++;
- }
- *s2 = NUL;
- return(0);
-}
-#endif /* COMMENT */
-
-char *
-gmdmtyp() { /* Get modem type */
-#ifndef NODIAL
- int i, x;
-
- debug(F111,"gmdmtyp","mdmtyp",mdmtyp);
- debug(F111,"gmdmtyp","mdmsav",mdmsav);
-
- x = mdmtyp;
- if (x < 0) /* In case of network dialing */
- x = mdmsav;
- if (x < 1)
- return("none");
- else
- for (i = 0; i < nmdm; i++)
- if ((mdmtab[i].kwval == x) && (mdmtab[i].flgs == 0))
- return(mdmtab[i].kwd);
-#endif /* NODIAL */
- return("none");
-}
-
-#ifndef NOXMIT
-#ifndef NOLOCAL
-/* T R A N S M I T -- Raw upload */
-
-/* Obey current line, duplex, parity, flow, text/binary settings. */
-/* Returns 0 upon apparent success, 1 on obvious failure. */
-
-/***
- Things to add:
- . Make both text and binary mode obey set file bytesize.
- . Maybe allow user to specify terminators other than CR?
- . Maybe allow user to specify prompts other than single characters?
- . Make STATISTICS also work for TRANSMIT.
- . If TRANSMIT is done without echo, make some kind of (optional) display.
- . Make the same optimization for binary-mode transmit that was done for
- text-mode (in the no-echo / no-prompt / no-pause case).
-***/
-
-/* T R A N S M I T -- Raw upload */
-
-/* s is the filename, t is the turnaround (prompt) character */
-
-/*
- Maximum number of characters to buffer.
- Must be less than LINBUFSIZ
-*/
-#ifdef OS2
-#define XMBUFS 4096 /* For compatibility with XYZmodem */
-#else /* OS2 */
-#define XMBUFS 1024
-#endif /* OS2 */
-
-#ifdef TNCODE
-#ifndef IAC
-#define IAC 255
-#endif /* IAC */
-#endif /* TNCODE */
-
-#define OUTXBUFSIZ 15
-static CHAR inxbuf[OUTXBUFSIZ+1]; /* Host-to-screen expansion buffer */
-static int inxcount = 0; /* and count */
-static CHAR outxbuf[OUTXBUFSIZ+1]; /* Keyboard-to-host expansion buf */
-static int outxcount = 0; /* and count */
-
-/* T R A N S M I T -- Unguarded non-protocol file transmission */
-/*
- Call with:
- char * s: Name of file to transmit.
- char t: Turnaround char for text-mode transmission (normally LF).
- int xlate: nonzero = charset translation for text-mode xfer, 0 = skip.
- int binary: nonzero = transmit in binary mode, 0 = in text mode.
-*/
-#define XBBUFSIZ 508 /* For binary blasting */
-static CHAR xbbuf[XBBUFSIZ+4];
-
-int
-#ifdef CK_ANSIC
-transmit(char * s, char t, int xlate, int binary, int xxecho)
-#else
-transmit(s,t,xlate,binary,xxecho) char *s; char t; int xlate, binary, xxecho;
-#endif /* CK_ANSIC */
-/* transmit */ {
-#ifdef MAC
- extern char sstate;
- int count = 100;
-#else
- int count = 0;
-#ifdef OS2
-#ifdef NT
- SIGTYP (* oldsig)(int); /* For saving old interrupt trap. */
-#else /* NT */
- SIGTYP (* volatile oldsig)(int);
-#endif /* NT */
-
-#else /* OS2 */
- SIGTYP (* oldsig)();
-#endif /* OS2 */
-#endif /* MAC */
- int eof = 0; /* End of File flag */
- int eol = 0; /* End of Line flag */
- int rc = 1; /* Return code. 0=fail, 1=succeed. */
- int myflow; /* Local copy of global flow... */
- int is_tn = 0; /* Do Telnet negotiations */
- int xbufsiz = XMBUFS; /* Size of TRANSMIT buffer */
- int x, y, c, i; /* Int workers... */
- int control = 0; /* Echo loop control */
- long nbytes = 0; /* File byte count */
- long zz; /* Long worker */
- char *p; /* Char * worker */
-
-#ifdef PIPESEND
- extern int pipesend;
-#endif /* PIPESEND */
-
-#ifndef NOCSETS
- int tcs = TC_TRANSP; /* Intermediate (xfer) char set */
- int langsv = L_USASCII; /* Save current language */
- int unicode = 0;
- int tcssize = 0;
-
-#ifdef CK_ANSIC /* ANSI C prototypes... */
- CHAR (*sxo)(CHAR);
- CHAR (*rxo)(CHAR);
- CHAR (*sxi)(CHAR);
- CHAR (*rxi)(CHAR);
-#else /* Not ANSI C... */
- CHAR (*sxo)();
- CHAR (*rxo)();
- CHAR (*sxi)();
- CHAR (*rxi)();
-#endif /* CK_ANSIC */
-#ifdef UNICODE
- union ck_short uc;
- int bomorder = 0;
-#ifdef CK_ANSIC
- extern int (*xl_ufc[MAXFCSETS+1])(USHORT); /* Unicode to FCS */
- extern USHORT (*xl_fcu[MAXFCSETS+1])(CHAR); /* FCS to Unicode */
- extern int (*xuf)(USHORT);
- extern USHORT (*xfu)(CHAR);
-#else
- extern int (*xl_ufc[MAXFCSETS+1])();
- extern USHORT (*xl_fcu[MAXFCSETS+1])();
- extern int (*xuf)();
- extern USHORT (*xfu)();
-#endif /* CK_ANSIC */
-#endif /* UNICODE */
-#endif /* NOCSETS */
-
- debug(F101,"xmit t","",t);
- debug(F101,"xmit xlate","",xlate);
- debug(F101,"xmit binary","",binary);
-
-#ifdef PIPESEND
- if (pipesend) {
- if (nopush) return(-2);
- if (zxcmd(ZIFILE,s) < 1) {
- printf("?Can't start command: %s\n",s);
- return(0);
- }
- } else
-#endif /* PIPESEND */
- if (zopeni(ZIFILE,s) == 0) { /* Open the file to be transmitted */
- printf("?Can't open file %s\n",s);
- return(0);
- }
- x = -1; /* Open the communication channel */
- if (ttopen(ttname,&x,mdmtyp,cdtimo) < 0) { /* (no harm if already open) */
- printf("Can't open device %s\n",ttname);
- return(0);
- }
- zz = x ? speed : -1L;
- if (binary) { /* Binary file transmission */
- myflow = (flow == FLO_XONX) ? FLO_NONE : flow;
-
- if (ttvt(zz,myflow) < 0) { /* So no Xon/Xoff! */
- printf("Can't condition line\n");
- return(0);
- }
- } else {
- if (ttpkt(zz,flow,parity) < 0) { /* Put the line in "packet mode" */
- printf("Can't condition line\n"); /* so Xon/Xoff will work, etc. */
- return(0);
- }
- }
- is_tn =
-#ifdef TNCODE
- (local && network && IS_TELNET()) || (!local && sstelnet)
-#else
- 0
-#endif /* TNCODE */
- ;
-
-#ifndef NOCSETS
-/* Set up character set translations */
-
- tcs = 0; /* "Transfer" or "Other" charset */
- sxo = rxo = NULL; /* Initialize byte-to-byte functions */
- sxi = rxi = NULL;
- unicode = 0; /* Assume Unicode won't be involved */
- if (!binary && xlate) { /* Set up charset translations */
-/*
- In the SENDING direction, we are converting from the local file's
- character-set (fcharset) to the remote terminal charset (tcsr). In the
- RECEIVING direction (echoing) we are converting from the remote end of the
- terminal charset (tcsr) to its local end (tcsl), which is not necessarily
- the same as the file character-set. Especially when the file character
- set is UCS-2, which is not a valid terminal character set. The various
- combinations are represented in this table:
-
- FCS = File Character Set
- RCS = Remote Terminal Character Set
- CCS = Console (Local Terminal) Character Set
-
- 8 4 2 1
- FCS FCS RCS CCS
- UCS UTF UTF UTF
- 0 0 0 0 = 0 = No translation
- 0 0 0 1 = 1 = FCS -> RCS, Echo RCS -> UTF
- 0 0 1 0 = 2 = FCS -> UTF, Echo UTF -> CCS
- 0 0 1 1 = 3 = FCS -> UTF, Echo no translation
-
- 0 1 0 0 = 4 = UTF -> RCS, Echo RCS -> CCS
- 0 1 0 1 = 5 = UTF -> RCS, Echo RCS -> UTF
- 0 1 1 0 = 6 = UTF -> UTF, Echo UTF -> CCS
- 0 1 1 1 = 7 = No translation
-
- 1 0 0 0 = 8 = UCS -> RCS, Echo RCS -> CCS
- 1 0 0 1 = 9 = UCS -> RCS, Echo RCS -> UTF
- 1 0 1 0 = 10 = UCS -> UTF, Echo UTF -> CCS
- 1 0 1 1 = 11 = UCS -> UTF, Echo no translation
-*/
-#ifdef UNICODE
- xfu = NULL; /* Unicode translation functions */
- xuf = NULL;
- bomorder = ucsorder; /* UCS-2 byte order */
-
- if (fcharset == FC_UCS2) /* File charset is UCS-2 */
- unicode |= 8;
- else if (fcharset == FC_UTF8) /* File charset is UTF-8 */
- unicode |= 4;
- if (tcsr == FC_UTF8) /* Remote term charset is UTF-8 */
- unicode |= 2;
- if (tcsl == FC_UTF8) /* Local term charset is UTF-8 */
- unicode |= 1;
-#endif /* UNICODE */
-/*
- When Unicode not involved -- TCS is the intermediate (xfer) set, and:
- sxo = File-to-Intermediate charset function
- rxo = Intermediate-to-Remote-Terminal charset function
- sxi = Remote-Terminal-to-Intermediate
- rxi = Intermediate-to-Local-Terminal
-*/
- tcs = gettcs(tcsr,fcharset); /* Get intermediate set. */
- sxo = xls[tcs][fcharset]; /* translation function */
- rxo = xlr[tcs][tcsr]; /* pointers for output functions */
- sxi = xls[tcs][tcsr]; /* and for input functions. */
- rxi = xlr[tcs][tcsl];
-/*
- At this point we have unicode nonzero if Unicode is involved in the
- conversion, and to 0 if it is not.
- The following is to prevent use of zmstuff() and zdstuff() by translation
- functions (stuffing works with file i/o, not with communication i/o).
-*/
- langsv = language; /* Save current SET LANGUAGE */
- language = L_USASCII; /* No language-specific translations */
- }
-#endif /* NOCSETS */
-
- i = 0; /* Beginning of buffer. */
-#ifndef MAC
-#ifndef AMIGA
- oldsig = signal(SIGINT, trtrap); /* Save current interrupt trap. */
-#endif /* AMIGA */
-#endif /* MAC */
- tr_int = 0; /* Have not been interrupted (yet). */
- rc = 1; /* Return code presumed good. */
-#ifdef VMS
- conres();
-#endif /* VMS */
-
-#ifndef NOCSETS
- debug(F101,"XMIT unicode","",unicode);
-#ifdef UNICODE
- debug(F101,"XMIT bomorder","",bomorder);
-#endif /* UNICODE */
-#endif /* NOCSETS */
-
- c = 0; /* Initial condition */
- while (c > -1 && !eof) { /* Loop for all characters in file */
- eol = 0;
-#ifdef MAC
- /*
- * It is expensive to run the miniparser so don't do it for
- * every character.
- */
- if (--count < 0) {
- count = 100;
- miniparser(1);
- if (sstate == 'a') {
- sstate = '\0';
- goto xmitfail;
- }
- }
-#else /* Not MAC */
- if (tr_int) { /* Interrupted? */
- printf("^C...\n"); /* Print message */
- goto xmitfail;
- }
-#endif /* MAC */
- c = zminchar(); /* Get a file character */
-#ifdef COMMENT
-/* too much */
-#ifdef DEBUG
- if (deblog) {
- if (c < 0)
- debug(F101,"XMIT zminchar","",c);
- else
- debug(F000,"XMIT zminchar","",c);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- if (c < -1) { /* Other error */
- printf("?TRANSMIT file read error: %s\n",ck_errstr());
- goto xmitfail;
- } else if (c > -1) {
- nbytes++;
- c &= fmask; /* Apply SET FILE BYTESIZE mask */
- } else if (c == -1) {
- eof = 1;
- debug(F101,"XMIT eof","",eof);
- }
- if (binary) { /* Binary... */
- if (c == -1) { /* If EOF */
- rc = 1; /* Success */
- eof = 1;
- goto xmitexit; /* Done */
- }
- if (!xmitw && !xxecho) { /* Special "blast" mode */
- if (count == XBBUFSIZ) { /* File input buffer full... */
- while (count > 0) {
- errno = 0;
- y = ttol(xbbuf,count);
- if (y < 0) { /* try to send it. */
- printf("?TRANSMIT output error: %s\n",
- ck_errstr());
- debug(F111,"XMIT binary ttol error",
- ck_errstr(),errno);
- rc = 0;
- break;
- }
- if (y < 0) break;
- count -= y;
- }
- count = 0;
- }
- xbbuf[count++] = c;
-#ifdef TNCODE
- if (c == IAC && is_tn) /* Telnet IAC */
- xbbuf[count++] = IAC; /* must be doubled */
-#endif /* TNCODE */
- continue;
- }
- if (ttoc(dopar((char) c)) < 0) { /* else just send the char */
- printf("?Can't transmit character\n");
- goto xmitfail;
- }
-#ifdef TNCODE
- if (c == IAC && is_tn) /* Quote Telnet IAC */
- ttoc((char)IAC);
-#endif /* TNCODE */
-
- if (xmitw) /* Pause if requested */
- msleep(xmitw);
-
- if (xxecho) { /* SET TRANSMIT ECHO ON? */
- if (duplex) { /* Yes, for half duplex */
-#ifndef NOLOCAL
-#ifdef OS2
- /* Echo to emulator */
- scriptwrtbuf((USHORT)(c & cmdmsk));
-#endif /* OS2 */
-#endif /* NOLOCAL */
- if (conoc((char)(c & cmdmsk)) < 0) /* echo locally. */
- goto xmitfail;
- } else { /* For full duplex, */
- int i, n; /* display whatever is there. */
- n = ttchk(); /* See how many chars are waiting */
- if (n < 0) { /* Connection dropped? */
- printf("?Connection lost\n");
- goto xmitfail;
- }
- for (i = 0; i < n; i++) { /* Read and echo that many. */
- x = ttinc(xmitt); /* Timed read just in case. */
- if (x > -1) { /* If no timeout */
- if (parity) x &= 0x7f; /* display the char, */
-#ifndef NOLOCAL
-#ifdef OS2
- /* Echo to emulator */
- scriptwrtbuf((USHORT)x);
-#endif /* OS2 */
-#endif /* NOLOCAL */
- if (conoc((char)(x & cmdmsk)) < 0) {
- printf("?Output error\n");
- goto xmitfail;
- }
- } else if (x == -2) {
- printf("Connection closed.\n");
- ttclos(1);
- goto xmitfail;
- } else if (x == -3) {
- printf(
- "Session Limit exceeded - closing connection.\n"
- );
- ttclos(1);
- goto xmitfail;
- } else {
- printf("?Communications error\n");
- goto xmitfail;
- }
- }
- }
- } else ttflui(); /* Not echoing, just flush input. */
-
- } else { /* Text mode, line at a time. */
-#ifdef UNICODE
- if (fcharset == FC_UCS2 && xlate) { /* Special for UCS-2 */
- char xbuf[8];
- x = 1 - (nbytes & 1); /* Odd or even byte */
- if (x == 0) /* Note: 1 = the 1st, 0 = 2nd, etc */
- uc.x_short = 0;
- if (bomorder) /* Little Endian */
- x = 1 - x; /* Save byte in appropriate half */
- debug(F101,"XMIT UCS2 x","",x);
- uc.x_char[x] = (CHAR) (c & 0xff);
- if (nbytes & 1) /* First byte, go back for next */
- continue;
- if (nbytes == 2) { /* UCS-2 Byte Order Mark */
- if (uc.x_short == (USHORT) 0xfeff) {
- debug(F100,"XMIT UCS2 BOM FEFF","",bomorder);
- continue;
- } else if (uc.x_short == (USHORT) 0xfffe) {
- bomorder = 1 - bomorder;
- debug(F100,"XMIT UCS2 BOM FFFE (swap)","",bomorder);
- continue;
- }
- }
- sprintf(xbuf,"%04X",uc.x_short); /* SAFE */
- debug(F111,"XMIT UCS2",xbuf,uc.x_short);
- if (nbytes & 1) /* Special eol test for UCS-2 */
- if (uc.x_short == '\n')
- eol = 1;
-#ifdef COMMENT
- if (uc.x_short == 0x2028 || uc.x_short == 0x2029)
- eol = 1;
-#endif /* COMMENT */
- } else
-#endif /* UNICODE */
- if (c == '\n') { /* Normal eol test otherwise */
- eol = 1;
- }
- if (eol) { /* End of line? */
- int stuff = -1;
- debug(F101,"XMIT eol length","",i);
- if (i == 0) { /* Blank line? */
- if (xmitf) /* Yes, insert fill if asked. */
- line[i++] = dopar((char) xmitf);
- }
- if (i == 0 || ((char) line[i-1]) != ((char) dopar(CR)))
- line[i++] = dopar(CR); /* Terminate it with CR */
- if (xmitl) {
- stuff = LF;
-#ifdef TNCODE
- } else if (is_tn && (tn_nlm != TNL_CR)) {
- /* TELNET NEWLINE ON/OFF/RAW */
- stuff = (tn_nlm == TNL_CRLF) ? LF : NUL;
-#endif /* TNCODE */
- }
- if (stuff > -1)
- line[i++] = dopar((char)stuff);
- line[i] = NUL;
- debug(F111,"XMIT eol line",line,i);
-
- } else if (c != -1) { /* Not a newline, regular character */
- int k, x;
- outxbuf[0] = c; /* In case of no translation */
- outxcount = 1; /* Assume result is one byte */
-#ifndef NOCSETS
- switch (unicode) {
- case 0: /* No Unicode involved */
- case 1:
- if (xlate) { /* If not /TRANSPARENT */
- /* Local-to-intermediate */
- if (sxo) c = (*sxo)((char)c);
- /* Intermediate-to-remote */
- if (rxo) c = (*rxo)((char)c);
- outxbuf[0] = c;
- }
- break;
-#ifdef UNICODE
- case 2: /* Local byte to UTF-8 */
- case 3:
- xfu = xl_fcu[fcharset];
- tcssize = fcsinfo[fcharset].size;
- outxcount =
- b_to_u((CHAR)c,outxbuf,OUTXBUFSIZ,tcssize);
- break;
- case 4: /* Local UTF-8 to remote byte */
- case 5:
- xuf = xl_ufc[tcsr];
- x = u_to_b((CHAR)c); /* Convert to byte */
- if (x == -1) { /* If more input bytes needed */
- continue; /* go back and get them */
- } else if (x == -2) { /* LS or PS (shouldn't happen) */
- outxbuf[0] = CR;
- } else if (x == -9) { /* UTF-8 error */
- outxbuf[0] = '?'; /* Insert error char */
- outxbuf[1] = u_to_b2(); /* Insert next char */
- outxcount = 2;
- } else {
- outxbuf[0] = /* Otherwise store result */
- (unsigned)(x & 0xff);
- }
- break;
- case 6: /* UTF-8 to UTF-8 */
- case 7:
- break;
- case 8: /* UCS-2 to byte */
- case 9:
- xuf = xl_ufc[tcsr];
- outxbuf[0] = (*xuf)(uc.x_short);
- break;
- case 10:
- case 11: { /* UCS-2 to UTF-8 */
- int j;
- CHAR * buf = NULL;
- x = ucs2_to_utf8(uc.x_short,&buf);
- if (x < 0) {
- outxbuf[0] = 0xff; /* (= U+FFFD) */
- outxbuf[1] = 0xbd;
- x = 2;
- }
- for (j = 0; j < x; j++)
- outxbuf[j] = buf[j];
- outxcount = x;
- break;
- }
-#endif /* UNICODE */
- }
-#endif /* NOCSETS */
- outxbuf[outxcount] = NUL;
- debug(F111,"XMIT outxbuf",outxbuf,outxcount);
-/*
- Now the input character (1 or more bytes) is translated into the output
- expansion buffer (1 or more bytes); outxcount = number of bytes to add to
- the TRANSMIT line buffer, which we do here, taking care of parity, SI/SO
- processing, and quoting Telnet IACs.
-*/
- for (k = 0; k < outxcount; k++) {
- c = outxbuf[k];
- if (xmits && parity && (c & 0200)) { /* If shifting */
- line[i++] = dopar(SO); /* needs to be done, */
- line[i++] = dopar((char)c); /* do it here, */
- line[i++] = dopar(SI); /* crudely. */
- } else {
- line[i++] = dopar((char)c);
-#ifdef TNCODE
- if (c == (CHAR)IAC && is_tn)
- line[i++] = (CHAR)IAC;
-#endif /* TNCODE */
- }
- }
- }
-/*
- Send characters if buffer full, or at end of line, or at end of file.
- (End of line only if echoing, waiting for a prompt, or pausing.)
-*/
- debug(F000,"XMIT c",ckitoa(i),c);
- if (i >= xbufsiz || eof || (eol && (xxecho || xmitw || t))) {
- p = line;
- line[i] = '\0';
- debug(F111,"transmit buf",p,i);
- if (ttol((CHAR *)p,i) < 0) { /* try to send it. */
- printf("?TRANSMIT output error: %s\n",ck_errstr());
- rc = 0;
- break;
- }
- i = 0; /* Reset buffer pointer. */
-/*
- Now we handle the echo. If the user wants to see it, or if we have to
- wait for the turnaround character, t. If the echo is being displayed,
- and terminal character-set translation is required, we do it here.
-*/
- if (duplex && xxecho) { /* If local echo, echo it */
- if (parity || cmdmsk == 0x7f) { /* Strip hi bits */
- char *ss = line; /* if necessary */
- while (*ss) {
- *ss &= 0x7f;
- ss++;
- }
- }
-#ifndef NOLOCAL
-#ifdef OS2
- { /* Echo to emulator */
- char *ss = p;
- while (*ss) {
- scriptwrtbuf((USHORT)*ss);
- ss++;
- }
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
- if (conoll(p) < 0)
- goto xmitfail;
- }
- if (xmitw) /* Sleep TRANSMIT PAUSE interval */
- msleep(xmitw);
-
- control = 0; /* Readback loop control */
- if (t != 0 && eol) /* TRANSMIT PROMPT given and at EOL */
- control |= 1;
- if (xxecho && !duplex) /* Echo desired and is remote */
- control |= 2;
-
- if (control) { /* Do this if reading back the echo */
- int n;
- x = 0;
- while (1) {
- if (control & 1) { /* Termination criterion */
- if (x == t) /* for turnaround */
- break;
- } else if (control & 2) { /* And for echoing */
- if ((n = ttchk()) < 1)
- break;
- }
- if ((x = ttinc(xmitt)) < 0) { /* Read with timeout */
- switch (x) {
- case -2:
- printf("Connection closed.\n");
- ttclos(1);
- goto xmitfail;
- case -3:
- printf(
- "Session Limit exceeded - closing connection.\n"
- );
- ttclos(1); /* full thru... */
- goto xmitfail;
- default:
- printf("?Timeout\n");
- goto xmitfail;
- }
- }
- if (x > -1 && (control & 2)) { /* Echo any echoes */
- if (parity)
- x &= 0x7f;
- c = x;
-#ifndef NOLOCAL
-#ifdef OS2
- scriptwrtbuf((USHORT)x);
-#endif /* OS2 */
-#endif /* NOLOCAL */
- inxbuf[0] = c;
- inxcount = 1;
-#ifndef NOCSETS
- switch (unicode & 3) { /* Remote bits */
- case 0:
- if (xlate) {
- if (sxi) c = (*sxi)((CHAR)c);
- if (rxi) c = (*rxi)((CHAR)c);
- inxbuf[0] = c;
- }
- break;
-#ifdef UNICODE
- case 1: /* Remote Byte to local UTF-8 */
- xfu = xl_fcu[tcsr];
- tcssize = fcsinfo[tcsr].size;
- inxcount =
- b_to_u((CHAR)c,
- inxbuf,
- OUTXBUFSIZ,
- tcssize
- );
- break;
- case 2: /* Remote UTF-8 to local Byte */
- xuf = xl_ufc[tcsl];
- x = u_to_b((CHAR)c);
- if (x < 0)
- continue;
- inxbuf[0] = (unsigned)(x & 0xff);
- break;
- case 3: /* UTF-8 to UTF-8 */
- break;
-#endif /* UNICODE */
- }
-#endif /* NOCSETS */
- inxbuf[inxcount] = NUL;
- if (conxo(inxcount,(char *)inxbuf) < 0)
- goto xmitfail;
- }
- }
- } else /* Not echoing */
- ttflui(); /* Just flush input buffer */
- } /* End of buffer-dumping block */
- } /* End of text mode */
- if (eof) {
- rc = 1;
- goto xmitexit;
- }
- } /* End of character-reading loop */
-
- xmitfail: /* Failure exit point */
- rc = 0;
-
- xmitexit: /* General exit point */
- if (rc > 0) {
- if (binary && !xmitw && !xxecho) { /* "blasting"? */
- while (count > 0) { /* Partial buffer still to go? */
- errno = 0;
- y = ttol(xbbuf,count);
- if (y < 0) {
- printf("?TRANSMIT output error: %s\n",
- ck_errstr());
- debug(F111,"XMIT binary eof ttol error",
- ck_errstr(),errno);
- rc = 0;
- break;
- }
- count -= y;
- }
- } else if (!binary && *xmitbuf) { /* Anything to send at EOF? */
- p = xmitbuf; /* Yes, point to string. */
- while (*p) /* Send it. */
- ttoc(dopar(*p++)); /* Don't worry about echo here. */
- }
- }
-
-#ifndef AMIGA
-#ifndef MAC
- signal(SIGINT,oldsig); /* Put old signal action back. */
-#endif /* MAC */
-#endif /* AMIGA */
-#ifdef VMS
- concb(escape); /* Put terminal back, */
-#endif /* VMS */
- zclose(ZIFILE); /* Close file, */
-#ifndef NOCSETS
- language = langsv; /* restore language, */
-#endif /* NOCSETS */
- ttres(); /* and terminal modes, */
- return(rc); /* and return successfully. */
-}
-#endif /* NOLOCAL */
-#endif /* NOXMIT */
-
-#ifndef NOCSETS
-
-_PROTOTYP( CHAR (*sxx), (CHAR) ); /* Local translation function */
-_PROTOTYP( CHAR (*rxx), (CHAR) ); /* Local translation function */
-_PROTOTYP( CHAR zl1as, (CHAR) ); /* Latin-1 to ascii */
-_PROTOTYP( CHAR xl1as, (CHAR) ); /* ditto */
-
-/* X L A T E -- Translate a local file from one character set to another */
-
-/*
- Translates input file (fin) from character set csin to character set csout
- and puts the result in the output file (fout). The two character sets are
- file character sets from fcstab.
-*/
-
-int
-xlate(fin, fout, csin, csout) char *fin, *fout; int csin, csout; {
-
-#ifndef MAC
-#ifdef OS2
- extern int k95stdout;
- extern int wherex[], wherey[];
- extern unsigned char colorcmd;
-#ifdef NT
- SIGTYP (* oldsig)(int); /* For saving old interrupt trap. */
-#else /* NT */
- SIGTYP (* volatile oldsig)(int); /* For saving old interrupt trap. */
-#endif /* NT */
-#else /* OS2 */
- SIGTYP (* oldsig)();
-#endif /* OS2 */
-#endif /* MAC */
-#ifdef CK_ANSIC
- int (*fn)(char); /* Output function pointer */
-#else
- int (*fn)();
-#endif /* CK_ANSIC */
- extern int xlatype;
- int filecode; /* Code for output file */
- int scrnflg = 0;
-
- int z = 1; /* Return code. */
- int x, c, c2; /* Workers */
-#ifndef UNICODE
- int tcs;
-#endif /* UNICODE */
-
- ffc = 0L;
-
- if (zopeni(ZIFILE,fin) == 0) { /* Open the file to be translated */
-#ifdef COMMENT
- /* An error message was already printed by zopeni() */
- printf("?Can't open input file %s\n",fin);
-#endif /* COMMENT */
- return(0);
- }
-#ifdef MAC
-/*
- If user specified no output file, it goes to the screen. For the Mac,
- this must be done a special way (result goes to a new window); the Mac
- doesn't have a "controlling terminal" device name.
-*/
- filecode = !strcmp(fout,CTTNAM) ? ZCTERM : ZOFILE;
-#else
-#ifdef VMS
- filecode = !strcmp(fout,CTTNAM) ? ZCTERM : ZMFILE;
-#else
-#ifdef OS2
- filecode = (!stricmp(fout,"con") || !stricmp(fout,"con:")) ?
- ZCTERM : ZMFILE;
- if ((filecode == ZCTERM) && !k95stdout && !inserver)
- csout = FC_UCS2;
-#else /* OS2 */
- filecode = ZOFILE;
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* MAC */
- if (zopeno(filecode,fout,NULL,NULL) == 0) { /* And the output file */
- printf("?Can't open output file %s\n",fout);
- return(0);
- }
-#ifndef AMIGA
-#ifndef MAC
- oldsig = signal(SIGINT, trtrap); /* Save current interrupt trap. */
-#endif /* MAC */
-#endif /* AMIGA */
-
- scrnflg = (filecode == ZCTERM); /* Set output function */
- if (scrnflg)
- fn = NULL;
- else if (filecode == ZMFILE)
- fn = putmfil;
- else
- fn = putfil;
-
- tr_int = 0; /* Have not been interrupted (yet). */
- z = 1; /* Return code presumed good. */
-
- if (!scrnflg && !quiet)
- printf(" %s (%s) => %s (%s)\n", /* Say what we're doing. */
- fin, fcsinfo[csin].keyword,
- fout,fcsinfo[csout].keyword
- );
-
-#ifndef UNICODE
-/*
- Non-Unicode picks the "most appropriate" transfer character set as the
- intermediate set, which results in loss of any characters that the source
- and target sets have in common, but are lacking from the intermediate set.
-*/
-#ifdef KANJI
- /* Special handling for Japanese... */
-
- if (fcsinfo[csin].alphabet == AL_JAPAN ||
- fcsinfo[csout].alphabet == AL_JAPAN) {
- USHORT eu;
- int c, x, y;
-
- xpnbyte(-1,0,0,NULL); /* Reset output machine */
- xlatype = XLA_JAPAN;
-
- while ((c = xgnbyte(FC_JEUC,csin,NULL)) > -1) { /* Get an EUC byte */
- if (tr_int) { /* Interrupted? */
- printf("^C...\n"); /* Print message */
- z = 0;
- break;
- }
- /* Send EUC byte to output machine */
- if ((x = xpnbyte(c,TC_JEUC,csout,fn)) < 0) {
- z = -1;
- break;
- }
- }
- goto xxlate;
- }
-#endif /* KANJI */
-
- /* Regular bytewise conversion... */
-
- tcs = gettcs(csin,csout); /* Get intermediate set. */
- if (csin == csout) { /* Input and output sets the same? */
- sxx = rxx = NULL; /* If so, no translation. */
- } else { /* Otherwise, set up */
- if (tcs < 0 || tcs > MAXTCSETS ||
- csin < 0 || csin > MAXFCSETS ||
- csout < 0 || csout > MAXFCSETS) {
- debug(F100,"XLATE csets out of range","",0);
- sxx = rxx = NULL;
- } else {
- sxx = xls[tcs][csin]; /* translation function */
- rxx = xlr[tcs][csout]; /* pointers. */
- if (rxx == zl1as) rxx = xl1as;
- }
- }
- while ((c = zminchar()) != -1) { /* Loop for all characters in file */
- if (tr_int) { /* Interrupted? */
- printf("^C...\n"); /* Print message */
- z = 0;
- break;
- }
- if (sxx) c = (*sxx)((CHAR)c); /* From fcs1 to tcs */
- if (rxx) c = (*rxx)((CHAR)c); /* from tcs to fcs2 */
- if (zchout(filecode,(char)c) < 0) { /* Output xlated character */
- z = -1;
- break;
- }
- }
- goto xxlate; /* Done. */
-
-#else /* UNICODE */
-/*
- Use Unicode as the intermediate character set. It's simple and gives
- little or no loss, but the overhead is a bit higher.
-*/
- initxlate(csin,csout); /* Set up translation functions */
-
- if (xlatype == XLA_NONE) {
- while ((c = zminchar()) != -1) { /* Loop for all characters in file */
- if (tr_int) { /* Interrupted? */
- printf("^C...\n"); /* Print message */
- z = 0;
- break;
- }
- if (zchout(filecode,(char)c) < 0) { /* Output xlated character */
- z = -1;
- break;
- }
- }
- goto xxlate; /* Done. */
- }
-
-
-#ifndef NOLOCAL
-#ifdef OS2
- if (csout == FC_UCS2 && /* we're translating to UCS-2 */
- filecode == ZCTERM && /* for the real screen... */
- !k95stdout && !inserver
- ) {
- union {
- USHORT ucs2;
- UCHAR bytes[2];
- } output;
-
- while (1) { /* In this case we go two-by-two. */
- if ((c = xgnbyte(FC_UCS2,csin,NULL)) < 0)
- break;
- output.bytes[0] = c;
- if ((c = xgnbyte(FC_UCS2,csin,NULL)) < 0)
- break;
- output.bytes[1] = c;
-
- if (tr_int) { /* Interrupted? */
- printf("^C...\n"); /* Print message */
- z = 0;
- break;
- }
-
- VscrnWrtUCS2StrAtt(VCMD,
- &output.ucs2,
- 1,
- wherey[VCMD],
- wherex[VCMD],
- &colorcmd
- );
- }
- } else
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
- /* General case: Get next byte translated from fcs to UCS-2 */
-
-#ifdef COMMENT
- while ((c = xgnbyte(FC_UCS2,csin,NULL)) > -1 &&
- (c2 = xgnbyte(FC_UCS2,csin,NULL)) > -1) {
- extern int fileorder;
-
- if (tr_int) { /* Interrupted? */
- printf("^C...\n"); /* Print message */
- z = 0;
- break;
- }
- debug(F001,"XLATE c","",c);
- debug(F001,"XLATE c2","",c2);
-
- /* And then send UCS-2 byte to translate-and-output machine */
-
- if ((x = xpnbyte(fileorder?c2:c,TC_UCS2,csout,fn)) < 0) {
- z = -1;
- break;
- }
- if ((x = xpnbyte(fileorder?c:c2,TC_UCS2,csout,fn)) < 0) {
- z = -1;
- break;
- }
- }
-#else
- while ((c = xgnbyte(FC_UCS2,csin,NULL)) > -1) {
- if (tr_int) { /* Interrupted? */
- printf("^C...\n"); /* Print message */
- z = 0;
- break;
- }
- if ((x = xpnbyte(c,TC_UCS2,csout,fn)) < 0) {
- z = -1;
- break;
- }
- }
-#endif /* COMMENT */
-
-#endif /* UNICODE */
-
- xxlate: /* Common exit point */
-
-#ifndef AMIGA
-#ifndef MAC
- signal(SIGINT,oldsig); /* Put old signal action back. */
-#endif /* MAC */
-#endif /* AMIGA */
- tr_int = 0;
- if (z < 0) {
- if (z == -1)
- printf("?File output error: %s\n",ck_errstr());
- z = 0;
- }
- zclose(ZIFILE); /* Close files */
- zclose(filecode); /* ... */
- return(success = z); /* and return status. */
-}
-
-int
-doxlate() {
-#ifdef OS2ONLY
- extern int tt_font;
-#endif /* OS2ONLY */
-#ifdef UNIX
- extern char ** mtchs; /* zxpand() file list */
-#endif /* UNIX */
- int x, y, incs, outcs, multiple = 0, wild = 0, fc = 0, len = 0;
- int ofisdir = 0;
- char * s, * tocs = "";
-
- if ((x = cmifi("File(s) to translate","",&s,&wild,xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of an existing file\n");
- return(-9);
- } else
- return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ); /* Save copy of string just parsed. */
-
- if ((incs = cmkey(fcstab,nfilc,"from character-set","",xxstring)) < 0)
- return(incs);
-
-#ifdef OS2
- if (isunicode())
- tocs = "ucs2";
- else
-#endif /* OS2 */
- tocs = getdcset();
-
- if ((outcs = cmkey(fcstab,nfilc,"to character-set",tocs,xxstring)) < 0)
- return(outcs);
- if ((x = cmofi("output file",CTTNAM,&s,xxstring)) < 0) return(x);
- if (x > 1)
- ofisdir = 1;
-
- len = ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
-
- if (len < 1)
- return(-2);
-
- if (ofisdir)
- multiple = 2;
- else if (wild) {
- if (isdir(tmpbuf))
- multiple = 2;
- else if (!strcmp(tmpbuf,CTTNAM))
- multiple = 1;
-#ifdef OS2
- else if (!stricmp(tmpbuf,"con") || !stricmp(tmpbuf,"con:"))
- multiple = 1;
-#else
-#ifdef UNIXOROSK
- else if (!strncmp(tmpbuf,"/dev/",4))
- multiple = 1;
-#endif /* UNIXOROSK */
-#endif /* OS2 */
- if (!multiple) {
- printf("?A single file please\n");
- return(-9);
- }
- }
- if (!multiple) { /* Just one file */
- return(success = xlate(line,tmpbuf,incs,outcs));
- } else { /* Translate multiple files */
- char dirbuf[CKMAXPATH+4];
- int k;
-#ifndef ZXREWIND
- int flags = ZX_FILONLY;
-#endif /* ZXREWIND */
-
- if (multiple == 2) { /* Target is a directory */
- k = ckstrncpy(dirbuf,tmpbuf,CKMAXPATH+1) - 1;
- if (k < 0)
- return(-2);
-#ifdef OS2ORUNIX
- if (dirbuf[k] != '/') {
- dirbuf[k+1] = '/';
- dirbuf[k+2] = NUL;
- }
-#else
-#ifdef OSK
- if (dirbuf[k] != '/') {
- dirbuf[k+1] = '/';
- dirbuf[k+2] = NUL;
- }
-#else
-#ifdef VMS
- if (ckmatch("*.DIR;1",s,0,0))
- k = cvtdir(tmpbuf,dirbuf,TMPBUFSIZ);
- if (dirbuf[k] != ']' &&
- dirbuf[k] != '>' &&
- dirbuf[k] != ':')
- return(-2);
-#else
-#ifdef datageneral
- if (dirbuf[k] != ':') {
- dirbuf[k+1] = ':';
- dirbuf[k+2] = NUL;
- }
-#else
-#ifdef STRATUS
- if (dirbuf[k] != '>') {
- dirbuf[k+1] = '>';
- dirbuf[k+2] = NUL;
- }
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* OSK */
-#endif /* OS2ORUNIX */
- }
-
-#ifdef ZXREWIND
- fc = zxrewind(); /* Rewind the file list */
-#else
- if (matchdot) flags |= ZX_MATCHDOT;
- fc = nzxpand(line,flags);
-#endif /* ZXREWIND */
-
- if (fc < 1) {
- printf("?Wildcard expansion error\n");
- return(-9);
- }
-#ifdef UNIX
- sh_sort(mtchs,NULL,fc,0,0,filecase); /* Sort the file list */
-#endif /* UNIX */
-
- while (1) { /* Loop through the files */
- znext(line);
- if (!line[0])
- break;
- if (multiple == 2)
- ckmakmsg(tmpbuf,TMPBUFSIZ,dirbuf,line,NULL,NULL);
- if (xlate(line,tmpbuf,incs,outcs) < 1)
- return(success = 0);
- }
- }
- return(success = 1);
-}
-#endif /* NOCSETS */
-
-static char hompthbuf[CKMAXPATH+1];
-
-char *
-homepath() {
- int x;
- extern char * myhome;
- char * h;
-
- h = myhome ? myhome : zhome();
- hompthbuf[0] = NUL;
-#ifdef UNIXOROSK
- x = ckstrncpy(hompthbuf,h,CKMAXPATH+1);
- if (x <= 0) {
- hompthbuf[0] = '/';
- hompthbuf[1] = NUL;
- } else if (x < CKMAXPATH - 2 && hompthbuf[x-1] != '/') {
- hompthbuf[x] = '/';
- hompthbuf[x+1] = NUL;
- }
- return(hompthbuf);
-#else
-#ifdef STRATUS
- if (strlen(h) < CKMAXPATH)
- sprintf(hompthbuf,"%s>",h); /* SAFE */
- return(hompthbuf);
-#else
- return(h);
-#endif /* STRATUS */
-#endif /* UNIXOROSK */
-}
-
-/* D O L O G -- Do the log command */
-
-int
-dolog(x) int x; {
- int y, disp; char *s = NULL, * p = NULL, * q = NULL;
- extern int isguest;
-#ifdef ZFNQFP
- struct zfnfp * fnp;
-#endif /* ZFNQFP */
-
- if (isguest) {
- printf("?Anonymous log creation not allowed\n");
- return(-9);
- }
- switch (x) { /* Which log... */
-
-#ifdef DEBUG
- case LOGD:
- q = "debug.log";
- y = cmofi("Name of debugging log file",q,&s,xxstring);
- break;
-#endif /* DEBUG */
-
- case LOGP:
- q = "packet.log";
- y = cmofi("Name of packet log file",q,&s,xxstring);
- break;
-
-#ifndef NOLOCAL
- case LOGS:
- q = "session.log";
- y = cmofi("Name of session log file",q,&s,xxstring);
- break;
-#endif /* NOLOCAL */
-
-#ifdef TLOG
- case LOGT:
- q = "transact.log";
- y = cmofi("Name of transaction log file",q,&s,xxstring);
- break;
-#endif /* TLOG */
-
-#ifdef CKLOGDIAL
- case LOGM: {
- int m, n;
- char mypath[CKMAXPATH+1];
- q = CXLOGFILE;
- m = ckstrncpy(mypath,homepath(),CKMAXPATH);
- n = strlen(CXLOGFILE);
- if (m + n < CKMAXPATH)
- ckstrncat(mypath,CXLOGFILE,CKMAXPATH);
- else
- ckstrncpy(mypath,CXLOGFILE,CKMAXPATH);
- y = cmofi("Name of connection log file",mypath,&s,xxstring);
- break;
- }
-#endif /* CKLOGDIAL */
-
- default:
- printf("\n?Unknown log designator - %d\n",x);
- return(-2);
- }
- if (y < 0) return(y);
- if (y == 2) { /* If they gave a directory name */
- int k;
- char * ds = "/";
- k = strlen(s);
- if (k > 0 && s[k-1] == '/') ds = "";
- ckmakmsg(tmpbuf,TMPBUFSIZ,s,ds,q,NULL);
- s = tmpbuf;
- }
-#ifdef ZFNQFP
-#ifdef OS2ORUNIX
- if (*s != '|') /* Allow for pipes */
-#else
-#ifdef OSK
- if (*s != '|')
-#endif /* OSK */
-#endif /* OS2ORUNIX */
- if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {
- if (fnp->fpath)
- if ((int) strlen(fnp->fpath) > 0)
- s = fnp->fpath;
- } /* else if error keep original string */
-#endif /* ZFNQFP */
-
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
-#ifdef MAC
- y = 0;
-#else
-
- p = "new";
-#ifdef TLOG
- if ((x == LOGT && tlogfmt == 2) || x == LOGM)
- p = "append";
-#endif /* TLOG */
-
- if ((y = cmkey(disptb,2,"Disposition",p,xxstring)) < 0)
- return(y);
-#endif /* MAC */
- disp = y;
- if ((y = cmcfm()) < 0) return(y);
-
- switch (x) {
-
-#ifdef DEBUG
- case LOGD:
- return(deblog = debopn(s,disp));
-#endif /* DEBUG */
-
-#ifndef NOXFER
- case LOGP:
- return(pktlog = pktopn(s,disp));
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
- case LOGS:
- setseslog(sesopn(s,disp));
- return(seslog);
-#endif /* NOLOCAL */
-
-#ifdef TLOG
- case LOGT:
- return(tralog = traopn(s,disp));
-#endif /* TLOG */
-
-#ifdef CKLOGDIAL
- case LOGM:
- return(dialog = diaopn(s,disp,0));
-#endif /* CKLOGDIAL */
-
- default:
- return(-2);
- }
-}
-
-#ifndef NOXFER
-int
-pktopn(s,disp) char *s; int disp; {
- static struct filinfo xx;
-
- if (!s)
- s = "";
- if (!*s)
- return(0);
-
- debug(F111,"pktopn",s,disp);
-
- zclose(ZPFILE);
-
-#ifdef OS2ORUNIX
- if (s[0] == '|') { /* Pipe */
- char * p = s + 1;
- debug(F110,"pktopn p",p,0);
- while (*p) {
- if (*p != ' ')
- break;
- else
- p++;
- }
- debug(F110,"pktopn pipe",p,0);
- pktlog = zxcmd(ZPFILE,p);
- debug(F101,"pktopn seslog","",seslog);
- } else { /* File */
-#endif /* OS2ORUNIX */
- if (disp) {
- xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
- xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = "";
- xx.lblopts = 0;
- pktlog = zopeno(ZPFILE,s,NULL,&xx);
- } else pktlog = zopeno(ZPFILE,s,NULL,NULL);
- if (!pktlog && !quiet)
- printf("?%s - %s\n",s,ck_errstr());
-#ifdef OS2ORUNIX
- }
-#endif /* OS2ORUNIX */
- if (pktlog > 0)
- ckstrncpy(pktfil,s,CKMAXPATH+1);
- else
- *pktfil = '\0';
- return(pktlog);
-}
-#endif /* NOXFER */
-
-int
-traopn(s,disp) char *s; int disp; {
-#ifdef TLOG
- static struct filinfo xx;
-
- if (!s)
- s = "";
- if (!*s)
- return(0);
-
- debug(F111,"traopn",s,disp);
- debug(F101,"traopn tlogfmt","",tlogfmt);
-
- zclose(ZTFILE);
-
-#ifdef OS2ORUNIX
- if (tlogfmt == 2) { /* FTP format is special... */
- VOID doiklog();
- if (!disp) /* Append? */
- if (zchki(s) > -1) /* No - does file exist? */
- (VOID) zdelet(s); /* Yes - delete it. */
- xferlog = 1;
- ckstrncpy(trafil,s,CKMAXPATH);
- makestr(&xferfile,s);
- doiklog();
- return(1);
- }
- if (s[0] == '|') { /* Pipe */
- char * p = s + 1;
- debug(F110,"traopn p",p,0);
- while (*p) {
- if (*p != ' ')
- break;
- else
- p++;
- }
- debug(F110,"traopn pipe",p,0);
- tralog = zxcmd(ZTFILE,p);
- debug(F101,"traopn tralog","",tralog);
- }
-#endif /* OS2ORUNIX */
-
- if (s[0] != '|') { /* File */
- if (disp) {
- xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
- xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = "";
- xx.lblopts = 0;
- tralog = zopeno(ZTFILE,s,NULL,&xx);
- } else tralog = zopeno(ZTFILE,s,NULL,NULL);
- }
- if (!tralog && !quiet)
- printf("?%s - %s\n",s,ck_errstr());
- if (tralog > 0 && tlogfmt > 0) {
- ckstrncpy(trafil,s,CKMAXPATH);
- tlog(F110,"Transaction Log:",versio,0L);
-#ifndef MAC
- tlog(F100,ckxsys,"",0L);
-#endif /* MAC */
- ztime(&s);
- tlog(F100,s,"",0L);
- } else
- *trafil = '\0';
- return(tralog);
-#else
- return(0);
-#endif /* TLOG */
-}
-
-#ifndef NOLOCAL
-int
-sesopn(s,disp) char * s; int disp; {
- static struct filinfo xx;
- extern int tsstate;
-
- tsstate = 0; /* Session log timestamp state */
-
- if (!s)
- s = "";
- if (!*s)
- return(0);
-
- debug(F111,"sesopn",s,disp);
-
- zclose(ZSFILE);
-
-#ifdef OS2ORUNIX
- if (s[0] == '|') { /* Pipe */
- char * p = s + 1;
- debug(F110,"sesopn p",p,0);
- while (*p) {
- if (*p != ' ')
- break;
- else
- p++;
- }
- debug(F110,"sesopn pipe",p,0);
- setseslog(zxcmd(ZSFILE,p));
- debug(F101,"sesopn seslog","",seslog);
- } else { /* File */
-#endif /* OS2ORUNIX */
- if (disp) {
- xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
- xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = "";
- xx.lblopts = 0;
- setseslog(zopeno(ZSFILE,s,NULL,&xx));
- } else
- setseslog(zopeno(ZSFILE,s,NULL,NULL));
- if (!seslog && !quiet)
- printf("?%s - %s\n",s,ck_errstr());
-#ifdef OS2ORUNIX
- }
-#endif /* OS2ORUNIX */
- if (seslog > 0)
- ckstrncpy(sesfil,s,CKMAXPATH+1);
- else
- *sesfil = '\0';
- return(seslog);
-}
-#endif /* NOLOCAL */
-#endif /* NOICP */
-
-int
-debopn(s,disp) char *s; int disp; {
-#ifdef DEBUG
-#ifdef CK_UTSNAME
- extern char unm_mch[], unm_nam[], unm_rel[], unm_ver[], unm_mod[];
-#endif /* CK_UTSNAME */
-#ifdef OS2
- extern char ckxsystem[];
-#endif /* OS2 */
- char *tp;
- static struct filinfo xx;
-
- if (!s)
- s = "";
- if (!*s)
- return(0);
-
- zclose(ZDFILE);
-
-#ifdef OS2ORUNIX
- if (s[0] == '|') { /* Pipe */
- char * p = s + 1;
- debug(F110,"debopn p",p,0);
- while (*p) {
- if (*p != ' ')
- break;
- else
- p++;
- }
- debug(F110,"debopn pipe",p,0);
- deblog = zxcmd(ZDFILE,p);
- debug(F101,"debopn deblog","",deblog);
- } else { /* File */
-#endif /* OS2ORUNIX */
- if (disp) {
- xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
- xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = "";
- xx.lblopts = 0;
- deblog = zopeno(ZDFILE,s,NULL,&xx);
- } else
- deblog = zopeno(ZDFILE,s,NULL,NULL);
- if (!deblog && !quiet)
- printf("?%s - %s\n",s,ck_errstr());
-#ifdef OS2ORUNIX
- }
-#endif /* OS2ORUNIX */
- if (deblog > 0) {
- ckstrncpy(debfil,s,CKMAXPATH+1);
- debug(F110,"Debug Log ",versio,0);
-#ifndef MAC
-#ifdef OS2
- debug(F110,ckxsys,ckxsystem,0);
-#else /* OS2 */
- debug(F100,ckxsys,"",0);
-#endif /* OS2 */
-#endif /* MAC */
-#ifdef CK_UTSNAME
- if (unm_mch[0]) {
- debug(F110,"uname machine",unm_mch,0);
- if (unm_mod[0])
- debug(F110,"uname model ",unm_mod,0);
- debug(F110,"uname sysname",unm_nam,0);
- debug(F110,"uname release",unm_rel,0);
- debug(F110,"uname version",unm_ver,0);
- }
-#ifdef KTARGET
- {
- char * s; /* Makefile target */
- s = KTARGET;
- if (!s) s = "";
- if (!*s) s = "(unknown)";
- debug(F110,"build target",s,0);
- }
-#endif /* KTARGET */
- deblog = 0;
- ztime(&tp);
- deblog = 1;
- debug(F100,tp,"",0);
-#endif /* UTSNAME */
- debug(F101,"byteorder","",byteorder);
-#ifndef NOICP
-#ifndef NOLOCAL
- if (local) {
- debug(F110,"Active connection: ",ttname,0);
- if (!network) {
- debug(F101,"Speed","",speed);
- if (hwparity)
- debug(F110,"Parity[hardware]",parnam((char)hwparity),0);
- else
- debug(F110,"Parity",parnam((char)parity),0);
- deblog = 0;
- debug(F110,"Modem",gmdmtyp(),0);
- deblog = 1;
- }
- } else {
- debug(F110,"Active connection: ","none",0);
- }
-#endif /* NOLOCAL */
-#endif /* NOICP */
- } else *debfil = '\0';
- return(deblog);
-#else
- return(0);
-#endif /* MAC */
-}
-
-
-/* C K D A T E -- Returns current date/time in standard format */
-
-static char nowbuf[18];
-
-char *
-ckdate() {
- extern struct keytab cmonths[];
- int x;
- char * t; /* Substitute today's date */
- char dbuf[32];
- ztime(&t);
-
-/* 012345678901234567890123 */
-/* Sat Jul 4 12:16:43 1998 */
-
- ckstrncpy(dbuf,t,32);
- t = dbuf;
- debug(F110,"ckdate dbuf",dbuf,0);
- nowbuf[0] = t[20];
- nowbuf[1] = t[21];
- nowbuf[2] = t[22];
- nowbuf[3] = t[23];
-
- nowbuf[4] = NUL;
- debug(F110,"ckdate nowbuf",nowbuf,0);
-
- t[7] = NUL;
- if ((x = lookup(cmonths,t+4,12,NULL)) < 0) {
- debug(F110,"ckdate bad month",t,0);
- return("<BAD_MONTH>");
- }
- sprintf(nowbuf+4,"%02d",x); /* SAFE */
- nowbuf[6] = (t[8] == SP) ? '0' : t[8];
- nowbuf[7] = t[9];
- nowbuf[8] = ' ';
-
- nowbuf[9] = NUL;
- debug(F110,"ckdate nowbuf",nowbuf,0);
-
- for (x = 11; x < 19; x++) nowbuf[x-2] = t[x];
- nowbuf[17] = NUL;
- debug(F110,"ckdate nowbuf",nowbuf,0);
-
- return((char *)nowbuf);
-}
-
-#ifndef NOICP
-#ifdef CKLOGDIAL
-
-/*
- fc = 0 for initial open, meaning open, then close immediately.
- fc > 0 for subsequent opens, meaning open for use, leave open.
-*/
-int
-diaopn(s,disp,fc) char *s; int disp, fc; {
- static struct filinfo xx;
-
- if (!s)
- s = "";
- if (!*s)
- return(0);
-
- debug(F110,"diaopn log",s,0);
- debug(F101,"diaopn fc",s,fc);
- debug(F101,"diaopn disp 1",s,disp);
- if (fc) disp = 1; /* Force append if open for use */
- debug(F101,"diaopn disp 2",s,disp);
-
- zclose(ZDIFIL); /* In case a log was already open */
-
-#ifdef OS2ORUNIX
- if (s[0] == '|') { /* Pipe */
- char * p = s + 1;
- debug(F110,"diaopn p",p,0);
- while (*p) {
- if (*p != ' ')
- break;
- else
- p++;
- }
- debug(F110,"diaopn pipe",p,0);
- dialog = zxcmd(ZDIFIL,p);
- debug(F101,"diaopn dialog","",dialog);
- } else { /* File */
-#endif /* OS2ORUNIX */
- if (disp) {
- xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
- xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = "";
- xx.lblopts = 0;
- dialog = zopeno(ZDIFIL,s,NULL,&xx);
- } else dialog = zopeno(ZDIFIL,s,NULL,NULL);
- if (!dialog)
- printf("?%s - %s\n",s,ck_errstr());
-#ifdef OS2ORUNIX
- }
-#endif /* OS2ORUNIX */
- if (dialog > 0)
- ckstrncpy(diafil,s,CKMAXPATH+1);
- else
- *diafil = '\0';
- if (fc == 0) /* Initial open */
- zclose(ZDIFIL); /* close it */
- return(dialog);
-}
-#endif /* CKLOGDIAL */
-
-#ifndef NOSHOW
-
-/* SHOW command routines */
-
-char *
-shoxm() {
- char * s;
- switch (binary) {
- case XYFT_T: s = "text"; break;
-#ifdef VMS
- case XYFT_B: s = "binary fixed"; break;
- case XYFT_I: s = "image"; break;
- case XYFT_L: s = "labeled"; break;
- case XYFT_U: s = "binary undef"; break;
-#else
-#ifdef MAC
- case XYFT_B: s = "binary"; break;
- case XYFT_M: s = "macbinary"; break;
-#else
- case XYFT_B: s = "binary"; break;
-#ifdef CK_LABELED
- case XYFT_L: s = "labeled"; break;
-#endif /* CK_LABELED */
-#endif /* MAC */
-#endif /* VMS */
- default: s = "unknown"; break;
- }
- return(s);
-}
-
-#ifndef NOXFER
-VOID /* SHOW TRANSFER */
-shoxfer() {
- extern int docrc, usepipes, xfrxla, whereflg;
- extern char * xfrmsg;
- printf("\n");
- printf(" Transfer Bell: %s\n",showoff(xfrbel));
- printf(" Transfer Interruption: %s\n",showoff(xfrint));
- printf(" Transfer Cancellation: %s\n",showoff(xfrcan));
-#ifndef NOCSETS
- printf(" Transfer Translation: %s\n",showoff(xfrxla));
- printf(" Transfer Character-set: ");
- if (tcharset == TC_TRANSP)
- printf("Transparent\n");
- else
- printf("%s\n",tcsinfo[tcharset].keyword);
-#endif /* NOCSETS */
- printf(" Transfer CRC-calculation: %s\n",showoff(docrc));
- printf(" Transfer Display: ");
- switch (fdispla) {
- case XYFD_N: printf("%s\n","none"); break;
- case XYFD_R: printf("%s\n","serial"); break;
- case XYFD_C: printf("%s\n","fullscreen"); break;
- case XYFD_S: printf("%s\n","crt"); break;
- case XYFD_B: printf("%s\n","brief"); break;
- case XYFD_G: printf("%s\n","gui"); break;
- }
- printf(" Transfer Message: %s\n", xfrmsg ? xfrmsg : "(none)");
- printf(" Transfer Locking-shift: ");
- if (lscapu == 2) {
- printf("forced");
- } else {
- printf("%s", (lscapr ? "enabled" : "disabled"));
- if (lscapr) printf(",%s%s", (lscapu ? " " : " not "), "used");
- }
- printf("\n Transfer Mode: %s\n",
- xfermode == XMODE_A ?
- "automatic" :
- "manual"
- );
- printf(" Transfer Pipes: %s\n", showoff(usepipes));
- printf(" Transfer Protocol: %s\n",ptab[protocol].p_name);
- printf(" Transfer Report: %s\n",showoff(whereflg));
- printf(" Transfer Slow-start: %s\n",showoff(slostart));
- printf("\n");
-}
-#endif /* NOXFER */
-
-VOID
-shoflow() {
- int i, x;
- extern int cxflow[], cxtype, ncxname, nfloname, autoflow;
- extern char * cxname[];
- printf("\nConnection type: %s\n",cxname[cxtype]);
- if (autoflow) {
- printf("Current flow-control: %s\n", floname[cxflow[cxtype]]);
- printf("Switches automatically: yes\n");
- } else {
- printf("Current flow-control: %s\n", floname[flow]);
- printf("Switches automatically: no\n");
- }
- printf("\nDefaults by connection type:\n");
- debug(F111,"shoflow cxtype",cxname[cxtype],cxtype);
- debug(F101,"shoflow flow","",flow);
- for (i = 0; i < ncxname; i++) {
-#ifdef NOLOCAL
- if (i > 0) break;
-#endif /* NOLOCAL */
-#ifndef NETCONN
- if (i > 2) break;
-#endif /* NETCONN */
-#ifndef DECNET
- if (i == CXT_DECNET) continue;
-#endif /* DECNET */
-#ifndef DECNET
-#ifndef SUPERLAT
- if (i == CXT_LAT) continue;
-#endif /* SUPERLAT */
-#endif /* DECNET */
-#ifndef CK_NETBIOS
- if (i == CXT_NETBIOS) continue;
-#endif /* CK_NETBIOS */
-#ifndef NPIPE
- if (i == CXT_NPIPE) continue;
-#endif /* NPIPE */
-#ifndef NETCMD
- if (i == CXT_PIPE) continue;
-#endif /* NETCMD */
-#ifndef ANYX25
- if (i == CXT_X25) continue;
-#endif /* ANYX25 */
- x = cxflow[i];
- debug(F101,"shoflow x","",x);
- if (x < nfloname)
- printf(" %-14s: %s\n",cxname[i],floname[x]);
- else
- printf(" %-14s: (%d)\n",cxname[i],x);
- }
- printf("\n");
-}
-
-#ifndef NOLOCAL
-#ifdef ANYX25
-int
-shox25(n) int n; {
- if (nettype == NET_SX25) {
- printf("SunLink X.25 V%d.%d",x25ver / 10,x25ver % 10);
- if (ttnproto == NP_X3) printf(", PAD X.3, X.28, X.29 protocol,");
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" Reverse charge call %s",
- revcall ? "selected" : "not selected");
- printf (", Closed user group ");
- if (closgr > -1)
- printf ("%d",closgr);
- else
- printf ("not selected");
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" Call user data %s.\n", cudata ? udata : "not selected");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- } else if (nettype == NET_VX25) {
- if (ttnproto == NP_X3) printf(", PAD X.3, X.28, X.29 protocol,");
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" Reverse charge call %s",
- revcall ? "selected" : "not selected");
- printf (", Closed user group [unsupported]");
- if (closgr > -1)
- printf ("%d",closgr);
- else
- printf ("not selected");
- printf (",");
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" Call user data %s.\n", cudata ? udata : "not selected");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- } else if (nettype == NET_IX25) {
- printf("AIX NPI X.25\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf("\n Reverse charge call %s",
- revcall ? "selected" : "not selected");
- printf (", Closed user group [unsupported]");
- if (closgr > -1)
- printf ("%d",closgr);
- else
- printf ("not selected");
- printf (",");
- printf("\n Call user data %s.\n", cudata ? udata : "not selected");
- }
- return(n);
-}
-
-#ifndef IBMX25
-int
-shopad(n) int n; {
- int i;
- printf("\nX.3 PAD Parameters:\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- for (i = 0; i < npadx3; i++) {
- printf(" [%d] %s %d\n",padx3tab[i].kwval,padx3tab[i].kwd,
- padparms[padx3tab[i].kwval]);
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- }
- return(n);
-}
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-VOID
-shoparc() {
- extern int reliable, stopbits, clsondisc;
- int i; char *s;
- long zz;
-
-#ifdef NEWFTP
- if (ftpisconnected()) {
- shoftp(1);
- printf("\n");
- }
-#endif /* NEWFTP */
-
- printf("Communications Parameters:\n");
-
- if (network
-#ifdef IKSD
- || inserver
-#endif /* IKSD */
- ) {
- printf(" Network Host: %s%s",ttname,
- (reliable == SET_ON || (reliable == SET_AUTO && !local)
-#ifdef TN_COMPORT
- && !istncomport()
-#endif /* TN_COMPORT */
-#ifdef IKSD
- || inserver
-#endif /* IKSD */
- ) ? " (reliable)" : "");
-#ifdef TN_COMPORT
- if (istncomport()) {
- int modemstate;
- char * oflow, * iflow = "", * parity, * stopsize, * signature;
- int baud = tnc_get_baud();
-
- switch (tnc_get_oflow()) {
- case TNC_CTL_OFLOW_NONE:
- oflow = "none";
- break;
- case TNC_CTL_OFLOW_XON_XOFF:
- oflow = "xon/xoff";
- break;
- case TNC_CTL_OFLOW_RTS_CTS:
- oflow = "rts/cts";
- break;
- case TNC_CTL_OFLOW_DCD:
- oflow = "dcd";
- break;
- case TNC_CTL_OFLOW_DSR:
- oflow = "dsr";
- break;
- default:
- oflow = "(unknown)";
- }
- switch (tnc_get_iflow()) {
- case TNC_CTL_IFLOW_NONE:
- iflow = "none";
- break;
- case TNC_CTL_IFLOW_XON_XOFF:
- iflow = "xon/xoff";
- break;
- case TNC_CTL_IFLOW_RTS_CTS:
- iflow = "rts/cts";
- break;
- case TNC_CTL_IFLOW_DTR:
- break;
- default:
- iflow = oflow;
- }
- switch (tnc_get_parity()) {
- case TNC_PAR_NONE:
- parity = "none";
- break;
- case TNC_PAR_ODD:
- parity = "odd";
- break;
- case TNC_PAR_EVEN:
- parity = "even";
- break;
- case TNC_PAR_MARK:
- parity = "mark";
- break;
- case TNC_PAR_SPACE:
- parity = "space";
- break;
- default:
- parity = "(unknown)";
- }
- switch (tnc_get_stopsize()) {
- case TNC_SB_1:
- stopsize = "1";
- break;
- case TNC_SB_1_5:
- stopsize = "1.5";
- break;
- case TNC_SB_2:
- stopsize = "2";
- break;
- default:
- stopsize = "(unknown)";
- }
- signature = (char *)tnc_get_signature();
- printf("\n Signature : %s\n",signature?signature:"");
- if (baud <= 0)
- printf(" Speed : (unknown)\n");
- else
- printf(" Speed : %d\n", baud);
- printf(" Outbound Flow Control: %s\n", oflow);
- printf(" Inbound Flow Control : %s\n", iflow);
- printf(" Parity : %s\n", parity);
- printf(" Data Size : %d\n", tnc_get_datasize());
- printf(" Stop Bits : %s\n", stopsize);
- printf(" DTR Signal : %d\n", tnc_get_dtr_state());
- printf(" RTS Signal : %d\n", tnc_get_rts_state());
- printf(" Modem State:\n");
- modemstate = tnc_get_ms();
- if (modemstate & TNC_MS_EDGE_RING)
- printf(" Trailing Edge Ring Detector On\n");
- else
- printf(" Trailing Edge Ring Detector Off\n");
- if (modemstate & TNC_MS_CTS_SIG)
- printf(" CTS Signal On\n");
- else
- printf(" CTS Signal Off\n");
- if (modemstate & TNC_MS_DSR_SIG)
- printf(" DSR Signal On\n");
- else
- printf(" DSR Signal Off\n");
- if (modemstate & TNC_MS_RI_SIG)
- printf(" Ring Indicator On\n");
- else
- printf(" Ring Indicator Off\n");
- if (modemstate & TNC_MS_RLSD_SIG)
- printf(" RLSD (CD) Signal On\n");
- else
- printf(" RLSD (CD) Signal Off\n");
- printf("\n");
- }
-#endif /* TN_COMPORT */
- } else {
-
- printf(" %s: %s%s, speed: ",
-#ifdef OS2
- "Port",
-#else
- "Line",
-#endif /* OS2 */
- ttname,
-#ifdef CK_TTYFD
- (local &&
-#ifdef VMS
- vmsttyfd() < 0
-#else
- ttyfd == -1
-#endif /* VMS */
- ) ?
- " (closed)" :
- (reliable == SET_ON ? " (reliable)" : "")
-#else
- ""
-#endif /* CK_TTYFD */
- );
- if (
-#ifdef CK_TTYFD
-#ifdef VMS
- vmsttyfd() < 0
-#else
- ttyfd == -1
-#endif /* VMS */
- ||
-#endif /* CK_TTYFD */
- (zz = ttgspd()) < 0) {
- printf("unknown");
- } else {
- if (speed == 8880) printf("75/1200");
- else if (speed == 134) printf("134.5");
- else printf("%ld",zz);
- }
- }
- if (network
-#ifdef IKSD
- || inserver
-#endif /* IKSD */
- )
- printf("\n Mode: ");
- else
- printf(", mode: ");
- if (local) printf("local"); else printf("remote");
- if (network == 0
-#ifdef IKSD
- && !inserver
-#endif/* IKSD */
- ) {
-#ifdef CK_TAPI
- if (tttapi && !tapipass )
- printf(", modem: %s","TAPI");
- else
-#endif /* CK_TAPI */
- printf(", modem: %s",gmdmtyp());
- } else {
-#ifdef NETCONN
- if (nettype == NET_TCPA) printf(", TCP/IP");
- if (nettype == NET_TCPB) printf(", TCP/IP");
- if (nettype == NET_DEC) {
- if (ttnproto == NP_LAT) printf(", DECnet LAT");
- else if ( ttnproto == NP_CTERM ) printf(", DECnet CTERM");
- else printf(", DECnet");
- }
- if (nettype == NET_SLAT) printf(", Meridian Technologies' SuperLAT");
-#ifdef NETFILE
- if (nettype == NET_FILE) printf(", local file");
-#endif /* NETFILE */
-#ifdef NETCMD
- if (nettype == NET_CMD) printf(", pipe");
-#endif /* NETCMD */
-#ifdef NETPTY
- if (nettype == NET_PTY) printf(", pseudoterminal");
-#endif /* NETPTY */
-#ifdef NETDLL
- if (nettype == NET_DLL) printf(", dynamic load library");
-#endif /* NETDLL */
- if (nettype == NET_PIPE) printf(", Named Pipes");
-#ifdef SSHBUILTIN
- if (nettype == NET_SSH)
- printf(", Secure Shell protocol (SECURE)");
-#endif /* SSHBUILTIN */
-#ifdef ANYX25
- if (shox25(0) < 0) return;
-#endif /* ANYX25 */
- if (IS_TELNET()) {
- printf(", telnet protocol");
- if (0
-#ifdef CK_ENCRYPTION
- || ck_tn_encrypting() && ck_tn_decrypting()
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- || tls_active_flag || ssl_active_flag
-#endif /* CK_SSL */
- )
- printf(" (SECURE)");
- }
-#ifdef RLOGCODE
- else if (ttnproto == NP_RLOGIN || ttnproto == NP_K4LOGIN ||
- ttnproto == NP_K5LOGIN)
- printf(", rlogin protocol");
- else if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN)
- printf(", rlogin protocol (SECURE)");
-#endif /* RLOGCODE */
-#ifdef CK_KERBEROS
-#ifdef KRB5
- else if (ttnproto == NP_K5U2U)
- printf(", Kerberos 5 User to User protocol (SECURE)");
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-#endif /* NETCONN */
- }
- printf("\n");
- if (hwparity && local && !network)
- s = parnam((char)hwparity);
- else
- s = parnam((char)parity);
- printf(" Parity: %s%s",hwparity ? "hardware " : "", s);
-#ifndef NOLOCAL
- if (local && !network) {
- int sb;
- char c;
- c = s[0];
- if (islower(c)) c = toupper(c);
- sb = stopbits;
- if (sb < 1) {
- sb = (speed > 0 && speed <= 110L) ? 2 : 1;
- printf(", stop-bits: (default)");
- } else {
- printf(", stop-bits: %d",sb);
- }
- if (hwparity)
- printf(" (8%c%d)",c,sb);
- else if (parity)
- printf(" (7%c%d)",c,sb);
- else
- printf(" (8N%d)",sb);
- printf("\n D");
- } else
- printf(", d");
-#endif /* NOLOCAL */
-
- printf("uplex: %s, ", duplex ? "half" : "full");
- debug(F101,"shoparp flow","",flow);
- printf("flow: %s", floname[flow]);
- printf(", handshake: ");
- if (turn) printf("%d\n",turnch); else printf("none\n");
-#ifdef COMMENT
- if (local && !network) { /* SET CARRIER-WATCH */
-#endif /* COMMENT */
- if (carrier == CAR_OFF) s = "off";
- else if (carrier == CAR_ON) s = "on";
- else if (carrier == CAR_AUT) s = "auto";
- else s = "unknown";
- printf(" Carrier-watch: %s", s);
- if (carrier == CAR_ON) {
- if (cdtimo) printf(", timeout: %d sec", cdtimo);
- else printf(", timeout: none");
- }
-#ifdef COMMENT
- }
-#endif /* COMMENT */
- printf(", close-on-disconnect: %s\n",showoff(clsondisc));
-
-#ifdef UNIX /* UUCP lockfile, UNIX only */
- if (local) {
-#ifndef NOUUCP
- if (!network && haslock && *flfnam)
- printf(" Lockfile: %s",flfnam);
-#ifndef USETTYLOCK
- if (!network && haslock && lock2[0])
- printf("\n Secondary lockfile: %s",lock2);
-#endif /* USETTYLOCK */
-#else
-#ifdef QNX
- {
- extern int qnxportlock, qnxopencount();
- if (local)
- printf(" Qnx-port-lock: %s, Open count: %d",
- showoff(qnxportlock),
- qnxopencount()
- );
- else
- printf(" Qnx-port-lock: %s", showoff(qnxportlock));
- }
-#endif /* QNX */
-#endif /* NOUUCP */
- printf("\n");
- } else {
- char * s;
- s = ttglckdir();
- if (!s) s = "";
- printf(" Lockfile directory: %s\n", *s ? s : "(none)");
- }
-#endif /* UNIX */
-#ifndef MACOSX
- if (!local) {
- printf(" Typical port device name: %s\n",ttgtpn());
- }
-#endif /* MACOSX */
- if (local) {
- int i;
- i = parity ? 7 : 8;
- if (i == 8) i = (cmask == 0177) ? 7 : 8;
- printf(" Terminal bytesize: %d,",i);
- printf(" escape character: %d (^%c)\n",escape,ctl(escape));
- }
-}
-
-int
-shotcp(n) int n; {
-#ifdef TCPSOCKET
- if (nettype == NET_TCPA || nettype == NET_TCPB) {
- printf("SET TCP parameters:\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" Reverse DNS lookup: %s\n", showooa(tcp_rdns));
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
-#ifdef CK_DNS_SRV
- printf(" DNS Service Records lookup: %s\n", showooa(tcp_dns_srv));
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* CK_DNS_SRV */
-
-#ifndef NOTCPOPTS
-#ifdef SOL_SOCKET
-#ifdef SO_KEEPALIVE
- printf(" Keepalive: %s\n", showoff(tcp_keepalive));
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* SO_KEEPALIVE */
-
-#ifdef SO_LINGER
- printf(" Linger: %s", tcp_linger ? "on, " : "off\n" );
- if (tcp_linger) {
- if (tcp_linger_tmo)
- printf("%d x 10 milliseconds\n",tcp_linger_tmo);
- else
- printf("no timeout\n");
- }
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* SO_LINGER */
-
-#ifdef SO_DONTROUTE
- printf(" DontRoute: %s\n", tcp_dontroute ? "on" : "off" );
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* SO_DONTROUTE */
-
-#ifdef TCP_NODELAY
- printf(" Nodelay: %s\n", showoff(tcp_nodelay));
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* TCP_NODELAY */
-
-#ifdef SO_SNDBUF
- if (tcp_sendbuf <= 0)
- printf(" Send buffer: (default size)\n");
- else
- printf(" Send buffer: %d bytes\n", tcp_sendbuf);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
- if (tcp_recvbuf <= 0)
- printf(" Receive buffer: (default size)\n");
- else
- printf(" Receive buffer: %d bytes\n", tcp_recvbuf);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* SO_RCVBUF */
-#endif /* SOL_SOCKET */
-#endif /* NOTCPOPTS */
- printf(" address: %s\n",tcp_address ? tcp_address : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#ifndef NOHTTP
- printf(" http-proxy: %s\n",tcp_http_proxy ? tcp_http_proxy : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#endif /* NOHTTP */
-#ifdef NT
-#ifdef CK_SOCKS
- printf(" socks-server: %s\n",tcp_socks_svr ? tcp_socks_svr : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#ifdef CK_SOCKS_NS
- printf(" socks-name-server: %s\n",
- tcp_socks_ns ? tcp_socks_ns : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#endif /* CK_SOCKS_NS */
-#endif /* CK_SOCKS */
-#endif /* NT */
- }
-#endif /* TCPSOCKET */
- return(n);
-}
-
-#ifdef TNCODE
-int
-shotopt(n) int n; {
- int opt;
-
- printf("%-21s %12s %12s %12s %12s\n\n",
- "Telnet Option","Me (client)","U (client)",
- "Me (server)","U (server)");
- n += 2;
- if (n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-
- for ( opt = TELOPT_FIRST; opt <= TELOPT_LAST; opt++) {
- switch (opt) {
- case TELOPT_AUTHENTICATION:
- case TELOPT_ENCRYPTION:
- case TELOPT_TTYPE:
- case TELOPT_NAWS:
- case TELOPT_BINARY:
- case TELOPT_NEWENVIRON:
- case TELOPT_SNDLOC:
- case TELOPT_XDISPLOC:
- case TELOPT_SGA:
- case TELOPT_ECHO:
- case TELOPT_KERMIT:
- case TELOPT_START_TLS:
- case TELOPT_FORWARD_X:
- case TELOPT_COMPORT:
- break;
- default:
- continue;
- }
- printf("%03d %-17s ",
- opt, TELOPT(opt)
- );
- printf("%12s %12s ",
- TELOPT_MODE(TELOPT_DEF_C_ME_MODE(opt)),
- TELOPT_MODE(TELOPT_DEF_C_U_MODE(opt))
- );
- printf("%12s %12s\n",
- TELOPT_MODE(TELOPT_DEF_S_ME_MODE(opt)),
- TELOPT_MODE(TELOPT_DEF_S_U_MODE(opt))
- );
-
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- if (sstelnet)
- printf("%21s %12s %12s %12s %12s\n",
- "",
- "",
- "",
- (TELOPT_ME(opt)?"WILL":"WONT"),
- (TELOPT_U(opt)?"DO":"DONT")
- );
- else
- printf("%21s %12s %12s %12s %12s\n",
- "",
- (TELOPT_ME(opt)?"WILL":"WONT"),
- (TELOPT_U(opt)?"DO":"DONT"),
- "",
- ""
- );
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- }
- return(n);
-}
-
-int
-shotel(n) int n; {
- extern int tn_duplex;
-#ifdef CK_ENVIRONMENT
- extern int tn_env_flg;
- extern char tn_env_acct[];
- extern char tn_env_job[];
- extern char tn_env_prnt[];
- extern char tn_env_sys[];
- extern char * tn_env_uservar[8][2];
- int x;
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_SNDLOC
- extern char * tn_loc;
-#endif /* CK_SNDLOC */
- printf("SET TELNET parameters:\n echo: %s\n NVT newline-mode: ",
- tn_duplex ? "local" : "remote");
- switch (tn_nlm) {
- case TNL_CRNUL: printf("%s\n","off (cr-nul)"); break;
- case TNL_CRLF: printf("%s\n","on (cr-lf)"); break;
- case TNL_CR: printf("%s\n","raw (cr)"); break;
- case TNL_LF: printf("%s\n","(lf)"); break;
- }
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#ifdef CK_AUTHENTICATION
- {
- int type = ck_tn_authenticated();
- printf(" authentication: ");
- switch (sstelnet ?
- TELOPT_U_MODE(TELOPT_AUTHENTICATION) :
- TELOPT_ME_MODE(TELOPT_AUTHENTICATION)
- ) {
- case TN_NG_AC: printf( "accepted " ); break;
- case TN_NG_RF: printf( "refused " ); break;
- case TN_NG_RQ: printf( "requested"); break;
- case TN_NG_MU: printf( "required "); break;
- }
-
-#ifdef CK_SSL
- if ((ssl_active_flag || tls_active_flag) &&
- ck_tn_auth_valid() == AUTH_VALID &&
- (!TELOPT_U(TELOPT_AUTHENTICATION) ||
- type == AUTHTYPE_NULL ||
- type == AUTHTYPE_AUTO))
- printf(" in use: X.509 certificate\n");
- else
-#endif /* CK_SSL */
- printf(" in use: %s\n",AUTHTYPE_NAME(type));
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- if (forward_flag)
- printf(" credentials forwarding requested %s\n",
- forwarded_tickets ? "and completed" :
- "but not completed");
- else
- printf(" credentials forwarding disabled\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- }
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
- {
- int i,x;
- int e_type = ck_tn_encrypting();
- int d_type = ck_tn_decrypting();
- char * e_str = NULL, * d_str = NULL;
- static struct keytab * tnetbl = NULL;
- static int ntnetbl = 0;
-
- x = ck_get_crypt_table(&tnetbl,&ntnetbl);
-
- for (i = 0; i < ntnetbl; i++) {
- if (e_type == tnetbl[i].kwval)
- e_str = tnetbl[i].kwd;
- if (d_type == tnetbl[i].kwval)
- d_str = tnetbl[i].kwd;
- }
- printf(" encryption: ");
- switch (TELOPT_ME_MODE(TELOPT_ENCRYPTION)) {
- /* This should be changed to report both ME and U modes */
- case TN_NG_AC: printf( "accepted " ); break;
- case TN_NG_RF: printf( "refused " ); break;
- case TN_NG_RQ: printf( "requested"); break;
- case TN_NG_MU: printf( "required "); break;
- }
- printf(" in use: ");
- switch ((e_type ? 1 : 0) | (d_type ? 2 : 0)) {
- case 0:
- printf("plain text in both directions");
- break;
- case 1:
- printf("%s output, plain text input",e_str);
- break;
- case 2:
- printf("plain text output, %s input",d_str);
- break;
- case 3:
- printf("%s output, %s input",e_str,d_str);
- break;
- }
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- }
-#endif /* CK_ENCRYPTION */
-#ifdef IKS_OPTION
- printf(" kermit: ");
- switch (TELOPT_U_MODE(TELOPT_KERMIT)) {
- case TN_NG_AC: printf( "u, accepted; " ); break;
- case TN_NG_RF: printf( "u, refused; " ); break;
- case TN_NG_RQ: printf( "u, requested; "); break;
- case TN_NG_MU: printf( "u, required; "); break;
- }
- switch (TELOPT_ME_MODE(TELOPT_KERMIT)) {
- case TN_NG_AC: printf( "me, accepted; " ); break;
- case TN_NG_RF: printf( "me, refused; " ); break;
- case TN_NG_RQ: printf( "me, requested; "); break;
- case TN_NG_MU: printf( "me, required; "); break;
- }
- if (TELOPT_U(TELOPT_KERMIT))
- printf(" u, %s",
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start ?
- "started" :
- "stopped"
- );
- else
- printf(" u, n/a");
- if (TELOPT_ME(TELOPT_KERMIT))
- printf(" me, %s;",
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start ?
- "started" :
- "stopped"
- );
- else
- printf(" me, n/a;");
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#endif /* IKS_OPTION */
- printf(" BINARY newline-mode: ");
- switch (tn_b_nlm) {
- case TNL_CRNUL: printf("%s\n","off (cr-nul)"); break;
- case TNL_CRLF: printf("%s\n","on (cr-lf)"); break;
- case TNL_CR: printf("%s\n","raw (cr)"); break;
- case TNL_LF: printf("%s\n","(lf)"); break;
- }
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" binary-mode: ");
- switch (TELOPT_U_MODE(TELOPT_BINARY)) {
- case TN_NG_AC: printf( "u, accepted; " ); break;
- case TN_NG_RF: printf( "u, refused; " ); break;
- case TN_NG_RQ: printf( "u, requested; "); break;
- case TN_NG_MU: printf( "u, required; "); break;
- }
- switch (TELOPT_ME_MODE(TELOPT_BINARY)) {
- case TN_NG_AC: printf( "me, accepted; " ); break ;
- case TN_NG_RF: printf( "me, refused; " ); break;
- case TN_NG_RQ: printf( "me, requested; "); break;
- case TN_NG_MU: printf( "me, required; "); break;
- }
- printf("u, %s; me, %s\n",
- TELOPT_U(TELOPT_BINARY) ? "BINARY" : "NVT",
- TELOPT_ME(TELOPT_BINARY) ? "BINARY" : "NVT"
- );
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" binary-transfer-mode: %s\n",showoff(tn_b_xfer));
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" bug binary-me-means-u-too: %s\n",showoff(tn_b_meu));
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" bug binary-u-means-me-too: %s\n",showoff(tn_b_ume));
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" bug sb-implies-will-do: %s\n",showoff(tn_sb_bug));
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" bug auth-krb5-des: %s\n",showoff(tn_auth_krb5_des_bug));
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" terminal-type: ");
- if (tn_term) {
- printf("%s\n",tn_term);
- } else {
- char *p;
-#ifdef OS2
- p = (tt_type >= 0 && tt_type <= max_tt) ?
- tt_info[tt_type].x_name :
- "UNKNOWN";
-#else
- p = getenv("TERM");
-#endif /* OS2 */
- if (p)
- printf("none (%s will be used)\n",p);
- else printf("none\n");
- }
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#ifdef CK_ENVIRONMENT
- printf(" environment: %s\n", showoff(tn_env_flg));
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" ACCOUNT: %s\n",tn_env_acct);
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" DISPLAY: %s\n",(char *)tn_get_display() ?
- (char *)tn_get_display() : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" JOB : %s\n",tn_env_job);
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" PRINTER: %s\n",tn_env_prnt);
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#ifndef NOSPL
- printf(" USER : %s\n",uidbuf);
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#endif /* NOSPL */
- printf(" SYSTEM : %s\n",tn_env_sys);
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- for (x = 0; x < 8; x++) {
- if (tn_env_uservar[x][0] && tn_env_uservar[x][1]) {
- printf(" %-7s: %s\n",tn_env_uservar[x][0],
- tn_env_uservar[x][1]);
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- }
- }
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_SNDLOC
- printf(" LOCATION: %s\n", tn_loc ? tn_loc : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#endif /* CK_SNDLOC */
-#ifdef CK_FORWARD_X
- printf(" .Xauthority-file: %s\n", (char *)XauFileName() ?
- (char *)XauFileName() : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
-#endif /* CK_FORWARD_X */
- return(n);
-}
-#endif /* TNCODE */
-
-#ifdef CK_NETBIOS
-static int
-shonb(n) int n; {
- printf("NETBIOS parameters:\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" API : %s\n",
- NetbeuiAPI ?
- "NETAPI.DLL - IBM Extended Services or Novell Netware Requester"
- : "ACSNETB.DLL - IBM Network Transport Services/2" ) ;
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" Local Name: [%s]\n", NetBiosName);
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- printf(" Adapter : %d\n", NetBiosAdapter);
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- if (NetBiosLSN > 0xFF) {
- printf(" Session : %d\n", NetBiosLSN);
- } else {
- printf(" Session : none active\n");
- }
- if (++n > cmd_rows - 3) if (!askmore()) return(-1); else n = 0;
- return(n);
-}
-#endif /* CK_NETBIOS */
-
-#ifndef NONET
-int
-shonet() {
-
-#ifndef NETCONN
- printf("\nNo networks are supported in this version of C-Kermit\n");
-
-#else
-#ifdef NOLOCAL
- printf("\nNo networks are supported in this version of C-Kermit\n");
-
-#else /* rest of this routine */
-
- int i, n = 4;
-
-#ifndef NODIAL
- if (nnetdir <= 1) {
- printf("\nNetwork directory: %s\n",netdir[0] ? netdir[0] : "(none)");
- n++;
- } else {
- int i;
- printf("\nNetwork directories:\n");
- for (i = 0; i < nnetdir; i++) {
- printf("%2d. %s\n",i,netdir[i]);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
- }
-#endif /* NODIAL */
-
-#ifdef SSHCMD
- {
- extern char * sshcmd;
- printf("SSH COMMAND: %s\n",sshcmd ? sshcmd : "ssh -e none");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
-#endif /* SSHCMD */
-
-#ifdef OS2
- printf("\nNetwork availability:\n");
-#else
- printf("\nSupported networks:\n");
-#endif /* OS2 */
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
-#ifdef VMS
-
-#ifdef TCPWARE
- printf(" Process Software Corporation TCPware for OpenVMS");
-#else
-#ifdef MULTINET
- printf(" TGV MultiNet TCP/IP");
-#else
-#ifdef WINTCP
- printf(" WOLLONGONG WIN/TCP");
-#else
-#ifdef DEC_TCPIP
- {
- static $DESCRIPTOR(tcp_desc,"_TCP0:");
- int status;
- long devclass;
- static int itmcod = DVI$_DEVCLASS;
-
-#ifdef COMMENT
- status = LIB$GETDVI(&itmcod, 0, &tcp_desc, &devclass);
-#else
- /* Martin Zinser 9/96 */
- status = lib$getdvi(&itmcod, 0, &tcp_desc, &devclass);
-#endif /* COMMENT */
- if ((status & 1) && (devclass == DC$_SCOM))
- printf(" Process Software Corporation TCPware for OpenVMS");
- else
-#ifdef UCX50
- printf(" DEC TCP/IP Services for (Open)VMS 5.0");
-#else
- printf(" DEC TCP/IP Services for (Open)VMS");
-#endif /* UCX50 */
- }
-#else
-#ifdef CMU_TCPIP
- printf(" CMU-OpenVMS/IP");
-#else
- printf(" None");
-#endif /* CMU_TCPIP */
-#endif /* DEC_TCPIP */
-#endif /* WINTCP */
-#endif /* MULTINET */
-#endif /* TCPWARE */
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#ifdef TNCODE
- printf(", TELNET protocol\n\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- n = shotel(n);
- if (n < 0) return(0);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* TNCODE */
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf("\n");
- n = shotcp(++n);
- if (n < 0) return(0);
-#else /* Not VMS */
-
-#ifdef SUNX25
- printf(" SunLink X.25\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* SUNX25 */
-
-#ifdef STRATUSX25
- printf(" Stratus VOS X.25\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* STRATUSX25 */
-
-#ifdef IBMX25
- printf(" IBM AIX X.25\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* IBMX25 */
-
-#ifdef HPX25
- printf(" HP-UX X.25\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* HPX25 */
-
-#ifdef SSHBUILTIN
- if (ck_ssleay_is_installed())
- printf(" SSH V1 and V2 protocols\n");
- else
- printf(" SSH V1 and V2 protocols - not available\n");
-#endif /* SSHBUILTIN */
-
-#ifdef DECNET
-#ifdef OS2
-#ifdef NT
- if (dnet_avail)
- printf(" DECnet, LAT and CTERM protocols\n");
- else
- printf(" DECnet, LAT and CTERM protocols - not available\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#else /* NT */
- if (dnet_avail)
- printf(" DECnet, LAT protocol\n");
- else
- printf(" DECnet, LAT protocol - not available\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* NT */
-#else
- printf(" DECnet\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* OS2 */
-#endif /* DECNET */
-
-#ifdef NPIPE
- printf(" Named Pipes\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* NPIPE */
-
-#ifdef CK_NETBIOS
- if (netbiosAvail)
- printf(" NETBIOS\n");
- else
- printf(" NETBIOS - not available\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* CK_NETBIOS */
-
-#ifdef SUPERLAT
- if (slat_avail)
- printf(" SuperLAT\n");
- else
- printf(" SuperLAT - not available\n") ;
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* SUPERLAT */
-
-#ifdef TCPSOCKET
- if (
-#ifdef OS2
- tcp_avail
-#else
- 1
-#endif /* OS2 */
- ) {
- char ipaddr[16];
-
- if (getlocalipaddrs(ipaddr,16,0) < 0) {
-#ifdef OS2ONLY
- printf(" TCP/IP via %s\n", tcpname);
-#else
- printf(" TCP/IP\n");
-#endif /* OS2ONLY */
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- } else {
- int i = 1;
-#ifdef OS2ONLY
- printf(" TCP/IP [%16s] via %s\n", ipaddr, tcpname);
-#else
- printf(" TCP/IP [%16s]\n",ipaddr);
-#endif /* OS2ONLY */
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
- while (getlocalipaddrs(ipaddr,16,i++) >= 0) {
- printf(" [%16s]\n",ipaddr);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
- }
- if (nettype == NET_TCPB) {
- printf("\n");
- n = shotcp(++n);
- if (n < 0) return(0);
-#ifdef TNCODE
- printf("\n");
- n = shotel(++n);
- if (n < 0) return(0);
-#endif /* TNCODE */
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
-#ifdef OS2
- } else {
- printf(" TCP/IP - not available%s\n",tcpname[0] ? tcpname : "" );
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* OS2 */
- }
-#endif /* TCPSOCKET */
-
-#ifdef CK_NETBIOS
- if (netbiosAvail && nettype == NET_BIOS) {
- printf("\n") ;
- if ((n = shonb(++n)) < 0) return(0);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
-#endif /* CK_NETBIOS */
-
-#endif /* VMS */
-
- printf("\nActive network connection:\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
- if (network) {
- printf(" Host: %s",ttname);
- if ((nettype == NET_TCPA || nettype == NET_TCPB) && *ipaddr)
- printf(" [%s]",ipaddr);
- } else
- printf(" Host: none");
- printf(", via: ");
- if (nettype == NET_TCPA || nettype == NET_TCPB)
- printf("tcp/ip\n");
- else if (nettype == NET_SX25)
- printf("SunLink X.25\n");
- else if (nettype == NET_VX25)
- printf("Stratus VOS X.25\n");
- else if (nettype == NET_IX25)
- printf("IBM AIX X.25\n");
- else if (nettype == NET_HX25)
- printf("HP-UX X.25\n");
- else if (nettype == NET_DEC) {
- if ( ttnproto == NP_LAT )
- printf("DECnet LAT\n");
- else if ( ttnproto == NP_CTERM )
- printf("DECnet CTERM\n");
- else
- printf("DECnet\n");
- } else if (nettype == NET_PIPE)
- printf("Named Pipes\n");
- else if (nettype == NET_BIOS)
- printf("NetBIOS\n");
- else if (nettype == NET_SLAT)
- printf("SuperLAT\n");
-
-#ifdef NETFILE
- else if ( nettype == NET_FILE )
- printf("local file\n");
-#endif /* NETFILE */
-#ifdef NETCMD
- else if ( nettype == NET_CMD )
- printf("pipe\n");
-#endif /* NETCMD */
-#ifdef NETPTY
- else if ( nettype == NET_PTY )
- printf("pseudoterminal\n");
-#endif /* NETPTY */
-#ifdef NETDLL
- else if ( nettype == NET_DLL )
- printf("dynamic link library\n");
-#endif /* NETDLL */
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
-#ifdef ANYX25
- if ((nettype == NET_SX25) ||
- (nettype == NET_VX25) ||
- (nettype == NET_IX25))
- if ((n = shox25(n)) < 0) return(0);
-#endif /* ANYX25 */
-
-#ifdef SSHBUILTIN
- if (nettype == NET_SSH) {
- printf("Secure Shell protocol\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
-#endif /* SSHBUILTIN */
-
- if (nettype == NET_TCPA || nettype == NET_TCPB) {
-#ifdef RLOGCODE
- if (ttnproto == NP_RLOGIN) {
- printf(" LOGIN (rlogin) protocol\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
-#ifdef CK_KERBEROS
- else if (ttnproto == NP_K4LOGIN) {
- printf(" Kerberos 4 LOGIN (klogin) protocol\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
- else if (ttnproto == NP_EK4LOGIN) {
- printf(" Encrypted Kerberos 4 LOGIN (eklogin) protocol\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
- else if (ttnproto == NP_K5LOGIN) {
- printf(" Kerberos 5 LOGIN (klogin) protocol\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
- else if (ttnproto == NP_EK5LOGIN) {
- printf(" Encrypted Kerberos 5 LOGIN (eklogin) protocol\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
-#ifdef CK_KERBEROS
- if (ttnproto == NP_K5U2U) {
- printf(" Kerberos 5 User to User protocol\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
-#endif /* CK_KERBEROS */
-
-#ifdef TNCODE
- if (IS_TELNET()) {
- printf(" TELNET protocol\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Echoing is currently %s\n",duplex ? "local" : "remote");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
-#endif /* TNCODE */
- if (ttnproto == NP_TCPRAW) {
- printf(" Raw TCP socket\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
- }
- printf("\n");
-#endif /* NOLOCAL */
-#endif /* NETCONN */
- return(0);
-}
-#endif /* NONET */
-
-#ifndef NODIAL
-VOID
-shodial() {
- if (mdmtyp >= 0 || local != 0) doshodial();
-}
-
-VOID
-shods(s) char *s; { /* Show a dial-related string */
- char c;
- if (s == NULL || !(*s)) { /* Empty? */
- printf("(none)\n");
- } else { /* Not empty. */
- while ((c = *s++)) /* Can contain controls */
- if (c == '\\') /* a backslash */
- printf("\\\\");
- else if (c > 31 && c < 127) {
- putchar(c);
- } else
- printf("\\{%d}",c);
- printf("\n");
- }
-}
-
-int
-doshodial() {
-
- int i, n = 2;
-
- printf(" Dial status: %d", dialsta);
-
-#ifdef BIGBUFOK
- if (dialsta > 90)
- printf(" = Unknown error");
- else if (dialsta < 0)
- printf(" = (none)");
- else if (dialsta < 35 && dialmsg[dialsta])
- printf(" = %s", dialmsg[dialsta]);
-#endif /* BIGBUFOK */
- n++;
- if (ndialdir <= 1) {
- printf("\n Dial directory: %s\n",dialdir[0] ? dialdir[0] : "(none)");
- } else {
- int i;
- printf("\n Dial directories:\n");
- for (i = 0; i < ndialdir; i++)
- printf("%2d. %s\n",i+1,dialdir[i]);
- n += ndialdir;
- }
- printf(" Dial method: ");
- if (dialmauto) printf("auto ");
- else if (dialmth == XYDM_D) printf("default");
- else if (dialmth == XYDM_P) printf("pulse ");
- else if (dialmth == XYDM_T) printf("tone ");
- printf(" Dial sort: %s\n",dialsrt ? "on" : "off");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Dial hangup: %s Dial display: %s\n",
- dialhng ? "on " : "off", dialdpy ? "on" : "off");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- if (dialrtr > 0) {
- printf(" Dial retries: %-12d Dial interval: %d\n",
- dialrtr, dialint);
- } else {
- printf(" Dial retries: (auto) Dial interval: %d\n", dialint);
- }
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Dial timeout: ");
-#ifdef CK_TAPI
- if (tttapi && !tapipass)
- printf("(tapi)");
- else
-#endif /* CK_TAPI */
- if (dialtmo > 0)
- printf("%4d sec", dialtmo);
- else
- printf("0 (auto)");
- printf(" Redial number: %s\n",dialnum ? dialnum : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Dial confirmation: %s Dial convert-directory: %s\n",
- dialcnf ? "on " : "off",
- dialcvt ? ((dialcvt == 1) ? "on" : "ask") : "off");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Dial ignore-dialtone: %s", dialidt ? "on " : "off");
- printf(" Dial pacing: %d\n",dialpace);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial prefix: %s\n", dialnpr ? dialnpr : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial suffix: %s\n", dialsfx ? dialsfx : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial country-code: %-12s", diallcc ? diallcc : "(none)");
- printf("Dial connect: %s", dialcon ? ((dialcon == 1) ? "on" : "auto")
- : "off");
- if (dialcon != CAR_OFF)
- printf(" %s", dialcq ? "quiet" : "verbose");
- printf(
-"\n Dial area-code: %-12s", diallac ? diallac : "(none)");
- n++;
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf("Dial restrict: ");
- if (dialrstr == 5) printf("international\n");
- else if (dialrstr == 4) printf("long-distance\n");
- else if (dialrstr == 2) printf("local\n");
- else if (dialrstr == 6) printf("none\n");
- else printf("?\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Dial lc-area-codes: ");
- if (nlocalac == 0)
- printf("(none)");
- else
- for (i = 0; i < nlocalac; i++)
- printf("%s ", diallcac[i]);
- printf(
-"\n Dial lc-prefix: %s\n", diallcp ? diallcp : "(none)");
- n++;
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial lc-suffix: %s\n", diallcs ? diallcs : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial ld-prefix: %s\n", dialldp ? dialldp : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial ld-suffix: %s\n", diallds ? diallds : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial force-long-distance %s\n", showoff(dialfld));
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial intl-prefix: %s\n", dialixp ? dialixp : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial intl-suffix: %s\n", dialixs ? dialixs : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial toll-free-area-code: ");
- if (ntollfree == 0)
- printf("(none)");
- else
- for (i = 0; i < ntollfree; i++)
- printf("%s ", dialtfc[i]);
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
- printf(
-" Dial pulse-countries: ");
- if (ndialpucc == 0)
- printf("(none)");
- else
- for (i = 0; i < ndialpucc; i++)
- printf("%s ", dialpucc[i]);
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
- printf(
-" Dial tone-countries: ");
- if (ndialtocc == 0)
- printf("(none)");
- else
- for (i = 0; i < ndialtocc; i++)
- printf("%s ", dialtocc[i]);
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
- printf(
- " Dial toll-free-prefix: %s\n",
- dialtfp ? dialtfp :
- (dialldp ? dialldp : "(none)")
- );
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Dial pbx-exchange: ");
- if (ndialpxx == 0)
- printf("(none)");
- else
- for (i = 0; i < ndialpxx; i++)
- printf("%s ", dialpxx[i]);
- printf("\n");
-
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial pbx-inside-prefix: %s\n", dialpxi ? dialpxi : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial pbx-outside-prefix: %s\n", dialpxo ? dialpxo : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(
-" Dial macro: %s\n", dialmac ? dialmac : "(none)");
- return(0);
-}
-#endif /* NODIAL */
-#endif /* NOLOCAL */
-
-/* Show File Parameters */
-
-static char *
-pathval(x) int x; {
- switch (x) {
- case PATH_OFF: return("off");
- case PATH_ABS: return("absolute");
- case PATH_REL: return("relative");
- case PATH_AUTO: return("auto");
- default: return("unknown");
- }
-}
-
-VOID
-shofil() {
- char *s; int i = 0, n = 1;
- extern char * ifdnam[];
- extern int wildena;
-#ifdef UNIX
- extern int wildxpand;
-#endif /* UNIX */
- extern char * snd_move, * snd_rename, * rcv_move, * rcv_rename;
-#ifdef PATTERNS
- extern int patterns;
-#endif /* PATTERNS */
- extern char * rfspec, * sfspec;
-#ifdef UNIX
- extern int zobufsize, zofbuffer, zofblock;
-#endif /* UNIX */
-#ifdef CK_CTRLZ
- extern int eofmethod;
-#endif /* CK_CTRLZ */
-
- printf("\n");
-
-#ifdef VMS
- printf(" File record-Length: %5d\n",frecl);
- n++;
-#endif /* VMS */
-
-#ifndef NOXFER
- printf(" Transfer mode: %s\n",
- xfermode == XMODE_A ?
- "automatic" :
- "manual"
- );
- n++;
-#ifdef PATTERNS
- printf(" File patterns: %s", showooa(patterns));
- if (xfermode == XMODE_M && patterns)
- printf(" (but disabled by TRANSFER-MODE MANUAL)");
- else if (patterns)
- printf(" (SHOW PATTERNS for list)");
- printf("\n");
- n++;
-#endif /* PATTERNS */
- if (filepeek)
- printf(" File scan: on %d\n", nscanfile);
- else
- printf(" File scan: off\n");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- if (xfermode == XMODE_A)
- printf(" Default file type: %s\n",shoxm());
- else
- printf(" File type: %s\n",shoxm());
- n++;
- if (fncnv == XYFN_L)
- s = "literal";
- else if (fncnv == XYFN_C)
- s = "converted";
- else
- s = "(unknown)";
- printf(" File names: %s\n",s);
- n++;
- printf(" Send pathnames: %s\n", pathval(fnspath));
- n++;
- printf(" Receive pathnames: %s\n", pathval(fnrpath));
- n++;
-#ifdef UNIXOROSK
- printf(" Match dot files: %s\n", matchdot ? "yes" : "no");
- n++;
-#ifdef UNIX
- printf(" Wildcard-expansion: %s (%s)\n", showoff(wildena),
- wildxpand ? "shell" : "kermit");
- n++;
-#endif /* UNIX */
-#endif /* UNIXOROSK */
- printf(" File collision: ");
- for (i = 0; i < ncolx; i++)
- if (colxtab[i].kwval == fncact) break;
- printf("%s\n", (i == ncolx) ? "unknown" : colxtab[i].kwd);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" File destination: %s\n",
- (dest == DEST_D) ? "disk" :
- ((dest == DEST_S) ? "screen" :
- ((dest == DEST_N) ? "nowhere" :
- "printer"))
- );
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- s = (keep >= 0 && keep <= 2) ? ifdnam[keep] : "keep";
- printf(" File incomplete: %s\n",s);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" File bytesize: %d\n",(fmask == 0177) ? 7 : 8);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#ifndef NOCSETS
- printf(" File character-set: %s\n",fcsinfo[fcharset].keyword);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" File default 7-bit: %s\n",fcsinfo[dcset7].keyword);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" File default 8-bit: %s\n",fcsinfo[dcset8].keyword);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#ifdef UNICODE
- printf(" File UCS bom: %s\n",showoff(ucsbom));
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" File UCS byte-order: %s-endian\n",
- ucsorder ? "little" : "big");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" Computer byteorder: %s-endian\n",
- byteorder ? "little" : "big");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#endif /* UNICODE */
-#endif /* NOCSETS */
-
- printf(" File end-of-line: ");
- i = feol;
- switch (feol) {
- case XYFA_C: printf("%s\n","cr"); break;
- case XYFA_L: printf("%s\n","lf"); break;
- case XYFA_2: printf("%s\n","crlf"); break;
- default: printf("%d\n",i);
- }
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#endif /* NOXFER */
-
-#ifdef CK_CTRLZ
- printf(" File eof: %s\n", eofmethod ? "ctrl-z" : "length");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#endif /* CK_CTRLZ */
-#ifndef NOXFER
-#ifdef CK_TMPDIR
- printf(" File download-directory: %s\n", dldir ? dldir : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#ifdef COMMENT
- i = 256;
- s = line;
- zzstring("\\v(tmpdir)",&s,&i);
- printf(" Temporary directory: %s\n", line);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#endif /* COMMENT */
-#endif /* CK_TMPDIR */
-#ifdef VMS
- {
- extern int vmssversions, vmsrversions;
- printf(" Send version-numbers: %s\n",showoff(vmssversions));
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" Receive version-numbers: %s\n",showoff(vmsrversions));
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- }
-#endif /* VMS */
- printf(" Send move-to: %s\n",
- snd_move ? snd_move : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" Send rename-to: %s\n",
- snd_rename ? snd_rename : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" Receive move-to: %s\n",
- rcv_move ? rcv_move : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" Receive rename-to: %s\n",
- rcv_rename ? rcv_rename : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#endif /* NOXFER */
-#ifdef KERMRC
- printf(" Initialization file: %s\n", noinit ? "(none)" :
-#ifdef CK_SYSINI
- CK_SYSINI
-#else
- kermrc
-#endif /* CK_SYSINI */
- );
-#endif /* KERMRC */
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-
- if (k_info_dir) {
- printf(" Kermit doc files: %s\n", k_info_dir);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- }
-
-#ifdef CKROOT
- s = zgetroot();
- printf(" Root set: %s\n", s ? s : "(none)");
-#endif /* CKROOT */
-
-#ifdef UNIX
- printf(" Disk output buffer: %d (writes are %s, %s)\n",
- zobufsize,
- zofbuffer ? "buffered" : "unbuffered",
- zofblock ? "blocking" : "nonblocking"
- );
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#ifdef DYNAMIC
- printf(" Stringspace: %d\n", zsetfil(0,2));
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" Listsize: %d\n", zsetfil(0,4));
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#endif /* DYNAMIC */
-#endif /* UNIX */
-#ifdef OS2ORUNIX
- printf(" Longest filename: %d\n", maxnam);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" Longest pathname: %d\n", maxpath);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
-#endif /* OS2ORUNIX */
-
- printf(" Last file sent: %s\n", sfspec ? sfspec : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" Last file received: %s\n", rfspec ? rfspec : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf("\n Also see:\n");
- n++;
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf(" SHOW PROTOCOL, SHOW XFER");
-#ifdef CK_LABELED
- printf(", SHOW LABELED");
-#endif /* CK_LABELED */
-#ifdef PATTERNS
- printf(", SHOW PATTERNS");
-#endif /* PATTERNS */
-#ifdef STREAMING
- printf(", SHOW STREAMING");
-#endif /* STREAMING */
-#ifndef NOCSETS
- printf(", SHOW CHARACTER-SETS");
-#endif /* NOCSETS */
- printf("\n\n");
-}
-
-#ifndef NOXFER
-VOID
-shoparp() { /* Protocol */
- extern int docrc, skipbup;
- char *s;
-
-#ifdef CK_TIMERS
- extern int rttflg;
-#endif /* CK_TIMERS */
-
- printf("Protocol: %s\n",ptab[protocol].p_name);
-
- if (protocol == PROTO_K) {
- printf("\nProtocol Parameters: Send Receive");
- if (timef)
- printf("\n Timeout (used=%2d):%7d*%8d ", timint, rtimo, pkttim);
- else
- printf("\n Timeout (used=%2d):%7d%9d ", timint, rtimo, pkttim);
-#ifdef XFRCAN
- printf(" Cancellation: %s",showoff(xfrcan));
- if (xfrcan)
- printf(" %d %d", xfrchr, xfrnum);
-#endif /* XFRCAN */
- printf("\n Padding: %11d%9d", npad, mypadn);
- if (bctr == 4)
- printf(" Block Check: blank-free-2\n");
- else
- printf(" Block Check: %6d\n",bctr);
- printf( " Pad Character:%11d%9d", padch, mypadc);
- printf(" Delay: %6d\n",ckdelay);
- printf( " Pause: %11d%9d", pktpaus, pktpaus);
- printf(" Attributes: %s\n",showoff(atcapr));
- printf( " Packet Start: %11d%9d", mystch, stchr);
- printf(" Max Retries: %6d%s\n",
- maxtry,
- (maxtry == 0) ? " (unlimited)" : ""
- );
- printf( " Packet End: %11d%9d", seol, eol);
- if (ebqflg)
- printf(" 8th-Bit Prefix: '%c'",ebq);
- else
- printf(" 8th-Bit Prefix: ('%c' but not used)",ebq);
- printf( "\n Packet Length:%11d ", spmax);
- printf("%8d ", urpsiz);
- if (rptflg)
- printf(" Repeat Prefix: '%c'",rptq);
- else
- printf(" Repeat Prefix: ('%c' but not used)",rptq);
- printf( "\n Maximum Length: %9d%9d", maxsps, maxrps);
- printf(" Window Size:%7d set, %d used\n",wslotr,wmax);
- printf( " Buffer Size: %11d%9d", bigsbsiz, bigrbsiz);
- printf(" Locking-Shift: ");
- if (lscapu == 2) {
- printf("forced");
- } else {
- printf("%s", (lscapr ? "enabled" : "disabled"));
- if (lscapr) printf(",%s%s", (lscapu ? " " : " not "), "used");
- }
- printf("\n\n");
-
- if (!(s = ptab[protocol].h_b_init)) s = "";
- printf(" Auto-upload command (binary): ");
- if (*s) {
- shostrdef((CHAR *)s);
- printf("\n");
- } else {
- printf("(none)\n");
- }
- if (!(s = ptab[protocol].h_t_init)) s = "";
- printf(" Auto-upload command (text): ");
- if (*s) {
- shostrdef((CHAR *)s);
- printf("\n");
- } else {
- printf("(none)\n");
- }
- if (!(s = ptab[protocol].h_x_init)) s = "";
- printf(" Auto-server command: ");
- if (*s) {
- shostrdef((CHAR *)s);
- printf("\n");
- } else {
- printf("(none)\n");
- }
- tmpbuf[0] = NUL;
-#ifdef CK_TIMERS
- if (rttflg) {
- extern int mintime, maxtime;
- sprintf(tmpbuf," Packet timeouts: dynamic %d:%d", /* SAFE */
- mintime,
- maxtime);
- } else {
- sprintf(tmpbuf," Packet timeouts: fixed"); /* SAFE */
- }
-#endif /* CK_TIMERS */
- if (tmpbuf[0])
- printf("%-31s",tmpbuf);
- printf("Send backup: %s\n",showoff(!skipbup));
-
- printf(" Transfer mode: %s", xfermode == XMODE_A ?
- "automatic " :
- "manual "
- );
- printf(" Transfer slow-start: %s, crc: %s\n",
- showoff(slostart),
- showoff(docrc)
- );
-#ifdef PIPESEND
- {
- extern int usepipes;
- printf(" Transfer pipes: %s ",usepipes ? "on " : "off");
- }
-#endif /* PIPESEND */
-#ifndef NOCSETS
- printf(" Transfer character-set: ");
- if (tcharset == TC_TRANSP)
- printf("transparent\n");
- else
- printf("%s\n", tcsinfo[tcharset].keyword );
-#endif /* NOCSETS */
-#ifdef PIPESEND
- {
- extern char * sndfilter, * rcvfilter;
- printf(" Send filter: %s\n", sndfilter ? sndfilter : "(none)");
- printf(" Receive filter: %s\n", rcvfilter ? rcvfilter : "(none)");
- }
-#endif /* PIPESEND */
- printf("\nAlso see:\n");
- printf(" SHOW FILE, SHOW XFER");
-
-#ifdef CK_LABELED
- printf(", SHOW LABELED");
-#endif /* CK_LABELED */
-#ifdef PATTERNS
- printf(", SHOW PATTERNS");
-#endif /* PATTERNS */
-#ifdef STREAMING
- printf(", SHOW STREAMING");
-#endif /* STREAMING */
-#ifndef NOCSETS
- printf(", SHOW CHARACTER-SETS");
-#endif /* NOCSETS */
- }
-
-#ifdef CK_XYZ
-#ifdef XYZ_INTERNAL
- if (protocol != PROTO_K) {
- int i;
- int x;
- printf(" File type: %s\n", binary ? "binary" : "text");
- if (protocol == PROTO_Z) { /* Zmodem */
- printf(" Window size: ");
- if (ptab[protocol].winsize < 1)
- printf("none\n");
- else
- printf("%d\n",wslotr);
-#ifdef COMMENT
- printf(" Packet (frame) length: ");
- if (ptab[protocol].spktlen < 0)
- printf("none\n");
- else
- printf("%d\n",spmax);
-#endif /* COMMENT */
- } else {
- if (ptab[protocol].spktlen >= 1000)
- printf(" 1K packets\n");
- else
- printf(" 128-byte packets\n");
- }
- printf(" Pathname stripping when sending: %s\n",
- showoff(ptab[protocol].fnsp)
- );
- printf(" Pathname stripping when receiving: %s\n",
- showoff(ptab[protocol].fnrp)
- );
- printf(" Filename collision action: ");
- for (i = 0; i < ncolx; i++)
- if (colxtab[i].kwval == fncact) break;
- printf("%-12s", (i == ncolx) ? "unknown" : colxtab[i].kwd);
-
- printf("\n Escape control characters: ");
- x = ptab[protocol].prefix;
- if (x == PX_ALL)
- printf("all\n");
- else if (x == PX_CAU || x==PX_WIL)
- printf("minimal\n");
- else
- printf("none\n");
- if (!(s = ptab[protocol].h_b_init))
- s = "";
- printf(" Autoreceive command (binary): %s\n", *s ? s : "(none)");
- if (!(s = ptab[protocol].h_t_init))
- s = "";
- printf(" Autoreceive command (text): %s\n", *s ? s : "(none)");
- }
-#else
-#ifndef NOPUSH
- if (protocol != PROTO_K) {
- _PROTOTYP( VOID shoextern, (void) );
- printf("\nExecuted by external commands:\n\n");
- s = ptab[protocol].p_b_scmd;
- if (!s) s = "";
- printf(" SEND command (binary): %s\n", *s ? s : "(none)");
- s = ptab[protocol].p_t_scmd;
- if (!s) s = "";
- printf(" SEND command (text): %s\n", *s ? s : "(none)");
- s = ptab[protocol].p_b_rcmd;
- if (!s) s = "";
- printf(" RECEIVE command (binary): %s\n", *s ? s : "(none)");
- s = ptab[protocol].p_t_rcmd;
- if (!s) s = "";
- printf(" RECEIVE command (text): %s\n", *s ? s : "(none)");
- s = ptab[protocol].h_b_init;
- if (!s) s = "";
- printf(" Autoreceive command (binary): %s\n", *s ? s : "(none)");
- s = ptab[protocol].h_t_init;
- if (!s) s = "";
- printf(" Autoreceive command (text): %s\n", *s ? s : "(none)");
- (VOID) shoextern();
- }
-#endif /* NOPUSH */
-#endif /* XYZ_INTERNAL */
-#endif /* CK_XYZ */
-}
-#endif /* NOXFER */
-
-#ifndef NOCSETS
-/* Character-set items */
-
-extern int s_cset, r_cset, axcset[], afcset[];
-extern struct keytab xfrmtab[];
-
-VOID
-shoparl() {
-#ifdef COMMENT
- int i;
-/* Misleading... */
- printf("\nAvailable Languages:\n");
- for (i = 0; i < MAXLANG; i++) {
- printf(" %s\n",langs[i].description);
- }
-#else
- printf("\nLanguage-specific translation rules: %s\n",
- language == L_USASCII ? "none" : langs[language].description);
- shocharset();
- printf("\n\n");
-#endif /* COMMENT */
-}
-
-VOID
-shocharset() {
- int x;
-#ifdef COMMENT
- char * s = "Unknown";
- extern int xlatype;
-#endif /* COMMENT */
-
-#ifndef NOXFER
- extern int xfrxla;
-#endif /* NOXFER */
-
- debug(F101,"SHOW FILE CHAR","",fcharset);
- printf("\n");
-#ifndef NOXFER
- printf(" Transfer Translation: %s\n", showoff(xfrxla));
- if (!xfrxla) {
- printf(
- " Because transfer translation is off, the following are ignored:\n\n");
- }
-#endif /* NOXFER */
- printf(" File Character-Set: %s (%s), ",
- fcsinfo[fcharset].keyword,
- fcsinfo[fcharset].name
- );
- if ((x = fcsinfo[fcharset].size) == 128)
- printf("7-bit");
- else if (x == 256)
- printf("8-bit");
- else
- printf("multibyte");
- printf("\n");
- printf(" File Scan: %s\n",showoff(filepeek));
- printf(" Default 7bit-Character-Set: %s\n",fcsinfo[dcset7].keyword);
- printf(" Default 8bit-Character-Set: %s\n",fcsinfo[dcset8].keyword);
- printf(" Transfer Character-Set");
-#ifdef COMMENT
- if (tslevel == TS_L2)
- printf(": (international)");
- else
-#endif /* COMMENT */
- if (tcharset == TC_TRANSP)
- printf(": Transparent");
- else
- printf(": %s (%s)",tcsinfo[tcharset].keyword, tcsinfo[tcharset].name);
- printf("\n");
-#ifdef COMMENT
- switch (xlatype) {
- case XLA_NONE: s = "None"; break;
- case XLA_BYTE: s = "Byte"; break;
- case XLA_JAPAN: s = "Japanese"; break;
- case XLA_UNICODE: s = "Unicode"; break;
- }
- printf("\n Translation type: %s\n",s);
-#endif /* COMMENT */
- printf(" SEND character-set-selection: %s\n",xfrmtab[s_cset].kwd);
- printf(" RECEIVE character-set-selection: %s\n",xfrmtab[r_cset].kwd);
- if (s_cset == XMODE_A || r_cset == XMODE_A)
- printf(
- " (Use SHOW ASSOCIATIONS to list automatic character-set selections.)\n"
- );
-}
-
-VOID
-showassoc() {
- int i, k, n = 4;
- char * s;
- printf("\nFor incoming files:\n\n");
- printf("Transfer Character-Set File Character-Set\n");
- for (i = 1; i <= MAXTCSETS; i++) {
- k = axcset[i];
- if (k < 0 || k > MAXFCSETS)
- s = "(none)";
- else
- s = fcsinfo[k].keyword;
- if (!s) s = "";
- if (!*s) s = "(none)";
- printf(" %-25s%s\n",tcsinfo[i].keyword,s);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- }
- printf("\nFor outbound files:\n\n");
- n += 2;
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- printf("File Character-Set Transfer Character-Set\n");
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- for (i = 0; i <= MAXFCSETS; i++) {
- k = afcset[i];
- if (k < 0 || k > MAXTCSETS)
- s = "(none)";
- else
- s = tcsinfo[k].keyword;
- if (!s) s = "";
- if (!*s) s = "(none)";
- printf(" %-25s%s\n",fcsinfo[i].keyword,s);
- if (++n > cmd_rows - 3) if (!askmore()) return; else n = 0;
- }
-}
-#endif /* NOCSETS */
-
-VOID
-shopar() {
- printf("Show what? (Type \"show ?\" for a list of possibilities.)\n");
-}
-#endif /* NOSHOW */
-
-#ifndef NOXFER
-/* D O S T A T -- Display file transfer statistics. */
-
-int
-dostat(brief) int brief; {
- extern long filrej, peakcps;
- extern int lastspmax, streamed, cleared, streamok;
- extern char whoareu[];
- int n = 0, ftp = 0;
- extern int docrc, interrupted, fatalio;
-
- ftp = lastxfer & W_FTP;
-
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- if (tt_cols[VTERM] < 0 || tt_rows[VTERM] < 0)
- ttgwsiz();
-#else /* OS2 */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
- debug(F101,"dostat xferstat","",xferstat);
- if (xferstat < 0) {
- printf(" No file transfers yet.\n");
- return(1);
- }
- n = 0;
- if (brief) { printf("\n"); n++; };
- printf(" protocol : %s\n",
- ftp ? "ftp" : ptab[protocol].p_name);
- n++;
- printf(" status : ");
- if (xferstat) printf("SUCCESS\n");
- else if (interrupted) printf("FAILURE (interrupted)\n");
- else if (fatalio) printf("FAILURE (i/o error)\n");
- else printf("FAILURE\n");
-#ifndef XYZ_INTERNAL
- if (!ftp && protocol != PROTO_K) {
- printf("\n external protocol statistics not available\n");
- return(1);
- }
-#endif /* XYZ_INTERNAL */
- n++;
- if (!ftp) {
- if (!xferstat > 0) {
- if (docrc)
- printf(" crc-16 of file(s) : %ld\n", crc16);
- else
- printf(" crc-16 of file(s) : (disabled)\n");
- n++;
- }
- if (!xferstat && *epktmsg) {
- printf(" reason : %s\n", epktmsg);
- n++;
- }
- }
- if (!brief) {
-#ifdef NEWFTP
- if (ftp) {
- extern char ftp_srvtyp[];
- printf(" remote system type : %s\n",ftp_srvtyp);
- } else
-#endif /* NEWFTP */
- if (whoareu[0]) {
- printf(" remote system type : %s\n",
- getsysid((char *)whoareu));
- n++;
- }
- printf(" files transferred : %ld\n",filcnt - filrej);
- if (!ftp)
- printf(" files not transferred : %ld\n",filrej);
- printf(" characters last file : %s\n",ckfstoa(ffc));
- printf(" total file characters : %s\n",ckfstoa(tfc));
- n += ftp ? 3 : 4;
- if (!ftp) {
- printf(" communication line in : %s\n",ckfstoa(tlci));
- printf(" communication line out : %s\n",ckfstoa(tlco));
- printf(" packets sent : %d\n", spackets);
- printf(" packets received : %d\n", rpackets);
- n += 4;
- }
- }
- if (ftp) goto dotimes;
-
- printf(" damaged packets rec'd : %d\n", crunched);
- printf(" timeouts : %d\n", timeouts);
- printf(" retransmissions : %d\n", retrans);
- n += 3;
-
- if (!brief) {
- if (filcnt > 0) {
- printf(" parity : %s",parnam((char)parity));
- n++;
- if (autopar) { printf(" (detected automatically)"); n++; }
- printf(
- "\n control characters : %ld prefixed, %ld unprefixed\n",
- ccp, ccu);
- n++;
- printf(" 8th bit prefixing : ");
- n++;
- if (ebqflg) printf("yes [%c]\n",ebq); else printf("no\n");
- n++;
- printf(" locking shifts : %s\n", lscapu ? "yes" : "no");
- n++;
- }
- }
- if (++n > cmd_rows - 3) { if (!askmore()) return(1); else n = 0; }
- if (streamed > 0)
- printf(" window slots used : (streaming)\n");
- else
- printf(" window slots used : %d of %d\n", wmax, wslotr);
- if (++n > cmd_rows - 3) { if (!askmore()) return(1); else n = 0; }
- printf(" reliable: : %s%s\n",
- streamok ? "" : "not ", "negotiated");
- if (++n > cmd_rows - 3) { if (!askmore()) return(1); else n = 0; }
- printf(" clearchannel: : %s%s\n",
- cleared ? "" : "not ", "negotiated");
- if (++n > cmd_rows - 3) { if (!askmore()) return(1); else n = 0; }
-
- if (!brief) {
- printf(" packet length : %d (send), %d (receive)\n",
- lastspmax, urpsiz);
- if (++n > cmd_rows - 3) { if (!askmore()) return(1); else n = 0; }
- printf(" compression : ");
- if (rptflg)
- printf("yes [%c] (%ld)\n",(char) rptq,rptn);
- else
- printf("no\n");
- if (++n > cmd_rows - 3) { if (!askmore()) return(1); else n = 0; }
- if (bctu == 4)
- printf(" block check type used : blank-free-2\n");
- else
- printf(" block check type used : %d\n",bctu);
- if (++n > cmd_rows - 3) { if (!askmore()) return(1); else n = 0; }
- }
-
- dotimes:
-
-#ifdef GFTIMER
-#ifdef COMMENT
- printf(" elapsed time : %0.3f sec, %s\n", fptsecs,hhmmss(tsecs));
-#endif /* COMMENT */
- printf(" elapsed time : %s (%0.3f sec)\n",
- hhmmss((long)(fptsecs + 0.5)),fptsecs);
-#else
-#ifdef COMMENT
- printf(" elapsed time : %s (%d sec)\n",hhmmss(tsecs),tsecs);
-#endif /* COMMENT */
- printf(" elapsed time : %d sec, %s\n",tsecs,hhmmss(tsecs));
-#endif /* GFTIMER */
- if (++n > cmd_rows - 3) { if (!askmore()) return(1); else n = 0; }
- if (!ftp && local && !network && !brief) {
- if (speed <= 0L) speed = ttgspd();
- if (speed > 0L) {
- if (speed == 8880)
- printf(" transmission rate : 75/1200 bps\n");
- else
- printf(" transmission rate : %ld bps\n",speed);
- if (++n > cmd_rows - 3) { if (!askmore()) return(1); else n = 0; }
- }
- }
- if (!ftp && local && !network && /* Only makes sense for */
- mdmtyp == 0 && /* direct serial connections */
- speed > 99L && /* when we really know the speed */
- speed != 8880L
- ) {
- int eff;
- eff = (((tfcps * 100L) / (speed / 100L)) + 5L) / 10L;
- printf(" effective data rate : %ld cps (%d%%)\n",tfcps,eff);
- } else
- printf(" effective data rate : %ld cps\n", tfcps);
- if (!ftp && peakcps > 0L && peakcps > tfcps)
- printf(" peak data rate : %ld cps\n", peakcps);
- if (brief)
- printf("\nUse STATISTICS /VERBOSE for greater detail.\n\n");
- return(1);
-}
-#endif /* NOXFER */
-
-#ifndef NOSPL
-
-/* The INPUT command */
-
-/*
- NOTE: An INPUT timeout of 0 means to perform a nonblocking read of the
- material that has already arrived and is waiting to be read, and perform
- matches against it, without doing any further reads. It should succeed
- or fail instantaneously.
-*/
-
-/* Output buffering for "doinput" */
-
-#ifdef pdp11
-#define MAXBURST 16 /* Maximum size of input burst */
-#else
-#define MAXBURST 1024
-#endif /* pdp11 */
-#ifdef OSK
-static CHAR *conbuf; /* Buffer to hold output for console */
-#else
-static CHAR conbuf[MAXBURST]; /* Buffer to hold output for console */
-#endif /* OSK */
-static int concnt = 0; /* Number of characters buffered */
-#ifdef OSK
-static CHAR *sesbuf; /* Buffer to hold output for session log */
-#else
-static CHAR sesbuf[MAXBURST]; /* Buffer to hold output for session log */
-#endif /* OSK */
-static int sescnt = 0; /* Number of characters buffered */
-
-extern int debses; /* TERMINAL DEBUG ON/OFF */
-
-static VOID /* Flush INPUT echoing */
-myflsh() { /* and session log output. */
- if (concnt > 0) {
- if (debses) { /* Terminal debugging? */
- int i;
- for (i = 0; i < concnt; i++)
- conol(dbchr(conbuf[i]));
- } else
- conxo(concnt, (char *) conbuf);
- concnt = 0;
- }
- if (sescnt > 0) {
- logstr((char *) sesbuf, sescnt);
- sescnt = 0;
- }
-}
-
-/* Execute the INPUT and MINPUT commands */
-
-int instatus = -1;
-long inetime = -1L;
-int inwait = 0;
-int nowrap = 0;
-
-/* For returning the input sequence that matched */
-
-#ifdef BIGBUFOK
-#define MATCHBUFSIZ 8191
-#else
-#define MATCHBUFSIZ 1023
-#endif /* BIGBUFOK */
-static char * matchbuf = NULL;
-static int matchindex = 0;
-static int burst = 0; /* Chars remaining in input burst */
-/*
- timo = How long to wait:
- < 0 = Wait forever
- 0 = Don't wait at all - material must already have arrived
- > 0 = Wait this many seconds
- ms = Array of strings to wait for.
- mp = Array of flags.
- If mp[i] == 0, ms[i] is literal, else it's a pattern.
- flags = bit mask
- INPSW_NOM = /NOMATCH = 1
- INPSW_CLR = /CLEAR = 2
- INPSW_NOW = /NOWRAP = 4
- INPSW_COU = /COUNT = 8
- count = /COUNT: value if a /COUNT switch was given.
-
- Returns:
- 0 on failure, 1 on success.
-*/
-#ifndef ES_NORMAL
-#define ES_NORMAL 0
-#endif /* ES_NORMAL */
-extern int inesc[], oldesc[];
-
-int
-doinput(timo,ms,mp,flags,count)
- int timo; char *ms[]; int mp[]; int flags; int count; {
- extern int inintr;
-#ifdef CK_AUTODL
- extern int inautodl;
-#endif /* CK_AUTODL */
- int x, y, i, t, rt, icn, anychar = 0, mi[MINPMAX];
-#ifdef GFTIMER
- CKFLOAT fpt = 0.0;
-#endif /* GFTIMER */
- int savecount = 0;
- int nomatch = 0;
- int clearfirst = 0;
- int lastchar = 0;
- int waiting = 0;
- int imask = 0;
- char ch, *xp, *s;
- CHAR c;
-#ifndef NOLOCAL
-#ifdef OS2
- extern int term_io;
- int term_io_save;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef TNCODE
- static int cr = 0;
-#endif /* TNCODE */
- int is_tn = 0;
-#ifdef SSHBUILTIN
- extern int ssh_cas;
- extern char * ssh_cmd;
-#endif /* SSHBUILTIN */
- int noescseq = 0; /* Filter escape sequences */
-
- debug(F101,"input count","",count);
- debug(F101,"input flags","",flags);
-
-/*
- CK_BURST enables the INPUT speedup code, which depends on ttchk() returning
- accurate information. If INPUT fails with this code enabled, change the
- above "#define" to "#undef".
-*/
-#define CK_BURST
-
-/***** CHANGE THIS TO A SET INPUT PARAMETER *****/
-
- noescseq = (sessft == XYFT_T); /* Filter escape sequences */
-
- imask = cmask;
- if (parity) imask = 0x7f;
- inwait = timo; /* For \v(inwait) */
-
- /* Options from command switches */
-
- nowrap = flags & INPSW_NOW; /* 4 = /NOWRAP */
- nomatch = flags & INPSW_NOM; /* 1 = /NOMATCH */
- clearfirst = flags & INPSW_CLR; /* 2 = /CLEAR */
- savecount = count;
-
- makestr(&inpmatch,NULL);
- if (!matchbuf) {
- matchbuf = malloc(MATCHBUFSIZ+1);
- matchbuf[0] = NUL;
- }
- matchindex = 0;
-
- /* If last time through we returned because of /NOWRAP and buffer full */
- /* now we have to clear the buffer to make room for another load. */
-
- if (nowrap && instatus == INP_BF)
- clearfirst = 1;
-
- if (clearfirst) { /* INPUT /CLEAR */
- int i;
- myflsh(); /* Flush screen and log buffers */
- for (i = 0; i < inbufsize; i++)
- inpbuf[i] = NUL;
- inpbp = inpbuf;
- }
- is_tn =
-#ifdef TNCODE
- (local && network && IS_TELNET()) || (!local && sstelnet)
-#else
- 0
-#endif /* TNCODE */
- ;
-
-#ifdef CK_SSL
- if (is_tn) if (ssl_raw_flag || tls_raw_flag) is_tn = 0;
-#endif /* CK_SSL */
-
- instatus = INP_IE; /* 3 = internal error */
- kbchar = 0;
-
-#ifdef OSK
- if (conbuf == NULL) {
- if ((conbuf = (CHAR *)malloc(MAXBURST*2)) == NULL) {
- return(0);
- }
- sesbuf = conbuf + MAXBURST;
- }
-#endif /* OSK */
-
-#ifndef NOLOCAL
- if (local) { /* In local mode... */
- if ((waiting = ttchk()) < 0) { /* check that connection is open */
- if (!quiet) {
- if ((!network
-#ifdef TN_COMPORT
- || istncomport()
-#endif /* TN_COMPORT */
- ) && carrier != CAR_OFF)
- printf("?Carrier detect failure on %s.\n", ttname);
- else
- printf("?Connection %s %s is not open.\n",
- network ? "to" : "on",
- ttname
- );
- }
- instatus = INP_IO;
- return(0);
- }
- debug(F101,"doinput waiting","",waiting);
- y = ttvt(speed,flow); /* Put line in "ttvt" mode */
- if (y < 0) {
- printf("?INPUT initialization error\n");
- instatus = INP_IO;
- return(0); /* Watch out for failure. */
- }
- }
-#endif /* NOLOCAL */
-
-#ifdef SSHBUILTIN
- if ( network && nettype == NET_SSH && ssh_cas && ssh_cmd &&
- !(strcmp(ssh_cmd,"kermit") && strcmp(ssh_cmd,"sftp"))) {
- if (!quiet)
- printf("?SSH Subsystem active: %s\n", ssh_cmd);
- instatus = INP_IKS;
- return(0);
- }
-#endif /* SSHBUILTIN */
-
- debug(F111,"doinput ms[0]",ms[0],waiting);
-
- if (!ms[0] || isemptystring(ms[0])) { /* No search string was given nor */
- if (count < 2) /* a /COUNT: switch so we just */
- anychar = 1; /* wait for the first character */
- }
- if (nomatch) anychar = 0; /* Don't match anything */
-
- if (!anychar && waiting == 0 && timo == 0)
- return(0);
-
-#ifndef NODEBUG
- if (deblog) {
- char xbuf[24];
- debug(F101,"doinput anychar","",anychar);
- debug(F101,"doinput timo","",timo);
- debug(F101,"doinput echo","",inecho);
-#ifdef CK_BURST
- debug(F101,"doinput burst","",burst);
-#endif /* CK_BURST */
- y = -1;
- while (ms[++y]) {
- sprintf(xbuf,"doinput string %2d",y); /* SAFE (24) */
- debug(F111,xbuf,ms[y],mp[y]);
- }
- }
-#endif /* NODEBUG */
-
-#ifdef IKS_OPTION
- if (is_tn) {
- /* If the remote side is in a state of IKS START-SERVER */
- /* we request that the state be changed. We will detect */
- /* a failure to adhere to the request when we call ttinc() */
- if (TELOPT_U(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start)
- iks_wait(KERMIT_REQ_STOP,0); /* Send Request-Stop */
-#ifdef CK_AUTODL
- /* If we are processing packets during INPUT and we have not */
- /* sent a START message, do so now. */
- if (inautodl && TELOPT_ME(TELOPT_KERMIT) &&
- !TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_START); /* Send Kermit-Server Start */
- }
-#endif /* CK_AUTODL */
- }
-#endif /* IKS_OPTION */
- x = 0; /* Return code, assume failure */
- instatus = INP_TO; /* Status, assume timeout */
-
- for (y = 0; y < MINPMAX; y++) /* Initialize... */
- mi[y] = 0; /* ..string pattern match position */
-
- if (!inpcas[cmdlvl]) { /* INPUT CASE = IGNORE? */
- y = -1;
- while ((xp = ms[++y])) { /* Convert each target to lowercase */
- while (*xp) {
- if (isupper(*xp)) *xp = (char) tolower(*xp);
- xp++;
- }
- }
- }
- rtimer(); /* Reset timer. */
-#ifdef GFTIMER
- rftimer(); /* Floating-point timer too. */
-#endif /* GFTIMER */
- inetime = -1L; /* Initialize elapsed time. */
- t = 0; /* Time now is 0. */
- m_found = 0; /* Default to timed-out */
- incount = 0; /* Character counter */
- rt = (timo == 0) ? 0 : 1; /* Character-read timeout interval */
-
-#ifndef NOLOCAL
-#ifdef OS2
- term_io_save = term_io; /* Disable I/O by emulator */
- term_io = 0;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
- while (1) { /* Character-getting loop */
-#ifdef CK_APC
- /* Check to see if there is an Autodown or other APC command */
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && apcstatus != APC_OFF)) {
- if (mlook(mactab,"_apc_commands",nmac) == -1) {
- debug(F110,"doinput about to execute APC",apcbuf,0);
- domac("_apc_commands",apcbuf,cmdstk[cmdlvl].ccflgs|CF_APC);
- delmac("_apc_commands",1);
- apcactive = APC_INACTIVE;
-#ifdef DEBUG
- } else {
- debug(F100,"doinput APC in progress","",0);
-#endif /* DEBUG */
- }
- }
-#endif /* CK_APC */
-
- if (timo == 0 && waiting < 1) { /* Special exit criterion */
- instatus = INP_TO; /* for timeout == 0 */
- break;
- }
- if (local) { /* One case for local */
- y = ttinc(rt); /* Get character from comm device */
- debug(F101,"doinput ttinc(rt) returns","",y);
- if (y < -1) { /* Connection failed. */
- instatus = INP_IO; /* Status = i/o error */
-#ifndef NOLOCAL
-#ifdef OS2
- term_io = term_io_save;
-#endif /* OS2 */
-#endif /* NOLOCAL */
- switch (y) {
- case -2: /* Connection lost */
- if (local && !network && carrier != CAR_OFF) {
- dologend();
- printf("Connection closed.\n");
- ttclos(1);
- }
- break;
- case -3:
- dologend();
- printf("Session Limit exceeded - closing connection.\n");
- ttclos(1);
- default:
- break;
- }
- debug(F111,"doinput Connection failed","returning 0",y);
- return(0);
- }
- if (inintr) {
- debug(F111,"doinput","inintr",inintr);
- if ((icn = conchk()) > 0) { /* Interrupted from keyboard? */
- debug(F101,"input interrupted from keyboard","",icn);
- kbchar = coninc(0);
- if (kbchar >= 0) {
- while (--icn > 0) {
- debug(F110,"doinput","absorbing",0);
- coninc(0); /* Yes, absorb what was typed. */
- }
- instatus = INP_UI; /* Fail and remember why. */
- break;
- }
- }
- }
- } else { /* Another for remote */
- y = coninc(rt);
- debug(F101,"doinput coninc(rt) returns","",y);
- }
- if (y > -1) { /* A character arrived */
- debug(F111,"doinput","a character arrived",y);
- if (timo == 0)
- waiting--;
-#ifndef OS2
-#define TN_NOLO
-#endif /* OS2 */
-#ifdef NOLOCAL
-#define TN_NOLO
-#endif /* NOLOCAL */
-
-#ifdef TN_NOLO
- debug(F100,"doinput TN_NOLO","",0);
-#ifdef TNCODE
- /* Check for telnet protocol negotiation */
- if (is_tn) {
- switch (y & 0xff) {
- case IAC:
- cr = 0;
- myflsh(); /* Break from input burst for tn_doop() */
-#ifdef CK_BURST
- burst = 0;
-#endif /* CK_BURST */
- waiting -= 2; /* (not necessarily...) */
- switch (tn_doop((CHAR)(y & 0xff),duplex,ttinc)) {
- case 2: duplex = 0; continue;
- case 1: duplex = 1; continue;
-#ifdef IKS_OPTION
- case 4:
- if (TELOPT_SB(TELOPT_KERMIT).kermit.u_start &&
- !tcp_incoming) {
- instatus = INP_IKS;
- printf(
- " Internet Kermit Service in SERVER mode.\n Please use REMOTE commands.\n"
- );
- break;
- }
- continue;
-#endif /* IKS_OPTION */
- case 6: /* TELNET DO LOGOUT received */
- continue;
- case 7:
- case 3: /* A quoted IAC */
- break;
- default:
- continue;
- }
- case CR:
- cr = 1;
- break;
- case NUL:
- if (!TELOPT_U(TELOPT_BINARY) && cr) {
- cr = 0;
- continue;
- }
- cr = 0;
- break;
- default:
- cr = 0;
- }
- /* I'm echoing remote chars */
- if (TELOPT_ME(TELOPT_ECHO) && tn_rem_echo)
- ttoc((char)y);
- }
-#endif /* TNCODE */
-#ifdef CK_AUTODL
- /* Check for file transfer packets */
- if (inautodl) autodown(y);
-#endif /* CK_AUTODL */
-#else /* TN_NOLO */
- debug(F100,"doinput !TN_NOLO","",0);
-#ifdef TNCODE
- /* Check for telnet protocol negotiation */
- if (is_tn) {
- int tx;
- switch (y & 0xff) {
- case IAC:
- myflsh(); /* Break from input burst for tn_doop() */
-#ifdef CK_BURST
- burst = 0;
-#endif /* CK_BURST */
-#ifdef IKS_OPTION
- tx = scriptwrtbuf((USHORT)y);
- if (tx == 4) {
- if (TELOPT_U(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start &&
- !tcp_incoming
- ) {
- instatus = INP_IKS;
- printf(
- " Internet Kermit Service in SERVER mode.\n Please use REMOTE commands.\n"
- );
- break;
- }
- } else if (tx == 6) {
- /* TELNET DO LOGOUT received */
-
- }
-#else /* IKS_OPTION */
- /* Handles Telnet negotiations */
- tx = scriptwrtbuf((USHORT)y);
- if (tx == 6) {
- /* TELNET DO LOGOUT received */
- }
-#endif /* IKS_OPTION */
- waiting -= 2; /* (not necessarily...) */
- cr = 0;
- continue; /* and autodownload check */
- case CR:
- cr = 1;
- tx = scriptwrtbuf((USHORT)y);
- if (tx == 6) {
- /* TELNET DO LOGOUT received */
- }
- break;
- case NUL:
- cr = 0;
- if (!TELOPT_U(TELOPT_BINARY) && cr)
- continue;
- tx = scriptwrtbuf((USHORT)y);
- if (tx == 6) {
- /* TELNET DO LOGOUT received */
- }
- break;
- default:
- cr = 0;
- tx = scriptwrtbuf((USHORT)y);
- if (tx == 6) {
- /* TELNET DO LOGOUT received */
- }
- }
- /* I'm echoing remote chars */
- if (TELOPT_ME(TELOPT_ECHO) && tn_rem_echo)
- ttoc((CHAR)y);
- } else
-#endif /* TNCODE */
- /* Handles terminal emulation responses */
- scriptwrtbuf((USHORT)y);
-#endif /* TN_NOLO */
-
- /* Real input character to be checked */
-
-#ifdef CK_BURST
- burst--; /* One less character waiting */
- debug(F101,"doinput burst","",burst);
-#endif /* CK_BURST */
- c = (CHAR) (imask & (CHAR) y); /* Mask off any parity */
- inchar[0] = c; /* Remember character for \v(inchar) */
-#ifdef COMMENT
-#ifdef CK_BURST
- /* Update "lastchar" time only once during input burst */
- if (burst <= 0)
-#endif /* CK_BURST */
-#endif /* COMMENT */
- lastchar = gtimer(); /* Remember when it came */
-
- if (c == '\0') { /* NUL, we can't use it */
- if (anychar) { /* Except if any character will do? */
- x = 1; /* Yes, done. */
- instatus = INP_OK;
- incount = 1; /* This must be the first and only. */
- break;
- } else goto refill; /* Otherwise continue INPUTting */
- }
- *inpbp++ = c; /* Store char in circular buffer */
- incount++; /* Count it for \v(incount) */
-
- if (flags & INPSW_COU) { /* INPUT /COUNT */
- if (--count < 1) {
- x = 1;
- instatus = INP_OK;
- incount = savecount;
- break;
- }
- }
- if (matchbuf) {
- if (matchindex < MATCHBUFSIZ) {
- matchbuf[matchindex++] = c;
- matchbuf[matchindex] = NUL;
- }
- }
-#ifdef MAC
- {
- extern char *ttermw; /* fake pointer cast */
- if (inecho) {
- outchar(ttermw, c); /* echo to terminal window */
- /* this might be too much overhead to do here ? */
- updatecommand(ttermw);
- }
- }
-#else /* Not MAC */
- if (inecho) { /* Buffer console output */
- conbuf[concnt++] = c;
- }
-#endif /* MAC */
-#ifndef OS2
- if (seslog) {
- int dummy = 0, skip = 0;
-#ifndef NOLOCAL
- if (noescseq) {
- dummy = chkaes(c,0);
- if (inesc[0] != ES_NORMAL || oldesc[0] != ES_NORMAL)
- skip = 1;
- }
-#endif /* NOLOCAL */
-#ifdef UNIXOROSK
- if (sessft == XYFT_T) {
-#ifdef UNIX
- if (c == '\r')
-#else
-#ifdef OSK
- if (c == '\012')
-#endif /* OSK */
-#endif /* UNIX */
- skip = 1;
- }
-#endif /* UNIXOROSK */
- if (!skip)
- sesbuf[sescnt++] = c; /* Buffer session log output */
- }
-#endif /* OS2 */
- if (anychar) { /* Any character will do? */
- x = 1;
- instatus = INP_OK;
- break;
- }
- if (!inpcas[cmdlvl]) { /* Ignore alphabetic case? */
- if (isupper(c)) /* Yes, convert input char to lower */
- c = (CHAR) tolower(c);
- }
- debug(F000,"doinput char","",c);
-
- /* Here is the matching section */
-
- y = -1; /* Loop thru search strings */
- while (!nomatch && (s = ms[++y])) { /* ...as many as we have. */
- if (mp[y]) { /* Pattern match? */
-#ifdef COMMENT
- int j;
- /* This is gross but it works... */
- /* We could just as easily have prepended '*' to the */
- /* pattern and skipped the loop, except then we would */
- /* not have any way to identify the matching string. */
- for (j = 0; j < matchindex; j++) {
- if (ckmatch(s,&matchbuf[j],1,1)) {
- matchindex = j;
- instatus = INP_OK;
- x = 1;
- break;
- }
- }
- if (x > 0)
- break;
-#else
- /* July 2001 - ckmatch() returns match position. */
- /* It works and it's not gross. */
- /* (4 = floating pattern) */
- x = ckmatch(s,matchbuf,inpcas[cmdlvl],1+4);
- if (x > 0) {
- matchindex = x - 1;
- instatus = INP_OK;
- x = 1;
- break;
- }
-#endif /* COMMENT */
- continue;
- } /* Literal match. */
- i = mi[y]; /* Match-position in search string. */
- debug(F000,"compare char","",(CHAR)s[i]);
- if (c == (CHAR) s[i]) { /* Check for match */
- i++; /* Got one, go to next character */
- } else { /* Don't have a match */
- int j;
- for (j = i; i > 0; ) { /* Back up in search string */
- i--; /* (Do this here to prevent compiler foulup) */
- /* j is the length of the substring that matched */
- if (c == (CHAR) s[i]) {
- if (!strncmp(s,&s[j-i],i)) {
- i++; /* c actually matches -- cfk */
- break;
- }
- }
- }
- }
- if ((CHAR) s[i] == (CHAR) '\0') { /* Matched to end? */
- ckstrncpy(matchbuf,ms[y],MATCHBUFSIZ);
- matchindex = 0;
- instatus = INP_OK; /* Yes, */
- x = 1;
- break; /* done. */
- }
- mi[y] = i; /* No, remember match-position */
- }
- if (x == 1) { /* Set \v(minput) result */
- instatus = INP_OK;
- m_found = y + 1;
- break;
- }
- if (inpbp >= inpbuf + inbufsize) { /* Reached end of buffer? */
- if (nowrap) { /* If /NOWRAP...*/
- instatus = INP_BF; /* ...return indicating buffer full. */
- *inpbp = NUL;
- goto xinput;
- }
- *inpbp = NUL; /* Make it null-terminated */
- inpbp = inpbuf; /* Yes. */
- }
- }
-#ifdef CK_BURST
- else if (y <= -1 && burst > 0) {
- debug(F111,"doinput (y<=-1&&burst>0)","burst",burst);
- /* A timeout occurred so there can't */
- burst = 0; /* be data waiting; must check timo */
- }
- refill:
- if (burst <= 0) { /* No buffered chars remaining... */
- myflsh(); /* Flush buffered output */
- if (local) { /* Get size of next input burst */
- burst = ttchk();
- if (burst < 0) { /* ttchk() says connection is closed */
- instatus = INP_IO; /* Status = i/o error */
-#ifndef NOLOCAL
-#ifdef OS2
- term_io = term_io_save;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
- if ((!network
-#ifdef TN_COMPORT
- || istncomport()
-#endif /* TN_COMPORT */
- ) && carrier != CAR_OFF) {
- /* The test is written this way because the Microsoft compiler
- * is producing bad code if written:
- *
- * if (network && (!istncomport() || carrier == CAR_OFF) )
- */
- break;
- } else {
- printf("Fatal error - disconnected.\n");
- ttclos(1);
- break;
- }
- }
- if (inintr) {
- if ((icn = conchk()) > 0) { /* Interrupt from keyboard? */
- kbchar = coninc(0);
- debug(F101,"input interrupted from keyboard","",icn);
- while (--icn > 0) coninc(0); /* Yes, absorb chars. */
- break; /* And fail. */
- }
- }
- } else {
- burst = conchk();
- }
- debug(F101,"doinput burst","",burst);
- /* Prevent overflow of "conbuf" and "sesbuf" */
- if (burst > MAXBURST)
- burst = MAXBURST;
-
- /* Did not match, timer exceeded? */
- t = gtimer();
- debug(F111,"doinput gtimer","burst",t);
- debug(F101,"doinput timo","",timo);
- if ((t >= timo) && (timo > 0))
- break;
- else if (insilence > 0 && (t - lastchar) > insilence)
- break;
- } else {
- debug(F111,"doinput (burst > 0)","burst",burst);
- }
-#else /* CK_BURST */
- refill:
- myflsh(); /* Flush buffered output */
- /* Did not match, timer exceeded? */
- t = gtimer();
- debug(F111,"doinput gtimer","no burst",t);
- debug(F101,"doinput timo","",timo);
- if ((t >= timo) && (timo > -1))
- break;
- else if (insilence > 0 && (t - lastchar) > insilence)
- break;
-#endif /* CK_BURST */
- } /* Still have time left, continue. */
- xinput:
- myflsh(); /* Flush buffered output */
- if (instatus == INP_BF) { /* Buffer full and /NOWAIT */
- x = 0; /* Must not succeed */
- } else { /* Buffer full and /NOWAIT */
- if (nomatch) x = 1; /* Succeed if nomatch and timed out */
- if (x > 0 && !nomatch)
- instatus = 0;
- }
-#ifndef NOLOCAL
-#ifdef OS2
- term_io = term_io_save;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef COMMENT
-#ifdef IKS_OPTION
-#ifdef CK_AUTODL
- if (is_tn && TELOPT_ME(TELOPT_KERMIT) && inautodl) {
- tn_siks(KERMIT_STOP); /* Send Kermit-Server Stop */
- }
-#endif /* CK_AUTODL */
-#endif /* IKS_OPTION */
-#endif /* COMMENT */
-
-#ifdef GFTIMER
- fpt = gftimer(); /* Get elapsed time */
-
-/* If a long is 32 bits, it would take about 50 days for this to overflow. */
-
- inetime = (int)(fpt * (CKFLOAT)1000.0);
-#else
- inetime = (int)(gtimer() * 1000);
-#endif /* GFTIMER */
-
- if (x > 0)
- makestr(&inpmatch,&matchbuf[matchindex]); /* \v(inmatch) */
- return(x); /* Return the return code. */
-}
-#endif /* NOSPL */
-
-#ifndef NOSPL
-/* REINPUT Command */
-
-/*
- Note, the timeout parameter is required, but ignored. Syntax is compatible
- with MS-DOS Kermit except timeout can't be omitted. This function only
- looks at the characters already received and does not read any new
- characters from the connection.
-*/
-int
-doreinp(timo,s,pat) int timo; char *s; int pat; {
- int x, y, i;
- char *xx, *xp, *xq = (char *)0;
- CHAR c;
-
- if (!s) s = "";
- debug(F101,"doreinput pat","",pat);
-
- y = (int)strlen(s);
- debug(F111,"doreinput search",s,y);
-
- if (y > inbufsize) { /* If search string longer than */
- debug(F101,"doreinput inbufsize","",inbufsize);
- return(0); /* input buffer, fail. */
- }
- makestr(&inpmatch,NULL);
- if (!matchbuf)
- matchbuf = malloc(MATCHBUFSIZ+1);
- matchindex = 0;
-
- x = 0; /* Return code, assume failure */
- i = 0; /* String pattern match position */
-
- if (!inpcas[cmdlvl]) { /* INPUT CASE = IGNORE? */
- xp = malloc(y+2); /* Make a separate copy of the */
- if (!xp) { /* search string. */
- printf("?malloc error 6\n");
- return(x);
- } else xq = xp; /* Keep pointer to beginning. */
- while (*s) { /* Yes, convert to lowercase */
- *xp = *s;
- if (isupper(*xp)) *xp = (char) tolower(*xp);
- xp++; s++;
- }
- *xp = NUL; /* Terminate it! */
- s = xq; /* Move search pointer to it. */
- }
- xx = *inpbp ? inpbp : inpbuf; /* Current INPUT buffer pointer */
- do {
- c = *xx++; /* Get next character */
- if (!c) break;
- if (xx >= inpbuf + inbufsize) /* Wrap around if necessary */
- xx = inpbuf;
- if (!inpcas[cmdlvl]) { /* Ignore alphabetic case? */
- if (isupper(c)) c = (CHAR) tolower(c); /* Yes */
- }
- if (pat) {
- int j;
- if (matchbuf) {
- if (matchindex < MATCHBUFSIZ) {
- matchbuf[matchindex++] = c;
- matchbuf[matchindex] = NUL;
- }
- for (j = 0; j < matchindex; j++) { /* Gross but effective */
- if (ckmatch(s,&matchbuf[j],1,1)) {
- debug(F101,"GOT IT","",j);
- matchindex = j;
- x = 1;
- break;
- }
- }
- }
- if (x > 0)
- break;
- continue;
- }
- debug(F000,"doreinp char","",c);
- debug(F000,"compare char","",(CHAR) s[i]);
- if (((char) c) == ((char) s[i])) { /* Check for match */
- i++; /* Got one, go to next character */
- } else { /* Don't have a match */
- int j;
- for (j = i; i > 0; ) { /* [jrs] search backwards for it */
- i--;
- if (((char) c) == ((char) s[i])) {
- if (!strncmp(s,&s[j-i],i)) {
- i++;
- break;
- }
- }
- }
- } /* [jrs] or return to zero from -1 */
- if (s[i] == '\0') { /* Matched all the way to end? */
- ckstrncpy(matchbuf,s,MATCHBUFSIZ);
- matchindex = 0;
- x = 1; /* Yes, */
- break; /* done. */
- }
- } while (xx != inpbp && x < 1); /* Until back where we started. */
-
- if (!inpcas[cmdlvl]) if (xq) free(xq); /* Free this if it was malloc'd. */
- makestr(&inpmatch,&matchbuf[matchindex]); /* \v(inmatch) */
- return(x); /* Return search result. */
-}
-
-/* X X S T R I N G -- Interpret strings containing backslash escapes */
-/* Z Z S T R I N G -- (new name...) */
-/*
- Copies result to new string.
- strips enclosing braces or doublequotes.
- interprets backslash escapes.
- returns 0 on success, nonzero on failure.
- tries to be compatible with MS-DOS Kermit.
-
- Syntax of input string:
- string = chars | "chars" | {chars}
- chars = (c*e*)*
- where c = any printable character, ascii 32-126
- and e = a backslash escape
- and * means 0 or more repetitions of preceding quantity
- backslash escape = \operand
- operand = {number} | number | fname(operand) | v(name) | $(name) | m(name)
- number = [r]n[n[n]]], i.e. an optional radix code followed by 1-3 digits
- radix code is oO (octal), xX (hex), dD or none (decimal) (see xxesc()).
-*/
-
-#ifndef NOFRILLS
-int
-yystring(s,s2) char *s; char **s2; { /* Reverse a string */
- int x;
- static char *new;
- new = *s2;
- if (!s || !new) return(-1); /* Watch out for null pointers. */
- if ((x = (int)strlen(s)) == 0) { /* Recursion done. */
- *new = '\0';
- return(0);
- }
- x--; /* Otherwise, call self */
- *new++ = s[x]; /* to reverse rest of string. */
- s[x] = 0;
- return(yystring(s,&new));
-}
-#endif /* NOFRILLS */
-
-static char ipabuf[16] = { NUL }; /* IP address buffer */
-
-static char *
-getip(s) char *s; {
- char c=NUL; /* Workers... */
- int i=0, p=0, d=0;
- int state = 0; /* State of 2-state FSA */
-
- while ((c = *s++)) {
- switch(state) {
- case 0: /* Find first digit */
- i = 0; /* Output buffer index */
- ipabuf[i] = NUL; /* Initialize output buffer */
- p = 0; /* Period counter */
- d = 0; /* Digit counter */
- if (isdigit(c)) { /* Have first digit */
- d = 1; /* Count it */
- ipabuf[i++] = c; /* Copy it */
- state = 1; /* Change state */
- }
- break;
-
- case 1: /* In numeric field */
- if (isdigit(c)) { /* Have digit */
- if (++d > 3) /* Too many */
- state = 0; /* Start over */
- else /* Not too many */
- ipabuf[i++] = c; /* Keep it */
- } else if (c == '.' && p < 3) { /* Have a period */
- p++; /* Count it */
- if (d == 0) /* Not preceded by a digit */
- state = 0; /* Start over */
- else /* OK */
- ipabuf[i++] = c; /* Keep it */
- d = 0; /* Reset digit counter */
- } else if (p == 3 && d > 0) { /* Not part of address */
- ipabuf[i] = NUL; /* If we have full IP address */
- return((char *)ipabuf); /* Return it */
- } else { /* Otherwise */
- state = 0; /* Start over */
- ipabuf[0] = NUL; /* (in case no more chars left) */
- }
- }
- } /* Fall thru at end of string */
- ipabuf[i] = NUL; /* Maybe we have one */
- return((p == 3 && d > 0) ? (char *)ipabuf : "");
-}
-#endif /* NOSPL */
-
-/* Date Routines */
-
-/* Z J D A T E -- Convert yyyymmdd date to Day of Year */
-
-static int jdays[12] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
-static int ldays[12] = { 0,31,60,91,121,152,182,213,244,274,305,335 };
-static char zjdbuf[12] = { NUL, NUL };
-/*
- Deinde, ne in posterum a XII kalendas aprilis aequinoctium recedat,
- statuimus bissextum quarto quoque anno (uti mos est) continuari debere,
- praeterquam in centesimis annis; qui, quamvis bissextiles antea semper
- fuerint, qualem etiam esse volumus annum MDC, post eum tamen qui deinceps
- consequentur centesimi non omnes bissextiles sint, sed in quadringentis
- quibusque annis primi quique tres centesimi sine bissexto transigantur,
- quartus vero quisque centesimus bissextilis sit, ita ut annus MDCC, MDCCC,
- MDCCCC bissextiles non sint. Anno vero MM, more consueto dies bissextus
- intercaletur, februario dies XXIX continente, idemque ordo intermittendi
- intercalandique bissextum diem in quadringentis quibusque annis perpetuo
- conservetur. - Gregorius XIII, Anno Domini MDLXXXII.
-*/
-char *
-zjdate(date) char * date; { /* date = yyyymmdd */
- char year[5];
- char month[3];
- char day[3];
- int d, m, x, y;
- int leapday, j;
- char * time = NULL;
-
- if (!date) date = ""; /* Validate arg */
- x = strlen(date);
- if (x < 1) return("0");
- if (x < 8) return("-1");
- for (x = 0; x < 8; x++)
- if (!isdigit(date[x]))
- return("-1");
-
- if (date[8]) if (date[9])
- time = date + 9;
-
- year[0] = date[0]; /* Isolate year */
- year[1] = date[1];
- year[2] = date[2];
- year[3] = date[3];
- year[4] = '\0';
-
- month[0] = date[4]; /* Month */
- month[1] = date[5];
- month[2] = '\0';;
-
- day[0] = date[6]; /* And day */
- day[1] = date[7];
- day[2] = '\0';
-
- leapday = 0; /* Assume no leap day */
- y = atoi(year);
- m = atoi(month);
- d = atoi(day);
- if (m > 2) { /* No Leap day before March */
- if (y % 4 == 0) { /* If year is divisible by 4 */
- leapday = 1; /* It's a Leap year */
- if (y % 100 == 0) { /* Except if divisible by 100 */
- if (y % 400 != 0) /* but not by 400 */
- leapday = 0;
- }
- }
- }
- j = jdays[m - 1] + d + leapday; /* Day of year */
- if (time)
- sprintf(zjdbuf,"%04d%03d %s",y,j,time); /* SAFE */
- else
- sprintf(zjdbuf,"%04d%03d",y,j); /* SAFE */
- return((char *)zjdbuf);
-}
-
-static char jzdbuf[32];
-
-/* J Z D A T E -- Convert Day of Year to yyyyddmm date */
-
-char *
-jzdate(date) char * date; { /* date = yyyyddd */
- char year[5]; /* with optional time */
- char day[4];
- char * time = NULL, * p;
- int d, m, x, y;
- int leapday, j;
- int * zz;
-
- if (!date) date = ""; /* Validate arg */
- x = strlen(date);
-
- debug(F111,"jzdate len",date,x);
-
- if (x < 1) return("0");
- if (x < 7) return("-1");
- if (x > 8) time = date + 8;
-
- for (x = 0; x < 7; x++)
- if (!isdigit(date[x]))
- return("-1");
-
- year[0] = date[0]; /* Isolate year */
- year[1] = date[1];
- year[2] = date[2];
- year[3] = date[3];
- year[4] = '\0';
-
- debug(F110,"jzdate year",year,0);
-
- day[0] = date[4]; /* And day */
- day[1] = date[5];
- day[2] = date[6];
- day[3] = '\0';
-
- debug(F110,"jzdate day",day,0);
-
- j = atoi(day);
- if (j > 366)
- return("-1");
-
- leapday = 0; /* Assume no leap day */
- y = atoi(year);
- if (y % 4 == 0) { /* If year is divisible by 4 */
- leapday = 1; /* It's a Leap year */
- if (y % 100 == 0) { /* Except if divisible by 100 */
- if (y % 400 != 0) /* but not by 400 */
- leapday = 0;
- }
- }
- debug(F101,"jzdate leapday","",leapday);
- zz = leapday ? ldays : jdays;
-
- for (x = 0; x < 11; x++)
- if (j > zz[x] && j <= zz[x+1])
- break;
- m = x + 1;
-
- debug(F101,"jzdate m","",m);
-
- d = j - zz[x];
-
- debug(F101,"jzdate d","",d);
-
- if (time)
- sprintf(jzdbuf,"%04d%02d%02d %s",y,m,d,time); /* SAFE */
- else
- sprintf(jzdbuf,"%04d%02d%02d",y,m,d); /* SAFE */
-
- debug(F101,"jzdate jzdbuf",jzdbuf,0);
-
- p = ckcvtdate((char *)jzdbuf, 0); /* Convert to standard form */
- ckstrncpy(jzdbuf,p,32);
- if (!time) jzdbuf[8] = NUL; /* Remove time if not wanted */
- return((char *)jzdbuf);
-}
-
-/* M J D -- Modified Julian Date */
-/*
- Call with:
- Standard-format date-time string: yyyymmdd[ hh:mm:ss].
- The time, if any, is ignored.
-
- Returns:
- -1L on error, otherwise:
- The number of days since 17 Nov 1858 as a whole number:
- 16 Nov 1858 = -1, 17 Nov 1858 = 0, 18 Nov 1858 = 1, 19 Nov 1858 = 2, ...
-
- The Modified Julian Date is defined by the International Astronomical
- Union as the true Julian date minus 2400000.5 days. The true Julian
- date is the number days since since noon of 1 January 4713 BCE of the
- Julian proleptic calendar. Conversions between calendar dates and
- Julian dates, however, assume Gregorian dating.
-*/
-long
-mjd(date) char * date; {
- char year[5];
- char month[3];
- char day[3];
- int x, a, d, m, y;
- long z;
-
- if (!date) date = ""; /* Validate arg */
- x = strlen(date);
- if (x < 1) return(0L);
- if (x < 8) return(-1L);
- for (x = 0; x < 8; x++)
- if (!isdigit(date[x]))
- return(-1L);
-
- year[0] = date[0]; /* Isolate year */
- year[1] = date[1];
- year[2] = date[2];
- year[3] = date[3];
- year[4] = '\0';
-
- month[0] = date[4]; /* Month */
- month[1] = date[5];
- month[2] = '\0';;
- m = atoi(month);
-
- day[0] = date[6]; /* And day */
- day[1] = date[7];
- day[2] = '\0';
- d = atoi(day);
-
- a = (14-m)/12; /* Calculate true Julian date */
- y = atoi(year) + 4800 - a;
- m = m + 12 * a - 3;
- z = d + (long)(306*m+5)/10 + (long)(y*365) + y/4 - y/100 + y/400 - 32045L;
-
- z -= 2400001L; /* Convert JD to MJD */
-
- return(z);
-}
-
-static char mjd2dbuf[32];
-
-/* M J D 2 D A T E -- Converts MJD to yyyymmdd */
-
-char *
-#ifdef CK_ANSIC
-mjd2date(long mjd)
-#else
-mjd2date(mjd) long mjd;
-#endif /* CK_ANSIC */
-/* mjd2date */ {
- long jd, l, n;
- int d, m, y;
- jd = (long)(mjd + 2400001L);
- l = jd + 68569;
- n = 4 * l / 146097L;
- l = l - (146097 * n + 3) / 4;
- y = 4000 * (l + 1) / 1461001L;
- l = l - 1461 * y / 4 + 31;
- m = 80 * l / 2447;
- d = l - 2447 * m / 80;
- l = m / 11;
- m = m + 2 - 12 * l;
- y = 100 * (n - 49) + y + l;
- sprintf(mjd2dbuf,"%04d%02d%02d",y,m,d); /* SAFE */
- return((char *)mjd2dbuf);
-}
-
-#ifndef NOSPL
-static char ** flist = (char **) NULL; /* File list for \fnextfile() */
-static int flistn = 0; /* Number of items in file list */
-
-/*
- The function return-value buffer must be global, since fneval() returns a
- pointer to it. fneval() is called only by zzstring(), which always copies
- the result out of this buffer to somewhere else, so it's OK to have only
- one buffer for this in most cases. However, since function calls can be
- nested -- e.g. functions whose arguments are functions, or recursive
- functions, at some point we should convert this to an array of buffers,
- indexed by function depth (which might or might not be the same as the
- "depth" variable). Also, since function results are potentially quite big,
- we'd need to allocate and deallocate dynamically as we descend and ascend
- function depth. Left for a future release...
-*/
-char fnval[FNVALL+2]; /* Function return value */
-static int fndepth = 0; /* (we don't actually use this yet) */
-int fnsuccess = 1;
-extern int fnerror;
-
-/* f p f o r m a t -- Floating-point number nicely formatted. */
-/*
- Returns results from a circular 1K buffer.
- Don't count on too many results remaining available at once; it could
- be anywhere from 5 to maybe 100, depending on the sizes of the results.
-*/
-#ifdef CKFLOAT
-#define FPFMTSIZ 1024
-static char fpfmtbuf[FPFMTSIZ] = { NUL, NUL };
-static int fpfbufpos = 0; /* (why was this char before?) */
-
-char *
-fpformat(fpresult,places,round) CKFLOAT fpresult; int places, round; {
- char fbuf[16]; /* For creating printf format */
- int nines = 0, sign = 0, x, y, i, j, size = 0;
- char * buf;
- CKFLOAT ftmp;
-
- x = places ? places : (fp_digits ? fp_digits : 6);
-
- debug(F101,"fpformat fpresult","",fpresult);
- debug(F101,"fpformat places","",places);
- debug(F101,"fpformat fpfbufpos 1","",fpfbufpos);
-
- ftmp = fpresult;
- if (ftmp < 0.0) ftmp = 0.0 - fpresult;
-
-#ifdef FNFLOAT
- if (!fp_rounding && /* If printf doesn't round, */
- (places > 0 || /* round result to decimal places. */
- (places == 0 && round)))
- fpresult += (0.5 / pow(10.0,(CKFLOAT)places));
- y = (ftmp == 0.0) ? 1 : (int)log10(ftmp);
- size = y + x + 3; /* Estimated length of result */
- if (fpresult < 0.0) size++;
-#else
- size = 200; /* No way to estimate, be generous */
-#endif /* FNFLOAT */
-
- debug(F101,"fpformat size","",size);
-
- if (fpfbufpos > (FPFMTSIZ - size)) /* Wrap around if necessary */
- fpfbufpos = 0;
- debug(F101,"fpformat fpfbufpos 1","",fpfbufpos);
-
- buf = &fpfmtbuf[fpfbufpos];
-
- if (places > 0) { /* If places specified */
- /* use specified places to write given number of digits */
- sprintf(fbuf,"%%0.%df",places); /* SAFE */
- sprintf(buf,fbuf,fpresult); /* SAFE */
- } else { /* Otherwise... */
- /* Go for max precision */
- sprintf(fbuf,"%%0.%df",fp_digits); /* SAFE */
- sprintf(buf,fbuf,fpresult); /* SAFE */
- }
- if (buf[0] == '-') sign = 1;
- debug(F111,"fpresult 1 errno",buf,errno); /* Check for over/underflow */
- debug(F111,"fpresult 1 fpfbufpos",buf,fpfbufpos);
- /* Give requested decimal places */
- for (i = sign; i < FPFMTSIZ && buf[i]; i++) {
- if (buf[i] == '.') /* First find the decimal point */
- break;
- else if (i > fp_digits + sign - 1) /* replacing garbage */
- buf[i] = '0'; /* digits with 0... */
- }
- if (buf[i] == '.') { /* Have decimal point */
- int gotend = 0;
- /* places < 0 so truncate fraction */
- if (places < 0 || (places == 0 && round)) {
- buf[i] = NUL;
- } else if (places > 0) { /* d > 0 so this many decimal places */
- i++; /* First digit after decimal */
- for (j = 0; j < places; j++) { /* Truncate after d decimal */
- if (!buf[j+i]) /* places or extend to d */
- gotend = 1; /* decimal places. */
- if (gotend || j+i+sign > fp_digits)
- buf[j+i] = '0';
- }
- buf[j+i] = NUL;
- } else { /* places == 0 so Do The Right Thing */
- for (j = (int)strlen(buf) - 1; j > i+1; j--) {
- if ((j - sign) > fp_digits)
- buf[j] = '0';
- if (buf[j] == '0')
- buf[j] = NUL; /* Strip useless trailing 0's. */
- else
- break;
- }
- }
- }
- fpfmtbuf[FPFMTSIZ-1] = NUL;
- j = strlen(buf);
- sign = 0;
- for (i = j-1; i >= 0; i--) {
- if (buf[i] == '9')
- nines++;
- else
- break;
- }
- /* Do something about xx.xx99999999... */
- if (nines > 5) {
- if (isdigit(buf[i]) && i < FPFMTSIZ - 2) {
- buf[i] = buf[i] + 1;
- buf[i+1] = '0';
- buf[i+2] = '\0';
- }
- }
- if (!strncmp(buf,"-0.0",FPFMTSIZ))
- ckstrncpy(buf,"0.0",FPFMTSIZ);
- fpfbufpos += (int)strlen(buf) + 1;
- return((char *)buf);
-}
-#endif /* CKFLOAT */
-
-static VOID
-evalerr(fn) char * fn; {
- if (fndiags) {
- if (divbyzero)
- ckmakmsg(fnval,FNVALL,"<ERROR:DIVIDE_BY_ZERO:\\f",fn,"()>",NULL);
- else
- ckmakmsg(fnval,FNVALL,"<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- }
-}
-
-
-static int
-ckcindex(c,s) char c, *s; {
- int rc;
- if (!c || !s) return(0);
- for (rc = 0; s[rc]; rc++) {
- if (c == s[rc]) return(rc+1);
- }
- return(0);
-}
-
-static char *
-dokwval(s,sep) char * s, * sep; {
- char c = '\0', * p, * kw = NULL, * vp = NULL;
- char * rc = "0"; /* Return code */
- int x = 0;
- if (!s) return(rc);
- if (!*s) return(rc);
- debug(F110,"kwval arg",s,0);
- debug(F110,"kwval sep",sep,0);
- p = (char *)malloc((int)strlen(s)+1);
- if (!p) goto xdokwval;
- strcpy(p,s); /* SAFE */
- s = p;
- while (*s < '!' && *s > '\0') /* Get first nonblank */
- s++;
- if (!*s) goto xdokwval;
- if (ckcindex(*s,sep)) /* Separator but no keyword */
- goto xdokwval;
- kw = s; /* Keyword */
- while (*s > ' ') {
- if (ckcindex(*s,sep)) { /* keyword=... */
- c = *s;
- break;
- }
- s++;
- }
- if (*kw) rc = "1"; /* Have keyword, promote return code */
- *s++ = NUL; /* Terminate keyword */
- while (*s < '!' && *s > '\0') /* Skip blanks */
- s++;
- if (!c && ckcindex(*s,sep)) {
- c = *s++; /* Have separator */
- while (*s < '!' && *s > '\0') /* Skip blanks */
- s++;
- }
- if (c) {
- vp = s;
- if (*vp) rc = "2"; /* Have value, another promotion */
-#ifdef COMMENT
- while (*s > ' ') /* Skip to end */
- s++;
- *s = NUL; /* Terminate value */
-#endif /* COMMENT */
- }
- debug(F110,"kwval c",ckctoa(c),0);
- debug(F110,"kwval keyword",kw,0);
- debug(F110,"kwval value",vp,0);
- makestr(&lastkwval,kw);
- vp = brstrip(vp);
- debug(F110,"kwval value",vp,0);
- x = addmac(kw,vp);
- debug(F111,"kwval addmac",kw,x);
- xdokwval:
- if (p) free(p);
- return((x < 0) ? "-1" : rc);
-}
-
-static int
-isaarray(s) char * s; { /* Is s an associative array element */
- int state = 0;
- CHAR c;
- if (!s) return(0);
- while ((c = *s++)) {
- if (!isprint(c)) {
- return(0);
- } else if (c == '<') {
- if (state != 0)
- return(0);
- state = 1;
- } else if (c == '>') {
- return((state != 1 || *s) ? 0 : 1);
- }
- }
- return(0);
-}
-
-static char * /* Evaluate builtin functions */
-fneval(fn,argp,argn,xp) char *fn, *argp[]; int argn; char * xp; {
- int i=0, j=0, k=0, len1=0, len2=0, len3=0, n=0, t=0, x=0, y=0;
- int cx, failed = 0; /* Return code, 0 = ok */
- long z = 0L;
- char *bp[FNARGS + 1]; /* Pointers to malloc'd strings */
- char c = NUL;
- char *p = NULL, *s = NULL;
- char *val1 = NULL, *val2 = NULL; /* Pointers to numeric string values */
-
-#ifdef RECURSIVE
- int rsave = recursive;
-#endif /* RECURSIVE */
-#ifdef OS2
- int zsave = zxpn;
-#endif /* OS2 */
-
- if (!fn) fn = ""; /* Protect against null pointers */
- if (!*fn) return("");
-
- for (i = 0; i < FNARGS; i++) /* Initialize argument pointers */
- bp[i] = NULL;
-/*
- IMPORTANT: Note that argn is not an accurate count of the number of
- arguments. We can't really tell if an argument is null until after we
- execute the code below. So argn is really the maximum number of arguments
- we might have. Argn should always be at least 1, even if the function is
- called with empty parentheses (but don't count on it).
-*/
- debug(F111,"fneval",fn,argn);
- debug(F110,"fneval",argp[0],0);
- if (argn > FNARGS) /* Discard excess arguments */
- argn = FNARGS;
-
- fndepth++;
- debug(F101,"fneval fndepth","",fndepth);
- p = fnval;
- fnval[0] = NUL;
- y = lookup(fnctab,fn,nfuncs,&x); /* Look up the function name */
- cx = y; /* Because y is too generic... */
- if (cx < 0) { /* Not found */
- failed = 1;
- if (fndiags) { /* FUNCTION DIAGNOSTIC ON */
- int x;
- x = strlen(fn);
- /* The following sprintf's are safe */
- switch (cx) {
- case -1:
- if (x + 32 < FNVALL)
- sprintf(fnval,"<ERROR:NO_SUCH_FUNCTION:\\f%s()>",fn);
- else
- sprintf(fnval,"<ERROR:NO_SUCH_FUNCTION>");
- break;
- case -2:
- if (x + 26 < FNVALL)
- sprintf(fnval,"<ERROR:NAME_AMBIGUOUS:\\f%s()>",fn);
- else
- sprintf(fnval,"<ERROR:NAME_AMBIGUOUS>");
- break;
- case -3:
- sprintf(fnval,"<ERROR:FUNCTION_NAME_MISSING:\\f()>");
- break;
- default:
- if (x + 26 < FNVALL)
- sprintf(fnval,"<ERROR:LOOKUP_FAILURE:\\f%s()>",fn);
- else
- sprintf(fnval,"<ERROR:LOOKUP_FAILURE>");
- break;
- }
- }
- goto fnend; /* Always leave via common exit */
- }
- fn = fnctab[x].kwd; /* Full name of function */
-
- if (argn < 0) {
- failed = 1;
- p = fnval;
- if (fndiags)
- sprintf(fnval,"<ERROR:MISSING_ARG:\\f%s()>",fn);
- goto fnend;
- }
- if (cx == FN_LIT) { /* literal(arg1) */
- debug(F010,"flit",xp,0);
- p = xp ? xp : ""; /* Return a pointer to arg itself */
- goto fnend;
- }
-
-#ifdef DEBUG
- if (deblog) {
- int j;
- for (j = 0; j < argn; j++)
- debug(F111,"fneval arg",argp[j],j);
- }
-#endif /* DEBUG */
- for (j = argn-1; j >= 0; j--) { /* Uncount empty trailing args */
- if (!argp[j])
- argn--;
- else if (!*(argp[j]))
- argn--;
- else break;
- }
- debug(F111,"fneval argn",fn,argn);
-/*
- \fliteral() and \fcontents() are special functions that do not evaluate
- their arguments, and are treated specially here. After these come the
- functions whose arguments are evaluated in the normal way.
-*/
-#ifdef COMMENT
- /* (moved up) */
- if (cx == FN_LIT) { /* literal(arg1) */
- debug(F110,"flit",xp,0);
- p = xp ? xp : ""; /* Return a pointer to arg itself */
- goto fnend;
- }
-#endif /* COMMENT */
- if (cx == FN_CON) { /* Contents of variable, unexpanded. */
- char c;
- int subscript = 0;
- if (!(p = argp[0]) || !*p) {
- failed = 1;
- p = fnval;
- if (fndiags)
- sprintf(fnval,"<ERROR:MISSING_ARG:\\fcontents()>");
- goto fnend;
- }
- p = brstrip(p);
- if (*p == CMDQ) p++;
- if ((c = *p) == '%') { /* Scalar variable. */
- c = *++p; /* Get ID character. */
- p = ""; /* Assume definition is empty */
- if (!c) { /* Double paranoia */
- failed = 1;
- p = fnval;
- if (fndiags)
- sprintf(fnval,"<ERROR:ARG_BAD_VARIABLE:\\fcontents()>");
- goto fnend;
- }
- if (c >= '0' && c <= '9') { /* Digit for macro arg */
- if (maclvl < 0) /* Digit variables are global */
- p = g_var[c]; /* if no macro is active */
- else /* otherwise */
- p = m_arg[maclvl][c - '0']; /* they're on the stack */
- } else if (c == '*') {
-#ifdef COMMENT
- p = (maclvl > -1) ? m_line[maclvl] : topline;
- if (!p) p = "";
-#else
- int nx = FNVALL;
- char * sx = fnval;
- p = fnval;
-#ifdef COMMENT
- if (cmdsrc() == 0 && topline)
- p = topline;
- else
-#endif /* COMMENT */
- if (zzstring("\\fjoin(&_[],{ },1)",&sx,&nx) < 0) {
- failed = 1;
- p = fnval;
- if (fndiags)
- sprintf(fnval,"<ERROR:OVERFLOW:\\fcontents()>");
- debug(F110,"zzstring fcontents(\\%*)",p,0);
- }
-#endif /* COMMENT */
- } else {
- if (isupper(c)) c -= ('a'-'A');
- p = g_var[c]; /* Letter for global variable */
- }
- if (!p) p = "";
- goto fnend;
- } else if (c == '&') { /* Array reference. */
- int vbi, d;
- if (arraynam(p,&vbi,&d) < 0) { /* Get name and subscript */
- failed = 1;
- p = fnval;
- if (fndiags)
- sprintf(fnval,"<ERROR:ARG_BAD_ARRAY:\\fcontents()>");
- goto fnend;
- }
- subscript = chkarray(vbi,d); /* Check the array */
- if (subscript >= 0) { /* Array is declared? */
- vbi -= ARRAYBASE; /* Convert name to index */
- if (a_dim[vbi] >= d) { /* If subscript in range */
- char **ap;
- ap = a_ptr[vbi]; /* get data pointer */
- if (ap) { /* and if there is one */
- p = ap[d]; /* return it */
- goto fnend;
- }
- }
- } else { /* Array not declared or element */
- fnval[0] = NUL; /* out of range - return null string */
- p = fnval; /* fdc 2010-12-30 */
- goto fnend;
- }
- } else {
- failed = 1;
- p = fnval;
- if (fndiags)
- sprintf(fnval,"<ERROR:ARG_NOT_VARIABLE:\\fcontents()>");
- goto fnend;
- }
- }
- p = fnval; /* Default result pointer */
- fnval[0] = NUL; /* Default result = empty string */
-
- for (i = 0; i < argn; i++) { /* Loop to expand each argument */
- n = MAXARGLEN; /* Allow plenty of space */
- bp[i] = s = malloc(n+1); /* Allocate space for this argument */
- if (bp[i] == NULL) { /* Handle failure to get space */
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:MALLOC_FAILURE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- p = argp[i] ? argp[i] : ""; /* Point to this argument */
-
-/*
- Trim leading and trailing spaces from the original argument, before
- evaluation. This code new to edit 184. Fixed in edit 199 to trim
- blanks BEFORE stripping braces.
-
-*/
- {
- int x, j;
- x = strlen(p);
- j = x - 1; /* Trim trailing whitespace */
- while (j > 0 && (*(p + j) == SP || *(p + j) == HT))
- *(p + j--) = NUL;
- while (*p == SP || *p == HT) /* Strip leading whitespace */
- p++;
- x = strlen(p);
- if (*p == '{' && *(p+x-1) == '}') { /* NOW strip braces */
- p[x-1] = NUL;
- p++;
- x -= 2;
- }
- }
-
-/* Now evaluate the argument */
-
- debug(F111,"fneval calling zzstring",p,n);
- t = zzstring(p,&s,&n); /* Expand arg into new space */
- debug(F101,"fneval zzstring","",t);
- debug(F101,"fneval zzstring","",n);
- if (t < 0) {
- debug(F101,"fneval zzstring fails, arg","",i);
- failed = 1;
- if (fndiags) {
- if (n == 0)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_TOO_LONG:\\f",fn,"()>",NULL);
- else
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_EVAL_FAILURE:\\f",fn,"()>",NULL);
- }
- goto fnend;
- }
- debug(F111,"fneval arg",bp[i],i);
- }
-
-#ifdef DEBUG
- if (deblog) {
- int j;
- for (j = 0; j < argn; j++) {
- debug(F111,"fneval arg post eval",argp[j],j);
- debug(F111,"fneval evaluated arg",bp[j],j);
- }
- }
-#endif /* DEBUG */
- {
- /* Adjust argn for empty trailing arguments. */
- /* For example when an arg is a variable name but the */
- /* variable has no value. July 2006. */
- int j, old; char *p;
- old = argn;
- for (j = argn - 1; j >= 0; j--) {
- p = bp[j];
- if (!p)
- argn--;
- else if (!*p)
- argn--;
- else
- break;
- }
-#ifdef DEBUG
- if (argn != old)
- debug(F101,"fneval adjusted argn","",argn);
-#endif /* DEBUG */
- }
-
-/*
- From this point on, bp[0..argn-1] are not NULL and all must be freed
- before returning.
-*/
- if (argn < 1) { /* Catch required args missing */
- switch (cx) {
- case FN_DEF:
- case FN_EVA:
- case FN_EXE:
- case FN_CHR:
- case FN_COD:
- case FN_MAX:
- case FN_MIN:
- case FN_MOD:
- case FN_FD:
- case FN_FS:
- case FN_TOD:
- case FN_FFN:
- case FN_BSN:
- case FN_RAW:
- case FN_CMD:
- case FN_2HEX:
- case FN_2OCT:
- case FN_DNAM:
-#ifdef FN_ERRMSG
- case FN_ERRMSG:
-#endif /* FN_ERRMSG */
-#ifdef CK_KERBEROS
- case FN_KRB_TK:
- case FN_KRB_NX:
- case FN_KRB_IV:
- case FN_KRB_TT:
- case FN_KRB_FG:
-#endif /* CK_KERBEROS */
- case FN_MJD2:
- case FN_N2TIM:
- case FN_DIM:
- case FN_DATEJ:
- case FN_PNCVT:
- case FN_PERM:
- case FN_ALOOK:
- case FN_TLOOK:
- case FN_ABS:
- case FN_AADUMP:
- case FN_JOIN:
-#ifdef CKFLOAT
- case FN_FPABS:
- case FN_FPEXP:
- case FN_FPLOG:
- case FN_FPLN:
- case FN_FPMOD:
- case FN_FPSQR:
- case FN_FPADD:
- case FN_FPDIV:
- case FN_FPMUL:
- case FN_FPPOW:
- case FN_FPSUB:
- case FN_FPINT:
- case FN_FPROU:
- case FN_FPSIN:
- case FN_FPCOS:
- case FN_FPTAN:
-#endif /* CKFLOAT */
-#ifdef TCPSOCKET
- case FN_HSTADD:
- case FN_HSTNAM:
-#endif /* TCPSOCKET */
- case FN_DELSEC:
-#ifdef COMMENT
- case FN_KWVAL:
- case FN_SLEEP:
- case FN_MSLEEP:
-#endif /* COMMENT */
-#ifdef NT
- case FN_SNAME:
- case FN_LNAME:
-#endif /* NT */
- failed = 1;
- p = fnval;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:MISSING_ARG:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- p = fnval; /* Reset these again. */
- fnval[0] = NUL;
-
- switch (cx) { /* Do function on expanded args. */
-#ifdef TCPSOCKET
- case FN_HSTADD:
- p = ckaddr2name(bp[0]);
- goto fnend;
- case FN_HSTNAM:
- p = ckname2addr(bp[0]);
- goto fnend;
-#endif /* TCPSOCKET */
-
- case FN_DEF: /* \fdefinition(arg1) */
- k = isaarray(bp[0]) ?
- mxxlook(mactab,bp[0],nmac) :
- mxlook(mactab,bp[0],nmac);
- p = (k > -1) ? mactab[k].mval : "";
- goto fnend;
-
- case FN_EVA: /* \fevaluate(arg1) */
- p = *(bp[0]) ? evalx(bp[0]) : "";
- if (!*p && fndiags) {
- failed = 1;
- p = fnval;
- evalerr(fn);
- }
- goto fnend;
-
- case FN_EXE: /* \fexecute(arg1) */
- j = (int)strlen(s = bp[0]); /* Length of macro invocation */
- p = ""; /* Initialize return value to null */
- if (j) { /* If there is a macro to execute */
- while (*s == SP) s++,j--; /* strip leading spaces */
- p = s; /* remember beginning of macro name */
- for (i = 0; i < j; i++) { /* find end of macro name */
- if (*s == SP)
- break;
- s++;
- }
- if (*s == SP) { /* if there was a space after */
- *s++ = NUL; /* terminate the macro name */
- while (*s == SP) s++; /* skip past any extra spaces */
- } else
- s = ""; /* maybe there are no arguments */
- if (p && *p) {
- k = mlook(mactab,p,nmac); /* Look up the macro name */
- debug(F111,"fexec mlook",p,k);
- } else
- k = -1;
- if (k < 0) {
- char * p2 = p;
- failed = 1;
- p = fnval;
- if (fndiags)
- ckmakxmsg(fnval,FNVALL,
- "<ERROR:NO_SUCH_MACRO:\\f",fn,"(",p2,")>",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- goto fnend;
- }
-/*
- This is just a WEE bit dangerous because we are copying up to 9 arguments
- into the space reserved for one. It won't overrun the buffer, but if there
- are lots of long arguments we might lose some. The other problem is that if
- the macro has more than 3 arguments, the 4th through last are all
- concatenated onto the third. (The workaround is to use spaces rather than
- commas to separate them.) Leaving it like this to avoid having to allocate
- tons more buffers.
-*/
- if (argn > 1) { /* Commas used instead of spaces */
- int i;
- char *p = bp[0]; /* Reuse this space */
- *p = NUL; /* Make into dodo() arg list */
- for (i = 1; i < argn; i++) {
- ckstrncat(p,bp[i],MAXARGLEN);
- ckstrncat(p," ",MAXARGLEN);
- }
- s = bp[0]; /* Point to new list */
- }
- p = ""; /* Initialize return value */
- if (k >= 0) { /* If macro found in table */
- /* Go set it up (like DO cmd) */
- if ((j = dodo(k,s,cmdstk[cmdlvl].ccflgs)) > 0) {
- if (cmpush() > -1) { /* Push command parser state */
- extern int ifc;
- int ifcsav = ifc; /* Push IF condition on stack */
- k = parser(1); /* Call parser to execute the macro */
- cmpop(); /* Pop command parser */
- ifc = ifcsav; /* Restore IF condition */
- if (k == 0) { /* No errors, ignore action cmds. */
- p = mrval[maclvl+1]; /* If OK, set return value. */
- if (p == NULL) p = "";
- }
- } else { /* Can't push any more */
- debug(F100,"zzstring fneval fexec failure","",0);
- printf("\n?\\fexec() too deeply nested\n");
- while (cmpop() > -1) ;
- p = "";
- }
- }
- }
- }
- debug(F110,"zzstring fneval fexecute final p",p,0);
- goto fnend;
-
-#ifdef RECURSIVE
- case FN_RDIR: /* \frdir..() - Recursive dir count */
- case FN_RFIL: /* \frfiles() - Recursive file count */
- /* recursive = 2; */ /* fall thru... */
-#endif /* RECURSIVE */
- case FN_FC: /* \ffiles() - File count. */
- case FN_DIR: { /* \ffdir.() - Directory count. */
- char abuf[16], *s;
- char ** ap = NULL;
- int x, xflags = 0;
- if (matchdot)
- xflags |= ZX_MATCHDOT;
- if (cx == FN_RDIR || cx == FN_RFIL) {
- xflags |= ZX_RECURSE;
-#ifdef CKSYMLINK
- /* Recursive - don't follow symlinks */
- xflags |= ZX_NOLINKS;
-#endif /* CKSYMLINK */
- }
- failed = 0;
- if (argn < 1) {
- p = "0";
- goto fnend;
- }
- if (cx == FN_DIR || cx == FN_RDIR) { /* Only list directories */
- debug(F100,"FN_DIR or FN_RDIR","",0);
- xflags |= ZX_DIRONLY;
-#ifdef OS2
- zxpn = 1; /* Use the alternate list */
-#endif /* OS2 */
- } else { /* List only files */
- debug(F100,"Not FN_DIR or FN_RDIR","",0);
- xflags |= ZX_FILONLY;
-#ifdef OS2
- zxpn = 1; /* Use the alternate list */
-#endif /* OS2 */
- }
- if (*(bp[0])) {
- k = nzxpand(bp[0],xflags);
- if (k < 0) k = 0;
- sprintf(fnval,"%d",k); /* SAFE */
- p = fnval;
- } else
- p = "0";
-
- if (argn > 1) { /* Assign list to array */
- fnval[0] = NUL; /* Initial return value */
- ckstrncpy(abuf,bp[1],16); /* Get array reference */
- s = abuf;
- if (*s == CMDQ) s++;
- failed = 1; /* Assume it's bad */
- p = fnval; /* Point to result */
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_BAD_ARRAY:\\f",fn,"()>",NULL);
- if (s[0] != '&') /* "Address" of array */
- goto fnend;
- if (s[2])
- if (s[2] != '[' || s[3] != ']')
- goto fnend;
- if (s[1] >= 64 && s[1] < 91) /* Convert upper to lower */
- s[1] += 32;
- if ((x = dclarray(s[1],k)) < 0) /* File list plus count */
- goto fnend;
- failed = 0; /* Unset failure flag */
- ap = a_ptr[x]; /* Point to array we just declared */
- sprintf(fnval,"%d",k); /* SAFE */
- }
-#ifdef OS2
- if (ap) { /* We are making an array */
- int i;
- char tmp[16];
- ap[0] = NULL; /* Containing number of files */
- makestr(&(ap[0]),ckitoa(k));
-
- ckstrncpy(tmp,fnval,16); /* Save return value */
-
- for (i = 1; i <= k; i++) { /* Fill it */
- ap[i] = NULL;
- znext(fnval); /* Next filename */
- if (!*fnval) /* No more, done */
- break; /* In case a premature end */
- makestr(&(ap[i]),fnval);
- }
-#ifdef ZXREWIND
- k = zxrewind(); /* Reset the file expansion */
-#else
- k = nzxpand(bp[0],xflags);
-#endif /* ZXREWIND */
- ckstrncpy(fnval,tmp,FNVALL); /* Restore return value */
- }
-#else /* OS2 */
- { /* Make copies of the list */
- int i; char tmp[16];
- if (flist) { /* Free old file list, if any */
- for (i = 0; flist[i]; i++) { /* and each string */
- free(flist[i]);
- flist[i] = NULL;
- }
- free((char *)flist);
- }
- ckstrncpy(tmp,fnval,16); /* Save our return value */
- flist = (char **) malloc((k+1) * sizeof(char *)); /* New array */
- if (flist) {
- for (i = 0; i <= k; i++) { /* Fill it */
- flist[i] = NULL;
- znext(fnval); /* Next filename */
- if (!*fnval) /* No more, done */
- break;
- makestr(&(flist[i]),fnval);
- }
- if (ap) { /* If array pointer given */
- ap[0] = NULL;
- makestr(&(ap[0]),ckitoa(k));
- for (i = 0; i < k; i++) { /* Copy file list to array */
- ap[i+1] = NULL;
- makestr(&(ap[i+1]),flist[i]);
- }
- }
- }
- ckstrncpy(fnval,tmp,FNVALL); /* Restore return value */
- flistn = 0; /* Reset global list pointer */
- }
-#endif /* OS2 */
-#ifdef RECURSIVE
- recursive = rsave;
-#endif /* RECURSIVE */
-#ifdef OS2
- zxpn = zsave;
-#endif /* OS2 */
- }
- goto fnend;
-
- case FN_FIL: /* \fnextfile() - Next file in list. */
- p = fnval; /* (no args) */
- *p = NUL;
-#ifdef OS2
- zxpn = 1; /* OS/2 - use the alternate list */
- znext(p); /* Call system-dependent function */
- zxpn = zsave; /* Restore original list */
-#else
- if (flist) /* Others, use our own list. */
- if (flist[flistn])
- p = flist[flistn++];
-#endif /* OS2 */
- goto fnend;
-
- } /* Break up big switch... */
-
- switch (cx) {
- case FN_IND: /* \findex(s1,s2,start,occurrence) */
- case FN_RIX: /* \frindex(s1,s2,start,occurrence) */
- case FN_SEARCH: /* \fsearch(pat,string,start,occ) */
- case FN_RSEARCH: /* \frsearch(pat,string,start,occ) */
- case FN_COUNT: { /* \fcount(s1,s2,start) */
- int i = 0, right = 0, search = 0, count = 0;
- int desired = 1;
- right = (cx == FN_RIX || cx == FN_RSEARCH);
- search = (cx == FN_SEARCH || cx == FN_RSEARCH);
- count = (cx == FN_COUNT);
- p = "0";
- if (argn > 1) { /* Only works if we have 2 or 3 args */
- int start = 0;
- char * pat = NULL;
- len1 = (int)strlen(pat = bp[0]); /* length of string to look for */
- len2 = (int)strlen(s = bp[1]); /* length of string to look in */
- if (len1 < 1 || len2 < 1) /* Watch out for empty strings */
- goto fnend;
- start = right ? -1 : 0; /* Default starting position */
- if (argn > 2) {
- val1 = *(bp[2]) ? evalx(bp[2]) : "1";
- if (argn > 3) {
- val2 = *(bp[3]) ? evalx(bp[3]) : "1";
- if (chknum(val2)) desired = atoi(val2);
- if (desired * len1 > len2) goto fnend;
- }
- if (chknum(val1)) {
- int t;
- t = atoi(val1);
- if (!search) { /* Index or Rindex */
- j = len2 - len1; /* Length difference */
- t--; /* Convert position to 0-based */
- if (t < 0) t = 0;
- start = t;
- if (!right && start < 0) start = 0;
- } else { /* Search or Rsearch */
- int x;
- if (t < 0) t = 0;
- if (right) { /* Right to left */
- if (t > len2) t = len2;
- start = len2 - t - 1;
- if (start < 0)
- goto fnend;
- x = len2 - t;
- s[x] = NUL;
- } else { /* Left to right */
- start = t - 1;
- if (start < 0) start = 0;
- if (start >= len2)
- goto fnend;
- }
- }
- } else {
- failed = 1;
- evalerr(fn);
- p = fnval;
- goto fnend;
- }
- }
- if (count) { /* \fcount() */
- int j;
- for (i = 0; start < len2; i++) {
- j = ckindex(pat,bp[1],start,0,inpcas[cmdlvl]);
- if (j == 0) break;
- start = j;
- }
-
- } else if (search) { /* \fsearch() or \frsearch() */
-
- if (right && pat[0] == '^') {
- right = 0;
- start = 0;
- }
- if (right) { /* From right */
- int k, j = 1;
- if (start < 0)
- start = len2 - 1;
- i = 0;
- while (start >= 0 && j <= desired) {
- for (i = start;
- (i >= 0) &&
- !(k = ckmatch(pat,s+i,inpcas[cmdlvl],1+4));
- i--) ;
- if (k < 1) { /* No match */
- i = 0;
- break;
- }
- if (j == desired) { /* The match we want? */
- i += k; /* Yes, return string index */
- break;
- }
- j++; /* No, count this match */
- s[i] = NUL; /* null it out */
- start = i-1; /* move left and look again */
- }
-
- } else { /* From left */
- int j;
- i = 0;
- for (j = 1; j <= desired && start < len2; j++) {
- i = ckmatch(pat,&s[start],inpcas[cmdlvl],1+4);
- if (i == 0 || j == desired) break;
- start += i + 1;
- }
- if (j == desired && i != 0)
- i += start;
- else
- i = 0;
- }
- } else { /* index or rindex */
- int j = 0;
- i = 0;
- for (j = 1; j <= desired && start < len2; j++) {
- i = ckindex(pat,bp[1],start,right,inpcas[cmdlvl]);
- if (i == 0 || j == desired) break;
- start = (right) ? len2 - i + 1 : i;
- }
- if (j != desired)
- i = 0;
- }
- sprintf(fnval,"%d",i); /* SAFE */
- p = fnval;
- }
- goto fnend;
- }
-
- case FN_RPL: /* \freplace(s1,s2,s3) */
- /*
- s = bp[0] = source string
- bp[1] = match string
- bp[2] = replacement string
- bp[3] = which occurrence (default = all);
- p = fnval = destination (result) string
- */
- if (argn < 1) /* Nothing */
- goto fnend;
- if (argn < 2) { /* Only works if we have 2 or 3 args */
- ckstrncpy(p,bp[0],FNVALL);
- } else {
- int occur = 0, xx = 0, j2;
- len1 = (int)strlen(bp[0]); /* length of string to look in */
- len2 = (int)strlen(bp[1]); /* length of string to look for */
- len3 = (argn < 3) ? 0 : (int)strlen(bp[2]); /* Len of replacemnt */
- j = len1 - len2 + 1;
- j2 = j;
- if (argn > 3) {
- if (chknum(bp[3])) {
- occur = atoi(bp[3]);
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- /* If args out of whack... */
- if (j < 1 || len1 == 0 || len2 == 0) {
- ckstrncpy(p,bp[0],FNVALL); /* just return original string */
- p[FNVALL] = NUL;
- } else {
- ragain:
- s = bp[0]; /* Point to beginning of string */
- while (j-- > 0) { /* For each character */
- if (!ckstrcmp(bp[1],s,len2,inpcas[cmdlvl]) &&
- (occur == 0 || occur == ++xx)) {
- if (len3) {
- ckstrncpy(p,bp[2],FNVALL);
- p += len3;
- }
- s += len2; /* and skip past it. */
- } else { /* No, */
- *p++ = *s++; /* just copy this character */
- }
- }
- *p = NUL;
- while ((*p++ = *s++));
- if (occur < 0) { /* cheap... */
- occur = xx + occur + 1;
- xx = 0;
- p = fnval;
- j = j2;
- if (occur > 0)
- goto ragain;
- }
- }
- }
- p = fnval;
- goto fnend;
-
- case FN_CHR: /* \fcharacter(arg1) */
- val1 = *(bp[0]) ? evalx(bp[0]) : "";
- if (chknum(val1)) { /* Must be numeric */
- i = atoi(val1);
- if (i >= 0 && i < 256) { /* Must be an 8-bit value */
- p = fnval;
- *p++ = (char) i;
- *p = NUL;
- p = fnval;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- }
- } else {
- failed = 1;
- evalerr(fn);
- }
- goto fnend;
-
- case FN_COD: /* \fcode(char) */
- if ((int)strlen(bp[0]) > 0) {
- p = fnval;
- i = *bp[0];
- sprintf(p,"%d",(i & 0xff)); /* SAFE */
- } else p = "0"; /* Can't happen */
- goto fnend;
-
- case FN_LEN: /* \flength(arg1) */
- if (argn > 0) {
- p = fnval;
- sprintf(p,"%d",(int)strlen(bp[0])); /* SAFE */
- } else p = "0";
- goto fnend;
-
- case FN_LOW: /* \flower(arg1) */
- s = bp[0] ? bp[0] : "";
- p = fnval;
- while (*s) {
- if (isupper(*s))
- *p = (char) tolower(*s);
- else
- *p = *s;
- p++; s++;
- }
- *p = NUL;
- p = fnval;
- goto fnend;
-
- case FN_MAX: /* \fmax(arg1,arg2) */
- case FN_MIN: /* \fmin(arg1,arg2) */
- case FN_MOD: /* \fmod(arg1,arg2) */
- val1 = *(bp[0]) ? evalx(bp[0]) : "";
-#ifdef COMMENT
- /* No longer necessary because evalx() no longer overwrites its */
- /* result every time it's called (2000/09/23). */
- free(bp[0]);
- bp[0] = NULL;
-#endif /* COMMENT */
- if (argn > 1) {
-#ifdef COMMENT
- /* Ditto... */
- bp[0] = malloc((int)strlen(val1)+1);
- if (bp[0])
- strcpy(bp[0],val1); /* safe */
- val1 = bp[0];
-#endif /* COMMENT */
- val2 = *(bp[1]) ? evalx(bp[1]) : "";
- if (chknum(val1) && chknum(val2)) {
- i = atoi(val1);
- j = atoi(val2);
- switch (y) {
- case FN_MAX:
- if (j < i) j = i;
- break;
- case FN_MIN:
- if (j > i) j = i;
- break;
- case FN_MOD:
- if (j == 0) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:DIVIDE_BY_ZERO:\\f",fn,"()>",NULL);
- else
- fnval[0] = NUL;
- goto fnend;
- } else
- j = i % j;
- }
- p = fnval;
- sprintf(p,"%d",j); /* SAFE */
- } else {
- failed = 1;
- evalerr(fn);
- }
- } else p = val1;
- goto fnend;
- } /* Break up big switch... */
-
- switch (y) {
- case FN_SUB: /* \fsubstr(arg1,arg2,arg3) */
- case FN_RIG: /* \fright(arg1,arg2) */
- case FN_LEF: /* \fleft(arg1,arg2) */
- if (argn < 1)
- goto fnend;
- val1 = "";
- if (argn > 1)
- if (*(bp[1]))
- val1 = evalx(bp[1]);
-#ifdef COMMENT
- if (bp[1]) free(bp[1]); /* Have to copy this */
- bp[1] = malloc((int)strlen(val1)+1);
- if (!bp[1]) {
- failed = 1;
- if (fndiags) {
- p = fnval;
- ckmakmsg(fnval,FNVALL,
- "<ERROR:MALLOC_FAILURE:\\f",fn,"()>",NULL);
- }
- goto fnend;
- }
- strcpy(bp[1],val1); /* safe */
- val1 = bp[1];
-#endif /* COMMENT */
- val2 = "";
- if (argn > 2)
- if (*(bp[2]))
- val2 = evalx(bp[2]);
- if (
- ((argn > 1) && (int)strlen(val1) && !rdigits(val1)) ||
- ((cx == FN_SUB) &&
- ((argn > 2) && (int)strlen(val2) && !rdigits(val2)))
- ) {
- failed = 1;
- evalerr(fn);
- } else {
- int lx;
- p = fnval; /* pointer to result */
- lx = strlen(bp[0]); /* length of arg1 */
- if (cx == FN_SUB) { /* substring */
- k = (argn > 2) ? atoi(val2) : MAXARGLEN; /* length */
- j = (argn > 1) ? atoi(val1) : 1; /* start pos for substr */
- } else if (cx == FN_LEF) { /* left */
- k = (argn > 1) ? atoi(val1) : lx;
- j = 1;
- } else { /* right */
- k = (argn > 1) ? atoi(val1) : lx; /* length */
- j = lx - k + 1; /* start pos for right */
- if (j < 1) j = 1;
- }
- if (k > 0 && j <= lx) { /* if start pos in range */
- s = bp[0]+j-1; /* point to source string */
- for (i = 0; (i < k) && (*p++ = *s++); i++) ; /* copy */
- }
- *p = NUL; /* terminate the result */
- p = fnval; /* and point to it. */
- }
- goto fnend;
-
- case FN_UPP: /* \fupper(arg1) */
- s = bp[0] ? bp[0] : "";
- p = fnval;
- while (*s) {
- if (islower(*s))
- *p = (char) toupper(*s);
- else
- *p = *s;
- p++; s++;
- }
- *p = NUL;
- p = fnval;
- goto fnend;
-
- case FN_REP: /* \frepeat(text,number) */
- if (argn < 1)
- goto fnend;
- val1 = "1";
- if (argn > 1)
- if (*(bp[1]))
- val1 = evalx(bp[1]);
- if (chknum(val1)) { /* Repeat count */
- n = atoi(val1);
- debug(F111,"SUNDAY frepeat n",val1,n);
- if (n > 0) { /* Make n copies */
- p = fnval;
- *p = '\0';
- k = (int)strlen(bp[0]); /* Make sure string has some length */
- debug(F111,"SUNDAY frepeat k","",k);
- debug(F111,"SUNDAY frepeat FNVALL","",FNVALL);
- if (k * n >= FNVALL) { /* But not too much... */
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:RESULT_TOO_LONG:\\f",fn,"()>",NULL);
- else
- fnval[0] = NUL;
- p = fnval;
- goto fnend;
- }
- if (k > 0) { /* If there is something to copy */
- for (i = 0; i < n; i++) { /* Copy loop */
- s = bp[0];
- for (j = 0; j < k; j++) {
- if ((p - fnval) >= FNVALL)
- break; /* shouldn't happen... */
- else
- *p++ = *s++;
- }
- }
- *p = NUL;
- }
- }
- } else {
- failed = 1;
- evalerr(fn);
- }
- p = fnval;
- goto fnend;
-
-#ifndef NOFRILLS
- case FN_REV: /* \freverse() */
- if (argn < 1)
- goto fnend;
- yystring(bp[0],&p);
- goto fnend;
-#endif /* NOFRILLS */
-
- case FN_RPA: /* \frpad() and \flpad() */
- case FN_LPA:
- if (argn < 1)
- goto fnend;
- val1 = "";
- if (argn > 1)
- if (*(bp[1]))
- val1 = evalx(bp[1]);
- if (argn == 1) { /* If a number wasn't given */
- p = fnval; /* just return the original string */
- ckstrncpy(p,bp[0],FNVALL);
- } else if (argn > 1 && !*val1) {
- failed = 1;
- evalerr(fn);
- } else /* if (chknum(val1)) */ { /* Repeat count */
- char pc;
- n = atoi(val1);
- if (n >= 0) {
- p = fnval;
- k = (int)strlen(bp[0]); /* Length of string to be padded */
- if (k >= n) { /* It's already long enough */
- ckstrncpy(p,bp[0],FNVALL);
- } else {
- if (n + k <= FNVALL) {
- pc = (char) ((argn < 3) ? SP : *bp[2]);
- if (!pc) pc = SP;
- if (cx == FN_RPA) { /* RPAD */
- strncpy(p,bp[0],k); /* (leave it like this) */
- p[k] = NUL;
- p += k;
- for (i = k; i < n; i++)
- *p++ = pc;
- } else { /* LPAD */
- n -= k;
- for (i = 0; i < n; i++)
- *p++ = pc;
- strncpy(p,bp[0],k); /* (leave it like this) */
- p[k] = NUL;
- p += k;
- }
- }
- *p = NUL;
- }
- }
- }
- p = fnval;
- goto fnend;
-
-#ifdef ZFCDAT
- case FN_FD: /* \fdate(filename) */
- p = fnval;
- s = zfcdat(bp[0]);
- if (!s) s = "";
- if (!*s) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:FILE_NOT_FOUND:\\f",fn,"()>",NULL);
- goto fnend;
- }
- ckstrncpy(fnval,s,FNVALL);
-#endif /* ZFCDAT */
- goto fnend;
-
- } /* Break up big switch... */
-
- switch (y) {
- case FN_FS: { /* \fsize(filename) */
- CK_OFF_T z;
- p = fnval;
- z = zchki(bp[0]);
- if (z < (CK_OFF_T)0) {
- failed = 1;
- if (fndiags) {
- if (z == (CK_OFF_T)-1)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:FILE_NOT_FOUND:\\f",fn,"()>",NULL);
- else if (z == (CK_OFF_T)-2)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:FILE_NOT_READABLE:\\f",fn,"()>",NULL);
- else if (z == (CK_OFF_T)-3)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:FILE_NOT_ACCESSIBLE:\\f",fn,"()>",NULL);
- else
- ckmakmsg(fnval,FNVALL,
- "<ERROR:FILE_ERROR:\\f",fn,"()>",NULL);
- }
- goto fnend;
- }
- ckstrncpy(fnval,ckfstoa(z),FNVALL);
- goto fnend;
- }
- case FN_VER: /* \fverify() */
- p = "-1";
- if (argn == 1) /* No second arg */
- goto fnend;
- else if (!bp[1]) /* Or second arg null */
- goto fnend;
- else if (!*(bp[1])) /* or empty. */
- goto fnend;
- p = "0";
- if (argn > 1) { /* Only works if we have 2 or 3 args */
- int start;
- char *s2, ch1, ch2;
- start = 0;
- if (argn > 2) { /* Starting position specified */
- val1 = *(bp[2]) ? evalx(bp[2]) : "0";
- if (chknum(val1)) {
- start = atoi(val1) /* - 1 */;
- if (start < 0) start = 0;
- if (start > (int)strlen(bp[1]))
- goto verfin;
- } else {
- failed = 1;
- evalerr(fn);
- goto fnend;
- }
- }
- i = start;
- p = "0";
- for (s = bp[1] + start; *s; s++,i++) {
- ch1 = *s;
- if (!inpcas[cmdlvl]) if (islower(ch1)) ch1 = toupper(ch1);
- j = 0;
- for (s2 = bp[0]; *s2; s2++) {
- ch2 = *s2;
- if (!inpcas[cmdlvl]) if (islower(ch2)) ch2 = toupper(ch2);
- if (ch1 == ch2) {
- j = 1;
- break;
- }
- }
- if (j == 0) {
- sprintf(fnval,"%d",i+1); /* SAFE */
- p = fnval;
- break;
- }
- }
- }
- verfin:
- goto fnend;
-
- case FN_IPA: /* Find and return IP address */
- if (argn > 0) { /* in argument string. */
- int start = 0;
- if (argn > 1) { /* Starting position specified */
- if (chknum(bp[1])) {
- start = atoi(bp[1]) - 1;
- if (start < 0) start = 0;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- p = getip(bp[0]+start);
- } else p = "";
- goto fnend;
-
-#ifdef OS2
- case FN_CRY:
- p = "";
- if (argn > 0) {
- p = fnval;
- ckstrncpy(p,bp[0],FNVALL);
- ck_encrypt(p);
- }
- goto fnend;
-
- case FN_OOX:
- p = "";
- if (argn > 0)
- p = (char *) ck_oox(bp[0], (argn > 1) ? bp[1] : "");
- goto fnend;
-#endif /* OS2 */
-
- case FN_HEX: /* \fhexify(arg1) */
- if (argn < 1)
- goto fnend;
- if ((int)strlen(bp[0]) < (FNVALL / 2)) {
- s = bp[0];
- p = fnval;
- while (*s) {
- x = (*s >> 4) & 0x0f;
- *p++ = hexdigits[x];
- x = *s++ & 0x0f;
- *p++ = hexdigits[x];
- }
- *p = NUL;
- p = fnval;
- }
- goto fnend;
-
- case FN_UNTAB: /* \funtab(arg1) */
- if (argn < 1)
- goto fnend;
- if ((int)strlen(bp[0]) < (FNVALL * 2)) {
- s = bp[0];
- p = fnval;
- if (untabify(bp[0],p,FNVALL) < 0) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:OVERFLOW:\\f",fn,"()>",NULL);
- }
- goto fnend;
- }
-
- case FN_UNH: { /* \funhex(arg1) */
- int c[2], i;
- if (argn < 1)
- goto fnend;
- if ((int)strlen(bp[0]) < (FNVALL * 2)) {
- s = bp[0];
- p = fnval;
- while (*s) {
- for (i = 0; i < 2; i++) {
- c[i] = *s++;
- if (!c[i]) { p = ""; goto unhexfin; }
- if (islower(c[i])) c[i] = toupper(c[i]);
- if (c[i] >= '0' && c[i] <= '9') {
- c[i] -= 0x30;
- } else if (c[i] >= 'A' && c[i] <= 'F') {
- c[i] -= 0x37;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,
- FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",
- fn,
- "()>",
- NULL
- );
- goto fnend;
- }
- }
- *p++ = ((c[0] << 4) & 0xf0) | (c[1] & 0x0f);
- }
- *p = NUL;
- p = fnval;
- }
- unhexfin:
- goto fnend;
- }
-
- case FN_BRK: { /* \fbreak() */
- char * c; /* Characters to break on */
- char c2, s2;
- int start = 0;
- int done = 0;
- if (argn < 1)
- goto fnend;
- if (argn > 2) {
- s = bp[2] ? bp[2] : "0";
- if (chknum(s)) {
- start = atoi(s);
- if (start < 0) start = 0;
- if (start > (int)strlen(bp[0]))
- goto brkfin;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- s = bp[0] + start; /* Source pointer */
-
- while (*s && !done) {
- s2 = *s;
- if (!inpcas[cmdlvl] && islower(s2)) s2 = toupper(s2);
- c = bp[1] ? bp[1] : ""; /* Character to break on */
- while (*c) {
- c2 = *c;
- if (!inpcas[cmdlvl] && islower(c2)) c2 = toupper(c2);
- if (c2 == s2) {
- done = 1;
- break;
- }
- c++;
- }
- if (done) break;
- *p++ = *s++;
- }
- *p = NUL; /* terminate the result */
- p = fnval; /* and point to it. */
- brkfin:
- goto fnend;
- }
-
- case FN_SPN: { /* \fspan() */
- char *q;
- char c1, c2;
- int start = 0;
- if (argn < 1)
- goto fnend;
- if (argn > 2) { /* Starting position */
- s = bp[2] ? bp[2] : "0";
- if (chknum(s)) {
- start = atoi(s);
- if (start < 0) start = 0;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- s = bp[0] + start; /* Source pointer */
- if (argn > 1 &&
- (int)strlen(bp[1]) > 0 &&
- start <= (int)strlen(bp[0])) {
- while (*s) { /* Loop thru source string */
- q = bp[1]; /* Span string */
- c1 = *s;
- if (!inpcas[cmdlvl])
- if (islower(c1)) c1 = toupper(c1);
- x = 0;
- while ((c2 = *q++)) {
- if (!inpcas[cmdlvl])
- if (islower(c2)) c2 = toupper(c2);
- if (c1 == c2) { x = 1; break; }
- }
- if (!x) break;
- *p++ = *s++;
- }
- *p = NUL; /* Terminate and return the result */
- p = fnval;
- }
- goto fnend;
- }
- } /* Break up big switch... */
-
- switch (y) {
- case FN_TRM: /* \ftrim(s1[,s2]) */
- case FN_LTR: /* \fltrim(s1[,s2]) */
- if (argn < 1)
- goto fnend;
- if ((len1 = (int)strlen(bp[0])) > 0) {
- if (len1 > FNVALL)
- len1 = FNVALL;
- s = " \t\r\n";
- if (argn > 1) /* Trim list given */
- s = bp[1];
- len2 = (int)strlen(s);
- if (len2 < 1) { /* or not... */
- s = " \t\r\n"; /* Default is to trim whitespace */
- len2 = 2;
- }
- if (cx == FN_TRM) { /* Trim from right */
- char * q, p2, q2;
- ckstrncpy(fnval,bp[0],FNVALL); /* Copy string to output */
- p = fnval + len1 - 1; /* Point to last character */
-
- while (p >= (char *)fnval) { /* Go backwards */
- q = s; /* Point to trim list */
- p2 = *p;
- if (!inpcas[cmdlvl])
- if (islower(p2)) p2 = toupper(p2);
- while (*q) { /* Is this char in trim list? */
- q2 = *q;
- if (!inpcas[cmdlvl])
- if (islower(q2)) q2 = toupper(q2);
- if (p2 == q2) { /* Yes, null it out */
- *p = NUL;
- break;
- }
- q++;
- }
- if (!*q) /* Trim list exhausted */
- break; /* So we're done. */
- p--; /* Else keep trimming */
- }
- } else { /* Trim from left */
- char * q, p2, q2;
- p = bp[0]; /* Source */
- while (*p) {
- p2 = *p;
- if (!inpcas[cmdlvl])
- if (islower(p2)) p2 = toupper(p2);
- q = s;
- while (*q) { /* Is this char in trim list? */
- q2 = *q;
- if (!inpcas[cmdlvl])
- if (islower(q2)) q2 = toupper(q2);
- if (p2 == q2) { /* Yes, point past it */
- p++; /* and try next source character */
- break;
- }
- q++; /* No, try next trim character */
- }
- if (!*q) /* Trim list exhausted */
- break; /* So we're done. */
- }
- ckstrncpy(fnval,p,FNVALL);
- }
- p = fnval;
- } else p = "";
- goto fnend;
-
- case FN_CAP: /* \fcapitalize(arg1) */
- if (argn < 1)
- goto fnend;
- s = bp[0];
- p = fnval;
- x = 0;
- while ((c = *s++)) {
- if (isalpha(c)) {
- if (x == 0) {
- x = 1;
- if (islower(c))
- c = toupper(c);
- } else if (isupper(c))
- c = tolower(c);
- }
- *p++ = c;
- }
- *p = NUL;
- p = fnval;
- goto fnend;
-
-#ifdef COMMENT
- case FN_TOD: /* Time of day to secs since midnite */
- sprintf(fnval,"%ld",tod2sec(bp[0])); /* SAFE */
- goto fnend;
-#endif /* COMMENT */
-
- case FN_FFN: /* Full pathname of file */
- zfnqfp(bp[0],FNVALL,p);
- if (!p) p = "";
- goto fnend;
-
- case FN_CHK: { /* \fchecksum() */
- long chk = 0;
- p = (argn > 0) ? bp[0] : "";
- while (*p) chk += *p++;
- sprintf(fnval,"%lu",chk); /* SAFE */
- p = fnval;
- goto fnend;
- }
-
-#ifndef NOXFER
- case FN_CRC: /* \fcrc16() */
- if (argn > 0)
- sprintf(fnval,"%u", /* SAFE */
- chk3((CHAR *)bp[0],(int)strlen(bp[0])));
- else
- p = "0";
- goto fnend;
-#endif /* NOXFER */
-
- case FN_BSN: /* \fbasename() */
- zstrip(bp[0],&p);
- goto fnend;
-
-#ifndef NOLOCAL
-#ifdef OS2
- case FN_SCRN_CX: /* \fscrncurx() */
- p = fnval;
- sprintf(p,"%d",(int)VscrnGetCurPos(VTERM)->x); /* SAFE */
- goto fnend;
-
- case FN_SCRN_CY: /* \fscrncury() */
- p = fnval;
- sprintf(p,"%d",(int)VscrnGetCurPos(VTERM)->y); /* SAFE */
- goto fnend;
-
- case FN_SCRN_STR: { /* \fscrnstr() */
- videoline * line = NULL;
- viocell * cells = NULL;
- int row = 0, col = 0, len = 0;
- /* NOTE: On Unicode systems, the screen contents are stored in */
- /* in Unicode. Therefore, we should really be performing a */
- /* conversion to the local character set. */
-
- /* 6/18/2000 - added the translation to lcs */
-
- if (bp[0] == NULL || bp[0][0] == '\0') {
- row = 0;
- } else {
- if (chknum(bp[0])) {
- row = atoi(bp[0]);
- if (row < 0)
- row = 0;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- line = VscrnGetLineFromTop( VTERM, (USHORT) row );
- if (line != NULL) {
- if (bp[1] == NULL || bp[1][0] == '\0')
- col = 0;
- else {
- if (chknum(bp[0])) {
- col = atoi(bp[1]);
- if (col < 0 || col >= line->width)
- col = 0;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- if (bp[2] == NULL || bp[2][0] == '\0') {
- len = line->width - (col+1);
- } else {
- if (!chknum(bp[2])) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- len = atoi(bp[2]);
- if (len < 0 || len > line->width)
- len = line->width;
- }
- cells = line->cells;
- for (i = 0; i < len; i++) {
- int pos = i + col;
- if (pos < line->width) {
- if (isunicode())
- fnval[i] = (CHAR) utolxlat(cells[pos].c);
- else
- fnval[i] = (CHAR) (cells[pos].c & 0xFF);
- if (fnval[i] == 0)
- fnval[i] = SP;
- } else
- fnval[i] = SP;
- }
- fnval[i] = '\0';
- } else {
- fnval[0] = '\0';
- }
- p = fnval;
- goto fnend;
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifndef NOPUSH
- case FN_RAW: /* \frawcommand() */
- case FN_CMD: { /* \fcommand() */
- int x, c, n = FNVALL;
- x = 0; /* Completion flag */
-/*
- ZIFILE can be safely used because we can't possibly be transferring a file
- while executing this function.
-*/
- if (!nopush && zxcmd(ZIFILE,bp[0]) > 0) { /* Open the command */
- while (n-- > -1) { /* Read from it */
- if ((c = zminchar()) < 0) {
- x = 1; /* EOF - set completion flag */
- if (cx == FN_CMD) { /* If not "rawcommand" */
- p--; /* remove trailing newlines */
- while (*p == CR || *p == LF)
- p--;
- p++;
- }
- *p = NUL; /* Terminate the string */
- break;
- } else /* Command still running */
- *p++ = c; /* Copy the bytes */
- }
- zclose(ZIFILE); /* Close the command */
- }
- /* Return null string if command's output was too long. */
- p = fnval;
- if (!x) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:RESULT_TOO_LONG:\\f",fn,"()>",NULL);
- }
- goto fnend;
- }
-#endif /* NOPUSH */
- } /* Break up big switch... */
-
- switch (y) {
- case FN_STX: /* \fstripx(string,c) */
- if (!(s = bp[0])) /* Make sure there is a string */
- goto fnend;
- c = '.'; /* Character to strip from */
- if (argn > 1) if (*bp[1]) c = *bp[1];
- n = ckstrncpy(fnval,bp[0],FNVALL);
- while (--n >= 0) {
- if (fnval[n] == c) {
- fnval[n] = NUL;
- break;
- }
- }
- p = fnval;
- goto fnend;
-
- case FN_STL: /* \flop(string,c) */
- case FN_LOPX: { /* \flopx(string,c) */
- int n = 1;
- if (!(s = bp[0])) /* Make sure there is a string */
- goto fnend;
- c = '.'; /* Character to strip to */
- if (argn > 1) if (*bp[1]) c = *bp[1];
- if (argn > 2) if (*bp[2]) {
-#ifndef NOFLOAT
- n = 0;
- if (isfloat(bp[2],0)) {
- n = (int)floatval;
- if (n < 0) n = 0;
- } else
-#endif /* NOFLOAT */
- n = atoi(bp[2]);
- }
- x = 0;
- if (cx == FN_LOPX) { /* Lopx (from right) */
- if (n == 0)
- goto fnend;
- s += strlen(s) - 1; /* We already know it's > 0 */
- while (s-- >= bp[0]) {
- if (*s == c) {
- n--;
- if (n == 0) {
- s++;
- x = 1;
- break;
- }
- }
- }
- if (!x) s = "";
- } else { /* Lop (from left) */
- if (n == 0) {
- p = bp[0];
- goto fnend;
- }
- while (*s++) {
- if (*(s-1) == c) {
- if (--n == 0) {
- x = 1;
- break;
- }
- }
- }
- if (!x) s = bp[0];
- }
- ckstrncpy(fnval,s,FNVALL);
- p = fnval;
- goto fnend;
- }
- case FN_STN: /* \fstripn(string,n) */
- if (argn < 1) /* Remove n chars from right */
- goto fnend;
- val1 = "0";
- if (argn > 1)
- if (*(bp[1]))
- val1 = evalx(bp[1]);
- if (!chknum(val1)) {
- failed = 1;
- evalerr(fn);
- goto fnend;
- }
- n = atoi(val1);
- if (n < 0) n = 0;
- k = (int)strlen(s = bp[0]) - n;
- if (k < 0) k = 0;
- p = fnval;
- while (k-- > 0)
- *p++ = *s++;
- *p = NUL;
- p = fnval;
- goto fnend;
-
- case FN_STB: { /* \fstripb(string,c) */
- char c2 = NUL;
- int i, k = 0;
- char * gr_opn = "\"{'([<"; /* Group open brackets */
- char * gr_cls = "\"}')]>"; /* Group close brackets */
-
- p = fnval;
- *p = NUL;
- if (!(s = bp[0])) /* Make sure there is a string */
- goto fnend;
- if ((x = strlen(s)) < 1)
- goto fnend;
- c = NUL; /* Brace/bracket kind */
- if (argn > 1) {
- if (*bp[1]) {
- if (chknum(bp[1])) {
- k = atoi(bp[1]);
- if (k < 0) k = 63;
- for (i = 0; i < 6; i++) {
- if (k & (1<<i)) {
- if (s[0] == gr_opn[i] && s[x-1] == gr_cls[i]) {
- ckstrncpy(fnval,s+1,FNVALL);
- fnval[x-2] = NUL;
- goto fnend;
- }
- }
- }
- ckstrncpy(fnval,s,FNVALL); /* No match */
- goto fnend;
- }
- }
- }
- c = !bp[1] ? 0 : *bp[1];
- if (!c) c = s[0];
- if (argn > 2) if (*bp[2]) c2 = *bp[2];
- if (*s == c) {
- if (!c2) {
- switch (c) {
- case '(': c2 = ')'; break;
- case '[': c2 = ']'; break;
- case '{': c2 = '}'; break;
- case '<': c2 = '>'; break;
- case '"': c2 = '"'; break;
- case 39: c2 = 39; break;
- case 96: c2 = 39; break;
- default:
- if (argn == 2) {
- c2 = c;
- } else {
- strncpy(fnval,s,x); /* Leave it like this */
- fnval[x] = NUL;
- goto fnend;
- }
- }
- }
- if (s[x-1] == c2) {
- strncpy(fnval,s+1,x-2); /* Leave it like this */
- fnval[x-2] = NUL;
- goto fnend;
- }
- }
- strncpy(fnval,s,x);
- fnval[x] = NUL;
- goto fnend;
- }
-
- case FN_2HEX: /* Number to hex */
- case FN_2OCT: /* Number to octal */
- val1 = evalx(bp[0]);
- if (!*val1) {
- failed = 1;
- evalerr(fn);
- goto fnend;
- }
- sprintf(fnval, cx == FN_2HEX ? "%lx" : "%lo", atol(val1)); /* SAFE */
- if (cx == FN_2HEX && (int)(strlen(fnval)&1))
- sprintf(fnval,"0%lx",atol(val1)); /* SAFE */
- p = fnval;
- goto fnend;
-
- case FN_DNAM: { /* Directory part of file name */
- char *s;
- zfnqfp(bp[0],FNVALL,p); /* Get full name */
- if (!isdir(p)) { /* Is it already a directory? */
- zstrip(p,&s); /* No get basename */
- if (*s) {
- x = ckindex(s,p,0,0,0); /* Pos of latter in former */
- if (x > 0) p[x-1] = NUL;
- }
- }
- if (!p) p = "";
- goto fnend;
- }
-
-#ifndef NORANDOM
- case FN_RAND: /* Random number */
-#ifdef CK_SSL
- if (RAND_bytes((unsigned char *)&k,sizeof(k)) < 0)
-#endif /* CK_SSL */
- k = rand();
- x = 0;
- if (argn > 0) {
- if (!chknum(bp[0])) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- x = atoi(bp[0]);
- }
-#ifdef COMMENT
- sprintf(fnval,"%d", (x > 0 && k > 0) || (x < 0 && k < 0) ? k % x :
- (x == 0 ? 0 : (0 - (k % (-x)))));
-#else
- debug(F111,"rand",ckitoa(x),k);
-#ifdef SUNOS4
-/* This is really strange but on SunOS, if we are requesting random numbers */
-/* between 0 and 4 or less, they always come out in sequence: 0 1 2 3 0 1 2 */
-/* Shifting the result of rand() in this case gives a more random result. */
- if (x < 5)
- k = k >> 5;
-#endif /* SUNOS4 */
- if ((x > 0 && k > 0) || (x < 0 && k < 0))
- x = k % x;
- else if (x == 0)
- x = 0;
- else
- x = 0 - (k % (-x));
- debug(F101,"rand x","",x);
- sprintf(fnval,"%d", x); /* SAFE */
-#endif /* COMMENT */
- p = fnval;
- goto fnend;
-#endif /* NORANDOM */
- } /* Break up big switch... */
-
- switch (y) {
- case FN_SPLIT: /* \fsplit(s1,a,s2,s3,mask) */
- case FN_WORD: { /* \fword(s1,n,s2,s3,mask) */
- int wordnum = 0;
- int splitting = 0;
- int x;
- int array = 0;
- int grouping = 0;
- int nocollapse = 0;
- char * sep = "";
- char * notsep = "";
- char * bp0 = NULL;
- char * bp1 = NULL;
- char abuf[16];
- struct stringarray * q = NULL;
-
- splitting = (cx == FN_SPLIT); /* Our job */
- debug(F101,"FN_SPLIT splitting","",splitting);
-
- fnval[0] = splitting ? '0' : NUL; /* Initial return value */
- fnval[1] = NUL;
- p = fnval;
- bp0 = bp[0]; /* Source string */
- if (!bp0) bp0 = "";
- debug(F111,"fsplit bp[0]",bp0,argn);
- if (argn < 1 || !*bp0) /* If none, return default value */
- goto fnend;
-
- bp1 = bp[1]; /* Function-dependent arg */
- if (!bp1) bp1 = ""; /* (array or number) */
- debug(F110,"fsplit bp[1]",bp1,0);
- if (bp[5]) {
- if (!chknum(bp[5])) {
- failed = 1;
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- x = atoi(bp[5]);
- nocollapse = x;
- }
- if (!splitting) { /* \fword(): n = desired word number */
- val1 = "1"; /* Default is first word */
- if (argn > 1) /* Word number supplied */
- if (*bp1)
- val1 = evalx(bp1);
- if (!chknum(val1)) {
- failed = 1;
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- n = atoi(val1);
- } else if (argn > 1 && *bp1) { /* \fsplit(): n = word count */
- ckstrncpy(abuf,bp1,16); /* Get array reference */
- debug(F110,"fsplit abuf 1",abuf,0);
- failed = 1; /* Assume it's bad */
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_BAD_ARRAY:\\f",fn,"()>",NULL);
- if (abuf[0] != '&') /* "Address" of array */
- goto fnend; /* It's bad */
- if (abuf[2]) { /* Check for brackets */
- if (abuf[2] != '[' || abuf[3] != ']') {
- goto fnend; /* Bad */
- }
- }
- debug(F110,"fsplit abuf 2",abuf,0);
- if (abuf[1] > 64 && abuf[1] < 91) /* Convert upper to lower */
- abuf[1] += 32;
- if (abuf[1] < 97 || abuf[1] > 122) { /* Check for a-z */
- goto fnend;
- }
- debug(F110,"fsplit abuf 3",abuf,0);
- array = 1;
- fnval[0] = NUL; /* No error, erase message */
- failed = 0; /* Unset failure flag */
- n = 0; /* Initialize word counter */
- }
- if (argn > 2) /* Have break set? */
- sep = bp[2];
- debug(F111,"fsplit sep",sep,argn);
- if (argn > 3) /* Have include set? */
- notsep = bp[3];
- debug(F111,"fsplit notsep",notsep,argn);
- if (argn > 4) { /* Have grouping set? */
- char * bp4 = bp[4];
- debug(F111,"fsplit bp4",bp4,argn);
- if (!bp4) bp4 = "0";
- if (!*bp4) bp4 = "0";
- if (chknum(bp4)) {
- grouping = atoi(bp4);
- if (grouping == -1)
- grouping = 127;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- /* Args parsed, now do the work */
-
- debug(F111,"fsplit bp0",bp0,n);
- q = cksplit(splitting,n,bp0,sep,notsep,grouping,0,nocollapse);
-
- wordnum = q ? q->a_size : -1; /* Check result */
- if (wordnum < 0) {
- failed = 1; /* Failure */
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- (wordnum == -1) ?
- "<ERROR:MALLOC_FAILURE:\\f" :
- "<ERROR:TOO_MANY_WORDS:\\f",
- fn,
- "()>",
- NULL
- );
- goto fnend;
- }
- if (splitting) { /* \fsplit() result */
- ckstrncpy(fnval,ckitoa(wordnum),FNVALL);
- if (array) { /* Array was not declared. */
- int i;
- if ((x = dclarray(abuf[1],wordnum)) < 0) { /* Declare it. */
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:MALLOC_FAILURE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- for (i = 1; i <= wordnum; i++) { /* Copy results */
- makestr(&(a_ptr[x][i]),q->a_head[i]);
- }
- a_ptr[x][0] = NULL; /* Array is 1-based */
- makestr(&(a_ptr[x][0]),fnval); /* Element = size */
- }
- } else { /* \fword() result */
- char * s;
- s = q->a_head[1];
- if (!s) s = "";
- ckstrncpy(fnval,s,FNVALL);
- }
- goto fnend; /* Done */
- }
-
- } /* Break up big switch... */
-
- switch (y) {
-
-#ifdef CK_KERBEROS
- case FN_KRB_TK: /* Kerberos tickets */
- case FN_KRB_NX: /* Kerberos next ticket */
- case FN_KRB_IV: /* Kerberos ticket is valid */
- case FN_KRB_FG: /* Kerberos Ticket flags */
- case FN_KRB_TT: { /* Kerberos ticket time */
- int kv = 0; /* Kerberos version */
- int n = 0;
- char * s = NULL;
- if (rdigits(bp[0])) {
- kv = atoi(bp[0]);
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- if (kv != 4 && kv != 5) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- if ((cx == FN_KRB_IV || cx == FN_KRB_TT || cx == FN_KRB_FG) &&
- argn < 2) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:MISSING_ARG:\\f",fn,"()>",NULL);
- goto fnend;
- }
- switch (y) {
- case FN_KRB_TK: /* Number of Kerberos tickets */
-#ifdef CK_AUTHENTICATION
- switch (kv) {
- case 4:
- n = ck_krb4_get_tkts();
- sprintf(fnval, "%d", (n >= 0) ? n : 0); /* SAFE */
- goto fnend;
- case 5: {
- extern char * krb5_d_cc;
- n = ck_krb5_get_tkts(krb5_d_cc);
- sprintf(fnval, "%d", (n >= 0) ? n : 0); /* SAFE */
- goto fnend;
- }
- }
-#else
- sprintf(fnval,"%d",0); /* SAFE */
-#endif /* CK_AUTHENTICATION */
- goto fnend;
-
- case FN_KRB_NX: /* Kerberos next ticket */
-#ifdef CK_AUTHENTICATION
- switch (kv) {
- case 4:
- s = ck_krb4_get_next_tkt();
- ckstrncpy(fnval, s ? s : "",FNVALL);
- goto fnend;
- case 5:
- s = ck_krb5_get_next_tkt();
- ckstrncpy(fnval, s ? s : "",FNVALL);
- goto fnend;
- }
-#else
- sprintf(fnval,"k%d next-ticket-string",kv); /* SAFE */
-#endif /* CK_AUTHENTICATION */
- goto fnend;
-
- case FN_KRB_IV: /* Kerberos ticket is valid */
-#ifdef CK_AUTHENTICATION
- /* Return 1 if valid, 0 if not */
- switch (kv) {
- case 4:
- n = ck_krb4_tkt_isvalid(bp[1]);
- sprintf(fnval, "%d", n > 0 ? 1 : 0); /* SAVE */
- goto fnend;
- case 5: {
- extern char * krb5_d_cc;
- n = ck_krb5_tkt_isvalid(krb5_d_cc,bp[1]);
- sprintf(fnval,"%d", n > 0 ? 1 : 0); /* SAFE */
- goto fnend;
- }
- }
-#else
- sprintf(fnval,"%d",0); /* SAFE */
-#endif /* CK_AUTHENTICATION */
- goto fnend;
-
- case FN_KRB_TT: /* Kerberos ticket time */
-#ifdef CK_AUTHENTICATION
- switch (kv) {
- case 4:
- n = ck_krb4_tkt_time(bp[1]);
- sprintf(fnval,"%d", n >= 0 ? n : 0); /* SAFE */
- goto fnend;
- case 5: {
- extern char * krb5_d_cc;
- n = ck_krb5_tkt_time(krb5_d_cc,bp[1]);
- sprintf(fnval,"%d", n >= 0 ? n : 0); /* SAFE */
- goto fnend;
- }
- }
-#else
- ckstrncpy(fnval,"600",FNVALL); /* Some time */
-#endif /* CK_AUTHENTICATION */
- goto fnend;
-
- case FN_KRB_FG: /* Kerberos ticket flags */
-#ifdef CK_AUTHENTICATION
- switch (kv) {
- case 4:
- fnval[0] = '\0';
- goto fnend;
- case 5: {
- extern char * krb5_d_cc;
- ckstrncpy(fnval,ck_krb5_tkt_flags(krb5_d_cc,bp[1]),FNVALL);
- goto fnend;
- }
- }
-#else
- fnval[0] = '\0';
-#endif /* CK_AUTHENTICATION */
- goto fnend;
- }
- p = fnval;
- goto fnend;
- }
-#endif /* CK_KERBEROS */
-
-#ifdef FN_ERRMSG
- case FN_ERRMSG:
- if (rdigits(bp[0])) {
- k = atoi(bp[0]);
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
-#ifdef VMS
- ckstrncpy(fnval,ckvmserrstr(k),FNVALL);
-#else
- x = errno;
- errno = k;
- ckstrncpy(fnval,ck_errstr(),FNVALL);
- errno = x;
-#endif /* VMS */
- p = fnval;
- goto fnend;
-#endif /* FN_ERRMSG */
-
- case FN_DIM: {
- int max;
- char abuf[16], *s;
- fnval[0] = NUL; /* Initial return value */
- ckstrncpy(abuf,bp[0],16); /* Get array reference */
- s = abuf;
- if (*s == CMDQ) s++;
- failed = 1; /* Assume it's bad */
- p = fnval; /* Point to result */
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,"<ERROR:ARG_BAD_ARRAY:\\f",fn,"()>",NULL);
- if (s[0] != '&') { /* "Address" of array */
- goto fnend;
- }
- if (s[2]) {
- if (s[2] != '[' || s[3] != ']') {
- goto fnend;
- }
- }
- if (s[1] >= 64 && s[1] < 91) /* Convert upper to lower */
- s[1] += 32;
- if (s[1] < 95 || s[1] > 122) { /* Check for a-z */
- goto fnend; /* Bad */
- }
- if ((max = chkarray(s[1],1)) < 1) /* (second arg was 1) */
- max = 0;
- failed = 0; /* Unset failure flag */
- sprintf(fnval,"%d",max); /* SAFE */
- goto fnend;
- }
-
- } /* Break up big switch... */
-
- switch (y) {
- case FN_JDATE:
- if (argn < 1) /* Check number of args */
- p = ckdate(); /* None, get today's date-time */
- else /* Some */
- p = bp[0]; /* Use first */
- p = ckcvtdate(p,0); /* Convert to standard form */
- ckstrncpy(fnval,zjdate(p),FNVALL); /* Convert to Julian */
- p = fnval; /* Point to result */
- failed = 0;
- if (*p == '-') {
- failed = 1;
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,"<ERROR:ARG_BAD_DATE:\\f",fn,"()>",NULL);
- }
- goto fnend;
-
- case FN_DATEJ:
- ckstrncpy(fnval,jzdate(bp[0]),FNVALL); /* Convert to yyyy<dayofyear> */
- p = fnval; /* Point to result */
- failed = 0;
- if (*p == '-') {
- failed = 1;
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,"<ERROR:ARG_BAD_DATE:\\f",fn,"()>",NULL);
- }
- goto fnend;
-
- case FN_DTIM: /* \fcvtdate() */
- case FN_TIME: /* Free-format time to hh:mm:ss */
- case FN_NTIM: /* Time to sec since midnight */
- s = (argn > 0) ? bp[0] : "";
- if (!s) s = "";
- if (!*s)
- p = ckdate(); /* None, get today's date */
- else /* Some */
- p = bp[0]; /* Use first */
- {
- char * s;
- s = p;
- while (*s) {
- if (*s < 32) {
- *s = NUL;
- break;
- }
- s++;
- }
- /* do { if (*s < '!') *s = NUL; break; } while (*s++); */
- }
- p = ckcvtdate(p,2); /* Convert to standard form */
- if (*p == '<') {
- failed = 1;
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_BAD_DATE_OR_TIME:\\f",fn,"()>",NULL);
- p = fnval;
- goto fnend;
- }
- if (argn > 1) { /* Format code */
- s = bp[1];
- if (!s) s = "";
- if (!*s) s = "0";
- if (!chknum(s)) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- p = fnval;
- goto fnend;
- }
- x = atoi(s);
- /* if (x) */ p = shuffledate(p,x);
- }
- if (cx == FN_TIME) {
- p += 9;
- } else if (cx == FN_NTIM) {
- long sec = 0L;
- p[11] = NUL;
- p[14] = NUL;
- sec = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
- sprintf(fnval,"%ld",sec); /* SAFE */
- p = fnval;
- }
- goto fnend;
-
- case FN_MJD: /* Modified Julian Date */
- if (argn < 1) /* Check number of args */
- p = zzndate(); /* None, get today's date-time */
- else /* Some */
- p = bp[0]; /* Use first */
- p = ckcvtdate(p,0); /* Convert to standard form */
- if (*p == '-') {
- failed = 1;
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,"<ERROR:ARG_BAD_DATE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- /* Convert to modified Julian date */
- sprintf(fnval,"%ld",mjd(p)); /* SAFE */
- p = fnval; /* Point to result */
- goto fnend;
-
- case FN_MJD2: {
- long k = 0L;
- int n = 0;
- p = evalx(bp[0]);
- if (*p == '-') {
- p++;
- n = 1;
- }
- if (!rdigits(p)) {
- failed = 1;
- evalerr(fn);
- p = fnval;
- goto fnend;
- } else {
- k = atol(p);
- if (n) k = -k;
- }
- ckstrncpy(fnval,mjd2date(k),FNVALL); /* Convert to Date */
- p = fnval; /* Point to result */
- failed = 0;
- goto fnend;
- }
-
-#ifndef NODIAL
- case FN_PNCVT: { /* Convert phone number */
- extern char * pncvt();
- failed = 0;
- p = pncvt(bp[0]);
- if (!p) p = "";
- if (!*p) {
- failed = 1;
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_BAD_PHONENUM:\\f",fn,"()>",NULL);
- }
- goto fnend;
- }
-#endif /* NODIAL */
-
- case FN_DAY:
- case FN_NDAY:
- if (argn < 1) /* Check number of args */
- p = zzndate(); /* None, get today's date-time */
- else /* Some */
- p = bp[0]; /* Use first */
- p = ckcvtdate(p,0); /* Convert to standard form */
- if (*p == '-') {
- failed = 1;
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,"<ERROR:ARG_BAD_DATE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- failed = 0;
- z = mjd(p); /* Convert to modified Julian date */
- z = z % 7L;
- if (z < 0) {
- z = 0 - z;
- k = 6 - ((int)z + 3) % 7;
- } else {
- k = ((int)z + 3) % 7; /* Day of week */
- }
- p = fnval; /* Point to result */
- if (cx == FN_NDAY)
- sprintf(fnval,"%d",k); /* SAFE */
- else
- ckstrncpy(fnval,wkdays[k],FNVALL);
- goto fnend;
-
- case FN_N2TIM: { /* Sec since midnight to hh:mm:ss */
- long k = 0L;
- int n = 0, hh, mm, ss;
- char * s = bp[0];
- if (argn < 1) /* If no arg substitute 0 */
- s = "0";
- p = evalx(s); /* Evaluate expression silently */
- if (*p == '-') { /* Check result for minus sign */
- p++;
- n = 1;
- }
- if (!rdigits(p)) { /* Check for numeric */
- failed = 1;
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- p = fnval;
- goto fnend;
- } else {
- k = atol(p);
- if (n) k = -k;
- }
- if (k < 0) { /* Check for negative */
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- p = fnval;
- goto fnend;
- }
- hh = k / 3600L; /* Have positive number */
- mm = (k % 3600L) / 60L; /* break it down... */
- ss = ((k % 3600L) % 60L);
-
- sprintf(fnval,"%02d:%02d:%02d",hh,mm,ss); /* SAFE */
- p = fnval;
- failed = 0;
- goto fnend;
- }
-
- case FN_PERM: { /* File permissions */
- p = fnval;
- z = zchki(bp[0]);
- if (z < 0) {
- failed = 1;
- if (fndiags) {
- if (z == -1)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:FILE_NOT_FOUND:\\f",fn,"()>",NULL);
- else if (z == -2)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:FILE_NOT_READABLE:\\f",fn,"()>",NULL);
- else if (z == -3)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:FILE_NOT_ACCESSIBLE:\\f",fn,"()>",NULL);
- else
- ckmakmsg(fnval,FNVALL,
- "<ERROR:FILE_ERROR:\\f",fn,"()>",NULL);
- }
- goto fnend;
- }
-#ifdef CK_PERMS
- ckstrncpy(fnval,ziperm(bp[0]),FNVALL);
-#else
- ckstrncpy(fnval,"(unknown)",FNVALL);
-#endif /* CK_PERMS */
- goto fnend;
- }
- case FN_TLOOK: /* tablelook() */
- case FN_ALOOK: { /* arraylook() */
- int i, x, hi, lo, max, cmdlen;
- char abuf[16], *s, *pat;
- char kwbuf[256];
- char delim = ':';
- failed = 1; /* Assume failure */
- ckstrncpy(fnval,"-1",FNVALL);
- pat = bp[0]; /* Point to search pattern */
- if (!pat) pat = ""; /* Watch out for NULL pointer */
- cmdlen = strlen(pat); /* Get pattern length */
- if (argn < 2 /* || cmdlen < 1 */ ) { /* Need two args */
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:MISSING_ARG:\\f",fn,"()>",NULL);
- goto fnend;
- }
- ckstrncpy(abuf,bp[1],16); /* Get array reference */
- if (argn > 2)
- delim = *(bp[2]);
- s = abuf;
- if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Get index and bounds */
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:ARG_BAD_ARRAY:\\f",fn,"()>",NULL);
- goto fnend;
- }
- p = fnval; /* Point to result */
- max = a_dim[x]; /* Size of array */
- if (lo < 0) lo = 0; /* Use given range if any */
- if (lo > max) lo = max;
- if (hi < 0) hi = max;
- if (hi > max) hi = max;
- failed = 0; /* Unset failure flag */
- if (max < 1)
- goto fnend;
- kwbuf[255] = NUL;
- for (i = lo; i <= hi; i++) {
- if (!a_ptr[x][i])
- continue;
- if (cx == FN_ALOOK) {
- if (ckmatch(pat,a_ptr[x][i],inpcas[cmdlvl],1+4)) {
- sprintf(fnval,"%d",i); /* SAFE */
- goto fnend;
- }
- } else if (cx == FN_TLOOK) {
- char * aa;
- int j = 0, v = 0, len;
- if (i == hi)
- break;
- aa = a_ptr[x][i]; /* Point to this array element */
- if (!aa) aa = "";
- while (j < 254 && *aa) { /* Isolate keyword */
- if (*aa == delim)
- break;
- kwbuf[j++] = *aa++;
- }
- kwbuf[j] = NUL;
- len = j;
- v = 0;
- if ((len == cmdlen && !ckstrcmp(kwbuf,pat,len,0)) ||
- ((v = !ckstrcmp(kwbuf,pat,cmdlen,0)) &&
- ckstrcmp(a_ptr[x][i+1],pat,cmdlen,0))) {
- sprintf(fnval,"%d",i); /* SAFE */
- goto fnend;
- }
- if (v) { /* Ambiguous */
- ckstrncpy(fnval,"-2",FNVALL);
- goto fnend;
- }
- }
- }
- if (cx == FN_TLOOK) { /* tablelook() last element */
- ckstrncpy(fnval,"-1",FNVALL);
- if (!ckstrcmp(a_ptr[x][hi],pat,cmdlen,0))
- sprintf(fnval,"%d",hi); /* SAFE */
- }
- goto fnend;
- }
- case FN_TOB64: /* Base-64 conversion */
- case FN_FMB64:
- p = fnval;
- *p = NUL;
- if (argn < 1)
- goto fnend;
- if (cx == FN_TOB64) {
- x = b8tob64(bp[0],-1,fnval,FNVALL);
- } else {
- x = strlen(bp[0]);
- if (x % 4) { /* length must be multiple of 4 */
- failed = 1;
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_INCOMPLETE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- b64tob8(NULL,0,NULL,0); /* Reset */
- x = b64tob8(bp[0],-1,fnval,FNVALL);
- b64tob8(NULL,0,NULL,0); /* Reset again */
- }
- if (x < 0) {
- failed = 1;
- if (fndiags) {
- char * m = "INTERNAL_ERROR";
- switch (x) {
- case -1: m = "ARG_TOO_LONG"; break;
- case -2: m = "ARG_OUT_OF_RANGE"; break;
- }
- if (ckmakmsg(fnval,FNVALL,"<ERROR:",m,"\\f",fn) > 0)
- ckstrncat(fnval,"()>",FNVALL);
- }
- }
- goto fnend;
-
- case FN_ABS: {
- char * s;
- s = bp[0];
- if (*s == '-' || *s == '+')
- s++;
- if (!rdigits(s)) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- ckstrncpy(fnval,s,FNVALL);
- goto fnend;
- }
-
- case FN_AADUMP: {
- char abuf[16], *s = NULL, **ap = NULL, **vp = NULL;
- char pattern[VNAML];
- int slen, i, j, k, first = -1;
- extern int xdelmac();
- p = fnval;
- if (argn < 2) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:MISSING_ARG2:\\f",fn,"()>",NULL);
- goto fnend;
- }
- debug(F101,"aaconvert argn","",argn);
- s = bp[0];
- slen = strlen(s);
-
- /* Count elements so we can create the array */
-
- ckmakmsg(pattern,VNAML,s,"<*>",NULL,NULL);
- for (k = 0, i = 0; i < nmac; i++) {
- if (ckmatch(pattern,mactab[i].kwd,0,1)) {
- if (first < 0) /* Remember location of first match */
- first = i;
- k++;
- }
- }
- debug(F101,"aaconvert matches","",k);
- debug(F101,"aaconvert first","",first);
- fnval[0] = NUL; /* Initial return value */
- ckstrncpy(abuf,bp[1],16); /* Get array reference */
- s = abuf;
- if (*s == CMDQ) s++;
- p = fnval; /* Point to result */
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,"<ERROR:ARG_BAD_ARRAY:\\f",fn,"()>",NULL);
- if (s[0] != '&') /* Address of array */
- goto fnend;
- if (s[2])
- if (s[2] != '[' || s[3] != ']')
- goto fnend;
- if (s[1] >= 64 && s[1] < 91) /* Convert upper to lower */
- s[1] += 32;
- if ((x = dclarray(s[1],k)) < 0) /* Declare array to size */
- goto fnend;
- ap = a_ptr[x]; /* Point to array we just declared */
- /* debug(F111,"aaconvert array 1",abuf,ap); */
- abuf[0] = NUL;
- if (argn > 2) {
- ckstrncpy(abuf,bp[2],16); /* Get value array reference */
- s = abuf;
- if (*s == CMDQ) s++;
- if (s[0] != '&') /* Address of array */
- goto fnend;
- if (s[2])
- if (s[2] != '[' || s[3] != ']')
- goto fnend;
- if (s[1] >= 64 && s[1] < 91) /* Convert upper to lower */
- s[1] += 32;
- if ((x = dclarray(s[1],k)) < 0)
- goto fnend;
- vp = a_ptr[x]; /* Point to array we just declared */
- }
- /* debug(F111,"aaconvert array 2",abuf,vp); */
- makestr(&ap[0],ckitoa(k));
- if (vp) makestr(&vp[0],ckitoa(k));
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:ASSOCIATIVE_ARRAY:\\f",fn,"()>",NULL);
-
- /* Copy macro index & value to the arrays and then remove the */
- /* macro, so the 'first' pointer keeps indicating the next one. */
- /* We could combine the initial counting loop with this one but */
- /* then it would be harder to create the array and anyway this */
- /* function is plenty fast as it is. */
-
- for (i = 1; i <= k; ) {
- if (!ckmatch(pattern,mactab[first].kwd,0,1)) {
- debug(F111,"aaconvert oddball",mactab[first].kwd,first);
- first++;
- continue;
- }
- ckstrncpy(tmpbuf,mactab[first].kwd,TMPBUFSIZ); /* Macro name */
- s = tmpbuf; /* Make writeable copy */
- s += slen; /* Isolate "index" */
- j = strlen(s) - 1;
- if (*s != '<' || *(s+j) != '>') { /* Check syntax */
- /* This shouldn't happen */
- debug(F111,"aaconvert ERROR",mactab[first].kwd,first);
- goto fnend;
- }
- *(s+j) = NUL; /* Remove final '>' */
- debug(F111,"aaconvert",s+1,i);
- makestr(&(ap[i]),s+1); /* Set first array to index */
- if (vp)
- makestr(&(vp[i]),mactab[first].mval); /* 2nd to value */
- if (xdelmac(first) < 0)
- goto fnend;
- i++;
- }
- sprintf(fnval,"%d",k); /* SAFE */
- p = fnval; /* Return size of array */
- debug(F110,"aaconvert return",p,0);
- failed = 0; /* Unset failure flag */
- goto fnend;
- }
-
- } /* End of switch() */
-
-#ifdef FNFLOAT
-/*
- Floating-point functions. To be included only if FNFLOAT is defined, which
- should happen only if CKFLOAT is also defined, and if the math library is
- linked in. Even then, we might have float-vs-double confusion as well as
- confusion about what the final "%f" format effector is supposed to reference
- (32 bits, 64 bits, etc). Expect trouble if CKFLOAT does not match the data
- type of math library functions or args.
-*/
- if (cx == FN_FPABS || /* Floating-point functions */
- cx == FN_FPADD ||
- cx == FN_FPDIV ||
- cx == FN_FPEXP ||
- cx == FN_FPLOG ||
- cx == FN_FPLN ||
- cx == FN_FPMOD ||
- cx == FN_FPMAX ||
- cx == FN_FPMIN ||
- cx == FN_FPMUL ||
- cx == FN_FPPOW ||
- cx == FN_FPSQR ||
- cx == FN_FPINT ||
- cx == FN_FPSUB ||
- cx == FN_FPROU ||
- cx == FN_FPSIN ||
- cx == FN_FPCOS ||
- cx == FN_FPTAN) {
- CKFLOAT farg[2], fpresult = 0.0;
- char fpbuf[64], * bp0;
- double dummy;
- /* int sign = 0; */
- int i, j, places = 0;
- int argcount = 1;
-
- failed = 1;
- p = fnval;
- bp0 = bp[0];
- if (!bp0)
- bp0 = "0";
- else if (!*bp0)
- bp0 = "0";
- if (!isfloat(bp0,0)) {
- k = mxlook(mactab,bp0,nmac);
- bp0 = (k > -1) ? mactab[k].mval : NULL;
- if (bp0) {
- if (!isfloat(bp0,0)) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_FLOAT:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- }
- if (cx == FN_FPINT) { /* Float to int */
- failed = 0;
- ckstrncpy(fnval,bp0,FNVALL);
- for (i = 0; fnval[i]; i++) {
- if (fnval[i] == '.') {
- fnval[i] = NUL;
- break;
- }
- }
- goto fnend;
- }
- switch (y) { /* These need 2 args */
- case FN_FPADD:
- case FN_FPDIV:
- case FN_FPMOD:
- case FN_FPMAX:
- case FN_FPMIN:
- case FN_FPMUL:
- case FN_FPPOW:
- case FN_FPSUB:
- argcount = 2;
- }
- /* Missing arguments are supplied as 0.0 */
-
- debug(F111,fn,"argcount",argcount);
- for (i = 0; i < argcount; i++) { /* Get floating-point args */
-#ifdef DEBUG
- if (deblog) {
- ckmakmsg(fpbuf,
- 64,
- "bp[",
- ckitoa(i),
- bp[i] ? bp[i] : "(null)",
- "]"
- );
- debug(F100,fpbuf,"",0);
- }
-#endif /* DEBUG */
- if (!bp[i]) {
- farg[i] = 0.0;
- } else if (!*(bp[i])) {
- farg[i] = 0.0;
- } else if (!isfloat(bp[i],0)) {
- char * tmp;
- k = mxlook(mactab,bp[i],nmac);
- tmp = (k > -1) ? mactab[k].mval : NULL;
- if (tmp) {
- if (!isfloat(tmp,0)) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_FLOAT:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- }
- farg[i] = floatval;
-
-#ifdef DEBUG
- if (deblog) {
- sprintf(fpbuf,"farg[%d]=%f",i,farg[i]); /* SAFE */
- debug(F100,fpbuf,"",0);
- }
-#endif /* DEBUG */
- }
- if (bp[argcount]) { /* Get decimal places */
- char * s;
- s = bp[argcount];
- if (!s) s = "";
- if (!*s) s = "0";
- s = evalx(s);
- if (!s) s = "";
- if (!*s) {
- evalerr(fn);
- goto fnend;
- }
- places = atoi(s);
- }
- errno = 0;
- failed = 0;
- switch (y) { /* Now do the requested function */
- case FN_FPABS: /* Floating-point absolute value */
-#ifndef COMMENT
- fpresult = fabs(farg[0]);
-#else
- if (farg[0] < 0.0)
- fpresult = 0.0 - farg[0];
-#endif /* COMMENT */
- break;
- case FN_FPADD: /* FP add */
- fpresult = farg[0] + farg[1];
- break;
- case FN_FPDIV: /* FP divide */
- case FN_FPMOD: /* FP modulus */
- if (!farg[1]) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:DIVIDE_BY_ZERO:\\f",fn,"()>",NULL);
- } else
- fpresult = (cx == FN_FPDIV) ?
- (farg[0] / farg[1]) :
- fmod(farg[0],farg[1]);
- break;
- case FN_FPEXP: /* FP e to the x */
- fpresult = (CKFLOAT) exp(farg[0]);
- break;
- case FN_FPLOG: /* FP base-10 logarithm */
- case FN_FPLN: /* FP natural logarithm */
- if (farg[0] < 0.0) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- } else
- fpresult = (cx == FN_FPLOG) ? log10(farg[0]) : log(farg[0]);
- break;
- case FN_FPMUL: /* FP multiply */
- fpresult = farg[0] * farg[1];
- break;
- case FN_FPPOW: /* FP raise to a power */
- fpresult = modf(farg[1],&dummy);
- if ((!farg[0] && farg[1] <= 0.0) ||
- (farg[0] < 0.0 && fpresult)) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- } else
- fpresult = pow(farg[0],farg[1]);
- break;
- case FN_FPSQR: /* FP square root */
- if (farg[0] < 0.0) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- } else
- fpresult = sqrt(farg[0]);
- break;
- case FN_FPSUB: /* FP subtract */
- fpresult = farg[0] - farg[1];
- break;
- case FN_FPROU: /* FP round */
- fpresult = farg[0];
- break;
- case FN_FPSIN: /* FP sine */
- fpresult = (CKFLOAT) sin(farg[0]);
- break;
- case FN_FPCOS: /* FP cosine */
- fpresult = (CKFLOAT) cos(farg[0]);
- break;
- case FN_FPTAN: /* FP tangent */
- fpresult = (CKFLOAT) tan(farg[0]);
- break;
- case FN_FPMAX:
- fpresult = (farg[0] > farg[1]) ? farg[0] : farg[1];
- break;
- case FN_FPMIN:
- fpresult = (farg[0] < farg[1]) ? farg[0] : farg[1];
- break;
- }
-
- /* Get here with fpresult = function result */
-
- if (errno) { /* If range or domain error */
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:FLOATING-POINT-OP:\\f",fn,"()>",NULL);
- }
- if (failed) /* and/or any other kind of error, */
- goto fnend; /* fail. */
-#ifndef COMMENT
- /* Call routine containing code that was formerly inline */
- ckstrncpy(fnval,fpformat(fpresult,places,cx == FN_FPROU),FNVALL);
-#else
- {
- char fbuf[16]; /* For creating printf format */
- if (!fp_rounding && /* If printf doesn't round, */
- (places > 0 || /* round result to decimal places. */
- (places == 0 && cx == FN_FPROU)))
- fpresult += (0.5 / pow(10.0,(CKFLOAT)places));
- if (places > 0) { /* If places specified */
- /* use specified places to write given number of digits */
- sprintf(fbuf,"%%0.%df",places); /* SAFE */
- sprintf(fnval,fbuf,fpresult); /* SAFE */
- } else { /* Otherwise... */
-#ifdef COMMENT
-/*
- Here we want to print exactly fp_digits significant digits, no matter which
- side of the decimal point they are on. That is, we want want the default
- format to show the maximum number of non-garbage digits, AND we want the last
- such digit to be rounded. Of course there is no way to do that, since the
- digit after the last non-garbage digit is, well, garbage. So the following
- clever ruse does no good.
-*/
- int sign = 0, m = 0;
- sprintf(fnval,"%f",fpresult);
- if (fnval[0] == '-') sign = 1;
- for (i = sign; i < FNVALL; i++) {
- if (isdigit(fnval[i]))
- m++;
- else
- break;
- }
- if (m > 1) {
- int d = fp_digits - m;
- if (d < 1) d = 1;
- sprintf(fbuf,"%%%d.%df",fp_digits+sign+1,d);
- } else {
- sprintf(fbuf,"%%0.%df",fp_digits);
- }
- sprintf(fnval,fbuf,fpresult);
-#else
- /* Go for max precision */
- sprintf(fbuf,"%%0.%df",fp_digits); /* SAFE */
- sprintf(fnval,fbuf,fpresult); /* SAFE */
-
-#endif /* COMMENT */
- }
- if (fnval[0] == '-') sign = 1;
- }
- debug(F111,"fpresult 1",fnval,errno); /* Check for over/underflow */
- for (i = sign; fnval[i]; i++) { /* Give requested decimal places */
- if (fnval[i] == '.') /* First find the decimal point */
- break;
- else if (i > fp_digits + sign - 1) /* replacing garbage */
- fnval[i] = '0'; /* digits with 0... */
- }
- if (fnval[i] == '.') { /* Have decimal point */
- int gotend = 0;
- /* d < 0 so truncate fraction */
- if (places < 0 || (places == 0 && cx == FN_FPROU)) {
- fnval[i] = NUL;
- } else if (places > 0) { /* d > 0 so this many decimal places */
- i++; /* First digit after decimal */
- for (j = 0; j < places; j++) { /* Truncate after d decimal */
- if (!fnval[j+i]) /* places or extend to d */
- gotend = 1; /* decimal places. */
- if (gotend || j+i+sign > fp_digits)
- fnval[j+i] = '0';
- }
- fnval[j+i] = NUL;
- } else { /* d == 0 so Do The Right Thing */
- for (j = (int)strlen(fnval) - 1; j > i+1; j--) {
- if ((j - sign) > fp_digits)
- fnval[j] = '0';
- if (fnval[j] == '0')
- fnval[j] = NUL; /* Strip useless trailing 0's. */
- else
- break;
- }
- }
- }
-#endif /* COMMENT */
- debug(F111,"fpresult 2",fnval,errno);
- goto fnend;
-
- }
-#endif /* FNFLOAT */
-
-#ifdef CKCHANNELIO
- if (cx == FN_FSTAT || /* File functions */
- cx == FN_FPOS ||
- cx == FN_FEOF ||
- cx == FN_FGCHAR ||
- cx == FN_FGLINE ||
- cx == FN_FGBLK ||
- cx == FN_FPCHAR ||
- cx == FN_FPLINE ||
- cx == FN_FPBLK ||
- cx == FN_NLINE ||
- cx == FN_FERMSG ||
- cx == FN_FILNO) {
- int x = 0, t = 0, channel;
- long z;
- extern int z_maxchan;
-
- failed = 1; /* Assume failure */
- p = fnval; /* until we validate args */
- if (cx == FN_FERMSG) {
- extern int z_error;
- if (argn < 1) {
- x = z_error;
- } else if (chknum(bp[0])) {
- x = atoi(bp[0]);
- } else if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- failed = 0;
- ckstrncpy(fnval,ckferror(x),FNVALL);
- goto fnend;
- }
- if (argn < 1) { /* All file functions need channel */
- if (cx == FN_FSTAT) { /* Except f_status(), e.g. when */
- fnval[0] = '0'; /* called with a variable that */
- fnval[1] = NUL; /* hasn't been defined yet. */
- failed = 0;
- } else {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:MISSING_ARG:\\f",fn,"()>",NULL);
- }
- goto fnend;
- }
- if (rdigits(bp[0])) { /* Channel must be numeric */
- channel = atoi(bp[0]);
- } else { /* Fail if it isn't */
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- if (channel < 0 || channel > z_maxchan) { /* Check channel range */
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- x = z_getmode(channel); /* Find out about the channel */
-
- failed = 0; /* Assume success from here down */
- if (cx == FN_FSTAT) { /* Status / modes of channel */
- if (x > -1)
- x &= FM_RWB; /* Mask out irrelevant bits */
- else /* In this case not open is OK */
- x = 0; /* 0 if not open, 1-7 if open */
- sprintf(fnval,"%d",x); /* SAFE */
- goto fnend;
- } else if (x < 1) { /* Not \f_status() so must be open */
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:FILE_NOT_OPEN:\\f",fn,"()>",NULL);
- goto fnend;
- }
- switch (y) { /* Do the requested function */
- case FN_FPOS: /* Get position */
- z = z_getpos(channel); /* FIX THIS */
- sprintf(fnval,"%ld",z); /* SAFE */
- goto fnend;
-
- case FN_NLINE: /* Get line number */
- z = z_getline(channel); /* FIX THIS */
- sprintf(fnval,"%ld",z); /* SAFE */
- goto fnend;
-
- case FN_FEOF: /* Check EOF */
- t = 0;
- if (x & FM_EOF) t = 1;
- sprintf(fnval,"%d",t); /* SAFE */
- goto fnend;
-
- case FN_FILNO: /* Get file handle */
- x = z_getfnum(channel);
- sprintf(fnval,"%d",x); /* SAFE */
- goto fnend;
-
- case FN_FPBLK: /* Read or write block */
- case FN_FGBLK:
- if (argn < 2) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:MISSING_ARG:\\f",fn,"()>",NULL);
- goto fnend;
- }
- if (rdigits(bp[1])) {
- t = atoi(bp[1]);
- } else {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- case FN_FGCHAR: /* Read or write character or line */
- case FN_FPCHAR:
- case FN_FGLINE:
- case FN_FPLINE:
- fnval[0] = NUL;
- switch (y) {
- case FN_FGCHAR: t = z_in(channel,fnval,FNVALL,1,1); break;
- case FN_FGLINE: t = z_in(channel,fnval,FNVALL,FNVALL-1,0); break;
- case FN_FGBLK:
- if (t >= FNVALL) t = FNVALL - 1;
- t = z_in(channel,fnval,FNVALL,t,1);
- break;
- case FN_FPCHAR: t = z_out(channel,bp[1],1,1); break;
- case FN_FPLINE: t = z_out(channel,bp[1],-1,0); break;
- case FN_FPBLK: t = z_out(channel,bp[1],-1,1); break;
- }
- if (t < 0) { /* Handle read/write error */
- failed = 1;
- if (fndiags && t != FX_EOF)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:FILE_ERROR_%d:\\f",fn,"()>",NULL);
- goto fnend;
- }
- if (cx == FN_FGCHAR) /* Null terminate char */
- fnval[1] = NUL;
- /* Write (put) functions return numeric status code */
- if (cx == FN_FPCHAR || cx == FN_FPLINE || cx == FN_FPBLK)
- sprintf(fnval,"%d",t); /* SAFE */
- goto fnend;
- }
- }
-#endif /* CKCHANNELIO */
-
- if (cx == FN_SQUEEZE) { /* String function \fsqueeze() */
- /* Squeeze out whitespace */
- /* Add options later for whether to trim leading and trailing blanks */
- /* and what to do about control characters, 8-bit whitespace, etc */
- int started = 0; /* Flag for first non-whitespace */
- int n = 0; /* Blank/Tab counter */
- s = bp[0] ? bp[0] : "";
- p = fnval; /* Result buffer */
- while (*s) { /* While there is input */
- if (!started && (*s == ' ' || *s == '\011')) {
- s++; /* Skip past leading whitespace */
- continue;
- }
- started++; /* Leading whitespace was skipped */
- if (*s != ' ' && *s != '\011') { /* Have a nonspace char */
- n = 0; /* reset space counter */
- *p++ = *s++; /* copy char to destination */
- continue;
- }
- if (n++ > 0) { /* Have blank or tab */
- s++; /* don't copy more than one */
- continue;
- }
- *p++ = ' '; /* Deposit one space */
- s++; /* and go to next source char */
- }
- if (*(p-1) == ' ') p--; /* Remove trailing space */
- *p = NUL; /* Terminate string */
- p = fnval; /* point to beginning */
- goto fnend; /* Done. */
- }
- if (cx == FN_PATTERN) { /* \fpattern() for INPUT */
- itsapattern = 1;
- if (argn > 0) {
- p = fnval;
- ckstrncpy(fnval,bp[0],FNVALL);
- } else p = "";
- goto fnend;
- }
- if (cx == FN_HEX2N || cx == FN_OCT2N) { /* \fhex2n(), \foct2n() */
- p = "0";
- if (argn < 1)
- goto fnend;
- p = ckradix(bp[0], ((cx == FN_HEX2N) ? 16 : 8), 10);
- if (!p) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- failed = 0;
- ckstrncpy(fnval,p,FNVALL);
- p = fnval;
- goto fnend;
- }
-
- if (cx == FN_HEX2IP) {
- int c[2], ip[4], i, k;
- p = "0";
- if (argn < 1)
- goto fnend;
- s = bp[0];
- if ((int)strlen(s) != 8) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- p = fnval;
- for (k = 0; k < 8; k += 2) {
- for (i = 0; i < 2; i++) {
- c[i] = *s++;
- if (islower(c[i])) c[i] = toupper(c[i]);
- if (c[i] >= '0' && c[i] <= '9') {
- c[i] -= 0x30;
- } else if (c[i] >= 'A' && c[i] <= 'F') {
- c[i] -= 0x37;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- ip[k/2] = c[0] << 4 | c[1];
- }
- sprintf(p,"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]); /* SAFE */
- }
- goto fnend;
- }
- if (cx == FN_IP2HEX) {
- int ip[4], i;
- char * q;
- p = "00000000";
- if (argn < 1)
- goto fnend;
- s = bp[0];
- p = fnval;
- for (i = 0; i < 3; i++) {
- q = ckstrchr(s,'.');
- if (q) {
- *q++ = NUL;
- ip[i] = atoi(s);
- s = q;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- ip[3] = atoi(s);
- sprintf(p,"%02x%02x%02x%02x",ip[0],ip[1],ip[2],ip[3]); /* SAFE */
- goto fnend;
- }
- if (cx == FN_RADIX) {
- failed = 1;
- p = fnval;
- if (argn < 3) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:MISSING_ARG:\\f",fn,"()>",NULL);
- goto fnend;
- }
- if (!rdigits(bp[1]) || !rdigits(bp[2])) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- p = ckradix(bp[0],atoi(bp[1]),atoi(bp[2]));
- if (!p) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- failed = 0;
- ckstrncpy(fnval,p,FNVALL);
- p = fnval;
- goto fnend;
- }
- if (cx == FN_JOIN) {
- int i, x, y, z, flag, flag2, hi, lo, max, seplen, grouping = 0;
- char abuf[16], c, *s, *q, *sep = NULL;
- char * gr_opn = "\"{'([<"; /* Group open brackets */
- char * gr_cls = "\"}')]>"; /* Group close brackets */
- char lb[2], rb[2]; /* Selected left and right brackets */
- int csv = 0, tsv = 0; /* Function flags */
- char specialchar = 0; /* Field char that triggers grouping */
- char *s2 = NULL; /* Address of malloc'd storage */
-
- failed = 1; /* Assume failure */
- fnval[0] = NUL;
- debug(F101,"FNJOIN ARGN","",argn);
-
- ckstrncpy(abuf,bp[0],16); /* Get array reference */
- s = abuf;
- if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Get index and bounds */
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:ARG_BAD_ARRAY:\\f",fn,"()>",NULL);
- goto fnend;
- }
- p = fnval; /* Point to result */
- max = a_dim[x]; /* Size of array */
- if (lo < 0) lo = 1; /* Use given range if any */
- if (lo > max) lo = max;
-#ifdef COMMENT
- hi = max;
-#else
-/*
- This is a workaround for the problem in which the dimension of the \&_[]
- array (but not its contents) grows upon entry to a SWITCH block. But this
- code prevents the dimension from growing. Go figure.
-*/
- if (hi < 0) { /* Bounds not given */
- if (x) /* Regular array */
- hi = max;
- else /* Argument vector array */
- for (hi = max; hi >= lo; hi--) { /* ignore any trailing */
- if (!a_ptr[x][hi]) continue; /* empty elements */
- if (!*(a_ptr[x][hi])) continue;
- break;
- }
- }
-#endif /* COMMENT */
- if (hi > max) hi = max;
- failed = 0; /* Unset failure flag */
- if (max < 1)
- goto fnend;
- sep = " "; /* Separator */
- lb[0] = NUL; /* Group start char (as string) */
- rb[0] = NUL;
- lb[1] = NUL; /* Group end char as string */
- rb[1] = NUL;
-
- if (argn > 1) {
- if (bp[1]) if (*bp[1]) { /* If arg1 given and not empty */
- if (!strcmp(bp[1],"CSV")) { /* Special "CSV" symbolic arg */
- csv++; /* Make a comma separated list */
- sep = ","; /* Comma */
- specialchar = *sep; /* Separator is special character */
- grouping = 1; /* Group with doublequotes */
- lb[0] = '"'; /* and here */
- rb[0] = '"'; /* they are */
- } else if (!strcmp(bp[1],"TSV")) { /* "TSV" symbolic arg */
- tsv++; /* Make a Tab separated list */
- sep = "\011"; /* Tab */
- specialchar = *sep;
- grouping = 0; /* No grouping */
- } else /* Normal case */
- sep = bp[1]; /* use the separator char specified */
- }
- }
- if (argn > 2 && !csv && !tsv) { /* Grouping? */
- char * bp2 = bp[2];
- if (!bp2) bp2 = "0";
- if (!*bp2) bp2 = "0";
- if (chknum(bp2)) {
- grouping = atoi(bp2);
- if (grouping < 0 || grouping > 63)
- grouping = 1;
- } else {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- if (grouping) { /* Take lowest-order one */
- int j, k; /* and set the others to 0 */
- for (k = 0; k < 6; k++) {
- j = 1 << k;
- if (grouping & j) {
- lb[0] = gr_opn[k];
- rb[0] = gr_cls[k];
- break;
- }
- }
- }
- }
- if (!csv && !tsv) { /* Normal case, not CSV or TSV */
- specialchar = SP; /* Special character is space */
- if (argn > 3) /* Nonzero 4th arg for no separator */
- if (chknum(bp[3]))
- if (atoi(bp[3]) > 0)
- sep = NULL;
- if (!sep) {
- sep = "";
- seplen = 0;
- } else
- seplen = strlen(sep);
- }
- for (i = lo; i <= hi; i++) { /* Loop thru selected array elements */
- s = a_ptr[x][i]; /* Get next element */
- if (!s)
- s = "";
- flag = 0; /* Flag to indicate grouping needed */
- flag2 = 0; /* Flag for internal doublequotes */
- if (grouping) { /* Does this element need quoting? */
- q = s; /* Look for special character */
- while ((c = *q++)) { /* If found */
- if (c == specialchar) /* grouping is required */
- flag++;
- if (csv && (c == '"')) /* Character that needs doubling */
- flag2++; /* in comma-separated list */
- if (flag && !csv) /* Exit early if no more to do */
- break;
- }
- }
- y = strlen(s); /* Get length of this element */
- if ((y > 0) && csv && !flag) { /* CSV item needs grouping */
- if (s[0] == SP || s[y-1] == SP || /* if it has leading */
- s[0] == HT || s[y-1] == HT) /* or trailing whitespace */
- flag++; /* then it needs grouping */
- }
- if (flag || flag2) { /* String needs grouping or quoting */
- char *ss = s;
- q = (char *)malloc(y + flag2 + 3); /* Make new buffer */
- if (q) {
- s2 = q; /* and this is what to free */
- if (flag) /* If grouping */
- *q++ = lb[0]; /* put opening group quote */
- while (*ss) { /* Loop through string */
- if (flag2 && (*ss == '"')) /* If CSV and this a '"' */
- *q++ = *ss; /* double it. */
- *q++ = *ss++; /* Copy the character */
- }
- if (flag) /* If grouping */
- *q++ = rb[0]; /* add closing group quote */
- *q = NUL; /* terminate the result. */
- s = s2;
- y = strlen(s);
- }
- }
- z = 0; /* Number of chars copied */
- flag = 0; /* flag is now buffer-overrun flag */
- if (y > 0) /* If this string is not empty */
- z = ckstrncat(fnval,s,FNVALL); /* copy it. */
- if (s2) free(s2); /* Free temp storage */
- if (z < y) /* Now check for buffer overrun. */
- flag++;
- if (!flag && *sep && i < hi) { /* If buffer still has room */
- z = ckstrncat(fnval,sep,FNVALL); /* copy delimiter */
- if (z < seplen)
- flag++;
- }
- if (flag) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:RESULT_TOO_LONG:\\f",fn,"()>",NULL);
- goto fnend;
- }
- }
- isjoin = 1;
- goto fnend;
- }
- if (cx == FN_SUBST) { /* \fsubstitute() */
- CHAR c, * s, * r, * tp[2], buf1[256], buf2[256], buf3[256];
- int len, i, j, state = 0, lo = 0, hi = 0;
-
- failed = 0;
- p = fnval; /* Result pointer */
- *p = NUL;
- if (!bp[0]) /* No target, no result*/
- goto fnend;
-
- len = strlen(bp[0]); /* Length of source */
- if (len == 0)
- goto fnend;
- if (len > FNVALL) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:RESULT_TOO_LONG:\\f",fn,"()>",NULL);
- goto fnend;
- }
- if (!bp[1]) {
- ckstrncpy(bp[0],fnval,FNVALL);
- goto fnend;
- }
- tp[0] = buf1; /* For s2-s3 interpretation loop */
- tp[1] = buf2;
-
- for (i = 0; i < 256; i++) { /* Initialize working buffers */
- buf1[i] = 0; /* s2 expansion buffer */
- buf2[i] = 0; /* s3 expansion buffer */
- buf3[i] = i; /* Translation table */
- }
- for (i = 0; i < 2; i++) { /* Interpret s2 and s3 */
- s = (CHAR *)bp[i+1]; /* Arg pointer */
- if (!s) s = (CHAR *)"";
- r = tp[i]; /* To construct interpreted arg */
- j = 0; /* Output buf pointer */
- state = 0; /* Initial state */
- while (c = *s++) { /* Loop thru arg chars */
- if (j > 255) /* Output buf full */
- break;
- switch (state) {
- case 0: /* Normal state */
- switch (c) {
- case '\\': /* Have quote */
- state = 1;
- break;
- case '[': /* Have range starter */
- state = 2;
- break;
- default: /* Anything else */
- r[j++] = c;
- break;
- }
- continue;
- case 1: /* Quoted char */
- r[j++] = c;
- state = 0;
- continue;
- case 2: /* Range bottom */
- lo = c;
- state++;
- continue;
- case 3: /* Range separater */
- if (c != '-') {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:BAD_RANGE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- state++;
- continue;
- case 4: /* Range top */
- hi = c;
- state++;
- continue;
- case 5: /* Range end */
- if (c != ']') {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:BAD_RANGE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- for (k = lo; k <= hi && j < 255; k++) /* Fill in */
- r[j++] = k;
- lo = 0; hi = 0; /* Reset */
- state = 0;
- continue;
- }
- }
- }
- for (i = 0; i < 256 && buf1[i]; i++) { /* Create translation table */
- k = (unsigned)buf1[i];
- buf3[k] = buf2[i];
- }
- s = (CHAR *)bp[0]; /* Point to source string */
- for (i = 0; i < len; i++) { /* Translation loop */
- k = (unsigned)s[i]; /* Get next char */
- if (!buf3[k]) /* Remove this char */
- continue;
- *p++ = buf3[k]; /* Substitute this char */
- }
- *p = NUL;
- p = fnval;
- goto fnend;
- }
-
-#ifndef NOSEXP
- if (cx == FN_SEXP) { /* \fsexpression(arg1) */
- char * p2;
- fsexpflag++;
- p = (argn > 0) ? dosexp(bp[0]) : "";
- fsexpflag--;
- p2 = fnval;
- while ((*p2++ = *p++)) ;
- p = fnval;
- goto fnend;
- }
-#endif /* NOSEXP */
-
- if (cx == FN_CMDSTK) { /* \fcmdstack(n1,n2) */
- int i, j, k;
- char * s;
-
- if (bp[0])
- val1 = *(bp[0]) ? evalx(bp[0]) : ckitoa(cmdlvl);
- else
- val1 = ckitoa(cmdlvl);
-#ifdef COMMENT
- free(bp[0]); /* (evalx() always uses same buffer) */
- bp[0] = NULL; /* (not any more!) */
-#endif /* COMMENT */
- failed = 1;
- if (argn > 1) {
-#ifdef COMMENT
- makestr(&(bp[0]),val1);
- val1 = bp[0];
-#endif /* COMMENT */
- val2 = *(bp[1]) ? evalx(bp[1]) : "0";
- if (!(chknum(val1) && chknum(val2))) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- goto fnend;
- }
- } else {
- val1 = ckitoa(cmdlvl);
- val2 = "0";
- }
- i = atoi(val1); /* Level */
- j = atoi(val2); /* Flags */
- if (i < 0 || i > cmdlvl) {
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_OUT_OF_RANGE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- failed = 0;
- p = fnval;
- k = cmdstk[i].src; /* What (prompt, file, macro) */
- if (j) {
- ckstrncpy(fnval,ckitoa(k),FNVALL);
- goto fnend;
- }
- switch (k) {
- case CMD_KB:
- ckstrncpy(fnval,"(prompt)",FNVALL);
- break;
- case CMD_TF:
- s = tfnam[cmdstk[i].lvl];
- if (!zfnqfp(s,FNVALL,fnval))
- ckstrncpy(fnval,s,FNVALL);
- break;
- case CMD_MD:
- ckstrncpy(fnval,m_arg[cmdstk[i].lvl][0],FNVALL);
- break;
- }
- goto fnend;
- }
-#ifdef CKFLOAT
- if (cx == FN_DIFDATE) { /* \fdiffdates(d1,d2) */
- char * d1, * d2;
- d1 = bp[0] ? bp[0] : ckdate();
- d2 = bp[1] ? bp[1] : ckdate();
- p = (char *)cmdiffdate(d1,d2);
- if (!p) {
- failed = 1;
- if (fndiags) {
- ckmakmsg(fnval,FNVALL,"<ERROR:BAD_DATE:\\f",fn,"()>",NULL);
- p = fnval;
- }
- }
- goto fnend;
- }
-#endif /* CKFLOAT */
- if (cx == FN_CMPDATE) { /* \fcmddates(d1,d2) */
- int x = 0;
- char d1[18], d2[18], * dp;
- failed = 0;
- d1[0] = NUL;
- d2[0] = NUL;
- p = fnval;
- dp = cmcvtdate(bp[0],1);
- if (dp) {
- ckstrncpy(d1,dp,18);
- if ((dp = cmcvtdate(bp[1],1))) {
- ckstrncpy(d2,dp,18);
- x = 1;
- }
- }
- if (x == 0) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:BAD_DATE:\\f",fn,"()>",NULL);
- } else {
- x = strcmp(d1,d2);
- if (x > 0)
- x = 1;
- else if (x < 0)
- x = -1;
- sprintf(fnval,"%d",x);
- }
- goto fnend;
- }
- if (cx == FN_TOGMT) { /* \futcdate(d1) */
- char * d1, * dp;
- char datebuf[32];
- char d2[32];
- p = fnval;
- failed = 1;
- if ((dp = cmcvtdate(bp[0],1))) { /* The given date */
- ckstrncpy(datebuf,dp,18);
- ckstrncpy(d2,dp,18); /* local time */
- ckstrncat(datebuf,"Z",19); /* Same time GMT */
- if ((dp = cmcvtdate(datebuf,1))) /* converted to local time */
- ckstrncpy(datebuf,dp,18);
- if ((p = (char *)cmdiffdate(d2,datebuf))) { /* Get offset */
- ckstrncat(d2,p,32); /* Append offset to local time */
- if ((dp = cmcvtdate(d2,1))) {
- failed = 0;
- ckstrncpy(fnval,dp,FNVALL);
- p = fnval;
- }
- }
- }
- if (failed && fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:BAD_DATE:\\f",fn,"()>",NULL);
- goto fnend;
- }
- if (cx == FN_DELSEC) { /* \fdelta2secs(delta-time) */
- long secs;
- p = fnval;
- if ((x = delta2sec(bp[0],&secs)) < 0) {
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,
- (x == -1) ?
- "<ERROR:BAD_DELTA_TIME:\\f" :
- "<ERROR:OVERFLOW:\\f",
- fn,
- "()>",
- NULL
- );
- goto fnend;
- }
- sprintf(p,"%ld",secs);
- goto fnend;
- }
- if (cx == FN_PC_DU) {
- char c, * s = bp[0];
- if (!s) s = "";
- p = fnval;
- while ((c = *s++)) {
- if (c == ':') {
- if (*s != '\\')
- *p++ = '/';
- } else if (c == '\\') {
- *p++ = '/';
- } else {
- *p++ = c;
- }
- }
- *p = NUL;
- p = fnval;
- goto fnend;
- }
- if (cx == FN_PC_UD) { /* Unix to DOS path */
- char c, * s = bp[0];
- if (!s) s = "";
- if (*s == '~') { /* Skip leading tilde */
- s++;
- if (*s == '/')
- s++;
- }
- p = fnval;
- while ((c = *s++))
- *p ++ = (c == '/') ? '\\' : c;
- *p = NUL;
- p = fnval;
- goto fnend;
- }
- if (cx == FN_KWVAL) { /* Keyword=Value */
- p = dokwval(bp[0],bp[1]?bp[1]:"=");
- goto fnend;
- }
-#ifdef COMMENT
-/* Cute idea but doesn't work */
- if (cx == FN_SLEEP || cx == FN_MSLEEP) {
- p = "";
- if (chknum(bp[0])) {
- x = atoi(bp[0]);
- } else {
- failed = 1;
- if (fndiags) {
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_NOT_NUMERIC:\\f",fn,"()>",NULL);
- p = fnval;
- }
- goto fnend;
- }
- if (cx == FN_SLEEP)
- x *= 1000;
- msleep(x);
- goto fnend;
- }
-#endif /* COMMENT */
-
-#ifdef NT
- if (cx == FN_SNAME) {
- GetShortPathName(bp[0],fnval,FNVALL);
- goto fnend;
- }
- if (cx == FN_LNAME) {
- ckGetLongPathName(bp[0],fnval,FNVALL);
- goto fnend;
- }
-#endif /* NT */
-
-/*
- \femailaddress():
- Picks the email address out of an RFC 2822 From: or Sender: header.
- Added 26 Nov 2005. Handles all common, and some uncommon, cases but
- doesn't totally bother about nested comments. Needed this for fetching
- email from a POP server and then constructing the BSD "From " line.
- Works with or without the "From: " or "Sender: " tag.
-*/
- if (cx == FN_EMAIL) {
- char c, * s = bp[0], * s2, * s3, * ap = "";
- int k, state = 0, quote = 0, infield = 0;
- int pc = 0; /* For nested comments */
- if (!s) s = "";
- if (!*s) goto xemail;
-
- if (ckindex("From: ",s,0,0,0) == 1) s += 5;
- if (ckindex("Sender: ",s,0,0,0) == 1) s += 7;
-
- k = strlen(s); /* Strip junk from end */
- if (k < 1) goto xemail;
- k--;
- while (k >= 0 && s[k] == CR || s[k] == LF)
- s[k--] = NUL;
- while (k >= 0 && s[k] == SP || s[k] == HT)
- s[k--] = NUL;
- if (k == 0)
- goto xemail;
-
-#ifndef COMMENT /* Simple method if not 100% foolproof */
- k = 0;
- for (s2 = s; *s2; s2++) { /* Find at-sign */
- if (*s2 == '@') {
- k++; /* If more than one use rightmost */
- s3 = s2;
- }
- }
- if (k < 1) /* No at-sign */
- goto xemail;
-
- for (ap = s3-1; ap >= s; ap--) { /* Back up to beginning of address */
- if (isspace(*ap) || *ap == '<') {
- ap++;
- break;
- }
- if (ap == s)
- break;
- }
- for (s2 = s3+1; *s2; s2++) { /* Find end of address */
- if (isspace(*s2) || *s2 == '>')
- break;
- }
- *s2-- = NUL;
- if (*ap == '[' && *s2 == ']') { /* Handle [blah@blah.blah] */
- ap++;
- *s2 = NUL;
- }
- if (!ckstrcmp(ap,"mailto:",7,0)) /* Handle mailto: URLs */
- ap += 7;
-
-#else /* Too complicated and error-prone */
-
- k = 0;
- for (s2 = s; *s2; s2++) { /* Strip leading whitespace */
- if (*s2 == SP || *s2 == HT) {
- k = 1;
- break;
- }
- }
- if (!k) { /* Simple address */
- ap = s;
- goto xemail;
- }
- do { /* Not simple, have to extract it */
- if (quote) {
- quote = 0;
- continue;
- } else if (*s == '\\') {
- quote = 1;
- continue;
- }
- switch (state) {
- case 0:
- if (!infield && *s == '"') { /* Quoted string */
- infield = 1;
- c = '"';
- state = 1;
- } else if (!infield && *s == '(') { /* Comment in parens */
- pc++;
- infield = 1;
- c = ')';
- if (*ap) *s = NUL;
- state = 1;
- } else if (!infield && *s == '<') { /* Address */
- infield = 1;
- c = '>';
- ap = s+1;
- state = 2;
- } else if (infield && (*s == SP || *s == HT)) {
- infield = 0;
- } else { /* One or more bare words */
- infield = 1; /* Could be an address */
- if (!*ap) ap = s; /* Could be comments */
- }
- continue;
- case 1: /* In Quoted string or Comment */
- if (infield && *s == c) { /* Look for end */
- infield = 0;
- *s++ = NUL;
- while (*s == SP || *s == HT) s++;
- if (!*ap)
- ap = s;
- state = 0;
- }
- continue;
- case 2: /* In address */
- if (infield && *s == c) { /* Looking for end */
- infield = 0;
- *s = NUL;
- break;
- }
- }
- } while (*s++);
-
- xemail:
- if (*ap) {
- while (*ap == SP || *ap == HT) ap++;
- }
- k = strlen(ap) - 1;
- while (k >= 0 && (ap[k] == SP || ap[k] == HT))
- ap[k--] = NUL;
- if (*ap) {
- failed = 0;
- if (*ap == '<') {
- k = strlen(ap);
- if (*(ap+k-1) == '>') {
- ap[k-1] = NUL;
- ap++;
- }
- }
- } else
- failed = 1;
- /* Here we might also want check against "*@*.*" */
-#endif /* COMMENt */
- xemail:
- ckstrncpy(fnval,ap,FNVALL);
- goto fnend;
- }
-
-#ifdef SEEK_CUR
-/*
- \fpicture(): Get dimensions of GIF or JPG image.
- fdc June 2006
-*/
- if (cx == FN_PICTURE) {
- FILE *fp = NULL;
- int c, x, w = 0, h = 0, eof = 0;
- unsigned int i, j, k;
- unsigned char buf[1024];
- char abuf[16], * p, * s;
- char ** ap = NULL;
-
- p = fnval; /* Point to result */
- failed = 1; /* Assume failure */
- if (argn > 1) {
- int xi;
- ckstrncpy(abuf,bp[1],16); /* Get array reference */
- s = abuf;
- if (*s == CMDQ) s++;
- if (fndiags) /* Default is this error message */
- ckmakmsg(fnval,FNVALL,
- "<ERROR:ARG_BAD_ARRAY:\\f",fn,"()>",NULL);
- if (s[0] != '&') /* "Address" of array */
- goto fnend;
- if (s[2])
- if (s[2] != '[' || s[3] != ']')
- goto fnend;
- if (s[1] >= 64 && s[1] < 91) /* Convert upper to lower */
- s[1] += 32;
- if ((xi = dclarray(s[1],2)) < 0) /* Two elements */
- goto fnend;
- ap = a_ptr[xi]; /* Point to array we just declared */
- }
- s = bp[0]; /* Filename */
- failed = 0; /* From here on we don't fail */
- p[0] = '0'; /* Default return value */
- p[1] = NUL;
- if (!ckmatch("*.{jpg,jpeg,gif}$",s,0,1+4)) /* Appropriate name? */
- goto fnend; /* No, fail */
- fp = fopen(s, "r"); /* Open it */
- if (fp == NULL) { /* Can't, fail */
- p[0] = '-';
- p[1] = '1';
- p[2] = NUL; /* Return -1 */
- goto fnend;
- }
- k = strlen(s);
- if (!ckstrcmp(&s[k-4],".gif",4,0)) { /* GIF file */
- if (fread(buf,1,10,fp) != 10) {
- fclose(fp);
- goto fnend;
- }
- /* Check signature */
- if (ckstrcmp((char *)buf,"GIF87a",6,0) &&
- ckstrcmp((char *)buf,"GIF89a",6,0)) {
- fclose(fp);
- goto fnend;
- }
- w = buf[6] + 256 * buf[7];
- h = buf[8] + 256 * buf[9];
- goto picend;
- } else if (!ckstrcmp(&s[k-4],".jpg",4,0) || /* JPEG file */
- !ckstrcmp(&s[k-5],".jpeg",5,0)) {
- if (fread(buf,1,2,fp) != 2) {
- fclose(fp);
- goto fnend;
- }
- if (buf[0] != 0xff || buf[1] != 0xd8) { /* Check signature */
- fclose(fp);
- goto fnend;
- }
- eof = 0;
- while (!eof) { /* Loop for each marker */
- while (!eof) { /* Find next marker */
- c = getc(fp);
- if (c == (unsigned int)EOF) {
- eof++;
- break;
- }
- if (c == 0xff) {
- buf[0] = c;
- c = getc(fp);
- if (c == (unsigned int)EOF) {
- eof++;
- break;
- }
- buf[1] = c;
- if (c == 0xd9)
- eof++;
- if (c >= 0xc0 && c <= 0xfe)
- break;
- }
- }
- if (eof) break;
- x = buf[1];
- if (x == 0xc0 || x == 0xc1 || x == 0xc2 || x == 0xc3 ||
- x == 0xc9 || x == 0xca || x == 0xcb) {
- if (fread(buf,1,7,fp) != 7) {
- fclose(fp);
- goto fnend;
- }
- h = buf[3] * 256 + buf[4];
- w = buf[5] * 256 + buf[6];
- goto picend;
- } else { /* Not a desired field */
- if (feof(fp)) {
- eof++;
- break;
- }
- if (fread(buf,1,2,fp) != 2) { /* Length of this field */
- fclose(fp);
- goto fnend;
- }
- j = 256 * buf[0] + buf[1] - 2; /* Skip next field */
- if (CKFSEEK(fp,(CK_OFF_T)j,SEEK_CUR) != 0) {
- fclose(fp);
- goto fnend;
- }
- }
- }
- }
- picend:
- fclose(fp);
- if (ap) {
- makestr(&(ap[0]),"2");
- makestr(&(ap[1]),ckitoa(w));
- makestr(&(ap[2]),ckitoa(h));
- }
- if (w > 0 && h > 0) {
- if (w > h) p[0] = '1';
- if (h >= w) p[0] = '2';
- }
- goto fnend;
- }
-#endif /* SEEK_CUR */
-
- if (cx == FN_PID) {
- int x = -1;
- if (chknum(bp[0])) { /* Need numeric argument */
- int pid;
- pid = atoi(bp[0]); /* Convert to int */
-#ifdef UNIX
- if (kill(pid,0) < 0) { /* Test it */
- if (errno ==
-#ifdef ESRCH
- ESRCH /* No such process */
-#else
- 3
-#endif /* ESRCH */
- )
- x = 0;
- } else /* Process exists */
- x = 1;
-#endif /* UNIX */
- }
- sprintf(fnval,"%d",x); /* SAFE */
- goto fnend;
- }
-
- if (cx == FN_FUNC) {
- char * s = bp[0];
- p = "0";
- debug(F111,"ffunc",s,argn);
- if (argn > 0) {
- int x, y;
- for (p = s; *p; p++) { /* Chop off trailing parens if any */
- if (*p == '(') {
- *p = NUL;
- break;
- }
- }
- /* Chop off leading "\\f" or "\f" or "f" */
- p = s;
- if (*p == CMDQ) /* Allow for \\f... */
- p++;
- if (*p == CMDQ && (*(p+1) == 'f' || *(p+1) == 'F')) { /* or \f */
- p += 2;
- } else if (*p == 'f' || *p == 'F') { /* or just f */
- p++;
- }
- y = lookup(fnctab,p,nfuncs,&x); /* Look up the result */
- debug(F111,"ffunc",p,y);
- p = (y > -1) ? "1" : "0";
- }
- goto fnend;
- }
- if (cx == FN_RECURSE) {
- int t, n;
- char * s;
- fnval[0] = NUL; /* Default result is empty string */
- s = bp[0]; /* Check for null argument */
- if (!s) s = ""; /* or empty argument */
- if (!*s) goto fnend; /* in which case return empty string */
- n = FNVALL; /* Not empty, max size for result */
- s = fnval; /* Location of result */
- {
- /* Force VARIABLE-EVALUATION SIMPLE RECURSIVE */
- /* NOTE: This is vulnerable to SIGINT and whatnot... */
- int tmp = vareval; /* Save VARIABLE-EVALUATION setting */
- vareval = 1; /* Force it to RECURSIVE */
- zzstring(bp[0],&s,&n); /* Expand arg into result space */
- vareval = tmp; /* Restore VARIABLE-EVALUATION */
- }
- goto fnend;
- }
-
- if (cx == FN_XLATE) { /* f_cvtcset() */
-#ifdef NOFRILLS
- ckstrncpy(fnval,bp[0],FNVALL);
-#else
-#ifndef NOUNICODE
- _PROTOTYP( char * cvtstring, (char *, int, int) );
- char * string, * cset1, * cset2;
- int id1, id2;
-#endif /* NOUNICODE */
- fnval[0] = NUL;
-#ifdef NOUNICODE
- ckstrncpy(fnval,bp[0],FNVALL);
-#else
- string = bp[0] ? bp[0] : ""; /* String to convert */
- if (!*string) goto fnend; /* It's empty */
-
- cset1 = bp[1] ? bp[1] : "ascii"; /* Current charset of string */
- cset2 = bp[2] ? bp[2] : "ascii"; /* Charset to convert to */
-
- id1 = lookup(fcstab,cset1,nfilc,NULL); /* Lookup 'from' set */
- if (id1 < 0) {
- failed = 1;
- ckmakmsg(fnval,FNVALL,"<ERROR:UNKNOWN_CHARSET:\\f",fn,"()>",NULL);
- goto fnend;
- }
- id2 = lookup(fcstab,cset2,nfilc,NULL); /* Lookup 'to' set */
- if (id2 < 0) {
- failed = 1;
- ckmakmsg(fnval,FNVALL,"<ERROR:UNKNOWN_CHARSET:\\f",fn,"()>",NULL);
- goto fnend;
- }
- string = cvtstring(string,id1,id2);
- ckstrncpy(fnval,string,FNVALL);
-#endif /* NOUNICODE */
-#endif /* NOFRILLS */
- goto fnend;
- }
-
-/* Decode strings containing hex escapes */
-
- if (cx == FN_UNPCT) { /* \fdecodehex() */
- char *s1, *s2;
- char *prefix; /* Can be 1 or 2 chars */
- char buf[3];
- int n = 0, k;
-
- p = fnval;
- *p = NUL;
- if (argn < 1) goto fnend; /* Empty string */
-
- s1 = bp[0] ? bp[0] : ""; /* Original string */
- prefix = bp[1] ? bp[1] : "%%"; /* Hex byte prefix */
- n = (int)strlen(prefix); /* Length of prefix */
- if (n < 1 || n > 2) { /* must be 1 or 2 */
- ckmakmsg(fnval,FNVALL,
- "<ERROR:INVALID_HEX_PREFIX:\\f",fn,"()>",NULL);
- goto xunpct;
- }
- while (*s1) {
- if (!ckstrcmp(s1,prefix,n,0)) { /* Case-independent */
- if (!*(s1+n)) {
- ckmakmsg(fnval,FNVALL,
- "<ERROR:INCOMPLETE_SEQUENCE:\\f",fn,"()>",NULL);
- goto xunpct;
- }
- buf[0] = *(s1+n); /* First hex character */
- buf[1] = *(s1+n+1); /* Second hex character */
- buf[2] = NUL;
- if ((k = ckhexbytetoint((char *)buf)) > -1) {
- *p++ = (char) k; /* Deposit decoded result */
- s1 += 2+n; /* and advance the source pointer */
- } else { /* Fail on conversion error */
- ckmakmsg(fnval,FNVALL,
- "<ERROR:NON_HEX_CHARS:\\f",fn,"()>",NULL);
- goto xunpct;
- }
- } else { /* Not a hex escape sequence */
- *p++ = *s1++; /* Just copy the character */
- }
- }
- *p = NUL; /* Terminate the result string */
- failed = 0; /* Say we didn't fail */
- p = fnval; /* Set up result pointer */
- goto fnend; /* and finish */
-
- xunpct: /* Error exit */
- p = fnval;
- failed = 1;
- goto fnend;
- }
-
-/* Check a string for encoding family */
-
- if (cx == FN_STRINGT) { /* \fstringtype() */
- p = "UNK";
- switch (scanstring(bp[0])) {
- case FT_7BIT: p = "7BIT"; break;
- case FT_8BIT: p = "8BIT"; break;
- case FT_UTF8: p = "UTF8"; break;
- case FT_UCS2: p = "UCS2"; break;
- case FT_TEXT: p = "TEXT"; break;
- case FT_BIN: p = "BINARY"; break;
- }
- ckstrncpy(fnval,p,FNVALL);
- p = fnval;
- goto fnend;
- }
-
-/* String compare s1, s2, [ case ], [ start ] , [ len ] */
-
- if (cx == FN_STRCMP) {
- int docase = 0; /* Case matters or not */
- int start = 0; /* Start of substring */
- int len = -1; /* Length of substring to compare */
- int x; char * s1, * s2; /* workers */
-
- p = "0"; /* Return value */
- if (argn == 0) { /* Two null strings are equal */
- ckstrncpy(fnval,p,FNVALL);
- p = fnval;
- goto fnend;
- }
- if (argn == 1) { /* Non-null string > null string */
- p = "1";
- ckstrncpy(fnval,p,FNVALL);
- p = fnval;
- goto fnend;
- }
- if (argn > 2) {
- s = *(bp[2]) ? evalx(bp[2]) : "0"; /* 0 = caseless */
- if (chknum(s)) docase = atoi(s);
- if (argn > 3) {
- s = *(bp[3]) ? evalx(bp[3]) : "1"; /* start is 1-based */
- if (chknum(s)) start = atoi(s);
- if (argn > 4) {
- s = *(bp[4]) ? evalx(bp[4]) : "-1"; /* -1 = whole thing */
- if (chknum(s)) len = atoi(s);
- }
- }
- }
- if (start > 0) start--; /* start is 0-based internally */
- s1 = bp[0]; /* Get length of first arg */
- x = (int)strlen(s1);
- if (x > start) /* Point to start position of s1 */
- s1 += start;
- else
- s1 = "";
- s2 = bp[1]; /* Get length of second arg */
- x = (int)strlen(s2);
- if (x > start) /* Point to start position of s2 */
- s2 += start;
- else
- s2 = "";
- x = ckstrcmp(s,s2,len,docase);
- p = ckitoa(x);
- ckstrncpy(fnval,p,FNVALL);
- p = fnval;
- goto fnend;
- }
-
-/* Note: when adding new functions remember to update dohfunc in ckuus2.c. */
-
- failed = 1;
- if (fndiags)
- ckmakmsg(fnval,FNVALL,"<ERROR:UNKNOWN_FUNCTION:\\f",fn,"()>",NULL);
-
- fnend:
- /* Free temporary storage for aguments */
- for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]);
- fndepth--;
- if (failed) { /* Handle failure */
- debug(F111,"fnend",fnval,errno);
- if (!p) p = "";
- if (p[0]) {
- /* In case this wasn't caught above... */
- k = strlen(p);
- if (p[0] != '<' && p[k-1] != '>') {
- ckmakmsg(fnval,FNVALL,"<ERROR:BAD_ARG:\\f",fn,"()>",NULL);
- p = fnval;
- }
- } else {
- ckmakmsg(fnval,FNVALL,"<ERROR:UNKNOWN:\\f",fn,"()>",NULL);
- p = fnval;
- }
- if (fnerror) /* SET FUNCTION ERROR ON */
- fnsuccess = 0; /* Make command fail (see ckuus5.c) */
- debug(F111,"fneval failed",p,fnsuccess);
- if (fndiags) /* SET FUNCTION DIAGNOSTICS ON */
- printf("?%s\n",p); /* Print error message now. */
- else
- return(""); /* Return nothing. */
- }
- return(p);
-}
-#endif /* NOSPL */
-
-static char ckpidbuf[32] = "????";
-
-#ifdef VMS
-_PROTOTYP(long zgpid,(void));
-#endif /* VMS */
-
-char *
-ckgetpid() { /* Return pid as string */
-#ifdef CK_PID
-#ifdef OS2
-#define getpid _getpid
- unsigned long zz;
-#else
- long zz;
-#endif /* OS2 */
-#ifdef VMS
- zz = zgpid();
-#else
- zz = getpid();
-#endif /* VMS */
- sprintf(ckpidbuf,"%ld",zz); /* SAFE */
-#endif /* CK_PID */
- return((char *)ckpidbuf);
-}
-
-#ifndef NOSPL
-#define EMBUFLEN 128 /* Error message buffer length */
-
-static char embuf[EMBUFLEN+1];
-
-char * /* Evaluate builtin variable */
-nvlook(s) char *s; {
- int x, y, cx;
- long z;
- char *p;
-#ifndef NODIAL
- MDMINF * m;
-#endif /* NODIAL */
-#ifndef NOKVERBS /* Keyboard macro material */
- extern int keymac, keymacx;
-#endif /* NOKVERBS */
-#ifdef CK_LOGIN
- extern int isguest;
-#endif /* CK_LOGIN */
- if (!s) s = "";
- x = strlen(s);
- if (fndiags) { /* FUNCTION DIAGNOSTIC ON */
- if (x + 32 < EMBUFLEN)
- sprintf(embuf,"<ERROR:NO_SUCH_VARIABLE:\\v(%s)>",s); /* SAFE */
- else
- sprintf(embuf,"<ERROR:NO_SUCH_VARIABLE>"); /* SAFE */
- } else /* FUNCTION DIAGNOSTIC OFF */
- embuf[0] = NUL;
- x = VVBUFL;
- p = vvbuf;
- if (zzstring(s,&p,&x) < 0) { /* e.g. for \v(\%a) */
- y = -1;
- } else {
- s = vvbuf;
- y = lookup(vartab,s,nvars,&x);
- }
- cx = y; /* y is too generic */
-#ifndef NODIAL
- m = (mdmtyp > 0) ? modemp[mdmtyp] : NULL; /* For \v(m_xxx) variables */
-#endif /* NODIAL */
-
- debug(F101,"nvlook y","",y);
-
- switch (y) {
- case VN_ARGC: /* ARGC */
- sprintf(vvbuf,"%d",maclvl < 0 ? topargc : macargc[maclvl]); /* SAFE */
- return(vvbuf);
-
- case VN_ARGS: /* ARGS */
- sprintf(vvbuf,"%d",xargs); /* SAFE */
- return(vvbuf);
-
- case VN_COUN: /* COUNT */
- sprintf(vvbuf,"%d",count[cmdlvl]); /* SAFE */
- return(vvbuf);
-
- case VN_DATE: /* DATE */
- ztime(&p); /* Get "asctime" string */
- if (p == NULL || *p == NUL) return(NULL);
- vvbuf[0] = p[8]; /* dd */
- vvbuf[1] = p[9];
- vvbuf[2] = SP;
- vvbuf[3] = p[4]; /* mmm */
- vvbuf[4] = p[5];
- vvbuf[5] = p[6];
- vvbuf[6] = SP;
- for (x = 20; x < 24; x++) /* yyyy */
- vvbuf[x - 13] = p[x];
- vvbuf[11] = NUL;
- return(vvbuf);
-
- case VN_NDAT: /* Numeric date */
- ckstrncpy(vvbuf,zzndate(),VVBUFL);
- return(vvbuf);
-
- case VN_DIRE: /* DIRECTORY */
- s = zgtdir(); /* Get current directory */
- if (!s)
-#ifdef UNIXOROSK
- s = "./";
-#else
-#ifdef VMS
- s = "[]";
-#else
- s = "";
-#endif /* VMS */
-#endif /* UNIXOROSK */
- ckstrncpy(vvbuf,s,VVBUFL);
- s = vvbuf;
-#ifdef UNIXOROSK
- x = strlen(s);
- if (x < VVBUFL - 1) {
- if (s[x-1] != '/') {
- s[x] = '/';
- s[x+1] = NUL;
- }
- }
-#endif /* UNIXOROSK */
- return(s);
-
- case VN_FILE: /* filespec */
- return(fspec);
-
- case VN_HOST: /* host name */
- if (*myhost) { /* If known */
- return(myhost); /* return it. */
- } else { /* Otherwise */
- ckstrncpy(vvbuf,"unknown",VVBUFL); /* just say "unknown" */
- return(vvbuf);
- }
-
- case VN_SYST: /* System type */
-#ifdef UNIX
- ckstrncpy(vvbuf,"UNIX",VVBUFL);
-#else
-#ifdef VMS
- ckstrncpy(vvbuf,"VMS",VVBUFL);
-#else
-#ifdef OSK
- ckstrncpy(vvbuf,"OS9/68K",VVBUFL);
-#else
-#ifdef AMIGA
- ckstrncpy(vvbuf,"Amiga",VVBUFL);
-#else
-#ifdef MAC
- ckstrncpy(vvbuf,"Macintosh",VVBUFL);
-#else
-#ifdef OS2
-#ifdef NT
- ckstrncpy(vvbuf,"WIN32",VVBUFL) ;
-#else /* NT */
- ckstrncpy(vvbuf,"OS/2",VVBUFL);
-#endif /* NT */
-#else
-#ifdef datageneral
- ckstrncpy(vvbuf,"AOS/VS",VVBUFL);
-#else
-#ifdef GEMDOS
- ckstrncpy(vvbuf,"Atari_ST",VVBUFL);
-#else
-#ifdef STRATUS
- ckstrncpy(vvbuf,"Stratus_VOS",VVBUFL);
-#else
- ckstrncpy(vvbuf,"unknown",VVBUFL);
-#endif /* STRATUS */
-#endif /* GEMDOS */
-#endif /* datageneral */
-#endif /* OS2 */
-#endif /* MAC */
-#endif /* AMIGA */
-#endif /* OSK */
-#endif /* VMS */
-#endif /* UNIX */
- return(vvbuf);
-
- case VN_SYSV: /* System herald */
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest)
- return("");
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- for (x = y = 0; x < VVBUFL; x++) {
- if (ckxsys[x] == SP && y == 0) continue;
- vvbuf[y++] = (char) ((ckxsys[x] == SP) ? '_' : ckxsys[x]);
- }
- vvbuf[y] = NUL;
- return(vvbuf);
- } /* Break up long switch statements... */
-
- switch(y) {
- case VN_TIME: /* TIME. Assumes that ztime returns */
- ztime(&p); /* "Thu Feb 8 12:00:00 1990" */
- if (p == NULL || *p == NUL) /* like asctime()! */
- return("");
- for (x = 11; x < 19; x++) /* copy hh:mm:ss */
- vvbuf[x - 11] = p[x]; /* to vvbuf */
- vvbuf[8] = NUL; /* terminate */
- return(vvbuf); /* and return it */
-
- case VN_NTIM: /* Numeric time */
- ztime(&p); /* "Thu Feb 8 12:00:00 1990" */
- if (p == NULL || *p == NUL) /* like asctime()! */
- return(NULL);
- z = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
- sprintf(vvbuf,"%ld",z); /* SAFE */
- return(vvbuf);
-
-#ifdef CK_TTYFD
- case VN_TTYF: /* TTY file descriptor */
- sprintf(vvbuf,"%d", /* SAFE */
-#ifdef VMS
- vmsttyfd()
-#else
- ttyfd
-#endif /* VMS */
- );
- return(vvbuf);
-#endif /* CK_TTYFD */
-
- case VN_VERS: /* Numeric Kermit version number */
- sprintf(vvbuf,"%ld",vernum); /* SAFE */
- return(vvbuf);
-
- case VN_XVNUM: /* Product-specific version number */
- sprintf(vvbuf,"%ld",xvernum); /* SAFE */
- return(vvbuf);
-
- case VN_HOME: /* Home directory */
- return(homepath());
-
- case VN_IBUF: /* INPUT buffer */
- return((char *)inpbuf);
-
- case VN_ICHR: /* INPUT character */
- inchar[1] = NUL;
- return((char *)inchar);
-
- case VN_ICNT: /* INPUT character count */
- sprintf(vvbuf,"%d",incount); /* SAFE */
- return(vvbuf);
-
- case VN_SPEE: { /* Transmission SPEED */
- long t;
- t = ttgspd();
- if (t < 0L)
- sprintf(vvbuf,"unknown"); /* SAFE */
- else
- sprintf(vvbuf,"%ld",t); /* SAFE */
- return(vvbuf);
- }
-
- case VN_SUCC: /* SUCCESS flag */
- /* Note inverted sense */
- sprintf(vvbuf,"%d",(success == 0) ? 1 : 0); /* SAFE */
- return(vvbuf);
-
- case VN_LINE: { /* LINE */
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"\\v(line) local",ttname,local);
- debug(F111,"\\v(line) inserver","",inserver);
-#ifdef TNCODE
- debug(F111,"\\v(line) tcp_incoming","",tcp_incoming);
-#endif /* TNCODE */
-#ifdef CK_TAPI
- debug(F111,"\\v(line) tttapi","",tttapi);
-#endif /* CK_TAPI */
- }
-#endif /* DEBUG */
-
-#ifdef CK_TAPI
- if (tttapi) { /* If I have made a TAPI connection */
- int i; /* return the TAPI device name */
- for (i = 0; i < ntapiline; i++) {
- if (!strcmp(ttname,tapilinetab[i].kwd)) {
- p = _tapilinetab[i].kwd;
- return(p);
- }
- }
- }
-#endif /* CK_TAPI */
-#ifndef NOXFER
- if (inserver /* If I am a TCP server */
-#ifdef TNCODE
- || tcp_incoming
-#endif /* TNCODE */
- )
-#ifdef TCPSOCKET
- p = ckgetpeer(); /* return peer name */
- else
-#endif /* TCPSOCKET */
-#endif /* NOXFER */
- if (local) /* Otherwise if in local mode */
- p = (char *) ttname; /* return SET LINE / SET HOST name */
- else /* Otherwise */
- p = ""; /* return empty string */
- if (!p) /* In case ckgetpeer() returns */
- p = ""; /* null pointer... */
- debug(F110,"\\v(line) p",p,0);
- if (!*p)
- p = (char *) ttname;
- return(p);
- }
- case VN_PROG: /* Program name */
- return("C-Kermit");
-
- } /* Break up long switch statements... */
-
- switch(y) {
- case VN_RET: /* Value of most recent RETURN */
- debug(F111,"\\v(return)",mrval[maclvl+1],maclvl+1);
- p = mrval[maclvl+1];
- if (p == NULL) p = "";
- return(p);
-
- case VN_FFC: /* Size of most recent file */
- sprintf(vvbuf, "%s", ckfstoa(ffc)); /* SAFE */
- return(vvbuf);
-
- case VN_TFC: /* Size of most recent file group */
- sprintf(vvbuf, "%s", ckfstoa(tfc)); /* SAFE */
- return(vvbuf);
-
- case VN_CPU: /* CPU type */
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest)
- return("");
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-#ifdef OS2
- {
- char * getcpu(void) ;
- return getcpu();
- }
-#else /* OS2 */
-#ifdef CKCPU
- return(CKCPU); /* Traditionally, compile-time value */
-#else
-#ifdef CK_UTSNAME
- { /* But if none, try runtime value */
- extern char unm_mch[];
- return((char *)unm_mch);
- }
-#else
- p = getenv("HOSTTYPE"); /* 20091116 */
- if (p) if (*p) return(p);
- return("unknown");
-#endif /* CK_UTSNAME */
-#endif /* CKCPU */
-#endif /* OS2 */
-
- case VN_CMDL: /* Command level */
- sprintf(vvbuf, "%d", cmdlvl); /* SAFE */
- return(vvbuf);
-
- case VN_DAY: /* Day of week */
- ztime(&p);
- if (p != NULL && *p != NUL) /* ztime() succeeded. */
- ckstrncpy(vvbuf,p,4);
- else
- vvbuf[0] = NUL; /* ztime() failed. */
- return(vvbuf); /* Return what we got. */
-
- case VN_NDAY: { /* Numeric day of week */
- long k;
- z = mjd(zzndate()); /* Get modified Julian date */
- k = (((int)(z % 7L)) + 3) % 7; /* Get day number */
- sprintf(vvbuf,"%ld",k); /* SAFE */
- return(vvbuf);
- }
-
- case VN_LCL: /* Local (vs remote) mode */
- ckstrncpy(vvbuf, local ? "1" : "0",VVBUFL);
- return(vvbuf);
-
- case VN_CMDS: /* Command source */
- if (cmdstk[cmdlvl].src == CMD_KB)
- ckstrncpy(vvbuf,"prompt",VVBUFL);
- else if (cmdstk[cmdlvl].src == CMD_MD)
- ckstrncpy(vvbuf,"macro",VVBUFL);
- else if (cmdstk[cmdlvl].src == CMD_TF)
- ckstrncpy(vvbuf,"file",VVBUFL);
- else
- ckstrncpy(vvbuf,"unknown",VVBUFL);
- return(vvbuf);
-
- case VN_CMDF: /* Current command file name */
-#ifdef COMMENT /* (see comments above) */
- if (tfnam[tlevel]) { /* (near dblbs declaration) */
- dblbs(tfnam[tlevel],vvbuf,VVBUFL);
- return(vvbuf);
- } else return("");
-#else
- if (tlevel < 0)
- return("");
- else
- return(tfnam[tlevel] ? tfnam[tlevel] : "");
-#endif /* COMMENT */
-
- case VN_MAC: /* Current macro name */
- return((maclvl > -1) ? m_arg[maclvl][0] : "");
-
- case VN_EXIT:
- sprintf(vvbuf,"%d",xitsta); /* SAFE */
- return(vvbuf);
-
- } /* Break up long switch statements... */
-
- switch(y) {
- case VN_PRTY: { /* Parity */
- char *ss;
- switch (parity) {
- case 0: ss = "none"; break;
- case 'e': ss = "even"; break;
- case 'm': ss = "mark"; break;
- case 'o': ss = "odd"; break;
- case 's': ss = "space"; break;
- default: ss = "unknown"; break;
- }
- ckstrncpy(vvbuf,ss,VVBUFL);
- return(vvbuf);
- }
-
- case VN_DIAL:
- sprintf(vvbuf,"%d", /* SAFE */
-#ifndef NODIAL
- dialsta
-#else
- -1
-#endif /* NODIAL */
- );
- return(vvbuf);
-
-#ifndef NODIAL
- case VN_DMSG:
-#ifdef BIGBUFOK
- ckstrncpy(vvbuf,dialmsg[dialsta],VVBUFL); /* Safe if src == NULL */
-#endif /* BIGBUFOK */
- return((char *)vvbuf);
-#endif /* NODIAL */
-
-#ifdef OS2
- case VN_KEYB:
- ckstrncpy(vvbuf,conkbg(),VVBUFL);
- return(vvbuf);
- case VN_SELCT: {
-#ifndef NOLOCAL
- const char * selection = GetSelection();
- return( (char *) (selection ? selection : "" )) ;
-#else
- return("");
-#endif /* NOLOCAL */
- }
-#endif /* OS2 */
-
-#ifndef NOXFER
- case VN_CPS:
- sprintf(vvbuf,"%ld",tfcps); /* SAFE */
- return(vvbuf);
-#endif /* NOXFER */
-
- case VN_MODE: /* File transfer mode */
- switch (binary) {
- case XYFT_T: ckstrncpy(vvbuf,"text",VVBUFL); break;
- case XYFT_B:
- case XYFT_U: ckstrncpy(vvbuf,"binary",VVBUFL); break;
- case XYFT_I: ckstrncpy(vvbuf,"image",VVBUFL); break;
- case XYFT_L: ckstrncpy(vvbuf,"labeled",VVBUFL); break;
- case XYFT_M: ckstrncpy(vvbuf,"macbinary",VVBUFL); break;
- default: ckstrncpy(vvbuf,"unknown",VVBUFL);
- }
- return(vvbuf);
-
-#ifdef CK_REXX
- case VN_REXX:
- return(rexxbuf);
-#endif /* CK_REXX */
-
- case VN_NEWL: /* System newline char or sequence */
-#ifdef UNIX
- ckstrncpy(vvbuf,"\n",VVBUFL);
-#else
-#ifdef datageneral
- ckstrncpy(vvbuf,"\n",VVBUFL);
-#else
-#ifdef OSK
- ckstrncpy(vvbuf,"\15",VVBUFL); /* Remember, these are octal... */
-#else
-#ifdef MAC
- ckstrncpy(vvbuf,"\15",VVBUFL);
-#else
-#ifdef OS2
- ckstrncpy(vvbuf,"\15\12",VVBUFL);
-#else
-#ifdef STRATUS
- ckstrncpy(vvbuf,"\n",VVBUFL);
-#else
-#ifdef VMS
- ckstrncpy(vvbuf,"\15\12",VVBUFL);
-#else
-#ifdef AMIGA
- ckstrncpy(vvbuf,"\n",VVBUFL);
-#else
-#ifdef GEMDOS
- ckstrncpy(vvbuf,"\n",VVBUFL);
-#else
- ckstrncpy(vvbuf,"\n",VVBUFL);
-#endif /* GEMDOS */
-#endif /* AMIGA */
-#endif /* VMS */
-#endif /* STRATUS */
-#endif /* OS2 */
-#endif /* MAC */
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* UNIX */
- return(vvbuf);
-
- case VN_ROWS: /* ROWS */
- case VN_COLS: /* COLS */
- ckstrncpy(vvbuf,(cx == VN_ROWS) ? "24" : "80",VVBUFL); /* Default */
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- if (tt_cols[VTERM] < 0 || tt_rows[VTERM] < 0)
- ttgwsiz();
- sprintf(vvbuf,"%d", /* SAFE */
- (cx == VN_ROWS) ? tt_rows[VTERM] : tt_cols[VTERM]);
-#else /* OS2 */
- if (ttgwsiz() > 0) /* Get window size */
- if (tt_cols > 0 && tt_rows > 0) /* sets tt_rows, tt_cols */
- sprintf(vvbuf,"%d", /* SAFE */
- (cx == VN_ROWS) ? tt_rows : tt_cols);
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
- return(vvbuf);
-
- case VN_TTYP:
-#ifdef NOTERM
- ckstrncpy(vvbuf,"unknown",VVBUFL);
-#else
-#ifdef OS2
- sprintf(vvbuf, "%s", /* SAFE */
- (tt_type >= 0 && tt_type <= max_tt) ?
- tt_info[tt_type].x_name :
- "unknown"
- );
-#else
-#ifdef MAC
- ckstrncpy(vvbuf,"vt320",VVBUFL);
-#else
- p = getenv("TERM");
- ckstrncpy(vvbuf,p ? p : "unknown",VVBUFL+1);
-#endif /* MAC */
-#endif /* OS2 */
-#endif /* NOTERM */
- return(vvbuf);
-
- case VN_MINP: /* MINPUT */
- sprintf(vvbuf, "%d", m_found); /* SAFE */
- return(vvbuf);
- } /* Break up long switch statements... */
-
- switch(y) {
- case VN_CONN: /* CONNECTION */
- if (!local) {
- ckstrncpy(vvbuf,"remote",VVBUFL);
- } else {
- if (!network)
- ckstrncpy(vvbuf,"serial",VVBUFL);
-#ifdef TCPSOCKET
- else if (nettype == NET_TCPB || nettype == NET_TCPA) {
- if (ttnproto == NP_TELNET)
- ckstrncpy(vvbuf,"tcp/ip_telnet",VVBUFL);
-#ifdef CK_SSL
- else if (ttnproto == NP_SSL || ttnproto == NP_SSL_RAW)
- ckstrncpy(vvbuf,"tcp/ip_ssl",VVBUFL);
- else if (ttnproto == NP_TLS || ttnproto == NP_SSL_RAW)
- ckstrncpy(vvbuf,"tcp/ip_tls",VVBUFL);
-#endif /* CK_SSL */
- else
- ckstrncpy(vvbuf,"tcp/ip",VVBUFL);
- }
-#endif /* TCPSOCKET */
-#ifdef SSHBUILTIN
- else if (nettype == NET_SSH)
- ckstrncpy(vvbuf,"tcp/ip_ssh",VVBUFL);
-#endif /* SSHBUILTIN */
-#ifdef ANYX25
- else if (nettype == NET_SX25 ||
- nettype == NET_VX25 ||
- nettype == NET_IX25
- )
- ckstrncpy(vvbuf,"x.25",VVBUFL);
-#endif /* ANYX25 */
-#ifdef DECNET
- else if (nettype == NET_DEC) {
- if (ttnproto == NP_LAT)
- ckstrncpy(vvbuf,"decnet_lat",VVBUFL);
- else if ( ttnproto == NP_CTERM )
- ckstrncpy(vvbuf,"decnet_cterm",VVBUFL);
- else
- ckstrncpy(vvbuf,"decnet",VVBUFL);
- }
-#endif /* DECNET */
-#ifdef SUPERLAT
- else if (nettype == NET_SLAT)
- ckstrncpy(vvbuf,"superlat",VVBUFL);
-#endif /* SUPERLAT */
-#ifdef NETFILE
- else if (nettype == NET_FILE)
- ckstrncpy(vvbuf,"local_file",VVBUFL);
-#endif /* NETFILE */
-#ifdef NETCMD
- else if (nettype == NET_CMD)
- ckstrncpy(vvbuf,"pipe",VVBUFL);
-#endif /* NETCMD */
-#ifdef NETPTY
- else if (nettype == NET_PTY)
- ckstrncpy(vvbuf,"pseudoterminal",VVBUFL);
-#endif /* NETPTY */
-#ifdef NETDLL
- else if (nettype == NET_DLL)
- ckstrncpy(vvbuf,"dynamic_link_library",VVBUFL);
-#endif /* NETDLL */
-
-#ifdef NPIPE
- else if (nettype == NET_PIPE)
- ckstrncpy(vvbuf,"named_pipe",VVBUFL);
-#endif /* NPIPE */
-#ifdef CK_NETBIOS
- else if (nettype == NET_BIOS)
- ckstrncpy(vvbuf,"netbios",VVBUFL);
-#endif /* CK_NETBIOS */
- else
- ckstrncpy(vvbuf,"unknown",VVBUFL);
- }
- return(vvbuf);
-
-#ifndef NOXFER
- case VN_SYSI: /* System ID, Kermit code */
- return((char *)cksysid);
-#endif /* NOXFER */
-
-#ifdef OS2
- case VN_SPA: {
- unsigned long space = zdskspace(0);
- if (space > 0 && space < 1024)
- sprintf(vvbuf,"-1");
- else
- sprintf(vvbuf,"%lu",space); /* SAFE */
- return(vvbuf);
- }
-#endif /* OS2 */
-
-#ifndef NOXFER
- case VN_QUE: {
- extern char querybuf[];
- return(querybuf);
- }
-#endif /* NOXFER */
-
-#ifndef NOCSETS
- case VN_CSET:
-#ifdef OS2
- sprintf(vvbuf,"cp%d",os2getcp()); /* SAFE */
-#else
- ckstrncpy(vvbuf,fcsinfo[fcharset].keyword,VVBUFL+1);
-#endif /* OS2 */
- return(vvbuf);
-#endif /* NOCSETS */
-
-#ifdef OS2
- case VN_EXEDIR:
- return(exedir);
- case VN_STAR:
- return(startupdir);
-#else
- case VN_EXEDIR:
- return(exedir ? exedir : "");
-#ifdef VMSORUNIX
- case VN_STAR:
- return(startupdir);
-#endif /* VMSORUNIX */
-#endif /* OS2 */
-
- case VN_INI:
- return(inidir);
-
- case VN_MDM:
- return(gmdmtyp());
-
- case VN_EVAL:
- return(evalbuf);
-
-#ifndef NODIAL
- case VN_D_CC: /* DIAL COUNTRY-CODE */
- return(diallcc ? diallcc : "");
-
- case VN_D_AC: /* DIAL AREA-CODE */
- return(diallac ? diallac : "");
-
- case VN_D_IP: /* DIAL INTERNATIONAL-PREFIX */
- return(dialixp ? dialixp : "");
-
- case VN_D_LP: /* DIAL LD-PREFIX */
- return(dialldp ? dialldp : "");
-
- case VN_D_LCP: /* DIAL LOCAL-PREFIX */
- return(diallcp ? diallcp : "");
-
- case VN_D_PXX: /* DIAL PBX-EXCHANGE that matched */
- return(matchpxx ? matchpxx : "");
-#else
- case VN_D_CC: /* DIAL COUNTRY-CODE */
- case VN_D_AC: /* DIAL AREA-CODE */
- case VN_D_IP: /* DIAL INTERNATIONAL-PREFIX */
- case VN_D_LP: /* DIAL LD-PREFIX */
- case VN_D_LCP: /* DIAL LOCAL-PREFIX */
- case VN_D_PXX: /* DIAL PBX-EXCHANGE */
- return("");
-#endif /* NODIAL */
- case VN_UID:
-#ifdef UNIX
- {
-#ifdef IKSD
- if (inserver)
- return((char *)uidbuf);
- else
-#endif /* IKSD */
- if (uidbuf[0])
- return((char *)uidbuf);
- else
- return(whoami());
- }
-#else
- return((char *)uidbuf);
-#endif /* UNIX */
- } /* Break up long switch statements... */
-
- switch(y) {
- case VN_PWD:
-#ifdef OS2
- if (activecmd == XXOUT || activecmd == XXLNOUT) {
- ckstrncpy(vvbuf,pwbuf,VVBUFL);
- ck_encrypt((char *)vvbuf);
- return((char *)vvbuf);
- } else
-#endif /* OS2 */
- return((char *)pwbuf);
-
- case VN_PRM:
- return((char *)prmbuf);
-
- case VN_PROTO:
-#ifdef NOXFER
- return("none");
-#else
-#ifdef CK_XYZ
- return(ptab[protocol].p_name);
-#else
- return("kermit");
-#endif /* CK_XYZ */
-#endif /* NOXFER */
-
-#ifndef NOXFER
-#ifdef CK_TMPDIR
- case VN_DLDIR:
- return(dldir ? dldir : "");
-#endif /* CK_TMPDIR */
-#endif /* NOXFER */
-
-#ifndef NODIAL
- case VN_M_INI: /* Modem init string */
- return(dialini ? dialini : (m ? m->wake_str : ""));
-
- case VN_M_DCM: /* Modem dial command */
- return(dialcmd ? dialcmd : (m ? m->dial_str : ""));
-
- case VN_M_DCO: /* Modem data compression on */
- return(dialdcon ? dialdcon : (m ? m->dc_on_str : ""));
-
- case VN_M_DCX: /* Modem data compression off */
- return(dialdcoff ? dialdcoff : (m ? m->dc_off_str : ""));
-
- case VN_M_ECO: /* Modem error correction on */
- return(dialecon ? dialecon : (m ? m->ec_on_str : ""));
-
- case VN_M_ECX: /* Modem error correction off */
- return(dialecoff ? dialecoff : (m ? m->ec_off_str : ""));
-
- case VN_M_AAO: /* Modem autoanswer on */
- return(dialaaon ? dialaaon : (m ? m->aa_on_str : ""));
-
- case VN_M_AAX: /* Modem autoanswer off */
- return(dialaaoff ? dialaaoff : (m ? m->aa_off_str : ""));
-
- case VN_M_HUP: /* Modem hangup command */
- return(dialhcmd ? dialhcmd : (m ? m->hup_str : ""));
-
- case VN_M_HWF: /* Modem hardware flow command */
- return(dialhwfc ? dialhwfc : (m ? m->hwfc_str : ""));
-
- case VN_M_SWF: /* Modem software flow command */
- return(dialswfc ? dialswfc : (m ? m->swfc_str : ""));
-
- case VN_M_NFC: /* Modem no flow-control command */
- return(dialnofc ? dialnofc : (m ? m->nofc_str : ""));
-
- case VN_M_PDM: /* Modem pulse dialing mode */
- return(dialpulse ? dialpulse : (m ? m->pulse : ""));
-
- case VN_M_TDM: /* Modem tone dialing mode */
- return(dialtone ? dialtone : (m ? m->tone : ""));
-
- case VN_M_NAM: /* Modem full name */
- return(dialname ? dialname : (m ? m->name : ""));
-#else
- case VN_M_INI: /* Modem init string */
- case VN_M_DCM: /* Modem dial command */
- case VN_M_DCO: /* Modem data compression on */
- case VN_M_DCX: /* Modem data compression off */
- case VN_M_ECO: /* Modem error correction on */
- case VN_M_ECX: /* Modem error correction off */
- case VN_M_AAO: /* Modem autoanswer on */
- case VN_M_AAX: /* Modem autoanswer off */
- case VN_M_HUP: /* Modem hangup command */
- case VN_M_HWF: /* Modem hardware flow command */
- case VN_M_SWF: /* Modem software flow command */
- case VN_M_NFC: /* Modem no flow-control command */
- case VN_M_PDM: /* Modem pulse dialing mode */
- case VN_M_TDM: /* Modem tone dialing mode */
- case VN_M_NAM:
- return("");
-#endif /* NODIAL */
-
- case VN_ISTAT: /* INPUT status */
- sprintf(vvbuf, "%d", instatus); /* SAFE */
- return(vvbuf);
-
- case VN_TEMP: /* Temporary directory */
- if (tempdir) {
- p = tempdir;
- } else {
-#ifdef OS2
-#ifdef NT
- p = getenv("K95TMP");
-#else
- p = getenv("K2TMP");
-#endif /* NT */
- if ( !p )
-#endif /* OS2 */
- p = getenv("CK_TMP");
- if (!p) p = getenv("TMPDIR");
- if (!p) p = getenv("TEMP");
- if (!p) p = getenv("TMP");
-
-#ifdef OS2ORUNIX
- if (p) {
- int len = strlen(p);
- if (p[len-1] != '/'
-#ifdef OS2
- && p[len-1] != '\\'
-#endif /* OS2 */
- ) {
- static char foo[CKMAXPATH];
- ckstrncpy(foo,p,CKMAXPATH);
- ckstrncat(foo,"/",CKMAXPATH);
- p = foo;
- }
- } else
-#else /* OS2ORUNIX */
- if (!p)
-#endif /* OS2ORUNIX */
-#ifdef UNIX /* Systems that have a standard */
- p = "/tmp/"; /* temporary directory... */
-#else
-#ifdef datageneral
- p = ":TMP:";
-#else
- p = "";
-#endif /* datageneral */
-#endif /* UNIX */
- }
- ckstrncpy(vvbuf,p,VVBUFL);
- p = vvbuf;
-
-/* This needs generalizing for VOS, AOS/VS, etc... */
-
- while (*p) {
-#ifdef OS2
- if (*p == '\\') *p = '/';
-#endif /* OS2 */
- p++;
- }
-#ifndef VMS
- if (p > vvbuf) {
- char c = /* Directory termination character */
-#ifdef MAC
- ':'
-#else
-#ifdef datageneral
- ':'
-#else
-#ifdef STRATUS
- '>'
-#else
- '/'
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* MAC */
- ;
-
- if (*(p-1) != c) {
- *p++ = c;
- *p = NUL;
- }
- }
-#endif /* VMS */
- return(vvbuf);
- } /* Break up long switch statements... */
-
- switch(y) {
- case VN_ERRNO: /* Error number */
-#ifdef VMS
- {
- extern int vms_lasterr;
- sprintf(vvbuf, "%d", vms_lasterr); /* SAFE */
- }
-#else
- sprintf(vvbuf, "%d", errno); /* SAFE */
-#endif /* VMS */
- return(vvbuf);
-
- case VN_ERSTR: /* Error string */
- ckstrncpy(vvbuf,ck_errstr(),VVBUFL);
- return(vvbuf);
-
-#ifndef NOXFER
- case VN_RPSIZ: /* RECEIVE packet-length */
- sprintf(vvbuf,"%d",urpsiz); /* SAFE */
- return(vvbuf);
-
- case VN_WINDO: /* WINDOW slots */
- sprintf(vvbuf,"%d",wslotr); /* SAFE */
- return(vvbuf);
-#endif /* NOXFER */
-
- case VN_TFLN: /* TAKE-file line number */
- if (tlevel > -1) {
- sprintf(vvbuf, "%d", tfline[tlevel]); /* SAFE */
- return(vvbuf);
- } else
- return("0");
-
- case VN_MDMSG: /* DIALRESULT */
-#ifndef NODIAL
- return((char *)modemmsg);
-#else
- return("");
-#endif /* NODIAL */
-
- case VN_DNUM: /* DIALNUMBER */
-#ifndef NODIAL
- return(dialnum ? (char *) dialnum : "");
-#else
- return("");
-#endif /* NODIAL */
-
- case VN_APC:
- sprintf(vvbuf, "%d", /* SAFE */
-#ifdef CK_APC
- apcactive
-#else
- 0
-#endif /* CK_APC */
- );
- return((char *)vvbuf);
-
-#ifdef OS2
-#ifndef NOKVERBS
- case VN_TRMK:
- sprintf(vvbuf, "%d", keymac); /* SAFE */
- return((char *)vvbuf);
-#endif /* NOKVERBS */
-#endif /* OS2 */
-
- case VN_IPADDR:
-#ifdef TCPSOCKET
-#ifndef OSK
- /* This dumps core on OS-9 for some reason, but only if executed */
- /* before we have made a TCP connection. This is obviously not */
- /* the ideal fix. */
- if (!myipaddr[0])
- getlocalipaddr();
-#endif /* OSK */
-#endif /* TCPSOCKET */
- ckstrncpy(vvbuf,
-#ifdef TCPSOCKET
- (char *)myipaddr,
-#else
- "",
-#endif /* TCPSOCKET */
- VVBUFL);
- return((char *)vvbuf);
-
-#ifndef NOXFER
- case VN_CRC16: /* CRC-16 of most recent transfer */
- sprintf(vvbuf,"%d",crc16); /* SAFE */
- return(vvbuf);
-#endif /* NOXFER */
-
-#ifdef CK_PID
- case VN_PID:
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest)
- return("");
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- return(ckgetpid());
-#endif /* CK_PID */
-
-#ifndef NOXFER
- case VN_FNAM: { /* \v(filename) */
- extern char filnam[], ofn1[], *sfspec, *rrfspec;
- char * tmp;
- switch (what) { /* File transfer is in progress */
-#ifdef NEWFTP
- case (W_FTP|W_RECV):
- case (W_FTP|W_SEND):
- return((char *)filnam);
-#endif /* NEWFTP */
- case W_RECV:
- case W_REMO:
- return((char *)ofn1);
- default: /* Most recent file transferred */
- if (filnam[0]) { /* (if any) */
- return((char *)filnam);
- } else if (lastxfer & W_SEND && sfspec) {
- if (fnspath == PATH_OFF)
- zstrip(sfspec,&tmp);
- else
- tmp = sfspec;
- return(tmp);
- } else if (lastxfer & W_RECV && rrfspec) {
- if (fnrpath == PATH_OFF)
- zstrip(rrfspec,&tmp);
- else
- tmp = rrfspec;
- return(tmp);
- } else
- return("");
- }
- }
- case VN_FNUM: /* \v(filenum) */
- sprintf(vvbuf,"%ld",filcnt); /* SAFE */
- return((char *)vvbuf);
-#endif /* NOXFER */
-
-#ifdef PEXITSTAT
- case VN_PEXIT: {
- extern int pexitstat;
- sprintf(vvbuf,"%d",pexitstat); /* SAFE */
- return((char *)vvbuf);
- }
-#endif /* PEXITSTAT */
-
-#ifndef NOXFER
- case VN_P_8BIT:
- vvbuf[0] = parity ? ebq : NUL;
- vvbuf[1] = NUL;
- return((char *)vvbuf);
-
- case VN_P_CTL: {
- extern CHAR myctlq;
- vvbuf[0] = myctlq;
- vvbuf[1] = NUL;
- return((char *)vvbuf);
- }
- case VN_P_RPT: {
- extern int rptena;
- vvbuf[0] = rptena ? rptq : NUL;
- vvbuf[1] = NUL;
- return((char *)vvbuf);
- }
-#endif /* NOXFER */
-
-#ifdef OS2
- case VN_REGN:
- return(get_reg_name());
- case VN_REGO:
- return(get_reg_corp());
- case VN_REGS:
- return(get_reg_sn());
-#endif /* OS2 */
- } /* Break up long switch statements... */
-
- switch(y) {
- case VN_XPROG:
-#ifdef OS2
-#ifdef NT
-#ifdef KUI
- return("K-95G");
-#else
- return("K-95");
-#endif /* KUI */
-#else
- return("K/2");
-#endif /* NT */
-#else
- return("C-Kermit");
-#endif /* OS2 */
-
- case VN_EDITOR:
-#ifdef NOFRILLS
- return("");
-#else
-#ifdef NOPUSH
- return("");
-#else
- {
- extern char editor[];
- char *ss;
- if (!editor[0]) {
- ss = getenv("EDITOR");
- if (ss) {
- ckstrncpy(editor,ss,CKMAXPATH);
- }
- }
- debug(F110,"\\v(editor)",editor,0);
- return(editor[0] ? (char *)editor : "");
- }
-#endif /* NOPUSH */
-#endif /* NOFRILLS */
-
- case VN_EDOPT:
-#ifdef NOFRILLS
- return("");
-#else
-#ifdef NOPUSH
- return("");
-#else
- {
- extern char editopts[];
- return(editopts[0] ? (char *)editopts : "");
- }
-#endif /* NOPUSH */
-#endif /* NOFRILLS */
-
- case VN_EDFILE:
-#ifdef NOFRILLS
- return("");
-#else
-#ifdef NOPUSH
- return("");
-#else
- {
- extern char editfile[];
- return(editfile[0] ? (char *)editfile : "");
- }
-#endif /* NOPUSH */
-#endif /* NOFRILLS */
-
-#ifdef BROWSER
- case VN_BROWSR: {
- extern char browser[];
- if (!browser[0]) {
- s = getenv("BROWSER");
- if (s) ckstrncpy(browser,s,CKMAXPATH);
- }
- return(browser[0] ? (char *)browser : "");
- }
- case VN_BROPT: {
- extern char browsopts[];
- return(browsopts[0] ? (char *)browsopts : "");
- }
- case VN_URL: {
- extern char browsurl[];
- return(browsurl[0] ? (char *)browsurl : "");
- }
-#endif /* BROWSER */
- case VN_HERALD:
- return((char *)versio);
-
- case VN_TEST: { /* test */
- extern char * ck_s_test, * ck_s_tver;
- if (!ck_s_test) ck_s_test = "";
- if (!ck_s_tver) ck_s_tver = "";
- if (*ck_s_test) {
- ckstrncpy(vvbuf,ck_s_test,VVBUFL);
- if (*ck_s_tver) {
- ckstrncat(vvbuf,".",VVBUFL);
- ckstrncat(vvbuf,ck_s_tver,VVBUFL);
- }
- } else
- ckstrncpy(vvbuf,"0",VVBUFL);
- return((char *)vvbuf);
- }
-
-#ifndef NOXFER
- case VN_XFSTAT: /* xferstatus */
- x = xferstat; /* Like success */
- if (x > -1) x = (x == 0) ? 1 : 0; /* External value is reversed */
- sprintf(vvbuf,"%d",x); /* SAFE */
- return((char *)vvbuf);
-
- case VN_XFMSG: /* xfermsg */
- return((char *)epktmsg);
-
-#ifndef NOMSEND
- case VN_SNDL: { /* sendlist */
- extern int filesinlist;
- sprintf(vvbuf,"%d",filesinlist); /* SAFE */
- return((char *)vvbuf);
- }
-#endif /* NOMSEND */
-#endif /* NOXFER */
-
-#ifdef CK_TRIGGER
- case VN_TRIG: {
- extern char * triggerval;
- return(triggerval ? triggerval : "");
- }
-#endif /* CK_TRIGGER */
-#ifdef OS2MOUSE
-#ifdef OS2
- case VN_MOU_X: {
- extern int MouseCurX;
- sprintf(vvbuf,"%d",MouseCurX); /* SAFE */
- return((char *)vvbuf);
- }
- case VN_MOU_Y: {
- extern int MouseCurY;
- sprintf(vvbuf,"%d",MouseCurY); /* SAFE */
- return((char *)vvbuf);
- }
-#endif /* OS2 */
-#endif /* OS2MOUSE */
- case VN_PRINT: {
- extern int printpipe;
- extern char * printername;
-#ifdef PRINTSWI
- extern int noprinter;
- if (noprinter) return("");
-#endif /* PRINTSWI */
- ckmakmsg(vvbuf,VVBUFL,
- printpipe ? "|" : "",
- printername ? printername :
-#ifdef OS2
- "PRN",
-#else
- "(default)",
-#endif /* OS2 */
- NULL,
- NULL
- );
- return((char *)vvbuf);
- }
- } /* Break up long switch statements... */
-
- switch(y) {
- case VN_ESC: /* Escape character */
- sprintf(vvbuf,"%d",escape); /* SAFE */
- return((char *)vvbuf);
-
- case VN_INTIME:
- sprintf(vvbuf,"%ld",inetime); /* SAFE */
- return((char *)vvbuf);
-
- case VN_INTMO:
- sprintf(vvbuf,"%d",inwait); /* SAFE */
- return((char *)vvbuf);
-
- case VN_SECURE:
- if (0
-#ifdef SSHBUILTIN
- || IS_SSH()
-#endif /* SSHBUILTIN */
-#ifdef CK_ENCRYPTION
- || ck_tn_encrypting() && ck_tn_decrypting()
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- || tls_active_flag || ssl_active_flag
-#endif /* CK_SSL */
- )
- return("1");
- else
- return("0");
-
- case VN_AUTHN:
-#ifdef CK_AUTHENTICATION
- {
- extern char szUserNameAuthenticated[];
- return((char *)szUserNameAuthenticated);
- }
-#else /* CK_AUTHENTICATION */
- return((char *)"");
-#endif /* CK_AUTHENTICATION */
-
- case VN_AUTHS:
-#ifdef CK_AUTHENTICATION
- switch (ck_tn_auth_valid()) {
- case AUTH_UNKNOWN:
- return((char *)"unknown");
- case AUTH_OTHER:
- return((char *)"other");
- case AUTH_USER:
- return((char *)"user");
- case AUTH_VALID:
- return((char *)"valid");
- case AUTH_REJECT:
- default:
- return((char *)"rejected");
- }
-#else /* CK_AUTHENTICATION */
- return((char *)"rejected");
-#endif /* CK_AUTHENTICATION */
-
- case VN_AUTHT:
-#ifdef CK_AUTHENTICATION
-#ifdef CK_SSL
- if ((ssl_active_flag || tls_active_flag) &&
- ck_tn_auth_valid() == AUTH_VALID &&
- (sstelnet ? (!TELOPT_U(TELOPT_AUTHENTICATION)) :
- (!TELOPT_ME(TELOPT_AUTHENTICATION))) ||
- ck_tn_authenticated() == AUTHTYPE_NULL ||
- ck_tn_authenticated() == AUTHTYPE_AUTO)
- return("X_509_CERTIFICATE");
- else
-#endif /* CK_SSL */
- return(AUTHTYPE_NAME(ck_tn_authenticated()));
-#else /* CK_AUTHENTICATION */
- return((char *)"NULL");
-#endif /* CK_AUTHENTICATION */
-
-#ifdef CK_KERBEROS
- case VN_K4PRN: {
- extern char * krb4_d_principal;
- if (krb4_d_principal)
- ckstrncpy(vvbuf,krb4_d_principal,VVBUFL+1);
- else
- *vvbuf = NUL;
- return((char *)vvbuf);
- }
- case VN_K5PRN: {
- extern char * krb5_d_principal;
- if (krb5_d_principal)
- ckstrncpy(vvbuf,krb5_d_principal,VVBUFL+1);
- else
- *vvbuf = NUL;
- return((char *)vvbuf);
- }
- case VN_K4RLM: {
- extern char * krb4_d_realm;
- if (krb4_d_realm) {
- ckstrncpy(vvbuf,krb4_d_realm,VVBUFL+1);
- } else {
- char * s = ck_krb4_getrealm();
- ckstrncpy(vvbuf,s ? s : "",VVBUFL+1);
- }
- return((char *)vvbuf);
- }
- case VN_K4SRV: {
- extern char * krb4_d_srv;
- if (krb4_d_srv)
- ckstrncpy(vvbuf,krb4_d_srv,VVBUFL+1);
- else
- ckstrncpy(vvbuf,"rcmd",VVBUFL);
- return((char *)vvbuf);
- }
- case VN_K5RLM: {
- extern char * krb5_d_realm;
- extern char * krb5_d_cc;
- if (krb5_d_realm) {
- ckstrncpy(vvbuf,krb5_d_realm,VVBUFL+1);
- } else {
- char * s = ck_krb5_getrealm(krb5_d_cc);
- ckstrncpy(vvbuf,s,VVBUFL+1);
- }
- return((char *)vvbuf);
- }
- case VN_K5CC: {
- extern char * krb5_d_cc;
- if (krb5_d_cc)
- ckstrncpy(vvbuf,krb5_d_cc,VVBUFL+1);
- else
- ckstrncpy(vvbuf,ck_krb5_get_cc_name(),VVBUFL+1);
- return((char *)vvbuf);
- }
- case VN_K5SRV: {
- extern char * krb5_d_srv;
- if (krb5_d_srv)
- ckstrncpy(vvbuf,krb5_d_srv,VVBUFL+1);
- else
- ckstrncpy(vvbuf,"host",VVBUFL);
- return((char *)vvbuf);
- }
- case VN_K4ENO: {
- extern int krb4_errno;
- sprintf(vvbuf,"%d",krb4_errno); /* SAFE */
- return((char *)vvbuf);
- }
- case VN_K5ENO: {
- extern int krb5_errno;
- sprintf(vvbuf,"%d",krb5_errno); /* SAFE */
- return((char *)vvbuf);
- }
- case VN_K4EMSG: {
- extern char * krb4_errmsg;
- ckstrncpy(vvbuf,krb4_errmsg?krb4_errmsg:"",VVBUFL+1);
- return((char *)vvbuf);
- }
- case VN_K5EMSG: {
- extern char * krb5_errmsg;
- ckstrncpy(vvbuf,krb5_errmsg,VVBUFL+1);
- return((char *)vvbuf);
- }
-#endif /* CK_KERBEROS */
-#ifdef CK_SSL
- case VN_X509_S:
- if (ssl_active_flag)
- ckstrncpy(vvbuf,ssl_get_subject_name(ssl_con),VVBUFL+1);
- else if (tls_active_flag)
- ckstrncpy(vvbuf,ssl_get_subject_name(tls_con),VVBUFL+1);
- else
- ckstrncpy(vvbuf,"",VVBUFL+1);
- return((char *)vvbuf);
- case VN_X509_I:
- if (ssl_active_flag)
- ckstrncpy(vvbuf,ssl_get_issuer_name(ssl_con),VVBUFL+1);
- else if (tls_active_flag)
- ckstrncpy(vvbuf,ssl_get_issuer_name(tls_con),VVBUFL+1);
- else
- ckstrncpy(vvbuf,"",VVBUFL+1);
- return((char *)vvbuf);
-#endif /* CK_SSL */
-
- case VN_OSNAM:
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest)
- return("");
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-#ifdef CK_UTSNAME
- {
- extern char unm_nam[];
- return((char *)unm_nam);
- }
-#else
- for (x = y = 0; x < VVBUFL; x++) {
- if (ckxsys[x] == SP && cx == 0) continue;
- vvbuf[y++] = (char) ((ckxsys[x] == SP) ? '_' : ckxsys[x]);
- }
- vvbuf[y] = NUL;
- return(vvbuf);
-#endif /* CK_UTSNAME */
-
- case VN_OSVER: {
-#ifdef CK_UTSNAME
- extern char unm_ver[];
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest)
- return("");
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- return((char *)unm_ver);
-#else
- return("");
-#endif /* CK_UTSNAME */
- }
-
- case VN_OSREL: {
-#ifdef CK_UTSNAME
- extern char unm_rel[];
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest)
- return("");
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- return((char *)unm_rel);
-#else
- return("");
-#endif /* CK_UTSNAME */
- }
- } /* Break up long switch statements... */
-
- switch(y) {
- case VN_NAME: {
- extern char * myname;
- return(myname);
- }
-
- case VN_MODL: {
-#ifdef CK_UTSNAME
- extern char unm_mod[], unm_mch[];
- int y = VVBUFL - 1;
- char * s = unm_mod;
-#endif /* CK_UTSNAME */
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest)
- return("");
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-
-#ifdef COMMENT /* was HPUX */
- if (!unm_mod[0] && !nopush)
- zzstring("\\fcommand(model)",&s,&y);
-/*
- Another possibility would be:
- "\\fcommand(ksh -c 'whence model 1>&- && model || uname -m')"
- But that would depend on having ksh.
-*/
-#else
-#ifdef OSF32 /* Digital UNIX 3.2 and higher... */
-/* Note: Ultrix has /etc/sizer, but it is not publicly executable. */
-/* sizer -c outputs 'cpu:<tab><tab>"DECxxxx"' */
- if (!unm_mod[0]) {
- char * p;
- int flag = 0;
- zzstring("\\fcommand(/usr/sbin/sizer -c)",&s,&y);
- debug(F110,"DU model",unm_mod,0);
- s = unm_mod;
- p = unm_mod;
- while (*p) { /* Extract the part in quotes */
- if (*p == '"') {
- if (flag)
- break;
- flag = 1;
- p++;
- continue;
- }
- if (flag)
- *s++ = *p;
- p++;
- }
- *s = NUL;
- }
-#endif /* OSF32 */
-#endif /* COMMENT */
-
-#ifdef CK_UTSNAME
- if (unm_mod[0])
- return((char *)unm_mod);
- else
- return((char *)unm_mch);
-#else
- return("");
-#endif /* CK_UTSNAME */
- }
-
-#ifdef IBMX25
- /* X.25 variables (local and remote address) */
- case VN_X25LA:
- if (!local_nua[0] && !x25local_nua(local_nua))
- *vvbuf = NULL;
- else
- ckstrncpy(vvbuf,local_nua,VVBUFL+1);
- return((char *)vvbuf);
-
- case VN_X25RA:
- if (!remote_nua[0])
- *vvbuf = NULL;
- else
- ckstrncpy(vvbuf,remote_nua,VVBUFL+1);
- return((char *)vvbuf);
-#endif /* IBMX25 */
-
-#ifndef NODIAL
- case VN_PDSFX: {
- extern char pdsfx[];
- return((char *)pdsfx);
- }
- case VN_DTYPE: {
- extern int dialtype;
- sprintf(vvbuf,"%d",dialtype); /* SAFE */
- return((char *)vvbuf);
- }
-#endif /* NODIAL */
-
-#ifdef UNIX
- case VN_LCKPID: {
- extern char lockpid[];
- return((char *)lockpid);
- }
-#endif /* UNIX */
-
-#ifndef NOXFER
- case VN_BLK:
- sprintf(vvbuf,"%d",bctr); /* SAFE */
- return((char *)vvbuf);
-
- case VN_TFTIM:
- sprintf(vvbuf, /* SAFE */
-#ifdef GFTIMER
- "%ld", (long)(fptsecs + 0.5)
-#else
- "%d", tsecs
-#endif /* GFTIMER */
- );
- return((char *)vvbuf);
-#endif /* NOXFER */
-
- case VN_HWPAR:
- case VN_SERIAL: {
- int sb;
- char c, * ss;
- extern int stopbits;
- vvbuf[0] = NUL;
- if (hwparity && local && !network)
- ss = parnam((char)hwparity);
- else
- ss = parnam((char)parity);
- if (cx == VN_HWPAR) {
- ckstrncpy(vvbuf,ss,VVBUFL);
- return((char *)vvbuf);
- }
- c = ss[0];
- if (islower(c)) c = toupper(c);
- sb = stopbits;
- if (sb < 1)
- sb = (speed > 0 && speed <= 110L) ? 2 : 1;
- if (hwparity)
- sprintf(vvbuf," 8%c%d",c,sb); /* SAFE */
- else if (parity)
- sprintf(vvbuf," 7%c%d",c,sb); /* SAFE */
- else
- sprintf(vvbuf," 8N%d",sb); /* SAFE */
- return((char *)vvbuf);
- }
-
-#ifdef UNIX
- case VN_LCKDIR: {
-#ifndef NOUUCP
- extern char * uucplockdir;
- ckstrncpy(vvbuf,uucplockdir,VVBUFL);
- x = strlen(vvbuf);
- if (x > 0) {
- if (vvbuf[x-1] != '/') {
- vvbuf[x] = '/';
- vvbuf[x+1] = NUL;
- }
- }
-#else
- vvbuf[0] = NUL;
-#endif /* NOUUCP */
- return((char *)vvbuf);
- }
-#endif /* UNIX */
- } /* Break up long switch statements... */
-
- switch(y) {
-#ifndef NODIAL
- case VN_DM_LP:
- case VN_DM_SP:
- case VN_DM_PD:
- case VN_DM_TD:
- case VN_DM_WA:
- case VN_DM_WD:
- case VN_DM_HF:
- case VN_DM_WB:
- case VN_DM_RC: {
- extern char * getdm();
- ckstrncpy(vvbuf,getdm(y),VVBUFL);
- return((char *)vvbuf);
- }
-#endif /* NODIAL */
-
- case VN_TY_LN:
- case VN_TY_LC: {
- extern int typ_lines;
- sprintf(vvbuf,"%d",typ_lines); /* SAFE */
- return((char *)vvbuf);
- }
- case VN_TY_LM: {
- extern int typ_mtchs;
- sprintf(vvbuf,"%d",typ_mtchs); /* SAFE */
- return((char *)vvbuf);
- }
- case VN_MACLVL:
- sprintf(vvbuf,"%d",maclvl); /* SAFE */
- return((char *)vvbuf);
- } /* Break up long switch statements... */
-
- switch(y) {
-#ifndef NOLASTFILE
- case VN_LASTFIL: {
- extern char * lastfile;
- return(lastfile ? lastfile : "");
- }
-#endif /* NOLASTFILE */
-#ifndef NOXFER
- case VN_XF_BC:
- sprintf(vvbuf,"%d",crunched); /* SAFE */
- return((char *)vvbuf);
-
- case VN_XF_TM:
- sprintf(vvbuf,"%d",timeouts); /* SAFE */
- return((char *)vvbuf);
-
- case VN_XF_RX:
- sprintf(vvbuf,"%d",retrans); /* SAFE */
- return((char *)vvbuf);
-#endif /* NOXFER */
-
- case VN_MS_CD: /* Modem signals */
- case VN_MS_CTS:
- case VN_MS_DSR:
- case VN_MS_DTR:
- case VN_MS_RI:
- case VN_MS_RTS: {
- int x, z = -1;
- x = ttgmdm(); /* Try to get them */
- if (x > -1) {
- switch (y) {
- case VN_MS_CD: z = (x & BM_DCD) ? 1 : 0; break;
- case VN_MS_DSR: z = (x & BM_DSR) ? 1 : 0; break;
- case VN_MS_CTS: z = (x & BM_CTS) ? 1 : 0; break;
-#ifdef MAC
- case VN_MS_DTR: z = (x & BM_DTR) ? 1 : 0; break;
-#else
-#ifndef STRATUS
- case VN_MS_RI: z = (x & BM_RNG) ? 1 : 0; break;
-#ifndef NT
- case VN_MS_DTR: z = (x & BM_DTR) ? 1 : 0; break;
- case VN_MS_RTS: z = (x & BM_RTS) ? 1 : 0; break;
-#endif /* NT */
-#endif /* STRATUS */
-#endif /* MAC */
- }
- }
- sprintf(vvbuf,"%d",z); /* SAFE */
- return((char *)vvbuf);
- }
- case VN_MATCH: /* INPUT MATCH */
- return(inpmatch ? inpmatch : "");
-
-#ifdef CKFLOAT
- case VN_ISCALE: /* INPUT SCALE-FACTOR */
- return(inpscale ? inpscale : "1.0");
-#endif /* CKFLOAT */
-
- case VN_SLMSG: { /* SET LINE / HOST message */
- extern char * slmsg;
- vvbuf[0] = NUL;
- if (slmsg)
- ckstrncpy(vvbuf,slmsg,VVBUFL);
- return(vvbuf);
- }
-
- case VN_TXTDIR: /* TEXTDIR */
- return(k_info_dir ? k_info_dir : "");
-
-#ifdef FNFLOAT
- case VN_MA_PI:
- return(math_pi);
-
- case VN_MA_E:
- return(math_e);
-
- case VN_MA_PR:
- sprintf(vvbuf,"%d",fp_digits); /* SAFE */
- return(vvbuf);
-#endif /* FNFLOAT */
-
- case VN_CMDBL:
- sprintf(vvbuf,"%d",CMDBL); /* SAFE */
- return(vvbuf);
-
-#ifdef CKCHANNELIO
- case VN_FERR: {
- extern int z_error;
- sprintf(vvbuf,"%d",z_error); /* SAFE */
- return(vvbuf);
- }
- case VN_FMAX: {
- extern int z_maxchan;
- sprintf(vvbuf,"%d",z_maxchan); /* SAFE */
- return(vvbuf);
- }
- case VN_FCOU: {
- extern int z_filcount;
- sprintf(vvbuf,"%d",z_filcount); /* SAFE */
- return(vvbuf);
- }
-#endif /* CKCHANNELIO */
-
-#ifndef NODIAL
- case VN_DRTR: {
- extern int dialcount;
- sprintf(vvbuf,"%d",dialcount); /* SAFE */
- return(vvbuf);
- }
-#endif /* NODIAL */
-
-#ifndef NOLOGDIAL
-#ifndef NOLOCAL
- case VN_CXTIME:
- sprintf(vvbuf,"%ld",dologshow(0)); /* SAFE */
- return(vvbuf);
-#endif /* NOLOCAL */
-#endif /* NOLOGDIAL */
-
- case VN_BYTE:
- sprintf(vvbuf,"%d",byteorder); /* SAFE */
- return(vvbuf);
-
- case VN_KBCHAR:
- vvbuf[0] = NUL;
- vvbuf[1] = NUL;
- if (kbchar > 0)
- vvbuf[0] = (kbchar & 0xff);
- return(vvbuf);
-
- case VN_TTYNAM: {
-#ifdef HAVECTTNAM
- extern char cttnam[];
- return((char *)cttnam);
-#else
- return(CTTNAM);
-#endif /* HAVECTTNAM */
- }
-
- case VN_PROMPT:
- return(cmgetp());
-
- case VN_BUILD: {
- extern char * buildid;
- return(buildid);
- }
-
-#ifndef NOSEXP
- case VN_SEXP: {
- extern char * lastsexp;
- return(lastsexp ? lastsexp : "");
- }
- case VN_VSEXP: {
- extern char * sexpval;
- return(sexpval ? sexpval : "");
- }
- case VN_LSEXP: {
- extern int sexpdep;
- ckstrncpy(vvbuf,ckitoa(sexpdep),VVBUFL);
- return(vvbuf);
- }
-#endif /* NOSEXP */
-
-#ifdef GFTIMER
- case VN_FTIME: {
- CKFLOAT f;
- ztime(&p);
- if (p == NULL || *p == NUL)
- return(NULL);
- z = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
- f = (CKFLOAT)z + ((CKFLOAT)ztusec) / 1000000.0;
- sprintf(vvbuf,"%f",f); /* SAFE */
- return(vvbuf);
- }
-#endif /* GFTIMER */
-
-#ifndef NOHTTP
- case VN_HTTP_C: { /* HTTP Code */
- extern int http_code;
- return(ckitoa(http_code));
- }
- case VN_HTTP_N: /* HTTP Connected */
- return( http_isconnected() ? "1" : "0");
- case VN_HTTP_H: /* HTTP Host */
- return( (char *)http_host() );
- case VN_HTTP_M: { /* HTTP Message */
- extern char http_reply_str[];
- return((char *)http_reply_str);
- }
- case VN_HTTP_S: /* HTTP Security */
- return((char *)http_security());
-#endif /* NOHTTP */
-
-#ifdef NEWFTP
- case VN_FTP_B:
- return((char *)ftp_cpl_mode());
- case VN_FTP_D:
- return((char *)ftp_dpl_mode());
- case VN_FTP_Z:
- return((char *)ftp_authtype());
- case VN_FTP_C: {
- extern int ftpcode;
- return(ckitoa(ftpcode));
- }
- case VN_FTP_M: {
- extern char ftp_reply_str[];
- if (isdigit(ftp_reply_str[0]) &&
- isdigit(ftp_reply_str[1]) &&
- isdigit(ftp_reply_str[2]) &&
- ftp_reply_str[3] == ' ')
- return(&ftp_reply_str[4]);
- else
- return(ftp_reply_str);
- }
- case VN_FTP_S: {
- extern char ftp_srvtyp[];
- return((char *)ftp_srvtyp);
- }
- case VN_FTP_H: {
- extern char * ftp_host;
- return(ftp_host ? ftp_host : "");
- }
- case VN_FTP_X: { /* FTP Connected */
- return(ftpisconnected() ? "1" : "0");
- }
- case VN_FTP_L: { /* FTP Logged in */
- return(ftpisloggedin() ? "1" : "0");
- }
- case VN_FTP_G: { /* FTP GET-PUT-REMOTE */
- extern int ftpget;
- char * s = "";
- switch (ftpget) {
- case 0: s = "kermit"; break;
- case 1: s = "ftp"; break;
- case 2: s = "auto"; break;
- }
- return(s);
- }
-#endif /* NEWFTP */
-
-#ifndef NOLOCAL
- case VN_CX_STA: { /* CONNECT status */
- extern int cx_status;
- return(ckitoa(cx_status));
- }
-#endif /* NOLOCAL */
- case VN_NOW: /* Timestamp */
- return(ckcvtdate(p,0));
-
- case VN_HOUR: /* Hour of the day */
- ztime(&p); /* "Thu Feb 8 12:00:00 1990" */
- if (!p) p = "";
- if (!*p) return(p);
- vvbuf[0] = p[11];
- vvbuf[1] = p[12];
- vvbuf[2] = NUL;
- return(vvbuf); /* and return it */
-
- case VN_BITS: /* Bits (16, 32, 64) */
- if (sizeof(long) > 4)
- return(ckitoa(8*sizeof(long)));
- else
- return(ckitoa(8*sizeof(int)));
-
- case VN_LASTKWV: /* 212 */
- return(lastkwval ? lastkwval : "");
-
- case VN_HOSTIP: { /* 212 */
-#ifdef TCPSOCKET
- extern char hostipaddr[];
- return((char *)hostipaddr);
-#else
- return("");
-#endif /* TCPSOCKET */
- }
- case VN_INPMSG:
- switch (instatus) {
- case INP_OK: return("SUCCESS");
- case INP_TO: return("Timed out");
- case INP_UI: return("Keyboard interrupt");
- case INP_IE: return("Internal error");
- case INP_IO: return("I/O error or connection lost");
- case INP_IKS: return("INPUT disabled");
- case INP_BF: return("Buffer filled and /NOWRAP set");
- default: return("Unknown");
- }
-
- case VN_VAREVAL: /* 212 */
- return(vareval ? "recursive" : "simple");
-
- case VN_LOG_CON: /* \v(...) for log files */
-#ifdef CKLOGDIAL
- return(diafil);
-#else
- return("");
-#endif
- case VN_LOG_PKT:
-#ifndef NOXFER
- return(pktfil);
-#else
- return("");
-#endif
- case VN_LOG_SES:
-#ifndef NOLOCAL
- return(sesfil);
-#else
- return("");
-#endif
- case VN_LOG_TRA:
-#ifdef TLOG
- return(trafil);
-#else
- return("");
-#endif
- case VN_LOG_DEB:
-#ifdef DEBUG
- return(debfil);
-#else
- return("");
-#endif
- case VN_PREVCMD: {
- extern char * prevcmd;
- return(prevcmd ? prevcmd : "");
- }
- }
-
-#ifndef NODIAL
- switch (y) { /* Caller ID values */
- extern char
- * callid_date, * callid_time, * callid_name,
- * callid_nmbr, * callid_mesg;
-
- case VN_CI_DA:
- return(callid_date ? callid_date : "");
-
- case VN_CI_TI:
- return(callid_time ? callid_time : "");
-
- case VN_CI_NA:
- return(callid_name ? callid_name : "");
-
- case VN_CI_NU:
- return(callid_nmbr ? callid_nmbr : "");
-
- case VN_CI_ME:
- return(callid_mesg ? callid_mesg : "");
-
- } /* End of variable-name switches */
-#endif /* NODIAL */
-
-#ifdef NT
- switch (y) {
- case VN_PERSONAL:
- p = (char *)GetPersonal();
- if (p) {
- GetShortPathName(p,vvbuf,VVBUFL);
- return(vvbuf);
- }
- return("");
- case VN_DESKTOP:
- p = (char *)GetDesktop();
- if (p) {
- GetShortPathName(p,vvbuf,VVBUFL);
- return(vvbuf);
- }
- return("");
- case VN_COMMON:
- p = (char *)GetAppData(1);
- if (p) {
- ckmakmsg(vvbuf,VVBUFL,p,"Kermit 95/",NULL,NULL);
- GetShortPathName(vvbuf,vvbuf,VVBUFL);
- return(vvbuf);
- }
- return("");
- case VN_APPDATA:
- p = (char *)GetAppData(0);
- if (p) {
- ckmakmsg(vvbuf,VVBUFL,p,"Kermit 95/",NULL,NULL);
- GetShortPathName(vvbuf,vvbuf,VVBUFL);
- return(vvbuf);
- }
- return("");
- }
-#endif /* NT */
-
-#ifdef TN_COMPORT
- switch (y) {
- case VN_TNC_SIG: {
- p = (char *) tnc_get_signature();
- ckstrncpy(vvbuf,p ? p : "",VVBUFL);
- return(vvbuf);
- }
- }
-#endif /* TN_COMPORT */
-
-#ifdef KUI
- switch (y) {
- case VN_GUI_RUN: {
- extern HWND getHwndKUI();
- if ( IsIconic(getHwndKUI()) )
- return("minimized");
- if ( IsZoomed(getHwndKUI()) )
- return("maximized");
- return("restored");
- }
- case VN_GUI_XP:
- sprintf(vvbuf,"%d",get_gui_window_pos_x()); /* SAFE */
- return(vvbuf);
- case VN_GUI_YP:
- sprintf(vvbuf,"%d",get_gui_window_pos_y()); /* SAFE */
- return(vvbuf);
- case VN_GUI_XR:
- sprintf(vvbuf,"%d",GetSystemMetrics(SM_CXSCREEN)); /* SAFE */
- return(vvbuf);
- case VN_GUI_YR:
- sprintf(vvbuf,"%d",GetSystemMetrics(SM_CYSCREEN)); /* SAFE */
- return(vvbuf);
- case VN_GUI_FNM:
- if ( ntermfont > 0 ) {
- int i;
- for (i = 0; i < ntermfont; i++) {
- if (tt_font == term_font[i].kwval) {
- ckstrncpy(vvbuf,term_font[i].kwd,VVBUFL);
- return(vvbuf);
- }
- }
- }
- return("(unknown)");
- case VN_GUI_FSZ:
- ckstrncpy(vvbuf,ckitoa(tt_font_size/2),VVBUFL);
- if ( tt_font_size % 2 )
- ckstrncat(vvbuf,".5",VVBUFL);
- return(vvbuf);
- }
-#endif /* KUI */
-
- fnsuccess = 0;
- if (fnerror) {
- fnsuccess = 0;
- }
- if (fndiags) {
- if (!embuf[0])
- ckstrncpy(embuf,"<ERROR:NO_SUCH_VARIABLE>",EMBUFLEN);
- printf("?%s\n",embuf);
- return((char *)embuf);
- } else
- return("");
-}
-#endif /* NOSPL */
-
-
-/*
- X X S T R I N G -- Expand variables and backslash codes.
-
- int xxtstring(s,&s2,&n);
-
- Expands \ escapes via recursive descent.
- Argument s is a pointer to string to expand (source).
- Argument s2 is the address of where to put result (destination).
- Argument n is the length of the destination string (to prevent overruns).
- Returns -1 on failure, 0 on success,
- with destination string null-terminated and s2 pointing to the
- terminating null, so that subsequent characters can be added.
- Failure reasons include destination buffer is filled up.
-*/
-
-#define XXDEPLIM 100 /* Recursion depth limit */
-/*
- In Windows the stack is limited to 256K so big character arrays like
- vnambuf can't be on the stack in recursive functions like zzstring().
- But that's no reason use malloc() in Unix or VMS, which don't have
- this kind of restriction.
-*/
-#ifdef DVNAMBUF /* Dynamic vnambuf[] */
-#undef DVNAMBUF /* Clean slate */
-#endif /* DVNAMBUF */
-
-#ifndef NOSPL /* Only if SPL included */
-#ifdef OS2 /* Only for K95 */
-#define DVNAMBUF
-#endif /* OS2 */
-#endif /* NOSPL */
-
-int
-zzstring(s,s2,n) char *s; char **s2; int *n; {
- int x, /* Current character */
- y, /* Worker */
- pp, /* Paren level */
- kp, /* Brace level */
- argn, /* Function argument counter */
- n2, /* Local copy of n */
- d, /* Array dimension */
- vbi, /* Variable id (integer form) */
- argl, /* String argument length */
- nx, /* Save original length */
- quoting = 0; /* 299 */
-
- char vb, /* Variable id (char form) */
- *vp, /* Pointer to variable definition */
- *new, /* Local pointer to target string */
-#ifdef COMMENT
- *old, /* Save original target pointer */
-#endif /* COMMENT */
- *p, /* Worker */
- *q, /* Worker */
- *s3; /* Worker */
- int x3; /* Worker */
- char *r = (char *)0; /* For holding function args */
- char *r2 = (char *)0;
- char *r3p;
-
-#ifndef NOSPL
-#ifdef DVNAMBUF
- char * vnambuf = NULL; /* Buffer for variable/function name */
-#else /* DVNAMBUF */
- char vnambuf[VNAML]; /* Buffer for variable/function name */
-#endif /* DVNAMBUF */
- char *argp[FNARGS]; /* Pointers to function args */
-#endif /* NOSPL */
-
- static int depth = 0; /* Call depth, avoid overflow */
-
- n2 = *n; /* Make local copies of args */
- nx = n2;
-
-#ifdef COMMENT
- /* This is always 32K in BIGBUFOK builds */
- if (depth == 0)
- debug(F101,"zzstring top-level n","",n2);
-#endif /* COMMENT */
-
- new = *s2; /* for one less level of indirection */
-#ifdef COMMENT
- old = new;
-#endif /* COMMENT */
-
-#ifndef NOSPL
- itsapattern = 0; /* For \fpattern() */
- isjoin = 0; /* For \fjoin() */
-#endif /* NOSPL */
- depth++; /* Sink to a new depth */
- if (depth > XXDEPLIM) { /* Too deep? */
- printf("?definition is circular or too deep\n");
- debug(F101,"zzstring fail","",depth);
- depth = 0;
- *new = NUL;
- return(-1);
- }
- if (!s || !new) { /* Watch out for null pointers */
- debug(F101,"zzstring fail 2","",depth);
- if (new)
- *new = NUL;
- depth = 0;
- return(-1);
- }
- s3 = s;
- argl = 0;
- while (*s3++) argl++; /* Get length of source string */
- debug(F010,"zzstring entry",s,0);
- if (argl == 0) { /* Empty string */
- debug(F111,"zzstring empty arg",s,argl);
- depth = 0;
- *new = NUL;
- return(0);
- }
- if (argl < 0) { /* Watch out for garbage */
- debug(F101,"zzstring fail 3","",depth);
- *new = NUL;
- depth = 0;
- return(-1);
- }
-#ifdef DVNAMBUF
- debug(F100,"vnambuf malloc...","",0);
- vnambuf = malloc(VNAML);
- if (vnambuf == NULL) {
- printf("?Out of memory");
- return(-1);
- }
- debug(F100,"vnambuf malloc ok","",0);
-#endif /* DVNAMBUF */
-
- while ((x = *s)) { /* Loop for all characters */
- if (x != CMDQ) { /* Is it the command-quote char? */
- *new++ = *s++; /* No, normal char, just copy */
- if (--n2 < 0) { /* and count it, careful of overflow */
- debug(F101,"zzstring overflow 1","",depth);
- depth = 0;
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- continue;
- }
-
-/* We have the command-quote character. */
-
- x = *(s+1); /* Get the following character. */
- if (isupper(x)) x = tolower(x);
- switch (x) { /* Act according to variable type */
-#ifndef NOSPL
- case 0: /* It's a lone backslash */
- *new++ = *s++;
- if (--n2 < 0) {
- debug(F101,"zzstring overflow 2","",0);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- break;
- case '%': /* Variable */
- s += 2; /* Get the letter or digit */
- vb = *s++; /* and move source pointer past it */
- vp = NULL; /* Assume definition is empty */
- if (vb >= '0' && vb <= '9') { /* Digit for macro arg */
- if (maclvl < 0) /* Digit variables are global */
- vp = g_var[vb]; /* if no macro is active */
- else /* otherwise */
- vp = m_arg[maclvl][vb - '0']; /* they're on the stack */
- } else if (vb == '*') { /* Macro args string */
-#ifdef COMMENT
- /* This doesn't take changes into account */
- vp = (maclvl >= 0) ? m_line[maclvl] : topline;
- if (!vp) vp = "";
-#else
- char * ss = new;
- if (zzstring("\\fjoin(&_[],,1)",&new,&n2) < 0) {
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- debug(F110,"zzstring \\%*",ss,0);
- break;
-#endif /* COMMENT */
- } else {
- if (isupper(vb)) vb += ('a'-'A');
- vp = g_var[vb]; /* Letter for global variable */
- }
- if (!vp) vp = "";
-#ifdef COMMENT
- if (vp) { /* If definition not empty */
-#endif /* COMMENT */
- if (vareval) {
- debug(F010,"zzstring %n vp",vp,0);
- /* call self to evaluate it */
- if (zzstring(vp,&new,&n2) < 0) {
- debug(F101,"zzstring fail 6","",depth);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1); /* Pass along failure */
- }
- } else {
- while ((*new++ = *vp++)) /* copy it to output string. */
- if (--n2 < 0) {
- if (q) free(q);
- debug(F101,"zzstring overflow 4.5","",depth);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- new--; /* Back up over terminating null */
- n2++; /* to allow for further deposits. */
- }
-#ifdef COMMENT
- } else {
- debug(F110,"zzstring %n vp","(NULL)",0);
- n2 = nx;
- new = old;
- *new = NUL;
- }
-#endif /* COMMENT */
- break;
- case '&': /* An array reference */
- x = arraynam(s,&vbi,&d); /* Get name and subscript */
- debug(F111,"zzstring arraynam",s,x);
- if (x < 0) {
- debug(F101,"zzstring fail 7","",depth);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- pp = 0; /* Bracket counter */
- while (*s) { /* Advance source pointer... */
- if (*s == '[') pp++;
- if (*s == ']' && --pp == 0) break;
- s++;
- }
- if (*s == ']') s++; /* ...past the closing bracket. */
-
- x = chkarray(vbi,d); /* Array is declared? */
- debug(F101,"zzstring chkarray","",x);
- if (x > -1) {
-#ifdef COMMENT
- char * s1 = NULL;
-#endif /* COMMENT */
- vbi -= ARRAYBASE; /* Convert name to index */
-
- if (a_dim[vbi] >= d) { /* If subscript in range */
- char **ap;
- ap = a_ptr[vbi]; /* get data pointer */
- if (ap) { /* and if there is one */
- if (ap[d]) { /* If definition not empty */
- debug(F111,"zzstring ap[d]",ap[d],d);
- if (vareval) {
- if (zzstring(ap[d],&new,&n2) < 0) {
- debug(F101,"zzstring fail 8","",depth);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1); /* Pass along failure */
- }
- } else {
- vp = ap[d];
- while ((*new++ = *vp++)) /* copy to result */
- if (--n2 < 0) {
- if (q) free(q);
- debug(F101,
- "zzstring overflow 8.5","",depth);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- new--; /* Back up over terminating null */
- n2++; /* to allow for further deposits. */
- }
- }
-
- } else {
- /* old = new; */
- n2 = nx;
- }
- }
- }
- break;
-
- case 'f': /* A builtin function */
- q = vnambuf; /* Copy the name */
- y = 0; /* into a separate buffer */
- s += 2; /* point past 'F' */
- while (y++ < VNAML) {
- if (*s == '(') { s++; break; } /* Look for open paren */
- if ((*q = *s) == NUL) break; /* or end of string */
- s++; q++;
- }
- *q = NUL; /* Terminate function name */
- if (y >= VNAML) { /* Handle pathological case */
- while (*s && (*s != '(')) /* of very long string entered */
- s++; /* as function name. */
- if (*s == ')') s++; /* Skip past it. */
- }
- r = r2 = malloc(argl+2); /* And make a place to copy args */
- /* debug(F101,"zzstring r2","",r2); */
- if (!r2) { /* Watch out for malloc failure */
- debug(F101,"zzstring fail 9","",depth);
- *new = NUL;
- depth = 0;
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- if (r3) free(r3); /* And another to copy literal arg string */
- r3 = malloc(argl+2);
- /* debug(F101,"zzstring r3","",r3); */
- if (!r3) {
- debug(F101,"zzstring fail 10","",depth);
- depth = 0;
- *new = NUL;
- if (r2) free(r2);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- } else
- r3p = r3;
- argn = 0; /* Argument counter */
- argp[argn++] = r; /* Point to first argument */
- y = 0; /* Completion flag */
- pp = 1; /* Paren level (already have one). */
- kp = 0;
- while (1) { /* Copy each argument, char by char. */
- *r3p++ = *s; /* This is a literal copy for \flit */
- if (!*s) break;
-
- if (*s == '{') { /* Left brace */
- kp++;
- }
- if (*s == '}') { /* Right brace */
- kp--;
- }
- if (*s == '(' && kp <= 0) { /* Open paren not in brace */
- pp++; /* Count it */
- }
- *r = *s; /* Now copy resulting byte */
- if (!*r) /* If NUL, done. */
- break;
- if (*r == ')' && kp <= 0) { /* Closing paren, count it. */
- if (--pp == 0) { /* Final one? */
- *r = NUL; /* Make it a terminating null */
- *(r3p - 1) = NUL;
- s++; /* Point past it in source string */
- y = 1; /* Flag we've got all the args */
- break; /* Done with while loop */
- }
- }
- if (*r == ',' && kp <= 0) { /* Comma */
- if (pp == 1) { /* If not within ()'s, */
- if (argn >= FNARGS) { /* Too many args */
- s++; r++; /* Keep collecting flit() string */
- continue;
- }
- *r = NUL; /* New arg, skip past comma */
- argp[argn++] = r+1; /* In range, point to new arg */
- } /* Otherwise just skip past */
- }
- s++; r++; /* Advance pointers */
- }
- if (!y) /* If we didn't find closing paren */
- argn = -1;
-#ifdef DEBUG
- if (deblog) {
- char buf[24];
- debug(F111,"zzstring function name",vnambuf,y);
- debug(F010,"zzstring function r3",r3,0);
- for (y = 0; y < argn; y++) {
- sprintf(buf,"arg %2d ",y);
- debug(F010,buf,argp[y],0);
- }
- }
-#endif /* DEBUG */
- {
- /* In case the function name itself is constructed */
- char buf[64]; char * p = buf; int n = 64;
- if (zzstring(vnambuf,&p,&n) > -1)
- ckstrncpy(vnambuf,buf,64);
- }
- vp = fneval(vnambuf,argp,argn,r3); /* Evaluate the function. */
- if (vp) { /* If definition not empty */
- while ((*new++ = *vp++)) { /* copy it to output string */
- if (--n2 < 0) { /* watch out for overflow */
- debug(F101,"zzstring fail 12","",depth);
- if (r2) { free(r2); r2 = NULL; }
- if (r3) { free(r3); r3 = NULL; }
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- }
- new--; /* Back up over terminating null */
- n2++; /* to allow for further deposits. */
- }
- if (r2) { free(r2); r2 = NULL; }
- if (r3) { free(r3); r3 = NULL; }
- break;
- case 'q': /* 299 String to be take literally */
- quoting = 1; /* 299 */
- case '$': /* An environment variable */
- case 'v': /* Or a named builtin variable. */
- case 'm': /* Or a macro /long variable */
- case 's': /* 196 Macro substring */
- case ':': /* 196 \-variable substring */
- pp = 0;
- p = s+2; /* $/V/M must be followed by (name) */
- if (*p != '(') { /* as in \$(HOME) or \V(count) */
- *new++ = *s++; /* If not, just copy it */
- if (--n2 < 0) {
- debug(F101,"zzstring overflow 3","",depth);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- break;
- }
- pp++;
- p++; /* Point to 1st char of name */
- q = vnambuf; /* Copy the name */
- y = 0; /* into a separate buffer */
- debug(F110,">>>> \\q(ARG)",p,0);
- while (y++ < VNAML) { /* Watch out for name too long */
- if (*p == '(') { /* Parens can be nested... */
- if (*(p-1) != CMDQ) /* 299 */
- pp++;
- } else if (*p == ')') { /* Name properly terminated with ')' */
- if (*(p-1) != CMDQ) /* 299 */
- pp--;
- if (pp == 0) {
- p++; /* Move source pointer past ')' */
- break;
- }
- }
- if ((*q = *p) == NUL) /* String ends before ')' */
- break;
- p++; q++; /* Advance pointers */
- }
- *q = NUL; /* Terminate the variable name */
- if (y >= VNAML) { /* Handle pathological case */
- while (*p && (*p != ')')) /* of very long string entered */
- p++; /* as variable name. */
- if (*p == ')') p++; /* Skip ahead to the end of it. */
- }
- s = p; /* Adjust global source pointer */
- s3 = vnambuf;
- x3 = 0;
- while (*s3++) x3++;
- p = malloc(x3 + 1); /* Make temporary space */
- if (p && !quoting) { /* If we got the space */
- vp = vnambuf; /* Point to original */
- strcpy(p,vp); /* (safe) Make a copy of it */
- y = VNAML; /* Length of name buffer */
- zzstring(p,&vp,&y); /* Evaluate the copy */
- free(p); /* Free the temporary space */
- p = NULL;
- }
- debug(F110,"zzstring vname",vnambuf,0);
- q = NULL;
- if (x == 'q') { /* 299 Quoting this string */
- vp = vnambuf; /* 299 */
- debug(F110,">>> VP",vp,0);
- } else if (x == '$') { /* Look up its value */
- vp = getenv(vnambuf); /* This way for environment variable */
- } else if (x == 'm' || x == 's' || x == ':') { /* Macro / substr */
- int k, x1 = -1, x2 = -1;
- char c = NUL;
- k = strlen(vnambuf);
- /* \s(name[n:m]) -- Compact substring notation */
- if ((x == 's' || x == ':') && (k > 1)) { /* Substring wanted */
- int bprc;
- if (vnambuf[k-1] == ']') {
- int i;
- for (i = 0; i < k-1; i++) {
- if (vnambuf[i] == '[') {
- bprc = boundspair(vnambuf,":_.",&x1,&x2,&c);
- debug(F111,"zzstring boundspair",vnambuf,bprc);
- debug(F000,"zzstring boundspair c","",c);
- if (bprc > -1) {
- vnambuf[i] = NUL;
- if (x1 < 1)
- x1 = 1;
- x1--; /* Adjust to 0-base */
- }
- break;
- }
- }
- }
- }
- if (x == ':') { /* Variable type (s or :) */
- vp = vnambuf;
- } else {
- y = isaarray(vnambuf) ?
- mxxlook(mactab,vnambuf,nmac) :
- mxlook(mactab,vnambuf,nmac);
- if (y > -1) { /* Got definition */
- vp = mactab[y].mval;
- } else {
- vp = NULL;
- }
- }
- debug(F111,"zzstring vp",vp,(vp==NULL)?0:strlen(vp));
-
- if (vp) {
- if ((x == 's' || x == ':') && (k > 1)) {
- /* Compact substring notation */
- if (x2 == 0) { /* Length */
- vp = NULL;
- } else if (x1 > -1) { /* Start */
- k = strlen(vp);
- debug(F101,">>> k","",k);
- /* If it's off the end, result is empty */
- if (x1 > k) {
- vp = NULL;
- } else if (k > 0) {
- /* Stay in bounds */
- if (c == '_' && x2 > k) /* startpos_endpos */
- x2 = k;
- if (c == ':' && x1 + x2 > k) /* start:length */
- x2 = -1;
- debug(F101,">>> x2","",x2);
- debug(F000,">>> c","",c);
- if ((q = malloc(k+1))) {
- strcpy(q,vp); /* safe */
- if (c == '.') {
- q[x1+1] = NUL;
- debug(F000,"XXX. q",q,c);
- }
- if (c == ':') { /* start:length */
- if ((x2 > -1) && ((x1 + x2) <= k)) {
- q[x1+x2] = NUL;
- }
- debug(F000,"XXX: q",q,c);
- } else if (c == '_') { /* start_endpos */
- if (x1 >= x2) {
- q[x1 = 0] = NUL;
- } else if (x2 < k && x2 > -1) {
- q[x2] = NUL;
- }
- debug(F000,"XXX_ q",q,c);
- }
- vp = q+x1;
- } else vp = NULL;
- } else vp = NULL;
- }
-
- debug(F110,"XXX vnambuf",vnambuf,0);
- debug(F000,"XXX c","",c);
- debug(F101,"XXX x1","",x1);
- debug(F101,"XXX x2","",x2);
- debug(F110,"XXX result",vp,0);
-#ifdef DEBUG
- if (deblog) {
- if (!vp) {
- } else {
- k = strlen(vp);
- }
- }
-#endif /* DEBUG */
- }
- }
- } else { /* or */
- vp = nvlook(vnambuf); /* this way for builtin variable */
- }
- if (vp) { /* If definition not empty */
- while ((*new++ = *vp++)) /* copy it to output string. */
- if (--n2 < 0) {
- if (q) free(q);
- debug(F101,"zzstring overflow 4","",depth);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- new--; /* Back up over terminating null */
- n2++; /* to allow for further deposits. */
- }
- if (q) {
- free(q);
- q = NULL;
- }
- break;
-#endif /* NOSPL */ /* Handle \nnn even if NOSPL. */
-
-#ifndef NOKVERBS
- case 'K':
- case 'k': {
- extern struct keytab kverbs[];
- extern int nkverbs;
-#define K_BUFLEN 30
- char kbuf[K_BUFLEN + 1]; /* Key verb name buffer */
- int x, y, z, brace = 0;
- s += 2;
-/*
- We assume that the verb name is {braced}, or it extends to the end of the
- string, s, or it ends with a space, control character, or backslash.
-*/
- p = kbuf; /* Copy verb name into local buffer */
- x = 0;
- if (*s == '{') {
- s++;
- brace++;
- }
- while ((x++ < K_BUFLEN) && (*s > SP) && (*s != CMDQ)) {
- if (brace && *s == '}') {
- s++;
- break;
- }
- *p++ = *s++;
- }
- brace = 0;
- *p = NUL; /* Terminate. */
- p = kbuf; /* Point back to beginning */
- debug(F110,"zzstring kverb",p,0);
- y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
- debug(F101,"zzstring lookup",0,y);
- if (y > -1) {
- dokverb(VCMD,y);
-#ifndef NOSPL
- } else { /* Is it a macro? */
- y = mxlook(mactab,p,nmac);
- if (y > -1) {
- debug(F111,"zzstring mxlook",p,y);
- if ((z = dodo(y,NULL,cmdstk[cmdlvl].ccflgs)) > 0) {
- if (cmpush() > -1) { /* Push command parser state */
- extern int ifc;
- int ifcsav = ifc; /* Push IF condition on stack */
- y = parser(1); /* New parser to execute macro */
- cmpop(); /* Pop command parser */
- ifc = ifcsav; /* Restore IF condition */
- if (y == 0) { /* No errors, ignore actions */
- p = mrval[maclvl+1]; /* If OK set return val */
- if (p == NULL) p = "";
- }
- } else { /* Can't push any more */
- debug(F101,"zzstring pushed too deep","",depth);
- printf(
- "\n?Internal error: zzstring stack overflow\n"
- );
- while (cmpop() > -1);
- p = "";
- }
- }
- }
-#endif /* NOSPL */
- }
- break;
- }
-#endif /* NOKVERBS */
-
- default: /* Maybe it's a backslash code */
- y = xxesc(&s); /* Go interpret it */
- if (y < 0) { /* Upon failure */
- *new++ = (char) x; /* Just quote the next character */
- s += 2; /* Move past the pair */
- n2 -= 2;
- if (n2 < 0) {
- debug(F101,"zzstring overflow 5","",depth);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- continue; /* and go back for more */
- } else {
- *new++ = (char) y; /* else deposit interpreted value */
- if (--n2 < 0) {
- debug(F101,"zzstring overflow 6","",depth);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(-1);
- }
- }
- }
- }
- *new = NUL; /* Terminate the new string */
- debug(F010,"zzstring while exit",*s2,0);
-
- depth--; /* Adjust stack depth gauge */
- *s2 = new; /* Copy results back into */
- *n = n2; /* the argument addresses */
- debug(F101,"zzstring ok","",depth);
-#ifdef DVNAMBUF
- if (vnambuf) free(vnambuf);
-#endif /* DVNAMBUF */
- return(0); /* and return. */
-}
-#endif /* NOICP */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus5.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuus5.c
deleted file mode 100644
index c4c8782..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus5.c
+++ /dev/null
@@ -1,12427 +0,0 @@
-#include "ckcsym.h"
-
-int xcmdsrc = 0;
-
-#ifdef NOICP
-int cmdsrc() { return(0); }
-#endif /* NOICP */
-
-/* C K U U S 5 -- "User Interface" for C-Kermit, part 5 */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/* Includes */
-
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckuusr.h"
-
-#ifdef DCMDBUF
-char *line; /* Character buffer for anything */
-char *tmpbuf;
-#else
-char line[LINBUFSIZ+1];
-char tmpbuf[TMPBUFSIZ+1]; /* Temporary buffer */
-#endif /* DCMDBUF */
-
-#ifndef NOICP
-
-#include "ckcnet.h"
-#ifndef NOCSETS
-#include "ckcxla.h"
-#endif /* NOCSETS */
-#ifdef MAC
-#include "ckmasm.h"
-#endif /* MAC */
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-
-extern char * ck_cryear; /* (ckcmai.c) Latest C-Kermit copyright year */
-
-#ifdef OS2
-#include "ckoetc.h"
-#ifndef NT
-#define INCL_NOPM
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#else /* NT */
-#include <windows.h>
-#define TAPI_CURRENT_VERSION 0x00010004
-#include <tapi.h>
-#include <mcx.h>
-#include "ckntap.h"
-#define APIRET ULONG
-extern int DialerHandle;
-extern int StartedFromDialer;
-#endif /* NT */
-#include "ckocon.h"
-#include "ckokey.h"
-#ifdef KUI
-#include "ikui.h"
-#endif /* KUI */
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) conoc(x)
-extern int cursor_save ;
-extern bool cursorena[] ;
-#endif /* OS2 */
-
-/* 2010-03-09 SMS. VAX C V3.1-051 needs <stat.h> for off_t. */
-#ifdef VMS
-#include <stat.h>
-#endif /* def VMS */
-
-/* For formatted screens, "more?" prompting, etc. */
-
-#ifdef FT18
-#define isxdigit(c) isdigit(c)
-#endif /* FT18 */
-
-#ifdef STRATUS /* Stratus Computer, Inc. VOS */
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) conoc(x)
-#ifdef getchar
-#undef getchar
-#endif /* getchar */
-#define getchar(x) coninc(0)
-#endif /* STRATUS */
-
-/* External variables */
-
-extern int carrier, cdtimo, local, quiet, backgrd, bgset, sosi, xsuspend,
- binary, escape, xargs, flow, cmdmsk, duplex, ckxech, seslog, what,
- inserver, diractive, tlevel, cwdf, nfuncs, msgflg, remappd, hints, mdmtyp,
- zincnt, cmask, rcflag, success, xitsta, pflag, tnlm, tn_nlm, xitwarn,
- debses, xaskmore, parity, saveask, wasclosed, whyclosed, cdactive,
- rcdactive, keepallchars, cmd_err;
-
-#ifdef LOCUS
-extern int locus, autolocus;
-#endif /* LOCUS */
-
-#ifndef NOMSEND
-extern int addlist;
-#endif /* NOMSEND */
-
-#ifdef CK_SPEED
-extern int prefixing;
-#endif /* CK_SPEED */
-
-extern int g_matchdot;
-
-#ifdef RECURSIVE
-extern int recursive;
-#endif /* RECURSIVE */
-extern int xfiletype;
-
-#ifdef IKSDCONF
-extern char * iksdconf;
-extern int iksdcf;
-#endif /* IKSDCONF */
-
-#ifdef CK_RECALL
-extern int on_recall;
-#endif /* CK_RECALL */
-
-extern int ngetpath, exitonclose;
-extern char * getpath[];
-extern CHAR * epktmsg;
-
-extern char * snd_move;
-extern char * snd_rename;
-extern char * rcv_move;
-extern char * rcv_rename;
-extern char * g_snd_move;
-extern char * g_snd_rename;
-extern char * g_rcv_move;
-extern char * g_rcv_rename;
-
-extern char * nm[];
-
-#ifdef CK_UTSNAME
-extern char unm_mch[];
-extern char unm_mod[];
-extern char unm_nam[];
-extern char unm_rel[];
-extern char unm_ver[];
-#endif /* CK_UTSNAME */
-
-#ifndef NOPUSH
-#ifndef NOFRILLS
-extern char editor[];
-extern char editfile[];
-extern char editopts[];
-#ifdef BROWSER
-extern char browser[];
-extern char browsopts[];
-extern char browsurl[];
-#endif /* BROWSER */
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-
-#ifndef NOFRILLS
-#ifndef NORENAME
-_PROTOTYP(VOID shorename, (void));
-#endif /* NORENAME */
-#endif /* NOFRILLS */
-
-#ifndef NOSERVER
-extern char * x_user, * x_passwd, * x_acct;
-#endif /* NOSERVER */
-
-#ifdef CKLOGDIAL
-extern int dialog;
-extern char diafil[];
-#endif /* CKLOGDIAL */
-
-#ifdef CKROOT
-extern int ckrooterr;
-#endif /* CKROOT */
-
-#ifndef NOSPL
-extern int cfilef, xxdot, vareval;
-extern char cmdfil[];
-
-struct localvar * localhead[CMDSTKL];
-struct localvar * localtail = NULL;
-struct localvar * localnext = NULL;
-
-_PROTOTYP( VOID shosexp, (void) );
-_PROTOTYP( static VOID shoinput, (void) );
-_PROTOTYP( static char gettok, (void) );
-_PROTOTYP( static VOID factor, (void) );
-_PROTOTYP( static VOID term, (void) );
-_PROTOTYP( static VOID termp, (void) );
-_PROTOTYP( static VOID exprp, (void) );
-_PROTOTYP( static VOID expr, (void) );
-_PROTOTYP( static VOID simple, (void) );
-_PROTOTYP( static VOID simpler, (void) );
-_PROTOTYP( static VOID simplest, (void) );
-_PROTOTYP( static CK_OFF_T xparse, (void) );
-#endif /* NOSPL */
-#ifndef NOSHOW
-_PROTOTYP( int sho_iks, (void) );
-#endif /* NOSHOW */
-
-#ifdef MAC
-char * ckprompt = "Mac-Kermit>"; /* Default prompt for Macintosh */
-char * ikprompt = "IKSD>";
-#else /* Not MAC */
-#ifdef NOSPL
-#ifdef OS2
-char * ckprompt = "K-95> "; /* Default prompt for Win32 */
-char * ikprompt = "IKSD> ";
-#else
-char * ckprompt = "C-Kermit>";
-char * ikprompt = "IKSD>";
-#endif /* NT */
-#else /* NOSPL */
-#ifdef OS2
-/* Default prompt for OS/2 and Win32 */
-#ifdef NT
-char * ckprompt = "[\\freplace(\\flongpath(\\v(dir)),/,\\\\)] K-95> ";
-char * ikprompt = "[\\freplace(\\flongpath(\\v(dir)),/,\\\\)] IKSD> ";
-#else /* NT */
-char * ckprompt = "[\\freplace(\\v(dir),/,\\\\)] K-95> ";
-char * ikprompt = "[\\freplace(\\v(dir),/,\\\\)] IKSD> ";
-#endif /* NT */
-#else /* OS2 */
-#ifdef VMS
-char * ckprompt = "\\v(dir) C-Kermit>"; /* Default prompt VMS */
-char * ikprompt = "\\v(dir) IKSD>";
-#else
-char * ckprompt = "(\\v(dir)) C-Kermit>"; /* Default prompt for others */
-char * ikprompt = "(\\v(dir)) IKSD>";
-#endif /* VMS */
-#endif /* NT */
-#endif /* NOSPL */
-#endif /* MAC */
-
-#ifndef CCHMAXPATH
-#define CCHMAXPATH 257
-#endif /* CCHMAXPATH */
-char inidir[CCHMAXPATH] = { NUL, NUL }; /* Directory INI file executed from */
-
-#ifdef TNCODE
-extern int tn_b_nlm; /* TELNET BINARY newline mode */
-#endif /* TNCODE */
-
-#ifndef NOKVERBS
-extern struct keytab kverbs[]; /* Table of \Kverbs */
-extern int nkverbs; /* Number of \Kverbs */
-#endif /* NOKVERBS */
-
-#ifndef NOPUSH
-extern int nopush;
-#endif /* NOPUSH */
-
-#ifdef CK_RECALL
-extern int cm_recall;
-#endif /* CK_RECALL */
-
-extern char *ccntab[];
-
-/* Printer stuff */
-
-extern char *printername;
-extern int printpipe;
-#ifdef BPRINT
-extern int printbidi, pportparity, pportflow;
-extern long pportspeed;
-#endif /* BPRINT */
-
-#ifdef OS2
-_PROTOTYP (int os2getcp, (void) );
-_PROTOTYP (int os2getcplist, (int *, int) );
-#ifdef OS2MOUSE
-extern int tt_mouse;
-#endif /* OS2MOUSE */
-extern int tt_update, tt_updmode, updmode, tt_utf8;
-#ifndef IKSDONLY
-extern int tt_status[];
-#endif /* IKSDONLY */
-#ifdef PCFONTS
-extern struct keytab term_font[];
-#else
-#ifdef KUI
-extern struct keytab * term_font;
-#endif /* KUI */
-#endif /* PCFONTS */
-extern int ntermfont, tt_font, tt_font_size;
-extern unsigned char colornormal, colorunderline, colorstatus,
- colorhelp, colorselect, colorborder, colorgraphic, colordebug,
- colorreverse, colorcmd, coloritalic;
-extern int priority;
-extern struct keytab prtytab[];
-extern int nprty;
-char * cmdmac = NULL;
-#endif /* OS2 */
-
-#ifdef VMS
-_PROTOTYP (int zkermini, (char *, int, char *) );
-#endif /* VMS */
-
-extern long vernum;
-extern int inecho, insilence, inbufsize, nvars, inintr;
-extern char *protv, *fnsv, *cmdv, *userv, *ckxv, *ckzv, *ckzsys, *xlav,
- *cknetv, *clcmds;
-#ifdef OS2
-extern char *ckyv;
-#endif /* OS2 */
-#ifdef CK_AUTHENTICATION
-extern char * ckathv;
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_SSL
-extern char * cksslv;
-#endif /* CK_SSL */
-#ifdef CK_ENCRYPTION
-#ifndef CRYPT_DLL
-extern char * ckcrpv;
-#endif /* CRYPT_DLL */
-#endif /* CK_ENCRYPTION */
-
-#ifdef SSHBUILTIN
-extern char *cksshv;
-#ifdef SFTP_BUILTIN
-extern char *cksftpv;
-#endif /* SFTP_BUILTIN */
-#endif /* SSHBUILTIN */
-
-#ifdef TNCODE
-extern char *cktelv;
-#endif /* TNCODE */
-#ifndef NOFTP
-#ifndef SYSFTP
-extern char * ckftpv;
-#endif /* SYSFTP */
-#endif /* NOFTP */
-
-extern int srvidl;
-
-#ifdef OS2
-extern char *ckonetv;
-extern int interm;
-#ifdef CK_NETBIOS
-extern char *ckonbiv;
-#endif /* CK_NETBIOS */
-#ifdef OS2MOUSE
-extern char *ckomouv;
-#endif /* OS2MOUSE */
-#endif /* OS2 */
-
-#ifndef NOLOCAL
-extern char *connv;
-#endif /* NOLOCAL */
-#ifndef NODIAL
-extern char *dialv;
-#endif /* NODIAL */
-#ifndef NOSCRIPT
-extern char *loginv;
-extern int secho;
-#endif /* NOSCRIPT */
-
-#ifndef NODIAL
-extern int nmdm, dirline;
-extern struct keytab mdmtab[];
-#endif /* NODIAL */
-
-extern int network, nettype, ttnproto;
-
-#ifdef OS2
-#ifndef NOTERM
-/* SET TERMINAL items... */
-extern int tt_type, tt_arrow, tt_keypad, tt_wrap, tt_answer, tt_scrsize[];
-extern int tt_bell, tt_roll[], tt_ctstmo, tt_cursor, tt_pacing, tt_type_mode;
-extern char answerback[];
-extern struct tt_info_rec tt_info[]; /* Indexed by terminal type */
-extern int max_tt;
-#endif /* NOTERM */
-#endif /* OS2 */
-
-_PROTOTYP( VOID shotrm, (void) );
-_PROTOTYP( int shofea, (void) );
-
-#ifdef OS2
-extern int tt_rows[], tt_cols[];
-#else /* OS2 */
-extern int tt_rows, tt_cols;
-#endif /* OS2 */
-extern int cmd_rows, cmd_cols;
-
-#ifdef CK_TMPDIR
-extern int f_tmpdir; /* Directory changed temporarily */
-extern char savdir[]; /* Temporary directory */
-#endif /* CK_TMPDIR */
-
-#ifndef NOLOCAL
-extern int tt_crd, tt_lfd, tt_escape;
-#endif /* NOLOCAL */
-
-#ifndef NOCSETS
-extern int language, nfilc, tcsr, tcsl, tcs_transp, fcharset;
-extern struct keytab fcstab[];
-extern struct csinfo fcsinfo[];
-#ifndef MAC
-extern struct keytab ttcstab[];
-#endif /* MAC */
-#endif /* NOCSETS */
-
-extern long speed;
-
-#ifndef NOXMIT
-extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw, xmitt;
-extern char xmitbuf[];
-#endif /* NOXMIT */
-
-extern char **xargv, *versio, *ckxsys, *dftty, *lp;
-
-#ifdef DCMDBUF
-extern char *cmdbuf, *atmbuf; /* Command buffers */
-#ifndef NOSPL
-extern char *savbuf; /* Command buffers */
-#endif /* NOSPL */
-#else
-extern char cmdbuf[], atmbuf[]; /* Command buffers */
-#ifndef NOSPL
-extern char savbuf[]; /* Command buffers */
-#endif /* NOSPL */
-#endif /* DCMDBUF */
-
-extern char toktab[], ttname[], psave[];
-extern CHAR sstate, feol;
-extern int cmflgs, techo, repars, ncmd;
-extern struct keytab cmdtab[];
-
-#ifndef NOSETKEY
-KEY *keymap;
-#ifndef OS2
-#define mapkey(x) keymap[x]
-#endif /* OS2 */
-MACRO *macrotab;
-_PROTOTYP( VOID shostrdef, (CHAR *) );
-#endif /* NOSETKEY */
-
-extern int cmdlvl;
-
-#ifndef NOSPL
-extern struct mtab *mactab;
-extern struct keytab mackey[];
-extern struct keytab vartab[], fnctab[], iftab[];
-extern int maclvl, nmac, mecho, fndiags, fnerror, fnsuccess, nif;
-#endif /* NOSPL */
-
-FILE *tfile[MAXTAKE]; /* TAKE file stack */
-char *tfnam[MAXTAKE];
-int tfline[MAXTAKE];
-
-int topcmd = -1; /* cmdtab index of current command */
-int havetoken = 0;
-extern int dblquo; /* Doublequoting enabled */
-
-#ifdef DCMDBUF /* Initialization filespec */
-char *kermrc = NULL;
-#else
-char kermrcb[KERMRCL];
-char *kermrc = kermrcb;
-#endif /* DCMDBUF */
-
-int noherald = 0;
-int cm_retry = 1; /* Command retry enabled */
-xx_strp xxstring = zzstring;
-
-#ifndef NOXFER
-extern int displa, bye_active, protocol, pktlog, remfile, rempipe, unkcs,
- keep, lf_opts, fncnv, pktpaus, autodl, xfrcan, xfrchr, xfrnum, srvtim,
- srvdis, query, retrans, streamed, reliable, crunched, timeouts,
- fnrpath, autopath, rpackets, spackets, epktrcvd, srvping;
-
-#ifdef CK_AUTODL
-extern int inautodl, cmdadl;
-#endif /* CK_AUTODL */
-
-#ifndef NOSERVER
-extern int en_asg, en_cwd, en_cpy, en_del, en_dir, en_fin, en_bye, en_ret,
- en_get, en_hos, en_que, en_ren, en_sen, en_set, en_spa, en_typ, en_who,
- en_mai, en_pri, en_mkd, en_rmd, en_xit, en_ena;
-#endif /* NOSERVER */
-
-extern int atcapr,
- atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
- attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
-
-#ifdef STRATUS
-extern int atfrmi, atfrmo, atcrei, atcreo, atacti, atacto;
-#endif /* STRATUS */
-
-#ifdef CK_PERMS
-extern int atlpri, atlpro, atgpri, atgpro;
-#endif /* CK_PERMS */
-
-#ifdef CK_LOGIN
-extern char * anonfile; /* Anonymous login init file */
-extern char * anonroot; /* Anonymous file-system root */
-extern char * userfile; /* Forbidden user file */
-extern int isguest; /* Flag for anonymous user */
-#endif /* CK_LOGIN */
-#endif /* NOXFER */
-
-#ifdef DCMDBUF
-int *xquiet = NULL;
-int *xvarev = NULL;
-#else
-int xquiet[CMDSTKL];
-int xvarev[CMDSTKL];
-#endif /* DCMDBUF */
-
-char * prstring[CMDSTKL];
-
-#ifndef NOSPL
-
-extern long ck_alarm;
-extern char alrm_date[], alrm_time[];
-
-/* Local declarations */
-
-static int nulcmd = 0; /* Flag for next cmd to be ignored */
-
-/* Definitions for predefined macros */
-
-/* First, the single-line macros, installed with addmac()... */
-
-/* IBM-LINEMODE macro */
-char *m_ibm = "set parity mark, set dupl half, set handsh xon, set flow none";
-
-/* FATAL macro */
-char *m_fat = "if def \\%1 echo \\%1, if not = \\v(local) 0 hangup, stop 1";
-
-#ifdef CK_SPEED
-#ifdef IRIX65
-char *m_fast = "set win 30, set rec pack 4000, set prefix cautious";
-#else
-#ifdef IRIX
-/* Because of bug in telnet server */
-char *m_fast = "set window 30, set rec pack 4000, set send pack 4000,\
- set pref cautious";
-#else
-#ifdef pdp11
-char *m_fast = "set win 3, set rec pack 1024, set prefix cautious";
-#else
-#ifdef BIGBUFOK
-char *m_fast = "set win 30, set rec pack 4000, set prefix cautious";
-#else
-char *m_fast = "set win 4, set rec pack 2200, set prefix cautious";
-#endif /* BIGBUFOK */
-#endif /* IRIX */
-#endif /* IRIX65 */
-#endif /* pdp11 */
-#ifdef pdp11
-char *m_cautious = "set win 2, set rec pack 512, set prefixing cautious";
-#else
-char *m_cautious = "set win 4, set rec pack 1000, set prefixing cautious";
-#endif /* pdp11 */
-char *m_robust = "set win 1, set rec pack 90, set prefixing all, \
-set reliable off, set clearchannel off";
-#else
-#ifdef BIGBUFOK
-#ifdef IRIX65
-char *m_fast = "set win 30, set rec pack 4000";
-#else
-#ifdef IRIX
-char *m_fast = "set win 30, set rec pack 4000, set send pack 4000";
-#else
-char *m_fast = "set win 30, set rec pack 4000";
-#endif /* IRIX */
-#endif /* IRIX65 */
-#else /* Not BIGBUFOK */
-char *m_fast = "set win 4, set rec pack 2200";
-#endif /* BIGBUFOK */
-char *m_cautious = "set win 4, set rec pack 1000";
-char *m_robust = "set win 1, set rec pack 90, set reliable off";
-#endif /* CK_SPEED */
-
-#ifdef VMS
-char *m_purge = "run purge \\%*";
-#endif /* VMS */
-
-#ifdef OS2
-char *m_manual = "browse \\v(exedir)docs/manual/kermit95.htm";
-#endif /* OS2 */
-
-/* Now the multiline macros, defined with addmmac()... */
-
-/* FOR macro for \%i-style loop variables (see dofor()...) */
-
-char *for_def[] = { "_assign _for\\v(cmdlevel) { _getargs,",
-"def \\\\\\%1 \\feval(\\%2),:_..top,if \\%5 \\\\\\%1 \\%3 goto _..bot,",
-"\\%6,:_..inc,incr \\\\\\%1 \\%4,goto _..top,:_..bot,_putargs},",
-"def break goto _..bot, def continue goto _..inc,",
-"do _for\\v(cmdlevel) \\%1 \\%2 \\%3 \\%4 { \\%5 },_assign _for\\v(cmdlevel)",
-""};
-
-/* This is the FOR macro when the loop variable is itself a macro */
-
-char *foz_def[] = { "_assign _for\\v(cmdlevel) { _getargs,",
-"def \\%1 \\feval(\\%2),:_..top,if \\%5 \\%1 \\%3 goto _..bot,",
-"\\%6,:_..inc,incr \\%1 \\%4,goto _..top,:_..bot,_putargs},",
-"def break goto _..bot, def continue goto _..inc,",
-"do _for\\v(cmdlevel) \\%1 \\%2 \\%3 \\%4 { \\%5 },_assign _for\\v(cmdlevel)",
-""};
-
-/* WHILE macro */
-char *whil_def[] = { "_assign _whi\\v(cmdlevel) {_getargs,",
-":_..inc,\\%1,\\%2,goto _..inc,:_..bot,_putargs},",
-"_def break goto _..bot, _def continue goto _..inc,",
-"do _whi\\v(cmdlevel),_assign _whi\\v(cmdlevel)",
-""};
-
-/* SWITCH macro */
-char *sw_def[] = { "_assign _sw_\\v(cmdlevel) {_getargs,",
-"_forward {\\%1},\\%2,:default,:_..bot,_putargs},_def break goto _..bot,",
-"do _sw_\\v(cmdlevel),_assign _sw_\\v(cmdlevel)",
-""};
-
-/* XIF macro */
-char *xif_def[] = {
-"_assign _if\\v(cmdlevel) {_getargs,\\%1,_putargs},",
-"do _if\\v(cmdlevel),_assign _if\\v(cmdlevel)",
-""};
-
-/*
- Variables declared here for use by other ckuus*.c modules.
- Space is allocated here to save room in ckuusr.c.
-*/
-#ifdef DCMDBUF
-struct cmdptr *cmdstk;
-int
- *ifcmd = NULL,
- *count = NULL,
- *iftest = NULL,
- *intime = NULL,
- *inpcas = NULL,
- *takerr = NULL,
- *merror = NULL;
-#else
-struct cmdptr cmdstk[CMDSTKL];
-int ifcmd[CMDSTKL], count[CMDSTKL], iftest[CMDSTKL], intime[CMDSTKL],
- inpcas[CMDSTKL], takerr[CMDSTKL], merror[CMDSTKL];
-#endif /* DCMDBUF */
-
-/* Macro stack */
-
-#ifdef COMMENT
-char *topline = NULL; /* Program invocation arg line */
-char *m_line[MACLEVEL] = { NULL, NULL }; /* Stack of macro invocation lines */
-#endif /* COMMENT */
-
-char **m_xarg[MACLEVEL]; /* Pointers to arg vector arrays */
-int n_xarg[MACLEVEL]; /* Sizes of arg vector arrays */
-char *m_arg[MACLEVEL][NARGS]; /* Args of each level */
-int macargc[MACLEVEL]; /* Argc of each level */
-char *macp[MACLEVEL]; /* Current position in each macro */
-char *macx[MACLEVEL]; /* Beginning of each macro def */
-char *mrval[MACLEVEL]; /* RETURN value at each level */
-int lastcmd[MACLEVEL]; /* Last command at each level */
-int topargc = 0; /* Argc at top level */
-char **topxarg = NULL; /* Argv at top level */
-char *toparg[MAXARGLIST+2];
-
-/* Global Variables */
-
-char *g_var[GVARS+1]; /* Global \%a..z pointers */
-extern char varnam[]; /* \%x variable name buffer */
-
-/* Arrays -- Dimension must be 'z' - ARRAYBASE + 1 */
-/* Note: a_link[x] < 0 means no link; >= 0 is a link */
-
-char **a_ptr[32]; /* Array pointers, for arrays a-z */
-int a_dim[32]; /* Dimensions for each array */
-int a_link[32]; /* Link (index of linked-to-array) */
-
-char **aa_ptr[CMDSTKL][32]; /* Array stack for automatic arrays */
-int aa_dim[CMDSTKL][32]; /* Dimensions for each array */
-
-/* INPUT command buffers and variables */
-
-char * inpbuf = NULL; /* Buffer for INPUT and REINPUT */
-extern char * inpbp; /* Global/static pointer to it */
-char inchar[2] = { NUL, NUL }; /* Last character that was INPUT */
-int incount = 0; /* INPUT character count */
-extern int instatus; /* INPUT status */
-static char * i_text[] = { /* INPUT status text */
- "success", "timeout", "interrupted", "internal error", "i/o error"
-};
-
-char lblbuf[LBLSIZ]; /* Buffer for labels */
-
-#else /* NOSPL */
-
-int takerr[MAXTAKE];
-#endif /* NOSPL */
-
-static char *prevdir = NULL;
-
-int pacing = 0; /* OUTPUT pacing */
-
-char *tp; /* Temporary buffer pointer */
-
-int timelimit = 0, asktimer = 0; /* Timers for time-limited commands */
-
-#ifdef CK_APC /* Application Program Command (APC) */
-int apcactive = APC_INACTIVE;
-int apcstatus = APC_OFF; /* OFF by default everywhere */
-#ifdef DCMDBUF
-char *apcbuf;
-#else
-char apcbuf[APCBUFLEN];
-#endif /* DCMDBUF */
-#endif /* CK_APC */
-
-extern char pktfil[],
-#ifdef DEBUG
- debfil[],
-#endif /* DEBUG */
-#ifdef TLOG
- trafil[],
-#endif /* TLOG */
- sesfil[];
-
-#ifndef NOFRILLS
-extern int rmailf, rprintf; /* REMOTE MAIL & PRINT items */
-extern char optbuf[];
-#endif /* NOFRILLS */
-
-extern int noinit; /* Flat to skip init file */
-
-#ifndef NOSPL
-static struct keytab kcdtab[] = { /* Symbolic directory names */
-#ifdef NT
- { "appdata", VN_APPDATA, 0 },
- { "common", VN_COMMON, 0 },
- { "desktop", VN_DESKTOP, 0 },
-#endif /* NT */
- { "download", VN_DLDIR, 0 },
-#ifdef OS2ORUNIX
- { "exedir", VN_EXEDIR, 0 },
-#endif /* OS2ORUNIX */
- { "home", VN_HOME, 0 },
- { "inidir", VN_INI, 0 },
-#ifdef UNIX
- { "lockdir", VN_LCKDIR, 0 },
-#endif /* UNIX */
-#ifdef NT
- { "my_documents",VN_PERSONAL, 0 },
- { "personal", VN_PERSONAL, CM_INV },
-#endif /* NT */
- { "startup", VN_STAR, 0 },
- { "textdir", VN_TXTDIR, 0 },
- { "tmpdir", VN_TEMP, 0 }
-};
-static int nkcdtab = (sizeof(kcdtab) / sizeof(struct keytab));
-#endif /* NOSPL */
-
-#ifndef NOSPL
-_PROTOTYP( VOID freelocal, (int) );
-_PROTOTYP( static CK_OFF_T expon, (CK_OFF_T, CK_OFF_T) );
-_PROTOTYP( static CK_OFF_T gcd, (CK_OFF_T, CK_OFF_T) );
-_PROTOTYP( static CK_OFF_T fact, (CK_OFF_T) );
-
-int /* Initialize macro data structures. */
-macini() { /* Allocate mactab and preset the first element. */
- int i;
- if (!(mactab = (struct mtab *) malloc(sizeof(struct mtab) * MAC_MAX)))
- return(-1);
- mactab[0].kwd = NULL;
- mactab[0].mval = NULL;
- mactab[0].flgs = 0;
- for (i = 0; i < MACLEVEL; i++)
- localhead[i] = NULL;
- return(0);
-}
-#endif /* NOSPL */
-
-/* C M D S R C -- Returns current command source */
-
-/* 0 = top level, 1 = file, 2 = macro, -1 = error (shouldn't happen) */
-
-/*
- As of 19 Aug 2000 this routine is obsolete. The scalar global variable
- xcmdsrc can be checked instead to save the overhead of a function call.
-*/
-int
-cmdsrc() {
-#ifdef COMMENT
- return(xcmdsrc);
-#else
-#ifndef NOSPL
- if (cmdlvl == 0)
- return(0);
- else if (cmdstk[cmdlvl].src == CMD_MD)
- return(2);
- else if (cmdstk[cmdlvl].src == CMD_TF)
- return(1);
- else
- return(-1);
-#else
- if (tlevel < 0)
- return(0);
- else
- return(1);
-#endif /* NOSPL */
-#endif /* COMMENT */
-}
-
-/* C M D I N I -- Initialize the interactive command parser */
-
-static int cmdinited = 0; /* Command parser initialized */
-extern int cmdint; /* Interrupts are allowed */
-#ifdef CK_AUTODL
-int cmdadl = 1; /* Autodownload */
-#else
-int cmdadl = 0;
-#endif /* CK_AUTODL */
-
-char * k_info_dir = NULL; /* Where to find text files */
-#ifdef UNIX
-static char * txtdir[] = {
- "/usr/local/doc/", /* Linux, SunOS, ... */
- "/usr/share/lib/", /* HP-UX 10.xx... */
- "/usr/share/doc/", /* Other possibilities... */
- "/usr/local/lib/", /* NOTE: Each of these is tried */
- "/usr/local/share/", /* as is, and also with a kermit */
- "/usr/local/share/doc/", /* subdirectory. */
- "/usr/local/share/lib/",
- "/opt/kermit/", /* Solaris */
- "/opt/kermit/doc/",
- "/opt/",
- "/usr/doc/",
- "/doc/",
- ""
-};
-#endif /* UNIX */
-
-/*
- lookup() cache to speed up script execution.
-
- This is a static cache. Items are stored in decreasing frequency of
- reference based on statistics from a range of scripts. This gives
- better performance than a dynamic cache, which would require a lot more
- code and also would require system-dependent elements including system
- calls (e.g. to get subsecond times for entry aging).
-*/
-#ifdef USE_LUCACHE /* Set in ckuusr.h */
-#define LUCACHE 32 /* Change this to reduce cache size */
-int lusize = 0;
-char * lucmd[LUCACHE];
-int luval[LUCACHE];
-int luidx[LUCACHE];
-struct keytab * lutab[LUCACHE];
-#endif /* USE_LUCACHE */
-
-static VOID
-luinit() { /* Initialize lookup() cache */
- int x, y;
-
-#ifdef USE_LUCACHE
- x = lookup(cmdtab,"if",ncmd,&y);
- lucmd[lusize] = "if";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(iftab,"not",nif,&y);
- lucmd[lusize] = "not";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = iftab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(vartab,"cmdlevel",nvars,&y);
- lucmd[lusize] = "cmdlevel";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = vartab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(cmdtab,"goto",ncmd,&y);
- lucmd[lusize] = "goto";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(iftab,">",nif,&y);
- lucmd[lusize] = ">";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = iftab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(cmdtab,"incr",ncmd,&y);
- lucmd[lusize] = "incr";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(cmdtab,"def",ncmd,&y);
- lucmd[lusize] = "def";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(cmdtab,"_assign",ncmd,&y);
- lucmd[lusize] = "_assign";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(cmdtab,"echo",ncmd,&y);
- lucmd[lusize] = "echo";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(fnctab,"eval",nfuncs,&y);
- lucmd[lusize] = "eval";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = fnctab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(fnctab,"lit",nfuncs,&y);
- lucmd[lusize] = "lit";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = fnctab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(cmdtab,"do",ncmd,&y);
- lucmd[lusize] = "do";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(cmdtab,"_getargs",ncmd,&y);
- lucmd[lusize] = "_getargs";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(iftab,"<",nif,&y);
- lucmd[lusize] = "<";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = iftab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(cmdtab,"_putargs",ncmd,&y);
- lucmd[lusize] = "_putargs";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(cmdtab,"asg",ncmd,&y);
- lucmd[lusize] = "asg";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
- if (++lusize > LUCACHE) return;
-
- x = lookup(cmdtab,"else",ncmd,&y);
- lucmd[lusize] = "else";
- luval[lusize] = x;
- luidx[lusize] = y;
- lutab[lusize] = cmdtab;
-#endif /* USE_LUCACHE */
-}
-
-VOID
-cmdini() {
- int i = 0, x = 0, y = 0, z = 0, skip = 0;
- char * p;
-#ifdef TTSPDLIST
- long * ss = NULL;
- extern int nspd;
- extern struct keytab * spdtab;
-#endif /* TTSPDLIST */
-
-#ifndef NOSPL
-/*
- On stack to allow recursion!
-*/
- char vnambuf[VNAML]; /* Buffer for variable names */
-#endif /* NOSPL */
-
- if (cmdinited) /* Already initialized */
- return; /* Don't do it again */
-
- for (i = 0; i < CMDSTKL; i++) /* Prompt strings for each */
- prstring[i] = NULL; /* command level */
-
-#ifndef NOCSETS
- p = getenv("K_CHARSET"); /* Set default file character set */
- if (p) { /* from environment */
- x = lookup(fcstab,p,nfilc,&y);
- if (x > -1)
- fcharset = x;
- }
-#endif /* NOCSETS */
-
- p = getenv("K_INFO_DIRECTORY"); /* Find Kermit info directory */
- if (p && *p && strlen(p) <= CKMAXPATH)
- makestr(&k_info_dir,p);
- if (!k_info_dir) {
- p = getenv("K_INFO_DIR");
- if (p && *p && strlen(p) <= CKMAXPATH)
- makestr(&k_info_dir,p);
- }
-#ifdef UNIX
- if (k_info_dir) { /* Look for Kermit docs directory */
- if (zchki(k_info_dir) == -2) {
- char xbuf[CKMAXPATH+32], *s = "";
- if (ckrchar(k_info_dir) != '/')
- s = "/";
- ckmakmsg(xbuf,CKMAXPATH+32,k_info_dir,s,"ckubwr.txt",NULL);
- if (zchki(xbuf) < 0)
- makestr(&k_info_dir,NULL);
- }
- }
- if (!k_info_dir) {
- char xbuf[CKMAXPATH+32];
- int i;
- for (i = 0; *(txtdir[i]); i++) {
- ckmakmsg(xbuf,CKMAXPATH+32,txtdir[i],"ckubwr.txt",NULL,NULL);
- if (zchki(xbuf) > 0) {
- makestr(&k_info_dir,txtdir[i]);
- debug(F110,"k_info_dir 1",k_info_dir,0);
- break;
- }
- ckmakmsg(xbuf,CKMAXPATH+32,
- txtdir[i],"kermit/","ckubwr.txt",NULL);
- if (zchki(xbuf) > 0) {
- ckmakmsg(xbuf,CKMAXPATH+32,txtdir[i],"kermit/",NULL,NULL);
- makestr(&k_info_dir,xbuf);
- debug(F110,"k_info_dir 2",k_info_dir,0);
- break;
- }
- ckmakmsg(xbuf,CKMAXPATH+32,
- txtdir[i],"ckermit/","ckubwr.txt",NULL);
- if (zchki(xbuf) > 0) {
- ckmakmsg(xbuf,CKMAXPATH+32,txtdir[i],"ckermit/",NULL,NULL);
- makestr(&k_info_dir,xbuf);
- debug(F110,"k_info_dir 3",k_info_dir,0);
- break;
- }
- }
- if (k_info_dir) { /* Make sure it ends with "/" */
- if (ckrchar(k_info_dir) != '/') {
- char xbuf[CKMAXPATH+32];
- ckmakmsg(xbuf,CKMAXPATH+32,k_info_dir,"/",NULL,NULL);
- makestr(&k_info_dir,xbuf);
- }
- }
- }
-#else
-#ifdef OS2
- {
- char xdir[CKMAXPATH+8], *s = "";
- extern char startupdir[];
- xdir[0] = NUL;
- if (ckrchar(startupdir) != '/')
- s = "/";
- if (strlen(s) + strlen(startupdir) + 5 < CKMAXPATH + 8 )
- ckmakmsg(xdir,CKMAXPATH+8,s,startupdir,"DOC/",NULL);
- makestr(&k_info_dir,xdir);
- }
-#endif /* OS2 */
-#endif /* UNIX */
-
-#ifdef TTSPDLIST
- if (!spdtab && (ss = ttspdlist())) { /* Get speed list if necessary */
- int j, k, m = 0, n; /* Create sorted keyword table */
- char buf[16];
- char * p;
- if ((spdtab =
- (struct keytab *) malloc(sizeof(struct keytab) * ss[0]))) {
- for (i = 1; i <= ss[0]; i++) { /* ss[0] = number of elements */
- if (ss[i] < 1L) break; /* Shouldn't happen */
- buf[0] = NUL; /* Make string */
- sprintf(buf,"%ld",ss[i]); /* SAFE */
- if (ss[i] == 8880L)
- ckstrncpy(buf,"75/1200",sizeof(buf));
- if (ss[i] == 134L)
- ckstrncat(buf,".5",16);
- n = strlen(buf);
- if ((n > 0) && (p = (char *)malloc(n+1))) {
- if (m > 0) { /* Have at least one in list */
- for (j = 0; /* Find slot */
- j < m && strcmp(buf,spdtab[j].kwd) > 0;
- j++
- )
- ;
- if (j < m) { /* Must insert */
- for (k = m-1; k >= j; k--) { /* Move others down */
- spdtab[k+1].kwd = spdtab[k].kwd;
- spdtab[k+1].flgs = spdtab[k].flgs;
- spdtab[k+1].kwval = spdtab[k].kwval;
- }
- }
- } else /* First one */
- j = 0;
- ckstrncpy(p,buf,n+1); /* Add new speed */
- spdtab[j].kwd = p;
- spdtab[j].flgs = 0;
- spdtab[j].kwval = (int) ss[i] / 10;
- m++; /* Count this one */
- }
- }
- }
- nspd = m;
- }
-#endif /* TTSPDLIST */
-
-#ifndef NOSPL
- /* Allocate INPUT command buffer */
- if (!inpbuf) {
- if (!(inpbuf = (char *) malloc(INPBUFSIZ+8)))
- fatal("cmdini: no memory for INPUT buffer");
- }
- for (x = 0; x < INPBUFSIZ; x++) /* Initialize it */
- inpbuf[x] = NUL;
- inpbp = inpbuf; /* Initialize pointer */
- inbufsize = INPBUFSIZ; /* and size. */
-#endif /* NOSPL */
-
-#ifdef DCMDBUF
- if (cmsetup() < 0) fatal("Can't allocate command buffers!");
-
-#ifndef NOSPL
- /* Allocate command stack allowing command parser to call itself */
-
- if (!(cmdstk = (struct cmdptr *) malloc(sizeof(struct cmdptr)*CMDSTKL)))
- fatal("cmdini: no memory for cmdstk");
- if (!(ifcmd = (int *) malloc(sizeof(int)*CMDSTKL)))
- fatal("cmdini: no memory for ifcmd");
- if (!(count = (int *) malloc(sizeof(int)*CMDSTKL)))
- fatal("cmdini: no memory for count");
- if (!(iftest = (int *) malloc(sizeof(int)*CMDSTKL)))
- fatal("cmdini: no memory for iftest");
- if (!(intime = (int *) malloc(sizeof(int)*CMDSTKL)))
- fatal("cmdini: no memory for intime");
- if (!(inpcas = (int *) malloc(sizeof(int)*CMDSTKL)))
- fatal("cmdini: no memory for inpcas");
- if (!(takerr = (int *) malloc(sizeof(int)*CMDSTKL)))
- fatal("cmdini: no memory for takerr");
- if (!(merror = (int *) malloc(sizeof(int)*CMDSTKL)))
- fatal("cmdini: no memory for merror");
- if (!(xquiet = (int *) malloc(sizeof(int)*CMDSTKL)))
- fatal("cmdini: no memory for xquiet");
- if (!(xvarev = (int *) malloc(sizeof(int)*CMDSTKL)))
- fatal("cmdini: no memory for xvarev");
- if (!kermrc)
- if (!(kermrc = (char *) malloc(KERMRCL+1)))
- fatal("cmdini: no memory for kermrc");
-#ifdef CK_APC
-/* Application Program Command buffer */
- if (!(apcbuf = malloc(APCBUFLEN + 1)))
- fatal("cmdini: no memory for apcbuf");
-#endif /* CK_APC */
-#endif /* NOSPL */
-
-/* line[] and tmpbuf[] are the two string buffers used by the command parser */
-
- if (!(line = malloc(LINBUFSIZ + 1)))
- fatal("cmdini: no memory for line");
- if (!(tmpbuf = malloc(LINBUFSIZ + 1)))
- fatal("cmdini: no memory for tmpbuf");
-#endif /* DCMDBUF */
-
-#ifndef NOSPL
-#ifdef CK_MINPUT
- { /* Initialize MINPUT pointers */
- int i;
- extern char *ms[];
- for (i = 0; i < MINPMAX; i++)
- ms[i] = NULL;
- }
-#endif /* CK_MINPUT */
-
- if (macini() < 0) /* Allocate macro buffers */
- fatal("Can't allocate macro buffers!");
-
- ifcmd[0] = 0; /* Command-level related variables. */
- iftest[0] = 0; /* Initialize variables at top level */
- count[0] = 0; /* of stack... */
- intime[0] = 0;
- inpcas[0] = 0;
- takerr[0] = 0;
- merror[0] = 0;
- xquiet[0] = quiet;
- xvarev[0] = vareval;
-#endif /* NOSPL */
-
-#ifndef NOSPL
- cmdlvl = 0; /* Initialize the command stack */
- xcmdsrc = CMD_KB;
- cmdstk[cmdlvl].src = CMD_KB; /* Source is console */
- cmdstk[cmdlvl].lvl = 0; /* Level is 0 */
- cmdstk[cmdlvl].ccflgs = 0; /* No flags */
-#endif /* NOSPL */
-
- tlevel = -1; /* Take file level = keyboard */
- for (i = 0; i < MAXTAKE; i++) /* Initialize command file names */
- tfnam[i] = NULL;
-
- cmsetp(ckprompt); /* Set up C-Kermit's prompt */
- /* Can't set IKSD prompt here since */
- /* we do not yet know if we are IKSD */
-#ifndef NOSPL
-
- initmac(); /* Initialize macro table */
-
-/* Predefine built-in one-line macros */
-
- addmac("ibm-linemode",m_ibm); /* IBM-LINEMODE */
- addmac("fatal",m_fat); /* FATAL macro */
- y = addmac("fast",m_fast); /* FAST macro */
- addmac("cautious",m_cautious); /* CAUTIOUS macro */
- addmac("robust",m_robust); /* ROBUST macro */
-#ifdef OS2
- addmac("manual",m_manual); /* MANUAL macro */
-#endif /* OS2 */
-#ifdef VMS
- addmac("purge",m_purge); /* PURGE macro */
-#endif /* VMS */
-
-/*
- Predefine built-in multiline macros; these are top-level commands
- that are implemented internally as macros. NOTE: When adding a new
- one of these, remember to update the END and RETURN commands to
- account for it, or else END and RETURN from within it won't work right.
-*/
- x = addmmac("_forx",for_def); /* FOR macro */
- if (x > -1) mactab[x].flgs = CM_INV;
- x = addmmac("_forz",foz_def); /* Other FOR macro */
- if (x > -1) mactab[x].flgs = CM_INV;
- x = addmmac("_xif",xif_def); /* XIF macro */
- if (x > -1) mactab[x].flgs = CM_INV;
- x = addmmac("_while",whil_def); /* WHILE macro */
- if (x > -1) mactab[x].flgs = CM_INV;
- x = addmmac("_switx",sw_def); /* SWITCH macro */
- if (x > -1) mactab[x].flgs = CM_INV;
-
-/* Fill in command-line argument vector */
-
- sprintf(vnambuf,"\\&@[%d]",xargs); /* SAFE */
- if (inserver) { /* But hidden in IKSD */
- y = -1;
- xargs = 0;
- } else
- y = arraynam(vnambuf,&x,&z); /* goes in array \&@[] */
-
- tmpbuf[0] = NUL;
- if (y > -1) {
- int j = -1;
- int yy = 0;
- dclarray((char)x,z); /* Declare the array */
-#ifndef NOTAKEARGS
- /* Macro argument vector */
- sprintf(vnambuf,"\\&_[%d]",z); /* SAFE */
- yy = arraynam(vnambuf,&x,&z); /* goes in array \&_[] */
- if (yy > -1) /* Name is OK */
- dclarray((char)x,z); /* Declare the array */
-#endif /* NOTAKEARGS */
- skip = 0;
- for (i = 0; i < xargs; i++) { /* Fill the arrays */
- sprintf(vnambuf,"\\&@[%d]",i); /* SAFE */
- addmac(vnambuf,xargv[i]);
- if (cfilef && i == 0)
- continue;
-#ifdef KERBANG
- if (skip) {
- j = 0;
- skip = 0;
- continue;
- }
-#endif /* KERBANG */
- if (j < 0 && /* Assign items after "=" or "--"*/
- (!strcmp(xargv[i],"=") || !strcmp(xargv[i],"--"))
- ) {
- j = 0; /* to \%1..\%9 */
-#ifdef KERBANG
- } else if (j < 0 &&
- (!strcmp(xargv[i],"+") ||
- !strncmp(xargv[i],"+ ",2) ||
- !strncmp(xargv[i],"+\t",2))
- ) {
- skip = 1;
- continue;
-#endif /* KERBANG */
- } else if (j > -1) {
- j++;
- if (j <= 9) {
- vnambuf[0] = '\\';
- vnambuf[1] = '%';
- vnambuf[2] = (char)(j+'0');
- vnambuf[3] = NUL;
- addmac(vnambuf,xargv[i]);
- }
- if (yy > -1) {
- char c, * p;
- int flag = 0;
- p = xargv[i];
- makestr(&(toparg[j]),p);
- while ((c = *p++)) { if (c == SP) { flag++; break; } }
- if (flag)
- ckstrncat(tmpbuf,"\"",TMPBUFSIZ);
- ckstrncat(tmpbuf,xargv[i],TMPBUFSIZ);
- if (flag)
- ckstrncat(tmpbuf,"\"",TMPBUFSIZ);
- ckstrncat(tmpbuf," ",TMPBUFSIZ);
- }
- }
- }
- if (cfilef) {
- addmac("\\%0",cmdfil);
- if (yy > -1)
- makestr(&(toparg[0]),cmdfil);
- } else {
- addmac("\\%0",xargv[0]);
- if (yy > -1)
- makestr(&(toparg[0]),xargv[0]);
- }
- if (yy > -1) {
- topargc = (j < 0) ? 1 : j + 1;
- topxarg = toparg;
-#ifdef COMMENT
- /* This needs work */
- if (!cfilef)
- makestr(&topline,tmpbuf);
-#endif /* COMMENT */
- } else {
- topargc = 0;
- topxarg = NULL;
- }
- a_dim[0] = topargc - 1;
- a_ptr[0] = topxarg;
- debug(F111,"a_dim[0]","A",a_dim[0]);
- }
- *vnambuf = NUL;
-#endif /* NOSPL */
-
- luinit(); /* Initialize lookup() cache */
-
-/* Get our home directory now. This needed in lots of places. */
-
- cmdinited = 1;
-}
-
-#ifdef NT
-_PROTOTYP(char * GetAppData,(int));
-#endif /* NT */
-
-VOID
-doinit() {
-#ifdef CKROOT
-extern int ckrooterr;
-#endif /* CKROOT */
- int x = 0, ok = 0;
-#ifdef OS2
- char * ptr = 0;
-#endif /* OS2 */
-
- if (!cmdinited)
- cmdini();
-
-#ifdef MAC
- return; /* Mac Kermit has no init file */
-
-#else /* !MAC */
-
-/* If skipping init file ('-Y' on Kermit command line), return now. */
-
- if (noinit) {
- kermrc[0] = '\0';
- inidir[0] = '\0';
-/*
- But returning from here results in inidir[] never being set to anything.
- Instead it should be set to wherever the init file *would* have been
- executed from. So this bit of code should be removed, and then we should
- sprinkle "if (noinit)" tests throughout the following code until we have
- set inidir[], and then return without actually taking the init file.
-*/
- return;
- }
-
-#ifdef OS2
-/*
- The -y init file must be fully specified or in the current directory.
- KERMRC is looked for via INIT, DPATH and PATH in that order. Finally, our
- own executable file path is taken and the .EXE suffix is replaced by .INI
- and this is tried as the initialization file.
-*/
-#ifdef CK_LOGIN
- debug(F101,"doinit inserver","",inserver);
- debug(F101,"doinit isguest","",isguest);
- debug(F110,"doinit anonfile",anonfile,0);
-
- if (isguest && anonfile) {
- ckstrncpy(line, anonfile, LINBUFSIZ+1);
- } else
-#endif /* CK_LOGIN */
- if (rcflag) {
- ckstrncpy(line,kermrc,LINBUFSIZ+1);
-#ifdef CK_LOGIN
- } else if (inserver) {
- char * appdata = NULL;
-#ifdef NT
- appdata = GetAppData(1);
- if ( appdata ) {
- ckmakmsg(line,LINBUFSIZ+1,appdata,
- "Kermit 95/k95.ini",NULL,NULL);
- if ( zchki(line) < 0 )
- line[0] = '\0';
- }
- if (line[0] == 0) {
- appdata = GetAppData(0);
- if ( appdata ) {
- ckmakmsg(line,LINBUFSIZ+1,appdata,
- "Kermit 95/k95.ini",NULL,NULL);
- if ( zchki(line) < 0 )
- line[0] = '\0';
- }
- }
-#endif /* NT */
- if (line[0] == 0) {
- appdata = zhome();
- if ( appdata ) {
- ckmakmsg(line,LINBUFSIZ+1,appdata,
-#ifdef NT
- "k95.ini",
-#else /* NT */
- "k2.ini",
-#endif /* NT */
- NULL,NULL);
- if ( zchki(line) < 0 )
- line[0] = '\0';
- }
- }
- debug(F110,"doinit inserver inifile",line,0);
-#endif /* CK_LOGIN */
- } else {
- char * env = 0;
-#ifdef NT
- env = getenv("K95.KSC");
-#else
- env = getenv("K2.KSC");
-#endif /* NT */
- if (!env) {
-#ifdef NT
- env = getenv("K95.INI");
-#else
- env = getenv("K2.INI");
-#endif /* NT */
- }
- if (!env)
- env = getenv("CKERMIT.INI");
- if (!env)
- env = getenv("CKERMIT_INI");
- line[0] = '\0';
-
- debug(F110,"doinit env",env,0);
- if (env)
- ckstrncpy(line,env,LINBUFSIZ+1);
-
-#ifdef NT
- if (line[0] == 0) {
- env = GetAppData(1);
- if ( env ) {
- ckmakmsg(line,LINBUFSIZ+1,env,"Kermit 95/k95.ini",NULL,NULL);
- if ( zchki(line) < 0 )
- line[0] = '\0';
- }
- }
- if (line[0] == 0) {
- env = GetAppData(0);
- if ( env ) {
- ckmakmsg(line,LINBUFSIZ+1,env,"Kermit 95/k95.ini",NULL,NULL);
- if ( zchki(line) < 0 )
- line[0] = '\0';
- }
- }
-#endif /* NT */
-
- if (line[0] == 0) {
- env = zhome();
- if ( env ) {
- ckmakmsg(line,LINBUFSIZ+1,env,
-#ifdef NT
- "k95.ini",
-#else /* NT */
- "k2.ini",
-#endif /* NT */
- NULL,NULL);
- if ( zchki(line) < 0 )
- line[0] = '\0';
- }
- }
-
- if (line[0] == 0)
- _searchenv(kermrc,"INIT",line);
- if (line[0] == 0)
- _searchenv(kermrc,"DPATH",line);
- if (line[0] == 0)
- _searchenv(kermrc,"PATH",line);
- if (line[0] == 0) {
- char *pgmptr = GetLoadPath();
- if (pgmptr && strlen(pgmptr) < LINBUFSIZ-8) {
- lp = strrchr(pgmptr, '\\');
- if (lp) {
- strncpy(line, pgmptr, lp - pgmptr);
-#ifdef NT
- strcpy(line + (lp - pgmptr), "/k95.ini");
-#else /* NT */
- strcpy(line + (lp - pgmptr), "/k2.ini");
-#endif /* NT */
- } else {
- lp = strrchr(pgmptr, '.');
- if (lp) {
- strncpy(line, pgmptr, lp - pgmptr);
- strcpy(line + (lp - pgmptr), ".ini");
- }
- }
- }
- }
- }
-
-#ifdef CKROOT
- if (!zinroot(line)) {
- debug(F110,"doinit setroot violation",line,0);
- return;
- }
-#endif /* CKROOT */
-
- debug(F110,"doinit fopen()",line,0);
- if ((tfile[0] = fopen(line,"r")) != NULL) {
- ok = 1;
- tlevel = 0;
- tfline[tlevel] = 0;
- if (tfnam[tlevel] = malloc(strlen(line)+1))
- strcpy(tfnam[tlevel],line); /* safe */
-#ifndef NOSPL
- cmdlvl++;
- xcmdsrc = CMD_TF;
- cmdstk[cmdlvl].src = CMD_TF;
- cmdstk[cmdlvl].lvl = tlevel;
- cmdstk[cmdlvl].ccflgs = 0;
- ifcmd[cmdlvl] = 0;
- iftest[cmdlvl] = 0;
- count[cmdlvl] = count[cmdlvl-1]; /* Inherit from previous level */
- intime[cmdlvl] = intime[cmdlvl-1];
- inpcas[cmdlvl] = inpcas[cmdlvl-1];
- takerr[cmdlvl] = takerr[cmdlvl-1];
- merror[cmdlvl] = merror[cmdlvl-1];
- xquiet[cmdlvl] = quiet;
- xvarev[cmdlvl] = vareval;
-#endif /* NOSPL */
- debug(F110,"doinit init file",line,0);
- } else {
- debug(F100,"doinit no init file","",0);
- }
- ckstrncpy(kermrc,line,KERMRCL);
- for (ptr = kermrc; *ptr; ptr++) /* Convert backslashes to slashes */
- if (*ptr == '\\')
- *ptr = '/';
-#else /* not OS2 */
- lp = line;
- lp[0] = '\0';
- debug(F101,"doinit rcflag","",rcflag);
-#ifdef GEMDOS
- zkermini(line, rcflag, kermrc);
-#else
-#ifdef VMS
- {
- int x;
- x = zkermini(line,LINBUFSIZ,kermrc);
- debug(F111,"CUSTOM zkermini",line,x);
- if (x == 0)
- line[0] = NUL;
- }
-#else /* not VMS */
-#ifdef CK_LOGIN
- debug(F101,"doinit isguest","",isguest);
- if (isguest)
- ckstrncpy(lp, anonfile ? anonfile : kermrc, LINBUFSIZ);
- else
-#endif /* CK_LOGIN */
- if (rcflag) { /* If init file name from cmd line */
- ckstrncpy(lp,kermrc,LINBUFSIZ); /* use it, */
- } else { /* otherwise... */
-#ifdef CK_INI_A /* If we've a system-wide init file */
- /* And it takes precedence over the user's... */
- ckstrncpy(lp,CK_SYSINI,KERMRCL); /* Use it */
- if (zchki(lp) < 0) { /* (if it exists...) */
-#endif /* CK_INI_A */
- char * homdir;
- char * env = 0;
- line[0] = NUL;
-
- /* Add support for environment variable */
- env = getenv("CKERMIT.INI");
- if (!env)
- env = getenv("CKERMIT_INI");
- if (env)
- ckstrncpy(lp,env,KERMRCL);
-
- if (lp[0] == 0) {
- homdir = zhome();
- if (homdir) { /* Home directory for init file. */
- ckstrncpy(lp,homdir,KERMRCL);
-#ifdef STRATUS
- ckstrncat(lp,">",KERMRCL);/* VOS dirsep */
-#else
- if (lp[0] == '/') ckstrncat(lp,"/",KERMRCL);
-#endif /* STRATUS */
- }
- ckstrncat(lp,kermrc,KERMRCL);/* Append default file name */
- }
-#ifdef CK_INI_A
- }
-#endif /* CK_INI_A */
-#ifdef CK_INI_B /* System-wide init defined? */
- /* But user's ini file takes precedence */
- if (zchki(lp) < 0) /* If user doesn't have her own, */
- ckstrncpy(lp,CK_SYSINI,KERMRCL); /* use system-wide one. */
-#endif /* CK_INI_B */
- }
-#endif /* VMS */
-#endif /* GEMDOS */
-
-#ifdef AMIGA
- reqoff(); /* Disable requestors */
-#endif /* AMIGA */
-
-#ifdef USE_CUSTOM
- /* If no init file was found, execute the customization file */
- debug(F111,"CUSTOM 1",line,rcflag);
- if ((!line[0] || zchki(line) < 0) && !rcflag) {
- int x;
-#ifdef OS2
- x = ckmakestr(line,LINBUFSIZ,GetAppData(1),"/","K95CUSTOM.INI",NULL);
- debug(F111,"CUSTOM 2",line,x);
- if (zchki(line) < 0) {
- x = ckmakestr(line,LINBUFSIZ,GetAppData(0),"/","K95USER.INI",NULL);
- debug(F111,"CUSTOM 3",line,x);
- }
-#else /* OS2 */
- x = ckstrncpy(line,zhome(),LINBUFSIZ);
-#ifndef VMS
- /* VMS zhome() returns "SYS$LOGIN:" */
- if (line[x-1] != DIRSEP) {
- line[x++] = DIRSEP;
- line[x] = NUL;
- }
-#endif /* VMS */
- x = ckstrncat(line,MYCUSTOM,LINBUFSIZ);
- debug(F111,"CUSTOM 4",line,x);
-#endif /* OS2 */
- }
- debug(F110,"CUSTOM 5",line,0);
-#endif /* USE_CUSTOM */
-
-#ifdef CKROOT
- if (!zinroot(line)) {
- debug(F110,"doinit setroot violation",line,0);
- return;
- }
-#endif /* CKROOT */
-
- debug(F110,"doinit ini file is",line,0);
- if ((tfile[0] = fopen(line,"r")) != NULL) { /* Try to open init file. */
- ok = 1;
- tlevel = 0;
- tfline[tlevel] = 0;
- if ((tfnam[tlevel] = malloc(strlen(line)+1)))
- strcpy(tfnam[tlevel],line); /* safe */
-
- ckstrncpy(kermrc,line,KERMRCL);
-
-#ifndef NOSPL
- cmdlvl++;
- ifcmd[cmdlvl] = 0;
- iftest[cmdlvl] = 0;
- count[cmdlvl] = count[cmdlvl-1]; /* Inherit from previous level */
- intime[cmdlvl] = intime[cmdlvl-1];
- inpcas[cmdlvl] = inpcas[cmdlvl-1];
- takerr[cmdlvl] = takerr[cmdlvl-1];
- merror[cmdlvl] = merror[cmdlvl-1];
- xquiet[cmdlvl] = quiet;
- xvarev[cmdlvl] = vareval;
- debug(F101,"doinit open ok","",cmdlvl);
- xcmdsrc = CMD_TF;
- cmdstk[cmdlvl].src = CMD_TF;
- cmdstk[cmdlvl].lvl = tlevel;
- cmdstk[cmdlvl].ccflgs = 0;
-#endif /* NOSPL */
- } else if (rcflag) {
- /* Print an error message only if a specific file was asked for. */
- printf("?%s - %s\n", ck_errstr(), line);
- }
-
-#ifdef datageneral
-/* If CKERMIT.INI not found in home directory, look in searchlist */
- if (/* homdir && */ (tlevel < 0)) {
- ckstrncpy(lp,kermrc,LINBUFSIZ);
- if ((tfile[0] = fopen(line,"r")) != NULL) {
- ok = 1;
- tlevel = 0;
- tfline[tlevel] = 0;
- if (tfnam[tlevel] = malloc(strlen(line)+1))
- strcpy(tfnam[tlevel],line); /* safe */
-#ifndef NOSPL
- cmdlvl++;
- xcmdsrc = CMD_TF;
- cmdstk[cmdlvl].src = CMD_TF;
- cmdstk[cmdlvl].lvl = tlevel;
- cmdstk[cmdlvl].ccflgs = 0;
- ifcmd[cmdlvl] = 0;
- iftest[cmdlvl] = 0;
- count[cmdlvl] = count[cmdlvl-1]; /* Inherit from previous level */
- intime[cmdlvl] = intime[cmdlvl-1];
- inpcas[cmdlvl] = inpcas[cmdlvl-1];
- takerr[cmdlvl] = takerr[cmdlvl-1];
- merror[cmdlvl] = merror[cmdlvl-1];
- xquiet[cmdlvl] = quiet;
- xvarev[cmdlvl] = vareval;
-#endif /* NOSPL */
- }
- }
-#endif /* datageneral */
-
-#ifdef AMIGA /* Amiga... */
- reqpop(); /* Restore requestors */
-#endif /* AMIGA */
-#endif /* OS2 */
-#endif /* MAC */
-
- /* Assign value to inidir */
-
- if (!ok) {
- inidir[0] = NUL;
- } else {
- ckstrncpy(inidir, kermrc, CCHMAXPATH);
- x = strlen(inidir);
- if (x > 0) {
- int i;
- for (i = x - 1; i > 0; i-- ) {
- if (ISDIRSEP(inidir[i])) {
- inidir[i+1] = NUL;
- break;
- }
- }
- }
-#ifdef NT
- GetShortPathName(inidir,inidir,CCHMAXPATH);
-#endif /* NT */
- }
-}
-
-VOID
-doiksdinit() {
-#ifdef CK_SSL
- /* IKSD doesn't request client certs */
- ssl_verify_flag = SSL_VERIFY_NONE;
-#endif /* CK_SSL */
-
- if (!cmdinited)
- cmdini();
-
-#ifdef IKSDCONF
-#ifdef OS2
- line[0] = '\0';
- _searchenv(iksdconf,"INIT",line);
- if (line[0] == 0)
- _searchenv(iksdconf,"DPATH",line);
- if (line[0] == 0)
- _searchenv(iksdconf,"PATH",line);
- if (line[0] == 0) {
- char *pgmptr = GetLoadPath();
- if (pgmptr && strlen(pgmptr) < LINBUFSIZ-8) {
- lp = strrchr(pgmptr, '\\');
- if (lp) {
- strncpy(line, pgmptr, lp - pgmptr);
- strcpy(line + (lp - pgmptr), "\\");
- strcpy(line + (lp - pgmptr + 1), iksdconf);
- } else {
- lp = strrchr(pgmptr, '.');
- if (lp) {
- strncpy(line, pgmptr, lp - pgmptr);
- strcpy(line + (lp - pgmptr), ".ksc");
- }
- }
- }
- }
- debug(F110,"doiksdinit() line",line,0);
- tfile[0] = fopen(line,"r");
-#else /* OS2 */
- tfile[0] = fopen(iksdconf,"r");
-#endif /* OS2 */
- if (tfile[0] != NULL) {
- tlevel = 0;
- tfline[tlevel] = 0;
-#ifdef OS2
- if (tfnam[tlevel] = malloc(strlen(line)+1))
- strcpy(tfnam[tlevel],line);
-#else /* OS2 */
- if ((tfnam[tlevel] = malloc(strlen(iksdconf)+1)))
- strcpy(tfnam[tlevel],iksdconf);
-#endif /* OS2 */
-#ifndef NOSPL
- cmdlvl++;
- xcmdsrc = CMD_TF;
- cmdstk[cmdlvl].src = CMD_TF;
- cmdstk[cmdlvl].lvl = tlevel;
- cmdstk[cmdlvl].ccflgs = 0;
- ifcmd[cmdlvl] = 0;
- iftest[cmdlvl] = 0;
- count[cmdlvl] = count[cmdlvl-1]; /* Inherit from previous level */
- intime[cmdlvl] = intime[cmdlvl-1];
- inpcas[cmdlvl] = inpcas[cmdlvl-1];
- takerr[cmdlvl] = takerr[cmdlvl-1];
- merror[cmdlvl] = merror[cmdlvl-1];
- xquiet[cmdlvl] = quiet;
- xvarev[cmdlvl] = vareval;
-#endif /* NOSPL */
- debug(F110,"doiksdinit file ok",tfnam[tlevel],0);
- } else {
- debug(F110,"doiksdinit open failed",tfnam[tlevel],0);
- }
-#endif /* IKSDCONF */
-}
-
-#ifndef NOSPL
-/*
- G E T N C M
-
- Get next command from current macro definition. Command is copied
- into string pointed to by argument s, max length n. Returns:
- 0 if a string was copied;
- -1 if there was no string to copy.
-*/
-int
-getncm(s,n) char *s; int n; {
- int y = 0; /* Character counter */
- int quote = 0;
- int kp = 0; /* Brace up-down counter */
- int pp = 0; /* Parenthesis up-down counter */
-#ifndef NODQMACRO
- int dq = 0; /* Doublequote counter */
-#endif /* NODQMACRO */
- char *s2; /* Copy of destination pointer */
-
- s2 = s; /* Initialize string pointers */
- *s = NUL; /* and destination buffer */
-
- /* debug(F010,"getncm entry",macp[maclvl],0); */
-
- for (y = 0; /* Loop for n bytes max */
- macp[maclvl] && *macp[maclvl] && y < n;
- y++, s++, macp[maclvl]++) {
-
- *s = *macp[maclvl]; /* Get next char from macro def */
-
-#ifndef COMMENT
-/*
- This is to allow quoting of parentheses, commas, etc, in function
- arguments, but it breaks just about everything else. DON'T REMOVE THIS
- COMMENT! (Otherwise you'll wind up adding the same code again and breaking
- everything again.) <-- The preceding warning should be obsolete since the
- statements below have been fixed, but in case of fire, remove the "n" from
- the <#>ifndef above. NEW WARNING: code added 12 Apr 2002 to exempt the
- opening brace in \{nnn} from being treated as a quoted brace.
-*/
- if (!quote && *s == CMDQ) {
- quote = 1;
- continue;
- }
- if (quote) {
- int notquote = 0;
- quote = 0;
- if (*s == '{') { /* Check for \{nnn} (8.0.203) */
- char c, * p;
- p = macp[maclvl] + 1;
- while ((c = *p++)) {
- if (isdigit(c))
- continue;
- else if (c == '}') {
- notquote++;
- break;
- } else {
- break;
- }
- }
- }
- if (notquote == 0)
- continue;
- }
-#endif /* COMMENT */
-
-/*
- Allow braces around macro definition to prevent commas from being turned to
- end-of-lines and also treat any commas within parens as text so that
- multiple-argument functions won't cause the command to break prematurely.
- 19 Oct 2001: Similar treatment was added for doublequotes, so
-
- define foo { echo "one, two, three" }
-
- would work as expected. This doesn't seem to have broken anything but
- if something comes up later, rebuild with NODQMACRO defined.
-*/
- if (*s == '{') kp++; /* Count braces */
- if (*s == '}' && kp > 0) kp--;
- if (*s == '(') pp++; /* Count parentheses. */
- if (*s == ')' && pp > 0) pp--;
-#ifndef NODQMACRO
-#ifndef COMMENT
- /* Too many false positives */
- /* No, not really -- this is indeed the best we can do */
- /* Reverted to this method Sun May 11 18:43:45 2003 */
- if (*s == '"') dq = 1 - dq; /* Account for doublequotes */
-#else /* Fri Apr 4 13:21:29 2003 */
- /* The code below breaks the SWITCH statement */
- /* There is no way to make this work -- it would require */
- /* building in all the knowledge of command parser. */
- if (dblquo && (*s == '"')) { /* Have doublequote */
- if (dq == 1) { /* Close quote only if... */
- if ((*(macp[maclvl]+1) == SP) || /* followed by space or... */
- (!*(macp[maclvl]+1)) || /* at end or ... */
- /* Next char is command separator... */
- /* Sun May 11 17:24:12 2003 */
- (kp < 1 && pp < 1 && (*(macp[maclvl]+1) == ','))
- )
- dq = 0; /* Close the quote */
- } else if (dq == 0) {
- /* Open quote only if at beginning or preceded by space */
- if (s > s2) {
- if (*(s-1) == SP)
- dq = 1;
- } else if (s == s2) {
- dq = 1;
- }
- }
- }
-#endif /* COMMENT */
-#endif /* NODQMACRO */
- if (*s == ',' && pp <= 0 && kp <= 0
-#ifndef NODQMACRO
- && dq == 0
-#endif /* NODQMACRO */
- ) {
- macp[maclvl]++; /* Comma not in {} or () */
- /* debug(F110,"next cmd",s,0); */
- kp = pp = 0; /* so we have the next command */
- break;
- }
- } /* Reached end. */
-#ifdef COMMENT
- /* DON'T DO THIS - IT BREAKS EVERYTHING */
- *s = NUL;
-#endif /* COMMENT */
- if (*s2 == NUL) { /* If nothing was copied, */
- /* debug(F100,"XXX getncm eom","",0); */
- popclvl(); /* pop command level. */
- return(-1);
- } else { /* otherwise, tack CR onto end */
- *s++ = CR;
- *s = '\0';
- /* debug(F110,"XXX getncm OK",s,0); */
- if (mecho && pflag) /* If MACRO ECHO ON, echo the cmd */
- printf("%s\n",s2);
- }
- return(0);
-}
-
-/* D O M A C -- Define and then execute a macro */
-
-int
-domac(name, def, flags) char *name, *def; int flags; {
- int x, m;
-#ifndef NOLOCAL
-#ifdef OS2
- extern int term_io;
- int term_io_sav = term_io;
- term_io = 0; /* Disable Terminal Emulator I/O */
-#endif /* OS2 */
-#endif /* NOLOCAL */
- m = maclvl; /* Current macro stack level */
- x = addmac(name, def); /* Define a new macro */
- if (x > -1) { /* If successful, */
- dodo(x,NULL,flags); /* start it (increments maclvl). */
- while (maclvl > m) { /* Keep going till done with it, */
- debug(F101,"domac loop maclvl 1","",maclvl);
- sstate = (CHAR) parser(1); /* parsing & executing each command, */
- debug(F101,"domac loop maclvl 2","",maclvl);
- if (sstate) proto(); /* including protocol commands. */
- }
- debug(F101,"domac loop exit maclvl","",maclvl);
- }
-#ifndef NOLOCAL
-#ifdef OS2
- term_io = term_io_sav;
-#endif /* OS2 */
-#endif /* NOLOCAL */
- return(success);
-}
-#endif /* NOSPL */
-
-/*
- G E T N C T
-
- Get next command from TAKE (command) file.
-
- Call with:
- s Pointer to buffer to read into
- n Length of buffer
- f File descriptor of file to read from
- flag 0 == keep line terminator on and allow continuation
- 1 == discard line terminator and don't allow continuation
-
- Call with flag == 0 to read a command from a TAKE file;
- Call with flag != 0 to read a line from a dialing or network directory.
-
- In both cases, trailing comments and/or trailing whitespace is/are stripped.
- If flag == 0, continued lines are combined into one line. A continued line
- is one that ends in hypen, or any line in a "block", which starts with "{"
- at the end of a line and ends with a matching "}" at the beginning of a
- subsequent line; blocks may be nested.
-
- Returns:
- 0 if a string was copied,
- -1 on EOF,
- -2 on malloc failure
- -3 if line is not properly terminated
- -4 if (possibly continued) line is too long.
-*/
-static int lpxlen = 0;
-
-int
-getnct(s,n,f,flag) char *s; int n; FILE *f; int flag; {
- int i = 0, len = 0, buflen = 0;
- char c = NUL, cc = NUL, ccl = NUL, ccx = NUL, *s2 = NULL;
- char *lp = NULL, *lpx = NULL, *lp2 = NULL, *lp3 = NULL, *lastcomma = NULL;
- char * prev = NULL;
- int bc = 0; /* Block counter */
-
- s2 = s; /* Remember original pointer */
- prev = s2; /* Here too */
- buflen = n; /* Remember original buffer length */
-
- if (n < 0)
- return(-2);
-
- /* Allocate a line buffer only if we don't have one that's big enough */
-
- debug(F111,"getnct",ckitoa(lpxlen),n);
-
- if (lpx && (n > lpxlen)) { /* Have one already */
- debug(F101,"getnct new buffer","",lpxlen);
- free(lpx); /* But it's not big enough */
- lpx = NULL; /* Free current one */
- lpxlen = 0;
- }
- if (!lpx) { /* Get new one */
- if (!(lpx = (char *) malloc(n))) {
- debug(F101,"getnct malloc failure","",0);
- printf("?Memory allocation failure [getnct:%d]\n",n);
- return(-2);
- }
- lpxlen = n;
- }
- lp2 = lpx;
-#ifdef KLUDGE
- /* NOTE: No longer used as of 14 Aug 2000 */
- lp2++;
-#endif /* KLUDGE */
-
- while (1) { /* Loop to read lines from file */
- debug(F101,"getnct while (1)","",n);
- if (fgets(lp2,n,f) == NULL) { /* Read a line into lp2 */
- debug(F110,"getnct EOF",s2,0); /* EOF */
- free(lpx); /* Free temporary storage */
- lpx = NULL;
- *s = NUL; /* Make destination be empty */
- return(-1); /* Return failure code */
- }
-
-#ifndef NODIAL
- if (flag) /* Count this line */
- dirline++;
- else
-#endif /* NODIAL */
- tfline[tlevel]++;
- len = strlen(lp2) - 1; /* Position of line terminator */
- if (len == 0 && lp2[0] != '\n') { /* Last line in file has one char */
- lp2[++len] = '\n'; /* that is not a newline */
- lp2[len] = NUL;
- }
- debug(F010,"getnct",lp2,0);
- if (len < 0)
- len = 0;
- if (techo && pflag) /* If TAKE ECHO ON, */
- printf("%3d. %s", /* echo it this line. */
-#ifndef NODIAL
- flag ? dirline :
-#endif /* NODIAL */
- tfline[tlevel],
- lp2
- );
- lp3 = lp2; /* Working pointer */
- i = len; /* Get first nonwhitespace character */
- while (i > 0 && (*lp3 == SP || *lp3 == HT)) {
- i--;
- lp3++;
- }
- if (i == 0 && bc > 0) /* Blank line in {...} block */
- continue;
-
- /* Isolate, remove, and check terminator */
-
- c = lp2[len]; /* Value of line terminator */
- /* debug(F101,"getnct terminator","",c); */
- if (c < LF || c > CR) { /* It's not a terminator */
- /* debug(F111,"getnct bad line",lp2,c); */
- if (feof(f) && len > 0 && len < n) {
- /* Kludge Alert... */
- if (!quiet)
- printf("WARNING: Last line of %s lacks terminator\n",
- s2 == cmdbuf ? "command file" : "directory file");
- c = lp2[++len] = '\n'; /* No big deal - supply one. */
- } else { /* Something's wrong, fail. */
- free(lpx);
- lpx = NULL;
- return(-3);
- }
- }
- /* Trim trailing whitespace */
-
- for (i = len - 1; i > -1 && lp2[i] <= SP; i--) /* Trim */
- ;
- /* debug(F101,"getnct i","",i); */
- lp2[i+1] = NUL; /* Terminate the string */
- /* debug(F110,"getnct lp2",lp2,0); */
- lp = lp2; /* Make a working pointer */
-
- /* Remove trailing or full-line comment */
-
- while ((cc = *lp)) {
- if (cc == ';' || cc == '#') { /* Comment introducer? */
- if (lp == lp2) { /* First char on line */
- *lp = NUL;
- break;
- } else if (*(lp - 1) == SP || *(lp - 1) == HT) {
- lp--;
- *lp = NUL; /* Or preceded by whitespace */
- break;
- }
- }
- lp++;
- }
- if (lp > lp2)
- lp--; /* Back up over the NUL */
-
- /* Now trim any space that preceded the comment */
-
- while ((*lp == SP || *lp == HT) && lp >= lp2) {
- *lp = NUL;
- if (lp <= lp2)
- break;
- lp--;
- }
- /* debug(F110,"getnct comment trimmed",lp2,0); */
-
- len = strlen(lp2); /* Length after trimming */
-
- if (n - len < 2) { /* Check remaining space */
- debug(F111,"getnct command too long",s2,buflen);
- printf("?Line too long, maximum length: %d.\n",buflen);
- free(lpx);
- return(-4);
- }
- ccl = (len > 0) ? lp2[len-1] : 0; /* Last character in line */
- ccx = (len > 1) ? lp2[len-2] : 0; /* Penultimate char in line */
-
-#ifdef COMMENT
- /* Line containing only whitespace and ,- */
- if ((len > 1) && (lp3 == lp2+len-2) && (ccl == '-') && (ccx == ','))
- continue;
-#endif /* COMMENT */
-
-#ifdef KLUDGE
-/*
- If it is a command and it begins with a token (like ! or .) that is not
- followed by a space, insert a space now; otherwise cmkey() can get mighty
- confused.
-*/
- if (s == s2 && !flag) {
- char *p = toktab;
- while (*p) {
- if (*p == *lp3 && *(p+1) != SP) {
- debug(F110,"getnct token",p,0);
- *lp3-- = SP;
- *lp3 = *p;
- if (lp3 < lp2) {
- lp2--;
- len++;
- }
- break;
- } else
- p++;
- }
- }
-#endif /* KLUDGE */
- lp = lp2;
-
- while ((*s++ = *lp++)) /* Copy result to target buffer */
- n--; /* accounting for length */
- s--; /* Back up over the NUL */
-
- /* Check whether this line is continued */
-
- if (flag) /* No line continuation when flag=1 */
- break; /* So break out of read-lines loop */
-
-#ifdef COMMENT
- debug(F000,"getnct first char","",*lp3);
- debug(F000,"getnct last char","",ccl);
- debug(F000,"getnct next-to-last char","",ccx);
-#endif /* COMMENT */
-
- if (bc > 0 && *lp3 == '}') { /* First char on line is '}' */
- bc--; /* Decrement block counter */
- }
-
- if (bc == 0 && /* Line is continued if bc > 0 */
-#ifdef COMMENT
- /* Not supported as of C-Kermit 6.0 */
- ccl != CMDQ && /* or line ends with CMDQ */
-#endif /* COMMENT */
- ccl != '-' && /* or line ends with dash */
- ccl != '{') /* or line ends with opening brace */
- break; /* None of those, we're done. */
-
- if (ccl == '-' || ccl == '{') /* Continuation character */
- if (ccx == CMDQ) /* But it's quoted */
- break; /* so ignore it */
-
- if (ccl == '{') { /* Last char on line is '{'? */
- bc++; /* Count the block opener. */
- } else if (ccl == '-') { /* Explicit continue? */
- char c, * ss;
- int state = 0, nn;
- s--; /* Yes, back up over terminators */
- n++; /* and over continuation character */
- nn = n; /* Save current count */
- ss = s; /* and pointer */
- s--; /* Back up over dash */
- n++;
- while (state < 2 && s >= prev) { /* Check for "{,-" */
- n++;
- c = *s--;
- if (c <= SP)
- continue;
- if (c != ',' && c != '{')
- break;
- switch (state) {
- case 0: /* Looking for comma */
- if (c == ',')
- state = 1;
- break;
- case 1: /* Looking for left brace */
- if (c == '{') {
- state = 2;
- s += 2;
- *s = NUL;
- bc++;
- }
- break;
- }
- }
- if (state != 2) { s = ss; n = nn; }
- *s = NUL;
- } else { /* None of those but (bc > 0) */
- lastcomma = s;
- *s++ = ','; /* and insert a comma */
- n--;
- }
-#ifdef COMMENT
- debug(F101,"getnct bc","",bc);
- debug(F100,"getnct continued","",0);
-#endif /* COMMENT */
-
- *s = NUL;
- prev = s;
-
- } /* read-lines while loop */
-
- if (lastcomma)
- *lastcomma = SP;
- if (!flag) /* Tack line terminator back on */
- *s++ = c;
- *s++ = NUL; /* Terminate the string */
- untab(s2); /* Done, convert tabs to spaces */
-#ifdef DEBUG
- if (!flag) {
- debug(F010,"CMD(F)",s2,0);
- }
-#endif /* DEBUG */
- free(lpx); /* Free temporary storage */
- return(0); /* Return success */
-}
-
-VOID
-shostack() { /* Dump the command stack */
- int i;
- char *p;
-#ifndef NOSPL
- for (i = cmdlvl; i > 0; i--) {
- if (cmdstk[i].src == CMD_TF) {
- p = tfnam[cmdstk[i].lvl];
- if (zfnqfp(p,TMPBUFSIZ,tmpbuf))
- p = tmpbuf;
- printf(" %2d. File : %s (line %d)\n",
- i,
- p,
- tfline[cmdstk[i].lvl]
- );
- } else if (cmdstk[i].src == CMD_MD) {
- char * m;
- m = m_arg[cmdstk[i].lvl][0]; /* Name of this macro */
- if (i > 0) { /* Special handling for 2-level */
- char *s; /* built-in macros... */
- s = m_arg[cmdstk[i-1].lvl][0]; /* Name next level up */
- if (s && cmdstk[i-1].src == CMD_MD) {
- if (!strcmp(s,"_forx"))
- m = "FOR";
- else if (!strcmp(s,"_xif"))
- m = "XIF";
- else if (!strcmp(s,"_while"))
- m = "WHILE";
- else if (!strcmp(s,"_switx"))
- m = "SWITCH";
- }
- }
- printf(" %2d. Macro : %s\n",i,m);
- } else if (cmdstk[i].src == CMD_KB) {
- printf(" %2d. Prompt:\n",i);
- } else {
- printf(" %2d. ERROR : Command source unknown\n",i);
- }
- }
-#else
- for (i = tlevel; i > -1; i--) {
- p = tfnam[i];
- if (zfnqfp(p,TMPBUFSIZ,tmpbuf))
- p = tmpbuf;
- printf(" %2d. File : %s (line %d)\n",
- i,
- p,
- tfline[i]
- );
- }
-#endif /* NOSPL */
- if (i == 0)
- printf(" %2d. Prompt: (top level)\n",0);
-}
-
-/* For command error messages - avoid dumping out the contents of some */
-/* some huge FOR loop if it contains a syntax error. */
-
-static char *
-cmddisplay(s, cx) char * s; int cx; {
- static char buf[80];
- if ((int)strlen(s) > 70) {
- sprintf(buf,"%.64s...",s); /* SAFE */
- s = buf;
- }
- return(s);
-}
-
-static VOID
-cmderr() {
- if (xcmdsrc > 0) {
- switch (cmd_err) { /* SET COMMAND ERROR-DISPLAY */
- case 0:
- break;
- case 1:
- case 2:
- if (tlevel > -1) {
-#ifndef NOSPL
- if (xcmdsrc == 2)
- printf(
-"In macro or block defined in file: %s starting about line %d\n",
- tfnam[tlevel] ? tfnam[tlevel] : "", tfline[tlevel]
- );
- else
-#endif /* NOSPL */
- printf("File: %s, Line: %d\n",
- tfnam[tlevel] ? tfnam[tlevel] : "", tfline[tlevel]
- );
- }
-#ifndef NOSPL
- if (cmd_err == 2) {
- if (cmdstk[cmdlvl].src == CMD_MD) { /* Executing a macro? */
- int m;
- m = cmdstk[cmdlvl].lvl;
- if (mlook(mactab,m_arg[m][0],nmac) >= 0)
- printf("Macro name: %s\n", m_arg[m][0]);
- }
- }
-#endif /* NOSPL */
- break;
-
- case 3:
- printf("Command stack:\n");
- shostack();
- }
- }
-}
-
-/* P A R S E R -- Top-level interactive command parser. */
-
-/*
- Call with:
- m = 0 for normal behavior: keep parsing and executing commands
- until an action command is parsed, then return with a
- Kermit start-state as the value of this function.
- m = 1 to parse only one command, can also be used to call parser()
- recursively.
- m = 2 to read but do not execute one command.
- In all cases, parser() returns:
- 0 if no Kermit protocol action required
- > 0 with a Kermit protocol start-state.
- < 0 upon error.
-*/
-int
-parser(m) int m; {
- int tfcode, xx, yy, zz; /* Workers */
- int is_tn = 0;
- int cdlost = 0;
-
-#ifndef NOSPL
- int inlevel; /* Level we were called at */
- extern int askflag, echostars;
-#endif /* NOSPL */
- char *cbp; /* Command buffer pointer */
-#ifdef MAC
- extern char *lfiles; /* Fake extern cast */
-#endif /* MAC */
- extern int interrupted;
-#ifndef NOXFER
- extern int sndcmd, getcmd, fatalio, clearrq;
-#endif /* NOXFER */
-
-#ifdef AMIGA
- reqres(); /* Restore AmigaDOS requestors */
-#endif /* AMIGA */
-
-#ifdef OS2
- if (cursor_save > -1) { /* Restore cursor if it was */
- cursorena[VCMD] = cursor_save; /* turned off during file transfer */
- cursor_save = -1;
- }
-#endif /* OS2 */
-
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"COMMAND PROMPT","",""); /* IKSD database */
-#endif /* IKSDB */
-
- is_tn = (local && network && IS_TELNET()) ||
- (!local && sstelnet);
-
- if (!xcmdsrc) /* If at top (interactive) level ... */
- concb((char)escape); /* put console in 'cbreak' mode. */
-
-#ifdef CK_TMPDIR
-/* If we were cd'd temporarily to another device or directory ... */
- if (f_tmpdir) {
- int x;
- x = zchdir((char *) savdir); /* ... restore previous directory */
- f_tmpdir = 0; /* and remember we did it. */
- debug(F111,"parser tmpdir restoring",savdir,x);
- }
-#endif /* CK_TMPDIR */
-
-#ifndef NOSPL
- inlevel = cmdlvl; /* Current macro level */
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"&parser entry maclvl","",maclvl);
- debug(F101,"&parser entry inlevel","",inlevel);
- debug(F101,"&parser entry tlevel","",tlevel);
- debug(F101,"&parser entry cmdlvl","",cmdlvl);
- debug(F101,"&parser entry m","",m);
- }
-#endif /* DEBUG */
-#endif /* NOSPL */
-
-#ifndef NOXFER
- ftreset(); /* Reset global file settings */
-#endif /* NOXFER */
-/*
- sstate becomes nonzero when a command has been parsed that requires some
- action from the protocol module. Any non-protocol actions, such as local
- directory listing or terminal emulation, are invoked directly from below.
-*/
- sstate = 0; /* Start with no start state. */
-
-#ifndef NOXFER
-#ifndef NOSPL
- query = 0; /* QUERY not active */
-#endif /* NOSPL */
-#ifndef NOHINTS
- if (!success) {
- if (local && !network && carrier != CAR_OFF) {
- int x; /* Serial connection */
- x = ttgmdm(); /* with carrier checking */
- if (x > -1) {
- if (!(x & BM_DCD)) {
- cdlost = 1;
- fatalio = 1;
- }
- }
- }
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"parser top what","",what);
- debug(F101,"parser top interrupted","",interrupted);
- debug(F101,"parser top cdlost","",cdlost);
- debug(F101,"parser top sndcmd","",sndcmd);
- debug(F101,"parser top getcmd","",getcmd);
- }
-#endif /* DEBUG */
- if (cdlost && !interrupted && (sndcmd || getcmd)) {
- printf("?Connection broken (carrier signal lost)\n");
- }
- if (sndcmd && protocol == PROTO_K &&
- !success && hints && !interrupted && !fatalio && !xcmdsrc) {
- int x = 0, n = 0;
- printf("\n*************************\n");
- printf("SEND-class command failed.\n");
- printf(" Packets sent: %d\n", spackets);
- printf(" Retransmissions: %d\n",retrans);
- printf(" Timeouts: %d\n", timeouts);
- printf(" Damaged packets: %d\n", crunched);
- if (epktrcvd) {
- printf(" Transfer canceled by receiver.\n");
- printf(" Receiver's message: \"%s\"\n",(char *)epktmsg);
- n++;
- } else {
- if (epktmsg) if (*epktmsg) {
- printf(" Fatal Kermit Protocol Error: %s\n",epktmsg);
- n++;
- }
- }
- if (local && !network && carrier != CAR_OFF) {
- int xx; /* Serial connection */
- xx = ttgmdm(); /* with carrier checking */
- if (xx > -1) {
- if (!(xx & BM_DCD))
- cdlost = 1;
- }
- }
-
-#ifdef UNIX
- if (errno != 0)
-#endif /* UNIX */
- {
- printf(" Most recent local OS error: \"%s\"\n",ck_errstr());
- n++;
- }
- printf(
- "\nHINTS... If the preceding error message%s not explain the failure:\n",
- (n > 1) ? "s do" : " does"
- );
-#ifndef NOLOCAL
- if (local) {
- if (rpackets == 0) {
- printf(" . Did you start a Kermit receiver on the far end?\n");
- } else {
- printf(
- " . Try changing the remote Kermit's FLOW-CONTROL setting.\n");
- if (!network && mdmtyp > 0)
- if ((3 * crunched) > spackets)
- printf(
- " . Try placing a new call to get a cleaner connection.\n");
- }
- } else if (rpackets > 0) {
- if (flow == FLO_NONE)
- printf(" . Give me a SET FLOW XON/XOFF command and try again.\n");
- else
- printf(" . Give me a SET FLOW NONE command and try again.\n");
- }
- x++;
-#endif /* NOLOCAL */
-
- if ((3 * timeouts) > spackets)
- printf(" . Adjust the timeout method (see HELP SET SEND).\n");
- if ((3 * retrans) > spackets)
- printf(" . Increase the retry limit (see HELP SET RETRY).\n");
-
-#ifdef CK_SPEED
- if (prefixing != PX_ALL && rpackets > 2) {
- printf(" . Try it again with: SET PREFIXING ALL\n");
- x++;
- }
-#endif /* CK_SPEED */
-#ifdef STREAMING
- if (streamed) {
- printf(" . Try it again with: SET STREAMING OFF\n");
- x++;
- } else if (reliable) {
- printf(" . Try it again with: SET RELIABLE OFF\n");
- x++;
- }
-#endif /* STREAMING */
-
-#ifdef CK_SPEED
- if (clearrq > 0 && prefixing == PX_NON) {
- printf(" . Try it again with: SET CLEAR-CHANNEL OFF\n");
- x++;
- }
-#endif /* CK_SPEED */
- if (!parity) {
- printf(" . Try it again with: SET PARITY SPACE\n");
- x++;
- }
- printf(" . %sive a ROBUST command and try again.\n",
- (x > 0) ? "As a last resort, g" : "G"
- );
- printf("Also:\n");
- printf(" . Be sure the source file has read permission.\n");
- printf(" . Be sure the target directory has write permission.\n");
-/*
- if the file was 2G or larger make sure other Kermit supports LFs...
-*/
- printf(" . Be sure the target disk has sufficient space.\n");
- printf("(Use SET HINTS OFF to suppress hints.)\n");
- printf("*************************\n\n");
- }
- debug(F101,"topcmd","",topcmd);
- if (getcmd && protocol == PROTO_K &&
- !success && hints && !interrupted && !fatalio && !xcmdsrc) {
- int x = 0;
- extern int urpsiz, wslotr;
- printf("\n*************************\n");
- printf("RECEIVE- or GET-class command failed.\n");
- printf(" Packets received: %d\n", rpackets);
- printf(" Damaged packets: %d\n", crunched);
- printf(" Timeouts: %d\n", timeouts);
- if (rpackets > 0)
- printf(" Packet length: %d\n", urpsiz);
- if (epktrcvd) {
- printf(" Transfer canceled by sender.\n");
- printf(" Sender's message: \"%s\"\n",(char *)epktmsg);
- }
-#ifdef UNIX
- if (errno != 0)
-#endif /* UNIX */
- printf(" Most recent local error: \"%s\"\n",ck_errstr());
- printf(
- "\nHINTS... If the preceding error message%s not explain the failure:\n",
- epktrcvd ? "s do" : " does"
- );
-#ifndef NOLOCAL
- if (local) {
- if (topcmd == XXGET)
- printf(" . Did you start a Kermit SERVER on the far end?\n");
- if (rpackets == 0) {
- if (topcmd != XXGET)
- printf(" . Did you start a Kermit SENDer on the far end?\n");
- } else {
- printf(
- " . Choose a different FLOW-CONTROL setting and try again.\n");
- }
- } else if (topcmd == XXGET)
- printf(" . Is the other Kermit in (or does it have) SERVER mode?\n");
- if (rpackets > 0 && urpsiz > 90)
- printf(" . Try smaller packets (SET RECEIVE PACKET-LENGTH).\n");
- if (rpackets > 0 && wslotr > 1 && !streamed)
- printf(" . Try a smaller window size (SET WINDOW).\n");
- if (!local && rpackets > 0) {
- if (flow == FLO_NONE)
- printf(" . Give me a SET FLOW XON/XOFF command and try again.\n");
- else
- printf(" . Give me a SET FLOW NONE command and try again.\n");
- }
- x++;
-#endif /* NOLOCAL */
-#ifdef STREAMING
- if (streamed) {
- printf(" . Try it again with: SET STREAMING OFF\n");
- x++;
- } else if (reliable && local) {
- printf(" . Try it again with: SET RELIABLE OFF\n");
- x++;
- } else
-#endif /* STREAMING */
- if (!parity) {
- printf(" . Try it again with: SET PARITY SPACE\n");
- x++;
- }
- printf((x > 0) ?
- " . As a last resort, give a ROBUST command and try again.\n" :
- " . Give a ROBUST command and try again.\n"
- );
- printf("Also:\n");
- printf(" . Be sure the target directory has write permission.\n");
- printf(" . Be sure the target disk has sufficient space.\n");
- printf(" . Try telling the %s to SET PREFIXING ALL.\n",
- topcmd == XXGET ? "server" : "sender"
- );
- printf(" . Try giving a ROBUST command to the %s.\n",
- topcmd == XXGET ? "server" : "sender"
- );
- printf("(Use SET HINTS OFF to suppress hints.)\n");
- printf("*************************\n\n");
- }
-#endif /* NOHINTS */
- getcmd = 0;
- sndcmd = 0;
- interrupted = 0;
-#endif /* NOXFER */
-
- while (sstate == 0) { /* Parse cmds until action requested */
- debug(F100,"parse top","",0);
- what = W_COMMAND; /* Now we're parsing commands. */
- rcdactive = 0; /* REMOTE CD not active */
- keepallchars = 0; /* MINPUT not active */
-
-#ifdef OS2
- if (apcactive == APC_INACTIVE)
- WaitCommandModeSem(-1);
-#endif /* OS2 */
-#ifdef IKS_OPTION
- if ((local &&
- !xcmdsrc &&
- is_tn &&
- TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start) ||
- (!local &&
- !cmdadl &&
- TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
- ) {
- tn_siks(KERMIT_STOP);
- }
-#endif /* IKS_OPTION */
-
-#ifndef NOXFER
- if (autopath) {
- fnrpath = PATH_AUTO;
- autopath = 0;
- }
- remfile = 0; /* Clear these in case REMOTE */
- remappd = 0; /* command was interrupted... */
- rempipe = 0;
- makestr(&snd_move,g_snd_move); /* Restore these */
- makestr(&rcv_move,g_rcv_move);
- makestr(&snd_rename,g_snd_rename);
- makestr(&rcv_rename,g_rcv_rename);
-#endif /* NOXFER */
-
- /* Take requested action if there was an error in the previous command */
-
- setint();
- debug(F101,"parser tlevel","",tlevel);
- debug(F101,"parser cmd_rows","",cmd_rows);
-
-#ifndef NOLOCAL
- debug(F101,"parser wasclosed","",wasclosed);
- if (wasclosed) { /* If connection was just closed */
-#ifndef NOSPL
- int k;
- k = mlook(mactab,"on_close",nmac); /* Look up "on_close" */
- if (k >= 0) { /* If found, */
- /* printf("ON_CLOSE CMD LOOP\n"); */
- dodo(k,ckitoa(whyclosed),0); /* Set it up */
- }
-#endif /* NOSPL */
- whyclosed = WC_REMO;
- wasclosed = 0;
- }
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
- xxdot = 0; /* Clear this... */
-
- debug(F101,"parser success","",success);
- if (success == 0) {
- if (cmdstk[cmdlvl].src == CMD_TF && takerr[cmdlvl]) {
- printf("Command file terminated by error.\n");
- popclvl();
- if (cmdlvl == 0) return(0);
- }
- if (cmdstk[cmdlvl].src == CMD_MD && merror[cmdlvl]) {
- printf("Command error: macro terminated.\n");
- popclvl();
- if (m && (cmdlvl < inlevel))
- return((int) sstate);
- }
- }
- nulcmd = (m == 2);
- debug(F101,"parser nulcmd","",nulcmd);
-#else
- if (success == 0 && tlevel > -1 && takerr[tlevel]) {
- printf("Command file terminated by error.\n");
- popclvl();
- cmini(ckxech); /* Clear the cmd buffer. */
- if (tlevel < 0) /* Just popped out of cmd files? */
- return(0); /* End of init file or whatever. */
- }
-#endif /* NOSPL */
-
-#ifdef MAC
- /* Check for TAKE initiated by menu. */
- if ((tlevel == -1) && lfiles)
- startlfile();
-#endif /* MAC */
-
- /* If in TAKE file, check for EOF */
-#ifndef NOSPL
-#ifdef MAC
- if
-#else
- while
-#endif /* MAC */
- ((cmdstk[cmdlvl].src == CMD_TF) /* If end of take file */
- && (tlevel > -1)
- && feof(tfile[tlevel])) {
- popclvl(); /* pop command level */
- cmini(ckxech); /* and clear the cmd buffer. */
- if (cmdlvl == 0) { /* Just popped out of all cmd files? */
- return(0); /* End of init file or whatever. */
- }
- }
-#ifdef MAC
- miniparser(1);
- if (sstate == 'a') { /* if cmd-. cancel */
- debug(F100, "parser: cancel take due to sstate", "", sstate);
- sstate = '\0';
- dostop();
- return(0); /* End of init file or whatever. */
- }
-#endif /* MAC */
-
-#else /* NOSPL */
- if ((tlevel > -1) && feof(tfile[tlevel])) { /* If end of take */
- popclvl(); /* Pop up one level. */
- cmini(ckxech); /* and clear the cmd buffer. */
- if (tlevel < 0) /* Just popped out of cmd files? */
- return(0); /* End of init file or whatever. */
- }
-#endif /* NOSPL */
-
-
-#ifndef NOSPL
- debug(F101,"parser cmdlvl","",cmdlvl);
- debug(F101,"parser cmdsrc","",cmdstk[cmdlvl].src);
-
- if (cmdstk[cmdlvl].src == CMD_MD) { /* Executing a macro? */
- debug(F100,"parser macro","",0);
- maclvl = cmdstk[cmdlvl].lvl; /* Get current level */
- debug(F101,"parser maclvl","",maclvl);
- cbp = cmdbuf; /* Copy next cmd to command buffer. */
- *cbp = NUL;
- if (*savbuf) { /* In case then-part of 'if' command */
- ckstrncpy(cbp,savbuf,CMDBL); /* was saved, restore it. */
- *savbuf = '\0';
- } else { /* Else get next cmd from macro def */
- if (getncm(cbp,CMDBL) < 0) {
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"parser end of macro m","",m);
- debug(F101,"parser end of macro cmdlvl","",cmdlvl);
- debug(F101,"parser end of macro inlevel","",inlevel);
- }
-#endif /* DEBUG */
- if (m && (cmdlvl < inlevel))
- return((int) sstate);
- else /* if (!m) */ continue;
- }
- }
- debug(F010,"CMD(M)",cmdbuf,0);
-
- } else if (cmdstk[cmdlvl].src == CMD_TF)
-#else
- if (tlevel > -1)
-#endif /* NOSPL */
- {
-#ifndef NOSPL
- debug(F111,"parser savbuf",savbuf,tlevel);
- if (*savbuf) { /* In case THEN-part of IF command */
- ckstrncpy(cmdbuf,savbuf,CMDBL); /* was saved, restore it. */
- *savbuf = '\0';
- } else
-#endif /* NOSPL */
-
- /* Get next line from TAKE file */
-
- if ((tfcode = getnct(cmdbuf,CMDBL,tfile[tlevel],0)) < 0) {
- debug(F111,"parser tfcode",tfile[tlevel],tfcode);
- if (tfcode < -1) { /* Error */
- printf("?Error in TAKE command file: %s\n",
- (tfcode == -2) ? "Memory allocation failure" :
- "Line too long or contains NUL characters"
- );
- dostop();
- }
- continue; /* -1 means EOF */
- }
-
- /* If interactive, get next command from user. */
-
- } else { /* User types it in. */
- if (pflag) prompt(xxstring);
- cmini(ckxech);
- }
-
- /* Now we know where next command is coming from. Parse and execute it. */
-
- repars = 1; /* 1 = command needs parsing */
-#ifndef NOXFER
- displa = 0; /* Assume no file transfer display */
-#endif /* NOXFER */
-
- while (repars) { /* Parse this cmd until entered. */
-
- debug(F101,"parser top of while loop","",0);
- xaskmore = saveask; /* Restore global more-prompting */
- diractive = 0; /* DIR command not active */
- cdactive = 0; /* CD command not active */
-#ifndef NOSPL
- askflag = 0; /* ASK command not active */
- echostars = 0; /* Nor ASKQ */
- debok = 1; /* Undisable debugging */
-#endif /* NOSPL */
-
-#ifdef RECURSIVE
- /* In case of "send /recursive ./?<Ctrl-U>" etc */
- recursive = 0; /* This is never sticky */
-#endif /* RECURSIVE */
- xfiletype = -1; /* Reset this between each command */
-#ifndef NOMSEND
- addlist = 0;
-#endif /* NOMSEND */
-#ifdef CK_RECALL
- on_recall = 1;
-#endif /* CK_RECALL */
- /* This might have been changed by a switch */
- if (g_matchdot > -1) {
- matchdot = g_matchdot;
- g_matchdot = -1;
- }
- cmres(); /* Reset buffer pointers. */
-
-#ifdef OS2
-#ifdef COMMENT
- /* we check to see if a macro is waiting to be executed */
- /* if so, we call domac on it */
- if (cmdmac) {
- ckstrncpy(cmdbuf, cmdmac, CMDBL);
- free(cmdmac);
- cmdmac = NULL;
- }
-#endif /* COMMENT */
-#endif /* OS2 */
-#ifndef NOXFER
- bye_active = 0;
-#endif /* NOXFER */
- havetoken = 0;
- xx = cmkey2(cmdtab,ncmd,"Command","",toktab,xxstring,1);
- debug(F101,"top-level cmkey2","",xx);
- if (xx == -5) {
- yy = chktok(toktab);
- debug(F101,"top-level cmkey token","",yy);
-#ifndef COMMENT
- /* Either way makes absolutely no difference */
- debug(F110,"NO UNGWORD",atmbuf,0);
- /* ungword(); */
-#else
- debug(F110,"TOKEN UNGWORD",atmbuf,0);
- ungword();
-#endif /* COMMENT */
- switch (yy) {
- case '#': xx = XXCOM; break; /* Comment */
- case ';': xx = XXCOM; break; /* Comment */
-#ifndef NOSPL
- case '.': xx = XXDEF; xxdot = 1; break; /* Assignment */
- case ':': xx = XXLBL; break; /* GOTO label */
-#endif /* NOSPL */
-
-#ifndef NOPUSH
-#ifdef CK_REDIR
- case '<':
-#endif /* CK_REDIR */
- case '@':
- case '!':
- if (nopush) {
- char *s; int x;
- if ((x = cmtxt("Text to be ignored","",&s,NULL)) < 0)
- return(x);
- success = 0;
- xx = XXCOM;
- } else {
- switch(yy) {
-#ifdef CK_REDIR
- case '<': xx = XXFUN; break; /* REDIRECT */
-#endif /* CK_REDIR */
- case '@':
- case '!': xx = XXSHE; break; /* Shell escape */
- }
- }
- break;
-#endif /* NOPUSH */
-#ifdef CK_RECALL
- case '^': xx = XXREDO; break;
-#endif /* CK_RECALL */
-#ifndef NOSPL
- case '{': xx = XXMACRO; break;
- case '(': xx = XXSEXP; break;
-#endif /* NOSPL */
-
- default:
- if (!quiet && !cmd_err) {
- printf("\n?Invalid - \"%s\"\n",
- cmddisplay((char *)cmdbuf,xx)
- );
- cmderr();
- }
- xx = -2;
- }
- havetoken = 1;
- debug(F101,"HAVE TOKEN","",xx);
- }
- if (xx > -1) {
- topcmd = xx; /* Top-level command index */
-#ifndef NOSPL
- if (maclvl > -1)
- lastcmd[maclvl] = xx;
-#endif /* NOSPL */
- debug(F101,"topcmd","",topcmd);
- debug(F101,"cmflgs","",cmflgs);
- }
-
-#ifndef NOSPL
- /* Special handling for IF..ELSE */
-
- debug(F101,"cmdlvl","",cmdlvl);
- debug(F101,"ifcmd[cmdlvl]","",ifcmd[cmdlvl]);
-
- if (ifcmd[cmdlvl]) /* Count stmts after IF */
- ifcmd[cmdlvl]++;
- if (ifcmd[cmdlvl] > 2 && xx != XXELS && xx != XXCOM)
- ifcmd[cmdlvl] = 0;
-
- /* Execute the command and take action based on return code. */
-
- if (nulcmd) { /* Ignoring this command? */
- xx = XXCOM; /* Make this command a comment. */
- }
- fnsuccess = 1; /* For catching \function() errors */
-#endif /* NOSPL */
-
- debug(F101,"calling docmd()","",xx);
- zz = docmd(xx); /* Parse rest of command & execute. */
-
-#ifndef NOSPL
- { /* For \v(lastcommand) */
- extern char * prevcmd;
- /* The exception list kind of a hack but let's try it... */
- if (ckstrcmp(cmdbuf,"_getarg",7,0) &&
- ckstrcmp(cmdbuf,"if ",3,0) &&
- ckstrcmp(cmdbuf,"xif ",4,0) &&
- ckstrcmp(cmdbuf,"do _if",6,0) &&
- ckstrcmp(cmdbuf,"_assign _if",11,0))
- ckstrncpy(prevcmd,cmdbuf,CMDBL);
- }
-#endif /* NOSPL */
-
-#ifndef NOSPL
- if (fnerror && !fnsuccess)
- success = 0;
-#endif /* NOSPL */
- debug(F101,"docmd returns","",zz);
- /* debug(F011,"cmdbuf",cmdbuf,30); */
- /* debug(F011,"atmbuf",atmbuf,30); */
-#ifdef MAC
- if (tlevel > -1) {
- if (sstate == 'a') { /* if cmd-. cancel */
- debug(F110, "parser: cancel take, sstate:", "a", 0);
- sstate = '\0';
- dostop();
- return(0); /* End of init file or whatever. */
- }
- }
-#endif /* MAC */
- switch (zz) {
- case -4: /* EOF (e.g. on redirected stdin) */
- doexit(GOOD_EXIT,xitsta); /* ...exit successfully */
- case -1: /* Reparse needed */
- repars = 1; /* Just set reparse flag and... */
- continue;
-#ifdef OS2
- case -7: /* They typed a disk letter */
- if (!zchdir((char *)cmdbuf)) {
- perror((char *)cmdbuf);
- success = 0;
- } else success = 1;
- repars = 0;
- continue;
-
-#endif /* OS2 */
- case -6: /* Invalid command given w/no args */
- case -2: { /* Invalid command given w/args */
- int x = 0;
- char * eol = "";
- x = strlen(cmdbuf); /* Avoid blank line */
- if (x > 0) {
- if (cmdbuf[x-1] != LF)
- eol = "\n";
- printf("?Invalid: %s%s",
- cmddisplay(cmdbuf,xx),eol
- );
- } else
- printf("?Invalid\n");
- }
- case -9: /* Bad, error message already done */
- success = 0;
- debug(F110,"top-level cmkey failed",cmdbuf,0);
- /* If in background w/ commands coming stdin, terminate */
- if (pflag == 0 && tlevel < 0)
- fatal("Kermit command error in background execution");
-/*
- Command retry feature, edit 190. If we're at interactive prompting level,
- reprompt the user with as much of the command as didn't fail.
-*/
-#ifdef CK_RECALL
- if (cm_retry && !xcmdsrc) { /* If at top level */
- int len;
- char *p, *s;
- len = strlen(cmdbuf); /* Length of command buffer */
- p = malloc(len + 1); /* Allocate space for copy */
- if (p) { /* If we got the space copy */
- strcpy(p,cmdbuf); /* the command buffer (SAFE). */
- /* Chop off final field, the one that failed. */
- s = p + len - 1; /* Point to end */
- while (*s == SP && s > p) /* Trim blanks */
- s--;
- while (*s != SP && s > p) /* Trim last field */
- s--;
- if (s > p) /* Keep the space */
- s++; /* after last good field */
- if (s >= p) /* Cut off remainder */
- *s = NUL;
- cmini(ckxech); /* Reinitialize the parser */
- ckstrncpy(cmdbuf,p,CMDBL); /* Copy result back */
- free(p); /* Free temporary storage */
- p = NULL;
- prompt(xxstring); /* Reprint the prompt */
- printf("%s",cmdbuf); /* Reprint partial command */
- repars = 1; /* Force reparse */
- continue;
- }
- } else
-#endif /* CK_RECALL */
- cmderr();
-
- cmini(ckxech); /* (fall thru) */
-
- case -3: /* Empty command OK at top level */
- repars = 0; /* Don't need to reparse. */
- continue; /* Go back and get another command. */
-
- default: /* Command was successful. */
-#ifndef NOSPL
- debug(F101,"parser preparing to continue","",maclvl);
-#endif /* NOSPL */
- debug(F101,"parser success","",success);
- repars = 0; /* Don't need to reparse. */
- continue; /* Go back and get another command. */
- }
- }
-#ifndef NOSPL
- debug(F101,"parser breaks out of while loop","",maclvl);
- if (m && (cmdlvl < inlevel)) return((int) sstate);
-#endif /* NOSPL */
- }
-
-/* Got an action command, return start state. */
-
- return((int) sstate);
-}
-
-#ifndef NOSPL
-/*
- OUTPUT command.
- Buffering and pacing added by L.I. Kirby, 5A(189), June 1993.
-*/
-#define OBSIZE 80 /* Size of local character buffer */
-
-static int obn; /* Buffer offset (high water mark) */
-static char obuf[OBSIZE+1]; /* OUTPUT buffer. */
-static char *obp; /* Pointer to output buffer. */
-_PROTOTYP( static int oboc, (char) );
-_PROTOTYP( static int xxout, (char *, int) );
-
-static int
-#ifdef CK_ANSIC
-xxout(char *obuf, int obsize)
-#else
-xxout(obuf, obsize) char *obuf; int obsize;
-#endif /* CK_ANSIC */
-/* xxout */ { /* OUTPUT command's output function */
- int i, rc;
-
- debug(F101,"xxout obsize","",obsize);
- debug(F101,"xxout pacing","",pacing);
- debug(F111,"xxout string",obuf,strlen(obuf));
-
- rc = 0; /* Initial return code. */
- if (!obuf || (obsize <= 0)) /* Nothing to output. */
- goto xxout_x; /* Return successfully */
-
- rc = -1; /* Now assume failure */
- if (pacing == 0) { /* Is pacing enabled? */
- if ((local ? /* No, write entire string at once */
- ttol((CHAR *)obuf, obsize) : /* to communications device */
- conxo(obsize, obuf)) /* or to console */
- != obsize)
- goto xxout_x;
- } else {
- for (i = 0; i < obsize; i++) { /* Write individual chars */
- if ((local ? ttoc(obuf[i]) : conoc(obuf[i])) < 0)
- goto xxout_x;
- msleep(pacing);
- }
- }
- if (duplex) {
-#ifdef OS2
- if (inecho && local) {
-#ifndef NOLOCAL
- for (i = 0; i < obsize; i++) { /* Write to emulator */
- scriptwrtbuf((USHORT)obuf[i]); /* which also logs session */
- }
-#endif /* NOLOCAL */
- conxo(obsize,obuf);
- } else if (seslog) { /* or log session here */
- logstr((char *) obuf, obsize);
- }
-#else /* OS2 */
- if (seslog) {
- logstr((char *) obuf, obsize);
- }
- if (inecho && local) {
- conxo(obsize,obuf);
- }
-#endif /* OS2 */
- }
- rc = 0; /* Success */
- xxout_x:
- obn = 0; /* Reset count */
- obp = obuf; /* and pointers */
- return(rc); /* return our return code */
-}
-
-#ifdef COMMENT
-/*
- Macros for OUTPUT command execution, to make it go faster.
-*/
-#define obfls() ((xxout(obuf,obn)<0)?-1:0)
-#define oboc(c) ((*obp++=(char)(c)),*obp=0,(((++obn)>=OBSIZE)?obfls():0))
-
-#else /* The macros cause some compilers to generate bad code. */
-
-static int
-#ifdef CK_ANSIC
-oboc(char c)
-#else
-oboc(c) char c;
-#endif /* CK_ANSIC */
-/* oboc */ { /* OUTPUT command's output function */
-
- *obp++ = c; /* Deposit character */
- *obp = NUL; /* Flush buffer if it's now full */
-
- return(((++obn) >= OBSIZE) ? xxout(obuf,obn) : 0);
-}
-#endif /* COMMENT */
-
-/* Routines for handling local variables -- also see popclvl(). */
-
-VOID
-freelocal(m) int m; { /* Free local variables */
- struct localvar * v, * tv; /* at macro level m... */
- debug(F101,"freelocal level","",m);
- if (m < 0) return;
- v = localhead[m]; /* List head for level m */
- while (v) {
- if (v->lv_name) /* Variable name */
- free(v->lv_name);
- if (v->lv_value) /* Value */
- free(v->lv_value);
- tv = v; /* Save pointer to this node */
- v = v->lv_next; /* Get next one */
- if (tv) /* Free this one */
- free((char *)tv);
- }
- localhead[m] = (struct localvar *) NULL; /* Done, set list head to NULL */
-}
-
-#define MAXLOCALVAR 64
-
-/* Return a pointer to the definition of a user-defined variable */
-
-static char *
-vardef(s,isarray,x1,x2) char * s; int * isarray, * x1, * x2; {
- char * p;
- char c;
- *isarray = 0;
- if (!s) return(NULL);
- if (!*s) return(NULL);
- p = s;
- if (*s == CMDQ) {
- p++;
- if (!*p)
- return(NULL);
- if ((c = *p) == '%') { /* Scalar variable. */
- c = *++p; /* Get ID character. */
- p = ""; /* Assume definition is empty */
- if (!c)
- return(NULL);
- if (c >= '0' && c <= '9') { /* Digit for macro arg */
- if (maclvl < 0) /* Digit variables are global */
- return(g_var[c]); /* if no macro is active */
- else /* otherwise */
- return(m_arg[maclvl][c - '0']); /* they're on the stack */
- } else if (isalpha(c)) {
- if (isupper(c)) c -= ('a'-'A');
- return(g_var[c]); /* Letter for global variable */
- } else
- return(NULL);
- } else if (c == '&') { /* Array reference. */
- int x, vbi, d;
- x = arraynam(p,&vbi,&d); /* Get name and subscript */
- if (x > -1 || d == -17) {
- *isarray = 1;
- *x1 = vbi;
- *x2 = (d == -17) ? 0 : d;
- }
- if (x < 0)
- return(NULL);
- if (chkarray(vbi,d) >= 0) { /* Array is declared? */
- vbi -= ARRAYBASE; /* Convert name to index */
- if (a_dim[vbi] >= d) { /* If subscript in range */
- char **ap;
- ap = a_ptr[vbi];
- return((ap) ? ap[d] : NULL);
- }
- }
- }
- return(NULL);
- } else {
- int k;
- k = mxlook(mactab,s,nmac);
- return((k > -1) ? mactab[k].mval : NULL);
- }
-}
-
-
-int
-addlocal(p) char * p; {
- int x, z, isarray = 0;
- char * s;
- struct localvar * v, *prev = (struct localvar *)NULL;
- extern int tra_asg; int tra_tmp;
-
- tra_tmp = tra_asg;
-
- s = vardef(p,&isarray,&x,&z); /* Get definition of variable */
- if (isarray) { /* Arrays are handled specially */
- pusharray(x,z);
- return(0);
- }
- if (!s) s = "";
- if ((v = localhead[cmdlvl])) { /* Already have some at this level? */
- while (v) { /* Find end of list */
- prev = v;
- v = v->lv_next;
- }
- }
- v = (struct localvar *) malloc(sizeof(struct localvar));
- if (!v) {
- printf("?Failure to allocate storage for local variables");
- return(-9);
- }
- if (!localhead[cmdlvl]) /* If first, set list head */
- localhead[cmdlvl] = v;
- else /* Otherwise link previous to this */
- prev->lv_next = v;
- prev = v; /* And make this previous */
- v->lv_next = (struct localvar *) NULL; /* No next yet */
-
- if (!(v->lv_name = (char *) malloc((int) strlen(p) + 1)))
- return(-1);
- strcpy(v->lv_name, p); /* Copy name into new node (SAFE) */
-
- if (*s) {
- if (!(v->lv_value = (char *) malloc((int) strlen(s) + 1)))
- return(-1);
- strcpy(v->lv_value, s); /* Copy value into new node (SAFE) */
- } else
- v->lv_value = NULL;
-
- tra_asg = 0;
- delmac(p,1); /* Delete the original macro */
- tra_asg = tra_tmp;
- return(0);
-}
-
-int
-dolocal() { /* Do the LOCAL command */
- int i, x;
- char * s;
- char * list[MAXLOCALVAR+2]; /* Up to 64 variables per line */
-
- if ((x = cmtxt("Variable name(s)","",&s,NULL)) < 0)
- return(x);
-
- xwords(s,MAXLOCALVAR,list,0); /* Break up line into "words" */
-
- /* Note: Arrays do not use the localhead list, but have their own stack */
-
- for (i = 1; i < MAXLOCALVAR && list[i]; i++) { /* Go through the list */
- if (addlocal(list[i]) < 0)
- goto localbad;
- }
- return(success = 1);
-
- localbad:
- printf("?Failure to allocate storage for local variables");
- freelocal(cmdlvl);
- return(-9);
-}
-
-/* D O O U T P U T -- Returns 0 on failure, 1 on success */
-
-#ifndef NOKVERBS
-#define K_BUFLEN 30
-#define SEND_BUFLEN 255
-#define sendbufd(x) { osendbuf[sendndx++] = x;\
- if (sendndx == SEND_BUFLEN) {dooutput(s,cx); sendndx = 0;}}
-#endif /* NOKVERBS */
-
-int outesc = 1; /* Process special OUTPUT escapes */
-
-int
-dooutput(s, cx) char *s; int cx; {
-#ifdef SSHBUILTIN
- extern int ssh_cas;
- extern char * ssh_cmd;
-#endif /* SSHBUILTIN */
- int x, xx, y, quote; /* Workers */
- int is_tn = 0;
-
- is_tn = (local && network && IS_TELNET()) ||
- (!local && sstelnet);
-
- debug(F111,"dooutput s",s,(int)strlen(s));
-
- if (local) { /* Condition external line */
-#ifdef NOLOCAL
- goto outerr;
-#else
- if (ttchk() < 0) {
- if (!network) {
- if (carrier != CAR_OFF) {
- int x;
- x = ttgmdm();
- if ((x > -1) && ((x & BM_DCD) == 0)) {
- printf(
-"?Carrier signal required but not present - Try SET CARRIER-WATCH OFF.\n"
- );
- return(0);
- }
- } else {
- printf(
-"?Problem with serial port or modem or cable - Try SHOW COMMUNICATIONS.\n"
- );
- return(0);
- }
- }
- printf("?Connection %s %s is not open or not functioning.\n",
- network ? "to" : "on",
- ttname
- );
- return(0);
- }
- if (ttvt(speed,flow) < 0) {
- printf("?OUTPUT initialization error\n");
- return(0);
- }
-#endif /* NOLOCAL */
- }
-#ifdef SSHBUILTIN
- if ( network && nettype == NET_SSH && ssh_cas && ssh_cmd &&
- !(strcmp(ssh_cmd,"kermit") && strcmp(ssh_cmd,"sftp"))) {
- if (!quiet)
- printf("?SSH Subsystem active: %s\n", ssh_cmd);
- return(0);
- }
-#endif /* SSHBUILTIN */
-
- if (!cmdgquo()) { /* COMMAND QUOTING OFF */
- x = strlen(s); /* Just send the string literally */
- xx = local ? ttol((CHAR *)s,x) : conxo(x,s);
- return(success = (xx == x) ? 1 : 0);
- }
- quote = 0; /* Initialize backslash (\) quote */
- obn = 0; /* Reset count */
- obp = obuf; /* and pointers */
-
- outagain:
- while ((x = *s++)) { /* Loop through the string */
- y = 0; /* Error code, 0 = no error. */
- debug(F000,"dooutput","",x);
- if (quote) { /* This character is quoted */
-#ifndef NOKVERBS
- if (x == 'k' || x == 'K') { /* \k or \K */
- extern struct keytab kverbs[];
- extern int nkverbs;
- extern char * keydefptr;
- extern int keymac;
- extern int keymacx;
- int x, y, brace = 0;
- int pause;
- char * p, * b;
- char kbuf[K_BUFLEN + 1]; /* Key verb name buffer */
- char osendbuf[SEND_BUFLEN +1];
- int sendndx = 0;
-
- if (xxout(obuf,obn) < 0) /* Flush buffer */
- goto outerr;
- debug(F100,"OUTPUT KVERB","",0); /* Send a KVERB */
- { /* Have K verb? */
- if (!*s) {
- break;
- }
-/*
- We assume that the verb name is {braced}, or it extends to the end of the
- string, s, or it ends with a space, control character, or backslash.
-*/
- p = kbuf; /* Copy verb name into local buffer */
- x = 0;
- while ((x++ < K_BUFLEN) && (*s > SP) && (*s != CMDQ)) {
- if (brace && *s == '}') {
- break;
- }
- *p++ = *s++;
- }
- if (*s && !brace) /* If we broke because of \, etc, */
- s--; /* back up so we get another look. */
- brace = 0;
- *p = NUL; /* Terminate. */
- p = kbuf; /* Point back to beginning */
- debug(F110,"dooutput kverb",p,0);
- y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
- debug(F101,"dooutput lookup",0,y);
- if (y > -1) {
- if (sendndx) {
- dooutput(osendbuf,cx);
- sendndx = 0;
- }
- dokverb(VCMD,y);
-#ifndef NOSPL
- } else { /* Is it a macro? */
- y = mxlook(mactab,p,nmac);
- if (y > -1) {
- cmpush();
- keymac = 1; /* Flag for key macro active */
- keymacx = y; /* Key macro index */
- keydefptr = s; /* Where to resume next time */
- debug(F111,"dooutput mxlook",keydefptr,y);
- parser(1);
- cmpop();
- }
-#endif /* NOSPL */
- }
- }
- quote = 0;
- continue;
- } else
-#endif /* NOKVERBS */
- if (outesc && (x == 'n' || x == 'N')) { /* \n or \N */
- if (xxout(obuf,obn) < 0) /* Flush buffer */
- goto outerr;
- debug(F100,"OUTPUT NUL","",0); /* Send a NUL */
- if (local)
- ttoc(NUL);
- else
- conoc(NUL);
- quote = 0;
- continue;
-
- } else if (outesc && (x == 'b' || x == 'B')) { /* \b or \B */
-
- if (xxout(obuf,obn) < 0) /* Flush buffer first */
- goto outerr;
- debug(F100,"OUTPUT BREAK","",0);
-#ifndef NOLOCAL
- ttsndb(); /* Send BREAK signal */
-#else
- if (local)
- ttoc(NUL);
- else
- conoc(NUL);
-#endif /* NOLOCAL */
- quote = 0; /* Turn off quote flag */
- continue; /* and not the b or B */
-#ifdef CK_LBRK
- } else if (outesc && (x == 'l' || x == 'L')) { /* \l or \L */
- if (xxout(obuf,obn) < 0) /* Flush buffer first */
- goto outerr;
- debug(F100,"OUTPUT Long BREAK","",0);
-#ifndef NOLOCAL
- ttsndlb(); /* Send Long BREAK signal */
-#else
- if (local)
- ttoc(NUL);
- else
- conoc(NUL);
-#endif /* NOLOCAL */
- quote = 0; /* Turn off quote flag */
- continue; /* and not the l or L */
-#endif /* CK_LBRK */
-
- } else if (x == CMDQ) { /* Backslash itself */
- debug(F100,"OUTPUT CMDQ","",0);
- xx = oboc(dopar(CMDQ)); /* Output the backslash. */
- if (xx < 0)
- goto outerr;
- quote = 0;
- continue;
-
- } else { /* if \ not followed by special esc */
- /* Note: Atari ST compiler won't allow macro call in "if ()" */
- xx = oboc(dopar(CMDQ)); /* Output the backslash. */
- if (xx < 0)
- goto outerr;
- quote = 0; /* Turn off quote flag */
- }
- } else if (x == CMDQ) { /* This is the quote character */
- quote = 1; /* Go back and get next character */
- continue; /* which is quoted */
- }
- xx = oboc(dopar((char)x)); /* Output this character */
- debug(F111,"dooutput",obuf,obn);
- if (xx < 0)
- goto outerr;
-#ifdef COMMENT
- if (seslog && duplex) { /* Log the character if log is on */
- logchar((char)x);
- }
-#endif /* COMMENT */
- if (x == '\015') { /* String contains carriage return */
- int stuff = -1, stuff2 = -1;
- if (tnlm) { /* TERMINAL NEWLINE ON */
- stuff = LF; /* Stuff LF */
- }
-#ifdef TNCODE
- /* TELNET NEWLINE ON/OFF/RAW */
- if (is_tn) {
- switch (TELOPT_ME(TELOPT_BINARY) ? /* NVT or BINARY */
- tn_b_nlm :
- tn_nlm
- ) {
- case TNL_CR:
- break;
- case TNL_CRNUL:
- stuff2 = stuff;
- stuff = NUL;
- break;
- case TNL_CRLF:
- stuff2 = stuff;
- stuff = LF;
- break;
- }
- }
-#endif /* TNCODE */
- if (stuff > -1) { /* Stuffing another character... */
- xx = oboc(dopar((CHAR)stuff));
- if (xx < 0)
- goto outerr;
-#ifdef COMMENT
- if (seslog && duplex) { /* Log stuffed char if appropriate */
- logchar((char)stuff);
- }
-#endif /* COMMENT */
- }
- if (stuff2 > -1) { /* Stuffing another character... */
- xx = oboc(dopar((CHAR)stuff2));
- if (xx < 0)
- goto outerr;
-#ifdef COMMENT
- if (seslog && duplex) { /* Log stuffed char if appropriate */
- logchar((char)stuff2);
- }
-#endif /* COMMENT */
- }
- if (xxout(obuf,obn) < 0) /* Flushing is required here! */
- goto outerr;
- }
- }
- if (cx == XXLNOUT) {
- s = "\015";
- cx = 0;
- goto outagain;
- }
- if (quote == 1) /* String ended with backslash */
- xx = oboc(dopar(CMDQ));
-
- if (obn > 0) /* OUTPUT done */
- if (xxout(obuf,obn) < 0) /* Flush the buffer if necessary. */
- goto outerr;
- return(1);
-
-outerr: /* OUTPUT command error handler */
- if (msgflg) printf("?OUTPUT execution error\n");
- return(0);
-
-/* Remove "local" OUTPUT macro defininitions */
-
-#ifdef COMMENT
-/* No more macros ... */
-#undef oboc
-#undef obfls
-#endif /* COMMENT */
-}
-#endif /* NOSPL */
-
-/* Display version herald and initial prompt */
-
-VOID
-herald() {
- int x = 0, i;
- extern int srvcdmsg;
- extern char * cdmsgfile[];
- char * ssl;
- char * krb4;
- char * krb5;
-
-#ifndef NOCMDL
- extern char * bannerfile;
- debug(F110,"herald bannerfile",bannerfile,0);
- if (bannerfile) {
- concb((char)escape);
- if (dotype(bannerfile,1,0,0,NULL,0,NULL,0,0,NULL,0) > 0) {
- debug(F111,"herald","srvcdmsg",srvcdmsg);
- if (srvcdmsg) {
- for (i = 0; i < 8; i++) {
- debug(F111,"herald cdmsgfile[i]",cdmsgfile[i],i);
- if (zchki(cdmsgfile[i]) > -1) {
- printf("\n");
- dotype(cdmsgfile[i],
- xaskmore,0,0,NULL,0,NULL,0,0,NULL,0);
- break;
- }
- }
- }
- return;
- }
- }
-#endif /* NOCMDL */
-
-#ifdef COMMENT
- /* The following generates bad code in SCO compilers. */
- /* Observed in both OSR5 and Unixware 2 -- after executing this */
- /* statement when all conditions are false, x has a value of -32. */
- if (noherald || quiet || bgset > 0 || (bgset != 0 && backgrd != 0))
- x = 1;
-#else
- x = 0;
- if (noherald || quiet)
- x = 1;
- else if (bgset > 0)
- x = 1;
- else if (bgset < 0 && backgrd > 0)
- x = 1;
-#endif /* COMMENT */
-
- ssl = "";
- krb4 = "";
- krb5 = "";
-#ifdef CK_AUTHENTICATION
-#ifdef CK_SSL
- ssl = "+SSL";
-#endif /* CK_SSL */
-#ifdef KRB4
- krb4 = "+KRB4";
-#endif /* KRB4 */
-#ifdef KRB5
- krb5 = "+KRB5";
-#endif /* KRB5 */
-#endif /* CK_AUTHENTICATION */
-
- if (x == 0) {
-#ifdef datageneral
- printf("%s, for%s\n",versio,ckxsys);
-#else
-#ifdef OSK
- printf("%s, for%s\n",versio,ckxsys);
-#else
-#ifdef CK_64BIT
- printf("%s, for%s%s%s%s (64-bit)\n\r",versio,ckxsys,ssl,krb4,krb5);
-#else
- printf("%s, for%s%s%s%s\n\r",versio,ckxsys,ssl,krb4,krb5);
-#endif/* CK_64BIT */
-#endif /* OSK */
-#endif /* datageneral */
- printf(" Copyright (C) 1985, %s,\n", ck_cryear);
- printf(" Trustees of Columbia University in the City of New York.\n");
-#ifdef OS2
- shoreg();
-#endif /* OS2 */
-
- if (!quiet && !backgrd) {
-#ifdef COMMENT
-/* "Default file-transfer mode is AUTOMATIC" is useless information... */
- char * s;
- extern int xfermode;
-#ifdef VMS
- s = "AUTOMATIC";
-#else
- if (xfermode == XMODE_A) {
- s = "AUTOMATIC";
- } else {
- s = gfmode(binary,1);
- }
- if (!s) s = "";
-#endif /* VMS */
- if (*s)
- printf("Default file-transfer mode is %s\n", s);
-#endif /* COMMENT */
-
- debug(F111,"herald","srvcdmsg",srvcdmsg);
- if (srvcdmsg) {
- for (i = 0; i < 8; i++) {
- debug(F111,"herald cdmsgfile[i]",cdmsgfile[i],i);
- if (zchki(cdmsgfile[i]) > -1) {
- printf("\n");
- dotype(cdmsgfile[i],
- xaskmore,0,0,NULL,0,NULL,0,0,NULL,0);
- break;
- }
- }
- }
- printf("Type ? or HELP for help.\n");
- }
- }
-}
-
-/* G F M O D E -- Get File (transfer) Mode */
-
-char *
-gfmode(binary,upcase) int binary, upcase; {
- char * s;
- switch (binary) {
- case XYFT_T: s = upcase ? "TEXT" : "text"; break;
-#ifdef VMS
- case XYFT_B: s = upcase ? "BINARY FIXED" : "binary fixed"; break;
- case XYFT_I: s = upcase ? "IMAGE" : "image"; break;
- case XYFT_L: s = upcase ? "LABELED" : "labeled"; break;
- case XYFT_U: s = upcase ? "BINARY UNDEF" : "binary undef"; break;
-#else
-#ifdef MAC
- case XYFT_B: s = upcase ? "BINARY" : "binary"; break;
- case XYFT_M: s = upcase ? "MACBINARY" : "macbinary"; break;
-#else
- case XYFT_B: s = upcase ? "BINARY" : "binary"; break;
-#ifdef CK_LABELED
- case XYFT_L: s = upcase ? "LABELED" : "labeled"; break;
-#endif /* CK_LABELED */
-#endif /* MAC */
-#endif /* VMS */
- case XYFT_X: s = upcase ? "TENEX" : "tenex"; break;
- default: s = "";
- }
- return(s);
-}
-
-#ifndef NOSPL
-static int
-isaa(s) char * s; { /* Is associative array */
- char c;
- int x;
- if (!s) s = "";
- if (!*s) return(0);
- s++;
- while ((c = *s++)) {
- if (c == '<') {
- x = strlen(s);
- return ((*(s+x-1) == '>') ? 1 : 0);
- }
- }
- return(0);
-}
-
-/* M L O O K -- Lookup the macro name in the macro table */
-
-/*
- Call this way: v = mlook(table,word,n);
-
- table - a 'struct mtab' table.
- word - the target string to look up in the table.
- n - the number of elements in the table.
-
- The keyword table must be arranged in ascending alphabetical order, and
- all letters must be lowercase.
-
- Returns the table index, 0 or greater, if the name was found, or:
-
- -3 if nothing to look up (target was null),
- -2 if ambiguous,
- -1 if not found.
-
- A match is successful if the target matches a keyword exactly, or if
- the target is a prefix of exactly one keyword. It is ambiguous if the
- target matches two or more keywords from the table.
-*/
-int
-mlook(table,cmd,n) struct mtab table[]; char *cmd; int n; {
- register int i;
- int v, w, cmdlen = 0;
- char c = 0, c1, * s;
- if (!cmd) cmd = "";
-
- for (s = cmd; *s; s++) cmdlen++; /* (instead of strlen) */
- debug(F111,"MLOOK",cmd,cmdlen);
-
- c1 = *cmd;
- if (isupper(c1))
- c1 = tolower(c1);
- if (cmdlen < 1)
- return(-3);
-
-/* Not null, look it up */
-
- if (n < 12) { /* Not worth it for small tables */
- i = 0;
- } else { /* Binary search for where to start */
- int lo = 0;
- int hi = n;
- int count = 0;
- while (lo+2 < hi && ++count < 12) {
- i = lo + ((hi - lo) / 2);
- c = *(table[i].kwd);
- if (isupper(c)) c = tolower(c);
- if (c < c1) {
- lo = i;
- } else {
- hi = i;
- }
- }
- i = (c < c1) ? lo+1 : lo;
- }
- for ( ; i < n-1; i++) {
- s = table[i].kwd;
- if (!s) s = "";
- if (!*s) continue; /* Empty table entry */
- c = *s;
- if (isupper(c)) c = tolower(c);
- if (c1 != c) continue; /* First char doesn't match */
- if (!ckstrcmp(s,cmd,-1,0)) /* Have exact match? */
- return(i);
- v = !ckstrcmp(s,cmd,cmdlen,0);
- w = ckstrcmp(table[i+1].kwd,cmd,cmdlen,0);
- if (v && w) /* Have abbreviated match? */
- return(i);
- if (v) /* Ambiguous? */
- return(-2);
- if (w > 0) /* Past our alphabetic area? */
- return(-1);
- }
-
-/* Last (or only) element */
-
- if (!ckstrcmp(table[n-1].kwd,cmd,cmdlen,0))
- return(n-1);
-
- return(-1);
-}
-
-/* mxlook is like mlook, but an exact full-length match is required */
-
-int
-mxlook(table,cmd,n) char *cmd; struct mtab table[]; int n; {
- register int i;
- int w, cmdlen = 0, one = 0;
- register char c = 0, c1, * s;
-
- if (!cmd) cmd = ""; /* Check args */
-
- for (s = cmd; *s; s++) cmdlen++; /* (instead of strlen) */
- debug(F111,"MXLOOK",cmd,cmdlen);
-
- c1 = *cmd; /* First char of string to look up */
- if (isupper(c1))
- c1 = tolower(c1);
- if (!*(cmd+1)) /* Special handling for 1-char names */
- one = 1;
-
- if (cmdlen < 1) /* Nothing to look up */
- return(-3);
-
- if (n < 12) { /* Not worth it for small tables */
- i = 0;
- } else { /* Binary search for where to start */
- int lo = 0;
- int hi = n;
- int count = 0;
- while (lo+2 < hi && ++count < 12) {
- i = lo + ((hi - lo) / 2);
- c = *(table[i].kwd);
- if (isupper(c)) c = tolower(c);
- if (c < c1) {
- lo = i;
- } else {
- hi = i;
- }
- }
- i = (c < c1) ? lo+1 : lo;
- }
- for ( ; i < n; i++) { /* Look thru table */
- s = table[i].kwd; /* This entry */
- if (!s) s = "";
- if (!*s) continue; /* Empty table entry */
- c = *s;
- if (isupper(c)) c = tolower(c);
- if (c1 != c) continue; /* First char doesn't match */
- if (one) { /* Name is one char long */
- if (!*(s+1))
- return(i); /* So is table entry */
- }
-#ifdef COMMENT
- if (((int)strlen(s) == cmdlen) &&
- (!ckstrcmp(s,cmd,cmdlen,0))) return(i);
-#else
- w = ckstrcmp(s,cmd,-1,0);
- if (!w) return(i);
- if (w > 0) return(-1);
-#endif /* COMMENT */
- }
- return(-1);
-}
-
-/* mxxlook is like mxlook, but case-sensitive */
-
-int
-mxxlook(table,cmd,n) char *cmd; struct mtab table[]; int n; {
- int i, cmdlen;
- if (!cmd) cmd = "";
- if (((cmdlen = strlen(cmd)) < 1) || (n < 1)) return(-3);
- /* debug(F111,"mxxlook target",cmd,n); */
- for (i = 0; i < n; i++) {
- if (((int)strlen(table[i].kwd) == cmdlen) &&
- (!strncmp(table[i].kwd,cmd,cmdlen)))
- return(i);
- }
- return(-1);
-}
-
-static int
-traceval(nam, val) char * nam, * val; { /* For TRACE command */
- if (val)
- printf(">>> %s: \"%s\"\n", nam, val);
- else
- printf(">>> %s: (undef)\n", nam);
- return(0);
-}
-
-#ifdef USE_VARLEN /* Not used */
-
-/* V A R L E N -- Get length of variable's value.
-
- Given a variable name, return the length of its definition or 0 if the
- variable is not defined. If it is defined, set argument s to point to its
- definition. Otherwise set s to NULL.
-*/
-int
-varlen(nam,s) char *nam; char **s; { /* Length of value of variable */
- int x, z;
- char *p = NULL, c;
-
- *s = NULL;
- if (!nam) return(0); /* Watch out for null pointer */
- if (*nam == CMDQ) {
- nam++;
- if (*nam == '%') { /* If it's a variable name */
- if (!(c = *(nam+1))) return(0); /* Get letter or digit */
- p = (char *)0; /* Initialize value pointer */
- if (maclvl > -1 && c >= '0' && c <= '9') { /* Digit? */
- p = m_arg[maclvl][c - '0']; /* Pointer from macro-arg table */
- } else { /* It's a global variable */
- if (c < 33 || c > GVARS) return(0);
- p = g_var[c]; /* Get pointer from global-var table */
- }
- } else if (*nam == '&') { /* An array reference? */
- char **q;
- if (arraynam(nam,&x,&z) < 0) /* If syntax is bad */
- return(-1); /* return -1. */
- x -= ARRAYBASE; /* Convert name to number. */
- if ((q = a_ptr[x]) == NULL) /* If array not declared, */
- return(0); /* return -2. */
- if (z > a_dim[x]) /* If subscript out of range, */
- return(0); /* return -3. */
- p = q[z];
- }
- } else { /* Macro */
- z = isaa(nam);
- x = z ? mxxlook(mactab,nam,nmac) : mlook(mactab,nam,nmac);
- if (x < 0)
- return(0);
- p = mactab[x].mval;
- }
- if (p)
- *s = p;
- else
- p = "";
- return((int)strlen(p));
-}
-#endif /* USE_VARLEN */
-
-/*
- This routine is for the benefit of those compilers that can't handle
- long string constants or continued lines within them. Long predefined
- macros like FOR, WHILE, and XIF have their contents broken up into
- arrays of string pointers. This routine concatenates them back into a
- single string again, and then calls the real addmac() routine to enter
- the definition into the macro table.
-*/
-int
-addmmac(nam,s) char *nam, *s[]; { /* Add a multiline macro definition */
- int i, x, y; char *p;
- x = 0; /* Length counter */
- for (i = 0; (y = (int)strlen(s[i])) > 0; i++) { /* Add up total length */
- debug(F111,"addmmac line",s[i],y);
- x += y;
- }
- debug(F101,"addmmac lines","",i);
- debug(F101,"addmmac loop exit","",y);
- debug(F111,"addmmac length",nam,x);
- if (x < 0) return(-1);
-
- p = malloc(x+1); /* Allocate space for all of it. */
- if (!p) {
- printf("?addmmac malloc error: %s\n",nam);
- debug(F110,"addmmac malloc error",nam,0);
- return(-1);
- }
- *p = '\0'; /* Start off with null string. */
- for (i = 0; *s[i]; i++) /* Concatenate them all together. */
- ckstrncat(p,s[i],x+1);
- y = (int)strlen(p); /* Final precaution. */
- debug(F111,"addmmac constructed string",p,y);
- if (y == x) {
- y = addmac(nam,p); /* Add result to the macro table. */
- } else {
- debug(F100,"addmmac length mismatch","",0);
- printf("\n!addmmac internal error!\n");
- y = -1;
- }
- free(p); /* Free the temporary copy. */
- return(y);
-}
-
-/* Here is the real addmac routine. */
-
-/* Returns -1 on failure, macro table index >= 0 on success. */
-
-int mtchanged = 0;
-
-int
-addmac(nam,def) char *nam, *def; { /* Add a macro to the macro table */
- int i, x, y, z, namlen, deflen, flag = 0;
- int replacing = 0, deleting = 0;
- char * p = NULL, c, *s;
- extern int tra_asg; int tra_tmp;
-
- if (!nam) return(-1);
- if (!*nam) return(-1);
-
-#ifdef IKSD
- if (inserver &&
-#ifdef IKSDCONF
- iksdcf
-#else /* IKSDCONF */
- 1
-#endif /* IKSDCONF */
- ) {
- if (!ckstrcmp("on_exit",nam,-1,0) ||
- !ckstrcmp("on_logout",nam,-1,0))
- return(-1);
- }
-#endif /* IKSD */
-
- namlen = 0;
- p = nam;
- while (*p++) namlen++; /* (instead of strlen) */
-
- tra_tmp = tra_asg; /* trace... */
- debug(F111,"addmac nam",nam,namlen);
- if (!def) { /* Watch out for null pointer */
- deflen = 0;
- debug(F111,"addmac def","(null pointer)",deflen);
- } else {
- deflen = 0;
- p = def;
- while (*p++) deflen++; /* (instead of strlen) */
- debug(F010,"addmac def",def,0);
- }
-#ifdef USE_VARLEN /* NOT USED */
- /* This does not boost performance much because varlen() does a lot */
- x = varlen(nam,&s);
- if (x > 0 && x >= deflen) {
- strcpy(s,def); /* NOT USED */
- flag = 1;
- p = s;
- }
-#endif /* USE_VARLEN */
-
- if (*nam == CMDQ) nam++; /* Backslash quote? */
- if (*nam == '%') { /* Yes, if it's a variable name, */
- if (!(c = *(nam + 1))) return(-1); /* Variable name letter or digit */
- if (!flag) {
- tra_asg = 0;
- delmac(nam,0); /* Delete any old value. */
- tra_asg = tra_tmp;
- }
- if (deflen < 1) { /* Null definition */
- p = NULL; /* Better not malloc or strcpy! */
- } else if (!flag) { /* A substantial definition */
- p = malloc(deflen + 1); /* Allocate space for it */
- if (!p) {
- printf("?addmac malloc error 2\n");
- return(-1);
- } else strcpy(p,def); /* Copy def into new space (SAFE) */
- }
-
- /* Now p points to the definition, or is a null pointer */
-
- if (c >= '0' && c <= '9') { /* \%0-9 variable */
- if (maclvl < 0) { /* Are we calling or in a macro? */
- g_var[c] = p; /* No, it's top level one */
- makestr(&(toparg[c - '0']),p); /* Take care \&_[] too */
- } else { /* Yes, it's a macro argument */
- m_arg[maclvl][c - '0'] = p; /* Assign the value */
- makestr(&(m_xarg[maclvl][c - '0']),p); /* And a copy here */
- }
- } else { /* It's a \%a-z variable */
- if (c < 33 || (unsigned int)c > GVARS) return(-1);
- if (isupper(c)) c = (char) tolower(c);
- g_var[c] = p; /* Put pointer in global-var table */
- }
- if (tra_asg) traceval(nam,p);
- return(0);
- } else if (*nam == '&') { /* An array reference? */
- char **q = NULL;
- int rc = 0;
- if ((y = arraynam(nam,&x,&z)) < 0) /* If syntax is bad */
- return(-1); /* return -1. */
- if (chkarray(x,z) < 0) /* If array not declared or */
- rc = -2; /* subscript out of range, ret -2 */
- if (!flag) {
- tra_asg = 0;
- delmac(nam,0); /* Delete any old value. */
- tra_asg = tra_tmp;
- }
- x -= ARRAYBASE; /* Convert name letter to index. */
- if (x > 'z' - ARRAYBASE + 1)
- rc = -1;
- if (rc != -1) {
- if ((q = a_ptr[x]) == NULL) /* If array not declared, */
- return(-3); /* return -3. */
- }
- if (rc < 0)
- return(rc);
- if (!flag) {
- if (deflen > 0) {
- if ((p = malloc(deflen+1)) == NULL) { /* Allocate space */
- printf("addmac macro error 7: %s\n",nam);
- return(-4); /* for new def, return -4 on fail. */
- }
- strcpy(p,def); /* Copy def into new space (SAFE). */
- } else p = NULL;
- }
- q[z] = p; /* Store pointer to it. */
- if (x == 0) { /* Arg vector array */
- if (z >= 0 && z <= 9) { /* Copy values to corresponding */
- if (maclvl < 0) { /* \%1..9 variables. */
- makestr(&(toparg[z]),p);
- } else {
- makestr(&(m_arg[maclvl][z]),p);
- }
- }
- }
- if (tra_asg) traceval(nam,p);
- return(0); /* Done. */
- }
-
-/* Not a macro argument or a variable, so it's a macro definition */
-
-#ifdef USE_VARLEN
- if (flag) {
- if (tra_asg) traceval(nam,p);
- return(0);
- }
-#endif /* USE_VARLEN */
- x = isaa(nam) ? /* If it's an associative array */
- mxxlook(mactab,nam,nmac) : /* look it up this way */
- mxlook(mactab,nam,nmac); /* otherwise this way. */
- if (x > -1) { /* If found... */
- if (deflen > 0) /* and a new definition was given */
- replacing = 1; /* we're replacing */
- else /* otherwise */
- deleting = 1; /* we're deleting */
- }
- if (deleting) { /* Deleting... */
- if (delmac(nam,0) < 0)
- return(-1);
- mtchanged++;
- if (tra_asg) traceval(nam,p);
- return(0);
- } else if (deflen < 1) /* New macro with no definition */
- return(0); /* Nothing to do. */
-
- if (replacing) { /* Replacing an existing macro */
- if (mactab[x].mval) { /* If it currently has a definition, */
- free(mactab[x].mval); /* free it. */
- mactab[x].mval = NULL;
- }
- mtchanged++;
- y = x; /* Replacement index. */
-
- } else { /* Adding a new macro... */
- char c1, c2; /* Use fast lookup to find the */
- c1 = *nam; /* alphabetical slot. */
- if (isupper(c1)) c1 = (char) tolower(c1);
-
- if (nmac < 5) { /* Not worth it for small tables */
- y = 0;
- } else { /* First binary search to find */
- int lo = 0; /* where to start */
- int hi = nmac;
- int count = 0;
- char c = 0;
- while (lo+2 < hi && ++count < 12) {
- y = lo + ((hi - lo) / 2);
- c = *(mactab[y].kwd);
- if (isupper(c)) c = (char) tolower(c);
- if (c < c1) {
- lo = y;
- } else {
- hi = y;
- }
- }
- y = (c < c1) ? lo+1 : lo;
- }
- /* Now search linearly from starting location */
- for ( ; y < MAC_MAX && mactab[y].kwd != NULL; y++) {
- c2 = *(mactab[y].kwd);
- if (isupper(c2)) c2 = (char) tolower(c2);
- if (c1 > c2)
- continue;
- if (c1 < c2)
- break;
- if (ckstrcmp(nam,mactab[y].kwd,-1,0) <= 0)
- break;
- }
- if (y == MAC_MAX) { /* Macro table is full. */
- debug(F101,"addmac table overflow","",y);
- printf("?Macro table overflow\n");
- return(-1);
- }
- if (mactab[y].kwd != NULL) { /* Must insert */
- for (i = nmac; i > y; i--) { /* Move the rest down one slot */
- mactab[i].kwd = mactab[i-1].kwd;
- mactab[i].mval = mactab[i-1].mval;
- mactab[i].flgs = mactab[i-1].flgs;
- }
- }
- mtchanged++;
- p = malloc(namlen + 1); /* Allocate space for name */
- if (!p) {
- printf("?Addmac: Out of memory - \"%s\"\n",nam);
- return(-1);
- }
- strcpy(p,nam); /* Copy name into new space (SAFE) */
- mactab[y].kwd = p; /* Add pointer to table */
- }
- if (deflen > 0) { /* If we have a definition */
- p = malloc(deflen + 1); /* Get space */
- if (p == NULL) {
- printf("?Space exhausted - \"%s\"\n", nam);
- if (mactab[y].kwd) {
- free(mactab[y].kwd);
- mactab[y].kwd = NULL;
- }
- return(-1);
- } else {
- strcpy(p,def); /* Copy the definition (SAFE) */
- }
- } else { /* definition is empty */
- p = NULL;
- }
- mactab[y].mval = p; /* Macro points to definition */
- mactab[y].flgs = 0; /* No flags */
- if (!replacing) /* If new macro */
- nmac++; /* count it */
- if (tra_asg) traceval(nam,p);
- return(y);
-}
-
-int
-xdelmac(x) int x; { /* Delete a macro given its index */
- int i;
- extern int tra_asg;
- if (x < 0) return(x);
- if (tra_asg)
- traceval(mactab[x].kwd,NULL);
-
- if (mactab[x].kwd) { /* Free the storage for the name */
- free(mactab[x].kwd);
- mactab[x].kwd = NULL;
- }
- if (mactab[x].mval) { /* and for the definition */
- free(mactab[x].mval);
- mactab[x].mval = NULL;
- }
- for (i = x; i < nmac; i++) { /* Now move up the others. */
- mactab[i].kwd = mactab[i+1].kwd;
- mactab[i].mval = mactab[i+1].mval;
- mactab[i].flgs = mactab[i+1].flgs;
- }
- nmac--; /* One less macro */
-
- mactab[nmac].kwd = NULL; /* Delete last item from table */
- mactab[nmac].mval = NULL;
- mactab[nmac].flgs = 0;
- mtchanged++;
- return(0);
-}
-
-int
-delmac(nam,exact) char *nam; int exact; { /* Delete the named macro */
- int x, z;
- char *p, c;
- extern int tra_asg;
-
- if (!nam) return(0); /* Watch out for null pointer */
- debug(F110,"delmac nam",nam,0);
-#ifdef IKSD
- if ( inserver &&
-#ifdef IKSDCONF
- iksdcf
-#else /* IKSDCONF */
- 1
-#endif /* IKSDCONF */
- ) {
- if (!ckstrcmp("on_exit",nam,-1,0) ||
- !ckstrcmp("on_logout",nam,-1,0))
- return(-1);
- }
-#endif /* IKSD */
-
- if (*nam == CMDQ) nam++;
- if (*nam == '%') { /* If it's a variable name */
- if (!(c = *(nam+1))) return(0); /* Get variable name letter or digit */
- p = (char *)0; /* Initialize value pointer */
- if (maclvl < 0 && c >= '0' && c <= '9') { /* Top-level digit? */
- p = toparg[c - '0'];
- if (p) if (p != g_var[c]) {
- free(p);
- toparg[c - '0'] = NULL;
- }
- p = g_var[c];
- g_var[c] = NULL; /* Zero the table entry */
- } else if (maclvl > -1 && c >= '0' && c <= '9') { /* Digit? */
- p = m_xarg[maclvl][c - '0'];
- if (p) if (p != g_var[c]) {
- free(p);
- m_xarg[maclvl][c - '0'] = NULL;
- }
- p = m_arg[maclvl][c - '0']; /* Get pointer from macro-arg table */
- m_arg[maclvl][c - '0'] = NULL; /* Zero the table pointer */
- } else { /* It's a global variable */
- if (c < 33 || (unsigned int)c > GVARS) return(0);
- p = g_var[c]; /* Get pointer from global-var table */
- g_var[c] = NULL; /* Zero the table entry */
- }
- if (p) {
- debug(F010,"delmac def",p,0);
- free(p); /* Free the storage */
- p = NULL;
- } else debug(F110,"delmac def","(null pointer)",0);
- if (tra_asg) traceval(nam,NULL);
- return(0);
- }
- if (*nam == '&') { /* An array reference? */
- char **q;
- if (arraynam(nam,&x,&z) < 0) /* If syntax is bad */
- return(-1); /* return -1. */
- x -= ARRAYBASE; /* Convert name to number. */
- if ((q = a_ptr[x]) == NULL) /* If array not declared, */
- return(-2); /* return -2. */
- if (z > a_dim[x]) /* If subscript out of range, */
- return(-3); /* return -3. */
- if (q[z]) { /* If there is an old value, */
- debug(F010,"delmac def",q[z],0);
- if (x != 0) /* Macro arg vector is just a copy */
- free(q[z]); /* Others are real so free them */
- q[z] = NULL;
- if (x == 0) { /* Arg vector array */
- if (z >= 0 && z <= 9) { /* Copy values to corresponding */
- if (maclvl < 0) { /* \%1..9 variables. */
- makestr(&(toparg[z]),NULL);
- } else {
- makestr(&(m_arg[maclvl][z]),NULL);
- }
- }
- }
- if (tra_asg) traceval(nam,NULL);
- } else debug(F010,"delmac def","(null pointer)",0);
- }
-
- /* Not a variable or an array, so it must be a macro. */
-
- z = isaa(nam);
- debug(F111,"delmac isaa",nam,z);
- debug(F111,"delmac exact",nam,exact);
- x = z ? mxxlook(mactab,nam,nmac) :
- exact ? mxlook(mactab,nam,nmac) :
- mlook(mactab,nam,nmac);
- if (x < 0) {
- debug(F111,"delmac mlook",nam,x);
- return(x);
- }
- return(xdelmac(x));
-}
-
-VOID
-initmac() { /* Init macro & variable tables */
- int i, j, x;
-
- nmac = 0; /* No macros */
- for (i = 0; i < MAC_MAX; i++) { /* Initialize the macro table */
- mactab[i].kwd = NULL;
- mactab[i].mval = NULL;
- mactab[i].flgs = 0;
- }
- mtchanged++;
- x = (MAXARGLIST + 1) * sizeof(char **);
- for (i = 0; i < MACLEVEL; i++) { /* Init the macro argument tables */
- m_xarg[i] = (char **) malloc(x);
- mrval[i] = NULL; /* Macro return value */
- /* Pointer to entire argument vector, level i, for \&_[] array */
- for (j = 0; j <= MAXARGLIST; j++) { /* Macro argument list */
- if (j < 10) /* For the \%0..\%9 variables */
- m_arg[i][j] = NULL; /* Pointer to arg j, level i. */
- if (m_xarg[i]) /* For \&_[] - all args. */
- m_xarg[i][j] = NULL;
- }
- }
- for (i = 0; i < GVARS; i++) { /* And the global variables table */
- g_var[i] = NULL;
- }
- /* And the table of arrays */
- for (i = 0; i < (int) 'z' - ARRAYBASE + 1; i++) {
- a_ptr[i] = (char **) NULL; /* Null pointer for each */
- a_dim[i] = 0; /* and a dimension of zero */
- a_link[i] = -1;
- for (j = 0; j < CMDSTKL; j++) {
- aa_ptr[j][i] = (char **) NULL;
- aa_dim[j][i] = 0;
- }
- }
-}
-
-int
-popclvl() { /* Pop command level, return cmdlvl */
- extern int tra_cmd;
- struct localvar * v;
- int i, topcmd;
- debug(F101,"popclvl cmdlvl","",cmdlvl);
- if (cmdlvl > 0) {
- if ((v = localhead[cmdlvl])) { /* Did we save any variables? */
- while (v) { /* Yes */
- if (v->lv_value) /* Copy old ones back */
- addmac(v->lv_name,v->lv_value);
- else
- delmac(v->lv_name,1);
- v = v->lv_next;
- }
- freelocal(cmdlvl); /* Free local storage */
- }
- /* Automatic arrays do not use the localhead list */
-
- for (i = 0; i < 28; i++) { /* Free any local arrays */
- if (aa_ptr[cmdlvl][i]) { /* Does this one exist? */
- dclarray((char)(i+ARRAYBASE),-1); /* Destroy global one */
- a_ptr[i] = aa_ptr[cmdlvl][i];
- a_dim[i] = aa_dim[cmdlvl][i];
- aa_ptr[cmdlvl][i] = (char **)NULL;
- aa_dim[cmdlvl][i] = 0;
- } else if (aa_dim[cmdlvl][i] == -23) { /* Secret code */
- dclarray((char)(i+ARRAYBASE),-1); /* (see pusharray()) */
- aa_ptr[cmdlvl][i] = (char **)NULL;
- aa_dim[cmdlvl][i] = 0;
- }
-
- /* Otherwise do nothing - it is a local array that was declared */
- /* at a level above this one so leave it alone. */
- }
- }
- if (cmdlvl < 1) { /* If we're already at top level */
- cmdlvl = 0; /* just make sure all the */
- tlevel = -1; /* stack pointers are set right */
- maclvl = -1; /* and return */
- } else if (cmdstk[cmdlvl].src == CMD_TF) { /* Reading from TAKE file? */
- debug(F101,"popclvl tlevel","",tlevel);
- if (tlevel > -1) { /* Yes, */
- fclose(tfile[tlevel]); /* close it */
-
- if (tra_cmd)
- printf("[%d] -F: \"%s\"\n",cmdlvl,tfnam[tlevel]);
- debug(F111,"CMD -F",tfnam[tlevel],cmdlvl);
- if (tfnam[tlevel]) { /* free storage for name */
- free(tfnam[tlevel]);
- tfnam[tlevel] = NULL;
- }
- tlevel--; /* and pop take level */
- cmdlvl--; /* and command level */
- quiet = xquiet[cmdlvl];
- vareval = xvarev[cmdlvl];
- } else
- tlevel = -1;
- } else if (cmdstk[cmdlvl].src == CMD_MD) { /* In a macro? */
- topcmd = lastcmd[maclvl];
- debug(F101,"popclvl maclvl","",maclvl);
- if (maclvl > -1) { /* Yes, */
-#ifdef COMMENT
- int i;
- char **q;
-#endif /* COMMENT */
- macp[maclvl] = ""; /* set macro pointer to null string */
- *cmdbuf = '\0'; /* clear the command buffer */
-
- if ((maclvl > 0) && /* 2 May 1999 */
- (m_arg[maclvl-1][0]) &&
- (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
- !strncmp(m_arg[maclvl-1][0],"_for",4) ||
- !strncmp(m_arg[maclvl-1][0],"_swi",4) ||
- !strncmp(m_arg[maclvl-1][0],"_whi",4)) &&
- mrval[maclvl+1]) {
- makestr(&(mrval[maclvl-1]),mrval[maclvl+1]);
- }
- if (maclvl+1 < MACLEVEL) {
- if (mrval[maclvl+1]) { /* Free any deeper return values. */
- free(mrval[maclvl+1]);
- mrval[maclvl+1] = NULL;
- }
- }
- if (tra_cmd)
- printf("[%d] -M: \"%s\"\n",cmdlvl,m_arg[cmdstk[cmdlvl].lvl][0]);
- debug(F111,"CMD -M",m_arg[cmdstk[cmdlvl].lvl][0],cmdlvl);
-
- maclvl--; /* Pop macro level */
- cmdlvl--; /* and command level */
- debug(F101,"popclvl mac new maclvl","",maclvl);
- debug(F010,"popclvl mac mrval[maclvl+1]",mrval[maclvl+2],0);
-
- quiet = xquiet[cmdlvl];
- vareval = xvarev[cmdlvl];
- if (maclvl > -1) {
- a_ptr[0] = m_xarg[maclvl];
- a_dim[0] = n_xarg[maclvl] - 1;
- debug(F111,"a_dim[0]","B",a_dim[0]);
- } else {
- a_ptr[0] = topxarg;
- a_dim[0] = topargc - 1;
- debug(F111,"a_dim[0]","C",a_dim[0]);
- }
- } else {
- maclvl = -1;
- }
-#ifndef NOSEXP
- debug(F101,"popclvl topcmd","",topcmd);
- if (topcmd == XXSEXP) {
- extern char * sexpval;
- makestr(&(mrval[maclvl+1]),sexpval);
- }
-#endif /* NOSEXP */
- } else {
- cmdlvl--;
- }
- debug(F101,"popclvl cmdlvl","",cmdlvl);
- if (prstring[cmdlvl]) {
- cmsetp(prstring[cmdlvl]);
- makestr(&(prstring[cmdlvl]),NULL);
- }
-#ifndef MAC
- if (cmdlvl < 1 || xcmdsrc == CMD_KB) { /* If at prompt */
- setint();
- concb((char)escape); /* Go into cbreak mode */
- }
-#endif /* MAC */
- xcmdsrc = cmdstk[cmdlvl].src;
- debug(F101,"popclvl xcmdsrc","",xcmdsrc);
- debug(F101,"popclvl tlevel","",tlevel);
- return(cmdlvl < 1 ? 0 : cmdlvl); /* Return command level */
-}
-#else /* No script programming language */
-int popclvl() { /* Just close current take file. */
- if (tlevel > -1) { /* if any... */
- if (tfnam[tlevel]) {
- free(tfnam[tlevel]);
- tfnam[tlevel] = NULL;
- }
- fclose(tfile[tlevel--]);
- }
- if (tlevel == -1) { /* And if back at top level */
- setint();
- concb((char)escape); /* and go back into cbreak mode. */
- }
- xcmdsrc = tlevel > -1 ? CMD_TF : 0;
- return(tlevel + 1);
-}
-#endif /* NOSPL */
-
-
-#ifndef NOSPL
-static int
-iseom(m) char * m; { /* Test if at end of macro def */
- if (!m)
- m = "";
- debug(F111,"iseom",m,maclvl);
- while (*m) {
- /* Anything but Space and Comma means more macro is left */
- if ((*m > SP) && (*m != ',')) {
- debug(F111,"iseom return",m,0);
- return(0);
- }
- m++;
- }
- debug(F111,"iseom return",m,1);
- return(1); /* Nothing left */
-}
-#endif /* NOSPL */
-
-/* Pop all command levels that can be popped */
-
-int
-prepop() {
- if (cmdlvl > 0) { /* If command level is > 0 and... */
- while (
-#ifndef NOSPL
- ((cmdstk[cmdlvl].src == CMD_TF) && /* Command source is file */
-#endif /* NOSPL */
- (tlevel > -1) &&
- feof(tfile[tlevel])) /* And at end of file... */
-#ifndef NOSPL
- /* Or command source is macro... */
- || ((cmdstk[cmdlvl].src == CMD_MD) &&
- (maclvl > -1) &&
- iseom(macp[maclvl]))) /* and at end of macro, then... */
-#endif /* NOSPL */
- {
- popclvl(); /* pop command level. */
- }
- }
- return(cmdlvl < 1 ? 0 : cmdlvl); /* Return command level */
-}
-
-/* STOP - get back to C-Kermit prompt, no matter where from. */
-
-int
-dostop() {
- extern int cmddep;
- while (popclvl()) ; /* Pop all macros & take files */
-#ifndef NOSPL
- if (cmddep > -1) /* And all recursive cmd pkg invocations */
- while (cmpop() > -1) ;
-#endif /* NOSPL */
- cmini(ckxech); /* Clear the command buffer. */
- return(0);
-}
-
-/* Close the given log */
-
-int
-doclslog(x) int x; {
- int y;
- switch (x) {
-#ifdef DEBUG
- case LOGD:
- if (deblog <= 0) {
- printf("?Debugging log wasn't open\n");
- return(0);
- }
- debug(F100,"Debug Log Closed","",0L);
- *debfil = '\0';
- deblog = 0;
- return(zclose(ZDFILE));
-#endif /* DEBUG */
-
-#ifndef NOXFER
- case LOGP:
- if (pktlog <= 0) {
- printf("?Packet log wasn't open\n");
- return(0);
- }
- *pktfil = '\0';
- pktlog = 0;
- return(zclose(ZPFILE));
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
- case LOGS:
- if (seslog <= 0) {
- printf("?Session log wasn't open\n");
- return(0);
- }
- *sesfil = '\0';
- setseslog(0);
- return(zclose(ZSFILE));
-#endif /* NOLOCAL */
-
-#ifdef TLOG
- case LOGT: {
-#ifdef IKSD
- extern int iklogopen, xferlog;
-#endif /* IKSD */
- if (tralog <= 0
-#ifdef IKSD
- && !iklogopen
-#endif /* IKSD */
- ) {
- if (msgflg)
- printf("?Transaction log wasn't open\n");
- return(0);
- }
-#ifdef IKSD
- if (iklogopen && !inserver) {
- close(xferlog);
- iklogopen = 0;
- }
-#endif /* IKSD */
- if (tralog) {
- tlog(F100,"Transaction Log Closed","",0L);
- zclose(ZTFILE);
- }
- *trafil = '\0';
- tralog = 0;
- return(1);
- }
-#endif /* TLOG */
-
-#ifdef CKLOGDIAL
- case LOGM:
- if (dialog <= 0) {
- if (msgflg) printf("?Connection log wasn't open\n");
- return(0);
- }
- *diafil = '\0';
- dialog = 0;
- return(zclose(ZDIFIL));
-#endif /* CKLOGDIAL */
-
-#ifndef NOSPL
- case LOGW: /* WRITE file */
- case LOGR: /* READ file */
- y = (x == LOGR) ? ZRFILE : ZWFILE;
- if (chkfn(y) < 1) /* If no file to close */
- return(1); /* succeed silently. */
- return(zclose(y)); /* Otherwise, close the file. */
-#endif /* NOSPL */
-
- default:
- printf("\n?Unexpected log designator - %d\n", x);
- return(0);
- }
-}
-
-static int slc = 0; /* Screen line count */
-
-char *
-showstring(s) char * s; {
- return(s ? s : "(null)");
-}
-
-char *
-showoff(x) int x; {
- return(x ? "on" : "off");
-}
-
-char *
-showooa(x) int x; {
- switch (x) {
- case SET_OFF: return("off");
- case SET_ON: return("on");
- case SET_AUTO: return("automatic");
- default: return("(unknown)");
- }
-}
-
-#ifdef GEMDOS
-isxdigit(c) int c; {
- return(isdigit(c) ||
- (c >= 'a' && c <= 'f') ||
- (c >= 'A' && c <= 'F'));
-}
-#endif /* GEMDOS */
-
-#ifndef NOSETKEY
-#ifdef OS2
-static struct keytab shokeytab[] = { /* SHOW KEY modes */
- "all", 1, 0,
- "one", 0, 0
-};
-static int nshokey = (sizeof(shokeytab) / sizeof(struct keytab));
-
-#define SHKEYDEF TT_MAX+5
-struct keytab shokeymtab[] = {
- "aaa", TT_AAA, CM_INV, /* AnnArbor */
- "adm3a", TT_ADM3A, 0, /* LSI ADM-3A */
- "adm5", TT_ADM5, 0, /* LSI ADM-5 */
- "aixterm", TT_AIXTERM, 0, /* IBM AIXterm */
- "annarbor", TT_AAA, 0, /* AnnArbor */
- "ansi-bbs", TT_ANSI, 0, /* ANSI.SYS (BBS) */
- "at386", TT_AT386, 0, /* Unixware ANSI */
- "avatar/0+", TT_ANSI, 0, /* AVATAR/0+ */
- "ba80", TT_BA80, 0, /* Nixdorf BA80 */
- "be", TT_BEOS, CM_INV|CM_ABR,
- "beos-ansi", TT_BEOS, CM_INV, /* BeOS ANSI */
- "beterm", TT_BEOS, 0, /* BeOS Console */
- "d200", TT_DG200, CM_INV|CM_ABR, /* Data General DASHER 200 */
- "d210", TT_DG210, CM_INV|CM_ABR, /* Data General DASHER 210 */
- "d217", TT_DG217, CM_INV|CM_ABR, /* Data General DASHER 217 */
- "default", SHKEYDEF, 0,
- "dg200", TT_DG200, 0, /* Data General DASHER 200 */
- "dg210", TT_DG210, 0, /* Data General DASHER 210 */
- "dg217", TT_DG217, 0, /* Data General DASHER 217 */
- "emacs", TT_KBM_EMACS, 0, /* Emacs mode */
- "h19", TT_H19, CM_INV, /* Heath-19 */
- "heath19", TT_H19, 0, /* Heath-19 */
- "hebrew", TT_KBM_HEBREW, 0, /* Hebrew mode */
- "hft", TT_HFT, 0, /* IBM HFT */
- "hp2621a", TT_HP2621, 0, /* HP 2621A */
- "hpterm", TT_HPTERM, 0, /* HP TERM */
- "hz1500", TT_HZL1500, 0, /* Hazeltine 1500 */
- "ibm3151", TT_IBM31, 0, /* IBM 3101-xx,3161 */
- "linux", TT_LINUX, 0, /* Linux */
- "qansi", TT_QANSI, 0, /* QNX ANSI */
- "qnx", TT_QNX, 0, /* QNX */
- "russian", TT_KBM_RUSSIAN, 0, /* Russian mode */
- "scoansi", TT_SCOANSI, 0, /* SCO ANSI */
- "sni-97801", TT_97801, 0, /* Sinix 97801 */
- "sun", TT_SUN, 0, /* Sun Console */
-#ifdef OS2PM
-#ifdef COMMENT
- "tek4014", TT_TEK40, 0,
-#endif /* COMMENT */
-#endif /* OS2PM */
- "tty", TT_NONE, 0,
- "tvi910+", TT_TVI910, 0,
- "tvi925", TT_TVI925, 0,
- "tvi950", TT_TVI950, 0,
- "vc404", TT_VC4404, 0,
- "vc4404", TT_VC4404, CM_INV,
- "vip7809", TT_VIP7809, 0,
- "vt100", TT_VT100, 0,
- "vt102", TT_VT102, 0,
- "vt220", TT_VT220, 0,
- "vt220pc", TT_VT220PC, 0,
- "vt320", TT_VT320, 0,
- "vt320pc", TT_VT320PC, 0,
- "vt52", TT_VT52, 0,
- "wp", TT_KBM_WP, 0,
- "wy160", TT_WY160, 0,
- "wy30", TT_WY30, 0,
- "wy370", TT_WY370, 0,
- "wy50", TT_WY50, 0,
- "wy60", TT_WY60, 0,
- "wyse30", TT_WY30, CM_INV,
- "wyse370", TT_WY370, CM_INV,
- "wyse50", TT_WY50, CM_INV,
- "wyse60", TT_WY60, CM_INV
-};
-int nshokeym = (sizeof(shokeymtab) / sizeof(struct keytab));
-#endif /* OS2 */
-
-VOID
-#ifdef OS2
-shokeycode(c,m) int c, m;
-#else
-shokeycode(c) int c;
-#endif
-/* shokeycode */ {
- KEY ch;
- CHAR *s;
-#ifdef OS2
- int i;
- con_event km;
-#else /* OS2 */
- int km;
-#endif /* OS2 */
-
-#ifdef OS2
- extern int mskkeys;
- char * mstr = "";
-
- if (c >= KMSIZE) {
- bleep(BP_FAIL);
- return;
- }
-#else /* OS2 */
- printf(" Key code \\%d => ", c);
-#endif /* OS2 */
-
-#ifndef OS2
- km = mapkey(c);
-
-#ifndef NOKVERBS
- if (IS_KVERB(km)) { /* \Kverb? */
- int i, kv;
- kv = km & ~(F_KVERB);
- printf("Verb: ");
- for (i = 0; i < nkverbs; i++)
- if (kverbs[i].kwval == kv) {
- printf("\\K%s",kverbs[i].kwd);
- break;
- }
- printf("\n");
- } else
-#endif /* NOKVERBS */
- if (IS_CSI(km)) {
- int xkm = km & 0xFF;
- if (xkm <= 32 || xkm >= 127)
- printf("String: \\{27}[\\{%d}\n",xkm);
- else
- printf("String: \\{27}[%c\n",xkm);
- } else if (IS_ESC(km)) {
- int xkm = km & 0xFF;
- if (xkm <= 32 || xkm >= 127)
- printf("String: \\{27}\\{%d}\n",xkm);
- else
- printf("String: \\{27}%c\n",xkm);
- } else if (macrotab[c]) { /* See if there's a macro */
- printf("String: "); /* If so, display its definition */
- s = macrotab[c];
- shostrdef(s);
- printf("\n");
-#ifndef NOKVERBS
- } else if (km >= 0x100) { /* This means "undefined" */
- printf("Undefined\n");
-#endif /* NOKVERBS */
- } else { /* No macro, show single character */
- printf("Character: ");
- ch = km;
- if (ch < 32 || ch == 127
-#ifdef OS2
- || ch > 255
-#endif /* OS2 */
-#ifndef NEXT
-#ifndef AUX
-#ifndef XENIX
-#ifndef OS2
- || (ch > 127 && ch < 160)
-#endif /* OS2 */
-#endif /* XENIX */
-#endif /* AUX */
-#endif /* NEXT */
- )
-/*
- These used to be %d, but gcc 1.93 & later complain about type mismatches.
- %u is supposed to be totally portable.
-*/
- printf("\\%u",(unsigned int) ch);
- else printf("%c \\%u",(CHAR) (ch & 0xff),(unsigned int) ch);
- if (ch == (KEY) c)
- printf(" (self, no translation)\n");
- else
- printf("\n");
- }
-#else /* OS2 */
- if (m < 0) {
- km = mapkey(c);
- mstr = "default";
- } else {
- km = maptermkey(c,m);
- for (i = 0; i < nshokeym; i++) {
- if (m == shokeymtab[i].kwval) {
- mstr = shokeymtab[i].kwd;
- break;
- }
- }
- }
- s = keyname(c);
- debug(F111,"shokeycode mstr",mstr,m);
- debug(F111,"shokeycode keyname",s,c);
- printf(" %sKey code \\%d %s (%s) => ",
- mskkeys ? "mskermit " : "",
- mskkeys ? cktomsk(c) : c,
- s == NULL ? "" : s, mstr);
-
- switch (km.type) {
-#ifndef NOKVERBS
- case kverb: {
- int i, kv;
- kv = km.kverb.id & ~(F_KVERB);
- printf("Verb: ");
- for (i = 0; i < nkverbs; i++) {
- if (kverbs[i].kwval == kv) {
- printf("\\K%s",kverbs[i].kwd);
- break;
- }
- }
- printf("\n");
- break;
- }
-#endif /* NOKVERBS */
- case csi: {
- int xkm = km.csi.key & 0xFF;
- if (xkm <= 32 || xkm >= 127)
- printf("String: \\{27}[\\{%d}\n",xkm);
- else
- printf("String: \\{27}[%c\n",xkm);
- break;
- }
- case esc: {
- int xkm = km.esc.key & 0xFF;
- if (xkm <= 32 || xkm >= 127)
- printf("String: \\{%d}\\{%d}\n",ISDG200(tt_type)?30:27,xkm);
- else
- printf("String: \\{%d}%c\n",ISDG200(tt_type)?30:27,xkm);
- break;
- }
- case macro: {
- printf("String: "); /* Macro, display its definition */
- shostrdef(km.macro.string);
- printf("\n");
- break;
- }
- case literal: {
- printf("Literal string: "); /* Literal, display its definition */
- shostrdef(km.literal.string);
- printf("\n");
- break;
- }
- case error: {
- if (c >= 0x100) {
- printf("Undefined\n");
- } else {
- printf("Character: ");
- ch = c;
- if (ch < 32 || ch == 127 || ch > 255
-#ifndef NEXT
-#ifndef AUX
-#ifndef XENIX
-#ifndef OS2
- || (ch > 127 && ch < 160)
-#endif /* OS2 */
-#endif /* XENIX */
-#endif /* AUX */
-#endif /* NEXT */
- )
-/*
- These used to be %d, but gcc 1.93 & later complain about type mismatches.
- %u is supposed to be totally portable.
-*/
- printf("\\%u",(unsigned int) ch);
- else printf("%c \\%u",(CHAR) (ch & 0xff),(unsigned int) ch);
- printf(" (self, no translation)\n");
- }
- break;
- }
- case key: {
- printf("Character: ");
- ch = km.key.scancode;
- if (ch < 32 || ch == 127 || ch > 255
-#ifndef NEXT
-#ifndef AUX
-#ifndef XENIX
-#ifndef OS2
- || (ch > 127 && ch < 160)
-#else
- || (ch > 127)
-#endif /* OS2 */
-#endif /* XENIX */
-#endif /* AUX */
-#endif /* NEXT */
- )
-/*
- These used to be %d, but gcc 1.93 & later complain about type mismatches.
- %u is supposed to be totally portable.
-*/
- printf("\\%u",(unsigned int) ch);
- else printf("%c \\%u",(CHAR) (ch & 0xff),(unsigned int) ch);
- if (ch == (KEY) c)
- printf(" (self, no translation)\n");
- else
- printf("\n");
- break;
- }
- }
-#endif /* OS2 */
-}
-#endif /* NOSETKEY */
-
-VOID
-shostrdef(s) CHAR * s; {
- CHAR ch;
- if (!s) s = (CHAR *)"";
- while ((ch = *s++)) {
- if (ch < 32 || ch == 127 || ch == 255
-/*
- Systems whose native character sets have graphic characters in C1...
-*/
-#ifndef NEXT /* NeXT */
-#ifndef AUX /* Macintosh */
-#ifndef XENIX /* IBM PC */
-#ifdef OS2
-/*
- It doesn't matter whether the local host can display 8-bit characters;
- they are not portable among character-sets and fonts. Who knows what
- would be displayed...
-*/
- || (ch > 127)
-#else /* OS2 */
- || (ch > 127 && ch < 160)
-#endif /* OS2 */
-#endif /* XENIX */
-#endif /* AUX */
-#endif /* NEXT */
- )
- printf("\\{%d}",ch); /* Display control characters */
- else putchar((char) ch); /* in backslash notation */
- }
-}
-
-#define xxdiff(v,sys) strncmp(v,sys,strlen(sys))
-
-#ifndef NOSHOW
-VOID
-shover() {
-#ifdef OS2
- extern char ckxsystem[];
-#endif /* OS2 */
- extern char *ck_patch, * cklibv;
- printf("\nVersions:\n %s\n",versio);
- printf(" Numeric: %ld\n",vernum);
-#ifdef OS2
- printf(" Operating System: %s\n", ckxsystem);
-#else /* OS2 */
- printf(" Built for: %s\n", ckxsys);
-#ifdef CK_UTSNAME
- if (unm_nam[0])
- printf(" Running on: %s %s %s %s\n", unm_nam,unm_ver,unm_rel,unm_mch);
-#endif /* CK_UTSNAME */
- printf(" Patches: %s\n", *ck_patch ? ck_patch : "(none)");
-#endif /* OS2 */
- if (xxdiff(ckxv,ckxsys))
- printf(" %s for%s\n",ckxv,ckxsys);
- else
- printf(" %s\n",ckxv);
- if (xxdiff(ckzv,ckzsys))
- printf(" %s for%s\n",ckzv,ckzsys);
- else
- printf(" %s\n",ckzv);
- printf(" %s\n",cklibv);
- printf(" %s\n",protv);
- printf(" %s\n",fnsv);
- printf(" %s\n %s\n",cmdv,userv);
-#ifndef NOCSETS
- printf(" %s\n",xlav);
-#endif /* NOCSETS */
-#ifndef MAC
-#ifndef NOLOCAL
- printf(" %s\n",connv);
-#ifdef OS2
- printf(" %s\n",ckyv);
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#endif /* MAC */
-#ifndef NODIAL
- printf(" %s\n",dialv);
-#endif /* NODIAL */
-#ifndef NOSCRIPT
- printf(" %s\n",loginv);
-#endif /* NOSCRIPT */
-#ifdef NETCONN
- printf(" %s\n",cknetv);
-#ifdef OS2
- printf(" %s\n",ckonetv);
-#ifdef CK_NETBIOS
- printf(" %s\n",ckonbiv);
-#endif /* CK_NETBIOS */
-#endif /* OS2 */
-#endif /* NETCONN */
-#ifdef TNCODE
- printf(" %s\n",cktelv);
-#endif /* TNCODE */
-#ifdef SSHBUILTIN
- printf(" %s\n",cksshv);
-#ifdef SFTP_BUILTIN
- printf(" %s\n",cksftpv);
-#endif /* SFTP_BUILTIN */
-#endif /* SSHBUILTIN */
-#ifdef OS2
-#ifdef OS2MOUSE
- printf(" %s\n",ckomouv);
-#endif /* OS2MOUSE */
-#endif /* OS2 */
-#ifdef NEWFTP
- printf(" %s\n",ckftpv);
-#endif /* NEWFTP */
-#ifdef CK_AUTHENTICATION
- printf(" %s\n",ckathv);
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
-#ifdef CRYPT_DLL
- printf(" %s\n",ck_crypt_dll_version());
-#else /* CRYPT_DLL */
- printf(" %s\n",ckcrpv);
-#endif /* CRYPT_DLL */
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- printf(" %s\n",cksslv);
-#endif /* CK_SSL */
- printf("\n");
-}
-
-#ifdef CK_LABELED
-VOID
-sholbl() {
-#ifdef VMS
- printf("VMS Labeled File Features:\n");
- printf(" acl %s (ACL info %s)\n",
- showoff(lf_opts & LBL_ACL),
- lf_opts & LBL_ACL ? "preserved" : "discarded");
- printf(" backup-date %s (backup date/time %s)\n",
- showoff(lf_opts & LBL_BCK),
- lf_opts & LBL_BCK ? "preserved" : "discarded");
- printf(" name %s (original filename %s)\n",
- showoff(lf_opts & LBL_NAM),
- lf_opts & LBL_NAM ? "preserved" : "discarded");
- printf(" owner %s (original file owner id %s)\n",
- showoff(lf_opts & LBL_OWN),
- lf_opts & LBL_OWN ? "preserved" : "discarded");
- printf(" path %s (original file's disk:[directory] %s)\n",
- showoff(lf_opts & LBL_PTH),
- lf_opts & LBL_PTH ? "preserved" : "discarded");
-#else
-#ifdef OS2
- printf("OS/2 Labeled File features (attributes):\n");
- printf(" archive: %s\n", showoff(lf_opts & LBL_ARC));
- printf(" extended: %s\n", showoff(lf_opts & LBL_EXT));
- printf(" hidden: %s\n", showoff(lf_opts & LBL_HID));
- printf(" read-only: %s\n", showoff(lf_opts & LBL_RO ));
- printf(" system: %s\n", showoff(lf_opts & LBL_SYS));
-#endif /* OS2 */
-#endif /* VMS */
-}
-#endif /* CK_LABELED */
-
-VOID
-shotcs(csl,csr) int csl, csr; { /* Show terminal character set */
-#ifndef NOCSETS
-#ifdef OS2
-#ifndef NOTERM
- extern struct _vtG G[4], *GL, *GR;
- extern int decnrcm, sni_chcode;
- extern int tt_utf8, dec_nrc, dec_kbd, dec_lang;
- extern prncs;
-
- printf(" Terminal character-sets:\n");
- if (IS97801(tt_type_mode)) {
- if (cmask == 0377)
- printf(" Mode: 8-bit Mode\n");
- else
- printf(" Mode: 7-bit Mode\n");
- printf(" CH.CODE is %s\n",sni_chcode?"On":"Off");
- } else if (ISVT100(tt_type_mode)) {
- if (decnrcm)
- printf(" Mode: 7-bit National Mode\n");
- else
- printf(" Mode: 8-bit Multinational Mode\n");
- }
- if ( isunicode() )
- printf(" Local: Unicode display / %s input\n",
- csl == TX_TRANSP ? "transparent" :
- csl == TX_UNDEF ? "undefined" : txrinfo[csl]->keywd);
- else
- printf(" Local: %s\n",
- csl == TX_TRANSP ? "transparent" :
- csl == TX_UNDEF ? "undefined" : txrinfo[csl]->keywd);
-
- if ( tt_utf8 ) {
- printf(" Remote: UTF-8\n");
- } else {
- printf(" Remote: %sG0: %s (%s)\n",
- GL == &G[0] ? "GL->" : GR == &G[0] ? "GR->" : " ",
- txrinfo[G[0].designation]->keywd,
- G[0].designation == TX_TRANSP ? "" :
- G[0].size == cs94 ? "94 chars" :
- G[0].size == cs96 ? "96 chars" : "multi-byte");
- printf(" %sG1: %s (%s)\n",
- GL == &G[1] ? "GL->" : GR == &G[1] ? "GR->" : " ",
- txrinfo[G[1].designation]->keywd,
- G[1].designation == TX_TRANSP ? "" :
- G[1].size == cs94 ? "94 chars" :
- G[1].size == cs96 ? "96 chars" : "multi-byte");
- printf(" %sG2: %s (%s)\n",
- GL == &G[2] ? "GL->" : GR == &G[2] ? "GR->" : " ",
- txrinfo[G[2].designation]->keywd,
- G[2].designation == TX_TRANSP ? "" :
- G[2].size == cs94 ? "94 chars" :
- G[2].size == cs96 ? "96 chars" : "multi-byte");
- printf(" %sG3: %s (%s)\n",
- GL == &G[3] ? "GL->" : GR == &G[3] ? "GR->" : " ",
- txrinfo[G[3].designation]->keywd,
- G[3].designation == TX_TRANSP ? "" :
- G[3].size == cs94 ? "94 chars" :
- G[3].size == cs96 ? "96 chars" : "multi-byte");
- }
- printf("\n");
- printf(" Keyboard character-sets:\n");
- printf(" Multinational: %s\n",txrinfo[dec_kbd]->keywd);
- printf(" National: %s\n",txrinfo[dec_nrc]->keywd);
- printf("\n");
- printf(" Printer character-set: %s\n",txrinfo[prncs]->keywd);
-#endif /* NOTERM */
-#else /* OS2 */
-#ifndef MAC
- char *s;
-
- debug(F101,"TERM LOCAL CSET","",csl);
- debug(F101,"TERM REMOTE CSET","",csr);
- printf(" Terminal character-set: ");
- if (tcs_transp) { /* No translation */
- printf("transparent\n");
- } else { /* Translation */
- printf("%s (remote) %s (local)\n",
- fcsinfo[csr].keyword,fcsinfo[csl].keyword);
- if (csr != csl) {
- switch(gettcs(csr,csl)) {
- case TC_USASCII: s = "ascii"; break;
- case TC_1LATIN: s = "latin1-iso"; break;
- case TC_2LATIN: s = "latin2-iso"; break;
- case TC_CYRILL: s = "cyrillic-iso"; break;
- case TC_JEUC: s = "japanese-euc"; break;
- case TC_HEBREW: s = "hebrew-iso"; break;
- case TC_GREEK: s = "greek-iso"; break;
- case TC_9LATIN: s = "latin9-iso"; break;
- default: s = "transparent"; break;
- }
- if (strcmp(s,fcsinfo[csl].keyword) &&
- strcmp(s,fcsinfo[csr].keyword))
- printf(" (via %s)\n",s);
- }
- }
-#endif /* MAC */
-#endif /* OS2 */
-#endif /* NOCSETS */
-}
-
-#ifndef NOLOCAL
-#ifdef OS2
-extern char htab[];
-VOID
-shotabs() {
- int i,j,k,n;
-
- printf("Tab Stops:\n\n");
- for (i = 0, j = 1, k = VscrnGetWidth(VCMD); i < MAXTERMCOL; ) {
- do {
- printf("%c",htab[++i]=='T'?'T':'-');
- } while (i % k && i < MAXTERMCOL);
- printf("\n");
- for ( ; j <= i; j++) {
- switch ( j%10 ) {
- case 1:
- printf("%c",j == 1 ? '1' : '.');
- break;
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- printf("%c",'.');
- break;
- case 8:
- n = (j+2)/100;
- if (n)
- printf("%d",n);
- else
- printf("%c",'.');
- break;
- case 9:
- n = (j+1)%100/10;
- if (n)
- printf("%d",n);
- else if (j>90)
- printf("0");
- else
- printf("%c",'.');
- break;
- case 0:
- printf("0");
- break;
- }
- }
- printf("\n");
- }
-#ifdef COMMENT
- for (i = 1; i <= 70; i++)
- printf("%c",htab[i]=='T'?'T':'-');
- printf("\n1.......10........20........30........40........50........60\
-........70\n\n");
- for (; i <= 140; i++)
- printf("%c",htab[i]=='T'?'T':'-');
- printf("\n........80........90.......100.......110.......120.......130\
-.......140\n\n");
- for (; i <= 210; i++)
- printf("%c",htab[i]=='T'?'T':'-');
- printf("\n.......150.......160.......170.......180.......190.......200\
-.......210\n\n");
- for (; i <= 255; i++)
- printf("%c",htab[i]=='T'?'T':'-');
- printf("\n.......220.......230.......240.......250..255\n");
-#endif
-
-}
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifdef OS2MOUSE
-VOID
-shomou() {
- int button, event, id, i;
- char * name = "";
-
- printf("Mouse settings:\n");
- printf(" Button Count: %d\n",mousebuttoncount());
- printf(" Active: %s\n\n",showoff(tt_mouse));
-
- for (button = 0; button < MMBUTTONMAX; button++)
- for (event = 0; event < MMEVENTSIZE; event++)
- if (mousemap[button][event].type != error)
- switch (mousemap[button][event].type) {
- case key:
- printf(" %s = Character: %c \\%d\n",
- mousename(button,event),
- mousemap[button][event].key.scancode,
- mousemap[button][event].key.scancode );
- break;
- case kverb:
- id = mousemap[button][event].kverb.id & ~(F_KVERB);
- if (id != K_IGNORE) {
- for (i = 0; i< nkverbs; i++)
- if (id == kverbs[i].kwval) {
- name = kverbs[i].kwd;
- break;
- }
- printf(" %s = Kverb: \\K%s\n",
- mousename(button,event),
- name
- );
- }
- break;
- case macro:
- printf(" %s = Macro: ",
- mousename(button,event) );
- shostrdef(mousemap[button][event].macro.string);
- printf("\n");
- break;
- }
-}
-#endif /* OS2MOUSE */
-
-#ifndef NOLOCAL
-VOID
-shotrm() {
- char *s;
- extern char * getiact();
- extern int tt_print, adl_err;
-#ifndef NOTRIGGER
- extern char * tt_trigger[];
-#endif /* NOTRIGGER */
-#ifdef CKTIDLE
- extern char * tt_idlesnd_str;
- extern int tt_idlesnd_tmo;
- extern int tt_idlelimit, tt_idleact;
-#endif /* CKTIDLE */
-#ifdef OS2
- extern int wy_autopage, autoscroll, sgrcolors, colorreset, user_erasemode,
- decscnm, decscnm_usr, tt_diff_upd, tt_senddata,
- wy_blockend, marginbell, marginbellcol, tt_modechg, dgunix;
- int lines = 0;
-#ifdef KUI
- extern CKFLOAT tt_linespacing[];
- extern tt_cursor_blink;
-#endif /* KUI */
-#ifdef PCFONTS
- int i;
- char *font;
-
- if (IsOS2FullScreen()) { /* Determine the font name */
- if (!os2LoadPCFonts()) {
- for (i = 0; i < ntermfont; i++) {
- if (tt_font == term_font[i].kwval) {
- font = term_font[i].kwd;
- break;
- }
- }
- } else {
- font = "(DLL not available)";
- }
- } else {
- font = "(full screen only)";
- }
-#endif /* PCFONTS */
-#ifdef KUI
- char font[64] = "(unknown)";
- if ( ntermfont > 0 ) {
- int i;
- for (i = 0; i < ntermfont; i++) {
- if (tt_font == term_font[i].kwval) {
- ckstrncpy(font,term_font[i].kwd,59);
- ckstrncat(font," ",64);
- ckstrncat(font,ckitoa(tt_font_size/2),64);
- if ( tt_font_size % 2 )
- ckstrncat(font,".5",64);
- break;
- }
- }
- }
-#endif /* KUI */
-
- printf("Terminal parameters:\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %1d%-12s %13s: %1d%-14s\n",
- "Bytesize: Command",
- (cmdmsk == 0377) ? 8 : 7,
- " bits","Terminal",
- (cmask == 0377) ? 8 : 7," bits");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s","Type",
- (tt_type >= 0 && tt_type <= max_tt) ?
- tt_info[tt_type].x_name :
- "unknown" );
- if (tt_type >= 0 && tt_type <= max_tt)
- if (strlen(tt_info[tt_type].x_id))
- printf(" %13s: <ESC>%s","ID",tt_info[tt_type].x_id);
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s %13s: %-15s\n","Echo",
- duplex ? "local" : "remote","Locking-shift",showoff(sosi));
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s %13s: %-15s\n","Newline-mode", showoff(tnlm),
- "Cr-display",tt_crd ? "crlf" : "normal");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s %13s: %-15s\n","Cursor",
-#ifdef KUI
- (tt_cursor == 2) ? (tt_cursor_blink ?
- "full (*)" : "full (.)") :
- (tt_cursor == 1) ? (tt_cursor_blink ?
- "half (*)" : "half (.)") :
- (tt_cursor_blink ? "underline (*)" : "underline (.)"),
-#else /* KUI */
- (tt_cursor == 2) ? "full" :
- (tt_cursor == 1) ? "half" : "underline",
-#endif /* KUI */
-#ifdef CK_AUTODL
- "autodownload",autodl == TAD_ON ?
- (adl_err ? "on, error stop" : "on, error continue") :
- autodl == TAD_ASK ?
- (adl_err ? "ask, error stop" : "ask, error continue") :
- "off"
-#else /* CK_AUTODL */
- "", ""
-#endif /* CK_AUTODL */
- );
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s %13s: %-15s\n","Arrow-keys",
- tt_arrow ? "application" : "cursor",
- "Keypad-mode", tt_keypad ? "application" : "numeric"
- );
-
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- /* Just to make sure we are using current info */
- updanswerbk();
-
- /*
- This line doesn't end with '\n' because the answerback string
- is terminated with a newline
- */
- printf(" %19s: %-13s %13s: %-15s","Answerback",
- showoff(tt_answer),"response",answerback);
- switch (tt_bell) {
- case XYB_NONE:
- s = "none";
- break;
- case XYB_VIS:
- s= "visible";
- break;
- case XYB_AUD | XYB_BEEP:
- s="beep";
- break;
- case XYB_AUD | XYB_SYS:
- s="system sounds";
- break;
- default:
- s="(unknown)";
- }
- printf(" %19s: %-13s %13s: %-15s\n","Bell",s,
- "Wrap",showoff(tt_wrap));
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s %13s: %-15s\n","Autopage",showoff(wy_autopage),
- "Autoscroll",showoff(autoscroll));
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s %13s: %-15s\n","SGR Colors",showoff(sgrcolors),
- "ESC[0m color",colorreset?"default-color":"current-color");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s %13s: %-15s\n",
- "Erase color",user_erasemode?"default-color":"current-color",
- "Screen mode",decscnm?"reverse":"normal");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- printf(" %19s: %-13d %13s: %-15d\n","Transmit-timeout",tt_ctstmo,
- "Output-pacing",tt_pacing);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- printf(" %19s: %-13d %13s: %s\n","Idle-timeout",tt_idlelimit,
- "Idle-action", getiact());
-
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s %13s: %-15s\n","Send data",
- showoff(tt_senddata),"End of Block", wy_blockend?"crlf/etx":"us/cr");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-#ifndef NOTRIGGER
- printf(" %19s: %-13s %13s: %d seconds\n","Auto-exit trigger",
- tt_trigger[0],"Output pacing",tt_pacing );
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-#endif /* NOTRIGGER */
- printf(" %19s: %-13s %13s: %-15d\n","Margin bell",
- showoff(marginbell),"at column", marginbellcol);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- switch (tt_modechg) {
- case TVC_DIS: s = "disabled"; break;
- case TVC_ENA: s = "enabled"; break;
- case TVC_W95: s = "win95-restricted"; break;
- default: s = "(unknown)";
- }
- printf(" %19s: %-13s %13s: %-15s\n","DG Unix mode",
- showoff(dgunix),"Video change", s);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
-#ifdef CK_APC
- if (apcstatus == APC_ON) s = "on";
- else if (apcstatus == APC_OFF) s = "off";
- else if (apcstatus == APC_ON|APC_UNCH) s = "unchecked";
- else if (apcstatus == APC_ON|APC_NOINP) s = "no-input";
- else if (apcstatus == APC_ON|APC_UNCH|APC_NOINP) s = "unchecked-no-input";
- printf(" %19s: %-13s %13s: %-15s\n",
- "APC", s,
-#ifdef PCFONTS
- "Font (VGA)",font
-#else /* PCFONTS */
-#ifdef KUI
- "Font",font
-#else
- "Font","(not supported)"
-#endif /* KUI */
-#endif /* PCFONTS */
-
- );
-#endif /* CK_APC */
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
-#ifdef CK_TTGWSIZ /* Console terminal screen size */
- if (tt_cols[VTERM] < 0 || tt_rows[VTERM] < 0)
- ttgwsiz(); /* Try to get latest size */
-#endif /* CK_TTGWSIZ */
- printf(" %19s: %-13d %13s: %-15d\n","Height",tt_rows[VTERM],
- "Width",tt_cols[VTERM]);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-#ifdef KUI
- printf(" %19s: %-12f %14s: %-15d\n","Line spacing",tt_linespacing[VTERM],
- "Display Height",VscrnGetDisplayHeight(VTERM));
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-#endif /* KUI */
- printf(" %19s: %-13s %13s: %d lines\n","Roll-mode",
- tt_roll[VTERM]?"insert":"overwrite","Scrollback", tt_scrsize[VTERM]);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- if (updmode == tt_updmode)
- if (updmode == TTU_FAST)
- s = "fast (fast)";
- else
- s = "smooth (smooth)";
- else
- if (updmode == TTU_FAST)
- s = "fast (smooth)";
- else
- s = "smooth (fast)";
-
- printf(" %19s: %-13s %13s: %d ms\n","Screen-update: mode",s,
- "interval",tt_update);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s %13s: %-15s\n",
- "Screen-optimization",showoff(tt_diff_upd),
- "Status line",showoff(tt_status[VTERM]));
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" %19s: %-13s %13s: %-15s\n","Debug",
- showoff(debses),"Session log", seslog? sesfil : "(none)" );
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- /* Display colors (should become SHOW COLORS) */
- {
- USHORT row, col;
- char * colors[16] = {
- "black","blue","green","cyan","red","magenta","brown","lgray",
- "dgray","lblue","lgreen","lcyan","lred","lmagent","yellow","white"
- };
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- printf(" Color:");
-#ifndef ONETERMUPD
- GetCurPos(&row, &col);
- WrtCharStrAtt("border", 6, row, 9, &colorborder );
- WrtCharStrAtt("debug", 5, row, 17, &colordebug );
- WrtCharStrAtt("helptext", 8, row, 25, &colorhelp );
- WrtCharStrAtt("reverse", 7, row, 34, &colorreverse );
- WrtCharStrAtt("select", 6, row, 42, &colorselect );
- WrtCharStrAtt("status", 6, row, 50, &colorstatus );
- WrtCharStrAtt("terminal", 8, row, 58, &colornormal );
- WrtCharStrAtt("underline", 9, row, 67, &colorunderline );
-#endif /* ONETERMUPD */
- row = VscrnGetCurPos(VCMD)->y+1;
- VscrnWrtCharStrAtt(VCMD, "border", 6, row, 9, &colorborder );
- VscrnWrtCharStrAtt(VCMD, "debug", 5, row, 17, &colordebug );
- VscrnWrtCharStrAtt(VCMD, "helptext", 8, row, 25, &colorhelp );
- VscrnWrtCharStrAtt(VCMD, "reverse", 7, row, 34, &colorreverse );
- VscrnWrtCharStrAtt(VCMD, "select", 6, row, 42, &colorselect );
- VscrnWrtCharStrAtt(VCMD, "status", 6, row, 50, &colorstatus );
- VscrnWrtCharStrAtt(VCMD, "terminal", 8, row, 58, &colornormal );
- VscrnWrtCharStrAtt(VCMD, "underline", 9, row, 67, &colorunderline );
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- /* Foreground color names */
- printf("%6s: %-8s%-8s%-9s%-8s%-8s%-8s%-9s%-9s\n","fore",
- "",
- colors[colordebug&0x0F],
- colors[colorhelp&0x0F],
- colors[colorreverse&0x0F],
- colors[colorselect&0x0F],
- colors[colorstatus&0x0F],
- colors[colornormal&0x0F],
- colors[colorunderline&0x0F]);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- /* Background color names */
- printf("%6s: %-8s%-8s%-9s%-8s%-8s%-8s%-9s%-9s\n","back",
- colors[colorborder],
- colors[colordebug>>4],
- colors[colorhelp>>4],
- colors[colorreverse>>4],
- colors[colorselect>>4],
- colors[colorstatus>>4],
- colors[colornormal>>4],
- colors[colorunderline>>4] );
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" Color:");
-#ifndef ONETERMUPD
- GetCurPos(&row, &col);
- WrtCharStrAtt("graphic", 7, row, 9, &colorgraphic );
- WrtCharStrAtt("command", 7, row, 17, &colorcmd );
- WrtCharStrAtt("italic", 6, row, 26, &coloritalic );
-#endif /* ONETERMUPD */
- row = VscrnGetCurPos(VCMD)->y+1;
- VscrnWrtCharStrAtt(VCMD, "graphic", 7, row, 9, &colorgraphic );
- VscrnWrtCharStrAtt(VCMD, "command", 7, row, 17, &colorcmd );
- VscrnWrtCharStrAtt(VCMD, "italic", 6, row, 26, &coloritalic );
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- /* Foreground color names */
- printf("%6s: %-8s%-8s%-8s\n","fore",
- colors[colorgraphic&0x0F],
- colors[colorcmd&0x0F],
- colors[coloritalic&0x0F]);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
- /* Background color names */
- printf("%6s: %-8s%-8s%-8s\n","back",
- colors[colorgraphic>>4],
- colors[colorcmd>>4],
- colors[coloritalic>>4]);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- }
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- {
- extern int trueblink, truedim, truereverse, trueunderline, trueitalic;
- printf(
- " Attribute: \
-blink: %-3s dim: %-3s italic: %-3s reverse: %-3s underline: %-3s\n",
- trueblink?"on":"off", truedim?"on":"off", trueitalic?"on":"off",
- truereverse?"on":"off", trueunderline?"on":"off");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- }
- {
- extern vtattrib WPattrib;
- printf(" ASCII Protected chars: %s%s%s%s%s%s%s\n",
- WPattrib.blinking?"blink ":"",
- WPattrib.italic?"italic ":"",
- WPattrib.reversed?"reverse ":"",
- WPattrib.underlined?"underline ":"",
- WPattrib.bold?"bold ":"",
- WPattrib.dim?"dim ":"",
- WPattrib.invisible?"invisible ":"");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- }
-
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- (VOID) shoesc(escape);
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
- printf(" See SHOW CHARACTER-SETS for character-set info\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
-
-#else /* OS2 */ /* Beginning of new non-OS2 version */
-
- printf("\n");
- printf("Terminal parameters:\n");
- printf(" %19s: %1d%-12s %13s: %1d%-14s\n",
- "Bytesize: Command",
- (cmdmsk == 0377) ? 8 : 7,
- " bits","Terminal",
- (cmask == 0377) ? 8 : 7," bits");
- s = getenv("TERM");
-#ifdef XPRINT
- printf(" %19s: %-13s %13s: %-15s\n",
- "Type",
- s ? s : "(unknown)",
- "Print",
- showoff(tt_print)
- );
-#else
- printf(" %19s: %-13s\n","Type", s ? s : "(unknown)");
-#endif /* XPRINT */
- printf(" %19s: %-13s %13s: %-15s\n","Echo",
- duplex ? "local" : "remote","Locking-shift",showoff(sosi));
- printf(" %19s: %-13s %13s: %-15s\n","Newline-mode",
- showoff(tnlm),"Cr-display",tt_crd ? "crlf" : "normal");
-
-#ifdef CK_APC
- if (apcstatus == APC_ON) s = "on";
- else if (apcstatus == APC_OFF) s = "off";
- else if (apcstatus == (APC_ON|APC_UNCH)) s = "unchecked";
- else if (apcstatus == (APC_ON|APC_NOINP)) s = "no-input";
- else if (apcstatus == (APC_ON|APC_UNCH|APC_NOINP))
- s = "unchecked-no-input";
- printf(" %19s: %-13s %13s: %-15s\n",
- "APC", s,
-#ifdef CK_AUTODL
- "Autodownload", autodl ?
- (adl_err ? "on, error stop" : "on, error continue") : "off"
-#else
- "",""
-#endif /* CK_AUTODL */
- );
-#endif /* CK_APC */
-
-#ifdef CK_TTGWSIZ /* Console terminal screen size */
- ttgwsiz(); /* Try to get latest size */
- printf(" %19s: %-13d %13s: %-15d\n","Height",tt_rows, "Width", tt_cols);
-#endif /* CK_TTGWSIZ */
-
- printf(" %19s: %-13s %13s: %-15s\n","Debug",
- showoff(debses),"Session log", seslog? sesfil : "(none)" );
-
-#ifdef CKTIDLE
- printf(" %19s: %-13d %13s: %s\n","Idle-timeout",tt_idlelimit,
- "Idle-action", getiact());
-#endif /* CKTIDLE */
-
- printf(" %19s: %-13s ","Lf-display", tt_lfd ? "crlf" : "normal");
-#ifdef UNIX
-#ifndef NOJC
- printf("%13s: %-15s","Suspend", showoff(xsuspend));
-#endif /* NOJC */
-#endif /* UNIX */
- printf("\n");
-
-#ifndef NOTRIGGER
- printf(" %19s: %-13s\n","Trigger",
- tt_trigger[0] ? tt_trigger[0] : "(none)");
-#endif /* NOTRIGGER */
- printf("\n");
-
- (VOID) shoesc(escape);
-#ifndef NOCSETS
- shotcs(tcsl,tcsr); /* Show terminal character sets */
-#endif /* NOCSETS */
-
-#endif /* OS2 */
-}
-
-VOID
-shmdmlin() { /* Briefly show modem & line */
-#ifndef NODIAL
-#ifndef MINIDIAL
-#ifdef OLDTBCODE
- extern int tbmodel;
- _PROTOTYP( char * gtbmodel, (void) );
-#endif /* OLDTBCODE */
-#endif /* MINIDIAL */
-#endif /* NODIAL */
- if (local)
-#ifdef OS2
- printf(" Port: %s, Modem type: ",ttname);
-#else
- printf(" Line: %s, Modem type: ",ttname);
-#endif /* OS2 */
- else
- printf(
-#ifdef OS2
-" Communication device not yet selected with SET PORT\n Modem type: "
-#else
-" Communication device not yet selected with SET LINE\n Modem type: "
-#endif /* OS2 */
- );
-#ifndef NODIAL
- printf("%s",gmdmtyp());
-#ifndef MINIDIAL
-#ifdef OLDTBCODE
- if (tbmodel) printf(" (%s)",gtbmodel()); /* Telebit model info */
-#endif /* OLDTBCODE */
-#endif /* MINIDIAL */
-#else
- printf("(disabled)");
-#endif /* NODIAL */
-}
-
-#ifdef CK_TAPI
-void
-shotapi(int option) {
- int rc=0,k ;
- char *s=NULL;
- LPDEVCFG lpDevCfg = NULL;
- LPCOMMCONFIG lpCommConfig = NULL;
- LPMODEMSETTINGS lpModemSettings = NULL;
- DCB * lpDCB = NULL;
- extern struct keytab * tapiloctab; /* Microsoft TAPI Locations */
- extern int ntapiloc;
- extern struct keytab * tapilinetab; /* Microsoft TAPI Line Devices */
- extern int ntapiline;
- extern int tttapi; /* TAPI in use */
- extern int tapipass; /* TAPI Passthrough mode */
- extern int tapiconv; /* TAPI Conversion mode */
- extern int tapilights;
- extern int tapipreterm;
- extern int tapipostterm;
- extern int tapimanual;
- extern int tapiinactivity;
- extern int tapibong;
- extern int tapiusecfg;
- extern char tapiloc[];
- extern int tapilocid;
- extern int TAPIAvail;
-
- if (!TAPIAvail) {
- printf("TAPI Support not enabled\r\n");
- return;
- }
- switch (option) {
- case 0:
- printf("TAPI Settings:\n");
- printf(" Line: %s\n",
- tttapi ? ttname : "(none in use)");
-
- cktapiBuildLocationTable(&tapiloctab, &ntapiloc);
- if (tapilocid == -1)
- tapilocid = cktapiGetCurrentLocationID();
-
- /* Find the current tapiloc entry */
- /* and use it as the default. */
- for (k = 0; k < ntapiloc; k++) {
- if (tapiloctab[k].kwval == tapilocid)
- break;
- }
- if (k >= 0 && k < ntapiloc)
- s = tapiloctab[k].kwd;
- else
- s = "(unknown)";
- printf(" Location: %s\n",s);
- printf(" Modem-dialing: %s\n",tapipass?"off":"on");
- printf(" Phone-number-conversions: %s\n",
- tapiconv==CK_ON?"on":tapiconv==CK_AUTO?"auto":"off");
- printf(" Modem-lights: %s %s\n",tapilights?"on ":"off",
- tapipass?"(n/a)":"");
- printf(" Predial-terminal: %s %s\n",tapipreterm?"on ":"off",
- tapipass?"(n/a)":"");
- printf(" Postdial-terminal: %s %s\n",tapipostterm?"on ":"off",
- tapipass?"(n/a)":"");
- printf(" Manual-dial: %s %s\n",tapimanual?"on ":"off",
- tapipass?"(n/a)":"");
- printf(" Inactivity-timeout: %d seconds %s\n",tapiinactivity,
- tapipass?"(n/a)":"");
- printf(" Wait-for-bong: %d seconds %s\n",tapibong,
- tapipass?"(n/a)":"");
- printf(" Use-windows-configuration: %s %s\n",
- tapiusecfg?"on ":"off", tapipass?"(n/a)":"");
- printf("\n");
-
-#ifdef BETATEST
- if (tapipass) {
-printf("K-95 uses the TAPI Line in an exclusive mode. Other applications\n");
-printf("may open the device but may not place calls nor answer calls.\n");
-printf("Dialing is performed using the K-95 dialing procedures. SET MODEM\n");
-printf("TYPE TAPI after the SET TAPI LINE command to activate the modem\n");
-printf("definition associated with the active TAPI LINE device.\n\n");
-
- } else {
-
-printf("K-95 uses the TAPI Line in a cooperative mode. Other applications\n");
-printf("may open the device, place and answer calls. Dialing is performed\n");
-printf("by TAPI. K-95 SET MODEM commands are not used.\n\n");
- }
-
- if (tapiconv == CK_ON ||
- tapiconv == CK_AUTO && !tapipass) {
-printf(
-"Phone numbers are converted from canonical to dialable form by TAPI\n");
-printf("using the dialing rules specified in the TAPI Dialing Properties\n");
-printf("dialog.\n\n");
-
- } else {
-
-printf(
-"Phone numbers are converted from canonical to dialable form by K-95\n");
-printf(
-"using the dialing rules specified with the SET DIAL commands. TAPI\n");
-printf(
-"Dialing Properties are imported automaticly upon startup and whenever\n");
-printf("the TAPI Dialing Properties are altered or when the TAPI Location\n");
-printf("is changed.\n\n");
- }
-#endif /* BETATEST */
-
- if (tapipass) {
- printf("Type SHOW MODEM to see MODEM configuration.\n");
- if (tapiconv == CK_ON)
- printf("Type SHOW DIAL to see DIAL-related items.\n");
- } else {
- if (tapiconv == CK_ON || tapiconv == CK_AUTO)
- printf("Type SHOW DIAL to see DIAL-related items.\n");
- }
- break;
- case 1:
- cktapiDisplayTapiLocationInfo();
- break;
- case 2:
- rc = cktapiGetModemSettings(&lpDevCfg,&lpModemSettings,
- &lpCommConfig,&lpDCB);
- if (rc) {
- cktapiDisplayModemSettings(lpDevCfg,lpModemSettings,
- lpCommConfig,lpDCB);
- } else {
- printf("?Unable to retrieve Modem Settings\n");
- }
- break;
- case 3: {
- HANDLE hModem = GetModemHandleFromLine((HLINE)0);
- if (hModem)
- DisplayCommProperties(hModem);
- else
- printf("?Unable to retrieve a valid Modem Handle\n");
- CloseHandle(hModem);
- break;
- }
- }
- printf("\n");
-}
-#endif /* CK_TAPI */
-#endif /* NOLOCAL */
-
-#ifdef PATTERNS
-static VOID
-shopat() {
- extern char * binpatterns[], * txtpatterns[];
- extern int patterns, filepeek;
- char **p, *s;
- int i, j, k, n, flag, width;
-#ifdef CK_TTGWSIZ
- ttgwsiz(); /* Try to get latest size */
-#ifdef OS2
- width = tt_cols[VCMD];
-#else /* OS2 */
- width = tt_cols;
-#endif /* OS2 */
- if (width < 1)
-#endif /* CK_TTGWSIZ */
- width = 80;
- printf("\n");
- printf(" Set file type: %s\n",gfmode(binary,1));
- printf(" Set file patterns: %s", showooa(patterns));
-#ifdef CK_LABELED
- if (binary == XYFT_L)
- printf(" (but SET FILE TYPE LABELED overrides)\n");
- else
-#endif /* CK_LABELED */
-#ifdef VMS
- if (binary == XYFT_I)
- printf(" (but SET FILE TYPE IMAGE overrides)\n");
- else
-#endif /* VMS */
- if (filepeek)
- printf(" (but SET FILE SCAN ON overrides)\n");
- else
- printf("\n");
- printf(" Maximum patterns allowed: %d\n", FTPATTERNS);
- for (k = 0; k < 2; k++) { /* For each kind of patter */
- printf("\n");
- if (k == 0) { /* binary... */
- printf(" File binary-patterns: ");
- p = binpatterns;
- } else { /* text... */
- printf(" File text-patterns: ");
- p = txtpatterns;
- }
- if (!p[0]) {
- printf("(none)\n");
- } else {
- printf("\n ");
- n = 2;
- for (i = 0; i < FTPATTERNS; i++) { /* For each pattern */
- if (!p[i]) /* Done */
- break;
- s = p[i]; /* Look for embedded space */
- for (j = 0, flag = 1; *s; s++, j++) /* and also get length */
- if (*s == SP)
- flag = 3;
- n += j + flag; /* Length of this line */
- if (n >= width - 1) {
- printf("\n ");
- n = j+2;
- }
- printf(flag == 3 ? " {%s}" : " %s", p[i]);
- }
- if (n > 2)
- printf("\n");
- }
- }
- printf("\n");
-}
-#endif /* PATTERNS */
-
-#ifndef NOSPL
-static VOID
-shooutput() {
- printf(" Output pacing: %d (milliseconds)\n",pacing);
- printf(" Output special-escapes: %s\n", showoff(outesc));
-}
-
-static VOID
-shoinput() {
-#ifdef CKFLOAT
- extern char * inpscale;
-#endif /* CKFLOAT */
-
-#ifdef CK_AUTODL
- printf(" Input autodownload: %s\n", showoff(inautodl));
-#endif /* CK_AUTODL */
- printf(" Input cancellation: %s\n", showoff(inintr));
- printf(" Input case: %s\n", inpcas[cmdlvl] ?
- "observe" : "ignore");
- printf(" Input buffer-length: %d\n", inbufsize);
- printf(" Input echo: %s\n", showoff(inecho));
- printf(" Input silence: %d (seconds)\n", insilence);
-#ifdef OS2
- printf(" Input terminal: %s\n", showoff(interm));
-#endif /* OS2 */
- printf(" Input timeout: %s\n", intime[cmdlvl] ?
- "quit" : "proceed");
-#ifdef CKFLOAT
- printf(" Input scale-factor: %s\n", inpscale ? inpscale : "1.0");
-#endif /* CKFLOAT */
-
- if (instatus < 0)
- printf(" Last INPUT: -1 (INPUT command not yet given)\n");
- else
- printf(" Last INPUT: %d (%s)\n", instatus,i_text[instatus]);
-}
-#endif /* NOSPL */
-
-#ifndef NOSPL
-int
-showarray() {
-#ifdef COMMENT
- char * p, * q, ** ap;
- int i;
-#endif /* COMMENT */
- char *s; int x = 0, y;
- int range[2];
-
- if ((y = cmfld("Array name","",&s,NULL)) < 0)
- if (y != -3)
- return(y);
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- if ((y = cmcfm()) < 0)
- return(y);
- if (*s) {
- char ** ap;
- if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
- printf("?Bad array: %s\n",s);
- return(-9);
- }
- ap = a_ptr[x];
- if (!ap) {
- printf("Array not declared: %s\n", s);
- return(success = 1);
- } else {
- int i, n, max;
- max = (range[1] > 0) ?
- range[1] :
- ((range[0] > 0) ? range[0] : a_dim[x]);
- if (range[0] < 0)
- range[0] = 0;
- if (max > a_dim[x])
- max = a_dim[x];
- n = 1;
- printf("\\&%c[]: Dimension = %d",arrayitoa(x),a_dim[x]);
- if (a_link[x] > -1)
- printf(" (Link to \\&%c[])",arrayitoa(a_link[x]));
- printf("\n");
- for (i = range[0]; i <= max; i++) {
- if (ap[i]) {
- printf("%3d. %s\n",i,ap[i]);
- if (xaskmore) {
- if (cmd_cols > 0) {
- x = strlen(ap[i]) + 5;
- y = (x % cmd_cols) ? 1 : 0;
- n += (x / cmd_cols) + y;
- } else {
- n++;
- }
- if (n > (cmd_rows - 3)) {
- if (!askmore())
- break;
- else
- n = 0;
- }
- }
- }
- }
- }
- return(1);
- }
-
- /* All arrays - just show name and dimension */
-
- for (y = 0; y < (int) 'z' - ARRAYBASE + 1; y++) {
- if (a_ptr[y]) {
- if (x == 0) printf("Declared arrays:\n");
- x = 1;
- printf(" \\&%c[%d]",
- (y == 1) ? 64 : y + ARRAYBASE, a_dim[y]);
- if (a_link[y] > -1)
- printf(" => \\&%c[]",arrayitoa(a_link[y]));
- printf("\n");
- }
- if (!x) printf(" No arrays declared\n");
- }
- return(1);
-}
-#endif /* NOSPL */
-
-int
-doshow(x) int x; {
- int y, z, i; long zz;
- extern int optlines;
- char *s;
-#ifdef OS2
- extern int os2gks;
- extern int tt_kb_mode;
-#endif /* OS2 */
- extern int srvcdmsg;
- extern char * cdmsgstr, * ckcdpath;
-
-#ifndef NOSETKEY
- if (x == SHKEY) { /* SHOW KEY */
- int c;
-#ifdef OS2
- if ((x = cmkey(shokeytab,nshokey,"How many keys should be shown?",
- "one",xxstring)) < 0) return(x);
- switch (tt_kb_mode) {
- case KBM_EM:
- s = "emacs";
- break;
- case KBM_HE:
- s = "hebrew";
- break;
- case KBM_RU:
- s = "russian";
- break;
- case KBM_EN:
- default:
- s = "default";
- break;
- }
- if ((z = cmkey(shokeymtab,nshokeym,"Which definition should be shown?",
- s,xxstring)) < 0) return(z);
- if (z == SHKEYDEF)
- z = -1;
-#endif /* OS2 */
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-
-#ifdef MAC
- printf("Not implemented\n");
- return(0);
-#else /* Not MAC */
-#ifdef OS2
- if (x) {
- con_event evt;
- for (c = 0; c < KMSIZE; c++) {
- evt = (z < 0) ? mapkey(c) : maptermkey(c,z);
- if (evt.type != error) {
- shokeycode(c,z);
- }
- }
- } else {
-#endif /* OS2 */
- printf(" Press key: ");
-#ifdef UNIX
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
-#endif /* UNIX */
- conbin((char)escape); /* Put terminal in binary mode */
-#ifdef OS2
- os2gks = 0; /* Raw scancode processing */
-#endif /* OS2 */
- c = congks(0); /* Get character or scan code */
-#ifdef OS2
- os2gks = 1; /* Cooked scancode processing */
-#endif /* OS2 */
- concb((char)escape); /* Restore terminal to cbreak mode */
- if (c < 0) { /* Check for error */
- printf("?Error reading key\n");
- return(0);
- }
-#ifndef OS2
-/*
- Do NOT mask when it can be a raw scan code, perhaps > 255
-*/
- c &= cmdmsk; /* Apply command mask */
-#endif /* OS2 */
- printf("\n");
-#ifdef OS2
- shokeycode(c,z);
-#else /* OS2 */
- shokeycode(c);
-#endif /* OS2 */
-#ifdef OS2
- }
-#endif /* OS2 */
- return(1);
-#endif /* MAC */
- }
-#ifndef NOKVERBS
- if (x == SHKVB) { /* SHOW KVERBS */
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- printf("\nThe following %d keyboard verbs are available:\n\n",nkverbs);
- kwdhelp(kverbs,nkverbs,"","\\K","",3,0);
- printf("\n");
- return(1);
- }
-#ifdef OS2
- if (x == SHUDK) { /* SHOW UDKs */
- extern void showudk(void);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- showudk();
- return(1);
- }
-#endif /* OS2 */
-#endif /* NOKVERBS */
-#endif /* NOSETKEY */
-
-#ifndef NOSPL
- if (x == SHMAC) { /* SHOW MACRO */
- struct FDB kw, fl, cm;
- int i, k, n = 0, left, flag, confirmed = 0;
- char * p, *q[64];
- for (i = 0; i < nmac; i++) { /* copy the macro table */
- mackey[i].kwd = mactab[i].kwd; /* into a regular keyword table */
- mackey[i].kwval = i; /* with value = pointer to macro tbl */
- mackey[i].flgs = mactab[i].flgs;
- }
- p = line;
- left = LINBUFSIZ;
- while (!confirmed && n < 64) {
- cmfdbi(&kw, /* First FDB - macro table */
- _CMKEY, /* fcode */
- "Macro name", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nmac, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- mackey, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* 2nd FDB - something not in mactab */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* 3rd FDB - Confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
- x = cmfdb(&kw); /* Parse something */
- if (x < 0)
- return(x);
- s = atmbuf; /* What the user typed */
- switch (cmresult.fcode) {
- case _CMKEY: /* If it was a keyword */
- y = mlook(mactab,atmbuf,nmac); /* get full name */
- if (y > -1)
- s = mactab[y].kwd; /* (fall thru on purpose...) */
- case _CMFLD:
- k = ckstrncpy(p,s,left) + 1; /* Copy result to list */
- left -= k;
- if (left <= 0) {
- *p = NUL;
- break;
- }
- q[n++] = p; /* Point to this item */
- p += k; /* Move buffer pointer past it */
- break;
- case _CMCFM: /* End of command */
- confirmed++;
- default:
- break;
- }
- }
- if (n == 0) {
- printf("Macros:\n");
- slc = 1;
- for (y = 0; y < nmac; y++)
- if (shomac(mactab[y].kwd,mactab[y].mval) < 0) break;
- return(1);
- }
- slc = 0;
- for (i = 0; i < n; i++) {
- flag = 0;
- s = q[i];
- if (!s) s = "";
- if (!*s) continue;
- if (iswild(s)) { /* Pattern match */
- for (k = 0, x = 0; x < nmac; x++) {
- if (ckmatch(s,mactab[x].kwd,0,1)) {
- shomac(mactab[x].kwd,mactab[x].mval);
- k++;
- }
- }
- if (!k)
- x = -1;
- else
- continue;
- } else { /* Exact match */
- x = mxlook(mactab,s,nmac);
- flag = 1;
- }
- if (flag && x == -1)
- x = mlook(mactab,s,nmac);
- switch (x) {
- case -3: /* Nothing to look up */
- case -1: /* Not found */
- printf("%s - (not defined)\n",s);
- break;
- case -2: /* Ambiguous, matches more than one */
- printf("%s - ambiguous\n",s);
- break;
- default: /* Matches one exactly */
- shomac(mactab[x].kwd,mactab[x].mval);
- break;
- }
- }
- return(1);
- }
-#endif /* NOSPL */
-
-/*
- Other SHOW commands only have two fields. Get command confirmation here,
- then handle with big switch() statement.
-*/
-#ifndef NOSPL
- if (x != SHBUI && x != SHARR)
-#endif /* NOSPL */
- if ((y = cmcfm()) < 0)
- return(y);
-
-#ifdef COMMENT
- /* This restriction is too general. */
-#ifdef IKSD
- if (inserver &&
-#ifdef CK_LOGIN
- isguest
-#else
- 0
-#endif /* CK_LOGIN */
- ) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#endif /* COMMENT */
-
- switch (x) {
-
-#ifdef ANYX25
-#ifndef IBMX25
- case SHPAD:
- shopad(0);
- break;
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
- case SHNET:
-#ifdef NOLOCAL
- printf(" No network support in this version of C-Kermit.\n");
-#else
-#ifndef NETCONN
- printf(" No network support in this version of C-Kermit.\n");
-#else
- shonet();
-#endif /* NETCONN */
-#endif /* NOLOCAL */
- break;
-
- case SHPAR:
- shopar();
- break;
-
-#ifndef NOXFER
- case SHATT:
- shoatt();
- break;
-#endif /* NOXFER */
-
-#ifndef NOSPL
- case SHCOU:
- printf(" %d\n",count[cmdlvl]);
- break;
-#endif /* NOSPL */
-
-#ifndef NOSERVER
- case SHSER: /* Show Server */
- i = 0;
-#ifndef NOFRILLS
- printf("Function: Status:\n");
- i++;
- printf(" GET %s\n",nm[en_get]);
- i++;
- printf(" SEND %s\n",nm[en_sen]);
- i++;
- printf(" MAIL %s\n",nm[inserver ? 0 : en_mai]);
- i++;
- printf(" PRINT %s\n",nm[inserver ? 0 : en_pri]);
- i++;
-#ifndef NOSPL
- printf(" REMOTE ASSIGN %s\n",nm[en_asg]);
- i++;
-#endif /* NOSPL */
- printf(" REMOTE CD/CWD %s\n",nm[en_cwd]);
- i++;
-#ifdef ZCOPY
- printf(" REMOTE COPY %s\n",nm[en_cpy]);
- i++;
-#endif /* ZCOPY */
- printf(" REMOTE DELETE %s\n",nm[en_del]);
- printf(" REMOTE DIRECTORY %s\n",nm[en_dir]);
- printf(" REMOTE HOST %s\n",nm[inserver ? 0 : en_hos]);
- i += 3;
-#ifndef NOSPL
- printf(" REMOTE QUERY %s\n",nm[en_que]);
- i++;
-#endif /* NOSPL */
- printf(" REMOTE MKDIR %s\n",nm[en_mkd]);
- printf(" REMOTE RMDIR %s\n",nm[en_rmd]);
- printf(" REMOTE RENAME %s\n",nm[en_ren]);
- printf(" REMOTE SET %s\n",nm[en_set]);
- printf(" REMOTE SPACE %s\n",nm[en_spa]);
- printf(" REMOTE TYPE %s\n",nm[en_typ]);
- printf(" REMOTE WHO %s\n",nm[inserver ? 0 : en_who]);
- printf(" BYE %s\n",nm[en_bye]);
- printf(" FINISH %s\n",nm[en_fin]);
- printf(" EXIT %s\n",nm[en_xit]);
- printf(" ENABLE %s\n",nm[en_ena]);
- i += 11;
-#endif /* NOFRILLS */
- if (i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
- printf("Server timeout: %d\n",srvtim);
- if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
- printf("Server idle-timeout: %d\n",srvidl);
- if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
- printf("Server keepalive %s\n", showoff(srvping));
- if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
- printf("Server cd-message %s\n", showoff(srvcdmsg));
- if (srvcdmsg && cdmsgstr)
- printf("Server cd-message %s\n", cdmsgstr);
- if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
- printf("Server display: %s\n", showoff(srvdis));
- if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
- printf("Server login: ");
- if (!x_user) {
- printf("(none)\n");
- } else {
- printf("\"%s\", \"%s\", \"%s\"\n",
- x_user,
- x_passwd ? x_passwd : "",
- x_acct ? x_acct : ""
- );
- }
- if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
- printf("Server get-path: ");
- if (ngetpath == 0) {
- printf(" (none)\n");
- } else {
- printf("\n");
- i += 3;
- for (x = 0; x < ngetpath; x++) {
- if (getpath[x]) printf(" %d. %s\n", x, getpath[x]);
- if (++i > (cmd_rows - 3)) { /* More than a screenful... */
- if (!askmore())
- break;
- else
- i = 0;
- }
- }
- }
- break;
-#endif /* NOSERVER */
-
- case SHSTA: /* Status of last command */
- printf(" %s\n", success ? "SUCCESS" : "FAILURE");
- return(0); /* Don't change it */
-
- case SHSTK: { /* Stack for MAC debugging */
-#ifdef MAC
- long sp;
- sp = -1;
- loadA0 ((char *)&sp); /* set destination address */
- SPtoaA0(); /* move SP to destination */
- printf("Stack at 0x%x\n", sp);
- show_queue(); /* more debugging */
- break;
-#else
- shostack();
-#endif /* MAC */
- break;
- }
-
-
-#ifndef NOLOCAL
-#ifdef OS2
- case SHTAB: /* SHOW TABS */
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- shotabs();
- break;
-#endif /* OS2 */
-
- case SHTER: /* SHOW TERMINAL */
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- shotrm();
- break;
-
-#ifdef OS2
- case SHVSCRN: /* SHOW Virtual Screen - for debug */
- shovscrn();
- break;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifdef OS2MOUSE
- case SHMOU: /* SHOW MOUSE */
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- shomou();
- break;
-#endif /* OS2MOUSE */
-
-#ifndef NOFRILLS
- case SHVER:
- shover();
- break;
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
- case SHBUI: /* Built-in variables */
- line[0] = NUL;
- if ((y = cmtxt("Variable name or pattern","",&s,xxstring)) < 0)
- return(y);
- ckstrncpy(line,s,LINBUFSIZ);
- /* if (line[0]) ckstrncat(line,"*",LINBUFSIZ); */
-
- case SHFUN: /* or built-in functions */
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- if (tt_cols[VTERM] < 0 || tt_rows[VTERM] < 0)
- ttgwsiz();
-#else /* OS2 */
- if (ttgwsiz() > 0) { /* Get current screen size */
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
- if (x == SHFUN) { /* Functions */
- printf("\nThe following functions are available:\n\n");
- kwdhelp(fnctab,nfuncs,"","\\F","()",3,0);
- printf("\n");
-#ifndef NOHELP
- printf(
-"HELP FUNCTION <name> gives the calling conventions of the given function.\n\n"
- );
-#endif /* NOHELP */
- break;
- } else { /* Variables */
- int j, flag = 0, havearg = 0;
- struct stringarray * q = NULL;
- char ** pp;
- if (line[0]) { /* Have something to search for */
- havearg = 1; /* Maybe a list of things */
- q = cksplit(1,0,line,NULL,"_-^$*?[]{}",0,0,0);
- if (!q) break;
- pp = q->a_head;
- }
- i = 0;
- for (y = 0; y < nvars; y++) {
- if ((vartab[y].flgs & CM_INV))
- continue;
- if (havearg) { /* If I have something to match */
- char * s2;
- for (flag = 0, j = 1; j <= q->a_size && !flag; j++) {
- s2 = pp[j] ? pp[j] : "";
-#ifdef COMMENT
-/* This is not needed because it's what the 4 arg does in ckmatch() */
- len = strlen(s2);
- if (len > 0) {
- if (s2[len-1] != '$') {/* To allow anchors */
- ckmakmsg(line,LINBUFSIZ,pp[j],"*",NULL,NULL);
- s2 = line;
- }
- }
-#endif /* COMMENT */
- if (ckmatch(s2,vartab[y].kwd,0,4) > 0) {
- flag = 1; /* Matches */
- break;
- }
- }
- if (!flag) /* Doesn't match */
- continue;
- }
- s = nvlook(vartab[y].kwd);
- printf(" \\v(%s) = ",vartab[y].kwd);
- if (vartab[y].kwval == VN_NEWL) { /* \v(newline) */
- while (*s) /* Show control chars symbolically */
- printf("\\{%d}",*s++);
- printf("\n");
- } else if (vartab[y].kwval == VN_IBUF || /* \v(input) */
- vartab[y].kwval == VN_QUE || /* \v(query) */
-#ifdef OS2
- vartab[y].kwval == VN_SELCT || /* \v(select) */
-#endif /* OS2 */
- (vartab[y].kwval >= VN_M_AAA && /* modem ones */
- vartab[y].kwval <= VN_M_ZZZ)
- ) {
- int r = 12; /* This one can wrap around */
- char buf[10];
- while (*s) {
- if (isprint(*s)) {
- buf[0] = *s;
- buf[1] = NUL;
- r++;
- } else {
- sprintf(buf,"\\{%d}",*s); /* SAFE */
- r += (int) strlen(buf);
- }
- if (r >= cmd_cols - 1) {
- printf("\n");
- r = 0;
- i++;
- }
- printf("%s",buf);
- s++;
- }
- printf("\n");
- } else
- printf("%s\n",s);
- if (++i > (cmd_rows - 3)) { /* More than a screenful... */
- if ((y >= nvars - 1) || !askmore())
- break;
- else
- i = 0;
- }
- }
- }
- break;
-
- case SHVAR: /* Global variables */
- x = 0; /* Variable count */
- slc = 1; /* Screen line count for "more?" */
- for (y = 33; y < GVARS; y++)
- if (g_var[y]) {
- if (x++ == 0) printf("Global variables:\n");
- sprintf(line," \\%%%c",y); /* SAFE */
- if (shomac(line,g_var[y]) < 0) break;
- }
- if (!x) printf(" No variables defined\n");
- break;
-
- case SHARG: { /* Args */
- char * s1, * s2;
- if (maclvl > -1) {
- printf("Macro arguments at level %d (\\v(argc) = %d):\n",
- maclvl,
- macargc[maclvl]
- );
- for (y = 0; y < macargc[maclvl]; y++) {
- s1 = m_arg[maclvl][y];
- if (!s1) s1 = "(NULL)";
- s2 = m_xarg[maclvl][y];
- if (!s2) s2 = "(NULL)";
- if (y < 10)
- printf(" \\%%%d = %s\n",y,s1);
- else
- printf(" \\&_[%d] = %s\n",y,s2);
- }
- } else {
- printf("Top-level arguments (\\v(argc) = %d):\n", topargc);
- for (y = 0; y < topargc; y++) {
- s1 = g_var[y + '0'];
- if (!s1) s1 = "(NULL)";
- s2 = toparg[y];
- if (!s2) s2 = "(NULL)";
- if (y < 10 && g_var[y])
- printf(" \\%%%d = %s\n",y,s1);
- if (toparg[y])
- printf(" \\&_[%d] = %s\n",y,s2);
- }
- }
- }
- break;
-
- case SHARR: /* Arrays */
- return(showarray());
-#endif /* NOSPL */
-
-#ifndef NOXFER
- case SHPRO: /* Protocol parameters */
- shoparp();
- printf("\n");
- break;
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
- case SHCOM: /* Communication parameters */
- printf("\n");
- shoparc();
-#ifdef OS2
- {
- int i;
- char *s = "(unknown)";
- for (i = 0; i < nprty; i++)
- if (prtytab[i].kwval == priority) {
- s = prtytab[i].kwd;
- break;
- }
- printf(" Priority: %s\n", s );
- }
-#endif /* OS2 */
-
- printf("\n");
-#ifdef NETCONN
- if (!network
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- ) {
-#endif /* NETCONN */
- shomdm();
- printf("\n");
-#ifdef NETCONN
- }
-#endif /* NETCONN */
-
-#ifndef NODIAL
-#ifdef IKSD
- if ( !inserver )
-#endif /* IKSD */
- {
- printf("Type SHOW DIAL to see DIAL-related items.\n");
- printf("Type SHOW MODEM to see modem-related items.\n");
-#ifdef CK_TAPI
- printf("Type SHOW TAPI to see TAPI-related items.\n");
-#endif /* CK_TAPI */
- printf("\n");
- }
-#endif /* NODIAL */
- break;
-#endif /* NOLOCAL */
-
- case SHFIL: /* File parameters */
- shofil();
- /* printf("\n"); */ /* (out o' space) */
- break;
-
-#ifndef NOCSETS
- case SHLNG: /* Languages */
- shoparl();
- break;
-#endif /* NOCSETS */
-
-#ifndef NOSPL
- case SHSCR: /* Scripts */
- printf(" Command quoting: %s\n", showoff(cmdgquo()));
- printf(" Take echo: %s\n", showoff(techo));
- printf(" Take error: %s\n", showoff(takerr[cmdlvl]));
- printf(" Macro echo: %s\n", showoff(mecho));
- printf(" Macro error: %s\n", showoff(merror[cmdlvl]));
- printf(" Quiet: %s\n", showoff(quiet));
- printf(" Variable evaluation: %s [\\%%x and \\&x[] variables]\n",
- vareval ? "recursive" : "simple");
- printf(" Function diagnostics: %s\n", showoff(fndiags));
- printf(" Function error: %s\n", showoff(fnerror));
-#ifdef CKLEARN
- {
- extern char * learnfile;
- extern int learning;
- if (learnfile) {
- printf(" LEARN file: %s (%s)\n",
- learnfile,
- learning ? "ON" : "OFF"
- );
- } else
- printf(" LEARN file: (none)\n");
- }
-#endif /* CKLEARN */
- shoinput();
- shooutput();
-#ifndef NOSCRIPT
- printf(" Script echo: %s\n", showoff(secho));
-#endif /* NOSCRIPT */
- printf(" Command buffer length: %d\n", CMDBL);
- printf(" Atom buffer length: %d\n", ATMBL);
- break;
-#endif /* NOSPL */
-
-#ifndef NOXMIT
- case SHXMI:
- printf("\n");
- printf(" File type: %s\n",
- binary ? "binary" : "text");
-#ifndef NOCSETS
- printf(" File character-set: %s\n",
- fcsinfo[fcharset].keyword);
-#ifdef OS2
- if ( isunicode() ) {
- printf(" Terminal Character (remote): %s\n",
- tt_utf8 ? "utf-8" : tcsr == TX_TRANSP ? "transparent" :
- tcsr == TX_UNDEF ? "undefined" : txrinfo[tcsr]->keywd);
- printf(" Terminal Character (local): %s\n",
- tcsl == TX_TRANSP ? "transparent" :
- tcsl == TX_UNDEF ? "undefined" : txrinfo[tcsl]->keywd);
- } else {
- printf(" Terminal Character (remote): %s\n",
- tt_utf8 ? "utf-8" : tcsr == TX_TRANSP ? "transparent" :
- tcsr == TX_UNDEF ? "undefined" : txrinfo[tcsr]->keywd);
- printf(" Terminal Character (local): %s\n",
- tcsl == TX_TRANSP ? "transparent" :
- tcsl == TX_UNDEF ? "undefined" : txrinfo[tcsl]->keywd);
- }
-#else /* OS2 */
- printf(" Terminal character-set (remote): %s\n",
- fcsinfo[tcsr].keyword);
- printf(" Terminal character-set (local): %s\n",
- fcsinfo[tcsl].keyword);
-#endif /* OS2 */
-#endif /* NOCSETS */
- printf(" Terminal bytesize: %d\n",
- (cmask == 0xff) ? 8 : 7);
- printf(" Terminal echo: %s\n",
- duplex ? "local" : "remote");
- printf(" Transmit EOF: ");
- if (*xmitbuf == NUL) {
- printf("(none)\n");
- } else {
- char *p;
- p = xmitbuf;
- while (*p) {
- if (*p < SP)
- printf("^%c",ctl(*p));
- else
- printf("%c",*p);
- p++;
- }
- printf("\n");
- }
- if (xmitf)
- printf(" Transmit Fill: %d\n", xmitf);
- else
- printf(" Transmit Fill: (none)\n");
- printf(" Transmit Linefeed: %s\n",showoff(xmitl));
- if (xmitp)
- printf(" Transmit Prompt: %d (%s)\n",
- xmitp,
- chartostr(xmitp)
- );
- else
- printf(" Transmit Prompt: (none)\n");
- printf(" Transmit Echo: %s\n", showoff(xmitx));
- printf(" Transmit Locking-Shift: %s\n", showoff(xmits));
- printf(" Transmit Pause: %d (millisecond%s)\n",
- xmitw,
- (xmitw == 1) ? "" : "s"
- );
- printf(" Transmit Timeout: %d (second%s)\n",
- xmitt,
- (xmitt == 1) ? "" : "s"
- );
- printf("\n");
- break;
-#endif /* NOXMIT */
-
-#ifndef NODIAL
- case SHMOD: /* SHOW MODEM */
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- shomodem(); /* Show SET MODEM items */
- break;
-#endif /* NODIAL */
-
-#ifndef MAC
- case SHDFLT:
- printf("%s\n",zgtdir());
- break;
-#endif /* MAC */
-
-#ifndef NOLOCAL
- case SHESC:
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- return(shoesc(escape));
-
-#ifndef NODIAL
- case SHDIA: /* SHOW DIAL */
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- shmdmlin();
- printf(", speed: ");
- if ((zz = ttgspd()) < 0) {
- printf("unknown");
- } else {
- if (zz == 8880) printf("75/1200"); else printf("%ld",zz);
- }
- if (carrier == CAR_OFF) s = "off";
- else if (carrier == CAR_ON) s = "on";
- else if (carrier == CAR_AUT) s = "auto";
- else s = "unknown";
- printf(", carrier: %s", s);
- if (carrier == CAR_ON) {
- if (cdtimo) printf(", timeout: %d sec", cdtimo);
- else printf(", timeout: none");
- }
- printf("\n");
- doshodial();
- if (local
-#ifdef NETCONN
- && !network
-#endif /* NETCONN */
- ) {
- printf("Type SHOW MODEM to see modem settings.\n");
-#ifdef CK_TAPI
- printf("Type SHOW TAPI to see TAPI-related items\n");
-#endif /* CK_TAPI */
- printf("Type SHOW COMMUNICATIONS to see modem signals.\n");
- }
- break;
-#endif /* NODIAL */
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
-#ifdef CK_LABELED
- case SHLBL: /* Labeled file info */
- sholbl();
- break;
-#endif /* CK_LABELED */
-#endif /* NOXFER */
-
- case SHCSE: /* Character sets */
-#ifdef NOCSETS
- printf(
-" Character set translation is not supported in this version of C-Kermit\n");
-#else
- shocharset();
-#ifndef NOXFER
- printf("\n Unknown-Char-Set: %s\n",
- unkcs ? "Keep" : "Discard");
-#endif /* NOXFER */
-#ifdef OS2
- printf("\n");
-#endif /* OS2 */
- shotcs(tcsl,tcsr);
- printf("\n");
-#ifdef OS2
- /* PC Code Page information */
- {
- char cpbuf[128];
- int cplist[16], cps;
- int activecp;
- cps = os2getcplist(cplist, sizeof(cplist));
-
- sprintf(cpbuf, /* SAFE */
- "%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d",
- cps > 1 ? cplist[1] : 0,
- cps > 2 ? cplist[2] : 0, cps > 3 ? cplist[3] : 0,
- cps > 4 ? cplist[4] : 0, cps > 5 ? cplist[5] : 0,
- cps > 6 ? cplist[6] : 0, cps > 7 ? cplist[7] : 0,
- cps > 8 ? cplist[8] : 0, cps > 9 ? cplist[9] : 0,
- cps > 10 ? cplist[10] : 0, cps > 11 ? cplist[11] : 0,
- cps > 12 ? cplist[12] : 0
- );
- printf(" Code Pages:\n");
- activecp = os2getcp();
- if ( activecp ) {
- printf(" Active: %d\n",activecp);
- if (!isWin95())
- printf(" Available: %s\n",cpbuf);
- } else
- printf(" Active: n/a\n");
- printf("\n");
- }
-#endif /* OS2 */
-#endif /* NOCSETS */
- break;
-
- case SHFEA: /* Features */
- shofea();
- break;
-
-#ifdef CK_SPEED
- case SHCTL: /* Control-Prefix table */
- shoctl();
- break;
-#endif /* CK_SPEED */
-
- case SHEXI: {
- extern int exithangup;
- printf("\n Exit warning %s\n", xitwarn ?
- (xitwarn == 1 ? "on" : "always") : "off");
- printf(" Exit on-disconnect: %s\n", showoff(exitonclose));
- printf(" Exit hangup: %s\n", showoff(exithangup));
- printf(" Current exit status: %d\n\n", xitsta);
- break;
- }
- case SHPRT: {
-#ifdef PRINTSWI
- extern int printtimo, printertype, noprinter;
- extern char * printterm, * printsep;
- extern int prncs;
-#ifdef BPRINT
- extern int printbidi;
-#endif /* BPRINT */
-#endif /* PRINTSWI */
-
-#ifdef IKSD
- if (inserver &&
-#ifdef CK_LOGIN
- isguest
-#else /* CK_LOGIN */
- 0
-#endif /* CK_LOGIN */
- ) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#ifdef PRINTSWI
- if (noprinter) {
- printf("Printer: (none)\n\n");
- break;
- }
-#endif /* PRINTSWI */
-
- printf("Printer: %s%s\n",
-
- printpipe ? "| " : "",
- printername ? printername :
-#ifdef OS2
- "PRN"
-#else
- "(default)"
-#endif /* OS2 */
- );
-#ifdef PRINTSWI
-#ifdef BPRINT
- if (printbidi) {
- printf(" /BIDIRECTIONAL\n");
- if (pportspeed > 0)
- printf(" /SPEED:%ld\n",pportspeed);
- printf(" /PARITY:%s\n",parnam((char)pportparity));
- printf(" /FLOW:%s\n",
- pportflow == FLO_NONE ? "NONE" :
- (pportflow == FLO_RTSC ? "RTS/CTS" : "XON/XOFF")
- );
- } else
- printf(" /OUTPUT-ONLY\n");
-#endif /* BPRINT */
- switch (printertype) {
- case PRT_NON: printf(" /NONE\n"); break;
- case PRT_FIL: printf(" /FILE\n"); break;
- case PRT_PIP: printf(" /PIPE\n"); break;
- case PRT_DOS: printf(" /DOS-DEVICE\n"); break;
- case PRT_WIN: printf(" /WINDOWS-QUEUE\n"); break;
- }
- printf(" /TIMEOUT:%d\n",printtimo);
- if (printterm) {
- printf(" /END-OF-JOB-STRING:");
- shostrdef(printterm);
- printf("\n");
- } else
- printf(" /END-OF-JOB-STRING:(none)\n");
- printf(" /JOB-HEADER-FILE:%s\n",printsep ? printsep : "(none)");
- printf(" /CHARACTER-SET: %s\n",txrinfo[prncs]->keywd);
-#endif /* PRINTSWI */
- printf("\n");
- break;
- }
-
- case SHCMD: {
-#ifdef DOUBLEQUOTING
- extern int dblquo;
-#endif /* DOUBLEQUOTING */
-#ifdef CK_AUTODL
- printf(" Command autodownload: %s\n",showoff(cmdadl));
-#else
- printf(" Command autodownload: (not available)\n");
-#endif /* CK_AUTODL */
- printf(" Command bytesize: %d bits\n", (cmdmsk == 0377) ? 8 : 7);
- printf(" Command error-display: %d\n", cmd_err);
-#ifdef CK_RECALL
- printf(" Command recall-buffer-size: %d\n",cm_recall);
-#else
- printf(" Command recall-buffer not available in this version\n");
-#endif /* CK_RECALL */
-#ifdef CK_RECALL
- printf(" Command retry: %s\n",showoff(cm_retry));
-#else
- printf(" Command retry not available in this version\n");
-#endif /* CK_RECALL */
- printf(" Command interruption: %s\n", showoff(cmdint));
- printf(" Command quoting: %s\n", showoff(cmdgquo()));
-#ifdef DOUBLEQUOTING
- printf(" Command doublequoting: %s\n", showoff(dblquo));
-#endif /* DOUBLEQUOTING */
- printf(" Command more-prompting: %s\n", showoff(xaskmore));
- printf(" Command height: %d\n", cmd_rows);
- printf(" Command width: %d\n", cmd_cols);
-#ifndef IKSDONLY
-#ifdef OS2
- printf(" Command statusline: %s\n",showoff(tt_status[VCMD]));
-#endif /* OS2 */
-#endif /* IKSDONLY */
-#ifdef LOCUS
- printf(" Locus: %s",
- autolocus ? (autolocus == 2 ? "ask" : "auto") :
- (locus ? "local" : "remote"));
- if (autolocus)
- printf(" (%s)", locus ? "local" : "remote");
- printf("\n");
-#endif /* LOCUS */
- printf(" Hints: %s\n", showoff(hints));
- printf(" Quiet: %s\n", showoff(quiet));
- printf(" Maximum command length: %d\n", CMDBL);
-#ifndef NOSPL
- {
- char * s;
- int k;
- printf(" Maximum number of macros: %d\n", MAC_MAX);
- printf(" Macros defined: %d\n", nmac);
- printf(" Maximum macro depth: %d\n", MACLEVEL);
- printf(" Maximum TAKE depth: %d\n", MAXTAKE);
- s = "(not defined)";
- k = mlook(mactab,"on_unknown_command",nmac);
- if (k > -1) if (mactab[k].mval) s = mactab[k].mval;
- printf(" ON_UNKNOWN_COMMAND: %s\n",s);
- }
-#endif /* NOSPL */
-#ifdef UNIX
-#ifndef NOJC
- printf(" Suspend: %s\n", showoff(xsuspend));
-#endif /* NOJC */
-#endif /* UNIX */
- printf(" Access to external commands and programs%s allowed\n",
-#ifndef NOPUSH
- !nopush ? "" :
-#endif /* NOPUSH */
- " not");
- break;
- }
-
-#ifndef NOSPL
- case SHALRM:
- if (ck_alarm)
- printf("Alarm at %s %s\n",alrm_date,alrm_time);
- else
- printf("(no alarm set)\n");
- break;
-#endif /* NOSPL */
-
-#ifndef NOMSEND
- case SHSFL: {
- extern struct filelist * filehead;
- if (!filehead) {
- printf("send-list is empty\n");
- } else {
- struct filelist * flp;
- char * s;
- flp = filehead;
- while (flp) {
- s = flp->fl_alias;
- if (!s) s = "(none)";
- printf("%s, mode: %s, alias: %s\n",
- flp->fl_name,
- gfmode(flp->fl_mode,0),
- s
- );
- flp = flp->fl_next;
- }
- }
- }
- break;
-#endif /* NOMSEND */
-
-#ifdef CKXXCHAR
- case SHDBL:
- shodbl();
- break;
-#endif /* CKXXCHAR */
-
-#ifndef NOPUSH
-#ifndef NOFRILLS
- case SHEDIT:
- if (!editor[0]) {
- s = getenv("EDITOR");
- if (s) ckstrncpy(editor,s,CKMAXPATH);
- }
- printf("\n editor: %s\n", editor[0] ? editor : "(none)");
- if (editor[0]) {
- printf(" options: %s\n", editopts[0] ? editopts : "(none)");
- printf(" file: %s\n", editfile[0] ? editfile : "(none)");
- }
- printf("\n");
- break;
-
-#ifdef BROWSER
- case SHBROWSE:
- if (!browser[0]) {
- s = getenv("BROWSER");
- if (s) ckstrncpy(browser,s,CKMAXPATH);
- }
- printf("\n browser: %s\n", browser[0] ? browser : "(none)");
- if (browser[0]) {
- printf(" options: %s\n", browsopts[0] ? browsopts : "(none)");
- printf(" url: %s\n", browsurl[0] ? browsurl : "(none)");
- }
- printf("\n");
- break;
-#endif /* BROWSER */
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-
-#ifndef NOLOCAL
-#ifdef CK_TAPI
- case SHTAPI: /* TAPI options */
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- shotapi(0);
- break;
- case SHTAPI_L: /* TAPI Locations */
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- shotapi(1);
- break;
- case SHTAPI_M: /* TAPI Modem */
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- shotapi(2);
- break;
- case SHTAPI_C: /* TAPI Comm */
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- shotapi(3);
- break;
-#endif /* CK_TAPI */
-
- case SHTCP: /* SHOTCP */
- printf("\n");
- shotcp(0);
- printf("\n");
- break;
-
-#ifdef TNCODE
- case SHTEL: /* TELNET */
- printf("\n");
- shotel(0);
- printf("\n");
- break;
-
- case SHTOPT: /* TELNET OPTIONS */
- printf("\n");
- shotopt(0);
- printf("\n");
- break;
-#endif /* TNCODE */
-
-#ifdef CK_TRIGGER
- case SHTRIG: {
- extern char * tt_trigger[], * triggerval;
- int i;
- if (!tt_trigger[0]) {
- printf(" Triggers: (none)\n");
- } else {
- printf(" Triggers:\n");
- for (i = 0; i < TRIGGERS; i++) {
- if (!tt_trigger[i])
- break;
- printf(" \"%s\"\n",tt_trigger[i]);
- }
- printf(" Most recent trigger encountered: ");
- if (triggerval)
- printf("\"%s\"\n",triggerval);
- else
- printf("(none)\n");
- }
- break;
- }
-#endif /* CK_TRIGGER */
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
- case SHINP:
- shoinput();
- break;
-#endif /* NOSPL */
-
- case SHLOG: {
-#ifndef MAC
-#ifdef IKSD
- if (inserver &&
-#ifdef CK_LOGIN
- isguest
-#else /* CK_LOGIN */
- 0
-#endif /* CK_LOGIN */
- ) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#ifdef DEBUG
- printf("\n Debug log: %s", deblog ? debfil : "(none)");
- {
- extern int debtim;
- if (debtim) printf(" (timestamps)");
- printf("\n");
- }
-#endif /* DEBUG */
-#ifndef NOXFER
- printf(" Packet log: %s\n", pktlog ? pktfil : "(none)");
-#endif /* NOXFER */
-#ifndef NOLOCAL
- printf(" Session log: %s", seslog ? sesfil : "(none)");
- {
- extern int sessft, slogts, slognul;
- switch (sessft) {
- case XYFT_T: printf(" (text)"); break;
- case XYFT_B: printf(" (binary)"); break;
- case XYFT_D: printf(" (debug)"); break;
- }
- if (slogts) printf("(timestamped)");
- if (slognul) printf("(null-padded)");
- printf("\n");
- }
-
-#endif /* NOLOCAL */
-#ifdef TLOG
- printf(" Transaction log: %s (%s)\n",
- (tralog ? (*trafil ? trafil : "(none)") : "(none)"),
- (tlogfmt ? ((tlogfmt == 2) ? "ftp" : "verbose") : "brief")
- );
-#endif /* TLOG */
-#ifdef CKLOGDIAL
- printf(" Connection log: %s\n", dialog ? diafil : "(none)");
-#endif /* CKLOGDIAL */
- printf("\n");
-#endif /* MAC */
- break;
- }
-
-#ifndef NOSPL
- case SHOUTP: /* OUTPUT */
- shooutput();
- break;
-#endif /* NOSPL */
-
-#ifdef PATTERNS
- case SHOPAT: /* PATTERNS */
- shopat();
- break;
-#endif /* PATTERNS */
-
-#ifdef STREAMING
- case SHOSTR: { /* STREAMING */
- extern int streamrq, clearrq, cleared;
- extern long tfcps;
- debug(F101,"SHOW RELIABLE reliable","",reliable);
- printf("\n Reliable: %s\n",showooa(reliable));
- printf(" Clearchannel: %s\n",showooa(clearrq));
- printf(" Streaming: %s\n\n",showooa(streamrq));
- if ((!local && (streamrq == SET_ON)) ||
- (streamrq == SET_AUTO && reliable))
- printf(" Streaming will be done if requested.\n");
- else if ((streamrq == SET_OFF) ||
- ((streamrq == SET_AUTO) && !reliable))
- printf(" Streaming will not be requested and will not be done.\n");
- else if ((streamrq == SET_ON) ||
- ((streamrq == SET_AUTO) && reliable))
- printf(
-" Streaming will be requested and will be done if the other Kermit agrees.\n");
- printf(" Last transfer: %sstreaming%s, %ld cps.\n",
- streamed > 0 ? "" : "no ",
- cleared ? ", clearchannel" : "",
- tfcps
- );
- printf("\n");
- break;
- }
-#endif /* STREAMING */
-
- case SHOIKS:
- return(sho_iks());
- break;
-
-#ifdef CK_AUTHENTICATION
- case SHOAUTH:
- return(sho_auth(0));
-#endif /* CK_AUTHENTICATION */
-
-#ifndef NOFTP
- case SHOFTP: {
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#ifdef SYSFTP
- {
- extern char ftpapp[], ftpopts[];
- printf(" ftp-client: %s\n", ftpapp[0] ? ftpapp : "(none)");
- if (ftpapp[0])
- printf(" ftp options: %s\n", ftpopts[0] ? ftpopts : "(none)");
- }
-#else
-#ifdef NEWFTP
- shoftp(0);
-#else
- printf("(No FTP client included in this version of Kermit.)\n");
-#endif /* NEWFTP */
-#endif /* SYSFTP */
- break;
- }
-#endif /* NOFTP */
-
-#ifndef NOCMDL
- case SHXOPT: {
-#ifdef IKSDB
- extern int dbenabled;
- extern char * dbfile, * dbdir;
-#endif /* IKSDB */
-#ifdef CKWTMP
- extern int ckxwtmp;
- extern char * wtmpfile;
-#endif /* CKWTMP */
-#ifdef CK_LOGIN
- extern int ckxanon, xferlog, logintimo;
- extern char * xferfile;
-#ifdef UNIX
- extern int ckxpriv;
-#endif /* UNIX */
-#ifdef CK_PERMS
- extern int ckxperms;
-#endif /* CK_PERMS */
-#endif /* CK_LOGIN */
- extern char * bannerfile, * helpfile;
-
-#ifdef IKSD
- if (inserver &&
-#ifdef CK_LOGIN
- isguest
-#else /* CK_LOGIN */
- 0
-#endif /* CK_LOGIN */
- ) {
- printf("Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- printf("\n");
- if (!cmdint)
- printf(" --nointerrupts\n");
- printf(" --bannerfile=%s\n",bannerfile ? bannerfile : "(null)");
- printf(" --cdfile:%s\n",cdmsgstr ? cdmsgstr : "(null)");
- printf(" --cdmessage:%d\n",srvcdmsg);
- printf(" --helpfile:%d\n",helpfile);
- if (inserver) {
- printf("\n");
- break;
- }
-#ifdef CKSYSLOG
-#ifdef SYSLOGLEVEL
- printf(" --syslog:%d (forced)\n",ckxsyslog);
-#else
- printf(" --syslog:%d\n",ckxsyslog);
-#endif /* SYSLOGLEVEL */
-#endif /* CKSYSLOG */
-#ifdef CKWTMP
- printf(" --wtmplog:%d\n",ckxwtmp);
- printf(" --wtmpfile=%s\n",wtmpfile ? wtmpfile : "(null)");
-#endif /* CKWTMP */
-#ifdef IKSD
-#ifdef CK_LOGIN
- printf(" --anonymous:%d\n",ckxanon);
-#ifdef UNIX
- printf(" --privid:%d\n",ckxpriv);
-#endif /* UNIX */
-#ifdef CK_PERMS
- printf(" --permission:%04o\n",ckxperms);
-#endif /* CK_PERMS */
- printf(" --initfile:%s\n",anonfile ? anonfile : "(null)");
- printf(" --userfile:%s\n",userfile ? userfile : "(null)");
- printf(" --root:%s\n",anonroot ? anonroot : "(null)");
- printf(" --xferlog=%d\n",xferlog);
- printf(" --xferfile=%s\n",xferfile ? xferfile : "(null)");
- printf(" --timeout=%d\n",logintimo);
-#endif /* CK_LOGIN */
-#ifdef IKSDB
- printf(" --database=%d\n",dbenabled);
- printf(" --dbfile=%s\n",dbfile ? dbfile : "(null)");
- if (dbdir)
- printf(" (db directory=[%s])\n",dbdir);
-#endif /* IKSDB */
-#ifdef IKSDCONF
- printf(" IKSD conf=%s\n",iksdconf);
-#endif /* IKSDCONF */
-#endif /* IKSD */
- printf("\n");
- break;
- }
-#endif /* NOCMDL */
-
- case SHCD: {
- extern char * myhome;
- s = getenv("CDPATH");
- if (!s) s = "(none)";
- printf("\n current directory: %s\n", zgtdir());
- printf(" previous directory: %s\n", prevdir ? prevdir : "(none)");
- printf(" cd home: %s\n", homepath());
- printf(" cd path: %s\n", ckcdpath ? ckcdpath : s);
- printf(" cd message: %s\n", showoff(srvcdmsg & 2));
- printf(" server cd-message: %s\n", showoff(srvcdmsg & 1));
- printf(" cd message file: %s\n\n",cdmsgstr ? cdmsgstr : "(none)");
- break;
- }
-#ifndef NOCSETS
- case SHASSOC:
- (VOID) showassoc();
- break;
-#endif /* NOCSETS */
-
-#ifdef CKLOGDIAL
- case SHCONNX:
-#ifdef NEWFTP
- if (ftpisconnected()) {
- extern char cxlogbuf[];
- dologshow(W_FTP | 1);
- if (cxlogbuf[0])
- dologshow(1);
- } else {
-#endif /* NEWFTP */
- dologshow(1);
-#ifdef NEWFTP
- }
-#endif /* NEWFTP */
- break;
-#endif /* CKLOGDIAL */
-
- case SHOPTS:
- optlines = 0;
-#ifndef NOFRILLS
- (VOID) showdelopts();
-#endif /* NOFRILLS */
-#ifdef DOMYDIR
- (VOID) showdiropts();
-#endif /* DOMYDIR */
-#ifdef CKPURGE
- (VOID) showpurgopts();
-#endif /* CKPURGE */
- (VOID) showtypopts();
- break;
-
-#ifndef NOLOCAL
- case SHOFLO:
- (VOID) shoflow();
- break;
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
- case SHOXFER:
- (VOID) shoxfer();
- break;
-#endif /* NOXFER */
-
-#ifdef CK_RECALL
- case SHHISTORY:
- (VOID) cmhistory();
- break;
-#endif /* CK_RECALL */
-
-#ifndef NOSEXP
-#ifndef NOSPL
- case SHSEXP:
- (VOID) shosexp();
- break;
-#endif /* NOSPL */
-#endif /* NOSEXP */
-
-#ifdef ANYSSH
- case SHOSSH:
- (VOID) shossh();
- break;
-#endif /* ANYSSH */
-
-#ifdef KUI
- case SHOGUI:
- (VOID) shogui();
- break;
-#endif /* KUI */
-
-#ifndef NOFRILLS
-#ifndef NORENAME
- case SHOREN:
- (VOID) shorename();
- break;
-#endif /* NORENAME */
-#endif /* NOFRILLS */
-
- default:
- printf("\nNothing to show...\n");
- return(-2);
- }
- return(success = 1);
-}
-
-#ifndef NOXFER
-int
-shoatt() {
- printf("Attributes: %s\n", showoff(atcapr));
- if (!atcapr) return(0);
- printf(" Blocksize: %s\n", showoff(atblki));
- printf(" Date: %s\n", showoff(atdati));
- printf(" Disposition: %s\n", showoff(atdisi));
- printf(" Encoding (Character Set): %s\n", showoff(atenci));
- printf(" Length: %s\n", showoff(atleni));
- printf(" Type (text/binary): %s\n", showoff(attypi));
- printf(" System ID: %s\n", showoff(atsidi));
- printf(" System Info: %s\n", showoff(atsysi));
-#ifdef CK_PERMS
- printf(" Permissions In: %s\n", showoff(atlpri));
- printf(" Permissions Out: %s\n", showoff(atlpro));
-#endif /* CK_PERMS */
-#ifdef STRATUS
- printf(" Format: %s\n", showoff(atfrmi));
- printf(" Creator: %s\n", showoff(atcrei));
- printf(" Account: %s\n", showoff(atacti));
-#endif /* STRATUS */
- return(0);
-}
-#endif /* NOXFER */
-
-#ifndef NOSPL
-int /* SHOW MACROS */
-shomac(s1, s2) char *s1, *s2; {
- int x, n, pp;
- pp = 0; /* Parenthesis counter */
-
- debug(F110,"shomac s1",s1,0);
- debug(F110,"shomac s2",s2,0);
-
-#ifdef IKSD
- if ( inserver &&
-#ifdef IKSDCONF
- iksdcf
-#else /* IKSDCONF */
- 1
-#endif /* IKSDCONF */
- ) {
- if (!ckstrcmp("on_exit",s1,-1,0) ||
- !ckstrcmp("on_logout",s1,-1,0))
- return(0);
- }
-#endif /* IKSD */
-
- if (!s1)
- return(0);
- else
- printf("%s = ",s1); /* Print blank line and macro name */
- n = (int)strlen(s1) + 4; /* Width of current line */
- if (!s2) s2 = "(not defined)";
-
- while ((x = *s2++)) { /* Loop thru definition */
- if (x == '(') pp++; /* Treat commas within parens */
- if (x == ')') pp--; /* as ordinary text */
- if (pp < 0) pp = 0; /* Outside parens, */
- if (x == ',' && pp == 0) { /* comma becomes comma-dash-NL. */
- putchar(',');
- putchar('-');
- x = '\n';
- }
- if (inserver && (x == '\n')) /* Send CR before LF */
- putchar(CR);
- putchar((CHAR)x); /* Output the character */
- if (x == '\n') { /* If it was a newline */
-#ifdef UNIX
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
-#endif /* UNIX */
- putchar(' '); /* Indent the next line 1 space */
- while(*s2 == ' ') s2++; /* skip past leading blanks */
- n = 2; /* restart the character counter */
- slc++; /* and increment the line counter. */
- } else if (++n > (cmd_cols - 1)) { /* If line is too wide */
- putchar('-'); /* output a dash */
- if (inserver)
- putchar(CR); /* and a carriage return */
- putchar(NL); /* and a newline */
-#ifdef UNIX
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
-#endif /* UNIX */
- n = 1; /* and restart the char counter */
- slc++; /* and increment the line counter */
- }
- if (n < 3 && slc > (cmd_rows - 3)) { /* If new line and screen full */
- if (!askmore()) return(-1); /* ask if they want more. */
- n = 1; /* They do, start a new line */
- slc = 0; /* and restart line counter */
- }
- }
- if (inserver)
- putchar(CR);
- putchar(NL); /* End of definition */
- if (++slc > (cmd_rows - 3)) {
- if (!askmore()) return(-1);
- slc = 0;
- }
- return(0);
-}
-#endif /* NOSPL */
-#endif /* NOSHOW */
-
-int x_ifnum = 0; /* Flag for IF NUMERIC active */
-
-#ifndef NOSPL
-/* Evaluate an arithmetic expression. */
-/* Code adapted from ev, by Howie Kaye of Columbia U & others. */
-
-static int xerror = 0;
-int divbyzero = 0;
-static char *cp;
-static CK_OFF_T tokval;
-static char curtok;
-static CK_OFF_T expval;
-
-#define LONGBITS (8*sizeof (CK_OFF_T))
-#define NUMBER 'N'
-#define N_EOT 'E'
-
-/*
- Replacement for strchr() and index(), neither of which seem to be universal.
-*/
-
-static char *
-#ifdef CK_ANSIC
-windex(char * s, char c)
-#else
-windex(s,c) char *s, c;
-#endif /* CK_ANSIC */
-/* windex */ {
- while (*s != NUL && *s != c) s++;
- if (*s == c) return(s); else return(NULL);
-}
-
-
-/*
- g e t t o k
-
- Returns the next token. If token is a NUMBER, sets tokval appropriately.
-*/
-static char
-gettok() {
- char tbuf[80] /* ,*tp */ ; /* Buffer to accumulate number */
-
- while (isspace(*cp)) /* Skip past leading spaces */
- cp++;
-
- debug(F110,"GETTOK",cp,0);
-
- switch (*cp) {
- case '$': /* ??? */
- case '+': /* Add */
- case '-': /* Subtract or Negate */
- case '@': /* Greatest Common Divisor */
- case '*': /* Multiply */
- case '/': /* Divide */
- case '%': /* Modulus */
- case '<': /* Left shift */
- case '>': /* Right shift */
- case '&': /* And */
- case '|': /* Or */
- case '#': /* Exclusive Or */
- case '~': /* Not */
- case '^': /* Exponent */
- case '!': /* Factorial */
- case '(': /* Parens for grouping */
- case ')': return(*cp++); /* operator, just return it */
- case '\n':
- case '\0': return(N_EOT); /* End of line, return that */
- }
-#ifdef COMMENT
-/* This is the original code, which allows only integer numbers. */
-
- if (isxdigit(*cp)) { /* Digit, must be a number */
- int radix = 10; /* Default radix */
- for (tp = tbuf; isxdigit(*cp); cp++)
- *tp++ = (char) (isupper(*cp) ? tolower(*cp) : *cp);
- *tp = '\0'; /* End number */
- switch(isupper(*cp) ? tolower(*cp) : *cp) { /* Examine break char */
- case 'h':
- case 'x': radix = 16; cp++; break; /* if radix signifier... */
- case 'o':
- case 'q': radix = 8; cp++; break;
- case 't': radix = 2; cp++; break;
- }
- for (tp = tbuf, tokval = 0; *tp != '\0'; tp++) {
- int dig;
- dig = *tp - '0'; /* Convert number */
- if (dig > 10) dig -= 'a'-'0'-10;
- if (dig >= radix) {
- if (cmdlvl == 0 && !x_ifnum && !xerror)
- printf("?Invalid digit '%c' in number\n",*tp);
- xerror = 1;
- return(NUMBER);
- }
- tokval = radix*tokval + dig;
- }
- return(NUMBER);
- }
- if (cmdlvl == 0 && !x_ifnum && !xerror)
- printf("Invalid character '%c' in input\n",*cp);
- xerror = 1;
- cp++;
- return(gettok());
-#else
-/* This code allows non-numbers to be treated as macro names */
- {
- int i, x;
- char * s, * cp1;
- cp1 = cp;
- tp = tbuf;
- for (i = 0; i < 80; i++) {
- /* Look ahead to next break character */
- /* pretty much anything that is not in the switch() above. */
- if (isalpha(*cp) || isdigit(*cp) ||
- *cp == '_' || *cp == ':' || *cp == '.' ||
- *cp == '[' || *cp == ']' ||
- *cp == '{' || *cp == '}'
- )
- tbuf[i] = *cp++;
- else
- break;
- }
- if (i >= 80) {
- printf("Too long - \"%s\"\n", cp1);
- xerror = 1;
- cp++;
- return(gettok());
- }
- if (xerror) return(NUMBER);
-
- tbuf[i] = NUL;
- s = tbuf;
- if (!isdigit(tbuf[0])) {
- char * s2 = NULL;
- x = mxlook(mactab,tbuf,nmac);
- debug(F111,"gettok mxlook",tbuf,x);
- if (x < 0) {
- if (cmdlvl == 0 && !x_ifnum && !xerror)
- printf("Bad number - \"%s\"\n",tbuf);
- xerror = 1;
- cp++;
- return(gettok());
- }
- s2 = mactab[x].mval;
- if (!s2) s2 = "";
- if (*s2) s = s2;
- }
-#ifdef CKFLOAT
- x = isfloat(s,0);
-#else
- x = chknum(s);
-#endif /* CKFLOAT */
- if (x > 0) {
- tokval = ckatofs(s);
- } else {
- if (cmdlvl == 0 && !x_ifnum && !xerror)
- printf("Bad number - \"%s\"\n",tbuf);
- xerror = 1;
- cp++;
- return(gettok());
- }
- return(NUMBER);
- }
-#endif /* COMMENT */
-}
-
-static CK_OFF_T
-#ifdef CK_ANSIC
-expon(CK_OFF_T x, CK_OFF_T y)
-#else
-expon(x,y) CK_OFF_T x,y;
-#endif /* CK_ANSIC */
-/* expon */ {
- CK_OFF_T result = 1;
- int sign = 1;
- if (y < 0) return(0);
- if (x < 0) {
- x = -x;
- if (y & 1) sign = -1;
- }
- while (y != 0) {
- if (y & 1) result *= x;
- y >>= 1;
- if (y != 0) x *= x;
- }
- return(result * sign);
-}
-
-/*
- * factor ::= simple | simple ^ factor
- *
- */
-static VOID
-factor() {
- CK_OFF_T oldval;
- simple();
- if (curtok == '^') {
- oldval = expval;
- curtok = gettok();
- factor();
- expval = expon(oldval,expval);
- }
-}
-
-/*
- * termp ::= NULL | {*,/,%,&} factor termp
- *
- */
-static VOID
-termp() {
- while (curtok == '*' || curtok == '/' || curtok == '%' || curtok == '&') {
- CK_OFF_T oldval;
- char op;
- op = curtok;
- curtok = gettok(); /* skip past operator */
- oldval = expval;
- factor();
- switch(op) {
- case '*': expval = oldval * expval; break;
- case '/':
- case '%':
- if (expval == 0) {
- if (!x_ifnum)
- printf("?Divide by zero\n");
- xerror = 1;
- divbyzero = 1;
- expval = -1;
- } else
- expval = (op == '/') ? (oldval / expval) : (oldval % expval);
- break;
- case '&':
- expval = oldval & expval; break;
- }
- }
-}
-
-static CK_OFF_T
-#ifdef CK_ANSIC
-fact(CK_OFF_T x)
-#else
-fact(x) CK_OFF_T x;
-#endif /* CK_ANSIC */
-/* fact */ { /* factorial */
- CK_OFF_T result = 1;
- while (x > 1)
- result *= x--;
- return(result);
-}
-
-/*
- * term ::= factor termp
- *
- */
-static VOID
-term() {
- factor();
- termp();
-}
-
-static CK_OFF_T
-#ifdef CK_ANSIC
-gcd(CK_OFF_T x, CK_OFF_T y)
-#else
-gcd(x,y) CK_OFF_T x,y;
-#endif /* CK_ANSIC */
-/* gcd */ { /* Greatest Common Divisor */
- int nshift = 0;
- if (x < 0) x = -x;
- if (y < 0) y = -y; /* validate arguments */
- if (x == 0 || y == 0) return(x + y); /* this is bogus */
-
- while (!((x & 1) | (y & 1))) { /* get rid of powers of 2 */
- nshift++;
- x >>= 1;
- y >>= 1;
- }
- while (x != 1 && y != 1 && x != 0 && y != 0) {
- while (!(x & 1)) x >>= 1; /* eliminate unnecessary */
- while (!(y & 1)) y >>= 1; /* powers of 2 */
- if (x < y) { /* force x to be larger */
- CK_OFF_T t;
- t = x;
- x = y;
- y = t;
- }
- x -= y;
- }
- if (x == 0 || y == 0) return((x + y) << nshift); /* gcd is non-zero one */
- else return((CK_OFF_T) 1 << nshift); /* else gcd is 1 */
-}
-
-/*
- * exprp ::= NULL | {+,-,|,...} term exprp
- *
- */
-static VOID
-exprp() {
- while (windex("+-|<>#@",curtok) != NULL) {
- CK_OFF_T oldval;
- char op;
- op = curtok;
- curtok = gettok(); /* skip past operator */
- oldval = expval;
- term();
- switch(op) {
- case '+' : expval = oldval + expval; break;
- case '-' : expval = oldval - expval; break;
- case '|' : expval = oldval | expval; break;
- case '#' : expval = oldval ^ expval; break;
- case '@' : expval = gcd(oldval,expval); break;
- case '<' : expval = oldval << expval; break;
- case '>' : expval = oldval >> expval; break;
- }
- }
-}
-
-/*
- * expr ::= term exprp
- *
- */
-static VOID
-expr() {
- term();
- exprp();
-}
-
-static CK_OFF_T
-xparse() {
- curtok = gettok();
- expr();
-#ifdef COMMENT
- if (curtok == '$') {
- curtok = gettok();
- if (curtok != NUMBER) {
- if (cmdlvl == 0 && !x_ifnum)
- printf("?Illegal radix\n");
- xerror = 1;
- return(0);
- }
- curtok = gettok();
- }
-#endif /* COMMENT */
- if (curtok != N_EOT) {
- if (cmdlvl == 0 && !x_ifnum && !xerror)
- printf("?Extra characters after expression\n");
- xerror = 1;
- }
- return(expval);
-}
-
-char * /* Silent front end for evala() */
-evalx(s) char *s; {
- char * p;
- int t;
- t = x_ifnum;
- x_ifnum = 1;
- p = evala(s);
- x_ifnum = t;
- return(p);
-}
-
-char *
-evala(s) char *s; {
- CK_OFF_T v; /* Numeric value */
- if (!s) return("");
- xerror = 0; /* Start out with no error */
- divbyzero = 0;
- cp = s; /* Make the argument global */
- v = xparse(); /* Parse the string */
- return(xerror ? "" : ckfstoa(v)); /* Return empty string on error */
-}
-
-/*
- * simplest ::= NUMBER | ( expr )
- *
- */
-static VOID
-simplest() {
- char * p;
- p = cp;
- if (curtok == NUMBER)
- expval = tokval;
- else if (curtok == '(') {
- curtok = gettok(); /* skip over paren */
- expr();
- if (curtok != ')') {
- if (cmdlvl == 0 && !x_ifnum && !xerror)
- printf("?Missing right parenthesis\n");
- xerror = 1;
- }
- debug(F110,"GETTOK SIMPLEST ()",p,0);
-
- } else {
- if (cmdlvl == 0 && !x_ifnum && !xerror)
- printf("?Operator unexpected\n");
- xerror = 1;
- }
- curtok = gettok();
-}
-
-/*
- * simpler ::= simplest | simplest !
- *
- */
-static VOID
-simpler() {
- simplest();
- if (curtok == '!') {
- curtok = gettok();
- expval = fact(expval);
- }
-}
-
-/*
- * simple ::= {-,~,!} simpler | simpler
- *
- */
-
-static VOID
-simple() {
- if (curtok == '-' || curtok == '~' || curtok == '!' || curtok == '+') {
- int op = curtok;
- curtok = gettok(); /* skip over - sign */
- simpler(); /* parse the factor again */
- if (op != '+')
- expval = (op == '-') ? -expval : ((op == '!') ? !expval : ~expval);
- } else simpler();
-}
-
-/* D C L A R R A Y -- Declare an array */
-/*
- Call with:
- char a = single character designator for the array, e.g. "a".
- int n = size of array. -1 means to undeclare the array.
- Returns:
- 0 or greater on success, having created the requested array with
- with n+1 elements, 0..n. If an array of the same name existed
- previously, it is destroyed. The new array has all its elements
- initialized to NULL pointers. When an array is successfully created,
- the return value is its index (0 = 'a', 1 = 'b', and so on.)
- -1 on failure (because 'a' out of range or malloc failure).
-*/
-int
-#ifdef CK_ANSIC
-dclarray(char a, int n)
-#else
-dclarray(a,n) char a; int n;
-#endif /* CK_ANSIC */
-/* dclarray */ {
- char c, **p; int i, n2, rc;
-
- if (a > 63 && a < 91) a += 32; /* Convert letters to lowercase */
- if (a < ARRAYBASE || a > 122) /* Verify name */
- return(-1);
-
- if (n < 0) /* Check arg */
- return(-1);
- if (n+1 < 0) /* MAXINT+1 wraps around */
- return(-1);
-
- c = a;
- a -= ARRAYBASE; /* Convert name to number */
- rc = a; /* Array index will be return code */
- if ((p = a_ptr[a]) != NULL) { /* Delete old array of same name */
- if (a_link[a] > -1) { /* Is it a link? */
- if (n == 0) { /* If we're just deleting it */
- a_ptr[a] = (char **) NULL; /* clear all the info. */
- a_dim[a] = 0;
- a_link[a] = -1;
- return(0);
- } /* Not deleting */
- a = a_link[a]; /* Switch to linked-to array */
- }
- n2 = a_dim[a]; /* Real array */
- for (i = 0; i <= n2; i++) { /* First delete its elements */
- if (p[i]) {
- free(p[i]);
- p[i] = NULL;
- }
- }
- free((char *)a_ptr[a]); /* Then the element list */
- if (n == 0) { /* If undeclaring this array... */
- for (i = 0; i < 122 - ARRAYBASE; i++) { /* Any linked arrays? */
- if (i != a && a_link[i] == a) { /* Find them */
- a_ptr[i] = (char **) NULL; /* and remove them */
- a_dim[i] = 0;
- a_link[i] = -1;
- }
- }
- }
- a_ptr[a] = (char **) NULL; /* Remove pointer to element list */
- a_dim[a] = 0; /* Set dimension at zero. */
- a_link[a] = -1; /* Unset link word */
- }
- if (n < 0) /* If only undeclaring, */
- return(0); /* we're done. */
- p = (char **) malloc((n+1) * sizeof(char **)); /* Allocate for new array */
- if (p == NULL) return(-1); /* Check */
- a_ptr[a] = p; /* Save pointer to member list */
- a_dim[a] = n; /* Save dimension */
- for (i = 0; i <= n; i++) /* Initialize members to null */
- p[i] = NULL;
- for (i = 0; i < (int) 'z' - ARRAYBASE; i++) { /* Any linked arrays? */
- if (i != a && a_link[i] == a) { /* Find and update them */
- a_ptr[i] = p;
- a_dim[i] = n;
- }
- }
- return(rc);
-}
-
-/* X A R R A Y -- Convert array name to array index */
-
-int
-xarray(s) char * s; {
- char buf[8];
- int x;
- char c;
-
- if (!s) s = "";
- debug(F110,"xarray",s,0);
- if (!*s)
- return(-1);
- x = strlen(s);
-
- buf[0] = NUL;
- buf[1] = NUL;
- buf[2] = s[0];
- buf[3] = (x > 0) ? s[1] : NUL;
- buf[4] = (x > 1) ? s[2] : NUL;
- buf[5] = (x > 2) ? s[3] : NUL;
- buf[6] = NUL;
- debug(F110,"xarray buf[3]",&buf[3],0);
- s = buf+2;
- if (*s == '&') {
- buf[1] = CMDQ;
- s--;
- } else if (*s != CMDQ) {
- buf[0] = CMDQ;
- buf[1] = '&';
- s = buf;
- }
- debug(F110,"xarray s",s,0);
- c = *(s+2);
- if (isupper(c))
- c = tolower(c);
- if (c == '@')
- c = 96;
- x = (int)c - ARRAYBASE;
- if (*(s+3) == '[')
- *(s+3) = NUL;
- if (x < 0) {
- return(-1);
- }
- if (x > ('z' - ARRAYBASE)) {
- debug(F101,"xarray x out of range","",x);
- return(-1);
- }
- if (*(s+3)) {
- debug(F110,"xarray syntax",s,0);
- return(-1);
- }
- return(x);
-}
-
-/*
- boundspair() -- parses blah[n:m]
-
- For use with array segment specifiers and compact substring notation.
- Ignores the "blah" part, gets the values of n and m, which can be
- numbers, variables, or arithmetic expressions; anything that resolves
- to a number.
-
- Call with:
- s - string to parse
- sep - array of permissible bounds separator chars
- lo - pointer to low-bound result (or -1)
- hi - pointer to hi-bound result (or -1)
- zz - pointer to separator char that was encountered (or NUL)
- Returns:
- -1 on failure
- 0 on success
-*/
-
-int
-#ifdef CK_ANSIC
-boundspair(char *s, char *sep, int *lo, int *hi, char *zz)
-#else
-boundspair(s,sep,lo,hi,zz) char *s, *sep, *zz; int *lo, *hi;
-#endif /* CK_ANSIC */
-{
- int i, x, y, range[2], bc = 0;
- char c = NUL, *s2 = NULL, buf[256], *p, *q, *r, *e[2], *tmp = NULL;
-
- debug(F110,"boundspair s",s,0);
- debug(F110,"boundspair sep",sep,0);
-
- *lo = -1; /* Default bounds */
- *hi = -1;
- *zz = 0; /* Default bounds separator */
-
- range[0] = -1; /* It's OK -- get contents */
- range[1] = -1; /* of subscript brackets */
- if (!s) s = "";
- if (!*s)
- return(-1);
- makestr(&tmp,s); /* Make a pokeable copy */
- p = tmp;
- q = NULL;
- r = NULL;
- for (p = s; *p; p++) { /* Get the two elements */
- if (*p == '[') {
- bc++; /* Bracket counter */
- if (bc == 1 && !q) q = p+1;
- } else if (*p == ']') {
- bc--;
- if (bc == 0 && q) *p = NUL;
- } else if (bc == 1) { /* If within brackers */
- s2 = ckstrchr(sep,*p); /* Check for separator */
- if (s2) {
- debug(F000,"boundspair *s2","",*s2);
- if (c) {
- debug(F000,"boundspair","Too many separators",*s2);
- makestr(&tmp,NULL);
- return(-1);
- }
- c = *s2; /* Separator character */
- *p = NUL;
- r = p+1;
- }
- }
- }
- if (bc == 0 && !q) {
- /* This allows such constructions as "show array a" */
- debug(F110,"boundspair","no brackets",0);
- makestr(&tmp,NULL);
- return(0);
- }
- if (bc != 0 || !q) {
- debug(F110,"boundspair","unbalanced or missing brackets",0);
- makestr(&tmp,NULL);
- return(-1);
- }
- if (!q) q = "";
- if (!*q) q = "-1";
- if (!r) r = "";
- if (!*r) r = "-1";
-
- e[0] = q;
- e[1] = r;
-
- debug(F000,"boundspair c","",c);
- debug(F110,"boundspair q",q,0);
- debug(F110,"boundspair r",r,0);
-
- for (i = 0; i < 2 && e[i]; i++) {
- y = 255; /* Expand variables, etc. */
- s = buf;
- zzstring(e[i],&s,&y);
- s = evalx(buf); /* Evaluate it arithmetically */
- if (s) if (*s)
- ckstrncpy(buf,s,256);
- if (!chknum(buf)) { /* Did we get a number? */
- debug(F110,"boundspair element not numeric",buf,0);
- makestr(&tmp,NULL); /* No, fail. */
- return(-1);
- }
- range[i] = atoi(buf);
- }
- makestr(&tmp,NULL); /* Free temporary poked string */
- *lo = range[0]; /* Return what we got */
- *hi = range[1];
- *zz = c;
- debug(F101,"boundspair lo","",*lo);
- debug(F101,"boundspair hi","",*hi);
- return(0);
-}
-
-/* A R R A Y B O U N D S -- Parse array segment notation \&a[n:m] */
-
-/*
- Call with s = array reference, plus two pointers to ints.
- Returns -1 on error, or array index, with the two ints set as follows:
- \&a[] -1, -1
- \&a[3] 3, -1
- \&a[3:17] 3, 17
- The array need not be declared -- this routine is just for parsing.
-*/
-int
-arraybounds(s,lo,hi) char * s; int * lo, * hi; {
- int i, x, y, range[2];
- char zz, buf[256], * p, * q;
- char * tmp = NULL;
-
- *lo = -1; /* Default bounds */
- *hi = -1;
-
- if (!s) s = ""; /* Defense de null args */
- if (!*s)
- return(-1);
-
- x = xarray(s); /* Check basic structure */
- debug(F111,"arraybounds xarray",s,x);
- if (x < 0) /* Not OK, fail. */
- return(-1);
- y = boundspair(s,":",lo,hi,&zz);
- debug(F111,"arraybounds boundspair",s,y);
- debug(F101,"arraybounds lo","",*lo);
- debug(F101,"arraybounds hi","",*hi);
- if (y < 0) /* Get bounds */
- return(-1);
- return(x);
-}
-
-/* A R R A Y N A M -- Parse an array name */
-
-/*
- Call with pointer to string that starts with the array reference.
- String may begin with either \& or just &.
- On success,
- Returns letter ID (always lowercase) in argument c,
- which can also be accent grave (` = 96; '@' is converted to grave);
- Dimension or subscript in argument n;
- IMPORTANT: These arguments must be provided by the caller as addresses
- of ints (not chars), for example:
- char *s; int x, y;
- arraynam(s,&x,&y);
- On failure, returns a negative number, with args n and c set to zero.
-*/
-int
-arraynam(ss,c,n) char *ss; int *c; int *n; {
- int i, y, pp, len;
- char x;
- char *s, *p, *sx, *vnp;
- /* On stack to allow for recursive calls... */
- char vnbuf[ARRAYREFLEN+1]; /* Entire array reference */
- char ssbuf[ARRAYREFLEN+1]; /* Subscript in "plain text" */
- char sxbuf[16]; /* Evaluated subscript */
-
- *c = *n = 0; /* Initialize return values */
- len = strlen(ss);
- for (pp = 0,i = 0; i < len; i++) { /* Check length */
- if (ss[i] == '[') {
- pp++;
- } else if (ss[i] == ']') {
- if (--pp == 0)
- break;
- }
- }
- if (i > ARRAYREFLEN) {
- printf("?Array reference too long - %s\n",ss);
- return(-9);
- }
- ckstrncpy(vnbuf,ss,ARRAYREFLEN);
- vnp = vnbuf;
- if (vnbuf[0] == CMDQ && vnbuf[1] == '&') vnp++;
- if (*vnp != '&') {
- printf("?Not an array - %s\n",vnbuf);
- return(-9);
- }
- x = *(vnp + 1); /* Fold case of array name */
-
- /* We don't use isupper & tolower here on purpose because these */
- /* would produce undesired effects with accented letters. */
- if (x > 63 && x < 91) x = *(vnp + 1) = (char) (x + 32);
- if ((x < ARRAYBASE) || (x > 122) || (*(vnp+2) != '[')) {
- if (msgflg) {
- printf("?Invalid format for array name - %s\n",vnbuf);
- return(-9);
- } else
- return(-2);
- }
- *c = x; /* Return the array name */
- s = vnp+3; /* Get dimension */
- p = ssbuf;
- pp = 1; /* Bracket counter */
- for (i = 0; i < ARRAYREFLEN && *s != NUL; i++) { /* Copy up to ] */
- if (*s == '[') pp++;
- if (*s == ']' && --pp == 0) break;
- *p++ = *s++;
- }
- if (*s != ']') {
- printf("?No closing bracket on array dimension - %s\n",vnbuf);
- return(-9);
- }
- p--; /* Trim whitespace from end */
- while (*p == SP || *p == HT)
- p--;
- p++;
- *p = NUL; /* Terminate subscript with null */
- p = ssbuf; /* Point to beginning of subscript */
- while (*p == SP || *p == HT) /* Trim whitespace from beginning */
- p++;
- sx = sxbuf; /* Where to put expanded subscript */
- y = 16;
- {
- /* Even if VARIABLE-EVALUATION SIMPLE use RECURSIVE for subscripts */
- /* NOTE: This is vulnerable to SIGINT and whatnot... */
- int tmp = vareval; /* Save VARIABLE-EVALUATION setting */
- vareval = 1; /* Force it to RECURSIVE */
- zzstring(p,&sx,&y); /* Convert variables, etc. */
- vareval = tmp; /* Restore VARIABLE-EVALUATION */
- }
- sx = sxbuf;
- while (*sx == SP) sx++;
- /* debug(F110,"arraynam sx","",sx); */
- if (!*sx) { /* Empty brackets... */
- *n = -17; /* (Secret code :-) */
- return(-2);
- }
- p = evala(sx); /* Run it thru \fneval()... */
- if (p) if (*p) ckstrncpy(sxbuf,p,16); /* We know it has to be a number. */
-
- if (!chknum(sxbuf)) { /* Make sure it's all digits */
- if (msgflg) {
- printf("?Array dimension or subscript missing or not numeric\n");
- return(-9);
- } else
- return(-2);
- }
- if ((y = atoi(sxbuf)) < 0) {
- if (cmflgs == 0) printf("\n");
- if (msgflg) {
- printf("?Array dimension or subscript not positive or zero\n");
- return(-9);
- } else
- return(-2);
- }
- *n = y; /* Return the subscript or dimension */
- return(0);
-}
-
-/* chkarray returns 0 or greater if array exists, negative otherwise */
-
-int
-chkarray(a,i) int a, i; { /* Check if array is declared */
- int x; /* and if subscript is in range */
- if (a == 64) a = 96; /* Convert atsign to grave accent */
- x = a - ARRAYBASE; /* Values must be in range 95-122 */
-#ifdef COMMENT
- if (x == 0 && maclvl < 0) /* Macro arg vector but no macro */
- return(0);
-#endif /* COMMENT */
- if (x < 0 || x > 'z' - ARRAYBASE) /* Not in range */
- return(-2);
- if (a_ptr[x] == NULL) return(-1); /* Not declared */
- if (i > a_dim[x]) return(-2); /* Declared but out of range. */
- return(a_dim[x]); /* All ok, return dimension */
-}
-
-#ifdef COMMENT /* This isn't used. */
-char *
-arrayval(a,i) int a, i; { /* Return value of \&a[i] */
- int x; char **p; /* (possibly NULL) */
- if (a == 64) a = 96; /* Convert atsign to grave accent */
- x = a - ARRAYBASE; /* Values must be in range 95-122 */
- if (x < 0 || x > 27) return(NULL); /* Not in range */
- if ((x > 0) && (p = a_ptr[x]) == NULL) /* Array not declared */
- return(NULL);
- if (i > a_dim[x]) /* Subscript out of range. */
- return(NULL);
- return(p[i]); /* All ok, return pointer to value. */
-}
-#endif /* COMMENT */
-
-/*
- pusharray() is called when an array name is included in a LOCAL statement.
- It moves the pointers from the global definition to the stack, and removes
- the global definition. Later, if the same array is declared in the local
- context, it occupies the global definition in the normal way. But when
- popclvl() is called, it replaces the global definition with the one saved
- here. The "secret code" is used to indicate to popclv() that it should
- remove the global array when popping through this level -- otherwise if a
- local array were declared that had no counterpart at any higher level, it
- would never be deleted. This allows Algol-like inheritance to work both
- on the way down and on the way back up.
-*/
-int
-pusharray(x,z) int x, z; {
- int y;
- debug(F000,"pusharray x","",x);
- debug(F101,"pusharray z","",z);
- y = chkarray(x,z);
- debug(F101,"pusharray y","",y);
- x -= ARRAYBASE; /* Convert name letter to index. */
- if (x < 0 || x > 27)
- return(-1);
- if (y < 0) {
- aa_ptr[cmdlvl][x] = (char **) NULL;
- aa_dim[cmdlvl][x] = -23; /* Secret code (see popclvl()) */
- } else {
- aa_ptr[cmdlvl][x] = a_ptr[x];
- aa_dim[cmdlvl][x] = y;
- }
- a_ptr[x] = (char **) NULL;
- a_dim[x] = 0;
- return(0);
-}
-
-/* P A R S E V A R -- Parse a variable name or array reference. */
-/*
- Call with:
- s = pointer to candidate variable name or array reference.
- *c = address of integer in which to return variable ID.
- *i = address of integer in which to return array subscript.
- Returns:
- -2: syntax error in variable name or array reference.
- 1: successful parse of a simple variable, with ID in c.
- 2: successful parse of an array reference, w/ID in c and subscript in i.
-*/
-int
-parsevar(s,c,i) char *s; int *c, *i; {
- char *p;
- int x,y,z;
-
- p = s;
- if (*s == CMDQ) s++; /* Point after backslash */
-
- if (*s != '%' && *s != '&') { /* Make sure it's % or & */
- printf("?Not a variable name - %s\n",p);
- return(-9);
- }
- if ((int)strlen(s) < 2) {
- printf("?Incomplete variable name - %s\n",p);
- return(-9);
- }
- if (*s == '%' && *(s+2) != '\0') {
- printf("?Only one character after '%%' in variable name, please\n");
- return(-9);
- }
- if (*s == '&' && *(s+2) != '[') {
- printf("?Array subscript expected - %s\n",p);
- return(-9);
- }
- if (*s == '%') { /* Simple variable. */
- y = *(s+1); /* Get variable ID letter/char */
- if (isupper(y)) y -= ('a'-'A'); /* Convert upper to lower case */
- *c = y; /* Set the return values. */
- *i = -1; /* No array subscript. */
- return(1); /* Return 1 = simple variable */
- }
- if (*s == '&') { /* Array reference. */
- y = arraynam(s,&x,&z); /* Go parse it. */
- debug(F101,"parsevar arraynam","",y);
- if ((y) < 0) {
- if (y == -2)
- return(pusharray(x,z));
- if (y != -9)
- printf("?Invalid array reference - %s\n",p);
- return(-9);
- }
- if (chkarray(x,z) < 0) { /* Check if declared, etc. */
- printf("?Array not declared or subscript out of range\n");
- return(-9);
- }
- *c = x; /* Return array letter */
- *i = z; /* and subscript. */
- return(2);
- }
- return(-2); /* None of the above. */
-}
-
-
-#define VALN 32
-
-/* Get the numeric value of a variable */
-/*
- Call with pointer to variable name, pointer to int for return value.
- Returns:
- 0 on success with second arg containing the value.
- -1 on failure (bad variable syntax, variable not defined or not numeric).
-*/
-int
-varval(s,v) char *s; CK_OFF_T *v; {
- char valbuf[VALN+1]; /* s is pointer to variable name */
- char name[256];
- char *p;
- int y;
-
- if (*s != CMDQ) { /* Handle macro names too */
- ckmakmsg(name,256,"\\m(",s,")",NULL);
- s = name;
- }
- p = valbuf; /* Expand variable into valbuf. */
- y = VALN;
- if (zzstring(s,&p,&y) < 0) return(-1);
- p = valbuf; /* Make sure value is numeric */
- if (!*p) { /* Be nice -- let an undefined */
- valbuf[0] = '0'; /* variable be treated as 0. */
- valbuf[1] = NUL;
- }
- if (chknum(p)) { /* Convert numeric string to int */
- *v = ckatofs(p); /* OK */
- } else { /* Not OK */
- p = evala(p); /* Maybe it's an expression */
- if (!chknum(p)) /* Did it evaluate? */
- return(-1); /* No, failure. */
- else /* Yes, */
- *v = ckatofs(p); /* success */
- }
- return(0);
-}
-
-/* Increment or decrement a variable */
-/* Returns -1 on failure, 0 on success */
-
-int
-incvar(s,x,z) char *s; CK_OFF_T x; int z; { /* Increment a numeric variable */
- CK_OFF_T n; /* s is pointer to variable name */
- /* x is amount to increment by */
- /* z != 0 means add */
- /* z = 0 means subtract */
- if (varval(s,&n) < 0) /* Convert numeric string to int */
- return(-1);
- if (z) /* Increment it by the given amount */
- n += x;
- else /* or decrement as requested. */
- n -= x;
- addmac(s,ckfstoa(n)); /* Replace old variable */
- return(0);
-}
-
-/* D O D O -- Do a macro */
-
-/*
- Call with x = macro table index, s = pointer to arguments.
- Returns 0 on failure, 1 on success.
-*/
-
-int
-dodo(x,s,flags) int x; char *s; int flags; {
- int y;
- extern int tra_asg, tra_cmd; int tra_tmp;
-#ifndef NOLOCAL
-#ifdef OS2
- extern int term_io;
- int term_io_sav = term_io;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
- if (x < 0) /* It can happen! */
- return(-1);
-
- tra_tmp = tra_asg;
-
- if (++maclvl >= MACLEVEL) { /* Make sure we have storage */
- debug(F101,"dodo maclvl too deep","",maclvl);
- --maclvl;
- printf("Macros nested too deeply\n");
- return(0);
- }
- macp[maclvl] = mactab[x].mval; /* Point to the macro body */
- macx[maclvl] = mactab[x].mval; /* Remember where the beginning is */
-
-#ifdef COMMENT
- makestr(&(m_line[maclvl]),s); /* Entire arg string for "\%*" */
-#endif /* COMMENT */
-
- cmdlvl++; /* Entering a new command level */
- if (cmdlvl >= CMDSTKL) { /* Too many macros + TAKE files? */
- debug(F101,"dodo cmdlvl too deep","",cmdlvl);
- cmdlvl--;
- printf("?TAKE files and DO commands nested too deeply\n");
- return(0);
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"CMD +M",mactab[x].kwd,cmdlvl);
- debug(F010,"CMD ->",s,0);
- }
-#endif /* DEBUG */
-
-#ifdef VMS
- conres(); /* So Ctrl-C, etc, will work. */
-#endif /* VMS */
-#ifndef NOLOCAL
-#ifdef OS2
- term_io = 0; /* Disable terminal emulator I/O */
-#endif /* OS2 */
-#endif /* NOLOCAL */
- ifcmd[cmdlvl] = 0;
- iftest[cmdlvl] = 0;
- count[cmdlvl] = count[cmdlvl-1]; /* Inherit COUNT from previous level */
- intime[cmdlvl] = intime[cmdlvl-1]; /* Inherit previous INPUT TIMEOUT */
- inpcas[cmdlvl] = inpcas[cmdlvl-1]; /* and INPUT CASE */
- takerr[cmdlvl] = takerr[cmdlvl-1]; /* and TAKE ERROR */
- merror[cmdlvl] = merror[cmdlvl-1]; /* and MACRO ERROR */
- xquiet[cmdlvl] = quiet;
- xvarev[cmdlvl] = vareval;
- xcmdsrc = CMD_MD;
- cmdstk[cmdlvl].src = CMD_MD; /* Say we're in a macro */
- cmdstk[cmdlvl].lvl = maclvl; /* and remember the macro level */
- cmdstk[cmdlvl].ccflgs = flags & ~CF_IMAC; /* Set flags */
-
- /* Initialize return value except in FOR, WHILE, IF, and SWITCH macros */
-
- if (!(flags & CF_IMAC) && mrval[maclvl]) {
- free(mrval[maclvl]);
- mrval[maclvl] = NULL;
- }
-
- /* Clear old %0..%9 arguments */
-
- addmac("%0",mactab[x].kwd); /* Define %0 = name of macro */
- makestr(&(m_xarg[maclvl][0]),mactab[x].kwd);
- varnam[0] = '%';
- varnam[2] = '\0';
- tra_asg = 0;
- for (y = 1; y < 10; y++) { /* Clear args %1..%9 */
- if (m_arg[maclvl][y]) { /* Don't call delmac() unless */
- varnam[1] = (char) (y + '0'); /* we have to... */
- delmac(varnam,0);
- }
- }
- tra_asg = tra_tmp;
-
-/* Assign the new args one word per arg, allowing braces to group words */
-
- xwords(s,MAXARGLIST,NULL,0);
-
-#ifndef NOLOCAL
-#ifdef OS2
- term_io = term_io_sav;
-#endif /* OS2 */
-#endif /* NOLOCAL */
- if (tra_cmd)
- printf("[%d] +M: \"%s\"\n",cmdlvl,mactab[x].kwd);
- return(1);
-}
-
-/* Insert "literal" quote around each comma-separated command to prevent */
-/* its premature expansion. Only do this if object command is surrounded */
-/* by braces. */
-
-static char* flit = "\\flit(";
-
-int
-litcmd(src,dest,n) char **src, **dest; int n; {
- int bc = 0, pp = 0;
- char c, *s, *lp, *ss;
-
- s = *src;
- lp = *dest;
-
- debug(F010,"litcmd",s,0);
-
- while (*s == SP) s++; /* Strip extra leading spaces */
-
- if (*s == '{') { /* Starts with brace */
- pp = 0; /* Paren counter */
- bc = 1; /* Count leading brace */
- *lp++ = *s++; /* Copy it */
- if (--n < 1) return(-1); /* Check space */
- while (*s == SP) s++; /* Strip interior leading spaces */
- ss = flit; /* Point to "\flit(" */
- while ((*lp++ = *ss++)) /* Copy it */
- if (--n < 1) /* and check space */
- return(-1);
- lp--; /* Back up over null */
-
- while (*s) { /* Go thru rest of text */
- c = *s;
- if (c == '{') bc++; /* Count brackets */
- if (c == '(') pp++; /* and parens */
- if (c == ')') { /* Right parenthesis. */
- pp--; /* Count it. */
- if (pp < 0) { /* An unbalanced right paren... */
-#ifdef COMMENT
-/*
- The problem here is that "\{" appears to be a quoted brace and therefore
- isn't counted; then the "}" matches an earlier opening brace, causing
- (e.g.) truncation of macros by getncm().
-*/
- if (n < 5) /* Out of space in dest buffer? */
- return(-1); /* If so, give up. */
- *lp++ = CMDQ; /* Must be quoted to prevent */
- *lp++ = '}'; /* premature termination of */
- *lp++ = '4'; /* \flit(...) */
- *lp++ = '1';
- *lp++ = '}';
- n -= 5;
-#else
-/* Here we rely on the fact the \nnn never takes more than 3 digits */
- if (n < 4) /* Out of space in dest buffer? */
- return(-1); /* If so, give up. */
- *lp++ = CMDQ; /* Must be quoted to prevent */
- *lp++ = '0'; /* premature termination of */
- *lp++ = '4'; /* \flit(...) */
- *lp++ = '1';
- n -= 4;
-#endif /* COMMENT */
- pp++; /* Uncount it. */
- s++;
- continue;
- }
- }
- if (c == '}') { /* Closing brace. */
- if (--bc == 0) { /* Final one? */
- *lp++ = ')'; /* Add closing paren for "\flit()" */
- if (--n < 1) return(-1);
- *lp++ = c;
- if (--n < 1) return(-1);
- s++;
- break;
- }
- }
- *lp++ = c; /* General case */
- if (--n < 1) return(-1);
- s++;
- }
- *lp = NUL;
- } else { /* No brackets around, */
- while ((*lp++ = *s++)) /* just copy. */
- if (--n < 1)
- return(-1);
- lp--;
- }
- *src = s; /* Return updated source */
- *dest = lp; /* and destination pointers */
- if (bc) /* Fail if braces unbalanced */
- return(-1);
- else /* Otherwise succeed. */
- return(0);
-}
-#endif /* NOSPL */
-
-/* Functions moved here from ckuusr.c to even out the module sizes... */
-
-/*
- Breaks up string s -- IN PLACE! -- into a list of up to max words.
- Pointers to each word go into the array list[].
- max is the maximum number of words (pointers).
- If list is NULL, then they are added to the macro table.
- flag = 0 means the last field is to be one word, like all the other fields,
- so anything after it is discarded.
- flag = 1 means the last field extends to the end of the string, even if
- there are lots of words left, so the last field contains the
- remainder of the string.
-*/
-VOID
-xwords(s,max,list,flag) char *s; int max; char *list[]; int flag; {
- char *p;
- int b, i, k, q, y, z;
-#ifndef NOSPL
- int macro;
- macro = (list == NULL);
- debug(F010,"xwords",s,0);
-#endif /* NOSPL */
-
-#ifdef XWORDSDEBUG
- printf("XWORDS string=%s\n",s);
- printf("XWORDS max=%d\n",max);
-#endif /* XWORDSDEBUG */
- p = s; /* Pointer to beginning of string */
- q = 0; /* Flag for doublequote removal */
- b = 0; /* Flag for outer brace removal */
- k = 0; /* Flag for in-word */
- y = 0; /* Brace nesting level */
- z = 0; /* "Word" counter, 0 thru max */
-
- if (list)
- for (i = 0; i <= max; i++) /* Initialize pointers */
- list[i] = NULL;
-
- if (flag) max--;
-
- while (1) { /* Go thru word list */
- if (!s || (*s == '\0')) { /* No more characters? */
- if (k != 0) { /* Was I in a word? */
- if (z == max) break; /* Yes, only go up to max. */
- z++; /* Count this word. */
-#ifdef XWORDSDEBUG
- printf("1 z++ = %d\n", z);
-#endif /* XWORDSDEBUG */
-#ifndef NOSPL
- if (macro) { /* Doing macro args */
- if (z < 10) {
- varnam[1] = (char) (z + '0'); /* Assign last arg */
- addmac(varnam,p);
- }
- if (z <= max) {
-#ifdef COMMENT
- if (maclvl < 0)
- addmac(varnam,p);
- else
-#endif /* COMMENT */
- makestr(&(m_xarg[maclvl][z]),p);
- }
- } else { /* Not doing macro args */
-#endif /* NOSPL */
- list[z] = p; /* Assign pointer. */
-#ifdef XWORDSDEBUG
- printf("[1]LIST[%d]=\"%s\"\n",z,list[z]);
-#endif /* XWORDSDEBUG */
-#ifndef NOSPL
- }
-#endif /* NOSPL */
- break; /* And get out. */
- } else break; /* Was not in a word */
- }
- if (k == 0 && (*s == SP || *s == HT)) { /* Eat leading blanks */
- s++;
- continue;
- } else if (q == 0 && *s == '{') { /* An opening brace */
- if (k == 0 && y == 0) { /* If leading brace */
- p = s+1; /* point past it */
- b = 1; /* and flag that we did this */
- }
- k = 1; /* Flag that we're in a word */
- y++; /* Count the brace. */
- } else if (q == 0 && *s == '}') { /* A closing brace. */
- y--; /* Count it. */
- if (y <= 0 && b != 0) { /* If it matches the leading brace */
- char c;
- c = *(s+1);
- if (!c || c == SP || c == HT) { /* at EOL or followed by SP */
- *s = SP; /* change it to a space */
- b = 0; /* and we're not in braces any more */
- }
- }
-#ifdef DOUBLEQUOTING
- /* Opening doublequote */
- } else if (k == 0 && b == 0 && *s == '"' && dblquo) {
- y++;
- p = s+1; /* point past it */
- q = 1; /* and flag that we did this */
- k = 1; /* Flag that we're in a word */
- /* Closing double quote */
- } else if (q > 0 && k > 0 && b == 0 && *s == '"' && dblquo) {
- char c;
- c = *(s+1);
- if (!c || c == SP || c == HT) { /* at EOL or followed by SP */
- y--;
- *s = SP; /* change it to a space */
- q = 0; /* and we're not in quotes any more */
- }
-#endif /* DOUBLEQUOTING */
-
- } else if (*s != SP && *s != HT) { /* Nonspace means we're in a word */
- if (k == 0) { /* If we weren't in a word before, */
- p = s; /* Mark the beginning */
- if (flag && z == max) { /* Want last word to be remainder? */
- z++;
-#ifdef XWORDSDEBUG
- printf("1 z++ = %d\n", z);
-#endif /* XWORDSDEBUG */
- list[z] = p; /* Yes, point to it */
-#ifdef XWORDSDEBUG
- printf("[4]LIST[%d]=\"%s\"\n",z,list[z]);
-#endif /* XWORDSDEBUG */
- break; /* and quit */
- }
- k = 1; /* Set in-word flag */
- }
- }
- /* If we're not inside a braced quantity, and we are in a word, and */
- /* we have hit whitespace, then we have a word. */
- if ((y < 1) && (k != 0) && (*s == SP || *s == HT) && !b) {
- if (!flag || z < max) /* if we don't want to keep rest */
- *s = '\0'; /* terminate the arg with null */
- k = 0; /* say we're not in a word any more */
- y = 0; /* start braces off clean again */
- if (z == max) break; /* Only go up to max. */
- z++; /* count this arg */
-#ifdef XWORDSDEBUG
- printf("1 z++ = %d\n", z);
-#endif /* XWORDSDEBUG */
-
-#ifndef NOSPL
- if (macro) {
- if (z < 10) {
- varnam[1] = (char) (z + '0'); /* compute its name */
- addmac(varnam,p); /* add it to the macro table */
- }
- if (z <= max) {
-#ifdef COMMENT
- if (maclvl < 0)
- addmac(varnam,p);
- else
-#endif /* COMMENT */
- makestr(&(m_xarg[maclvl][z]),p);
- }
- } else {
-#endif /* NOSPL */
- list[z] = p;
-#ifdef XWORDSDEBUG
- printf("[2]LIST[%d]=\"%s\"\n",z,list[z]);
-#endif /* XWORDSDEBUG */
-#ifndef NOSPL
- }
-#endif /* NOSPL */
- p = s+1;
- }
- s++; /* Point past this character */
- }
- if ((z == 0) && (y > 1)) { /* Extra closing brace(s) at end */
- z++;
-#ifndef NOSPL
- if (macro) {
- if (z < 10) {
- varnam[1] = z + '0'; /* compute its name */
- addmac(varnam,p); /* Add rest of line to last arg */
- }
- if (z <= max) {
-#ifdef COMMENT
- if (maclvl < 0)
- addmac(varnam,p);
- else
-#endif /* COMMENT */
- makestr(&(m_xarg[maclvl][z]),p);
- }
- } else {
-#endif /* NOSPL */
- list[z] = p;
-#ifdef XWORDSDEBUG
- printf("[3]LIST[%d]=\"%s\"\n",z,list[z]);
-#endif /* XWORDSDEBUG */
-#ifndef NOSPL
- }
-#endif /* NOSPL */
- }
-#ifndef NOSPL
- if (macro) { /* Macro */
- if (maclvl < 0) {
- a_dim[0] = z; /* Array dimension is one less */
- topargc = z + 1; /* than \v(argc) */
- debug(F111,"a_dim[0]","D",a_dim[0]);
- } else {
- macargc[maclvl] = z + 1; /* Set \v(argc) variable */
- n_xarg[maclvl] = z + 1; /* This is the actual number */
- a_ptr[0] = m_xarg[maclvl]; /* Point \&_[] at the args */
- a_dim[0] = z; /* And give it this dimension */
- debug(F111,"a_dim[0]","E",a_dim[0]);
- }
- }
-#endif /* NOSPL */
- return;
-}
-
-#ifndef NOSPL
-
-/* D O S H I F T -- Do the SHIFT Command; shift macro args left by n */
-
-/* Note: at some point let's consolidate m_arg[][] and m_xarg[][]. */
-
-int
-doshift(n) int n; { /* n = shift count */
- int i, top, level;
- char /* *s, *m, */ buf[6]; /* Buffer to build scalar names */
- char * sx = tmpbuf;
- int nx = TMPBUFSIZ;
-
- debug(F101,"SHIFT count","",n);
- debug(F101,"SHIFT topargc","",topargc);
-
- if (n < 1) /* Stay in range */
- return(n == 0 ? 1 : 0);
-
- level = maclvl;
- top = (level < 0) ? topargc : macargc[level];
-
- if (n >= top)
- n = top - 1;
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"SHIFT count 2","",n);
- debug(F101,"SHIFT level","",level);
- if (level > -1)
- debug(F101,"SHIFT macargc[level]","",macargc[level]);
- }
-#endif /* DEBUG */
-
- buf[0] = '\\'; /* Initialize name template */
- buf[1] = '%';
- buf[2] = NUL;
- buf[3] = NUL;
-
- for (i = 1; i <= n; i++) { /* Free shifted-over args */
- if (level < 0) {
- makestr(&(toparg[i]),NULL);
- } else {
- makestr(&(m_xarg[level][i]),NULL);
- }
- if (i < 10) { /* Is this necessary? */
- buf[2] = (char)(i+'0');
- delmac(buf,0);
- }
- }
- for (i = 1; i <= top-n; i++) { /* Shift remaining args */
- if (level < 0) {
-#ifdef COMMENT
- toparg[i] = toparg[i+n]; /* Full vector */
-#else
- makestr(&(toparg[i]),toparg[i+n]); /* Full vector */
-#endif /* COMMENT */
- if (i < 10) /* Scalars... */
- makestr(&(g_var[i+'0']),toparg[i+n]);
- } else {
-#ifdef COMMENT
- m_xarg[level][i] = m_xarg[level][i+n];
-#else
- makestr(&(m_xarg[level][i]),m_xarg[level][i+n]);
-#endif /* COMMENT */
- if (i < 10) {
- buf[2] = (char)(i+'0');
- debug(F010,"SHIFT buf",buf,0);
- addmac(buf,m_xarg[level][i+n]);
- }
- }
- }
- for (i = top-n; i <= top; i++) { /* Clear n args from the end */
- if (level < 0) {
-#ifdef COMMENT
- toparg[i] = NULL;
-#else
- makestr(&(toparg[i]),NULL);
-#endif /* COMMENt */
- if (i < 10)
- makestr(&(g_var[i+'0']),NULL);
- } else {
-#ifdef COMMENT
- m_xarg[level][i] = NULL;
-#else
- makestr(&(m_xarg[level][i]),NULL);
-#endif /* COMMENt */
- if (i < 10) {
- buf[2] = (char)(i+'0');
- delmac(buf,0);
- }
- }
- }
- if (level > -1) { /* Macro args */
- macargc[level] -= n; /* Adjust count */
- n_xarg[maclvl] = macargc[level]; /* Here too */
- a_dim[0] = macargc[level] - 1; /* Adjust array dimension */
- debug(F111,"a_dim[0]","F",a_dim[0]);
- zzstring("\\fjoin(&_[],{ },1)",&sx,&nx); /* Handle \%* */
-#ifdef COMMENT
- makestr(&(m_line[level]),tmpbuf);
-#endif /* COMMENT */
- } else { /* Ditto for top level */
- topargc -= n;
- a_dim[0] = topargc - 1;
- debug(F111,"a_dim[0]","G",a_dim[0]);
- zzstring("\\fjoin(&_[],{ },1)",&sx,&nx);
-#ifdef COMMENT
- makestr(&topline,tmpbuf);
-#endif /* COMMENT */
- }
- return(1);
-}
-#endif /* NOSPL */
-
-int
-docd(cx) int cx; { /* Do the CD command */
- int x;
- extern int server, srvcdmsg, cdactive;
- extern char * cdmsgfile[], * ckcdpath;
- char *s, *p;
-#ifdef MAC
- char temp[34];
-#endif /* MAC */
-#ifdef IKSDCONF
-extern int iksdcf;
-#endif /* IKSDCONF */
-
-#ifndef NOFRILLS
- if (cx == XXBACK) {
- if ((x = cmcfm()) < 0)
- cwdf = 1;
- if (prevdir) {
- s = zgtdir();
- if (!zchdir(prevdir)) {
- cwdf = 0;
- perror(s);
- } else {
- makestr(&prevdir,s);
- }
- }
- return(cwdf);
- }
-#endif /* NOFRILLS */
-
- if (cx == XXCDUP) {
-#ifdef VMS
- s = "[-]";
-#else
-#ifdef datageneral
- s = "^";
-#else
- s = "..";
-#endif /* datageneral */
-#endif /* VMS */
- ckstrncpy(line,s,LINBUFSIZ);
- goto gocd;
- }
-#ifndef NOSPL
- if (cx == XXKCD) { /* Symbolic (Kermit) CD */
- char * p;
- int n, k;
- x = cmkey(kcdtab,nkcdtab,"Symbolic directory name","home",xxstring);
- if (x < 0)
- return(x);
- x = lookup(kcdtab,atmbuf,nkcdtab,&k); /* Get complete keyword */
- if (x < 0) {
- printf("?Lookup error\n"); /* shouldn't happen */
- return(-9);
- }
- if ((x = cmcfm()) < 0)
- return(x);
- if (k == VN_HOME) { /* HOME: allow SET HOME to override */
- ckstrncpy(line,homepath(),LINBUFSIZ);
- } else { /* Other symbolic name */
- /* Convert to variable syntax */
- ckmakmsg(tmpbuf,TMPBUFSIZ,"\\v(",kcdtab[k].kwd,")",NULL);
- p = line; /* Expand the variable */
- n = LINBUFSIZ;
- zzstring(tmpbuf,&p,&n);
- if (!line[0]) { /* Fail if variable not defined */
- printf("?%s - not defined\n",tmpbuf);
- return(success = 0);
- }
- }
- s = line; /* All OK, go try to CD... */
- goto gocd;
- }
-#endif /* NOSPL */
-
- cdactive = 1;
-#ifdef GEMDOS
- if ((x = cmdir("Name of local directory, or carriage return",
- homepath(),
- &s,
- NULL
- )
- ) < 0 )
- return(x);
-#else
-#ifdef OS2
- if ((x = cmdirp("Name of PC disk and/or directory,\n\
- or press the Enter key for the default",
- homepath(),
- &s,
- ckcdpath ? ckcdpath : getenv("CDPATH"),
- xxstring
- )
- ) < 0 )
- return(x);
-#else
-#ifdef MAC
- x = ckstrncpy(temp,homepath(),32);
- if (x > 0) if (temp[x-1] != ':') { temp[x] = ':'; temp[x+1] = NUL; }
- if ((x = cmtxt("Name of Macintosh volume and/or folder,\n\
- or press the Return key for the desktop on the boot disk",
- temp,&s, xxstring)) < 0 )
- return(x);
-#else
- if ((x = cmdirp("Carriage return for home directory,\n\
-or name of directory on this computer",
-#ifdef VMS
- "SYS$LOGIN", /* With no colon */
-#else
- homepath(), /* In VMS this is "SYS$LOGIN:" */
-#endif /* VMS */
- &s,
- ckcdpath ? ckcdpath : getenv("CDPATH"),
- xxstring
- )) < 0)
- return(x);
-#endif /* MAC */
-#endif /* OS2 */
-#endif /* GEMDOS */
- ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
- s = line;
-#ifdef VMS
- if (ckmatch("*.DIR;1$",s,0,0))
- if (cvtdir(s,tmpbuf,TMPBUFSIZ) > 0)
- s = tmpbuf;
-#endif /* VMS */
- debug(F110,"docd",s,0);
-#ifndef MAC
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
-#endif /* MAC */
-
- gocd:
-
-#ifdef datageneral
- x = strlen(line); /* homdir ends in colon, */
- if (x > 1 && line[x-1] == ':') /* and "dir" doesn't like that... */
- line[x-1] = NUL;
-#endif /* datageneral */
-
-#ifdef MAC
- cwdf = 1;
- if (!zchdir(s)) {
- cwdf = 0;
- if (*s != ':') { /* If it failed, */
- char *p; /* supply leading colon */
- int len = (int)strlen(s) + 2;
- p = malloc(len); /* and try again... */
- if (p) {
- strcpy(p,":"); /* safe */
- strcat(p,s); /* safe */
- if (zchdir(p))
- cwdf = 1;
- free(p);
- p = NULL;
- }
- }
- }
- if (!cwdf)
- perror(s);
-#else
- p = zgtdir();
- if (!zchdir(s)) {
- cwdf = 0;
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off limits: \"%s\"\n",s);
- else
-#endif /* CKROOT */
- perror(s);
- } else cwdf = 1;
-#endif /* MAC */
-
- x = 0;
- if (cwdf) {
- makestr(&prevdir,p);
- debug(F111,"docd","srvcdmsg",srvcdmsg);
- if (srvcdmsg
-#ifdef IKSDCONF
- && !(inserver && !iksdcf)
-#endif /* IKSDCONF */
- ) {
- int i;
- for (i = 0; i < 8; i++) {
- debug(F111,"docd cdmsgfile[i]",cdmsgfile[i],i);
- if (zchki(cdmsgfile[i]) > -1) {
- x = 1;
- dotype(cdmsgfile[i],xaskmore,0,0,NULL,0,NULL,0,0,NULL,0);
- break;
- }
- }
- }
- }
-/* xdocd: */
- if (!x && srvcdmsg && !server
-#ifdef IKSDCONF
- && !(inserver && !iksdcf)
-#endif /* IKSDCONF */
- && !quiet && !xcmdsrc)
- printf("%s\n", zgtdir());
-
- return(cwdf);
-}
-
-static int on_ctrlc = 0;
-
-VOID
-fixcmd() { /* Fix command parser after interruption */
-#ifndef NOSPL
-#ifndef NOONCTRLC
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- char * s = "on_ctrlc"; /* Name of Ctrl-C handling macro */
- k = mlook(mactab,s,nmac); /* Look it up. */
- if (k >= 0) { /* If found, */
- if (on_ctrlc++ == 0) { /* if not already executing, */
- if (dodo(k,"",0) > -1) /* set it up, */
- parser(1); /* execute it, */
- }
- delmac(s,1); /* and undefine it. */
- }
- }
- on_ctrlc = 0;
-#endif /* NOONCTRLC */
-#endif /* NOSPL */
- dostop(); /* Back to top level (also calls conint()). */
- bgchk(); /* Check background status */
- if (*psave) { /* If old prompt saved, */
- cmsetp(psave); /* restore it. */
- *psave = NUL;
- }
- success = 0; /* Tell parser last command failed */
-}
-
-#ifndef NOSHOW /* SHOW FEATURES */
-/*
- Note, presently optlist[] index overflow is not checked.
- There is plenty of room (less than 360 entries for 1000 slots).
- When space starts to get tight, check for noptlist >= NOPTLIST
- every time noptlist is incremented.
-*/
-#define NOPTLIST 1024
-static int noptlist = 0;
-static char * optlist[NOPTLIST+1];
-static int hpos = 0;
-
-int
-prtopt(lines,s) int * lines; char *s; { /* Print an option */
- int y, i; /* Does word wrap. */
- if (!s) s = "";
- i = *lines;
- if (!*s) { /* Empty argument */
- if (hpos > 0) { /* means to end this line. */
- printf("\n"); /* Not needed if already at */
- if (++i > (cmd_rows - 3)) { /* beginning of new line. */
- if (!askmore())
- return(0);
- else
- i = 0;
- }
- }
- printf("\n"); /* And then make a blank line */
- if (++i > (cmd_rows - 3)) {
- if (!askmore())
- return(0);
- else
- i = 0;
- }
- hpos = 0;
- *lines = i;
- return(1);
- }
- y = (int)strlen(s) + 1;
- hpos += y;
- debug(F101,"prtopt hpos","",hpos);
- debug(F101,"prtopt cmd_cols","",cmd_cols);
-
- if (
-#ifdef OS2
- hpos > ((cmd_cols > 40) ? (cmd_cols - 1) : 79)
-#else /* OS2 */
- hpos > ((tt_cols > 40) ? (tt_cols - 1) : 79)
-#endif /* OS2 */
- ) {
- printf("\n");
- if (++i > (cmd_rows - 3)) {
- if (!askmore())
- return(0);
- else
- i = 0;
- }
- printf(" %s",s);
- hpos = y;
- } else
- printf(" %s",s);
- *lines = i;
- return(1);
-}
-
-static VOID
-initoptlist() {
- int i;
- if (noptlist > 0)
- return;
- for (i = 0; i < NOPTLIST; i++)
- optlist[i] = NULL;
-
-#ifdef MAC
-#ifdef MPW
- makestr(&(optlist[noptlist++]),"MPW");
-#endif /* MPW */
-#endif /* MAC */
-
-#ifdef MAC
-#ifdef THINK_C
- makestr(&(optlist[noptlist++]),"THINK_C");
-#endif /* THINK_C */
-#endif /* MAC */
-
-#ifdef __386__
- makestr(&(optlist[noptlist++]),"__386__");
-#endif /* __386__ */
-
-/* Memory models... */
-
-#ifdef __FLAT__
- makestr(&(optlist[noptlist++]),"__FLAT__");
-#endif /* __FLAT__ */
-#ifdef __SMALL__
- makestr(&(optlist[noptlist++]),"__SMALL__");
-#endif /* __SMALL__ */
-#ifdef __MEDIUM__
- makestr(&(optlist[noptlist++]),"__MEDIUM__");
-#endif /* __MEDIUM__ */
-#ifdef __COMPACT__
- makestr(&(optlist[noptlist++]),"__COMPACT__");
-#endif /* __COMPACT__ */
-#ifdef __LARGE__
- makestr(&(optlist[noptlist++]),"__LARGE__");
-#endif /* __LARGE__ */
-
-#ifdef DEBUG
-#ifdef IFDEBUG
- makestr(&(optlist[noptlist++]),"IFDEBUG");
-#else
- makestr(&(optlist[noptlist++]),"DEBUG");
-#endif /* IFDEBUG */
-#endif /* DEBUG */
-#ifdef TLOG
- makestr(&(optlist[noptlist++]),"TLOG");
-#endif /* TLOG */
-#ifdef BIGBUFOK
- makestr(&(optlist[noptlist++]),"BIGBUFOK");
-#endif /* BIGBUFOK */
-#ifdef INPBUFSIZ
- sprintf(line,"INPBUFSIZ=%d",INPBUFSIZ); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* INPBUFSIZE */
-#ifdef LINBUFSIZ
- sprintf(line,"LINBUFSIZ=%d",LINBUFSIZ); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* LINBUFSIZE */
-#ifdef INBUFSIZE
- sprintf(line,"INBUFSIZE=%d",INBUFSIZE); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* INBUFSIZE */
-#ifdef OBUFSIZE
- sprintf(line,"OBUFSIZE=%d",OBUFSIZE); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* OBUFSIZE */
-#ifdef FD_SETSIZE
- sprintf(line,"FD_SETSIZE=%d",FD_SETSIZE); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* FD_SETSIZE */
-#ifdef XFRCAN
- makestr(&(optlist[noptlist++]),"XFRCAN");
-#endif /* XFRCAN */
-#ifdef XPRINT
- makestr(&(optlist[noptlist++]),"XPRINT");
-#endif /* XPRINT */
-#ifdef PIPESEND
- makestr(&(optlist[noptlist++]),"PIPESEND");
-#endif /* PIPESEND */
-#ifdef CK_SPEED
- makestr(&(optlist[noptlist++]),"CK_SPEED");
-#endif /* CK_SPEED */
-#ifdef CK_FAST
- makestr(&(optlist[noptlist++]),"CK_FAST");
-#endif /* CK_FAST */
-#ifdef CK_APC
- makestr(&(optlist[noptlist++]),"CK_APC");
-#endif /* CK_APC */
-#ifdef CK_AUTODL
- makestr(&(optlist[noptlist++]),"CK_AUTODL");
-#endif /* CK_AUTODL */
-#ifdef CK_MKDIR
- makestr(&(optlist[noptlist++]),"CK_MKDIR");
-#endif /* CK_MKDIR */
-#ifdef NOMKDIR
- makestr(&(optlist[noptlist++]),"NOMKDIR");
-#endif /* NOMKDIR */
-#ifdef CK_LABELED
- makestr(&(optlist[noptlist++]),"CK_LABELED");
-#endif /* CK_LABELED */
-#ifdef NODIAL
- makestr(&(optlist[noptlist++]),"NODIAL");
-#endif /* NODIAL */
-#ifdef MINIDIAL
- makestr(&(optlist[noptlist++]),"MINIDIAL");
-#endif /* MINIDIAL */
-#ifdef WHATAMI
- makestr(&(optlist[noptlist++]),"WHATAMI");
-#endif /* WHATAMI */
-#ifdef DYNAMIC
- makestr(&(optlist[noptlist++]),"DYNAMIC");
-#endif /* DYNAMIC */
-#ifndef NOSPL
- sprintf(line,"CMDDEP=%d",CMDDEP); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* NOSPL */
-
-#ifdef MAXPATHLEN
- sprintf(line,"MAXPATHLEN=%d",MAXPATHLEN); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAXPATHLEN */
-
-#ifdef DEVNAMLEN
- sprintf(line,"DEVNAMLEN=%d",DEVNAMLEN); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* DEVNAMLEN */
-
-#ifdef NO_PARAM_H
- makestr(&(optlist[noptlist++]),"NO_PARAM_H");
-#endif /* NO_PARAM_H */
-
-#ifdef INCL_PARAM_H
- makestr(&(optlist[noptlist++]),"INCL_PARAM_H");
-#endif /* INCL_PARAM_H */
-
- sprintf(line,"CKMAXPATH=%d",CKMAXPATH); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-
- sprintf(line,"CKMAXOPEN=%d",CKMAXOPEN); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-
- sprintf(line,"Z_MAXCHAN=%d",Z_MAXCHAN); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-
-#ifdef OPEN_MAX
- sprintf(line,"OPEN_MAX=%d",OPEN_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* OPEN_MAX */
-
-#ifdef _POSIX_OPEN_MAX
- sprintf(line,"_POSIX_OPEN_MAX=%d",_POSIX_OPEN_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* _POSIX_OPEN_MAX */
-
-#ifdef CKCHANNELIO
- {
- extern int z_maxchan;
-#ifdef UNIX
- extern int ckmaxfiles;
- sprintf(line,"ckmaxfiles=%d",ckmaxfiles); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* UNIX */
- sprintf(line,"z_maxchan=%d",z_maxchan); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
- }
-#endif /* CKCHANNELIO */
-
-#ifdef FOPEN_MAX
- sprintf(line,"FOPEN_MAX=%d",FOPEN_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* FOPEN_MAX */
-
-#ifdef MAXGETPATH
- sprintf(line,"MAXGETPATH=%d",MAXGETPATH); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAXGETPATH */
-
-#ifdef CMDBL
- sprintf(line,"CMDBL=%d",CMDBL); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* CMDBL */
-
-#ifdef VNAML
- sprintf(line,"VNAML=%d",VNAML); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* VNAML */
-
-#ifdef ARRAYREFLEN
- sprintf(line,"ARRAYREFLEN=%d",ARRAYREFLEN); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* ARRAYREFLEN */
-
-#ifdef UIDBUFLEN
- sprintf(line,"UIDBUFLEN=%d",UIDBUFLEN); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* UIDBUFLEN */
-
-#ifdef FORDEPTH
- sprintf(line,"FORDEPTH=%d",FORDEPTH); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* FORDEPTH */
-
-#ifdef MAXTAKE
- sprintf(line,"MAXTAKE=%d",MAXTAKE); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAXTAKE */
-
-#ifdef MACLEVEL
- sprintf(line,"MACLEVEL=%d",MACLEVEL); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MACLEVEL */
-
-#ifdef MAC_MAX
- sprintf(line,"MAC_MAX=%d",MAC_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAC_MAX */
-
-#ifdef _LARGEFILE_SOURCE
- makestr(&(optlist[noptlist++]),"_LARGEFILE_SOURCE");
-#endif /* _LARGEFILE_SOURCE */
-
-#ifdef _FILE_OFFSET_BITS
- sprintf(line,"_FILE_OFFSET_BITS=%d",_FILE_OFFSET_BITS); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* _FILE_OFFSET_BITS */
-
-#ifdef __USE_FILE_OFFSET64
- makestr(&(optlist[noptlist++]),"__USE_FILE_OFFSET64");
-#endif /* __USE_FILE_OFFSET64 */
-
-#ifdef __USE_LARGEFILE64
- makestr(&(optlist[noptlist++]),"__USE_LARGEFILE64");
-#endif /* __USE_LARGEFILE64 */
-
-#ifdef COMMENT
-#ifdef CHAR_MAX
- sprintf(line,"CHAR_MAX=%llx",CHAR_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* CHAR_MAX */
-#ifdef UCHAR_MAX
- sprintf(line,"UCHAR_MAX=%llx",UCHAR_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* UCHAR_MAX */
-#ifdef SHRT_MAX
- sprintf(line,"SHRT_MAX=%llx",SHRT_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* SHRT_MAX */
-#ifdef USHRT_MAX
- sprintf(line,"USHRT_MAX=%llx",USHRT_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* USHRT_MAX */
-#ifdef INT_MAX
- sprintf(line,"INT_MAX=%llx",INT_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* INT_MAX */
-#ifdef UINT_MAX
- sprintf(line,"UINT_MAX=%llx",UINT_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* UINT_MAX */
-#ifdef MAX_LONG
- sprintf(line,"MAX_LONG=%llx",MAX_LONG); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAX_LONG */
-#ifdef LONG_MAX
- sprintf(line,"LONG_MAX=%llx",LONG_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* LONG_MAX */
-#ifdef ULONG_MAX
- sprintf(line,"ULONG_MAX=%llx",ULONG_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* ULONG_MAX */
-#ifdef MAXINT
- sprintf(line,"MAXINT=%llx",MAXINT); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAXINT */
-#ifdef MAXLONG
- sprintf(line,"MAXLONG=%llx",MAXLONG); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAXLONG */
-#ifdef NT
-#ifdef LLONG_MAX
- sprintf(line,"LLONG_MAX=%I64x",LLONG_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* LLONG_MAX */
-#ifdef ULLONG_MAX
- sprintf(line,"ULLONG_MAX=%I64x",ULLONG_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* ULLONG_MAX */
-#ifdef MAXLONGLONG
- sprintf(line,"MAXLONGLONG=%I64x",MAXLONGLONG); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAXLONGLONG */
-#else
-#ifdef LLONG_MAX
- sprintf(line,"LLONG_MAX=%llx",LLONG_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* LLONG_MAX */
-#ifdef ULLONG_MAX
- sprintf(line,"ULLONG_MAX=%llx",ULLONG_MAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* ULLONG_MAX */
-#ifdef MAXLONGLONG
- sprintf(line,"MAXLONGLONG=%llx",MAXLONGLONG); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAXLONGLONG */
-#endif
-#ifdef _INTEGRAL_MAX_BITS
- sprintf(line,"_INTEGRAL_MAX_BITS=%d",_INTEGRAL_MAX_BITS); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* _INTEGRAL_MAX_BITS */
-#endif /* COMMENT */
-
-#ifdef MINPUTMAX
- sprintf(line,"MINPUTMAX=%d",MINPUTMAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MINPUTMAX */
-
-#ifdef MAXWLD
- sprintf(line,"MAXWLD=%d",MAXWLD); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#else
-#ifdef OS2
- makestr(&(optlist[noptlist++]),"MAXWLD=unlimited");
-#endif /* OS2 */
-#endif /* MAXWLD */
-
-#ifdef MSENDMAX
- sprintf(line,"MSENDMAX=%d",MSENDMAX); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MSENDMAX */
-
-#ifdef MAXDDIR
- sprintf(line,"MAXDDIR=%d",MAXDDIR); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAXDDIR */
-
-#ifdef MAXDNUMS
- sprintf(line,"MAXDNUMS=%d",MAXDNUMS); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* MAXDNUMS */
-
-#ifdef UNIX
- makestr(&(optlist[noptlist++]),"UNIX");
-#endif /* UNIX */
-
-#ifdef VMS
- makestr(&(optlist[noptlist++]),"VMS");
-#ifdef __VMS_VER
- sprintf(line,"__VMS_VER=%d",__VMS_VER); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* __VMS_VER */
-#ifdef VMSV70
- makestr(&(optlist[noptlist++]),"VMSV70");
-#endif /* VMSV70 */
-#ifdef OLD_VMS
- makestr(&(optlist[noptlist++]),"OLD_VMS");
-#endif /* OLD_VMS */
-#ifdef vms
- makestr(&(optlist[noptlist++]),"vms");
-#endif /* vms */
-#ifdef VMSV60
- makestr(&(optlist[noptlist++]),"VMSV60");
-#endif /* VMSV60 */
-#ifdef VMSV80
- makestr(&(optlist[noptlist++]),"VMSV80");
-#endif /* VMSV80 */
-#ifdef VMSSHARE
- makestr(&(optlist[noptlist++]),"VMSSHARE");
-#endif /* VMSSHARE */
-#ifdef NOVMSSHARE
- makestr(&(optlist[noptlist++]),"NOVMSSHARE");
-#endif /* NOVMSSHARE */
-#endif /* VMS */
-
-#ifdef datageneral
- makestr(&(optlist[noptlist++]),"datageneral");
-#endif /* datageneral */
-#ifdef apollo
- makestr(&(optlist[noptlist++]),"apollo");
-#endif /* apollo */
-#ifdef aegis
- makestr(&(optlist[noptlist++]),"aegis");
-#endif /* aegis */
-#ifdef A986
- makestr(&(optlist[noptlist++]),"A986");
-#endif /* A986 */
-#ifdef AMIGA
- makestr(&(optlist[noptlist++]),"AMIGA");
-#endif /* AMIGA */
-#ifdef CONVEX9
- makestr(&(optlist[noptlist++]),"CONVEX9");
-#endif /* CONVEX9 */
-#ifdef CONVEX10
- makestr(&(optlist[noptlist++]),"CONVEX10");
-#endif /* CONVEX9 */
-#ifdef MAC
- makestr(&(optlist[noptlist++]),"MAC");
-#endif /* MAC */
-#ifdef AUX
- makestr(&(optlist[noptlist++]),"AUX");
-#endif /* AUX */
-
-#ifdef OS2
- makestr(&(optlist[noptlist++]),"OS2");
-#ifdef NT
- makestr(&(optlist[noptlist++]),"NT");
-#endif /* NT */
-#endif /* OS2 */
-
-#ifdef OSK
- makestr(&(optlist[noptlist++]),"OS9");
-#endif /* OSK */
-
-#ifdef MSDOS
- makestr(&(optlist[noptlist++]),"MSDOS");
-#endif /* MSDOS */
-
-#ifdef DIRENT
- makestr(&(optlist[noptlist++]),"DIRENT");
-#endif /* DIRENT */
-
-#ifdef SDIRENT
- makestr(&(optlist[noptlist++]),"SDIRENT");
-#endif /* SDIRENT */
-
-#ifdef NDIR
- makestr(&(optlist[noptlist++]),"NDIR");
-#endif /* NDIR */
-
-#ifdef XNDIR
- makestr(&(optlist[noptlist++]),"XNDIR");
-#endif /* XNDIR */
-
-#ifdef SAVEDUID
- makestr(&(optlist[noptlist++]),"SAVEDUID");
-#endif /* SAVEDUID */
-
-#ifdef RENAME
- makestr(&(optlist[noptlist++]),"RENAME");
-#endif /* RENAME */
-
-#ifdef CK_TMPDIR
- makestr(&(optlist[noptlist++]),"CK_TMPDIR");
-#endif /* CK_TMPDIR */
-
-#ifdef NOCCTRAP
- makestr(&(optlist[noptlist++]),"NOCCTRAP");
-#endif /* NOCCTRAP */
-
-#ifdef NOCOTFMC
- makestr(&(optlist[noptlist++]),"NOCOTFMC");
-#endif /* NOCOTFMC */
-
-#ifdef NOFRILLS
- makestr(&(optlist[noptlist++]),"NOFRILLS");
-#endif /* NOFRILLS */
-
-#ifdef PARSENSE
- makestr(&(optlist[noptlist++]),"PARSENSE");
-#endif /* PARSENSE */
-
-#ifdef TIMEH
- makestr(&(optlist[noptlist++]),"TIMEH");
-#endif /* TIMEH */
-
-#ifdef NOTIMEH
- makestr(&(optlist[noptlist++]),"TIMEH");
-#endif /* NOTIMEH */
-
-#ifdef SYSTIMEH
- makestr(&(optlist[noptlist++]),"SYSTIMEH");
-#endif /* SYSTIMEH */
-
-#ifdef NOSYSTIMEH
- makestr(&(optlist[noptlist++]),"SYSTIMEH");
-#endif /* NOSYSTIMEH */
-
-#ifdef SYSTIMEBH
- makestr(&(optlist[noptlist++]),"SYSTIMEBH");
-#endif /* SYSTIMEBH */
-
-#ifdef NOSYSTIMEBH
- makestr(&(optlist[noptlist++]),"SYSTIMEBH");
-#endif /* NOSYSTIMEBH */
-
-#ifdef UTIMEH
- makestr(&(optlist[noptlist++]),"UTIMEH");
-#endif /* UTIMEH */
-
-#ifdef SYSUTIMEH
- makestr(&(optlist[noptlist++]),"SYSUTIMEH");
-#endif /* SYSUTIMEH */
-
-#ifdef CK_NEED_SIG
- makestr(&(optlist[noptlist++]),"CK_NEED_SIG");
-#endif /* CK_NEED_SIG */
-
-#ifdef CK_TTYFD
- makestr(&(optlist[noptlist++]),"CK_TTYFD");
-#endif /* CK_TTYFD */
-
-#ifdef NETCONN
- makestr(&(optlist[noptlist++]),"NETCONN");
-#endif /* NETCONN */
-
-#ifdef TCPSOCKET
- makestr(&(optlist[noptlist++]),"TCPSOCKET");
-#ifdef NOTCPOPTS
- makestr(&(optlist[noptlist++]),"NOTCPOPTS");
-#endif /* NOTCPOPTS */
-#ifdef CK_DNS_SRV
- makestr(&(optlist[noptlist++]),"CK_DNS_SRV");
-#endif /* CK_DNS_SRV */
-#ifdef NO_DNS_SRV
- makestr(&(optlist[noptlist++]),"NO_DNS_SRV");
-#endif /* NO_DNS_SRV */
-#ifdef CKGHNLHOST
- makestr(&(optlist[noptlist++]),"CKGHNLHOST");
-#endif /* CKGHNLHOST */
-#ifdef NOLISTEN
- makestr(&(optlist[noptlist++]),"NOLISTEN");
-#endif /* NOLISTEN */
-#ifdef SOL_SOCKET
- makestr(&(optlist[noptlist++]),"SOL_SOCKET");
-#endif /* SOL_SOCKET */
-#ifdef SO_OOBINLINE
- makestr(&(optlist[noptlist++]),"SO_OOBINLINE");
-#endif /* SO_OOBINLNE */
-#ifdef SO_DONTROUTE
- makestr(&(optlist[noptlist++]),"SO_DONTROUTE");
-#endif /* SO_DONTROUTE */
-#ifdef SO_KEEPALIVE
- makestr(&(optlist[noptlist++]),"SO_KEEPALIVE");
-#endif /* SO_KEEPALIVE */
-#ifdef SO_LINGER
- makestr(&(optlist[noptlist++]),"SO_LINGER");
-#endif /* SO_LINGER */
-#ifdef TCP_NODELAY
- makestr(&(optlist[noptlist++]),"TCP_NODELAY");
-#endif /* TCP_NODELAY */
-#ifdef SO_SNDBUF
- makestr(&(optlist[noptlist++]),"SO_SNDBUF");
-#endif /* SO_SNDBUF */
-#ifdef SO_RCVBUF
- makestr(&(optlist[noptlist++]),"SO_RCVBUF");
-#endif /* SO_RCVBUF */
-#ifdef h_addr
- makestr(&(optlist[noptlist++]),"h_addr");
-#endif /* h_addr */
-#ifdef HADDRLIST
- makestr(&(optlist[noptlist++]),"HADDRLIST");
-#endif /* HADDRLIST */
-#ifdef CK_SOCKS
- makestr(&(optlist[noptlist++]),"CK_SOCKS");
-#ifdef CK_SOCKS5
- makestr(&(optlist[noptlist++]),"CK_SOCKS5");
-#endif /* CK_SOCKS5 */
-#ifdef CK_SOCKS_NS
- makestr(&(optlist[noptlist++]),"CK_SOCKS_NS");
-#endif /* CK_SOCKS_NS */
-#endif /* CK_SOCKS */
-#ifdef RLOGCODE
- makestr(&(optlist[noptlist++]),"RLOGCODE");
-#endif /* RLOGCODE */
-#ifdef NETCMD
- makestr(&(optlist[noptlist++]),"NETCMD");
-#endif /* NETCMD */
-#ifdef NONETCMD
- makestr(&(optlist[noptlist++]),"NONETCMD");
-#endif /* NONETCMD */
-#ifdef NETPTY
- makestr(&(optlist[noptlist++]),"NETPTY");
-#endif /* NETPTY */
-#ifdef CK_ENVIRONMENT
- makestr(&(optlist[noptlist++]),"CK_ENVIRONMENT");
-#endif /* CK_ENVIRONMENT */
-#endif /* TCPSOCKET */
-#ifdef TNCODE
- makestr(&(optlist[noptlist++]),"TNCODE");
-#endif /* TNCODE */
-#ifdef CK_FORWARD_X
- makestr(&(optlist[noptlist++]),"CK_FORWARD_X");
-#endif /* CK_FORWARD_X */
-#ifdef TN_COMPORT
- makestr(&(optlist[noptlist++]),"TN_COMPORT");
-#endif /* TN_COMPORT */
-#ifdef MULTINET
- makestr(&(optlist[noptlist++]),"MULTINET");
-#endif /* MULTINET */
-#ifdef DEC_TCPIP
- makestr(&(optlist[noptlist++]),"DEC_TCPIP");
-#endif /* DEC_TCPIP */
-#ifdef TCPWARE
- makestr(&(optlist[noptlist++]),"TCPWARE");
-#endif /* TCPWARE */
-#ifdef UCX50
- makestr(&(optlist[noptlist++]),"UCX50");
-#endif /* UCX50 */
-#ifdef CMU_TCPIP
- makestr(&(optlist[noptlist++]),"CMU_TCPIP");
-#endif /* CMU_TCPIP */
-#ifdef TTLEBUF
- makestr(&(optlist[noptlist++]),"TTLEBUF");
-#endif /* TTLEBUF */
-#ifdef NETLEBUF
- makestr(&(optlist[noptlist++]),"NETLEBUF");
-#endif /* NETLEBUF */
-#ifdef IKS_OPTION
- makestr(&(optlist[noptlist++]),"IKS_OPTION");
-#endif /* IKS_OPTION */
-#ifdef IKSDB
- makestr(&(optlist[noptlist++]),"IKSDB");
-#endif /* IKSDB */
-#ifdef IKSDCONF
- makestr(&(optlist[noptlist++]),"IKSDCONF");
-#endif /* IKSDCONF */
-#ifdef CK_LOGIN
- makestr(&(optlist[noptlist++]),"CK_LOGIN");
-#endif /* CK_LOGIN */
-#ifdef CK_PAM
- makestr(&(optlist[noptlist++]),"CK_PAM");
-#endif /* CK_PAM */
-#ifdef CK_SHADOW
- makestr(&(optlist[noptlist++]),"CK_SHADOW");
-#endif /* CK_SHADOW */
-#ifdef CONGSPD
- makestr(&(optlist[noptlist++]),"CONGSPD");
-#endif /* CONGSPD */
-#ifdef SUNX25
- makestr(&(optlist[noptlist++]),"SUNX25");
-#endif /* SUNX25 */
-#ifdef IBMX25
- makestr(&(optlist[noptlist++]),"IBMX25");
-#endif /* IBMX25 */
-#ifdef HPX25
- makestr(&(optlist[noptlist++]),"HPX25");
-#endif /* HPX25 */
-#ifdef DECNET
- makestr(&(optlist[noptlist++]),"DECNET");
-#endif /* DECNET */
-#ifdef SUPERLAT
- makestr(&(optlist[noptlist++]),"SUPERLAT");
-#endif /* SUPERLAT */
-#ifdef NPIPE
- makestr(&(optlist[noptlist++]),"NPIPE");
-#endif /* NPIPE */
-#ifdef CK_NETBIOS
- makestr(&(optlist[noptlist++]),"CK_NETBIOS");
-#endif /* CK_NETBIOS */
-#ifdef ATT7300
- makestr(&(optlist[noptlist++]),"ATT7300");
-#endif /* ATT7300 */
-#ifdef ATT6300
- makestr(&(optlist[noptlist++]),"ATT6300");
-#endif /* ATT6300 */
-#ifdef HDBUUCP
- makestr(&(optlist[noptlist++]),"HDBUUCP");
-#endif /* HDBUUCP */
-#ifdef USETTYLOCK
- makestr(&(optlist[noptlist++]),"USETTYLOCK");
-#endif /* USETTYLOCK */
-#ifdef USE_UU_LOCK
- makestr(&(optlist[noptlist++]),"USE_UU_LOCK");
-#endif /* USE_UU_LOCK */
-#ifdef HAVE_LOCKDEV
- makestr(&(optlist[noptlist++]),"HAVE_LOCKDEV");
-#endif /* HAVE_LOCKDEV */
-#ifdef HAVE_BAUDBOY
- makestr(&(optlist[noptlist++]),"HAVE_BAUDBOY");
-#endif /* HAVE_BAUDBOY */
-#ifdef HAVE_OPENPTY
- makestr(&(optlist[noptlist++]),"HAVE_OPENPTY");
-#endif /* HAVE_OPENPTY */
-#ifdef TTPTYCMD
- makestr(&(optlist[noptlist++]),"TTPTYCMD");
-#endif /* TTPTYCMD */
-#ifdef NOUUCP
- makestr(&(optlist[noptlist++]),"NOUUCP");
-#endif /* NOUUCP */
-#ifdef LONGFN
- makestr(&(optlist[noptlist++]),"LONGFN");
-#endif /* LONGFN */
-#ifdef RDCHK
- makestr(&(optlist[noptlist++]),"RDCHK");
-#endif /* RDCHK */
-#ifdef SELECT
- makestr(&(optlist[noptlist++]),"SELECT");
-#endif /* SELECT */
-#ifdef USLEEP
- makestr(&(optlist[noptlist++]),"USLEEP");
-#endif /* USLEEP */
-#ifdef NAP
- makestr(&(optlist[noptlist++]),"NAP");
-#endif /* NAP */
-#ifdef NAPHACK
- makestr(&(optlist[noptlist++]),"NAPHACK");
-#endif /* NAPHACK */
-#ifdef CK_POLL
- makestr(&(optlist[noptlist++]),"CK_POLL");
-#endif /* CK_POLL */
-#ifdef NOIEXTEN
- makestr(&(optlist[noptlist++]),"NOIEXTEN");
-#endif /* NOIEXTEN */
-#ifdef EXCELAN
- makestr(&(optlist[noptlist++]),"EXCELAN");
-#endif /* EXCELAN */
-#ifdef INTERLAN
- makestr(&(optlist[noptlist++]),"INTERLAN");
-#endif /* INTERLAN */
-#ifdef NOFILEH
- makestr(&(optlist[noptlist++]),"NOFILEH");
-#endif /* NOFILEH */
-#ifdef NOSYSIOCTLH
- makestr(&(optlist[noptlist++]),"NOSYSIOCTLH");
-#endif /* NOSYSIOCTLH */
-#ifdef DCLPOPEN
- makestr(&(optlist[noptlist++]),"DCLPOPEN");
-#endif /* DCLPOPEN */
-#ifdef NOSETBUF
- makestr(&(optlist[noptlist++]),"NOSETBUF");
-#endif /* NOSETBUF */
-#ifdef NOXFER
- makestr(&(optlist[noptlist++]),"NOXFER");
-#endif /* NOXFER */
-#ifdef NOCURSES
- makestr(&(optlist[noptlist++]),"NOCURSES");
-#endif /* NOCURSES */
-#ifdef NOSERVER
- makestr(&(optlist[noptlist++]),"NOSERVER");
-#endif /* NOSERVER */
-#ifdef NOPATTERNS
- makestr(&(optlist[noptlist++]),"NOPATTERNS");
-#else
-#ifdef PATTERNS
- makestr(&(optlist[noptlist++]),"PATTERNS");
-#endif /* PATTERNS */
-#endif /* NOPATTERNS */
-#ifdef NOCKEXEC
- makestr(&(optlist[noptlist++]),"NOCKEXEC");
-#else
-#ifdef CKEXEC
- makestr(&(optlist[noptlist++]),"CKEXEC");
-#endif /* CKEXEC */
-#endif /* NOCKEXEC */
-#ifdef NOAUTODL
- makestr(&(optlist[noptlist++]),"NOAUTODL");
-#endif /* NOAUTODL */
-#ifdef NOMSEND
- makestr(&(optlist[noptlist++]),"NOMSEND");
-#endif /* NOMSEND */
-#ifdef NOFDZERO
- makestr(&(optlist[noptlist++]),"NOFDZERO");
-#endif /* NOFDZERO */
-#ifdef NOPOPEN
- makestr(&(optlist[noptlist++]),"NOPOPEN");
-#endif /* NOPOPEN */
-#ifdef NOPARTIAL
- makestr(&(optlist[noptlist++]),"NOPARTIAL");
-#endif /* NOPARTIAL */
-#ifdef NOKVERBS
- makestr(&(optlist[noptlist++]),"NOKVERBS");
-#endif /* NOKVERBS */
-#ifdef NOSETREU
- makestr(&(optlist[noptlist++]),"NOSETREU");
-#endif /* NOSETREU */
-#ifdef LCKDIR
- makestr(&(optlist[noptlist++]),"LCKDIR");
-#endif /* LCKDIR */
-#ifdef ACUCNTRL
- makestr(&(optlist[noptlist++]),"ACUCNTRL");
-#endif /* ACUCNTRL */
-#ifdef BSD4
- makestr(&(optlist[noptlist++]),"BSD4");
-#endif /* BSD4 */
-#ifdef BSD44
- makestr(&(optlist[noptlist++]),"BSD44");
-#endif /* BSD44 */
-#ifdef BSD41
- makestr(&(optlist[noptlist++]),"BSD41");
-#endif /* BSD41 */
-#ifdef BSD43
- makestr(&(optlist[noptlist++]),"BSD43");
-#endif /* BSD43 */
-#ifdef BSD29
- makestr(&(optlist[noptlist++]),"BSD29");
-#endif /* BSD29 */
-#ifdef BSDI
- makestr(&(optlist[noptlist++]),"BSDI");
-#endif /* BSDI */
-#ifdef __bsdi__
- makestr(&(optlist[noptlist++]),"__bsdi__");
-#endif /* __bsdi__ */
-#ifdef __NetBSD__
- makestr(&(optlist[noptlist++]),"__NetBSD__");
-#endif /* __NetBSD__ */
-#ifdef __OpenBSD__
- makestr(&(optlist[noptlist++]),"__OpenBSD__");
-#endif /* __OpenBSD__ */
-#ifdef __FreeBSD__
- makestr(&(optlist[noptlist++]),"__FreeBSD__");
-#endif /* __FreeBSD__ */
-#ifdef FREEBSD4
- makestr(&(optlist[noptlist++]),"FREEBSD4");
-#endif /* FREEBSD4 */
-#ifdef FREEBSD8
- makestr(&(optlist[noptlist++]),"FREEBSD8");
-#endif /* FREEBSD8 */
-#ifdef FREEBSD9
- makestr(&(optlist[noptlist++]),"FREEBSD9");
-#endif /* FREEBSD9 */
-#ifdef __linux__
- makestr(&(optlist[noptlist++]),"__linux__");
-#endif /* __linux__ */
-#ifdef LINUX_HI_SPD
- makestr(&(optlist[noptlist++]),"LINUX_HI_SPD");
-#endif /* LINUX_HI_SPD */
-#ifdef LYNXOS
- makestr(&(optlist[noptlist++]),"LYNXOS");
-#endif /* LYNXOS */
-#ifdef V7
- makestr(&(optlist[noptlist++]),"V7");
-#endif /* V7 */
-#ifdef AIX370
- makestr(&(optlist[noptlist++]),"AIX370");
-#endif /* AIX370 */
-#ifdef RTAIX
- makestr(&(optlist[noptlist++]),"RTAIX");
-#endif /* RTAIX */
-#ifdef HPUX
- makestr(&(optlist[noptlist++]),"HPUX");
-#endif /* HPUX */
-#ifdef HPUX9
- makestr(&(optlist[noptlist++]),"HPUX9");
-#endif /* HPUX9 */
-#ifdef HPUX10
- makestr(&(optlist[noptlist++]),"HPUX10");
-#endif /* HPUX10 */
-#ifdef HPUX1000
- makestr(&(optlist[noptlist++]),"HPUX1000");
-#endif /* HPUX1000 */
-#ifdef HPUX1100
- makestr(&(optlist[noptlist++]),"HPUX1100");
-#endif /* HPUX1100 */
-#ifdef HPUXPRE65
- makestr(&(optlist[noptlist++]),"HPUXPRE65");
-#endif /* HPUXPRE65 */
-#ifdef DGUX
- makestr(&(optlist[noptlist++]),"DGUX");
-#endif /* DGUX */
-#ifdef DGUX430
- makestr(&(optlist[noptlist++]),"DGUX430");
-#endif /* DGUX430 */
-#ifdef DGUX540
- makestr(&(optlist[noptlist++]),"DGUX540");
-#endif /* DGUX540 */
-#ifdef DGUX543
- makestr(&(optlist[noptlist++]),"DGUX543");
-#endif /* DGUX543 */
-#ifdef DGUX54410
- makestr(&(optlist[noptlist++]),"DGUX54410");
-#endif /* DGUX54410 */
-#ifdef DGUX54411
- makestr(&(optlist[noptlist++]),"DGUX54411");
-#endif /* DGUX54411 */
-#ifdef sony_news
- makestr(&(optlist[noptlist++]),"sony_news");
-#endif /* sony_news */
-#ifdef CIE
- makestr(&(optlist[noptlist++]),"CIE");
-#endif /* CIE */
-#ifdef XENIX
- makestr(&(optlist[noptlist++]),"XENIX");
-#endif /* XENIX */
-#ifdef SCO_XENIX
- makestr(&(optlist[noptlist++]),"SCO_XENIX");
-#endif /* SCO_XENIX */
-#ifdef ISIII
- makestr(&(optlist[noptlist++]),"ISIII");
-#endif /* ISIII */
-#ifdef I386IX
- makestr(&(optlist[noptlist++]),"I386IX");
-#endif /* I386IX */
-#ifdef RTU
- makestr(&(optlist[noptlist++]),"RTU");
-#endif /* RTU */
-#ifdef PROVX1
- makestr(&(optlist[noptlist++]),"PROVX1");
-#endif /* PROVX1 */
-#ifdef PYRAMID
- makestr(&(optlist[noptlist++]),"PYRAMID");
-#endif /* PYRAMID */
-#ifdef TOWER1
- makestr(&(optlist[noptlist++]),"TOWER1");
-#endif /* TOWER1 */
-#ifdef UTEK
- makestr(&(optlist[noptlist++]),"UTEK");
-#endif /* UTEK */
-#ifdef ZILOG
- makestr(&(optlist[noptlist++]),"ZILOG");
-#endif /* ZILOG */
-#ifdef TRS16
- makestr(&(optlist[noptlist++]),"TRS16");
-#endif /* TRS16 */
-#ifdef MINIX
- makestr(&(optlist[noptlist++]),"MINIX");
-#endif /* MINIX */
-#ifdef MINIX2
- makestr(&(optlist[noptlist++]),"MINIX2");
-#endif /* MINIX2 */
-#ifdef MINIX3
- makestr(&(optlist[noptlist++]),"MINIX3");
-#endif /* MINIX3 */
-#ifdef MINIX315
- makestr(&(optlist[noptlist++]),"MINIX315");
-#endif /* MINIX315 */
-#ifdef C70
- makestr(&(optlist[noptlist++]),"C70");
-#endif /* C70 */
-#ifdef AIXPS2
- makestr(&(optlist[noptlist++]),"AIXPS2");
-#endif /* AIXPS2 */
-#ifdef AIXRS
- makestr(&(optlist[noptlist++]),"AIXRS");
-#endif /* AIXRS */
-#ifdef UTSV
- makestr(&(optlist[noptlist++]),"UTSV");
-#endif /* UTSV */
-#ifdef ATTSV
- makestr(&(optlist[noptlist++]),"ATTSV");
-#endif /* ATTSV */
-#ifdef SVR3
- makestr(&(optlist[noptlist++]),"SVR3");
-#endif /* SVR3 */
-#ifdef SVR4
- makestr(&(optlist[noptlist++]),"SVR4");
-#endif /* SVR4 */
-#ifdef DELL_SVR4
- makestr(&(optlist[noptlist++]),"DELL_SVR4");
-#endif /* DELL_SVR4 */
-#ifdef ICL_SVR4
- makestr(&(optlist[noptlist++]),"ICL_SVR4");
-#endif /* ICL_SVR4 */
-#ifdef OSF
- makestr(&(optlist[noptlist++]),"OSF");
-#endif /* OSF */
-#ifdef OSF1
- makestr(&(optlist[noptlist++]),"OSF1");
-#endif /* OSF1 */
-#ifdef __OSF
- makestr(&(optlist[noptlist++]),"__OSF");
-#endif /* __OSF */
-#ifdef __OSF__
- makestr(&(optlist[noptlist++]),"__OSF__");
-#endif /* __OSF__ */
-#ifdef __osf__
- makestr(&(optlist[noptlist++]),"__osf__");
-#endif /* __osf__ */
-#ifdef __OSF1
- makestr(&(optlist[noptlist++]),"__OSF1");
-#endif /* __OSF1 */
-#ifdef __OSF1__
- makestr(&(optlist[noptlist++]),"__OSF1__");
-#endif /* __OSF1__ */
-#ifdef PTX
- makestr(&(optlist[noptlist++]),"PTX");
-#endif /* PTX */
-#ifdef POSIX
- makestr(&(optlist[noptlist++]),"POSIX");
-#endif /* POSIX */
-#ifdef BSD44ORPOSIX
- makestr(&(optlist[noptlist++]),"BSD44ORPOSIX");
-#endif /* BSD44ORPOSIX */
-#ifdef SVORPOSIX
- makestr(&(optlist[noptlist++]),"SVORPOSIX");
-#endif /* SVORPOSIX */
-#ifdef SVR4ORPOSIX
- makestr(&(optlist[noptlist++]),"SVR4ORPOSIX");
-#endif /* SVR4ORPOSIX */
-#ifdef OS2ORVMS
- makestr(&(optlist[noptlist++]),"OS2ORVMS");
-#endif /* OS2ORVMS */
-#ifdef OS2ORUNIX
- makestr(&(optlist[noptlist++]),"OS2ORUNIX");
-#endif /* OS2ORUNIX */
-#ifdef VMSORUNIX
- makestr(&(optlist[noptlist++]),"VMSORUNIX");
-#endif /* VMSORUNIX */
-#ifdef VMS64BIT
- makestr(&(optlist[noptlist++]),"VMS64BIT"); /* VMS on Alpha or IA64 */
-#endif /* VMS64BIT */
-#ifdef VMSI64
- makestr(&(optlist[noptlist++]),"VMSI64"); /* VMS on IA64 */
-#endif /* VMSI64 */
-#ifdef _POSIX_SOURCE
- makestr(&(optlist[noptlist++]),"_POSIX_SOURCE");
-#endif /* _POSIX_SOURCE */
-#ifdef _XOPEN_SOURCE
- makestr(&(optlist[noptlist++]),"_XOPEN_SOURCE");
-#endif
-#ifdef _ALL_SOURCE
- makestr(&(optlist[noptlist++]),"_ALL_SOURCE");
-#endif
-#ifdef _SVID3
- makestr(&(optlist[noptlist++]),"_SVID3");
-#endif /* _SVID3 */
-#ifdef Plan9
- makestr(&(optlist[noptlist++]),"Plan9");
-#endif /* Plan9 */
-#ifdef SOLARIS
- makestr(&(optlist[noptlist++]),"SOLARIS");
-#ifdef SOLARIS24
- makestr(&(optlist[noptlist++]),"SOLARIS24");
-#endif /* SOLARIS24 */
-#ifdef SOLARIS25
- makestr(&(optlist[noptlist++]),"SOLARIS25");
-#endif /* SOLARIS25 */
-#ifdef SOLARIS26
- makestr(&(optlist[noptlist++]),"SOLARIS26");
-#endif /* SOLARIS26 */
-#ifdef SOLARIS7
- makestr(&(optlist[noptlist++]),"SOLARIS7");
-#endif /* SOLARIS7 */
-#ifdef SOLARIS8
- makestr(&(optlist[noptlist++]),"SOLARIS8");
-#endif /* SOLARIS8 */
-#ifdef SOLARIS9
- makestr(&(optlist[noptlist++]),"SOLARIS9");
-#endif /* SOLARIS9 */
-#ifdef SOLARIS10
- makestr(&(optlist[noptlist++]),"SOLARIS10");
-#endif /* SOLARIS10 */
-#endif /* SOLARIS */
-
-#ifdef SUNOS4
- makestr(&(optlist[noptlist++]),"SUNOS4");
-#endif /* SUNOS4 */
-#ifdef SUN4S5
- makestr(&(optlist[noptlist++]),"SUN4S5");
-#endif /* SUN4S5 */
-#ifdef IRIX
- makestr(&(optlist[noptlist++]),"IRIX");
-#endif /* IRIX */
-#ifdef ENCORE
- makestr(&(optlist[noptlist++]),"ENCORE");
-#endif /* ENCORE */
-#ifdef ultrix
- makestr(&(optlist[noptlist++]),"ultrix");
-#endif
-#ifdef sxaE50
- makestr(&(optlist[noptlist++]),"sxaE50");
-#endif
-#ifdef mips
- makestr(&(optlist[noptlist++]),"mips");
-#endif
-#ifdef MIPS
- makestr(&(optlist[noptlist++]),"MIPS");
-#endif
-#ifdef vax
- makestr(&(optlist[noptlist++]),"vax");
-#endif
-#ifdef VAX
- makestr(&(optlist[noptlist++]),"VAX");
-#endif
-#ifdef alpha
- makestr(&(optlist[noptlist++]),"alpha");
-#endif
-#ifdef ALPHA
- makestr(&(optlist[noptlist++]),"ALPHA");
-#endif
-#ifdef __ALPHA
- makestr(&(optlist[noptlist++]),"__ALPHA");
-#endif
-#ifdef __alpha
- makestr(&(optlist[noptlist++]),"__alpha");
-#endif
-#ifdef __AXP
- makestr(&(optlist[noptlist++]),"__AXP");
-#endif
-#ifdef AXP
- makestr(&(optlist[noptlist++]),"AXP");
-#endif
-#ifdef axp
- makestr(&(optlist[noptlist++]),"axp");
-#endif
-#ifdef __ALPHA__
- makestr(&(optlist[noptlist++]),"__ALPHA__");
-#endif
-#ifdef __alpha__
- makestr(&(optlist[noptlist++]),"__alpha__");
-#endif
-#ifdef sun
- makestr(&(optlist[noptlist++]),"sun");
-#endif
-#ifdef sun3
- makestr(&(optlist[noptlist++]),"sun3");
-#endif
-#ifdef sun386
- makestr(&(optlist[noptlist++]),"sun386");
-#endif
-#ifdef _SUN
- makestr(&(optlist[noptlist++]),"_SUN");
-#endif
-#ifdef sun4
- makestr(&(optlist[noptlist++]),"sun4");
-#endif
-#ifdef sparc
- makestr(&(optlist[noptlist++]),"sparc");
-#endif
-#ifdef _CRAY
- makestr(&(optlist[noptlist++]),"_CRAY");
-#endif /* _CRAY */
-#ifdef NEXT33
- makestr(&(optlist[noptlist++]),"NEXT33");
-#endif
-#ifdef NEXT
- makestr(&(optlist[noptlist++]),"NEXT");
-#endif
-#ifdef NeXT
- makestr(&(optlist[noptlist++]),"NeXT");
-#endif
-#ifdef MACH
- makestr(&(optlist[noptlist++]),"MACH");
-#endif
-
-#ifdef MACOSX
- makestr(&(optlist[noptlist++]),"MACOSX");
-#endif
-#ifdef MACOSX10
- makestr(&(optlist[noptlist++]),"MACOSX10");
-#endif
-#ifdef MACOSX103
- makestr(&(optlist[noptlist++]),"MACOSX10e");
-#endif
-#ifdef COMMENT
-/* not used */
-#ifdef MACOSX103
- makestr(&(optlist[noptlist++]),"MACOSX103");
-#endif
-#endif /* COMMENT */
-
-#ifdef sgi
- makestr(&(optlist[noptlist++]),"sgi");
-#endif
-#ifdef M_SYS5
- makestr(&(optlist[noptlist++]),"M_SYS5");
-#endif
-#ifdef __SYSTEM_FIVE
- makestr(&(optlist[noptlist++]),"__SYSTEM_FIVE");
-#endif
-#ifdef sysV
- makestr(&(optlist[noptlist++]),"sysV");
-#endif
-#ifdef M_XENIX /* SCO Xenix V and UNIX/386 */
- makestr(&(optlist[noptlist++]),"M_XENIX");
-#endif
-#ifdef M_UNIX /* SCO UNIX */
- makestr(&(optlist[noptlist++]),"M_UNIX");
-#endif
-#ifdef _M_UNIX /* SCO UNIX 3.2v4 = ODT 2.0 */
- makestr(&(optlist[noptlist++]),"_M_UNIX");
-#endif
-#ifdef CK_SCOV5
- makestr(&(optlist[noptlist++]),"CK_SCOV5");
-#endif
-#ifdef SCO_OSR504
- makestr(&(optlist[noptlist++]),"SCO_OSR504");
-#endif
-#ifdef M_IA64
- makestr(&(optlist[noptlist++]),"M_IA64");
-#endif
-#ifdef _M_IA64
- makestr(&(optlist[noptlist++]),"_M_IA64");
-#endif
-#ifdef ia64
- makestr(&(optlist[noptlist++]),"ia64");
-#endif
-#ifdef _ia64
- makestr(&(optlist[noptlist++]),"_ia64");
-#endif
-#ifdef _ia64_
- makestr(&(optlist[noptlist++]),"_ia64_");
-#endif
-#ifdef __ia64
- makestr(&(optlist[noptlist++]),"__ia64");
-#endif
-#ifdef M_I686
- makestr(&(optlist[noptlist++]),"M_I686");
-#endif
-#ifdef _M_I686
- makestr(&(optlist[noptlist++]),"_M_I686");
-#endif
-#ifdef i686
- makestr(&(optlist[noptlist++]),"i686");
-#endif
-#ifdef M_I586
- makestr(&(optlist[noptlist++]),"M_I586");
-#endif
-#ifdef _M_I586
- makestr(&(optlist[noptlist++]),"_M_I586");
-#endif
-#ifdef i586
- makestr(&(optlist[noptlist++]),"i586");
-#endif
-#ifdef M_I486
- makestr(&(optlist[noptlist++]),"M_I486");
-#endif
-#ifdef _M_I486
- makestr(&(optlist[noptlist++]),"_M_I486");
-#endif
-#ifdef i486
- makestr(&(optlist[noptlist++]),"i486");
-#endif
-#ifdef M_I386
- makestr(&(optlist[noptlist++]),"M_I386");
-#endif
-#ifdef _M_I386
- makestr(&(optlist[noptlist++]),"_M_I386");
-#endif
-#ifdef i386
- makestr(&(optlist[noptlist++]),"i386");
-#endif
-#ifdef __i386
- makestr(&(optlist[noptlist++]),"__i386");
-#endif
-#ifdef __x86
- makestr(&(optlist[noptlist++]),"__x86");
-#endif
-#ifdef __amd64
- makestr(&(optlist[noptlist++]),"__amd64");
-#endif
-#ifdef _ILP32
- makestr(&(optlist[noptlist++]),"_ILP32");
-#endif
-#ifdef _ILP64
- makestr(&(optlist[noptlist++]),"_ILP64");
-#endif
-#ifdef _LP32
- makestr(&(optlist[noptlist++]),"_LP32");
-#endif
-#ifdef _LP64
- makestr(&(optlist[noptlist++]),"_LP64");
-#endif
-#ifdef __LP32__
- makestr(&(optlist[noptlist++]),"__LP32__");
-#endif
-#ifdef __LP64__
- makestr(&(optlist[noptlist++]),"__LP64__");
-#endif
-#ifdef _XGP4_2
- makestr(&(optlist[noptlist++]),"_XGP4_2");
-#endif
-#ifdef __ppc__
- makestr(&(optlist[noptlist++]),"__ppc__");
-#endif
-#ifdef __ppc32__
- makestr(&(optlist[noptlist++]),"__ppc32__");
-#endif
-#ifdef __ppc64__
- makestr(&(optlist[noptlist++]),"__ppc64__");
-#endif
-#ifdef CK_64BIT
- makestr(&(optlist[noptlist++]),"CK_64BIT");
-#endif
-#ifdef i286
- makestr(&(optlist[noptlist++]),"i286");
-#endif
-#ifdef M_I286
- makestr(&(optlist[noptlist++]),"M_I286");
-#endif
-#ifdef __sparc
- makestr(&(optlist[noptlist++]),"__sparc");
-#endif
-#ifdef __sparcv8
- makestr(&(optlist[noptlist++]),"__sparcv8");
-#endif
-#ifdef __sparcv9
- makestr(&(optlist[noptlist++]),"__sparcv9");
-#endif
-#ifdef mc68000
- makestr(&(optlist[noptlist++]),"mc68000");
-#endif
-#ifdef mc68010
- makestr(&(optlist[noptlist++]),"mc68010");
-#endif
-#ifdef mc68020
- makestr(&(optlist[noptlist++]),"mc68020");
-#endif
-#ifdef mc68030
- makestr(&(optlist[noptlist++]),"mc68030");
-#endif
-#ifdef mc68040
- makestr(&(optlist[noptlist++]),"mc68040");
-#endif
-#ifdef M_68000
- makestr(&(optlist[noptlist++]),"M_68000");
-#endif
-#ifdef M_68010
- makestr(&(optlist[noptlist++]),"M_68010");
-#endif
-#ifdef M_68020
- makestr(&(optlist[noptlist++]),"M_68020");
-#endif
-#ifdef M_68030
- makestr(&(optlist[noptlist++]),"M_68030");
-#endif
-#ifdef M_68040
- makestr(&(optlist[noptlist++]),"M_68040");
-#endif
-#ifdef m68k
- makestr(&(optlist[noptlist++]),"m68k");
-#endif
-#ifdef m88k
- makestr(&(optlist[noptlist++]),"m88k");
-#endif
-#ifdef pdp11
- makestr(&(optlist[noptlist++]),"pdp11");
-#endif
-#ifdef iAPX
- makestr(&(optlist[noptlist++]),"iAPX");
-#endif
-#ifdef hpux
- makestr(&(optlist[noptlist++]),"hpux");
-#endif
-#ifdef __hpux
- makestr(&(optlist[noptlist++]),"__hpux");
-#endif
-#ifdef __hp9000s800
- makestr(&(optlist[noptlist++]),"__hp9000s800");
-#endif
-#ifdef __hp9000s700
- makestr(&(optlist[noptlist++]),"__hp9000s700");
-#endif
-#ifdef __hp9000s500
- makestr(&(optlist[noptlist++]),"__hp9000s500");
-#endif
-#ifdef __hp9000s300
- makestr(&(optlist[noptlist++]),"__hp9000s300");
-#endif
-#ifdef __hp9000s200
- makestr(&(optlist[noptlist++]),"__hp9000s200");
-#endif
-#ifdef AIX
- makestr(&(optlist[noptlist++]),"AIX");
-#endif
-#ifdef _AIXFS
- makestr(&(optlist[noptlist++]),"_AIXFS");
-#endif
-#ifdef u370
- makestr(&(optlist[noptlist++]),"u370");
-#endif
-#ifdef u3b
- makestr(&(optlist[noptlist++]),"u3b");
-#endif
-#ifdef u3b2
- makestr(&(optlist[noptlist++]),"u3b2");
-#endif
-#ifdef multimax
- makestr(&(optlist[noptlist++]),"multimax");
-#endif
-#ifdef balance
- makestr(&(optlist[noptlist++]),"balance");
-#endif
-#ifdef ibmrt
- makestr(&(optlist[noptlist++]),"ibmrt");
-#endif
-#ifdef _IBMRT
- makestr(&(optlist[noptlist++]),"_IBMRT");
-#endif
-#ifdef ibmrs6000
- makestr(&(optlist[noptlist++]),"ibmrs6000");
-#endif
-#ifdef _AIX
- makestr(&(optlist[noptlist++]),"_AIX");
-#endif /* _AIX */
-#ifdef _IBMR2
- makestr(&(optlist[noptlist++]),"_IBMR2");
-#endif
-#ifdef UNIXWARE
- makestr(&(optlist[noptlist++]),"UNIXWARE");
-#endif
-#ifdef QNX
- makestr(&(optlist[noptlist++]),"QNX");
-#ifdef __QNX__
- makestr(&(optlist[noptlist++]),"__QNX__");
-#ifdef __16BIT__
- makestr(&(optlist[noptlist++]),"__16BIT__");
-#endif
-#ifdef CK_QNX16
- makestr(&(optlist[noptlist++]),"CK_QNX16");
-#endif
-#ifdef __32BIT__
- makestr(&(optlist[noptlist++]),"__32BIT__");
-#endif
-#ifdef CK_QNX32
- makestr(&(optlist[noptlist++]),"CK_QNX32");
-#endif
-#endif /* __QNX__ */
-#endif /* QNX */
-
-#ifdef QNX6
- makestr(&(optlist[noptlist++]),"QNX6");
-#endif /* QNX6 */
-
-#ifdef NEUTRINO
- makestr(&(optlist[noptlist++]),"NEUTRINO");
-#endif /* NEUTRINO */
-
-#ifdef __STRICT_BSD__
- makestr(&(optlist[noptlist++]),"__STRICT_BSD__");
-#endif
-#ifdef __STRICT_ANSI__
- makestr(&(optlist[noptlist++]),"__STRICT_ANSI__");
-#endif
-#ifdef _ANSI_C_SOURCE
- makestr(&(optlist[noptlist++]),"_ANSI_C_SOURCE");
-#endif
-#ifdef __STDC__
- makestr(&(optlist[noptlist++]),"__STDC__");
-#endif
-#ifdef cplusplus
- makestr(&(optlist[noptlist++]),"cplusplus");
-#endif
-#ifdef __DECC
- makestr(&(optlist[noptlist++]),"__DECC");
-#ifdef __DECC_VER
- sprintf(line,"__DECC_VER=%d",__DECC_VER); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* __DECC_VER */
-#endif /* __DECC */
-#ifdef __CRTL_VER
- sprintf(line,"__CRTL_VER=%d",__CRTL_VER); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* __CRTL_VER */
-#ifdef __GNUC__ /* gcc in ansi mode */
- makestr(&(optlist[noptlist++]),"__GNUC__");
-#endif
-#ifdef GNUC /* gcc in traditional mode */
- makestr(&(optlist[noptlist++]),"GNUC");
-#endif
-#ifdef __EGCS__ /* egcs in ansi mode */
- makestr(&(optlist[noptlist++]),"__EGCS__");
-#endif
-#ifdef __egcs__ /* egcs in ansi mode */
- makestr(&(optlist[noptlist++]),"__egcs__");
-#endif
-#ifdef __WATCOMC__
- makestr(&(optlist[noptlist++]),"__WATCOMC__");
-#endif
-#ifdef CK_ANSIC
- makestr(&(optlist[noptlist++]),"CK_ANSIC");
-#endif
-#ifdef CK_ANSILIBS
- makestr(&(optlist[noptlist++]),"CK_ANSILIBS");
-#endif
-#ifdef CKCONINTB4CB
- makestr(&(optlist[noptlist++]),"CKCONINTB4CB");
-#endif /* CKCONINTB4CB */
-#ifdef NOTERMCAP
- makestr(&(optlist[noptlist++]),"NOTERMCAP");
-#endif /* NOTERMCAP */
-#ifdef __GLIBC__
- makestr(&(optlist[noptlist++]),"__GLIBC__");
-#endif
-#ifdef _SC_JOB_CONTROL
- makestr(&(optlist[noptlist++]),"_SC_JOB_CONTROL");
-#endif
-#ifdef _POSIX_JOB_CONTROL
- makestr(&(optlist[noptlist++]),"_POSIX_JOB_CONTROL");
-#endif
-#ifdef SIG_I
- makestr(&(optlist[noptlist++]),"SIG_I");
-#endif /* SIG_I */
-#ifdef SIG_V
- makestr(&(optlist[noptlist++]),"SIG_V");
-#endif /* SIG_V */
-#ifdef CK_POSIX_SIG
- makestr(&(optlist[noptlist++]),"CK_POSIX_SIG");
-#endif
-#ifdef SVR3JC
- makestr(&(optlist[noptlist++]),"SVR3JC");
-#endif
-#ifdef _386BSD
- makestr(&(optlist[noptlist++]),"_386BSD");
-#endif
-#ifdef _BSD
- makestr(&(optlist[noptlist++]),"_BSD");
-#endif
-#ifdef USE_MEMCPY
- makestr(&(optlist[noptlist++]),"USE_MEMCPY");
-#endif /* USE_MEMCPY */
-#ifdef USE_LSTAT
- makestr(&(optlist[noptlist++]),"USE_LSTAT");
-#endif /* USE_LSTAT */
-#ifdef TERMIOX
- makestr(&(optlist[noptlist++]),"TERMIOX");
-#endif /* TERMIOX */
-#ifdef STERMIOX
- makestr(&(optlist[noptlist++]),"STERMIOX");
-#endif /* STERMIOX */
-#ifdef CK_CURSES
- makestr(&(optlist[noptlist++]),"CK_CURSES");
-#endif /* CK_CURSES */
-#ifdef CK_NEWTERM
- makestr(&(optlist[noptlist++]),"CK_NEWTERM");
-#endif /* CK_NEWTERM */
-#ifdef CK_WREFRESH
- makestr(&(optlist[noptlist++]),"CK_WREFRESH");
-#endif /* CK_WREFRESH */
-#ifdef CK_PCT_BAR
- makestr(&(optlist[noptlist++]),"CK_PCT_BAR");
-#endif /* CK_PCT_BAR */
-#ifdef CK_DTRCD
- makestr(&(optlist[noptlist++]),"CK_DTRCD");
-#endif /* CK_DTRCD */
-#ifdef CK_DTRCTS
- makestr(&(optlist[noptlist++]),"CK_DTRCTS");
-#endif /* CK_DTRCTS */
-#ifdef CK_RTSCTS
- makestr(&(optlist[noptlist++]),"CK_RTSCTS");
-#endif /* CK_RTSCTS */
-#ifdef POSIX_CRTSCTS
- makestr(&(optlist[noptlist++]),"POSIX_CRTSCTS");
-#endif /* POSIX_CRTSCTS */
-#ifdef FIXCRTSCTS
- makestr(&(optlist[noptlist++]),"FIXCRTSCTS");
-#endif /* FIXCRTSCTS */
-#ifdef HWPARITY
- makestr(&(optlist[noptlist++]),"HWPARITY");
-#endif /* HWPARITY */
-#ifdef CK_SYSINI
-#ifdef CK_INI_A
- makestr(&(optlist[noptlist++]),"CK_INI_A");
- ckmakmsg(line,LINBUFSIZ,"CK_SYSINI=\"",CK_SYSINI,"\"",NULL);
- makestr(&(optlist[noptlist++]),line);
-#else
-#ifdef CK_INI_B
- makestr(&(optlist[noptlist++]),"CK_INI_B");
- ckmakmsg(line,LINBUFSIZ,"CK_SYSINI=\"",CK_SYSINI,"\"",NULL);
- makestr(&(optlist[noptlist++]),line);
-#else
- makestr(&(optlist[noptlist++]),"CK_SYSINI");
-#endif /* CK_INI_B */
-#endif /* CK_INI_A */
-#endif /* CK_DSYSINI */
-#ifdef CK_DSYSINI
- makestr(&(optlist[noptlist++]),"CK_DSYSINI");
-#endif /* CK_DSYSINI */
-#ifdef CK_TTGWSIZ
- makestr(&(optlist[noptlist++]),"CK_TTGWSIZ");
-#endif /* CK_TTGWSIZ */
-#ifdef CK_NAWS
- makestr(&(optlist[noptlist++]),"CK_NAWS");
-#endif /* CK_NAWS */
-#ifdef MDMHUP
- makestr(&(optlist[noptlist++]),"MDMHUP");
-#endif /* MDMHUP */
-#ifdef HUP_CLOSE_POSIX
- makestr(&(optlist[noptlist++]),"HUP_CLOSE_POSIX");
-#endif /* HUP_CLOSE_POSIX */
-#ifdef NO_HUP_CLOSE_POSIX
- makestr(&(optlist[noptlist++]),"NO_HUP_CLOSE_POSIX");
-#endif /* NO_HUP_CLOSE_POSIX */
-#ifdef DCMDBUF
- makestr(&(optlist[noptlist++]),"DCMDBUF");
-#endif /* DCMDBUF */
-#ifdef CK_RECALL
- makestr(&(optlist[noptlist++]),"CK_RECALL");
-#endif /* CK_RECALL */
-#ifdef BROWSER
- makestr(&(optlist[noptlist++]),"BROWSER");
-#endif /* BROWSER */
-#ifdef CLSOPN
- makestr(&(optlist[noptlist++]),"CLSOPN");
-#endif /* CLSOPN */
-#ifdef STRATUS
- makestr(&(optlist[noptlist++]),"STRATUS");
-#endif /* STRATUS */
-#ifdef __VOS__
- makestr(&(optlist[noptlist++]),"__VOS__");
-#endif /* __VOS__ */
-#ifdef STRATUSX25
- makestr(&(optlist[noptlist++]),"STRATUSX25");
-#endif /* STRATUSX25 */
-#ifdef OS2MOUSE
- makestr(&(optlist[noptlist++]),"OS2MOUSE");
-#endif /* OS2MOUSE */
-#ifdef CK_REXX
- makestr(&(optlist[noptlist++]),"CK_REXX");
-#endif /* CK_REXX */
-#ifdef CK_TIMERS
- makestr(&(optlist[noptlist++]),"CK_TIMERS");
-#endif /* CK_TIMERS */
-#ifdef TTSPDLIST
- makestr(&(optlist[noptlist++]),"TTSPDLIST");
-#endif /* TTSPDLIST */
-#ifdef CK_PERMS
- makestr(&(optlist[noptlist++]),"CK_PERMS");
-#endif /* CK_PERMS */
-#ifdef CKTUNING
- makestr(&(optlist[noptlist++]),"CKTUNING");
-#endif /* CKTUNING */
-#ifdef NEWFTP
- makestr(&(optlist[noptlist++]),"NEWFTP");
-#endif /* NEWFTP */
-#ifdef SYSFTP
- makestr(&(optlist[noptlist++]),"SYSFTP");
-#endif /* SYSFTP */
-#ifdef NOFTP
- makestr(&(optlist[noptlist++]),"NOFTP");
-#endif /* NOFTP */
-#ifdef CKHTTP
- makestr(&(optlist[noptlist++]),"CKHTTP");
-#endif /* CKHTTP */
-#ifdef NOHTTP
- makestr(&(optlist[noptlist++]),"NOHTTP");
-#endif /* NOHTTP */
-#ifdef CKROOT
- makestr(&(optlist[noptlist++]),"CKROOT");
-#endif /* CKROOT */
-#ifdef CKREALPATH
- makestr(&(optlist[noptlist++]),"CKREALPATH");
-#endif /* CKREALPATH */
-#ifdef STREAMING
- makestr(&(optlist[noptlist++]),"STREAMING");
-#endif /* STREAMING */
-#ifdef UNPREFIXZERO
- makestr(&(optlist[noptlist++]),"UNPREFIXZERO");
-#endif /* UNPREFIXZERO */
-#ifdef CKREGEX
- makestr(&(optlist[noptlist++]),"CKREGEX");
-#endif /* CKREGEX */
-#ifdef ZXREWIND
- makestr(&(optlist[noptlist++]),"ZXREWIND");
-#endif /* ZXREWIND */
-#ifdef CKSYSLOG
- makestr(&(optlist[noptlist++]),"CKSYSLOG");
-#endif /* CKSYSLOG */
-#ifdef SYSLOGLEVEL
- sprintf(line,"SYSLOGLEVEL=%d",SYSLOGLEVEL); /* SAFE */
- makestr(&(optlist[noptlist++]),line);
-#endif /* SYSLOGLEVEL */
-#ifdef NOSEXP
- makestr(&(optlist[noptlist++]),"NOSEXP");
-#endif /* NOSEXP */
-#ifdef CKLEARN
- makestr(&(optlist[noptlist++]),"CKLEARN");
-#else
-#ifdef NOLOEARN
- makestr(&(optlist[noptlist++]),"NOLOEARN");
-#endif /* NOLOEARN */
-#endif /* CKLEARN */
-
-#ifdef NOFLOAT
- makestr(&(optlist[noptlist++]),"NOFLOAT");
-#else
-#ifdef FNFLOAT
- makestr(&(optlist[noptlist++]),"FNFLOAT");
-#endif /* FNFLOAT */
-#ifdef CKFLOAT
-#ifdef GFTIMER
- makestr(&(optlist[noptlist++]),"GFTIMER");
-#endif /* GFTIMER */
-#ifdef CKFLOAT_S
- ckmakmsg(line,LINBUFSIZ,"CKFLOAT=",CKFLOAT_S,NULL,NULL);
- makestr(&(optlist[noptlist++]),line);
-#else
- makestr(&(optlist[noptlist++]),"CKFLOAT");
-#endif /* CKFLOAT_S */
-#endif /* CKFLOAT */
-#endif /* NOFLOAT */
-
-#ifdef SSH
- makestr(&(optlist[noptlist++]),"SSH");
-#endif /* SSH */
-#ifdef NETDLL
- makestr(&(optlist[noptlist++]),"NETDLL");
-#endif /* NETDLL */
-#ifdef NETFILE
- makestr(&(optlist[noptlist++]),"NETFILE");
-#endif /* NETFILE */
-#ifdef CK_TAPI
- makestr(&(optlist[noptlist++]),"CK_TAPI");
-#endif /* CK_TAPI */
-#ifdef CK_SSL
- makestr(&(optlist[noptlist++]),"CK_SSL");
-#ifdef OPENSSL_VERSION_TEXT
- ckmakmsg(line,LINBUFSIZ,
- "OPENSSL_VERSION_TEXT=","\"",OPENSSL_VERSION_TEXT,"\"");
- makestr(&(optlist[noptlist++]),line);
-#endif /* OPENSSL_VERSION_TEXT */
-#endif /* CK_SSL */
- debug(F101,"initoptlist noptlist","",noptlist);
- sh_sort(optlist,NULL,noptlist,0,0,0);
-}
-
-int
-shofea() {
- int i;
- int flag = 0;
- int lines = 1;
-#ifdef FNFLOAT
- extern int fp_digits, fp_rounding;
-#endif /* FNFLOAT */
- extern int byteorder;
- printf("%s\n",versio);
- if (inserver)
- return(1);
-
- debug(F101,"shofea NOPTLIST","",NOPTLIST);
- initoptlist();
- debug(F101,"shofea noptlist","",noptlist);
-#ifdef OS2
-#ifdef NT
-#ifdef _M_ALPHA
- printf("Microsoft Windows Operating Systems for Alpha CPUs.\n");
-#else /* _M_ALPHA */
-#ifdef _M_PPC
- printf("Microsoft Windows Operating Systems for PowerPC CPUs.\n");
-#else /* _M_PPC */
-#ifdef _M_MRX000
- printf("Microsoft Windows Operating Systems for MIPS CPUs.\n");
-#else /* _M_MRX000 */
-#ifdef _M_IX86
- printf("Microsoft Windows Operating Systems for 32-bit Intel CPUs.\n");
-#else /* _M_IX86 */
- UNKNOWN WINDOWS PLATFORM
-#endif /* _M_IX86 */
-#endif /* _M_MRX000 */
-#endif /* _M_PPC */
-#endif /* _M_ALPHA */
-#else /* NT */
-#ifdef M_I286
- printf("IBM OS/2 16-bit.\n");
-#else
- printf("IBM OS/2 32-bit.\n");
-#endif /* M_I286 */
-#endif /* NT */
- lines++;
-#endif /* OS2 */
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf("Major optional features included:\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-
- if (sizeof(CK_OFF_T) == 8) {
- printf(" Large files and large integers (64 bits)\n");
- if (++lines > cmd_rows - 3) {
- if (!askmore()) return(1); else lines = 0;
- }
- }
-#ifdef NETCONN
- printf(" Network support (type SHOW NET for further info)\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#ifdef IKS_OPTION
- printf(" Telnet Kermit Option\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* IKS_OPTION */
-#ifdef CK_AUTHENTICATION
- printf(" Telnet Authentication Option\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#ifdef CK_KERBEROS
-#ifdef KRB4
-#ifdef KRB5
- printf(" Kerberos(TM) IV and Kerberos V authentication\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#else /* KRB5 */
- printf(" Kerberos(TM) IV authentication\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* KRB5 */
-#else /* KRB4 */
-#ifdef KRB5
- printf(" Kerberos(TM) V authentication\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* KRB5 */
-#endif /* KRB4 */
-#endif /* CK_KERBEROS */
-#ifdef CK_SRP
- printf(" SRP(TM) (Secure Remote Password) authentication\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_SRP */
-#ifdef CK_SSL
- printf(" Secure Sockets Layer (SSL)\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" Transport Layer Security (TLS)\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_SSL */
-#ifdef SSHBUILTIN
- printf(" Secure Shell (SSH) [internal]\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* SSHBUILTIN */
-#ifdef SSHCMD
- printf(" Secure Shell (SSH) [external]\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* SSHCMD */
-#ifdef CK_ENCRYPTION
- printf(" Telnet Encryption Option\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#ifdef CK_DES
- printf(" Telnet DES Encryption\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_DES */
-#ifdef CK_CAST
- printf(" Telnet CAST Encryption\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_CAST */
-
-#ifdef CK_KERBEROS
-#ifdef KRB5
-#ifdef ALLOW_KRB_3DES_ENCRYPT
- printf(" Kerberos 3DES/AES Telnet Encryption\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* ALLOW_KRB_3DES_ENCRYPT */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#endif /* CK_ENCRYPTION */
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_FORWARD_X
- printf(" X Windows forwarding\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_FORWARD_X */
-#ifdef TN_COMPORT
- printf(" Telnet Remote Com Port Control Option\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* TN_COMPORT */
-#ifdef CK_SOCKS
-#ifdef CK_SOCKS5
- printf(" SOCKS 5\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#else /* CK_SOCKS5 */
- printf(" SOCKS 4\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_SOCKS5 */
-#endif /* CK_SOCKS */
-#ifdef NEWFTP
- printf(" Built-in FTP client\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* NEWFTP */
-#ifdef CKHTTP
- printf(" Built-in HTTP client\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CKHTTP */
-#endif /* NETCONN */
-
-#ifdef CK_RTSCTS
- printf(" Hardware flow control\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_RTSCTS */
-
-#ifdef CK_XYZ
-#ifdef XYZ_INTERNAL
- printf(" Built-in XYZMODEM protocols\n");
-#else
- printf(" External XYZMODEM protocol support\n");
-#endif /* XYZ_INTERNAL */
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_XYZ */
-
-#ifndef NOCSETS
- printf(" Latin-1 (West European) character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#ifdef LATIN2
- printf(" Latin-2 (East European) character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* LATIN2 */
-#ifdef CYRILLIC
- printf(" Cyrillic (Russian, Ukrainian, etc) character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CYRILLIC */
-#ifdef GREEK
- printf(" Greek character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* GREEK */
-#ifdef HEBREW
- printf(" Hebrew character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* HEBREW */
-#ifdef KANJI
- printf(" Japanese character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* KANJI */
-#ifdef UNICODE
- printf(" Unicode character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* UNICODE */
-#ifdef CKOUNI
- if (isunicode())
- printf(" Unicode support for ISO-2022 Terminal Emulation\n");
- else
- printf(" Unicode translation for Terminal Character-Sets\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CKOUNI */
-#endif /* NOCSETS */
-
-#ifdef NETPTY
- printf(" Pseudoterminal control\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* NETPTY */
-
-#ifdef CK_REDIR
- printf(" REDIRECT command\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_REDIR */
-
-#ifdef CK_RESEND
- printf(" RESEND command\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_RESEND */
-
-#ifndef NOXFER
-#ifdef CK_CURSES
- printf(" Fullscreen file transfer display\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_CURSES */
-#endif /* NOXFER */
-
-#ifdef CK_SPEED
- printf(" Control-character unprefixing\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_SPEED */
-
-#ifdef STREAMING
- printf(" Streaming\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* STREAMING */
-
-#ifdef CK_AUTODL
- printf(" Autodownload\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_AUTODL */
-
-#ifdef OS2MOUSE
- printf(" Mouse support\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* OS2MOUSE */
-
-#ifdef CK_REXX
- printf(" REXX script language interface\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_REXX */
-
-#ifdef IKSD
-#ifdef CK_LOGIN
- printf(" Internet Kermit Service with user login support\n");
-#else /* CK_LOGIN */
- printf(" Internet Kermit Service without user login support\n");
-#endif /* CK_LOGIN */
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* IKSD */
-
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf("Major optional features not included:\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-
- if (sizeof(CK_OFF_T) <= 4) {
- printf(" No large files or large integers\n");
- if (++lines > cmd_rows - 3) {
- if (!askmore()) return(1); else lines = 0;
- }
- }
-
-#ifdef NOXFER
- printf(" No file-transfer protocols\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#else
-#ifndef CK_CURSES
-#ifndef MAC
- printf(" No fullscreen file transfer display\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* MAC */
-#endif /* CK_CURSES */
-
-#ifdef NOSERVER
- printf(" No server mode\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOSERVER */
-
-#ifndef CK_SPEED
- printf(" No control-character unprefixing\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* CK_SPEED */
-
-#ifndef STREAMING
- printf(" No streaming\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* STREAMING */
-
-#ifndef CK_AUTODL
- printf(" No autodownload\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* CK_AUTODL */
-
-#ifndef CK_XYZ
- printf(" No built-in XYZMODEM protocols\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* CK_XYZ */
-
-#ifdef NOFLOAT
- printf(" No floating-point arithmetic\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
- printf(" No S-Expressions (LISP interpreter)\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#else
-#ifdef NOSEXP
- printf(" No S-Expressions (LISP interpreter)\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOSEXP */
-#endif /* NOFLOAT */
-
-#ifdef NOTLOG
- printf(" No transaction log\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOTLOG */
-#endif /* NOXFER */
-
-#ifdef NODEBUG
- printf(" No debugging\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NODEBUG */
-
-#ifdef NOHELP
- printf(" No built-in help\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOHELP */
-
-#ifdef NOLOCAL
- printf(" No making connections\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#else
-#ifndef NETCONN
- printf(" No network support\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#else /* NETCONN */
-#ifndef IKS_OPTION
- printf(" No Telnet Kermit Option\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* IKS_OPTION */
-#endif /* NETCONN */
-
-#ifdef NOSSH
- printf(" No Secure Shell (SSH)\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* NOSSH */
-#ifndef CK_AUTHENTICATION
- printf(" No Kerberos(TM) authentication\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" No SRP(TM) (Secure Remote Password) protocol\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" No Secure Sockets Layer (SSL) protocol\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" No Transport Layer Security (TLS) protocol\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" No encryption\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#else /* CK_AUTHENTICATION */
-#ifndef CK_KERBEROS
- printf(" No Kerberos(TM) authentication\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#else /* CK_KERBEROS */
-#ifndef KRB4
- printf(" No Kerberos(TM) IV authentication\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* KRB4 */
-#ifndef KRB5
- printf(" No Kerberos(TM) V authentication\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-#ifndef CK_SRP
- printf(" No SRP(TM) (Secure Remote Password) authentication\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* CK_SRP */
-#ifndef CK_SSL
- printf(" No Secure Sockets Layer (SSL) protocol\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" No Transport Layer Security (TLS) protocol\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* CK_SSL */
-#ifndef CK_ENCRYPTION
- printf(" No Telnet Encryption Option\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#else /* CK_ENCRYPTION */
-#ifndef OS2
-#ifndef CK_DES
- printf(" No Telnet DES encryption\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* CK_DES */
-#ifndef CK_CAST
- printf(" No Telnet CAST encryption\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* CK_CAST */
-
-#ifdef COMMENT
-#ifdef CK_KERBEROS
-#ifdef KRB5
-#ifndef ALLOW_KRB_3DES_ENCRYPT
- printf(" No Kerberos 3DES/AES Telnet Encryption\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* ALLOW_KRB_3DES_ENCRYPT */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-#endif /* COMMENT */
-
-#endif /* OS2 */
-#endif /* CK_ENCRYPTION */
-#endif /* CK_AUTHENTICATION */
-#ifndef CK_FORWARD_X
- printf(" No X Windows forwarding\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_FORWARD_X */
-#ifndef TN_COMPORT
- printf(" No Telnet Remote Com Port Control Option\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* TN_COMPORT */
-#ifndef CK_SOCKS
- printf(" No SOCKS\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_SOCKS */
-#ifndef NEWFTP
- printf(" No built-in FTP client\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* NEWFTP */
-#ifdef NOHTTP
- printf(" No built-in HTTP client\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* NOHTTP */
-
-#ifdef NODIAL
- printf(" No DIAL command\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#else
-#ifdef MINIDIAL
- printf(" Support for most modem types excluded\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* MINIDIAL */
-#endif /* NODIAL */
-#endif /* NOLOCAL */
-
-#ifndef CK_RTSCTS
-#ifndef MAC
- printf(" No hardware flow control\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* MAC */
-#endif /* CK_RTSCTS */
-
-#ifdef NOXMIT
- printf(" No TRANSMIT command\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOXMIT */
-
-#ifdef NOSCRIPT
- printf(" No SCRIPT command\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOSCRIPT */
-
-#ifdef NOSPL
- printf(" No script programming features\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOSPL */
-
-#ifdef NOCSETS
- printf(" No character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#else
-
-#ifndef LATIN2
- printf(" No Latin-2 character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* LATIN2 */
-
-#ifdef NOGREEK
- printf(" No Greek character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOGREEK */
-
-#ifdef NOHEBREW
- printf(" No Hebrew character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOHEBREW */
-
-#ifdef NOUNICODE
- printf(" No Unicode character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOUNICODE */
-
-#ifdef NOCYRIL
- printf(" No Cyrillic character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOCYRIL */
-
-#ifndef KANJI
- printf(" No Kanji character-set translation\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* KANJI */
-#endif /* NOCSETS */
-
-#ifdef NOCMDL
- printf(" No command-line arguments\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOCMDL */
-
-#ifdef NOPUSH
- printf(" No escape to system\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOPUSH */
-
-#ifdef NOJC
-#ifdef UNIX
- printf(" No UNIX job control\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* UNIX */
-#endif /* NOJC */
-
-#ifdef NOSETKEY
- printf(" No SET KEY command\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NOSETKEY */
-
-#ifndef CK_REDIR
- printf(" No REDIRECT or PIPE command\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* CK_REDIR */
-
-#ifdef UNIX
-#ifndef NETPTY
- printf(" No pseudoterminal control\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* NETPTY */
-#endif /* UNIX */
-
-#ifndef CK_RESEND
- printf(" No RESEND command\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* CK_RESEND */
-
-#ifdef OS2
-#ifdef __32BIT__
-#ifndef OS2MOUSE
- printf(" No Mouse support\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* __32BIT__ */
-#endif /* OS2 */
-#endif /* OS2MOUSE */
-
-#ifdef OS2
-#ifndef NT
-#ifndef CK_REXX
- printf(" No REXX script language interface\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* CK_REXX */
-#endif /* NT */
-#endif /* OS2 */
-
-#ifndef IKSD
- printf(" No Internet Kermit Service\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- flag = 1;
-#endif /* IKSD */
-
- if (flag == 0) {
- printf(" None\n");
- if (++lines > cmd_rows - 3)
- { if (!askmore()) return(1); else lines = 0; }
- }
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-
-#ifdef CK_UTSNAME
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf("Host info:\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" Machine: %s\n",unm_mch[0] ? unm_mch : "(unknown)");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" Model: %s\n",unm_mod[0] ? unm_mod : "(unknown)");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" OS: %s\n",unm_nam[0] ? unm_nam : "(unknown)");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" OS Release: %s\n",unm_rel[0] ? unm_rel : "(unknown)");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf(" OS Version: %s\n",unm_ver[0] ? unm_ver : "(unknown)");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
- printf("\n");
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* CK_UTSNAME */
-
-/*
- Print compile-time (-D) options, as well as C preprocessor
- predefined symbols that might affect us...
-*/
-#ifdef KTARGET
- {
- char * s; /* Makefile target */
- s = KTARGET;
- if (!s) s = "";
- if (!*s) s = "(unknown)";
- printf("\n");
- if (++lines > cmd_rows - 3) {
- if (!askmore()) return(1); else lines = 0;
- }
- printf("Target: %s\n", s);
- if (++lines > cmd_rows - 3) {
- if (!askmore()) return(1); else lines = 0;
- }
- }
-#endif /* KTARGET */
-
-#ifdef __VERSION__
-#ifdef __GNUC__
- printf("GCC version: %s\n", __VERSION__);
-#else
- printf("Compiler version: %s\n", __VERSION__);
-#endif /* __GNUC__ */
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-#endif /* __VERSION__ */
-
-#ifdef __DATE__ /* GNU and other ANSI */
-#ifdef __TIME__
- printf("Compiled %s %s, options:\n", __DATE__, __TIME__);
-#else
- printf("Compiled %s, options:\n", __DATE__);
-#endif /* __TIME__ */
-#else /* !__DATE__ */
- printf("Compiler options:\n");
-#endif /* __DATE__ */
- if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
-
- for (i = 0; i < noptlist; i++) /* Print sorted option list */
- if (!prtopt(&lines,optlist[i]))
- return(0);
-
- if (!prtopt(&lines,"")) return(0); /* Start a new section */
-
-/* Sizes of data types */
-
- ckmakmsg(line,
- LINBUFSIZ,
- "byte order: ",
- byteorder ? "little" : "big",
- " endian",
- NULL
- );
- {
-/* Whether to use %d or %ld with sizeof is a portability issue, so... */
- int size = 0;
-
- if (!prtopt(&lines,line)) return(0);
- if (!prtopt(&lines,"")) return(0); /* Start a new section */
-
- size = (int)sizeof(int);
- sprintf(line,"sizeofs: int=%d",size); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
-
- size = (int)sizeof(long);
- sprintf(line,"long=%d",size); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
-
-#ifndef OS2
- /* Windows doesn't have off_t */
- size = (int)sizeof(off_t);
- sprintf(line,"off_t=%d",size); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
-#endif /* OS2 */
-
- size = (int)sizeof(CK_OFF_T);
- sprintf(line,"CK_OFF_T=%d",size); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
-
-#ifdef BIGBUFOK
- size = (int)sizeof(size_t);
- sprintf(line,"size_t=%d",size); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
-#endif /* BIGBUFOK */
-
- size = (int)sizeof(short);
- sprintf(line,"short=%d",size); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
-
- size = (int)sizeof(char);
- sprintf(line,"char=%d",size); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
-
- size = (int)sizeof(char *);
- sprintf(line,"char*=%d",size); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
-
- size = (int)sizeof(float);
- sprintf(line,"float=%d",size); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
-
- size = (int)sizeof(double);
- sprintf(line,"double=%d",size); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
- }
-
-#ifdef FNFLOAT
- if (!prtopt(&lines,"")) return(0); /* Start a new section */
- if (!prtopt(&lines,"floating-point:")) return(0);
- sprintf(line,"precision=%d",fp_digits); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
- sprintf(line,"rounding=%d",fp_rounding); /* SAFE */
- if (!prtopt(&lines,line)) return(0);
-#endif /* FNFLOAT */
-
- prtopt(&lines,"");
- return(0);
-}
-#endif /* NOSHOW */
-#endif /* NOICP */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus6.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuus6.c
deleted file mode 100644
index a4990c6..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus6.c
+++ /dev/null
@@ -1,12009 +0,0 @@
-#include "ckcsym.h"
-#ifndef NOICP
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/* Includes */
-
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckuusr.h"
-#include "ckcxla.h"
-#include "ckcnet.h" /* Network symbols */
-#include <signal.h>
-
-#ifndef NOSTAT
-#ifdef VMS
-/* 2010-03-09 SMS. VAX C needs help to find "sys". It's easier not to try. */
-#include <stat.h>
-#else /* def VMS */
-#include <sys/stat.h>
-#endif /* def VMS [else] */
-#endif /* NOSTAT */
-
-#ifdef VMS
-#ifndef TCPSOCKET
-#include <errno.h>
-#endif /* TCPSOCKET */
-#endif /* VMS */
-
-#ifdef datageneral
-#define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
-#endif /* datageneral */
-
-#ifdef QNX6
-#define readblock kreadblock
-#endif /* QNX6 */
-
-/* External Kermit Variables, see ckmain.c for description. */
-
-extern xx_strp xxstring;
-
-extern int local, xitsta, binary, parity, escape, flow, cmd_rows, turn,
- turnch, duplex, ckxech, seslog, dfloc, cnflg, tlevel, pflag, msgflg, mdmtyp,
- zincnt, quiet, repars, techo, network, nzxopts, what, filepeek, recursive;
-
-extern int xaskmore, tt_rows, tt_cols, cmd_cols, g_matchdot, diractive,
- xcmdsrc, nscanfile, reliable, nolinks, cmflgs;
-
-#ifdef VMSORUNIX
-extern int zgfs_dir, zgfs_link;
-#endif /* VMSORUNIX */
-
-#ifdef CK_IFRO
- extern int remonly;
-#endif /* CK_IFRO */
-
-#ifdef OS2
-extern int StartedFromDialer ;
-extern int vmode;
-extern int k95stdout;
-#ifndef NT
-#define INCL_NOPM
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#else
-#define APIRET ULONG
-#include <windows.h>
-#include <tapi.h>
-#include "ckntap.h"
-#endif /* NT */
-#include "ckocon.h"
-#endif /* OS2 */
-
-extern long vernum, speed;
-extern char *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
-extern char *dialv, *loginv, *for_def[], *whil_def[], *xif_def[], *sw_def[];
-extern char *foz_def[];
-extern char *ckxsys, *ckzsys;
-#ifndef OS2
-extern char *DIRCMD;
-#ifndef UNIX
-extern char *DELCMD;
-#endif /* UNIX */
-#endif /* OS2 */
-extern char ttname[], filnam[];
-extern CHAR sstate, feol;
-extern char *zinptr;
-
-#ifdef UNIX
-extern char ** mtchs; /* zxpand() file list */
-#endif /* UNIX */
-
-#ifndef NOXFER
-extern int oopts, omode, oname, opath; /* O-Packet options */
-
-extern int stdinf, sndsrc, size, rpsiz, urpsiz, fncnv, fnrpath, displa,
- stdouf, isguest, pktlog, nfils, keep, maxrps, fblksiz, frecl, frecfm,
- atcapr, atdiso, spsizf, spsiz, spsizr, spmax, wslotr, prefixing,
- fncact, fnspath, nprotos, g_proto, g_urpsiz, g_spsizf,
- g_spsiz, g_spsizr, g_spmax, g_wslotr, g_prefixing, g_fncact, g_fncnv,
- g_fnspath, g_fnrpath, xfrxla, g_xfrxla;
-
-extern char *cmarg, *cmarg2;
-
-#ifndef NOMSEND /* Multiple SEND */
-extern char *msfiles[];
-#endif /* NOMSEND */
-extern char fspec[]; /* Most recent filespec */
-extern int fspeclen;
-
-#ifdef CK_TMPDIR
-extern int f_tmpdir; /* Directory changed temporarily */
-extern char savdir[]; /* For saving current directory */
-#endif /* CK_TMPDIR */
-
-extern struct keytab protos[]; /* File transfer protocols */
-extern struct ck_p ptab[NPROTOS];
-#endif /* NOXFER */
-
-#ifdef DCMDBUF /* Declarations from cmd package */
-extern char *cmdbuf, *atmbuf; /* Command buffers */
-#else
-extern char cmdbuf[], atmbuf[]; /* Command buffers */
-#endif /* DCMDBUF */
-
-extern int nopush;
-
-#ifndef NOSPL
-int askflag = 0; /* ASK-class command active */
-int echostars = 0; /* ASKQ should echo asterisks */
-extern char **a_ptr[];
-extern int a_dim[];
-extern char **m_xarg[];
-extern int n_xarg[];
-extern struct mtab *mactab;
-extern int nmac;
-extern long ck_alarm;
-extern char alrm_date[], alrm_time[];
-extern int x_ifnum;
-#endif /* NOSPL */
-
-extern int inserver; /* I am IKSD */
-extern int backgrd; /* Kermit executing in background */
-extern char psave[]; /* For saving & restoring prompt */
-extern char *tp; /* Temporary buffer */
-
-int readblock = 4096; /* READ buffer size */
-CHAR * readbuf = NULL; /* Pointer to read buffer */
-int readsize = 0; /* Number of chars actually read */
-int getcmd = 0; /* GET-class command was given */
-
-extern int zchkod, zchkid;
-
-/* C K U U S 6 -- "User Interface" for Unix Kermit (Part 6) */
-
-struct keytab deltab[] = { /* DELETE Command Options */
- { "/all", DEL_ALL, CM_INV },
- { "/after", DEL_AFT, CM_ARG },
- { "/ask", DEL_ASK, 0 },
- { "/before", DEL_BEF, CM_ARG },
- { "/directories", DEL_DIR, 0 },
- { "/dotfiles", DEL_DOT, 0 },
- { "/except", DEL_EXC, CM_ARG },
- { "/heading", DEL_HDG, 0 },
- { "/l", DEL_LIS, CM_INV|CM_ABR },
- { "/larger-than", DEL_LAR, CM_ARG },
- { "/list", DEL_LIS, 0 },
- { "/log", DEL_LIS, CM_INV },
- { "/noask", DEL_NAS, 0 },
- { "/nodotfiles", DEL_NOD, 0 },
- { "/noheading", DEL_NOH, 0 },
- { "/nol", DEL_NOL, CM_INV|CM_ABR },
- { "/nolist", DEL_NOL, 0 },
- { "/nolog", DEL_NOL, CM_INV },
- { "/nopage", DEL_NOP, 0 },
- { "/not-after", DEL_NAF, CM_ARG },
- { "/not-before", DEL_NBF, CM_ARG },
- { "/not-since", DEL_NAF, CM_INV|CM_ARG },
- { "/page", DEL_PAG, 0 },
- { "/quiet", DEL_QUI, CM_INV },
- { "/recursive", DEL_REC, 0 },
- { "/simulate", DEL_SIM, 0 },
- { "/since", DEL_AFT, CM_ARG|CM_INV },
- { "/smaller-than", DEL_SMA, CM_ARG },
- { "/summary", DEL_SUM, 0 },
- { "/tree", DEL_ALL, 0 },
- { "/type", DEL_TYP, CM_ARG },
- { "/verbose", DEL_VRB, CM_INV }
-};
-int ndeltab = sizeof(deltab)/sizeof(struct keytab);
-
-/* /QUIET-/VERBOSE (/LIST-/NOLIST) (/LOG-/NOLOG) table */
-
-struct keytab qvswtab[] = {
- { "/l", DEL_LIS, CM_INV|CM_ABR },
- { "/list", DEL_LIS, 0 },
- { "/log", DEL_LIS, CM_INV },
- { "/nol", DEL_NOL, CM_INV|CM_ABR },
- { "/nolist", DEL_NOL, 0 },
- { "/nolog", DEL_NOL, CM_INV },
- { "/quiet", DEL_QUI, CM_INV },
- { "/verbose", DEL_VRB, CM_INV }
-};
-int nqvswtab = sizeof(qvswtab)/sizeof(struct keytab);
-
-static struct keytab renamsw[] = {
- { "/collision", REN_OVW, CM_ARG },
-#ifndef NOUNICODE
- { "/convert", REN_XLA, CM_ARG },
-#endif /* NOUNICODE */
- { "/fixspaces", REN_SPA, CM_ARG },
- { "/l", DEL_LIS, CM_INV|CM_ABR },
- { "/list", DEL_LIS, 0 },
- { "/log", DEL_LIS, CM_INV },
- { "/lower", REN_LOW, CM_ARG },
- { "/nol", DEL_NOL, CM_INV|CM_ABR },
- { "/nolist", DEL_NOL, 0 },
- { "/nolog", DEL_NOL, CM_INV },
- { "/quiet", DEL_QUI, CM_INV },
- { "/replace", REN_RPL, CM_ARG },
- { "/simulate", DEL_SIM, 0 },
- { "/upper", REN_UPP, CM_ARG },
- { "/verbose", DEL_VRB, CM_INV }
-};
-static int nrenamsw = sizeof(renamsw)/sizeof(struct keytab);
-
-static struct keytab renamset[] = {
- { "collision", REN_OVW, 0 },
- { "list", DEL_LIS, 0 }
-};
-static int nrenamset = sizeof(renamset)/sizeof(struct keytab);
-
-/* Args for RENAME /LOWER: and /UPPER: */
-
-static struct keytab r_upper[] = {
- { "all", 1, 0 },
- { "lower", 0, 0 }
-};
-
-static struct keytab r_lower[] = {
- { "all", 1, 0 },
- { "upper", 0, 0 }
-};
-
-/* Args for RENAME /COLLISION... */
-
-#define RENX_FAIL 0
-#define RENX_OVWR 1
-#define RENX_SKIP 2
-
-static struct keytab r_collision[] = {
- { "fail", RENX_FAIL, 0 },
- { "overwrite", RENX_OVWR, 0 },
- { "proceed", RENX_SKIP, CM_INV },
- { "skip", RENX_SKIP, 0 }
-};
-static int nr_collision = sizeof(r_collision)/sizeof(struct keytab);
-
-struct keytab copytab[] = {
- { "/append", 998, 0 },
-#ifndef NOSPL
- { "/fromb64", 997, 0 },
-#endif /* NOSPL */
- { "/l", DEL_LIS, CM_INV|CM_ABR },
- { "/list", DEL_LIS, 0 },
- { "/log", DEL_LIS, CM_INV },
- { "/nol", DEL_NOL, CM_INV|CM_ABR },
- { "/nolist", DEL_NOL, 0 },
- { "/nolog", DEL_NOL, CM_INV },
- { "/overwrite", 994, CM_ARG },
-#ifndef NOXFER
- { "/preserve", 995, 0 },
-#endif /* NOXFER */
- { "/quiet", DEL_QUI, CM_INV },
- { "/swap-bytes", 999, 0 },
-#ifndef NOSPL
- { "/tob64", 996, 0 },
-#endif /* NOSPL */
- { "/verbose", DEL_VRB, CM_INV }
-};
-int ncopytab = sizeof(copytab)/sizeof(struct keytab);
-
-#define OVW_ALWAYS 0
-#define OVW_NEVER 1
-#define OVW_OLDER 2
-#define OVW_NEWER 3
-
-static struct keytab ovwtab[] = {
- { "always", OVW_ALWAYS, 0 },
- { "never", OVW_NEVER, 0 },
- { "newer", OVW_NEWER, 0 },
- { "older", OVW_OLDER, 0 }
-};
-static int novwtab = 4;
-
-#ifndef NOXFER
-static struct keytab gettab[] = { /* GET options */
- { "/as-name", SND_ASN, CM_ARG },
- { "/binary", SND_BIN, 0 },
-#ifdef CALIBRATE
- { "/calibrate", SND_CAL, CM_INV },
-#endif /* CALIBRATE */
-#ifdef PIPESEND
- { "/command", SND_CMD, CM_PSH },
-#endif /* PIPESEND */
- { "/delete", SND_DEL, 0 },
- { "/except", SND_EXC, CM_ARG },
- { "/filenames", SND_NAM, CM_ARG },
-#ifdef PIPESEND
- { "/filter", SND_FLT, CM_ARG|CM_PSH },
-#endif /* PIPESEND */
-#ifdef VMS
- { "/image", SND_IMG, 0 },
- { "/labeled", SND_LBL, 0 },
-#else
- { "/image", SND_BIN, CM_INV },
-#endif /* VMS */
-#ifdef CK_TMPDIR
- { "/move-to", SND_MOV, CM_ARG },
-#endif /* CK_TMPDIR */
- { "/pathnames", SND_PTH, CM_ARG },
- { "/pipes", SND_PIP, CM_ARG|CM_PSH },
- { "/quiet", SND_SHH, 0 },
-#ifdef CK_RESEND
- { "/recover", SND_RES, 0 },
-#endif /* CK_RESEND */
- { "/recursive", SND_REC, 0 },
- { "/rename-to", SND_REN, CM_ARG },
-#ifdef COMMENT
- { "/smaller-than", SND_SMA, CM_ARG },
-#endif /* COMMENT */
- { "/subdirectories", SND_REC, CM_INV },
- { "/text", SND_TXT, 0 },
- { "/transparent", SND_XPA, 0 }
-};
-#define NGETTAB sizeof(gettab)/sizeof(struct keytab)
-static int ngettab = NGETTAB;
-
-static struct keytab rcvtab[] = { /* RECEIVE options */
- { "/as-name", SND_ASN, CM_ARG },
- { "/binary", SND_BIN, 0 },
-#ifdef CALIBRATE
- { "/calibrate", SND_CAL, CM_INV },
-#endif /* CALIBRATE */
-#ifdef PIPESEND
- { "/command", SND_CMD, CM_PSH },
-#endif /* PIPESEND */
- { "/except", SND_EXC, CM_ARG },
- { "/filenames", SND_NAM, CM_ARG },
-#ifdef PIPESEND
- { "/filter", SND_FLT, CM_ARG|CM_PSH },
-#endif /* PIPESEND */
-#ifdef VMS
- { "/image", SND_IMG, 0 },
- { "/labeled", SND_LBL, 0 },
-#else
- { "/image", SND_BIN, CM_INV },
-#endif /* VMS */
-#ifdef CK_TMPDIR
- { "/move-to", SND_MOV, CM_ARG },
-#endif /* CK_TMPDIR */
- { "/pathnames", SND_PTH, CM_ARG },
- { "/pipes", SND_PIP, CM_ARG|CM_PSH },
-#ifdef CK_XYZ
- { "/protocol", SND_PRO, CM_ARG },
-#else
- { "/protocol", SND_PRO, CM_ARG|CM_INV },
-#endif /* CK_XYZ */
- { "/quiet", SND_SHH, 0 },
- { "/recursive", SND_REC, 0 },
- { "/rename-to", SND_REN, CM_ARG },
- { "/text", SND_TXT, 0 },
- { "/transparent", SND_XPA, 0 }
-};
-#define NRCVTAB sizeof(rcvtab)/sizeof(struct keytab)
-static int nrcvtab = NRCVTAB;
-#endif /* NOXFER */
-
-/* WAIT table */
-
-#define WAIT_FIL 997
-#define WAIT_MDM 998
-
-struct keytab waittab[] = {
- { "cd", BM_DCD, CM_INV }, /* (Carrier Detect) */
- { "cts", BM_CTS, CM_INV }, /* (Clear To Send) */
- { "dsr", BM_DSR, CM_INV }, /* (Data Set Ready) */
- { "file", WAIT_FIL, 0 }, /* New category selector keywords */
- { "modem-signals", WAIT_MDM, 0 }, /* ... */
- { "ri", BM_RNG, CM_INV } /* (Ring Indicator) */
-};
-int nwaittab = (sizeof(waittab) / sizeof(struct keytab));
-
-/* Modem signal table */
-
-struct keytab mstab[] = {
- { "cd", BM_DCD, 0 }, /* Carrier Detect */
- { "cts", BM_CTS, 0 }, /* Clear To Send */
- { "dsr", BM_DSR, 0 }, /* Data Set Ready */
- { "ri", BM_RNG, 0 } /* Ring Indicator */
-};
-int nms = (sizeof(mstab) / sizeof(struct keytab));
-
-#define WF_MOD 1
-#define WF_DEL 2
-#define WF_CRE 3
-
-struct keytab wfswi[] = { /* WAIT FILE switches */
- { "creation", WF_CRE, 0 }, /* Wait for file to be created */
- { "deletion", WF_DEL, 0 }, /* Wait for file to be deleted */
- { "modification", WF_MOD, 0 } /* Wait for file to be modified */
-};
-int nwfswi = (sizeof(wfswi) / sizeof(struct keytab));
-
-#ifndef NOSPL
-struct keytab asgtab[] = { /* Assignment operators for "." */
- { "::=", 2, 0 }, /* ASSIGN and EVALUATE */
- { ":=", 1, 0 }, /* ASSIGN */
- { "=", 0, 0 } /* DEFINE */
-};
-int nasgtab = (sizeof(asgtab) / sizeof(struct keytab));
-
-struct keytab opntab[] = {
-#ifndef NOPUSH
- { "!read", OPN_PI_R, CM_INV },
- { "!write", OPN_PI_W, CM_INV },
-#endif /* NOPUSH */
- { "append", OPN_FI_A, 0 },
- { "host", OPN_NET, 0 },
-#ifdef OS2
- { "line", OPN_SER, CM_INV },
- { "port", OPN_SER, 0 },
-#else
- { "line", OPN_SER, 0 },
- { "port", OPN_SER, CM_INV },
-#endif /* OS2 */
- { "read", OPN_FI_R, 0 },
- { "write", OPN_FI_W, 0 }
-};
-int nopn = (sizeof(opntab) / sizeof(struct keytab));
-
-/* IF conditions */
-
-#define XXIFCO 0 /* IF COUNT */
-#define XXIFER 1 /* IF ERRORLEVEL */
-#define XXIFEX 2 /* IF EXIST */
-#define XXIFFA 3 /* IF FAILURE */
-#define XXIFSU 4 /* IF SUCCESS */
-#define XXIFNO 5 /* IF NOT */
-#define XXIFDE 6 /* IF DEFINED */
-#define XXIFEQ 7 /* IF EQUAL (strings) */
-#define XXIFAE 8 /* IF = (numbers) */
-#define XXIFLT 9 /* IF < (numbers) */
-#define XXIFGT 10 /* IF > (numbers) */
-#define XXIFLL 11 /* IF Lexically Less Than (strings) */
-#define XXIFLG 12 /* IF Lexically Greater Than (strings) */
-#define XXIFEO 13 /* IF EOF (READ file) */
-#define XXIFBG 14 /* IF BACKGROUND */
-#define XXIFNU 15 /* IF NUMERIC */
-#define XXIFFG 16 /* IF FOREGROUND */
-#define XXIFDI 17 /* IF DIRECTORY */
-#define XXIFNE 18 /* IF NEWER */
-#define XXIFRO 19 /* IF REMOTE-ONLY */
-#define XXIFAL 20 /* IF ALARM */
-#define XXIFSD 21 /* IF STARTED-FROM-DIALER */
-#define XXIFTR 22 /* IF TRUE */
-#define XXIFNT 23 /* IF FALSE */
-#define XXIFTM 24 /* IF TERMINAL-MACRO */
-#define XXIFEM 25 /* IF EMULATION */
-#define XXIFOP 26 /* IF OPEN */
-#define XXIFLE 27 /* IF <= */
-#define XXIFGE 28 /* IF >= */
-#define XXIFIP 29 /* IF INPATH */
-#define XXIFTA 30 /* IF TAPI */
-#define XXIFMA 31 /* IF MATCH */
-#define XXIFFL 32 /* IF FLAG */
-#define XXIFAB 33 /* IF ABSOLUTE */
-#define XXIFAV 34 /* IF AVAILABLE */
-#define XXIFAT 35 /* IF ASKTIMEOUT */
-#define XXIFRD 36 /* IF READABLE */
-#define XXIFWR 37 /* IF WRITEABLE */
-#define XXIFAN 38 /* IF ... AND ... */
-#define XXIFOR 39 /* IF ... OR ... */
-#define XXIFLP 40 /* IF left parenthesis */
-#define XXIFRP 41 /* IF right parenthesis */
-#define XXIFNQ 42 /* IF != (== "NOT =") */
-#define XXIFQU 43 /* IF QUIET */
-#define XXIFCK 44 /* IF C-KERMIT */
-#define XXIFK9 45 /* IF K-95 */
-#define XXIFMS 46 /* IF MS-KERMIT */
-#define XXIFWI 47 /* IF WILD */
-#define XXIFLO 48 /* IF LOCAL */
-#define XXIFCM 49 /* IF COMMAND */
-#define XXIFFP 50 /* IF FLOAT */
-#define XXIFIK 51 /* IF IKS */
-#define XXIFKB 52 /* IF KBHIT */
-#define XXIFKG 53 /* IF KERBANG */
-#define XXIFVE 54 /* IF VERSION */
-#define XXIFDC 55 /* IF DECLARED */
-#define XXIFGU 56 /* IF GUI */
-#define XXIFLN 57 /* IF LINK */
-#define XXIFDB 58 /* IF DEBUG */
-
-struct keytab iftab[] = { /* IF commands */
- { "!", XXIFNO, 0 },
- { "!=", XXIFNQ, 0 },
- { "&&", XXIFAN, 0 },
- { "(", XXIFLP, 0 },
- { ")", XXIFRP, 0 },
- { "<", XXIFLT, 0 },
- { "<=", XXIFLE, 0 },
- { "=", XXIFAE, 0 },
- { "==", XXIFAE, CM_INV },
- { ">", XXIFGT, 0 },
- { ">=", XXIFGE, 0 },
- { "absolute", XXIFAB, 0 },
- { "alarm", XXIFAL, 0 },
- { "and", XXIFAN, 0 },
- { "asktimeout", XXIFAT, 0 },
- { "available", XXIFAV, 0 },
- { "background", XXIFBG, 0 },
- { "c-kermit", XXIFCK, 0 },
- { "command", XXIFCM, 0 },
- { "count", XXIFCO, 0 },
- { "dcl", XXIFDC, CM_INV },
- { "debug", XXIFDB, 0 },
- { "declared", XXIFDC, 0 },
- { "defined", XXIFDE, 0 },
-#ifdef CK_TMPDIR
- { "directory", XXIFDI, 0 },
-#endif /* CK_TMPDIR */
- { "emulation", XXIFEM, 0 },
-#ifdef COMMENT
- { "eof", XXIFEO, 0 },
-#endif /* COMMENT */
- { "equal", XXIFEQ, 0 },
- { "error", XXIFFA, CM_INV },
- { "exist", XXIFEX, 0 },
- { "failure", XXIFFA, 0 },
- { "false", XXIFNT, 0 },
- { "flag", XXIFFL, 0 },
-#ifdef CKFLOAT
- { "float", XXIFFP, 0 },
-#endif /* CKFLOAT */
- { "foreground", XXIFFG, 0 },
-#ifdef OS2
- { "gui", XXIFGU, 0 },
-#else
- { "gui", XXIFGU, CM_INV },
-#endif /* OS2 */
-#ifdef IKSD
- { "iksd", XXIFIK, 0 },
-#else
- { "iksd", XXIFIK, CM_INV },
-#endif /* IKSD */
- { "integer", XXIFNU, CM_INV },
- { "k-95", XXIFK9, 0 },
- { "kbhit", XXIFKB, 0 },
-#ifdef UNIX
- { "kerbang", XXIFKG, 0 },
-#else
- { "kerbang", XXIFKG, CM_INV },
-#endif /* UNIX */
- { "lgt", XXIFLG, 0 },
-#ifdef UNIX
- { "link", XXIFLN, 0 },
-#endif /* UNIX */
- { "llt", XXIFLL, 0 },
- { "local", XXIFLO, 0 },
- { "match", XXIFMA, 0 },
- { "ms-kermit", XXIFMS, CM_INV },
-#ifdef ZFCDAT
- { "newer", XXIFNE, 0 },
-#endif /* ZFCDAT */
- { "not", XXIFNO, 0 },
- { "numeric", XXIFNU, 0 },
- { "ok", XXIFSU, CM_INV },
- { "open", XXIFOP, 0 },
- { "or", XXIFOR, 0 },
- { "quiet", XXIFQU, 0 },
- { "readable", XXIFRD, 0 },
- { "remote-only",XXIFRO, 0 },
- { "started-from-dialer",XXIFSD, CM_INV },
- { "success", XXIFSU, 0 },
- { "tapi", XXIFTA, 0 },
-#ifdef OS2
- { "terminal-macro", XXIFTM, 0 },
-#else
- { "terminal-macro", XXIFTM, CM_INV },
-#endif /* OS2 */
- { "true", XXIFTR, 0 },
- { "version", XXIFVE, 0 },
- { "wild", XXIFWI, 0 },
- { "writeable", XXIFWR, 0 },
- { "||", XXIFOR, 0 },
- { "", 0, 0 }
-};
-int nif = (sizeof(iftab) / sizeof(struct keytab)) - 1;
-
-struct keytab iotab[] = { /* Keywords for IF OPEN */
- { "!read-file", ZRFILE, CM_INV },
- { "!write-file", ZWFILE, CM_INV },
- { "append-file", ZWFILE, CM_INV },
- { "connection", 8888, 0 },
-#ifdef CKLOGDIAL
- { "cx-log", 7777, 0 },
-#endif /* CKLOGDIAL */
- { "debug-log", ZDFILE, 0 },
- { "error", 9999, 0 },
- { "packet-log", ZPFILE, 0 },
- { "read-file", ZRFILE, 0 },
- { "screen", ZSTDIO, 0 },
- { "session-log", ZSFILE, 0 },
- { "transaction-log", ZTFILE, 0 },
- { "write-file", ZWFILE, 0 }
-};
-int niot = (sizeof(iotab) / sizeof(struct keytab));
-#endif /* NOSPL */
-
-/* Variables and prototypes */
-
-_PROTOTYP(static int doymdir,(int));
-_PROTOTYP(static int renameone,(char *,char *,
- int,int,int,int,int,int,int,int,int,int,int));
-
-#ifdef NETCONN
-extern int nnetdir; /* How many network directories */
-#endif /* NETCONN */
-#ifdef CK_SECURITY
-_PROTOTYP(int ck_krb4_is_installed,(void));
-_PROTOTYP(int ck_krb5_is_installed,(void));
-_PROTOTYP(int ck_ntlm_is_installed,(void));
-_PROTOTYP(int ck_srp_is_installed,(void));
-_PROTOTYP(int ck_ssleay_is_installed,(void));
-_PROTOTYP(int ck_ssh_is_installed,(void));
-_PROTOTYP(int ck_crypt_is_installed,(void));
-#else
-#define ck_krb4_is_installed() (0)
-#define ck_krb5_is_installed() (0)
-#define ck_ntlm_is_installed() (0)
-#define ck_srp_is_installed() (0)
-#define ck_ssleay_is_installed() (0)
-#define ck_ssh_is_installed() (0)
-#define ck_crypt_is_installed() (0)
-#endif /* CK_SECURITY */
-
-#define AV_KRB4 1
-#define AV_KRB5 2
-#define AV_NTLM 3
-#define AV_SRP 4
-#define AV_SSL 5
-#define AV_CRYPTO 6
-#define AV_SSH 7
-
-struct keytab availtab[] = { /* Available authentication types */
- { "crypto", AV_CRYPTO, CM_INV }, /* and encryption */
- { "encryption", AV_CRYPTO, 0 },
- { "k4", AV_KRB4, CM_INV },
- { "k5", AV_KRB5, CM_INV },
- { "kerberos4", AV_KRB4, 0 },
- { "kerberos5", AV_KRB5, 0 },
- { "krb4", AV_KRB4, CM_INV },
- { "krb5", AV_KRB5, CM_INV },
- { "ntlm", AV_NTLM, 0 },
- { "srp", AV_SRP, 0 },
- { "ssh", AV_SSH, 0 },
- { "ssl", AV_SSL, 0 },
- { "tls", AV_SSL, 0 },
- { "", 0, 0 }
-};
-int availtabn = sizeof(availtab)/sizeof(struct keytab)-1;
-
-#ifndef NODIAL
-_PROTOTYP(static int ddcvt, (char *, FILE *, int) );
-_PROTOTYP(static int dncvt, (int, int, int, int) );
-_PROTOTYP(char * getdname, (void) );
-
-static int partial = 0; /* For partial dial */
-static char *dscopy = NULL;
-int dialtype = -1;
-
-char *dialnum = (char *)0; /* Remember DIAL number for REDIAL */
-int dirline = 0; /* Dial directory line number */
-extern char * dialdir[]; /* Dial directory file names */
-extern int dialdpy; /* DIAL DISPLAY on/off */
-extern int ndialdir; /* How many dial directories */
-extern int ntollfree; /* Toll-free call info */
-extern int ndialpxx; /* List of PBX exchanges */
-extern char *dialtfc[];
-char * matchpxx = NULL; /* PBX exchange that matched */
-extern int nlocalac; /* Local area-code list */
-extern char * diallcac[];
-extern int tttapi;
-#ifdef CK_TAPI
-extern int tapiconv; /* TAPI Conversions */
-extern int tapipass; /* TAPI Passthrough */
-#endif /* CK_TAPI */
-extern int dialatmo;
-extern char * dialnpr, * dialsfx;
-extern char * dialixp, * dialixs, * dialmac;
-extern char * dialldp, * diallds, * dialtfp;
-extern char * dialpxi, * dialpxo, * diallac;
-extern char * diallcp, * diallcs, * diallcc;
-extern char * dialpxx[];
-
-extern int dialcnf; /* DIAL CONFIRMATION */
-int dialfld = 0; /* DIAL FORCE-LONG-DISTANCE */
-int dialsrt = 1; /* DIAL SORT ON */
-int dialrstr = 6; /* DIAL RESTRICTION */
-int dialtest = 0; /* DIAL TEST */
-int dialcount = 0; /* \v(dialcount) */
-
-extern int dialsta; /* Dial status */
-int dialrtr = -1, /* Dial retries */
- dialint = 10; /* Dial retry interval */
-extern long dialcapas; /* Modem capabilities */
-extern int dialcvt; /* DIAL CONVERT-DIRECTORY */
-#endif /* NODIAL */
-
-#ifndef NOSPL
-#define IFCONDLEN 256
-int ifc, /* IF case */
- not = 0, /* Flag for IF NOT */
- ifargs = 0; /* Count of IF condition words */
-char ifcond[IFCONDLEN]; /* IF condition text */
-char *ifcp; /* Pointer to IF condition text */
-extern int vareval;
-#ifdef DCMDBUF
-extern int
- *ifcmd, *count, *iftest, *intime,
- *inpcas, *takerr, *merror, *xquiet, *xvarev;
-#else
-extern int ifcmd[]; /* Last command was IF */
-extern int iftest[]; /* Last IF was true */
-extern int count[]; /* For IF COUNT, one for each cmdlvl */
-extern int intime[]; /* Ditto for other stackables... */
-extern int inpcas[];
-extern int takerr[];
-extern int merror[];
-extern int xquiet[];
-extern int xvarev[];
-#endif /* DCMDBUF */
-#else
-extern int takerr[];
-#endif /* NOSPL */
-
-#ifdef DCMDBUF
-extern char *line; /* Character buffer for anything */
-extern char *tmpbuf;
-#else
-extern char line[], tmpbuf[];
-#endif /* DCMDBUF */
-extern char *lp; /* Pointer to line buffer */
-
-int cwdf = 0; /* CWD has been done */
-
-/* Flags for ENABLE/DISABLE */
-extern int en_cwd, en_cpy, en_del, en_dir, en_fin,
- en_get, en_hos, en_ren, en_sen, en_set, en_spa, en_typ, en_who, en_bye,
- en_asg, en_que, en_ret, en_mai, en_pri, en_mkd, en_rmd, en_xit, en_ena;
-
-extern FILE *tfile[]; /* File pointers for TAKE command */
-extern char *tfnam[]; /* Names of TAKE files */
-extern int tfline[]; /* TAKE-file line number */
-
-extern int success; /* Command success/failure flag */
-extern int cmdlvl; /* Current position in command stack */
-
-#ifndef NOSPL
-extern int maclvl; /* Macro to execute */
-extern char *macx[]; /* Index of current macro */
-extern char *mrval[]; /* Macro return value */
-extern char *macp[]; /* Pointer to macro */
-extern int macargc[]; /* ARGC from macro invocation */
-
-#ifdef COMMENT
-extern char *m_line[];
-#endif /* COMMENT */
-
-extern char *m_arg[MACLEVEL][NARGS]; /* Stack of macro arguments */
-extern char *g_var[]; /* Global variables %a, %b, etc */
-
-#ifdef DCMDBUF
-extern struct cmdptr *cmdstk; /* The command stack itself */
-#else
-extern struct cmdptr cmdstk[]; /* The command stack itself */
-#endif /* DCMDBUF */
-#endif /* NOSPL */
-
-#define xsystem(s) zsyscmd(s)
-
-static int x, y, z = 0;
-static char *s, *p;
-
-#ifdef OS2
-_PROTOTYP( int os2settitle, (char *, int) );
-#endif /* OS2 */
-
-extern struct keytab yesno[], onoff[], fntab[];
-extern int nyesno, nfntab;
-
-#ifndef NOSPL
-
-/* Do the ASK, ASKQ, GETOK, and READ commands */
-
-int asktimedout = 0;
-
-#define ASK_PUP 1
-#define ASK_TMO 2
-#define ASK_GUI 3
-#define ASK_QUI 4
-#define ASK_DEF 5
-#define ASK_ECH 6
-
-static struct keytab asktab[] = {
- { "/default", ASK_DEF, CM_ARG },
- { "/gui", ASK_GUI,
-#ifdef KUI
- 0
-#else /* KUI */
- CM_INV
-#endif /* KUI */
- },
- { "/popup", ASK_PUP,
-#ifdef OS2
- 0
-#else /* OS2 */
- CM_INV
-#endif /* OS2 */
- },
- { "/quiet", ASK_QUI, 0 },
- { "/timeout", ASK_TMO, CM_ARG },
- { "", 0, 0 }
-};
-static int nasktab = sizeof(asktab)/sizeof(struct keytab)-1;
-
-static struct keytab askqtab[] = {
- { "/default", ASK_DEF, CM_ARG },
- { "/echo", ASK_ECH, CM_ARG },
- { "/gui", ASK_GUI,
-#ifdef KUI
- 0
-#else /* KUI */
- CM_INV
-#endif /* KUI */
- },
- { "/noecho", ASK_QUI, CM_INV },
- { "/popup", ASK_PUP,
-#ifdef OS2
- 0
-#else /* OS2 */
- CM_INV
-#endif /* OS2 */
- },
- { "/quiet", ASK_QUI, 0 },
- { "/timeout", ASK_TMO, CM_ARG },
- { "", 0, 0 }
-};
-static int naskqtab = sizeof(askqtab)/sizeof(struct keytab)-1;
-
-int
-doask(cx) int cx; {
- extern int asktimer, timelimit;
-#ifdef CK_RECALL
- extern int on_recall;
-#endif /* CK_RECALL */
- int echochar = 0;
- int popupflg = 0;
- int guiflg = 0;
- int nomsg = 0;
- int mytimer = 0;
-#ifdef CK_APC
- extern int apcactive, apcstatus;
-#endif /* CK_APC */
-
- char dfbuf[1024]; /* Buffer for default answer */
- char * dfanswer = NULL; /* Pointer to it */
-
- char vnambuf[VNAML+1]; /* Buffer for variable names */
- char *vnp = NULL; /* Pointer to same */
-
- dfbuf[0] = NUL;
- vnambuf[0] = NUL;
-
-#ifdef CK_APC
- if ( apcactive != APC_INACTIVE && (apcstatus & APC_NOINP) ) {
- return(success = 0);
- }
-#endif /* CK_APC */
-
- mytimer = asktimer; /* Inherit global ASK timer */
- echostars = 0; /* For ASKQ */
-
- if (cx == XXASK || cx == XXASKQ) {
- struct FDB sw, fl;
- int getval;
- char c;
- if (cx == XXASKQ) /* Don't log ASKQ response */
- debok = 0;
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Variable name or switch",
- "", /* default */
- "", /* addtl string data */
- ((cx == XXASK) ? nasktab : naskqtab), /* Table size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- ((cx == XXASK) ? asktab : askqtab), /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Anything that doesn't match */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse something */
- if (x < 0)
- return(x);
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (cmresult.nresult) {
- case ASK_QUI:
- nomsg = 1;
- if (cx == XXASKQ)
- echostars = 0;
- break;
- case ASK_PUP:
- popupflg = 1;
- break;
- case ASK_GUI:
- guiflg = 1;
- break;
- case ASK_TMO: {
- if ((y = cmnum("seconds","1",10,&x,xxstring)) < 0)
- return(y);
- if (x < 0)
- x = 0;
- mytimer = x;
- break;
- }
- case ASK_ECH: {
- if ((y = cmfld("Character to echo","*",&s,xxstring)) < 0)
- return(y);
- echochar = *s;
- break;
- }
- case ASK_DEF: {
- if ((y = cmfld("Text to supply if reply is empty",
- "",&s,xxstring)) < 0)
- return(y);
- ckstrncpy(dfbuf,s,1024);
- dfanswer = dfbuf;
- break;
- }
- default: return(-2);
- }
- }
- /* Have variable name, make copy. */
- ckstrncpy(vnambuf,cmresult.sresult,VNAML);
- vnp = vnambuf;
- if (vnambuf[0] == CMDQ &&
- (vnambuf[1] == '%' || vnambuf[1] == '&'))
- vnp++;
- y = 0;
- if (*vnp == '%' || *vnp == '&') {
- if ((y = parsevar(vnp,&x,&z)) < 0)
- return(y);
- }
- } else if (cx != XXGOK && cx != XXRDBL) { /* Get variable name */
- if ((y = cmfld("Variable name","",&s,NULL)) < 0) {
- if (y == -3) {
- printf("?Variable name required\n");
- return(-9);
- } else return(y);
- }
- ckstrncpy(vnambuf,s,VNAML); /* Make a copy. */
- vnp = vnambuf;
- if (vnambuf[0] == CMDQ &&
- (vnambuf[1] == '%' || vnambuf[1] == '&'))
- vnp++;
- y = 0;
- if (*vnp == '%' || *vnp == '&') {
- if ((y = parsevar(vnp,&x,&z)) < 0)
- return(y);
- }
- }
- if (cx == XXREA || cx == XXRDBL) { /* READ or READBLOCK command */
- if ((y = cmcfm()) < 0) /* Get confirmation */
- return(y);
- if (chkfn(ZRFILE) < 1) { /* File open? */
- printf("?Read file not open\n");
- return(success = 0);
- }
- if (!(s = (char *)readbuf)) { /* Where to read into. */
- printf("?Oops, no READ buffer!\n");
- return(success = 0);
- }
- y = zsinl(ZRFILE, s, readblock); /* Read a line. */
- debug(F111,"read zsinl",s,y);
- if (y < 0) { /* On EOF or other error, */
- zclose(ZRFILE); /* close the file, */
- delmac(vnp,0); /* delete the variable, */
- return(success = 0); /* and return failure. */
- } else { /* Read was OK. */
- readsize = (int) strlen(s);
- success = (addmac(vnp,s) < 0 ? 0 : 1); /* Define variable */
- debug(F111,"read addmac",vnp,success);
- return(success); /* Return success. */
- }
- }
-
- /* ASK, ASKQ, GETOK, or GETC */
-
- if (cx == XXGOK) { /* GETOK can take switches */
- struct FDB sw, fl;
- int getval;
- char c;
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Variable name or question prompt",
- "", /* default */
- "", /* addtl string data */
- nasktab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- asktab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Anything that doesn't match */
- _CMTXT, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse something */
- if (x < 0)
- return(x);
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (cmresult.nresult) {
- case ASK_PUP:
- popupflg = 1;
- break;
- case ASK_GUI:
- guiflg = 1;
- break;
- case ASK_TMO: {
- if ((y = cmnum("seconds","1",10,&x,xxstring)) < 0)
- return(y);
- if (x < 0)
- x = 0;
- mytimer = x;
- break;
- }
- case ASK_DEF: {
- if ((y = cmfld("Text to supply if reply is empty",
- "",&s,xxstring)) < 0)
- return(y);
- ckstrncpy(dfbuf,s,1024);
- dfanswer = dfbuf;
- break;
- }
- case ASK_QUI:
- nomsg = 1;
- break;
- default: return(-2);
- }
- }
- p = cmresult.sresult;
- } else
- if ((y = cmtxt(
-"Prompt,\n\
- enclose in { braces } or \" quotes \" to preserve leading and trailing\n\
- spaces, precede question mark with backslash (\\).",
- "",&p,xxstring)) < 0)
- return(y);
-
- if (!p) p = "";
-#ifndef NOLOCAL
-#ifdef OS2
- if (popupflg) { /* Popup requested */
- int len = -1;
- ckstrncpy(tmpbuf,brstrip(p),TMPBUFSIZ);
- p = tmpbuf;
- if (cx == XXASK || cx == XXASKQ) {
- if (cx == XXASK)
- len = popup_readtext(vmode,NULL,p,line,LINBUFSIZ,mytimer);
- else
- len = popup_readpass(vmode,NULL,p,line,LINBUFSIZ,mytimer);
- asktimedout = ( len < 0 && mytimer );
- } else if (cx == XXGOK) {
- printf("?Sorry, GETOK /POPUP not implemented yet\n");
- timelimit = 0;
- return(-9);
- }
- if (len >= 0) {
- y = addmac(vnp,(char *)line); /* Add it to the macro table. */
- } else if ( asktimedout && dfanswer ) {
- y = addmac(vnp,dfanswer); /* Add it to the macro table. */
- asktimedout = 0;
- len = 0;
- }
- timelimit = 0;
- return(success = ((len >= 0) && (y >= 0)) && !asktimedout);
- }
-#ifdef KUI
- if (guiflg) { /* GUI requested */
- int rc, n;
- char * s1;
- s1 = tmpbuf;
- n = TMPBUFSIZ-1;
- zzstring(brstrip(p),&s1,&n);
- p = tmpbuf;
- if (cx == XXASK || cx == XXASKQ) {
- rc = gui_txt_dialog(NULL,p,(cx == XXASK),
- line,LINBUFSIZ,dfanswer,mytimer);
- asktimedout = (rc == -1 && mytimer);
- if (rc == 1) {
- y = addmac(vnp,(char *)line); /* Add it to the macro table. */
- } else if ( asktimedout && dfanswer ) {
- y = addmac(vnp,dfanswer); /* Add default to macro table. */
- asktimedout = 0;
- rc = 1;
- }
- timelimit = 0;
- return(success = (rc == 1 && (y >= 0)) && !asktimedout);
- } else if (cx == XXGOK) {
- int x;
- x = lookup(yesno,dfanswer,nyesno,NULL);
- if (x != 1) x = 2;
- rc = uq_ok(NULL, p, 3, NULL, x);
- return(success = (rc == 1));
- }
- }
-#endif /* KUI */
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
- concb((char)escape); /* Enter CBREAK mode */
- cmsavp(psave,PROMPTL); /* Save old prompt */
- cmsetp(brstrip(p)); /* Make new prompt */
-
-reprompt:
- if (cx == XXASKQ) { /* For ASKQ, */
- cmini(0); /* no-echo mode. */
- if (echochar)
- echostars = echochar;
- } else { /* For others, regular echoing. */
- cmini(ckxech);
- echostars = 0;
- }
- askflag = 1;
- x = -1; /* This means to reparse. */
- cmflgs = 0;
- if (pflag)
- prompt(xxstring); /* Issue prompt. */
-
- asktimedout = 0; /* Handle timed responses. */
- timelimit = mytimer;
-reparse:
- cmres();
- if (cx == XXGOK) { /* GETOK */
-#ifdef CK_RECALL
- on_recall = 0;
-#endif /* CK_RECALL */
- askflag = 0;
- /* GETOK uses keyword table */
- x = cmkey(yesno,nyesno,"",dfanswer,xxstring);
- if (x < 0) { /* Parse error */
- if (x == -10) {
- char * ds;
- ds = dfanswer ? dfanswer : "No";
- if (!nomsg)
- printf("?Timed out, assuming \"%s\"",ds);
- printf("\n");
- asktimedout = 1;
- x = lookup(yesno,ds,nyesno,NULL);
- if (x != 1) x = 0;
- goto gokdone;
- } else if (x == -3) { /* No answer? */
- printf("Please respond Yes or No\n"); /* Make them answer */
- cmini(ckxech);
- goto reprompt;
- } else if (x == -1) {
- goto reparse;
- } else
- goto reprompt;
- }
- if (cmcfm() < 0) /* Get confirmation */
- goto reparse;
- gokdone:
- askflag = 0;
- cmsetp(psave); /* Restore prompt */
-#ifdef VMS
- if (cmdlvl > 0) /* In VMS and not at top level, */
- conres(); /* restore console again. */
-#endif /* VMS */
- timelimit = 0;
- return(x); /* Return success or failure */
- } else if (cx == XXGETC /* GETC */
-#ifdef OS2
- || cx == XXGETK /* or GETKEYCODE */
-#endif /* OS2 */
- ) { /* GETC */
- char tmp[16];
- conbin((char)escape); /* Put keyboard in raw mode */
-#ifndef NOSETKEY
-#ifdef OS2
- if (cx == XXGETK) { /* GETKEYCODE */
- extern int os2gks;
- int t;
- t = os2gks; /* Turn off kverb recognition */
- os2gks = 0;
- x = congks(timelimit); /* Read a key event, blocking */
- os2gks = t; /* Put back kverb recognition */
- } else /* GETC */
-#endif /* OS2 */
-#endif /* NOSETKEY */
- {
- debug(F101,"GETC conchk","",conchk());
- x = coninc(timelimit); /* Just read one character */
- debug(F101,"GETC coninc","",x);
- }
- concb((char)escape); /* Put keyboard back in cbreak mode */
- if (x > -1) {
- if (xcmdsrc == 0)
- printf("\r\n");
-#ifdef OS2
- if (cx == XXGETK) { /* GETKEYCODE */
- sprintf(tmp,"%d",x); /* SAFE */
- } else {
-#endif /* OS2 */
- tmp[0] = (char) (x & 0xff);
- tmp[1] = NUL;
-#ifdef OS2
- }
-#endif /* OS2 */
- y = addmac(vnp,tmp); /* Add it to the macro table. */
- debug(F111,"getc/getk addmac",vnp,y);
- } else y = -1;
- cmsetp(psave); /* Restore old prompt. */
- if (x < -1) {
- asktimedout = 1;
- if (!quiet && !nomsg)
- printf("?Timed out");
- printf("\n");
- }
- timelimit = 0;
- return(success = ((y < 0 ? 0 : 1) && (asktimedout == 0)));
- } else { /* ASK or ASKQ */
-#ifdef CK_RECALL
- on_recall = 0; /* Don't put response in recall buf */
-#endif /* CK_RECALL */
- askflag = 1; /* ASK[Q] always goes to terminal */
- y = cmdgquo(); /* Get current quoting */
- cmdsquo(0); /* Turn off quoting */
- while (x == -1) { /* Prompt till they answer */
- x = cmtxt("Please respond.",dfanswer,&s,NULL);
- debug(F111,"ASK cmtxt",s,x);
- cmres();
- }
- cmdsquo(y); /* Restore previous quoting */
- if (cx == XXASKQ) /* ASKQ must echo CRLF here */
- printf("\r\n");
- if (x == -10 && dfanswer) { /* Don't fail on timeout if */
- s = dfanswer; /* a default was specified */
- asktimedout = 0; /* and don't fail */
- x = 0;
- }
- if (x < 0) { /* If cmtxt parse error, */
- cmsetp(psave); /* restore original prompt */
-#ifdef VMS
- if (cmdlvl > 0) /* In VMS and not at top level, */
- conres(); /* restore console again. */
-#endif /* VMS */
- if (x == -10) { /* Timed out with no response */
- if (!nomsg)
- printf("?Timed out");
- printf("\n");
- asktimedout = 1;
- if (dfanswer) /* Supply default answer if any */
- s = dfanswer;
- success = x = 0; /* (was "x = -9;") */
- }
- timelimit = 0;
- return(x); /* and return cmtxt's error code. */
- }
- if (!s || *s == NUL) { /* If user typed a bare CR, */
- cmsetp(psave); /* Restore old prompt, */
- delmac(vnp,0); /* delete variable if it exists, */
-#ifdef VMS
- if (cmdlvl > 0) /* In VMS and not at top level, */
- conres(); /* restore console again. */
-#endif /* VMS */
- timelimit = 0;
- return(success = 1); /* and return. */
- }
- y = addmac(vnp,s); /* Add it to the macro table. */
- debug(F111,"ask addmac",vnp,y);
- cmsetp(psave); /* Restore old prompt. */
-#ifdef VMS
- if (cmdlvl > 0) /* In VMS and not at top level, */
- conres(); /* restore console again. */
-#endif /* VMS */
- timelimit = 0;
- return(success = (y < 0 ? 0 : 1) && (asktimedout == 0));
- }
-}
-#endif /* NOSPL */
-
-#ifndef NOSPL
-int
-doincr(cx) int cx; { /* INCREMENT, DECREMENT */
- char vnambuf[VNAML+1]; /* Buffer for variable names */
- int eval = 0;
- CK_OFF_T x;
- eval = (cx == XX_DECR || cx == XX_INCR);
-
- if ((y = cmfld("Variable name","",&s, eval ? xxstring : NULL)) < 0) {
- if (y == -3) {
- printf("?Variable name required\n");
- return(-9);
- } else return(y);
- }
- ckstrncpy(vnambuf,s,VNAML);
- if ((y = cmnumw("by amount","1",10,&x,xxstring)) < 0)
- return(y);
- if ((y = cmcfm()) < 0)
- return(y);
-
- z = (cx == XX_INCR || cx == XXINC) ? 1 : 0; /* Increment or decrement? */
-
- if (incvar(vnambuf,x,z) < 0) {
- printf("?Variable %s not defined or not numeric\n",vnambuf);
- return(success = 0);
- }
- return(success = 1);
-}
-
-/* Used by doundef() */
-static int
-xxundef(s,verbose,simulate) char * s; int verbose, simulate; {
- int rc = 0;
- if (!s) return(0);
- if (*s == CMDQ && *(s+1) == '%') {
- char c = *(s+2), * p = NULL;
- if (c >= '0' && c <= '9') {
- if (maclvl < 0)
- p = g_var[c];
- else
- p = m_arg[maclvl][c - '0'];
- } else {
- if (isupper(c)) c += ('a'-'A');
- if (c >= 'a' && c <= 'z')
- p = g_var[c];
- }
- if (!p) return(-1);
- }
- if (verbose)
- printf(" %s ",s);
- if (simulate) {
- printf("(SELECTED)\n");
- } else if ((x = delmac(s,1)) > -1) { /* Full name required */
- rc = 1;
- if (verbose) printf("(OK)\n");
- } else if (verbose)
- printf("(FAILED)\n");
- return(rc);
-}
-
-/* Do the (_)DEFINE, (_)ASSIGN, and UNDEFINE commands */
-
-#define UND_MAT 1
-#define UND_VRB 2
-#define UND_EXC 3
-#define UND_SIM 3
-
-static struct keytab undefswi[] = {
- { "/list", UND_VRB, 0 },
-#ifdef COMMENT
- { "/except", UND_EXC, CM_ARG },
-#endif /* COMMENT */
- { "/matching", UND_MAT, 0 },
- { "/simulate", UND_SIM, 0 },
- { "/verbose", UND_VRB, CM_INV }
-};
-static int nundefswi = sizeof(undefswi) / sizeof(struct keytab);
-
-#define UNDEFMAX 64
-static char ** undeflist = NULL;
-int
-doundef(cx) int cx; { /* UNDEF, _UNDEF */
- int i, j, n, rc = 0, arraymsg = 0;
- int domatch = 0, verbose = 0, errors = 0, simulate = 0, flag = 0;
- char *vnp, vnbuf[4];
-#ifdef COMMENT
- char *except = NULL;
-#endif /* COMMENT */
- struct FDB sw, fl;
- int getval;
- char c;
-
- if (!undeflist) { /* Allocate list if necessary */
- undeflist = (char **)malloc(UNDEFMAX * sizeof(char *));
- if (!undeflist) {
- printf("?Memory allocation failure\n");
- return(-9);
- }
- for (i = 0; i < UNDEFMAX; i++)
- undeflist[i] = NULL;
- }
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Variable name or switch",
- "", /* default */
- "", /* addtl string data */
- nundefswi, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- undefswi, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Anything that doesn't match */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- (cx == XXUNDEF) ? NULL : xxstring,
- NULL,
- NULL
- );
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse something */
- if (x < 0)
- return(x);
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- switch (cmresult.nresult) {
- case UND_MAT: domatch = 1; break;
- case UND_SIM: simulate = 1; /* fall thru on purpose */
- case UND_VRB: verbose = 1; break;
-
-#ifdef COMMENT
- case UND_EXC:
- if (!getval) break;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Pattern required\n");
- x = -9;
- }
- goto xgetx;
- }
- makestr(&except,cmresult.sresult);
- break;
-#endif /* COMMENT */
-
- default:
- return(-2);
- }
- }
- n = 0;
- makestr(&(undeflist[n++]),cmresult.sresult);
- for (i = 1; i < UNDEFMAX; i++) {
- x = cmfld("Macro or variable name","",&s,
- ((cx == XXUNDEF) ? NULL : xxstring)
- );
- if (x == -3) {
- if ((y = cmcfm()) < 0)
- return(y);
- break;
- } else if (y < 0) {
- return(y);
- }
- makestr(&(undeflist[n++]),s);
- }
- /* Now we have a list of n variables or patterns to undefine */
-
- for (i = 0; i < n; i++) {
- flag = 0;
- if (!(vnp = undeflist[i]))
- continue;
- if (vnp[0] == CMDQ && (vnp[1] == '%' || vnp[1] == '&')) {
- flag++;
- vnp++;
- }
- if (!domatch) { /* Pattern match not requested */
- if (flag) {
- if ((y = parsevar(vnp,&x,&z)) < 0) {
- vnp--;
- if (verbose) printf(" %s...error\n",vnp);
- continue;
- }
- vnp--;
- }
- x = xxundef(vnp,verbose,simulate);
- if (x > -1) {
- if (!x && !simulate) errors++;
- rc += x;
- }
- continue;
- }
- /* Pattern match requested */
-
- if (!flag) { /* It's a macro */
- for (j = 0; j < nmac; j++) {
- if (ckmatch(vnp,mactab[j].kwd,0,1)) {
- x = xxundef(mactab[j].kwd,verbose,simulate);
- if (x > -1) {
- rc += x;
- if (!x) errors++;
- }
- if (!simulate)
- j--; /* Because mactab shifted up */
- }
- }
- } else if (vnp[0] == '%') { /* It's a \%x variable */
- vnbuf[0] = CMDQ;
- vnbuf[1] = '%';
- vnbuf[3] = NUL;
- for (j = '0'; j <= 'z'; j++) { /* 0..9 a..z */
- vnbuf[2] = j;
- if (ckmatch(vnp,&vnbuf[1],0,1)) {
- x = xxundef(vnbuf,verbose,simulate);
- if (x > -1) {
- if (!x) errors++;
- rc += x;
- }
- }
- if (j == '9') j = (int)'a' - 1; /* 9 -> a */
- }
- } else if (vnp[0] == '&') {
- if (!arraymsg && !quiet) {
- printf("?UNDEFINE /MATCH can't be used with arrays.\n");
- printf("(Type HELP ARRAY to see other methods.)\n");
- }
- arraymsg++;
- errors++;
- }
- }
- if (verbose)
- printf("undefined: %d, errors: %d\n",rc,errors);
-
- for (i = 0; i < UNDEFMAX; i++) { /* Check them all */
- if (undeflist[i]) { /* in case we were interrupted */
- free(undeflist[i]); /* previously... */
- undeflist[i] = NULL;
- }
- }
- return(success = (errors == 0) ? 1 : 0);
-}
-
-int
-dodef(cx) int cx; {
- extern int xxdot;
- extern char ppvnambuf[];
- int doeval = 0;
- char vnambuf[VNAML+1]; /* Buffer for variable names */
- char *vnp; /* Pointer to same */
- int k, mydot;
- mydot = xxdot; /* Copy */
- xxdot = 0; /* and reset */
-/*
- In case we got here from a command that begins like ".\%a", cmkey() has
- already evaluated \%a, but we don't want that, so we retrieve the variable
- name from a special pre-evaluation buffer in the command module, and we
- undo the "unget word" that would be done because of the token, because if
- the variable was defined, it will unget its value rather than its name.
-*/
- s = NULL;
-
- if (mydot && ppvnambuf[0] == '.' && ppvnambuf[1]) {
- s = ppvnambuf+1;
- unungw();
- }
- if (!s) {
- if (cx == XXDFX || cx == XXASX)
- /* Evaluate variable name */
- y = cmfld("Macro or variable name","",&s,xxstring);
- else
- /* Don't evaluate the variable name */
- y = cmfld("Macro or variable name","",&s,NULL);
- if (y < 0) {
- if (y == -3) {
- printf("?Variable name required\n");
- return(-9);
- } else return(y);
- }
- }
- k = strlen(s);
- if (k > VNAML) {
- printf("?Name too long: \"%s\"\n",s);
- return(-9);
- }
- ckstrncpy(vnambuf,s,VNAML);
- vnambuf[VNAML] = NUL;
- vnp = vnambuf;
- if (vnambuf[0] == CMDQ && (vnambuf[1] == '%' || vnambuf[1] == '&')) vnp++;
- if (*vnp == '%' || *vnp == '&') {
- if ((y = parsevar(vnp,&x,&z)) < 0) return(y);
-#ifdef COMMENT
- if (cx == XXUNDEF) { /* Undefine */
- if ((y = cmtxt("Text to be ignored","",&s,NULL)) < 0) return(y);
- delmac(vnp,0);
- return(success = 1);
- }
-#endif /* COMMENT */
- debug(F101,"dodef parsevar x","",x);
- if (mydot) {
- if ((doeval = cmkey(asgtab,nasgtab,"operator","=",NULL)) < 0)
- return(doeval);
- if (doeval > 0) /* Type of assignment */
- cx = XXASS;
- }
- if (y == 1) { /* Simple variable */
- if ((y = cmtxt("Definition of variable","",&s,NULL)) < 0)
- return(y);
- s = brstrip(s);
- debug(F110,"xxdef var name",vnp,0);
- debug(F110,"xxdef var def",s,0);
- } else if (y == 2) { /* Array element */
- if ((y = arraynam(vnp,&x,&z)) < 0) return(y);
- if (x == 96) {
- printf("?Argument vector array is read-only\n");
- return(-9);
- }
- if (chkarray(x,z) < 0) return(-2);
- if ((y = cmtxt("Definition of array element","",&s,NULL)) < 0)
- return(y);
- debug(F110,"xxdef array ref",vnp,0);
- debug(F110,"xxdef array def",s,0);
- }
- } else { /* Macro */
-#ifdef COMMENT
- if (cx == XXUNDEF) { /* Undefine */
- if ((y = cmtxt("Text to be ignored","",&s,NULL)) < 0) return(y);
- delmac(vnp,0);
- return(success = 1);
- }
-#endif /* COMMENT */
- if (mydot) {
- if ((doeval = cmkey(asgtab,nasgtab,"operator","=",NULL)) < 0)
- return(doeval);
- if (doeval > 0)
- cx = XXASS;
- }
- if ((y = cmtxt("Definition of macro","",&s,NULL)) < 0) return(y);
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"xxdef macro name",vnp,0);
- debug(F010,"xxdef macro def",s,0);
- }
-#endif /* DEBUG */
- s = brstrip(s);
- }
- if (*s == NUL) { /* No arg given, undefine */
- delmac(vnp,1); /* silently... */
- return(success = 1); /* even if it doesn't exist... */
- }
- /* Defining a new macro or variable */
-
- if (cx == XXASS || cx == XXASX) { /* ASSIGN rather than DEFINE? */
- int t;
- t = LINBUFSIZ-1;
- lp = line; /* If so, expand its value now */
- zzstring(s,&lp,&t);
- s = line;
- }
- if (doeval == 2) { /* Arithmetic evaluation wanted too? */
- ckstrncpy(line,evala(s),LINBUFSIZ);
- line[LINBUFSIZ] = NUL;
- }
- /* debug(F111,"calling addmac",s,(int)strlen(s)); */
-
- y = addmac(vnp,s); /* Add it to the appropriate table. */
- if (y < 0) {
- printf("?%s failed\n",(cx == XXASS || cx == XXASX) ?
- "ASSIGN" : "DEFINE");
- return(success = 0);
- } else if (cx == XXASX || cx == XXDFX) /* For _ASG or _DEF, */
- return(1); /* don't change success variable */
- else
- return(success = 1);
-}
-#endif /* NOSPL */
-
-
-#ifndef NODIAL
-/*
- L U D I A L -- Lookup up dialing directory entry.
-
- Call with string to look up and file descriptor of open dialing directory
- file. On success, returns number of matches found, with numbers stored
- in an array accessible via getdnum().
-*/
-static char *dn_p[MAXDNUMS + 1]; /* Dial Number pointers */
-static char *dn_p2[MAXDNUMS + 1]; /* Converted dial number pointers */
-static int dn_x[MAXDNUMS + 1]; /* Type of call */
-static int dncount = 0;
-char * d_name = NULL; /* Dial name pointer */
-
-char * /* Get dial directory entry name */
-getdname() {
- return(d_name ? d_name : "");
-}
-
-char *
-getdnum(n) int n; { /* Get dial number n from directory */
- if (n < 0 || n > dncount || n > MAXDNUMS)
- return("");
- else
- return(dn_p[n]);
-}
-
-char * /* Check area code for spurious leading digit */
-chk_ac(i,buf) int i; char buf[]; {
- char *p;
- if (!buf)
- return("");
- p = (char *) buf; /* Country we are calling: */
- if (i == 44 || /* UK */
- i == 49 || /* Germany */
- i == 39 || /* Italy */
- i == 31 || /* Netherlands */
- i == 351 || /* Portugal */
- i == 55 || /* Brazil */
- i == 972 || /* Israel */
- i == 41 || /* Switzerland */
- i == 43 || /* Austria */
- i == 42 || /* Czech Republic */
- i == 36 || /* Hungary */
- i == 30 || /* Greece */
- i == 352 || /* Luxembourg */
- i == 48 || /* Poland */
- i == 27 || /* South Africa */
- i == 33 || /* France (as of 1997) */
- i == 358 /* Finland (ditto) */
- ) {
- if (buf[0] == '0')
- p++;
- }
- return(p);
-}
-
-/* Call Is Long Distance -- Expand this to cover 10-digit local dialing etc */
-/*
- src = area code of caller
- dest = area code of callee
- Returns:
- 0 if call is local
- 1 if call is long distance
- 2 if call is local but area code must be dialed anyway
-*/
-static int
-callisld(src, dest) char * src, * dest; {
- int i;
- if (dialfld) /* Force long distance? */
- return(1);
- if (!strcmp(src,dest)) { /* Area codes are the same */
- for (i = 0; i < nlocalac; i++) /* Is AC in the lc-area-codes list? */
- if (!strcmp(src,diallcac[i]))
- return(2); /* Yes so must be dialed */
- return(0); /* No so don't dial it. */
- }
- for (i = 0; i < nlocalac; i++) /* ACs not the same so look in list */
- if (!strcmp(dest,diallcac[i])) /* Match */
- return(2); /* So local call with area code */
- return(1); /* Not local so long-distance */
-}
-
-char pdsfx[64] = { NUL, NUL };
-
-#ifndef NOSPL
-static char *
-xdial(s) char *s; { /* Run dial string thru macro */
- int x, m;
- char * s2;
- s2 = NULL;
- makestr(&s2,s); /* Copy the argument */
- if (!dialmac) /* Dial macro name given? */
- return(NULL);
- if ((x = mxlook(mactab,dialmac,nmac)) < 0) /* Is the macro defined? */
- return(NULL);
- m = maclvl;
- x = dodo(x,s2,0); /* Set up the macro */
- if (s2) free(s2);
- if (x > 0) {
- while (maclvl > m) /* Execute the parser */
- parser(1);
- return(mrval[maclvl+1]); /* Return the result */
- }
- return(NULL);
-}
-#endif /* NOSPL */
-
-static int
-dncvt(k,cx, prefix, suffix)
- int k, cx, prefix, suffix; { /* Dial Number Convert */
- int i, j, n, what; /* cx is top-level command index */
- char *ss; /* prefix - add prefixes? */
- char *p, *p2, *pxo; /* suffix - add suffixes? */
- char *lac;
- char *npr;
- char *sfx;
- /* char *psfx; */
- char ccbuf[128];
- int cc;
- char acbuf[24];
- char *acptr;
- char outbuf[256];
-/*
- First pass for strict (punctuation-based) interpretation.
- If it fails, we try the looser (length-based) one.
-*/
- dialtype = -1;
- what = 0; /* Type of call */
- s = dn_p[k]; /* Number to be converted. */
- debug(F111,"dncvt",s,k);
- if (dn_p2[k]) {
- free(dn_p2[k]);
- dn_p2[k] = NULL;
- }
- if (!s) {
- printf("Error - No phone number to convert\n");
- return(-1);
- }
- if ((int)strlen(s) > 200) {
- ckstrncpy(outbuf,s,40);
- printf("?Too long: \"%s...\"\n",outbuf);
- return(-1);
- }
- npr = (prefix && dialnpr) ? dialnpr : "";
- sfx = (suffix && dialsfx) ? dialsfx : "";
- /* if (partial) psfx = dialsfx ? dialsfx : ""; */
- pxo = (prefix && dialpxo) ? dialpxo : "";
- lac = diallac ? diallac : ""; /* Local area code */
-
- outbuf[0] = NUL; /* Initialize conversion buffer */
- ss = s; /* Remember original string */
-
- if (*s != '+') { /* Literal number */
- dn_x[k] = DN_UNK; /* Sort key is "unknown". */
- ckmakmsg(outbuf,256, /* Sandwich it between */
- pxo,npr,s,sfx /* DIAL PREFIX and SUFFIX */
- );
-#ifdef CK_TAPI
- if (tttapi && /* TAPI does its own conversions */
- !tapipass && /* if not in passthru mode */
- tapiconv == CK_AUTO || /* and TAPI conversions are AUTO */
- tapiconv == CK_ON /* OR if TAPI conversions are ON */
- ) {
- char * p = NULL;
- dialtype = -2;
- if (!cktapiConvertPhoneNumber(dn_p[k], &p))
- return(-1);
- makestr(&dn_p2[k], p);
- if (p) free(p);
- return(0);
- } else
-#endif /* CK_TAPI */
- makestr(&dn_p2[k], outbuf); /* Not TAPI */
- dialtype = what;
- return(0); /* Done. */
- }
- i = 0; /* Portable number */
- s++; /* Tiptoe past the plus sign */
- ccbuf[0] = NUL; /* Do country code first */
-
- if (!diallcc) { /* Do we know our own? */
- if (cx != XXLOOK)
- printf("Error - prior SET DIAL COUNTRY-CODE command required\n");
- return(-1);
- }
-
- /* Parse the number */
-
- while (1) { /* Get the country code */
- while (*s == HT || *s == SP)
- s++;
- if (!s) /* Not in standard format */
- break;
- if (*s == '(') { /* Beginning of area code */
- s++; /* Skip past parenthesis */
- ccbuf[i] = NUL; /* End of country code */
- if (!s) { /* Check for end of string */
- printf("Error - phone number ends prematurely: \"%s\"\n",ss);
- return(-1);
- }
- break;
- } else { /* Collect country code */
- if (isdigit(*s))
- ccbuf[i++] = *s; /* copy this character */
- s++;
- if (!*s || i > 127) /* watch out for memory leak */
- break;
- }
- }
- cc = atoi(ccbuf); /* Numeric version of country code */
-
- i = 0; /* Now get area code */
- acbuf[0] = NUL; /* Initialize area-code buffer */
- acptr = acbuf; /* and pointer. */
- while (1) {
- while (*s == HT || *s == SP) /* Ignore whitespace */
- s++;
- if (!s) /* String finished */
- break;
- if (*s == ')') { /* End of area code */
- s++; /* Skip past parenthesis */
- acbuf[i] = NUL; /* Terminate area-code buffer */
- break;
- } else { /* Part of area code */
- if (isdigit(*s)) /* If it's a digit, */
- acbuf[i++] = *s; /* copy this character */
- s++; /* Point to next */
- if (!*s || i > 23) /* Watch out for overflow */
- break;
- }
- }
-
-/*
- Here we strip any leading 0 for countries that we know have
- 0 as a long-distance prefix and do not have any area codes that
- start with 0 (formerly also ditto for "9" in Finland...)
-*/
- i = atoi(ccbuf);
- acptr = chk_ac(i,acbuf);
-
- while (*s == HT || *s == SP) /* Skip whitespace */
- s++;
-
-/* printf("S=[%s], ACPTR=[%s]\n",s,acptr); */
-
- if (*s && *acptr) { /* Area code was delimited */
-
- while (*s == '-' || *s == '.') /* Skip past gratuitious punctuation */
- s++;
- if (!*s) s--; /* But not to end of string */
-
- if (strcmp(diallcc,ccbuf)) { /* Out of country? */
- if (!dialixp) { /* Need intl-prefix */
- if (cx != XXLOOK)
- printf("Error - No international dialing prefix defined\n");
- return(-1);
- }
- what = dn_x[k] = DN_INTL;
- p = (prefix && dialixp) ? dialixp : ""; /* Intl-prefix */
- p2 = (suffix && dialixs) ? dialixs : ""; /* Intl-suffix */
-
- /* Form the final phone number */
-#ifdef COMMENT
- sprintf(pdsfx,"%s%s",p2,sfx); /* UNSAFE */
- sprintf(outbuf,
- "%s%s%s%s%s%s%s%s",
- pxo,npr,p,ccbuf,acptr,s,p2,sfx
- );
-#else
- ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
- ckmakxmsg(outbuf,256,pxo,npr,p,ccbuf,acptr,s,p2,sfx,
- NULL,NULL,NULL,NULL);
-#endif /* COMMENT */
-
- } else if ((x = callisld(lac,acptr)) >= 1) { /* In-country LD */
- if (!diallac && cx != XXLOOK) { /* Don't know my own area code */
- if (cc == 1)
- printf("WARNING - Prior SET DIAL AREA-CODE needed\n");
- }
- if (x == 2) { /* Local call with area code */
- what = dn_x[k] = DN_LOCAL; /* Local-call */
- p = (prefix && diallcp) ? diallcp : ""; /* local-prefix */
- p2 = (suffix && diallcs) ? diallcs : ""; /* local-suffix */
- } else {
- what = dn_x[k] = DN_LONG; /* Long-distance */
- for (i = 0; i < ntollfree; i++) { /* But toll-free too? */
- if (!strcmp(acptr,dialtfc[i])) {
- what = dn_x[k] = DN_FREE;
- break;
- }
- }
- if (what == DN_FREE) { /* Toll-free call */
- p = (prefix && dialtfp) ? dialtfp :
- ((prefix && dialldp) ? dialldp : "");
- p2 = ""; /* no suffix */
- } else { /* normal long distance */
- p = (prefix && dialldp) ? dialldp : ""; /* ld-prefix */
- p2 = (suffix && diallds) ? diallds : ""; /* ld-suffix */
- }
- }
- /* Form the number to be dialed */
-#ifdef COMMENT
- sprintf(outbuf,"%s%s%s%s%s%s%s",
- pxo,npr,p,acptr,s,p2,sfx
- );
- sprintf(pdsfx,"%s%s",p2,sfx);
-#else
- ckmakxmsg(outbuf,256,
- pxo,npr,p,acptr,s,p2,sfx,
- NULL,NULL,NULL,NULL,NULL);
- ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
-#endif /* COMMENT */
- } else { /* Same country, same area code */
- what = dn_x[k] = DN_LOCAL; /* So it's a local call. */
- if (!prefix || !(dialpxo || ndialpxx)) { /* Not dialing from PBX */
- p = (prefix && diallcp) ? diallcp : ""; /* local-prefix */
- p2 = (suffix && diallcs) ? diallcs : ""; /* local-suffix */
-#ifdef COMMENT
- if (x == 2)
- sprintf(outbuf,"%s%s%s%s%s%s",npr,p,acptr,s,p2,sfx);
- else
- sprintf(outbuf,"%s%s%s%s%s",npr,p,s,p2,sfx);
- sprintf(pdsfx,"%s%s",p2,sfx);
-#else
- if (x == 2)
- ckmakxmsg(outbuf,256,
- npr,p,acptr,s,p2,sfx,
- NULL,NULL,NULL,NULL,NULL,NULL);
- else
- ckmakxmsg(outbuf,256,
- npr,p,s,p2,sfx,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
-#endif /* COMMENT */
-
- } else { /* Dialing from a PBX and not TAPI */
- if (ndialpxx) { /* Is it internal? */
-#ifdef COMMENT
- i = (int) strlen(dialpxx);
- j = (int) strlen(s);
- x = -1;
- if (j > i)
- x = ckstrcmp(dialpxx,s,i,0);
-#else
- int kx;
- x = -1;
- j = (int) strlen(s);
- for (kx = 0; kx < ndialpxx; kx++) {
- i = (int) strlen(dialpxx[kx]);
- if (j > i)
- if (!(x = ckstrcmp(dialpxx[kx],s,i,0)))
- break;
- }
-#endif /* COMMENT */
- if (!x) {
- char * icp, buf[32];
- makestr(&matchpxx,dialpxx[kx]);
- debug(F111,"dncvt matchpxx",matchpxx,kx);
- what = dn_x[kx] = DN_INTERN; /* Internal call. */
- s += i;
- /* Internal-call prefix */
- icp = dialpxi;
-#ifndef NOSPL
- if (icp) {
- if (*icp == '\\') {
- char c, *bp;
- int n;
- c = *(icp+1);
- if (isupper(c)) c = tolower(c);
- if (c == 'v' || c == 'f') {
- n = 32;
- bp = buf;
- zzstring(icp,&bp,&n);
- icp = buf;
- }
- }
- }
-#endif /* NOSPL */
- p = (prefix && icp) ? icp : "";
-#ifdef COMMENT
- sprintf(outbuf,"%s%s%s%s",npr,p,s,sfx);
-#else
- ckmakmsg(outbuf,256,npr,p,s,sfx);
-#endif /* COMMENT */
- } else { /* External local call */
- /* local-prefix */
- p = (prefix && diallcp) ? diallcp : "";
- /* local-suffix */
- p2 = (prefix && diallcs) ? diallcs : "";
-#ifdef COMMENT
- if (x == 2)
- sprintf(outbuf,"%s%s%s%s%s%s%s",
- dialpxo ? dialpxo : "",
- npr,p,acptr,s,p2,sfx);
- else
- sprintf(outbuf,
- "%s%s%s%s%s%s",
- dialpxo ? dialpxo : "",
- npr,p,s,p2,sfx
- );
-#else
- if (x == 2)
- ckmakxmsg(outbuf, 256,
- dialpxo ? dialpxo : "",
- npr,p,acptr,s,p2,sfx,
- NULL,NULL,NULL,NULL,NULL);
- else
- ckmakxmsg(outbuf, 256,
- dialpxo ? dialpxo : "",
- npr,p,s,p2,sfx,
- NULL,NULL,NULL,NULL,NULL,NULL);
-#endif /* COMMENT */
- }
- }
- }
- }
-
- } else { /* Area code was not delimited */
-
- char xbuf[256]; /* Comparison based only on length */
- char ybuf[256];
- int x, j;
-
- s = ss;
-
- for (i = 0; i < 255; i++) {
- if (!*s) break;
- while (!isdigit(*s)) { /* Pay attention only to digits */
- s++;
- if (!*s) break;
- }
- xbuf[i] = *s++;
- }
- xbuf[i] = NUL;
-
- x = 1; /* Assume LD */
- n = 0;
- if (!dialfld) { /* If LD not forced */
- for (j = 0; j < nlocalac; j++) { /* check local AC list? */
- ckmakmsg(ybuf,256,diallcc,diallcac[j],NULL,NULL);
- n = (int) strlen(ybuf);
- if (n > 0 && !ckstrcmp(xbuf,ybuf,n,0)) {
- x = 2;
- break;
- }
- }
- if (x == 1) { /* Or exact match with local CC+AC? */
- ckmakmsg(ybuf,256,diallcc,lac,NULL,NULL);
- n = (int) strlen(ybuf);
- if (n > 0 && !ckstrcmp(xbuf,ybuf,n,0))
- x = 0;
- }
- }
- if (x == 0 || x == 2) { /* Local call */
- int xx,kx; /* Begin 1 Dec 2001... */
- /* Account for PBX internal calls */
- if (ndialpxx) {
- xx = -1;
- j = (int) strlen(ybuf);
- for (kx = 0; kx < ndialpxx; kx++) {
- i = (int) strlen(dialpxx[kx]);
- if (j >= i)
- if (!(xx = ckstrcmp(dialpxx[kx],&xbuf[j],i,0)))
- break;
- }
- }
- if (!xx) {
- char * icp, buf[32];
- makestr(&matchpxx,dialpxx[kx]);
- debug(F111,"dncvt matchpxx",matchpxx,kx);
- what = dn_x[kx] = DN_INTERN; /* Internal call. */
- s = xbuf + j + i;
- icp = dialpxi; /* Internal-call prefix */
-#ifndef NOSPL
- if (icp) {
- if (*icp == '\\') {
- char c, *bp;
- int n;
- c = *(icp+1);
- if (isupper(c)) c = tolower(c);
- if (c == 'v' || c == 'f') {
- n = 32;
- bp = buf;
- zzstring(icp,&bp,&n);
- icp = buf;
- }
- }
- }
-#endif /* NOSPL */
- p = (prefix && icp) ? icp : "";
- ckmakmsg(outbuf,256,npr,p,s,sfx);
- /* End 1 Dec 2001... */
-
- } else { /* Not PBX internal */
-
- dn_x[k] = DN_LOCAL;
- p = (prefix && diallcp) ? diallcp : "";
- p2 = (suffix && diallcs) ? diallcs : "";
- s = (char *) (xbuf + ((x == 0) ? n : (int)strlen(diallcc)));
- ckmakxmsg(outbuf,256,
- pxo,npr,p,s,p2,sfx,
- NULL,NULL,NULL,NULL,NULL,NULL);
- ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
- }
- } else { /* Not local */
- n = ckstrncpy(ybuf,diallcc,256);
- if (n > 0 && !ckstrcmp(xbuf,ybuf,n,0)) { /* Long distance */
- dn_x[k] = DN_LONG;
- p = (prefix && dialldp) ? dialldp : "";
- p2 = (suffix && diallds) ? diallds : "";
- s = xbuf + n;
- while (*s == '-' || *s == '.')
- s++;
-#ifdef COMMENT
- sprintf(outbuf,"%s%s%s%s%s%s",pxo,npr,p,s,p2,sfx);
- sprintf(pdsfx,"%s%s",p2,sfx);
-#else
- ckmakxmsg(outbuf,256,
- pxo,npr,p,s,p2,sfx,
- NULL,NULL,NULL,NULL,NULL,NULL);
- ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
-#endif /* COMMENT */
- } else {
- dn_x[k] = DN_INTL; /* International */
- if (!dialixp) {
- if (cx != XXLOOK) {
- printf(
- "Error - No international dialing prefix defined\n"
- );
- return(-1);
- }
- }
- p = (prefix && dialixp) ? dialixp : "";
- p2 = (suffix && dialixs) ? dialixs : "";
-#ifdef COMMENT
- sprintf(outbuf,"%s%s%s%s%s%s",pxo,npr,p,xbuf,p2,sfx);
- sprintf(pdsfx,"%s%s",p2,sfx);
-#else
- ckmakxmsg(outbuf,256,
- pxo,npr,p,xbuf,p2,sfx,
- NULL,NULL,NULL,NULL,NULL,NULL);
- ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
-#endif /* COMMENT */
- }
- }
- }
-#ifdef CK_TAPI
- if (tttapi && /* TAPI performs the conversions */
- !tapipass &&
- tapiconv == CK_AUTO ||
- tapiconv == CK_ON
- ) {
- p = NULL;
- dialtype = -2;
- if (!cktapiConvertPhoneNumber(dn_p[k],&p))
- return(-1);
- makestr(&dn_p2[k], p);
- if (p) free(p);
- return(0);
- } else {
-#endif /* CK_TAPI */
- makestr(&dn_p2[k], outbuf);
-#ifdef CK_TAPI
- }
-#endif /* CK_TAPI */
- dialtype = what;
- return(0);
-}
-
-static int
-ddcvt(s, f, n) char * s; FILE * f; int n; { /* Dial Directory Convert */
- char linebuf[1024], *s2; /* Buffers and pointers */
-#ifdef VMS
- char * temp = NULL;
-#endif /* VMS */
- char *info[8]; /* Pointers to words from entry */
- FILE * f2 = NULL;
- int x, rc;
- rc = -1;
-
- debug(F110,"ddcvt file",s,0);
-
- if (!s || !f) /* No filename or file */
- return(-1);
- if (!*s)
-
- fclose(f);
- znewn(s,&s2); /* s2 = address of static buffer */
- debug(F110,"ddcvt newname",s2,0);
-
-#ifdef VMS
- /* In VMS, znewn() returns the same file name with a new version number */
- makestr(&temp,s); /* Swap - otherwise the new */
- s = s2; /* version has the older version */
- s2 = temp; /* number... */
- debug(F110,"ddcvt after swap s",s,0);
- debug(F110,"ddcvt after swap s2",s2,0);
- makestr(&(dialdir[n]),s); /* New file gets new version number */
- debug(F110,"ddcvt after makestr s2",s2,0);
- debug(F111,"ddcvt dialdir[n]",dialdir[n],n);
-#else
- if (zrename(s,s2) < 0) { /* Not VMS - rename old file */
- perror(s2); /* to new (wierd) name. */
- goto ddexit;
- }
-#endif /* VMS */
- debug(F110,"ddcvt s2 (old)",s2,0);
- if ((f = fopen(s2,"r")) == NULL) { /* Reopen old file with wierd name */
- debug(F110,"ddcvt s2 open error",ck_errstr(),0);
- dirline = 0; /* (or in VMS, old version) */
- perror(s2);
- goto ddexit;
- }
- debug(F110,"ddcvt fopen(s2) OK",s2,0);
-
- debug(F110,"ddcvt s (new)",s,0);
- if ((f2 = fopen(s,"w")) == NULL) { /* Create new file with old name */
- debug(F110,"ddcvt s open error",ck_errstr(),0);
- perror(s); /* (or in VMS, new version) */
- goto ddexit;
- }
- debug(F110,"ddcvt fopen(s) OK",s,0);
-
- printf("\nSaving old directory as %s.\nConverting %s...",s2,s);
- fprintf(f2,"; %s - Kermit dialing directory\n", s);
- fprintf(f2,"%-16s %-20s ; %5s %-6s ; %s\n",
- "; Name","Number","Speed","Parity","Comment"
- );
-
- while (1) {
- linebuf[0] = NUL; /* Read a line */
- if (fgets(linebuf,1023,f) == NULL)
- break;
- debug(F110,"ddcvt linebuf",linebuf,0);
- if (!linebuf[0]) { /* Empty line */
- fprintf(f2,"\n");
- continue;
- }
- x = (int) strlen(linebuf); /* Strip line terminator, */
- while (x-- > 0) { /* if any. */
- if (linebuf[x] <= SP)
- linebuf[x] = NUL;
- else
- break;
- }
- xwords(linebuf,5,info,1); /* Parse it the old way */
- for (x = 1; x < 6; x++)
- if (!info[x]) info[x] = "";
- fprintf(f2,"%-16s %-20s ; %5s %-6s %s\n",
- info[1],info[2],info[3],info[4],info[5]
- );
- }
- printf(" OK\n\n");
- rc = 0; /* Success */
- ddexit:
- if (f) fclose(f);
- if (f2) fclose(f2);
-#ifdef VMS
- if (temp) free(temp);
-#endif /* VMS */
- return(rc);
-}
-
-int /* s = name to look up */
-#ifdef CK_ANSIC /* cx = index of command */
-ludial(char *s, int cx) /* (DIAL, LOOKUP, etc) */
-#else
-ludial(s, cx) char *s; int cx;
-#endif /* CK_ANSIC */
-/* ludial */ {
-
- int dd, n1, n2, n3, i, j, t; /* Workers */
- int olddir, newdir, oldentry, newentry;
- int pass = 0;
- int oldflg = 0;
- int ambiguous = 0; /* Flag for lookup was ambiguous */
- char *info[7]; /* Pointers to words from entry */
- char *pp; /* Pointer to element of array */
- FILE * f;
- char *line; /* File input buffer */
-
-/* #define LUDEBUG */
-
-#ifdef LUDEBUG
-int zz = 1;
-#endif /* LUDEBUG */
-
- if (!s || ndialdir < 1) /* Validate arguments */
- return(-1);
-
- if ((n1 = (int) strlen(s)) < 1) /* Length of string to look up */
- return(-1);
-
- if (!(line = malloc(1024))) /* Allocate input buffer */
- return(-1);
-
-#ifdef LUDEBUG
-if (zz) printf("LUDIAL 1 s[%s], n1=%d\n",s,n1);
-#endif /* LUDEBUG */
-
- pass = 0;
- lu_again:
- f = NULL; /* Dial directory file descriptor */
- t = dncount = 0; /* Dial-number match count */
- dd = 0; /* Directory counter */
- olddir = 0;
- newdir = 0;
-/*
- We need to recognize both old- and new-style directories.
- But we can't allow old-style and new-style entries in the same
- directory because there is no way to tell for sure the difference between
- an old-style entry like this:
-
- foo 5551212 9600
-
- and a new-style literal entry like this:
-
- foo 555 9600
-
- I.e. is the "9600" a speed, or part of the phone number?
-*/
- while (1) { /* We make one pass */
- if (!f) { /* Directory not open */
- if (dd >= ndialdir) /* No directories left? */
- break; /* Done. */
- debug(F111,"ludial dialdir[dd]",dialdir[dd],dd);
- if ((f = fopen(dialdir[dd],"r")) == NULL) { /* Open it */
- perror(dialdir[dd]); /* Can't, print message saying why */
- if (line) {
- free(line);
- line = NULL;
- }
- dd++; /* Go on to next one, if any... */
- continue;
- }
- dirline = 0; /* Directory file line number */
- if (dialdpy && !pass)
- printf("Opening: %s...\n",dialdir[dd]);
- dd++;
- if (!oldflg) olddir = 0;
- newdir = 0;
- }
- oldentry = 0;
- newentry = 0;
- line[0] = NUL;
- if (getnct(line,1023,f,1) < 0) { /* Read a line */
- if (f) { /* f can be clobbered! */
- fclose(f); /* Close the file */
- f = NULL; /* Indicate next one needs opening */
- oldflg = 0;
- }
- continue;
- }
- if (!line[0]) /* Empty line */
- continue;
-#ifdef LUDEBUG
-if (zz) printf("LUDIAL 2 s[%s]\n",s);
-#endif /* LUDEBUG */
-
- /* Make a copy and parse it the old way */
- /* A copy is needed because xwords() pokes NULs into the string */
-
- if ((pp = malloc((int)strlen(line) + 1))) {
- strcpy(pp,line); /* safe */
- xwords(pp,5,info,0); /* Parse it the old way */
-
-#ifdef LUDEBUG
-if (zz) printf("LUDIAL 3 s[%s]\n",s);
-#endif /* LUDEBUG */
-
- if (!info[1])
- continue;
- if (*info[1] == ';') { /* If full-line comment, */
- newdir = 1; /* (only new directories have them) */
- continue; /* keep reading. */
- }
- if (!info[2])
- continue;
- if (*info[2] == '+')
- newentry = 1;
- if (info[4]) {
- if ((*info[4] == '=') ||
- !ckstrcmp(info[4],"none", 4,0) ||
- !ckstrcmp(info[4],"even", 4,0) ||
- !ckstrcmp(info[4],"space",5,0) ||
- !ckstrcmp(info[4],"mark", 4,0) ||
- !ckstrcmp(info[4],"odd", 3,0)
- )
- oldentry = 1;
- }
- }
- if (pp) {
- free(pp);
- pp = NULL;
- }
-
- /* Check consistency */
-
- if ((oldentry || olddir) && (newentry || newdir)) {
- printf(
-"\nERROR: You seem to have old- and new-format entries mixed in your\n");
- printf(
-"dialing directory. You'll have to edit it by hand to convert it to the\n");
-#ifndef NOHELP
- printf("new format. Type HELP DIAL for further information.\n\n");
-#else
- printf("new format.\n\n");
-#endif /* NOHELP */
- if (line) {
- free(line);
- line = NULL;
- }
- return(-1);
- }
- if (!olddir && oldentry) {
- int convert = 0;
- olddir = 1;
- if (dialcvt == 2) { /* 2 == ASK */
- sprintf(tmpbuf,
-"WARNING: Old-style dialing directory detected:\n%s", line);
- convert = uq_ok(tmpbuf,
- "Shall I convert it for you? ",3,NULL,0);
- } else
- convert = dialcvt;
- if (convert) {
- debug(F111,"ludial calling ddcvt",dialdir[dd-1],dd);
- if (ddcvt(dialdir[dd-1],f,dd-1) < 0) {
- debug(F111,"ludial ddcvt failed",dialdir[dd-1],dd);
- oldflg = 1;
- printf(
-" Sorry, can't convert.");
- printf(
-" Will ignore speed and parity fields, continuing...\n\n");
- } else {
- olddir = newdir = 0;
- debug(F111,"ludial ddcvt ok",dialdir[dd-1],dd);
- }
- dd--;
- f = NULL;
- continue;
- } else {
- if (dialcvt == 2)
- printf(
-" OK, will ignore speed and parity fields, continuing...\n\n");
- olddir = 1;
- }
- }
-
-#ifdef LUDEBUG
-if (zz) printf("LUDIAL XX s[%s], n1=%d\n",s,n1);
-#endif /* LUDEBUG */
-
- /* Now parse again for real */
-
- if (oldentry) /* Parse it the old way */
- xwords(line,5,info,0);
- else /* Parse it the new way */
- xwords(line,2,info,1);
-
-#ifdef LUDEBUG
-if (zz) printf("LUDIAL YY s[%s], n1=%d\n",s,n1);
-if (zz) printf("%s [%s]\n",info[1],info[2]);
-#endif /* LUDEBUG */
-
- if (info[1]) { /* First word is entry name */
- if ((n3 = (int) strlen(info[1])) < 1) /* Its length */
- continue; /* If no first word, keep reading. */
- if (n3 < n1) /* Search name is longer */
- continue; /* Can't possibly match */
- if (ambiguous && n3 != n1)
- continue;
-
-#ifdef LUDEBUG
-if (zz) printf("MATCHING: [%s] [%s], n1=%d\n",s,info[1],n1);
-#endif /* LUDEBUG */
-
- if (ckstrcmp(s,info[1],n1,0)) /* Caseless string comparison */
- continue;
-
-#ifdef LUDEBUG
-if (zz) printf("MATCH OK: [%s] [%s], n1=%d\n",s,info[1],n1);
-#endif /* LUDEBUG */
-
- if (!info[2]) /* No phone number given */
- continue;
- if ((n2 = (int) strlen(info[2])) < 1) /* Length of phone number */
- continue; /* Ignore empty phone numbers */
-
- /* Got one */
-
- if (!(pp = (char *)malloc(n2 + 1))) { /* Allocate storage for it */
- printf("?internal error - ludial malloc 1\n");
- if (line) {
- free(line);
- line = NULL;
- }
- dncount = 0;
- return(-1);
- }
- strcpy(pp,info[2]); /* safe */
-
- if (dncount > MAXDNUMS) {
- printf("Warning: %d matches found, %d max\n",
- dncount,
- MAXDNUMS
- );
- dncount = MAXDNUMS;
- break;
- }
- dn_p[dncount++] = pp; /* Add pointer to array. */
- if (dncount == 1) { /* First one... */
- if (d_name) free(d_name);
- if (!(d_name = (char *)malloc(n3 + 1))) { /* Save its name */
- printf("?internal error - ludial malloc 2\n");
- if (line) {
- free(line);
- line = NULL;
- }
- dncount = 0;
- return(-1);
- }
- t = n3; /* And its length */
- strcpy(d_name,info[1]); /* safe */
- } else { /* Second or subsequent one */
-
-#ifdef LUDEBUG
- if (zz)
- printf("d_name=[%s],info[1]=%s,t=[%d]\n",d_name,info[1],t);
-#endif /* LUDEBUG */
-
- if ((int) strlen(info[1]) == t) /* Lengths compare */
- if (!ckstrcmp(d_name,info[1],t,0)) /* Caseless compare OK */
- continue;
-
- /* Name given by user matches entries with different names */
-
- if (ambiguous) /* Been here before */
- break;
-
- ambiguous = 1; /* Now an exact match is required */
- for (j = 0; j < dncount; j++) { /* Clean out previous list */
- if (dn_p[j]) {
- free(dn_p[j]);
- dn_p[j] = NULL;
- }
- }
- pass++; /* Second pass... */
- goto lu_again; /* Do it all over again. */
- }
- }
- }
- if (line) free(line);
- if (dncount == 0 && ambiguous) {
- printf(" Lookup: \"%s\" - ambiguous%s\n",
- s,
- cx == XXLOOK ? "" : " - dialing skipped"
- );
- return(-2);
- }
- return(dncount);
-}
-
-char *
-pncvt(s) char *s; { /* Phone number conversion */
- char *p = NULL; /* (just a wrapper for dncvt() */
- char *q = NULL;
- static char pnbuf[128];
- makestr(&p,dn_p[0]); /* Save these in case they are */
- makestr(&q,dn_p2[0]); /* being used */
- makestr(&dn_p[0],s); /* Copy the argument string to here */
- dncvt(0,XXLOOK,1,1); /* Convert it */
- if (!dn_p2[0]) /* Put result where can return it */
- pnbuf[0] = NUL;
- else
- ckstrncpy(pnbuf,dn_p2[0],127);
- makestr(&dn_p[0],p); /* Restore these */
- makestr(&dn_p2[0],q);
- makestr(&p,NULL); /* Free these */
- makestr(&q,NULL);
- return((char *)pnbuf);
-}
-
-int
-dodial(cx) int cx; { /* DIAL or REDIAL */
- int i = 0, x = 0; /* Workers */
- int sparity = -1; /* For saving global parity value */
- int previous = 0;
- int len = 0;
- int literal = 0;
- int flowsave;
- int lufound = 0; /* Did any lookup succeed? */
- int prefix = 1;
- int postfix = 1;
- int wasalpha = 0;
- int xredial = 0;
- int braces = 0;
-
- char *p = NULL, *s3 = NULL, * sav = NULL;
- int j = 0, t = 0, n = 0;
- int xretries, xlcc;
-
-#ifdef COMMENT
- debug(F101,"dodial cx","",cx);
- debug(F111,"dodial diallcc",diallcc,diallcc);
-#endif /* COMMENT */
-
- xretries = dialrtr; /* If retries not set, */
- if (diallcc) { /* choose default based on */
- xlcc = atoi(diallcc); /* local country code. */
- if (xretries < 0) {
- switch (xlcc) {
- case 1: xretries = 10; break; /* No restrictions in NANP */
- /* Add other country codes here */
- /* that are known to have no restrictions on redialing. */
- default: xretries = 1;
- }
- }
- }
- if (cx == XXPDIA) { /* Shortcut... */
- cx = XXDIAL;
- partial = 1;
- debug(F100,"PDIAL sets partial=1","",0);
- postfix = 0; /* Do not add postfix */
- } else {
- partial = 0;
- debug(F100,"DIAL sets partial=0","",0);
- }
- previous = dialsta; /* Status of previous call, if any */
- if (previous == DIA_PART) {
- prefix = 0; /* do not add prefix */
- }
- s = NULL; /* Initialize user's dial string */
- if (cx == XXRED) { /* REDIAL or... */
- if ((y = cmcfm()) < 0)
- return(y);
- } else if (cx == XXANSW) { /* ANSWER or ... */
- if ((y = cmnum("timeout (seconds)","0",10,&x,xxstring)) < 0)
- return(y);
- dialatmo = x;
- if ((y = cmcfm()) < 0)
- return(y);
- } else { /* DIAL or LOOKUP */
- if (ndialdir > 0)
- s3 = "Number to dial or entry from dial directory";
- else
- s3 = "Number to dial";
- if ((x = cmtxt(s3, dialnum ? dialnum : "",&s,xxstring)) < 0)
- return(x);
- if (s) {
- len = (int) strlen(s);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Save literal copy */
-#ifdef COMMENT
- if (len > 1) { /* Strip outer braces if given */
- if (*s == '{') {
- if (s[len-1] == '}') {
- s[len-1] = NUL;
- s++;
- len -= 2;
- }
- }
- }
-#else
- s = brstrip(s); /* Strip outer braces or quotes */
-#endif /* COMMENT */
- }
- }
-
- if (cx != XXLOOK) { /* Not LOOKUP */
-#ifdef IKSD
- if (inserver) {
- printf("Sorry, dialing is disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-#ifdef CK_TAPI
- if (tttapi && !tapipass) {
- ; /* Skip the modem test if TAPI */
- } else
-#endif /* CK_TAPI */
- if (mdmtyp < 1 && !dialtest) {
- if (network
-#ifdef TN_COMPORT
- && !istncomport()
-#endif /* TN_COMPORT */
- )
- printf("Please SET HOST first, and then SET MODEM TYPE\n");
- else
- printf("Sorry, you must SET MODEM TYPE first\n");
- dialsta = DIA_NOMO;
- return(success = 0);
- }
- if (!local && !dialtest) {
- printf("Sorry, you must SET %s or SET HOST first\n",
-#ifdef OS2
- "PORT"
-#else
- "LINE"
-#endif /* OS2 */
- );
- dialsta = DIA_NOLI;
- return(success = 0);
- }
- if ((!network
-#ifdef TN_COMPORT
- || istncomport()
-#endif /* TN_COMPORT */
- ) && !dialtest &&
-#ifdef CK_TAPI
- !tttapi &&
-#endif /* CK_TAPI */
- (speed < 0L)
-#ifdef UNIX
- && (strcmp(ttname,"/dev/null"))
-#else
-#ifdef OSK
- && (strcmp(ttname,"/nil"))
-#endif /* OSK */
-#endif /* UNIX */
- ) {
- printf("\nSorry, you must SET SPEED first\n");
- dialsta = DIA_NOSP;
- return(success = 0);
- }
- }
- if (cx != XXANSW) {
- for (j = 0; j < MAXDNUMS; j++) { /* Initialize dial-number list */
- if (!dialnum) { /* First time dialing */
- dn_p[j] = NULL; /* initialize all pointers. */
- dn_p2[j] = NULL;
- } else if (dn_p[j]) { /* Not the first time, */
- free(dn_p[j]); /* free previous, if any, */
- dn_p[j] = NULL; /* then set to NULL. */
- if (dn_p2[j])
- free(dn_p2[j]);
- dn_p2[j] = NULL;
- } else break; /* Already NULL */
- }
- if (len == 0)
- s = NULL;
- if (!s)
- s = dialnum;
- if (!s) {
- if (cx == XXLOOK)
- printf("?Lookup what?\n");
- else
- printf("%s\n", (cx == XXRED) ?
- "?No DIAL command given yet" :
- "?You must specify a number to dial"
- );
- return(-9);
- }
-
- /* Now we have the "raw" dial or lookup string and s is not NULL */
-
- makestr(&dscopy,s); /* Put it in a safe place */
- s = dscopy;
- n = 0;
-
- debug(F111,"dodial",s,ndialdir);
-
- wasalpha = 0;
- if (isalpha(*s)) {
- wasalpha = 1;
- if (ndialdir > 0) { /* Do we have a dialing directory? */
- n = ludial(s,cx); /* Look up what the user typed */
- if (n == 0)
- printf(" Lookup: \"%s\" - not found%s\n",
- s,
- cx == XXLOOK ? "" : " - dialing as given\n"
- );
- }
- debug(F101,"dodial",s,n);
- if (n < 0 && cx != XXLOOK) { /* Error out if they wanted to dial */
- if (n == -1) /* -2 means ludial already gave msg */
- printf(" Lookup: fatal error - dialing skipped\n");
- dialsta = DIA_DIR;
- return(-9);
- }
- if (n > 0) /* A successful lookup */
- lufound = 1;
- } else if (*s == '=') { /* If number starts with = sign */
- s++; /* strip it */
- literal = 1; /* remember this */
- while (*s == SP) s++; /* and then also any leading spaces */
- } else if (tmpbuf[0] == '{' && tmpbuf[1] == '{') {
- makelist(tmpbuf,dn_p,MAXDNUMS);
- makestr(&dscopy,tmpbuf);
- s = tmpbuf;
- for (n = 0; n < MAXDNUMS; n++) /* (have to count how many) */
- if (!dn_p[n]) break;
- braces = 1;
- }
- if (cx == XXLOOK && !wasalpha && !braces) {
- /* We've been told to lookup a number or a quoted name */
- char *p;
- n = 0;
- p = literal ? s : pncvt(dscopy);
- if (!p) p = "";
- if (*p) {
- printf("%s => %s\n", dscopy, p);
- return(success = 1);
- } else {
- printf("?Bad phone number\n");
- return(success = 0);
- }
- }
- /* Save DIAL or successful LOOKUP string for future DIAL or REDIAL */
- /* But don't save pieces of partial dial ... */
-
- debug(F101,"DIAL save dialnum partial","",partial);
- debug(F101,"DIAL save dialnum previous","",previous);
- if ((cx == XXDIAL && partial == 0 && previous != DIA_PART) ||
- (cx == XXLOOK && n > 0)) {
- makestr(&dialnum,dscopy);
- if (!quiet && dscopy && !dialnum)
- printf("WARNING - memory allocation failure: redial number\n");
- }
- if (n > 0) {
- if (!quiet && !backgrd && !braces /* && dialdpy */ ) {
- if (!strcmp(d_name,s))
- printf(" Lookup: \"%s\" - exact match\n",s);
- else
- printf(" Lookup: \"%s\" - uniquely matches \"%s\"\n",
- s,
- d_name
- );
- }
- if ((cx == XXLOOK) ||
- ((n > 1) && !quiet && !backgrd /* && dialdpy */ )) {
- printf(" %d telephone number%sfound for \"%s\"%s\n",
- n,
- (n == 1) ? " " : "s ",
- s,
- (n > 0) ? ":" : "."
- );
- s3 = getdname();
- }
- for (i = 0; i < n; i++) { /* Convert */
- dn_x[i] = -1;
- if (dncvt(i,cx,prefix,postfix) < 0) {
- if (cx != XXLOOK) {
- dialsta = DIA_DIR;
- return(-9);
- }
- }
- }
- if (dialsrt && n > 1) { /* Sort into optimal order */
- for (i = 0; i < n-1; i++) {
- for (j = i+1; j < n; j++) {
- if (dn_x[j] < dn_x[i]) {
- t = dn_x[j];
- dn_x[j] = dn_x[i];
- dn_x[i] = t;
- p = dn_p[j];
- dn_p[j] = dn_p[i];
- dn_p[i] = p;
- p = dn_p2[j];
- dn_p2[j] = dn_p2[i];
- dn_p2[i] = p;
- }
- }
- }
- }
- if ((cx == XXLOOK) ||
- ((n > 1) && !quiet && !backgrd /* && dialdpy */ )) {
- int nn = n;
-#ifndef NOSPL
- char * p;
-#endif /* NOSPL */
- if (cx != XXLOOK)
- if (n > 12) nn = 12;
- for (i = 0; i < nn; i++) {
- printf("%3d. %-12s %-20s => %-20s (%d)\n",i+1,
- s3, dn_p[i],
- dn_p2[i] ? dn_p2[i] : "(processing failed)",
- dn_x[i]
- );
- }
- if (cx != XXLOOK && n != nn)
- printf("And %d more...\n", n - nn);
- }
- } else if (n == 0) { /* Not found in directory */
- makestr(&(dn_p[0]),literal ? s : dscopy);
- makestr(&d_name,literal ? s : dscopy);
- dncount = 1;
- n = 1;
- if (dncvt(0,cx,prefix,postfix) < 0) { /* In case they typed a */
- dialsta = DIA_DIR; /* portable-format number ... */
- return(-9);
- }
- }
-
-#ifndef NONET
-#ifdef NETCONN
- /* It's not good that the networks directory depends on NOT-NODIAL.. */
- if (cx == XXLOOK && dscopy) { /* Networks here too... */
- extern char *nh_p[], *nh_p2[], *n_name;
- extern char *nh_px[4][MAXDNUMS+1];
- n = -1;
- if (nnetdir > 0) { /* Do we have a network directory? */
- dirline = 0;
- n = lunet(dscopy); /* Look up what the user typed */
- }
- if (n > -1) {
- int k;
- if (n > 0) /* A successful lookup */
- lufound = 1;
- if (cx == XXLOOK && n == 0)
- printf(" Lookup: \"%s\" - not found\n",dscopy);
- else
- printf("%s %d network entr%s found for \"%s\"%s\n",
- cx == XXLOOK ? " Lookup:" : "",
- n,
- (n == 1) ? "y" : "ies",
- dscopy,
- (n > 0) ? ":" : "."
- );
-
- for (i = 0; i < n; i++) {
-
- printf("%3d. %-12s => %-9s %s",
- i+1,n_name,nh_p2[i],nh_p[i]);
- for (k = 0; k < 4; k++) {
- if (nh_px[k][i]) {
- printf(" %s",nh_px[k][i]);
- } else
- break;
- }
- printf("\n");
- }
- }
- }
-#endif /* NETCONN */
-#endif /* NONET */
- if (cx == XXLOOK)
- return(success = lufound);
- } /* cx != XXANSW */
-
-#ifdef VMS
- conres(); /* So Ctrl-C/Y will work */
-#endif /* VMS */
-/*
- Some modems do not react well to parity. Also, if we are dialing through a
- TCP/IP TELNET modem server, parity can be fatally misinterpreted as TELNET
- negotiations.
-
- This should work even if the user interrupts the DIAL command, because the
- DIAL module has its own interrupt handler. BUT... if, for some reason, a
- dialing device actually *requires* parity (e.g. CCITT V.25bis says that even
- parity should be used), this might prevent successful dialing. For that
- reason, we don't do this for V.25bis modems.
-*/
- sparity = parity; /* Save current parity */
- if ((dialcapas & CKD_V25) == 0) /* If not V.25bis... */
- parity = 0; /* Set parity to NONE */
-
- flowsave = flow;
-/*
- These modems use some kind of screwy flow control while in command mode,
- and do not present CTS as they should. So if RTS/CTS is set (or even if
- it isn't) disable flow control during dialing.
-*/
-#ifndef MINIDIAL
- if (mdmtyp == n_ATT1910 || mdmtyp == n_ATT1900) {
- flow = FLO_NONE; /* This is not enough */
-#ifdef CK_TTSETFLOW
- ttsetflow(FLO_NONE); /* Really turn it off */
-#endif /* CK_TTSETFLOW */
- }
-#endif /* MINIDIAL */
- if (!network
-#ifdef TN_COMPORT
- || istncomport()
-#endif /* TN_COMPORT */
- ) {
- int x;
- if ((x = ttgmdm()) > -1) {
- if (!x && msgflg) {
- printf(
-"WARNING - No modem signals detected. Is your modem turned on? If not,\n\
-use Ctrl-C to interrupt dialing, turn on your modem, then %s.\n",
- cx == XXANSW ?
- "ANSWER again" :
- "REDIAL"
- );
- }
- if (flow == FLO_RTSC) {
- if (!(x & BM_CTS)) {
- if (msgflg)
- printf(
-"WARNING - SET FLOW RTS/CTS is in effect but modem's CTS signal is off.\n\
-Disabling flow control temporarily %s...\n",
- cx == XXANSW ?
- "while waiting for call" :
- "during dialing"
- );
- flow = FLO_NONE;
- }
- }
- }
- }
- if (cx == XXANSW) { /* ANSWER */
- success = ckdial("",0,0,1,0);
- goto dialfin;
- }
-
-/* Edit 192 adds the ability to dial repeatedly. */
-
- i = 0;
- dialcount = 0;
- do {
- if (i > 0) printf("\nDial attempt %d of %d...\n", i+1, xretries);
- dialcount = i+1;
- success = 0;
- /* And the ability to dial alternate numbers. */
- /* Loop to dial each in a list of numbers for the same name... */
- for (j = 0; j < n && !success; j++) { /* until one answers. */
- s = dn_p2[j]; /* Next number in list */
- if (dn_x[j] >= dialrstr) { /* Dial restriction */
- printf("Restricted: %s, skipping...\n",dn_p[j]);
- continue;
- }
- xredial = (i == 0 && j == 0) ? 0 : 1;
- if (!s) s = dn_p[j];
-
-#ifndef NOSPL
- sav = s;
- p = xdial(s); /* Apply DIAL macro now */
- if (p) if (*p) s = p;
-#endif /* NOSPL */
-
- /* Dial confirmation */
- /* NOTE: the uq_xxx() calls allow for a GUI dialog */
-
- if (i == 0 && dialcnf) {
- char msgbuf[128];
- ckmakmsg(msgbuf,128,"Dialing ",s,NULL,NULL);
- x = uq_ok(msgbuf,"Is this number correct? ",3,NULL,0);
- if (!x) {
-
-#ifndef COMMENT
- x = uq_txt( /* Allow GUI dialog */
-#ifdef OS2
-" Please enter the correct number,\r\n or press Enter to skip.",
-#else
-" Please enter the correct number,\r\n or press Return to skip.",
-#endif /* OS2 */
- "Corrected phone number: ",
- 1,
- NULL,
- atmbuf,
- ATMBL,
- s,
- DEFAULT_UQ_TIMEOUT
- );
- if (x && atmbuf[0]) { /* They gave a new one */
- s = atmbuf;
- makestr(&(dn_p2[j]), s);
- }
-
-#else /* COMMENT */
-
-#ifdef CK_RECALL
- extern int on_recall;
-#endif /* CK_RECALL */
- cmsavp(psave,PROMPTL);
- cmsetp(
-#ifdef OS2
-" Please enter the correct number,\r\n or press Enter to skip: "
-#else
-" Please enter the correct number,\r\n or press Return to skip: "
-#endif /* OS2 */
- );
- cmini(ckxech);
- x = -1;
- if (pflag) prompt(NULL);
-#ifdef CK_RECALL
- on_recall = 0;
-#endif /* CK_RECALL */
- y = cmdgquo();
- cmdsquo(0);
- while (x < 0) {
- x = cmtxt("Corrected phone number","",&s,NULL);
- cmres();
- }
- if ((int) strlen(s) < 1) {
- cmsetp(psave);
- continue;
- }
- makestr(&(dn_p2[j]), s);
- cmdsquo(y);
- cmsetp(psave);
-#endif /* COMMENT */
- }
- }
- if (dialtest) { /* Just testing */
- if (i + j == 0)
- printf("\nTESTING...\n");
- if (dialmac)
- printf(" Number: \"%s\" => \"%s\"\n",sav,s);
- else
- printf(" Number: \"%s\"\n",s);
- dialsta = DIA_BUSY;
- success = 0;
- } else {
- what |= W_DIALING;
- success = ckdial(s,i,j,partial ? 3 : 0, xredial); /* Dial it */
- what &= ~(W_DIALING);
- if (!success) {
- if (dialsta < 8 || /* Break out if unrecoverable error */
- dialsta == DIA_INTR ||
- dialsta == DIA_ERR ||
- previous == DIA_PART
- )
- break;
- }
- }
- }
- if (success) /* Succeeded, leave the outer loop */
- break;
- if (dialsta < 8 || /* Break out if unrecoverable error */
- dialsta == DIA_INTR || /* Interrupted */
- dialsta == DIA_NODT || /* No dialtone */
- dialsta == DIA_NOAC || /* Access forbidden */
- dialsta == DIA_BLCK || /* Blacklisted */
- dialsta == DIA_DIR || /* Dialing directory error */
- dialsta == DIA_ERR || /* Modem command error */
- previous == DIA_PART)
- break;
- if (++i >= xretries) /* Break out if too many tries */
- break;
- if (!backgrd && !quiet) {
- if (dialint > 5)
- printf(
-"\nWill redial in %d second%s- press any key to redial immediately.\n",
- dialint,
- dialint == 1 ? " " : "s "
- );
- printf("Ctrl-C to cancel...\n");
- }
- x = dialint; /* Redial interval */
- while (x-- > 0) {
- if ((y = conchk()) > 0) { /* Did they type something? */
- while (y--) coninc(0); /* Yes, absorb it */
- break; /* And wake up */
- }
- sleep(1); /* No interrupt, sleep a sec */
- }
- } while (!success);
-
- dialfin:
-
- if (cx != XXLOOK) {
- if (!success)
- bleep((short) BP_FAIL);
- else if (!quiet)
- bleep((short) BP_NOTE);
-#ifdef OS2
- setint(); /* Fix OS/2 interrupts */
-#endif /* OS2 */
- if (sparity > -1)
- parity = sparity; /* Restore parity if we saved it */
- flow = flowsave;
-#ifdef OS2
- ttres(); /* Restore DIAL device */
-#endif /* OS2 */
-#ifdef VMS
- concb((char)escape); /* Restore console */
-#endif /* VMS */
-#ifdef OS2
- { /* Set session title */
- char * p, name[72]; /* in window list. */
- char * q;
- if (cx == XXANSW) {
- q = "Incoming call";
- } else {
- if (d_name)
- q = d_name;
- else if (dialnum)
- q = dialnum;
- else if (ttname[0])
- q = ttname;
- else q = "";
- }
- p = name;
- if (success) {
- strncpy(name,q,48);
- while (*p) { /* Uppercase it for emphasis. */
- if (islower(*p))
- *p = toupper(*p);
- p++;
- }
- } else
- name[0] = NUL ;
- os2settitle((char *) name, TRUE);
- }
-#endif /* OS2 */
- }
- if (cx != XXLOOK) {
- if (success) {
- if (reliable == SET_AUTO) { /* It's not a reliable connection. */
- reliable = SET_OFF;
- debug(F101,"dodial reliable","",reliable);
- }
- } else {
-#ifndef NOHINTS
- extern int hints;
- if (hints && !quiet && dialsta != 9) { /* 9 == User interrupted */
- extern int dialmhu, dialhng, dialdpy;
- extern char * dialmsg[];
- printf("\n*************************\n");
- printf("DIAL-class command failed.\n");
- printf("Modem type: %s\n", gmdmtyp());
- printf("Device: %s\n", ttname);
- printf("Speed: %ld\n", speed);
- printf("Dial status: %d",dialsta);
- if (dialsta < 35 && dialmsg[dialsta])
- printf(" [%s]",dialmsg[dialsta]);
- printf("\n");
- if (dialsta == DIA_TIMO ||
- dialsta == DIA_NRDY ||
- (dialsta > 13 && dialsta != DIA_BUSY && dialsta != DIA_NOAN)
- ) {
- switch (dialsta) {
- case DIA_TIMO:
- printf(
-" . SET DIAL TIMEOUT to a greater value and try again.\n"
- );
- break;
- case DIA_NRSP:
- case DIA_NRDY:
- case DIA_NOIN:
- printf(
-" . Is the modem turned on?\n"
- );
- printf(
-" . Are you using the right communication port?\n"
- );
- break;
- case DIA_NODT:
- printf(
-" . Is the modem connected to the telephone line?\n"
- );
- }
- if (mdmtyp == n_GENERIC) {
- printf(
-" . Please choose a specific modem type with SET MODEM TYPE and try again.\n"
- );
- printf(
-" SET MODEM TYPE ? to see the list of known modem types.\n"
- );
- } else {
- printf(
-" . Are you sure you have chosen the appropriate modem type?\n"
- );
- }
- if (speed > 19200L) {
- printf(
-" . Maybe the interface speed (%ld) is too fast:\n", speed
- );
- printf(
-" SET SPEED to a lower speed and try again.\n"
- );
- printf(
-" SET SPEED ? to see the list of valid speeds.\n"
- );
- }
- if (dialhng) {
- if (dialmhu)
- printf(
-" . SET MODEM HANGUP-METHOD RS232 and try again.\n"
- );
- else
- printf(
-" . SET MODEM HANGUP-METHOD MODEM-COMMAND and try again.\n"
- );
- printf(
-" . If that doesn't work, try again with SET DIAL HANGUP OFF.\n"
- );
- } else {
- printf(
-" . Give a HANGUP or SET DIAL HANGUP ON command and try again.\n"
- );
- }
- if (!dialdpy)
- printf(
-" . Use SET DIAL DISPLAY ON to watch the dialog between Kermit and modem.\n"
- );
- }
-#ifndef NOSHOW
- printf(
-" . SHOW COMMUNICATIONS, SHOW MODEM, SHOW DIAL to see current settings.\n"
- );
-#endif /* NOSHOW */
-
-#ifndef NOHELP
- printf(
-" . HELP SET MODEM, HELP SET DIAL, and HELP DIAL for more information.\n"
- );
-#endif /* NOHELP */
- printf("(Use SET HINTS OFF to suppress future hints.)\n");
- printf("*************************\n\n");
- }
-#endif /* NOHINTS */
- }
- }
- return(success);
-}
-#endif /* NODIAL */
-
-/* D O T Y P E -- Type (display) a file with various options... */
-
-#ifdef BIGBUFOK
-#define TYPBUFL 16384
-#else
-#define TYPBUFL 256
-#endif /* BIGBUFOK */
-
-int typ_lines = 0; /* \v(ty_ln) */
-int typ_mtchs = 0; /* \v(ty_lm) */
-static int typ_int = 0; /* Flag if TYPE interrupted */
-
-#ifdef UNICODE
-extern int fcharset, fileorder, byteorder, ucsorder;
-#define TYPXBUFL TYPBUFL+TYPBUFL+TYPBUFL+4
-static char * mp = NULL;
-static char * mbuf = NULL;
-static long xn = 0L;
-
-static int
-#ifdef CK_ANSIC
-storechar(char c)
-#else
-storechar(c) char c;
-#endif /* CK_ANSIC */
-{
- if (!mp) return(-1);
- if (++xn > TYPXBUFL)
- return(-1);
- debug(F111,"storechar xn",ckitoa((int)c),xn);
- *mp++ = c;
- return(0);
-}
-#endif /* UNICODE */
-
-static FILE * ofp = NULL; /* For /OUTPUT: file */
-
-static int
-typeline(buf,len,outcs,ofp) char * buf; int len, outcs; FILE * ofp; {
- register int i;
-
- debug(F011,"typeline buf",buf,len);
- /* debug(F101,"typeline outcs","",outcs); */
-
-#ifdef OS2
-#ifndef NOLOCAL
-#ifdef UNICODE
- /* In K95 only, the buffer is guaranteed to be in UCS-2 if outcs >= 0. */
- /* Len is its length in bytes. There is no line terminator. */
- /* outcs is the file character-set number (FC_xxx) of the target set */
- /* that was requested by the user. */
- if (!inserver && !k95stdout) {
- extern int wherex[], wherey[];
- extern unsigned char colorcmd;
-
- VscrnWrtUCS2StrAtt( VCMD, (unsigned short *)buf, len/2,
- wherey[VCMD], wherex[VCMD], &colorcmd);
- printf("\r\n");
- return(0);
- }
-#endif /* UNICODE */
-#endif /* NOLOCAL */
-#endif /* OS2 */
-
-/* In Unix, VMS, etc, the line has already been converted to the desired */
-/* character-set, if one was given. OR... on all platforms, including in */
-/* K95, we don't know the character set. In either case we dump the line */
-/* byte by byte in case it contains NULs (printf() would truncate). */
-
-#ifdef COMMENT
- for (i = 0; i < len; i++)
- putchar(buf[i]);
-#else
- for (i = 0; i < len; i++) {
- if (ofp == stdout) {
- putchar(buf[i]);
- } else {
- putc(buf[i],ofp);
- }
- }
-#endif /* COMMENT */
-
-#ifdef IKSD
- if (inserver) {
-#ifdef UNICODE
- if (outcs == FC_UCS2) {
- if (ofp == stdout) {
- putchar(NUL);
- } else {
- putc(NUL,ofp);
- }
- }
-#endif /* UNICODE */
- if (ofp == stdout) {
- putchar('\r');
- } else {
- putc('\r',ofp);
- }
- }
-#endif /* IKSD */
-#ifdef UNICODE
- if (outcs == FC_UCS2) {
- if (ofp == stdout) {
- putchar(NUL);
- } else {
- putc(NUL,ofp);
- }
- }
-#endif /* UNICODE */
- if (ofp == stdout) {
- putchar('\n');
- } else {
- putc('\n',ofp);
- }
- fflush(stdout);
- return(0);
-}
-
-static int /* Get translated line */
-typegetline(incs, outcs, buf, n) int incs, outcs, n; char * buf; {
- int x = 0, c0, c1, len = 0, count = 0, eof = 0, xlate = 0;
-#ifdef UNICODE
- int xxn = -1;
- int yyn = -9;
- xn = 0L;
-
-#ifdef DEBUG
- if (deblog && typ_lines == 0) {
- debug(F101,"typegetline incs","",incs);
- debug(F101,"typegetline outcs","",outcs);
- debug(F101,"typegetline feol","",feol);
- debug(F101,"typegetline byteorder","",byteorder);
- debug(F101,"typegetline ucsorder ","",ucsorder);
- debug(F111,"typegetline fileorder","1",fileorder);
- }
-#endif /* DEBUG */
-
- if (incs < 0) /* Shouldn't happen */
- return(-2);
-
- if (outcs == -1) /* Can happen */
- outcs = incs;
-
- if (incs != outcs || incs == FC_UCS2) { /* See if we should translate */
- xlate = 1;
- if (!mbuf) { /* Allocate buffer if not allocated */
- mbuf = (char *)malloc(TYPXBUFL+1); /* yet */
- if (!mbuf) {
- printf("WARNING: Translation buffer allocation failure.\n");
- printf("Translation will be skipped...\n");
- xlate = 0;
- }
- }
- }
- if (xlate) { /* Translating... */
- mp = mbuf; /* Reset working buffer pointer */
-/*
- Here we call xgnbyte() in a loop, having it return UCS-2 bytes. In K95, we
- use UCS-2 directly. Elsewhere, we feed the UCS-2 bytes into xpnbyte() to
- convert them to the desired target character set. But since we are using
- UCS-2, we have several sources for confusion: (1) xgnbyte() might return in
- LE or BE byte order, with no explicit indication of what the order is; but
- (2) xpnbyte() wants BE; but (3) Windows wants LE.
-*/
- while (1) {
- if (typ_int) /* Quit if interrupted */
- return(0);
- c0 = xgnbyte(FC_UCS2,incs,NULL); /* Convert to UCS-2 */
- debug(F000,"typegetline c0","",c0);
- if (c0 < 0) { /* EOF */
- eof++;
- break;
- }
- c1 = xgnbyte(FC_UCS2,incs,NULL); /* Convert to UCS-2 */
- debug(F000,"typegetline c1","",c1);
- if (c1 < 0) { /* EOF */
- eof++;
- break;
- }
-#ifdef DEBUG
- if (deblog && typ_lines == 0) {
- if (count == 0) /* Check fileorder after BOM */
- debug(F111,"typegetline fileorder","2",fileorder);
- }
-#endif /* DEBUG */
-
-#ifdef COMMENT
-/* Now we have the two UCS-2 bytes. Which order are they in? */
-
- if (fileorder > 0) { /* Little Endian */
- int t; /* So swap them */
- debug(F100,"typegetline swapping","",0);
- t = c1;
- c1 = c0;
- c0 = t;
- }
-#endif /* COMMENT */
- if (c0 == 0 && c1 == 0x0D) /* Now see if we have EOL */
- yyn = xn;
-
- if (c0 == 0 && c1 == 0x0A) /* Now see if we have EOL */
- xxn = xn;
-
- count++; /* Count byte */
-
-/* Give the two bytes to xpnbyte() in BE order */
-
- if ((x = xpnbyte(c0,TC_UCS2,outcs,storechar)) < 0) return(-1);
- if ((x = xpnbyte(c1,TC_UCS2,outcs,storechar)) < 0) return(-1);
-
- if (xxn > -1) { /* Have end of line? */
- xn = xxn;
- if (yyn == xxn - 2) /* Adjust for CRLF */
- xn = yyn;
- break; /* And break out of loop. */
- }
- }
- mbuf[xn] = NUL;
- if (xn > n) /* Can truncate here... */
- xn = n;
- memcpy(buf,mbuf,xn);
- debug(F011,"typegetline xlate",buf,xn);
- return((eof && (xn == 0)) ? -1 : xn);
- }
-#endif /* UNICODE */
-#ifdef COMMENT
- /* We can't use this because, stupidly, zsinl() doesn't return a length. */
- /* It could be changed but then we'd have to change all ck?fio.c modules */
- x = zsinl(ZIFILE,buf,n);
-#else
- /* So instead, we copy zsinl() to here... */
- /* But note: This does not necessarily handle UCS-2 alignment properly; */
- /* that's what the code in the first section of this routine is for. */
- /* But it does tolerate files that contain NULs. */
- {
- int a;
- char *s;
-
- s = buf;
- a = -1; /* Current character, none yet. */
- debug(F101,"typegetline zsinl simulation","",n);
- while (n--) { /* Up to given length */
-#ifdef COMMENT
- int old = 0;
- if (feol) /* Previous character */
- old = a;
-#endif /* COMMENT */
- if (zchin(ZIFILE,&a) < 0) { /* Read a character from the file */
- debug(F101,"typegetline zchin fail","",count);
- if (count == 0)
- x = -1; /* EOF or other error */
- break;
- } else
- count++;
- if (feol) { /* Single-character line terminator */
- if (a == feol)
- break;
- } else { /* CRLF line terminator */
-#ifdef COMMENT
-/* Debug log shows that in Windows, <CR><LF> is returned as <LF>. */
-/* Apparently we're not reading the file in binary mode. */
-
- if (a == '\015') /* CR, get next character */
- continue;
- if (old == '\015') { /* Previous character was CR */
- if (a == '\012') { /* This one is LF, so we have a line */
- break;
- } else { /* Not LF, deposit CR */
- *s++ = '\015';
- n--;
- len++;
- }
- }
-#else
- if (a == LF) {
- if (s[len] == CR) { /* This probably won't happen */
- s[len] = NUL;
- s--;
- len--;
- }
- break;
- }
-#endif /* COMMENT */
- }
- *s = a; /* Deposit character */
- s++;
- len++;
- }
- *s = '\0'; /* Terminate the string */
- }
-#endif /* COMMENT */
- return(x < 0 ? -1 : len);
-}
-
-
-#ifndef MAC
-SIGTYP
-#ifdef CK_ANSIC
-tytrap(int foo) /* TYPE interrupt trap */
-#else
-tytrap(foo) int foo;
-#endif /* CK_ANSIC */
-/* tytrap */ {
-#ifdef __EMX__
- signal(SIGINT, SIG_ACK);
-#endif
- debug(F100,"type tytrap SIGINT","",0);
- typ_int = 1; /* (Need arg for ANSI C) */
- SIGRETURN;
-}
-#endif /* MAC */
-
-int
-dotype(file, paging, first, head, pat, width, prefix, incs, outcs, outfile, z)
- char * file, * pat, * prefix; int paging, first, head, width, incs, outcs;
- char * outfile; int z;
-/* dotype */ {
- extern CK_OFF_T ffc;
- char buf[TYPBUFL+2];
- char * s = NULL;
- int rc = 1, lines = 0, ucs2 = 0;
- char ** tail = NULL;
- int * tlen = NULL;
- int tailing = 0, counting = 0;
- int x, c, n, i, j, k = 0;
- int number = 0, save, len, pfxlen = 0, evalpfx = 1;
-#ifdef UNICODE
- int ucsbom_sav;
- extern int ucsbom;
-#endif /* UNICODE */
-#ifdef NT
- int gui = 0;
-#endif /* NT */
-
-#ifndef MAC
-#ifdef OS2
-#ifdef NT
- SIGTYP (* oldsig)(int); /* For saving old interrupt trap. */
-#else /* NT */
- SIGTYP (* volatile oldsig)(int);
-#endif /* NT */
-#else /* OS2 */
- SIGTYP (* oldsig)();
-#endif /* OS2 */
-#endif /* MAC */
-
-#ifdef KUI
- if (outfile == (char *)1) {
- gui = 1;
- outfile = "";
- }
-#endif /* KUI */
-
- if (!file) file = "";
- if (!*file) return(-2);
-
- if (ofp != stdout) { /* In case of previous interruption */
- if (ofp) fclose(ofp);
- ofp = stdout;
- }
- if (!outfile) outfile = "";
- if (outfile[0]) {
- ofp = fopen(outfile,"w"); /* Open output file */
- if (!ofp) {
- printf("?Can't open output file %s: %s\n",outfile,ck_errstr());
- ofp = stdout;
- return(-9);
- }
- }
- number = z;
- if (number && prefix) prefix = NULL;
-
-#ifdef UNICODE
- ucsbom_sav = ucsbom; /* We are not creating a file */
- ucsbom = 0; /* Do not use BOM bytes */
-#endif /* UNICODE */
-
- typ_int = 0;
-
- save = binary; /* Save file type */
-
- debug(F101,"dotype incs","",incs);
- debug(F101,"dotype outcs","",outcs);
-
-#ifdef UNICODE
- debug(F111,"dotype fileorder","A",fileorder);
-#ifdef OS2
- if (!inserver && !k95stdout)
- outcs = FC_UCS2;
-#endif /* OS2 */
-
- if (outcs == FC_UCS2) /* Output is UCS-2? */
- ucs2 = 1;
- if (fileorder < 0)
- fileorder = ucsorder;
- debug(F111,"dotype fileorder","B",fileorder);
-#endif /* UNICODE */
-
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- /* Check whether window size changed */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- debug(F101,"dotype cmd_rows","",cmd_rows);
- debug(F101,"dotype cmd_cols","",cmd_cols);
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
- if (prefix)
- pfxlen = strlen(prefix);
-
- if (paging < 0) { /* Count only, don't print */
- counting = 1;
- prefix = NULL;
- width = 0;
- paging = 0;
- }
- if (ucs2) /* Crude... */
- width *= 2;
-
-#ifdef OS2
- if (*file) {
- ckstrncpy(buf, file, TYPBUFL); /* Change / to \. */
- p = buf;
- while (*p) {
- if (*p == '/') *p = '\\';
- p++;
- }
- file = buf;
- } else {
- rc = 0;
- goto xdotype;
- }
-#endif /* OS2 */
-
- if (zchki(file) == -2) { /* It's a directory */
- debug(F111,"dotype zchki failure",file,-2);
- if (xcmdsrc == 0) {
- printf("?Not a regular file: \"%s\"\n",file);
- rc = -9;
- } else
- rc = 0;
- goto xdotype;
- }
- if (!zopeni(ZIFILE, file)) { /* Not a directory, open it */
- debug(F111,"dotype zopeni failure",file,0);
- if (xcmdsrc == 0) {
- printf("?Can't open file: \"%s\"\n",file);
- rc = -9;
- } else
- rc = 0;
- goto xdotype;
- }
-
-#ifndef AMIGA
-#ifndef MAC
- errno = 0;
- oldsig = signal(SIGINT, tytrap); /* Save current interrupt trap. */
- /* debug(F111,"type SIGINT trap set",ckitoa(errno),oldsig); */
-#endif /* MAC */
-#endif /* AMIGA */
-
- if (paging > -1) /* More-prompting */
- xaskmore = paging;
-
- binary = 0;
-
- if (head < 0) { /* "tail" was requested */
- tailing = 1; /* Set flag */
- head = 0 - head; /* Get absolute number of lines */
- if (!counting) {
- tail = (char **) malloc(head * sizeof(char *)); /* Allocate list */
- if (!tail) {
- printf("?Memory allocation failure\n");
- goto xdotype;
-
- }
- tlen = (int *) malloc(head * sizeof(int));
- if (!tlen) {
- printf("?Memory allocation failure\n");
- goto xdotype;
-
- }
- for (i = 0; i < head; i++) { /* Initialize each pointer in list. */
- tail[i] = NULL;
- tlen[i] = 0;
- }
- }
- }
- typ_lines = 0;
- typ_mtchs = 0;
-
-#ifdef UNICODE
- if (outcs > -1 && (incs != outcs || incs == FC_UCS2)) { /* Translating? */
- ffc = (CK_OFF_T)0;
- initxlate(incs,outcs); /* Set up translation functions */
- } else
-#endif /* UNICODE */
- outcs = -1; /* Means we don't know the charset */
-
- debug(F101,"dotype ffc","",ffc);
- debug(F101,"dotype outcs 2","",outcs);
-#ifdef UNICODE
- debug(F111,"dotype fileorder","C",fileorder);
-#endif /* UNICODE */
-
- /* Allow the buffer to contain NULs */
-
- for (n = first;
- (len = typegetline(incs,outcs,buf,TYPBUFL)) > -1;
- lines++
- ) {
- debug(F011,"dotype line",buf,len);
-#ifndef MAC
- if (typ_int) { /* Interrupted? */
- typ_int = 0;
- debug(F101,"type interrupted line","",lines);
- printf("^C...\n"); /* Print message */
- if (ofp != stdout) { /* Close any output file */
- if (ofp) fclose(ofp);
- ofp = stdout;
- }
- goto xxdotype;
- }
-#endif /* MAC */
- typ_lines++; /* For \v(ty_ln) */
- if (pat) /* Matching? */
- if (!ckmatch(pat,buf,1,1+4)) /* Line matches pattern? */
- continue; /* No, skip it */
- typ_mtchs++;
-
- if (head > 0 && !tailing && lines == head) /* Handle /HEAD:n */
- break;
-
- buf[TYPBUFL+1] = NUL; /* Just in case... */
- if (prefix) { /* Add specified prefix to each line */
- char pbuf[64];
- char * pp;
- pp = prefix;
-#ifndef NOSPL
- if (evalpfx) { /* Prefix is a variable? */
- int n = 63; /* Maybe - evaluate it and see */
- char * p = pbuf;
- zzstring(prefix,&p,&n); /* If there is no change */
- if (!strcmp(prefix,pbuf)) { /* it's not a variable */
- evalpfx = 0; /* So don't do this again. */
- } else { /* It was a variable */
- pp = pbuf; /* So substitute its value */
- pfxlen = 63 - n; /* and get its new length */
- }
- }
-#endif /* NOSPL */
- if (len + pfxlen + 2 < TYPBUFL) {
- /* Shift right to make room for prefix */
- memcpy((char *)line+pfxlen,(char *)buf,len);
- lset((char *)line,pp,pfxlen,SP);
- debug(F110,"dotype prefix",line,pfxlen);
- len += pfxlen;
- memcpy((char *)buf,(char *)line,len);
- }
- } else if (number) { /* Line numbers */
- int x;
- sprintf(line,"%4d. ",typ_lines);
- x = strlen(line);
- len += x;
- if (len < LINBUFSIZ) {
- memcpy((char *)&line[x],(char *)buf,len);
- memcpy((char *)buf,(char *)line,len);
- }
- }
- if (width > 0 && width <= TYPBUFL) { /* Truncate at given width. */
- char * obuf = line; /* But to do that first we must */
- int i,k,z; /* expand tabs; assume every 8 cols. */
- line[0] = NUL;
- for (i = 0, k = 0; i < width; k++) { /* Character loop... */
- if (!buf[k]) /* No more chars in this line, done. */
- break;
- if (buf[k] != '\t') { /* If it's not a tab */
- if (i >= LINBUFSIZ) /* Check for overflow */
- break;
- obuf[i++] = buf[k]; /* and then deposit it. */
- obuf[i] = NUL; /* Keep it null-terminated */
- continue;
- }
- z = 8 - (i % 8); /* It's a tab, expand it. */
- if (z == 0) z = 8;
- for (j = 0; j < z && i < LINBUFSIZ; j++) {
-#ifdef UNICODE
- if (ucs2 && !ucsorder)
- obuf[i++] = NUL;
-#endif /* UNICODE */
- obuf[i++] = ' ';
-#ifdef UNICODE
- if (ucs2 && ucsorder)
- obuf[i++] = NUL;
-#endif /* UNICODE */
- }
- obuf[i++] = NUL;
- obuf[i] = NUL;
- }
- obuf[width] = NUL; /* Now truncate at given width. */
-#ifdef COMMENT
- /* This doesn't work for UCS-2 because it contains NULs */
- ckstrncpy(buf,obuf,TYPBUFL); /* and copy it back (again?) */
-#else
- memcpy((char *)buf,(char *)obuf,i); /* Copy it back */
-#endif /* COMMENT */
- len = (i > width) ? width : i; /* Spare us another strlen()... */
- }
- if (tailing) { /* If /TAIL:n... */
- k = lines % head; /* save this line in circular buffer */
- if (!counting) {
- if (tail[k]) free(tail[k]);
- tail[k] = malloc(len+2);
- if (!tail[k]) {
- printf("?Memory allocation failure\n");
- goto xdotype;
- }
- memcpy(tail[k],buf,len);
- tlen[k] = len;
- continue;
- }
- }
- if (counting) /* If only counting */
- continue; /* we're done with this line */
-
- if (paging) { /* Displaying this line... */
- int u;
- u = len; /* Length in BYTES */
- if (ucs2) /* If outputting in UCS-2 */
- u /= 2; /* convert length to CHARACTERS */
- x = (u / cmd_cols) + 1; /* Crudely allow for wrap */
- if (cmd_rows > 0 && cmd_cols > 0)
- n += x; /* This assumes terminal will wrap */
- }
-#ifdef KUI
- if ( gui ) {
- int i;
- unsigned short * uch = (unsigned short *)buf;
- for ( i=0; i<len/2; i++)
- gui_text_popup_append(uch[i]);
- gui_text_popup_append(CR);
- gui_text_popup_append(LF);
- }
- else
-#endif /* KUI */
- typeline(buf,len,outcs,ofp); /* Print line, length based */
-#ifdef CK_TTGWSIZ
- debug(F101,"dotype n","",n);
- if (paging > 0 && ofp == stdout) { /* Pause at end of screen */
- if (cmd_rows > 0 && cmd_cols > 0) {
- if (n > cmd_rows - 3) {
- if (!askmore())
- goto xdotype;
- else
- n = 0;
- }
- }
- }
-#endif /* CK_TTGWSIZ */
- }
-
- xdotype:
- if (counting) {
- fprintf(ofp,
- "%s: %d line%s\n",file,typ_lines,typ_lines == 1 ? "" : "s");
- if (pat)
- fprintf(ofp,
- "%s: %d match%s\n",pat,typ_mtchs,typ_mtchs == 1 ? "" : "es");
- goto xxdotype;
- }
- if (tailing && tail) { /* Typing tail of file? */
- if (lines < head) { /* Yes, show the lines we saved */
- k = 0; /* Show all lines */
- } else { /* More lines than tail number */
- lines = k; /* Last line to show */
- k++; /* First line to show */
- if (k >= head)
- k = 0;
- }
- n = first; /* Output line counter */
- for (i = k ;; i++) { /* Loop thru circular buffer */
-#ifndef MAC
- if (typ_int) { /* Interrupted? */
- printf("^C...\n"); /* Print message */
- goto xxdotype;
- }
-#endif /* MAC */
- j = i % head; /* Index of this line */
- s = tail[j]; /* Point to line to display */
- if (!s) /* (shouldn't happen...) */
- break;
- if (paging) { /* Crudely allow for line wrap */
- x = tlen[j];
- if (ucs2) x /= 2;
- x = x / cmd_cols + 1;
- if (cmd_rows > 0 && cmd_cols > 0)
- n += x;
- }
- typeline(s,tlen[j],outcs,ofp); /* Display this line */
- if (paging && ofp == stdout) { /* Pause at end of screen */
- if (cmd_rows > 0 && cmd_cols > 0) {
- if (n > cmd_rows - 3) {
- if (!askmore())
- break;
- else
- n = 0;
- }
- }
- }
- tail[j] = NULL;
- free(s); /* Free the line */
- if (i % head == lines) /* When to stop */
- break;
- }
- free((char *)tail); /* Free the list */
- tail = NULL;
- if (tlen) free((char *)tlen);
- tlen = NULL;
- }
-
-/* Come here when finished or on SIGINT */
-
- xxdotype:
-#ifndef AMIGA
-#ifndef MAC
- signal(SIGINT,oldsig); /* Put old signal action back. */
-#endif /* MAC */
-#endif /* AMIGA */
- if (tailing && tail) {
- for (i = 0; i < head; i++) { /* Free each line. */
- if (tail[i])
- free(tail[i]);
- }
- free((char *)tail); /* Free list pointer */
- if (tlen)
- free((char *)tlen);
- }
- x = zclose(ZIFILE); /* Done, close the input file */
- if (ofp != stdout) { /* Close any output file */
- if (ofp) fclose(ofp);
- ofp = stdout;
- }
- binary = save; /* Restore text/binary mode */
-#ifdef UNICODE
- ucsbom = ucsbom_sav; /* Restore BOM usage */
-#endif /* UNICODE */
-
-#ifdef KUI
- if ( gui )
- gui_text_popup_wait(-1); /* Wait for user to close the dialog */
-#endif /* KUI */
- return(rc);
-}
-
-/* GREP command */
-
-#define GREP_CASE 0 /* /CASE */
-#define GREP_COUN 1 /* /COUNT */
-#define GREP_DOTF 2 /* /DOTFILES */
-#define GREP_NAME 3 /* /NAMEONLY */
-#define GREP_NOBK 4 /* /NOBACKUP */
-#define GREP_NODO 5 /* /NODOTFILES */
-#define GREP_NOLI 6 /* /NOLIST */
-#define GREP_NOMA 7 /* /INVERT = /NOMATCH */
-#define GREP_NOPA 8 /* /NOPAGE */
-#define GREP_NUMS 9 /* /LINENUMBERS */
-#define GREP_PAGE 10 /* /PAGE */
-#define GREP_RECU 11 /* /RECURSIVE */
-#define GREP_TYPE 12 /* /TYPE: */
-#define GREP_OUTP 13 /* /OUTPUTFILE: */
-#define GREP_EXCP 14 /* /EXCEPT: */
-
-static struct keytab greptab[] = {
- { "/count", GREP_COUN, CM_ARG },
- { "/dotfiles", GREP_DOTF, 0 },
- { "/except", GREP_EXCP, CM_ARG },
- { "/linenumbers", GREP_NUMS, 0 },
- { "/nameonly", GREP_NAME, 0 },
- { "/nobackupfiles",GREP_NOBK, 0 },
- { "/nocase", GREP_CASE, 0 },
- { "/nodotfiles", GREP_NODO, 0 },
- { "/nolist", GREP_NOLI, 0 },
- { "/nomatch", GREP_NOMA, 0 },
- { "/nopage", GREP_NOPA, 0 },
- { "/output", GREP_OUTP, CM_ARG },
- { "/page", GREP_PAGE, 0 },
- { "/quiet", GREP_NOLI, CM_INV },
-#ifdef RECURSIVE
- { "/recursive", GREP_RECU, 0 },
-#endif /* RECURSIVE */
- { "/type", GREP_TYPE, CM_ARG },
- { "", 0, 0 }
-};
-static int ngreptab = sizeof(greptab)/sizeof(struct keytab)-1;
-
-static char * grep_except = NULL;
-
-int
-dogrep() {
- int match, x, y, fc, getval, mc = 0, count = 0, bigcount = 0;
- int fline = 0, sline = 0, wild = 0, len = 0;
- int xmode = -1, scan = 0;
- char c, name[CKMAXPATH+1], outfile[CKMAXPATH+1], *p, *s, *cv = NULL;
- FILE * fp = NULL;
-
- int /* Switch values and defaults */
- gr_coun = 0,
- gr_name = 0,
- gr_nobk = 0,
- gr_case = 1,
- gr_noli = 0,
- gr_noma = 0,
- gr_nums = 0,
- gr_excp = 0,
- gr_page = xaskmore;
-
- struct FDB sw, fl;
-
- g_matchdot = matchdot; /* Save global matchdot setting */
- outfile[0] = NUL;
- makestr(&grep_except,NULL);
-
- if (ofp != stdout) { /* In case of previous interruption */
- if (ofp) fclose(ofp);
- ofp = stdout;
- }
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "String or pattern to search for, or switch",
- "", /* default */
- "", /* addtl string data */
- ngreptab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- greptab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Anything that doesn't match */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring, /* xxstring */
- NULL,
- NULL
- );
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse something */
- if (x < 0)
- return(x);
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if ((cmresult.nresult != GREP_COUN) && !getval &&
- (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (cmresult.nresult) {
- case GREP_COUN: {
- gr_coun++;
- if (getval) {
- if ((x = cmfld("Variable for result","",&s,NULL)) < 0)
- return(x);
- makestr(&cv,s);
- }
- break;
- }
- case GREP_CASE: gr_case=0; break;
- case GREP_NAME: gr_name++; gr_noli=0; break;
- case GREP_NOBK: gr_nobk++; break;
- case GREP_NOLI: gr_noli++; gr_name=0; gr_nums=0; break;
- case GREP_NOMA: gr_noma++; break;
- case GREP_NOPA: gr_page=0; break;
- case GREP_NUMS: gr_nums++; gr_noli=0; break;
- case GREP_PAGE: gr_page++; gr_noli=0; break;
- case GREP_NODO:
- matchdot = 0;
- break;
- case GREP_DOTF:
- matchdot = 1;
- break;
-#ifdef RECURSIVE
- case GREP_RECU:
- recursive = 1;
- break;
-#endif /* RECURSIVE */
- case GREP_TYPE: {
- extern struct keytab txtbin[];
- if ((x = cmkey(txtbin,3,"","",xxstring)) < 0)
- return(x);
- if (x == 2) { /* ALL */
- xmode = -1;
- } else { /* TEXT or BINARY only */
- xmode = x;
- scan = 1;
- }
- break;
- }
- case GREP_OUTP: /* Send output to file */
- if ((x = cmofi("File for GREP'd lines","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(outfile,s,CKMAXPATH);
- break;
- case GREP_EXCP: /* Exception pattern */
- if (getval) {
- if ((x = cmfld("Exception pattern",
- "",
- &s,
- xxstring
- )) < 0)
- return(x);
- gr_excp++;
- makestr(&grep_except,s);
- }
- }
- }
- if (outfile[0]) {
- ofp = fopen(outfile,"w"); /* Open output file */
- if (!ofp) {
- printf("?Can't open output file %s: %s\n",outfile,ck_errstr());
- ofp = stdout;
- return(-9);
- }
- gr_page = 0;
- }
- s = cmresult.sresult;
- s = brstrip(s); /* Strip braces from pattern */
- if (!*s) {
- printf("?Pattern required\n");
- return(-9);
- }
- ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Save pattern */
- if ((x = cmifi("File(s) to search","",&s,&wild,xxstring)) < 0) {
- if (x == -3) {
- printf("?File specification required\n");
- x = -9;
- }
- return(x);
- }
- s = brstrip(s); /* Strip braces from filename */
-#ifndef ZXREWIND
- ckstrncpy(line,s,LINBUFSIZ);
-#endif /* ZXREWIND */
- if ((y = cmcfm()) < 0)
- return(y);
-
- if (gr_page > -1)
- xaskmore = gr_page; /* Paging... */
-
- p = tmpbuf; /* Point to pattern */
-#ifdef COMMENT
-/* Now this is done in ckmatch */
- if (*p == '^') { /* '^' anchors pattern to beginning */
- p++;
- } else if (*p != '*') { /* Otherwise prepend implied '*' */
- tmpbuf[0] = '*';
- p = tmpbuf;
- }
- x = strlen(p); /* Get length of result */
- if (x > 0 && x < TMPBUFSIZ) { /* '$' at end anchors pattern to end */
- if (p[x-1] == '$') {
- p[x-1] = NUL;
- } else if (p[x-1] != '*') {
- p[x] = '*';
- p[x+1] = NUL;
- }
- }
-#endif /* COMMENT */
- debug(F111,"grep pat",p,x);
-
-#ifdef ZXREWIND
- fc = zxrewind(); /* Rewind the file list */
-#else
- {
- int flags = ZX_FILONLY; /* Expand file list */
- if (matchdot) flags |= ZX_MATCHDOT;
- if (recursive) flags |= ZX_RECURSE;
- fc = nzxpand(line,flags);
- }
-#endif /* ZXREWIND */
-#ifdef UNIX
- sh_sort(mtchs,NULL,fc,0,0,filecase);
-#endif /* UNIX */
-
- debug(F101,"grep cmd_rows","",cmd_rows);
- debug(F101,"grep cmd_cols","",cmd_cols);
-
- while (1) { /* Loop for each file */
- znext(name); /* Get next file */
- if (!name[0]) /* No more, done */
- break;
- if (gr_nobk) /* Skipping backup files? */
- if (ckmatch("*.~[1-9]*~",name,1,1)) /* Backup file? */
- continue; /* Yes, skip */
- if (scan) { /* /TYPE: given? */
- switch (scanfile(name,&y,nscanfile)) { /* Yes, scan the file */
- case FT_BIN:
- if (xmode != 1)
- continue;
- break;
- case FT_TEXT:
- case FT_7BIT:
- case FT_8BIT:
-#ifdef UNICODE
- case FT_UTF8:
- case FT_UCS2:
-#endif /* UNICODE */
- if (xmode != 0)
- continue;
- }
- }
- fp = fopen(name,"r"); /* Open */
- if (!fp) /* Can't */
- continue; /* Skip */
- count = 0; /* Match count, this file */
- fline = 0; /* Line count, this file */
- while (1) { /* Loop for each line */
- if (fgets(line,LINBUFSIZ,fp) == NULL) { /* Get next line */
- fclose(fp);
- fp = NULL;
- debug(F100,"GREP EOF","",0);
- break;
- }
- fline++; /* Count this line */
- line[LINBUFSIZ] = NUL; /* Make sure it's terminated */
- debug(F111,"GREP",line,fline);
- len = (int)strlen(line); /* Get length */
- while (len > 0 && (line[len-1] == '\n' || line[len-1] == '\r'))
- line[--len] = NUL; /* Chop off terminators */
- match = ckmatch(p,line,gr_case,1+4); /* Match against pattern */
- if (match && gr_excp) {
- if (ckmatch(grep_except,line,gr_case,1+4))
- match = 0;
- }
- if (gr_noma) /* Invert match sense if requested */
- match = !match;
- if (match) { /* Have a matching line */
- mc++; /* Total match count */
- count++; /* Match count this file */
- if (gr_name) { /* Don't care how many lines match */
- fclose(fp); /* Close the file */
- fp = NULL; /* and quit the line-reading loop. */
- break;
- }
- if (gr_coun || gr_noli) /* Not listing each line */
- continue; /* so don't print anything now. */
- if (wild) { /* If searching multiple files */
- fprintf(ofp,"%s:",name); /* print filename. */
- len += (int)strlen(name) + 1;
- }
- if (gr_nums) { /* If line numbers wanted */
- char nbuf[32];
- len += ckmakmsg(nbuf,32,ckitoa(fline),":",NULL,NULL);
- fprintf(ofp,"%s",nbuf);
- }
- if (cmd_rows > 0 && cmd_cols > 0)
- sline += (len / cmd_cols) + 1;
- fprintf(ofp,"%s\n",line); /* Print the line. */
- if (sline > cmd_rows - 3) {
- if (!askmore()) goto xgrep; else sline = 0;
- }
- }
- }
- if (!gr_noli) { /* If not not listing... */
- x = 0;
- if (gr_coun) { /* Show match count only */
- fprintf(ofp,"%s:%d\n",name,count);
- x++;
- } else if (gr_name && count > 0) { /* Show name only */
- fprintf(ofp,"%s\n",name);
- x++;
- }
- if (x > 0) {
- if (++sline > cmd_rows - 3) {
- if (!askmore()) goto xgrep; else sline = 0;
- }
- }
- }
- bigcount += count; /* Overall count */
- }
- xgrep:
-#ifndef NOSPL
- if (gr_coun && cv) { /* /COUNT:blah */
- addmac(cv,ckitoa(bigcount)); /* set the variable */
- makestr(&cv,NULL); /* free this */
- }
-#endif /* NOSPL */
- if (fp) fclose(fp); /* close input file if still open */
- if (ofp != stdout) { /* Close any output file */
- if (ofp) fclose(ofp);
- ofp = stdout;
- }
- return(success = mc ? 1 : 0);
-}
-
-/* System-independent directory */
-
-static char ** dirlist = NULL;
-static int ndirlist = 0;
-
-static VOID
-freedirlist() {
- if (dirlist) {
- int i;
- for (i = 0; i < ndirlist; i++) {
- if (dirlist[i])
- free(dirlist[i]);
- }
- free((char *)dirlist);
- dirlist = NULL;
- }
- ndirlist = 0;
-}
-
-static struct keytab dirswtab[] = { /* DIRECTORY command switches */
- { "/after", DIR_AFT, CM_ARG },
- { "/all", DIR_ALL, 0 },
-#ifndef NOSPL
- { "/array", DIR_ARR, CM_ARG },
-#endif /* NOSPL */
- { "/ascending", DIR_ASC, 0 },
- { "/backup", DIR_BUP, 0 },
- { "/before", DIR_BEF, CM_ARG },
- { "/brief", DIR_BRF, 0 },
- { "/count", DIR_COU, CM_ARG },
- { "/descending", DIR_DSC, CM_INV },
- { "/directories", DIR_DIR, 0 },
- { "/dotfiles", DIR_DOT, 0 },
- { "/englishdate", DIR_DAT, 0 },
- { "/except", DIR_EXC, CM_ARG },
- { "/files", DIR_FIL, 0 },
- { "/heading", DIR_HDG, 0 },
- { "/isodate", DIR_ISO, 0 },
- { "/larger-than", DIR_LAR, CM_ARG },
-#ifdef CKSYMLINK
- { "/followlinks", DIR_LNK, 0 },
-#endif /* CKSYMLINK */
- { "/message", DIR_MSG, CM_ARG },
- { "/nobackupfiles",DIR_NOB, 0 },
- { "/nodotfiles", DIR_NOD, 0 },
-#ifdef CKSYMLINK
- { "/nofollowlinks",DIR_NLK, 0 },
-#endif /* CKSYMLINK */
- { "/noheading", DIR_NOH, 0 },
-#ifdef CKSYMLINK
- { "/nolinks", DIR_NOL, 0 },
-#endif /* CKSYMLINK */
- { "/nomessage", DIR_NOM, 0 },
-#ifdef CK_TTGWSIZ
- { "/nopage", DIR_NOP, 0 },
-#endif /* CK_TTGWSIZ */
-#ifdef RECURSIVE
- { "/norecursive", DIR_NOR, 0 },
-#else
-#ifdef VMS
- { "/norecursive", DIR_NOR, 0 },
-#else
-#ifdef datageneral
- { "/norecursive", DIR_NOR, 0 },
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* RECURSIVE */
- { "/nosort", DIR_NOS, 0 },
- { "/not-after", DIR_NAF, CM_ARG },
- { "/not-before", DIR_NBF, CM_ARG },
- { "/not-since", DIR_NAF, CM_INV|CM_ARG },
- { "/noxfermode", DIR_NOT, 0 },
- { "/output", DIR_OUT, CM_ARG },
-#ifdef CK_TTGWSIZ
- { "/page", DIR_PAG, 0 },
-#endif /* CK_TTGWSIZ */
-#ifdef RECURSIVE
- { "/recursive", DIR_REC, 0 },
-#else
-#ifdef VMS
- { "/recursive", DIR_REC, 0 },
-#else
-#ifdef datageneral
- { "/recursive", DIR_REC, 0 },
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* RECURSIVE */
- { "/reverse", DIR_DSC, 0 },
- { "/since", DIR_AFT, CM_ARG|CM_INV },
- { "/smaller-than",DIR_SMA, CM_ARG },
- { "/sort", DIR_SRT, CM_ARG },
- { "/summary", DIR_SUM, 0 },
- { "/top", DIR_TOP, CM_ARG },
- { "/type", DIR_BIN, CM_ARG },
- { "/xfermode", DIR_TYP, 0 },
- { "/verbose", DIR_VRB, 0 },
- { "",0,0 }
-};
-static int ndirswtab = (sizeof(dirswtab) / sizeof(struct keytab)) - 1;
-
-static struct keytab dirsort[] = { /* DIRECTORY /SORT: options */
- { "date", DIRS_DT, 0 },
- { "name", DIRS_NM, 0 },
- { "size", DIRS_SZ, 0 }
-};
-static int ndirsort = (sizeof(dirsort) / sizeof(struct keytab));
-
-static int dir_date = -1; /* Option defaults (-1 means none) */
-static int dir_page = -1;
-static int dir_verb = 1;
-static int dir_msg = -1;
-#ifdef VMS
-static int dir_sort = -1; /* Names are already sorted in VMS */
-static int dir_rvrs = -1;
-#else
-static int dir_sort = 1; /* Sort by default */
-static int dir_rvrs = 0; /* Not in reverse */
-#endif /* VMS */
-static int dir_skey = DIRS_NM; /* By name */
-#ifdef RECURSIVE
-static int dir_recu = -1;
-#endif /* RECURSIVE */
-static int dir_mode = -1;
-static int dir_show = -1; /* Show all files by default */
-int dir_dots = -1; /* Except dot files */
-int dir_back = 1;
-int dir_head = 0;
-static char * dirmsg = NULL;
-static int dirmsglen = 0;
-
-#ifndef NOSHOW
-VOID
-showdiropts() {
- int x = 0;
- extern int optlines;
- prtopt(&optlines,"DIRECTORY");
- if (dir_show > 0) {
- prtopt(&optlines,(dir_show == 1) ? "/FILES" :
- ((dir_show == 2) ? "/DIRECTORIES" : "/ALL"));
- x++;
- } else {
- prtopt(&optlines,"/ALL");
- x++;
- }
- if (dir_verb > -1) {
- prtopt(&optlines,dir_verb ? "/VERBOSE" : "/BRIEF");
- x++;
- }
- if (dir_page > -1) {
- prtopt(&optlines,dir_page ? "/PAGE" : "/NOPAGE");
- x++;
- }
- if (dir_date > -1) {
- prtopt(&optlines,dir_date ? "/ENGLISHDATE" : "/ISODATE");
- x++;
- }
- if (dir_dots > -1) {
- prtopt(&optlines,dir_dots ? "/DOTFILES" : "/NODOTFILES");
- x++;
- }
- if (dir_back > -1) {
- prtopt(&optlines,dir_back ? "/BACKUP" : "/NOBACKUP");
- x++;
- }
- if (dir_head > -1) {
- prtopt(&optlines,dir_head ? "/HEADING" : "/NOHEADING");
- x++;
- }
-#ifdef RECURSIVE
- if (dir_recu > -1) {
- prtopt(&optlines,dir_recu ? "/RECURSIVE" : "/NORECURSIVE");
- x++;
- }
-#endif /* RECURSIVE */
- if (dir_mode > -1) {
- prtopt(&optlines,dir_mode ? "/XFERMODE" : "/NOXFERMODE");
- x++;
- }
- if (dir_sort == 0) {
- x++;
- prtopt(&optlines,"/NOSORT ");
- } else if (dir_sort > 0) {
- x++;
- if (dir_skey == DIRS_NM) s = "/SORT:NAME";
- else if (dir_skey == DIRS_SZ) s = "/SORT:SIZE";
- else if (dir_skey == DIRS_DT) s = "/SORT:DATE";
- prtopt(&optlines,s);
- }
- if (dir_rvrs > -1) {
- prtopt(&optlines,dir_rvrs ? "/REVERSE" : "/ASCENDING");
- x++;
- }
- if (dir_msg > -1) {
- if (dir_msg == 0) {
- prtopt(&optlines,"/NOMESSAGE");
- } else {
- ckmakmsg(tmpbuf,TMPBUFSIZ,"/MESSAGE:{",dirmsg,"}",NULL);
- prtopt(&optlines,tmpbuf);
- }
- x++;
- }
- if (!x) prtopt(&optlines,"(no options set)");
- prtopt(&optlines,"");
-}
-#endif /* NOSHOW */
-
-int
-setdiropts() { /* Set DIRECTORY option defaults */
- int xb = -1, xv = -1, xp = -1, xd = -1, xh = -1, xf = -1;
- int xk = -1, xr = -1, xs = -1, xx = -1, xm = -1, xa = -1, xg = -1;
- int getval;
- char c;
- while (1) {
- if ((y = cmswi(dirswtab,ndirswtab,"Switch","",xxstring)) < 0) {
- if (y == -3)
- break;
- else
- return(y);
- }
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (y) {
- case DIR_BRF: xv = 0; break;
- case DIR_VRB: xv = 1; break;
- case DIR_PAG: xp = 1; break;
- case DIR_NOP: xp = 0; break;
- case DIR_ISO: xd = 0; break;
- case DIR_DAT: xd = 1; break;
- case DIR_HDG: xh = 1; break;
- case DIR_NOH: xh = 0; break;
- case DIR_DOT: xf = 1; break;
- case DIR_NOD: xf = 0; break;
- case DIR_ALL: xa = 3; break;
- case DIR_DIR: xa = 2; break;
- case DIR_FIL: xa = 1; break;
- case DIR_SRT:
- x = DIRS_NM;
- if (getval)
- if ((x = cmkey(dirsort,ndirsort,"Sort key","name",xxstring)) < 0)
- return(x);
- xk = x;
- xs = 1;
- break;
- case DIR_NOS: xs = 0; break;
- case DIR_ASC: xx = 0; break;
- case DIR_DSC: xx = 1; break;
- case DIR_REC: xr = 1; break;
- case DIR_NOR: xr = 0; break;
- case DIR_TYP: xm = 1; break;
- case DIR_NOT: xm = 0; break;
- case DIR_BUP: xb = 1; break;
- case DIR_NOB: xb = 0; break;
- case DIR_NOM: xg = 0; break;
- case DIR_MSG:
- if (getval)
- if ((x = cmfld("Message to append to each line",
- "",
- &s,
- xxstring
- )) < 0)
- return(x);
- xg = 1;
- ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
- break;
- default:
- printf("?This option can not be set\n");
- return(-9);
- }
- }
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
- if (xv > -1) dir_verb = xv; /* Confirmed, save defaults */
- if (xp > -1) dir_page = xp;
- if (xd > -1) dir_date = xd;
- if (xh > -1) dir_head = xh;
- if (xs > -1) dir_sort = xs;
- if (xk > -1) dir_skey = xk;
- if (xx > -1) dir_rvrs = xx;
- if (xf > -1) dir_dots = xf;
- if (xa > -1) dir_show = xa;
- if (xm > -1) dir_mode = xm;
- if (xb > -1) dir_back = xb;
-#ifdef RECURSIVE
- if (xr > -1) dir_recu = xr;
-#endif /* RECURSIVE */
- if (xg > -1) dir_msg = xg;
- if (xg > 0)
- makestr(&dirmsg,tmpbuf);
- return(success = 1);
-}
-
-int
-domydir(cx) int cx; { /* Internal DIRECTORY command */
- extern char *months[];
-#ifdef VMS
- _PROTOTYP( char * zrelname, (char *,char *) );
- char * cdp = NULL;
-#endif /* VMS */
-
- char name[CKMAXPATH+1], outfile[CKMAXPATH+1], *p = NULL, c = NUL;
- char linebuf[CKMAXPATH+256];
- char * mstr = NULL, * dstr = NULL, * s2 = NULL, * cv = NULL;
- CK_OFF_T len = (CK_OFF_T)0, nbytes = (CK_OFF_T)0;
- CK_OFF_T minsize = (CK_OFF_T)-1, maxsize = (CK_OFF_T)-1;
- long ndirs = 0, nfiles = 0, nmatches = 0;
- int verbose = 0, wild = 0, page = 0, n = 0, engdate = 0, summary = 0;
- int heading = 0, xsort = 0, reverse = 0, sortby = 0, msg = 0;
- int k, i = 0, x = 0, nx = 0, skey = 0, dlen = 0, itsadir = 0;
- int show = 3, xfermod = 0, backup = 1, rc = 0, getval = 0;
- int touch = 0;
- int fs = 0;
- int multiple = 0;
- int cmifn1 = 1, cmifn2 = 0;
- int dir_top = 0, dir_cou = 0;
- int dontshowlinks = 0;
- int dontfollowlinks = 0;
- int arrayindex = -1;
- struct FDB sw, fi, fl;
- char dbuf[32], xbuf[32];
-
-#ifndef NOSPL
- char array = NUL;
- char ** ap = NULL;
-#endif /* NOSPL */
- char
- * dir_aft = NULL,
- * dir_bef = NULL,
- * dir_naf = NULL,
- * dir_nbf = NULL,
- * dir_exc = NULL;
- char * xlist[16];
-
- debug(F101,"domydir cx","",cx);
-
- g_matchdot = matchdot; /* Save global matchdot setting */
-#ifdef COMMENT
- nolinks = 2; /* (it should already be 2) */
-#endif /* COMMENT */
- outfile[0] = NUL; /* No output file yet */
-
- if (ofp != stdout) { /* In case of previous interruption */
- if (ofp) fclose(ofp);
- ofp = stdout;
- }
- for (i = 0; i < 16; i++) xlist[i] = NULL;
-
- dir_top = 0;
- name[0] = NUL;
- freedirlist(); /* In case not freed last time */
- page = dir_page > -1 ? dir_page : xaskmore; /* Set option defaults */
- engdate = dir_date > -1 ? dir_date : 0;
- verbose = dir_verb > -1 ? dir_verb : 1;
- heading = dir_head > -1 ? dir_head : 0;
- xsort = dir_sort > -1 ? dir_sort : 0;
- sortby = dir_skey > -1 ? dir_skey : 0;
- reverse = dir_rvrs > -1 ? dir_rvrs : 0;
- msg = dir_msg > -1 ? dir_msg : 0;
-#ifdef UNIXOROSK
- if (dir_dots > -1) matchdot = dir_dots;
-#endif /* UNIXOROSK */
- xfermod = dir_mode > -1 ? dir_mode : 0;
- backup = dir_back > -1 ? dir_back : 1;
-#ifdef RECURSIVE
- recursive = dir_recu > -1 ? dir_recu : 0;
-#endif /* RECURSIVE */
- show = dir_show > -1 ? dir_show : 3;
-
- if (cx == XXWDIR) { /* WDIRECTORY */
- debug(F100,"domydir WDIRECTORY","",0);
- reverse = 1; /* Reverse chronological order */
- xsort = 1;
- sortby = DIRS_DT;
- } else if (cx == XXHDIR) { /* HDIRECTORY */
- debug(F100,"domydir HDIRECTORY","",0);
- reverse = 1; /* Reverse order by size */
- xsort = 1;
- sortby = DIRS_SZ;
- } else if (cx == XXTOUC) {
- touch = 1;
- verbose = 0;
- }
-
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- ttgcwsz(); /* Screen length for more-prompting */
-#else /* OS2 */
- /* Check whether window size changed */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
- diractive = 1;
- cmifn1 = nolinks | 1; /* 1 = files or directories */
- cmifn2 = 0; /* 0 = not directories only */
-
- again:
-
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Enter or Return to confirm the command, or\n\
- file specification, or switch",
- "", /* default */
- "", /* addtl string data */
- ndirswtab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- dirswtab, /* Keyword table */
- &fi /* Pointer to next FDB */
- );
- cmfdbi(&fi, /* 2nd FDB - filespec to match */
- _CMIFI, /* fcode */
- "File specification", /* hlpmsg */
-#ifdef datageneral
- "+", /* Default filespec is wildcard */
-#else /* that matches all files... */
-#ifdef VMS
- "*.*",
-#else
- "*",
-#endif /* VMS */
-#endif /* datageneral */
- "", /* addtl string data */
- cmifn1,
- cmifn2, /* 1 = only dirs; 0 files or dirs */
- xxstring,
- NULL,
- &fl
- );
- cmfdbi(&fl, /* Anything that doesn't match */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse something */
- debug(F101,"domydir cmfdb","",x);
- if (x < 0)
- return(x);
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- k = cmresult.nresult;
- if (!getval &&
- (cmgkwflgs() & CM_ARG) && k != DIR_TOP && k != DIR_COU) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (k) {
- case DIR_COU: {
- dir_cou++;
- if (getval) {
- if ((x = cmfld("Variable for result","",&s,NULL)) < 0)
- return(x);
- makestr(&cv,s);
- }
- break;
- }
- case DIR_BRF: verbose = 0; break;
- case DIR_VRB: verbose = 1; break;
-#ifdef CK_TTGWSIZ
- case DIR_PAG: page = 1; break;
- case DIR_NOP: page = 0; break;
-#endif /* CK_TTGWSIZ */
- case DIR_ISO: engdate = 0; break;
- case DIR_DAT: engdate = 1; break;
- case DIR_HDG: heading = 1; break;
- case DIR_NOH: heading = 0; break;
-#ifdef UNIXOROSK
- case DIR_DOT: matchdot = 1; break;
- case DIR_NOD: matchdot = 0; break;
-#endif /* UNIXOROSK */
- case DIR_ALL:
- show = 3;
- cmifn1 |= 1;
- cmifn2 = 0;
- goto again;
- case DIR_DIR:
- show = 2;
- cmifn1 |= 1;
- cmifn2 = 1;
- goto again;
- case DIR_FIL:
- show = 1;
- cmifn1 &= ~(1);
- cmifn2 = 0;
- goto again;
- case DIR_SRT:
- x = DIRS_NM;
- if (c == ':' || c == '=')
- if ((x = cmkey(dirsort,ndirsort,"Sort key","name",xxstring)) < 0)
- return(x);
- xsort = 1;
- sortby = x;
- break;
-
- case DIR_BUP: backup = 1; fs++; break;
- case DIR_NOB: backup = 0; fs++; break;
-
- case DIR_NOS: xsort = 0; break;
- case DIR_ASC: reverse = 0; break;
- case DIR_DSC: reverse = 1; break;
-#ifdef RECURSIVE
- case DIR_REC: recursive = 1; diractive = 1; break;
- case DIR_NOR: recursive = 0; diractive = 0; break;
-#endif /* RECURSIVE */
- case DIR_TYP: xfermod = 1; break;
- case DIR_NOT: xfermod = 0; break;
-
-#ifdef CKSYMLINK
- case DIR_LNK: /* Follow links */
-#ifdef COMMENT
- /* A command switch shouldn't be setting a global value! */
- nolinks = 0;
-#endif /* COMMENT */
- cmifn1 &= ~(2);
- dontfollowlinks = 0;
- goto again;
- case DIR_NLK: /* Don't follow links */
-#ifdef COMMENT
- nolinks = 2;
-#endif /* COMMENT */
- cmifn1 &= ~(2);
- dontfollowlinks = 1;
- goto again;
- case DIR_NOL: /* Don't show links at all */
- dontshowlinks = 1;
- goto again;
-#endif /* CKSYMLINK */
-
- case DIR_NOM: msg = 0; break;
- case DIR_MSG:
- if (c == ':' || c == '=')
- if ((x = cmfld("Message to append to each line",
- "",
- &s,
- xxstring
- )) < 0)
- return(x);
- msg = 1;
- ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
- break;
-
- case DIR_SMA:
- case DIR_LAR: {
- CK_OFF_T y;
- if (!getval) break;
- if ((x = cmnumw("File size in bytes","0",10,&y,xxstring)) < 0)
- return(x);
- fs++;
- show = 1;
- switch (cmresult.nresult) {
- case DIR_SMA: minsize = y; break;
- case DIR_LAR: maxsize = y; break;
- }
- break;
- }
- case DIR_TOP:
- dir_top = 10;
- if (!getval) break;
- if ((x = cmnum("How many lines to show","10",10,&y,xxstring))< 0)
- return(x);
- dir_top = y;
- break;
-
-#ifndef NOSPL
- case DIR_ARR:
- if (c != ':' && c != '=') {
- printf("?Array name required\n");
- return(-9);
- }
- if ((x = cmfld("Array name (a single letter will do)",
- "",
- &s,
- NULL
- )) < 0) {
- if (x == -3) {
- printf("?Array name required\n");
- return(-9);
- } else
- return(x);
- }
- if (!*s) {
- printf("?Array name required\n");
- return(-9);
- }
- s2 = s;
- if (*s == CMDQ) s++;
- if (*s == '&') s++;
- if (!isalpha(*s)) {
- printf("?Bad array name - \"%s\"\n",s2);
- return(-9);
- }
- array = *s++;
- if (isupper(array)) array = tolower(array);
- if (*s && (*s != '[' || *(s+1) != ']')) {
- printf("?Bad array name - \"%s\"\n",s2);
- return(-9);
- }
- break;
-#endif /* NOSPL */
- case DIR_AFT:
- case DIR_BEF:
- case DIR_NAF:
- case DIR_NBF:
- if (!getval) break;
- if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) {
- if (x == -3) {
- printf("?Date-time required\n");
- rc = -9;
- } else
- rc = x;
- goto xdomydir;
- }
- fs++;
- switch (k) {
- case DIR_AFT: makestr(&dir_aft,s); break;
- case DIR_BEF: makestr(&dir_bef,s); break;
- case DIR_NAF: makestr(&dir_naf,s); break;
- case DIR_NBF: makestr(&dir_nbf,s); break;
- }
- break;
- case DIR_EXC:
- if (!getval) break;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Pattern required\n");
- rc = -9;
- } else
- rc = x;
- goto xdomydir;
- }
- fs++;
- makestr(&dir_exc,s);
- break;
-
- case DIR_SUM:
- summary = 1; break;
-
- case DIR_BIN: {
- extern struct keytab txtbin[];
- extern int xfiletype;
- if (!getval) break;
- if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0) {
- rc = x;
- goto xdomydir;
- }
- if (x == 2) {
- xfiletype = -1;
- } else {
- xfiletype = x;
- fs = 1;
- }
- break;
- }
- case DIR_OUT:
- if ((x = cmofi("File for directory listing","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(outfile,s,CKMAXPATH+1);
- break;
-
- default:
- printf("?Sorry, not implemented yet - \"%s\"\n", atmbuf);
- goto xdomydir;
- }
- }
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Safe copy of filespec */
-
-/* ^^^ START MULTIPLE */
-
- while (!touch) {
- x = cmfld("Another filespec or Enter","",&s,xxstring);
- if (x == -3)
- break;
- if (x < 0)
- return(x);
- ckstrncat(line,",",LINBUFSIZ);
- ckstrncat(line,s,LINBUFSIZ);
- multiple++;
- }
- ckmakmsg(tmpbuf,TMPBUFSIZ,"{",line,"}",NULL);
- ckstrncpy(line,tmpbuf,LINBUFSIZ);
- cmresult.nresult = 1;
- cmresult.fcode = _CMIFI;
-
-/* ^^^ END MULTIPLE */
-
- s = line;
-
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
-
-/*
- Command is TOUCH and file doesn't exist.
-*/
- if (touch) { /* TOUCH */
- if ((cmresult.fcode == _CMIFI && zchki(s) == (CK_OFF_T)-1)) {
- FILE * fp;
- s = brstrip(s);
- if (!iswild(s)) {
-#ifdef UNIX
- if (s[0] == '~')
- s = tilde_expand(s);
-#endif /* UNIX */
- fp = fopen(s,"w"); /* Create file */
- if (!fp) {
- printf("?TOUCH %s: %s\n",s,ck_errstr());
- rc = -9;
- goto xdomydir;
- }
- fclose(fp);
- cx = XXDIR; /* Now maybe list it. */
- multiple++; /* Force new directory scan */
- }
- }
- } else
-
- if (cmresult.fcode != _CMIFI) { /* Nothing matched */
- /*
- Note - this never gets executed because after the "begin
- multiple" hack above, the result is always _CMIFI).
- */
- char * m;
- if (*s == '/')
-#ifdef UNIXOROSK
- m = "does not match switch or name of accessible file";
-#else
-#ifdef OS2
- m = "does not match switch or name of accessible file";
-#else
- m = "no switches match";
-#endif /* OS2 */
-#endif /* UNIXOROSX */
- else
- m = "not found or not accessible";
- printf("\"%s\" - %s\n",s,m);
- rc = -9;
- goto xdomydir;
- }
-#ifdef COMMENT
- /* This can't be right because it's based on _CMCFM */
- wild = cmresult.nresult; /* Wildcard was given? */
- debug(F111,"domydir cmifi2",s,wild);
-#else
- wild = 0;
-#endif /* COMMENT */
-
- if (outfile[0]) { /* If an output file was specified */
- ofp = fopen(outfile,"w"); /* open it */
- if (!ofp) {
- printf("?Can't open output file %s: %s\n",outfile,ck_errstr());
- ofp = stdout;
- return(-9);
- }
- page = 0;
- }
-
-#ifdef OS2
- if (!wild) {
- if (zchki(s) == -2) { /* Found a directory */
- p = s + (int)strlen(s) - 1; /* Yes */
- if (*p == '\\' || *p == '/')
- strcat(s, "*");
- else if (*p == ':')
- strcat(s, "./*");
- else
- strcat(s, "/*");
- wild = 1; /* Now it's wild */
- }
- }
-#else
- if (!wild) if (isdir(s)) { /* Is it a directory? */
- p = s + (int)strlen(s) - 1; /* Yes */
-#ifdef VMS
- {
- /* Convert from FOO.DIR;1 to [x.FOO] if necessary */
- char buf[CKMAXPATH+1];
- debug(F000,"domydir directory 0",s,*p);
- if (cvtdir(s,buf,CKMAXPATH) > 0)
- ckstrncpy(line,buf,LINBUFSIZ);
- }
-#endif /* VMS */
- debug(F000,"domydir directory 1",s,*p);
-#ifdef VMS
- if (*p == ']' || *p == '>' || *p == ':')
- strcat(s, "*.*");
-#else
-#ifdef datageneral
- if (*p == ':')
- strcat(s, "+");
- else
- strcat(s, ":+");
-#else
-#ifdef STRATUS
- if (*p == '>')
- strcat(s, "*");
- else
- strcat(s, ">*");
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* VMS */
- wild = 1; /* Now it's wild */
- debug(F000,"domydir directory 2",s,*p);
- }
-#endif /* OS2 */
-
-#ifdef ZXREWIND
-/* cmifi() already called nzxpand so we can just re-use the same list. */
- if (!multiple) {
- x = zxrewind(); /* Rewind the list */
- debug(F111,"domydir zxrewind",s,x);
- } else {
-#endif /* ZXREWIND */
-/*
- In case we gave multiple filespecs they are now in {a,b,c} list format.
- Which is a valid wildcard. We pass it to nzxpand() to get back the list
- of files that match. This is fine for DIRECTORY but it's not find for
- TOUCH because we want TOUCH to see those names so it can create the files.
- So for now at least, if TOUCH is to be used to create files -- as opposed
- to changing the timestamps of existing files -- it can only do one file
- at a time.
-*/
- nzxopts = (show == ZX_DIRONLY) ? ZX_DIRONLY :
- (show == ZX_FILONLY ? ZX_FILONLY : 0);
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- if (recursive) nzxopts |= ZX_RECURSE;
- x = nzxpand(s,nzxopts); /* Expand file list */
- debug(F111,"domydir nzxpand",s,x);
-#ifdef ZXREWIND
- }
-#endif /* ZXREWIND */
-
-#ifndef NOSPL
- if (array) {
- int n, xx;
- n = (x < 0) ? 0 : x;
- if ((xx = dclarray(array,n)) < 0) {
- printf("?Array declaration failure\n");
- rc = -9;
- goto xdomydir;
- }
- arrayindex = xx;
- ap = a_ptr[xx]; /* Pointer to list of elements */
- if (ap) /* Set element 0 to dimension */
- makestr(&(ap[0]),"0"); /* which so far is zero */
- if (n < 1) { /* No files matched, done. */
- rc = 0;
- goto xdomydir;
- }
- } else
-#endif /* NOSPL */
- if (!touch && x < 1) {
-#ifdef CKROOT
- extern int ckrooterr;
- if (ckrooterr)
- printf("?Off limits: %s\n",s);
- else
-#endif /* CKROOT */
- if (x == 0 && isdir(s))
- printf("?Empty directory - \"%s\"\n", s);
- else
- printf("?%s %s match - \"%s\"\n",
- (x == 0) ? "No" : "Too many",
- (show == 2) ? "directories" : "files",
- brstrip(s)
- );
- rc = -9;
- goto xdomydir;
- }
- nx = x; /* Remember how many files */
- if (nx < 2) xsort = 0; /* Skip sorting if none or one */
-
- if (msg) {
- makestr(&dirmsg,tmpbuf);
- dirmsglen = strlen(tmpbuf);
- }
-
-#ifdef VMS
- cdp = zgtdir(); /* Get current directory */
- debug(F110,"domydir VMS zgtdir",cdp,0);
-#endif /* VMS */
-
- if (xsort && verbose) { /* If sorting, allocate space */
- if (!(dirlist = (char **) malloc((x + 1) * sizeof(char **)))) {
- if (!quiet) {
- printf("* Warning: Failure to allocate memory for sorting.\n");
- printf("* Will proceed without sorting...\n");
- }
- xsort = 0;
- }
- debug(F101,"domydir sort malloc","",xsort);
- }
-
- /* Display the listing */
-
-#ifndef NOSPL
- if (array) /* Storing instead of printing */
- heading = 0;
-#endif /* NOSPL */
-
- if (heading) { /* If /HEADING print heading */
- zfnqfp(s,TMPBUFSIZ,tmpbuf);
- fprintf(ofp,"\nDirectory of %s\n\n",tmpbuf);
- n += 3;
- }
- if (page > -1) /* Paging */
- xaskmore = page;
-
- if (!verbose && !touch) { /* /BRIEF */
- if (outfile[0]) { /* To file */
- int k = 0;
- znext(name);
- while (name[0]) { /* One line per file */
- k++;
- if (fs) if (fileselect(name,
- dir_aft,dir_bef,dir_naf,dir_nbf,
- minsize,maxsize,!backup,16,xlist) < 1) {
- znext(name);
- continue;
- }
- fprintf(ofp,"%s\n",name);
- znext(name);
- }
- if (heading)
- fprintf(ofp,"Files: %d\n\n",k);
- rc = 1;
- goto xdomydir;
- } else {
- rc = xfilhelp(x,"","",n,0,1,
- dir_aft,dir_bef,dir_naf,dir_nbf,
- minsize,maxsize,!backup,16,xlist);
- if (rc < 0)
- goto xdomydir;
- if (heading && rc > 0)
- fprintf(ofp,"Files: %d\n\n",x); /* (Might scroll a line or 2) */
- rc = 1;
- goto xdomydir;
- }
- }
- ndirs = nfiles = 0L; /* Initialize counters */
- nbytes = (CK_OFF_T)0;
-
- if (dir_exc) /* Have exception list? */
- makelist(dir_exc,xlist,16); /* Yes, convert to array */
-
- diractive = 1;
- znext(name); /* Get next file */
- while (name[0]) { /* Loop for each file */
- if (fs) if (fileselect(name,
- dir_aft,dir_bef,dir_naf,dir_nbf,
- minsize,maxsize,!backup,16,xlist) < 1) {
- znext(name);
- continue;
- }
- len = zgetfs(name); /* Get file length */
- debug(F111,"domydir zgetfs",name,len);
-#ifdef VMSORUNIX
- itsadir = zgfs_dir; /* See if it's a directory */
-#else
- itsadir = (len == (CK_OFF_T)-2 || isdir(name));
-#endif /* VMSOUNIX */
- debug(F111,"domydir itsadir",name,itsadir);
- if ((itsadir && (show == 1)) || (!itsadir && (show == 2))) {
- znext(name);
- continue;
- }
- /* Get here when we know we have selected this file */
-
- nmatches++;
- if (itsadir) { /* Accumulate totals for summary */
- ndirs++;
- } else {
- nfiles++;
- nbytes += len;
- }
- dstr = NULL;
- if (cx == XXTOUC) { /* Command was TOUCH, not DIRECTORY */
- char * filename;
- struct zattr xx;
- dstr = ckcvtdate("",0);
- xx.date.val = dstr;
- xx.date.len = (int)strlen(xx.date.val);
- xx.lprotect.len = 0;
- debug(F110,"domydir touch",name,0);
- debug(F110,"domydir touch",dstr,0);
- if (zstime(name,&xx,0) < 0) {
- printf("?TOUCH %s: %s\n",name,ck_errstr());
- rc = -9;
- goto xdomydir;
- }
- if (!verbose) { /* No listing so skip detail */
- znext(name);
- continue;
- }
- }
- if (summary) { /* Summary only, no detail */
- znext(name);
- continue;
- }
-
-#ifndef NOSPL
- if (array) {
- debug(F111,"domydir array",name,nfiles);
- if (ap)
- makestr(&(ap[nmatches]),name);
- znext(name);
- continue;
- }
-#endif /* NOSPL */
-
-/*
- NOTE: The sprintf's in this routine should be safe. They involve
- permission strings, date/time strings, and filenames, all of which have
- known maximum lengths; none of these items is input from users. The
- destination buffers are large enough to hold maximum sizes for any and
- all items. NOTE 2: If command was TOUCH, dstr was already set just
- above.
-*/
- if (!dstr) { /* Get file's modification date/time */
- dstr = zfcdat(name);
- debug(F111,"domydir zcfdat",dstr,0);
- }
- if (!dstr) dstr = "";
- {
-/*
- Note that zfcdat() always returns "" or yyyymmdd hh:mm:ss, so any warnings
- about possible out-of-bounds dstr[] array refs do not apply. This block of
- code is to stifle the warnings and also allows for any out-of-spec
- zfcdat() implementations.
-*/
- int x;
- char * p = "00000000 00:00:00";
- x = ckstrncpy(xbuf,dstr,32);
- if (x < 17) ckstrncpy(&xbuf[x],p+x,32-x);
- dstr = xbuf;
- }
- if (engdate) { /* English date requested? */
- short month, day, year, hour, minute, seconds;
- month = (dstr[4]-48)*10 + (dstr[5]-48);
- mstr = (month > 0 && month <= 12) ? months[month-1] : "xxx";
- day = (dstr[6]-48)*10 + (dstr[7]-48);
- year = (((dstr[0]-48)*10 +
- (dstr[1]-48))*10 +
- (dstr[2]-48))*10 +
- (dstr[3]-48);
- hour = (dstr[9]-48)*10 + (dstr[10]-48);
- minute = (dstr[12]-48)*10 + (dstr[13]-48);
- seconds = (dstr[15]-48)*10 + (dstr[16]-48);
- sprintf(dbuf, /* SAFE */
- "%2d-%s-%4d %02d:%02d:%02d",
- day,mstr,year,hour,minute,seconds
- );
- dstr = dbuf;
- } else { /* ISO date */
- dbuf[0] = dstr[0]; /* yyyy */
- dbuf[1] = dstr[1];
- dbuf[2] = dstr[2];
- dbuf[3] = dstr[3];
- dbuf[4] = '-';
- dbuf[5] = dstr[4]; /* mm (numeric) */
- dbuf[6] = dstr[5];
- dbuf[7] = '-';
- dbuf[8] = dstr[6]; /* dd */
- dbuf[9] = dstr[7];
- strcpy(dbuf+10,dstr+8); /* hh:mm:ss */
- dstr = dbuf;
- }
- dlen = strlen(dbuf); /* Length of date */
- name[CKMAXPATH] = NUL;
-#ifdef CK_PERMS
-#ifdef VMSORUNIX
- p = ziperm(name); /* Get permissions */
- debug(F110,"ziperm perms",p,0);
-#else
- p = zgperm(name);
- debug(F110,"zgperm perms",p,0);
-#endif /* VMSORUNIX */
-#else
- p = NULL;
- debug(F110,"NULL perms",p,0);
-#endif /* CK_PERMS */
-
-#ifdef VMS
- /* Get relative name to save space -- VMS fullnames are long... */
- ckstrncpy(name,zrelname(name,cdp),CKMAXPATH);
-#endif /* VMS */
-
- if (itsadir && len < (CK_OFF_T)0) { /* Directory */
-#ifdef VMS
- sprintf(linebuf,"%-22s%-10s %s %s",p,"<DIR>",dstr,name);
-#else
- if (p)
- sprintf(linebuf,"%10s%-10s %s %s",p,"<DIR>",dstr,name);
- else
- sprintf(linebuf,"%-10s %s %s", "<DIR>", dstr, name);
-#endif /* VMS */
- } else { /* Regular file */
-#ifdef VMS
- sprintf(linebuf,"%-22s%10s %s %s", p, ckfstoa(len), dstr, name);
-#else
- if (p)
- sprintf(linebuf,"%10s%10s %s %s", p, ckfstoa(len), dstr, name);
- else
- sprintf(linebuf,"%10s %s %s", ckfstoa(len), dstr, name);
-#endif /* VMS */
- }
-#ifdef UNIX
-#ifdef CKSYMLINK
- if (zgfs_link) { /* If it's a symlink */
- if (dontshowlinks) { /* If /NOLINKS don't show it */
- znext(name);
- continue;
- }
- }
- if (zgfs_link && !dontfollowlinks) { /* Symlink and following links */
- int n, m; /* Show what the link points to */
- extern char linkname[];
- n = strlen(linebuf);
- m = strlen(linkname) + n;
- if (m < CKMAXPATH + 58)
- strcpy(linebuf+n, " -> "); /* safe (checked) */
- if (m + 4 < CKMAXPATH - 58)
- strcpy(linebuf+n+4, linkname); /* safe (checked) */
- } else
-#endif /* CKSYMLINK */
-#endif /* UNIX */
- if (xfermod) { /* Show transfer mode */
- int i, x, y;
- char * s = "";
- y = -1;
- x = scanfile(name,&y,nscanfile);
- switch (x) {
- case FT_TEXT: s = " (T)"; break;
- case FT_7BIT: s = " (T)(7BIT)"; break;
- case FT_8BIT: s = " (T)(8BIT)"; break;
-#ifdef UNICODE
- case FT_UTF8: s = " (T)(UTF8)"; break;
- case FT_UCS2:
- s = y ? " (T)(UCS2LE)" : " (T)(UCS2BE)";
- break;
-#endif /* UNICODE */
- case FT_BIN: s = " (B)"; break;
- }
- if (!*s) {
- s = binary ? " (B)" : " (T)";
- }
- if (*s) {
- int n;
- n = strlen(linebuf);
- if (n + 4 < CKMAXPATH - 58)
- strcpy(linebuf+n, s); /* safe (checked) */
- }
- }
- if (msg && dirmsg) {
- int n;
- n = strlen(linebuf);
- if (n + dirmsglen + 2 < CKMAXPATH)
- sprintf((char *)(linebuf+n)," %s", dirmsg); /* SAFE */
- }
- if (xsort) { /* Sorting - save line */
- i = strlen(linebuf);
- if ((ndirlist >= nx) ||
- !(dirlist[ndirlist] = (char *)malloc(i+1))) {
- printf("?Memory allocation error - try /NOSORT\n");
- rc = -9;
- goto xdomydir;
- }
- strcpy(dirlist[ndirlist],linebuf); /* safe */
- ndirlist++;
- }
- znext(name); /* Peek ahead to next file */
- if (!xsort) {
- if (!touch || (touch && verbose))
- fprintf(ofp,"%s\n",linebuf);
- if (page && (name[0] || heading)) { /* If /PAGE */
- if (cmd_cols > 0) {
- int x = strlen(linebuf);
- int y;
- y = (x % cmd_cols) ? 1 : 0;
- n += x / cmd_cols + y;
- } else {
- n++;
- }
-#ifdef CK_TTGWSIZ
- if (n > (cmd_rows - 3)) { /* Do more-prompting */
- if (!askmore()) {
- rc = 0;
- goto xdomydir;
- } else
- n = 0;
- }
-#endif /* CK_TTGWSIZ */
- }
- }
- }
-#ifndef NOSPL
- if (array) {
- if (ap)
- makestr(&(ap[0]),ckitoa(nmatches));
- rc = 1;
- goto xdomydir;
- }
-#endif /* NOSPL */
- if (xsort) {
- int namepos;
- skey = 0;
-#ifdef VMS
- namepos = dlen + 35;
- switch (sortby) {
- case DIRS_NM: skey = namepos; break;
- case DIRS_DT: skey = 33; break;
- case DIRS_SZ: skey = 21;
- }
-#else
- if (p) {
- namepos = dlen + 24;
- switch (sortby) {
- case DIRS_NM: skey = namepos; break;
- case DIRS_DT: skey = 22; break;
- case DIRS_SZ: skey = 10;
- }
- } else {
- namepos = dlen + 14;
- switch (sortby) {
- case DIRS_NM: skey = namepos; break;
- case DIRS_DT: skey = 12; break;
- case DIRS_SZ: skey = 0;
- }
- }
-#endif /* VMS */
- sh_sort(dirlist,NULL,ndirlist,skey,reverse,filecase);
- if (dir_top > 0 && dir_top < ndirlist)
- ndirlist = dir_top;
- for (i = 0; i < ndirlist; i++) {
- fprintf(ofp,"%s\n",dirlist[i]);
- if (page && (i < ndirlist -1 || heading)) { /* If /PAGE */
- if (cmd_cols > 0) {
- int x = strlen(dirlist[i]);
- int y;
- y = (x % cmd_cols) ? 1 : 0;
- n += ((int)strlen(dirlist[i]) / cmd_cols) + y;
- } else {
- n++;
- }
-#ifdef CK_TTGWSIZ
- if (n > (cmd_rows - 3)) { /* Do more-prompting */
- if (!askmore()) {
- rc = 0;
- goto xdomydir;
- } else
- n = 0;
- }
-#endif /* CK_TTGWSIZ */
- }
- }
- }
-
- if (heading || summary) {
-#ifdef CKFLOAT
- CKFLOAT gm;
-#endif /* CKFLOAT */
- fprintf(ofp,"\n%ld director%s, %ld file%s, %s byte%s",
- ndirs,
- (ndirs == 1) ? "y" : "ies",
- nfiles,
- (nfiles == 1) ? "" : "s",
- ckfstoa(nbytes),
- (nbytes == 1) ? "" : "s"
- );
-#ifdef CKFLOAT
- gm = ((CKFLOAT) nbytes ) / 1000000.0;
- if (gm > 1000.0)
- fprintf(ofp," (%0.2fGB)",(gm / 1000.0));
- else if (gm >= 0.01)
- fprintf(ofp," (%0.2fMB)",gm);
-#endif /* CKFLOAD */
- fprintf(ofp,"\n\n");
- } else if (dir_cou && !cv) {
- fprintf(ofp,"\n Files: %ld\n\n",nfiles);
- }
- xdomydir:
-#ifndef NOSPL
- if (dir_cou && cv) { /* /COUNT:var */
- addmac(cv,ckitoa(nfiles)); /* set the variable */
- makestr(&cv,NULL); /* free this */
- }
- if (ap) { /* If we have a result array */
- if (a_dim[arrayindex] > nmatches) /* but it was not filled */
- a_dim[arrayindex] = nmatches; /* adjust dimension */
- }
-#endif /* NOSPL */
- if (g_matchdot > -1) {
- matchdot = g_matchdot; /* Restore these... */
- g_matchdot = -1;
- }
- freedirlist();
- if (ofp != stdout) { /* Close any output file */
- if (ofp) fclose(ofp);
- ofp = stdout;
- }
- if (rc > 0)
- success = 1;
- return(rc);
-}
-
-int
-dodir(cx) int cx; { /* Do the DIRECTORY command */
- char *dc , *msg;
-
-#ifdef OS2
- return(domydir(cx));
-#else /* OS2 */
- if (nopush
-#ifdef DOMYDIR /* Builds that domydir() by default */
- || (cx == XXDIR || cx == XXLDIR || cx == XXWDIR ||
- cx == XXHDIR || cx == XXTOUC)
-#endif /* DOMYDIR */
- )
- return(domydir(cx)); /* Built-in directory command */
-
- /* Use the system's directory command. */
-
- msg = (cx == XXLS) ?
- "Arguments for ls" :
- "Directory and/or file specification";
- if ((x = cmtxt(msg,"",&s,xxstring)) < 0)
- return(x);
-
- ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Copy the filespec */
- s = tmpbuf;
-
- if ((y = cmcfm()) < 0) return(y);
-
- lp = line;
- if (!(dc = getenv("CK_DIR")))
- dc = DIRCMD;
- ckmakmsg(lp,LINBUFSIZ,dc," ",s,NULL);
- debug(F110,"DIR",line,0);
-#ifdef VMS
- conres();
-#endif /* VMS */
- x = zshcmd(line);
-#ifdef VMS
- concb((char)escape);
-#endif /* VMS */
- return(success = (x < 1) ? 0 : 1);
-#endif /* OS2 */
-}
-
-#ifndef NOSERVER
-#ifndef NOFRILLS
-/* Do the ENABLE and DISABLE commands */
-
-int
-doenable(y,x) int y, x; {
-#ifdef CK_LOGIN
- if (isguest) /* IKSD: Don't let guests */
- return(0); /* enable anything that's disabled */
-#endif /* CK_LOGIN */
- switch (x) {
- case EN_ALL:
- en_cwd = en_cpy = en_del = en_dir = en_fin = en_get = y;
- en_ren = en_sen = en_set = en_spa = en_typ = en_ret = y;
- if (!inserver)
- en_who = en_mai = en_pri = y;
- en_mkd = en_rmd = y;
- en_xit = y;
-#ifndef datageneral
- en_bye = y;
-#endif /* datageneral */
-#ifndef NOPUSH
- if (!nopush && !inserver)
- en_hos = y;
-#endif /* NOPUSH */
-#ifndef NOSPL
- en_asg = en_que = y;
-#endif /* NOSPL */
- break;
-
- case EN_BYE:
-#ifndef datageneral
-/*
- In Data General AOS/VS Kermit can't log out its superior process.
-*/
- en_bye = y;
-#endif /* datageneral */
- break;
- case EN_CPY:
- en_cpy = y;
- break;
- case EN_CWD:
- en_cwd = y;
-#ifdef IKSD
- if (inserver && y == 0) {
- fnrpath = PATH_OFF;
- fnspath = PATH_OFF;
- }
-#endif /* IKSD */
- break;
- case EN_DEL: /* Deleting of files */
- en_del = y;
- break;
- case EN_DIR:
- en_dir = y;
- break;
- case EN_FIN:
- en_fin = y;
- break;
- case EN_GET:
- en_get = y;
- break;
-#ifndef NOPUSH
- case EN_HOS:
- if (!nopush)
- en_hos = y;
- break;
-#endif /* NOPUSH */
- case EN_REN:
- en_ren = y;
- break;
- case EN_SEN:
- en_sen = y;
- break;
- case EN_SET:
- en_set = y;
- break;
- case EN_SPA:
- en_spa = y;
- break;
- case EN_TYP:
- en_typ = y;
- break;
- case EN_WHO:
- en_who = y;
- break;
-#ifndef NOSPL
- case EN_ASG:
- en_asg = y;
- break;
- case EN_QUE:
- en_que = y;
- break;
-#endif /* NOSPL */
- case EN_RET:
- en_del = y;
- break;
- case EN_MAI:
-#ifdef CK_LOGIN
- if (isguest && y) {
- printf("?Sorry, not valid for guests\n");
- return(-9);
- }
-#endif /* CK_LOGIN */
- en_mai = y;
- break;
- case EN_PRI:
-#ifdef CK_LOGIN
- if (isguest && y) {
- printf("?Sorry, not valid for guests\n");
- return(-9);
- }
-#endif /* CK_LOGIN */
- en_pri = y;
- break;
- case EN_MKD:
- en_mkd = y;
- break;
- case EN_RMD:
- en_rmd = y;
- break;
- case EN_XIT:
- en_xit = y;
- break;
- case EN_ENA:
- if (((y & 1) && !(en_ena & 1)) ||
- ((y & 2) && !(en_ena & 2))) {
- printf("?Sorry, DISABLE ENABLE can not be undone\n");
- return(-9);
- } else {
- en_ena = y;
- break;
- }
- default:
- return(-2);
- }
- return(1);
-}
-#endif /* NOFRILLS */
-#endif /* NOSERVER */
-
-#ifndef NOFRILLS
-
-static int del_lis = 0;
-static int del_dot = 0;
-static int del_hdg = 0;
-static int del_pag = -1;
-static int del_ask = 0;
-
-#ifndef NOSHOW
-VOID
-showdelopts() {
- int x = 0;
- extern int optlines;
- prtopt(&optlines,"");
- prtopt(&optlines,"DELETE");
- if (del_ask > -1) {
- prtopt(&optlines, del_ask ? "/ASK" : "/NOASK");
- x++;
- }
-#ifdef UNIXOROSK
- if (del_dot > -1) {
- prtopt(&optlines, del_dot ? "/DOTFILES" : "/NODOTFILES");
- x++;
- }
-#endif /* UNIXOROSK */
- if (del_lis > -1) {
- prtopt(&optlines, del_lis ? "/LIST" : "/NOLIST");
- x++;
- }
- if (del_hdg > -1) {
- prtopt(&optlines, del_hdg ? "/HEADING" : "/NOHEADING");
- x++;
- }
-#ifndef CK_TTGWSIZ
- if (del_pag > -1) {
- prtopt(&optlines, del_pag ? "/PAGE" : "/NOPAGE");
- x++;
- }
-#endif /* CK_TTGWSIZ */
- if (!x) prtopt(&optlines,"(no options set)");
- prtopt(&optlines,"");
-}
-#endif /* NOSHOW */
-
-
-int
-setdelopts() {
- int x_lis = -1, x_pag = -1, x_dot = -1, x_hdg = -1, x_ask = -1;
- int getval = 0;
- char c;
- while (1) {
- if ((y = cmswi(deltab,ndeltab,"Switch","",xxstring)) < 0) {
- if (y == -3)
- break;
- else
- return(y);
- }
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (y) {
- case DEL_DOT:
- x_dot = 1;
- break;
- case DEL_NOD:
- x_dot = 0;
- break;
- case DEL_HDG:
- x_hdg = 1;
- break;
- case DEL_LIS:
- x_lis = 1;
- break;
- case DEL_NOL:
- x_lis = 0;
- break;
-#ifndef CK_TTGWSIZ
- case DEL_PAG:
- x_pag = 1;
- break;
- case DEL_NOP:
- x_pag = 0;
- break;
-#endif /* CK_TTGWSIZ */
- case DEL_QUI:
- x_lis = 0;
- break;
- case DEL_VRB:
- x_lis = 1;
- break;
- case DEL_ASK:
- x_ask = 1;
- break;
- case DEL_NAS:
- x_ask = 0;
- break;
- default:
- printf("?Sorry, this option can not be set\n");
- return(-9);
- }
- }
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
- if (x_pag > -1) del_pag = x_pag;
- if (x_dot > -1) del_dot = x_dot;
- if (x_hdg > -1) del_hdg = x_hdg;
- if (x_lis > -1) del_lis = x_lis;
- if (x_ask > -1) del_ask = x_ask;
- return(success = 1);
-}
-
-#ifdef OS2
-static char ** xmtchs = NULL;
-static int xmtchn = 0;
-#endif /* OS2 */
-
-int
-dodel() { /* DELETE */
- int i, j, k, x;
- int fs = 0; /* Need to call fileselect() */
- int len = 0;
- int bad = 0;
- int getval = 0, asking = 0;
- int simulate = 0, rc = 0;
- CK_OFF_T minsize = -1L, maxsize = -1L;
- int havename = 0, confirmed = 0;
- int qflag = 0;
- int summary = 0;
- int deldirs = 0;
- int deltree = 0;
- int itsadir = 0;
- int argisdir = 0;
- int xmode = -1, scan = 0, skip = 0;
-#ifdef COMMENT
- int pass = 0;
-#endif /* COMMENT */
- char c;
- char * deldef = "";
- char safebuf[CKMAXPATH+1];
- struct FDB sw, fi, fl;
- char
- * del_aft = NULL,
- * del_bef = NULL,
- * del_naf = NULL,
- * del_nbf = NULL,
- * del_exc = NULL;
- int
- x_lis = 0,
- /* x_dot = -1, */
- x_hdg = 0;
-
- char * dxlist[8];
-
- for (i = 0; i < 8; i++) dxlist[i] = NULL;
-
- g_matchdot = matchdot;
-
- if (del_lis > -1) x_lis = del_lis;
- if (del_dot > -1) matchdot = del_dot;
- if (del_hdg > -1) x_hdg = del_hdg;
- if (del_pag > -1) xaskmore = del_pag;
- if (del_ask > -1) asking = del_ask;
-
- diractive = 1;
- nolinks = 2; /* By default don't follow links */
-
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "File specification;\n or switch",
- "", /* default */
- "", /* addtl string data */
- ndeltab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- deltab, /* Keyword table */
- &fi /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Anything that doesn't match */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- again:
- cmfdbi(&fi, /* 2nd FDB - file to delete */
- _CMIFI, /* fcode */
- "File(s) to delete", /* hlpmsg */
- deldef, /* default */
- "", /* addtl string data */
- nolinks | deldirs, /* 0 = files, 1 = files or dirs */
- 0, /* 1 = dirs only */
- xxstring,
- NULL,
- &fl
- );
- while (!havename && !confirmed) {
- x = cmfdb(&sw); /* Parse something */
- if (x < 0) { /* Error */
- if (x == -3)
- break;
- if (x == -2 || x == -9)
- printf("?Does not match switch or filename: \"%s\"\n",atmbuf);
- return(x);
- }
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- c = cmgbrk(); /* Get break character */
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- rc = -9;
- goto xdelete;
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- rc = -9;
- goto xdelete;
- }
- switch (k = cmresult.nresult) {
- case DEL_AFT:
- case DEL_BEF:
- case DEL_NAF:
- case DEL_NBF:
- if (!getval) break;
- if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) {
- if (x == -3) {
- printf("?Date-time required\n");
- x = -9;
- } else
- rc = x;
- goto xdelete;
- }
- fs++;
- deltree = 0;
- switch (k) {
- case DEL_AFT: makestr(&del_aft,s); break;
- case DEL_BEF: makestr(&del_bef,s); break;
- case DEL_NAF: makestr(&del_naf,s); break;
- case DEL_NBF: makestr(&del_nbf,s); break;
- }
- break;
- case DEL_DOT:
- matchdot = 1;
- break;
- case DEL_NOD:
- matchdot = 0;
- break;
- case DEL_ALL:
- fs = 0;
-#ifdef VMS
- deldef = "*.*"; /* UNIX, Windows, OS/2 */
-#else
-#ifdef datageneral
- deldef = "+"; /* AOS/VS */
-#else
- deldef = "*"; /* UNIX, Windows, OS/2, VMS... */
-#endif /* datageneral */
-#endif /* VMS */
- deltree = 1;
- nolinks = 2;
- matchdot = 1;
- recursive = 1; /* Fall through purposely... */
- case DEL_DIR:
- deldirs = 1;
- goto again;
- case DEL_EXC:
- if (!getval) break;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Pattern required\n");
- x = -9;
- } else
- rc = x;
- goto xdelete;
- }
- fs++;
- deltree = 0;
- makestr(&del_exc,s);
- break;
- case DEL_HDG:
- x_hdg = 1;
- break;
-#ifdef RECURSIVE
- case DEL_REC:
- recursive = 1;
- break;
-#endif /* RECURSIVE */
- case DEL_LIS:
- x_lis = 1;
- break;
- case DEL_SUM:
- summary = 1;
- x_lis = 0;
- x_hdg = 1;
- break;
- case DEL_NOL:
- x_lis = 0;
- break;
-#ifndef CK_TTGWSIZ
- case DEL_PAG:
- xaskmore = 1;
- break;
- case DEL_NOP:
- xaskmore = 0;
- break;
-#endif /* CK_TTGWSIZ */
- case DEL_QUI:
- qflag = 1;
- x_lis = 0;
- break;
- case DEL_VRB:
- x_lis = 1;
- break;
-
- case DEL_SMA:
- case DEL_LAR:
- if (!getval) break;
- if ((x = cmnum("File size in bytes","0",10,&y,xxstring)) < 0)
- return(x);
- fs++;
- deltree = 0;
- switch (cmresult.nresult) {
- case DEL_SMA: minsize = y; break;
- case DEL_LAR: maxsize = y; break;
- }
- break;
-
- case DEL_SIM:
- simulate = 1;
- x_lis = 1;
- break;
- case DEL_ASK:
- asking = 1;
- break;
- case DEL_NAS:
- asking = 0;
- break;
- case DEL_TYP: {
- extern struct keytab txtbin[];
- if (!getval) break;
- if ((x = cmkey(txtbin,3,"","",xxstring)) < 0)
- return(x);
- if (x == 2) { /* ALL */
- xmode = -1;
- } else { /* TEXT or BINARY only */
- xmode = x;
- scan = 1;
- }
- break;
- }
- default:
- printf("?Not implemented yet - \"%s\"\n",atmbuf);
- return(-9);
- }
- }
- if (qflag && (cmresult.fcode == _CMFLD)) {
- if ((x = cmcfm()) < 0)
- return(x);
- else
- return(success = 0);
- }
- if (cmresult.fcode != _CMIFI) {
- if (*atmbuf) {
- int x;
- if (iswild(atmbuf) && nzxpand(atmbuf,nzxopts) == 0)
- printf("?No files match: %s\n",brstrip(atmbuf));
- else if ((x = zchki(atmbuf)) == -1)
- printf("?File not found: %s\n",brstrip(atmbuf));
- else if (x == -2)
- printf("?Not a regular file: %s\n",atmbuf);
- else
- /* printf("?Not a deletable file: %s\n",atmbuf); */
- goto tryanyway;
- } else {
- printf("?A file specification is required\n");
- }
- return(-9);
- }
- tryanyway:
- ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ); /* Safe copy of filespec */
- if (deldirs) {
- ckstrncpy(safebuf,cmresult.sresult,CKMAXPATH);
-#ifdef VMSORUNIX
- len = zgetfs(tmpbuf); /* Is it a directory name? */
- argisdir = zgfs_dir; /* Then because of how zxpand() */
- if (argisdir && zgfs_link) /* works, we have to add it to */
- argisdir = 0; /* the list. */
- if (itsadir)
- len = -2;
-#else
- len = zchki(tmpbuf);
- if (len < 0)
- argisdir = isdir(tmpbuf);
-#endif /* VMSORUNIX */
- }
- debug(F110,"DELETE file",tmpbuf,0);
- if ((x = cmcfm()) < 0)
- return(x);
-
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && isguest) {
- printf("?Sorry, DELETE unavailable to guests\n");
- return(-9);
- }
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-
-#ifndef OS2ORUNIX
- if (simulate) {
- printf("?Sorry, /SIMULATE not implemented on this platform\n");
- return(-9);
- }
-#endif /* OS2ORUNIX */
-
-#ifdef COMMENT
- /* (not needed) */
- if (!iswild(tmpbuf)) {
- char *m;
- errno = 0;
- x = zchki(tmpbuf);
- if (x < 0) {
- switch (x) {
- case -2: m = "Not a regular file"; break;
- case -1: m = "File not found or not accessible"; break;
- default: m = errno ? ck_errstr() : "Can't delete";
- }
- printf("?%s: \"%s\"\n",m,tmpbuf);
- return(-9);
- }
- }
-#endif /* COMMENT */
-
- makelist(del_exc,dxlist,8);
-
-/* tmpbuf[] has the name - now do any needed conversions on it */
-
-#ifdef OS2
- { /* Lower level functions change / to \, not good for CMD.EXE. */
- char *p = tmpbuf;
- while (*p) { /* Change them back to \ */
- if (*p == '/') *p = '\\';
- p++;
- }
- }
-#endif /* OS2 */
-
-#ifdef VMS
- if (iswild(tmpbuf)) {
-#ifdef COMMENT
- /* Does not handle '.' as version separator */
- char *p = tmpbuf;
- x = 0;
- while (*p) {
- if (*p == ';') {
- x = 1;
- break;
- } else
- p++;
- }
- if (!x) ckstrncat(tmpbuf,";*",TMPBUFSIZ);
-#else
- j = 0; x = 0; /* for end_dot and number of dots */
- i = strlen(tmpbuf);
- if (tmpbuf[i] == ';') {
- ckstrncat(tmpbuf,"0",TMPBUFSIZ);
- } else {
- if (tmpbuf[i--] == '.')
- j++;
- for (; i >= 0; i--) {
- if (tmpbuf[i] == ';' || tmpbuf[i] == ':' ||
- tmpbuf[i] == ']' || tmpbuf[i] == '>')
- break;
- else if (tmpbuf[i] == '.')
- x++;
- }
- if (tmpbuf[i] != ';') { /* dot may have been used */
- if (j) { /* last char is dot */
- if (x) /* second is version separator */
- ckstrncat(tmpbuf,"0",TMPBUFSIZ);
- else /* 'foo.' */
- ckstrncat(tmpbuf,";0",TMPBUFSIZ);
- } else if (x == 1) /* lacking a version separator */
- ckstrncat(tmpbuf,";0",TMPBUFSIZ);
- else if (x == 0) /* x == 2 has a version */
- ckstrncat(tmpbuf,".*;0",TMPBUFSIZ);
- }
- }
-#endif /* COMMENT */
- }
-#endif /* VMS */
-
- debug(F110,"dodel tmpbuf",tmpbuf,0); /* Filename */
-
-#ifndef OS2ORUNIX /* No built-in DELETE code... */
- /* Construct system command. */
- ckmakmsg(line,LINBUFSIZ,DELCMD," ",tmpbuf,NULL);
-#else
-#ifdef VMS
- if (asking) { /* Maybe overwrite in VMS */
- if (x_lis) /* if options are needed... */
- ckmakmsg(line,LINBUFSIZ,DELCMD," /confirm/log ",tmpbuf,NULL);
- else
- ckmakmsg(line,LINBUFSIZ,DELCMD," /confirm ",tmpbuf,NULL);
- } else if (x_lis)
- ckmakmsg(line,LINBUFSIZ,DELCMD," /log ",tmpbuf,NULL);
- conres();
-#endif /* VMS */
-
- debug(F110,"dodel line",line,0);
-#endif /* OS2ORUNIX */
-
-#ifdef MAC
- success = (zdelet(tmpbuf) == 0);
-
-#else /* !MAC ... */
-
-#ifdef OS2ORUNIX
- {
- int filespace = 0;
- int count = 0;
- int lines = 0;
- int n = 0;
-
- s = tmpbuf;
-
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- /* Check whether window size changed */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
- if (x_hdg > 0 && !summary) {
- printf("Deleting %s...%s\n", s, simulate ? " (SIMULATION)" : "");
- n += 2;
- }
-#ifdef ZXREWIND
- z = zxrewind(); /* Rewind file list */
-#else
- if (!deldirs)
- nzxopts = ZX_FILONLY;
- if (recursive) nzxopts |= ZX_RECURSE;
- if (matchdot) nzxopts |= ZX_MATCHDOT;
- errno = 0;
- z = nzxpand(s,nzxopts); /* Expand file list */
-#endif /* ZXREWIND */
- debug(F111,"dodel",s,z);
-
- /* If deleting directories, sort in reverse order */
- /* so we delete the files first, then the directory. */
-
-#ifdef OS2
- /* In K95, we have no mtchs array, nor any control over */
- /* the order in which znext() returns filenames, so we */
- /* must copy the array and sort it. */
- {
- int i;
- if (xmtchs) { /* Free previous list in case */
- debug(F101,"dodel freeing previous list","",xmtchn);
- for (i = 0; i < xmtchn; i++) /* it wasn't freed last time. */
- if (xmtchs[i])
- free(xmtchs[i]);
- free(xmtchs);
- }
- xmtchn = 0;
- xmtchs = (char **)malloc(z * (sizeof(char **))); /* Make new one */
- if (!xmtchs) {
- printf("?Memory allocation failure\n");
- return(-9);
- }
- for (i = 0; i < z; i++) {
- xmtchs[i] = NULL;
- znext(tmpbuf);
- if (!*tmpbuf)
- break;
- makestr(&(xmtchs[i]),tmpbuf);
- if (!xmtchs[i]) {
- printf("?Memory allocation failure\n");
- xmtchn = i - 1;
- rc = -9;
- goto xdelete;
- }
- /* debug(F111,"dodel add",xmtchs[i],i); */
- }
- xmtchn = i;
- debug(F101,"dodel xmtchn","",xmtchn);
- sh_sort(xmtchs,NULL,z,0,deldirs,0);
- }
-#else
-#ifdef UNIX
- sh_sort(mtchs,NULL,z,0,deldirs,filecase);
-#endif /* UNIX */
-#endif /* OS2 */
-
- if (z > 0) {
- int i;
-#ifdef OS2
- int ix = 0;
-#endif /* OS2 */
- success = 1;
- if (x_hdg > 0)
- printf("\n");
-
- while (
-#ifdef OS2
- ix < xmtchn
-#else
- 1
-#endif /* OS2 */
- ) { /* Loop for all files */
-#ifdef OS2
- ckstrncpy(tmpbuf,xmtchs[ix++],TMPBUFSIZ);
-#else
- znext(tmpbuf); /* Get next file */
-#endif /* OS2 */
- if (!*tmpbuf) { /* No more */
- if (deldirs && recursive && argisdir) {
- ckstrncpy(tmpbuf,safebuf,TMPBUFSIZ);
- argisdir = 0; /* (only do this once) */
- } else
- break;
- }
- skip = 0;
- if (!deltree) {
- if (fs)
- if (fileselect(tmpbuf,
- del_aft,del_bef,del_naf,del_nbf,
- minsize,maxsize,0,8,dxlist) < 1) {
- skip++;
- }
- }
- if (!skip && scan && itsadir) {
- skip++;
- }
- if (!skip && scan) {
- switch (scanfile(tmpbuf,&y,nscanfile)) {
- case FT_BIN:
- if (xmode != 1)
- skip++;
- break;
- case FT_TEXT:
- case FT_7BIT:
- case FT_8BIT:
-#ifdef UNICODE
- case FT_UTF8:
- case FT_UCS2:
-#endif /* UNICODE */
- if (xmode != 0)
- skip++;
- }
- }
- if (!skip && asking) {
- int x;
- ckmakmsg(line,LINBUFSIZ," Delete ",tmpbuf,"? ",NULL);
- x = getyesno(line,3);
- switch (x) {
- case 0: continue; /* no */
- case 1: break; /* yes */
- case 2: goto xdelete; /* quit */
- case 3: asking = 0; break; /* go */
- }
- }
-#ifdef VMSORUNIX
- len = zgetfs(tmpbuf); /* Get length and accessibility */
- itsadir = zgfs_dir;
- if (itsadir && zgfs_link) { /* Treat links to directories */
- itsadir = 0; /* as regular files */
- if (scan) /* But not if /TYPE: was given */
- skip++;
- }
- if (itsadir) /* (emulate non-Unix code) */
- len = -2;
-#else
- len = zchki(tmpbuf); /* Get accessibility */
- if (len < 0) /* See if it's a directory */
- itsadir = isdir(tmpbuf);
-#endif /* VMSORUNIX */
-
- if (skip) {
-#ifdef COMMENT /* Too verbose */
- if (x_lis > 0) {
- lines++;
- printf(" %s (SKIPPED)\n",tmpbuf);
-#ifdef CK_TTGWSIZ
- if (++n > cmd_rows - 3)
- if (!askmore()) goto xdelete; else n = 0;
-#endif /* CK_TTGWSIZ */
- }
-#endif /* COMMENT */
- continue;
- }
-
- debug(F111,"DELETE len",tmpbuf,len);
- if (simulate) {
- filespace += len;
- count++;
- if (x_lis > 0) {
- lines++;
- printf(" %s (SELECTED)\n",tmpbuf);
- if (++n > cmd_rows - 3) {
- int xx;
- xx = askmore();
- if (!xx) goto xdelete; else n = 0;
- }
- }
- } else if (len >= 0 || !itsadir) { /* Regular file */
- zdelet(tmpbuf); /* or symlink, etc... */
- if (zchki(tmpbuf) < 0) {
- filespace += len;
- count++;
- if (x_lis > 0) {
- lines++;
- printf(" %s (OK)\n",tmpbuf);
- if (++n > cmd_rows - 3)
- if (!askmore()) goto xdelete; else n = 0;
- }
- } else {
- bad++;
- success = 0;
- if (x_lis > 0) {
- lines++;
- printf(" %s (FAILED: %s)\n",tmpbuf,ck_errstr());
- if (++n > cmd_rows - 3)
- if (!askmore()) goto xdelete; else n = 0;
- }
- }
- } else if (/* pass > 0 && */ deldirs && itsadir) {
- /* It's a directory */
- if (zrmdir(tmpbuf) > -1) { /* Only works if empty */
- count++;
- if (x_lis > 0) {
- lines++;
- printf(" %s (OK)\n",tmpbuf);
- if (++n > cmd_rows - 3)
- if (!askmore()) goto xdelete; else n = 0;
- }
- } else {
- success = 0;
- if (x_lis > 0) {
- lines++;
- printf(" %s (FAILED: %s)\n",
- tmpbuf,
- ck_errstr());
- if (++n > cmd_rows - 3)
- if (!askmore()) goto xdelete; else n = 0;
- }
- }
- } else if (x_lis > 0) {
- lines++;
- if (isdir(tmpbuf))
- printf(" %s (FAILED: directory)\n",tmpbuf);
- else
- printf(" %s (FAILED: not a regular file)\n",tmpbuf);
- if (++n > cmd_rows - 3)
- if (!askmore()) goto xdelete; else n = 0;
- }
- }
- if (x_hdg > 0) {
- if (lines > 0)
- printf("\n");
- if (++n > cmd_rows - 3)
- if (!askmore()) goto xdelete; else n = 0;
- printf("%d file%s %sdeleted, %d byte%s %sfreed%s\n",
- count,
- count != 1 ? "s" : "",
- simulate ? "would be " : "",
- filespace,
- filespace != 1 ? "s" : "",
- simulate ? "would be " : "",
- simulate ? " (maybe)" : ""
- );
- }
- if (!x_lis && !success && !quiet) {
- printf("?DELETE failed for %d file%s \
-(use DELETE /LIST to see details)\n",
- bad, bad == 1 ? "" : "s"
- );
- }
- } else if (x_lis > 0) {
- if (errno)
- printf("?%s: %s\n",ck_errstr(), tmpbuf);
- else
- printf("?Can't delete: %s\n",tmpbuf);
- }
- }
-#else /* OS2ORUNIX */
-#ifndef VMS /* Others - let the system do it. */
- xsystem(line);
- x = nzxpand(tmpbuf,nzxopts);
- success = (x > 0) ? 0 : 1;
- if (x_hdg > 0)
- printf("%s - %sdeleted\n", tmpbuf, success ? "" : "not ");
-#else
- if (asking)
- printf("\n");
- x = xsystem(line); /* zshcmd returns 1 for success */
- success = (x > 0) ? 1 : 0;
- if (x_hdg > 0 && !asking)
- printf("%s - %sdeleted\n", tmpbuf, success ? "" : "not ");
- concb((char)escape);
-#endif /* VMS */
-#endif /* OS2ORUNIX */
-#endif /* MAC */
- xdelete:
- if (g_matchdot > -1) {
- matchdot = g_matchdot; /* Restore these... */
- g_matchdot = -1;
- }
-#ifdef OS2
- if (xmtchs) {
- int i;
- debug(F101,"dodel freeing list","",xmtchn);
- for (i = 0; i < xmtchn; i++)
- if (xmtchs[i]) free(xmtchs[i]);
- free(xmtchs);
- xmtchs = NULL;
- xmtchn = 0;
- }
-#endif /* OS2 */
- debug(F101,"dodel result","",rc);
- return((rc < 0) ? rc : success);
-}
-#endif /* NOFRILLS */
-
-#ifndef NOSPL /* The ELSE command */
-_PROTOTYP( VOID pushqcmd, (char *) );
-
-int
-doelse() {
- if (!ifcmd[cmdlvl]) {
- printf("?ELSE doesn't follow IF\n");
- return(-2);
- }
-#ifdef COMMENT
-/*
- Wrong. This prevents IF..ELSE IF...ELSE IF...ELSE IF...ELSE...
- from working.
-*/
- ifcmd[cmdlvl] = 0;
-#endif /* COMMENT */
- if (!iftest[cmdlvl]) { /* If IF was false do ELSE part */
- if (maclvl > -1 || tlevel > -1) { /* In macro or command file */
- debug(F100,"doelse pushing","",0);
-#ifndef COMMENT
- pushcmd(NULL); /* save rest of command. */
-#else
- /* This fixes certain obscure problems */
- /* but breaks many other constructions that must work. */
- pushqcmd(NULL);
-#endif /* COMMENT */
- } else { /* If interactive, */
- cmini(ckxech); /* just start a new command */
- printf("\n"); /* (like in MS-DOS Kermit) */
- if (pflag) prompt(xxstring);
- }
- } else { /* Condition is false */
- if ((y = cmtxt("command to be ignored","",&s,NULL)) < 0)
- return(y); /* Gobble up rest of line */
- }
- return(0);
-}
-#endif /* NOSPL */
-
-#ifndef NOSPL
-int
-doswitch() {
- char *lp, *ap; /* Macro argument pointer */
- int len = 0, x, y, pp = 0;
- char brbuf[3];
-
- /* Get variable name */
-
- tmpbuf[0] = NUL;
- brbuf[0] = '{';
- brbuf[1] = '}';
- brbuf[2] = NUL;
-
- y = cmfld("Variable name","",&s,xxstring);
- debug(F111,"doswitch cmfld",s,y);
- if (y < 0) {
- if (y == -3) /* Because brstrip() writes */
- s = brbuf; /* into its argument. */
- else
- return(y);
- }
- debug(F110,"doswitch A",s,0);
- if (!strcmp(s,"(")) {
- pp++;
- if ((y = cmfld("Variable name","",&s,xxstring)) < 0) {
- if (y == -3)
- s = brbuf;
- else
- return(y);
- debug(F110,"doswitch B",s,0);
- }
- }
- len = ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
- if (tmpbuf[0] == CMDQ) {
- if (chkvar(s) < 1) {
- printf("?Variable name required\n");
- return(-9);
- }
- }
- if (pp > 0) { /* If open paren given parse closing */
- if ((y = cmfld("Closing parenthesis","",&s,NULL)) < 0)
- return(y);
- if (strcmp(atmbuf,")")) {
- printf("?Closing parenthesis required\n");
- return(-9);
- }
- }
- lp = line;
- x = ckstrncpy(lp,"_switx ",LINBUFSIZ); /* _switx + space */
- lp += x;
- ap = lp;
- debug(F010,"SWITCH a",line,0);
-
-#ifdef COMMENT
- x = ckmakmsg(lp,LINBUFSIZ-x,tmpbuf," ",NULL,NULL); /* variable name + SP */
-#else
- { /* variable name + SP */
- char * p = tmpbuf;
- if (len > 0) {
- if (tmpbuf[0] == '(' && tmpbuf[len-1] == ')') {
- tmpbuf[len-1] = NUL;
- p++;
- }
- }
- x = ckmakmsg(lp,LINBUFSIZ-x,"{",brstrip(p),"}"," ");
- }
-#endif /* COMMENT */
- debug(F010,"SWITCH b",line,0);
- lp += x;
-
- /* Get body */
-
- if ((y = cmtxt("series of cases","",&s,NULL)) < 0) return(y);
- if ((y = (int)strlen(s)) < 1) return(-2);
- if (s[0] != '{' && s[y-1] != '}') { /* Supply braces if missing */
- ckmakmsg(tmpbuf,TMPBUFSIZ,"{ ",s," }",NULL);
- s = tmpbuf;
- }
- if (litcmd(&s,&lp,(LINBUFSIZ - (lp - (char *)line) - 2)) < 0) {
- printf("?Unbalanced braces\n");
- return(0);
- }
- debug(F010,"SWITCH c",line,0);
-
- x = mlook(mactab,"_switx",nmac); /* Look up SWITCH macro definition */
- if (x < 0) { /* Not there? */
- addmmac("_switx",sw_def); /* Put it back. */
- if ((x = mlook(mactab,"_switx",nmac)) < 0) { /* Look it up again. */
- printf("?SWITCH macro definition gone!\n"); /* Shouldn't happen. */
- return(success = 0);
- }
- }
- debug(F010,"SWITCH command",line,0); /* Execute the SWITCH macro. */
- success = dodo(x,ap,cmdstk[cmdlvl].ccflgs | CF_IMAC);
- debug(F101,"SWITCH status","",success);
- return(success);
-}
-
-int
-dofor() { /* The FOR command. */
- int i, fx, fy, fz; /* loop variables */
- char *ap, *di; /* macro argument pointer */
- int pp = 0; /* Paren level */
- int mustquote = 0;
-
- for (i = 0; i < 2; i++) {
- if ((y = cmfld("Variable name","",&s,NULL)) < 0) {
- if (y == -3) {
- printf("?Variable name required\n");
- return(-9);
- } else
- return(y);
- }
- if (strcmp(s,"("))
- break;
- pp++;
- }
-#ifdef COMMENT
- if ((y = parsevar(s,&x,&z)) < 0) /* Check variable. */
- return(y);
-#else
- if (*s == CMDQ) /* If loop variable starts with */
- mustquote++; /* backslash, mustquote is > 0. */
-#endif /* COMMENT */
-
- lp = line; /* Build a copy of the command */
- ckstrncpy(lp,"_forx ",LINBUFSIZ);
- lp += (int)strlen(line); /* "_for" macro. */
- ap = lp; /* Save pointer to macro args. */
-
- if (*s == CMDQ) s++; /* Skip past backslash if any. */
- while ((*lp++ = *s++)) ; /* copy it */
- lp--; *lp++ = SP; /* add a space */
-
- if ((y = cmnum("initial value","",10,&fx,xxstring)) < 0) {
- if (y == -3) return(-2);
- else return(y);
- }
- debug(F101,"dofor fx","",fx);
- s = atmbuf; /* Copy the atom buffer */
-
- if ((int)strlen(s) < 1) goto badfor;
-/*
- In edit 192, we change the loop variables to be evaluated at loop entry,
- not each time through the loop. This was required in order to allow
- \v(argc) to be used as a loop variable, or in a loop-variable expression.
- Thus, we can't have FOR loops that modify their own exit conditions by
- changing the final value or the increment. The problem with \v(argc) was
- that it is on the macro stack; after entry into the _forx macro, it is at
- the wrong place.
-*/
- sprintf(tmpbuf,"%d",fx); /* (SAFE) Substitute actual value */
- s = tmpbuf;
- while ((*lp++ = *s++)) ; /* (what they actually typed) */
- lp--; *lp++ = SP;
-#ifdef DEBUG
- *lp = NUL;
- debug(F110,"FOR A",line,0);
-#endif /* DEBUG */
-
- if ((y = cmnum("final value","",10,&fy,xxstring)) < 0) {
- if (y == -3) return(-2);
- else return(y);
- }
- debug(F101,"dofor fy","",fy);
- s = atmbuf; /* Same deal */
- if ((int)strlen(s) < 1)
- goto badfor;
-
- sprintf(tmpbuf,"%d",fy); /* SAFE */
- s = tmpbuf;
- while ((*lp++ = *s++)) ;
- lp--;
- *lp++ = SP;
-#ifdef DEBUG
- *lp = NUL;
- debug(F110,"FOR B",line,0);
-#endif /* DEBUG */
-
- x_ifnum = 1; /* Increment or parenthesis */
- di = (fx < fy) ? "1" : "-1"; /* Default increment */
- if ((y = cmnum("increment",di,10,&fz,xxstring)) < 0) {
- debug(F111,"dofor increment",atmbuf,y);
- x_ifnum = 0;
- if (y == -3) { /* Premature termination */
- return(-2);
- } else if (y == -2) { /* Maybe closing paren */
- if (!strcmp(atmbuf,")")) {
- pp--; /* Count it */
- s = di; /* supply default interval */
- fz = atoi(s);
- } else /* Not closing paren, invalid */
- return(y);
- } else /* Other error */
- return(y);
- } else { /* Number */
- x_ifnum = 0;
- debug(F101,"dofor fz","",fz);
- s = atmbuf; /* Use it */
- }
- if ((int)strlen(s) < 1)
- goto badfor;
-
- sprintf(tmpbuf,"%d",fz); /* (SAFE) Same deal */
- s = tmpbuf;
- while ((*lp++ = *s++)) ;
- lp--; *lp++ = SP;
-
-#ifdef DEBUG
- *lp = NUL;
- debug(F110,"FOR C",line,0);
-#endif /* DEBUG */
-
- /* Insert the appropriate comparison operator */
- if (fz < 0)
- *lp++ = '<';
- else
- *lp++ = '>';
- *lp++ = SP;
-
-#ifdef DEBUG
- *lp = NUL;
- debug(F110,"FOR D",line,0);
-#endif /* DEBUG */
-
- if (pp > 0) { /* If open paren given parse closing */
- if ((y = cmfld("Closing parenthesis","",&s,NULL)) < 0)
- return(y);
- if (strcmp(atmbuf,")")) {
- printf("?Closing parenthesis required\n");
- return(-9);
- }
- }
- if ((y = cmtxt("Command to execute","",&s,NULL)) < 0) return(y);
- if ((y = (int)strlen(s)) < 1) return(-2);
- if (s[0] != '{' && s[y-1] != '}') { /* Supply braces if missing */
- ckmakmsg(tmpbuf,TMPBUFSIZ,"{ ",s," }",NULL);
- s = tmpbuf;
- }
- if (litcmd(&s,&lp,(LINBUFSIZ - (lp - (char *)line) - 2)) < 0) {
- printf("?Unbalanced braces\n");
- return(0);
- }
-#ifdef DEBUG
- *lp = NUL;
- debug(F110,"FOR E",line,0);
-#endif /* DEBUG */
-
-#ifdef COMMENT
-/* Too strict */
- if (fz == 0) {
- printf("?Zero increment not allowed\n");
- return(0);
- }
-#endif /* COMMENT */
-/*
- In version 8.0 we decided to allow macro names anyplace a numeric-valed
- variable could appear. But this caused trouble for the FOR loops because
- the quoting in for_def[] assumed a \%i-style loop variable. We account
- for this here in the if (mustquote)...else logic by invoking separate
- FOR macro definitions in the two cases.
-*/
- if (mustquote) { /* \%i-style loop variable */
- x = mlook(mactab,"_forx",nmac); /* Look up FOR macro definition */
- if (x < 0) { /* Not there? */
- addmmac("_forx",for_def); /* Put it back. */
- if ((x = mlook(mactab,"_forx",nmac)) < 0) { /* Look it up again. */
- printf("?FOR macro definition gone!\n");
- return(success = 0);
- }
- }
- } else { /* Loop variable is a macro */
- x = mlook(mactab,"_forz",nmac);
- if (x < 0) {
- addmmac("_forz",foz_def);
- if ((x = mlook(mactab,"_forz",nmac)) < 0) {
- printf("?FOR macro definition gone!\n");
- return(success = 0);
- }
- }
- }
- debug(F010,"FOR command",line,0); /* Execute the FOR macro. */
- return(success = dodo(x,ap,cmdstk[cmdlvl].ccflgs | CF_IMAC));
-
-badfor:
- printf("?Incomplete FOR command\n");
- return(-2);
-}
-#endif /* NOSPL */
-
-
-#ifndef NOSPL
-
-/* T O D 2 S E C -- Convert time of day as hh:mm:ss to secs since midnite */
-/*
- Call with a string hh:mm or hh:mm:ss.
- Returns a 0 to 86400 on success, or a negative number on failure.
-*/
-long
-tod2sec(t) char * t; {
- long t2;
- long hh = 0L, mm = 0L, ss = 0L;
-
- if (!t) t = "";
- if (!*t)
- return(-3L);
- debug(F110,"tod2sec",t,0);
-
- if (isdigit(*t)) /* Get hours from argument */
- hh = *t++ - '0';
- else
- return(-1L);
- if (isdigit(*t))
- hh = hh * 10 + *t++ - '0';
-#ifdef COMMENT
- if (hh > 24L)
- return(-1L);
-#endif /* COMMENT */
- if (*t == ':')
- t++;
- else if (!*t)
- goto xtod2sec;
- else
- return(-1L);
-
- if (isdigit(*t)) /* Minutes */
- mm = *t++ - '0';
- else
- return(-1L);
- if (isdigit(*t))
- mm = mm * 10 + *t++ - '0';
- if (mm > 60L)
- return(-1L);
- if (*t == ':')
- t++;
- else if (!*t)
- goto xtod2sec;
- else
- return(-1L);
-
- if (isdigit(*t)) /* Seconds */
- ss = *t++ - '0';
- else
- return(-1L);
- if (isdigit(*t))
- ss = ss * 10 + *t++ - '0';
- if (ss > 60L)
- return(-1L);
-
- if (*t > 32) /* No trailing junk allowed */
- return(-1L);
-
- xtod2sec:
-
- t2 = hh * 3600L + mm * 60L + ss; /* Seconds since midnight from arg */
- debug(F101,"tod2sec t2","",t2);
-
- return(t2);
-}
-
-int waitinterval = 1;
-
-#ifdef OLDWAIT
-#undef OLDWAIT
-#endif /* OLDWAIT */
-
-int kbchar = NUL;
-
-int
-dopaus(cx) int cx; {
- long zz;
- extern int sleepcan;
-
-#ifdef OLDWAIT
- zz = -1L;
- x_ifnum = 1; /* Turn off internal complaints */
- if (cx == XXWAI)
- y = cmnum("seconds to wait, or time of day hh:mm:ss","1",10,&x,xxstring);
- else if (cx == XXPAU)
- y = cmnum("seconds to pause, or time of day hh:mm:ss",
- "1",10,&x,xxstring);
- else
- y = cmnum("milliseconds to sleep, or time of day hh:mm:ss",
- "100",10,&x,xxstring);
- x_ifnum = 0;
- if (y < 0) {
- if (y == -2) { /* Invalid number or expression */
- char *p = tmpbuf; /* Retrieve string from atmbuf */
- int n = TMPBUFSIZ;
- *p = NUL;
- zzstring(atmbuf,&p,&n); /* Evaluate in case it's a variable */
- zz = tod2sec(tmpbuf); /* Convert to secs since midnight */
- if (zz < 0L) {
- printf("?Number, expression, or time of day required\n");
- return(-9);
- } else {
- char now[32]; /* Current time */
- char *p;
- long tnow;
- p = now;
- ztime(&p);
- tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
- if (zz < tnow) /* User's time before now */
- zz += 86400L; /* So make it tomorrow */
- zz -= tnow; /* Seconds from now. */
- }
- } else
- return(y);
- }
- if (x < 0) x = 0;
- switch (cx) {
- case XXPAU: /* PAUSE */
- case XXMSL: /* MSLEEP */
- if ((y = cmcfm()) < 0) return(y);
- break;
- case XXWAI: /* WAIT */
- z = 0; /* Modem signal mask */
- while (1) { /* Read zero or more signal names */
- y = cmkey(mstab,nms,"modem signal","",xxstring);
- if (y == -3) break; /* -3 means they typed CR */
- if (y < 0) return(y); /* Other negatives are errors */
- z |= y; /* OR the bit into the signal mask */
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- default: /* Shouldn't happen */
- return(-2);
- }
-
-/* Command is entered, now do it. */
-
- if (zz > -1L) { /* Time of day given? */
- x = zz;
- if (zz != (long) x) {
- printf(
-"Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
- );
- return(-9);
- }
- }
- if (cx == XXMSL) { /* Millisecond sleep */
- msleep(zz < 0 ? x : x * 1000);
- return(success = 1);
- }
- if (cx == XXPAU && !sleepcan) { /* SLEEP CANCELLATION is OFF */
- sleep(x);
- return(success = 1);
- }
-
- /* WAIT, or else SLEEP with cancellation allowed... */
-
- do { /* Sleep loop */
- int mdmsig;
- if (sleepcan) { /* Keyboard cancellation allowed? */
- if (y = conchk()) { /* Did they type something? */
-#ifdef COMMENT
- while (y--) coninc(0); /* Yes, gobble it all up */
-#else
- /* There is a debate over whether PAUSE should absorb */
- /* its cancelling character(s). There are several */
- /* reasons why it should gobble at least one character: */
- /* (1) MS-DOS Kermit does it */
- /* (2) if not, subsequent PAUSE commands will terminate */
- /* immediately */
- /* (3) if not, subsequent ASK commands will use it as */
- /* valid input. If \13, then it will get no input */
- /* (4) if not, then the character appears on the command */
- /* line after all enclosing macros are complete. */
- kbchar = coninc(0); /* Gobble one up */
-#endif /* COMMENT */
- break; /* And quit PAUSing or WAITing */
- }
- }
- if (cx == XXWAI) { /* WAIT (z == modem signal mask) */
- debug(F101,"WAIT x","",x);
- if (z > 0) { /* Looking for any modem signals? */
- mdmsig = ttgmdm(); /* Yes, get them */
- if (mdmsig < 0) /* Failed */
- return(success = 0);
- if ((mdmsig & z) == z) /* Got what we wanted? */
- return(success = 1); /* Succeed */
- }
- if (x == 0) /* WAIT 0 and didn't get our signals */
- break;
- }
- sleep(1); /* No interrupt, sleep one second */
- } while (--x > 0);
-
- if (cx == XXWAI) /* If WAIT and loop exhausted */
- success = (z == 0); /* Fail. */
- else /* */
- success = (x == 0); /* Set SUCCESS/FAILURE for PAUSE. */
- return(success);
-
-#else /* New code uses chained FDBs and allows FILE waits... */
-
- char * m = ""; /* Help message */
- struct FDB nu, fl; /* Parse function descriptor blocks */
- int filewait = 0;
- int mdmsig = 0, fs = 0;
- char filedate[32];
-
- kbchar = 0;
-
- switch (cx) {
- case XXWAI: m = "seconds to wait, or time of day hh:mm:ss"; break;
- case XXPAU: m = "seconds to pause, or time of day hh:mm:ss"; break;
- case XXMSL: m = "milliseconds to sleep, or time of day hh:mm:ss"; break;
- }
- zz = -1L;
- cmfdbi(&nu,
- _CMNUM, /* Number */
- m, /* Help message */
- (cx == XXMSL) ? "100" : "1", /* Default */
- "", /* N/A */
- 0, /* N/A */
- 0, /* N/A */
- xxstring, /* Processing function */
- NULL, /* N/A */
- &fl /* Next */
- );
- cmfdbi(&fl, /* Time of day */
- _CMFLD, /* Field */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring, /* processing func */
- NULL, /* N/A */
- NULL /* No next */
- );
- x = cmfdb(&nu); /* Parse a number or a field */
- if (x < 0) {
- if (x == -3)
- x = -2;
- return(x);
- }
- switch (cmresult.fcode) {
- case _CMNUM: /* Number */
- x = cmresult.nresult;
- break;
- case _CMFLD: /* Field */
- zz = tod2sec(cmresult.sresult); /* Convert to secs since midnight */
- if (zz < 0L) {
- printf("?Number, expression, or time of day required\n");
- return(-9);
- } else {
- char now[32]; /* Current time */
- char *p;
- long tnow;
- p = now;
- ztime(&p);
- tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
- if (zz < tnow) /* User's time before now */
- zz += 86400L; /* So make it tomorrow */
- zz -= tnow; /* Seconds from now. */
- }
- }
- debug(F101,"PAUSE/WAIT/MSLEEP zz","",zz);
- switch (cx) {
- case XXPAU: /* PAUSE */
- case XXMSL: /* MSLEEP */
- if ((y = cmcfm()) < 0) return(y);
- break;
- case XXWAI: /* WAIT */
- z = 0; /* Modem signal mask */
- y = cmkey(waittab,nwaittab,"","",xxstring);
- if (y < 0) {
- if (y == -3) {
- if ((y = cmcfm()) < 0)
- return(y);
- break;
- } else
- return(y);
- }
- if (y == WAIT_FIL) { /* FILE */
- int wild = 0;
- if ((z = cmkey(wfswi,nwfswi,"event","",xxstring)) < 0)
- return(z);
- filewait = z;
- if (filewait == WF_MOD || filewait == WF_DEL)
- z = cmifi("Filename","",&s,&wild,xxstring);
- else
- z = cmfld("Filename","",&s,xxstring);
- if (z < 0)
- return(z);
- if (wild || ((filewait == WF_CRE) && iswild(s))) {
- printf("?Wildcards not valid here\n");
- return(-9);
- }
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((z = cmcfm()) < 0)
- return(z);
- break;
- } else if (y != WAIT_MDM) { /* A modem signal */
- z |= y; /* OR the bit into the signal mask */
- }
- if (!filewait) { /* Modem signals... */
- while (1) { /* Get zero or more signal names */
- y = cmkey(mstab,nms,"modem signal","",xxstring);
- if (y == -3) break; /* -3 means they typed CR */
- if (y < 0) return(y); /* Other negatives are errors */
- z |= y; /* OR the bit into the signal mask */
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
- }
-
- default: /* Shouldn't happen */
- return(-2);
- } /* switch (cx) */
-
-/* Command is entered, now do it. */
-
- if (zz > -1L) { /* Time of day given? */
- x = zz;
- if (zz != (long) x) {
- printf(
-"Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
- );
- return(-9);
- }
- }
- if (sleepcan)
- concb((char)escape); /* Ensure single-char wakeup */
-
- if (cx == XXMSL) { /* Millisecond sleep */
- msleep(zz < 0 ? x : x * 1000);
- return(success = 1);
- }
- if (cx == XXPAU && !sleepcan) { /* SLEEP CANCELLATION is OFF */
- sleep(x);
- return(success = 1);
- }
- if (filewait) { /* FILE... */
- fs = zchki(tmpbuf); /* Check if file exists */
- switch (filewait) {
- case WF_DEL:
- if (fs == -1)
- return(success = 1);
- break;
- case WF_MOD:
- if (fs == -1) {
- printf("?File does not exit: %s\n",tmpbuf);
- return(-9);
- }
- s = zfcdat(tmpbuf); /* Get current modification date */
- if (!s) s = "";
- if (ckstrncpy(filedate,s,32) != 17) {
- printf("?Can't get modification time: %s\n",tmpbuf);
- return(-9);
- }
- break;
- case WF_CRE:
- if (fs > -1)
- return(success = 1);
- break;
- }
- }
- do { /* Polling loop */
- if (sleepcan) { /* Keyboard cancellation allowed? */
- if ((y = conchk()) > 0) { /* Did they type something? */
- kbchar = coninc(0); /* Yes, get first char they typed */
- debug(F000,"WAIT kbchar","",kbchar);
-#ifdef COMMENT
- while (--y > 0) /* Gobble the rest up */
- coninc(0);
-#endif /* COMMENT */
- return(success = 0); /* And quit PAUSing or WAITing */
- }
- }
- if (filewait == 0) {
- if (cx == XXWAI) { /* WAIT for modem signals */
- if (z != 0) {
- mdmsig = ttgmdm(); /* Get them. */
- debug(F101,"WAIT ttgmdm","",mdmsig);
- if (mdmsig < 0) /* Failure to get them? */
- return(success = 0); /* Fail. */
- if ((mdmsig & z) == z) /* Got desired ones? */
- return(success = 1); /* Succeed. */
- } else if (x == 0)
- return(success = 0);
- }
- } else { /* FILE... */
- fs = zchki(tmpbuf); /* Get file status */
- if (filewait == WF_MOD) { /* Wait for modification */
- if (fs == -1) /* Failure to get status */
- return(success = 0); /* so WAIT fails. */
- s = zfcdat(tmpbuf); /* Get current modification time */
- if (!s) s = ""; /* And compare with the time */
- if (strcmp(s,filedate)) /* when the WAIT started */
- return(success = 1);
- } else if (filewait == WF_DEL) { /* Wait for deletion */
- if (fs == -1) /* If file doesn't exist, */
- return(success = 1); /* succeed. */
- } else if (filewait == WF_CRE) { /* Wait for creation */
- if (fs != -1) /* If file exists */
- return(success = 1); /* succeed. */
- }
- }
- if (x < 1) /* SLEEP/WAIT/PAUSE 0 */
- break;
- sleep(waitinterval); /* No interrupt, sleep */
- x -= waitinterval; /* Deduct sleep time */
- } while (x > 0);
-
- if (cx == XXWAI) /* WAIT time expired */
- success = (z == 0); /* Succeed if no modem signals */
- else /* For SLEEP or PAUSE, success */
- success = (x == 0); /* depends on whether it was */
- return(success); /* interrupted from the keyboard. */
-#endif /* OLDWAIT */
-}
-#endif /* NOSPL */
-
-#ifdef OS2ORUNIX
-_PROTOTYP(int zcmpfn,(char *, char *));
-#endif /* OS2ORUNIX */
-
-#ifndef NOFRILLS
-#ifdef NT
-int
-dolink() {
- /* Parse a file or a directory name */
- int i, x, z, listing = 0, havename = 0, wild = 0, rc = 1;
- struct FDB sw, fi;
-
- cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */
- _CMKEY, /* fcode */
- "Filename or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nqvswtab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- qvswtab, /* Keyword table */
- &fi /* Pointer to next FDB */
- );
-
- cmfdbi(&fi, /* 1st FDB - file to type */
- _CMIFI, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 3, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
-
- while (!havename) {
- x = cmfdb(&sw); /* Parse something */
- if (x < 0) /* Error */
- return(x);
- switch (cmresult.fcode) {
- case _CMKEY:
- switch (cmresult.nresult) {
- case DEL_LIS:
- case DEL_VRB:
- listing = 1;
- break;
- case DEL_NOL:
- case DEL_QUI:
- listing = 0;
- break;
- }
- break;
- case _CMIFI:
- s = cmresult.sresult;
- havename = 1;
- break;
- default:
- return(-2);
- }
- }
- wild = cmresult.nresult; /* Source specification wild? */
-
- ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of source name */
- s = line;
-
- if (!wild)
- wild = iswild(line);
-
- p = tmpbuf; /* Place for new name */
- if ((x = cmofi(wild ? "Target directory" : "New name",
- "",&s,xxstring)) < 0) { /* Get new name */
- if (x == -3) {
- printf("?%s required\n", wild ? "Target directory" : "New name");
- return(-9);
- } else return(x);
- }
- ckstrncpy(p,s,TMPBUFSIZ); /* Make a safe copy of the new name */
- if ((y = cmcfm()) < 0) return(y);
-
- if (!wild) { /* Just one */
- if (listing) printf("%s => %s ",line,p);
- if (zlink(line,p) < 0) {
- if (listing) printf("(FAILED: %s\n",ck_errstr());
- rc = 0;
- } else {
- if (listing) printf("(OK)\n");
- }
- return(success = rc);
- }
- if (!isdir(p)) { /* Multiple */
- printf( /* if target is not a directory */
-"?Multiple source files not allowed if target is not a directory.\n");
- return(-9);
- }
-#ifdef COMMENT
- else { /* Show full path of target */
- char buf[CKMAXPATH]; /* (too much) */
- if (zfnqfp(p,CKMAXPATH,buf))
- ckstrncpy(tmpbuf,buf,TMPBUFSIZ);
- }
-#endif /* COMMENT */
-
-#ifdef VMS
- conres(); /* Let Ctrl-C work. */
-#endif /* VMS */
- debug(F110,"dolink line",line,0);
-
-#ifdef ZXREWIND
- z = zxrewind(); /* Rewind file list */
-#else
- z = nzxpand(s,0); /* Expand file list */
-#endif /* ZXREWIND */
- debug(F111,"dolink p",p,z);
-
-#ifdef UNIX
- if (wild && z > 1)
- sh_sort(mtchs,NULL,z,0,0,filecase); /* Alphabetize the filename list */
-#endif /* UNIX */
-
- while (z-- > 0) {
- if (!(z == 0 && !wild))
- znext(line);
- if (!line[0])
- break;
- if (listing) printf("%s => %s ",line,p);
- if (zlink(line,p) < 0) {
- if (listing) printf("(FAILED: %s\n",ck_errstr());
- rc = 0;
- } else {
- if (listing) printf("(OK)\n");
- }
- }
-#ifdef VMS
- concb((char)escape);
-#endif /* VMS */
- return(success = rc);
-}
-#endif /* NT */
-
-#ifdef ZCOPY
-int
-docopy() {
- int i, x, listing = 0, nolist = 0, havename = 0, getval;
- char c;
- struct FDB sw, fi;
- int overwrite = OVW_ALWAYS;
- int targetisdir = 0;
- int targetlen = 0;
- int appending = 0;
- int preserve = 0;
- int swapping = 0;
- int fromb64 = 0;
- int tob64 = 0;
- int wild = 0;
- int rc = 1;
-
- char newname[CKMAXPATH], * nm;
- nm = newname;
-
- cmfdbi(&sw, /* 1st FDB - switches */
- _CMKEY, /* fcode */
- "Filename or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- ncopytab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- copytab, /* Keyword table */
- &fi /* Pointer to next FDB */
- );
- cmfdbi(&fi, /* 2nd FDB - file to copy */
- _CMIFI, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
-
- while (!havename) {
- x = cmfdb(&sw); /* Parse something */
- if (x < 0) /* Error */
- return(x);
- switch (cmresult.fcode) {
- case _CMKEY:
- c = cmgbrk(); /* Get break character */
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- rc = -9;
- return(rc);
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- rc = -9;
- return(rc);
- }
- switch (cmresult.nresult) {
- case DEL_LIS:
- case DEL_VRB:
- nolist = 0;
- listing = 1;
- break;
- case DEL_NOL:
- case DEL_QUI:
- nolist = 1;
- listing = 0;
- break;
- case 999:
- swapping = 1;
- break;
- case 998:
- appending = 1;
- break;
- case 995:
- preserve = 1;
- break;
- case 994:
- if ((x = cmkey(ovwtab,novwtab,
- "When to overwrite existing destination file",
- "",xxstring)) < 0)
- return(x);
- overwrite = x;
- break;
-#ifndef NOSPL
- case 997:
- fromb64 = 1;
- break;
- case 996:
- tob64 = 1;
- break;
-#endif /* NOSPL */
- }
- break;
- case _CMIFI:
- s = cmresult.sresult;
- havename = 1;
- break;
- default:
- return(-2);
- }
- }
- wild = cmresult.nresult;
- ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of source name */
- s = line;
- p = tmpbuf; /* Place for new name */
-
- /* Get destination name */
- if ((x = cmofi("destination name and/or directory",
-#ifdef UNIX
- "."
-#else
- ""
-#endif /* UNIX */
- ,&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Name for destination file required\n");
- return(-9);
- } else return(x);
- }
- ckstrncpy(p,s,TMPBUFSIZ); /* Safe copy of destination name */
- if ((y = cmcfm()) < 0) return(y);
- if (appending && swapping) {
- printf("?Sorry, /APPEND and /SWAP conflict\n");
- return(-9);
- }
-#ifdef COMMENT
-/*
- This unreasonably prevented "COPY /APPEND *.* bigfile" from concatenating
- a bunch of files into one big file.
-*/
- if (appending && wild) {
- printf("?Sorry, /APPEND can be used only with single files\n");
- return(-9);
- }
-#endif /* COMMENT */
- targetisdir = isdir(p);
- x = strlen(p);
- if (targetisdir) {
-#ifdef UNIXOROSK
- if (p[x-1] != '/') {
- ckstrncat(p,"/",TMPBUFSIZ);
- x++;
- }
-#else
-#ifdef OS2
- if (p[x-1] != '/') {
- ckstrncat(p,"/",TMPBUFSIZ);
- x++;
- }
-#else
-#ifdef STRATUS
- if (p[x-1] != '>') {
- ckstrncat(p,">",TMPBUFSIZ);
- x++;
- }
-#else
-#ifdef datageneral
- if (p[x-1] != ':') {
- ckstrncat(p,":",TMPBUFSIZ);
- x++;
- }
-#else
- if (p[x-1] != '/') {
- ckstrncat(p,"/",TMPBUFSIZ);
- x++;
- }
-#endif /* datageneral */
-#endif /* STRATUS */
-#endif /* OS2 */
-#endif /* UNIXOROSK */
- }
- targetlen = x;
-
- if (!appending) { /* If /APPEND not given */
- if (wild && !targetisdir) { /* No wildcards allowed */
- printf( /* if target is not a directory */
-"?Multiple source files not allowed if target is not a directory.\n");
- return(-9);
- }
- }
-
-#ifdef VMS
- conres(); /* Let Ctrl-C work. */
-#endif /* VMS */
- debug(F110,"docopy line",line,0);
- debug(F110,"docopy p",p,0);
- debug(F110,"docopy nm",nm,0);
-
-#ifdef ZXREWIND
- z = zxrewind(); /* Rewind file list */
-#else
- z = nzxpand(s,0); /* Expand file list */
-#endif /* ZXREWIND */
-
-#ifdef UNIX
- if (wild)
- sh_sort(mtchs,NULL,z,0,0,filecase); /* Alphabetize the filename list */
-#endif /* UNIX */
-
-#ifdef IKSD
- if (!targetisdir && zchki(p) > -1) { /* Destination file exists? */
- if (inserver && (!ENABLED(en_del)
-#ifdef CK_LOGIN
- || isguest
-#endif /* CK_LOGIN */
- )) {
- printf("?Sorry, overwriting existing files is disabled\n");
- return(-9);
- }
- }
-#endif /* IKSD */
-
- if (tob64 && fromb64) { /* To and from B64 = no conversion */
- tob64 = 0;
- fromb64 = 0;
- }
- debug(F110,"COPY dest",p,0);
-
- while (z > 0) {
-
- znext(line);
- if (!line[0])
- break;
-
- errno = 0; /* Reset errno */
-
- if (targetisdir) {
- zstrip(line,&nm);
- ckmakmsg(newname,CKMAXPATH,p,nm,NULL,NULL);
- nm = newname;
- } else {
- nm = p;
- }
- if (overwrite) { /* Overwrite checking? */
- if (zchki(nm) >= (CK_OFF_T)0) { /* Destination file exists? */
-
- char d1[20], * d2;
- char * n1, * n2;
- int i, skip = 0;
-
- i = strlen(line); /* Isolate source filename */
- for (; i >= 0; i--) {
- if (ISDIRSEP(line[i])) {
- n1 = &line[i+1];
- break;
- }
- }
- debug(F110,"COPY n1", n1, 0);
- i = strlen(nm); /* And destination filename */
- for (; i >= 0; i--) {
- if (ISDIRSEP(nm[i])) {
- n2 = &nm[i+1];
- break;
- }
- }
- debug(F110,"COPY n2", n2, 0);
- if (!strcmp(n1,n2)) { /* Same name? */
- if (overwrite == OVW_NEVER) { /* Never overwrite? */
- if (listing) /* Skip */
- if (listing) printf("%s => %s (SKIPPED)\n",line,nm);
- continue;
- }
- ckstrncpy(d1,zfcdat(line),20); /* Source file timestamp */
- d2 = zfcdat(nm); /* Timestamp of dest file */
- x = strcmp(d1,d2); /* Compare them */
- if (((overwrite == OVW_NEWER) && (x < 0)) ||
- ((overwrite == OVW_OLDER) && (x > 0))) {
- if (listing)
- if (listing) printf("%s => %s (SKIPPED)\n",line,nm);
- continue;
- }
- }
- }
- }
- if (listing) printf("%s => %s ",line,nm);
-
- /* Straight copy */
- if (!swapping && !appending && !fromb64 && !tob64) {
- debug(F110,"COPY zcopy",line,0);
-
- if ((x = zcopy(line,p)) < 0) { /* Let zcopy() do it. */
- debug(F111,"COPY not OK",line,x);
- switch (x) {
- case -2:
- if (listing)
- printf("(FAILED: Not a regular file)\n");
- else if (!nolist)
- printf("?Not a regular file - %s\n",line);
- rc = 0;
- break;
- case -3:
- if (listing)
- printf("(FAILED: Not found or not accessible)\n");
- else if (!nolist)
- printf("?Not found or not accessible - %s\n",line);
- rc = 0;
- break;
- case -4:
- if (listing)
- printf("(FAILED: Permission denied)\n");
- else if (!nolist)
- printf("?Permission denied - %s\n",line);
- rc = 0;
- break;
- case -5:
- if (listing)
- printf("(Source and destination are the same file)\n");
- else if (!nolist)
- printf(
- "?Source and destination are the same file - %s\n",
- line
- );
- break;
- case -6:
- if (listing)
- printf("(FAILED: Input/Output error)\n");
- else if (!nolist)
- printf("?Input/Output error - %s\n",line);
- rc = 0;
- break;
- case -7:
- if (listing)
- printf("(FAILED: %s - %s)\n",p,ck_errstr());
- else if (!nolist)
- printf("?%s - %s\n",ck_errstr(),p);
- rc = 0;
- break;
- default:
- if (listing)
- printf("(FAILED: %s)\n",ck_errstr());
- else if (!nolist)
- printf("?%s\n",ck_errstr());
- rc = 0;
- }
- } else { /* Regular copy succeeded */
- debug(F110,"COPY OK..",newname,0);
-#ifndef NOXFER
- if (preserve) { /* Handle /PRESERVE */
- char * pstr = ""; /* File permissions string */
- struct zattr xx; /* File attribute structure */
- extern char * cksysid;
-
- initattr(&xx); /* Initialize the struct */
-
- xx.systemid.val = cksysid; /* Set our system ID */
- xx.systemid.len = (int)strlen(cksysid);
-#ifdef CK_PERMS
- pstr = zgperm(line); /* Get source file's permissions */
-#endif /* CK_PERMS */
- xx.lprotect.val = pstr;
- xx.lprotect.len = (int)strlen(pstr);
- xx.date.val = zfcdat(line); /* Source file's timestamp */
- xx.date.len = (int)strlen(xx.date.val);
- if (zstime(nm,&xx,0) < 0) {
- printf("?COPY /PRESERVE %s: %s\n",nm,ck_errstr());
- rc = -9;
- }
- }
-#endif /* NOXFER */
- if (listing && rc > -1)
- printf("(OK)\n");
- }
-
- } else { /* Special options */
-
- int prev, y, x = 0; /* Variables needed for them */
- int i, t;
- char ibuf[100];
- char obuf[200];
- FILE * in = NULL;
- FILE * out = NULL;
-
- if ((in = fopen(line,"r")) == NULL) { /* Open input file */
- if (listing)
- printf("(FAILED: %s)\n",ck_errstr());
- else if (!nolist)
- printf("?%s - %s)\n",ck_errstr(),line);
- rc = 0;
- continue;
- }
- if (targetisdir) { /* Target is directory */
- char * buf = NULL; /* so append this filename to it */
- zstrip(line,&buf);
- p[targetlen] = NUL;
- if (buf)
- ckstrncat(p,buf,TMPBUFSIZ);
- }
-#ifdef OS2ORUNIX
- if (zcmpfn(line,p)) { /* Input and output are same file? */
- if (listing)
- printf("(FAILED: Source and destination identical)\n");
- else if (!nolist)
- printf("?Source and destination identical - %s\n", line);
- rc = 0;
- continue;
- }
-#endif /* OS2ORUNIX */
- if ((out = fopen(p, (appending ? "a" : "w"))) == NULL) {
- fclose(in);
- if (listing)
- printf("(FAILED: %s - %s)\n",p,ck_errstr());
- else if (!nolist)
- printf("?%s - %s\n",p,ck_errstr());
- rc = 0;
- continue;
- }
-#ifndef NOSPL
- if (tob64) { /* Converting to Base-64 */
-
- debug(F110,"COPY tob64",line,0);
-
- while (1) { /* Loop... */
- prev = x;
- if ((x = fread(ibuf,1,54,in)) < 1) { /* EOF */
- if (listing)
- printf("(OK)\n");
- break;
- }
- if (prev % 3) {
- if (listing)
- printf("(FAILED: Phase error at %d)\n",prev);
- else if (!nolist)
- printf("?Phase error at %d\n",prev);
- rc = 0;
- break;
- }
- if (swapping) {
- if (x & 1) {
- if (listing)
- printf("(FAILED: Swap error)\n");
- else if (!nolist)
- printf("?Swap error\n");
- rc = 0;
- break;
- }
- for (i = 0; i < x; i+=2) {
- t = ibuf[i];
- ibuf[i] = ibuf[i+1];
- ibuf[i+1] = t;
- }
- }
- if ((y = b8tob64(ibuf,x,obuf,180)) < 0) {
- if (listing)
- printf("(FAILED: Encoding error)\n");
- else if (!nolist)
- printf("?Encoding error\n");
- rc = 0;
- break;
- }
- fprintf(out,"%s\n",obuf);
- }
-
- } else if (fromb64) { /* Converting from Base 64 */
-
- debug(F110,"COPY fromb64",line,0);
-
- if ((out = fopen(p,appending ? "a" : "w")) == NULL) {
- fclose(in);
- if (listing)
- printf("(FAILED: %s - %s)\n",p,ck_errstr());
- else if (!nolist)
- printf("?%s - %s\n",p,ck_errstr());
- rc = 0;
- continue;
- }
- x = 1;
- while (x) {
- x = fread(ibuf,1,80,in);
- if ((y = b64tob8(ibuf,x,obuf,80)) < 0) {
- if (listing)
- printf("(FAILED: Decoding error)\n");
- else if (!nolist)
- printf("?Decoding error\n");
- rc = 0;
- break;
- }
- if (swapping) {
- if (x & 1) {
- if (listing)
- printf("(FAILED: Swap error)\n");
- else if (!nolist)
- printf("?Swap error\n");
- rc = 0;
- break;
- }
- for (i = 0; i < y; i+=2) {
- t = obuf[i];
- obuf[i] = obuf[i+1];
- obuf[i+1] = t;
- }
- }
- if (y > 0) {
- if (fwrite(obuf,1,y,out) < 1) {
- if (listing)
- printf("(FAILED: %s - %s)\n",p,ck_errstr());
- else if (!nolist)
- printf("?%s - %s\n",p,ck_errstr());
- rc = 0;
- break;
- }
- }
- }
-
- } else
-#endif /* NOSPL */
-
- if (swapping) { /* Swapping bytes */
-
- CHAR c[3];
- c[2] = NUL;
-
- debug(F110,"COPY swapping",line,0);
-
- while (1) {
- x = fread((char *)c,1,2,in);
- if (x < 1) {
- if (listing)
- printf("(OK)\n");
- break;
- } else if (x == 1) {
- c[1] = c[0];
- c[0] = NUL;
- printf(
- "(WARNING: Odd byte count)");
- if (!listing) printf("\n");
- }
- if (fprintf(out,"%c%c",c[1],c[0]) == EOF) {
- if (listing)
- printf("(FAILED: %s - %s)\n",p,ck_errstr());
- else if (!nolist)
- printf("?%s - %s\n",p,ck_errstr());
- rc = 0;
- break;
- }
- }
-
- } else if (appending) { /* Appending to target file */
-
- char c;
-
- debug(F110,"COPY appending",line,0);
-
- while (1) {
- x = fread(&c,1,1,in);
- if (x < 1) {
- if (listing)
- printf("(OK)\n");
- break;
- }
- if (fwrite(&c,1,1,out) < 1) {
- if (listing)
- printf("(FAILED: %s - %s)\n",p,ck_errstr());
- else if (!nolist)
- printf("?%s - %s\n",p,ck_errstr());
- rc = 0;
- break;
- }
- }
- }
- if (out) fclose(out);
- if (in) fclose(in);
- }
-#ifdef VMSORUNIX
- concb((char)escape);
-#endif /* VMSORUNIX */
- }
- if (rc > -1) success = rc;
- return(rc);
-}
-#endif /* ZCOPY */
-#endif /* NOFRILLS */
-
-#ifndef NOCSETS
-#ifndef NOUNICODE
-static struct keytab * xfcstab = NULL; /* For RENAME /CONVERT: */
-static char cvtbufin[CKMAXPATH+8] = { NUL, NUL };
-static char cvtbufout[CKMAXPATH+8] = { NUL, NUL };
-static char * pcvtbufin = NULL;
-static char * pcvtbufout = NULL;
-
-static int /* Input function xgnbyte() */
-cvtfnin() {
- CHAR c;
- c = *pcvtbufin++;
- return(c ? c : -1);
-}
-
-_PROTOTYP(int cvtfnout,(char)); /* Output function for xpnbyte() */
-int
-#ifdef CK_ANSIC
-cvtfnout(char c)
-#else
-cvtfnout(c) char c;
-#endif /* CK_ANSIC */
-{
- if (pcvtbufout - cvtbufout >= CKMAXPATH)
- return(-1);
- *pcvtbufout++ = c;
- *pcvtbufout = NUL;
- return(1);
-}
-
-/* Convert a string from any charset to any other charset */
-
-char *
-cvtstring(s,csin,csout) char * s; int csin, csout; {
- int c;
- extern CK_OFF_T ffc;
-
- ckstrncpy(cvtbufin,s,CKMAXPATH); /* Put it in a public place */
- pcvtbufin = cvtbufin; /* with public pointers */
- pcvtbufout = cvtbufout;
- *pcvtbufout = NUL;
-
- if (csin == csout) /* If the two sets are the same */
- return((char *)cvtbufin); /* don't bother converting */
-
- initxlate(csin,csout); /* Initialize the translator */
-
- while ((c = xgnbyte(FC_UCS2,csin,cvtfnin)) > -1) { /* Loop thru string */
- if (xpnbyte(c,TC_UCS2,csout,cvtfnout) < 0) {
- ffc = (CK_OFF_T)0;
- return("");
- }
- }
- /* ffc is touched by xgnbyte() but this is not file transfer */
- /* so we have to undo it */
- ffc = (CK_OFF_T)0;
- return((char *)cvtbufout);
-}
-#endif /* NOUNICODE */
-#endif /* NOCSETS */
-
-#ifndef NORENAME
-#ifndef NOFRILLS
-#ifdef ZRENAME
-
-/* The RENAME command - expanded and improved in 8.0.212 April 2006 */
-
-static char * ren_sub[4] = { NULL,NULL,NULL,NULL }; /* For RENAME /REPLACE */
-
-int ren_list = 0; /* Default listing action for RENAME */
-int ren_coll = RENX_OVWR; /* Default collision action */
-
-int
-shorename() {
- char * s;
- switch (ren_coll) {
- case RENX_FAIL: s = "fail"; break;
- case RENX_OVWR: s = "overwrite"; break;
- case RENX_SKIP: s = "proceed"; break;
- }
- printf(" rename collision: %s\n",s);
- printf(" rename list: %s\n",showoff(ren_list));
- return(1);
-}
-
-int
-setrename() { /* Parse SET RENAME options */
- int x, y;
- if ((x = cmkey(renamset,nrenamset,"","", xxstring)) < 0)
- return(x);
- switch (x) {
- case REN_OVW: /* COLLISION */
- if ((x = cmkey(r_collision,nr_collision,"","", xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ren_coll = x;
- break;
- case DEL_LIS: /* LIST */
- return(seton(&ren_list));
- }
- return(success = 1);
-}
-
-/* Reverse a string - Assumes a single-byte character set */
-
-int
-gnirts(s1, s2, len) char * s1, * s2; int len; {
- int n, m = 0;
- if (!s1) /* Null source pointer, fail */
- return(0);
- n = (int) strlen(s1);
- if (n > len-1) /* Source longer than dest, fail */
- return(0);
- s2[n--] = NUL; /* Deposit null byte at end of dest */
- for (; n >= 0; n--) { /* Copy the rest backwards */
- *s2++ = s1[n];
- m++;
- }
- return(m);
-}
-
-/*
- r e n a m e o n e
-
- Worker function to rename one file for dorenam() (below).
- old = name of file or directory to be renamed
- new = new name (not required for /UPPER, /LOWER, and /REPLACE)
- replacing = 1 if doing string replacement on the name
- casing = 1 if converting name to lowercase, 2 if to uppercase
- all = if doing case conversion on all names, not just monocase ones
- converting = 1 if converting character sets
- cset1 = character set to convert from (File Character Set index)
- cset2 = character set to convert to (ditto, see ck?xla.h)
- listing = 1 to show results of rename
- nolist = 1 to be completely silent (don't even print error messages)
- op = 1 means simulate, 2 means check for collision, 0 means rename
- size = length of result buffer.
- collision = action to take if destination file already exists:
- 0 = fail
- 1 = overwrite and succeed
- 2 = skip and succeed
- Returns:
- 0: on failure to rename or when a forbidden collision would have occurred.
- 1: on success (file was renamed or did not need to be renamed).
- Note:
- If this code is ever built on any platform that is not Unix, Windows,
- VMS, or OS/2, this routine might need some adjustment.
-*/
-
-/* Opcodes for op... */
-#define REN_OP_SIM 1 /* Simulate */
-#define REN_OP_CHK 2 /* Check for collisions */
-
-static int
-renameone(old,new,
- replacing,casing,all,converting,cset1,cset2,
- listing,nolist,op,size,collision)
- char * old, * new;
- int replacing,casing,all,converting,cset1,cset2,
- listing,nolist,op,size,collision;
-{
- char buf[CKMAXPATH]; /* Temporary filename buffer */
- char out[CKMAXPATH]; /* Buffer for new name */
- char dir[CKMAXPATH]; /* Destination directory */
- char pat[CKMAXPATH]; /* Path segment on old filename */
-
- char * destdir; /* Destination directory, if any */
- char * srcpath; /* Source path, if any */
- int rc = 1, flag = 0, skip = 0; /* Control */
- int honorcase = 0, replaced = 0;
- int anchor = 0; /* 1 = beginning, 2 = end */
- int occur = 0; /* Occurrence */
- int minus = 0; /* Occurrence is negative */
- int allbut = 0; /* Occurrence is "all but" */
- int arg2isfile = 0; /* Arg2 ("new") is a filename */
-
- debug(F110,"RENAMEONE old",old,0);
- debug(F110,"RENAMEONE new",new,0);
- debug(F110,"RENAMEONE ren_sub[0]",ren_sub[0],0);
- debug(F110,"RENAMEONE ren_sub[1]",ren_sub[1],0);
- debug(F110,"RENAMEONE ren_sub[2]",ren_sub[2],0);
-
- if (op == REN_OP_SIM && !nolist) /* For convenience */
- listing = 1;
-#ifndef NOSPL
- honorcase = inpcas[cmdlvl]; /* Inherit SET CASE value */
-#else
-#ifdef UNIX
- honorcase = 1;
-#else
- honorcase = 0;
-#endif /* UNIX */
-#endif /* NOSPL */
-
- if (!old) old = ""; /* In case of bad args */
- if (!new) new = "";
- if (!*old) return(success = 0);
- ckstrncpy(out,new,CKMAXPATH); /* So we don't write into */
- new = out; /* our argument... */
- size = CKMAXPATH;
-
- pat[0] = NUL; /* Assume no path in source file.. */
- srcpath = pat;
- {
- int n; /* If the old name includes a path */
- n = (int)strlen(old) - 1; /* put it in a separate place. */
- for (; n >= 0; n--) { /* We are renaming the file only. */
- if (ISDIRSEP(old[n])) {
- ckstrncpy(pat,old,CKMAXPATH);
- pat[n+1] = NUL;
- old = old+n+1;
- break;
- }
- }
- }
- debug(F110,"RENAMEONE old 2",old,0);
- debug(F110,"RENAMEONE pat 2",pat,0);
-
- dir[0] = NUL; /* Assume no destination directory */
- destdir = dir;
- if (*new) { /* If Arg2 given */
- if (isdir(new)) { /* If it's a directory */
- ckstrncpy(dir,new,CKMAXPATH); /* put it here */
- } else { /* otherwise */
- arg2isfile++; /* flag that it's a filename */
- }
- }
- if (!casing && !replacing && !converting) {
- if (!*new)
- return(success = 0);
- if (!arg2isfile) { /* Destination is a directory? */
- if (!isdir(old)) { /* and source is not? */
-#ifndef VMS
- int n, x = 0; /* Concatenate them */
- if ((n = strlen(new)) > 0) /* so we can check for */
- if (ISDIRSEP(new[n-1])) /* collisions. */
- x++;
- ckmakmsg(buf,size,new,x ? "" : "/", old, "");
-#else
- ckmakmsg(buf,size,new, old, NULL, NULL);
-#endif /* VMS */
- debug(F110,"RENAMEONE new new",new,0);
- new = buf;
- size = CKMAXPATH;
- }
- }
- } else if (*new) { /* Directory to move file to */
- int n, x = 0; /* after changing its name */
- if (!isdir(new))
- return(success = 0);
-#ifndef VMS
- if ((n = strlen(new)) > 0)
- if (ISDIRSEP(new[n-1]))
- x++;
- ckmakmsg(dir,CKMAXPATH,new,x ? "" : "/", "", "");
-#else
- ckstrncpy(dir,new,CKMAXPATH);
-#endif /* VMS */
- }
-
-#ifndef NOCSETS
-#ifndef NOUNICODE
- if (converting) {
- new = cvtstring(old,cset1,cset2);
- }
-#endif /* NOUNICODE */
-#endif /* NOCSETS */
-
- if (replacing) { /* Replacing strings */
- int todo = 0;
- int len0, len1, len2;
- char c, *p, *s, *bp[3];
-
- bp[0] = old; /* Original name */
- bp[1] = ren_sub[0]; /* String to be replaced */
- bp[2] = ren_sub[1]; /* What to replace it with */
- if (!bp[2]) bp[2] = "";
-
- len0 = (int)strlen(bp[0]); /* length of original filename */
- len1 = (int)strlen(bp[1]); /* length of target substring */
- len2 = (int)strlen(bp[2]); /* Length of replacement string */
-
- if (ren_sub[2]) { /* Optional options */
- p = ren_sub[2];
- while ((c = *p++)) {
- switch (c) {
- case '^':
- anchor = 1; occur = 0; minus = 0; allbut = 0; break;
- case '$':
- anchor = 2; occur = 0; minus = 0; allbut = 0; break;
- case 'A': honorcase = 1; minus = 0; allbut = 0; break;
- case 'a': honorcase = 0; minus = 0; allbut = 0; break;
- case '-': minus = 1; break;
- case '~': allbut = 1; break;
- default:
- if (isdigit(c)) {
- occur = c - '0';
- if (minus) occur = 0 - occur;
- anchor = 0;
- }
- minus = 0;
- }
- }
- }
- if (anchor) { /* Anchored replacement... */
- y = len0 - len1;
- if (y > 0) {
- int x;
- switch (anchor) {
- case 1: /* Anchored at beginning */
- if (!ckstrcmp(bp[1],bp[0],len1,honorcase)) {
- x = ckstrncpy(new,bp[2],size);
- (VOID) ckstrncpy(new+x,bp[0]+len1,size-x);
- replaced = 1;
- }
- break;
- case 2: /* Anchored at end */
- if (!ckstrcmp(bp[1],bp[0]+y,len1,honorcase)) {
- x = ckstrncpy(new,bp[0],y+1);
- (VOID) ckstrncpy(new+y,bp[2],size-x);
- replaced = 1;
- }
- break;
- }
- }
- if (!replaced) {
- ckstrncpy(new,old,size); /* Keep old name */
- replaced = 1;
- }
- } else { /* Replace all occurrences */
- int j, n = 0; /* or a particular occurrence */
- char c;
- int x = 0;
- char * s0 = NULL, * s1 = NULL, * s2 = NULL;
- p = new; /* Pointer to new name */
-
- if (occur < 0) { /* nth occurrence from the right */
- occur = 0 - occur;
- s0 = (char *)malloc(len0+1); /* Reverse original string */
- if (s0) {
- (VOID) gnirts(bp[0],s0,len0+1);
- bp[0] = s0;
- } else return(0);
- s1 = (char *)malloc(len1+1); /* Reverse target string */
- if (s1) {
- (VOID) gnirts(bp[1],s1,len1+1);
- bp[1] = s1;
- } else return(0);
- s2 = (char *)malloc(len2+1); /* Reverse replacement string */
- if (s2) {
- (VOID) gnirts(bp[2],s2,len2+1);
- bp[2] = s2;
- } else return(0);
- debug(F111,"RENAMEONE s0",s0,len0);
- debug(F111,"RENAMEONE s1",s1,len1);
- debug(F111,"RENAMEONE s2",s2,len2);
- }
- s = bp[0]; /* Pointer to old name */
- p = new; /* Pointer to new name */
- j = len0 - len1 + 1; /* How much to scan */
- while (j-- > 0) { /* For each character... */
- if (!ckstrcmp(bp[1],s,len1,honorcase)) { /* Match? */
- n++; /* Occurrence counter */
- todo = (occur == 0) ||
- (!allbut && n == occur) ||
- (allbut && n != occur);
- if (!todo) { /* Desired occurrence? */
- size -= ckstrncpy(p,bp[1],size); /* No... */
- p += len1; /* Copy target string */
- s += len1; /* instead of replacement string */
- continue;
- }
- if (len2) { /* If replacement string not empty */
- size -= ckstrncpy(p,bp[2],size); /* Copy it */
- p += len2;
- }
- s += len1; /* Advance source position */
- } else { /* No match */
- *p++ = *s++; /* just copy this character */
- size--;
- }
- }
- while ((*p++ = *s++)); /* Done copy the rest */
- replaced = 1; /* Remember we changed the name */
- if (s0) { /* Were we doing "all but"? */
- debug(F110,"RENAMEONE new1",new,0);
- x = (int)strlen(new); /* Unreverse the result */
- if ((p = (char *)malloc(x+2))) {
- (VOID) gnirts(new,p,x+2);
- debug(F110,"RENAMEONE new2",new,0);
- ckstrncpy(new,p,x+2);
- free(p);
- }
- if (s0) free(s0); /* Free the temporary strings */
- if (s1) free(s1);
- if (s2) free(s2);
- debug(F110,"RENAMEONE new3",new,0);
- }
- }
- }
- if (casing) { /* Changing case? */
- char c, * t; /* See if mixed case. */
- if (!replaced)
- ckstrncpy(new,old,size); /* Copy old name to new name */
- t = new;
- while ((c = *t++)) {
- if (islower(c)) flag |= 1; /* Have a lowercase letter */
- else if (isupper(c)) flag |= 2; /* Have an uppercase letter */
- if (flag == 3) break; /* Have a mixed-case name */
- }
- if (all || flag < 3) { /* Not skipping or not mixed case */
- if (casing == 1 && flag != 1) /* Change case to lower */
- (VOID) cklower(new);
- else if (casing == 2 && flag != 2) /* Change case to upper */
- (VOID) ckupper(new);
- }
- }
- debug(F110,"XXX 1 new",new,0);
- debug(F110,"XXX 1 old",old,0);
- debug(F110,"XXX 1 srcpath",srcpath,0);
- debug(F110,"XXX 1 destdir",destdir,0);
-
- if (*destdir && !arg2isfile) { /* Moving without renaming */
- ckstrncat(srcpath,old,CKMAXPATH);
- old = srcpath;
- new = destdir;
- } else if (*destdir || *srcpath) { /* Were there any pathnames? */
- char tmp[CKMAXPATH];
- ckmakmsg(tmp,CKMAXPATH,srcpath,old,NULL,NULL);
- ckstrncpy(old,tmp,CKMAXPATH);
- if (*destdir) { /* Directory-to-move-to given? */
- ckstrncat(destdir,new,CKMAXPATH);
- new = destdir;
- } else if (*srcpath && !arg2isfile) { /* Or was there a source path? */
- ckstrncat(srcpath,new,CKMAXPATH);
- new = srcpath;
- }
- }
- debug(F110,"XXX 2",new,0);
-
- skip = 0; /* Can we skip this one? */
-#ifdef COMMENT
- if (casing && !replaced) {
- skip = (((all == 0) && (flag == 3)) || (flag == casing)) ? 1 : 0;
- if (!skip && destdir) skip = 0;
- }
-#endif /* COMMENT */
- if (!skip) {
- if (!ckstrcmp(old,new,-1,1))
- skip = 1;
- }
- if (op == 0 && !skip && (collision != RENX_OVWR)) {
- if (zchki(new) > (CK_OFF_T)-1) { /* New file already exists? */
- switch (collision) { /* Yes, take specified action */
- case RENX_SKIP: /* Skip this one and proceed */
- skip = 2;
- break;
- case RENX_FAIL: /* Or fail. */
- skip = 3;
- if (!listing && !nolist)
- printf("?File already exists: %s\n",new);
- }
- }
- }
- debug(F110,"RENAMEONE new",new,0);
- debug(F101,"RENAMEONE flag","",flag);
- debug(F101,"RENAMEONE skip","",skip);
- debug(F100,"RENAMEONE ----------------","",0);
-
- if (skip == 3) {
- if (listing) printf("%s => %s (SKIPPED: %s already exists)\n",
- old,new,new);
- rc = 0;
- } else if (skip) { /* Skipping this one */
- if (listing) printf("%s => %s (%s)\n",
- old,new,
- (skip == 2) ? "COLLISION: SKIPPED" : "SKIPPED");
- } else { /* Have to rename this one */
- if (op == REN_OP_CHK) { /* Checking for collisions */
- return((zchki(new) > (CK_OFF_T)-1) ? 0 : 1 );
- } else if (op == REN_OP_SIM) { /* Simulating */
- if (listing) printf("%s => %s (SIMULATED)\n",old,new);
- } else { /* Really renaming */
- if (listing) printf("%s => %s ",old,new);
- if (zrename(old,new) < 0) {
- rc = 0;
- if (listing)
- printf("(FAILED: %s)\n",ck_errstr());
- else if (!nolist)
- printf("?%s\n",ck_errstr());
- } else {
- if (listing) printf("(OK)\n");
- }
- }
- }
- return(success = rc); /* Succeeds also if nothing needed to be renamed */
-}
-
-int
-dorenam() {
-#ifndef NOCSETS
-#ifndef NOUNICODE
- extern int nfilc;
- extern struct keytab fcstab[];
- extern struct csinfo fcsinfo[];
-#endif /* NOUNICODE */
-#endif /* NOCSETS */
- int cset1 = 0, cset2 = 0;
-
- int i, x, z, fn, listing = 0, havename = 0, wild = 0, rc = 1, noarg = 0;
- int nolist = 0, all = 0, casing = 0, replacing = 0, getval = 0, sim = 0;
- int converting = 0, collision = 0;
-
- char c;
- struct FDB sw, fi;
-
- collision = ren_coll; /* Inherit SET RENAME COLLISION */
- listing = ren_list; /* Inhereit SET RENAME LIST */
-
- if (ren_sub[0]) makestr(&(ren_sub[0]),NULL);
- if (ren_sub[1]) makestr(&(ren_sub[1]),NULL);
- if (ren_sub[2]) makestr(&(ren_sub[2]),NULL);
- line[0] = NUL;
- tmpbuf[0] = NUL;
-
- cmfdbi(&sw, /* 1st FDB - switches */
- _CMKEY, /* fcode */
- "Filename or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nrenamsw, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- renamsw, /* Keyword table */
- &fi /* Pointer to next FDB */
- );
-
- cmfdbi(&fi, /* 2nd FDB - file or directory name */
- _CMIFI, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 3, /* Flags */
- 0, /* 0 = Parse file or directory names */
- xxstring,
- NULL,
- NULL
- );
-
- if (cmflgs == 1) {
- printf("?File or directory name required\n");
- return(-9);
- }
- while (!havename) {
- noarg = 0;
- x = cmfdb(&sw); /* Parse something */
- if (x == -3) { /* They hit Enter prematurely */
- printf("?Command incomplete\n");
- return(-9);
- } else if (x < 0) { /* Other error */
- if (x == -1)
- return(x);
- if (iswild(atmbuf) && nzxpand(atmbuf,nzxopts) == 0)
- printf("?No files match: %s\n",brstrip(atmbuf));
- else if (zchki(atmbuf) == -1)
- printf("?File not found: %s\n",brstrip(atmbuf));
- else
- printf("?Error with switch or filename: %s\n",brstrip(atmbuf));
- return(-9);
- }
- fn = cmresult.nresult; /* For brevity */
- switch (cmresult.fcode) { /* Handle each kind of field */
- case _CMKEY: /* Keyword (switch) */
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (!getval && (cmgkwflgs() & CM_ARG))
- noarg = 1; /* Remember arg is missing */
- switch (cmresult.nresult) { /* Handle the switch */
- case DEL_LIS: /* /LIST */
- case DEL_VRB: /* /VERBOSE */
- listing = 1;
- break;
- case DEL_NOL: /* /NOLIST */
- case DEL_QUI: /* /QUIET */
- nolist = 1;
- listing = 0;
- break;
- case DEL_SIM: /* /SIMULATE */
- sim = 1;
- break;
- case REN_UPP: /* /UPPER: */
- case REN_LOW: /* /LOWER */
- all = 1;
- if (!noarg) {
- if ((x = cmkey((fn == REN_UPP) ? r_upper : r_lower,
- 2, "","all",xxstring)) < 0) {
- if (x == -3)
- x = 1;
- else
- return(x);
- }
- all = x;
- }
- /* 0 = don't convert; 1 = convert to lower; 2 = to upper */
- casing = (fn == REN_UPP) ? 2 : 1;
- converting = 0;
- break;
- case REN_OVW: /* /COLLISION */
- if (!noarg) {
- if ((x = cmkey(r_collision,
- nr_collision,"","overwrite",xxstring))<0) {
- if (x == -3)
- x = RENX_OVWR;
- else
- return(x);
- }
- collision = x;
- }
- break;
- case REN_RPL: /* /REPLACE: */
- if (noarg) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- if ((x = cmfld("String to remove, or {{String1}{String2}}",
- "",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Target string required\n");
- x = -9;
- }
- return(x);
- }
- if (s[0]) {
- if (s[0] == '{' && s[1] == '{') /* Get the list */
- makelist(s,ren_sub,3);
- else
- makestr(&(ren_sub[0]),s);
- }
- converting = 0;
- break;
-
- case REN_SPA: /* /FIXSPACES: */
- if (!noarg)
- if ((x = cmfld("Character or string to replace spaces with",
- "_",&s,xxstring)) < 0)
- if (x == -3)
- s = "_";
- else
- return(x);
- makestr(&(ren_sub[0])," ");
- makestr(&(ren_sub[1]),noarg ? "_" : brstrip(s));
- makestr(&(ren_sub[3]),NULL);
- converting = 0;
- break;
-
-#ifndef NOCSETS
-#ifndef NOUNICODE
- case REN_XLA: /* /CONVERT:cset1:cset2 */
- if (!xfcstab) { /* Make a copy of the file charset */
- int i, x; /* table with CM_ARG set for each */
- x = (nfilc + 1) * sizeof(struct keytab);
- xfcstab = (struct keytab *)malloc(x);
- if (!xfcstab) {
- printf("?Memory allocation failure\n");
- return(-9);
- }
- for (i = 0; i < nfilc; i++) {
- xfcstab[i].kwd = fcstab[i].kwd;
- xfcstab[i].kwval = fcstab[i].kwval;
- xfcstab[i].flgs = fcstab[i].flgs | CM_ARG;
- }
- }
- if ((x = cmswi(xfcstab,nfilc,
- "Character-set of old name","",xxstring)) < 0) {
- if (x == -3) {
- printf("?Pair of character-set names required\n");
- return(-9);
- } else
- return(x);
- }
- cset1 = x;
- c = cmgbrk();
- if (!getval) {
- printf("?Secondcharacter-set name required\n");
- return(-9);
- }
- if ((x = cmkey(fcstab,nfilc,
- "Character-set of new name","",xxstring)) < 0) {
- if (x == -3) {
- printf("?Second character-set name required\n");
- return(-9);
- } else
- return(x);
- }
- cset2 = x;
- if (casing)
- casing = 0;
- if (ren_sub[0])
- makestr(&(ren_sub[0]),NULL);
- if (ren_sub[1])
- makestr(&(ren_sub[1]),NULL);
- if (ren_sub[2])
- makestr(&(ren_sub[2]),NULL);
- converting = 1;
- break;
-#endif /* NOUNICODE */
-#endif /* NOCSETS */
- }
- break;
- case _CMIFI: /* File or directory name */
- s = cmresult.sresult;
- havename = 1;
- break;
- default:
- printf("?File or directory name required\n");
- return(-9);
- }
- }
- if (havename) {
- ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of source name */
- } else {
- printf("?Internal error\n");
- return(-9); /* Shouldn't happen */
- }
- wild = cmresult.nresult; /* Source specification wild? */
- if (!wild)
- wild = iswild(line);
-
- debug(F111,"RENAME WILD",line,wild);
-
- p = tmpbuf; /* Place for new name */
- p[0] = NUL;
- replacing = ren_sub[0] ? 1 : 0;
-
-#ifdef COMMENT
- if (!(casing || replacing || converting)) {
- if ((x = cmofi(wild ? "Target directory" : "New name",
- "",&s,xxstring)) < 0) { /* Get new name */
- if (x == -3) {
- printf("?%s required\n",
- wild ? "Target directory" : "New name");
- return(-9);
- } else return(x);
- }
- ckstrncpy(p,s,TMPBUFSIZ); /* Make a safe copy of the new name */
- }
-#else
- if ((x = cmofi(wild ? "Target directory" : "New name",
- "",&s,xxstring)) < 0) { /* Get new name */
- if (x == -3) {
- if (casing || replacing || converting) {
- s = "";
- } else {
- printf("?%s required\n",
- wild ? "Target directory" : "New name");
- return(-9);
- }
- } else return(x);
- }
- ckstrncpy(p,s,TMPBUFSIZ); /* Make a safe copy of the new name */
-#endif /* COMMENT */
-
- if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
-
-#ifdef COMMENT
-#ifndef NOUNICODE
- if (converting) {
- printf(" From: %s\n",fcsinfo[cset1].keyword);
- printf(" To: %s\n",fcsinfo[cset2].keyword);
- }
-#endif /* NOUNICODE */
- if (casing) {
- printf("CASING: %s\n", (casing == 1) ? "LOWER" : "UPPER");
- }
- if (replacing) {
- printf("REPLACING: '%s' with '%s'\n",
- ren_sub[0],
- ren_sub[1] ? ren_sub[1] : "");
- }
-#endif /* COMMENT */
-
- s = line;
- if (!wild) /* Just one */
- return(success =
- renameone(s,p,
- replacing,casing,all,converting,cset1,cset2,
- listing,nolist,sim,TMPBUFSIZ,collision));
-
- if (!casing && !replacing && !converting) { /* Multiple files */
- if (!isdir(p)) {
- printf( /* if target is not a directory */
-"?Multiple source files not allowed if target is not a directory.\n");
- return(-9);
- }
- }
-#ifdef COMMENT
- else { /* Show full path of target */
- char buf[CKMAXPATH]; /* (too much) */
- if (zfnqfp(p,CKMAXPATH,buf))
- ckstrncpy(tmpbuf,buf,TMPBUFSIZ);
- }
-#endif /* COMMENT */
-
-#ifdef VMS
- conres(); /* Let Ctrl-C work. */
-#endif /* VMS */
- debug(F110,"dorename line",line,0);
-
-#ifdef ZXREWIND
- z = zxrewind(); /* Rewind file list */
-#else
- z = nzxpand(s,0); /* Expand file list */
-#endif /* ZXREWIND */
- debug(F111,"dorename p",p,z);
-
-#ifdef UNIX
- if (wild && z > 1)
- sh_sort(mtchs,NULL,z,0,0,filecase); /* Alphabetize the filename list */
-#endif /* UNIX */
-
- /* For /COLLISION:FAIL make a silent pass to see if there would be any */
-
- if (collision == RENX_FAIL) {
- int n = 0;
- char line[CKMAXPATH+2];
- while (z-- > 0) {
- if (!(z == 0 && !wild))
- znext(line);
- if (!line[0])
- break;
- if (!renameone((char *)line,p,
- replacing,casing,all,converting,cset1,cset2,
- 0,1,REN_OP_CHK,TMPBUFSIZ,RENX_FAIL))
- n++;
- }
- if (n > 0) {
- printf("?Failed: %d file%s would be overwritten\n",
- n, (n != 1) ? "s" : "");
-#ifdef VMS
- concb((char)escape);
-#endif /* VMS */
- return(success = 0);
- }
- /* Get the file list back. */
-#ifdef ZXREWIND
- z = zxrewind();
-#else
- z = nzxpand(s,0);
-#endif /* ZXREWIND */
- }
- while (z-- > 0 && rc > 0) {
- char line[CKMAXPATH+2];
- if (!(z == 0 && !wild))
- znext(line);
- if (!line[0])
- break;
- rc = renameone((char *)line,p,
- replacing,casing,all,converting,cset1,cset2,
- listing,nolist,sim,TMPBUFSIZ,collision);
- }
-#ifdef VMS
- concb((char)escape);
-#endif /* VMS */
- return(success = rc);
-}
-#endif /* ZRENAME */
-#endif /* NOFRILLS */
-#endif /* NORENAME */
-
-#ifndef NOSPL
-
-/* Do the RETURN command */
-
-int
-doreturn(s) char *s; {
- int x;
- extern int tra_asg;
- char * line, * lp;
-
- if (cmdlvl < 1) {
- printf("\n?Can't return from level %d\n",maclvl);
- return(success = 0);
- }
- line = malloc(LINBUFSIZ);
- if (line == NULL)
- return(success = 0);
- lp = line; /* Expand return value now */
- x = LINBUFSIZ-1;
- if (!s) s = "";
- debug(F110,"RETURN s",s,0);
- if (zzstring(s,&lp,&x) > -1) {
- s = line;
- debug(F110,"RETURN zzstring",s,0);
- }
-
- /* Pop from all FOR/WHILE/SWITCH/XIFs */
- while ((maclvl > 0) &&
- (m_arg[maclvl-1][0]) &&
- (cmdstk[cmdlvl].src == CMD_MD) &&
- (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
- !strncmp(m_arg[maclvl-1][0],"_for",4) ||
- !strncmp(m_arg[maclvl-1][0],"_swi",4) ||
- !strncmp(m_arg[maclvl-1][0],"_whi",4))) {
- debug(F111,"RETURN IF/FOR/WHI/SWI pop",m_arg[maclvl-1][0],maclvl);
- dogta(XXPTA); /* Put args back */
- popclvl(); /* Pop up two levels */
- popclvl();
- }
- if (tra_asg) { /* If tracing show return value */
- if (*s)
- printf("<<< %s: \"%s\"\n", m_arg[maclvl][0], s);
- else
- printf("<<< %s: (null)\n", m_arg[maclvl][0]);
- }
- popclvl(); /* Pop from enclosing TAKE or macro */
- debug(F111,"RETURN tolevel",s,maclvl);
- if (!s) s = "";
- if (!*s) s = NULL;
- makestr(&(mrval[maclvl+1]),s); /* Set the RETURN value */
- free(line);
- return(success = 1); /* Macro succeeds if we RETURN */
-}
-#endif /* NOSPL */
-
-#ifndef NOSPL
-/* Do the OPEN command */
-
-int
-doopen() { /* OPEN { append, read, write } */
- int x, y, z = 0; char *s;
- static struct filinfo fcb; /* (must be static) */
- if ((x = cmkey(opntab,nopn,"mode","",xxstring)) < 0) {
- if (x == -3) {
- printf("?Mode required\n");
- return(-9);
- } else return(x);
- }
- switch (x) {
- case OPN_FI_R: /* Old file (READ) */
- if (chkfn(ZRFILE) > 0) {
- printf("?Read file already open\n");
- return(-2);
- }
- if ((z = cmifi("File to read","",&s,&y,xxstring)) < 0) {
- if (z == -3) {
- printf("?Input filename required\n");
- return(-9);
- } else return(z);
- }
- if (y) { /* No wildcards allowed */
- printf("\n?Please specify a single file\n");
- return(-2);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- if ((int)strlen(line) < 1) return(-2);
- if ((z = cmnum("buffer size","4096",10,&y,xxstring)) < 0)
- return(z);
- if (y < 1) {
- printf("?Positive number required\n");
- return(-9);
- }
- if ((z = cmcfm()) < 0) return(z);
- readblock = y;
- if (readbuf)
- free((char *)readbuf);
- if (!(readbuf = (CHAR *) malloc(readblock+1))) {
- printf("?Can't allocate read buffer\n");
- return(-9);
- }
- return(success = zopeni(ZRFILE,line));
-
-#ifndef MAC
-#ifndef NOPUSH
- case OPN_PI_R: /* Pipe/Process (!READ) */
- if (nopush) {
- printf("?Read from pipe disabled\n");
- return(success=0);
- }
- if (chkfn(ZRFILE) > 0) {
- printf("?Read file already open\n");
- return(-2);
- }
- if ((y = cmtxt("System command to read from","",&s,xxstring)) < 0) {
- if (y == -3) {
- printf("?Command name required\n");
- return(-9);
- } else return(y);
- }
- ckstrncpy(line,brstrip(s),LINBUFSIZ);
- if (!line[0]) return(-2);
- if ((y = cmcfm()) < 0) return(y);
- if (!readbuf) {
- if (!(readbuf = (CHAR *) malloc(readblock+1))) {
- printf("?Can't allocate read buffer\n");
- return(-9);
- }
- }
- return(success = zxcmd(ZRFILE,line));
-
- case OPN_PI_W: /* Write to pipe */
- if (nopush) {
- printf("?Write to pipe disabled\n");
- return(success=0);
- }
- if (chkfn(ZWFILE) > 0) {
- printf("?Write file already open\n");
- return(-2);
- }
- if ((y = cmtxt("System command to write to","",&s,xxstring)) < 0) {
- if (y == -3) {
- printf("?Command name required\n");
- return(-9);
- } else return(y);
- }
- ckstrncpy(line,brstrip(s),LINBUFSIZ);
- if (!line[0]) return(-2);
- if ((y = cmcfm()) < 0) return(y);
- success = zxcmd(ZWFILE,line);
- if (!success && msgflg)
- printf("Can't open process for writing: %s\n",line);
- return(success);
-#endif /* NOPUSH */
-#endif /* MAC */
-
- case OPN_FI_W: /* New file (WRITE) */
- case OPN_FI_A: /* (APPEND) */
- if ((z = cmofi("Name of local file to create","",&s,xxstring)) < 0) {
- if (z == -3) {
- printf("?Filename required\n");
- return(-9);
- } else return(z);
- }
- if (z == 2) {
- printf("?Sorry, %s is a directory name\n",s);
- return(-9);
- }
- if (chkfn(ZWFILE) > 0) {
- printf("?Write/Append file already open\n");
- return(-2);
- }
- fcb.bs = fcb.cs = fcb.rl = fcb.fmt = fcb.org = fcb.cc = fcb.typ = 0;
- fcb.lblopts = 0;
- fcb.dsp = (x == OPN_FI_W) ? XYFZ_N : XYFZ_A; /* Create or Append */
- ckstrncpy(line,s,LINBUFSIZ);
- if ((int)strlen(line) < 1) return(-2);
- if ((y = cmcfm()) < 0) return(y);
- return(success = zopeno(ZWFILE,line,NULL,&fcb));
-
-#ifndef NOLOCAL
- case OPN_SER: /* OPEN PORT or LINE */
- case OPN_NET: { /* OPEN HOST */
- extern int didsetlin, ttnproto;
- if (x == OPN_NET) {
- z = ttnproto;
- ttnproto = NP_NONE;
- }
- if ((y = setlin((x == OPN_SER) ? XYLINE : XYHOST, 1, 0)) < 0) {
- if (x == OPN_NET)
- ttnproto = z;
- success = 0;
- }
- didsetlin++;
- return(y);
- }
-#endif /* NOLOCAL */
-
- default:
- printf("?Not implemented");
- return(-2);
- }
-}
-#endif /* NOSPL */
-
-#ifndef NOXFER
-/* D O X G E T -- GET command parser with switches */
-
-#ifdef CK_LABELED
-int g_lf_opts = -1;
-extern int lf_opts;
-#endif /* CK_LABELED */
-
-int
-doxget(cx) int cx; {
- extern int /* External variables we need */
-#ifdef RECURSIVE
- recursive,
-#endif /* RECURSIVE */
- xfermode, fdispla, protocol, usepipes,
- g_binary, g_xfermode, g_displa, g_rpath, g_usepipes;
- extern char * rcv_move; /* Directory to move new files to */
- extern char * rcv_rename; /* What to rename new files to */
- extern char * rcvexcept[]; /* RECEIVE / GET exception list */
- int opkt = 0; /* Flag for O-Packet needed */
-
-#ifdef PIPESEND
- extern int pipesend;
- extern char * rcvfilter;
-#endif /* PIPESEND */
- extern struct keytab rpathtab[];
- extern int nrpathtab;
- extern CK_OFF_T calibrate;
- int asname = 0; /* Flag for have as-name */
- int konly = 0; /* Kermit-only function */
- int c, i, n, confirmed = 0; /* Workers */
- int getval = 0; /* Whether to get switch value */
- int rcvcmd = 0; /* Whether it is the RECEIVE command */
- int mget = 0; /* Whether it is the MGET command */
- struct stringint pv[SND_MAX+1]; /* Temporary array for switch values */
- struct FDB sw, fl, cm; /* FDBs for each parse function */
- char * cmdstr = "this command";
-
-#ifdef NEWFTP
- if (cx == XXGET || cx == XXREGET || cx == XXMGET || cx == XXRETR) {
- extern int ftpget;
- extern int ftpisopen();
- if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
- int x;
- x = doftpget(cx,0);
- debug(F101,"doftpget return","",x);
- if (x > -1)
- success = x;
- debug(F101,"doftpget success","",success);
- return(x);
- }
- }
-#endif /* NEWFTP */
-
- debug(F101,"xget cx","",cx);
-
- oopts = -1;
- omode = -1;
-
- for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */
- pv[i].sval = NULL;
- pv[i].ival = -1;
- pv[i].wval = (CK_OFF_T)-1;
- }
- /* Preset switch values based on top-level command that called us */
-
- switch (cx) {
- case XXREC: /* RECEIVE */
- cmdstr = "RECEIVE";
- rcvcmd = 1; break;
- case XXGET: /* GET */
- cmdstr = "GET";
- konly = 1;
- break;
-#ifdef CK_RESEND
- case XXREGET: /* REGET */
- cmdstr = "REGET";
- konly = 1;
- pv[SND_BIN].ival = 1; /* Implies /BINARY */
- pv[SND_RES].ival = 1; break;
-#endif /* CK_RESEND */
- case XXRETR: /* RETRIEVE */
- cmdstr = "RETRIEVE";
- konly = 1;
- pv[SND_DEL].ival = 1; break;
-#ifdef PIPESEND
- case XXCREC: /* CRECEIVE */
- cmdstr = "CRECEIVE";
- konly = 1;
- rcvcmd = 1;
- pv[SND_CMD].ival = 1; break;
- case XXCGET: /* CGET */
- cmdstr = "CGET";
- konly = 1;
- pv[SND_CMD].ival = 1; break;
-#endif /* PIPESEND */
-#ifndef NOMGET
- case XXMGET: /* MGET */
- cmdstr = "MGET";
- konly = 1;
- mget = 1; break;
-#endif /* NOMGET */
- }
- debug(F111,"xget rcvcmd",cmdstr,rcvcmd);
- debug(F101,"xget konly","",konly);
-
-#ifdef CK_XYZ
- if (!rcvcmd && protocol != PROTO_K) {
- printf("?Sorry, %s works only with Kermit protocol\n",cmdstr);
- return(-9);
- }
-#endif /* CK_XYZ */
-
- /* Set up chained parse functions... */
-
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- rcvcmd ?
- "Optional name/template to store incoming files under, or switch" :
- "Remote filename, or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- rcvcmd ? nrcvtab : ngettab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- rcvcmd ? rcvtab : gettab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- if (rcvcmd || mget) /* RECEIVE or MGET */
- cmfdbi(&fl,
- _CMTXT, /* fcode */
- rcvcmd ? /* hlpmsg */
- "Output filename or Command" : /* Output filename */
- "File(s) to GET", /* Files we are asking for */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
-#ifdef COMMENT
-#ifdef CK_XYZ
- (protocol == PROTO_X || protocol == PROTO_XC) ?
- xxstring :
- (rcvcmd ? (xx_strp)0 : xxstring)
-#else
- rcvcmd ? (xx_strp)0 : xxstring /* Processing function */
-#endif /* CK_XYZ */
-#else /* COMMENT */
- xxstring /* Always evaluate - fdc 2006/02/01 */
-#endif /* COMMENT */
- ,
- NULL,
- &cm
- );
- else
- cmfdbi(&fl, /* Remote filename or command */
- _CMFLD, /* fcode */
- "Remote filename", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* Confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
-
- /* (See doxsend() for fuller commentary) */
-
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse something */
- debug(F101,"xget cmfdb","",x);
- if (x < 0) /* Error */
- goto xgetx; /* or reparse needed */
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- c = cmgbrk(); /* Get break character */
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- x = -9;
- goto xgetx;
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- x = -9;
- goto xgetx;
- }
- n = cmresult.nresult; /* Numeric result = switch value */
- debug(F101,"xget switch","",n);
-
- switch (n) { /* Process the switch */
-#ifdef PIPESEND
- case SND_CMD: /* These take no args */
- if (nopush) {
- printf("?Sorry, system command access is disabled\n");
- x = -9;
- goto xgetx;
- } else if (rcvfilter) {
- printf(
-"?Sorry, no GET /COMMAND when RECEIVE FILTER selected\n");
- x = -9;
- goto xgetx;
- }
- if (rcvcmd)
- sw.hlpmsg = "Command, or switch"; /* Change help message */
- /* Fall thru... */
-#endif /* PIPESEND */
-
- case SND_REC: /* /RECURSIVE */
- pv[SND_PTH].ival = PATH_REL; /* Implies relative pathnames */
- pv[n].ival = 1; /* Set the recursive flag */
- break;
-
- case SND_RES: /* /RECOVER */
- pv[SND_BIN].ival = 1; /* Implies /BINARY */
- pv[n].ival = 1; /* Set the resend flag */
- break;
-
- case SND_DEL: /* /DELETE */
- case SND_SHH: /* /QUIET */
- case SND_CAL: /* /CALIBRATE */
- case SND_XPA: /* /TRANSPARENT */
- pv[n].ival = 1; /* Just set the appropriate flag */
- break;
-
- case SND_PIP: /* /PIPES:{ON,OFF} */
- if (!getval) {
- pv[n].ival = 1;
- break;
- }
- if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
- goto xgetx;
- if (!nopush)
- pv[n].ival = x;
- break;
-
- /* File transfer modes - each undoes the others */
-
- case SND_BIN: /* Binary */
- case SND_TXT: /* Text */
- case SND_IMG: /* Image */
- case SND_LBL: /* Labeled */
- pv[SND_BIN].ival = 0; /* Unset all */
- pv[SND_TXT].ival = 0;
- pv[SND_IMG].ival = 0;
- pv[SND_LBL].ival = 0;
- pv[n].ival = 1; /* Set the requested one */
- break;
-
- case SND_EXC: /* Excludes */
- if (!getval) break;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Pattern required\n");
- x = -9;
- }
- goto xgetx;
- }
- if (pv[n].sval) free(pv[n].sval);
- y = strlen(s);
- if (y > 256) {
- printf("?Pattern too long - 256 max\n");
- x = -9;
- goto xgetx;
- }
- pv[n].sval = malloc(y+1);
- if (pv[n].sval) {
- strcpy(pv[n].sval,s); /* safe */
- pv[n].ival = 1;
- }
- break;
-
-#ifdef COMMENT
- /* Not implemented */
- case SND_PRI: /* GET to printer */
- pv[n].ival = 1;
- if (!getval) break;
- if ((x = cmfld("Print options","",&s,xxstring)) < 0)
- goto xgetx;
- pv[n].sval = malloc((int)strlen(s)+1);
- if (pv[n].sval)
- strcpy(pv[n].sval,s); /* safe */
- break;
-#endif /* COMMENT */
-
- case SND_MOV: /* MOVE after */
- case SND_REN: /* RENAME after */
- if (!getval) break;
- if ((x = cmfld(n == SND_MOV ?
- "device and/or directory for source file after sending" :
- "new name for source file after sending",
- "",
- &s,
- n == SND_MOV ? xxstring : NULL
- )) < 0) {
- if (x == -3) {
- printf("%s\n", n == SND_MOV ?
- "?Destination required" :
- "?New name required"
- );
- x = -9;
- }
- goto xgetx;
- }
- if (pv[n].sval) {
- free(pv[n].sval);
- pv[n].sval = NULL;
- }
- s = brstrip(s);
- y = strlen(s);
- if (y > 0) {
- pv[n].sval = malloc(y+1);
- if (pv[n].sval) {
- strcpy(pv[n].sval,s); /* safe */
- pv[n].ival = 1;
- }
- }
- break;
-
- case SND_ASN: /* As-name */
- if (!getval) break;
- if (mget) {
- printf("?Sorry, as-name not allowed with MGET\n");
- x = -9;
- goto xgetx;
- }
- if (
-#ifdef COMMENT
- (x = cmfld("Name to store it under","",&s,NULL))
-#else
- (x = cmfld("Name to store it under","",&s,xxstring))
-#endif /* COMMENT */
- < 0)
- goto xgetx;
- s = brstrip(s);
- if ((y = strlen(s)) > 0) {
- if (pv[n].sval) free(pv[n].sval);
- pv[n].sval = malloc(y+1);
- if (pv[n].sval) {
- strcpy(pv[n].sval,s); /* safe */
- pv[n].ival = 1;
- }
- }
- break;
-
-#ifdef PIPESEND
- case SND_FLT: /* Filter */
- debug(F101,"xget /filter getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Filter program to receive through",
- "",&s,NULL)) < 0) {
- if (x == -3)
- s = "";
- else
- goto xgetx;
- }
- if (*s) s = brstrip(s);
- y = strlen(s);
- for (x = 0; x < y; x++) { /* Make sure they included "\v(...)" */
- if (s[x] != '\\') continue;
- if (s[x+1] == 'v') break;
- }
- if (x == y) {
- printf(
- "?Filter must contain a replacement variable for filename.\n"
- );
- x = -9;
- goto xgetx;
- }
- pv[n].ival = 1;
- if (pv[n].sval) {
- free(pv[n].sval);
- pv[n].sval = NULL;
- }
- if ((y = strlen(s)) > 0) {
- if ((pv[n].sval = malloc(y+1)))
- strcpy(pv[n].sval,s); /* safe */
- }
- break;
-#endif /* PIPESEND */
-
- case SND_PTH: /* Pathnames */
- if (!getval) {
- pv[n].ival = PATH_REL;
- break;
- }
- if ((x = cmkey(rpathtab,nrpathtab,"","on",xxstring)) < 0)
- goto xgetx;
- pv[n].ival = x; /* Ditto */
- break;
-
- case SND_NAM: /* Filenames */
- if (!getval) break;
- if ((x = cmkey(fntab,nfntab,"","converted",xxstring)) < 0)
- goto xgetx;
- pv[n].ival = x;
- break;
-
- case SND_PRO: /* Protocol to use */
- if (!getval) break;
- if ((x = cmkey(protos,nprotos,"File-transfer protocol","",
- xxstring)) < 0) {
- if (x == -3)
- x = 0;
- else
- goto xgetx;
- }
- debug(F111,"xget /proto",atmbuf,x);
- pv[n].ival = x;
- if (konly && x != PROTO_K) {
- printf(
-"?Sorry, this command works only with Kermit protocol\n"
- );
- x = -9;
- goto xgetx;
- }
- break;
-
- default:
- printf("?Unexpected switch value - %d\n",cmresult.nresult);
- x = -9;
- goto xgetx;
- }
- }
- debug(F101,"xget cmresult fcode","",cmresult.fcode);
-
- cmarg = line; /* Initialize string pointers */
- cmarg2 = tmpbuf;
- asname = 0;
- line[0] = NUL; /* and buffers. */
- tmpbuf[0] = NUL;
-
- switch (cmresult.fcode) { /* How did we get out of switch loop */
- case _CMFLD: /* (3) Remote filespec */
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- break;
- case _CMTXT: /* (4) As-name */
- if (rcvcmd) {
- ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
- if ((int)strlen(tmpbuf) > 0)
- asname = 1;
- } else {
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- }
- case _CMCFM: /* (6) Confirmation */
- confirmed = 1;
- break;
- default:
- printf("?Unexpected function code: %d\n",cmresult.fcode);
- x = -9;
- goto xgetx;
- }
- debug(F110,"xget string",cmarg,0);
- debug(F101,"xget confirmed","",confirmed);
-
- cmarg = brstrip(cmarg); /* Strip any braces */
-
- if (!confirmed) { /* CR not typed yet, get more fields */
- if (pv[SND_CMD].ival > 0) {
- debug(F100,"xget calling cmtxt","",0);
- x = cmtxt("Local command to pipe into","",&s,NULL);
- if (x < 0 && x != -3) goto xgetx;
- if (x != -3) {
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- asname = 1;
- }
- } else if (!rcvcmd) {
-#ifdef VMS
- /* cmofi() fails if you give it a directory name */
- x = cmfld("Name or directory for incoming file","",&s,NULL);
- debug(F111,"xget cmfld",s,x);
-#else
- x = cmofi("Name or directory for incoming file","",&s,NULL);
- debug(F111,"xget cmofi",s,x);
-#endif /* VMS */
- if (x < 0 && x != -3) goto xgetx;
- if (x != -3) {
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((x = cmcfm()) < 0) goto xgetx;
- asname = 1;
- }
- }
- }
- /* Arrive here with cmarg and cmarg2 all set */
-
- debug(F111,"xget asname",cmarg2,asname);
- if (!asname) {
- if (pv[SND_ASN].sval)
- ckstrncpy(tmpbuf,pv[SND_ASN].sval,TMPBUFSIZ);
- else
- tmpbuf[0] = NUL;
- }
- cmarg2 = brstrip(cmarg2); /* Strip outer braces if any. */
- debug(F110,"xget cmarg",cmarg,0);
- debug(F110,"xget cmarg2",cmarg2,0);
-
- if (!*cmarg &&
- (cx == XXGET || cx == XXREGET || cx == XXCGET || cx == XXMGET)) {
- printf("?A remote file specification is required\n");
- x = -9;
- goto xgetx;
- }
-#ifdef PIPESEND
- if (pv[SND_CMD].ival > 0) { /* /COMMAND sets pipesend flag */
- x = -9;
- if (!*cmarg2) {
- printf("?Command required\n");
- goto xgetx;
- } else if (nopush) {
- printf("?Sorry, system command access is disabled\n");
- goto xgetx;
- } else if (rcvfilter) {
- printf("?Sorry, no GET /COMMAND while RECEIVE FILTER selected\n");
- goto xgetx;
- } else
- pipesend = 1;
- }
- debug(F101,"xget /COMMAND pipesend","",pipesend);
-#endif /* PIPESEND */
-
-#ifdef CK_RESEND
- if (pv[SND_RES].ival > 0) { /* REGET or GET /RECOVER */
-#ifdef RECURSIVE
- if (pv[SND_REC].ival > 0) { /* RECURSIVE */
-#ifdef COMMENT
- printf("?Unsupported option combination: /RECOVER /RECURSIVE\n");
- x = -9;
- goto xgetx;
-#else
- opkt = 1;
-#endif /* COMMENT */
- }
-#endif /* RECURSIVE */
- if (pv[SND_DEL].ival > 0) { /* /DELETE */
-#ifdef COMMENT
- printf("?Unsupported option combination: /RECOVER /DELETE\n");
- x = -9;
- goto xgetx;
-#else
- opkt = 1;
-#endif /* COMMENT */
- }
- }
-#endif /* CK_RESEND */
-
- if (pv[SND_EXC].ival > 0) /* /EXCEPT */
- makelist(pv[SND_EXC].sval,rcvexcept,NSNDEXCEPT);
-
-#ifdef IKS_OPTION
- if (!rcvcmd
-#ifdef CK_XYZ
- && protocol == PROTO_K
-#endif /* CK_XYZ */
- ) {
- if (!iks_wait(KERMIT_REQ_START,1)) {
- printf(
- "?A Kermit Server is not available to process this command\n");
- x = -9; /* correct the return code */
- goto xgetx;
- }
- }
-#endif /* IKS_OPTION */
-
-#ifdef CK_XYZ
- {
- int po, pg; /* (for clarity) */
- po = pv[SND_PRO].ival; /* /PROTOCOL option */
- pg = protocol; /* Protocol global */
- if ((rcvcmd && !*cmarg2) && /* If no as-name was given */
- /* and /PROTOCOL is XMODEM or global protocol is XMODEM... */
- ((po < 0 && (pg == PROTO_X || pg == PROTO_XC)) ||
- (po > -1 && (po == PROTO_X || po == PROTO_XC)))
- ) {
- printf(
-"Sorry, you must specify a name when receiving a file with XMODEM protocol\n"
- );
- x = -9;
- goto xgetx;
- }
- }
-#endif /* CK_XYZ */
-
-#ifdef RECURSIVE
- if (pv[SND_REC].ival > 0) { /* RECURSIVE */
- recursive = 1;
- pv[SND_PTH].ival = PATH_REL; /* Implies relative pathnames too */
- }
-#endif /* RECURSIVE */
-
- if (pv[SND_PIP].ival > -1) {
- g_usepipes = usepipes;
- usepipes = pv[SND_PIP].ival;
- }
-
- /* Save global protocol parameters */
-
- g_proto = protocol;
-#ifdef CK_LABELED
- g_lf_opts = lf_opts; /* Save labeled transfer options */
-#endif /* CK_LABELED */
- g_urpsiz = urpsiz; /* Receive packet length */
- g_spsizf = spsizf; /* Send packet length flag */
- g_spsiz = spsiz; /* Send packet length */
- g_spsizr = spsizr; /* etc etc */
- g_spmax = spmax;
- g_wslotr = wslotr;
- g_prefixing = prefixing;
- g_fncact = fncact;
- g_fncnv = fncnv;
- g_fnspath = fnspath;
- g_fnrpath = fnrpath;
- g_xfrxla = xfrxla;
-
- if (pv[SND_PRO].ival > -1) { /* Change according to switch */
- protocol = pv[SND_PRO].ival;
- if (ptab[protocol].rpktlen > -1) /* copied from initproto() */
- urpsiz = ptab[protocol].rpktlen;
- if (ptab[protocol].spktflg > -1)
- spsizf = ptab[protocol].spktflg;
- if (ptab[protocol].spktlen > -1) {
- spsiz = ptab[protocol].spktlen;
- if (spsizf)
- spsizr = spmax = spsiz;
- }
- if (ptab[protocol].winsize > -1)
- wslotr = ptab[protocol].winsize;
- if (ptab[protocol].prefix > -1)
- prefixing = ptab[protocol].prefix;
- if (ptab[protocol].fnca > -1)
- fncact = ptab[protocol].fnca;
- if (ptab[protocol].fncn > -1)
- fncnv = ptab[protocol].fncn;
- if (ptab[protocol].fnsp > -1)
- fnspath = ptab[protocol].fnsp;
- if (ptab[protocol].fnrp > -1)
- fnrpath = ptab[protocol].fnrp;
- }
- debug(F101,"xget protocol","",protocol);
- debug(F111,"xget cmarg2",cmarg2,xfermode);
-
- g_xfermode = xfermode;
- g_binary = binary;
- if (pv[SND_BIN].ival > 0) { /* Change according to switch */
- xfermode = XMODE_M;
- binary = XYFT_B; /* FILE TYPE BINARY */
- omode = GMOD_BIN; /* O-Packet mode */
- debug(F101,"doxget /BINARY xfermode","",xfermode);
- } else if (pv[SND_TXT].ival > 0) { /* Ditto for /TEXT */
- xfermode = XMODE_M;
- binary = XYFT_T;
- omode = GMOD_TXT;
- debug(F101,"doxget /TEXT xfermode","",xfermode);
- } else if (pv[SND_IMG].ival > 0) {
- xfermode = XMODE_M;
-#ifdef VMS
- binary = XYFT_I;
-#else
- binary = XYFT_B;
-#endif /* VMS */
- omode = GMOD_TXT;
- debug(F101,"doxget /IMAGE xfermode","",xfermode);
- }
-#ifdef CK_LABELED
- else if (pv[SND_LBL].ival > 0) {
- xfermode = XMODE_M;
- binary = XYFT_L;
- omode = GMOD_LBL;
- debug(F101,"doxget /LABELED xfermode","",xfermode);
- }
-#endif /* CK_LABELED */
- debug(F101,"xget binary","",binary);
- debug(F101,"xget omode","",omode);
-
- if (pv[SND_XPA].ival > 0) /* /TRANSPARENT */
- xfrxla = 0; /* Don't translate character sets */
-
-#ifdef PIPESEND
- if (pv[SND_FLT].ival > 0)
- makestr(&rcvfilter,pv[SND_FLT].sval);
-#endif /* PIPESEND */
-
-#ifdef CK_TMPDIR
- if (pv[SND_MOV].ival > 0) {
- int len;
- char * p = pv[SND_MOV].sval;
-#ifdef CK_LOGIN
- if (isguest) {
- printf("?Sorry, /MOVE-TO not available to guests\n");
- x = -9;
- goto xgetx;
- }
-#endif /* CK_LOGIN */
- len = strlen(p);
- if (!isdir(p)) { /* Check directory */
-#ifdef CK_MKDIR
- char * s = NULL;
- s = (char *)malloc(len + 4);
- if (s) {
- strcpy(s,p); /* safe */
-#ifdef datageneral
- if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
-#else
- if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
-#endif /* datageneral */
- s[len++] = 'X';
- s[len] = NUL;
- x = zmkdir(s);
- free(s);
- if (x < 0) {
- printf("?Can't create \"%s\"\n",p);
- x = -9;
- goto xgetx;
- }
- }
-#else
- printf("?Directory \"%s\" not found\n",p);
- x = -9;
- goto xgetx;
-#endif /* CK_MKDIR */
- }
- zfnqfp(p,LINBUFSIZ,line);
- makestr(&rcv_move,line);
- }
-#endif /* CK_TMPDIR */
-
- if (pv[SND_REN].ival > 0) { /* /RENAME-TO:name */
- char * p = pv[SND_REN].sval;
-#ifdef CK_LOGIN
- if (isguest) {
- printf("?Sorry, /RENAME-TO not available to guests\n");
- x = -9;
- goto xgetx;
- }
-#endif /* CK_LOGIN */
- if (!p) p = "";
- if (!*p) {
- printf("?New name required for /RENAME\n");
- x = -9;
- goto xgetx;
- }
- p = brstrip(p);
- makestr(&rcv_rename,p);
- debug(F110,"xget rcv_rename","",0);
- }
-
-#ifdef CALIBRATE
- if (pv[SND_CAL].ival > 0)
- calibrate = (CK_OFF_T)1;
-#endif /* CALIBRATE */
- g_displa = fdispla;
- if (pv[SND_SHH].ival > 0)
- fdispla = 0;
- debug(F101,"xget display","",fdispla);
-
- if (pv[SND_NAM].ival > -1) { /* /FILENAMES */
- g_fncnv = fncnv; /* Save global value */
- fncnv = pv[SND_NAM].ival;
- debug(F101,"xsend fncnv","",fncnv);
- /* We should also handle O packet filename option here */
- /* but we don't really need to since WHATAMI already handles it */
- }
- if (pv[SND_PTH].ival > -1) { /* PATHNAMES */
- g_rpath = fnrpath; /* Save global values */
- fnrpath = pv[SND_PTH].ival;
- debug(F101,"xsend fnrpath","",fnrpath);
-#ifndef NZLTOR
- if (fnrpath != PATH_OFF) {
- g_fncnv = fncnv;
- fncnv = XYFN_L;
- debug(F101,"xsend fncnv","",fncnv);
- }
- /* We should also handle O packet pathname option here */
- /* but we don't really need to since WHATAMI already handles it */
-#endif /* NZLTOR */
- }
-
- /* Set protocol start state */
-
- if (opkt) { /* Extended GET Options*/
- sstate = (CHAR) 'o';
- oopts = 0;
- if (pv[SND_DEL].ival > 0) oopts |= GOPT_DEL; /* GET /DELETE */
- if (pv[SND_RES].ival > 0) oopts |= GOPT_RES; /* GET /RECOVER */
- if (pv[SND_REC].ival > 0) oopts |= GOPT_REC; /* GET /RECURSIVE */
- } else if (rcvcmd)
- sstate = (CHAR) 'v'; /* RECEIVE or CRECEIVE */
- else if (pv[SND_DEL].ival > 0)
- sstate = (CHAR) 'h'; /* GET /DELETE (= RETRIEVE) */
- else if (pv[SND_RES].ival > 0)
- sstate = (CHAR) 'j'; /* GET /RECOVER (= REGET) */
- else
- sstate = (CHAR) 'r'; /* Regular GET */
- getcmd = 1;
- debug(F000,"xget sstate","",sstate);
-#ifdef MAC
- what = W_RECV;
- scrcreate();
-#endif /* MAC */
- if (local) {
- if (pv[SND_SHH].ival != 0)
- displa = 1;
- if (protocol == PROTO_K) /* fdc 20070108 */
- ttflui();
- }
- x = 0;
-#ifdef PIPESEND
- if (pipesend)
- goto xgetx;
-#endif /* PIPESEND */
-
-#ifdef CK_TMPDIR
-/*
- cmarg2 is also allowed to be a device or directory name;
- even the name of a directory that doesn't exist.
-*/
- y = strlen(cmarg2);
- debug(F111,"xget strlen(cmarg2)",cmarg2,y);
- if ((y > 0) &&
-#ifdef OS2
- ((isalpha(cmarg2[0]) &&
- cmarg2[1] == ':' &&
- cmarg2[2] == NUL) ||
- (cmarg[y-1] == '/' || cmarg[y-1] == '\\') ||
- isdir(cmarg2))
-#else
-#ifdef UNIXOROSK
- (cmarg2[y-1] == '/' || isdir(cmarg2))
-#else
-#ifdef VMS
- (cmarg2[y-1] == ']' || cmarg2[y-1] == '>' || isdir(cmarg2))
-#else
-#ifdef STRATUS
- (cmarg2[y-1] == '>' || isdir(cmarg2))
-#else
-#ifdef datageneral
- (cmarg2[y-1] == ':' || cmarg[0] == ':' || isdir(cmarg2))
-#else
- isdir(cmarg2)
-#endif /* datageneral */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* UNIXOROSK */
-#endif /* OS2 */
- ) {
- debug(F110,"doxget RECEIVE cmarg2 disk or dir",cmarg2,0);
- if (!f_tmpdir) {
- int x;
- s = zgtdir();
- if (s) {
- ckstrncpy(savdir,s,TMPDIRLEN); /* remember old disk/dir */
- f_tmpdir = 1; /* and that we did this */
- } else {
- printf("?Can't get current directory\n");
- cmarg2 = "";
- f_tmpdir = 0;
- x = -9;
- goto xgetx;
- }
-#ifdef CK_MKDIR
- x = zchki(cmarg2); /* Does as-name exist? */
- if (x == -1) { /* Doesn't exist */
- char * p = NULL; /* Try to create it */
- x = strlen(cmarg2);
- if ((p = (char *)malloc(x+4))) {
- sprintf(p,"%s%s",cmarg2,"x.x"); /* SAFE (prechecked) */
- x = zmkdir(p);
- free(p);
- if (x < 0) {
- printf("?Can't create %s\n",cmarg2);
- x = -9;
- goto xgetx;
- }
- }
- }
-#endif /* CK_MKDIR */
- if (!zchdir(cmarg2)) { /* change to given disk/directory, */
- printf("?Can't access %s\n",cmarg2);
- x = -9;
- goto xgetx;
- }
- cmarg2 = "";
- }
- }
-#endif /* CK_TMPDIR */
-
- ckstrncpy(fspec,cmarg,CKMAXPATH); /* Note - this is a REMOTE filespec */
- debug(F111,"xget fspec",fspec,fspeclen);
- debug(F110,"xget cmarg2",cmarg2,0);
-
- xgetx:
- for (i = 0; i < SND_MAX; i++)
- if (pv[i].sval)
- free(pv[i].sval);
- return(x);
-}
-#endif /* NOXFER */
-
-#ifndef NOSPL
-
-/*
- D O G T A -- Do _GETARGS or _PUTARGS Command.
-
- Used by XIF, FOR, WHILE, and SWITCH, each of which are implemented as
- 2-level macros; the first level defines the macro, the second runs it.
- This routine hides the fact that they are macros by importing the
- macro arguments (if any) from two levels up, to make them available
- in the IF, FOR, SWITCH, and WHILE commands themselves; for example as
- loop indices, etc, and within the IF/FOR/WHILE/SWITCH body itself.
- _PUTARGS is in case we changed any of these variables or used SHIFT
- on them, so the new values won't be lost as we pop up the stack.
-*/
-int
-dogta(cx) int cx; {
- int i, n;
- char c, *p, mbuf[4];
- extern int topargc, cmdint;
- extern char ** topxarg;
-
- if ((y = cmcfm()) < 0)
- return(y);
- debug(F101,"dogta cx","",cx);
- debug(F101,"dogta maclvl","",maclvl);
- if (cx == XXGTA) {
- debug(F101,"dogta _GETARGS maclvl","",maclvl);
- } else if (cx == XXPTA) {
- debug(F101,"dogta _PUTARGS maclvl","",maclvl);
- } else {
- return(-2);
- }
- if (maclvl < 1)
- return(success = 0);
-
- /* Make new copies of macro arguments /%0..9 */
-
- mbuf[0] = '%'; mbuf[1] = '0'; mbuf[2] = NUL; /* Argument name buf */
-
- if (cx == XXPTA) { /* Go NOINT because _PUTARGS */
- if (cmdint) /* temporarily changes maclvl. */
- connoi(); /* Interrupts OFF. */
- }
- for (i = 0; i < 10; i++) { /* For all args */
- c = (char) (i + '0'); /* Make name */
- mbuf[1] = (char) c; /* Insert digit */
- if (cx == XXGTA) { /* Get arg from level-minus-2 */
- if (maclvl == 1) p = g_var[c]; /* If at level 1 use globals 0..9 */
- else p = m_arg[maclvl-2][i]; /* Otherwise they're on the stack */
- addmac(mbuf,p);
-#ifdef COMMENT
- if (maclvl > 1)
- makestr(&(m_line[maclvl]),m_line[maclvl-2]);
-#endif /* COMMENT */
- } else if (cx == XXPTA) { /* Put args level+2 */
- maclvl -= 2; /* This is gross, it's because we're */
- addmac(mbuf,m_arg[maclvl+2][i]); /* adding macros two levels up */
- maclvl += 2; /* and addmac() uses maclvl. */
- count[cmdlvl - 2] = count[cmdlvl];
- intime[cmdlvl - 2] = intime[cmdlvl];
- inpcas[cmdlvl - 2] = inpcas[cmdlvl];
- takerr[cmdlvl - 2] = takerr[cmdlvl];
- merror[cmdlvl - 2] = merror[cmdlvl];
- xquiet[cmdlvl - 2] = xquiet[cmdlvl];
- xvarev[cmdlvl - 2] = xvarev[cmdlvl];
- } else return(success = 0); /* Bad call to this routine */
- }
- if (cx == XXPTA) { /* Restore interrupts if we */
- if (cmdint) /* turned them off above. */
- conint(trap,stptrap);
- }
- /* Now take care of the argument vector array \&_[], \v(return), */
- /* and \v(argc) by just copying the pointers. */
-
- if (cx == XXGTA) { /* GETARGS from 2 levels up */
- if (maclvl == 1) {
- a_ptr[0] = topxarg; /* \&_[] array */
- a_dim[0] = topargc - 1; /* Dimension doesn't include [0] */
- m_xarg[maclvl] = topxarg;
- n_xarg[maclvl] = topargc; /* But \v(argc) does include \%0 */
- macargc[maclvl] = topargc;
- makestr(&(mrval[maclvl+1]),mrval[0]); /* (see vnlook()) */
- } else {
- a_ptr[0] = m_xarg[maclvl-2];
- a_dim[0] = n_xarg[maclvl-2];
- m_xarg[maclvl] = m_xarg[maclvl-2];
- n_xarg[maclvl] = n_xarg[maclvl-2];
- macargc[maclvl] = n_xarg[maclvl-2];
- makestr(&(mrval[maclvl+1]),mrval[maclvl-1]); /* (see vnlook()) */
-
- }
- } else { /* PUTARGS 2 levels up */
- if (maclvl > 1) {
- a_ptr[0] = m_xarg[maclvl];
- m_xarg[maclvl-2] = m_xarg[maclvl];
- a_dim[0] = n_xarg[maclvl];
- n_xarg[maclvl-2] = n_xarg[maclvl];
- macargc[maclvl-2] = n_xarg[maclvl];
- }
- }
- return(1); /* Internal command - don't change success */
-}
-#endif /* NOSPL */
-
-#ifndef NOSPL
-/*
- Do the GOTO and [_]FORWARD commands.
- s = Label to search for, cx = function code: XXGOTO, XXFWD, or XXXFWD.
-*/
-
-int
-dogoto(s, cx) char *s; int cx; {
- int i, j, x, y, z, bc;
- int empty = 0, stopflg = 0;
- char * cmd; /* Name of this command */
- char tmplbl[LBLSIZ+1], *lp; /* Current label from command stream */
- char tmp2[LBLSIZ+1]; /* SWITCH label conversion buffer */
- char tmp3[LBLSIZ+1]; /* Target label */
-
- stopflg = (cx == XXXFWD); /* _FORWARD (used in SWITCH) */
- bc = 0; /* Brace counter */
-
- cmd = (cx == XXGOTO) ? "GOTO" : ((cx == XXFWD) ? "FORWARD" : "_FORWARD");
- if (!s) s = "";
- if (!*s) empty = 1;
-
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"GOTO command",cmd,cx);
- debug(F101,"GOTO cmdlvl","",cmdlvl);
- debug(F101,"GOTO maclvl","",maclvl);
- debug(F101,"GOTO tlevel","",tlevel);
- debug(F111,"GOTO target",s,empty);
- }
-#endif /* DEBUG */
- debug(F110,cmd,s,0);
- x = ckstrncpy(tmp3+1,s,LBLSIZ);
- debug(F101,"GOTO target len","",x);
- debug(F101,"GOTO target at x","",s[x]);
- if (s[x]) {
- debug(F100,"GOTO target overflow","",0);
- printf("?GOTO target or SWITCH case label too long\n");
- if (stopflg) dostop(); /* If in SWITCH return to prompt */
- return(success = 0);
- }
- s = tmp3+1;
- if (*s != ':') { /* Make copy of label */
- tmp3[0] = ':'; /* guaranteed to start with ":" */
- s--;
- }
- if (!stopflg && !empty) {
- if (s[1] == '.' || s[1] == SP || s[1] == NUL) {
- printf("?Bad label syntax - '%s'\n",s);
- if (stopflg) dostop(); /* If in SWITCH return to prompt */
- return(success = 0);
- }
- }
- if (cmdlvl == 0) {
- printf("?Sorry, %s only works in a command file or macro\n",cmd);
- return(success = 0);
- }
- y = strlen(s); /* y = length of target label */
- debug(F111,cmd,s,y);
-
- while (cmdlvl > 0) { /* As long as not at top level... */
- if (cmdstk[cmdlvl].src == CMD_MD) { /* GOTO inside macro */
- int i, m, flag;
- char *xp, *tp;
-
- /* GOTO: rewind the macro; FORWARD: start at current position */
-
- lp = (cx == XXGOTO) ? macx[maclvl] : macp[maclvl];
- m = (int)strlen(lp);
- debug(F111,"GOTO in macro",lp,m);
-
- flag = 1; /* flag for valid label position */
- for (i = 0; i < m; i++,lp++) { /* search for label in macro body */
- if (*lp == '{') /* But only at this level */
- bc++; /* Anything inside braces is off */
- else if (*lp == '}') /* limits. */
- bc--;
- if (stopflg && bc > 0) /* This is good for SWITCH */
- continue; /* but interferes with WHILE, etc. */
- if (*lp == ',') {
- flag = 1;
- continue;
- }
- if (flag) { /* If in valid label position */
- if (*lp == SP) /* eat leading spaces */
- continue;
- if (*lp != ':') { /* Look for label introducer */
- flag = 0; /* this isn't it */
- continue; /* keep looking */
- }
- }
- if (!flag) /* We don't have a label */
- continue; /* so keep looking... */
- xp = lp; tp = tmplbl; /* Copy the label from the macro */
- j = 0; /* to make it null-terminated */
- while ((*tp = *xp)) {
- if (j++ > LBLSIZ-1) { /* j = length of word from macro */
- printf("?GOTO target or SWITCH case label too long\n");
- if (stopflg) dostop(); /* Return to prompt */
- return(success = 0);
- }
- if (!*tp || *tp == ',') /* Look for end of word */
- break;
- else tp++, xp++; /* Next character */
- }
- *tp = NUL; /* In case we stopped early */
- /* Now do caseless string comparison, using longest length */
- debug(F111,"macro GOTO label",s,y);
- debug(F111,"macro target label",tmplbl,j);
- if (stopflg) { /* Allow variables as SWITCH labels */
- int n = LBLSIZ - 1;
- char * p = tmp2;
- zzstring(tmplbl,&p,&n);
- if (n < 0) {
- printf("?GOTO target or SWITCH case label too long\n");
- if (stopflg) dostop(); /* Return to prompt */
- return(0);
- }
- ckstrncpy(tmplbl,tmp2,LBLSIZ);
- }
- debug(F111,"GOTO s",s,y);
- debug(F111,"GOTO tmplbl",tmplbl,j);
- debug(F111,"GOTO empty",ckitoa(stopflg),empty);
-
- if (empty) { /* Empty target */
- z = (!strcmp(s,":") && /* String is empty */
- /* and Label is ":" or ":*"... */
- (!strcmp(tmplbl,":") || !strcmp(tmplbl,":*")))
- ? 0 : 1;
- debug(F111,"GOTO","A",z);
- } else if (stopflg) {
- z = ckmatch(tmplbl,s,inpcas[cmdlvl],1) ? 0 : 1;
- debug(F111,"GOTO","B",z);
- } else {
- z = (stopflg && inpcas[cmdlvl]) ?
- strcmp(s,tmplbl) :
- ckstrcmp(s,tmplbl,(y > j) ? y : j, 0);
- debug(F111,"GOTO","C",z);
- }
- if (!z) {
- break;
- } else if (stopflg &&
- !ckstrcmp(":default",tmplbl,(8 > j) ? 8 : j, 0)) {
- debug(F100,"GOTO DEFAULT","",0);
- break;
- } else {
- flag = 0;
- }
- }
- debug(F111,"GOTO macro i",cmd,i);
- debug(F111,"GOTO macro m",cmd,m);
- if (i >= m) { /* Didn't find the label */
- debug(F101,"GOTO failed cmdlvl","",cmdlvl);
-#ifdef COMMENT
- /* MOVED TO AFTER POPCLVL ABOUT 20 LINES DOWN 5 AUG 2002 */
- if (stopflg)
- return(0);
-#endif /* COMMENT */
- if ((maclvl > 0) &&
- (m_arg[maclvl-1][0]) &&
- (cmdstk[cmdlvl].src == CMD_MD) &&
- (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
- !strncmp(m_arg[maclvl-1][0],"_for",4) ||
- !strncmp(m_arg[maclvl-1][0],"_swi",4) ||
- !strncmp(m_arg[maclvl-1][0],"_whi",4))) {
- dogta(XXPTA); /* Restore args */
- debug(F101,"GOTO in XIF/FOR/WHI/SWI popping","",cmdlvl);
- popclvl(); /* Pop an extra level */
- }
- debug(F101,"GOTO popping","",cmdlvl);
- if (!popclvl()) { /* pop up to next higher level */
- printf("?Label '%s' not found\n",s); /* if none */
- return(0); /* Quit */
- } else if (stopflg) { /* SWITCH no case label match */
- return(0); /* and no DEFAULT lable. */
- } else {
- continue; /* otherwise look again */
- }
- }
- debug(F110,"GOTO found macro label",tmplbl,0);
- macp[maclvl] = lp; /* set macro buffer pointer */
- return(1);
- } else if (cmdstk[cmdlvl].src == CMD_TF) {
- x = 0; /* GOTO issued in take file */
- debug(F111,"GOTO in TAKE file",cmd,cx);
- if (cx == XXGOTO) { /* If GOTO, but not FORWARD, */
- rewind(tfile[tlevel]); /* search file from beginning */
- tfline[tlevel] = 0;
- }
- while (! feof(tfile[tlevel])) {
-#ifdef COMMENT
-/* This is wrong - it lets us jump to labels inside inferior blocks */
- tfline[tlevel]++;
- if (fgets(line,LINBUFSIZ,tfile[tlevel]) == NULL) /* Get line */
-#else
- if (getnct(line,LINBUFSIZ,tfile[tlevel],0) < 0)
-#endif /* COMMENT */
- break; /* If no more, done, label not found */
- lp = line; /* Got line */
- while (*lp == SP || *lp == HT)
- lp++; /* Strip leading whitespace */
- if (*lp != ':') continue; /* Check for label introducer */
- while (*(lp+1) == SP) { /* Remove space between : and name */
- *(lp+1) = ':';
- lp++; /* Strip leading whitespace */
- }
- tp = lp; /* Get end of word */
- j = 0;
- while (*tp) { /* And null-terminate it */
- if (*tp < 33) {
- *tp = NUL;
- break;
- } else tp++, j++;
- }
- if (!ckstrcmp(lp,s,(y > j) ? y : j,0)) { /* Caseless compare */
- x = 1; /* Got it */
- break; /* done. */
- } else if (stopflg &&
- !ckstrcmp(":default",tmplbl,(8 > j) ? 8 : j,0)) {
- x = 1;
- break;
- }
- }
- if (x == 0) { /* If not found, print message */
- debug(F101,"GOTO failed at cmdlvl","",cmdlvl);
- if (stopflg)
- return(0);
- if (!popclvl()) { /* pop up to next higher level */
- printf("?Label '%s' not found\n",s); /* if none */
- return(0); /* quit */
- } else continue; /* otherwise look again */
- }
- return(x); /* Send back return code */
- }
- }
- printf("?Stack problem in GOTO %s\n",s); /* Shouldn't see this */
- return(0);
-}
-#endif /* NOSPL */
-
-/* Finish parsing and do the IF, XIF, and WHILE commands */
-
-#ifndef NOSPL
-
-/* C H K V A R -- Check (if it's a) Variable */
-
-
-#ifdef OLDCHKVAR
-/*
- Crude and disgusting, but needed for OS/2, DOS, and Windows, where filenames
- have backslashes in them. How do we know if a backslash in a filename is a
- directory separator, or if it's a Kermit backslash? This routine does a
- rough syntax check of the next few characters and if it looks like it MIGHT
- be a variable, then it tries to evaluate it, and if the result is not empty,
- we say it's a variable, although sometimes it might not be -- some cases are
- truly ambiguous. For example there might a DOS directory called \%a, and
- we also have a variable with the same name. This is all for the sake of not
- having to tell PC users that they have to double all backslashes in file
- and directory names.
-*/
-#else
-/*
- Somewhat less crude & disgusting. The previous method was nondeterministic
- and (worse) it interfered with macro argument passing. So now we only
- check the syntax of backslash-items to see if they are variables, but we
- do NOT check their values.
-*/
-#endif /* OLDCHKVAR */
-/*
- Call with a string pointer pointing at the backslash of the purported
- variable. Returns 1 if it has the syntax of a variable, 0 if not.
-*/
-int
-chkvar(s) char *s; {
- int z = 0; /* Return code - assume failure. */
- if (!s) s = ""; /* Watch our for null pointers. */
- if (!*s) return(0); /* Empty arg so not a variable. */
- if (*s == CMDQ) { /* Object begins with backslash. */
- char c;
- c = s[1]; /* Character following backslash. */
- if (c) {
- int t = 0;
- if (c == CMDQ) /* Quoted backslash */
- return(1);
- c = (char) (islower(c) ? toupper(c) : c); /* Otherwise... */
- if (c == '%') { /* Simple variable */
-#ifdef OLDCHKVAR
- t = 1;
-#else
- return(1);
-#endif /* OLDCHKVAR */
- } else if (c == '&') { /* Array */
- if (!s[2]) return(0);
- if (s[3] == '[')
- t = ckindex("]",s,4,0,1);
-#ifndef OLDCHKVAR
- return((t > 0) ? 1 : 0);
-#endif /* OLDCHKVAR */
- } else if (c == '$' || /* Environment variable */
- c == 'V' || /* Built-in variable */
- c == 'M') { /* Macro name */
- t = (s[2] == '(');
-#ifndef OLDCHKVAR
- return((t > 0) ? 1 : 0);
-#endif /* OLDCHKVAR */
- } else if (c == 'F') { /* Function reference */
- /* Don't actually call it - it might have side effects */
- int x;
- if ((x = ckindex("(",s,3,0,1))) /* Just check syntax */
- if ((x = ckindex(")",s,x,0,1)))
- z = 1;
- /* Insert a better syntax check here if necessary */
- }
-#ifdef OLDCHKVAR
- if (t) {
- t = 255; /* This lets us test \v(xxx) */
- lp = line; /* and even \f...(xxx) */
- zzstring(s,&lp,&t); /* Evaluate it, whatever it is. */
- t = strlen(line); /* Get its length. */
- debug(F111,"chkvar",line,t);
- z = t > 0; /* If length > 0, it's defined */
- }
-#endif /* OLDCHKVAR */
- }
- }
- return(z);
-}
-
-/* B O O L E X P -- Evaluate a Boolean expression */
-
-#define BOOLLEN 1024
-static char boolval[BOOLLEN];
-
-int
-boolexp(cx) int cx; {
- int x, y, z; char *s, *p;
- int parens = 0, pcount = 0, ecount = 0;
- char *q, *bx;
- struct FDB kw, nu;
-#ifdef FNFLOAT
- struct FDB fl;
- CKFLOAT f1 = 0.0, f2 = 0.0;
- int f1flag = 0, f2flag = 0;
-#endif /* FNFLOAT */
-#ifdef OS2
- extern int keymac;
-#endif /* OS2 */
-
- not = 0; /* Flag for whether "NOT" was seen */
- z = 0; /* Initial IF condition */
- ifargs = 0; /* Count of IF condition words */
- bx = boolval; /* Initialize boolean value */
- *bx = NUL;
-
- ifagain:
- cmfdbi(&kw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Number, numeric-valued variable, Boolean expression, or keyword",
- "", /* default */
- "", /* addtl string data */
- nif, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 4 = silent */
- xxstring, /* Processing function */
- iftab, /* Keyword table */
- &nu /* Pointer to next FDB */
- );
- cmfdbi(&nu, /* 2nd FDB - An integer */
- _CMNUM, /* fcode */
- "", /* hlpmsg */
- "", /* Default */
- "", /* addtl string data */
- 0,
- 0,
- xxstring,
- NULL,
-#ifdef FNFLOAT
- &fl
-#else
- NULL
-#endif /* FNFLOAT */
- );
-#ifdef FNFLOAT
- cmfdbi(&fl, /* A floating-point number */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
-#endif /* FNFLOAT */
- x = cmfdb(&kw); /* Parse a keyword or a number */
- debug(F111,"boolval cmfdb","",x);
- if (x < 0) {
- if (x == -3)
- x = -2;
- return(x);
- }
- debug(F111,"boolval switch","",cmresult.fcode);
- switch (cmresult.fcode) { /* What did we get? */
- case _CMFLD: { /* A "field" */
- int i;
- char * s;
- s = cmresult.sresult;
-/*
- C-Kermit 9.0: This allows a macro name to serve as an
- IF condition without having to enclose it in \m(...).
-*/
- if (
-#ifdef FNFLOAT
- !isfloat(cmresult.sresult,0) /* Not a number */
-#else
- !chknum(cmresult.sresult) /* Not a number */
-#endif /* FNFLOAT */
- ) {
- i = mlook(mactab,cmresult.sresult,nmac); /* Look it up */
- if (i > -1) /* in the macro table */
- s = mactab[x].mval; /* and get its value */
- else /* Otherwise if no such macro */
- s = "0"; /* evaluate as FALSE. */
- }
-#ifdef FNFLOAT
- if (isfloat(s,0)) { /* A floating-point number? */
- f1 = floatval; /* Yes, get its value */
- f1flag = 1; /* remember we did this */
- ifc = 9999; /* Set special "if-code" */
- }
-#else
- if (chknum(s)) {
- cmresult.nresult = atoi(s);
- ifc = 9999;
- break;
- }
-#endif /* FNFLOAT */
- else
- return(-2);
- }
- case _CMNUM: /* A number... */
- ifc = 9999; /* Set special "if-code" */
- break;
- case _CMKEY: /* A keyword */
- ifc = cmresult.nresult; /* Get if-code */
- break;
- default:
- return(-2);
- }
- switch (ifc) { /* set z = 1 for true, 0 for false */
- case 9999: /* Number */
-#ifdef FNFLOAT
- if (f1flag) {
- z = (f1 == 0.0) ? 0 : 1;
- } else
-#endif /* FNFLOAT */
- z = (cmresult.nresult == 0) ? 0 : 1;
- break;
- case XXIFLP: /* Left paren */
- if (pcount == 0 && ifargs > 0)
- return(-2);
- parens = 1;
- pcount++;
- ifargs++;
- *bx++ = '(';
- goto ifagain;
- case XXIFRP: /* Right paren */
- if (!parens)
- return(-2);
- if (--pcount < 0)
- return(-2);
- ifargs++;
- *bx++ = ')';
- *bx = NUL;
- if (pcount == 0)
- goto ifend;
- goto ifagain;
- case XXIFAN: /* AND (&&) */
- ifargs++;
- if (!ecount)
- return(-2);
- *bx++ = '&';
- goto ifagain;
- case XXIFOR: /* OR (||) */
- ifargs++;
- if (!ecount)
- return(-2);
- *bx++ = '|';
- goto ifagain;
- case XXIFNO: /* IF NOT [ NOT [ NOT ... ] ] */
- if (bx > boolval) { /* evala() doesn't like cascaded */
- if (*(bx-1) == '!') { /* unary operators... */
- *(bx-1) = NUL; /* So here, two wrongs make a right. */
- bx--;
- } else {
- *bx++ = '!';
- }
- } else {
- *bx++ = '!';
- }
- ifargs++;
- goto ifagain;
- case XXIFTR: /* IF TRUE */
- z = 1;
- debug(F101,"if true","",z);
- ifargs += 1;
- break;
- case XXIFNT: /* IF FALSE */
- z = 0;
- debug(F101,"if true","",z);
- ifargs += 1;
- break;
- case XXIFSU: /* IF SUCCESS */
- z = ( success != 0 ) ? 1 : 0;
- debug(F101,"if success","",z);
- ifargs += 1;
- break;
- case XXIFFA: /* IF FAILURE */
- z = ( success == 0 ) ? 1 : 0;
- debug(F101,"if failure","",z);
- ifargs += 1;
- break;
-
- case XXIFDE: /* IF DEFINED */
- if ((x = cmfld("Macro or variable name","",&s,NULL)) < 0)
- return((x == -3) ? -2 : x);
-
- if (*s == CMDQ) {
- char * lp;
- char line[256];
- int t, x;
- if (*(s+1) == 'f' || *(s+1) == 'F') { /* Built-in function */
- extern struct keytab fnctab[];
- extern int nfuncs;
- ckstrncpy(line,s+2,256);
- if (line[0]) {
- lp = ckstrchr(line,'(');
- if (lp) *lp = NUL;
- x = lookup(fnctab,line,nfuncs,&t);
- z = x > -1;
- }
- debug(F111,"if defined function",line,z);
- } else if (*(s+1) == 'v' || *(s+1) == 'V') { /* 8.0.200 */
- extern struct keytab vartab[];
- extern int nvars;
- z = 0;
- if (*(s+2) == '(') {
- ckstrncpy(line,s+3,256);
- if (line[0]) {
- lp = ckstrchr(line,')');
- if (lp) *lp = NUL;
- x = lookup(vartab,line,nvars,&t);
- z = x > -1;
- if (z) { /* 8.0.203 */
- int t; /* It must have a value to succeed */
- t = 255; /* as in C-Kermit 6.0 and 7.0 */
- lp = line; /* (this was broken in 8.0.200-201) */
- zzstring(s,&lp,&t);
- t = strlen(line);
- z = line[0] ? 1 : 0;
- }
- }
- }
- debug(F111,"if defined variable",line,z);
- } else {
- z = chkvar(s); /* Starts with backslash */
- if (z > 0) { /* Yes... */
- t = 255; /* than buffer so if zzstring fails */
- lp = line; /* check for that -- overflow means */
- line[0] = NUL; /* the quantity is defined. */
- x = zzstring(s,&lp,&t);
- if ((x < 0 && t != 255) || !line[0])
- z = 0;
- debug(F111,"if defined zzstring",line,z);
- debug(F101,"if defined zzstring t","",t);
- }
- }
- } else {
- z = (mxlook(mactab,s,nmac) > -1); /* Look for exact match */
- }
- debug(F111,"if defined final",s,z);
- ifargs += 2;
- break;
-
- case XXIFDC: { /* IF DECLARED */
- char * lp;
- char line[32];
- int j, k, t, x;
- if ((x = cmfld("Array name","",&s,NULL)) < 0)
- return((x == -3) ? -2 : x);
- if (*s == CMDQ) {
- if (*(s+1) != '&') {
- t = 31;
- lp = line;
- line[0] = NUL;
- x = zzstring(s,&lp,&t);
- s = line;
- }
- }
- z = 0;
- if ((x = arraybounds(s,&j,&k)) > -1) {
- if (a_ptr[x]) {
- if (j < 1)
- z = 1;
- else if (j <= a_dim[x])
- z = 1;
- if (z == 1 && k > a_dim[x])
- z = 0;
- }
- }
- break;
- }
- case XXIFBG: /* IF BACKGROUND */
- case XXIFFG: /* IF FOREGROUND */
- bgchk(); /* Check background status */
- if (ifc == XXIFFG) /* Foreground */
- z = pflag ? 1 : 0;
- else z = pflag ? 0 : 1; /* Background */
- ifargs += 1;
- break;
-
- case XXIFCO: /* IF COUNT */
- z = ( --count[cmdlvl] > 0 );
- if (cx == XXWHI) count[cmdlvl] += 2; /* Don't ask... */
- debug(F101,"if count","",z);
- ifargs += 1;
- break;
-
- case XXIFEX: /* IF EXIST */
-#ifdef CK_TMPDIR
- case XXIFDI: /* IF DIRECTORY */
-#endif /* CK_TMPDIR */
- case XXIFAB: /* IF ABSOLUTE */
- case XXIFLN: /* IF LINK */
- if ((x = cmfld(
- ((ifc == XXIFDI) ? "Directory name" : "File"),
- "",&s,
-#ifdef OS2
- NULL /* This allows \'s in filenames */
-#else
- xxstring
-#endif /* OS2 */
- )) < 0) {
- if (x == -3) {
- extern int cmflgs;
- if (cmflgs == 1) {
- printf("?File or directory name required\n");
- return(-9);
- }
- } else return(x);
- }
- s = brstrip(s);
-#ifdef UNIX
- if (ifc == XXIFLN) {
- z = isalink(s);
- } else
-#endif /* UNIX */
- if (ifc == XXIFAB) {
- z = isabsolute(s);
- } else if (ifc == XXIFEX) {
- z = (zgetfs(s) > -1L);
- debug(F101,"if exist 1","",z);
-#ifdef OS2
- if (!z) { /* File not found. */
- int t; /* Try expanding variables */
- t = LINBUFSIZ-1; /* and looking again. */
- lp = line;
- zzstring(s,&lp,&t);
- s = line;
- z = ( zchki(s) > -1L );
- debug(F101,"if exist 2","",z);
- }
-#endif /* OS2 */
-#ifdef CK_TMPDIR
- } else {
-#ifdef VMS
- z = (zchki(s) == -2)
-#else
-/* Because this doesn't catch $DISK1:[FOO]BLAH.DIR;1 */
- z = isdir(s)
-#ifdef OS2
- || (isalpha(s[0]) && s[1] == ':' && s[2] == NUL)
-#endif /* OS2 */
-#endif /* VMS */
- ;
- debug(F101,"if directory 1","",z);
-
- if (!z) { /* File not found. */
- int t; /* Try expanding variables */
- t = LINBUFSIZ-1; /* and looking again. */
- lp = line;
- zzstring(s,&lp,&t);
- s = line;
- z = isdir(s)
-#ifdef OS2
- || (isalpha(s[0]) && s[1] == ':' && s[2] == NUL)
-#endif /* OS2 */
- ;
- debug(F101,"if directory 2","",z);
- }
-#endif /* CK_TMPDIR */
- }
- ifargs += 2;
- break;
-
- case XXIFEQ: /* IF EQUAL (string comparison) */
- case XXIFLL: /* IF Lexically Less Than */
- case XXIFLG: /* If Lexically Greater Than */
- if ((x = cmfld("first word or variable name","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Text required\n");
- return(-9);
- } else return(x);
- }
- s = brstrip(s); /* Strip braces */
- x = (int)strlen(s);
- if (x > LINBUFSIZ-1) {
- printf("?IF: strings too long\n");
- return(-2);
- }
- lp = line; /* lp points to first string */
- ckstrncpy(line,s,LINBUFSIZ);
- if ((y = cmfld("second word or variable name","",&s,xxstring)) < 0) {
- if (y == -3) {
- printf("?Text required\n");
- return(-9);
- } else return(y);
- }
- s = brstrip(s);
- y = (int)strlen(s);
- if (x + y + 2 > LINBUFSIZ) {
- printf("?IF: strings too long\n");
- return(-2);
- }
- tp = lp + x + 2; /* tp points to second string */
- strcpy(tp,s); /* safe (checked) */
- x = ckstrcmp(lp,tp,-1,inpcas[cmdlvl]); /* Use longest length */
- switch (ifc) {
- case XXIFEQ: /* IF EQUAL (string comparison) */
- z = (x == 0);
- break;
- case XXIFLL: /* IF Lexically Less Than */
- z = (x < 0);
- break;
- case XXIFLG: /* If Lexically Greater Than */
- z = (x > 0);
- break;
- }
- debug(F101,"IF EQ result","",z);
- ifargs += 3;
- break;
-
- case XXIFVE: /* IF VERSION */
- case XXIFAE: /* IF (arithmetically) = */
- case XXIFNQ: /* IF != (not arithmetically equal) */
- case XXIFLT: /* IF < */
- case XXIFLE: /* IF <= */
- case XXIFGE: /* IF >= */
- case XXIFGT: { /* IF > */
-
- /* July 2006 - converted to use CK_OFF_T rather than int to */
- /* allow long integers on platforms that have ck_off_t > 32 bits */
- int xx;
- CK_OFF_T n1 = (CK_OFF_T)0, n2 = (CK_OFF_T)0;
- if (ifc == XXIFVE) {
- n1 = (CK_OFF_T) vernum;
- } else {
- x = cmfld("first number or variable name","",&s,xxstring);
- if (x == -3) {
- printf("?Quantity required\n");
- return(-9);
- }
- if (x < 0) return(x);
- debug(F101,"xxifgt cmfld","",x);
- ckstrncpy(line,s,LINBUFSIZ);
- lp = brstrip(line);
- debug(F110,"xxifgt exp1",lp,0);
-
-/* The following bit is for compatibility with old versions of MS-DOS Kermit */
-
- if (!ckstrcmp(lp,"count",5,0)) {
- n1 = (CK_OFF_T)count[cmdlvl];
- } else if (!ckstrcmp(lp,"version",7,0)) {
- n1 = (CK_OFF_T) vernum;
- } else if (!ckstrcmp(lp,"argc",4,0)) {
- n1 = (CK_OFF_T) macargc[maclvl];
- } else {
-
-/* End of compatibility bit */
-
-#ifdef FNFLOAT
- if (isfloat(lp,0) > 1) { /* Allow floating-point comparisons */
- f1 = floatval;
- f1flag = 1;
- } else
-#endif /* FNFLOAT */
- if (chknum(lp)) {
- n1 = ckatofs(lp);
- } else { /* Check for arithmetic expression */
- q = evala(lp); /* cmnum() does this but ... */
- if (chknum(q)) { /* we're not using cmnum(). */
- n1 = ckatofs(q);
- } else {
- printf("?Value not numeric - %s", lp);
- return(-9);
- }
- }
- }
- }
- y = cmfld("number or variable name","",&s,xxstring);
- if (y == -3) {
- printf("?Quantity required\n");
- return(-9);
- }
- if (y < 0) return(y);
- s = brstrip(s);
- if (!*s) return(-2);
- if (ifc == XXIFVE) {
- tp = line;
- } else {
- x = (int)strlen(lp);
- tp = line + x + 2;
- }
- ckstrncpy(tp,s,LINBUFSIZ-x-2);
- debug(F110,"xxifgt exp2",tp,0);
- if (!ckstrcmp(tp,"count",5,0)) {
- n2 = (CK_OFF_T) count[cmdlvl];
- } else if (!ckstrcmp(tp,"version",7,0)) {
- n2 = (CK_OFF_T) vernum;
- } else if (!ckstrcmp(tp,"argc",4,0)) {
- n2 = (CK_OFF_T) macargc[maclvl];
- } else {
-#ifdef FNFLOAT
- if (isfloat(tp,0) > 1) {
- f2 = floatval;
- f2flag = 1;
- } else
-#endif /* FNFLOAT */
- if (chknum(tp)) {
- n2 = ckatofs(tp);
- } else {
- q = evala(tp);
- if (chknum(q)) { /* we're not using cmnum(). */
- n2 = ckatofs(q);
- } else {
- printf("?Value not numeric - %s", tp);
- return(-9);
- }
- }
- }
- xx = (ifc == XXIFVE) ? XXIFGE : ifc;
-
-#ifdef FNFLOAT
- if (f1flag && !f2flag) {
- f2 = (CKFLOAT)n2;
- f2flag = 1;
- }
- if (f2flag && !f1flag)
- f1 = (CKFLOAT)n1;
- if (f1flag)
- z = ((f1 < f2 && xx == XXIFLT)
- || (f1 != f2 && xx == XXIFNQ)
- || (f1 <= f2 && xx == XXIFLE)
- || (f1 == f2 && xx == XXIFAE)
- || (f1 >= f2 && xx == XXIFGE)
- || (f1 > f2 && xx == XXIFGT));
- else
-#endif /* FNFLOAT */
- z = ((n1 < n2 && xx == XXIFLT)
- || (n1 != n2 && xx == XXIFNQ)
- || (n1 <= n2 && xx == XXIFLE)
- || (n1 == n2 && xx == XXIFAE)
- || (n1 >= n2 && xx == XXIFGE)
- || (n1 > n2 && xx == XXIFGT));
- debug(F101,"xxifge z","",z);
- if (ifc == XXIFVE)
- ifargs += 2;
- else
- ifargs += 3;
- break;
- }
-
- case XXIFNU: /* IF NUMERIC */
- x = cmfld("variable name or constant","",&s,NULL);
- if (x == -3) {
- extern int cmflgs;
- if (cmflgs == 1) {
- printf("?Quantity required\n");
- return(-9);
- }
- } else if (x < 0)
- return(x);
- x = LINBUFSIZ-1;
- lp = line;
- zzstring(s,&lp,&x);
- lp = line;
- debug(F110,"xxifnu quantity",lp,0);
- z = chknum(lp);
-#ifdef COMMENT
-/*
- This works, but it's not wise -- IF NUMERIC is mostly used to see if a
- string really does contain only numeric characters. If they want to force
- evaluation, they can use \feval() on the argument string.
-*/
- if (!z) { /* Not a number */
- x_ifnum = 1; /* Avoid "eval" error messages */
- q = evala(lp); /* Maybe it's an expression */
- z = chknum(q); /* that evaluates to a number */
- x_ifnum = 0; /* Put eval messages back to normal */
- if (z) debug(F110,"xxifnu exp",lp,0);
- }
-#endif /* COMMENT */
- debug(F101,"xxifnu chknum","",z);
- ifargs += 2;
- break;
-
-#ifdef ZFCDAT
- case XXIFNE: { /* IF NEWER */
- char d1[20], * d2; /* Buffers for 2 dates */
- if ((z = cmifi("First file","",&s,&y,xxstring)) < 0)
- return(z);
- ckstrncpy(d1,zfcdat(s),20);
- if ((z = cmifi("Second file","",&s,&y,xxstring)) < 0)
- return(z);
- d2 = zfcdat(s);
- if ((int)strlen(d1) != 17 || (int)strlen(d2) != 17) {
- printf("?Failure to get file date\n");
- return(-9);
- }
- debug(F110,"xxifnewer d1",d1,0);
- debug(F110,"xxifnewer d2",d2,0);
- z = (strcmp(d1,d2) > 0) ? 1 : 0;
- debug(F101,"xxifnewer","",z);
- ifargs += 2;
- break;
- }
-#endif /* ZFCDAT */
-
-#ifdef CK_IFRO
- case XXIFRO: /* REMOTE-ONLY advisory */
- ifargs++;
-#ifdef NOLOCAL
- z = 1;
-#else
- z = remonly;
-#endif /* NOLOCAL */
- break;
-#endif /* CK_IFRO */
-
- case XXIFAL: /* ALARM */
- ifargs++;
- debug(F101,"IF ALARM ck_alarm","",ck_alarm);
- debug(F110,"IF ALARM alrm_date",alrm_date,0);
- debug(F110,"IF ALARM alrm_time",alrm_time,0);
-
- if (ck_alarm < 1L || alrm_date[0] < '0' || alrm_time[0] < '0') {
- z = 0; /* ALARM not SET */
- break; /* so IF ALARM fails */
- }
- /* Get current date and time */
- ckstrncpy(tmpbuf,ckcvtdate("",1),TMPBUFSIZ);
- s = tmpbuf;
- s[8] = NUL;
- z = (int) strncmp(tmpbuf,alrm_date,8); /* Compare dates */
- debug(F101,"IF ALARM date z","",z);
- if (z == 0) { /* Dates are the same */
- /* Compare times */
- z = (tod2sec(tmpbuf+9) >= atol(alrm_time)) ? 1 : -1;
- debug(F101,"IF ALARM time z","",z);
- }
- tmpbuf[0] = NUL; /* z >= 0 if alarm is passed */
- z = ((z >= 0) ? 1 : 0); /* z < 0 otherwise */
- debug(F101,"IF ALARM final z","",z);
- break;
-
- case XXIFOP: /* IF OPEN */
- if ((x = cmkey(iotab,niot,"file or log","",xxstring)) < 0)
- return(x);
- if (x == 9999 || x == ZSTDIO) {
- bgchk(); /* Check background status */
- z = pflag ? 1 : 0;
- } else if (x == 8888) {
- z = local ? ttchk() > -1 : 0;
-#ifdef CKLOGDIAL
- } else if (x == 7777) {
- extern int dialog;
- z = dialog ? 1 : 0;
-#endif /* CKLOGDIAL */
- } else
- z = (chkfn(x) > 0) ? 1 : 0;
- ifargs += 1;
- break;
-
- case XXIFSD: /* Started-From-Dialer */
-#ifdef OS2
- z = StartedFromDialer;
-#else
- z = 0;
-#endif /* OS2 */
- break;
-
- case XXIFTM: /* Terminal-Macro */
-#ifdef OS2
- z = cmdstk[cmdlvl].ccflgs & CF_KMAC;
-#else
- z = 0;
-#endif /* OS2 */
- break;
-
- case XXIFEM: /* Emulation is active */
-#ifdef OS2
- z = 1;
-#else
- z = 0;
-#endif /* OS2 */
- break;
-
- case XXIFIK: /* Running as IKSD? */
- z = inserver;
- break;
-
- case XXIFTA: /* Connection is TAPI */
- z = 0;
-#ifndef NODIAL
-#ifdef CK_TAPI
- if (local && !network && tttapi)
- z = 1;
-#endif /* CK_TAPI */
-#endif /* NODIAL */
- break;
-
- case XXIFMA: /* IF MATCH */
- x = cmfld("String or variable","",&s,xxstring);
- if (x == -3) {
- extern int cmflgs;
- if (cmflgs == 1) {
- printf("?String required\n");
- return(-9);
- }
- } else if (x < 0)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- s = brstrip(line);
- debug(F110,"xxifma string",line,0);
- x = cmfld("Pattern","",&p,xxstring);
- if (x == -3) {
- extern int cmflgs;
- if (cmflgs == 1) {
- printf("?Pattern required\n");
- return(-9);
- }
- } else if (x < 0)
- return(x);
- ckstrncpy(tmpbuf,p,TMPBUFSIZ);
- p = brstrip(tmpbuf);
- debug(F110,"xxifma pattern",tmpbuf,0);
- z = ckmatch(p,s,inpcas[cmdlvl],1);
- break;
-
- case XXIFFL: { /* IF FLAG */
- extern int ooflag;
- z = ooflag;
- break;
- }
- case XXIFAV: { /* IF AVAILABLE */
- if ((x = cmkey(availtab,availtabn,"","",xxstring)) < 0)
- return(x);
- switch (x) {
- case AV_KRB4:
- z = ck_krb4_is_installed();
- break;
- case AV_KRB5:
- z = ck_krb5_is_installed();
- break;
- case AV_SRP:
- z = ck_srp_is_installed();
- break;
- case AV_SSL:
- z = ck_ssleay_is_installed();
- break;
- case AV_NTLM:
- z = ck_ntlm_is_installed();
- break;
- case AV_CRYPTO:
- z = ck_crypt_is_installed();
- break;
- case AV_SSH:
- z = ck_ssh_is_installed();
- break;
- default:
- z = 0;
- }
- break;
- }
- case XXIFAT: /* IF ASKTIMEOUT */
- z = asktimedout;
- break;
-
- case XXIFRD: /* IF READABLE */
- case XXIFWR: /* IF WRITEABLE */
- if ((x = cmfld("File or directory name",
- "",
- &s,
-#ifdef OS2
- NULL /* This allows \'s in filenames */
-#else
- xxstring
-#endif /* OS2 */
- )) < 0) {
- if (x == -3) {
- extern int cmflgs;
- if (cmflgs == 1) {
- printf("?File or directory name required\n");
- return(-9);
- }
- } else return(x);
- }
- s = brstrip(s);
-/*
- zchk[io]() do not do what we want here for directories, so we set
- a global flag telling it to behave specially in this case. Othewise
- we'd have to change the API and change all ck?fio.c modules accordingly.
-*/
- y = 0; /* Try-again control */
-#ifdef OS2
- ifrdagain:
-#endif /* OS2 */
- if (ifc == XXIFRD) { /* IF READABLE */
- zchkid = 1;
- z = zchki(s) > -1;
- zchkid = 0;
- } else if (ifc == XXIFWR) { /* IF WRITEABLE */
- zchkod = 1;
- z = zchko(s) > -1;
- zchkod = 0;
- }
-#ifdef OS2
- if (!z && !y) { /* File not found. */
- int t; /* Try expanding variables */
- t = LINBUFSIZ-1; /* and looking again. */
- lp = line;
- zzstring(s,&lp,&t);
- s = line;
- z = zchko(s) > -1;
- y++;
- goto ifrdagain;
- }
-#endif /* OS2 */
- ifargs += 2;
- break;
- case XXIFQU: /* IF QUIET */
- z = quiet ? 1 : 0;
- debug(F101,"if quiet","",z);
- ifargs += 1;
- break;
-
- case XXIFWI: /* WILD */
- if ((x = cmfld("File specification","",&s,xxstring)) < 0) return(x);
- z = iswild(s);
- break;
-
- case XXIFCK: /* C-KERMIT */
-#ifdef OS2
- z = 0;
-#else
- z = 1;
-#endif /* OS2 */
- break;
-
- case XXIFK9: /* K-95 */
-#ifdef OS2
- z = 1;
-#else
- z = 0;
-#endif /* OS2 */
- break;
-
- case XXIFGU: /* GUI */
-#ifdef KUI
- z = 1;
-#else
- z = 0;
-#endif /* KUI */
- break;
-
- case XXIFMS: /* MS-KERMIT */
- z = 0;
- break;
-
- case XXIFLO: /* IF LOCAL */
- z = local ? 1 : 0;
- break;
-
- case XXIFCM: { /* IF COMMAND */
- extern struct keytab cmdtab[];
- extern int ncmd;
- if ((x = cmfld("Word","",&s,xxstring)) < 0)
- return(x);
- z = lookup(cmdtab,s,ncmd,&y);
- z = (z == -2 || z > -1) ? 1 : 0;
- break;
- }
-#ifdef CKFLOAT
- case XXIFFP: /* IF FLOAT */
- if ((x = cmfld("Number","",&s,xxstring)) < 0)
- if (x != -3) /* e.g. empty variable */
- return(x);
- z = isfloat(s,0);
- break;
-#endif /* CKFLOAT */
-
- case XXIFKB: /* KBHIT */
- z = conchk();
- if (z < 0) z = 0;
- if (z > 1) z = 1;
- break;
-
- case XXIFKG: { /* KERBANG */
- extern int cfilef;
-#ifdef COMMENT
- z = (xcmdsrc == 0) ? 0 : (cfilef && cmdlvl == 1);
-#else
- z = (xcmdsrc == 0) ? 0 : (cfilef && tlevel == 0);
-#endif /* COMMENT */
- break;
- }
-
- case XXIFDB: { /* IF DEBUG - 2010/03/16 */
- extern int debmsg;
- z = debmsg;
- break;
- }
-
- default: /* Shouldn't happen */
- return(-2);
- } /* end of switch */
-
- if (z)
- *bx++ = '1';
- else
- *bx++ = '0';
- *bx = NUL;
- if (bx > boolval + BOOLLEN - 2) {
- printf("?Boolean expression too long");
- return(-9);
- }
- ecount++; /* Expression counter */
- debug(F101,"boolexp parens","",parens);
- debug(F101,"boolexp pcount","",pcount);
- if (parens && pcount > 0)
- goto ifagain;
-
- ifend: /* No more - done */
- *bx = NUL;
- z = atoi(evalx(boolval));
- debug(F111,"boolexp boolval",boolval,z);
- return(z);
-}
-
-/* D O I F -- Do the IF command */
-
-int
-doif(cx) int cx; {
- int x, y, z; char *s, *p;
- char *q;
-#ifdef OS2
- extern int keymac;
-#endif /* OS2 */
-
- debug(F101,"doif cx","",cx);
-
- z = boolexp(cx); /* Evaluate the condition(s) */
- debug(F010,"doif cmdbuf",cmdbuf,0);
- debug(F101,"doif boolexp","",z);
- if (z < 0)
- return(z);
-
- if (cx == XXIF) { /* Allow IF to have XIF semantics. */
- char * p;
- p = cmpeek();
- if (!p) p = "";
- while (*p) {
- if (*p == SP || *p == HT)
- p++;
- else
- break;
- }
- if (*p == '{')
- cx = XXIFX;
- }
- switch (cx) { /* Separate handling for IF and XIF */
-
- case XXASSER: /* And ASSERT */
- if ((x = cmcfm()) < 0)
- return(x);
- return(success = z);
-
- case XXIF: /* This is IF... */
- ifcmd[cmdlvl] = 1; /* We just completed an IF command */
- debug(F101,"doif condition","",z);
- if (z) { /* Condition is true */
- iftest[cmdlvl] = 1; /* Remember that IF succeeded */
- if (maclvl > -1) { /* In macro, */
- pushcmd(NULL); /* save rest of command. */
- } else if (tlevel > -1) { /* In take file, */
- debug(F100, "doif: pushing command", "", 0);
- pushcmd(NULL); /* save rest of command. */
- } else { /* If interactive, */
- cmini(ckxech); /* just start a new command */
- printf("\n"); /* (like in MS-DOS Kermit) */
- if (pflag) prompt(xxstring);
- }
- } else { /* Condition is false */
- iftest[cmdlvl] = 0; /* Remember command failed. */
- if ((y = cmtxt("command to be ignored","",&s,NULL)) < 0)
- return(y); /* Gobble up rest of line */
- }
- return(0);
-
- case XXIFX: { /* This is XIF (Extended IF) */
- char *p;
- char e[5];
- int i;
- if ((y = cmtxt("Object command","",&s,NULL)) < 0)
- return(y); /* Get object command. */
- p = s;
- lp = line;
- debug(F110,"doif THEN part",s,-54);
- if (litcmd(&p,&lp,LINBUFSIZ - 1) < 0) { /* Quote THEN-part */
- return(-2);
- }
- debug(F111,"doif THEN part 2",line,z);
-
- while (*p == SP) p++; /* Strip trailing spaces */
- ifcmd[cmdlvl] = 0; /* Assume ELSE part in same line */
- iftest[cmdlvl] = z ? 1 : 0;
- if (*p) { /* At end? */
- if (!z) { /* No, use ELSE-part, if any */
- for (i = 0; i < 4; i++) e[i] = *p++;
- if (ckstrcmp(e,"else",4,0)) /* See if we have an ELSE */
- return(-2); /* Something else - error. */
- debug(F010,"doif ELSE line 1",p,0);
- while (*p == SP) p++; /* Skip spaces */
- if (*p != '{') { /* Brace ELSE part if necessary */
- ckmakmsg(tmpbuf,TMPBUFSIZ,"{",p," }",NULL);
- p = tmpbuf;
- debug(F010,"doif ELSE line 2",p,0);
- }
- lp = line; /* Write over THEN part... */
- *lp = NUL; /* with ELSE part. */
- if (litcmd(&p,&lp,LINBUFSIZ - 2) < 0) {
- return(-2);
- }
- while (*p == SP) p++; /* Strip trailing spaces */
- if (*p) return(-2); /* Should be nothing here. */
- debug(F010,"doif ELSE line 3",line,0);
- }
- } else { /* At end, treat like an IF command */
- if (!z) line[0] = NUL; /* Condition not true and no ELSE */
- ifcmd[cmdlvl] = 1; /* Allow ELSE on next line */
- debug(F101,"IF condition","",z);
- }
- if (line[0]) {
- x = mlook(mactab,"_xif",nmac); /* Get index of "_xif" macro. */
- if (x < 0) { /* Not there? */
- addmmac("_xif",xif_def); /* Put it back. */
- if (mlook(mactab,"_xif",nmac) < 0) { /* Look it up again. */
- printf("?XIF macro gone!\n");
- return(success = 0);
- }
- }
- dodo(x,line,cmdstk[cmdlvl].ccflgs | CF_IMAC);
- }
- return(0);
- }
- case XXWHI: { /* WHILE Command */
- p = cmdbuf; /* Capture IF condition */
- ifcond[0] = NUL; /* from command buffer */
- while (*p == SP) p++;
- while (*p != SP) p++;
- ifcp = ifcond;
- ifcp += ckstrncpy(ifcp,"{ \\flit(if ( not ",IFCONDLEN);
-#ifdef COMMENT
-/*
- This doesn't work because it breaks on the first left brace, which does
- not necessarily start the command list, e.g. "while equal \%a {\35}".
-*/
- while (*p != '{' && *p != NUL) *ifcp++ = *p++;
- p = " ) goto _..bot) } ";
- while (*ifcp++ = *p++) ;
-#else
-/*
- The command parser sets cmbptr to the spot where it left off parsing in
- the command buffer.
-*/
- {
- extern char * cmbptr;
- if (cmbptr) {
- while (p < cmbptr && *p != NUL)
- *ifcp++ = *p++;
- p = " ) goto _..bot) } ";
- while ((*ifcp++ = *p++)) ;
- } else {
- printf("?Internal error parsing WHILE condition\n");
- return(-9);
- }
- }
-#endif /* COMMENT */
-
- debug(F110,"WHILE cmd",ifcond,0);
-
- if ((y = cmtxt("Object command","",&s,NULL)) < 0)
- return(y); /* Get object command. */
- p = s;
- lp = line;
- if (litcmd(&p,&lp,LINBUFSIZ - 2) < 0) { /* Quote object command */
- return(-2);
- }
- debug(F101,"WHILE body",line,-54);
- if (line[0]) {
- char *p;
- x = mlook(mactab,"_while",nmac); /* index of "_while" macro. */
- if (x < 0) { /* Not there? */
- addmmac("_while",whil_def); /* Put it back. */
- if (mlook(mactab,"_while",nmac) < 0) { /* Look it up again */
- printf("?WHILE macro definition gone!\n");
- return(success = 0);
- }
- }
- p = malloc((int)strlen(ifcond) + (int)strlen(line) + 2);
- if (p) {
- strcpy(p,ifcond); /* safe (prechecked) */
- strcat(p,line); /* safe (prechecked) */
- debug(F010,"WHILE dodo",p,0);
- dodo(x,p,cmdstk[cmdlvl].ccflgs | CF_IMAC);
- free(p);
- p = NULL;
- } else {
- printf("?Can't allocate storage for WHILE command");
- return(success = 0);
- }
- }
- return(0);
- }
- default:
- return(-2);
- }
-}
-#endif /* NOSPL */
-
-/* Set up a TAKE command file */
-
-int
-dotake(s) char *s; {
-#ifndef NOSPL
- extern int tra_cmd;
-#endif /* NOSPL */
-#ifndef NOLOCAL
-#ifdef OS2
- extern int term_io;
- int term_io_sav = term_io;
-#endif /* OS2 */
-#endif /* NOLOCAL */
- int slen;
-
- debug(F110,"dotake",s,0);
- if (!s) s = "";
- if (!*s) return(success = 0);
- slen = strlen(s);
- debug(F101,"dotake len","",slen);
-
- if ((tfile[++tlevel] = fopen(s,"r")) == NULL) {
- perror(s);
- debug(F110,"dotake fail",s,0);
- tlevel--;
- return(success = 0);
- } else {
- tfline[tlevel] = 0; /* Line counter */
-#ifdef VMS
- conres(); /* So Ctrl-C will work */
-#endif /* VMS */
-#ifndef NOLOCAL
-#ifdef OS2
- term_io = 0; /* Disable Terminal Emulator I/O */
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifndef NOSPL
- cmdlvl++; /* Entering a new command level */
- debug(F111,"CMD +F",s,cmdlvl);
- debug(F101,"dotake cmdlvl","",cmdlvl);
- debug(F101,"dotake tlevel","",tlevel);
- if (cmdlvl > CMDSTKL) {
- debug(F100,"dotake stack overflow","",0);
- cmdlvl--;
- debug(F111,"CMD*-F",s,cmdlvl);
- fclose(tfile[tlevel--]);
- printf("?TAKE files and/or DO commands nested too deeply\n");
- return(success = 0);
- }
- if (tfnam[tlevel]) { /* Copy the filename */
- free(tfnam[tlevel]);
- tfnam[tlevel] = NULL;
- }
- if ((tfnam[tlevel] = malloc(strlen(s) + 1))) {
- strcpy(tfnam[tlevel],s); /* safe */
- } else {
- printf("?Memory allocation failure\n");
- return(success = 0);
- }
- ifcmd[cmdlvl] = 0; /* Set variables for this cmd file */
- iftest[cmdlvl] = 0;
- count[cmdlvl] = count[cmdlvl-1]; /* Inherit this */
- intime[cmdlvl] = intime[cmdlvl-1]; /* Inherit this */
- inpcas[cmdlvl] = inpcas[cmdlvl-1]; /* Inherit this */
- takerr[cmdlvl] = takerr[cmdlvl-1]; /* Inherit this */
- merror[cmdlvl] = merror[cmdlvl-1]; /* Inherit this */
- xquiet[cmdlvl] = quiet;
- xvarev[cmdlvl] = vareval;
- xcmdsrc = CMD_TF;
- cmdstk[cmdlvl].src = CMD_TF; /* Say we're in a TAKE file */
- cmdstk[cmdlvl].lvl = tlevel; /* nested at this level */
- cmdstk[cmdlvl].ccflgs = cmdstk[cmdlvl-1].ccflgs;
-#else
- takerr[tlevel] = takerr[tlevel-1]; /* Inherit this */
-#endif /* NOSPL */
- }
-#ifndef NOSPL
- if (tra_cmd)
- printf("[%d] +F: \"%s\"\n",cmdlvl,s);
-#endif /* NOSPL */
-#ifndef NOLOCAL
-#ifdef OS2
- term_io = term_io_sav;
-#endif /* OS2 */
-#endif /* NOLOCAL */
- return(1);
-}
-#endif /* NOICP */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus7.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuus7.c
deleted file mode 100644
index 1e74ab6..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuus7.c
+++ /dev/null
@@ -1,15323 +0,0 @@
-#include "ckcsym.h"
-
-/* C K U U S 7 -- "User Interface" for C-Kermit, part 7 */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- This file created from parts of ckuus3.c, which became too big for
- Mark Williams Coherent compiler to handle.
-*/
-
-/*
- Definitions here supersede those from system include files.
-*/
-#include "ckcdeb.h" /* Debugging & compiler things */
-#include "ckcasc.h" /* ASCII character symbols */
-#include "ckcker.h" /* Kermit application definitions */
-#include "ckcxla.h" /* Character set translation */
-#include "ckcnet.h" /* Network symbols */
-#include "ckuusr.h" /* User interface symbols */
-#include "ckucmd.h"
-#include "ckclib.h"
-
-#ifdef VMS
-#ifndef TCPSOCKET
-#include <errno.h>
-#endif /* TCPSOCKET */
-#endif /* VMS */
-
-#ifdef OS2
-#ifndef NT
-#define INCL_NOPM
-#define INCL_VIO /* Needed for ckocon.h */
-#define INCL_DOSMODULEMGR
-#include <os2.h>
-#undef COMMENT
-#else /* NT */
-#define APIRET ULONG
-#include <windows.h>
-#include <tapi.h>
-#include "cknwin.h"
-#include "ckntap.h"
-#endif /* NT */
-#include "ckowin.h"
-#include "ckocon.h"
-#include "ckodir.h"
-#ifdef OS2MOUSE
-#include "ckokey.h"
-#endif /* OS2MOUSE */
-#ifdef KUI
-#include "ikui.h"
-#endif /* KUI */
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) conoc(x)
-extern int mskkeys;
-extern int mskrename;
-#endif /* OS2 */
-
-#ifdef CK_AUTHENTICATION
-#include "ckuath.h"
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-#ifdef SSHBUILTIN
-#include "ckossh.h"
-#endif /* SSHBUILTIN */
-#ifdef STRATUS /* Stratus Computer, Inc. VOS */
-#ifdef putchar
-#undef putchar
-#endif /* putchar */
-#define putchar(x) conoc(x)
-#ifdef getchar
-#undef getchar
-#endif /* getchar */
-#define getchar(x) coninc(0)
-#endif /* STRATUS */
-
-char * slmsg = NULL;
-
-static int x, y = 0, z;
-static char *s;
-
-extern CHAR feol;
-extern int g_matchdot, hints, xcmdsrc, rcdactive;
-
-extern char * k_info_dir;
-
-#ifdef CK_LOGIN
-#ifdef CK_PAM
-int gotemptypasswd = 0; /* distinguish empty passwd from none given */
-#endif /* CK_PAM */
-#endif /* CK_LOGIN */
-
-#ifndef NOSPL
-extern int nmac;
-extern struct mtab *mactab;
-#endif /* NOSPL */
-
-#ifndef NOXFER
-#ifdef CK_SPEED
-extern short ctlp[]; /* Control-char prefixing table */
-#endif /* CK_SPEED */
-
-#ifdef PIPESEND
-extern char * sndfilter, * g_sfilter;
-extern char * rcvfilter, * g_rfilter;
-#endif /* PIPESEND */
-
-extern char * snd_move;
-extern char * snd_rename;
-extern char * g_snd_move;
-extern char * g_snd_rename;
-extern char * rcv_move;
-extern char * rcv_rename;
-extern char * g_rcv_move;
-extern char * g_rcv_rename;
-
-#ifdef PATTERNS
-extern char *binpatterns[], *txtpatterns[];
-extern int patterns;
-#endif /* PATTERNS */
-
-extern char * remdest;
-#ifdef CK_TMPDIR
-char * dldir = NULL;
-#endif /* CK_TMPDIR */
-
-extern struct ck_p ptab[];
-
-extern int protocol, remfile, rempipe, remappd, reliable, xreliable, fmask,
- fncnv, frecl, maxrps, wslotr, bigsbsiz, bigrbsiz, urpsiz, rpsiz, spsiz,
- bctr, npad, timef, timint, spsizr, spsizf, maxsps, spmax, nfils, displa,
- atcapr, pkttim, rtimo, fncact, mypadn, fdispla, f_save, pktpaus, setreliable,
- fnrpath, fnspath, atenci, atenco, atdati, atdato, atleni, atleno, atblki,
- atblko, attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
-
-extern int stathack;
-
-extern int atfrmi, atfrmo;
-#ifdef STRATUS
-extern int atcrei, atcreo, atacti, atacto;
-#endif /* STRATUS */
-#ifdef CK_PERMS
-extern int atlpri, atlpro, atgpri, atgpro;
-#endif /* CK_PERMS */
-
-extern CHAR
- sstate, eol, seol, stchr, mystch, mypadc, padch, ctlq, myctlq;
-
-#ifdef IKSD
-extern int inserver;
-#ifdef IKSDCONF
-extern int iksdcf;
-#endif /* IKSDCONF */
-#endif /* IKSD */
-
-extern char *cmarg, *cmarg2;
-
-#ifndef NOFRILLS
-extern char optbuf[]; /* Buffer for MAIL or PRINT options */
-extern int rprintf; /* REMOTE PRINT flag */
-#endif /* NOFRILLS */
-#endif /* NOXFER */
-
-#ifdef CK_TRIGGER
-extern char * tt_trigger[];
-#endif /* CK_TRIGGER */
-
-extern int tcs_transp;
-#ifdef PCTERM
-extern int tt_pcterm;
-#endif /* PCTERM */
-#ifdef NT
-extern int tt_vtnt;
-#endif /* NT */
-
-#ifdef SSHBUILTIN
-int sl_ssh_xfw = 0;
-int sl_ssh_xfw_saved = 0;
-int sl_ssh_ver = 0;
-int sl_ssh_ver_saved = 0;
-#endif /* SSHBUILTIN */
-
-#ifdef CK_AUTHENTICATION
-extern int auth_type_user[];
-int sl_auth_type_user[AUTHTYPLSTSZ] = {AUTHTYPE_NULL, AUTHTYPE_NULL};
-int sl_auth_saved = 0;
-int sl_topt_a_su = 0;
-int sl_topt_a_s_saved = 0;
-int sl_topt_a_cm = 0;
-int sl_topt_a_c_saved = 0;
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
-extern int cx_type;
-int sl_cx_type = 0;
-int sl_cx_saved = 0;
-int sl_topt_e_su = 0;
-int sl_topt_e_sm = 0;
-int sl_topt_e_s_saved = 0;
-int sl_topt_e_cu = 0;
-int sl_topt_e_cm = 0;
-int sl_topt_e_c_saved = 0;
-#endif /* CK_ENCRYPTION */
-extern char uidbuf[];
-static int uidflag = 0;
-char sl_uidbuf[UIDBUFLEN] = { NUL, NUL };
-int sl_uid_saved = 0;
-#ifdef TNCODE
-int sl_tn_wait = 0;
-int sl_tn_saved = 0;
-#endif /* TNCODE */
-
-#ifdef TNCODE
-extern int tn_wait_flg;
-#endif /* TNCODE */
-
-VOID
-slrestor() {
-#ifdef CK_AUTHENTICATION
- int x;
- if (sl_auth_saved) {
- for (x = 0; x < AUTHTYPLSTSZ; x++)
- auth_type_user[x] = sl_auth_type_user[x];
- sl_auth_saved = 0;
- }
- if (sl_topt_a_s_saved) {
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = sl_topt_a_su;
- sl_topt_a_s_saved = 0;
- }
- if (sl_topt_a_c_saved) {
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = sl_topt_a_cm;
- sl_topt_a_c_saved = 0;
- }
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
- if (sl_cx_saved) {
- cx_type = sl_cx_type;
- sl_cx_saved = 0;
- }
- if (sl_topt_e_s_saved) {
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = sl_topt_e_su;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = sl_topt_e_sm;
- sl_topt_e_s_saved = 0;
- }
- if (sl_topt_e_c_saved) {
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = sl_topt_e_cu;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = sl_topt_e_cm;
- sl_topt_e_c_saved = 0;
- }
-#endif /* CK_ENCRYPTION */
- if (sl_uid_saved) {
- ckstrncpy(uidbuf,sl_uidbuf,UIDBUFLEN);
- sl_uid_saved = 0;
- }
-#ifdef TNCODE
- if (sl_tn_saved) {
- tn_wait_flg = sl_tn_wait;
- sl_tn_saved = 0;
- }
-#endif /* TNCODE */
-#ifdef SSHBUILTIN
- if (sl_ssh_xfw_saved) {
- ssh_xfw = sl_ssh_xfw;
- sl_ssh_xfw_saved = 0;
- }
- if (sl_ssh_ver_saved) {
- ssh_ver = sl_ssh_ver;
- sl_ssh_ver_saved = 0;
- }
-#endif /* SSHBUILTIN */
-}
-
-int oldplex = -1; /* Duplex holder around network */
-
-#ifndef NOICP
-#ifdef LOCUS
-extern int locus, autolocus;
-#endif /* LOCUS */
-#ifndef NODIAL
-extern int dialsta;
-#endif /* NODIAL */
-
-/* Note: gcc -Wall wants braces around each keyword table entry. */
-
-static struct keytab psltab[] = { /* SET LINE/PORT command options */
- { "/connect", SL_CNX, 0 },
-#ifdef OS2ORVMS
- { "/noshare", SL_NSH, 0 },
-#endif /* OS2ORVMS */
- { "/server", SL_SRV, 0 },
-#ifdef OS2ORVMS
- { "/share", SL_SHR, 0 },
-#endif /* OS2ORVMS */
- { "", 0, 0 }
-};
-static int npsltab = sizeof(psltab)/sizeof(struct keytab) - 1;
-
-#ifdef NETCONN
-static struct keytab shtab[] = { /* SET HOST command options */
-#ifdef NETCMD
- /* (COMMAND is also a network type) */
- { "/command", SL_CMD, CM_INV },
-#endif /* NETCMD */
- { "/connect", SL_CNX, 0 },
- { "/network-type", SL_NET, CM_ARG },
- { "/nowait", SL_NOWAIT, 0 },
-#ifndef NOSPL
-#ifdef CK_AUTHENTICATION
- { "/password", SL_PSW, CM_ARG },
-#endif /* CK_AUTHENTICATION */
-#endif /* NOSPL */
-#ifdef NETCMD
- { "/pipe", SL_CMD, 0 },
-#endif /* NETCMD */
-#ifdef NETPTY
- { "/pty", SL_PTY, 0 },
-#endif /* NETPTY */
- { "/server", SL_SRV, 0 },
- { "/timeout", SL_TMO, CM_ARG },
- { "/userid", SL_UID, CM_ARG },
- { "/wait", SL_WAIT, 0 },
- { "", 0, 0 }
-};
-static int nshtab = sizeof(shtab)/sizeof(struct keytab) - 1;
-
-static struct keytab shteltab[] = { /* TELNET command options */
-#ifdef CK_AUTHENTICATION
- { "/auth", SL_AUTH, CM_ARG },
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
- { "/encrypt", SL_ENC, CM_ARG },
-#endif /* CK_ENCRYPTION */
- { "/nowait", SL_NOWAIT, 0 },
-#ifndef NOSPL
-#ifdef CK_AUTHENTICATION
- { "/password", SL_PSW, CM_ARG },
-#endif /* CK_AUTHENTICATION */
-#endif /* NOSPL */
- { "/timeout", SL_TMO, CM_ARG },
- { "/userid", SL_UID, CM_ARG },
- { "/wait", SL_WAIT, 0 },
- { "", 0 ,0 }
-};
-static int nshteltab = sizeof(shteltab)/sizeof(struct keytab) - 1;
-
-#ifdef RLOGCODE
-static struct keytab shrlgtab[] = { /* SET HOST RLOGIN command options */
-#ifdef CK_KERBEROS
-#ifdef CK_ENCRYPTION
- { "/encrypt", SL_ENC, 0 },
-#endif /* CK_ENCRYPTION */
- { "/k4", SL_KRB4, CM_INV },
- { "/k5", SL_KRB5, CM_INV },
- { "/kerberos4", SL_KRB4, 0 },
- { "/kerberos5", SL_KRB5, 0 },
- { "/kerberos_iv", SL_KRB4, CM_INV },
- { "/kerberos_v", SL_KRB5, CM_INV },
- { "/krb4", SL_KRB4, CM_INV },
- { "/krb5", SL_KRB5, CM_INV },
-#endif /* CK_KERBEROS */
- { "", 0 ,0 }
-};
-static int nshrlgtab = sizeof(shrlgtab)/sizeof(struct keytab)-1;
-#endif /* RLOGCODE */
-
-extern struct keytab netcmd[];
-extern int nnets;
-#ifndef NODIAL
-extern int dirline;
-extern int nnetdir; /* Network services directory */
-extern char *netdir[];
-_PROTOTYP( VOID ndreset, (void) );
-char *nh_p[MAXDNUMS + 1]; /* Network directory entry pointers */
-char *nh_p2[MAXDNUMS + 1]; /* Network directory entry nettype */
-char *nh_px[4][MAXDNUMS + 1]; /* Network-specific stuff... */
-#endif /* NODIAL */
-int nhcount = 0;
-int ndinited = 0;
-char * n_name = NULL; /* Network name pointer */
-#endif /* NETCONN */
-
-_PROTOTYP(int remtxt, (char **) );
-_PROTOTYP(VOID rmsg, (void) );
-_PROTOTYP(static int remcfm, (void) );
-
-extern int nopush;
-
-int mdmsav = -1; /* Save modem type around network */
-extern int isguest; /* Global flag for anonymous login */
-
-extern xx_strp xxstring;
-
-extern int success, binary, b_save, ckwarn, msgflg, quiet, cmask, pflag, local,
- nettype, escape, mdmtyp, duplex, dfloc, network, cdtimo, autoflow, tnlm,
- sosi, tlevel, lf_opts, backgrd, flow, debses, parity, ttnproto, ckxech,
- x_ifnum, cmflgs, haveline, cxtype, cxflow[], maclvl;
-
-#ifdef DCMDBUF
-extern struct cmdptr *cmdstk; /* The command stack itself */
-#else
-extern struct cmdptr cmdstk[]; /* The command stack itself */
-#endif /* DCMDBUF */
-extern FILE * tfile[];
-extern char * macp[];
-
-extern char psave[]; /* For saving & restoring prompt */
-extern int sprmlen, rprmlen;
-
-#ifdef OS2
-static struct keytab strmkeytab[] = {
- { "clear", 0, 0 },
- { "default", 1, 0 }
-};
-static int nstrmkeytab = sizeof(strmkeytab)/sizeof(struct keytab);
-
-static struct keytab strmswitab[] = {
- { "/literal", 0, 0 }
-};
-static int nstrmswitab = sizeof(strmswitab)/sizeof(struct keytab);
-
-static struct keytab normrev[] = {
- { "dark-display", 0, 0 },
- { "light-display", 1, 0 },
- { "normal", 0, 0 },
- { "reverse", 1, 0 }
-};
-
-static struct keytab prnmtab[] = {
- { "auto", 1, 0 },
- { "copy", 2, 0 },
- { "off", 0, 0 },
- { "on", 1, CM_INV }, /* Compatibility with XPRINT version */
- { "user", 3, 0 },
- { "transparent", 3, CM_INV } /* not really transparent */
-};
-static int nprnmtab = sizeof(prnmtab)/sizeof(struct keytab);
-
-extern int tt_diff_upd;
-
-#ifdef NT
-#define stricmp _stricmp
-extern int tt_attr_bug;
-#endif /* NT */
-extern int tt_rows[], tt_cols[];
-extern int tt_cols_usr;
-extern int tt_szchng[VNUM];
-int tt_modechg = TVC_ENA;
-extern int tt_url_hilite, tt_url_hilite_attr;
-extern struct _vtG G[4];
-extern int priority;
-extern bool send_c1;
-int send_c1_usr = FALSE;
-extern int sgrcolors;
-extern int marginbell, marginbellcol;
-extern int autoscroll, wy_autopage;
-extern int tt_sac;
-extern int dec_nrc, dec_lang, dec_kbd;
-#else /* OS2 */
-extern int tt_rows, tt_cols;
-#endif /* OS2 */
-
-extern int tt_escape;
-extern long speed;
-
-extern char *dftty;
-
-extern char *tp, *lp; /* Temporary buffer & pointers */
-extern char ttname[];
-
-#ifdef CK_TAPI
-int tttapi = 0; /* is Line TAPI? */
-struct keytab * tapilinetab = NULL;
-struct keytab * _tapilinetab = NULL;
-int ntapiline = 0;
-#endif /* CK_TAPI */
-
-#ifdef NETCONN /* Network items */
-
-#ifdef ANYX25
-extern int revcall, closgr, cudata, nx25;
-extern char udata[];
-extern struct keytab x25tab[];
-#ifndef IBMX25
-extern int npadx3;
-extern CHAR padparms[];
-extern struct keytab padx3tab[];
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifdef OS2
-extern bool ttshare;
-#ifndef NT
-extern bool ttslip,ttppp;
-#endif /* NT */
-#endif /* OS2 */
-#ifdef NPIPE
-extern char pipename[];
-#endif /* NPIPE */
-
-#ifdef TCPSOCKET
-static struct keytab tcprawtab[] = { /* SET HOST options */
- { "/default", NP_DEFAULT, CM_INV },
-#ifdef CK_AUTHENTICATION
-#ifdef CK_KERBEROS
-#ifdef RLOGCODE
- { "/ek4login", NP_EK4LOGIN, 0 },
- { "/ek5login", NP_EK5LOGIN, 0 },
- { "/k4login", NP_K4LOGIN, 0 },
- { "/k5login", NP_K5LOGIN, 0 },
-#endif /* RLOGCODE */
-#ifdef KRB5_U2U
- { "/k5user2user", NP_K5U2U, 0 },
-#endif /* KRB5_U2U */
-#endif /* CK_KERBEROS */
-#endif /* CK_AUTHENTICATION */
- { "/no-telnet-init", NP_NONE, 0 },
- { "/none", NP_NONE, CM_INV },
- { "/raw-socket", NP_TCPRAW, 0 },
-#ifdef RLOGCODE
- { "/rlogin", NP_RLOGIN, 0 },
-#endif /* RLOGCODE */
-#ifdef CK_SSL
- { "/ssl", NP_SSL, 0 },
- { "/ssl-raw", NP_SSL_RAW, 0 },
- { "/ssl-telnet", NP_SSL_TELNET, 0 },
-#endif /* CK_SSL */
- { "/telnet", NP_TELNET, 0 },
-#ifdef CK_SSL
- { "/tls", NP_TLS, 0 },
- { "/tls-raw", NP_TLS_RAW, 0 },
- { "/tls-telnet", NP_TLS_TELNET, 0 },
-#endif /* CK_SSL */
- { "", 0, 0 }
-};
-static int ntcpraw = (sizeof(tcprawtab) / sizeof(struct keytab)) - 1;
-
-#ifdef RLOGCODE
-_PROTOTYP( int rlog_naws, (void) );
-#endif /* RLOGCODE */
-#endif /* TCPSOCKET */
-
-#ifdef SUPERLAT
-extern char slat_pwd[18];
-#endif /* SUPERLAT */
-#endif /* NETCONN */
-
-#ifdef COMMENT
-#ifndef NOSETKEY
-extern KEY *keymap;
-#ifndef OS2
-#define mapkey(x) keymap[x]
-#endif /* OS2 */
-extern MACRO *macrotab;
-#ifndef NOKVERBS
-extern struct keytab kverbs[];
-extern int nkverbs;
-#endif /* NOKVERBS */
-#endif /* NOSETKEY */
-#else
-#ifndef NOSETKEY
-extern KEY *keymap;
-extern MACRO *macrotab;
-#ifndef NOKVERBS
-extern struct keytab kverbs[];
-extern int nkverbs;
-#endif /* NOKVERBS */
-#endif /* NOSETKEY */
-#endif /* COMMENT */
-
-#ifdef OS2 /* AUTODOWNLOAD parameters */
-extern int adl_kmode, adl_zmode; /* Match Packet to signal download */
-extern char * adl_kstr; /* KERMIT Download String */
-extern char * adl_zstr; /* ZMODEM Download String */
-extern int adl_kc0, adl_zc0; /* Process ADL C0s in emulation */
-#endif /* OS2 */
-
-/* Keyword tables ... */
-
-extern struct keytab onoff[], rltab[];
-extern int nrlt;
-
-#ifndef NOCSETS
-static struct keytab fdfltab[] = {
- { "7bit-character-set", 7, 0 },
- { "8bit-character-set", 8, 0 }
-};
-static int nfdflt = (sizeof(fdfltab) / sizeof(struct keytab));
-#endif /* NOCSETS */
-
-/* SET FILE parameters */
-
-static struct keytab filtab[] = {
-#ifndef NOXFER
-#ifdef PATTERNS
- { "binary-patterns", XYFIBP, 0 },
-#endif /* PATTERNS */
- { "bytesize", XYFILS, 0 },
-#ifndef NOCSETS
- { "character-set", XYFILC, 0 },
-#endif /* NOCSETS */
- { "collision", XYFILX, 0 },
- { "default", XYF_DFLT, 0 },
- { "destination", XYFILY, 0 },
- { "display", XYFILD, CM_INV },
-#ifdef CK_TMPDIR
- { "download-directory", XYFILG, 0 },
-#endif /* CK_TMPDIR */
-#endif /* NOXFER */
- { "end-of-line", XYFILA, 0 },
- { "eol", XYFILA, CM_INV },
-#ifdef CK_CTRLZ
- { "eof", XYFILV, 0 },
-#endif /* CK_CTRLZ */
-#ifndef NOXFER
- { "fastlookups", 9997, CM_INV },
- { "incomplete", XYFILI, 0 },
-#ifndef datageneral
- { "inspection", XYF_INSP, CM_INV },
-#endif /* datageneral */
-#ifdef CK_LABELED
- { "label", XYFILL, 0 },
-#endif /* CK_LABELED */
-
-#ifdef UNIX
-#ifdef DYNAMIC
- { "listsize", XYF_LSIZ, 0 },
-#endif /* DYNAMIC */
-#endif /* UNIX */
-
- { "names", XYFILN, 0 },
-#ifdef UNIX
- { "output", XYFILH, 0 },
-#endif /* UNIX */
-#ifdef PATTERNS
- { "patterns", XYFIPA, 0 },
-#endif /* PATTERNS */
-#ifdef COMMENT /* Not implemented (but see CHMOD) */
- { "permissions", XYF_PRM, CM_INV },
- { "protection", XYF_PRM, 0 },
-#endif /* COMMENt */
-#ifdef VMS
- { "record-length", XYFILR, 0 },
-#endif /* VMS */
-#ifndef datageneral
- { "scan", XYF_INSP, 0 },
-#endif /* datageneral */
-
-#ifdef UNIX
-#ifdef DYNAMIC
- { "stringspace", XYF_SSPA, 0 },
-#endif /* DYNAMIC */
-#endif /* UNIX */
-
-#ifdef PATTERNS
- { "t", XYFILT, CM_INV|CM_ABR },
- { "text-patterns", XYFITP, 0 },
-#endif /* PATTERNS */
-#endif /* NOXFER */
- { "type", XYFILT, 0 },
-#ifdef UNICODE
- { "ucs", XYFILU, 0 },
-#endif /* UNICODE */
-#ifndef NOXFER
- { "warning", XYFILW, CM_INV }
-#endif /* NOXFER */
-};
-static int nfilp = (sizeof(filtab) / sizeof(struct keytab));
-
-struct keytab pathtab[] = {
- { "absolute", PATH_ABS, 0 },
- { "none", PATH_OFF, CM_INV },
- { "off", PATH_OFF, 0 },
- { "on", PATH_ABS, CM_INV },
- { "relative", PATH_REL, 0 }
-};
-int npathtab = (sizeof(pathtab) / sizeof(struct keytab));
-
-struct keytab rpathtab[] = {
- { "absolute", PATH_ABS, 0 },
- { "auto", PATH_AUTO, 0 },
- { "none", PATH_OFF, CM_INV },
- { "off", PATH_OFF, 0 },
- { "on", PATH_ABS, CM_INV },
- { "relative", PATH_REL, 0 }
-};
-int nrpathtab = (sizeof(rpathtab) / sizeof(struct keytab));
-
-#ifdef CK_CTRLZ
-struct keytab eoftab[] = { /* EOF detection method */
- { "ctrl-z", 1, 0 },
- { "length", 0, 0 },
- { "noctrl-z", 0, CM_INV }
-};
-#endif /* CK_CTRLZ */
-
-struct keytab fttab[] = { /* File types for SET FILE TYPE */
- { "ascii", XYFT_T, CM_INV },
-#ifdef VMS
- { "b", XYFT_B, CM_INV|CM_ABR },
-#endif /* VMS */
- { "binary", XYFT_B, 0 },
-#ifdef VMS
- { "block", XYFT_I, CM_INV },
- { "image", XYFT_I, 0 },
-#endif /* VMS */
-#ifdef CK_LABELED
- { "labeled", XYFT_L, 0 },
-#endif /* CK_LABELED */
-#ifdef MAC
- { "macbinary", XYFT_M, 0 },
-#endif /* MAC */
- { "text", XYFT_T, 0 }
-};
-int nfttyp = (sizeof(fttab) / sizeof(struct keytab));
-
-static struct keytab rfttab[] = { /* File types for REMOTE SET FILE */
- { "ascii", XYFT_T, CM_INV },
- { "binary", XYFT_B, 0 },
-#ifdef VMS
- { "labeled", XYFT_L, 0 },
-#else
-#ifdef OS2
- { "labeled", XYFT_L, 0 },
-#endif /* OS2 */
-#endif /* VMS */
- { "text", XYFT_T, 0 }
-};
-static int nrfttyp = (sizeof(rfttab) / sizeof(struct keytab));
-
-#ifdef OS2ORUNIX
-#define ZOF_BLK 0
-#define ZOF_NBLK 1
-#define ZOF_BUF 2
-#define ZOF_NBUF 3
-static struct keytab zoftab[] = {
- { "blocking", ZOF_BLK, 0 },
- { "buffered", ZOF_BUF, 0 },
- { "nonblocking", ZOF_NBLK, 0 },
- { "unbuffered", ZOF_NBUF, 0 }
-};
-static int nzoftab = (sizeof(zoftab) / sizeof(struct keytab));
-#endif /* OS2ORUNIX */
-
-extern int query; /* Global flag for QUERY active */
-
-#ifndef NOSPL
-#ifndef NOXFER
-static struct keytab vartyp[] = { /* Variable types for REMOTE QUERY */
- { "global", (int) 'G', CM_INV },
- { "kermit", (int) 'K', 0 },
- { "system", (int) 'S', 0 },
- { "user", (int) 'G', 0 }
-};
-static int nvartyp = (sizeof(vartyp) / sizeof(struct keytab));
-#endif /* NOXFER */
-#endif /* NOSPL */
-
-#ifdef CK_TIMERS
-static struct keytab timotab[] = { /* Timer types */
- { "dynamic", 1, 0 },
- { "fixed", 0, 0 }
-};
-#endif /* CK_TIMERS */
-
-#ifdef DCMDBUF
-extern char *atxbuf, *atmbuf; /* Atom buffer */
-extern char *cmdbuf; /* Command buffer */
-extern char *line, *tmpbuf; /* Character buffers for anything */
-extern int *intime; /* INPUT TIMEOUT */
-
-#else /* Not DCMDBUF ... */
-
-extern char atxbuf[], atmbuf[]; /* Atom buffer */
-extern char cmdbuf[]; /* Command buffer */
-extern char line[], tmpbuf[]; /* Character buffer for anything */
-extern int intime[];
-
-#endif /* DCMDBUF */
-
-#ifndef NOCSETS
-extern struct keytab fcstab[]; /* For SET FILE CHARACTER-SET */
-extern struct csinfo fcsinfo[]; /* File character set info. */
-extern struct keytab ttcstab[];
-extern int nfilc, fcharset, tcharset, ntermc, tcsr, tcsl, dcset7, dcset8;
-#ifdef CKOUNI
-extern int tt_utf8;
-#endif /* CKOUNI */
-#ifdef OS2
-_PROTOTYP( int os2setcp, (int) );
-_PROTOTYP( int os2getcp, (void) );
-_PROTOTYP( void os2debugoff, (void) );
-#endif /* OS2 */
-#endif /* NOCSETS */
-
-extern int cmdlvl; /* Overall command level */
-
-#ifndef NOSPL
-#ifdef DCMDBUF
-extern int *inpcas; /* INPUT CASE setting on cmd stack */
-#else
-extern int inpcas[];
-#endif /* DCMDBUF */
-#endif /* NOSPL */
-
-#ifdef CK_CURSES
-#ifndef VMS
-_PROTOTYP(int tgetent,(char *, char *));
-#else
-#ifdef __DECC
-_PROTOTYP(int tgetent,(char *, char *));
-#endif /* __DECC */
-#endif /* VMS */
-#endif /* CK_CURSES */
-
-#ifndef NOXMIT
-#define XMITF 0 /* SET TRANSMIT values */
-#define XMITL 1 /* (Local to this module) */
-#define XMITP 2
-#define XMITE 3
-#define XMITX 4
-#define XMITS 5
-#define XMITW 6
-#define XMITT 7
-
-#define XMBUFL 50
-extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw, xmitt;
-char xmitbuf[XMBUFL+1] = { NUL }; /* TRANSMIT eof string */
-
-struct keytab xmitab[] = { /* SET TRANSMIT */
- { "echo", XMITX, 0 },
- { "eof", XMITE, 0 },
- { "fill", XMITF, 0 },
- { "linefeed", XMITL, 0 },
- { "locking-shift", XMITS, 0 },
- { "pause", XMITW, 0 },
- { "prompt", XMITP, 0 },
- { "timeout", XMITT, 0 }
-};
-int nxmit = (sizeof(xmitab) / sizeof(struct keytab));
-#endif /* NOXMIT */
-
-/* For SET FILE COLLISION */
-/* Some of the following may be possible for some C-Kermit implementations */
-/* but not others. Those that are not possible for your implementation */
-/* should be ifdef'd out. */
-
-struct keytab colxtab[] = { /* SET FILE COLLISION options */
-#ifndef MAC
- { "append", XYFX_A, 0 }, /* append to old file */
-#endif /* MAC */
-#ifdef COMMENT
- { "ask", XYFX_Q, 0 }, /* ask what to do (not implemented) */
-#endif
- { "backup", XYFX_B, 0 }, /* rename old file */
-#ifndef MAC
- /* This crashes Mac Kermit. */
- { "discard", XYFX_D, CM_INV }, /* don't accept new file */
- { "no-supersede", XYFX_D, CM_INV }, /* ditto (MSK compatibility) */
-#endif /* MAC */
- { "overwrite", XYFX_X, 0 }, /* overwrite the old file */
- { "reject", XYFX_D, 0 }, /* (better word than discard) */
- { "rename", XYFX_R, 0 }, /* rename the incoming file */
-#ifndef MAC /* This crashes Mac Kermit. */
- { "update", XYFX_U, 0 }, /* replace if newer */
-#endif /* MAC */
- { "", 0, 0 }
-};
-int ncolx = (sizeof(colxtab) / sizeof(struct keytab)) - 1;
-
-static struct keytab rfiltab[] = { /* for REMOTE SET FILE */
-#ifndef NOCSETS
- { "character-set", XYFILC, 0 },
-#endif /* NOCSETS */
- { "collision", XYFILX, 0 },
- { "incomplete", XYFILI, 0 },
- { "names", XYFILN, 0 },
- { "record-length", XYFILR, 0 },
- { "type", XYFILT, 0 }
-};
-int nrfilp = (sizeof(rfiltab) / sizeof(struct keytab));
-
-struct keytab eoltab[] = { /* File eof delimiters */
- { "cr", XYFA_C, 0 },
- { "crlf", XYFA_2, 0 },
- { "lf", XYFA_L, 0 }
-};
-static int neoltab = (sizeof(eoltab) / sizeof(struct keytab));
-
-struct keytab fntab[] = { /* File naming */
- { "converted", XYFN_C, 0 },
- { "literal", XYFN_L, 0 },
- { "standard", XYFN_C, CM_INV }
-};
-int nfntab = (sizeof(fntab) / sizeof(struct keytab));
-
-#ifndef NOLOCAL
-/* Terminal parameters table */
-static struct keytab trmtab[] = {
-#ifdef OS2
- { "answerback", XYTANS, 0 },
-#endif /* OS2 */
-#ifdef CK_APC
- { "apc", XYTAPC, 0 },
-#endif /* CK_APC */
-#ifdef OS2
- { "arrow-keys", XYTARR, 0 },
-#endif /* OS2 */
-#ifdef NT
- { "at", XYTATTR, CM_INV|CM_ABR },
- { "att", XYTATTR, CM_INV|CM_ABR },
- { "attr", XYTATTR, CM_INV|CM_ABR },
- { "attr-bug", XYTATTBUG, CM_INV },
-#endif /* NT */
-#ifdef OS2
- { "attribute", XYTATTR, 0 },
-#endif /* OS2 */
-#ifdef CK_APC
-#ifdef CK_AUTODL
- { "autodownload", XYTAUTODL, 0, },
-#endif /* CK_AUTODL */
-#endif /* CK_APC */
-#ifdef OS2
- { "autopage", XYTAPAGE, 0 },
- { "autoscroll", XYTASCRL, 0 },
- { "bell", XYTBEL, CM_INV },
-#endif /* OS2 */
- { "bytesize", XYTBYT, 0 },
-#ifndef NOCSETS
- { "character-set", XYTCS, 0 },
-#endif /* NOCSETS */
-#ifdef OS2
- { "code-page", XYTCPG, 0 },
- { "color", XYTCOL, 0 },
- { "controls", XYTCTRL, 0 },
-#endif /* OS2 */
- { "cr-display", XYTCRD, 0 },
-#ifdef OS2
- { "cursor", XYTCUR, 0 },
-#endif /* OS2 */
- { "debug", XYTDEB, 0 },
-#ifdef OS2
- { "dg-unix-mode", XYTUNX, 0 },
-#endif /* OS2 */
- { "echo", XYTEC, 0 },
- { "escape-character", XYTESC, 0 },
-#ifdef OS2
-#ifdef PCFONTS
- { "font", XYTFON, 0 },
-#else
-#ifdef KUI
- { "font", XYTFON, 0 },
-#endif /* KUI */
-#endif /* PCFONTS */
-#endif /* OS2 */
- { "height", XYTHIG, 0 },
-#ifdef CKTIDLE
- { "idle-action", XYTIACT, 0 },
- { "idle-limit", XYTITMO, CM_INV },
- { "idle-send", XYTIDLE, CM_INV },
- { "idle-timeout", XYTITMO, 0 },
-#endif /* CKTIDLE */
-#ifdef OS2
-#ifndef NOCSETS
- { "kbd-follows-gl/gr", XYTKBDGL, 0 },
-#endif /* NOCSETS */
- { "key", XYTKEY, 0 },
- { "keyboard-mode", XYTKBMOD, 0 },
- { "keypad-mode", XYTKPD, 0 },
-#endif /* OS2 */
- { "lf-display", XYTLFD, 0 },
-#ifndef NOCSETS
-#ifdef OS2
-#ifndef KUI
- { "line-spacing", XYTLSP, CM_INV },
- { "local-character-set", XYTLCS, 0 },
-#else
- { "line-spacing", XYTLSP, 0 },
- { "local-character-set", XYTLCS, CM_INV },
-#endif /* KUI */
-#else
- { "local-character-set", XYTLCS, CM_INV },
-#endif /* OS2 */
-#endif /* NOCSETS */
- { "locking-shift", XYTSO, 0 },
-#ifdef OS2
- { "margin-bell", XYTMBEL, 0 },
-#endif /* OS2 */
-#ifdef OS2MOUSE
- { "mouse", XYTMOU, CM_INV },
-#endif /* OS2MOUSE */
- { "newline-mode", XYTNL, 0 },
-#ifdef OS2
- { "output-pacing", XYTPAC, 0 },
-#ifdef PCTERM
- { "pcterm", XYTPCTERM, 0 },
-#endif /* PCTERM */
-#endif /* OS2 */
-#ifdef OS2ORUNIX
- { "print", XYTPRN, 0 },
-#endif /* OS2ORUNIX */
-#ifndef NOCSETS
-#ifdef OS2
- { "remote-character-set", XYTRCS, 0 },
-#else
- { "remote-character-set", XYTRCS, CM_INV },
-#endif /* OS2 */
-#endif /* NOCSETS */
-#ifdef OS2
- { "roll-mode", XYTROL, 0 },
- { "s", XYTUPD, CM_ABR|CM_INV },
- { "sc", XYTUPD, CM_ABR|CM_INV },
- { "scr", XYTUPD, CM_ABR|CM_INV },
- { "scree", XYTUPD, CM_ABR|CM_INV },
- { "screen", XYTUPD, CM_ABR|CM_INV },
- { "screen-", XYTUPD, CM_ABR|CM_INV },
- { "screen-mode", XYTSCNM, 0 },
- { "screen-optimize", XYTOPTI, 0 },
- { "screen-update", XYTUPD, 0 },
- { "scrollback", XYSCRS, 0 },
- { "send-data", XYTSEND, 0 },
- { "send-end-of-block", XYTSEOB, 0 },
- { "sgr-colors", XYTSGRC, 0 },
- { "sni-ch.code", XYTSNICC, 0 },
- { "sni-firmware-versions", XYTSNIFV, 0 },
- { "sni-language", XYTVTLNG, 0 },
- { "sni-pagemode", XYTSNIPM, CM_INV },
- { "sni-scrollmode", XYTSNISM, CM_INV },
- { "spacing-attribute-character", XYTSAC, CM_INV },
- { "statusline", XYTSTAT, 0 },
- { "tra", XYTCTS, CM_INV|CM_ABR },
- { "transmit-timeout", XYTCTS, 0 },
-#endif /* OS2 */
-
-#ifdef OS2ORUNIX
- { "transparent-print", XYTPRN, CM_INV },
-#endif /* OS2ORUNIX */
-
-#ifdef CK_TRIGGER
- { "trigger", XYTRIGGER,0 },
-#endif /* CK_TRIGGER */
-#ifdef OS2
- { "type", XYTTYP, 0 },
-#else
- { "type", XYTTYP, CM_INV },
-#endif /* OS2 */
-
-#ifndef NOCSETS
-#ifdef UNICODE
-#ifdef CKOUNI
- { "unicode", XYTUNI, CM_INV },
-#endif /* CKOUNI */
-#endif /* UNICODE */
-#endif /* NOCSETS */
-#ifdef OS2
- { "unix-mode", XYTUNX, CM_INV },
- { "url-highlight", XYTURLHI, 0 },
-#ifdef NT
- { "video-change", XYTVCH, 0 },
-#endif /* NT */
- { "vt-language", XYTVTLNG, 0 },
- { "vt-nrc-mode", XYTVTNRC, 0 },
-#endif /* OS2 */
- { "width", XYTWID, 0 },
-#ifdef OS2
- { "wrap", XYTWRP, 0 },
-#endif /* OS2 */
- { "", 0, 0 }
-};
-int ntrm = (sizeof(trmtab) / sizeof(struct keytab)) - 1;
-
-#ifdef OS2
-struct keytab termctrl[] = { /* SET TERM CONTROLS */
- { "7", 7, 0 },
- { "8", 8, 0 }
-};
-int ntermctrl = (sizeof(termctrl) / sizeof(struct keytab));
-
-struct keytab curontab[] = { /* SET TERM CURSOR */
-#ifdef KUI
- { "noblink", 2, 0 },
-#else
- { "noblink", 2, CM_INV },
-#endif /* KUI */
- { "off", 0, 0 },
- { "on", 1, 0 }
-};
-int ncuron = (sizeof(curontab) / sizeof(struct keytab));
-
-struct keytab rolltab[] = { /* Set TERM Roll Options */
- { "insert", TTR_INSERT, 0 },
- { "keystrokes",TTR_KEYS, 0 },
- { "off", TTR_OVER, CM_INV },
- { "on", TTR_INSERT, CM_INV },
- { "overwrite", TTR_OVER, 0 }
-};
-int nroll = (sizeof(rolltab) / sizeof(struct keytab));
-
-struct keytab rollkeytab[] = { /* Set TERM ROLL KEYSTROKES */
- { "ignore", TTRK_IGN, 0 },
- { "restore-and-send", TTRK_RST, 0 },
- { "send", TTRK_SND, 0 }
-};
-int nrollkey = (sizeof(rollkeytab) / sizeof(struct keytab));
-
-#define TT_GR_ALL 4
-#define TT_GR_G0 0
-#define TT_GR_G1 1
-#define TT_GR_G2 2
-#define TT_GR_G3 3
-#define TT_GR_KBD 4
-struct keytab graphsettab[] = { /* DEC VT Graphic Sets */
- { "all", TT_GR_ALL, 0 },
- { "g0", TT_GR_G0, 0 },
- { "g1", TT_GR_G1, 0 },
- { "g2", TT_GR_G2, 0 },
- { "g3", TT_GR_G3, 0 },
- { "keyboard", TT_GR_KBD, 0 }
-};
-int ngraphset = (sizeof(graphsettab) / sizeof(struct keytab));
-#endif /* OS2 */
-
-struct keytab adltab[] = { /* Autodownload Options */
- { "ask", TAD_ASK, 0 },
- { "error", TAD_ERR, 0 },
-#ifdef OS2
- { "kermit", TAD_K, 0 },
-#endif /* OS2 */
- { "off", TAD_OFF, 0 },
- { "on", TAD_ON, 0 },
-#ifdef OS2
- { "zmodem", TAD_Z, 0 },
-#endif /* OS2 */
- { "", 0, 0 }
-};
-int nadltab = (sizeof(adltab) / sizeof(struct keytab)) - 1;
-
-struct keytab adlerrtab[] = { /* Autodownload Error Options */
- { "continue", 0, 0 },
- { "go", 0, CM_INV },
- { "stop", 1, 0 }
-};
-int nadlerrtab = (sizeof(adlerrtab) / sizeof(struct keytab));
-
-#ifdef OS2
-struct keytab adlxtab[] = { /* Autodownload Options */
- { "c0-conflicts", TAD_X_C0, 0 },
- { "detection-method", TAD_X_DETECT, 0 },
- { "string", TAD_X_STR, 0 }
-};
-int nadlxtab = (sizeof(adlxtab) / sizeof(struct keytab));
-
-struct keytab adldtab[] = { /* Auto-dl Detection Methods */
- { "packet", ADL_PACK, 0 },
- { "string", ADL_STR, 0 }
-};
-int nadldtab = (sizeof(adldtab) / sizeof(struct keytab));
-
-struct keytab adlc0tab[] = { /* Auto-dl Detection Methods */
- { "ignored-by-emulator", 0, 0 },
- { "processed-by-emulator", 1, 0 }
-};
-int nadlc0tab = (sizeof(adlc0tab) / sizeof(struct keytab));
-
-#ifndef NOCSETS
-struct keytab vtlangtab[] = {
- { "belgian", VTL_BELGIAN , 0 },
- { "british", VTL_BRITISH , 0 },
- { "canadian", VTL_CANADIAN, 0 },
- { "czech", VTL_CZECH , 0 },
- { "danish", VTL_DANISH , 0 },
- { "dutch", VTL_DUTCH , 0 },
- { "finnish", VTL_FINNISH , 0 },
- { "french", VTL_FRENCH , 0 },
- { "french-canadian",VTL_FR_CAN , 0 },
- { "german", VTL_GERMAN , 0 },
- { "greek", VTL_GREEK , 0 },
- { "hebrew", VTL_HEBREW , 0 },
- { "hungarian", VTL_HUNGARIA, 0 },
- { "italian", VTL_ITALIAN , 0 },
- { "latin-american", VTL_LATIN_AM, 0 },
- { "north-american", VTL_NORTH_AM, 0 },
- { "norwegian", VTL_NORWEGIA, 0 },
- { "polish", VTL_POLISH , 0 },
- { "portugese", VTL_PORTUGES, 0 },
- { "romanian", VTL_ROMANIAN, 0 },
- { "russian", VTL_RUSSIAN , 0 },
- { "scs", VTL_SCS , CM_INV },
- { "slovak", VTL_SLOVAK , 0 },
- { "spanish", VTL_SPANISH , 0 },
- { "swedish", VTL_SWEDISH , 0 },
- { "swiss-french", VTL_SW_FR , 0 },
- { "swiss-german", VTL_SW_GR , 0 },
- { "turkish-f", VTL_TURK_F , CM_INV },
- { "turkish-q", VTL_TURK_Q , CM_INV }
-};
-int nvtlangtab = (sizeof(vtlangtab) / sizeof(struct keytab));
-#endif /* NOCSETS */
-#endif /* OS2 */
-
-struct keytab crdtab[] = { /* Carriage-return display */
- { "crlf", 1, 0 },
- { "normal", 0, 0 }
-};
-extern int tt_crd; /* Carriage-return display variable */
-extern int tt_lfd; /* Linefeed display variable */
-
-#ifdef CK_APC
-extern int apcstatus, apcactive;
-static struct keytab apctab[] = { /* Terminal APC parameters */
- { "no-input", APC_ON|APC_NOINP,0 },
- { "off", APC_OFF, 0 },
- { "on", APC_ON, 0 },
- { "unchecked", APC_ON|APC_UNCH, 0 },
- { "unchecked-no-input", APC_ON|APC_NOINP|APC_UNCH, 0 }
-};
-int napctab = (sizeof(apctab) / sizeof(struct keytab));
-#endif /* CK_APC */
-#endif /* NOLOCAL */
-
-extern int autodl, adl_err, adl_ask;
-
-struct keytab beltab[] = { /* Terminal bell mode */
-#ifdef OS2
- { "audible", XYB_AUD, 0 },
- { "none", XYB_NONE, 0 },
-#else
- { "audible", XYB_AUD, CM_INV },
- { "none", XYB_NONE, CM_INV },
-#endif /* OS2 */
-#ifdef OS2
- { "off", XYB_NONE, CM_INV },
- { "on", XYB_AUD, CM_INV },
-#else
- { "off", XYB_NONE, 0 },
- { "on", XYB_AUD, 0 },
-#endif /* OS2 */
-#ifdef OS2
- { "visible", XYB_VIS, 0 },
-#endif /* OS2 */
- { "", 0, 0 }
-};
-int nbeltab = sizeof(beltab)/sizeof(struct keytab) - 1;
-
-int tt_unicode = 1; /* Use Unicode if possible */
-#ifdef CKTIDLE
-int tt_idlesnd_tmo = 0; /* Idle Send Timeout, disabled */
-char * tt_idlesnd_str = NULL; /* Idle Send String, none */
-char * tt_idlestr = NULL;
-extern int tt_idleact, tt_idlelimit;
-#endif /* CKTIDLE */
-
-#ifdef OS2
-#ifndef NOLOCAL
-/*
- OS/2 serial communication devices.
-*/
-struct keytab os2devtab[] = {
- { "1", 1, CM_INV }, /* Invisible synonyms, like */
- { "2", 2, CM_INV }, /* "set port 1" */
- { "3", 3, CM_INV },
- { "4", 4, CM_INV },
- { "5", 5, CM_INV },
- { "6", 6, CM_INV },
- { "7", 7, CM_INV },
- { "8", 8, CM_INV },
- { "com1", 1, 0 }, /* Real device names */
- { "com2", 2, 0 },
- { "com3", 3, 0 },
- { "com4", 4, 0 },
- { "com5", 5, 0 },
- { "com6", 6, 0 },
- { "com7", 7, 0 },
- { "com8", 8, 0 },
-#ifdef OS2ONLY
- { "slipcom1", 1, 0 }, /* For use with SLIP driver */
- { "slipcom2", 2, 0 }, /* shared access */
- { "slipcom3", 3, 0 },
- { "slipcom4", 4, 0 },
- { "slipcom5", 5, 0 },
- { "slipcom6", 6, 0 },
- { "slipcom7", 7, 0 },
- { "slipcom8", 8, 0 },
- { "pppcom1", 1, 0 }, /* For use with PPP driver */
- { "pppcom2", 2, 0 }, /* shared access */
- { "pppcom3", 3, 0 },
- { "pppcom4", 4, 0 },
- { "pppcom5", 5, 0 },
- { "pppcom6", 6, 0 },
- { "pppcom7", 7, 0 },
- { "pppcom8", 8, 0 }
-#endif /* OS2ONLY */
-};
-int nos2dev = (sizeof(os2devtab) / sizeof(struct keytab)) - 1;
-
-#ifdef OS2ONLY
-struct keytab os2ppptab[] = {
- { "0", 0, CM_INV },
- { "1", 1, CM_INV }, /* Invisible synonyms, like */
- { "2", 2, CM_INV }, /* "set port 1" */
- { "3", 3, CM_INV },
- { "4", 4, CM_INV },
- { "5", 5, CM_INV },
- { "6", 6, CM_INV },
- { "7", 7, CM_INV },
- { "8", 8, CM_INV },
- { "9", 9, CM_INV },
- { "ppp0", 0, 0 },
- { "ppp1", 1, 0 }, /* For use with PPP driver */
- { "ppp2", 2, 0 }, /* shared access */
- { "ppp3", 3, 0 },
- { "ppp4", 4, 0 },
- { "ppp5", 5, 0 },
- { "ppp6", 6, 0 },
- { "ppp7", 7, 0 },
- { "ppp8", 8, 0 },
- { "ppp9", 9, 0 }
-};
-int nos2ppp = (sizeof(os2ppptab) / sizeof(struct keytab));
-#endif /* OS2ONLY */
-
-/*
- Terminal parameters that can be set by SET commands.
- Used by the ck?con.c terminal emulator code.
- For now, only used for #ifdef OS2. Should add these for Macintosh.
-*/
-int tt_arrow = TTK_NORM; /* Arrow key mode: normal (cursor) */
-int tt_keypad = TTK_NORM; /* Keypad mode: normal (numeric) */
-int tt_shift_keypad = 0; /* Keypad Shift mode: Off */
-int tt_wrap = 1; /* Terminal wrap, 1 = On */
-int tt_type = TT_VT220; /* Terminal type, initially VT220 */
-int tt_type_mode = TT_VT220; /* Terminal type set by host command */
-int tt_cursor = 0; /* Terminal cursor, 0 = Underline */
-int tt_cursor_usr = 0; /* Users Terminal cursor type */
-int tt_cursorena_usr = 1; /* Users Terminal cursor enabled */
-int tt_cursor_blink = 1; /* Terminal Cursor Blink */
-int tt_answer = 0; /* Terminal answerback (disabled) */
-int tt_scrsize[VNUM] = {512,512,512,1}; /* Terminal scrollback buffer size */
-int tt_roll[VNUM] = {1,1,1,1}; /* Terminal roll (on) */
-int tt_rkeys[VNUM] = {1,1,1,1}; /* Terminal roll keys (send) */
-int tt_pacing = 0; /* Terminal output-pacing (none) */
-int tt_ctstmo = 15; /* Terminal transmit-timeout */
-int tt_codepage = -1; /* Terminal code-page */
-int tt_update = 100; /* Terminal screen-update interval */
-int tt_updmode = TTU_FAST; /* Terminal screen-update mode FAST */
-extern int updmode;
-#ifndef KUI
-int tt_status[VNUM] = {1,1,0,0}; /* Terminal status line displayed */
-int tt_status_usr[VNUM] = {1,1,0,0};
-#else /* KUI */
-extern CKFLOAT floatval;
-CKFLOAT tt_linespacing[VNUM] = {1.0,1.0,1.0,1.0};
-#ifdef K95G
-int tt_status[VNUM] = {1,1,0,0}; /* Terminal status line displayed */
-int tt_status_usr[VNUM] = {1,1,0,0};
-#else /* K95G */
-int tt_status[VNUM] = {0,0,0,0}; /* Terminal status line displayed */
-int tt_status_usr[VNUM] = {0,0,0,0};
-#endif /* K95G */
-#endif /* KUI */
-int tt_senddata = 0; /* Let host read terminal data */
-extern int wy_blockend; /* Terminal Send Data EOB type */
-int tt_hidattr = 1; /* Attributes are hidden */
-
-extern unsigned char colornormal, colorselect,
-colorunderline, colorstatus, colorhelp, colorborder,
-colorgraphic, colordebug, colorreverse, coloritalic;
-
-extern int trueblink, trueunderline, truereverse, trueitalic, truedim;
-
-extern int bgi, fgi;
-extern int scrninitialized[];
-
-struct keytab audibletab[] = { /* Terminal Bell Audible mode */
- { "beep", XYB_BEEP, 0 }, /* Values ORd with bell mode */
- { "system-sounds", XYB_SYS, 0 }
-};
-int naudibletab = sizeof(audibletab)/sizeof(struct keytab);
-
-struct keytab akmtab[] = { /* Arrow key mode */
- { "application", TTK_APPL, 0 },
- { "cursor", TTK_NORM, 0 }
-};
-struct keytab kpmtab[] = { /* Keypad mode */
- { "application", TTK_APPL, 0 },
- { "numeric", TTK_NORM, 0 }
-};
-
-struct keytab ttcolmodetab[] = {
- { "current-color", 0, 0 },
- { "default-color", 1, 0 }
-};
-int ncolmode = sizeof(ttcolmodetab)/sizeof(struct keytab);
-
-#define TTCOLNOR 0
-#define TTCOLREV 1
-#define TTCOLUND 2
-#define TTCOLSTA 3
-#define TTCOLHLP 4
-#define TTCOLBOR 5
-#define TTCOLSEL 6
-#define TTCOLDEB 7
-#define TTCOLGRP 8
-#define TTCOLITA 9
-#define TTCOLRES 10
-#define TTCOLERA 11
-
-struct keytab ttycoltab[] = { /* Terminal Screen coloring */
- { "border", TTCOLBOR, 0 }, /* Screen border color */
- { "debug-terminal", TTCOLDEB, 0 }, /* Debug color */
- { "erase", TTCOLERA, 0 }, /* Erase mode */
- { "graphic", TTCOLGRP, 0 }, /* Graphic Color */
- { "help-text", TTCOLHLP, 0 }, /* Help screens */
- { "italic", TTCOLITA, 0 }, /* Italic Color */
- { "normal", TTCOLNOR, CM_INV }, /* Normal screen text */
- { "reset-on-esc[0m", TTCOLRES, 0 }, /* Reset on ESC [ 0 m */
- { "reverse-video", TTCOLREV, 0 }, /* Reverse video */
- { "status-line", TTCOLSTA, 0 }, /* Status line */
- { "selection", TTCOLSEL, 0 }, /* Selection color */
- { "terminal-screen", TTCOLNOR, 0 }, /* Better name than "normal" */
- { "underlined-text", TTCOLUND, 0 } /* Underlined text */
-};
-int ncolors = (sizeof(ttycoltab) / sizeof(struct keytab));
-
-#define TTATTNOR 0
-#define TTATTBLI 1
-#define TTATTREV 2
-#define TTATTUND 3
-#define TTATTPRO 4
-#define TTATTBLD 5
-#define TTATTDIM 6
-#define TTATTINV 7
-#define TTATTITA 8
-#define TTATTDONE 9
-
-struct keytab ttyattrtab[] = {
- { "blink", TTATTBLI, 0 },
- { "dim", TTATTDIM, 0 },
- { "italic", TTATTITA, 0 },
- { "protected", TTATTPRO, 0 },
- { "reverse", TTATTREV, 0 },
- { "underline", TTATTUND, 0 }
-};
-int nattrib = (sizeof(ttyattrtab) / sizeof(struct keytab));
-
-struct keytab ttyprotab[] = {
- { "blink", TTATTBLI, 0 },
- { "bold", TTATTBLD, 0 },
- { "dim", TTATTDIM, 0 },
- { "done", TTATTDONE, CM_INV },
- { "invisible", TTATTINV, 0 },
- { "italic", TTATTITA, 0 },
- { "normal", TTATTNOR, 0 },
- { "reverse", TTATTREV, 0 },
- { "underlined", TTATTUND, 0 }
-
-};
-int nprotect = (sizeof(ttyprotab) / sizeof(struct keytab));
-
-struct keytab ttyseobtab[] = {
- { "crlf_etx", 1, 0 },
- { "us_cr", 0, 0 }
-};
-
-struct keytab ttyclrtab[] = { /* Colors */
- { "black", 0, 0 },
- { "blue", 1, 0 },
- { "brown", 6, 0 },
- { "cyan", 3, 0 },
- { "darkgray", 8, CM_INV },
- { "dgray", 8, 0 },
- { "green", 2, 0 },
- { "lblue", 9, CM_INV },
- { "lcyan", 11, CM_INV },
- { "lgray", 7, CM_INV },
- { "lgreen", 10, CM_INV },
- { "lightblue", 9, 0 },
- { "lightcyan", 11, 0 },
- { "lightgray", 7, 0 },
- { "lightgreen", 10, 0 },
- { "lightmagenta", 13, 0 },
- { "lightred", 12, 0 },
- { "lmagenta", 13, CM_INV },
- { "lred", 12, CM_INV },
- { "magenta", 5, 0 },
- { "red", 4, 0 },
- { "white", 15, 0 },
- { "yellow", 14, 0 }
-};
-int nclrs = (sizeof (ttyclrtab) / sizeof (struct keytab));
-
-struct keytab ttycurtab[] = {
- { "full", TTC_BLOCK, 0 },
- { "half", TTC_HALF, 0 },
- { "underline", TTC_ULINE, 0 }
-};
-int ncursors = 3;
-
-struct keytab ttyptab[] = {
- { "aaa", TT_AAA, CM_INV }, /* AnnArbor */
- { "adm3a", TT_ADM3A, 0 }, /* LSI ADM-3A */
- { "adm5", TT_ADM5, 0 }, /* LSI ADM-5 */
- { "aixterm", TT_AIXTERM, 0 }, /* IBM AIXterm */
- { "annarbor", TT_AAA, 0 }, /* AnnArbor */
- { "ansi-bbs", TT_ANSI, 0 }, /* ANSI.SYS (BBS) */
- { "at386", TT_AT386, 0 }, /* Unixware ANSI */
- { "avatar/0+",TT_ANSI, 0 }, /* AVATAR/0+ */
- { "ba80", TT_BA80, 0 }, /* Nixdorf BA80 */
- { "be", TT_BEOS, CM_INV|CM_ABR },
- { "beos-ansi",TT_BEOS, CM_INV }, /* BeOS ANSI */
- { "beterm", TT_BEOS, 0 }, /* BeOS Terminal (as of PR2 ) */
- { "d200", TT_DG200, CM_INV|CM_ABR }, /* Data General DASHER 200 */
- { "d210", TT_DG210, CM_INV|CM_ABR }, /* Data General DASHER 210 */
- { "d217", TT_DG217, CM_INV|CM_ABR }, /* Data General DASHER 217 */
- { "dg200", TT_DG200, 0 }, /* Data General DASHER 200 */
- { "dg210", TT_DG210, 0 }, /* Data General DASHER 210 */
- { "dg217", TT_DG217, 0 }, /* Data General DASHER 217 */
- { "h1500", TT_HZL1500, CM_INV }, /* Hazeltine 1500 */
- { "h19", TT_H19, CM_INV }, /* Heath-19 */
- { "heath19", TT_H19, 0 }, /* Heath-19 */
- { "hft", TT_HFT, 0 }, /* IBM High Function Terminal */
- { "hp2621a", TT_HP2621, 0 }, /* HP 2621A */
- { "hpterm", TT_HPTERM, 0 }, /* HP TERM */
- { "hz1500", TT_HZL1500, 0 }, /* Hazeltine 1500 */
- { "ibm3151", TT_IBM31, 0 }, /* IBM 3101-xx,3161 */
- { "linux", TT_LINUX, 0 }, /* Linux */
- { "qansi", TT_QANSI, 0 }, /* QNX ANSI */
- { "qnx", TT_QNX, 0 }, /* QNX Console */
- { "scoansi", TT_SCOANSI, 0 }, /* SCO ANSI */
- { "sni-97801",TT_97801, 0 }, /* SNI 97801 */
- { "sun", TT_SUN, 0 }, /* SUN Console */
-/*
- The idea of NONE is to let the console driver handle the escape sequences,
- which, in theory at least, would give not only ANSI emulation, but also any
- other kind of emulation that might be provided by alternative console
- drivers, if any existed.
-
- For this to work, ckocon.c would need to be modified to make higher-level
- calls, like VioWrtTTY(), DosWrite(), or (simply) write(), rather than
- VioWrt*Cell() and similar, and it would also have to give up its rollback
- feature, and its status line and help screens would also have to be
- forgotten or else done in an ANSI way.
-
- As matters stand, we already have perfectly good ANSI emulation built in,
- and there are no alternative console drivers available, so there is no point
- in having a terminal type of NONE, so it is commented out. However, should
- you uncomment it, it will work like a "glass tty" -- no escape sequence
- interpretation at all; somewhat similar to debug mode, except without the
- debugging (no highlighting of control chars or escape sequences); help
- screens, status line, and rollback will still work.
-*/
-#ifdef OS2PM
-#ifdef COMMENT
- { "tek4014", TT_TEK40, 0 },
-#endif /* COMMENT */
-#endif /* OS2PM */
- { "tty", TT_NONE, 0 },
- { "tvi910+", TT_TVI910, 0 },
- { "tvi925", TT_TVI925, 0 },
- { "tvi950", TT_TVI950, 0 },
- { "vc404", TT_VC4404, 0 },
- { "vc4404", TT_VC4404, CM_INV },
- { "vip7809", TT_VIP7809,0 },
- { "vt100", TT_VT100, 0 },
- { "vt102", TT_VT102, 0 },
- { "vt220", TT_VT220, 0 },
- { "vt220pc", TT_VT220PC,0 },
- { "vt320", TT_VT320, 0 },
- { "vt320pc", TT_VT320PC,0 },
- { "vt52", TT_VT52, 0 },
-#ifdef NT
- { "vtnt", TT_VTNT, 0 },
-#else /* NT */
- { "vtnt", TT_VTNT, CM_INV },
-#endif /* NT */
- { "wy160", TT_WY160, 0 },
- { "wy30", TT_WY30, 0 },
- { "wy370", TT_WY370, 0 },
- { "wy50", TT_WY50, 0 },
- { "wy60", TT_WY60, 0 },
- { "wyse30", TT_WY30, CM_INV },
- { "wyse370", TT_WY370, CM_INV },
- { "wyse50", TT_WY50, CM_INV },
- { "wyse60", TT_WY60, CM_INV }
-};
-int nttyp = (sizeof(ttyptab) / sizeof(struct keytab));
-
-struct keytab ttkeytab[] = {
- { "aaa", TT_AAA, CM_INV }, /* AnnArbor */
- { "adm3a", TT_ADM3A, 0 }, /* LSI ADM-3A */
- { "adm5", TT_ADM5, 0 }, /* LSI ADM-5 */
- { "aixterm", TT_AIXTERM, 0 }, /* IBM AIXterm */
- { "annarbor", TT_AAA, 0 }, /* AnnArbor */
- { "ansi-bbs", TT_ANSI, 0 }, /* ANSI.SYS (BBS) */
- { "at386", TT_AT386, 0 }, /* Unixware ANSI */
- { "avatar/0+", TT_ANSI, 0 }, /* AVATAR/0+ */
- { "ba80", TT_BA80, 0 }, /* Nixdorf BA80 */
- { "be", TT_BEOS, CM_INV|CM_ABR },
- { "beos-ansi", TT_BEOS, CM_INV }, /* BeOS ANSI */
- { "beterm", TT_BEOS, 0 }, /* BeOS Terminal (DR2) */
- { "d200", TT_DG200, CM_INV|CM_ABR }, /* DG DASHER 200 */
- { "d210", TT_DG210, CM_INV|CM_ABR }, /* DG DASHER 210 */
- { "d217", TT_DG217, CM_INV|CM_ABR }, /* DG DASHER 217 */
- { "dg200", TT_DG200, 0 }, /* DG DASHER 200 */
- { "dg210", TT_DG210, 0 }, /* DG DASHER 210 */
- { "dg217", TT_DG217, 0 }, /* DG DASHER 217 */
- { "emacs", TT_KBM_EMACS, 0 }, /* Emacs mode */
- { "h19", TT_H19, CM_INV }, /* Heath-19 */
- { "heath19", TT_H19, 0 }, /* Heath-19 */
- { "hebrew", TT_KBM_HEBREW, 0 }, /* Hebrew mode */
- { "hft", TT_HFT, 0 }, /* IBM High Function Term */
- { "hp2621a", TT_HP2621, 0 }, /* HP 2621A */
- { "hpterm", TT_HPTERM, 0 }, /* HP TERM */
- { "hz1500", TT_HZL1500, 0 }, /* Hazeltine 1500 */
- { "ibm3151", TT_IBM31, 0 }, /* IBM 3101-xx,3161 */
- { "linux", TT_LINUX, 0 }, /* Linux */
- { "qansi", TT_QANSI, 0 }, /* QNX ANSI */
- { "qnx", TT_QNX, 0 }, /* QNX */
- { "russian", TT_KBM_RUSSIAN,0 }, /* Russian mode */
- { "scoansi", TT_SCOANSI, 0 }, /* SCO ANSI */
- { "sni-97801", TT_97801, 0 }, /* SNI 97801 */
- { "sun", TT_SUN, 0 }, /* SUN Console */
-#ifdef OS2PM
-#ifdef COMMENT
- { "tek4014", TT_TEK40, 0 },
-#endif /* COMMENT */
-#endif /* OS2PM */
- { "tty", TT_NONE, 0 },
- { "tvi910+", TT_TVI910, 0 },
- { "tvi925", TT_TVI925, 0 },
- { "tvi950", TT_TVI950, 0 },
- { "vc404", TT_VC4404, 0 },
- { "vc4404", TT_VC4404, CM_INV },
- { "vip7809", TT_VIP7809, 0 },
- { "vt100", TT_VT100, 0 },
- { "vt102", TT_VT102, 0 },
- { "vt220", TT_VT220, 0 },
- { "vt220pc", TT_VT220PC, 0 },
- { "vt320", TT_VT320, 0 },
- { "vt320pc", TT_VT320PC, 0 },
- { "vt52", TT_VT52, 0 },
- { "vtnt", TT_VTNT, CM_INV },
- { "wp", TT_KBM_WP, 0 }, /* Word Perfect mode */
- { "wy160", TT_WY160, 0 },
- { "wy30", TT_WY30, 0 },
- { "wy370", TT_WY370, 0 },
- { "wy50", TT_WY50, 0 },
- { "wy60", TT_WY60, 0 },
- { "wyse30", TT_WY30, CM_INV },
- { "wyse370", TT_WY370, CM_INV },
- { "wyse50", TT_WY50, CM_INV },
- { "wyse60", TT_WY60, CM_INV }
-};
-int nttkey = (sizeof(ttkeytab) / sizeof(struct keytab));
-
-#ifndef NOSETKEY
-struct keytab kbmodtab[] = {
- { "emacs", KBM_EM, 0 },
- { "english", KBM_EN, CM_INV },
- { "hebrew", KBM_HE, 0 },
- { "normal", KBM_EN, 0 },
- { "none", KBM_EN, CM_INV },
- { "russian", KBM_RU, 0 },
- { "wp", KBM_WP, 0 }
-};
-int nkbmodtab = (sizeof(kbmodtab) / sizeof(struct keytab));
-#endif /* NOSETKEY */
-#endif /* NOLOCAL */
-
-int tt_inpacing = 0; /* input-pacing (none) */
-
-struct keytab prtytab[] = { /* OS/2 Priority Levels */
- { "foreground-server", XYP_SRV, 0 },
- { "idle", XYP_IDLE, CM_INV },
- { "regular", XYP_REG, 0 },
- { "time-critical", XYP_RTP, 0 }
-};
-int nprty = (sizeof(prtytab) / sizeof(struct keytab));
-#endif /* OS2 */
-
-#ifdef NT
-struct keytab win95tab[] = { /* Win95 work-arounds */
- { "8.3-filenames", XYW8_3, 0 },
- { "alt-gr", XYWAGR, 0 },
- { "horizontal-scan-line-substitutions", XYWHSL, 0 },
- { "keyboard-translation", XYWKEY, 0 },
- { "lucida-substitutions", XYWLUC, 0 },
- { "overlapped-io", XYWOIO, 0 },
- { "popups", XYWPOPUP, 0 },
- { "select-bug", XYWSELECT, 0 }
-};
-int nwin95 = (sizeof(win95tab) / sizeof(struct keytab));
-#endif /* NT */
-
-#ifdef OS2MOUSE
-extern int wideresult;
-int tt_mouse = 1; /* Terminal mouse on/off */
-
-struct keytab mousetab[] = { /* Mouse items */
- { "activate", XYM_ON, 0 },
- { "button", XYM_BUTTON, 0 },
- { "clear", XYM_CLEAR, 0 },
- { "debug", XYM_DEBUG, 0 }
-};
-int nmtab = (sizeof(mousetab)/sizeof(struct keytab));
-
-struct keytab mousebuttontab[] = { /* event button */
- { "1", XYM_B1, 0 },
- { "2", XYM_B2, 0 },
- { "3", XYM_B3, 0 },
- { "one", XYM_B1, CM_INV },
- { "three", XYM_B3, CM_INV },
- { "two", XYM_B2, CM_INV }
-};
-int nmbtab = (sizeof(mousebuttontab) / sizeof(struct keytab));
-
-struct keytab mousemodtab[] = { /* event button key modifier */
- { "alt", XYM_ALT, 0 },
- { "alt-shift", XYM_SHIFT|XYM_ALT, 0 },
- { "ctrl", XYM_CTRL, 0 },
- { "ctrl-alt", XYM_CTRL|XYM_ALT, 0 },
- { "ctrl-alt-shift", XYM_CTRL|XYM_SHIFT|XYM_ALT, 0 },
- { "ctrl-shift", XYM_CTRL|XYM_SHIFT, 0 },
- { "none", 0, 0 },
- { "shift", XYM_SHIFT, 0 }
-};
-int nmmtab = (sizeof(mousemodtab) / sizeof(struct keytab));
-
-struct keytab mclicktab[] = { /* event button click modifier */
- { "click", XYM_C1, 0 },
- { "drag", XYM_DRAG, 0 },
- { "double-click", XYM_C2, 0 }
-};
-int nmctab = (sizeof(mclicktab) / sizeof(struct keytab));
-
-#ifndef NOKVERBS
-extern int nkverbs;
-extern struct keytab kverbs[];
-#endif /* NOKVERBS */
-#endif /* OS2MOUSE */
-
-/* #ifdef VMS */
-struct keytab fbtab[] = { /* Binary record types for VMS */
- { "fixed", XYFT_B, 0 }, /* Fixed is normal for binary */
- { "undefined", XYFT_U, 0 } /* Undefined if they ask for it */
-};
-int nfbtyp = (sizeof(fbtab) / sizeof(struct keytab));
-/* #endif */
-
-#ifdef VMS
-struct keytab lbltab[] = { /* Labeled File info */
- { "acl", LBL_ACL, 0 },
- { "backup-date", LBL_BCK, 0 },
- { "name", LBL_NAM, 0 },
- { "owner", LBL_OWN, 0 },
- { "path", LBL_PTH, 0 }
-};
-int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
-#else
-#ifdef OS2
-struct keytab lbltab[] = { /* Labeled File info */
- { "archive", LBL_ARC, 0 },
- { "extended", LBL_EXT, 0 },
- { "hidden", LBL_HID, 0 },
- { "read-only", LBL_RO, 0 },
- { "system", LBL_SYS, 0 }
-};
-int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
-#endif /* OS2 */
-#endif /* VMS */
-
-#ifdef CK_CURSES
-#ifdef CK_PCT_BAR
-static struct keytab fdftab[] = { /* SET FILE DISPLAY FULL options */
- { "thermometer", 1, 0, },
- { "no-thermometer", 0, 0 }
-};
-extern int thermometer;
-#endif /* CK_PCT_BAR */
-#endif /* CK_CURSES */
-
-static struct keytab fdtab[] = { /* SET FILE DISPLAY options */
-#ifdef MAC /* Macintosh */
- { "fullscreen", XYFD_R, 0 }, /* Full-screen but not curses */
- { "none", XYFD_N, 0 },
- { "off", XYFD_N, CM_INV },
- { "on", XYFD_R, CM_INV },
- { "quiet", XYFD_N, CM_INV },
-#else /* Not Mac */
- { "brief", XYFD_B, 0 }, /* Brief */
- { "crt", XYFD_S, 0 }, /* CRT display */
-#ifdef CK_CURSES
-#ifdef COMMENT
- { "curses", XYFD_C, CM_INV }, /* Full-screen, curses */
-#endif /* COMMENT */
- { "fullscreen", XYFD_C, 0 }, /* Full-screen, whatever the method */
-#endif /* CK_CURSES */
-#ifdef KUI
- { "gui", XYFD_G, 0 }, /* GUI */
-#endif /* KUI */
- { "none", XYFD_N, 0 }, /* No display */
- { "off", XYFD_N, CM_INV }, /* Ditto */
- { "on", XYFD_R, CM_INV }, /* On = Serial */
- { "quiet", XYFD_N, CM_INV }, /* No display */
- { "serial", XYFD_R, 0 }, /* Serial */
-#endif /* MAC */
- { "", 0, 0 }
-};
-int nfdtab = (sizeof(fdtab) / sizeof(struct keytab)) - 1;
-
-struct keytab rsrtab[] = { /* For REMOTE SET RECEIVE */
- { "packet-length", XYLEN, 0 },
- { "timeout", XYTIMO, 0 }
-};
-int nrsrtab = (sizeof(rsrtab) / sizeof(struct keytab));
-
-/* Send/Receive Parameters */
-
-struct keytab srtab[] = {
- { "backup", XYBUP, 0 },
-#ifndef NOCSETS
- { "character-set-selection", XYCSET, 0 },
-#endif /* NOCSETS */
- { "control-prefix", XYQCTL, 0 },
-#ifdef CKXXCHAR
- { "double-character", XYDBL, 0 },
-#endif /* CKXXCHAR */
- { "end-of-packet", XYEOL, 0 },
-#ifdef PIPESEND
- { "filter", XYFLTR, 0 },
-#endif /* PIPESEND */
-#ifdef CKXXCHAR
- { "ignore-character", XYIGN, 0 },
-#endif /* CKXXCHAR */
- { "i-packets", 993, 0 },
- { "move-to", XYMOVE, 0 },
- { "negotiation-string-max-length", XYINIL, CM_INV },
- { "packet-length", XYLEN, 0 },
- { "pad-character", XYPADC, 0 },
- { "padding", XYNPAD, 0 },
- { "pathnames", XYFPATH, 0 },
- { "pause", XYPAUS, 0 },
-#ifdef CK_PERMS
- { "permissions", 994, 0}, /* 206 */
-#endif /* CK_PERMS */
- { "quote", XYQCTL, CM_INV }, /* = CONTROL-PREFIX */
- { "rename-to", XYRENAME, 0 },
- { "start-of-packet", XYMARK, 0 },
- { "timeout", XYTIMO, 0 },
-#ifdef VMS
- { "version-numbers", 887, 0 }, /* VMS version numbers */
-#endif /* VMS */
- { "", 0, 0 }
-};
-int nsrtab = (sizeof(srtab) / sizeof(struct keytab)) - 1;
-
-#ifdef UNICODE
-#define UCS_BOM 1
-#define UCS_BYT 2
-static struct keytab ucstab[] = {
- { "bom", UCS_BOM, 0 },
- { "byte-order", UCS_BYT, 0 },
- { "", 0, 0 }
-};
-int nucstab = (sizeof(ucstab) / sizeof(struct keytab)) - 1;
-
-static struct keytab botab[] = {
- { "big-endian", 0, 0 },
- { "little-endian", 1, 0 }
-};
-static int nbotab = 2;
-#endif /* UNICODE */
-
-/* REMOTE SET */
-
-struct keytab rmstab[] = {
- { "attributes", XYATTR, 0 },
- { "block-check", XYCHKT, 0 },
- { "file", XYFILE, 0 },
- { "incomplete", XYIFD, CM_INV }, /* = REMOTE SET FILE INCOMPLETE */
- { "match", XYMATCH,0 },
- { "receive", XYRECV, 0 },
- { "retry", XYRETR, 0 },
- { "server", XYSERV, 0 },
- { "transfer", XYXFER, 0 },
- { "window", XYWIND, 0 },
- { "xfer", XYXFER, CM_INV }
-};
-int nrms = (sizeof(rmstab) / sizeof(struct keytab));
-
-struct keytab attrtab[] = {
-#ifdef STRATUS
- { "account", AT_ACCT, 0 },
-#endif /* STRATUS */
- { "all", AT_XALL, 0 },
-#ifdef COMMENT
- { "blocksize", AT_BLKS, 0 }, /* (not used) */
-#endif /* COMMENT */
-#ifndef NOCSETS
- { "character-set", AT_ENCO, 0 },
-#endif /* NOCSETS */
-#ifdef STRATUS
- { "creator", AT_CREA, 0 },
-#endif /* STRATUS */
- { "date", AT_DATE, 0 },
- { "disposition", AT_DISP, 0 },
- { "encoding", AT_ENCO, CM_INV },
- { "format", AT_RECF, CM_INV },
- { "length", AT_LENK, 0 },
- { "off", AT_ALLN, 0 },
- { "on", AT_ALLY, 0 },
-#ifdef COMMENT
- { "os-specific", AT_SYSP, 0 }, /* (not used by UNIX or VMS) */
-#endif /* COMMENT */
-#ifdef CK_PERMS
- { "protection", AT_LPRO, 0 },
- { "permissions", AT_LPRO, CM_INV },
-#endif /* CK_PERMS */
- { "record-format", AT_RECF, 0 },
- { "system-id", AT_SYSI, 0 },
- { "type", AT_FTYP, 0 }
-};
-int natr = (sizeof(attrtab) / sizeof(struct keytab)); /* how many attributes */
-
-#ifdef CKTIDLE
-struct keytab idlacts[] = {
- { "exit", IDLE_EXIT, 0 },
- { "hangup", IDLE_HANG, 0 },
- { "output", IDLE_OUT, 0 },
- { "return", IDLE_RET, 0 },
-#ifdef TNCODE
- { "telnet-nop", IDLE_TNOP, 0 },
- { "telnet-ayt", IDLE_TAYT, 0 },
-#endif /* TNCODE */
- { "", 0, 0 }
-};
-int nidlacts = (sizeof(idlacts) / sizeof(struct keytab)) - 1;
-#endif /* CKTIDLE */
-
-#ifndef NOSPL
-extern int indef, inecho, insilence, inbufsize, inautodl, inintr;
-#ifdef CKFLOAT
-extern CKFLOAT inscale;
-#endif /* CKFLOAT */
-extern char * inpbuf, * inpbp;
-#ifdef OS2
-extern int interm;
-#endif /* OS2 */
-struct keytab inptab[] = { /* SET INPUT parameters */
-#ifdef CK_AUTODL
- { "autodownload", IN_ADL, 0 },
-#endif /* CK_AUTODL */
- { "buffer-length", IN_BUF, 0 },
- { "cancellation", IN_CAN, 0 },
- { "case", IN_CAS, 0 },
- { "default-timeout", IN_DEF, CM_INV }, /* There is no default timeout */
- { "echo", IN_ECH, 0 },
-#ifdef OS2
- { "pacing", IN_PAC, CM_INV },
-#endif /* OS2 */
- { "scale-factor", IN_SCA, 0 },
- { "silence", IN_SIL, 0 },
-#ifdef OS2
- { "terminal", IN_TRM, 0 },
-#endif /* OS2 */
- { "timeout-action", IN_TIM, 0 }
-};
-int ninp = (sizeof(inptab) / sizeof(struct keytab));
-
-struct keytab intimt[] = { /* SET INPUT TIMEOUT parameters */
- { "proceed", 0, 0 }, /* 0 = proceed */
- { "quit", 1, 0 } /* 1 = quit */
-};
-
-struct keytab incast[] = { /* SET INPUT CASE parameters */
- { "ignore", 0, 0 }, /* 0 = ignore */
- { "observe", 1, 0 } /* 1 = observe */
-};
-#endif /* NOSPL */
-
-struct keytab nabltab[] = { /* For any command that needs */
- { "disabled", 0, 0 },
- { "enabled", 1, 0 },
- { "off", 0, CM_INV }, /* these keywords... */
- { "on", 1, CM_INV }
-};
-int nnabltab = sizeof(nabltab) / sizeof(struct keytab);
-
-#ifdef OS2
-struct keytab tvctab[] = { /* SET TERM VIDEO-CHANGE */
- { "disabled", TVC_DIS, 0 },
- { "enabled", TVC_ENA, 0 },
-#ifdef NT
- { "win95-safe", TVC_W95, 0 },
-#endif /* NT */
- { "", 0, 0 }
-};
-int ntvctab = (sizeof(tvctab) / sizeof(struct keytab)) - 1;
-
-struct keytab msktab[] = { /* SET MS-DOS KERMIT compatibilities */
-#ifdef COMMENT
- { "color", MSK_COLOR, 0 },
-#endif /* COMMENT */
- { "file-renaming", MSK_REN, 0 },
- { "keycodes", MSK_KEYS, 0 }
-};
-int nmsk = (sizeof(msktab) / sizeof(struct keytab));
-
-struct keytab scrnupd[] = { /* SET TERMINAL SCREEN-UPDATE */
- { "fast", TTU_FAST, 0 },
- { "smooth", TTU_SMOOTH, 0 }
-};
-int nscrnupd = (sizeof(scrnupd) / sizeof(struct keytab));
-
-#ifdef PCFONTS
-/* This definition of the term_font[] table is only for */
-/* the OS/2 Full Screen Session and is not used on Windows */
-struct keytab term_font[] = { /* SET TERMINAL FONT */
-#ifdef COMMENT
- { "cp111", TTF_111, 0 },
- { "cp112", TTF_112, 0 },
- { "cp113", TTF_113, 0 },
-#endif /* COMMENT */
- { "cp437", TTF_437, 0 },
- { "cp850", TTF_850, 0 },
-#ifdef COMMENT
- { "cp851", TTF_851, 0 },
-#endif /* COMMENT */
- { "cp852", TTF_852, 0 },
-#ifdef COMMENT
- { "cp853", TTF_853, 0 },
- { "cp860", TTF_860, 0 },
- { "cp861", TTF_861, 0 },
-#endif /* COMMENT */
- { "cp862", TTF_862, 0 },
-#ifdef COMMENT
- { "cp863", TTF_863, 0 },
- { "cp864", TTF_864, 0 },
- { "cp865", TTF_865, 0 },
-#endif /* COMMENT */
- { "cp866", TTF_866, 0 },
-#ifdef COMMENT
- { "cp880", TTF_880, 0 },
- { "cp881", TTF_881, 0 },
- { "cp882", TTF_882, 0 },
- { "cp883", TTF_883, 0 },
- { "cp884", TTF_884, 0 },
- { "cp885", TTF_885, 0 },
-#endif /* COMMENT */
- { "default",TTF_ROM,0 }
-};
-int ntermfont = (sizeof(term_font) / sizeof(struct keytab));
-int tt_font = TTF_ROM; /* Terminal screen font */
-#else /* PCFONTS */
-#ifdef NT
-#ifdef KUI
-struct keytab * term_font = NULL;
-struct keytab * _term_font = NULL;
-char * tt_facename = NULL;
-int ntermfont = 0;
-int tt_font = 0;
-int tt_font_size = 0;
-#endif /* KUI */
-#endif /* NT */
-#endif /* PCFONTS */
-
-struct keytab anbktab[] = { /* For any command that needs */
- { "message", 2, 0 }, /* these keywords... */
- { "off", 0, 0 },
- { "on", 1, 0 },
- { "unsafe-messag0", 99, CM_INV },
- { "unsafe-message", 3, CM_INV }
-};
-int nansbk = (sizeof(anbktab) / sizeof(struct keytab));
-
-int win95_popup = 1;
-#ifdef NT
-#ifdef KUI
-int win95lucida = 0;
-int win95hsl = 1;
-#else /* KUI */
-int win95lucida = 1;
-int win95hsl = 1;
-#endif /* KUI */
-#else /* NT */
-int win95lucida = 0;
-int win95hsl = 1;
-#endif /* NT */
-#ifdef NT
-int win95altgr = 0;
-extern int win95selectbug;
-extern int win95_8_3;
-
-#ifdef COMMENT
-extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR);
-extern struct keytab tcstab[];
-extern int ntcs;
-#endif /* COMMENT */
-extern int maxow, maxow_usr; owwait; /* Overlapped I/O variables */
-#endif /* NT */
-#endif /* OS2 */
-
-
-/* The following routines broken out of doprm() to give compilers a break. */
-
-/* S E T O N -- Parse on/off (default on), set parameter to result */
-
-int
-seton(prm) int *prm; {
- int x, y;
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- *prm = y;
- return(1);
-}
-
-/* S E T O N A U T O -- Parse on/off/auto (default auto) & set result */
-
-struct keytab onoffaut[] = {
- { "auto", SET_AUTO, 0 }, /* 2 */
- { "off", SET_OFF, 0 }, /* 0 */
- { "on", SET_ON, 0 } /* 1 */
-};
-
-int
-setonaut(prm) int *prm; {
- int x, y;
- if ((y = cmkey(onoffaut,3,"","auto",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- *prm = y;
- return(1);
-}
-
-/* S E T N U M -- Set parameter to result of cmnum() parse. */
-/*
- Call with pointer to integer variable to be set,
- x = number from cnum parse, y = return code from cmnum,
- max = maximum value to accept, -1 if no maximum.
- Returns -9 on failure, after printing a message, or 1 on success.
-*/
-int
-setnum(prm,x,y,max) int x, y, *prm, max; {
- debug(F101,"setnum","",y);
- if (y == -3) {
- printf("\n?Value required\n");
- return(-9);
- }
- if (y == -2) {
- printf("%s?Not a number: %s\n",cmflgs == 1 ? "" : "\n", atxbuf);
- return(-9);
- }
- if (y < 0) return(y);
- if (max > -1 && x > max) {
- printf("?Sorry, %d is the maximum\n",max);
- return(-9);
- }
- if ((y = cmcfm()) < 0) return(y);
- *prm = x;
- return(1);
-}
-
-/* S E T C C -- Set parameter var to an ASCII control character value. */
-/*
- Parses a number, or a literal control character, or a caret (^) followed
- by an ASCII character whose value is 63-95 or 97-122, then gets confirmation,
- then sets the parameter to the code value of the character given. If there
- are any parse errors, they are returned, otherwise on success 1 is returned.
-*/
-int
-setcc(dflt,var) char *dflt; int *var; {
- int x, y;
- unsigned int c;
- char *hlpmsg = "Control character,\n\
- numeric ASCII value,\n\
- or in ^X notation,\n\
- or preceded by a backslash and entered literally";
-
- /* This is a hack to turn off complaints from expression evaluator. */
- x_ifnum = 1;
- y = cmnum(hlpmsg, dflt, 10, &x, xxstring); /* Parse a number */
- x_ifnum = 0; /* Allow complaints again */
- if (y < 0) { /* Parse failed */
- if (y != -2) /* Reparse needed or somesuch */
- return(y); /* Pass failure back up the chain */
- }
- /* Real control character or literal 8-bit character... */
-
- for (c = strlen(atmbuf) - 1; c > 0; c--) /* Trim */
- if (atmbuf[c] == SP) atmbuf[c] = NUL;
-
- if (y < 0) { /* It was not a number */
- if (((c = atmbuf[0])) && !atmbuf[1]) { /* Literal character? */
- c &= 0xff;
- if (((c > 31) && (c < 127)) || (c > 255)) {
- printf("\n?%d: Out of range - must be 0-31 or 127-255\n",c);
- return(-9);
- } else {
- if ((y = cmcfm()) < 0) /* Confirm */
- return(y);
- *var = c; /* Set the variable */
- return(1);
- }
- } else if (atmbuf[0] == '^' && !atmbuf[2]) { /* Or ^X notation? */
- c = atmbuf[1];
- if (islower((char) c)) /* Uppercase lowercase letters */
- c = toupper(c);
- if (c > 62 && c < 96) { /* Check range */
- if ((y = cmcfm()) < 0)
- return(y);
- *var = ctl(c); /* OK */
- return(1);
- } else {
- printf("?Not a control character - %s\n", atmbuf);
- return(-9);
- }
- } else { /* Something illegal was typed */
- printf("?Invalid - %s\n", atmbuf);
- return(-9);
- }
- }
- if (((x > 31) && (x < 127)) || (x > 255)) { /* They typed a number */
- printf("\n?%d: Out of range - must be 0-31 or 127-255\n",x);
- return(-9);
- }
- if ((y = cmcfm()) < 0) /* In range, confirm */
- return(y);
- *var = x; /* Set variable */
- return(1);
-}
-
-#ifndef NOSPL /* The SORT command... */
-
-static struct keytab srtswtab[] = { /* SORT command switches */
- { "/case", SRT_CAS, CM_ARG },
- { "/key", SRT_KEY, CM_ARG },
- { "/numeric", SRT_NUM, 0 },
- { "/range", SRT_RNG, CM_ARG },
- { "/reverse", SRT_REV, 0 }
-};
-static int nsrtswtab = sizeof(srtswtab)/sizeof(struct keytab);
-
-extern char **a_ptr[]; /* Array pointers */
-extern int a_dim[]; /* Array dimensions */
-
-int
-dosort() { /* Do the SORT command */
- char c, *p = NULL, ** ap, ** xp = NULL;
- struct FDB sw, fl, cm;
- int hi, lo;
- int xn = 0, xr = -1, xk = -1, xc = -1, xs = 0;
- int getval = 0, range[2], confirmed = 0;
-
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Array name or switch",
- "", /* default */
- "", /* addtl string data */
- nsrtswtab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- NULL, /* Processing function */
- srtswtab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Anything that doesn't match */
- _CMFLD, /* fcode */
- "Array name", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* Or premature confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
-
- range[0] = -1;
- range[1] = -1;
-
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw);
- if (x < 0)
- return(x);
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- c = cmgbrk();
- getval = (c == ':' || c == '=');
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- return(-9);
- }
- switch (cmresult.nresult) {
- case SRT_REV:
- xr = 1;
- break;
- case SRT_KEY:
- if (getval) {
- if ((y = cmnum("Column for comparison (1-based)",
- "1",10,&x,xxstring)) < 0)
- return(y);
- xk = x - 1;
- } else
- xk = 0;
- break;
- case SRT_CAS:
- if (getval) {
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
- return(y);
- xc = y;
- } else
- xc = 1;
- break;
- case SRT_RNG: /* /RANGE */
- if (getval) {
- char buf[32];
- char buf2[16];
- int i;
- char * p, * q;
- if ((y = cmfld("low:high element","1",&s,NULL)) < 0)
- return(y);
- s = brstrip(s);
- ckstrncpy(buf,s,32);
- p = buf;
- for (i = 0; *p && i < 2; i++) { /* Get low and high */
- q = p; /* Start of this piece */
- while (*p) { /* Find end of this piece */
- if (*p == ':') {
- *p = NUL;
- p++;
- break;
- }
- p++;
- }
- y = 15; /* Evaluate this piece */
- s = buf2;
- zzstring(q,&s,&y);
- s = evalx(buf2);
- if (s) if (*s) ckstrncpy(buf2,s,16);
- if (!rdigits(buf2)) {
- printf("?Not numeric: %s\n",buf2);
- return(-9);
- }
- range[i] = atoi(buf2);
- }
- }
- break;
- case SRT_NUM: /* /NUMERIC */
- xn = 1;
- break;
- default:
- return(-2);
- }
- }
- switch (cmresult.fcode) {
- case _CMCFM:
- confirmed = 1;
- break;
- case _CMFLD:
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Safe copy of name */
- s = line;
- break;
- default:
- printf("?Unexpected function code: %d\n",cmresult.fcode);
- return(-9);
- }
- if (confirmed) {
- printf("?Array name required\n");
- return(-9);
- }
- ckmakmsg(tmpbuf,TMPBUFSIZ,
- "Second array to sort according to ",s,NULL,NULL);
- if ((x = cmfld(tmpbuf,"",&p,NULL)) < 0)
- if (x != -3)
- return(x);
- tmpbuf[0] = NUL;
- ckstrncpy(tmpbuf,p,TMPBUFSIZ);
- p = tmpbuf;
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
-
- x = arraybounds(s,&lo,&hi); /* Get array index & bounds */
- if (x < 0) { /* Check */
- printf("?Bad array name: %s\n",s);
- return(-9);
- }
- if (lo > -1) range[0] = lo; /* Set range */
- if (hi > -1) range[1] = hi;
- ap = a_ptr[x]; /* Get pointer to array element list */
- if (!ap) { /* Check */
- printf("?Array not declared: %s\n", s);
- return(-9);
- }
- if (range[0] < 0) /* Starting element */
- range[0] = 1;
- if (range[1] < 0) /* Final element */
- range[1] = a_dim[x];
- if (range[1] > a_dim[x]) {
- printf("?range %d:%d exceeds array dimension %d\n",
- range[0],range[1],a_dim[x]
- );
- return(-9);
- }
- ap += range[0];
- xs = range[1] - range[0] + 1; /* Number of elements to sort */
- if (xs < 1) { /* Check */
- printf("?Bad range: %d:%d\n",range[0],range[1]);
- return(-9);
- }
- if (xk < 0) xk = 0; /* Key position */
- if (xr < 0) xr = 0; /* Reverse flag */
- if (xn) /* Numeric flag */
- xc = 2;
- else if (xc < 0) /* Not numeric */
- xc = inpcas[cmdlvl]; /* so alpha case option */
-
- if (*p) { /* Parallel array given? */
- y = xarray(p); /* Yes, get its index. */
- if (y < 0) {
- printf("?Bad array name: %s\n", p);
- return(-9);
- }
- if (y != x) { /* If the 2 arrays are different */
- xp = a_ptr[y]; /* Pointer to 2nd array element list */
- if (!xp) {
- printf("?Array not declared: %s\n", p);
- return(-9);
- }
- if (a_dim[y] < range[1]) {
- printf("?Array %s smaller than %s\n", p, s);
- return(-9);
- }
- xp += range[0]; /* Set base to same as 1st array */
- }
- }
- sh_sort(ap,xp,xs,xk,xr,xc); /* Sort the array(s) */
- return(success = 1); /* Always succeeds */
-}
-#endif /* NOSPL */
-
-static struct keytab purgtab[] = { /* PURGE command switches */
- { "/after", PU_AFT, CM_ARG },
- { "/ask", PU_ASK, 0 },
- { "/before", PU_BEF, CM_ARG },
- { "/delete", PU_DELE, CM_INV },
-#ifdef UNIXOROSK
- { "/dotfiles", PU_DOT, 0 },
-#endif /* UNIXOROSK */
- { "/except", PU_EXC, CM_ARG },
- { "/heading", PU_HDG, 0 },
- { "/keep", PU_KEEP, CM_ARG },
- { "/larger-than", PU_LAR, CM_ARG },
- { "/list", PU_LIST, 0 },
- { "/log", PU_LIST, CM_INV },
- { "/noask", PU_NASK, 0 },
- { "/nodelete", PU_NODE, CM_INV },
-#ifdef UNIXOROSK
- { "/nodotfiles", PU_NODOT,0 },
-#endif /* UNIXOROSK */
- { "/noheading", PU_NOH, 0 },
- { "/nol", PU_NOLI, CM_INV|CM_ABR },
- { "/nolist", PU_NOLI, 0 },
- { "/nolog", PU_NOLI, CM_INV },
-#ifdef CK_TTGWSIZ
- { "/nopage", PU_NOPA, 0 },
-#endif /* CK_TTGWSIZ */
- { "/not-after", PU_NAF, CM_ARG },
- { "/not-before", PU_NBF, CM_ARG },
- { "/not-since", PU_NAF, CM_INV|CM_ARG },
-#ifdef CK_TTGWSIZ
- { "/page", PU_PAGE, 0 },
-#endif /* CK_TTGWSIZ */
- { "/quiet", PU_QUIE, CM_INV },
-#ifdef RECURSIVE
- { "/recursive", PU_RECU, 0 },
-#endif /* RECURSIVE */
- { "/since", PU_AFT, CM_ARG|CM_INV },
- { "/simulate", PU_NODE, 0 },
- { "/smaller-than", PU_SMA, CM_ARG },
- { "/verbose", PU_VERB, CM_INV }
-};
-static int npurgtab = sizeof(purgtab)/sizeof(struct keytab);
-
-
-
-
-
-int
-bkupnum(s,i) char * s; int *i; {
- int k = 0, pos = 0;
- char * p = NULL, *q;
- *i = pos;
- if (!s) s = "";
- if (!*s)
- return(-1);
- if ((k = strlen(s)) < 5)
- return(-1);
-
- if (s[k-1] != '~')
- return(-1);
- pos = k - 2;
- q = s + pos;
- while (q >= s && isdigit(*q)) {
- p = q--;
- pos--;
- }
- if (!p)
- return(-1);
- if (q < s+2)
- return(-1);
- if (*q != '~' || *(q-1) != '.')
- return(-1);
- pos--;
- *i = pos;
- debug(F111,"bkupnum",s+pos,pos);
- return(atoi(p));
-}
-
-#ifdef CKPURGE
-/* Presently only for UNIX because we need direct access to the file array. */
-/* Not needed for VMS anyway, because we don't make backup files there. */
-
-#define MAXKEEP 32 /* Biggest /KEEP: value */
-
-static int
- pu_keep = 0, pu_list = 0, pu_dot = 0, pu_ask = 0, pu_hdg = 0;
-
-#ifdef CK_TTGWSIZ
-static int pu_page = -1;
-#else
-static int pu_page = 0;
-#endif /* CK_TTGWSIZ */
-
-#ifndef NOSHOW
-VOID
-showpurgopts() { /* SHOW PURGE command options */
- int x = 0;
- extern int optlines;
- prtopt(&optlines,"PURGE");
- if (pu_ask > -1) {
- x++;
- prtopt(&optlines, pu_ask ? "/ASK" : "/NOASK");
- }
-#ifdef UNIXOROSK
- if (pu_dot > -1) {
- x++;
- prtopt(&optlines, pu_dot ? "/DOTFILES" : "/NODOTFILES");
- }
-#endif /* UNIXOROSK */
- if (pu_keep > -1) {
- x++;
- ckmakmsg(tmpbuf,TMPBUFSIZ,"/KEEP:",ckitoa(pu_keep),NULL,NULL);
- prtopt(&optlines,tmpbuf);
- }
- if (pu_list > -1) {
- x++;
- prtopt(&optlines, pu_list ? "/LIST" : "/NOLIST");
- }
- if (pu_hdg > -1) {
- x++;
- prtopt(&optlines, pu_hdg ? "/HEADING" : "/NOHEADING");
- }
-#ifdef CK_TTGWSIZ
- if (pu_page > -1) {
- x++;
- prtopt(&optlines, pu_page ? "/PAGE" : "/NOPAGE");
- }
-#endif /* CK_TTGWSIZ */
- if (!x) prtopt(&optlines,"(no options set)");
- prtopt(&optlines,"");
-}
-#endif /* NOSHOW */
-
-int
-setpurgopts() { /* Set PURGE command options */
- int c, z, getval = 0;
- int
- x_keep = -1, x_list = -1, x_page = -1,
- x_hdg = -1, x_ask = -1, x_dot = -1;
-
- while (1) {
- if ((y = cmswi(purgtab,npurgtab,"Switch","",xxstring)) < 0) {
- if (y == -3)
- break;
- else
- return(y);
- }
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (y) {
- case PU_KEEP:
- z = 1;
- if (c == ':' || c == '=')
- if ((y = cmnum("How many backup files to keep",
- "1",10,&z,xxstring)) < 0)
- return(y);
- if (z < 0 || z > MAXKEEP) {
- printf("?Please specify a number between 0 and %d\n",
- MAXKEEP
- );
- return(-9);
- }
- x_keep = z;
- break;
- case PU_LIST:
- case PU_VERB:
- x_list = 1;
- break;
- case PU_QUIE:
- case PU_NOLI:
- x_list = 0;
- break;
-#ifdef CK_TTGWSIZ
- case PU_PAGE:
- x_page = 1;
- break;
- case PU_NOPA:
- x_page = 0;
- break;
-#endif /* CK_TTGWSIZ */
- case PU_HDG:
- x_hdg = 1;
- break;
- case PU_NOH:
- x_hdg = 0;
- break;
- case PU_ASK:
- x_ask = 1;
- break;
- case PU_NASK:
- x_ask = 0;
- break;
-#ifdef UNIXOROSK
- case PU_DOT:
- x_dot = 1;
- break;
- case PU_NODOT:
- x_dot = 0;
- break;
-#endif /* UNIXOROSK */
- default:
- printf("?This option can not be set\n");
- return(-9);
- }
- }
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
- if (x_keep > -1) /* Set PURGE defaults. */
- pu_keep = x_keep;
- if (x_list > -1)
- pu_list = x_list;
-#ifdef CK_TTGWSIZ
- if (x_page > -1)
- pu_page = x_page;
-#endif /* CK_TTGWSIZ */
- if (x_hdg > -1)
- pu_hdg = x_hdg;
- if (x_ask > -1)
- pu_ask = x_ask;
- if (x_dot > -1)
- pu_dot = x_dot;
- return(success = 1);
-}
-
-int
-dopurge() { /* Do the PURGE command */
- extern char ** mtchs;
- extern int xaskmore, cmd_rows, recursive;
- int simulate = 0, asking = 0;
- int listing = 0, paging = -1, lines = 0, deleting = 1, errors = 0;
- struct FDB sw, sf, cm;
- int g, i, j, k, m = 0, n, x, y, z, done = 0, count = 0, flags = 0;
- int tokeep = 0, getval = 0, havename = 0, confirmed = 0;
- int xx[MAXKEEP+1]; /* Array of numbers to keep */
- int min = -1;
- int x_hdg = 0, fs = 0, rc = 0;
- CK_OFF_T minsize = -1L, maxsize = -1L;
- char namebuf[CKMAXPATH+4];
- char basebuf[CKMAXPATH+4];
- char
- * pu_aft = NULL,
- * pu_bef = NULL,
- * pu_naf = NULL,
- * pu_nbf = NULL,
- * pu_exc = NULL;
- char * pxlist[8]; /* Exception list */
-
- if (pu_keep > -1) /* Set PURGE defaults. */
- tokeep = pu_keep;
- if (pu_list > -1)
- listing = pu_list;
-#ifdef CK_TTGWSIZ
- if (pu_page > -1)
- paging = pu_page;
-#endif /* CK_TTGWSIZ */
-
- for (i = 0; i <= MAXKEEP; i++) /* Clear this number buffer */
- xx[i] = 0;
- for (i = 0; i < 8; i++) /* Initialize these... */
- pxlist[i] = NULL;
-
- g_matchdot = matchdot; /* Save these... */
-
- cmfdbi(&sw, /* 1st FDB - PURGE switches */
- _CMKEY, /* fcode */
- "Filename or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- npurgtab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- purgtab, /* Keyword table */
- &sf /* Pointer to next FDB */
- );
- cmfdbi(&sf, /* 2nd FDB - filespec to purge */
- _CMIFI, /* fcode */
- "",
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* Or premature confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
-
- while (!havename && !confirmed) {
- x = cmfdb(&sw); /* Parse something */
- if (x < 0) { /* Error */
- rc = x;
- goto xpurge;
- } else if (cmresult.fcode == _CMKEY) {
- char c;
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- rc = -9;
- goto xpurge;
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- rc = -9;
- goto xpurge;
- }
- switch (k = cmresult.nresult) {
- case PU_KEEP:
- z = 1;
- if (c == ':' || c == '=') {
- if ((y = cmnum("How many backup files to keep",
- "1",10,&z,xxstring)) < 0) {
- rc = y;
- goto xpurge;
- }
- }
- if (z < 0 || z > MAXKEEP) {
- printf("?Please specify a number between 0 and %d\n",
- MAXKEEP
- );
- rc = -9;
- goto xpurge;
- }
- tokeep = z;
- break;
- case PU_LIST:
- listing = 1;
- break;
- case PU_NOLI:
- listing = 0;
- break;
-#ifdef CK_TTGWSIZ
- case PU_PAGE:
- paging = 1;
- break;
- case PU_NOPA:
- paging = 0;
- break;
-#endif /* CK_TTGWSIZ */
- case PU_DELE:
- deleting = 1;
- break;
- case PU_NODE:
- deleting = 0;
- simulate = 1;
- listing = 1;
- break;
- case PU_ASK:
- asking = 1;
- break;
- case PU_NASK:
- asking = 0;
- break;
- case PU_AFT:
- case PU_BEF:
- case PU_NAF:
- case PU_NBF:
- if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) {
- if (x == -3) {
- printf("?Date-time required\n");
- rc = -9;
- } else
- rc = x;
- goto xpurge;
- }
- fs++;
- switch (k) {
- case PU_AFT: makestr(&pu_aft,s); break;
- case PU_BEF: makestr(&pu_bef,s); break;
- case PU_NAF: makestr(&pu_naf,s); break;
- case PU_NBF: makestr(&pu_nbf,s); break;
- }
- break;
- case PU_SMA:
- case PU_LAR:
- if ((x = cmnum("File size in bytes","0",10,&y,xxstring)) < 0) {
- rc = x;
- goto xpurge;
- }
- fs++;
- switch (cmresult.nresult) {
- case PU_SMA: minsize = y; break;
- case PU_LAR: maxsize = y; break;
- }
- break;
- case PU_DOT:
- matchdot = 1;
- break;
- case PU_NODOT:
- matchdot = 0;
- break;
- case PU_EXC:
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Pattern required\n");
- rc = -9;
- } else
- rc = x;
- goto xpurge;
- }
- fs++;
- makestr(&pu_exc,s);
- break;
- case PU_HDG:
- x_hdg = 1;
- break;
-#ifdef RECURSIVE
- case PU_RECU: /* /RECURSIVE */
- recursive = 2;
- break;
-#endif /* RECURSIVE */
- default:
- printf("?Not implemented yet - \"%s\"\n",atmbuf);
- rc = -9;
- goto xpurge;
- }
- } else if (cmresult.fcode == _CMIFI) {
- havename = 1;
- } else if (cmresult.fcode == _CMCFM) {
- confirmed = 1;
- } else {
- rc = -2;
- goto xpurge;
- }
- }
- if (havename) {
-#ifdef CKREGEX
- ckmakmsg(line,LINBUFSIZ,cmresult.sresult,".~[1-9]*~",NULL,NULL);
-#else
- ckmakmsg(line,LINBUFSIZ,cmresult.sresult,".~*~",NULL,NULL);
-#endif /* CKREGEX */
- } else {
-#ifdef CKREGEX
- ckstrncpy(line,"*.~[1-9]*~",LINBUFSIZ);
-#else
- ckstrncpy(line,"*.~*~",LINBUFSIZ);
-#endif /* CKREGEX */
- }
- if (!confirmed) {
- if ((x = cmcfm()) < 0) {
- rc = x;
- goto xpurge;
- }
- }
- /* Parse finished - now action */
-
-#ifdef CK_LOGIN
- if (isguest) {
- printf("?File deletion by guests not permitted.\n");
- rc = -9;
- goto xpurge;
- }
-#endif /* CK_LOGIN */
-
-#ifdef CK_TTGWSIZ
- if (paging < 0) /* /[NO]PAGE not given */
- paging = xaskmore; /* so use prevailing */
-#endif /* CK_TTGWSIZ */
-
- lines = 0;
- if (x_hdg > 0) {
- printf("Purging %s, keeping %d...%s\n",
- s,
- tokeep,
- simulate ? " (SIMULATION)" : "");
- lines += 2;
- }
- flags = ZX_FILONLY;
- if (recursive) flags |= ZX_RECURSE;
- n = nzxpand(line,flags); /* Get list of backup files */
- if (tokeep < 1) { /* Deleting all of them... */
- for (i = 0; i < n; i++) {
- if (fs) if (fileselect(mtchs[i],
- pu_aft,pu_bef,pu_naf,pu_nbf,
- minsize,maxsize,0,8,pxlist) < 1) {
- if (listing > 0) {
- printf(" %s (SKIPPED)\n",mtchs[i]);
-#ifdef CK_TTGWSIZ
- if (paging)
- if (++lines > cmd_rows - 3) {
- if (!askmore()) goto xpurge; else lines = 0;
- }
-#endif /* CK_TTGWSIZ */
- }
- continue;
- }
- if (asking) {
- int x;
- ckmakmsg(tmpbuf,TMPBUFSIZ," Delete ",mtchs[i],"?",NULL);
- x = getyesno(tmpbuf,1);
- switch (x) {
- case 0: continue;
- case 1: break;
- case 2: goto xpurge;
- }
- }
- x = deleting ? zdelet(mtchs[i]) : 0;
- if (x > -1) {
- if (listing)
- printf(" %s (%s)\n", mtchs[i],deleting ? "OK" : "SELECTED");
- count++;
- } else {
- errors++;
- if (listing)
- printf(" %s (FAILED)\n", mtchs[i]);
- }
-#ifdef CK_TTGWSIZ
- if (listing && paging)
- if (++lines > cmd_rows - 3) {
- if (!askmore()) goto xpurge; else lines = 0;
- }
-#endif /* CK_TTGWSIZ */
- }
- goto xpurge;
- }
- if (n < tokeep) { /* Not deleting any */
- count = 0;
- if (listing)
- printf(" Matches = %d: Not enough to purge.\n",n);
- goto xpurge;
- }
-
- /* General case - delete some but not others */
-
- sh_sort(mtchs,NULL,n,0,0,filecase); /* Alphabetize the list (ESSENTIAL) */
-
- g = 0; /* Start of current group */
- for (i = 0; i < n; i++) { /* Go thru sorted file list */
- x = znext(namebuf); /* Get next file */
- if (x < 1 || !namebuf[0] || i == n - 1) /* No more? */
- done = 1; /* NOTE: 'done' must be 0 or 1 only */
- if (fs) if (fileselect(namebuf,
- pu_aft,pu_bef,pu_naf,pu_nbf,
- minsize,maxsize,0,8,pxlist) < 1) {
- if (listing > 0) {
- printf(" %s (SKIPPED)\n",namebuf);
- if (++lines > cmd_rows - 3)
- if (!askmore()) goto xpurge; else lines = 0;
- }
- continue;
- }
- if (x > 0)
- if ((m = bkupnum(namebuf,&z)) < 0) /* This file's backup number. */
- continue;
- for (j = 0; j < tokeep; j++) { /* Insert in list. */
- if (m > xx[j]) {
- for (k = tokeep - 1; k > j; k--)
- xx[k] = xx[k-1];
- xx[j] = m;
- break;
- }
- }
- /* New group? */
- if (done || (i > 0 && ckstrcmp(namebuf,basebuf,z,1))) {
- if (i + done - g > tokeep) { /* Do we have enough to purge? */
- min = xx[tokeep-1]; /* Yes, lowest backup number to keep */
- debug(F111,"dopurge group",basebuf,min);
- for (j = g; j < i + done; j++) { /* Go through this group */
- x = bkupnum(mtchs[j],&z); /* Get file backup number */
- if (x > 0 && x < min) { /* Below minimum? */
- x = deleting ? zdelet(mtchs[j]) : 0;
- if (x < 0) errors++;
- if (listing)
- printf(" %s (%s)\n",
- mtchs[j],
- ((x < 0) ? "ERROR" :
- (deleting ? "DELETED" : "SELECTED"))
- );
- count++;
- } else if (listing) /* Not below minimum - keep this one */
- printf(" %s (KEPT)\n",mtchs[j]);
-#ifdef CK_TTGWSIZ
- if (listing && paging)
- if (++lines > cmd_rows - 3) {
- if (!askmore()) goto xpurge; else lines = 0;
- }
-#endif /* CK_TTGWSIZ */
- }
- } else if (listing && paging) { /* Not enough to purge */
- printf(" %s.~*~ (KEPT)\n",basebuf);
-#ifdef CK_TTGWSIZ
- if (++lines > cmd_rows - 3) {
- if (!askmore()) goto xpurge; else lines = 0;
- }
-#endif /* CK_TTGWSIZ */
- }
- for (j = 0; j < tokeep; j++) /* Clear the backup number list */
- xx[j] = 0;
- g = i; /* Reset the group pointer */
- }
- if (done) /* No more files, done. */
- break;
- strncpy(basebuf,namebuf,z); /* Set basename of this file */
- basebuf[z] = NUL;
- }
- xpurge: /* Common exit point */
- if (g_matchdot > -1) {
- matchdot = g_matchdot; /* Restore these... */
- g_matchdot = -1;
- }
- if (rc < 0) return(rc); /* Parse error */
- if (x_hdg)
- printf("Files purged: %d%s\n",
- count,
- deleting ? "" : " (not really)"
- );
- return(success = count > 0 ? 1 : (errors > 0) ? 0 : 1);
-}
-#endif /* CKPURGE */
-
-#ifndef NOXFER
-#ifndef NOLOCAL
-int
-doxdis(which) int which; { /* 1 = Kermit, 2 = FTP */
- extern int nolocal;
- int x, y = 0, z;
-#ifdef NEWFTP
- extern int ftp_dis;
-#endif /* NEWFTP */
-
-#ifdef COMMENT
- char *s;
-#endif /* COMMENT */
-
- if ((x = cmkey(fdtab,nfdtab,"file transfer display style","",
- xxstring)) < 0)
- return(x);
-#ifdef CK_PCT_BAR
- if ((y = cmkey(fdftab,2,"","thermometer",xxstring)) < 0)
- return(y);
-#endif /* CK_PCT_BAR */
- if ((z = cmcfm()) < 0) return(z);
-#ifdef CK_CURSES
- if (x == XYFD_C) { /* FULLSCREEN */
-#ifdef COMMENT
-#ifndef MYCURSES
- extern char * trmbuf; /* Real curses */
- int z;
-#endif /* MYCURSES */
-#endif /* COMMENT */
-
- if (nolocal) /* Nothing to do in this case */
- return(success = 1);
-
-#ifdef COMMENT
-#ifndef MYCURSES
-#ifndef VMS
- s = getenv("TERM");
- debug(F110,"doxdis TERM",s,0);
- if (!s) s = "";
- fxdinit(x);
- if (*s && trmbuf) { /* Don't call tgetent */
- z = tgetent(trmbuf,s); /* if trmbuf not allocated */
- debug(F111,"doxdis tgetent",s,z);
- } else {
- z = 0;
- debug(F110,"doxdis tgetent skipped",s,0);
- }
- if (z < 1) {
- printf("Sorry, terminal type unknown: \"%s\"\n",s);
- return(success = 0);
- }
-#endif /* VMS */
-#endif /* MYCURSES */
-#else
- fxdinit(x);
-#endif /* COMMENT */
-
-#ifdef CK_PCT_BAR
- thermometer = y;
-#endif /* CK_PCT_BAR */
-
- line[0] = '\0'; /* (What's this for?) */
- }
-#endif /* CK_CURSES */
- if (which == 1) /* It's OK. */
- fdispla = x;
-#ifdef NEWFTP
- else if (which == 2)
- ftp_dis = x;
-#endif /* NEWFTP */
- return(success = 1);
-}
-#endif /* NOLOCAL */
-#endif /* NOXFER */
-
-int
-setfil(rmsflg) int rmsflg; {
-#ifdef COMMENT
- extern int en_del;
-#endif /* COMMENT */
-#ifndef NOXFER
- if (rmsflg) {
- if ((y = cmkey(rfiltab,nrfilp,"Remote file parameter","",
- xxstring)) < 0) {
- if (y == -3) {
- printf("?Remote file parameter required\n");
- return(-9);
- } else return(y);
- }
- } else {
-#endif /* NOXFER */
- if ((y = cmkey(filtab,nfilp,"File parameter","",xxstring)) < 0)
- return(y);
-#ifndef NOXFER
- }
-#endif /* NOXFER */
- switch (y) {
-#ifdef COMMENT /* Not needed */
- case XYFILB: /* Blocksize */
- if ((y = cmnum("file block size",ckitoa(DBLKSIZ),10,&z,xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- if (rmsflg) {
- sstate = setgen('S', "311", ckitoa(z), "");
- return((int) sstate);
- } else {
- fblksiz = z;
- return(success = 1);
- }
-#endif /* COMMENT */
-
-#ifndef NOXFER
- case XYFILS: /* Byte size */
- if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
- return(y);
- if (z != 7 && z != 8) {
- printf("\n?The choices are 7 and 8\n");
- return(0);
- }
- if ((y = cmcfm()) < 0) return(y);
- if (z == 7) fmask = 0177;
- else if (z == 8) fmask = 0377;
- return(success = 1);
-
-#ifndef NOCSETS
- case XYFILC: { /* Character set */
- char * csetname = NULL;
- extern int
- r_cset, s_cset, afcset[]; /* SEND CHARACTER-SET AUTO or MANUAL */
-
- struct FDB kw, fl;
- cmfdbi(&kw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- rmsflg ? "server character-set name" : "", /* help */
- "", /* default */
- "", /* addtl string data */
- nfilc, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 0 = keyword */
- xxstring, /* Processing function */
- fcstab, /* Keyword table */
- rmsflg ? &fl : NULL /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Anything that doesn't match */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- if ((x = cmfdb(&kw)) < 0)
- return(x);
- if (cmresult.fcode == _CMKEY) {
- x = cmresult.nresult;
- csetname = fcsinfo[x].keyword;
- } else {
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- csetname = line;
- }
- if ((z = cmcfm()) < 0) return(z);
- if (rmsflg) {
- sstate = setgen('S', "320", csetname, "");
- return((int) sstate);
- }
- fcharset = x;
- if (s_cset == XMODE_A) /* If SEND CHARACTER-SET is AUTO */
- if (x > -1 && x <= MAXFCSETS)
- if (afcset[x] > -1 && afcset[x] <= MAXTCSETS)
- tcharset = afcset[x]; /* Pick corresponding xfer charset */
- setxlatype(tcharset,fcharset); /* Translation type */
- /* If I say SET FILE CHARACTER-SET blah, I want to be blah! */
- r_cset = XMODE_M; /* Don't switch incoming set! */
- x = fcsinfo[fcharset].size; /* Also set default x-bit charset */
- if (x == 128) /* 7-bit... */
- dcset7 = fcharset;
- else if (x == 256) /* 8-bit... */
- dcset8 = fcharset;
- return(success = 1);
- }
-#endif /* NOCSETS */
-
-#ifndef NOLOCAL
- case XYFILD: /* Display */
- return(doxdis(1)); /* 1 == kermit */
-#endif /* NOLOCAL */
-#endif /* NOXFER */
-
- case XYFILA: /* End-of-line */
-#ifdef NLCHAR
- s = "";
- if (NLCHAR == 015)
- s = "cr";
- else if (NLCHAR == 012)
- s = "lf";
- if ((x = cmkey(eoltab, neoltab,
- "local text-file line terminator",s,xxstring)) < 0)
- return(x);
-#else
- if ((x = cmkey(eoltab, neoltab,
- "local text-file line terminator","crlf",xxstring)) < 0)
- return(x);
-#endif /* NLCHAR */
- if ((z = cmcfm()) < 0) return(z);
- feol = (CHAR) x;
- return(success = 1);
-
-#ifndef NOXFER
- case XYFILN: /* Names */
- if ((x = cmkey(fntab,nfntab,"how to handle filenames","converted",
- xxstring)) < 0)
- return(x);
- if ((z = cmcfm()) < 0) return(z);
- if (rmsflg) {
- sstate = setgen('S', "301", ckitoa(1 - x), "");
- return((int) sstate);
- } else {
- ptab[protocol].fncn = x; /* Set structure */
- fncnv = x; /* Set variable */
- f_save = x; /* And set "permanent" variable */
- return(success = 1);
- }
-
- case XYFILR: /* Record length */
- if ((y = cmnum("file record length",
- ckitoa(DLRECL),10,&z,xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- if (rmsflg) {
- sstate = setgen('S', "312", ckitoa(z), "");
- return((int) sstate);
- } else {
- frecl = z;
- return(success = 1);
- }
-
-#ifdef COMMENT
- case XYFILO: /* Organization */
- if ((x = cmkey(forgtab,nforg,"file organization","sequential",
- xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- if (rmsflg) {
- sstate = setgen('S', "314", ckitoa(x), "");
- return((int) sstate);
- } else {
- forg = x;
- return(success = 1);
- }
-#endif /* COMMENT */
-
-#ifdef COMMENT /* Not needed */
- case XYFILF: /* Format */
- if ((x = cmkey(frectab,nfrec,"file record format","stream",
- xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- if (rmsflg) {
- sstate = setgen('S', "313", ckitoa(x), "");
- return((int) sstate);
- } else {
- frecfm = x;
- return(success = 1);
- }
-#endif /* COMMENT */
-
-#ifdef COMMENT
- case XYFILP: /* Printer carriage control */
- if ((x = cmkey(fcctab,nfcc,"file carriage control","newline",
- xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- if (rmsflg) {
- sstate = setgen('S', "315", ckitoa(x), "");
- return((int) sstate);
- } else {
- fcctrl = x;
- return(success = 1);
- }
-#endif /* COMMENT */
-#endif /* NOXFER */
-
- case XYFILT: /* Type */
- if ((x = cmkey(rmsflg ? rfttab : fttab,
- rmsflg ? nrfttyp : nfttyp,
- "type of file transfer","text",xxstring)) < 0)
- return(x);
-
-#ifdef VMS
- /* Allow VMS users to choose record format for binary files */
- if ((x == XYFT_B) && (rmsflg == 0)) {
- if ((x = cmkey(fbtab,nfbtyp,"VMS record format","fixed",
- xxstring)) < 0)
- return(x);
- }
-#endif /* VMS */
- if ((y = cmcfm()) < 0) return(y);
- binary = x;
- b_save = x;
-#ifdef MAC
- (void) mac_setfildflg(binary);
-#endif /* MAC */
-#ifndef NOXFER
- if (rmsflg) {
- /* Allow for LABELED in VMS & OS/2 */
- sstate = setgen('S', "300", ckitoa(x), "");
- return((int) sstate);
- } else {
-#endif /* NOXFER */
- return(success = 1);
-#ifndef NOXFER
- }
-#endif /* NOXFER */
-
-#ifndef NOXFER
- case XYFILX: /* Collision Action */
- if ((x = cmkey(colxtab,ncolx,"Filename collision action","backup",
- xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef CK_LOGIN
- if (isguest) {
- /* Don't let guests change existing files */
- printf("?This command not valid for guests\n");
- return(-9);
- }
-#endif /* CK_LOGIN */
-#ifdef COMMENT
- /* Not appropriate - DISABLE DELETE only refers to server */
- if ((x == XYFX_X || x == XYFX_B || x == XYFX_U || x == XYFX_A) &&
- (!ENABLED(en_del))) {
- printf("?Sorry, file deletion is disabled.\n");
- return(-9);
- }
-#endif /* COMMENT */
- fncact = x;
- ptab[protocol].fnca = x;
- if (rmsflg) {
- sstate = setgen('S', "302", ckitoa(fncact), "");
- return((int) sstate);
- } else {
- if (fncact == XYFX_R) ckwarn = 1; /* FILE WARNING implications */
- if (fncact == XYFX_X) ckwarn = 0; /* ... */
- return(success = 1);
- }
-
- case XYFILW: /* Warning/Write-Protect */
- if ((x = seton(&ckwarn)) < 0) return(x);
- if (ckwarn)
- fncact = XYFX_R;
- else
- fncact = XYFX_X;
- return(success = 1);
-
-#ifdef CK_LABELED
- case XYFILL: /* LABELED FILE parameters */
- if ((x = cmkey(lbltab,nlblp,"Labeled file feature","",
- xxstring)) < 0)
- return(x);
- if ((success = seton(&y)) < 0)
- return(success);
- if (y) /* Set or reset the selected bit */
- lf_opts |= x; /* in the options bitmask. */
- else
- lf_opts &= ~x;
- return(success);
-#endif /* CK_LABELED */
-
- case XYFILI: { /* INCOMPLETE */
- extern struct keytab ifdatab[];
- extern int keep;
- if ((y = cmkey(ifdatab,3,"","auto",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- if (rmsflg) {
- sstate = setgen('S',
- "310",
- y == 0 ? "0" : (y == 1 ? "1" : "2"),
- ""
- );
- return((int) sstate);
- } else {
- keep = y;
- return(success = 1);
- }
- }
-
-#ifdef CK_TMPDIR
- case XYFILG: { /* Download directory */
- int x;
- char *s;
-#ifdef ZFNQFP
- struct zfnfp * fnp;
-#endif /* ZFNQFP */
-#ifdef MAC
- char temp[34];
-#endif /* MAC */
-
-#ifdef GEMDOS
- if ((x = cmdir("Name of local directory, or carriage return",
- "",&s,
- NULL)) < 0 ) {
- if (x != -3)
- return(x);
- }
-#else
-#ifdef OS2
- if ((x = cmdir("Name of PC disk and/or directory,\n\
- or press the Enter key to use current directory",
- "",&s,xxstring)) < 0 ) {
- if (x != -3)
- return(x);
- }
-#else
-#ifdef MAC
- x = ckstrncpy(temp,zhome(),32);
- if (x > 0) if (temp[x-1] != ':') { temp[x] = ':'; temp[x+1] = NUL; }
- if ((x = cmtxt("Name of Macintosh volume and/or folder,\n\
- or press the Return key for the desktop on the boot disk",
- temp,&s, xxstring)) < 0 )
- return(x);
-#else
- if ((x = cmdir("Name of local directory, or carriage return",
- "", &s, xxstring)) < 0 ) {
- if (x != -3)
- return(x);
- }
-#endif /* MAC */
-#endif /* OS2 */
-#endif /* GEMDOS */
- debug(F110,"download dir",s,0);
-
-#ifndef MAC
- if (x == 2) {
- printf("?Wildcards not allowed in directory name\n");
- return(-9);
- }
-#endif /* MAC */
-
-#ifdef ZFNQFP
- if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {
- if (fnp->fpath)
- if ((int) strlen(fnp->fpath) > 0)
- s = fnp->fpath;
- }
- debug(F110,"download zfnqfp",s,0);
-#endif /* ZFNQFP */
-
- ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
-#ifndef MAC
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
-#endif /* MAC */
-
-#ifdef CK_LOGIN
- if (isguest) {
- /* Don't let guests change existing files */
- printf("?This command not valid for guests\n");
- return(-9);
- }
-#endif /* CK_LOGIN */
- x = strlen(s);
-
- if (x) {
-#ifdef datageneral /* AOS/VS */
- if (s[x-1] == ':') /* homdir ends in colon, */
- s[x-1] = NUL; /* and "dir" doesn't like that... */
-#else
-#ifdef OS2ORUNIX /* Unix or K-95... */
- if ((x < (LINBUFSIZ - 2)) && /* Add trailing dirsep */
- (s[x-1] != '/')) { /* if none present. */
- s[x] = '/'; /* Note that Windows path has */
- s[x+1] = NUL; /* been canonicalized to forward */
- } /* slashes at this point. */
-#endif /* OS2ORUNIX */
-#endif /* datageneral */
- makestr(&dldir,s);
- } else
- makestr(&dldir,NULL); /* dldir is NULL when not assigned */
-
- return(success = 1);
- }
-#endif /* CK_TMPDIR */
- case XYFILY:
- return(setdest());
-#endif /* NOXFER */
-
-#ifdef CK_CTRLZ
- case XYFILV: { /* EOF */
- extern int eofmethod;
- if ((x = cmkey(eoftab,3,"end-of-file detection method","",
- xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- eofmethod = x;
- return(success = 1);
- }
-#endif /* CK_CTRLZ */
-
-#ifndef NOXFER
-#ifdef UNIX
- case XYFILH: { /* OUTPUT */
- extern int zofbuffer, zobufsize, zofblock;
-#ifdef DYNAMIC
- extern char * zoutbuffer;
-#endif /* DYNAMIC */
-
- if ((x = cmkey(zoftab,nzoftab,"output file writing method","",
- xxstring)) < 0)
- return(x);
- if (x == ZOF_BUF || x == ZOF_NBUF) {
- if ((y = cmnum("output buffer size","32768",10,&z,xxstring)) < 0)
- return(y);
- if (z < 1) {
- printf("?Bad size - %d\n", z);
- return(-9);
- }
- }
- if ((y = cmcfm()) < 0) return(y);
- switch (x) {
- case ZOF_BUF:
- case ZOF_NBUF:
- zofbuffer = (x == ZOF_BUF);
- zobufsize = z;
- break;
- case ZOF_BLK:
- case ZOF_NBLK:
- zofblock = (x == ZOF_BLK);
- break;
- }
-#ifdef DYNAMIC
- if (zoutbuffer) free(zoutbuffer);
- if (!(zoutbuffer = (char *)malloc(z))) {
- printf("MEMORY ALLOCATION ERROR - FATAL\n");
- doexit(BAD_EXIT,-1);
- } else
- zobufsize = z;
-#else
- if (z <= OBUFSIZE) {
- zobufsize = z;
- } else {
- printf("?Sorry, %d is too big - %d is the maximum\n",z,OBUFSIZE);
- return(-9);
- }
-#endif /* DYNAMIC */
- return(success = 1);
- }
-#endif /* UNIX */
-
-#ifdef PATTERNS
- case XYFIBP: /* BINARY-PATTERN */
- case XYFITP: { /* TEXT-PATTERN */
- char * tmp[FTPATTERNS];
- int i, n = 0;
- while (n < FTPATTERNS) {
- tmp[n] = NULL;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
- break;
- ckstrncpy(line,s,LINBUFSIZ);
- s = brstrip(line);
- makestr(&(tmp[n++]),s);
- }
- if (x == -3) x = cmcfm();
- for (i = 0; i <= n; i++) {
- if (x > -1) {
- if (y == XYFIBP)
- makestr(&(binpatterns[i]),tmp[i]);
- else
- makestr(&(txtpatterns[i]),tmp[i]);
- }
- free(tmp[i]);
- }
- if (y == XYFIBP) /* Null-terminate the list */
- makestr(&(binpatterns[i]),NULL);
- else
- makestr(&(txtpatterns[i]),NULL);
- return(x);
- }
-
- case XYFIPA: /* PATTERNS */
- if ((x = setonaut(&patterns)) < 0)
- return(x);
- return(success = 1);
-#endif /* PATTERNS */
-#endif /* NOXFER */
-
-#ifdef UNICODE
- case XYFILU: { /* UCS */
- extern int ucsorder, ucsbom, byteorder;
- if ((x = cmkey(ucstab,nucstab,"","",xxstring)) < 0)
- return(x);
- switch (x) {
- case UCS_BYT:
- if ((y = cmkey(botab,nbotab,
- "Byte order",
- byteorder ? "little-endian" : "big-endian",
- xxstring
- )
- ) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- ucsorder = y;
- return(success = 1);
- case UCS_BOM:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- ucsbom = y;
- return(success = 1);
- default:
- return(-2);
- }
- }
-#endif /* UNICODE */
-
-#ifndef datageneral
- case XYF_INSP: { /* SCAN (INSPECTION) */
- extern int filepeek, nscanfile;
- if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
- return(x);
- if (y) {
- if ((y = cmnum("How much to scan",ckitoa(SCANFILEBUF),
- 10,&z,xxstring)) < 0)
- return(y);
- }
- if ((y = cmcfm()) < 0)
- return(y);
-#ifdef VMS
- filepeek = 0;
- nscanfile = 0;
- return(success = 0);
-#else
- filepeek = x;
- nscanfile = z;
- return(success = 1);
-#endif /* VMS */
- }
-#endif /* datageneral */
-
- case XYF_DFLT:
- y = 0;
-#ifndef NOCSETS
- if ((y = cmkey(fdfltab,nfdflt,"","",xxstring)) < 0)
- return(y);
- if (y == 7 || y == 8) {
- if (y == 7)
- s = fcsinfo[dcset7].keyword;
- else
- s = fcsinfo[dcset8].keyword;
- if ((x = cmkey(fcstab,nfilc,"character-set",s,xxstring)) < 0)
- return(x);
- }
- ckstrncpy(line,fcsinfo[x].keyword,LINBUFSIZ);
- s = line;
-#endif /* NOCSETS */
- if ((z = cmcfm()) < 0)
- return(z);
- switch (y) {
-#ifndef NOCSETS
- case 7:
- if (fcsinfo[x].size != 128) {
- printf("%s - Not a 7-bit set\n",s);
- return(-9);
- }
- dcset7 = x;
- break;
- case 8:
- if (fcsinfo[x].size != 256) {
- printf("%s - Not an 8-bit set\n",s);
- return(-9);
- }
- dcset8 = x;
- break;
-#endif /* NOCSETS */
- default:
- return(-2);
- }
- return(success = 1);
-
-#ifndef NOXFER
- case 9997: /* FASTLOOKUPS */
- return(success = seton(&stathack));
-#endif /* NOXFER */
-
-#ifdef UNIX
-#ifdef DYNAMIC
- case XYF_LSIZ: { /* LISTSIZE */
- int zz;
- y = cmnum("Maximum number of filenames","",10,&x,xxstring);
- if ((x = setnum(&zz,x,y,-1)) < 0)
- return(x);
- if (zsetfil(zz,3) < 0) {
- printf("?Memory allocation failure\n");
- return(-9);
- }
- return(success = 1);
- }
- case XYF_SSPA: { /* STRINGSPACE */
- int zz;
- y = cmnum("Number of characters for filename list",
- "",10,&x,xxstring);
- if ((x = setnum(&zz,x,y,-1)) < 0)
- return(x);
- if (zsetfil(zz,1) < 0) {
- printf("?Memory allocation failure\n");
- return(-9);
- }
- return(success = 1);
- }
-
-#endif /* DYNAMIC */
-#endif /* UNIX */
-
- default:
- printf("?unexpected file parameter\n");
- return(-2);
- }
-}
-
-#ifdef UNIX
-#ifndef NOPUTENV
-#ifdef BIGBUFOK
-#define NPUTENVS 4096
-#else
-#define NPUTENVS 128
-#endif /* BIGBUFOK */
-/* environment variables must be static, not automatic */
-
-static char * putenvs[NPUTENVS]; /* Array of environment var strings */
-static int nputenvs = -1; /* Pointer into array */
-/*
- If anyone ever notices the limitation on the number of PUTENVs, the list
- can be made dynamic, we can recycle entries with the same name, etc.
-*/
-int
-doputenv(s1, s2) char * s1; char * s2; {
- char * s, * t = tmpbuf; /* Create or alter environment var */
-
- if (nputenvs == -1) { /* Table not used yet */
- int i; /* Initialize the pointers */
- for (i = 0; i < NPUTENVS; i++)
- putenvs[i] = NULL;
- nputenvs = 0;
- }
- if (!s1) return(1); /* Nothing to do */
- if (!*s1) return(1); /* ditto */
-
- if (ckindex("=",s1,0,0,0)) { /* Does the name contain an '='? */
- printf( /* putenv() does not allow this. */
- /* This also catches the 'putenv name=value' case */
- "?PUTENV - Equal sign in variable name - 'help putenv' for info.\n");
- return(-9);
- }
- nputenvs++; /* Point to next free string */
-
- debug(F111,"doputenv s1",s1,nputenvs);
- debug(F111,"doputenv s2",s2,nputenvs);
-
- if (nputenvs > NPUTENVS - 1) { /* Notice the end */
- printf("?PUTENV - static buffer space exhausted\n");
- return(-9);
- }
- /* Quotes are not needed but we allow them for familiarity */
- /* but then we strip them, so syntax is same as for Unix shell */
-
- if (s2) {
- s2 = brstrip(s2);
- } else {
- s2 = (char *)"";
- }
- ckmakmsg(t,TMPBUFSIZ,s1,"=",s2,NULL);
- debug(F111,"doputenv",t,nputenvs);
- (VOID) makestr(&(putenvs[nputenvs]),t); /* Make a safe permananent copy */
- if (!putenvs[nputenvs]) {
- printf("?PUTENV - memory allocation failure\n");
- return(-9);
- }
- if (putenv(putenvs[nputenvs])) {
- printf("?PUTENV - %s\n",ck_errstr());
- return(-9);
- } else return(success = 1);
-}
-#endif /* NOPUTENV */
-#endif /* UNIX */
-
-int
-settrmtyp() {
-#ifdef OS2
-#ifdef TNCODE
- extern int ttnum; /* Last Telnet Terminal Type sent */
- extern int ttnumend; /* Has end of list been found */
-#endif /* TNCODE */
- if ((x = cmkey(ttyptab,nttyp,"","vt220",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- settermtype(x,1);
-#ifdef TNCODE
- /* So we send the correct terminal name to the host if it asks for it */
- ttnum = -1; /* Last Telnet Terminal Type sent */
- ttnumend = 0; /* end of list not found */
-#endif /* TNCODE */
- return(success = 1);
-#else /* Not OS2 */
-#ifdef UNIX
- extern int fxd_inited;
- x = cmtxt("Terminal type name, case sensitive","",&s,NULL);
-#ifdef NOPUTENV
- success = 1;
-#else
- success = doputenv("TERM",s); /* Set the TERM variable */
-#ifdef CK_CURSES
- fxd_inited = 0; /* Force reinitialization of curses database */
- (void)doxdis(0); /* Re-initialize file transfer display */
- concb((char)escape); /* Fix command terminal */
-#endif /* CK_CURSES */
-#endif /* NOPUTENV */
- return(success);
-#else
- printf(
-"\n Sorry, this version of C-Kermit does not support the SET TERMINAL TYPE\n");
- printf(
-" command. Type \"help set terminal\" for further information.\n");
- return(success = 0);
-#endif /* UNIX */
-#endif /* OS2 */
-}
-
-#ifndef NOLOCAL
-#ifdef OS2
-/* MS-DOS KERMIT compatibility modes */
-int
-setmsk() {
- if ((y = cmkey(msktab,nmsk,"MS-DOS Kermit compatibility mode",
- "keycodes",xxstring)) < 0) return(y);
-
- switch ( y ) {
-#ifdef COMMENT
- case MSK_COLOR:
- return(seton(&mskcolors));
-#endif /* COMMENT */
- case MSK_KEYS:
- return(seton(&mskkeys));
- case MSK_REN:
- return(seton(&mskrename));
- default: /* Shouldn't get here. */
- return(-2);
- }
-}
-#endif /* OS2 */
-
-#ifdef CKTIDLE
-static char iactbuf[132];
-
-char *
-getiact() {
- switch (tt_idleact) {
- case IDLE_RET: return("return");
- case IDLE_EXIT: return("exit");
- case IDLE_HANG: return("hangup");
-#ifdef TNCODE
- case IDLE_TNOP: return("Telnet NOP");
- case IDLE_TAYT: return("Telnet AYT");
-#endif /* TNCODE */
-
- case IDLE_OUT: {
- int c, k, n;
- char * p, * q, * t;
- k = ckstrncpy(iactbuf,"output ",132);
- n = k;
- q = &iactbuf[k];
- p = tt_idlestr;
- if (!p) p = "";
- if (!*p) return("output NUL");
- while ((c = *p++) && n < 131) {
- c &= 0xff;
- if (c == '\\') {
- if (n > 130) break;
- *q++ = '\\';
- *q++ = '\\';
- *q = NUL;
- n += 2;
- } else if ((c > 32 && c < 127) || c > 159) {
- *q++ = c;
- *q = NUL;
- n++;
- } else {
- if (n > (131 - 6))
- break;
- sprintf(q,"\\{%d}",c);
- k = strlen(q);
- q += k;
- n += k;
- *q = NUL;
- }
- }
- *q = NUL;
-#ifdef OS2
- k = tt_cols[VTERM];
-#else
- k = tt_cols;
-#endif /* OS2 */
- if (n > k - 52) {
- n = k - 52;
- iactbuf[n-2] = '.';
- iactbuf[n-1] = '.';
- iactbuf[n] = NUL;
- }
- return(iactbuf);
- }
- default: return("unknown");
- }
-}
-#endif /* CKTIDLE */
-
-#ifndef NOCSETS
-VOID
-setlclcharset(x) int x; {
- int i;
- tcsl = y; /* Local character set */
-#ifdef OS2
- for (i = 0; i < 4; i++) {
- G[i].init = TRUE;
- x = G[i].designation;
- G[i].c1 = (x != tcsl) && cs_is_std(x);
- x = G[i].def_designation;
- G[i].def_c1 = (x != tcsl) && cs_is_std(x);
- }
-#endif /* OS2 */
-}
-
-VOID
-setremcharset(x, z) int x, z; {
- int i;
-
-#ifdef KUI
- KuiSetProperty( KUI_TERM_REMCHARSET, (long) x, (long) z ) ;
-#endif /* KUI */
-#ifdef UNICODE
- if (x == TX_TRANSP)
-#else /* UNICODE */
- if (x == FC_TRANSP)
-#endif /* UNICODE */
- { /* TRANSPARENT? */
-#ifndef OS2
- tcsr = tcsl; /* Make both sets the same */
-#else /* OS2 */
-#ifdef CKOUNI
- tt_utf8 = 0; /* Turn off UTF8 flag */
- tcsr = tcsl = dec_kbd = TX_TRANSP; /* No translation */
- tcs_transp = 1;
-
- if (!cs_is_nrc(tcsl)) {
- G[0].def_designation = G[0].designation = TX_ASCII;
- G[0].init = TRUE;
- G[0].def_c1 = G[0].c1 = FALSE;
- G[0].size = cs94;
- G[0].national = FALSE;
- }
- for (i = cs_is_nrc(tcsl) ? 0 : 1; i < 4; i++) {
- G[i].def_designation = G[i].designation = tcsl;
- G[i].init = TRUE;
- G[i].def_c1 = G[i].c1 = FALSE;
- switch (cs_size(G[i].designation)) { /* 94, 96, or 128 */
- case 128:
- case 96:
- G[i].size = G[i].def_size = cs96;
- break;
- case 94:
- G[i].size = G[i].def_size = cs94;
- break;
- default:
- G[i].size = G[i].def_size = csmb;
- break;
- }
- G[i].national = cs_is_nrc(x);
- }
-#else /* CKOUNI */
- tcsr = tcsl; /* Make both sets the same */
- for (i = 0; i < 4; i++) {
- G[i].def_designation = G[i].designation = FC_TRANSP;
- G[i].init = FALSE;
- G[i].size = G[i].def_size = cs96;
- G[i].c1 = G[i].def_c1 = FALSE;
- G[i].rtoi = NULL;
- G[i].itol = NULL;
- G[i].ltoi = NULL;
- G[i].itor = NULL;
- G[i].national = FALSE;
- }
-#endif /* CKOUNI */
-#endif /* OS2 */
- return;
- }
-#ifdef OS2
-#ifdef CKOUNI
- else if (x == TX_UTF8) {
- tcs_transp = 0;
- tt_utf8 = 1; /* Turn it on if we are UTF8 */
- return;
- }
-#endif /* CKOUNI */
- else {
- tcs_transp = 0;
- tcsr = x; /* Remote character set */
-#ifdef CKOUNI
- tt_utf8 = 0; /* Turn off UTF8 flag */
-#endif /* CKOUNI */
-
- if (z == TT_GR_ALL) {
- int i;
-#ifdef UNICODE
- dec_kbd = x;
-#endif /* UNICODE */
- for (i = 0; i < 4; i++) {
- G[i].init = TRUE;
- if ( i == 0 && !cs_is_nrc(x) ) {
- G[0].designation = G[0].def_designation = FC_USASCII;
- G[0].size = G[0].def_size = cs94;
- G[0].national = 1;
- } else {
- G[i].def_designation = G[i].designation = x;
- switch (cs_size(x)) { /* 94, 96, or 128 */
- case 128:
- case 96:
- G[i].size = G[i].def_size = cs96;
- break;
- case 94:
- G[i].size = G[i].def_size = cs94;
- break;
- default:
- G[i].size = G[i].def_size = csmb;
- break;
- }
- G[i].national = cs_is_nrc(x);
- }
- G[i].c1 = G[i].def_c1 = x != tcsl && cs_is_std(x);
- }
-#ifdef UNICODE
- } else if (z == TT_GR_KBD) { /* Keyboard only */
- dec_kbd = x;
-#endif /* UNICODE */
- } else { /* Specific Gn */
- G[z].def_designation = G[z].designation = x;
- G[z].init = TRUE;
- switch (cs_size(x)) { /* 94, 96, or 128 */
- case 128:
- case 96:
- G[z].size = G[z].def_size = cs96;
- break;
- case 94:
- G[z].size = G[z].def_size = cs94;
- break;
- default:
- G[z].size = G[z].def_size = csmb;
- break;
- }
- G[z].c1 = G[z].def_c1 = x != tcsl && cs_is_std(x);
- G[z].national = cs_is_nrc(x);
- }
- }
-#else /* not OS2 */
- tcsr = x; /* Remote character set */
-#endif /* OS2 */
-}
-#endif /* NOCSETS */
-
-VOID
-setcmask(x) int x; {
- if (x == 7) {
- cmask = 0177;
- } else if (x == 8) {
- cmask = 0377;
- parity = 0;
- }
-#ifdef KUI
- KuiSetProperty(KUI_TERM_CMASK,x,0);
-#endif /* KUI */
-}
-
-#ifdef CK_AUTODL
-VOID
-setautodl(x,y) int x,y; {
- autodl = x;
- adl_ask = y;
-#ifdef KUI
- KuiSetProperty(KUI_TERM_AUTODOWNLOAD,x?(y?2:1):0,0);
-#endif /* KUI */
-}
-#endif /* CK_AUTODL */
-
-#ifdef OS2
-VOID
-seturlhl(int x) {
- tt_url_hilite = x;
-#ifdef KUI
- KuiSetProperty(KUI_TERM_URL_HIGHLIGHT,x,0);
-#endif /* KUI */
-}
-
-VOID
-setaprint(int x) {
- extern int aprint;
- aprint = x;
-#ifdef KUI
- KuiSetProperty(KUI_TERM_PRINTERCOPY,x,0);
-#endif /* KUI */
-}
-#endif /* OS2 */
-
-int
-settrm() {
- int i = 0;
-#ifdef OS2
- extern int colorreset, user_erasemode;
-#endif /* OS2 */
- if ((y = cmkey(trmtab,ntrm,"", "",xxstring)) < 0) return(y);
-#ifdef MAC
- printf("\n?Sorry, not implemented yet. Please use the Settings menu.\n");
- return(-9);
-#else
-#ifdef IKSD
- if (inserver) {
- if ((y = cmcfm()) < 0) return(y);
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-
- switch (y) {
- case XYTBYT: /* SET TERMINAL BYTESIZE */
- if ((y = cmnum("bytesize for terminal connection","8",10,&x,
- xxstring)) < 0)
- return(y);
- if (x != 7 && x != 8) {
- printf("\n?The choices are 7 and 8\n");
- return(success = 0);
- }
- if ((y = cmcfm()) < 0) return(y);
- setcmask(x);
-#ifdef OS2
- if (IS97801(tt_type_mode))
- SNI_bitmode(x);
-#endif /* OS2 */
- return(success = 1);
-
- case XYTSO: /* SET TERMINAL LOCKING-SHIFT */
- return(seton(&sosi));
-
- case XYTNL: /* SET TERMINAL NEWLINE-MODE */
- return(seton(&tnlm));
-
-#ifdef OS2
- case XYTCOL:
- if ((x = cmkey(ttycoltab,ncolors,"","terminal",xxstring)) < 0)
- return(x);
- else if (x == TTCOLRES) {
- if ((y = cmkey(ttcolmodetab,ncolmode,
- "","default-color",xxstring)) < 0)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- colorreset = y;
- return(success = 1);
- } else if (x == TTCOLERA) {
- if ((y = cmkey(ttcolmodetab,ncolmode,"",
- "current-color",xxstring)) < 0)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- user_erasemode = y;
- return(success=1);
- } else { /* No parse error */
- int fg = 0, bg = 0;
- fg = cmkey(ttyclrtab, nclrs,
- (x == TTCOLBOR ?
- "color for screen border" :
- "foreground color and then background color"),
- "lgray", xxstring);
- if (fg < 0)
- return(fg);
- if (x != TTCOLBOR) {
- if ((bg = cmkey(ttyclrtab,nclrs,
- "background color","blue",xxstring)) < 0)
- return(bg);
- }
- if ((y = cmcfm()) < 0)
- return(y);
- switch (x) {
- case TTCOLNOR:
- colornormal = fg | bg << 4;
- fgi = fg & 0x08;
- bgi = bg & 0x08;
- break;
- case TTCOLREV:
- colorreverse = fg | bg << 4;
- break;
- case TTCOLITA:
- coloritalic = fg | bg << 4;
- break;
- case TTCOLUND:
- colorunderline = fg | bg << 4;
- break;
- case TTCOLGRP:
- colorgraphic = fg | bg << 4;
- break;
- case TTCOLDEB:
- colordebug = fg | bg << 4;
- break;
- case TTCOLSTA:
- colorstatus = fg | bg << 4;
- break;
- case TTCOLHLP:
- colorhelp = fg | bg << 4;
- break;
- case TTCOLBOR:
- colorborder = fg;
- break;
- case TTCOLSEL:
- colorselect = fg | bg << 4;
- break;
- default:
- printf("%s - invalid\n",cmdbuf);
- return(-9);
- break;
- }
- scrninitialized[VTERM] = 0;
- VscrnInit(VTERM);
- }
- return(success = 1);
-
- case XYTCUR: { /* SET TERMINAL CURSOR */
- extern int cursorena[];
- extern int cursoron[] ; /* Cursor state on/off */
- if ((x = cmkey(ttycurtab,ncursors,"","underline",xxstring)) < 0)
- return(x);
- if ((z = cmkey(curontab,ncuron,"","on",xxstring)) < 0)
- return(z);
- if ((y = cmcfm()) < 0) return(y);
- tt_cursor = tt_cursor_usr = x;
- if ( z == 2 ) {
- cursorena[VTERM] = tt_cursorena_usr = 1;
- tt_cursor_blink = 0;
- } else {
- cursorena[VTERM] = tt_cursorena_usr = z;/* turn cursor on/off */
- tt_cursor_blink = 1;
- }
- cursoron[VTERM] = FALSE; /* Force newcursor to restore the cursor */
- return(success = 1);
- }
-#endif /* OS2 */
-
- case XYTTYP: /* SET TERMINAL TYPE */
- return(settrmtyp());
-
-#ifdef OS2
- case XYTARR: /* SET TERMINAL ARROW-KEYS */
- if ((x = cmkey(akmtab,2,"","",xxstring)) < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
- tt_arrow = x; /* TTK_NORM / TTK_APPL; see ckuusr.h */
- return(success = 1);
-
- case XYTKPD: /* SET TERMINAL KEYPAD-MODE */
- if ((x = cmkey(kpmtab,2,"","",xxstring)) < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
- tt_keypad = x; /* TTK_NORM / TTK_APPL; see ckuusr.h */
- return(success = 1);
-
- case XYTUNX: { /* SET TERM UNIX-MODE (DG) */
- extern int dgunix,dgunix_usr;
- x = seton(&dgunix);
- dgunix_usr = dgunix;
- return(x);
- }
- case XYTKBMOD: { /* SET TERM KEYBOARD MODE */
- extern int tt_kb_mode;
- if ((x = cmkey(kbmodtab,
- nkbmodtab,
- "normal",
- "special keyboard mode for terminal emulation",
- xxstring)
- ) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- tt_kb_mode = x;
- return(success = 1);
- }
-
- case XYTWRP: /* SET TERMINAL WRAP */
- return(seton(&tt_wrap));
-
- case XYSCRS:
- if ((y = cmnum("CONNECT scrollback buffer size, lines","2000",10,&x,
- xxstring)) < 0)
- return(y);
- /* The max number of lines is the RAM */
- /* we can actually dedicate to a */
- /* scrollback buffer given the maximum */
- /* process memory space of 512MB */
- if (x < 256 || x > 2000000L) {
- printf("\n?The size must be between 256 and 2,000,000.\n");
- return(success = 0);
- }
- if ((y = cmcfm()) < 0) return(y);
- tt_scrsize[VTERM] = x;
- VscrnInit(VTERM);
- return(success = 1);
-#endif /* OS2 */
-
-#ifndef NOCSETS
- case XYTCS: { /* SET TERMINAL CHARACTER-SET */
- int eol;
- /* set terminal character-set <remote> <local> */
- if ((x = cmkey(
-#ifdef CKOUNI
- txrtab,ntxrtab,
-#else /* CKOUNI */
- ttcstab,ntermc,
-#endif /* CKOUNI */
- "remote terminal character-set","",xxstring)) < 0)
- return(x);
-
-#ifdef UNICODE
- if (x == TX_TRANSP
-#ifdef CKOUNI
- || x == TX_UTF8
-#endif /* CKOUNI */
- ) {
- if ((y = cmcfm()) < 0) /* Confirm the command */
- return(y);
-#ifdef OS2
- if ( isunicode() && x == TX_TRANSP ) {
- /* If we are in unicode display mode then transparent
- * only affects the output direction. We need to know
- * the actual remote character set in order to perform
- * the tcsr -> ucs2 translation for display.
- */
- x = y = tcsl;
- } else
-#endif /* OS2 */
- y = x;
- }
-#else /* UNICODE */
- if (x == FC_TRANSP) {
- if ((y = cmcfm()) < 0) /* Confirm the command */
- return(y);
- y = x;
- }
-#endif /* UNICODE */
-
- /* Not transparent or UTF8, so get local set to translate it into */
- s = "";
-#ifdef OS2
- y = os2getcp(); /* Default is current code page */
- switch (y) {
- case 437: s = "cp437"; break;
- case 850: s = "cp850"; break;
- case 852: s = "cp852"; break;
- case 857: s = "cp857"; break;
- case 858: s = "cp858"; break;
- case 862: s = "cp862"; break;
- case 866: s = "cp866"; break;
- case 869: s = "cp869"; break;
- case 1250: s = "cp1250"; break;
- case 1251: s = "cp1251"; break;
- case 1252: s = "cp1252"; break;
- case 1253: s = "cp1253"; break;
- case 1254: s = "cp1254"; break;
- case 1255: s = "cp1255"; break;
- case 1256: s = "cp1256"; break;
- case 1257: s = "cp1257"; break;
- case 1258: s = "cp1258"; break;
- }
-#ifdef PCFONTS
-/*
- If the user has loaded a font with SET TERMINAL FONT then we want
- to change the default code page to the font that was loaded.
-*/
- if (tt_font != TTF_ROM) {
- for (y = 0; y < ntermfont; y++ ) {
- if (term_font[y].kwval == tt_font) {
- s = term_font[y].kwd;
- break;
- }
- }
- }
-#endif /* PCFONTS */
-#else /* Not K95... */
- s = fcsinfo[fcharset].keyword;
-#endif /* OS2 */
-
- if ((y = cmkey(
-#ifdef CKOUNI
- txrtab,ntxrtab,
-#else /* CKOUNI */
- ttcstab,ntermc,
-#endif /* CKOUNI */
- "local character-set",s,xxstring)) < 0)
- return(y);
-
-#ifdef UNICODE
- if (y == TX_UTF8) {
- printf("?UTF8 may not be used as a local character set.\r\n");
- return(-9);
- }
-#endif /* UNICODE */
-#ifdef OS2
- if ((z = cmkey(graphsettab,ngraphset,
- "DEC VT intermediate graphic set","all",xxstring)) < 0)
- return(z);
-#endif /* OS2 */
- if ((eol = cmcfm()) < 0)
- return(eol); /* Confirm the command */
-
- /* End of command parsing - actions begin */
- setlclcharset(y);
- setremcharset(x,z);
- return(success = 1);
- }
-#endif /* NOCSETS */
-
-#ifndef NOCSETS
- case XYTLCS: /* SET TERMINAL LOCAL-CHARACTER-SET */
- /* set terminal character-set <local> */
- s = getdcset(); /* Get display character-set name */
- if ((y = cmkey(
-#ifdef CKOUNI
- txrtab,ntxrtab,
-#else /* CKOUNI */
- fcstab,nfilc,
-#endif /* CKOUNI */
- "local character-set",s,xxstring)) < 0)
- return(y);
-
-#ifdef UNICODE
- if (y == TX_UTF8) {
- printf("?UTF8 may not be used as a local character set.\r\n");
- return(-9);
- }
-#endif /* UNICODE */
- if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
-
- /* End of command parsing - action begins */
-
- setlclcharset(y);
- return(success = 1);
-#endif /* NOCSETS */
-
-#ifndef NOCSETS
-#ifdef UNICODE
- case XYTUNI: /* SET TERMINAL UNICODE */
- return(seton(&tt_unicode));
-#endif /* UNICODE */
-
- case XYTRCS: /* SET TERMINAL REMOTE-CHARACTER-SET */
- /* set terminal character-set <remote> <Graphic-set> */
- if ((x = cmkey(
-#ifdef CKOUNI
- txrtab, ntxrtab,
-#else /* CKOUNI */
- ttcstab,ntermc,
-#endif /* CKOUNI */
- "remote terminal character-set","",xxstring)) < 0)
- return(x);
-
-#ifdef UNICODE
- if (x == TX_TRANSP
-#ifdef CKOUNI
- || x == TX_UTF8
-#endif /* CKOUNI */
- ) {
- if ((y = cmcfm()) < 0) /* Confirm the command */
- return(y);
-#ifdef OS2
- if ( isunicode() && x == TX_TRANSP ) {
- /* If we are in unicode display mode then transparent
- * only affects the output direction. We need to know
- * the actual remote character set in order to perform
- * the tcsr -> ucs2 translation for display.
- */
- x = tcsl;
- }
-#endif /* OS2 */
- }
-#else /* UNICODE */
- if (x == FC_TRANSP) {
- if ((y = cmcfm()) < 0) /* Confirm the command */
- return(y);
- }
-#endif /* UNICODE */
- else {
-#ifdef OS2
- if ((z = cmkey(graphsettab,ngraphset,
- "DEC VT intermediate graphic set","all",xxstring)) < 0)
- return(z);
-#endif /* OS2 */
- if ((y = cmcfm()) < 0) /* Confirm the command */
- return(y);
- }
- /* Command parsing ends here */
-
- setremcharset(x,z);
- return(success = 1);
-#endif /* NOCSETS */
-
- case XYTEC: /* SET TERMINAL ECHO */
- if ((x = cmkey(rltab,nrlt,"which side echos during CONNECT",
- "remote", xxstring)) < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef NETCONN
- oldplex = x;
-#endif /* NETCONN */
- duplex = x;
- return(success = 1);
-
- case XYTESC: /* SET TERM ESC */
- if ((x = cmkey(nabltab,nnabltab,"","enabled",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- tt_escape = x;
- return(1);
-
- case XYTCRD: /* SET TERMINAL CR-DISPLAY */
- if ((x = cmkey(crdtab,2,"", "normal", xxstring)) < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
- tt_crd = x;
- return(success = 1);
-
- case XYTLFD: /* SET TERMINAL LF-DISPLAY */
- if ((x = cmkey(crdtab,2,"", "normal", xxstring)) < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
- tt_lfd = x;
- return(success = 1);
-
-#ifdef OS2
- case XYTANS: { /* SET TERMINAL ANSWERBACK */
-/*
- NOTE: We let them enable and disable the answerback sequence, but we
- do NOT let them change it, and we definitely do not let the host set it.
- This is a security feature.
-
- As of 1.1.8 we allow the SET TERM ANSWERBACK MESSAGE <string> to be
- used just as MS-DOS Kermit does. C0 and C1 controls as well as DEL
- are not allowed to be used as characters. They are translated to
- underscore. This may not be set by APC.
-*/
- if ((x = cmkey(anbktab,nansbk,"", "off", xxstring)) < 0)
- return(x);
- if (x < 2) {
- if ((y = cmcfm()) < 0)
- return(y);
- tt_answer = x;
- return(success = 1);
- } else if ( x == 2 || x == 3) {
- int len = 0;
- extern int safeanswerbk;
- extern char useranswerbk[];
- if ((y = cmtxt("Answerback extension","",&s,xxstring)) < 0)
- return(y);
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
- return(success = 0);
- len = strlen(s);
- if (x == 2) {
- /* Safe Answerback's don't have C0/C1 chars */
- for (z = 0; z < len; z++) {
- if ((s[z] & 0x7F) <= SP || (s[z] & 0x7F) == DEL)
- useranswerbk[z] = '_';
- else
- useranswerbk[z] = s[z];
- }
- useranswerbk[z] = '\0';
- safeanswerbk = 1 ; /* TRUE */
- } else {
- ckstrncpy(useranswerbk,s,60); /* (see ckocon.c) */
- safeanswerbk = 0; /* FALSE */
- }
- updanswerbk();
- return(success = 1);
- } else
- return(success = 0);
- }
-#endif /* OS2 */
-
-#ifdef CK_APC
- case XYTAPC:
- if ((y = cmkey(apctab,napctab,
- "application program command execution","",
- xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
- return(success = 0);
- apcstatus = y;
- return(success = 1);
-
-#ifdef CK_AUTODL
- case XYTAUTODL: /* AUTODOWNLOAD */
- if ((y = cmkey(adltab,nadltab,"Auto-download options","",
- xxstring)) < 0)
- return(y);
- switch (y) {
- case TAD_ON:
- case TAD_OFF:
- if ((x = cmcfm()) < 0)
- return(x);
- setautodl(y,0);
- break;
- case TAD_ASK:
- if ((x = cmcfm()) < 0)
- return(x);
- setautodl(TAD_ON,1);
- break;
- case TAD_ERR:
- if ((y = cmkey(adlerrtab,nadlerrtab,"","", xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- adl_err = y;
- break;
-#ifdef OS2
- case TAD_K:
- if ((y = cmkey(adlxtab,nadlxtab,"","", xxstring)) < 0)
- return(y);
- switch (y) {
- case TAD_X_C0:
- if ((y = cmkey(adlc0tab,nadlc0tab,"",
- "processed-by-emulator",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- adl_kc0 = y;
- break;
- case TAD_X_DETECT:
- if ((y = cmkey(adldtab,nadldtab,"","packet",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- adl_kmode = y;
- break;
- case TAD_X_STR:
- if ((y = cmtxt("Kermit start string","KERMIT READY TO SEND...",
- &s,xxstring)) < 0)
- return(y);
- free(adl_kstr);
- adl_kstr = strdup(s);
- break;
- }
- break;
-
- case TAD_Z:
- if ((y = cmkey(adlxtab,nadlxtab,"","",xxstring)) < 0)
- return(y);
- switch (y) {
- case TAD_X_C0:
- if ((y = cmkey(adlc0tab,nadlc0tab,"",
- "processed-by-emulator",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- adl_zc0 = y;
- break;
- case TAD_X_DETECT:
- if ((y = cmkey(adldtab,nadldtab,"","packet",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- adl_zmode = y;
- break;
- case TAD_X_STR:
- if ((y = cmtxt("","rz\\{13}",&s,xxstring)) < 0)
- return(y);
- free(adl_zstr);
- adl_zstr = strdup(s);
- break;
- }
- break;
-#endif /* OS2 */
- }
- return(success = 1);
-
-#endif /* CK_AUTODL */
-#endif /* CK_APC */
-
-#ifdef OS2
- case XYTBEL:
- return(success = setbell());
-
- case XYTMBEL: /* MARGIN-BELL */
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if (y) { /* ON */
- if ((z = cmnum("Column at which to set margin bell",
- "72",10,&x,xxstring)) < 0)
- return(z);
- }
- if ((z = cmcfm()) < 0) return(z);
- marginbell = y;
- marginbellcol = x;
- return(success = 1);
-#endif /* OS2 */
-
-#ifdef CKTIDLE
- case XYTIDLE: /* IDLE-SEND */
- case XYTITMO: /* IDLE-TIMEOUT */
- if ((z = cmnum("seconds of idle time to wait, or 0 to disable",
- "0",10,&x,xxstring)) < 0)
- return(z);
- if (y == XYTIDLE) {
- if ((y = cmtxt("string to send, may contain kverbs and variables",
- "\\v(newline)",&s,xxstring)) < 0)
- return(y);
- tt_idlesnd_tmo = x; /* (old) */
- tt_idlelimit = x; /* (new) */
- makestr(&tt_idlestr,brstrip(s)); /* (new) */
- tt_idlesnd_str = tt_idlestr; /* (old) */
- tt_idleact = IDLE_OUT; /* (new) */
- } else {
- if ((y = cmcfm()) < 0)
- return(y);
- tt_idlelimit = x;
- }
-#ifdef OS2
- puterror(VTERM);
-#endif /* OS2 */
- return(success = 1);
-
- case XYTIACT: { /* SET TERM IDLE-ACTION */
- if ((y = cmkey(idlacts,nidlacts,"","",xxstring)) < 0)
- return(y);
- if (y == IDLE_OUT) {
- if ((x = cmtxt("string to send, may contain kverbs and variables"
- , "",&s,xxstring)) < 0)
- return(x);
- makestr(&tt_idlestr,brstrip(s)); /* (new) */
- tt_idlesnd_str = tt_idlestr; /* (old) */
- } else {
- if ((x = cmcfm()) < 0)
- return(x);
- }
- tt_idleact = y;
- return(success = 1);
- }
-#endif /* CKTIDLE */
-
- case XYTDEB: /* TERMINAL DEBUG */
- y = seton(&x); /* Go parse ON or OFF */
- if (y > 0) /* Command succeeded? */
- setdebses(x);
- return(y);
-
-#ifdef OS2
- case XYTASCRL: /* SET TERMINAL AUTOSCROLL */
- y = seton(&autoscroll);
- return(y);
-
- case XYTAPAGE: /* SET TERMINAL AUTOPAGE */
- y = seton(&wy_autopage);
- return(y);
-
- case XYTROL: /* SET TERMINAL ROLL */
- if ((y = cmkey(rolltab,nroll,"scrollback mode","insert",xxstring))<0)
- return(y);
- if (y == TTR_KEYS) {
- if ((x = cmkey(rollkeytab,nrollkey,"","send",xxstring))<0)
- return(x);
- if ((z = cmcfm()) < 0) return(z);
- tt_rkeys[VTERM] = x;
- } else {
- if ((x = cmcfm()) < 0) return(x);
- tt_roll[VTERM] = y;
- }
- return(success = 1);
-
- case XYTCTS: /* SET TERMINAL TRANSMIT-TIMEOUT */
- y = cmnum("Maximum seconds to allow CTS off during CONNECT",
- "5",10,&x,xxstring);
- return(setnum(&tt_ctstmo,x,y,10000));
-
- case XYTCPG: { /* SET TERMINAL CODE-PAGE */
- int i;
- int cp = -1;
- y = cmnum("PC code page to use during terminal emulation",
- ckitoa(os2getcp()),10,&x,xxstring);
- if ((x = setnum(&cp,x,y,11000)) < 0) return(x);
- if (os2setcp(cp) != 1) {
-#ifdef NT
- if (isWin95())
- printf(
- "Sorry, Windows 95 does not support code page switching\n");
- else
-#endif /* NT */
- printf(
- "Sorry, %d is not a valid code page for this system.\n",cp);
- return(-9);
- }
- /* Force the terminal character-sets conversions to be updated */
- for ( i = 0; i < 4; i++ )
- G[i].init = TRUE;
- return(1);
- }
-
- case XYTPAC: /* SET TERMINAL OUTPUT-PACING */
- y = cmnum(
- "Pause between sending each character during CONNECT, milliseconds",
- "-1",10,&x,xxstring);
- return(setnum(&tt_pacing,x,y,10000));
-
-#ifdef OS2MOUSE
- case XYTMOU: { /* SET TERMINAL MOUSE */
- int old_mou = tt_mouse;
- if ((x = seton(&tt_mouse)) < 0)
- return(x);
- if (tt_mouse != old_mou)
- if (tt_mouse)
- os2_mouseon();
- else
- os2_mouseoff();
- return(1);
- }
-#endif /* OS2MOUSE */
-#endif /* OS2 */
-
- case XYTWID: {
- if ((y = cmnum(
-#ifdef OS2
- "number of columns in display window during CONNECT",
-#else
- "number of columns on your screen",
-#endif /* OS2 */
- "80",10,&x,xxstring)) < 0)
- return(y);
- if ((y = cmcfm()) < 0) return(y);
-#ifdef OS2
- return(success = os2_settermwidth(x));
-#else /* Not OS/2 */
- tt_cols = x;
- return(success = 1);
-#endif /* OS2 */
- }
-
- case XYTHIG:
- if ((y = cmnum(
-#ifdef OS2
- "number of rows in display window during CONNECT, not including status line",
- tt_status[VTERM]?"24":"25",
-#else
- "24","number of rows on your screen",
-#endif /* OS2 */
- 10,&x,xxstring)) < 0)
- return(y);
- if ((y = cmcfm()) < 0) return(y);
-
-#ifdef OS2
- return (success = os2_settermheight(x));
-#else /* Not OS/2 */
- tt_rows = x;
- return(success = 1);
-#endif /* OS2 */
-
-#ifdef OS2
- case XYTPRN: { /* Print Mode */
- extern bool xprint, aprint, cprint, uprint;
- if ((y = cmkey(prnmtab,nprnmtab,"","off", xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- switch (y) {
- case 0:
- if (cprint || uprint || aprint || xprint)
- printeroff();
- cprint = xprint = uprint = 0;
- setaprint(0);
- break;
- case 1:
- if (!(cprint || uprint || aprint || xprint))
- printeron();
- setaprint(1);
- cprint = xprint = uprint = 0;
- break;
- case 2:
- if (!(cprint || uprint || aprint || xprint))
- printeron();
- cprint = 1;
- setaprint(0);
- xprint = uprint = 0;
- break;
- case 3:
- if (!(cprint || uprint || aprint || xprint))
- printeron();
- uprint = 1;
- setaprint(0);
- xprint = cprint = 0;
- break;
- }
- return(1);
- }
-#else
-#ifdef XPRINT
- case XYTPRN: {
- extern int tt_print;
- if ((x = seton(&tt_print)) < 0)
- return(x);
- return(success = 1);
- }
-#endif /* XPRINT */
-#endif /* OS2 */
-
-#ifdef OS2
- case XYTSCNM: {
- extern int decscnm, decscnm_usr;
- if ((y = cmkey(normrev,4,"",
- decscnm_usr?"reverse":"normal",
- xxstring)
- ) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- decscnm_usr = y;
- if (decscnm != decscnm_usr)
- flipscreen(VTERM);
- return(1);
- }
- case XYTOPTI:
- if ((y = cmkey(onoff,2,"",tt_diff_upd?"on":"off",
- xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- tt_diff_upd = y;
- return(1);
- case XYTUPD: {
- int mode, delay;
- if ((mode = cmkey(scrnupd,nscrnupd,"","fast",xxstring)) < 0) {
- return(mode);
- } else {
- y = cmnum(
- "Pause between FAST screen updates in CONNECT mode, milliseconds",
- "100",10,&x,xxstring
- );
- if (x < 0 || x > 1000 ) {
- printf(
- "\n?The update rate must be between 0 and 1000 milliseconds.\n"
- );
- return(success = 0);
- }
- if ((y = cmcfm()) < 0) return(y);
-
- updmode = tt_updmode = mode;
- return(setnum(&tt_update,x,y,10000));
- }
- }
- case XYTCTRL:
- if ((x = cmkey(termctrl,ntermctrl,"","7",xxstring)) < 0) {
- return(x);
- } else {
- if ((y = cmcfm()) < 0)
- return(y);
- switch ( x ) {
- case 8:
- send_c1 = send_c1_usr = TRUE;
- break;
- case 7:
- default:
- send_c1 = send_c1_usr = FALSE;
- break;
- }
- }
- return(success = TRUE);
- break;
-
-#ifdef PCFONTS
- case XYTFON:
- if ( !IsOS2FullScreen() ) {
- printf(
- "\n?SET TERMINAL FONT is only supported in Full Screen sessions.\n");
- return(success = FALSE);
- }
-
- if ((x = cmkey(term_font,ntermfont,"","default",xxstring)) < 0) {
- return(x);
- } else {
- if ((y = cmcfm()) < 0) return(y);
- if ( !os2LoadPCFonts() ) {
- tt_font = x;
- return(success = TRUE);
- } else {
- printf(
- "\n?PCFONTS.DLL is not available in CKERMIT executable directory.\n");
- return(success = FALSE);
- }
- }
- break;
-#else /* PCFONTS */
-#ifdef NT
-#ifdef KUI
- case XYTFON:
- return(setguifont()); /* ckuus3.c */
-#endif /* KUI */
-#endif /* NT */
-#endif /* PCFONTS */
-
- case XYTVCH: {
- extern int pheight, marginbot, cmd_rows, cmd_cols;
- if ((x = cmkey(tvctab,ntvctab,"",isWin95()?"win95-safe":"enabled",
- xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
-#ifndef KUI
- if (x != tt_modechg) {
- switch (x) {
- case TVC_DIS:
- /* When disabled the heights of all of the virtual screens */
- /* must be equal to the physical height of the console */
- /* window and may not be changed. */
- /* The width of the window may not be altered. */
- tt_modechg = TVC_ENA; /* Temporary */
- if (marginbot > pheight-(tt_status[VTERM]?1:0))
- marginbot = pheight-(tt_status[VTERM]?1:0);
- tt_szchng[VCMD] = 1 ;
- tt_rows[VCMD] = pheight;
- VscrnInit(VCMD);
- SetCols(VCMD);
- cmd_rows = y;
-
- tt_szchng[VTERM] = 2 ;
- tt_rows[VTERM] = pheight - (tt_status[VTERM]?1:0);
- VscrnInit(VTERM);
-
- break;
-
- case TVC_ENA:
- /* When enabled the physical height of the console windows */
- /* should be adjusted to the height of the virtual screen */
- /* The width may be set to anything. */
- /* nothing to do */
- break;
-
- case TVC_W95:
- /* Win95-safe mode allows the physical height to change */
- /* but restricts it to a width of 80 and a height equal to */
- /* 25, 43, or 50. Must be adjusted now. */
- /* The virtual heights must be equal to the above. */
- if (pheight != 25 && pheight != 43 && pheight != 50) {
- if (pheight < 25)
- y = 25;
- else if (pheight < 43)
- y = 43;
- else
- y = 50;
- } else
- y = pheight;
-
- tt_modechg = TVC_ENA; /* Temporary */
-
- tt_szchng[VCMD] = 1;
- tt_rows[VCMD] = y;
- tt_cols[VCMD] = 80;
- VscrnInit(VCMD);
- SetCols(VCMD);
- cmd_rows = y;
- cmd_cols = 80;
-
- marginbot = y-(tt_status[VTERM]?1:0);
- tt_szchng[VTERM] = 2;
- tt_rows[VTERM] = y - (tt_status[VTERM]?1:0);
- tt_cols[VTERM] = 80;
- VscrnInit(VTERM);
- break;
- }
- tt_modechg = x;
- }
- return(success = 1);
-#else
- return(success = 0);
-#endif /* KUI */
- }
- case XYTSTAT: {
- extern int marginbot;
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- if (y != tt_status[VTERM] || y != tt_status_usr[VTERM]) {
- /* Might need to fixup the margins */
- if ( marginbot == VscrnGetHeight(VTERM)-(tt_status[VTERM]?1:0) )
- if (y) {
- marginbot--;
- } else {
- marginbot++;
- }
- tt_status_usr[VTERM] = tt_status[VTERM] = y;
- if (y) {
- tt_szchng[VTERM] = 2;
- tt_rows[VTERM]--;
- VscrnInit(VTERM); /* Height set here */
-#ifdef TNCODE
- if (TELOPT_ME(TELOPT_NAWS))
- tn_snaws();
-#endif /* TNCODE */
-#ifdef RLOGCODE
- if (TELOPT_ME(TELOPT_NAWS))
- rlog_naws();
-#endif /* RLOGCODE */
-#ifdef SSHBUILTIN
- if (TELOPT_ME(TELOPT_NAWS))
- ssh_snaws();
-#endif /* SSHBUILTIN */
- } else {
- tt_szchng[VTERM] = 1;
- tt_rows[VTERM]++;
- VscrnInit(VTERM); /* Height set here */
-#ifdef TNCODE
- if (TELOPT_ME(TELOPT_NAWS))
- tn_snaws();
-#endif /* TNCODE */
-#ifdef RLOGCODE
- if (TELOPT_ME(TELOPT_NAWS))
- rlog_naws();
-#endif /* RLOGCODE */
-#ifdef SSHBUILTIN
- if (TELOPT_ME(TELOPT_NAWS))
- ssh_snaws();
-#endif /* SSHBUILTIN */
- }
- }
- return(1);
- }
-#endif /* OS2 */
-
-#ifdef NT
- case XYTATTBUG:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- tt_attr_bug = y;
- return(1);
-#endif /* NT */
-
-#ifdef OS2
- case XYTSGRC:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- sgrcolors = y;
- return(1);
-
- case XYTSEND:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- tt_senddata = y;
- return(1);
-
- case XYTSEOB:
- if ((y = cmkey(ttyseobtab,2,"","us_cr",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- wy_blockend = y;
- return(1);
-
- case XYTURLHI: {
- int done = 0, attr = VT_CHAR_ATTR_NORMAL;
-
- if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
- return(x);
- if (x) {
- z = 0;
- while (!done) {
- if ((y = cmkey(ttyprotab,nprotect,"",
- z?"done":"reverse",xxstring)) < 0)
- return(y);
- switch (y) {
- case TTATTDONE:
- done = TRUE;
- break;
- case TTATTBLI:
- attr |= VT_CHAR_ATTR_BLINK;
- break;
- case TTATTREV:
- attr |= VT_CHAR_ATTR_REVERSE;
- break;
- case TTATTITA:
- attr |= VT_CHAR_ATTR_ITALIC;
- break;
- case TTATTUND:
- attr |= VT_CHAR_ATTR_UNDERLINE;
- break;
- case TTATTBLD:
- attr |= VT_CHAR_ATTR_BOLD;
- break;
- case TTATTDIM:
- attr |= VT_CHAR_ATTR_DIM;
- break;
- case TTATTINV:
- attr |= VT_CHAR_ATTR_INVISIBLE;
- break;
- case TTATTNOR:
- break;
- }
- z = 1; /* One attribute has been chosen */
- }
- }
- if ((z = cmcfm()) < 0) return(z);
- seturlhl(x);
- if (x)
- tt_url_hilite_attr = attr;
- return(1);
- }
- case XYTATTR:
- if ((x = cmkey(ttyattrtab,nattrib,"","underline",xxstring)) < 0)
- return(x);
- switch (x) {
- case TTATTBLI:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- trueblink = y;
-#ifndef KUI
- if ( !trueblink && trueunderline ) {
- trueunderline = 0;
- printf("Warning: Underline being simulated by color.\n");
- }
-
-#endif /* KUI */
- break;
-
- case TTATTDIM:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- truedim = y;
- break;
-
- case TTATTREV:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- truereverse = y;
- break;
-
- case TTATTUND:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- trueunderline = y;
-#ifndef KUI
- if (!trueblink && trueunderline) {
- trueblink = 1;
- printf("Warning: True blink mode is active.\n");
- }
-#endif /* KUI */
- break;
-
- case TTATTITA:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- trueitalic = y;
- break;
-
- case TTATTPRO: { /* Set default Protected Character attribute */
- extern vtattrib WPattrib; /* current WP Mode Attrib */
- extern vtattrib defWPattrib; /* default WP Mode Attrib */
- vtattrib wpa = {0,0,0,0,0,1,0,0,0,0,0}; /* Protected */
- int done = 0;
-
- x = 0;
- while (!done) {
- if ((y = cmkey(ttyprotab,nprotect,"",
- x?"done":"dim",xxstring)) < 0)
- return(y);
- switch (y) {
- case TTATTNOR:
- break;
- case TTATTBLI: /* Blinking doesn't work */
- wpa.blinking = TRUE;
- break;
- case TTATTREV:
- wpa.reversed = TRUE;
- break;
- case TTATTITA:
- wpa.italic = TRUE;
- break;
- case TTATTUND:
- wpa.underlined = TRUE;
- break;
- case TTATTBLD:
- wpa.bold = TRUE;
- break;
- case TTATTDIM:
- wpa.dim = TRUE;
- break;
- case TTATTINV:
- wpa.invisible = TRUE ;
- break;
- case TTATTDONE:
- done = TRUE;
- break;
- }
- x = 1; /* One attribute has been chosen */
- }
- if ((x = cmcfm()) < 0) return(x);
- WPattrib = defWPattrib = wpa;
- break;
- }
- }
- return(1);
-
- case XYTKEY: { /* SET TERMINAL KEY */
- int t, x, y;
- int clear = 0, deflt = 0;
- int confirmed = 0;
- int flag = 0;
- int kc = -1; /* Key code */
- int litstr = 0; /* Literal String? */
- char *s = NULL; /* Key binding */
-#ifndef NOKVERBS
- char *p = NULL; /* Worker */
-#endif /* NOKVERBS */
- con_event defevt;
- extern int os2gks;
- extern int mskkeys;
- extern int initvik;
- struct FDB kw,sw,nu,cm;
-
- defevt.type = error;
-
- if ((t = cmkey(ttkeytab,nttkey,"","",xxstring)) < 0)
- return(t);
- cmfdbi(&nu, /* First FDB - command switches */
- _CMNUM, /* fcode */
- "/literal, keycode, or action",
- "", /* default */
- "", /* addtl string data */
- 10, /* addtl numeric data 1: radix */
- 0, /* addtl numeric data 2: 0 */
- xxstring, /* Processing function */
- NULL, /* Keyword table */
- &sw /* Pointer to next FDB */
- ); /* */
- cmfdbi(&sw, /* Second FDB - switches */
- _CMKEY, /* fcode */
- "",
- "", /* default */
- "", /* addtl string data */
- nstrmswitab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- strmswitab, /* Keyword table */
- &kw /* Pointer to next FDB */
- );
- cmfdbi(&kw, /* Third FDB - command switches */
- _CMKEY, /* fcode */
- "/literal, keycode, or action",
- "", /* default */
- "", /* addtl string data */
- nstrmkeytab, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2 */
- xxstring, /* Processing function */
- strmkeytab, /* Keyword table */
- &cm /* Pointer to next FDB */
- );
- cmfdbi(&cm, /* Final FDB - Confirmation */
- _CMCFM, /* fcode */
- "",
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- NULL, /* Keyword table */
- NULL /* Pointer to next FDB */
- );
- while (kc < 0) {
- x = cmfdb(&nu); /* Parse something */
- if (x < 0)
- return(x);
-
- switch (cmresult.fcode) {
- case _CMCFM:
- printf(" Press key to be defined: ");
- conbin((char)escape); /* Put terminal in binary mode */
- os2gks = 0; /* Turn off Kverb preprocessing */
- kc = congks(0); /* Get character or scan code */
- os2gks = 1; /* Turn on Kverb preprocessing */
- concb((char)escape); /* Restore terminal to cbreak mode */
- if (kc < 0) { /* Check for error */
- printf("?Error reading key\n");
- return(0);
- }
- shokeycode(kc,t); /* Show current definition */
- flag = 1; /* Remember it's a multiline command */
- break;
- case _CMNUM:
- kc = cmresult.nresult;
- break;
- case _CMKEY:
- if (cmresult.fdbaddr == &sw) { /* Switch */
- if (cmresult.nresult == 0)
- litstr = 1;
- } else if (cmresult.fdbaddr == &kw) { /* Keyword */
- if (cmresult.nresult == 0)
- clear = 1;
- else
- deflt = 1;
- if ((x = cmcfm()) < 0)
- return(x);
- if (clear)
- clearkeymap(t);
- else if (deflt)
- defaultkeymap(t);
- initvik = 1;
- return(1);
- }
- }
- }
-
- /* Normal SET TERMINAL KEY <terminal> <scancode> <value> command... */
-
- if (mskkeys)
- kc = msktock(kc);
-
- if (kc < 0 || kc >= KMSIZE) {
- printf("?key code must be between 0 and %d\n", KMSIZE - 1);
- return(-9);
- }
- if (kc == escape) {
- printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
- return(-9);
- }
- wideresult = -1;
- if (flag) {
- cmsavp(psave,PROMPTL);
- cmsetp(" Enter new definition: ");
- cmini(ckxech);
- }
- def_again:
- if (flag) prompt(NULL);
- if ((y = cmtxt("key definition,\n\
- or Ctrl-C to cancel this command,\n\
- or Enter to restore default definition",
- "",&s,NULL)) < 0) {
- if (flag) /* Handle parse errors */
- goto def_again;
- else
- return(y);
- }
- s = brstrip(s);
-#ifndef NOKVERBS
- p = s; /* Save this place */
-#endif /* NOKVERBS */
-/*
- If the definition included any \Kverbs, quote the backslash so the \Kverb
- will still be in the definition when the key is pressed. We don't do this
- in zzstring(), because \Kverbs are valid only in this context and nowhere
- else.
-
- We use this code active for all versions that support SET KEY, even if they
- don't support \Kverbs, because otherwise \K would behave differently for
- different versions.
-*/
- for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
- if ((x > 0) &&
- (s[x] == 'K' || s[x] == 'k')
- ) { /* Have K */
-
- if ((x == 1 && s[x-1] == CMDQ) ||
- (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
- line[y++] = CMDQ; /* Make it \\K */
- }
- if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
- line[y-1] = CMDQ; /* Have \{K */
- line[y++] = '{'; /* Make it \\{K */
- }
- }
- line[y] = s[x];
- }
- line[y++] = NUL; /* Terminate */
- s = line + y + 1; /* Point to after it */
- x = LINBUFSIZ - (int) strlen(line) - 1; /* Get remaining space */
- if ((x < (LINBUFSIZ / 2)) ||
- (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
- printf("?Key definition too long\n");
- if (flag) cmsetp(psave);
- return(-9);
- }
- s = line + y + 1; /* Point to result. */
-
-#ifndef NOKVERBS
-/*
- Special case: see if the definition starts with a \Kverb.
- If it does, point to it with p, otherwise set p to NULL.
-*/
- p = s;
- if (*p++ == CMDQ) {
- if (*p == '{') p++;
- p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
- }
-#endif /* NOKVERBS */
-
- switch (strlen(s)) { /* Action depends on length */
- case 0: /* Clear individual key def */
- deletekeymap(t,kc);
- break;
- case 1:
- if (!litstr) {
- defevt.type = key; /* Single character */
- defevt.key.scancode = *s;
- break;
- }
- default: /* Character string */
-#ifndef NOKVERBS
- if (p) {
- y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
- /* Need exact match */
- debug(F101,"set key kverb lookup",0,y);
- if (y > -1) {
- defevt.type = kverb;
- defevt.kverb.id = y;
- break;
- }
- }
-#endif /* NOKVERBS */
- if (litstr) {
- defevt.type = literal;
- defevt.literal.string = (char *) malloc(strlen(s)+1);
- if (defevt.literal.string)
- strcpy(defevt.literal.string, s); /* safe */
- } else {
- defevt.type = macro;
- defevt.macro.string = (char *) malloc(strlen(s)+1);
- if (defevt.macro.string)
- strcpy(defevt.macro.string, s); /* safe */
- }
- break;
- }
- insertkeymap(t, kc, defevt);
- if (flag)
- cmsetp(psave);
- initvik = 1; /* Update VIK table */
- return(1);
- }
-
-#ifdef PCTERM
- case XYTPCTERM: /* PCTERM Keyboard Mode */
- if ((x = seton(&tt_pcterm)) < 0) return(x);
- return(success = 1);
-#endif /* PCTERM */
-#endif /* OS2 */
-
-#ifdef CK_TRIGGER
- case XYTRIGGER:
- if ((y = cmtxt("String to trigger automatic return to command mode",
- "",&s,xxstring)) < 0)
- return(y);
- makelist(s,tt_trigger,TRIGGERS);
- return(1);
-#endif /* CK_TRIGGER */
-
-#ifdef OS2
- case XYTSAC:
- if ((y = cmnum("ASCII value to use for spacing attributes",
- "32",10,&x,xxstring)) < 0)
- return(y);
- if ((y = cmcfm()) < 0) return(y);
- tt_sac = x;
- return(success = 1);
-
- case XYTKBDGL: { /* SET TERM KBD-FOLLOWS-GL/GR */
- extern int tt_kb_glgr; /* from ckoco3.c */
- if ((x = seton(&tt_kb_glgr)) < 0)
- return(x);
- return(success = 1);
- }
-#ifndef NOCSETS
- case XYTVTLNG: /* SET TERM DEC-LANGUAGE */
- if ((y = cmkey(vtlangtab,nvtlangtab,"VT language",
- IS97801(tt_type_mode)?"german":"north-american",
- xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
-
- /* A real VT terminal would use the language to set the */
- /* default keyboard language for both 8-bit multinational */
- /* and 7-bit national modes. For 8-bit mode it would */
- /* set the terminal character-set to the ISO set if it */
- /* is not already set. */
- /* Latin-1 can be replaced by DEC Multinational */
- switch (y) {
- case VTL_NORTH_AM: /* North American */
- /* Multinational: Latin-1 */
- /* National: US_ASCII */
- dec_lang = y;
- dec_nrc = TX_ASCII;
- dec_kbd = TX_8859_1;
- break;
- case VTL_BRITISH :
- /* Multinational: Latin-1 */
- /* National: UK_ASCII */
- dec_lang = y;
- dec_nrc = TX_BRITISH;
- dec_kbd = TX_8859_1;
- break;
- case VTL_FRENCH :
- case VTL_BELGIAN :
- case VTL_CANADIAN:
- /* Multinational: Latin-1 */
- /* National: FR_ASCII */
- dec_lang = y;
- dec_nrc = TX_FRENCH;
- dec_kbd = TX_8859_1;
- break;
- case VTL_FR_CAN :
- /* Multinational: Latin-1 */
- /* National: FC_ASCII */
- dec_lang = y;
- dec_nrc = TX_CN_FRENCH;
- dec_kbd = TX_8859_1;
- break;
- case VTL_DANISH :
- case VTL_NORWEGIA:
- /* Multinational: Latin-1 */
- /* National: NO_ASCII */
- dec_lang = y;
- dec_nrc = TX_NORWEGIAN;
- dec_kbd = TX_8859_1;
- break;
- case VTL_FINNISH :
- /* Multinational: Latin-1 */
- /* National: FI_ASCII */
- dec_lang = y;
- dec_nrc = TX_FINNISH;
- dec_kbd = TX_8859_1;
- break;
- case VTL_GERMAN :
- /* Multinational: Latin-1 */
- /* National: GR_ASCII */
- dec_lang = y;
- dec_nrc = TX_GERMAN;
- dec_kbd = TX_8859_1;
- break;
- case VTL_DUTCH :
- /* Multinational: Latin-1 */
- /* National: DU_ASCII */
- dec_lang = y;
- dec_nrc = TX_DUTCH;
- dec_kbd = TX_8859_1;
- break;
- case VTL_ITALIAN :
- /* Multinational: Latin-1 */
- /* National: IT_ASCII */
- dec_lang = y;
- dec_nrc = TX_ITALIAN;
- dec_kbd = TX_8859_1;
- break;
- case VTL_SW_FR :
- case VTL_SW_GR :
- /* Multinational: Latin-1 */
- /* National: CH_ASCII */
- dec_lang = y;
- dec_nrc = TX_SWISS;
- dec_kbd = TX_8859_1;
- break;
- case VTL_SWEDISH :
- /* Multinational: Latin-1 */
- /* National: SW_ASCII */
- dec_lang = y;
- dec_nrc = TX_SWEDISH;
- dec_kbd = TX_8859_1;
- break;
- case VTL_SPANISH :
- /* Multinational: Latin-1 */
- /* National: SP_ASCII */
- dec_lang = y;
- dec_nrc = TX_SPANISH;
- dec_kbd = TX_8859_1;
- break;
- case VTL_PORTUGES:
- /* Multinational: Latin-1 */
- /* National: Portugese ASCII */
- dec_lang = y;
- dec_nrc = TX_PORTUGUESE;
- dec_kbd = TX_8859_1;
- break;
- case VTL_HEBREW :
- /* Multinational: Latin-Hebrew / DEC-Hebrew */
- /* National: DEC 7-bit Hebrew */
- dec_lang = y;
- dec_nrc = TX_HE7;
- dec_kbd = TX_8859_8;
- break;
- case VTL_GREEK :
- /* Multinational: Latin-Greek / DEC-Greek */
- /* National: DEC Greek NRC */
- /* is ELOT927 equivalent to DEC Greek???? */
- dec_lang = y;
- dec_nrc = TX_ELOT927;
- dec_kbd = TX_8859_7;
- break;
-#ifdef COMMENT
- case VTL_TURK_Q :
- case VTL_TURK_F :
- /* Multinational: Latin-Turkish / DEC-Turkish */
- /* National: DEC 7-bit Turkish */
- break;
-#endif /* COMMENT */
- case VTL_HUNGARIA:
- /* Multinational: Latin-2 */
- /* National: no national mode */
- dec_lang = y;
- dec_nrc = TX_HUNGARIAN;
- dec_kbd = TX_8859_2;
- break;
- case VTL_SLOVAK :
- case VTL_CZECH :
- case VTL_POLISH :
- case VTL_ROMANIAN:
- /* Multinational: Latin-2 */
- /* National: no national mode */
- dec_lang = y;
- dec_nrc = TX_ASCII;
- dec_kbd = TX_8859_2;
- break;
- case VTL_RUSSIAN :
- /* Multinational: Latin-Cyrillic / KOI-8 */
- /* National: DEC Russian NRC */
- dec_lang = y;
- dec_nrc = TX_KOI7;
- dec_kbd = TX_8859_5;
- break;
- case VTL_LATIN_AM:
- /* Multinational: not listed in table */
- /* National: not listed in table */
- dec_lang = y;
- dec_nrc = TX_ASCII;
- dec_kbd = TX_8859_1;
- break;
-#ifdef COMMENT
- case VTL_SCS :
- /* Multinational: Latin-2 */
- /* National: SCS NRC */
- break;
-#endif /* COMMENT */
- default:
- return(success = 0);
- }
- if (IS97801(tt_type_mode)) {
- SNI_bitmode(cmask == 0377 ? 8 : 7);
- }
- return(success = 1);
-#endif /* NOCSETS */
-
- case XYTVTNRC: { /* SET TERM DEC-NRC-MODE */
- extern int decnrcm_usr, decnrcm; /* from ckoco3.c */
- if ((x = seton(&decnrcm_usr)) < 0)
- return(x);
- decnrcm = decnrcm_usr;
- return(success = 1);
- }
- case XYTSNIPM: { /* SET TERM SNI-PAGEMODE */
- extern int sni_pagemode, sni_pagemode_usr;
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- sni_pagemode_usr = sni_pagemode = y;
- return(success = 1);
- }
- case XYTSNISM: { /* SET TERM SNI-SCROLLMODE */
- extern int sni_scroll_mode, sni_scroll_mode_usr;
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- sni_scroll_mode_usr = sni_scroll_mode = y;
- return(success = 1);
- }
- case XYTSNICC: { /* SET TERM SNI-CH.CODE */
- extern int sni_chcode_usr;
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
- if ((x = cmcfm()) < 0) return(x);
- sni_chcode_usr = y;
- SNI_chcode(y);
- return(success = 1);
- }
- case XYTSNIFV: { /* SET TERM SNI-FIRMWARE-VERSIONS */
- extern CHAR sni_kbd_firmware[], sni_term_firmware[];
- CHAR kbd[7],term[7];
-
- if ((x = cmfld("Keyboard Firmware Version",sni_kbd_firmware,
- &s, xxstring)) < 0)
- return(x);
- if ((int)strlen(s) != 6) {
- printf("?Sorry - the firmware version must be 6 digits long\n");
- return(-9);
- }
- for (i = 0; i < 6; i++) {
- if (!isdigit(s[i])) {
- printf("?Sorry - the firmware version can only contain digits [0-9]\n");
- return(-9);
- }
- }
- ckstrncpy(kbd,s,7);
-
- if ((x = cmfld("Terminal Firmware Version",sni_term_firmware,
- &s, xxstring)) < 0)
- return(x);
- if ((int)strlen(s) != 6) {
- printf("?Sorry - the firmware version must be 6 digits long\n");
- return(-9);
- }
- for (i = 0; i < 6; i++) {
- if (!isdigit(s[i])) {
- printf("?Sorry - the firmware version can only contain digits [0-9]\n");
- return(-9);
- }
- }
- ckstrncpy(term,s,7);
- if ((x = cmcfm()) < 0) return(x);
-
- ckstrncpy(sni_kbd_firmware,kbd,7);
- ckstrncpy(sni_term_firmware,term,7);
- return(success = 1);
- }
-
- case XYTLSP: { /* SET TERM LINE-SPACING */
- if ((x = cmfld("Line Spacing","1",&s, xxstring)) < 0)
- return(x);
- if (isfloat(s,0) < 1) { /* (sets floatval) */
- printf("?Integer or floating-point number required\n");
- return(-9);
- }
- if (floatval < 1.0 || floatval > 3.0) {
- printf("?Value must within the range 1.0 and 3.0 (inclusive)\n");
- return(-9);
- }
- if ((x = cmcfm()) < 0) return(x);
-#ifdef KUI
- tt_linespacing[VCMD] = tt_linespacing[VTERM] = floatval;
- return(success = 1);
-#else /* KUI */
- printf("?Sorry, Line-spacing is only supported in K95G.EXE.\n");
- return(success = 0);
-#endif /* KUI */
- }
-#endif /* OS2 */
-
- default: /* Shouldn't get here. */
- return(-2);
- }
-#endif /* MAC */
-#ifdef COMMENT
- /*
- This was supposed to shut up picky compilers but instead it makes
- most compilers complain about "statement not reached".
- */
- return(-2);
-#endif /* COMMENT */
-#ifdef OS2
- return(-2);
-#endif /* OS2 */
-}
-
-#ifdef OS2
-int
-settitle(void) {
- extern char usertitle[];
- if ((y = cmtxt("title text","",&s,xxstring)) < 0)
- return(y);
-#ifdef IKSD
- if (inserver) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- s = brstrip(s);
- ckstrncpy(usertitle,s,64);
- os2settitle("",1);
- return(1);
-}
-
-static struct keytab dialertab[] = { /* K95 Dialer types */
- "backspace", 0, 0,
- "enter", 1, 0
-};
-static int ndialer = 2;
-
-int
-setdialer(void) {
- int t, x, y;
- int clear = 0, deflt = 0;
- int kc; /* Key code */
- char *s = NULL; /* Key binding */
-#ifndef NOKVERBS
- char *p = NULL; /* Worker */
-#endif /* NOKVERBS */
- con_event defevt;
- extern int os2gks;
- extern int mskkeys;
- extern int initvik;
-
- defevt.type = error;
-
- if (( x = cmkey(dialertab, ndialer,
- "Kermit-95 dialer work-arounds",
- "", xxstring)) < 0 )
- return(x);
- switch (x) {
- case 0: /* Backspace */
- kc = 264;
- break;
- case 1: /* Enter */
- kc = 269;
- break;
- default:
- printf("Illegal value in setdialer()\n");
- return(-9);
- }
- if ((y = cmtxt("Key definition","",&s,xxstring)) < 0)
- return(y);
-
-#ifdef IKSD
- if (inserver) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- s = brstrip(s);
-#ifndef NOKVERBS
- p = s; /* Save this place */
-#endif /* NOKVERBS */
-/*
- If the definition included any \Kverbs, quote the backslash so the \Kverb
- will still be in the definition when the key is pressed. We don't do this
- in zzstring(), because \Kverbs are valid only in this context and nowhere
- else.
-
- We use this code active for all versions that support SET KEY, even if they
- don't support \Kverbs, because otherwise \K would behave differently for
- different versions.
-*/
- for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
- if ((x > 0) &&
- (s[x] == 'K' || s[x] == 'k')
- ) { /* Have K */
-
- if ((x == 1 && s[x-1] == CMDQ) ||
- (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
- line[y++] = CMDQ; /* Make it \\K */
- }
- if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
- line[y-1] = CMDQ; /* Have \{K */
- line[y++] = '{'; /* Make it \\{K */
- }
- }
- line[y] = s[x];
- }
- line[y++] = NUL; /* Terminate */
- s = line + y + 1; /* Point to after it */
- x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
- if ((x < (LINBUFSIZ / 2)) ||
- (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
- printf("?Key definition too long\n");
- return(-9);
- }
- s = line + y + 1; /* Point to result. */
-
-#ifndef NOKVERBS
-/*
- Special case: see if the definition starts with a \Kverb.
- If it does, point to it with p, otherwise set p to NULL.
-*/
- p = s;
- if (*p++ == CMDQ) {
- if (*p == '{') p++;
- p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
- }
-#endif /* NOKVERBS */
-
- /* Clear the definition for SET KEY */
- if (macrotab[kc]) { /* Possibly free old macro from key. */
- free((char *)macrotab[kc]);
- macrotab[kc] = NULL;
- }
- keymap[kc] = (KEY) kc;
-
- /* Now reprogram the default value for all terminal types */
- /* remember to treat Wyse and Televideo terminals special */
- /* because of their use of Kverbs for Backspace and Enter */
- for (t = 0; t <= TT_MAX; t++) {
- if ( ISDG200(t) && kc == 264) {
- extern char * udkfkeys[] ;
- if (kc == 264) { /* \Kdgbs */
- if (udkfkeys[83])
- free(udkfkeys[83]);
- udkfkeys[83] = strdup(s);
- }
- } else if (ISWYSE(t) || ISTVI(t)) {
- extern char * udkfkeys[] ;
- if (kc == 264) { /* \Kwybs or \Ktvibs */
- if (udkfkeys[32])
- free(udkfkeys[32]);
- udkfkeys[32] = strdup(s);
- }
- if (kc == 269) { /* \Kwyenter and \Kwyreturn */
- if (udkfkeys[39]) /* \Ktvienter and \Ktvireturn */
- free(udkfkeys[39]);
- udkfkeys[39] = strdup(s);
- if (udkfkeys[49])
- free(udkfkeys[49]);
- udkfkeys[49] = strdup(s);
- }
- } else {
- switch (strlen(s)) { /* Action depends on length */
- case 0: /* Clear individual key def */
- deletekeymap(t,kc);
- break;
- case 1:
- defevt.type = key; /* Single character */
- defevt.key.scancode = *s;
- break;
- default: /* Character string */
-#ifndef NOKVERBS
- if (p) {
- y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
- /* Exact match req'd */
- debug(F101,"set key kverb lookup",0,y);
- if (y > -1) {
- defevt.type = kverb;
- defevt.kverb.id = y;
- break;
- }
- }
-#endif /* NOKVERBS */
- defevt.type = macro;
- defevt.macro.string = (char *) malloc(strlen(s)+1);
- if (defevt.macro.string)
- strcpy(defevt.macro.string, s); /* safe */
- break;
- }
- insertkeymap( t, kc, defevt ) ;
- initvik = 1; /* Update VIK table */
- }
- }
- return(1);
-}
-#endif /* OS2 */
-
-#ifdef NT
-int
-setwin95( void ) {
- int x, y, z;
-
- if (( y = cmkey(win95tab, nwin95,
- "Windows 95 specific work-arounds",
- "keyboard-translation",
- xxstring)) < 0 )
- return (y);
- switch (y) {
- case XYWPOPUP:
- if ((y = cmkey(onoff,2,"popups are used to prompt the user for data",
- "on",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- win95_popup = y;
- return(1);
-
- case XYW8_3:
- if ((y = cmkey(onoff,2,"8.3 FAT file names","off",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- win95_8_3 = y;
- return(1);
-
- case XYWSELECT:
- if ((y = cmkey(onoff,2,"\"select()\" fails on write","off",
- xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- win95selectbug = y;
- return(1);
-
- case XYWAGR:
- if ((y = cmkey(onoff,2,"Right-Alt is Alt-Gr","off",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- win95altgr = y;
- return(1);
-
- case XYWOIO:
- if ((y = cmkey(onoff,2,"Use Overlapped I/O","on",xxstring)) < 0)
- return(y);
- if (y) {
- if ((x = cmnum("Maximum number of outstanding I/O requests",
- "10",10,&z,xxstring)) < 0)
- return(x);
- if (z < 1 || z > 7) {
- printf(
-"?Maximum outstanding I/O requests must be between 1 and 7.\n");
- return(-9);
- }
- } else
- z = 1;
- if ((x = cmcfm()) < 0) return(x);
- owwait = !y;
- maxow = maxow_usr = z;
- return(1);
-
- case XYWKEY:
-#ifndef COMMENT
- printf("\n?\"Keyboard-Translation\" is no longer required.\n");
- return(-9);
-#else /* COMMENT */
- if (( z = cmkey(tcstab, ntcs,
- "Keyboard Character Set",
- "latin1-iso",
- xxstring)) < 0)
- return (z);
- if ((x = cmcfm()) < 0)
- return(x);
-
- win95kcsi = z;
- win95kl2 = (win95kcsi == TC_2LATIN);
-
- if (win95kcsi == TC_TRANSP) {
- win95kcs = NULL;
- } else {
-#ifdef UNICODE
- win95kcs = xlr[win95kcsi][tx2fc(tcsl)];
-#else /* UNICODE */
- win95kcs = xlr[win95kcsi][tcsl];
-#endif /* UNICODE */
- }
- return(1);
-#endif /* COMMENT */
-
- case XYWLUC:
- if ((y = cmkey(onoff,2,"Unicode-to-Lucida-Console substitutions",
- "on",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- win95lucida = y;
- return(1);
-
- case XYWHSL:
- if ((y = cmkey(onoff,2,"Horizontal Scan Line substitutions",
- "on",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- win95hsl = y;
- return(1);
-
- default:
- printf("Illegal value in setwin95()\n");
- return(-9);
- }
-}
-#endif /* NT */
-
-#ifdef OS2
-int
-setprty (
-#ifdef CK_ANSIC
- void
-#endif /* CK_ANSIC */
-/* setprty */ ) {
- int x, y, z;
-
- if (( y = cmkey(prtytab, nprty,
- "priority level of terminal and communication threads",
- "foreground-server",
- xxstring)) < 0 )
- return (y);
-
- if ((x = cmcfm()) < 0)
- return (x);
-#ifdef IKSD
- if (inserver &&
-#ifdef IKSDCONF
- iksdcf
-#else
- 1
-#endif /* IKSDCONF */
- ) {
- if ((y = cmcfm()) < 0) return(y);
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- priority = y;
- return(TRUE);
-}
-#endif /* OS2 */
-
-int
-setbell() {
- int y, x;
-#ifdef OS2
- int z;
-#endif /* OS2 */
-
- if ((y = cmkey(beltab,nbeltab,
-#ifdef OS2
- "how console and terminal bells should\nbe generated", "audible",
-#else
- "Whether Kermit should ring the terminal bell (beep)", "on",
-#endif /* OS2 */
- xxstring)) < 0)
- return(y);
-
-#ifdef IKSD
- if (inserver) {
- if ((y = cmcfm()) < 0) return(y);
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-
- switch (y) { /* SET BELL */
- case XYB_NONE:
-#ifdef OS2
- case XYB_VIS:
-#endif /* OS2 */
- if ((x = cmcfm()) < 0)
- return(x);
-#ifdef OS2
- tt_bell = y;
-#else
- tt_bell = 0;
-#endif /* OS2 */
- break;
-
- case XYB_AUD:
-#ifdef OS2
- if ((x = cmkey(audibletab, naudibletab,
- "how audible console and terminal\nbells should be generated",
- "beep",xxstring))<0)
- return(x);
- if ((z = cmcfm()) < 0)
- return(z);
- tt_bell = y | x;
-#else
- /* This lets C-Kermit accept but ignore trailing K95 keywords */
- if ((x = cmtxt("Confirm with carriage return","",&s,xxstring)) < 0)
- return(x);
- tt_bell = 1;
-#endif /* OS2 */
- break;
- }
- return(1);
-}
-
-#ifdef OS2MOUSE
-int
-setmou(
-#ifdef CK_ANSIC
- void
-#endif /* CK_ANSIC */
- /* setmou */ ) {
- extern int initvik;
- int button = 0, event = 0;
- char * p;
-
- if ((y = cmkey(mousetab,nmtab,"","",xxstring)) < 0)
- return(y);
-
-#ifdef IKSD
- if (inserver) {
- if ((y = cmcfm()) < 0) return(y);
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
-
- if (y == XYM_ON) { /* MOUSE ACTIVATION */
- int old_mou = tt_mouse;
- if ((x = seton(&tt_mouse)) < 0)
- return(x);
- if (tt_mouse != old_mou)
- if (tt_mouse)
- os2_mouseon();
- else
- os2_mouseoff();
- return(1);
- }
-
- if (y == XYM_DEBUG) { /* MOUSE DEBUG */
- extern int MouseDebug;
- if ((x = seton(&MouseDebug)) < 0)
- return(x);
- return(1);
- }
-
- if (y == XYM_CLEAR) { /* Reset Mouse Defaults */
- if ((x = cmcfm()) < 0) return(x);
- mousemapinit(-1,-1);
- initvik = 1; /* Update VIK Table */
- return 1;
- }
- if (y != XYM_BUTTON) { /* Shouldn't happen. */
- printf("Internal parsing error\n");
- return(-9);
- }
-
- /* MOUSE EVENT ... */
-
- if ((button = cmkey(mousebuttontab,nmbtab,
- "Button number","1",
- xxstring)) < 0)
- return(button);
-
- if ((y = cmkey(mousemodtab,nmmtab,
- "Keyboard modifier","none",
- xxstring)) < 0)
- return(y);
-
- event |= y; /* OR in the bits */
-
- if ((y = cmkey(mclicktab,nmctab,"","click",xxstring)) < 0)
- return(y);
-
- /* Two bits are assigned, if neither are set then it is button one */
-
- event |= y; /* OR in the bit */
-
- wideresult = -1;
-
- if ((y = cmtxt("definition,\n\
-or Ctrl-C to cancel this command,\n\
-or Enter to restore default definition",
- "",&s,NULL)) < 0) {
- return(y);
- }
- s = brstrip(s);
- p = s; /* Save this place */
-/*
- If the definition included any \Kverbs, quote the backslash so the \Kverb
- will still be in the definition when the key is pressed. We don't do this
- in zzstring(), because \Kverbs are valid only in this context and nowhere
- else. This code copied from SET KEY, q.v. for addt'l commentary.
-*/
- for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
- if ((x > 0) &&
- (s[x] == 'K' || s[x] == 'k')
- ) { /* Have K */
-
- if ((x == 1 && s[x-1] == CMDQ) ||
- (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
- line[y++] = CMDQ; /* Make it \\K */
- }
- if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
- line[y-1] = CMDQ; /* Have \{K */
- line[y++] = '{'; /* Make it \\{K */
- }
- }
- line[y] = s[x];
- }
- line[y++] = NUL; /* Terminate */
- s = line + y + 1; /* Point to after it */
- x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
- if ((x < (LINBUFSIZ / 2)) ||
- (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
- printf("?Key definition too long\n");
- return(-9);
- }
- s = line + y + 1; /* Point to result. */
-
-#ifndef NOKVERBS
-/*
- Special case: see if the definition starts with a \Kverb.
- If it does, point to it with p, otherwise set p to NULL.
-*/
- p = s;
- if (*p++ == CMDQ) {
- if (*p == '{') p++;
- p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
- }
-#else
- p = NULL;
-#endif /* NOKVERBS */
-
- /* free the old definition if necessary */
- if (mousemap[button][event].type == macro) {
- free( mousemap[button][event].macro.string);
- mousemap[button][event].macro.string = NULL;
- }
- switch (strlen(s)) { /* Action depends on length */
- case 0: /* Reset to default binding */
- mousemapinit( button, event );
- break;
- case 1: /* Single character */
- mousemap[button][event].type = key;
- mousemap[button][event].key.scancode = *s;
- break;
- default: /* Character string */
-#ifndef NOKVERBS
- if (p) {
- y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
- debug(F101,"set mouse kverb lookup",0,y); /* need exact match */
- if (y > -1) {
- /* Assign the kverb to the event */
- mousemap[button][event].type = kverb;
- mousemap[button][event].kverb.id = F_KVERB | y;
- break;
- }
- }
-#endif /* NOKVERBS */
-
- /* Otherwise, it's a macro, so assign the macro to the event */
- mousemap[button][event].type = macro;
- mousemap[button][event].macro.string = (MACRO) malloc(strlen(s)+1);
- if (mousemap[button][event].macro.string)
- strcpy((char *) mousemap[button][event].macro.string, s); /* safe */
- break;
- }
- initvik = 1; /* Update VIK Table */
- if ( (button == XYM_B3) && (mousebuttoncount() < 3) && !quiet )
- {
- printf("?Warning: this machine does not have a three button mouse.\n");
- return(0);
- }
- return(1);
-}
-#endif /* OS2MOUSE */
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
-int /* SET SEND/RECEIVE */
-setsr(xx, rmsflg) int xx; int rmsflg; {
- if (xx == XYRECV)
- ckstrncpy(line,"Parameter for inbound packets",LINBUFSIZ);
- else
- ckstrncpy(line,"Parameter for outbound packets",LINBUFSIZ);
-
- if (rmsflg) {
- if ((y = cmkey(rsrtab,nrsrtab,line,"",xxstring)) < 0) {
- if (y == -3) {
- printf("?Remote receive parameter required\n");
- return(-9);
- } else return(y);
- }
- } else {
- if ((y = cmkey(srtab,nsrtab,line,"",xxstring)) < 0) return(y);
- }
- switch (y) {
- case XYQCTL: /* CONTROL-PREFIX */
- if ((x = cmnum("ASCII value of control prefix","",10,&y,xxstring)) < 0)
- return(x);
- if ((x = cmcfm()) < 0) return(x);
- if ((y > 32 && y < 63) || (y > 95 && y < 127)) {
- if (xx == XYRECV)
- ctlq = (CHAR) y; /* RECEIVE prefix, use with caution! */
- else
- myctlq = (CHAR) y; /* SEND prefix, OK to change */
- return(success = 1);
- } else {
- printf("?Illegal value for prefix character\n");
- return(-9);
- }
-
- case XYEOL:
- if ((y = setcc("13",&z)) < 0)
- return(y);
- if (z > 31) {
- printf("Sorry, the legal values are 0-31\n");
- return(-9);
- }
- if (xx == XYRECV)
- eol = (CHAR) z;
- else
- seol = (CHAR) z;
- return(success = y);
-
- case XYLEN:
- y = cmnum("Maximum number of characters in a packet","90",10,&x,
- xxstring);
- if (xx == XYRECV) { /* Receive... */
- if ((y = setnum(&z,x,y,maxrps)) < 0)
- return(y);
- if (protocol != PROTO_K) {
- printf("?Sorry, this command does not apply to %s protocol.\n",
- ptab[protocol].p_name
- );
- printf("Use SET SEND PACKET-LENGTH for XYZMODEM\n");
- return(-9);
- }
- if (z < 10) {
- printf("Sorry, 10 is the minimum\n");
- return(-9);
- }
- if (rmsflg) {
- sstate = setgen('S', "401", ckitoa(z), "");
- return((int) sstate);
- } else {
- if (protocol == PROTO_K) {
- if (z > MAXRP) z = MAXRP;
- y = adjpkl(z,wslotr,bigrbsiz);
- if (y != z) {
- urpsiz = y;
- if (!xcmdsrc)
- if (msgflg) printf(
-" Adjusting receive packet-length to %d for %d window slots\n",
- y, wslotr);
- }
- urpsiz = y;
- ptab[protocol].rpktlen = urpsiz;
- rpsiz = (y > 94) ? 94 : y;
- } else {
-#ifdef CK_XYZ
- if ((protocol == PROTO_X || protocol == PROTO_XC) &&
- z != 128 && z != 1024) {
- printf("Sorry, bad packet length for XMODEM.\n");
- printf("Please use 128 or 1024.\n");
- return(-9);
- }
-#endif /* CK_XYZ */
- urpsiz = rpsiz = z;
- }
- }
- } else { /* Send... */
- if ((y = setnum(&z,x,y,maxsps)) < 0)
- return(y);
- if (z < 10) {
- printf("Sorry, 10 is the minimum\n");
- return(-9);
- }
- if (protocol == PROTO_K) {
- if (z > MAXSP) z = MAXSP;
- spsiz = z; /* Set it */
- y = adjpkl(spsiz,wslotr,bigsbsiz);
- if (y != spsiz && !xcmdsrc)
- if (msgflg)
- printf("Adjusting packet size to %d for %d window slots\n",
- y,wslotr);
- } else
- y = z;
-#ifdef CK_XYZ
- if ((protocol == PROTO_X || protocol == PROTO_XC) &&
- z != 128 && z != 1024) {
- printf("Sorry, bad packet length for XMODEM.\n");
- printf("Please use 128 or 1024.\n");
- return(-9);
- }
-#endif /* CK_XYZ */
- spsiz = spmax = spsizr = y; /* Set it and flag that it was set */
- spsizf = 1; /* to allow overriding Send-Init. */
- ptab[protocol].spktflg = spsizf;
- ptab[protocol].spktlen = spsiz;
- }
- if (pflag && protocol == PROTO_K && !xcmdsrc) {
- if (z > 94 && !reliable && msgflg) {
- /* printf("Extended-length packets requested.\n"); */
- if (bctr < 2 && z > 200) printf("\
-Remember to SET BLOCK 2 or 3 for long packets.\n");
- }
- if (speed <= 0L) speed = ttgspd();
-#ifdef COMMENT
-/*
- Kermit does this now itself.
-*/
- if (speed <= 0L && z > 200 && msgflg) {
- printf("\
-Make sure your timeout interval is long enough for %d-byte packets.\n",z);
- }
-#endif /* COMMENT */
- }
- return(success = y);
-
- case XYMARK:
-#ifdef DOOMSDAY
-/*
- Printable start-of-packet works for UNIX and VMS only!
-*/
- x_ifnum = 1;
- y = cmnum("Code for packet-start character","1",10,&x,xxstring);
- x_ifnum = 0;
- if ((y = setnum(&z,x,y,126)) < 0) return(y);
-#else
- if ((y = setcc("1",&z)) < 0)
- return(y);
-#endif /* DOOMSDAY */
- if (xx == XYRECV)
- stchr = (CHAR) z;
- else {
- mystch = (CHAR) z;
-#ifdef IKS_OPTION
- /* If IKS negotiation in use */
- if (TELOPT_U(TELOPT_KERMIT) || TELOPT_ME(TELOPT_KERMIT))
- tn_siks(KERMIT_SOP); /* Report change to other side */
-#endif /* IKS_OPTION */
- }
- return(success = y);
-
- case XYNPAD: /* PADDING */
- y = cmnum("How many padding characters for inbound packets","0",10,&x,
- xxstring);
- if ((y = setnum(&z,x,y,94)) < 0) return(y);
- if (xx == XYRECV)
- mypadn = (CHAR) z;
- else
- npad = (CHAR) z;
- return(success = y);
-
- case XYPADC: /* PAD-CHARACTER */
- if ((y = setcc("0",&z)) < 0) return(y);
- if (xx == XYRECV) mypadc = z; else padch = z;
- return(success = y);
-
- case XYTIMO: /* TIMEOUT */
- if (xx == XYRECV) {
- y = cmnum("Packet timeout interval",ckitoa(URTIME),10,&x,xxstring);
- if ((y = setnum(&z,x,y,94)) < 0) return(y);
-
- if (rmsflg) { /* REMOTE SET RECEIVE TIMEOUT */
- sstate = setgen('S', "402", ckitoa(z), "");
- return((int) sstate);
- } else { /* SET RECEIVE TIMEOUT */
- pkttim = z; /* Value to put in my negotiation */
- } /* packet for other Kermit to use */
-
- } else { /* SET SEND TIMEOUT */
-#ifdef CK_TIMERS
- extern int rttflg, mintime, maxtime;
- int tmin = 0, tmax = 0;
-#endif /* CK_TIMERS */
- y = cmnum("Packet timeout interval",ckitoa(DMYTIM),10,&x,xxstring);
- if (y == -3) { /* They cancelled a previous */
- x = DMYTIM; /* SET SEND command, so restore */
- timef = 0; /* and turn off the override flag */
- y = cmcfm();
- }
-#ifdef CK_TIMERS
- if (y < 0) return(y);
- if (x < 0) {
- printf("?Out of range - %d\n",x);
- return(-9);
- }
- if ((z = cmkey(timotab,2,"","dynamic",xxstring)) < 0) return(z);
- if (z) {
- if ((y = cmnum("Minimum timeout to allow",
- "1",10,&tmin,xxstring)) < 0)
- return(y);
- if (tmin < 1) {
- printf("?Out of range - %d\n",tmin);
- return(-9);
- }
- if ((y = cmnum("Maximum timeout to allow",
- "0",10,&tmax,xxstring)) < 0)
- return(y);
- /* 0 means let Kermit choose, < 0 means no maximum */
- }
- if ((y = cmcfm()) < 0)
- return(y);
- rttflg = z; /* Round-trip timer flag */
- z = x;
-#else
- if ((y = setnum(&z,x,y,94)) < 0)
- return(y);
-#endif /* CK_TIMERS */
- timef = 1; /* Turn on the override flag */
- timint = rtimo = z; /* Override value for me to use */
-#ifdef CK_TIMERS
- if (rttflg) { /* Lower and upper bounds */
- mintime = tmin;
- maxtime = tmax;
- }
-#endif /* CK_TIMERS */
- }
- return(success = 1);
-
- case XYFPATH: /* PATHNAMES */
- if (xx == XYRECV) {
- y = cmkey(rpathtab,nrpathtab,"","auto",xxstring);
- } else {
- y = cmkey(pathtab,npathtab,"","off",xxstring);
- }
- if (y < 0) return(y);
-
- if ((x = cmcfm()) < 0) return(x);
- if (xx == XYRECV) { /* SET RECEIVE PATHNAMES */
- fnrpath = y;
- ptab[protocol].fnrp = fnrpath;
- } else { /* SET SEND PATHNAMES */
- fnspath = y;
- ptab[protocol].fnsp = fnspath;
- }
- return(success = 1); /* Note: 0 = ON, 1 = OFF */
- /* In other words, ON = leave pathnames ON, OFF = take them off. */
-
- case XYPAUS: /* SET SEND/RECEIVE PAUSE */
- y = cmnum("Milliseconds to pause between packets","0",10,&x,xxstring);
- if ((y = setnum(&z,x,y,15000)) < 0)
- return(y);
- pktpaus = z;
- return(success = 1);
-
-#ifdef CKXXCHAR /* SET SEND/RECEIVE IGNORE/DOUBLE */
- case XYIGN:
- case XYDBL: {
- int i, zz;
- short *p;
- extern short dblt[];
- extern int dblflag, ignflag;
-
- /* Make space for a temporary copy of the ignore/double table */
-
- zz = y;
-#ifdef COMMENT
- if (zz == XYIGN && xx == XYSEND) {
- blah blah who cares
- }
- if (zz == XYDBL && xx == XYRECV) {
- blah blah
- }
-#endif /* COMMENT */
- p = (short *)malloc(256 * sizeof(short));
- if (!p) {
- printf("?Internal error - malloc failure\n");
- return(-9);
- }
- for (i = 0; i < 256; i++) p[i] = dblt[i]; /* Copy current table */
-
- while (1) { /* Collect a list of numbers */
-#ifndef NOSPL
- x_ifnum = 1; /* Turn off complaints from eval() */
-#endif /* NOSPL */
- if ((x = cmnum(zz == XYDBL ?
- "Character to double" :
- "Character to ignore",
- "",10,&y,xxstring
- )) < 0) {
-#ifndef NOSPL
- x_ifnum = 0;
-#endif /* NOSPL */
- if (x == -3) /* Done */
- break;
- if (x == -2) {
- if (p) { free(p); p = NULL; }
- debug(F110,"SET S/R DOUBLE/IGNORE atmbuf",atmbuf,0);
- if (!ckstrcmp(atmbuf,"none",4,0) ||
- !ckstrcmp(atmbuf,"non",3,0) ||
- !ckstrcmp(atmbuf,"no",2,0) ||
- !ckstrcmp(atmbuf,"n",1,0)) {
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
- for (y = 0; y < 256; y++)
- dblt[y] &= (zz == XYDBL) ? 1 : 2;
- if (zz == XYDBL) dblflag = 0;
- if (zz == XYIGN) ignflag = 0;
- return(success = 1);
- } else {
- printf(
- "?Please specify a number or the word NONE\n");
- return(-9);
- }
- } else {
- free(p);
- p = NULL;
- return(x);
- }
- }
-#ifndef NOSPL
- x_ifnum = 0;
-#endif /* NOSPL */
- if (y < 0 || y > 255) {
- printf("?Please enter a character code in range 0-255\n");
- free(p);
- p = NULL;
- return(-9);
- }
- p[y] |= (zz == XYDBL) ? 2 : 1;
- if (zz == XYDBL) dblflag = 1;
- if (zz == XYIGN) ignflag = 1;
- } /* End of while loop */
-
- if ((x = cmcfm()) < 0) return(x);
-/*
- Get here only if they have made no mistakes. Copy temporary table back to
- permanent one, then free temporary table and return successfully.
-*/
- if (p) {
- for (i = 0; i < 256; i++) dblt[i] = p[i];
- free(p);
- p = NULL;
- }
- return(success = 1);
- }
-#endif /* CKXXCHAR */
-
-#ifdef PIPESEND
- case XYFLTR: { /* SET { SEND, RECEIVE } FILTER */
- if ((y = cmtxt((xx == XYSEND) ?
- "Filter program for sending files -\n\
- use \\v(filename) to substitute filename" :
- "Filter program for receiving files -\n\
- use \\v(filename) to substitute filename",
- "",&s,NULL)) < 0)
- return(y);
- if (!*s) { /* Removing a filter... */
- if (xx == XYSEND && sndfilter) {
- makestr(&g_sfilter,NULL);
- makestr(&sndfilter,NULL);
- } else if (rcvfilter) {
- makestr(&g_rfilter,NULL);
- makestr(&rcvfilter,NULL);
- }
- return(success = 1);
- } /* Adding a filter... */
- s = brstrip(s); /* Strip any braces */
- y = strlen(s);
- if (xx == XYSEND) { /* For SEND filter... */
- for (x = 0; x < y; x++) { /* make sure they included "\v(...)" */
- if (s[x] != '\\') continue;
- if (s[x+1] == 'v') break;
- }
- if (x == y) {
- printf(
- "?Filter must contain a replacement variable for filename.\n"
- );
- return(-9);
- }
- }
- if (xx == XYSEND) {
- makestr(&sndfilter,s);
- makestr(&g_sfilter,s);
- } else {
- makestr(&rcvfilter,s);
- makestr(&g_rfilter,s);
- }
- return(success = 1);
- }
-#endif /* PIPESEND */
-
- case XYINIL:
- y = cmnum("Max length for protocol init string","-1",10,&x,xxstring);
- if ((y = setnum(&z,x,y,-1)) < 0)
- return(y);
- if (xx == XYSEND)
- sprmlen = z;
- else
- rprmlen = z;
- return(success = 1);
-
- case 993: {
- extern int sendipkts;
- if (xx == XYSEND) {
- if ((x = seton(&sendipkts)) < 0)
- return(x);
- }
- return(1);
- }
-#ifdef CK_PERMS
- case 994:
- switch(xx) {
- case XYSEND:
- if ((x = seton(&atlpro)) < 0) return(x);
- atgpro = atlpro;
- return(1);
- case XYRECV:
- if ((x = seton(&atlpri)) < 0) return(x);
- atgpri = atlpri;
- return(1);
- default:
- return(-2);
- }
-#endif /* CK_PERMS */
-
-#ifndef NOCSETS
- case XYCSET: { /* CHARACTER-SET-SELECTION */
- extern struct keytab xfrmtab[];
- extern int r_cset, s_cset;
- if ((y = cmkey(xfrmtab,2,"","automatic",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- if (xx == XYSEND)
- s_cset = y;
- else
- r_cset = y;
- return(success = 1);
- }
-#endif /* NOCSETS */
-
- case XYBUP:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
- return(y);
- if ((x = cmcfm()) < 0) return(x);
- if (xx == XYSEND) {
- extern int skipbup;
- skipbup = (y == 0) ? 1 : 0;
- return(success = 1);
- } else {
- printf(
-"?Please use SET FILE COLLISION to choose the desired action\n");
- return(-9);
- }
-
- case XYMOVE:
-#ifdef COMMENT
- y = cmdir("Directory to move file(s) to after successful transfer",
- "",&s,xxstring);
-#else
- y = cmtxt("Directory to move file(s) to after successful transfer",
- "",&s,xxstring);
-#endif /* COMMENT */
-
- if (y < 0 && y != -3)
- return(y);
- ckstrncpy(line,s,LINBUFSIZ);
- s = brstrip(line);
-
-#ifdef COMMENT
- /* Only needed for cmdir() */
- if ((x = cmcfm()) < 0)
- return(x);
-#endif /* COMMENT */
-
- /* Check directory existence if absolute */
- /* THIS MEANS IT CAN'T INCLUDE ANY DEFERRED VARIABLES! */
- if (s) if (*s) {
- if (isabsolute(s) && !isdir(s)) {
- printf("?Directory does not exist - %s\n",s);
- return(-9);
- }
- }
- if (xx == XYSEND) {
- if (*s) {
-#ifdef COMMENT
- /* Allow it to be relative */
- zfnqfp(s,LINBUFSIZ,line);
-#endif /* COMMENT */
- makestr(&snd_move,line);
- makestr(&g_snd_move,line);
- } else {
- makestr(&snd_move,NULL);
- makestr(&g_snd_move,NULL);
- }
- } else {
- if (*s) {
-#ifdef COMMENT
- /* Allow it to be relative */
- zfnqfp(s,LINBUFSIZ,line);
-#endif /* COMMENT */
- makestr(&rcv_move,line);
- makestr(&g_rcv_move,line);
- } else {
- makestr(&rcv_move,NULL);
- makestr(&g_rcv_move,NULL);
- }
- }
- return(success = 1);
-
- case XYRENAME:
- y = cmtxt("Template to rename file(s) to after successful transfer",
- "",&s,NULL); /* NOTE: no xxstring */
- if (y < 0 && y != -3) /* Evaluation is deferred */
- return(y);
- ckstrncpy(line,s,LINBUFSIZ);
- s = brstrip(line);
- if ((x = cmcfm()) < 0)
- return(x);
- if (xx == XYSEND) {
- if (*s) {
- makestr(&snd_rename,s);
- makestr(&g_snd_rename,s);
- } else {
- makestr(&snd_rename,NULL);
- makestr(&g_snd_rename,NULL);
- }
- } else {
- if (*s) {
- makestr(&rcv_rename,s);
- makestr(&g_rcv_rename,s);
- } else {
- makestr(&rcv_rename,NULL);
- makestr(&g_rcv_rename,NULL);
- }
- }
- return(success = 1);
-
-#ifdef VMS
- case 887: /* VERSION-NUMBERS */
- if (xx == XYSEND) {
- extern int vmssversions;
- return(seton(&vmssversions));
- } else {
- extern int vmsrversions;
- return(seton(&vmsrversions));
- }
-#endif /* VMS */
-
- default:
- return(-2);
- } /* End of SET SEND/RECEIVE... */
-}
-#endif /* NOXFER */
-
-#ifndef NOXMIT
-int
-setxmit() {
- if ((y = cmkey(xmitab,nxmit,"","",xxstring)) < 0) return(y);
- switch (y) {
- case XMITE: /* EOF */
- y = cmtxt("Characters to send at end of file,\n\
- Use backslash codes for control characters","",&s,xxstring);
- if (y < 0) return(y);
- if ((int)strlen(s) > XMBUFL) {
- printf("?Too many characters, %d maximum\n",XMBUFL);
- return(-2);
- }
- ckstrncpy(xmitbuf,s,XMBUFL);
- return(success = 1);
-
- case XMITF: /* Fill */
- y = cmnum("Numeric code for blank-line fill character","0",10,&x,
- xxstring);
- if ((y = setnum(&z,x,y,127)) < 0) return(y);
- xmitf = z;
- return(success = 1);
- case XMITL: /* Linefeed */
- return(seton(&xmitl));
- case XMITS: /* Locking-Shift */
- return(seton(&xmits));
- case XMITP: /* Prompt */
- y = cmnum("Numeric code for host's prompt character, 0 for none",
- "10",10,&x,xxstring);
- if ((y = setnum(&z,x,y,127)) < 0) return(y);
- xmitp = z;
- return(success = 1);
- case XMITX: /* Echo */
- return(seton(&xmitx));
- case XMITW: /* Pause */
- y = cmnum("Number of milliseconds to pause between binary characters\n\
-or text lines during transmission","0",10,&x,xxstring);
- if ((y = setnum(&z,x,y,1000)) < 0) return(y);
- xmitw = z;
- return(success = 1);
- case XMITT: /* Timeout */
- y = cmnum("Seconds to wait for each character to echo",
- "1",10,&x,xxstring);
- if ((y = setnum(&z,x,y,1000)) < 0) return(y);
- xmitt = z;
- return(success = 1);
- default:
- return(-2);
- }
-}
-#endif /* NOXMIT */
-
-#ifndef NOXFER
-/* D O R M T -- Do a remote command */
-
-VOID
-rmsg() {
- if (pflag && !quiet && fdispla != XYFD_N)
- printf(
-#ifdef CK_NEED_SIG
- " Type your escape character, %s, followed by X or E to cancel.\n",
- dbchr(escape)
-#else
- " Press the X or E key to cancel.\n"
-#endif /* CK_NEED_SIG */
- );
-}
-
-static int xzcmd = 0; /* Global copy of REMOTE cmd index */
-
-/* R E M C F M -- Confirm a REMOTE command */
-/*
- Like cmcfm(), but allows for a redirection indicator on the end,
- like "> filename" or "| command". Returns what cmcfm() would have
- returned: -1 if reparse needed, etc etc blah blah. On success,
- returns 1 with:
-
- char * remdest containing the name of the file or command.
- int remfile set to 1 if there is to be any redirection.
- int remappd set to 1 if output file is to be appended to.
- int rempipe set to 1 if remdest is a command, 0 if it is a file.
-*/
-static int
-remcfm() {
- int x;
- char *s;
- char c;
-
- remfile = 0;
- rempipe = 0;
- remappd = 0;
-
- if ((x = cmtxt(
- "> filename, | command,\n\
-or type carriage return to confirm the command",
- "",&s,xxstring)) < 0)
- return(x);
- if (remdest) {
- free(remdest);
- remdest = NULL;
- }
- debug(F101,"remcfm local","",local);
- debug(F110,"remcfm s",s,0);
- debug(F101,"remcfm cmd","",xzcmd);
-/*
- This check was added in C-Kermit 6.0 or 7.0 but it turns out to be
- unhelpful in the situation where the remote is running a script that sends
- REMOTE commands to the local workstation. What happens is, the local
- server executes the command and sends the result back as screen text, which
- is indicated by using an X packet instead of an F packet as the file
- header. There are two parts to this: executing the command under control
- of the remote Kermit, which is desirable (and in fact some big applications
- depend on it, and therefore never installed any new C-Kermit versions after
- 5A), and displaying the result. Commenting out the check allows the
- command to be executed, but the result is still sent back to the remote in
- a file transfer, where it vanishes into the ether. Actually it's on the
- communication connection, mixed in with the packets. Pretty amazing that
- the file transfer still works, right?
-*/
-#ifdef COMMENT
- if (!*s) { /* No redirection indicator */
- if (!local &&
- (xzcmd == XZDIR || xzcmd == XZTYP ||
- xzcmd == XZXIT || xzcmd == XZSPA ||
- xzcmd == XZHLP || xzcmd == XZPWD ||
- xzcmd == XZLGI || xzcmd == XZLGO ||
- xzcmd == XZWHO || xzcmd == XZHOS)) {
- printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
- return(-9);
- } else
- return(1);
- }
-#endif /* COMMENT */
- c = *s; /* We have something */
- if (c != '>' && c != '|') { /* Is it > or | ? */
- printf("?Not confirmed\n"); /* No */
- return(-9);
- }
- s++; /* See what follows */
- if (c == '>' && *s == '>') { /* Allow for ">>" too */
- s++;
- remappd = 1; /* Append to output file */
- }
- while (*s == SP || *s == HT) s++; /* Strip intervening whitespace */
- if (!*s) {
- printf("?%s missing\n", c == '>' ? "Filename" : "Command");
- return(-9);
- }
- if (c == '>' && zchko(s) < 0) { /* Check accessibility */
- printf("?Access denied - %s\n", s);
- return(-9);
- }
- remfile = 1; /* Set global results */
- rempipe = (c == '|');
- if (rempipe
-#ifndef NOPUSH
- && nopush
-#endif /* NOPUSH */
- ) {
- printf("?Sorry, access to external commands is disabled.\n");
- return(-9);
- }
- makestr(&remdest,s);
-#ifndef NODEBUG
- if (deblog) {
- debug(F101,"remcfm remfile","",remfile);
- debug(F101,"remcfm remappd","",remappd);
- debug(F101,"remcfm rempipe","",rempipe);
- debug(F110,"remcfm remdest",remdest, 0);
- }
-#endif /* NODEBUG */
- return(1);
-}
-
-/* R E M T X T -- Like remcfm()... */
-/*
- ... but for REMOTE commands that end with cmtxt().
- Here we must decipher braces to discover whether the trailing
- redirection indicator is intended for local use, or to be sent out
- to the server, as in:
-
- remote host blah blah > file This end
- remote host { blah blah } > file This end
- remote host { blah blah > file } That end
- remote host { blah blah > file } > file Both ends
-
- Pipes too:
-
- remote host blah blah | cmd This end
- remote host { blah blah } | cmd This end
- remote host { blah blah | cmd } That end
- remote host { blah blah | cmd } | cmd Both ends
-
- Or both:
-
- remote host blah blah | cmd > file This end, etc etc...
-
- Note: this really only makes sense for REMOTE HOST, but why be picky?
- Call after calling cmtxt(), with pointer to string that cmtxt() parsed,
- as in "remtxt(&s);".
-
- Returns:
- 1 on success with braces & redirection things removed & pointer updated,
- -9 on failure (bad indirection), after printing error message.
-*/
-int
-remtxt(p) char ** p; {
- int i, x, bpos, ppos;
- char c, *s, *q;
-
- remfile = 0; /* Initialize global results */
- rempipe = 0;
- remappd = 0;
- if (remdest) {
- free(remdest);
- remdest = NULL;
- }
- s = *p;
- if (!s) /* No redirection indicator */
- s = "";
-#ifdef COMMENT
- if (!*s) { /* Ditto */
- if (!local &&
- (xzcmd == XZDIR || xzcmd == XZTYP ||
- xzcmd == XZXIT || xzcmd == XZSPA ||
- xzcmd == XZHLP || xzcmd == XZPWD ||
- xzcmd == XZLGI || xzcmd == XZLGO ||
- xzcmd == XZWHO || xzcmd == XZHOS)) {
- printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
- if (hints) {
- printf("Hint: Try again with an output redirector.\n");
- }
- return(-9);
- } else
- return(1);
- }
-#endif /* COMMENT */
- bpos = -1; /* Position of > (bracket) */
- ppos = -1; /* Position of | (pipe) */
- x = strlen(s); /* Length of cmtxt() string */
-
- for (i = x-1; i >= 0; i--) { /* Search right to left. */
- c = s[i];
- if (c == '}') /* Break on first right brace */
- break; /* Don't look at contents of braces */
- else if (c == '>') /* Record position of > */
- bpos = i;
- else if (c == '|') /* and of | */
- ppos = i;
- }
- if (bpos < 0 && ppos < 0) { /* No redirectors. */
-#ifdef COMMENT
- if (!local &&
- (xzcmd == XZDIR || xzcmd == XZTYP ||
- xzcmd == XZXIT || xzcmd == XZSPA ||
- xzcmd == XZHLP || xzcmd == XZPWD ||
- xzcmd == XZLGI || xzcmd == XZLGO ||
- xzcmd == XZWHO || xzcmd == XZHOS)) {
- printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
- if (hints) {
- printf("Hint: Try again with an output redirector.\n");
- }
- return(-9);
- }
-#endif /* COMMENT */
- s = brstrip(s); /* Remove outer braces if any. */
- *p = s; /* Point to result */
- return(1); /* and return. */
- }
- remfile = 1; /* It's | or > */
- i = -1; /* Get leftmost symbol */
- if (bpos > -1) /* Bracket */
- i = bpos;
- if (ppos > -1 && (ppos < bpos || bpos < 0)) { /* or pipe */
- i = ppos;
- rempipe = 1;
- }
- if (rempipe
-#ifndef NOPUSH
- && nopush
-#endif /* NOPUSH */
- ) {
- printf("?Sorry, access to external commands is disabled.\n");
- return(-9);
- }
- c = s[i]; /* Copy of symbol */
-
- if (c == '>' && s[i+1] == '>') /* ">>" for append? */
- remappd = 1; /* It's not just a flag it's a number */
-
- q = s + i + 1 + remappd; /* Point past symbol in string */
- while (*q == SP || *q == HT) q++; /* and any intervening whitespace */
- if (!*q) {
- printf("?%s missing\n", c == '>' ? "Filename" : "Command");
- return(-9);
- }
- if (c == '>' && zchko(q) < 0) { /* (Doesn't work for | cmd > file) */
- printf("?Access denied - %s\n", q);
- return(-9);
- }
- makestr(&remdest,q); /* Create the destination string */
- q = s + i - 1; /* Point before symbol */
- while (q > s && (*q == SP || *q == HT)) /* Strip trailing whitespace */
- q--;
- *(q+1) = NUL; /* Terminate the string. */
- s = brstrip(s); /* Remove any braces */
- *p = s; /* Set return value */
-
-#ifndef NODEBUG
- if (deblog) {
- debug(F101,"remtxt remfile","",remfile);
- debug(F101,"remtxt remappd","",remappd);
- debug(F101,"remtxt rempipe","",rempipe);
- debug(F110,"remtxt remdest",remdest, 0);
- debug(F110,"remtxt command",s,0);
- }
-#endif /* NODEBUG */
-
- return(1);
-}
-
-int
-plogin(xx) int xx; {
- char *p1 = NULL, *p2 = NULL, *p3 = NULL;
- int psaved = 0, rc = 0;
-#ifdef CK_RECALL
- extern int on_recall; /* around Password prompting */
-#endif /* CK_RECALL */
- debug(F101,"plogin local","",local);
-
- if (!local || (network && ttchk() < 0)) {
- printf("?No connection\n");
- return(-9);
- }
- if ((x = cmfld("User ID","",&s,xxstring)) < 0) { /* Get User ID */
- if (x != -3) return(x);
- }
- y = strlen(s);
- if (y > 0) {
- if ((p1 = malloc(y + 1)) == NULL) {
- printf("?Internal error: malloc\n");
- rc = -9;
- goto XZXLGI;
- } else
- strcpy(p1,s); /* safe */
- if ((rc = cmfld("Password","",&s,xxstring)) < 0)
- if (rc != -3) goto XZXLGI;
- y = strlen(s);
- if (y > 0) {
- if ((p2 = malloc(y + 1)) == NULL) {
- printf("?Internal error: malloc\n");
- rc = -9;
- goto XZXLGI;
- } else
- strcpy(p2,s); /* safe */
- if ((rc = cmfld("Account","",&s,xxstring)) < 0)
- if (rc != -3) goto XZXLGI;
- y = strlen(s);
- if (y > 0) {
- if ((p3 = malloc(y + 1)) == NULL) {
- printf("?Internal error: malloc\n");
- rc = -9;
- goto XZXLGI;
- } else
- strcpy(p3,s); /* safe */
- }
- }
- }
- if ((rc = remtxt(&s)) < 0) /* Confirm & handle redirectors */
- goto XZXLGI;
-
- if (!p1) { /* No Userid specified... */
- debok = 0; /* Don't log this */
- /* Prompt for username, password, and account */
-#ifdef CK_RECALL
- on_recall = 0;
-#endif /* CK_RECALL */
- cmsavp(psave,PROMPTL); /* Save old prompt */
- psaved = 1;
- debug(F110,"REMOTE LOGIN saved",psave,0);
-
- cmsetp("Username: "); /* Make new prompt */
- concb((char)escape); /* Put console in cbreak mode */
- cmini(1);
- prompt(xxstring);
- rc = -9;
- for (x = -1; x < 0; ) { /* Prompt till they answer */
- cmres(); /* Reset the parser */
- x = cmtxt("","",&s,NULL); /* Get a literal line of text */
- }
- y = strlen(s);
- if (y < 1) {
- printf("?Canceled\n");
- goto XZXLGI;
- }
- if ((p1 = malloc(y + 1)) == NULL) {
- printf("?Internal error: malloc\n");
- goto XZXLGI;
- } else
- strcpy(p1,s); /* safe */
-
- cmsetp("Password: "); /* Make new prompt */
- concb((char)escape); /* Put console in cbreak mode */
- cmini(0); /* No echo */
- prompt(xxstring);
- debok = 0;
- for (x = -1; x < 0 && x != -3; ) { /* Get answer */
- cmres(); /* Reset the parser */
- x = cmtxt("","",&s,NULL); /* Get literal line of text */
- }
- if ((p2 = malloc((int)strlen(s) + 1)) == NULL) {
- printf("?Internal error: malloc\n");
- goto XZXLGI;
- } else
- strcpy(p2,s); /* safe */
- printf("\r\n");
- if ((rc = cmcfm()) < 0)
- goto XZXLGI;
- }
- sstate = setgen('I',p1,p2,p3); /* Get here with at least user ID */
- rc = 0;
-
- XZXLGI: /* Common exit point */
- if (psaved)
- cmsetp(psave); /* Restore original prompt */
- if (p3) { free(p3); p3 = NULL; } /* Free malloc'd storage */
- if (p2) { free(p2); p2 = NULL; }
- if (p1) { free(p1); p1 = NULL; }
- if (rc > -1) {
- if (local && rc > -1) /* If local, flush tty input buffer */
- ttflui();
- }
- return(rc);
-}
-
-#ifdef OS2
-#ifndef NOLOCAL
-int
-dormt(xx) int xx; {
- int rc = 0;
- extern int term_io;
- int term_io_sav = term_io;
-#ifdef NEWFTP
- extern int ftpget, ftpisopen();
- if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
- return(doftprmt(xx,0));
-#endif /* NEWFTP */
- term_io = 0;
- rc = xxdormt(xx);
- term_io = term_io_sav;
- return rc;
-}
-
-
-int
-xxdormt(xx) int xx;
-#else /* NOLOCAL */
-int
-dormt(xx) int xx;
-#endif /* NOLOCAL */
-#else /* OS2 */
-int
-dormt(xx) int xx;
-#endif /* OS2 */
-{ /* REMOTE commands */
- int x, y, retcode;
- char *s, sbuf[50], *s2;
-
-#ifdef NEWFTP
- extern int ftpget, ftpisopen();
- if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
- return(doftprmt(xx,0));
-#endif /* NEWFTP */
-
- remfile = 0; /* Clear these */
- rempipe = 0;
- remappd = 0;
-
- if (xx < 0) return(xx); /* REMOTE what? */
-
- xzcmd = xx; /* Make global copy of arg */
-
- if (xx == XZSET) { /* REMOTE SET */
- if ((y = cmkey(rmstab,nrms,"","",xxstring)) < 0) {
- if (y == -3) {
- printf("?Parameter name required\n");
- return(-9);
- } else return(y);
- }
- return(doprm(y,1));
- }
-
- switch (xx) { /* Others... */
-
- case XZCDU:
- if ((x = cmcfm()) < 0) return(x);
- printf("?Sorry, REMOTE CDUP not supported yet\n");
- return(-9);
-
- case XZCWD: /* CWD (CD) */
- if ((x = cmtxt("Remote directory name","",&s,xxstring)) < 0)
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
- debug(F111,"XZCWD: ",s,x);
- *sbuf = NUL;
- s2 = sbuf;
-/*
- The following is commented out because since the disappearance of the
- DECSYSTEM-20 from the planet, no known computer requires a password for
- changing directory.
-*/
-#ifdef DIRPWDPR
- if (*s != NUL) { /* If directory name given, */
- /* get password on separate line. */
- if (tlevel > -1) { /* From take file... */
-
- if (fgets(sbuf,50,tfile[tlevel]) == NULL)
- fatal("take file ends prematurely in 'remote cwd'");
- debug(F110," pswd from take file",s2,0);
- for (x = (int)strlen(sbuf);
- x > 0 && (sbuf[x-1] == NL || sbuf[x-1] == CR);
- x--)
- sbuf[x-1] = '\0';
-
- } else { /* From terminal... */
-
- printf(" Password: "); /* get a password */
-#ifdef IKSD
- if (!local && inserver) {
- x = coninc(0);
- } else
-#endif /* IKSD */
-#ifdef OS2
- x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
- getchar();
-#else /* OS2 */
- x = getchar();
-#endif /* OS2 */
- while ((x != NL) && (x != CR)) {
- if ((x &= 0177) == '?') {
- printf("? Password of remote directory\n Password: ");
- s2 = sbuf;
- *sbuf = NUL;
- } else if (x == ESC) /* Mini command line editor... */
- bleep(BP_WARN);
- else if (x == BS || x == 0177)
- s2--;
- else if (x == 025) { /* Ctrl-U */
- s2 = sbuf;
- *sbuf = NUL;
- } else
- *s2++ = x;
-
- /* Get the next character */
-#ifdef IKSD
- if (!local && inserver) {
- x = coninc(0);
- } else
-#endif /* IKSD */
-#ifdef OS2
- x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
- getchar();
-#else /* OS2 */
- x = getchar();
-#endif /* OS2 */
- }
- *s2 = NUL;
- putchar('\n');
- }
- s2 = sbuf;
- } else s2 = "";
-#endif /* DIRPWDPR */
-
- debug(F110," password",s2,0);
- rcdactive = 1;
- sstate = setgen('C',s,s2,"");
- retcode = 0;
- break;
-
- case XZDEL: /* Delete */
- if ((x = cmtxt("Name of remote file(s) to delete",
- "",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of remote file(s) required\n");
- return(-9);
- } else return(x);
- }
- if ((x = remtxt(&s)) < 0)
- return(x);
- if (local) ttflui(); /* If local, flush tty input buffer */
- retcode = sstate = rfilop(s,'E');
- break;
-
- case XZDIR: /* Directory */
- if ((x = cmtxt("Remote directory or file specification","",&s,
- xxstring)) < 0)
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
- if (local) ttflui(); /* If local, flush tty input buffer */
- rmsg();
- retcode = sstate = setgen('D',s,"","");
- break;
-
- case XZHLP: /* Help */
- if ((x = remcfm()) < 0) return(x);
- sstate = setgen('H',"","","");
- retcode = 0;
- break;
-
- case XZHOS: /* Host */
- if ((x = cmtxt("Command for remote system","",&s,xxstring)) < 0)
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
- if ((y = (int)strlen(s)) < 1)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- cmarg = line;
- rmsg();
- retcode = sstate = 'c';
- break;
-
-#ifndef NOFRILLS
- case XZKER:
- if ((x = cmtxt("Command for remote Kermit","",&s,xxstring)) < 0)
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
- if ((int)strlen(s) < 1) {
- if (x == -3) {
- printf("?Remote Kermit command required\n");
- return(-9);
- } else return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- cmarg = line;
- retcode = sstate = 'k';
- rmsg();
- break;
-
- case XZLGI: /* Login */
- rcdactive = 1; /* Suppress "Logged in" msg if quiet */
- return(plogin(XXREM));
-
- case XZLGO: { /* Logout */
- extern int bye_active;
- if ((x = remcfm()) < 0) return(x);
- sstate = setgen('I',"","","");
- retcode = 0;
- bye_active = 1; /* Close connection when done */
- break;
- }
-
- case XZPRI: /* Print */
- if (!atdiso || !atcapr) { /* Disposition attribute off? */
- printf("?Disposition Attribute is Off\n");
- return(-2);
- }
- cmarg = "";
- cmarg2 = "";
- if ((x = cmifi("Local file(s) to print on remote printer","",&s,&y,
- xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of local file(s) required\n");
- return(-9);
- }
- return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of filename */
- *optbuf = NUL; /* Wipe out any old options */
- if ((x = cmtxt("Options for remote print command","",&s,xxstring)) < 0)
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
- if ((int)strlen(optbuf) > 94) { /* Make sure this is legal */
- printf("?Option string too long\n");
- return(-9);
- }
- ckstrncpy(optbuf,s,OPTBUFLEN); /* Make a safe copy of options */
- nfils = -1; /* Expand file list internally */
- cmarg = line; /* Point to file list. */
- rprintf = 1; /* REMOTE PRINT modifier for SEND */
- sstate = 's'; /* Set start state to SEND */
- if (local) displa = 1;
- retcode = 0;
- break;
-#endif /* NOFRILLS */
-
- case XZSPA: /* Space */
- if ((x = cmtxt("Confirm, or remote directory name",
- "",&s,xxstring)) < 0)
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
- retcode = sstate = setgen('U',s,"","");
- break;
-
- case XZMSG: /* Message */
- if ((x = cmtxt("Short text message for server","",&s,xxstring)) < 0)
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
- retcode = sstate = setgen('M',s,"","");
- break;
-
-#ifndef NOFRILLS
- case XZTYP: /* Type */
- if ((x = cmtxt("Remote file specification","",&s,xxstring)) < 0)
- return(x);
- if ((int)strlen(s) < 1) {
- printf("?Remote filename required\n");
- return(-9);
- }
- if ((x = remtxt(&s)) < 0)
- return(x);
- rmsg();
- retcode = sstate = rfilop(s,'T');
- break;
-#endif /* NOFRILLS */
-
-#ifndef NOFRILLS
- case XZWHO:
- if ((x = cmtxt("Remote user name, or carriage return",
- "",&s,xxstring)) < 0)
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
- retcode = sstate = setgen('W',s,"","");
- break;
-#endif /* NOFRILLS */
-
- case XZPWD: /* PWD */
- if ((x = remcfm()) < 0) return(x);
- sstate = setgen('A',"","","");
- retcode = 0;
- break;
-
-#ifndef NOSPL
- case XZQUE: { /* Query */
- char buf[2];
- extern char querybuf[], * qbufp;
- extern int qbufn;
- if ((y = cmkey(vartyp,nvartyp,"","",xxstring)) < 0)
- return(y);
- if ((x = cmtxt(y == 'F' ? "Remote function invocation" :
- ('K' ? "Remote variable name or function":
- "Remote variable name"),
- "",
- &s,
- (y == 'K') ? xxstring : NULL
- )) < 0) /* Don't evaluate */
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
- query = 1; /* QUERY is active */
- qbufp = querybuf; /* Initialize query response buffer */
- qbufn = 0;
- querybuf[0] = NUL;
- buf[0] = (char) (y & 127);
- buf[1] = NUL;
- retcode = sstate = setgen('V',"Q",(char *)buf,s);
- break;
- }
-
- case XZASG: { /* Assign */
- char buf[VNAML];
- if ((y = cmfld("Remote variable name","",&s,NULL)) < 0) /* No eval */
- return(y);
- if ((int)strlen(s) >= VNAML) {
- printf("?Too long\n");
- return(-9);
- }
- ckstrncpy(buf,s,VNAML);
- if ((x = cmtxt("Assignment for remote variable",
- "",&s,xxstring)) < 0) /* Evaluate this one */
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
-#ifdef COMMENT
-/*
- Server commands can't be long packets. In principle there's no reason
- why they shouldn't be, except that we don't know at this point if the
- server is capable of accepting long packets because we haven't started
- the protocol yet. In practice, allowing a long packet here breaks a lot
- of assumptions, causes buffer overruns and crashes, etc. To be fixed
- later. (But since this is commented out, evidently I fixed it later...)
-*/
- if ((int)strlen(s) > 85) { /* Allow for encoding expansion */
- printf("?Sorry, value is too long - 85 characters max\n");
- return(-9);
- }
-#endif /* COMMENT */
- retcode = sstate = setgen('V',"S",(char *)buf,s);
- break;
- }
-#endif /* NOSPL */
-
- case XZCPY: { /* COPY */
- char buf[TMPBUFSIZ];
- buf[TMPBUFSIZ-1] = '\0';
- if ((x = cmfld("Name of remote file to copy","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of remote file required\n");
- return(-9);
- }
- else
- return(x);
- }
- ckstrncpy(buf,s,TMPBUFSIZ);
- if ((x = cmfld("Name of remote destination file or directory",
- "",&s, xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of remote file or directory required\n");
- return(-9);
- } else return(x);
- }
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((x = remcfm()) < 0)
- return(x);
- if (local) ttflui(); /* If local, flush tty input buffer */
- retcode = sstate = setgen('K',buf,tmpbuf,"");
- break;
- }
- case XZREN: { /* Rename */
- char buf[TMPBUFSIZ];
- buf[TMPBUFSIZ-1] = '\0';
- if ((x = cmfld("Name of remote file to rename",
- "",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of remote file required\n");
- return(-9);
- } else return(x);
- }
- ckstrncpy(buf,s,TMPBUFSIZ);
- if ((x = cmfld("New name of remote file","",&s, xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of remote file required\n");
- return(-9);
- } else return(x);
- }
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((x = remcfm()) < 0)
- return(x);
- if (local) ttflui(); /* If local, flush device buffer */
- retcode = sstate = setgen('R',buf,tmpbuf,"");
- break;
- }
- case XZMKD: /* mkdir */
- case XZRMD: /* rmdir */
- if ((x = cmtxt((xx == XZMKD) ?
- "Name of remote directory to create" :
- "Name of remote directory to delete",
- "",
- &s,
- xxstring
- )) < 0) {
- if (x == -3) {
- printf("?Name required\n");
- return(-9);
- } else return(x);
- }
- if ((x = remtxt(&s)) < 0)
- return(x);
- if (local) ttflui(); /* If local, flush tty input buffer */
- retcode = sstate = rfilop(s, (char)(xx == XZMKD ? 'm' : 'd'));
- break;
-
- case XZXIT: /* Exit */
- if ((x = remcfm()) < 0) return(x);
- sstate = setgen('X',"","","");
- retcode = 0;
- break;
-
- default:
- if ((x = remcfm()) < 0) return(x);
- printf("?Not implemented - %s\n",cmdbuf);
- return(-2);
- }
- if (local && retcode > -1) /* If local, flush tty input buffer */
- ttflui();
- return(retcode);
-}
-
-
-/* R F I L O P -- Remote File Operation */
-
-CHAR
-#ifdef CK_ANSIC
-rfilop(char * s, char t)
-#else
-rfilop(s,t) char *s, t;
-#endif /* CK_ANSIC */
-/* rfilop */ {
- if (*s == NUL) {
- printf("?File specification required\n");
- return((CHAR) 0);
- }
- debug(F111,"rfilop",s,t);
- return(setgen(t,s,"",""));
-}
-#endif /* NOXFER */
-
-#ifdef ANYX25
-int
-setx25() {
- if ((y = cmkey(x25tab,nx25,"X.25 call options","",xxstring)) < 0)
- return(y);
- switch (y) {
- case XYUDAT:
- if ((z = cmkey(onoff,2,"X.25 call user data","",xxstring))
- < 0) return(z);
- if (z == 0) {
- if ((z = cmcfm()) < 0) return(z);
- cudata = 0; /* disable call user data */
- return (success = 1);
- }
- if ((x = cmtxt("X.25 call user data string","",&s,xxstring)) < 0)
- return(x);
- if ((int)strlen(s) == 0) {
- return (-3);
- } else if ((int)strlen(s) > MAXCUDATA) {
- printf("?The length must be > 0 and <= %d\n",MAXCUDATA);
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- ckstrncpy(udata,s,MAXCUDATA);
- cudata = 1; /* X.25 call user data specified */
- return (success = 1);
- case XYCLOS:
- if ((z = cmkey(onoff,2,"X.25 closed user group call","",xxstring))
- < 0) return(z);
- if (z == 0) {
- if ((z = cmcfm()) < 0) return(z);
- closgr = -1; /* disable closed user group */
- return (success = 1);
- }
- if ((y = cmnum("0 <= cug index >= 99","",10,&x,xxstring)) < 0)
- return(y);
- if (x < 0 || x > 99) {
- printf("?The choices are 0 <= cug index >= 99\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- closgr = x; /* closed user group selected */
- return (success = 1);
-
- case XYREVC:
- if((z = cmkey(onoff,2,"X.25 reverse charge call","",xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- revcall = z;
- return (success = 1);
- }
-}
-
-#ifndef IBMX25
-int
-setpadp() {
- if ((y = cmkey(padx3tab,npadx3,"PAD X.3 parameter name","",xxstring)) < 0)
- return(y);
- x = y;
- switch (x) {
- case PAD_BREAK_CHARACTER:
- if ((y = cmnum("PAD break character value","",10,&z,xxstring)) < 0)
- return(y);
- if ((y = cmcfm()) < 0) return(y);
- break;
- case PAD_ESCAPE:
- if ((y = cmnum("PAD escape","",10,&z,xxstring)) < 0) return(y);
- if (z != 0 && z != 1) {
- printf("?The choices are 0 or 1\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
- case PAD_ECHO:
- if ((y = cmnum("PAD echo","",10,&z,xxstring)) < 0) return(y);
- if (z != 0 && z != 1) {
- printf("?The choices are 0 or 1\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
- case PAD_DATA_FORWARD_CHAR:
- if ((y = cmnum("PAD data forward char","",10,&z,xxstring)) < 0)
- return(y);
- if (z != 0 && z != 2) {
- printf("?The choices are 0 or 2\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
- case PAD_DATA_FORWARD_TIMEOUT:
- if ((y = cmnum("PAD data forward timeout","",10,&z,xxstring)) < 0)
- return(y);
- if (z < 0 || z > 255) {
- printf("?The choices are 0 or 1 <= timeout <= 255\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
- case PAD_FLOW_CONTROL_BY_PAD:
- if ((y = cmnum("PAD pad flow control","",10,&z,xxstring)) < 0)
- return(y);
- if (z != 0 && z != 1) {
- printf("?The choices are 0 or 1\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
- case PAD_SUPPRESSION_OF_SIGNALS:
- if ((y = cmnum("PAD service","",10,&z,xxstring)) < 0) return(y);
- if (z != 0 && z != 1) {
- printf("?The choices are 0 or 1\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_BREAK_ACTION:
- if ((y = cmnum("PAD break action","",10,&z,xxstring)) < 0) return(y);
- if (z != 0 && z != 1 && z != 2 && z != 5 && z != 8 && z != 21) {
- printf("?The choices are 0, 1, 2, 5, 8 or 21\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_SUPPRESSION_OF_DATA:
- if ((y = cmnum("PAD data delivery","",10,&z,xxstring)) < 0) return(y);
- if (z != 0 && z != 1) {
- printf("?The choices are 0 or 1\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_PADDING_AFTER_CR:
- if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
- if (z < 0 || z > 7) {
- printf("?The choices are 0 or 1 <= crpad <= 7\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_LINE_FOLDING:
- if ((y = cmnum("PAD linefold","",10,&z,xxstring)) < 0) return(y);
- if (z < 0 || z > 255) {
- printf("?The choices are 0 or 1 <= linefold <= 255\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_LINE_SPEED:
- if ((y = cmnum("PAD baudrate","",10,&z,xxstring)) < 0) return(y);
- if (z < 0 || z > 18) {
- printf("?The choices are 0 <= baudrate <= 18\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_FLOW_CONTROL_BY_USER:
- if ((y = cmnum("PAD terminal flow control","",10,&z,xxstring)) < 0)
- return(y);
- if (z != 0 && z != 1) {
- printf("?The choices are 0 or 1\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_LF_AFTER_CR:
- if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
- if (z < 0 || z == 3 || z > 7) {
- printf("?The choices are 0, 1, 2, 4, 5, 6 or 7\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_PADDING_AFTER_LF:
- if ((y = cmnum("PAD lfpad","",10,&z,xxstring)) < 0) return(y);
- if (z < 0 || z > 7) {
- printf("?The choices are 0 or 1 <= lfpad <= 7\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_EDITING:
- if ((y = cmnum("PAD edit control","",10,&z,xxstring)) < 0) return(y);
- if (z != 0 && z != 1) {
- printf("?The choices are 0 or 1\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_CHAR_DELETE_CHAR:
- if ((y = cmnum("PAD char delete char","",10,&z,xxstring)) < 0)
- return(y);
- if (z < 0 || z > 127) {
- printf("?The choices are 0 or 1 <= chardelete <= 127\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_BUFFER_DELETE_CHAR:
- if ((y = cmnum("PAD buffer delete char","",10,&z,xxstring)) < 0)
- return(y);
- if (z < 0 || z > 127) {
- printf("?The choices are 0 or 1 <= bufferdelete <= 127\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
-
- case PAD_BUFFER_DISPLAY_CHAR:
- if ((y = cmnum("PAD display line char","",10,&z,xxstring)) < 0)
- return(y);
- if (z < 0 || z > 127) {
- printf("?The choices are 0 or 1 <= displayline <= 127\n");
- return(-2);
- }
- if ((y = cmcfm()) < 0) return(y);
- break;
- }
- padparms[x] = z;
- return(success = 1);
-}
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifndef NOXFER
-int
-setat(rmsflg) int rmsflg; {
- int xx;
- if ((y = cmkey(attrtab,natr,"File Attribute packets","",xxstring)) < 0)
- return(y);
- if (y == AT_XALL) { /* ATTRIBUTES ALL ON or ALL OFF */
- if ((z = seton(&xx)) < 0) return(z);
- if (rmsflg) {
- printf("Sorry, command not available\n");
- return(-9);
- } else {
- atenci = xx; /* Encoding in */
- atenco = xx; /* Encoding out */
- atdati = xx; /* Date in */
- atdato = xx; /* Date out */
- atdisi = xx; /* Disposition in/out */
- atdiso = xx;
- atleni = xx; /* Length in/out (both kinds) */
- atleno = xx;
- atblki = xx; /* Blocksize in/out */
- atblko = xx;
- attypi = xx; /* File type in/out */
- attypo = xx;
- atsidi = xx; /* System ID in/out */
- atsido = xx;
- atsysi = xx; /* System-dependent params in/out */
- atsyso = xx;
-#ifdef CK_PERMS /* Protection */
- atlpri = xx; /* Local in */
- atlpro = xx; /* Local out */
- atgpri = xx; /* Generic in */
- atgpro = xx; /* Generic out */
-#endif /* CK_PERMS */
-#ifdef STRATUS
- atfrmi = xx; /* Format in/out */
- atfrmo = xx;
- atcrei = xx; /* Creator id in/out */
- atcreo = xx;
- atacti = xx; /* Account in/out */
- atacto = xx;
-#endif /* STRATUS */
- }
- return(z);
- } else if (y == AT_ALLY || y == AT_ALLN) { /* ATTRIBUTES ON or OFF */
- if ((x = cmcfm()) < 0) return(x);
- atcapr = (y == AT_ALLY) ? 1 : 0;
- if (rmsflg) {
- sstate = setgen('S', "132", atcapr ? "1" : "0", "");
- return((int) sstate);
- } else return(success = 1);
- }
- /* Otherwise, it's an individual attribute that wants turning off/on */
-
- if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
- if ((x = cmcfm()) < 0) return(x);
-
-/* There are better ways to do this... */
-/* The real problem is that we're not separating the in and out cases */
-/* and so we have to arbitrarily pick the "in" case, i.e tell the remote */
-/* server to ignore incoming attributes of the specified type, rather */
-/* than telling it not to send them. The protocol does not (yet) define */
-/* codes for "in-and-out-at-the-same-time". */
-
- switch (y) {
-#ifdef CK_PERMS
-/* We're lumping local and generic protection together for now... */
- case AT_LPRO:
- case AT_GPRO:
- if (rmsflg) {
- sstate = setgen('S', "143", z ? "1" : "0", "");
- return((int) sstate);
- }
- atlpri = atlpro = atgpri = atgpro = z; break;
-#endif /* CK_PERMS */
- case AT_DISP:
- if (rmsflg) {
- sstate = setgen('S', "142", z ? "1" : "0", "");
- return((int) sstate);
- }
- atdisi = atdiso = z; break;
- case AT_ENCO:
- if (rmsflg) {
- sstate = setgen('S', "141", z ? "1" : "0", "");
- return((int) sstate);
- }
- atenci = atenco = z; break;
- case AT_DATE:
- if (rmsflg) {
- sstate = setgen('S', "135", z ? "1" : "0", "");
- return((int) sstate);
- }
- atdati = atdato = z; break;
- case AT_LENB:
- case AT_LENK:
- if (rmsflg) {
- sstate = setgen('S', "133", z ? "1" : "0", "");
- return((int) sstate);
- }
- atleni = atleno = z; break;
- case AT_BLKS:
- if (rmsflg) {
- sstate = setgen('S', "139", z ? "1" : "0", "");
- return((int) sstate);
- }
- atblki = atblko = z; break;
- case AT_FTYP:
- if (rmsflg) {
- sstate = setgen('S', "134", z ? "1" : "0", "");
- return((int) sstate);
- }
- attypi = attypo = z; break;
-#ifdef STRATUS
- case AT_CREA:
- if (rmsflg) {
- sstate = setgen('S', "136", z ? "1" : "0", "");
- return((int) sstate);
- }
- atcrei = atcreo = z; break;
- case AT_ACCT:
- if (rmsflg) {
- sstate = setgen('S', "137", z ? "1" : "0", "");
- return((int) sstate);
- }
- atacti = atacto = z; break;
-#endif /* STRATUS */
- case AT_SYSI:
- if (rmsflg) {
- sstate = setgen('S', "145", z ? "1" : "0", "");
- return((int) sstate);
- }
- atsidi = atsido = z; break;
- case AT_RECF:
- if (rmsflg) {
- sstate = setgen('S', "146", z ? "1" : "0", "");
- return((int) sstate);
- }
- atfrmi = atfrmo = z; break;
- case AT_SYSP:
- if (rmsflg) {
- sstate = setgen('S', "147", z ? "1" : "0", "");
- return((int) sstate);
- }
- atsysi = atsyso = z; break;
- default:
- printf("?Not available\n");
- return(-2);
- }
- return(1);
-}
-#endif /* NOXFER */
-
-#ifndef NOSPL
-int
-setinp() {
- if ((y = cmkey(inptab,ninp,"","",xxstring)) < 0) return(y);
- switch (y) {
-#ifdef OS2
- case IN_PAC: /* SET INPUT PACING */
- z = cmnum("milliseconds","0",10,&x,xxstring);
- return(setnum(&tt_inpacing,x,z,1000));
- case IN_TRM: /* SET INPUT TERMINAL */
- return(seton(&interm));
-#endif /* OS2 */
- case IN_DEF: /* SET INPUT DEFAULT-TIMEOUT */
- z = cmnum("Positive number","",10,&x,xxstring);
- return(setnum(&indef,x,z,94));
-#ifdef CKFLOAT
- case IN_SCA: /* SET INPUT SCALE-FACTOR */
- if ((x = cmfld("Number such as 2 or 0.5","1.0",&s, xxstring)) < 0)
- return(x);
- if (isfloat(s,0)) { /* A floating-point number? */
- extern char * inpscale;
- inscale = floatval; /* Yes, get its value */
- makestr(&inpscale,s); /* Save it as \v(inscale) */
- return(success = 1);
- } else {
- return(-2);
- }
-#endif /* CKFLOAT */
- case IN_TIM: /* SET INPUT TIMEOUT-ACTION */
- if ((z = cmkey(intimt,2,"","",xxstring)) < 0) return(z);
- if ((x = cmcfm()) < 0) return(x);
- intime[cmdlvl] = z;
- return(success = 1);
- case IN_CAS: /* SET INPUT CASE */
- if ((z = cmkey(incast,2,"","",xxstring)) < 0) return(z);
- if ((x = cmcfm()) < 0) return(x);
- inpcas[cmdlvl] = z;
- return(success = 1);
- case IN_ECH: /* SET INPUT ECHO */
- return(seton(&inecho));
- case IN_SIL: /* SET INPUT SILENCE */
- z = cmnum("Seconds of inactivity before INPUT fails","",10,&x,
- xxstring);
- return(setnum(&insilence,x,z,-1));
-
- case IN_BUF: /* SET INPUT BUFFER-SIZE */
- if ((z = cmnum("Number of bytes in INPUT buffer",
- ckitoa(INPBUFSIZ),10,&x, xxstring)) < 0)
- return(z);
- if ((y = cmcfm()) < 0) return(y);
- inbufsize = 0;
- if (inpbuf) {
- free(inpbuf);
- inpbuf = NULL;
- inpbp = NULL;
- }
- if (!(s = (char *)malloc(x + 1)))
- return(0);
- inpbuf = s;
- inpbp = s;
- inbufsize = x;
- for (x = 0; x <= inbufsize; x++)
- inpbuf[x] = NUL;
- return(success = 1);
-
-#ifdef CK_AUTODL
- case IN_ADL: /* AUTODOWNLOAD */
- return(seton(&inautodl));
-#endif /* CK_AUTODL */
-
- case IN_CAN: /* SET INPUT INTERRUPTS */
- return(seton(&inintr));
- }
- return(0);
-}
-#endif /* NOSPL */
-
-#ifdef NETCONN
-VOID
-ndreset() {
-#ifndef NODIAL /* This depends on DIAL... */
- int i=0, j=0;
- if (!ndinited) /* Don't free garbage... */
- return;
- for (i = 0; i < nhcount; i++) { /* Clean out previous list */
- if (nh_p[i])
- free(nh_p[i]);
- nh_p[i] = NULL;
- if (nh_p2[i])
- free(nh_p2[i]);
- nh_p2[i] = NULL;
- for (j = 0; j < 4; j++) {
- if (nh_px[j][i])
- free(nh_px[j][i]);
- nh_px[j][i] = NULL;
- }
- }
-#endif /* NODIAL */
-}
-
-VOID
-ndinit() { /* Net directory pointers */
-#ifndef NODIAL /* This depends on DIAL... */
- int i, j;
- if (ndinited++) /* Don't do this more than once. */
- return;
- for (i = 0; i < MAXDDIR; i++) { /* Init all pointers to NULL */
- netdir[i] = NULL;
- }
- for (i = 0; i < MAXDNUMS; i++) {
- nh_p[i] = NULL;
- nh_p2[i] = NULL;
- for (j = 0; j < 4; j++)
- nh_px[j][i] = NULL;
- }
-#endif /* NODIAL */
-}
-
-#ifndef NODIAL
-#ifdef NETCONN
-VOID /* Get net defaults from environment */
-getnetenv() {
- char *p = NULL;
-
- makestr(&p,getenv("K_NET_DIRECTORY")); /* Dialing directories */
- if (p) {
- int i;
- xwords(p,MAXDDIR,netdir,0);
- for (i = 0; i < MAXDDIR; i++) { /* Fill in any gaps... */
- if (!netdir[i+1])
- break;
- else
- netdir[i] = netdir[i+1];
- debug(F111,"netdir[i]",netdir[i],i);
- }
- nnetdir = i;
- }
-}
-#endif /* NETCONN */
-#endif /* NODIAL */
-
-int
-#ifdef CK_ANSIC
-lunet(char *s) /* s = name to look up */
-#else
-lunet(s) char *s;
-#endif /* CK_ANSIC */
-/* lunet */ {
-#ifndef NODIAL /* This depends on DIAL... */
- int n, n1, t, dd = 0;
- int ambiguous = 0;
- FILE * f;
- char *line = NULL;
- extern int dialdpy;
- int netdpy = dialdpy;
- char *info[8];
-
- nhcount = 0; /* Set this before returning */
-
- if (!s || nnetdir < 1) /* Validate arguments */
- return(-1);
-
- if (isdigit(*s) || *s == '*' || *s == '.')
- return(0);
-
- if ((n1 = (int) strlen(s)) < 1) /* Length of string to look up */
- return(-1);
-
- if (!(line = malloc(1024))) /* Allocate input buffer */
- return(-1);
-
- lu_again:
- f = NULL; /* Network directory file descriptor */
- t = nhcount = 0; /* Match count */
- dd = 0; /* Directory counter */
-
- dirline = 0;
- while (1) { /* We make one pass */
- if (!f) { /* Directory not open */
- if (dd >= nnetdir) /* No directories left? */
- break; /* Done. */
- if ((f = fopen(netdir[dd],"r")) == NULL) { /* Open it */
- perror(netdir[dd]); /* Can't, print message saying why */
- dd++;
- continue; /* But go on to next one. */
- }
- if (netdpy)
- printf("Opening %s...\n",netdir[dd]);
- dd++;
- }
- line[0] = NUL;
- if (getnct(line,1023,f,1) < 0) { /* Read a line */
- if (f) { /* f can be clobbered! */
- fclose(f); /* Close the file */
- f = NULL; /* Indicate next one needs opening */
- }
- continue;
- }
- if (!line[0]) /* Empty line */
- continue;
-
- xwords(line,7,info,0); /* Parse it */
-
- if (!info[1] || !info[2] || !info[3]) /* Required fields */
- continue;
- if (*info[1] == ';') /* Full-line comment */
- continue;
- if ((n = (int) strlen(info[1])) < 1) /* Length of name-tag */
- continue;
- if (n < n1) /* Search name is longer */
- continue; /* Can't possibly match */
- if (ambiguous && n != n1)
- continue;
- if (ckstrcmp(s,info[1],n1,0)) /* Compare using length of */
- continue; /* search string s. */
-
- /* Have a match */
-
- makestr(&(nh_p[nhcount]), info[3]); /* address */
- makestr(&(nh_p2[nhcount]),info[2]); /* net type */
- makestr(&(nh_px[0][nhcount]),info[4]); /* net-specific stuff... */
- makestr(&(nh_px[1][nhcount]),info[5]);
- makestr(&(nh_px[2][nhcount]),info[6]);
- makestr(&(nh_px[3][nhcount]),info[7]);
-
- nhcount++; /* Count this match */
- if (nhcount > MAXDNUMS) { /* Watch out for too many */
- printf("Warning: %d matches found, %d max\n",
- nhcount,
- MAXDNUMS
- );
- nhcount = MAXDNUMS;
- break;
- }
- if (nhcount == 1) { /* First one - save entry name */
- if (n_name) { /* Free the one from before if any */
- free(n_name);
- n_name = NULL;
- }
- if (!(n_name = (char *)malloc(n + 1))) { /* Allocate new storage */
- printf("?memory allocation error - lunet:3\n");
- if (line) {
- free(line);
- line = NULL;
- }
- nhcount = 0;
- return(-1);
- }
- t = n; /* Remember its length */
- strcpy(n_name,info[1]); /* safe */
- } else { /* Second or subsequent one */
- if ((int) strlen(info[1]) == t) /* Lengths compare */
- if (!ckstrcmp(n_name,info[1],t,0)) /* Caseless compare OK */
- continue;
-
- /* Name given by user matches entries with different names */
-
- if (ambiguous) /* Been here before */
- break;
-
- ambiguous = 1; /* Now an exact match is required */
- ndreset(); /* Clear out previous list */
- goto lu_again; /* Do it all over again. */
- }
- }
- if (line) {
- free(line);
- line = NULL;
- }
- if (nhcount == 0 && ambiguous)
- printf("?\"%s\" - ambiguous in network directory\n",s);
-#else
- nhcount = 0;
-#endif /* NODIAL */
- return(nhcount);
-}
-#endif /* NETCONN */
-
-#ifndef NOLOCAL
-/* C L S C O N N X -- Close connection */
-
-int
-clsconnx(ask) int ask; {
- int x, rc = 0;
-#ifdef NEWFTP
- extern int ftpget, ftpisopen();
- if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
- return(success = ftpbye());
-#endif /* NEWFTP */
- debug(F101,"clsconnx local","",local);
- if (local) {
- x = ask ? hupok(1) : 1; /* Make sure it's OK to close */
- if (!x) {
- rc = -1;
- debug(F101,"clsconnx hupok says no","",rc);
- return(rc);
- }
- ttflui(); /* Clear away buffered up junk */
-#ifndef NODIAL
-#ifdef OS2ONLY
-/* Don't hangup a line that is shared with the SLIP or PPP driver */
- if (!ttslip && !ttppp)
-#endif /* OS2ONLY */
- mdmhup();
-#endif /* NODIAL */
- if (network && msgflg)
- printf(" Closing connection\n");
- ttclos(0); /* Close old connection, if any */
- rc = 1;
- {
- extern int wasclosed, whyclosed;
- if (wasclosed) {
- whyclosed = WC_CLOS;
-#ifndef NOSPL
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- /* printf("ON_CLOSE CLSCONNX\n"); */
- wasclosed = 0;
- k = mlook(mactab,"on_close",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ckitoa(whyclosed),0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
-#endif /* NOSPL */
- whyclosed = WC_REMO;
- wasclosed = 0;
- }
- }
- }
-#ifdef VMS /* Or maybe #ifndef UNIX? */
- else { /* Need to do this in VMS to */
- ttclos(0); /* free the tty channel number */
- rc = 1; /* obtained in ttopen() or else */
- } /* subsequent ttopen's won't work */
-#endif /* VMS */
- dologend();
- haveline = 0;
- if (mdmtyp < 0) { /* Switching from net to async? */
- if (mdmsav > -1) /* Restore modem type from last */
- mdmtyp = mdmsav; /* SET MODEM command, if any. */
- else
- mdmtyp = 0;
- mdmsav = -1;
- }
- if (network)
- network = 0;
-#ifdef NETCONN
- if (oldplex > -1) { /* Restore previous duplex setting. */
- duplex = oldplex;
- oldplex = -1;
- }
-#endif /* NETCONN */
-#ifndef MAC
- ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default communication */
-#endif /* MAC */
- local = dfloc; /* device and local/remote status */
- if (local) {
- cxtype = CXT_DIRECT; /* Something reasonable */
- speed = ttgspd(); /* Get the current speed */
- } else {
- cxtype = CXT_REMOTE;
- speed = -1L;
- }
-#ifndef NOXFER
- if (xreliable > -1 && !setreliable) {
- reliable = xreliable;
- debug(F101,"clsconnx reliable A","",reliable);
- } else if (!setreliable) {
- reliable = SET_AUTO;
- debug(F101,"clsconnx reliable B","",reliable);
- }
-#endif /* NOXFER */
- setflow(); /* Revert flow control */
- return(rc);
-}
-
-int
-clskconnx(x) int x; { /* Close Kermit connection only */
- int t, rc; /* (not FTP) */
-#ifdef NEWFTP
- extern int ftpget;
- t = ftpget;
- ftpget = 0;
-#endif /* NEWFTP */
- rc = clsconnx(x);
-#ifdef NEWFTP
- ftpget = t;
-#endif /* NEWFTP */
- return(rc);
-}
-
-/* May 2002: setlin() decomposition starts here ... */
-
-#ifdef OS2
-#define SRVBUFSIZ PIPENAML
-#else /* OS2 */
-#define SRVBUFSIZ 63
-#endif /* OS2 */
-#define HOSTNAMLEN 15*65
-
-int netsave = -1;
-static char * tmpstring = NULL;
-static char * tmpusrid = NULL;
-
-#ifdef SSHCMD
-char * sshcmd = NULL;
-char * defsshcmd = "ssh -e none";
-#else
-#ifdef SSHBUILTIN
-char * sshrcmd = NULL;
-char * sshtmpcmd = NULL;
-#endif /* SSHBUILTIN */
-#endif /* SSHCMD */
-
-/* c x _ f a i l -- Common error exit routine for cx_net, cx_line */
-
-int
-cx_fail(msg, text) int msg; char * text; {
- makestr(&slmsg,text); /* For the record (or GUI) */
- if (msg) /* Not GUI, not quiet, etc */
- printf("?%s\n",text); /* Print error message */
- slrestor(); /* Restore LINE/HOST to known state */
- return(msg ? -9 : (success = 0)); /* Return appropriate code */
-}
-
-#ifdef NETCONN
-/* c x _ n e t -- Make a network connection */
-
-/*
- Call with:
- net = network type
- protocol = protocol type
- host = string pointer to host name.
- svc = string pointer to service or port on host.
- username = username for connection
- password = password for connection
- command = command to execute
- param1 = Telnet: Authentication type
- SSH: Version
- param2 = Telnet: Encryption type
- SSH: Command as Subsystem
- param3 = Telnet: 1 to wait for negotiations, 0 otherwise
- SSH: X11 Forwarding
- cx = 1 to automatically enter Connect mode, 0 otherwise.
- sx = 1 to automatically enter Server mode, 0 otherwise.
- flag = if no host name given, 1 = close current connection, 0 = resume
- gui = 1 if called from GUI dialog, 0 otherwise.
- Returns:
- 1 on success
- 0 on failure and no message printed, slmsg set to failure message.
- -9 on failure and message printed, ditto.
-*/
-int
-#ifdef CK_ANSIC
-cx_net( int net, int protocol, char * xhost, char * svc,
- char * username, char * password, char * command,
- int param1, int param2, int param3, int cx, int sx, int flag, int gui)
-#else /* CK_ANSIC */
-cx_net(net, protocol, xhost, svc,
- username, password, command,
- param1, param2, param3, cx, sx, flag, gui)
- char * xhost, * svc, * username, *password, *command;
- int net, protocol, cx, sx, flag, param1, param2, param3, gui;
-#endif /* CK_ANSIC */
-/* cx_net */ {
-
- int i, n, x, msg;
- int _local = -1;
-
- extern char pwbuf[], * g_pswd;
- extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
-
- char srvbuf[SRVBUFSIZ+1]; /* Service */
- char hostbuf[HOSTNAMLEN]; /* Host buffer to manipulate */
- char hostname[HOSTNAMLEN]; /* Copy of host parameter */
- char * host = hostbuf; /* Pointer to copy of host param */
-
- if (!xhost) xhost = ""; /* Watch out for null pointers */
- if (!svc) svc = "";
- ckstrncpy(host,xhost,HOSTNAMLEN); /* Avoid buffer confusion */
-
- debug(F110,"cx_net host",host,0);
- debug(F111,"cx_net service",svc,SRVBUFSIZ);
- debug(F101,"cx_net network type","",net);
-
- msg = (gui == 0) && msgflg; /* Whether to print messages */
-
-#ifndef NODIAL
- debug(F101,"cx_net nnetdir","",nnetdir);
- x = 0; /* Look up in network directory */
- if (*host == '=') { /* If number starts with = sign */
- host++; /* strip it */
- while (*host == SP) host++; /* and any leading spaces */
- debug(F110,"cx_net host 2",host,0);
- nhcount = 0;
- } else if (*host) { /* We want to look it up. */
- if (nnetdir > 0) /* If there is a directory... */
- x = lunet(host); /* (sets nhcount) */
- else /* otherwise */
- nhcount = 0; /* we didn't find any there */
- if (x < 0) /* Internal error? */
- return(cx_fail(msg,"Network directory lookup error"));
- debug(F111,"cx_net lunet nhcount",host,nhcount);
- }
-#endif /* NODIAL */
-
- /* New connection wanted. Make a copy of the host name/address... */
-
- if (clskconnx(1) < 0) /* Close current Kermit connection */
- return(cx_fail(msg,"Error closing previous connection"));
-
- if (*host) { /* They gave a hostname */
- _local = 1; /* Network connection always local */
- if (mdmsav < 0)
- mdmsav = mdmtyp; /* Remember old modem type */
- mdmtyp = -net; /* Special code for network */
- } else { /* They just said "set host" */
- host = dftty; /* So go back to normal */
- _local = dfloc; /* default tty, location, */
- if (flag) { /* Close current connection */
- setflow(); /* Maybe change flow control */
- haveline = 1; /* (* is this right? *) */
- dologend();
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#endif /* NODIAL */
-#ifdef LOCUS
- if (autolocus) {
- setlocus(1,1);
- }
-#endif /* LOCUS */
- /* XXX - Is this right? */
- /* Should we be returning without doing anything ? */
- /* Yes it's right -- we closed the old connection just above. */
- return(success = 1);
- }
- }
- success = 0;
- if (host != line) /* line[] is a global */
- ckstrncpy(line,host,LINBUFSIZ);
- ckstrncpy(hostname,host,HOSTNAMLEN);
- ckstrncpy(srvbuf,svc,SRVBUFSIZ+1);
-
-#ifndef NODIAL
- if ((nhcount > 1) && msg) {
- int k;
- printf("%d entr%s found for \"%s\"%s\n",
- nhcount,
- (nhcount == 1) ? "y" : "ies",
- s,
- (nhcount > 0) ? ":" : "."
- );
- for (i = 0; i < nhcount; i++) {
- printf("%3d. %-12s => %-9s %s",
- i+1,n_name,nh_p2[i],nh_p[i]);
- for (k = 0; k < 4; k++) { /* Also list net-specific items */
- if (nh_px[k][i]) /* free format... */
- printf(" %s",nh_px[k][i]);
- else
- break;
- }
- printf("\n");
- }
- }
- if (nhcount == 0)
- n = 1;
- else
- n = nhcount;
-#else
- n = 1;
- nhcount = 0;
-#endif /* NODIAL */
-
- for (i = 0; i < n; i++) { /* Loop for each entry found */
- debug(F101,"cx_net loop i","",i);
-#ifndef NODIAL
- if (nhcount > 0) { /* If we found at least one entry... */
- ckstrncpy(line,nh_p[i],LINBUFSIZ); /* Copy current entry */
- if (lookup(netcmd,nh_p2[i],nnets,&x) > -1) { /* Net type */
- int xx;
- xx = netcmd[x].kwval;
- /* User specified SSH so don't let net directory override */
- if (net != NET_SSH || xx != NET_TCPB) {
- net = xx;
- mdmtyp = 0 - net;
- }
- } else {
- makestr(&slmsg,"Network type not supported");
- if (msg)
- printf("Error - network type \"%s\" not supported\n",
- nh_p2[i]
- );
- continue;
- }
- switch (net) { /* Net-specific directory things */
-#ifdef SSHBUILTIN
- case NET_SSH: /* SSH */
- /* Any SSH specific network directory stuff? */
- break; /* NET_SSH */
-#endif /* SSHBUILTIN */
-
- case NET_TCPB: { /* TCP/IP TELNET,RLOGIN,... */
-#ifdef TCPSOCKET
- char *q;
- int flag = 0;
-
- /* Extract ":service", if any, from host string */
- debug(F110,"cx_net service 1",line,0);
- for (q = line; (*q != '\0') && (*q != ':'); q++)
- ;
- if (*q == ':') { *q++ = NUL; flag = 1; }
- debug(F111,"cx_net service 2",line,flag);
-
- /* Get service, if any, from directory entry */
-
- if (!*srvbuf) {
- if (nh_px[0][i]) {
- ckstrncpy(srvbuf,nh_px[0][i],SRVBUFSIZ);
- debug(F110,"cx_net service 3",srvbuf,0);
- }
- if (flag) {
- ckstrncpy(srvbuf,q,SRVBUFSIZ);
- debug(F110,"cx_net service 4",srvbuf,0);
- }
- }
- ckstrncpy(hostname,line,HOSTNAMLEN);
-
- /* If we have a service, append to host name/address */
- if (*srvbuf) {
- ckstrncat(line, ":", LINBUFSIZ);
- ckstrncat(line, srvbuf, LINBUFSIZ);
- debug(F110,"cx_net service 5",line,0);
- }
-#ifdef RLOGCODE
- /* If no service given but command was RLOGIN */
- else if (ttnproto == NP_RLOGIN) { /* add this... */
- ckstrncat(line, ":login",LINBUFSIZ);
- debug(F110,"cx_net service 6",line,0);
- }
-#ifdef CK_AUTHENTICATION
-#ifdef CK_KERBEROS
- else if (ttnproto == NP_K4LOGIN ||
- ttnproto == NP_K5LOGIN) { /* add this... */
- ckstrncat(line, ":klogin",LINBUFSIZ);
- debug(F110,"cx_net service 7",line,0);
- }
- else if (ttnproto == NP_EK4LOGIN ||
- ttnproto == NP_EK5LOGIN) { /* add this... */
- ckstrncat(line, ":eklogin",LINBUFSIZ);
- debug(F110,"cx_net service 8",line,0);
- }
-#endif /* CK_KERBEROS */
-#endif /* CK_AUTHENTICATION */
-#endif /* RLOGCODE */
- else { /* Otherwise, add ":telnet". */
- ckstrncat(line, ":telnet", LINBUFSIZ);
- debug(F110,"cx_net service 9",line,0);
- }
- if (username) { /* This is a parameter... */
- ckstrncpy(uidbuf,username,UIDBUFLEN);
- uidflag = 1;
- }
- /* Fifth field, if any, is user ID (for rlogin) */
-
- if (nh_px[1][i] && !uidflag)
- ckstrncpy(uidbuf,username,UIDBUFLEN);
-#ifdef RLOGCODE
- if (IS_RLOGIN() && !uidbuf[0])
- return(cx_fail(msg,"Username required"));
-#endif /* RLOGCODE */
-#endif /* TCPSOCKET */
- break;
- }
- case NET_PIPE: /* Pipe */
-#ifdef NPIPE
- if (!pipename[0]) { /* User didn't give a pipename */
- if (nh_px[0][i]) { /* But directory entry has one */
- if (strcmp(pipename,"\\pipe\\")) {
- ckstrncpy(pipename,"\\pipe\\",LINBUFSIZ);
- ckstrncat(srvbuf,nh_px[0][i],PIPENAML-6);
- } else {
- ckstrncpy(pipename,nh_px[0][i],PIPENAML);
- }
- debug(F110,"cx_net pipeneme",pipename,0);
- }
- }
-#endif /* NPIPE */
- break;
-
- case NET_SLAT: /* LAT / CTERM */
-#ifdef SUPERLAT
- if (!slat_pwd[0]) { /* User didn't give a password */
- if (nh_px[0][i]) { /* But directory entry has one */
- ckstrncpy(slat_pwd,nh_px[0][i],18);
- debug(F110,"cx_net SuperLAT password",slat_pwd,0);
- }
- }
-#endif /* SUPERLAT */
- break;
-
- case NET_SX25: /* X.25 keyword parameters */
- case NET_IX25:
- case NET_VX25: {
-#ifdef ANYX25
- int k; /* Cycle through the four fields */
- for (k = 0; k < 4; k++) {
- if (!nh_px[k][i]) /* Bail out if none left */
- break;
- if (!ckstrcmp(nh_px[k][i],"cug=",4,0)) {
- closgr = atoi(nh_px[k][i]+4);
- debug(F101,"X25 CUG","",closgr);
- } else if (!ckstrcmp(nh_px[k][i],"cud=",4,0)) {
- cudata = 1;
- ckstrncpy(udata,nh_px[k][i]+4,MAXCUDATA);
- debug(F110,"X25 CUD",cudata,0);
- } else if (!ckstrcmp(nh_px[k][i],"rev=",4,0)) {
- revcall = !ckstrcmp(nh_px[k][i]+4,"=on",3,0);
- debug(F101,"X25 REV","",revcall);
-#ifndef IBMX25
- } else if (!ckstrcmp(nh_px[k][i],"pad=",4,0)) {
- int x3par, x3val;
- char *s1, *s2;
- s1 = s2 = nh_px[k][i]+4; /* PAD parameters */
- while (*s2) { /* Pick them apart */
- if (*s2 == ':') {
- *s2 = NUL;
- x3par = atoi(s1);
- s1 = ++s2;
- continue;
- } else if (*s2 == ',') {
- *s2 = NUL;
- x3val = atoi(s1);
- s1 = ++s2;
- debug(F111,"X25 PAD",x3par,x3val);
- if (x3par > -1 &&
- x3par <= MAXPADPARMS)
- padparms[x3par] = x3val;
- continue;
- } else
- s2++;
- }
-#endif /* IBMX25 */
- }
- }
-#endif /* ANYX25 */
- break;
- }
- default: /* Nothing special for other nets */
- break;
- }
- } else
-#endif /* NODIAL */
- { /* No directory entries found. */
- ckstrncpy(line,hostname,LINBUFSIZ); /* Put this back... */
- /* If the user gave a TCP service */
- if (net == NET_TCPB || net == NET_SSH)
- if (*srvbuf) { /* Append it to host name/address */
- ckstrncat(line, ":", LINBUFSIZ);
- ckstrncat(line, srvbuf,LINBUFSIZ);
- }
- }
- /*
- Get here with host name/address and all net-specific
- parameters set, ready to open the connection.
- */
- mdmtyp = -net; /* This should have been done */
- /* already but just in case ... */
-
- debug(F110,"cx_net net line[] before ttopen",line,0);
- debug(F101,"cx_net net mdmtyp before ttopen","",mdmtyp);
- debug(F101,"cx_net net ttnproto","",ttnproto);
-
-#ifdef SSHBUILTIN
- if (net == NET_SSH) {
- makestr(&ssh_hst,hostname); /* Stash everything */
- if (username) {
- if (!sl_uid_saved) {
- ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
- sl_uid_saved = 1;
- }
- ckstrncpy(uidbuf,username,UIDBUFLEN);
- }
- if (srvbuf[0]) {
- makestr(&ssh_prt,srvbuf);
- } else
- makestr(&ssh_prt,NULL);
-
- if (command) {
- makestr(&ssh_cmd,brstrip(command));
- ssh_cas = param2;
- } else
- makestr(&ssh_cmd,NULL);
-
- if (param1 > -1) {
-#ifndef SSHTEST
- if (!sl_ssh_ver_saved) {
- sl_ssh_ver = ssh_ver;
- sl_ssh_ver_saved = 1;
- }
-#endif /* SSHTEST */
- ssh_ver = param1;
- }
- if (param3 > -1) {
-#ifndef SSHTEST
- if (!sl_ssh_xfw_saved) {
- sl_ssh_xfw = ssh_xfw;
- sl_ssh_xfw_saved = 1;
- }
-#endif /* SSHTEST */
- ssh_xfw = param3;
- }
- } else /* NET_SSH */
-#endif /* SSHBUILTIN */
-#ifdef TCPSOCKET
- if (net == NET_TCPB) {
- switch (protocol) {
-#ifdef CK_SSL
-#ifdef COMMENT
-/*
- Jeff's version from 30 Dec 2006 - doesn't work - SSL/TLS_RAW still
- start Telnet negotions if a 0xff byte comes in.
-*/
- case NP_SSL_RAW:
- ttnproto = NP_SSL_RAW;
- debug(F101,"NP_SSL_RAW ttnproto","",ttnproto);
- ssl_only_flag = 1;
- tls_only_flag = 0;
- break;
-
- case NP_TLS_RAW:
- ttnproto = NP_TLS_RAW;
- debug(F101,"NP_TLS_RAW ttnproto","",ttnproto);
- ssl_only_flag = 0;
- tls_only_flag = 1;
- break;
-
- case NP_SSL:
- ttnproto = NP_SSL;
- debug(F101,"NP_SSL ttnproto","",ttnproto);
- ssl_only_flag = 1;
- tls_only_flag = 0;
- break;
-
- case NP_TLS:
- ttnproto = NP_TLS;
- debug(F101,"NP_TLS ttnproto","",ttnproto);
- ssl_only_flag = 0;
- tls_only_flag = 1;
- break;
-
- case NP_SSL_TELNET:
- ttnproto = NP_TELNET;
- debug(F101,"NP_SSL_TELNET ttnproto","",ttnproto);
- ssl_only_flag = 1;
- tls_only_flag = 0;
- break;
-
- case NP_TLS_TELNET:
- ttnproto = NP_TELNET;
- debug(F101,"NP_TLS_TELNET ttnproto","",ttnproto);
- ssl_only_flag = 0;
- tls_only_flag = 1;
- break;
-#else
-/* fdc version of 4 Dec 2006 works OK */
- case NP_SSL_RAW:
- case NP_SSL:
- ssl_raw_flag = (protocol == NP_SSL_RAW) ? 1 : 0;
- ttnproto = protocol;
- debug(F101,protocol==NP_SSL ?
- "NP_SSL ttnproto" :
- "NP_SSL_RAW ttnproto",
- "",ttnproto);
- ssl_only_flag = 1;
- tls_only_flag = 0;
- break;
-
- case NP_TLS:
- case NP_TLS_RAW:
- tls_raw_flag = (protocol == NP_SSL_RAW) ? 1 : 0;
- ttnproto = protocol;
- debug(F101,protocol==NP_TLS ?
- "NP_TLS ttnproto" :
- "NP_TLS_RAW ttnproto",
- "",ttnproto);
- ssl_only_flag = 0;
- tls_only_flag = 1;
- break;
-
- case NP_SSL_TELNET:
- ssl_raw_flag = 0;
- ttnproto = NP_TELNET;
- debug(F101,"NP_SSL_TELNET ttnproto","",ttnproto);
- ssl_only_flag = 1;
- tls_only_flag = 0;
- break;
-
- case NP_TLS_TELNET:
- tls_raw_flag = 0;
- ttnproto = NP_TELNET;
- debug(F101,"NP_TLS_TELNET ttnproto","",ttnproto);
- ssl_only_flag = 0;
- tls_only_flag = 1;
- break;
-#endif /* COMMENT */
-#endif /* CK_SSL */
-
- case NP_NONE:
- case NP_TCPRAW:
- case NP_RLOGIN:
- case NP_K4LOGIN:
- case NP_K5LOGIN:
- case NP_EK4LOGIN:
- case NP_EK5LOGIN:
- case NP_TELNET:
- case NP_KERMIT:
- default:
- ttnproto = protocol;
-#ifdef CK_SSL
-#ifdef COMMENT
- /* Jeff version from 30 Dec 2006 */
- ssl_only_flag = 0;
- tls_only_flag = 0;
-#else
- /* fdc version from 4 Dec 2006 */
- ssl_raw_flag = 0;
- tls_raw_flag = 0;
- ssl_only_flag = 0;
- tls_only_flag = 0;
-#endif /* COMMENT */
-#endif /* CK_SSL */
- break;
- }
-#ifdef CK_AUTHENTICATION
- if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
- param1 > -1) {
- if (!sl_auth_saved) {
- int x;
- for (x = 0; x < AUTHTYPLSTSZ; x++)
- sl_auth_type_user[x] = auth_type_user[x];
- sl_auth_saved = 1;
- }
- if (!sl_topt_a_s_saved) {
- sl_topt_a_su = TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION);
- sl_topt_a_s_saved = 1;
- }
- if (!sl_topt_a_c_saved) {
- sl_topt_a_cm = TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION);
- sl_topt_a_c_saved = 1;
- }
- switch (param1) {
- case AUTHTYPE_AUTO:
- auth_type_user[0] = AUTHTYPE_AUTO;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
- break;
- case AUTHTYPE_NULL:
- auth_type_user[0] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
- break;
-#ifdef CK_SRP
- case AUTHTYPE_SRP:
- auth_type_user[0] = AUTHTYPE_SRP;
- auth_type_user[1] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
-#endif /* CK_SRP */
-#ifdef CK_SSL
- case AUTHTYPE_SSL:
- auth_type_user[0] = AUTHTYPE_SSL;
- auth_type_user[1] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
-#endif /* CK_SSL */
-#ifdef NT
- case AUTHTYPE_NTLM:
- auth_type_user[0] = AUTHTYPE_NTLM;
- auth_type_user[1] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
-#endif /* NT */
-#ifdef CK_KERBEROS
- case AUTHTYPE_KERBEROS_V4:
- auth_type_user[0] = AUTHTYPE_KERBEROS_V4;
- auth_type_user[1] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
-
- case AUTHTYPE_KERBEROS_V5:
- auth_type_user[0] = AUTHTYPE_KERBEROS_V5;
- auth_type_user[1] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
-#endif /* CK_KERBEROS */
- }
- }
- /*
- If the user requires a particular type of Kerberos connection,
- make sure we have a valid TGT.
- */
- makestr(&slmsg,"Authentication failure");
- if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
- (line[0] == '*' &&
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU ||
- line[0] != '*' &&
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU)
- ) {
-#ifdef CK_KERBEROS
- if ( auth_type_user[0] == AUTHTYPE_KERBEROS_V4 ) {
- extern int krb4_autoget;
- if (!ck_krb4_is_installed())
- return(cx_fail(msg,
- "Required authentication method (Kerberos 4) is not installed"));
-#ifdef COMMENT
- /* This code results in false failures when using */
- /* kerberos to machines in realms other than the */
- /* default since we don't know the realm of the */
- /* other machine until perform the reverse DNS */
- /* lookup. */
- else if (line[0] != '*' && !ck_krb4_is_tgt_valid() &&
- (!krb4_autoget ||
- krb4_autoget && !ck_krb4_autoget_TGT(NULL))) {
- return(cx_fail(msg,
- "Kerberos 4: Ticket Getting Ticket not valid"));
- }
-#endif /* COMMENT */
- } else if (auth_type_user[0] == AUTHTYPE_KERBEROS_V5) {
- extern int krb5_autoget;
- if (!ck_krb5_is_installed()) {
- return(cx_fail(msg,
- "Required authentication method (Kerberos 5) is not installed"));
- }
-#ifdef COMMENT
- /* This code results in false failures when using */
- /* kerberos to machines in realms other than the */
- /* default since we don't know the realm of the */
- /* other machine until perform the reverse DNS */
- /* lookup. */
- else if (line[0] != '*' && !ck_krb5_is_tgt_valid() &&
- (!krb5_autoget ||
- krb5_autoget && !ck_krb5_autoget_TGT(NULL))) {
- return(cx_fail(msg,
- "Kerberos 5: Ticket Getting Ticket not valid."));
- }
-#endif /* COMMENT */
- }
-#endif /* CK_KERBEROS */
-#ifdef NT
- if (auth_type_user[0] == AUTHTYPE_NTLM) {
- if (!ck_ntlm_is_installed()) {
- return(cx_fail(msg,
- "Required authentication method (NTLM) is not installed"));
- } else if (line[0] != '*' && !ck_ntlm_is_valid(0)) {
- return(cx_fail(msg,"NTLM: Credentials are unavailable."));
- }
- }
-#endif /* NT */
-#ifdef CK_SSL
- if (auth_type_user[0] == AUTHTYPE_SSL) {
- if (!ck_ssleay_is_installed()) {
- return(cx_fail(msg,
- "Required authentication method (SSL) is not installed"));
- }
- }
-#endif /* CK_SSL */
-#ifdef CK_SRP
- if (auth_type_user[0] == AUTHTYPE_SRP) {
- if (!ck_srp_is_installed()) {
- return(cx_fail(msg,
- "Required authentication method (SRP) is not installed"));
- }
- }
-#endif /* CK_SRP */
- }
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
- if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
- param2 > -1) {
- if (!sl_cx_saved) {
- sl_cx_type = cx_type;
- sl_cx_saved = 1;
- }
- if (!sl_topt_e_s_saved) {
- sl_topt_e_su = TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION);
- sl_topt_e_sm = TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION);
- sl_topt_e_s_saved = 1;
- }
- if (!sl_topt_e_c_saved) {
- sl_topt_e_cu = TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION);
- sl_topt_e_cm = TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION);
- sl_topt_e_c_saved = 1;
- }
- cx_type = param2;
- if (cx_type == CX_AUTO) {
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- } else if (cx_type == CX_NONE) {
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- } else {
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
- }
- if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN ||
- (ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
- ((line[0] == '*' &&
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU) ||
- (line[0] != '*' &&
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU))
- ) {
- if (!ck_crypt_is_installed()) {
- return(cx_fail(msg,
- "Required Encryption methods are not installed"));
- }
- }
-#endif /* CK_ENCRYPTION */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
-#ifdef KRB4
- if (ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN) {
- extern int krb4_autoget;
- char tgt[256];
- char * realm;
-
- /* We don't have the full hostname at yet so */
- /* we do a DNS lookup before calling ttopen() */
-
- realm = ck_krb4_realmofhost(ckgetfqhostname(hostname));
- ckmakmsg(tgt,256,"krbtgt.",realm,"@",realm);
- if (!ck_krb4_is_installed()) {
- return(cx_fail(msg,
- "Required authentication method (Kerberos 4) is not installed"
- ));
- } else {
- if ((ck_krb4_tkt_isvalid(tgt) <= 0) &&
- (!krb4_autoget ||
- krb4_autoget && !ck_krb4_autoget_TGT(realm))) {
- return(cx_fail(msg,
- "Kerberos 4: Ticket Getting Ticket not valid"));
- }
- }
- }
-#endif /* KRB4 */
-#ifdef KRB5
- if (ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN ||
- ttnproto == NP_K5U2U)
- {
- extern int krb5_autoget;
- char tgt[256];
- char * realm;
-
- /* Must get full hostname before calling ttopen() */
-
- realm = ck_krb5_realmofhost(ckgetfqhostname(hostname));
- ckmakmsg(tgt,256,"krbtgt/",realm,"@",realm);
-
- if (!ck_krb5_is_installed()) {
- return(cx_fail(msg,
- "Required authentication method (Kerberos 5) not installed"));
- } else if (!((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
- ck_krb5_is_tgt_valid()) &&
- (!krb5_autoget ||
- krb5_autoget && !ck_krb5_autoget_TGT(realm))) {
- return(cx_fail(msg,
- "Kerberos 5: Ticket Getting Ticket not valid."));
- }
- }
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
-
-#ifndef NOSPL
-#ifdef RLOGCODE
- if (username) {
- if (!sl_uid_saved) {
- ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
- sl_uid_saved = 1;
- }
- ckstrncpy(uidbuf,username,UIDBUFLEN);
- uidflag = 1;
- }
-#endif /* RLOGCODE */
-#ifdef TNCODE
- if (!sl_tn_saved) {
- sl_tn_wait = tn_wait_flg;
- sl_tn_saved = 1;
- }
- tn_wait_flg = param3;
-#endif /* TNCODE */
-#endif /* NOSPL */
- } /* if (net == NET_TCPB) */
-#endif /* TCPSOCKET */
-
-#ifndef NOSPL
-#ifdef CK_SECURITY
- if (password) {
- if (password[0]) {
- ckstrncpy(pwbuf,password,PWBUFL+1);
- pwflg = 1;
- pwcrypt = 0;
- } else
- pwflg = 0;
- }
-#endif /* CK_SECURITY */
-#endif /* NOSPL */
-
- /* Try to open - network */
- ckstrncpy(ttname,line,TTNAMLEN);
- y = ttopen(line, &_local, mdmtyp, 0 );
-
-#ifndef NOHTTP
- /* If the connection failed and we are using an HTTP Proxy
- * and the reason for the failure was an authentication
- * error, then we need to give the user to ability to
- * enter a username and password, just like a browser.
- *
- * I tried to do all of this within the netopen() call
- * but it is much too much work.
- */
- while (y < 0 && tcp_http_proxy != NULL ) {
-
- if (tcp_http_proxy_errno == 401 ||
- tcp_http_proxy_errno == 407 ) {
- char uid[UIDBUFLEN];
- char pwd[256];
- struct txtbox tb[2];
- int ok;
-
- tb[0].t_buf = uid;
- tb[0].t_len = UIDBUFLEN;
- tb[0].t_lbl = "Proxy Userid: ";
- tb[0].t_dflt = NULL;
- tb[0].t_echo = 1;
- tb[1].t_buf = pwd;
- tb[1].t_len = 256;
- tb[1].t_lbl = "Proxy Passphrase: ";
- tb[1].t_dflt = NULL;
- tb[1].t_echo = 2;
-
- ok = uq_mtxt("Proxy Server Authentication Required\n",
- NULL, 2, tb);
-
- if (ok && uid[0]) {
- char * proxy_user, * proxy_pwd;
-
- proxy_user = tcp_http_proxy_user;
- proxy_pwd = tcp_http_proxy_pwd;
-
- tcp_http_proxy_user = uid;
- tcp_http_proxy_pwd = pwd;
-
- ckstrncpy(ttname,line,TTNAMLEN);
- y = ttopen(line, &_local, mdmtyp, 0);
- memset(pwd,0,sizeof(pwd));
- tcp_http_proxy_user = proxy_user;
- tcp_http_proxy_pwd = proxy_pwd;
- } else
- break;
- } else
- break;
- }
-#endif /* NOHTTP */
- if (y < 0) {
- slrestor();
- makestr(&slmsg,"Network connection failure");
-#ifdef VMS
- if (msg && hints && !xcmdsrc && IS_RLOGIN()) {
- makestr(&slmsg,"RLOGIN failure");
- if (socket_errno == EACCES) {
- printf("*************************\n");
- printf(
- "Hint: RLOGIN requires privileges to open an outbound port.\n");
- printf(
- "(Use SET HINTS OFF to suppress future hints.)\n");
- printf("*************************\n");
- }
- }
-#else /* Not VMS... */
- if (errno) {
- int x;
- debug(F111,"set host line, errno","",errno);
- makestr(&slmsg,ck_errstr());
- if (msg) {
-#ifdef OS2
- printf("Can't connect to %s\n",line);
-#else /* OS2 */
-#ifdef UNIX
- if (hints && !xcmdsrc && IS_RLOGIN()) {
- makestr(&slmsg,"RLOGIN failure");
- printf("*************************\n");
- printf(
- "Hint: RLOGIN requires privileges to open an outbound port.\n");
- printf(
- "(Use SET HINTS OFF to suppress future hints.)\n");
- printf("*************************\n");
- }
-#endif /* UNIX */
-#endif /* OS2 */
- } else printf("Can't connect to %s\n",line);
- } else
-#endif /* VMS */
- if (msg) printf("Can't open connection to %s\n",line);
- continue;
- } else {
- success = 1;
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#endif /* NODIAL */
- switch (net) {
- case NET_TCPA:
- case NET_TCPB:
- cxtype = CXT_TCPIP;
-#ifdef COMMENT
-/* This works but it messes up interactive anonymous login */
-#ifndef NOXFER
-#ifdef IKS_OPTION
- /* If we have connected to an Internet Kermit service */
- /* and a /USER: switch was given, then log in. */
-
- if (TELOPT_U(TELOPT_KERMIT) || TELOPT_ME(TELOPT_KERMIT)) {
- debug(F111,"cx_net IKSD /USER:",uidbuf,haveuser);
- if (haveuser /* && cx == 0 */ ) { /* /USER: given */
- char * psw = pwbuf; /* Do we have a password? */
- if (!*psw) { /* No... */
- if (!strcmp(uidbuf,"anonymous") ||
- !strcmp(uidbuf,"ftp")) {
- extern char myhost[];
- char * u = (char *)sl_uidbuf;
- char * h = (char *)myhost;
- if (!*u) u = "nobody";
- if (!*h) h = "nowhere";
- ckmakmsg(tmpbuf,TMPBUFSIZ,u,"@",h,NULL);
- psw = tmpbuf;
- debug(F110,"cx_net IKSD anon",psw,0);
- } else {
- readpass(" Password: ",pwbuf,PWBUFL);
- }
- }
- sstate = setgen('I',uidbuf,psw,"");
- }
- }
-#endif /* IKS_OPTION */
-#endif /* NOXFER */
-#endif /* COMMENT */
- break;
- case NET_SSH:
- cxtype = CXT_SSH;
- duplex = 0; /* Remote echo */
- break;
- case NET_SLAT:
- cxtype = CXT_LAT;
- break;
- case NET_SX25:
- case NET_IX25:
- case NET_HX25:
- case NET_VX25:
- cxtype = CXT_X25;
- break;
- case NET_BIOS:
- cxtype = CXT_NETBIOS;
- break;
- case NET_FILE:
- case NET_PIPE:
- case NET_CMD:
- case NET_DLL:
- case NET_PTY:
- cxtype = CXT_PIPE;
- break;
- default:
- cxtype = CXT_PIPE;
- break;
- }
- break;
- }
- } /* for-loop */
- s = line;
-
- debug(F101,"cx_net post ttopen success","",success);
- if (!success) {
- local = dfloc; /* Go back to normal */
-#ifndef MAC
- ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty name */
-#endif /* MAC */
- speed = ttgspd();
- network = 0; /* No network connection active */
- haveline = 0;
- if (mdmtyp < 0) { /* Switching from net to async? */
- if (mdmsav > -1) /* Restore modem type from last */
- mdmtyp = mdmsav; /* SET MODEM command, if any. */
- else
- mdmtyp = 0;
- mdmsav = -1;
- }
- return(0); /* Return failure */
- }
- if (_local > -1) local = _local; /* Opened ok, set local/remote. */
- makestr(&slmsg,NULL);
- network = (mdmtyp < 0); /* Remember connection type. */
- ckstrncpy(ttname,s,TTNAMLEN); /* Copy name into real place. */
- debug(F110,"cx_net ok",ttname,0);
- debug(F101,"cx_net network","",network);
-#ifndef NOXFER
- if ((reliable != SET_OFF || !setreliable)) /* Assume not reliable. */
- reliable = SET_OFF;
-#endif /* NOXFER */
- if (!network || istncomport())
- speed = ttgspd(); /* Get the current speed. */
- debug(F101,"cx_net local","",local);
- if (network) {
- debug(F101,"cx_net net","",net);
-#ifndef NOXFER
- /* Force prefixing of 255 on TCP/IP connections... */
- if (net == NET_TCPB
-#ifdef SSHBUILTIN
- || net == NET_SSH
-#endif /* SSHBUILTIN */
- ) {
- debug(F101,"cx_net reliable A","",reliable);
-#ifdef CK_SPEED
- ctlp[(unsigned)255] = 1;
-#endif /* CK_SPEED */
- if ((reliable != SET_OFF || !setreliable)) {
-#ifdef TN_COMPORT
- if (istncomport()) { /* Telnet communication port */
- reliable = SET_OFF; /* Transport is not reliable */
- debug(F101,"cx_net reliable istncomport()","",1);
- } else {
- reliable = SET_ON; /* Transport is reliable end to end */
- debug(F101,"cx_net reliable istncomport()","",0);
- }
-#else
- reliable = SET_ON; /* Transport is reliable end to end */
-#endif /* ifdef TN_COMPORT */
- }
- debug(F101,"cx_net reliable B","",reliable);
- } else if (net == NET_SX25 ||
- net == NET_VX25 ||
- net == NET_IX25 ||
- net == NET_HX25) {
- duplex = 1; /* Local echo for X.25 */
- if (reliable != SET_OFF || !setreliable)
- reliable = SET_ON; /* Transport is reliable end to end */
- }
-#endif /* NOXFER */
- }
-#ifndef NOXFER
- debug(F101,"cx_net reliable","",reliable);
-#endif /* NOXFER */
-#ifdef OS2
- if (mdmtyp <= 0) /* Network or Direct Connection */
- DialerSend(OPT_KERMIT_CONNECT, 0);
-#endif /* OS2 */
-
- xcx_net:
-
- setflow(); /* Set appropriate flow control */
-
- haveline = 1;
-#ifdef CKLOGDIAL
- dolognet();
-#endif /* CKLOGDIAL */
-
-#ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ttname,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
-#endif /* NOSPL */
-
- if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
- if (cx) { /* /CONNECT */
- if (!gui) {
- /* Command was confirmed so we can pre-pop command level. */
- /* This is so CONNECT module won't think we're executing a */
- /* script if CONNECT was the final command in the script. */
- if (cmdlvl > 0)
- prepop();
- }
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#endif /* NODIAL */
-#ifdef LOCUS
- if (autolocus) {
- setlocus(1,1);
- }
-#endif /* LOCUS */
- success = doconect(0, cmdlvl == 0 ? 1 : 0);
- if (ttchk() < 0)
- dologend();
- debug(F101,"cx_net post doconect success","",success);
- return(success);
-#ifndef NOXFER
- } else if (sx) { /* /SERVER */
- sstate = 'x';
-#ifdef MAC
- what = W_RECV;
- scrcreate();
-#endif /* MAC */
- if (local) displa = 1;
-#ifdef AMIGA
- reqoff(); /* No DOS requestors while server */
-#endif /* AMIGA */
-#endif /* NOXFER */
- }
- }
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#endif /* NODIAL */
-#ifdef LOCUS
- if (autolocus) {
- setlocus(1,1);
- }
-#endif /* LOCUS */
- return(success = 1);
-}
-#endif /* NETCONN */
-
-/* c x _ s e r i a l -- Make a serial connection */
-
-/*
- Call with:
- device = string pointer to device name.
- cx = 1 to automatically enter Connect mode, 0 otherwise.
- sx = 1 to automatically enter Server mode, 0 otherwise.
- shr = 1 if device should be opened in shareable mode, 0 otherwise.
- flag = if no dev name given: 1 = close current connection, 0 = resume.
- gui = 1 if called from GUI dialog, 0 otherwise.
- Returns:
- 1 on success
- 0 on failure and no message printed, slmsg set to failure message.
- -9 on failure and message printed, ditto.
-*/
-
-/* these are bit flags */
-#define CX_TAPI 1
-#define CX_PPP 2
-#define CX_SLIP 4
-
-int
-#ifdef CK_ANSIC
-cx_serial(char *device,
- int cx, int sx, int shr, int flag, int gui, int special)
-#else /* CK_ANSIC */
-cx_serial(device, cx, sx, shr, flag, gui, special)
- char * device; int cx, sx, shr, flag, gui, special;
-#endif /* CK_ANSIC */
-/* cx_serial */ {
- int i, n, x, y, msg;
- int _local = -1;
- char *s;
-
- debug(F110,"cx_serial device",device,0);
- s = device;
- msg = (gui == 0) && msgflg; /* Whether to print messages */
- success = 0;
-
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#endif /* NODIAL */
- debug(F101,"cx_serial mdmtyp","",mdmtyp);
- if (clskconnx(1) < 0) /* Close the Kermit connection */
- return(success = 0);
- if (*s) { /* They gave a device name */
- _local = -1; /* Let ttopen decide about it */
- } else { /* They just said "set line" */
- s = dftty; /* so go back to normal tty */
- _local = dfloc; /* and mode. */
- }
-#ifdef VMS
- {
- extern int ok_to_share;
- ok_to_share = shr;
- }
-#endif /* VMS */
-
-#ifdef OS2 /* Must wait until after ttclos() */
-#ifdef NT /* to change these settings */
-#ifdef CK_TAPI
- tttapi = special & CX_TAPI;
-#endif /* CK_TAPI */
-#else
- ttslip = special & CX_SLIP;
- ttppp = special & CX_PPP;
-#endif /* NT */
- ttshare = shr; /* Shareable device ? */
- debug(F110,"OS2 SET PORT final s",s,"");
-#endif /* OS2 */
-
- /* Open the new line */
-
- ckstrncpy(ttname,s,TTNAMLEN);
- if ((y = ttopen(s,&_local,mdmtyp,cdtimo)) > -1) {
- cxtype = (mdmtyp > 0) ? CXT_MODEM : CXT_DIRECT;
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#ifdef CK_TAPI
- /* if the line is a tapi device, then we need to auto-execute */
- /* SET MODEM TYPE TAPI - which we do the equivalent of here. */
- if (tttapi) {
- extern int usermdm;
- usermdm = 0;
- initmdm(38); /* From ckudia.c n_TAPI == 38 */
- }
-#endif /* CK_TAPI */
-#endif /* NODIAL */
- success = 1;
- } else { /* Failed */
-#ifdef OS2ONLY
- if (!strcmp(s,dftty)) /* Do not generate an error with dftty */
- ;
- else if (y == -6 && ttslip) {
- makestr(&slmsg,"Can't access SLIP driver");
- if (msg) printf("?%s\n",slmsg);
- } else if (y == -6 && ttppp) {
- makestr(&slmsg,"Can't access PPP driver");
- if (msg) printf("?%s\n",slmsg);
- } else
-#endif /* OS2ONLY */
- if (y == -2) {
- makestr(&slmsg,"Timed out - no carrier");
- if (msg) {
- printf("?%s\n",slmsg);
- if (hints) {
- printf("\n*************************\n");
- printf(
- "HINT (Use SET HINTS OFF to suppress future hints):\n");
- printf(
- "Try SET CARRIER OFF and SET LINE again, or else\n");
- printf("SET MODEM, SET LINE, and then DIAL.\n");
- printf("*************************\n\n");
- }
- }
- } else if (y == -3) {
- makestr(&slmsg,"Access to lock denied");
- if (msg) {
-#ifdef UNIX
- printf(
- "Sorry, write access to UUCP lockfile directory denied.\n");
-#ifndef NOHINTS
- if (hints) {
- printf("\n*************************\n");
- printf(
- "HINT (Use SET HINTS OFF to suppress future hints):\n");
- printf(
- "Please read the installation instructions file, %sckuins.txt,\n",
- k_info_dir ? k_info_dir : ""
- );
- printf(
- "or the UNIX appendix of the manual, \"Using C-Kermit\"\n"
- );
- printf(
- "or visit http://www.columbia.edu/kermit/ckuins.html \n"
- );
- printf("*************************\n\n");
- }
-#endif /* NOHINTS */
-#else
- printf("Sorry, access to lock denied: %s\n",s);
-#endif /* UNIX */
- }
- } else if (y == -4) {
- makestr(&slmsg,"Access to device denied");
- if (msg) {
- printf("Sorry, access to device denied: %s\n",s);
-#ifdef UNIX
-#ifndef NOHINTS
- if (hints) {
- printf("\n*************************\n");
- printf(
- "HINT (Use SET HINTS OFF to suppress future hints):\n");
- printf(
- "Please read the installation instructions file, %sckuins.txt,\n",
- k_info_dir ? k_info_dir : ""
- );
- printf(
- "or the UNIX appendix of the manual, \"Using C-Kermit\".\n"
- );
- printf("*************************\n\n");
- }
-#endif /* NOHINTS */
-#endif /* UNIX */
- }
- } else if (y == -5) {
- makestr(&slmsg,"Device is in use or unavailable");
- if (msg)
-#ifdef VMS
- printf(
- "Sorry, device is in use or otherwise unavailable: %s\n",s);
-#else
- printf("Sorry, device is in use: %s\n",s);
-#endif /* VMS */
- } else { /* Other error. */
- makestr(&slmsg,"Device open failed");
- if (
-#ifdef VMS
- 1
-#else
- errno
-#endif /* VMS */
- ) {
- int x; /* Find a safe, long buffer */
- makestr(&slmsg,ck_errstr());
-#ifndef VMS
- debug(F111,"cx_serial serial errno",slmsg,errno);
-#endif /* VMS */
- if (msg)
- printf("Connection to %s failed: %s\n",s,slmsg);
- } else if (msg)
- printf("Sorry, can't open connection: %s\n",s);
- }
- }
- network = 0; /* No network connection active */
- speed = ttgspd();
- if (!success) {
- local = dfloc; /* Go back to normal */
-#ifndef MAC
- ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty name */
-#endif /* MAC */
- haveline = 0;
- if (mdmtyp < 0) { /* Switching from net to async? */
- if (mdmsav > -1) /* Restore modem type from last */
- mdmtyp = mdmsav; /* SET MODEM command, if any. */
- else
- mdmtyp = 0;
- mdmsav = -1;
- }
- return(msg ? -9 : 0); /* Return failure */
- }
- if (_local > -1)
- local = _local; /* Opened ok, set local/remote. */
- makestr(&slmsg,NULL); /* Erase SET LINE message */
- ckstrncpy(ttname,s,TTNAMLEN); /* Copy name into real place. */
- debug(F110,"cx_serial ok",ttname,0);
-#ifndef NOXFER
- if ((reliable != SET_OFF || !setreliable)) /* Assume not reliable. */
- reliable = SET_OFF;
-#endif /* NOXFER */
-
- xcx_serial:
- setflow(); /* Set appropriate flow control */
- haveline = 1;
-#ifdef CKLOGDIAL
- dologline();
-#endif /* CKLOGDIAL */
-
-#ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ttname,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
-#endif /* NOSPL */
-
- if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
- extern int carrier;
- if (carrier != CAR_OFF) { /* Looking for carrier? */
- /* Open() turns on DTR -- wait up to a second for CD to come up */
- int i, x;
- for (i = 0; i < 10; i++) { /* WAIT 1 CD... */
- x = ttgmdm();
- if (x < 0 || x & BM_DCD)
- break;
- msleep(100);
- }
- }
- if (cx) { /* /CONNECT */
- /* Command was confirmed so we can pre-pop command level. */
- /* This is so CONNECT module won't think we're executing a */
- /* script if CONNECT was the final command in the script. */
-
- if (cmdlvl > 0)
- prepop();
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#endif /* NODIAL */
-#ifdef LOCUS
- if (autolocus) {
- setlocus(1,1);
- }
-#endif /* LOCUS */
- success = doconect(0, cmdlvl == 0 ? 1 : 0);
- if (ttchk() < 0)
- dologend();
- return(success);
-#ifndef NOXFER
- } else if (sx) { /* /SERVER */
- sstate = 'x';
-#ifdef MAC
- what = W_RECV;
- scrcreate();
-#endif /* MAC */
- if (local) displa = 1;
-#ifdef AMIGA
- reqoff(); /* No DOS requestors while server */
-#endif /* AMIGA */
-#endif /* NOXFER */
- }
- }
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#endif /* NODIAL */
-#ifdef LOCUS
- if (autolocus) {
- setlocus(1,1);
- }
-#endif /* LOCUS */
- return(success = 1);
-}
-
-
-/* S E T L I N -- parse name of and then open communication device. */
-/*
- Call with:
- xx == XYLINE for a serial (tty) line, XYHOST for a network host,
- zz == 0 means if user doesn't give a device name, continue current
- active connection (if any);
- zz != 0 means if user doesn't give a device name, then close the
- current connection and restore the default communication device.
- fc == 0 to just make the connection, 1 to also CONNECT (e.g. "telnet").
-*/
-int
-setlin(xx, zz, fc)
- int xx, zz, fc;
-{
- extern char pwbuf[], * g_pswd;
- extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
- int wait;
- /* int tn_wait_sv; */
- int mynet;
- int _local = -1;
- int c, i, haveswitch = 0;
- int haveuser = 0;
- int getval = 0;
- int wild = 0; /* Filespec has wildcards */
- int cx = 0; /* Connect after */
- int sx = 0; /* Become server after */
- int a_type = -1; /* Authentication type */
- int e_type = -1; /* Telnet /ENCRYPT type */
-#ifdef CK_ENCRYPTION
- int encrypt = 0; /* Encrypted? */
-#endif /* CK_ENCRYPTION */
- int shr = 0; /* Share serial device */
- int confirmed = 0; /* Command has been entered */
- struct FDB sw, tx, nx;
-#ifdef OS2
- struct FDB fl;
-#endif /* OS2 */
-
- char * ss;
-#ifdef TCPSOCKET
- int rawflg = 0;
-#endif /* TCPSOCKET */
-
- char srvbuf[SRVBUFSIZ+1];
-
-#ifdef OS2
-#ifdef NT
- int xxtapi = 0;
-#else
- int xxslip = 0, xxppp = 0;
-#endif /* NT */
-#endif /* OS2 */
-
- int dossh = 0;
-
- debug(F101,"setlin fc","",fc);
- debug(F101,"setlin zz","",zz);
- debug(F101,"setlin xx","",xx);
-
-#ifdef SSHCMD
- if (xx == XXSSH) { /* SSH becomes PTY SSH ... */
- dossh = 1;
- xx = XYHOST;
- } else if (!ckstrcmp("ssh ",line,4,0)) { /* 2010/03/01 */
- dossh = 1;
- xx = XYHOST;
- }
- debug(F101,"setlin dossh","",dossh);
-#endif /* SSHCMD */
-
-#ifdef TNCODE
- /* tn_wait_sv = tn_wait_flg; */
- wait = tn_wait_flg;
-#else
- /* tn_wait_sv = 0; */
- wait = 0;
-#endif /* TNCODE */
-
- mynet = nettype;
-
- if (nolocal) {
- makestr(&slmsg,"Making connections is disabled");
- printf("?Sorry, making connections is disabled\n");
- return(-9);
- }
- if (netsave > -1)
- nettype = netsave;
-
- if (fc != 0 || zz == 0) /* Preset /CONNECT switch */
- cx = 1;
-
- debug(F101,"setlin cx","",cx);
-
- *srvbuf = NUL;
-
- line[0] = NUL;
- s = line;
-
-#ifdef NETCONN
-#ifdef CK_SECURITY
- if (tmpstring)
- makestr(&tmpstring,NULL);
-#endif /* CK_SECURITY */
- if (tmpusrid)
- makestr(&tmpusrid,NULL);
-#endif /* NETCONN */
-
- autoflow = 1; /* Enable automatic flow setting */
-
- if (xx == XYHOST) { /* SET HOST <hostname> */
-#ifndef NETCONN
- makestr(&slmsg,"Network connections not supported");
- printf("?%s\n",slmsg);
- return(-9);
-#else /* NETCONN */
-#ifndef NOPUSH
- if ((mynet == NET_CMD || mynet == NET_PTY || dossh) && nopush) {
- makestr(&slmsg,"Access to external commands is disabled");
- printf("?Sorry, access to external commands is disabled\n");
- return(-9);
- }
-#endif /* NOPUSH */
-
-#ifdef SSHCMD
- if (dossh) { /* SSH connection via pty */
- int k;
- extern int ttyfd; /* 2010/03/01 */
- k = ckstrncpy(line, sshcmd ? sshcmd : defsshcmd, LINBUFSIZ);
- debug(F111,"setlin sshcmd 1",line,k);
- if ((x = cmtxt("Optional switches and hostname","",&s,xxstring))<0)
- return(x);
-
- /* 2010-03-30 */
- if (!*s && ttyfd < 0 && !ckstrcmp("ssh ",ttname,4,0)) {
- x = ckstrncpy(line,ttname,LINBUFSIZ);
- } else {
- if (!*s) {
- printf("?SSH to where?\n");
- return(-9);
- }
- if (k < LINBUFSIZ) {
- line[k++] = SP;
- line[k] = NUL;
- debug(F111,"setlin sshcmd 2",line,k);
- } if (k < LINBUFSIZ) {
- ckstrncpy(&line[k],s,LINBUFSIZ-k);
- debug(F111,"setlin sshcmd 3",line,k);
- } else {
- printf("?Too long\n");
- return(-9);
- }
- }
- x = cx_net( NET_PTY, /* network type */
- 0, /* protocol (not used) */
- line, /* host */
- NULL, /* service (not used) */
- NULL, /* username (not used) */
- NULL, /* password (not used) */
- NULL, /* command (not used) */
- -1,-1,-1, /* params 1-3 (not used) */
- 1, /* connect immediately */
- sx, /* server? */
- zz, /* close current? */
- 0); /* not gui */
- debug(F111,"setlin cx_net",line,x);
- return(x);
- }
-#endif /* SSHCMD */
-
-/*
- Here we parse optional switches and then the hostname or whatever,
- which depends on the network type. The tricky part is, the network type
- can be set by a switch.
-*/
-#ifndef NOSPL
- makestr(&g_pswd,pwbuf); /* Save global pwbuf */
- g_pflg = pwflg; /* and flag */
- g_pcpt = pwcrypt;
-#endif /* NOSPL */
-
- confirmed = 0;
- haveswitch = 0;
-#ifdef NETFILE
- if (mynet != NET_FILE) {
-#endif /* NETFILE */
- ss = (mynet == NET_CMD || mynet == NET_PTY) ?
- "Command, or switch" :
- (mynet == NET_TCPA || mynet == NET_TCPB
- || mynet == NET_SSH) ?
- "Hostname, ip-address, or switch" :
- "Host or switch";
- if (fc) {
- if (mynet == NET_TCPB &&
- (ttnproto == NP_TELNET || ttnproto == NP_KERMIT)) {
- if (nshteltab) {
- haveswitch++;
- cmfdbi(&sw,_CMKEY,ss,"","",nshteltab,4,xxstring,
- shteltab,&nx);
- }
- }
-#ifdef RLOGCODE
- else if (mynet == NET_TCPB && ttnproto == NP_RLOGIN) {
- if (nshrlgtab) {
- haveswitch++;
- cmfdbi(&sw,_CMKEY,ss,"","",nshrlgtab,4,xxstring,
- shrlgtab,&nx);
- }
- }
-#endif /* RLOGCODE */
- } else {
- haveswitch++;
- cmfdbi(&sw,_CMKEY,ss,"","",nshtab,4,xxstring,shtab,&nx);
- }
-#ifdef NETFILE
- }
-#endif /* NETFILE */
- if (mynet == NET_TCPB || mynet == NET_SLAT ||
- mynet == NET_SSH || mynet == NET_DEC) {
- cmfdbi(&nx,_CMFLD,"Host","","",0,0,xxstring,NULL,NULL);
-#ifdef NETFILE
- } else if (mynet == NET_FILE) {
- cmfdbi(&nx,_CMIFI,"Filename","","",0,0,xxstring,NULL,NULL);
-#endif /* NETFILE */
-#ifdef PTYORPIPE
- } else if (mynet == NET_CMD || mynet == NET_PTY) {
- cmfdbi(&nx,_CMTXT,"Command","","",0,0,xxstring,NULL,NULL);
-#endif /* PTYORPIPE */
- } else {
- cmfdbi(&nx,_CMTXT,"Host","","",0,0,xxstring,NULL,NULL);
- }
- while (1) {
- x = cmfdb(haveswitch ? &sw : &nx);
- debug(F101,"setlin cmfdb","",x);
- if (x < 0)
- if (x != -3)
- return(x);
- if (x == -3) {
- if ((x = cmcfm()) < 0) {
- return(x);
- } else {
- confirmed = 1;
- break;
- }
- }
- if (cmresult.fcode != _CMKEY) { /* Not a switch */
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Save the data */
- s = line; /* that was parsed... */
- if (cmresult.fcode == _CMIFI) {
- wild = cmresult.nresult;
- } else if (cmresult.fcode == _CMTXT) {
- confirmed = 1;
- }
- break; /* and break out of this loop */
- }
- c = cmgbrk(); /* Have switch - get break character */
- getval = (c == ':' || c == '='); /* Must parse an agument? */
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- return(-9);
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (cmresult.nresult) { /* It's a switch.. */
- case SL_CNX: /* /CONNECT */
- cx = 1;
- sx = 0;
- break;
- case SL_SRV: /* /SERVER */
- cx = 0;
- sx = 1;
- break;
-#ifdef NETCMD
- case SL_CMD: /* /COMMAND */
- netsave = mynet;
- mynet = NET_CMD;
- break;
-#endif /* NETCMD */
-#ifdef NETPTY
- case SL_PTY: /* /PTY */
- netsave = mynet;
- mynet = NET_PTY;
- break;
-#endif /* NETPTY */
- case SL_NET: /* /NETWORK-TYPE */
- if ((x = cmkey(netcmd,nnets,"","",xxstring)) < 0)
- return(x);
- mynet = x;
- break;
-
-#ifdef CK_SECURITY
- case SL_PSW: /* /PASSWORD: */
- if (!getval)
- break;
- debok = 0;
- if ((x = cmfld("Password","",&s,xxstring)) < 0) {
- if (x == -3) {
- makestr(&tmpstring,"");
- } else {
- return(x);
- }
- } else {
- s = brstrip(s);
- if ((x = (int)strlen(s)) > PWBUFL) {
- makestr(&slmsg,"Internal error");
- printf("?Sorry, too long - max = %d\n",PWBUFL);
- return(-9);
- }
- makestr(&tmpstring,s);
- }
- break;
-#endif /* CK_SECURITY */
-
- case SL_UID: /* /USERID: */
- if (!getval)
- break;
- if ((x = cmfld("Userid","",&s,xxstring)) < 0) {
- if (x == -3) {
- makestr(&tmpusrid,"");
- } else {
- return(x);
- }
- } else {
- s = brstrip(s);
- if ((x = (int)strlen(s)) > 63) {
- makestr(&slmsg,"Internal error");
- printf("?Sorry, too long - max = %d\n",63);
- return(-9);
- }
- makestr(&tmpusrid,s);
- haveuser = 1;
- }
- break;
-
-#ifdef CK_AUTHENTICATION
-#ifdef CK_SRP
- case SL_SRP:
- a_type = AUTHTYPE_SRP;
- break;
-#endif /* CK_SRP */
-#ifdef CK_SSL
- case SL_SSL:
- a_type = AUTHTYPE_SSL;
- break;
-#endif /* CK_SSL */
-#ifdef NT
- case SL_NTLM:
- a_type = AUTHTYPE_NTLM;
- break;
-#endif /* NT */
-#ifdef CK_KERBEROS
- case SL_KRB4:
- a_type = AUTHTYPE_KERBEROS_V4;
- if (ttnproto == NP_RLOGIN)
- ttnproto =
-#ifdef CK_ENCRYPTION
- encrypt ? NP_EK4LOGIN :
-#endif /* CK_ENCRYPTION */
- NP_K4LOGIN;
- else if (ttnproto == NP_K5LOGIN)
- ttnproto = NP_K4LOGIN;
-#ifdef CK_ENCRYPTION
- else if (ttnproto == NP_EK5LOGIN)
- ttnproto = NP_EK4LOGIN;
-#endif /* CK_ENCRYPTION */
- break;
- case SL_KRB5:
- a_type = AUTHTYPE_KERBEROS_V5;
- if (ttnproto == NP_RLOGIN)
- ttnproto =
-#ifdef CK_ENCRYPTION
- encrypt ? NP_EK5LOGIN :
-#endif /* CK_ENCRYPTION */
- NP_K5LOGIN;
- else if (ttnproto == NP_K4LOGIN)
- ttnproto = NP_K5LOGIN;
-#ifdef CK_ENCRYPTION
- else if (ttnproto == NP_EK4LOGIN)
- ttnproto = NP_EK5LOGIN;
-#endif /* CK_ENCRYPTION */
- break;
-#endif /* CK_KERBEROS */
- case SL_AUTH: {
- extern struct keytab autyptab[];
- extern int nautyp;
- if ((x = cmkey(autyptab,nautyp,"type of authentication",
- "automatic",xxstring)) < 0)
- return(x);
- a_type = x;
- break;
- }
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
- case SL_ENC:
- switch (ttnproto) {
- case NP_K4LOGIN:
- ttnproto = NP_EK4LOGIN;
- encrypt = 1;
- break;
- case NP_K5LOGIN:
- ttnproto = NP_EK5LOGIN;
- encrypt = 1;
- break;
- case NP_KERMIT:
- case NP_TELNET: {
- static struct keytab * tnetbl = NULL;
- static int ntnetbl = 0;
- x = ck_get_crypt_table(&tnetbl,&ntnetbl);
- debug(F101,"ck_get_crypt_table x","",x);
- debug(F101,"ck_get_crypt_table n","",ntnetbl);
- if (x < 1 || !tnetbl || ntnetbl < 1) /* Didn't get it */
- x = 0;
- if (!x) {
- makestr(&slmsg,"Internal error");
- printf("?Oops, types not loaded\n");
- return(-9);
- }
- if ((x = cmkey(tnetbl,ntnetbl,"type of encryption",
- "automatic",xxstring)) < 0)
- return(x);
- e_type = x;
- break;
- }
- }
- break;
-#endif /* CK_ENCRYPTION */
- case SL_WAIT:
- wait = 1;
- break;
- case SL_NOWAIT:
- wait = 0;
- break;
- }
- }
-
-#ifdef NETFILE
- if (mynet == NET_FILE) { /* Parsed by cmifi() */
- if ((x = cmcfm()) < 0) /* Needs confirmation */
- return(x);
- x = cx_net(mynet, /* nettype */
- 0, /* protocol (not used) */
- line, /* host */
- "", /* port */
- NULL, /* alternate username */
- NULL, /* password */
- NULL, /* command to execute */
- 0, /* param1 */
- 0, /* param2 */
- 0, /* param3 */
- cx, /* enter CONNECT mode */
- sx, /* enter SERVER mode */
- zz, /* close connection if open */
- 0 /* gui */
- );
- }
-#endif /* NETFILE */
-
-#ifdef NETCMD
- if (mynet == NET_CMD || mynet == NET_PTY) {
- char *p = NULL;
- if (!confirmed) {
- if ((x = cmtxt("Rest of command","",&s,xxstring)) < 0)
- return(x);
- if (*s) {
- ckstrncat(line," ",LINBUFSIZ);
- ckstrncat(line,s,LINBUFSIZ);
- }
- s = line;
- }
- /* s == line - so we must protect the line buffer */
- s = brstrip(s);
- makestr(&p,s);
- ckstrncpy(line,p,LINBUFSIZ);
- makestr(&p,NULL);
-
- x = cx_net( mynet, /* nettype */
- 0, /* protocol (not used) */
- line, /* host */
- "", /* port */
- NULL, /* alternate username */
- NULL, /* password */
- NULL, /* command to execute */
- 0, /* param1 */
- 0, /* param2 */
- 0, /* param3 */
- cx, /* enter CONNECT mode */
- sx, /* enter SERVER mode */
- zz, /* close connection if open */
- 0 /* gui */
- );
- }
-#endif /* NETCMD */
-
-#ifdef NPIPE /* Named pipe */
- if (mynet == NET_PIPE) { /* Needs backslash twiddling */
- if (line[0]) {
- if (strcmp(line,"*")) { /* If remote, begin with */
- char * p = NULL;
- makestr(&p,line);
- ckstrncpy(line,"\\\\",LINBUFSIZ); /* server name */
- ckstrncat(line,p,LINBUFSIZ);
- makestr(&p,NULL);
- } else {
- line[0]='\0';
- }
- ckstrncat(line,"\\pipe\\", LINBUFSIZ); /* Make pipe name */
- ckstrncat(line,pipename, LINBUFSIZ); /* Add name of pipe */
-
- x = cx_net(mynet, /* nettype */
- 0, /* protocol (not used) */
- line, /* host */
- "", /* port */
- NULL, /* alternate username */
- NULL, /* password */
- NULL, /* command to execute */
- 0, /* param1 */
- 0, /* param2 */
- 0, /* param3 */
- cx, /* enter CONNECT mode */
- sx, /* enter SERVER mode */
- zz, /* close connection if open */
- 0 /* gui */
- );
- }
- }
-#endif /* NPIPE */
-
-#ifdef SUPERLAT
- if (mynet == NET_SLAT) { /* Needs password, etc. */
- slat_pwd[0] = NUL; /* Erase any previous password */
- debok = 0;
- if (*line) { /* If they gave a host name... */
- if ((x = cmfld(
- "password,\n or carriage return if no password required",
- "",
- &s,
- xxstring
- )) < 0 && x != -3)
- return(x);
- ckstrncpy(slat_pwd,s,18); /* Set the password, if any */
- }
- if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
-
- x = cx_net(mynet, /* nettype */
- 0, /* protocol (not used) */
- line, /* host */
- "", /* port */
- NULL, /* alternate username */
- NULL, /* password */
- NULL, /* command to execute */
- 0, /* param1 */
- 0, /* param2 */
- 0, /* param3 */
- cx, /* enter CONNECT mode */
- sx, /* enter SERVER mode */
- zz, /* close connection if open */
- 0 /* gui */
- );
- }
-#endif /* SUPERLAT */
-
-#ifdef DECNET
- if (mynet == NET_DEC) {
- if (!line[0]) { /* If they gave a host name... */
- printf("?hostname required\n");
- return(-3);
- }
- if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
-
- x = cx_net(mynet, /* nettype */
- 0, /* protocol (not used) */
- line, /* host */
- "", /* port */
- NULL, /* alternate username */
- NULL, /* password */
- NULL, /* command to execute */
- 0, /* param1 */
- 0, /* param2 */
- 0, /* param3 */
- cx, /* enter CONNECT mode */
- sx, /* enter SERVER mode */
- zz, /* close connection if open */
- 0 /* gui */
- );
- }
-#endif /* DECNET */
-
-#ifdef SSHBUILTIN
- if (mynet == NET_SSH) { /* SSH connection */
- int k, havehost = 0, trips = 0;
- int tmpver = -1, tmpxfw = -1, tmpssh_cas;
-#ifndef SSHTEST
- extern int sl_ssh_xfw, sl_ssh_xfw_saved;
- extern int sl_ssh_ver, sl_ssh_ver_saved;
-#endif /* SSHTEST */
- extern struct keytab sshopnsw[];
- extern int nsshopnsw;
- extern char *ssh_tmpcmd, *ssh_tmpport;
- struct FDB sw, kw, fl;
-
- debug(F110,"setlin SSH service 0",srvbuf,0);
- debug(F110,"setlin SSH host s 2",s,0);
- if (*s) { /* If they gave a host name... */
- debug(F110,"setlin SSH host s 1",s,0);
- if (*s == '*') {
- makestr(&slmsg,"Incoming connections not supported");
- printf(
- "?Sorry, incoming connections not supported for SSH.\n"
- );
- return(-9);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- } else {
- printf("?hostname required\n");
- return(-3);
- }
-
- /* Parse [ port ] [ switches ] */
- cmfdbi(&kw, /* Switches */
- _CMKEY,
- "Port number or service name,\nor switch",
- "",
- "",
- nsshopnsw,
- 4,
- xxstring,
- sshopnsw,
- &fl
- );
- cmfdbi(&fl, /* Port number or service name */
- _CMFLD,
- "",
- "",
- "",
- 0,
- 0,
- xxstring,
- NULL,
- NULL
- );
- trips = 0; /* Explained below */
- while (1) { /* Parse port and switches */
- y = cmfdb(&kw); /* Get a field */
- if (y == -3) /* User typed CR so quit from loop */
- break;
- if (y < 0) /* Other parse error, pass it back */
- return(y);
- switch (cmresult.fcode) { /* Field or Keyword? */
- case _CMFLD: /* Field */
- ckstrncpy(srvbuf,cmresult.sresult,SRVBUFSIZ);
- break;
- case _CMKEY: /* Keyword */
- switch (cmresult.nresult) { /* Which one? */
- case SSHSW_PWD:
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- debok = 0;
- if ((y = cmfld("Password","",&s,xxstring)) < 0) {
- if (y == -3) {
- makestr(&tmpstring,"");
- } else {
- return(y);
- }
- } else {
- s = brstrip(s);
- if ((y = (int)strlen(s)) > PWBUFL) {
- makestr(&slmsg,"Internal error");
- printf("?Sorry, too long - max = %d\n",PWBUFL);
- return(-9);
- }
- makestr(&tmpstring,s);
- }
- break;
- case SSHSW_USR: /* /USER: */
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- if ((y = cmfld("Username","",&s,xxstring)) < 0)
- return(y);
- s = brstrip(s);
- makestr(&tmpusrid,s);
- break;
- case SSHSW_VER:
- if ((y = cmnum("Number","",10,&z,xxstring)) < 0)
- return(y);
- if (z < 1 || z > 2) {
- printf("?Out of range: %d\n",z);
- return(-9);
- }
- tmpver = z;
- break;
- case SSHSW_CMD:
- case SSHSW_SUB:
- if ((y = cmfld("Text","",&s,xxstring)) < 0)
- return(y);
- makestr(&ssh_tmpcmd,s);
- tmpssh_cas = (cmresult.nresult == SSHSW_SUB);
- break;
- case SSHSW_X11:
- if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
- return(y);
- tmpxfw = y;
- break;
- default:
- return(-2);
- }
- }
- if (trips++ == 0) { /* After first time through */
- cmfdbi(&kw, /* only parse switches, not port. */
- _CMKEY,
- "Switch",
- "",
- "",
- nsshopnsw,
- 4,
- xxstring,
- sshopnsw,
- NULL
- );
- }
- }
- if ((y = cmcfm()) < 0) /* Get confirmation */
- return(y);
-
- debug(F110,"setlin pre-cx_net line",line,0);
- debug(F110,"setlin pre-cx_net srvbuf",srvbuf,0);
- x = cx_net( mynet, /* nettype */
- 0, /* protocol (not used) */
- line, /* host */
- srvbuf, /* port */
- tmpusrid, /* alternate username */
- tmpstring, /* password */
- ssh_tmpcmd, /* command to execute */
- tmpver, /* param1 - ssh version */
- tmpssh_cas, /* param2 - ssh cas */
- tmpxfw, /* param3 - ssh x11fwd */
- cx, /* enter CONNECT mode */
- sx, /* enter SERVER mode */
- zz, /* close connection if open */
- 0 /* gui */
- );
- if (tmpusrid)
- makestr(&tmpusrid,NULL);
- if (ssh_tmpcmd)
- makestr(&ssh_tmpcmd,NULL);
- }
-#endif /* SSHBUILTIN */
-
-#ifdef TCPSOCKET
- if (mynet == NET_TCPB) { /* TCP/IP connection */
- debug(F110,"setlin service 0",srvbuf,0);
- debug(F110,"setlin host s 2",s,0);
- if (*s) { /* If they gave a host name... */
- debug(F110,"setlin host s 1",s,0);
-#ifdef NOLISTEN
- if (*s == '*') {
- makestr(&slmsg,"Incoming connections not supported");
- printf(
- "?Sorry, incoming connections not supported in this version of Kermit.\n"
- );
- return(-9);
- }
-#endif /* NOLISTEN */
-#ifdef RLOGCODE
- /* Allow a username if rlogin is requested */
- if (mynet == NET_TCPB &&
- (ttnproto == NP_RLOGIN || ttnproto == NP_K5LOGIN ||
- ttnproto == NP_EK5LOGIN || ttnproto == NP_K4LOGIN ||
- ttnproto == NP_EK4LOGIN
- )) {
- int y;
- uidflag = 0;
- /* Check for "host:service" */
- for ( ; (*s != '\0') && (*s != ':'); s++) ;
- if (*s) { /* Service, save it */
- *s = NUL;
- ckstrncpy(srvbuf,++s,SRVBUFSIZ);
- } else { /* No :service, then use default. */
-#ifdef VMS
- switch (ttnproto) {
- case NP_RLOGIN:
- ckstrncpy(srvbuf,"513",SRVBUFSIZ); /* "login" */
- break;
- case NP_K4LOGIN:
- case NP_K5LOGIN:
- ckstrncpy(srvbuf,"543",SRVBUFSIZ); /* "klogin" */
- break;
- case NP_EK4LOGIN:
- case NP_EK5LOGIN:
- ckstrncpy(srvbuf,"2105",SRVBUFSIZ); /* "eklogin" */
- break;
- }
-#else /* VMS */
- switch (ttnproto) {
- case NP_RLOGIN:
- ckstrncpy(srvbuf,"login",SRVBUFSIZ);
- break;
- case NP_K4LOGIN:
- case NP_K5LOGIN:
- ckstrncpy(srvbuf,"klogin",SRVBUFSIZ);
- break;
- case NP_EK4LOGIN:
- case NP_EK5LOGIN:
- ckstrncpy(srvbuf,"eklogin",SRVBUFSIZ);
- break;
- }
-#endif /* VMS */
- }
- if (!confirmed) {
- y = cmfld("Userid on remote system",
- uidbuf,&s,xxstring);
- if (y < 0 && y != -3)
- return(y);
- if ((int)strlen(s) > 63) {
- makestr(&slmsg,"Internal error");
- printf("Sorry, too long\n");
- return(-9);
- }
- makestr(&tmpusrid,s);
- }
- } else { /* TELNET or SET HOST */
-#endif /* RLOGCODE */
- /* Check for "host:service" */
- for ( ; (*s != '\0') && (*s != ':'); s++) ;
- if (*s) { /* Service, save it */
- *s = NUL;
- ckstrncpy(srvbuf,++s,SRVBUFSIZ);
- } else if (!confirmed) {
- /* No :service, let them type one. */
- if (*line != '*') { /* Not incoming */
- if (mynet == NET_TCPB && ttnproto == NP_KERMIT) {
- if ((x = cmfld(
- "TCP service name or number",
- "kermit",&s,xxstring)
- ) < 0 && x != -3)
- return(x);
-#ifdef RLOGCODE
- } else if (mynet == NET_TCPB &&
- ttnproto == NP_RLOGIN) {
- if ((x = cmfld(
- "TCP service name or number,\n or carriage return for rlogin (513)",
- "login",&s,xxstring)
- ) < 0 && x != -3)
- return(x);
-#ifdef CK_AUTHENTICATION
-#ifdef CK_KERBEROS
- } else if (mynet == NET_TCPB &&
- (ttnproto == NP_K4LOGIN ||
- ttnproto == NP_K5LOGIN)) {
- if ((x = cmfld(
- "TCP service name or number,\n or carriage return for klogin (543)",
- "klogin",&s,xxstring)
- ) < 0 && x != -3)
- return(x);
- } else if (mynet == NET_TCPB &&
- (ttnproto == NP_EK4LOGIN ||
- ttnproto == NP_EK5LOGIN)) {
- if ((x = cmfld(
- "TCP service name or number,\n or carriage return for eklogin (2105)",
- "eklogin",&s,xxstring)
- ) < 0 && x != -3)
- return(x);
-#endif /* CK_KERBEROS */
-#endif /* CK_AUTHENTICATION */
-#endif /* RLOGCODE */
- } else {
- /* Do not set a default value in this call */
- /* If you do then it will prevent entries */
- /* in the network directory from accessing */
- /* alternate ports. */
-
- if ((x = cmfld(
- "TCP service name or number",
- "",&s,xxstring)
- ) < 0 && x != -3)
- return(x);
- }
- } else { /* Incoming connection */
- if ((x = cmfld("TCP service name or number",
- "",&s,xxstring)
- ) < 0 && x != -3)
- return(x);
- }
- if (*s) /* If they gave a service, */
- ckstrncpy(srvbuf,s,SRVBUFSIZ); /* copy it */
- debug(F110,"setlin service 0.5",srvbuf,0);
- }
-#ifdef RLOGCODE
- }
-#endif /* RLOGCODE */
- if (!confirmed) {
- char * defproto;
- switch (ttnproto) {
- case NP_RLOGIN:
- defproto = "/rlogin";
- break;
- case NP_K4LOGIN:
- defproto = "/k4login";
- break;
- case NP_K5LOGIN:
- defproto = "/k5login";
- break;
- case NP_EK4LOGIN:
- defproto = "/ek4login";
- break;
- case NP_EK5LOGIN:
- defproto = "/ek5login";
- break;
- case NP_KERMIT:
- case NP_TELNET:
- defproto = "/telnet";
- break;
- default:
- defproto = "/default";
- }
- if ((x = cmkey(tcprawtab,ntcpraw,"Switch",defproto,
- xxstring)) < 0) {
- if (x != -3)
- return(x);
- else if ((x = cmcfm()) < 0)
- return(x);
- } else {
- rawflg = x;
- if ((x = cmcfm()) < 0)
- return(x);
- }
- }
- }
- debug(F110,"setlin pre-cx_net line",line,0);
- debug(F110,"setlin pre-cx_net srvbuf",srvbuf,0);
- x = cx_net( mynet, /* nettype */
- rawflg /* protocol */,
- line, /* host */
- srvbuf, /* port */
- tmpusrid, /* alternate username */
- tmpstring, /* password */
- NULL, /* command to execute */
- a_type, /* param1 - telnet authtype */
- e_type, /* param2 - telnet enctype */
- wait, /* param3 - telnet wait */
- cx, /* enter CONNECT mode */
- sx, /* enter SERVER mode */
- zz, /* close connection if open */
- 0 /* gui */
- );
- }
-#endif /* TCPSOCKET */
-
-#ifdef CK_SECURITY
- if (tmpstring)
- makestr(&tmpstring,NULL);
-#endif /* CK_SECURITY */
- if (tmpusrid)
- makestr(&tmpusrid,NULL);
- debug(F111,"setlin cx_net",line,x);
- return(x);
-#endif /* NETCONN */
- }
-
-/* Serial tty device, possibly modem, connection... */
-
-#ifdef OS2
-/*
- User can type:
- COM1..COM8 = Regular COM port
- 1..8 = Synonym for COM1..COM8, is translated to COM1..COM8
- _n = (n is a number) = open file handle
- string = any text string = name of some other kind of device,
- taken literally, as given.
-*/
- s = "Communication device name";
-
-#ifdef CK_TAPI
- if (TAPIAvail)
- cktapiBuildLineTable(&tapilinetab, &_tapilinetab, &ntapiline);
- if (!(tapilinetab && _tapilinetab && ntapiline > 0) &&
- xx == XYTAPI_LIN ) {
- makestr(&slmsg,"TAPI device not configured");
- printf("\nNo TAPI Line Devices are configured for this system\n");
- return(-9);
- }
- if (xx == XYTAPI_LIN) { /* Default (first) TAPI line */
- s = "tapi"; /* (whatever it is) */
- } else { /* Query the user */
-#endif /* CK_TAPI */
-
-/* Now parse optional switches and then device name */
-
- confirmed = 0;
- cmfdbi(&sw,_CMKEY,"Device name, or switch",
- "","",npsltab,4,xxstring,psltab,&fl);
- cmfdbi(&fl,_CMFLD,"",dftty,"",0,0,xxstring,NULL,NULL);
- while (1) {
- x = cmfdb(&sw);
- debug(F101,"setlin cmfdb","",x);
- if (x < 0)
- if (x != -3)
- return(x);
- if (x == -3) {
- if ((x = cmcfm()) < 0) {
- return(x);
- } else {
- confirmed = 1;
- break;
- }
- }
- if (cmresult.fcode == _CMFLD) {
- s = cmresult.sresult;
- break;
- } else if (cmresult.fcode == _CMKEY) {
- switch (cmresult.nresult) {
- case SL_CNX: /* /CONNECT */
- cx = 1;
- sx = 0;
- break;
- case SL_SRV: /* /SERVER */
- cx = 0;
- sx = 1;
- break;
- case SL_SHR: /* /SHARE */
- shr = 1;
- break;
- case SL_NSH: /* /NOSHARE */
- shr = 0;
- break;
- }
- }
- }
-#ifdef CK_TAPI
- }
-#endif /* CK_TAPI */
-
- debug(F110,"OS2 SET PORT s",s,0);
- y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
- debug(F101,"OS2 SET PORT x","",x);
- debug(F101,"OS2 SET PORT y","",y);
- if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
- s = os2devtab[x+8].kwd; /* Substitite its real name */
-#ifdef NT
- xxtapi = 0;
-#else /* NT */
- xxslip = xxppp = 0;
-#endif /* NT */
- debug(F110,"OS2 SET PORT subst s",s,"");
-#ifndef NT
- } else if ((y >-1) && (x >= 16 && x < 24)) { /* SLIP access */
- s = os2devtab[x-8].kwd; /* Substitite its real name */
- debug(F110,"OS2 SET PORT SLIP subst s",s,"");
- xxslip = 1;
- xxppp = 0;
- } else if ((y >-1) && (x >= 24 && x < 32)) { /* PPP access */
- s = os2devtab[x-16].kwd; /* Substitite its real name */
- debug(F110,"OS2 SET PORT PPP subst s",s,"");
- xxppp = 1;
- xxslip = 0;
- if ((y = cmkey(os2ppptab,
- nos2ppp,
- "PPP driver interface",
- "ppp0",
- xxstring)
- ) < 0)
- return(y);
- debug(F101,"OS2 SET PORT PPP INTERFACE y","",y);
- xxppp = (y % 10) + 1;
-#endif /* NT */
- } else if (*s == '_') { /* User used "_" prefix */
- s++; /* Remove it */
- /* Rest must be numeric */
- debug(F110,"OS2 SET PORT HANDLE _subst s",s,0);
- if (!rdigits(s)) {
- makestr(&slmsg,"Invalid file handle");
- printf("?Invalid format for file handle\n");
- return(-9);
- }
-#ifdef NT
- xxtapi = 0;
-#else /* NT */
- xxslip = xxppp = 0;
-#endif /* NT */
- } else { /* A normal COMx port or a string */
- s = brstrip(s); /* Strip braces if any */
-#ifdef NT
-#ifdef CK_TAPI
- /* Windows TAPI support - Look up in keyword table */
- if (tapilinetab && _tapilinetab && ntapiline > 0) {
- if (!ckstrcmp(s,"tapi",4,0)) {
-
- /* Find out what the lowest numbered TAPI device is */
- /* and use it as the default. */
- int j = 9999, k = -1;
- for (i = 0; i < ntapiline; i++) {
- if (tapilinetab[i].kwval < j) {
- j = tapilinetab[i].kwval;
- k = i;
- }
- }
- if (k >= 0)
- s = _tapilinetab[k].kwd;
- else
- s = "";
-
- if ((y = cmkey(_tapilinetab,ntapiline,
- "TAPI device name",s,xxstring)) < 0)
- return(y);
-
- xxtapi = 1;
-
- /* Get the non Underscored string */
- for (i = 0; i < ntapiline; i++ ) {
- if (tapilinetab[i].kwval == y) {
- s = tapilinetab[i].kwd;
- break;
- }
- }
- } else
- xxtapi = 0;
- }
-#endif /* CK_TAPI */
-#else /* NT */
- /* not OS/2 SLIP or PPP */
- xxslip = xxppp = 0;
-#endif /* NT */
- }
- ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Copy to a safe place */
- s = tmpbuf;
- if ((x = cmcfm()) < 0)
- return(x);
-
-#else /* !OS2 */
-
- cmfdbi(&sw,_CMKEY,"Device name, or switch",
- "","",npsltab,4,xxstring,psltab,&tx);
- cmfdbi(&tx,_CMTXT,"",dftty,"",0,0,xxstring,NULL,NULL);
- while (!confirmed) {
- x = cmfdb(&sw);
- debug(F101,"setlin cmfdb","",x);
- if (x < 0)
- if (x != -3)
- return(x);
- if (x == -3) {
- if ((x = cmcfm()) < 0) {
- return(x);
- } else {
- confirmed = 1;
- break;
- }
- }
- switch (cmresult.fcode) {
- case _CMTXT:
- ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
- s = tmpbuf;
- debug(F110,"setlin CMTXT",tmpbuf,0);
- confirmed = 1;
- break;
- case _CMKEY: /* Switch */
- debug(F101,"setlin CMKEY",tmpbuf,cmresult.nresult);
- switch (cmresult.nresult) {
- case SL_CNX: /* /CONNECT */
- cx = 1;
- sx = 0;
- break;
- case SL_SRV: /* /SERVER */
- cx = 0;
- sx = 1;
- break;
-#ifdef VMS
- case SL_SHR: /* /SHARE */
- shr = 1;
- break;
- case SL_NSH: /* /NOSHARE */
- shr = 0;
- break;
-#endif /* VMS */
- }
- continue;
- default:
- debug(F101,"setlin bad cmfdb result","",cmresult.fcode);
- makestr(&slmsg,"Internal error");
- printf("?Internal parsing error\n");
- return(-9);
- }
- }
-#endif /* OS2 */
- if (!confirmed)
- if ((x = cmcfm()) < 0)
- return(x);
-
- debug(F110,"setlin pre-cx_serial s",s,0);
- debug(F110,"setlin pre-cx_serial line",line,0);
- x = cx_serial(s,cx,sx,shr,zz,0,
-#ifdef OS2
-#ifdef NT
- (xxtapi ? CX_TAPI : 0)
-#else
- (xxslip ? CX_SLIP : 0) | (xxppp ? CX_PPP : 0)
-#endif /* NT */
-#else /* OS2 */
- 0
-#endif /* OS2 */
- );
- debug(F111,"setlin cx_serial",line,x);
- return(x);
-}
-#endif /* NOLOCAL */
-
-#ifdef CKCHANNELIO
-/*
- C-Library based file-i/o package for scripts. This should be portable to
- all C-Kermit versions since it uses the same APIs we have always used for
- processing command files. The entire channel i/o package is contained
- herein, apart from some keyword table entries in the main keyword table
- and the help text in the HELP command module.
-
- On platforms like VMS and VOS, this package handles only UNIX-style
- stream files. If desired, it can be replaced for those platforms by
- <#>ifdef'ing out this code and adding the equivalent replacement routines
- to the ck?fio.c module, e.g. for RMS-based file i/o in ckvfio.c.
-*/
-#ifndef NOSTAT
-#ifdef VMS
-/* 2010-03-09 SMS. VAX C needs help to find "sys". It's easier not to try. */
-#include <stat.h>
-#else /* def VMS */
-#include <sys/stat.h>
-#endif /* def VMS [else] */
-#endif /* NOSTAT */
-
-#ifdef NLCHAR
-static int z_lt = 1; /* Length of line terminator */
-#else
-static int z_lt = 2;
-#endif /* NLCHAR */
-
-struct ckz_file { /* C-Kermit file struct */
- FILE * z_fp; /* Includes the C-Lib file struct */
- unsigned int z_flags; /* Plus C-Kermit mode flags, */
- CK_OFF_T z_nline; /* current line number if known, */
- char z_name[CKMAXPATH+2]; /* and the file's name. */
-};
-static struct ckz_file ** z_file = NULL; /* Array of C-Kermit file structs */
-static int z_inited = 0; /* Flag for array initialized */
-int z_maxchan = Z_MAXCHAN; /* Max number of C-Kermit channels */
-int z_openmax = CKMAXOPEN; /* Max number of open files overall */
-int z_nopen = 0; /* How many channels presently open */
-int z_error = 0; /* Most recent error */
-int z_filcount = -1; /* Most recent FILE COUNT result */
-
-#define RD_LINE 0 /* FILE READ options */
-#define RD_CHAR 1
-#define RD_SIZE 2
-#define RD_TRIM 8 /* Like Snobol &TRIM = 1 */
-#define RD_UNTA 9 /* Untabify */
-
-#define WR_LINE RD_LINE /* FILE WRITE options */
-#define WR_CHAR RD_CHAR
-#define WR_SIZE RD_SIZE
-#define WR_STRI 3
-#define WR_LPAD 4
-#define WR_RPAD 5
-
-#ifdef UNIX
-extern int ckmaxfiles; /* Filled in by sysinit(). */
-#endif /* UNIX */
-
-/* See ckcker.h for error numbers */
-/* See ckcdeb.h for Z_MAXCHAN and CKMAXOPEN definitions */
-/* NOTE: For VMS we might be able to fill in ckmaxfiles */
-/* from FILLM and CHANNELCNT -- find out about these... */
-
-static char * fopnargs[] = { /* Mode combinations for fopen() */
-#ifdef COMMENT
- /* All combinations of rwa */
- "", "r", "w", "rw", "a", "ra", "wa", "rwa", /* Text mode */
- "b", "rb", "wb", "rwb", "ab", "rab", "wab", "rwab" /* Binary mode */
-#else
- /* Combinations and syntax permitted by C libraries... */
- "", "r", "w", "r+", "a", "", "a", "", /* Text mode */
-#ifdef OS2
- "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for K95 */
-#else
-#ifdef VMS
- "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for VMS */
-#else
- "", "r", "w", "r+", "a", "", "a", "" /* Binary modes for UNIX */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* COMMENT */
-};
-static int nfopnargs = sizeof(fopnargs) / sizeof(char *);
-
-char * /* Error messages */
-ckferror(n) int n; {
- switch (n) {
- case FX_NER: return("No error");
- case FX_SYS: return(ck_errstr());
- case FX_EOF: return("End of file");
- case FX_NOP: return("File not open");
- case FX_CHN: return("Channel out of range");
- case FX_RNG: return("Parameter out of range");
- case FX_NMF: return("Too many files open");
- case FX_FOP: return("Operation conflicts with OPEN mode");
- case FX_NYI: return("OPEN mode not supported");
- case FX_BOM: return("Illegal combination of OPEN modes");
- case FX_ACC: return("Access denied");
- case FX_FNF: return("File not found");
- case FX_OFL: return("Buffer overflow");
- case FX_LNU: return("Current line number unknown");
- case FX_ROO: return("Off limits");
- case FX_UNK: return("Operation fails - reason unknown");
- default: return("Error number out of range");
- }
-}
-
-/*
- Z _ O P E N -- Open a file for the requested type of access.
-
- Call with:
- name: Name of file to be opened.
- flags: Any combination of FM_xxx values except FM_EOF (ckcker.h).
- Returns:
- >= 0 on success: The assigned channel number
- < 0 on failure: A negative FX_xxx error code (ckcker.h).
-*/
-int
-z_open(name, flags) char * name; int flags; {
- int i, n;
- FILE * t;
- char * mode;
- debug(F111,"z_open",name,flags);
- if (!name) name = ""; /* Check name argument */
- if (!name[0])
- return(z_error = FX_BFN);
- if (flags & FM_CMD) /* Opening pipes not implemented yet */
- return(z_error = FX_NYI); /* (and not portable either) */
- debug(F101,"z_open nfopnargs","",nfopnargs);
- if (flags < 0 || flags >= nfopnargs) /* Range check flags */
- return(z_error = FX_RNG);
- mode = fopnargs[flags]; /* Get fopen() arg */
- debug(F111,"z_open fopen args",mode,flags);
- if (!mode[0]) /* Check for illegal combinations */
- return(z_error = FX_BOM);
- if (!z_inited) { /* If file structs not inited */
- debug(F101,"z_open z_maxchan 1","",z_maxchan);
-#ifdef UNIX
- debug(F101,"z_open ckmaxfiles","",ckmaxfiles);
- if (ckmaxfiles > 0) { /* Set in ck?tio.c: sysinit() */
- int x;
- x = ckmaxfiles - ZNFILS - 5;
- if (x > z_maxchan) /* sysconf() value greater than */
- z_maxchan = x; /* value from header files. */
- debug(F101,"z_open z_maxchan 2","",z_maxchan);
- }
-#endif /* UNIX */
- if (z_maxchan < Z_MINCHAN) /* Allocate at least this many. */
- z_maxchan = Z_MINCHAN;
- debug(F101,"z_open z_maxchan 3","",z_maxchan);
- /* Note: This could be a pretty big chunk of memory */
- /* if z_maxchan is a big number. If this becomes a problem */
- /* we'll need to malloc and free each element at open/close time */
-#ifdef COMMENT
- /* May 2006 - it's time - in current Linux this about 3MB */
- if (!(z_file = (struct ckz_file *)
- malloc(sizeof(struct ckz_file) * (z_maxchan + 1))))
- return(z_error = FX_NMF);
- for (i = 0; i < z_maxchan; i++) {
- z_file[i].z_fp = NULL;
- z_file[i].z_flags = 0;
- z_file[i].z_nline = 0;
- *(z_file[i].z_name) = '\0';
- }
-#else
- /* New economical way, allocate storage for each channel as needed */
- if (!z_file) {
- z_file = (struct ckz_file **)malloc((z_maxchan + 1) *
- sizeof(struct ckz_file *));
- if (!z_file)
- return(z_error = FX_NMF);
- for (i = 0; i < z_maxchan; i++)
- z_file[i] = NULL;
- }
-#endif /* COMMENT */
- z_inited = 1; /* Remember we initialized */
- }
- for (n = -1, i = 0; i < z_maxchan; i++) { /* Find a free channel */
-#ifdef COMMENT
- if (!z_file[i].z_fp) {
- n = i;
- break;
- }
-#else
- if (!z_file[i]) {
- z_file[i] = (struct ckz_file *) malloc(sizeof(struct ckz_file));
- if (!z_file[i])
- return(z_error = FX_NMF);
- n = i;
- break;
- }
-#endif /* COMMENT */
-
- }
- if (n < 0 || n >= z_maxchan) /* Any free channels? */
- return(z_error = FX_NMF); /* No, fail. */
- errno = 0;
-
- z_file[n]->z_flags = 0; /* In case of failure... */
- z_file[n]->z_fp = NULL; /* Set file pointer to NULL */
-
- t = fopen(name, mode); /* Try to open the file. */
- if (!t) { /* Failed... */
- debug(F111,"z_open error",name,errno);
-#ifdef EMFILE
- if (errno == EMFILE)
- return(z_error = FX_NMF);
-#endif /* EMFILE */
- free(z_file[n]);
- z_file[n] = NULL;
- return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error code */
- }
-#ifdef NT
-#ifdef O_SEQUENTIAL
- if (t) /* Caching hint for NT */
- _setmode(_fileno(t),O_SEQUENTIAL);
-#endif /* O_SEQUENTIAL */
-#endif /* NT */
- z_nopen++; /* Open, count it. */
- z_file[n]->z_fp = t; /* Stash the file pointer */
- z_file[n]->z_flags = flags; /* and the flags */
- z_file[n]->z_nline = 0; /* Current line number is 0 */
- z_error = 0;
- zfnqfp(name,CKMAXPATH,z_file[n]->z_name); /* and the file's full name */
- return(n); /* Return the channel number */
-}
-
-int
-z_close(channel) int channel; { /* Close file on given channel */
- int x;
- FILE * t;
- if (!z_inited) /* Called before any files are open? */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan) /* Channel out of range? */
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(z_error = FX_NOP);
- if (!(t = z_file[channel]->z_fp)) /* Channel wasn't open? */
- return(z_error = FX_NOP);
- errno = 0; /* Set errno 0 to get a good reading */
- x = fclose(t); /* Try to close */
- if (x == EOF) /* On failure */
- return(z_error = FX_SYS); /* indicate system error. */
- z_nopen--; /* Closed OK, decrement open count */
- z_file[channel]->z_fp = NULL; /* Set file pointer to NULL */
- z_file[channel]->z_nline = 0; /* Current line number is 0 */
- z_file[channel]->z_flags = 0; /* Set flags to 0 */
- *(z_file[channel]->z_name) = '\0'; /* Clear name */
- free(z_file[channel]);
- z_file[channel] = NULL;
- return(z_error = 0);
-}
-
-/*
- Z _ O U T -- Output string to channel.
-
- Call with:
- channel: Channel number to write to.
- s: String to write.
- length > -1: How many characters of s to write.
- length < 0: Write entire NUL-terminated string.
- flags == 0: Supply line termination.
- flags > 0: Don't supply line termination.
- flags < 0: Write 'length' NUL characters.
- Special case:
- If flags > -1 and s is empty or NULL and length == 1, write 1 NUL.
- Returns:
- Number of characters written to channel on success, or
- negative FX_xxx error code on failure.
-*/
-int
-z_out(channel,s,length,flags) int channel, flags, length; char * s; {
- FILE * t;
- int x, n;
- char c = '\0';
-
- if (!s) s = ""; /* Guard against null pointer */
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"z_out",s,channel);
- debug(F101,"z_out length","",length);
- debug(F101,"z_out flags","",flags);
- }
-#endif /* DEBUG */
- if (!z_inited) /* File i/o inited? */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan) /* Channel in range? */
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(z_error = FX_NOP);
- if (!(t = z_file[channel]->z_fp)) /* File open? */
- return(z_error = FX_NOP);
- if (!((z_file[channel]->z_flags) & (FM_WRI|FM_APP))) /* In write mode? */
- return(z_error = FX_FOP);
- n = length; /* Length of string to write */
- if (n < 0) { /* Negative means get it ourselves */
- if (flags < 0) /* Except when told to write NULs in */
- return(z_error = FX_RNG); /* which case args are inconsistent */
- n = strlen(s); /* Get length of string arg */
- }
- errno = 0; /* Reset errno */
- debug(F101,"z_out n","",n);
- if (flags < 0) { /* Writing NULs... */
- int i;
- for (i = 0; i < n; i++) {
- x = fwrite(&c,1,1,t);
- if (x < 1)
- return(z_error = (errno ? FX_SYS : FX_UNK));
- }
- z_file[channel]->z_nline = -1; /* Current line no longer known */
- z_error = 0;
- return(i);
- } else { /* Writing string arg */
- if (n == 1 && !s[0]) /* Writing one char but it's NUL */
- x = fwrite(&c,1,1,t);
- else /* Writing non-NUL char or string */
- x = fwrite(s,1,n,t);
- debug(F101,"z_out fwrite",ckitoa(x),errno);
- if (x < n) /* Failure to write requested amount */
- return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error */
- if (flags == 0) { /* If supplying line termination */
- if (fwrite("\n",1,1,t)) /* do that */
- x += z_lt; /* count the terminator */
- if (z_file[channel]->z_nline > -1) /* count this line */
- z_file[channel]->z_nline++;
- } else {
- z_file[channel]->z_nline = -1; /* Current line no longer known */
- }
- }
- z_error = 0;
- return(x);
-}
-
-#define Z_INBUFLEN 64
-
-/*
- Z _ I N -- Multichannel i/o file input function.
-
- Call with:
- channel number to read from.
- s = address of destination buffer.
- buflen = destination buffer length.
- length = Number of bytes to read, must be < buflen.
- flags: 0 = read a line; nonzero = read the given number of bytes.
- Returns:
- Number of bytes read into buffer or a negative error code.
- A terminating NUL is deposited after the last byte that was read.
-*/
-int
-z_in(channel,s,buflen,length,flags)
- int channel, buflen, length, flags; char * s;
-/* z_in */ {
- int i, j, x;
- FILE * t;
- char * p;
-
- if (!z_inited) /* Check everything... */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(z_error = FX_NOP);
- if (!(t = z_file[channel]->z_fp))
- return(z_error = FX_NOP);
- if (!((z_file[channel]->z_flags) & FM_REA))
- return(z_error = FX_FOP);
- if (!s) /* Check destination */
- return(z_error = FX_RNG);
- s[0] = NUL;
- if (length == 0) /* Read 0 bytes - easy. */
- return(z_error = 0);
- debug(F101,"z_in channel","",channel);
- debug(F101,"z_in buflen","",buflen);
- debug(F101,"z_in length","",length);
- debug(F101,"z_in flags","",flags);
- if (length < 0 || buflen < 0) /* Check length args */
- return(z_error = FX_RNG);
- if (buflen <= length)
- return(z_error = FX_RNG);
- errno = 0; /* Reset errno */
- if (flags) { /* Read block or byte */
- int n; /* 20050912 */
- n = length; /* 20050912 */
- i = 0; /* 20050912 */
- while (n > 0) { /* 20050912 */
- i = fread(s,1,n,t); /* 20050912 */
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"z_in block",s,i);
- debug(F101,"z_in block errno","",errno);
- debug(F101,"z_in block ferror","",ferror(t));
- debug(F101,"z_in block feof","",feof(t));
- }
-#endif /* DEBUG */
- if (i == 0) break; /* 20050912 */
- s += i; /* 20050912 */
- n -= i; /* 20050912 */
- }
- /* Current line no longer known */
- z_file[channel]->z_nline = (CK_OFF_T)-1;
- } else { /* Read line */
-#ifndef COMMENT
- /* This method is used because it's simpler than the others */
- /* and also marginally faster. */
- debug(F101,"z_in getc loop","",CKFTELL(t));
- for (i = 0; i < length; i++) {
- if ((x = getc(t)) == EOF) {
- debug(F101,"z_in getc error","",CKFTELL(t));
- s[i] = '\0';
- break;
- }
- s[i] = x;
- if (s[i] == '\n') {
- s[i] = '\0';
- break;
- }
- }
- debug(F111,"z_in line byte loop",ckitoa(errno),i);
- debug(F111,"z_in line got",s,z_file[channel]->z_nline);
- if (z_file[channel]->z_nline > -1)
- z_file[channel]->z_nline++;
-#else
-#ifdef COMMENT2
- /* Straightforward but strlen() slows it down. */
- s[0] = '\0';
- i = 0;
- if (fgets(s,length,t)) {
- i = strlen(s);
- if (i > 0 && s[i-1] == '\n') i--;
- }
- debug(F111,"z_in line fgets",ckitoa(errno),i);
- if (z_file[channel]->z_nline > -1)
- z_file[channel]->z_nline++;
-#else
- /* This is a do-it-yourself fgets() with its own readahead and */
- /* putback. It's a bit faster than real fgets() but not enough */
- /* to justify the added complexity or the risk of the ftell() and */
- /* fseek() calls failing. */
- int k, flag = 0;
- CK_OFF_T pos;
- for (i = 0; !flag && i <= (length - Z_INBUFLEN); i += Z_INBUFLEN) {
- k = ((length - i) < Z_INBUFLEN) ? length - i : Z_INBUFLEN;
- if ((x = fread(s+i,1,k,t)) < 1)
- break;
- s[i+x] = '\0';
- for (j = 0; j < x; j++) {
- if (s[i+j] == '\n') {
- s[i+j] = '\0';
- flag ++;
- pos = CKFTELL(t);
- if (pos > -1) {
- pos -= (x - j - 1);
- x = CKFSEEK(t, pos, 0);
- i += j;
- break;
- } else
- return(z_error = FX_SYS);
- }
- }
- }
- if (z_file[channel]->z_nline > -1)
- z_file[channel]->z_nline++;
- debug(F111,"z_in line chunk loop",ckitoa(errno),i);
-#endif /* COMMENT2 */
-#endif /* COMMENT */
- }
- debug(F111,"z_in i",ckitoa(errno),i);
- if (i < 0) i = 0; /* NUL-terminate result */
- s[i] = '\0';
- if (i > 0) {
- z_error = 0;
- return(i);
- }
- if (i == 0 && feof(t)) /* EOF on reading? */
- return(z_error = FX_EOF); /* Return EOF code */
- return(errno ? (z_error = -1) : i); /* Return length or system error */
-}
-
-int
-z_flush(channel) int channel; { /* Flush output channel */
- FILE * t;
- int x;
- if (!z_inited) /* Regular checks */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(z_error = FX_NOP);
- if (!(t = z_file[channel]->z_fp))
- return(z_error = FX_NOP);
- if (!((z_file[channel]->z_flags) & (FM_WRI|FM_APP))) /* Write access? */
- return(z_error = FX_FOP);
- errno = 0; /* Reset errno */
- x = fflush(t); /* Try to flush */
- return(x ? (z_error = FX_SYS) : 0); /* Return system error or 0 if OK */
-}
-
-int
-#ifdef CK_ANSIC
-z_seek(int channel, CK_OFF_T pos) /* Move file pointer to byte */
-#else
-z_seek(channel,pos) int channel; CK_OFF_T pos; /* (seek to given position) */
-#endif /* CK_ANSIC */
-{
- int i, x = 0, rc;
- FILE * t;
- if (!z_inited) /* Check... */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(z_error = FX_NOP);
- if (!(t = z_file[channel]->z_fp))
- return(z_error = FX_NOP);
- if (pos < 0L) {
- x = 2;
- pos = (pos == -2) ? -1L : 0L;
- }
- errno = 0;
- rc = CKFSEEK(t,pos,x); /* Try to seek */
- debug(F111,"z_seek",ckitoa(errno),rc);
- if (rc < 0) /* OK? */
- return(z_error = FX_SYS); /* No. */
- z_file[channel]->z_nline = ((pos || x) ? -1 : 0);
- return(z_error = 0);
-}
-
-int
-#ifdef CK_ANSIC
-z_line(int channel, CK_OFF_T pos) /* Move file pointer to line */
-#else
-z_line(channel,pos) int channel; CK_OFF_T pos; /* (seek to given position) */
-#endif /* CK_ANSIC */
-{
- int i, len, x = 0;
- CK_OFF_T current = (CK_OFF_T)0, prev = (CK_OFF_T)-1, old = (CK_OFF_T)-1;
- FILE * t;
- char tmpbuf[256];
- if (!z_inited) /* Check... */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(z_error = FX_NOP);
- if (!(t = z_file[channel]->z_fp))
- return(z_error = FX_NOP);
- debug(F101,"z_line pos","",pos);
- if (pos < 0L) { /* EOF wanted */
- CK_OFF_T n;
- n = z_file[channel]->z_nline;
- debug(F101,"z_line n","",n);
- if (n < 0 || pos < 0) {
- rewind(t);
- n = 0;
- }
- while (1) { /* This could take a while... */
- if ((x = getc(t)) == EOF)
- break;
- if (x == '\n') {
- n++;
- if (pos == -2) {
- old = prev;
- prev = CKFTELL(t);
- }
- }
- }
- debug(F101,"z_line old","",old);
- debug(F101,"z_line prev","",prev);
- if (pos == -2) {
- if ((x = z_seek(channel,old)) < 0)
- return(z_error = x);
- else
- n--;
- }
- z_file[channel]->z_nline = n;
- return(z_error = 0);
- }
- if (pos == 0L) { /* Rewind wanted */
- z_file[channel]->z_nline = 0L;
- rewind(t);
- debug(F100,"z_line rewind","",0);
- return(0L);
- }
- tmpbuf[255] = NUL; /* Make sure buf is NUL terminated */
- current = z_file[channel]->z_nline; /* Current line */
- /*
- If necessary the following could be optimized, e.g. for positioning
- to a previous line in a large file without starting over.
- */
- if (current < 0 || pos < current) { /* Not known or behind us... */
- debug(F101,"z_line rewinding","",pos);
- if ((x = z_seek(channel, 0L)) < 0) /* Rewind */
- return(z_error = x);
- if (pos == 0) /* If 0th line wanted we're done */
- return(z_error = 0);
- current = 0;
- }
- while (current < pos) { /* Search for specified line */
- if (fgets(tmpbuf,255,t)) {
- len = strlen(tmpbuf);
- if (len > 0 && tmpbuf[len-1] == '\n') {
- current++;
- debug(F111,"z_line read",ckitoa(len),current);
- } else if (len == 0) {
- return(z_error = FX_UNK);
- }
- } else {
- z_file[channel]->z_nline = -1L;
- debug(F101,"z_line premature EOF","",current);
- return(z_error = FX_EOF);
- }
- }
- z_file[channel]->z_nline = current;
- debug(F101,"z_line result","",current);
- z_error = 0;
- return(current);
-}
-
-char *
-z_getname(channel) int channel; { /* Return name of file on channel */
- FILE * t;
- if (!z_inited) {
- z_error = FX_NOP;
- return(NULL);
- }
- if (channel >= z_maxchan) {
- z_error = FX_CHN;
- return(NULL);
- }
- if (!z_file[channel]) {
- z_error = FX_NOP;
- return(NULL);
- }
- if (!(t = z_file[channel]->z_fp)) {
- z_error = FX_NOP;
- return(NULL);
- }
- return((char *)(z_file[channel]->z_name));
-}
-
-int
-z_getmode(channel) int channel; { /* Return OPEN modes of channel */
- FILE * t; /* 0 if file not open */
-#ifndef NOSTAT
-#ifdef NT
- struct _stat statbuf;
-#else /* NT */
- struct stat statbuf;
-#endif /* NT */
-#endif /* NOSTAT */
- int x;
- if (!z_inited)
- return(0);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(0);
- if (!(t = z_file[channel]->z_fp))
- return(0);
- x = z_file[channel]->z_flags;
- if (feof(t)) { /* This might not work for */
- x |= FM_EOF; /* output files */
-#ifndef NOSTAT
- /* But this does if we can use it. */
- } else if (stat(z_file[channel]->z_name,&statbuf) > -1) {
- if (CKFTELL(t) == statbuf.st_size)
- x |= FM_EOF;
-#endif /* NOSTAT */
- }
- return(x);
-}
-
-CK_OFF_T
-z_getpos(channel) int channel; { /* Get file pointer position */
- FILE * t; /* on this channel */
- CK_OFF_T x;
- if (!z_inited)
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(z_error = FX_NOP);
- if (!(t = z_file[channel]->z_fp))
- return(z_error = FX_NOP);
- x = CKFTELL(t);
- return((x < 0L) ? (z_error = FX_SYS) : x);
-}
-
-CK_OFF_T
-z_getline(channel) int channel; { /* Get current line number */
- FILE * t; /* in file on this channel */
- CK_OFF_T rc;
- if (!z_inited)
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(z_error = FX_NOP);
- if (!(t = z_file[channel]->z_fp))
- return(z_error = FX_NOP);
- debug(F101,"z_getline","",z_file[channel]->z_nline);
- rc = z_file[channel]->z_nline;
- return((rc < 0) ? (z_error = FX_LNU) : rc);
-}
-
-int
-z_getfnum(channel) int channel; { /* Get file number / handle */
- FILE * t; /* for file on this channel */
- if (!z_inited)
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(z_error = FX_NOP);
- if (!(t = z_file[channel]->z_fp))
- return(z_error = FX_NOP);
- z_error = 0;
- return(fileno(t));
-}
-
-/*
- Line-oriented counts and seeks are as dumb as they can be at the moment.
- Later we can speed them up by building little indexes.
-*/
-CK_OFF_T
-z_count(channel, what) int channel, what; { /* Count bytes or lines in file */
- FILE * t;
- int i, x;
- CK_OFF_T pos, count = (CK_OFF_T)0;
- if (!z_inited) /* Check stuff... */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!z_file[channel])
- return(z_error = FX_NOP);
- if (!(t = z_file[channel]->z_fp))
- return(z_error = FX_NOP);
- pos = CKFTELL(t); /* Save current file pointer */
- errno = 0;
- z_error = 0;
- if (what == RD_CHAR) { /* Size in bytes requested */
-#ifdef COMMENT
- if (!CKFSEEK(t,0L,2)) { /* Seek to end */
- count = CKFTELL(t); /* Get file pointer */
- CKFSEEK(t,pos,0); /* Restore file file pointer */
- return(count);
- } else /* Fallback in case seek fails */
-#endif /* COMMENT */
- return(zgetfs(z_file[channel]->z_name));
- }
- rewind(t); /* Line count requested - rewind. */
- while (1) { /* Count lines. */
- if ((x = getc(t)) == EOF) /* Stupid byte loop */
- break; /* but it works as well as anything */
- if (x == '\n') /* else... */
- count++;
- }
- x = CKFSEEK(t,pos,0); /* Restore file pointer */
- return(count);
-}
-
-/* User interface for generalized channel-oriented file i/o */
-
-struct keytab fctab[] = { /* FILE subcommands */
- { "close", FIL_CLS, 0 },
- { "count", FIL_COU, 0 },
- { "flush", FIL_FLU, 0 },
- { "list", FIL_LIS, 0 },
- { "open", FIL_OPN, 0 },
- { "read", FIL_REA, 0 },
- { "rewind", FIL_REW, 0 },
- { "seek", FIL_SEE, 0 },
- { "status", FIL_STA, 0 },
- { "write", FIL_WRI, 0 }
-};
-int nfctab = (sizeof (fctab) / sizeof (struct keytab));
-
-static struct keytab fcswtab[] = { /* OPEN modes */
- { "/append", FM_APP, 0 },
- { "/binary", FM_BIN, 0 },
-#ifdef COMMENT
- { "/command", FM_CMD, 0 }, /* Not implemented */
-#endif /* COMMENT */
- { "/read", FM_REA, 0 },
- { "/write", FM_WRI, 0 }
-};
-static int nfcswtab = (sizeof (fcswtab) / sizeof (struct keytab));
-
-static struct keytab fclkwtab[] = { /* CLOSE options */
- { "all", 1, 0 }
-};
-
-static struct keytab fsekwtab[] = { /* SEEK symbols */
- { "eof", 1, 0 },
- { "last", 2, 0 }
-};
-static int nfsekwtab = (sizeof (fsekwtab) / sizeof (struct keytab));
-
-#define SEE_LINE RD_LINE /* SEEK options */
-#define SEE_CHAR RD_CHAR
-#define SEE_REL 3
-#define SEE_ABS 4
-#define SEE_FIND 5
-
-static struct keytab fskswtab[] = {
- { "/absolute", SEE_ABS, 0 },
- { "/byte", SEE_CHAR, 0 },
- { "/character", SEE_CHAR, CM_INV },
- { "/find", SEE_FIND, CM_ARG },
- { "/line", SEE_LINE, 0 },
- { "/relative", SEE_REL, 0 }
-};
-static int nfskswtab = (sizeof (fskswtab) / sizeof (struct keytab));
-
-#define COU_LINE RD_LINE /* COUNT options */
-#define COU_CHAR RD_CHAR
-#define COU_LIS 3
-#define COU_NOL 4
-
-static struct keytab fcoswtab[] = {
- { "/bytes", COU_CHAR, 0 },
- { "/characters",COU_CHAR, CM_INV },
- { "/lines", COU_LINE, 0 },
- { "/list", COU_LIS, 0 },
- { "/nolist", COU_NOL, 0 },
- { "/quiet", COU_NOL, CM_INV }
-};
-static int nfcoswtab = (sizeof (fcoswtab) / sizeof (struct keytab));
-
-static struct keytab frdtab[] = { /* READ types */
- { "/block", RD_SIZE, CM_INV|CM_ARG },
- { "/byte", RD_CHAR, CM_INV },
- { "/character", RD_CHAR, 0 },
- { "/line", RD_LINE, 0 },
- { "/size", RD_SIZE, CM_ARG },
- { "/trim", RD_TRIM, 0 },
- { "/untabify", RD_UNTA, 0 }
-};
-static int nfrdtab = (sizeof (frdtab) / sizeof (struct keytab));
-
-static struct keytab fwrtab[] = { /* WRITE types */
- { "/block", WR_SIZE, CM_INV|CM_ARG },
- { "/byte", WR_CHAR, CM_INV },
- { "/character", WR_CHAR, 0 },
- { "/line", WR_LINE, 0 },
- { "/lpad", WR_LPAD, CM_ARG },
- { "/rpad", WR_RPAD, CM_ARG },
- { "/size", WR_SIZE, CM_ARG },
- { "/string", WR_STRI, 0 }
-};
-static int nfwrtab = (sizeof (fwrtab) / sizeof (struct keytab));
-
-static char blanks[] = "\040\040\040\040"; /* Some blanks for formatting */
-static char * seek_target = NULL;
-
-int
-dofile(op) int op; { /* Do the FILE command */
- char vnambuf[VNAML]; /* Buffer for variable names */
- char *vnp = NULL; /* Pointer to same */
- char zfilnam[CKMAXPATH+2];
- char * p, * m;
- struct FDB fl, sw, nu;
- CK_OFF_T z;
- int rsize, filmode = 0, relative = -1, eofflg = 0;
- int rc, x, y, cx, n, getval, dummy, confirmed, listing = -1;
- int charflag = 0, sizeflag = 0;
- int pad = 32, wr_lpad = 0, wr_rpad = 0, rd_trim = 0, rd_untab = 0;
-
- makestr(&seek_target,NULL);
-
- if (op == XXFILE) { /* FILE command was given */
- /* Get subcommand */
- if ((cx = cmkey(fctab,nfctab,"Operation","",xxstring)) < 0) {
- if (cx == -3) {
- printf("?File operation required\n");
- x = -9;
- }
- return(cx);
- }
- } else { /* Shorthand command was given */
- switch (op) {
- case XXF_CL: cx = FIL_CLS; break; /* FCLOSE */
- case XXF_FL: cx = FIL_FLU; break; /* FFLUSH */
- case XXF_LI: cx = FIL_LIS; break; /* FLIST */
- case XXF_OP: cx = FIL_OPN; break; /* etc... */
- case XXF_RE: cx = FIL_REA; break;
- case XXF_RW: cx = FIL_REW; break;
- case XXF_SE: cx = FIL_SEE; break;
- case XXF_ST: cx = FIL_STA; break;
- case XXF_WR: cx = FIL_WRI; break;
- case XXF_CO: cx = FIL_COU; break;
- default: return(-2);
- }
- }
- switch (cx) { /* Do requested subcommand */
- case FIL_OPN: /* OPEN */
- cmfdbi(&sw, /* Switches */
- _CMKEY, /* fcode */
- "Variable or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nfcswtab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- fcswtab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Anything that doesn't match */
- _CMFLD, /* fcode */
- "Variable", /* hlpmsg */
- "",
- "",
- 0,
- 0,
- NULL,
- NULL,
- NULL
- );
- while (1) {
- x = cmfdb(&sw); /* Parse something */
- if (x < 0) {
- if (x == -3) {
- printf("?Variable name and file name required\n");
- x = -9;
- }
- return(x);
- }
- if (cmresult.fcode == _CMFLD)
- break;
- else if (cmresult.fcode == _CMKEY) {
- char c;
- c = cmgbrk();
- if ((getval =
- (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
-#ifdef COMMENT
- /* Uncomment if we add any switches here that take args */
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9); /* (none do...) */
- }
-#endif /* COMMENT */
- filmode |= cmresult.nresult; /* OR in the file mode */
- } else
- return(-2);
- }
- /* Not a switch - get the string */
- ckstrncpy(vnambuf,cmresult.sresult,VNAML);
- if (!vnambuf[0] || chknum(vnambuf)) { /* (if there is one...) */
- printf("?Variable name required\n");
- return(-9);
- }
- vnp = vnambuf; /* Check variable-name syntax */
- if (vnambuf[0] == CMDQ &&
- (vnambuf[1] == '%' || vnambuf[1] == '&'))
- vnp++;
- y = 0;
- if (*vnp == '%' || *vnp == '&') {
- if ((y = parsevar(vnp,&x,&dummy)) < 0) {
- printf("?Syntax error in variable name\n");
- return(-9);
- }
- }
- /* Assign a negative channel number in case we fail */
- addmac(vnambuf,"-1");
-
- if (!(filmode & FM_RWA)) /* If no access mode specified */
- filmode |= FM_REA; /* default to /READ. */
-
- y = 0; /* Now parse the filename */
- if ((filmode & FM_RWA) == FM_WRI) {
- x = cmofi("Name of new file","",&s,xxstring);
- } else if ((filmode & FM_RWA) == FM_REA) {
- x = cmifi("Name of existing file","",&s,&y,xxstring);
- } else {
- x = cmiofi("Filename","",&s,&y,xxstring);
- debug(F111,"fopen /append x",s,x);
- }
- if (x < 0) {
- if (x == -3) {
- printf("?Filename required\n");
- x = -9;
- }
- return(x);
- }
- if (y) { /* No wildcards */
- printf("?Wildcards not allowed here\n");
- return(-9);
- }
- if (filmode & (FM_APP|FM_WRI)) { /* Check output access */
-#ifndef VMS
- if (zchko(s) < 0) { /* and set error code if denied */
- z_error = FX_ACC;
- printf("?Write access denied - \"%s\"\n",s);
- return(-9);
- }
-#endif /* VMS */
- }
- ckstrncpy(zfilnam,s,CKMAXPATH); /* Is OK - make safe copy */
- if ((x = cmcfm()) < 0) /* Get confirmation of command */
- return(x);
- if ((n = z_open(zfilnam,filmode)) < 0) {
- printf("?OPEN failed - %s: %s\n",zfilnam,ckferror(n));
- return(-9);
- }
- addmac(vnambuf,ckitoa(n)); /* Assign channel number to variable */
- return(success = 1);
-
- case FIL_REW: /* REWIND */
- if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
- if (x == -3) {
- printf("?Channel number required\n");
- x = -9;
- }
- return(x);
- }
- if ((x = cmcfm()) < 0)
- return(x);
- if (n == -9) return(success = 0);
- if (n == -8) return(success = 1);
-
- if ((rc = z_seek(n,0L)) < 0) {
- printf("?REWIND failed - Channel %d: %s\n",n,ckferror(rc));
- return(-9);
- }
- return(success = 1);
-
- case FIL_CLS: /* CLOSE */
-#ifdef COMMENT /* fdc 20100804 - bad idea */
- {
- int i, j, k; /* Supply default if only one open */
- s = "";
- for (k = 0, j = 0, i = 0; i < z_maxchan; i++) {
- if (z_file)
- if (z_file[i])
- if (z_file[i]->z_fp) { k++; j = i; }
- }
- if (k == 1) s = ckitoa(j);
- }
-#endif /* COMMENT */
- cmfdbi(&nu, /* Second FDB - channel number */
- _CMNUM, /* fcode */
- "Channel number or ALL", /* Help message */
- s, /* default */
- "", /* addtl string data */
- 10, /* addtl numeric data 1: radix */
- 0, /* addtl numeric data 2: 0 */
- xxstring, /* Processing function */
- NULL, /* Keyword table */
- &sw /* Pointer to next FDB */
- ); /* Pointer to next FDB */
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "", /* help message */
- "", /* Default */
- "", /* No addtl string data */
- 1, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- fclkwtab, /* Keyword table */
- NULL /* Last in chain */
- );
- x = cmfdb(&nu); /* Parse something */
- if (x < 0) {
- if (x == -3) {
- printf("?Channel number or ALL required\n");
- x = -9;
- }
- return(x);
- }
- if (cmresult.fcode == _CMNUM)
- n = cmresult.nresult;
- else if (cmresult.fcode == _CMKEY)
- n = -1;
- if ((x = cmcfm()) < 0)
- return(x);
- if (n == -9) return(success = 0);
- if (n == -8) return(success = 1);
-
- rc = 1;
- if (n < 0) {
- int count = 0;
- int i;
- for (i = 0; i < z_maxchan; i++) {
- x = z_close(i);
- if (x == FX_SYS) {
- printf("?CLOSE failed - Channel %d: %s\n",n,ckferror(x));
- rc = 0;
- } else if (x > -1)
- count++;
- }
- debug(F101,"FILE CLOSE ALL","",count);
- } else if ((x = z_close(n)) < 0) {
- printf("?CLOSE failed - Channel %d: %s\n",n,ckferror(x));
- return(-9);
- }
- return(success = rc);
-
- case FIL_REA: /* READ */
- case FIL_WRI: /* WRITE */
- rsize = 0;
- cmfdbi(&sw, /* Switches */
- _CMKEY, /* fcode */
- "Channel or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- (cx == FIL_REA) ? nfrdtab : nfwrtab,
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- (cx == FIL_REA) ? frdtab : fwrtab, /* Keyword table */
- &nu /* Pointer to next FDB */
- );
- cmfdbi(&nu, /* Channel number */
- _CMNUM, /* fcode */
- "Channel",
- "", /* default */
- "", /* addtl string data */
- 10, /* addtl numeric data 1: radix */
- 0, /* addtl numeric data 2: 0 */
- xxstring, /* Processing function */
- NULL, /* Keyword table */
- NULL /* Pointer to next FDB */
- );
- do {
- x = cmfdb(&sw); /* Parse something */
- if (x < 0) {
- if (x == -3) {
- printf("?Channel number required\n");
- x = -9;
- }
- return(x);
- }
- if (cmresult.fcode == _CMNUM) /* Channel number */
- break;
- else if (cmresult.fcode == _CMKEY) { /* Switch */
- char c;
- c = cmgbrk();
- if ((getval =
- (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (cmresult.nresult) {
- case WR_LINE:
- charflag = 0;
- sizeflag = 0;
- rsize = 0;
- break;
- case WR_CHAR:
- rsize = 1;
- charflag = 1;
- sizeflag = 1;
- break;
- case WR_SIZE:
- if ((x = cmnum("Bytes","",10,&rsize, xxstring)) < 0) {
- if (x == -3) {
- printf("?Number required\n");
- x = -9;
- }
- return(x);
- }
- if (rsize > LINBUFSIZ) {
- printf("?Maximum FREAD/FWRITE size is %d\n",LINBUFSIZ);
- rsize = 0;
- return(-9);
- }
- charflag = 0;
- sizeflag = 1;
- break;
- case WR_STRI:
- rsize = 1;
- charflag = 0;
- sizeflag = 0;
- break;
- case WR_LPAD:
- case WR_RPAD:
- if ((x = cmnum("Numeric ASCII character value",
- "32",10,&pad, xxstring)) < 0)
- return(x);
- if (cmresult.nresult == WR_LPAD)
- wr_lpad = 1;
- else
- wr_rpad = 1;
- break;
- case RD_TRIM:
- rd_trim = 1;
- break;
- case RD_UNTA:
- rd_untab = 1;
- break;
- }
- debug(F101,"FILE READ rsize 2","",rsize);
- } else
- return(-2);
- } while
- (cmresult.fcode == _CMKEY);
-
- n = cmresult.nresult; /* Channel */
- debug(F101,"FILE READ/WRITE channel","",n);
-
- if (cx == FIL_WRI) { /* WRITE */
- int len = 0;
- if ((x = cmtxt("Text","",&s,xxstring)) < 0)
- return(x);
- if (n == -9) return(success = 0);
- if (n == -8) return(success = 1);
-
- ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
- s = line;
- s = brstrip(s); /* Strip braces */
- if (charflag) { /* Write one char */
- len = 1; /* So length = 1 */
- rsize = 1; /* Don't supply terminator */
- } else if (!sizeflag) { /* Write a string */
- len = -1; /* So length is unspecified */
- } else { /* Write a block of given size */
- int i, k, xx;
- if (rsize > TMPBUFSIZ) {
- z_error = FX_OFL;
- printf("?Buffer overflow\n");
- return(-9);
- }
- len = rsize; /* rsize is really length */
- rsize = 1; /* Don't supply a terminator */
- xx = strlen(s); /* Size of given string */
- if (xx >= len) { /* Bigger or equal */
- s[len] = NUL;
- } else if (wr_lpad) { /* Smaller, left-padding requested */
- for (i = 0; i < len - xx; i++) /* Must make a copy */
- tmpbuf[i] = pad;
- ckstrncpy(tmpbuf+i,s,TMPBUFSIZ-i);
- tmpbuf[len] = NUL;
- s = tmpbuf; /* Redirect write source */
- } else if (wr_rpad) { /* Smaller with right-padding */
- for (i = xx; i < len; i++)
- s[i] = pad;
- s[len] = NUL;
- }
- }
- if ((rc = z_out(n,s,len,rsize)) < 0) { /* Try to write */
- printf("?Channel %d WRITE error: %s\n",n,ckferror(rc));
- return(-9);
- }
- } else { /* FIL_REA READ */
- confirmed = 0;
- vnambuf[0] = NUL;
- x = cmfld("Variable name","",&s,NULL);
- debug(F111,"FILE READ cmfld",s,x);
- if (x < 0) {
- if (x == -3 || !*s) {
- if ((x = cmcfm()) < 0)
- return(x);
- else
- confirmed++;
- } else
- return(x);
- }
- ckstrncpy(vnambuf,s,VNAML);
- debug(F111,"FILE READ vnambuf",vnambuf,confirmed);
- if (vnambuf[0]) { /* Variable name given, check it */
- if (!confirmed) {
- x = cmcfm();
- if (x < 0)
- return(x);
- else
- confirmed++;
- }
- vnp = vnambuf;
- if (vnambuf[0] == CMDQ &&
- (vnambuf[1] == '%' || vnambuf[1] == '&'))
- vnp++;
- y = 0;
- if (*vnp == '%' || *vnp == '&') {
- if ((y = parsevar(vnp,&x,&dummy)) < 0) {
- printf("?Syntax error in variable name\n");
- return(-9);
- }
- }
- }
- debug(F111,"FILE READ variable",vnambuf,confirmed);
-
- if (!confirmed)
- if ((x = cmcfm()) < 0)
- return(x);
-
- if (n == -9) return(success = 0);
- if (n == -8) return(success = 1);
-
- line[0] = NUL; /* Clear destination buffer */
-#ifdef COMMENT
- if (rsize >= LINBUFSIZ) /* Don't overrun it */
- rsize = LINBUFSIZ - 1;
-#endif /* COMMENT */
-
- if (rsize == 0) { /* Read a line */
- rc = z_in(n,line,LINBUFSIZ,LINBUFSIZ-1,0);
- } else {
- rc = z_in(n,line,LINBUFSIZ,rsize,1); /* Read a block */
- }
- if (rc < 0) { /* Error... */
- debug(F101,"FILE READ error","",rc);
- debug(F101,"FILE READ errno","",errno);
- if (rc == FX_EOF) { /* EOF - fail but no error message */
- return(success = 0);
- } else { /* Other error - fail and print msg */
- printf("?READ error: %s\n",ckferror(rc));
- return(-9);
- }
- }
- if (rsize == 0) { /* FREAD /LINE postprocessing */
- if (rd_trim) { /* Trim */
- int i, k;
- k = strlen(line);
- if (k > 0) {
- for (i = k-1; i > 0; i--) {
- if (line[i] == SP || line[i] == '\t')
- line[i] = NUL;
- else
- break;
- }
- }
- }
- if (rd_untab) { /* Untabify */
- if (untabify(line,tmpbuf,TMPBUFSIZ) > -1)
- ckstrncpy(line,tmpbuf,LINBUFSIZ);
- }
- }
- debug(F110,"FILE READ data",line,0);
- if (vnambuf[0]) /* Read OK - If variable name given */
- addmac(vnambuf,line); /* Assign result to variable */
- else /* otherwise */
- printf("%s\n",line); /* just print it */
- }
- return(success = 1);
-
- case FIL_SEE: /* SEEK */
- case FIL_COU: /* COUNT */
- rsize = RD_CHAR; /* Defaults to /BYTE */
- cmfdbi(&sw, /* Switches */
- _CMKEY, /* fcode */
- "Channel or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- ((cx == FIL_SEE) ? nfskswtab : nfcoswtab),
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- ((cx == FIL_SEE) ? fskswtab : fcoswtab),
- &nu /* Pointer to next FDB */
- );
- cmfdbi(&nu, /* Channel number */
- _CMNUM, /* fcode */
- "Channel",
- "", /* default */
- "", /* addtl string data */
- 10, /* addtl numeric data 1: radix */
- 0, /* addtl numeric data 2: 0 */
- xxstring, /* Processing function */
- NULL, /* Keyword table */
- NULL /* Pointer to next FDB */
- );
- do {
- x = cmfdb(&sw); /* Parse something */
- if (x < 0) {
- if (x == -3) {
- printf("?Channel number required\n");
- x = -9;
- }
- return(x);
- }
- if (cmresult.fcode == _CMNUM) /* Channel number */
- break;
- else if (cmresult.fcode == _CMKEY) { /* Switch */
- char c;
- c = cmgbrk();
- if ((getval =
- (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (cx == FIL_SEE) {
- switch (cmresult.nresult) {
- case SEE_REL: relative = 1; break;
- case SEE_ABS: relative = 0; break;
- case SEE_FIND: {
- if (getval) {
- y = cmfld("string or pattern","",&s,xxstring);
- if (y < 0)
- return(y);
- makestr(&seek_target,brstrip(s));
- break;
- }
- }
- default: rsize = cmresult.nresult;
- }
- } else if (cx == FIL_COU) {
- switch (cmresult.nresult) {
- case COU_LIS: listing = 1; break;
- case COU_NOL: listing = 0; break;
- default: rsize = cmresult.nresult;
- }
- }
- }
- } while
- (cmresult.fcode == _CMKEY);
-
- n = cmresult.nresult; /* Channel */
- debug(F101,"FILE SEEK/COUNT channel","",n);
- if (cx == FIL_COU) {
- if ((x = cmcfm()) < 0)
- return(x);
- if (n == -9) return(success = 0);
- if (n == -8) return(success = 1);
-
- z_filcount = z_count(n,rsize);
- if (z_filcount < 0) {
- rc = z_filcount;
- printf("?COUNT error: %s\n",ckferror(rc));
- return(-9);
- }
- if (listing < 0)
- listing = !xcmdsrc;
- if (listing)
- printf(" %ld %s%s\n",
- z_filcount,
- ((rsize == RD_CHAR) ? "byte" : "line"),
- ((z_filcount == 1L) ? "" : "s")
- );
- return(success = (z_filcount > -1) ? 1 : 0);
- }
- m = (rsize == RD_CHAR) ?
- "Number of bytes;\n or keyword" :
- "Number of lines;\n or keyword";
- cmfdbi(&sw, /* SEEK symbolic targets (EOF) */
- _CMKEY, /* fcode */
- m,
- "",
- "", /* addtl string data */
- nfsekwtab, /* addtl numeric data 1: table size */
- 0, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- fsekwtab, /* Keyword table */
- &nu /* Pointer to next FDB */
- );
- cmfdbi(&nu, /* Byte or line number */
- _CMNUW, /* fcode */
- "",
- "", /* default */
- "", /* addtl string data */
- 10, /* addtl numeric data 1: radix */
- 0, /* addtl numeric data 2: 0 */
- xxstring, /* Processing function */
- NULL, /* Keyword table */
- NULL /* Pointer to next FDB */
- );
- x = cmfdb(&sw); /* Parse something */
- if (x < 0) {
- if (x == -3) {
- printf("?Channel number or EOF required\n");
- x = -9;
- }
- return(x);
- }
- if (cmresult.fcode == _CMNUW) {
- z = cmresult.wresult;
- debug(F110,"FILE SEEK atmbuf",atmbuf,0);
- if (relative < 0) {
- if (cx == FIL_SEE && (atmbuf[0] == '+' || atmbuf[0] == '-'))
- relative = 1;
- else
- relative = 0;
- }
- } else if (cmresult.fcode == _CMKEY) {
- eofflg = cmresult.nresult;
- relative = 0;
- y = 0 - eofflg;
- }
- if ((x = cmcfm()) < 0)
- return(x);
- if (n == -9) return(success = 0);
- if (n == -8) return(success = 1);
- y = 1; /* Recycle this */
- z_flush(n);
- debug(F101,"FILE SEEK relative","",relative);
- debug(F101,"FILE SEEK rsize","",rsize);
-
- if (rsize == RD_CHAR) { /* Seek to byte position */
- if (relative > 0) {
- CK_OFF_T pos;
- pos = z_getpos(n);
- if (pos < (CK_OFF_T)0) {
- rc = pos;
- printf("?Relative SEEK failed: %s\n",ckferror(rc));
- return(-9);
- }
- z += pos;
- } else {
- if (z < 0 && !eofflg) { /* Negative arg but not relative */
- y = 0; /* Remember this was bad */
- z = 0; /* but substitute 0 */
- }
- }
- debug(F101,"FILE SEEK /CHAR z","",z);
- if (z < 0 && !eofflg) {
- z_error = FX_RNG;
- return(success = 0);
- }
- if ((rc = z_seek(n,z)) < 0) {
- if (rc == FX_EOF) return(success = 0);
- printf("?SEEK /BYTE failed - Channel %d: %s\n",n,ckferror(rc));
- return(-9);
- }
- } else { /* Seek to line */
- if (relative > 0) {
- CK_OFF_T pos;
- pos = z_getline(n);
- debug(F101,"FILE SEEK /LINE pos","",pos);
- if (pos < 0) {
- rc = pos;
- printf("?Relative SEEK failed: %s\n",ckferror(rc));
- return(-9);
- }
- z += pos;
- }
- debug(F101,"FILE SEEK /LINE z","",z);
- debug(F101,"FILE SEEK /LINE eofflg","",eofflg);
- if (z < 0 && !eofflg) {
- z_error = FX_RNG;
- return(success = 0);
- }
- if ((rc = z_line(n,z)) < 0) {
- if (rc == FX_EOF) return(success = 0);
- printf("?SEEK /LINE failed - Channel %d: %s\n",n,ckferror(rc));
- return(-9);
- }
- }
- /*
- Now, having sought to the desired starting spot, if a /FIND:
- target was specified, look for it now.
- */
- if (seek_target) {
- int flag = 0, ispat = 0, matchresult = 0;
- while (!flag) {
- y = z_in(n,line,LINBUFSIZ,LINBUFSIZ-1,0);
- if (y < 0) {
- y = 0;
- break;
- }
- if (ispattern(seek_target)) {
- matchresult = ckmatch(seek_target,line,inpcas[cmdlvl],1+4);
- } else {
- /* This is faster */
- matchresult = ckindex(seek_target,line,0,0,inpcas[cmdlvl]);
- }
- if (matchresult) {
- flag = 1;
- break;
- }
- }
- if (flag) {
- debug(F111,"FSEEK HAVE MATCH",seek_target,z_getline(n));
- /* Back up to beginning of line where target found */
- if ((y = z_line(n,z_getline(n)-1)) < 0) {
- if (rc == FX_EOF) return(success = 0);
- printf("?SEEK /LINE failed - Channel %d: %s\n",
- n,ckferror(rc));
- return(-9);
- }
- debug(F101,"FSEEK LINE","",y);
- }
- }
- return(success = (y < 0) ? 0 : 1);
-
- case FIL_LIS: { /* LIST open files */
-#ifdef CK_TTGWSIZ
- extern int cmd_rows, cmd_cols;
-#endif /* CK_TTGWSIZ */
- extern int xaskmore;
- int i, x, n = 0, paging = 0;
- char * s;
-
- if ((x = cmcfm()) < 0)
- return(x);
-
-#ifdef CK_TTGWSIZ
- if (cmd_rows > 0 && cmd_cols > 0)
-#endif /* CK_TTGWSIZ */
- paging = xaskmore;
-
- printf("System open file limit:%5d\n", z_openmax);
- printf("Maximum for FILE OPEN: %5d\n", z_maxchan);
- printf("Files currently open: %5d\n\n", z_nopen);
- n = 4;
- for (i = 0; i < z_maxchan; i++) {
- s = z_getname(i); /* Got one? */
- if (s) { /* Yes */
- char m[8];
- m[0] = NUL;
- printf("%2d. %s",i,s); /* Print name */
- n++; /* Count it */
- x = z_getmode(i); /* Get modes & print them */
- if (x > 0) {
- if (x & FM_REA) ckstrncat(m,"R",8);
- if (x & FM_WRI) ckstrncat(m,"W",8);
- if (x & FM_APP) ckstrncat(m,"A",8);
- if (x & FM_BIN) ckstrncat(m,"B",8);
- if (m[0])
- printf(" (%s)",m);
- if (x & FM_EOF)
- printf(" [EOF]");
- else /* And file position too */
- printf(" %s",ckfstoa(z_getpos(i)));
- }
- printf("\n");
-#ifdef CK_TTGWSIZ
- if (paging > 0) { /* Pause at end of screen */
- if (n > cmd_rows - 3) {
- if (!askmore())
- break;
- else
- n = 0;
- }
- }
-#endif /* CK_TTGWSIZ */
- }
- }
- return(success = 1);
- }
-
- case FIL_FLU: /* FLUSH */
- if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
- if (x == -3) {
- printf("?Channel number required\n");
- x = -9;
- }
- return(x);
- }
- if ((x = cmcfm()) < 0)
- return(x);
- if (n == -9) return(success = 0);
- if (n == -8) return(success = 1);
- if ((rc = z_flush(n)) < 0) {
- printf("?FLUSH failed - Channel %d: %s\n",n,ckferror(rc));
- return(-9);
- }
- return(success = 1);
-
- case FIL_STA: /* STATUS */
- {
- int i, j, k; /* Supply default if only one open */
- s = "";
- for (k = 0, j = 0, i = 0; i < z_maxchan; i++) {
- if (z_file)
- if (z_file[i])
- if (z_file[i]->z_fp) { k++; j = i; }
- }
- if (k == 1) s = ckitoa(j);
- }
- if ((x = cmnum("Channel number",s,10,&n, xxstring)) < 0) {
- if (x == -3) {
- if (z_nopen > 1) {
- printf("?%d files open - please supply channel number\n",
- z_nopen);
- return(-9);
- }
- } else
- return(x);
- }
- if ((y = cmcfm()) < 0)
- return(y);
- if ((!z_file || z_nopen == 0) && x == -3) {
- printf("No files open\n");
- return(success = 1);
- }
- p = blanks + 3; /* Tricky formatting... */
- if (n < 1000) p--;
- if (n < 100) p--;
- if (n < 10) p--;
- if ((rc = z_getmode(n)) < 0) {
- printf("Channel %d:%s%s\n",n,p,ckferror(rc));
- return(success = 0);
- } else if (!rc) {
- printf("Channel %d:%sNot open\n",n,p);
- return(success = 0);
- } else {
- CK_OFF_T xx;
- s = z_getname(n);
- if (!s) s = "(name unknown)";
- printf("Channel %d:%sOpen\n",n,p);
- printf(" File: %s\n Modes: ",s);
- if (rc & FM_REA) printf(" /READ");
- if (rc & FM_WRI) printf(" /WRITE");
- if (rc & FM_APP) printf(" /APPEND");
- if (rc & FM_BIN) printf(" /BINARY");
- if (rc & FM_CMD) printf(" /COMMAND");
- if (rc & FM_EOF) printf(" [EOF]");
- printf("\n Size: %s\n",ckfstoa(z_count(n,RD_CHAR)));
- printf(" At byte: %s\n",ckfstoa(z_getpos(n)));
- xx = z_getline(n);
- if (xx > (CK_OFF_T)-1)
- printf(" At line: %s\n",ckfstoa(xx));
- return(success = 1);
- }
- default:
- return(-2);
- }
-}
-#endif /* CKCHANNELIO */
-
-#ifndef NOSETKEY
-/* Save Key maps and in OS/2 Mouse maps */
-int
-savkeys(name,disp) char * name; int disp; {
- char *tp;
- static struct filinfo xx;
- int savfil, i, j, k;
- char buf[1024];
-
- zclose(ZMFILE);
-
- if (disp) {
- xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
- xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = "";
- xx.lblopts = 0;
- savfil = zopeno(ZMFILE,name,NULL,&xx);
- } else savfil = zopeno(ZMFILE,name,NULL,NULL);
-
- if (savfil) {
-#ifdef OS2
- ztime(&tp);
- zsout(ZMFILE, "; Kermit 95 SAVE KEYMAP file: ");
- zsoutl(ZMFILE,tp);
- if (mskkeys) {
- zsoutl(ZMFILE,
- "if eq \"\\v(program)\" \"C-Kermit\" set mskermit keycodes on");
- } else {
- zsoutl(ZMFILE,
- "if NOT eq \"\\v(program)\" \"C-Kermit\" stop 1 C-Kermit required.");
- zsoutl(ZMFILE,"set mskermit keycodes off");
- }
- zsoutl(ZMFILE,"");
-#else /* OS2 */
- ztime(&tp);
- zsout(ZMFILE, "; C-Kermit SAVE KEYMAP file: ");
- zsoutl(ZMFILE,tp);
-#endif /* OS2 */
-
- zsoutl(ZMFILE,"; Clear previous keyboard mappings ");
- zsoutl(ZMFILE,"set key clear");
-#ifdef OS2
- for (k = 0; k < nttkey; k++) {
- if (!ttkeytab[k].flgs) {
- ckmakmsg(buf,1024,
- "set terminal key ",
- ttkeytab[k].kwd,
- " clear",
- NULL
- );
- zsoutl(ZMFILE,buf);
- }
- }
-#endif /* OS2 */
- zsoutl(ZMFILE,"");
-
- for (i = 0; i < KMSIZE; i++) {
- if (macrotab[i]) {
- int len = strlen((char *)macrotab[i]);
-#ifdef OS2
- ckmakmsg(buf,
- 1024,
- "set key \\",
- ckitoa(mskkeys ? cktomsk(i) : i),
- " ",
- NULL
- );
-#else /* OS2 */
- ckmakmsg(buf,
- 1024,
- "set key \\",
- ckitoa(i),
- NULL,NULL
- );
-#endif /* OS2 */
- zsout(ZMFILE,buf);
-
- for (j = 0; j < len; j++) {
- char ch = macrotab[i][j];
- if (ch <= SP || ch >= DEL ||
- ch == '-' || ch == ',' ||
- ch == '{' || ch == '}' ||
- ch == ';' || ch == '?' ||
- ch == '.' || ch == '\'' ||
- ch == '\\' || ch == '/' ||
- ch == '#') {
- ckmakmsg(buf,1024,"\\{",ckitoa((int)ch),"}",NULL);
- zsout(ZMFILE,buf);
- } else {
- ckmakmsg(buf,1024,ckctoa((char)ch),NULL,NULL,NULL);
- zsout(ZMFILE,buf);
- }
- }
-#ifdef OS2
- ckmakmsg(buf,1024,"\t; ",keyname(i),NULL,NULL);
- zsoutl(ZMFILE,buf);
-#else
- zsoutl(ZMFILE,"");
-#endif /* OS2 */
- } else if ( keymap[i] != i ) {
-#ifndef NOKVERBS
- if (IS_KVERB(keymap[i])) {
- for (j = 0; j < nkverbs; j++)
- if (kverbs[j].kwval == (keymap[i] & ~F_KVERB))
- break;
- if (j != nkverbs) {
-#ifdef OS2
-#ifdef COMMENT
- sprintf(buf, "set key \\%d \\K%s\t; %s",
- mskkeys ? cktomsk(i) : i,
- kverbs[j].kwd, keyname(i)
- );
-#else
- ckmakxmsg(buf, /* 12 string args */
- 1024,
- "set key \\",
- ckitoa(mskkeys ? cktomsk(i) : i),
- " \\K",
- kverbs[j].kwd,
- "\t; ",
- keyname(i),
- NULL, NULL, NULL, NULL, NULL, NULL);
-#endif /* COMMENT */
- zsoutl(ZMFILE,buf);
-#else
-#ifdef COMMENT
- sprintf(buf, "set key \\%d \\K%s", i, kverbs[j].kwd);
-#else
- ckmakmsg(buf,1024,
- "set key \\",
- ckitoa(i),
- " \\K",
- kverbs[j].kwd
- );
-#endif /* COMMENT */
- zsoutl(ZMFILE,buf);
-#endif
- }
- } else
-#endif /* NOKVERBS */
- {
-#ifdef OS2
-#ifdef COMMENT
- sprintf(buf, "set key \\%d \\{%d}\t; %s",
- mskkeys ? cktomsk(i) : i,
- keymap[i],
- keyname(i)
- );
-#else
- ckmakxmsg(buf, /* 8 string args */
- 1024,
- "set key \\",
- ckitoa(mskkeys ? cktomsk(i) : i),
- " \\{",
- ckitoa(keymap[i]),
- "}\t; ",
- keyname(i),
- NULL,NULL,NULL,NULL,NULL,NULL);
-#endif /* COMMENT */
- zsoutl(ZMFILE,buf);
-#else
-#ifdef COMMENT
- sprintf(buf, "set key \\%d \\{%d}", i, keymap[i]);
-#else
- ckmakxmsg(buf,1024,
- "set key \\",
- ckitoa(i),
- " \\{",
- ckitoa(keymap[i]),
- "}",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
-#endif /* COMMENT */
- zsoutl(ZMFILE,buf);
-#endif /* OS2 */
- }
- }
- }
-#ifdef OS2
- /* OS/2 also has the SET TERMINAL KEY <termtype> defines */
- for (k = 0; k < nttkey; k++) {
- extern struct keynode * ttkeymap[];
- struct keynode * pnode = NULL;
-
- if (ttkeytab[k].flgs) /* Don't process CM_INV or CM_ABR */
- continue;
-
- zsoutl(ZMFILE,"");
- ckmakmsg(buf,1024,"; SET TERMINAL KEY ",ttkeytab[k].kwd,NULL,NULL);
- zsoutl(ZMFILE,buf);
-
- for (pnode = ttkeymap[ttkeytab[k].kwval];
- pnode;
- pnode = pnode->next
- ) {
- switch (pnode->def.type) {
- case key:
-#ifdef COMMENT
- sprintf(buf, "set terminal key %s \\%d \\{%d}\t; %s",
- ttkeytab[k].kwd,
- mskkeys ? cktomsk(pnode->key) : pnode->key,
- pnode->def.key.scancode,
- keyname(pnode->key)
- );
-#else
- ckmakxmsg(buf,
- 1024,
- "set terminal key ",
- ttkeytab[k].kwd,
- " \\",
- ckitoa(mskkeys ?
- cktomsk(pnode->key) :
- pnode->key),
- " \\{",
- ckitoa(pnode->def.key.scancode),
- "}\t; ",
- keyname(pnode->key),
- NULL,NULL,NULL,NULL
- );
-#endif /* COMMENT */
- zsoutl(ZMFILE,buf);
- break;
- case kverb:
- for (j = 0; j < nkverbs; j++)
- if (kverbs[j].kwval == (pnode->def.kverb.id & ~F_KVERB))
- break;
- if (j != nkverbs) {
-#ifdef COMMENT
- sprintf(buf, "set terminal key %s \\%d \\K%s\t; %s",
- ttkeytab[k].kwd,
- mskkeys ? cktomsk(pnode->key) : pnode->key,
- kverbs[j].kwd, keyname(pnode->key)
- );
-#else
- ckmakxmsg(buf,
- 1024,
- "set terminal key ",
- ttkeytab[k].kwd,
- " \\",
- ckitoa(mskkeys ?
- cktomsk(pnode->key) :
- pnode->key),
- " \\K",
- kverbs[j].kwd,
- "\t; ",
- keyname(pnode->key),
- NULL,NULL,NULL,NULL
- );
-#endif /* COMMENT */
- zsoutl(ZMFILE,buf);
- }
- break;
- case macro: {
- int len = strlen((char *)pnode->def.macro.string);
-#ifdef COMMENT
- sprintf(buf,"set terminal key %s \\%d ",
- ttkeytab[k].kwd,
- mskkeys ? cktomsk(pnode->key) : pnode->key);
-#else
- ckmakxmsg(buf,
- 1024,
- "set terminal key ",
- ttkeytab[k].kwd,
- " \\",
- ckitoa(mskkeys ?
- cktomsk(pnode->key) :
- pnode->key),
- " ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
-#endif /* COMMENT */
- zsout(ZMFILE,buf);
-
- for (j = 0; j < len; j++) {
- char ch = pnode->def.macro.string[j];
- if (ch <= SP || ch >= DEL ||
- ch == '-' || ch == ',' ||
- ch == '{' || ch == '}' ||
- ch == ';' || ch == '?' ||
- ch == '.' || ch == '\'' ||
- ch == '\\' || ch == '/' ||
- ch == '#') {
- ckmakmsg(buf,1024,
- "\\{",ckitoa((int)ch),"}",NULL);
- zsout(ZMFILE,buf);
- } else {
- ckmakmsg(buf,1024,
- ckctoa((char)ch),NULL,NULL,NULL);
- zsout(ZMFILE,buf);
- }
- }
- ckmakmsg(buf,1024,"\t; ",keyname(pnode->key),NULL,NULL);
- zsoutl(ZMFILE,buf);
- break;
- }
- case literal: {
- int len = strlen((char *)pnode->def.literal.string);
-#ifdef COMMENT
- sprintf(buf,"set terminal key %s /literal \\%d ",
- ttkeytab[k].kwd,
- mskkeys ? cktomsk(pnode->key) : pnode->key);
-#else
- ckmakxmsg(buf,
- 1024,
- "set terminal key ",
- ttkeytab[k].kwd,
- " /literal \\",
- ckitoa(mskkeys ?
- cktomsk(pnode->key) :
- pnode->key),
- " ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
-#endif /* COMMENT */
- zsout(ZMFILE,buf);
-
- for (j = 0; j < len; j++) {
- char ch = pnode->def.literal.string[j];
- if (ch <= SP || ch >= DEL ||
- ch == '-' || ch == ',' ||
- ch == '{' || ch == '}' ||
- ch == ';' || ch == '?' ||
- ch == '.' || ch == '\'' ||
- ch == '\\' || ch == '/' ||
- ch == '#') {
- ckmakmsg(buf,1024,
- "\\{",ckitoa((int)ch),"}",NULL);
- zsout(ZMFILE,buf);
- } else {
- ckmakmsg(buf,1024,
- ckctoa((char)ch),NULL,NULL,NULL);
- zsout(ZMFILE,buf);
- }
- }
- ckmakmsg(buf,1024,"\t; ",keyname(pnode->key),NULL,NULL);
- zsoutl(ZMFILE,buf);
- break;
- }
- case esc:
-#ifdef COMMENT
- sprintf(buf,
- "set terminal key %s /literal \\%d \\{%d}\\{%d}\t; %s",
- ttkeytab[k].kwd,
- mskkeys ? cktomsk(pnode->key) : pnode->key,
- ISDG200(ttkeytab[k].kwval) ? 30 : 27,
- pnode->def.esc.key & ~F_ESC,
- keyname(pnode->key)
- );
-#else
- ckmakxmsg(buf,
- 1024,
- "set terminal key ",
- ttkeytab[k].kwd,
- " /literal \\",
- ckitoa(mskkeys ?
- cktomsk(pnode->key) :
- pnode->key),
- " \\{",
- ckitoa(ISDG200(ttkeytab[k].kwval) ? 30 : 27),
- "}\\{",
- ckitoa(pnode->def.esc.key & ~F_ESC),
- "}\t; ",
- keyname(pnode->key),
- NULL,NULL
- );
-#endif /* COMMENT */
- zsoutl(ZMFILE,buf);
- break;
- case csi:
-#ifdef COMMENT
- sprintf(buf,
- "set terminal key %s /literal \\%d \\{27}[\\{%d}\t; %s",
- ttkeytab[k].kwd,
- mskkeys ? cktomsk(pnode->key) : pnode->key,
- pnode->def.csi.key & ~F_CSI,
- keyname(pnode->key)
- );
-#else
- ckmakxmsg(buf,
- 1024,
- "set terminal key ",
- ttkeytab[k].kwd,
- " /literal \\",
- ckitoa(mskkeys ?
- cktomsk(pnode->key) :
- pnode->key),
- " \\{27}[\\{",
- ckitoa(pnode->def.csi.key & ~F_CSI),
- "}\t; ",
- keyname(pnode->key),
- NULL,NULL,NULL,NULL
- );
-#endif /* COMMENT */
- zsoutl(ZMFILE,buf);
- break;
- default:
- continue;
- }
- }
- }
-#endif /* OS2 */
-
- zsoutl(ZMFILE,"");
- zsoutl(ZMFILE,"; End");
- zclose(ZMFILE);
- return(success = 1);
- } else {
- return(success = 0);
- }
-}
-#endif /* NOSETKEY */
-
-#define SV_SCRL 0
-#define SV_HIST 1
-
-#ifdef OS2
-#ifndef NOLOCAL
-static struct keytab trmtrmopt[] = {
- { "scrollback", SV_SCRL, 0 }
-};
-#endif /* NOLOCAL */
-#endif /* OS2 */
-
-static struct keytab cmdtrmopt[] = {
-#ifdef CK_RECALL
- { "history", SV_HIST, 0 },
-#endif /* CK_RECALL */
-#ifdef OS2
-#ifndef NOLOCAL
- { "scrollback", SV_SCRL, 0 },
-#endif /* NOLOCAL */
-#endif /* OS2 */
- { "", 0, 0 }
-};
-static int ncmdtrmopt = (sizeof (cmdtrmopt) / sizeof (struct keytab)) - 1;
-
-#ifdef OS2
-#ifndef NOLOCAL
-_PROTOTYP(int savscrbk, (int, char *, int));
-#endif /* NOLOCAL */
-#endif /* OS2 */
-
-#ifdef CK_RECALL
-_PROTOTYP(int savhistory, (char *, int));
-#endif /* CK_RECALL */
-
-int
-dosave(xx) int xx; {
- int x, y = 0, disp;
- char * s = NULL;
- extern struct keytab disptb[];
-#ifdef ZFNQFP
- struct zfnfp * fnp;
-#endif /* ZFNQFP */
-
-#ifndef NOSETKEY
- if (xx == XSKEY) { /* SAVE KEYMAP.. */
- z = cmofi("Name of Kermit command file","keymap.ksc",&s,xxstring);
- } else {
-#endif /* NOSETKEY */
- switch (xx) {
- case XSCMD: /* SAVE COMMAND.. */
- if ((y = cmkey(cmdtrmopt, ncmdtrmopt, "What to save",
-#ifdef OS2
- "scrollback",
-#else
- "history",
-#endif /* OS2 */
- xxstring)) < 0)
- return(y);
- break;
-#ifdef OS2
-#ifndef NOLOCAL
- case XSTERM: /* SAVE TERMINAL.. */
- if ((y = cmkey(trmtrmopt,1,
- "What to save","scrollback",xxstring)) < 0)
- return(y);
- break;
-#endif /* NOLOCAL */
-#endif /* OS2 */
- }
- z = cmofi("Filename",
- ((y == SV_SCRL) ? "scrollbk.txt" : "history.txt"),
- &s,
- xxstring
- );
-#ifndef NOSETKEY
- }
-#endif /* NOSETKEY */
- if (z < 0) /* Check output-file parse results */
- return(z);
- if (z == 2) {
- printf("?Sorry, %s is a directory name\n",s);
- return(-9);
- }
-#ifdef ZFNQFP
- if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {/* Convert to full pathname */
- if (fnp->fpath)
- if ((int) strlen(fnp->fpath) > 0)
- s = fnp->fpath;
- }
-#endif /* ZFNQFP */
-
- ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of pathname */
- s = line;
-#ifdef MAC
- z = 0;
-#else
- /* Get NEW/APPEND disposition */
- if ((z = cmkey(disptb,2,"Disposition","new",xxstring)) < 0)
- return(z);
-#endif /* MAC */
- disp = z;
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
-
- switch (xx) { /* Do action.. */
-#ifndef NOSETKEY
- case XSKEY: /* SAVE KEYMAP */
- return (savkeys(s,disp));
-#endif /* NOSETKEY */
-
- case XSCMD: /* SAVE COMMAND.. */
-#ifdef OS2
-#ifndef NOLOCAL
- if (y == SV_SCRL) /* .. SCROLLBACK */
- return(success = savscrbk(VCMD,s,disp));
-#endif /* NOLOCAL */
-#endif /* OS2 */
-#ifndef NORECALL
- if (y == SV_HIST) /* .. HISTORY */
- return(success = savhistory(s,disp));
-#endif /* NORECALL */
- break;
-
-#ifdef OS2
-#ifndef NOLOCAL
- case XSTERM: /* SAVE TERMINAL SCROLLBACK */
- return(success = savscrbk(VTERM,s,disp));
-#endif /* NOLOCAL */
-#endif /* OS2 */
- }
- success = 0;
- return(-2);
-}
-
-/*
- R E A D T E X T
-
- Read text with a custom prompt into given buffer using command parser but
- with no echoing or entry into recall buffer.
-*/
-int
-readtext(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
-#ifdef CK_RECALL
- extern int on_recall; /* Around Password prompting */
-#endif /* CK_RECALL */
- int rc;
-#ifndef NOLOCAL
-#ifdef OS2
- extern int vmode;
- extern int startflags;
- int vmode_sav = vmode;
-
- if (!prmpt) prmpt = "";
-
- if (win95_popup && !(startflags & 96)
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- )
- return(popup_readtext(vmode,NULL,prmpt,buffer,bufsiz,0));
-
- if (vmode == VTERM) {
- vmode = VCMD;
- VscrnIsDirty(VTERM);
- VscrnIsDirty(VCMD);
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifdef CK_RECALL
- on_recall = 0;
-#endif /* CK_RECALL */
- cmsavp(psave,PROMPTL); /* Save old prompt */
- cmsetp(prmpt); /* Make new prompt */
- concb((char)escape); /* Put console in cbreak mode */
- cmini(1); /* and echo mode */
- if (pflag) prompt(xxstring); /* Issue prompt if at top level */
- cmres(); /* Reset the parser */
- for (rc = -1; rc < 0; ) { /* Prompt till they answer */
- rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
- cmres(); /* Reset the parser again */
- }
- ckstrncpy(buffer,s,bufsiz);
- cmsetp(psave); /* Restore original prompt */
-
-#ifndef NOLOCAL
-#ifdef OS2
- if (vmode != vmode_sav) {
- vmode = VTERM;
- VscrnIsDirty(VCMD);
- VscrnIsDirty(VTERM);
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
- return(0);
-}
-#endif /* NOICP */
-
-/* A general function to allow a Password or other information */
-/* to be read from the command prompt without it going into */
-/* the recall buffer or being echo'd. */
-
-int
-readpass(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
- int x;
-#ifdef NOICP
- if (!prmpt) prmpt = "";
- printf("%s", prmpt);
-#ifdef COMMENT
- /* Some linkers won't allow this because it's unsafe */
- gets(buffer);
-#else /* COMMENT */
- {
- int c, i; char * p;
- p = buffer;
- for (i = 0; i < bufsiz-1; i++) {
- if ((c = getchar()) == EOF)
- break;
- if (c < SP)
- break;
- buffer[i] = c;
- }
- buffer[i] = NUL;
- }
-#endif /* COMMENT */
- return(1);
-#else /* NOICP */
-#ifdef CK_RECALL
- extern int on_recall; /* around Password prompting */
-#endif /* CK_RECALL */
- int rc;
-#ifndef NOLOCAL
-#ifdef OS2
- extern int vmode;
- extern int startflags;
- int vmode_sav = vmode;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef CKSYSLOG
- int savlog;
-#endif /* CKSYSLOG */
- if (!prmpt) prmpt = "";
-#ifndef NOLOCAL
- debok = 0; /* Don't log */
-#ifdef OS2
- if (win95_popup && !(startflags & 96)
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- ) {
- x = popup_readpass(vmode,NULL,prmpt,buffer,bufsiz,0);
- debok = 1;
- return(x);
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifdef CKSYSLOG
- savlog = ckxsyslog; /* Save and turn off syslogging */
- ckxsyslog = 0;
-#endif /* CKSYSLOG */
-#ifndef NOLOCAL
-#ifdef OS2
- if (vmode == VTERM) {
- vmode = VCMD;
- VscrnIsDirty(VTERM);
- VscrnIsDirty(VCMD);
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef CK_RECALL
- on_recall = 0;
-#endif /* CK_RECALL */
- cmsavp(psave,PROMPTL); /* Save old prompt */
- cmsetp(prmpt); /* Make new prompt */
- concb((char)escape); /* Put console in cbreak mode */
- cmini(0); /* and no-echo mode */
- if (pflag) prompt(xxstring); /* Issue prompt if at top level */
- cmres(); /* Reset the parser */
- for (rc = -1; rc < 0; ) { /* Prompt till they answer */
- rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
- cmres(); /* Reset the parser again */
- }
- ckstrncpy(buffer,s,bufsiz);
- printf("\r\n"); /* Echo a CRLF */
- cmsetp(psave); /* Restore original prompt */
- cmini(1); /* Restore echo mode */
-#ifndef NOLOCAL
-#ifdef OS2
- if (vmode != vmode_sav) {
- vmode = VTERM;
- VscrnIsDirty(VCMD);
- VscrnIsDirty(VTERM);
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef CKSYSLOG
- ckxsyslog = savlog; /* Restore syslogging */
-#endif /* CKSYSLOG */
- debok = 1;
- return(0);
-#endif /* NOICP */
-}
-
-#ifndef NOICP
-struct keytab authtab[] = { /* Available authentication types */
-#ifdef CK_KERBEROS
- { "k4", AUTH_KRB4, CM_INV },
- { "k5", AUTH_KRB5, CM_INV },
- { "kerberos4", AUTH_KRB4, 0 },
- { "kerberos5", AUTH_KRB5, 0 },
- { "krb4", AUTH_KRB4, CM_INV },
- { "krb5", AUTH_KRB5, CM_INV },
-#endif /* CK_KERBEROS */
-#ifdef NT
- { "ntlm", AUTH_NTLM, 0 },
-#endif /* NT */
-#ifdef CK_SRP
- { "srp", AUTH_SRP, 0 },
-#endif /* CK_SRP */
-#ifdef CK_SSL
- { "ssl", AUTH_SSL, 0 },
-#endif /* CK_SSL */
- { "", 0, 0 }
-};
-int authtabn = sizeof(authtab)/sizeof(struct keytab)-1;
-
-#ifdef CK_KERBEROS
-struct keytab kerbtab[] = { /* Kerberos authentication types */
- { "k4", AUTH_KRB4, CM_INV },
- { "k5", AUTH_KRB5, CM_INV },
- { "kerberos4", AUTH_KRB4, 0 },
- { "kerberos5", AUTH_KRB5, 0 },
- { "krb4", AUTH_KRB4, CM_INV },
- { "krb5", AUTH_KRB5, CM_INV }
-};
-int kerbtabn = sizeof(kerbtab)/sizeof(struct keytab);
-
-static struct keytab krb_s_tbl[] = { /* AUTHENTICATE command switches: */
- { "/cache", KRB_S_CA, CM_ARG }
-};
-static int krb_s_n = sizeof(krb_s_tbl)/sizeof(struct keytab);
-
-static struct keytab krb_v_tbl[] = { /* KERBEROS version values: */
- { "4", 4, 0 },
- { "5", 5, 0 }, /* (add others as needed...) */
- { "auto", 0, 0 } /* Note: 0 = auto */
-};
-static int krb_v_n = sizeof(krb_v_tbl)/sizeof(struct keytab);
-
-static struct keytab krb_a_tbl[] = { /* KERBEROS actions: */
- { "destroy", KRB_A_DE, 0 },
- { "initialize", KRB_A_IN, 0 },
- { "list-credentials", KRB_A_LC, 0 }
-};
-static int krb_a_n = sizeof(krb_a_tbl)/sizeof(struct keytab);
-
-static struct keytab krb4_i_tbl[] = { /* KERBEROS 4 INITIALIZE switches: */
- { "/brief", KRB_I_BR, 0 }, /* /BRIEF */
- { "/instance", KRB_I_IN, CM_ARG }, /* /INSTANCE: */
- { "/lifetime", KRB_I_LF, CM_ARG }, /* /LIFETIME: */
- { "/not-preauth", KRB_I_NPA, 0 }, /* /NOT-PREAUTH */
- { "/password", KRB_I_PW, CM_ARG }, /* /PASSWORD: */
-#ifdef OS2
- { "/popup", KRB_I_POP, 0 }, /* /POPUP */
-#endif /* OS2 */
- { "/preauth", KRB_I_PA, 0 }, /* /PREAUTH */
- { "/realm", KRB_I_RL, CM_ARG }, /* /REALM: */
- { "/verbose", KRB_I_VB, 0 }, /* /VERBOSE */
- { "", 0, 0 }
-};
-static int krb4_i_n = sizeof(krb4_i_tbl)/sizeof(struct keytab) - 1;
-
-static struct keytab krb5_i_tbl[] = { /* KERBEROS 5 INITIALIZE switches: */
- { "/addresses", KRB_I_ADR, CM_ARG },
- { "/forwardable", KRB_I_FW, 0 }, /* /FORWARDABLE */
- { "/instance", KRB_I_IN, CM_ARG }, /* /INSTANCE: */
- { "/k4", KRB_I_K4, CM_INV }, /* /KERBEROS4 */
- { "/kerberos4", KRB_I_K4, 0 }, /* /KERBEROS4 */
- { "/krb4", KRB_I_K4, CM_INV }, /* /KERBEROS4 */
- { "/lifetime", KRB_I_LF, CM_ARG }, /* /LIFETIME: */
- { "/no-addresses", KRB_I_NAD, 0 }, /* /NO-ADDRESSES */
- { "/no-k4", KRB_I_NK4, CM_INV },/* /NO-KERBEROS4 */
- { "/no-kerberos4", KRB_I_NK4, 0 }, /* /NO-KERBEROS4 */
- { "/no-krb4", KRB_I_NK4, CM_INV },/* /NO-KERBEROS4 */
- { "/not-forwardable", KRB_I_NFW, 0 }, /* /NOT-FORWARDABLE */
- { "/not-proxiable", KRB_I_NPR, 0 }, /* /NOT-PROXIABLE */
- { "/password", KRB_I_PW, CM_ARG }, /* /PASSWORD: */
-#ifdef OS2
- { "/popup", KRB_I_POP, 0 }, /* /POPUP */
-#endif /* OS2 */
- { "/postdate", KRB_I_PD, CM_ARG }, /* /POSTDATE: */
- { "/pr", KRB_I_PR, CM_INV|CM_ABR }, /* to allow for */
- { "/pro", KRB_I_PR, CM_INV|CM_ABR }, /* different spellings */
- { "/prox", KRB_I_PR, CM_INV|CM_ABR },
- { "/proxiable", KRB_I_PR, 0 }, /* /PROXIABLE */
- { "/proxyable", KRB_I_PR, CM_INV }, /* /PROXYABLE */
- { "/realm", KRB_I_RL, CM_ARG }, /* /REALM: */
- { "/renew", KRB_I_RN, 0 }, /* /RENEW */
- { "/renewable", KRB_I_RB, CM_ARG }, /* /RENEWABLE: */
- { "/service", KRB_I_SR, CM_ARG }, /* /SERVICE: */
- { "/validate", KRB_I_VA, 0 }, /* /VALIDATE */
- { "", 0, 0 }
-};
-static int krb5_i_n = sizeof(krb5_i_tbl)/sizeof(struct keytab) - 1;
-
-static struct keytab klctab[] = { /* List Credentials switches*/
- { "/addresses", XYKLCAD, 0 },
- { "/encryption", XYKLCEN, 0 },
- { "/flags", XYKLCFL, 0 }
-};
-static int nklctab = sizeof(klctab)/sizeof(struct keytab);
-
-extern int krb_action;
-extern struct krb_op_data krb_op;
-
-extern struct krb5_list_cred_data krb5_lc;
-extern struct krb5_init_data krb5_init;
-extern char * krb5_d_principal; /* Default principal */
-extern char * krb5_d_instance;
-extern char * krb5_d_realm; /* Default realm */
-extern char * krb5_d_cc; /* Default credentials cache */
-extern char * krb5_d_srv; /* Default service name */
-extern int krb5_d_lifetime; /* Default lifetime */
-extern int krb5_d_forwardable;
-extern int krb5_d_proxiable;
-extern int krb5_d_renewable;
-extern int krb5_autoget;
-extern int krb5_autodel;
-extern int krb5_d_getk4;
-extern int krb5_d_no_addresses;
-extern int krb5_checkaddrs;
-extern char * krb5_d_addrs[];
-extern char * k5_keytab; /* Keytab file */
-
-extern struct krb4_init_data krb4_init;
-extern char * krb4_d_principal; /* Default principal */
-extern char * krb4_d_realm; /* Default realm */
-extern char * krb4_d_srv; /* Default service name */
-extern int krb4_d_lifetime; /* Default lifetime */
-extern int krb4_d_preauth;
-extern char * krb4_d_instance;
-extern int krb4_autoget;
-extern int krb4_autodel;
-extern int krb4_checkaddrs;
-extern char * k4_keytab; /* Keytab file */
-#endif /* CK_KERBEROS */
-
-#ifndef NOSHOW
-int
-sho_iks() {
-#ifdef IKSDCONF
-#ifdef CK_LOGIN
- extern int ckxsyslog, ckxwtmp, ckxanon;
-#ifdef UNIX
- extern int ckxpriv;
-#endif /* UNIX */
-#ifdef CK_PERMS
- extern int ckxperms;
-#endif /* CK_PERMS */
- extern char * anonfile, * userfile, * anonroot;
-#ifdef OS2
- extern char * anonacct;
-#endif /* OS2 */
-#ifdef NT
- extern char * iks_domain;
-#endif /* NT */
-#endif /* CK_LOGIN */
-#ifdef CKWTMP
- extern char * wtmpfile;
-#endif /* CKWTMP */
-#ifdef IKSDB
- extern char * dbfile;
- extern int dbenabled;
-#endif /* IKSDB */
-#ifdef CK_LOGIN
- extern int logintimo;
-#endif /* CK_LOGIN */
- extern int srvcdmsg, success, iksdcf, noinit, arg_x;
- extern char * cdmsgfile[], * cdmsgstr, *kermrc;
- char * bannerfile = NULL;
- char * helpfile = NULL;
- extern int xferlog;
- extern char * xferfile;
- int i;
-
- if (isguest) {
- printf("?Command disabled\r\n");
- return(success = 0);
- }
-
- printf("IKS Settings\r\n");
-#ifdef CK_LOGIN
-#ifdef OS2
- printf(" Anonymous Account: %s\r\n",anonacct?anonacct:"<none>");
-#endif /* OS2 */
- printf(" Anonymous Initfile: %s\r\n",anonfile?anonfile:"<none>");
- printf(" Anonymous Login: %d\r\n",ckxanon);
- printf(" Anonymous Root: %s\r\n",anonroot?anonroot:"<none>");
-#endif /* CK_LOGIN */
- printf(" Bannerfile: %s\r\n",bannerfile?bannerfile:"<none>");
- printf(" CDfile: %s\r\n",cdmsgfile[0]?cdmsgfile[0]:"<none>");
- for ( i=1;i<16 && cdmsgfile[i];i++ )
- printf(" CDfile: %s\r\n",cdmsgfile[i]);
- printf(" CDMessage: %d\r\n",srvcdmsg);
-#ifdef IKSDB
- printf(" DBfile: %s\r\n",dbfile?dbfile:"<none>");
- printf(" DBenabled: %d\r\n",dbenabled);
-#endif /* IKSDB */
-#ifdef CK_LOGIN
-#ifdef NT
- printf(" Default-domain: %s\r\n",iks_domain?iks_domain:".");
-#endif /* NT */
-#endif /* CK_LOGIN */
- printf(" Helpfile: %s\r\n",helpfile?helpfile:"<none>");
- printf(" Initfile: %s\r\n",kermrc?kermrc:"<none>");
- printf(" No-Initfile: %d\r\n",noinit);
-#ifdef CK_LOGIN
-#ifdef CK_PERM
- printf(" Permission code: %0d\r\n",ckxperms);
-#endif /* CK_PERM */
-#ifdef UNIX
- printf(" Privileged Login: %d\r\n",ckxpriv);
-#endif /* UNIX */
-#endif /* CK_LOGIN */
- printf(" Server-only: %d\r\n",arg_x);
- printf(" Syslog: %d\r\n",ckxsyslog);
- printf(" Timeout (seconds): %d\r\n",logintimo);
- printf(" Userfile: %s\r\n",userfile?userfile:"<none>");
-#ifdef CK_LOGIN
-#ifdef CKWTMP
- printf(" Wtmplog: %d\r\n",ckxwtmp);
- printf(" Wtmpfile: %s\r\n",wtmpfile?wtmpfile:"<none>");
-#endif /* CKWTMP */
-#endif /* CK_LOGIN */
- printf(" Xferfile: %s\r\n",xferfile?xferfile:"<none>");
- printf(" Xferlog: %d\r\n",xferlog);
-#else /* IKSDCONF */
- printf("?Nothing to show.\r\n");
-#endif /* IKSDCONF */
- return(success = 1);
-}
-
-#ifdef CK_AUTHENTICATION
-int
-sho_auth(cx) int cx; {
- extern int auth_type_user[], cmd_rows;
- int i;
- char * p;
- int kv = 0, all = 0, n = 0;
-
-#ifdef IKSD
- if (inserver && isguest) {
- printf("?Sorry, command disabled.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- if (cx) {
- kv = cx;
- } else if (auth_type_user[0] != AUTHTYPE_AUTO) {
- kv = auth_type_user[0];
- } else {
- all = 1;
- kv = AUTHTYPE_KERBEROS_V4;
- }
- while (kv) {
- switch (kv) {
- case AUTHTYPE_KERBEROS_V4:
- kv = all ? AUTHTYPE_KERBEROS_V5 : 0;
- if (ck_krb4_is_installed()) {
- printf(" Authentication: Kerberos 4\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- } else {
- printf(" Authentication: Kerberos 4 (not installed)\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- continue;
- }
-#ifdef CK_KERBEROS
- printf(" Keytab file: %s\n",
- k4_keytab ? k4_keytab : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- if (krb_action < 0) {
- p = "(none)";
- } else {
- for (p = "", i = 0; i < krb_a_n; i++) {
- if (krb_action == krb_a_tbl[i].kwval) {
- p = krb_a_tbl[i].kwd;
- break;
- }
- }
- }
- printf(" Action: %s\n", p);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default lifetime %d\n",krb4_d_lifetime);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Lifetime: %d (minutes)\n",krb4_init.lifetime);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default preauth: %d\n",krb4_d_preauth);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Preauth: %d\n",krb4_init.preauth);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default principal: \"%s\"\n",
- krb4_d_principal ? krb4_d_principal : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Principal: \"%s\"\n",
- krb4_init.principal ? krb4_init.principal : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default realm: \"%s\"\n",
- krb4_d_realm ? krb4_d_realm : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Realm: \"%s\"\n",
- krb4_init.realm ? krb4_init.realm : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default instance: \"%s\"\n",
- krb4_d_instance ? krb4_d_instance : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Instance: \"%s\"\n",
- krb4_init.instance ? krb4_init.instance : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Auto-Get TGTs: %d\n",krb4_autoget);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Auto-Destroy TGTs: %s\n",
- krb4_autodel==KRB_DEL_NO?"never":
- krb4_autodel==KRB_DEL_CL?"on-close":"on-exit");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Check IP Addresses: %d\n",krb4_checkaddrs);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#ifdef COMMENT
- printf(" Password: \"%s\"\n",
- krb4_init.password ? krb4_init.password : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* COMMENT */
-#endif /* CK_KERBEROS */
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- break;
- case AUTHTYPE_KERBEROS_V5:
- kv = all ? AUTHTYPE_SSL : 0;
- if (ck_krb5_is_installed()) {
- if (ck_gssapi_is_installed())
- printf(" Authentication: Kerberos 5 plus GSSAPI\n");
- else
- printf(" Authentication: Kerberos 5\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- } else {
- printf(" Authentication: Kerberos 5 (not installed)\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- continue;
- }
-
-#ifdef CK_KERBEROS
- printf(" Cache file: %s\n",
- krb_op.cache ? krb_op.cache : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default cache: %s\n",
- krb5_d_cc ? krb5_d_cc : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Keytab file: %s\n",
- k5_keytab ? k5_keytab : "(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- if (krb_action < 0) {
- p = "(none)";
- } else {
- for (p = "", i = 0; i < krb_a_n; i++) {
- if (krb_action == krb_a_tbl[i].kwval) {
- p = krb_a_tbl[i].kwd;
- break;
- }
- }
- }
- printf(" Action: %s\n", p);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-
- printf(" Default forwardable %d\n",krb5_d_forwardable);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Forwardable: %d\n",krb5_init.forwardable);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default lifetime %d\n",krb5_d_lifetime);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Lifetime: %d (minutes)\n",krb5_init.lifetime);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Postdate: \"%s\"\n",
- krb5_init.postdate ? krb5_init.postdate: "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default proxiable: %d\n",krb5_d_proxiable);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Proxiable: %d\n",krb5_init.proxiable);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Renew: %d\n",krb5_init.renew);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default renewable: %d (minutes)\n",krb5_d_renewable);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Renewable: %d (minutes)\n",krb5_init.renewable);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Service: \"%s\"\n",
- krb5_init.service ? krb5_init.service : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Validate: %d\n",krb5_init.validate);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default principal: \"%s\"\n",
- krb5_d_principal ? krb5_d_principal : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Principal: \"%s\"\n",
- krb5_init.principal ? krb5_init.principal : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default instance: \"%s\"\n",
- krb5_d_instance ? krb5_d_instance : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default realm: \"%s\"\n",
- krb5_d_realm ? krb5_d_realm : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Realm: \"%s\"\n",
- krb5_init.realm ? krb5_init.realm : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Auto-Get TGTs: %d\n",krb5_autoget);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Auto-Destroy TGTs: %s\n",
- krb5_autodel==KRB_DEL_NO?"never":
- krb5_autodel==KRB_DEL_CL?"on-close":"on-exit");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Default get K4 TGTs: %d\n",krb5_d_getk4);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Get K4 TGTs: %d\n",krb5_init.getk4);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Check IP Addresses: %d\n",krb5_checkaddrs);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" No IP Addresses: %d\n",krb5_d_no_addresses);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" IP-Addresses: ");
- if (krb5_init.addrs && krb5_init.addrs[0]) {
- for (i = 0; krb5_init.addrs[i]; i++) {
- if (i)
- printf(",");
- printf("%s",krb5_init.addrs[i]);
- }
- } else if (krb5_d_addrs[0]) {
- for (i = 0;i < KRB5_NUM_OF_ADDRS && krb5_d_addrs[i];i++) {
- if (i)
- printf(",");
- printf("%s",krb5_d_addrs[i]);
- }
- } else {
- printf("(use default)");
- }
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#ifdef COMMENT
- printf(" Password: \"%s\"\n",
- krb5_init.password ? krb5_init.password : "");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* COMMENT */
-#endif /* CK_KERBEROS */
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- break;
-#ifdef CK_SSL
- case AUTHTYPE_SSL:
- kv = all ? AUTHTYPE_SRP : 0;
- if (ck_ssleay_is_installed()) {
- printf(" Authentication: SSL/TLS (%s)\n",
- SSLeay_version(SSLEAY_VERSION));
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- } else {
- printf(" Authentication: SSL/TLS (not installed)\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- continue;
- }
- printf(" RSA Certs file: %s\n",ssl_rsa_cert_file?
- ssl_rsa_cert_file:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" RSA Certs Chain file: %s\n",ssl_rsa_cert_chain_file?
- ssl_rsa_cert_chain_file:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" RSA Key file: %s\n",ssl_rsa_key_file?
- ssl_rsa_key_file:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" DSA Certs file: %s\n",ssl_dsa_cert_file?
- ssl_dsa_cert_file:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" DSA Certs Chain file: %s\n",ssl_dsa_cert_chain_file?
- ssl_dsa_cert_chain_file:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" DH Key file: %s\n",ssl_dh_key_file?
- ssl_dh_key_file:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" DH Param file: %s\n",ssl_dh_param_file?
- ssl_dh_param_file:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" CRL file: %s\n",ssl_crl_file?
- ssl_crl_file:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" CRL dir: %s\n",ssl_crl_dir?
- ssl_crl_dir:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Random file: %s\n",ssl_rnd_file?
- ssl_rnd_file:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Verify file: %s\n",ssl_verify_file?
- ssl_verify_file:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Verify dir: %s\n",ssl_verify_dir?
- ssl_verify_dir:"(none)");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Cipher list: %s\n",ssl_cipher_list ? ssl_cipher_list :
- DEFAULT_CIPHER_LIST);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- if (ssl_con == NULL) {
- SSL_library_init();
- ssl_ctx = (SSL_CTX *)
- SSL_CTX_new((SSL_METHOD *)TLSv1_method());
- if (ssl_ctx != NULL)
- ssl_con= (SSL *) SSL_new(ssl_ctx);
- }
- if (ssl_con != NULL) {
- CHAR * p = NULL;
- int i;
-
- for (i = 0; ; i++) {
- p = (CHAR *) SSL_get_cipher_list(ssl_con,i);
- if (p == NULL)
- break;
- printf(" %s\n",p);
- if (++n > cmd_rows - 3)
- if (!askmore()) return(0); else n = 0;
- }
- }
- printf(" Certs OK? %s\n",ssl_certsok_flag? "yes" : "no");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Debug mode: %s\n", ssl_debug_flag ? "on" : "off");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Verbose mode: %s\n", ssl_verbose_flag ? "on" : "off");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" Verify mode: %s\n",
- ssl_verify_flag == SSL_VERIFY_NONE ? "none" :
- ssl_verify_flag == SSL_VERIFY_PEER ? "peer-cert" :
- "fail-if-no-peer-cert");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" SSL only? %s\n", ssl_only_flag ? "yes" : "no");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" TLS only? %s\n", tls_only_flag ? "yes" : "no");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
-#endif /* CK_SSL */
- break;
- case AUTHTYPE_NTLM:
- kv = 0;
- if (ck_ntlm_is_installed()) {
- printf(" Authentication: NTLM\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" No options\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- } else {
- printf(" Authentication: NTLM (not installed)\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- continue;
- }
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- break;
- case AUTHTYPE_SRP:
- kv = all ? AUTHTYPE_NTLM : 0;
- if (ck_srp_is_installed()) {
- if (ck_krypto_is_installed())
- printf(" Authentication: SRP plus Krypto API\n");
- else
- printf(" Authentication: SRP\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf(" No options\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- } else {
- printf(" Authentication: SRP (not installed)\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- continue;
- }
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- break;
- }
- }
- return(success = 1);
-}
-#endif /* CK_AUTHENTICATION */
-#endif /* NOSHOW */
-
-#ifdef CK_KERBEROS
-
-/* C P _ A U T H -- AUTHENTICATE command parsing */
-
-int
-cp_auth() { /* Command_Parse AUTHENTICATE */
- int c, i, n; /* Workers */
- int rc = 0; /* Return code */
- int getval; /* Parsing helpers */
- int tmpauth = 0; /* Temporary authentication type */
- int kv = 0; /* Temporary Kerberos version */
- int tmp_action = -1; /* Temporary Kerberos action */
- int tmp_klc = 0; /* Temporary list-credentials */
- char tmphlp[256]; /* For building help message */
- char * p;
- char * tmppswd = NULL; /* Password */
- char * tmpprinz = NULL; /* Principal */
- char * tmprealm = NULL; /* Realm */
- char * tmpcache = NULL; /* Cache file */
- char * tmpinst = NULL; /* K4 Instance */
- char * tmpaddrs[KRB5_NUM_OF_ADDRS];
-#ifdef CK_RECALL
- extern int on_recall; /* around Password prompting */
-#endif /* CK_RECALL */
- struct stringint pv[KRB_I_MAX+1]; /* Temporary array for switch values */
- struct FDB kw, sw, fl; /* FDBs for each parse function */
-
- krb_action = -1; /* Initialize Kerberos action. */
- tmp_action = -1; /* And our local copy. */
- for (i = 0; i < KRB5_NUM_OF_ADDRS; i++)
- tmpaddrs[i] = NULL;
-
- if ((y = cmkey(kerbtab,kerbtabn,"authentication type","",xxstring)) < 0)
- {
- if (y == -3)
- printf("?Authentication type not specified - nothing happens\n");
- return(y);
- }
- tmpauth = y;
- debug(F101,"kerberos authentication","",tmpauth);
- switch (tmpauth) {
- case AUTH_KRB4: kv = 4; break; /* Don't assume values are the same */
- case AUTH_KRB5: kv = 5; break;
- default:
- printf("?Authentication type not supported: \"%s\"\n",atmbuf);
- return(-9);
- }
-
- /* From here down is Kerberos */
- ini_kerb(); /* Reset Init data to defaults */
-
- if (kv == 4) { /* Set K4 defaults */
- if (krb4_d_realm)
- makestr(&tmprealm,krb4_d_realm);
- if (krb4_d_principal)
- makestr(&tmpprinz,krb4_d_principal);
- if (krb4_d_instance)
- makestr(&tmpinst,krb4_d_instance);
- } else if (kv == 5) { /* Set K5 defaults */
- if (krb5_d_cc)
- makestr(&tmpcache,krb5_d_cc);
- if (krb5_d_realm)
- makestr(&tmprealm,krb5_d_realm);
- if (krb5_d_principal)
- makestr(&tmpprinz,krb5_d_principal);
- if (krb5_d_instance)
- makestr(&tmpinst,krb5_d_instance);
- }
- for (i = 0; i <= KRB_I_MAX; i++) { /* Initialize switch values */
- pv[i].sval = NULL; /* to null pointers */
- pv[i].ival = 0; /* and 0 int values */
- pv[i].wval = (CK_OFF_T)-1; /* and -1 wide values */
- }
- if (kv == 4) { /* Kerberos 4 */
- pv[KRB_I_LF].ival = krb4_d_lifetime;
- pv[KRB_I_PA].ival = krb4_d_preauth;
-
- if ((n = cmkey(krb_a_tbl,krb_a_n,"Kerberos 4 action","",xxstring)) < 0)
- {
- if (n == -3)
- printf("?Action not specified - nothing happens.\n");
- return(n);
- }
- } else if (kv == 5) { /* Kerberos 5 */
- pv[KRB_I_FW].ival = krb5_d_forwardable;
- pv[KRB_I_PR].ival = krb5_d_proxiable;
- pv[KRB_I_LF].ival = krb5_d_lifetime;
- pv[KRB_I_RB].ival = krb5_d_renewable;
- pv[KRB_I_K4].ival = krb5_d_getk4;
- pv[KRB_I_NAD].ival = krb5_d_no_addresses;
-
- /* Make help message that shows switches and action keywords */
- ckstrncpy(tmphlp,"Kerberos 5 action, one of the following:\n ",256);
- for (i = 0; i < krb_a_n; i++) {
- ckstrncat(tmphlp,krb_a_tbl[i].kwd,sizeof(tmphlp));
- if (i == krb_a_n - 1)
- ckstrncat(tmphlp,"\nor switch",sizeof(tmphlp));
- else
- ckstrncat(tmphlp," ",sizeof(tmphlp));
- }
- /* Set up first set of chained FDB's */
-
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- tmphlp, /* hlpmsg */
- "", /* default (none) */
- "", /* addtl string data */
- krb_s_n, /* Switch table size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- krb_s_tbl, /* Switch table */
- &kw /* Pointer to next FDB */
- );
- cmfdbi(&kw, /* Second FDB - action keywords */
- _CMKEY, /* fcode */
- "Kerberos action", /* hlpmsg */
- "", /* default (none) */
- "", /* addtl string data */
- krb_a_n, /* Switch table size */
- 0, /* addtl num data (0 = NOT switch) */
- xxstring, /* Processing function */
- krb_a_tbl, /* Keyword table */
- NULL /* Pointer to next FDB (none) */
- );
-
- /* Parse */
-
- while (1) { /* Parse 0 or more switches */
- rc = cmfdb(&sw); /* Parse something */
- debug(F101,"kerberos cmfdb 1 rc","",rc);
- if (rc < 0) { /* Error */
- if (rc == -3)
- printf("?Action not specified - nothing happens.\n");
- return(rc); /* or reparse needed */
- }
- if (cmresult.fdbaddr != &sw) /* Break out if not a switch */
- break;
- c = cmgbrk(); /* Have switch - get break character */
- getval = (c == ':' || c == '='); /* Must parse an agument? */
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- return(-9); /* OK because nothing malloc'd yet */
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- n = cmresult.nresult; /* Numeric result = switch value */
- debug(F101,"kerberos command switch","",n);
-
- switch (n) { /* Handle the switch */
- case KRB_S_CA: /* /CACHE:<filename> */
- p = krb5_d_cc ? krb5_d_cc : "";
- if ((y = cmofi("Name of cache file",p,&s,xxstring)) < 0) {
- if (y == -3)
- s = NULL;
- else
- return(y);
- }
- makestr(&tmpcache,s);
- break;
- default:
- printf("?Unexpected switch value - internal error\n");
- return(-9); /* (if) nothing malloc'd yet. */
- }
- }
- if (cmresult.fdbaddr != &kw) { /* Checking... */
- printf("?Unexpected result - internal error\n");
- return(-9); /* Nothing malloc'd yet. */
- }
- n = cmresult.nresult; /* Get keyword value */
- } else {
- printf("?Unexpected Kerberos version - Internal error\n");
- return(-9);
- }
- debug(F101,"kerberos action","",n);
- switch (n) {
- case KRB_A_IN: /* INITIALIZE */
- case KRB_A_DE: /* DESTROY */
- case KRB_A_LC: /* LIST-CREDENTIALS */
- tmp_action = n; /* OK, set */
- break;
- default: /* Not OK, punt. */
- printf("?Unexpected action - internal error\n");
- return(-9);
- }
- if (tmp_action == KRB_A_IN) { /* Action is INITIALIZE */
- int x;
- cmfdbi(&sw, /* INITIALIZE switches */
- _CMKEY, /* fcode */
- "Principal,\n or optional INITIALIZE switch(es)", /* hlpmsg */
- "", /* default (none) */
- "", /* addtl string data */
- kv == 4 ? krb4_i_n : krb5_i_n, /* Switch table size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- kv == 4 ? krb4_i_tbl : krb5_i_tbl, /* Switch table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* 3rd FDB - command to send from */
- _CMFLD, /* fcode */
- "Principal", /* hlpmsg */
- kv == 4 ? krb4_d_principal : krb5_d_principal, /* principal */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- while (1) { /* Parse INIT switches or principal */
- rc = cmfdb(&sw);
- debug(F101,"kerberos cmfdb 2 rc","",rc);
- if (rc < 0) {
- if (rc == -3)
- printf("?Principal name required\n");
- goto kerbx;
- }
- debug(F101,"kerberos cmfdb 2 fcode","",cmresult.fcode);
- if (cmresult.fcode != _CMKEY) /* Not a switch, quit switch loop */
- break;
- c = cmgbrk(); /* Switch - get break character */
- debug(F101,"kerberos cmfdb 2 cmgbrk","",c);
- getval = (c == ':' || c == '=');
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- return(-9); /* OK because nothing malloc'd yet */
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- n = cmresult.nresult; /* Numeric result = switch value */
- switch (n) {
- /* These don't take args... */
- case KRB_I_PA: /* /PREAUTH */
- case KRB_I_FW: /* /FORWARDABLE */
- case KRB_I_PR: /* /PROXIABLE */
- case KRB_I_RN: /* /RENEW */
- case KRB_I_VA: /* /VALIDATE */
- case KRB_I_NPA: /* /NOT-PREAUTH */
- case KRB_I_NFW: /* /NOT-FORWARDABLE */
- case KRB_I_NPR: /* /NOT-PROXIABLE */
- case KRB_I_VB: /* /VERBOSE */
- case KRB_I_BR: /* /BRIEF */
- case KRB_I_K4: /* /KERBEROS4 */
- case KRB_I_NK4: /* /NO-KERBEROS4 */
- case KRB_I_POP: /* /POPUP */
- case KRB_I_NAD: /* /NO-ADDRESSES */
- if (getval) {
- printf("?This switch does not take a value\n");
- rc = -9;
- goto kerbx;
- }
- switch (n) {
- case KRB_I_NPA:
- pv[KRB_I_PA].ival = 0;
- break;
- case KRB_I_NFW:
- pv[KRB_I_FW].ival = 0;
- break;
- case KRB_I_NPR:
- pv[KRB_I_PR].ival = 0;
- break;
- case KRB_I_VB:
- pv[KRB_I_BR].ival = 0;
- break;
- case KRB_I_NK4:
- pv[KRB_I_K4].ival = 0;
- break;
- default:
- pv[n].ival = 1;
- }
- break;
-
- /* These do take arguments */
-
- case KRB_I_RB: /* /RENEWABLE:<minutes> */
- pv[n].ival = 0;
- if (!getval) break;
- if ((rc = cmnum("Minutes",ckitoa(krb5_init.renewable),
- 10,&y, xxstring)) < 0)
- goto kerbx;
- pv[n].ival = y;
- break;
-
- case KRB_I_LF: /* /LIFETIME:<minutes> */
- pv[n].ival = 0;
- /* Default is previous value */
- sprintf(tmpbuf,"%d", /* SAFE */
- kv == 4 ?
- krb4_init.lifetime :
- krb5_init.lifetime
- );
- if (!getval) break;
- if ((rc = cmnum("Minutes",tmpbuf,10,&y, xxstring)) < 0)
- goto kerbx;
- pv[n].ival = y;
- break;
-
- case KRB_I_PD: /* /POSTDATE:<timestamp> */
- if (pv[n].sval) {
- free(pv[n].sval);
- pv[n].sval = NULL;
- }
- if (!getval) break;
- if ((rc = cmdate("date-time","",&s,0,xxstring)) < 0)
- goto kerbx;
- makestr(&(pv[n].sval),s);
- break;
-
- case KRB_I_SR: /* /SERVICE:<name> */
- if (pv[n].sval) {
- free(pv[n].sval);
- pv[n].sval = NULL;
- }
- if (!getval) break;
- if ((rc = cmfld("Service-name","",&s,xxstring)) < 0)
- goto kerbx;
- makestr(&(pv[n].sval),s);
- break;
-
- case KRB_I_RL: /* /REALM:<name> */
- if (pv[n].sval) {
- free(pv[n].sval);
- pv[n].sval = NULL;
- }
- if (!getval) break;
- if (kv == 4)
- p = krb4_d_realm ? krb4_d_realm : "";
- else
- p = krb5_d_realm ? krb5_d_realm : "";
- if ((rc = cmfld("Realm",p,&s,xxstring)) < 0)
- goto kerbx;
- makestr(&(pv[n].sval),s);
- break;
-
- case KRB_I_IN: /* /INSTANCE:<name> */
- if (pv[n].sval) {
- free(pv[n].sval);
- pv[n].sval = NULL;
- }
- if (!getval) break;
- if (kv == 4)
- p = krb4_d_instance ? krb4_d_instance : "";
- else
- p = krb5_d_instance ? krb5_d_instance : "";
- if ((rc = cmfld("Instance",p,&s,xxstring)) < 0)
- goto kerbx;
- makestr(&(pv[n].sval),s);
- break;
-
- case KRB_I_PW: /* /PASSWORD:<password> */
- debok = 0;
- if (pv[n].sval) {
- free(pv[n].sval);
- pv[n].sval = NULL;
- }
- if (!getval) break;
- if ((rc = cmfld("Password","",&s,xxstring)) < 0)
- if (rc != -3)
- goto kerbx;
- makestr(&(pv[n].sval),s);
- break;
-
- case KRB_I_ADR: /* /ADDRESSES:{<address-list>} */
- if (pv[n].sval) {
- free(pv[n].sval);
- pv[n].sval = NULL;
- }
- if (!getval) break;
- if ((rc = cmfld("List of IP addresses","",&s,xxstring)) < 0)
- goto kerbx;
- makelist(s,tmpaddrs,KRB5_NUM_OF_ADDRS);
- for (i = 0; i < KRB5_NUM_OF_ADDRS && tmpaddrs[i]; i++) {
- if (inet_addr(tmpaddrs[i]) == 0xffffffff) {
- printf("invalid ip address: %s\n",tmpaddrs[i]);
- rc = -9;
- goto kerbx;
- }
- }
- pv[KRB_I_NAD].ival = 0;
- break;
-
- default:
- printf("?Unexpected switch value - internal error\n");
- rc = -9;
- goto kerbx;
- }
- }
- if (cmresult.fcode != _CMFLD) {
- printf("?Unexected result - internal error\n");
- rc = -9;
- goto kerbx;
- }
- /* cmresult.sresult may be of the form PRINCIPAL@REALM */
- i = ckindex("@",cmresult.sresult,0,0,0);
- if (i != 0) {
- makestr(&tmprealm,&cmresult.sresult[i]);
- cmresult.sresult[i-1] = '\0';
- }
- makestr(&tmpprinz,cmresult.sresult); /* Principal (user) */
-
- if ((rc = cmcfm()) < 0) { /* Now get confirmation */
- if (rc == -3) {
- printf("?Principal name required\n");
- }
- goto kerbx;
- }
- if (!tmpprinz || !tmpprinz[0]) {
- printf("?Principal name required\n");
- goto kerbx;
- }
- if (!pv[KRB_I_RN].ival && !pv[KRB_I_VA].ival) {
- /* Don't use a password if Validating or Renewing */
- if (pv[KRB_I_PW].sval) { /* If they gave a /PASSWORD switch */
- makestr(&tmppswd,pv[KRB_I_PW].sval); /* use this value */
- }
-#ifdef COMMENT
- /* Password prompting has been moved to ck_krb[45]_initTGT() */
- else { /* Otherwise must prompt for it */
- char prmpt[80];
- if (pv[KRB_I_RL].sval)
- sprintf(prmpt,"%s@%s's Password: ",
- tmpprinz,pv[KRB_I_RL].sval);
- else if (tmprealm)
- sprintf(prmpt,"%s@%s's Password: ",
- tmpprinz,tmprealm);
- else
- sprintf(prmpt,"%s's Password: ",tmpprinz);
-#ifdef OS2
- if (pv[KRB_I_POP].ival) {
- char passwd[80]="";
- readpass(prmpt,passwd,80);
- makestr(&tmppswd,passwd);
- memset(passwd,0,80);
- } else
-#endif /* OS2 */
- {
-#ifdef CK_RECALL
- on_recall = 0;
-#endif /* CK_RECALL */
- cmsavp(psave,PROMPTL); /* Save old prompt */
- cmsetp(prmpt); /* Make new prompt */
- concb((char)escape); /* Put console in cbreak mode */
- cmini(0); /* and no-echo mode */
- /* Issue prompt if at top level */
- if (pflag) prompt(xxstring);
- cmres(); /* Reset the parser */
- for (rc = -1; rc < 0; ) { /* Prompt till they answer */
- /* Get a literal line of text */
- rc = cmtxt("","",&s,NULL);
- cmres(); /* Reset the parser again */
- }
- makestr(&tmppswd,s);
- printf("\n"); /* Echo a CRLF */
- cmsetp(psave); /* Restore original prompt */
- }
- }
- x = 0; /* Check for password */
- if (tmppswd)
- if (*tmppswd)
- x = 1;
- if (!x) {
- printf("?Password required\n");
- goto kerbx;
- }
-#endif /* COMMENT */
- }
- } else if (kv == 5 && tmp_action == KRB_A_LC) { /* LIST-CREDENTIALS */
- tmp_klc = 0;
- while (1) {
- if ((x = cmkey(klctab,nklctab,"Switch","",xxstring)) < 0) {
- if (x == -3) {
- if ((rc = cmcfm()) < 0)
- goto kerbx;
- else
- break;
- } else {
- rc = x;
- goto kerbx;
- }
- }
- tmp_klc |= x;
- }
- } else if ((rc = cmcfm()) < 0) /* DESTROY, just confirm */
- goto kerbx;
-
-/* Done - Move confirmed data to final locations */
-
- krb_action = tmp_action; /* Action requested */
- krb_op.version = kv; /* Kerberos version */
- krb_op.cache = tmpcache; /* Cache file */
- tmpcache = NULL; /* So we don't free it */
-
- switch (krb_action) {
- case KRB_A_IN: /* INITIALIZE */
- if (kv == 5) {
- krb5_init.forwardable = pv[KRB_I_FW].ival;
- krb5_init.proxiable = pv[KRB_I_PR].ival;
- krb5_init.lifetime = pv[KRB_I_LF].ival;
- krb5_init.renew = pv[KRB_I_RN].ival;
- krb5_init.renewable = pv[KRB_I_RB].ival;
- krb5_init.validate = pv[KRB_I_VA].ival;
-
- /* Here we just reassign the pointers and then set them to NULL */
- /* so they won't be freed below. */
-
- krb5_init.postdate = pv[KRB_I_PD].sval; pv[KRB_I_PD].sval = NULL;
- krb5_init.service = pv[KRB_I_SR].sval; pv[KRB_I_SR].sval = NULL;
- if (pv[KRB_I_RL].sval) {
- krb5_init.realm = pv[KRB_I_RL].sval; pv[KRB_I_RL].sval = NULL;
- } else if (tmprealm) {
- krb5_init.realm = tmprealm; tmprealm = NULL;
- }
- if (pv[KRB_I_IN].sval) {
- krb5_init.instance = pv[KRB_I_IN].sval;
- pv[KRB_I_IN].sval = NULL;
- } else if ( tmpinst ) {
- krb5_init.instance = tmpinst;
- tmpinst = NULL;
- }
- if (tmpprinz) {
- krb5_init.principal = tmpprinz;
- tmpprinz = NULL;
- }
- krb5_init.password = tmppswd;
- tmppswd = NULL;
-
- krb5_init.getk4 = pv[KRB_I_K4].ival;
- if (krb5_init.getk4) {
- krb4_init.lifetime = pv[KRB_I_LF].ival;
- if (krb5_init.realm)
- makestr(&krb4_init.realm,krb5_init.realm);
- krb4_init.preauth = krb4_d_preauth;
- krb4_init.verbose = pv[KRB_I_BR].ival ? 0 : 1;
- if (krb5_init.principal)
- makestr(&krb4_init.principal,krb5_init.principal);
- if (krb5_init.principal)
- makestr(&krb4_init.password,krb5_init.password);
- }
- krb5_init.no_addresses = pv[KRB_I_NAD].ival;
- if (tmpaddrs[0]) {
- for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
- if (krb5_init.addrs[i]) {
- free(krb5_init.addrs[i]);
- krb5_init.addrs[i] = NULL;
- }
- krb5_init.addrs[i] = tmpaddrs[i];
- tmpaddrs[i] = NULL;
- }
- }
- } else if (kv == 4) { /* Same deal for Kerberos 4 */
- krb4_init.lifetime = pv[KRB_I_LF].ival;
- if (pv[KRB_I_RL].sval) {
- krb4_init.realm = pv[KRB_I_RL].sval;
- pv[KRB_I_RL].sval = NULL;
- } else if ( tmprealm ) {
- krb4_init.realm = tmprealm;
- tmprealm = NULL;
- }
- if (pv[KRB_I_IN].sval) {
- krb4_init.instance = pv[KRB_I_IN].sval;
- pv[KRB_I_IN].sval = NULL;
- } else if ( tmpinst ) {
- krb4_init.instance = tmpinst;
- tmpinst = NULL;
- }
- krb4_init.preauth = pv[KRB_I_PA].ival;
- krb4_init.verbose = pv[KRB_I_BR].ival ? 0 : 1;
-
- if (tmpprinz) {
- krb4_init.principal = tmpprinz;
- tmpprinz = NULL;
- }
- krb4_init.password = tmppswd;
- tmppswd = NULL;
- }
- break;
- case KRB_A_LC: /* List Credentials */
- krb5_lc.encryption = tmp_klc & XYKLCEN;
- krb5_lc.flags = tmp_klc & XYKLCFL;
- krb5_lc.addr = tmp_klc & XYKLCAD;
- break;
- }
-
-/* Common exit - Free temporary storage */
-
- kerbx:
- for (i = 0; i <= KRB_I_MAX; i++) { /* Free malloc'd switch data */
- if (pv[i].sval)
- free(pv[i].sval);
- }
- for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
- if (tmpaddrs[i])
- free(tmpaddrs[i]);
- }
- if (tmpprinz) free(tmpprinz); /* And these too. */
- if (tmppswd) free(tmppswd);
- if (tmpcache) free(tmpcache);
- if (tmprealm) free(tmprealm);
- if (tmpinst) free(tmpinst);
-
- return(rc); /* Return the return code */
-}
-#endif /* CK_KERBEROS */
-
-#ifdef CK_LOGIN
-int
-#ifdef CK_ANSIC
-ckxlogin(CHAR * userid, CHAR * passwd, CHAR * acct, int promptok)
-#else /* CK_ANSIC */
-ckxlogin(userid, passwd, acct, promptok)
- CHAR * userid; CHAR * passwd; CHAR * acct; int promptok;
-#endif /* CK_ANSIC */
-/* ckxlogin */ {
-#ifdef CK_RECALL
- extern int on_recall; /* around Password prompting */
-#endif /* CK_RECALL */
-#ifdef COMMENT
- extern int guest;
-#endif /* COMMENT */
- int rprompt = 0; /* Restore prompt */
-#ifdef CKSYSLOG
- int savlog;
-#endif /* CKSYSLOG */
-
- extern int what, srvcdmsg;
-
- int x = 0, ok = 0, rc = 0;
- CHAR * _u = NULL, * _p = NULL, * _a = NULL;
-
- debug(F111,"ckxlogin userid",userid,promptok);
- debug(F110,"ckxlogin passwd",passwd,0);
-
- isguest = 0; /* Global "anonymous" flag */
-
- if (!userid) userid = (CHAR *)"";
- if (!passwd) passwd = (CHAR *)"";
-
- debug(F111,"ckxlogin userid",userid,what);
-
-#ifdef CK_RECALL
- on_recall = 0;
-#endif /* CK_RECALL */
-
-#ifdef CKSYSLOG
- savlog = ckxsyslog; /* Save and turn off syslogging */
-#endif /* CKSYSLOG */
-
- if ((!*userid || !*passwd) && /* Need to prompt for missing info */
- promptok) {
- cmsavp(psave,PROMPTL); /* Save old prompt */
- debug(F110,"ckxlogin saved",psave,0);
- rprompt = 1;
- }
- if (!*userid) {
- if (!promptok)
- return(0);
- cmsetp("Username: "); /* Make new prompt */
- concb((char)escape); /* Put console in cbreak mode */
- cmini(1);
-
-/* Flush typeahead */
-
-#ifdef IKS_OPTION
- debug(F101,
- "ckxlogin TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
- "",
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start
- );
-#endif /* IKS_OPTION */
-
- while (ttchk() > 0) {
- x = ttinc(0);
- debug(F101,"ckxlogin flush user x","",x);
- if (x < 0)
- doexit(GOOD_EXIT,0); /* Connection lost */
-#ifdef TNCODE
- if (sstelnet) {
- if (x == IAC) {
- x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
- debug(F101,"ckxlogin user tn_doop","",x);
-#ifdef IKS_OPTION
- debug(F101,
- "ckxlogin user TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
- "",
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start
- );
-#endif /* IKS_OPTION */
-
- if (x < 0)
- goto XCKXLOG;
- switch (x) {
- case 1: ckxech = 1; break; /* Turn on echoing */
- case 2: ckxech = 0; break; /* Turn off echoing */
-#ifdef IKS_OPTION
- case 4: /* IKS event */
- if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
- break; /* else fall thru... */
-#endif /* IKS_OPTION */
- case 6: /* Logout */
- goto XCKXLOG;
- }
- }
- }
-#endif /* TNCODE */
- }
- if (pflag) prompt(xxstring); /* Issue prompt if at top level */
- cmres(); /* Reset the parser */
- for (x = -1; x < 0;) { /* Prompt till they answer */
- /* Get a literal line of text */
- x=cmtxt("Your username, or \"ftp\", or \"anonymous\"","",&s,NULL);
- if (x == -4 || x == -10) {
- printf("\r\n%sLogin cancelled\n",
- x == -10 ? "Timed out: " : "");
-#ifdef CKSYSLOG
- ckxsyslog = savlog;
-#endif /* CKSYSLOG */
- doexit(GOOD_EXIT,0);
- }
- if (sstate) /* Did a packet come instead? */
- goto XCKXLOG;
- cmres(); /* Reset the parser again */
- }
- if ((_u = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
- printf("?Internal error: malloc\n");
- goto XCKXLOG;
- } else {
- strcpy((char *)_u,s); /* safe */
- userid = _u;
- }
- }
- ok = zvuser((char *)userid); /* Verify username */
- debug(F111,"ckxlogin zvuser",userid,ok);
-
- if (!*passwd && promptok
-#ifdef COMMENT
- && guest
-#endif /* COMMENT */
- ) {
- char prmpt[80];
-
-#ifdef CKSYSLOG
- savlog = ckxsyslog; /* Save and turn off syslogging */
- ckxsyslog = 0;
-#endif /* CKSYSLOG */
-
-/* Flush typeahead again */
-
- while (ttchk() > 0) {
- x = ttinc(0);
- debug(F101,"ckxlogin flush user x","",x);
-#ifdef TNCODE
- if (sstelnet) {
- if (x == IAC) {
- x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
- debug(F101,"ckxlogin pass tn_doop","",x);
-#ifdef IKS_OPTION
- debug(F101,
- "ckxlogin pass TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
- "",
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start
- );
-#endif /* IKS_OPTION */
- if (x < 0)
- goto XCKXLOG;
- switch (x) {
- case 1: ckxech = 1; break; /* Turn on echoing */
- case 2: ckxech = 0; break; /* Turn off echoing */
- case 4: /* IKS event */
- if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
- break; /* else fall thru... */
- case 6: /* Logout */
- goto XCKXLOG;
- }
- }
- }
-#endif /* TNCODE */
- }
- if (!strcmp((char *)userid,"anonymous") ||
- !strcmp((char *)userid,"ftp")) {
- if (!ok)
- goto XCKXLOG;
- ckstrncpy(prmpt,"Enter e-mail address as Password: ",80);
- } else if (*userid && strlen((char *)userid) < 60) {
-#ifdef NT
- extern CHAR * pReferenceDomainName;
- if (pReferenceDomainName)
- ckmakxmsg(prmpt,
- 80,
- "Enter ",
- pReferenceDomainName,
- "\\\\",
- userid,
- "'s Password: ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- else
-#endif /* NT */
- ckmakmsg(prmpt,80,"Enter ",(char *)userid,"'s Password: ",NULL);
- } else
- ckstrncpy(prmpt,"Enter Password: ",80);
- cmsetp(prmpt); /* Make new prompt */
- concb((char)escape); /* Put console in cbreak mode */
- if (strcmp((char *)userid,"anonymous") &&
- strcmp((char *)userid,"ftp")) { /* and if not anonymous */
- debok = 0;
- cmini(0); /* and no-echo mode */
- } else {
- cmini(1);
- }
- if (pflag) prompt(xxstring); /* Issue prompt if at top level */
- cmres(); /* Reset the parser */
- for (x = -1; x < 0;) { /* Prompt till they answer */
-#ifdef CK_PAM
- gotemptypasswd=0;
-#endif /* CK_PAM */
- x = cmtxt("","",&s,NULL); /* Get a literal line of text */
- if (x == -4 || x == -10) {
- printf("\r\n%sLogin cancelled\n",
- x == -10 ? "Timed out: " : "");
-#ifdef CKSYSLOG
- ckxsyslog = savlog;
-#endif /* CKSYSLOG */
- doexit(GOOD_EXIT,0);
- }
-#ifdef CK_PAM
- if (!*s)
- gotemptypasswd = 1;
-#endif /* CK_PAM */
- if (sstate) /* In case of a Kermit packet */
- goto XCKXLOG;
- cmres(); /* Reset the parser again */
- }
- printf("\r\n"); /* Echo a CRLF */
- if ((_p = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
- printf("?Internal error: malloc\n");
- goto XCKXLOG;
- } else {
- strcpy((char *)_p,s); /* safe */
- passwd = _p;
- }
- }
-#ifdef CK_PAM
- else {
- cmres(); /* Reset the parser */
-
- /* We restore the prompt now because the PAM engine will call */
- /* readpass() which will overwrite psave. */
- if (rprompt) {
- cmsetp(psave); /* Restore original prompt */
- debug(F110,"ckxlogin restored",psave,0);
- rprompt = 0;
- }
- }
-#endif /* CK_PAM */
-
-#ifdef CKSYSLOG
- ckxsyslog = savlog;
-#endif /* CKSYSLOG */
-
- if (ok) {
- ok = zvpass((char *)passwd); /* Check password */
- debug(F101,"ckxlogin zvpass","",ok);
-#ifdef CK_PAM
- } else {
- /* Fake pam password failure for nonexistent users */
- sleep(1);
- printf("Authentication failure\n");
-#endif /* CK_PAM */
- }
-
- if (ok > 0 && isguest) {
-#ifndef NOPUSH
- nopush = 1;
-#endif /* NOPUSH */
- srvcdmsg = 1;
- }
- rc = ok; /* Set the return code */
- if ((char *)uidbuf != (char *)userid)
- ckstrncpy(uidbuf,(char *)userid,UIDBUFLEN); /* Remember username */
-
- XCKXLOG: /* Common exit */
-#ifdef CKSYSLOG
- ckxsyslog = savlog; /* In case of GOTO above */
-#endif /* CKSYSLOG */
- if (rprompt) {
- cmsetp(psave); /* Restore original prompt */
- debug(F110,"ckxlogin restored",psave,0);
- }
- if (_u || _p || _a) {
- if (_u) free(_u);
- if (_p) free(_p);
- if (_a) free(_a);
- }
- return(rc);
-}
-
-int
-ckxlogout() {
- doexit(GOOD_EXIT,0); /* doexit calls zvlogout */
- return(0); /* not reached */
-}
-#endif /* CK_LOGIN */
-
-#endif /* NOICP */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusr.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuusr.c
deleted file mode 100644
index 3b77fe6..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusr.c
+++ /dev/null
@@ -1,13376 +0,0 @@
-#ifdef SSHTEST
-#define SSHBUILTIN
-#endif /* SSHTEST */
-
-#include "ckcsym.h"
-char *userv = "User Interface 9.0.299, 9 Jun 2011";
-
-/* C K U U S R -- "User Interface" for C-Kermit (Part 1) */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- Originally the entire user interface was in one module, ckuusr.c. Over
- the years it has been split into many modules: ckuus2.c, ckuus3.c, ...,
- ckuus7.c. ckuus2.c contains the HELP command parser and help-text strings;
- ckuusy.c contains the UNIX-style command-line interface; ckuusx.c contains
- routines needed by both the command-line interface and the interactive
- command parser.
-*/
-
-/*
- The ckuus*.c modules depend on the existence of C library features like
- fopen, fgets, feof, (f)printf, argv/argc, etc. Other functions that are
- likely to vary among different platforms -- like setting terminal modes or
- interrupts -- are invoked via calls to functions that are defined in the
- system- dependent modules, ck?[ft]io.c. The command line parser processes
- any arguments found on the command line, as passed to main() via argv/argc.
- The interactive parser uses the facilities of the cmd package (developed for
- this program, but usable by any program). Any command parser may be
- substituted for this one. The only requirements for the Kermit command
- parser are these:
-
- . Set parameters via global variables like duplex, speed, ttname, etc. See
- ckcmai.c for the declarations and descriptions of these variables.
-
- . If a command can be executed without the use of Kermit protocol, then
- execute the command directly and set the variable sstate to 0. Examples
- include 'set' commands, local directory listings, the 'connect' command.
-
- . If a command requires the Kermit protocol, set the following variables:
-
- sstate string data
- 'x' (enter server mode) (none)
- 'r' (send a 'get' command) cmarg, cmarg2
- 'v' (enter receive mode) cmarg2
- 'g' (send a generic command) cmarg
- 's' (send files) nfils, cmarg & cmarg2 OR cmlist
- 'c' (send a remote host command) cmarg
-
- cmlist is an array of pointers to strings.
- cmarg, cmarg2 are pointers to strings.
- nfils is an integer.
-
- cmarg can be a filename string (possibly wild), or
- a pointer to a prefabricated generic command string, or
- a pointer to a host command string.
- cmarg2 is an "as-name" - the name to send file(s) under, or
- the name under which to store incoming file(s); must not be wild.
- A null or empty value means to use the file's own name.
- cmlist is a list of filenames, such as passed via argv.
- nfils is an integer, interpreted as follows:
- -1: filespec (possibly wild) in cmarg, must be expanded internally.
- 0: send from stdin (standard input).
- >0: number of files to send, from cmlist.
-
- The screen() function is used to update the screen during file transfer.
- The tlog() function writes to a transaction log.
- The debug() function writes to a debugging log.
- The intmsg() and chkint() functions provide the user i/o for interrupting
- file transfers.
-*/
-
-/* Includes */
-
-#ifdef MULTINET
-#define MULTINET_OLD_STYLE /* Leave select prototype undefined */
-#endif /* MULTINET */
-
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckcnet.h" /* Network symbols */
-#include "ckuusr.h"
-#include "ckcxla.h"
-
-int g_fncact = -1; /* Needed for NOICP builds */
-int noinit = 0; /* Flag for skipping init file */
-int nscanfile = SCANFILEBUF;
-
-int rcdactive = 0; /* RCD active */
-int keepallchars = 0; /* See cmfld() */
-
-int locus = 1; /* Current LOCUS is LOCAL */
-#ifdef OS2
-int autolocus = 2; /* Automatic LOCUS switching: ASK */
-#else /* OS2 */
-int autolocus = 1; /* Automatic LOCUS switching enabled */
-#endif /* OS2 */
-
-#ifndef NOICP
-#ifdef CKLEARN
-#ifdef VMS
-#include <time.h> /* For CKLEARN */
-#endif /* VMS */
-#endif /* CKLEARN */
-#ifdef OS2
-#ifndef NT
-#define INCL_NOPM
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#else
-#define APIRET ULONG
-#include <windows.h>
-#include <tapi.h>
-#include "cknwin.h"
-#include "ckntap.h" /* CK_TAPI definition */
-#endif /* NT */
-#include "ckowin.h"
-#include "ckocon.h"
-extern int tcp_avail;
-extern bool viewonly;
-extern int k95stdout;
-extern int tt_scroll;
-#ifndef NOTERM
-extern tt_status[VNUM];
-#endif /* NOTERM */
-int display_demo = 1;
-#include "ckossh.h"
-#ifdef KUI
-#include "ikui.h"
-#endif /* KUI */
-#endif /* OS2 */
-
-int optlines = 0;
-int didsetlin = 0;
-
-#ifdef NEWFTP
-extern int ftpget, ftpisopen(), doftpres();
-_PROTOTYP(int doftptyp,(int));
-_PROTOTYP(VOID doftpglobaltype,(int));
-#endif /* NEWFTP */
-
-#ifdef VMS
-extern int batch;
-#endif /* VMS */
-
-#ifdef datageneral
-#include <packets:common.h>
-#define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
-#endif /* datageneral */
-
-extern int xcmdsrc, hints, cmflgs, whyclosed;
-
-char * hlptok = NULL;
-
-#ifdef CK_TTGWSIZ /* Whether to use more-prompting */
-int xaskmore = 1; /* Momentary setting */
-int saveask = 1; /* Permanent setting */
-#else
-int xaskmore = 0;
-int saveask = 0;
-#endif /* CK_TTGWSIZ */
-
-#ifndef NOCSETS
-extern int nfilc;
-extern struct keytab fcstab[];
-extern int fcharset;
-#endif /* NOCSETS */
-
-char * g_pswd = NULL;
-int g_pcpt = -1;
-int g_pflg = -1;
-
-extern int cmd_rows, cmd_cols;
-
-#ifdef CKROOT
-extern int ckrooterr;
-#endif /* CKROOT */
-
-extern int inserver, filepeek;
-
-#ifdef CKLEARN
-FILE * learnfp = NULL;
-char * learnfile = NULL;
-int learning = 0;
-#endif /* CKLEARN */
-
-#ifndef NOXFER
-extern int atcapr, atdiso, nfils, moving, protocol, sendmode, epktflg, size,
- sndsrc, server, displa, fncnv, fnspath, fnrpath, xfermode, urpsiz,
- spsizf, spsiz, spsizr, spmax, wslotr, prefixing, fncact, reliable,
- setreliable;
-
-#ifdef IKSDCONF
-extern int iksdcf;
-#endif /* IKSDCONF */
-
-#ifdef CK_LOGIN
-extern int isguest;
-#endif /* CK_LOGIN */
-
-extern CK_OFF_T sendstart;
-
-extern char *cmarg, *cmarg2, **cmlist, *dftty;
-
-extern struct keytab fntab[]; extern int nfntab;
-extern struct ck_p ptab[NPROTOS];
-
-int sndcmd = 0; /* Last command was a SEND-class command. */
-
-int g_xfermode = -1;
-int g_proto = -1;
-int g_urpsiz = -1;
-int g_spsizf = -1;
-int g_spsiz = -1;
-int g_spsizr = -1;
-int g_spmax = -1;
-int g_wslotr = -1;
-int g_prefixing = -1;
-int g_fncnv = -1;
-int g_fnspath = -1;
-int g_fnrpath = -1;
-int g_fnact = -1;
-int g_displa = -1;
-int g_spath = -1;
-int g_rpath = -1;
-char * g_sfilter = NULL;
-char * g_rfilter = NULL;
-
-extern int patterns;
-#ifdef PATTERNS
-extern char *txtpatterns[], *binpatterns[];
-int g_patterns = -1;
-#endif /* PATTERNS */
-int g_skipbup = -1;
-
-#ifdef PIPESEND
-extern int usepipes, pipesend;
-extern char * sndfilter;
-#endif /* PIPESEND */
-
-#ifndef NOSPL
-extern int sndxlo, sndxhi, sndxin;
-#endif /* NOSPL */
-
-extern char fspec[]; /* Most recent filespec */
-extern int fspeclen; /* Length of fspec[] buffer */
-
-#ifndef NOFRILLS
-extern int rmailf; /* MAIL command items */
-extern char optbuf[];
-#endif /* NOFRILLS */
-
-extern int
- en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
- en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
- en_mkd, en_rmd, en_asg;
-
-#ifndef NOMSEND /* Multiple SEND */
-extern char *msfiles[];
-int filesinlist = 0; /* And ADD ... */
-extern struct filelist * filehead;
-extern struct filelist * filetail;
-extern struct filelist * filenext;
-extern int addlist;
-#endif /* NOMSEND */
-
-static struct keytab addtab[] = {
-#ifdef PATTERNS
- { "binary-patterns", ADD_BIN, 0 },
-#endif /* PATTERNS */
-#ifndef NOMSEND
- { "send-list", ADD_SND, 0 },
-#endif /* NOMSEND */
-#ifdef PATTERNS
- { "text-patterns", ADD_TXT, 0 },
-#endif /* PATTERNS */
- { "", 0, 0 }
-};
-static int naddtab = sizeof(addtab)/sizeof(struct keytab) - 1;
-
-#ifndef NOCSETS
-struct keytab assoctab[] = {
- { "file-character-set", ASSOC_FC, 0 },
- { "transfer-character-set", ASSOC_TC, 0 },
- { "xfer-character-set", ASSOC_TC, CM_INV }
-};
-static int nassoc = sizeof(assoctab)/sizeof(struct keytab);
-extern int afcset[MAXFCSETS+1]; /* Character-set associations */
-extern int axcset[MAXTCSETS+1];
-#endif /* NOCSETS */
-
-#ifndef ADDCMD
-#ifndef NOMSEND
-#define ADDCMD
-#endif /* NOMSEND */
-#ifndef ADDCMD
-#ifdef PATTERNS
-#define ADDCMD
-#endif /* PATTERNS */
-#endif /* ADDCMD */
-#endif /* ADDCMD */
-#endif /* NOXFER */
-
-/* External Kermit Variables, see ckmain.c for description. */
-
-extern xx_strp xxstring;
-extern long xvernum;
-
-extern int local, xitsta, binary, msgflg, escape, duplex, quiet, tlevel,
- pflag, zincnt, ckxech, carrier, what, nopush, haveline, bye_active;
-#ifdef TNCODE
-extern int debses;
-extern char tn_msg[];
-#endif /* TNCODE */
-
-int sleepcan = 1;
-int g_binary = -1;
-int g_recursive = -1;
-int g_matchdot = -1;
-extern int nolinks;
-
-extern long vernum;
-extern char *versio, *copyright[];
-extern char *ckxsys;
-#ifndef NOHELP
-extern char *introtxt[];
-extern char *newstxt[];
-#endif /* NOHELP */
-
-#ifndef OS2
-#ifndef UNIX
-extern char *PWDCMD;
-#endif /* UNIX */
-extern char *WHOCMD;
-#endif /* OS2 */
-
-extern char ttname[];
-
-extern CHAR sstate;
-
-extern int network; /* Have active network connection */
-extern int nettype; /* Type of network */
-extern int ttnproto; /* NET_TCPB protocol */
-
-#ifndef NODIAL
-extern int dialsta, dialatmo, dialcon, dialcq; /* DIAL status, etc. */
-#endif /* NODIAL */
-
-#ifdef CK_APC
-extern int apcactive, apcstatus;
-#endif /* CK_APC */
-
-#ifndef NOPUSH
-#ifndef NOFRILLS
-extern char editor[];
-extern char editopts[];
-extern char editfile[];
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-
-#ifdef BROWSER
-extern char browser[]; /* Web browser application */
-extern char browsopts[]; /* Web browser options */
-extern char browsurl[]; /* Most recent URL */
-#endif /* BROWSER */
-#ifndef NOFTP
-char ftpapp[CKMAXPATH+1] = { NUL, NUL }; /* ftp executable */
-char ftpopts[128] = { NUL, NUL }; /* ftp command-line options */
-#endif /* NOFTP */
-extern struct keytab onoff[]; /* On/Off keyword table */
-
-#ifdef CK_TMPDIR
-int f_tmpdir = 0; /* Directory changed temporarily */
-char savdir[TMPDIRLEN]; /* For saving current directory */
-#endif /* CK_TMPDIR */
-
-int activecmd = -1; /* Keyword index of active command */
-int doconx = -1; /* CONNECT-class command active */
-int ooflag = 0; /* User-settable on/off flag */
-
-int rcflag = 0; /* Pointer to home directory string */
-int repars, /* Reparse needed */
- techo = 0; /* Take echo */
-int secho = 1; /* SCRIPT echo */
-
-int xitwarn = /* Warn about open connection on exit */
-#ifdef NOWARN
-0
-#else
-1
-#endif /* NOWARN */
-;
-
-struct keytab onoffsw[] = {
- { "/off", 0, 0 },
- { "/on", 1, 0 }
-};
-
-#ifdef CKEXEC
-struct keytab redirsw[] = {
- { "/redirect", 1, 0 }
-};
-#endif /* CKEXEC */
-
-#ifndef NOXMIT
-/* Variables for TRANSMIT command */
-
-int xmitx = 1; /* Whether to echo during TRANSMIT */
-int xmitf = 0; /* Character to fill empty lines */
-int xmitl = 0; /* 0 = Don't send linefeed too */
-int xmitp = LF; /* Host line prompt */
-int xmits = 0; /* Use shift-in/shift-out, 0 = no */
-int xmitw = 0; /* Milliseconds to pause during TRANSMIT */
-int xmitt = 1; /* Seconds to wait for each char to echo */
-int xmita = 1; /* Action upon timeout */
-
-#define XMI_BIN 1
-#define XMI_TXT 2
-#define XMI_CMD 3
-#define XMI_TRA 4
-#define XMI_VRB 5
-#define XMI_QUI 6
-#define XMI_NOW 7
-#define XMI_NOE 8
-
-static struct keytab xmitsw[] = { /* TRANSMIT command options */
- { "/binary", XMI_BIN, 0 },
-#ifdef PIPESEND
- { "/command", XMI_CMD, CM_INV|CM_PSH },
-#endif /* PIPESEND */
- { "/noecho", XMI_NOE, 0 },
- { "/nowait", XMI_NOW, 0 },
-#ifdef PIPESEND
- { "/pipe", XMI_CMD, 0 },
-#endif /* PIPESEND */
-#ifdef COMMENT
- { "/quiet", XMI_QUI, 0 },
-#endif /* COMMENT */
- { "/text", XMI_TXT, 0 },
- { "/transparent", XMI_TRA, 0 },
-#ifdef COMMENT
- { "/verbose", XMI_VRB, 0 },
-#endif /* COMMENT */
- { "", 0, 0 }
-};
-#define NXMITSW sizeof(xmitsw)/sizeof(struct keytab) - 1
-static int nxmitsw = NXMITSW;
-
-#endif /* NOXMIT */
-
-/* Declarations from ck?fio.c module */
-
-extern char *SPACMD, *SPACM2; /* SPACE commands */
-
-/* Command-oriented items */
-
-#ifdef DCMDBUF
-extern char *cmdbuf; /* Command buffers */
-extern char *atmbuf;
-extern char *line; /* Character buffer for anything */
-extern char *tmpbuf; /* Short temporary string buffer */
-extern int *ifcmd;
-extern int *intime;
-extern int *inpcas;
-#else
-extern char cmdbuf[]; /* Command buffers */
-extern char atmbuf[];
-extern char line[]; /* Character buffer for anything */
-extern char tmpbuf[]; /* Temporary buffer */
-extern int ifcmd[];
-extern int intime[];
-extern int inpcas[];
-#endif /* DCMDBUF */
-
-#ifndef NOSPL
-extern char * prstring[];
-#endif /* NOSPL */
-
-char *lp; /* Pointer to line buffer */
-
-#ifndef NOSPL
-int vareval = 1; /* Evaluation method */
-int unkmacro = 0; /* Flag for in ON_UNKNOWN_COMMAND */
-int oldeval = 0;
-char evalbuf[33]; /* EVALUATE result */
-extern char * inpbuf; /* Buffer for INPUT and REINPUT */
-char *inpbp; /* And pointer to same */
-int m_found; /* MINPUT result */
-int i_active = 0; /* INPUT command is active */
-char *ms[MINPMAX]; /* Pointers to MINPUT strings */
-static int mpinited = 0; /* Flag they have been initialized */
-static int mp[MINPMAX]; /* and MINPUT flags */
-extern int fndiags, fnerror, fnsuccess; /* Function diagnostics */
-#ifndef NOSEXP
-char * lastsexp = NULL; /* S-Expressions */
-char * sexpval = NULL;
-int sexpecho = SET_AUTO;
-#endif /* NOSEXP */
-#endif /* NOSPL */
-
-char psave[PROMPTL] = { NUL }; /* For saving & restoring prompt */
-
-extern int success; /* Command success/failure flag */
-extern int cmdlvl; /* Current position in command stack */
-
-#ifndef NOSPL
-int /* SET INPUT parameters. */
-/* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */
- inbufsize = 0, /* INPUT buffer size */
- indef = 1, /* default timeout, seconds */
- inecho = 1, /* 1 = echo on */
- inautodl = 0, /* INPUT autodownload */
- inintr = 1, /* INPUT interrupion allowed */
- insilence = 0; /* 0 = no silence constraint */
-
-#ifdef CKFLOAT
-CKFLOAT inscale = 1.0; /* Timeout scale factor */
-#endif /* CKFLOAT */
-
-#ifdef OS2
-int interm = 1; /* Terminal emulator displays input */
-#endif /* OS2 */
-int maclvl = -1; /* Macro nesting level */
-int mecho = 0; /* Macro echo, 0 = don't */
-char varnam[6]; /* For variable names */
-extern int macargc[]; /* ARGC from macro invocation */
-
-extern char *m_arg[MACLEVEL][NARGS]; /* Stack of macro arguments */
-extern char *mrval[];
-
-extern char **a_ptr[]; /* Array pointers */
-extern int a_dim[]; /* Array dimensions */
-extern int a_link[];
-
-#ifdef DCMDBUF
-extern struct cmdptr *cmdstk; /* The command stack itself */
-#else
-extern struct cmdptr cmdstk[]; /* The command stack itself */
-#endif /* DCMDBUF */
-
-long ck_alarm = 0; /* SET ALARM value */
-char alrm_date[24] = { ' ',' ',' ',' ',' ',' ',' ',' ',' ' };
-char alrm_time[24] = { ' ',' ',' ',' ',' ',' ',' ' };
-
-struct keytab inputsw[] = {
- { "/clear", INPSW_CLR, 0 },
- { "/count", INPSW_COU, CM_ARG },
- { "/nomatch", INPSW_NOM, 0 },
- { "/nowrap", INPSW_NOW, 0 }
-};
-static int ninputsw = sizeof(inputsw)/sizeof(struct keytab);
-
-/* The following should be reconciled with the above */
-
-#ifdef COMMENT /* INPUT switches not used yet... */
-static struct keytab inswtab[] = {
-#ifdef COMMENT
- { "/assign", IN_ASG, CM_ARG },
-#endif /* COMMENT */
- { "/autodownload", IN_ADL, CM_ARG },
- { "/case", IN_CAS, CM_ARG },
- { "/echo", IN_ECH, CM_ARG },
- { "/interrupts", IN_NOI, CM_ARG },
- { "/silence", IN_SIL, CM_ARG },
-#ifdef COMMENT
- { "/pattern", IN_PAT, CM_ARG },
-#endif /* COMMENT */
- { "", 0, 0 }
-};
-static int ninswtab = (sizeof(inswtab) / sizeof(struct keytab)) - 1;
-#endif /* COMMENT */
-
-
-#endif /* NOSPL */
-
-static int x, y, z = 0; /* Local workers */
-static char *s;
-
-#ifdef CK_MINPUT
-static char c1chars[] = { /* C1 control chars escept NUL */
- 001,002,003,004,005,006,007,010,011,012,013,014,015,016,017,020,
- 021,022,023,024,025,026,027,030,031,032,033,034,035,036,037
-};
-#endif /* CK_MINPUT */
-
-#define xsystem(s) zsyscmd(s)
-
-/* Top-Level Interactive Command Keyword Table */
-/* Keywords must be in lowercase and in alphabetical order. */
-
-struct keytab cmdtab[] = {
-#ifndef NOPUSH
- { "!", XXSHE, CM_INV|CM_PSH }, /* Shell escape */
-#else
- { "!", XXNOTAV, CM_INV|CM_PSH },
-#endif /* NOPUSH */
- { "#", XXCOM, CM_INV }, /* Comment */
-#ifndef NOSPL
- { "(", XXSEXP,CM_INV }, /* S-Expression */
- { ".", XXDEF, CM_INV }, /* Assignment */
- { ":", XXLBL, CM_INV }, /* Label */
-#endif /* NOSPL */
-#ifdef CK_REDIR
-#ifndef NOPUSH
- { "<", XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
-#else
- { "<", XXNOTAV, CM_INV|CM_PSH }, /* REDIRECT */
-#endif /* NOPUSH */
-#endif /* CK_REDIR */
-#ifndef NOPUSH
- { "@", XXSHE, CM_INV|CM_PSH }, /* DCL escape */
-#else
- { "@", XXNOTAV, CM_INV|CM_PSH }, /* DCL escape */
-#endif /* NOPUSH */
-
-#ifdef CK_RECALL
- { "^", XXREDO,CM_INV|CM_NOR }, /* Synonym for REDO */
-#endif /* CK_RECALL */
-#ifndef NOSPL
- { "_asg", XXASX, CM_INV }, /* Used internally by FOR, etc */
- { "_assign", XXASX, CM_INV }, /* Used internally by FOR, etc */
- { "_decrement", XX_DECR, CM_INV },
- { "_define", XXDFX, CM_INV }, /* Used internally by FOR, etc */
- { "_evaluate", XX_EVAL, CM_INV },
- { "_forward", XXXFWD, CM_INV }, /* Used internally by SWITCH */
- { "_getargs", XXGTA, CM_INV }, /* Used internally by FOR, etc */
- { "_increment", XX_INCR, CM_INV },
- { "_putargs", XXPTA, CM_INV }, /* Used internally by FOR, etc */
- { "_undefine", XXUNDFX, CM_INV },
-#endif /* NOSPL */
-
- { "about", XXVER, CM_INV }, /* Synonym for VERSION */
-#ifndef NOSPL
-#ifdef NEWFTP
- { "account", XXACCT, CM_INV }, /* (FTP) Account */
-#endif /* NEWFTP */
-#ifdef ADDCMD
- { "add", XXADD, 0 }, /* ADD */
-#endif /* ADDCMD */
-#ifndef NODIAL
- { "answer", XXANSW, CM_LOC }, /* ANSWER the phone */
-#else
- { "answer", XXNOTAV, CM_INV|CM_LOC }, /* ANSWER the phone */
-#endif /* NODIAL */
- { "apc", XXAPC, 0 }, /* Application Program Command */
-#ifndef NOSPL
- { "array", XXARRAY, 0 }, /* Array operations */
-#endif /* NOSPL */
- { "ascii", XXASC, CM_INV }, /* == SET FILE TYPE TEXT */
- { "asg", XXASS, CM_INV }, /* Invisible synonym for ASSIGN */
- { "ask", XXASK, 0 }, /* ASK for text, assign to variable */
- { "askq", XXASKQ,0 }, /* ASK quietly (no echo) */
-#ifndef NOSPL
- { "ass", XXASS, CM_INV|CM_ABR }, /* ASSIGN */
- { "assert", XXASSER, CM_INV }, /* ASSERT */
- { "assign", XXASS, 0 }, /* ASSIGN */
-#endif /* NOSPL */
-#ifndef NOXFER
-#ifndef NOCSETS
- { "associate", XXASSOC, 0 }, /* ASSOCIATE */
-#else
- { "associate", XXNOTAV, CM_INV }, /* ASSOCIATE */
-#endif /* NOCSETS */
-#endif /* NOXFER */
-#ifdef CK_KERBEROS
-#ifdef CK_AUTHENTICATION
- { "authenticate",XXAUTH, 0 }, /* Authentication */
-#else
- { "authenticate",XXAUTH, CM_INV },
-#endif /* CK_AUTHENTICATION */
-#endif /* CK_KERBEROS */
-#endif /* NOSPL */
-#ifndef NOFRILLS
- { "back", XXBACK, 0 }, /* BACK to previous directory */
-#else
- { "back", XXNOTAV,CM_INV },
-#endif /* NOFRILLS */
- { "beep", XXBEEP,CM_INV }, /* BEEP */
-#ifndef NOXFER
- { "binary", XXBIN, CM_INV }, /* == SET FILE TYPE BINARY */
-#endif /* NOXFER */
-#ifndef NOFRILLS
- { "bug", XXBUG, CM_INV }, /* BUG report instructions */
-#else
- { "bug", XXNOTAV, CM_INV },
-#endif /* NOFRILLS */
-#ifdef BROWSER
- { "browse", XXBROWS, CM_PSH|CM_LOC }, /* BROWSE (start browser) */
-#else
- { "browse", XXNOTAV, CM_INV|CM_PSH|CM_LOC },
-#endif /* BROWSER */
-#ifndef NOXFER
- { "bye", XXBYE, 0 }, /* BYE to remote server */
-#endif /* NOXFER */
-#ifndef NOLOCAL
- { "c", XXCON, CM_INV|CM_ABR|CM_LOC }, /* (CONNECT) */
-#endif /* NOLOCAL */
-#ifndef NOFRILLS
- { "cat", XXCAT, CM_INV }, /* Invisible synonym for TYPE */
-#endif /* NOFRILLS */
-#ifndef NOSPL
-
-#ifndef NOXFER
- { "cautious", XXCAU, CM_INV },
-#endif /* NOXFER */
-
-#endif /* NOSPL */
-
- { "cd", XXCWD, 0 }, /* Change Directory */
- { "cdup", XXCDUP, CM_INV }, /* Change Directory Up */
-
-#ifndef NOXFER
-#ifdef PIPESEND
- { "cget", XXCGET, CM_INV|CM_PSH }, /* CGET */
-#else
- { "cget", XXNOTAV, CM_INV|CM_PSH }, /* CGET */
-#endif /* PIPESEND */
-#endif /* NOXFER */
- { "ch", XXCHK, CM_INV|CM_ABR },
- { "check", XXCHK, 0 }, /* CHECK for a feature */
-#ifdef CK_PERMS
-#ifdef UNIX
- { "chmod", XXCHMOD, 0 }, /* CHMOD */
-#else
- { "chmod", XXNOTAV, CM_INV },
-#endif /* UNIX */
-#else
- { "chmod", XXNOTAV, CM_INV },
-#endif /* CK_PERMS */
-#ifdef CKROOT
- { "chroot", XXCHRT, CM_INV }, /* CHROOT */
-#endif /* CKROOT */
- { "ckermit", XXKERMI, CM_INV }, /* CKERMIT (like KERMIT) */
- { "cl", XXCLO, CM_ABR|CM_INV },
-#ifndef NOFRILLS
- { "clear", XXCLE, 0 }, /* CLEAR input and/or device buffer */
-#else
- { "clear", XXNOTAV, CM_INV },
-#endif /* NOFRILLS */
- { "close", XXCLO, 0 }, /* CLOSE a log or other file */
- { "cls", XXCLS, CM_INV }, /* Clear Screen (CLS) */
- { "comment", XXCOM, CM_INV }, /* Introduce a comment */
-#ifndef NOLOCAL
- { "connect", XXCON, CM_LOC }, /* Begin terminal connection */
-#else
- { "connect", XXNOTAV, CM_LOC },
-#endif /* NOLOCAL */
- { "continue", XXCONT, CM_INV }, /* CONTINUE */
-#ifndef NOFRILLS
-#ifdef ZCOPY
- { "co", XXCPY, CM_INV|CM_ABR },
- { "cop", XXCPY, CM_INV|CM_ABR },
- { "copy", XXCPY, 0 }, /* COPY a file */
-#else
- { "copy", XXNOTAV, CM_INV },
-#endif /* ZCOPY */
- { "copyright", XXCPR, CM_INV }, /* COPYRIGHT */
-#ifdef ZCOPY
- { "cp", XXCPY, CM_INV }, /* COPY a file */
-#endif /* ZCOPY */
-#ifndef NOLOCAL
-#ifndef OS2
- { "cq", XXCQ, CM_INV|CM_LOC }, /* CQ (connect quietly) */
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifndef NOXFER
-#ifdef PIPESEND
- { "creceive", XXCREC,CM_INV|CM_PSH }, /* RECEIVE to a command */
- { "csend", XXCSEN,CM_INV|CM_PSH }, /* SEND from command */
-#else
- { "creceive", XXNOTAV,CM_INV|CM_PSH },
- { "csend", XXNOTAV,CM_INV|CM_PSH },
-#endif /* PIPESEND */
-#endif /* NOXFER */
-#endif /* NOFRILLS */
-
- { "cwd", XXCWD, CM_INV }, /* Traditional synonym for cd */
-
-#ifndef NOSPL
- { "date", XXDATE, 0 }, /* DATE */
- { "dcl", XXDCL, CM_INV }, /* DECLARE an array (see ARRAY) */
- { "debug", XXDEBUG, 0 }, /* Print a debugging msg [9.0] */
- { "declare", XXDCL, CM_INV }, /* DECLARE an array (see ARRAY) */
- { "decrement", XXDEC, 0 }, /* DECREMENT a numeric variable */
- { "define", XXDEF, 0 }, /* DEFINE a macro or variable */
-#else
- { "date", XXNOTAV, CM_INV },
- { "dcl", XXNOTAV, CM_INV },
- { "declare", XXNOTAV, CM_INV },
- { "decrement", XXNOTAV, CM_INV },
- { "define", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
- { "delete", XXDEL, 0 }, /* DELETE a file */
-#else
- { "delete", XXNOTAV, CM_INV },
-#endif /* NOFRILLS */
-
-#ifndef NODIAL
- { "dial", XXDIAL, CM_LOC }, /* DIAL a phone number */
-#else
- { "dial", XXNOTAV, CM_INV|CM_LOC },
-#endif /* NODIAL */
-
-#ifdef NT
- { "dialer", XXDIALER, CM_INV }, /* K95 Dialer */
-#endif /* NT */
-
- { "directory", XXDIR, 0 }, /* DIRECTORY of files */
-
-#ifndef NOFRILLS
-#ifndef NOSERVER
- { "disable", XXDIS, 0 }, /* DISABLE a server function */
-#else
- { "disable", XXNOTAV, CM_INV },
-#endif /* NOSERVER */
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
- { "do", XXDO, 0 }, /* DO (execute) a macro */
-#else
- { "do", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
- { "e", XXEXI, CM_INV|CM_ABR },
-
-#ifndef NOFRILLS
-#ifndef NOXFER
- { "e-packet", XXERR, CM_INV }, /* Send an Error-Packet */
-#endif /* NOXFER */
-#endif /* NOFRILLS */
-
- { "echo", XXECH, 0 }, /* ECHO text */
-
-#ifndef NOFRILLS
-#ifndef NOPUSH
- { "edit", XXEDIT, CM_PSH }, /* EDIT */
-#else
- { "edit", XXNOTAV, CM_INV|CM_PSH }, /* EDIT */
-#endif /* NOPUSH */
-#endif /* NOFRILLS */
-
- { "eightbit", XXEIGHT, CM_INV }, /* EIGHTBIT */
-
-#ifndef NOSPL
- { "else", XXELS, CM_INV }, /* ELSE part of IF statement */
-#else
- { "else", XXNOTAV, CM_INV }, /* ELSE part of IF statement */
-#endif /* NOSPL */
-
-#ifndef NOSERVER
-#ifndef NOFRILLS
- { "enable", XXENA, 0 }, /* ENABLE a server function */
-#else
- { "enable", XXNOTAV, CM_INV },
-#endif /* NOFRILLS */
-#endif /* NOSERVER */
-
-#ifndef NOSPL
- { "end", XXEND, 0 }, /* END command file or macro */
-#else
- { "end", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
- { "erase", XXDEL, CM_INV }, /* Synonym for DELETE */
-
-#ifndef NOSPL
- { "evaluate", XXEVAL, 0 }, /* EVALUATE */
-#else
- { "evaluate", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
- { "ex", XXEXI, CM_INV|CM_ABR }, /* Let "ex" still be EXIT */
-
-#ifdef CKEXEC
- { "exec", XXEXEC, CM_INV|CM_LOC }, /* exec() */
-#else
- { "exec", XXNOTAV, CM_INV|CM_LOC },
-#endif /* CKEXEC */
-
- { "exit", XXEXI, 0 }, /* EXIT from C-Kermit */
- { "extended-options", XXXOPTS,CM_INV|CM_HLP }, /* Extended-Options */
-
-#ifdef OS2
- { "extproc", XXCOM, CM_INV }, /* Dummy command for OS/2 */
-#endif /* OS2 */
-
-#ifndef NOXFER
- { "f", XXFIN, CM_INV|CM_ABR }, /* Invisible abbrev for FIN */
-#endif /* NOXFER */
-
-#ifndef NOSPL
- { "fail", XXFAIL, CM_INV }, /* FAIL */
-
-#ifndef NOXFER
- { "fast", XXFAST, CM_INV },
-#endif /* NOXFER */
-
-#ifdef CKCHANNELIO
- { "fclose", XXF_CL, CM_INV }, /* FCLOSE */
- { "fcount", XXF_CO, CM_INV }, /* FCOUNT */
- { "fflush", XXF_FL, CM_INV }, /* FFLUSH */
-#endif /* CKCHANNELIO */
-
-#ifndef NOXFER
- { "fi", XXFIN, CM_INV|CM_ABR }, /* FINISH */
-#endif /* NOXFER */
-
-#ifdef CKCHANNELIO
- { "file", XXFILE, 0 }, /* FILE */
-#endif /* CKCHANNELIO */
-#endif /* NOSPL */
-
-#ifndef NOXFER
- { "fin", XXFIN, CM_INV|CM_ABR }, /* FINISH */
-#endif /* NOXFER */
-
-#ifndef UNIXOROSK
- { "find", XXGREP, 0 }, /* FIND (grep) */
-#else
- { "find", XXGREP,CM_INV },
-#endif /* UNIXOROSK */
-
-#ifndef NOXFER
- { "finish", XXFIN, 0 }, /* FINISH */
-#endif /* NOXFER */
-
-#ifdef TCPSOCKET
- { "firewall", XXFIREW, CM_INV|CM_HLP },
-#endif /* TCPSOCKET */
-
-#ifdef CKCHANNELIO
- { "flist", XXF_LI, CM_INV }, /* FLIST */
- { "fopen", XXF_OP, CM_INV }, /* FOPEN */
-#endif /* CKCHANNELIO */
-
-#ifndef NOSPL
- { "fo", XXFOR, CM_INV|CM_ABR }, /* Invisible abbrev for... */
- { "for", XXFOR, 0 }, /* FOR loop */
- { "forward", XXFWD, CM_INV }, /* FORWARD */
-#endif /* NOSPL */
-#ifndef NOFRILLS
- { "fot", XXDIR, CM_INV }, /* "fot" = "dir" (for Chris) */
-#endif /* NOFRILLS */
-
-#ifdef CKCHANNELIO
- { "fread", XXF_RE, CM_INV }, /* FREAD */
- { "frewind", XXF_RW, CM_INV }, /* FREWIND */
- { "fseek", XXF_SE, CM_INV }, /* FSEEK */
- { "fstatus", XXF_ST, CM_INV }, /* FSTATUS */
-#endif /* CKCHANNELIO */
-
-#ifdef TCPSOCKET
-#ifndef NOFTP
-#ifdef SYSFTP
-#ifndef NOPUSH
- { "ftp", XXFTP, CM_INV|CM_PSH|CM_LOC }, /* System FTP */
-#else
- { "ftp", XXNOTAV, CM_INV|CM_PSH|CM_LOC },
-#endif /* NOPUSH */
-#else /* SYSFTP */
- { "ftp", XXFTP, 0 }, /* Built-in FTP */
-#endif /* SYSFTP */
-#else /* NOFTP */
- { "ftp", XXNOTAV, CM_INV }, /* No FTP */
-#endif /* NOFTP */
-#endif /* TCPSOCKET */
-
-#ifndef NOSPL
- { "function", XXFUNC, CM_INV|CM_HLP }, /* (for HELP FUNCTION) */
-#endif /* NOSPL */
-
-#ifdef CKCHANNELIO
- { "fwrite", XXF_WR, CM_INV }, /* FWRITE */
-#endif /* CKCHANNELIO */
-
-#ifndef NOXFER
- { "g", XXGET, CM_INV|CM_ABR }, /* Invisible abbrev for GET */
-#ifndef NOSPL
- { "ge", XXGET, CM_INV|CM_ABR }, /* Ditto */
-#endif /* NOSPL */
- { "get", XXGET, 0 }, /* GET */
-#endif /* NOXFER */
-#ifndef NOSPL
- { "getc", XXGETC, 0 }, /* GETC */
-#ifdef OS2
- { "getkeycode", XXGETK, 0 }, /* GETKEYCODE */
-#endif /* OS2 */
-#ifndef NOFRILLS
- { "getok", XXGOK, 0 }, /* GETOK (ask for Yes/No/OK) */
-#endif /* NOFRILLS */
-#endif /* NOSPL */
-#ifndef NOSPL
- { "goto", XXGOTO,0 }, /* GOTO label in take file or macro */
-#endif /* NOSPL */
-#ifdef UNIXOROSK
- { "grep", XXGREP,0 }, /* GREP (find) */
-#else
- { "grep", XXGREP,CM_INV }, /* GREP (find) */
-#endif /* UNIXOROSK */
- { "h", XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
- { "he", XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
-#ifndef NOFRILLS
- { "head", XXHEAD, 0 },
-#endif /* NOFRILLS */
-#ifndef NOLOCAL
- { "hangup", XXHAN, CM_LOC }, /* HANGUP the connection */
-#endif /* NOLOCAL */
- { "hdirectory", XXHDIR, CM_INV }, /* DIR sorted by size biggest first */
- { "HELP", XXHLP, 0 }, /* Display HELP text */
-#ifndef NOHTTP
-#ifdef TCPSOCKET
- { "http", XXHTTP, 0 }, /* HTTP operations */
-#endif /* TCPSOCKET */
-#endif /* NOHTTP */
-#ifndef NOSPL
- { "i", XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
- { "if", XXIF, 0 }, /* IF ( condition ) command */
-#ifdef TCPSOCKET
- { "iksd", XXIKSD, CM_INV }, /* Make connection to IKSD */
-#else
- { "iksd", XXNOTAV, CM_INV },
-#endif /* TCPSOCKET */
- { "in", XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
- { "increment", XXINC, 0 }, /* Increment a numeric variable */
- { "input", XXINP, 0 }, /* INPUT text from comm device */
-#endif /* NOSPL */
-
-#ifndef NOHELP
- { "int", XXINT, CM_INV|CM_ABR },
- { "intr", XXINT, CM_INV|CM_ABR },
- { "INTRO", XXINT, 0 },
- { "introduction",XXINT, CM_INV }, /* Print introductory text */
-#else
- { "intro", XXNOTAV, CM_INV },
- { "introduction",XXNOTAV, CM_INV },
-#endif /* NOHELP */
-
-#ifdef OS2
- { "k95", XXKERMI, CM_INV }, /* Hmmm what's this... */
-#endif /* OS2 */
-
-#ifndef NOSPL
- { "kcd", XXKCD, 0 },
-#endif /* NOSPL */
-
- { "kermit", XXKERMI, CM_INV },
-
-#ifdef OS2
-#ifndef NOKVERBS
- { "kverb", XXKVRB, CM_INV|CM_HLP }, /* Keyboard verb */
-#endif /* NOKVERBS */
-#endif /* OS2 */
-
-#ifndef NOFRILLS
- { "l", XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */
-#endif /* NOFRILLS */
-
- { "lcd", XXLCWD, CM_INV },
- { "lcdup", XXLCDU, CM_INV },
- { "lcwd", XXLCWD, CM_INV },
- { "ldelete", XXLDEL, CM_INV },
- { "ldirectory", XXLDIR, CM_INV },
-
-#ifdef CKLEARN
- { "learn", XXLEARN, 0 }, /* LEARN - automatic script writing */
-#else
- { "learn", XXNOTAV, CM_INV },
-#endif /* CKLEARN */
-
- { "li", XXLNOUT, CM_INV|CM_ABR },
- { "LICENSE", XXCPR, 0 }, /* LICENSE */
-
-#ifndef NOSPL
- { "lineout", XXLNOUT, 0 }, /* LINEOUT = OUTPUT + eol */
-#endif /* NOSPL */
-
-#ifdef NT
- { "link", XXLINK, 0 }, /* LINK source destination */
-#endif /* NT */
-
- { "lmkdir", XXLMKD, CM_INV },
- { "lmv", XXLREN, CM_INV },
-
-#ifndef NOFRILLS
- { "lo", XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
- { "local", XXLOCAL, CM_INV }, /* LOCAL variable declaration */
-#else
- { "local", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
- { "locus", XXLOCU, CM_INV|CM_HLP }, /* "help locus" */
-
- { "log", XXLOG, 0 }, /* Open a log file */
-
- { "login", XXLOGIN, 0 }, /* (REMOTE) LOGIN to server or IKSD */
- { "logout", XXLOGOUT, 0 }, /* LOGOUT from server or IKSD */
-
-#ifndef NOFRILLS
-#ifndef NODIAL
- { "lookup", XXLOOK, 0 }, /* LOOKUP */
-#else
- { "lookup", XXNOTAV, CM_INV },
-#endif /* NODIAL */
-
- { "lpwd", XXLPWD, CM_INV },
- { "lrename", XXLREN, CM_INV },
- { "lrmdir", XXLRMD, CM_INV },
-
-#ifdef UNIXOROSK
- { "ls", XXLS, CM_INV|CM_PSH }, /* UNIX ls command */
-#else
- { "ls", XXDIR, CM_INV }, /* Invisible synonym for DIR */
-#endif /* UNIXOROSK */
-#ifndef NOXFER
- { "mail", XXMAI, 0 }, /* Send a file as e-mail */
-#endif /* NOXFER */
-#ifndef NOHELP
- { "manual", XXMAN, CM_PSH }, /* MAN(UAL) */
-#else
- { "manual", XXNOTAV, CM_INV|CM_PSH },
-#endif /* NOHELP */
-#endif /* NOFRILLS */
-#ifdef CK_MKDIR
- { "md", XXMKDIR, CM_INV }, /* Synonym for MKDIR */
-#endif /* CK_MKDIR */
- { "message", XXMSG, 0 }, /* Print debugging message */
-#ifdef CK_MINPUT
- { "minput", XXMINP, 0 }, /* MINPUT */
-#else
- { "minput", XXNOTAV, CM_INV },
-#endif /* CK_MINPUT */
-#ifndef NOMSEND
- { "mget", XXMGET, 0 }, /* MGET */
-#else
- { "mget", XXNOTAV, CM_INV },
-#endif /* NOMSEND */
-#ifdef CK_MKDIR
- { "mkdir", XXMKDIR, 0 }, /* MKDIR */
-#else
- { "mkdir", XXNOTAV, CM_INV },
-#endif /* CK_MKDIR */
-
-#ifndef NOXFER
-#ifndef NOMSEND
- { "mmove", XXMMOVE, 0 }, /* MMOVE */
-#else
- { "mmove", XXNOTAV, CM_INV },
-#endif /* NOMSEND */
-#endif /* NOXFER */
-
-#ifndef NOFRILLS
- { "more", XXMORE, CM_INV }, /* MORE */
-#endif /* NOFRILLS */
-
-#ifndef NOXFER
- { "move", XXMOVE, 0 }, /* MOVE */
-#endif /* NOXFER */
-
-#ifndef NOSPL
- { "mpause", XXMSL, CM_INV }, /* Millisecond sleep */
-#else
- { "mpause", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOXFER
-#ifndef NOMSEND
- { "mput", XXMSE, CM_INV }, /* MPUT = MSEND */
- { "ms", XXMSE, CM_INV|CM_ABR },
- { "msend", XXMSE, 0 }, /* Multiple SEND */
-#else
- { "mput", XXNOTAV, CM_INV },
- { "msend", XXNOTAV, CM_INV },
-#endif /* NOMSEND */
-#endif /* NOXFER */
- { "msg", XXMSG, CM_INV }, /* Print debugging message */
-#ifndef NOSPL
- { "msleep", XXMSL, 0 }, /* Millisecond sleep */
-#else
- { "msleep", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-#ifndef NOFRILLS
- { "mv", XXREN, CM_INV }, /* Synonym for rename */
-#endif /* NOFRILLS */
-#ifndef NOHELP
- { "news", XXNEW, CM_INV }, /* Display NEWS of new features */
-#else
- { "news", XXNOTAV, CM_INV },
-#endif /* NOHELP */
- { "nolocal", XXNLCL, CM_INV }, /* Disable SET LINE / SET HOST */
- { "nopush", XXNPSH, CM_INV }, /* Disable PUSH command/features */
-#ifdef OS2
- { "noscroll", XXNSCR, CM_INV }, /* Disable scroll operations */
-#endif /* OS2 */
-#ifndef NOSPL
- { "o", XXOUT, CM_INV|CM_ABR }, /* Invisible synonym for OUTPUT */
- { "open", XXOPE, 0 }, /* OPEN file for reading or writing */
-#else
- { "open", XXOPE, CM_INV }, /* OPEN */
-#endif /* NOSPL */
-#ifndef NOHELP
- { "options", XXOPTS,CM_INV|CM_HLP }, /* Options */
-#endif /* NOHELP */
- { "orientation", XXORIE, 0 },
-#ifndef NOSPL
- { "output", XXOUT, 0 }, /* OUTPUT text to comm device */
-#else
- { "output", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-#ifdef ANYX25
-#ifndef IBMX25
- { "pad", XXPAD, CM_LOC }, /* X.3 PAD commands */
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifdef NEWFTP
- { "passive", XXPASV, CM_INV }, /* (FTP) PASSIVE */
-#endif /* NEWFTP */
-
-#ifndef NOHELP
- { "patterns", XXPAT,CM_INV|CM_HLP }, /* Pattern syntax */
-#endif /* NOHELP */
-
-#ifndef NOSPL
- { "pause", XXPAU, 0 }, /* Sleep for specified interval */
-#else
- { "pause", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-#ifndef NODIAL
- { "pdial", XXPDIA, CM_LOC }, /* PDIAL (partial dial) */
-#else
- { "pdial", XXNOTAV, CM_INV|CM_LOC },
-#endif /* NODIAL */
-#ifdef TCPSOCKET
-#ifndef NOPUSH
- { "ping", XXPNG, CM_INV|CM_PSH|CM_LOC }, /* PING */
-#else
- { "ping", XXNOTAV, CM_INV|CM_PSH|CM_LOC },
-#endif /* NOPUSH */
-#endif /* TCPSOCKET */
-#ifdef NETCMD
-#ifndef NOPUSH
- { "pipe", XXPIPE, CM_PSH }, /* PIPE */
-#else
- { "pipe", XXNOTAV, CM_INV|CM_PSH }, /* PIPE */
-#endif /* NOPUSH */
-#endif /* NETCMD */
-
-#ifndef NOSPL
- { "pop", XXEND, CM_INV }, /* Invisible synonym for END */
-#endif /* NOSPL */
-#ifndef NOFRILLS
- { "print", XXPRI, 0 }, /* PRINT a file locally */
-#endif /* NOFRILLS */
-
- { "prompt", XXPROMP, CM_INV }, /* Go interactive (from script) */
-
-#ifndef NOXFER
-#ifdef CK_RESEND
- { "psend", XXPSEN, CM_INV }, /* PSEND */
-#else
- { "psend", XXNOTAV, CM_INV },
-#endif /* CK_RESEND */
-#endif /* NOXFER */
-
-#ifdef NETPTY
- { "pty", XXPTY, CM_PSH }, /* PTY */
-#else
- { "pty", XXNOTAV, CM_INV|CM_PSH },
-#endif /* NETPTY */
-
-#ifndef NOPUSH
- { "pu", XXSHE, CM_INV|CM_ABR|CM_PSH }, /* PU = PUSH */
-#endif /* NOPUSH */
-
-#ifdef CKPURGE
- { "purge", XXPURGE, 0 }, /* PURGE (real) */
-#else
-#ifdef VMS
- { "purge", XXPURGE, 0 }, /* PURGE (fake) */
-#else
- { "purge", XXNOTAV, CM_INV },
-#endif /* VMS */
-#endif /* CKPURGE */
-
-#ifndef NOPUSH
- { "push", XXSHE, CM_PSH }, /* PUSH command (like RUN, !) */
-#else
- { "push", XXNOTAV, CM_INV|CM_PSH },
-#endif /* NOPUSH */
-
-#ifndef NOXFER
- { "put", XXSEN, CM_INV }, /* PUT = SEND */
-#endif /* NOXFER */
-
-#ifdef UNIX
-#ifndef NOPUTENV
- { "putenv", XXPUTE, CM_INV }, /* PUTENV */
-#endif /* NOPUTENV */
-#endif /* UNIX */
-
- { "pwd", XXPWD, 0 }, /* Print Working Directory */
- { "q", XXQUI, CM_INV|CM_ABR }, /* Invisible synonym for QUIT */
-
-#ifndef NOXFER
- { "query", XXRQUE,CM_INV }, /* (= REMOTE QUERY) */
-#endif /* NOXFER */
-
- { "quit", XXQUI, 0 }, /* QUIT from program = EXIT */
-
-#ifndef NOXFER
- { "r", XXREC, CM_INV|CM_ABR }, /* Inv synonym for RECEIVE */
-#endif /* NOXFER */
-
-#ifndef NOXFER
- { "rasg", XXRASG, CM_INV }, /* REMOTE ASSIGN */
- { "rassign", XXRASG, CM_INV }, /* ditto */
- { "rcd", XXRCWD, CM_INV }, /* REMOTE CD */
- { "rcdup", XXRCDUP,CM_INV }, /* REMOTE CD */
- { "rcopy", XXRCPY, CM_INV }, /* REMOTE COPY */
- { "rcwd", XXRCWD, CM_INV }, /* REMOTE CWD */
- { "rdelete", XXRDEL, CM_INV }, /* REMOTE DELETE */
- { "rdirectory", XXRDIR, CM_INV }, /* REMODE DIRECTORY */
-#endif /* NOXFER */
-
-#ifndef NOSPL
- { "read", XXREA, 0 }, /* READ a line from a file */
-#else
- { "read", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOXFER
- { "receive", XXREC, 0 }, /* RECEIVE files */
-#endif /* NOXFER */
-
-#ifndef NODIAL
- { "red", XXRED, CM_INV|CM_ABR|CM_LOC }, /* Inv syn for REDIAL */
- { "redi", XXRED, CM_INV|CM_ABR|CM_LOC }, /* ditto */
- { "redial", XXRED, CM_LOC }, /* REDIAL last DIAL number */
-#else
- { "red", XXNOTAV, CM_INV|CM_LOC },
- { "redi", XXNOTAV, CM_INV|CM_LOC },
- { "redial", XXNOTAV, CM_INV|CM_LOC },
-#endif /* NODIAL */
-
-#ifdef CK_REDIR
-#ifdef OS2
-#ifndef NOPUSH
- { "redirect", XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
-#else
- { "redirect", XXNOTAV, CM_INV|CM_PSH },
-#endif /* NOPUSH */
-#else /* OS2 */
-#ifndef NOPUSH
- { "redirect", XXFUN, CM_PSH }, /* REDIRECT */
-#else
- { "redirect", XXNOTAV, CM_INV|CM_PSH },
-#endif /* NOPUSH */
-#endif /* OS2 */
-#endif /* CK_REDIR */
-
-#ifdef CK_RECALL
- { "redo", XXREDO, CM_NOR }, /* REDO */
-#else
- { "redo", XXNOTAV, CM_INV },
-#endif /* CK_RECALL */
-
-#ifndef NOXFER
-#ifdef CK_RESEND
- { "reget", XXREGET, 0 }, /* REGET */
-#else
- { "reget", XXNOTAV, CM_INV },
-#endif /* CK_RESEND */
-#endif /* NOXFER */
-
-#ifndef NOSPL
- { "reinput", XXREI, CM_INV }, /* REINPUT (from INPUT buffer) */
-#else
- { "reinput", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOXFER
-#ifdef ADDCMD
- { "rem", XXREM, CM_INV|CM_ABR },
- { "remo", XXREM, CM_INV|CM_ABR },
-#endif /* ADDCMD */
- { "remote", XXREM, 0 }, /* Send REMOTE command to server */
-#endif /* NOXFER */
-
-#ifdef ADDCMD
- { "remove", XXREMV,0 }, /* REMOVE (something from a list) */
-#else
- { "remove", XXNOTAV, CM_INV },
-#endif /* ADDCMD */
-
-#ifndef NOFRILLS
-#ifndef NORENAME
- { "rename", XXREN, 0 }, /* RENAME a local file */
-#else
- { "rename", XXNOTAV, CM_INV },
-#endif /* NORENAME */
- { "replay", XXTYP, CM_INV }, /* REPLAY (for now, just type) */
-#endif /* NOFRILLS */
-
-#ifndef NOXFER
-#ifdef CK_RESEND
- { "rep", XXTYP, CM_INV|CM_ABR }, /* REPLAY abbreviation */
- { "reput", XXRSEN, CM_INV }, /* REPUT = RESEND */
- { "res", XXRSEN, CM_INV|CM_ABR }, /* RESEND */
- { "rese", XXRSEN, CM_INV|CM_ABR }, /* RESEND */
- { "resend", XXRSEN, 0 }, /* RESEND */
-#else
- { "reput", XXNOTAV, CM_INV },
- { "res", XXNOTAV, CM_INV },
- { "rese", XXNOTAV, CM_INV },
- { "resend", XXNOTAV, CM_INV },
-#endif /* CK_RESEND */
-#endif /* NOXFER */
-
- { "reset", XXRESET, CM_INV }, /* RESET */
-
-#ifdef CK_RESEND
-#ifndef NOSPL
- { "ret", XXRET, CM_INV|CM_ABR },
-#endif /* NOSPL */
-#endif /* CK_RESEND */
-
-#ifndef NOXFER
- { "retrieve", XXRETR, CM_INV }, /* RETRIEVE */
-#endif /* NOXFER */
-
-#ifndef NOSPL
- { "return", XXRET, 0 }, /* RETURN from a function */
-#else
- { "return", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOXFER
- { "rexit", XXRXIT, CM_INV }, /* REMOTE EXIT */
-#endif /* NOXFER */
-
-#ifdef CK_REXX
-#ifndef NOPUSH
- { "rexx", XXREXX, CM_PSH }, /* Execute a Rexx command */
-#else
- { "rexx", XXNOTAV, CM_INV|CM_PSH },
-#endif /* NOPUSH */
-#endif /* CK_REXX */
-
-#ifndef NOXFER
- { "rhelp", XXRHLP, CM_INV }, /* REMOTE HELP */
- { "rhost", XXRHOS, CM_INV }, /* REMOTE HOST */
- { "rkermit", XXRKER, CM_INV }, /* REMOTE KERMIT */
-#endif /* NOXFER */
-
-#ifdef TCPSOCKET
- { "rlogin", XXRLOG, CM_LOC }, /* Make an Rlogin connection */
-#else
- { "rlogin", XXNOTAV, CM_INV|CM_LOC },
-#endif /* TCPSOCKET */
-
-#ifndef NOFRILLS
- { "rm", XXDEL, CM_INV }, /* Invisible synonym for delete */
-#endif /* NOFRILLS */
-
-#ifdef CK_MKDIR
- { "rmdir", XXRMDIR, 0 }, /* RMDIR */
-#else
- { "rmdir", XXNOTAV, CM_INV },
-#endif /* CK_MKDIR */
-
-#ifndef NOXFER
- { "rmessage", XXRMSG, CM_INV }, /* REMOTE MESSAGE */
- { "rmkdir", XXRMKD, CM_INV }, /* REMOTE MKDIR */
- { "rmsg", XXRMSG, CM_INV }, /* REMOTE MESSAGE */
-#ifndef NOSPL
- { "robust", XXROB, CM_INV },
-#else
- { "robust", XXNOTAV, CM_INV },
-#endif /* NOSPL */
- { "rprint", XXRPRI, CM_INV }, /* REMOTE PRINT */
- { "rpwd", XXRPWD, CM_INV }, /* REMOTE PWD */
- { "rquery", XXRQUE, CM_INV }, /* REMOTE QUERY */
-#endif /* NOXFER */
-
-#ifdef CK_RECALL
- { "rr", XXREDO, CM_INV|CM_NOR },
-#endif /* CK_RECALL */
-
-#ifndef NOXFER
- { "rrename", XXRREN, CM_INV }, /* REMOTE RENAME */
- { "rrmdir", XXRRMD, CM_INV }, /* REMOTE REMDIR */
- { "rset", XXRSET, CM_INV }, /* REMOTE SET */
- { "rspace", XXRSPA, CM_INV }, /* REMOTE SPACE */
- { "rtype", XXRTYP, CM_INV }, /* REMOTE TYPE */
-#endif /* NOXFER */
-
-#ifndef NOPUSH
- { "run", XXSHE, CM_PSH }, /* RUN a program or command */
-#else
- { "run", XXNOTAV, CM_INV|CM_PSH },
-#endif /* NOPUSH */
-
-#ifndef NOXFER
- { "rwho", XXRWHO, CM_INV }, /* REMOTE WHO */
- { "s", XXSEN, CM_INV|CM_ABR }, /* Invisible synonym for send */
-#endif /* NOXFER */
-
-#ifndef NOSETKEY
-#ifdef OS2
- { "save", XXSAVE, 0 }, /* SAVE something */
-#else
- { "save", XXSAVE, CM_INV },
-#endif /* OS2 */
-#else
- { "save", XXNOTAV, CM_INV },
-#endif /* NOSETKEY */
-
-#ifndef NOSCRIPT
- { "sc", XXLOGI, CM_INV|CM_ABR|CM_LOC },
- { "scr", XXLOGI, CM_INV|CM_ABR|CM_LOC },
-#endif /* NOSCRIPT */
- { "screen", XXSCRN, 0 }, /* SCREEN actions */
-#ifndef NOSCRIPT
- { "script", XXLOGI, CM_LOC }, /* Expect-Send-style script line */
-#else
- { "script", XXNOTAV, CM_INV|CM_LOC },
-#endif /* NOSCRIPT */
-
- { "search", XXGREP,CM_INV }, /* Synonym for GREP and FIND */
-
-#ifndef NOXFER
- { "send", XXSEN, 0 }, /* Send (a) file(s) */
-#ifndef NOSERVER
- { "server", XXSER, 0 }, /* Be a SERVER */
-#else
- { "server", XXNOTAV, CM_INV },
-#endif /* NOSERVER */
-#endif /* NOXFER */
-
- { "set", XXSET, 0 }, /* SET parameters */
-
-#ifndef NOSPL
-#ifndef NOSEXP
- { "sexpression", XXSEXP, CM_INV|CM_HLP }, /* SEXPR */
-#endif /* NOSEXP */
-
-#ifdef SFTP_BUILTIN
- { "sftp", XXSFTP, 0 }, /* SFTP */
-#endif /* SFTP_BUILTIN */
-
-#ifndef NOSHOW
- { "sh", XXSHO, CM_INV|CM_ABR }, /* SHOW parameters */
-#endif /* NOSHOW */
- { "shift", XXSHIFT, 0 }, /* SHIFT args */
-#else
- { "shift", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOSHOW
- { "show", XXSHO, 0 }, /* SHOW parameters */
-#else
- { "show", XXNOTAV, CM_INV },
-#endif /* NOSHOW */
-
-#ifdef NEWFTP
- { "site", XXSITE, CM_INV }, /* (FTP) SITE */
-#endif /* NEWFTP */
-
-#ifdef SSHBUILTIN
- { "skermit", XXSKRM, 0 }, /* SKERMIT */
-#endif /* SSHBUILTIN */
-
-#ifndef NOSPL
-#ifndef NOFRILLS
- { "sleep", XXPAU, CM_INV }, /* SLEEP for specified interval */
-#endif /* NOFRILLS */
-#endif /* NOSPL */
-
-#ifndef NOSPL
- { "sort", XXSORT, CM_INV }, /* (see ARRAY) */
-#else
- { "sort", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef MAC
-#ifndef NOFRILLS
- { "sp", XXSPA, CM_INV|CM_ABR },
- { "spa", XXSPA, CM_INV|CM_ABR },
-#endif /* NOFRILLS */
- { "space", XXSPA, 0 }, /* Show available disk SPACE */
-#endif /* MAC */
-
-#ifndef NOFRILLS
-#ifndef NOPUSH
- { "spawn", XXSHE, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
-#else
- { "spawn", XXNOTAV, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
-#endif /* NOPUSH */
-#endif /* NOFRILLS */
-
-#ifdef ANYSSH
- { "ssh", XXSSH, 0 },
-#endif /* ANYSSH */
-
-#ifndef NOXFER
- { "sta", XXSTA, CM_INV|CM_ABR },
- { "stat", XXSTA, CM_INV|CM_ABR },
- { "statistics", XXSTA, 0 }, /* Display file transfer stats */
-#endif /* NOXFER */
-
- { "status", XXSTATUS,0 }, /* Show status of previous command */
-
-#ifndef NOSPL
- { "stop", XXSTO, 0 }, /* STOP all take files and macros */
- { "succeed", XXSUCC, CM_INV }, /* SUCCEED */
-#else
- { "stop", XXNOTAV, CM_INV },
- { "succeed", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
- { "SUPPORT", XXBUG, 0 }, /* Tech support instructions */
-#else
- { "support", XXNOTAV, CM_INV },
-#endif /* NOFRILLS */
-
-#ifndef NOJC
- { "suspend", XXSUS, CM_PSH }, /* SUSPEND C-Kermit (UNIX only) */
-#else
- { "suspend", XXNOTAV, CM_INV|CM_PSH },
-#endif /* NOJC */
-
-#ifndef NOSPL
- { "switch", XXSWIT, 0 }, /* SWITCH */
-#else
- { "switch", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifdef CK_TAPI
- { "ta", XXTAK, CM_INV|CM_ABR }, /* (because of TAPI) */
-#endif /* CK_TAPI */
-
-#ifndef NOFRILLS
- { "tail", XXTAIL, 0 }, /* Display end of a local file */
-#endif /* NOFRILLS */
-
- { "take", XXTAK, 0 }, /* TAKE commands from a file */
-
-#ifdef CK_TAPI
- { "tapi", XXTAPI, CM_LOC }, /* Microsoft TAPI commands */
-#else
- { "tapi", XXNOTAV, CM_INV|CM_LOC },
-#endif /* CK_TAPI */
-
-#ifndef NOFRILLS
-#ifdef TCPSOCKET
- { "tel", XXTEL, CM_INV|CM_ABR|CM_LOC },
- { "telnet", XXTEL, CM_LOC }, /* TELNET (TCP/IP only) */
- { "telopt", XXTELOP, CM_INV }, /* TELOPT (ditto) */
-#else
- { "tel", XXNOTAV, CM_INV|CM_LOC },
- { "telnet", XXNOTAV, CM_INV|CM_LOC },
- { "telopt", XXNOTAV, CM_INV },
-#endif /* TCPSOCKET */
-#ifdef OS2
- { "terminal", XXTERM, CM_INV|CM_LOC }, /* == SET TERMINAL TYPE */
-#else
- { "terminal", XXTERM, CM_INV },
-#endif /* OS2 */
-#endif /* NOFRILLS */
-#ifndef NOXFER
- { "text", XXASC, CM_INV }, /* == SET FILE TYPE TEXT */
-#endif /* NOXFER */
- { "touch", XXTOUC, 0 }, /* TOUCH */
-#ifndef NOSPL
- { "trace", XXTRACE, 0 }, /* TRACE */
-#else
- { "trace", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOCSETS
- { "translate", XXXLA, 0 }, /* TRANSLATE local file char sets */
-#else
- { "translate", XXNOTAV, CM_INV },
-#endif /* NOCSETS */
-
-#ifndef NOXMIT
- { "transmit", XXTRA, 0 }, /* Send (upload) a file, no protocol */
-#else
- { "transmit", XXNOTAV, CM_INV },
-#endif /* NOXMIT */
-
-#ifndef NOFRILLS
- { "type", XXTYP, 0 }, /* Display a local file */
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
- { "undcl", XXUNDCL, CM_INV },
- { "undeclare", XXUNDCL, 0 }, /* UNDECLARE an array */
- { "undefine", XXUNDEF, 0 }, /* UNDEFINE a variable or macro */
-#else
- { "undcl", XXNOTAV, CM_INV },
- { "undeclare", XXNOTAV, CM_INV },
- { "undefine", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifdef NEWFTP
- { "user", XXUSER, CM_INV }, /* (FTP) USER */
-#endif /* NEWFTP */
-
- { "version", XXVER, 0 }, /* VERSION-number display */
-
-#ifdef OS2
- { "viewonly", XXVIEW, CM_LOC }, /* VIEWONLY Terminal Mode */
-#endif /* OS2 */
-
- { "void", XXVOID, 0 }, /* VOID */
-
-#ifndef NOSPL
- { "wait", XXWAI, 0 }, /* WAIT */
-#else
- { "wait", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
- { "wdirectory", XXWDIR, CM_INV }, /* Like TOPS-20, reverse chron order */
- { "wermit", XXKERMI, CM_INV },
-
-#ifndef NOXFER
- { "where", XXWHERE, 0 }, /* WHERE (did my file go?) */
-#endif /* NOXFER */
-
-#ifndef NOSPL
- { "while", XXWHI, 0 }, /* WHILE loop */
-#else
- { "while", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef OS2
-#ifndef MAC
-#ifndef NOFRILLS
- { "who", XXWHO, CM_PSH }, /* WHO's logged in? */
-#endif /* NOFRILLS */
-#endif /* MAC */
-#endif /* OS2 */
-
-#ifndef NOHELP
- { "wildcards", XXWILD,CM_INV|CM_HLP }, /* Wildcard syntax */
-#endif /* NOHELP */
-
-#ifndef NOSPL
- { "wr", XXWRI, CM_INV|CM_ABR },
- { "wri", XXWRI, CM_INV|CM_ABR },
- { "writ", XXWRI, CM_INV|CM_ABR },
- { "write", XXWRI, 0 }, /* WRITE characters to a file */
- { "write-line", XXWRL, CM_INV }, /* WRITE a line to a file */
- { "writeln", XXWRL, CM_INV }, /* Pascalisch synonym for write-line */
-#else
- { "wr", XXNOTAV, CM_INV },
- { "wri", XXNOTAV, CM_INV },
- { "writ", XXNOTAV, CM_INV },
- { "write", XXNOTAV, CM_INV },
- { "write-line", XXNOTAV, CM_INV },
- { "writeln", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
- { "xecho", XXXECH,0 }, /* XECHO */
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
- { "xif", XXIFX, CM_INV }, /* Extended IF command (obsolete) */
-#else
- { "xif", XXNOTAV, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOCSETS
- { "xlate", XXXLA, CM_INV }, /* Synonym for TRANSLATE */
-#else
- { "xlate", XXNOTAV, CM_INV },
-#endif /* NOCSETS */
-
-#ifndef NOXMIT
- { "xm", XXTRA, CM_INV|CM_ABR }, /* Avoid conflict with XMESSAGE */
-#else
- { "xm", XXNOTAV, CM_INV|CM_ABR }, /* Synonym for TRANSMIT */
-#endif /* NOXMIT */
-
- { "xmessage", XXXMSG, 0 }, /* Print debugging message */
-
-#ifndef NOXMIT
- { "xmit", XXTRA, CM_INV }, /* Synonym for TRANSMIT */
-#else
- { "xmit", XXNOTAV, CM_INV },
-#endif /* NOXMIT */
-
-#ifndef OS2
-#ifndef NOJC
- { "z", XXSUS, CM_INV|CM_PSH }, /* Synonym for SUSPEND */
-#else
- { "z", XXNOTAV, CM_INV|CM_PSH },
-#endif /* NOJC */
-#endif /* OS2 */
-
-#ifndef NOSPL
- { "{", XXMACRO, CM_INV }, /* Immediate macro */
-#endif /* NOSPL */
- { "", 0, 0 }
-};
-int ncmd = (sizeof(cmdtab) / sizeof(struct keytab)) - 1;
-
-/* NOTE: Tokens must also be entered above into cmdtab[]. */
-
-char toktab[] = {
-#ifndef NOPUSH
- '!', /* Shell escape */
-#endif /* NOPUSH */
- '#', /* Comment */
-#ifndef NOSPL
- '(', /* S-Expression */
- '.', /* Assignment */
-#endif /* NOSPL */
- ';', /* Comment */
-#ifndef NOSPL
- ':', /* Label */
-#endif /* NOSPL */
-#ifndef NOPUSH
-#ifdef CK_REDIR
- '<', /* REDIRECT */
-#endif /* CK_REDIR */
- '@', /* DCL escape */
-#endif /* NOPUSH */
-#ifdef CK_RECALL
- '^', /* Command recall */
-#endif /* CK_RECALL */
-#ifndef NOSPL
- '{', /* Immediate macro */
-#endif /* NOSPL */
- '\0' /* End of this string */
-};
-int xxdot = 0; /* Used with "." token */
-
-struct keytab yesno[] = { /* Yes/No keyword table */
- { "no", 0, 0 },
- { "ok", 1, 0 },
- { "yes", 1, 0 }
-};
-int nyesno = (sizeof(yesno) / sizeof(struct keytab));
-
-/* Save keyword table */
-
-struct keytab savtab[] = {
-#ifdef OS2
- { "command", XSCMD, 0 },
-#else
-#ifdef CK_RECALL
- { "command", XSCMD, 0 },
-#endif /* CK_RECALL */
-#endif /* OS2 */
-#ifndef NOSETKEY
- { "keymap", XSKEY, 0 },
-#endif /* NOSETKEY */
-#ifdef OS2
- { "terminal", XSTERM, 0 },
-#endif /* OS2 */
- { "", 0, 0 }
-};
-int nsav = (sizeof(savtab) / sizeof(struct keytab)) - 1;
-
-/* Parameter keyword table */
-
-struct keytab prmtab[] = {
- { "alarm", XYALRM, 0 },
-#ifdef COMMENT /* SET ANSWER not implemented yet */
-#ifndef NODIAL
- { "answer", XYANSWER,0 },
-#endif /* NODIAL */
-#endif /* COMMENT */
- { "ask-timer", XYTIMER, 0 },
-#ifndef NOXFER
- { "attributes", XYATTR, 0 },
-#endif /* NOXFER */
-#ifdef CK_AUTHENTICATION
- { "authentication", XYAUTH, 0 },
-#else /* CK_AUTHENTICATION */
-#ifdef CK_SSL
- { "authentication", XYAUTH, 0 },
-#endif /* CK_SSL */
-#endif /* CK_AUTHENTICATION */
- { "b", XYBACK, CM_INV|CM_ABR|CM_PSH },
- { "ba", XYBACK, CM_INV|CM_ABR|CM_PSH },
-#ifdef VMS
- { "background", XYBACK, CM_INV|CM_PSH },
- { "batch", XYBACK, CM_PSH },
-#else
- { "background", XYBACK, CM_PSH },
- { "batch", XYBACK, CM_INV|CM_PSH },
-#endif /* VMS */
-#ifndef NOLOCAL
- { "baud", XYSPEE, CM_INV|CM_LOC },
-#endif /* NOLOCAL */
- { "bell", XYBELL, 0 },
-#ifndef NOXFER
- { "block-check", XYCHKT, 0 },
-#endif /* NOXFER */
-#ifdef OS2
-#ifdef BPRINT
- { "bprinter", XYBDCP, CM_INV },
-#endif /* BPRINT */
-#endif /* OS2 */
-#ifdef BROWSER
- { "browser", XYBROWSE,CM_PSH|CM_LOC },
-#endif /* BROWSER */
-#ifndef NOXFER
-#ifdef DYNAMIC
- { "buffers", XYBUF, 0 },
-#endif /* DYNAMIC */
-#endif /* NOXFER */
-#ifndef NOLOCAL
-#ifndef MAC
- { "carrier-watch", XYCARR, CM_LOC },
-#endif /* MAC */
-#endif /* NOLOCAL */
-#ifndef NOSPL
- { "case", XYCASE, 0 },
-#endif /* NOSPL */
- { "cd", XYCD, 0 },
-#ifndef NOXFER
- { "cl", XYCLEAR, CM_INV|CM_ABR },
- { "cle", XYCLEAR, CM_INV|CM_ABR },
- { "clea", XYCLEAR, CM_INV|CM_ABR },
- { "clear", XYCLEAR, CM_INV|CM_ABR },
- { "clear-channel", XYCLEAR, 0 },
- { "clearchannel", XYCLEAR, CM_INV },
-#endif /* NOXFER */
-#ifndef NOLOCAL
- { "close-on-disconnect", XYDISC, CM_INV|CM_LOC },
-#endif /* NOLOCAL */
- { "cmd", XYCMD, CM_INV },
- { "command", XYCMD, 0 },
-#ifdef CK_SPEED
- { "con", XYQCTL, CM_INV|CM_ABR },
-#endif /* CK_SPEED */
- { "console", XYCMD, CM_INV },
-#ifdef CK_SPEED
- { "control-character",XYQCTL, 0 },
-#endif /* CK_SPEED */
-#ifndef NOSPL
- { "count", XYCOUN, 0 },
-#endif /* NOSPL */
-#ifndef NOXFER
- { "d", XYDELA, CM_INV|CM_ABR },
- { "de", XYDELA, CM_INV|CM_ABR },
-#endif /* NOXFER */
- { "debug", XYDEBU, 0 },
-#ifdef VMS
- { "default", XYDFLT, 0 },
-#else
-#ifndef MAC
- { "default", XYDFLT, CM_INV },
-#endif /* MAC */
-#endif /* VMS */
-#ifndef NOXFER
- { "delay", XYDELA, 0 },
- { "destination", XYDEST, 0 },
-#endif /* NOXFER */
-#ifndef NODIAL
- { "di", XYDIAL, CM_INV|CM_ABR|CM_LOC },
- { "dia", XYDIAL, CM_INV|CM_ABR|CM_LOC },
- { "dial", XYDIAL, CM_LOC },
-#endif /* NODIAL */
-#ifdef OS2
- { "dialer", XYDLR, CM_INV },
-#endif /* OS2 */
-#ifndef NOLOCAL
- { "disconnect", XYDISC, CM_LOC },
- { "duplex", XYDUPL, CM_LOC },
-#endif /* NOLOCAL */
-#ifndef NOPUSH
-#ifndef NOFRILLS
- { "editor", XYEDIT, CM_PSH },
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-#ifdef CK_CTRLZ
- { "eof", XYEOF, CM_INV },
-#endif /* CK_CTRLZ */
-#ifndef NOLOCAL
- { "escape-character", XYESC, CM_LOC },
-#endif /* NOLOCAL */
-#ifndef NOSPL
- { "evaluate", XYEVAL, CM_INV },
-#endif /* NOSPL */
- { "exit", XYEXIT, 0 },
-#ifndef NOXFER
-#ifdef CK_XYZ
-#ifndef NOPUSH
-#ifndef XYZ_INTERNAL
- { "external-protocol",XYEXTRN, 0 },
-#endif /* XYZ_INTERNAL */
-#endif /* NOPUSH */
-#endif /* CK_XYZ */
- { "f-ack-bug", XYFACKB, CM_INV },
- { "f-ack-path", XYFACKP, CM_INV },
-#endif /* NOXFER */
- { "file", XYFILE, 0 },
- { "fl", XYFLOW, CM_INV|CM_ABR },
-#ifndef NOSPL
- { "flag", XYFLAG, 0 },
-#endif /* NOSPL */
-#ifdef TCPSOCKET
-#ifndef SYSFTP
-#ifndef NOFTP
- { "ft", XYFTPX, CM_INV|CM_ABR },
- { "ftp", XYFTPX, 0 },
-#endif /* NOFTP */
-#endif /* SYSFTP */
-#endif /* TCPSOCKET */
-#ifdef BROWSER
- { "ftp-client", XYFTP, CM_PSH },
-#endif /* BROWSER */
- { "flow-control", XYFLOW, 0 },
-#ifndef NOSPL
- { "function", XYFUNC, 0 },
-#endif /* NOSPL */
-#ifdef NEWFTP
- { "get-put-remote", XYGPR, 0 },
-#endif /* NEWFTP */
-#ifdef KUI
- { "gui", XYGUI, 0 },
-#endif /* KUI */
- { "handshake", XYHAND, 0 },
- { "hints", XYHINTS, 0 },
-#ifdef NETCONN
- { "host", XYHOST, CM_LOC },
-#endif /* NETCONN */
-#ifndef NOSPL
- { "i", XYINPU, CM_INV|CM_ABR },
-#endif /* NOSPL */
-#ifdef IKSD
- { "iks", XYIKS, 0 },
-#else
- { "iks", XYIKS, CM_INV },
-#endif /* IKSD */
-#ifndef NOSPL
- { "in", XYINPU, CM_INV|CM_ABR },
-#endif /* NOSPL */
-#ifndef NOXFER
- { "incomplete", XYIFD, CM_INV },
-#endif /* NOXFER */
-#ifndef NOSPL
- { "input", XYINPU, 0 },
-#endif /* NOSPL */
-#ifndef NOSETKEY
- { "key", XYKEY, 0 },
-#endif /* NOSETKEY */
- { "l", XYLINE, CM_INV|CM_ABR },
-#ifndef NOCSETS
- { "language", XYLANG, 0 },
-#endif /* NOCSETS */
-#ifndef NOLOCAL
- { "line", XYLINE, CM_LOC },
- { "local-echo", XYLCLE, CM_INV|CM_LOC },
-#endif /* NOLOCAL */
-#ifdef LOCUS
- { "locus", XYLOCUS, 0 },
-#endif /* LOCUS */
-#ifndef NOSPL
- { "login", XYLOGIN, CM_LOC },
-#endif /* NOSPL */
-#ifndef NOSPL
- { "macro", XYMACR, 0 },
-#endif /* NOSPL */
- { "match", XYMATCH, 0 },
-#ifdef COMMENT
-#ifdef VMS
- { "messages", XYMSGS, 0 },
-#endif /* VMS */
-#endif /* COMMENT */
-#ifndef NODIAL
- { "modem", XYMODM, CM_LOC },
-#endif /* NODIAL */
-#ifndef NOLOCAL
-#ifdef OS2MOUSE
- { "mouse", XYMOUSE, 0 },
-#endif /* OS2MOUSE */
-#endif /* NOLOCAL */
-#ifdef OS2
- { "mskermit", XYMSK, 0 },
-#endif /* OS2 */
-#ifdef NETCONN
- { "network", XYNET, CM_LOC },
-#endif /* NETCONN */
-#ifndef NOSPL
- { "output", XYOUTP, 0 },
-#endif /* NOSPL */
- { "options", XYOPTS, 0 },
- { "pause", XYSLEEP, CM_INV },
-#ifdef ANYX25
-#ifndef IBMX25
- { "pad", XYPAD, CM_LOC },
-#endif /* IBMX25 */
-#endif /* ANYX25 */
- { "parity", XYPARI, 0 },
-#ifndef NOLOCAL
-#ifdef OS2
- { "port", XYLINE, CM_LOC },
-#else
- { "port", XYLINE, CM_INV|CM_LOC },
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifndef NOFRILLS
- { "pr", XYPROM, CM_INV|CM_ABR },
- { "printer", XYPRTR, 0 },
-#endif /* NOFRILLS */
-#ifdef OS2
- { "priority", XYPRTY, 0 },
-#endif /* OS2 */
-#ifdef CK_SPEED
- { "prefixing", XYPREFIX, 0 },
-#endif /* CK_SPEED */
-#ifndef NOFRILLS
- { "prompt", XYPROM, 0 },
-#endif /* NOFRILLS */
-#ifndef NOXFER
- { "protocol", XYPROTO, 0 },
-#endif /* NOXFER */
- { "q", XYQUIE, CM_INV|CM_ABR },
-#ifndef NOXFER
- { "q8flag", XYQ8FLG, CM_INV },
-#endif /* NOXFER */
-#ifdef QNX
- { "qnx-port-lock", XYQNXPL, 0 },
-#else
- { "qnx-port-lock", XYQNXPL, CM_INV },
-#endif /* QNX */
- { "quiet", XYQUIE, 0 },
-#ifndef NOXFER
- { "rec", XYRECV, CM_INV|CM_ABR },
- { "receive", XYRECV, 0 },
- { "recv", XYRECV, CM_INV },
-#endif /* NOXFER */
- { "reliable", XYRELY, 0 },
- { "rename", XY_REN, 0 },
-#ifndef NOXFER
- { "repeat", XYREPT, 0 },
- { "retry-limit", XYRETR, 0 },
-#endif /* NOXFER */
-#ifdef CKROOT
- { "root", XYROOT, 0 },
-#endif /* CKROOT */
-#ifndef NOSCRIPT
- { "script", XYSCRI, CM_LOC },
-#endif /* NOSCRIPT */
-#ifndef NOXFER
- { "send", XYSEND, 0 },
-#ifndef NOLOCAL
-#ifndef NOSERVER
- { "ser", XYSERV, CM_INV|CM_ABR },
-#endif /* NOSERVER */
-#endif /* NOXFER */
- { "serial", XYSERIAL,CM_LOC },
-#endif /* NOLOCAL */
-#ifndef NOSERVER
- { "server", XYSERV, 0 },
-#endif /* NOSERVER */
-#ifdef SESLIMIT
-#ifndef NOLOCAL
- { "session-l", XYSESS, CM_INV|CM_ABR },
-#endif /* NOLOCAL */
- { "session-limit", XYLIMIT, CM_INV|CM_LOC }, /* Session Limit */
-#endif /* SESLIMIT */
-
-#ifndef NOLOCAL
- { "session-log", XYSESS, CM_LOC },
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
-#ifndef NOSEXP
- { "sexpression", XYSEXP, CM_INV },
-#endif /* NOSEXP */
-#endif /* NOSPL */
-
- { "sleep", XYSLEEP, 0 },
-
-#ifndef NOLOCAL
- { "speed", XYSPEE, CM_LOC },
-#endif /* NOLOCAL */
-
-#ifdef ANYSSH
- { "ssh", XYSSH, 0 },
-#endif /* ANYSSH */
-
-#ifndef NOSPL
- { "startup-file", XYSTARTUP, CM_INV },
-#endif /* NOSPL */
-
-#ifndef NOLOCAL
-#ifdef HWPARITY
- { "stop-bits", XYSTOP, CM_LOC },
-#else
-#ifdef TN_COMPORT
- { "stop-bits", XYSTOP, CM_LOC },
-#endif /* TN_COMPORT */
-#endif /* HWPARITY */
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
-#ifdef STREAMING
- { "streaming", XYSTREAM, 0 },
-#endif /* STREAMING */
-#endif /* NOXFER */
-
-#ifndef NOJC
- { "suspend", XYSUSP, CM_PSH },
-#endif /* NOJC */
-#ifdef CKSYSLOG
- { "syslog", XYSYSL, CM_INV },
-#endif /* CKSYSLOG */
- { "take", XYTAKE, 0 },
-
-#ifdef CK_TAPI
- { "tapi", XYTAPI, CM_LOC },
-#endif /* CK_TAPI */
-
-#ifndef NOTCPOPTS
-#ifdef TCPSOCKET
- { "tcp", XYTCP, CM_LOC },
-#endif /* TCPSOCKET */
-#endif /* NOTCPOPTS */
-
-#ifdef TNCODE
- { "tel", XYTEL, CM_INV|CM_ABR },
- { "telnet", XYTEL, 0 },
- { "telopt", XYTELOP, 0 },
-#endif /* TNCODE */
-
-#ifndef NOSPL
- { "temp-directory", XYTMPDIR,0 },
-#endif /* NOSPL */
-
-#ifndef NOLOCAL
- { "terminal", XYTERM, CM_LOC },
-#endif /* NOLOCAL */
-
-#ifdef OS2
- { "title", XYTITLE, CM_LOC },
-#endif /* OS2 */
-#ifdef TLOG
- { "transaction-log", XYTLOG, 0 },
-#endif /* TLOG */
-#ifndef NOXFER
- { "transfer", XYXFER, 0 },
-#endif /* NOXFER */
-#ifndef NOXMIT
- { "transmit", XYXMIT, 0 },
-#endif /* NOXMIT */
-#ifndef NOXFER
-#ifndef NOCSETS
- { "unknown-char-set", XYUNCS, 0 },
-#endif /* NOCSETS */
-#ifndef NOSPL
- { "variable-evaluation", XYVAREV, CM_INV },
-#endif /* NOSPL */
-#endif /* NOXFER */
- { "wait", XYSLEEP, CM_INV },
-#ifndef NOPUSH
-#ifdef UNIX
- { "wildcard-expansion", XYWILD, 0 },
-#endif /* UNIX */
-#endif /* NOPUSH */
-#ifdef NT
- { "w", XYWIND, CM_INV|CM_ABR },
- { "wi", XYWIND, CM_INV|CM_ABR },
- { "win", XYWIND, CM_INV|CM_ABR },
-#endif /* NT */
- { "window-size", XYWIND, 0 },
-#ifdef NT
- { "win95", XYWIN95, 0 },
-#endif /* NT */
-#ifdef ANYX25
- { "x.25", XYX25, CM_LOC },
- { "x25", XYX25, CM_INV|CM_LOC },
-#endif /* ANYX25 */
- { "xfer", XYXFER, CM_INV },
-#ifndef NOXMIT
- { "xmit", XYXMIT, CM_INV },
-#endif /* NOXMIT */
- { "", 0, 0 }
-};
-int nprm = (sizeof(prmtab) / sizeof(struct keytab)) - 1; /* How many */
-
-struct keytab scntab[] = { /* Screen commands */
- { "clear", SCN_CLR, 0 },
- { "cleol", SCN_CLE, 0 },
- { "move-to", SCN_MOV, 0 }
-};
-int nscntab = (sizeof(scntab) / sizeof(struct keytab)); /* How many */
-
-#ifdef ANYSSH /* SSH command table */
-#ifdef SSHBUILTIN
-int ssh_pf_lcl_n = 0,
- ssh_pf_rmt_n = 0;
-struct ssh_pf ssh_pf_lcl[32] = { 0, NULL, 0 }; /* SSH Port Forwarding */
-struct ssh_pf ssh_pf_rmt[32] = { 0, NULL, 0 }; /* structs... */
-extern char * ssh_hst, * ssh_cmd, * ssh_prt;
-extern int ssh_ver, ssh_xfw;
-char * ssh_tmpuid = NULL, *ssh_tmpcmd = NULL, *ssh_tmpport = NULL,
- * ssh_tmpstr = NULL;
-
-int
- sshk_type = SSHKT_2D, /* SSH KEY CREATE /TYPE:x */
- sshk_bits = 1024, /* SSH KEY CREATE /BITS:n */
- sshk_din = SKDF_OSSH, /* SSH KEY DISPLAY /IN-FORMAT: */
- sshk_dout = SKDF_OSSH; /* SSH KEY DISPLAY /OUT-FORMAT: */
-
-char
- * sshk1_comment = NULL, /* SSH V1 COMMENT */
- * sshkp_old = NULL, /* Old key passphrase */
- * sshkp_new = NULL, /* New key passphrase */
- * sshkc_pass = NULL, /* KEY CREATE /PASS:xxx */
- * sshkc_comm = NULL, /* KEY CREATE /V1-RSA-COMMENT:xxx */
- * sshd_file = NULL, /* DISPLAY file */
- * sshk_file = NULL; /* SSH CREATE KEY file */
-
-static struct keytab sshclr[] = {
- { "local-port-forward", SSHC_LPF, 0 },
- { "remote-port-forward", SSHC_RPF, 0 },
- { "", 0, 0 }
-};
-static int nsshclr = (sizeof(sshclr) / sizeof(struct keytab)) - 1;
-
-struct keytab sshopnsw[] = {
- { "/command", SSHSW_CMD, CM_ARG },
- { "/password", SSHSW_PWD, CM_ARG },
- { "/subsystem", SSHSW_SUB, CM_ARG },
- { "/user", SSHSW_USR, CM_ARG },
- { "/version", SSHSW_VER, CM_ARG },
- { "/x11-forwarding", SSHSW_X11, CM_ARG },
- { "", 0, 0 }
-};
-int nsshopnsw = (sizeof(sshopnsw) / sizeof(struct keytab)) - 1;
-
-static struct keytab sshkwtab[] = {
- { "add", XSSH_ADD, 0 },
- { "agent", XSSH_AGT, 0 },
- { "clear", XSSH_CLR, 0 },
- { "forward-local-port", XSSH_FLP, CM_INV },
- { "forward-remote-port", XSSH_FRP, CM_INV },
- { "key", XSSH_KEY, 0 },
- { "open", XSSH_OPN, 0 },
- { "v2", XSSH_V2, 0 },
- { "", 0, 0 }
-};
-static int nsshcmd = (sizeof(sshkwtab) / sizeof(struct keytab)) - 1;
-
-static struct keytab ssh2tab[] = {
- { "rekey", XSSH2_RKE, 0 },
- { "", 0, 0 }
-};
-static int nssh2tab = (sizeof(ssh2tab) / sizeof(struct keytab));
-
-static struct keytab addfwd[] = { /* SET SSH ADD command table */
- { "local-port-forward", SSHF_LCL, 0 },
- { "remote-port-forward", SSHF_RMT, 0 },
- { "", 0, 0 }
-};
-static int naddfwd = (sizeof(addfwd) / sizeof(struct keytab)) - 1;
-
-static struct keytab sshagent[] = { /* SET SSH AGENT command table */
- { "add", SSHA_ADD, 0 },
- { "delete", SSHA_DEL, 0 },
- { "list", SSHA_LST, 0 },
- { "", 0, 0 }
-};
-static int nsshagent = (sizeof(sshagent) / sizeof(struct keytab)) - 1;
-
-static struct keytab sshagtsw[] = { /* SET SSH AGENT LIST switch table */
- { "/fingerprint", SSHASW_FP, 0 },
- { "", 0, 0 }
-};
-static int nsshagtsw = (sizeof(sshagtsw) / sizeof(struct keytab)) - 1;
-
-static struct keytab sshkey[] = { /* SET SSH KEY command table */
- { "change-passphrase", SSHK_PASS, 0 },
- { "create", SSHK_CREA, 0 },
- { "display", SSHK_DISP, 0 },
- { "v1", SSHK_V1, 0 },
- { "", 0, 0 }
-};
-static int nsshkey = (sizeof(sshkey) / sizeof(struct keytab)) - 1;
-
-static struct keytab sshkv1[] = { /* SET SSH KEY V1 command table */
- { "set-comment", 1, 0 }
-};
-
-static struct keytab sshkpsw[] = { /* SET SSH KEY PASSPHRASE table */
- { "/new-passphrase", 2, CM_ARG },
- { "/old-passphrase", 1, CM_ARG }
-};
-
-static struct keytab sshkcrea[] = { /* SSH KEY CREATE table */
- { "/bits", SSHKC_BI, CM_ARG },
- { "/passphrase", SSHKC_PP, CM_ARG },
- { "/type", SSHKC_TY, CM_ARG },
- { "/v1-rsa-comment", SSHKC_1R, CM_ARG }
-};
-static int nsshkcrea = (sizeof(sshkcrea) / sizeof(struct keytab));
-
-static struct keytab sshkcty[] = { /* SSH KEY CREATE /TYPE:xxx */
- { "srp", SSHKT_SRP, 0 },
- { "v1-rsa", SSHKT_1R, 0 },
- { "v2-dsa", SSHKT_2D, 0 },
- { "v2-rsa", SSHKT_2R, 0 }
-};
-static int nsshkcty = (sizeof(sshkcty) / sizeof(struct keytab));
-
-static struct keytab sshdswi[] = { /* SET SSH KEY DISPLAY /switches */
- { "/format", SSHKD_OUT, CM_ARG }
-};
-static int nsshdswi = (sizeof(sshdswi) / sizeof(struct keytab));
-
-#ifdef COMMENT
-static struct keytab sshdifmt[] = { /* SSH KEY DISPLAY /IN-FORMAT: */
- { "openssh", SKDF_OSSH, 0 },
- { "ssh.com", SKDF_SSHC, 0 }
-};
-static int nsshdifmt = (sizeof(sshdifmt) / sizeof(struct keytab));
-#endif /* COMMENT */
-
-static struct keytab sshdofmt[] = { /* SSH KEY DISPLAY /IN-FORMAT: */
- { "fingerprint", SKDF_FING, 0 },
- { "ietf", SKDF_IETF, 0 },
- { "openssh", SKDF_OSSH, 0 },
- { "ssh.com", SKDF_SSHC, 0 }
-};
-static int nsshdofmt = (sizeof(sshdofmt) / sizeof(struct keytab));
-
-static struct keytab sshkermit[] = { /* SKERMIT */
- { "open", SKRM_OPN, 0 }
-};
-static int nsshkermit = (sizeof(sshkermit) / sizeof(struct keytab));
-
-struct keytab sshkrmopnsw[] = {
- { "/password", SSHSW_PWD, CM_ARG },
- { "/user", SSHSW_USR, CM_ARG },
- { "/version", SSHSW_VER, CM_ARG },
- { "", 0, 0 }
-};
-int nsshkrmopnsw = (sizeof(sshkrmopnsw) / sizeof(struct keytab)) - 1;
-#endif /* SSHBUILTIN */
-
-#ifdef SFTP_BUILTIN
-static struct keytab sftpkwtab[] = { /* SFTP */
- { "cd", SFTP_CD, 0 },
- { "chgrp", SFTP_CHGRP, 0 },
- { "chmod", SFTP_CHMOD, 0 },
- { "chown", SFTP_CHOWN, 0 },
- { "delete", SFTP_RM, 0 },
- { "dir", SFTP_DIR, 0 },
- { "get", SFTP_GET, 0 },
- { "mkdir", SFTP_MKDIR, 0 },
- { "open", SFTP_OPN, 0 },
- { "put", SFTP_PUT, 0 },
- { "pwd", SFTP_PWD, 0 },
- { "rename", SFTP_REN, 0 },
- { "rm", SFTP_RM, CM_INV },
- { "rmdir", SFTP_RMDIR, 0 },
- { "symlink", SFTP_LINK, 0 },
- { "version", SFTP_VER, 0 }
-};
-static int nsftpkwtab = (sizeof(sftpkwtab) / sizeof(struct keytab));
-#endif /* SFTP_BUILTIN */
-#endif /* ANYSSH */
-
-#ifdef NETCONN
-struct keytab netkey[] = { /* SET NETWORK table */
- { "directory", XYNET_D, 0 },
- { "type", XYNET_T, 0 }
-};
-int nnetkey = (sizeof(netkey) / sizeof(struct keytab));
-
-struct keytab netcmd[] = {
-/*
- These are the network types.
-*/
-#ifdef NETCMD
- { "command", NET_CMD, CM_INV }, /* Command */
-#endif /* NETCMD */
-
-#ifdef DECNET /* DECnet / PATHWORKS */
- { "decnet", NET_DEC, 0 },
-#endif /* DECNET */
-
-#ifdef NETDLL
- { "dll", NET_DLL, CM_INV }, /* DLL to be loaded */
-#endif /* NETDLL */
-
-#ifdef NETFILE
- { "file", NET_FILE, CM_INV }, /* FILE (real crude) */
-#endif /* NETFILE */
-
-#ifdef NPIPE /* Named Pipes */
- { "named-pipe", NET_PIPE, 0 },
-#endif /* NPIPE */
-
-#ifdef CK_NETBIOS
- { "netbios", NET_BIOS, 0 }, /* NETBIOS */
-#endif /* CK_NETBIOS */
-
-#ifdef DECNET /* DECnet / PATHWORKS (alias) */
- { "pathworks", NET_DEC, CM_INV },
-#endif /* DECNET */
-
-#ifdef NETCMD
- { "pipe", NET_CMD, 0 }, /* Pipe */
-#endif /* NETCMD */
-
-#ifdef NETPTY
- { "pseudoterminal",NET_PTY, 0 }, /* Pseudoterminal */
-#endif /* NETPTY */
-
-#ifdef NETPTY
- { "pty", NET_PTY, CM_INV }, /* Inv syn for pseudoterm */
-#endif /* NETPTY */
-
-#ifdef SSHBUILTIN
- { "ssh", NET_SSH, 0 },
-#endif /* SSHBUILTIN */
-
-#ifdef SUPERLAT
- { "superlat", NET_SLAT, 0 }, /* Meridian Technologies' SuperLAT */
-#endif /* SUPERLAT */
-
-#ifdef TCPSOCKET /* TCP/IP sockets library */
- { "tcp/ip", NET_TCPB, 0 },
-#endif /* TCPSOCKET */
-#ifdef SUPERLAT
- { "tes32", NET_SLAT, 0 }, /* Emulux TES32 */
-#endif /* SUPERLAT */
-#ifdef ANYX25 /* X.25 */
-#ifdef SUNX25
- { "x", NET_SX25, CM_INV|CM_ABR },
- { "x.25", NET_SX25, 0 },
- { "x25", NET_SX25, CM_INV },
-#else
-#ifdef STRATUSX25
- { "x", NET_VX25, CM_INV|CM_ABR },
- { "x.25", NET_VX25, 0 },
- { "x25", NET_VX25, CM_INV },
-#endif /* STRATUSX25 */
-#endif /* SUNX25 */
-#ifdef IBMX25
- { "x", NET_IX25, CM_INV|CM_ABR },
- { "x.25", NET_IX25, CM_INV },
- { "x25", NET_IX25, CM_INV },
-#endif /* IBMX25 */
-#ifdef HPX25
- { "x", NET_IX25, CM_INV|CM_ABR },
- { "x.25", NET_IX25, 0 },
- { "x25", NET_IX25, CM_INV },
-#endif /* HPX25 */
-#endif /* ANYX25 */
- { "", 0, 0 }
-};
-int nnets = (sizeof(netcmd) / sizeof(struct keytab));
-
-#ifndef NOTCPOPTS
-#ifdef TCPSOCKET
-
-/* TCP options */
-
-struct keytab tcpopt[] = {
- { "address", XYTCP_ADDRESS, 0 },
-#ifdef CK_DNS_SRV
- { "dns-service-records", XYTCP_DNS_SRV, 0 },
-#endif /* CK_DNS_SRV */
-#ifdef SO_DONTROUTE
- { "dontroute", XYTCP_DONTROUTE, 0 },
-#endif /* SO_DONTROUTE */
-#ifndef NOHTTP
- { "http-proxy", XYTCP_HTTP_PROXY, 0 },
-#endif /* NOHTTP */
-#ifdef SO_KEEPALIVE
- { "keepalive", XYTCP_KEEPALIVE, 0 },
-#endif /* SO_KEEPALIVE */
-#ifdef SO_LINGER
- { "linger", XYTCP_LINGER, 0 },
-#endif /* SO_LINGER */
-#ifdef TCP_NODELAY
- { "nagle", XYTCP_NAGLE, CM_INV },
- { "nodelay", XYTCP_NODELAY, 0 },
-#endif /* TCP_NODELAY */
- { "reverse-dns-lookup", XYTCP_RDNS, 0 },
-#ifdef SO_RCVBUF
- { "recvbuf", XYTCP_RECVBUF, 0 },
-#endif /* SO_RCVBUF */
-#ifdef SO_SNDBUF
- { "sendbuf", XYTCP_SENDBUF, 0 },
-#endif /* SO_SNDBUF */
-#ifdef NT
-#ifdef CK_SOCKS
- { "socks-server", XYTCP_SOCKS_SVR, 0 },
-#endif /* CK_SOCKS */
-#endif /* NT */
-#ifdef VMS
-#ifdef DEC_TCPIP
- { "ucx-port-bug", XYTCP_UCX, 0 },
-#endif /* DEC_TCPIP */
-#endif /* VMS */
- { "",0,0 }
-};
-int ntcpopt = (sizeof(tcpopt) / sizeof(struct keytab));
-#endif /* TCPSOCKET */
-#endif /* NOTCPOPTS */
-#endif /* NETCONN */
-
-#ifdef OS2
-/* K95 Manual Chapter Table -- Keep these two tables in sync! */
-
-static char * linktbl[] = { /* Internal links in k95.htm */
- "#top", /* 00 */
- "#what", /* 01 */
- "#install", /* 02 */
- "#start", /* 03 */
- "#dialer", /* 04 */
- "#entries", /* 05 */
- "#command", /* 06 */
- "#terminal", /* 07 */
- "#transfer", /* 08 */
- "#hostmode" /* 09 */
-};
-
-static struct keytab chaptbl[] = {
- { "Command-Screen", 6, 0 },
- { "Contents", 0, 0 },
- { "Dialer-Entries", 5, 0 },
- { "File-Transfer", 8, 0 },
- { "Getting-Started", 3, 0 },
- { "Host-Mode", 9, 0 },
- { "Installation", 2, 0 },
- { "Terminal-Emulation", 7, 0 },
- { "Using-The-Dialer", 4, 0 },
- { "What-Is-K95", 1, 0 },
- { "", 0, 0 }
-};
-static int nchaptbl = (sizeof(chaptbl) / sizeof(struct keytab) - 1);
-#endif /* OS2 */
-
-#ifndef NOXFER
-/* Remote Command Table */
-
-struct keytab remcmd[] = {
-#ifndef NOSPL
- { "as", XZASG, CM_INV|CM_ABR },
- { "asg", XZASG, CM_INV },
- { "assign", XZASG, 0 },
-#endif /* NOSPL */
- { "cd", XZCWD, 0 },
- { "cdup", XZCDU, CM_INV },
- { "copy", XZCPY, 0 },
- { "cwd", XZCWD, CM_INV },
- { "delete", XZDEL, 0 },
- { "directory", XZDIR, 0 },
- { "e", XZXIT, CM_ABR|CM_INV },
- { "erase", XZDEL, CM_INV },
- { "exit", XZXIT, 0 },
- { "help", XZHLP, 0 },
-#ifndef NOPUSH
- { "host", XZHOS, 0 },
-#endif /* NOPUSH */
-#ifndef NOFRILLS
- { "kermit", XZKER, 0 },
- { "l", XZLGI, CM_ABR|CM_INV },
- { "lo", XZLGI, CM_ABR|CM_INV },
- { "log", XZLGI, CM_ABR|CM_INV },
- { "login", XZLGI, 0 },
- { "logout", XZLGO, 0 },
- { "message", XZMSG, 0 },
- { "mkdir", XZMKD, 0 },
- { "print", XZPRI, 0 },
-#endif /* NOFRILLS */
- { "pwd", XZPWD, 0 },
-#ifndef NOSPL
- { "query", XZQUE, 0 },
-#endif /* NOSPL */
- { "rename", XZREN, 0 },
- { "rmdir", XZRMD, 0 },
- { "set", XZSET, 0 },
- { "space", XZSPA, 0 },
-#ifndef NOFRILLS
- { "type", XZTYP, 0 },
- { "who", XZWHO, 0 },
-#endif /* NOFRILLS */
- { "", 0, 0}
-};
-int nrmt = (sizeof(remcmd) / sizeof(struct keytab)) - 1;
-#endif /* NOXFER */
-
-struct keytab logtab[] = {
-#ifdef CKLOGDIAL
- { "connections", LOGM, CM_INV },
- { "cx", LOGM, 0 },
-#endif /* CKLOGDIAL */
-#ifdef DEBUG
- { "debugging", LOGD, 0 },
-#endif /* DEBUG */
- { "packets", LOGP, 0 },
-#ifndef NOLOCAL
- { "session", LOGS, 0 },
-#endif /* NOLOCAL */
-#ifdef TLOG
- { "transactions", LOGT, 0 },
-#endif /* TLOG */
- { "", 0, 0 }
-};
-int nlog = (sizeof(logtab) / sizeof(struct keytab)) - 1;
-
-struct keytab writab[] = {
-#ifndef NOSPL
- { "append-file", LOGW, CM_INV },
-#endif /* NOSPL */
- { "debug-log", LOGD, 0 },
- { "error", LOGE, 0 },
-#ifndef NOSPL
- { "file", LOGW, 0 },
-#endif /* NOSPL */
- { "packet-log", LOGP, 0 },
- { "screen", LOGX, 0 },
-#ifndef NOLOCAL
- { "session-log", LOGS, 0 },
-#endif /* NOLOCAL */
- { "sys$output", LOGX, CM_INV },
- { "t", LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
- { "tr", LOGT, CM_ABR|CM_INV }, /* the book... */
- { "tra", LOGT, CM_ABR|CM_INV },
- { "tran", LOGT, CM_ABR|CM_INV },
- { "trans", LOGT, CM_ABR|CM_INV },
- { "transa", LOGT, CM_ABR|CM_INV },
- { "transac", LOGT, CM_ABR|CM_INV },
- { "transact", LOGT, CM_ABR|CM_INV },
- { "transacti", LOGT, CM_ABR|CM_INV },
- { "transactio", LOGT, CM_ABR|CM_INV },
- { "transaction", LOGT, CM_ABR|CM_INV },
- { "transaction-log", LOGT, 0 },
- { "transactions", LOGT, CM_INV }
-};
-int nwri = (sizeof(writab) / sizeof(struct keytab));
-
-static struct keytab clrtab[] = { /* Keywords for CLEAR command */
-#ifndef NOSPL
- { "alarm", CLR_ALR, 0 },
-#ifdef CK_APC
- { "apc", CLR_APC, 0 },
-#endif /* CK_APC */
-#ifdef PATTERNS
- { "binary-patterns", CLR_BIN, 0 },
-#endif /* PATTERNS */
- { "both", CLR_DEV|CLR_INP, CM_INV },
-#endif /* NOSPL */
-#ifdef OS2
- { "command-screen", CLR_CMD, 0 },
-#endif /* OS2 */
-#ifndef NOSPL
- { "device", CLR_DEV, CM_INV|CM_ABR },
- { "device-and-input", CLR_DEV|CLR_INP, 0 },
-#endif /* NOSPL */
- { "device-buffer", CLR_DEV, 0 },
-#ifndef NODIAL
- { "dial-status", CLR_DIA, 0 },
-#endif /* NODIAL */
-#ifndef NOSPL
- { "input-buffer", CLR_INP, 0 },
-#endif /* NOSPL */
- { "keyboard-buffer", CLR_KBD, 0 },
- { "send-list", CLR_SFL, 0 },
-#ifdef OS2
- { "scr", CLR_SCL, CM_INV|CM_ABR },
-#endif /* OS2 */
- { "screen", CLR_SCR, 0 },
-#ifdef OS2
- { "scrollback", CLR_SCL, CM_INV },
- { "terminal-screen", CLR_TRM, 0 },
-#endif /* OS2 */
-#ifdef PATTERNS
- { "text-patterns", CLR_TXT, 0 },
-#endif /* PATTERNS */
- { "", 0, 0 }
-};
-int nclear = (sizeof(clrtab) / sizeof(struct keytab)) - 1;
-
-struct keytab clstab[] = { /* Keywords for CLOSE command */
-#ifndef NOSPL
- { "!read", LOGR, CM_INV },
- { "!write", LOGW, CM_INV },
-#ifndef NOPUSH
-#endif /* NOPUSH */
-#endif /* NOSPL */
-#ifndef NOSPL
- { "append-file", LOGW, CM_INV },
-#endif /* NOSPL */
-#ifndef NOLOCAL
- { "connection", 9999, 0 },
-#endif /* NOLOCAL */
-#ifdef CKLOGDIAL
- { "cx-log", LOGM, 0 },
-#endif /* CKLOGDIAL */
-#ifdef DEBUG
- { "debug-log", LOGD, 0 },
-#endif /* DEBUG */
- { "host", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
- { "line", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
- { "p", LOGP, CM_INV|CM_ABR },
- { "packet-log", LOGP, 0 },
- { "port", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
-#ifndef NOSPL
- { "read-file", LOGR, 0 },
-#endif /* NOSPL */
-#ifndef NOLOCAL
- { "session-log", LOGS, 0 },
-#endif /* NOLOCAL */
-#ifdef TLOG
- { "t", LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
- { "tr", LOGT, CM_ABR|CM_INV }, /* the book... */
- { "tra", LOGT, CM_ABR|CM_INV },
- { "tran", LOGT, CM_ABR|CM_INV },
- { "trans", LOGT, CM_ABR|CM_INV },
- { "transa", LOGT, CM_ABR|CM_INV },
- { "transac", LOGT, CM_ABR|CM_INV },
- { "transact", LOGT, CM_ABR|CM_INV },
- { "transacti", LOGT, CM_ABR|CM_INV },
- { "transactio", LOGT, CM_ABR|CM_INV },
- { "transaction", LOGT, CM_ABR|CM_INV },
- { "transaction-log", LOGT, 0 },
- { "transactions", LOGT, CM_INV },
-#endif /* TLOG */
-#ifndef NOSPL
- { "write-file", LOGW, 0 },
-#endif /* NOSPL */
- { "", 0, 0 }
-};
-int ncls = (sizeof(clstab) / sizeof(struct keytab)) - 1;
-
-/* SHOW command arguments */
-
-#ifndef NOSHOW
-struct keytab shotab[] = {
-#ifndef NOSPL
- { "alarm", SHALRM, 0 },
- { "arg", SHARG, CM_INV|CM_ABR },
- { "arguments", SHARG, 0 },
- { "args", SHARG, CM_INV },
- { "arrays", SHARR, 0 },
-#endif /* NOSPL */
-
-#ifndef NOCSETS
- { "associations", SHASSOC, 0 },
-#endif /* NOCSETS */
-
-#ifndef NOXFER
- { "attributes", SHATT, 0 },
-#endif /* NOXFER */
-
-#ifdef CK_AUTHENTICATION
- { "authentication", SHOAUTH, CM_INV },
-#endif /* CK_AUTHENTICATION */
-
-#ifndef NOPUSH
-#ifdef BROWSER
- { "browser", SHBROWSE, CM_PSH|CM_LOC },
-#endif /* BROWSER */
-#endif /* NOPUSH */
- { "cd", SHCD, 0 },
- { "character-sets", SHCSE, 0 },
- { "cmd", SHCMD, CM_INV },
-#ifndef NOLOCAL
- { "com", SHCOM, CM_INV|CM_ABR },
- { "comm", SHCOM, CM_INV|CM_ABR },
- { "communications", SHCOM, 0 },
-#endif /* NOLOCAL */
- { "command", SHCMD, 0 },
- { "connection", SHCONNX, 0 },
-#ifdef CK_SPEED
- { "control-prefixing", SHCTL, 0 },
-#endif /* CK_SPEED */
-#ifdef CKLOGDIAL
- { "cx", SHCONNX, CM_INV },
-#endif /* CKLOGDIAL */
-#ifndef NOSPL
- { "count", SHCOU, 0 },
-#endif /* NOSPL */
- { "d", SHDIA, CM_INV|CM_ABR },
-#ifdef VMS
- { "default", SHDFLT, 0 },
-#else
- { "default", SHDFLT, CM_INV },
-#endif /* VMS */
-#ifndef NODIAL
- { "dial", SHDIA, CM_LOC },
-#endif /* NODIAL */
- { "double/ignore",SHDBL, 0 },
-#ifndef NOPUSH
-#ifndef NOFRILLS
- { "editor", SHEDIT, CM_PSH },
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-#ifndef NOLOCAL
- { "escape", SHESC, CM_LOC },
-#endif /* NOLOCAL */
- { "exit", SHEXI, 0 },
- { "extended-options", SHXOPT, CM_INV },
- { "features", SHFEA, 0 },
- { "file", SHFIL, 0 },
-#ifndef NOLOCAL
- { "flow-control", SHOFLO, 0 },
-#endif /* NOLOCAL */
-#ifdef BROWSER
- { "ftp", SHOFTP, CM_PSH|CM_LOC },
-#else
-#ifndef NOFTP
-#ifndef SYSFTP
-#ifdef TCPSOCKET
- { "ftp", SHOFTP, 0 }, /* (built-in ftp) */
-#endif /* TCPSOCKET */
-#endif /* SYSFTP */
-#endif /* NOFTP */
-#endif /* BROWSER */
-#ifndef NOSPL
- { "functions", SHFUN, 0 },
- { "globals", SHVAR, 0 },
-#endif /* NOSPL */
-#ifdef KUI
- { "gui", SHOGUI, 0 },
-#endif /* KUI */
-#ifdef CK_RECALL
- { "history", SHHISTORY, 0 },
-#endif /* CK_RECALL */
- { "ignore/double",SHDBL, CM_INV },
- { "iksd", SHOIKS, CM_INV },
-#ifndef NOSPL
- { "input", SHINP, 0 },
-#endif /* NOSPL */
-#ifndef NOSETKEY
- { "k", SHKEY, CM_INV|CM_ABR },
- { "key", SHKEY, 0 },
-#ifndef NOKVERBS
- { "kverbs", SHKVB, 0 },
-#endif /* NOKVERBS */
-#endif /* NOSETKEY */
-#ifdef CK_LABELED
- { "labeled-file-info", SHLBL, 0 },
-#endif /* CK_LABELED */
-#ifndef NOCSETS
- { "languages", SHLNG, 0 },
-#endif /* NOCSETS */
- { "logs", SHLOG, 0 },
-#ifndef NOSPL
- { "macros", SHMAC, 0 },
-#endif /* NOSPL */
-#ifndef NODIAL
- { "modem", SHMOD, CM_LOC },
-#else
- { "modem-signals",SHCOM, CM_INV|CM_LOC },
-#endif /* NODIAL */
-#ifndef NOLOCAL
-#ifdef OS2MOUSE
- { "mouse", SHMOU, CM_LOC },
-#endif /* OS2MOUSE */
-#endif /* NOLOCAL */
-#ifdef NETCONN
- { "network", SHNET, CM_LOC },
-#else
- { "network", SHNET, CM_INV|CM_LOC },
-#endif /* NETCONN */
- { "options", SHOPTS, 0 },
-#ifndef NOSPL
- { "output", SHOUTP, CM_INV },
-#endif /* NOSPL */
-#ifdef ANYX25
-#ifndef IBMX25
- { "pad", SHPAD, CM_LOC },
-#endif /* IBMX25 */
-#endif /* ANYX25 */
- { "parameters", SHPAR, CM_INV },
-#ifdef PATTERNS
- { "patterns", SHOPAT, 0 },
-#endif /* PATTERNS */
- { "printer", SHPRT, 0 },
-#ifdef CK_SPEED
- { "prefixing", SHCTL, CM_INV },
-#endif /* CK_SPEED */
-#ifndef NOXFER
- { "protocol", SHPRO, 0 },
-#endif /* NOXFER */
- { "rename", SHOREN, 0 },
-#ifndef NOSPL
- { "scripts", SHSCR, CM_LOC },
-#endif /* NOSPL */
- { "send-list", SHSFL, 0 },
-#ifndef NOSERVER
- { "server", SHSER, 0 },
-#endif /* NOSERVER */
-#ifndef NOSEXP
- { "sexpression", SHSEXP, 0 },
-#endif /* NOSEXP */
-#ifdef ANYSSH
- { "ssh", SHOSSH, 0 },
-#endif /* ANYSSH */
- { "stack", SHSTK, 0 },
- { "status", SHSTA, 0 },
-#ifdef STREAMING
- { "streaming", SHOSTR, 0 },
-#endif /* STREAMING */
-#ifndef NOLOCAL
-#ifdef OS2
- { "tabs", SHTAB, CM_INV|CM_LOC },
-#endif /* OS2 */
-#ifdef CK_TAPI
- { "tapi", SHTAPI, CM_LOC },
- { "tapi-comm", SHTAPI_C, CM_INV|CM_LOC },
- { "tapi-location", SHTAPI_L, CM_INV|CM_LOC },
- { "tapi-modem", SHTAPI_M, CM_INV|CM_LOC },
-#endif /* CK_TAPI */
- { "tcp", SHTCP, CM_LOC },
-#ifdef TNCODE
- { "tel", SHTEL, CM_INV|CM_ABR },
- { "telnet", SHTEL, 0 },
- { "telopt", SHTOPT, 0 },
-#endif /* TNCODE */
- { "terminal", SHTER, CM_LOC },
-#endif /* NOLOCAL */
-#ifndef NOXMIT
- { "tr", SHXMI, CM_INV|CM_ABR },
- { "tra", SHXMI, CM_INV|CM_ABR },
- { "tran", SHXMI, CM_INV|CM_ABR },
- { "trans", SHXMI, CM_INV|CM_ABR },
-#endif /* NOXMIT */
-#ifndef NOXFER
- { "transfer", SHOXFER, 0 },
-#endif /* NOXFER */
-#ifndef NOXMIT
- { "transmit", SHXMI, 0 },
-#endif /* NOXMIT */
-#ifdef CK_TRIGGER
- { "trigger", SHTRIG, CM_LOC },
-#endif /* CK_TRIGGER */
-#ifndef NOSETKEY
-#ifndef NOKVERBS
-#ifdef OS2
- { "udk", SHUDK, CM_LOC },
-#endif /* OS2 */
-#endif /* NOKVERBS */
-#endif /* NOSETKEY */
-#ifndef NOSPL
- { "variables", SHBUI, 0 },
-#endif /* NOSPL */
-#ifndef NOFRILLS
- { "versions", SHVER, 0 },
-#endif /* NOFRILLS */
-#ifdef OS2
- { "vscrn", SHVSCRN, CM_INV|CM_LOC },
-#endif /* OS2 */
- { "xfer", SHOXFER, CM_INV },
-#ifndef NOXMIT
- { "xmit", SHXMI, CM_INV },
-#endif /* NOXMIT */
- { "", 0, 0 }
-};
-int nsho = (sizeof(shotab) / sizeof(struct keytab)) - 1;
-#endif /* NOSHOW */
-
-#ifdef ANYX25
-#ifndef IBMX25
-struct keytab padtab[] = { /* PAD commands */
- { "clear", XYPADL, 0 },
- { "interrupt", XYPADI, 0 },
- { "reset", XYPADR, 0 },
- { "status", XYPADS, 0 }
-};
-int npadc = (sizeof(padtab) / sizeof(struct keytab));
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifndef NOSERVER
-static struct keytab kmstab[] = {
- { "both", 3, 0 },
- { "local", 1, 0 },
- { "remote", 2, 0 }
-};
-
-static struct keytab enatab[] = { /* ENABLE commands */
- { "all", EN_ALL, 0 },
-#ifndef NOSPL
- { "as", EN_ASG, CM_INV|CM_ABR },
- { "asg", EN_ASG, CM_INV },
- { "assign", EN_ASG, 0 },
-#endif /* NOSPL */
-#ifndef datageneral
- { "bye", EN_BYE, 0 },
-#endif /* datageneral */
- { "cd", EN_CWD, 0 },
-#ifdef ZCOPY
- { "copy", EN_CPY, 0 },
-#endif /* ZCOPY */
- { "cwd", EN_CWD, CM_INV },
- { "delete", EN_DEL, 0 },
- { "directory", EN_DIR, 0 },
- { "enable", EN_ENA, CM_INV },
- { "exit", EN_XIT, 0 },
- { "finish", EN_FIN, 0 },
- { "get", EN_GET, 0 },
- { "host", EN_HOS, 0 },
- { "mail", EN_MAI, 0 },
- { "mkdir", EN_MKD, 0 },
- { "print", EN_PRI, 0 },
-#ifndef NOSPL
- { "query", EN_QUE, 0 },
-#endif /* NOSPL */
- { "rename", EN_REN, 0 },
- { "retrieve", EN_RET, CM_INV },
- { "rmdir", EN_RMD, 0 },
- { "send", EN_SEN, 0 },
- { "set", EN_SET, 0 },
- { "space", EN_SPA, 0 },
- { "type", EN_TYP, 0 },
- { "who", EN_WHO, 0 }
-};
-static int nena = (sizeof(enatab) / sizeof(struct keytab));
-#endif /* NOSERVER */
-
-struct keytab txtbin[] = {
- { "all", 2, 0 },
- { "binary", 1, 0 },
- { "text", 0, 0 }
-};
-
-#ifndef NOXFER
-static struct keytab sndtab[] = { /* SEND command options */
- { "/after", SND_AFT, CM_ARG },
-#ifndef NOSPL
- { "/array", SND_ARR, CM_ARG },
-#endif /* NOSPL */
- { "/as-name", SND_ASN, CM_ARG },
- { "/b", SND_BIN, CM_INV|CM_ABR },
- { "/before", SND_BEF, CM_ARG },
- { "/binary", SND_BIN, 0 },
-#ifdef CALIBRATE
- { "/c", SND_CMD, CM_INV|CM_ABR },
- { "/calibrate", SND_CAL, CM_INV|CM_ARG },
-#endif /* CALIBRATE */
- { "/command", SND_CMD, CM_PSH },
- { "/delete", SND_DEL, 0 },
-#ifdef UNIXOROSK
- { "/dotfiles", SND_DOT, 0 },
-#endif /* UNIXOROSK */
- { "/except", SND_EXC, CM_ARG },
-#ifdef PIPESEND
- { "/filter", SND_FLT, CM_ARG|CM_PSH },
-#endif /* PIPESEND */
- { "/filenames", SND_NAM, CM_ARG },
-#ifdef CKSYMLINK
- { "/followlinks", SND_LNK, 0 },
-#endif /* CKSYMLINK */
-#ifdef VMS
- { "/image", SND_IMG, 0 },
-#else
- { "/image", SND_BIN, CM_INV },
-#endif /* VMS */
-#ifdef CK_LABELED
- { "/labeled", SND_LBL, 0 },
-#endif /* CK_LABELED */
- { "/larger-than", SND_LAR, CM_ARG },
- { "/listfile", SND_FIL, CM_ARG },
-#ifndef NOFRILLS
- { "/mail", SND_MAI, CM_ARG },
-#endif /* NOFRILLS */
-#ifdef CK_TMPDIR
- { "/move-to", SND_MOV, CM_ARG },
-#endif /* CK_TMPDIR */
- { "/nobackupfiles", SND_NOB, 0 },
-#ifdef UNIXOROSK
- { "/nodotfiles", SND_NOD, 0 },
-#endif /* UNIXOROSK */
-#ifdef CKSYMLINK
- { "/nofollowlinks", SND_NLK, 0 },
-#endif /* CKSYMLINK */
- { "/not-after", SND_NAF, CM_ARG },
- { "/not-before", SND_NBE, CM_ARG },
- { "/pathnames", SND_PTH, CM_ARG },
- { "/print", SND_PRI, CM_ARG },
-#ifdef CK_XYZ
- { "/protocol", SND_PRO, CM_ARG },
-#else
- { "/protocol", SND_PRO, CM_ARG|CM_INV },
-#endif /* CK_XYZ */
- { "/quiet", SND_SHH, 0 },
- { "/recover", SND_RES, 0 },
-#ifdef RECURSIVE
-/* Systems where we do recursion */
- { "/recursive", SND_REC, 0 },
-#else
-#ifdef VMS
-/* Systems that do recursion themselves without our assistance */
-/* if we give them the right kind of wildcard */
- { "/recursive", SND_REC, 0 },
-#else
-#ifdef datageneral
- { "/recursive", SND_REC, 0 },
-#else
- { "/recursive", SND_REC, CM_INV },
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* RECURSIVE */
- { "/rename-to", SND_REN, CM_ARG },
- { "/since", SND_AFT, CM_INV|CM_ARG },
- { "/smaller-than", SND_SMA, CM_ARG },
- { "/starting-at", SND_STA, CM_ARG },
-#ifndef NOFRILLS
- { "/su", SND_ASN, CM_ARG|CM_INV|CM_ABR },
- { "/sub", SND_ASN, CM_ARG|CM_INV|CM_ABR },
- { "/subject", SND_ASN, CM_ARG },
-#endif /* NOFRILLS */
-#ifdef RECURSIVE
- { "/subdirectories", SND_REC, CM_INV },
-#endif /* RECURSIVE */
- { "/text", SND_TXT, 0 },
- { "/transparent", SND_XPA, 0 },
- { "/type", SND_TYP, CM_ARG }
-};
-#define NSNDTAB sizeof(sndtab)/sizeof(struct keytab)
-static int nsndtab = NSNDTAB;
-
-#ifndef NOMSEND
-static struct keytab msndtab[] = { /* MSEND options */
- { "/after", SND_AFT, CM_ARG },
- { "/before", SND_BEF, CM_ARG },
- { "/binary", SND_BIN, 0 },
- { "/delete", SND_DEL, 0 },
- { "/except", SND_EXC, CM_ARG },
- { "/filenames", SND_NAM, CM_ARG },
-#ifdef CKSYMLINK
- { "/followlinks", SND_LNK, 0 },
-#endif /* CKSYMLINK */
-#ifdef VMS
- { "/image", SND_IMG, 0 },
-#else
- { "/image", SND_BIN, CM_INV },
-#endif /* VMS */
-#ifdef CK_LABELED
- { "/labeled", SND_LBL, 0 },
-#endif /* CK_LABELED */
- { "/larger-than", SND_LAR, CM_ARG },
- { "/list", SND_FIL, CM_ARG },
-#ifndef NOFRILLS
- { "/mail", SND_MAI, CM_ARG },
-#endif /* NOFRILLS */
-#ifdef CK_TMPDIR
- { "/move-to", SND_MOV, CM_ARG },
-#endif /* CK_TMPDIR */
-#ifdef CKSYMLINK
- { "/nofollowlinks", SND_NLK, 0 },
-#endif /* CKSYMLINK */
- { "/not-after", SND_NAF, CM_ARG },
- { "/not-before", SND_NBE, CM_ARG },
- { "/pathnames", SND_PTH, CM_ARG },
- { "/print", SND_PRI, CM_ARG },
-#ifdef CK_XYZ
- { "/protocol", SND_PRO, CM_ARG },
-#endif /* CK_XYZ */
- { "/quiet", SND_SHH, 0 },
- { "/recover", SND_RES, 0 },
- { "/rename-to", SND_REN, CM_ARG },
- { "/since", SND_AFT, CM_INV|CM_ARG },
- { "/smaller-than", SND_SMA, CM_ARG },
- { "/starting-at", SND_STA, CM_ARG },
-#ifndef NOFRILLS
- { "/subject", SND_ASN, CM_ARG },
-#endif /* NOFRILLS */
- { "/text", SND_TXT, 0 },
- { "/transparent", SND_XPA, 0 },
- { "/type", SND_TYP, CM_ARG }
-};
-#define NMSNDTAB sizeof(msndtab)/sizeof(struct keytab)
-static int nmsndtab = NMSNDTAB;
-#endif /* NOMSEND */
-#endif /* NOXFER */
-
-/* CONNECT command switches */
-
-#define CONN_II 0 /* Idle interval */
-#define CONN_IS 1 /* Idle string */
-#define CONN_IL 2 /* Idle limit */
-#define CONN_NV 3 /* Non-Verbose */
-#define CONN_TL 4 /* Time limit */
-#define CONN_TS 5 /* Trigger string */
-#define CONN_AS 6 /* Asynchronous */
-#define CONN_SY 7 /* Synchronous */
-#define CONN_MAX 7 /* Number of CONNECT switches */
-
-#ifndef NOLOCAL
-static struct keytab conntab[] = {
-#ifdef OS2
- { "/asynchronous", CONN_AS, CM_INV },
-#endif /* OS2 */
-#ifdef XLIMITS
- { "/idle-interval", CONN_II, CM_ARG },
- { "/idle-limit", CONN_IL, CM_ARG },
- { "/idle-string", CONN_IS, CM_ARG },
- { "/quietly", CONN_NV, CM_INV },
-#else
- { "/quietly", CONN_NV, 0 },
-#endif /* XLIMITS */
-#ifdef OS2
- { "/synchronous", CONN_SY, CM_INV },
-#endif /* OS2 */
-#ifdef XLIMITS
- { "/time-limit", CONN_TL, CM_ARG },
-#endif /* XLIMITS */
-#ifdef CK_TRIGGER
- { "/trigger", CONN_TS, CM_ARG },
-#endif /* CK_TRIGGER */
- { "",0,0 }
-};
-#define NCONNTAB sizeof(conntab)/sizeof(struct keytab)
-static int nconntab = NCONNTAB;
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
-static struct keytab stattab[] = { /* STATISTICS command switches */
- { "/brief", 1, 0 },
- { "/verbose", 0, 0 }
-};
-#endif /* NOXFER */
-
-#ifndef NOSPL
-#ifdef COMMENT
-struct mtab mactab[MAC_MAX] = { /* Preinitialized macro table */
- { NULL, NULL, 0 }
-};
-#else
-struct mtab *mactab; /* Dynamically allocated macro table */
-#endif /* COMMENT */
-int nmac = 0;
-
-struct keytab mackey[MAC_MAX]; /* Macro names as command keywords */
-#endif /* NOSPL */
-
-#ifndef NOSPL
-#ifdef OS2
-struct keytab beeptab[] = { /* Beep options */
- { "error", BP_FAIL, 0 },
- { "information", BP_NOTE, 0 },
- { "warning", BP_WARN, 0 }
-};
-int nbeeptab = sizeof(beeptab)/sizeof(struct keytab);
-
-/* CLEAR COMMMAND-SCREEN options */
-
-#define CLR_C_ALL 0
-#define CLR_C_BOL 1
-#define CLR_C_BOS 2
-#define CLR_C_EOL 3
-#define CLR_C_EOS 4
-#define CLR_C_LIN 5
-#define CLR_C_SCR 6
-
-struct keytab clrcmdtab[] = {
- { "all", CLR_C_ALL, 0 },
- { "bol", CLR_C_BOL, 0 },
- { "bos", CLR_C_BOS, 0 },
- { "eol", CLR_C_EOL, 0 },
- { "eos", CLR_C_EOS, 0 },
- { "line", CLR_C_LIN, 0 },
- { "scrollback", CLR_C_SCR, 0 }
-};
-int nclrcmd = sizeof(clrcmdtab)/sizeof(struct keytab);
-#endif /* OS2 */
-#endif /* NOSPL */
-
-#ifdef COMMENT
-/* Not used at present */
-static struct keytab pagetab[] = {
- { "/more", 1, CM_INV },
- { "/nopage", 0, 0 },
- { "/page", 1, 0 }
-};
-int npagetab = sizeof(pagetab)/sizeof(struct keytab);
-#endif /* COMMENT */
-
-#define TYP_NOP 0 /* /NOPAGE */
-#define TYP_PAG 1 /* /PAGE */
-#define TYP_HEA 2 /* /HEAD:n */
-#define TYP_TAI 3 /* /TAIL:n */
-#define TYP_PAT 4 /* /MATCH:pattern */
-#define TYP_WID 5 /* /WIDTH:cols */
-#define TYP_COU 6 /* /COUNT */
-#define TYP_OUT 7 /* /OUTPUT:file */
-#define TYP_PFX 8 /* /PREFIX:string */
-#ifdef UNICODE
-#define TYP_XIN 9 /* /TRANSLATE-FROM:charset */
-#define TYP_XUT 10 /* /TRANSLATE-TO:charset */
-#define TYP_XPA 11 /* /TRANSPARENT */
-#endif /* UNICODE */
-#ifdef KUI
-#define TYP_GUI 12 /* /GUI:title */
-#define TYP_HIG 13 /* /HEIGHT:rows */
-#endif /* KUI */
-#define TYP_NUM 14 /* /NUMBER */
-
-static struct keytab typetab[] = { /* TYPE command switches */
- { "/count", TYP_COU, 0 },
-#ifdef UNICODE
- { "/character-set", TYP_XIN, CM_ARG },
-#endif /* UNICODE */
-#ifdef KUI
- { "/gui", TYP_GUI, CM_ARG },
-#endif /* KUI */
- { "/head", TYP_HEA, CM_ARG },
-#ifdef KUI
- { "/height", TYP_HIG, CM_ARG },
-#endif /* KUI */
- { "/match", TYP_PAT, CM_ARG },
-#ifdef CK_TTGWSIZ
- { "/more", TYP_PAG, CM_INV },
- { "/nopage", TYP_NOP, 0 },
- { "/number", TYP_NUM, 0 },
- { "/output", TYP_OUT, CM_ARG },
- { "/page", TYP_PAG, 0 },
-#endif /* CK_TTGWSIZ */
- { "/prefix", TYP_PFX, CM_ARG },
- { "/tail", TYP_TAI, CM_ARG },
-#ifdef UNICODE
- { "/translate-to", TYP_XUT, CM_ARG },
- { "/transparent", TYP_XPA, 0 },
-#endif /* UNICODE */
- { "/width", TYP_WID, CM_ARG },
-#ifdef UNICODE
- { "/xlate-to", TYP_XUT, CM_INV|CM_ARG },
-#endif /* UNICODE */
- { "", 0, 0 }
-};
-int ntypetab = sizeof(typetab)/sizeof(struct keytab) - 1;
-
-int typ_page = -1; /* TYPE /[NO]PAGE default */
-int typ_wid = -1;
-
-#ifndef NOSPL
-#define TRA_ALL 999 /* TRACE command */
-#define TRA_ASG 0
-#define TRA_CMD 1
-
-int tra_asg = 0;
-int tra_cmd = 0;
-
-static struct keytab tracetab[] = { /* TRACE options */
- { "all", TRA_ALL, 0 },
- { "assignments", TRA_ASG, 0 },
- { "command-level", TRA_CMD, 0 }
-};
-static int ntracetab = sizeof(tracetab)/sizeof(struct keytab);
-#endif /* NOSPL */
-
-#ifndef NOSHOW
-VOID
-showtypopts() {
- printf(" TYPE ");
- if (typ_page > -1) {
- prtopt(&optlines,typ_page ? "/PAGE" : "/NOPAGE");
- } else
- prtopt(&optlines,"(no options set)");
- if (typ_wid > -1) {
- ckmakmsg(tmpbuf,TMPBUFSIZ,"/WIDTH:",ckitoa(typ_wid),NULL,NULL);
- prtopt(&optlines,tmpbuf);
- }
- prtopt(&optlines,"");
-}
-#endif /* NOSHOW */
-
-#ifdef LOCUS
-/* isauto == 1 if locus is being switched automatically */
-
-VOID
-setlocus(x, isauto) int x, isauto; {
- extern int quitting;
- if (x) x = 1;
- if (x && locus) return;
- if (!x && !locus) return;
- /* Get here if it actually needs to be changed */
-#ifdef OS2
- if (isauto && /* Automatically switching */
- !quitting && /* not exiting */
- autolocus == 2) { /* and AUTOLOCUS is set to ASK */
- char locmsg[300];
- ckmakmsg(locmsg,300,
- "Switching Locus to ",
- x ? "LOCAL" : "REMOTE",
- " for file management commands\n"
- "such as CD, DIRECTORY, DELETE, RENAME. Type HELP SET\n"
- "LOCUS at the K-95> prompt for further info. Use the\n"
-#ifdef KUI
- "Actions menu or SET LOCUS command to disable automatic\n"
- "Locus switching or to disable these queries.",
-#else /* KUI */
- "SET LOCUS command to disable automatic locus switching\n"
- "or to disable these queries.",
-#endif /* KUI */
- NULL);
- if (uq_ok(locmsg,"OK to switch Locus?",3,NULL,1)) {
- locus = x;
-#ifdef KUI
- KuiSetProperty(KUI_LOCUS,x,0);
-#endif /* KUI */
- return;
- }
- } else {
-#endif /* OS2 */
- if (isauto && msgflg && !quitting)
- printf("Switching LOCUS for file-management commands to %s %s.\n",
- x ? "LOCAL" : "REMOTE",
- "(HELP LOCUS for info)"
- );
- locus = x;
-#ifdef OS2
-#ifdef KUI
- KuiSetProperty(KUI_LOCUS,x,0);
-#endif /* KUI */
- }
-#endif /* OS2 */
-}
-
-VOID
-setautolocus(x) int x; {
- autolocus = x;
-#ifdef KUI
- KuiSetProperty(KUI_AUTO_LOCUS,x,0);
-#endif /* KUI */
-}
-#endif /* LOCUS */
-
-int
-settypopts() { /* Set TYPE option defaults */
- int xp = -1;
- int c, getval;
- while (1) {
- if ((y = cmswi(typetab,ntypetab,"Switch","",xxstring)) < 0) {
- if (y == -3)
- break;
- else
- return(y);
- }
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- switch (y) {
- case TYP_NOP: xp = 0; break;
- case TYP_PAG: xp = 1; break;
- case TYP_WID:
- if (getval)
- if ((x = cmnum("Column at which to truncate",
- ckitoa(cmd_cols),10,&y,xxstring)) < 0)
- return(x);
- typ_wid = y;
- break;
-
- default:
- printf("?Sorry, this option can not be set\n");
- return(-9);
- }
- }
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
- if (xp > -1) typ_page = xp; /* Confirmed, save defaults */
- return(success = 1);
-}
-
-/* Forward declarations of functions local to this module */
-
-#ifdef UNIX
-_PROTOTYP (int douchmod, ( void ) );
-#endif /* UNIX */
-#ifdef CKPURGE
-_PROTOTYP (int dopurge, ( void ) );
-#endif /* CKPURGE */
-#ifndef NOSPL
-_PROTOTYP (int doundef, ( int ) );
-_PROTOTYP (int doask, ( int ) );
-_PROTOTYP (int dodef, ( int ) );
-_PROTOTYP (int doelse, ( void ) );
-_PROTOTYP (int dofor, ( void ) );
-#endif /* NOSPL */
-#ifndef NODIAL
-_PROTOTYP (int dodial, ( int ) );
-#endif /* NODIAL */
-_PROTOTYP (int dodel, ( void ) );
-_PROTOTYP (int dopaus, ( int ) );
-#ifndef NOPUSH
-#ifdef TCPSOCKET
-_PROTOTYP (int doping, ( void ) );
-_PROTOTYP (int doftp, ( void ) );
-#endif /* TCPSOCKET */
-#endif /* NOPUSH */
-#ifndef NORENAME
-#ifndef NOFRILLS
-_PROTOTYP (int dorenam, ( void ) );
-#endif /* NOFRILLS */
-#endif /* NORENAME */
-#ifdef ZCOPY
-_PROTOTYP (int docopy, ( void ) );
-#endif /* ZCOPY */
-#ifdef NT
-_PROTOTYP (int dolink, ( void ));
-#endif /* NT */
-#ifdef CK_REXX
-_PROTOTYP (int dorexx, ( void ) );
-#endif /* CK_REXX */
-
-#ifdef TNCODE
-static struct keytab telcmd[] = {
- { "abort", TN_ABORT, CM_INV }, /* Emotionally toned - don't show */
- { "ao", TN_AO, 0 },
- { "ayt", TN_AYT, 0 },
- { "break", BREAK, 0 },
- { "cancel",TN_ABORT, 0 },
- { "dmark", TN_DM, 0 },
- { "do", DO, 0 },
- { "dont", DONT, 0 },
- { "ec", TN_EC, 0 },
- { "el", TN_EL, 0 },
- { "eof", TN_EOF, 0 },
- { "eor", TN_EOR, 0 },
-#ifdef CK_KERBEROS
-#ifdef KRB5
-#define TN_FWD 1
- { "forward", TN_FWD, CM_INV },
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
- { "ga", TN_GA, 0 },
- { "ip", TN_IP, 0 },
- { "nop", TN_NOP, 0 },
- { "sak", TN_SAK, CM_INV },
- { "sb", SB, 0 },
- { "se", SE, 0 },
- { "susp", TN_SUSP, 0 },
- { "will", WILL, 0 },
- { "wont", WONT, 0 }
-};
-static int ntelcmd = (sizeof(telcmd) / sizeof(struct keytab));
-
-static struct keytab tnopts[] = {
-#ifdef CK_AUTHENTICATION
- { "auth", TELOPT_AUTHENTICATION, 0 },
-#else
- { "auth", TELOPT_AUTHENTICATION, CM_INV },
-#endif /* CK_AUTHENTICATION */
- { "binary", TELOPT_BINARY, 0 },
-#ifdef TN_COMPORT
- { "c", TELOPT_COMPORT, CM_INV|CM_ABR},
- { "co", TELOPT_COMPORT, CM_INV|CM_ABR},
- { "com", TELOPT_COMPORT, CM_INV|CM_ABR},
- { "com-port-control", TELOPT_COMPORT, 0 },
- { "comport-control", TELOPT_COMPORT, CM_INV},
-#else /* TN_COMPORT */
- { "com-port-control", TELOPT_COMPORT, CM_INV },
- { "comport-control", TELOPT_COMPORT, CM_INV},
-#endif /* TN_COMPORT */
- { "echo", TELOPT_ECHO, 0 },
-#ifdef CK_ENCRYPTION
- { "encrypt", TELOPT_ENCRYPTION, 0 },
-#else
- { "encrypt", TELOPT_ENCRYPTION, CM_INV },
-#endif /* CK_ENCRYPTION */
-#ifdef CK_FORWARD_X
- { "forward-x", TELOPT_FORWARD_X, 0 },
-#else
- { "forward-x", TELOPT_FORWARD_X, CM_INV },
-#endif /* CK_FORWARD_X */
-#ifdef IKS_OPTION
- { "kermit", TELOPT_KERMIT, 0 },
-#else
- { "kermit", TELOPT_KERMIT, CM_INV },
-#endif /* IKS_OPTION */
- { "lflow", TELOPT_LFLOW, CM_INV },
- { "logout", TELOPT_LOGOUT, CM_INV },
-#ifdef CK_NAWS
- { "naws", TELOPT_NAWS, 0 },
-#else
- { "naws", TELOPT_NAWS, CM_INV },
-#endif /* CK_NAWS */
-#ifdef CK_ENVIRONMENT
- { "new-environment", TELOPT_NEWENVIRON, 0 },
-#else
- { "new-environment", TELOPT_NEWENVIRON, CM_INV },
-#endif /* CK_ENVIRONMENT */
- { "pragma-heartbeat",TELOPT_PRAGMA_HEARTBEAT, CM_INV },
- { "pragma-logon", TELOPT_PRAGMA_LOGON, CM_INV },
- { "pragma-sspi", TELOPT_SSPI_LOGON, CM_INV },
- { "sak", TELOPT_IBM_SAK, CM_INV },
-#ifdef CK_SNDLOC
- { "send-location", TELOPT_SNDLOC, 0 },
-#else
- { "send-location", TELOPT_SNDLOC, CM_INV },
-#endif /* CK_SNDLOC */
- { "sga", TELOPT_SGA, 0 },
-#ifdef CK_SSL
- { "start-tls", TELOPT_START_TLS, 0 },
-#else
- { "start-tls", TELOPT_START_TLS, CM_INV },
-#endif /* CK_SSL */
- { "ttype", TELOPT_TTYPE, 0 },
-#ifdef CK_ENVIRONMENT
- { "xdisplay-location", TELOPT_XDISPLOC, 0 },
-#else
- { "xdisplay-location", TELOPT_XDISPLOC, CM_INV },
-#endif /* CK_ENVIRONMENT */
- { "", 0, 0 }
-};
-static int ntnopts = (sizeof(tnopts) / sizeof(struct keytab)) - 1;
-
-static struct keytab tnsbopts[] = {
-#ifdef CK_NAWS
- { "naws", TELOPT_NAWS, 0 },
-#endif /* CK_NAWS */
- { "", 0, 0 }
-};
-static int ntnsbopts = (sizeof(tnsbopts) / sizeof(struct keytab)) - 1;
-#endif /* TNCODE */
-
-#ifdef TCPSOCKET
-#ifndef NOPUSH
-#ifdef SYSFTP
-int
-doftp() { /* (External) FTP command */
- char *p, *f; /* (See doxftp() for internal one) */
- int x;
-
- if (network) /* If we have a current connection */
- ckstrncpy(line,ttname,LINBUFSIZ); /* get the host name */
- else *line = '\0'; /* as default host */
- for (p = line; *p; p++) /* Remove ":service" from end. */
- if (*p == ':') { *p = '\0'; break; }
- if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
- return(x);
- if (nopush) {
- printf("?Sorry, FTP command disabled\n");
- return(success = 0);
- }
-/* Construct FTP command */
-#ifdef VMS
-#ifdef MULTINET /* TGV MultiNet */
- ckmakmsg(line,LINBUFSIZ,"multinet ftp ",s,NULL,NULL);
-#else
- ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
-#endif /* MULTINET */
-#else /* Not VMS */
-#ifdef OS2ORUNIX
-#ifndef NOFTP
- f = ftpapp;
- if (!f) f = "";
- if (!f[0]) f = "ftp";
- ckmakmsg(line,LINBUFSIZ,f," ",s,NULL);
-#ifdef OS2
- p = line + strlen(ftpapp);
- while (p != line) {
- if (*p == '/') *p = '\\';
- p--;
- }
-#endif /* OS2 */
-#else /* NOFTP */
- ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
-#endif /* NOFTP */
-#else /* OS2ORUNIX */
- ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
-#endif /* OS2ORUNIX */
-#endif /* VMS */
- conres(); /* Make console normal */
-#ifdef DEC_TCPIP
- printf("\n"); /* Prevent prompt-stomping */
-#endif /* DEC_TCPIP */
- x = zshcmd(line);
- concb((char)escape);
- return(success = x);
-}
-#endif /* SYSFTP */
-
-int
-doping() { /* PING command */
- char *p; /* just runs ping program */
- int x;
-
- if (network) /* If we have a current connection */
- ckstrncpy(line,ttname,LINBUFSIZ); /* get the host name */
- else *line = '\0'; /* as default host to be pinged. */
- for (p = line; *p; p++) /* Remove ":service" from end. */
- if (*p == ':') { *p = '\0'; break; }
- if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
- return(x);
- if (nopush) {
- printf("?Sorry, PING command disabled\n");
- return(success = 0);
- }
-
- /* Construct PING command */
-#ifdef VMS
-#ifdef MULTINET /* TGV MultiNet */
- ckmakmsg(line,LINBUFSIZ,"multinet ping ",s," /num=1",NULL);
-#else
- ckmakmsg(line,LINBUFSIZ,"ping ",s," 56 1",NULL); /* Other VMS TCP/IP's */
-#endif /* MULTINET */
-#else /* Not VMS */
- ckmakmsg(line,LINBUFSIZ,"ping ",s,NULL,NULL);
-#endif /* VMS */
- conres(); /* Make console normal */
-#ifdef DEC_TCPIP
- printf("\n"); /* Prevent prompt-stomping */
-#endif /* DEC_TCPIP */
- x = zshcmd(line);
- concb((char)escape);
- return(success = x);
-}
-#endif /* NOPUSH */
-#endif /* TCPSOCKET */
-
-static VOID
-doend(x) int x; {
-#ifndef NOSPL
- /* Pop from all FOR/WHILE/XIF/SWITCH's */
- debug(F101,"doend maclvl 1","",maclvl);
- while ((maclvl > 0) &&
- (m_arg[maclvl-1][0]) &&
- (cmdstk[cmdlvl].src == CMD_MD) &&
- (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
- !strncmp(m_arg[maclvl-1][0],"_for",4) ||
- !strncmp(m_arg[maclvl-1][0],"_whi",4) ||
- !strncmp(m_arg[maclvl-1][0],"_swi",4))) {
- debug(F110,"END popping",m_arg[maclvl-1][0],0);
- dogta(XXPTA); /* Put args back */
- popclvl(); /* Pop up two levels */
- popclvl();
- debug(F101,"doend maclvl 2","",maclvl);
- }
- if (maclvl > -1) {
- if (mrval[maclvl]) /* Free previous retval if any */
- free(mrval[maclvl]);
- mrval[maclvl] = malloc(16); /* Room for up to 15 digits */
- if (mrval[maclvl]) /* Record current retval */
- ckmakmsg(mrval[maclvl],16,ckitoa(x),NULL,NULL,NULL);
- }
-#endif /* NOSPL */
- popclvl(); /* Now pop out of macro or TAKE file */
-#ifndef NOSPL
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"END maclvl 3","",maclvl);
- debug(F111,"END mrval[maclvl]",mrval[maclvl],maclvl);
- debug(F111,"END mrval[maclvl+1]",mrval[maclvl+1],maclvl+1);
- }
-#endif /* DEBUG */
-#endif /* NOSPL */
-}
-
-#ifdef CKROOT
-int
-dochroot() {
- if ((x = cmdir("Name of new root directory","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Directory name required\n");
- return(-9);
- }
- return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- if ((x = cmcfm()) < 0) return(x);
- s = brstrip(s);
- x = zsetroot(s);
- if (x < 0) {
- char * m = NULL;
- switch (x) {
- case -1:
- case -2: m = "Not a directory"; break;
- case -3: m = "Internal error"; break;
- case -4: m = "Access denied"; break;
- case -5: m = "Off limits"; break;
- }
- if (m) printf("%s: \"%s\"\n", m, s);
- return(m ? -9 : -2);
- } else {
- nopush = 1;
- return(success = 1);
- }
-}
-#endif /* CKROOT */
-
-#ifndef NOXFER
-static char * asnbuf = NULL; /* As-name buffer pointer */
-
-char sndxnam[] = { "_array_x_" }; /* (with replaceable x!) */
-
-/*
- The new SEND command, replacing BSEND, CSEND, PSEND, etc etc.
- Call with cx = top-level keyword value. Returns:
- < 0 On parse error.
- 0 On other type of failure (e.g. requested operation not allowed).
- 1 On success with sstate set to 's' so protocol will begin.
-*/
-
-/* D O X S E N D -- Parse SEND and related commands with switches */
-
-int
-doxsend(cx) int cx; {
- int c, i, n, wild, confirmed = 0; /* Workers */
- int x, y; /* of the world... */
- int getval = 0; /* Whether to get switch value */
- extern char * snd_move; /* Directory to move sent files to */
- extern char * snd_rename; /* What to rename sent files to */
- extern char * filefile; /* File containing filenames to send */
- extern int xfiletype; /* Send only text (or binary) files */
- extern struct keytab pathtab[]; /* PATHNAMES option keywords */
- extern int npathtab; /* How many of them */
- extern int recursive; /* Recursive directory traversal */
- extern int rprintf; /* REMOTE PRINT flag */
- extern int fdispla; /* TRANSFER DISPLAY setting */
- extern int skipbup; /* Skip backup files when sending */
- struct stringint pv[SND_MAX+1]; /* Temporary array for switch values */
- struct FDB sf, sw, fl, cm; /* FDBs for each parse function */
- int mlist = 0; /* Flag for MSEND or MMOVE */
- char * m; /* For making help messages */
- extern struct keytab protos[]; /* File transfer protocols */
- extern int xfrxla, g_xfrxla, nprotos;
- extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */
- extern char sndnbefore[], sndnafter[];
- extern CK_OFF_T sndsmaller, sndlarger, calibrate;
-#ifndef NOSPL
- int range[2]; /* Array range */
- char ** ap = NULL; /* Array pointer */
- int arrayx = -1; /* Array index */
-#endif /* NOSPL */
-
-#ifdef NEWFTP
- if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
- if (cx == XXMAI) {
- printf("?Sorry, No MAIL with FTP\n");
- return(-9);
- }
- return(doftpput(cx,0));
- }
-#endif /* NEWFTP */
-
- for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */
- pv[i].sval = NULL; /* to null pointers */
- pv[i].ival = -1; /* and -1 int values */
- pv[i].wval = (CK_OFF_T)-1; /* and -1 wide values */
- }
-#ifndef NOSPL
- range[0] = -1;
- range[1] = -1;
- sndxin = -1; /* Array index */
-#endif /* NOSPL */
- sndarray = NULL; /* Array pointer */
-
-#ifdef UNIXOROSK
- g_matchdot = matchdot; /* Match dot files */
-#endif /* UNIXOROSK */
- g_recursive = recursive; /* Recursive sending */
- recursive = 0; /* Save global value, set local */
- debug(F101,"xsend entry fncnv","",fncnv);
-
- /* Preset switch values based on top-level command that called us */
-
- switch (cx) {
- case XXMSE: /* MSEND */
- mlist = 1; break;
- case XXCSEN: /* CSEND */
- pv[SND_CMD].ival = 1; break;
- case XXMMOVE: /* MMOVE */
- mlist = 1;
- case XXMOVE: /* MOVE */
- pv[SND_DEL].ival = 1; break;
- case XXRSEN: /* RESEND */
- pv[SND_BIN].ival = 1; /* Implies /BINARY */
- pv[SND_RES].ival = 1; break;
- case XXMAI: /* MAIL */
- pv[SND_MAI].ival = 1; break;
- }
-
- /* Set up chained parse functions... */
-
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Filename, or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
-#ifdef NOMSEND
- nsndtab, /* addtl numeric data 1: tbl size */
-#else
- mlist ? nmsndtab : nsndtab, /* addtl numeric data 1: tbl size */
-#endif /* NOMSEND */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
-#ifdef NOMSEND
- sndtab, /* Keyword table */
-#else
- mlist ? msndtab : sndtab,
-#endif /* NOMSEND */
- &sf /* Pointer to next FDB */
- );
- cmfdbi(&sf, /* 2nd FDB - file to send */
- _CMIFI, /* fcode */
- "File(s) to send", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nolinks, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- mlist ? &cm : &fl
- );
- cmfdbi(&fl, /* 3rd FDB - command to send from */
- _CMFLD, /* fcode */
- "Command", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* 4th FDB - Confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
-
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse something */
- debug(F101,"xsend cmfdb","",x);
- if (x < 0) /* Error */
- goto xsendx; /* or reparse needed */
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
-/*
- They gave a switch, but let's see how they terminated it.
- If they ended it with : or =, then we must parse a value.
- If they ended it with anything else, then we must NOT parse a value.
-*/
- c = cmgbrk(); /* Get break character */
- getval = (c == ':' || c == '='); /* to see how they ended the switch */
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- x = -9;
- goto xsendx;
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- x = -9;
- goto xsendx;
- }
- n = cmresult.nresult; /* Numeric result = switch value */
- debug(F101,"xsend switch","",n);
-
- switch (n) { /* Process the switch */
- case SND_CMD: /* These take no args */
- if (nopush) {
- printf("?Sorry, system command access is disabled\n");
- x = -9;
- goto xsendx;
- }
-#ifdef PIPESEND
- else if (sndfilter) {
- printf(
-"?Sorry, no SEND /COMMAND or CSEND when SEND FILTER selected\n");
- x = -9;
- goto xsendx;
- }
-#endif /* PIPESEND */
- sw.hlpmsg = "Command, or switch"; /* Change help message */
- pv[n].ival = 1; /* Just set the flag */
- pv[SND_ARR].ival = 0;
- break;
-
- case SND_REC: /* /RECURSIVE */
- recursive = 2; /* Set the real variable */
- pv[SND_PTH].ival = PATH_REL; /* Give them relative pathnames */
- pv[n].ival = 1; /* Just set the flag */
- break;
-
- case SND_RES: /* /RECOVER (resend) */
- pv[SND_ARR].ival = 0;
- pv[SND_BIN].ival = 1; /* Implies /BINARY */
- case SND_NOB: /* /NOBACKUP */
- case SND_DEL: /* /DELETE */
- case SND_SHH: /* /QUIET */
- pv[n].ival = 1; /* Just set the flag */
- break;
-
-#ifdef UNIXOROSK
-/* Like recursive, these are set immediately because they affect cmifi() */
- case SND_DOT: /* /DOTFILES */
- matchdot = 1;
- break;
- case SND_NOD: /* /NODOTFILES */
- matchdot = 0;
- break;
-#endif /* UNIXOROSK */
-
- /* File transfer modes - each undoes the others */
-
- case SND_BIN: /* Binary */
- case SND_TXT: /* Text */
- case SND_IMG: /* Image */
- case SND_LBL: /* Labeled */
- pv[SND_BIN].ival = 0;
- pv[SND_TXT].ival = 0;
- pv[SND_IMG].ival = 0;
- pv[SND_LBL].ival = 0;
- pv[n].ival = 1;
- break;
-
-#ifdef CKSYMLINK
- case SND_LNK:
- case SND_NLK:
- nolinks = (n == SND_NLK) ? 2 : 0;
- cmfdbi(&sf, /* Redo cmifi() */
- _CMIFI, /* fcode */
- "File(s) to send", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nolinks, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- mlist ? &cm : &fl
- );
- break;
-#endif /* CKSYMLINK */
-
- case SND_EXC: /* Excludes */
- if (!getval) break;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Pattern required\n");
- x = -9;
- }
- goto xsendx;
- }
- if (pv[n].sval) free(pv[n].sval);
- y = strlen(s);
- if (y > 256) {
- printf("?Pattern too long - 256 max\n");
- x = -9;
- goto xsendx;
- }
- pv[n].sval = malloc(y+1);
- if (pv[n].sval) {
- strcpy(pv[n].sval,s); /* safe */
- pv[n].ival = 1;
- }
- break;
-
- case SND_MOV: /* MOVE after */
- case SND_REN: /* RENAME after */
- if (!getval) break;
- if ((x = cmfld(n == SND_MOV ?
- "device and/or directory for source file after sending" :
- "new name for source file after sending",
- "",
- &s,
- n == SND_MOV ? xxstring : NULL
- )) < 0) {
- if (x == -3) {
- printf("%s\n", n == SND_MOV ?
- "?Destination required" :
- "?New name required"
- );
- x = -9;
- }
- goto xsendx;
- }
- if (pv[n].sval) free(pv[n].sval);
- s = brstrip(s);
- y = strlen(s);
- if (y > 0) {
- pv[n].sval = malloc(y+1);
- if (pv[n].sval) {
- strcpy(pv[n].sval,s); /* safe */
- pv[n].ival = 1;
- }
- }
- break;
-
- case SND_SMA: /* Smaller / larger than */
- case SND_LAR: {
- CK_OFF_T w;
- if (!getval) break;
- if ((x = cmnumw("Size in bytes","0",10,&w,xxstring)) < 0)
- goto xsendx;
- pv[n].wval = w;
- break;
- }
- case SND_AFT: /* Send /AFTER:date-time */
- case SND_BEF: /* Send /BEFORE:date-time */
- case SND_NAF: /* Send /NOT-AFTER:date-time */
- case SND_NBE: /* Send /NOT-BEFORE:date-time */
- if (!getval) break;
- if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) {
- if (x == -3) {
- printf("?Date-time required\n");
- x = -9;
- }
- goto xsendx;
- }
- if (pv[n].sval) free(pv[n].sval);
- pv[n].sval = malloc((int)strlen(s)+1);
- if (pv[n].sval) {
- strcpy(pv[n].sval,s); /* safe */
- pv[n].ival = 1;
- }
- break;
-
- case SND_MAI: /* Send as mail (= MAIL) */
-#ifdef IKSD
- if (inserver && !ENABLED(en_mai)) {
- printf("?Sorry, sending files as mail is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
- pv[n].ival = 1;
- if (!getval) break;
- if ((x = cmfld("e-mail address","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?address required\n");
- x = -9;
- }
- goto xsendx;
- }
- s = brstrip(s);
- if (pv[n].sval) free(pv[n].sval);
- pv[n].sval = malloc((int)strlen(s)+1);
- if (pv[n].sval)
- strcpy(pv[n].sval,s); /* safe */
- break;
-
- case SND_PRI: /* Send to be printed (REMOTE PRINT) */
-#ifdef IKSD
- if (inserver && !ENABLED(en_mai)) {
- printf("?Sorry, sending files for printing is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
- pv[n].ival = 1;
- if (!getval) break;
- if ((x = cmfld("Print options","",&s,xxstring)) < 0)
- if (x != -3) goto xsendx;
- s = brstrip(s);
- if (pv[n].sval) free(pv[n].sval);
- pv[n].sval = malloc((int)strlen(s)+1);
- if (pv[n].sval)
- strcpy(pv[n].sval,s); /* safe */
- break;
-
- case SND_ASN: /* As-name */
- debug(F101,"xsend /as-name getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Name to send under","",&s,NULL)) < 0) {
- if (x == -3) {
- printf("?name required\n");
- x = -9;
- }
- goto xsendx;
- }
- s = brstrip(s);
- if ((y = strlen(s)) > 0) {
- if (pv[n].sval) free(pv[n].sval);
- pv[n].sval = malloc(y+1);
- if (pv[n].sval) {
- strcpy(pv[n].sval,s); /* safe */
- pv[n].ival = 1;
- }
- }
- break;
-
- case SND_STA: { /* Starting position (= PSEND) */
- CK_OFF_T w;
- if (!getval) break;
- if ((x = cmnumw("0-based position","0",10,&w,xxstring)) < 0)
- goto xsendx;
- pv[n].wval = w;
- break;
- }
- case SND_PRO: /* Protocol to use */
- if (!getval) break;
- if ((x = cmkey(protos,nprotos,"File-transfer protocol","",
- xxstring)) < 0) {
- if (x == -3) {
- printf("?name of protocol required\n");
- x = -9;
- }
- goto xsendx;
- }
- pv[n].ival = x;
- break;
-
-#ifdef PIPESEND
- case SND_FLT: /* Filter */
- debug(F101,"xsend /filter getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
- if (x == -3)
- s = "";
- else
- goto xsendx;
- }
- if (*s) s = brstrip(s);
- y = strlen(s);
- for (x = 0; x < y; x++) { /* Make sure they included "\v(...)" */
- if (s[x] != '\\') continue;
- if (s[x+1] == 'v') break;
- }
- if (x == y) {
- printf(
- "?Filter must contain a replacement variable for filename.\n"
- );
- x = -9;
- goto xsendx;
- }
- pv[n].ival = 1;
- if (pv[n].sval) {
- free(pv[n].sval);
- pv[n].sval = NULL;
- }
- if ((y = strlen(s)) > 0) {
- if ((pv[n].sval = malloc(y+1)))
- strcpy(pv[n].sval,s); /* safe */
- }
- break;
-#endif /* PIPESEND */
-
- case SND_PTH: /* Pathnames */
- if (!getval) {
- pv[n].ival = PATH_REL;
- break;
- }
- if ((x = cmkey(pathtab,npathtab,"","absolute",xxstring)) < 0)
- goto xsendx;
- pv[n].ival = x;
- break;
-
- case SND_NAM: /* Filenames */
- if (!getval) break;
- if ((x = cmkey(fntab,nfntab,"","converted",xxstring)) < 0)
- goto xsendx;
- debug(F101,"xsend /filenames","",x);
- pv[n].ival = x;
- break;
-
-#ifdef CALIBRATE
- case SND_CAL: { /* /CALIBRATE */
- CK_OFF_T w;
- if (getval) {
- if ((x = cmnumw("number of Kbytes to send",
- "1024",10,&w,xxstring)) < 0)
- goto xsendx;
- } else
- w = (CK_OFF_T)1024;
- pv[n].wval = w;
- pv[SND_ARR].ival = 0;
- break;
- }
-#endif /* CALIBRATE */
-
- case SND_FIL: /* Name of file containing filnames */
- if (!getval) break;
- if ((x = cmifi("Name of file containing list of filenames",
- "",&s,&y,xxstring)) < 0) {
- if (x == -3) {
- printf("?Filename required\n");
- x = -9;
- }
- goto xsendx;
- } else if (y) {
- printf("?Wildcards not allowed\n");
- x = -9;
- goto xsendx;
- }
- if (pv[n].sval)
- free(pv[n].sval);
- if (s) if (*s) {
- if ((pv[n].sval = malloc((int)strlen(s)+1))) {
- strcpy(pv[n].sval,s);
- pv[n].ival = 1;
- pv[SND_ARR].ival = 0;
- }
- }
- break;
-
-#ifndef NOSPL
- case SND_ARR: /* SEND /ARRAY: */
- if (!getval) break;
- ap = NULL;
- if ((x = cmfld("Array name (a single letter will do)",
- "",
- &s,
- NULL
- )) < 0) {
- if (x == -3)
- break;
- else
- return(x);
- }
- if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
- printf("?Bad array: %s\n",s);
- return(-9);
- }
- if (!(ap = a_ptr[x])) {
- printf("?No such array: %s\n",s);
- return(-9);
- }
- pv[n].ival = 1;
- pv[SND_CMD].ival = 0; /* Undo any conflicting ones... */
- pv[SND_RES].ival = 0;
- pv[SND_CAL].ival = 0;
- pv[SND_FIL].ival = 0;
- arrayx = x;
- break;
-#endif /* NOSPL */
-
- case SND_XPA: /* /TRANSPARENT */
- pv[n].ival = 1;
- break;
-
- case SND_TYP: /* Only files of given type */
- if (!getval) break;
- if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0)
- goto xsendx;
- pv[n].ival = (x == 2) ? -1 : x;
- break;
-
- default:
- printf("?Unexpected switch value - %d\n",cmresult.nresult);
- x = -9;
- goto xsendx;
- }
- }
- debug(F101,"xsend cmresult fcode","",cmresult.fcode);
-
-#ifdef COMMENT
- /* List switch parsing results in debug log */
- for (i = 0; i <= SND_MAX; i++) {
- ckmakmsg(line,LINBUFSIZ,"xsend switch ",ckitoa(i),NULL,NULL);
- debug(F111,line, pv[i].sval, pv[i].ival);
- }
-#endif /* COMMENT */
-
-/* Now we have all switches, plus maybe a filename or command, or nothing */
-
-#ifdef PIPESEND
- if (protocol != PROTO_K && pv[SND_CMD].ival > 0) {
- printf("?Sorry, %s works only with Kermit protocol\n",
- (cx == XXCSEN) ? "CSEND" : "SEND /COMMAND");
- x = -9;
- goto xsendx;
- }
- if (pv[SND_RES].ival > 0 || /* /RECOVER */
- pv[SND_STA].wval > 0) { /* or /STARTING */
- if (sndfilter || pv[SND_FLT].ival > 0) {
- printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n");
- x = -9;
- goto xsendx;
- }
- }
-#endif /* PIPESEND */
-
- cmarg = "";
- cmarg2 = "";
- line[0] = NUL;
- s = line;
- wild = 0;
-
- switch (cmresult.fcode) { /* How did we get out of switch loop */
- case _CMIFI: /* Input filename */
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
- if (pv[SND_ARR].ival > 0)
- cmarg2 = line;
- else
- wild = cmresult.nresult; /* Wild flag */
- if (!recursive && !wild)
- nolinks = 0;
- break;
- case _CMFLD: /* Field */
- /* Only allowed with /COMMAND and /ARRAY */
- if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off limits: %s\n",cmresult.sresult);
- else
-#endif /* CKROOT */
- printf("?%s - \"%s\"\n",
- iswild(cmresult.sresult) ?
- "No files match" : "File not found",
- cmresult.sresult
- );
- x = -9;
- goto xsendx;
- }
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- if (pv[SND_ARR].ival > 0)
- cmarg2 = line;
- break;
- case _CMCFM: /* Confirmation */
- /* s = ""; */
- confirmed = 1;
- break;
- default:
- printf("?Unexpected function code: %d\n",cmresult.fcode);
- x = -9;
- goto xsendx;
- }
- debug(F110,"xsend string",s,0);
- debug(F101,"xsend confirmed","",confirmed);
-
- /* Save and change protocol and transfer mode */
- /* Global values are restored in main parse loop */
-
- g_proto = protocol; /* Save current global protocol */
- g_urpsiz = urpsiz;
- g_spsizf = spsizf;
- g_spsiz = spsiz;
- g_spsizr = spsizr;
- g_spmax = spmax;
- g_wslotr = wslotr;
- g_prefixing = prefixing;
- g_fncact = fncact;
- g_fncnv = fncnv;
- g_fnspath = fnspath;
- g_fnrpath = fnrpath;
- g_xfrxla = xfrxla;
-
- if (pv[SND_PRO].ival > -1) { /* Change according to switch */
- protocol = pv[SND_PRO].ival;
- if (ptab[protocol].rpktlen > -1) /* copied from initproto() */
- urpsiz = ptab[protocol].rpktlen;
- if (ptab[protocol].spktflg > -1)
- spsizf = ptab[protocol].spktflg;
- if (ptab[protocol].spktlen > -1) {
- spsiz = ptab[protocol].spktlen;
- if (spsizf)
- spsizr = spmax = spsiz;
- }
- if (ptab[protocol].winsize > -1)
- wslotr = ptab[protocol].winsize;
- if (ptab[protocol].prefix > -1)
- prefixing = ptab[protocol].prefix;
- if (ptab[protocol].fnca > -1)
- fncact = ptab[protocol].fnca;
- if (ptab[protocol].fncn > -1)
- fncnv = ptab[protocol].fncn;
- if (ptab[protocol].fnsp > -1)
- fnspath = ptab[protocol].fnsp;
- if (ptab[protocol].fnrp > -1)
- fnrpath = ptab[protocol].fnrp;
- }
- debug(F101,"xsend protocol","",protocol);
-
- if (pv[SND_NOB].ival > -1) { /* /NOBACKUP (skip backup file) */
- g_skipbup = skipbup;
- skipbup = 1;
- }
- if (pv[SND_REC].ival > 0) /* /RECURSIVE */
- recursive = 2;
-
- if (pv[SND_TYP].ival > -1) { /* /TYPE */
- xfiletype = pv[SND_TYP].ival;
- if (xfiletype == 2)
- xfiletype = -1;
- }
- g_binary = binary; /* Save global transfer mode */
-#ifdef PATTERNS
- g_patterns = patterns; /* Save FILE PATTERNS setting */
-#endif /* PATTERNS */
- if (pv[SND_BIN].ival > 0) { /* Change according to switch */
- /* If they said /BINARY they mean /BINARY */
- patterns = 0; /* So no pattern-based switching */
- g_xfermode = xfermode; /* or automatic transfer mode */
- xfermode = XMODE_M;
- binary = XYFT_B;
- debug(F101,"doxsend /BINARY xfermode","",xfermode);
- } else if (pv[SND_TXT].ival > 0) { /* Ditto for /TEXT */
- patterns = 0;
- g_xfermode = xfermode;
- xfermode = XMODE_M;
- binary = XYFT_T;
- debug(F101,"doxsend /TEXT xfermode","",xfermode);
- } else if (pv[SND_IMG].ival > 0) {
-#ifdef VMS
- binary = XYFT_I;
-#else
- binary = XYFT_B;
-#endif /* VMS */
- }
-#ifdef CK_LABELED
- else if (pv[SND_LBL].ival > 0) {
- binary = XYFT_L;
- }
-#endif /* CK_LABELED */
- debug(F101,"xsend binary","",binary);
-
- if (pv[SND_XPA].ival > 0) /* /TRANSPARENT */
- xfrxla = 0; /* Don't translate character sets */
-
- /* Check for legal combinations of switches, filenames, etc */
-
-#ifdef PIPESEND
- if (pv[SND_CMD].ival > 0) { /* COMMAND - strip any braces */
- debug(F110,"SEND /COMMAND before stripping",s,0);
- s = brstrip(s);
- debug(F110,"SEND /COMMAND after stripping",s,0);
- if (!*s) {
- printf("?Sorry, a command to send from is required\n");
- x = -9;
- goto xsendx;
- }
- cmarg = s;
- }
-#endif /* PIPESEND */
-
-/* Set up /MOVE and /RENAME */
-
- if (pv[SND_DEL].ival > 0 &&
- (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
- printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
- x = -9;
- goto xsendx;
- }
-#ifdef CK_TMPDIR
- if (pv[SND_MOV].ival > 0) {
- int len;
- char * p = pv[SND_MOV].sval;
-#ifdef CK_LOGIN
- if (isguest) {
- printf("?Sorry, /MOVE-TO not available to guests\n");
- x = -9;
- goto xsendx;
- }
-#endif /* CK_LOGIN */
- len = strlen(p);
- if (!isdir(p)) { /* Check directory */
-#ifdef CK_MKDIR
- char * s = NULL;
- s = (char *)malloc(len + 4);
- if (s) {
- strcpy(s,p); /* safe */
-#ifdef datageneral
- if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
-#else
- if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
-#endif /* datageneral */
- s[len++] = 'X';
- s[len] = NUL;
- x = zmkdir(s);
- free(s);
- if (x < 0) {
- printf("?Can't create \"%s\"\n",p);
- x = -9;
- goto xsendx;
- }
- }
-#else
- printf("?Directory \"%s\" not found\n",p);
- x = -9;
- goto xsendx;
-#endif /* CK_MKDIR */
- }
- zfnqfp(p,LINBUFSIZ,tmpbuf);
- makestr(&snd_move,tmpbuf);
- }
-#endif /* CK_TMPDIR */
-
- if (pv[SND_REN].ival > 0) { /* /RENAME */
- char * p = pv[SND_REN].sval;
-#ifdef CK_LOGIN
- if (isguest) {
- printf("?Sorry, /RENAME-TO not available to guests\n");
- x = -9;
- goto xsendx;
- }
-#endif /* CK_LOGIN */
- if (!p) p = "";
- if (!*p) {
- printf("?New name required for /RENAME\n");
- x = -9;
- goto xsendx;
- }
- p = brstrip(p);
-#ifndef NOSPL
- /* If name given is wild, rename string must contain variables */
- if (wild) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(p,&s,&x);
- if (!strcmp(tmpbuf,p)) {
- printf(
- "?/RENAME for file group must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xsendx;
- }
- }
-#endif /* NOSPL */
- makestr(&snd_rename,p);
- }
-
-/* Handle /RECOVER and /START */
-
-#ifdef CK_RESEND
- if (pv[SND_RES].ival > 0 && binary != XYFT_B && !filepeek
-#ifdef PATTERNS
- && !patterns
-#else
-#ifdef VMS
-/* VMS sets text/binary automatically later when it opens the file */
- && 0
-#endif /* VMS */
-#endif /* PATTERNS */
- ) {
- printf("?Sorry, /BINARY required\n");
- x = -9;
- goto xsendx;
- }
- if (pv[SND_STA].wval > 0) { /* /START */
- if (wild) {
- printf("?Sorry, wildcards not permitted with /START\n");
- x = -9;
- goto xsendx;
- }
- if (sizeof(int) < 4) {
- printf("?Sorry, this command needs at least 32-bit integers\n");
- x = -9;
- goto xsendx;
- }
-#ifdef CK_XYZ
- if (protocol != PROTO_K) {
- printf("?Sorry, SEND /START works only with Kermit protocol\n");
- x = -9;
- goto xsendx;
- }
-#endif /* CK_XYZ */
- }
-#ifdef CK_XYZ
- if (pv[SND_RES].ival > 0) {
- if (protocol != PROTO_K && protocol != PROTO_Z) {
- printf(
- "Sorry, /RECOVER is possible only with Kermit or ZMODEM protocol\n"
- );
- x = -9;
- goto xsendx;
- }
- }
-#endif /* CK_XYZ */
-#endif /* CK_RESEND */
-
- if (protocol == PROTO_K) {
- if ((pv[SND_MAI].ival > 0 || /* MAIL */
- pv[SND_PRI].ival > 0 || /* PRINT */
- pv[SND_RES].ival > 0 /* RESEND */
- ) &&
- (!atdiso || !atcapr)) { /* Disposition attribute off? */
- printf("?Sorry, ATTRIBUTE DISPOSITION must be ON\n");
- x = -9;
- goto xsendx;
- }
- }
-
-#ifdef CK_XYZ
- if (wild && (protocol == PROTO_X || protocol == PROTO_XC)) {
- printf(
-"Sorry, you can only send one file at a time with XMODEM protocol\n"
- );
- x = -9;
- goto xsendx;
- }
-#endif /* CK_XYZ */
-
- if (!confirmed) { /* CR not typed yet, get more fields */
- char *m;
- if (mlist) { /* MSEND or MMOVE */
- nfils = 0; /* We already have the first one */
-#ifndef NOMSEND
- msfiles[nfils++] = line; /* Store pointer */
- lp = line + (int)strlen(line) + 1; /* Point past it */
- debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
- while (1) { /* Get more filenames */
- char *p;
- if ((x = cmifi("Names of files to send, separated by spaces",
- "", &s,&y,xxstring)) < 0) {
- if (x != -3)
- goto xsendx;
- if ((x = cmcfm()) < 0)
- goto xsendx;
- break;
- }
- msfiles[nfils++] = lp; /* Got one, count it, point to it, */
- p = lp; /* remember pointer, */
- while ((*lp++ = *s++)) /* and copy it into buffer */
- if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
- printf("?MSEND list too long\n");
- line[0] = NUL;
- x = -9;
- goto xsendx;
- }
- debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
- if (nfils == 1) fspec[0] = NUL; /* Take care of \v(filespec) */
-#ifdef ZFNQFP
- zfnqfp(p,TMPBUFSIZ,tmpbuf);
- p = tmpbuf;
-#endif /* ZFNQFP */
- if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
- strcat(fspec,p); /* safe */
- strcat(fspec," "); /* safe */
- } else
-#ifdef COMMENT
- printf("WARNING - \\v(filespec) buffer overflow\n");
-#else
- debug(F101,"doxsend filespec buffer overflow","",0);
-#endif /* COMMENT */
- }
-#endif /* NOMSEND */
- } else { /* Regular SEND */
- char *p; int y;
- nfils = -1;
- if (pv[SND_MAI].ival > 0)
- m = (pv[SND_MAI].sval) ?
- "e-mail address (optional)" :
- "e-mail address (required)";
- else if (pv[SND_PRI].ival > 0)
- m = "printer options (optional)";
- else if (wild)
- m =
-"\nOptional as-name template containing replacement variables \
-like \\v(filename)";
- else
- m = "Optional name to send it with";
- if ((x = cmtxt(m,"",&p,NULL)) < 0)
- goto xsendx;
- if (!p) p = "";
- if (*p) { /* If some text was given... */
- p = brstrip(p); /* Replace /AS-NAME: value if any */
- if ((y = strlen(p)) > 0) {
- if (pv[SND_MAI].ival > 0) {
- makestr(&pv[SND_MAI].sval, p);
- } else {
- if (pv[SND_ASN].sval) free(pv[SND_ASN].sval);
- pv[SND_ASN].sval = malloc(y+1);
- if (pv[SND_ASN].sval) {
- strcpy(pv[SND_ASN].sval,p); /* safe */
- pv[SND_ASN].ival = 1;
- }
- }
- }
- }
- }
- }
- /* Set cmarg2 from as-name, however we got it. */
-
- if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !*cmarg2) {
- int x;
- x = strlen(line);
- ckstrncpy(line+x+2,pv[SND_ASN].sval,LINBUFSIZ-x-1);
- cmarg2 = line+x+2;
- debug(F110,"doxsend cmarg2",cmarg2,0);
- }
-
-#ifndef NOFRILLS
- if ((pv[SND_MAI].ival > 0) && (pv[SND_PRI].ival > 0)) {
- printf("Sorry, /MAIL and /PRINT are conflicting options\n");
- x = -9;
- goto xsendx;
- }
- n = 0; /* /MAIL or /PRINT? */
- if (pv[SND_MAI].ival > 0)
- n = SND_MAI;
- else if (pv[SND_PRI].ival > 0)
- n = SND_PRI;
- if (n) { /* Yes... */
-#ifdef DEBUG
- char * p;
- if (n == SND_MAI)
- p = "/MAIL";
- else
- p = "/PRINT";
- debug(F111,"xsend",p,n);
-#endif /* DEBUG */
-#ifdef CK_XYZ
- if (protocol != PROTO_K) {
- printf("Sorry, %s available only with Kermit protocol\n",
- (n == SND_MAI) ? "/MAIL" : "/PRINT"
- );
- x = -9;
- goto xsendx;
- }
-#endif /* CK_XYZ */
- debug(F101,"xsend print/mail wild","",wild);
- *optbuf = NUL; /* Wipe out any old options */
- s = pv[n].sval; /* mail address or print switch val */
- if (!s) s = "";
- debug(F110,"doxsend mail address or printer options",s,0);
- if (n == SND_MAI && !*s) {
- printf("?E-mail address required\n");
- x = -9;
- goto xsendx;
- } else if ((int)strlen(s) > 94) { /* Ensure legal size */
- printf("?%s too long\n",
- (n == SND_MAI) ?
- "E-mail address" :
- "Print option string"
- );
- x = -9;
- goto xsendx;
- }
- ckstrncpy(optbuf,s,OPTBUFLEN); /* OK, copy to option buffer */
- cmarg = line; /* File to send */
- if (n == SND_MAI) {
- debug(F110,"xsend mailing",cmarg,0);
- debug(F110,"xsend address:",optbuf,0);
- rmailf = 1;
- } else {
- debug(F110,"xsend printing",cmarg,0);
- debug(F110,"xsend options",optbuf,0);
- rprintf = 1;
- }
- }
-#endif /* NOFRILLS */
-
-#ifdef CALIBRATE
- if (pv[SND_CAL].wval > 0) { /* Handle /CALIBRATE */
- if (confirmed) {
- calibrate = pv[SND_CAL].wval * (CK_OFF_T)1024;
- sndsrc = -9;
- nfils = 1;
- wild = 0;
-#ifndef NOMSEND
- addlist = 0;
-#endif /* NOMSEND */
- ckstrncpy(line,"CALIBRATION",LINBUFSIZ);
- s = cmarg = line;
- if (!cmarg2) cmarg2 = "";
- debug(F110,"doxsend cmarg2 calibrate",cmarg2,0);
- } else if (line[0]) {
- calibrate = 0;
- pv[SND_CAL].ival = 0;
- pv[SND_CAL].wval = 0;
- }
- }
-#endif /* CALIBRATE */
-
- if (pv[SND_FIL].ival > 0) {
- if (confirmed && !calibrate) {
- if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
- debug(F110,"xsend can't open",pv[SND_FIL].sval,0);
- printf("?Failure to open %s\n",filefile);
- x = -9;
- goto xsendx;
- }
- makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */
- debug(F110,"xsend opened",filefile,0);
- wild = 1;
- }
- }
-
- /* SEND alone... */
-
-#ifndef NOSPL
- if (confirmed && pv[SND_ARR].ival > 0) {
- if (!*cmarg2) {
- sndxnam[7] = (char)((arrayx == 1) ? 64 : arrayx + ARRAYBASE);
- cmarg2 = sndxnam;
- }
- cmarg = "";
- goto sendend;
- }
-#endif /* NOSPL */
-
- if (confirmed && !line[0] && !filefile && !calibrate) {
-#ifndef NOMSEND
- if (filehead) { /* OK if we have a SEND-LIST */
- nfils = filesinlist;
- sndsrc = nfils; /* Like MSEND */
- addlist = 1; /* But using a different list... */
- filenext = filehead;
- goto sendend;
- }
-#endif /* NOMSEND */
- printf("?Filename required but not given\n");
- x = -9;
- goto xsendx;
- }
-
- /* Not send-list or array */
-
-#ifndef NOMSEND
- addlist = 0; /* Don't use SEND-LIST. */
- filenext = NULL;
-#endif /* NOMSEND */
-
- if (mlist) { /* MSEND or MMOVE */
-#ifndef NOMSEND
- cmlist = msfiles; /* List of files to send */
- sndsrc = nfils;
- cmarg2 = "";
- sendstart = (CK_OFF_T)0;
-#endif /* NOMSEND */
-#ifdef PIPESEND
- pipesend = 0;
-#endif /* PIPESEND */
- } else if (filefile) { /* File contains list of filenames */
- s = "";
- cmarg = "";
- cmarg2 = "";
- line[0] = NUL;
- nfils = 1;
- sndsrc = 1;
-
- } else if (!calibrate && pv[SND_ARR].ival < 1 && pv[SND_CMD].ival < 1) {
-
- nfils = sndsrc = -1; /* Not MSEND, MMOVE, /LIST, or /ARRAY */
- if ( /* or /COMMAND */
-
-#ifndef NOFRILLS
- !rmailf && !rprintf /* Not MAIL or PRINT */
-#else
- 1
-#endif /* NOFRILLS */
- ) {
- CK_OFF_T y = (CK_OFF_T)1;
- if (!wild)
- y = zchki(s);
- if (y < (CK_OFF_T)0) {
- printf("?Read access denied - \"%s\"\n", s);
- x = -9;
- goto xsendx;
- }
- if (s != line) /* We might already have done this. */
- ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */
- else
- debug(F110,"doxsend line=s",line,0);
- cmarg = line; /* File to send */
- }
- zfnqfp(cmarg,fspeclen,fspec);
- }
- if (!mlist) { /* For all but MSEND... */
-#ifdef PIPESEND
- if (pv[SND_CMD].ival > 0) /* /COMMAND sets pipesend flag */
- pipesend = 1;
- debug(F101,"xsend /COMMAND pipesend","",pipesend);
- if (pipesend && filefile) {
- printf("?Invalid switch combination\n");
- x = -9;
- goto xsendx;
- }
-#endif /* PIPESEND */
-
-#ifndef NOSPL
- /* If as-name given and filespec is wild, as-name must contain variables */
- debug(F111,"doxsend cmarg2 wild",cmarg2,wild);
- if (wild && *cmarg2) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(cmarg2,&s,&x);
- if (!strcmp(tmpbuf,cmarg2)) {
- printf(
- "?As-name for file group must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xsendx;
- }
- }
-#endif /* NOSPL */
-
- /* Strip braces from as-name */
- debug(F110,"xsend cmarg2 before stripping",cmarg2,0);
- cmarg2 = brstrip(cmarg2);
- debug(F110,"xsend filename",cmarg,0);
- debug(F110,"xsend as-name",cmarg2,0);
-
- /* Copy as-name to a safe place */
-
- if (asnbuf) {
- free(asnbuf);
- asnbuf = NULL;
- }
- if ((y = strlen(cmarg2)) > 0) {
- asnbuf = (char *) malloc(y + 1);
- if (asnbuf) {
- strcpy(asnbuf,cmarg2); /* safe */
- cmarg2 = asnbuf;
- } else cmarg2 = "";
- }
-
-#ifdef CK_RESEND
- debug(F111,"xsend pv[SND_STA].ival","",pv[SND_STA].ival);
- if (pv[SND_STA].wval > (CK_OFF_T)-1) { /* /START position */
- if (wild) {
- printf("?/STARTING-AT may not be used with multiple files.\n");
- x = -9;
- goto xsendx;
- } else
- sendstart = pv[SND_STA].wval;
- } else
- sendstart = (CK_OFF_T)0;
- debug(F101,"xsend /STARTING","",sendstart);
-#endif /* CK_RESEND */
- }
-
-sendend: /* Common successful exit */
- moving = 0;
- if (pv[SND_SHH].ival > 0) { /* SEND /QUIET... */
- g_displa = fdispla;
- fdispla = 0;
- debug(F101,"xsend display","",fdispla);
- }
-
-#ifndef NOSPL /* SEND /ARRAY... */
- if (pv[SND_ARR].ival > 0) {
- if (!ap) { x = -2; goto xsendx; } /* (shouldn't happen) */
- if (range[0] == -1) /* If low end of range not specified */
- range[0] = 1; /* default to 1 */
- if (range[1] == -1) /* If high not specified */
- range[1] = a_dim[arrayx]; /* default to size of array */
- if ((range[0] < 0) || /* Check range */
- (range[0] > a_dim[arrayx]) ||
- (range[1] < range[0]) ||
- (range[1] > a_dim[arrayx])) {
- printf("?Bad array range - [%d:%d]\n",range[0],range[1]);
- x = -9;
- goto xsendx;
- }
- sndarray = ap; /* Array pointer */
- sndxin = arrayx; /* Array index */
- sndxlo = range[0]; /* Array range */
- sndxhi = range[1];
- sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE);
-
-#ifdef COMMENT
- printf("SENDING FROM ARRAY: &%c[]...\n", /* debugging */
- (sndxin == 1) ? 64 : sndxin + ARRAYBASE);
- printf("Lo=%d\nHi=%d\n", sndxlo, sndxhi);
- printf("cmarg=[%s]\ncmarg2=[%s]\n", cmarg, cmarg2);
- while ((x = agnbyte()) > -1) {
- putchar((char)x);
- }
- return(1);
-#endif /* COMMENT */
- }
-#endif /* NOSPL */
-
- if (pv[SND_ARR].ival < 1) { /* File selection & disposition... */
-
- if (pv[SND_DEL].ival > 0) /* /DELETE was specified */
- moving = 1;
- debug(F101,"xsend /DELETE","",moving);
- if (pv[SND_AFT].ival > 0) /* Copy SEND criteria */
- ckstrncpy(sndafter,pv[SND_AFT].sval,19);
- if (pv[SND_BEF].ival > 0)
- ckstrncpy(sndbefore,pv[SND_BEF].sval,19);
- if (pv[SND_NAF].ival > 0)
- ckstrncpy(sndnafter,pv[SND_NAF].sval,19);
- if (pv[SND_NBE].ival > 0)
- ckstrncpy(sndnbefore,pv[SND_NBE].sval,19);
- if (pv[SND_EXC].ival > 0)
- makelist(pv[SND_EXC].sval,sndexcept,NSNDEXCEPT);
- if (pv[SND_SMA].wval > (CK_OFF_T)-1)
- sndsmaller = pv[SND_SMA].wval;
- if (pv[SND_LAR].wval > (CK_OFF_T)-1)
- sndlarger = pv[SND_LAR].wval;
- if (pv[SND_NAM].ival > -1) {
- g_fncnv = fncnv; /* Save global value */
- fncnv = pv[SND_NAM].ival;
- debug(F101,"xsend fncnv","",fncnv);
- }
- if (pv[SND_PTH].ival > -1) {
- g_spath = fnspath; /* Save global values */
- fnspath = pv[SND_PTH].ival;
-#ifndef NZLTOR
- if (fnspath != PATH_OFF) {
- g_fncnv = fncnv; /* Bad bad... */
- fncnv = XYFN_C;
- }
-#endif /* NZLTOR */
- debug(F101,"xsend fnspath","",fnspath);
- debug(F101,"xsend fncnv","",fncnv);
- }
- }
-
-#ifdef PIPESEND
- if (pv[SND_FLT].ival > 0) {
- makestr(&sndfilter,pv[SND_FLT].sval);
- debug(F110,"xsend /FILTER", sndfilter, 0);
- }
-#endif /* PIPESEND */
-
-#ifdef CK_APC
-/* MOVE not allowed in APCs */
- if (moving &&
- (apcactive == APC_LOCAL || apcactive == APC_REMOTE)
- && !(apcstatus & APC_UNCH))
- return(success = 0);
-#endif /* CK_APC */
-#ifdef IKS_OPTION
- if (
-#ifdef CK_XYZ
- protocol == PROTO_K &&
-#endif /* CK_XYZ */
- !iks_wait(KERMIT_REQ_START,1)) {
- printf("?A Kermit Server is not available to process this command.\n");
- printf("?Start a RECEIVE command to complement this command.\n");
- }
-#endif /* IKS_OPTION */
-
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (moving && inserver && isguest) {
- printf("?File deletion not allowed for guests.\n");
- return(-9);
- }
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-
- sstate = 's'; /* Set start state to SEND */
- sndcmd = 1;
-#ifdef CK_RESEND
- if (pv[SND_RES].ival > 0) /* Send sendmode appropriately */
- sendmode = SM_RESEND;
- else if (pv[SND_STA].ival > 0)
- sendmode = SM_PSEND;
- else
-#endif /* CK_RESEND */
- if (mlist)
- sendmode = SM_MSEND;
- else
- sendmode = SM_SEND;
-#ifdef MAC
- what = W_SEND;
- scrcreate();
-#endif /* MAC */
- if (local && pv[SND_SHH].ival != 0) { /* If in local mode, */
- displa = 1; /* turn on file transfer display */
- }
- x = 0;
-
- xsendx: /* Common exit, including failure */
- debug(F101,"doxsend sndsrc","",sndsrc);
- for (i = 0; i <= SND_MAX; i++) { /* Free malloc'd memory */
- if (pv[i].sval)
- free(pv[i].sval);
- }
- return(x);
-}
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
-/* D O X C O N N -- CONNECT command parsing with switches */
-
-#ifdef XLIMITS
-#define XLIMORTRIGGER
-#else
-#ifdef CK_TRIGGER
-#define XLIMORTRIGGER
-#endif /* CK_TRIGGER */
-#endif /* XLIMITS */
-
-#ifdef CKTIDLE
-int tt_idlelimit = 0; /* Terminal idle limit */
-int tt_idleact = IDLE_RET; /* Terminal idle action */
-#endif /* CKTIDLE */
-
-#ifdef OS2 /* K95 only: */
-extern int
- tt_idlesnd_tmo; /* Idle interval */
-int tt_timelimit = 0; /* Time limit, 0 = none */
-extern char * /* Parse results - strings: */
- tt_idlesnd_str; /* Idle string */
-#endif /* OS2 */
-
-#ifdef CK_TRIGGER
-extern char *tt_trigger[];
-extern CHAR *tt_trmatch[];
-extern char *triggerval;
-static char *g_tt_trigger[TRIGGERS];
-#endif /* CK_TRIGGER */
-
-#ifdef OS2
-static int g_tt_idlesnd_tmo, g_tt_timelimit; /* For saving and restoring */
-static int g_tt_idlelimit, g_tt_saved = 0;
-static char * g_tt_idlesnd_str; /* global settings */
-#endif /* OS2 */
-
-static struct stringint pv[CONN_MAX+1];
-
-VOID
-resconn() {
- int i;
-
-#ifdef OS2
- if ( g_tt_saved ) {
- tt_idlelimit = g_tt_idlelimit;
- tt_idlesnd_tmo = g_tt_idlesnd_tmo;
- tt_timelimit = g_tt_timelimit;
- tt_idlesnd_str = g_tt_idlesnd_str;
- g_tt_saved = 0;
- }
-#endif /* OS2 */
-
-#ifdef CK_TRIGGER
- for (i = 0; i < TRIGGERS; i++)
- tt_trigger[i] = g_tt_trigger[i];
-#endif /* CK_TRIGGER */
-
- for (i = 0; i <= CONN_MAX; i++) { /* Free malloc'd memory */
- if (pv[i].sval)
- free(pv[i].sval);
- pv[i].sval = NULL;
- }
-}
-
-int
-doxconn(cx) int cx; {
- int c, i, n; /* Workers */
- int x, y;
- int getval = 0; /* Whether to get switch value */
- int async = 0; /* Make an async connect */
- struct FDB sw, cm; /* FDBs for each parse function */
- extern FILE * tfile[];
- extern char * macp[];
-
-#ifdef OS2
- g_tt_idlesnd_tmo = tt_idlesnd_tmo; /* Save global settings */
- g_tt_timelimit = tt_timelimit;
- g_tt_idlelimit = tt_idlelimit;
- g_tt_idlesnd_str = tt_idlesnd_str;
- g_tt_saved = 1;
-#endif /* OS2 */
-
-#ifdef CK_TRIGGER
- if (!tt_trigger[0]) { /* First initialization */
- for (i = 1; i < TRIGGERS; i++)
- tt_trigger[i] = NULL;
- }
- for (i = 0; i < TRIGGERS; i++)
- g_tt_trigger[i] = tt_trigger[i];
- if (triggerval) {
- free(triggerval);
- triggerval = NULL;
- }
-#endif /* CK_TRIGGER */
-
- for (i = 0; i <= CONN_MAX; i++) { /* Initialize switch values */
- pv[i].sval = NULL; /* to null pointers */
- pv[i].ival = -1; /* and -1 int values */
- pv[i].wval = (CK_OFF_T)-1;
- }
- if (cx == XXCQ) /* CQ == CONNECT /QUIETLY */
- pv[CONN_NV].ival = 1;
-
- /* Set up chained parse functions... */
-
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nconntab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- conntab, /* Keyword table */
- &cm /* Pointer to next FDB */
- );
- cmfdbi(&cm, /* 2nd FDB - Confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
-
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse switch or confirmation */
- debug(F101,"doxconn cmfdb","",x);
- if (x < 0) { /* Error */
- if (x == -9 || x == -2)
- printf("?No switches match - \"%s\"\n",atmbuf);
- goto xconnx; /* or reparse needed */
- }
- if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
- break;
- c = cmgbrk(); /* Get break character */
- getval = (c == ':' || c == '='); /* to see how they ended the switch */
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- x = -9;
- goto xconnx;
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- n = cmresult.nresult; /* Numeric result = switch value */
- debug(F101,"doxconn switch","",n);
-
- switch (n) { /* Process the switch */
-#ifdef OS2
- case CONN_AS: /* Asynchronous */
- pv[CONN_AS].ival = 1;
- pv[CONN_SY].ival = 0;
- break;
- case CONN_SY: /* Synchronous */
- pv[CONN_SY].ival = 1;
- pv[CONN_AS].ival = 0;
- break;
-#endif /* OS2 */
- case CONN_NV: /* Non-verbal */
- pv[n].ival = 1;
- break;
-#ifdef XLIMITS
- case CONN_II: /* Idle-interval */
- case CONN_IL: /* Idle-limit */
- case CONN_TL: /* Time-limit */
- if (!getval) break;
- if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0)
- goto xconnx;
- pv[n].ival = y;
- break;
- case CONN_IS: /* Idle-string */
-#endif /* XLIMITS */
-#ifdef CK_TRIGGER
- case CONN_TS: /* Trigger-string */
-#endif /* CK_TRIGGER */
-#ifdef XLIMORTRIGGER
- if (!getval) break;
- if ((x = cmfld("String (enclose in braces if it contains spaces)",
- "",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?String required\n");
- x = -9;
- }
- goto xconnx;
- }
- if (n != CONN_TS)
- s = brstrip(s);
- if ((y = strlen(s)) > 0) {
- if (pv[n].sval) free(pv[n].sval);
- pv[n].sval = malloc(y+1);
- if (pv[n].sval) {
- strcpy(pv[n].sval,s); /* safe */
- pv[n].ival = 1;
- }
- }
- break;
-#endif /* XLIMORTRIGGER */
- default:
- printf("?Unexpected switch value - %d\n",cmresult.nresult);
- x = -9;
- goto xconnx;
- }
- }
- debug(F101,"doxconn cmresult.fcode","",cmresult.fcode);
- if (cmresult.fcode != _CMCFM) {
- printf("?Unexpected function code: %d\n",cmresult.fcode);
- x = -9;
- goto xconnx;
- }
-
- /* Command was confirmed so we can pre-pop command level. */
- /* This is so CONNECT module won't think we're executing a script */
- /* if CONNECT was the final command in the script. */
-
- if (cmdlvl > 0)
- prepop();
-
-#ifdef OS2 /* Make results available globally */
- if (pv[CONN_IL].ival > -1) /* Idle limit */
- tt_idlelimit = pv[CONN_IL].ival;
- if (pv[CONN_II].ival > -1) /* Idle limit */
- tt_idlesnd_tmo = pv[CONN_II].ival;
- if (pv[CONN_IS].sval) /* Idle string */
- if (tt_idlesnd_str = (char *)malloc((int)strlen(pv[CONN_IS].sval)+1))
- strcpy(tt_idlesnd_str,pv[CONN_IS].sval); /* safe */
- if (pv[CONN_TL].ival > -1) /* Session limit */
- tt_timelimit = pv[CONN_TL].ival;
- async = (pv[CONN_AS].ival > 0 ||
- pv[CONN_SY].ival <= 0 && cmdlvl == 0) ? 1 : 0;
-#endif /* OS2 */
-
-#ifdef CK_TRIGGER
- if (pv[CONN_TS].sval) /* Trigger strings */
- makelist(pv[CONN_TS].sval,tt_trigger,TRIGGERS);
- for (i = 0; i < TRIGGERS; i++) /* Trigger match pointers */
- tt_trmatch[i] = NULL;
- if (triggerval) { /* Reset trigger value */
- free(triggerval);
- triggerval = NULL;
- }
-#endif /* CK_TRIGGER */
-
-#ifdef SSHCMD
-/*
- 2010/03/01...
- The previous connection was through the external ssh client and now, with
- that connection closed, the user says "connect" and expects a new connection
- to be made to the same host, because that's how all the other connection
- methods work, so (and this is quite a hack)...
-*/
- if (!ckstrcmp("ssh ",ttname,4,0)) { /* Previous "host" was "ssh blah" */
- _PROTOTYP (int redossh, ( void ) );
- extern int ttyfd;
- if (ttyfd < 0) { /* And connection is no longer open */
- int xx;
- xx = redossh(); /* So redo the SSH connection */
- if (xx < 0) return(xx);
- goto xconnx;
- }
- }
-#endif /* SSHCMD */
- x = doconect((pv[CONN_NV].ival > 0) ? 1 : 0, async);
- {
- int xx;
- debug(F101,"doxconn doconect returns","",x);
- if ((xx = ttchk()) < 0) dologend();
- debug(F101,"doxconn ttchk returns","",xx);
- }
-
-#ifdef CK_TRIGGER
- debug(F111,"doxconn doconect triggerval",triggerval,x);
-#endif /* CK_TRIGGER */
-
- xconnx:
- /* Back from CONNECT -- Restore global settings */
-
- if (!async)
- resconn();
-
- success = (x > 0) ? 1 : 0;
- return(x);
-}
-#endif /* NOLOCAL */
-
-#ifdef ADDCMD
-/* cx == XXADD or XXREMV */
-/* fc == ADD_BIN or ADD_TXT */
-static int
-doadd(cx,fc) int cx, fc; {
-#ifdef PATTERNS
- char * tmp[FTPATTERNS];
- char **p = NULL;
- int i, j, k, n = 0, x = 0, last;
-
-#endif /* PATTERNS */
- if (cx != XXADD && cx != XXREMV) {
- printf("?Unexpected function code: %d\n",cx);
- return(-9);
- }
-#ifdef PATTERNS
- while (n < FTPATTERNS) { /* Collect new patterns */
- tmp[n] = NULL;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
- break;
- ckstrncpy(line,s,LINBUFSIZ);
- s = brstrip(line);
- makestr(&(tmp[n++]),s);
- }
- if (x == -3)
- x = cmcfm();
- if (x < 0)
- goto xdoadd;
- p = (fc == ADD_BIN) ? binpatterns : txtpatterns; /* Which list */
- last = 0;
- for (i = 0; i < FTPATTERNS; i++) { /* Find last one in list */
- if (!p[i]) {
- last = i;
- break;
- }
- }
- if (cx == XXADD) { /* Adding */
- if (last + n > FTPATTERNS) { /* Check if too many */
- printf("?Too many patterns - %d is the maximum\n", FTPATTERNS);
- goto xdoadd;
- }
- for (i = 0; i < n; i++) { /* Copy in the new ones. */
- for (j = 0, x = 0; x == 0 && j < last ; j++ )
- x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */
- if (x == 0)
- makestr(&(p[last++]),tmp[i]);
- }
- makestr(&(p[last]),NULL); /* Null-terminate the list */
- x = 1;
- goto xdoadd; /* Done */
- } else if (cx == XXREMV) { /* Remove something(s) */
- int j, k;
- if (last == 0) /* List is empty */
- goto xdoadd; /* Nothing to remove */
- for (i = 0; i < n; i++) { /* i = Patterns they typed */
- for (j = 0; j < last; j++) { /* j = Patterns in list */
- /* Change this to ckstrcmp()... */
- if (filecase)
- x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */
- else
- x = ckstrcmp(tmp[i],p[j],-1,0); /* Case-independent match */
- if (x) { /* This one matches */
- makestr(&(p[j]),NULL); /* Free it */
- for (k = j; k < last; k++) /* Move the rest up */
- p[k] = p[k+1];
- p[k] = NULL; /* Erase last one */
- if (!p[k])
- break;
- }
- }
- }
- }
- xdoadd: /* Common exit */
- for (i = 0; i < n; i++)
- if (tmp[i])
- free(tmp[i]);
- return(x);
-#endif /* PATTERNS */
-}
-
-/* ADD SEND-LIST */
-
-static int
-addsend(cx) int cx; {
-#ifndef NOMSEND
- extern struct keytab fttab[];
- extern int nfttyp;
- struct filelist * flp;
- char * fmode = "";
- int xmode = 0;
- int xbinary = 0;
-#endif /* NOMSEND */
-
-#ifdef NOMSEND
- printf("?Sorry, ADD/REMOVE SEND-LIST not available.\n");
- return(-9);
-#endif /* NOMSEND */
- if (cx == XXREMV) {
- printf("?Sorry, REMOVE SEND-LIST not implemented yet.\n");
- return(-9);
- }
-#ifndef NOMSEND
-#ifndef XYZ_INTERNAL
- if (protocol != PROTO_K) {
- printf("?Sorry, ADD SEND-LIST does not work with external protocols\n");
- return(-9);
- }
-#endif /* XYZ_INTERNAL */
-
- x = cmifi("File specification to add","", &s,&y,xxstring);
- if (x < 0) {
- if (x == -3) {
- printf("?A file specification is required\n");
- return(-9);
- } else
- return(x);
- }
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- s = tmpbuf;
- if (filesinlist == 0) /* Take care of \v(filespec) */
- fspec[0] = NUL;
- zfnqfp(s,LINBUFSIZ,line);
- s = line;
- if (((int)strlen(fspec) + (int)strlen(s) + 1) < fspeclen) {
- strcat(fspec,s); /* safe */
- strcat(fspec," "); /* safe */
- } else
- printf("WARNING - \\v(filespec) buffer overflow\n");
-
-
- xbinary = binary;
- if ((patterns || filepeek) /* FILE PATTERNS or SCAN is ON */
-#ifdef CK_LABELED
- && binary != XYFT_L /* And not if FILE TYPE LABELED */
-#endif /* CK_LABELED */
-#ifdef VMS
- && binary != XYFT_I /* or FILE TYPE IMAGE */
-#endif /* VMS */
- ) {
- int k, x;
- x = -1;
- k = scanfile(line,&x,nscanfile);
- if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
- }
- fmode = gfmode(xbinary,0);
- if ((x = cmkey(fttab,nfttyp,
- "type of file transfer", fmode, xxstring)) < 0)
- return(x);
- xmode = x;
-
- cmarg2 = "";
- if ((x = cmfld(y ?
- "\nAs-name template containing replacement variables such as \\v(filename)" :
- "Name to send it with", "",&s,NULL)) < 0)
- if (x != -3)
- return(x);
-#ifndef NOSPL
- if (y && *s) {
- char * p = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(s,&p,&x);
- if (!strcmp(tmpbuf,s)) {
- printf(
- "?As-name for file group must contain variables such as \\v(filename)\n"
- );
- return(-9);
- }
- }
-#endif /* NOSPL */
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- cmarg2 = tmpbuf;
-
- if ((x = cmcfm()) < 0)
- return(x);
- flp = (struct filelist *) malloc(sizeof(struct filelist));
- if (flp) {
- if (filetail)
- filetail->fl_next = flp;
- filetail = flp;
- if (!filehead)
- filehead = flp;
- x = (int) strlen(line); /* Length of filename */
- s = (char *) malloc(x + 1);
- if (s) {
- strcpy(s,line); /* safe */
- flp->fl_name = s;
- flp->fl_mode = xmode;
- x = (int) strlen(cmarg2); /* Length of as-name */
- if (x < 1) {
- flp->fl_alias = NULL;
- } else {
- s = (char *) malloc(x + 1);
- if (s) {
- strcpy(s,cmarg2); /* safe */
- flp->fl_alias = s;
- } else {
- printf("Sorry, can't allocate space for as-name");
- return(-9);
- }
- }
- flp->fl_next = NULL;
- filesinlist++; /* Count this node */
- return(success = 1); /* Finished adding this node */
- } else {
- printf("Sorry, can't allocate space for name");
- return(-9);
- }
- } else {
- printf("Sorry, can't allocate file list node");
- return(-9);
- }
-#endif /* NOMSEND */
-}
-#endif /* ADDCMD */
-
-#ifndef NOHTTP /* HTTP ops... */
-#ifdef TCPSOCKET
-#define HTTP_GET 0 /* GET */
-#define HTTP_PUT 1 /* PUT */
-#define HTTP_POS 2 /* POST */
-#define HTTP_IDX 3 /* INDEX */
-#define HTTP_HED 4 /* HEAD */
-#define HTTP_DEL 5 /* DELETE */
-#define HTTP_CON 6 /* CONNECT */
-#define HTTP_OPN 7 /* OPEN */
-#define HTTP_CLS 8 /* CLOSE */
-
-static struct keytab httptab[] = {
- { "close", HTTP_CLS, 0 },
- { "connect", HTTP_CON, 0 },
- { "delete", HTTP_DEL, 0 },
- { "get", HTTP_GET, 0 },
- { "head", HTTP_HED, 0 },
- { "index", HTTP_IDX, 0 },
- { "open", HTTP_OPN, 0 },
- { "put", HTTP_PUT, 0 },
- { "post", HTTP_POS, 0 }
-};
-static int nhttptab = sizeof(httptab)/sizeof(struct keytab);
-
-/* HTTP switches */
-#define HT_SW_AG 0 /* /AGENT */
-#define HT_SW_HD 1 /* /HEADER */
-#define HT_SW_US 2 /* /USER */
-#define HT_SW_PW 3 /* /PASSWORD */
-#define HT_SW_AR 4 /* /ARRAY */
-#define HT_SW_TP 5 /* /TOSCREEN */
-
-static struct keytab httpswtab[] = {
- { "/agent", HT_SW_AG, CM_ARG },
-#ifndef NOSPL
- { "/array", HT_SW_AR, CM_ARG },
-#endif /* NOSPL */
- { "/header", HT_SW_HD, CM_ARG },
- { "/password", HT_SW_PW, CM_ARG },
- { "/toscreen", HT_SW_TP, 0 },
- { "/user", HT_SW_US, CM_ARG },
- { "", 0, 0 }
-};
-static int nhttpswtab = sizeof(httpswtab)/sizeof(struct keytab) - 1;
-
-/* HTTP PUT/POST switches */
-#define HT_PP_MT 0 /* /MIME-TYPE */
-
-static struct keytab httpptab[] = {
- { "/mime-type", HT_PP_MT, CM_ARG },
- { "", 0, 0 }
-};
-static int nhttpptab = sizeof(httpptab)/sizeof(struct keytab) - 1;
-
-#define HTTP_MAXHDR 8
-
-static int
-xdohttp(action, lfile, rf, dfile, agent, hdr, user, pass, mime, array, type)
- int action;
- char *lfile, *rf, *dfile, *agent, *hdr, *user, *pass, *mime, array;
- int type;
-/* xdohttp */ {
- int i, rc = 0;
- char * hdrlist[HTTP_MAXHDR];
- char rfile[CKMAXPATH+1];
- extern int httpfd;
-
- /* Check for a valid state to execute the command */
- if (inserver) {
- printf("?The HTTP command may not be used from the IKS\r\n");
- } else if (httpfd == -1) {
- if (http_reopen() < 0)
- printf("?No connection\n");
- else
- rc = 1;
- } else {
- rc = 1;
- }
-
- /* If the command is not valid, exit with failure */
- if (rc == 0)
- return(success = 0);
-
- if (action != HTTP_CON && rf[0] != '/') {
- rfile[0] = '/';
- ckstrncpy(&rfile[1],rf,CKMAXPATH);
- } else {
- ckstrncpy(rfile,rf,CKMAXPATH);
- }
- for (i = 0; i < HTTP_MAXHDR; i++) /* Initialize header list */
- hdrlist[i] = NULL;
- makelist(hdr,hdrlist,HTTP_MAXHDR); /* Make header list */
-
-#ifdef BETADEBUG
- for (i = 0; i < nhttptab; i++) /* Find action keyword */
- if (httptab[i].kwval == action)
- break;
- if (i == nhttptab) { /* Shouldn't happen... */
- printf("?Invalid action - %d\n",action);
- return(0); /* Failure */
- }
-
- printf("HTTP action: %s\n",httptab[i].kwd);
- printf(" Agent: %s\n",agent ? agent : "(null)");
-
- if (hdrlist[1]) {
- printf(" Header list: 1. %s\n",hdrlist[0]);
- for (i = 1; i < HTTP_MAXHDR && hdrlist[i]; i++)
- printf("%15d. %s\n",i+1,hdrlist[i]);
- } else
- printf(" Header: %s\n",hdrlist[0] ? hdrlist[0] : "(null)");
-
- printf(" User: %s\n",user ? user : "(null)");
-#ifdef COMMENT
- printf(" Password: %s\n",pass ? pass : "(null)");
-#endif /* COMMENT */
-
-#ifndef NOSPL
- if (array)
- printf(" Array: \\%%%c[]\n", array);
- else
- printf(" Array: (none)\n");
-#endif /* NOSPL */
-
- if (action == HTTP_PUT || action == HTTP_POS)
- printf(" Mime-type: %s\n",mime ? mime : "(null)");
-
- printf(" Local file: %s\n",lfile ? lfile : "(null)");
- printf(" Remote file: %s\n",rfile ? rfile : "(null)");
- printf(" Destination file: %s\n",dfile ? dfile : "(null)");
-#endif /* BETADEBUG */
-
- /* The http_xxxx() functions return 0 on success, -1 on failure */
- switch (action) {
- case HTTP_CON: {
- extern int ttyfd;
- rc = http_connect(httpfd,agent,hdrlist,user,pass,array,rfile);
- break;
- }
- case HTTP_DEL:
- rc = http_delete(agent,hdrlist,user,pass,array,rfile);
- break;
- case HTTP_GET:
- rc = http_get(agent,hdrlist,user,pass,array,lfile,rfile,type);
- break;
- case HTTP_HED:
- rc = http_head(agent,hdrlist,user,pass,array,lfile,rfile,type);
- break;
- case HTTP_PUT:
- rc = http_put(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
- type);
- break;
- case HTTP_POS:
- rc = http_post(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
- type);
- break;
- case HTTP_IDX:
- rc = http_index(agent,hdrlist,user,pass,array,lfile,rfile,type);
- break;
- default:
- rc = -1;
- }
- return(rc == 0 ? 1 : 0); /* Success is set by caller */
-}
-#endif /* TCPSOCKET */
-#endif /* NOHTTP */
-
-#ifndef NOSPL /* ARRAY ops... */
-static struct keytab arraytab[] = {
- { "clear", ARR_CLR, 0 },
- { "copy", ARR_CPY, 0 },
- { "dcl", ARR_DCL, CM_INV },
- { "declare", ARR_DCL, 0 },
- { "destroy", ARR_DST, CM_INV },
- { "equate", ARR_EQU, CM_INV },
- { "link", ARR_EQU, 0 },
- { "resize", ARR_RSZ, 0 },
- { "set", ARR_SET, 0 },
-#ifndef NOSHOW
- { "show", ARR_SHO, 0 },
-#endif /* NOSHOW */
- { "sort", ARR_SRT, 0 },
- { "undeclare", ARR_DST, 0 },
- { "", 0, 0 }
-};
-static int narraytab = sizeof(arraytab)/sizeof(struct keytab) - 1;
-
-#ifdef CKLEARN
-static struct keytab learnswi[] = {
- { "/close", 2, 0 },
- { "/off", 0, 0 },
- { "/on", 1, 0 }
-};
-#endif /* CKLEARN */
-
-int
-arrayitoa(x) int x; { /* Array index to array letter */
- if (x == 1)
- return(64);
- else if (x < 0 || x > (122 - ARRAYBASE))
- return(-1);
- else
- return(x + ARRAYBASE);
-}
-
-int
-arrayatoi(c) int c; { /* Array letter to array index */
- if (c == 64)
- c = 96;
- if (c > 63 && c < 91)
- c += 32;
- if (c < ARRAYBASE || c > 122)
- return(-1);
- return(c - ARRAYBASE);
-}
-
-static int /* Declare an array */
-dodcl(cx) int cx; {
- int i, n, v, lo, hi, rc = 0;
- int isdynamic = 0;
- char tmpbuf[64];
- char ** p = NULL;
- char tmp[64]; /* Local temporary string buffer */
- if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
- if (y == -3) {
- printf("?Array name required\n");
- return(-9);
- } else return(y);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- x = arraybounds(s,&lo,&hi); /* Check syntax and get bounds */
- debug(F111,"dodcl arraybounds",s,x);
- if (x < 0) { /* Error - Maybe it's a variable */
- char * p; /* whose value is an array name */
- int n;
- p = tmpbuf;
- n = 63;
- p[0] = NUL;
- if (s[0] == CMDQ && s[1] == '&')
- s++;
- if (zzstring(s,&p,&n) > -1) {
- s = tmpbuf;
- x = arraybounds(s,&lo,&hi);
- debug(F111,"dodcl arraybounds 2",s,x);
- }
- if (x < 0) {
- printf("?Bad array name - \"%s\"\n",s);
- return(-9);
- }
- }
- debug(F101,"dodcl hi","",hi);
- debug(F101,"dodcl lo","",lo);
- debug(F101,"dodcl lo+1","",lo+1);
-
- if (lo == -1 && hi == -1) { /* Have good array name and bounds */
- isdynamic = 1;
- n = CMDBL / 5;
- } else if (hi > -1) {
- printf("?Segment notation not allowed in array declarations\n");
- return(-9);
- } else if ((lo+1) < 0) {
- debug(F101,"dodcl underflow","",lo+1);
- printf("?Dimension underflow\n");
- return(-9);
- } else
- n = lo;
- x = arrayitoa(x);
- if (cx == XXUNDCL) {
- n = 0;
- v = 0;
- if ((y = cmcfm()) < 0)
- return(y);
- } else {
- p = (char **)malloc(sizeof(char **)*(n+1));
- if (!p) {
- printf("?Memory allocation error\n");
- return(-9);
- }
- v = 0; /* Highest initialized member */
- p[0] = NULL; /* Element 0 */
- keepallchars = 1;
- while (n > 0 && v < n) { /* Parse initializers */
- p[v+1] = NULL;
- ckmakxmsg(tmp,
- 64,
- "Initial value for \\&",
- ckctoa((char)x),
- "[",
- ckitoa(v+1),
- "]",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
-
- rc = cmfld((char *)tmp,"",&s,xxstring); /* Get field */
- if (rc < 0) { /* Error... */
- if (rc == -3) { /* Empty element */
- if (cmflgs == 1) /* because end of line? */
- break; /* Yes, done initializing */
- else /* No, it's just empty */
- continue; /* Go on to next one. */
- } else { /* Other parse error */
- goto dclx; /* Go free temp pointers */
- }
- }
- rc = 1;
- if (v == 0 && !strcmp(s,"=")) /* Skip the = sign. */
- continue;
- s = brstrip(s); /* Strip any braces */
- makestr(&(p[++v]),s);
- }
- keepallchars = 0;
- if ((y = cmtxt("Carriage return to confirm","",&s,NULL)) < 0)
- return(y);
- if (isdynamic)
- n = v;
- }
- if (dclarray((char)x,n) < 0) { /* Declare the array */
- printf("?Declare failed\n");
- goto dclx;
- }
- for (i = 1; i <= v; i++) { /* Add any initial values */
- tmp[0] = '&';
- ckmakmsg(&tmp[1],63,ckctoa((char)x),"[",ckitoa(i),"]");
- if (addmac(tmp,p[i]) < 0) {
- printf("Array initialization error: %s %s\n",tmp,p[i]);
- rc = -9;
- goto dclx;
- }
- }
- dclx:
- if (p) {
- for (i = 1; i <= v; i++)
- if (p[i]) free(p[i]);
- free((char *)p);
- }
- debug(F101,"DCL rc","",rc);
- return(success = rc);
-}
-
-static int
-rszarray() {
- int i, x, y, n, lo, hi, islink = -1;
- char c, * s, ** ap = NULL;
- if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
- if (x == -3) {
- printf("?Array name required\n");
- return(-9);
- } else return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */
- s = line;
- x = arraybounds(s,&lo,&hi);
- if (x < 0) { /* Parse the name, get index */
- printf("?Bad array reference - \"%s\"\n", s);
- return(-9);
- }
- if (lo < 0 && hi < 0) {
- y = cmnum("New size","",10,&lo,xxstring);
- if (y < 0) {
- if (y == -3)
- printf("?New size required\n");
- return(y);
- }
- }
- if ((y = cmcfm()) < 0)
- return(y);
- if (a_link[x] > -1) { /* Link? */
- islink = x; /* Yes follow it */
- x = a_link[x]; /* and remember */
- }
- if (!a_ptr[x]) {
- printf("?Array not declared - \"%s\"\n", s);
- return(-9);
- }
- if (lo < 0) {
- printf("?New size required\n");
- return(-9);
- }
- if (hi > -1) {
- printf("?Array segments not allowed for this operation\n");
- return(-9);
- }
- c = arrayitoa(x); /* Get array letter */
- if (c == '@') { /* Argument vector array off limits */
- printf("?Sorry, \\&@[] is read-only\n");
- return(-9);
- }
- if (lo == 0) { /* If new size is 0... */
- dclarray(c,0); /* Undeclare the array */
- return(success = 1);
- }
- n = a_dim[x]; /* Current size */
- ap = (char **) malloc((lo+1) * sizeof(char *)); /* New array */
- y = (n < lo) ? n : lo;
- for (i = 0; i <= y; i++) /* Copy the part that fits */
- ap[i] = a_ptr[x][i];
- if (n < lo) { /* If original array smaller */
- for (; i <= lo; i++) /* initialize extra elements in */
- ap[i] = NULL; /* new array to NULL. */
- } else if (n > lo) { /* If new array smaller */
- for (; i <= lo; i++) /* deallocate leftover elements */
- makestr(&(a_ptr[x][i]),NULL); /* from original array. */
- }
- free((char *)a_ptr[x]); /* Free original array list */
- a_ptr[x] = ap; /* Replace with new one */
- a_dim[x] = lo; /* Record the new dimension */
- if (islink > -1) { /* Was this a link? */
- a_ptr[islink] = ap; /* If so point to the resized array */
- a_dim[islink] = lo;
- } else { /* If not are there links to here? */
- for (i = 0; i < (int) 'z' - ARRAYBASE; i++) { /* Any linked arrays? */
- if (i != x && a_link[i] == x) { /* Find and update them */
- a_ptr[i] = ap;
- a_dim[i] = lo;
- }
- }
- }
- return(success = 1);
-}
-
-static int
-copyarray() {
- int i, j, x1, lo1, hi1, x2, lo2, hi2, whole = 0;
- char c1, c2, * a1, * a2;
- if ((y = cmfld("Name of source array","",&s,NULL)) < 0)
- return(y);
- ckstrncpy(line,s,LINBUFSIZ);
- a1 = line;
- if ((x1 = arraybounds(a1,&lo1,&hi1)) < 0) {
- printf("?Bad array reference - \"%s\"\n", a1);
- return(-9);
- } else if (!a_ptr[x1]) {
- printf("?Array not declared - \"%s\"\n", a1);
- return(-9);
- }
- c1 = arrayitoa(x1);
-
- if ((y = cmfld("Name of destination array","",&s,NULL)) < 0)
- return(y);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- a2 = tmpbuf;
- if ((x2 = arraybounds(a2,&lo2,&hi2)) < 0) {
- printf("?Bad array reference - \"%s\"\n", a2);
- return(-9);
- }
- c2 = arrayitoa(x2);
-
- if ((x = cmcfm()) < 0)
- return(x);
-
- if (c2 == '@') { /* Argument vector array off limits */
- printf("?Sorry, \\&@[] is read-only\n");
- return(-9);
- }
- if (lo1 < 0 && lo2 < 0 && hi1 < 0 && hi2 < 0) /* Special case for */
- whole = 1; /* whole array... */
-
- if (lo1 < 0) lo1 = whole ? 0 : 1; /* Supply lower bound of source */
- if (hi1 < 0) hi1 = a_dim[x1]; /* Supply upper bound of source */
- if (lo2 < 0) lo2 = whole ? 0 : 1; /* Lower bound of target */
- if (hi2 < 0) hi2 = lo2 + hi1 - lo1; /* Upper bound of target */
- if (a_ptr[x2]) { /* Target array is already declared? */
- if (hi2 > a_dim[x2]) /* If upper bound out of range */
- hi2 = a_dim[x2]; /* shrink to fit */
- } else { /* Otherwise... */
- x2 = dclarray(c2, hi2); /* declare the target array */
- }
- for (i = lo1, j = lo2; i <= hi1 && j <= hi2; i++,j++) { /* Copy */
- makestr(&(a_ptr[x2][j]),a_ptr[x1][i]);
- }
- return(success = 1);
-}
-
-static int /* Undeclare an array */
-unarray() {
- int x, y, n, rc = 0;
- char c, * s;
-
- if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
- if (y == -3) {
- printf("?Array name required\n");
- return(-9);
- } else return(y);
- }
- ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */
- s = line;
- if ((y = cmcfm()) < 0)
- return(y);
- if ((x = arraybounds(s,&y,&n)) < 0) { /* Parse the name, get index */
- printf("?Bad array reference - \"%s\"\n", s);
- return(-9);
- }
- if (y > 0 || n > 0) {
- printf("?Partial arrays can not be destroyed\n");
- return(-9);
- }
- c = arrayitoa(x); /* Get array letter */
- if (a_ptr[x]) { /* If array is declared */
- if (c == '@') { /* Argument vector array off limits */
- printf("?Sorry, \\&@[] is read-only\n");
- return(-9);
- }
- rc = dclarray(c,-1); /* Undeclare the array */
- } else /* It wasn't declared */
- rc = 1;
- if (rc > -1) { /* Set return code and success */
- success = 1;
- rc = 1;
- } else {
- success = 0;
- printf("?Failed - destroy \"\\&%c[]\"\n", c);
- rc = -9;
- }
- return(rc);
-}
-
-static int
-clrarray(cx) int cx; {
- int i, x, lo, hi;
- char c, * s, * val = NULL;
-
- if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
- if (x == -3) {
- printf("?Array name required\n");
- return(-9);
- } else return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */
- s = line;
- if (cx == ARR_SET) { /* SET */
- if ((x = cmtxt("Value","",&val,xxstring)) < 0)
- return(x);
- ckstrncpy(tmpbuf,val,TMPBUFSIZ); /* Value to set */
- val = tmpbuf;
- if (!*val) val = NULL;
- } else if ((x = cmcfm()) < 0) /* CLEAR */
- return(x);
-
- if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the name */
- printf("?Bad array reference - \"%s\"\n", s);
- return(-9);
- }
- c = arrayitoa(x); /* Get array letter */
- if (!a_ptr[x]) { /* If array is declared */
- printf("?Array %s is not declared\n", s);
- return(-9);
- } else if (c == '@') { /* Argument vector array off limits */
- printf("?Sorry, \\&@[] is read-only\n");
- return(-9);
- }
- if (lo < 0) lo = 0;
- if (hi < 0) hi = a_dim[x];
- for (i = lo; i <= hi; i++) /* Clear/Set selected range */
- makestr(&(a_ptr[x][i]),val);
-
- return(success = 1);
-}
-
-extern char **aa_ptr[CMDSTKL][28];
-extern int aa_dim[CMDSTKL][28];
-
-static int /* Create symbolic link to an array */
-linkarray() {
- int i = 0, x, y, lo, hi, flag = 0;
- char c, * s, * p;
-
- if ((x = cmfld("Array name not currently in use","",&s,NULL)) < 0) {
- if (x == -3) {
- printf("?Array name required\n");
- return(-9);
- } else return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of link name */
- s = line;
- if ((x = cmfld("Name of existing array","",&p,xxstring)) < 0) {
- if (x == -3) {
- printf("?Array name required\n");
- return(-9);
- } else return(x);
- }
- ckstrncpy(tmpbuf,p,TMPBUFSIZ); /* Make safe copy of array name */
- p = tmpbuf;
- if ((x = cmcfm()) < 0)
- return(x);
-
- if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the link name */
- printf("?Bad array reference - \"%s\"\n", s);
- return(-9);
- }
- if (a_ptr[x]) { /* Must not already exist */
- c = arrayitoa(x);
- printf("?Array already exists: \\&%c[]\n", c);
- return(-9);
- }
- if (lo > -1 || hi > -1) {
- printf("?Sorry, whole arrays only: %s\n",s);
- return(-9);
- }
- if ((y = arraybounds(p,&lo,&hi)) < 0) { /* Parse the array name */
- printf("?Bad array reference - \"%s\"\n", s);
- return(-9);
- }
- if (lo > -1 || hi > -1) {
- printf("?Sorry, whole arrays only: %s\n",p);
- return(-9);
- }
- if (x == y) {
- for (i = cmdlvl; i >= 0; i--)
- if (aa_ptr[i][x]) {
- flag++;
- break;
- }
- }
- if (flag) {
- a_ptr[x] = aa_ptr[i][y]; /* Link to saved copy */
- a_dim[x] = aa_dim[i][y];
- } else { /* Otherwise... */
- c = arrayitoa(y); /* Check if it's declared */
- if (!a_ptr[y]) {
- printf("?Array is not declared: \\&%c[]\n", c);
- return(-9);
- }
- if (a_link[y] > -1) { /* And if it's a link itself */
- printf("?Links to links not allowed: \\&%c[]\n", c);
- return(-9);
- }
- a_ptr[x] = a_ptr[y]; /* All OK, make the link */
- a_dim[x] = a_dim[y];
- }
- a_link[x] = y;
- return(success = 1);
-}
-#endif /* NOSPL */
-
-#ifndef NOCSETS
-static char * dcsetname = NULL;
-
-/* Get Display Character-Set Name */
-
-char *
-getdcset() {
- char * s;
- int y;
-#ifdef PCFONTS
- extern int tt_font, ntermfont;
- extern struct keytab term_font[];
-#endif /* PCFONTS */
-
- s = "";
-#ifdef OS2
- y = os2getcp(); /* Default is current code page */
- switch (y) {
- case 437: s = "cp437"; break;
- case 850: s = "cp850"; break;
- case 852: s = "cp852"; break;
- case 857: s = "cp857"; break;
- case 858: s = "cp858"; break;
- case 862: s = "cp862"; break;
- case 866: s = "cp866"; break;
- case 869: s = "cp869"; break;
- case 1250: s = "cp1250"; break;
- case 1251: s = "cp1251"; break;
- case 1252: s = "cp1252"; break;
- case 1253: s = "cp1253"; break;
- case 1254: s = "cp1254"; break;
- case 1255: s = "cp1255"; break;
- case 1256: s = "cp1256"; break;
- case 1257: s = "cp1257"; break;
- case 1258: s = "cp1258"; break;
- }
-#ifdef PCFONTS
-/*
- If the user has loaded a font with SET TERMINAL FONT then we want
- to change the default code page to the font that was loaded.
-*/
- if (tt_font != TTF_ROM) {
- for (y = 0; y < ntermfont; y++ ) {
- if (term_font[y].kwval == tt_font) {
- s = term_font[y].kwd;
- break;
- }
- }
- }
-#endif /* PCFONTS */
-#else /* OS2 */
-#ifdef COMMENT
- /* Hack not needed as of C-Kermit 7.1 */
- if (fcharset == FC_1LATIN) {
- s = "latin1-iso"; /* Hack to avoid reporting "cp1252" */
- } else { /* Report current file character set */
-#endif /* COMMENT */
- for (y = 0; y <= nfilc; y++)
- if (fcstab[y].kwval == fcharset) {
- s = fcstab[y].kwd;
- break;
- }
-#ifdef COMMENT
- }
-#endif /* COMMENT */
-#endif /* OS2 */
- makestr(&dcsetname,s); /* Return stable pointer */
- return((char *)dcsetname);
-}
-#endif /* NOCSETS */
-
-#ifndef NOFRILLS
-static int
-doclear() {
- if ((x = cmkey(clrtab,nclear,"item to clear",
-#ifdef NOSPL
- "device-buffer"
-#else
- "device-and-input"
-#endif /* NOSPL */
- ,xxstring)) < 0) return(x);
-#ifndef NOSPL
-#ifdef OS2
- if (x == CLR_CMD || x == CLR_TRM) {
- if ((z = cmkey(clrcmdtab,nclrcmd,"how much screen to clear\n",
- "all",xxstring)) < 0)
- return(z);
- }
-#endif /* OS2 */
-#endif /* NOSPL */
- if ((y = cmcfm()) < 0)
- return(y);
-
- /* Clear device input buffer if requested */
- y = (x & CLR_DEV) ? ttflui() : 0;
-
- if (x & CLR_SCR) /* CLEAR SCREEN */
- y = ck_cls(); /* (= SCREEN CLEAR = CLS) */
-
- if (x & CLR_KBD) { /* CLEAR KEYBOARD */
- int n;
- n = conchk();
- y = 0;
- while (n-- > 0 && (y = coninc(0) > -1))
- ;
- y = (y > -1) ? 0 : -1;
- }
-
-#ifndef NOSPL
- /* Clear INPUT command buffer if requested */
- if (x & CLR_INP) {
- for (z = 0; z < inbufsize; z++)
- inpbuf[z] = NUL;
- inpbp = inpbuf;
- y = 0;
- }
-#ifdef CK_APC
- if (x & CLR_APC) {
- debug(F101,"Executing CLEAR APC","",apcactive);
- apcactive = 0;
- y = 0;
- }
-#endif /* CK_APC */
- if (x & CLR_ALR) {
- setalarm(0L);
- y = 0;
- }
-#endif /* NOSPL */
-
-#ifdef PATTERNS
- if (x & (CLR_TXT|CLR_BIN)) {
- int i;
- for (i = 0; i < FTPATTERNS; i++) {
- if (x & CLR_TXT)
- makestr(&txtpatterns[i],NULL);
- if (x & CLR_BIN)
- makestr(&binpatterns[i],NULL);
- }
- y = 0;
- }
-#endif /* PATTERNS */
-
-#ifndef NODIAL
- if (x & CLR_DIA) {
- dialsta = DIA_UNK;
- y = 0;
- }
-#endif /* NODIAL */
-
-#ifndef NOMSEND
- if (x & CLR_SFL) { /* CLEAR SEND-LIST */
- if (filehead) {
- struct filelist * flp, * next;
- flp = filehead;
- while (flp) {
- if (flp->fl_name)
- free(flp->fl_name);
- if (flp->fl_alias)
- free(flp->fl_alias);
- next = flp->fl_next;
- free((char *)flp);
- flp = next;
- }
- }
- filesinlist = 0;
- filehead = NULL;
- filetail = NULL;
- addlist = 0;
- y = 0;
- }
-#endif /* NOMSEND */
-
-#ifdef OS2
-#ifndef NOLOCAL
- switch (x) {
- case CLR_SCL:
- clearscrollback(VTERM);
- break;
- case CLR_CMD:
- switch ( z ) {
- case CLR_C_ALL:
- clear();
- break;
- case CLR_C_BOS:
- clrboscr_escape(VCMD,SP);
- break;
- case CLR_C_BOL:
- clrbol_escape(VCMD,SP);
- break;
- case CLR_C_EOL:
- clrtoeoln(VCMD,SP);
- break;
- case CLR_C_EOS:
- clreoscr_escape(VCMD,SP);
- break;
- case CLR_C_LIN:
- clrline_escape(VCMD,SP);
- break;
- case CLR_C_SCR:
- clearscrollback(VCMD);
- break;
- default:
- printf("Not implemented yet, sorry.\n");
- break;
- }
- break;
-
-#ifndef NOTERM
- case CLR_TRM:
- switch ( z ) {
- case CLR_C_ALL:
- if (VscrnGetBufferSize(VTERM) > 0 ) {
- VscrnScroll(VTERM, UPWARD, 0,
- VscrnGetHeight(VTERM)-(tt_status[VTERM]?2:1),
- VscrnGetHeight(VTERM) -
- (tt_status[VTERM]?1:0), TRUE, SP
- );
- cleartermscreen(VTERM);
- }
- break;
- case CLR_C_BOS:
- clrboscr_escape(VTERM,SP);
- break;
- case CLR_C_BOL:
- clrbol_escape(VTERM,SP);
- break;
- case CLR_C_EOL:
- clrtoeoln(VTERM,SP);
- break;
- case CLR_C_EOS:
- clreoscr_escape(VTERM,SP);
- break;
- case CLR_C_LIN:
- clrline_escape(VTERM,SP);
- break;
- case CLR_C_SCR:
- clearscrollback(VTERM);
- break;
- default:
- printf("Not implemented yet, sorry.\n");
- break;
- }
- break;
-#endif /* NOTERM */
- }
- y = 0;
-#endif /* NOLOCAL */
-#endif /* OS2 */
- return(success = (y == 0));
-}
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
-static int
-doeval(cx) int cx; {
- char *p;
- char vnambuf[VNAML], * vnp = NULL; /* These must be on the stack */
- if (!oldeval) {
- if ((y = cmfld("Variable name","",&s,
- ((cx == XX_EVAL) ? xxstring : NULL))) < 0) {
- if (y == -3) {
- printf("?Variable name required\n");
- return(-9);
- } else return(y);
- }
- ckstrncpy(vnambuf,s,VNAML); /* Make a copy. */
- vnp = vnambuf;
- if (vnambuf[0] == CMDQ &&
- (vnambuf[1] == '%' || vnambuf[1] == '&'))
- vnp++;
- y = 0;
- if (*vnp == '%' || *vnp == '&') {
- if ((y = parsevar(vnp,&x,&z)) < 0)
- return(y);
- }
- }
- if ((x = cmtxt("Integer arithmetic expression","",&s,xxstring)) < 0)
- return(x);
- p = evala(s);
- if (!p) p = "";
- if (oldeval && *p)
- printf("%s\n", p);
- ckstrncpy(evalbuf,p,32);
- if (!oldeval)
- return(success = addmac(vnambuf,p));
- else
- return(success = *p ? 1 : 0);
-}
-#endif /* NOSPL */
-
-#ifdef TNCODE
-static int
-dotelopt() {
- if ((x = cmkey(telcmd, ntelcmd, "TELNET command", "", xxstring)) < 0 )
- return(x);
- switch (x) {
- case WILL:
- case WONT:
- case DO:
- case DONT:
- if ((y = cmkey(tnopts,ntnopts,"TELNET option","",xxstring)) < 0)
- return(y);
- if ((z = cmcfm()) < 0) return(z);
-
- switch (x) {
- case WILL:
- if (TELOPT_UNANSWERED_WILL(y))
- return(success = 0);
- break;
- case WONT:
- if (TELOPT_UNANSWERED_WONT(y))
- return(success = 0);
- break;
- case DO:
- if (TELOPT_UNANSWERED_DO(y))
- return(success = 0);
- break;
- case DONT:
- if (TELOPT_UNANSWERED_DONT(y))
- return(success = 0);
- break;
- }
- if (local) {
- success = ((tn_sopt(x,y) > -1) ? 1 : 0);
- } else {
- printf("ff%02x%02x\n",x,y);
- success = 1;
- }
- if (success) {
- switch (x) {
- case WILL:
- TELOPT_UNANSWERED_WILL(y) = 1;
- break;
- case WONT:
- if ( TELOPT_ME(y) )
- TELOPT_UNANSWERED_WONT(y) = 1;
- break;
- case DO:
- TELOPT_UNANSWERED_DO(y) = 1;
- break;
- case DONT:
- if ( TELOPT_ME(y) )
- TELOPT_UNANSWERED_DONT(y) = 1;
- break;
- }
- if (tn_wait("XXTELOP") < 0) {
- tn_push();
- success = 0;
- }
- }
- return(success);
- case SB:
- if ((y=cmkey(tnsbopts,ntnsbopts,"TELNET option","",xxstring)) < 0)
- return(y);
- switch (y) {
- case TELOPT_NAWS:
- /* Some compilers require switch() to have at least 1 case */
-#ifdef CK_NAWS
- TELOPT_SB(TELOPT_NAWS).naws.x = 0;
- TELOPT_SB(TELOPT_NAWS).naws.y = 0;
- if (local)
- return(success = ((tn_snaws() > -1) ? 1 : 0));
- else
- return(success = 0);
-#else
- return(success = 0);
-#endif /* CK_NAWS */
- }
- return(success = 0);
-
-#ifdef CK_KERBEROS
-#ifdef KRB5
- case TN_FWD:
- success = (kerberos5_forward() == AUTH_SUCCESS);
- return(success);
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
- default:
- if ((z = cmcfm()) < 0) return(z);
-#ifndef NOLOCAL
- if (local) {
- CHAR temp[3];
- if (network && IS_TELNET()) { /* TELNET */
- temp[0] = (CHAR) IAC;
- temp[1] = x;
- temp[2] = NUL;
- success = (ttol((CHAR *)temp,2) > -1 ? 1 : 0);
- if (tn_deb || debses || deblog) {
- /* TN_MSG_LEN is in ckctel.h */
- ckmakmsg(tn_msg,256,"TELNET SENT ",TELCMD(x),NULL,NULL);
- debug(F101,tn_msg,"",x);
- if (debses || tn_deb) tn_debug(tn_msg);
- }
- return(success);
- }
- return(success = 0);
- } else {
-#endif /* NOLOCAL */
- printf("ff%02x\n",x);
- return(success = 1);
-#ifndef NOLOCAL
- }
-#endif /* NOLOCAL */
- }
-}
-#endif /* TNCODE */
-
-
-#ifndef NOPUSH
-#ifndef NOFRILLS
-static int
-doedit() {
-#ifdef OS2
- char * p = NULL;
-#endif /* OS2 */
- if (!editor[0]) {
- s = getenv("EDITOR");
- if (s) ckstrncpy(editor,s,CKMAXPATH);
- editor[CKMAXPATH] = NUL;
- if (!editor[0]) {
- printf("?Editor not defined - use SET EDITOR to define\n");
- return(-9);
- }
- }
- ckstrncpy(tmpbuf,editfile,TMPBUFSIZ);
-/*
- cmiofi() lets us parse the name of an existing file, or the name of
- a nonexistent file to be created.
-*/
- x = cmiofi("File to edit", (char *)tmpbuf, &s, &y, xxstring);
- debug(F111,"edit",s,x);
- if (x < 0 && x != -3)
- return(x);
- if (x == -3) {
- tmpbuf[0] = NUL;
- } else {
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- }
- if ((z = cmcfm()) < 0) return(z);
- if (y) {
- printf("?A single file please\n");
- return(-9);
- }
- if (nopush) {
- printf("?Sorry, editing not allowed\n");
- return(success = 0);
- }
- if (tmpbuf[0]) {
- /* Get full path in case we change directories between EDIT commands */
- zfnqfp(tmpbuf, CKMAXPATH, editfile);
- editfile[CKMAXPATH] = NUL;
-#ifdef OS2
- p = editfile; /* Flip the stupid slashes */
- while (*p) {
- if (*p == '/') *p = '\\';
- p++;
- }
-#endif /* OS2 */
- } else
- editfile[0] = NUL;
- if (editfile[0]) {
- if (zchki(editfile) < (CK_OFF_T)0 && zchko(editfile) < 0) {
- printf("?Access denied: %s\n",editfile);
- return(-9);
- }
- }
- x = 0;
- if (editopts[0]) {
-#ifdef OS2
- x = ckindex("%1",(char *)editopts,0,0,1);
- if (x > 0)
- editopts[x] = 's';
- else
-#endif /* OS2 */
- x = ckindex("%s",(char *)editopts,0,0,1);
- }
- if (((int)strlen(editopts) + (int)strlen(editfile) + 1) < TMPBUFSIZ) {
- if (x)
- sprintf(tmpbuf,editopts,editfile);
- else
- sprintf(tmpbuf,"%s %s",editopts,editfile);
- }
- s = line;
- ckmakmsg(s,LINBUFSIZ,editor," ",tmpbuf,NULL);
-#ifdef OS2
- p = s + strlen(editor); /* And again with the slashes */
- while (p != s) {
- if (*p == '/') *p = '\\';
- p--;
- }
-#endif /* OS2 */
- conres();
- x = zshcmd(s);
- concb((char)escape);
- return(x);
-}
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-
-#ifdef BROWSER
-static int
-dobrowse() {
-#ifdef OS2
- char * p = NULL;
-#endif /* OS2 */
- if (nopush) {
- printf("?Sorry, browsing not allowed\n");
- return(success = 0);
- }
-#ifndef NT
- /* Windows lets the Shell Execute the URL if no Browser is defined */
- if (!browser[0]) {
- s = getenv("BROWSER");
- if (s) ckstrncpy(browser,s,CKMAXPATH);
- browser[CKMAXPATH] = NUL;
- if (!browser[0]) {
- printf("?Browser not defined - use SET BROWSER to define\n");
- return(-9);
- }
- }
-#endif /* NT */
- ckstrncpy(tmpbuf,browsurl,TMPBUFSIZ);
- if ((x = cmtxt("URL",(char *)browsurl,&s,xxstring)) < 0)
- return(x);
- ckstrncpy(browsurl,s,4096);
- x = 0;
- if (browsopts[0]) {
-#ifdef OS2
- x = ckindex("%1",(char *)browsopts,0,0,1);
- if (x > 0)
- browsopts[x] = 's';
- else
-#endif /* OS2 */
- x = ckindex("%s",(char *)browsopts,0,0,1);
- }
- if (((int)strlen(browsopts) + (int)strlen(browsurl) + 1) < TMPBUFSIZ) {
- if (x)
- sprintf(tmpbuf,browsopts,browsurl);
- else
- sprintf(tmpbuf,"%s %s",browsopts,browsurl);
- }
-#ifdef NT
- if (!browser[0])
- return(success = Win32ShellExecute(browsurl));
-#endif /* NT */
- s = line;
- ckmakmsg(s,LINBUFSIZ,browser," ",tmpbuf,NULL);
-#ifdef OS2
- p = line + strlen(browser); /* Flip slashes */
- while (p != line) {
- if (*p == '/') *p = '\\';
- p--;
- }
-#endif /* OS2 */
- conres();
- x = zshcmd(s);
- concb((char)escape);
- return(x);
-}
-#endif /* BROWSER */
-
-#ifdef CK_RECALL
-static int
-doredo() { /* Find a previous cmd and redo it */
- extern int on_recall, in_recall;
- int x;
- char * p;
-
- if ((x = cmtxt(
-"pattern, or first few characters of a previous command",
- "*",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- x = strlen(s);
- s = line;
- if (*s == '{') { /* Braces disable adding * to end */
- if (s[x-1] == '}') {
- s[x-1] = NUL;
- s++;
- x--;
- }
- } else { /* No braces, add * to end. */
- s[x] = '*';
- s[x+1] = NUL;
- }
-
- while (x > 0 && s[x] == '*' && s[x-1] == '*') s[x--] = NUL;
-
- if (!on_recall || !in_recall) {
- printf("?Sorry, command recall can't be used now.\n");
- return(-9);
- }
- if ((p = cmgetcmd(s))) { /* Look for it history buffer */
- ckmakmsg(cmdbuf,CMDBL,p,"\r",NULL,NULL); /* Copy to command buffer */
- if (!quiet) /* Echo it */
- printf("%s\n",cmdbuf);
- cmaddnext(); /* Force re-add to history buffer */
- return(cmflgs = -1); /* Force reparse */
- } else {
- printf("?Sorry - \"%s\" not found\n", s);
- return(-9);
- }
-}
-#endif /* CK_RECALL */
-
-#ifndef NOXFER
-#ifndef NOCSETS
-static int
-doassoc() { /* ASSOCIATE */
- extern struct keytab tcstab[];
- extern int ntcs;
- if ((x = cmkey(assoctab, nassoc, "", "", xxstring)) < 0 )
- return(x);
-
- switch (x) { /* Associate what? */
-
- case ASSOC_TC: /* Transfer character-set... */
- if ((x = cmkey(tcstab, ntcs,
- "transfer character-set name","",xxstring)) < 0)
- return(x);
- if ((y = cmkey(fcstab, nfilc,
- "with file character-set","", xxstring)) < 0)
- if (y != -3)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- axcset[x] = y;
- return(success = 1);
-
- case ASSOC_FC: /* File character-set... */
- if ((x = cmkey(fcstab, nfilc,
- "file character-set name","",xxstring)) < 0)
- return(x);
- if ((y = cmkey(tcstab, ntcs,
- "with transfer character-set","", xxstring)) < 0)
- if (y != -3)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- afcset[x] = y;
- return(success = 1);
-
- default:
- return(-2);
- }
-}
-#endif /* NOCSETS */
-#endif /* NOXFER */
-
-#ifndef NOHELP
-static int
-domanual() {
-#ifdef OS2
- if ((x = cmcfm()) < 0)
- return(x);
- if (nopush) {
- printf("?Sorry, access to system commands is disabled.\n");
- return(-9);
- }
- y = mxlook(mactab,"manual",nmac);
- if (y > -1) {
- z = maclvl; /* Save the current maclvl */
- dodo(y,NULL,cmdstk[cmdlvl].ccflgs); /* Run the macro */
- while (maclvl > z) {
- debug(F101,"XXMAN loop maclvl 1","",maclvl);
- sstate = (CHAR) parser(1);
- debug(F101,"XXMAN loop maclvl 2","",maclvl);
- if (sstate) proto();
- }
- debug(F101,"XXMAN loop exit maclvl","",maclvl);
- return(success);
- }
- return(success = 0);
-#else
- if ((x = cmtxt(
-#ifdef UNIX
- "Carriage return to confirm the command, or manual topic",
-#else
- "Carriage return to confirm the command, or help topic",
-#endif /* UNIX */
- "kermit",
- &s,
- xxstring
- )
- ) < 0)
- return(x);
-#endif /* OS2 */
-
-#ifdef UNIX
- ckmakmsg(tmpbuf,TMPBUFSIZ,"man ",s,NULL,NULL);
-#else
- ckmakmsg(tmpbuf,TMPBUFSIZ,"help ",s,NULL,NULL);
-#endif /* UNIX */
- debug(F110,"MANUAL",tmpbuf,0);
- if (nopush) {
- printf("?Sorry, access to system commands is disabled.\n");
- return(-9);
- } else {
- conres(); /* Restore the console */
- success = zshcmd(tmpbuf);
- concb((char)escape); /* Restore CBREAK mode */
- return(success);
- }
-}
-#endif /* NOHELP */
-
-#ifndef NOHTTP
-#ifdef TCPSOCKET
-static struct keytab sslswtab[] = {
- { "/ssl", 1, 0 },
- { "/tls", 1, 0 }
-};
-
-#ifndef NOURL
-struct urldata http_url = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
-#endif /* NOURL */
-
-static int
-dohttp() { /* HTTP */
- struct FDB sw, kw, fi;
- int n, getval, allinone = 0;
- char c, * p;
- char rdns[128];
-
- char * http_agent = NULL; /* Parse results */
- char * http_hdr = NULL;
- char * http_user = NULL;
- char * http_pass = NULL;
- char * http_mime = NULL;
- char * http_lfile = NULL;
- char * http_rfile = NULL;
- char * http_dfile = NULL;
- char http_array = NUL;
- int http_action = -1;
-
- char * http_host = NULL;
- char * http_srv = NULL;
- int http_ssl = 0;
-
- static char * http_d_agent = NULL;
- static char * http_d_user = NULL;
- static char * http_d_pass = NULL;
-
- static int http_d_type = 0;
- int http_type = http_d_type;
-
-#ifdef OS2
- p = "Kermit 95"; /* Default user agent */
-#else
- p = "C-Kermit";
-#endif /* OS2 */
- makestr(&http_agent,p);
- makestr(&http_mime,"text/HTML"); /* MIME type default */
- rdns[0] = '\0';
-
- cmfdbi(&sw, /* 1st FDB - general switches */
- _CMKEY, /* fcode */
- "OPEN, CLOSE, GET, HEAD, PUT, INDEX, or POST,\n or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nhttpswtab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- httpswtab, /* Keyword table */
- &kw /* Pointer to next FDB */
- );
- cmfdbi(&kw, /* 2nd FDB - commands */
- _CMKEY, /* fcode */
- "Command", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nhttptab, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 0 = keyword */
- xxstring, /* Processing function */
- httptab, /* Keyword table */
- NULL /* Pointer to next FDB */
- );
-
- while (1) {
- x = cmfdb(&sw); /* Parse something */
- if (x < 0) /* Error */
- goto xhttp;
- n = cmresult.nresult;
- if (cmresult.fdbaddr == &kw) /* Command - exit this loop */
- break;
- c = cmgbrk(); /* Switch... */
- getval = (c == ':' || c == '=');
- x = -9;
- if (getval && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- goto xhttp;
- }
- switch (cmresult.nresult) { /* Handle each switch */
- case HT_SW_TP: /* /TOSCREEN */
- http_type = 1;
- break;
- case HT_SW_AG: /* /AGENT */
- if (getval) {
- if ((x = cmfld("User agent",p,&s,xxstring)) < 0)
- goto xhttp;
- } else {
- s = p;
- }
- makestr(&http_agent,s);
- break;
- case HT_SW_HD: /* /HEADER */
- s = NULL;
- if (getval) {
- if ((x = cmfld("Header line","",&s,xxstring)) < 0) {
- if (x == -3)
- s = NULL;
- else
- goto xhttp;
- }
- }
- makestr(&http_hdr,s);
- break;
- case HT_SW_US: /* /USER */
- s = NULL;
- if (getval) {
- if ((x = cmfld("User ID","",&s,xxstring)) < 0) {
- if (x == -3)
- s = "";
- else
- goto xhttp;
- }
- }
- makestr(&http_user,s);
- break;
- case HT_SW_PW: /* /PASSWORD */
- debok = 0;
- s = NULL;
- if (getval) {
- if ((x = cmfld("Password","",&s,xxstring)) < 0)
- goto xhttp;
- }
- makestr(&http_pass,s);
- break;
-#ifndef NOSPL
- case HT_SW_AR: { /* /ARRAY: */
- char * s2, array = NUL;
- if (!getval) {
- printf("?This switch requires an argument\n");
- x = -9;
- goto xhttp;
- }
- if ((x = cmfld("Array name (a single letter will do)",
- "",
- &s,
- NULL
- )) < 0) {
- if (x == -3) {
- printf("?Array name required\n");
- x = -9;
- goto xhttp;
- } else
- goto xhttp;
- }
- if (!*s) {
- printf("?Array name required\n");
- x = -9;
- goto xhttp;
- }
- s2 = s;
- if (*s == CMDQ) s++;
- if (*s == '&') s++;
- if (!isalpha(*s)) {
- printf("?Bad array name - \"%s\"\n",s2);
- x = -9;
- goto xhttp;
- }
- array = *s++;
- if (isupper(array))
- array = tolower(array);
- if (*s && (*s != '[' || *(s+1) != ']')) {
- printf("?Bad array name - \"%s\"\n",s2);
- http_array = NUL;
- x = -9;
- goto xhttp;
- }
- http_array = array;
- break;
- }
-#endif /* NOSPL */
- default:
- x = -2;
- goto xhttp;
- }
- }
- http_action = n; /* Save the action */
- if (http_action == HTTP_PUT || http_action == HTTP_POS) {
- cmfdbi(&sw, /* 1st FDB - switch */
- _CMKEY, /* fcode */
- "Local filename\n Or switch", /* help */
- "", /* default */
- "", /* addtl string data */
- nhttpptab, /* keyword table size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- httpptab, /* Keyword table */
- &fi /* Pointer to next FDB */
- );
- cmfdbi(&fi, /* 2nd FDB - filename */
- _CMIFI, /* fcode */
- "Local filename", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- while (1) {
- x = cmfdb(&sw);
- if (x < 0)
- goto xhttp; /* Free any malloc'd temp strings */
- n = cmresult.nresult;
- if (cmresult.fcode != _CMKEY)
- break;
- c = cmgbrk(); /* Switch... */
- getval = (c == ':' || c == '=');
- if (getval && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- x = -9;
- goto xhttp;
- }
- switch (n) {
- case HT_PP_MT:
- s = "text/HTML";
- if (getval) {
- if ((x = cmfld("MIME type",
- "text/HTML",&s,xxstring)) < 0)
- goto xhttp;
- }
- makestr(&http_mime,s);
- break;
- default:
- x = -2;
- goto xhttp;
- }
- }
- makestr(&http_lfile,cmresult.sresult);
- n = ckindex("/",http_lfile,-1,1,0);
- if (n)
- p = &http_lfile[n];
- else
- p = http_lfile;
- if ((x = cmfld("URL or remote filename",p,&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?%s what?\n",(http_action == HTTP_PUT) ? "Put" : "Post");
- x = -9;
- }
- goto xhttp;
- }
- if (!*s) s = NULL;
- makestr(&http_rfile,s);
-
- if ((x = cmtxt("Response filename","",&s,xxstring)) < 0) {
- if (x != -3)
- goto xhttp;
- }
- if (*s)
- makestr(&http_dfile,s);
- }
- switch (http_action) {
- case HTTP_DEL: /* DELETE */
- if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Delete what?\n");
- x = -9;
- }
- goto xhttp;
- }
- makestr(&http_rfile,s);
- break;
- case HTTP_CON: /* CONNECT */
- if ((x = cmfld("Remote host[:port]","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Remote host[:port] is required\n");
- x = -9;
- }
- goto xhttp;
- }
- makestr(&http_rfile,s);
- break;
- case HTTP_HED: { /* HEAD */
- char buf[CKMAXPATH+1];
- if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Head of what?\n");
- x = -9;
- }
- goto xhttp;
- }
- makestr(&http_rfile,s);
-
- if (http_array || http_type) { /* Default result filename */
- p = ""; /* None if /ARRAY or /TOSCREEN */
- } else {
- n = ckindex("/",http_rfile,-1,1,0); /* Otherwise strip path */
- if (n) /* and add ".head" */
- p = &http_rfile[n];
- else
- p = http_rfile;
- ckmakmsg(buf,CKMAXPATH,p,".head",NULL,NULL);
- p = buf;
- }
- if ((x = cmofi("Local filename",p,&s,xxstring)) < 0) {
- if (x != -3)
- goto xhttp;
- }
- makestr(&http_lfile,s);
- break;
- }
- case HTTP_GET: /* GET */
- case HTTP_IDX: { /* INDEX */
- extern int wildena;
- int tmp;
- char * lfile = "";
- if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Get what?\n");
- x = -9;
- }
- goto xhttp;
- }
- makestr(&http_rfile,s);
- if (http_action == HTTP_GET && !http_type)
- zstrip(http_rfile,&lfile);
- /* URLs often contain question marks or other metacharacters */
- /* cmofi() doesn't like them */
- tmp = wildena;
- wildena = 0;
- if ((x = cmofi("Local filename",lfile,&s,xxstring)) < 0) {
- wildena = tmp;
- if (x != -3)
- goto xhttp;
- }
- wildena = tmp;
- makestr(&http_lfile,s);
- break;
- }
- case HTTP_OPN: {
- int sslswitch = 0;
-#ifdef CK_SSL
- struct FDB sw, fl;
- cmfdbi(&sw,
- _CMKEY, /* fcode */
- "IP host name or address, or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 2, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- sslswtab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* 2nd FDB - host */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- x = cmfdb(&sw); /* Parse switch or host */
- if (x < 0) /* Error */
- goto xhttp;
- if (cmresult.fcode == _CMFLD) { /* Host */
- s = cmresult.sresult; /* Set up expected pointer */
- goto havehost; /* Go parse rest of command */
- }
- sslswitch = 1; /* /SSL or /TLS switch - set flag */
-#endif /* CK_SSL */
-
- /* Parse host */
-
- if ((x = cmfld("URL, hostname, or ip-address","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Open what?\n");
- x = -9;
- }
- goto xhttp;
- }
-
- havehost: /* Come here with s -> host */
-#ifdef CK_URL
- x = urlparse(s,&http_url); /* Was a URL given? */
- if (x < 1) { /* Not a URL */
-#endif /* CK_URL */
- makestr(&http_host,s);
- if ((x =
- cmfld("Service name or port number",
- sslswitch ? "https" : "http",&s,xxstring)) < 0)
- goto xhttp;
- else
- makestr(&http_srv,s);
-#ifdef CK_URL
- } else if (ckstrcmp(http_url.svc,"http",-1,0) && /* Non-HTTP URL */
- ckstrcmp(http_url.svc,"https",-1,0)) {
- printf("?Non-HTTP URL\n");
- x = -9;
- goto xhttp;
- } else { /* Have HTTP URL */
- makestr(&http_srv, http_url.svc);
- makestr(&http_user,http_url.usr);
- makestr(&http_pass,http_url.psw);
- makestr(&http_host,http_url.hos);
- if (http_url.por)
- makestr(&http_srv,http_url.por);
- makestr(&http_rfile,http_url.pth);
- }
- if (http_rfile) { /* Open, GET, and Close */
- printf("?Directory/file path not allowed in HTTP OPEN URL\n");
- x = -9;
- goto xhttp;
- }
- if (!ckstrcmp("https",http_srv,-1,0) || sslswitch ||
- !ckstrcmp("443",http_srv,-1,0))
- http_ssl = 1;
-#endif /* CK_URL */
- break;
- }
- case HTTP_CLS:
- break;
- }
- if ((x = cmcfm()) < 0)
- goto xhttp;
-
- if (http_action == HTTP_OPN) {
- x = (http_open(http_host,http_srv,http_ssl,rdns,128,http_agent) == 0);
- if (x) {
- if (!quiet) {
- if (rdns[0])
- printf("Connected to %s [%s]\r\n",http_host,rdns);
- else
- printf("Connected to %s\r\n",http_host);
- }
- if (http_agent) {
- if (http_d_agent)
- free(http_d_agent);
- http_d_agent = http_agent;
- http_agent = NULL;
- }
- if (http_user) {
- if (http_d_user)
- free(http_d_user);
- http_d_user = http_user;
- http_user = NULL;
- }
- if (http_pass) {
- if (http_d_pass) {
- memset(http_d_pass,0,strlen(http_d_pass));
- free(http_d_pass);
- }
- http_d_pass = http_pass;
- http_pass = NULL;
- }
- http_d_type = http_type;
- } else {
- if (!quiet)
- printf("?HTTP Connection failed.\r\n");
- }
- } else if (http_action == HTTP_CLS) {
- if (http_d_agent) {
- free(http_d_agent);
- http_d_agent = NULL;
- }
- if (http_d_user) {
- free(http_d_user);
- http_d_user = NULL;
- }
- if (http_d_pass) {
- memset(http_d_pass,0,strlen(http_d_pass));
- free(http_d_pass);
- http_d_pass = NULL;
- }
- http_d_type = 0;
- x = (http_close() == 0);
- }
- if ((http_action != HTTP_CLS) &&
- (http_action != HTTP_CON) && http_rfile) { /* Remote file is URL? */
-
- /* All-in-one actions when a URL is given... */
-
-#ifdef CK_URL
- if (urlparse(http_rfile,&http_url) > 0) { /* Have URL? */
- if (ckstrcmp(http_url.svc,"http",-1,0) && /* It's an HTTP URL? */
- ckstrcmp(http_url.svc,"https",-1,0)) {
- printf("?Non-HTTP URL\n");
- x = -9;
- goto xhttp;
- } else { /* Yes, collect the pieces */
- makestr(&http_srv, http_url.svc);
- makestr(&http_user,http_url.usr);
- makestr(&http_pass,http_url.psw);
- makestr(&http_host,http_url.hos);
- if (http_url.por)
- makestr(&http_srv,http_url.por);
- makestr(&http_rfile,http_url.pth);
- }
- if (!http_rfile) { /* Still have a path? */
- makestr(&http_rfile,"/");
- }
- if (!ckstrcmp("https",http_srv,-1,0) || /* Check for SSL/TLS */
- !ckstrcmp("443",http_srv,-1,0))
- http_ssl = 1;
- if (http_isconnected()) /* Close any open HTTP connection */
- http_close();
- if (http_pass == NULL && http_d_pass != NULL)
- makestr(&http_pass,http_d_pass);
- x = (http_open(http_host,
- http_srv,http_ssl,rdns,128,http_d_agent) == 0);
- if (x < 0) {
- x = 0;
- goto xhttp;
- }
- allinone = 1;
- }
-#endif /* CK_URL */
- if (http_pass == NULL && http_d_pass != NULL)
- makestr(&http_pass,http_d_pass);
-
- if (http_action == HTTP_OPN && allinone) {
- http_action = HTTP_GET;
- }
- x = xdohttp(http_action,
- http_lfile,
- http_rfile,
- http_dfile,
- http_agent ? http_agent : http_d_agent,
- http_hdr,
- http_user ? http_user : http_d_user,
- http_pass ? http_pass : http_d_pass,
- http_mime,
- http_array,
- http_type
- );
- if (allinone)
- x = (http_close() == 0);
- }
-
- xhttp:
- if (http_agent) free(http_agent);
- if (http_hdr) free(http_hdr);
- if (http_user) free(http_user);
- if (http_pass) {
- memset(http_pass,0,strlen(http_pass));
- free(http_pass);
- }
- if (http_mime) free(http_mime);
- if (http_lfile) free(http_lfile);
- if (http_rfile) free(http_rfile);
- if (http_dfile) free(http_dfile);
- if (http_host) free(http_host);
- if (http_srv) free(http_srv);
-
- if (x > -1)
- success = x;
- return(x);
-}
-#endif /* TCPSOCKET */
-#endif /* NOHTTP */
-
-
-#ifndef NOSPL
-static int
-dotrace() {
- int on = 1;
- struct FDB sw, kw;
- cmfdbi(&sw, /* 1st FDB - switch */
- _CMKEY, /* fcode */
- "Trace object;\n Or switch", /* help */
- "", /* default */
- "", /* addtl string data */
- 2, /* keyword table size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- onoffsw, /* Keyword table */
- &kw /* Pointer to next FDB */
- );
- cmfdbi(&kw, /* 2nd FDB - Trace object */
- _CMKEY, /* fcode */
- "Trace object", /* help */
- "all", /* default */
- "", /* addtl string data */
- ntracetab, /* keyword table size */
- 0, /* addtl numeric data 2: 0 = keyword */
- xxstring, /* Processing function */
- tracetab, /* Keyword table */
- NULL /* Pointer to next FDB */
- );
- if ((x = cmfdb(&sw)) < 0)
- return(x);
- if (cmresult.fdbaddr == &sw) {
- on = cmresult.nresult;
- if ((x = cmkey(tracetab, ntracetab,"","all",xxstring)) < 0)
- return(x);
- } else {
- x = cmresult.nresult;
- }
- if ((y = cmcfm()) < 0)
- return(y);
-
- switch (x) {
- case TRA_ASG:
- tra_asg = on;
- break;
- case TRA_CMD:
- tra_cmd = on;
- break;
- case TRA_ALL:
- tra_asg = on;
- tra_cmd = on;
- break;
- default:
- return(-2);
- }
- printf("TRACE %s\n", on ? "ON" : "OFF");
- return(success = 1);
-}
-#endif /* NOSPL */
-
-
-static int
-doprompt() {
- extern int xcmdsrc;
- if ((x = cmtxt("Optional message","",&s,xxstring)) < 0)
- return(x);
-#ifdef NOSPL
- printf("?Sorry, PROMPT requires script programming language\n");
- return(-9);
-#else
- debug(F101,"Prompt cmdlvl","",cmdlvl);
- cmdlvl++;
- if (cmdlvl > CMDSTKL) {
- printf("?Command stack overflow: %d\n",cmdlvl);
- cmdlvl--;
- return(-9);
- }
- xcmdsrc = CMD_KB;
- cmdstk[cmdlvl].src = CMD_KB; /* Say we're at the prompt */
- cmdstk[cmdlvl].lvl = 0;
- cmdstk[cmdlvl].ccflgs = cmdstk[cmdlvl-1].ccflgs;
- if (tra_cmd)
- printf("[%d] +P: \"(prompt)\"\n",cmdlvl);
- concb((char)escape);
- if (!quiet)
- printf(
-"(Recursive command prompt: Resume script with CONTINUE, STOP to stop...)\n"
- );
- if (*s) { /* If prompt given */
- makestr(&(prstring[cmdlvl-1]),cmgetp()); /* Save current prompt */
- cmsetp(s); /* Set new one */
- }
- return(success = 1);
-#endif /* NOSPL */
-}
-
-#ifdef CKLEARN
-VOID
-learncmd(s) char *s; { /* Record commands in learned script */
- char buf[64];
- int i, k;
- if (learnfp && learning) { /* Only if open and on */
- k = ckstrncpy(buf,s,64);
- for (i = 0; i < k; i++) { /* Get top-level command keyword */
- if (buf[i] <= SP) {
- buf[i] = NUL;
- break;
- }
- }
- k = lookup(cmdtab,buf,ncmd,NULL); /* Look it up */
- if (k == XXCON || k == XXLEARN) /* Don't record CONNECT or LEARN */
- return;
- if (k == XXTEL) {
- fputs("SET HOST /NETWORK:TCP",learnfp);
- fputs(&s[i],learnfp);
- fputs(" TELNET /TELNET",learnfp);
- fputs("\nIF FAIL STOP 1 Connection failed\n",learnfp);
- } else {
- fputs(s,learnfp);
- fputs("\n",learnfp);
- }
- }
-}
-#endif /* CKLEARN */
-
-
-#ifdef SSHCMD
-/*
- 2010/03/01...
- Reopen a connection that was made with an external ssh client
- after it has been closed.
- */
-int
-redossh() {
- int x, netsave;
- x = nettype;
- debug(F111,"redossh nettype",ttname,nettype);
- if ((y = setlin(XXSSH,0,1)) < 0) {
- if (errno)
- printf("?%s\n",ck_errstr());
- else
- return(y);
- nettype = x; /* Failed, restore net type. */
- success = 0;
- return(y);
- }
- netsave = x;
- return(y);
-}
-#endif /* SSHCMD */
-
-/*
- Like hmsga() in ckuus2.c but takes a single substitution parameter, s2,
- which replaces every occurrence of "%s" in the first argument.
- Added to print text containing the copyright year, so the year doesn't
- have to be hardwired into lots of scattered text strings.
-*/
-int /* Print an array of lines, */
-#ifdef CK_ANSIC
-hmsgaa(char *s[], char *s2) /* pausing at end of each screen. */
-#else
-hmsgaa(s,s2) char *s[]; char *s2;
-#endif /* CK_ANSIC */
-{
- extern int hmtopline;
-#ifdef OS2
- extern int tt_rows[], tt_cols[];
-#else /* OS2 */
- extern int tt_rows, tt_cols;
-#endif /* OS2 */
- int x, y, i, j, k, n;
- if ((x = cmcfm()) < 0) return(x);
-
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- /* Check whether window size changed */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
- printf("\n"); /* Start off with a blank line */
- n = (hmtopline > 0) ? hmtopline : 1; /* Line counter */
- for (i = 0; *s[i]; i++) {
- printf((char *)s[i],s2); /* Print a line. */
- printf("\n");
- y = (int)strlen(s[i]);
- k = 1;
- for (j = 0; j < y; j++) /* See how many newlines were */
- if (s[i][j] == '\n') k++; /* in the string... */
- n += k;
- if (n > (cmd_rows - 3) && *s[i+1]) /* After a screenful, give them */
- if (!askmore()) return(0); /* a "more?" prompt. */
- else n = 0;
- }
- printf("\n");
- return(0);
-}
-
-/* D O C M D -- Do a command */
-
-/*
- Returns:
- -2: user typed an illegal command
- -1: reparse needed
- 0: parse was successful (even tho command may have failed).
-*/
-#ifdef DEBUG
-int cmdstats[256] = { -1, -1 };
-#endif /* DEBUG */
-
-int
-docmd(cx) int cx; {
- extern int nolocal, cmkwflgs;
-
- debug(F101,"docmd entry, cx","",cx);
- activecmd = cx;
- doconx = ((activecmd == XXCON) || (activecmd == XXTEL) ||
- (activecmd == XXRLOG) || (activecmd == XXPIPE) ||
- (activecmd == XXIKSD) || (activecmd == XXPTY));
-/*
- Originally all commands were handled with a big switch() statement,
- but eventually this started blowing up compilers. Now we have a series
- of separate if statements and small switches, with the commands that are
- most commonly executed in scipts and loops coming first, to speed up
- compute-bound scripts.
- */
-
-#ifdef DEBUG
- if (cmdstats[0] == -1) { /* Count commands */
- int i; /* for tuning... */
- for (i = 0; i < 256; i++)
- cmdstats[i] = 0;
- }
-#endif /* DEBUG */
-
- switch (cx) {
- case -4: /* EOF */
-#ifdef OSK
- if (msgflg) printf("\n");
-#else
- if (msgflg) printf("\r\n");
-#endif /* OSK */
- doexit(GOOD_EXIT,xitsta);
- case -3: /* Null command */
- return(0);
- case -9: /* Like -2, but errmsg already done */
- case -1: /* Reparse needed */
- return(cx);
- case -6: /* Special */
- case -2: /* Error, maybe */
-
-#ifndef NOSPL
-/*
- Maybe they typed a macro name. Let's look it up and see.
-*/
- if (cx == -6) /* If they typed CR */
- ckstrncat(cmdbuf,"\015",CMDBL); /* add it back to command buffer. */
- if (ifcmd[cmdlvl] == 2) /* Watch out for IF commands. */
- ifcmd[cmdlvl]--;
- repars = 1; /* Force reparse */
- cmres();
- cx = XXDO; /* Try DO command */
-#else
- return(cx);
-#endif /* NOSPL */
- default:
- if (cx < 0)
- return(cx);
- break;
- }
-#ifdef DEBUG
- if (cx < 256)
- cmdstats[cx]++;
-#endif /* DEBUG */
-
- if ((cmkwflgs & CM_PSH)
-#ifndef NOPUSH
- && nopush
-#endif /* NOPUSH */
- ) {
- printf("?Access to system disabled\n");
- return(-9);
- }
- if ((cmkwflgs & CM_LOC)
-#ifndef NOLOCAL
- && nolocal
-#endif /* NOLOCAL */
- ) {
- printf("?Connections disabled\n");
- return(-9);
- }
-
-#ifndef NOSPL
- /* Used in FOR loops */
-
- if (cx == XX_INCR || cx == XXINC || /* _INCREMENT, INCREMENT */
- cx == XX_DECR || cx == XXDEC) /* _DECREMENT, DECREMENT */
- return(doincr(cx));
-
- /* Define (or change the definition of) a macro or variable */
-
- if (cx == XXUNDEF || cx == XXUNDFX) {
-#ifdef IKSD
- if (inserver && !ENABLED(en_asg)) {
- printf("?Sorry, DEFINE/ASSIGN disabled\n");
- return(-9);
- }
-#endif /* IKSD */
- return(doundef(cx)); /* [_]UNDEFINE */
- }
- if (cx == XXDEF || cx == XXASS ||
- cx == XXDFX || cx == XXASX) {
-#ifdef IKSD
- if (inserver && !ENABLED(en_asg)) {
- printf("?Sorry, DEFINE/ASSIGN disabled\n");
- return(-9);
- }
-#endif /* IKSD */
- if (atmbuf[0] == '.' && !atmbuf[1]) /* "." entered as keyword */
- xxdot = 1; /* i.e. with space after it... */
- return(dodef(cx)); /* DEFINE, ASSIGN, etc... */
- }
-
- /* IF, WHILE, and friends */
-
- if (cx == XXIF || cx == XXIFX || cx == XXWHI || cx == XXASSER) {
- return(doif(cx));
- }
- if (cx == XXSWIT) { /* SWITCH */
- return(doswitch());
- }
-
- /* GOTO, FORWARD, and _FORWARD (used internally by FOR, WHILE, etc) */
-
- if (cx == XXGOTO || cx == XXFWD || cx == XXXFWD) { /* GOTO or FORWARD */
- /* Note, here we don't set SUCCESS/FAILURE flag */
-#ifdef COMMENT
- if ((y = cmfld("label","",&s,xxstring)) < 0) {
- if (y == -3) {
- if (cx != XXXFWD) {
- printf("?Label name required\n");
- return(-9);
- }
- } else
- return(y);
- }
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((x = cmcfm()) < 0) return(x);
-#else
- if ((y = cmtxt("label","",&s,xxstring)) < 0) {
- if (y == -3) {
- if (cx != XXXFWD) {
- printf("?GOTO: Label name required: \"%s\" \"%s\"\n",
- atmbuf,
- cmdbuf);
- return(-9);
- }
- } else
- return(y);
- }
- ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
-#endif /* COMMENT */
- s = tmpbuf;
- debug(F111,"GOTO target",s,cx);
- return(dogoto(s,cx));
- }
- if (cx == XXDO || cx == XXMACRO) { /* DO (a macro) */
- char mnamebuf[16]; /* (buffer for controlled temp name) */
- struct FDB kw, fl;
- int mx; /* Macro index (on stack!) */
-
- debug(F101,"XXMACRO 0",line,cx);
- if (cx == XXDO) {
- if (nmac == 0) {
- printf("\n?No macros defined\n");
- return(-9);
- }
- for (y = 0; y < nmac; y++) { /* copy the macro table into a */
- mackey[y].kwd = mactab[y].kwd; /* regular keyword table */
- mackey[y].kwval = y; /* with value = pointer to macro tbl */
- mackey[y].flgs = mactab[y].flgs;
- }
- cmfdbi(&kw, /* First FDB - macro name */
- _CMKEY, /* fcode */
- "Macro", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nmac, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 0 = cmkey */
- xxstring, /* Processing function */
- mackey, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* 2nd FDB - for "{" */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "",
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- x = cmfdb(&kw); /* Parse something */
- if (x < 0) { /* Error */
- if (x == -3) {
- printf("?Macro name required\n");
- return(-9);
- } else
- return(x);
- }
- if (cmresult.fcode == _CMKEY) {
- extern int mtchanged;
- char * macroname = NULL;
-
- /* In case args include an \fexec() that changes the macro table */
-
- mx = x; /* Save macro index on stack */
- mtchanged = 0; /* Mark state of macro table */
- makestr(¯oname,mactab[mx].kwd); /* Save name */
-
- if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0)
- return(y); /* Get macro args */
-
- if (mtchanged) { /* Macro table changed? */
- mx = mlook(mactab,macroname,nmac); /* Look up name again */
- }
- if (macroname)
- free(macroname);
-
- return(dodo(mx,s,cmdstk[cmdlvl].ccflgs) < 1 ?
- (success = 0) : 1);
- }
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* _CMFLD */
- if (atmbuf[0] == '{') {
- if ((y = cmcfm()) < 0)
- return(y);
- }
- } else { /* XXMACRO ("immediate macro") */
- int k = 0;
- line[k++] = '{';
- line[k++] = SP;
- line[k] = NUL;
- debug(F111,"XXMACRO A",line,k);
- if ((y = cmtxt("Braced list of commands","",&s,xxstring)) < 0)
- return(y);
- k = ckstrncpy(line+k,s,LINBUFSIZ-k);
- debug(F111,"XXMACRO B",line,k);
- }
- x = strlen(line);
- if ((line[0] == '{' && line[x-1] != '}') || line[0] == '}')
- return(-2);
- if (line[0] != '{' && line[x-1] != '}') {
- /* Unknown command. If ON_UNKNOWN_COMMAND macro is defined, */
- /* parse args and then execute it, but only if it is not */
- /* already active. */
- int k = -1;
- if (!unkmacro) {
- k = mxlook(mactab,"on_unknown_command",nmac);
- }
- if (k > -1) {
- ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
- z = maclvl; /* Save the current maclvl */
- if ((y = cmtxt("text","",&s,xxstring)) < 0)
- return(y);
- ckstrncat(tmpbuf," ",TMPBUFSIZ);
- ckstrncat(tmpbuf,s,TMPBUFSIZ);
- unkmacro = 1;
- debug(F110,"ON_UNKNOWN_COMMAND",s,0);
- dodo(k,tmpbuf,cmdstk[cmdlvl].ccflgs); /* Run the macro */
- while (maclvl > z) {
- sstate = (CHAR) parser(1);
- if (sstate) proto();
- }
- debug(F101,"UNKMAC loop exit maclvl","",maclvl);
- unkmacro = 0;
- return(success);
- }
- if (x > 0)
- printf("?Not a command or macro name: \"%s\"\n",line);
- else
- printf("?Not a command or macro name.\n");
- return(-9);
- }
- s = brstrip(line);
- sprintf(mnamebuf," ..tmp:%03d",cmdlvl); /* safe (16) */
- x = addmac(mnamebuf,s);
- return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs) < 1 ? (success = 0) : 1);
- }
-
- if (cx == XXLBL) { /* LABEL */
- if ((x = cmfld("label","",&s,xxstring)) < 0) {
- if (x == -3) {
-#ifdef COMMENT
- printf("?LABEL: Label name required: \"%s\"\n", cmdbuf);
- return(-9);
-#else
- s = "";
-#endif /* COMMENT */
- } else return(x);
-
- }
- debug(F111,"LABEL",s,x);
- if ((x = cmcfm()) < 0) return(x);
- return(0);
- }
-
- if (cx == XXEVAL || cx == XX_EVAL) /* _EVALUATE, EVALUATE */
- return(doeval(cx));
-
-#ifndef NOSEXP
- if (cx == XXSEXP) { /* Lisp-like S-Expression */
- struct stringarray * q;
- char /* *p, *r, */ *tmp, *m;
- int i, k, n, quote = 0, contd = 0, size = 0, len = 0;
- extern int sexprc, sexppv;
-
- tmp = tmpbuf; /* Buffer to collect SEXP */
- tmpbuf[0] = NUL; /* Clear it */
- size = TMPBUFSIZ; /* Capacity of buffer */
- sexprc = -1; /* Assume bad input */
- n = 0; /* Paren balance counter */
-
- while (1) { /* Allow SEXP on multiple lines */
- m = contd ?
- "Continuation of S-Expression" :
- "S-Expression (\"help sexp\" for details)";
- x = cmtxt(m,"",&s,xxstring);
- if (x < 0)
- return(x);
- if (!*s) /* Needed for (=) and (:) */
- s = cmdbuf+1; /* I can't explain why. */
- k = ckmakmsg(tmp, size, contd ? " " : "(", s, NULL, NULL);
- if (k < 1) {
- printf("?SEXP too long - %d max\n",TMPBUFSIZ);
- return(-9);
- }
- debug(F111,contd ? "sexp contd" : "sexp",s,k);
-
- for (i = len; i < len+k; i++) { /* Check balance */
- if (!quote && tmpbuf[i] == CMDQ) {
- quote = 1;
- continue;
- }
- if (quote) {
- quote = 0;
- continue;
- }
- if (tmpbuf[i] == '(')
- n++;
- else if (tmpbuf[i] == ')')
- n--;
- }
- if (n == 0) { /* Break when balanced */
- break;
- }
- if (n < 0) { /* Too many right parens */
- printf("?Unbalanced S-Expression: \"%s\"\n",tmpbuf);
- return(-9);
- }
- contd++; /* Need more right parens */
- cmini(ckxech); /* so keep parsing */
- tmp += k; /* adjust buffer pointer */
- size -= k; /* and capacity */
- len += k; /* and length so far */
- }
- s = tmpbuf;
- makestr(&lastsexp,s);
- q = cksplit(1,SEXPMAX,s,NULL,NULL,8,0,0); /* Precheck for > 1 SEXP */
- debug(F101,"sexp split","",q->a_size);
-
- if (q->a_size == 1) { /* We should get exactly one back */
- char * result, * dosexp();
- sexprc = 0; /* Reset out-of-band return code */
- result = dosexp(s); /* Get result */
- debug(F111,"sexp result",result,sexprc);
- if (sexprc == 0) { /* Success */
- /* Echo the result if desired */
- if ((!xcmdsrc && sexpecho != SET_OFF) || sexpecho == SET_ON)
- printf(" %s\n",result ? result : "");
- makestr(&sexpval,result);
- success = sexppv > -1 ? sexppv : 1;
- return(success);
- }
- }
- if (sexprc < 0)
- printf("?Invalid S-Expression: \"%s\"\n",lastsexp);
- return(-9);
- }
-#endif /* NOSEXP */
-
-#endif /* NOSPL */
-
- if (cx == XXECH || cx == XXXECH || cx == XXVOID
-#ifndef NOSPL
- || cx == XXAPC
-#endif /* NOSPL */
- ) { /* ECHO or APC */
- if ((x = cmtxt((cx == XXECH || cx == XXXECH) ?
- "Text to be echoed" :
- ((cx == XXVOID) ? "Text" :
- "Application Program Command text"),
- "",
- &s,
- xxstring
- )
- ) < 0)
- return(x);
- if (!s) s = "";
-#ifdef COMMENT
-/* This is to preserve the pre-8.0 behavior but it's too confusing */
- x = strlen(s);
- x = (x > 1) ? ((s[0] == '"' && s[x-1] == '"') ? 1 : 0) : 0;
-#endif /* COMMENT */
- s = brstrip(s); /* Strip braces and doublequotes */
- if (cx == XXECH) { /* ECHO */
-#ifndef NOSPL
- if (!fndiags || fnsuccess) {
-#endif /* NOSPL */
-#ifdef COMMENT
- /* The "if (x)" business preserves previous behavior */
- /* by putting back the doublequotes if they were included. */
- if (x)
- printf("\"%s\"\n",s);
- else
-#endif /* COMMENT */
- printf("%s\n",s);
-#ifndef NOSPL
- }
-#endif /* NOSPL */
- } else if (cx == XXXECH) { /* XECHO */
- if (x)
- printf("\"%s\"",s);
- else
- printf("%s",s);
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- } else if (cx == XXAPC) { /* APC */
-#ifdef CK_APC
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
- return(success = 0);
-#endif /* CK_APC */
- if (!local) {
- printf("%c_%s%c\\",ESC,s,ESC);
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
-
- } else { /* Local mode - have connection */
-#ifndef NOSPL
- if (ckmakxmsg(tmpbuf, /* Form APC string in buffer */
- TMPBUFSIZ,
- ckctoa((char)ESC),
- ckctoa('_'),
- s,
- ckctoa((char)ESC),
- ckctoa('\\'),
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- ) > 0)
- return(success = dooutput(tmpbuf, XXOUT));
- printf("?Too long\n");
- return(-9);
-#else
- printf("%c_%s%c\\",ESC,s,ESC);
-#endif /* NOSPL */
- }
- }
- return(success = 1);
- }
-
-#ifndef NOSPL
-/* Copy macro args from/to two levels up, used internally by _floop et al. */
- if (cx == XXGTA || cx == XXPTA) { /* _GETARGS, _PUTARGS */
- int x;
- debug(F101,"docmd XXGTA","",XXGTA);
- debug(F101,"docmd cx","",cx);
- debug(F101,"docmd XXGTA maclvl","",maclvl);
- x = dogta(cx);
- debug(F101,"docmd dogta returns","",x);
- debug(F101,"docmd dogta maclvl","",maclvl);
- return(x);
- }
-#endif /* NOSPL */
-
-#ifndef NOSPL
-#ifdef CKCHANNELIO
- if (cx == XXFILE)
- return(dofile(cx));
- else if (cx == XXF_RE || cx == XXF_WR || cx == XXF_OP ||
- cx == XXF_CL || cx == XXF_SE || cx == XXF_RW ||
- cx == XXF_FL || cx == XXF_LI || cx == XXF_ST || cx == XXF_CO)
- return(dofile(cx));
-#endif /* CKCHANNELIO */
-
-/* ASK, ASKQ, READ */
- if (cx == XXASK || cx == XXASKQ || cx == XXREA ||
- cx == XXRDBL || cx == XXGETC || cx == XXGETK) {
- return(doask(cx));
- }
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
-#ifndef NOHELP
- if (cx == XXBUG) { /* BUG */
- if ((x = cmcfm()) < 0) return(x);
- return(dobug());
- }
-#endif /* NOHELP */
-#endif /* NOFRILLS */
-
-#ifndef NOXFER
- if (cx == XXBYE) { /* BYE */
- extern int ftp_cmdlin;
- if ((x = cmcfm()) < 0) return(x);
-
-#ifdef NEWFTP
- if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
- extern int stayflg, ftp_fai;
- success = ftpbye();
- if (ftp_cmdlin && !stayflg && !local)
- doexit(ftp_fai ? BAD_EXIT : GOOD_EXIT,-1);
- else
- return(success);
- }
-#endif /* NEWFTP */
-
- if (!local) {
- printf("?No connection - use EXIT to quit.\n");
- return(-9);
- }
-
-#ifdef CK_XYZ
- if (protocol != PROTO_K) {
- printf("?Sorry, BYE only works with Kermit protocol\n");
- return(-9);
- }
-#endif /* CK_XYZ */
-
-#ifdef IKS_OPTION
- if (
-#ifdef CK_XYZ
- protocol == PROTO_K &&
-#endif /* CK_XYZ */
- !iks_wait(KERMIT_REQ_START,1)) {
- printf(
- "?A Kermit Server is not available to process this command\n");
- return(-9); /* Correct the return code */
- }
-#endif /* IKS_OPTION */
-
- bye_active = 1;
- sstate = setgen('L',"","","");
- if (local) ttflui(); /* If local, flush tty input buffer */
- return(0);
- }
-#endif /* NOXFER */
-
- if (cx == XXBEEP) { /* BEEP */
- int x;
-#ifdef OS2
- int y;
- if ((y = cmkey(beeptab, nbeeptab, "which kind of beep", "information",
- xxstring)) < 0 )
- return (y);
- if ((x = cmcfm()) < 0) return(x);
- bleep((short)y); /* y is one of the BP_ values */
-#else /* OS2 */
- if ((x = cmcfm()) < 0) return(x);
-#ifndef NOSPL
- bleep(BP_NOTE);
-#else
- putchar('\07');
-#endif /* NOSPL */
-#endif /* OS2 */
- return(0);
- }
-
-#ifndef NOFRILLS
- if (cx == XXCLE) /* CLEAR */
- return(success = doclear());
-#endif /* NOFRILLS */
-
- if (cx == XXCOM) { /* COMMENT */
- if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
- return(x);
- /* Don't change SUCCESS flag for this one */
- return(0);
- }
-
-#ifndef NOLOCAL
- if (cx == XXCON || cx == XXCQ) /* CONNECT or CONNECT /QUIETLY */
- return(doxconn(cx));
-#endif /* NOLOCAL */
-
-#ifndef NOFRILLS
-#ifdef ZCOPY
- if (cx == XXCPY) { /* COPY a file */
-#ifdef IKSD
- if (inserver && !ENABLED(en_cpy)) {
- printf("?Sorry, COPY is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
- )
- return(success = 0);
-#endif /* CK_APC */
- return(docopy());
- }
-#endif /* ZCOPY */
-#ifdef NT
- if ( cx == XXLINK ) {
-#ifdef IKSD
- if (inserver && !ENABLED(en_cpy)) {
- printf("?Sorry, LINK (COPY) is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
- )
- return(success = 0);
-#endif /* CK_APC */
- return(dolink());
- }
-#endif /* NT */
-#endif /* NOFRILLS */
-
- /* CD and friends */
- if (cx == XXCWD || cx == XXCDUP || cx == XXBACK ||
- cx == XXLCWD || cx == XXLCDU || cx == XXKCD) {
-#ifdef LOCUS
- if (!locus) {
- if (cx == XXCWD) {
-#ifdef NOXFER
- return(-2);
-#else
- return(dormt(XZCWD));
-#endif /* NOXFER */
- } else if (cx == XXCDUP) {
-#ifdef NOXFER
- return(-2);
-#else
- return(dormt(XZCDU));
-#endif /* NOXFER */
- }
- }
-#endif /* LOCUS */
-#ifdef IKSD
- if (inserver && !ENABLED(en_cwd)) {
- printf("?Sorry, changing directories is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
- return(success = docd(cx));
- }
-
- if (cx == XXCHK) /* CHECK */
- return(success = dochk());
-
- if (cx == XXCLO) { /* CLOSE */
- x = cmkey(clstab,ncls,"\"CONNECTION\", or log or file to close",
- "connection",xxstring);
- if (x == -3) {
- printf("?You must say which file or log\n");
- return(-9);
- }
- if (x < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
-#ifndef NOLOCAL
- if (x == 9999) { /* CLOSE CONNECTION */
- x = clsconnx(0);
- switch (x) {
- case 0:
- if (msgflg) printf("?Connection was not open\n");
- case -1:
- return(0);
- case 1:
- whyclosed = WC_CLOS;
- return(1);
- }
- return(0);
- }
-#endif /* NOLOCAL */
- y = doclslog(x);
- success = (y == 1);
- return(success);
- }
-
-#ifndef NOSPL
- if (cx == XXDCL || cx == XXUNDCL) { /* DECLARE an array */
- return(dodcl(cx));
- }
-#endif /* NOSPL */
-
-#ifndef NODIAL
- if (cx == XXRED || cx == XXDIAL || cx == XXPDIA ||
- cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */
-#ifdef VMS
- extern int batch;
-#else
-#ifdef UNIXOROSK
- extern int backgrd;
-#endif /* UNIXOROSK */
-#endif /* VMS */
- x = dodial(cx);
- debug(F101,"dodial returns","",x);
- if ((cx == XXDIAL || cx == XXRED || cx == XXANSW) &&
- (x > 0) && /* If DIAL or REDIAL succeeded */
- (dialsta != DIA_PART) && /* and it wasn't partial */
- (dialcon > 0)) {
- if ((dialcon == 1 || /* And DIAL CONNECT is ON, */
- ((dialcon == 2) && /* or DIAL CONNECT is AUTO */
- !xcmdsrc /* and we're at top level... */
-#ifdef VMS
- && !batch /* Not if running from batch */
-#else
-#ifdef UNIXOROSK
- && !backgrd /* Not if running in background */
-#endif /* UNIXOROSK */
-#endif /* VMS */
- ))) /* Or AUTO */
- x = doconect(dialcq, /* Then also CONNECT */
- cmdlvl == 0 ? 1 : 0
- );
- if (ttchk() < 0)
- dologend();
- }
- return(success = x);
- }
-#endif /* NODIAL */
-
-#ifndef NOPUSH
-#ifdef CK_REXX
- if (cx == XXREXX) { /* REXX */
- extern int nopush;
- if ( nopush )
- return(success=0);
- return(dorexx());
- }
-#endif /* CK_REXX */
-#endif /* NOPUSH */
-
-#ifndef NOFRILLS
- if (cx == XXDEL || cx == XXLDEL) { /* DELETE */
-#ifdef LOCUS
- if (!locus && cx != XXLDEL) {
-#ifdef NOXFER
- return(-2);
-#else
- return(dormt(XZDEL));
-#endif /* NOXFER */
- }
-#endif /* LOCUS */
-#ifdef IKSD
- if (inserver && (!ENABLED(en_del)
-#ifdef CK_LOGIN
- || isguest
-#endif /* CK_LOGIN */
- )) {
- printf("?Sorry, DELETE is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- if ((apcactive == APC_LOCAL) ||
- ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
- return(success = 0);
-#endif /* CK_APC */
- return(dodel());
- }
-#endif /* NOFRILLS */
-
- if (cx == XXTOUC) /* TOUCH */
- return(dodir(cx));
-
- /* DIRECTORY commands */
-
- if (cx == XXDIR || cx == XXLS || cx == XXLDIR ||
- cx == XXWDIR || cx == XXHDIR) {
-#ifdef LOCUS
- if (!locus && cx != XXLDIR) {
-#ifdef NOXFER
- return(-2);
-#else
- return(dormt(XZDIR));
-#endif /* NOXFER */
- }
-#endif /* LOCUS */
-#ifdef IKSD
- if (inserver && !ENABLED(en_dir)) {
- printf("?Sorry, DIRECTORY is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
- return(dodir(cx));
- }
-
-#ifndef NOSPL
- if (cx == XXELS) /* ELSE */
- return(doelse());
-#endif /* NOSPL */
-
-#ifndef NOSERVER
-#ifndef NOFRILLS
- if (cx == XXENA || cx == XXDIS) { /* ENABLE, DISABLE */
- s = (cx == XXENA) ?
- "Server function to enable" :
- "Server function to disable";
-
- if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of server function required\n");
- return(-9);
- } else return(x);
- }
- if ((y = cmkey(kmstab,3,"mode","both",xxstring)) < 0) {
- if (y == -3) {
- printf("?Please specify remote, local, or both\n");
- return(-9);
- } else return(y);
- }
- if (cx == XXDIS) /* Disabling, not enabling */
- y = 3 - y;
- if ((z = cmcfm()) < 0) return(z);
-#ifdef CK_APC
- if ((apcactive == APC_LOCAL) ||
- ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
- return(success = 0);
-#endif /* CK_APC */
-#ifdef IKSD
- /* This may seem like it duplicates the work in doenable() */
- /* but this code returns failure whereas doenable() returns */
- /* success. */
- if (inserver &&
-#ifdef IKSDCONF
- iksdcf &&
-#endif /* IKSDCONF */
- (x == EN_HOS || x == EN_PRI || x == EN_MAI || x == EN_WHO ||
- isguest))
- return(success = 0);
-#endif /* IKSD */
- return(doenable(y,x));
- }
-#endif /* NOFRILLS */
-#endif /* NOSERVER */
-
-#ifndef NOSPL
- if (cx == XXRET) { /* RETURN */
- if ((x = cmtxt("Optional return value","",&s,NULL)) < 0)
- return(x);
- s = brstrip(s); /* Strip braces */
- if (cmdlvl == 0) /* At top level, nothing happens... */
- return(success = 1);
- switch (cmdstk[cmdlvl].src) { /* Action depends on command source */
- case CMD_TF: /* Command file */
- popclvl(); /* Pop command level */
- return(success = 1); /* always succeeds */
- case CMD_MD: /* Macro */
- case CMD_KB: /* Prompt */
- return(doreturn(s)); /* Trailing text is return value. */
- default: /* Shouldn't happen */
- return(-2);
- }
- }
-#endif /* NOSPL */
-
-#ifndef NOSPL
- if (cx == XXOPE) /* OPEN */
- return(doopen());
-#endif /* NOSPL */
-
-#ifndef NOSPL
- if (cx == XXOUT || cx == XXLNOUT) { /* OUTPUT or LINEOUT */
- if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
- return(x);
-#ifdef CK_APC
- if ((apcactive == APC_LOCAL) ||
- ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
- return(success = 0);
-#endif /* CK_APC */
- debug(F110,"OUTPUT 1",s,0);
- s = brstrip(s); /* Strip enclosing braces, */
- debug(F110,"OUTPUT 2",s,0);
-/*
- I don't think I could ever fully explain this in a million years...
- We have read the user's string without calling the variable-expander
- function. Now, before we call it, we have to double backslashes that
- appear before \N, \B, \L, and \ itself, so the expander function will
- reduce them back to single backslashes, so when we call dooutput()...
- But it's more complicated than that.
-*/
- if (cmdgquo()) { /* Only if COMMAND QUOTING ON ... */
- for (x = 0, y = 0; s[x]; x++, y++) {
- if (s[x] == CMDQ) {
- char c = s[x+1];
- if (c == 'n' || c == 'N' ||
- c == 'b' || c == 'B' ||
- c == 'l' || c == 'L' ||
- c == CMDQ)
- line[y++] = CMDQ;
- }
- line[y] = s[x];
- }
- line[y++] = '\0'; /* Now expand variables, etc. */
- debug(F110,"OUTPUT 3",line,0);
- s = line+y+1;
- x = LINBUFSIZ - (int) strlen(line) - 1;
- debug(F101,"OUTPUT size","",x);
- if (zzstring(line,&s,&x) < 0)
- return(success = 0);
- s = line+y+1;
- debug(F110,"OUTPUT 4",s,0);
- }
- success = dooutput(s,cx);
- return(success);
- }
-#endif /* NOSPL */
-
-#ifdef ANYX25
-#ifndef IBMX25
- if (cx == XXPAD) { /* PAD commands */
- x = cmkey(padtab,npadc,"PAD command","",xxstring);
- if (x == -3) {
- printf("?You must specify a PAD command to execute\n");
- return(-9);
- }
- if (x < 0) return(x);
-
- switch (x) {
- case XYPADL:
- if (x25stat() < 0)
- printf("Sorry, you must 'set network' & 'set host' first\r\n");
- else {
- x25clear();
- initpad();
- }
- break;
- case XYPADS:
- if (x25stat() < 0)
- printf("Not connected\r\n");
- else {
- extern int linkid, lcn;
- conol("Connected thru ");
- conol(ttname);
- printf(", Link id %d, Logical channel number %d\r\n",
- linkid,lcn);
- }
- break;
- case XYPADR:
- if (x25stat() < 0)
- printf("Sorry, you must 'set network' & 'set host' first\r\n");
- else
- x25reset(0,0);
- break;
- case XYPADI:
- if (x25stat() < 0)
- printf("Sorry, you must 'set network' & 'set host' first\r\n");
- else
- x25intr(0);
- }
- return(0);
- }
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifndef NOSPL
- if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
- return(dopaus(cx));
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
- if (cx == XXPRI) {
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && (isguest || !ENABLED(en_pri))) {
- printf("?Sorry, printing is disabled\n");
- return(-9);
- }
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
- if (x == -3) {
- printf("?A file specification is required\n");
- return(-9);
- } else return(x);
- }
- if (y != 0) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = "";
-#ifndef NT
- if ((x = cmtxt("Local print command options, or carriage return","",&s,
- xxstring)) < 0)
- return(x);
-#endif /* NT */
- if ((x = cmcfm()) < 0)
- return(x);
- return(success = (zprint(s,line) == 0) ? 1 : 0);
- }
-#endif /* NOFRILLS */
-
-#ifdef TCPSOCKET
-#ifndef NOPUSH
- if (cx == XXPNG) /* PING an IP host */
- return(doping());
-#endif /* NOPUSH */
-
-#ifndef NOFTP
- if (cx == XXFTP) /* FTP */
-#ifdef SYSFTP
-#ifndef NOPUSH
- return(doftp()); /* Just runs system's ftp program */
-#else
- return(-2);
-#endif /* NOPUSH */
-#else
- return(doxftp());
-#endif /* SYSFTP */
-#endif /* NOFTP */
-#endif /* TCPSOCKET */
-
- if (cx == XXPWD || cx == XXLPWD) { /* PWD */
-#ifdef OS2
- char *pwp;
-#endif /* OS2 */
- if ((x = cmcfm()) < 0)
- return(x);
-#ifdef LOCUS
- if (!locus && cx != XXLPWD) {
-#ifdef NOXFER
- return(-2);
-#else
- return(dormt(XZPWD));
-#endif /* NOXFER */
- }
-#endif /* LOCUS */
-
-#ifndef MAC
-#ifndef OS2
-#ifdef UNIX
- printf("%s\n",zgtdir());
-#else
- xsystem(PWDCMD);
-#endif /* UNIX */
- return(success = 1); /* Blind faith */
-#else /* OS2 */
- if (pwp = zgtdir()) {
- if (*pwp) {
-#ifdef NT
- line[0] = NUL;
- ckGetLongPathName(pwp,line,LINBUFSIZ);
- line[LINBUFSIZ-1] = NUL;
- tmpbuf[0] = NUL;
- GetShortPathName(pwp,tmpbuf,TMPBUFSIZ);
- tmpbuf[TMPBUFSIZ-1] = NUL;
- pwp = line;
- if (!strcmp(line,tmpbuf)) {
-#endif /* NT */
- printf("%s\n",pwp);
-#ifdef NT
- } else {
- printf(" Long name: %s\n",line);
- printf(" Short name: %s\n",tmpbuf);
- }
-#endif /* NT */
- }
- return(success = ((int)strlen(pwp) > 0));
- } else return(success = 0);
-#endif /* OS2 */
-#else /* MAC */
- if (pwp = zgtdir()) {
- printf("%s\n",pwp);
- return(success = ((int)strlen(pwp) > 0));
- } else return(success = 0);
-#endif /* MAC */
- }
-
- if (cx == XXQUI || cx == XXEXI) { /* EXIT, QUIT */
- extern int quitting;
-
- if ((y = cmnum("exit status code",ckitoa(xitsta),10,&x,xxstring)) < 0)
- return(y);
- if ((y = cmtxt("Optional EXIT message","",&s,xxstring)) < 0)
- return(y);
- s = brstrip(s);
- ckstrncpy(line,s,LINBUFSIZ);
-
- if (!hupok(0)) /* Check if connection still open */
- return(success = 0);
-
- if (line[0]) /* Print EXIT message if given */
- printf("%s\n",(char *)line);
-
- quitting = 1; /* Flag that we are quitting. */
-
-#ifdef VMS
- doexit(GOOD_EXIT,x);
-#else
-#ifdef OSK
-/* Returning any codes here makes the OS-9 shell print an error message. */
- doexit(GOOD_EXIT,-1);
-#else
-#ifdef datageneral
- doexit(GOOD_EXIT,x);
-#else
- doexit(x,-1);
-#endif /* datageneral */
-#endif /* OSK */
-#endif /* VMS */
- }
-
-#ifndef NOXFER
-#ifndef NOFRILLS
- if (cx == XXERR) { /* ERROR */
-#ifdef CK_XYZ
- if (protocol != PROTO_K) {
- printf("Sorry, E-PACKET only works with Kermit protocol\n");
- return(-9);
- }
-#endif /* CK_XYZ */
- if ((x = cmcfm()) < 0) return(x);
- ttflui();
- epktflg = 1;
- sstate = 'a';
- return(0);
- }
-#endif /* NOFRILLS */
-
- if (cx == XXFIN) { /* FINISH */
-#ifdef NEWFTP
- if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
- return(ftpbye());
-#endif /* NEWFTP */
-#ifdef CK_XYZ
- if (protocol != PROTO_K) {
- printf("Sorry, FINISH only works with Kermit protocol\n");
- return(-9);
- }
-#endif /* CK_XYZ */
- if ((x = cmcfm()) < 0) return(x);
-
-#ifdef IKS_OPTION
- if (
-#ifdef CK_XYZ
- protocol == PROTO_K &&
-#endif /* CK_XYZ */
- !iks_wait(KERMIT_REQ_START,1)) {
- printf(
- "?A Kermit Server is not available to process this command\n");
- return(-9); /* Correct the return code */
- }
-#endif /* IKS_OPTION */
-
- sstate = setgen('F',"","","");
- if (local) ttflui(); /* If local, flush tty input buffer */
- return(0);
- }
-#endif /* NOXFER */
-
-#ifndef NOSPL
- if (cx == XXFOR) /* FOR loop */
- return(dofor());
-#endif /* NOSPL */
-
-#ifndef NOXFER
- /* GET MGET REGET RETRIEVE etc */
- if (cx == XXGET || cx == XXMGET || cx == XXREGET || cx == XXRETR) {
-#ifdef IKSD
- if (inserver && !ENABLED(en_sen)) {
- printf("?Sorry, reception of files is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
- return(doxget(cx));
- }
-#endif /* NOXFER */
-
-#ifndef NOSPL
-#ifndef NOFRILLS
- if (cx == XXGOK) { /* GETOK */
- return(success = doask(cx));
- }
-#endif /* NOFRILLS */
-#endif /* NOSPL */
-
- if (cx == XXHLP) { /* HELP */
-#ifdef NOHELP
- return(dohlp(XXHLP));
-#else
- x = cmkey2(cmdtab,
- ncmd,"\nCommand or topic","help",toktab,xxstring,1+2+8);
- debug(F111,"HELP command x",cmdbuf,x);
- if (x == -5) {
- y = chktok(toktab);
- debug(F101,"HELP cmkey token","",y);
- /* ungword(); */
- switch (y) {
-#ifndef NOPUSH
- case '!':
- case '@': x = XXSHE; break;
- case '<': x = XXFUN; break;
-#endif /* NOPUSH */
- case '#': x = XXCOM; break;
- case ';': x = XXCOM; break;
-#ifndef NOSPL
- case '.': x = XXDEF; break;
- case ':': x = XXLBL; break;
-#ifndef NOSEXP
- case '(': x = XXSEXP; break;
-#endif /* NOSEXP */
-#endif /* NOSPL */
-#ifdef CK_RECALL
- case '^': x = XXREDO; break;
-#endif /* CK_RECALL */
- case '&': x = XXECH; break; /* (what is this?) */
- default:
- printf("\n?Invalid - %s\n",cmdbuf);
- x = -2;
- }
- }
- makestr(&hlptok,atmbuf);
- debug(F111,"HELP token",hlptok,x);
- return(dohlp(x));
-#endif /* NOHELP */
- }
-
-#ifndef NOHELP
- if (cx == XXINT) /* INTRO */
- return(hmsga(introtxt));
- if (cx == XXNEW) { /* NEWS */
- int x;
- extern char * k_info_dir;
- x = hmsga(newstxt);
- return(x);
- }
-
-#ifdef OS2ONLY
- if (cx == XXUPD) { /* View UPDATE file */
- extern char exedir[];
- char * pTopic;
- char updstr[2048];
- if ((x = cmtxt("topic name","",&pTopic,xxstring)) < 0)
- return x;
-#ifdef COMMENT
- sprintf(updstr,
- "start view %s\\docs\\k2.inf+%s\\docs\\using_ck.inf+\
-%s\\docs\\dialing.inf+%s\\docs\\modems.inf %s",
- exedir,exedir,exedir,exedir,pTopic
- );
-#else
- if (ckmakxmsg(updstr,
- 2048,
- "start view ",
- exedir,
- "\\docs\\k2.inf+",
- exedir,
- "\\docs\\using_ck.inf+",
- exedir,
- "\\docs\\dialing.inf+",
- exedir,
- "\\docs\\modems.inf ",
- pTopic,
- NULL,
- NULL
- ) > 0)
-#endif /* COMMENT */
- system(updstr);
- return(success = 1);
- }
-#endif /* OS2ONLY */
-#endif /* NOHELP */
-
-#ifndef NOLOCAL
- if (cx == XXHAN) { /* HANGUP */
- if ((x = cmcfm()) < 0) return(x);
-#ifdef NEWFTP
- if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
- return(success = ftpbye());
-#endif /* NEWFTP */
-#ifndef NODIAL
- if ((x = mdmhup()) < 1) {
- debug(F101,"HANGUP mdmup","",x);
-#endif /* NODIAL */
- x = tthang();
- debug(F101,"HANGUP tthang","",x);
- x = (x > -1);
-#ifndef NODIAL
- }
- dialsta = DIA_UNK;
-#endif /* NODIAL */
- whyclosed = WC_CLOS;
- ttchk(); /* In case of CLOSE-ON-DISCONNECT */
- dologend();
-#ifdef OS2
- if (x)
- DialerSend(OPT_KERMIT_HANGUP, 0);
-#endif /* OS2 */
- if (x) haveline = 0;
- return(success = x);
- }
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
- /* INPUT, REINPUT, and MINPUT */
-
- if (cx == XXINP || cx == XXREI || cx == XXMINP) {
- long zz;
- int flags = 0, incount = 0;
- extern int itsapattern, isjoin, isinbuflen;
- int c, getval;
-
- struct FDB sw, nu, fl;
- int fc, havetime = 0;
- char * m;
-
- if (cx == XXREI) {
- m = "Timeout in seconds (ignored)";
- } else {
- m = "Seconds to wait for input,\n or time of day hh:mm:ss,\
- or switch";
- }
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- m, /* helpmsg */
- ckitoa(indef), /* default */
- "", /* addtl string data */
- ninputsw, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- inputsw, /* Keyword table */
- &nu /* Pointer to next FDB */
- );
- cmfdbi(&nu,
- _CMNUM, /* Number */
- m, /* Help message */
- ckitoa(indef), /* default */
- "", /* N/A */
- 10, /* Radix = 10 */
- 0, /* N/A */
- xxstring, /* Processing function */
- NULL, /* N/A */
- &fl /* Next */
- );
- cmfdbi(&fl, /* Time of day hh:mm:ss */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "",
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- fc = (cx == XXREI) ? cmfdb(&nu) : cmfdb(&sw); /* Parse something */
-
- for (y = 0; y < MINPMAX; y++) { /* Initialize search strings */
- mp[y] = 0; /* Assume it's not a pattern */
- if (!mpinited) {
- ms[y] = NULL;
- }
- if (ms[y]) {
- free(ms[y]); /* Free old strings, if any */
- ms[y] = NULL;
- }
- }
- mpinited = 1;
- while (!havetime) {
- if (fc < 0) { /* Error */
- if (fc == -3) {
- printf("?Syntax error in INPUT-class command\n");
- return(-9);
- } else
- return(fc);
- }
- switch (cmresult.fcode) {
- case _CMKEY: /* Switch */
- c = cmgbrk();
- if ((getval = (c == ':' || c == '=')) &&
- !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (getval && cmresult.nresult == INPSW_COU) {
- if ((y = cmnum("Number of bytes to read",
- "",10,&x,xxstring)) < 0)
- return(y);
- incount = x;
- }
- flags |= cmresult.nresult;
- fc = cmfdb(&sw); /* Maybe parse more switches */
- continue;
-
- case _CMNUM: /* Seconds to time out */
- x = cmresult.nresult;
-#ifdef CKFLOAT
- if (inscale != 1.0) /* Scale */
- x *= inscale;
-#endif /* CKFLOAT */
- havetime++;
- break;
-
- case _CMFLD:
- zz = tod2sec(atmbuf); /* Convert to secs since midnight */
- if (zz < 0L) {
- printf("?Number, expression, or time of day required\n");
- return(-9);
- } else {
- char now[32]; /* Current time */
- char *p;
- long tnow;
- p = now;
- ztime(&p);
- tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
- if (zz < tnow) /* User's time before now */
- zz += 86400L; /* So make it tomorrow */
- zz -= tnow; /* Seconds from now. */
- if (zz > -1L) {
- x = zz;
- if (zz != (long) x) {
- printf(
-"Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
-);
- return(-9);
- }
- }
- havetime++;
- }
- break;
- default:
- printf("?Internal error\n");
- return(-9);
- }
- }
- /* Now parse the search text */
-
-#ifdef CK_MINPUT
- if (cx == XXMINP) { /* MINPUT */
- int i, k = 0, n = 0;
- struct stringarray * q;
- keepallchars = 1;
- while (k < MINPMAX) {
- if ((y = cmfld("String or pattern","",&s,xxstring)) < 0) {
- if (y == -3) {
- if ((y = cmcfm()) < 0)
- return(y);
- break;
- } else {
- return(y);
- }
- }
- debug(F111,"MINPUT field",s,k);
- if (isjoin) {
- if ((q = cksplit(1,0,s," ",(char *)c1chars,3,0,0))) {
- char ** ap = q->a_head;
- n = q->a_size;
- debug(F101,"minput cksplit size","",n);
- for (i = 1; i <= n && k < MINPMAX; i++) {
- if (!ap[i]) /* Add non-empty elements */
- continue;
- if (!*(ap[i]))
- continue;
- makestr(&(ms[k]),ap[i]);
- debug(F111,"MINPUT JOIN",ms[k],k);
- k++;
- }
- }
- } else {
- if (s) if (*s) {
- makestr(&(ms[k]),brstrip(s));
- if (itsapattern) mp[k] = 1;
- debug(F111,"MINPUT",ms[k],itsapattern);
- k++;
- }
- }
- }
- keepallchars = 0;
- } else {
-#endif /* CK_MINPUT */
-
- /* INPUT or REINPUT */
-
- if (flags & INPSW_COU) {
- if ((y = cmcfm()) < 0)
- return(y);
- } else {
- if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
- return(y);
- }
- mp[0] = itsapattern ? 1 : 0;
- makestr(&(ms[0]),brstrip(s));
- ms[1] = NULL;
-
-#ifdef CK_MINPUT
- }
-#endif /* CK_MINPUT */
-
- if (incount > 0) /* No searching if /COUNT: given */
- makestr(&(ms[0]),NULL);
-
- if (cx == XXINP || cx == XXMINP) { /* Not REINPUT... */
- i_active = 1;
- /* Go try to input the search string */
- success = doinput(x,ms,mp,flags,incount);
- i_active = 0;
- } else { /* REINPUT */
- success = doreinp(x,ms[0],itsapattern);
- }
- if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */
- popclvl(); /* If so, pop command level. */
- if (pflag && cmdlvl == 0) {
- if (cx == XXINP) printf("?INPUT timed out\n");
- if (cx == XXMINP) printf("?MINPUT timed out\n");
- if (cx == XXREI) printf("?REINPUT failed\n");
- }
- }
- return(success); /* Return do(re)input's return code */
- }
-
-#endif /* NOSPL */
-
- if (cx == XXLOG) { /* LOG */
- x = cmkey(logtab,nlog,"What to log","",xxstring);
- if (x == -3) {
- printf("?Type of log required\n");
- return(-9);
- }
- if (x < 0) return(x);
- x = dolog(x);
- if (x < 0)
- return(x);
- else
- return(success = x);
- }
-
- if (cx == XXLOGIN) { /* (REMOTE) LOGIN */
-#ifdef NEWFTP
- if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
- return(success = doftpusr());
-#endif /* NEWFTP */
-#ifdef IKSD
- if (inserver) {
- printf("?Already logged in\n");
- return(-9);
- } else
-#endif /* IKSD */
- {
-#ifdef NOXFER
- return(-2);
-#else
- return(dormt(XZLGI));
-#endif /* NOXFER */
- }
- }
- if (cx == XXLOGOUT) { /* (REMOTE) LOGOUT */
-#ifdef NEWFTP
- if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
- return(success = doftpres());
-#endif /* NEWFTP */
-
-#ifdef IKSD
- if (inserver) {
- if ((x = cmcfm()) < 0)
- return(x);
- doexit(GOOD_EXIT,xitsta);
- } else
-#endif /* IKSD */
- if (!local || (network && ttchk() < 0)) {
- printf("?No connection.\n");
- return(-9);
- } else {
-#ifdef NOXFER
- return(-2);
-#else
- return(dormt(XZLGO));
-#endif /* NOXFER */
- }
- }
-
-#ifndef NOSCRIPT
- if (cx == XXLOGI) { /* UUCP-style script */
- if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
- return(x);
-#ifdef CK_APC
- if ((apcactive == APC_LOCAL) ||
- ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
- return(success = 0);
-#endif /* CK_APC */
-#ifdef VMS
- conres(); /* For Ctrl-C to work... */
-#endif /* VMS */
- return(success = dologin(s)); /* Return 1=completed, 0=failed */
- }
-#endif /* NOSCRIPT */
-
-#ifndef NOXFER
-#ifdef PIPESEND
- if (cx == XXCREC) { /* CRECEIVE */
- if (protocol != PROTO_K) {
- printf("?Sorry, CRECEIVE works only with Kermit protocol\n");
- return(-9);
- } else
- return(doxget(cx));
- }
- if (cx == XXCGET) { /* CGET */
- return(doxget(cx));
- }
-#endif /* PIPESEND */
-
- if (cx == XXREC) /* RECEIVE */
- return(doxget(cx));
-#endif /* NOXFER */
-
-#ifndef NOXFER
- if (cx == XXREM) { /* REMOTE */
-#ifdef NEWFTP
- if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
- return(doftprmt(0,0));
-#endif /* NEWFTP */
-#ifdef CK_XYZ
- if (protocol != PROTO_K) {
- printf("Sorry, REMOTE commands only work with Kermit protocol\n");
- return(-9);
- }
-#endif /* CK_XYZ */
- x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
- if (x == -3) {
- printf("?You must specify a command for the remote server\n");
- return(-9);
- }
- return(dormt(x));
- }
-#endif /* NOXFER */
-
-#ifndef NORENAME
-#ifndef NOFRILLS
- if (cx == XXREN || cx == XXLREN) { /* RENAME */
-#ifdef LOCUS
- if (!locus && cx != XXLREN) {
-#ifdef NOXFER
- return(-2);
-#else
- return(dormt(XZREN));
-#endif /* NOXFER */
- }
-#endif /* LOCUS */
-#ifdef IKSD
- if (inserver && (!ENABLED(en_ren)
-#ifdef CK_LOGIN
- || isguest
-#endif /* CK_LOGIN */
- )) {
- printf("?Sorry, renaming of files is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- if ((apcactive == APC_LOCAL) ||
- ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
- return(success = 0);
-#endif /* CK_APC */
- return(dorenam());
- }
-#endif /* NOFRILLS */
-#endif /* NORENAME */
-
- if (cx == XXEIGHT) { /* EIGHTBIT */
- extern int parity, cmask, cmdmsk;
- if ((x = cmcfm()) < 0)
- return(x);
- parity = 0;
- cmask = 0xff;
- cmdmsk = 0xff;
- return(success = 1);
- }
-
-#ifndef NOXFER
-/* SEND, CSEND, MOVE, MAIL, and RESEND use the new common code */
-
- if (cx == XXSEN /* SEND */
-#ifdef PIPESEND
- || cx == XXCSEN /* CSEND */
-#endif /* PIPESEND */
- || cx == XXMOVE /* MOVE */
- || cx == XXMAI /* MAIL */
-#ifdef CK_RESEND
- || cx == XXRSEN /* RESEND */
-#endif /* CK_RESEND */
- ) {
-#ifdef IKSD
- if (inserver && !ENABLED(en_get)) {
- printf("?Sorry, sending files is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
- return(doxsend(cx));
- }
-
-/* PSEND, ADD, and REMOVE use special parsing */
-
-#ifdef ADDCMD
- /* ADD and REMOVE */
- if (cx == XXADD || cx == XXREMV) {
- char * m;
- m = (cx == XXADD) ? "Add to which list?" : "Remove from which list?";
- x = cmkey(addtab,naddtab,m,"",xxstring);
- if (x < 0)
- return(x);
-#ifndef NOMSEND
- if (x == ADD_SND)
- return(addsend(cx));
- else
-#endif /* NOMSEND */
- return(doadd(cx,x));
- }
-#endif /* ADDCMD */
-
-#ifdef CK_RESEND
- if (cx == XXPSEN) { /* PSEND */
- int seekto = 0; /* FIX THIS */
-
- cmarg = cmarg2 = "";
- x = cmifi("File to partially send", "", &s, &y, xxstring);
- if (x < 0) {
- if (x == -3) {
- printf("?A file specification is required\n");
- return(-9);
- } else return(x);
- }
- nfils = -1; /* Files come from internal list. */
-#ifndef NOMSEND
- addlist = 0; /* Don't use SEND-LIST. */
- filenext = NULL;
-#endif /* NOMSEND */
- ckstrncpy(line,s,LINBUFSIZ); /* Save copy of string just parsed. */
- debug(F110,"PSEND line",line,0);
- if (y != 0) {
- printf("?Sorry, wildcards not permitted in this command\n");
- return(-9);
- }
- if (sizeof(int) < 4) {
- printf("?Sorry, this command needs 32-bit integers\n");
- return(-9);
- }
- x = cmnum("starting position (byte number)",
- "",10,&seekto,xxstring);
- if (x < 0)
- return(x);
- zfnqfp(s,fspeclen,fspec); /* Get full path */
- if ((x = cmtxt("Name to send it with","",&s,NULL)) < 0)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
-
-#ifdef IKSD
- if (inserver && !ENABLED(en_get)) {
- printf("?Sorry, sending files is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
-#ifdef PIPESEND
- if (sndfilter) {
- printf("?Sorry, no PSEND while SEND FILTER selected\n");
- return(-9);
- }
-#endif /* PIPESEND */
-#ifdef CK_XYZ
- if ((protocol == PROTO_X || protocol == PROTO_XC)) {
- printf("Sorry, PSEND works only with Kermit protocol\n");
- return(-9);
- }
-#endif /* CK_XYZ */
-
- cmarg2 = brstrip(tmpbuf); /* Strip braces */
- cmarg = line; /* File to send */
- debug(F110,"PSEND filename",cmarg,0);
- debug(F110,"PSEND as-name",cmarg2,0);
- sendstart = seekto;
- sstate = 's'; /* Set start state to SEND */
-#ifndef NOMSEND
- addlist = 0;
- filenext = NULL;
-#endif /* NOMSEND */
- sendmode = SM_PSEND;
-#ifdef MAC
- what = W_SEND;
- scrcreate();
-#endif /* MAC */
- if (local) { /* If in local mode, */
- displa = 1; /* enable file transfer display */
- }
- return(0);
- }
-#endif /* CK_RESEND */
-#endif /* NOXFER */
-
-#ifndef NOXFER
-#ifndef NOMSEND
- if (cx == XXMSE || cx == XXMMOVE) {
-#ifdef NEWFTP
- if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
- return(doftpput(cx,0));
-#endif /* NEWFTP */
-#ifdef CK_XYZ
- if (protocol == PROTO_X || protocol == PROTO_XC) {
- printf(
-"Sorry, you can only send one file at a time with XMODEM protocol\n"
- );
- return(-9);
- }
-#endif /* CK_XYZ */
- return(doxsend(cx));
- }
-
-#ifdef COMMENT /* (moved to doxsend) */
- if (cx == XXMSE || cx == XXMMOVE) { /* MSEND and MMOVE commands */
- nfils = 0; /* Like getting a list of */
- lp = line; /* files on the command line */
- addlist = 0; /* Do not use SEND-LIST */
- filenext = NULL; /* Ditto ! */
-
- while (1) {
- char *p;
- if ((x = cmifi("Names of files to send, separated by spaces","",
- &s,&y,xxstring)) < 0) {
- if (x == -3) {
- if (nfils <= 0) {
- printf("?A file specification is required\n");
- return(-9);
- } else break;
- }
- return(x);
- }
- msfiles[nfils++] = lp; /* Got one, count it, point to it, */
- p = lp; /* remember pointer, */
- while (*lp++ = *s++) /* and copy it into buffer */
- if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
- printf("?MSEND list too long\n");
- line[0] = NUL;
- return(-9);
- }
- debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
- if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
-#ifdef ZFNQFP
- zfnqfp(p,TMPBUFSIZ,tmpbuf);
- p = tmpbuf;
-#endif /* ZFNQFP */
- if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
- strcat(fspec,p); /* safe */
- strcat(fspec," "); /* safe */
- } else printf("WARNING - \\v(filespec) buffer overflow\n");
- }
- cmlist = msfiles; /* Point cmlist to pointer array */
- cmarg2 = ""; /* No internal expansion list (yet) */
- sndsrc = nfils; /* Filenames come from cmlist */
- sendmode = SM_MSEND; /* Remember this kind of SENDing */
- sstate = 's'; /* Set start state for SEND */
- if (cx == XXMMOVE) /* If MMOVE'ing, */
- moving = 1; /* set this flag. */
-#ifdef MAC
- what = W_SEND;
- scrcreate();
-#endif /* MAC */
- if (local) { /* If in local mode, */
- displa = 1; /* turn on file transfer display */
- ttflui(); /* and flush tty input buffer. */
- }
- return(0);
- }
-#endif /* COMMENT */
-#endif /* NOMSEND */
-#endif /* NOXFER */
-
-#ifndef NOSERVER
- if (cx == XXSER) { /* SERVER */
-#ifdef CK_XYZ
- if (protocol != PROTO_K) {
- printf("Sorry, SERVER only works with Kermit protocol\n");
- return(-9);
- }
-#endif /* CK_XYZ */
-#ifdef COMMENT
-/*
- Parse for time limit, but since we don't use it yet,
- the parsing is commented out.
-*/
- x_ifnum = 1; /* Turn off internal complaints */
- y = cmnum("optional time limit, seconds, or time of day as hh:mm:ss",
- "0", 10, &x, xxstring
- );
- x_ifnum = 0;
- if (y < 0) {
- if (y == -2) { /* Invalid number or expression */
- zz = tod2sec(atmbuf); /* Convert to secs since midnight */
- if (zz < 0L) {
- printf("?Number, expression, or time of day required\n");
- return(-9);
- } else {
- char now[32]; /* Current time */
- char *p;
- long tnow;
- p = now;
- ztime(&p);
- tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
- if (zz < tnow) /* User's time before now */
- zz += 86400L; /* So make it tomorrow */
- zz -= tnow; /* Seconds from now. */
- }
- } else
- return(y);
- }
- if (zz > -1L) {
- x = zz;
- if (zz != (long) x) {
- printf(
-"Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
- );
- return(-9);
- }
- }
- if (x < 0)
- x = 0;
-#endif /* COMMENT */
-
- if ((x = cmcfm()) < 0) return(x);
- sstate = 'x';
-#ifdef MAC
- what = W_RECV;
- scrcreate();
-#endif /* MAC */
- if (local) displa = 1;
-#ifdef AMIGA
- reqoff(); /* No DOS requestors while server */
-#endif /* AMIGA */
- return(0);
- }
-#endif /* NOSERVER */
-
- if (cx == XXSAVE) { /* SAVE command */
- x = cmkey(savtab,nsav,"option","keymap",xxstring);
- if (x == -3) {
- printf("?You must specify an option to save\n");
- return(-9);
- }
- if (x < 0) return(x);
- /* have to set success separately for each item in doprm()... */
- /* actually not really, could have just had doprm return 0 or 1 */
- /* and set success here... */
- y = dosave(x);
- if (y == -3) {
- printf("?More fields required\n");
- return(-9);
- } else return(y);
- }
-
- if (cx == XXSET) { /* SET command */
- x = cmkey(prmtab,nprm,"Parameter","",xxstring);
- if (x == -3) {
- printf("?You must specify a parameter to set\n");
- return(-9);
- }
- if (x < 0) return(x);
- /* have to set success separately for each item in doprm()... */
- /* actually not really, could have just had doprm return 0 or 1 */
- /* and set success here... */
- y = doprm(x,0);
- if (y == -3) {
- printf("?More fields required\n");
- return(-9);
- } else return(y);
- }
-
-#ifndef NOPUSH
- if (cx == XXSHE /* SHELL (system) command */
- || cx == XXEXEC /* exec() */
- ) {
- int rx = 0;
- char * p = NULL;
- int i /* ,n */ ;
-#ifdef UNIXOROSK
- char * args[256];
-#endif /* UNIXOROSK */
-
-#ifdef IKSD
- if (inserver && (nopush || !ENABLED(en_hos))) {
- printf("?Sorry, host command access is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
-
-#ifdef CKEXEC
- if (cx == XXEXEC) { /* EXEC (overlay ourselves) */
- struct FDB sw, fl;
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Command to overlay C-Kermit\n or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 1, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- redirsw, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* 2nd FDB - command to exec */
- _CMFLD, /* fcode */
- "Command to overlay C-Kermit", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL /* No more after this */
- );
- while (1) {
- x = cmfdb(&sw); /* Parse something */
- debug(F101,"exec cmfdb","",x);
- if (x < 0)
- return(x);
- /* Generalize this if we add more switches */
- if (cmresult.fcode == _CMKEY) {
- rx = 1;
- continue;
- }
- if (cmresult.fcode == _CMFLD)
- break;
- return(-2);
- }
- ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
- if (!tmpbuf[0]) {
- printf("?Command required\n");
- return(-9);
- }
- p = brstrip(tmpbuf);
- args[0] = NULL; /* Set argv[0] to it */
- makestr(&args[0],p);
- for (i = 1; i < 255; i++) { /* Get arguments for command */
- if ((x = cmfld("Argument","",&s,xxstring)) < 0) {
- if (x == -3) {
- if ((x = cmcfm()) < 0)
- return(x);
- break;
- } else
- return(x);
- }
- args[i] = NULL;
- s = brstrip(s);
- makestr(&args[i],s);
- }
- args[i] = NULL;
- } else {
-#endif /* CKEXEC */
- if ((x = cmtxt("System command to execute","",&s,xxstring)) < 0)
- return(x);
-#ifdef CKEXEC
- }
-#endif /* CKEXEC */
- if (nopush)
- return(success = 0);
-#ifdef CK_APC
- if (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
- return(success = 0);
-#endif /* CK_APC */
- conres(); /* Make console normal */
-#ifdef OS2
- if (!(s && *s)) {
- os2push();
- return(success = 1);
- } else
-#endif /* OS2 */
- if (cx == XXSHE) {
- x = zshcmd(s);
- debug(F101,"RUN zshcmd code","",x);
- concb((char)escape);
- return(success = x);
-#ifdef CKEXEC
- } else {
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"EXEC cmd",p,0);
- for (i = 0; i < 256 && args[i]; i++)
- debug(F111,"EXEC arg",args[i],i);
- }
-#endif /* DEBUG */
- if (p) {
- z_exec(p,args,rx); /* Overlay ourself */
- debug(F100,"EXEC fails","",0);
- concb((char)escape); /* In case it returns */
- }
- return(success = 0);
-#endif /* CKEXEC */
- }
- }
-
-#ifdef CK_REDIR
- if (cx == XXFUN) { /* REDIRECT */
-#ifdef CK_APC
- if ((apcactive == APC_LOCAL) ||
- ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
- return(success = 0);
-#endif /* CK_APC */
- ckmakmsg(tmpbuf,
- TMPBUFSIZ,
- "Local command to run,\n",
- "with its standard input/output redirected to ",
- local ? ttname : "the communications connection",
- "\n"
- );
- if ((x = cmtxt(tmpbuf,"",&s,xxstring)) < 0)
- return(x);
- if (nopush) {
- printf("?REDIRECT disabled\n");
- return(success=0);
- }
- if (!local) {
- printf("?SET LINE or SET HOST required first\n");
- return(-9);
- }
- if (!*s) {
- printf("?REDIRECT requires a command to redirect\n");
- return(-9);
- }
- return(success = ttruncmd(s));
- }
-#endif /* CK_REDIR */
-#endif /* NOPUSH */
-
-#ifndef NOSHOW
- if (cx == XXSHO) { /* SHOW */
- x = cmkey(shotab,nsho,"","parameters",xxstring);
- if (x < 0) return(x);
- return(doshow(x));
- }
-#endif /* NOSHOW */
-
-#ifndef MAC
- if (cx == XXSPA) { /* SPACE */
-#ifdef IKSD
- if (inserver && !ENABLED(en_spa)) {
- printf("?Sorry, SPACE command disabled\n");
- return(-9);
- }
-#endif /* IKSD */
-#ifdef datageneral
- /* AOS/VS can take an argument after its "space" command. */
- if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
- return(x);
- if (nopush) {
- printf("?Sorry, SPACE command disabled\n");
- return(-9);
- } else if (*s == NUL) {
- xsystem(SPACMD);
- } else {
- ckmakmsg(line,LINBUFSIZ,"space ",s,NULL,NULL);
- xsystem(line);
- }
-#else
-#ifdef OS2
- if ((x = cmtxt("Press Enter for current disk,\n\
- or specify a disk letter like A:","",&s,xxstring)) < 0)
- return(x);
- if (*s == NUL) { /* Current disk */
- unsigned long space = zdskspace(0);
- if (space > 0 && space < 1024)
- printf(" Free space: unknown\n");
- else
- printf(" Free space: %ldK\n", space/1024L);
- } else {
- int drive = toupper(*s);
- unsigned long space = zdskspace(drive - 'A' + 1);
- if (space > 0 && space < 1024)
- printf(" Drive %c: unknown free\n");
- else
- printf(" Drive %c: %ldK free\n", drive,space / 1024L);
- }
-#else
-#ifdef UNIXOROSK
- x = cmdir("Confirm for current disk,\n\
- or specify a disk device or directory","",&s,xxstring);
- if (x == -3)
- s = "";
- else if (x < 0)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- s = tmpbuf;
- if ((x = cmcfm()) < 0) return(x);
- if (nopush) {
- printf("?Sorry, SPACE command disabled\n");
- return(-9);
- }
- if (!*s) { /* Current disk */
- xsystem(SPACMD);
- } else { /* Specified disk */
- ckmakmsg(line,LINBUFSIZ,SPACM2," ",s,NULL);
- xsystem(line);
- }
-#else
- if ((x = cmcfm()) < 0) return(x);
- if (nopush) {
- printf("?Sorry, SPACE command disabled\n");
- return(-9);
- }
- xsystem(SPACMD);
-#endif /* UNIXOROSK */
-#endif /* OS2 */
-#endif /* datageneral */
- return(success = 1); /* Pretend it worked */
- }
-#endif /* MAC */
-
-#ifndef NOXFER
- if (cx == XXSTA) { /* STATISTICS */
- if ((x = cmkey(stattab,2,"Carriage return, or option",
- "/brief",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- return(success = dostat(x));
- }
-#endif /* NOXFER */
-
- if (cx == XXSTO || cx == XXEND) { /* STOP, END, or POP */
- if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
- return(y);
- if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
- return(y);
- s = brstrip(s);
- if (*s) printf("%s\n",s);
- if (cx == XXSTO) {
- dostop();
- } else {
- doend(x);
- }
- return(success = (x == 0));
- }
- if (cx == XXSUS) { /* SUSPEND */
- if ((y = cmcfm()) < 0) return(y);
-#ifdef NOJC
- printf("Sorry, this version of Kermit cannot be suspended\n");
-#else
-#ifdef IKSD
- if (inserver) {
- printf("?Sorry, IKSD can not be suspended\n");
- return(-9);
- } else
-#endif /* IKSD */
- if (nopush) {
- printf("?Sorry, access to system is disabled\n");
- return(-9);
- }
- stptrap(0);
-#endif /* NOJC */
- return(0);
- }
-
- if (cx == XXTAK) { /* TAKE */
- char * scriptenv = NULL;
-#ifdef OS2
- char * GetAppData(int);
- extern char startupdir[],exedir[],inidir[];
- char * keymapenv = NULL;
- char * appdata0 = NULL, *appdata1 = NULL;
- int xx;
-#define TAKEPATHLEN 4096
-#else /* OS2 */
-#define TAKEPATHLEN 1024
-#endif /* OS2 */
- char takepath[TAKEPATHLEN];
-
- if (tlevel >= MAXTAKE-1) {
- printf("?Take files nested too deeply\n");
- return(-9);
- }
-#ifdef OS2
-#ifdef NT
- scriptenv = getenv("K95SCRIPTS");
- keymapenv = getenv("K95KEYMAPS");
- makestr(&appdata0,(char *)GetAppData(0));
- makestr(&appdata1,(char *)GetAppData(1));
-#else /* NT */
- scriptenv = getenv("K2SCRIPTS");
- keymapenv = getenv("K2KEYMAPS");
-#endif /* NT */
-#endif /* OS2 */
-
- if (!scriptenv) /* Let this work for Unix etc too */
- scriptenv = getenv("CK_SCRIPTS"); /* Use this if defined */
-#ifndef OS2
- if (!scriptenv) /* Otherwise use home directory */
- scriptenv = homepath();
-#endif /* OS2 */
- if (!scriptenv)
- scriptenv = "";
- ckstrncpy(takepath,scriptenv,TAKEPATHLEN);
- debug(F110,"TAKE initial takepath",takepath,0);
-
-#ifdef OS2
- if (!keymapenv)
- keymapenv = getenv("CK_KEYMAPS");
- if (!keymapenv)
- keymapenv = "";
-
- ckstrncat(takepath,
- (scriptenv && scriptenv[strlen(scriptenv)-1]==';')?"":";",
- TAKEPATHLEN
- );
- ckstrncat(takepath,keymapenv?keymapenv:"",TAKEPATHLEN);
- ckstrncat(takepath,
- (keymapenv && keymapenv[strlen(keymapenv)-1]==';')?"":";",
- TAKEPATHLEN
- );
- ckstrncat(takepath,startupdir,TAKEPATHLEN);
- ckstrncat(takepath,";",TAKEPATHLEN);
- ckstrncat(takepath,startupdir,TAKEPATHLEN);
- ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
- ckstrncat(takepath,startupdir,TAKEPATHLEN);
- ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
-
- ckstrncat(takepath,appdata1,TAKEPATHLEN);
- ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN);
- ckstrncat(takepath,appdata1,TAKEPATHLEN);
- ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN);
- ckstrncat(takepath,appdata1,TAKEPATHLEN);
- ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN);
-
- ckstrncat(takepath,appdata0,TAKEPATHLEN);
- ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN);
- ckstrncat(takepath,appdata0,TAKEPATHLEN);
- ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN);
- ckstrncat(takepath,appdata0,TAKEPATHLEN);
- ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN);
-
- ckstrncat(takepath,inidir,TAKEPATHLEN);
- ckstrncat(takepath,";",TAKEPATHLEN);
- ckstrncat(takepath,inidir,TAKEPATHLEN);
- ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
- ckstrncat(takepath,inidir,TAKEPATHLEN);
- ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
-
- ckstrncat(takepath,zhome(),TAKEPATHLEN);
- ckstrncat(takepath,";",TAKEPATHLEN);
- ckstrncat(takepath,zhome(),TAKEPATHLEN);
- ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
- ckstrncat(takepath,zhome(),TAKEPATHLEN);
- ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
-
- ckstrncat(takepath,exedir,TAKEPATHLEN);
- ckstrncat(takepath,";",TAKEPATHLEN);
- ckstrncat(takepath,exedir,TAKEPATHLEN);
- ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
- ckstrncat(takepath,exedir,TAKEPATHLEN);
- ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
-#endif /* OS2 */
- debug(F110,"TAKE final takepath",takepath,0);
-
- if ((y = cmifip("Commands from file",
- "",&s,&x,0,takepath,xxstring)) < 0) {
- if (y == -3) {
- printf("?A file name is required\n");
- return(-9);
- } else
- return(y);
- }
- if (x != 0) {
- printf("?Wildcards not allowed in command file name\n");
- return(-9);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- debug(F110,"TAKE file",s,0);
- if (isdir(s)) {
- printf("?Can't execute a directory - \"%s\"\n", s);
- return(-9);
- }
-#ifndef NOTAKEARGS
- {
- char * p;
- x = strlen(line);
- debug(F111,"TAKE args",line,x);
- p = line + x + 1;
- if ((y = cmtxt("Optional arguments","",&s,xxstring)) < 0)
- return(y);
- if (*s) { /* Args given? */
- ckstrncpy(p,s,LINBUFSIZ-x-1);
-#ifdef ZFNQFP
- zfnqfp(line,TMPBUFSIZ,tmpbuf);
- s = tmpbuf;
-#else
- s = line;
-#endif /* ZFNQFP */
- debug(F110,"TAKE filename",s,0);
- x = strlen(s);
- debug(F101,"TAKE new len",s,x);
-
-#ifdef COMMENT
-/*
- This was added in C-Kermit 7.0 to allow args to be passed from the TAKE
- command to the command file. But it overwrites the current argument vector,
- which is at best surprising, and at worst unsafe.
-*/
- addmac("%0",s); /* Define %0 = name of file */
- varnam[0] = '%';
- varnam[2] = '\0';
- debug(F110,"take arg 0",s,0);
- debug(F110,"take args",p,0);
- for (y = 1; y < 10; y++) { /* Clear current args %1..%9 */
- varnam[1] = (char) (y + '0');
- delmac(varnam,0);
- }
- xwords(p,MAXARGLIST,NULL,0); /* Assign new args */
- debug(F110,"take args",p,0);
-#else
-/*
- This method is used in 8.0. If the TAKE command includes arguments, we
- insert an intermediate temporary macro between the current level; we pass
- the arguments to the macro and then the macro TAKEs the command file.
- If the user Ctrl-C's out of the TAKE file, some temporary macro definitions
- and other small malloc'd bits might be left behind.
-*/
- {
- char * q = NULL;
- char * r = NULL;
- int k, m;
- m = maclvl;
- q = (char *)malloc(x+24);
- if (q) {
- r = (char *)malloc(x+24);
- if (r) {
- sprintf(q,"_file[%s](%d)",s,cmdlvl); /* safe */
- sprintf(r,"take %s",s); /* safe */
- k = addmac(q,r);
- if (k > -1) {
- dodo(k,p,0);
- while (maclvl > m) {
- sstate = (CHAR) parser(1);
- if (sstate) proto();
- }
- }
- k = delmac(q,0);
- free(q);
- free(r);
- return(success);
- }
- }
- }
- return(success = 0);
-#endif /* COMMENT */
- }
- }
-#else
- if ((y = cmcfm()) < 0) return(y);
-#endif /* NOTAKEARGS */
- return(success = dotake(line));
- }
-
-#ifndef NOLOCAL
-#ifdef OS2
- if (cx == XXVIEW) { /* VIEW Only Terminal mode */
- viewonly = TRUE;
- success = doconect(0, 0);
- viewonly = FALSE;
- return success;
- }
-#endif /* OS2 */
-
-#ifdef NETCONN
- if (cx == XXTEL || cx == XXIKSD) { /* TELNET */
- int x,z;
-#ifdef OS2
- if (!tcp_avail) {
- printf("?Sorry, either TCP/IP is not available on this system or\n\
-necessary DLLs did not load. Use SHOW NETWORK to check network status.\n");
- success = 0;
- return(-9);
- } else
-#endif /* OS2 */
- {
- x = nettype; /* Save net type in case of failure */
- z = ttnproto; /* Save protocol in case of failure */
- nettype = NET_TCPB;
- ttnproto = (cx == XXTEL) ? NP_TELNET : NP_KERMIT;
- if ((y = setlin(XYHOST,0,1)) <= 0) {
- nettype = x; /* Failed, restore net type. */
- ttnproto = z; /* and protocol */
- success = 0;
- }
- didsetlin++;
- }
- return(y);
- }
-
-#ifndef PTYORPIPE
-#ifdef NETCMD
-#define PTYORPIPE
-#else
-#ifdef NETPTY
-#define PTYORPIPE
-#endif /* NETPTY */
-#endif /* NETCMD */
-#endif /* PTYORPIPE */
-
-#ifdef PTYORPIPE
- if (cx == XXPIPE || cx == XXPTY) { /* PIPE or PTY */
- int x;
- extern int netsave;
- x = nettype; /* Save net type in case of failure */
- nettype = (cx == XXPIPE) ? NET_CMD : NET_PTY;
- if ((y = setlin(XYHOST,0,1)) < 0) {
- nettype = x; /* Failed, restore net type. */
- ttnproto = z; /* and protocol */
- success = 0;
- }
- didsetlin++;
- netsave = x;
- return(y);
- }
-#endif /* PTYORPIPE */
-
-#ifdef ANYSSH
- if (cx == XXSSH) { /* SSH (Secure Shell) */
- extern int netsave;
-#ifdef SSHBUILTIN
- int k, x, havehost = 0, trips = 0;
- int tmpver = -1, tmpxfw = -1;
-#ifndef SSHTEST
- extern int sl_ssh_xfw, sl_ssh_xfw_saved;
- extern int sl_ssh_ver, sl_ssh_ver_saved;
-#endif /* SSHTEST */
- extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
- extern char * slmsg;
- extern char uidbuf[], sl_uidbuf[];
- extern char pwbuf[], * g_pswd;
- extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
- struct FDB sw, kw, fl;
-
- if (ssh_tmpstr)
- memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
- makestr(&ssh_tmpstr,NULL);
- makestr(&ssh_tmpuid,NULL);
- makestr(&ssh_tmpcmd,NULL);
- makestr(&ssh_tmpport,NULL);
-
- cmfdbi(&kw, /* 1st FDB - commands */
- _CMKEY, /* fcode */
- "host [ port ],\n or action", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nsshcmd, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 0 = keyword */
- xxstring, /* Processing function */
- sshkwtab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Host */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
-
- x = cmfdb(&kw);
- if (x == -3) {
- printf("?ssh what?\n");
- return(-9);
- }
- if (x < 0)
- return(x);
- havehost = 0;
- if (cmresult.fcode == _CMFLD) {
- havehost = 1;
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
- cmresult.nresult = XSSH_OPN;
- }
- switch (cmresult.nresult) { /* SSH keyword */
- case XSSH_OPN: /* SSH OPEN */
- if (!havehost) {
- if ((x = cmfld("Host","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- }
- /* Parse [ port ] [ switches ] */
- cmfdbi(&kw, /* Switches */
- _CMKEY,
- "Port number or service name,\nor switch",
- "",
- "",
- nsshopnsw,
- 4,
- xxstring,
- sshopnsw,
- &fl
- );
- cmfdbi(&fl, /* Port number or service name */
- _CMFLD,
- "",
- "",
- "",
- 0,
- 0,
- xxstring,
- NULL,
- NULL
- );
- trips = 0; /* Explained below */
- while (1) { /* Parse port and switches */
- x = cmfdb(&kw); /* Get a field */
- if (x == -3) /* User typed CR so quit from loop */
- break;
- if (x < 0) /* Other parse error, pass it back */
- return(x);
- switch (cmresult.fcode) { /* Field or Keyword? */
- case _CMFLD: /* Field */
- makestr(&ssh_tmpport,cmresult.sresult);
- break;
- case _CMKEY: /* Keyword */
- switch (cmresult.nresult) { /* Which one? */
- case SSHSW_USR: /* /USER: */
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- if ((y = cmfld("Username","",&s,xxstring)) < 0)
- return(y);
- s = brstrip(s);
- makestr(&ssh_tmpuid,s);
- break;
- case SSHSW_PWD:
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- debok = 0;
- if ((x = cmfld("Password","",&s,xxstring)) < 0) {
- if (x == -3) {
- makestr(&ssh_tmpstr,"");
- } else {
- return(x);
- }
- } else {
- s = brstrip(s);
- if ((x = (int)strlen(s)) > PWBUFL) {
- makestr(&slmsg,"Internal error");
- printf("?Sorry, too long - max = %d\n",PWBUFL);
- return(-9);
- }
- makestr(&ssh_tmpstr,s);
- }
- break;
-
- case SSHSW_VER:
- if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
- return(x);
- if (z < 1 || z > 2) {
- printf("?Out of range: %d\n",z);
- return(-9);
- }
- tmpver = z;
- break;
- case SSHSW_CMD:
- case SSHSW_SUB:
- if ((x = cmfld("Text","",&s,xxstring)) < 0)
- return(x);
- makestr(&ssh_tmpcmd,s);
- ssh_cas = (cmresult.nresult == SSHSW_SUB);
- break;
- case SSHSW_X11:
- if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
- return(x);
- tmpxfw = x;
- break;
- default:
- return(-2);
- }
- }
- if (trips++ == 0) { /* After first time through */
- cmfdbi(&kw, /* only parse switches, not port. */
- _CMKEY,
- "Switch",
- "",
- "",
- nsshopnsw,
- 4,
- xxstring,
- sshopnsw,
- NULL
- );
- }
- }
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
- if (clskconnx(1) < 0) { /* Close current Kermit connection */
- if ( ssh_tmpstr ) {
- memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
- makestr(&ssh_tmpstr,NULL);
- }
- return(success = 0);
- }
- makestr(&ssh_hst,line); /* Stash everything */
- if (ssh_tmpuid) {
- if (!sl_uid_saved) {
- ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
- sl_uid_saved = 1;
- }
- ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
- makestr(&ssh_tmpuid,NULL);
- }
- if (ssh_tmpport) {
- makestr(&ssh_prt,ssh_tmpport);
- makestr(&ssh_tmpport,NULL);
- } else
- makestr(&ssh_prt,NULL);
-
- if (ssh_tmpcmd) {
- makestr(&ssh_cmd,brstrip(ssh_tmpcmd));
- makestr(&ssh_tmpcmd,NULL);
- } else
- makestr(&ssh_cmd,NULL);
-
- if (tmpver > -1) {
-#ifndef SSHTEST
- if (!sl_ssh_ver_saved) {
- sl_ssh_ver = ssh_ver;
- sl_ssh_ver_saved = 1;
- }
-#endif /* SSHTEST */
- ssh_ver = tmpver;
- }
- if (tmpxfw > -1) {
-#ifndef SSHTEST
- if (!sl_ssh_xfw_saved) {
- sl_ssh_xfw = ssh_xfw;
- sl_ssh_xfw_saved = 1;
- }
-#endif /* SSHTEST */
- ssh_xfw = tmpxfw;
- }
- if (ssh_tmpstr) {
- if (ssh_tmpstr[0]) {
- ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
- pwflg = 1;
- pwcrypt = 0;
- } else
- pwflg = 0;
- makestr(&ssh_tmpstr,NULL);
- }
- nettype = NET_SSH;
- if (mdmsav < 0)
- mdmsav = mdmtyp;
- mdmtyp = -nettype;
- x = 1;
-
-#ifndef NOSPL
- makestr(&g_pswd,pwbuf); /* Save global pwbuf */
- g_pflg = pwflg; /* and flag */
- g_pcpt = pwcrypt;
-#endif /* NOSPL */
-
- /* Line parameter to ttopen() is ignored */
- debug(F110,"SSH line",line,0);
- k = ttopen(line,&x,mdmtyp, 0);
- if (k < 0) {
- printf("?Unable to connect to %s\n",ssh_hst);
- mdmtyp = mdmsav;
- slrestor();
- return(success = 0);
- }
- duplex = 0; /* Remote echo */
- ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
- debug(F110,"ssh ttname",ttname,0);
- makestr(&slmsg,NULL); /* No SET LINE error message */
- cxtype = CXT_SSH;
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#endif /* NODIAL */
- success = 1; /* SET LINE succeeded */
- network = 1; /* Network connection (not serial) */
- local = 1; /* Local mode (not remote) */
- if ((reliable != SET_OFF || !setreliable))
- reliable = SET_ON; /* Transport is reliable end to end */
-#ifdef OS2
- DialerSend(OPT_KERMIT_CONNECT, 0);
-#endif /* OS2 */
- setflow(); /* Set appropriate flow control */
-
- haveline = 1;
-#ifdef CKLOGDIAL
-#ifdef NETCONN
- dolognet();
-#endif /* NETCONN */
-#endif /* CKLOGDIAL */
-
-#ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ssh_hst,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
-#endif /* NOSPL */
-#ifdef LOCUS
- if (autolocus)
- setlocus(1,1);
-#endif /* LOCUS */
-
- /* Command was confirmed so we can pre-pop command level. */
- /* This is so CONNECT module won't think we're executing a */
- /* script if CONNECT was the final command in the script. */
- if (cmdlvl > 0)
- prepop();
- success = doconect(0,cmdlvl == 0 ? 1 : 0);
- if (ttchk() < 0)
- dologend();
- return(success);
-
- case XSSH_CLR:
- if ((y = cmkey(sshclr,nsshclr,"","", xxstring)) < 0) {
- if (y == -3) {
- printf("?clear what?\n");
- return(-9);
- }
- return(y);
- }
- if ((x = cmcfm()) < 0)
- return(x);
- switch (y) {
- case SSHC_LPF:
- ssh_pf_lcl_n = 0;
- break;
- case SSHC_RPF:
- ssh_pf_rmt_n = 0;
- break;
- default:
- return(-2);
- }
- return(success = 1); /* or whatever */
-
- case XSSH_AGT: { /* SSH AGENT */
- int doeach = 0;
- if ((y = cmkey(sshagent,nsshagent,"","",xxstring)) < 0)
- return(y);
- switch (y) {
- case SSHA_ADD: /* SSH AGENT ADD ... */
- if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) {
-#ifndef SSHTEST
- if (x == -3) /* No name given */
- doeach = 1; /* so do them all */
- else
-#endif /* SSHTEST */
- return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmcfm()) < 0)
- return(x);
-#ifdef SSHTEST
- x = 0;
-#else
- if (doeach) {
- int i;
- x = 0;
- for (i = 0; i < ssh_idf_n; i++)
- x += ssh_agent_add_file(ssh_idf[i]);
- } else
- x = ssh_agent_add_file(line);
-#endif /* SSHTEST */
- return(success = (x == 0));
-
- case SSHA_DEL: { /* SSH AGENT DELETE ... */
- int doall = 0;
- if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) {
-#ifndef SSHTEST
- if (x == -3) /* No name given */
- doall = 1; /* so do them all */
- else
-#endif /* SSHTEST */
- return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmcfm()) < 0)
- return(x);
-#ifdef SSHTEST
- x = 0;
-#else
- if (doall)
- x = ssh_agent_delete_all();
- else
- x = ssh_agent_delete_file(line);
-#endif /* SSHTEST */
- return(success = (x == 0));
- }
- case SSHA_LST: {
- int fingerprint = 0;
- if ((y = cmswi(sshagtsw,nsshagtsw,"","",xxstring)) < 0) {
- if (y != -3)
- return(y);
- } else if (cmgbrk() > SP) {
- printf("?This switch does not take an argument\n");
- return(-9);
- } else if (y == SSHASW_FP) {
- fingerprint = 1;
- }
- if ((x = cmcfm()) < 0)
- return(x);
-#ifdef SSHTEST
- return(success = 1);
-#else
- return(success =
- (ssh_agent_list_identities(fingerprint) == 0));
-#endif /* SSHTEST */
- }
- default:
- return(-2);
- }
- }
- case XSSH_ADD: { /* SSH ADD */
- /* ssh add { local, remote } port host port */
- int cx, i, j, k;
- char * h;
- if ((cx = cmkey(addfwd,naddfwd,"","", xxstring)) < 0)
- return(cx);
- if ((x = cmnum((cx == SSHF_LCL) ?
- "Local port number" : "Remote port number",
- "",10,&j,xxstring)) < 0)
- return(x);
- if ((x = cmfld("Host","",&s,xxstring)) < 0)
- return(x);
- makestr(&h,s);
- if ((x = cmnum("Port","",10,&k,xxstring)) < 0)
- return(x);
- if ((x = cmcfm()) < 0)
- return(x);
-
- switch(cx) {
- case SSHF_LCL:
- if (ssh_pf_lcl_n == 32) {
- printf(
-"?Maximum number of local port forwardings already specified\n"
- );
- free(h);
- return(success = 0);
- }
- ssh_pf_lcl[ssh_pf_lcl_n].p1 = j;
- makestr(&(ssh_pf_lcl[ssh_pf_lcl_n].host),h);
- makestr(&h,NULL);
- ssh_pf_lcl[ssh_pf_lcl_n].p2 = k;
- ssh_pf_lcl_n++;
- break;
- case SSHF_RMT:
- if (ssh_pf_rmt_n == 32) {
- printf(
-"?Maximum number of remote port forwardings already specified\n"
- );
- free(h);
- return(success = 0);
- }
- ssh_pf_rmt[ssh_pf_rmt_n].p1 = j;
- makestr(&(ssh_pf_rmt[ssh_pf_rmt_n].host),h);
- makestr(&h,NULL);
- ssh_pf_rmt[ssh_pf_rmt_n].p2 = k;
- ssh_pf_rmt_n++;
- }
- return(success = 1);
- }
- /* Not supporting arbitrary forwarding yet */
- case XSSH_FLP: /* SSH FORWARD-LOCAL-PORT */
- case XSSH_FRP: { /* SSH FORWARD-REMOTE-PORT */
- int li_port = 0;
- int to_port = 0;
- char * fw_host = NULL;
- int n;
- if ((x = cmnum(cmresult.nresult == XSSH_FLP ?
- "local-port":"remote-port",
- "",10,&li_port,xxstring)) < 0)
- return(x);
- if (li_port < 1 || li_port > 65535) {
- printf("?Out range - min: 1, max: 65535\n");
- return(-9);
- }
- if ((x = cmfld("host",ssh_hst?ssh_hst:"",&s,xxstring)) < 0)
- return(x);
- n = ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- fw_host = tmpbuf;
- if ((x = cmnum("host-port",ckuitoa(li_port),10,
- &to_port,xxstring)) < 0)
- return(x);
- if (to_port < 1 || to_port > 65535) {
- printf("?Out range - min: 1, max: 65535\n");
- return(-9);
- }
- if ((x = cmcfm()) < 0)
- return(x);
- switch (cmresult.nresult) {
- case XSSH_FLP: /* SSH FORWARD-LOCAL-PORT */
-#ifndef SSHTEST
- ssh_fwd_local_port(li_port,fw_host,to_port);
-#endif /* SSHTEST */
- return(success = 1);
- case XSSH_FRP: /* SSH FORWARD-REMOTE-PORT */
-#ifndef SSHTEST
- ssh_fwd_remote_port(li_port,fw_host,to_port);
-#endif /* SSHTEST */
- return(success = 1);
- }
- return(success = 1);
- }
- case XSSH_V2: /* SSH V2 */
- if ((cx = cmkey(ssh2tab,nssh2tab,"","", xxstring)) < 0)
- return(cx);
- switch (cx) {
- case XSSH2_RKE:
- if ((x = cmcfm()) < 0)
- return(x);
-#ifndef SSHTEST
- ssh_v2_rekey();
-#endif /* SSHTEST */
- return(success = 1);
- default:
- return(-2);
- }
- case XSSH_KEY:
- if ((cx = cmkey(sshkey,nsshkey,"","", xxstring)) < 0)
- return(cx);
- switch (cx) {
- case SSHK_PASS: { /* Change passphrase */
- char * oldp = NULL, * newp = NULL;
- struct FDB df, sw;
- cmfdbi(&sw,
- _CMKEY, /* fcode */
- "Filename, or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 2, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- sshkpsw, /* Keyword table */
- &df /* Pointer to next FDB */
- );
- cmfdbi(&df, /* 2nd FDB - file for display */
- _CMIFI, /* output file */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- line[0] = NUL;
-
- while (1) {
- x = cmfdb(&sw);
- if (x == -3) break;
- if (x < 0)
- return(x);
- if (cmresult.fcode != _CMKEY)
- break;
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- if ((y = cmfld("Passphrase","",&s,xxstring)) < 0)
- return(y);
- switch (cmresult.nresult) {
- case 1: /* Old */
- makestr(&oldp,s);
- break;
- case 2: /* New */
- makestr(&newp,s);
- }
- }
- if (cmresult.fcode == _CMIFI) { /* Filename */
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
- ckstrncpy(line,tmpbuf,LINBUFSIZ);
- }
- if ((x = cmcfm()) < 0) return(x);
-
-#ifndef SSHTEST
- x = sshkey_change_passphrase(line[0] ? line : NULL,
- oldp, newp);
-#endif /* SSHTEST */
- makestr(&oldp,NULL);
- makestr(&newp,NULL);
- success = (x == 0);
- return(success);
- }
- case SSHK_CREA: { /* SSH KEY CREATE /switches... */
- int bits = 1024, keytype = SSHKT_2R;
- char * pass = NULL, * comment = NULL;
- struct FDB df, sw;
-
- /*
- * char * sshkey_default_file(int keytype)
- * will provide the default filename for a given keytype
- * is it possible to have the default value for the 2nd
- * FDB set and changed when a /TYPE switch is provided?
- * Would this allow for tab completion of the filename?
- */
- cmfdbi(&sw,
- _CMKEY, /* fcode */
- "Filename, or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nsshkcrea, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- sshkcrea, /* Keyword table */
- &df /* Pointer to next FDB */
- );
- cmfdbi(&df, /* 2nd FDB - file for display */
- _CMOFI, /* output file */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- line[0] = NUL;
-
- while (1) {
- x = cmfdb(&sw);
- if (x == -3) break;
- if (x < 0)
- return(x);
- if (cmresult.fcode != _CMKEY)
- break;
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (cmresult.nresult) {
- case SSHKC_BI: /* /BITS:n */
- if ((y = cmnum("","1024",10,&z,xxstring)) < 0)
- return(y);
- if (z < 512 || z > 4096) {
- printf("?Out range - min: 512, max: 4096\n");
- return(-9);
- }
- bits = z;
- break;
- case SSHKC_PP: /* /PASSPHRASE:blah */
- if ((y = cmfld("Passphrase","",&s,xxstring)) < 0)
- return(y);
- makestr(&pass,s);
- break;
- case SSHKC_TY: /* /TYPE:keyword */
- if ((y = cmkey(sshkcty,nsshkcty,"",
- "v2-rsa",xxstring)) < 0)
- return(y);
- keytype = y;
- break;
- case SSHKC_1R: /* /COMMENT */
- if ((y = cmfld("Text","",&s,xxstring)) < 0)
- return(y);
- makestr(&comment,s);
- break;
- }
- }
- if (cmresult.fcode == _CMOFI) { /* Filename */
- if (cmresult.sresult) {
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
- ckstrncpy(line,tmpbuf,LINBUFSIZ);
- }
- }
- if ((y = cmcfm()) < 0) /* Confirm */
- return(y);
-#ifndef SSHTEST
- x = sshkey_create(line[0] ? line : NULL,
- bits, pass, keytype, comment);
- if (pass)
- memset(pass,0,strlen(pass));
-#endif /* SSHTEST */
- makestr(&pass,NULL);
- makestr(&comment,NULL);
- return(success = (x == 0));
- }
- case SSHK_DISP: { /* SSH KEY DISPLAY /switches... */
- char c;
- int infmt = 0, outfmt = 0;
- struct FDB df, sw;
- cmfdbi(&sw,
- _CMKEY, /* fcode */
- "Filename, or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nsshdswi, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- sshdswi, /* Keyword table */
- &df /* Pointer to next FDB */
- );
- cmfdbi(&df, /* 2nd FDB - file for display */
- _CMIFI, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- line[0] = NUL;
-
- while (1) {
- x = cmfdb(&sw);
- if (x == -3) break;
- if (x < 0)
- return(x);
- if (cmresult.fcode != _CMKEY)
- break;
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- switch (cmresult.nresult) {
-#ifdef COMMENT
- case SSHKD_IN: /* /IN-FORMAT: */
- if ((y = cmkey(sshdifmt,nsshdifmt,
- "","",xxstring)) < 0)
- return(y);
- infmt = y;
- break;
-#endif /* COMMENT */
- case SSHKD_OUT: /* /FORMAT: */
- if ((y = cmkey(sshdofmt,nsshdofmt,
- "","",xxstring)) < 0)
- return(y);
- outfmt = y;
- break;
- }
- }
- if (cmresult.fcode == _CMIFI) { /* Filename */
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
- ckstrncpy(line,tmpbuf,LINBUFSIZ);
- }
-#ifdef COMMENT
- if (!line[0]) {
- printf("?Key filename required\n");
- return(-9);
- }
-#endif /* COMMENT */
- if ((y = cmcfm()) < 0) /* Confirm */
- return(y);
-#ifndef SSHTEST
- switch (outfmt) {
- case SKDF_OSSH:
- /* 2nd param is optional passphrase */
- x = sshkey_display_public(line[0] ? line : NULL, NULL);
- break;
- case SKDF_SSHC:
- /* 2nd param is optional passphrase */
- x = sshkey_display_public_as_ssh2(line[0] ? line : NULL,
- NULL);
- break;
- case SKDF_IETF:
- x = sshkey_display_fingerprint(line[0] ? line : NULL, 1);
- break;
- case SKDF_FING:
- x = sshkey_display_fingerprint(line[0] ? line : NULL, 0);
- break;
- }
-#endif /* SSHTEST */
- return(success = (x == 0));
- }
- case SSHK_V1: /* SSH KEY V1 SET-COMMENT */
- if ((x = cmkey(sshkv1,1,"","set-comment", xxstring)) < 0)
- return(x);
- if (x != 1) return(-2);
- if ((x = cmifi("Key file name","",&s,&y,xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of key file required\n");
- return(-9);
- }
- }
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmtxt("Comment text","",&s,xxstring)) < 0)
- return(x);
-#ifndef SSHTEST
- x = sshkey_v1_change_comment(line, /* filename */
- s, /* new comment */
- NULL /* passphrase */
- );
-#endif /* SSHTEST */
- success = (x == 0);
- return(success);
- }
- default:
- return(-2);
- }
-#else /* SSHBUILTIN */
-#ifdef SSHCMD
- x = nettype;
- if ((y = setlin(XXSSH,0,1)) < 0) {
- if (errno)
- printf("?%s\n",ck_errstr());
- else
-#ifdef COMMENT
- /* This isn't right either because it catches command editing */
- printf("?Sorry, pseudoterminal open failed\n");
- if (hints)
- printf("Hint: Try \"ssh -t %s\"\n",line);
-#else
- return(y);
-#endif /* COMMENT */
- nettype = x; /* Failed, restore net type. */
- ttnproto = z; /* and protocol */
- success = 0;
- }
- didsetlin++;
- netsave = x;
- return(y);
-#endif /* SSHCMD */
-#endif /* SSHBUILTIN */
- }
-#endif /* ANYSSH */
-
-#ifdef SSHBUILTIN
- if (cx == XXSKRM) { /* SKERMIT (Secure Shell Kermit) */
- extern int netsave;
- int k, x, havehost = 0, trips = 0;
- int tmpver = -1, tmpxfw = -1;
-#ifndef SSHTEST
- extern int sl_ssh_xfw, sl_ssh_xfw_saved;
- extern int sl_ssh_ver, sl_ssh_ver_saved;
-#endif /* SSHTEST */
- extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
- extern char * slmsg;
- extern char uidbuf[], sl_uidbuf[];
- extern char pwbuf[], * g_pswd;
- extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
- struct FDB sw, kw, fl;
-
- if (ssh_tmpstr)
- memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
- makestr(&ssh_tmpstr,NULL);
- makestr(&ssh_tmpuid,NULL);
- makestr(&ssh_tmpcmd,NULL);
- makestr(&ssh_tmpport,NULL);
-
- cmfdbi(&kw, /* 1st FDB - commands */
- _CMKEY, /* fcode */
- "host [ port ],\n or action", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nsshkermit, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 0 = keyword */
- xxstring, /* Processing function */
- sshkermit, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Host */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
-
- x = cmfdb(&kw);
- if (x == -3) {
- printf("?skermit what?\n");
- return(-9);
- }
- if (x < 0)
- return(x);
- havehost = 0;
- if (cmresult.fcode == _CMFLD) {
- havehost = 1;
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
- cmresult.nresult = SKRM_OPN;
- }
- switch (cmresult.nresult) { /* SSH keyword */
- case SKRM_OPN: /* SSH OPEN */
- if (!havehost) {
- if ((x = cmfld("Host","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- }
- /* Parse [ port ] [ switches ] */
- cmfdbi(&kw, /* Switches */
- _CMKEY,
- "Port number or service name,\nor switch",
- "",
- "",
- nsshkrmopnsw,
- 4,
- xxstring,
- sshkrmopnsw,
- &fl
- );
- cmfdbi(&fl, /* Port number or service name */
- _CMFLD,
- "",
- "",
- "",
- 0,
- 0,
- xxstring,
- NULL,
- NULL
- );
- trips = 0; /* Explained below */
- while (1) { /* Parse port and switches */
- x = cmfdb(&kw); /* Get a field */
- if (x == -3) /* User typed CR so quit from loop */
- break;
- if (x < 0) /* Other parse error, pass it back */
- return(x);
- switch (cmresult.fcode) { /* Field or Keyword? */
- case _CMFLD: /* Field */
- makestr(&ssh_tmpport,cmresult.sresult);
- break;
- case _CMKEY: /* Keyword */
- switch (cmresult.nresult) { /* Which one? */
- case SSHSW_USR: /* /USER: */
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- if ((y = cmfld("Username","",&s,xxstring)) < 0)
- return(y);
- s = brstrip(s);
- makestr(&ssh_tmpuid,s);
- break;
- case SSHSW_PWD:
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- debok = 0;
- if ((x = cmfld("Password","",&s,xxstring)) < 0) {
- if (x == -3) {
- makestr(&ssh_tmpstr,"");
- } else {
- return(x);
- }
- } else {
- s = brstrip(s);
- if ((x = (int)strlen(s)) > PWBUFL) {
- makestr(&slmsg,"Internal error");
- printf("?Sorry, too long - max = %d\n",PWBUFL);
- return(-9);
- }
- makestr(&ssh_tmpstr,s);
- }
- break;
-
- case SSHSW_VER:
- if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
- return(x);
- if (z < 1 || z > 2) {
- printf("?Out of range: %d\n",z);
- return(-9);
- }
- tmpver = z;
- break;
- default:
- return(-2);
- }
- }
- if (trips++ == 0) { /* After first time through */
- cmfdbi(&kw, /* only parse switches, not port. */
- _CMKEY,
- "Switch",
- "",
- "",
- nsshkrmopnsw,
- 4,
- xxstring,
- sshkrmopnsw,
- NULL
- );
- }
- }
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
- if (clskconnx(1) < 0) { /* Close current Kermit connection */
- if ( ssh_tmpstr ) {
- memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
- makestr(&ssh_tmpstr,NULL);
- }
- return(success = 0);
- }
- makestr(&ssh_hst,line); /* Stash everything */
- if (ssh_tmpuid) {
- if (!sl_uid_saved) {
- ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
- sl_uid_saved = 1;
- }
- ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
- makestr(&ssh_tmpuid,NULL);
- }
- if (ssh_tmpport) {
- makestr(&ssh_prt,ssh_tmpport);
- makestr(&ssh_tmpport,NULL);
- } else
- makestr(&ssh_prt,NULL);
-
- /* Set the Subsystem to Kermit */
- ssh_cas = 1;
- makestr(&ssh_cmd,"kermit");
-
- if (tmpver > -1) {
-#ifndef SSHTEST
- if (!sl_ssh_ver_saved) {
- sl_ssh_ver = ssh_ver;
- sl_ssh_ver_saved = 1;
- }
-#endif /* SSHTEST */
- ssh_ver = tmpver;
- }
- /* Disable X11 Forwarding */
-#ifndef SSHTEST
- if (!sl_ssh_xfw_saved) {
- sl_ssh_xfw = ssh_xfw;
- sl_ssh_xfw_saved = 1;
- }
-#endif /* SSHTEST */
- ssh_xfw = 0;
-
- if (ssh_tmpstr) {
- if (ssh_tmpstr[0]) {
- ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
- pwflg = 1;
- pwcrypt = 0;
- } else
- pwflg = 0;
- makestr(&ssh_tmpstr,NULL);
- }
- nettype = NET_SSH;
- if (mdmsav < 0)
- mdmsav = mdmtyp;
- mdmtyp = -nettype;
- x = 1;
-
-#ifndef NOSPL
- makestr(&g_pswd,pwbuf); /* Save global pwbuf */
- g_pflg = pwflg; /* and flag */
- g_pcpt = pwcrypt;
-#endif /* NOSPL */
-
- /* Line parameter to ttopen() is ignored */
- k = ttopen(line,&x,mdmtyp, 0);
- if (k < 0) {
- printf("?Unable to connect to %s\n",ssh_hst);
- mdmtyp = mdmsav;
- slrestor();
- return(success = 0);
- }
- duplex = 0; /* Remote echo */
- ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
- debug(F110,"ssh ttname",ttname,0);
- makestr(&slmsg,NULL); /* No SET LINE error message */
- cxtype = CXT_SSH;
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#endif /* NODIAL */
- success = 1; /* SET LINE succeeded */
- network = 1; /* Network connection (not serial) */
- local = 1; /* Local mode (not remote) */
- if ((reliable != SET_OFF || !setreliable))
- reliable = SET_ON; /* Transport is reliable end to end */
-#ifdef OS2
- DialerSend(OPT_KERMIT_CONNECT, 0);
-#endif /* OS2 */
- setflow(); /* Set appropriate flow control */
-
- haveline = 1;
-#ifdef CKLOGDIAL
-#ifdef NETCONN
- dolognet();
-#endif /* NETCONN */
-#endif /* CKLOGDIAL */
-
-#ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ssh_hst,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
-#endif /* NOSPL */
-#ifdef LOCUS
- if (autolocus)
- setlocus(1,1);
-#endif /* LOCUS */
-
- /* Command was confirmed so we can pre-pop command level. */
- /* This is so CONNECT module won't think we're executing a */
- /* script if CONNECT was the final command in the script. */
- if (cmdlvl > 0)
- prepop();
- return(success = 1);
-
- default:
- return(-2);
- }
- }
-#endif /* SSHBUILTIN */
-
-#ifdef SFTP_BUILTIN
- if (cx == XXSFTP) { /* SFTP (Secure Shell File Transfer) */
- extern int netsave;
- int k, x, havehost = 0, trips = 0;
- int tmpver = -1, tmpxfw = -1;
-#ifndef SSHTEST
- extern int sl_ssh_xfw, sl_ssh_xfw_saved;
- extern int sl_ssh_ver, sl_ssh_ver_saved;
-#endif /* SSHTEST */
- extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
- extern char * slmsg;
- extern char uidbuf[], sl_uidbuf[];
- extern char pwbuf[], * g_pswd;
- extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
- struct FDB sw, kw, fl;
-
- if (ssh_tmpstr)
- memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
- makestr(&ssh_tmpstr,NULL);
- makestr(&ssh_tmpuid,NULL);
- makestr(&ssh_tmpcmd,NULL);
- makestr(&ssh_tmpport,NULL);
-
- cmfdbi(&kw, /* 1st FDB - commands */
- _CMKEY, /* fcode */
- "host [ port ],\n or action", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nsftpkwtab, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 0 = keyword */
- xxstring, /* Processing function */
- sftpkwtab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* Host */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
-
- x = cmfdb(&kw);
- if (x == -3) {
- printf("?sftp what?\n");
- return(-9);
- }
- if (x < 0)
- return(x);
- havehost = 0;
- if (cmresult.fcode == _CMFLD) {
- havehost = 1;
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
- cmresult.nresult = SFTP_OPN;
- }
- switch (cmresult.nresult) { /* SFTP keyword */
- case SFTP_OPN: /* SFTP OPEN */
- if (!havehost) {
- if ((x = cmfld("Host","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- }
- /* Parse [ port ] [ switches ] */
- cmfdbi(&kw, /* Switches */
- _CMKEY,
- "Port number or service name,\nor switch",
- "",
- "",
- nsshkrmopnsw,
- 4,
- xxstring,
- sshkrmopnsw,
- &fl
- );
- cmfdbi(&fl, /* Port number or service name */
- _CMFLD,
- "",
- "",
- "",
- 0,
- 0,
- xxstring,
- NULL,
- NULL
- );
- trips = 0; /* Explained below */
- while (1) { /* Parse port and switches */
- x = cmfdb(&kw); /* Get a field */
- if (x == -3) /* User typed CR so quit from loop */
- break;
- if (x < 0) /* Other parse error, pass it back */
- return(x);
- switch (cmresult.fcode) { /* Field or Keyword? */
- case _CMFLD: /* Field */
- makestr(&ssh_tmpport,cmresult.sresult);
- break;
- case _CMKEY: /* Keyword */
- switch (cmresult.nresult) { /* Which one? */
- case SSHSW_USR: /* /USER: */
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- if ((y = cmfld("Username","",&s,xxstring)) < 0)
- return(y);
- s = brstrip(s);
- makestr(&ssh_tmpuid,s);
- break;
- case SSHSW_PWD:
- if (!cmgbrk()) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- debok = 0;
- if ((x = cmfld("Password","",&s,xxstring)) < 0) {
- if (x == -3) {
- makestr(&ssh_tmpstr,"");
- } else {
- return(x);
- }
- } else {
- s = brstrip(s);
- if ((x = (int)strlen(s)) > PWBUFL) {
- makestr(&slmsg,"Internal error");
- printf("?Sorry, too long - max = %d\n",PWBUFL);
- return(-9);
- }
- makestr(&ssh_tmpstr,s);
- }
- break;
-
- case SSHSW_VER:
- if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
- return(x);
- if (z < 1 || z > 2) {
- printf("?Out of range: %d\n",z);
- return(-9);
- }
- tmpver = z;
- break;
- default:
- return(-2);
- }
- }
- if (trips++ == 0) { /* After first time through */
- cmfdbi(&kw, /* only parse switches, not port. */
- _CMKEY,
- "Switch",
- "",
- "",
- nsshkrmopnsw,
- 4,
- xxstring,
- sshkrmopnsw,
- NULL
- );
- }
- }
- if ((x = cmcfm()) < 0) /* Get confirmation */
- return(x);
- if (clskconnx(1) < 0) { /* Close current Kermit connection */
- if ( ssh_tmpstr ) {
- memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
- makestr(&ssh_tmpstr,NULL);
- }
- return(success = 0);
- }
- makestr(&ssh_hst,line); /* Stash everything */
- if (ssh_tmpuid) {
- if (!sl_uid_saved) {
- ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
- sl_uid_saved = 1;
- }
- ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
- makestr(&ssh_tmpuid,NULL);
- }
- if (ssh_tmpport) {
- makestr(&ssh_prt,ssh_tmpport);
- makestr(&ssh_tmpport,NULL);
- } else
- makestr(&ssh_prt,NULL);
-
- /* Set the Subsystem to Kermit */
- ssh_cas = 1;
- makestr(&ssh_cmd,"sftp");
-
- if (tmpver > -1) {
-#ifndef SSHTEST
- if (!sl_ssh_ver_saved) {
- sl_ssh_ver = ssh_ver;
- sl_ssh_ver_saved = 1;
- }
-#endif /* SSHTEST */
- ssh_ver = tmpver;
- }
- /* Disable X11 Forwarding */
-#ifndef SSHTEST
- if (!sl_ssh_xfw_saved) {
- sl_ssh_xfw = ssh_xfw;
- sl_ssh_xfw_saved = 1;
- }
-#endif /* SSHTEST */
- ssh_xfw = 0;
-
- if (ssh_tmpstr) {
- if (ssh_tmpstr[0]) {
- ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
- pwflg = 1;
- pwcrypt = 0;
- } else
- pwflg = 0;
- makestr(&ssh_tmpstr,NULL);
- }
- nettype = NET_SSH;
- if (mdmsav < 0)
- mdmsav = mdmtyp;
- mdmtyp = -nettype;
- x = 1;
-
-#ifndef NOSPL
- makestr(&g_pswd,pwbuf); /* Save global pwbuf */
- g_pflg = pwflg; /* and flag */
- g_pcpt = pwcrypt;
-#endif /* NOSPL */
-
- /* Line parameter to ttopen() is ignored */
- k = ttopen(line,&x,mdmtyp, 0);
- if (k < 0) {
- printf("?Unable to connect to %s\n",ssh_hst);
- mdmtyp = mdmsav;
- slrestor();
- return(success = 0);
- }
- duplex = 0; /* Remote echo */
- ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
- debug(F110,"ssh ttname",ttname,0);
- makestr(&slmsg,NULL); /* No SET LINE error message */
- cxtype = CXT_SSH;
-#ifndef NODIAL
- dialsta = DIA_UNK;
-#endif /* NODIAL */
- success = 1; /* SET LINE succeeded */
- network = 1; /* Network connection (not serial) */
- local = 1; /* Local mode (not remote) */
- if ((reliable != SET_OFF || !setreliable))
- reliable = SET_ON; /* Transport is reliable end to end */
-#ifdef OS2
- DialerSend(OPT_KERMIT_CONNECT, 0);
-#endif /* OS2 */
- setflow(); /* Set appropriate flow control */
-
- haveline = 1;
-#ifdef CKLOGDIAL
-#ifdef NETCONN
- dolognet();
-#endif /* NETCONN */
-#endif /* CKLOGDIAL */
-
-#ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ssh_hst,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
-#endif /* NOSPL */
-#ifdef LOCUS
- if (autolocus)
- setlocus(1,1);
-#endif /* LOCUS */
-
- /* Command was confirmed so we can pre-pop command level. */
- /* This is so CONNECT module won't think we're executing a */
- /* script if CONNECT was the final command in the script. */
- if (cmdlvl > 0)
- prepop();
-
- success = sftp_do_init();
- return(success = 1);
-
- case SFTP_CD:
- case SFTP_CHGRP:
- case SFTP_CHMOD:
- case SFTP_CHOWN:
- case SFTP_RM:
- case SFTP_DIR:
- case SFTP_GET:
- case SFTP_MKDIR:
- case SFTP_PUT:
- case SFTP_PWD:
- case SFTP_REN:
- case SFTP_RMDIR:
- case SFTP_LINK:
- case SFTP_VER:
- if ((y = cmtxt("command parameters","",&s,xxstring)) < 0)
- return(y);
- if (ssh_tchk() < 0 || !ssh_cas || strcmp(ssh_cmd,"sftp")) {
- printf("?Not connected to SFTP Service\n");
- return(success = 0);
- }
- success = sftp_do_cmd(cmresult.nresult,s);
- return(success);
- default:
- return(-2);
- }
- }
-#endif /* SFTP_BUILTIN */
-
- if (cx == XXRLOG) { /* RLOGIN */
-#ifdef RLOGCODE
- int x,z;
-#ifdef OS2
- if (!tcp_avail) {
- printf("?Sorry, either TCP/IP is not available on this system or\n\
-necessary DLLs did not load. Use SHOW NETWORK to check network status.\n"
- );
- success = 0;
- return(-9);
- } else {
-#endif /* OS2 */
- x = nettype; /* Save net type in case of failure */
- z = ttnproto; /* Save protocol in case of failure */
- nettype = NET_TCPB;
- ttnproto = NP_RLOGIN;
- if ((y = setlin(XYHOST,0,1)) <= 0) {
- nettype = x; /* Failed, restore net type. */
- ttnproto = z; /* and protocol */
- success = 0;
- }
- didsetlin++;
-#ifdef OS2
- }
-#endif /* OS2 */
- return(y);
-#else
- printf("?Sorry, RLOGIN is not configured in this copy of C-Kermit.\n");
- return(-9);
-#endif /* RLOGCODE */
- }
-#endif /* NETCONN */
-#endif /* NOLOCAL */
-
-#ifndef NOXMIT
- if (cx == XXTRA) { /* TRANSMIT */
- extern int xfrxla;
- int i, n, xpipe = 0, xbinary = 0, xxlate = 1, xxnowait = 0, getval;
- int xxecho = 0;
- int scan = 1;
- char c;
- struct FDB sf, sw, tx; /* FDBs for parse functions */
-#ifndef NOCSETS
- extern int tcs_transp; /* Term charset is transparent */
-#else
- int tcs_transp = 1;
-#endif /* NOCSETS */
-
-#ifdef COMMENT
- xbinary = binary; /* Default text/binary mode */
-#else
- xbinary = 0; /* Default is text */
-#endif /* COMMENT */
- xxecho = xmitx;
-
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Filename, or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nxmitsw, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- xmitsw, /* Keyword table */
- &sf /* Pointer to next FDB */
- );
- cmfdbi(&sf, /* 2nd FDB - file to send */
- _CMIFI, /* fcode */
- "File to transmit", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
-#ifdef PIPESEND
- &tx
-#else
- NULL
-#endif /* PIPESEND */
- );
-#ifdef PIPESEND
- cmfdbi(&tx,
- _CMTXT, /* fcode */
- "Command", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
-#endif /* PIPESEND */
-
- while (1) {
- x = cmfdb(&sw);
- if (x < 0)
- return(x);
- if (cmresult.fcode != _CMKEY)
- break;
- c = cmgbrk(); /* Have switch, get break character */
- if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- n = cmresult.nresult; /* Numeric result = switch ID */
- switch (n) { /* Process the switch */
-#ifdef PIPESEND
- case XMI_CMD: /* Transmit from a command */
- if (nopush) {
- printf("?Sorry, system command access is disabled\n");
- return(-9);
- }
- sw.hlpmsg = "Command, or switch"; /* Change help message */
- xpipe = 1; /* (No way to undo this one) */
- break;
-#endif /* PIPESEND */
-
- case XMI_BIN: /* Binary */
- xbinary = 1;
- xxlate = 0; /* Don't translate charsets */
- scan = 0;
- break;
-
- case XMI_TXT: /* Text */
- xbinary = 0;
- xxlate = !tcs_transp; /* Translate if TERM CHAR not TRANSP */
- scan = 0;
- break;
-
- case XMI_TRA: /* Transparent text */
- xbinary = 0;
- xxlate = 0; /* But don't translate charsets */
- scan = 0;
- break;
-
-#ifdef COMMENT
- case XMI_VRB: /* /VERBOSE */
- case XMI_QUI: /* /QUIET */
- break; /* (not implemented yet) */
-#endif /* COMMENT */
-
- case XMI_NOW: /* /NOWAIT */
- xxnowait = 1;
- break;
-
- case XMI_NOE: /* /NOWAIT */
- xxecho = 0;
- break;
-
- default:
- return(-2);
- }
-
- }
- if (cmresult.fcode != _CMIFI && cmresult.fcode != _CMTXT)
- return(-2);
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Filename */
- if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
- ckstrncpy(line,tmpbuf,LINBUFSIZ);
- s = line;
- if ((y = cmcfm()) < 0) /* Confirm */
- return(y);
-#ifdef CK_APC
- if ((apcactive == APC_LOCAL) ||
- ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
- return(success = 0);
-#endif /* CK_APC */
- if (cmresult.nresult != 0) {
- printf("?Only a single file may be transmitted\n");
- return(-9);
- }
-#ifdef PIPESEND
- if (xpipe) {
- s = brstrip(s);
- if (!*s) {
- printf("?Sorry, a command to send from is required\n");
- return(-9);
- }
- pipesend = 1;
- }
-#endif /* PIPESEND */
-
- if (scan && (filepeek
-#ifndef NOXFER
- || patterns
-#endif /* NOXFER */
- )) { /* If user didn't specify type */
- int k, x; /* scan the file to see */
- x = -1;
- k = scanfile(s,&x,nscanfile);
- if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
- }
- if (!xfrxla) xxlate = 0;
- success = transmit(s,
- (char) (xxnowait ? '\0' : (char)xmitp),
- xxlate,
- xbinary,
- xxecho
- );
- return(success);
- }
-#endif /* NOXMIT */
-
-#ifndef NOFRILLS
- if (cx == XXTYP || cx == XXCAT || cx == XXMORE ||
- cx == XXHEAD || cx == XXTAIL) {
- int paging = 0, havename = 0, head = 0, width = 0;
- int height = 0, count = 0;
- char pfxbuf[64], * prefix = NULL;
- char outfile[CKMAXPATH+1];
- struct FDB sf, sw;
- char * pat = NULL;
- int incs = 0, outcs = 0, cset = -1, number = 0;
-#ifdef UNICODE
- char * tocs = "";
- extern int fileorder;
-#ifdef OS2
-#ifdef NT
- char guibuf[128], * gui_title = NULL;
- int gui = 0;
-#endif /* NT */
-#ifndef NOCSETS
- extern int tcsr, tcsl;
-#endif /* NOCSETS */
-#endif /* OS2 */
-#endif /* UNICODE */
-
- outfile[0] = NUL;
-
- if (cx == XXMORE)
- paging = 1;
- else if (cx == XXCAT)
- paging = 0;
- else
- paging = (typ_page < 0) ? xaskmore : typ_page;
- if (paging < 0)
- paging = saveask;
-
- if (cx == XXHEAD) {
- head = 10;
- cx = XXTYP;
- } else if (cx == XXTAIL) {
- head = -10;
- cx = XXTYP;
- }
-
-#ifdef IKSD
- if (inserver && !ENABLED(en_typ)) {
- printf("?Sorry, TYPE command disabled\n");
- return(-9);
- }
-#endif /* IKSD */
-
- cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */
- _CMKEY, /* fcode */
- "Filename or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- ntypetab, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- typetab, /* Keyword table */
- &sf /* Pointer to next FDB */
- );
- cmfdbi(&sf, /* 1st FDB - file to type */
- _CMIFI, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
-
- while (!havename) {
- x = cmfdb(&sw); /* Parse something */
- debug(F101,"type cmfdb","",x);
- debug(F101,"type cmresult.fcode","",cmresult.fcode);
- debug(F101,"type cmresult.nresult","",cmresult.nresult);
- if (x < 0) { /* Error */
- if (x == -3) {
- x = -9;
- printf("?Filename required\n");
- }
- return(x);
- } else if (cmresult.fcode == _CMKEY) {
- char c; int getval;
- c = cmgbrk();
- getval = (c == ':' || c == '=');
- if (getval && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
-#ifdef COMMENT
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- /* Not if it has a default! */
- return(-9);
- }
-#endif /* COMMENT */
- switch (cmresult.nresult) {
-#ifdef CK_TTGWSIZ
- case TYP_PAG:
- paging = 1;
- break;
-
- case TYP_NOP:
- paging = 0;
- break;
-#endif /* CK_TTGWSIZ */
-
- case TYP_COU:
- paging = 0;
- count = 1;
- break;
-
- case TYP_HEA:
- case TYP_TAI:
- y = 10;
- if (getval)
- if ((x = cmnum("Number of lines",
- "10",10,&y,xxstring)) < 0)
- return(x);
- head = (cmresult.nresult == TYP_TAI) ? -y : y;
- break;
-
- case TYP_WID:
- y = typ_wid > -1 ? typ_wid : cmd_cols;
- if (getval)
- if ((x = cmnum("Column at which to truncate",
- ckitoa(y),10,&y,xxstring)) < 0)
- return(x);
- width = y;
- break;
-
-#ifdef KUI
- case TYP_HIG:
- if (getval)
- if ((x = cmnum("Height of GUI dialog",
- ckitoa(y),10,&y,xxstring)) < 0)
- return(x);
- height = y;
- break;
-#endif /* KUI */
-
- case TYP_PAT:
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- if ((x = cmfld("pattern","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- pat = tmpbuf;
- break;
-
- case TYP_PFX:
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- if ((x = cmfld("prefix for each line","",&s,xxstring)) < 0)
- return(x);
- if ((int)strlen(s) > 63) {
- printf("?Too long - 63 max\n");
- return(-9);
- }
- ckstrncpy(pfxbuf,s,64);
- prefix = brstrip(pfxbuf);
- number = 0;
- break;
-
-#ifdef KUI
- case TYP_GUI:
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- if ((x = cmfld("Dialog box title","",&s,xxstring)) < 0) {
- if (x != -3)
- return(x);
- } else {
- if ((int)strlen(s) > 127) {
- printf("?Too long - 127 max\n");
- return(-9);
- }
- ckstrncpy(guibuf,s,128);
- gui_title = brstrip(guibuf);
- }
- gui = 1;
- break;
-#endif /* KUI */
-
- case TYP_NUM: /* /NUMBER */
- number = 1;
- prefix = NULL;
- break;
-
-#ifdef UNICODE
- case TYP_XPA: /* /TRANSPARENT */
- incs = 0;
- cset = 0;
- outcs = -1;
- break;
-
- case TYP_XIN: /* /CHARACTER-SET: */
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
- if ((incs = cmkey(fcstab,nfilc,
- "character-set name","",xxstring)) < 0) {
- if (incs == -3) /* Note: No default */
- incs = -2;
- return(incs);
- }
- cset = incs;
- break;
-
- case TYP_XUT: /* /TRANSLATE-TO: */
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- return(-9);
- }
-#ifdef OS2
- if (!inserver && !k95stdout) {
- tocs = "ucs2";
- } else {
-#ifdef CKOUNI
- tocs = rlookup(txrtab,ntxrtab,tcsl);
-#else /* CKOUNI */
- extern struct keytab ttcstab[];
- extern int ntxrtab;
- tocs = rlookup(ttcstab,ntermc,tocs);
- if (!tocs)
- tocs = getdcset();
-#endif /* CKOUNI */
- }
-#else /* OS2 */
- tocs = getdcset();
-#endif /* OS2 */
- if ((outcs = cmkey(fcstab,nfilc,
- "character-set",tocs,xxstring)) < 0)
- return(outcs);
- break;
-#endif /* UNICODE */
- case TYP_OUT:
- if ((x = cmofi("File for result lines","",
- &s,xxstring)) < 0)
- return(x);
- ckstrncpy(outfile,s,CKMAXPATH);
- break;
- }
- } else if (cmresult.fcode == _CMIFI)
- havename = 1;
- else
- return(-2);
- }
- if (havename) {
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- y = cmresult.nresult;
- } else {
- if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0) {
- if (x == -3) {
- printf("?Name of an existing file required\n");
- return(-9);
- } else return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- }
- if (y != 0) {
- printf("?A single file please\n");
- return(-9);
- }
-#ifdef KUI
- if ( outfile[0] && gui ) {
- printf("?/GUI and /OUTPUT are incompatible\n");
- return(-9);
- }
-#endif /* KUI */
-
- if ((y = cmcfm()) < 0) /* Confirm the command */
- return(y);
-
-#ifdef UNICODE
- fileorder = -1;
- if (cset < 0 && filepeek) { /* If no charset switches given */
- int k, x = -1;
- k = scanfile(line,&x,nscanfile); /* Call file analyzer */
- debug(F111,"type scanfile",line,k);
- debug(F101,"type scanfile flag","",x);
- switch(k) {
- case FT_UTF8: /* which can detect UTF-8... */
- cset = 0;
- incs = FC_UTF8;
- break;
- case FT_UCS2: /* and UCS-2... */
- cset = 0;
- incs = FC_UCS2;
- fileorder = x; /* even if there is no BOM. */
- debug(F101,"type fileorder","",fileorder);
- break;
- }
- }
-#ifdef OS2
- if (cset < 0) { /* If input charset still not known */
-#ifdef CKOUNI
- tocs = rlookup(txrtab,ntxrtab,tcsl);
-#else /* CKOUNI */
- extern struct keytab ttcstab[];
- extern int ntxrtab;
- tocs = rlookup(ttcstab,ntermc,incs);
- if (!tocs)
- tocs = getdcset();
-#endif /* CKOUNI */
- incs = lookup(fcstab,tocs,nfilc,&x);
- }
-#endif /* OS2 */
-
- if (outcs == 0 && incs != 0) { /* Supply default target charset */
- int x = 0; /* if switch not given. */
- tocs = getdcset();
- outcs = lookup(fcstab,tocs,nfilc,&x);
- }
-#else /* !UNICODE */
- if (cset < 0) incs = outcs = 0;
-#endif /* UNICODE */
-
- if (outfile[0] && paging) /* This combination makes no sense */
- paging = 0; /* so turn off paging */
-
-#ifdef KUI
- /* No paging when dialog is used */
- if ( gui && paging )
- paging = 0;
-
- if ( !gui && height ) {
- printf("?The /HEIGHT switch is not supported without /GUI\n");
- return(-9);
- }
-#endif /* KUI */
-
- if (count) paging = -1;
- debug(F111,"type",line,paging);
-#ifdef KUI
- if ( gui ) {
- s = (char *)1; /* ok, its an ugly hack */
- if (gui_text_popup_create(gui_title ?
- gui_title : line, height,width) < 0) {
- printf("?/GUI not supported on this system\n");
- gui = 0;
- return(-9);
- }
- width = 0;
- } else
-#endif /* KUI */
- s = outfile;
- success =
- dotype(line,paging,0,head,pat,width,prefix,incs,outcs,s,number);
- return(success);
- }
-#endif /* NOFRILLS */
-
-#ifndef NOCSETS
- if (cx == XXXLA) { /* TRANSLATE file's charset */
- _PROTOTYP (int doxlate, ( void ) );
- return(doxlate());
- }
-#endif /* NOCSETS */
-
- if (cx == XXVER) { /* VERSION */
- int n = 0;
- extern char * ck_patch, * ck_s_test;
-#ifdef COMMENT
- extern int hmtopline;
-#endif /* COMMENT */
- if ((y = cmcfm()) < 0)
- return(y);
-
-#ifdef CK_64BIT
- printf("\n%s, for%s (64-bit)\n Numeric: %ld",versio,ckxsys,vernum);
-#else
- printf("\n%s, for%s\n Numeric: %ld",versio,ckxsys,vernum);
-#endif /* CK_64BIT */
- printf("\n\n");
- printf("Authors:\n");
- printf(" Frank da Cruz, Columbia University\n");
- printf(" Jeffrey Eric Altman, Secure Endpoints, Inc. %s\n",
- "<jaltman@secure-endpoints.com>"
- );
- printf(" Contributions from many others.\n");
- n = 7;
- if (*ck_s_test) {
- printf("\nTHIS IS A TEST VERSION, NOT FOR PRODUCTION USE.\n");
- n += 2;
- }
- if (*ck_patch) {
- printf(" Patches: %s\n", ck_patch);
- n++;
- }
- printf(" Type COPYRIGHT for copyright and license.\n\n");
-#ifdef OS2
- shoreg();
-#else
-#ifdef COMMENT
- hmtopline = n+1;
- hmsga(copyright);
- hmtopline = 0;
-#endif /* COMMENT */
-#endif /* OS2 */
- return(success = 1);
- }
-
- if (cx == XXCPR) { /* COPYRIGHT or LICENSE */
- _PROTOTYP( int hmsgaa, (char * [], char *) );
- extern char * ck_cryear;
- if ((y = cmcfm()) < 0)
- return(y);
- hmsgaa(copyright,ck_cryear);
- return(success = 1);
- }
-
-#ifndef MAC /* Only for multiuser systems */
-#ifndef OS2
-#ifndef NOFRILLS
- if (cx == XXWHO) { /* WHO */
- char *wc;
-#ifdef IKSD
- if (inserver && !ENABLED(en_who)) {
- printf("?Sorry, WHO command disabled\n");
- return(-9);
- }
-#endif /* IKSD */
-#ifdef datageneral
- if ((z = cmcfm()) < 0) return(z);
- if (nopush) {
- printf("?Sorry, who not allowed\n");
- return(success = 0);
- }
- xsystem(WHOCMD);
-#else
- if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
- if (nopush) {
- printf("?Sorry, WHO command disabled\n");
- return(success = 0);
- }
- if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
- if (wc)
- if ((int) strlen(wc) > 0) {
- ckmakmsg(line,LINBUFSIZ,wc," ",s,NULL);
- xsystem(line);
- }
-#endif /* datageneral */
- return(success = 1);
- }
-#endif /* NOFRILLS */
-#endif /* OS2 */
-#endif /* MAC */
-
-#ifndef NOFRILLS
- if (cx == XXWRI || cx == XXWRL || cx == XXWRBL) { /* WRITE */
- int x,y; /* On stack in case of \fexec() */
- if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
- if (x == -3) printf("?Write to what?\n");
- return(x);
- }
- if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
- s = brstrip(s);
- switch (x) {
- case LOGD: y = ZDFILE; break;
- case LOGP: y = ZPFILE; break;
-#ifndef NOLOCAL
- case LOGS: y = ZSFILE; break;
-#endif /* NOLOCAL */
- case LOGT: y = ZTFILE; break;
-#ifndef NOSPL
- case LOGW: y = ZWFILE; break;
-#endif /* NOSPL */
- case LOGX: /* SCREEN (stdout) */
- case LOGE: /* ERROR (stderr) */
- if (x == LOGE) {
- debug(F110,
- (cx == XXWRL) ? "WRITELN ERROR" : "WRITE ERROR", s,0);
- fprintf(stderr,"%s%s",s,(cx == XXWRL) ? "\n" : "");
- } else {
- debug(F110,
- (cx == XXWRL) ? "WRITELN SCREEN" : "WRITE SCREEN", s,0);
- printf("%s%s",s,(cx == XXWRL) ? "\n" : "");
- }
- return(success = 1);
- default: return(-2);
- }
- if (chkfn(y) > 0) {
- x = (cx == XXWRI) ? zsout(y,s) : zsoutl(y,s);
- debug(F111,"WRITE",
- (cx == XXWRI) ? "zsout" : "zsoutl",
- x);
- if (x < 0) printf("?Write error\n");
- } else {
- x = -1;
- printf("?File or log not open\n");
- }
- debug(F101,"WRITE x","",x);
- return(success = (x == 0) ? 1 : 0);
- }
-#endif /* NOFRILLS */
-
-#ifndef NOXFER
- if (cx == XXASC || cx == XXBIN) {
- if ((x = cmcfm()) < 0) return(x);
-#ifdef NEWFTP
-/*
- Make C-Kermit work like other ftp clients, where
- the ASCII (TEXT) and BINARY commands are global settings.
-*/
- if (ftpisopen()) {
- doftpglobaltype((cx == XXASC) ? XYFT_T : XYFT_B);
- /* Fall thru--the command it should apply to both FTP and Kermit */
- /* return(success = 1); */
- }
-#endif /* NEWFTP */
-
- xfermode = XMODE_M; /* Set manual Kermit transfer mode */
- binary = (cx == XXASC) ? XYFT_T : XYFT_B;
- return(success = 1);
- }
-#endif /* NOXFER */
-
- if (cx == XXCLS) {
- if ((x = cmcfm()) < 0) return(x);
- y = ck_cls();
- return(success = (y > -1) ? 1 : 0);
- }
-
-#ifdef CK_MKDIR
- if (cx == XXMKDIR || cx == XXLMKD) {
- char *p;
-#ifdef LOCUS
- if (!locus && cx != XXLMKD) {
-#ifdef NOXFER
- return(-2);
-#else
- return(dormt(XZMKD));
-#endif /* NOXFER */
- }
-#endif /* LOCUS */
-#ifdef IKSD
- if (inserver && !ENABLED(en_mkd)) {
- printf("?Sorry, directory creation is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
- if ((x = cmfld("Name for new directory","",&s,xxstring)) < 0) {
- if (x != -3) {
- return(x);
- } else {
- printf("?Directory name required\n");
- return(-9);
- }
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- if ((x = cmcfm()) < 0) return(x);
- s = brstrip(s);
- bgchk(); /* Set msgflg */
- x = ckmkdir(0,s,&p,msgflg,0);
-#ifdef COMMENT
- if (msgflg && x == 0)
- printf("?Directory already exists\n");
-#endif /* COMMENT */
- return(success = (x < 0) ? 0 : 1);
- }
- if (cx == XXRMDIR || cx == XXLRMD) { /* RMDIR */
- char *p;
-#ifdef LOCUS
- if (!locus && cx != XXLRMD) {
-#ifdef NOXFER
- return(-2);
-#else
- return(dormt(XZRMD));
-#endif /* NOXFER */
- }
-#endif /* LOCUS */
-#ifdef IKSD
- if (inserver && !ENABLED(en_rmd)) {
- printf("?Sorry, directory removal is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
- if ((x = cmdir("Name of directory to be removed","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- if ((x = cmcfm()) < 0) return(x);
- s = brstrip(s);
- x = ckmkdir(1,s,&p,msgflg,0);
- return(success = (x < 0) ? 0 : 1);
- }
-#endif /* CK_MKDIR */
-
-#ifdef TNCODE
- if (cx == XXTELOP)
- return(dotelopt());
-#endif /* TNCODE */
-
-#ifndef NOPUSH
- if (cx == XXNPSH) {
- if ((z = cmcfm()) < 0) return(z);
- nopush = 1;
-#ifndef NOSERVER
- en_hos = 0;
-#endif /* NOSERVER */
-#ifdef PIPESEND
- usepipes = 0;
-#endif /* PIPESEND */
- return(success = 1);
- }
-#endif /* NOPUSH */
-
-#ifdef OS2
- if (cx == XXNSCR) {
- if ((z = cmcfm()) < 0) return(z);
- tt_scroll = 0;
- return(success = 1);
- }
-#endif /* OS2 */
-
-#ifndef NOSPL
- if (cx == XXLOCAL) /* LOCAL variable declarations */
- return(success = dolocal());
-#endif /* NOSPL */
-
- if (cx == XXKERMI) { /* The KERMIT command */
- char * list[65];
- extern char **xargv;
- extern int xargc;
- int i;
- if ((y = cmtxt("kermit command-line arguments, -h for help",
- "",&s,xxstring)) < 0)
- return(y);
- ckstrncpy(line,"kermit ",LINBUFSIZ);
- ckstrncat(line,s,LINBUFSIZ-8);
- xwords(line,64,list,0);
- for (i = 1; i < 64; i++) {
- if (!list[i])
- break;
- }
- i--;
- xargc = i;
- xargv = list;
- xargv++;
- sstate = cmdlin();
- if (sstate) {
- extern int justone;
- debug(F000,"KERMIT sstate","",sstate);
- justone = 1; /* Force return to command mode */
- proto(); /* after protocol */
- return(success);
- } else {
- debug(F101,"KERMIT sstate","",sstate);
- return(success = 1); /* Not exactly right, but... */
- }
- }
- if (cx == XXDATE) { /* DATE command */
- extern char cmdatebuf[], * cmdatemsg;
-
-#ifndef COMMENT
- char * dp;
- if ((y = cmtxt("date and/or time, or carriage return for current",
- "",&s,xxstring)) < 0)
- return(y);
- s = brstrip(s);
- dp = cmcvtdate(s,1);
- if (!dp) {
- printf("?%s\n",cmdatemsg ? cmdatemsg : "Date conversion error");
- success = 0;
- } else {
- printf("%s\n",dp);
- success = 1;
- }
-#else
- /* This works fine but messes up my "dates" torture-test script */
-
- if ((x = cmdate("Date and/or time, or carriage return for current",
- "",&s,0,xxstring)) < 0) {
- return(x);
- } else {
- printf("%s\n",cmdatebuf);
- success = 1;
- }
-#endif /* COMMENT */
- return(success);
- }
-#ifndef NOPUSH
-#ifndef NOFRILLS
- if (cx == XXEDIT)
- return(doedit());
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-
-#ifdef BROWSER /* Defined only ifndef NOPUSH */
- if (cx == XXBROWS)
- return(dobrowse());
-#endif /* BROWSER */
-
-#ifdef CK_TAPI
- if (cx == XXTAPI) { /* Microsoft TAPI */
- return (success = dotapi());
- }
-#endif /* CK_TAPI */
-
-#ifndef NOXFER
- if (cx == XXWHERE) {
- extern char * rfspec, * sfspec, * srfspec, * rrfspec;
- if ((x = cmcfm()) < 0) return(x);
- printf("\nFile most recently...\n\n");
- printf(" Sent: %s\n", sfspec ? sfspec : "(none)");
- if (sfspec && srfspec) {
- printf(" Stored as: %s\n", srfspec);
- printf("\n");
- }
- printf(" Received: %s\n", rrfspec ? rrfspec : "(none)");
- if (rfspec && rrfspec)
- printf(" Stored as: %s\n", rfspec);
- printf(
-"\nIf the full path is not shown, then the file is probably in your current\n"
- );
- printf(
-"directory or your download directory (if any - SHOW FILE to find out).\n\n"
- );
- return(success = 1);
- }
-#endif /* NOXFER */
-
-#ifdef CK_RECALL
- if (cx == XXREDO)
- return(doredo());
-#endif /* CK_RECALL */
-
-#ifdef CKROOT
- if (cx == XXCHRT) /* Change Kermit's root directory */
- return(dochroot());
-#endif /* CKROOT */
-
-#ifdef CK_KERBEROS
- if (cx == XXAUTH) { /* KERBEROS */
- x = cp_auth(); /* Parse it */
-#ifdef IKSD
- if (inserver) {
- printf("?Command disabled in IKSD.\r\n");
- return(success = 0);
- }
-#endif /* IKSD */
- if (x < 0) /* Pass parse errors back */
- return(x);
- return(success = doauth(cx));
- }
-#endif /* CK_KERBEROS */
-
-#ifndef NOLOCAL
- if (cx == XXTERM) {
- return(settrmtyp());
- }
-#endif /* NOLOCAL */
-
- if (cx == XXSTATUS) {
- if ((x = cmcfm()) < 0) return(x);
- printf( " %s\n", success ? "SUCCESS" : "FAILURE" );
- return(0); /* Don't change it */
- }
-
- if (cx == XXFAIL) {
- if ((x = cmcfm()) < 0) return(x);
- return(success = 0);
- }
-
- if (cx == XXSUCC) {
- if ((x = cmcfm()) < 0) return(x);
- return(success = 1);
- }
-
- if (cx == XXNLCL) {
- extern int nolocal;
- if ((x = cmcfm()) < 0) return(x);
- nolocal = 1;
- return(success = 1);
- }
-
-#ifndef NOXFER
- if (cx == XXRASG) /* Shortcuts for REMOTE commands */
- return(dormt(XZASG));
- if (cx == XXRCWD)
- return(dormt(XZCWD));
- if (cx == XXRCPY)
- return(dormt(XZCPY));
- if (cx == XXRDEL)
- return(dormt(XZDEL));
- if (cx == XXRDIR)
- return(dormt(XZDIR));
- if (cx == XXRXIT)
- return(dormt(XZXIT));
- if (cx == XXRHLP)
- return(dormt(XZHLP));
- if (cx == XXRHOS)
- return(dormt(XZHOS));
- if (cx == XXRKER)
- return(dormt(XZKER));
- if (cx == XXRPWD)
- return(dormt(XZPWD));
- if (cx == XXRQUE)
- return(dormt(XZQUE));
- if (cx == XXRREN)
- return(dormt(XZREN));
- if (cx == XXRMKD)
- return(dormt(XZMKD));
- if (cx == XXRMSG)
- return(dormt(XZMSG));
- if (cx == XXRRMD)
- return(dormt(XZRMD));
- if (cx == XXRSET)
- return(dormt(XZSET));
- if (cx == XXRSPA)
- return(dormt(XZSPA));
- if (cx == XXRTYP)
- return(dormt(XZTYP));
- if (cx == XXRWHO)
- return(dormt(XZWHO));
- if (cx == XXRCDUP)
- return(dormt(XZCDU));
- if (cx == XXRPRI)
- return(dormt(XZPRI));
-#endif /* NOXFER */
-
- if (cx == XXRESET) { /* RESET */
- if ((x = cmcfm()) < 0)
- return(x);
- concb((char)escape); /* Make command echoing to normal */
- doclean(0); /* Close all files */
- return(success = 1);
- }
-
-#ifndef NOXFER
-#ifndef NOCSETS
- if (cx == XXASSOC) /* ASSOCIATE */
- return(doassoc());
-#endif /* NOCSETS */
-#endif /* NOXFER */
-
-#ifndef NOSPL
- if (cx == XXSHIFT) { /* SHIFT */
- if ((y = cmnum("Number of arguments to shift","1",10,&x,xxstring)) < 0)
- return(y);
- if ((z = cmcfm()) < 0)
- return(z);
- return(success = doshift(x));
- }
-#endif /* NOSPL */
-
-#ifndef NOHELP
- if (cx == XXMAN)
- return(domanual());
-#endif /* NOHELP */
-
-#ifndef NOSPL
- if (cx == XXSORT) /* SORT an array */
- return(dosort());
-#endif /* NOSPL */
-
- if (cx == XXPURGE) {
-#ifdef IKSD
- if (inserver && (!ENABLED(en_del)
-#ifdef CK_LOGIN
- || isguest
-#endif /* CK_LOGIN */
- )) {
- printf("?Sorry, DELETE is disabled\n");
- return(-9);
- }
-#endif /* IKSD */
-#ifdef CK_APC
- if ((apcactive == APC_LOCAL) ||
- ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
- return(success = 0);
-#endif /* CK_APC */
-#ifdef CKPURGE
- return(dopurge());
-#else
-#ifdef VMS
- if ((x = cmtxt("optional switches followed by filespec",
- "",&s,xxstring)) < 0)
- return(x);
- if (nopush) {
- printf("?Sorry, DCL access is disabled\n");
- return(-9);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- x = mlook(mactab,"purge",nmac);
- return(success = dodo(x,s,cmdstk[cmdlvl].ccflgs));
-#else
- return(-2);
-#endif /* VMS */
-#endif /* CKPURGE */
- }
-
-#ifndef NOSPL
- if (cx == XXFAST) {
- if ((x = cmcfm()) < 0) return(x);
- x = mlook(mactab,"fast",nmac);
- return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
- }
- if (cx == XXCAU) {
- if ((x = cmcfm()) < 0) return(x);
- x = mlook(mactab,"cautious",nmac);
- return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
- }
- if (cx == XXROB) {
- if ((x = cmcfm()) < 0) return(x);
- x = mlook(mactab,"robust",nmac);
- return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
- }
-#endif /* NOSPL */
-
- if (cx == XXSCRN) { /* SCREEN */
- int row, col;
- if ((x = cmkey(scntab, nscntab,"screen action","", xxstring)) < 0)
- return(x);
- switch (x) { /* MOVE-TO (cursor position) */
- case SCN_MOV:
- if ((y = cmnum("Row (1-based)","",10,&z,xxstring)) < 0)
- return(y);
- row = z;
- y = cmnum("Column (1-based)","1",10,&z,xxstring);
- if (y < 0)
- return(y);
- col = z;
- if ((y = cmcfm()) < 0)
- return(y);
- if (row < 0 || col < 0) {
- printf("?Row and Column must be 1 or greater\n");
- return(-9);
- }
- if (cmd_rows > 0 && row > cmd_rows)
- row = cmd_rows;
- if (cmd_cols > 0 && col > cmd_cols)
- col = cmd_cols;
- y = ck_curpos(row,col);
- return(success = (y > -1) ? 1 : 0);
-
- case SCN_CLR: /* CLEAR */
- if ((y = cmcfm()) < 0)
- return(y);
- debug(F100,"screen calling ck_cls()","",0);
- y = ck_cls();
- return(success = (y > -1) ? 1 : 0);
-
- case SCN_CLE: /* CLEOL */
- if ((y = cmcfm()) < 0)
- return(y);
- y = ck_cleol();
- return(success = (y > -1) ? 1 : 0);
- }
- }
-
-#ifndef NOHTTP
-#ifdef TCPSOCKET
- if (cx == XXHTTP)
- return(dohttp());
-#endif /* TCPSOCKET */
-#endif /* NOHTTP */
-
-#ifndef NOSPL
- if (cx == XXARRAY) { /* ARRAY */
-#ifndef NOSHOW
- extern int showarray();
-#endif /* NOSHOW */
- if ((x = cmkey(arraytab, narraytab,"Array operation","",xxstring)) < 0)
- return(x);
- switch (x) {
- case ARR_DCL:
- return(dodcl(XXDCL));
- case ARR_SRT:
- return(dosort());
-#ifndef NOSHOW
- case ARR_SHO:
- return(showarray());
-#endif /* NOSHOW */
- case ARR_CPY:
- return(copyarray());
- case ARR_SET:
- case ARR_CLR:
- return(clrarray(x));
- case ARR_DST:
- return(unarray());
- case ARR_RSZ:
- return(rszarray());
- case ARR_EQU:
- return(linkarray());
-
- default:
- printf("?Sorry, not implemented yet - \"%s\"\n",cmdbuf);
- return(-9);
- }
- }
- if (cx == XXTRACE) /* TRACE */
- return(dotrace());
-#endif /* NOSPL */
-
-#ifdef CK_PERMS
-#ifdef UNIX
- if (cx == XXCHMOD)
- return(douchmod()); /* Do Unix chmod */
-#endif /* UNIX */
-#endif /* CK_PERMS */
-
- if (cx == XXPROMP)
- return(doprompt());
-
- if (cx == XXGREP)
- return(dogrep());
-
- if (cx == XXDEBUG) { /* DEBUG */
-#ifndef DEBUG
- int dummy = 0;
- return(seton(&dummy));
-#else
- return(seton(&deblog));
-#endif /* DEBUG */
- }
- if (cx == XXMSG || cx == XXXMSG) { /* MESSAGE */
- extern int debmsg; /* Script debugging messages */
- if ((x = cmtxt("Message to print if SET DEBUG MESSAGE is ON or STDERR",
- "",&s,xxstring)) < 0)
- return(x);
- if (!s) /* Watch out for null result */
- s = ""; /* Make it an empty string */
- else /* Not null */
- s = brstrip(s); /* Strip braces and doublequotes */
- switch (debmsg) { /* Not debugging - don't print */
- case 0:
- break;
- case 1:
- printf("%s",s); /* Print to stdout */
- if (cx == XXMSG) printf("\n");
- break;
- case 2:
- fprintf(stderr,"%s",s); /* Ditto but print to stderr */
- if (cx == XXMSG) fprintf(stderr,"\n");
- break;
- }
- return(0); /* Return without affecting SUCCESS */
- }
-
-#ifdef CKLEARN
- if (cx == XXLEARN) { /* LEARN */
- struct FDB of, sw, cm;
- int closing = 0, off = 0, on = 0, confirmed = 0;
- char c;
-
- cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */
- _CMKEY, /* fcode */
- "Script file name, or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 3, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- learnswi, /* Keyword table */
- &of /* Pointer to next FDB */
- );
- cmfdbi(&of,_CMOFI,"","","",0,0,xxstring,NULL,&cm);
- cmfdbi(&cm,_CMCFM,"","","",0,0,NULL,NULL,NULL);
- line[0] = NUL;
-
- while (!confirmed) {
- x = cmfdb(&sw); /* Parse something */
- if (x < 0)
- return(x);
- switch (cmresult.fcode) { /* What was it? */
- case _CMOFI: /* Output file name */
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- break;
- case _CMKEY: /* Switch */
- c = cmgbrk();
- if ((c == ':' || c == '=') && !(cmgkwflgs() & CM_ARG)) {
- printf("?This switch does not take an argument\n");
- return(-9);
- }
- switch (cmresult.nresult) {
- case 2: /* /CLOSE */
- closing = 1; /* Fall thru on purpose */
- case 0: /* /OFF */
- off = 1;
- on = 0;
- break;
- case 1: /* /ON */
- on = 1;
- off = 0;
- break;
- }
- break;
- case _CMCFM: /* Confirmation */
- confirmed++;
- break;
- }
- }
- if (closing) {
- if (learnfp) {
- fclose(learnfp);
- learnfp = NULL;
- }
- makestr(&learnfile,NULL);
- }
- if (line[0]) {
- if (!on && !off)
- on = 1;
- if (learnfp) {
- fclose(learnfp);
- learnfp = NULL;
- }
- makestr(&learnfile,line);
- if (learnfile) {
- char * modes = "w";
- learnfp = fopen(learnfile,modes);
- if (!learnfp) {
- debug(F110,"LEARN file open error",learnfile,0);
- perror(learnfile);
- return(-9);
- } else {
-#ifdef ZFNQFP
- if (zfnqfp(learnfile,TMPBUFSIZ,tmpbuf))
- makestr(&learnfile,tmpbuf);
-#endif /* ZFNQFP */
- debug(F110,"LEARN file open ok",learnfile,0);
- if (!quiet) {
- printf("Recording to %s...\n\n",learnfile);
- printf(
-" WARNING: If you type your password during script recording, it will appear\n\
- in the file. Be sure to edit it or take other appropriate precautions.\n\n"
- );
- }
- fputs( "; Scriptfile: ",learnfp);
- fputs(learnfile,learnfp);
- fputs("\n; Directory: ",learnfp);
- fputs(zgtdir(),learnfp);
- fputs("\n; Recorded: ",learnfp);
- fputs(ckdate(),learnfp);
- fputs("\n",learnfp);
- }
- }
- }
- if (on) {
- learning = 1;
- } else if (off) {
- learning = 0;
- }
- debug(F101,"LEARN learning","",learning);
- return(success = 1);
- }
-#endif /* CKLEARN */
-
-#ifdef NEWFTP
- if (cx == XXUSER || cx == XXACCT) {
- if (!ftpisopen()) {
- printf("?FTP connection is not open\n");
- return(-9);
- }
- return(success = (cx == XXUSER) ? doftpusr() : doftpacct());
- }
- if (cx == XXSITE || cx == XXPASV) {
- if (!ftpisopen()) {
- printf("?FTP connection is not open\n");
- return(-9);
- }
- return(success = (cx == XXSITE) ? doftpsite() : dosetftppsv());
- }
-#endif /* NEWFTP */
-
- if (cx == XXORIE) { /* ORIENTATION */
- extern char * myname;
- int i, y, n = 0;
- char * s, *p, vbuf[32];
- char * vars[16]; char * legend[16];
-
- if ((y = cmcfm()) < 0)
- return(y);
-
- printf("\nProgram name:\n %s\n\n",myname);
- n += 4;
-
-#ifdef NT
- vars[0] = "home"; legend[0] = "Your home directory";
- vars[1] = "directory"; legend[1] = "K95's current directory";
- vars[2] = "exedir"; legend[2] = "K95 Program directory";
- vars[3] = "inidir"; legend[3] = "K95 Initialization file directory";
- vars[4] = "startup"; legend[4] = "Current directory when started";
-
- vars[5] = "common";
- legend[5] = "K95 data for all users and K95SITE.INI file";
-
- vars[6] = "personal"; legend[6] = "Your personal data directory tree";
- vars[7] = "desktop"; legend[7] = "Your deskop directory tree";
-
- vars[8] = "appdata";
- legend[8] = "Your personal K95 data tree and K95CUSTOM.INI file";
-
- vars[9] = "download"; legend[9] = "Your K95 download directory";
- vars[10] = "tmpdir"; legend[10] = "Your TEMP directory";
- vars[11] = NULL; legend[11] = NULL;
-
- for (i = 0; i < 16 && vars[i]; i++) {
- printf("%s:\n",legend[i]);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL);
- printf(" Variable: %s\n",vbuf);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- y = TMPBUFSIZ;
- s = tmpbuf;
- zzstring(vbuf,&s,&y);
- line[0] = NUL;
- ckGetLongPathName(tmpbuf,line,LINBUFSIZ);
- printf(" Long name: %s\n",line);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- line[0] = NUL;
- GetShortPathName(tmpbuf,line,LINBUFSIZ);
- printf(" Short name: %s\n",line);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
-#else /* NT */
-
- vars[0] = "home"; legend[0] = "Your home directory";
- vars[1] = "directory"; legend[1] = "Kermit's current directory";
- vars[2] = "exedir"; legend[2] = "Kermit's program directory";
- vars[3] = "inidir"; legend[3] = "Initialization file directory";
- vars[4] = "startup"; legend[4] = "Current directory when started";
- vars[5] = "download"; legend[5] = "Kermit download directory";
- vars[6] = NULL; legend[6] = NULL;
-
- for (i = 0; i < 16 && vars[i]; i++) {
- printf("%s:\n",legend[i]);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL);
- printf(" Variable: %s\n",vbuf);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- y = TMPBUFSIZ;
- s = tmpbuf;
- zzstring(vbuf,&s,&y);
- printf(" Value: %s\n",tmpbuf);
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- printf("\n");
- if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
- }
-#endif /* NT */
- return(success = 1);
- }
-
-#ifdef NT
- if (cx == XXDIALER) {
- StartDialer();
- return(success = 1);
- }
-#endif /* NT */
-
- if (cx == XXCONT) { /* CONTINUE */
- if ((x = cmcfm()) < 0)
- return(x);
- if (!xcmdsrc) { /* At prompt: continue script */
- if (cmdlvl > 0)
- popclvl(); /* Pop command level */
- return(success = 1); /* always succeeds */
-#ifndef NOSPL
- } else { /* In script: whatever... */
- x = mlook(mactab,"continue",nmac);
- /* Don't set success */
- return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
-#endif /* NOSPL */
- }
- }
-#ifdef UNIX
-#ifndef NOPUTENV
-/*
- NOTE: Syntax is PUTENV name value, not PUTENV name=value.
- I could check for this but it would be too much magic.
-*/
- if (cx == XXPUTE) { /* PUTENV */
- char * t = tmpbuf; /* Create or alter environment var */
- char * s1 = NULL, * s2 = NULL;
- if ((x = cmfld("Variable name","",&s,xxstring)) < 0)
- return(x);
- if (s) if (s == "") s = NULL;
- (VOID) makestr(&s1,s);
- if (s && !s1) {
- printf("?PUTENV - memory allocation failure\n");
- return(-9);
- }
- if ((x = cmtxt("Value","",&s,xxstring)) < 0)
- return(x);
- if (s) if (s == "") s = NULL;
- (VOID) makestr(&s2,s);
- success = doputenv(s1,s2);
- (VOID) makestr(&s1,NULL);
- (VOID) makestr(&s2,NULL);
- return(success);
- }
-#endif /* NOPUTENV */
-#endif /* UNIX */
-
- if (cx == XXNOTAV) { /* Command in table not available */
- ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
- if ((x = cmtxt("Rest of command","",&s,NULL)) < 0)
- return(x);
- printf("Sorry, \"%s\" not configured in this version of Kermit.\n",
- tmpbuf
- );
- return(success = 0);
- }
- return(-2); /* None of the above */
-
-} /* end of docmd() */
-
-#endif /* NOICP */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusr.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckuusr.h
deleted file mode 100644
index 83891fb..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusr.h
+++ /dev/null
@@ -1,3049 +0,0 @@
-/* C K U U S R . H -- Symbol definitions for C-Kermit ckuus*.c modules */
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#ifndef CKUUSR_H
-#define CKUUSR_H
-
-#include "ckucmd.h" /* Get symbols from command package */
-
-#ifndef NOLUCACHE /* Use lookup() cache */
-#ifndef NOSPL /* To speed up script programs */
-#ifndef USE_LUCACHE
-#define USE_LUCACHE
-#endif /* USE_LUCACHE */
-#endif /* NOSPL */
-#endif /* NOLUCACHE */
-
-#ifndef NODOUBLEQUOTING /* New to 8.0 */
-#define DOUBLEQUOTING /* Allow fields to be enclosed in */
-#endif /* NODOUBLEQUOTING */ /* doublequotes. */
-
-#ifndef NOLOCUS /* SET LOCUS */
-#define LOCUS
-#endif /* NOLOCUS */
-
-/* Sizes of things - FNVALL and MAXARGLEN increased from 8K 20050912 */
-
-#ifdef BIGBUFOK
-#define FNVALL CMDBL /* Function return value length */
-#define MAXARGLEN CMDBL /* Max func arg length after eval */
-#define MAXARGLIST 1024 /* Max number of args for a macro */
-#define FSPECL CMDBL /* Max length for MSEND/GET string */
-#define MSENDMAX 1024 /* Number of filespecs for MSEND */
-#define MAC_MAX 16384 /* Maximum number of macros */
-
-#else /* Same as above but for smaller builds... */
-
-#define FNVALL 1022
-#define MAXARGLEN 1023
-#define MAXARGLIST 64
-#define FSPECL 300
-#define MSENDMAX 128
-#define MAC_MAX 1024
-#endif /* BIGBUFOK */
-
-#define GVARS 127 /* Highest global var allowed */
-#ifdef BIGBUFOK
-#define VNAML 4096 /* Max length for variable name */
-#define ARRAYREFLEN 1024 /* Max length for array reference */
-#define FORDEPTH 32 /* Maximum depth of nested FOR loops */
-#define MAXTAKE 54 /* Maximum nesting of TAKE files */
-#define MACLEVEL 128 /* Maximum nesting for macros */
-#define INPBUFSIZ 4096 /* Size of INPUT buffer */
-#define PROMPTL 1024 /* Max length for prompt */
-#define LBLSIZ 8192 /* Maximum length for a GOTO label */
-#else
-#define VNAML 256 /* Max length for variable name */
-#define ARRAYREFLEN 128 /* Max length for array reference */
-#define FORDEPTH 10 /* Maximum depth of nested FOR loops */
-#define MAXTAKE 32 /* Maximum nesting of TAKE files */
-#define MACLEVEL 64 /* Maximum nesting for macros */
-#define INPBUFSIZ 256
-#define PROMPTL 256 /* Max length for prompt */
-#define LBLSIZ 128 /* Maximum length for a GOTO label */
-#endif /* BIGBUFOK */
-#define NARGS 10 /* Max number of macro arguments */
-#define LINBUFSIZ (CMDBL + 10) /* Size of line[] buffer */
-#define TMPBUFSIZ (CMDBL + 10) /* Size of temporary buffer */
-
-#define CMDSTKL ( MACLEVEL + MAXTAKE + 2) /* Command stack depth */
-
-#ifndef NOPURGE /* PURGE command */
-#ifdef UNIX
-#define CKPURGE
-#endif /* UNIX */
-#endif /* NOPURGE */
-
-#ifndef NOMINPUT /* MINPUT command */
-#ifndef NOSPL
-#define CK_MINPUT
-#ifndef MINPMAX
-#ifdef BIGBUFOK
-#define MINPMAX 96 /* Max number of MINPUT strings */
-#else
-#define MINPMAX 16
-#endif /* BIGBUFOK */
-#endif /* MINPMAX */
-#define MINPBUFL 256 /* Size of MINPUT temp buffer */
-#endif /* NOSPL */
-#endif /* NOMINPUT */
-
-#define ARRAYBASE 95 /* Lowest array-name character */
-
-#ifndef NOKERBANG
-#ifndef KERBANG
-#define KERBANG
-#endif /* KERBANG */
-#endif /* NOKERBANG */
-
-/* Bit values (1, 2, 4, 8, ...) for the ccflgs field */
-
-#define CF_APC 1 /* Executing an APC command */
-#define CF_KMAC 2 /* Executing a \Kmacro */
-#define CF_CMDL 4 /* Macro from -C "blah" command line */
-#define CF_REXX 8 /* Macro from REXX interpreter */
-#define CF_IMAC 16 /* Internal macro like FOR, WHILE... */
-
-struct cmdptr { /* Command stack structure */
- int src; /* Command Source */
- int lvl; /* Current TAKE or DO level */
- int ccflgs; /* Flags */
-};
-
-struct mtab { /* Macro table, like keyword table */
- char *kwd; /* But with pointers for vals */
- char *mval; /* instead of ints. */
- short flgs;
-};
-
-struct localvar { /* Local variable structure. */
- char * lv_name;
- char * lv_value;
- struct localvar * lv_next;
-};
-
-struct stringlist { /* General purpose string list */
- char * sl_name;
- struct stringlist * sl_next;
-};
-
-struct stringint { /* String and (wide) integer */
- char * sval; /* used mainly with command switches */
- int ival;
- CK_OFF_T wval;
-};
-
-#ifndef NOICP
-/*
- C-Kermit Initialization file...
-
- System-dependent defaults are built into the program, see below.
- These can be overridden in either of two ways:
- 1. CK_DSYSINI is defined at compile time, in which case a default
- system-wide initialization file name is chosen from below, or:
- 2: CK_SYSINI is defined to be a string, which lets the program
- builder choose the initialization filespec at compile time.
- These can be given on the CC command line, so the source code need not be
- changed.
-*/
-
-#ifndef CK_SYSINI /* If no initialization file given, */
-#ifdef CK_DSYSINI /* but CK_DSYSINI is defined... */
-
-/* Supply system-dependent "default default" initialization file */
-
-#ifdef UNIX /* For UNIX, system-wide */
-/* This allows one copy of the standard init file on the whole system, */
-/* rather than a separate copy in each user's home directory. */
-#ifdef HPUX10
-#define CK_SYSINI "/usr/share/lib/kermit/ckermit.ini"
-#else
-#ifdef CU_ACIS
-#define CK_SYSINI "/usr/share/lib/kermit/ckermit.ini"
-#else
-#ifdef __linux__
-#define CK_SYSINI "/usr/share/kermit/ckermit.ini"
-#else
-#define CK_SYSINI "/usr/local/bin/ckermit.ini"
-#endif /* linux */
-#endif /* CU_ACIS */
-#endif /* HPUX10 */
-/* Fill in #else..#ifdef's here for VMS, OS/2, etc. */
-/* Fill in matching #endif's here. */
-#endif /* UNIX */
-
-#endif /* CK_DSYSINI */
-#endif /* CK_SYSINI */
-
-#ifdef CK_SYSINI /* Init-file precedence */
-#ifndef CK_INI_A /* A means system-wide file first */
-#ifndef CK_INI_B /* B means user's first */
-#define CK_INI_A /* A is default */
-#endif /* CK_INI_B */
-#endif /* CK_INI_A */
-#else
-#ifdef CK_INI_A /* Otherwise */
-#undef CK_INI_A /* make sure these aren't defined */
-#endif /* CK_INI_A */
-#ifdef CK_INI_B
-#undef CK_INI_B
-#endif /* CK_INI_B */
-#endif /* CK_SYSINI */
-
-#ifdef CK_SYSINI /* One more check... */
-#ifdef CK_INI_A /* Make sure they're not both */
-#ifdef CK_INI_B /* defined. */
-#undef CK_INI_B
-#endif /* CK_INI_B */
-#endif /* CK_INI_A */
-#endif /* CK_SYSINI */
-/*
- If neither CK_DSYSINI nor CK_SYSINI are defined, these are the
- built-in defaults for each platform. USE_CUSTOM means to execute the
- customization file automatically if the initialization file is not found.
-*/
-#ifndef NOCUSTOM
-#ifndef USE_CUSTOM
-#define USE_CUSTOM
-#endif /* USE_CUSTOM */
-#endif /* NOCUSTOM */
-
-#ifndef KERMRCL /* Path length for init file */
-#define KERMRCL CKMAXPATH
-#endif /* KERMRCL */
-
-#ifdef vms
-#define KERMRC "CKERMIT.INI" /* Init file name */
-#define MYCUSTOM "CKERMOD.INI" /* Customization file name */
-#else
-#ifdef OS2
-#ifdef NT
-#define KERMRC "k95.ini"
-#define MYCUSTOM "k95custom.ini"
-#else
-#define KERMRC "k2.ini"
-#define MYCUSTOM "k2custom.ini"
-#endif /* NT */
-#else
-#ifdef UNIXOROSK
-#define KERMRC ".kermrc"
-#define MYCUSTOM ".mykermrc"
-#else
-#ifdef STRATUS
-#define KERMRC "ckermit.ini"
-#define MYCUSTOM "ckermod.ini"
-#else
-#define KERMRC "CKERMIT.INI"
-#define MYCUSTOM "ckermod.ini"
-#endif /* STRATUS */
-#endif /* UNIXOROSK */
-#endif /* OS2 */
-#endif /* vms */
-
-#ifndef KERMRCL
-#define KERMRCL 256
-#endif /* KERMRCL */
-#endif /* NOICP */
-
-/* User interface features */
-
-#ifdef CK_CURSES /* Thermometer */
-#ifndef NO_PCT_BAR
-#ifndef CK_PCT_BAR
-#define CK_PCT_BAR
-#endif /* NO_PCT_BAR */
-#endif /* CK_PCT_BAR */
-#endif /* CK_CURSES */
-
-#ifdef KUI /* KUI requires the Thermometer code */
-#ifndef NO_PCT_BAR
-#ifndef CK_PCT_BAR
-#define CK_PCT_BAR
-#endif /* NO_PCT_BAR */
-#endif /* CK_PCT_BAR */
-#endif /* KUI */
-
-/* Includes */
-
-#ifdef MINIX
-/* why? */
-#include <sys/types.h>
-#endif /* MINIX */
-
-/* Symbols for command source */
-
-#define CMD_KB 0 /* KeyBoard or standard input */
-#define CMD_TF 1 /* TAKE command File */
-#define CMD_MD 2 /* Macro Definition */
-
-/*
- SET TRANSFER CANCELLATION command should be available in all versions.
- But for now...
-*/
-#ifdef UNIX /* UNIX has it */
-#ifndef XFRCAN
-#define XFRCAN
-#endif /* XFRCAN */
-#endif /* UNIX */
-#ifdef VMS /* VMS has it */
-#ifndef XFRCAN
-#define XFRCAN
-#endif /* XFRCAN */
-#endif /* VMS */
-#ifdef datageneral /* DG AOS/VS has it */
-#ifndef XFRCAN
-#define XFRCAN
-#endif /* XFRCAN */
-#endif /* datageneral */
-#ifdef STRATUS /* Stratus VOS has it */
-#ifndef XFRCAN
-#define XFRCAN
-#endif /* XFRCAN */
-#endif /* STRATUS */
-#ifdef OSK /* OS-9 */
-#ifndef XFRCAN
-#define XFRCAN
-#endif /* XFRCAN */
-#endif /* OSK */
-
-#ifndef NOCMDL
-/* Extended Command-Line Option Codes (keep alphabetical by keyword) */
-
-#define XA_ANON 0 /* --anonymous */
-#define XA_BAFI 1 /* --bannerfile */
-#define XA_CDFI 2 /* --cdfile */
-#define XA_CDMS 3 /* --cdmessage */
-#define XA_HELP 4 /* --help */
-#define XA_HEFI 5 /* --helpfile */
-#define XA_IKFI 6 /* --xferfile */
-#define XA_IKLG 7 /* --xferlog */
-#define XA_ANFI 8 /* --initfile */
-#define XA_PERM 9 /* --permissions */
-#define XA_ROOT 10 /* --root */
-#define XA_SYSL 11 /* --syslog */
-#define XA_USFI 12 /* --userfile */
-#define XA_WTFI 13 /* --wtmpfile */
-#define XA_WTMP 14 /* --wtmplog */
-#define XA_TIMO 15 /* --timeout */
-#define XA_NOIN 16 /* --nointerrupts */
-#define XA_DBAS 17 /* --database */
-#define XA_DBFI 18 /* --dbfile */
-#define XA_PRIV 19 /* --privid */
-#define XA_VERS 20 /* --version */
-#define XA_NPRM 21 /* --noperms */
-#define XA_XPOS 22 /* Window position X coordinate */
-#define XA_YPOS 23 /* Window position Y coordinate */
-#define XA_FNAM 24 /* Font Facename */
-#define XA_FSIZ 25 /* Font Size */
-#define XA_TERM 26 /* Terminal type */
-#define XA_CSET 27 /* Remote Character Set */
-#define XA_ROWS 28 /* Screen rows (height) */
-#define XA_COLS 29 /* Screen columns (width) */
-#define XA_TEL 30 /* Make a Telnet connection */
-#define XA_FTP 31 /* Make an FTP connection */
-#define XA_SSH 32 /* Make an SSH connection */
-#define XA_USER 33 /* Username for login */
-#define XA_PASS 34 /* Password for login */
-#define XA_TITL 35 /* Window Title */
-#define XA_NOMN 36 /* No GUI Menu Bar */
-#define XA_NOTB 37 /* No GUI Tool Bar */
-#define XA_NOSB 38 /* No GUI Status Bar */
-#define XA_NOPUSH 39 /* Disable external commands */
-#define XA_NOSCROLL 40 /* Disable scrollback operations */
-#define XA_NOESCAPE 41 /* Disable escape from connect mode */
-#define XA_LOCK 42 /* All lockdown options */
-#define XA_NOBAR 43 /* No GUI Bars */
-#define XA_WMAX 44
-#define XA_WMIN 45
-#define XA_SCALE 46 /* GUI Scale Font */
-#define XA_CHGD 47 /* GUI Change Dimensions */
-#define XA_NOCLOSE 48 /* GUI Disable Close Window */
-#define XA_UNBUF 49 /* UNIX unbuffered console */
-#define XA_MAX 49 /* Highest extended option number */
-#endif /* NOCMDL */
-
-#ifndef NOICP
-/* Top Level Commands */
-/* Values associated with top-level commands must be 0 or greater. */
-
-#define XXBYE 0 /* BYE */
-#define XXCLE 1 /* CLEAR */
-#define XXCLO 2 /* CLOSE */
-#define XXCON 3 /* CONNECT */
-#define XXCPY 4 /* COPY */
-#define XXCWD 5 /* CWD (Change Working Directory) */
-#define XXDEF 6 /* DEFINE (a macro or variable) */
-#define XXDEL 7 /* (Local) DELETE */
-#define XXDIR 8 /* (Local) DIRECTORY */
-
-/* DIRECTORY Command options... */
-#define DIR_BRF 1 /* BRIEF */
-#define DIR_VRB 2 /* VERBOSE */
-#define DIR_PAG 3 /* PAGE */
-#define DIR_NOP 4 /* NOPAGE */
-#define DIR_ISO 5 /* ISODATE */
-#define DIR_DAT 6 /* ENGLISHDATE */
-#define DIR_HDG 7 /* HEADINGS */
-#define DIR_NOH 8 /* NOHEADINGS */
-#define DIR_SRT 9 /* SORT */
-#define DIR_NOS 10 /* NOSORT */
-#define DIR_ASC 11 /* ASCENDING */
-#define DIR_DSC 12 /* DESCENDING */
-#define DIR_REC 13 /* RECURSIVE */
-#define DIR_NOR 14 /* NORECURIVE */
-#define DIR_DOT 15 /* DOTFILES */
-#define DIR_NOD 16 /* NODOTFILES */
-#define DIR_DIR 17 /* DIRECTORIES */
-#define DIR_FIL 18 /* FILES */
-#define DIR_ALL 19 /* ALL */
-#define DIR_NAM 20 /* NAMES: */
-#define DIR_TYP 21 /* FILETYPES */
-#define DIR_NOT 22 /* NOFILETYPES */
-#define DIR_BUP 23 /* BACKUP */
-#define DIR_NOB 24 /* NOBACKUP */
-#define DIR_MSG 25 /* MESSAGE */
-#define DIR_NOM 26 /* NOMESSAGE */
-#define DIR_ARR 27 /* ARRAY: */
-#define DIR_NAR 28 /* NOARRAY */
-#define DIR_EXC 29 /* EXCEPT: */
-#define DIR_LAR 30 /* LARGER-THAN: */
-#define DIR_SMA 31 /* SMALLER-THAN: */
-#define DIR_AFT 32 /* AFTER: */
-#define DIR_NAF 33 /* NOT-AFTER: */
-#define DIR_BEF 34 /* BEFORE: */
-#define DIR_NBF 35 /* NOT-BEFORE: */
-#define DIR_SUM 36 /* SUMMARY */
-#define DIR_BIN 37 /* TYPE (only show binary or text) */
-#define DIR_LNK 38 /* follow symlinks */
-#define DIR_NLK 39 /* don't follow symlinks */
-#define DIR_OUT 40 /* Output file for listing */
-#define DIR_TOP 41 /* Top n lines */
-#define DIR_COU 42 /* COUNT:var */
-#define DIR_NOL 43 /* NOLINKS (don't show symlinks at at all) */
-
-#define DIRS_NM 0 /* Sort directory by NAME */
-#define DIRS_DT 1 /* Sort directory by DATE */
-#define DIRS_SZ 2 /* Sort directory by SIZE */
-
-#define XXDIS 9 /* DISABLE */
-#define XXECH 10 /* ECHO */
-#define XXEXI 11 /* EXIT */
-#define XXFIN 12 /* FINISH */
-#define XXGET 13 /* GET */
-#define XXHLP 14 /* HELP */
-#define XXINP 15 /* INPUT */
-#define XXLOC 16 /* LOCAL */
-#define XXLOG 17 /* LOG */
-#define XXMAI 18 /* MAIL */
-#define XXMOU 19 /* (Local) MOUNT */
-#define XXMSG 20 /* (Local) MESSAGE */
-#define XXOUT 21 /* OUTPUT */
-#define XXPAU 22 /* PAUSE */
-#define XXPRI 23 /* (Local) PRINT */
-#define XXQUI 24 /* QUIT */
-#define XXREC 25 /* RECEIVE */
-#define XXREM 26 /* REMOTE */
-#define XXREN 27 /* (Local) RENAME */
-#define XXSEN 28 /* SEND */
-
-/* SEND switches */
-
-#define SND_BIN 0 /* Binary mode */
-#define SND_DEL 1 /* Delete after */
-#define SND_EXC 2 /* Except */
-#define SND_LAR 3 /* Larger than */
-#define SND_MAI 4 /* Mail */
-#define SND_BEF 5 /* Before */
-#define SND_AFT 6 /* After */
-#define SND_PRI 7 /* Print */
-#define SND_SHH 8 /* Quiet */
-#define SND_REC 9 /* Recursive */
-#define SND_SMA 10 /* Smaller than */
-#define SND_STA 11 /* Starting-from */
-#define SND_TXT 12 /* Text mode */
-#define SND_CMD 13 /* From command (pipe) */
-#define SND_RES 14 /* Resend/Recover */
-#define SND_PRO 15 /* Protocol */
-#define SND_ASN 16 /* As-name */
-#define SND_IMG 17 /* Image */
-#define SND_LBL 18 /* Labeled */
-#define SND_NAF 19 /* Not-After */
-#define SND_NBE 20 /* Not-Before */
-#define SND_FLT 21 /* Filter */
-#define SND_PTH 22 /* Pathnames */
-#define SND_NAM 23 /* Filenames */
-#define SND_MOV 24 /* MOVE to another directory */
-#define SND_REN 25 /* RENAME after sending */
-#define SND_CAL 26 /* Calibrate */
-#define SND_FIL 27 /* File containing list of files to send */
-#define SND_NOB 28 /* Skip backup files */
-#define SND_DOT 29 /* Include dot-files */
-#define SND_NOD 30 /* Exclude dot-files */
-#define SND_ARR 31 /* Send from array */
-#define SND_TYP 32 /* TYPE (only send text (or binary)) */
-#define SND_XPA 33 /* TRANSPARENT */
-#define SND_PIP 34 /* PIPES */
-#define SND_ERR 35 /* ERROR */
-#define SND_CSL 36 /* Local character set */
-#define SND_CSR 37 /* Remote character set */
-#define SND_UPD 38 /* Update */
-#define SND_COL 39 /* Collision */
-#define SND_NML 40 /* Namelist */
-#define SND_SRN 41 /* Server-Rename */
-#define SND_LNK 42 /* Follow links */
-#define SND_NLK 43 /* Don't follow links */
-#define SND_SIM 44 /* Simulate */
-#define SND_DIF 45 /* If dates Differ */
-#define SND_PAT 46 /* Pattern to use locally when GET'ing */
-#define SND_NLS 47 /* (FTP only) MGET forces NLST */
-#define SND_MLS 48 /* (FTP only) MGET forces MLSD */
-
-#define SND_MAX 48 /* Highest SEND switch */
-
-#define XXSER 29 /* SERVER */
-#define XXSET 30 /* SET */
-#define XXSHE 31 /* Command for SHELL */
-#define XXSHO 32 /* SHOW */
-#define XXSPA 33 /* (Local) SPACE */
-#define XXSTA 34 /* STATISTICS */
-#define XXSUB 35 /* (Local) SUBMIT */
-#define XXTAK 36 /* TAKE */
-#define XXTRA 37 /* TRANSMIT */
-#define XXTYP 38 /* (Local) TYPE */
-#define XXWHO 39 /* (Local) WHO */
-#define XXDIAL 40 /* (Local) DIAL */
-#define XXLOGI 41 /* (Local) SCRIPT */
-#define XXCOM 42 /* Comment */
-#define XXHAN 43 /* HANGUP */
-#define XXXLA 44 /* TRANSLATE */
-#define XXIF 45 /* IF */
-#define XXLBL 46 /* label */
-#define XXGOTO 47 /* GOTO */
-#define XXEND 48 /* END */
-#define XXSTO 49 /* STOP */
-#define XXDO 50 /* DO */
-#define XXPWD 51 /* PWD */
-#define XXTES 52 /* TEST */
-#define XXASK 53 /* ASK */
-#define XXASKQ 54 /* ASKQ */
-#define XXASS 55 /* ASSIGN */
-#define XXREI 56 /* REINPUT */
-#define XXINC 57 /* INCREMENT */
-#define XXDEC 59 /* DECREMENT */
-#define XXELS 60 /* ELSE */
-#define XXEXE 61 /* EXECUTE */
-#define XXWAI 62 /* WAIT */
-#define XXVER 63 /* VERSION */
-#define XXENA 64 /* ENABLE */
-#define XXWRI 65 /* WRITE */
-#define XXCLS 66 /* CLS (clear screen) */
-#define XXRET 67 /* RETURN */
-#define XXOPE 68 /* OPEN */
-#define XXREA 69 /* READ */
-#define XXON 70 /* ON */
-#define XXDCL 71 /* DECLARE */
-#define XXBEG 72 /* BEGIN (not used) */
-#define XXFOR 72 /* FOR */
-#define XXWHI 73 /* WHILE */
-#define XXIFX 74 /* Extended IF */
-#define XXCMS 75 /* SEND from command output (not yet) */
-#define XXCMR 76 /* RECEIVE to a command's input (not yet) */
-#define XXCMG 77 /* GET to a command's input (not yet) */
-#define XXSUS 78 /* SUSPEND */
-#define XXERR 79 /* ERROR */
-#define XXMSE 80 /* MSEND */
-#define XXBUG 81 /* BUG */
-#define XXPAD 82 /* PAD (as in X.25 PAD) ANYX25 */
-#define XXRED 83 /* REDIAL */
-#define XXGTA 84 /* _getargs (invisible internal) */
-#define XXPTA 85 /* _putargs (invisible internal) */
-#define XXGOK 86 /* GETOK - Ask for YES/NO */
-#define XXTEL 87 /* TELNET */
-#define XXASX 88 /* _ASSIGN (evaluates var name) */
-#define XXDFX 89 /* _DEFINE (evaluates var name) */
-#define XXPNG 90 /* PING (for TCP/IP) */
-#define XXINT 91 /* INTRODUCTION */
-#define XXCHK 92 /* CHECK (a feature) */
-#define XXMSL 93 /* MSLEEP, MPAUSE (millisecond sleep) */
-#define XXNEW 94 /* NEWS */
-#define XXAPC 95 /* APC */
-#define XXFUN 96 /* REDIRECT */
-#define XXWRL 97 /* WRITE-LINE */
-#define XXREXX 98 /* Rexx */
-#define XXMINP 100 /* MINPUT */
-#define XXRSEN 101 /* RESEND */
-#define XXPSEN 102 /* PSEND */
-#define XXGETC 103 /* GETC */
-#define XXEVAL 104 /* EVALUATE */
-#define XXFWD 105 /* FORWARD */
-#define XXUPD 106 /* UPDATES */
-#define XXBEEP 107 /* BEEP */
-#define XXMOVE 108 /* MOVE */
-#define XXMMOVE 109 /* MMOVE */
-#define XXREGET 110 /* REGET */
-#define XXLOOK 111 /* LOOKUP */
-#define XXVIEW 112 /* VIEW (terminal buffer) */
-#define XXANSW 113 /* ANSWER (the phone) */
-#define XXPDIA 114 /* PDIAL (partial dial) */
-#define XXASC 115 /* ASCII / TEXT */
-#define XXBIN 116 /* BINARY */
-#define XXFTP 117 /* FTP */
-#define XXMKDIR 118 /* MKDIR */
-#define XXRMDIR 119 /* RMDIR */
-#define XXTELOP 120 /* TELOPT */
-#define XXRLOG 121 /* RLOGIN */
-#define XXUNDEF 122 /* UNDEFINE */
-#define XXNPSH 123 /* NOPUSH */
-#define XXADD 124 /* ADD */
-#define ADD_SND 0 /* ADD SEND-LIST */
-#define ADD_BIN 1 /* ADD BINARY-PATTERNS */
-#define ADD_TXT 2 /* ADD TEXT-PATTERNS */
-#define XXLOCAL 125 /* LOCAL */
-#define XXKERMI 126 /* KERMIT */
-#define XXDATE 127 /* DATE */
-#define XXSWIT 128 /* SWITCH */
-#define XXXFWD 129 /* _FORWARD */
-#define XXSAVE 130 /* SAVE */
-#define XXXECH 131 /* XECHO */
-#define XXRDBL 132 /* READBLOCK */
-#define XXWRBL 133 /* WRITEBLOCK */
-#define XXRETR 134 /* RETRIEVE */
-#define XXEIGHT 135 /* EIGHTBIT */
-#define XXEDIT 136 /* EDIT */
-#define XXCSEN 137 /* CSEND */
-#define XXCREC 138 /* CRECEIVE */
-#define XXCQ 139 /* CQ */
-#define XXTAPI 140 /* TAPI actions such as dialogs */
-#define XXRES 141 /* RESET */
-#define XXCGET 142 /* CGET */
-#define XXFUNC 143 /* Function (help-only) */
-#define XXKVRB 144 /* Kverb (help-only) */
-#define XXBROWS 145 /* BROWSE */
-#define XXMGET 146 /* MGET */
-#define XXBACK 147 /* BACK */
-#define XXWHERE 148 /* WHERE */
-#define XXREDO 149 /* REDO */
-#define XXEXCH 150 /* EXCHANGE */
-#define XXREMV 151 /* REMOVE */
-#define XXCHRT 152 /* CHROOT */
-#define XXOPTS 153 /* Options (help-only) */
-#define XXAUTH 154 /* AUTHORIZE */
-#define XXPIPE 155 /* PIPE */
-#define XXSSH 156 /* SSH */
-#define XXTERM 157 /* TERMINAL */
-#define XXSTATUS 158 /* STATUS */
-#define XXCPR 159 /* COPYRIGHT */
-#define XXASSER 160 /* ASSERT */
-#define XXSUCC 161 /* SUCCEED */
-#define XXFAIL 162 /* FAIL */
-#define XXLOGIN 163 /* LOGIN */
-#define XXLOGOUT 164 /* LOGOUT */
-#define XXNLCL 165 /* NOLOCAL */
-#define XXWILD 166 /* WILDCARDS (help-only) */
-
-/* One-word synonyms for REMOTE commands */
-
-#define XXRCPY 167 /* REMOTE COPY */
-#define XXRCWD 168 /* Change Working Directory */
-#define XXRDEL 169 /* Delete */
-#define XXRDIR 170 /* Directory */
-#define XXRHLP 171 /* Help */
-#define XXRHOS 172 /* Host */
-#define XXRKER 173 /* Kermit */
-#define XXRMSG 174 /* Message */
-#define XXRPRI 175 /* Print */
-#define XXRREN 176 /* Rename */
-#define XXRSET 177 /* Set */
-#define XXRSPA 178 /* Space */
-#define XXRSUB 179 /* Submit */
-#define XXRTYP 180 /* Type */
-#define XXRWHO 181 /* Who */
-#define XXRPWD 182 /* Print Working Directory */
-#define XXRQUE 183 /* Query */
-#define XXRASG 184 /* Assign */
-#define XXRMKD 185 /* mkdir */
-#define XXRRMD 186 /* rmdir */
-#define XXRXIT 187 /* Exit */
-
-/* Top-Level commands, cont'd... */
-
-#define XXGETK 188 /* GETKEYCODE */
-#define XXMORE 189 /* MORE */
-#define XXXOPTS 190 /* Extended-Options (help-only) */
-#define XXIKSD 191 /* IKSD */
-#define XXRESET 192 /* RESET */
-#define XXASSOC 193 /* ASSOCIATE */
-
-#define ASSOC_FC 0 /* ASSOCIATE FILE-CHARACTER-SET */
-#define ASSOC_TC 1 /* ASSOCIATE TRANSFER-CHARACTER-SET */
-
-#define XXSHIFT 194 /* SHIFT */
-#define XXMAN 195 /* MANUAL */
-#define XXLS 196 /* LS */
-#define XXSORT 197 /* SORT */
-#define XXPURGE 198 /* PURGE */
-#define XXFAST 199 /* FAST */
-#define XXCAU 200 /* CAUTIOUS */
-#define XXROB 201 /* ROBUST */
-#define XXMACRO 202 /* Immediate macro */
-#define XXSCRN 203 /* SCREEN */
-#define XXLNOUT 204 /* LINEOUT */
-#define XX_INCR 205 /* _INCREMENT */
-#define XX_DECR 206 /* _DECREMENT */
-#define XX_EVAL 207 /* _EVALUATE */
-#define XXARRAY 208 /* ARRAY */
-#define XXPARSE 209 /* PARSE */
-#define XXHTTP 210 /* HTTP */
-
-#ifdef CKCHANNELIO
-#define XXFILE 211 /* FILE */
-#define XXF_CL 212 /* FCLOSE */
-#define XXF_FL 213 /* FFLUSH */
-#define XXF_LI 214 /* FLIST */
-#define XXF_OP 215 /* FOPEN */
-#define XXF_RE 216 /* FREAD */
-#define XXF_SE 217 /* FSEEK */
-#define XXF_ST 218 /* FSTATUS */
-#define XXF_WR 219 /* FWRITE */
-#define XXF_RW 220 /* FREWIND */
-#define XXF_CO 221 /* FCOUNT */
-#endif /* CKCHANNELIO */
-
-#define XXEXEC 222 /* exec() */
-#define XXTRACE 223 /* TRACE */
-#define XXNOTAV 224 /* The "not available" command */
-#define XXPTY 225 /* PTY (like PIPE) */
-#define XXCHMOD 226 /* CHMOD */
-#define XXPROMP 227 /* PROMPT */
-#define XXFEACH 228 /* FOREACH */
-#define XXGREP 229 /* GREP */
-#define XXSEXP 230 /* S-Expression */
-#define XXUNDCL 231 /* UNDECLARE */
-#define XXVOID 232 /* VOID */
-#define XXPUT 233 /* PUT */
-#define XXUNDFX 234 /* _UNDEFINE */
-#define XXHEAD 235 /* HEAD */
-#define XXTAIL 236 /* TAIL */
-#define XXDEBUG 237 /* DEBUG */
-#define XXLEARN 238 /* LEARN */
-#define XXPAT 239 /* PATTERNS (help only) */
-
-#define XXCDUP 240 /* CDUP (Change working directory upwards) */
-#define XXRCDUP 241 /* REMOTE CDUP */
-#define XXCAT 242 /* CAT (= TYPE /NOPAGE) */
-#define XXFIREW 243 /* FIREWALL (help only) */
-
-#define XXLCWD 244 /* Local C(W)D */
-#define XXLCDU 245 /* Local CDUP */
-#define XXLPWD 246 /* Local PWD */
-#define XXLDEL 247 /* Local DELETE */
-#define XXLDIR 248 /* Local DIRECTORY */
-#define XXLREN 249 /* Local RENAME */
-#define XXLMKD 250 /* Local MKDIR */
-#define XXLRMD 251 /* Local RMDIR */
-#define XXUSER 252 /* (FTP) USER */
-#define XXACCT 253 /* (FTP) ACCOUNT */
-#define XXLINK 254 /* LINK source destination */
-#define XXORIE 255 /* ORIENT(ATION) */
-#define XXDIALER 256 /* DIALER */
-#define XXKCD 257 /* KCD */
-#define XXSITE 258 /* (FTP) SITE */
-#define XXPASV 259 /* (FTP) PASSIVE */
-#define XXCONT 260 /* CONTINUE */
-#define XXNSCR 261 /* NOSCROLL */
-#define XXSFTP 262 /* SFTP */
-#define XXSKRM 263 /* SKERMIT */
-#define XXWDIR 264 /* WDIRECTORY */
-#define XXHDIR 265 /* HDIRECTORY */
-#define XXTOUC 266 /* TOUCH */
-#define XXLOCU 267 /* LOCUS (for HELP) */
-#define XXPUTE 268 /* PUTENV */
-#define XXXMSG 269 /* XMESSAGE */
-
-/* End of Top-Level Commands */
-
-#define SCN_CLR 0 /* SCREEN CLEAR */
-#define SCN_CLE 1 /* SCREEN CLEOL */
-#define SCN_MOV 2 /* SCREEN MOVE */
-
-/* ARRAY operations */
-
-#define ARR_DCL 0 /* Declare */
-#define ARR_CPY 1 /* Copy */
-#define ARR_RSZ 2 /* Resize */
-#define ARR_SRT 3 /* Sort */
-#define ARR_CLR 4 /* Clear */
-#define ARR_SEA 5 /* Search */
-#define ARR_DST 6 /* Destroy */
-#define ARR_SHO 7 /* Show */
-#define ARR_SET 8 /* Set */
-#define ARR_EQU 9 /* Equate */
-
-/* SORT options */
-
-#define SRT_CAS 0 /* /CASE */
-#define SRT_KEY 1 /* /KEY:n */
-#define SRT_REV 2 /* /REVERSE */
-#define SRT_RNG 3 /* /RANGE:n:m */
-#define SRT_NUM 4 /* /NUMERIC */
-
-/* PURGE command options */
-
-#define PU_KEEP 0 /* /KEEP: */
-#define PU_LIST 1 /* /LIST */
-#define PU_PAGE 2 /* /PAGE */
-#define PU_NOPA 3 /* /NOPAGE */
-#define PU_NODE 4 /* /SIMULATE */
-#define PU_DELE 5 /* /DELETE */
-#define PU_NOLI 6 /* /NOLIST */
-#define PU_QUIE 7 /* /QUIET (= NOLIST) */
-#define PU_VERB 8 /* /VERBOSE (= LIST) */
-#define PU_ASK 9 /* /ASK */
-#define PU_NASK 10 /* /NOASK */
-#define PU_LAR 11 /* /LARGER-THAN: */
-#define PU_SMA 12 /* /SMALLER-THAN: */
-#define PU_AFT 13 /* /AFTER: */
-#define PU_NAF 14 /* /NOT-AFTER: */
-#define PU_BEF 15 /* /BEFORE: */
-#define PU_NBF 16 /* /NOT-BEFORE: */
-#define PU_EXC 17 /* /EXCEPT: */
-#define PU_RECU 18 /* /RECURSIVE */
-#define PU_DOT 19 /* /DOTFILES */
-#define PU_NODOT 20 /* /NODOTFILES */
-#define PU_HDG 21 /* /HEADING */
-#define PU_NOH 22 /* /NOHEADING */
-
-/* DELETE command options */
-
-#define DEL_NOL 0 /* /NOLIST */
-#define DEL_LIS 1 /* /LIST */
-#define DEL_HDG 2 /* /HEADINGS */
-#define DEL_NOH 2 /* /NOHEADINGS */
-#define DEL_BEF 3 /* /BEFORE: */
-#define DEL_NBF 4 /* /NOT-BEFORE: */
-#define DEL_AFT 5 /* /AFTER: */
-#define DEL_NAF 6 /* /NOT-AFTER: */
-#define DEL_DOT 7 /* /DOTFILES */
-#define DEL_NOD 8 /* /NODOTFILES */
-#define DEL_EXC 9 /* /EXCEPT:*/
-#define DEL_PAG 10 /* /PAGE */
-#define DEL_NOP 11 /* /NOPAGE */
-#define DEL_REC 12 /* /RECURSIVE */
-#define DEL_NOR 13 /* /NORECURSIVE */
-#define DEL_VRB 14 /* /VERBOSE */
-#define DEL_QUI 15 /* /QUIET */
-#define DEL_SMA 16 /* /SMALLER-THAN: */
-#define DEL_LAR 17 /* /LARGER-THAN: */
-#define DEL_SIM 18 /* /SIMULATE */
-#define DEL_ASK 19 /* /ASK */
-#define DEL_NAS 20 /* /NOASK */
-#define DEL_SUM 21 /* /SUMMARY */
-#define DEL_DIR 22 /* /DIRECTORY */
-#define DEL_ALL 23 /* /ALL */
-#define DEL_TYP 24 /* /TYPE: */
-#define DEL_LNK 25 /* /FOLLOWLINKS */
-#define DEL_NLK 26 /* /NOFOLLOWLINKS */
-
-/* RENAME switches that can be used in the same table as the DEL switches */
-
-#define REN_LOW 100 /* Convert to lowercase */
-#define REN_UPP 101 /* Converto to uppercase */
-#define REN_RPL 102 /* String replacement */
-#define REN_OVW 103 /* Overwrite file with same name */
-#define REN_XLA 104 /* Translate character sets */
-#define REN_SPA 105 /* Fix spaces */
-
-/* FILE operations */
-
-#define FIL_OPN 0 /* OPEN */
-#define FIL_CLS 1 /* CLOSE */
-#define FIL_REA 2 /* READ */
-#define FIL_GET 3 /* GET */
-#define FIL_WRI 4 /* WRITE */
-#define FIL_REW 5 /* REWIND */
-#define FIL_LIS 6 /* LIST */
-#define FIL_FLU 7 /* FLUSH */
-#define FIL_SEE 8 /* SEEK */
-#define FIL_STA 9 /* STATUS */
-#define FIL_COU 10 /* COUNT */
-
-/* OPEN / CLOSE items */
-
-#define OPN_FI_R 1 /* FILE READ */
-#define OPN_FI_W 2 /* FILE WRITE */
-#define OPN_FI_A 3 /* FILE APPEND */
-#define OPN_PI_R 4 /* PIPE READ */
-#define OPN_PI_W 5 /* PIPE WRITE */
-#define OPN_PT_R 6 /* PTY READ */
-#define OPN_PT_W 7 /* PTY WRITE */
-#define OPN_SER 8 /* PORT or LINE */
-#define OPN_NET 9 /* HOST */
-
-/* KERBEROS command switches */
-
-#define KRB_S_VE 0 /* /VERSION */
-#define KRB_S_CA 1 /* /CACHE: */
-#define KRB_S_MAX 1 /* Highest KERBEROS switch number */
-
-#ifdef CK_KERBEROS
-
-/* KERBEROS actions */
-
-#define KRB_A_IN 0 /* INITIALIZE */
-#define KRB_A_DE 1 /* DESTROY */
-#define KRB_A_LC 2 /* LIST-CREDENTIALS */
-
-/* KERBEROS INIT switches */
-
-#define KRB_I_FW 0 /* /FORWARDABLE */
-#define KRB_I_LF 1 /* /LIFETIME: */
-#define KRB_I_PD 2 /* /POSTDATE: */
-#define KRB_I_PR 3 /* /PROXIABLE */
-#define KRB_I_RB 4 /* /RENEWABLE: */
-#define KRB_I_RN 5 /* /RENEW */
-#define KRB_I_SR 6 /* /SERVICE: */
-#define KRB_I_VA 7 /* /VALIDATE */
-#define KRB_I_RL 8 /* /REALM: */
-#define KRB_I_IN 9 /* /INSTANCE: */
-#define KRB_I_PW 10 /* /PASSWORD: */
-#define KRB_I_PA 11 /* /PREAUTH */
-#define KRB_I_VB 12 /* /VERBOSE */
-#define KRB_I_BR 13 /* /BRIEF */
-#define KRB_I_NFW 14 /* /NOT-FORWARDABLE */
-#define KRB_I_NPR 15 /* /NOT-PROXIABLE */
-#define KRB_I_NPA 16 /* /NOT-PREAUTH */
-#define KRB_I_K4 17 /* /KERBEROS4 (should k5 get k4 as well) */
-#define KRB_I_NK4 18 /* /NO-KERBEROS4 */
-#define KRB_I_POP 19 /* /POPUP */
-#define KRB_I_ADR 20 /* /ADDRESSES: */
-#define KRB_I_NAD 21 /* /NO-ADDRESSES */
-#define KRB_I_MAX 21 /* Highest KERBEROS INIT switch number */
-
-#endif /* CK_KERBEROS */
-
-/* SET parameters */
-
-#define XYBREA 0 /* BREAK simulation */
-#define XYCHKT 1 /* Block check type */
-#define XYDEBU 2 /* Debugging */
-#define XYDELA 3 /* Delay */
-#define XYDUPL 4 /* Duplex */
-#define XYEOL 5 /* End-Of-Line (packet terminator) */
-#define XYESC 6 /* Escape character */
-#define XYFILE 7 /* File Parameters (see ckcker.h for values) */
- /* (this space available) */
-#define XYFLOW 9 /* Flow Control */
-#define XYHAND 10 /* Handshake */
-#define XYIFD 11 /* Incomplete File Disposition */
-#define XYIMAG 12 /* "Image Mode" */
-#define XYINPU 13 /* INPUT command parameters */
-#define XYLEN 14 /* Maximum packet length to send */
-#define XYLINE 15 /* Communication line to use */
-
-/* SET LINE / SET HOST command switches */
-
-#define SL_CNX 0 /* /CONNECT */
-#define SL_SRV 1 /* /SERVER */
-#define SL_SHR 2 /* /SHARE */
-#define SL_NSH 3 /* /NOSHARE */
-#define SL_BEE 4 /* /BEEP */
-#define SL_ANS 5 /* /ANSWER */
-#define SL_DIA 6 /* /DIAL:xxx */
-#define SL_SPD 7 /* /SPEED:xxx */
-#define SL_FLO 8 /* /FLOW:xxx */
-#define SL_TMO 9 /* /TIMEOUT:xxx */
-#define SL_CMD 10 /* /COMMAND */
-#define SL_PSW 11 /* /PASSWORD:xxx */
-#define SL_IKS 12 /* /KERMIT-SERVICE */
-#define SL_NET 13 /* /NETWORK-TYPE:xxx */
-#define SL_ENC 14 /* /ENCRYPT:type (telnet) /ENCRYPT (rlogin) */
-#define SL_KRB4 15 /* /KERBEROS 4 (rlogin/telnet) */
-#define SL_KRB5 16 /* /KERBEROS 5 (rlogin/telnet) */
-#define SL_SRP 17 /* /SRP (telnet) */
-#define SL_NTLM 18 /* /NTLM (telnet) */
-#define SL_SSL 19 /* /SSL (telnet) */
-#define SL_UID 20 /* /USERID:xxxx */
-#define SL_AUTH 21 /* /AUTH:type */
-#define SL_WAIT 22 /* /WAIT */
-#define SL_NOWAIT 23 /* /NOWAIT */
-#define SL_PTY 24 /* /PTY */
-
-#define XYLOG 16 /* Log file */
-#define XYMARK 17 /* Start of Packet mark */
-#define XYNPAD 18 /* Amount of padding */
-#define XYPADC 19 /* Pad character */
-#define XYPARI 20 /* Parity */
-#define XYPAUS 21 /* Interpacket pause */
-#define XYPROM 22 /* Program prompt string */
-#define XYQBIN 23 /* 8th-bit prefix */
-#define XYQCTL 24 /* Control character prefix */
-#define XYREPT 25 /* Repeat count prefix */
-#define XYRETR 26 /* Retry limit */
-#define XYSPEE 27 /* Line speed (baud rate) */
-#define XYTACH 28 /* Character to be doubled */
-#define XYTIMO 29 /* Timeout interval */
-#define XYMODM 30 /* Modem - also see XYDIAL */
-
-#define XYSEND 31 /* SET SEND parameters */
-#define XYRECV 32 /* SET RECEIVE parameters */
-#define XYTERM 33 /* SET TERMINAL parameters */
-#define XYTBYT 0 /* Terminal Bytesize (7 or 8) */
-#define XYTTYP 1 /* Terminal emulation Type */
-#define TT_NONE 0 /* NONE, no emulation */
-#ifdef OS2
-/*
- Note, the symbols for VT and VT-like terminals should be in ascending
- numerical order, so that higher ones can be treated as supersets of
- lower ones with respect to capabilities.
-
- This is no longer the case with the influx of new terminal types.
- Just make sure that the ISXXXXX() macros include the proper family
- groups.
-*/
-#define TT_DG200 1 /* Data General 200 */
-#define TT_DG210 2 /* Data General 210 */
-#define TT_DG217 3 /* Data General 217 */
-#define TT_HP2621 4 /* Hewlett-Packard 2621A */
-#define TT_HPTERM 5 /* Hewlett-Packard Console */
-#define TT_HZL1500 6 /* Hazeltine 1500 */
-#define TT_VC4404 7 /* Volker Craig VC4404/404 */
-#define TT_WY30 8 /* WYSE-30/30+ */
-#define TT_WY50 9 /* WYSE-50/50+ */
-#define TT_WY60 10 /* WYSE-60 */
-#define TT_WY160 11 /* WYSE-160 */
-#define TT_QNX 12 /* QNX */
-#define TT_QANSI 13 /* QNX Ansi emulation */
-#define TT_VT52 14 /* DEC VT-52 */
-#define TT_H19 15 /* Heath-19 */
-#define TT_IBM31 16 /* IBM 31xx */
-#define TT_SCOANSI 17 /* SCOANSI (Unix mode) */
-#define TT_AT386 18 /* Unixware AT386 (Unix mode) */
-#define TT_ANSI 19 /* IBM ANSI.SYS (BBS) */
-#define TT_VIP7809 20 /* Honeywell VIP7809 */
-#define TT_LINUX 21 /* Linux Console */
-#define TT_HFT 22 /* IBM High Function Terminal */
-#define TT_AIXTERM 23 /* IBM AIXterm */
-#define TT_SUN 24 /* SUN Console */
-#define TT_BA80 25 /* Nixdorf BA80 */
-#define TT_BEOS 26 /* BeOS Ansi */
-#define TT_VT100 27 /* DEC VT-100 */
-#define TT_VT102 28 /* DEC VT-102 */
-#define TT_VT220 29 /* DEC VT-220 */
-#define TT_VT220PC 30 /* DEC VT-220 with PC keyboard */
-#define TT_VT320 31 /* DEC VT-320 */
-#define TT_VT320PC 32 /* DEC VT-320 with PC keyboard */
-#define TT_WY370 33 /* WYSE 370 ANSI Terminal */
-#define TT_97801 34 /* Sinix 97801-5xx terminal */
-#define TT_AAA 35 /* Ann Arbor Ambassador */
-#define TT_TVI910 36 /* TVI 910+ */
-#define TT_TVI925 37 /* TVI 925 */
-#define TT_TVI950 38 /* TVI950 */
-#define TT_ADM3A 39 /* LSI ADM 3A */
-#define TT_ADM5 40 /* LSI ADM 5 */
-#define TT_VTNT 41 /* Microsoft NT Virtual Terminal */
-#define TT_MAX TT_VTNT
-#define TT_VT420 96 /* DEC VT-420 */
-#define TT_VT520 97 /* DEC VT-520/525 */
-#define TT_TEK40 99 /* Tektronix 401x */
-#define TT_KBM_EMACS TT_MAX+1
-#define TT_KBM_HEBREW TT_MAX+2
-#define TT_KBM_RUSSIAN TT_MAX+3
-#define TT_KBM_WP TT_MAX+4
-
-#define ISAAA(x) (x == TT_AAA)
-#define ISANSI(x) (x >= TT_SCOANSI && x <= TT_ANSI)
-#define ISBA80(x) (x == TT_BA80)
-#define ISBEOS(x) (x == TT_BEOS)
-#define ISQNX(x) (x == TT_QNX)
-#define ISQANSI(x) (x == TT_QANSI)
-#define ISLINUX(x) (x == TT_LINUX)
-#define ISSCO(x) (x == TT_SCOANSI)
-#define ISAT386(x) (x == TT_AT386)
-#define ISAVATAR(x) (x == TT_ANSI)
-#define ISSUN(x) (x == TT_SUN)
-#define ISUNIXCON(x) (x == TT_SCOANSI || x == TT_AT386 || \
- x == TT_LINUX || x == TT_SUN)
-#define ISDG200(x) (x >= TT_DG200 && x <= TT_DG217)
-#define ISHZL(x) (x == TT_HZL1500)
-#define ISH19(x) (x == TT_H19)
-#define ISIBM31(x) (x == TT_IBM31)
-#define ISTVI(x) (x >= TT_TVI910 && x <= TT_TVI950)
-#define ISTVI910(x) (x == TT_TVI910)
-#define ISTVI925(x) (x == TT_TVI925)
-#define ISTVI950(x) (x == TT_TVI950)
-#define ISVT52(x) (x == TT_VT52 || x == TT_H19)
-#ifdef COMMENT
-#define ISVT520(x) (x == TT_VT520)
-#define ISVT420(x) (x >= TT_VT420 && x <= TT_VT520)
-#else /* COMMENT */
-/* Since we do not yet support 420/520 extend 320 */
-#define ISVT520(x) (ISVT320(x))
-#define ISVT420(x) (ISVT320(x))
-#endif /* COMMENT */
-#define ISVT320(x) (x >= TT_VT320 && x <= TT_AAA)
-#define ISVT220(x) (x >= TT_VT220 && x <= TT_AAA || \
- ISBEOS(x) || ISQANSI(x) || \
- ISLINUX(x) || ISSUN(x))
-#define ISVT102(x) (x >= TT_VIP7809 && x <= TT_BA80 || \
- x == TT_VT102 || ISVT220(x))
-#define ISVT100(x) (x == TT_VT100 || ISVT102(x))
-#define ISWY30(x) (x == TT_WY30)
-#define ISWYSE(x) (x >= TT_WY30 && x <= TT_WY160)
-#define ISWY50(x) (x == TT_WY50)
-#define ISWY60(x) (x == TT_WY60 || x == TT_WY160)
-#define ISWY160(x) (x == TT_WY160)
-#define ISWY370(x) (x == TT_WY370)
-#define ISVC(x) (x == TT_VC4404)
-#define ISHP(x) (x == TT_HPTERM || x == TT_HP2621)
-#define ISHPTERM(x) (x == TT_HPTERM)
-#define ISVIP(x) (x == TT_VIP7809)
-#define IS97801(x) (x == TT_97801)
-#define ISHFT(x) (x == TT_HFT || x == TT_AIXTERM)
-#define ISAIXTERM(x) (x == TT_AIXTERM)
-#define ISTEK(x) (x == TT_TEK40)
-#define ISVTNT(x) (x == TT_VTNT)
-#define ISADM3A(x) (x == TT_ADM3A)
-#define ISADM5(x) (x == TT_ADM5)
-#endif /* OS2 */
-
-#define XYTCS 2 /* Terminal Character Set */
-#define XYTSO 3 /* Terminal Shift-In/Shift-Out */
-#define XYTNL 4 /* Terminal newline mode */
-#ifdef OS2
-#define XYTCOL 5 /* Terminal colors */
-#endif /* OS2 */
-#define XYTEC 6 /* Terminal echo = duplex = local-echo */
-#ifdef OS2
-#define XYTCUR 7 /* Terminal cursor */
-#define TTC_ULINE 0
-#define TTC_HALF 1
-#define TTC_BLOCK 2
-#define XYTARR 8 /* Terminal arrow-key mode */
-#define XYTKPD 9 /* Terminal keypad mode */
-#define TTK_NORM 0 /* Normal mode for arrow / keyad keys */
-#define TTK_APPL 1 /* Application mode for arrow / keyad keys */
-#define XYTWRP 10 /* Terminal wrap */
-#endif /* OS2 */
-#define XYTCRD 11 /* Terminal CR-display */
-#define XYTANS 12 /* Terminal answerback */
-#ifdef OS2
-#define XYSCRS 13 /* Terminal scrollback buffer size */
-#endif /* OS2 */
-#define XYTAPC 14 /* Terminal APC */
-#ifdef OS2
-#define XYTBEL 15 /* Terminal Bell */
-#endif /* OS2 */
-#define XYTDEB 16 /* Terminal Debug */
-#ifdef OS2
-#define XYTROL 17 /* Terminal Rollback */
-#define TTR_OVER 0 /* Rollback Overwrite */
-#define TTR_INSERT 1 /* Rollback Insert */
-#define TTR_KEYS 2 /* Keystrokes */
-#define TTRK_IGN 0 /* Ignore */
-#define TTRK_RST 2 /* Restore and Send */
-#define TTRK_SND 1 /* Send */
-#define XYTCTS 18 /* Terminal Transmit-Timeout */
-#define XYTCPG 19 /* Terminal Code Page */
-#ifdef COMMENT
-#define XYTHCU 20 /* Terminal Hide-Cursor */
-#endif /* COMMENT */
-#define XYTPAC 21 /* Terminal Output-Pacing */
-#define XYTMOU 22 /* Terminal Mouse */
-#endif /* OS2 */
-#define XYTHIG 23 /* Terminal Width */
-#define XYTWID 24 /* Terminal Height */
-#ifdef OS2
-#define XYTUPD 25 /* Terminal Screen-update */
-#define TTU_FAST 0 /* FAST but jerky */
-#define TTU_SMOOTH 1 /* SMOOTH but slow */
-#define XYTFON 26 /* Terminal Full screen Font */
-#define TTF_ROM 0 /* ROM font */
-#define TTF_CY1 1 /* CYRILL1 font */
-#define TTF_CY2 2 /* CYRILL2 font */
-#define TTF_CY3 3 /* CYRILL3 font */
-#define TTF_111 111 /* CP111 font */
-#define TTF_112 112 /* CP112 font */
-#define TTF_113 113 /* CP113 font */
-#define TTF_437 437 /* CP437 font */
-#define TTF_850 850 /* CP850 font */
-#define TTF_851 851 /* CP851 font */
-#define TTF_852 852 /* CP852 font */
-#define TTF_853 853 /* CP853 font */
-#define TTF_860 860 /* CP860 font */
-#define TTF_861 861 /* CP861 font */
-#define TTF_862 862 /* CP862 font */
-#define TTF_863 863 /* CP863 font */
-#define TTF_864 864 /* CP864 font */
-#define TTF_865 865 /* CP865 font */
-#define TTF_866 866 /* CP866 font */
-#define TTF_880 880 /* CP880 font */
-#define TTF_881 881 /* CP881 font */
-#define TTF_882 882 /* CP882 font */
-#define TTF_883 883 /* CP883 font */
-#define TTF_884 884 /* CP884 font */
-#define TTF_885 885 /* CP885 font */
-#define XYTVCH 27 /* SET TERMINAL VIDEO-CHANGE */
-#define TVC_DIS 0 /* DISABLED */
-#define TVC_ENA 1 /* ENABLED */
-#define TVC_W95 2 /* WIN95-SAFE */
-#endif /* OS2 */
-#define XYTAUTODL 28 /* SET TERMINAL AUTODOWNLOAD */
-#define TAD_OFF 0 /* OFF */
-#define TAD_ON 1 /* ON */
-#define TAD_K 2 /* KERMIT */
-#define TAD_Z 3 /* ZMODEM */
-#define TAD_X_STR 0 /* STRING */
-#define TAD_X_DETECT 1 /* DETECTION ( PACKET, STRING ) */
-#define TAD_X_C0 2 /* C0 CONFLICTS */
-#define TAD_ERR 4 /* ERROR { STOP, CONTINUE } */
-#define TAD_ASK 5 /* ASK (dialog) */
-#define XYTAUTOUL 29 /* SET TERMINAL AUTOUPLOAD */
-#ifdef OS2
-#define XYTATTBUG 30 /* SET TERM ATTR-BUG */
-#define XYTSTAT 31 /* SET TERM STATUSLINE */
-#endif /* OS2 */
-#define XYTESC 32 /* SET TERM ESCAPE-CHARACTER */
-#define XYTCTRL 33 /* SET TERM CONTROLS */
-#ifdef OS2
-#define XYTATTR 34 /* SET TERM ATTRIBUTE representation */
-#define XYTSGRC 35 /* SET TERM SGRCOLORS */
-#endif /* OS2 */
-#define XYTLCS 36 /* SET TERM LOCAL-CHARACTER-SET */
-#define XYTRCS 37 /* SET TERM REMOTE-CHARACTER-SET */
-#define XYTUNI 38 /* SET TERM UNICODE */
-#define XYTKEY 39 /* SET TERM KEY */
-#ifdef OS2
-#define XYTSEND 40 /* SET TERM SEND-DATA */
-#define XYTSEOB 41 /* SET TERM SEND-END-OF-BLOCK */
-#define XYTMBEL 42 /* SET TERM MARGIN-BELL */
-#endif /* OS2 */
-#define XYTIDLE 43 /* SET TERM IDLE-SEND */
-#ifdef OS2
-#define XYTKBMOD 44 /* SET TERM KEYBOARD-MODE */
-#define XYTUNX 45 /* SET TERM UNIX-MODE (DG) */
-#define XYTASCRL 46 /* SET TERM AUTOSCROLL */
-#define XYTAPAGE 47 /* SET TERM AUTOPAGE */
-#endif /* OS2 */
-#define XYTRIGGER 48 /* SET TERM TRIGGER */
-#ifdef OS2
-#define XYTPCTERM 49 /* SET TERM PCTERM */
-#define XYTOPTI 50 /* SET TERM SCREEN-OPTIMIZE */
-#define XYTSCNM 51 /* SET TERM SCREEN-MODE (DECSCNM) */
-#endif /* OS2 */
-#define XYTPRN 52 /* SET TERM PRINT {AUTO, COPY, OFF} */
-#ifdef OS2
-#define XYTSAC 53 /* SET TERM SPACING-ATTRIBUTE-CHARACTER (inv) */
-#define XYTSNIPM 54 /* SET TERM SNI-AUTOROLL */
-#define XYTSNISM 55 /* SET TERM SNI-SCROLLMODE */
-#define XYTKBDGL 56 /* SET TERM KBD-FOLLOWS-GL/GR */
-#define XYTVTLNG 57 /* SET TERM VT-LANGUAGE */
-#define VTL_NORTH_AM 1
-#define VTL_BRITISH 2
-#define VTL_BELGIAN 3
-#define VTL_FR_CAN 4
-#define VTL_DANISH 5
-#define VTL_FINNISH 6
-#define VTL_GERMAN 7
-#define VTL_DUTCH 8
-#define VTL_ITALIAN 9
-#define VTL_SW_FR 10
-#define VTL_SW_GR 11
-#define VTL_SWEDISH 12
-#define VTL_NORWEGIA 13
-#define VTL_FRENCH 14
-#define VTL_SPANISH 15
-#define VTL_PORTUGES 16
-#define VTL_HEBREW 19
-#define VTL_GREEK 22
-#define VTL_CANADIAN 28
-#define VTL_TURK_Q 29
-#define VTL_TURK_F 30
-#define VTL_HUNGARIA 31
-#define VTL_SLOVAK 33
-#define VTL_CZECH 34
-#define VTL_POLISH 35
-#define VTL_ROMANIAN 36
-#define VTL_SCS 38
-#define VTL_RUSSIAN 39
-#define VTL_LATIN_AM 40
-#define XYTVTNRC 58 /* SET TERM VT-NRC-MODE */
-#define XYTSNICC 59 /* SET TERM SNI-CH.CODE */
-#define XYTSNIFV 60 /* SET TERM SNI-FIRMWARE-VERSIONS */
-#define XYTURLHI 61 /* SET TERM URL-HIGHLIGHT */
-#endif /* OS2 */
-#define XYTITMO 62 /* SET TERM IDLE-TIMEOUT */
-#define XYTIACT 63 /* SET TERM IDLE-ACTION */
-#define XYTLSP 64 /* SET TERM LINE-SPACING */
-#define XYTLFD 65 /* SET TERM LF-DISPLAY */
-
-#define XYATTR 34 /* Attribute packets */
-#define XYSERV 35 /* Server parameters */
-#define XYSERT 0 /* Server timeout */
-#define XYSERD 1 /* Server display */
-#define XYSERI 2 /* Server idle */
-#define XYSERP 3 /* Server get-path */
-#define XYSERL 4 /* Server login */
-#define XYSERC 5 /* Server CD-Message */
-#define XYSERK 6 /* Server keepalive */
-#define XYWIND 36 /* Window size */
-#define XYXFER 37 /* Transfer */
-#define XYX_CAN 0 /* Cancellation */
-#define XYX_CSE 1 /* Character-Set */
-#define XYX_LSH 2 /* Locking-Shift */
-#define XYX_PRO 3 /* Protocol */
-#define XYX_MOD 4 /* Mode */
-#define XYX_DIS 5 /* Display */
-#define XYX_SLO 6 /* Slow-start */
-#define XYX_CRC 7 /* CRC calculation */
-#define XYX_BEL 8 /* Bell */
-#define XYX_PIP 9 /* Pipes */
-#define XYX_INT 10 /* Interruption */
-#define XYX_XLA 11 /* (character-set) Translation On/Off */
-#define XYX_MSG 12 /* Message */
-#define XYX_RPT 13 /* Report */
-#define XYLANG 38 /* Language */
-#define XYCOUN 39 /* Count */
-#define XYTAKE 40 /* Take */
-#define XYUNCS 41 /* Unknown-character-set */
-#define XYKEY 42 /* Key */
-#define XYMACR 43 /* Macro */
-#define XYHOST 44 /* Hostname on network */
-#define XYNET 45 /* SET NETWORK things */
-
-#define XYNET_D 99 /* NETWORK DIRECTORY */
-#define XYNET_T 100 /* NETWORK TYPE */
-
-#define XYCARR 46 /* Carrier */
-#define XYXMIT 47 /* Transmit */
-
-#define XYDIAL 48 /* Dial options */
-
-/* And now we interrupt the flow to bring you lots of stuff about dialing */
-
-#ifndef MAXTOLLFREE /* Maximum number of toll-free area codes */
-#define MAXTOLLFREE 8
-#endif /* MAXTOLLFREE */
-
-#ifndef MAXTPCC /* Maximum Tone or Pulse dialing countries */
-#define MAXTPCC 160
-#endif /* MAXTPCC */
-
-#ifndef MAXPBXEXCH /* Maximum number of PBX exchanges */
-#define MAXPBXEXCH 8
-#endif /* MAXPBXEXCH */
-
-#ifndef MAXLOCALAC
-#define MAXLOCALAC 32
-#endif /* MAXLOCALAC */
-
-#ifndef MAXDNUMS
-#ifdef BIGBUFOK
-#define MAXDDIR 32 /* Maximum number of dialing directories */
-#define MAXDNUMS 4095 /* Max numbers to fetch from dialing directories */
-#else
-#define MAXDDIR 12
-#define MAXDNUMS 1024
-#endif /* BIGBUFOK */
-#endif /* MAXDNUMS */
-/*
- IMPORTANT: In 5A(192), the old SET DIAL command was split into two commands:
- SET MODEM (for modem-related parameters) and SET DIAL (for dialing items).
- To preserve the old formats, etc, invisibly we keep one symbol space for
- both commands.
-*/
-#define XYDHUP 0 /* Dial Hangup */
-#define XYDINI 1 /* MODEM (dial) Initialization string */
-#define XYDKSP 2 /* MODEM (dial) Kermit-Spoof */
-#define XYDTMO 3 /* Dial Timeout */
-#define XYDDPY 4 /* Dial Display */
-#define XYDSPD 5 /* Dial Speed matching */
-#define XYDMNP 6 /* MODEM (dial) MNP negotiation enabled (obsolete) */
-#define XYDEC 7 /* MODEM (dial) error correction enabled */
-#define XYDDC 8 /* MODEM (dial) compression enabled */
-#define XYDHCM 9 /* MODEM (dial) hangup-string (moved elsewhere) */
-#define XYDDIR 10 /* Dial directory */
-#define XYDDIA 11 /* MODEM (dial) dial-command */
-#define XYDMHU 12 /* MODEM HANGUP (dial modem-hangup) */
-
-#ifndef DEFMDHUP /* Default MODEM HANGUP-METHOD */
-#define DEFMDMHUP 1 /* 0 = RS232, 1 = modem command */
-#endif /* DEFMDMHUP */
-
-#define XYDNPR 13 /* Dial PREFIX */
-#define XYDSTR 14 /* MODEM COMMAND (dial string) ... */
-
-#define XYDS_DC 0 /* Data compression */
-#define XYDS_EC 1 /* Error correction */
-#define XYDS_HU 2 /* Hangup command */
-#define XYDS_HW 3 /* Hardware flow control */
-#define XYDS_IN 4 /* Init-string */
-#define XYDS_NF 5 /* No flow control */
-#define XYDS_PX 6 /* Prefix (no, this goes in SET DIAL) */
-#define XYDS_SW 7 /* Software flow control */
-#define XYDS_DT 8 /* Tone dialing command */
-#define XYDS_DP 9 /* Pulse dialing command */
-#define XYDS_AN 10 /* Autoanswer */
-#define XYDS_RS 11 /* Reset */
-#define XYDS_MS 12 /* Dial mode string */
-#define XYDS_MP 13 /* Dial mode prompt */
-#define XYDS_SP 14 /* Modem speaker */
-#define XYDS_VO 15 /* Modem speaker volume */
-#define XYDS_ID 16 /* Ignore dialtone */
-#define XYDS_I2 17 /* Init string #2 */
-
-#define XYDM_A 9 /* Method: Auto */
-#define XYDM_D 0 /* Default */
-#define XYDM_T 2 /* Tone */
-#define XYDM_P 3 /* Pulse */
-
-#define XYDFC 15 /* MODEM (dial) flow-control */
-#define XYDMTH 16 /* Dial method */
-#define XYDESC 17 /* MODEM (dial) escape-character */
-#define XYDMAX 18 /* MODEM (dial) maximum interface speed */
-#define XYDCAP 19 /* MODEM (dial) capabilities */
-#define XYDTYP 20 /* MODEM TYPE */
-#define XYDINT 21 /* DIAL retries */
-#define XYDRTM 22 /* DIAL time between retries */
-#define XYDNAM 23 /* MODEM NAME */
-#define XYDLAC 24 /* DIAL (LOCAL-)AREA-CODE */
-#define XYDMCD 25 /* MODEM CARRIER */
-
-#define XYDCNF 26 /* DIAL CONFIRMATION */
-#define XYDCVT 27 /* DIAL CONVERT-DIRECTORY */
-#define XYDIXP 28 /* DIAL INTERNATIONAL-PREFIX */
-#define XYDIXS 29 /* DIAL INTERNATIONAL-SUFFIX */
-#define XYDLCC 30 /* DIAL LOCAL-COUNTRY-CODE */
-#define XYDLDP 31 /* DIAL LONG-DISTANCE-PREFIX */
-#define XYDLDS 32 /* DIAL LONG-DISTANCE-SUFFIX */
-#define XYDPXX 33 /* DIAL PBX-EXCHANGE */
-#define XYDPXI 34 /* DIAL PBX-INTERNAL-PREFIX */
-#define XYDPXO 35 /* DIAL PBX-OUTSIDE-PREFIX */
-#define XYDSFX 36 /* DIAL SUFFIX */
-#define XYDSRT 37 /* DIAL SORT */
-#define XYDTFC 38 /* DIAL TOLL-FREE-AREA-CODE */
-#define XYDTFP 39 /* DIAL TOLL-FREE-PREFIX */
-#define XYDTFS 40 /* DIAL TOLL-FREE-SUFFIX */
-#define XYDCON 41 /* DIAL CONNECT */
-#define XYDRSTR 42 /* DIAL RESTRICT */
-#define XYDRSET 43 /* MODEM RESET */
-#define XYDLCP 44 /* DIAL LOCAL-PREFIX */
-#define XYDLCS 45 /* DIAL LOCAL-SUFFIX */
-#define XYDLLAC 46 /* DIAL LC-AREA-CODES */
-#define XYDFLD 47 /* DIAL FORCE LONG-DISTANCE */
-#define XYDSPK 48 /* MODEM SPEAKER */
-#define XYDVOL 49 /* MODEM VOLUME */
-#define XYDIDT 50 /* IGNORE DIALTONE */
-#define XYDPAC 51 /* PACING */
-#define XYDMAC 52 /* MACRO */
-#define XYDPUCC 53 /* PULSE-COUNTRIES */
-#define XYDTOCC 54 /* TONE-COUNTRIES */
-#define XYDTEST 55 /* TEST */
-
-#define XYA_CID 1 /* SET ANSWER CALLER-ID */
-#define XYA_RNG 2 /* SET ANSWER RINGS */
-
-#define XYSESS 49 /* SET SESSION options */
-#define XYBUF 50 /* Buffer length */
-#define XYBACK 51 /* Background */
-#define XYDFLT 52 /* Default */
-#define XYDBL 53 /* Double */
-#define XYCMD 54 /* COMMAND */
-#define XYCASE 55 /* Case */
-#define XYCOMP 56 /* Compression */
-#define XYX25 57 /* X.25 parameter (ANYX25) */
-#define XYPAD 58 /* X.3 PAD parameter (ANYX25) */
-#define XYWILD 59 /* Wildcard expansion method */
-
-#define WILD_OFF 0 /* Wildcard expansion off */
-#define WILD_ON 1 /* Wildcard expansion on */
-#define WILD_KER 2 /* Wildcard expansion by Kermit */
-#define WILD_SHE 3 /* Wildcard expansion by Shell */
-
-#define XYSUSP 60 /* Suspend */
-#define XYMAIL 61 /* Mail-Command */
-#define XYPRIN 62 /* Print-Command */
-#define XYQUIE 63 /* Quiet */
-#define XYLCLE 64 /* Local-echo */
-#define XYSCRI 65 /* SCRIPT command parameters */
-#define XYMSGS 66 /* MESSAGEs ON/OFF */
-#ifdef TNCODE
-#define XYTEL 67 /* SET TELNET parameters */
-#define CK_TN_EC 0 /* TELNET ECHO */
-#define CK_TN_TT 1 /* TELNET TERMINAL-TYPE */
-#define CK_TN_NL 2 /* TELNET NEWLINE-MODE */
-#define CK_TN_BM 3 /* TELNET BINARY-MODE */
-#define CK_TN_BUG 4 /* TELNET BUG */
-#define CK_TN_ENV 5 /* TELNET ENVIRONMENT */
-#define TN_ENV_USR 0 /* VAR USER */
-#define TN_ENV_JOB 1 /* VAR JOB */
-#define TN_ENV_ACCT 2 /* VAR ACCT */
-#define TN_ENV_PRNT 3 /* VAR PRINTER */
-#define TN_ENV_SYS 4 /* VAR SYSTEMTYPE */
-#define TN_ENV_DISP 5 /* VAR DISPLAY */
-#define TN_ENV_UVAR 6 /* USERVAR */
-#define TN_ENV_LOC 7 /* USERVAR LOCATION */
-#define TN_ENV_ON 98 /* ON (enabled) */
-#define TN_ENV_OFF 99 /* OFF (disabled) */
-#define CK_TN_LOC 6 /* TELNET LOCATION */
-#define CK_TN_AU 7 /* TELNET AUTHENTICATION */
-#define TN_AU_FWD 4 /* AUTH FORWARD */
-#define TN_AU_TYP 5 /* AUTH TYPE */
-#define AUTH_NONE 0 /* AUTH NONE */
-#define AUTH_KRB4 1 /* AUTH Kerberos IV */
-#define AUTH_KRB5 2 /* AUTH Kerberos V */
-#define AUTH_SSL 7 /* AUTH Secure Sockets Layer */
-#define AUTH_TLS 98 /* AUTH Transport Layer Security */
-#define AUTH_SRP 5 /* AUTH Secure Remote Password */
-#define AUTH_NTLM 15 /* AUTH NT Lan Manager */
-#define AUTH_AUTO 99 /* AUTH AUTOMATIC */
-#define TN_AU_HOW 8 /* AUTH HOW FLAG */
-#define TN_AU_ENC 9 /* AUTH ENCRYPT FLAG */
-#define CK_TN_ENC 8 /* TELNET ENCRYPTION */
-#define TN_EN_TYP 4 /* ENCRYPT TYPE */
-#define TN_EN_START 5 /* ENCRYPT START */
-#define TN_EN_STOP 6 /* ENCRYPT STOP */
-#define CK_TN_IKS 9 /* TELNET KERMIT-SERVER */
-#define CK_TN_RE 10 /* TELNET REMOTE-ECHO */
-#define CK_TN_TLS 11 /* TELNET START_TLS */
-#define CK_TN_XD 12 /* TELNET XDISPLOC */
-#define CK_TN_NAWS 13 /* TELNET NAWS */
-#define CK_TN_WAIT 14 /* TELNET WAIT-FOR-NEGOTIATIONS */
-#define CK_TN_SGA 15 /* TELNET SGA */
-#define CK_TN_CLIENT 16 /* TELNET CLIENT */
-#define CK_TN_SERVER 17 /* TELNET SERVER */
-#define CK_TN_PHR 18 /* TELNET PRAGMA-HEARTBEAT */
-#define CK_TN_PLG 19 /* TELNET PRAGMA-LOGON */
-#define CK_TN_PSP 20 /* TELNET PRAGMA-SSPI */
-#define CK_TN_SAK 21 /* TELNET IBM SAK */
-#define CK_TN_FLW 22 /* TELNET LFLOW */
-#define CK_TN_XF 23 /* TELNET TRANSFER-MODE */
-#define CK_TN_PUID 24 /* TELNET PROMPT-FOR-USERID */
-#define CK_TN_NE 25 /* TELNET NO-ENCRYPT-DURING-XFER */
-#define CK_TN_CPC 26 /* TELNET COM-PORT-CONTROL */
-#define CK_TN_DB 27 /* TELNET DEBUG */
-#define CK_TN_FX 28 /* TELNET FORWARD_X */
-#define CK_TN_DL 29 /* TELNET DELAY-SB */
-#define CK_TN_SFU 30 /* TELNET SFU-COMPATIBILITY */
-#define CK_TN_LOG 31 /* TELNET LOGOUT */
-#endif /* TNCODE */
-#define XYOUTP 68 /* OUTPUT command parameters */
-#define OUT_PAC 0 /* OUTPUT PACING */
-#define OUT_ESC 1 /* OUTPUT SPECIAL-ESCAPES */
-#define XYEXIT 69 /* SET EXIT */
-#define XYPRTR 70 /* SET PRINTER */
-#define XYFPATH 71 /* PATHNAME */
-
-#ifdef OS2
-#define XYMOUSE 72 /* MOUSE SUPPORT */
-#define XYM_ON 0 /* Mouse ON/OFF */
-#define XYM_BUTTON 1 /* Define Mouse Events */
-#define XYM_CLEAR 2 /* Clear Mouse Events */
-#define XYM_DEBUG 3 /* Debug Mode ON/OFF */
-/* These must match similar definitions in ckokey.h */
-#define XYM_B1 0 /* Mouse Button One */
-#define XYM_B2 1 /* Mouse Button Two */
-#define XYM_B3 2 /* Mouse Button Three */
-#define XYM_ALT 1 /* Alt */
-#define XYM_CTRL 2 /* Ctrl */
-#define XYM_SHIFT 4 /* Shift */
-#define XYM_C1 0 /* Single Click */
-#define XYM_C2 8 /* Double Click */
-#define XYM_DRAG 16 /* Drag Event */
-#endif /* OS2 */
-
-#define XYBELL 73 /* BELL */
-
-#ifdef OS2
-#define XYPRTY 74 /* Thread Priority Level */
-#define XYP_IDLE 1
-#define XYP_REG 2
-#define XYP_SRV 4
-#define XYP_RTP 3
-#endif /* OS2 */
-
-#define XYALRM 75 /* SET ALARM */
-#define XYPROTO 76 /* SET PROTOCOL */
-#define XYPREFIX 77 /* SET PREFIXING */
-#define XYLOGIN 78 /* Login info for script programs... */
-
-#define LOGI_UID 0 /* User ID */
-#define LOGI_PSW 1 /* Password */
-#define LOGI_PRM 2 /* Prompt */
-
-#define XYSTARTUP 79 /* Startup file */
-#define XYTMPDIR 80 /* Temporary directory */
-
-#ifdef OS2
-#define XYTAPI 81 /* Microsoft Telephone API options */
-#define XYTAPI_CFG 1 /* TAPI Configure-Line Dialog */
-#define XYTAPI_DIAL 2 /* TAPI Dialing-Properties Dialog */
-#define XYTAPI_LIN 3 /* TAPI Line */
-#define XYTAPI_LOC 4 /* TAPI Location */
-#define XYTAPI_PASS 5 /* TAPI Passthrough */
-#define XYTAPI_CON 6 /* TAPI Conversions */
-#define XYTAPI_LGHT 7 /* TAPI Modem Lights */
-#define XYTAPI_PRE 8 /* TAPI Pre-dialing Terminal */
-#define XYTAPI_PST 9 /* TAPI Post-dialing Terminal */
-#define XYTAPI_INA 10 /* TAPI Inactivity Timeout */
-#define XYTAPI_BNG 11 /* TAPI Wait for Credit Card Tone */
-#define XYTAPI_MAN 12 /* TAPI Manual Dialing */
-#define XYTAPI_USE 13 /* TAPI Use Line Config settings */
-#endif /* OS2 */
-
-#ifdef TCPSOCKET
-#define XYTCP 82 /* TCP options */
-#define XYTCP_NODELAY 1 /* No Delay */
-#define XYTCP_SENDBUF 2 /* Send Buffer Size */
-#define XYTCP_LINGER 3 /* Linger */
-#define XYTCP_RECVBUF 4 /* Receive Buffer Size */
-#define XYTCP_KEEPALIVE 5 /* Keep Alive packets */
-#define XYTCP_UCX 6 /* UCX 2.0 port swabbing bug */
-#define XYTCP_NAGLE 7 /* Delay - inverse of 1 */
-#define XYTCP_RDNS 8 /* Reverse DNS lookup */
-#define XYTCP_ADDRESS 9 /* Set preferred IP Address */
-#define XYTCP_DNS_SRV 10 /* Use DNS Service Records */
-#define XYTCP_DONTROUTE 11 /* Dont Route */
-#define XYTCP_SOCKS_SVR 12 /* Name of Socks Server */
-#define XYTCP_HTTP_PROXY 13 /* Name/Port of HTTP Proxy Server */
-#define XYTCP_SOCKS_NS 14 /* Name of Socks Name Server */
-#endif /* TCPSOCKET */
-
-#ifdef OS2
-#define XYMSK 83 /* MS-DOS Kermit compatibility options */
-#define MSK_COLOR 0 /* Terminal color handling */
-#define MSK_KEYS 1 /* SET KEY uses MSK keycodes */
-#define MSK_REN 2 /* File renaming uses 8.3 notation always */
-#endif /* OS2 */
-
-#define XYDEST 84 /* SET DESTINATION as in MS-DOS Kermit */
-
-#ifdef OS2
-#define XYWIN95 85 /* SET WIN95 work arounds */
-#define XYWKEY 0 /* Keyboard translation */
-#define XYWAGR 1 /* Alt-Gr */
-#define XYWOIO 2 /* Overlapped I/O */
-#define XYWLUC 3 /* Lucida Console substitutions */
-#define XYWSELECT 4 /* Select on Write Bug */
-#define XYW8_3 5 /* Use 8.3 filenames? */
-#define XYWPOPUP 6 /* Use Popups? */
-#define XYWHSL 7 /* Horz Scan Line substitutions */
-#define XYDLR 86 /* SET K95 DIALER work arounds */
-#define XYTITLE 87 /* SET TITLE of window */
-#endif /* OS2 */
-
-#define XYIGN 88 /* SET IGNORE-CHARACTER */
-#define XYEDIT 89 /* SET EDITOR */
-#define XYFLTR 90 /* SET { SEND, RECEIVE } FILTER */
-#define XYBROWSE 91 /* SET BROWSER */
-#define XYEOF 92 /* EOF (= FILE EOF) */
-#ifdef OS2
-#define XYBDCP 93 /* BPRINTER */
-#endif /* OS2 */
-#define XYFLAG 94 /* FLAG */
-#define XYLIMIT 95 /* SESSION-LIMIT */
-#define XYINIL 96 /* Protocol negotiation string max length */
-#define XYRELY 97 /* RELIABLE */
-#define XYSTREAM 98 /* STREAMING */
-#define XYTLOG 99 /* TRANSACTION-LOG */
-#define XYCLEAR 100 /* CLEARCHANNEL */
-#define XYAUTH 101 /* AUTHENTICATION */
-
-#ifdef TNCODE
-#define XYKRBPR 0 /* Kerberos Principal */
-#define XYKRBRL 1 /* Kerberos Realm */
-#define XYKRBCC 2 /* Kerberos 5 Credentials-Cache */
-#define XYKRBSRV 3 /* Kerberos Service Name */
-#define XYKRBDBG 4 /* Kerberos Debugging */
-#define XYKRBLIF 5 /* Kerberos Lifetime */
-#define XYKRBPRE 6 /* Kerberos 4 Preauth */
-#define XYKRBINS 7 /* Kerberos 4 Instance */
-#define XYKRBFWD 8 /* Kerberos 5 Forwardable */
-#define XYKRBPRX 9 /* Kerberos 5 Proxiable */
-#define XYKRBRNW 10 /* Kerberos 5 Renewable lifetime */
-#define XYKRBGET 11 /* Kerberos Auto-Get-TGTs */
-#define XYKRBDEL 12 /* Kerberos Auto-Destroy-TGTs */
-#define KRB_DEL_NO 0 /* Kerberos No Auto Destroy */
-#define KRB_DEL_CL 1 /* Kerberos Auto Destory on Close */
-#define KRB_DEL_EX 2 /* Kerberos Auto Destroy on Exit */
-#define XYKRBK5K4 13 /* Kerberos 5 Get K4 Tickets */
-#define XYKRBPRM 14 /* Kerberos 4/5 Prompt */
-#define XYKRBADR 15 /* Kerberos 4/5 CheckAddrs */
-#define XYKRBNAD 16 /* Kerberos 5 No Addresses */
-#define XYKRBADD 17 /* Kerberos 5 Address List */
-#define XYKRBKTB 18 /* Kerberos 4/5 Key Table */
-#define XYSRPPRM 0 /* SRP Prompt */
-#define XYSSLRCFL 0 /* SSL/TLS RSA Certs file */
-#define XYSSLCOK 1 /* SSL/TLS Certs-Ok flag */
-#define XYSSLCRQ 2 /* SSL/TLS Certs-Required flag */
-#define XYSSLCL 3 /* SSL/TLS Cipher List */
-#define XYSSLDBG 4 /* SSL/TLS Debug flag */
-#define XYSSLRKFL 5 /* SSL/TLS RSA Key File */
-#define XYSSLLFL 6 /* SSL/TLS Log File */
-#define XYSSLON 7 /* SSL/TLS Only flag */
-#define XYSSLSEC 8 /* SSL/TLS Secure flag */
-#define XYSSLVRB 9 /* SSL/TLS Verbose flag */
-#define XYSSLVRF 10 /* SSL/TLS Verify flag */
-#define XYSSLDUM 11 /* SSL/TLS Dummy flag */
-#define XYSSLDCFL 12 /* SSL/TLS DSA Certs file */
-#define XYSSLDKFL 13 /* SSL/TLS DH Certs file */
-#define XYSSLDPFL 14 /* SSL/TLS DH Param file */
-#define XYSSLCRL 15 /* SSL/TLS CRL file */
-#define XYSSLCRLD 16 /* SSL/TLS CRL dir */
-#define XYSSLVRFF 17 /* SSL/TLS Verify file */
-#define XYSSLVRFD 18 /* SSL/TLS Verify dir */
-#define XYSSLRND 19 /* SSL/TLS Random file */
-#define XYSSLDCCF 20 /* SSL/TLS DSA Certs Chain File */
-#define XYSSLRCCF 21 /* SSL/TLS RSA Certs Chain File */
-
-/* The following must be powers of 2 for a bit mask */
-
-#define XYKLCEN 1 /* Kerberos List Credentials: Encryption */
-#define XYKLCFL 2 /* Kerberos List Credentials: Flags */
-#define XYKLCAD 4 /* Kerberos List Credentials: Addresses */
-#endif /* TNCODE */
-
-#define XYFUNC 102 /* SET FUNCTION */
-
-#define FUNC_DI 0 /* FUNCTION DIAGNOSTICS */
-#define FUNC_ER 1 /* FUNCTION ERROR */
-
-#define XYFTP 103 /* FTP application */
-#define XYSLEEP 104 /* SLEEP / PAUSE options */
-#define XYSSH 105 /* SSH options */
-#define XYTELOP 106 /* TELNET OPTIONS (TELOPT) */
-#define XYCD 107 /* SET CD */
-#define XYCSET 108 /* CHARACTER-SET */
-#define XYSTOP 109 /* STOP-BITS */
-#define XYSERIAL 110 /* SERIAL */
-#define XYDISC 111 /* CLOSE-ON-DISCONNECT */
-#define XYOPTS 112 /* OPTIONS */
-#define XYQ8FLG 113 /* Q8FLAG (invisible) */
-#define XYTIMER 114 /* TIMER */
-#define XYFACKB 115 /* F-ACK-BUG */
-#define XYBUP 116 /* SET SEND/RECEIVE BACKUP */
-#define XYMOVE 117 /* SET SEND/RECEIVE MOVE-TO */
-#define XYRENAME 118 /* SET SEND/RECEIVE RENAME-TO */
-#define XYHINTS 119 /* SET HINTS */
-#define XYEVAL 120 /* SET EVALUATE */
-#define XYFACKP 121 /* F-ACK-PATH */
-#define XYSYSL 122 /* SysLog */
-#define XYQNXPL 123 /* QNX Port Lock */
-#define XYIKS 124 /* SET IKS ... */
-#define XYROOT 125 /* SET ROOT */
-#define XYFTPX 126 /* SET FTP */
-#define XYSEXP 127 /* SET SEXP */
-#define XYGPR 128 /* SET GET-PUT-REMOTE */
-#define XYLOCUS 129 /* SET LOCUS */
-#define XYGUI 130 /* SET GUI */
-#define XYANSWER 131 /* SET ANSWER */
-#define XYMATCH 132 /* SET MATCHDOT */
-#define XYSFTP 133 /* SET SFTP */
-#define XY_REN 134 /* SET RENAME */
-#define XYEXTRN 135 /* SET EXTERNAL-PROTOCOL */
-#define XYVAREV 136 /* SET VARIABLE-EVALUATION */
-
-/* End of SET commands */
-
-/* S-Expressions -- floating-point support required */
-
-#ifndef CKFLOAT
-#ifndef NOSEXP
-#define NOSEXP
-#endif /* NOSEXP */
-#endif /* CKFLOAT */
-
-/* Maximum number of elements in an S-Expression */
-
-#ifndef NOSEXP
-#ifndef SEXPMAX
-#ifdef BIGBUFOK
-#define SEXPMAX 1024
-#else
-#define SEXPMAX 32
-#endif /* BIGBUFOK */
-#endif /* SEXPMAX */
-#endif /* NOSEXP */
-
-#ifdef ANYX25
-/* PAD command parameters */
-
-#define XYPADL 0 /* clear virtual call */
-#define XYPADS 1 /* status of virtual call */
-#define XYPADR 2 /* reset of virtual call */
-#define XYPADI 3 /* send an interrupt packet */
-
-/* Used with XYX25... */
-#define XYUDAT 0 /* X.25 call user data */
-#define XYCLOS 1 /* X.25 closed user group call */
-#define XYREVC 2 /* X.25 reverse charge call */
-#endif /* ANYX25 */
-
-#ifdef OS2
-/* SET PRINTER switches */
-
-#define PRN_OUT 0 /* Output only */
-#define PRN_BID 1 /* Bidirectional */
-#define PRN_DOS 2 /* DOS device */
-#define PRN_WIN 3 /* Windows queue */
-#define PRN_TMO 4 /* Timeout */
-#define PRN_TRM 5 /* Terminator */
-#define PRN_SEP 6 /* Separator */
-#define PRN_SPD 7 /* COM-port speed */
-#define PRN_FLO 8 /* COM-port flow control */
-#define PRN_PAR 9 /* COM-port parity */
-#define PRN_NON 10 /* No printer */
-#define PRN_FIL 11 /* Filename */
-#define PRN_PIP 12 /* Pipename */
-#define PRN_PS 13 /* Text to PS */
-#define PRN_WID 14 /* PS Width */
-#define PRN_LEN 15 /* PS Length */
-#define PRN_RAW 16 /* Non-PS */
-#define PRN_CS 17 /* Character Set */
-#define PRN_MAX 17 /* Number of switches defined */
-
-/* Printer types */
-
-#define PRT_DOS 0 /* DOS */
-#define PRT_WIN 1 /* Windows Queue */
-#define PRT_FIL 2 /* File */
-#define PRT_PIP 3 /* Pipe */
-#define PRT_NON 4 /* None */
-
-#define PRINTSWI
-#endif /* OS2 */
-#endif /* NOICP */
-
-#ifndef NODIAL
-/*
- Symbols for modem types, moved here from ckudia.c, May 1997, because now
- they are also used in some other modules. The numbers MUST correspond to
- the ordering of entries within the modemp[] array.
-*/
-#ifdef MINIDIAL /* Minimum dialer support */
-
-#define n_DIRECT 0 /* Direct connection -- no modem */
-#define n_CCITT 1 /* CCITT/ITU-T V.25bis */
-#define n_HAYES 2 /* Hayes 2400 */
-#define n_UNKNOWN 3 /* Unknown */
-#define n_UDEF 4 /* User-Defined */
-#define n_GENERIC 5 /* Generic High Speed */
-#define n_ITUTV250 6 /* ITU-T V.250 */
-#define MAX_MDM 6 /* Number of modem types */
-
-#else /* Full-blown dialer support */
-
-#define n_DIRECT 0 /* Direct connection -- no modem */
-#define n_ATTDTDM 1
-#define n_ATTISN 2
-#define n_ATTMODEM 3
-#define n_CCITT 4
-#define n_CERMETEK 5
-#define n_DF03 6
-#define n_DF100 7
-#define n_DF200 8
-#define n_GDC 9
-#define n_HAYES 10
-#define n_PENRIL 11
-#define n_RACAL 12
-#define n_UNKNOWN 13
-#define n_VENTEL 14
-#define n_CONCORD 15
-#define n_ATTUPC 16 /* aka UNIX PC and ATT7300 */
-#define n_ROLM 17 /* Rolm CBX DCM */
-#define n_MICROCOM 18 /* Microcoms in SX command mode */
-#define n_USR 19 /* Modern USRs */
-#define n_TELEBIT 20 /* Telebits of all kinds */
-#define n_DIGITEL 21 /* Digitel DT-22 (CCITT variant) */
-#define n_H_1200 22 /* Hayes 1200 */
-#define n_H_ULTRA 23 /* Hayes Ultra and maybe Optima */
-#define n_H_ACCURA 24 /* Hayes Accura and maybe Optima */
-#define n_PPI 25 /* Practical Peripherals */
-#define n_DATAPORT 26 /* AT&T Dataport */
-#define n_BOCA 27 /* Boca */
-#define n_MOTOROLA 28 /* Motorola Fastalk or Lifestyle */
-#define n_DIGICOMM 29 /* Digicomm Connection */
-#define n_DYNALINK 30 /* Dynalink 1414VE */
-#define n_INTEL 31 /* Intel 14400 Faxmodem */
-#define n_UCOM_AT 32 /* Microcoms in AT mode */
-#define n_MULTI 33 /* Multitech MT1432 */
-#define n_SUPRA 34 /* SupraFAXmodem */
-#define n_ZOLTRIX 35 /* Zoltrix */
-#define n_ZOOM 36 /* Zoom */
-#define n_ZYXEL 37 /* ZyXEL */
-#define n_TAPI 38 /* TAPI Line modem - whatever it is */
-#define n_TBNEW 39 /* Newer Telebit models */
-#define n_MAXTECH 40 /* MaxTech XM288EA */
-#define n_UDEF 41 /* User-Defined */
-#define n_RWV32 42 /* Generic Rockwell V.32 */
-#define n_RWV32B 43 /* Generic Rockwell V.32bis */
-#define n_RWV34 44 /* Generic Rockwell V.34 */
-#define n_MWAVE 45 /* IBM Mwave Adapter */
-#define n_TELEPATH 46 /* Gateway Telepath */
-#define n_MICROLINK 47 /* MicroLink modems */
-#define n_CARDINAL 48 /* Cardinal modems */
-#define n_GENERIC 49 /* Generic high-speed */
-#define n_XJACK 50 /* Megahertz X-Jack */
-#define n_SPIRITII 51 /* Quickcomm Spirit II */
-#define n_MONTANA 52 /* Motorola Montana */
-#define n_COMPAQ 53 /* Compaq Data+Fax Modem */
-#define n_FUJITSU 54 /* Fujitsu Fax/Modem Adpater */
-#define n_MHZATT 55 /* Megahertz AT&T V.34 */
-#define n_SUPRASON 56 /* SupraSonic */
-#define n_BESTDATA 57 /* Best Data */
-#define n_ATT1900 58 /* AT&T STU III Model 1900 */
-#define n_ATT1910 59 /* AT&T STU III Model 1910 */
-#define n_KEEPINTOUCH 60 /* AT&T KeepinTouch */
-#define n_USRX2 61 /* USR XJ-1560 X2 56K */
-#define n_ROLMAT 62 /* Rolm with AT command set */
-#define n_ATLAS 63 /* Atlas / Newcom ixfC 33.6 */
-#define n_CODEX 64 /* Motorola Codex 326X Series */
-#define n_MT5634ZPX 65 /* Multitech MT5634ZPX */
-#define n_ULINKV250 66 /* Microlink ITU-T V.250 56K */
-#define n_ITUTV250 67 /* Generic ITU-T V.250 */
-#define n_RWV90 68 /* Generic Rockwell V.90 */
-#define n_SUPRAX 69 /* Diamond Supra Express V.90 */
-#define n_LUCENT 70 /* Lucent Venus chipset */
-#define n_PCTEL 71 /* PCTel chipset */
-#define n_CONEXANT 72 /* Conexant modem family */
-#define n_ZOOMV34 73 /* Zoom */
-#define n_ZOOMV90 74 /* Zoom */
-#define n_ZOOMV92 75 /* ZOOM V.92 */
-#define n_MOTSM56 76 /* Motorola SM56 chipset */
-#define MAX_MDM 76 /* Number of modem types */
-
-#endif /* MINIDIAL */
-#endif /* NODIAL */
-
-#ifndef NOICP
-/* SHOW command symbols */
-
-#define SHPAR 0 /* Parameters */
-#define SHVER 1 /* Versions */
-#define SHCOM 2 /* Communications */
-#define SHPRO 3 /* Protocol */
-#define SHFIL 4 /* File */
-#define SHLNG 5 /* Language */
-#define SHCOU 6 /* Count */
-#define SHMAC 7 /* Macros */
-#define SHKEY 8 /* Key */
-#define SHSCR 9 /* Scripts */
-#define SHSPD 10 /* Speed */
-#define SHSTA 11 /* Status */
-#define SHSER 12 /* Server */
-#define SHXMI 13 /* Transmit */
-#define SHATT 14 /* Attributes */
-#define SHMOD 15 /* Modem */
-#define SHDFLT 16 /* Default (as in VMS) */
-#define SHVAR 17 /* Show global variables */
-#define SHARG 18 /* Show macro arguments */
-#define SHARR 19 /* Show arrays */
-#define SHBUI 20 /* Show builtin variables */
-#define SHFUN 21 /* Show functions */
-#define SHPAD 22 /* Show (X.25) PAD */
-#define SHTER 23 /* Show terminal settings */
-#define SHESC 24 /* Show escape character */
-#define SHDIA 25 /* Show DIAL parameters */
-#define SHNET 26 /* Show network parameters */
-#define SHLBL 27 /* Show VMS labeled file parameters */
-#define SHSTK 28 /* Show stack, MAC debugging */
-#define SHCSE 29 /* Show character sets */
-#define SHFEA 30 /* Show features */
-#define SHCTL 31 /* Show control-prefix table */
-#define SHEXI 32 /* Show EXIT items */
-#define SHPRT 33 /* Show printer */
-#define SHCMD 34 /* Show command parameters */
-#define SHKVB 35 /* Show \Kverbs */
-#define SHMOU 36 /* Show Mouse (like Show Key) */
-#define SHTAB 37 /* Show Tabs (OS/2) */
-#define SHVSCRN 38 /* Show Virtual Screen (OS/2) */
-#define SHALRM 39 /* ALARM */
-#define SHSFL 40 /* SEND-LIST */
-#define SHUDK 41 /* DEC VT UDKs (OS/2) */
-#define SHDBL 42 /* DOUBLE/IGNORE characters */
-#define SHEDIT 43 /* EDITOR */
-#define SHBROWSE 44 /* BROWSER */
-#define SHTAPI 45 /* TAPI */
-#define SHTAPI_L 46 /* TAPI Location */
-#define SHTAPI_M 47 /* TAPI Modem Properties */
-#define SHTAPI_C 48 /* TAPI Comm Properties */
-#define SHTEL 49 /* SHOW TELNET */
-#define SHINP 50 /* SHOW INPUT */
-#define SHTRIG 51 /* SHOW TRIGGER */
-#define SHLOG 52 /* SHOW LOGS */
-#define SHOUTP 53 /* SHOW OUTPUT */
-#define SHOPAT 54 /* SHOW PATTERNS */
-#define SHOSTR 55 /* SHOW STREAMING */
-#define SHOAUTH 56 /* SHOW AUTHENTICATION */
-#define SHOFTP 57 /* SHOW FTP */
-#define SHTOPT 58 /* SHOW TELOPT */
-#define SHXOPT 59 /* SHOW EXTENDED-OPTIONS */
-#define SHCD 60 /* SHOW CD */
-#define SHASSOC 61 /* SHOW ASSOCIATIONS */
-#define SHCONNX 62 /* SHOW CONNECTION */
-#define SHOPTS 63 /* SHOW OPTIONS */
-#define SHOFLO 64 /* SHOW FLOW-CONTROL */
-#define SHOXFER 65 /* SHOW TRANSFER */
-#define SHTCP 66 /* SHOW TCP */
-#define SHHISTORY 67 /* SHOW (command) HISTORY */
-#define SHSEXP 68 /* SHOW SEXPRESSIONS */
-#define SHOSSH 69 /* SHOW SSH */
-#define SHOIKS 70 /* SHOW IKS */
-#define SHOGUI 71 /* SHOW GUI (K95) */
-#define SHOREN 72 /* SHOW RENAME */
-
-/* REMOTE command symbols */
-
-#define XZCPY 0 /* Copy */
-#define XZCWD 1 /* Change Working Directory */
-#define XZDEL 2 /* Delete */
-#define XZDIR 3 /* Directory */
-#define XZHLP 4 /* Help */
-#define XZHOS 5 /* Host */
-#define XZKER 6 /* Kermit */
-#define XZLGI 7 /* Login */
-#define XZLGO 8 /* Logout */
-#define XZMAI 9 /* Mail <-- wrong, this should be top-level */
-#define XZMOU 10 /* Mount */
-#define XZMSG 11 /* Message */
-#define XZPRI 12 /* Print */
-#define XZREN 13 /* Rename */
-#define XZSET 14 /* Set */
-#define XZSPA 15 /* Space */
-#define XZSUB 16 /* Submit */
-#define XZTYP 17 /* Type */
-#define XZWHO 18 /* Who */
-#define XZPWD 19 /* Print Working Directory */
-#define XZQUE 20 /* Query */
-#define XZASG 21 /* Assign */
-#define XZMKD 22 /* mkdir */
-#define XZRMD 23 /* rmdir */
-#define XZXIT 24 /* Exit */
-#define XZCDU 25 /* CDUP */
-
-/* SET INPUT command parameters */
-
-#define IN_DEF 0 /* Default timeout */
-#define IN_TIM 1 /* Timeout action */
-#define IN_CAS 2 /* Case (matching) */
-#define IN_ECH 3 /* Echo */
-#define IN_SIL 4 /* Silence */
-#define IN_BUF 5 /* Buffer size */
-#define IN_PAC 6 /* Input Pacing (debug) */
-#define IN_TRM 7 /* Input Terminal Display */
-#define IN_ADL 8 /* Input autodownload */
-#define IN_PAT 9 /* Pattern to match */
-#define IN_ASG 10 /* Assign matching text to variable */
-#define IN_CAN 11 /* Keyboard cancellation of INPUT */
-#define IN_SCA 12 /* Timeout scaling */
-
-/* ENABLE/DISABLE command parameters */
-
-#define EN_ALL 0 /* ALL */
-#define EN_CWD 1 /* CD/CWD */
-#define EN_DIR 2 /* DIRECTORY */
-#define EN_FIN 3 /* FINISH */
-#define EN_GET 4 /* GET */
-#define EN_HOS 5 /* HOST command */
-#define EN_KER 6 /* KERMIT command */
-#define EN_LOG 7 /* LOGIN */
-#define EN_SEN 8 /* SEND */
-#define EN_SET 9 /* SET */
-#define EN_SPA 10 /* SPACE */
-#define EN_TYP 11 /* TYPE */
-#define EN_WHO 12 /* WHO, finger */
-#define EN_DEL 13 /* Delete */
-#define EN_BYE 14 /* BYE (as opposed to FINISH) */
-#define EN_QUE 15 /* QUERY */
-#define EN_ASG 16 /* ASSIGN */
-#define EN_CPY 17 /* COPY */
-#define EN_REN 18 /* RENAME */
-#define EN_RET 19 /* RETRIEVE */
-#define EN_MAI 20 /* MAIL */
-#define EN_PRI 21 /* PRINT */
-#define EN_MKD 22 /* MKDIR */
-#define EN_RMD 23 /* RMDIR */
-#define EN_XIT 24 /* EXIT */
-#define EN_ENA 25 /* ENABLE */
-#endif /* NOICP */
-
-#ifndef NOICP
-/* CLEAR command symbols */
-#define CLR_DEV 1 /* Clear Device Buffers */
-#define CLR_INP 2 /* Clear Input Buffers */
-#define CLR_BTH CLR_DEV|CLR_INP /* Clear Device and Input */
-#define CLR_SCL 4 /* Clear Scrollback buffer */
-#define CLR_CMD 8 /* Clear Command Screen */
-#define CLR_TRM 16 /* Clear Terminal Screen */
-#define CLR_DIA 32 /* Clear Dial Status */
-#define CLR_SFL 64 /* Clear Send-File-List */
-#define CLR_APC 128 /* Clear APC */
-#define CLR_ALR 256 /* Clear Alarm */
-#define CLR_TXT 512 /* Clear text-patterns */
-#define CLR_BIN 1024 /* Clear binary-patterns */
-#define CLR_SCR 2048 /* Clear screen */
-#define CLR_KBD 4096 /* Clear keyboard buffer */
-#endif /* NOICP */
-
-/* Symbols for logs */
-
-#define LOGD 0 /* Debugging */
-#define LOGP 1 /* Packets */
-#define LOGS 2 /* Session */
-#define LOGT 3 /* Transaction */
-#define LOGX 4 /* Screen */
-#define LOGR 5 /* The "open read" file */
-#define LOGW 6 /* The "open write/append" file */
-#define LOGE 7 /* Error (e.g. stderr) */
-#define LOGM 8 /* The dialing log */
-
-#ifndef NOSPL
-/* Symbols for builtin variables */
-
-#define VN_ARGC 0 /* ARGC */
-#define VN_COUN 1 /* COUNT */
-#define VN_DATE 2 /* DATE */
-#define VN_DIRE 3 /* DIRECTORY */
-#define VN_ERRO 4 /* ERRORLEVEL */
-#define VN_TIME 5 /* TIME */
-#define VN_VERS 6 /* VERSION */
-#define VN_IBUF 7 /* INPUT buffer */
-#define VN_SUCC 8 /* SUCCESS flag */
-#define VN_LINE 9 /* LINE */
-#define VN_ARGS 10 /* Program command-line arg count */
-#define VN_SYST 11 /* System type */
-#define VN_SYSV 12 /* System version */
-#define VN_RET 13 /* RETURN value */
-#define VN_FILE 14 /* Most recent filespec */
-#define VN_NDAT 15 /* Numeric date yyyy/mm/dd */
-#define VN_HOME 16 /* Home directory */
-#define VN_SPEE 17 /* Transmission speed */
-#define VN_HOST 18 /* Host name */
-#define VN_TTYF 19 /* TTY file descriptor (UNIX only) */
-#define VN_PROG 20 /* Program name */
-#define VN_NTIM 21 /* NTIME */
-#define VN_FFC 22 /* Characters in last file xferred */
-#define VN_TFC 23 /* Chars in last file group xferred */
-#define VN_CPU 24 /* CPU type */
-#define VN_CMDL 25 /* Command level */
-#define VN_DAY 26 /* Day of week, string */
-#define VN_NDAY 27 /* Day of week, numeric */
-#define VN_LCL 28 /* Local (vs) remote mode */
-#define VN_CMDS 29 /* Command source */
-#define VN_CMDF 30 /* Command file name */
-#define VN_MAC 31 /* Macro name */
-#define VN_EXIT 32 /* Exit status */
-#define VN_ICHR 33 /* INPUT character */
-#define VN_ICNT 34 /* INPUT count */
-#define VN_PRTY 35 /* Current parity */
-#define VN_DIAL 36 /* DIAL status */
-#define VN_KEYB 37 /* Keyboard type */
-#define VN_CPS 38 /* Chars per second, last transfer */
-#define VN_RPL 39 /* Receive packet length */
-#define VN_SPL 40 /* Send packet length */
-#define VN_MODE 41 /* Transfer mode (text, binary) */
-#define VN_REXX 42 /* Rexx return value */
-#define VN_NEWL 43 /* Newline character or sequence */
-#define VN_COLS 44 /* Columns on console screen */
-#define VN_ROWS 45 /* Rows on console screen */
-#define VN_TTYP 46 /* Terminal type */
-#define VN_MINP 47 /* MINPUT result */
-#define VN_CONN 48 /* Connection type */
-#define VN_SYSI 49 /* System ID */
-#define VN_TZ 50 /* Timezone */
-#define VN_SPA 51 /* Space */
-#define VN_QUE 52 /* Query */
-#define VN_STAR 53 /* Startup directory */
-#define VN_CSET 54 /* Local character set */
-#define VN_MDM 55 /* Modem type */
-#define VN_EVAL 56 /* Most recent EVALUATE result */
-
-#define VN_D_CC 57 /* DIAL COUNTRY-CODE */
-#define VN_D_AC 58 /* DIAL AREA-CODE */
-#define VN_D_IP 59 /* DIAL INTERNATIONAL-PREFIX */
-#define VN_D_LP 60 /* DIAL LD-PREFIX */
-
-#define VN_UID 61
-#define VN_PWD 62
-#define VN_PRM 63
-
-#define VN_PROTO 64 /* Protocol */
-#define VN_DLDIR 65 /* Download directory */
-
-#define VN_M_AAA 66 /* First MODEM one */
-#define VN_M_INI 66 /* Modem init string */
-#define VN_M_DCM 67 /* Modem dial command */
-#define VN_M_DCO 68 /* Modem data compression on */
-#define VN_M_DCX 69 /* Modem data compression off */
-#define VN_M_ECO 70 /* Modem error correction on */
-#define VN_M_ECX 71 /* Modem error correction off */
-#define VN_M_AAO 72 /* Modem autoanswer on */
-#define VN_M_AAX 73 /* Modem autoanswer off */
-#define VN_M_HUP 74 /* Modem hangup command */
-#define VN_M_HWF 75 /* Modem hardware flow command */
-#define VN_M_SWF 76 /* Modem software flow command */
-#define VN_M_NFC 77 /* Modem no flow-control command */
-#define VN_M_PDM 78 /* Modem pulse dialing mode */
-#define VN_M_TDM 79 /* Modem tone dialing mode */
-#define VN_M_ZZZ 79 /* Last MODEM one */
-
-#define VN_SELCT 80 /* Selected Text from Mark Mode */
-#define VN_TEMP 81 /* Temporary directory */
-#define VN_ISTAT 82 /* INPUT command status */
-#define VN_INI 83 /* INI (kermrc) directory */
-#define VN_EXEDIR 84 /* EXE directory */
-#define VN_ERRNO 85 /* Value of errno */
-#define VN_ERSTR 86 /* Corresponding error message */
-#define VN_TFLN 87 /* TAKE file line number */
-#define VN_XVNUM 88 /* Product-specific version number */
-#define VN_RPSIZ 89 /* Receive packet length */
-#define VN_WINDO 90 /* Window size */
-#define VN_MDMSG 91 /* Modem message */
-#define VN_DNUM 92 /* Dial number */
-#define VN_APC 93 /* APC active */
-#define VN_IPADDR 94 /* My IP address */
-#define VN_CRC16 95 /* CRC-16 of most recent file group */
-#define VN_TRMK 96 /* Macro executed from Terminal Mode */
-#define VN_PID 97 /* Process ID */
-#define VN_FNAM 98 /* Name of file being transferred */
-#define VN_FNUM 99 /* Number of file being transferred */
-#define VN_PEXIT 100 /* Process exit status */
-#define VN_P_CTL 101 /* Control Prefix */
-#define VN_P_8BIT 102 /* 8-bit prefix */
-#define VN_P_RPT 103 /* Repeat count prefix */
-#define VN_D_LCP 104 /* DIAL LOCAL-PREFIX */
-#define VN_URL 105 /* Last URL selected */
-#define VN_REGN 106 /* Registration Name */
-#define VN_REGO 107 /* Registration Organization */
-#define VN_REGS 108 /* Registration Serial number */
-#define VN_XPROG 109 /* xprogram (like xversion) */
-#define VN_EDITOR 110 /* Editor */
-#define VN_EDOPT 111 /* Editor options */
-#define VN_EDFILE 112 /* Editor file */
-#define VN_BROWSR 113 /* Browser */
-#define VN_BROPT 114 /* Browser options */
-#define VN_HERALD 115 /* Program herald */
-#define VN_TEST 116 /* Program test level or "0" */
-#define VN_XFSTAT 117 /* File-Transfer status */
-#define VN_XFMSG 119 /* File-Transfer message */
-#define VN_SNDL 120 /* Send-list status */
-#define VN_TRIG 121 /* Trigger value */
-#define VN_MOU_X 122 /* OS/2 Mouse Cursor X */
-#define VN_MOU_Y 123 /* OS/2 Mouse Cursor Y */
-#define VN_PRINT 124 /* Printer */
-#define VN_ESC 125 /* Escape character */
-#define VN_INTIME 126 /* INPUT elapsed time */
-#define VN_K4RLM 127 /* Kerberos 4 Realm */
-#define VN_K5RLM 128 /* Kerberos 5 Realm */
-#define VN_K4PRN 129 /* Kerberos 4 Principal */
-#define VN_K5PRN 130 /* Kerberos 5 Principal */
-#define VN_K4CC 131 /* Kerberos 4 Credentials Cache */
-#define VN_K5CC 132 /* Kerberos 5 Credentials Cache */
-#define VN_OSNAM 133 /* OS name */
-#define VN_OSVER 134 /* OS version */
-#define VN_OSREL 135 /* OS release */
-#define VN_NAME 136 /* Name I was called by */
-#define VN_MODL 137 /* CPU model */
-#define VN_X25LA 138 /* X.25 local address */
-#define VN_X25RA 139 /* X.25 remote address */
-#define VN_K4SRV 140 /* Kerberos 4 Service Name */
-#define VN_K5SRV 141 /* Kerberos 5 Service Name */
-#define VN_PDSFX 142 /* PDIAL suffix */
-#define VN_DTYPE 143 /* DIAL type */
-#define VN_LCKPID 144 /* Lockfile PID (UNIX) */
-#define VN_BLK 145 /* Block check */
-#define VN_TFTIM 146 /* File transfer elapsed time */
-#define VN_D_PXX 147 /* DIAL PBX-EXCHANGE */
-#define VN_HWPAR 148 /* Hardware Parity */
-#define VN_SERIAL 149 /* SET SERIAL value */
-#define VN_LCKDIR 150 /* Lockfile directory (UNIX) */
-
-#define VN_K4ENO 151 /* Kerberos 4 Last Errno */
-#define VN_K4EMSG 152 /* Kerberos 4 Last Err Msg */
-#define VN_K5ENO 153 /* Kerberos 5 Last Errno */
-#define VN_K5EMSG 154 /* Kerberos 5 Last Err Msg */
-
-#define VN_INTMO 155 /* Input timeout */
-#define VN_AUTHS 156 /* Authentication State */
-
-#define VN_DM_LP 157 /* Dial Modifier: Long Pause */
-#define VN_DM_SP 158 /* Dial Modifier: Short Pause */
-#define VN_DM_PD 159 /* Dial Modifier: Pulse Dial */
-#define VN_DM_TD 160 /* Dial Modifier: Tone Dial */
-#define VN_DM_WA 161 /* Dial Modifier: Wait for Answer */
-#define VN_DM_WD 162 /* Dial Modifier: Wait for Dialtone */
-#define VN_DM_RC 163 /* Dial Modifier: Return to Command */
-
-/* (more below...) */
-
-#define VN_TY_LN 164 /* TYPE command line number */
-#define VN_TY_LC 165 /* TYPE command line count */
-#define VN_TY_LM 166 /* TYPE command match count */
-
-#define VN_MACLVL 167 /* \v(maclevel) */
-
-#define VN_XF_BC 168 /* Transfer blockcheck errors */
-#define VN_XF_TM 169 /* Transfer timeouts */
-#define VN_XF_RX 170 /* Transfer retransmissions */
-
-#define VN_M_NAM 171 /* Modem full name */
-#define VN_MS_CD 172 /* Modem signal CD */
-#define VN_MS_CTS 173 /* Modem signal CTS */
-#define VN_MS_DSR 174 /* Modem signal DSR */
-#define VN_MS_DTR 175 /* Modem signal DTR */
-#define VN_MS_RI 176 /* Modem signal RI */
-#define VN_MS_RTS 177 /* Modem signal RTS */
-
-#define VN_MATCH 178 /* Most recent pattern match */
-#define VN_SLMSG 179 /* SET LINE (error) message */
-#define VN_TXTDIR 180 /* Kermit text-file directory */
-#define VN_MA_PI 181 /* Math constant Pi */
-#define VN_MA_E 182 /* Math constant e */
-#define VN_MA_PR 183 /* Math precision (digits) */
-#define VN_CMDBL 184 /* Command buffer length */
-
-#define VN_AUTHT 185 /* Authentication Type */
-
-#ifdef CKCHANNELIO
-#define VN_FERR 186 /* FILE error */
-#define VN_FMAX 187 /* FILE max */
-#define VN_FCOU 188 /* Result of last FILE COUNT */
-#endif /* CKCHANNELIO */
-
-#define VN_DRTR 189 /* DIAL retry counter */
-#define VN_CXTIME 190 /* Elapsed time in session */
-#define VN_BYTE 191 /* Byte order */
-#define VN_AUTHN 192 /* Authentication Name */
-#define VN_KBCHAR 193 /* kbchar */
-#define VN_TTYNAM 194 /* Name of controlling terminal */
-
-#define VN_X509_S 195 /* X.509 Certificate Subject */
-#define VN_X509_I 196 /* X.509 Certificate Issuer */
-
-#define VN_PROMPT 197 /* C-Kermit's prompt */
-#define VN_BUILD 198 /* Build ID string */
-
-#define VN_SEXP 199 /* Last S-Expression */
-#define VN_VSEXP 200 /* Value of last S-Expression */
-#define VN_LSEXP 201 /* SEXP depth */
-
-#define VN_FTIME 202 /* Time as floating-poing number */
-
-#define VN_FTP_C 203 /* FTP Reply Code */
-#define VN_FTP_M 204 /* FTP Reply Message */
-#define VN_FTP_S 205 /* FTP Server type */
-#define VN_FTP_H 206 /* FTP Host */
-#define VN_FTP_X 207 /* FTP Connected */
-#define VN_FTP_L 208 /* FTP Logged in */
-#define VN_FTP_G 209 /* FTP GET-PUT-REMOTE setting */
-
-#define VN_SECURE 210 /* Encrypted connection 0 or 1 */
-
-#define VN_DM_HF 211 /* Dial Modifier: Hook Flash */
-#define VN_DM_WB 212 /* Dial Modifier: Wait for Bong */
-#define VN_CX_STA 213 /* CX_STATUS */
-
-#define VN_FTP_B 214 /* FTP CPL */
-#define VN_FTP_D 215 /* FTP DPL */
-#define VN_FTP_Z 216 /* FTP SECURITY */
-#define VN_HTTP_C 217 /* HTTP Code */
-#define VN_HTTP_N 218 /* HTTP Connected */
-#define VN_HTTP_H 219 /* HTTP Host */
-#define VN_HTTP_M 220 /* HTTP Message */
-#define VN_HTTP_S 221 /* HTTP Security */
-
-#define VN_NOW 222 /* Timestamp yyyymmdd hh:mm:ss */
-#define VN_HOUR 223 /* Current hour of the day 0-23 */
-
-#define VN_CI_DA 224 /* Caller ID date */
-#define VN_CI_TI 225 /* Caller ID time */
-#define VN_CI_NA 226 /* Caller ID name */
-#define VN_CI_NU 227 /* Caller ID number */
-#define VN_CI_ME 228 /* Caller ID message */
-#define VN_PERSONAL 229 /* Personal Directory on Windows */
-#define VN_APPDATA 230 /* User AppData directory */
-#define VN_COMMON 231 /* Common AppData directory */
-#define VN_DESKTOP 232 /* User Desktop directory */
-#define VN_TNC_SIG 233 /* RFC 2717 Signature */
-
-#ifdef KUI
-#define VN_GUI_XP 234 /* GUI Window X position */
-#define VN_GUI_YP 235 /* GUI Window Y position */
-#define VN_GUI_XR 236 /* GUI Window X resolution */
-#define VN_GUI_YR 237 /* GUI Window Y resolution */
-#define VN_GUI_RUN 238 /* GUI Window Run mode */
-#define VN_GUI_FNM 239 /* GUI Window Font Name */
-#define VN_GUI_FSZ 240 /* GUI Window Font Size */
-#endif /* KUI */
-
-#define VN_LOG_PKT 241 /* Packet Log Filename */
-#define VN_LOG_TRA 242 /* Transaction Log Filename */
-#define VN_LOG_SES 243 /* Session Log Filename */
-#define VN_LOG_DEB 244 /* Debug Log Filename */
-#define VN_LOG_CON 245 /* Connection Log Filename */
-
-#define VN_ISCALE 246 /* INPUT scale factor */
-#define VN_BITS 247 /* Bits of this build (16, 32, 64) */
-#define VN_LASTFIL 248 /* Last input filespec */
-#define VN_LASTKWV 249 /* Last \fkeywordvalue() keyword */
-#define VN_DMSG 250 /* Msg corresponding to dialstatus */
-#define VN_HOSTIP 251 /* IP address of remote host */
-#define VN_INPMSG 252 /* Msg corresponding to instatus */
-#define VN_VAREVAL 253 /* SET VARIABLE-EVALUATION setting */
-#define VN_PREVCMD 254 /* Previous command */
-#endif /* NOSPL */
-
-/* INPUT status values */
-
-#define INP_OK 0 /* Succeeded */
-#define INP_TO 1 /* Timed out */
-#define INP_UI 2 /* User interrupted */
-#define INP_IE 3 /* Internal error */
-#define INP_IO 4 /* I/O error or connection lost */
-#define INP_IKS 5 /* Kermit Server Active */
-#define INP_BF 6 /* Buffer full */
-
-/* INPUT switch values */
-
-#define INPSW_NOM 1 /* /NOMATCH */
-#define INPSW_CLR 2 /* /CLEAR */
-#define INPSW_NOW 4 /* /NOWRAP */
-#define INPSW_COU 8 /* /COUNT */
-
-#ifndef NOSPL
-/* Symbols for builtin functions */
-
-#define FNARGS 6 /* Maximum number of function args */
-
-#define FN_IND 0 /* Index (of string 1 in string 2) */
-#define FN_LEN 1 /* Length (of string) */
-#define FN_LIT 2 /* Literal (don't expand the string) */
-#define FN_LOW 3 /* Lower (convert to lowercase) */
-#define FN_MAX 4 /* Max (maximum) */
-#define FN_MIN 5 /* Min (minimum) */
-#define FN_MOD 6 /* Mod (modulus) */
-#define FN_EVA 7 /* Eval (evaluate arith expression) */
-#define FN_SUB 8 /* Substr (substring) */
-#define FN_UPP 9 /* Upper (convert to uppercase) */
-#define FN_REV 10 /* Reverse (a string) */
-#define FN_REP 11 /* Repeat (a string) */
-#define FN_EXE 12 /* Execute (a macro) */
-#define FN_VAL 13 /* Return value (of a macro) */
-#define FN_LPA 14 /* LPAD (left pad) */
-#define FN_RPA 15 /* RPAD (right pad) */
-#define FN_DEF 16 /* Definition of a macro, unexpanded */
-#define FN_CON 17 /* Contents of a variable, ditto */
-#define FN_FIL 18 /* File list */
-#define FN_FC 19 /* File count */
-#define FN_CHR 20 /* Character (like BASIC CHR$()) */
-#define FN_RIG 21 /* Right (like BASIC RIGHT$()) */
-#define FN_COD 22 /* Code value of character */
-#define FN_RPL 23 /* Replace */
-#define FN_FD 24 /* File date */
-#define FN_FS 25 /* File size */
-#define FN_RIX 26 /* Rindex (index from right) */
-#define FN_VER 27 /* Verify */
-#define FN_IPA 28 /* Find and return IP address */
-#define FN_CRY 39 /* ... */
-#define FN_OOX 40 /* ... */
-#define FN_HEX 41 /* Hexify */
-#define FN_UNH 42 /* Unhexify */
-#define FN_BRK 43 /* Break */
-#define FN_SPN 44 /* Span */
-#define FN_TRM 45 /* Trim */
-#define FN_LTR 46 /* Left-Trim */
-#define FN_CAP 47 /* Capitalize */
-#define FN_TOD 48 /* Time-of-day-to-secs-since-midnite */
-#define FN_SEC 49 /* Secs-since-midnite-to-time-of-day */
-#define FN_FFN 50 /* Full file name */
-#define FN_CHK 51 /* Checksum of text */
-#define FN_CRC 52 /* CRC-16 of text */
-#define FN_BSN 53 /* Basename of file */
-#define FN_CMD 54 /* Output of a command (cooked) */
-#define FN_RAW 55 /* Output of a command (raw) */
-#define FN_STX 56 /* Strip from right */
-#define FN_STL 57 /* Strip from left */
-#define FN_STN 58 /* Strip n chars */
-#define FN_SCRN_CX 59 /* Screen Cursor X Pos */
-#define FN_SCRN_CY 60 /* Screen Cursor Y Pos */
-#define FN_SCRN_STR 61 /* Screen String */
-#define FN_2HEX 62 /* Number (not string) to hex */
-#define FN_2OCT 63 /* Number (not string) to octal */
-#define FN_RFIL 64 /* Recursive file list */
-#define FN_DIR 65 /* Directory list */
-#define FN_RDIR 66 /* Recursive directory list */
-#define FN_DNAM 67 /* Directory part of filename */
-#define FN_RAND 68 /* Random number */
-#define FN_WORD 69 /* Word extraction */
-#define FN_SPLIT 70 /* Split string into words */
-#define FN_KRB_TK 71 /* Kerberos tickets */
-#define FN_KRB_NX 72 /* Kerberos next ticket */
-#define FN_KRB_IV 73 /* Kerberos ticket is valid */
-#define FN_KRB_TT 74 /* Kerberos ticket time */
-#define FN_ERRMSG 75 /* Error code to message */
-
-#ifndef UNIX
-#ifndef VMS
-#undef FN_ERRMSG
-#endif /* VMS */
-#endif /* UNIX */
-
-#define FN_DIM 76 /* Dimension of array */
-#define FN_DTIM 77 /* Convert to standard date/time */
-#define FN_JDATE 78 /* Regular date to day of year */
-#define FN_PNCVT 79 /* Convert phone number for dialing */
-#define FN_DATEJ 80 /* Day of year to date */
-#define FN_MJD 81 /* Date to modified Julian date */
-#define FN_MJD2 82 /* Modified Julian date to date */
-#define FN_DAY 83 /* Day of week of given date */
-#define FN_NDAY 84 /* Numeric day of week of given date */
-#define FN_TIME 85 /* Convert to hh:mm:ss */
-#define FN_NTIM 86 /* Convert to seconds since midnite */
-#define FN_N2TIM 87 /* Sec since midnite to hh:mm:ss */
-#define FN_PERM 88 /* Permissions of file */
-#define FN_KRB_FG 89 /* Kerberos Ticket Flags */
-#define FN_SEARCH 90 /* Search for pattern in string */
-#define FN_RSEARCH 91 /* Ditto, but right to left */
-#define FN_XLATE 92 /* Translate string charset */
-#define FN_ALOOK 93 /* Array lookup */
-#define FN_TLOOK 94 /* Table lookup */
-#define FN_TOB64 95 /* Encode into Base64 */
-#define FN_FMB64 96 /* Decode from Base64 */
-
-#define FN_ABS 97 /* Absolute value */
-
-#ifdef CKFLOAT
-#define FN_FPADD 98 /* Floating-point add */
-#define FN_FPSUB 99 /* Floating-point substract */
-#define FN_FPMUL 100 /* Floating-point multiply */
-#define FN_FPDIV 101 /* Floating-point divide */
-#define FN_FPEXP 102 /* Floating-point e to the x */
-#define FN_FPLN 103 /* Floating-point natural log */
-#define FN_FPLOG 104 /* Floating-point base-10 log */
-#define FN_FPPOW 105 /* Floating-point raise to power */
-#define FN_FPSQR 106 /* Floating-point square root */
-#define FN_FPABS 107 /* Floating-point absolute value */
-#define FN_FPMOD 108 /* Floating-point modulus */
-#define FN_FPMAX 109 /* Floating-point maximum */
-#define FN_FPMIN 110 /* Floating-point minimum*/
-#define FN_FPINT 111 /* Floating-point to integer */
-#define FN_FPROU 112 /* Floating-point round */
-#define FN_FPSIN 113 /* FP sine */
-#define FN_FPCOS 114 /* FP cosine */
-#define FN_FPTAN 115 /* FP tangent */
-#endif /* CKFLOAT */
-
-#ifdef CKCHANNELIO
-#define FN_FSTAT 116 /* File status */
-#define FN_FPOS 117 /* File position */
-#define FN_FEOF 118 /* File eof */
-#define FN_FILNO 119 /* File number / handle */
-#define FN_FGCHAR 120 /* File getchar */
-#define FN_FGLINE 121 /* File getline */
-#define FN_FGBLK 122 /* File getblock */
-#define FN_FPCHAR 123 /* File putchar */
-#define FN_FPLINE 124 /* File putline */
-#define FN_FPBLK 125 /* File putblock */
-#define FN_NLINE 126 /* File get current line number */
-#define FN_FERMSG 127 /* File error message */
-#endif /* CKCHANNELIO */
-
-#define FN_LEF 128 /* Left (= substr starting on left) */
-#define FN_AADUMP 129 /* Associative Array Dump */
-#define FN_STB 130 /* \fstripb() */
-#define FN_PATTERN 131 /* \fpattern() */
-#define FN_HEX2N 132 /* \fhexton() */
-#define FN_OCT2N 133 /* \foctton() */
-#define FN_HEX2IP 134 /* \fhextoip() */
-#define FN_IP2HEX 135 /* \fiptohex() */
-#define FN_RADIX 136 /* \fradix() */
-#define FN_JOIN 137 /* \fjoin() */
-#define FN_SUBST 138 /* \fsubstitute() */
-#define FN_SEXP 139 /* \fsexpression() */
-#define FN_CMDSTK 140 /* \fcmdstack() */
-#define FN_TOGMT 141 /* \ftogmt() */
-#define FN_CMPDATE 142 /* \fcmpdates() */
-#define FN_DIFDATE 143 /* \fdiffdates() */
-#ifdef TCPSOCKET
-#define FN_HSTADD 144 /* \faddr2name() */
-#define FN_HSTNAM 145 /* \fname2addr() */
-#endif /* TCPSOCKET */
-#define FN_DELSEC 146 /* \fdelta2sec() */
-#define FN_PC_DU 147 /* Path conversion DOS to Unix */
-#define FN_PC_VU 148 /* Path conversion VMS to Unix */
-#define FN_PC_UD 149 /* Path conversion Unix to DOS */
-#define FN_PC_UV 150 /* Path conversion Unix to VMS */
-#define FN_KWVAL 151 /* \fkeywordvalue() */
-#define FN_SLEEP 152 /* \fsleep() */
-#define FN_MSLEEP 153 /* \fmsleep() */
-#define FN_LNAME 154 /* \fLongPathName() (Windows) */
-#define FN_SNAME 155 /* \fShortPathName() (Windows) */
-#define FN_UNTAB 156 /* \funtabify() */
-#define FN_LOPX 157 /* \flopx() */
-#define FN_EMAIL 158 /* \femailaddress() */
-#define FN_PICTURE 159 /* \fpictureinfo() */
-#define FN_PID 160 /* \fpidinfo() */
-#define FN_COUNT 161 /* \fcount() */
-#define FN_FUNC 162 /* \ffunction() */
-#define FN_RECURSE 163 /* \frecurse() */
-#define FN_SQUEEZE 164 /* \fsqueeze() */
-#define FN_UNPCT 165 /* \fdecodehex() */
-#define FN_STRINGT 166 /* \fstringtype() */
-#define FN_STRCMP 167 /* \fstrcmp() */
-
-#endif /* NOSPL */
-
-/* Time Units */
-
-#define TU_DAYS 0
-#define TU_WEEKS 1
-#define TU_MONTHS 2
-#define TU_YEARS 3
-
-#ifdef CK_CURSES
-/* Screen line numbers for fullscreen file-transfer display */
-
-#define CW_BAN 0 /* Curses Window Banner */
-#define CW_DIR 2 /* Current directory */
-#define CW_LIN 3 /* Communication device */
-#define CW_SPD 4 /* Communication speed */
-#define CW_PAR 5 /* Parity */
-#define CW_TMO 6
-#define CW_NAM 7 /* Filename */
-#define CW_TYP 8 /* File type */
-#define CW_SIZ 9 /* File size */
-#define CW_PCD 10 /* Percent done */
-
-#ifndef CK_PCT_BAR
-#define CW_TR 11 /* Time remaining */
-#define CW_CP 12 /* Characters per second */
-#define CW_WS 13 /* Window slots */
-#define CW_PT 14 /* Packet type */
-#define CW_PC 15 /* Packet count */
-#define CW_PL 16 /* Packet length */
-#define CW_PR 17 /* Packet retry */
-#ifdef COMMENT
-#define CW_PB 17 /* Packet block check */
-#endif /* COMMENT */
-#else /* CK_PCT_BAR */
-#define CW_BAR 11 /* Percent Bar Scale */
-#define CW_TR 12 /* Time remaining */
-#define CW_CP 13 /* Chars per sec */
-#define CW_WS 14 /* Window slots */
-#define CW_PT 15 /* Packet type */
-#define CW_PC 16 /* Packet count */
-#define CW_PL 17 /* Packet length */
-#define CW_PR 18 /* Packet retry */
-#ifdef COMMENT
-#define CW_PB 18 /* Packet block check */
-#endif /* COMMENT */
-#endif /* CK_PCT_BAR */
-
-#define CW_ERR 19 /* Error message */
-#define CW_MSG 20 /* Info message */
-#define CW_INT 22 /* Instructions */
-#define CW_FFC 99 /* File Characters Sent/Received */
-#endif /* CK_CURSES */
-
-#ifndef NOICP
-/* Save Commands */
-#define XSKEY 0 /* Key map file */
-#define XSCMD 1 /* Command mode */
-#define XSTERM 2 /* Terminal mode */
-#endif /* NOICP */
-
-#ifndef NODIAL
-/* Dial routine sort priorities */
-#define DN_INTERN 0
-#define DN_FREE 1
-#define DN_LOCAL 2
-#define DN_UNK 3
-#define DN_LONG 4
-#define DN_INTL 5
-#endif /* NODIAL */
-
-#ifdef SSHBUILTIN
-#define XSSH_OPN 1
-#define XSSH_V2 2
-#define XSSH_FLP 3
-#define XSSH_FRP 4
-#define XSSH_ADD 5
-#define XSSH_KEY 6
-#define XSSH_CLR 7
-#define XSSH_AGT 8
-
-#define SSHKT_1R 0 /* SSH KEY TYPE symbols */
-#define SSHKT_2R 1 /* must match ssh/key.h values */
-#define SSHKT_2D 2
-#define SSHKT_SRP 3
-
-#define SSHKD_IN 1 /* SSH KEY DISPLAY /IN-FORMAT */
-#define SSHKD_OUT 2 /* SSH KEY DISPLAY /OUT-FORMAT */
-
-#define SKDF_OSSH 1 /* Key display format OpenSSH */
-#define SKDF_SSHC 2 /* Key display format SSH.COM */
-#define SKDF_IETF 3 /* Key display format IETF */
-#define SKDF_FING 4 /* Key display format FINGERPRINT */
-
-#define SSHSW_USR 1
-#define SSHSW_VER 2
-#define SSHSW_CMD 3
-#define SSHSW_X11 4
-#define SSHSW_PWD 5
-#define SSHSW_SUB 6
-
-#define SSHC_LPF 1
-#define SSHC_RPF 2
-
-#define XSSH2_RKE 1
-
-#define SSHF_LCL 1
-#define SSHF_RMT 2
-
-#define SSHA_ADD 1
-#define SSHA_DEL 2
-#define SSHA_LST 3
-
-#define SSHASW_FP 1
-
-#define SSHK_PASS 1
-#define SSHK_CREA 2
-#define SSHK_DISP 3
-#define SSHK_V1 4
-
-#define SSHKC_BI 1
-#define SSHKC_PP 2
-#define SSHKC_TY 3
-#define SSHKC_1R 4
-
-#define SKRM_OPN 1
-#endif /* SSHBUILTIN */
-
-#ifdef SFTP_BUILTIN
-#define SFTP_OPN 1
-#define SFTP_CD 2
-#define SFTP_CHGRP 3
-#define SFTP_CHMOD 4
-#define SFTP_CHOWN 5
-#define SFTP_DIR 6
-#define SFTP_GET 7
-#define SFTP_MKDIR 8
-#define SFTP_PWD 9
-#define SFTP_PUT 10
-#define SFTP_REN 11
-#define SFTP_RM 12
-#define SFTP_RMDIR 13
-#define SFTP_LINK 14
-#define SFTP_VER 15
-
-#define XY_SFTP_RCS 1
-#define XY_SFTP_EOL 2
-#endif /* SFTP_BUILTIN */
-
-/* ANSI-C prototypes for user interface functions */
-
-#ifdef UNIX
-_PROTOTYP( int doputenv, ( char *, char * ) );
-#endif /* UNIX */
-
-_PROTOTYP( int chkaes, ( char, int ) );
-
-#ifndef NOICP
-_PROTOTYP( int matchname, ( char *, int, int ) );
-_PROTOTYP( int ck_cls, ( void ) );
-_PROTOTYP( int ck_cleol, ( void ) );
-_PROTOTYP( int ck_curpos, ( int, int ) );
-_PROTOTYP( int cmdsrc, ( void ) );
-_PROTOTYP( int parser, ( int ) );
-_PROTOTYP( int chkvar, (char *) );
-_PROTOTYP( int zzstring, (char *, char **, int *) );
-#ifndef NOFRILLS
-_PROTOTYP( int yystring, (char *, char **) );
-#endif /* NOFRILLS */
-_PROTOTYP( int getncm, (char *, int) );
-_PROTOTYP( int getnct, (char *, int, FILE *, int) );
-#endif /* NOICP */
-_PROTOTYP( VOID bgchk, (void) );
-_PROTOTYP( char * nvlook, (char *) );
-_PROTOTYP( int xarray, (char *) );
-_PROTOTYP( int arraynam, (char *, int *, int *) );
-_PROTOTYP( int arraybounds, (char *, int *, int *) );
-_PROTOTYP( int boundspair, (char *, char *, int *, int *, char *) );
-_PROTOTYP( int arrayitoa, (int) );
-_PROTOTYP( int arrayatoi, (int) );
-_PROTOTYP( char * bldlen, (char *, char *) );
-_PROTOTYP( int chkarray, (int, int) );
-_PROTOTYP( int dclarray, (char, int) );
-_PROTOTYP( int pusharray, (int, int) );
-_PROTOTYP( int parsevar, (char *, int *, int *) );
-_PROTOTYP( int macini, (void) );
-_PROTOTYP( VOID initmac, (void) );
-_PROTOTYP( int delmac, (char *, int) );
-_PROTOTYP( int addmac, (char *, char *) );
-_PROTOTYP( int domac, (char *, char *, int) );
-_PROTOTYP( int addmmac, (char *, char *[]) );
-_PROTOTYP( int dobug, (void) );
-_PROTOTYP( int docd, (int) );
-_PROTOTYP( int doclslog, (int) );
-_PROTOTYP( int docmd, (int) );
-_PROTOTYP( int dodir, (int) );
-_PROTOTYP( int dodo, (int, char *, int) );
-_PROTOTYP( int doenable, (int, int) );
-_PROTOTYP( int dogoto, (char *, int) );
-_PROTOTYP( int dogta, (int) );
-_PROTOTYP( int dohlp, (int) );
-_PROTOTYP (int doincr, (int) );
-_PROTOTYP( int dohrmt, (int) );
-_PROTOTYP( int doif, (int) );
-_PROTOTYP( int doinput, (int, char *[], int[], int, int) );
-_PROTOTYP( int doreinp, (int, char *, int) );
-_PROTOTYP( int dolog, (int) );
-_PROTOTYP( int dologin, (char *) );
-_PROTOTYP( int doopen, (void) );
-_PROTOTYP( int doprm, (int, int) );
-_PROTOTYP( int doreturn, (char *) );
-_PROTOTYP( int dormt, (int) );
-_PROTOTYP( int dosort, (void) );
-_PROTOTYP( int dostat, (int) );
-_PROTOTYP( int dostop, (void) );
-_PROTOTYP( int dotype, (char *, int, int, int, char *, int, char *, int, int,
- char *, int));
-_PROTOTYP( int transmit, (char *, char, int, int, int) );
-_PROTOTYP( int xlate, (char *, char *, int, int) );
-_PROTOTYP( int litcmd, (char **, char **, int) );
-_PROTOTYP( int incvar, (char *, CK_OFF_T, int) );
-_PROTOTYP( int ckdial, (char *, int, int, int, int) );
-_PROTOTYP( int hmsg, (char *) );
-_PROTOTYP( int hmsga, (char * []) );
-_PROTOTYP( int mlook, (struct mtab [], char *, int) );
-_PROTOTYP( int mxlook, (struct mtab [], char *, int) );
-_PROTOTYP( int mxxlook, (struct mtab [], char *, int) );
-_PROTOTYP( int prtopt, (int *, char *) );
-_PROTOTYP( CHAR rfilop, (char *, char) );
-_PROTOTYP( int setcc, (char *, int *) );
-_PROTOTYP( int setnum, (int *, int, int, int) );
-_PROTOTYP( int seton, (int *) );
-_PROTOTYP( int setonaut, (int *) );
-_PROTOTYP( VOID shmdmlin, (void) );
-_PROTOTYP( VOID initmdm, (int) );
-_PROTOTYP( char * showoff, (int) );
-_PROTOTYP( char * showooa, (int) );
-_PROTOTYP( char * showstring, (char *) );
-_PROTOTYP( int pktopn, (char *,int) );
-_PROTOTYP( int traopn, (char *,int) );
-_PROTOTYP( int sesopn, (char *,int) );
-_PROTOTYP( int debopn, (char *,int) );
-_PROTOTYP( int diaopn, (char *,int,int) );
-_PROTOTYP( int prepop, (void) );
-_PROTOTYP( int popclvl, (void) );
-_PROTOTYP( int varval, (char *, CK_OFF_T *) );
-_PROTOTYP( char * evala, (char *) );
-_PROTOTYP( char * evalx, (char *) );
-_PROTOTYP( int setalarm, (long) );
-_PROTOTYP( int setat, (int) );
-_PROTOTYP( int setinp, (void) );
-_PROTOTYP( VOID dolognet, (void) );
-_PROTOTYP( VOID dologline, (void) );
-_PROTOTYP( int setlin, (int, int, int) );
-_PROTOTYP( int setmodem, (void) );
-_PROTOTYP( int setfil, (int) );
-_PROTOTYP( char * homepath, (void) );
-#ifdef OS2
-_PROTOTYP( int settapi, (void) ) ;
-#ifdef OS2MOUSE
-_PROTOTYP( int setmou, (void) );
-#endif /* OS2MOUSE */
-#endif /* OS2 */
-#ifdef LOCUS
-_PROTOTYP( VOID setlocus, (int,int) );
-_PROTOTYP( VOID setautolocus, (int) );
-#endif /* LOCUS */
-_PROTOTYP( int setbell, (void) );
-_PROTOTYP( VOID setcmask, (int));
-_PROTOTYP( VOID setautodl, (int,int));
-_PROTOTYP( VOID setdebses, (int));
-_PROTOTYP( VOID setseslog, (int));
-_PROTOTYP( VOID setaprint, (int));
-_PROTOTYP( int settrm, (void) );
-_PROTOTYP( int settrmtyp, (void) );
-_PROTOTYP( int setsr, (int, int) );
-_PROTOTYP( int setxmit, (void) );
-_PROTOTYP( int dosetkey, (void) );
-_PROTOTYP( int dochk, (void) );
-_PROTOTYP( int ludial, (char *, int) );
-_PROTOTYP( char * getdnum, (int) );
-_PROTOTYP( VOID getnetenv, (void) );
-_PROTOTYP( int getyesno, (char *, int) );
-_PROTOTYP( VOID xwords, (char *, int, char *[], int) );
-#ifdef OS2
-_PROTOTYP( VOID keynaminit, (void) );
-#endif /* OS2 */
-_PROTOTYP( int xlookup, (struct keytab[], char *, int, int *) );
-_PROTOTYP( char * rlookup, (struct keytab[], int, int) );
-_PROTOTYP( int hupok, (int) );
-_PROTOTYP( char * zzndate, (void) );
-_PROTOTYP( char * zjdate, (char *) );
-_PROTOTYP( char * jzdate, (char *) );
-_PROTOTYP( char * ckdate, (void) );
-_PROTOTYP( char * chk_ac, (int, char[]) );
-_PROTOTYP( char * gmdmtyp, (void) );
-_PROTOTYP( char * gfmode, (int, int) );
-_PROTOTYP( int setdest, (void) );
-_PROTOTYP( VOID ndinit, (void) );
-_PROTOTYP( int doswitch, (void) );
-_PROTOTYP( int dolocal, (void) );
-_PROTOTYP( long tod2sec, (char *) );
-_PROTOTYP( int lunet, (char *) );
-_PROTOTYP( int doxdis, (int) );
-_PROTOTYP( int dosave, (int) );
-_PROTOTYP( int doxsend, (int) );
-_PROTOTYP( int doxget, (int) );
-_PROTOTYP( int doxconn, (int) );
-_PROTOTYP( int clsconnx, (int) );
-_PROTOTYP( VOID ftreset, (void) );
-#ifdef CK_KERBEROS
-_PROTOTYP (int cp_auth, ( void ) );
-#endif /* CK_KERBEROS */
-_PROTOTYP( long mjd, (char *) );
-_PROTOTYP( char * mjd2date, (long) );
-_PROTOTYP( char * ckgetpid, (void) );
-
-_PROTOTYP( int dogrep, (void) );
-
-#ifndef NOFTP
-#ifndef SYSFTP
-_PROTOTYP( int doxftp, (void) );
-_PROTOTYP( int doftphlp, (void) );
-_PROTOTYP( int dosetftp, (void) );
-_PROTOTYP( int dosetftphlp, (void) );
-_PROTOTYP( int shoftp, (int) );
-#endif /* SYSFTP */
-#endif /* NOFTP */
-
-_PROTOTYP( VOID cmhistory, (void) );
-_PROTOTYP( char * getdcset, (void) );
-_PROTOTYP( char * ttgtpn, (void) );
-
-#ifndef NOSHOW
-_PROTOTYP( int doshow, (int) );
-_PROTOTYP( int shotcp, (int) );
-_PROTOTYP( VOID shopar, (void) );
-_PROTOTYP( VOID shofil, (void) );
-_PROTOTYP( VOID shoparp, (void) );
-_PROTOTYP( int shoatt, (void) );
-_PROTOTYP( VOID shover, (void) );
-_PROTOTYP( VOID shoctl, (void) );
-_PROTOTYP( VOID shodbl, (void) );
-#ifndef NOSPL
-_PROTOTYP( int shomac, (char *, char *) );
-_PROTOTYP( int doshift, (int) );
-#endif /* NOSPL */
-#ifndef NOCSETS
-_PROTOTYP( VOID shocharset, (void) );
-_PROTOTYP( VOID shoparl, (void) );
-_PROTOTYP( VOID shotcs, (int, int) );
-#endif /* NOCSETS */
-#ifndef NOLOCAL
-_PROTOTYP( VOID shoparc, (void) );
-_PROTOTYP( int shomodem, (void) );
-#ifndef NODIAL
-_PROTOTYP( VOID shods, (char *) );
-_PROTOTYP( VOID shodial, (void) );
-_PROTOTYP( int doshodial, (void) );
-#endif /* NODIAL */
-#ifndef NONET
-_PROTOTYP( int shonet, (void) );
-_PROTOTYP( int shotopt, (int) );
-_PROTOTYP( int shotel, (int) );
-#ifdef CK_AUTHENTICATION
-_PROTOTYP (int sho_auth,( int ) );
-#endif /* CK_AUTHENTICATION */
-#endif /* NONET */
-_PROTOTYP( VOID shomdm, (void) );
-#endif /* NOLOCAL */
-#ifdef OS2
-_PROTOTYP( VOID shokeycode, (int,int) );
-#else
-_PROTOTYP( VOID shokeycode, (int) );
-#endif /* OS2 */
-_PROTOTYP( VOID showassoc, (void) );
-_PROTOTYP( VOID showdiropts, (void) );
-_PROTOTYP( VOID showdelopts, (void) );
-_PROTOTYP( VOID showtypopts, (void) );
-_PROTOTYP( VOID showpurgopts, (void) );
-_PROTOTYP( VOID shoflow, (void) );
-_PROTOTYP( VOID shoxfer, (void) );
-#ifdef ANYSSH
-_PROTOTYP( VOID shossh, (void) );
-#endif /* ANYSSH */
-#endif /* NOSHOW */
-
-_PROTOTYP( VOID shostrdef, (CHAR *) );
-
-#ifndef NOSPL
-_PROTOTYP( int addlocal, (char *) );
-#endif /* NOSPL */
-
-_PROTOTYP( int setdelopts, (void) );
-
-#ifdef VMS
-_PROTOTYP( int cvtdir, (char *, char *, int) );
-#endif /* VMS */
-
-#ifdef FNFLOAT
-_PROTOTYP( VOID initfloat, (void) );
-#endif /* FNFLOAT */
-
-#ifdef CKCHANNELIO
-_PROTOTYP( int dofile, (int) );
-#endif /* CKCHANNELIO */
-
-#ifdef CKROOT
-_PROTOTYP( int dochroot, (void) );
-#endif /* CKROOT */
-
-#ifdef NEWFTP
-_PROTOTYP( int doftpusr, (void) );
-_PROTOTYP( int doftpput, (int,int) );
-_PROTOTYP( int doftpget, (int,int) );
-_PROTOTYP( int doftprmt, (int,int) );
-_PROTOTYP( int ftpopen, (char *, char *, int) );
-_PROTOTYP( int cmdlinget, (int) );
-_PROTOTYP( int cmdlinput, (int) );
-_PROTOTYP( int doftparg, (char) );
-_PROTOTYP( int doftpacct, (void) );
-_PROTOTYP( int doftpsite, (void) );
-_PROTOTYP( int dosetftppsv, (void) );
-_PROTOTYP( int ftpbye, (void) );
-#endif /* NEWFTP */
-
-#ifdef COMMENT
-/* These prototypes are no longer used */
-_PROTOTYP( char * getdws, (int) );
-_PROTOTYP( char * getdcs, (int) );
-_PROTOTYP( int doget, (int) );
-_PROTOTYP( char * arrayval, (int, int) );
-#endif /* COMMENT */
-
-#ifdef KUI
-_PROTOTYP(int BuildFontTable,
- (struct keytab ** pTable, struct keytab ** pTable2, int * pN));
-#endif /* KUI */
-
-_PROTOTYP(int cx_net, (int net, int protocol, char * xhost, char * svc,
- char * username, char * password, char * command,
- int param1, int param2, int param3,
- int cx, int sx, int flag, int gui));
-_PROTOTYP(int cx_serial, (char *device,
- int cx, int sx, int shr, int flag, int gui, int special));
-
-#endif /* CKUUSR_H */
-
-/* End of ckuusr.h */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusx.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuusx.c
deleted file mode 100644
index 4c464f7..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusx.c
+++ /dev/null
@@ -1,9721 +0,0 @@
-#include "ckcsym.h"
-
-/* C K U U S X -- "User Interface" common functions. */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- This module contains user interface functions needed by both the interactive
- user interface and the command-line-only user interface, as well as the
- screen-control routines (curses and equivalent).
-*/
-
-/* Includes */
-
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckuusr.h"
-#include "ckcxla.h"
-
-#ifndef NOHTERMCAP
-#ifdef NOTERMCAP
-#define NOHTERMCAP
-#else
-#ifndef BSD44
-#define NOHTERMCAP
-#else
-#ifdef __bsdi__
-#define NOHTERMCAP
-#else
-#ifdef OPENBSD
-#define NOHTERMCAP
-#else
-#ifdef MACOSX
-#define NOHTERMCAP
-#endif /* MACOSX */
-#endif /* OPENBSD */
-#endif /* __bsdi__ */
-#endif /* BSD44 */
-#endif /* NOTERMCAP */
-#endif /* NOHTERMCAP */
-
-#ifndef NOTERMCAP
-#ifdef BSD44
-#ifndef NOHTERMCAP
-#include <termcap.h>
-#endif /* NOHTERMCAP */
-#endif /* BSD44 */
-#else /* !BSD44 */
-#ifdef linux
-#include <term.h>
-#endif /* linux */
-#endif /* NOTERMCAP */
-
-#ifdef OS2
-#include <string.h>
-_PROTOTYP(char * os2_gethostname, (void));
-#define getpid _getpid
-#endif /* OS2 */
-#ifdef BSD44
-#include <errno.h>
-#endif /* BSD44 */
-
-extern xx_strp xxstring;
-
-#ifdef OS2
-#include "ckcnet.h"
-#else /* OS2 */
-_PROTOTYP( char * ckgetpeer, (VOID));
-_PROTOTYP(int getlocalipaddr, (void));
-_PROTOTYP(int istncomport, (void));
-#ifndef NOCKGETFQHOST
-_PROTOTYP( char * ckgetfqhostname,(char *));
-#endif /* NOCKGETFQHOST */
-#ifndef NETCONN
-/*
- We should just pull in ckcnet.h here, but it causes a conflict with curses.h.
-*/
-#ifdef TCPSOCKET
-#define NETCONN
-#else
-#ifdef SUNX25
-#define NETCONN
-#else
-#ifdef STRATUSX25
-#define NETCONN
-#else
-#ifdef IBMX25
-#define NETCONN
-#else
-#ifdef HPX25
-#define NETCONN
-#else
-#ifdef DECNET
-#define NETCONN
-#else
-#ifdef NPIPE
-#define NETCONN
-#else
-#ifdef CK_NETBIOS
-#define NETCONN
-#ifdef SUPERLAT
-#define NETCONN
-#else
-#endif /* SUPERLAT */
-#endif /* TCPSOCKET */
-#endif /* SUNX25 */
-#endif /* STRATUSX25 */
-#endif /* IBMX25 */
-#endif /* HPX25 */
-#endif /* DECNET */
-#endif /* NPIPE */
-#endif /* CK_NETBIOS */
-#endif /* NETCONN */
-#endif /* OS2 */
-
-#ifndef TCPSOCKET
-#ifdef MULTINET
-#define TCPSOCKET
-#endif /* MULTINET */
-#ifdef DEC_TCPIP
-#define TCPSOCKET
-#endif /* DEC_TCPIP */
-#ifdef WINTCP
-#define TCPSOCKET
-#endif /* WINTCP */
-#ifdef TCPWARE
-#define TCPSOCKET
-#endif /* TCPWARE */
-#endif /* TCPSOCKET */
-
-#ifdef OS2
-#ifdef NT
-#include <windows.h>
-#include <tapi.h>
-#include "ckntap.h"
-#else /* NT */
-#define INCL_VIO
-#include <os2.h>
-#endif /* NT */
-#ifdef COMMENT /* Would you believe */
-#undef COMMENT /* <os2.h> defines this ? */
-#endif /* COMMENT */
-#ifdef CK_NETBIOS
-#include "ckonbi.h"
-#endif /* CK_NETBIOS */
-
-#include "ckocon.h"
-extern ascreen commandscreen;
-#ifdef KUI
-#include "ikui.h"
-#endif /* KUI */
-#endif /* OS2 */
-
-#ifdef NT
-#include "cknwin.h"
-#endif /* NT */
-#ifdef OS2
-#include "ckowin.h"
-#include "ckosyn.h"
-#endif /* OS2 */
-
-#ifdef CK_TAPI
-extern int tttapi;
-extern int tapipass;
-#endif /* CK_TAPI */
-
-#ifdef CK_KERBEROS
-#include "ckuath.h"
-#endif /* CK_KERBEROS */
-
-#ifndef WINTCP
-#include <signal.h>
-#endif /* WINTCP */
-
-#ifdef VMS
-#include <descrip.h>
-#include <ssdef.h>
-#include <stsdef.h>
-#ifndef OLD_VMS
-#include <lib$routines.h> /* Not for VAX C 2.3 */
-#else
-#include <libdef.h>
-#endif /* OLD_VMS */
-#ifdef WINTCP
-#include <signal.h>
-#endif /* WINTCP */
-#endif /* VMS */
-
-#ifdef DCLFDOPEN
-/* fdopen() needs declaring because it's not declared in <stdio.h> */
-_PROTOTYP( FILE * fdopen, (int, char *) );
-#endif /* DCLFDOPEN */
-
-#ifdef DCLPOPEN
-/* popen() needs declaring because it's not declared in <stdio.h> */
-_PROTOTYP( FILE * popen, (char *, char *) );
-#endif /* DCLPOPEN */
-
-int tt_crd = 0; /* Carriage return display */
-int tt_lfd = 0; /* Linefeed display */
-int interrupted = 0; /* Interrupted from keyboard flag */
-int fxd_inited = 0; /* Fullscreen stuff initialized */
-
-#ifdef DEBUG
-char debfil[CKMAXPATH+1]; /* Debugging log file name */
-#endif /* DEBUG */
-
-#ifdef TLOG
-char trafil[CKMAXPATH+1]; /* Transaction log file name */
-#endif /* TLOG */
-
-char sesfil[CKMAXPATH+1]; /* Session log file name */
-
-#ifdef CKLOGDIAL
-char diafil[CKMAXPATH+1]; /* Connection log file name */
-char cxlogbuf[CXLOGBUFL+1]; /* Connection log record buffer */
-int cx_active = 0; /* Connection is active */
-extern int dialog;
-#endif /* CKLOGDIAL */
-
-#ifdef DYNAMIC
-static char *cmdstr = NULL; /* Place to build generic command */
-#else
-#ifdef pdp11
-static char cmdstr[256];
-#else
-static char cmdstr[4096];
-#endif /* pdp11 */
-#endif /* DYNAMIC */
-
-#ifndef NOMSEND
-char fspec[CMDBL+4]; /* Filename string for \v(filespec) */
-int fspeclen = CMDBL;
-#else
-char fspec[CKMAXPATH+4];
-int fspeclen = CKMAXPATH;
-#endif /* NOMSEND */
-
-char * rfspec = NULL; /* Received filespec: local */
-char * prfspec = NULL; /* Preliminary rfspec */
-char * sfspec = NULL; /* Sent filespec: local */
-char * psfspec = NULL; /* Preliminary sfspec */
-char * srfspec = NULL; /* Received filespec: remote */
-char * psrfspec = NULL; /* Preliminary srfspec */
-char * rrfspec = NULL; /* Sent filespec: remote */
-char * prrfspec = NULL; /* Preliminary rrfspec */
-
-int success = 1, /* Command success/failure flag */
- cmdlvl = 0, /* Command level */
- action = 0, /* Action selected on command line */
- slogts = 0, /* Session-log timestamps on/off */
- slognul = 0, /* Session-log null-terminated lines */
-#ifdef UNIX
- sessft = XYFT_T, /* Session log file type */
-#else
- sessft = XYFT_B, /* (text for UNIX binary for others) */
-#endif /* UNIX */
- pflag = 1, /* Print prompt */
- msgflg = 1; /* Print informational messages */
-
-extern int xaskmore, saveask; /* More-prompting */
-
-#ifdef CK_APC
-extern int apcactive;
-#endif /* CK_APC */
-/* External variables */
-
-extern int local, quiet, binary, network, what, parity, xitsta, escape,
- tlevel, bgset, backgrd, xsuspend, cmdint, nettype, seslog, dfloc;
-
-extern int cmd_rows, cmd_cols, xcmdsrc;
-
-extern char cmdfil[];
-
-#ifdef VMS
-extern int batch;
-#endif /* VMS */
-
-#ifdef datageneral /* 2/12/92 ENH */
-#include <sysid.h>
-extern int con_reads_mt, conint_ch, conint_avl;
-#endif /* datageneral */
-
-extern long speed;
-
-extern char ttname[], *dftty, *cmarg, **cmlist, *versio, myhost[];
-
-#ifndef NOCSETS
-extern int fcharset, tcharset, xfrxla;
-extern struct csinfo fcsinfo[], tcsinfo[];
-#endif /* NOCSETS */
-
-#ifdef OS2
-extern unsigned char colorcmd;
-#endif /* OS2 */
-
-#ifdef NOXFER
-
-int fdispla = XYFD_N;
-
-#else /* NOXFER is not defined */
-
-#ifdef OS2 /* File transfer display type */
-int fdispla = XYFD_C; /* Curses (fullscreen) if we have it */
-#else
-#ifdef CK_CURSES
-int fdispla = XYFD_C;
-#else
-int fdispla = XYFD_S; /* Otherwise CRT */
-#endif /* CK_CURSES */
-#endif /* OS2 */
-
-extern struct ck_p ptab[];
-extern int protocol, xfrbel, xfrint;
-
-#ifdef STREAMING
-extern int streaming, streamok;
-#endif /* STREAMING */
-
-/* Used internally */
-
-#ifdef KUI
-_PROTOTYP( VOID screeng, (int, char, long, char *) );
-#endif /* KUI */
-_PROTOTYP( VOID screenc, (int, char, CK_OFF_T, char *) );
-
-
-#ifdef CK_CURSES
-#ifndef DYNAMIC
-static char xtrmbuf[TRMBUFL]; /* tgetent() buffer */
-char * trmbuf = xtrmbuf;
-#else
-char * trmbuf = NULL;
-#endif /* DYNAMIC */
-_PROTOTYP( static VOID dpyinit, (void) );
-_PROTOTYP( static long shocps, (int, CK_OFF_T, CK_OFF_T) );
-_PROTOTYP( static CK_OFF_T shoetl, (CK_OFF_T, long, CK_OFF_T, CK_OFF_T) );
-#endif /* CK_CURSES */
-
-static int ft_win = 0; /* Fullscreen file transfer display window is active */
-
-/* Variables declared here */
-
-static char * skreason[] = {
- "", /* 0 */
- "Remote file not older", /* SKP_DAT */
- "Identical modification times", /* SKP_EQU */
- "Type", /* SKP_TYP */
- "Size", /* SKP_SIZ */
- "Name collision", /* SKP_NAM */
- "Exception List", /* SKP_EXL */
- "Dot file", /* SKP_DOT */
- "Backup file", /* SKP_BKU */
- "Recovery not needed", /* SKP_RES */
- "Access denied", /* SKP_ACC */
- "Not a regular file", /* SKP_NRF */
- "Simulated", /* SKP_SIM */
- "Simulated - Remote file older", /* SKP_XUP */
- "Simulated - No remote file", /* SKP_XNX */
-};
-static int nskreason = (sizeof(skreason) / sizeof(char *));
-
-char *
-gskreason(n) int n; {
- return((n > 0 && n < nskreason) ? skreason[n] : "");
-}
-
-char pktfil[CKMAXPATH+1]; /* Packet log file name */
-
-#ifndef NOMSEND /* Multiple SEND */
-char *msfiles[MSENDMAX];
-#endif /* NOMSEND */
-
-#ifdef CK_TIMERS
-extern long rttdelay;
-extern int rttflg;
-#endif /* CK_TIMERS */
-extern int rcvtimo;
-
-#ifdef CK_RESEND
-extern int sendmode;
-extern CK_OFF_T sendstart, rs_len;
-#endif /* CK_RESEND */
-
-#ifdef CK_PCT_BAR /* File transfer thermometer */
-int thermometer = 1; /* ON by default */
-#endif /* CK_PCT_BAR */
-
-#ifdef GFTIMER
-CKFLOAT gtv = -1.0, oldgtv = -1.0;
-#else
-#ifndef OS2
-static
-#endif /* OS2 */
- long gtv = -1L, oldgtv = -1L;
-#endif /* GFTIMER */
-
-extern int server, bctu, rptflg, ebqflg, spsiz, urpsiz, wmax, czseen, cxseen,
- winlo, displa, timint, npad, ebq, bctr, rptq, atcapu, lpcapu,
- swcapu, wslotn, wslotr, rtimo, mypadn, sq, capas, rpsiz, tsecs,
- pktlog, lscapu, dest, srvdis, wslots, spackets, spktl, rpktl,
- retrans, wcur, numerrs, fsecs, whatru, crunched, timeouts,
- rpackets, fncnv, bye_active, discard, inserver, diractive, cdactive;
-
-extern long filcnt, filrej, rptn, filcps, tfcps, cps, peakcps;
-extern CK_OFF_T ffc, tfc, fsize;
-
-long oldcps = 0L;
-
-extern CHAR *rdatap, padch, seol, ctlq, mypadc, eol, *epktmsg;
-extern char *xfrmsg;
-
-#ifdef IKSDB
-FILE * dbfp = NULL; /* File pointer to database file */
-
-int dbenabled = 1; /* Flag for database is enabled */
-extern int ikdbopen; /* Flag for database is open */
-
-unsigned long mydbseek = 0L; /* Seek pointer to my record */
-int mydbslot = 0; /* My slot number */
-unsigned long myflags = 0L; /* My flags */
-unsigned long myatype = 0L; /* My authorization type */
-unsigned long myamode = 0L; /* My authorization mode */
-unsigned long mystate = 0L; /* My state (SEND, RECEIVE, etc) */
-unsigned long mypid = 0L; /* My PID */
-unsigned long myip = 0L; /* My IP address */
-unsigned long peerip = 0L; /* My peer's IP address */
-
-unsigned long dbip = 0L; /* IP address in db record */
-unsigned long dbpid = 0L; /* PID in db record */
-unsigned long dbflags = 0L; /* Flags field in db record */
-unsigned long dblastused = 0L; /* Last in-use record in db */
-char dbrec[DB_RECL]; /* Database record buffer */
-
-char * dbdir = NULL; /* Database directory */
-char * dbfile = NULL; /* Database file full pathname */
-char myhexip[33] = { NUL, NUL }; /* My IP address in hex */
-char peerhexip[33] = { NUL, NUL }; /* Client's IP address in hex */
-#endif /* IKSDB */
-
-#ifdef GFTIMER
-extern CKFLOAT fpfsecs, fptsecs, fpxfsecs;
-#else
-extern long xfsecs;
-#endif /* GFTIMER */
-#endif /* NOXFER */
-
-#ifdef TCPSOCKET
-#ifdef NEWFTP
-extern char * ftp_host, ftp_srvtyp[];
-extern int ftp_csx, ftp_csl, ftp_deb;
-#endif /* NEWFTP */
-extern char myipaddr[];
-#endif /* TCPSOCKET */
-
-#ifndef NOICP
-#ifndef NOSPL
- extern struct mtab *mactab; /* For ON_EXIT macro. */
- extern int nmac;
-#endif /* NOSPL */
-#ifdef DCMDBUF
-extern char *cmdbuf; /* Command buffer */
-#else
-extern char cmdbuf[]; /* Command buffer */
-#endif /* DCMDBUF */
-extern int cmd_quoting;
-#endif /* NOICP */
-
-#ifndef NOCCTRAP
-#ifdef NT
-#include <setjmpex.h>
-#else /* NT */
-#include <setjmp.h>
-#endif /* NT */
-#include "ckcsig.h"
-extern ckjmpbuf cmjbuf;
-#endif /* NOCCTRAP */
-
-extern int xfiletype, nscanfile;
-
-int
-shoesc(escape) int escape; {
- extern char * ccntab[]; /* C0 control character name table */
- extern int tt_escape;
- if ((escape > 0 && escape < 32) || (escape == 127)) {
- printf(" Escape character: Ctrl-%c (ASCII %d, %s): %s\r\n",
- ctl(escape),
- escape,
- (escape == 127 ? "DEL" : ccntab[escape]),
- tt_escape ? "enabled" : "disabled"
- );
- } else {
- printf(" Escape character: Code %d",escape);
- if (escape > 160 && escape < 256)
- printf(" (%c)",escape);
- printf(": %s\r\n", tt_escape ? "enabled" : "disabled");
- }
- return(0);
-}
-
-#ifndef NOXFER
-/* P R E S E T -- Reset global protocol variables */
-
-extern int recursive;
-
-#ifdef PATTERNS
-int patterns = SET_AUTO; /* Whether to use filename patterns */
-extern int g_patterns; /* For saving and restoring */
-#else
-int patterns = SET_OFF;
-#endif /* PATTERNS */
-
-#ifndef NOICP
-#ifdef CK_LABELED
-extern int g_lf_opts, lf_opts;
-#endif /* CK_LABELED */
-extern int g_matchdot, g_usepipes, usepipes;
-extern int g_binary, g_proto, g_displa, g_spath, g_rpath, g_fncnv;
-extern int g_recursive;
-extern int g_xfermode, xfermode;
-extern int g_urpsiz, g_spsizf, g_spsiz;
-extern int g_spsizr, g_spmax, g_wslotr, g_prefixing, g_fncact;
-extern int g_fnspath, g_fnrpath, g_skipbup;
-extern int nolinks;
-#ifdef CKSYMLINK
-extern int zgfs_link;
-#endif /* CKSYMLINK */
-#ifndef NOSPL
-extern int g_pflg, pwflg, g_pcpt, pwcrypt;
-extern char * g_pswd, pwbuf[];
-#endif /* NOSPL */
-#endif /* NOICP */
-
-extern int spsizf, spsizr, spmax, prefixing, fncact, fnspath, fnrpath;
-extern int moving; /* SEND criteria */
-extern char sndafter[], sndbefore[], *sndexcept[], *rcvexcept[];
-extern CK_OFF_T sndlarger, sndsmaller, calibrate;
-extern int rmailf, rprintf, skipbup;
-extern char optbuf[];
-
-#ifdef PIPESEND
-extern char * g_sfilter, * g_rfilter;
-extern char * sndfilter, * rcvfilter;
-#endif /* PIPESEND */
-extern char ** sndarray;
-
-VOID
-ftreset() {
-#ifndef NOICP
- int i;
- extern char * filefile;
- extern int reliable, xreliable, c_save, ss_save, slostart, urclear;
- extern int oopts, omode, oname, opath, kactive, autopath;
- extern char * snd_move; /* Directory to move sent files to */
- extern char * snd_rename; /* What to rename sent files to */
- extern char * rcv_move;
- extern char * rcv_rename;
- extern char * g_snd_move;
- extern char * g_snd_rename;
- extern char * g_rcv_move;
- extern char * g_rcv_rename;
-
-#ifdef CK_TMPDIR
- extern int f_tmpdir;
- extern char savdir[];
-#endif /* CK_TMPDIR */
-
-#ifdef CK_SPEED
-#ifdef COMMENT
- extern int f_ctlp;
- extern short s_ctlp[], ctlp[];
-#endif /* COMMENT */
-#endif /* CK_SPEED */
-
-#ifndef NOCSETS
- extern int fcs_save, tcs_save;
- extern int g_xfrxla, xfrxla;
-#endif /* NOCSETS */
-
-/* Restore / reset per-command file-transfer switches */
-
- makestr(&snd_move,g_snd_move);
- makestr(&rcv_move,g_rcv_move);
- makestr(&snd_rename,g_snd_rename);
- makestr(&rcv_rename,g_rcv_rename);
-
- kactive = 0; /* Kermit protocol no longer active */
- oopts = -1; /* O-Packet Options */
- omode = -1; /* O-Packet Transfer Mode */
- oname = -1; /* O-Packet Filename Options */
- opath = -1; /* O-Packet Pathname Options */
-
-#ifdef CK_RESEND
- rs_len = 0L; /* REGET position */
-#endif /* CK_RESEND */
-
-#ifdef COMMENT
-#ifdef CK_SPEED
- if (f_ctlp) {
- for (i = 0; i < 256; i++)
- ctlp[i] = s_ctlp[i];
- f_ctlp = 0;
- }
-#endif /* CK_SPEED */
-#endif /* COMMENT */
-
-#ifdef CK_TMPDIR
- if (f_tmpdir) { /* If we changed to download dir */
- zchdir((char *) savdir); /* Go back where we came from */
- f_tmpdir = 0;
- }
-#endif /* CK_TMPDIR */
-
- calibrate = 0L; /* Calibration run */
- if (xreliable > -1) {
- reliable = xreliable;
- debug(F101,"ftreset reliable","",reliable);
- }
- urclear = 0;
-
- if (autopath) { /* SET RECEIVE PATHNAMES AUTO */
- fnrpath = PATH_AUTO;
- autopath = 0;
- }
- if (filefile) { /* File list */
- zclose(ZMFILE);
- makestr(&filefile,NULL);
- }
- if (c_save > -1) { /* Block Check Type */
- bctr = c_save;
- c_save = -1;
- }
- if (ss_save > -1) { /* Slow Start */
- slostart = ss_save;
- ss_save = -1;
- }
-#ifdef CK_LABELED
- if (g_lf_opts > -1) {
- lf_opts = g_lf_opts; /* Restore labeled transfer options */
- g_lf_opts = -1;
- }
-#endif /* CK_LABELED */
-
-#ifndef NOCSETS
- if (tcs_save > -1) { /* Character sets */
- tcharset = tcs_save;
- tcs_save = -1;
- }
- if (fcs_save > -1) {
- fcharset = fcs_save;
- fcs_save = -1;
- }
- if (g_xfrxla > -1) {
- xfrxla = g_xfrxla;
- g_xfrxla = -1;
- }
- setxlatype(tcharset,fcharset); /* Translation type */
-#endif /* NOCSETS */
-
-#ifdef NETCONN
-#ifndef NOSPL
- if (g_pswd) {
- ckstrncpy(pwbuf,g_pswd,PWBUFL);
- makestr(&g_pswd,NULL);
- }
- if (g_pflg > -1) {
- pwflg = g_pflg;
- g_pflg = -1;
- }
- if (g_pcpt > -1) {
- pwcrypt = g_pcpt;
- g_pcpt = -1;
- }
-#endif /* NOSPL */
-#endif /* NETCONN */
-
- if (g_binary > -1) { /* File type */
- binary = g_binary;
- g_binary = -1;
- }
- if (g_xfermode > -1) { /* Transfer mode */
- xfermode = g_xfermode;
- g_xfermode = -1;
- }
-#ifdef PATTERNS
- if (g_patterns > -1) { /* Filename patterns */
- patterns = g_patterns;
- g_patterns = -1;
- }
-#endif /* PATTERNS */
-
- if (g_usepipes > -1) {
- usepipes = g_usepipes;
- g_usepipes = -1;
- }
- if (g_matchdot > -1) {
- matchdot = g_matchdot;
- g_matchdot = -1;
- }
- if (g_proto > -1) { /* Protocol */
- protocol = g_proto;
- g_proto = -1;
- }
- if (g_urpsiz > -1) {
- urpsiz = g_urpsiz;
- debug(F101,"ftreset restoring urpsiz","",urpsiz);
- g_urpsiz = -1;
- }
- if (g_spsizf > -1) {
- spsizf = g_spsizf;
- debug(F101,"ftreset restoring spsizf","",spsizf);
- g_spsizf = -1;
- }
- if (g_spsiz > -1) {
- spsiz = g_spsiz;
- debug(F101,"ftreset restoring spsiz","",spsiz);
- g_spsiz = -1;
- }
- if (g_spsizr > -1) {
- spsizr = g_spsizr;
- debug(F101,"ftreset restoring spsizr","",spsizr);
- g_spsizr = -1;
- }
- if (g_spmax > -1) {
- spmax = g_spmax;
- g_spmax = -1;
- }
- if (g_wslotr > -1) {
- wslotr = g_wslotr;
- g_wslotr = -1;
- }
- if (g_prefixing > -1) {
- prefixing = g_prefixing;
- g_prefixing = -1;
- }
- if (g_fncact > -1) {
- fncact = g_fncact;
- g_fncact = -1;
- }
- if (g_fncnv > -1) {
- fncnv = g_fncnv;
- g_fncnv = -1;
- }
- if (g_fnspath > -1) {
- fnspath = g_fnspath;
- g_fnspath = -1;
- }
- if (g_fnrpath > -1) {
- fnrpath = g_fnrpath;
- g_fnrpath = -1;
- }
- if (g_skipbup > -1) {
- skipbup = g_skipbup;
- g_skipbup = -1;
- }
- nolinks = 2; /* /FOLLOWLINKS is never global */
- recursive = 0; /* /RECURSIVE can never be global */
- xfiletype = -1;
-
- if (g_displa > -1) { /* File transfer display */
- fdispla = g_displa;
- g_displa = -1;
- }
- if (g_spath > -1) { /* Send pathnames */
- fnspath = g_spath;
- g_spath = -1;
- }
- if (g_rpath > -1) { /* Receive pathnames */
- fnrpath = g_rpath;
- g_rpath = -1;
- }
- if (g_fncnv > -1) { /* Filename conversion */
- fncnv = g_fncnv;
- g_fncnv = -1;
- }
-#ifdef PIPESEND
- makestr(&sndfilter,g_sfilter); /* Send filter */
- makestr(&rcvfilter,g_rfilter); /* Receive filter */
-#endif /* PIPESEND */
-
-#ifndef NOFRILLS
- rmailf = rprintf = 0; /* MAIL and PRINT modifiers for SEND */
- optbuf[0] = NUL; /* MAIL and PRINT options */
-#endif /* NOFRILLS */
-
- moving = 0; /* Reset delete-after-send indicator */
- sndafter[0] = NUL; /* Reset SEND selection switches */
- sndbefore[0] = NUL;
-
- for (i = 0; i < NSNDEXCEPT; i++) {
- if (sndexcept[i])
- free(sndexcept[i]);
- sndexcept[i] = NULL;
- if (rcvexcept[i])
- free(rcvexcept[i]);
- rcvexcept[i] = NULL;
- }
- sndlarger = (CK_OFF_T)-1;
- sndsmaller = (CK_OFF_T)-1;
- debug(F101,"present sndsmaller","",sndsmaller);
-#ifdef GFTIMER
- gtv = -1.0;
- oldgtv = -1.0;
-#else
- gtv = -1L;
- oldgtv = -1L;
-#endif /* GFTIMER */
-#endif /* NOICP */
-}
-#endif /* NOXFER */
-
-char *
-ttgtpn() { /* Get typical port name */
-/*
- Ideally this routine would be implemented in each of the cku?io.* modules,
- but that requires changing the API definition.
-*/
- return(
-#ifdef OS2
-#ifdef OS2ONLY
-"COM1"
-#else /* OS2ONLY */
-"TAPI [ name ] or COM1"
-#endif /* OS2ONLY */
-#else /* OS2 */
-#ifdef VMS
-"TXA0:, TTA0:, or LTA0:"
-#else /* VMS */
-#ifdef SOLARIS
-"/dev/cua/a"
-#else /* SOLARIS */
-#ifdef HPUX10
-"/dev/cua0p0"
-#else /* HPUX10 */
-#ifdef HPUX
-"/dev/cua00"
-#else /* HPUX */
-#ifdef __FreeBSD__
-"/dev/cuaa0"
-#else /* __FreeBSD__ */
-#ifdef __linux__
-"/dev/ttyS0"
-#else /* __linux__ */
-#ifdef BSD44
-"/dev/tty00"
-#else /* BSD44 */
-#ifdef OSK
-"/t1"
-#else /* OSK */
-#ifdef QNX
-"/dev/ser1"
-#else /* QNX */
-#ifdef QNX6
-"/dev/ser1"
-#else /* QNX6 */
-#ifdef UNIXWARE
-"/dev/term/00 or /dev/tty00"
-#else /* UNIXWARE */
-#ifdef CK_SCOV5
-"/dev/tty1A"
-#else /* CK_SCOV5 */
-#ifdef CK_SCO32V4
-"/dev/tty1A"
-#else /* CK_SCO32V4 */
-#ifdef M_XENIX
-"/dev/tty1A"
-#else /* M_XENIX */
-#ifdef AIXRS
-"/dev/tty0"
-#else /* AIXRS */
-#ifdef DGUX
-"/dev/tty00"
-#else /* DGUX */
-#ifdef datageneral
-"@con1"
-#else /* datageneral */
-#ifdef IRIX
-"/dev/ttym0"
-#else /* IRIX */
-#ifdef SUNOS4
-"/dev/ttyh0"
-#else /* SUNOS4 */
-#ifdef SV68R3V6
-"/dev/scc0"
-#else /* SV68R3V6 */
-#ifdef MOTSV88R4
-"/dev/contty00"
-#else /* MOTSV88R4 */
-#ifdef NEXT
-"/dev/cufa"
-#else
-#ifdef OSF
-"/dev/ttyd1"
-#else
-#ifdef SINIX
-"/dev/ttyc1"
-#else
-#ifdef UNIX
-"/dev/cua, /dev/acu, /dev/tty0, etc"
-#else /* UNIX */
-"(sorry no example available)"
-#endif /* UNIX */
-#endif /* SINIX */
-#endif /* OSF */
-#endif /* NEXT */
-#endif /* MOTSV88R4 */
-#endif /* SV68R3V6 */
-#endif /* SUNOS4 */
-#endif /* IRIX */
-#endif /* datageneral */
-#endif /* DGUX */
-#endif /* AIX */
-#endif /* M_XENIX */
-#endif /* CK_SCO32V4 */
-#endif /* CK_SCOV5 */
-#endif /* UNIXWARE */
-#endif /* QNX6 */
-#endif /* QNX */
-#endif /* OSK */
-#endif /* BSD44 */
-#endif /* __linux__ */
-#endif /* __FreeBSD__ */
-#endif /* HPUX */
-#endif /* HPUX10 */
-#endif /* SOLARIS */
-#endif /* VMS */
-#endif /* OS2 */
- );
-}
-
-/* C K _ E R R S T R -- Return message from most recent system error */
-
-#ifdef CKROOT
-extern int ckrooterr;
-#endif /* CKROOT */
-
-char *
-ck_errstr() {
-#ifdef USE_STRERROR
-#ifndef CK_ANSILIBS
- /* Should have been declared in <string.h> */
-_PROTOTYP( char * strerror, (int) );
-#endif /* CK_ANSILIBS */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
-#endif /* CKROOT */
- return(strerror(errno));
-#else /* !USE_STRERROR */
-#ifdef VMS
- extern char * ckvmserrstr(unsigned long);
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
-#endif /* CKROOT */
- return(ckvmserrstr(0L));
-#else /* !VMS */
-#ifdef BSD44
-#ifdef __386BSD__
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#else /* !__386BSD__ */
-#ifndef __bsdi__
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern const char *const sys_errlist[];
-#endif /* NDSYSERRLIST */
-#endif /* __bsdi__ */
-#endif /* __386BSD__ */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
- else
-#endif /* CKROOT */
- if (errno >= sys_nerr)
- return("Error number out of range");
- else
- return((char *) sys_errlist[errno]);
-#else /* !BSD44 */
-#ifdef ATTSV
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
- else
-#endif /* CKROOT */
- if (errno >= sys_nerr)
- return("Error number out of range");
- else
- return((char *) sys_errlist[errno]);
-#else /* !ATTSV */
-#ifdef BSD4
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
- else
-#endif /* CKROOT */
- if (errno >= sys_nerr)
- return("Error number out of range");
- else
- return((char *) sys_errlist[errno]);
-#else
-#ifdef OS2
-#ifndef NDSYSERRLIST
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#ifdef NT
- extern int_sys_nerr;
-#endif /* NT */
- char *e;
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
-#endif /* CKROOT */
- e = (errno > -1
-#ifdef NT
- && errno <= _sys_nerr
-#endif /* NT */
- ) ?
-#ifdef NT
- (char *) sys_errlist[errno]
-#else /* NT */
- /* I don't know how to get a CLIB error string in OS/2 */
- strerror(errno)
-#endif /* NT */
- : "";
- return(e ? e : "");
-#else /* OS2 */
- return("");
-#endif /* OS2 */
-#endif /* BSD4 */
-#endif /* ATTSV */
-#endif /* BSD44 */
-#endif /* VMS */
-#endif /* USE_STRERROR */
-}
-
-#ifdef PATTERNS
-/*
- Filename pattern recognition lists for automatic text/binary switching.
- These are somewhat passe after the addition of scanfile() (7.0).
- But with the addition of FTP [M]GET, they're back in style (8.0).
-
- Although, with FTP the lists need to be used in the reverse. With
- Kermit the list is used to imply the types of the local system. Whereas
- with FTP, the list must be used to imply the type of the remote system.
- Therefore, all platforms must now support all of the lists.
-*/
-char *txtpatterns[FTPATTERNS+1] = { NULL, NULL };
-char *binpatterns[FTPATTERNS+1] = { NULL, NULL };
-/*
- Default pattern lists for each platform...
-
- NOTE: In most cases we leave ".hlp", ".ini", and ".scr" alone; although they
- are traditionally text types, they are binary in Windows. So they are
- handled by the prevailing SET FILE TYPE, rather than automatically.
- Similarly for ".dat", ".inf", and so on. Also ".ps" since PostScript files
- are not always text. ".log" is omitted since logs can be text or binary,
- except in VMS they are usually text, etc etc.
-
- Later (Sep 2003): Add PostScript to binary patterns.
-*/
-static char *txtp[SYS_MAX][FTPATTERNS] = {
- /* UNKNOWN */ {
- NULL, NULL
- },
- { /* UNIX */
- "*.txt","*.c","*.h","*.r","*.w","*.cpp","*.cc","*.ksc","*.bwr","*.upd",
- "*.html","*.htm","*.mss","*.tex","*.nr","[Mm]akefile", "*.hex", "*.hqx",
- "*.for","*.f77","*.f","*.F","*.s","*.pas","*.java","*.el","*.lisp","*.sh",
- "*.m4","*.perl","*.pl","*.pod","*.pm","*.awk","*.sno","*.spt","*.sed",
- "*.ksc","*.TXT", "*read.me", "*READ.ME", ".*", "*/.*", "*.mem","*.mac",
- NULL
- },
- { /* WIN32 */
- "*.txt","*.ksc","*.htm","*.html","*.bat","*.cmd","*.jav","*.asm", "*.hex",
- "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w",
- "*.java", "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile",
- "*.mem","*.mac","*.cc","*.pl","*.pod","*.pm","*.m4",NULL
- },
- { /* VMS */
- "*.com","*.txt","*.c", "*.for","*.pas","*.rno","*.rnh","*.mar","*.bli",
- "*.hlp","*.mss","*.doc","*.bwr","*.cld","*.hex","*.bas","*.ini","*.log",
- "*.mms","*.opt","*.ksc","*.perl","*.pl","*.pod","*.pm","*.sno","*.spt",
- "*.mem",NULL
- },
- { /* OS2 */
- "*.txt","*.ksc","*.htm","*.html","*.bat","*.cmd","*.jav","*.asm", "*.hex",
- "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w",
- "*.java", "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile",
- NULL
- },
- { /* DOS */
- "*.txt","*.ksc","*.htm","*.bat","*.cmd","*.jav","*.asm", "*.hex",
- "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w",
- "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile", NULL
- },
- { /* TOPS-10 */
- "*.cmd","*.hlp","*.doc","*.ini","*.txt","*.mac","*.for","*.sai","*.bli",
- "*.pas","*.sno","*.spt","*.pcl","*.mss","*.rno","*.b36","*.tex","*.pub",
- "*.req","*.r36","*.mem","*.bwr","*.ccl","*.ctl","*.rnh","*.ksc",NULL
- },
- { /* TOPS-20 */
- "*.cmd","*.hlp","*.doc","*.ini","*.txt","*.mac","*.for","*.sai","*.bli",
- "*.pas","*.sno","*.spt","*.pcl","*.mss","*.rno","*.b36","*.tex","*.pub",
- "*.req","*.r36","*.mem","*.bwr","*.ccl","*.ctl","*.rnh","*.ksc",NULL
- },
- { /* STRATUS VOS */
- "*.txt","*.ksc","*.htm","*.html","*.bat", "*.cmd","*.jav","*.asm","*.hex",
- "*.hqx","*.c", "*.h", "*.w", "*.java","*.bwr","*.upd","*.ttp","*.cm",
- "*.pl1","*.emacs", "read.me", "*.pl", "makefile", NULL
- },
- { /* DG AOS/VS */
- "*.txt", "*.c", "*.h", "*.w", "*.er", "*.bwr", "*.upd", "read.me",
- "*.cli", "*.ksc", NULL
- },
- { /* OSK */
- "*.c","*.cpp","*.h","*.a","*akefile", /* program sources */
- "*.for","*.f77","*.f","*.F","*.s","*.pas","*.java","*.el","*.lisp",
- "*.sh","*.perl","*.awk","*.sno","*.spt","*.sed",
- "*.txt","*.w", /* general text */
- "*.ksc","*.bwr","*.upd",
- "*.html","*.htm","*.mss","*.tex","*.nr","*.hex", "*.hqx",
- "*.TXT", "*read.me", "*READ.ME", ".*", "*/.*",
- NULL
- }
-};
-
-/* Note: .DOC added to (some) binary patterns June 1998... Microsoft wins. */
-
-static char *binp[SYS_MAX][FTPATTERNS] = {
- { /* UNKNOWN */
- NULL, NULL
- },
- { /* UNIX */
- "*.gz","*.Z","*.tgz","*.gif", "*.tar","*.zip","*.o","*.so","*.a","*.out",
- "*.exe", "*.jpg", "*.jpeg", "*.tif","*.tiff", "*.pdf", "*.so.*", "*.class",
- "*.rpm", "*.bmp", "*.bz2", "*.BMP", "*.dll", "*.doc", "*.vxd", "*.dcx",
- "*.xl*", "*.lzh", "*.lhz", "*.au", "*.voc", "*.mpg", "*.mpeg","[wk]ermit",
- "*.ps", NULL
- },
- { /* WIN32 */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.class","*.cla","*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.lzh", "*.vxd", "*.snd", "*.au", "* .voc", "*.mpg", "*.mpeg",
- "*.ps", NULL
- },
- { /* VMS */
- "*.exe","*.obj","*.bak","*.bin","*.adf","*.stb","*.mai","*.sys","*.dmp",
- "*.ps", "*.dat","*.par", NULL
- },
- { /* OS2 */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.class", "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.ps", "*.lzh", NULL
- },
- { /* DOS */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.ps", "*.lzh", NULL
- },
- { /* TOPS10 */
- "*.exe","*.sav","*.bin","*.rim","*.rel","*.unv","*.lib","*.tap","*.dvi",
- "*.ps", NULL
- },
- { /* TOPS20 */
- "*.exe","*.sav","*.bin","*.rim","*.rel","*.unv","*.lib","*.tap","*.dvi",
- "*.ps", NULL
- },
- { /* STRATUS VOS */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.class", "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.ps", "*.lzh", "*.pm", NULL
- },
- { /* DG */
- "*.ob", "*.pr", "*.dmp", "*.ps", NULL
- },
- { /* OSK */
- "*.gz","*.Z","*.z","*.tgz","*.lhz","*.tar", /* archivers */
- "*.zip","*.ar","*.zoo","*.rpm","*.lzh",
- /* object files, libraries, executables */
- "*.r","*.l","*.exe", "*.dll", "*.so.*", "*.class",
- /* images */
- "*.gif", "*.jpg", "*.jpeg", "*.tif","*.tiff", "*.pdf", "*.ps",
- "*.bmp", "*.bz2", "*.BMP","*.pcx",
- NULL
- }
-};
-
-/*
- Set up default pattern lists so they can be freed and re-malloc'd.
- Each pattern list must terminated by a null element.
-*/
-VOID
-initpat() {
- int i;
- for (i = 0; i < FTPATTERNS; i++) {
- txtpatterns[i] = NULL;
- binpatterns[i] = NULL;
- }
- for (i = 0; i < FTPATTERNS; i++) {
-#ifdef UNIX
- makestr(&(txtpatterns[i]),txtp[SYS_UNIX][i]);
-#else /* UNIX */
-#ifdef OS2
-#ifdef NT
- makestr(&(txtpatterns[i]),txtp[SYS_WIN32][i]);
-#else /* NT */
- makestr(&(txtpatterns[i]),txtp[SYS_OS2][i]);
-#endif /* NT */
-#else /* OS2 */
-#ifdef VMS
- makestr(&(txtpatterns[i]),txtp[SYS_VMS][i]);
-#else /* VMS */
-#ifdef STRATUS
- makestr(&(txtpatterns[i]),txtp[SYS_VOS][i]);
-#else /* STRATUS */
-#ifdef datageneral
- makestr(&(txtpatterns[i]),txtp[SYS_DG][i]);
-#else /* datageneral */
-#ifdef OSK
- makestr(&(txtpatterns[i]),txtp[SYS_OSK][i]);
-#else /* OSK */
- makestr(&(txtpatterns[i]),txtp[SYS_UNK][i]);
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIX */
- if (!txtp[i])
- break;
- }
- for (i = 0; i < FTPATTERNS; i++) {
-#ifdef UNIX
- makestr(&(binpatterns[i]),binp[SYS_UNIX][i]);
-#else /* UNIX */
-#ifdef OS2
-#ifdef NT
- makestr(&(binpatterns[i]),binp[SYS_WIN32][i]);
-#else /* NT */
- makestr(&(binpatterns[i]),binp[SYS_OS2][i]);
-#endif /* NT */
-#else /* OS2 */
-#ifdef VMS
- makestr(&(binpatterns[i]),binp[SYS_VMS][i]);
-#else /* VMS */
-#ifdef STRATUS
- makestr(&(binpatterns[i]),binp[SYS_VOS][i]);
-#else /* STRATUS */
-#ifdef datageneral
- makestr(&(binpatterns[i]),binp[SYS_DG][i]);
-#else /* datageneral */
-#ifdef OSK
- makestr(&(binpatterns[i]),binp[SYS_OSK][i]);
-#else /* OSK */
- makestr(&(binpatterns[i]),binp[SYS_UNK][i]);
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIX */
- if (!binp[i])
- break;
- }
-}
-
-/*
- m a t c h n a m e -- Compare filename with text & binary name patterns.
-
- Returns:
- 0 if name matches a text pattern but not a binary pattern.
- 1 if name matches a binary pattern but not a text pattern.
- -1 if name matches no patterns.
- -2 if name matches a binary pattern and a text pattern.
-*/
-int
-matchname(filename, local, os) char * filename; int local; int os; {
- int rc = -1; /* Return code */
- char * name, * p;
-#ifdef OS2ORUNIX
- char tmpbuf[CKMAXPATH+1];
-#endif /* OS2ORUNIX */
-
- name = filename ? filename : ""; /* Copy of original arg */
- if (patterns && *name) { /* If PATTERNS ON... */
- int i;
-
-#ifdef OS2ORUNIX
- if (ckmatch("*.~[1-9]*~",name,1,1)) { /* Name has backup suffix? */
- int k;
- k = ckstrncpy(tmpbuf,name,CKMAXPATH+1); /* Yes, copy and strip */
- for (i = k - 3; i > 4; i--) {
- if (tmpbuf[i] == '~' && tmpbuf[i-1] == '.') {
- tmpbuf[i-1] = NUL;
- break;
- }
- }
- name = tmpbuf; /* And point to stripped copy */
- }
-#endif /* OS2ORUNIX */
- zstrip(name,&p); /* Strip pathname too */
- name = p;
-
- if (local) {
- if (txtpatterns[0]) { /* Search text patterns */
- for (i = 0; i < FTPATTERNS && txtpatterns[i]; i++) {
- if (ckmatch(txtpatterns[i],name,filecase,1)) {
- rc = 0;
- break;
- }
- }
- }
- if (binpatterns[0]) { /* And search binary patterns */
- for (i = 0; i < FTPATTERNS && binpatterns[i]; i++) {
- if (ckmatch(binpatterns[i],name,filecase,1)) {
- rc = (rc > -1) ? -2 : 1;
- break;
- }
- }
- }
- } else {
- if (os >= 0 && os < SYS_MAX) {
- if (txtp[os][0]) {
- for (i = 0; i < FTPATTERNS && txtp[os][i]; i++) {
- if (ckmatch(txtp[os][i],name,filecase,1)) {
- rc = 0;
- break;
- }
- }
- }
- if (binp[os][0]) {
- for (i = 0; i < FTPATTERNS && binp[os][i]; i++) {
- if (ckmatch(binp[os][i],name,filecase,1)) {
- rc = (rc > -1) ? -2 : 1;
- break;
- }
- }
- }
- }
- }
- }
- debug(F111,"matchname",name,rc);
- return(rc);
-}
-#endif /* PATTERNS */
-
-#ifdef UNICODE
-#ifndef NOEVENMAX
-#define EVENMAX
-#endif /* NOEVENMAX */
-#endif /* UNICODE */
-
-/* S C A N F I L E -- Analyze a file's contents */
-
-/*
- Call with:
- name: Pointer to name of existing file.
- flag: Pointer to int in which to return additional numeric data.
-
- Returns:
- -1 on failure (to open file or to read from it).
- Integer, 0..4, on success indicating file type:
- 0 = 7-bit text (flag = -1)
- 1 = UTF-8 text (flag = -1)
- 2 = UCS-2 text (flag = 0: big-endian; flag = 1: little-endian)
- 3 = 8-bit text (flag = 0: no C1 bytes; flag = 1: includes C1 bytes)
- 4 = Text (type unknown)
- 5 = binary (flag = -1)
-
- If UNICODE is defined:
-
- 1. If file begins with a valid BOM, it is believed. Otherwise we
- read the first 4K of the file (since it might be email with verbose
- headers) and analyze it:
-
- 2. If file contains only valid UTF-8 sequences, we call it UTF-8;
- otherwise:
-
- 3. If the file contains lots of alternate 0 bytes, we call it UCS-2, and
- set the polarity according to whether the preponderance of them are in
- even or odd positions; otherwise:
-
- 4. If EVENMAX is defined and the file contains lots of alternate bytes that
- are identical, even if they aren't zero, and the number of such bytes
- is at least four times the length of the maximum run of alternating
- identical bytes of the opposite polarity, we call it UCS-2; otherwise:
-
- 5. If the file contained no bytes with their 8th bits on and no controls
- other than CR, LF, HT, and FF, we call it ASCII; otherwise:
-
- 6. If it contains C0 control characters other than CR, LF, HT, and FF, we
- call it binary; otherwise:
-
- 7. We call it 8-bit text, character set unknown (could be Latin-1 or
- anything else).
-
- Note that malformed UTF-8 is not diagnosed as UTF-8.
-
- If UNICODE is not defined:
-
- 1. If the file contains C0 control characters other than CR, LF, HT, and
- FF, we call it binary; otherwise:
-
- 2. If the file contains any 8-bit bytes, we call it 8-bit text; otherwise:
-
- 3. We call it 7-bit text.
-
- In the non-Unicode case, UCS-2 is diagnosed as binary, but UTF-8 as
- 8-bit text.
-
- There is no significant speed difference between the Unicode and
- non-Unicode cases.
-*/
-int
-scanfile(name,flag,nscanfile) char * name; int * flag, nscanfile; {
- FILE * fp; /* File pointer */
- unsigned char buf[SCANFILEBUF]; /* File data buffer for analysis */
- int x, val = -1, count = 0; /* Workers */
- int rc = -1; /* Return code */
- int pv = -1; /* Pattern-match value */
- int eof = 0; /* Flag for file EOF encountered */
- int bytes = 0; /* Total byte count */
-#ifdef UNICODE
- unsigned int c0, c1; /* First 2 file bytes (for BOM) */
-#endif /* UNICODE */
- extern int pipesend, filepeek;
-
- register int i; /* Loop control */
- int readsize = 0; /* How much to read */
- int eightbit = 0; /* Number of bytes with 8th bit on */
- int c0controls = 0; /* C0 non-text control-char counter */
- int c0noniso = 0; /* C0 non-ISO control-char counter */
- int c1controls = 0; /* C1 control-character counter */
- unsigned int c; /* Current character */
- int runmax = 0; /* Longest run of 0 bytes */
- int runzero = 0; /* Run of 0 bytes */
- int pctzero = 0; /* Percentage of 0 bytes */
- int txtcz = 0;
-#ifdef CK_CTRLZ
- extern int eofmethod;
-#endif /* CK_CTRLZ */
-
-#ifdef UNICODE
- int notutf8 = 0; /* Nonzero if definitely not UTF-8 */
- int utf8state = 0; /* UTF-8 recognizer state */
- int oddzero = 0; /* Number of 0 bytes in odd postions */
- int evenzero = 0; /* and in even positions */
- int lfnul = 0; /* Number of <LF><NUL> sequences */
- int crlf = 0; /* Number of <CRLF> sequences */
-#else
- int notutf8 = 1;
-#endif /* UNICODE */
-
-#ifdef COMMENT
-#ifdef EVENMAX
- int oddrun = 0, oddmax = 0, oddbyte = 0, oddmaxbyte = 0;
- int evenrun = 0, evenmax = 0, evenbyte = 0, evenmaxbyte = 0;
-#endif /* EVENMAX */
-#endif /* COMMENT */
-
-#ifndef NOXFER
- if (pipesend || calibrate || sndarray) /* Only for real files */
- return(-1);
-#endif /* NOXFER */
- debug(F111,"scanfile",name,nscanfile);
-#ifdef PATTERNS
- if (!filepeek) {
- pv = matchname(name,1,-1);
- if (pv < 0)
- rc = -1;
- else
- rc = (pv == 1) ? FT_BIN : FT_TEXT;
- debug(F111,"scanfile !filepeek result",name,rc);
- return(rc);
- }
-#endif /* PATTERNS */
-
-#ifdef VMS
-/* We don't scan in VMS where text files have various record formats in */
-/* which record headers contain seemingly non-text bytes. So the best */
-/* we can do in VMS is tell whether the file is text or binary, period. */
- {
- int b, x;
- b = binary; /* Save current binary setting */
- if (zopeni(ZIFILE,name) > 0) { /* In VMS this sets binary */
- x = binary; /* Get result */
- zclose(ZIFILE); /* Close the file */
- binary = b; /* Restore previous binary setting */
- rc = x ? FT_BIN : FT_TEXT;
- val = 0;
- goto xscanfile;
- }
- }
-#endif /* VMS */
-
- eof = 0; /* End-of-file reached indicator */
-#ifdef OS2
- fp = fopen(name, "rb"); /* Open the file in binary mode */
-#else
- fp = fopen(name, "r");
-#endif /* OS2 */
-
- if (!fp) /* Failed? */
- return(-1);
-
- while (1) { /* One or more gulps from file */
- if (eof) { /* EOF from last time? */
- debug(F111,"scanfile at EOF",name,bytes);
- if (runzero > runmax)
- runmax = runzero;
- break;
- }
- if (nscanfile < 0) { /* Reading whole file */
- readsize = SCANFILEBUF;
- } else { /* Reading first nscanfilee bytes */
- readsize = nscanfile - bytes;
- if (readsize < 1)
- break;
- if (readsize > SCANFILEBUF)
- readsize = SCANFILEBUF;
- }
- debug(F101,"scanfile readsize","",readsize);
- count = fread(buf,1,readsize,fp); /* Read a buffer */
- if (count == EOF || count == 0) {
- debug(F111,"scanfile EOF",name,count);
- break;
- }
- debug(F111,"scanfile buffer ok",name,count);
-
- if (bytes == 0 && count > 8) {
- /* PDF files can look like text in the beginning. */
- if (!ckstrcmp((char *)buf,"%PDF-1.",7,1)) {
- if (isdigit(buf[7])) {
- if (buf[8] == '\015' ||
- count > 9 && buf[8] == SP && buf[9] == '\015') {
-#ifdef DEBUG
- buf[8] = NUL;
- debug(F110,"scanfile PDF",buf,0);
-#endif /* DEBUG */
- binary = 1; /* But they are binary. */
- break;
- }
- }
- } else if (!ckstrcmp((char *)buf,"%!PS-Ado",8,1)) {
- /* Ditto for PostScript */
-#ifdef DEBUG
- int i;
- for (i = 8; i < count; i++) {
- if (buf[i] < '!') {
- buf[i] = NUL;
- break;
- }
- }
- debug(F110,"scanfile PostScript",buf,0);
-#endif /* DEBUG */
- binary = 1;
- break;
-#ifndef NOPCLSCAN
- } else if (!ckstrcmp((char *)buf,") HP-PCL",8,1)) {
- /* HP PCL printer language */
-#ifdef DEBUG
- int i;
- for (i = 8; i < count; i++) {
- if (buf[i] < '!') {
- buf[i] = NUL;
- break;
- }
- }
- debug(F110,"scanfile PCL",buf,0);
-#endif /* DEBUG */
- binary = 1;
- break;
- }
-#endif /* NOPCLSCAN */
-#ifndef NOPJLSCAN
- else if (buf[0] == '\033' && (buf[1] == 'E' || buf[1] == '%')) {
- /* Ditto for PJL Job printer header */
-#ifdef DEBUG
- int i;
- for (i = 2; i < count; i++) {
- if (buf[i] < '!') {
- buf[i] = NUL;
- break;
- }
- }
- debug(F110,"scanfile PJL Job printer header",buf,0);
-#endif /* DEBUG */
- binary = 1;
- break;
-#endif /* NOPJLSCAN */
- }
- }
-
-#ifdef UNICODE
- if (bytes == 0 && count > 1) {
- int incl_cnt = 0;
-
- /* First look for BOM */
-
- c0 = (unsigned)((unsigned)buf[0]&0xFF); /* First file byte */
- c1 = (unsigned)((unsigned)buf[1]&0xFF); /* Second byte */
-
- if (c0 == 0xFE && c1 == 0xFF) { /* UCS-2 BE */
- rc = FT_UCS2;
- val = 0;
- debug(F111,"scanfile UCS2 BOM BE",ckitoa(val),rc);
- incl_cnt++;
- } else if (c0 == 0xFF && c1 == 0xFE) { /* UCS-2 LE */
- rc = FT_UCS2;
- val = 1;
- debug(F111,"scanfile UCS2 BOM LE",ckitoa(val),rc);
- incl_cnt++;
- } else if (count > 2) if (c0 == 0xEF && c1 == 0xBB &&
- (unsigned)((unsigned)buf[2]&0xFF) == 0xBF) {
- rc = FT_UTF8;
- debug(F111,"scanfile UTF8 BOM",ckitoa(val),rc);
- incl_cnt++;
- }
- if (incl_cnt) { /* Have BOM */
- bytes += count;
- goto xscanfile;
- }
- }
-#endif /* UNICODE */
-
- bytes += count; /* Count bytes read */
- eof = feof(fp); /* Flag for at EOF */
-
- for (i = 0; i < count; i++) { /* For each byte... */
- c = (unsigned)buf[i]; /* For ease of reference */
- if (!c) { /* Zero byte? */
-#ifdef EVENMAX
- if (i&1) /* In odd position */
- oddzero++;
- else
- evenzero++; /* In even position */
-#endif /* EVENMAX */
- runzero++;
- } else { /* Not a zero byte */
- if (runzero > runmax)
- runmax = runzero;
- if (runmax > 2) /* That's all we need to be certain */
- break; /* it's a binary file. */
- runzero = 0;
- }
-
-#ifdef COMMENT
-#ifdef EVENMAX
-
-/* This is to catch UCS-2 with a non-ASCII, non-Latin-1 repertoire */
-
- if (i > 1) { /* Look for runs of alternating chars */
- if (i&1) {
- if (c == buf[i-2]) { /* In odd positions */
- oddrun++;
- oddbyte = c;
- } else {
- oddmax = oddrun;
- oddmaxbyte = oddbyte;
- }
- } else { /* and even positions */
- if (c == buf[i-2]) {
- evenrun++;
- evenbyte = c;
- } else {
- evenmax = evenrun;
- evenmaxbyte = evenbyte;
- }
- }
- }
-#endif /* EVENMAX */
-#endif /* COMMENT */
-
- if ((c & 0x80) == 0) { /* We have a 7-bit byte */
-#ifdef UNICODE
- if (i > 0 && c == 10) { /* Linefeed */
- if (buf[i-1] == 0) lfnul++; /* Preceded by NUL */
- else if (buf[i-1] == 13) crlf++; /* or by CR... */
- }
-#endif /* UNICODE */
- if (c < ' ') { /* Check for CO controls */
- if (c != LF && c != CR && c != HT && c != FF) {
- c0controls++;
- if (c != ESC && c != SO && c != SI)
- c0noniso++;
- }
- if ((c == '\032') /* Ctrl-Z */
-#ifdef COMMENT
- && eof && (i >= count - 2)
-#endif /* COMMENT */
- ) {
- c0controls--;
- c0noniso--;
-#ifdef CK_CTRLZ
- if (eofmethod == XYEOF_Z && txtcz == 0) {
- if (c0controls == 0) /* All text prior to Ctrl-Z */
- txtcz = 1;
- }
-#endif /* CK_CTRLZ */
- }
- }
-#ifdef UNICODE
- if (!notutf8 && utf8state) { /* In UTF-8 sequence? */
- utf8state = 0;
- debug(F000,"scanfile","7-bit byte in UTF8 sequence",c);
- notutf8++; /* Then it's not UTF-8 */
- continue;
- }
-#endif /* UNICODE */
- } else { /* We have an 8-bit byte */
- eightbit++; /* Count it */
- if (c >= 0x80 && c < 0xA0) /* Check for C1 controls */
- c1controls++;
-#ifdef UNICODE
- if (!notutf8) { /* If it might still be UTF8... */
- switch (utf8state) { /* Enter the UTF-8 state machine */
- case 0: /* First byte... */
- if ((c & 0xE0) == 0xC0) { /* Tells number of */
- utf8state = 1; /* subsequent bytes */
- } else if ((c & 0xF0) == 0xE0) {
- utf8state = 2;
- } else if ((c & 0xF8) == 0xF0) {
- utf8state = 3;
- } else {
- notutf8++;
- }
- break;
- case 1: /* Subsequent byte */
- case 2:
- case 3:
- if ((c & 0xC0) != 0x80) { /* Must start with 10 */
- debug(F000,"scanfile",
- "bad byte in UTF8 sequence",c);
- notutf8++;
- break;
- }
- utf8state--; /* Good, one less in this sequence */
- break;
- default: /* Shouldn't happen */
- debug(F111,"scanfile","bad UTF8 state",utf8state);
- notutf8++;
- }
- }
-#endif /* UNICODE */
- }
- }
- }
- fclose(fp); /* Close the file */
- debug(F101,"scanfile bytes","",bytes);
-
- if (bytes == 0) /* If nothing was read */
- return(-1); /* we're done. */
-
-#ifdef EVENMAX
- /* In case we had a run that never broke... */
-#ifdef COMMENT
- if (oddmax == 0) {
- oddmax = oddrun;
- oddmaxbyte = oddbyte;
- }
- if (evenmax == 0) {
- evenmax = evenrun;
- evenmaxbyte = evenbyte;
- }
-#endif /* COMMENT */
- if (runmax == 0) {
- runmax = runzero;
- }
-#endif /* EVENMAX */
-
-#ifdef UNICODE
- if (bytes > 100) /* Bytes is not 0 */
- pctzero = (evenzero + oddzero) / (bytes / 100);
- else
- pctzero = ((evenzero + oddzero) * 100) / bytes;
-#endif /* UNICODE */
-
-#ifdef DEBUG
- if (deblog) { /* If debugging, dump statistics */
- debug(F101,"scanfile c0controls ","",c0controls);
- debug(F101,"scanfile c0noniso ","",c0noniso);
- debug(F101,"scanfile c1controls ","",c1controls);
- debug(F101,"scanfile eightbit ","",eightbit);
-#ifdef UNICODE
- debug(F101,"scanfile crlf ","",crlf);
- debug(F101,"scanfile lfnul ","",lfnul);
- debug(F101,"scanfile notutf8 ","",notutf8);
- debug(F101,"scanfile evenzero ","",evenzero);
- debug(F101,"scanfile oddzero ","",oddzero);
- debug(F101,"scanfile even/odd ","",(evenzero / (oddzero + 1)));
- debug(F101,"scanfile odd/even ","",(oddzero / (evenzero + 1)));
- debug(F101,"scanfile pctzero ","",pctzero);
-#endif /* UNICODE */
-#ifdef COMMENT
-#ifdef EVENMAX
- debug(F101,"scanfile oddmax ","",oddmax);
- debug(F101,"scanfile oddmaxbyte ","",oddmaxbyte);
- debug(F101,"scanfile evenmax ","",evenmax);
- debug(F101,"scanfile evenmaxbyte","",evenmaxbyte);
-#endif /* EVENMAX */
-#endif /* COMMENT */
- debug(F101,"scanfile runmax ","",runmax);
- }
-#endif /* DEBUG */
-
-#ifdef UNICODE
- x = eightbit ? bytes / 20 : bytes / 4; /* For UCS-2... */
-
- if (runmax > 2) { /* File has run of more than 2 NULs */
- debug(F100,"scanfile BIN runmax","",0);
- rc = FT_BIN; /* so it can't be any kind of text. */
- goto xscanfile;
-
- } else if (rc == FT_UCS2 || (rc == FT_UTF8 && runmax == 0)) {
- goto xscanfile; /* File starts with a BOM */
-
- } else if (eightbit > 0 && !notutf8) { /* File has 8-bit data */
- if (runmax > 0) { /* and runs of NULs */
- debug(F100,"scanfile BIN (nnUTF8) runmax","",0);
- rc = FT_BIN; /* UTF-8 doesn't have NULs */
- } else { /* No NULs */
- debug(F100,"scanfile UTF8 (nnUTF8 + runmax == 0)","",0);
- rc = FT_UTF8; /* and not not UTF-8, so is UTF-8 */
- }
- goto xscanfile;
- }
-/*
- For UCS-2 detection, see if the text contains lines delimited by
- ASCII controls and containing spaces, ASCII digits, or other ASCII
- characters, thus forcing the presence of a certain percentage of zero bytes.
- For this purpose require 20% zero bytes, with at least six times as many
- in even (odd) positions as in odd (even) positions.
-*/
- if ((evenzero >= x && oddzero == 0) ||
- ((((evenzero / (oddzero + 1)) > 6) && (pctzero > 20)) &&
- (crlf == 0) &&
- (lfnul > 1))
- ) {
- debug(F100,"scanfile UCS2 noBOM BE (even/oddzero)","",0);
- rc = FT_UCS2;
- val = 0;
- } else if ((evenzero == 0 && oddzero >= x) ||
- ((((oddzero / (evenzero + 1)) > 6) && (pctzero > 20)) &&
- (crlf == 0) &&
- (lfnul > 1))
- ) {
- debug(F100,"scanfile UCS2 noBOM LE (even/oddzero)","",0);
- rc = FT_UCS2;
- val = 1;
-
-#ifdef COMMENT
-#ifdef EVENMAX
-/*
- If the tests above fail, we still might have UCS-2 if there are significant
- runs of identical bytes in alternating positions, but only if it also has
- unusual C0 controls (otherwise we'd pick up hex files here). NOTE: We
- don't actually do this -- EVENMAX is not defined (see comments above at
- first occurrence of EVENMAX).
-*/
- } else if (c0noniso && evenmax > bytes / 4) {
- debug(F100,"scanfile UCS2 BE (evenmax)","",0);
- rc = FT_UCS2;
- val = 0;
- } else if (c0noniso && oddmax > bytes / 4) {
- debug(F100,"scanfile UCS2 LE (evenmax)","",0);
- rc = FT_UCS2;
- val = 1;
-#endif /* EVENMAX */
-#endif /* COMMENT */
-
- }
-/*
- It seems to be UCS-2 but let's be more certain since there is no BOM...
- If the number of 7- and 8-bit characters is approximately equal, it might
- be a compressed file. In this case we decide based on the name.
-*/
- if (rc == FT_UCS2) {
- if (eightbit > 0) {
- int j, k;
- j = (c1controls * 100) / (c0controls + 1);
- debug(F101,"scanfile c1/c0 ","",j);
- k = (bytes * 100) / eightbit;
- debug(F101,"scanfile pct 8bit ","",k);
- if (k > 40 && k < 60 && j > 60) {
- if (ckmatch("{*.Z,*.gz,*.zip,*.ZIP}",name,1,1)) {
- debug(F110,"scanfile 8-bit BIN compressed",name,0);
- rc = FT_BIN;
- goto xscanfile;
- }
- }
- }
- /* Small file - not enough evidence unless ... */
-
- if (bytes < 100) {
- if (oddzero != 0 && evenzero != 0) {
- debug(F100,"scanfile small UCS2 doubtful","",0);
- rc = FT_BIN;
- goto xscanfile;
- } else if (oddzero == 0 && evenzero == 0) {
- rc = eightbit ? FT_8BIT : FT_7BIT;
- }
- }
- goto xscanfile; /* Seems to be UCS-2 */
- }
-
-/* If none of the above, it's probably not Unicode. */
-
- if (!eightbit) { /* It's 7-bit */
- if (c0controls) { /* This would be strange */
- if ((c0noniso > 0) && (txtcz == 0)) {
- debug(F100,"scanfile 7-bit BIN (c0coniso)","",0);
- rc = FT_BIN;
- } else {
- debug(F100,"scanfile 7-bit ISO2022 TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
- } else { /* 7-bit text */
- debug(F100,"scanfile 7-bit TEXT (no c0controls)","",0);
- rc = FT_7BIT;
- }
- } else if (!c0noniso || txtcz) { /* 8-bit text */
- debug(F100,"scanfile 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else { /* 8-bit binary */
- debug(F100,"scanfile 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- }
-
-#else /* !UNICODE */
-
- if (c0noniso) {
- debug(F100,"scanfile 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- } else if (eightbit) {
- debug(F100,"scanfile 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else {
- debug(F100,"scanfile 7-bit TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
-
-#endif /* UNICODE */
-
- xscanfile:
- if (flag) *flag = val;
- debug(F101,"scanfile result ","",rc);
- return(rc);
-}
-
-/*
- scanstring - like scan file but for a string.
- This is just a quick butchery of scanfile without thinking too much.
-*/
-int
-scanstring(s) char * s; {
- int x, val = -1, count = 0; /* Workers */
- int rc = -1; /* Return code */
- int pv = -1; /* Pattern-match value */
- int bytes = 0; /* Total byte count */
-#ifdef UNICODE
- unsigned int c0, c1; /* First 2 file bytes (for BOM) */
-#endif /* UNICODE */
- extern int pipesend, filepeek;
-
- register int i; /* Loop control */
- int readsize = 0; /* How much to read */
- int eightbit = 0; /* Number of bytes with 8th bit on */
- int c0controls = 0; /* C0 non-text control-char counter */
- int c0noniso = 0; /* C0 non-ISO control-char counter */
- int c1controls = 0; /* C1 control-character counter */
- unsigned int c; /* Current character */
- int runmax = 0; /* Longest run of 0 bytes */
- int runzero = 0; /* Run of 0 bytes */
- int pctzero = 0; /* Percentage of 0 bytes */
- int txtcz = 0;
-
-#ifdef UNICODE
- int notutf8 = 0; /* Nonzero if definitely not UTF-8 */
- int utf8state = 0; /* UTF-8 recognizer state */
- int oddzero = 0; /* Number of 0 bytes in odd postions */
- int evenzero = 0; /* and in even positions */
- int lfnul = 0; /* Number of <LF><NUL> sequences */
- int crlf = 0; /* Number of <CRLF> sequences */
-#else
- int notutf8 = 1;
-#endif /* UNICODE */
-
- char * buf = s;
- if (!s) s = "";
- count = strlen(s);
-
-#ifdef UNICODE
- if (bytes == 0 && count > 1) {
- int incl_cnt = 0;
-
- /* First look for BOM */
-
- c0 = (unsigned)((unsigned)buf[0]&0xFF); /* First file byte */
- c1 = (unsigned)((unsigned)buf[1]&0xFF); /* Second byte */
-
- if (c0 == 0xFE && c1 == 0xFF) { /* UCS-2 BE */
- rc = FT_UCS2;
- val = 0;
- debug(F111,"scanstring UCS2 BOM BE",ckitoa(val),rc);
- incl_cnt++;
- } else if (c0 == 0xFF && c1 == 0xFE) { /* UCS-2 LE */
- rc = FT_UCS2;
- val = 1;
- debug(F111,"scanstring UCS2 BOM LE",ckitoa(val),rc);
- incl_cnt++;
- } else if (count > 2) if (c0 == 0xEF && c1 == 0xBB &&
- (unsigned)((unsigned)buf[2]&0xFF) == 0xBF) {
- rc = FT_UTF8;
- debug(F111,"scanstring UTF8 BOM",ckitoa(val),rc);
- incl_cnt++;
- }
- if (incl_cnt) { /* Have BOM */
- bytes += count;
- goto xscanstring;
- }
- }
-#endif /* UNICODE */
-
- bytes += count; /* Count bytes read */
-
- for (i = 0; i < count; i++) { /* For each byte... */
- c = (unsigned)buf[i]; /* For ease of reference */
- if (!c) { /* Zero byte? */
- goto xscanstring; /* Null terminated string */
- }
- if ((c & 0x80) == 0) { /* We have a 7-bit byte */
-#ifdef UNICODE
- if (i > 0 && c == 10) { /* Linefeed */
- if (buf[i-1] == 0) lfnul++; /* Preceded by NUL */
- else if (buf[i-1] == 13) crlf++; /* or by CR... */
- }
-#endif /* UNICODE */
- if (c < ' ') { /* Check for CO controls */
- if (c != LF && c != CR && c != HT && c != FF) {
- c0controls++;
- if (c != ESC && c != SO && c != SI)
- c0noniso++;
- }
- if ((c == '\032') /* Ctrl-Z */
- ) {
- c0controls--;
- c0noniso--;
- }
- }
-#ifdef UNICODE
- if (!notutf8 && utf8state) { /* In UTF-8 sequence? */
- utf8state = 0;
- debug(F000,"scanstring","7-bit byte in UTF8 sequence",c);
- notutf8++; /* Then it's not UTF-8 */
- continue;
- }
-#endif /* UNICODE */
- } else { /* We have an 8-bit byte */
- eightbit++; /* Count it */
- if (c >= 0x80 && c < 0xA0) /* Check for C1 controls */
- c1controls++;
-#ifdef UNICODE
- if (!notutf8) { /* If it might still be UTF8... */
- switch (utf8state) { /* Enter the UTF-8 state machine */
- case 0: /* First byte... */
- if ((c & 0xE0) == 0xC0) { /* Tells number of */
- utf8state = 1; /* subsequent bytes */
- } else if ((c & 0xF0) == 0xE0) {
- utf8state = 2;
- } else if ((c & 0xF8) == 0xF0) {
- utf8state = 3;
- } else {
- notutf8++;
- }
- break;
- case 1: /* Subsequent byte */
- case 2:
- case 3:
- if ((c & 0xC0) != 0x80) { /* Must start with 10 */
- debug(F000,"scanstring",
- "bad byte in UTF8 sequence",c);
- notutf8++;
- break;
- }
- utf8state--; /* Good, one less in this sequence */
- break;
- default: /* Shouldn't happen */
- debug(F111,"scanstring","bad UTF8 state",utf8state);
- notutf8++;
- }
- }
-#endif /* UNICODE */
- }
- }
- if (bytes == 0) /* If nothing was read */
- return(-1); /* we're done. */
-
-#ifdef UNICODE
- if (bytes > 100) /* Bytes is not 0 */
- pctzero = (evenzero + oddzero) / (bytes / 100);
- else
- pctzero = ((evenzero + oddzero) * 100) / bytes;
-#endif /* UNICODE */
-
-#ifdef UNICODE
- x = eightbit ? bytes / 20 : bytes / 4; /* For UCS-2... */
-
- if (runmax > 2) { /* File has run of more than 2 NULs */
- debug(F100,"scanstring BIN runmax","",0);
- rc = FT_BIN; /* so it can't be any kind of text. */
- goto xscanstring;
-
- } else if (rc == FT_UCS2 || (rc == FT_UTF8 && runmax == 0)) {
- goto xscanstring; /* File starts with a BOM */
-
- } else if (eightbit > 0 && !notutf8) { /* File has 8-bit data */
- if (runmax > 0) { /* and runs of NULs */
- debug(F100,"scanstring BIN (nnUTF8) runmax","",0);
- rc = FT_BIN; /* UTF-8 doesn't have NULs */
- } else { /* No NULs */
- debug(F100,"scanstring UTF8 (nnUTF8 + runmax == 0)","",0);
- rc = FT_UTF8; /* and not not UTF-8, so is UTF-8 */
- }
- goto xscanstring;
- }
-/*
- It seems to be UCS-2 but let's be more certain since there is no BOM...
- If the number of 7- and 8-bit characters is approximately equal, it might
- be a compressed file. In this case we decide based on the name.
-*/
- if (rc == FT_UCS2) {
- if (bytes < 100) {
- if (oddzero != 0 && evenzero != 0) {
- debug(F100,"scanstring small UCS2 doubtful","",0);
- rc = FT_BIN;
- goto xscanstring;
- } else if (oddzero == 0 && evenzero == 0) {
- rc = eightbit ? FT_8BIT : FT_7BIT;
- }
- }
- goto xscanstring; /* Seems to be UCS-2 */
- }
-
-/* If none of the above, it's probably not Unicode. */
-
- if (!eightbit) { /* It's 7-bit */
- if (c0controls) { /* This would be strange */
- if ((c0noniso > 0) && (txtcz == 0)) {
- debug(F100,"scanstring 7-bit BIN (c0coniso)","",0);
- rc = FT_BIN;
- } else {
- debug(F100,"scanstring 7-bit ISO2022 TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
- } else { /* 7-bit text */
- debug(F100,"scanstring 7-bit TEXT (no c0controls)","",0);
- rc = FT_7BIT;
- }
- } else if (!c0noniso || txtcz) { /* 8-bit text */
- debug(F100,"scanstring 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else { /* 8-bit binary */
- debug(F100,"scanstring 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- }
-
-#else /* !UNICODE */
-
- if (c0noniso) {
- debug(F100,"scanstring 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- } else if (eightbit) {
- debug(F100,"scanstring 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else {
- debug(F100,"scanstring 7-bit TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
-
-#endif /* UNICODE */
-
- xscanstring:
- debug(F101,"scanstring result ","",rc);
- return(rc);
-}
-
-
-
-/* F I L E S E L E C T -- Select this file for sending */
-
-int
-#ifdef CK_ANSIC
-fileselect(
- char *f, char *sa, char *sb, char *sna, char *snb,
- CK_OFF_T minsiz, CK_OFF_T maxsiz,
- int nbu, int nxlist,
- char ** xlist
-)
-#else
-fileselect(f,sa,sb,sna,snb,minsiz,maxsiz,nbu,nxlist,xlist)
- char *f,*sa,*sb,*sna,*snb; CK_OFF_T minsiz,maxsiz;
- int nbu,nxlist; char ** xlist;
-#endif /* CK_ANSIC */
-/* fileselect */ {
- char *fdate;
- int n;
- CK_OFF_T z;
-
- debug(F111,"fileselect minsiz",ckfstoa(minsiz),minsiz);
- debug(F111,"fileselect maxsiz",ckfstoa(maxsiz),maxsiz);
- debug(F111,"fileselect (CK_OFF_T)-1",ckfstoa((CK_OFF_T)-1),(CK_OFF_T)-1);
-
- if (!sa) sa = "";
- if (!sb) sb = "";
- if (!sna) sna = "";
- if (!snb) snb = "";
-
-#ifdef CKSYMLINK
-#ifndef NOICP
-#ifndef NOXFER
- if (nolinks) {
- CK_OFF_T zz;
- zz = zgetfs(f);
- debug(F111,"fileselect NOLINKS zgetfs",f,zz);
- if (zz < (CK_OFF_T)0)
- return(0);
- debug(F111,"fileselect NOLINKS zgfs_link",f,zgfs_link);
- if (zgfs_link)
- return(0);
- }
-#endif /* NOXFER */
-#endif /* NOICP */
-#endif /* CKSYMLINK */
-
- debug(F110,"fileselect",f,0);
- if (*sa || *sb || *sna || *snb) {
- fdate = zfcdat(f); /* Date/time of this file */
- if (!fdate) fdate = "";
- n = strlen(fdate);
- debug(F111,"fileselect fdate",fdate,n);
- if (n != 17) /* Failed to get it */
- return(1);
- /* /AFTER: */
- if (sa[0] && (strcmp(fdate,(char *)sa) <= 0)) {
- debug(F110,"fileselect sa",sa,0);
- /* tlog(F110,"Skipping (too old)",f,0); */
- return(0);
- }
- /* /BEFORE: */
- if (sb[0] && (strcmp(fdate,(char *)sb) >= 0)) {
- debug(F110,"fileselect sb",sb,0);
- /* tlog(F110,"Skipping (too new)",f,0); */
- return(0);
- }
- /* /NOT-AFTER: */
- if (sna[0] && (strcmp(fdate,(char *)sna) > 0)) {
- debug(F110,"fileselect sna",sna,0);
- /* tlog(F110,"Skipping (too new)",f,0); */
- return(0);
- }
- /* /NOT-BEFORE: */
- if (snb[0] && (strcmp(fdate,(char *)snb) < 0)) {
- debug(F110,"fileselect snb",snb,0);
- /* tlog(F110,"Skipping (too old)",f,0); */
- return(0);
- }
- }
- /* Smaller or larger */
- if (minsiz > (CK_OFF_T)-1 || maxsiz > (CK_OFF_T)-1) {
- z = zchki(f); /* Get size */
- debug(F101,"fileselect filesize","",z);
- if (z < (CK_OFF_T)0)
- return(1);
- if ((minsiz > (CK_OFF_T)-1) && (z >= minsiz)) {
- debug(F111,"fileselect minsiz skipping",f,minsiz);
- /* tlog(F111,"Skipping (too big)",f,z); */
- return(0);
- }
- if ((maxsiz > (CK_OFF_T)-1) && (z <= maxsiz)) {
- debug(F111,"fileselect maxsiz skipping",f,maxsiz);
- /* tlog(F110,"Skipping (too small)",f,0); */
- return(0);
- }
- }
- if (nbu) { /* Skipping backup files? */
- if (ckmatch(
-#ifdef CKREGEX
- "*.~[0-9]*~" /* Not perfect but close enough. */
-#else
- "*.~*~" /* Less close. */
-#endif /* CKREGEX */
- ,f,filecase,1)) {
- debug(F110,"fileselect skipping backup",f,0);
- return(0);
- }
- }
- for (n = 0; xlist && n < nxlist; n++) {
- if (!xlist[n]) {
- debug(F101,"fileselect xlist empty",0,n);
- break;
- }
- if (ckmatch(xlist[n],f,filecase,1)) {
- debug(F111,"fileselect xlist",xlist[n],n);
- debug(F110,"fileselect skipping",f,0);
- return(0);
- }
- }
- if (xfiletype > -1) {
- n = scanfile(f,NULL,nscanfile);
- if (n < 0) {
- n = binary ? 1 : 0;
- } else {
- n = (n == FT_BIN) ? 1 : 0;
- }
- if (n != xfiletype)
- return(0);
- }
- debug(F110,"fileselect selecting",f,0);
- return(1);
-}
-
-
-#ifdef TCPSOCKET
-#ifdef NT
-extern int WSASafeToCancel;
-#endif /* NT */
-#endif /* TCPSOCKET */
-
-VOID
-setflow() {
- extern int flow, autoflow, mdmtyp, cxtype, cxflow[];
-#ifndef NODIAL
- extern int dialcapas, dialfc;
- extern MDMINF * modemp[];
- MDMINF * p = NULL;
- long bits = 0;
-#endif /* NODIAL */
-
- debug(F101,"setflow autoflow","",autoflow);
-
-/* #ifdef COMMENT */
-/* WHY WAS THIS COMMENTED OUT? */
- if (!autoflow) /* Only if FLOW is AUTO */
- return;
-/* #endif */ /* COMMENT */
-
- debug(F101,"setflow local","",local);
- debug(F101,"setflow network","",network);
- debug(F101,"setflow cxtype","",cxtype);
-
-#ifdef TN_COMPORT
- if (network && istncomport()) {
- flow = cxflow[CXT_MODEM];
- debug(F101,"setflow TN_COMPORT flow","",flow);
- return;
- }
-#endif /* TN_COMPORT */
-
- if (network || !local || cxtype == CXT_DIRECT) {
- flow = cxflow[cxtype]; /* Set appropriate flow control */
- debug(F101,"setflow flow","",flow);
- return;
- }
- if (cxtype != CXT_MODEM) /* Connection type should be modem */
- return;
-
-#ifndef NODIAL
- bits = dialcapas; /* Capability bits */
- if (!bits) { /* No bits? */
- p = modemp[mdmtyp]; /* Look in modem info structure */
- if (p)
- bits = p->capas;
- }
- if (dialfc == FLO_AUTO) { /* If DIAL flow is AUTO */
-#ifdef CK_RTSCTS /* If we can do RTS/CTS flow control */
- if (bits & CKD_HW) /* and modem can do it too */
- flow = FLO_RTSC; /* then switch to RTS/CTS */
- else /* otherwise */
- flow = FLO_XONX; /* use Xon/Xoff. */
-#else
-#ifndef NEXT
-#ifndef IRIX
- flow = FLO_XONX; /* Use Xon/Xoff. */
-#endif /* IRIX */
-#endif /* NEXT */
-#endif /* CK_RTSCTS */
- }
-#endif /* NODIAL */
- debug(F101,"setflow modem flow","",flow);
- return;
-}
-
-#ifndef NOLOCAL
-#ifdef CK_TRIGGER
-
-/* A U T O E X I T C H K -- Check for CONNECT-mode trigger string */
-/*
- Returns -1 if trigger not found, or else the trigger index, 0 or greater.
- (Replace with fancier and more efficient matcher later...)
- NOTE: to prevent unnecessary function call overhead, call this way:
-
- x = tt_trigger[0] ? autoexitchk(c) : -1;
-
-*/
-int
-#ifdef CK_ANSIC
-autoexitchk(CHAR c)
-#else
-autoexitchk(c) CHAR c;
-#endif /* CK_ANSIC */
-/* autoexitchk */ {
- extern CHAR * tt_trmatch[];
- extern char * tt_trigger[];
- int i;
- for (i = 0; i < TRIGGERS; i++) {
- if (!tt_trigger[i]) { /* No more triggers in list */
- break;
- } else if (*tt_trigger[i]) {
- if (!tt_trmatch[i]) /* Just starting? */
- tt_trmatch[i] = (CHAR *)tt_trigger[i]; /* Set match pointer */
- if (c == *tt_trmatch[i]) { /* Compare this character */
- tt_trmatch[i]++; /* It matches */
- if (!*tt_trmatch[i]) { /* End of match string? */
- tt_trmatch[i] = (CHAR *) tt_trigger[i]; /* Yes, rewind, */
- debug(F101,"autoexitchk",tt_trigger[i],i); /* log, */
- return(i); /* and return success */
- }
- } else /* No match */
- tt_trmatch[i] = (CHAR *) tt_trigger[i]; /* Rewind match string */
- } /* and go on the next match string */
- }
- return(-1); /* No match found */
-}
-#endif /* CK_TRIGGER */
-
-#ifndef NOSHOW
-/* S H O M D M -- Show modem signals */
-
-VOID
-shomdm() {
-/*
- Note use of "\r\n" to make sure this report prints right, even when
- called during CONNECT mode.
-*/
- int y;
- y = ttgmdm();
- switch (y) {
- case -3: printf(
- "Modem signals unavailable in this version of Kermit\r\n");
- break;
- case -2: printf("No modem control for this device\r\n"); break;
- case -1: printf("Modem signals unavailable\r\n"); break;
- default:
-#ifndef MAC
- printf(
- " Carrier Detect (CD): %s\r\n",(y & BM_DCD) ? "On": "Off");
- printf(
- " Dataset Ready (DSR): %s\r\n",(y & BM_DSR) ? "On": "Off");
-#endif /* MAC */
- printf(
- " Clear To Send (CTS): %s\r\n",(y & BM_CTS) ? "On": "Off");
-#ifndef STRATUS
-#ifndef MAC
- printf(
- " Ring Indicator (RI): %s\r\n",(y & BM_RNG) ? "On": "Off");
-#endif /* MAC */
- printf(
- " Data Terminal Ready (DTR): %s\r\n",
-#ifdef NT
- "(unknown)"
-#else /* NT */
- (y & BM_DTR) ? "On": "Off"
-#endif /* NT */
- );
-#ifndef MAC
- printf(
- " Request To Send (RTS): %s\r\n",
-#ifdef NT
- "(unknown)"
-#else /* NT */
- (y & BM_RTS) ? "On": "Off"
-#endif /* NT */
- );
-#endif /* MAC */
-#endif /* STRATUS */
- }
-#ifdef BETADEBUG
-#ifdef CK_TAPI
- if (tttapi && !tapipass) {
- LPDEVCFG lpDevCfg = NULL;
- LPCOMMCONFIG lpCommConfig = NULL;
- LPMODEMSETTINGS lpModemSettings = NULL;
- DCB * lpDCB = NULL;
-
- if (cktapiGetModemSettings(&lpDevCfg,&lpModemSettings,
- &lpCommConfig,&lpDCB)) {
- printf("\n");
- cktapiDisplayModemSettings(lpDevCfg,lpModemSettings,
- lpCommConfig,lpDCB);
- }
- }
-#endif /* CK_TAPI */
-#endif /* BETADEBUG */
-}
-#endif /* NOSHOW */
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
-/* S D E B U -- Record spar results in debugging log */
-
-VOID
-sdebu(len) int len; {
- debug(F111,"spar: data",(char *) rdatap,len);
- debug(F101," spsiz ","", spsiz);
- debug(F101," timint","",timint);
- debug(F101," npad ","", npad);
- debug(F101," padch ","", padch);
- debug(F101," seol ","", seol);
- debug(F101," ctlq ","", ctlq);
- debug(F101," ebq ","", ebq);
- debug(F101," ebqflg","",ebqflg);
- debug(F101," bctr ","", bctr);
- debug(F101," rptq ","", rptq);
- debug(F101," rptflg","",rptflg);
- debug(F101," lscapu","",lscapu);
- debug(F101," atcapu","",atcapu);
- debug(F101," lpcapu","",lpcapu);
- debug(F101," swcapu","",swcapu);
- debug(F101," wslotn","", wslotn);
- debug(F101," whatru","", whatru);
-}
-/* R D E B U -- Debugging display of rpar() values */
-
-VOID
-rdebu(d,len) CHAR *d; int len; {
- debug(F111,"rpar: data",d,len);
- debug(F101," rpsiz ","", xunchar(d[0]));
- debug(F101," rtimo ","", rtimo);
- debug(F101," mypadn","",mypadn);
- debug(F101," mypadc","",mypadc);
- debug(F101," eol ","", eol);
- debug(F101," ctlq ","", ctlq);
- debug(F101," sq ","", sq);
- debug(F101," ebq ","", ebq);
- debug(F101," ebqflg","",ebqflg);
- debug(F101," bctr ","", bctr);
- debug(F101," rptq ","", d[8]);
- debug(F101," rptflg","",rptflg);
- debug(F101," capas ","", capas);
- debug(F101," bits ","",d[capas]);
- debug(F101," lscapu","",lscapu);
- debug(F101," atcapu","",atcapu);
- debug(F101," lpcapu","",lpcapu);
- debug(F101," swcapu","",swcapu);
- debug(F101," wslotr","", wslotr);
- debug(F101," rpsiz(extended)","",rpsiz);
-}
-
-#ifdef COMMENT
-/* C H K E R R -- Decide whether to exit upon a protocol error */
-
-VOID
-chkerr() {
- if (backgrd && !server) fatal("Protocol error");
-}
-#endif /* COMMENT */
-#endif /* NOXFER */
-
-/* F A T A L -- Fatal error message */
-
-VOID
-fatal(msg) char *msg; {
- extern int initflg;
- static int initing = 0;
- if (!msg) msg = "";
- debug(F111,"fatal",msg,initflg);
-
- if (!initflg) { /* If called from prescan */
- if (initing) /* or called from sysinit() */
- exit(253);
- initing = 1;
- sysinit();
- }
-
- debug(F111,"fatal",msg,xitsta);
- tlog(F110,"Fatal:",msg,0L);
-#ifdef VMS
- if (strncmp(msg,"%CKERMIT",8))
- conol("%CKERMIT-E-FATAL, ");
- conoll(msg);
-#else /* !VMS */
- conoll(msg);
-#endif /* VMS */
-#ifdef OS2
-#ifndef NOXFER
- if (xfrbel) {
- bleep(BP_FAIL);
- sleep(1);
- bleep(BP_FAIL);
- }
-#endif /* NOXFER */
-
-#endif /* OS2 */
- doexit(BAD_EXIT,xitsta | 1); /* Exit indicating failure */
-}
-
-#ifndef NOXFER
-/* B L D L E N -- Make length-encoded copy of string */
-
-char *
-bldlen(str,dest) char *str, *dest; {
- int len;
- len = (int)strlen(str);
- if (len > 94)
- *dest = SP;
- else
- *dest = (char) tochar(len);
- strcpy(dest+1,str); /* Checked below in setgen() */
- return(dest+len+1);
-}
-
-
-/* S E T G E N -- Construct a generic command */
-/*
- Call with Generic command character followed by three string arguments.
- Trailing strings are allowed to be empty (""). Each string except the last
- non-empty string must be less than 95 characters long. The final nonempty
- string is allowed to be longer.
-*/
-CHAR
-#ifdef CK_ANSIC
-setgen(char type, char * arg1, char * arg2, char * arg3)
-#else
-setgen(type,arg1,arg2,arg3) char type, *arg1, *arg2, *arg3;
-#endif /* CK_ANSIC */
-/* setgen */ {
- char *upstr, *cp;
-#ifdef DYNAMIC
- if (!cmdstr)
- if (!(cmdstr = malloc(MAXSP + 1)))
- fatal("setgen: can't allocate memory");
-#endif /* DYNAMIC */
-
- cp = cmdstr;
- *cp++ = type;
- *cp = NUL;
- if (!arg1) arg1 = "";
- if (!arg2) arg2 = "";
- if (!arg3) arg3 = "";
- if (((int)strlen(arg1)+(int)strlen(arg2)+(int)strlen(arg3)+4) < MAXSP) {
- if (*arg1 != NUL) {
- upstr = bldlen(arg1,cp);
- if (*arg2 != NUL) {
- upstr = bldlen(arg2,upstr);
- if (*arg3 != NUL) bldlen(arg3,upstr);
- }
- }
- cmarg = cmdstr;
- debug(F110,"setgen",cmarg,0);
- return('g');
- }
- return('E');
-}
-#endif /* NOXFER */
-
-#ifndef NOMSEND
-static char *mgbufp = NULL;
-
-/* F N P A R S E -- */
-
-/*
- Argument is a character string containing one or more filespecs.
- This function breaks the string apart into an array of pointers, one
- to each filespec, and returns the number of filespecs. Used by server
- when it receives a GET command to allow it to process multiple file
- specifications in one transaction. Sets cmlist to point to a list of
- file pointers, exactly as if they were command line arguments.
-
- This version of fnparse treats spaces as filename separators. If your
- operating system allows spaces in filenames, you'll need a different
- separator.
-
- This version of fnparse mallocs a string buffer to contain the names. It
- cannot assume that the string that is pointed to by the argument is safe.
-*/
-int
-fnparse(string) char *string; {
- char *p, *s, *q;
- int r = 0, x; /* Return code */
-#ifdef RECURSIVE
- debug(F111,"fnparse",string,recursive);
-#endif /* RECURSIVE */
-
- if (mgbufp) free(mgbufp); /* Free this from last time. */
- mgbufp = malloc((int)strlen(string)+2);
- if (!mgbufp) {
- debug(F100,"fnparse malloc error","",0);
- return(0);
- }
-#ifndef NOICP
-#ifndef NOSPL
- ckstrncpy(fspec,string,fspeclen); /* Make copy for \v(filespec) */
-#endif /* NOSPL */
-#endif /* NOICP */
- s = string; /* Input string */
- p = q = mgbufp; /* Point to the copy */
- r = 0; /* Initialize our return code */
- while (*s == SP || *s == HT) /* Skip leading spaces and tabs */
- s++;
- for (x = strlen(s); /* Strip trailing spaces */
- (x > 1) && (s[x-1] == SP || s[x-1] == HT);
- x--)
- s[x-1] = NUL;
- while (1) { /* Loop through rest of string */
- if (*s == CMDQ) { /* Backslash (quote character)? */
- if ((x = xxesc(&s)) > -1) { /* Go interpret it. */
- *q++ = (char) x; /* Numeric backslash code, ok */
- } else { /* Just let it quote next char */
- s++; /* get past the backslash */
- *q++ = *s++; /* deposit next char */
- }
- continue;
- } else if (*s == SP || *s == NUL) { /* Unquoted space or NUL? */
- *q++ = NUL; /* End of output filename. */
- msfiles[r] = p; /* Add this filename to the list */
- debug(F111,"fnparse",msfiles[r],r);
- r++; /* Count it */
- if (*s == NUL) break; /* End of string? */
- while (*s == SP) s++; /* Skip repeated spaces */
- p = q; /* Start of next name */
- continue;
- } else *q++ = *s; /* Otherwise copy the character */
- s++; /* Next input character */
- }
- debug(F101,"fnparse r","",r);
- msfiles[r] = ""; /* Put empty string at end of list */
- cmlist = msfiles;
- return(r);
-}
-#endif /* NOMSEND */
-
-char * /* dbchr() for DEBUG SESSION */
-dbchr(c) int c; {
- static char s[8];
- char *cp = s;
-
- c &= 0xff;
- if (c & 0x80) { /* 8th bit on */
- *cp++ = '~';
- c &= 0x7f;
- }
- if (c < SP) { /* Control character */
- *cp++ = '^';
- *cp++ = (char) ctl(c);
- } else if (c == DEL) {
- *cp++ = '^';
- *cp++ = '?';
- } else { /* Printing character */
- *cp++ = (char) c;
- }
- *cp = '\0'; /* Terminate string */
- cp = s; /* Return pointer to it */
- return(cp);
-}
-
-/* C K H O S T -- Get name of local host (where C-Kermit is running) */
-
-/*
- Call with pointer to buffer to put hostname in, and length of buffer.
- Copies hostname into buffer on success, puts null string in buffer on
- failure.
-*/
-#ifdef BSD44
-#define BSD4
-#undef ATTSV
-#endif /* BSD44 */
-
-#ifdef SVORPOSIX
-#ifndef BSD44
-#ifndef apollo
-#include <sys/utsname.h>
-#endif /* apollo */
-#endif /* BSD44 */
-#else
-#ifdef BELLV10
-#include <utsname.h>
-#endif /* BELLV10 */
-#endif /* SVORPOSIX*/
-
-#ifdef CKSYSLOG
-extern char uidbuf[], * clienthost;
-#endif /* CKSYSLOG */
-
-VOID
-ckhost(vvbuf,vvlen) char * vvbuf; int vvlen; {
-
-#ifndef NOPUSH
- extern int nopush;
-#ifndef NOSERVER
- extern int en_hos;
-#endif /* NOSERVER */
-#endif /* NOPUSH */
-
-#ifdef pdp11
- *vvbuf = NUL;
-#else /* Everything else - rest of this routine */
-
- char *g;
- int havefull = 0;
-#ifdef VMS
- int x;
-#endif /* VMS */
-
-#ifdef SVORPOSIX
-#ifndef BSD44
-#ifndef _386BSD
-#ifndef APOLLOSR10
- struct utsname hname;
-#endif /* APOLLOSR10 */
-#endif /* _386BSD */
-#endif /* BSD44 */
-#endif /* SVORPOSIX */
-#ifdef datageneral
- int ac0 = (char *) vvbuf, ac1 = -1, ac2 = 0;
-#endif /* datageneral */
-
-#ifndef NOPUSH
- if (getenv("CK_NOPUSH")) { /* No shell access allowed */
- nopush = 1; /* on this host... */
-#ifndef NOSERVER
- en_hos = 0;
-#endif /* NOSERVER */
- }
-#endif /* NOPUSH */
-
- *vvbuf = NUL; /* How let's get our host name ... */
-
-#ifndef BELLV10 /* Does not have gethostname() */
-#ifndef OXOS
-#ifdef SVORPOSIX
-#ifdef APOLLOSR10
- ckstrncpy(vvbuf,"Apollo",vvlen);
-#else
-#ifdef BSD44
- if (gethostname(vvbuf,vvlen) < 0)
- *vvbuf = NUL;
-#else
-#ifdef _386BSD
- if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL;
-#else
-#ifdef QNX
-#ifdef TCPSOCKET
- if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL;
-#else
- if (uname(&hname) > -1) ckstrncpy(vvbuf,hname.nodename,vvlen);
-#endif /* TCPSOCKET */
-#else /* SVORPOSIX but not _386BSD or BSD44 */
-#ifdef __ia64__
- if (uname(&hname) > -1) ckstrncpy(vvbuf,hname.nodename,vvlen);
-#else
- if (uname(&hname) > -1) {
- char * p;
- p = hname.nodename;
-#ifdef TCPSOCKET
-#ifndef NOCKGETFQHOST
- if (!ckstrchr(p,'.'))
- p = (char *)ckgetfqhostname(p);
-#endif /* NOCKGETFQHOST */
-#endif /* TCPSOCKET */
- if (!p) p = "";
- if (!*p) p = "(unknown)";
- ckstrncpy(vvbuf,p,vvlen);
- }
-#endif /* __ia64__ */
-#endif /* QNX */
-#endif /* _386BSD */
-#endif /* BSD44 */
-#endif /* APOLLOSR10 */
-#else /* !SVORPOSIX */
-#ifdef BSD4
- if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL;
-#else /* !BSD4 */
-#ifdef VMS
- g = getenv("SYS$NODE");
- if (g) ckstrncpy(vvbuf,g,vvlen);
- x = (int)strlen(vvbuf);
- if (x > 1 && vvbuf[x-1] == ':' && vvbuf[x-2] == ':') vvbuf[x-2] = NUL;
-#else
-#ifdef datageneral
- if (sys($HNAME,&ac0,&ac1,&ac2) == 0) /* successful */
- vvlen = ac2 + 1; /* enh - have to add one */
-#else
-#ifdef OS2 /* OS/2 */
- g = os2_gethostname();
- if (g) ckstrncpy(vvbuf,g,vvlen);
-#else /* OS2 */
-#ifdef OSK
-#ifdef TCPSOCKET
- if (gethostname(vvbuf, vvlen) < 0) *vvbuf = NUL;
-#endif /* TCPSOCKET */
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* BSD4 */
-#endif /* SVORPOSIX */
-#else /* OXOS */
- /* If TCP/IP is not installed, gethostname() fails, use uname() */
- if (gethostname(vvbuf,vvlen) < 0) {
- if (uname(&hname) > -1)
- ckstrncpy(vvbuf,hname.nodename,vvlen);
- else
- *vvbuf = NUL;
- }
-#endif /* OXOS */
-#endif /* BELLV10 */
- if (*vvbuf == NUL) { /* If it's still empty */
- g = getenv("HOST"); /* try this */
- if (g) ckstrncpy(vvbuf,g,vvlen);
- }
- vvbuf[vvlen-1] = NUL; /* Make sure result is terminated. */
-#endif /* pdp11 */
-}
-#ifdef BSD44
-#undef BSD4
-#define ATTSV
-#endif /* BSD44 */
-
-/*
- A S K M O R E -- Poor person's "more".
- Returns 0 if no more, 1 if more wanted.
-*/
-int
-askmore() {
- char c;
- int rv, cx;
-#ifdef IKSD
- extern int timelimit;
-#endif /* IKSD */
-#ifdef IKSDCONF
- extern int iksdcf;
-#endif /* IKSDCONF */
-#ifdef CK_APC
- extern int apcstatus, apcactive;
-#endif /* CK_APC */
-
-#ifdef NOICP
- return(1);
-#else
- if (!xaskmore)
- return(1);
-#ifdef IKSDCONF
- if (inserver && !iksdcf)
- return(1);
-#endif /* IKSDCONF */
-#ifdef CK_APC
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && (apcstatus & APC_NOINP)))
- return(1);
-#endif /* CK_APC */
-#ifdef VMS
- if (batch)
- return(1);
-#else
-#ifdef UNIX
- if (backgrd)
- return(1);
-#endif /* UNIX */
-#endif /* VMS */
-
-#ifndef VMS
- concb((char)escape); /* Force CBREAK mode. */
-#endif /* VMS */
-
- rv = -1;
- while (rv < 0) {
-#ifndef OS2
- printf("more? ");
-#ifdef UNIX
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
-#endif /* UNIX */
-#else
- printf("more? ");
- fflush(stdout);
-#endif /* OS2 */
-
-#ifdef IKSD
- if (inserver) {
- cx = cmdgetc(timelimit);
- if (cx < -1 && timelimit) {
- printf("\n?IKS idle timeout - Goodbye.\n");
- doexit(GOOD_EXIT,0);
- } else if (cx == -1) { /* Connection lost */
- doexit(BAD_EXIT,0);
- }
- c = (char) cx;
- } else {
-#endif /* IKSD */
-#ifdef VMS
- conbin((char)escape); /* Protect against Ctrl-Z */
- cx = coninc(0);
- concb((char)escape);
-#else
- cx = cmdgetc(0);
-#endif /* VMS */
- debug(F101,"askmore cmdgetc","",cx);
- if (cx == EOF) {
- debug(F100,"askmore EOF","",0);
-#ifdef VMS
- c = '\032';
-#else
- c = 'n';
-#endif /* VMS */
- } else {
- c = (char)cx;
- }
- debug(F101,"askmore c","",c);
-
-#ifdef IKSD
- }
-#endif /* IKSD */
- switch (c) {
- /* Yes */
- case 'p': case 'P': case 'g': case 'G': /* Proceed or Go */
- xaskmore = 0;
- /* fall thru on purpose */
-
- case SP: case 'y': case 'Y': case 012: case 015:
-#ifdef OSK
- write(1, "\015 \015", sizeof "\015 \015" - 1);
-#else
- printf("\015 \015");
-#endif /* OSK */
- rv = 1;
- break;
- /* No */
- case 'n': case 'N': case 'q': case 'Q':
-#ifdef OSK
- printf("\n");
-#else
- printf("\015\012");
-#endif /* OSK */
- rv = 0;
- break;
- case '\003':
- case '\004':
- case '\032':
-#ifdef OSK
- printf("^%c...\n", (c + 0100));
-#else
- printf("^%c...\015\012", (c + 0100));
-#endif /* OSK */
- rv = 0;
- break;
- /* Invalid answer */
- default:
- debug(F111,"askmore","invalid answer",c);
- printf("Y or space-bar for yes, N for no, G to show the rest\n");
- continue;
- }
-#ifdef OS2
- printf("\r \r");
- fflush(stdout);
-#endif /* OS2 */
- }
- return(rv);
-#endif /* NOICP */
-}
-
-/* T R A P -- Terminal interrupt handler */
-
-SIGTYP
-#ifdef CK_ANSIC
-trap(int sig)
-#else
-trap(sig) int sig;
-#endif /* CK_ANSIC */
-/* trap */ {
- extern int b_save, f_save;
-#ifndef NOICP
- extern int timelimit;
-#endif /* NOICP */
-#ifdef OS2
- extern unsigned long startflags;
-#ifndef NOSETKEY
- extern int os2gks;
-#endif /* NOSETKEY */
- int i;
-#endif /* OS2 */
-#ifndef NOSPL
- extern int i_active, instatus;
-#endif /* NOSPL */
-#ifdef VMS
- int i; FILE *f;
-#endif /* VMS */
- extern int zchkod, zchkid;
-#ifndef NOSPL
- extern int unkmacro;
-#endif /* NOSPL */
-
- debok = 1;
-#ifdef NTSIG
- connoi();
-#endif /* NTSIG */
-#ifdef __EMX__
- signal(SIGINT, SIG_ACK);
-#endif
-#ifdef GEMDOS
-/* GEM is not reentrant, no i/o from interrupt level */
- cklongjmp(cmjbuf,1); /* Jump back to parser now! */
-#endif /* GEMDOS */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F100,"*********************","",0);
- if (sig == SIGINT)
- debug(F101,"trap caught SIGINT","",sig);
- else
- debug(F101,"trap caught signal","",sig);
- debug(F100,"*********************","",0);
- }
-#endif /* DEBUG */
-
-#ifdef OS2
- if ( sig == SIGBREAK && (startflags & 128) ) {
- debug(F101,"trap ignoring SIGBREAK","",sig);
- return;
- }
-#endif /* OS2 */
-
-#ifndef NOICP
- timelimit = 0; /* In case timed ASK interrupted */
-#ifndef NOSPL
- unkmacro = 0; /* Or ON_UNKNOWN_MACRO interrupted.. */
-#endif /* NOSPL */
-#endif /* NOICP */
- zchkod = 0; /* Or file expansion interrupted... */
- zchkid = 0;
- interrupted = 1;
-
- if (what & W_CONNECT) { /* Are we in CONNECT mode? */
-/*
- The HP workstation Reset key sends some kind of ueber-SIGINT that can not
- be SIG_IGNored, so we wind up here somehow (even though this is *not* the
- current SIGINT handler). Just return.
-*/
- debug(F101,"trap: SIGINT caught during CONNECT","",sig);
- SIGRETURN;
- }
-#ifndef NOSPL
- if (i_active) { /* INPUT command was active? */
- i_active = 0; /* Not any more... */
- instatus = INP_UI; /* INPUT status = User Interrupted */
- }
-#endif /* NOSPL */
-
-#ifndef NOXFER
- ftreset(); /* Restore global protocol settings */
- binary = b_save; /* Then restore these */
- fncnv = f_save;
- bye_active = 0;
- diractive = 0;
- cdactive = 0;
-#endif /* NOXFER */
- zclose(ZIFILE); /* If we were transferring a file, */
- zclose(ZOFILE); /* close it. */
-#ifndef NOICP
- cmdsquo(cmd_quoting); /* If command quoting was turned off */
-#ifdef CKLEARN
- {
- extern FILE * learnfp;
- extern int learning;
- if (learnfp) {
- fclose(learnfp);
- learnfp = NULL;
- learning = 0;
- }
- }
-#endif /* CKLEARN */
-#endif /* NOICP */
-#ifdef CK_APC
- delmac("_apc_commands",1);
- apcactive = APC_INACTIVE;
-#endif /* CK_APC */
-
-#ifdef VMS
-/*
- Fix terminal.
-*/
- if (ft_win) { /* If curses window open */
- debug(F100,"^C trap() curses","",0);
- xxscreen(SCR_CW,0,0L,""); /* Close it */
- conres(); /* Restore terminal */
- i = printf("^C..."); /* Echo ^C to standard output */
- } else {
- conres();
- i = printf("^C...\n"); /* Echo ^C to standard output */
- }
- if (i < 1 && ferror(stdout)) { /* If there was an error */
- debug(F100,"^C trap() error","",0);
- fclose(stdout); /* close standard output */
- f = fopen(dftty, "w"); /* open the controlling terminal */
- if (f) stdout = f; /* and make it standard output */
- printf("^C...\n"); /* and echo the ^C again. */
- }
-#else /* Not VMS */
-#ifdef STRATUS
- conres(); /* Set console back to normal mode */
-#endif /* STRATUS */
-#ifndef NOXFER
- if (ft_win) { /* If curses window open, */
- debug(F100,"^C trap() curses","",0);
- xxscreen(SCR_CW,0,0L,""); /* close it. */
- printf("^C..."); /* Echo ^C to standard output */
- } else {
-#endif /* NOXFER */
- printf("^C...\n");
-#ifndef NOXFER
- }
-#endif /* NOXFER */
-#endif /* VMS */
-#ifdef datageneral
- connoi_mt(); /* Kill asynch task that listens to */
- ttimoff();
- conres(); /* the keyboard */
-#endif /* datageneral */
-
-#ifndef NOCCTRAP
-/* This is stupid -- every version should have ttimoff()... */
-#ifdef UNIX
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef OSK
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef STRATUS
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef OS2
-#ifndef NOSETKEY
- os2gks = 1; /* Turn back on keycode mapping */
-#endif /* NOSETKEY */
-#ifndef NOLOCAL
- for (i = 0; i < VNUM; i++)
- VscrnResetPopup(i);
-#endif /* NOLOCAL */
-#ifdef TCPSOCKET
-#ifdef NT
- /* WSAIsBlocking() returns FALSE in Win95 during a blocking accept call */
- if ( WSASafeToCancel /* && WSAIsBlocking() */ ) {
- WSACancelBlockingCall();
- }
-#endif /* NT */
-#endif /* TCPSOCKET */
-#ifdef CK_NETBIOS
- NCBCancelOutstanding();
-#endif /* CK_NETBIOS */
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef VMS
- ttimoff(); /* Turn off any timer interrupts */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* STRATUS */
-#endif /* OSK */
-#endif /* UNIX */
-
-#ifdef NETPTY
- /* Clean up Ctrl-C out of REDIRECT or external protocol */
- {
- extern PID_T pty_fork_pid;
- extern int pty_master_fd, pty_slave_fd;
- int x;
-
- signal(SIGCHLD,SIG_IGN); /* We don't want this any more */
-
- debug(F101,"trap pty_master_fd","",pty_master_fd);
- if (pty_master_fd > 2) {
- x = close(pty_master_fd);
- debug(F101,"trap pty_master_fd close","",x);
- }
- pty_master_fd = -1;
- debug(F101,"trap pty_slave_fd","",pty_slave_fd);
- if (pty_slave_fd > 2) {
- x = close(pty_slave_fd);
- debug(F101,"trap pty_slave_fd close","",x);
- }
- pty_slave_fd = -1;
- debug(F101,"trap pty_fork_pid","",pty_fork_pid);
- if (pty_fork_pid > 0) {
- x = kill(pty_fork_pid,0); /* See if the fork is really there */
- debug(F111,"trap pty_fork_pid kill 0 errno",ckitoa(x),errno);
- if (x == 0) { /* Seems to be active */
- x = kill(pty_fork_pid,SIGHUP); /* Ask it to clean up & exit */
- debug(F101,"trap pty_fork_pid kill SIGHUP","",x);
- msleep(100);
- errno = 0;
- x = kill(pty_fork_pid,0); /* Is it still there? */
- if (x == 0
-#ifdef ESRCH
- /* This module is not always exposed to <errno.h> */
- || errno != ESRCH
-#endif /* ESRCH */
- ) {
- x = kill(pty_fork_pid,SIGKILL);
- debug(F101,"trap pty_fork_pid kill SIGKILL","",x);
- }
- }
- pty_fork_pid = -1;
- }
- }
-#endif /* NETPTY */
-
-#ifdef OSK
- sigmask(-1);
-/*
- We are in an intercept routine but do not perform a F$RTE (done implicitly
- by rts). We have to decrement the sigmask as F$RTE does. Warning: longjump
- only restores the cpu registers, NOT the fpu registers. So don't use fpu at
- all or at least don't use common fpu (double or float) register variables.
-*/
-#endif /* OSK */
-
-#ifdef NTSIG
- PostCtrlCSem();
-#else /* NTSIG */
- debug(F100,"trap about to longjmp","",0);
-#ifdef NT
- cklongjmp(ckjaddr(cmjbuf),1);
-#else /* NT */
- cklongjmp(cmjbuf,1);
-#endif /* NT */
-#endif /* NTSIG */
-#else /* NOCCTRAP */
-/* No Ctrl-C trap, just exit. */
-#ifdef CK_CURSES /* Curses support? */
- xxscreen(SCR_CW,0,0L,""); /* Close curses window */
-#endif /* CK_CURSES */
- doexit(BAD_EXIT,what); /* Exit poorly */
-#endif /* NOCCTRAP */
- SIGRETURN;
-}
-
-
-/* C K _ T I M E -- Returns pointer to current time. */
-
-char *
-ck_time() {
- static char tbuf[10];
- char *p;
- int x;
-
- ztime(&p); /* "Thu Feb 8 12:00:00 1990" */
- if (!p) /* like asctime()! */
- return("");
- if (*p) {
- for (x = 11; x < 19; x++) /* copy hh:mm:ss */
- tbuf[x - 11] = p[x]; /* to tbuf */
- tbuf[8] = NUL; /* terminate */
- }
- return(tbuf); /* and return it */
-}
-
-/* C C _ C L E A N -- Cleanup after terminal interrupt handler */
-
-#ifdef GEMDOS
-int
-cc_clean() {
- zclose(ZIFILE); /* If we were transferring a file, */
- zclose(ZOFILE); /* close it. */
- printf("^C...\n"); /* Not VMS, no problem... */
-}
-#endif /* GEMDOS */
-
-
-/* S T P T R A P -- Handle SIGTSTP (suspend) signals */
-
-SIGTYP
-#ifdef CK_ANSIC
-stptrap(int sig)
-#else
-stptrap(sig) int sig;
-#endif /* CK_ANSIC */
-/* stptrap */ {
-
-#ifndef NOJC
- int x; extern int cmflgs;
- debug(F101,"stptrap() caught signal","",sig);
- if (!xsuspend) {
- printf("\r\nsuspend disabled\r\n");
-#ifndef NOICP
- if (what & W_COMMAND) { /* If we were parsing commands */
- prompt(xxstring); /* reissue the prompt and partial */
- if (!cmflgs) /* command (if any) */
- printf("%s",cmdbuf);
- }
-#endif /* NOICP */
- } else {
- conres(); /* Reset the console */
-#ifndef OS2
- /* Flush pending output first, in case we are continued */
- /* in the background, which could make us block */
- fflush(stdout);
-
- x = psuspend(xsuspend); /* Try to suspend. */
- if (x < 0)
-#endif /* OS2 */
- printf("Job control not supported\r\n");
- conint(trap,stptrap); /* Rearm the trap. */
- debug(F100,"stptrap back from suspend","",0);
- switch (what) {
- case W_CONNECT: /* If suspended during CONNECT? */
- conbin((char)escape); /* put console back in binary mode */
- debug(F100,"stptrap W_CONNECT","",0);
- break;
-#ifndef NOICP
- case W_COMMAND: /* Suspended in command mode */
- debug(F101,"stptrap W_COMMAND pflag","",pflag);
- concb((char)escape); /* Put back CBREAK tty mode */
- if (pflag) { /* If command parsing was */
- prompt(xxstring); /* reissue the prompt and partial */
- if (!cmflgs) /* command (if any) */
- printf("%s",cmdbuf);
- }
- break;
-#endif /* NOICP */
- default: /* All other cases... */
- debug(F100,"stptrap default","",0);
- concb((char)escape); /* Put it back in CBREAK mode */
- break;
- }
- }
-#endif /* NOJC */
- SIGRETURN;
-}
-
-#ifdef TLOG
-#define TBUFL 300
-
-/* T L O G -- Log a record in the transaction file */
-/*
- Call with a format and 3 arguments: two strings and a number:
- f - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
- s1,s2 - String arguments 0 and 1.
- n - Long, argument 2.
-*/
-VOID
-#ifdef CK_ANSIC
-dotlog(int f, char *s1, char *s2, CK_OFF_T n)
-#else
-dotlog(f,s1,s2,n) int f; CK_OFF_T n; char *s1, *s2;
-#endif /* CK_ANSIC */
-/* dotlog */ {
- static char s[TBUFL];
- extern int tlogfmt;
- char *sp = s; int x;
- if (!s1) s1 = "";
- if (!s2) s2 = "";
-
- if (!tralog) return; /* If no transaction log, don't */
- if (tlogfmt != 1) return;
- switch (f) {
- case F000: /* 0 (special) "s1 n s2" */
- if ((int)strlen(s1) + (int)strlen(s2) + 15 > TBUFL)
- sprintf(sp,"?T-Log string too long");
- else
- sprintf(sp,"%s %s %s",s1,ckfstoa(n),s2);
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F001: /* 1, " n" */
- sprintf(sp," %s",ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F010: /* 2, "[s2]" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if (x + 6 > TBUFL)
- sprintf(sp,"?String too long");
- else sprintf(sp,"[%s]",s2);
- if (zsoutl(ZTFILE,"") < 0) tralog = 0;
- break;
- case F011: /* 3, "[s2] n" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if (x + 6 > TBUFL)
- sprintf(sp,"?String too long");
- else sprintf(sp,"[%s] %s",s2,ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F100: /* 4, "s1" */
- if (zsoutl(ZTFILE,s1) < 0) tralog = 0;
- break;
- case F101: /* 5, "s1: n" */
- if ((int)strlen(s1) + 15 > TBUFL)
- sprintf(sp,"?String too long");
- else sprintf(sp,"%s: %s",s1,ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F110: /* 6, "s1 s2" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if ((int)strlen(s1) + x + 4 > TBUFL)
- sprintf(sp,"?String too long");
- else
- sprintf(sp,"%s%s%s",s1,((*s2 == ':') ? "" : " "),s2);
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F111: /* 7, "s1 s2: n" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if ((int)strlen(s1) + x + 15 > TBUFL)
- sprintf(sp,"?String too long");
- else
- sprintf(sp,"%s%s%s: %s",s1,((*s2 == ':') ? "" : " "),s2,ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- default:
- sprintf(sp,"?Invalid format for tlog() - %d",f);
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- }
-}
-
-/*
- D O X L O G
-
- This is the transaction-log writer for BRIEF format.
- The idea is produce one record (line) per file. Each record
- has the following delimited fields:
- Date (yyyymmdd)
- Time (hh:mm:ss)
- Action: SEND or RECV
- File name
- File size
- Transfer mode (text, binary, image, labeled, etc).
- Status: OK or FAILED
- Free-form comments in doublequotes
- The default separator is comma.
- If a field contains the separator, it is enclosed in doublequotes.
-*/
-VOID
-#ifdef CK_ANSIC
-doxlog(int x, char * fn, CK_OFF_T fs, int fm, int status, char * msg)
-#else
-doxlog(x, fn, fs, fm, status, msg)
- int x; char * fn; CK_OFF_T fs; int fm; int status; char * msg;
-#endif /* CK_ANSIC */
-/* doxlog */ {
- extern int tlogsep;
- char sep[2];
- char buf[CKMAXPATH+256], * bufp;
- char tmpbuf[32];
- char * s, * p;
- int len, left, ftp = 0, k;
-
- if (!tralog) return; /* If no transaction log, don't */
-
- if (!fn) fn = ""; /* Protect against null pointers */
- if (!msg) msg = "";
- if (x & W_FTP)
- ftp++;
-
- sep[0] = (char) tlogsep;
- sep[1] = NUL;
- if (!sep[0]) sep[0] = ',';
-
- bufp = buf;
- left = sizeof(buf);
- debug(F101,"XXX doxlog left 1","",left);
-
- p = zzndate(); /* Date */
- ckmakmsg(buf, left, p ? p : "00000000", sep, NULL, NULL);
- bufp += 9;
- left -= 9;
- debug(F111,"XXX doxlog left 2",buf,left);
-
- ztime(&p);
- ckstrncpy(bufp,p+11,left);
- bufp += 8;
- left -= 8;
- debug(F111,"XXX doxlog left 3",buf,left);
-
- if (ftp) {
- if (!(x & (W_SEND|W_RECV)))
- return;
- s = (x & W_SEND) ? "PUT" : "GET";
- k = 3;
- } else {
- s = (x & W_SEND) ? "SEND" : "RECV";
- k = 4;
- }
- ckmakmsg(bufp,left,sep,s,sep,NULL);
- bufp += k + 2;
- left -= (k + 2);
- debug(F111,"XXX doxlog left 4",buf,left);
-
- s = "";
- if (ckstrchr(fn,sep[0])) /* Filename */
- s = "\"";
- ckmakmsg(bufp,left,s,fn,s,sep);
- sprintf(tmpbuf,"%s",ckfstoa(fs)); /* Size */
- ckstrncat(buf,tmpbuf,CKMAXPATH);
- ckstrncat(buf,sep,CKMAXPATH);
- debug(F110,"doxlog 4",buf,0);
-
-#ifdef NOICP
- /* Transfer mode */
- ckstrncpy(tmpbuf, (binary ? "binary" : "text"), TMPBUFSIZ);
-#else
- ckstrncpy(tmpbuf,gfmode(fm,0),TMPBUFSIZ);
-#endif /* NOICP */
- if (ckstrchr(tmpbuf,sep[0])) { /* Might contain spaces */
- ckstrncat(buf,"\"",CKMAXPATH);
- ckstrncat(buf,tmpbuf,CKMAXPATH);
- ckstrncat(buf,"\"",CKMAXPATH);
- } else
- ckstrncat(buf,tmpbuf,CKMAXPATH);
- ckstrncat(buf,sep,CKMAXPATH);
- debug(F110,"doxlog 5",buf,0);
-
- ckstrncat(buf, status ? "FAILED" : "OK",CKMAXPATH);
- len = strlen(buf);
- left = CKMAXPATH+256 - len;
- if (left < 2) fatal("doxlog buffer overlow");
-
- debug(F111,"XXX doxlog left 5",buf,left);
-
- debug(F110,"doxlog buf 1", buf, len);
- s = buf + len;
- if (status == 0 && left > 32) {
- long cps = 0L;
-#ifdef GFTIMER
- debug(F101,"DOXLOG fpxfsecs","",(long)(fpxfsecs * 1000));
- if (fpxfsecs) cps = (long)((CKFLOAT) fs / fpxfsecs);
- sprintf(s,"%s\"%0.3fsec %ldcps\"",sep,fpxfsecs,cps);
-#else
- if (xfsecs) cps = fs / xfsecs;
- sprintf(s,"%s\"%ldsec %ldcps\"",sep,xfsecs,cps);
-#endif /* GFTIMER */
- } else if ((int)strlen(msg) + 4 < left) {
- sprintf(s,"%s\"%s\"",sep,msg);
- }
- debug(F111,"XXX doxlog left 5",buf,left);
-
- debug(F110,"doxlog 5",buf,0);
- x = zsoutl(ZTFILE,buf);
- debug(F101,"doxlog zsoutl","",x);
- if (x < 0) tralog = 0;
-}
-#endif /* TLOG */
-
-#ifndef MAC
-/*
- The rest of this file is for all implementations but the Macintosh.
-*/
-
-#ifdef CK_CURSES
-static int repaint = 0; /* Transfer display needs repainting */
-#endif /* CK_CURSES */
-
-#ifndef NOXFER
-/* C H K I N T -- Check for console interrupts */
-
-/*
- Used during file transfer in local mode only:
- . If user has not touched the keyboard, returns 0 with no side effects.
- . If user typed S or A (etc, see below) prints status message and returns 0.
- . If user typed X or F (etc, see below) returns 0 with cxseen set to 1.
- . If user typed Z or B (etc, see below) returns 0 with czseen set to 1.
- . If user typed E or C (etc, see below) returns -1.
-*/
-int
-chkint() {
- int ch, cn, ofd; long zz;
- if (!xfrint)
- return(0);
- if ((!local) || (quiet)) return(0); /* Only do this if local & not quiet */
-#ifdef datageneral
- if (con_reads_mt) /* if conint_mt task is active */
- if (conint_avl) { /* and there's an interrupt pending */
- cn = 1; /* process it */
- ch = conint_ch;
- conint_avl = 0; /* turn off flag so conint_mt can */
- } else /* proceed */
- return(0);
- else /* if conint_mt not active */
- if ((ch = coninc(2)) < 0) /* try to get char manually */
- return(0); /* I/O error, or no data */
- else /* if successful, set cn so we */
- cn = 1; /* know we got one */
- debug(F101,"chkint got keyboard character",ch,cn);
-#else /* !datageneral */
-#ifdef NTSIG
- {
- extern int TlsIndex;
- struct _threadinfo * threadinfo;
- threadinfo = (struct _threadinfo *) TlsGetValue(TlsIndex);
- if (threadinfo) {
- if (!WaitSem(threadinfo->DieSem,0))
- return -1; /* Cancel Immediately */
- }
- }
-#endif /* NTSIG */
- cn = conchk(); /* Any input waiting? */
- debug(F101,"conchk","",cn);
- if (cn < 1) return(0);
- ch = coninc(5) ;
- debug(F101,"coninc","",ch);
- if (ch < 0) return(0);
-#endif /* datageneral */
-
- ch &= 0177;
- switch (ch) {
- case 'A': case 'a': case 0001: /* Status report */
- case 'S': case 's':
- if (fdispla != XYFD_R && fdispla != XYFD_S && fdispla != XYFD_N)
- return(0); /* Only for serial, simple or none */
- ofd = fdispla; /* [MF] Save file display type */
- if (fdispla == XYFD_N)
- fdispla = XYFD_R; /* [MF] Pretend serial if no display */
- xxscreen(SCR_TN,0,0l,"Status report:");
- xxscreen(SCR_TN,0,0l," file type: ");
- if (binary) {
- switch(binary) {
- case XYFT_L: xxscreen(SCR_TZ,0,0l,"labeled"); break;
- case XYFT_I: xxscreen(SCR_TZ,0,0l,"image"); break;
- case XYFT_U: xxscreen(SCR_TZ,0,0l,"binary undefined"); break;
- default:
- case XYFT_B: xxscreen(SCR_TZ,0,0l,"binary"); break;
- }
- } else {
-#ifdef NOCSETS
- xxscreen(SCR_TZ,0,0l,"text");
-#else
- xxscreen(SCR_TU,0,0l,"text, ");
- if (tcharset == TC_TRANSP || xfrxla == 0) {
- xxscreen(SCR_TZ,0,0l,"transparent");
- } else {
- if (what & W_SEND) {
- xxscreen(SCR_TZ,0,0l,tcsinfo[tcharset].keyword);
- xxscreen(SCR_TU,0,0l," => ");
- xxscreen(SCR_TZ,0,0l,fcsinfo[fcharset].keyword);
- } else {
- xxscreen(SCR_TZ,0,0l,fcsinfo[fcharset].keyword);
- xxscreen(SCR_TU,0,0l," => ");
- xxscreen(SCR_TZ,0,0l,tcsinfo[tcharset].keyword);
- }
- }
-#endif /* NOCSETS */
- }
- xxscreen(SCR_QE,0,filcnt," file number");
- if (fsize) xxscreen(SCR_QE,0,fsize," size");
- xxscreen(SCR_QE,0,ffc," characters so far");
- if (fsize > 0L) {
-#ifdef CK_RESEND
- zz = what & W_SEND ? sendstart : what & W_RECV ? rs_len : 0;
- zz = ( (ffc + zz) * 100L ) / fsize;
-#else
- zz = ( ffc * 100L ) / fsize;
-#endif /* CK_RESEND */
- xxscreen(SCR_QE,0,zz, " percent done");
- }
- if (bctu == 4) { /* Block check */
- xxscreen(SCR_TU,0,0L," block check: ");
- xxscreen(SCR_TZ,0,0L,"blank-free-2");
- } else xxscreen(SCR_QE,0,(long)bctu, " block check");
- xxscreen(SCR_QE,0,(long)rptflg," compression");
- xxscreen(SCR_QE,0,(long)ebqflg," 8th-bit prefixing");
- xxscreen(SCR_QE,0,(long)lscapu," locking shifts");
- if (!network)
- xxscreen(SCR_QE,0, speed, " speed");
- if (what & W_SEND)
-
- xxscreen(SCR_QE,0,spsiz, " packet length");
- else if (what & W_RECV || what & W_REMO)
- xxscreen(SCR_QE,0,urpsiz," packet length");
- xxscreen(SCR_QE,0,wslots, " window slots");
- fdispla = ofd; /* [MF] Restore file display type */
- return(0);
-
- case 'B': case 'b': case 0002: /* Cancel batch */
- case 'Z': case 'z': case 0032:
- czseen = 1;
- interrupted = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- (((what & W_RECV) && (wslots > 1)) ?
- "Canceling batch, wait... " :
- "Canceling batch... ")
- );
- return(0);
-
- case 'F': case 'f': case 0006: /* Cancel file */
- case 'X': case 'x': case 0030:
- cxseen = 1;
- interrupted = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- (((what & W_RECV) && (wslots > 1)) ?
- "Canceling file, wait... " :
- "Canceling file... ")
- );
- return(0);
-
- case 'R': case 'r': case 0022: /* Resend packet */
- case 0015: case 0012:
-#ifdef STREAMING
- if (streaming)
- return(0);
-#endif /* STREAMING */
- xxscreen(SCR_ST,ST_MSG,0l,"Resending packet... ");
- numerrs++;
- resend(winlo);
- return(0);
-
-#ifdef datageneral
- case '\03': /* We're not trapping ^C's with */
- trap(0); /* signals, so we check here */
-#endif /* datageneral */
-
- case 'C': case 'c': /* Ctrl-C */
-#ifndef datageneral
- case '\03':
-#endif /* datageneral */
-
- case 'E': case 'e': /* Send error packet */
- case 0005:
- interrupted = 1;
- return(-1);
-
-#ifdef CK_CURSES
- case 0014: /* Ctrl-L to refresh screen */
- case 'L': case 'l': /* Also accept L (upper, lower) */
- case 0027: /* Ctrl-W synonym for VMS & Ingres */
- repaint = 1;
- return(0);
-#endif /* CK_CURSES */
-
- case 'T':
- case 't': /* Turn on debug-log timestamps */
-#ifdef DEBUG
- {
- extern int debtim;
- if (ch == 'T') {
- debtim = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- "Debug timestamps On... ");
- } else {
- debtim = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- "Debug timestamps Off... ");
- }
- }
-#endif /* DEBUG */
- return(0);
-
- case 'D':
-#ifdef DEBUG
- if (!deblog) {
- debopn("debug.log",0);
- if (deblog) {
- xxscreen(SCR_ST,ST_MSG,0l,"debug.log open... ");
- } else {
- xxscreen(SCR_ST,ST_MSG,0l,"debug.log open FAILED... ");
- }
- } else {
- xxscreen(SCR_ST,ST_MSG,0l,"Debug log On... ");
- }
- if (deblog)
- debok = 1;
-#endif /* DEBUG */
- return(0);
-
- case 'd': /* Turn off debugging */
-#ifdef DEBUG
- if (deblog)
- xxscreen(SCR_ST,ST_MSG,0l,"Debug log Off... ");
- debok = 0;
-#endif /* DEBUG */
- return(0);
-
- default: /* Anything else, print message */
- intmsg(1L);
- return(0);
- }
-}
-
-/* I N T M S G -- Issue message about terminal interrupts */
-
-VOID
-#ifdef CK_ANSIC
-intmsg(long n)
-#else
-intmsg(n) long n;
-#endif /* CK_ANSIC */
-/* intmsg */ {
-#ifdef CK_NEED_SIG
- char buf[80];
-#endif /* CK_NEED_SIG */
-
- if (!displa || quiet) /* Not if we're being quiet */
- return;
- if (server && (!srvdis || n > -1L)) /* Special for server */
- return;
-#ifdef CK_NEED_SIG
- buf[0] = NUL; /* Keep compilers happy */
-#endif /* CK_NEED_SIG */
-#ifndef OXOS
-#ifdef SVORPOSIX
- conchk(); /* Clear out pending escape-signals */
-#endif /* SVORPOSIX */
-#endif /* ! OXOS */
-#ifdef VMS
- conres(); /* So Ctrl-C will work */
-#endif /* VMS */
- if ((!server && n == 1L) || (server && n < 0L)) {
-
-#ifdef CK_NEED_SIG
- if (xfrint) {
- ckmakmsg(buf,
- 80,
- "Type escape character (",
- dbchr(escape),
- ") followed by:",
- NULL
- );
- xxscreen(SCR_TN,0,0l,buf);
- }
-#endif /* CK_NEED_SIG */
-
- if (xfrint) {
- if (protocol == PROTO_K) {
- xxscreen(SCR_TN,0,0l,"X to cancel file, CR to resend current packet");
- xxscreen(SCR_TN,0,0l,"Z to cancel group, A for status report");
- xxscreen(SCR_TN,0,0l,"E to send Error packet, Ctrl-C to quit immediately: ");
- } else {
- xxscreen(SCR_TN,0,0l,"Ctrl-C to cancel file transfer: ");
- }
- } else {
- xxscreen(SCR_TN,0,0l,"Transfer interruption disabled. ");
- }
- }
- else xxscreen(SCR_TU,0,0l," ");
-}
-
-#ifndef NODISPLAY
-static int newdpy = 0; /* New display flag */
-static char fbuf[80]; /* Filename buffer */
-static char abuf[80]; /* As-name buffer */
-static char a2buf[80]; /* Second As-name buffer */
-static CK_OFF_T oldffc = 0L;
-static CK_OFF_T dots = 0L;
-static int hpos = 0;
-
-static VOID /* Initialize Serial or CRT display */
-dpyinit() {
- int m = 0, n = 0;
- char * s = "";
-
- newdpy = 0; /* Don't do this again */
- oldffc = (CK_OFF_T)0; /* Reset this */
- dots = (CK_OFF_T)0; /* and this.. */
- oldcps = cps = 0L;
-
- conoll(""); /* New line */
- if (what & W_SEND) s = "Sending: "; /* Action */
- else if (what & W_RECV) s = "Receiving: ";
- n = (int)strlen(s) + (int)strlen(fbuf);
- conol(fbuf);
- m = (int)strlen(abuf) + 4;
- if (n + m > cmd_cols) {
- conoll("");
- n = 0;
- } else
- n += m;
- if (*abuf) {
- conol(" => ");
- conol(abuf);
- }
- m = (int)strlen(a2buf) + 4;
- if (n + m > cmd_cols) {
- conoll("");
- n = 0;
- } else
- n += m;
- if (*a2buf) {
- conol(" => ");
- conol(a2buf);
- }
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- conoll("");
- if (fsize > (CK_OFF_T)-1) { /* Size */
- sprintf(fbuf,"Size: %s, Type: ",ckfstoa(fsize)); /* SAFE (80) */
- conol(fbuf); *fbuf = NUL;
- } else conol("Size: unknown, Type: ");
- if (binary) { /* Type */
- switch(binary) {
- case XYFT_L: conol("labeled"); break;
- case XYFT_I: conol("image"); break;
- case XYFT_U: conol("binary undefined"); break;
- default:
- case XYFT_B: conol("binary"); break;
- }
- } else {
-#ifdef NOCSETS
- conol("text");
-#else
- conol("text, ");
- if (tcharset == TC_TRANSP || xfrxla == 0) {
- conol("transparent");
- } else {
- if (what & W_SEND) {
- conol(fcsinfo[fcharset].keyword);
- conol(" => ");
- conol(tcsinfo[tcharset].keyword);
- } else {
- conol(tcsinfo[tcharset].keyword);
- conol(" => ");
- conol(fcsinfo[fcharset].keyword);
- }
- }
-#endif /* NOCSETS */
- }
-#ifdef STREAMING
- if (streaming)
- conol(", STREAMING");
-#endif /* STREAMING */
- conoll("");
-
- if (fdispla == XYFD_S) { /* CRT field headings */
-/*
- Define CK_CPS to show current transfer rate.
- Leave it undefined to show estimated time remaining.
- Estimated-time-remaining code from Andy Fyfe, not tested on
- pathological cases.
-*/
-#define CK_CPS
-
-#ifdef CK_CPS
- conoll(" File Percent Packet");
- conoll(" Bytes Done CPS Length");
-#else
- conoll(" File Percent Secs Packet");
- conoll(" Bytes Done Left Length");
-#endif /* CK_CPS */
- newdpy = 0;
- }
- hpos = 0;
-}
-
-/*
- showpkt(c)
- c = completion code: 0 means transfer in progress, nonzero means it's done.
- Show the file transfer progress counter and perhaps verbose packet type.
-*/
-VOID
-#ifdef CK_ANSIC
-showpkt(char c)
-#else
-showpkt(c) char c;
-#endif /* CK_ANSIC */
-/* showpkt */ {
-
-#ifndef GFTIMER
- long et; /* Elapsed time, entire batch */
-#endif /* GFTIMER */
- CK_OFF_T howfar; /* How far into file */
- long pd; /* Percent done, this file */
- long tp; /* Transfer rate, entire batch */
- long ps; /* Packet size, current packet */
- CK_OFF_T mytfc; /* Local copy of byte counter */
-
-#ifdef GFTIMER
- CKFLOAT tnow;
-#endif /* GFTIMER */
-
- if (newdpy) /* Put up filenames, etc, */
- dpyinit(); /* if they're not there already. */
-
- howfar = ffc; /* How far */
-/*
- Calculate CPS rate even if not displaying on screen for use in file
- transfer statistics.
-*/
-#ifdef GFTIMER
- tnow = gftimer(); /* Time since we started */
- ps = (what & W_RECV) ? rpktl : spktl; /* Packet size */
-#ifdef CK_RESEND
- if (what & W_SEND) /* In case we didn't start at */
- howfar += sendstart; /* the beginning... */
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- pd = -1; /* Percent done. */
- if (c == NUL) { /* Still going, figure % done */
- if (!fsize) return; /* Empty file, don't bother */
- pd = (fsize > 99) ? (howfar / (fsize / (CK_OFF_T)100)) : 0;
- if (pd > 100) pd = 100; /* Expansion */
- }
- if (c != NUL)
- if (!cxseen && !discard && !czseen)
- pd = 100; /* File complete, so 100%. */
-
- mytfc = (pd < 100) ? tfc + ffc : tfc; /* CPS */
- tp = (long)((tnow > 0.0) ? (CKFLOAT) mytfc / tnow : 0);
- if (c && (tp == 0))
- tp = ffc;
-
- cps = tp; /* Set global variable */
- if (cps > peakcps && /* Peak transfer rate */
- ((what & W_SEND && spackets > wslots + 4) ||
- (!(what & W_SEND) && spackets > 10))) {
- peakcps = cps;
- }
-
-#else /* Not GFTIMER */
-
- et = gtimer(); /* Elapsed time */
- ps = (what & W_RECV) ? rpktl : spktl; /* Packet length */
-#ifdef CK_RESEND
- if (what & W_SEND) /* And if we didn't start at */
- howfar += sendstart; /* the beginning... */
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- pd = -1; /* Percent done. */
- if (c == NUL) { /* Still going, figure % done */
- if (fsize == 0L) return; /* Empty file, don't bother */
- pd = (fsize > 99) ? (howfar / (fsize / (CK_OFF_T)100)) : 0;
- if (pd > 100) pd = 100; /* Expansion */
- }
- if (c != NUL)
- if (!cxseen && !discard && !czseen)
- pd = 100; /* File complete, so 100%. */
-
-
-#ifndef CK_CPS
-/*
- fsecs = time (from gtimer) that this file started (set in sfile()).
- Rate so far is ffc / (et - fsecs), estimated time for remaining bytes
- is (fsize - ffc) / (ffc / (et - fsecs)).
-*/
- tp = (howfar > 0) ? (fsize - howfar) * (et - fsecs) / howfar : 0;
-#endif /* CK_CPS */
-
-#ifdef CK_CPS
- mytfc = (pd < 100) ? tfc + ffc : tfc;
- tp = (et > 0) ? mytfc / et : 0; /* Transfer rate */
- if (c && (tp == 0)) /* Watch out for subsecond times */
- tp = ffc;
-
- cps = tp; /* Set global variable */
- if (cps > peakcps && /* Peak transfer rate */
- ((what & W_SEND && spackets > wslots + 4) ||
- (!(what & W_SEND) && spackets > 10))) {
- peakcps = cps;
- }
-#endif /* CK_CPS */
-
-#endif /* GFTIMER */
-
- if (fdispla == XYFD_S) { /* CRT display */
- char buffer[128];
- /* These sprintfs should be safe until we have 32-digit numbers */
-
- if (pd > -1L)
- sprintf(buffer, "%c%9s%5ld%%%8ld%8ld ", CR,ckfstoa(howfar),pd,tp,ps);
- else
- sprintf(buffer, "%c%9s %8ld%8ld ", CR,ckfstoa(howfar),tp,ps);
- conol(buffer);
- hpos = 31;
- } else if (fdispla == XYFD_R) { /* SERIAL */
- long i, k;
- if (howfar - oldffc < 1024) /* Update display every 1K */
- return;
- oldffc = howfar; /* Time for new display */
- k = (howfar / 1024L) - dots; /* How many K so far */
- for (i = 0L; i < k; i++) {
- if (hpos++ > (cmd_cols - 3)) { /* Time to wrap? */
- conoll("");
- hpos = 0;
- }
- conoc('.'); /* Print a dot for this K */
- dots++; /* Count it */
- }
- }
-}
-
-
-/* C K S C R E E N -- Screen display function */
-
-/*
- ckscreen(f,c,n,s)
- f - argument descriptor
- c - a character or small integer
- n - a long integer
- s - a string.
-
- and global fdispla = SET FILE DISPLAY value:
-
- XYFD_N = NONE
- XYFD_R = SERIAL: Dots, etc, works on any terminal, even hardcopy.
- XYFD_S = CRT: Works on any CRT, writes over current line.
- XYFD_C = FULLSCREEN: Requires terminal-dependent screen control.
- XYFD_B = BRIEF: Like SERIAL but only filename & completion status.
- XYFD_G = GUI; Windows GUI, same behavior as FULLSCREEN
-*/
-VOID
-#ifdef CK_ANSIC
-ckscreen(int f, char c,CK_OFF_T n,char *s)
-#else
-ckscreen(f,c,n,s) int f; char c; CK_OFF_T n; char *s;
-#endif /* CK_ANSIC */
-/* screen */ {
- char buf[80];
- int len; /* Length of string */
-#ifdef UNIX
-#ifndef NOJC
- int obg;
-_PROTOTYP( VOID conbgt, (int) );
-#endif /* NOJC */
-#endif /* UNIX */
- int ftp = 0;
-
- ftp = (what & W_FTP) ? 1 : 0; /* FTP or Kermit? */
-
- if (!local && !ftp) /* In remote mode - don't do this */
- return;
-
- if (!s) s = "";
-
- if (!fxd_inited) /* Initialize if necessary */
- fxdinit(fdispla);
-
-#ifdef UNIX
-#ifndef NOJC
- obg = backgrd; /* Previous background status */
- conbgt(1); /* See if running in background */
- if (!backgrd && obg) { /* Just came into foreground? */
- concb((char)escape); /* Put console back in CBREAK mode */
- setint(); /* Restore interrupts */
- }
-#endif /* NOJC */
-#endif /* UNIX */
-
- if ((f != SCR_WM) && (f != SCR_EM)) /* Always update warnings & errors */
- if (!displa ||
- (backgrd && bgset) ||
- fdispla == XYFD_N ||
- (server && !srvdis)
- )
- return;
-
-#ifdef VMS
- if (f == SCR_FN) /* VMS - shorten the name */
- s = zrelname(s,zgtdir());
-#endif /* VMS */
-
- if (dest == DEST_S) /* SET DESTINATION SCREEN */
- return; /* would interfere... */
-
-#ifdef KUI
- if (fdispla == XYFD_G) { /* If gui display selected */
- screeng(f,c,n,s); /* call the gui version */
- return;
- }
-#endif /* KUI */
-#ifdef CK_CURSES
- if (fdispla == XYFD_C) { /* If fullscreen display selected */
- screenc(f,c,n,s); /* call the fullscreen version */
- return;
- }
-#endif /* CK_CURSES */
-
- len = (int)strlen(s); /* Length of string */
-
- switch (f) { /* Handle our function code */
- case SCR_FN: /* Filename */
- if (fdispla == XYFD_B) {
-#ifdef NEWFTP
- if (ftp)
- printf(" %s %s", what & W_SEND ? "PUT" : "GET", s);
- else
-#endif /* NEWFTP */
- printf(" %s %s", what & W_SEND ? "SEND" : "RECV", s);
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- return;
- }
-#ifdef MAC
- conoll(""); conol(s); conoc(SP); hpos = len + 1;
-#else
- ckstrncpy(fbuf,s,80);
- abuf[0] = a2buf[0] = NUL;
- newdpy = 1; /* New file so refresh display */
-#endif /* MAC */
- return;
-
- case SCR_AN: /* As-name */
- if (fdispla == XYFD_B) {
-#ifdef COMMENT
- printf("(as %s) ",s);
-#endif /* COMMENT */
- return;
- }
-#ifdef MAC
- if (hpos + len > 75) { conoll(""); hpos = 0; }
- conol("=> "); conol(s);
- if ((hpos += (len + 3)) > 78) { conoll(""); hpos = 0; }
-#else
- if (abuf[0]) {
- ckstrncpy(a2buf,s,80);
- } else {
- ckstrncpy(abuf,s,80);
- }
-#endif /* MAC */
- return;
-
- case SCR_FS: /* File-size */
- if (fdispla == XYFD_B) {
- printf(" (%s) (%s byte%s)",
-#ifdef NOICP
- (binary ? "binary" : "text")
-#else
- gfmode(binary,0)
-#endif /* NOICP */
- , ckfstoa(n), n == 1 ? "" : "s");
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- return;
- }
-#ifdef MAC
- sprintf(buf,", Size: %s",ckfstoa(n)); conoll(buf); hpos = 0;
-#endif /* MAC */
- return;
-
- case SCR_XD: /* X-packet data */
- if (fdispla == XYFD_B)
- return;
-#ifdef MAC
- conoll(""); conoll(s); hpos = 0;
-#else
- ckstrncpy(fbuf,s,80);
- abuf[0] = a2buf[0] = NUL;
-#endif /* MAC */
- return;
-
- case SCR_ST: /* File status */
- switch (c) {
- case ST_OK: /* Transferred OK */
- showpkt('Z'); /* Update numbers one last time */
- if (fdispla == XYFD_B) {
-#ifdef GFTIMER
- if (fpxfsecs)
- printf(": OK (%0.3f sec, %ld cps)",fpxfsecs,
- (long)((CKFLOAT)ffc / fpxfsecs));
-#else
- if (xfsecs)
- printf(": OK (%d sec, %ld cps)",xfsecs,ffc/xfsecs);
-#endif /* GFTIMER */
- printf("\n");
- return;
- }
- if ((hpos += 5) > 78) conoll(""); /* Wrap screen line. */
- conoll(" [OK]"); hpos = 0; /* Print OK message. */
- if (fdispla == XYFD_S) { /* We didn't show Z packet when */
- conoc('Z'); /* it came, so show it now. */
- hpos = 1;
- }
- return;
-
- case ST_DISC: /* Discarded */
- if (fdispla == XYFD_B) {
- printf(": DISCARDED\n");
- return;
- }
- if ((hpos += 12) > 78) conoll("");
- conoll(" [discarded]"); hpos = 0;
- return;
-
- case ST_INT: /* Interrupted */
- if (fdispla == XYFD_B) {
- printf(": INTERRUPTED\n");
- return;
- }
- if ((hpos += 14) > 78) conoll("");
- conoll(" [interrupted]"); hpos = 0;
- return;
-
- case ST_SIM:
- if (fdispla == XYFD_B) {
- if (n == SKP_XNX)
- printf(": WOULD BE TRANSFERRED (New file)\n");
- else if (n == SKP_XUP)
- printf(": WOULD BE TRANSFERRED (Remote file older)\n");
- else if (n == SKP_SIM)
- printf(": WOULD BE TRANSFERRED\n");
- else if (n > 0 && n < nskreason)
- printf(": SKIPPED (%s)\n",skreason[n]);
- else
- printf(": SKIPPED\n");
- return;
- } else if (fdispla == XYFD_S) {
- if (fdispla == XYFD_S && fbuf[0]) { /* CRT display */
- conoll(""); /* New line */
- if (what & W_SEND) conol("Would Send: "); /* Action */
- else if (what & W_RECV) conol("Would Receive: ");
- conol(fbuf);
- if (*abuf) conol(" => "); conol(abuf); /* Names */
- if (*a2buf) conol(" => "); conol(a2buf); /* Names */
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- }
- conoll(" [simulated]");
- return;
- }
- if ((hpos += 10) > 78) conoll("");
- conol(" [simulated]"); hpos = 0;
- return;
-
- case ST_SKIP: /* Skipped */
- if (fdispla == XYFD_B) {
- if (n == SKP_XNX)
- printf(": WOULD BE TRANSFERRED (New file)\n");
- else if (n == SKP_XUP)
- printf(": WOULD BE TRANSFERRED (Remote file older)\n");
- else if (n == SKP_SIM)
- printf(": WOULD BE TRANSFERRED\n");
- else if (n > 0 && n < nskreason)
- printf(": SKIPPED (%s)\n",skreason[n]);
- else
- printf(": SKIPPED\n");
- return;
- } else if (fdispla == XYFD_S) {
- if (fdispla == XYFD_S && fbuf[0]) { /* CRT display */
- conoll(""); /* New line */
- if (what & W_SEND) conol("Sending: "); /* Action */
- else if (what & W_RECV) conol("Receiving: ");
- conol(fbuf);
- if (*abuf) conol(" => "); conol(abuf); /* Names */
- if (*a2buf) conol(" => "); conol(a2buf); /* Names */
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- }
- conoll(" [skipped]");
- return;
- }
- if ((hpos += 10) > 78) conoll("");
- conol(" "); conol(fbuf);
- conoll(" [skipped]"); hpos = 0;
- return;
-
- case ST_ERR: /* Error */
- if (fdispla == XYFD_B) {
- printf(": ERROR: %s\n",s);
- return;
- }
- conoll("");
- conol("Error: "); conoll(s); hpos = 0;
- return;
-
- case ST_MSG: /* Message */
-#ifdef NEWFTP
- if (fdispla == XYFD_B) {
- if (ftp && ftp_deb)
- printf(": MESSAGE: %s\n",s);
- return;
- }
-#endif /* NEWFTP */
- conoll("");
- conol("Message: ");
- conoll(s);
- hpos = 0;
- return;
-
- case ST_REFU: /* Refused */
- if (fdispla == XYFD_B) {
- printf(": REFUSED\n");
- return;
- } else if (fdispla == XYFD_S) {
- if (fdispla == XYFD_S && fbuf[0]) { /* CRT display */
- conoll(""); /* New line */
- if (what & W_SEND) conol("Sending: "); /* Action */
- else if (what & W_RECV) conol("Receiving: ");
- conol(fbuf);
- if (*abuf) conol(" => "); conol(abuf); /* Names */
- if (*a2buf) conol(" => "); conol(a2buf); /* Names */
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- conoll("");
- }
- conol("Refused: "); conoll(s);
- return;
- }
- conoll("");
- conol("Refused: "); conoll(s); hpos = 0;
- return;
-
- case ST_INC: /* Incomplete */
- if (fdispla == XYFD_B) {
- printf(": INCOMPLETE\n");
- return;
- }
- if ((hpos += 12) > 78) conoll("");
- conoll(" [incomplete]"); hpos = 0;
- return;
-
- default:
- conoll("*** screen() called with bad status ***");
- hpos = 0;
- return;
- }
-
-#ifdef MAC
- case SCR_PN: /* Packet number */
- if (fdispla == XYFD_B) {
- return;
- }
- ckmakmsg(buf,80,s,": ",ckltoa(n),NULL);
- conol(buf); hpos += (int)strlen(buf); return;
-#endif /* MAC */
-
- case SCR_PT: /* Packet type or pseudotype */
- if (fdispla == XYFD_B)
- return;
- if (c == 'Y') return; /* Don't bother with ACKs */
- if (c == 'D') { /* In data transfer phase, */
- showpkt(NUL); /* show progress. */
- return;
- }
-#ifndef AMIGA
- if (hpos++ > 77) { /* If near right margin, */
- conoll(""); /* Start new line */
- hpos = 0; /* and reset counter. */
- }
-#endif /* AMIGA */
- if (c == 'Z' && fdispla == XYFD_S)
- return;
- else
- conoc(c); /* Display the packet type. */
-#ifdef AMIGA
- if (c == 'G') conoll(""); /* New line after G packets */
-#endif /* AMIGA */
- return;
-
- case SCR_TC: /* Transaction complete */
- if (xfrbel) bleep(BP_NOTE);
- if (fdispla == XYFD_B) { /* Brief display... */
- if (filcnt > 1) {
- long fx;
- fx = filcnt - filrej;
- printf(" SUMMARY: %ld file%s", fx, ((fx == 1) ? "" : "s"));
- printf(", %s byte%s", ckfstoa(tfc), ((tfc == 1) ? "" : "s"));
-#ifdef GFTIMER
- printf(", %0.3f sec, %ld cps", fptsecs, tfcps);
-#else
- printf(", %ld sec, %ld cps", tsecs, tfcps);
-#endif /* GFTIMER */
- printf(".\n");
- }
- } else {
- conoll("");
- }
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- return;
-
- case SCR_EM: /* Error message */
- if (fdispla == XYFD_B) {
- printf(" ERROR: %s\n",s);
- return;
- }
- conoll(""); conoc('?'); conoll(s); hpos = 0; return;
-
- case SCR_WM: /* Warning message */
- if (fdispla == XYFD_B) {
- printf(" WARNING: %s\n",s);
- return;
- }
- conoll(""); conoll(s); hpos = 0; return;
-
- case SCR_MS: /* Message from other Kermit */
- if (fdispla == XYFD_B) {
- printf(" MESSAGE: %s\n",s);
- return;
- }
- conoll(""); conoll(s); hpos = 0; return;
-
- case SCR_TU: /* Undelimited text */
- if (fdispla == XYFD_B)
- return;
- if ((hpos += len) > 77) { conoll(""); hpos = len; }
- conol(s); return;
-
- case SCR_TN: /* Text delimited at beginning */
- if (fdispla == XYFD_B)
- return;
- conoll(""); conol(s); hpos = len; return;
-
- case SCR_TZ: /* Text delimited at end */
- if (fdispla == XYFD_B)
- return;
- if ((hpos += len) > 77) { conoll(""); hpos = len; }
- conoll(s); return;
-
- case SCR_QE: /* Quantity equals */
- if (fdispla == XYFD_B)
- return;
- ckmakmsg(buf,80,s,": ",ckltoa(n),NULL);
- conoll(buf); hpos = 0; return;
-
- case SCR_CW: /* Close fullscreen window */
- return; /* No window to close */
-
- case SCR_CD:
- return;
-
- default:
- conoll("*** screen() called with bad object ***");
- hpos = 0;
- return;
- }
-}
-#endif /* NODISPLAY */
-
-/* E R M S G -- Nonfatal error message */
-
-/* Should be used only for printing the message text from an Error packet. */
-
-VOID
-ermsg(msg) char *msg; { /* Print error message */
- debug(F110,"ermsg",msg,0);
- if (local)
- xxscreen(SCR_EM,0,0L,msg);
- tlog(F110,"Protocol Error:",msg,0L);
-}
-#endif /* NOXFER */
-
-VOID
-setseslog(x) int x; {
- seslog = x;
-#ifdef KUI
- KuiSetProperty(KUI_TERM_CAPTURE,x,0);
-#endif /* KUI */
-}
-
-VOID
-doclean(fc) int fc; { /* General cleanup */
-#ifdef OS2ORUNIX
- extern int ttyfd;
-#endif /* OS2ORUNIX */
- extern int keep;
- extern int exithangup;
-#ifndef NOXFER
- extern char filnam[];
-#endif /* NOXFER */
-#ifndef NOICP
- int x;
-
- if (fc > 0)
- dostop(); /* Stop all command files and end macros */
-#endif /* NOICP */
-
-#ifndef NOXFER
- if (pktlog) {
- *pktfil = '\0';
- pktlog = 0;
- zclose(ZPFILE);
- }
-#endif /* NOXFER */
- if (seslog) {
- *sesfil = '\0';
- setseslog(0);
- zclose(ZSFILE);
- }
-#ifdef TLOG
- if (tralog) {
- tlog(F100,"Transaction Log Closed","",0L);
- *trafil = '\0';
- tralog = 0;
- zclose(ZTFILE);
- }
-#endif /* TLOG */
-
- debug(F100,"doclean calling dologend","",0);
- dologend(); /* End current log record if any */
-#ifdef COMMENT
- if (dialog) { /* If connection log open */
- dialog = 0;
- *diafil = '\0'; /* close it. */
- zclose(ZDIFIL);
- }
-#endif /* COMMENT */
-
-#ifndef NOICP
-#ifndef NOSPL
- zclose(ZRFILE); /* READ and WRITE files, if any. */
- zclose(ZWFILE);
-#ifndef NOXFER
- zclose(ZIFILE); /* And other files too */
- x = chkfn(ZOFILE); /* Download in progress? */
- debug(F111,"doclean chkfn ZOFILE",filnam,x);
- debug(F111,"doclean keep","",keep);
- zclose(ZOFILE); /* Close output file */
- if (x > 0 && !keep) { /* If it was being downloaded */
- if (filnam[0])
- x = zdelet(filnam); /* Delete if INCOMPLETE = DISCARD */
- debug(F111,"doclean download filename",filnam,x);
- }
-#endif /* NOXFER */
- zclose(ZSYSFN);
- zclose(ZMFILE);
-
- if (fc < 1) { /* RESETing, not EXITing */
-#ifdef DEBUG
- if (deblog) { /* Close the debug log. */
- *debfil = '\0';
- deblog = 0;
- zclose(ZDFILE);
- }
-#endif /* DEBUG */
- return;
- }
-#endif /* NOSPL */
-#endif /* NOICP */
-
-#ifndef NOLOCAL
- debug(F101,"doclean exithangup","",exithangup);
- if (local && exithangup) { /* Close communication connection */
- extern int haslock;
- int x;
-
- x = ttchk();
- debug(F101,"doclean ttchk()","",x);
-#ifdef OS2ORUNIX
- debug(F101,"doclean ttyfd","",ttyfd);
-#endif /* OS2ORUNIX */
- if (x >= 0
-#ifdef OS2
- || ttyfd != -1
-#else
-#ifdef UNIX
- || haslock /* Make sure we get lockfile! */
- || (!network && ttyfd > -1)
-#endif /* UNIX */
-#endif /* OS2 */
- ) {
- extern int wasclosed, whyclosed;
- debug(F100,"doclean hanging up and closing","",0);
- if (msgflg) {
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- printf("Closing %s...",ttname);
- }
-#ifndef NODIAL
- mdmhup(); /* Hangup the modem??? */
-#endif /* NODIAL */
- ttclos(0); /* Close external line, if any */
- if (msgflg) {
- printf("OK\n");
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- }
- if (wasclosed) {
- whyclosed = WC_CLOS;
-#ifndef NOSPL
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_close",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- wasclosed = 0;
- /* printf("ON_CLOSE DOCLEAN\n"); */
- *(mactab[k].kwd) = NUL; /* See comment below */
- if (dodo(k,ckitoa(whyclosed),0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
-#endif /* NOSPL */
- wasclosed = 0;
- }
- }
- ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty */
- local = dfloc; /* And default remote/local status */
- }
-#ifdef DEBUG
- else if (local) debug(F100,"doclean hangup/close skipped","",0);
-#endif /* DEBUG */
-#endif /* NOLOCAL */
-
-#ifdef NEWFTP
- ftpbye(); /* If FTP connection open, close it */
-#endif /* NEWFTP */
-
-#ifdef IKSD
- if (inserver)
- ttclos(0); /* If IKSD, close socket */
-#endif /* IKSD */
-
-#ifndef NOSPL
-/*
- If a macro named "on_exit" is defined, execute it. Also remove it from the
- macro table, in case its definition includes an EXIT or QUIT command, which
- would cause much recursion and would prevent the program from ever actually
- EXITing.
-*/
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- char * cmd = "on_exit"; /* MSVC 2.x compiler error */
- k = mlook(mactab,cmd,nmac); /* Look up "on_exit" */
- if (k >= 0) { /* If found, */
-#ifdef COMMENT
- /* This makes a mess if ON_EXIT itself executes macros */
- *(mactab[k].kwd) = NUL; /* poke its name from the table, */
-#else
- /* Replace the keyword with something that doesn't wreck the */
- /* order of the keyword table */
- ckstrncpy(mactab[k].kwd,"on_exxx",8);
-#endif /* COMMENT */
- if (dodo(k,"",0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
-#endif /* NOSPL */
-/*
- Put console terminal back to normal. This is done here because the
- ON_EXIT macro calls the parser, which meddles with console terminal modes.
-*/
- conres(); /* Restore console terminal. */
-
-#ifdef COMMENT
-/* Should be no need for this, and maybe it's screwing things up? */
- connoi(); /* Turn off console interrupt traps */
-#endif /* COMMENT */
-
- /* Delete the Startup File if we are supposed to. */
-#ifndef NOICP
- {
- extern int DeleteStartupFile;
- debug(F111,"doclean DeleteStartupFile",cmdfil,DeleteStartupFile);
- if (DeleteStartupFile) {
- int rc = zdelet(cmdfil);
- debug(F111,"doclean zdelet",cmdfil,rc);
- }
- }
-#endif /* NOICP */
- syscleanup(); /* System-dependent cleanup, last */
-}
-
-/* D O E X I T -- Exit from the program. */
-
-/*
- First arg is general, system-independent symbol: GOOD_EXIT or BAD_EXIT.
- If second arg is -1, take 1st arg literally.
- If second arg is not -1, work it into the exit code.
-*/
-VOID
-doexit(exitstat,code) int exitstat, code; {
- extern int x_logged, quitting;
-#ifdef OS2
- extern int display_demo;
- extern int SysInited;
-#endif /* OS2 */
-#ifdef CK_KERBEROS
-#ifdef KRB4
- extern int krb4_autodel;
-#endif /* KRB4 */
-#ifdef KRB5
- extern int krb5_autodel;
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef VMS
- char envstr[64];
- static $DESCRIPTOR(symnam,"CKERMIT_STATUS");
- static struct dsc$descriptor_s symval;
-#endif /* VMS */
- int i;
-
-#ifdef DEBUG
-#ifdef USE_LUCACHE
- extern long lucalls, luhits, xxhits, luloop;
- extern int lusize;
-#endif /* USE_LUCACHE */
-#ifndef NOSPL
- extern int cmdstats[];
-#endif /* NOSPL */
-
- quitting++;
-
-#ifdef OS2
- if ( !SysInited ) {
- static int initing = 0;
- if ( initing )
- exit(253);
- initing = 1;
- sysinit();
- }
-#endif /* OS2 */
-
- if (deblog) {
-#ifdef USE_LUCACHE
- debug(F101,"lookup cache size","",lusize);
- debug(F101,"lookup calls ....","",lucalls);
- debug(F101,"lookup cache hits","",luhits);
- debug(F101,"lookup start hits","",xxhits);
- debug(F101,"lookup loop iterations","",luloop);
-#endif /* USE_LUCACHE */
-#ifndef NOSPL
- for (i = 0; i < 256; i++) {
- if (cmdstats[i])
- debug(F111,"CMSTATS",ckitoa(i),cmdstats[i]);
- }
-#endif /* NOSPL */
- debug(F101,"doexit exitstat","",exitstat);
- debug(F101,"doexit code","",code);
- debug(F101,"doexit xitsta","",xitsta);
- }
-#endif /* DEBUG */
-
-#ifdef CK_KERBEROS
- /* If we are automatically destroying Kerberos credentials on Exit */
- /* do it now. */
-#ifdef KRB4
- if (krb4_autodel == KRB_DEL_EX) {
- extern struct krb_op_data krb_op;
- krb_op.version = 4;
- krb_op.cache = NULL;
- ck_krb4_destroy(&krb_op);
- }
-#endif /* KRB4 */
-#ifdef KRB5
- if (krb5_autodel == KRB_DEL_EX) {
- extern struct krb_op_data krb_op;
- extern char * krb5_d_cc;
- krb_op.version = 5;
- krb_op.cache = krb5_d_cc;
- ck_krb5_destroy(&krb_op);
- }
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifndef NOLOCAL
-#ifdef OS2
- if (SysInited)
- {
-#ifdef DCMDBUF
- extern struct cmdptr *cmdstk;
-#else
- extern struct cmdptr cmdstk[];
-#endif /* DCMDBUF */
- extern int tt_status[];
- extern int vmode;
-
- /* If there is a demo screen to be displayed, display it */
- if (display_demo) {
- demoscrn(VCMD);
- display_demo = 0;
- }
-#ifndef KUI
- /* This is going to be hideous. If we have a status line */
- /* in the command window turn it off before we exit. */
-
- if ( tt_status[VCMD] && vmode == VCMD ) {
- domac("_clear_statusline","set command statusline off",
- cmdstk[cmdlvl].ccflgs);
- delmac("_clear_statusline",1);
- RequestScreenMutex(-1);
- VscrnIsDirty(vmode);
- ReleaseScreenMutex();
- while ( IsVscrnDirty(vmode) )
- msleep(200);
- RequestScreenMutex(-1);
- ReleaseScreenMutex();
- }
-#endif /* KUI */
- DialerSend(OPT_KERMIT_EXIT,exitstat);
-#ifndef KUI
- debug(F100,"doexit about to msleep","",0);
-
- if ( isWin95() )
- msleep(250);
-#endif /* KUI */
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && x_logged) {
-#ifndef NOSPL
-/*
- If a macro named "on_logout" is defined, execute it. Also remove it from the
- macro table, in case its definition includes an EXIT or QUIT command, which
- would cause much recursion and would prevent the program from ever actually
- EXITing.
-*/
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- char * cmd = "on_logout"; /* MSVC 2.x compiler error */
- k = mlook(mactab,cmd,nmac); /* Look up "on_logout" */
- if (k >= 0) { /* If found, */
- *(mactab[k].kwd) = NUL; /* poke its name from the table, */
- if (dodo(k,"",0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
-#endif /* NOSPL */
- zvlogout();
- }
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-
- debug(F100,"doexit about to doclean","",0);
- doclean(1); /* Clean up most things */
-
-#ifdef VMS
- if (code == -1)
- code = 0; /* Since we set two different items */
- sprintf(envstr,"%d", exitstat | code); /* SAFE */
- symval.dsc$w_length = (int)strlen(envstr);
- symval.dsc$a_pointer = envstr;
- symval.dsc$b_class = DSC$K_CLASS_S;
- symval.dsc$b_dtype = DSC$K_DTYPE_T;
- i = 2; /* Store in global table */
-#ifdef COMMENT /* Martin Zinser */
- LIB$SET_SYMBOL(&symnam, &symval, &i);
-#else
- lib$set_symbol(&symnam, &symval, &i);
-#endif /* COMMENT */
- if (exitstat == BAD_EXIT)
- exitstat = SS$_ABORT | STS$M_INHIB_MSG;
- if (exitstat == GOOD_EXIT)
- exitstat = SS$_NORMAL | STS$M_INHIB_MSG;
-#else /* Not VMS */
- if (code != -1) /* Take 1st arg literally */
- exitstat |= code;
-#endif /* VMS */
-
-#ifdef IKSD
-#ifdef IKSDB
- debug(F101,"doexit ikdbopen","",ikdbopen);
- if (ikdbopen && dbfp) { /* If IKSD database open */
- int x;
- x = freeslot(mydbslot); /* Free our slot... */
- debug(F101,"doexit freeslot","",x);
- fclose(dbfp); /* and close it. */
- }
-#endif /* IKSDB */
-#endif /* IKSD */
-
-/* We have put this off till the very last moment... */
-
-#ifdef DEBUG
- if (deblog) { /* Close the debug log. */
- debug(F101,"C-Kermit EXIT status","",exitstat);
- *debfil = '\0';
- deblog = 0;
- zclose(ZDFILE);
- }
-#endif /* DEBUG */
-
-#ifdef OS2
- _exit(exitstat); /* Exit from C-Kermit (no matter what) */
-#else /* OS2 */
- exit(exitstat); /* Exit from C-Kermit */
-#endif /* OS2 */
-}
-
-VOID
-bgchk() { /* Check background status */
- if (bgset < 0) { /* They didn't type SET BACKGROUND */
-#ifdef VMS /* Set prompt flag based on */
- pflag = !batch; /* what we detected at startup. */
-#else
- pflag = !backgrd;
-#endif /* VMS */
- } else { /* Otherwise SET BACKGROUND value */
- pflag = (bgset == 0 ? 1 : 0);
- }
-
-#ifndef NOICP
- /* Message flag on only if at top level, pflag is on, and QUIET is OFF */
- if (!xcmdsrc)
- msgflg = (pflag == 0) ? 0 : !quiet;
- else msgflg = 0;
-#else
- msgflg = 0;
-#endif /* NOICP */
-}
-
-/* Set console interrupts */
-
-VOID
-setint() { /* According to SET COMMAND INTERRUP */
- int x = 0;
- if (cmdint) x |= 1;
- if (xsuspend) x |= 2;
- debug(F101,"setint","",x);
-
- switch (x) { /* Set the desired combination */
- case 0: connoi(); break; /* No interrupts */
- case 1: conint(trap,SIG_IGN); break;
- case 2: conint(SIG_IGN,stptrap); break;
- case 3: conint(trap,stptrap); break;
- }
- bgchk(); /* Check background status */
-}
-
-#ifdef DEBUG
-/* D E B U G -- Enter a record in the debugging log */
-
-/*
- Call with a format, two strings, and a number:
- f - Format, a bit string in range 0-7.
- If bit x is on, then argument number x is printed.
- s1 - String, argument number 1. If selected, printed as is.
- s2 - String, argument number 2. If selected, printed in brackets.
- n - Long int, argument 3. If selected, printed preceded by equals sign.
-
- f=0 is special: print s1,s2, and interpret n as a char.
-
- f=F011 (3) is also special; in this case s2 is interpeted as a counted
- string that might contain NULs. n is the length. If n is negative, this
- means the string has been truncated and ".." should be printed after the
- first n bytes. NUL and LF bytes are printed as "<NUL>" and "<LF>".
-
- Globals:
- deblog: nonzero if debug log open.
- debok: nonzero if ok to write entries.
-*/
-/*
- WARNING: Don't change DEBUFL without changing sprintf() formats below,
- accordingly.
-*/
-#define DBUFL 4000
-/*
- WARNING: This routine is not thread-safe, especially when Kermit is
- executing on multiple CPUs -- as different threads write to the same
- static buffer, the debug statements are all interleaved. To be fixed
- later...
-*/
-static char *dbptr = (char *)0;
-
-int
-#ifdef CK_ANSIC
-dodebug(int f, char *s1, char *s2, CK_OFF_T n)
-#else
-dodebug(f,s1,s2,n) int f; char *s1, *s2; CK_OFF_T n;
-#endif /* CK_ANSIC */
-/* dodebug */ {
- char *sp;
- int len1, len2;
- extern int debtim;
-#ifdef OS2
- extern int SysInited;
-#endif /* OS2 */
-
- if (!deblog || !debok)
- return(0);
-
-#ifdef COMMENT
- /* expensive... */
- if (!chkfn(ZDFILE)) /* Debug log not open, don't. */
- return(0);
-#endif /* COMMENT */
- if (!dbptr) { /* Allocate memory buffer */
- dbptr = malloc(DBUFL+4); /* This only happens once */
- if (!dbptr) {
- zclose(ZDFILE);
- return(0);
- }
- }
-/*
- This prevents infinite recursion in case we accidentally put a debug()
- call in this routine, or call another routine that contains debug() calls.
- From this point on, all returns from this return must be via goto xdebug,
- which sets deblog back to 1.
-*/
-#ifdef OS2
- if (SysInited) {
- if (RequestDebugMutex(30000))
- goto xdebug;
- }
-#else /* OS2 */
- deblog = 0; /* Prevent infinite recursion */
-#endif /* OS2 */
-
- if (debtim) { /* Timestamp */
- char *tb, tsbuf[48];
- ztime(&tb);
- ckstrncpy(tsbuf,tb,32);
- if (ztmsec > -1L) {
- sprintf(tsbuf+19,".%03ld ",ztmsec); /* SAFE */
- } else {
- tsbuf[19] = ':';
- tsbuf[20] = SP;
- tsbuf[21] = NUL;
- }
- zsout(ZDFILE,tsbuf+11);
- }
- if (!s1) s1="(NULL)";
- if (!s2) s2="(NULL)";
-
- len1 = strlen(s1);
- len2 = strlen(s2);
-
-#ifdef COMMENT
-/*
- This should work, but it doesn't.
- So instead we'll cope with overflow via sprintf formats.
- N.B.: UNFORTUNATELY, this means we have to put constants in the
- sprintf formats.
-*/
- if (f != F011 && (!f || (f & 6))) { /* String argument(s) included? */
- x = (int) strlen(s1) + (int) strlen(s2) + 18;
- if (x > dbufl) { /* Longer than buffer? */
- if (dbptr) /* Yes, free previous buffer */
- free(dbptr);
- dbptr = (char *) malloc(x + 2); /* Allocate a new one */
- if (!dbptr) {
- zsoutl(ZDFILE,"DEBUG: Memory allocation failure");
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- } else {
- dbufl = x;
- sprintf(dbptr,"DEBUG: Buffer expanded to %d\n", x + 18);
- zsoutl(ZDFILE,dbptr);
- }
- }
- }
-#endif /* COMMENT */
-
-#ifdef COMMENT
-/* The aforementioned sprintf() formats were like this: */
- if (n > 31 && n < 127)
- sprintf(sp,"%.100s%.2000s:%c\n",s1,s2,(CHAR) n);
- else if (n < 32 || n == 127)
- sprintf(sp,"%.100s%.2000s:^%c\n",s1,s2,(CHAR) ((n+64) & 0x7F));
- else if (n > 127 && n < 160)
- sprintf(sp,"%.100s%.2000s:~^%c\n",s1,s2,(CHAR)((n-64) & 0x7F));
- else if (n > 159 && n < 256)
- sprintf(sp,"%.100s%.2000s:~%c\n",s1,s2,(CHAR) (n & 0x7F));
- else sprintf(sp,"%.100s%.2000s:%ld\n",s1,s2,n);
-/*
- But, naturally, it turns out these are not portable either, so now
- we do the stupidest possible thing.
-*/
-#endif /* COMMENT */
-
-#ifdef BIGBUFOK
-/* Need to accept longer strings when debugging authenticated connections */
- if (f == F010) {
- if (len2 + 2 >= DBUFL) s2 = "(string too long)";
- } else if (f != F011 && f != F100) {
- if (len1 > 100) s1 = "(string too long)";
- if (len2 + 101 >= DBUFL) s2 = "(string too long)";
- }
-#else
- if (f != F011) {
- if (len1 > 100) s1 = "(string too long)";
- if (len2 + 101 >= DBUFL) s2 = "(string too long)";
- }
-#endif /* BIGBUFOK */
-
- sp = dbptr;
-
- switch (f) { /* Write log record according to format. */
- case F000: /* 0 = print both strings, and n as a char. */
- if (len2 > 0) {
- if ((n > 31 && n < 127) || (n > 159 && n < 256))
- sprintf(sp,"%s[%s]=%c\n",s1,s2,(CHAR) n);
- else if (n < 32 || n == 127)
- sprintf(sp,"%s[%s]=^%c\n",s1,s2,(CHAR) ((n+64) & 0x7F));
- else if (n > 127 && n < 160)
- sprintf(sp,"%s[%s]=~^%c\n",s1,s2,(CHAR)((n-64) & 0x7F));
- else sprintf(sp,"%s[%s]=0x%lX\n",s1,s2,(long)n);
- } else {
- if ((n > 31 && n < 127) || (n > 159 && n < 256))
- sprintf(sp,"%s=%c\n",s1,(CHAR) n);
- else if (n < 32 || n == 127)
- sprintf(sp,"%s=^%c\n",s1,(CHAR) ((n+64) & 0x7F));
- else if (n > 127 && n < 160)
- sprintf(sp,"%s=~^%c\n",s1,(CHAR)((n-64) & 0x7F));
- else sprintf(sp,"%s=0x%lX\n",s1,(long)n);
- }
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
-
- case F001: /* 1, "=n" */
-#ifdef COMMENT
- /* This was never used */
- sprintf(sp,"=%s\n",ckfstoa(n));
-#else
- /* Like F111, but shows number n in hex */
- ckmakxmsg(sp,DBUFL,
- s1,
- (*s1 ? ":" : ""),
- s2,
- (*s2 ? ":" : ""),
- ckltox(n),
- "\n",
- NULL,NULL,NULL,NULL,NULL,NULL
- );
-#endif /* COMMENT */
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
-
-/*
- This one was never used so (October 2000) we now use it like F011,
- except in this case we treat s2 as NUL terminated.
-*/
- case F010:
- n = -debxlen;
-/*
- This one treats n as the length of the string s2, which may contain NULs.
- It's good for logging NUL-bearing data in the debug log.
-*/
- case F011: {
- int i, j, contd = 0;
- char * p = s2, *pbuf = NULL; /* p = source pointer */
- int m; /* pbuf = destination pointer */
-
- if (f == F011) {
- if (n < 0) { /* n = size of source */
- n = 0 - n; /* Negative means to add "..." */
- contd = 1;
- }
- } else {
- int x, flag = 0;
- x = strlen(s2);
- if (n < 0) {
- flag = 1;
- n = 0 - n;
- }
- if (x < n)
- n = x;
- }
- if (n == 0) /* 0 means do nothing */
- goto xdebug;
- m = DBUFL - 8; /* Get size for interpreted part */
- if (n > m) /* Ensure requested size not too big */
- n = m;
- pbuf = dbptr; /* Construction pointer */
- i = 0;
- pbuf[i++] = '['; /* Interpret the string into it */
- for (j = 0; j < n && i < m-4; p++,j++) { /* char by char... */
- if (*p == LF) {
- if (i >= m-4)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'L';
- pbuf[i++] = 'F';
- pbuf[i++] = '>';
- continue;
- } else if (*p == CR) {
- if (i >= m-4)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'C';
- pbuf[i++] = 'R';
- pbuf[i++] = '>';
- continue;
- } else if (*p == HT) {
- if (i >= m-5)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'T';
- pbuf[i++] = 'A';
- pbuf[i++] = 'B';
- pbuf[i++] = '>';
- continue;
- } else if (*p) {
- pbuf[i++] = *p;
- continue;
- } else {
- if (i >= m-5)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'N';
- pbuf[i++] = 'U';
- pbuf[i++] = 'L';
- pbuf[i++] = '>';
- continue;
- }
- }
- if (i < m-2 && (*p || contd)) {
- pbuf[i++] = '.';
- pbuf[i++] = '.';
- }
- pbuf[i++] = ']';
- pbuf[i] = NUL;
- if (zsout(ZDFILE,s1) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
- if (zsoutl(ZDFILE,pbuf) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",s1,pbuf);
- }
-#endif /* CKSYSLOG */
- }
- break;
-
- case F100: /* 4, "s1" */
- if (zsoutl(ZDFILE,s1) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",s1,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- case F101: /* 5, "s1=n" */
- sprintf(sp,"%s=%s\n",s1,ckfstoa(n));
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- case F110: /* 6, "s1[s2]" */
- sprintf(sp,"%s[%s]\n",s1,s2);
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- case F111: /* 7, "s1[s2]=n" */
- sprintf(sp,"%s[%s]=%s\n",s1,s2,ckfstoa(n));
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- default:
- sprintf(sp,"\n?Invalid format for debug() - %d\n",f);
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- }
- xdebug: /* Common exit point */
-#ifdef OS2
- if (SysInited)
- ReleaseDebugMutex();
-#else /* OS2 */
- deblog = 1; /* Restore this */
-#endif /* OS2 */
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-dohexdump(CHAR *msg, CHAR *st, int cnt)
-#else
-dohexdump(msg,st,cnt) CHAR *msg; CHAR *st; int cnt;
-#endif /* CK_ANSIC */
-/* dohexdump */ {
- int i = 0, j = 0, k = 0;
- char tmp[8];
-#ifdef OS2
- extern int SysInited;
-#endif /* OS2 */
-
- if (!deblog) return(0); /* If no debug log, don't. */
- if (!dbptr) { /* Allocate memory buffer */
- dbptr = malloc(DBUFL+1); /* This only happens once */
- if (!dbptr) {
- deblog = 0;
- zclose(ZDFILE);
- return(0);
- }
- }
-
-#ifdef OS2
- if (SysInited) {
- if (RequestDebugMutex(30000))
- goto xdebug;
- }
-#else /* OS2 */
- deblog = 0; /* Prevent infinite recursion */
-#endif /* OS2 */
-
- if (msg != NULL) {
- ckmakxmsg(dbptr,
- DBUFL,
- "HEXDUMP: ",
- (char *)msg,
- " (",
- ckitoa(cnt),
- " bytes)\n",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- }
- } else {
- ckmakmsg(dbptr,
- DBUFL,
- "HEXDUMP: (",
- ckitoa(cnt),
- " bytes)\n",
- NULL
- );
- zsout(ZDFILE,dbptr);
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- }
- }
- for (i = 0; i < cnt; i++) {
- dbptr[0] = '\0';
- for (j = 0 ; (j < 16); j++) {
- if ((i + j) < cnt)
- sprintf(tmp,
- "%s%02x ",
- (j == 8 ? "| " : ""),
- (CHAR) st[i + j]
- );
- else
- sprintf(tmp,
- "%s ",
- (j == 8 ? "| " : "")
- );
- ckstrncat(dbptr,tmp,DBUFL+1);
- }
- ckstrncat(dbptr," ",DBUFL+1);
- for (k = 0; (k < 16) && ((i + k) < cnt); k++) {
- sprintf(tmp,
- "%s%c",
- (k == 8 ? " " : ""),
- isprint(st[i + k]) ? st[i + k] : '.'
- );
- ckstrncat(dbptr,tmp,DBUFL+1);
- }
- ckstrncat(dbptr,"\n",DBUFL+1);
- i += j - 1;
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- }
- } /* end for */
-
-
- xdebug:
-#ifdef OS2
- if (SysInited)
- ReleaseDebugMutex();
-#else /* OS2 */
- deblog = 1;
-#endif /* OS2 */
- return(0);
-}
-#endif /* DEBUG */
-
-/* Session Log... */
-
-int tsstate = 0;
-
-VOID
-#ifdef OS2
-logchar(unsigned short c)
-#else /* OS2 */
-#ifdef CK_ANSIC
-logchar(char c)
-#else
-logchar(c) char c;
-#endif /* CK_ANSIC */
-#endif /* OS2 */
-/* logchar */ { /* Log character c to session log */
- extern int slognul;
- int oktolog = 0;
-#ifndef NOLOCAL
- if (!seslog)
- return;
-
- if ((sessft != XYFT_T) || (
-#ifdef UNIX
- c != '\r' &&
-#else
-#ifdef datageneral
- c != '\r' &&
-#else
-#ifdef STRATUS
- c != '\r' &&
-#else
-#ifdef AMIGA
- c != '\r' &&
-#else
-#ifdef GEMDOS
- c != '\r' &&
-#endif /* GEMDOS */
-#endif /* AMIGA */
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* UNIX */
-#ifdef OSK
- c != '\n' &&
-#else
-#ifdef MAC
- c != '\n' &&
-#endif /* MAC */
-#endif /* OSK */
- c != XON &&
- c != XOFF))
- oktolog = 1;
- if (c == '\0' && !sessft) /* NUL in text mode */
- if (slognul) oktolog = 1; /* only if padding (2009/10/22) */
- if (!oktolog)
- return;
- if (slogts) { /* Log is timestamped */
- if (tsstate == 0) { /* State = between-lines */
- char * p; /* zstime() pointer */
- char ts[48]; /* timestamp buffer */
- ztime(&p); /* Get asctime() string */
- ckstrncpy(ts,p,32); /* Make safe copy */
- if (ztmsec > -1L) { /* Add msecs if we have them */
- sprintf(&ts[19],".%03ld: ",ztmsec); /* SAFE */
- } else {
- ts[19] = ':';
- ts[20] = SP;
- ts[21] = NUL;
- }
- if (zsout(ZSFILE,&ts[11]) < 0)
- goto xlogchar;
- }
- }
- if (c == '\n') /* At end of line? */
- tsstate = 0; /* yes */
- else
- tsstate = 1; /* no */
- if (zchout(ZSFILE,(CHAR)(c & 0xFF)) < 0) /* Log the character */
- goto xlogchar;
- if (tsstate == 0 && slognul != 0) { /* Null-terminating lines? */
- if (zchout(ZSFILE,(CHAR)0) < 0) /* Add a NUL */
- goto xlogchar;
- }
- return;
-
- xlogchar:
- conoll("");
- conoll("ERROR WRITING SESSION LOG, LOG CLOSED!");
- setseslog(0);
- zclose(ZSFILE);
-#endif /* NOLOCAL */
-}
-
-VOID
-logstr(s, len) char * s; int len; { /* Log string to session log */
-#ifndef NOLOCAL
- int n = 0;
- if (!s)
- return;
- while (seslog && (n < len))
- logchar(s[n++]);
-#endif /* NOLOCAL */
-}
-
-#ifdef CK_CURSES
-int
-ck_repaint() {
- repaint = 1;
- return(0);
-}
-
-#ifdef STRATUS
-/* VOS has curses but no tgetent() */
-int
-tgetent(s1, s2) char * s1, * s2; {
- return(1);
-}
-#endif /* STRATUS */
-
-#ifdef VMS
-#ifdef __DECC
-_PROTOTYP(int tgetent,(char *, char *));
-#endif /* __DECC */
-#endif /* VMS */
-
-/*
- There are three different ways to do fullscreen on VMS.
- 1. Use the real curses library, VAXCCURSE.
- 2. Use do-it-yourself code.
- 3. Use the Screen Manager, SMG$.
-
- Method 1 doesn't work quite right; you can't call endwin(), so once you've
- started curses mode, you can never leave.
-
- Method 2 doesn't optimize the screen, and so much more time is spent in
- screen writes. This actually causes file transfers to fail because the
- tty device input buffer can be overrun while the screen is being updated,
- especially on a slow MicroVAX that has small typeahead buffers.
-
- In the following #ifdef block, #define one of them and #undef the other 2.
-
- So now let's try method 3...
-*/
-#ifdef VMS
-#define CK_SMG /* Screen Manager */
-#undef MYCURSES /* Do-it-yourself */
-#undef VMSCURSE /* VAXCCURSE library */
-#endif /* VMS */
-/*
- But just before New Years, 2000, the SMG library seemed to break on
- both VMS systems we have here (an Alpha with VMS 7.1 and a VAX with 5.5).
- So back to MYCURSES, which works fine.
-*/
-#ifdef VMS
-#undef CK_SMG
-#define MYCURSES
-#endif /* VMS */
-
-#ifdef MYCURSES
-#define stdscr 0
-#ifdef CK_WREFRESH
-#undef CK_WREFRESH
-#endif /* CK_WREFRESH */
-#endif /* MYCURSES */
-
-/* S C R E E N C -- Screen display function, uses curses */
-
-/* Idea for curses display contributed by Chris Pratt of APV Baker, UK */
-
-/* Avoid conficts with curses.h */
-
-#ifdef QNX
-/* Same as ckcasc.h, but in a different radix... */
-#ifdef ESC
-#undef ESC
-#endif /* ESC */
-#endif /* QNX */
-
-#ifndef MYCURSES
-#undef VOID /* This was defined in ckcdeb.h */
-#endif /* MYCURSES */
-
-#undef BS /* These were defined in ckcasc.h */
-#undef CR
-#undef NL
-#undef SO
-#ifdef US
-#undef US
-#endif /* US */
-#undef SP /* Used in ncurses */
-#define CHR_SP 32 /* Use this instead */
-
-#ifdef VMS /* VMS fullscreen display */
-#ifdef MYCURSES /* Do-it-yourself method */
-extern int isvt52; /* From CKVTIO.C */
-#define printw printf
-#else
-#ifdef VMSCURSE /* VMS curses library VAXCCURSE */
-#include <curses.h>
-/* Note: Screen manager doesn't need a header file */
-#endif /* VMSCURSE */
-#endif /* MYCURSES */
-#else /* Not VMS */
-#ifdef MYCURSES /* Do-it-yourself method */
-#define isvt52 0 /* Used by OS/2, VT-100/ANSI always */
-#ifdef CKXPRINTF
-#define printw ckxprintf
-#else /* CKXPRINTF */
-#ifdef KUI
-#define printw Vscrnprintw
-#else /* KUI */
-#define printw printf
-#endif /* KUI */
-#endif /* CKXPRINTF */
-#else /* Use real curses */
-#ifdef CK_NCURSES /* or ncurses... */
-#ifdef CKXPRINTF /* Our printf macro conflicts with */
-#undef printf /* use of "printf" in ncurses.h */
-#endif /* CKXPRINTF */
-#include <ncurses.h>
-#ifdef CKXPRINTF
-#define printf ckxprintf
-#endif /* CKXPRINTF */
-#else /* Not ncurses */
-#ifdef CKXPRINTF /* Our printf macro conflicts with */
-#undef printf /* use of "printf" in curses.h */
-#endif /* CKXPRINTF */
-#ifdef M_XENIX /* SCO XENIX... */
-#ifdef M_TERMCAP
-#undef M_TERMCAP
-#endif /* M_TERMCAP */
-#ifndef M_TERMINFO
-#define M_TERMINFO
-#endif /* M_TERMINFO */
-#endif /* M_XENIX */
-#ifdef RTAIX
-#undef NLS /* Avoid 'redeclaration of free'. */
-#endif /* RTAIX */
-#include <curses.h>
-#ifdef CKXPRINTF
-#define printf ckxprintf
-#endif /* CKXPRINTF */
-#endif /* CK_NCURSES */
-#endif /* MYCURSES */
-#endif /* VMS */
-
-#ifdef BUG999
-_PROTOTYP(int tgetent,(char *, char *));
-_PROTOTYP(char *tgetstr,(char *, char **));
-_PROTOTYP(int tputs,(char *, int, int (*)()));
-_PROTOTYP(char *tgoto,(const char *, int, int));
-#endif /* BUG999 */
-#ifdef linux
-#include <term.h>
-#endif
-
-#endif /* CK_CURSES */
-
-/* F X D I N I T -- File Xfer Display Initialization */
-
-#ifdef CK_CURSES
-#ifndef MYCURSES
-#ifndef CK_SMG
-static
-#ifdef CK_ANSIC
-/* Can't use VOID because of curses.h */
-void
-ck_termset(int);
-#else
-ck_termset();
-#endif /* CK_ANSIC */
-#endif /* CK_SMG */
-#endif /* MYCURSES */
-#endif /* CK_CURSES */
-
-#ifdef NOTERMCAP
-static int notermcap = 1;
-#else
-static int notermcap = 0;
-#endif /* NOTERMCAP */
-
-#ifndef NODISPLAY
-CKVOID
-fxdinit(xdispla) int xdispla; {
-#ifndef COHERENT
-#ifndef OS2
-#ifndef STRATUS
- char *s;
- int x, dummy;
-
- debug(F101,"fxdinit xdispla","",xdispla);
- debug(F101,"fxdinit fxd_inited","",fxd_inited);
-
-#ifdef IKSD
-#ifndef NOXFER
- /* No curses for IKSD */
- if (inserver) {
- fdispla = XYFD_N;
- return;
- }
- if (fxd_inited) /* Only do this once */
- return;
-#endif /* NOXFER */
-#endif /* IKSD */
-
- if (xdispla == XYFD_R || xdispla == XYFD_S || xdispla == XYFD_B) {
- if (xfrmsg) {
- printf("%s\n",xfrmsg);
- makestr(&xfrmsg,NULL);
- }
- }
-
-#ifdef CK_CURSES
-#ifdef VMS
- /* Force BRIEF in Batch logs */
- if (batch && (xdispla == XYFD_C || xdispla == XYFD_S))
- xdispla = XYFD_B;
-#else
- if (xdispla == XYFD_C || xdispla == 9999) {
-
-#ifdef DYNAMIC
- if (!trmbuf) {
-/*
- Allocate tgetent() buffer. Make it big -- some termcaps can be huge;
- tgetent() merrily writes past the end of the buffer, causing core dumps
- or worse.
-*/
- trmbuf = (char *)malloc(TRMBUFL);
- if (!trmbuf) {
- notermcap = 1;
- debug(F101,"fxdinit malloc trmbuf","FAILED",TRMBUFL);
- fdispla = XYFD_S;
- return;
- }
-#ifdef COMMENT
- debug(F111,"fxdinit malloc trmbuf","OK",TRMBUFL);
- debug(F001,"fxdinit trmbuf","",trmbuf);
- memset(trmbuf,'\0',(size_t)TRMBUFL);
- debug(F100,"fxdinit memset OK","",0);
-#endif /* COMMENT */
- }
-#endif /* DYNAMIC */
-
- debug(F100,"fxdinit before getenv(TERM)","",0);
- s = getenv("TERM");
- debug(F110,"fxdinit after getenv(TERM)",s,0);
- if (!s) s = "";
- if (*s) {
- debug(F110,"fxdinit before tgetent()",s,0);
- x = tgetent(trmbuf,s);
- debug(F111,"fxdinit tgetent",s,x);
- } else {
- x = 0;
- notermcap = 1;
- debug(F110,"fxdinit TERM null - no tgetent",s,0);
- }
- if (x < 1 && !quiet && !backgrd
-#ifdef VMS
- && !batch
-#endif /* VMS */
- ) {
- printf("Warning: terminal type unknown: \"%s\"\n",s);
-#ifdef COMMENT
- /* Confusing - nobody knows what this means */
- printf("SCREEN command will use ANSI sequences.\n");
-#endif /* COMMENT */
- if (local)
- printf("Fullscreen file transfer display disabled.\n");
- fdispla = XYFD_S;
- }
-#ifndef MYCURSES
-#ifndef CK_SMG
- ck_termset(x);
-#endif /* CK_SMG */
-#endif /* MYCURSES */
- fxd_inited = 1;
- }
-#endif /* CK_CURSES */
-#endif /* VMS */
-#endif /* STRATUS */
-#endif /* OS2 */
-#endif /* COHERENT */
-}
-#endif /* NODISPLAY */
-
-#ifdef CK_CURSES
-#ifdef CK_SMG
-/*
- Long section for Screen Manager starts here...
- By William Bader.
-*/
-#include "ckvvms.h"
-#ifdef OLD_VMS
-#include <smgdef.h> /* use this on VAX C 2.4 */
-/* #include <smgmsg.h> */
-#else
-#include <smg$routines.h> /* Martin Zinser */
-#endif /* OLD_VMS */
-
-extern unsigned int vms_status; /* Used for system service return status */
-
-static long smg_pasteboard_id = -1; /* pasteboard identifier */
-static long smg_display_id = -1; /* display identifier */
-static int smg_open = 0; /* flag if smg current open */
-static int smg_inited = 0; /* flag if smg initialized */
-
-#ifdef COMMENT
-#define clrtoeol() SMG$ERASE_LINE(&smg_display_id, 0, 0)
-
-#define clear() SMG$ERASE_DISPLAY(&smg_display_id, 0, 0, 0, 0)
-
-#define touchwin(scr) SMG$REPAINT_SCREEN(&smg_pasteboard_id)
-
-#else /* Not COMMENT */
-
-#define clrtoeol() smg$erase_line(&smg_display_id, 0, 0)
-
-#define clear() smg$erase_display(&smg_display_id, 0, 0, 0, 0)
-
-#define touchwin(scr) smg$repaint_screen(&smg_pasteboard_id)
-#endif /* COMMENT */
-
-#define clearok(curscr,ok) /* Let wrefresh() do the work */
-
-#define wrefresh(cursrc) touchwin(scr)
-
-static void
-move(row, col) int row, col; {
- /* Change from 0-based for curses to 1-based for SMG */
- if (!smg_open)
- return;
- ++row; ++col;
- debug(F111,"VMS smg move",ckitoa(row),col);
-#ifdef COMMENT /* Martin Zinser */
- CHECK_ERR("move: smg$set_cursor_abs",
- SMG$SET_CURSOR_ABS(&smg_display_id, &row, &col));
-#else
- CHECK_ERR("move: smg$set_cursor_abs",
- smg$set_cursor_abs(&smg_display_id, &row, &col));
-#endif /* COMMENT */
- debug(F101,"VMS smg move vms_status","",vms_status);
-}
-
-#ifdef VMS_V40
-#define OLD_VMS
-#endif /* VMS_V40 */
-#ifdef VMS_V42
-#define OLD_VMS
-#endif /* VMS_V42 */
-#ifdef VMS_V44
-#define OLD_VMS
-#endif /* VMS_V44 */
-
-static int
-initscr() {
- int rows = 24, cols = 80;
- int row = 1, col = 1;
-
- debug(F101,"VMS initscr smg_pasteboard_id A","",smg_pasteboard_id);
-
- if (smg_pasteboard_id == -1) { /* Open the screen */
-#ifdef OLD_VMS /* Note: Routine calls lowercased 9/96 */
- CHECK_ERR("initscr: smg$create_pasteboard",
- smg$create_pasteboard(&smg_pasteboard_id, 0, 0, 0, 0));
-#else
- /* For VMS V5, not tested */
- CHECK_ERR("initscr: smg$create_pasteboard",
- smg$create_pasteboard(&smg_pasteboard_id, 0, 0, 0, 0, 0));
-#endif /* OLD_VMS */
- }
- debug(F101,"VMS initscr smg_pasteboard_id B","",smg_pasteboard_id);
- if (smg_pasteboard_id == -1) {
- printf("?Error initializing fullscreen display\n");
- fdispla = XYFD_S;
- dpyinit();
- return(0);
- }
- debug(F101,"VMS initscr smg_display_id","",smg_display_id);
- if (smg_display_id == -1) { /* Create a display window */
-
-#ifdef COMMENT /* Martin Zinser */
- CHECK_ERR("initscr: smg$create_virtual_display",
- SMG$CREATE_VIRTUAL_DISPLAY(&rows, &cols, &smg_display_id,
- 0, 0, 0));
-
- /* Connect the display window to the screen */
- CHECK_ERR("initscr: smg$paste_virtual_display",
- SMG$PASTE_VIRTUAL_DISPLAY(&smg_display_id,&smg_pasteboard_id,
- &row,&col));
-#else
- CHECK_ERR("initscr: smg$create_virtual_display",
- smg$create_virtual_display(&rows, &cols, &smg_display_id,
- 0, 0, 0));
-
- /* Connect the display window to the screen */
- CHECK_ERR("initscr: smg$paste_virtual_display",
- smg$paste_virtual_display(&smg_display_id,&smg_pasteboard_id,
- &row,&col));
-#endif /* COMMENT */
- }
- debug(F101,"VMS initscr smg_open A","",smg_open);
- if (!smg_open) { /* Start a batch update */
- smg_open = 1;
-#ifdef COMMENT
- CHECK_ERR("initscr: smg$begin_pasteboard_update",
- SMG$BEGIN_PASTEBOARD_UPDATE(&smg_pasteboard_id));
-#else
- CHECK_ERR("initscr: smg$begin_pasteboard_update",
- smg$begin_pasteboard_update(&smg_pasteboard_id));
-#endif /* COMMENT */
- debug(F101,"VMS initscr smg$begin_pasteboard_update","",vms_status);
- }
- debug(F101,"VMS initscr smg_open B","",smg_open);
- smg_inited = 1;
- return(1);
-}
-
-static void
-refresh() {
- debug(F101,"refresh smg_pasteboard_id","",smg_pasteboard_id);
-
- if (smg_open == 0 || smg_pasteboard_id == -1)
- return;
-
-#ifdef COMMENT /* Martin Zinser */
- CHECK_ERR("refresh: smg$end_pasteboard_update",
- SMG$END_PASTEBOARD_UPDATE(&smg_pasteboard_id));
- CHECK_ERR("refresh: smg$begin_pasteboard_update",
- SMG$BEGIN_PASTEBOARD_UPDATE(&smg_pasteboard_id));
-#else
- CHECK_ERR("refresh: smg$end_pasteboard_update",
- smg$end_pasteboard_update(&smg_pasteboard_id));
- CHECK_ERR("refresh: smg$begin_pasteboard_update",
- smg$begin_pasteboard_update(&smg_pasteboard_id));
-#endif /* COMMENT */
-}
-
-static void
-endwin() {
- if (!smg_open)
- return;
-
- smg_open = 0;
-
-#ifdef COMMENT
- CHECK_ERR("endwin: smg$end_pasteboard_update",
- SMG$END_PASTEBOARD_UPDATE(&smg_pasteboard_id));
-#else
- CHECK_ERR("endwin: smg$end_pasteboard_update",
- smg$end_pasteboard_update(&smg_pasteboard_id));
-#endif /* COMMENT */
-
- move(22, 0);
-
-#ifdef COMMENT
-/*
- These calls clear the screen.
- (convert routine calls to lowercase - Martin Zinser)
-*/
- CHECK_ERR("endwin: smg$delete_virtual_display",
- SMG$DELETE_VIRTUAL_DISPLAY(&smg_display_id));
- smg_display_id = -1;
-
- CHECK_ERR("endwin: smg$delete_pasteboard",
- SMG$DELETE_PASTEBOARD(&smg_pasteboard_id, 0));
- smg_pasteboard_id = -1;
-#endif /* COMMENT */
-}
-
-#ifdef COMMENT
-/* DECC 6.2 screams bloody murder about printw ("not enough args") */
-/* but adding the following prototype only makes it holler louder. */
-#ifdef __DECC
-/* "varargs" prototype for printw */
-_PROTOTYP(static int printw,(char *, ...));
-#endif /* __DECC */
-#endif /* COMMENT */
-
-#ifdef __DECC
-#include <stdarg.h>
-_PROTOTYP(static void printw,(char *, ...));
-static void
-printw(char *str,...) {
- char buf[255];
- va_list ap;
- $DESCRIPTOR(text_dsc, 0);
- text_dsc.dsc$a_pointer=buf;
- if (!smg_open)
- return;
- va_start(ap,str);
- text_dsc.dsc$w_length = vsprintf(buf, str, ap);
- va_end(ap);
- CHECK_ERR("printw: smg$put_chars",
- smg$put_chars(&smg_display_id, &text_dsc, 0, 0, 0, 0, 0));
-}
-#else
-static void
-printw(str, a1, a2, a3, a4, a5, a6, a7, a8)
- char *str;
- long a1, a2, a3, a4, a5, a6, a7, a8;
-/* printw */ {
- char buf[255];
- $DESCRIPTOR(text_dsc, 0);
- if (!smg_open)
- return;
- text_dsc.dsc$a_pointer=buf;
- text_dsc.dsc$w_length = sprintf(buf, str, a1, a2, a3, a4, a5, a6, a7, a8);
- CHECK_ERR("printw: smg$put_chars",
- smg$put_chars(&smg_display_id, &text_dsc, 0, 0, 0, 0, 0));
-}
-#endif /* __DECC */
-
-#define CK_CURPOS
-int
-ck_curpos(row, col) {
- debug(F111,"VMS smg ck_curpos",ckitoa(row),col);
- if (!smg_inited || !smg_open) {
- initscr();
- }
- debug(F101,"VMS smg curpos smg_open","",smg_open);
- if (!smg_open)
- return(0);
- debug(F111,"VMS smg ck_curpos",ckitoa(row-1),col-1);
- move(row - 1, col - 1); /* SMG is 0-based */
- refresh();
- /* endwin(); */
- return(0);
-}
-
-int
-ck_cls() {
- debug(F101,"VMS smg ck_cls smg_inited","",smg_inited);
- if (!smg_inited || !smg_open) {
- initscr();
- }
- debug(F101,"VMS smg ck_cls smg_open","",smg_open);
- if (!smg_open)
- return(0);
- clear();
- refresh();
- /* endwin(); */
- return(0);
-}
-
-int
-ck_cleol() {
- debug(F101,"VMS smg ck_cleol smg_inited","",smg_inited);
- if (!smg_inited || !smg_open) {
- initscr();
- }
- debug(F101,"VMS smg ck_cleol smg_open","",smg_open);
- if (!smg_open)
- return(0);
- clrtoeol();
- refresh();
- /* endwin(); */
- return(0);
-}
-#endif /* CK_SMG */
-
-#ifdef MYCURSES
-/*
- Do-it-yourself curses implementation for VMS, OS/2 and other ANSI/VT-100's.
- Supports only the VT52 and VT1xx (and later VT2xx/3xx/4xx) terminals.
- By Terry Kennedy, St Peters College.
-
- First, some stuff we can just ignore:
-*/
-
-static int
-touchwin(x) int x; {
- return(0);
-}
-static int
-initscr() {
- return(0);
-}
-static int
-refresh() {
- return(0);
-}
-static int
-endwin() {
- return(0);
-}
-
-/*
- * Now, some stuff we need to do:
- */
-
-_PROTOTYP( int move, (int, int) );
-#ifndef OS2
-int
-move(row, col) int row, col; {
- if (isvt52)
- printf("\033Y%c%c", row + 037, col + 037);
- else
- printf("\033[%d;%dH", row + 1, col + 1);
- return(0);
-}
-
-int
-clear() {
- move(0,0);
- if (isvt52)
- printf("\033J");
- else
- printf("\033[J");
- return(0);
-}
-
-int
-clrtoeol() {
- if (isvt52)
- printf("\033K");
- else
- printf("\033[K");
- return(0);
-}
-
-#define CK_CURPOS
-int
-ck_cls() {
- return(clear());
-}
-
-int
-ck_cleol() {
- return(clrtoeol());
-}
-
-int
-ck_curpos(row, col) int row, col; {
- move(row, col);
- return(0);
-}
-
-#else /* OS2 */
-/* Windows NT and Windows 95 do not provide ANSI emulation */
-/* Therefore we might as well not use it for OS/2 either */
-
-int
-move(row, col) int row, col; {
-#ifndef ONETERMUPD
- SetCurPos(row, col);
-#endif /* ONETERMUPD */
- lgotoxy( VCMD, col+1, row+1);
- VscrnIsDirty(VCMD);
- return(0);
-}
-
-int
-clear() {
- viocell cell;
- move(0,0);
-#ifdef ONETERMUPD
- if (VscrnGetBufferSize(VCMD) > 0) {
- VscrnScroll(VCMD, UPWARD, 0,
- VscrnGetHeight(VCMD)-(1),
- VscrnGetHeight(VCMD)-(0), TRUE, CHR_SP);
- cleartermscreen(VCMD);
- }
-#else
- cell.c = ' ';
- cell.a = colorcmd;
- WrtNCell(cell, cmd_rows * cmd_cols, 0, 0);
-#endif /* ONETERMUPD */
- return(0);
-}
-
-int
-clrtoeol() {
- USHORT row, col;
- viocell cell;
-
- cell.c = ' ';
- cell.a = colorcmd;
-#ifndef ONETERMUPD
- GetCurPos(&row, &col );
- WrtNCell(cell, cmd_cols - col -1, row, col);
-#endif /* ONETERMUPD */
- clrtoeoln(VCMD,CHR_SP);
- return(0);
-}
-
-#define CK_CURPOS
-int
-ck_curpos(row, col) int row, col; {
- move(row, col);
- return(0);
-}
-
-int
-ck_cls() {
- return(clear());
-}
-
-int
-ck_cleol() {
- return(clrtoeol());
-}
-
-#endif /* OS2 */
-#endif /* MYCURSES */
-
-#ifndef NOTERMCAP
-#ifndef CK_CURPOS
-#define CK_CURPOS
-
-/* Termcap/Terminfo section */
-
-static char cur_cls[32] = { NUL, NUL };
-static char cur_cleol[32] = { NUL, NUL };
-static char cur_cm[64] = { NUL, NUL };
-static char tgsbuf[128] = { NUL, NUL };
-
-static
-#ifdef CK_ANSIC
-void
-#endif /* CK_ANSIC */
-ck_termset(x) int x; {
- cur_cls[0] = NUL;
- cur_cleol[0] = NUL;
- cur_cm[0] = NUL;
-#ifdef tgetent
- debug(F100,"tgetent is a macro","",0);
-#endif /* tgetent */
-#ifdef tgetstr
- debug(F100,"tgetstr is a macro","",0);
-#endif /* tgetstr */
-#ifdef tputs
- debug(F100,"tputs is a macro","",0);
-#endif /* tputs */
-#ifdef tgoto
- debug(F100,"tgoto is a macro","",0);
-#endif /* tgoto */
-#ifdef NOTERMCAP
- /* tgetstr() gets a segmentation fault on OSF/1 */
- debug(F100,"ck_termset NOTERMCAP","",0);
-#else
- if (notermcap) {
- debug(F100,"ck_termset notermcap","",0);
- return;
- }
- debug(F101,"ck_termset x","",x);
- if (x > 0) {
- char * bp;
- bp = tgsbuf;
- *bp = NUL;
- debug(F110,"ck_termset calling tgetstr","cl",0);
- if (tgetstr("cl", &bp)) { /* Get clear-screen code */
- debug(F110,"ck_termset tgetstr cl",tgsbuf,"");
- if ((int)strlen(tgsbuf) < 32)
- ckstrncpy(cur_cls,tgsbuf,32);
- } else
- return;
- bp = tgsbuf;
- if (tgetstr("ce", &bp)) { /* Get clear-to-end-of-line code */
- debug(F110,"ck_termset tgetstr ce",tgsbuf,"");
- if ((int)strlen(tgsbuf) < 32)
- ckstrncpy(cur_cleol,tgsbuf,32);
- } else
- return;
- bp = tgsbuf;
- if (tgetstr("cm", &bp)) { /* Get cursor-movement code */
- debug(F110,"ck_termset tgetstr cm",tgsbuf,"");
- if ((int)strlen(tgsbuf) < 64)
- ckstrncpy(cur_cm,tgsbuf,64);
- } else
- return;
- }
-#endif /* NOTERMCAP */
-}
-
-#ifndef TPUTSFNTYPE
-#ifdef TPUTSISVOID
-#define TPUTSFNTYPE void
-#else
-#define TPUTSFNTYPE int
-#endif /* TPUTSISVOID */
-#endif /* TPUTSFNTYPE */
-
-#ifndef TPUTSARGTYPE
-#ifdef HPUX9
-#define TPUTSARGTYPE char
-#else
-#ifdef HPUX10
-#define TPUTSARGTYPE char
-#else
-#define TPUTSARGTYPE int
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* TPUTSARGTYPE */
-
-static TPUTSFNTYPE
-#ifdef CK_ANSIC
-ck_outc(TPUTSARGTYPE x)
-#else
-ck_outc(x) TPUTSARGTYPE x;
-#endif /* CK_ANSIC */
-{ /* To satisfy tputs() arg3 prototype */
- int rc;
- char c;
- c = (char) x;
- rc = (inserver) ? ttoc(c) : conoc(c);
-#ifndef TPUTSISVOID
- return(rc);
-#endif /* TPUTSISVOID */
-}
-
-int
-ck_curpos(row, col) int row, col; {
-#ifdef CK_ANSIC
- TPUTSFNTYPE (*fn)(TPUTSARGTYPE);
-#else
- TPUTSFNTYPE (*fn)();
-#endif /* CK_ANSIC */
- if (!fxd_inited)
- fxdinit(9999);
- if (!cur_cm[0]) { /* We don't have escape sequences */
-#ifdef COMMENT
- return(-1); /* Do nothing */
-#else
- /* Both C-Kermit's SCREEN command and ANSI/VT100 are 1-based */
- printf("\033[%d;%dH", row, col); /* Or default to ANSI */
-#endif /* COMMENT */
- } else {
- fn = ck_outc;
- /* termcap/terminfo is 0-based */
- tputs(
-#ifdef TPUTSARG1CONST
- (const char *)
-#endif /* TPUTSARG1CONST */
- tgoto(cur_cm,col-1,row-1),1,fn);
- }
- return(0);
-}
-
-int
-ck_cls() {
-#ifdef CK_ANSIC
- TPUTSFNTYPE (*fn)(TPUTSARGTYPE);
-#else
- TPUTSFNTYPE (*fn)();
-#endif /* CK_ANSIC */
- if (!fxd_inited)
- fxdinit(9999);
- if (!cur_cls[0]) { /* If we don't have escape sequences */
-#ifdef COMMENT
- return(-1); /* Do nothing */
-#else
- printf("\033[;H\033[2J"); /* Or default to ANSI */
-#endif /* COMMENT */
- } else {
- fn = ck_outc;
- debug(F111,"ck_cls 2",cur_cls,fxd_inited);
- tputs(cur_cls,cmd_rows,fn);
- }
- return(0);
-}
-
-int
-ck_cleol() {
-#ifdef CK_ANSIC
- TPUTSFNTYPE (*fn)(TPUTSARGTYPE);
-#else
- TPUTSFNTYPE (*fn)();
-#endif /* CK_ANSIC */
- if (!fxd_inited)
- fxdinit(9999);
- if (!cur_cleol[0]) { /* If we don't have escape sequences */
-#ifdef COMMENT
- return(-1); /* Do nothing */
-#else
- printf("\033[K"); /* Or use ANSI */
-#endif /* COMMENT */
- } else {
- fn = ck_outc;
- tputs(cur_cleol,1,fn);
- }
- return(0);
-}
-#endif /* CK_CURPOS */
-#else
-static void
-ck_termset(x) int x; {
- if (x) return;
-}
-#endif /* NOTERMCAP */
-
-#ifndef CK_CURPOS
-#define CK_CURPOS
-int
-ck_cls() {
- printf("\033[;H\033[2J");
- return(0);
-}
-
-int
-ck_cleol() {
- printf("\033[K");
- return(0);
-}
-
-int
-ck_curpos(row, col) int row, col; {
- printf("\033[%d;%dH", row, col);
- return(0);
-}
-#endif /* CK_CURPOS */
-
-
-#ifndef NOXFER
-static int cinit = 0; /* Flag for curses init'd */
-static int cendw = 0; /* endwin() was called */
-
-static
-#ifdef CK_ANSIC /* Because VOID used by curses.h */
-void
-#else
-#ifdef MYCURSES
-VOID
-#else
-int
-#endif /* MYCURSES */
-#endif /* CK_ANSIC */
-#ifdef CK_ANSIC /* Update % transfered and % bar */
-updpct(long old, long new)
-#else /* CK_ANSIC */
-updpct(old, new) long old, new;
-#endif /* CK_ANSIC */
-/* updpct */ {
-#ifdef COMMENT
- int m, n;
- move(CW_PCD,22);
- printw("%ld", new);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_PCD, (long) new);
-#endif /* K95G */
-#endif /* KUI */
-#ifdef CK_PCT_BAR
- if (thermometer) {
- if (old > new) {
- old = 0;
- move(CW_PCD, 26);
- clrtoeol();
- }
- m = old/2;
- move(CW_PCD, 26 + m);
- n = new / 2 - m;
-#ifndef OS2
- while (n > 0) {
- if ((m + 1) % 5 == 0)
- printw("*");
- else
- printw("=");
- m++;
- n--;
- }
- if (new % 2 != 0) printw("-");
- /* move(CW_PCD, 22+53); */
-#else /* OS2 */
- while (n > 0) {
- printw("%c", '\333');
- m++; n--;
- }
- if (new % 2 != 0)
- printw("%c", '\261');
-#endif /* OS2 */
- }
-#endif /* CK_PCT_BAR */
- /* clrtoeol(); */
-#else /* !COMMENT */
-#ifdef OS2
-#define CHAR1 '\333' /* OS2 - CP437 */
-#define CHAR2 '\261'
-#else
-#define CHAR1 '/' /* Default */
-#define CHAR2 '-'
-#endif /* OS2 */
- debug(F101,"updpct old","",old);
- debug(F101,"updpct new","",new);
- move(CW_PCD,22);
- printw("%-3ld", new); /* (was) printw("%ld", new); */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PCD, (long) new );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef CK_PCT_BAR
- if (thermometer) {
- int m, n;
-
- if (old > new) {
- old = 0 ;
- move(CW_PCD, 26);
- clrtoeol();
- }
- if (new <= 100L) {
- m = old / 2;
- n = new / 2 - m;
- move(CW_PCD, 26+m);
- while (n-- > 0)
- printw("%c", CHAR1);
- if (new % 2 != 0)
- printw("%c", CHAR2);
- }
- }
-#endif /* CK_PCT_BAR */
-#endif /* COMMENT */
-}
-
-static CK_OFF_T old_tr = (CK_OFF_T)-1; /* Time remaining previously */
-
-static CK_OFF_T
-#ifdef CK_ANSIC
-shoetl(CK_OFF_T old_tr, long cps, CK_OFF_T fsiz, CK_OFF_T howfar)
-#else
- shoetl(old_tr, cps, fsiz, howfar) long cps; CK_OFF_T old_tr, fsiz, howfar;
-#endif /* CK_ANSIC */
-/* shoetl */ { /* Estimated time left in transfer */
- CK_OFF_T tr; /* Time remaining, seconds */
-
-#ifdef GFTIMER
- if (fsiz > 0L && cps > 0L)
- tr = (CK_OFF_T)((CKFLOAT)(fsiz - howfar) / (CKFLOAT)cps);
- else
- tr = (CK_OFF_T)-1;
-#else
- tr = (fsiz > 0L && cps > 0L) ?
- ((fsiz - howfar) / cps) :
- (CK_OFF_T)-1;
-#endif /* GFTIMER */
- move(CW_TR,22);
- if (tr > (CK_OFF_T)-1) {
- if (tr != old_tr) {
- printw("%s",hhmmss(tr));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long)CW_TR, (long)hhmmss(tr));
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- }
- } else {
- printw("(unknown)");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TR, (long) "(unknown)" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- }
- return(tr);
-}
-
-static long
-#ifdef CK_ANSIC
-shocps(int pct, CK_OFF_T fsiz, CK_OFF_T howfar)
-#else
-shocps(pct, fsiz, howfar) int pct; CK_OFF_T fsiz, howfar;
-#endif /* CK_ANSIC */
-/* shocps */ {
-#ifdef CPS_WEIGHTED
- static CK_OFF_T oldffc = 0L;
-#endif /* CPS_WEIGHTED */
-#ifdef GFTIMER
- CKFLOAT secs, xx;
-#else
- CK_OFF_T secs, xx;
-#endif /* GFTIMER */
-
-#ifdef GFTIMER
- xx = (gtv >= 0.0) ? gtv : 0.0; /* Floating-point version */
- gtv = gftimer();
- if ((gtv - oldgtv) < (CKFLOAT) 1.0) /* Only do this once per second */
- return(oldcps);
- oldgtv = xx;
-#else
- xx = (gtv >= 0) ? gtv : 0; /* Whole-number version */
- gtv = gtimer();
- if ((gtv - oldgtv) < 1)
- return(oldcps);
- oldgtv = xx;
-#endif /* GFTIMER */
-
-#ifdef CPS_WEIGHTED
- /* debug(F100,"SHOCPS: WEIGHTED","",0); */
- if (gtv != oldgtv) { /* The first packet is ignored */
- if (ffc < oldffc)
- oldffc = ffc;
- oldcps = cps;
- if (oldcps && oldgtv >
-#ifdef GFTIMER
- 1.0
-#else
- 1
-#endif /* GFTIMER */
- ) { /* The first second is ignored */
-/*
- This version of shocps() produces a weighted average that some
- people like, but most people find it disconcerting and bombard us
- with questions and complaints about why the CPS figure fluctuates so
- wildly. So now you only get the weighted average if you build the
- program yourself with CPS_WEIGHTED defined.
-*/
-#ifndef CPS_VINCE
-#ifdef GFTIMER
- cps = (long)((((CKFLOAT)oldcps * 3.0) +
- (CKFLOAT)(ffc - oldffc) / (gtv-oldgtv) ) / 4.0);
-#else
- cps = ( (oldcps * 3) + (ffc - oldffc) / (gtv-oldgtv) ) / 4;
-#endif /* GFTIMER */
-#else
-/* And an alternate weighting scheme from Vincent Fatica... */
- cps = (3 *
- ((1+pct/300)*oldffc/oldgtv+(1-pct/100)*(ffc-oldffc)/(gtv-oldgtv)))
- / 4;
-#endif /* CPS_VINCE */
- } else {
- /* No weighted average since there is nothing to weigh */
-#ifdef GFTIMER
- cps = (long)(gtv != 0.0 ?
- (CKFLOAT)(ffc - oldffc) / (gtv - oldgtv) :
- (ffc - oldffc)) ;
-#else
- cps = gtv ? (ffc - oldffc) / (gtv - oldgtv) : (ffc - oldffc) ;
-#endif /* GFTIMER */
- }
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"SHOCPS: pct ","",pct);
- debug(F101,"SHOCPS: gtv ","",gtv);
- debug(F101,"SHOCPS: oldgtv","",oldgtv);
- debug(F101,"SHOCPS: dgtv ","",(long)(gtv-oldgtv));
- debug(F101,"SHOCPS: ffc ","",ffc);
- debug(F101,"SHOCPS: oldffc","",oldffc);
- debug(F101,"SHOCPS: dffc ","",ffc-oldffc);
- debug(F101,"SHOCPS: cps ","",cps);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- move(CW_CP,22);
- printw("%ld", cps);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, (long) cps );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldffc = ffc;
- }
-#else /* !CPS_WEIGHTED */
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F100,"SHOCPS: NOT WEIGHTED","",0);
- debug(F101,"SHOCPS: pct ","",pct);
- debug(F101,"SHOCPS: gtv ","",gtv);
- debug(F101,"SHOCPS: oldgtv ","",oldgtv);
- debug(F101,"SHOCPS: dgtv ","",(long)gtv - (long)oldgtv);
- debug(F101,"SHOCPS: ffc ","",ffc);
- debug(F101,"SHOCPS: oldffc ","",oldffc);
- debug(F101,"SHOCPS: dffc ","",ffc-oldffc);
- debug(F101,"SHOCPS: cps ","",cps);
- debug(F101,"SHOCPS: filcnt ","",filcnt);
-#ifdef GFTIMER
- debug(F101,"SHOCPS: fpfsecs","",fpfsecs);
-#endif /* GFTIMER */
- }
- debug(F101,"shocps gtv","",gtv);
-#endif /* DEBUG */
-#ifdef GFTIMER
-#endif /* COMMENT */
- /* debug(F101,"shocps fpfsecs","",fpfsecs); */
- secs = gtv - fpfsecs;
- /* debug(F101,"shocps secs","",(long)secs); */
- if (secs > 0.0) {
- cps = (long)((CKFLOAT) ffc / secs);
- /* debug(F101,"shocps cps","",cps); */
- move(CW_CP,22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, (long) cps );
-#endif /* K95G */
-#endif /* KUI */
- printw("%ld", cps);
- clrtoeol();
- }
-#else /* Not GFTIMER */
- if ((secs = gtv - fsecs) > 0) {
- cps = (secs < 1L) ? ffc : ffc / secs;
- move(CW_CP,22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, (long) cps );
-#endif /* K95G */
-#endif /* KUI */
- printw("%ld", cps);
- clrtoeol();
- }
-#endif /* GFTIMER */
-#endif /* CPS_WEIGHTED */
-
- if (cps > peakcps && /* Peak transfer rate */
- ((what & W_SEND && spackets > wslots + 4) ||
- (!(what & W_SEND) && spackets > 10))) {
- peakcps = cps;
- }
- old_tr = shoetl(old_tr, cps, fsiz, howfar);
- return(cps);
-}
-
-static
-#ifdef CK_ANSIC /* Because VOID used by curses.h */
-void
-#else
-#ifdef MYCURSES
-VOID
-#else
-int
-#endif /* MYCURSES */
-#endif /* CK_ANSIC */
-scrft() { /* Display file type */
- char xferstr[256];
- xferstr[0] = NUL;
- debug(F101,"scrft binary","",binary);
- if (binary) {
- switch(binary) {
- case XYFT_L:
- ckstrncpy(xferstr,"LABELED",256);
- break;
- case XYFT_I:
- ckstrncpy(xferstr,"IMAGE",256);
- break;
- case XYFT_U:
- ckstrncpy(xferstr,"BINARY UNDEFINED",256);
- break;
- case XYFT_M:
- ckstrncpy(xferstr,"MACBINARY",256);
- break;
- case XYFT_X:
- ckstrncpy(xferstr,"TENEX",256);
- break;
- default:
- case XYFT_B:
- ckstrncpy(xferstr,"BINARY",256);
- break;
- }
-#ifdef CK_RESEND
- if (what & W_SEND && sendstart > 0L) {
- if (sendmode == SM_PSEND) {
- ckstrncat(xferstr, " / partial", 256);
- } else if (sendmode == SM_RESEND) {
- ckstrncat(xferstr, " / resend", 256);
- }
- } else if (what & W_RECV && rs_len > 0L) {
- ckstrncat(xferstr, " / resend", 256);
- }
-#endif /* CK_RESEND */
- } else {
-
-#ifndef NOCSETS
- ckstrncpy(xferstr,"TEXT",256);
-#ifdef NEWFTP
-#ifndef NOUNICODE
- if (what & W_FTP) {
- if (ftp_csx < 0)
- ckstrncat(xferstr," (no translation)", 256);
- else
- ckmakxmsg(&xferstr[4],252,
- " (",
- fcsinfo[(what & W_SEND) ? ftp_csl : ftp_csx].keyword,
- " => ",
- fcsinfo[(what & W_SEND) ? ftp_csx : ftp_csl].keyword,
- ")",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- } else
-#endif /* NOUNICODE */
-#endif /* NEWFTP */
- if (tcharset == TC_TRANSP) {
- ckstrncat(xferstr, " (no translation)", 256);
- } else {
- if (what & W_SEND) {
- sprintf( &xferstr[strlen(xferstr)], /* safe */
- " (%s => %s)",
- fcsinfo[fcharset].keyword, /* built-in keywords */
- tcsinfo[tcharset].keyword /* lengths are controlled */
- );
- } else {
- sprintf( &xferstr[strlen(xferstr)], /* safe */
- " (%s => %s)",
- tcsinfo[tcharset].keyword, /* built-in keywords */
- fcsinfo[fcharset].keyword); /* lengths controlled */
- }
- }
-#endif /* NOCSETS */
- }
- move(CW_TYP,22);
- printw("%s", xferstr);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TYP, (long) xferstr );
-#endif /* K95G */
-#endif /* KUI */
- return;
-}
-
-#ifdef CK_NEWTERM
-static FILE *ck_stdout = NULL;
-static int ck_fd = -1;
-#endif /* CK_NEWTERM */
-
-static long pct = 0L, oldpct = 0L, oldrtt = -1L;
-static int oldtyp = 0, oldwin = -1, oldtry = -1, oldlen = -1, oldtim = -1;
-
-#ifdef NETCONN
-static char *netname[] = {
- "none", /* 00 */
- "TCP/IP", /* 01 TCP (Sockets) */
- "TCP/IP", /* 02 TCP (Streams) */
- "X.25", /* 03 SunLink X.24 */
- "DECnet", /* 04 DECnet */
- "VAX PSI", /* 05 VAX PSI */
- "Named Pipes", /* 06 LAN Manager Named Pipe */
- "X.25", /* 07 Stratus VOS X.25 */
- "NetBIOS", /* 08 IBM NETBIOS */
- "SuperLAT", /* 07 Meridian SuperLAT */
- "File", /* 10 File */
- "Command", /* 11 Subprocess (pipe) */
- "DLL", /* 12 DLL does i/o */
- "X.25", /* 13 IBM AIXLink X.25 */
- "X.25", /* 14 HP-UX X.25 */
- "PTY", /* 15 Pseudoterminal */
- "SSH", /* 16 SSH */
- "<ERROR>", /* 17 In case new types are added */
- "<ERROR>", /* 18 but nobody remembers to update */
- "<ERROR>", /* 19 this table ... */
- NULL /* 20 */
-};
-static int nnetname = (sizeof(netname) / sizeof(char *));
-
-#endif /* NETCONN */
-
-#ifdef CK_ANSIC
-void
-screenc(int f, char c,CK_OFF_T n,char *s)
-#else
-CKVOID
-screenc(f,c,n,s)
-int f; /* argument descriptor */
-char c; /* a character or small integer */
-CK_OFF_T n; /* a long integer */
-char *s; /* a string */
-#endif /* CK_ANSIC */
-/* screenc() */ {
-#ifdef CK_SSL
- extern int tls_active_flag, ssl_active_flag;
-#endif /* CK_SSL */
-#ifdef RLOGCODE
- extern int ttnproto;
-#endif /* RLOGCODE */
- static int q = 0;
- static long fcnt = 0L; /* Number of files transferred */
- static CK_OFF_T fsiz = (CK_OFF_T)-1; /* Copy of file size */
- static CK_OFF_T fbyt = 0L; /* Total file bytes of all files transferred */
- static CK_OFF_T howfar = 0L; /* How much of current file has been xfer'd */
- static int pctlbl = 0L; /* Percent done vs Bytes so far */
- long cps = 0L;
-
- int net = 0;
- int xnet = 0;
- int ftp = 0;
- int len; /* Length of string */
- int errors = 0; /* Error counter */
- int x; /* Worker */
-
- debug(F101,"screenc cinit","",cinit);
- debug(F101,"screenc cendw","",cendw);
-
- if (!s) s = ""; /* Always do this. */
-
- ftp = (what & W_FTP) ? 1 : 0; /* FTP or Kermit */
- net = network || ftp;
- xnet = ftp ? 1 : nettype; /* NET_TCPB == 1 */
-
- if (cinit == 0 || cendw > 0) { /* Handle borderline cases... */
- if (f == SCR_CW) { /* Close window, but it's not open */
- ft_win = 0;
- return;
- }
- debug(F111,"screenc A",s,f);
- if (f == SCR_EM ||
- (f == SCR_PT && c == 'E')) { /* Fatal error before window open */
- conoll(""); conoc('?'); conoll(s); return; /* Regular display */
- }
- }
- if (cinit == 0) { /* Only call initscr() once */
- char * s;
- /* Check these now -- if they are defined but not numeric */
- /* they can crash curses */
- s = getenv("LINES");
- if (s) if (!rdigits(s)) {
- printf("?LINES variable not numeric: \"%s\".\n",s);
- printf("(Fullscreen display disabled)\n");
- fdispla = XYFD_S;
- return;
- }
- s = getenv("COLUMNS");
- if (s) if (!rdigits(s)) {
- printf("?COLUMNS variable not numeric: \"%s\".\n",s);
- printf("(Fullscreen display disabled)\n");
- fdispla = XYFD_S;
- return;
- }
- cendw = 1; /* New window needs repainting */
-#ifdef COMMENT
- if (!initscr()) { /* Oops, can't initialize window? */
-/*
- In fact, this doesn't happen. "man curses" says initscr() halts the
- entire program if it fails, which is true on the systems where I've
- tested it. It will fail if your terminal type is not known to it.
- That's why SET FILE DISPLAY FULLSCREEN calls tgetent() to make sure the
- terminal type is known before allowing a curses display.
-*/
- fprintf(stderr,"CURSES INITSCR ERROR\r\n");
- fdispla = XYFD_S; /* Fall back to CRT display */
- return;
- } else {
- cinit++; /* Window initialized ok */
- debug(F100,"CURSES INITSCR OK","",0);
- }
-#else /* Save some memory. */
-#ifdef CK_NEWTERM
- /* (From Andy Fyfe <andy@vlsi.cs.caltech.edu>)
- System V curses seems to reserve the right to alter the buffering
- on the output FILE* without restoring it. Fortunately System V
- curses provides newterm(), an alternative to initscr(), that
- allows us to specify explicitly the terminal type and input and
- output FILE pointers. Thus we duplicate stdout, and let curses
- have the copy. The original remains unaltered. Unfortunately,
- newterm() seems to be particular to System V.
- */
- s = getenv("TERM");
- if (ck_fd < 0) {
- ck_fd = dup(fileno(stdout));
- ck_stdout = (ck_fd >= 0) ? (FILE *)fdopen(ck_fd, "w") : NULL;
- }
- debug(F100,"screenc newterm...","",0);
-
-/* NOTE: It might be necessary to do this with stdin too! */
-/* This would have been the case in FreeBSD 4.1 but they fixed the */
-/* problem by restoring the buffering of stdin before the final release. */
-/* (But T.E. Dickey says stdin is not buffered?) */
-
- if (ck_stdout == NULL || newterm(s, ck_stdout, stdin) == 0) {
- fprintf(stderr,
- "Fullscreen display not supported for terminal type: %s\r\n",s);
- fdispla = XYFD_S; /* Use CRT instead */
- return;
- }
- debug(F100,"screenc newterm ok","",0);
-#else
- debug(F100,"screen calling initscr","",0);
- initscr(); /* Initialize curses. */
- debug(F100,"screen initscr ok","",0);
-#endif /* CK_NEWTERM */
- cinit++; /* Remember curses was initialized. */
-#endif /* COMMENT */
- }
- ft_win = 1; /* Window is open */
- if (repaint) {
-#ifdef CK_WREFRESH
-/*
- This totally repaints the screen, just what we want, but we can only
- do this with real curses, and then only if clearok() and wrefresh() are
- provided in the curses library.
-*/
-#ifdef OS2
- RestoreCmdMode();
-#else
-#ifdef QNX
-#ifndef QNX16
- clearok(stdscr, 1); /* QNX doesn't have curscr */
-#endif /* QNX16 */
- wrefresh(stdscr);
-#else
- wrefresh(curscr);
-#endif /* QNX */
-#endif /* OS2 */
-#else /* No CK_WREFRESH */
-/*
- Kermit's do-it-yourself method, works with all types of fullscreen
- support, but does not repaint all the fields. For example, the filename
- is lost, because it arrives at a certain time and never comes again, and
- Kermit presently does not save it anywhere. Making this method work for
- all fields would be a rather major recoding task, duplicating what curses
- already does, and would add a lot of complexity and storage space.
-*/
- cendw = 1;
-#endif /* CK_WREFRESH */
- repaint = 0;
- }
- if (cendw) { /* endwin() was called previously */
-#ifdef VMS
- initscr(); /* (or should have been!) */
- clear();
- touchwin(stdscr);
- refresh();
-#else
-#ifdef QNX
-/*
- In QNX, if we don't call initscr() here we core dump.
- I don't have any QNX curses documentation, but other curses manuals
- say that initscr() should be called only once per application, and
- experience shows that on other systems, calling initscr() here generally
- results in a core dump.
-*/
- debug(F100,"screenc re-calling initscr QNX","",0);
- initscr();
- clear();
- refresh();
-#ifdef COMMENT
-/*
- But even so, second and subsequent curses displays are messed up.
- Calling touchwin, refresh, etc, doesn't make any difference.
-*/
- debug(F100,"screenc calling touchwin QNX","",0);
- touchwin(stdscr);
- debug(F100,"screenc calling refresh QNX","",0);
- refresh();
-#endif /* COMMENT */
-
-#else /* All others... */
- debug(F100,"screenc calling clear","",0);
- clear();
- debug(F100,"screenc clear ok","",0);
-#endif /* QNX */
-#endif /* VMS */
- debug(F100,"screenc setup ok","",0);
- debug(F100,"screenc doing first move","",0);
- move(CW_BAN,0); /* Display the banner */
- debug(F110,"screenc myhost",myhost,0);
-#ifdef TCPSOCKET
- debug(F110,"screenc myipaddr",myipaddr,0);
-#endif /* TCPSOCKET */
-#ifdef HPUX1010
- debug(F100,"screenc calling first printw...","",0);
-/* Right here is where HP-UX 10.10 libxcurse.1 Rev 76.20 hangs... */
-#endif /* HPUX1010 */
- if (myhost[0]) {
-#ifdef TCPSOCKET
- if (!myipaddr[0]
-#ifdef OS2
- /* We need to perform this test because on non-TCP/IP */
- /* systems the call to getlocalipaddr() results in a */
- /* DNS Lookup which takes several minutes to time out */
- && net &&
- (xnet == NET_TCPA || xnet == NET_TCPB
-#ifdef SSHBUILTIN
- || xnet == NET_SSH
-#endif /* SSHBUILTIN */
- )
-#endif /* OS2 */
- )
- getlocalipaddr();
- if (myipaddr[0] && strcmp((char *)myhost,(char *)myipaddr))
- printw("%s, %s [%s]",versio,(char *)myhost,(char *)myipaddr);
- else
-#endif /* TCPSOCKET */
- printw("%s, %s",versio,(char *)myhost);
- } else {
- printw("%s",versio);
- }
-#ifdef HPUX1010
- debug(F100,"screenc first printw returns","",0);
-#endif /* HPUX1010 */
- move(CW_DIR,3);
- printw("Current Directory: %s",zgtdir());
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) zgtdir() );
-#endif /* K95G */
-#endif /* KUI */
- if (net) {
- move(CW_LIN,8);
- printw("Network Host: %s",
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "(unknown)") :
-#endif /* NEWFTP */
- ttname
- );
- } else {
- move(CW_LIN,0);
- printw("Communication Device: %s",ttname);
- }
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_LIN, (long) ttname );
-#endif /* K95G */
-#endif /* KUI */
-
- if (net) {
- move(CW_SPD,8);
- printw("Network Type: ");
- } else {
- move(CW_SPD,1);
- printw("Communication Speed: ");
- }
- move(CW_SPD,22); /* Serial speed or network type */
- if (net) {
-#ifdef NETCONN
- int secure = 0;
- char * xname;
- if (xnet > nnetname)
- xname = "[ERROR]";
- else
- xname = netname[xnet];
-#ifdef NEWFTP
- if (ftp) {
- if (ftpissecure())
- secure = 1;
- } else
-#endif /* NEWFTP */
- if (0
-#ifdef SSHBUILTIN
- || IS_SSH()
-#endif /* SSHBUILTIN */
-#ifdef CK_ENCRYPTION
- || ck_tn_encrypting() && ck_tn_decrypting()
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- || tls_active_flag || ssl_active_flag
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
-#ifdef CK_ENCRYPTION
- || ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_ENCRYPTION */
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
- ) {
- secure = 1;
- }
- if (secure) {
-#ifdef KUI
-#ifndef K95G
- char buf[30];
- sprintf(buf,"%s (SECURE)",xname);
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) buf
- );
-#endif /* K95G */
-#endif /* KUI */
- printw("%s (SECURE)",xname);
- } else {
- printw("%s",xname);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) xname
- );
-#endif /* K95G */
-#endif /* KUI */
- }
-#else
- printw("(network)");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(network)"
- );
-#endif /* K95G */
-#endif /* KUI */
-#endif /* NETCONN */
- } else {
- if (speed < 0L)
- speed = ttgspd();
- if (speed > 0L) {
- if (speed == 8880) {
- printw("75/1200");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "75/1200"
- );
-#endif /* K95G */
-#endif /* KUI */
- } else {
- char speedbuf[64] ;
- sprintf(speedbuf, "%ld", speed);
- printw("%s",speedbuf);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) speedbuf
- );
-#endif /* K95G */
-#endif /* KUI */
- }
- } else {
- printw("unknown");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(unknown)"
- );
-#endif /* K95G */
-#endif /* KUI */
- }
- }
- move(CW_PAR,14);
- printw("Parity: %s",ftp ? "none" : parnam((char)parity));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef CK_TIMERS
- if (/* rttflg && */ protocol == PROTO_K) {
- move(CW_TMO, 9); printw("RTT/Timeout:"); }
-#endif /* CK_TIMERS */
- move(CW_TYP,11); printw("File Type:");
- move(CW_SIZ,11); printw("File Size:");
- move(CW_PCD, 8);
- clrtoeol();
- pctlbl = (what & W_SEND);
- printw("%s:", pctlbl ? "Percent Done" : "Bytes So Far");
-
-#ifdef XYZ_INTERNAL
- move(CW_BAR, 1);
- printw("%10s Protocol:", ftp ? "FTP" : ptab[protocol].p_name);
-#endif /* XYZ_INTERNAL */
-#ifdef CK_PCT_BAR
- if (thermometer) {
- oldpct = pct = 0;
- move(CW_BAR,22);
- printw(" ...10...20...30...40...50...60...70...80...90..100");
- move(CW_BAR,22+56);
- }
-#endif /* CK_PCT_BAR */
- move(CW_TR, 1); printw("Estimated Time Left:");
- move(CW_CP, 2); printw("Transfer Rate, CPS:");
- move(CW_WS, 8); printw("Window Slots:%s",
- ((protocol == PROTO_K) && !ftp) ?
- "" : " N/A"
- );
- move(CW_PT, 9); printw("Packet Type:");
- if (ftp || protocol != PROTO_K) {
- move(CW_PT,22);
- printw("%s", "N/A");
- move(CW_PC, 11); printw("I/O Count:");
- move(CW_PL, 10); printw("I/O Length:");
- } else {
- move(CW_PC, 8); printw("Packet Count:");
- move(CW_PL, 7); printw("Packet Length:");
- }
-#ifndef COMMENT
- move(CW_PR, 9); printw("Error Count:");
-#else
- move(CW_PR, 2); printw("Packet Retry Count:");
-#endif
-#ifdef COMMENT
- move(CW_PB, 2); printw("Packet Block Check:");
-#endif /* COMMENT */
- move(CW_ERR,10); printw("Last Error:");
- move(CW_MSG, 8); printw("Last Message:");
- if (xfrmsg) {
- move(CW_MSG, 22); printw("%s",xfrmsg);
- makestr(&xfrmsg,NULL);
- }
- move(CW_INT, 0);
- if (!xfrint) {
- printw("(Transfer interruption is disabled)");
- } else {
-#ifdef CK_NEED_SIG
- printw(
-"<%s>X to cancel file, <%s>Z to cancel group, <%s><CR> to resend last packet",
- dbchr(escape), dbchr(escape), dbchr(escape)
- );
- move(CW_INT + 1, 0);
- printw(
-"<%s>E to send Error packet, ^C to quit immediately, <%s>L to refresh screen.",
- dbchr(escape), dbchr(escape)
- );
-#else /* !CK_NEED_SIG */
- move(CW_INT, 0);
-#ifdef OS2
- if (protocol == PROTO_K) {
- printw(
-"X to cancel file, Z to cancel group, <Enter> to resend last packet,"
- );
- }
-#else /* !OS2 */
-#ifdef VMS /* In VMS avoid bottom line */
- printw(
-"X: Cancel this file; E: Cancel transfer; ^C: Quit now; ^W: Refresh screen."
- );
-#else
- printw(
-"X to cancel file, Z to cancel group, <CR> to resend last packet,"
- );
-#endif /* VMS */
-#endif /* OS2 */
-
-#ifndef VMS
- move(CW_INT + 1, 0);
- if (protocol == PROTO_K) {
- printw(
-"E to send Error packet, ^C to quit immediately, ^L to refresh screen."
- );
- } else {
- printw("^C to cancel file transfer.");
- }
-#endif /* VMS */
-#endif /* CK_NEED_SIG */
- }
- refresh();
- cendw = 0;
- }
- debug(F101,"SCREENC switch","",f);
- debug(F000,"SCREENC c","",c);
- debug(F101,"SCREENC n","",n);
-
- len = strlen(s); /* Length of argument string */
- switch (f) { /* Handle our function code */
- case SCR_FN: /* Filename */
- oldpct = pct = 0L; /* Reset percents */
-#ifdef GFTIMER
- gtv = (CKFLOAT) -1.0;
- /* oldgtv = (CKFLOAT) -1.0; */
-#else
- gtv = -1L;
- /* oldgtv = -1L; */
-#endif /* GFTIMER */
- oldwin = -1;
- fsiz = (CK_OFF_T)-1; /* Invalidate previous file size */
- move(CW_PCD,22); /* Erase percent done from last time */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PCD, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_FFC, (long) 0 );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- move(CW_SIZ,22); /* Erase file size from last time */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) 0 );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- move(CW_ERR,22); /* And last error message */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) "" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-#ifdef COMMENT
-#ifdef STREAMING
- if (protocol == PROTO_K && streamok) {
- move(CW_BAR, 1);
-#ifdef XYZ_INTERNAL
- printw(" Kermit STREAMING:");
-#else
- printw(" STREAMING:");
-#endif /* XYZ_INTERNAL */
- }
-#endif /* STREAMING */
-#endif /* COMMENT */
-
- if (what & W_SEND) { /* If we're sending... */
-#ifdef NEWFTP
- if (what & W_FTP) { /* FTP */
- move(CW_NAM,10);
- printw(" FTP PUT:");
- } else
-#endif /* NEWFTP */
-#ifdef CK_RESEND
- switch (sendmode) { /* Kermit */
- case SM_RESEND:
- move(CW_NAM,10);
- printw(" RESENDING:");
- break;
- default:
- move(CW_NAM,10);
- printw(" SENDING:");
- break;
- }
-#else
- move(CW_NAM,10);
- printw(" SENDING:");
-#endif /* CK_RESEND */
-
- } else if (what & W_RECV) { /* If we're receiving... */
-#ifdef NEWFTP
- if (what & W_FTP) { /* FTP */
- move(CW_NAM,10);
- printw(" FTP GET:");
- } else {
-#endif /* NEWFTP */
- move(CW_NAM,10);
- printw(" RECEIVING:");
-#ifdef NEWFTP
- }
- } else if (what == (W_FTP|W_FT_DELE)) {
- move(CW_NAM,10);
- printw("FTP DELETE:");
-#endif /* NEWFTP */
- } else { /* If we don't know... */
- move(CW_NAM,10); /* (should never see this) */
- printw(" File Name:");
- }
- move(CW_NAM,22); /* Display the filename */
- if (len > 57) {
- printw("%.55s..",s);
- len = 57;
- } else printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- q = len; /* Remember name length for later */
- clrtoeol();
- scrft(); /* Display file type (can change) */
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_AN: /* File as-name */
- if (q + len + 4 < 58) { /* Will fit */
- move(CW_NAM, 22 + q);
- printw(" => %s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- } else { /* Too long */
- move(CW_NAM, 22); /* Overwrite previous name */
- q = 0;
- if (len + 4 > 57) { /* wg15 */
- printw(" => %.51s..",s); /* wg15 */
- len = 53; /* wg15 */
- } else printw(" => %s",s); /* wg15 */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- }
- q += len + 4; /* Remember horizontal position */
- clrtoeol();
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_FS: /* File size */
- fsiz = n;
- move(CW_SIZ,22);
- if (fsiz > (CK_OFF_T)-1) {
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) n );
-#endif /* K95G */
-#endif /* KUI */
- printw("%s",ckfstoa(n));
- }
- if (fsiz == -2L) {
- printw("POSSIBLY EXCEEDS LOCAL FILE SIZE LIMIT");
- }
- clrtoeol();
-#ifdef COMMENT
- move(CW_PCD, 8);
- if (fsiz > (CK_OFF_T)-1) { /* Put up percent label */
- pctlbl = 1;
- clrtoeol();
- printw("Percent Done:");
- }
-#else
- move(CW_PCD, 8);
- clrtoeol();
- if (fsiz > (CK_OFF_T)-1) { /* Put up percent label */
- pctlbl = 1;
- printw("Percent Done:");
- } else {
- pctlbl = 0;
- printw("Bytes So Far:");
- }
-#endif /* COMMENT */
- clrtoeol();
- scrft(); /* File type */
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_PT: /* Packet type or pseudotype */
- if (spackets < 5) {
- extern int sysindex;
- extern struct sysdata sysidlist[];
- /* Things that won't change after the 4th packet */
- move(CW_PAR,22);
- printw("%s",parnam((char)parity));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-#ifdef COMMENT
- move(CW_PB, 22); /* Block check on this packet */
- if (bctu == 4)
- printw("B");
- else
- printw("%d",bctu);
- clrtoeol();
-#endif /* COMMENT */
- if (
-#ifdef NEWFTP
- (ftp && (spackets == 1 || rpackets == 1)) ||
-#endif /* NEWFTP */
- spackets == 4
- ) {
- move(CW_LIN,8);
- if (
-#ifdef NEWFTP
- ftp ||
-#endif /* NEWFTP */
- ((protocol == PROTO_K) && (sysindex > -1))
- ) {
- if (net) {
- move(CW_LIN,8);
- printw("Network Host: %s (%s)",
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "") :
-#endif /* NEWFTP */
- ttname,
-#ifdef NEWFTP
- ftp ? ftp_srvtyp :
-#endif /* NEWFTP */
- sysidlist[sysindex].sid_name
- );
- } else {
- move(CW_LIN,0);
- printw("Communication Device: %s (remote host is %s)",
- ttname,
- sysidlist[sysindex].sid_name
- );
- }
- clrtoeol();
- }
- }
- }
-#ifdef CK_TIMERS
- if (/* rttflg && */ protocol == PROTO_K) {
- long xx;
- if (
-#ifdef STREAMING
- streaming && oldwin != -2
-#else
- 0
-#endif /* STREAMING */
- ) {
- move(CW_TMO, 22);
- printw("00 / 00");
- clrtoeol();
- } else {
- xx = (rttdelay + 500) / 1000;
- if (xx != oldrtt || rcvtimo != oldtim) {
- move(CW_TMO, 22);
- printw("%02ld / %02d", xx, rcvtimo);
- oldrtt = xx;
- oldtim = rcvtimo;
- clrtoeol();
- }
- }
- }
-#endif /* CK_TIMERS */
-
- x = (what & W_RECV) ? /* Packet length */
- rpktl+(protocol==PROTO_K?1:0) :
- spktl;
- if (x != oldlen) { /* But only if it changed. */
- move(CW_PL, 22);
- printw("%d",x);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PL, (long) x );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldlen = x;
- }
- move(CW_PC, 22); /* Packet count (always). */
-
- printw("%d", (what & W_RECV) ? rpackets : spackets);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PC, (long) spackets );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-
- if (protocol == PROTO_K && !ftp) { /* Window slots */
- char ws[16];
- int flag;
- flag = 0;
-#ifdef STREAMING
- if (streaming) {
- if (oldwin != -2) {
- sprintf(ws,"STREAMING");
- flag = 1;
- oldwin = -2;
- }
- } else
-#endif /* STREAMING */
- if (wcur != oldwin) {
- sprintf(ws, "%d of %d", wcur < 1 ? 1 : wcur, wslotn);
- flag = 1;
- oldwin = wcur;
- }
- if (flag) {
- move(CW_WS, 22);
- printw("%s", ws);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_WS, (long) ws );
-#endif /* K95G */
-#endif /* KUI */
- }
- }
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Retry count, if changed */
- move(CW_PR, 22);
- printw("%d",errors);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PR, (long) errors );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldtry = errors;
- }
- /* Sender's packet type */
- if (!ftp && (c != oldtyp && c != 'Y' && c != 'N')) {
- char type[2];
- sprintf(type, "%c",c);
- move(CW_PT,22);
- printw("%s", type);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PT, (long) type );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldtyp = c;
- }
- switch (c) { /* Now handle specific packet types */
- case 'S': /* Beginning of transfer */
- fcnt = fbyt = 0L; /* Clear counters */
-#ifdef GFTIMER
- gtv = -1.0;
-#else /* GFTIMER */
- gtv = -1L; /* And old/new things... */
-#endif /* GFTIMER */
- oldpct = pct = 0L;
- break;
-
- case 'Z': /* or EOF */
- debug(F101,"screenc SCR_PT Z pktnum","",n);
- debug(F101,"screenc SCR_PT Z oldpct","",oldpct);
- debug(F101,"screenc SCR_PT Z pct","",pct);
- case 'D': /* Data packet */
- if (fsiz > 0L) { /* Show percent done if known */
- oldpct = pct; /* Remember previous percent */
- howfar = ffc;
-#ifdef CK_RESEND
- if (what & W_SEND) /* Account for PSEND or RESEND */
- howfar += sendstart;
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- /* Percent done, to be displayed... */
- if (c == 'Z') {
- if (!discard && !cxseen && !czseen) pct = 100L;
- } else
- pct = (fsiz > 99L) ? (howfar / (fsiz / 100L)) : 0L;
- if (pct > 100L || /* Allow for expansion and */
- (oldpct == 99L && pct < 0L)) /* other boundary conditions */
- pct = 100L;
- if (pct != oldpct) /* Only do this 100 times per file */
- updpct(oldpct, pct);
- } else {
- move(CW_PCD,22);
- printw("%s", ckfstoa(ffc));
- }
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) howfar);
-#endif /* K95G */
-#endif /* KUI */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- break;
-
- case '%': /* Timeouts, retransmissions */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
-
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- move(CW_PR, 22);
- printw("%d",errors);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR, (long) errors
- );
-#endif /* K95G */
-#endif /* KUI */
- }
- oldtry = errors;
- if (s) if (*s) {
- move(CW_ERR,22);
- printw("%s",s);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_ERR, (long) s);
-#endif /* K95G */
-#endif /* KUI */
- }
- break;
-
- case 'E': /* Error packet */
-#ifdef COMMENT
- move(CW_ERR,22); /* Print its data field */
- if (*s) {
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- }
- clrtoeol();
-#endif /* COMMENT */
- fcnt = fbyt = 0L; /* So no bytes for this file */
- break;
- case 'Q': /* Crunched packet */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- move(CW_ERR,22);
- printw("Damaged Packet");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Damaged Packet"
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- break;
- case 'q': /* Ctrl-C or connection lost */
- move(CW_MSG,22);
- clrtoeol();
- if (!s) s = "";
- printw("%s", *s ? s : "User interruption or connection lost");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) s
- );
-#endif /* K95G */
-#endif /* KUI */
- break;
- case 'T': /* Timeout */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- move(CW_ERR,22);
- printw("Timeout %d sec",rcvtimo);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Timeout"
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- move(CW_PR, 22);
- printw("%d",errors);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR, (long) errors
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldtry = errors;
- }
- break;
- default: /* Others, do nothing */
- break;
- }
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_ST: /* File transfer status */
- debug(F101,"screenc SCR_ST c","",c);
- debug(F101,"screenc SCR_ST success","",success);
- debug(F101,"screenc SCR_ST cxseen","",cxseen);
-#ifdef COMMENT
- move(CW_PCD,22); /* Update percent done */
- if (c == ST_OK) { /* OK, print 100 % */
- if (pctlbl)
- updpct(oldpct,100);
- else
- printw("%s", ckfstoa(ffc));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
-#endif /* K95G */
-#endif /* KUI */
- pct = 100;
- oldpct = 0;
- } else if (fsiz > 0L) /* Not OK, update final percent */
-/*
- The else part writes all over the screen -- howfar and/or fsiz have
- been reset as a consequence of the not-OKness of the transfer.
-*/
- if (pctlbl)
- updpct(oldpct, (howfar * 100L) / fsiz);
- clrtoeol();
-#else
- if (c == ST_OK) { /* OK, print 100 % */
- move(CW_PCD,22); /* Update percent done */
- if (pctlbl) {
- if (oldpct == 0) /* Switching from "bytes so far" */
- clrtoeol(); /* to "percent done"... */
- updpct(oldpct,100);
- } else
- printw("%s", ckfstoa(ffc));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = 100;
- oldpct = 0;
-#endif /* COMMENT */
- clrtoeol();
- }
-#endif /* COMMENT */
-
-#ifdef COMMENT
-/* No, leave it there so they can read it */
- move(CW_MSG,22); /* Remove any previous message */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_MSG, (long) "" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
-#endif /* COMMENT */
-
- move(CW_TR, 22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TR, (long) "" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
-
- switch (c) { /* Print new status message */
- case ST_OK: /* Transfer OK */
- fcnt++; /* Count this file */
- if (what == (W_FTP|W_FT_DELE)) {
- move(CW_MSG,22);
- clrtoeol();
- printw("Delete OK");
- } else {
- fbyt += ffc;
- move(CW_MSG,22);
- clrtoeol();
- printw("Transfer OK");
- }
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) "Transfer OK"
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
- return;
-
- case ST_DISC: /* Discarded */
- move(CW_ERR,22);
- printw("File discarded");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "File discarded"
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_INT: /* Interrupted */
- move(CW_ERR,22);
- printw("Transfer interrupted");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Transfer interrupted"
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_SKIP: /* Skipped */
- move(CW_ERR,22);
- if (n > 0 && n < nskreason)
- printw("File skipped (%s)",skreason[n]);
- else
- printw("File skipped");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "File skipped"
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_ERR: /* Error message */
- move(CW_ERR,22);
- if (!s) s = (char *)epktmsg;
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_REFU: /* Refused */
- move(CW_ERR,22);
- if (*s) {
- char errbuf[64] ;
- sprintf( errbuf, "Refused, %s", s ) ;
- printw("%s", errbuf);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long) CW_ERR,(long) errbuf);
-#endif /* K95G */
-#endif /* KUI */
- } else {
- printw("Refused");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Refused");
-#endif /* K95G */
-#endif /* KUI */
- }
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_INC:
- move(CW_ERR,22);
- printw("Incomplete");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Incomplete");
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_MSG:
- move(CW_MSG,22);
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_MSG,(long)s);
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
- return;
-
- default: /* Bad call */
- move(CW_ERR,22);
- printw("*** screen() called with bad status ***");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR,
- (long) "*** screen() called with bad status ***" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh(); return;
- }
-
- case SCR_TC: { /* Transaction complete */
- char msgbuf[128];
- move(CW_CP,22); /* Overall transfer rate */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, tfcps);
-#endif /* K95G */
-#endif /* KUI */
- printw("%s", ckfstoa(tfcps));
- clrtoeol();
- if (success) {
- move(CW_MSG,22); /* Print statistics in message line */
- clrtoeol();
- }
- if (success) {
- sprintf(msgbuf,
- "SUCCESS. Files: %ld, Bytes: %s, %ld CPS",
- filcnt - filrej,
- ckfstoa(fbyt),
- tfcps
- );
- printw("%s", msgbuf);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) msgbuf
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-
- }
- move(CW_TR, 1);
- printw(" Elapsed Time: %s",hhmmss((long)
-#ifdef GFTIMER
- (fptsecs + 0.5)
-#else
- tsecs
-#endif /* GFTIMER */
- ));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_TR,
- (long) hhmmss((long)
-#ifdef GFTIMER
- (fptsecs + 0.5)
-#else
- tsecs
-#endif /* GFTIMER */
- ));
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- move(23,0); clrtoeol(); /* Clear instructions lines */
- move(22,0); clrtoeol(); /* to make room for prompt. */
- refresh();
-
-#ifdef GFTIMER
- oldgtv = (CKFLOAT) -1.0;
-#else
- oldgtv = -1L;
-#endif /* GFTIMER */
-
-#ifndef VMSCURSE
- debug(F100,"screenc endwin A","",0);
- endwin();
-#ifdef COMMENT
-/*
- Why and when was this call to conres() added? It makes no sense,
- and it breaks echoing on Solaris 8.
-*/
-#ifdef SOLARIS
- conres();
-#endif /* SOLARIS */
-#endif /* COMMENT */
-#endif /* VMSCURSE */
-
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
- cendw = 1;
- if (xfrbel) bleep(BP_NOTE); /* Close window, then beep. */
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- ft_win = 0; /* Window closed. */
- return;
- }
- case SCR_EM: /* Error packet (fatal) */
- move (CW_ERR,22);
- printw("FAILURE: %s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- if (xfrbel) bleep(BP_FAIL);
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh(); return;
-
- case SCR_QE: /* Quantity equals */
- case SCR_TU: /* Undelimited text */
- case SCR_TN: /* Text delimited at start */
- case SCR_TZ: /* Text delimited at end */
- return; /* (ignored in fullscreen display) */
-
- case SCR_MS: /* Message from Kermit partner */
- move(CW_MSG,22);
- printw("%s",s);
- clrtoeol(); refresh(); return;
-
- case SCR_XD: /* X-packet data */
- pct = oldpct = 0;
- move(CW_NAM,22);
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh(); return;
-
- case SCR_CW: /* Close Window */
- clrtoeol(); move(23,0); clrtoeol(); move(22,0); clrtoeol();
- refresh();
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
-
-#ifndef VMSCURSE
- debug(F100,"screenc endwin B","",0);
- endwin();
-#endif /* VMSCURSE */
- ft_win = 0; /* Flag that window is closed. */
- cendw = 1; return;
-
- case SCR_CD: /* Display current directory */
- move(CW_DIR,22);
- printw("%s", s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- default: /* Bad call */
- move (CW_ERR,22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "*** screen() called with bad function code ***"
- );
-#endif /* K95G */
-#endif /* KUI */
- printw("*** screen() called with bad function code ***");
- clrtoeol(); refresh(); return;
- }
-}
-#endif /* CK_CURSES */
-
-#ifdef KUI
-#ifdef CK_ANSIC
-void
-screeng(int f, char c,long n,char *s)
-#else
-CKVOID
-screeng(f,c,n,s)
-int f; /* argument descriptor */
-char c; /* a character or small integer */
-long n; /* a long integer */
-char *s; /* a string */
-#endif /* CK_ANSIC */
-/* screeng() */ {
-#ifdef CK_SSL
- extern int tls_active_flag, ssl_active_flag;
-#endif /* CK_SSL */
-#ifdef RLOGCODE
- extern int ttnproto;
-#endif /* RLOGCODE */
- static int q = 0;
- static CK_OFF_T fsiz = (CK_OFF_T)-1; /* Copy of file size */
- static long fcnt = 0L; /* Number of files transferred */
- static long fbyt = 0L; /* Total file bytes of all files transferred */
- static CK_OFF_T howfar = (CK_OFF_T)0; /* How much of file xfer'd so far */
- static int pctlbl = 0L; /* Percent done vs Bytes so far */
- long cps = 0L;
-
- int net = 0;
- int xnet = 0;
- int ftp = 0;
- int len; /* Length of string */
- int errors = 0; /* Error counter */
- int x; /* Worker */
-
- debug(F101,"screeng cinit","",cinit);
- debug(F101,"screeng cendw","",cendw);
-
- if (!s) s = ""; /* Always do this. */
-
- ftp = (what & W_FTP) ? 1 : 0; /* FTP or Kermit */
- net = network || ftp;
- xnet = ftp ? 1 : nettype; /* NET_TCPB == 1 */
-
- if (cinit == 0 || cendw > 0) { /* Handle borderline cases... */
- if (f == SCR_CW) { /* Close window, but it's not open */
- ft_win = 0;
- return;
- }
- debug(F111,"screeng A",s,f);
- if (f == SCR_EM ||
- (f == SCR_PT && c == 'E')) { /* Fatal error before window open */
- conoll(""); conoc('?'); conoll(s); return; /* Regular display */
- }
- }
- if (cinit == 0) { /* Only call initscr() once */
- /* Check these now -- if they are defined but not numeric */
- /* they can crash curses */
- cendw = 1; /* New window needs repainting */
- debug(F100,"screeng calling initscr","",0);
- initscr(); /* Initialize curses. */
- debug(F100,"screeng initscr ok","",0);
- cinit++; /* Remember curses was initialized. */
- }
- ft_win = 1; /* Window is open */
- if (repaint) {
-#ifdef CK_WREFRESH
-/*
- This totally repaints the screen, just what we want, but we can only
- do this with real curses, and then only if clearok() and wrefresh() are
- provided in the curses library.
-*/
- RestoreCmdMode();
-#else /* No CK_WREFRESH */
-/*
- Kermit's do-it-yourself method, works with all types of fullscreen
- support, but does not repaint all the fields. For example, the filename
- is lost, because it arrives at a certain time and never comes again, and
- Kermit presently does not save it anywhere. Making this method work for
- all fields would be a rather major recoding task, duplicating what curses
- already does, and would add a lot of complexity and storage space.
-*/
- cendw = 1;
-#endif /* CK_WREFRESH */
- repaint = 0;
- }
- if (cendw) { /* endwin() was called previously */
- debug(F100,"screeng setup ok","",0);
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) zgtdir() );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_LIN,
- (long) (
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "(unknown)") :
-#endif /* NEWFTP */
- ttname) );
-
- if (net) {
-#ifdef NETCONN
- int secure = 0;
- char * xname;
- if (xnet > nnetname)
- xname = "[ERROR]";
- else
- xname = netname[xnet];
-#ifdef NEWFTP
- if (ftp) {
- if (ftpissecure())
- secure = 1;
- } else
-#endif /* NEWFTP */
- if (0
-#ifdef SSHBUILTIN
- || IS_SSH()
-#endif /* SSHBUILTIN */
-#ifdef CK_ENCRYPTION
- || ck_tn_encrypting() && ck_tn_decrypting()
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- || tls_active_flag || ssl_active_flag
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
-#ifdef CK_ENCRYPTION
- || ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_ENCRYPTION */
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
- ) {
- secure = 1;
- }
- if (secure) {
- char buf[30];
- sprintf(buf,"%s (SECURE)",xname);
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) buf
- );
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) xname
- );
- }
-#else
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(network)"
- );
-#endif /* NETCONN */
- } else {
- if (speed < 0L)
- speed = ttgspd();
- if (speed > 0L) {
- if (speed == 8880) {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "75/1200"
- );
- } else {
- char speedbuf[64] ;
- sprintf(speedbuf, "%ld", speed);
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) speedbuf
- );
- }
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(unknown)"
- );
- }
- }
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
- pctlbl = (what & W_SEND);
- cendw = 0;
- }
- debug(F101,"SCREENC switch","",f);
- debug(F000,"SCREENC c","",c);
- debug(F101,"SCREENC n","",n);
-
- len = strlen(s); /* Length of argument string */
- switch (f) { /* Handle our function code */
- case SCR_FN: /* Filename */
- oldpct = pct = 0L; /* Reset percents */
-#ifdef GFTIMER
- gtv = (CKFLOAT) -1.0;
- /* oldgtv = (CKFLOAT) -1.0; */
-#else
- gtv = -1L;
- /* oldgtv = -1L; */
-#endif /* GFTIMER */
- oldwin = -1;
- fsiz = (CK_OFF_T)-1L; /* Invalidate previous file size */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PCD, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_FFC, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) "" );
-
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
- q = len; /* Remember name length for later */
- scrft(); /* Display file type (can change) */
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_AN: /* File as-name */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_FS: /* File size */
- fsiz = n;
- if (fsiz > (CK_OFF_T)-1) {
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) n );
- }
- if (fsiz > (CK_OFF_T)-1) { /* Put up percent label */
- pctlbl = 1;
- } else {
- pctlbl = 0;
- }
- scrft(); /* File type */
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_PT: /* Packet type or pseudotype */
- if (spackets < 5) {
- extern int sysindex;
- extern struct sysdata sysidlist[];
- /* Things that won't change after the 4th packet */
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
- if (
-#ifdef NEWFTP
- (ftp && (spackets == 1 || rpackets == 1)) ||
-#endif /* NEWFTP */
- spackets == 4
- ) {
- if (
-#ifdef NEWFTP
- ftp ||
-#endif /* NEWFTP */
- ((protocol == PROTO_K) && (sysindex > -1))
- ) {
- char msgbuf[128];
- if (net) {
- sprintf(msgbuf,"Network Host: %s (%s)",
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "") :
-#endif /* NEWFTP */
- ttname,
-#ifdef NEWFTP
- ftp ? ftp_srvtyp :
-#endif /* NEWFTP */
- sysidlist[sysindex].sid_name
- );
- } else {
- sprintf(msgbuf,
- "Communication Device: %s (remote host is %s)",
- ttname,
- sysidlist[sysindex].sid_name
- );
- }
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_LIN,
- (long) msgbuf
- );
- }
- }
- }
-#ifdef CK_TIMERS
- if (/* rttflg && */ protocol == PROTO_K) {
- long xx;
- if (
-#ifdef STREAMING
- streaming && oldwin != -2
-#else
- 0
-#endif /* STREAMING */
- ) {
- char msgbuf[64];
- sprintf(msgbuf,"00 / 00");
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_TMO,
- (long) msgbuf
- );
- } else {
- xx = (rttdelay + 500) / 1000;
- if (xx != oldrtt || rcvtimo != oldtim) {
- char msgbuf[64];
- sprintf(msgbuf,"%02ld / %02d", xx, rcvtimo);
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_TMO,
- (long) msgbuf
- );
- oldrtt = xx;
- oldtim = rcvtimo;
- clrtoeol();
- }
- }
- }
-#endif /* CK_TIMERS */
-
- x = (what & W_RECV) ? /* Packet length */
- rpktl+(protocol==PROTO_K?1:0) :
- spktl;
- if (x != oldlen) { /* But only if it changed. */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PL, (long) x );
- oldlen = x;
- }
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PC, (long) spackets );
-
- if (protocol == PROTO_K && !ftp) { /* Window slots */
- char ws[16];
- int flag;
- flag = 0;
-#ifdef STREAMING
- if (streaming) {
- if (oldwin != -2) {
- sprintf(ws,"STREAMING");
- flag = 1;
- oldwin = -2;
- }
- } else
-#endif /* STREAMING */
- if (wcur != oldwin) {
- sprintf(ws, "%d of %d", wcur < 1 ? 1 : wcur, wslotn);
- flag = 1;
- oldwin = wcur;
- }
- if (flag) {
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_WS, (long) ws );
- }
- }
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Retry count, if changed */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PR, (long) errors );
- oldtry = errors;
- }
- /* Sender's packet type */
- if (!ftp && (c != oldtyp && c != 'Y' && c != 'N')) {
- char type[2];
- sprintf(type, "%c",c);
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PT, (long) type );
- oldtyp = c;
- }
- switch (c) { /* Now handle specific packet types */
- case 'S': /* Beginning of transfer */
- fcnt = fbyt = 0L; /* Clear counters */
-#ifdef GFTIMER
- gtv = -1.0;
-#else /* GFTIMER */
- gtv = -1L; /* And old/new things... */
-#endif /* GFTIMER */
- oldpct = pct = 0L;
- break;
-
- case 'Z': /* or EOF */
- debug(F101,"screeng SCR_PT Z pktnum","",n);
- debug(F101,"screeng SCR_PT Z oldpct","",oldpct);
- debug(F101,"screeng SCR_PT Z pct","",pct);
- case 'D': /* Data packet */
- if (fsiz > 0L) { /* Show percent done if known */
- oldpct = pct; /* Remember previous percent */
- howfar = ffc;
-#ifdef CK_RESEND
- if (what & W_SEND) /* Account for PSEND or RESEND */
- howfar += sendstart;
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- /* Percent done, to be displayed... */
- if (c == 'Z') {
- if (!discard && !cxseen && !czseen) pct = 100L;
- } else
- pct = (fsiz > 99L) ? (howfar / (fsiz / 100L)) : 0L;
- if (pct > 100L || /* Allow for expansion and */
- (oldpct == 99L && pct < 0L)) /* other boundary conditions */
- pct = 100L;
- if (pct != oldpct) /* Only do this 100 times per file */
- updpct(oldpct, pct);
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
- }
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) howfar);
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- break;
-
- case '%': /* Timeouts, retransmissions */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
-
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR,
- (long) errors
- );
- }
- oldtry = errors;
- if (s) if (*s) {
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_ERR, (long) s);
- }
- break;
-
- case 'E': /* Error packet */
- if (*s) {
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
- }
- fcnt = fbyt = 0L; /* So no bytes for this file */
- break;
- case 'Q': /* Crunched packet */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Damaged Packet"
- );
- break;
- case 'q': /* Ctrl-C or connection lost */
- if (!s) s = "";
- if (!*s) s = "User interruption or connection lost";
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) s
- );
- break;
- case 'T': /* Timeout */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Timeout"
- );
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR, (long) errors
- );
- oldtry = errors;
- }
- break;
- default: /* Others, do nothing */
- break;
- }
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_ST: /* File transfer status */
- debug(F101,"screeng SCR_ST c","",c);
- debug(F101,"screeng SCR_ST success","",success);
- debug(F101,"screeng SCR_ST cxseen","",cxseen);
-#ifdef COMMENT
- if (c == ST_OK) { /* OK, print 100 % */
- if (pctlbl)
- updpct(oldpct,100);
- else
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
- pct = 100;
- oldpct = 0;
- } else if (fsiz > 0L) /* Not OK, update final percent */
-/*
- The else part writes all over the screen -- howfar and/or fsiz have
- been reset as a consequence of the not-OKness of the transfer.
-*/
- if (pctlbl)
- updpct(oldpct, (howfar * 100L) / fsiz);
-#else
- if (c == ST_OK) { /* OK, print 100 % */
- if (pctlbl) {
- updpct(oldpct,100);
- } else
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
-#ifdef COMMENT
- pct = 100;
- oldpct = 0;
-#endif /* COMMENT */
- }
-#endif /* COMMENT */
-
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TR, (long) "" );
-
- switch (c) { /* Print new status message */
- case ST_OK: /* Transfer OK */
- fcnt++; /* Count this file */
- if (what == (W_FTP|W_FT_DELE)) {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) "Delete OK"
- );
- } else {
- fbyt += ffc;
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) "Transfer OK"
- );
- }
- return;
-
- case ST_DISC: /* Discarded */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "File discarded"
- );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_INT: /* Interrupted */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Transfer interrupted"
- );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_SKIP: { /* Skipped */
- char errbuf[64] ;
- if (n > 0 && n < nskreason)
- sprintf( errbuf, "File skipped, (%s)", skreason[n] ) ;
- else
- sprintf( errbuf, "File skipped" ) ;
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) errbuf
- );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
- }
- case ST_ERR: /* Error message */
- if (!s) s = (char *)epktmsg;
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_REFU: /* Refused */
- if (*s) {
- char errbuf[64] ;
- sprintf( errbuf, "Refused, %s", s ) ;
- KuiSetProperty(KUI_FILE_TRANSFER,(long) CW_ERR,(long) errbuf);
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Refused");
- }
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_INC:
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Incomplete");
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_MSG:
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_MSG,(long)s);
- return;
-
- default: /* Bad call */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR,
- (long) "*** screen() called with bad status ***" );
- return;
- }
-
- case SCR_TC: { /* Transaction complete */
- char msgbuf[128];
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, tfcps);
- if (success) {
- sprintf(msgbuf,
- "SUCCESS. Files: %s, Bytes: %ld, %ld CPS",
- filcnt - filrej,
- ckfstoa(fbyt),
- tfcps
- );
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) msgbuf
- );
- }
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_TR,
- (long) hhmmss((long)
-#ifdef GFTIMER
- (fptsecs + 0.5)
-#else
- tsecs
-#endif /* GFTIMER */
- ));
-
-#ifdef GFTIMER
- oldgtv = (CKFLOAT) -1.0;
-#else
- oldgtv = -1L;
-#endif /* GFTIMER */
-
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
- cendw = 1;
- if (xfrbel) bleep(BP_NOTE); /* Close window, then beep. */
- ft_win = 0; /* Window closed. */
- return;
- }
- case SCR_EM: /* Error packet (fatal) */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
- if (xfrbel) bleep(BP_FAIL);
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case SCR_QE: /* Quantity equals */
- case SCR_TU: /* Undelimited text */
- case SCR_TN: /* Text delimited at start */
- case SCR_TZ: /* Text delimited at end */
- return; /* (ignored in fullscreen display) */
-
- case SCR_XD: /* X-packet data */
- pct = oldpct = 0;
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
- return;
-
- case SCR_CW: /* Close Window */
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
-
- ft_win = 0; /* Flag that window is closed. */
- cendw = 1; return;
-
- case SCR_CD: /* Display current directory */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) s );
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- default: /* Bad call */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "*** screen() called with bad function code ***"
- );
- return;
- }
-}
-#endif /* KUI */
-#endif /* MAC */
-
-#endif /* NOXFER */
-
-#ifndef CK_CURPOS
-/* Dummies for when cursor control is not supported */
-int
-ck_curpos(row, col) {
- return(-1);
-}
-
-int
-ck_cls() {
- return(-1);
-}
-
-int
-ck_cleol() {
- return(-1);
-}
-#endif /* CK_CURPOS */
-
-#ifndef NOIKSD
-#ifdef IKSDB
-
-struct iksdbfld dbfld[] = {
- /* Offset Length Type */
- { DB_FLAGS, dB_FLAGS, DBT_HEX }, /* 0 db_FLAGS Flags */
- { DB_ATYPE, dB_ATYPE, DBT_HEX }, /* 1 db_ATYPE Auth type */
- { DB_AMODE, dB_AMODE, DBT_HEX }, /* 3 db_AMODE Auth mode */
- { DB_STATE, dB_STATE, DBT_HEX }, /* 2 db_STATE State */
- { DB_MYPID, dB_MYPID, DBT_HEX }, /* 5 db_MYPID PID */
- { DB_SADDR, dB_SADDR, DBT_HEX }, /* 4 db_SADDR Server address */
- { DB_CADDR, dB_CADDR, DBT_HEX }, /* 6 db_CADDR Client address */
- { DB_START, dB_START, DBT_DAT }, /* 7 db_START Session start */
- { DB_LASTU, dB_LASTU, DBT_DAT }, /* 8 db_LASTU Last update */
- { DB_ULEN, dB_ULEN, DBT_HEX }, /* 9 db_ULEN Username length */
- { DB_DLEN, dB_DLEN, DBT_HEX }, /* 10 db_DLEN Directory name length */
- { DB_ILEN, dB_ILEN, DBT_HEX }, /* 11 db_ILEN Info length */
- { DB_PAD1, dB_PAD1, DBT_UND }, /* 12 db_PAD1 (Reserved) */
- { DB_USER, dB_USER, DBT_STR }, /* 13 db_USER Username */
- { DB_DIR, dB_DIR, DBT_STR }, /* 14 db_DIR Current Directory */
- { DB_INFO, dB_INFO, DBT_STR } /* 15 db_INFO State-specific info */
-};
-
-static char lcknam[CKMAXPATH+1]; /* Lockfile pathname */
-static char tmplck[CKMAXPATH+1]; /* Temporary lockfile name */
-
-static char * updmode = /* Update mode for fopen() */
-#ifdef OS2
- "r+b"
-#else
-#ifdef VMS
- "r+b"
-#else
- "r+"
-#endif /* VMS */
-#endif /* OS2 */
- ;
-
-/* D B I N I T -- Initialize the IKSD database... */
-
-int
-dbinit() {
- extern int dbinited;
- int x = 0;
- debug(F110,"dbinit dbdir 1",dbdir,0);
- debug(F110,"dbinit dbfile 1",dbfile,0);
- if (dbinited)
- return(0);
-#ifdef OS2
- if (!dbdir) {
-#ifdef NT
- char * p = NULL;
- if (!isWin95()) {
- p = getenv("SystemRoot");
- } else {
- p = getenv("winbootdir");
- if (!p) p = getenv("windir");
- }
- if (!p) p = "C:/";
- dbdir = malloc(strlen(p)+2);
- strcpy(dbdir,p); /* safe */
- p = dbdir;
- while (*p) {
- if (*p == '\\')
- *p = '/';
- p++;
- }
- if (*(p-1) != '/' ) {
- *p++ = '/';
- *p = '\0';
- }
-#else /* NT */
- makestr(&dbdir,"C:/");
-#endif /* NT */
- }
-#else /* OS2 */
- if (!dbdir)
- makestr(&dbdir,IK_DBASEDIR);
-#endif /* OS2 */
-
- if (!dbfile) {
- char * s = "";
- x = strlen(dbdir);
- if (dbdir[x-1] != '/') {
- s = "/";
- x++;
- }
- x += (int)strlen(IK_DBASEFIL);
- dbfile = (char *)malloc(x+1);
- sprintf(dbfile,"%s%s%s",dbdir,s,IK_DBASEFIL);
- }
- debug(F110,"dbinit dbdir 2",dbdir,0);
- debug(F110,"dbinit dbfile 2",dbfile,0);
- mypid = getpid(); /* Get my pid */
- debug(F101,"dbinit mypid","",mypid);
-
- if (!myhexip[0]) { /* Set my hex IP address */
-#ifdef TCPSOCKET
- extern unsigned long myxipaddr;
- if (getlocalipaddr() > -1) {
- myip = myxipaddr;
- sprintf(myhexip,"%08lx",myip); /* (Needs fixing for IPv6) */
- } else
-#endif /* TCPSOCKET */
- ckstrncpy(myhexip,"00000000",9);
- }
- debug(F111,"dbinit myip",myhexip,myip);
- if (!peerhexip[0]) { /* Get peer's hex IP address */
-#ifdef TCPSOCKET
- extern unsigned long peerxipaddr;
- if (ckgetpeer()) {
- peerip = peerxipaddr;
- sprintf(peerhexip,"%08lx",peerip); /* (Needs fixing for IPv6) */
- debug(F111,"dbinit peerip",peerhexip,peerip);
- } else {
- debug(F101,"dbinit ckgetpeer failure","",errno);
- ckstrncpy(peerhexip,"00000000",9);
- }
-#else
- ckstrncpy(peerhexip,"00000000",9);
-#endif /* TCPSOCKET */
- }
- debug(F111,"dbinit peerip",peerhexip,peerip);
- debug(F101,"dbinit dbenabled","",dbenabled);
- if (dbenabled && inserver) {
- mydbslot = getslot();
- debug(F111,"dbinit getslot",ckitoa(ikdbopen),x);
- if (ikdbopen) dbinited = 1;
- }
- return(0);
-}
-
-/* U P D S L O T -- Update slot n */
-
-/*
- Opens the database if necessary, seeks to slot n, writes current record
- and adds current time to last-update field. n is the record sequence number
- (0, 1, 2, ...), not the seek pointer. Returns -1 on failure, 0 on success.
-*/
-int
-updslot(n) int n; { /* Update our slot */
- int rc = 0;
- CK_OFF_T position;
-
- debug(F111,"updslot","ikdbopen",ikdbopen);
- if (!ikdbopen) /* Not if not ok */
- return(0);
- if (!dbfp) { /* Open database if not open */
- dbfp = fopen(dbfile,updmode); /* In update no-truncate mode */
- if (!dbfp) {
- debug(F110,"updslot fopen failed",dbfile,0);
- ikdbopen = 0;
- return(-1);
- }
- }
- /* debug(F111,"updslot dbfile",dbfile,dbfp); */
- position = n * DB_RECL;
- if (CKFSEEK(dbfp,position,0) < 0) { /* Seek to desired slot */
- debug(F111,"updslot fseek failed",dbfile,mydbseek);
- ikdbopen = 0;
- rc = -1;
- } else {
- /* Update the update time */
- strncpy(&dbrec[dbfld[db_LASTU].off],
- ckdate(),
- dbfld[db_LASTU].len
- );
- if (fwrite(dbrec,1,DB_RECL,dbfp) < DB_RECL) { /* Write the record */
- debug(F110,"updslot fwrite failed",dbfile,0);
- ikdbopen = 0;
- rc = -1;
- } else { /* Flush the write */
- fflush(dbfp);
- }
- }
- return(rc);
-}
-
-/* I N I T S L O T -- Initialize slot n with my info */
-
-int
-initslot(n) int n; { /* Initialize slot */
- int k;
-#ifdef TCPSOCKET
- extern unsigned long peerxipaddr;
-#endif /* TCPSOCKET */
-
- debug(F101,"initslot","",n);
-
-#ifdef USE_MEMCPY
- memset(dbrec,32,DB_RECL);
-#else
- for (k = 0; k < DB_RECL; k++)
- dbrec[k] = '\040';
-#endif /* USE_MEMCPY */
-
- myflags = DBF_INUSE; /* Set in-use flag */
- mystate = W_NOTHING;
- myatype = 0L;
- myamode = 0L;
-
- k = dbfld[db_FLAGS].len; /* Length of flags field */
- strncpy(&dbrec[dbfld[db_FLAGS].off],ulongtohex(myflags,k),k);
-
- k = dbfld[db_ATYPE].len;
- strncpy(&dbrec[dbfld[db_ATYPE].off],ulongtohex(myatype,k),k);
-
- k = dbfld[db_AMODE].len;
- strncpy(&dbrec[dbfld[db_AMODE].off],ulongtohex(myamode,k),k);
-
- k = dbfld[db_STATE].len;
- strncpy(&dbrec[dbfld[db_STATE].off],ulongtohex(mystate,k),k);
-
- k = dbfld[db_SADDR].len;
- strncpy(&dbrec[dbfld[db_SADDR].off],ulongtohex(myip,k),k);
-
-#ifdef TCPSOCKET
- ckgetpeer();
- k = dbfld[db_CADDR].len;
- strncpy(&dbrec[dbfld[db_CADDR].off],ulongtohex(peerxipaddr,k),k);
-#else
- k = dbfld[db_CADDR].len;
- strncpy(&dbrec[dbfld[db_CADDR].off],ulongtohex(0L,k),k);
-#endif /* TCPSOCKET */
-
- k = dbfld[db_MYPID].len;
- strncpy(&dbrec[dbfld[db_MYPID].off],ulongtohex(mypid,k),k);
-
- k = dbfld[db_START].len;
- strncpy(&dbrec[dbfld[db_START].off],ckdate(),k);
-
- k = dbfld[db_ULEN].len;
- strncpy(&dbrec[dbfld[db_ULEN].off],"0000",4);
-
- k = dbfld[db_DLEN].len;
- strncpy(&dbrec[dbfld[db_DLEN].off],"0000",4);
-
- k = dbfld[db_ILEN].len;
- strncpy(&dbrec[dbfld[db_ILEN].off],"0000",4);
-
- strncpy(&dbrec[dbfld[db_INFO].off],"INIT",4);
- return(updslot(n));
-}
-
-int
-slotstate(x,s1,s2,s3) int x; char *s1, *s2, *s3; {
- int k, l1, l2, l3, z;
- mystate = x;
- debug(F101,"slotstate ikdbopen","",ikdbopen);
- if (!ikdbopen)
- return(-1);
- if (!s1) s1 = "";
- l1 = strlen(s1);
- if (!s2) s2 = "";
- l2 = strlen(s2);
- if (!s3) s3 = "";
- l3 = strlen(s3);
- strncpy(&dbrec[DB_STATE],ulongtohex(mystate,4),4);
- k = dbfld[db_ILEN].len;
- z = l1 + l2 + l3 + 2;
- if (z > dB_INFO)
- z = dB_INFO;
- strncpy(&dbrec[DB_ILEN],ulongtohex((unsigned long)z,k),k);
- k = dbfld[db_INFO].len;
- z = dbfld[db_INFO].off;
- if (l1 <= k) {
- lset(&dbrec[z],s1,l1+1,32);
- z += l1+1;
- k -= l1+1;
- if (l2 <= k) {
- lset(&dbrec[z],s2,l2+1,32);
- z += l2+1;
- k -= l2+1;
- if (l3 <= k)
- lset(&dbrec[z],s3,k,32);
- }
- }
-#ifdef DEBUG
- if (deblog) {
- char buf[128];
- int i;
- strncpy(buf,&dbrec[DB_INFO],127);
- buf[127] = NUL;
- for (i = 126; i > 0 && buf[i] == 32; i--) buf[i] = 0;
- debug(F111,"slotstate",buf,mystate);
- }
-#endif /* DEBUG */
- z = updslot(mydbslot);
- debug(F101,"slotstate updslot","",z);
- return(z);
-}
-
-int
-slotdir(s1,s2) char * s1, * s2; { /* Update current directory */
- int k, len1, len2;
- if (!ikdbopen)
- return(-1);
- if (!s1) s1 = "";
- if (!s2) s2 = "";
- len1 = strlen(s1);
- len2 = strlen(s2);
- k = dbfld[db_DLEN].len;
- strncpy(&dbrec[DB_DLEN],ulongtohex((unsigned long)(len1+len2),k),k);
- k = dbfld[db_DIR].len;
- if (len1 > 0) {
- lset(&dbrec[dbfld[db_DIR].off],s1,len1,32);
- lset(&dbrec[dbfld[db_DIR].off+len1],s2,k-len1,32);
- } else {
- lset(&dbrec[dbfld[db_DIR].off],s2,k,32);
- }
- return(updslot(mydbslot));
-}
-
-/* F R E E S L O T -- Free slot n */
-
-int
-freeslot(n) int n; {
- int k;
- if (!ikdbopen)
- return(0);
- dbflags = 0L;
- if (n == mydbslot) {
- dbflags = myflags & ~DBF_INUSE;
- dbflags &= ~DBF_LOGGED;
- }
- k = dbfld[db_FLAGS].len;
- strncpy(&dbrec[dbfld[db_FLAGS].off],ulongtohex(dbflags,k),k);
- return(updslot(n));
-}
-
-/* G E T S L O T -- Find a free database slot; returns slot number */
-
-#ifdef UNIX
-#include <fcntl.h> /* For creat() */
-#endif /* UNIX */
-
-int
-getslot() { /* Find a free slot for us */
- FILE * rfp = NULL; /* Returns slot number (0, 1, ...) */
- char idstring[64]; /* PID string buffer (decimal) */
- char pidbuf[64], * s;
- int j, k, n, x, rc = -1;
- int lockfd, tries, haveslot = 0;
- long lockpid;
- CK_OFF_T i;
- /* char ipbuf[17]; */
-
- if (!myhexip[0]) /* Set my hex IP address if not set */
- ckstrncpy((char *)myhexip,"7F000001",33);
- sprintf(idstring,"%08lx:%010ld\n",myip,mypid);
- debug(F110,"getslot idstring", idstring, 0);
-
- /* Make temporary lockfile name IP.PID (hex.hex) */
- /* This should fit in 14 chars -- huge PIDs are usually not possible */
- /* on 14-char filename systems. */
-
- sprintf(tmplck,"%s%08lx.%lx",dbdir,myip,mypid);
- debug(F110,"getslot tempfile",tmplck,0);
-
- /* Make a temporary file */
-
- lockfd = creat(tmplck, 0600); /* BUT THIS ISN'T PORTABLE */
- if (lockfd < 0) {
- debug(F111,"getslock temp lockfile create failure", tmplck, errno);
- return(-1);
- }
- /* Write my (decimal) PID into the temp file */
-
- write(lockfd,idstring,(int)strlen(idstring));
- if (close(lockfd) < 0) { /* Close lockfile */
- debug(F101,"getslot error closing temp lockfile", "", errno);
- return(-1);
- }
- sprintf(lcknam,"%s%s",dbdir,IK_LOCKFILE); /* Build lockfile name */
- debug(F110,"getslot lockfile",lcknam,0);
-
- rfp = fopen(lcknam,"r"); /* See if lockfile exists */
- if (rfp) { /* If so... */
- rset(pidbuf,"",64,0);
- x = fread(pidbuf,1,63,rfp); /* Read ID string from it */
- fclose(rfp); /* and close it quickly */
- debug(F110,"getslot lock exists",pidbuf,0);
- if (x > 0) { /* If we have a PID, check it */
- char * s = pidbuf;
- while (*s) {
- if (islower(*s)) *s = toupper(*s);
- if (*s == ':') {
- *s = NUL;
- debug(F110,"getslot lock IP",pidbuf,0);
- debug(F110,"gteslot my IP",myhexip,0);
- if (!strcmp(pidbuf,myhexip)) { /* Same IP address? */
- lockpid = atol(s+1); /* Yes, now get PID */
- debug(F101,"getslot lockpid","",lockpid);
-
- /* Check if PID lockpid on this computer is alive */
- x = zchkpid(lockpid);
- if (!x) {
- debug(F100,"getslot PID stale,removing lock","",0);
- unlink(lcknam);
- }
- break;
- }
- }
- s++;
- }
- } else {
- debug(F111,"getslot lockfile open failure",lcknam,errno);
- }
- }
- /* Try IK_LCKTRIES (16) times to rename temp file to lockfile */
-
- for (tries = IK_LCKTRIES; tries > 0; tries--) {
- if (zrename(tmplck,lcknam) == 0)
- break;
- debug(F101,"getslot database locked by pid", "", dbpid);
- sleep(IK_LCKSLEEP);
- }
- if (tries < 1) { /* Couldn't */
- debug(F110,"getslot create lock failure",lcknam,0);
- return(-1);
- }
- /* Have lock, open database */
-
- debug(F110,"getslot has lock",lcknam,0); /* Have lock */
-
- if (!dbfile)
- return(-1);
-
- /* If database doesn't exist, create it. */
-
- debug(F110,"getslot dbfile",dbfile,0);
- if (zchki(dbfile) < 0) {
- debug(F110,"getslot creating new database",dbfile,0);
- x = creat(dbfile,0660);
- if (x < 0) {
- debug(F111,"getslot creat() failed", dbfile, errno);
- goto xslot;
- }
- close(x);
- }
- dbfp = fopen(dbfile,updmode); /* Open it in update mode */
- if (!dbfp) {
- debug(F111,"getslot fopen failed",dbfile,errno);
- goto xslot;
- }
- /* Now find a free (or new) slot... */
-
- dblastused = 0L; /* Seek pointer to last record inuse */
- mydbseek = 0L; /* Seek pointer for my record */
-
- /* Quickly read the whole database; n = record counter, i = seek pointer */
-
- for (n = 0, i = 0; !feof(dbfp); i += DB_RECL, n++) {
- x = fread(dbrec,1,DB_RECL,dbfp); /* Read a record */
- if (x < 1) /* EOF not caught by feof() */
- break;
-#ifndef NOFTRUNCATE
- if (x != DB_RECL) { /* Watch out for trailing junk */
- debug(F101,"getslot bad size","",x); /* (Shouldn't happen...) */
-#ifdef COHERENT
- chsize(fileno(dbfp),i);
-#else
- ftruncate(fileno(dbfp),(CK_OFF_T)i);
-#endif /* COHERENT */
- x = 0;
- CKFSEEK(dbfp,i,0);
- break;
- }
-#endif /* NOFTRUNCATE */
- debug(F101,"getslot record","",n);
- k = dbfld[db_FLAGS].off;
- j = dbfld[db_FLAGS].len;
- dbflags = hextoulong(&dbrec[k],j);
- debug(F001,"getslot dbflags","",dbflags);
- k = dbfld[db_MYPID].off;
- j = dbfld[db_MYPID].len;
- dbpid = hextoulong(&dbrec[k],j);
- debug(F001,"getslot dbpid","",dbpid);
- k = dbfld[db_SADDR].off;
- j = dbfld[db_SADDR].len;
- dbip = hextoulong(&dbrec[k],j);
- debug(F001,"getslot dbip","",dbip);
-
- if (dbflags & DBF_INUSE) { /* Remember last slot in use */
- x = 0; /* Make sure it's REALLY in use */
- if (dbpid == mypid && dbip == myip) { /* Check for PID == my PID */
- x = 1;
- debug(F101,"getslot record pid","",dbpid);
- } else { /* Or for stale PID */
- x = zchkpid(dbpid);
- debug(F101,"getslot zchkpid()","",x);
- }
- if (!x) { /* Bogus record */
- x = freeslot(n);
- debug(F101,"getslot stale record pid: freeslot()","",x);
- if (x > -1 && !haveslot)
- dbflags = 0;
- } else { /* It's really in use */
- dblastused = i;
- }
- }
- if (!haveslot) { /* If I don't have a slot yet */
- if (!(dbflags & DBF_INUSE)) { /* Claim this one */
- debug(F101,"getslot free slot", "", n);
- haveslot = 1;
- mydbseek = i;
- mydbslot = n; /* But keep going... */
- }
- }
- }
- /* Come here with i == seek pointer to first record after eof */
-
- if (!haveslot) { /* Found no free slot so add to end */
- debug(F101,"getslot new slot","",n);
- haveslot = 1;
- mydbseek = i;
- mydbslot = n;
- }
- ikdbopen = 1; /* OK to make database entries */
- debug(F101,"getslot records","",n);
- debug(F101,"getslot dblastused","",dblastused);
- debug(F101,"getslot i","",i);
-
- /* Trim stale records from end */
-
-#ifndef NOFTRUNCATE
- if (i > dblastused+DB_RECL) {
- debug(F101,"getslot truncating at","",dblastused+DB_RECL);
-#ifdef COHERENT
- x = chsize(fileno(dbfp),dblastused+DB_RECL);
-#else
- x = ftruncate(fileno(dbfp),(CK_OFF_T)(dblastused+DB_RECL));
-#endif /* COHERENT */
- if (x < 0) /* (Not fatal) */
- debug(F101,"getslot ftruncate failed", "", errno);
- }
-#endif /* NOFTRUNCATE */
-
- /* Initialize my record */
-
- if (initslot(mydbslot) < 0) {
- debug(F101,"getslot initslot() error","",n);
- ikdbopen = 0;
- goto xslot;
- }
- debug(F101,"getslot OK","",mydbslot);
- rc = mydbslot; /* OK return code */
-
- xslot: /* Unlock the database and return */
- if (unlink(lcknam) < 0) {
- debug(F111,"getslot lockfile removal failed",lcknam,errno);
- rc = -1;
- }
- return(rc);
-}
-#endif /* IKSDB */
-#endif /* NOIKSD */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusx.c.c99 b/ckermit-9.0.302-build/ckermit-9.0.302/ckuusx.c.c99
deleted file mode 100644
index a8a857b..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusx.c.c99
+++ /dev/null
@@ -1,9718 +0,0 @@
-#include "ckcsym.h"
-
-/* C K U U S X -- "User Interface" common functions. */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- This module contains user interface functions needed by both the interactive
- user interface and the command-line-only user interface, as well as the
- screen-control routines (curses and equivalent).
-*/
-
-/* Includes */
-
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckuusr.h"
-#include "ckcxla.h"
-
-#ifndef NOHTERMCAP
-#ifdef NOTERMCAP
-#define NOHTERMCAP
-#else
-#ifndef BSD44
-#define NOHTERMCAP
-#else
-#ifdef __bsdi__
-#define NOHTERMCAP
-#else
-#ifdef OPENBSD
-#define NOHTERMCAP
-#else
-#ifdef MACOSX
-#define NOHTERMCAP
-#endif /* MACOSX */
-#endif /* OPENBSD */
-#endif /* __bsdi__ */
-#endif /* BSD44 */
-#endif /* NOTERMCAP */
-#endif /* NOHTERMCAP */
-
-#ifndef NOTERMCAP
-#ifdef BSD44
-#ifndef NOHTERMCAP
-#include <termcap.h>
-#endif /* NOHTERMCAP */
-#endif /* BSD44 */
-#else /* !BSD44 */
-#ifdef linux
-#include <term.h>
-#endif /* linux */
-#endif /* NOTERMCAP */
-
-#ifdef OS2
-#include <string.h>
-_PROTOTYP(char * os2_gethostname, (void));
-#define getpid _getpid
-#endif /* OS2 */
-#ifdef BSD44
-#include <errno.h>
-#endif /* BSD44 */
-
-extern xx_strp xxstring;
-
-#ifdef OS2
-#include "ckcnet.h"
-#else /* OS2 */
-_PROTOTYP( char * ckgetpeer, (VOID));
-_PROTOTYP(int getlocalipaddr, (void));
-_PROTOTYP(int istncomport, (void));
-#ifndef NOCKGETFQHOST
-_PROTOTYP( char * ckgetfqhostname,(char *));
-#endif /* NOCKGETFQHOST */
-#ifndef NETCONN
-/*
- We should just pull in ckcnet.h here, but it causes a conflict with curses.h.
-*/
-#ifdef TCPSOCKET
-#define NETCONN
-#else
-#ifdef SUNX25
-#define NETCONN
-#else
-#ifdef STRATUSX25
-#define NETCONN
-#else
-#ifdef IBMX25
-#define NETCONN
-#else
-#ifdef HPX25
-#define NETCONN
-#else
-#ifdef DECNET
-#define NETCONN
-#else
-#ifdef NPIPE
-#define NETCONN
-#else
-#ifdef CK_NETBIOS
-#define NETCONN
-#ifdef SUPERLAT
-#define NETCONN
-#else
-#endif /* SUPERLAT */
-#endif /* TCPSOCKET */
-#endif /* SUNX25 */
-#endif /* STRATUSX25 */
-#endif /* IBMX25 */
-#endif /* HPX25 */
-#endif /* DECNET */
-#endif /* NPIPE */
-#endif /* CK_NETBIOS */
-#endif /* NETCONN */
-#endif /* OS2 */
-
-#ifndef TCPSOCKET
-#ifdef MULTINET
-#define TCPSOCKET
-#endif /* MULTINET */
-#ifdef DEC_TCPIP
-#define TCPSOCKET
-#endif /* DEC_TCPIP */
-#ifdef WINTCP
-#define TCPSOCKET
-#endif /* WINTCP */
-#ifdef TCPWARE
-#define TCPSOCKET
-#endif /* TCPWARE */
-#endif /* TCPSOCKET */
-
-#ifdef OS2
-#ifdef NT
-#include <windows.h>
-#include <tapi.h>
-#include "ckntap.h"
-#else /* NT */
-#define INCL_VIO
-#include <os2.h>
-#endif /* NT */
-#ifdef COMMENT /* Would you believe */
-#undef COMMENT /* <os2.h> defines this ? */
-#endif /* COMMENT */
-#ifdef CK_NETBIOS
-#include "ckonbi.h"
-#endif /* CK_NETBIOS */
-
-#include "ckocon.h"
-extern ascreen commandscreen;
-#ifdef KUI
-#include "ikui.h"
-#endif /* KUI */
-#endif /* OS2 */
-
-#ifdef NT
-#include "cknwin.h"
-#endif /* NT */
-#ifdef OS2
-#include "ckowin.h"
-#include "ckosyn.h"
-#endif /* OS2 */
-
-#ifdef CK_TAPI
-extern int tttapi;
-extern int tapipass;
-#endif /* CK_TAPI */
-
-#ifdef CK_KERBEROS
-#include "ckuath.h"
-#endif /* CK_KERBEROS */
-
-#ifndef WINTCP
-#include <signal.h>
-#endif /* WINTCP */
-
-#ifdef VMS
-#include <descrip.h>
-#include <ssdef.h>
-#include <stsdef.h>
-#ifndef OLD_VMS
-#include <lib$routines.h> /* Not for VAX C 2.3 */
-#else
-#include <libdef.h>
-#endif /* OLD_VMS */
-#ifdef WINTCP
-#include <signal.h>
-#endif /* WINTCP */
-#endif /* VMS */
-
-#ifdef DCLFDOPEN
-/* fdopen() needs declaring because it's not declared in <stdio.h> */
-_PROTOTYP( FILE * fdopen, (int, char *) );
-#endif /* DCLFDOPEN */
-
-#ifdef DCLPOPEN
-/* popen() needs declaring because it's not declared in <stdio.h> */
-_PROTOTYP( FILE * popen, (char *, char *) );
-#endif /* DCLPOPEN */
-
-int tt_crd = 0; /* Carriage return display */
-int tt_lfd = 0; /* Linefeed display */
-int interrupted = 0; /* Interrupted from keyboard flag */
-int fxd_inited = 0; /* Fullscreen stuff initialized */
-
-#ifdef DEBUG
-char debfil[CKMAXPATH+1]; /* Debugging log file name */
-#endif /* DEBUG */
-
-#ifdef TLOG
-char trafil[CKMAXPATH+1]; /* Transaction log file name */
-#endif /* TLOG */
-
-char sesfil[CKMAXPATH+1]; /* Session log file name */
-
-#ifdef CKLOGDIAL
-char diafil[CKMAXPATH+1]; /* Connection log file name */
-char cxlogbuf[CXLOGBUFL+1]; /* Connection log record buffer */
-int cx_active = 0; /* Connection is active */
-extern int dialog;
-#endif /* CKLOGDIAL */
-
-#ifdef DYNAMIC
-static char *cmdstr = NULL; /* Place to build generic command */
-#else
-#ifdef pdp11
-static char cmdstr[256];
-#else
-static char cmdstr[4096];
-#endif /* pdp11 */
-#endif /* DYNAMIC */
-
-#ifndef NOMSEND
-char fspec[CMDBL+4]; /* Filename string for \v(filespec) */
-int fspeclen = CMDBL;
-#else
-char fspec[CKMAXPATH+4];
-int fspeclen = CKMAXPATH;
-#endif /* NOMSEND */
-
-char * rfspec = NULL; /* Received filespec: local */
-char * prfspec = NULL; /* Preliminary rfspec */
-char * sfspec = NULL; /* Sent filespec: local */
-char * psfspec = NULL; /* Preliminary sfspec */
-char * srfspec = NULL; /* Received filespec: remote */
-char * psrfspec = NULL; /* Preliminary srfspec */
-char * rrfspec = NULL; /* Sent filespec: remote */
-char * prrfspec = NULL; /* Preliminary rrfspec */
-
-int success = 1, /* Command success/failure flag */
- cmdlvl = 0, /* Command level */
- action = 0, /* Action selected on command line */
- slogts = 0, /* Session-log timestamps on/off */
- slognul = 0, /* Session-log null-terminated lines */
-#ifdef UNIX
- sessft = XYFT_T, /* Session log file type */
-#else
- sessft = XYFT_B, /* (text for UNIX binary for others) */
-#endif /* UNIX */
- pflag = 1, /* Print prompt */
- msgflg = 1; /* Print informational messages */
-
-extern int xaskmore, saveask; /* More-prompting */
-
-#ifdef CK_APC
-extern int apcactive;
-#endif /* CK_APC */
-/* External variables */
-
-extern int local, quiet, binary, network, what, parity, xitsta, escape,
- tlevel, bgset, backgrd, xsuspend, cmdint, nettype, seslog, dfloc;
-
-extern int cmd_rows, cmd_cols, xcmdsrc;
-
-extern char cmdfil[];
-
-#ifdef VMS
-extern int batch;
-#endif /* VMS */
-
-#ifdef datageneral /* 2/12/92 ENH */
-#include <sysid.h>
-extern int con_reads_mt, conint_ch, conint_avl;
-#endif /* datageneral */
-
-extern long speed;
-
-extern char ttname[], *dftty, *cmarg, **cmlist, *versio, myhost[];
-
-#ifndef NOCSETS
-extern int fcharset, tcharset, xfrxla;
-extern struct csinfo fcsinfo[], tcsinfo[];
-#endif /* NOCSETS */
-
-#ifdef OS2
-extern unsigned char colorcmd;
-#endif /* OS2 */
-
-#ifdef NOXFER
-
-int fdispla = XYFD_N;
-
-#else /* NOXFER is not defined */
-
-#ifdef OS2 /* File transfer display type */
-int fdispla = XYFD_C; /* Curses (fullscreen) if we have it */
-#else
-#ifdef CK_CURSES
-int fdispla = XYFD_C;
-#else
-int fdispla = XYFD_S; /* Otherwise CRT */
-#endif /* CK_CURSES */
-#endif /* OS2 */
-
-extern struct ck_p ptab[];
-extern int protocol, xfrbel, xfrint;
-
-#ifdef STREAMING
-extern int streaming, streamok;
-#endif /* STREAMING */
-
-/* Used internally */
-
-#ifdef KUI
-_PROTOTYP( VOID screeng, (int, char, long, char *) );
-#endif /* KUI */
-_PROTOTYP( VOID screenc, (int, char, CK_OFF_T, char *) );
-
-
-#ifdef CK_CURSES
-#ifndef DYNAMIC
-static char xtrmbuf[TRMBUFL]; /* tgetent() buffer */
-char * trmbuf = xtrmbuf;
-#else
-char * trmbuf = NULL;
-#endif /* DYNAMIC */
-_PROTOTYP( static VOID dpyinit, (void) );
-_PROTOTYP( static long shocps, (int, CK_OFF_T, CK_OFF_T) );
-_PROTOTYP( static CK_OFF_T shoetl, (CK_OFF_T, long, CK_OFF_T, CK_OFF_T) );
-#endif /* CK_CURSES */
-
-static int ft_win = 0; /* Fullscreen file transfer display window is active */
-
-/* Variables declared here */
-
-static char * skreason[] = {
- "", /* 0 */
- "Remote file not older", /* SKP_DAT */
- "Identical modification times", /* SKP_EQU */
- "Type", /* SKP_TYP */
- "Size", /* SKP_SIZ */
- "Name collision", /* SKP_NAM */
- "Exception List", /* SKP_EXL */
- "Dot file", /* SKP_DOT */
- "Backup file", /* SKP_BKU */
- "Recovery not needed", /* SKP_RES */
- "Access denied", /* SKP_ACC */
- "Not a regular file", /* SKP_NRF */
- "Simulated", /* SKP_SIM */
- "Simulated - Remote file older", /* SKP_XUP */
- "Simulated - No remote file", /* SKP_XNX */
-};
-static int nskreason = (sizeof(skreason) / sizeof(char *));
-
-char *
-gskreason(n) int n; {
- return((n > 0 && n < nskreason) ? skreason[n] : "");
-}
-
-char pktfil[CKMAXPATH+1]; /* Packet log file name */
-
-#ifndef NOMSEND /* Multiple SEND */
-char *msfiles[MSENDMAX];
-#endif /* NOMSEND */
-
-#ifdef CK_TIMERS
-extern long rttdelay;
-extern int rttflg;
-#endif /* CK_TIMERS */
-extern int rcvtimo;
-
-#ifdef CK_RESEND
-extern int sendmode;
-extern CK_OFF_T sendstart, rs_len;
-#endif /* CK_RESEND */
-
-#ifdef CK_PCT_BAR /* File transfer thermometer */
-int thermometer = 1; /* ON by default */
-#endif /* CK_PCT_BAR */
-
-#ifdef GFTIMER
-CKFLOAT gtv = -1.0, oldgtv = -1.0;
-#else
-#ifndef OS2
-static
-#endif /* OS2 */
- long gtv = -1L, oldgtv = -1L;
-#endif /* GFTIMER */
-
-extern int server, bctu, rptflg, ebqflg, spsiz, urpsiz, wmax, czseen, cxseen,
- winlo, displa, timint, npad, ebq, bctr, rptq, atcapu, lpcapu,
- swcapu, wslotn, wslotr, rtimo, mypadn, sq, capas, rpsiz, tsecs,
- pktlog, lscapu, dest, srvdis, wslots, spackets, spktl, rpktl,
- retrans, wcur, numerrs, fsecs, whatru, crunched, timeouts,
- rpackets, fncnv, bye_active, discard, inserver, diractive, cdactive;
-
-extern long filcnt, filrej, rptn, filcps, tfcps, cps, peakcps;
-extern CK_OFF_T ffc, tfc, fsize;
-
-long oldcps = 0L;
-
-extern CHAR *rdatap, padch, seol, ctlq, mypadc, eol, *epktmsg;
-extern char *xfrmsg;
-
-#ifdef IKSDB
-FILE * dbfp = NULL; /* File pointer to database file */
-
-int dbenabled = 1; /* Flag for database is enabled */
-extern int ikdbopen; /* Flag for database is open */
-
-unsigned long mydbseek = 0L; /* Seek pointer to my record */
-int mydbslot = 0; /* My slot number */
-unsigned long myflags = 0L; /* My flags */
-unsigned long myatype = 0L; /* My authorization type */
-unsigned long myamode = 0L; /* My authorization mode */
-unsigned long mystate = 0L; /* My state (SEND, RECEIVE, etc) */
-unsigned long mypid = 0L; /* My PID */
-unsigned long myip = 0L; /* My IP address */
-unsigned long peerip = 0L; /* My peer's IP address */
-
-unsigned long dbip = 0L; /* IP address in db record */
-unsigned long dbpid = 0L; /* PID in db record */
-unsigned long dbflags = 0L; /* Flags field in db record */
-unsigned long dblastused = 0L; /* Last in-use record in db */
-char dbrec[DB_RECL]; /* Database record buffer */
-
-char * dbdir = NULL; /* Database directory */
-char * dbfile = NULL; /* Database file full pathname */
-char myhexip[33] = { NUL, NUL }; /* My IP address in hex */
-char peerhexip[33] = { NUL, NUL }; /* Client's IP address in hex */
-#endif /* IKSDB */
-
-#ifdef GFTIMER
-extern CKFLOAT fpfsecs, fptsecs, fpxfsecs;
-#else
-extern long xfsecs;
-#endif /* GFTIMER */
-#endif /* NOXFER */
-
-#ifdef TCPSOCKET
-#ifdef NEWFTP
-extern char * ftp_host, ftp_srvtyp[];
-extern int ftp_csx, ftp_csl, ftp_deb;
-#endif /* NEWFTP */
-extern char myipaddr[];
-#endif /* TCPSOCKET */
-
-#ifndef NOICP
-#ifndef NOSPL
- extern struct mtab *mactab; /* For ON_EXIT macro. */
- extern int nmac;
-#endif /* NOSPL */
-#ifdef DCMDBUF
-extern char *cmdbuf; /* Command buffer */
-#else
-extern char cmdbuf[]; /* Command buffer */
-#endif /* DCMDBUF */
-extern int cmd_quoting;
-#endif /* NOICP */
-
-#ifndef NOCCTRAP
-#ifdef NT
-#include <setjmpex.h>
-#else /* NT */
-#include <setjmp.h>
-#endif /* NT */
-#include "ckcsig.h"
-extern ckjmpbuf cmjbuf;
-#endif /* NOCCTRAP */
-
-extern int xfiletype, nscanfile;
-
-int
-shoesc(escape) int escape; {
- extern char * ccntab[]; /* C0 control character name table */
- extern int tt_escape;
- if ((escape > 0 && escape < 32) || (escape == 127)) {
- printf(" Escape character: Ctrl-%c (ASCII %d, %s): %s\r\n",
- ctl(escape),
- escape,
- (escape == 127 ? "DEL" : ccntab[escape]),
- tt_escape ? "enabled" : "disabled"
- );
- } else {
- printf(" Escape character: Code %d",escape);
- if (escape > 160 && escape < 256)
- printf(" (%c)",escape);
- printf(": %s\r\n", tt_escape ? "enabled" : "disabled");
- }
- return(0);
-}
-
-#ifndef NOXFER
-/* P R E S E T -- Reset global protocol variables */
-
-extern int recursive;
-
-#ifdef PATTERNS
-int patterns = SET_AUTO; /* Whether to use filename patterns */
-extern int g_patterns; /* For saving and restoring */
-#else
-int patterns = SET_OFF;
-#endif /* PATTERNS */
-
-#ifndef NOICP
-#ifdef CK_LABELED
-extern int g_lf_opts, lf_opts;
-#endif /* CK_LABELED */
-extern int g_matchdot, g_usepipes, usepipes;
-extern int g_binary, g_proto, g_displa, g_spath, g_rpath, g_fncnv;
-extern int g_recursive;
-extern int g_xfermode, xfermode;
-extern int g_urpsiz, g_spsizf, g_spsiz;
-extern int g_spsizr, g_spmax, g_wslotr, g_prefixing, g_fncact;
-extern int g_fnspath, g_fnrpath, g_skipbup;
-extern int nolinks;
-#ifdef CKSYMLINK
-extern int zgfs_link;
-#endif /* CKSYMLINK */
-#ifndef NOSPL
-extern int g_pflg, pwflg, g_pcpt, pwcrypt;
-extern char * g_pswd, pwbuf[];
-#endif /* NOSPL */
-#endif /* NOICP */
-
-extern int spsizf, spsizr, spmax, prefixing, fncact, fnspath, fnrpath;
-extern int moving; /* SEND criteria */
-extern char sndafter[], sndbefore[], *sndexcept[], *rcvexcept[];
-extern CK_OFF_T sndlarger, sndsmaller, calibrate;
-extern int rmailf, rprintf, skipbup;
-extern char optbuf[];
-
-#ifdef PIPESEND
-extern char * g_sfilter, * g_rfilter;
-extern char * sndfilter, * rcvfilter;
-#endif /* PIPESEND */
-extern char ** sndarray;
-
-VOID
-ftreset() {
-#ifndef NOICP
- int i;
- extern char * filefile;
- extern int reliable, xreliable, c_save, ss_save, slostart, urclear;
- extern int oopts, omode, oname, opath, kactive, autopath;
- extern char * snd_move; /* Directory to move sent files to */
- extern char * snd_rename; /* What to rename sent files to */
- extern char * rcv_move;
- extern char * rcv_rename;
- extern char * g_snd_move;
- extern char * g_snd_rename;
- extern char * g_rcv_move;
- extern char * g_rcv_rename;
-
-#ifdef CK_TMPDIR
- extern int f_tmpdir;
- extern char savdir[];
-#endif /* CK_TMPDIR */
-
-#ifdef CK_SPEED
-#ifdef COMMENT
- extern int f_ctlp;
- extern short s_ctlp[], ctlp[];
-#endif /* COMMENT */
-#endif /* CK_SPEED */
-
-#ifndef NOCSETS
- extern int fcs_save, tcs_save;
- extern int g_xfrxla, xfrxla;
-#endif /* NOCSETS */
-
-/* Restore / reset per-command file-transfer switches */
-
- makestr(&snd_move,g_snd_move);
- makestr(&rcv_move,g_rcv_move);
- makestr(&snd_rename,g_snd_rename);
- makestr(&rcv_rename,g_rcv_rename);
-
- kactive = 0; /* Kermit protocol no longer active */
- oopts = -1; /* O-Packet Options */
- omode = -1; /* O-Packet Transfer Mode */
- oname = -1; /* O-Packet Filename Options */
- opath = -1; /* O-Packet Pathname Options */
-
-#ifdef CK_RESEND
- rs_len = 0L; /* REGET position */
-#endif /* CK_RESEND */
-
-#ifdef COMMENT
-#ifdef CK_SPEED
- if (f_ctlp) {
- for (i = 0; i < 256; i++)
- ctlp[i] = s_ctlp[i];
- f_ctlp = 0;
- }
-#endif /* CK_SPEED */
-#endif /* COMMENT */
-
-#ifdef CK_TMPDIR
- if (f_tmpdir) { /* If we changed to download dir */
- zchdir((char *) savdir); /* Go back where we came from */
- f_tmpdir = 0;
- }
-#endif /* CK_TMPDIR */
-
- calibrate = 0L; /* Calibration run */
- if (xreliable > -1) {
- reliable = xreliable;
- debug(F101,"ftreset reliable","",reliable);
- }
- urclear = 0;
-
- if (autopath) { /* SET RECEIVE PATHNAMES AUTO */
- fnrpath = PATH_AUTO;
- autopath = 0;
- }
- if (filefile) { /* File list */
- zclose(ZMFILE);
- makestr(&filefile,NULL);
- }
- if (c_save > -1) { /* Block Check Type */
- bctr = c_save;
- c_save = -1;
- }
- if (ss_save > -1) { /* Slow Start */
- slostart = ss_save;
- ss_save = -1;
- }
-#ifdef CK_LABELED
- if (g_lf_opts > -1) {
- lf_opts = g_lf_opts; /* Restore labeled transfer options */
- g_lf_opts = -1;
- }
-#endif /* CK_LABELED */
-
-#ifndef NOCSETS
- if (tcs_save > -1) { /* Character sets */
- tcharset = tcs_save;
- tcs_save = -1;
- }
- if (fcs_save > -1) {
- fcharset = fcs_save;
- fcs_save = -1;
- }
- if (g_xfrxla > -1) {
- xfrxla = g_xfrxla;
- g_xfrxla = -1;
- }
- setxlatype(tcharset,fcharset); /* Translation type */
-#endif /* NOCSETS */
-
-#ifdef NETCONN
-#ifndef NOSPL
- if (g_pswd) {
- ckstrncpy(pwbuf,g_pswd,PWBUFL);
- makestr(&g_pswd,NULL);
- }
- if (g_pflg > -1) {
- pwflg = g_pflg;
- g_pflg = -1;
- }
- if (g_pcpt > -1) {
- pwcrypt = g_pcpt;
- g_pcpt = -1;
- }
-#endif /* NOSPL */
-#endif /* NETCONN */
-
- if (g_binary > -1) { /* File type */
- binary = g_binary;
- g_binary = -1;
- }
- if (g_xfermode > -1) { /* Transfer mode */
- xfermode = g_xfermode;
- g_xfermode = -1;
- }
-#ifdef PATTERNS
- if (g_patterns > -1) { /* Filename patterns */
- patterns = g_patterns;
- g_patterns = -1;
- }
-#endif /* PATTERNS */
-
- if (g_usepipes > -1) {
- usepipes = g_usepipes;
- g_usepipes = -1;
- }
- if (g_matchdot > -1) {
- matchdot = g_matchdot;
- g_matchdot = -1;
- }
- if (g_proto > -1) { /* Protocol */
- protocol = g_proto;
- g_proto = -1;
- }
- if (g_urpsiz > -1) {
- urpsiz = g_urpsiz;
- debug(F101,"ftreset restoring urpsiz","",urpsiz);
- g_urpsiz = -1;
- }
- if (g_spsizf > -1) {
- spsizf = g_spsizf;
- debug(F101,"ftreset restoring spsizf","",spsizf);
- g_spsizf = -1;
- }
- if (g_spsiz > -1) {
- spsiz = g_spsiz;
- debug(F101,"ftreset restoring spsiz","",spsiz);
- g_spsiz = -1;
- }
- if (g_spsizr > -1) {
- spsizr = g_spsizr;
- debug(F101,"ftreset restoring spsizr","",spsizr);
- g_spsizr = -1;
- }
- if (g_spmax > -1) {
- spmax = g_spmax;
- g_spmax = -1;
- }
- if (g_wslotr > -1) {
- wslotr = g_wslotr;
- g_wslotr = -1;
- }
- if (g_prefixing > -1) {
- prefixing = g_prefixing;
- g_prefixing = -1;
- }
- if (g_fncact > -1) {
- fncact = g_fncact;
- g_fncact = -1;
- }
- if (g_fncnv > -1) {
- fncnv = g_fncnv;
- g_fncnv = -1;
- }
- if (g_fnspath > -1) {
- fnspath = g_fnspath;
- g_fnspath = -1;
- }
- if (g_fnrpath > -1) {
- fnrpath = g_fnrpath;
- g_fnrpath = -1;
- }
- if (g_skipbup > -1) {
- skipbup = g_skipbup;
- g_skipbup = -1;
- }
- nolinks = 2; /* /FOLLOWLINKS is never global */
- recursive = 0; /* /RECURSIVE can never be global */
- xfiletype = -1;
-
- if (g_displa > -1) { /* File transfer display */
- fdispla = g_displa;
- g_displa = -1;
- }
- if (g_spath > -1) { /* Send pathnames */
- fnspath = g_spath;
- g_spath = -1;
- }
- if (g_rpath > -1) { /* Receive pathnames */
- fnrpath = g_rpath;
- g_rpath = -1;
- }
- if (g_fncnv > -1) { /* Filename conversion */
- fncnv = g_fncnv;
- g_fncnv = -1;
- }
-#ifdef PIPESEND
- makestr(&sndfilter,g_sfilter); /* Send filter */
- makestr(&rcvfilter,g_rfilter); /* Receive filter */
-#endif /* PIPESEND */
-
-#ifndef NOFRILLS
- rmailf = rprintf = 0; /* MAIL and PRINT modifiers for SEND */
- optbuf[0] = NUL; /* MAIL and PRINT options */
-#endif /* NOFRILLS */
-
- moving = 0; /* Reset delete-after-send indicator */
- sndafter[0] = NUL; /* Reset SEND selection switches */
- sndbefore[0] = NUL;
-
- for (i = 0; i < NSNDEXCEPT; i++) {
- if (sndexcept[i])
- free(sndexcept[i]);
- sndexcept[i] = NULL;
- if (rcvexcept[i])
- free(rcvexcept[i]);
- rcvexcept[i] = NULL;
- }
- sndlarger = (CK_OFF_T)-1;
- sndsmaller = (CK_OFF_T)-1;
- debug(F101,"present sndsmaller","",sndsmaller);
-#ifdef GFTIMER
- gtv = -1.0;
- oldgtv = -1.0;
-#else
- gtv = -1L;
- oldgtv = -1L;
-#endif /* GFTIMER */
-#endif /* NOICP */
-}
-#endif /* NOXFER */
-
-char *
-ttgtpn() { /* Get typical port name */
-/*
- Ideally this routine would be implemented in each of the cku?io.* modules,
- but that requires changing the API definition.
-*/
- return(
-#ifdef OS2
-#ifdef OS2ONLY
-"COM1"
-#else /* OS2ONLY */
-"TAPI [ name ] or COM1"
-#endif /* OS2ONLY */
-#else /* OS2 */
-#ifdef VMS
-"TXA0:, TTA0:, or LTA0:"
-#else /* VMS */
-#ifdef SOLARIS
-"/dev/cua/a"
-#else /* SOLARIS */
-#ifdef HPUX10
-"/dev/cua0p0"
-#else /* HPUX10 */
-#ifdef HPUX
-"/dev/cua00"
-#else /* HPUX */
-#ifdef __FreeBSD__
-"/dev/cuaa0"
-#else /* __FreeBSD__ */
-#ifdef __linux__
-"/dev/ttyS0"
-#else /* __linux__ */
-#ifdef BSD44
-"/dev/tty00"
-#else /* BSD44 */
-#ifdef OSK
-"/t1"
-#else /* OSK */
-#ifdef QNX
-"/dev/ser1"
-#else /* QNX */
-#ifdef QNX6
-"/dev/ser1"
-#else /* QNX6 */
-#ifdef UNIXWARE
-"/dev/term/00 or /dev/tty00"
-#else /* UNIXWARE */
-#ifdef CK_SCOV5
-"/dev/tty1A"
-#else /* CK_SCOV5 */
-#ifdef CK_SCO32V4
-"/dev/tty1A"
-#else /* CK_SCO32V4 */
-#ifdef M_XENIX
-"/dev/tty1A"
-#else /* M_XENIX */
-#ifdef AIXRS
-"/dev/tty0"
-#else /* AIXRS */
-#ifdef DGUX
-"/dev/tty00"
-#else /* DGUX */
-#ifdef datageneral
-"@con1"
-#else /* datageneral */
-#ifdef IRIX
-"/dev/ttym0"
-#else /* IRIX */
-#ifdef SUNOS4
-"/dev/ttyh0"
-#else /* SUNOS4 */
-#ifdef SV68R3V6
-"/dev/scc0"
-#else /* SV68R3V6 */
-#ifdef MOTSV88R4
-"/dev/contty00"
-#else /* MOTSV88R4 */
-#ifdef NEXT
-"/dev/cufa"
-#else
-#ifdef OSF
-"/dev/ttyd1"
-#else
-#ifdef SINIX
-"/dev/ttyc1"
-#else
-#ifdef UNIX
-"/dev/cua, /dev/acu, /dev/tty0, etc"
-#else /* UNIX */
-"(sorry no example available)"
-#endif /* UNIX */
-#endif /* SINIX */
-#endif /* OSF */
-#endif /* NEXT */
-#endif /* MOTSV88R4 */
-#endif /* SV68R3V6 */
-#endif /* SUNOS4 */
-#endif /* IRIX */
-#endif /* datageneral */
-#endif /* DGUX */
-#endif /* AIX */
-#endif /* M_XENIX */
-#endif /* CK_SCO32V4 */
-#endif /* CK_SCOV5 */
-#endif /* UNIXWARE */
-#endif /* QNX6 */
-#endif /* QNX */
-#endif /* OSK */
-#endif /* BSD44 */
-#endif /* __linux__ */
-#endif /* __FreeBSD__ */
-#endif /* HPUX */
-#endif /* HPUX10 */
-#endif /* SOLARIS */
-#endif /* VMS */
-#endif /* OS2 */
- );
-}
-
-/* C K _ E R R S T R -- Return message from most recent system error */
-
-#ifdef CKROOT
-extern int ckrooterr;
-#endif /* CKROOT */
-
-char *
-ck_errstr() {
-#ifdef USE_STRERROR
-#ifndef CK_ANSILIBS
- /* Should have been declared in <string.h> */
-_PROTOTYP( char * strerror, (int) );
-#endif /* CK_ANSILIBS */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
-#endif /* CKROOT */
- return(strerror(errno));
-#else /* !USE_STRERROR */
-#ifdef VMS
- extern char * ckvmserrstr(unsigned long);
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
-#endif /* CKROOT */
- return(ckvmserrstr(0L));
-#else /* !VMS */
-#ifdef BSD44
-#ifdef __386BSD__
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#else /* !__386BSD__ */
-#ifndef __bsdi__
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern const char *const sys_errlist[];
-#endif /* NDSYSERRLIST */
-#endif /* __bsdi__ */
-#endif /* __386BSD__ */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
- else
-#endif /* CKROOT */
- if (errno >= sys_nerr)
- return("Error number out of range");
- else
- return((char *) sys_errlist[errno]);
-#else /* !BSD44 */
-#ifdef ATTSV
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
- else
-#endif /* CKROOT */
- if (errno >= sys_nerr)
- return("Error number out of range");
- else
- return((char *) sys_errlist[errno]);
-#else /* !ATTSV */
-#ifdef BSD4
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
- else
-#endif /* CKROOT */
- if (errno >= sys_nerr)
- return("Error number out of range");
- else
- return((char *) sys_errlist[errno]);
-#else
-#ifdef OS2
-#ifndef NDSYSERRLIST
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#ifdef NT
- extern int_sys_nerr;
-#endif /* NT */
- char *e;
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
-#endif /* CKROOT */
- e = (errno > -1
-#ifdef NT
- && errno <= _sys_nerr
-#endif /* NT */
- ) ?
-#ifdef NT
- (char *) sys_errlist[errno]
-#else /* NT */
- /* I don't know how to get a CLIB error string in OS/2 */
- strerror(errno)
-#endif /* NT */
- : "";
- return(e ? e : "");
-#else /* OS2 */
- return("");
-#endif /* OS2 */
-#endif /* BSD4 */
-#endif /* ATTSV */
-#endif /* BSD44 */
-#endif /* VMS */
-#endif /* USE_STRERROR */
-}
-
-#ifdef PATTERNS
-/*
- Filename pattern recognition lists for automatic text/binary switching.
- These are somewhat passe after the addition of scanfile() (7.0).
- But with the addition of FTP [M]GET, they're back in style (8.0).
-
- Although, with FTP the lists need to be used in the reverse. With
- Kermit the list is used to imply the types of the local system. Whereas
- with FTP, the list must be used to imply the type of the remote system.
- Therefore, all platforms must now support all of the lists.
-*/
-char *txtpatterns[FTPATTERNS+1] = { NULL, NULL };
-char *binpatterns[FTPATTERNS+1] = { NULL, NULL };
-/*
- Default pattern lists for each platform...
-
- NOTE: In most cases we leave ".hlp", ".ini", and ".scr" alone; although they
- are traditionally text types, they are binary in Windows. So they are
- handled by the prevailing SET FILE TYPE, rather than automatically.
- Similarly for ".dat", ".inf", and so on. Also ".ps" since PostScript files
- are not always text. ".log" is omitted since logs can be text or binary,
- except in VMS they are usually text, etc etc.
-
- Later (Sep 2003): Add PostScript to binary patterns.
-*/
-static char *txtp[SYS_MAX][FTPATTERNS] = {
- /* UNKNOWN */ {
- NULL, NULL
- },
- { /* UNIX */
- "*.txt","*.c","*.h","*.r","*.w","*.cpp","*.cc","*.ksc","*.bwr","*.upd",
- "*.html","*.htm","*.mss","*.tex","*.nr","[Mm]akefile", "*.hex", "*.hqx",
- "*.for","*.f77","*.f","*.F","*.s","*.pas","*.java","*.el","*.lisp","*.sh",
- "*.m4","*.perl","*.pl","*.pod","*.pm","*.awk","*.sno","*.spt","*.sed",
- "*.ksc","*.TXT", "*read.me", "*READ.ME", ".*", "*/.*", "*.mem","*.mac",
- NULL
- },
- { /* WIN32 */
- "*.txt","*.ksc","*.htm","*.html","*.bat","*.cmd","*.jav","*.asm", "*.hex",
- "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w",
- "*.java", "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile",
- "*.mem","*.mac","*.cc","*.pl","*.pod","*.pm","*.m4",NULL
- },
- { /* VMS */
- "*.com","*.txt","*.c", "*.for","*.pas","*.rno","*.rnh","*.mar","*.bli",
- "*.hlp","*.mss","*.doc","*.bwr","*.cld","*.hex","*.bas","*.ini","*.log",
- "*.mms","*.opt","*.ksc","*.perl","*.pl","*.pod","*.pm","*.sno","*.spt",
- "*.mem",NULL
- },
- { /* OS2 */
- "*.txt","*.ksc","*.htm","*.html","*.bat","*.cmd","*.jav","*.asm", "*.hex",
- "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w",
- "*.java", "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile",
- NULL
- },
- { /* DOS */
- "*.txt","*.ksc","*.htm","*.bat","*.cmd","*.jav","*.asm", "*.hex",
- "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w",
- "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile", NULL
- },
- { /* TOPS-10 */
- "*.cmd","*.hlp","*.doc","*.ini","*.txt","*.mac","*.for","*.sai","*.bli",
- "*.pas","*.sno","*.spt","*.pcl","*.mss","*.rno","*.b36","*.tex","*.pub",
- "*.req","*.r36","*.mem","*.bwr","*.ccl","*.ctl","*.rnh","*.ksc",NULL
- },
- { /* TOPS-20 */
- "*.cmd","*.hlp","*.doc","*.ini","*.txt","*.mac","*.for","*.sai","*.bli",
- "*.pas","*.sno","*.spt","*.pcl","*.mss","*.rno","*.b36","*.tex","*.pub",
- "*.req","*.r36","*.mem","*.bwr","*.ccl","*.ctl","*.rnh","*.ksc",NULL
- },
- { /* STRATUS VOS */
- "*.txt","*.ksc","*.htm","*.html","*.bat", "*.cmd","*.jav","*.asm","*.hex",
- "*.hqx","*.c", "*.h", "*.w", "*.java","*.bwr","*.upd","*.ttp","*.cm",
- "*.pl1","*.emacs", "read.me", "*.pl", "makefile", NULL
- },
- { /* DG AOS/VS */
- "*.txt", "*.c", "*.h", "*.w", "*.er", "*.bwr", "*.upd", "read.me",
- "*.cli", "*.ksc", NULL
- },
- { /* OSK */
- "*.c","*.cpp","*.h","*.a","*akefile", /* program sources */
- "*.for","*.f77","*.f","*.F","*.s","*.pas","*.java","*.el","*.lisp",
- "*.sh","*.perl","*.awk","*.sno","*.spt","*.sed",
- "*.txt","*.w", /* general text */
- "*.ksc","*.bwr","*.upd",
- "*.html","*.htm","*.mss","*.tex","*.nr","*.hex", "*.hqx",
- "*.TXT", "*read.me", "*READ.ME", ".*", "*/.*",
- NULL
- }
-};
-
-/* Note: .DOC added to (some) binary patterns June 1998... Microsoft wins. */
-
-static char *binp[SYS_MAX][FTPATTERNS] = {
- { /* UNKNOWN */
- NULL, NULL
- },
- { /* UNIX */
- "*.gz","*.Z","*.tgz","*.gif", "*.tar","*.zip","*.o","*.so","*.a","*.out",
- "*.exe", "*.jpg", "*.jpeg", "*.tif","*.tiff", "*.pdf", "*.so.*", "*.class",
- "*.rpm", "*.bmp", "*.bz2", "*.BMP", "*.dll", "*.doc", "*.vxd", "*.dcx",
- "*.xl*", "*.lzh", "*.lhz", "*.au", "*.voc", "*.mpg", "*.mpeg","[wk]ermit",
- "*.ps", NULL
- },
- { /* WIN32 */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.class","*.cla","*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.lzh", "*.vxd", "*.snd", "*.au", "* .voc", "*.mpg", "*.mpeg",
- "*.ps", NULL
- },
- { /* VMS */
- "*.exe","*.obj","*.bak","*.bin","*.adf","*.stb","*.mai","*.sys","*.dmp",
- "*.ps", "*.dat","*.par", NULL
- },
- { /* OS2 */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.class", "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.ps", "*.lzh", NULL
- },
- { /* DOS */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.ps", "*.lzh", NULL
- },
- { /* TOPS10 */
- "*.exe","*.sav","*.bin","*.rim","*.rel","*.unv","*.lib","*.tap","*.dvi",
- "*.ps", NULL
- },
- { /* TOPS20 */
- "*.exe","*.sav","*.bin","*.rim","*.rel","*.unv","*.lib","*.tap","*.dvi",
- "*.ps", NULL
- },
- { /* STRATUS VOS */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.class", "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.ps", "*.lzh", "*.pm", NULL
- },
- { /* DG */
- "*.ob", "*.pr", "*.dmp", "*.ps", NULL
- },
- { /* OSK */
- "*.gz","*.Z","*.z","*.tgz","*.lhz","*.tar", /* archivers */
- "*.zip","*.ar","*.zoo","*.rpm","*.lzh",
- /* object files, libraries, executables */
- "*.r","*.l","*.exe", "*.dll", "*.so.*", "*.class",
- /* images */
- "*.gif", "*.jpg", "*.jpeg", "*.tif","*.tiff", "*.pdf", "*.ps",
- "*.bmp", "*.bz2", "*.BMP","*.pcx",
- NULL
- }
-};
-
-/*
- Set up default pattern lists so they can be freed and re-malloc'd.
- Each pattern list must terminated by a null element.
-*/
-VOID
-initpat() {
- int i;
- for (i = 0; i < FTPATTERNS; i++) {
- txtpatterns[i] = NULL;
- binpatterns[i] = NULL;
- }
- for (i = 0; i < FTPATTERNS; i++) {
-#ifdef UNIX
- makestr(&(txtpatterns[i]),txtp[SYS_UNIX][i]);
-#else /* UNIX */
-#ifdef OS2
-#ifdef NT
- makestr(&(txtpatterns[i]),txtp[SYS_WIN32][i]);
-#else /* NT */
- makestr(&(txtpatterns[i]),txtp[SYS_OS2][i]);
-#endif /* NT */
-#else /* OS2 */
-#ifdef VMS
- makestr(&(txtpatterns[i]),txtp[SYS_VMS][i]);
-#else /* VMS */
-#ifdef STRATUS
- makestr(&(txtpatterns[i]),txtp[SYS_VOS][i]);
-#else /* STRATUS */
-#ifdef datageneral
- makestr(&(txtpatterns[i]),txtp[SYS_DG][i]);
-#else /* datageneral */
-#ifdef OSK
- makestr(&(txtpatterns[i]),txtp[SYS_OSK][i]);
-#else /* OSK */
- makestr(&(txtpatterns[i]),txtp[SYS_UNK][i]);
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIX */
- if (!txtp[i])
- break;
- }
- for (i = 0; i < FTPATTERNS; i++) {
-#ifdef UNIX
- makestr(&(binpatterns[i]),binp[SYS_UNIX][i]);
-#else /* UNIX */
-#ifdef OS2
-#ifdef NT
- makestr(&(binpatterns[i]),binp[SYS_WIN32][i]);
-#else /* NT */
- makestr(&(binpatterns[i]),binp[SYS_OS2][i]);
-#endif /* NT */
-#else /* OS2 */
-#ifdef VMS
- makestr(&(binpatterns[i]),binp[SYS_VMS][i]);
-#else /* VMS */
-#ifdef STRATUS
- makestr(&(binpatterns[i]),binp[SYS_VOS][i]);
-#else /* STRATUS */
-#ifdef datageneral
- makestr(&(binpatterns[i]),binp[SYS_DG][i]);
-#else /* datageneral */
-#ifdef OSK
- makestr(&(binpatterns[i]),binp[SYS_OSK][i]);
-#else /* OSK */
- makestr(&(binpatterns[i]),binp[SYS_UNK][i]);
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIX */
- if (!binp[i])
- break;
- }
-}
-
-/*
- m a t c h n a m e -- Compare filename with text & binary name patterns.
-
- Returns:
- 0 if name matches a text pattern but not a binary pattern.
- 1 if name matches a binary pattern but not a text pattern.
- -1 if name matches no patterns.
- -2 if name matches a binary pattern and a text pattern.
-*/
-int
-matchname(filename, local, os) char * filename; int local; int os; {
- int rc = -1; /* Return code */
- char * name, * p;
-#ifdef OS2ORUNIX
- char tmpbuf[CKMAXPATH+1];
-#endif /* OS2ORUNIX */
-
- name = filename ? filename : ""; /* Copy of original arg */
- if (patterns && *name) { /* If PATTERNS ON... */
- int i;
-
-#ifdef OS2ORUNIX
- if (ckmatch("*.~[1-9]*~",name,1,1)) { /* Name has backup suffix? */
- int k;
- k = ckstrncpy(tmpbuf,name,CKMAXPATH+1); /* Yes, copy and strip */
- for (i = k - 3; i > 4; i--) {
- if (tmpbuf[i] == '~' && tmpbuf[i-1] == '.') {
- tmpbuf[i-1] = NUL;
- break;
- }
- }
- name = tmpbuf; /* And point to stripped copy */
- }
-#endif /* OS2ORUNIX */
- zstrip(name,&p); /* Strip pathname too */
- name = p;
-
- if (local) {
- if (txtpatterns[0]) { /* Search text patterns */
- for (i = 0; i < FTPATTERNS && txtpatterns[i]; i++) {
- if (ckmatch(txtpatterns[i],name,filecase,1)) {
- rc = 0;
- break;
- }
- }
- }
- if (binpatterns[0]) { /* And search binary patterns */
- for (i = 0; i < FTPATTERNS && binpatterns[i]; i++) {
- if (ckmatch(binpatterns[i],name,filecase,1)) {
- rc = (rc > -1) ? -2 : 1;
- break;
- }
- }
- }
- } else {
- if (os >= 0 && os < SYS_MAX) {
- if (txtp[os][0]) {
- for (i = 0; i < FTPATTERNS && txtp[os][i]; i++) {
- if (ckmatch(txtp[os][i],name,filecase,1)) {
- rc = 0;
- break;
- }
- }
- }
- if (binp[os][0]) {
- for (i = 0; i < FTPATTERNS && binp[os][i]; i++) {
- if (ckmatch(binp[os][i],name,filecase,1)) {
- rc = (rc > -1) ? -2 : 1;
- break;
- }
- }
- }
- }
- }
- }
- debug(F111,"matchname",name,rc);
- return(rc);
-}
-#endif /* PATTERNS */
-
-#ifdef UNICODE
-#ifndef NOEVENMAX
-#define EVENMAX
-#endif /* NOEVENMAX */
-#endif /* UNICODE */
-
-/* S C A N F I L E -- Analyze a file's contents */
-
-/*
- Call with:
- name: Pointer to name of existing file.
- flag: Pointer to int in which to return additional numeric data.
-
- Returns:
- -1 on failure (to open file or to read from it).
- Integer, 0..4, on success indicating file type:
- 0 = 7-bit text (flag = -1)
- 1 = UTF-8 text (flag = -1)
- 2 = UCS-2 text (flag = 0: big-endian; flag = 1: little-endian)
- 3 = 8-bit text (flag = 0: no C1 bytes; flag = 1: includes C1 bytes)
- 4 = Text (type unknown)
- 5 = binary (flag = -1)
-
- If UNICODE is defined:
-
- 1. If file begins with a valid BOM, it is believed. Otherwise we
- read the first 4K of the file (since it might be email with verbose
- headers) and analyze it:
-
- 2. If file contains only valid UTF-8 sequences, we call it UTF-8;
- otherwise:
-
- 3. If the file contains lots of alternate 0 bytes, we call it UCS-2, and
- set the polarity according to whether the preponderance of them are in
- even or odd positions; otherwise:
-
- 4. If EVENMAX is defined and the file contains lots of alternate bytes that
- are identical, even if they aren't zero, and the number of such bytes
- is at least four times the length of the maximum run of alternating
- identical bytes of the opposite polarity, we call it UCS-2; otherwise:
-
- 5. If the file contained no bytes with their 8th bits on and no controls
- other than CR, LF, HT, and FF, we call it ASCII; otherwise:
-
- 6. If it contains C0 control characters other than CR, LF, HT, and FF, we
- call it binary; otherwise:
-
- 7. We call it 8-bit text, character set unknown (could be Latin-1 or
- anything else).
-
- Note that malformed UTF-8 is not diagnosed as UTF-8.
-
- If UNICODE is not defined:
-
- 1. If the file contains C0 control characters other than CR, LF, HT, and
- FF, we call it binary; otherwise:
-
- 2. If the file contains any 8-bit bytes, we call it 8-bit text; otherwise:
-
- 3. We call it 7-bit text.
-
- In the non-Unicode case, UCS-2 is diagnosed as binary, but UTF-8 as
- 8-bit text.
-
- There is no significant speed difference between the Unicode and
- non-Unicode cases.
-*/
-int
-scanfile(name,flag,nscanfile) char * name; int * flag, nscanfile; {
- FILE * fp; /* File pointer */
- unsigned char buf[SCANFILEBUF]; /* File data buffer for analysis */
- int x, val = -1, count = 0; /* Workers */
- int rc = -1; /* Return code */
- int pv = -1; /* Pattern-match value */
- int eof = 0; /* Flag for file EOF encountered */
- int bytes = 0; /* Total byte count */
-#ifdef UNICODE
- unsigned int c0, c1; /* First 2 file bytes (for BOM) */
-#endif /* UNICODE */
- extern int pipesend, filepeek;
-
- register int i; /* Loop control */
- int readsize = 0; /* How much to read */
- int eightbit = 0; /* Number of bytes with 8th bit on */
- int c0controls = 0; /* C0 non-text control-char counter */
- int c0noniso = 0; /* C0 non-ISO control-char counter */
- int c1controls = 0; /* C1 control-character counter */
- unsigned int c; /* Current character */
- int runmax = 0; /* Longest run of 0 bytes */
- int runzero = 0; /* Run of 0 bytes */
- int pctzero = 0; /* Percentage of 0 bytes */
- int txtcz = 0;
-#ifdef CK_CTRLZ
- extern int eofmethod;
-#endif /* CK_CTRLZ */
-
-#ifdef UNICODE
- int notutf8 = 0; /* Nonzero if definitely not UTF-8 */
- int utf8state = 0; /* UTF-8 recognizer state */
- int oddzero = 0; /* Number of 0 bytes in odd postions */
- int evenzero = 0; /* and in even positions */
- int lfnul = 0; /* Number of <LF><NUL> sequences */
- int crlf = 0; /* Number of <CRLF> sequences */
-#else
- int notutf8 = 1;
-#endif /* UNICODE */
-
-#ifdef COMMENT
-#ifdef EVENMAX
- int oddrun = 0, oddmax = 0, oddbyte = 0, oddmaxbyte = 0;
- int evenrun = 0, evenmax = 0, evenbyte = 0, evenmaxbyte = 0;
-#endif /* EVENMAX */
-#endif /* COMMENT */
-
-#ifndef NOXFER
- if (pipesend || calibrate || sndarray) /* Only for real files */
- return(-1);
-#endif /* NOXFER */
- debug(F111,"scanfile",name,nscanfile);
-#ifdef PATTERNS
- if (!filepeek) {
- pv = matchname(name,1,-1);
- if (pv < 0)
- rc = -1;
- else
- rc = (pv == 1) ? FT_BIN : FT_TEXT;
- debug(F111,"scanfile !filepeek result",name,rc);
- return(rc);
- }
-#endif /* PATTERNS */
-
-#ifdef VMS
-/* We don't scan in VMS where text files have various record formats in */
-/* which record headers contain seemingly non-text bytes. So the best */
-/* we can do in VMS is tell whether the file is text or binary, period. */
- {
- int b, x;
- b = binary; /* Save current binary setting */
- if (zopeni(ZIFILE,name) > 0) { /* In VMS this sets binary */
- x = binary; /* Get result */
- zclose(ZIFILE); /* Close the file */
- binary = b; /* Restore previous binary setting */
- rc = x ? FT_BIN : FT_TEXT;
- val = 0;
- goto xscanfile;
- }
- }
-#endif /* VMS */
-
- eof = 0; /* End-of-file reached indicator */
-#ifdef OS2
- fp = fopen(name, "rb"); /* Open the file in binary mode */
-#else
- fp = fopen(name, "r");
-#endif /* OS2 */
-
- if (!fp) /* Failed? */
- return(-1);
-
- while (1) { /* One or more gulps from file */
- if (eof) { /* EOF from last time? */
- debug(F111,"scanfile at EOF",name,bytes);
- if (runzero > runmax)
- runmax = runzero;
- break;
- }
- if (nscanfile < 0) { /* Reading whole file */
- readsize = SCANFILEBUF;
- } else { /* Reading first nscanfilee bytes */
- readsize = nscanfile - bytes;
- if (readsize < 1)
- break;
- if (readsize > SCANFILEBUF)
- readsize = SCANFILEBUF;
- }
- debug(F101,"scanfile readsize","",readsize);
- count = fread(buf,1,readsize,fp); /* Read a buffer */
- if (count == EOF || count == 0) {
- debug(F111,"scanfile EOF",name,count);
- break;
- }
- debug(F111,"scanfile buffer ok",name,count);
-
- if (bytes == 0 && count > 8) {
- /* PDF files can look like text in the beginning. */
- if (!ckstrcmp((char *)buf,"%PDF-1.",7,1)) {
- if (isdigit(buf[7])) {
- if (buf[8] == '\015' ||
- count > 9 && buf[8] == SP && buf[9] == '\015') {
-#ifdef DEBUG
- buf[8] = NUL;
- debug(F110,"scanfile PDF",buf,0);
-#endif /* DEBUG */
- binary = 1; /* But they are binary. */
- break;
- }
- }
- } else if (!ckstrcmp((char *)buf,"%!PS-Ado",8,1)) {
- /* Ditto for PostScript */
-#ifdef DEBUG
- int i;
- for (i = 8; i < count; i++) {
- if (buf[i] < '!') {
- buf[i] = NUL;
- break;
- }
- }
- debug(F110,"scanfile PostScript",buf,0);
-#endif /* DEBUG */
- binary = 1;
- break;
-#ifndef NOPCLSCAN
- } else if (!ckstrcmp((char *)buf,") HP-PCL",8,1)) {
- /* HP PCL printer language */
-#ifdef DEBUG
- int i;
- for (i = 8; i < count; i++) {
- if (buf[i] < '!') {
- buf[i] = NUL;
- break;
- }
- }
- debug(F110,"scanfile PCL",buf,0);
-#endif /* DEBUG */
- binary = 1;
- break;
- }
-#endif /* NOPCLSCAN */
-#ifndef NOPJLSCAN
- else if (buf[0] == '\033' && (buf[1] == 'E' || buf[1] == '%')) {
- /* Ditto for PJL Job printer header */
-#ifdef DEBUG
- int i;
- for (i = 2; i < count; i++) {
- if (buf[i] < '!') {
- buf[i] = NUL;
- break;
- }
- }
- debug(F110,"scanfile PJL Job printer header",buf,0);
-#endif /* DEBUG */
- binary = 1;
- break;
-#endif /* NOPJLSCAN */
- }
- }
-
-#ifdef UNICODE
- if (bytes == 0 && count > 1) {
- int incl_cnt = 0;
-
- /* First look for BOM */
-
- c0 = (unsigned)((unsigned)buf[0]&0xFF); /* First file byte */
- c1 = (unsigned)((unsigned)buf[1]&0xFF); /* Second byte */
-
- if (c0 == 0xFE && c1 == 0xFF) { /* UCS-2 BE */
- rc = FT_UCS2;
- val = 0;
- debug(F111,"scanfile UCS2 BOM BE",ckitoa(val),rc);
- incl_cnt++;
- } else if (c0 == 0xFF && c1 == 0xFE) { /* UCS-2 LE */
- rc = FT_UCS2;
- val = 1;
- debug(F111,"scanfile UCS2 BOM LE",ckitoa(val),rc);
- incl_cnt++;
- } else if (count > 2) if (c0 == 0xEF && c1 == 0xBB &&
- (unsigned)((unsigned)buf[2]&0xFF) == 0xBF) {
- rc = FT_UTF8;
- debug(F111,"scanfile UTF8 BOM",ckitoa(val),rc);
- incl_cnt++;
- }
- if (incl_cnt) { /* Have BOM */
- bytes += count;
- goto xscanfile;
- }
- }
-#endif /* UNICODE */
-
- bytes += count; /* Count bytes read */
- eof = feof(fp); /* Flag for at EOF */
-
- for (i = 0; i < count; i++) { /* For each byte... */
- c = (unsigned)buf[i]; /* For ease of reference */
- if (!c) { /* Zero byte? */
-#ifdef EVENMAX
- if (i&1) /* In odd position */
- oddzero++;
- else
- evenzero++; /* In even position */
-#endif /* EVENMAX */
- runzero++;
- } else { /* Not a zero byte */
- if (runzero > runmax)
- runmax = runzero;
- if (runmax > 2) /* That's all we need to be certain */
- break; /* it's a binary file. */
- runzero = 0;
- }
-
-#ifdef COMMENT
-#ifdef EVENMAX
-
-/* This is to catch UCS-2 with a non-ASCII, non-Latin-1 repertoire */
-
- if (i > 1) { /* Look for runs of alternating chars */
- if (i&1) {
- if (c == buf[i-2]) { /* In odd positions */
- oddrun++;
- oddbyte = c;
- } else {
- oddmax = oddrun;
- oddmaxbyte = oddbyte;
- }
- } else { /* and even positions */
- if (c == buf[i-2]) {
- evenrun++;
- evenbyte = c;
- } else {
- evenmax = evenrun;
- evenmaxbyte = evenbyte;
- }
- }
- }
-#endif /* EVENMAX */
-#endif /* COMMENT */
-
- if ((c & 0x80) == 0) { /* We have a 7-bit byte */
-#ifdef UNICODE
- if (i > 0 && c == 10) { /* Linefeed */
- if (buf[i-1] == 0) lfnul++; /* Preceded by NUL */
- else if (buf[i-1] == 13) crlf++; /* or by CR... */
- }
-#endif /* UNICODE */
- if (c < ' ') { /* Check for CO controls */
- if (c != LF && c != CR && c != HT && c != FF) {
- c0controls++;
- if (c != ESC && c != SO && c != SI)
- c0noniso++;
- }
- if ((c == '\032') /* Ctrl-Z */
-#ifdef COMMENT
- && eof && (i >= count - 2)
-#endif /* COMMENT */
- ) {
- c0controls--;
- c0noniso--;
-#ifdef CK_CTRLZ
- if (eofmethod == XYEOF_Z && txtcz == 0) {
- if (c0controls == 0) /* All text prior to Ctrl-Z */
- txtcz = 1;
- }
-#endif /* CK_CTRLZ */
- }
- }
-#ifdef UNICODE
- if (!notutf8 && utf8state) { /* In UTF-8 sequence? */
- utf8state = 0;
- debug(F000,"scanfile","7-bit byte in UTF8 sequence",c);
- notutf8++; /* Then it's not UTF-8 */
- continue;
- }
-#endif /* UNICODE */
- } else { /* We have an 8-bit byte */
- eightbit++; /* Count it */
- if (c >= 0x80 && c < 0xA0) /* Check for C1 controls */
- c1controls++;
-#ifdef UNICODE
- if (!notutf8) { /* If it might still be UTF8... */
- switch (utf8state) { /* Enter the UTF-8 state machine */
- case 0: /* First byte... */
- if ((c & 0xE0) == 0xC0) { /* Tells number of */
- utf8state = 1; /* subsequent bytes */
- } else if ((c & 0xF0) == 0xE0) {
- utf8state = 2;
- } else if ((c & 0xF8) == 0xF0) {
- utf8state = 3;
- } else {
- notutf8++;
- }
- break;
- case 1: /* Subsequent byte */
- case 2:
- case 3:
- if ((c & 0xC0) != 0x80) { /* Must start with 10 */
- debug(F000,"scanfile",
- "bad byte in UTF8 sequence",c);
- notutf8++;
- break;
- }
- utf8state--; /* Good, one less in this sequence */
- break;
- default: /* Shouldn't happen */
- debug(F111,"scanfile","bad UTF8 state",utf8state);
- notutf8++;
- }
- }
-#endif /* UNICODE */
- }
- }
- }
- fclose(fp); /* Close the file */
- debug(F101,"scanfile bytes","",bytes);
-
- if (bytes == 0) /* If nothing was read */
- return(-1); /* we're done. */
-
-#ifdef EVENMAX
- /* In case we had a run that never broke... */
-#ifdef COMMENT
- if (oddmax == 0) {
- oddmax = oddrun;
- oddmaxbyte = oddbyte;
- }
- if (evenmax == 0) {
- evenmax = evenrun;
- evenmaxbyte = evenbyte;
- }
-#endif /* COMMENT */
- if (runmax == 0) {
- runmax = runzero;
- }
-#endif /* EVENMAX */
-
-#ifdef UNICODE
- if (bytes > 100) /* Bytes is not 0 */
- pctzero = (evenzero + oddzero) / (bytes / 100);
- else
- pctzero = ((evenzero + oddzero) * 100) / bytes;
-#endif /* UNICODE */
-
-#ifdef DEBUG
- if (deblog) { /* If debugging, dump statistics */
- debug(F101,"scanfile c0controls ","",c0controls);
- debug(F101,"scanfile c0noniso ","",c0noniso);
- debug(F101,"scanfile c1controls ","",c1controls);
- debug(F101,"scanfile eightbit ","",eightbit);
-#ifdef UNICODE
- debug(F101,"scanfile crlf ","",crlf);
- debug(F101,"scanfile lfnul ","",lfnul);
- debug(F101,"scanfile notutf8 ","",notutf8);
- debug(F101,"scanfile evenzero ","",evenzero);
- debug(F101,"scanfile oddzero ","",oddzero);
- debug(F101,"scanfile even/odd ","",(evenzero / (oddzero + 1)));
- debug(F101,"scanfile odd/even ","",(oddzero / (evenzero + 1)));
- debug(F101,"scanfile pctzero ","",pctzero);
-#endif /* UNICODE */
-#ifdef COMMENT
-#ifdef EVENMAX
- debug(F101,"scanfile oddmax ","",oddmax);
- debug(F101,"scanfile oddmaxbyte ","",oddmaxbyte);
- debug(F101,"scanfile evenmax ","",evenmax);
- debug(F101,"scanfile evenmaxbyte","",evenmaxbyte);
-#endif /* EVENMAX */
-#endif /* COMMENT */
- debug(F101,"scanfile runmax ","",runmax);
- }
-#endif /* DEBUG */
-
-#ifdef UNICODE
- x = eightbit ? bytes / 20 : bytes / 4; /* For UCS-2... */
-
- if (runmax > 2) { /* File has run of more than 2 NULs */
- debug(F100,"scanfile BIN runmax","",0);
- rc = FT_BIN; /* so it can't be any kind of text. */
- goto xscanfile;
-
- } else if (rc == FT_UCS2 || (rc == FT_UTF8 && runmax == 0)) {
- goto xscanfile; /* File starts with a BOM */
-
- } else if (eightbit > 0 && !notutf8) { /* File has 8-bit data */
- if (runmax > 0) { /* and runs of NULs */
- debug(F100,"scanfile BIN (nnUTF8) runmax","",0);
- rc = FT_BIN; /* UTF-8 doesn't have NULs */
- } else { /* No NULs */
- debug(F100,"scanfile UTF8 (nnUTF8 + runmax == 0)","",0);
- rc = FT_UTF8; /* and not not UTF-8, so is UTF-8 */
- }
- goto xscanfile;
- }
-/*
- For UCS-2 detection, see if the text contains lines delimited by
- ASCII controls and containing spaces, ASCII digits, or other ASCII
- characters, thus forcing the presence of a certain percentage of zero bytes.
- For this purpose require 20% zero bytes, with at least six times as many
- in even (odd) positions as in odd (even) positions.
-*/
- if ((evenzero >= x && oddzero == 0) ||
- ((((evenzero / (oddzero + 1)) > 6) && (pctzero > 20)) &&
- (crlf == 0) &&
- (lfnul > 1))
- ) {
- debug(F100,"scanfile UCS2 noBOM BE (even/oddzero)","",0);
- rc = FT_UCS2;
- val = 0;
- } else if ((evenzero == 0 && oddzero >= x) ||
- ((((oddzero / (evenzero + 1)) > 6) && (pctzero > 20)) &&
- (crlf == 0) &&
- (lfnul > 1))
- ) {
- debug(F100,"scanfile UCS2 noBOM LE (even/oddzero)","",0);
- rc = FT_UCS2;
- val = 1;
-
-#ifdef COMMENT
-#ifdef EVENMAX
-/*
- If the tests above fail, we still might have UCS-2 if there are significant
- runs of identical bytes in alternating positions, but only if it also has
- unusual C0 controls (otherwise we'd pick up hex files here). NOTE: We
- don't actually do this -- EVENMAX is not defined (see comments above at
- first occurrence of EVENMAX).
-*/
- } else if (c0noniso && evenmax > bytes / 4) {
- debug(F100,"scanfile UCS2 BE (evenmax)","",0);
- rc = FT_UCS2;
- val = 0;
- } else if (c0noniso && oddmax > bytes / 4) {
- debug(F100,"scanfile UCS2 LE (evenmax)","",0);
- rc = FT_UCS2;
- val = 1;
-#endif /* EVENMAX */
-#endif /* COMMENT */
-
- }
-/*
- It seems to be UCS-2 but let's be more certain since there is no BOM...
- If the number of 7- and 8-bit characters is approximately equal, it might
- be a compressed file. In this case we decide based on the name.
-*/
- if (rc == FT_UCS2) {
- if (eightbit > 0) {
- int j, k;
- j = (c1controls * 100) / (c0controls + 1);
- debug(F101,"scanfile c1/c0 ","",j);
- k = (bytes * 100) / eightbit;
- debug(F101,"scanfile pct 8bit ","",k);
- if (k > 40 && k < 60 && j > 60) {
- if (ckmatch("{*.Z,*.gz,*.zip,*.ZIP}",name,1,1)) {
- debug(F110,"scanfile 8-bit BIN compressed",name,0);
- rc = FT_BIN;
- goto xscanfile;
- }
- }
- }
- /* Small file - not enough evidence unless ... */
-
- if (bytes < 100) {
- if (oddzero != 0 && evenzero != 0) {
- debug(F100,"scanfile small UCS2 doubtful","",0);
- rc = FT_BIN;
- goto xscanfile;
- } else if (oddzero == 0 && evenzero == 0) {
- rc = eightbit ? FT_8BIT : FT_7BIT;
- }
- }
- goto xscanfile; /* Seems to be UCS-2 */
- }
-
-/* If none of the above, it's probably not Unicode. */
-
- if (!eightbit) { /* It's 7-bit */
- if (c0controls) { /* This would be strange */
- if ((c0noniso > 0) && (txtcz == 0)) {
- debug(F100,"scanfile 7-bit BIN (c0coniso)","",0);
- rc = FT_BIN;
- } else {
- debug(F100,"scanfile 7-bit ISO2022 TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
- } else { /* 7-bit text */
- debug(F100,"scanfile 7-bit TEXT (no c0controls)","",0);
- rc = FT_7BIT;
- }
- } else if (!c0noniso || txtcz) { /* 8-bit text */
- debug(F100,"scanfile 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else { /* 8-bit binary */
- debug(F100,"scanfile 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- }
-
-#else /* !UNICODE */
-
- if (c0noniso) {
- debug(F100,"scanfile 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- } else if (eightbit) {
- debug(F100,"scanfile 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else {
- debug(F100,"scanfile 7-bit TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
-
-#endif /* UNICODE */
-
- xscanfile:
- if (flag) *flag = val;
- debug(F101,"scanfile result ","",rc);
- return(rc);
-}
-
-/*
- scanstring - like scan file but for a string.
- This is just a quick butchery of scanfile without thinking too much.
-*/
-int
-scanstring(s) char * s; {
- int x, val = -1, count = 0; /* Workers */
- int rc = -1; /* Return code */
- int pv = -1; /* Pattern-match value */
- int bytes = 0; /* Total byte count */
-#ifdef UNICODE
- unsigned int c0, c1; /* First 2 file bytes (for BOM) */
-#endif /* UNICODE */
- extern int pipesend, filepeek;
-
- register int i; /* Loop control */
- int readsize = 0; /* How much to read */
- int eightbit = 0; /* Number of bytes with 8th bit on */
- int c0controls = 0; /* C0 non-text control-char counter */
- int c0noniso = 0; /* C0 non-ISO control-char counter */
- int c1controls = 0; /* C1 control-character counter */
- unsigned int c; /* Current character */
- int runmax = 0; /* Longest run of 0 bytes */
- int runzero = 0; /* Run of 0 bytes */
- int pctzero = 0; /* Percentage of 0 bytes */
- int txtcz = 0;
-
-#ifdef UNICODE
- int notutf8 = 0; /* Nonzero if definitely not UTF-8 */
- int utf8state = 0; /* UTF-8 recognizer state */
- int oddzero = 0; /* Number of 0 bytes in odd postions */
- int evenzero = 0; /* and in even positions */
- int lfnul = 0; /* Number of <LF><NUL> sequences */
- int crlf = 0; /* Number of <CRLF> sequences */
-#else
- int notutf8 = 1;
-#endif /* UNICODE */
-
- char * buf = s;
- if (!s) s = "";
- count = strlen(s);
-
-#ifdef UNICODE
- if (bytes == 0 && count > 1) {
- int incl_cnt = 0;
-
- /* First look for BOM */
-
- c0 = (unsigned)((unsigned)buf[0]&0xFF); /* First file byte */
- c1 = (unsigned)((unsigned)buf[1]&0xFF); /* Second byte */
-
- if (c0 == 0xFE && c1 == 0xFF) { /* UCS-2 BE */
- rc = FT_UCS2;
- val = 0;
- debug(F111,"scanstring UCS2 BOM BE",ckitoa(val),rc);
- incl_cnt++;
- } else if (c0 == 0xFF && c1 == 0xFE) { /* UCS-2 LE */
- rc = FT_UCS2;
- val = 1;
- debug(F111,"scanstring UCS2 BOM LE",ckitoa(val),rc);
- incl_cnt++;
- } else if (count > 2) if (c0 == 0xEF && c1 == 0xBB &&
- (unsigned)((unsigned)buf[2]&0xFF) == 0xBF) {
- rc = FT_UTF8;
- debug(F111,"scanstring UTF8 BOM",ckitoa(val),rc);
- incl_cnt++;
- }
- if (incl_cnt) { /* Have BOM */
- bytes += count;
- goto xscanstring;
- }
- }
-#endif /* UNICODE */
-
- bytes += count; /* Count bytes read */
-
- for (i = 0; i < count; i++) { /* For each byte... */
- c = (unsigned)buf[i]; /* For ease of reference */
- if (!c) { /* Zero byte? */
- goto xscanstring; /* Null terminated string */
- }
- if ((c & 0x80) == 0) { /* We have a 7-bit byte */
-#ifdef UNICODE
- if (i > 0 && c == 10) { /* Linefeed */
- if (buf[i-1] == 0) lfnul++; /* Preceded by NUL */
- else if (buf[i-1] == 13) crlf++; /* or by CR... */
- }
-#endif /* UNICODE */
- if (c < ' ') { /* Check for CO controls */
- if (c != LF && c != CR && c != HT && c != FF) {
- c0controls++;
- if (c != ESC && c != SO && c != SI)
- c0noniso++;
- }
- if ((c == '\032') /* Ctrl-Z */
- ) {
- c0controls--;
- c0noniso--;
- }
- }
-#ifdef UNICODE
- if (!notutf8 && utf8state) { /* In UTF-8 sequence? */
- utf8state = 0;
- debug(F000,"scanstring","7-bit byte in UTF8 sequence",c);
- notutf8++; /* Then it's not UTF-8 */
- continue;
- }
-#endif /* UNICODE */
- } else { /* We have an 8-bit byte */
- eightbit++; /* Count it */
- if (c >= 0x80 && c < 0xA0) /* Check for C1 controls */
- c1controls++;
-#ifdef UNICODE
- if (!notutf8) { /* If it might still be UTF8... */
- switch (utf8state) { /* Enter the UTF-8 state machine */
- case 0: /* First byte... */
- if ((c & 0xE0) == 0xC0) { /* Tells number of */
- utf8state = 1; /* subsequent bytes */
- } else if ((c & 0xF0) == 0xE0) {
- utf8state = 2;
- } else if ((c & 0xF8) == 0xF0) {
- utf8state = 3;
- } else {
- notutf8++;
- }
- break;
- case 1: /* Subsequent byte */
- case 2:
- case 3:
- if ((c & 0xC0) != 0x80) { /* Must start with 10 */
- debug(F000,"scanstring",
- "bad byte in UTF8 sequence",c);
- notutf8++;
- break;
- }
- utf8state--; /* Good, one less in this sequence */
- break;
- default: /* Shouldn't happen */
- debug(F111,"scanstring","bad UTF8 state",utf8state);
- notutf8++;
- }
- }
-#endif /* UNICODE */
- }
- }
- if (bytes == 0) /* If nothing was read */
- return(-1); /* we're done. */
-
-#ifdef UNICODE
- if (bytes > 100) /* Bytes is not 0 */
- pctzero = (evenzero + oddzero) / (bytes / 100);
- else
- pctzero = ((evenzero + oddzero) * 100) / bytes;
-#endif /* UNICODE */
-
-#ifdef UNICODE
- x = eightbit ? bytes / 20 : bytes / 4; /* For UCS-2... */
-
- if (runmax > 2) { /* File has run of more than 2 NULs */
- debug(F100,"scanstring BIN runmax","",0);
- rc = FT_BIN; /* so it can't be any kind of text. */
- goto xscanstring;
-
- } else if (rc == FT_UCS2 || (rc == FT_UTF8 && runmax == 0)) {
- goto xscanstring; /* File starts with a BOM */
-
- } else if (eightbit > 0 && !notutf8) { /* File has 8-bit data */
- if (runmax > 0) { /* and runs of NULs */
- debug(F100,"scanstring BIN (nnUTF8) runmax","",0);
- rc = FT_BIN; /* UTF-8 doesn't have NULs */
- } else { /* No NULs */
- debug(F100,"scanstring UTF8 (nnUTF8 + runmax == 0)","",0);
- rc = FT_UTF8; /* and not not UTF-8, so is UTF-8 */
- }
- goto xscanstring;
- }
-/*
- It seems to be UCS-2 but let's be more certain since there is no BOM...
- If the number of 7- and 8-bit characters is approximately equal, it might
- be a compressed file. In this case we decide based on the name.
-*/
- if (rc == FT_UCS2) {
- if (bytes < 100) {
- if (oddzero != 0 && evenzero != 0) {
- debug(F100,"scanstring small UCS2 doubtful","",0);
- rc = FT_BIN;
- goto xscanstring;
- } else if (oddzero == 0 && evenzero == 0) {
- rc = eightbit ? FT_8BIT : FT_7BIT;
- }
- }
- goto xscanstring; /* Seems to be UCS-2 */
- }
-
-/* If none of the above, it's probably not Unicode. */
-
- if (!eightbit) { /* It's 7-bit */
- if (c0controls) { /* This would be strange */
- if ((c0noniso > 0) && (txtcz == 0)) {
- debug(F100,"scanstring 7-bit BIN (c0coniso)","",0);
- rc = FT_BIN;
- } else {
- debug(F100,"scanstring 7-bit ISO2022 TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
- } else { /* 7-bit text */
- debug(F100,"scanstring 7-bit TEXT (no c0controls)","",0);
- rc = FT_7BIT;
- }
- } else if (!c0noniso || txtcz) { /* 8-bit text */
- debug(F100,"scanstring 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else { /* 8-bit binary */
- debug(F100,"scanstring 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- }
-
-#else /* !UNICODE */
-
- if (c0noniso) {
- debug(F100,"scanstring 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- } else if (eightbit) {
- debug(F100,"scanstring 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else {
- debug(F100,"scanstring 7-bit TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
-
-#endif /* UNICODE */
-
- xscanstring:
- debug(F101,"scanstring result ","",rc);
- return(rc);
-}
-
-
-
-/* F I L E S E L E C T -- Select this file for sending */
-
-int
-#ifdef CK_ANSIC
-fileselect(
- char *f, char *sa, char *sb, char *sna, char *snb,
- CK_OFF_T minsiz, CK_OFF_T maxsiz,
- int nbu, int nxlist,
- char ** xlist
-)
-#else
-fileselect(f,sa,sb,sna,snb,minsiz,maxsiz,nbu,nxlist,xlist)
- char *f,*sa,*sb,*sna,*snb; CK_OFF_T minsiz,maxsiz;
- int nbu,nxlist; char ** xlist;
-#endif /* CK_ANSIC */
-/* fileselect */ {
- char *fdate;
- int n;
- CK_OFF_T z;
-
- debug(F111,"fileselect minsiz",ckfstoa(minsiz),minsiz);
- debug(F111,"fileselect maxsiz",ckfstoa(maxsiz),maxsiz);
- debug(F111,"fileselect (CK_OFF_T)-1",ckfstoa((CK_OFF_T)-1),(CK_OFF_T)-1);
-
- if (!sa) sa = "";
- if (!sb) sb = "";
- if (!sna) sna = "";
- if (!snb) snb = "";
-
-#ifdef CKSYMLINK
-#ifndef NOICP
-#ifndef NOXFER
- if (nolinks) {
- CK_OFF_T zz;
- zz = zgetfs(f);
- debug(F111,"fileselect NOLINKS zgetfs",f,zz);
- if (zz < (CK_OFF_T)0)
- return(0);
- debug(F111,"fileselect NOLINKS zgfs_link",f,zgfs_link);
- if (zgfs_link)
- return(0);
- }
-#endif /* NOXFER */
-#endif /* NOICP */
-#endif /* CKSYMLINK */
-
- debug(F110,"fileselect",f,0);
- if (*sa || *sb || *sna || *snb) {
- fdate = zfcdat(f); /* Date/time of this file */
- if (!fdate) fdate = "";
- n = strlen(fdate);
- debug(F111,"fileselect fdate",fdate,n);
- if (n != 17) /* Failed to get it */
- return(1);
- /* /AFTER: */
- if (sa[0] && (strcmp(fdate,(char *)sa) <= 0)) {
- debug(F110,"fileselect sa",sa,0);
- /* tlog(F110,"Skipping (too old)",f,0); */
- return(0);
- }
- /* /BEFORE: */
- if (sb[0] && (strcmp(fdate,(char *)sb) >= 0)) {
- debug(F110,"fileselect sb",sb,0);
- /* tlog(F110,"Skipping (too new)",f,0); */
- return(0);
- }
- /* /NOT-AFTER: */
- if (sna[0] && (strcmp(fdate,(char *)sna) > 0)) {
- debug(F110,"fileselect sna",sna,0);
- /* tlog(F110,"Skipping (too new)",f,0); */
- return(0);
- }
- /* /NOT-BEFORE: */
- if (snb[0] && (strcmp(fdate,(char *)snb) < 0)) {
- debug(F110,"fileselect snb",snb,0);
- /* tlog(F110,"Skipping (too old)",f,0); */
- return(0);
- }
- }
- /* Smaller or larger */
- if (minsiz > (CK_OFF_T)-1 || maxsiz > (CK_OFF_T)-1) {
- z = zchki(f); /* Get size */
- debug(F101,"fileselect filesize","",z);
- if (z < (CK_OFF_T)0)
- return(1);
- if ((minsiz > (CK_OFF_T)-1) && (z >= minsiz)) {
- debug(F111,"fileselect minsiz skipping",f,minsiz);
- /* tlog(F111,"Skipping (too big)",f,z); */
- return(0);
- }
- if ((maxsiz > (CK_OFF_T)-1) && (z <= maxsiz)) {
- debug(F111,"fileselect maxsiz skipping",f,maxsiz);
- /* tlog(F110,"Skipping (too small)",f,0); */
- return(0);
- }
- }
- if (nbu) { /* Skipping backup files? */
- if (ckmatch(
-#ifdef CKREGEX
- "*.~[0-9]*~" /* Not perfect but close enough. */
-#else
- "*.~*~" /* Less close. */
-#endif /* CKREGEX */
- ,f,filecase,1)) {
- debug(F110,"fileselect skipping backup",f,0);
- return(0);
- }
- }
- for (n = 0; xlist && n < nxlist; n++) {
- if (!xlist[n]) {
- debug(F101,"fileselect xlist empty",0,n);
- break;
- }
- if (ckmatch(xlist[n],f,filecase,1)) {
- debug(F111,"fileselect xlist",xlist[n],n);
- debug(F110,"fileselect skipping",f,0);
- return(0);
- }
- }
- if (xfiletype > -1) {
- n = scanfile(f,NULL,nscanfile);
- if (n < 0) {
- n = binary ? 1 : 0;
- } else {
- n = (n == FT_BIN) ? 1 : 0;
- }
- if (n != xfiletype)
- return(0);
- }
- debug(F110,"fileselect selecting",f,0);
- return(1);
-}
-
-
-#ifdef TCPSOCKET
-#ifdef NT
-extern int WSASafeToCancel;
-#endif /* NT */
-#endif /* TCPSOCKET */
-
-VOID
-setflow() {
- extern int flow, autoflow, mdmtyp, cxtype, cxflow[];
-#ifndef NODIAL
- extern int dialcapas, dialfc;
- extern MDMINF * modemp[];
- MDMINF * p = NULL;
- long bits = 0;
-#endif /* NODIAL */
-
- debug(F101,"setflow autoflow","",autoflow);
-
-/* #ifdef COMMENT */
-/* WHY WAS THIS COMMENTED OUT? */
- if (!autoflow) /* Only if FLOW is AUTO */
- return;
-/* #endif */ /* COMMENT */
-
- debug(F101,"setflow local","",local);
- debug(F101,"setflow network","",network);
- debug(F101,"setflow cxtype","",cxtype);
-
-#ifdef TN_COMPORT
- if (network && istncomport()) {
- flow = cxflow[CXT_MODEM];
- debug(F101,"setflow TN_COMPORT flow","",flow);
- return;
- }
-#endif /* TN_COMPORT */
-
- if (network || !local || cxtype == CXT_DIRECT) {
- flow = cxflow[cxtype]; /* Set appropriate flow control */
- debug(F101,"setflow flow","",flow);
- return;
- }
- if (cxtype != CXT_MODEM) /* Connection type should be modem */
- return;
-
-#ifndef NODIAL
- bits = dialcapas; /* Capability bits */
- if (!bits) { /* No bits? */
- p = modemp[mdmtyp]; /* Look in modem info structure */
- if (p)
- bits = p->capas;
- }
- if (dialfc == FLO_AUTO) { /* If DIAL flow is AUTO */
-#ifdef CK_RTSCTS /* If we can do RTS/CTS flow control */
- if (bits & CKD_HW) /* and modem can do it too */
- flow = FLO_RTSC; /* then switch to RTS/CTS */
- else /* otherwise */
- flow = FLO_XONX; /* use Xon/Xoff. */
-#else
-#ifndef NEXT
-#ifndef IRIX
- flow = FLO_XONX; /* Use Xon/Xoff. */
-#endif /* IRIX */
-#endif /* NEXT */
-#endif /* CK_RTSCTS */
- }
-#endif /* NODIAL */
- debug(F101,"setflow modem flow","",flow);
- return;
-}
-
-#ifndef NOLOCAL
-#ifdef CK_TRIGGER
-
-/* A U T O E X I T C H K -- Check for CONNECT-mode trigger string */
-/*
- Returns -1 if trigger not found, or else the trigger index, 0 or greater.
- (Replace with fancier and more efficient matcher later...)
- NOTE: to prevent unnecessary function call overhead, call this way:
-
- x = tt_trigger[0] ? autoexitchk(c) : -1;
-
-*/
-int
-#ifdef CK_ANSIC
-autoexitchk(CHAR c)
-#else
-autoexitchk(c) CHAR c;
-#endif /* CK_ANSIC */
-/* autoexitchk */ {
- extern CHAR * tt_trmatch[];
- extern char * tt_trigger[];
- int i;
- for (i = 0; i < TRIGGERS; i++) {
- if (!tt_trigger[i]) { /* No more triggers in list */
- break;
- } else if (*tt_trigger[i]) {
- if (!tt_trmatch[i]) /* Just starting? */
- tt_trmatch[i] = (CHAR *)tt_trigger[i]; /* Set match pointer */
- if (c == *tt_trmatch[i]) { /* Compare this character */
- tt_trmatch[i]++; /* It matches */
- if (!*tt_trmatch[i]) { /* End of match string? */
- tt_trmatch[i] = (CHAR *) tt_trigger[i]; /* Yes, rewind, */
- debug(F101,"autoexitchk",tt_trigger[i],i); /* log, */
- return(i); /* and return success */
- }
- } else /* No match */
- tt_trmatch[i] = (CHAR *) tt_trigger[i]; /* Rewind match string */
- } /* and go on the next match string */
- }
- return(-1); /* No match found */
-}
-#endif /* CK_TRIGGER */
-
-#ifndef NOSHOW
-/* S H O M D M -- Show modem signals */
-
-VOID
-shomdm() {
-/*
- Note use of "\r\n" to make sure this report prints right, even when
- called during CONNECT mode.
-*/
- int y;
- y = ttgmdm();
- switch (y) {
- case -3: printf(
- "Modem signals unavailable in this version of Kermit\r\n");
- break;
- case -2: printf("No modem control for this device\r\n"); break;
- case -1: printf("Modem signals unavailable\r\n"); break;
- default:
-#ifndef MAC
- printf(
- " Carrier Detect (CD): %s\r\n",(y & BM_DCD) ? "On": "Off");
- printf(
- " Dataset Ready (DSR): %s\r\n",(y & BM_DSR) ? "On": "Off");
-#endif /* MAC */
- printf(
- " Clear To Send (CTS): %s\r\n",(y & BM_CTS) ? "On": "Off");
-#ifndef STRATUS
-#ifndef MAC
- printf(
- " Ring Indicator (RI): %s\r\n",(y & BM_RNG) ? "On": "Off");
-#endif /* MAC */
- printf(
- " Data Terminal Ready (DTR): %s\r\n",
-#ifdef NT
- "(unknown)"
-#else /* NT */
- (y & BM_DTR) ? "On": "Off"
-#endif /* NT */
- );
-#ifndef MAC
- printf(
- " Request To Send (RTS): %s\r\n",
-#ifdef NT
- "(unknown)"
-#else /* NT */
- (y & BM_RTS) ? "On": "Off"
-#endif /* NT */
- );
-#endif /* MAC */
-#endif /* STRATUS */
- }
-#ifdef BETADEBUG
-#ifdef CK_TAPI
- if (tttapi && !tapipass) {
- LPDEVCFG lpDevCfg = NULL;
- LPCOMMCONFIG lpCommConfig = NULL;
- LPMODEMSETTINGS lpModemSettings = NULL;
- DCB * lpDCB = NULL;
-
- if (cktapiGetModemSettings(&lpDevCfg,&lpModemSettings,
- &lpCommConfig,&lpDCB)) {
- printf("\n");
- cktapiDisplayModemSettings(lpDevCfg,lpModemSettings,
- lpCommConfig,lpDCB);
- }
- }
-#endif /* CK_TAPI */
-#endif /* BETADEBUG */
-}
-#endif /* NOSHOW */
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
-/* S D E B U -- Record spar results in debugging log */
-
-VOID
-sdebu(len) int len; {
- debug(F111,"spar: data",(char *) rdatap,len);
- debug(F101," spsiz ","", spsiz);
- debug(F101," timint","",timint);
- debug(F101," npad ","", npad);
- debug(F101," padch ","", padch);
- debug(F101," seol ","", seol);
- debug(F101," ctlq ","", ctlq);
- debug(F101," ebq ","", ebq);
- debug(F101," ebqflg","",ebqflg);
- debug(F101," bctr ","", bctr);
- debug(F101," rptq ","", rptq);
- debug(F101," rptflg","",rptflg);
- debug(F101," lscapu","",lscapu);
- debug(F101," atcapu","",atcapu);
- debug(F101," lpcapu","",lpcapu);
- debug(F101," swcapu","",swcapu);
- debug(F101," wslotn","", wslotn);
- debug(F101," whatru","", whatru);
-}
-/* R D E B U -- Debugging display of rpar() values */
-
-VOID
-rdebu(d,len) CHAR *d; int len; {
- debug(F111,"rpar: data",d,len);
- debug(F101," rpsiz ","", xunchar(d[0]));
- debug(F101," rtimo ","", rtimo);
- debug(F101," mypadn","",mypadn);
- debug(F101," mypadc","",mypadc);
- debug(F101," eol ","", eol);
- debug(F101," ctlq ","", ctlq);
- debug(F101," sq ","", sq);
- debug(F101," ebq ","", ebq);
- debug(F101," ebqflg","",ebqflg);
- debug(F101," bctr ","", bctr);
- debug(F101," rptq ","", d[8]);
- debug(F101," rptflg","",rptflg);
- debug(F101," capas ","", capas);
- debug(F101," bits ","",d[capas]);
- debug(F101," lscapu","",lscapu);
- debug(F101," atcapu","",atcapu);
- debug(F101," lpcapu","",lpcapu);
- debug(F101," swcapu","",swcapu);
- debug(F101," wslotr","", wslotr);
- debug(F101," rpsiz(extended)","",rpsiz);
-}
-
-#ifdef COMMENT
-/* C H K E R R -- Decide whether to exit upon a protocol error */
-
-VOID
-chkerr() {
- if (backgrd && !server) fatal("Protocol error");
-}
-#endif /* COMMENT */
-#endif /* NOXFER */
-
-/* F A T A L -- Fatal error message */
-
-VOID
-fatal(msg) char *msg; {
- extern int initflg;
- static int initing = 0;
- if (!msg) msg = "";
- debug(F111,"fatal",msg,initflg);
-
- if (!initflg) { /* If called from prescan */
- if (initing) /* or called from sysinit() */
- exit(253);
- initing = 1;
- sysinit();
- }
-
- debug(F111,"fatal",msg,xitsta);
- tlog(F110,"Fatal:",msg,0L);
-#ifdef VMS
- if (strncmp(msg,"%CKERMIT",8))
- conol("%CKERMIT-E-FATAL, ");
- conoll(msg);
-#else /* !VMS */
- conoll(msg);
-#endif /* VMS */
-#ifdef OS2
-#ifndef NOXFER
- if (xfrbel) {
- bleep(BP_FAIL);
- sleep(1);
- bleep(BP_FAIL);
- }
-#endif /* NOXFER */
-
-#endif /* OS2 */
- doexit(BAD_EXIT,xitsta | 1); /* Exit indicating failure */
-}
-
-#ifndef NOXFER
-/* B L D L E N -- Make length-encoded copy of string */
-
-char *
-bldlen(str,dest) char *str, *dest; {
- int len;
- len = (int)strlen(str);
- if (len > 94)
- *dest = SP;
- else
- *dest = (char) tochar(len);
- strcpy(dest+1,str); /* Checked below in setgen() */
- return(dest+len+1);
-}
-
-
-/* S E T G E N -- Construct a generic command */
-/*
- Call with Generic command character followed by three string arguments.
- Trailing strings are allowed to be empty (""). Each string except the last
- non-empty string must be less than 95 characters long. The final nonempty
- string is allowed to be longer.
-*/
-CHAR
-#ifdef CK_ANSIC
-setgen(char type, char * arg1, char * arg2, char * arg3)
-#else
-setgen(type,arg1,arg2,arg3) char type, *arg1, *arg2, *arg3;
-#endif /* CK_ANSIC */
-/* setgen */ {
- char *upstr, *cp;
-#ifdef DYNAMIC
- if (!cmdstr)
- if (!(cmdstr = malloc(MAXSP + 1)))
- fatal("setgen: can't allocate memory");
-#endif /* DYNAMIC */
-
- cp = cmdstr;
- *cp++ = type;
- *cp = NUL;
- if (!arg1) arg1 = "";
- if (!arg2) arg2 = "";
- if (!arg3) arg3 = "";
- if (((int)strlen(arg1)+(int)strlen(arg2)+(int)strlen(arg3)+4) < MAXSP) {
- if (*arg1 != NUL) {
- upstr = bldlen(arg1,cp);
- if (*arg2 != NUL) {
- upstr = bldlen(arg2,upstr);
- if (*arg3 != NUL) bldlen(arg3,upstr);
- }
- }
- cmarg = cmdstr;
- debug(F110,"setgen",cmarg,0);
- return('g');
- }
- return('E');
-}
-#endif /* NOXFER */
-
-#ifndef NOMSEND
-static char *mgbufp = NULL;
-
-/* F N P A R S E -- */
-
-/*
- Argument is a character string containing one or more filespecs.
- This function breaks the string apart into an array of pointers, one
- to each filespec, and returns the number of filespecs. Used by server
- when it receives a GET command to allow it to process multiple file
- specifications in one transaction. Sets cmlist to point to a list of
- file pointers, exactly as if they were command line arguments.
-
- This version of fnparse treats spaces as filename separators. If your
- operating system allows spaces in filenames, you'll need a different
- separator.
-
- This version of fnparse mallocs a string buffer to contain the names. It
- cannot assume that the string that is pointed to by the argument is safe.
-*/
-int
-fnparse(string) char *string; {
- char *p, *s, *q;
- int r = 0, x; /* Return code */
-#ifdef RECURSIVE
- debug(F111,"fnparse",string,recursive);
-#endif /* RECURSIVE */
-
- if (mgbufp) free(mgbufp); /* Free this from last time. */
- mgbufp = malloc((int)strlen(string)+2);
- if (!mgbufp) {
- debug(F100,"fnparse malloc error","",0);
- return(0);
- }
-#ifndef NOICP
-#ifndef NOSPL
- ckstrncpy(fspec,string,fspeclen); /* Make copy for \v(filespec) */
-#endif /* NOSPL */
-#endif /* NOICP */
- s = string; /* Input string */
- p = q = mgbufp; /* Point to the copy */
- r = 0; /* Initialize our return code */
- while (*s == SP || *s == HT) /* Skip leading spaces and tabs */
- s++;
- for (x = strlen(s); /* Strip trailing spaces */
- (x > 1) && (s[x-1] == SP || s[x-1] == HT);
- x--)
- s[x-1] = NUL;
- while (1) { /* Loop through rest of string */
- if (*s == CMDQ) { /* Backslash (quote character)? */
- if ((x = xxesc(&s)) > -1) { /* Go interpret it. */
- *q++ = (char) x; /* Numeric backslash code, ok */
- } else { /* Just let it quote next char */
- s++; /* get past the backslash */
- *q++ = *s++; /* deposit next char */
- }
- continue;
- } else if (*s == SP || *s == NUL) { /* Unquoted space or NUL? */
- *q++ = NUL; /* End of output filename. */
- msfiles[r] = p; /* Add this filename to the list */
- debug(F111,"fnparse",msfiles[r],r);
- r++; /* Count it */
- if (*s == NUL) break; /* End of string? */
- while (*s == SP) s++; /* Skip repeated spaces */
- p = q; /* Start of next name */
- continue;
- } else *q++ = *s; /* Otherwise copy the character */
- s++; /* Next input character */
- }
- debug(F101,"fnparse r","",r);
- msfiles[r] = ""; /* Put empty string at end of list */
- cmlist = msfiles;
- return(r);
-}
-#endif /* NOMSEND */
-
-char * /* dbchr() for DEBUG SESSION */
-dbchr(c) int c; {
- static char s[8];
- char *cp = s;
-
- c &= 0xff;
- if (c & 0x80) { /* 8th bit on */
- *cp++ = '~';
- c &= 0x7f;
- }
- if (c < SP) { /* Control character */
- *cp++ = '^';
- *cp++ = (char) ctl(c);
- } else if (c == DEL) {
- *cp++ = '^';
- *cp++ = '?';
- } else { /* Printing character */
- *cp++ = (char) c;
- }
- *cp = '\0'; /* Terminate string */
- cp = s; /* Return pointer to it */
- return(cp);
-}
-
-/* C K H O S T -- Get name of local host (where C-Kermit is running) */
-
-/*
- Call with pointer to buffer to put hostname in, and length of buffer.
- Copies hostname into buffer on success, puts null string in buffer on
- failure.
-*/
-#ifdef BSD44
-#define BSD4
-#undef ATTSV
-#endif /* BSD44 */
-
-#ifdef SVORPOSIX
-#ifndef BSD44
-#ifndef apollo
-#include <sys/utsname.h>
-#endif /* apollo */
-#endif /* BSD44 */
-#else
-#ifdef BELLV10
-#include <utsname.h>
-#endif /* BELLV10 */
-#endif /* SVORPOSIX*/
-
-#ifdef CKSYSLOG
-extern char uidbuf[], * clienthost;
-#endif /* CKSYSLOG */
-
-VOID
-ckhost(vvbuf,vvlen) char * vvbuf; int vvlen; {
-
-#ifndef NOPUSH
- extern int nopush;
-#ifndef NOSERVER
- extern int en_hos;
-#endif /* NOSERVER */
-#endif /* NOPUSH */
-
-#ifdef pdp11
- *vvbuf = NUL;
-#else /* Everything else - rest of this routine */
-
- char *g;
- int havefull = 0;
-#ifdef VMS
- int x;
-#endif /* VMS */
-
-#ifdef SVORPOSIX
-#ifndef BSD44
-#ifndef _386BSD
-#ifndef APOLLOSR10
- struct utsname hname;
-#endif /* APOLLOSR10 */
-#endif /* _386BSD */
-#endif /* BSD44 */
-#endif /* SVORPOSIX */
-#ifdef datageneral
- int ac0 = (char *) vvbuf, ac1 = -1, ac2 = 0;
-#endif /* datageneral */
-
-#ifndef NOPUSH
- if (getenv("CK_NOPUSH")) { /* No shell access allowed */
- nopush = 1; /* on this host... */
-#ifndef NOSERVER
- en_hos = 0;
-#endif /* NOSERVER */
- }
-#endif /* NOPUSH */
-
- *vvbuf = NUL; /* How let's get our host name ... */
-
-#ifndef BELLV10 /* Does not have gethostname() */
-#ifndef OXOS
-#ifdef SVORPOSIX
-#ifdef APOLLOSR10
- ckstrncpy(vvbuf,"Apollo",vvlen);
-#else
-#ifdef BSD44
- if (gethostname(vvbuf,vvlen) < 0)
- *vvbuf = NUL;
-#else
-#ifdef _386BSD
- if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL;
-#else
-#ifdef QNX
-#ifdef TCPSOCKET
- if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL;
-#else
- if (uname(&hname) > -1) ckstrncpy(vvbuf,hname.nodename,vvlen);
-#endif /* TCPSOCKET */
-#else /* SVORPOSIX but not _386BSD or BSD44 */
-#ifdef __ia64__
- if (uname(&hname) > -1) ckstrncpy(vvbuf,hname.nodename,vvlen);
-#else
- if (uname(&hname) > -1) {
- char * p;
- p = hname.nodename;
-#ifdef TCPSOCKET
-#ifndef NOCKGETFQHOST
- if (!ckstrchr(p,'.'))
- p = (char *)ckgetfqhostname(p);
-#endif /* NOCKGETFQHOST */
-#endif /* TCPSOCKET */
- if (!p) p = "";
- if (!*p) p = "(unknown)";
- ckstrncpy(vvbuf,p,vvlen);
- }
-#endif /* __ia64__ */
-#endif /* QNX */
-#endif /* _386BSD */
-#endif /* BSD44 */
-#endif /* APOLLOSR10 */
-#else /* !SVORPOSIX */
-#ifdef BSD4
- if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL;
-#else /* !BSD4 */
-#ifdef VMS
- g = getenv("SYS$NODE");
- if (g) ckstrncpy(vvbuf,g,vvlen);
- x = (int)strlen(vvbuf);
- if (x > 1 && vvbuf[x-1] == ':' && vvbuf[x-2] == ':') vvbuf[x-2] = NUL;
-#else
-#ifdef datageneral
- if (sys($HNAME,&ac0,&ac1,&ac2) == 0) /* successful */
- vvlen = ac2 + 1; /* enh - have to add one */
-#else
-#ifdef OS2 /* OS/2 */
- g = os2_gethostname();
- if (g) ckstrncpy(vvbuf,g,vvlen);
-#else /* OS2 */
-#ifdef OSK
-#ifdef TCPSOCKET
- if (gethostname(vvbuf, vvlen) < 0) *vvbuf = NUL;
-#endif /* TCPSOCKET */
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* BSD4 */
-#endif /* SVORPOSIX */
-#else /* OXOS */
- /* If TCP/IP is not installed, gethostname() fails, use uname() */
- if (gethostname(vvbuf,vvlen) < 0) {
- if (uname(&hname) > -1)
- ckstrncpy(vvbuf,hname.nodename,vvlen);
- else
- *vvbuf = NUL;
- }
-#endif /* OXOS */
-#endif /* BELLV10 */
- if (*vvbuf == NUL) { /* If it's still empty */
- g = getenv("HOST"); /* try this */
- if (g) ckstrncpy(vvbuf,g,vvlen);
- }
- vvbuf[vvlen-1] = NUL; /* Make sure result is terminated. */
-#endif /* pdp11 */
-}
-#ifdef BSD44
-#undef BSD4
-#define ATTSV
-#endif /* BSD44 */
-
-/*
- A S K M O R E -- Poor person's "more".
- Returns 0 if no more, 1 if more wanted.
-*/
-int
-askmore() {
- char c;
- int rv, cx;
-#ifdef IKSD
- extern int timelimit;
-#endif /* IKSD */
-#ifdef IKSDCONF
- extern int iksdcf;
-#endif /* IKSDCONF */
-#ifdef CK_APC
- extern int apcstatus, apcactive;
-#endif /* CK_APC */
-
-#ifdef NOICP
- return(1);
-#else
- if (!xaskmore)
- return(1);
-#ifdef IKSDCONF
- if (inserver && !iksdcf)
- return(1);
-#endif /* IKSDCONF */
-#ifdef CK_APC
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && (apcstatus & APC_NOINP)))
- return(1);
-#endif /* CK_APC */
-#ifdef VMS
- if (batch)
- return(1);
-#else
-#ifdef UNIX
- if (backgrd)
- return(1);
-#endif /* UNIX */
-#endif /* VMS */
-
-#ifndef VMS
- concb((char)escape); /* Force CBREAK mode. */
-#endif /* VMS */
-
- rv = -1;
- while (rv < 0) {
-#ifndef OS2
- printf("more? ");
-#ifdef UNIX
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
-#endif /* UNIX */
-#else
- printf("more? ");
- fflush(stdout);
-#endif /* OS2 */
-
-#ifdef IKSD
- if (inserver) {
- cx = cmdgetc(timelimit);
- if (cx < -1 && timelimit) {
- printf("\n?IKS idle timeout - Goodbye.\n");
- doexit(GOOD_EXIT,0);
- } else if (cx == -1) { /* Connection lost */
- doexit(BAD_EXIT,0);
- }
- c = (char) cx;
- } else {
-#endif /* IKSD */
-#ifdef VMS
- conbin((char)escape); /* Protect against Ctrl-Z */
- cx = coninc(0);
- concb((char)escape);
-#else
- cx = cmdgetc(0);
-#endif /* VMS */
- debug(F101,"askmore cmdgetc","",cx);
- if (cx == EOF) {
- debug(F100,"askmore EOF","",0);
-#ifdef VMS
- c = '\032';
-#else
- c = 'n';
-#endif /* VMS */
- } else {
- c = (char)cx;
- }
- debug(F101,"askmore c","",c);
-
-#ifdef IKSD
- }
-#endif /* IKSD */
- switch (c) {
- /* Yes */
- case 'p': case 'P': case 'g': case 'G': /* Proceed or Go */
- xaskmore = 0;
- /* fall thru on purpose */
-
- case SP: case 'y': case 'Y': case 012: case 015:
-#ifdef OSK
- write(1, "\015 \015", sizeof "\015 \015" - 1);
-#else
- printf("\015 \015");
-#endif /* OSK */
- rv = 1;
- break;
- /* No */
- case 'n': case 'N': case 'q': case 'Q':
-#ifdef OSK
- printf("\n");
-#else
- printf("\015\012");
-#endif /* OSK */
- rv = 0;
- break;
- case '\003':
- case '\004':
- case '\032':
-#ifdef OSK
- printf("^%c...\n", (c + 0100));
-#else
- printf("^%c...\015\012", (c + 0100));
-#endif /* OSK */
- rv = 0;
- break;
- /* Invalid answer */
- default:
- debug(F111,"askmore","invalid answer",c);
- printf("Y or space-bar for yes, N for no, G to show the rest\n");
- continue;
- }
-#ifdef OS2
- printf("\r \r");
- fflush(stdout);
-#endif /* OS2 */
- }
- return(rv);
-#endif /* NOICP */
-}
-
-/* T R A P -- Terminal interrupt handler */
-
-SIGTYP
-#ifdef CK_ANSIC
-trap(int sig)
-#else
-trap(sig) int sig;
-#endif /* CK_ANSIC */
-/* trap */ {
- extern int b_save, f_save;
-#ifndef NOICP
- extern int timelimit;
-#endif /* NOICP */
-#ifdef OS2
- extern unsigned long startflags;
-#ifndef NOSETKEY
- extern int os2gks;
-#endif /* NOSETKEY */
- int i;
-#endif /* OS2 */
-#ifndef NOSPL
- extern int i_active, instatus;
-#endif /* NOSPL */
-#ifdef VMS
- int i; FILE *f;
-#endif /* VMS */
- extern int zchkod, zchkid;
-#ifndef NOSPL
- extern int unkmacro;
-#endif /* NOSPL */
-
- debok = 1;
-#ifdef NTSIG
- connoi();
-#endif /* NTSIG */
-#ifdef __EMX__
- signal(SIGINT, SIG_ACK);
-#endif
-#ifdef GEMDOS
-/* GEM is not reentrant, no i/o from interrupt level */
- cklongjmp(cmjbuf,1); /* Jump back to parser now! */
-#endif /* GEMDOS */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F100,"*********************","",0);
- if (sig == SIGINT)
- debug(F101,"trap caught SIGINT","",sig);
- else
- debug(F101,"trap caught signal","",sig);
- debug(F100,"*********************","",0);
- }
-#endif /* DEBUG */
-
-#ifdef OS2
- if ( sig == SIGBREAK && (startflags & 128) ) {
- debug(F101,"trap ignoring SIGBREAK","",sig);
- return;
- }
-#endif /* OS2 */
-
-#ifndef NOICP
- timelimit = 0; /* In case timed ASK interrupted */
-#ifndef NOSPL
- unkmacro = 0; /* Or ON_UNKNOWN_MACRO interrupted.. */
-#endif /* NOSPL */
-#endif /* NOICP */
- zchkod = 0; /* Or file expansion interrupted... */
- zchkid = 0;
- interrupted = 1;
-
- if (what & W_CONNECT) { /* Are we in CONNECT mode? */
-/*
- The HP workstation Reset key sends some kind of ueber-SIGINT that can not
- be SIG_IGNored, so we wind up here somehow (even though this is *not* the
- current SIGINT handler). Just return.
-*/
- debug(F101,"trap: SIGINT caught during CONNECT","",sig);
- SIGRETURN;
- }
-#ifndef NOSPL
- if (i_active) { /* INPUT command was active? */
- i_active = 0; /* Not any more... */
- instatus = INP_UI; /* INPUT status = User Interrupted */
- }
-#endif /* NOSPL */
-
-#ifndef NOXFER
- ftreset(); /* Restore global protocol settings */
- binary = b_save; /* Then restore these */
- fncnv = f_save;
- bye_active = 0;
- diractive = 0;
- cdactive = 0;
-#endif /* NOXFER */
- zclose(ZIFILE); /* If we were transferring a file, */
- zclose(ZOFILE); /* close it. */
-#ifndef NOICP
- cmdsquo(cmd_quoting); /* If command quoting was turned off */
-#ifdef CKLEARN
- {
- extern FILE * learnfp;
- extern int learning;
- if (learnfp) {
- fclose(learnfp);
- learnfp = NULL;
- learning = 0;
- }
- }
-#endif /* CKLEARN */
-#endif /* NOICP */
-#ifdef CK_APC
- delmac("_apc_commands",1);
- apcactive = APC_INACTIVE;
-#endif /* CK_APC */
-
-#ifdef VMS
-/*
- Fix terminal.
-*/
- if (ft_win) { /* If curses window open */
- debug(F100,"^C trap() curses","",0);
- xxscreen(SCR_CW,0,0L,""); /* Close it */
- conres(); /* Restore terminal */
- i = printf("^C..."); /* Echo ^C to standard output */
- } else {
- conres();
- i = printf("^C...\n"); /* Echo ^C to standard output */
- }
- if (i < 1 && ferror(stdout)) { /* If there was an error */
- debug(F100,"^C trap() error","",0);
- fclose(stdout); /* close standard output */
- f = fopen(dftty, "w"); /* open the controlling terminal */
- if (f) stdout = f; /* and make it standard output */
- printf("^C...\n"); /* and echo the ^C again. */
- }
-#else /* Not VMS */
-#ifdef STRATUS
- conres(); /* Set console back to normal mode */
-#endif /* STRATUS */
-#ifndef NOXFER
- if (ft_win) { /* If curses window open, */
- debug(F100,"^C trap() curses","",0);
- xxscreen(SCR_CW,0,0L,""); /* close it. */
- printf("^C..."); /* Echo ^C to standard output */
- } else {
-#endif /* NOXFER */
- printf("^C...\n");
-#ifndef NOXFER
- }
-#endif /* NOXFER */
-#endif /* VMS */
-#ifdef datageneral
- connoi_mt(); /* Kill asynch task that listens to */
- ttimoff();
- conres(); /* the keyboard */
-#endif /* datageneral */
-
-#ifndef NOCCTRAP
-/* This is stupid -- every version should have ttimoff()... */
-#ifdef UNIX
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef OSK
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef STRATUS
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef OS2
-#ifndef NOSETKEY
- os2gks = 1; /* Turn back on keycode mapping */
-#endif /* NOSETKEY */
-#ifndef NOLOCAL
- for (i = 0; i < VNUM; i++)
- VscrnResetPopup(i);
-#endif /* NOLOCAL */
-#ifdef TCPSOCKET
-#ifdef NT
- /* WSAIsBlocking() returns FALSE in Win95 during a blocking accept call */
- if ( WSASafeToCancel /* && WSAIsBlocking() */ ) {
- WSACancelBlockingCall();
- }
-#endif /* NT */
-#endif /* TCPSOCKET */
-#ifdef CK_NETBIOS
- NCBCancelOutstanding();
-#endif /* CK_NETBIOS */
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef VMS
- ttimoff(); /* Turn off any timer interrupts */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* STRATUS */
-#endif /* OSK */
-#endif /* UNIX */
-
-#ifdef NETPTY
- /* Clean up Ctrl-C out of REDIRECT or external protocol */
- {
- extern PID_T pty_fork_pid;
- extern int pty_master_fd, pty_slave_fd;
- int x;
-
- signal(SIGCHLD,SIG_IGN); /* We don't want this any more */
-
- debug(F101,"trap pty_master_fd","",pty_master_fd);
- if (pty_master_fd > 2) {
- x = close(pty_master_fd);
- debug(F101,"trap pty_master_fd close","",x);
- }
- pty_master_fd = -1;
- debug(F101,"trap pty_slave_fd","",pty_slave_fd);
- if (pty_slave_fd > 2) {
- x = close(pty_slave_fd);
- debug(F101,"trap pty_slave_fd close","",x);
- }
- pty_slave_fd = -1;
- debug(F101,"trap pty_fork_pid","",pty_fork_pid);
- if (pty_fork_pid > 0) {
- x = kill(pty_fork_pid,0); /* See if the fork is really there */
- debug(F111,"trap pty_fork_pid kill 0 errno",ckitoa(x),errno);
- if (x == 0) { /* Seems to be active */
- x = kill(pty_fork_pid,SIGHUP); /* Ask it to clean up & exit */
- debug(F101,"trap pty_fork_pid kill SIGHUP","",x);
- msleep(100);
- errno = 0;
- x = kill(pty_fork_pid,0); /* Is it still there? */
- if (x == 0
-#ifdef ESRCH
- /* This module is not always exposed to <errno.h> */
- || errno != ESRCH
-#endif /* ESRCH */
- ) {
- x = kill(pty_fork_pid,SIGKILL);
- debug(F101,"trap pty_fork_pid kill SIGKILL","",x);
- }
- }
- pty_fork_pid = -1;
- }
- }
-#endif /* NETPTY */
-
-#ifdef OSK
- sigmask(-1);
-/*
- We are in an intercept routine but do not perform a F$RTE (done implicitly
- by rts). We have to decrement the sigmask as F$RTE does. Warning: longjump
- only restores the cpu registers, NOT the fpu registers. So don't use fpu at
- all or at least don't use common fpu (double or float) register variables.
-*/
-#endif /* OSK */
-
-#ifdef NTSIG
- PostCtrlCSem();
-#else /* NTSIG */
- debug(F100,"trap about to longjmp","",0);
-#ifdef NT
- cklongjmp(ckjaddr(cmjbuf),1);
-#else /* NT */
- cklongjmp(cmjbuf,1);
-#endif /* NT */
-#endif /* NTSIG */
-#else /* NOCCTRAP */
-/* No Ctrl-C trap, just exit. */
-#ifdef CK_CURSES /* Curses support? */
- xxscreen(SCR_CW,0,0L,""); /* Close curses window */
-#endif /* CK_CURSES */
- doexit(BAD_EXIT,what); /* Exit poorly */
-#endif /* NOCCTRAP */
- SIGRETURN;
-}
-
-
-/* C K _ T I M E -- Returns pointer to current time. */
-
-char *
-ck_time() {
- static char tbuf[10];
- char *p;
- int x;
-
- ztime(&p); /* "Thu Feb 8 12:00:00 1990" */
- if (!p) /* like asctime()! */
- return("");
- if (*p) {
- for (x = 11; x < 19; x++) /* copy hh:mm:ss */
- tbuf[x - 11] = p[x]; /* to tbuf */
- tbuf[8] = NUL; /* terminate */
- }
- return(tbuf); /* and return it */
-}
-
-/* C C _ C L E A N -- Cleanup after terminal interrupt handler */
-
-#ifdef GEMDOS
-int
-cc_clean() {
- zclose(ZIFILE); /* If we were transferring a file, */
- zclose(ZOFILE); /* close it. */
- printf("^C...\n"); /* Not VMS, no problem... */
-}
-#endif /* GEMDOS */
-
-
-/* S T P T R A P -- Handle SIGTSTP (suspend) signals */
-
-SIGTYP
-#ifdef CK_ANSIC
-stptrap(int sig)
-#else
-stptrap(sig) int sig;
-#endif /* CK_ANSIC */
-/* stptrap */ {
-
-#ifndef NOJC
- int x; extern int cmflgs;
- debug(F101,"stptrap() caught signal","",sig);
- if (!xsuspend) {
- printf("\r\nsuspend disabled\r\n");
-#ifndef NOICP
- if (what & W_COMMAND) { /* If we were parsing commands */
- prompt(xxstring); /* reissue the prompt and partial */
- if (!cmflgs) /* command (if any) */
- printf("%s",cmdbuf);
- }
-#endif /* NOICP */
- } else {
- conres(); /* Reset the console */
-#ifndef OS2
- /* Flush pending output first, in case we are continued */
- /* in the background, which could make us block */
- fflush(stdout);
-
- x = psuspend(xsuspend); /* Try to suspend. */
- if (x < 0)
-#endif /* OS2 */
- printf("Job control not supported\r\n");
- conint(trap,stptrap); /* Rearm the trap. */
- debug(F100,"stptrap back from suspend","",0);
- switch (what) {
- case W_CONNECT: /* If suspended during CONNECT? */
- conbin((char)escape); /* put console back in binary mode */
- debug(F100,"stptrap W_CONNECT","",0);
- break;
-#ifndef NOICP
- case W_COMMAND: /* Suspended in command mode */
- debug(F101,"stptrap W_COMMAND pflag","",pflag);
- concb((char)escape); /* Put back CBREAK tty mode */
- if (pflag) { /* If command parsing was */
- prompt(xxstring); /* reissue the prompt and partial */
- if (!cmflgs) /* command (if any) */
- printf("%s",cmdbuf);
- }
- break;
-#endif /* NOICP */
- default: /* All other cases... */
- debug(F100,"stptrap default","",0);
- concb((char)escape); /* Put it back in CBREAK mode */
- break;
- }
- }
-#endif /* NOJC */
- SIGRETURN;
-}
-
-#ifdef TLOG
-#define TBUFL 300
-
-/* T L O G -- Log a record in the transaction file */
-/*
- Call with a format and 3 arguments: two strings and a number:
- f - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
- s1,s2 - String arguments 0 and 1.
- n - Long, argument 2.
-*/
-VOID
-#ifdef CK_ANSIC
-dotlog(int f, char *s1, char *s2, CK_OFF_T n)
-#else
-dotlog(f,s1,s2,n) int f; CK_OFF_T n; char *s1, *s2;
-#endif /* CK_ANSIC */
-/* dotlog */ {
- static char s[TBUFL];
- extern int tlogfmt;
- char *sp = s; int x;
- if (!s1) s1 = "";
- if (!s2) s2 = "";
-
- if (!tralog) return; /* If no transaction log, don't */
- if (tlogfmt != 1) return;
- switch (f) {
- case F000: /* 0 (special) "s1 n s2" */
- if ((int)strlen(s1) + (int)strlen(s2) + 15 > TBUFL)
- sprintf(sp,"?T-Log string too long");
- else
- sprintf(sp,"%s %s %s",s1,ckfstoa(n),s2);
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F001: /* 1, " n" */
- sprintf(sp," %s",ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F010: /* 2, "[s2]" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if (x + 6 > TBUFL)
- sprintf(sp,"?String too long");
- else sprintf(sp,"[%s]",s2);
- if (zsoutl(ZTFILE,"") < 0) tralog = 0;
- break;
- case F011: /* 3, "[s2] n" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if (x + 6 > TBUFL)
- sprintf(sp,"?String too long");
- else sprintf(sp,"[%s] %s",s2,ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F100: /* 4, "s1" */
- if (zsoutl(ZTFILE,s1) < 0) tralog = 0;
- break;
- case F101: /* 5, "s1: n" */
- if ((int)strlen(s1) + 15 > TBUFL)
- sprintf(sp,"?String too long");
- else sprintf(sp,"%s: %s",s1,ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F110: /* 6, "s1 s2" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if ((int)strlen(s1) + x + 4 > TBUFL)
- sprintf(sp,"?String too long");
- else
- sprintf(sp,"%s%s%s",s1,((*s2 == ':') ? "" : " "),s2);
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F111: /* 7, "s1 s2: n" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if ((int)strlen(s1) + x + 15 > TBUFL)
- sprintf(sp,"?String too long");
- else
- sprintf(sp,"%s%s%s: %s",s1,((*s2 == ':') ? "" : " "),s2,ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- default:
- sprintf(sp,"?Invalid format for tlog() - %d",f);
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- }
-}
-
-/*
- D O X L O G
-
- This is the transaction-log writer for BRIEF format.
- The idea is produce one record (line) per file. Each record
- has the following delimited fields:
- Date (yyyymmdd)
- Time (hh:mm:ss)
- Action: SEND or RECV
- File name
- File size
- Transfer mode (text, binary, image, labeled, etc).
- Status: OK or FAILED
- Free-form comments in doublequotes
- The default separator is comma.
- If a field contains the separator, it is enclosed in doublequotes.
-*/
-VOID
-#ifdef CK_ANSIC
-doxlog(int x, char * fn, CK_OFF_T fs, int fm, int status, char * msg)
-#else
-doxlog(x, fn, fs, fm, status, msg)
- int x; char * fn; CK_OFF_T fs; int fm; int status; char * msg;
-#endif /* CK_ANSIC */
-/* doxlog */ {
- extern int tlogsep;
- char sep[2];
- char buf[CKMAXPATH+256], * bufp;
- char tmpbuf[32];
- char * s, * p;
- int len, left, ftp = 0, k;
-
- if (!tralog) return; /* If no transaction log, don't */
-
- if (!fn) fn = ""; /* Protect against null pointers */
- if (!msg) msg = "";
- if (x & W_FTP)
- ftp++;
-
- sep[0] = (char) tlogsep;
- sep[1] = NUL;
- if (!sep[0]) sep[0] = ',';
-
- bufp = buf;
- left = sizeof(buf);
- debug(F101,"XXX doxlog left 1","",left);
-
- p = zzndate(); /* Date */
- ckmakmsg(buf, left, p ? p : "00000000", sep, NULL, NULL);
- bufp += 9;
- left -= 9;
- debug(F111,"XXX doxlog left 2",buf,left);
-
- ztime(&p);
- ckstrncpy(bufp,p+11,left);
- bufp += 8;
- left -= 8;
- debug(F111,"XXX doxlog left 3",buf,left);
-
- if (ftp) {
- if (!(x & (W_SEND|W_RECV)))
- return;
- s = (x & W_SEND) ? "PUT" : "GET";
- k = 3;
- } else {
- s = (x & W_SEND) ? "SEND" : "RECV";
- k = 4;
- }
- ckmakmsg(bufp,left,sep,s,sep,NULL);
- bufp += k + 2;
- left -= (k + 2);
- debug(F111,"XXX doxlog left 4",buf,left);
-
- s = "";
- if (ckstrchr(fn,sep[0])) /* Filename */
- s = "\"";
- ckmakmsg(bufp,left,s,fn,s,sep);
- sprintf(tmpbuf,"%s",ckfstoa(fs)); /* Size */
- ckstrncat(buf,tmpbuf,CKMAXPATH);
- ckstrncat(buf,sep,CKMAXPATH);
- debug(F110,"doxlog 4",buf,0);
-
-#ifdef NOICP
- /* Transfer mode */
- ckstrncpy(tmpbuf, (binary ? "binary" : "text"), TMPBUFSIZ);
-#else
- ckstrncpy(tmpbuf,gfmode(fm,0),TMPBUFSIZ);
-#endif /* NOICP */
- if (ckstrchr(tmpbuf,sep[0])) { /* Might contain spaces */
- ckstrncat(buf,"\"",CKMAXPATH);
- ckstrncat(buf,tmpbuf,CKMAXPATH);
- ckstrncat(buf,"\"",CKMAXPATH);
- } else
- ckstrncat(buf,tmpbuf,CKMAXPATH);
- ckstrncat(buf,sep,CKMAXPATH);
- debug(F110,"doxlog 5",buf,0);
-
- ckstrncat(buf, status ? "FAILED" : "OK",CKMAXPATH);
- len = strlen(buf);
- left = CKMAXPATH+256 - len;
- if (left < 2) fatal("doxlog buffer overlow");
-
- debug(F111,"XXX doxlog left 5",buf,left);
-
- debug(F110,"doxlog buf 1", buf, len);
- s = buf + len;
- if (status == 0 && left > 32) {
- long cps = 0L;
-#ifdef GFTIMER
- debug(F101,"DOXLOG fpxfsecs","",(long)(fpxfsecs * 1000));
- if (fpxfsecs) cps = (long)((CKFLOAT) fs / fpxfsecs);
- sprintf(s,"%s\"%0.3fsec %ldcps\"",sep,fpxfsecs,cps);
-#else
- if (xfsecs) cps = fs / xfsecs;
- sprintf(s,"%s\"%ldsec %ldcps\"",sep,xfsecs,cps);
-#endif /* GFTIMER */
- } else if ((int)strlen(msg) + 4 < left) {
- sprintf(s,"%s\"%s\"",sep,msg);
- }
- debug(F111,"XXX doxlog left 5",buf,left);
-
- debug(F110,"doxlog 5",buf,0);
- x = zsoutl(ZTFILE,buf);
- debug(F101,"doxlog zsoutl","",x);
- if (x < 0) tralog = 0;
-}
-#endif /* TLOG */
-
-#ifndef MAC
-/*
- The rest of this file is for all implementations but the Macintosh.
-*/
-
-#ifdef CK_CURSES
-static int repaint = 0; /* Transfer display needs repainting */
-#endif /* CK_CURSES */
-
-#ifndef NOXFER
-/* C H K I N T -- Check for console interrupts */
-
-/*
- Used during file transfer in local mode only:
- . If user has not touched the keyboard, returns 0 with no side effects.
- . If user typed S or A (etc, see below) prints status message and returns 0.
- . If user typed X or F (etc, see below) returns 0 with cxseen set to 1.
- . If user typed Z or B (etc, see below) returns 0 with czseen set to 1.
- . If user typed E or C (etc, see below) returns -1.
-*/
-int
-chkint() {
- int ch, cn, ofd; long zz;
- if (!xfrint)
- return(0);
- if ((!local) || (quiet)) return(0); /* Only do this if local & not quiet */
-#ifdef datageneral
- if (con_reads_mt) /* if conint_mt task is active */
- if (conint_avl) { /* and there's an interrupt pending */
- cn = 1; /* process it */
- ch = conint_ch;
- conint_avl = 0; /* turn off flag so conint_mt can */
- } else /* proceed */
- return(0);
- else /* if conint_mt not active */
- if ((ch = coninc(2)) < 0) /* try to get char manually */
- return(0); /* I/O error, or no data */
- else /* if successful, set cn so we */
- cn = 1; /* know we got one */
- debug(F101,"chkint got keyboard character",ch,cn);
-#else /* !datageneral */
-#ifdef NTSIG
- {
- extern int TlsIndex;
- struct _threadinfo * threadinfo;
- threadinfo = (struct _threadinfo *) TlsGetValue(TlsIndex);
- if (threadinfo) {
- if (!WaitSem(threadinfo->DieSem,0))
- return -1; /* Cancel Immediately */
- }
- }
-#endif /* NTSIG */
- cn = conchk(); /* Any input waiting? */
- debug(F101,"conchk","",cn);
- if (cn < 1) return(0);
- ch = coninc(5) ;
- debug(F101,"coninc","",ch);
- if (ch < 0) return(0);
-#endif /* datageneral */
-
- ch &= 0177;
- switch (ch) {
- case 'A': case 'a': case 0001: /* Status report */
- case 'S': case 's':
- if (fdispla != XYFD_R && fdispla != XYFD_S && fdispla != XYFD_N)
- return(0); /* Only for serial, simple or none */
- ofd = fdispla; /* [MF] Save file display type */
- if (fdispla == XYFD_N)
- fdispla = XYFD_R; /* [MF] Pretend serial if no display */
- xxscreen(SCR_TN,0,0l,"Status report:");
- xxscreen(SCR_TN,0,0l," file type: ");
- if (binary) {
- switch(binary) {
- case XYFT_L: xxscreen(SCR_TZ,0,0l,"labeled"); break;
- case XYFT_I: xxscreen(SCR_TZ,0,0l,"image"); break;
- case XYFT_U: xxscreen(SCR_TZ,0,0l,"binary undefined"); break;
- default:
- case XYFT_B: xxscreen(SCR_TZ,0,0l,"binary"); break;
- }
- } else {
-#ifdef NOCSETS
- xxscreen(SCR_TZ,0,0l,"text");
-#else
- xxscreen(SCR_TU,0,0l,"text, ");
- if (tcharset == TC_TRANSP || xfrxla == 0) {
- xxscreen(SCR_TZ,0,0l,"transparent");
- } else {
- if (what & W_SEND) {
- xxscreen(SCR_TZ,0,0l,tcsinfo[tcharset].keyword);
- xxscreen(SCR_TU,0,0l," => ");
- xxscreen(SCR_TZ,0,0l,fcsinfo[fcharset].keyword);
- } else {
- xxscreen(SCR_TZ,0,0l,fcsinfo[fcharset].keyword);
- xxscreen(SCR_TU,0,0l," => ");
- xxscreen(SCR_TZ,0,0l,tcsinfo[tcharset].keyword);
- }
- }
-#endif /* NOCSETS */
- }
- xxscreen(SCR_QE,0,filcnt," file number");
- if (fsize) xxscreen(SCR_QE,0,fsize," size");
- xxscreen(SCR_QE,0,ffc," characters so far");
- if (fsize > 0L) {
-#ifdef CK_RESEND
- zz = what & W_SEND ? sendstart : what & W_RECV ? rs_len : 0;
- zz = ( (ffc + zz) * 100L ) / fsize;
-#else
- zz = ( ffc * 100L ) / fsize;
-#endif /* CK_RESEND */
- xxscreen(SCR_QE,0,zz, " percent done");
- }
- if (bctu == 4) { /* Block check */
- xxscreen(SCR_TU,0,0L," block check: ");
- xxscreen(SCR_TZ,0,0L,"blank-free-2");
- } else xxscreen(SCR_QE,0,(long)bctu, " block check");
- xxscreen(SCR_QE,0,(long)rptflg," compression");
- xxscreen(SCR_QE,0,(long)ebqflg," 8th-bit prefixing");
- xxscreen(SCR_QE,0,(long)lscapu," locking shifts");
- if (!network)
- xxscreen(SCR_QE,0, speed, " speed");
- if (what & W_SEND)
-
- xxscreen(SCR_QE,0,spsiz, " packet length");
- else if (what & W_RECV || what & W_REMO)
- xxscreen(SCR_QE,0,urpsiz," packet length");
- xxscreen(SCR_QE,0,wslots, " window slots");
- fdispla = ofd; /* [MF] Restore file display type */
- return(0);
-
- case 'B': case 'b': case 0002: /* Cancel batch */
- case 'Z': case 'z': case 0032:
- czseen = 1;
- interrupted = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- (((what & W_RECV) && (wslots > 1)) ?
- "Canceling batch, wait... " :
- "Canceling batch... ")
- );
- return(0);
-
- case 'F': case 'f': case 0006: /* Cancel file */
- case 'X': case 'x': case 0030:
- cxseen = 1;
- interrupted = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- (((what & W_RECV) && (wslots > 1)) ?
- "Canceling file, wait... " :
- "Canceling file... ")
- );
- return(0);
-
- case 'R': case 'r': case 0022: /* Resend packet */
- case 0015: case 0012:
-#ifdef STREAMING
- if (streaming)
- return(0);
-#endif /* STREAMING */
- xxscreen(SCR_ST,ST_MSG,0l,"Resending packet... ");
- numerrs++;
- resend(winlo);
- return(0);
-
-#ifdef datageneral
- case '\03': /* We're not trapping ^C's with */
- trap(0); /* signals, so we check here */
-#endif /* datageneral */
-
- case 'C': case 'c': /* Ctrl-C */
-#ifndef datageneral
- case '\03':
-#endif /* datageneral */
-
- case 'E': case 'e': /* Send error packet */
- case 0005:
- interrupted = 1;
- return(-1);
-
-#ifdef CK_CURSES
- case 0014: /* Ctrl-L to refresh screen */
- case 'L': case 'l': /* Also accept L (upper, lower) */
- case 0027: /* Ctrl-W synonym for VMS & Ingres */
- repaint = 1;
- return(0);
-#endif /* CK_CURSES */
-
- case 'T':
- case 't': /* Turn on debug-log timestamps */
-#ifdef DEBUG
- {
- extern int debtim;
- if (ch == 'T') {
- debtim = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- "Debug timestamps On... ");
- } else {
- debtim = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- "Debug timestamps Off... ");
- }
- }
-#endif /* DEBUG */
- return(0);
-
- case 'D':
-#ifdef DEBUG
- if (!deblog) {
- debopn("debug.log",0);
- if (deblog) {
- xxscreen(SCR_ST,ST_MSG,0l,"debug.log open... ");
- } else {
- xxscreen(SCR_ST,ST_MSG,0l,"debug.log open FAILED... ");
- }
- } else {
- xxscreen(SCR_ST,ST_MSG,0l,"Debug log On... ");
- }
- if (deblog)
- debok = 1;
-#endif /* DEBUG */
- return(0);
-
- case 'd': /* Turn off debugging */
-#ifdef DEBUG
- if (deblog)
- xxscreen(SCR_ST,ST_MSG,0l,"Debug log Off... ");
- debok = 0;
-#endif /* DEBUG */
- return(0);
-
- default: /* Anything else, print message */
- intmsg(1L);
- return(0);
- }
-}
-
-/* I N T M S G -- Issue message about terminal interrupts */
-
-VOID
-#ifdef CK_ANSIC
-intmsg(long n)
-#else
-intmsg(n) long n;
-#endif /* CK_ANSIC */
-/* intmsg */ {
-#ifdef CK_NEED_SIG
- char buf[80];
-#endif /* CK_NEED_SIG */
-
- if (!displa || quiet) /* Not if we're being quiet */
- return;
- if (server && (!srvdis || n > -1L)) /* Special for server */
- return;
-#ifdef CK_NEED_SIG
- buf[0] = NUL; /* Keep compilers happy */
-#endif /* CK_NEED_SIG */
-#ifndef OXOS
-#ifdef SVORPOSIX
- conchk(); /* Clear out pending escape-signals */
-#endif /* SVORPOSIX */
-#endif /* ! OXOS */
-#ifdef VMS
- conres(); /* So Ctrl-C will work */
-#endif /* VMS */
- if ((!server && n == 1L) || (server && n < 0L)) {
-
-#ifdef CK_NEED_SIG
- if (xfrint) {
- ckmakmsg(buf,
- 80,
- "Type escape character (",
- dbchr(escape),
- ") followed by:",
- NULL
- );
- xxscreen(SCR_TN,0,0l,buf);
- }
-#endif /* CK_NEED_SIG */
-
- if (xfrint) {
- if (protocol == PROTO_K) {
- xxscreen(SCR_TN,0,0l,"X to cancel file, CR to resend current packet");
- xxscreen(SCR_TN,0,0l,"Z to cancel group, A for status report");
- xxscreen(SCR_TN,0,0l,"E to send Error packet, Ctrl-C to quit immediately: ");
- } else {
- xxscreen(SCR_TN,0,0l,"Ctrl-C to cancel file transfer: ");
- }
- } else {
- xxscreen(SCR_TN,0,0l,"Transfer interruption disabled. ");
- }
- }
- else xxscreen(SCR_TU,0,0l," ");
-}
-
-#ifndef NODISPLAY
-static int newdpy = 0; /* New display flag */
-static char fbuf[80]; /* Filename buffer */
-static char abuf[80]; /* As-name buffer */
-static char a2buf[80]; /* Second As-name buffer */
-static CK_OFF_T oldffc = 0L;
-static CK_OFF_T dots = 0L;
-static int hpos = 0;
-
-static VOID /* Initialize Serial or CRT display */
-dpyinit() {
- int m = 0, n = 0;
- char * s = "";
-
- newdpy = 0; /* Don't do this again */
- oldffc = (CK_OFF_T)0; /* Reset this */
- dots = (CK_OFF_T)0; /* and this.. */
- oldcps = cps = 0L;
-
- conoll(""); /* New line */
- if (what & W_SEND) s = "Sending: "; /* Action */
- else if (what & W_RECV) s = "Receiving: ";
- n = (int)strlen(s) + (int)strlen(fbuf);
- conol(fbuf);
- m = (int)strlen(abuf) + 4;
- if (n + m > cmd_cols) {
- conoll("");
- n = 0;
- } else
- n += m;
- if (*abuf) {
- conol(" => ");
- conol(abuf);
- }
- m = (int)strlen(a2buf) + 4;
- if (n + m > cmd_cols) {
- conoll("");
- n = 0;
- } else
- n += m;
- if (*a2buf) {
- conol(" => ");
- conol(a2buf);
- }
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- conoll("");
- if (fsize > (CK_OFF_T)-1) { /* Size */
- sprintf(fbuf,"Size: %s, Type: ",ckfstoa(fsize)); /* SAFE (80) */
- conol(fbuf); *fbuf = NUL;
- } else conol("Size: unknown, Type: ");
- if (binary) { /* Type */
- switch(binary) {
- case XYFT_L: conol("labeled"); break;
- case XYFT_I: conol("image"); break;
- case XYFT_U: conol("binary undefined"); break;
- default:
- case XYFT_B: conol("binary"); break;
- }
- } else {
-#ifdef NOCSETS
- conol("text");
-#else
- conol("text, ");
- if (tcharset == TC_TRANSP || xfrxla == 0) {
- conol("transparent");
- } else {
- if (what & W_SEND) {
- conol(fcsinfo[fcharset].keyword);
- conol(" => ");
- conol(tcsinfo[tcharset].keyword);
- } else {
- conol(tcsinfo[tcharset].keyword);
- conol(" => ");
- conol(fcsinfo[fcharset].keyword);
- }
- }
-#endif /* NOCSETS */
- }
-#ifdef STREAMING
- if (streaming)
- conol(", STREAMING");
-#endif /* STREAMING */
- conoll("");
-
- if (fdispla == XYFD_S) { /* CRT field headings */
-/*
- Define CK_CPS to show current transfer rate.
- Leave it undefined to show estimated time remaining.
- Estimated-time-remaining code from Andy Fyfe, not tested on
- pathological cases.
-*/
-#define CK_CPS
-
-#ifdef CK_CPS
- conoll(" File Percent Packet");
- conoll(" Bytes Done CPS Length");
-#else
- conoll(" File Percent Secs Packet");
- conoll(" Bytes Done Left Length");
-#endif /* CK_CPS */
- newdpy = 0;
- }
- hpos = 0;
-}
-
-/*
- showpkt(c)
- c = completion code: 0 means transfer in progress, nonzero means it's done.
- Show the file transfer progress counter and perhaps verbose packet type.
-*/
-VOID
-#ifdef CK_ANSIC
-showpkt(char c)
-#else
-showpkt(c) char c;
-#endif /* CK_ANSIC */
-/* showpkt */ {
-
-#ifndef GFTIMER
- long et; /* Elapsed time, entire batch */
-#endif /* GFTIMER */
- CK_OFF_T howfar; /* How far into file */
- long pd; /* Percent done, this file */
- long tp; /* Transfer rate, entire batch */
- long ps; /* Packet size, current packet */
- CK_OFF_T mytfc; /* Local copy of byte counter */
-
-#ifdef GFTIMER
- CKFLOAT tnow;
-#endif /* GFTIMER */
-
- if (newdpy) /* Put up filenames, etc, */
- dpyinit(); /* if they're not there already. */
-
- howfar = ffc; /* How far */
-/*
- Calculate CPS rate even if not displaying on screen for use in file
- transfer statistics.
-*/
-#ifdef GFTIMER
- tnow = gftimer(); /* Time since we started */
- ps = (what & W_RECV) ? rpktl : spktl; /* Packet size */
-#ifdef CK_RESEND
- if (what & W_SEND) /* In case we didn't start at */
- howfar += sendstart; /* the beginning... */
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- pd = -1; /* Percent done. */
- if (c == NUL) { /* Still going, figure % done */
- if (!fsize) return; /* Empty file, don't bother */
- pd = (fsize > 99) ? (howfar / (fsize / (CK_OFF_T)100)) : 0;
- if (pd > 100) pd = 100; /* Expansion */
- }
- if (c != NUL)
- if (!cxseen && !discard && !czseen)
- pd = 100; /* File complete, so 100%. */
-
- mytfc = (pd < 100) ? tfc + ffc : tfc; /* CPS */
- tp = (long)((tnow > 0.0) ? (CKFLOAT) mytfc / tnow : 0);
- if (c && (tp == 0))
- tp = ffc;
-
- cps = tp; /* Set global variable */
- if (cps > peakcps && /* Peak transfer rate */
- ((what & W_SEND && spackets > wslots + 4) ||
- (!(what & W_SEND) && spackets > 10))) {
- peakcps = cps;
- }
-
-#else /* Not GFTIMER */
-
- et = gtimer(); /* Elapsed time */
- ps = (what & W_RECV) ? rpktl : spktl; /* Packet length */
-#ifdef CK_RESEND
- if (what & W_SEND) /* And if we didn't start at */
- howfar += sendstart; /* the beginning... */
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- pd = -1; /* Percent done. */
- if (c == NUL) { /* Still going, figure % done */
- if (fsize == 0L) return; /* Empty file, don't bother */
- pd = (fsize > 99) ? (howfar / (fsize / (CK_OFF_T)100)) : 0;
- if (pd > 100) pd = 100; /* Expansion */
- }
- if (c != NUL)
- if (!cxseen && !discard && !czseen)
- pd = 100; /* File complete, so 100%. */
-
-
-#ifndef CK_CPS
-/*
- fsecs = time (from gtimer) that this file started (set in sfile()).
- Rate so far is ffc / (et - fsecs), estimated time for remaining bytes
- is (fsize - ffc) / (ffc / (et - fsecs)).
-*/
- tp = (howfar > 0) ? (fsize - howfar) * (et - fsecs) / howfar : 0;
-#endif /* CK_CPS */
-
-#ifdef CK_CPS
- mytfc = (pd < 100) ? tfc + ffc : tfc;
- tp = (et > 0) ? mytfc / et : 0; /* Transfer rate */
- if (c && (tp == 0)) /* Watch out for subsecond times */
- tp = ffc;
-
- cps = tp; /* Set global variable */
- if (cps > peakcps && /* Peak transfer rate */
- ((what & W_SEND && spackets > wslots + 4) ||
- (!(what & W_SEND) && spackets > 10))) {
- peakcps = cps;
- }
-#endif /* CK_CPS */
-
-#endif /* GFTIMER */
-
- if (fdispla == XYFD_S) { /* CRT display */
- char buffer[128];
- /* These sprintfs should be safe until we have 32-digit numbers */
-
- if (pd > -1L)
- sprintf(buffer, "%c%9s%5ld%%%8ld%8ld ", CR,ckfstoa(howfar),pd,tp,ps);
- else
- sprintf(buffer, "%c%9s %8ld%8ld ", CR,ckfstoa(howfar),tp,ps);
- conol(buffer);
- hpos = 31;
- } else if (fdispla == XYFD_R) { /* SERIAL */
- long i, k;
- if (howfar - oldffc < 1024) /* Update display every 1K */
- return;
- oldffc = howfar; /* Time for new display */
- k = (howfar / 1024L) - dots; /* How many K so far */
- for (i = 0L; i < k; i++) {
- if (hpos++ > (cmd_cols - 3)) { /* Time to wrap? */
- conoll("");
- hpos = 0;
- }
- conoc('.'); /* Print a dot for this K */
- dots++; /* Count it */
- }
- }
-}
-
-
-/* C K S C R E E N -- Screen display function */
-
-/*
- ckscreen(f,c,n,s)
- f - argument descriptor
- c - a character or small integer
- n - a long integer
- s - a string.
-
- and global fdispla = SET FILE DISPLAY value:
-
- XYFD_N = NONE
- XYFD_R = SERIAL: Dots, etc, works on any terminal, even hardcopy.
- XYFD_S = CRT: Works on any CRT, writes over current line.
- XYFD_C = FULLSCREEN: Requires terminal-dependent screen control.
- XYFD_B = BRIEF: Like SERIAL but only filename & completion status.
- XYFD_G = GUI; Windows GUI, same behavior as FULLSCREEN
-*/
-VOID
-#ifdef CK_ANSIC
-ckscreen(int f, char c,CK_OFF_T n,char *s)
-#else
-ckscreen(f,c,n,s) int f; char c; CK_OFF_T n; char *s;
-#endif /* CK_ANSIC */
-/* screen */ {
- char buf[80];
- int len; /* Length of string */
-#ifdef UNIX
-#ifndef NOJC
- int obg;
-_PROTOTYP( VOID conbgt, (int) );
-#endif /* NOJC */
-#endif /* UNIX */
- int ftp = 0;
-
- ftp = (what & W_FTP) ? 1 : 0; /* FTP or Kermit? */
-
- if (!local && !ftp) /* In remote mode - don't do this */
- return;
-
- if (!s) s = "";
-
- if (!fxd_inited) /* Initialize if necessary */
- fxdinit(fdispla);
-
-#ifdef UNIX
-#ifndef NOJC
- obg = backgrd; /* Previous background status */
- conbgt(1); /* See if running in background */
- if (!backgrd && obg) { /* Just came into foreground? */
- concb((char)escape); /* Put console back in CBREAK mode */
- setint(); /* Restore interrupts */
- }
-#endif /* NOJC */
-#endif /* UNIX */
-
- if ((f != SCR_WM) && (f != SCR_EM)) /* Always update warnings & errors */
- if (!displa ||
- (backgrd && bgset) ||
- fdispla == XYFD_N ||
- (server && !srvdis)
- )
- return;
-
-#ifdef VMS
- if (f == SCR_FN) /* VMS - shorten the name */
- s = zrelname(s,zgtdir());
-#endif /* VMS */
-
- if (dest == DEST_S) /* SET DESTINATION SCREEN */
- return; /* would interfere... */
-
-#ifdef KUI
- if (fdispla == XYFD_G) { /* If gui display selected */
- screeng(f,c,n,s); /* call the gui version */
- return;
- }
-#endif /* KUI */
-#ifdef CK_CURSES
- if (fdispla == XYFD_C) { /* If fullscreen display selected */
- screenc(f,c,n,s); /* call the fullscreen version */
- return;
- }
-#endif /* CK_CURSES */
-
- len = (int)strlen(s); /* Length of string */
-
- switch (f) { /* Handle our function code */
- case SCR_FN: /* Filename */
- if (fdispla == XYFD_B) {
-#ifdef NEWFTP
- if (ftp)
- printf(" %s %s", what & W_SEND ? "PUT" : "GET", s);
- else
-#endif /* NEWFTP */
- printf(" %s %s", what & W_SEND ? "SEND" : "RECV", s);
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- return;
- }
-#ifdef MAC
- conoll(""); conol(s); conoc(SP); hpos = len + 1;
-#else
- ckstrncpy(fbuf,s,80);
- abuf[0] = a2buf[0] = NUL;
- newdpy = 1; /* New file so refresh display */
-#endif /* MAC */
- return;
-
- case SCR_AN: /* As-name */
- if (fdispla == XYFD_B) {
-#ifdef COMMENT
- printf("(as %s) ",s);
-#endif /* COMMENT */
- return;
- }
-#ifdef MAC
- if (hpos + len > 75) { conoll(""); hpos = 0; }
- conol("=> "); conol(s);
- if ((hpos += (len + 3)) > 78) { conoll(""); hpos = 0; }
-#else
- if (abuf[0]) {
- ckstrncpy(a2buf,s,80);
- } else {
- ckstrncpy(abuf,s,80);
- }
-#endif /* MAC */
- return;
-
- case SCR_FS: /* File-size */
- if (fdispla == XYFD_B) {
- printf(" (%s) (%s byte%s)",
-#ifdef NOICP
- (binary ? "binary" : "text")
-#else
- gfmode(binary,0)
-#endif /* NOICP */
- , ckfstoa(n), n == 1 ? "" : "s");
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- return;
- }
-#ifdef MAC
- sprintf(buf,", Size: %s",ckfstoa(n)); conoll(buf); hpos = 0;
-#endif /* MAC */
- return;
-
- case SCR_XD: /* X-packet data */
- if (fdispla == XYFD_B)
- return;
-#ifdef MAC
- conoll(""); conoll(s); hpos = 0;
-#else
- ckstrncpy(fbuf,s,80);
- abuf[0] = a2buf[0] = NUL;
-#endif /* MAC */
- return;
-
- case SCR_ST: /* File status */
- switch (c) {
- case ST_OK: /* Transferred OK */
- showpkt('Z'); /* Update numbers one last time */
- if (fdispla == XYFD_B) {
-#ifdef GFTIMER
- if (fpxfsecs)
- printf(": OK (%0.3f sec, %ld cps)",fpxfsecs,
- (long)((CKFLOAT)ffc / fpxfsecs));
-#else
- if (xfsecs)
- printf(": OK (%d sec, %ld cps)",xfsecs,ffc/xfsecs);
-#endif /* GFTIMER */
- printf("\n");
- return;
- }
- if ((hpos += 5) > 78) conoll(""); /* Wrap screen line. */
- conoll(" [OK]"); hpos = 0; /* Print OK message. */
- if (fdispla == XYFD_S) { /* We didn't show Z packet when */
- conoc('Z'); /* it came, so show it now. */
- hpos = 1;
- }
- return;
-
- case ST_DISC: /* Discarded */
- if (fdispla == XYFD_B) {
- printf(": DISCARDED\n");
- return;
- }
- if ((hpos += 12) > 78) conoll("");
- conoll(" [discarded]"); hpos = 0;
- return;
-
- case ST_INT: /* Interrupted */
- if (fdispla == XYFD_B) {
- printf(": INTERRUPTED\n");
- return;
- }
- if ((hpos += 14) > 78) conoll("");
- conoll(" [interrupted]"); hpos = 0;
- return;
-
- case ST_SIM:
- if (fdispla == XYFD_B) {
- if (n == SKP_XNX)
- printf(": WOULD BE TRANSFERRED (New file)\n");
- else if (n == SKP_XUP)
- printf(": WOULD BE TRANSFERRED (Remote file older)\n");
- else if (n == SKP_SIM)
- printf(": WOULD BE TRANSFERRED\n");
- else if (n > 0 && n < nskreason)
- printf(": SKIPPED (%s)\n",skreason[n]);
- else
- printf(": SKIPPED\n");
- return;
- } else if (fdispla == XYFD_S) {
- if (fdispla == XYFD_S && fbuf[0]) { /* CRT display */
- conoll(""); /* New line */
- if (what & W_SEND) conol("Would Send: "); /* Action */
- else if (what & W_RECV) conol("Would Receive: ");
- conol(fbuf);
- if (*abuf) conol(" => "); conol(abuf); /* Names */
- if (*a2buf) conol(" => "); conol(a2buf); /* Names */
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- }
- conoll(" [simulated]");
- return;
- }
- if ((hpos += 10) > 78) conoll("");
- conol(" [simulated]"); hpos = 0;
- return;
-
- case ST_SKIP: /* Skipped */
- if (fdispla == XYFD_B) {
- if (n == SKP_XNX)
- printf(": WOULD BE TRANSFERRED (New file)\n");
- else if (n == SKP_XUP)
- printf(": WOULD BE TRANSFERRED (Remote file older)\n");
- else if (n == SKP_SIM)
- printf(": WOULD BE TRANSFERRED\n");
- else if (n > 0 && n < nskreason)
- printf(": SKIPPED (%s)\n",skreason[n]);
- else
- printf(": SKIPPED\n");
- return;
- } else if (fdispla == XYFD_S) {
- if (fdispla == XYFD_S && fbuf[0]) { /* CRT display */
- conoll(""); /* New line */
- if (what & W_SEND) conol("Sending: "); /* Action */
- else if (what & W_RECV) conol("Receiving: ");
- conol(fbuf);
- if (*abuf) conol(" => "); conol(abuf); /* Names */
- if (*a2buf) conol(" => "); conol(a2buf); /* Names */
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- }
- conoll(" [skipped]");
- return;
- }
- if ((hpos += 10) > 78) conoll("");
- conol(" "); conol(fbuf);
- conoll(" [skipped]"); hpos = 0;
- return;
-
- case ST_ERR: /* Error */
- if (fdispla == XYFD_B) {
- printf(": ERROR: %s\n",s);
- return;
- }
- conoll("");
- conol("Error: "); conoll(s); hpos = 0;
- return;
-
- case ST_MSG: /* Message */
-#ifdef NEWFTP
- if (fdispla == XYFD_B) {
- if (ftp && ftp_deb)
- printf(": MESSAGE: %s\n",s);
- return;
- }
-#endif /* NEWFTP */
- conoll("");
- conol("Message: ");
- conoll(s);
- hpos = 0;
- return;
-
- case ST_REFU: /* Refused */
- if (fdispla == XYFD_B) {
- printf(": REFUSED\n");
- return;
- } else if (fdispla == XYFD_S) {
- if (fdispla == XYFD_S && fbuf[0]) { /* CRT display */
- conoll(""); /* New line */
- if (what & W_SEND) conol("Sending: "); /* Action */
- else if (what & W_RECV) conol("Receiving: ");
- conol(fbuf);
- if (*abuf) conol(" => "); conol(abuf); /* Names */
- if (*a2buf) conol(" => "); conol(a2buf); /* Names */
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- conoll("");
- }
- conol("Refused: "); conoll(s);
- return;
- }
- conoll("");
- conol("Refused: "); conoll(s); hpos = 0;
- return;
-
- case ST_INC: /* Incomplete */
- if (fdispla == XYFD_B) {
- printf(": INCOMPLETE\n");
- return;
- }
- if ((hpos += 12) > 78) conoll("");
- conoll(" [incomplete]"); hpos = 0;
- return;
-
- default:
- conoll("*** screen() called with bad status ***");
- hpos = 0;
- return;
- }
-
-#ifdef MAC
- case SCR_PN: /* Packet number */
- if (fdispla == XYFD_B) {
- return;
- }
- ckmakmsg(buf,80,s,": ",ckltoa(n),NULL);
- conol(buf); hpos += (int)strlen(buf); return;
-#endif /* MAC */
-
- case SCR_PT: /* Packet type or pseudotype */
- if (fdispla == XYFD_B)
- return;
- if (c == 'Y') return; /* Don't bother with ACKs */
- if (c == 'D') { /* In data transfer phase, */
- showpkt(NUL); /* show progress. */
- return;
- }
-#ifndef AMIGA
- if (hpos++ > 77) { /* If near right margin, */
- conoll(""); /* Start new line */
- hpos = 0; /* and reset counter. */
- }
-#endif /* AMIGA */
- if (c == 'Z' && fdispla == XYFD_S)
- return;
- else
- conoc(c); /* Display the packet type. */
-#ifdef AMIGA
- if (c == 'G') conoll(""); /* New line after G packets */
-#endif /* AMIGA */
- return;
-
- case SCR_TC: /* Transaction complete */
- if (xfrbel) bleep(BP_NOTE);
- if (fdispla == XYFD_B) { /* Brief display... */
- if (filcnt > 1) {
- long fx;
- fx = filcnt - filrej;
- printf(" SUMMARY: %ld file%s", fx, ((fx == 1) ? "" : "s"));
- printf(", %s byte%s", ckfstoa(tfc), ((tfc == 1) ? "" : "s"));
-#ifdef GFTIMER
- printf(", %0.3f sec, %ld cps", fptsecs, tfcps);
-#else
- printf(", %ld sec, %ld cps", tsecs, tfcps);
-#endif /* GFTIMER */
- printf(".\n");
- }
- } else {
- conoll("");
- }
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- return;
-
- case SCR_EM: /* Error message */
- if (fdispla == XYFD_B) {
- printf(" ERROR: %s\n",s);
- return;
- }
- conoll(""); conoc('?'); conoll(s); hpos = 0; return;
-
- case SCR_WM: /* Warning message */
- if (fdispla == XYFD_B) {
- printf(" WARNING: %s\n",s);
- return;
- }
- conoll(""); conoll(s); hpos = 0; return;
-
- case SCR_MS: /* Message from other Kermit */
- if (fdispla == XYFD_B) {
- printf(" MESSAGE: %s\n",s);
- return;
- }
- conoll(""); conoll(s); hpos = 0; return;
-
- case SCR_TU: /* Undelimited text */
- if (fdispla == XYFD_B)
- return;
- if ((hpos += len) > 77) { conoll(""); hpos = len; }
- conol(s); return;
-
- case SCR_TN: /* Text delimited at beginning */
- if (fdispla == XYFD_B)
- return;
- conoll(""); conol(s); hpos = len; return;
-
- case SCR_TZ: /* Text delimited at end */
- if (fdispla == XYFD_B)
- return;
- if ((hpos += len) > 77) { conoll(""); hpos = len; }
- conoll(s); return;
-
- case SCR_QE: /* Quantity equals */
- if (fdispla == XYFD_B)
- return;
- ckmakmsg(buf,80,s,": ",ckltoa(n),NULL);
- conoll(buf); hpos = 0; return;
-
- case SCR_CW: /* Close fullscreen window */
- return; /* No window to close */
-
- case SCR_CD:
- return;
-
- default:
- conoll("*** screen() called with bad object ***");
- hpos = 0;
- return;
- }
-}
-#endif /* NODISPLAY */
-
-/* E R M S G -- Nonfatal error message */
-
-/* Should be used only for printing the message text from an Error packet. */
-
-VOID
-ermsg(msg) char *msg; { /* Print error message */
- debug(F110,"ermsg",msg,0);
- if (local)
- xxscreen(SCR_EM,0,0L,msg);
- tlog(F110,"Protocol Error:",msg,0L);
-}
-#endif /* NOXFER */
-
-VOID
-setseslog(x) int x; {
- seslog = x;
-#ifdef KUI
- KuiSetProperty(KUI_TERM_CAPTURE,x,0);
-#endif /* KUI */
-}
-
-VOID
-doclean(fc) int fc; { /* General cleanup */
-#ifdef OS2ORUNIX
- extern int ttyfd;
-#endif /* OS2ORUNIX */
- extern int keep;
- extern int exithangup;
-#ifndef NOXFER
- extern char filnam[];
-#endif /* NOXFER */
-#ifndef NOICP
- int x;
-
- if (fc > 0)
- dostop(); /* Stop all command files and end macros */
-#endif /* NOICP */
-
-#ifndef NOXFER
- if (pktlog) {
- *pktfil = '\0';
- pktlog = 0;
- zclose(ZPFILE);
- }
-#endif /* NOXFER */
- if (seslog) {
- *sesfil = '\0';
- setseslog(0);
- zclose(ZSFILE);
- }
-#ifdef TLOG
- if (tralog) {
- tlog(F100,"Transaction Log Closed","",0L);
- *trafil = '\0';
- tralog = 0;
- zclose(ZTFILE);
- }
-#endif /* TLOG */
-
- debug(F100,"doclean calling dologend","",0);
- dologend(); /* End current log record if any */
-#ifdef COMMENT
- if (dialog) { /* If connection log open */
- dialog = 0;
- *diafil = '\0'; /* close it. */
- zclose(ZDIFIL);
- }
-#endif /* COMMENT */
-
-#ifndef NOICP
-#ifndef NOSPL
- zclose(ZRFILE); /* READ and WRITE files, if any. */
- zclose(ZWFILE);
-#ifndef NOXFER
- zclose(ZIFILE); /* And other files too */
- x = chkfn(ZOFILE); /* Download in progress? */
- debug(F111,"doclean chkfn ZOFILE",filnam,x);
- debug(F111,"doclean keep","",keep);
- zclose(ZOFILE); /* Close output file */
- if (x > 0 && !keep) { /* If it was being downloaded */
- if (filnam[0])
- x = zdelet(filnam); /* Delete if INCOMPLETE = DISCARD */
- debug(F111,"doclean download filename",filnam,x);
- }
-#endif /* NOXFER */
- zclose(ZSYSFN);
- zclose(ZMFILE);
-
- if (fc < 1) { /* RESETing, not EXITing */
-#ifdef DEBUG
- if (deblog) { /* Close the debug log. */
- *debfil = '\0';
- deblog = 0;
- zclose(ZDFILE);
- }
-#endif /* DEBUG */
- return;
- }
-#endif /* NOSPL */
-#endif /* NOICP */
-
-#ifndef NOLOCAL
- debug(F101,"doclean exithangup","",exithangup);
- if (local && exithangup) { /* Close communication connection */
- extern int haslock;
- int x;
-
- x = ttchk();
- debug(F101,"doclean ttchk()","",x);
-#ifdef OS2ORUNIX
- debug(F101,"doclean ttyfd","",ttyfd);
-#endif /* OS2ORUNIX */
- if (x >= 0
-#ifdef OS2
- || ttyfd != -1
-#else
-#ifdef UNIX
- || haslock /* Make sure we get lockfile! */
- || (!network && ttyfd > -1)
-#endif /* UNIX */
-#endif /* OS2 */
- ) {
- extern int wasclosed, whyclosed;
- debug(F100,"doclean hanging up and closing","",0);
- if (msgflg) {
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- printf("Closing %s...",ttname);
- }
-#ifndef NODIAL
- mdmhup(); /* Hangup the modem??? */
-#endif /* NODIAL */
- ttclos(0); /* Close external line, if any */
- if (msgflg) {
- printf("OK\n");
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- }
- if (wasclosed) {
- whyclosed = WC_CLOS;
-#ifndef NOSPL
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_close",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- wasclosed = 0;
- /* printf("ON_CLOSE DOCLEAN\n"); */
- *(mactab[k].kwd) = NUL; /* See comment below */
- if (dodo(k,ckitoa(whyclosed),0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
-#endif /* NOSPL */
- wasclosed = 0;
- }
- }
- ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty */
- local = dfloc; /* And default remote/local status */
- }
-#ifdef DEBUG
- else if (local) debug(F100,"doclean hangup/close skipped","",0);
-#endif /* DEBUG */
-#endif /* NOLOCAL */
-
-#ifdef NEWFTP
- ftpbye(); /* If FTP connection open, close it */
-#endif /* NEWFTP */
-
-#ifdef IKSD
- if (inserver)
- ttclos(0); /* If IKSD, close socket */
-#endif /* IKSD */
-
-#ifndef NOSPL
-/*
- If a macro named "on_exit" is defined, execute it. Also remove it from the
- macro table, in case its definition includes an EXIT or QUIT command, which
- would cause much recursion and would prevent the program from ever actually
- EXITing.
-*/
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- char * cmd = "on_exit"; /* MSVC 2.x compiler error */
- k = mlook(mactab,cmd,nmac); /* Look up "on_exit" */
- if (k >= 0) { /* If found, */
-#ifdef COMMENT
- /* This makes a mess if ON_EXIT itself executes macros */
- *(mactab[k].kwd) = NUL; /* poke its name from the table, */
-#else
- /* Replace the keyword with something that doesn't wreck the */
- /* order of the keyword table */
- ckstrncpy(mactab[k].kwd,"on_exxx",8);
-#endif /* COMMENT */
- if (dodo(k,"",0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
-#endif /* NOSPL */
-/*
- Put console terminal back to normal. This is done here because the
- ON_EXIT macro calls the parser, which meddles with console terminal modes.
-*/
- conres(); /* Restore console terminal. */
-
-#ifdef COMMENT
-/* Should be no need for this, and maybe it's screwing things up? */
- connoi(); /* Turn off console interrupt traps */
-#endif /* COMMENT */
-
- /* Delete the Startup File if we are supposed to. */
-#ifndef NOICP
- {
- extern int DeleteStartupFile;
- debug(F111,"doclean DeleteStartupFile",cmdfil,DeleteStartupFile);
- if (DeleteStartupFile) {
- int rc = zdelet(cmdfil);
- debug(F111,"doclean zdelet",cmdfil,rc);
- }
- }
-#endif /* NOICP */
- syscleanup(); /* System-dependent cleanup, last */
-}
-
-/* D O E X I T -- Exit from the program. */
-
-/*
- First arg is general, system-independent symbol: GOOD_EXIT or BAD_EXIT.
- If second arg is -1, take 1st arg literally.
- If second arg is not -1, work it into the exit code.
-*/
-VOID
-doexit(exitstat,code) int exitstat, code; {
- extern int x_logged, quitting;
-#ifdef OS2
- extern int display_demo;
- extern int SysInited;
-#endif /* OS2 */
-#ifdef CK_KERBEROS
-#ifdef KRB4
- extern int krb4_autodel;
-#endif /* KRB4 */
-#ifdef KRB5
- extern int krb5_autodel;
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef VMS
- char envstr[64];
- static $DESCRIPTOR(symnam,"CKERMIT_STATUS");
- static struct dsc$descriptor_s symval;
-#endif /* VMS */
- int i;
-
-#ifdef DEBUG
-#ifdef USE_LUCACHE
- extern long lucalls, luhits, xxhits, luloop;
- extern int lusize;
-#endif /* USE_LUCACHE */
-#ifndef NOSPL
- extern int cmdstats[];
-#endif /* NOSPL */
-
- quitting++;
-
-#ifdef OS2
- if ( !SysInited ) {
- static int initing = 0;
- if ( initing )
- exit(253);
- initing = 1;
- sysinit();
- }
-#endif /* OS2 */
-
- if (deblog) {
-#ifdef USE_LUCACHE
- debug(F101,"lookup cache size","",lusize);
- debug(F101,"lookup calls ....","",lucalls);
- debug(F101,"lookup cache hits","",luhits);
- debug(F101,"lookup start hits","",xxhits);
- debug(F101,"lookup loop iterations","",luloop);
-#endif /* USE_LUCACHE */
-#ifndef NOSPL
- for (i = 0; i < 256; i++) {
- if (cmdstats[i])
- debug(F111,"CMSTATS",ckitoa(i),cmdstats[i]);
- }
-#endif /* NOSPL */
- debug(F101,"doexit exitstat","",exitstat);
- debug(F101,"doexit code","",code);
- debug(F101,"doexit xitsta","",xitsta);
- }
-#endif /* DEBUG */
-
-#ifdef CK_KERBEROS
- /* If we are automatically destroying Kerberos credentials on Exit */
- /* do it now. */
-#ifdef KRB4
- if (krb4_autodel == KRB_DEL_EX) {
- extern struct krb_op_data krb_op;
- krb_op.version = 4;
- krb_op.cache = NULL;
- ck_krb4_destroy(&krb_op);
- }
-#endif /* KRB4 */
-#ifdef KRB5
- if (krb5_autodel == KRB_DEL_EX) {
- extern struct krb_op_data krb_op;
- extern char * krb5_d_cc;
- krb_op.version = 5;
- krb_op.cache = krb5_d_cc;
- ck_krb5_destroy(&krb_op);
- }
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifndef NOLOCAL
-#ifdef OS2
- if (SysInited)
- {
-#ifdef DCMDBUF
- extern struct cmdptr *cmdstk;
-#else
- extern struct cmdptr cmdstk[];
-#endif /* DCMDBUF */
- extern int tt_status[];
- extern int vmode;
-
- /* If there is a demo screen to be displayed, display it */
- if (display_demo) {
- demoscrn(VCMD);
- display_demo = 0;
- }
-#ifndef KUI
- /* This is going to be hideous. If we have a status line */
- /* in the command window turn it off before we exit. */
-
- if ( tt_status[VCMD] && vmode == VCMD ) {
- domac("_clear_statusline","set command statusline off",
- cmdstk[cmdlvl].ccflgs);
- delmac("_clear_statusline",1);
- RequestScreenMutex(-1);
- VscrnIsDirty(vmode);
- ReleaseScreenMutex();
- while ( IsVscrnDirty(vmode) )
- msleep(200);
- RequestScreenMutex(-1);
- ReleaseScreenMutex();
- }
-#endif /* KUI */
- DialerSend(OPT_KERMIT_EXIT,exitstat);
-#ifndef KUI
- debug(F100,"doexit about to msleep","",0);
-
- if ( isWin95() )
- msleep(250);
-#endif /* KUI */
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && x_logged) {
-#ifndef NOSPL
-/*
- If a macro named "on_logout" is defined, execute it. Also remove it from the
- macro table, in case its definition includes an EXIT or QUIT command, which
- would cause much recursion and would prevent the program from ever actually
- EXITing.
-*/
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- char * cmd = "on_logout"; /* MSVC 2.x compiler error */
- k = mlook(mactab,cmd,nmac); /* Look up "on_logout" */
- if (k >= 0) { /* If found, */
- *(mactab[k].kwd) = NUL; /* poke its name from the table, */
- if (dodo(k,"",0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
-#endif /* NOSPL */
- zvlogout();
- }
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-
- debug(F100,"doexit about to doclean","",0);
- doclean(1); /* Clean up most things */
-
-#ifdef VMS
- if (code == -1)
- code = 0; /* Since we set two different items */
- sprintf(envstr,"%d", exitstat | code); /* SAFE */
- symval.dsc$w_length = (int)strlen(envstr);
- symval.dsc$a_pointer = envstr;
- symval.dsc$b_class = DSC$K_CLASS_S;
- symval.dsc$b_dtype = DSC$K_DTYPE_T;
- i = 2; /* Store in global table */
-#ifdef COMMENT /* Martin Zinser */
- LIB$SET_SYMBOL(&symnam, &symval, &i);
-#else
- lib$set_symbol(&symnam, &symval, &i);
-#endif /* COMMENT */
- if (exitstat == BAD_EXIT)
- exitstat = SS$_ABORT | STS$M_INHIB_MSG;
- if (exitstat == GOOD_EXIT)
- exitstat = SS$_NORMAL | STS$M_INHIB_MSG;
-#else /* Not VMS */
- if (code != -1) /* Take 1st arg literally */
- exitstat |= code;
-#endif /* VMS */
-
-#ifdef IKSD
-#ifdef IKSDB
- debug(F101,"doexit ikdbopen","",ikdbopen);
- if (ikdbopen && dbfp) { /* If IKSD database open */
- int x;
- x = freeslot(mydbslot); /* Free our slot... */
- debug(F101,"doexit freeslot","",x);
- fclose(dbfp); /* and close it. */
- }
-#endif /* IKSDB */
-#endif /* IKSD */
-
-/* We have put this off till the very last moment... */
-
-#ifdef DEBUG
- if (deblog) { /* Close the debug log. */
- debug(F101,"C-Kermit EXIT status","",exitstat);
- *debfil = '\0';
- deblog = 0;
- zclose(ZDFILE);
- }
-#endif /* DEBUG */
-
-#ifdef OS2
- _exit(exitstat); /* Exit from C-Kermit (no matter what) */
-#else /* OS2 */
- exit(exitstat); /* Exit from C-Kermit */
-#endif /* OS2 */
-}
-
-VOID
-bgchk() { /* Check background status */
- if (bgset < 0) { /* They didn't type SET BACKGROUND */
-#ifdef VMS /* Set prompt flag based on */
- pflag = !batch; /* what we detected at startup. */
-#else
- pflag = !backgrd;
-#endif /* VMS */
- } else { /* Otherwise SET BACKGROUND value */
- pflag = (bgset == 0 ? 1 : 0);
- }
-
-#ifndef NOICP
- /* Message flag on only if at top level, pflag is on, and QUIET is OFF */
- if (!xcmdsrc)
- msgflg = (pflag == 0) ? 0 : !quiet;
- else msgflg = 0;
-#else
- msgflg = 0;
-#endif /* NOICP */
-}
-
-/* Set console interrupts */
-
-VOID
-setint() { /* According to SET COMMAND INTERRUP */
- int x = 0;
- if (cmdint) x |= 1;
- if (xsuspend) x |= 2;
- debug(F101,"setint","",x);
-
- switch (x) { /* Set the desired combination */
- case 0: connoi(); break; /* No interrupts */
- case 1: conint(trap,SIG_IGN); break;
- case 2: conint(SIG_IGN,stptrap); break;
- case 3: conint(trap,stptrap); break;
- }
- bgchk(); /* Check background status */
-}
-
-#ifdef DEBUG
-/* D E B U G -- Enter a record in the debugging log */
-
-/*
- Call with a format, two strings, and a number:
- f - Format, a bit string in range 0-7.
- If bit x is on, then argument number x is printed.
- s1 - String, argument number 1. If selected, printed as is.
- s2 - String, argument number 2. If selected, printed in brackets.
- n - Long int, argument 3. If selected, printed preceded by equals sign.
-
- f=0 is special: print s1,s2, and interpret n as a char.
-
- f=F011 (3) is also special; in this case s2 is interpeted as a counted
- string that might contain NULs. n is the length. If n is negative, this
- means the string has been truncated and ".." should be printed after the
- first n bytes. NUL and LF bytes are printed as "<NUL>" and "<LF>".
-
- Globals:
- deblog: nonzero if debug log open.
- debok: nonzero if ok to write entries.
-*/
-/*
- WARNING: Don't change DEBUFL without changing sprintf() formats below,
- accordingly.
-*/
-#define DBUFL 4000
-/*
- WARNING: This routine is not thread-safe, especially when Kermit is
- executing on multiple CPUs -- as different threads write to the same
- static buffer, the debug statements are all interleaved. To be fixed
- later...
-*/
-static char *dbptr = (char *)0;
-
-int
-#ifdef CK_ANSIC
-dodebug(int f, char *s1, char *s2, CK_OFF_T n)
-#else
-dodebug(f,s1,s2,n) int f; char *s1, *s2; CK_OFF_T n;
-#endif /* CK_ANSIC */
-/* dodebug */ {
- char *sp;
- int len1, len2;
- extern int debtim;
-#ifdef OS2
- extern int SysInited;
-#endif /* OS2 */
-
- if (!deblog || !debok)
- return(0);
-
-#ifdef COMMENT
- /* expensive... */
- if (!chkfn(ZDFILE)) /* Debug log not open, don't. */
- return(0);
-#endif /* COMMENT */
- if (!dbptr) { /* Allocate memory buffer */
- dbptr = malloc(DBUFL+4); /* This only happens once */
- if (!dbptr) {
- zclose(ZDFILE);
- return(0);
- }
- }
-/*
- This prevents infinite recursion in case we accidentally put a debug()
- call in this routine, or call another routine that contains debug() calls.
- From this point on, all returns from this return must be via goto xdebug,
- which sets deblog back to 1.
-*/
-#ifdef OS2
- if (SysInited) {
- if (RequestDebugMutex(30000))
- goto xdebug;
- }
-#else /* OS2 */
- deblog = 0; /* Prevent infinite recursion */
-#endif /* OS2 */
-
- if (debtim) { /* Timestamp */
- char *tb, tsbuf[48];
- ztime(&tb);
- ckstrncpy(tsbuf,tb,32);
- if (ztmsec > -1L) {
- sprintf(tsbuf+19,".%03ld ",ztmsec); /* SAFE */
- } else {
- tsbuf[19] = ':';
- tsbuf[20] = SP;
- tsbuf[21] = NUL;
- }
- zsout(ZDFILE,tsbuf+11);
- }
- if (!s1) s1="(NULL)";
- if (!s2) s2="(NULL)";
-
- len1 = strlen(s1);
- len2 = strlen(s2);
-
-#ifdef COMMENT
-/*
- This should work, but it doesn't.
- So instead we'll cope with overflow via sprintf formats.
- N.B.: UNFORTUNATELY, this means we have to put constants in the
- sprintf formats.
-*/
- if (f != F011 && (!f || (f & 6))) { /* String argument(s) included? */
- x = (int) strlen(s1) + (int) strlen(s2) + 18;
- if (x > dbufl) { /* Longer than buffer? */
- if (dbptr) /* Yes, free previous buffer */
- free(dbptr);
- dbptr = (char *) malloc(x + 2); /* Allocate a new one */
- if (!dbptr) {
- zsoutl(ZDFILE,"DEBUG: Memory allocation failure");
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- } else {
- dbufl = x;
- sprintf(dbptr,"DEBUG: Buffer expanded to %d\n", x + 18);
- zsoutl(ZDFILE,dbptr);
- }
- }
- }
-#endif /* COMMENT */
-
-#ifdef COMMENT
-/* The aforementioned sprintf() formats were like this: */
- if (n > 31 && n < 127)
- sprintf(sp,"%.100s%.2000s:%c\n",s1,s2,(CHAR) n);
- else if (n < 32 || n == 127)
- sprintf(sp,"%.100s%.2000s:^%c\n",s1,s2,(CHAR) ((n+64) & 0x7F));
- else if (n > 127 && n < 160)
- sprintf(sp,"%.100s%.2000s:~^%c\n",s1,s2,(CHAR)((n-64) & 0x7F));
- else if (n > 159 && n < 256)
- sprintf(sp,"%.100s%.2000s:~%c\n",s1,s2,(CHAR) (n & 0x7F));
- else sprintf(sp,"%.100s%.2000s:%ld\n",s1,s2,n);
-/*
- But, naturally, it turns out these are not portable either, so now
- we do the stupidest possible thing.
-*/
-#endif /* COMMENT */
-
-#ifdef BIGBUFOK
-/* Need to accept longer strings when debugging authenticated connections */
- if (f == F010) {
- if (len2 + 2 >= DBUFL) s2 = "(string too long)";
- } else if (f != F011 && f != F100) {
- if (len1 > 100) s1 = "(string too long)";
- if (len2 + 101 >= DBUFL) s2 = "(string too long)";
- }
-#else
- if (f != F011) {
- if (len1 > 100) s1 = "(string too long)";
- if (len2 + 101 >= DBUFL) s2 = "(string too long)";
- }
-#endif /* BIGBUFOK */
-
- sp = dbptr;
-
- switch (f) { /* Write log record according to format. */
- case F000: /* 0 = print both strings, and n as a char. */
- if (len2 > 0) {
- if ((n > 31 && n < 127) || (n > 159 && n < 256))
- sprintf(sp,"%s[%s]=%c\n",s1,s2,(CHAR) n);
- else if (n < 32 || n == 127)
- sprintf(sp,"%s[%s]=^%c\n",s1,s2,(CHAR) ((n+64) & 0x7F));
- else if (n > 127 && n < 160)
- sprintf(sp,"%s[%s]=~^%c\n",s1,s2,(CHAR)((n-64) & 0x7F));
- else sprintf(sp,"%s[%s]=0x%lX\n",s1,s2,(long)n);
- } else {
- if ((n > 31 && n < 127) || (n > 159 && n < 256))
- sprintf(sp,"%s=%c\n",s1,(CHAR) n);
- else if (n < 32 || n == 127)
- sprintf(sp,"%s=^%c\n",s1,(CHAR) ((n+64) & 0x7F));
- else if (n > 127 && n < 160)
- sprintf(sp,"%s=~^%c\n",s1,(CHAR)((n-64) & 0x7F));
- else sprintf(sp,"%s=0x%lX\n",s1,(long)n);
- }
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
-
- case F001: /* 1, "=n" */
-#ifdef COMMENT
- /* This was never used */
- sprintf(sp,"=%s\n",ckfstoa(n));
-#else
- /* Like F111, but shows number n in hex */
- ckmakxmsg(sp,DBUFL,
- s1,
- (*s1 ? ":" : ""),
- s2,
- (*s2 ? ":" : ""),
- ckltox(n),
- "\n",
- NULL,NULL,NULL,NULL,NULL,NULL
- );
-#endif /* COMMENT */
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
-
-/*
- This one was never used so (October 2000) we now use it like F011,
- except in this case we treat s2 as NUL terminated.
-*/
- case F010:
- n = -debxlen;
-/*
- This one treats n as the length of the string s2, which may contain NULs.
- It's good for logging NUL-bearing data in the debug log.
-*/
- case F011: {
- int i, j, contd = 0;
- char * p = s2, *pbuf = NULL; /* p = source pointer */
- int m; /* pbuf = destination pointer */
-
- if (f == F011) {
- if (n < 0) { /* n = size of source */
- n = 0 - n; /* Negative means to add "..." */
- contd = 1;
- }
- } else {
- int x, flag = 0;
- x = strlen(s2);
- if (n < 0) {
- flag = 1;
- n = 0 - n;
- }
- if (x < n)
- n = x;
- }
- if (n == 0) /* 0 means do nothing */
- goto xdebug;
- m = DBUFL - 8; /* Get size for interpreted part */
- if (n > m) /* Ensure requested size not too big */
- n = m;
- pbuf = dbptr; /* Construction pointer */
- i = 0;
- pbuf[i++] = '['; /* Interpret the string into it */
- for (j = 0; j < n && i < m-4; p++,j++) { /* char by char... */
- if (*p == LF) {
- if (i >= m-4)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'L';
- pbuf[i++] = 'F';
- pbuf[i++] = '>';
- continue;
- } else if (*p == CR) {
- if (i >= m-4)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'C';
- pbuf[i++] = 'R';
- pbuf[i++] = '>';
- continue;
- } else if (*p == HT) {
- if (i >= m-5)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'T';
- pbuf[i++] = 'A';
- pbuf[i++] = 'B';
- pbuf[i++] = '>';
- continue;
- } else if (*p) {
- pbuf[i++] = *p;
- continue;
- } else {
- if (i >= m-5)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'N';
- pbuf[i++] = 'U';
- pbuf[i++] = 'L';
- pbuf[i++] = '>';
- continue;
- }
- }
- if (i < m-2 && (*p || contd)) {
- pbuf[i++] = '.';
- pbuf[i++] = '.';
- }
- pbuf[i++] = ']';
- pbuf[i] = NUL;
- if (zsout(ZDFILE,s1) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
- if (zsoutl(ZDFILE,pbuf) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",s1,pbuf);
- }
-#endif /* CKSYSLOG */
- }
- break;
-
- case F100: /* 4, "s1" */
- if (zsoutl(ZDFILE,s1) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",s1,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- case F101: /* 5, "s1=n" */
- sprintf(sp,"%s=%s\n",s1,ckfstoa(n));
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- case F110: /* 6, "s1[s2]" */
- sprintf(sp,"%s[%s]\n",s1,s2);
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- case F111: /* 7, "s1[s2]=n" */
- sprintf(sp,"%s[%s]=%s\n",s1,s2,ckfstoa(n));
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- default:
- sprintf(sp,"\n?Invalid format for debug() - %d\n",f);
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- }
- xdebug: /* Common exit point */
-#ifdef OS2
- if (SysInited)
- ReleaseDebugMutex();
-#else /* OS2 */
- deblog = 1; /* Restore this */
-#endif /* OS2 */
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-dohexdump(CHAR *msg, CHAR *st, int cnt)
-#else
-dohexdump(msg,st,cnt) CHAR *msg; CHAR *st; int cnt;
-#endif /* CK_ANSIC */
-/* dohexdump */ {
- int i = 0, j = 0, k = 0;
- char tmp[8];
-#ifdef OS2
- extern int SysInited;
-#endif /* OS2 */
-
- if (!deblog) return(0); /* If no debug log, don't. */
- if (!dbptr) { /* Allocate memory buffer */
- dbptr = malloc(DBUFL+1); /* This only happens once */
- if (!dbptr) {
- deblog = 0;
- zclose(ZDFILE);
- return(0);
- }
- }
-
-#ifdef OS2
- if (SysInited) {
- if (RequestDebugMutex(30000))
- goto xdebug;
- }
-#else /* OS2 */
- deblog = 0; /* Prevent infinite recursion */
-#endif /* OS2 */
-
- if (msg != NULL) {
- ckmakxmsg(dbptr,
- DBUFL,
- "HEXDUMP: ",
- (char *)msg,
- " (",
- ckitoa(cnt),
- " bytes)\n",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- }
- } else {
- ckmakmsg(dbptr,
- DBUFL,
- "HEXDUMP: (",
- ckitoa(cnt),
- " bytes)\n",
- NULL
- );
- zsout(ZDFILE,dbptr);
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- }
- }
- for (i = 0; i < cnt; i++) {
- dbptr[0] = '\0';
- for (j = 0 ; (j < 16); j++) {
- if ((i + j) < cnt)
- sprintf(tmp,
- "%s%02x ",
- (j == 8 ? "| " : ""),
- (CHAR) st[i + j]
- );
- else
- sprintf(tmp,
- "%s ",
- (j == 8 ? "| " : "")
- );
- ckstrncat(dbptr,tmp,DBUFL+1);
- }
- ckstrncat(dbptr," ",DBUFL+1);
- for (k = 0; (k < 16) && ((i + k) < cnt); k++) {
- sprintf(tmp,
- "%s%c",
- (k == 8 ? " " : ""),
- isprint(st[i + k]) ? st[i + k] : '.'
- );
- ckstrncat(dbptr,tmp,DBUFL+1);
- }
- ckstrncat(dbptr,"\n",DBUFL+1);
- i += j - 1;
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- }
- } /* end for */
-
-
- xdebug:
-#ifdef OS2
- if (SysInited)
- ReleaseDebugMutex();
-#else /* OS2 */
- deblog = 1;
-#endif /* OS2 */
- return(0);
-}
-#endif /* DEBUG */
-
-/* Session Log... */
-
-int tsstate = 0;
-
-VOID
-#ifdef OS2
-logchar(unsigned short c)
-#else /* OS2 */
-#ifdef CK_ANSIC
-logchar(char c)
-#else
-logchar(c) char c;
-#endif /* CK_ANSIC */
-#endif /* OS2 */
-/* logchar */ { /* Log character c to session log */
- extern int slognul;
- int oktolog = 0;
-#ifndef NOLOCAL
- if (!seslog)
- return;
-
- if ((sessft != XYFT_T) || (
-#ifdef UNIX
- c != '\r' &&
-#else
-#ifdef datageneral
- c != '\r' &&
-#else
-#ifdef STRATUS
- c != '\r' &&
-#else
-#ifdef AMIGA
- c != '\r' &&
-#else
-#ifdef GEMDOS
- c != '\r' &&
-#endif /* GEMDOS */
-#endif /* AMIGA */
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* UNIX */
-#ifdef OSK
- c != '\n' &&
-#else
-#ifdef MAC
- c != '\n' &&
-#endif /* MAC */
-#endif /* OSK */
- c != XON &&
- c != XOFF))
- oktolog = 1;
- if (c == '\0' && !sessft) /* NUL in text mode */
- if (slognul) oktolog = 1; /* only if padding (2009/10/22) */
- if (!oktolog)
- return;
- if (slogts) { /* Log is timestamped */
- if (tsstate == 0) { /* State = between-lines */
- char * p; /* zstime() pointer */
- char ts[48]; /* timestamp buffer */
- ztime(&p); /* Get asctime() string */
- ckstrncpy(ts,p,32); /* Make safe copy */
- if (ztmsec > -1L) { /* Add msecs if we have them */
- sprintf(&ts[19],".%03ld: ",ztmsec); /* SAFE */
- } else {
- ts[19] = ':';
- ts[20] = SP;
- ts[21] = NUL;
- }
- if (zsout(ZSFILE,&ts[11]) < 0)
- goto xlogchar;
- }
- }
- if (c == '\n') /* At end of line? */
- tsstate = 0; /* yes */
- else
- tsstate = 1; /* no */
- if (zchout(ZSFILE,(CHAR)(c & 0xFF)) < 0) /* Log the character */
- goto xlogchar;
- if (tsstate == 0 && slognul != 0) { /* Null-terminating lines? */
- if (zchout(ZSFILE,(CHAR)0) < 0) /* Add a NUL */
- goto xlogchar;
- }
- return;
-
- xlogchar:
- conoll("");
- conoll("ERROR WRITING SESSION LOG, LOG CLOSED!");
- setseslog(0);
- zclose(ZSFILE);
-#endif /* NOLOCAL */
-}
-
-VOID
-logstr(s, len) char * s; int len; { /* Log string to session log */
-#ifndef NOLOCAL
- int n = 0;
- if (!s)
- return;
- while (seslog && (n < len))
- logchar(s[n++]);
-#endif /* NOLOCAL */
-}
-
-#ifdef CK_CURSES
-int
-ck_repaint() {
- repaint = 1;
- return(0);
-}
-
-#ifdef STRATUS
-/* VOS has curses but no tgetent() */
-int
-tgetent(s1, s2) char * s1, * s2; {
- return(1);
-}
-#endif /* STRATUS */
-
-#ifdef VMS
-#ifdef __DECC
-_PROTOTYP(int tgetent,(char *, char *));
-#endif /* __DECC */
-#endif /* VMS */
-
-/*
- There are three different ways to do fullscreen on VMS.
- 1. Use the real curses library, VAXCCURSE.
- 2. Use do-it-yourself code.
- 3. Use the Screen Manager, SMG$.
-
- Method 1 doesn't work quite right; you can't call endwin(), so once you've
- started curses mode, you can never leave.
-
- Method 2 doesn't optimize the screen, and so much more time is spent in
- screen writes. This actually causes file transfers to fail because the
- tty device input buffer can be overrun while the screen is being updated,
- especially on a slow MicroVAX that has small typeahead buffers.
-
- In the following #ifdef block, #define one of them and #undef the other 2.
-
- So now let's try method 3...
-*/
-#ifdef VMS
-#define CK_SMG /* Screen Manager */
-#undef MYCURSES /* Do-it-yourself */
-#undef VMSCURSE /* VAXCCURSE library */
-#endif /* VMS */
-/*
- But just before New Years, 2000, the SMG library seemed to break on
- both VMS systems we have here (an Alpha with VMS 7.1 and a VAX with 5.5).
- So back to MYCURSES, which works fine.
-*/
-#ifdef VMS
-#undef CK_SMG
-#define MYCURSES
-#endif /* VMS */
-
-#ifdef MYCURSES
-#define stdscr 0
-#ifdef CK_WREFRESH
-#undef CK_WREFRESH
-#endif /* CK_WREFRESH */
-#endif /* MYCURSES */
-
-/* S C R E E N C -- Screen display function, uses curses */
-
-/* Idea for curses display contributed by Chris Pratt of APV Baker, UK */
-
-/* Avoid conficts with curses.h */
-
-#ifdef QNX
-/* Same as ckcasc.h, but in a different radix... */
-#ifdef ESC
-#undef ESC
-#endif /* ESC */
-#endif /* QNX */
-
-#ifndef MYCURSES
-#undef VOID /* This was defined in ckcdeb.h */
-#endif /* MYCURSES */
-
-#undef BS /* These were defined in ckcasc.h */
-#undef CR
-#undef NL
-#undef SO
-#ifdef US
-#undef US
-#endif /* US */
-#undef SP /* Used in ncurses */
-#define CHR_SP 32 /* Use this instead */
-
-#ifdef VMS /* VMS fullscreen display */
-#ifdef MYCURSES /* Do-it-yourself method */
-extern int isvt52; /* From CKVTIO.C */
-#define printw printf
-#else
-#ifdef VMSCURSE /* VMS curses library VAXCCURSE */
-#include <curses.h>
-/* Note: Screen manager doesn't need a header file */
-#endif /* VMSCURSE */
-#endif /* MYCURSES */
-#else /* Not VMS */
-#ifdef MYCURSES /* Do-it-yourself method */
-#define isvt52 0 /* Used by OS/2, VT-100/ANSI always */
-#ifdef CKXPRINTF
-#define printw ckxprintf
-#else /* CKXPRINTF */
-#ifdef KUI
-#define printw Vscrnprintw
-#else /* KUI */
-#define printw printf
-#endif /* KUI */
-#endif /* CKXPRINTF */
-#else /* Use real curses */
-#ifdef CK_NCURSES /* or ncurses... */
-#ifdef CKXPRINTF /* Our printf macro conflicts with */
-#undef printf /* use of "printf" in ncurses.h */
-#endif /* CKXPRINTF */
-#include <ncurses.h>
-#ifdef CKXPRINTF
-#define printf ckxprintf
-#endif /* CKXPRINTF */
-#else /* Not ncurses */
-#ifdef CKXPRINTF /* Our printf macro conflicts with */
-#undef printf /* use of "printf" in curses.h */
-#endif /* CKXPRINTF */
-#ifdef M_XENIX /* SCO XENIX... */
-#ifdef M_TERMCAP
-#undef M_TERMCAP
-#endif /* M_TERMCAP */
-#ifndef M_TERMINFO
-#define M_TERMINFO
-#endif /* M_TERMINFO */
-#endif /* M_XENIX */
-#ifdef RTAIX
-#undef NLS /* Avoid 'redeclaration of free'. */
-#endif /* RTAIX */
-#include <curses.h>
-#ifdef CKXPRINTF
-#define printf ckxprintf
-#endif /* CKXPRINTF */
-#endif /* CK_NCURSES */
-#endif /* MYCURSES */
-#endif /* VMS */
-
-#ifdef BUG999
-_PROTOTYP(int tgetent,(char *, char *));
-_PROTOTYP(char *tgetstr,(char *, char **));
-_PROTOTYP(int tputs,(char *, int, int (*)()));
-_PROTOTYP(char *tgoto,(const char *, int, int));
-#endif /* BUG999 */
-
-#endif /* CK_CURSES */
-
-/* F X D I N I T -- File Xfer Display Initialization */
-
-#ifdef CK_CURSES
-#ifndef MYCURSES
-#ifndef CK_SMG
-static
-#ifdef CK_ANSIC
-/* Can't use VOID because of curses.h */
-void
-ck_termset(int);
-#else
-ck_termset();
-#endif /* CK_ANSIC */
-#endif /* CK_SMG */
-#endif /* MYCURSES */
-#endif /* CK_CURSES */
-
-#ifdef NOTERMCAP
-static int notermcap = 1;
-#else
-static int notermcap = 0;
-#endif /* NOTERMCAP */
-
-#ifndef NODISPLAY
-CKVOID
-fxdinit(xdispla) int xdispla; {
-#ifndef COHERENT
-#ifndef OS2
-#ifndef STRATUS
- char *s;
- int x, dummy;
-
- debug(F101,"fxdinit xdispla","",xdispla);
- debug(F101,"fxdinit fxd_inited","",fxd_inited);
-
-#ifdef IKSD
-#ifndef NOXFER
- /* No curses for IKSD */
- if (inserver) {
- fdispla = XYFD_N;
- return;
- }
- if (fxd_inited) /* Only do this once */
- return;
-#endif /* NOXFER */
-#endif /* IKSD */
-
- if (xdispla == XYFD_R || xdispla == XYFD_S || xdispla == XYFD_B) {
- if (xfrmsg) {
- printf("%s\n",xfrmsg);
- makestr(&xfrmsg,NULL);
- }
- }
-
-#ifdef CK_CURSES
-#ifdef VMS
- /* Force BRIEF in Batch logs */
- if (batch && (xdispla == XYFD_C || xdispla == XYFD_S))
- xdispla = XYFD_B;
-#else
- if (xdispla == XYFD_C || xdispla == 9999) {
-
-#ifdef DYNAMIC
- if (!trmbuf) {
-/*
- Allocate tgetent() buffer. Make it big -- some termcaps can be huge;
- tgetent() merrily writes past the end of the buffer, causing core dumps
- or worse.
-*/
- trmbuf = (char *)malloc(TRMBUFL);
- if (!trmbuf) {
- notermcap = 1;
- debug(F101,"fxdinit malloc trmbuf","FAILED",TRMBUFL);
- fdispla = XYFD_S;
- return;
- }
-#ifdef COMMENT
- debug(F111,"fxdinit malloc trmbuf","OK",TRMBUFL);
- debug(F001,"fxdinit trmbuf","",trmbuf);
- memset(trmbuf,'\0',(size_t)TRMBUFL);
- debug(F100,"fxdinit memset OK","",0);
-#endif /* COMMENT */
- }
-#endif /* DYNAMIC */
-
- debug(F100,"fxdinit before getenv(TERM)","",0);
- s = getenv("TERM");
- debug(F110,"fxdinit after getenv(TERM)",s,0);
- if (!s) s = "";
- if (*s) {
- debug(F110,"fxdinit before tgetent()",s,0);
- x = tgetent(trmbuf,s);
- debug(F111,"fxdinit tgetent",s,x);
- } else {
- x = 0;
- notermcap = 1;
- debug(F110,"fxdinit TERM null - no tgetent",s,0);
- }
- if (x < 1 && !quiet && !backgrd
-#ifdef VMS
- && !batch
-#endif /* VMS */
- ) {
- printf("Warning: terminal type unknown: \"%s\"\n",s);
-#ifdef COMMENT
- /* Confusing - nobody knows what this means */
- printf("SCREEN command will use ANSI sequences.\n");
-#endif /* COMMENT */
- if (local)
- printf("Fullscreen file transfer display disabled.\n");
- fdispla = XYFD_S;
- }
-#ifndef MYCURSES
-#ifndef CK_SMG
- ck_termset(x);
-#endif /* CK_SMG */
-#endif /* MYCURSES */
- fxd_inited = 1;
- }
-#endif /* CK_CURSES */
-#endif /* VMS */
-#endif /* STRATUS */
-#endif /* OS2 */
-#endif /* COHERENT */
-}
-#endif /* NODISPLAY */
-
-#ifdef CK_CURSES
-#ifdef CK_SMG
-/*
- Long section for Screen Manager starts here...
- By William Bader.
-*/
-#include "ckvvms.h"
-#ifdef OLD_VMS
-#include <smgdef.h> /* use this on VAX C 2.4 */
-/* #include <smgmsg.h> */
-#else
-#include <smg$routines.h> /* Martin Zinser */
-#endif /* OLD_VMS */
-
-extern unsigned int vms_status; /* Used for system service return status */
-
-static long smg_pasteboard_id = -1; /* pasteboard identifier */
-static long smg_display_id = -1; /* display identifier */
-static int smg_open = 0; /* flag if smg current open */
-static int smg_inited = 0; /* flag if smg initialized */
-
-#ifdef COMMENT
-#define clrtoeol() SMG$ERASE_LINE(&smg_display_id, 0, 0)
-
-#define clear() SMG$ERASE_DISPLAY(&smg_display_id, 0, 0, 0, 0)
-
-#define touchwin(scr) SMG$REPAINT_SCREEN(&smg_pasteboard_id)
-
-#else /* Not COMMENT */
-
-#define clrtoeol() smg$erase_line(&smg_display_id, 0, 0)
-
-#define clear() smg$erase_display(&smg_display_id, 0, 0, 0, 0)
-
-#define touchwin(scr) smg$repaint_screen(&smg_pasteboard_id)
-#endif /* COMMENT */
-
-#define clearok(curscr,ok) /* Let wrefresh() do the work */
-
-#define wrefresh(cursrc) touchwin(scr)
-
-static void
-move(row, col) int row, col; {
- /* Change from 0-based for curses to 1-based for SMG */
- if (!smg_open)
- return;
- ++row; ++col;
- debug(F111,"VMS smg move",ckitoa(row),col);
-#ifdef COMMENT /* Martin Zinser */
- CHECK_ERR("move: smg$set_cursor_abs",
- SMG$SET_CURSOR_ABS(&smg_display_id, &row, &col));
-#else
- CHECK_ERR("move: smg$set_cursor_abs",
- smg$set_cursor_abs(&smg_display_id, &row, &col));
-#endif /* COMMENT */
- debug(F101,"VMS smg move vms_status","",vms_status);
-}
-
-#ifdef VMS_V40
-#define OLD_VMS
-#endif /* VMS_V40 */
-#ifdef VMS_V42
-#define OLD_VMS
-#endif /* VMS_V42 */
-#ifdef VMS_V44
-#define OLD_VMS
-#endif /* VMS_V44 */
-
-static int
-initscr() {
- int rows = 24, cols = 80;
- int row = 1, col = 1;
-
- debug(F101,"VMS initscr smg_pasteboard_id A","",smg_pasteboard_id);
-
- if (smg_pasteboard_id == -1) { /* Open the screen */
-#ifdef OLD_VMS /* Note: Routine calls lowercased 9/96 */
- CHECK_ERR("initscr: smg$create_pasteboard",
- smg$create_pasteboard(&smg_pasteboard_id, 0, 0, 0, 0));
-#else
- /* For VMS V5, not tested */
- CHECK_ERR("initscr: smg$create_pasteboard",
- smg$create_pasteboard(&smg_pasteboard_id, 0, 0, 0, 0, 0));
-#endif /* OLD_VMS */
- }
- debug(F101,"VMS initscr smg_pasteboard_id B","",smg_pasteboard_id);
- if (smg_pasteboard_id == -1) {
- printf("?Error initializing fullscreen display\n");
- fdispla = XYFD_S;
- dpyinit();
- return(0);
- }
- debug(F101,"VMS initscr smg_display_id","",smg_display_id);
- if (smg_display_id == -1) { /* Create a display window */
-
-#ifdef COMMENT /* Martin Zinser */
- CHECK_ERR("initscr: smg$create_virtual_display",
- SMG$CREATE_VIRTUAL_DISPLAY(&rows, &cols, &smg_display_id,
- 0, 0, 0));
-
- /* Connect the display window to the screen */
- CHECK_ERR("initscr: smg$paste_virtual_display",
- SMG$PASTE_VIRTUAL_DISPLAY(&smg_display_id,&smg_pasteboard_id,
- &row,&col));
-#else
- CHECK_ERR("initscr: smg$create_virtual_display",
- smg$create_virtual_display(&rows, &cols, &smg_display_id,
- 0, 0, 0));
-
- /* Connect the display window to the screen */
- CHECK_ERR("initscr: smg$paste_virtual_display",
- smg$paste_virtual_display(&smg_display_id,&smg_pasteboard_id,
- &row,&col));
-#endif /* COMMENT */
- }
- debug(F101,"VMS initscr smg_open A","",smg_open);
- if (!smg_open) { /* Start a batch update */
- smg_open = 1;
-#ifdef COMMENT
- CHECK_ERR("initscr: smg$begin_pasteboard_update",
- SMG$BEGIN_PASTEBOARD_UPDATE(&smg_pasteboard_id));
-#else
- CHECK_ERR("initscr: smg$begin_pasteboard_update",
- smg$begin_pasteboard_update(&smg_pasteboard_id));
-#endif /* COMMENT */
- debug(F101,"VMS initscr smg$begin_pasteboard_update","",vms_status);
- }
- debug(F101,"VMS initscr smg_open B","",smg_open);
- smg_inited = 1;
- return(1);
-}
-
-static void
-refresh() {
- debug(F101,"refresh smg_pasteboard_id","",smg_pasteboard_id);
-
- if (smg_open == 0 || smg_pasteboard_id == -1)
- return;
-
-#ifdef COMMENT /* Martin Zinser */
- CHECK_ERR("refresh: smg$end_pasteboard_update",
- SMG$END_PASTEBOARD_UPDATE(&smg_pasteboard_id));
- CHECK_ERR("refresh: smg$begin_pasteboard_update",
- SMG$BEGIN_PASTEBOARD_UPDATE(&smg_pasteboard_id));
-#else
- CHECK_ERR("refresh: smg$end_pasteboard_update",
- smg$end_pasteboard_update(&smg_pasteboard_id));
- CHECK_ERR("refresh: smg$begin_pasteboard_update",
- smg$begin_pasteboard_update(&smg_pasteboard_id));
-#endif /* COMMENT */
-}
-
-static void
-endwin() {
- if (!smg_open)
- return;
-
- smg_open = 0;
-
-#ifdef COMMENT
- CHECK_ERR("endwin: smg$end_pasteboard_update",
- SMG$END_PASTEBOARD_UPDATE(&smg_pasteboard_id));
-#else
- CHECK_ERR("endwin: smg$end_pasteboard_update",
- smg$end_pasteboard_update(&smg_pasteboard_id));
-#endif /* COMMENT */
-
- move(22, 0);
-
-#ifdef COMMENT
-/*
- These calls clear the screen.
- (convert routine calls to lowercase - Martin Zinser)
-*/
- CHECK_ERR("endwin: smg$delete_virtual_display",
- SMG$DELETE_VIRTUAL_DISPLAY(&smg_display_id));
- smg_display_id = -1;
-
- CHECK_ERR("endwin: smg$delete_pasteboard",
- SMG$DELETE_PASTEBOARD(&smg_pasteboard_id, 0));
- smg_pasteboard_id = -1;
-#endif /* COMMENT */
-}
-
-#ifdef COMMENT
-/* DECC 6.2 screams bloody murder about printw ("not enough args") */
-/* but adding the following prototype only makes it holler louder. */
-#ifdef __DECC
-/* "varargs" prototype for printw */
-_PROTOTYP(static int printw,(char *, ...));
-#endif /* __DECC */
-#endif /* COMMENT */
-
-#ifdef __DECC
-#include <stdarg.h>
-_PROTOTYP(static void printw,(char *, ...));
-static void
-printw(char *str,...) {
- char buf[255];
- va_list ap;
- $DESCRIPTOR(text_dsc, 0);
- text_dsc.dsc$a_pointer=buf;
- if (!smg_open)
- return;
- va_start(ap,str);
- text_dsc.dsc$w_length = vsprintf(buf, str, ap);
- va_end(ap);
- CHECK_ERR("printw: smg$put_chars",
- smg$put_chars(&smg_display_id, &text_dsc, 0, 0, 0, 0, 0));
-}
-#else
-static void
-printw(str, a1, a2, a3, a4, a5, a6, a7, a8)
- char *str;
- long a1, a2, a3, a4, a5, a6, a7, a8;
-/* printw */ {
- char buf[255];
- $DESCRIPTOR(text_dsc, 0);
- if (!smg_open)
- return;
- text_dsc.dsc$a_pointer=buf;
- text_dsc.dsc$w_length = sprintf(buf, str, a1, a2, a3, a4, a5, a6, a7, a8);
- CHECK_ERR("printw: smg$put_chars",
- smg$put_chars(&smg_display_id, &text_dsc, 0, 0, 0, 0, 0));
-}
-#endif /* __DECC */
-
-#define CK_CURPOS
-int
-ck_curpos(row, col) {
- debug(F111,"VMS smg ck_curpos",ckitoa(row),col);
- if (!smg_inited || !smg_open) {
- initscr();
- }
- debug(F101,"VMS smg curpos smg_open","",smg_open);
- if (!smg_open)
- return(0);
- debug(F111,"VMS smg ck_curpos",ckitoa(row-1),col-1);
- move(row - 1, col - 1); /* SMG is 0-based */
- refresh();
- /* endwin(); */
- return(0);
-}
-
-int
-ck_cls() {
- debug(F101,"VMS smg ck_cls smg_inited","",smg_inited);
- if (!smg_inited || !smg_open) {
- initscr();
- }
- debug(F101,"VMS smg ck_cls smg_open","",smg_open);
- if (!smg_open)
- return(0);
- clear();
- refresh();
- /* endwin(); */
- return(0);
-}
-
-int
-ck_cleol() {
- debug(F101,"VMS smg ck_cleol smg_inited","",smg_inited);
- if (!smg_inited || !smg_open) {
- initscr();
- }
- debug(F101,"VMS smg ck_cleol smg_open","",smg_open);
- if (!smg_open)
- return(0);
- clrtoeol();
- refresh();
- /* endwin(); */
- return(0);
-}
-#endif /* CK_SMG */
-
-#ifdef MYCURSES
-/*
- Do-it-yourself curses implementation for VMS, OS/2 and other ANSI/VT-100's.
- Supports only the VT52 and VT1xx (and later VT2xx/3xx/4xx) terminals.
- By Terry Kennedy, St Peters College.
-
- First, some stuff we can just ignore:
-*/
-
-static int
-touchwin(x) int x; {
- return(0);
-}
-static int
-initscr() {
- return(0);
-}
-static int
-refresh() {
- return(0);
-}
-static int
-endwin() {
- return(0);
-}
-
-/*
- * Now, some stuff we need to do:
- */
-
-_PROTOTYP( int move, (int, int) );
-#ifndef OS2
-int
-move(row, col) int row, col; {
- if (isvt52)
- printf("\033Y%c%c", row + 037, col + 037);
- else
- printf("\033[%d;%dH", row + 1, col + 1);
- return(0);
-}
-
-int
-clear() {
- move(0,0);
- if (isvt52)
- printf("\033J");
- else
- printf("\033[J");
- return(0);
-}
-
-int
-clrtoeol() {
- if (isvt52)
- printf("\033K");
- else
- printf("\033[K");
- return(0);
-}
-
-#define CK_CURPOS
-int
-ck_cls() {
- return(clear());
-}
-
-int
-ck_cleol() {
- return(clrtoeol());
-}
-
-int
-ck_curpos(row, col) int row, col; {
- move(row, col);
- return(0);
-}
-
-#else /* OS2 */
-/* Windows NT and Windows 95 do not provide ANSI emulation */
-/* Therefore we might as well not use it for OS/2 either */
-
-int
-move(row, col) int row, col; {
-#ifndef ONETERMUPD
- SetCurPos(row, col);
-#endif /* ONETERMUPD */
- lgotoxy( VCMD, col+1, row+1);
- VscrnIsDirty(VCMD);
- return(0);
-}
-
-int
-clear() {
- viocell cell;
- move(0,0);
-#ifdef ONETERMUPD
- if (VscrnGetBufferSize(VCMD) > 0) {
- VscrnScroll(VCMD, UPWARD, 0,
- VscrnGetHeight(VCMD)-(1),
- VscrnGetHeight(VCMD)-(0), TRUE, CHR_SP);
- cleartermscreen(VCMD);
- }
-#else
- cell.c = ' ';
- cell.a = colorcmd;
- WrtNCell(cell, cmd_rows * cmd_cols, 0, 0);
-#endif /* ONETERMUPD */
- return(0);
-}
-
-int
-clrtoeol() {
- USHORT row, col;
- viocell cell;
-
- cell.c = ' ';
- cell.a = colorcmd;
-#ifndef ONETERMUPD
- GetCurPos(&row, &col );
- WrtNCell(cell, cmd_cols - col -1, row, col);
-#endif /* ONETERMUPD */
- clrtoeoln(VCMD,CHR_SP);
- return(0);
-}
-
-#define CK_CURPOS
-int
-ck_curpos(row, col) int row, col; {
- move(row, col);
- return(0);
-}
-
-int
-ck_cls() {
- return(clear());
-}
-
-int
-ck_cleol() {
- return(clrtoeol());
-}
-
-#endif /* OS2 */
-#endif /* MYCURSES */
-
-#ifndef NOTERMCAP
-#ifndef CK_CURPOS
-#define CK_CURPOS
-
-/* Termcap/Terminfo section */
-
-static char cur_cls[32] = { NUL, NUL };
-static char cur_cleol[32] = { NUL, NUL };
-static char cur_cm[64] = { NUL, NUL };
-static char tgsbuf[128] = { NUL, NUL };
-
-static
-#ifdef CK_ANSIC
-void
-#endif /* CK_ANSIC */
-ck_termset(x) int x; {
- cur_cls[0] = NUL;
- cur_cleol[0] = NUL;
- cur_cm[0] = NUL;
-#ifdef tgetent
- debug(F100,"tgetent is a macro","",0);
-#endif /* tgetent */
-#ifdef tgetstr
- debug(F100,"tgetstr is a macro","",0);
-#endif /* tgetstr */
-#ifdef tputs
- debug(F100,"tputs is a macro","",0);
-#endif /* tputs */
-#ifdef tgoto
- debug(F100,"tgoto is a macro","",0);
-#endif /* tgoto */
-#ifdef NOTERMCAP
- /* tgetstr() gets a segmentation fault on OSF/1 */
- debug(F100,"ck_termset NOTERMCAP","",0);
-#else
- if (notermcap) {
- debug(F100,"ck_termset notermcap","",0);
- return;
- }
- debug(F101,"ck_termset x","",x);
- if (x > 0) {
- char * bp;
- bp = tgsbuf;
- *bp = NUL;
- debug(F110,"ck_termset calling tgetstr","cl",0);
- if (tgetstr("cl", &bp)) { /* Get clear-screen code */
- debug(F110,"ck_termset tgetstr cl",tgsbuf,"");
- if ((int)strlen(tgsbuf) < 32)
- ckstrncpy(cur_cls,tgsbuf,32);
- } else
- return;
- bp = tgsbuf;
- if (tgetstr("ce", &bp)) { /* Get clear-to-end-of-line code */
- debug(F110,"ck_termset tgetstr ce",tgsbuf,"");
- if ((int)strlen(tgsbuf) < 32)
- ckstrncpy(cur_cleol,tgsbuf,32);
- } else
- return;
- bp = tgsbuf;
- if (tgetstr("cm", &bp)) { /* Get cursor-movement code */
- debug(F110,"ck_termset tgetstr cm",tgsbuf,"");
- if ((int)strlen(tgsbuf) < 64)
- ckstrncpy(cur_cm,tgsbuf,64);
- } else
- return;
- }
-#endif /* NOTERMCAP */
-}
-
-#ifndef TPUTSFNTYPE
-#ifdef TPUTSISVOID
-#define TPUTSFNTYPE void
-#else
-#define TPUTSFNTYPE int
-#endif /* TPUTSISVOID */
-#endif /* TPUTSFNTYPE */
-
-#ifndef TPUTSARGTYPE
-#ifdef HPUX9
-#define TPUTSARGTYPE char
-#else
-#ifdef HPUX10
-#define TPUTSARGTYPE char
-#else
-#define TPUTSARGTYPE int
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* TPUTSARGTYPE */
-
-static TPUTSFNTYPE
-#ifdef CK_ANSIC
-ck_outc(TPUTSARGTYPE x)
-#else
-ck_outc(x) TPUTSARGTYPE x;
-#endif /* CK_ANSIC */
-{ /* To satisfy tputs() arg3 prototype */
- int rc;
- char c;
- c = (char) x;
- rc = (inserver) ? ttoc(c) : conoc(c);
-#ifndef TPUTSISVOID
- return(rc);
-#endif /* TPUTSISVOID */
-}
-
-int
-ck_curpos(row, col) int row, col; {
-#ifdef CK_ANSIC
- TPUTSFNTYPE (*fn)(TPUTSARGTYPE);
-#else
- TPUTSFNTYPE (*fn)();
-#endif /* CK_ANSIC */
- if (!fxd_inited)
- fxdinit(9999);
- if (!cur_cm[0]) { /* We don't have escape sequences */
-#ifdef COMMENT
- return(-1); /* Do nothing */
-#else
- /* Both C-Kermit's SCREEN command and ANSI/VT100 are 1-based */
- printf("\033[%d;%dH", row, col); /* Or default to ANSI */
-#endif /* COMMENT */
- } else {
- fn = ck_outc;
- /* termcap/terminfo is 0-based */
- tputs(
-#ifdef TPUTSARG1CONST
- (const char *)
-#endif /* TPUTSARG1CONST */
- tgoto(cur_cm,col-1,row-1),1,fn);
- }
- return(0);
-}
-
-int
-ck_cls() {
-#ifdef CK_ANSIC
- TPUTSFNTYPE (*fn)(TPUTSARGTYPE);
-#else
- TPUTSFNTYPE (*fn)();
-#endif /* CK_ANSIC */
- if (!fxd_inited)
- fxdinit(9999);
- if (!cur_cls[0]) { /* If we don't have escape sequences */
-#ifdef COMMENT
- return(-1); /* Do nothing */
-#else
- printf("\033[;H\033[2J"); /* Or default to ANSI */
-#endif /* COMMENT */
- } else {
- fn = ck_outc;
- debug(F111,"ck_cls 2",cur_cls,fxd_inited);
- tputs(cur_cls,cmd_rows,fn);
- }
- return(0);
-}
-
-int
-ck_cleol() {
-#ifdef CK_ANSIC
- TPUTSFNTYPE (*fn)(TPUTSARGTYPE);
-#else
- TPUTSFNTYPE (*fn)();
-#endif /* CK_ANSIC */
- if (!fxd_inited)
- fxdinit(9999);
- if (!cur_cleol[0]) { /* If we don't have escape sequences */
-#ifdef COMMENT
- return(-1); /* Do nothing */
-#else
- printf("\033[K"); /* Or use ANSI */
-#endif /* COMMENT */
- } else {
- fn = ck_outc;
- tputs(cur_cleol,1,fn);
- }
- return(0);
-}
-#endif /* CK_CURPOS */
-#else
-static void
-ck_termset(x) int x; {
- if (x) return;
-}
-#endif /* NOTERMCAP */
-
-#ifndef CK_CURPOS
-#define CK_CURPOS
-int
-ck_cls() {
- printf("\033[;H\033[2J");
- return(0);
-}
-
-int
-ck_cleol() {
- printf("\033[K");
- return(0);
-}
-
-int
-ck_curpos(row, col) int row, col; {
- printf("\033[%d;%dH", row, col);
- return(0);
-}
-#endif /* CK_CURPOS */
-
-
-#ifndef NOXFER
-static int cinit = 0; /* Flag for curses init'd */
-static int cendw = 0; /* endwin() was called */
-
-static
-#ifdef CK_ANSIC /* Because VOID used by curses.h */
-void
-#else
-#ifdef MYCURSES
-VOID
-#else
-int
-#endif /* MYCURSES */
-#endif /* CK_ANSIC */
-#ifdef CK_ANSIC /* Update % transfered and % bar */
-updpct(long old, long new)
-#else /* CK_ANSIC */
-updpct(old, new) long old, new;
-#endif /* CK_ANSIC */
-/* updpct */ {
-#ifdef COMMENT
- int m, n;
- move(CW_PCD,22);
- printw("%ld", new);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_PCD, (long) new);
-#endif /* K95G */
-#endif /* KUI */
-#ifdef CK_PCT_BAR
- if (thermometer) {
- if (old > new) {
- old = 0;
- move(CW_PCD, 26);
- clrtoeol();
- }
- m = old/2;
- move(CW_PCD, 26 + m);
- n = new / 2 - m;
-#ifndef OS2
- while (n > 0) {
- if ((m + 1) % 5 == 0)
- printw("*");
- else
- printw("=");
- m++;
- n--;
- }
- if (new % 2 != 0) printw("-");
- /* move(CW_PCD, 22+53); */
-#else /* OS2 */
- while (n > 0) {
- printw("%c", '\333');
- m++; n--;
- }
- if (new % 2 != 0)
- printw("%c", '\261');
-#endif /* OS2 */
- }
-#endif /* CK_PCT_BAR */
- /* clrtoeol(); */
-#else /* !COMMENT */
-#ifdef OS2
-#define CHAR1 '\333' /* OS2 - CP437 */
-#define CHAR2 '\261'
-#else
-#define CHAR1 '/' /* Default */
-#define CHAR2 '-'
-#endif /* OS2 */
- debug(F101,"updpct old","",old);
- debug(F101,"updpct new","",new);
- move(CW_PCD,22);
- printw("%-3ld", new); /* (was) printw("%ld", new); */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PCD, (long) new );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef CK_PCT_BAR
- if (thermometer) {
- int m, n;
-
- if (old > new) {
- old = 0 ;
- move(CW_PCD, 26);
- clrtoeol();
- }
- if (new <= 100L) {
- m = old / 2;
- n = new / 2 - m;
- move(CW_PCD, 26+m);
- while (n-- > 0)
- printw("%c", CHAR1);
- if (new % 2 != 0)
- printw("%c", CHAR2);
- }
- }
-#endif /* CK_PCT_BAR */
-#endif /* COMMENT */
-}
-
-static CK_OFF_T old_tr = (CK_OFF_T)-1; /* Time remaining previously */
-
-static CK_OFF_T
-#ifdef CK_ANSIC
-shoetl(CK_OFF_T old_tr, long cps, CK_OFF_T fsiz, CK_OFF_T howfar)
-#else
- shoetl(old_tr, cps, fsiz, howfar) long cps; CK_OFF_T old_tr, fsiz, howfar;
-#endif /* CK_ANSIC */
-/* shoetl */ { /* Estimated time left in transfer */
- CK_OFF_T tr; /* Time remaining, seconds */
-
-#ifdef GFTIMER
- if (fsiz > 0L && cps > 0L)
- tr = (CK_OFF_T)((CKFLOAT)(fsiz - howfar) / (CKFLOAT)cps);
- else
- tr = (CK_OFF_T)-1;
-#else
- tr = (fsiz > 0L && cps > 0L) ?
- ((fsiz - howfar) / cps) :
- (CK_OFF_T)-1;
-#endif /* GFTIMER */
- move(CW_TR,22);
- if (tr > (CK_OFF_T)-1) {
- if (tr != old_tr) {
- printw("%s",hhmmss(tr));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long)CW_TR, (long)hhmmss(tr));
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- }
- } else {
- printw("(unknown)");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TR, (long) "(unknown)" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- }
- return(tr);
-}
-
-static long
-#ifdef CK_ANSIC
-shocps(int pct, CK_OFF_T fsiz, CK_OFF_T howfar)
-#else
-shocps(pct, fsiz, howfar) int pct; CK_OFF_T fsiz, howfar;
-#endif /* CK_ANSIC */
-/* shocps */ {
-#ifdef CPS_WEIGHTED
- static CK_OFF_T oldffc = 0L;
-#endif /* CPS_WEIGHTED */
-#ifdef GFTIMER
- CKFLOAT secs, xx;
-#else
- CK_OFF_T secs, xx;
-#endif /* GFTIMER */
-
-#ifdef GFTIMER
- xx = (gtv >= 0.0) ? gtv : 0.0; /* Floating-point version */
- gtv = gftimer();
- if ((gtv - oldgtv) < (CKFLOAT) 1.0) /* Only do this once per second */
- return(oldcps);
- oldgtv = xx;
-#else
- xx = (gtv >= 0) ? gtv : 0; /* Whole-number version */
- gtv = gtimer();
- if ((gtv - oldgtv) < 1)
- return(oldcps);
- oldgtv = xx;
-#endif /* GFTIMER */
-
-#ifdef CPS_WEIGHTED
- /* debug(F100,"SHOCPS: WEIGHTED","",0); */
- if (gtv != oldgtv) { /* The first packet is ignored */
- if (ffc < oldffc)
- oldffc = ffc;
- oldcps = cps;
- if (oldcps && oldgtv >
-#ifdef GFTIMER
- 1.0
-#else
- 1
-#endif /* GFTIMER */
- ) { /* The first second is ignored */
-/*
- This version of shocps() produces a weighted average that some
- people like, but most people find it disconcerting and bombard us
- with questions and complaints about why the CPS figure fluctuates so
- wildly. So now you only get the weighted average if you build the
- program yourself with CPS_WEIGHTED defined.
-*/
-#ifndef CPS_VINCE
-#ifdef GFTIMER
- cps = (long)((((CKFLOAT)oldcps * 3.0) +
- (CKFLOAT)(ffc - oldffc) / (gtv-oldgtv) ) / 4.0);
-#else
- cps = ( (oldcps * 3) + (ffc - oldffc) / (gtv-oldgtv) ) / 4;
-#endif /* GFTIMER */
-#else
-/* And an alternate weighting scheme from Vincent Fatica... */
- cps = (3 *
- ((1+pct/300)*oldffc/oldgtv+(1-pct/100)*(ffc-oldffc)/(gtv-oldgtv)))
- / 4;
-#endif /* CPS_VINCE */
- } else {
- /* No weighted average since there is nothing to weigh */
-#ifdef GFTIMER
- cps = (long)(gtv != 0.0 ?
- (CKFLOAT)(ffc - oldffc) / (gtv - oldgtv) :
- (ffc - oldffc)) ;
-#else
- cps = gtv ? (ffc - oldffc) / (gtv - oldgtv) : (ffc - oldffc) ;
-#endif /* GFTIMER */
- }
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"SHOCPS: pct ","",pct);
- debug(F101,"SHOCPS: gtv ","",gtv);
- debug(F101,"SHOCPS: oldgtv","",oldgtv);
- debug(F101,"SHOCPS: dgtv ","",(long)(gtv-oldgtv));
- debug(F101,"SHOCPS: ffc ","",ffc);
- debug(F101,"SHOCPS: oldffc","",oldffc);
- debug(F101,"SHOCPS: dffc ","",ffc-oldffc);
- debug(F101,"SHOCPS: cps ","",cps);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- move(CW_CP,22);
- printw("%ld", cps);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, (long) cps );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldffc = ffc;
- }
-#else /* !CPS_WEIGHTED */
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F100,"SHOCPS: NOT WEIGHTED","",0);
- debug(F101,"SHOCPS: pct ","",pct);
- debug(F101,"SHOCPS: gtv ","",gtv);
- debug(F101,"SHOCPS: oldgtv ","",oldgtv);
- debug(F101,"SHOCPS: dgtv ","",(long)gtv - (long)oldgtv);
- debug(F101,"SHOCPS: ffc ","",ffc);
- debug(F101,"SHOCPS: oldffc ","",oldffc);
- debug(F101,"SHOCPS: dffc ","",ffc-oldffc);
- debug(F101,"SHOCPS: cps ","",cps);
- debug(F101,"SHOCPS: filcnt ","",filcnt);
-#ifdef GFTIMER
- debug(F101,"SHOCPS: fpfsecs","",fpfsecs);
-#endif /* GFTIMER */
- }
- debug(F101,"shocps gtv","",gtv);
-#endif /* DEBUG */
-#ifdef GFTIMER
-#endif /* COMMENT */
- /* debug(F101,"shocps fpfsecs","",fpfsecs); */
- secs = gtv - fpfsecs;
- /* debug(F101,"shocps secs","",(long)secs); */
- if (secs > 0.0) {
- cps = (long)((CKFLOAT) ffc / secs);
- /* debug(F101,"shocps cps","",cps); */
- move(CW_CP,22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, (long) cps );
-#endif /* K95G */
-#endif /* KUI */
- printw("%ld", cps);
- clrtoeol();
- }
-#else /* Not GFTIMER */
- if ((secs = gtv - fsecs) > 0) {
- cps = (secs < 1L) ? ffc : ffc / secs;
- move(CW_CP,22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, (long) cps );
-#endif /* K95G */
-#endif /* KUI */
- printw("%ld", cps);
- clrtoeol();
- }
-#endif /* GFTIMER */
-#endif /* CPS_WEIGHTED */
-
- if (cps > peakcps && /* Peak transfer rate */
- ((what & W_SEND && spackets > wslots + 4) ||
- (!(what & W_SEND) && spackets > 10))) {
- peakcps = cps;
- }
- old_tr = shoetl(old_tr, cps, fsiz, howfar);
- return(cps);
-}
-
-static
-#ifdef CK_ANSIC /* Because VOID used by curses.h */
-void
-#else
-#ifdef MYCURSES
-VOID
-#else
-int
-#endif /* MYCURSES */
-#endif /* CK_ANSIC */
-scrft() { /* Display file type */
- char xferstr[256];
- xferstr[0] = NUL;
- debug(F101,"scrft binary","",binary);
- if (binary) {
- switch(binary) {
- case XYFT_L:
- ckstrncpy(xferstr,"LABELED",256);
- break;
- case XYFT_I:
- ckstrncpy(xferstr,"IMAGE",256);
- break;
- case XYFT_U:
- ckstrncpy(xferstr,"BINARY UNDEFINED",256);
- break;
- case XYFT_M:
- ckstrncpy(xferstr,"MACBINARY",256);
- break;
- case XYFT_X:
- ckstrncpy(xferstr,"TENEX",256);
- break;
- default:
- case XYFT_B:
- ckstrncpy(xferstr,"BINARY",256);
- break;
- }
-#ifdef CK_RESEND
- if (what & W_SEND && sendstart > 0L) {
- if (sendmode == SM_PSEND) {
- ckstrncat(xferstr, " / partial", 256);
- } else if (sendmode == SM_RESEND) {
- ckstrncat(xferstr, " / resend", 256);
- }
- } else if (what & W_RECV && rs_len > 0L) {
- ckstrncat(xferstr, " / resend", 256);
- }
-#endif /* CK_RESEND */
- } else {
-
-#ifndef NOCSETS
- ckstrncpy(xferstr,"TEXT",256);
-#ifdef NEWFTP
-#ifndef NOUNICODE
- if (what & W_FTP) {
- if (ftp_csx < 0)
- ckstrncat(xferstr," (no translation)", 256);
- else
- ckmakxmsg(&xferstr[4],252,
- " (",
- fcsinfo[(what & W_SEND) ? ftp_csl : ftp_csx].keyword,
- " => ",
- fcsinfo[(what & W_SEND) ? ftp_csx : ftp_csl].keyword,
- ")",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- } else
-#endif /* NOUNICODE */
-#endif /* NEWFTP */
- if (tcharset == TC_TRANSP) {
- ckstrncat(xferstr, " (no translation)", 256);
- } else {
- if (what & W_SEND) {
- sprintf( &xferstr[strlen(xferstr)], /* safe */
- " (%s => %s)",
- fcsinfo[fcharset].keyword, /* built-in keywords */
- tcsinfo[tcharset].keyword /* lengths are controlled */
- );
- } else {
- sprintf( &xferstr[strlen(xferstr)], /* safe */
- " (%s => %s)",
- tcsinfo[tcharset].keyword, /* built-in keywords */
- fcsinfo[fcharset].keyword); /* lengths controlled */
- }
- }
-#endif /* NOCSETS */
- }
- move(CW_TYP,22);
- printw("%s", xferstr);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TYP, (long) xferstr );
-#endif /* K95G */
-#endif /* KUI */
- return;
-}
-
-#ifdef CK_NEWTERM
-static FILE *ck_stdout = NULL;
-static int ck_fd = -1;
-#endif /* CK_NEWTERM */
-
-static long pct = 0L, oldpct = 0L, oldrtt = -1L;
-static int oldtyp = 0, oldwin = -1, oldtry = -1, oldlen = -1, oldtim = -1;
-
-#ifdef NETCONN
-static char *netname[] = {
- "none", /* 00 */
- "TCP/IP", /* 01 TCP (Sockets) */
- "TCP/IP", /* 02 TCP (Streams) */
- "X.25", /* 03 SunLink X.24 */
- "DECnet", /* 04 DECnet */
- "VAX PSI", /* 05 VAX PSI */
- "Named Pipes", /* 06 LAN Manager Named Pipe */
- "X.25", /* 07 Stratus VOS X.25 */
- "NetBIOS", /* 08 IBM NETBIOS */
- "SuperLAT", /* 07 Meridian SuperLAT */
- "File", /* 10 File */
- "Command", /* 11 Subprocess (pipe) */
- "DLL", /* 12 DLL does i/o */
- "X.25", /* 13 IBM AIXLink X.25 */
- "X.25", /* 14 HP-UX X.25 */
- "PTY", /* 15 Pseudoterminal */
- "SSH", /* 16 SSH */
- "<ERROR>", /* 17 In case new types are added */
- "<ERROR>", /* 18 but nobody remembers to update */
- "<ERROR>", /* 19 this table ... */
- NULL /* 20 */
-};
-static int nnetname = (sizeof(netname) / sizeof(char *));
-
-#endif /* NETCONN */
-
-#ifdef CK_ANSIC
-void
-screenc(int f, char c,CK_OFF_T n,char *s)
-#else
-CKVOID
-screenc(f,c,n,s)
-int f; /* argument descriptor */
-char c; /* a character or small integer */
-CK_OFF_T n; /* a long integer */
-char *s; /* a string */
-#endif /* CK_ANSIC */
-/* screenc() */ {
-#ifdef CK_SSL
- extern int tls_active_flag, ssl_active_flag;
-#endif /* CK_SSL */
-#ifdef RLOGCODE
- extern int ttnproto;
-#endif /* RLOGCODE */
- static int q = 0;
- static long fcnt = 0L; /* Number of files transferred */
- static CK_OFF_T fsiz = (CK_OFF_T)-1; /* Copy of file size */
- static CK_OFF_T fbyt = 0L; /* Total file bytes of all files transferred */
- static CK_OFF_T howfar = 0L; /* How much of current file has been xfer'd */
- static int pctlbl = 0L; /* Percent done vs Bytes so far */
- long cps = 0L;
-
- int net = 0;
- int xnet = 0;
- int ftp = 0;
- int len; /* Length of string */
- int errors = 0; /* Error counter */
- int x; /* Worker */
-
- debug(F101,"screenc cinit","",cinit);
- debug(F101,"screenc cendw","",cendw);
-
- if (!s) s = ""; /* Always do this. */
-
- ftp = (what & W_FTP) ? 1 : 0; /* FTP or Kermit */
- net = network || ftp;
- xnet = ftp ? 1 : nettype; /* NET_TCPB == 1 */
-
- if (cinit == 0 || cendw > 0) { /* Handle borderline cases... */
- if (f == SCR_CW) { /* Close window, but it's not open */
- ft_win = 0;
- return;
- }
- debug(F111,"screenc A",s,f);
- if (f == SCR_EM ||
- (f == SCR_PT && c == 'E')) { /* Fatal error before window open */
- conoll(""); conoc('?'); conoll(s); return; /* Regular display */
- }
- }
- if (cinit == 0) { /* Only call initscr() once */
- char * s;
- /* Check these now -- if they are defined but not numeric */
- /* they can crash curses */
- s = getenv("LINES");
- if (s) if (!rdigits(s)) {
- printf("?LINES variable not numeric: \"%s\".\n",s);
- printf("(Fullscreen display disabled)\n");
- fdispla = XYFD_S;
- return;
- }
- s = getenv("COLUMNS");
- if (s) if (!rdigits(s)) {
- printf("?COLUMNS variable not numeric: \"%s\".\n",s);
- printf("(Fullscreen display disabled)\n");
- fdispla = XYFD_S;
- return;
- }
- cendw = 1; /* New window needs repainting */
-#ifdef COMMENT
- if (!initscr()) { /* Oops, can't initialize window? */
-/*
- In fact, this doesn't happen. "man curses" says initscr() halts the
- entire program if it fails, which is true on the systems where I've
- tested it. It will fail if your terminal type is not known to it.
- That's why SET FILE DISPLAY FULLSCREEN calls tgetent() to make sure the
- terminal type is known before allowing a curses display.
-*/
- fprintf(stderr,"CURSES INITSCR ERROR\r\n");
- fdispla = XYFD_S; /* Fall back to CRT display */
- return;
- } else {
- cinit++; /* Window initialized ok */
- debug(F100,"CURSES INITSCR OK","",0);
- }
-#else /* Save some memory. */
-#ifdef CK_NEWTERM
- /* (From Andy Fyfe <andy@vlsi.cs.caltech.edu>)
- System V curses seems to reserve the right to alter the buffering
- on the output FILE* without restoring it. Fortunately System V
- curses provides newterm(), an alternative to initscr(), that
- allows us to specify explicitly the terminal type and input and
- output FILE pointers. Thus we duplicate stdout, and let curses
- have the copy. The original remains unaltered. Unfortunately,
- newterm() seems to be particular to System V.
- */
- s = getenv("TERM");
- if (ck_fd < 0) {
- ck_fd = dup(fileno(stdout));
- ck_stdout = (ck_fd >= 0) ? (FILE *)fdopen(ck_fd, "w") : NULL;
- }
- debug(F100,"screenc newterm...","",0);
-
-/* NOTE: It might be necessary to do this with stdin too! */
-/* This would have been the case in FreeBSD 4.1 but they fixed the */
-/* problem by restoring the buffering of stdin before the final release. */
-/* (But T.E. Dickey says stdin is not buffered?) */
-
- if (ck_stdout == NULL || newterm(s, ck_stdout, stdin) == 0) {
- fprintf(stderr,
- "Fullscreen display not supported for terminal type: %s\r\n",s);
- fdispla = XYFD_S; /* Use CRT instead */
- return;
- }
- debug(F100,"screenc newterm ok","",0);
-#else
- debug(F100,"screen calling initscr","",0);
- initscr(); /* Initialize curses. */
- debug(F100,"screen initscr ok","",0);
-#endif /* CK_NEWTERM */
- cinit++; /* Remember curses was initialized. */
-#endif /* COMMENT */
- }
- ft_win = 1; /* Window is open */
- if (repaint) {
-#ifdef CK_WREFRESH
-/*
- This totally repaints the screen, just what we want, but we can only
- do this with real curses, and then only if clearok() and wrefresh() are
- provided in the curses library.
-*/
-#ifdef OS2
- RestoreCmdMode();
-#else
-#ifdef QNX
-#ifndef QNX16
- clearok(stdscr, 1); /* QNX doesn't have curscr */
-#endif /* QNX16 */
- wrefresh(stdscr);
-#else
- wrefresh(curscr);
-#endif /* QNX */
-#endif /* OS2 */
-#else /* No CK_WREFRESH */
-/*
- Kermit's do-it-yourself method, works with all types of fullscreen
- support, but does not repaint all the fields. For example, the filename
- is lost, because it arrives at a certain time and never comes again, and
- Kermit presently does not save it anywhere. Making this method work for
- all fields would be a rather major recoding task, duplicating what curses
- already does, and would add a lot of complexity and storage space.
-*/
- cendw = 1;
-#endif /* CK_WREFRESH */
- repaint = 0;
- }
- if (cendw) { /* endwin() was called previously */
-#ifdef VMS
- initscr(); /* (or should have been!) */
- clear();
- touchwin(stdscr);
- refresh();
-#else
-#ifdef QNX
-/*
- In QNX, if we don't call initscr() here we core dump.
- I don't have any QNX curses documentation, but other curses manuals
- say that initscr() should be called only once per application, and
- experience shows that on other systems, calling initscr() here generally
- results in a core dump.
-*/
- debug(F100,"screenc re-calling initscr QNX","",0);
- initscr();
- clear();
- refresh();
-#ifdef COMMENT
-/*
- But even so, second and subsequent curses displays are messed up.
- Calling touchwin, refresh, etc, doesn't make any difference.
-*/
- debug(F100,"screenc calling touchwin QNX","",0);
- touchwin(stdscr);
- debug(F100,"screenc calling refresh QNX","",0);
- refresh();
-#endif /* COMMENT */
-
-#else /* All others... */
- debug(F100,"screenc calling clear","",0);
- clear();
- debug(F100,"screenc clear ok","",0);
-#endif /* QNX */
-#endif /* VMS */
- debug(F100,"screenc setup ok","",0);
- debug(F100,"screenc doing first move","",0);
- move(CW_BAN,0); /* Display the banner */
- debug(F110,"screenc myhost",myhost,0);
-#ifdef TCPSOCKET
- debug(F110,"screenc myipaddr",myipaddr,0);
-#endif /* TCPSOCKET */
-#ifdef HPUX1010
- debug(F100,"screenc calling first printw...","",0);
-/* Right here is where HP-UX 10.10 libxcurse.1 Rev 76.20 hangs... */
-#endif /* HPUX1010 */
- if (myhost[0]) {
-#ifdef TCPSOCKET
- if (!myipaddr[0]
-#ifdef OS2
- /* We need to perform this test because on non-TCP/IP */
- /* systems the call to getlocalipaddr() results in a */
- /* DNS Lookup which takes several minutes to time out */
- && net &&
- (xnet == NET_TCPA || xnet == NET_TCPB
-#ifdef SSHBUILTIN
- || xnet == NET_SSH
-#endif /* SSHBUILTIN */
- )
-#endif /* OS2 */
- )
- getlocalipaddr();
- if (myipaddr[0] && strcmp((char *)myhost,(char *)myipaddr))
- printw("%s, %s [%s]",versio,(char *)myhost,(char *)myipaddr);
- else
-#endif /* TCPSOCKET */
- printw("%s, %s",versio,(char *)myhost);
- } else {
- printw("%s",versio);
- }
-#ifdef HPUX1010
- debug(F100,"screenc first printw returns","",0);
-#endif /* HPUX1010 */
- move(CW_DIR,3);
- printw("Current Directory: %s",zgtdir());
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) zgtdir() );
-#endif /* K95G */
-#endif /* KUI */
- if (net) {
- move(CW_LIN,8);
- printw("Network Host: %s",
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "(unknown)") :
-#endif /* NEWFTP */
- ttname
- );
- } else {
- move(CW_LIN,0);
- printw("Communication Device: %s",ttname);
- }
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_LIN, (long) ttname );
-#endif /* K95G */
-#endif /* KUI */
-
- if (net) {
- move(CW_SPD,8);
- printw("Network Type: ");
- } else {
- move(CW_SPD,1);
- printw("Communication Speed: ");
- }
- move(CW_SPD,22); /* Serial speed or network type */
- if (net) {
-#ifdef NETCONN
- int secure = 0;
- char * xname;
- if (xnet > nnetname)
- xname = "[ERROR]";
- else
- xname = netname[xnet];
-#ifdef NEWFTP
- if (ftp) {
- if (ftpissecure())
- secure = 1;
- } else
-#endif /* NEWFTP */
- if (0
-#ifdef SSHBUILTIN
- || IS_SSH()
-#endif /* SSHBUILTIN */
-#ifdef CK_ENCRYPTION
- || ck_tn_encrypting() && ck_tn_decrypting()
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- || tls_active_flag || ssl_active_flag
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
-#ifdef CK_ENCRYPTION
- || ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_ENCRYPTION */
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
- ) {
- secure = 1;
- }
- if (secure) {
-#ifdef KUI
-#ifndef K95G
- char buf[30];
- sprintf(buf,"%s (SECURE)",xname);
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) buf
- );
-#endif /* K95G */
-#endif /* KUI */
- printw("%s (SECURE)",xname);
- } else {
- printw("%s",xname);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) xname
- );
-#endif /* K95G */
-#endif /* KUI */
- }
-#else
- printw("(network)");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(network)"
- );
-#endif /* K95G */
-#endif /* KUI */
-#endif /* NETCONN */
- } else {
- if (speed < 0L)
- speed = ttgspd();
- if (speed > 0L) {
- if (speed == 8880) {
- printw("75/1200");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "75/1200"
- );
-#endif /* K95G */
-#endif /* KUI */
- } else {
- char speedbuf[64] ;
- sprintf(speedbuf, "%ld", speed);
- printw("%s",speedbuf);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) speedbuf
- );
-#endif /* K95G */
-#endif /* KUI */
- }
- } else {
- printw("unknown");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(unknown)"
- );
-#endif /* K95G */
-#endif /* KUI */
- }
- }
- move(CW_PAR,14);
- printw("Parity: %s",ftp ? "none" : parnam((char)parity));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef CK_TIMERS
- if (/* rttflg && */ protocol == PROTO_K) {
- move(CW_TMO, 9); printw("RTT/Timeout:"); }
-#endif /* CK_TIMERS */
- move(CW_TYP,11); printw("File Type:");
- move(CW_SIZ,11); printw("File Size:");
- move(CW_PCD, 8);
- clrtoeol();
- pctlbl = (what & W_SEND);
- printw("%s:", pctlbl ? "Percent Done" : "Bytes So Far");
-
-#ifdef XYZ_INTERNAL
- move(CW_BAR, 1);
- printw("%10s Protocol:", ftp ? "FTP" : ptab[protocol].p_name);
-#endif /* XYZ_INTERNAL */
-#ifdef CK_PCT_BAR
- if (thermometer) {
- oldpct = pct = 0;
- move(CW_BAR,22);
- printw(" ...10...20...30...40...50...60...70...80...90..100");
- move(CW_BAR,22+56);
- }
-#endif /* CK_PCT_BAR */
- move(CW_TR, 1); printw("Estimated Time Left:");
- move(CW_CP, 2); printw("Transfer Rate, CPS:");
- move(CW_WS, 8); printw("Window Slots:%s",
- ((protocol == PROTO_K) && !ftp) ?
- "" : " N/A"
- );
- move(CW_PT, 9); printw("Packet Type:");
- if (ftp || protocol != PROTO_K) {
- move(CW_PT,22);
- printw("%s", "N/A");
- move(CW_PC, 11); printw("I/O Count:");
- move(CW_PL, 10); printw("I/O Length:");
- } else {
- move(CW_PC, 8); printw("Packet Count:");
- move(CW_PL, 7); printw("Packet Length:");
- }
-#ifndef COMMENT
- move(CW_PR, 9); printw("Error Count:");
-#else
- move(CW_PR, 2); printw("Packet Retry Count:");
-#endif
-#ifdef COMMENT
- move(CW_PB, 2); printw("Packet Block Check:");
-#endif /* COMMENT */
- move(CW_ERR,10); printw("Last Error:");
- move(CW_MSG, 8); printw("Last Message:");
- if (xfrmsg) {
- move(CW_MSG, 22); printw("%s",xfrmsg);
- makestr(&xfrmsg,NULL);
- }
- move(CW_INT, 0);
- if (!xfrint) {
- printw("(Transfer interruption is disabled)");
- } else {
-#ifdef CK_NEED_SIG
- printw(
-"<%s>X to cancel file, <%s>Z to cancel group, <%s><CR> to resend last packet",
- dbchr(escape), dbchr(escape), dbchr(escape)
- );
- move(CW_INT + 1, 0);
- printw(
-"<%s>E to send Error packet, ^C to quit immediately, <%s>L to refresh screen.",
- dbchr(escape), dbchr(escape)
- );
-#else /* !CK_NEED_SIG */
- move(CW_INT, 0);
-#ifdef OS2
- if (protocol == PROTO_K) {
- printw(
-"X to cancel file, Z to cancel group, <Enter> to resend last packet,"
- );
- }
-#else /* !OS2 */
-#ifdef VMS /* In VMS avoid bottom line */
- printw(
-"X: Cancel this file; E: Cancel transfer; ^C: Quit now; ^W: Refresh screen."
- );
-#else
- printw(
-"X to cancel file, Z to cancel group, <CR> to resend last packet,"
- );
-#endif /* VMS */
-#endif /* OS2 */
-
-#ifndef VMS
- move(CW_INT + 1, 0);
- if (protocol == PROTO_K) {
- printw(
-"E to send Error packet, ^C to quit immediately, ^L to refresh screen."
- );
- } else {
- printw("^C to cancel file transfer.");
- }
-#endif /* VMS */
-#endif /* CK_NEED_SIG */
- }
- refresh();
- cendw = 0;
- }
- debug(F101,"SCREENC switch","",f);
- debug(F000,"SCREENC c","",c);
- debug(F101,"SCREENC n","",n);
-
- len = strlen(s); /* Length of argument string */
- switch (f) { /* Handle our function code */
- case SCR_FN: /* Filename */
- oldpct = pct = 0L; /* Reset percents */
-#ifdef GFTIMER
- gtv = (CKFLOAT) -1.0;
- /* oldgtv = (CKFLOAT) -1.0; */
-#else
- gtv = -1L;
- /* oldgtv = -1L; */
-#endif /* GFTIMER */
- oldwin = -1;
- fsiz = (CK_OFF_T)-1; /* Invalidate previous file size */
- move(CW_PCD,22); /* Erase percent done from last time */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PCD, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_FFC, (long) 0 );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- move(CW_SIZ,22); /* Erase file size from last time */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) 0 );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- move(CW_ERR,22); /* And last error message */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) "" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-#ifdef COMMENT
-#ifdef STREAMING
- if (protocol == PROTO_K && streamok) {
- move(CW_BAR, 1);
-#ifdef XYZ_INTERNAL
- printw(" Kermit STREAMING:");
-#else
- printw(" STREAMING:");
-#endif /* XYZ_INTERNAL */
- }
-#endif /* STREAMING */
-#endif /* COMMENT */
-
- if (what & W_SEND) { /* If we're sending... */
-#ifdef NEWFTP
- if (what & W_FTP) { /* FTP */
- move(CW_NAM,10);
- printw(" FTP PUT:");
- } else
-#endif /* NEWFTP */
-#ifdef CK_RESEND
- switch (sendmode) { /* Kermit */
- case SM_RESEND:
- move(CW_NAM,10);
- printw(" RESENDING:");
- break;
- default:
- move(CW_NAM,10);
- printw(" SENDING:");
- break;
- }
-#else
- move(CW_NAM,10);
- printw(" SENDING:");
-#endif /* CK_RESEND */
-
- } else if (what & W_RECV) { /* If we're receiving... */
-#ifdef NEWFTP
- if (what & W_FTP) { /* FTP */
- move(CW_NAM,10);
- printw(" FTP GET:");
- } else {
-#endif /* NEWFTP */
- move(CW_NAM,10);
- printw(" RECEIVING:");
-#ifdef NEWFTP
- }
- } else if (what == (W_FTP|W_FT_DELE)) {
- move(CW_NAM,10);
- printw("FTP DELETE:");
-#endif /* NEWFTP */
- } else { /* If we don't know... */
- move(CW_NAM,10); /* (should never see this) */
- printw(" File Name:");
- }
- move(CW_NAM,22); /* Display the filename */
- if (len > 57) {
- printw("%.55s..",s);
- len = 57;
- } else printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- q = len; /* Remember name length for later */
- clrtoeol();
- scrft(); /* Display file type (can change) */
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_AN: /* File as-name */
- if (q + len + 4 < 58) { /* Will fit */
- move(CW_NAM, 22 + q);
- printw(" => %s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- } else { /* Too long */
- move(CW_NAM, 22); /* Overwrite previous name */
- q = 0;
- if (len + 4 > 57) { /* wg15 */
- printw(" => %.51s..",s); /* wg15 */
- len = 53; /* wg15 */
- } else printw(" => %s",s); /* wg15 */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- }
- q += len + 4; /* Remember horizontal position */
- clrtoeol();
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_FS: /* File size */
- fsiz = n;
- move(CW_SIZ,22);
- if (fsiz > (CK_OFF_T)-1) {
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) n );
-#endif /* K95G */
-#endif /* KUI */
- printw("%s",ckfstoa(n));
- }
- if (fsiz == -2L) {
- printw("POSSIBLY EXCEEDS LOCAL FILE SIZE LIMIT");
- }
- clrtoeol();
-#ifdef COMMENT
- move(CW_PCD, 8);
- if (fsiz > (CK_OFF_T)-1) { /* Put up percent label */
- pctlbl = 1;
- clrtoeol();
- printw("Percent Done:");
- }
-#else
- move(CW_PCD, 8);
- clrtoeol();
- if (fsiz > (CK_OFF_T)-1) { /* Put up percent label */
- pctlbl = 1;
- printw("Percent Done:");
- } else {
- pctlbl = 0;
- printw("Bytes So Far:");
- }
-#endif /* COMMENT */
- clrtoeol();
- scrft(); /* File type */
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_PT: /* Packet type or pseudotype */
- if (spackets < 5) {
- extern int sysindex;
- extern struct sysdata sysidlist[];
- /* Things that won't change after the 4th packet */
- move(CW_PAR,22);
- printw("%s",parnam((char)parity));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-#ifdef COMMENT
- move(CW_PB, 22); /* Block check on this packet */
- if (bctu == 4)
- printw("B");
- else
- printw("%d",bctu);
- clrtoeol();
-#endif /* COMMENT */
- if (
-#ifdef NEWFTP
- (ftp && (spackets == 1 || rpackets == 1)) ||
-#endif /* NEWFTP */
- spackets == 4
- ) {
- move(CW_LIN,8);
- if (
-#ifdef NEWFTP
- ftp ||
-#endif /* NEWFTP */
- ((protocol == PROTO_K) && (sysindex > -1))
- ) {
- if (net) {
- move(CW_LIN,8);
- printw("Network Host: %s (%s)",
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "") :
-#endif /* NEWFTP */
- ttname,
-#ifdef NEWFTP
- ftp ? ftp_srvtyp :
-#endif /* NEWFTP */
- sysidlist[sysindex].sid_name
- );
- } else {
- move(CW_LIN,0);
- printw("Communication Device: %s (remote host is %s)",
- ttname,
- sysidlist[sysindex].sid_name
- );
- }
- clrtoeol();
- }
- }
- }
-#ifdef CK_TIMERS
- if (/* rttflg && */ protocol == PROTO_K) {
- long xx;
- if (
-#ifdef STREAMING
- streaming && oldwin != -2
-#else
- 0
-#endif /* STREAMING */
- ) {
- move(CW_TMO, 22);
- printw("00 / 00");
- clrtoeol();
- } else {
- xx = (rttdelay + 500) / 1000;
- if (xx != oldrtt || rcvtimo != oldtim) {
- move(CW_TMO, 22);
- printw("%02ld / %02d", xx, rcvtimo);
- oldrtt = xx;
- oldtim = rcvtimo;
- clrtoeol();
- }
- }
- }
-#endif /* CK_TIMERS */
-
- x = (what & W_RECV) ? /* Packet length */
- rpktl+(protocol==PROTO_K?1:0) :
- spktl;
- if (x != oldlen) { /* But only if it changed. */
- move(CW_PL, 22);
- printw("%d",x);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PL, (long) x );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldlen = x;
- }
- move(CW_PC, 22); /* Packet count (always). */
-
- printw("%d", (what & W_RECV) ? rpackets : spackets);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PC, (long) spackets );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-
- if (protocol == PROTO_K && !ftp) { /* Window slots */
- char ws[16];
- int flag;
- flag = 0;
-#ifdef STREAMING
- if (streaming) {
- if (oldwin != -2) {
- sprintf(ws,"STREAMING");
- flag = 1;
- oldwin = -2;
- }
- } else
-#endif /* STREAMING */
- if (wcur != oldwin) {
- sprintf(ws, "%d of %d", wcur < 1 ? 1 : wcur, wslotn);
- flag = 1;
- oldwin = wcur;
- }
- if (flag) {
- move(CW_WS, 22);
- printw("%s", ws);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_WS, (long) ws );
-#endif /* K95G */
-#endif /* KUI */
- }
- }
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Retry count, if changed */
- move(CW_PR, 22);
- printw("%d",errors);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PR, (long) errors );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldtry = errors;
- }
- /* Sender's packet type */
- if (!ftp && (c != oldtyp && c != 'Y' && c != 'N')) {
- char type[2];
- sprintf(type, "%c",c);
- move(CW_PT,22);
- printw("%s", type);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PT, (long) type );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldtyp = c;
- }
- switch (c) { /* Now handle specific packet types */
- case 'S': /* Beginning of transfer */
- fcnt = fbyt = 0L; /* Clear counters */
-#ifdef GFTIMER
- gtv = -1.0;
-#else /* GFTIMER */
- gtv = -1L; /* And old/new things... */
-#endif /* GFTIMER */
- oldpct = pct = 0L;
- break;
-
- case 'Z': /* or EOF */
- debug(F101,"screenc SCR_PT Z pktnum","",n);
- debug(F101,"screenc SCR_PT Z oldpct","",oldpct);
- debug(F101,"screenc SCR_PT Z pct","",pct);
- case 'D': /* Data packet */
- if (fsiz > 0L) { /* Show percent done if known */
- oldpct = pct; /* Remember previous percent */
- howfar = ffc;
-#ifdef CK_RESEND
- if (what & W_SEND) /* Account for PSEND or RESEND */
- howfar += sendstart;
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- /* Percent done, to be displayed... */
- if (c == 'Z') {
- if (!discard && !cxseen && !czseen) pct = 100L;
- } else
- pct = (fsiz > 99L) ? (howfar / (fsiz / 100L)) : 0L;
- if (pct > 100L || /* Allow for expansion and */
- (oldpct == 99L && pct < 0L)) /* other boundary conditions */
- pct = 100L;
- if (pct != oldpct) /* Only do this 100 times per file */
- updpct(oldpct, pct);
- } else {
- move(CW_PCD,22);
- printw("%s", ckfstoa(ffc));
- }
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) howfar);
-#endif /* K95G */
-#endif /* KUI */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- break;
-
- case '%': /* Timeouts, retransmissions */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
-
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- move(CW_PR, 22);
- printw("%d",errors);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR, (long) errors
- );
-#endif /* K95G */
-#endif /* KUI */
- }
- oldtry = errors;
- if (s) if (*s) {
- move(CW_ERR,22);
- printw("%s",s);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_ERR, (long) s);
-#endif /* K95G */
-#endif /* KUI */
- }
- break;
-
- case 'E': /* Error packet */
-#ifdef COMMENT
- move(CW_ERR,22); /* Print its data field */
- if (*s) {
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- }
- clrtoeol();
-#endif /* COMMENT */
- fcnt = fbyt = 0L; /* So no bytes for this file */
- break;
- case 'Q': /* Crunched packet */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- move(CW_ERR,22);
- printw("Damaged Packet");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Damaged Packet"
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- break;
- case 'q': /* Ctrl-C or connection lost */
- move(CW_MSG,22);
- clrtoeol();
- if (!s) s = "";
- printw("%s", *s ? s : "User interruption or connection lost");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) s
- );
-#endif /* K95G */
-#endif /* KUI */
- break;
- case 'T': /* Timeout */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- move(CW_ERR,22);
- printw("Timeout %d sec",rcvtimo);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Timeout"
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- move(CW_PR, 22);
- printw("%d",errors);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR, (long) errors
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldtry = errors;
- }
- break;
- default: /* Others, do nothing */
- break;
- }
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_ST: /* File transfer status */
- debug(F101,"screenc SCR_ST c","",c);
- debug(F101,"screenc SCR_ST success","",success);
- debug(F101,"screenc SCR_ST cxseen","",cxseen);
-#ifdef COMMENT
- move(CW_PCD,22); /* Update percent done */
- if (c == ST_OK) { /* OK, print 100 % */
- if (pctlbl)
- updpct(oldpct,100);
- else
- printw("%s", ckfstoa(ffc));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
-#endif /* K95G */
-#endif /* KUI */
- pct = 100;
- oldpct = 0;
- } else if (fsiz > 0L) /* Not OK, update final percent */
-/*
- The else part writes all over the screen -- howfar and/or fsiz have
- been reset as a consequence of the not-OKness of the transfer.
-*/
- if (pctlbl)
- updpct(oldpct, (howfar * 100L) / fsiz);
- clrtoeol();
-#else
- if (c == ST_OK) { /* OK, print 100 % */
- move(CW_PCD,22); /* Update percent done */
- if (pctlbl) {
- if (oldpct == 0) /* Switching from "bytes so far" */
- clrtoeol(); /* to "percent done"... */
- updpct(oldpct,100);
- } else
- printw("%s", ckfstoa(ffc));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = 100;
- oldpct = 0;
-#endif /* COMMENT */
- clrtoeol();
- }
-#endif /* COMMENT */
-
-#ifdef COMMENT
-/* No, leave it there so they can read it */
- move(CW_MSG,22); /* Remove any previous message */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_MSG, (long) "" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
-#endif /* COMMENT */
-
- move(CW_TR, 22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TR, (long) "" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
-
- switch (c) { /* Print new status message */
- case ST_OK: /* Transfer OK */
- fcnt++; /* Count this file */
- if (what == (W_FTP|W_FT_DELE)) {
- move(CW_MSG,22);
- clrtoeol();
- printw("Delete OK");
- } else {
- fbyt += ffc;
- move(CW_MSG,22);
- clrtoeol();
- printw("Transfer OK");
- }
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) "Transfer OK"
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
- return;
-
- case ST_DISC: /* Discarded */
- move(CW_ERR,22);
- printw("File discarded");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "File discarded"
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_INT: /* Interrupted */
- move(CW_ERR,22);
- printw("Transfer interrupted");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Transfer interrupted"
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_SKIP: /* Skipped */
- move(CW_ERR,22);
- if (n > 0 && n < nskreason)
- printw("File skipped (%s)",skreason[n]);
- else
- printw("File skipped");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "File skipped"
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_ERR: /* Error message */
- move(CW_ERR,22);
- if (!s) s = (char *)epktmsg;
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_REFU: /* Refused */
- move(CW_ERR,22);
- if (*s) {
- char errbuf[64] ;
- sprintf( errbuf, "Refused, %s", s ) ;
- printw("%s", errbuf);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long) CW_ERR,(long) errbuf);
-#endif /* K95G */
-#endif /* KUI */
- } else {
- printw("Refused");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Refused");
-#endif /* K95G */
-#endif /* KUI */
- }
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_INC:
- move(CW_ERR,22);
- printw("Incomplete");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Incomplete");
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_MSG:
- move(CW_MSG,22);
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_MSG,(long)s);
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
- return;
-
- default: /* Bad call */
- move(CW_ERR,22);
- printw("*** screen() called with bad status ***");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR,
- (long) "*** screen() called with bad status ***" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh(); return;
- }
-
- case SCR_TC: { /* Transaction complete */
- char msgbuf[128];
- move(CW_CP,22); /* Overall transfer rate */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, tfcps);
-#endif /* K95G */
-#endif /* KUI */
- printw("%s", ckfstoa(tfcps));
- clrtoeol();
- if (success) {
- move(CW_MSG,22); /* Print statistics in message line */
- clrtoeol();
- }
- if (success) {
- sprintf(msgbuf,
- "SUCCESS. Files: %ld, Bytes: %s, %ld CPS",
- filcnt - filrej,
- ckfstoa(fbyt),
- tfcps
- );
- printw("%s", msgbuf);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) msgbuf
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-
- }
- move(CW_TR, 1);
- printw(" Elapsed Time: %s",hhmmss((long)
-#ifdef GFTIMER
- (fptsecs + 0.5)
-#else
- tsecs
-#endif /* GFTIMER */
- ));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_TR,
- (long) hhmmss((long)
-#ifdef GFTIMER
- (fptsecs + 0.5)
-#else
- tsecs
-#endif /* GFTIMER */
- ));
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- move(23,0); clrtoeol(); /* Clear instructions lines */
- move(22,0); clrtoeol(); /* to make room for prompt. */
- refresh();
-
-#ifdef GFTIMER
- oldgtv = (CKFLOAT) -1.0;
-#else
- oldgtv = -1L;
-#endif /* GFTIMER */
-
-#ifndef VMSCURSE
- debug(F100,"screenc endwin A","",0);
- endwin();
-#ifdef COMMENT
-/*
- Why and when was this call to conres() added? It makes no sense,
- and it breaks echoing on Solaris 8.
-*/
-#ifdef SOLARIS
- conres();
-#endif /* SOLARIS */
-#endif /* COMMENT */
-#endif /* VMSCURSE */
-
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
- cendw = 1;
- if (xfrbel) bleep(BP_NOTE); /* Close window, then beep. */
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- ft_win = 0; /* Window closed. */
- return;
- }
- case SCR_EM: /* Error packet (fatal) */
- move (CW_ERR,22);
- printw("FAILURE: %s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- if (xfrbel) bleep(BP_FAIL);
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh(); return;
-
- case SCR_QE: /* Quantity equals */
- case SCR_TU: /* Undelimited text */
- case SCR_TN: /* Text delimited at start */
- case SCR_TZ: /* Text delimited at end */
- return; /* (ignored in fullscreen display) */
-
- case SCR_MS: /* Message from Kermit partner */
- move(CW_MSG,22);
- printw("%s",s);
- clrtoeol(); refresh(); return;
-
- case SCR_XD: /* X-packet data */
- pct = oldpct = 0;
- move(CW_NAM,22);
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh(); return;
-
- case SCR_CW: /* Close Window */
- clrtoeol(); move(23,0); clrtoeol(); move(22,0); clrtoeol();
- refresh();
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
-
-#ifndef VMSCURSE
- debug(F100,"screenc endwin B","",0);
- endwin();
-#endif /* VMSCURSE */
- ft_win = 0; /* Flag that window is closed. */
- cendw = 1; return;
-
- case SCR_CD: /* Display current directory */
- move(CW_DIR,22);
- printw("%s", s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- default: /* Bad call */
- move (CW_ERR,22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "*** screen() called with bad function code ***"
- );
-#endif /* K95G */
-#endif /* KUI */
- printw("*** screen() called with bad function code ***");
- clrtoeol(); refresh(); return;
- }
-}
-#endif /* CK_CURSES */
-
-#ifdef KUI
-#ifdef CK_ANSIC
-void
-screeng(int f, char c,long n,char *s)
-#else
-CKVOID
-screeng(f,c,n,s)
-int f; /* argument descriptor */
-char c; /* a character or small integer */
-long n; /* a long integer */
-char *s; /* a string */
-#endif /* CK_ANSIC */
-/* screeng() */ {
-#ifdef CK_SSL
- extern int tls_active_flag, ssl_active_flag;
-#endif /* CK_SSL */
-#ifdef RLOGCODE
- extern int ttnproto;
-#endif /* RLOGCODE */
- static int q = 0;
- static CK_OFF_T fsiz = (CK_OFF_T)-1; /* Copy of file size */
- static long fcnt = 0L; /* Number of files transferred */
- static long fbyt = 0L; /* Total file bytes of all files transferred */
- static CK_OFF_T howfar = (CK_OFF_T)0; /* How much of file xfer'd so far */
- static int pctlbl = 0L; /* Percent done vs Bytes so far */
- long cps = 0L;
-
- int net = 0;
- int xnet = 0;
- int ftp = 0;
- int len; /* Length of string */
- int errors = 0; /* Error counter */
- int x; /* Worker */
-
- debug(F101,"screeng cinit","",cinit);
- debug(F101,"screeng cendw","",cendw);
-
- if (!s) s = ""; /* Always do this. */
-
- ftp = (what & W_FTP) ? 1 : 0; /* FTP or Kermit */
- net = network || ftp;
- xnet = ftp ? 1 : nettype; /* NET_TCPB == 1 */
-
- if (cinit == 0 || cendw > 0) { /* Handle borderline cases... */
- if (f == SCR_CW) { /* Close window, but it's not open */
- ft_win = 0;
- return;
- }
- debug(F111,"screeng A",s,f);
- if (f == SCR_EM ||
- (f == SCR_PT && c == 'E')) { /* Fatal error before window open */
- conoll(""); conoc('?'); conoll(s); return; /* Regular display */
- }
- }
- if (cinit == 0) { /* Only call initscr() once */
- /* Check these now -- if they are defined but not numeric */
- /* they can crash curses */
- cendw = 1; /* New window needs repainting */
- debug(F100,"screeng calling initscr","",0);
- initscr(); /* Initialize curses. */
- debug(F100,"screeng initscr ok","",0);
- cinit++; /* Remember curses was initialized. */
- }
- ft_win = 1; /* Window is open */
- if (repaint) {
-#ifdef CK_WREFRESH
-/*
- This totally repaints the screen, just what we want, but we can only
- do this with real curses, and then only if clearok() and wrefresh() are
- provided in the curses library.
-*/
- RestoreCmdMode();
-#else /* No CK_WREFRESH */
-/*
- Kermit's do-it-yourself method, works with all types of fullscreen
- support, but does not repaint all the fields. For example, the filename
- is lost, because it arrives at a certain time and never comes again, and
- Kermit presently does not save it anywhere. Making this method work for
- all fields would be a rather major recoding task, duplicating what curses
- already does, and would add a lot of complexity and storage space.
-*/
- cendw = 1;
-#endif /* CK_WREFRESH */
- repaint = 0;
- }
- if (cendw) { /* endwin() was called previously */
- debug(F100,"screeng setup ok","",0);
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) zgtdir() );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_LIN,
- (long) (
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "(unknown)") :
-#endif /* NEWFTP */
- ttname) );
-
- if (net) {
-#ifdef NETCONN
- int secure = 0;
- char * xname;
- if (xnet > nnetname)
- xname = "[ERROR]";
- else
- xname = netname[xnet];
-#ifdef NEWFTP
- if (ftp) {
- if (ftpissecure())
- secure = 1;
- } else
-#endif /* NEWFTP */
- if (0
-#ifdef SSHBUILTIN
- || IS_SSH()
-#endif /* SSHBUILTIN */
-#ifdef CK_ENCRYPTION
- || ck_tn_encrypting() && ck_tn_decrypting()
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- || tls_active_flag || ssl_active_flag
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
-#ifdef CK_ENCRYPTION
- || ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_ENCRYPTION */
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
- ) {
- secure = 1;
- }
- if (secure) {
- char buf[30];
- sprintf(buf,"%s (SECURE)",xname);
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) buf
- );
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) xname
- );
- }
-#else
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(network)"
- );
-#endif /* NETCONN */
- } else {
- if (speed < 0L)
- speed = ttgspd();
- if (speed > 0L) {
- if (speed == 8880) {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "75/1200"
- );
- } else {
- char speedbuf[64] ;
- sprintf(speedbuf, "%ld", speed);
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) speedbuf
- );
- }
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(unknown)"
- );
- }
- }
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
- pctlbl = (what & W_SEND);
- cendw = 0;
- }
- debug(F101,"SCREENC switch","",f);
- debug(F000,"SCREENC c","",c);
- debug(F101,"SCREENC n","",n);
-
- len = strlen(s); /* Length of argument string */
- switch (f) { /* Handle our function code */
- case SCR_FN: /* Filename */
- oldpct = pct = 0L; /* Reset percents */
-#ifdef GFTIMER
- gtv = (CKFLOAT) -1.0;
- /* oldgtv = (CKFLOAT) -1.0; */
-#else
- gtv = -1L;
- /* oldgtv = -1L; */
-#endif /* GFTIMER */
- oldwin = -1;
- fsiz = (CK_OFF_T)-1L; /* Invalidate previous file size */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PCD, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_FFC, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) "" );
-
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
- q = len; /* Remember name length for later */
- scrft(); /* Display file type (can change) */
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_AN: /* File as-name */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_FS: /* File size */
- fsiz = n;
- if (fsiz > (CK_OFF_T)-1) {
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) n );
- }
- if (fsiz > (CK_OFF_T)-1) { /* Put up percent label */
- pctlbl = 1;
- } else {
- pctlbl = 0;
- }
- scrft(); /* File type */
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_PT: /* Packet type or pseudotype */
- if (spackets < 5) {
- extern int sysindex;
- extern struct sysdata sysidlist[];
- /* Things that won't change after the 4th packet */
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
- if (
-#ifdef NEWFTP
- (ftp && (spackets == 1 || rpackets == 1)) ||
-#endif /* NEWFTP */
- spackets == 4
- ) {
- if (
-#ifdef NEWFTP
- ftp ||
-#endif /* NEWFTP */
- ((protocol == PROTO_K) && (sysindex > -1))
- ) {
- char msgbuf[128];
- if (net) {
- sprintf(msgbuf,"Network Host: %s (%s)",
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "") :
-#endif /* NEWFTP */
- ttname,
-#ifdef NEWFTP
- ftp ? ftp_srvtyp :
-#endif /* NEWFTP */
- sysidlist[sysindex].sid_name
- );
- } else {
- sprintf(msgbuf,
- "Communication Device: %s (remote host is %s)",
- ttname,
- sysidlist[sysindex].sid_name
- );
- }
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_LIN,
- (long) msgbuf
- );
- }
- }
- }
-#ifdef CK_TIMERS
- if (/* rttflg && */ protocol == PROTO_K) {
- long xx;
- if (
-#ifdef STREAMING
- streaming && oldwin != -2
-#else
- 0
-#endif /* STREAMING */
- ) {
- char msgbuf[64];
- sprintf(msgbuf,"00 / 00");
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_TMO,
- (long) msgbuf
- );
- } else {
- xx = (rttdelay + 500) / 1000;
- if (xx != oldrtt || rcvtimo != oldtim) {
- char msgbuf[64];
- sprintf(msgbuf,"%02ld / %02d", xx, rcvtimo);
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_TMO,
- (long) msgbuf
- );
- oldrtt = xx;
- oldtim = rcvtimo;
- clrtoeol();
- }
- }
- }
-#endif /* CK_TIMERS */
-
- x = (what & W_RECV) ? /* Packet length */
- rpktl+(protocol==PROTO_K?1:0) :
- spktl;
- if (x != oldlen) { /* But only if it changed. */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PL, (long) x );
- oldlen = x;
- }
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PC, (long) spackets );
-
- if (protocol == PROTO_K && !ftp) { /* Window slots */
- char ws[16];
- int flag;
- flag = 0;
-#ifdef STREAMING
- if (streaming) {
- if (oldwin != -2) {
- sprintf(ws,"STREAMING");
- flag = 1;
- oldwin = -2;
- }
- } else
-#endif /* STREAMING */
- if (wcur != oldwin) {
- sprintf(ws, "%d of %d", wcur < 1 ? 1 : wcur, wslotn);
- flag = 1;
- oldwin = wcur;
- }
- if (flag) {
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_WS, (long) ws );
- }
- }
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Retry count, if changed */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PR, (long) errors );
- oldtry = errors;
- }
- /* Sender's packet type */
- if (!ftp && (c != oldtyp && c != 'Y' && c != 'N')) {
- char type[2];
- sprintf(type, "%c",c);
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PT, (long) type );
- oldtyp = c;
- }
- switch (c) { /* Now handle specific packet types */
- case 'S': /* Beginning of transfer */
- fcnt = fbyt = 0L; /* Clear counters */
-#ifdef GFTIMER
- gtv = -1.0;
-#else /* GFTIMER */
- gtv = -1L; /* And old/new things... */
-#endif /* GFTIMER */
- oldpct = pct = 0L;
- break;
-
- case 'Z': /* or EOF */
- debug(F101,"screeng SCR_PT Z pktnum","",n);
- debug(F101,"screeng SCR_PT Z oldpct","",oldpct);
- debug(F101,"screeng SCR_PT Z pct","",pct);
- case 'D': /* Data packet */
- if (fsiz > 0L) { /* Show percent done if known */
- oldpct = pct; /* Remember previous percent */
- howfar = ffc;
-#ifdef CK_RESEND
- if (what & W_SEND) /* Account for PSEND or RESEND */
- howfar += sendstart;
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- /* Percent done, to be displayed... */
- if (c == 'Z') {
- if (!discard && !cxseen && !czseen) pct = 100L;
- } else
- pct = (fsiz > 99L) ? (howfar / (fsiz / 100L)) : 0L;
- if (pct > 100L || /* Allow for expansion and */
- (oldpct == 99L && pct < 0L)) /* other boundary conditions */
- pct = 100L;
- if (pct != oldpct) /* Only do this 100 times per file */
- updpct(oldpct, pct);
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
- }
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) howfar);
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- break;
-
- case '%': /* Timeouts, retransmissions */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
-
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR,
- (long) errors
- );
- }
- oldtry = errors;
- if (s) if (*s) {
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_ERR, (long) s);
- }
- break;
-
- case 'E': /* Error packet */
- if (*s) {
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
- }
- fcnt = fbyt = 0L; /* So no bytes for this file */
- break;
- case 'Q': /* Crunched packet */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Damaged Packet"
- );
- break;
- case 'q': /* Ctrl-C or connection lost */
- if (!s) s = "";
- if (!*s) s = "User interruption or connection lost";
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) s
- );
- break;
- case 'T': /* Timeout */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Timeout"
- );
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR, (long) errors
- );
- oldtry = errors;
- }
- break;
- default: /* Others, do nothing */
- break;
- }
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_ST: /* File transfer status */
- debug(F101,"screeng SCR_ST c","",c);
- debug(F101,"screeng SCR_ST success","",success);
- debug(F101,"screeng SCR_ST cxseen","",cxseen);
-#ifdef COMMENT
- if (c == ST_OK) { /* OK, print 100 % */
- if (pctlbl)
- updpct(oldpct,100);
- else
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
- pct = 100;
- oldpct = 0;
- } else if (fsiz > 0L) /* Not OK, update final percent */
-/*
- The else part writes all over the screen -- howfar and/or fsiz have
- been reset as a consequence of the not-OKness of the transfer.
-*/
- if (pctlbl)
- updpct(oldpct, (howfar * 100L) / fsiz);
-#else
- if (c == ST_OK) { /* OK, print 100 % */
- if (pctlbl) {
- updpct(oldpct,100);
- } else
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
-#ifdef COMMENT
- pct = 100;
- oldpct = 0;
-#endif /* COMMENT */
- }
-#endif /* COMMENT */
-
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TR, (long) "" );
-
- switch (c) { /* Print new status message */
- case ST_OK: /* Transfer OK */
- fcnt++; /* Count this file */
- if (what == (W_FTP|W_FT_DELE)) {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) "Delete OK"
- );
- } else {
- fbyt += ffc;
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) "Transfer OK"
- );
- }
- return;
-
- case ST_DISC: /* Discarded */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "File discarded"
- );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_INT: /* Interrupted */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Transfer interrupted"
- );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_SKIP: { /* Skipped */
- char errbuf[64] ;
- if (n > 0 && n < nskreason)
- sprintf( errbuf, "File skipped, (%s)", skreason[n] ) ;
- else
- sprintf( errbuf, "File skipped" ) ;
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) errbuf
- );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
- }
- case ST_ERR: /* Error message */
- if (!s) s = (char *)epktmsg;
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_REFU: /* Refused */
- if (*s) {
- char errbuf[64] ;
- sprintf( errbuf, "Refused, %s", s ) ;
- KuiSetProperty(KUI_FILE_TRANSFER,(long) CW_ERR,(long) errbuf);
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Refused");
- }
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_INC:
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Incomplete");
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_MSG:
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_MSG,(long)s);
- return;
-
- default: /* Bad call */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR,
- (long) "*** screen() called with bad status ***" );
- return;
- }
-
- case SCR_TC: { /* Transaction complete */
- char msgbuf[128];
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, tfcps);
- if (success) {
- sprintf(msgbuf,
- "SUCCESS. Files: %s, Bytes: %ld, %ld CPS",
- filcnt - filrej,
- ckfstoa(fbyt),
- tfcps
- );
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) msgbuf
- );
- }
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_TR,
- (long) hhmmss((long)
-#ifdef GFTIMER
- (fptsecs + 0.5)
-#else
- tsecs
-#endif /* GFTIMER */
- ));
-
-#ifdef GFTIMER
- oldgtv = (CKFLOAT) -1.0;
-#else
- oldgtv = -1L;
-#endif /* GFTIMER */
-
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
- cendw = 1;
- if (xfrbel) bleep(BP_NOTE); /* Close window, then beep. */
- ft_win = 0; /* Window closed. */
- return;
- }
- case SCR_EM: /* Error packet (fatal) */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
- if (xfrbel) bleep(BP_FAIL);
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case SCR_QE: /* Quantity equals */
- case SCR_TU: /* Undelimited text */
- case SCR_TN: /* Text delimited at start */
- case SCR_TZ: /* Text delimited at end */
- return; /* (ignored in fullscreen display) */
-
- case SCR_XD: /* X-packet data */
- pct = oldpct = 0;
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
- return;
-
- case SCR_CW: /* Close Window */
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
-
- ft_win = 0; /* Flag that window is closed. */
- cendw = 1; return;
-
- case SCR_CD: /* Display current directory */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) s );
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- default: /* Bad call */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "*** screen() called with bad function code ***"
- );
- return;
- }
-}
-#endif /* KUI */
-#endif /* MAC */
-
-#endif /* NOXFER */
-
-#ifndef CK_CURPOS
-/* Dummies for when cursor control is not supported */
-int
-ck_curpos(row, col) {
- return(-1);
-}
-
-int
-ck_cls() {
- return(-1);
-}
-
-int
-ck_cleol() {
- return(-1);
-}
-#endif /* CK_CURPOS */
-
-#ifndef NOIKSD
-#ifdef IKSDB
-
-struct iksdbfld dbfld[] = {
- /* Offset Length Type */
- { DB_FLAGS, dB_FLAGS, DBT_HEX }, /* 0 db_FLAGS Flags */
- { DB_ATYPE, dB_ATYPE, DBT_HEX }, /* 1 db_ATYPE Auth type */
- { DB_AMODE, dB_AMODE, DBT_HEX }, /* 3 db_AMODE Auth mode */
- { DB_STATE, dB_STATE, DBT_HEX }, /* 2 db_STATE State */
- { DB_MYPID, dB_MYPID, DBT_HEX }, /* 5 db_MYPID PID */
- { DB_SADDR, dB_SADDR, DBT_HEX }, /* 4 db_SADDR Server address */
- { DB_CADDR, dB_CADDR, DBT_HEX }, /* 6 db_CADDR Client address */
- { DB_START, dB_START, DBT_DAT }, /* 7 db_START Session start */
- { DB_LASTU, dB_LASTU, DBT_DAT }, /* 8 db_LASTU Last update */
- { DB_ULEN, dB_ULEN, DBT_HEX }, /* 9 db_ULEN Username length */
- { DB_DLEN, dB_DLEN, DBT_HEX }, /* 10 db_DLEN Directory name length */
- { DB_ILEN, dB_ILEN, DBT_HEX }, /* 11 db_ILEN Info length */
- { DB_PAD1, dB_PAD1, DBT_UND }, /* 12 db_PAD1 (Reserved) */
- { DB_USER, dB_USER, DBT_STR }, /* 13 db_USER Username */
- { DB_DIR, dB_DIR, DBT_STR }, /* 14 db_DIR Current Directory */
- { DB_INFO, dB_INFO, DBT_STR } /* 15 db_INFO State-specific info */
-};
-
-static char lcknam[CKMAXPATH+1]; /* Lockfile pathname */
-static char tmplck[CKMAXPATH+1]; /* Temporary lockfile name */
-
-static char * updmode = /* Update mode for fopen() */
-#ifdef OS2
- "r+b"
-#else
-#ifdef VMS
- "r+b"
-#else
- "r+"
-#endif /* VMS */
-#endif /* OS2 */
- ;
-
-/* D B I N I T -- Initialize the IKSD database... */
-
-int
-dbinit() {
- extern int dbinited;
- int x = 0;
- debug(F110,"dbinit dbdir 1",dbdir,0);
- debug(F110,"dbinit dbfile 1",dbfile,0);
- if (dbinited)
- return(0);
-#ifdef OS2
- if (!dbdir) {
-#ifdef NT
- char * p = NULL;
- if (!isWin95()) {
- p = getenv("SystemRoot");
- } else {
- p = getenv("winbootdir");
- if (!p) p = getenv("windir");
- }
- if (!p) p = "C:/";
- dbdir = malloc(strlen(p)+2);
- strcpy(dbdir,p); /* safe */
- p = dbdir;
- while (*p) {
- if (*p == '\\')
- *p = '/';
- p++;
- }
- if (*(p-1) != '/' ) {
- *p++ = '/';
- *p = '\0';
- }
-#else /* NT */
- makestr(&dbdir,"C:/");
-#endif /* NT */
- }
-#else /* OS2 */
- if (!dbdir)
- makestr(&dbdir,IK_DBASEDIR);
-#endif /* OS2 */
-
- if (!dbfile) {
- char * s = "";
- x = strlen(dbdir);
- if (dbdir[x-1] != '/') {
- s = "/";
- x++;
- }
- x += (int)strlen(IK_DBASEFIL);
- dbfile = (char *)malloc(x+1);
- sprintf(dbfile,"%s%s%s",dbdir,s,IK_DBASEFIL);
- }
- debug(F110,"dbinit dbdir 2",dbdir,0);
- debug(F110,"dbinit dbfile 2",dbfile,0);
- mypid = getpid(); /* Get my pid */
- debug(F101,"dbinit mypid","",mypid);
-
- if (!myhexip[0]) { /* Set my hex IP address */
-#ifdef TCPSOCKET
- extern unsigned long myxipaddr;
- if (getlocalipaddr() > -1) {
- myip = myxipaddr;
- sprintf(myhexip,"%08lx",myip); /* (Needs fixing for IPv6) */
- } else
-#endif /* TCPSOCKET */
- ckstrncpy(myhexip,"00000000",9);
- }
- debug(F111,"dbinit myip",myhexip,myip);
- if (!peerhexip[0]) { /* Get peer's hex IP address */
-#ifdef TCPSOCKET
- extern unsigned long peerxipaddr;
- if (ckgetpeer()) {
- peerip = peerxipaddr;
- sprintf(peerhexip,"%08lx",peerip); /* (Needs fixing for IPv6) */
- debug(F111,"dbinit peerip",peerhexip,peerip);
- } else {
- debug(F101,"dbinit ckgetpeer failure","",errno);
- ckstrncpy(peerhexip,"00000000",9);
- }
-#else
- ckstrncpy(peerhexip,"00000000",9);
-#endif /* TCPSOCKET */
- }
- debug(F111,"dbinit peerip",peerhexip,peerip);
- debug(F101,"dbinit dbenabled","",dbenabled);
- if (dbenabled && inserver) {
- mydbslot = getslot();
- debug(F111,"dbinit getslot",ckitoa(ikdbopen),x);
- if (ikdbopen) dbinited = 1;
- }
- return(0);
-}
-
-/* U P D S L O T -- Update slot n */
-
-/*
- Opens the database if necessary, seeks to slot n, writes current record
- and adds current time to last-update field. n is the record sequence number
- (0, 1, 2, ...), not the seek pointer. Returns -1 on failure, 0 on success.
-*/
-int
-updslot(n) int n; { /* Update our slot */
- int rc = 0;
- CK_OFF_T position;
-
- debug(F111,"updslot","ikdbopen",ikdbopen);
- if (!ikdbopen) /* Not if not ok */
- return(0);
- if (!dbfp) { /* Open database if not open */
- dbfp = fopen(dbfile,updmode); /* In update no-truncate mode */
- if (!dbfp) {
- debug(F110,"updslot fopen failed",dbfile,0);
- ikdbopen = 0;
- return(-1);
- }
- }
- /* debug(F111,"updslot dbfile",dbfile,dbfp); */
- position = n * DB_RECL;
- if (CKFSEEK(dbfp,position,0) < 0) { /* Seek to desired slot */
- debug(F111,"updslot fseek failed",dbfile,mydbseek);
- ikdbopen = 0;
- rc = -1;
- } else {
- /* Update the update time */
- strncpy(&dbrec[dbfld[db_LASTU].off],
- ckdate(),
- dbfld[db_LASTU].len
- );
- if (fwrite(dbrec,1,DB_RECL,dbfp) < DB_RECL) { /* Write the record */
- debug(F110,"updslot fwrite failed",dbfile,0);
- ikdbopen = 0;
- rc = -1;
- } else { /* Flush the write */
- fflush(dbfp);
- }
- }
- return(rc);
-}
-
-/* I N I T S L O T -- Initialize slot n with my info */
-
-int
-initslot(n) int n; { /* Initialize slot */
- int k;
-#ifdef TCPSOCKET
- extern unsigned long peerxipaddr;
-#endif /* TCPSOCKET */
-
- debug(F101,"initslot","",n);
-
-#ifdef USE_MEMCPY
- memset(dbrec,32,DB_RECL);
-#else
- for (k = 0; k < DB_RECL; k++)
- dbrec[k] = '\040';
-#endif /* USE_MEMCPY */
-
- myflags = DBF_INUSE; /* Set in-use flag */
- mystate = W_NOTHING;
- myatype = 0L;
- myamode = 0L;
-
- k = dbfld[db_FLAGS].len; /* Length of flags field */
- strncpy(&dbrec[dbfld[db_FLAGS].off],ulongtohex(myflags,k),k);
-
- k = dbfld[db_ATYPE].len;
- strncpy(&dbrec[dbfld[db_ATYPE].off],ulongtohex(myatype,k),k);
-
- k = dbfld[db_AMODE].len;
- strncpy(&dbrec[dbfld[db_AMODE].off],ulongtohex(myamode,k),k);
-
- k = dbfld[db_STATE].len;
- strncpy(&dbrec[dbfld[db_STATE].off],ulongtohex(mystate,k),k);
-
- k = dbfld[db_SADDR].len;
- strncpy(&dbrec[dbfld[db_SADDR].off],ulongtohex(myip,k),k);
-
-#ifdef TCPSOCKET
- ckgetpeer();
- k = dbfld[db_CADDR].len;
- strncpy(&dbrec[dbfld[db_CADDR].off],ulongtohex(peerxipaddr,k),k);
-#else
- k = dbfld[db_CADDR].len;
- strncpy(&dbrec[dbfld[db_CADDR].off],ulongtohex(0L,k),k);
-#endif /* TCPSOCKET */
-
- k = dbfld[db_MYPID].len;
- strncpy(&dbrec[dbfld[db_MYPID].off],ulongtohex(mypid,k),k);
-
- k = dbfld[db_START].len;
- strncpy(&dbrec[dbfld[db_START].off],ckdate(),k);
-
- k = dbfld[db_ULEN].len;
- strncpy(&dbrec[dbfld[db_ULEN].off],"0000",4);
-
- k = dbfld[db_DLEN].len;
- strncpy(&dbrec[dbfld[db_DLEN].off],"0000",4);
-
- k = dbfld[db_ILEN].len;
- strncpy(&dbrec[dbfld[db_ILEN].off],"0000",4);
-
- strncpy(&dbrec[dbfld[db_INFO].off],"INIT",4);
- return(updslot(n));
-}
-
-int
-slotstate(x,s1,s2,s3) int x; char *s1, *s2, *s3; {
- int k, l1, l2, l3, z;
- mystate = x;
- debug(F101,"slotstate ikdbopen","",ikdbopen);
- if (!ikdbopen)
- return(-1);
- if (!s1) s1 = "";
- l1 = strlen(s1);
- if (!s2) s2 = "";
- l2 = strlen(s2);
- if (!s3) s3 = "";
- l3 = strlen(s3);
- strncpy(&dbrec[DB_STATE],ulongtohex(mystate,4),4);
- k = dbfld[db_ILEN].len;
- z = l1 + l2 + l3 + 2;
- if (z > dB_INFO)
- z = dB_INFO;
- strncpy(&dbrec[DB_ILEN],ulongtohex((unsigned long)z,k),k);
- k = dbfld[db_INFO].len;
- z = dbfld[db_INFO].off;
- if (l1 <= k) {
- lset(&dbrec[z],s1,l1+1,32);
- z += l1+1;
- k -= l1+1;
- if (l2 <= k) {
- lset(&dbrec[z],s2,l2+1,32);
- z += l2+1;
- k -= l2+1;
- if (l3 <= k)
- lset(&dbrec[z],s3,k,32);
- }
- }
-#ifdef DEBUG
- if (deblog) {
- char buf[128];
- int i;
- strncpy(buf,&dbrec[DB_INFO],127);
- buf[127] = NUL;
- for (i = 126; i > 0 && buf[i] == 32; i--) buf[i] = 0;
- debug(F111,"slotstate",buf,mystate);
- }
-#endif /* DEBUG */
- z = updslot(mydbslot);
- debug(F101,"slotstate updslot","",z);
- return(z);
-}
-
-int
-slotdir(s1,s2) char * s1, * s2; { /* Update current directory */
- int k, len1, len2;
- if (!ikdbopen)
- return(-1);
- if (!s1) s1 = "";
- if (!s2) s2 = "";
- len1 = strlen(s1);
- len2 = strlen(s2);
- k = dbfld[db_DLEN].len;
- strncpy(&dbrec[DB_DLEN],ulongtohex((unsigned long)(len1+len2),k),k);
- k = dbfld[db_DIR].len;
- if (len1 > 0) {
- lset(&dbrec[dbfld[db_DIR].off],s1,len1,32);
- lset(&dbrec[dbfld[db_DIR].off+len1],s2,k-len1,32);
- } else {
- lset(&dbrec[dbfld[db_DIR].off],s2,k,32);
- }
- return(updslot(mydbslot));
-}
-
-/* F R E E S L O T -- Free slot n */
-
-int
-freeslot(n) int n; {
- int k;
- if (!ikdbopen)
- return(0);
- dbflags = 0L;
- if (n == mydbslot) {
- dbflags = myflags & ~DBF_INUSE;
- dbflags &= ~DBF_LOGGED;
- }
- k = dbfld[db_FLAGS].len;
- strncpy(&dbrec[dbfld[db_FLAGS].off],ulongtohex(dbflags,k),k);
- return(updslot(n));
-}
-
-/* G E T S L O T -- Find a free database slot; returns slot number */
-
-#ifdef UNIX
-#include <fcntl.h> /* For creat() */
-#endif /* UNIX */
-
-int
-getslot() { /* Find a free slot for us */
- FILE * rfp = NULL; /* Returns slot number (0, 1, ...) */
- char idstring[64]; /* PID string buffer (decimal) */
- char pidbuf[64], * s;
- int j, k, n, x, rc = -1;
- int lockfd, tries, haveslot = 0;
- long lockpid;
- CK_OFF_T i;
- /* char ipbuf[17]; */
-
- if (!myhexip[0]) /* Set my hex IP address if not set */
- ckstrncpy((char *)myhexip,"7F000001",33);
- sprintf(idstring,"%08lx:%010ld\n",myip,mypid);
- debug(F110,"getslot idstring", idstring, 0);
-
- /* Make temporary lockfile name IP.PID (hex.hex) */
- /* This should fit in 14 chars -- huge PIDs are usually not possible */
- /* on 14-char filename systems. */
-
- sprintf(tmplck,"%s%08lx.%lx",dbdir,myip,mypid);
- debug(F110,"getslot tempfile",tmplck,0);
-
- /* Make a temporary file */
-
- lockfd = creat(tmplck, 0600); /* BUT THIS ISN'T PORTABLE */
- if (lockfd < 0) {
- debug(F111,"getslock temp lockfile create failure", tmplck, errno);
- return(-1);
- }
- /* Write my (decimal) PID into the temp file */
-
- write(lockfd,idstring,(int)strlen(idstring));
- if (close(lockfd) < 0) { /* Close lockfile */
- debug(F101,"getslot error closing temp lockfile", "", errno);
- return(-1);
- }
- sprintf(lcknam,"%s%s",dbdir,IK_LOCKFILE); /* Build lockfile name */
- debug(F110,"getslot lockfile",lcknam,0);
-
- rfp = fopen(lcknam,"r"); /* See if lockfile exists */
- if (rfp) { /* If so... */
- rset(pidbuf,"",64,0);
- x = fread(pidbuf,1,63,rfp); /* Read ID string from it */
- fclose(rfp); /* and close it quickly */
- debug(F110,"getslot lock exists",pidbuf,0);
- if (x > 0) { /* If we have a PID, check it */
- char * s = pidbuf;
- while (*s) {
- if (islower(*s)) *s = toupper(*s);
- if (*s == ':') {
- *s = NUL;
- debug(F110,"getslot lock IP",pidbuf,0);
- debug(F110,"gteslot my IP",myhexip,0);
- if (!strcmp(pidbuf,myhexip)) { /* Same IP address? */
- lockpid = atol(s+1); /* Yes, now get PID */
- debug(F101,"getslot lockpid","",lockpid);
-
- /* Check if PID lockpid on this computer is alive */
- x = zchkpid(lockpid);
- if (!x) {
- debug(F100,"getslot PID stale,removing lock","",0);
- unlink(lcknam);
- }
- break;
- }
- }
- s++;
- }
- } else {
- debug(F111,"getslot lockfile open failure",lcknam,errno);
- }
- }
- /* Try IK_LCKTRIES (16) times to rename temp file to lockfile */
-
- for (tries = IK_LCKTRIES; tries > 0; tries--) {
- if (zrename(tmplck,lcknam) == 0)
- break;
- debug(F101,"getslot database locked by pid", "", dbpid);
- sleep(IK_LCKSLEEP);
- }
- if (tries < 1) { /* Couldn't */
- debug(F110,"getslot create lock failure",lcknam,0);
- return(-1);
- }
- /* Have lock, open database */
-
- debug(F110,"getslot has lock",lcknam,0); /* Have lock */
-
- if (!dbfile)
- return(-1);
-
- /* If database doesn't exist, create it. */
-
- debug(F110,"getslot dbfile",dbfile,0);
- if (zchki(dbfile) < 0) {
- debug(F110,"getslot creating new database",dbfile,0);
- x = creat(dbfile,0660);
- if (x < 0) {
- debug(F111,"getslot creat() failed", dbfile, errno);
- goto xslot;
- }
- close(x);
- }
- dbfp = fopen(dbfile,updmode); /* Open it in update mode */
- if (!dbfp) {
- debug(F111,"getslot fopen failed",dbfile,errno);
- goto xslot;
- }
- /* Now find a free (or new) slot... */
-
- dblastused = 0L; /* Seek pointer to last record inuse */
- mydbseek = 0L; /* Seek pointer for my record */
-
- /* Quickly read the whole database; n = record counter, i = seek pointer */
-
- for (n = 0, i = 0; !feof(dbfp); i += DB_RECL, n++) {
- x = fread(dbrec,1,DB_RECL,dbfp); /* Read a record */
- if (x < 1) /* EOF not caught by feof() */
- break;
-#ifndef NOFTRUNCATE
- if (x != DB_RECL) { /* Watch out for trailing junk */
- debug(F101,"getslot bad size","",x); /* (Shouldn't happen...) */
-#ifdef COHERENT
- chsize(fileno(dbfp),i);
-#else
- ftruncate(fileno(dbfp),(CK_OFF_T)i);
-#endif /* COHERENT */
- x = 0;
- CKFSEEK(dbfp,i,0);
- break;
- }
-#endif /* NOFTRUNCATE */
- debug(F101,"getslot record","",n);
- k = dbfld[db_FLAGS].off;
- j = dbfld[db_FLAGS].len;
- dbflags = hextoulong(&dbrec[k],j);
- debug(F001,"getslot dbflags","",dbflags);
- k = dbfld[db_MYPID].off;
- j = dbfld[db_MYPID].len;
- dbpid = hextoulong(&dbrec[k],j);
- debug(F001,"getslot dbpid","",dbpid);
- k = dbfld[db_SADDR].off;
- j = dbfld[db_SADDR].len;
- dbip = hextoulong(&dbrec[k],j);
- debug(F001,"getslot dbip","",dbip);
-
- if (dbflags & DBF_INUSE) { /* Remember last slot in use */
- x = 0; /* Make sure it's REALLY in use */
- if (dbpid == mypid && dbip == myip) { /* Check for PID == my PID */
- x = 1;
- debug(F101,"getslot record pid","",dbpid);
- } else { /* Or for stale PID */
- x = zchkpid(dbpid);
- debug(F101,"getslot zchkpid()","",x);
- }
- if (!x) { /* Bogus record */
- x = freeslot(n);
- debug(F101,"getslot stale record pid: freeslot()","",x);
- if (x > -1 && !haveslot)
- dbflags = 0;
- } else { /* It's really in use */
- dblastused = i;
- }
- }
- if (!haveslot) { /* If I don't have a slot yet */
- if (!(dbflags & DBF_INUSE)) { /* Claim this one */
- debug(F101,"getslot free slot", "", n);
- haveslot = 1;
- mydbseek = i;
- mydbslot = n; /* But keep going... */
- }
- }
- }
- /* Come here with i == seek pointer to first record after eof */
-
- if (!haveslot) { /* Found no free slot so add to end */
- debug(F101,"getslot new slot","",n);
- haveslot = 1;
- mydbseek = i;
- mydbslot = n;
- }
- ikdbopen = 1; /* OK to make database entries */
- debug(F101,"getslot records","",n);
- debug(F101,"getslot dblastused","",dblastused);
- debug(F101,"getslot i","",i);
-
- /* Trim stale records from end */
-
-#ifndef NOFTRUNCATE
- if (i > dblastused+DB_RECL) {
- debug(F101,"getslot truncating at","",dblastused+DB_RECL);
-#ifdef COHERENT
- x = chsize(fileno(dbfp),dblastused+DB_RECL);
-#else
- x = ftruncate(fileno(dbfp),(CK_OFF_T)(dblastused+DB_RECL));
-#endif /* COHERENT */
- if (x < 0) /* (Not fatal) */
- debug(F101,"getslot ftruncate failed", "", errno);
- }
-#endif /* NOFTRUNCATE */
-
- /* Initialize my record */
-
- if (initslot(mydbslot) < 0) {
- debug(F101,"getslot initslot() error","",n);
- ikdbopen = 0;
- goto xslot;
- }
- debug(F101,"getslot OK","",mydbslot);
- rc = mydbslot; /* OK return code */
-
- xslot: /* Unlock the database and return */
- if (unlink(lcknam) < 0) {
- debug(F111,"getslot lockfile removal failed",lcknam,errno);
- rc = -1;
- }
- return(rc);
-}
-#endif /* IKSDB */
-#endif /* NOIKSD */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusx.c.printw b/ckermit-9.0.302-build/ckermit-9.0.302/ckuusx.c.printw
deleted file mode 100644
index d332bed..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusx.c.printw
+++ /dev/null
@@ -1,9718 +0,0 @@
-#include "ckcsym.h"
-
-/* C K U U S X -- "User Interface" common functions. */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- This module contains user interface functions needed by both the interactive
- user interface and the command-line-only user interface, as well as the
- screen-control routines (curses and equivalent).
-*/
-
-/* Includes */
-
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckuusr.h"
-#include "ckcxla.h"
-
-#ifndef NOHTERMCAP
-#ifdef NOTERMCAP
-#define NOHTERMCAP
-#else
-#ifndef BSD44
-#define NOHTERMCAP
-#else
-#ifdef __bsdi__
-#define NOHTERMCAP
-#else
-#ifdef OPENBSD
-#define NOHTERMCAP
-#else
-#ifdef MACOSX
-#define NOHTERMCAP
-#endif /* MACOSX */
-#endif /* OPENBSD */
-#endif /* __bsdi__ */
-#endif /* BSD44 */
-#endif /* NOTERMCAP */
-#endif /* NOHTERMCAP */
-
-#ifndef NOTERMCAP
-#ifdef BSD44
-#ifndef NOHTERMCAP
-#include <termcap.h>
-#endif /* NOHTERMCAP */
-#endif /* BSD44 */
-#else /* !BSD44 */
-#ifdef linux
-#include <term.h>
-#endif /* linux */
-#endif /* NOTERMCAP */
-
-#ifdef OS2
-#include <string.h>
-_PROTOTYP(char * os2_gethostname, (void));
-#define getpid _getpid
-#endif /* OS2 */
-#ifdef BSD44
-#include <errno.h>
-#endif /* BSD44 */
-
-extern xx_strp xxstring;
-
-#ifdef OS2
-#include "ckcnet.h"
-#else /* OS2 */
-_PROTOTYP( char * ckgetpeer, (VOID));
-_PROTOTYP(int getlocalipaddr, (void));
-_PROTOTYP(int istncomport, (void));
-#ifndef NOCKGETFQHOST
-_PROTOTYP( char * ckgetfqhostname,(char *));
-#endif /* NOCKGETFQHOST */
-#ifndef NETCONN
-/*
- We should just pull in ckcnet.h here, but it causes a conflict with curses.h.
-*/
-#ifdef TCPSOCKET
-#define NETCONN
-#else
-#ifdef SUNX25
-#define NETCONN
-#else
-#ifdef STRATUSX25
-#define NETCONN
-#else
-#ifdef IBMX25
-#define NETCONN
-#else
-#ifdef HPX25
-#define NETCONN
-#else
-#ifdef DECNET
-#define NETCONN
-#else
-#ifdef NPIPE
-#define NETCONN
-#else
-#ifdef CK_NETBIOS
-#define NETCONN
-#ifdef SUPERLAT
-#define NETCONN
-#else
-#endif /* SUPERLAT */
-#endif /* TCPSOCKET */
-#endif /* SUNX25 */
-#endif /* STRATUSX25 */
-#endif /* IBMX25 */
-#endif /* HPX25 */
-#endif /* DECNET */
-#endif /* NPIPE */
-#endif /* CK_NETBIOS */
-#endif /* NETCONN */
-#endif /* OS2 */
-
-#ifndef TCPSOCKET
-#ifdef MULTINET
-#define TCPSOCKET
-#endif /* MULTINET */
-#ifdef DEC_TCPIP
-#define TCPSOCKET
-#endif /* DEC_TCPIP */
-#ifdef WINTCP
-#define TCPSOCKET
-#endif /* WINTCP */
-#ifdef TCPWARE
-#define TCPSOCKET
-#endif /* TCPWARE */
-#endif /* TCPSOCKET */
-
-#ifdef OS2
-#ifdef NT
-#include <windows.h>
-#include <tapi.h>
-#include "ckntap.h"
-#else /* NT */
-#define INCL_VIO
-#include <os2.h>
-#endif /* NT */
-#ifdef COMMENT /* Would you believe */
-#undef COMMENT /* <os2.h> defines this ? */
-#endif /* COMMENT */
-#ifdef CK_NETBIOS
-#include "ckonbi.h"
-#endif /* CK_NETBIOS */
-
-#include "ckocon.h"
-extern ascreen commandscreen;
-#ifdef KUI
-#include "ikui.h"
-#endif /* KUI */
-#endif /* OS2 */
-
-#ifdef NT
-#include "cknwin.h"
-#endif /* NT */
-#ifdef OS2
-#include "ckowin.h"
-#include "ckosyn.h"
-#endif /* OS2 */
-
-#ifdef CK_TAPI
-extern int tttapi;
-extern int tapipass;
-#endif /* CK_TAPI */
-
-#ifdef CK_KERBEROS
-#include "ckuath.h"
-#endif /* CK_KERBEROS */
-
-#ifndef WINTCP
-#include <signal.h>
-#endif /* WINTCP */
-
-#ifdef VMS
-#include <descrip.h>
-#include <ssdef.h>
-#include <stsdef.h>
-#ifndef OLD_VMS
-#include <lib$routines.h> /* Not for VAX C 2.3 */
-#else
-#include <libdef.h>
-#endif /* OLD_VMS */
-#ifdef WINTCP
-#include <signal.h>
-#endif /* WINTCP */
-#endif /* VMS */
-
-#ifdef DCLFDOPEN
-/* fdopen() needs declaring because it's not declared in <stdio.h> */
-_PROTOTYP( FILE * fdopen, (int, char *) );
-#endif /* DCLFDOPEN */
-
-#ifdef DCLPOPEN
-/* popen() needs declaring because it's not declared in <stdio.h> */
-_PROTOTYP( FILE * popen, (char *, char *) );
-#endif /* DCLPOPEN */
-
-int tt_crd = 0; /* Carriage return display */
-int tt_lfd = 0; /* Linefeed display */
-int interrupted = 0; /* Interrupted from keyboard flag */
-int fxd_inited = 0; /* Fullscreen stuff initialized */
-
-#ifdef DEBUG
-char debfil[CKMAXPATH+1]; /* Debugging log file name */
-#endif /* DEBUG */
-
-#ifdef TLOG
-char trafil[CKMAXPATH+1]; /* Transaction log file name */
-#endif /* TLOG */
-
-char sesfil[CKMAXPATH+1]; /* Session log file name */
-
-#ifdef CKLOGDIAL
-char diafil[CKMAXPATH+1]; /* Connection log file name */
-char cxlogbuf[CXLOGBUFL+1]; /* Connection log record buffer */
-int cx_active = 0; /* Connection is active */
-extern int dialog;
-#endif /* CKLOGDIAL */
-
-#ifdef DYNAMIC
-static char *cmdstr = NULL; /* Place to build generic command */
-#else
-#ifdef pdp11
-static char cmdstr[256];
-#else
-static char cmdstr[4096];
-#endif /* pdp11 */
-#endif /* DYNAMIC */
-
-#ifndef NOMSEND
-char fspec[CMDBL+4]; /* Filename string for \v(filespec) */
-int fspeclen = CMDBL;
-#else
-char fspec[CKMAXPATH+4];
-int fspeclen = CKMAXPATH;
-#endif /* NOMSEND */
-
-char * rfspec = NULL; /* Received filespec: local */
-char * prfspec = NULL; /* Preliminary rfspec */
-char * sfspec = NULL; /* Sent filespec: local */
-char * psfspec = NULL; /* Preliminary sfspec */
-char * srfspec = NULL; /* Received filespec: remote */
-char * psrfspec = NULL; /* Preliminary srfspec */
-char * rrfspec = NULL; /* Sent filespec: remote */
-char * prrfspec = NULL; /* Preliminary rrfspec */
-
-int success = 1, /* Command success/failure flag */
- cmdlvl = 0, /* Command level */
- action = 0, /* Action selected on command line */
- slogts = 0, /* Session-log timestamps on/off */
- slognul = 0, /* Session-log null-terminated lines */
-#ifdef UNIX
- sessft = XYFT_T, /* Session log file type */
-#else
- sessft = XYFT_B, /* (text for UNIX binary for others) */
-#endif /* UNIX */
- pflag = 1, /* Print prompt */
- msgflg = 1; /* Print informational messages */
-
-extern int xaskmore, saveask; /* More-prompting */
-
-#ifdef CK_APC
-extern int apcactive;
-#endif /* CK_APC */
-/* External variables */
-
-extern int local, quiet, binary, network, what, parity, xitsta, escape,
- tlevel, bgset, backgrd, xsuspend, cmdint, nettype, seslog, dfloc;
-
-extern int cmd_rows, cmd_cols, xcmdsrc;
-
-extern char cmdfil[];
-
-#ifdef VMS
-extern int batch;
-#endif /* VMS */
-
-#ifdef datageneral /* 2/12/92 ENH */
-#include <sysid.h>
-extern int con_reads_mt, conint_ch, conint_avl;
-#endif /* datageneral */
-
-extern long speed;
-
-extern char ttname[], *dftty, *cmarg, **cmlist, *versio, myhost[];
-
-#ifndef NOCSETS
-extern int fcharset, tcharset, xfrxla;
-extern struct csinfo fcsinfo[], tcsinfo[];
-#endif /* NOCSETS */
-
-#ifdef OS2
-extern unsigned char colorcmd;
-#endif /* OS2 */
-
-#ifdef NOXFER
-
-int fdispla = XYFD_N;
-
-#else /* NOXFER is not defined */
-
-#ifdef OS2 /* File transfer display type */
-int fdispla = XYFD_C; /* Curses (fullscreen) if we have it */
-#else
-#ifdef CK_CURSES
-int fdispla = XYFD_C;
-#else
-int fdispla = XYFD_S; /* Otherwise CRT */
-#endif /* CK_CURSES */
-#endif /* OS2 */
-
-extern struct ck_p ptab[];
-extern int protocol, xfrbel, xfrint;
-
-#ifdef STREAMING
-extern int streaming, streamok;
-#endif /* STREAMING */
-
-/* Used internally */
-
-#ifdef KUI
-_PROTOTYP( VOID screeng, (int, char, long, char *) );
-#endif /* KUI */
-_PROTOTYP( VOID screenc, (int, char, CK_OFF_T, char *) );
-
-
-#ifdef CK_CURSES
-#ifndef DYNAMIC
-static char xtrmbuf[TRMBUFL]; /* tgetent() buffer */
-char * trmbuf = xtrmbuf;
-#else
-char * trmbuf = NULL;
-#endif /* DYNAMIC */
-_PROTOTYP( static VOID dpyinit, (void) );
-_PROTOTYP( static long shocps, (int, CK_OFF_T, CK_OFF_T) );
-_PROTOTYP( static CK_OFF_T shoetl, (CK_OFF_T, long, CK_OFF_T, CK_OFF_T) );
-#endif /* CK_CURSES */
-
-static int ft_win = 0; /* Fullscreen file transfer display window is active */
-
-/* Variables declared here */
-
-static char * skreason[] = {
- "", /* 0 */
- "Remote file not older", /* SKP_DAT */
- "Identical modification times", /* SKP_EQU */
- "Type", /* SKP_TYP */
- "Size", /* SKP_SIZ */
- "Name collision", /* SKP_NAM */
- "Exception List", /* SKP_EXL */
- "Dot file", /* SKP_DOT */
- "Backup file", /* SKP_BKU */
- "Recovery not needed", /* SKP_RES */
- "Access denied", /* SKP_ACC */
- "Not a regular file", /* SKP_NRF */
- "Simulated", /* SKP_SIM */
- "Simulated - Remote file older", /* SKP_XUP */
- "Simulated - No remote file", /* SKP_XNX */
-};
-static int nskreason = (sizeof(skreason) / sizeof(char *));
-
-char *
-gskreason(n) int n; {
- return((n > 0 && n < nskreason) ? skreason[n] : "");
-}
-
-char pktfil[CKMAXPATH+1]; /* Packet log file name */
-
-#ifndef NOMSEND /* Multiple SEND */
-char *msfiles[MSENDMAX];
-#endif /* NOMSEND */
-
-#ifdef CK_TIMERS
-extern long rttdelay;
-extern int rttflg;
-#endif /* CK_TIMERS */
-extern int rcvtimo;
-
-#ifdef CK_RESEND
-extern int sendmode;
-extern CK_OFF_T sendstart, rs_len;
-#endif /* CK_RESEND */
-
-#ifdef CK_PCT_BAR /* File transfer thermometer */
-int thermometer = 1; /* ON by default */
-#endif /* CK_PCT_BAR */
-
-#ifdef GFTIMER
-CKFLOAT gtv = -1.0, oldgtv = -1.0;
-#else
-#ifndef OS2
-static
-#endif /* OS2 */
- long gtv = -1L, oldgtv = -1L;
-#endif /* GFTIMER */
-
-extern int server, bctu, rptflg, ebqflg, spsiz, urpsiz, wmax, czseen, cxseen,
- winlo, displa, timint, npad, ebq, bctr, rptq, atcapu, lpcapu,
- swcapu, wslotn, wslotr, rtimo, mypadn, sq, capas, rpsiz, tsecs,
- pktlog, lscapu, dest, srvdis, wslots, spackets, spktl, rpktl,
- retrans, wcur, numerrs, fsecs, whatru, crunched, timeouts,
- rpackets, fncnv, bye_active, discard, inserver, diractive, cdactive;
-
-extern long filcnt, filrej, rptn, filcps, tfcps, cps, peakcps;
-extern CK_OFF_T ffc, tfc, fsize;
-
-long oldcps = 0L;
-
-extern CHAR *rdatap, padch, seol, ctlq, mypadc, eol, *epktmsg;
-extern char *xfrmsg;
-
-#ifdef IKSDB
-FILE * dbfp = NULL; /* File pointer to database file */
-
-int dbenabled = 1; /* Flag for database is enabled */
-extern int ikdbopen; /* Flag for database is open */
-
-unsigned long mydbseek = 0L; /* Seek pointer to my record */
-int mydbslot = 0; /* My slot number */
-unsigned long myflags = 0L; /* My flags */
-unsigned long myatype = 0L; /* My authorization type */
-unsigned long myamode = 0L; /* My authorization mode */
-unsigned long mystate = 0L; /* My state (SEND, RECEIVE, etc) */
-unsigned long mypid = 0L; /* My PID */
-unsigned long myip = 0L; /* My IP address */
-unsigned long peerip = 0L; /* My peer's IP address */
-
-unsigned long dbip = 0L; /* IP address in db record */
-unsigned long dbpid = 0L; /* PID in db record */
-unsigned long dbflags = 0L; /* Flags field in db record */
-unsigned long dblastused = 0L; /* Last in-use record in db */
-char dbrec[DB_RECL]; /* Database record buffer */
-
-char * dbdir = NULL; /* Database directory */
-char * dbfile = NULL; /* Database file full pathname */
-char myhexip[33] = { NUL, NUL }; /* My IP address in hex */
-char peerhexip[33] = { NUL, NUL }; /* Client's IP address in hex */
-#endif /* IKSDB */
-
-#ifdef GFTIMER
-extern CKFLOAT fpfsecs, fptsecs, fpxfsecs;
-#else
-extern long xfsecs;
-#endif /* GFTIMER */
-#endif /* NOXFER */
-
-#ifdef TCPSOCKET
-#ifdef NEWFTP
-extern char * ftp_host, ftp_srvtyp[];
-extern int ftp_csx, ftp_csl, ftp_deb;
-#endif /* NEWFTP */
-extern char myipaddr[];
-#endif /* TCPSOCKET */
-
-#ifndef NOICP
-#ifndef NOSPL
- extern struct mtab *mactab; /* For ON_EXIT macro. */
- extern int nmac;
-#endif /* NOSPL */
-#ifdef DCMDBUF
-extern char *cmdbuf; /* Command buffer */
-#else
-extern char cmdbuf[]; /* Command buffer */
-#endif /* DCMDBUF */
-extern int cmd_quoting;
-#endif /* NOICP */
-
-#ifndef NOCCTRAP
-#ifdef NT
-#include <setjmpex.h>
-#else /* NT */
-#include <setjmp.h>
-#endif /* NT */
-#include "ckcsig.h"
-extern ckjmpbuf cmjbuf;
-#endif /* NOCCTRAP */
-
-extern int xfiletype, nscanfile;
-
-int
-shoesc(escape) int escape; {
- extern char * ccntab[]; /* C0 control character name table */
- extern int tt_escape;
- if ((escape > 0 && escape < 32) || (escape == 127)) {
- printf(" Escape character: Ctrl-%c (ASCII %d, %s): %s\r\n",
- ctl(escape),
- escape,
- (escape == 127 ? "DEL" : ccntab[escape]),
- tt_escape ? "enabled" : "disabled"
- );
- } else {
- printf(" Escape character: Code %d",escape);
- if (escape > 160 && escape < 256)
- printf(" (%c)",escape);
- printf(": %s\r\n", tt_escape ? "enabled" : "disabled");
- }
- return(0);
-}
-
-#ifndef NOXFER
-/* P R E S E T -- Reset global protocol variables */
-
-extern int recursive;
-
-#ifdef PATTERNS
-int patterns = SET_AUTO; /* Whether to use filename patterns */
-extern int g_patterns; /* For saving and restoring */
-#else
-int patterns = SET_OFF;
-#endif /* PATTERNS */
-
-#ifndef NOICP
-#ifdef CK_LABELED
-extern int g_lf_opts, lf_opts;
-#endif /* CK_LABELED */
-extern int g_matchdot, g_usepipes, usepipes;
-extern int g_binary, g_proto, g_displa, g_spath, g_rpath, g_fncnv;
-extern int g_recursive;
-extern int g_xfermode, xfermode;
-extern int g_urpsiz, g_spsizf, g_spsiz;
-extern int g_spsizr, g_spmax, g_wslotr, g_prefixing, g_fncact;
-extern int g_fnspath, g_fnrpath, g_skipbup;
-extern int nolinks;
-#ifdef CKSYMLINK
-extern int zgfs_link;
-#endif /* CKSYMLINK */
-#ifndef NOSPL
-extern int g_pflg, pwflg, g_pcpt, pwcrypt;
-extern char * g_pswd, pwbuf[];
-#endif /* NOSPL */
-#endif /* NOICP */
-
-extern int spsizf, spsizr, spmax, prefixing, fncact, fnspath, fnrpath;
-extern int moving; /* SEND criteria */
-extern char sndafter[], sndbefore[], *sndexcept[], *rcvexcept[];
-extern CK_OFF_T sndlarger, sndsmaller, calibrate;
-extern int rmailf, rprintf, skipbup;
-extern char optbuf[];
-
-#ifdef PIPESEND
-extern char * g_sfilter, * g_rfilter;
-extern char * sndfilter, * rcvfilter;
-#endif /* PIPESEND */
-extern char ** sndarray;
-
-VOID
-ftreset() {
-#ifndef NOICP
- int i;
- extern char * filefile;
- extern int reliable, xreliable, c_save, ss_save, slostart, urclear;
- extern int oopts, omode, oname, opath, kactive, autopath;
- extern char * snd_move; /* Directory to move sent files to */
- extern char * snd_rename; /* What to rename sent files to */
- extern char * rcv_move;
- extern char * rcv_rename;
- extern char * g_snd_move;
- extern char * g_snd_rename;
- extern char * g_rcv_move;
- extern char * g_rcv_rename;
-
-#ifdef CK_TMPDIR
- extern int f_tmpdir;
- extern char savdir[];
-#endif /* CK_TMPDIR */
-
-#ifdef CK_SPEED
-#ifdef COMMENT
- extern int f_ctlp;
- extern short s_ctlp[], ctlp[];
-#endif /* COMMENT */
-#endif /* CK_SPEED */
-
-#ifndef NOCSETS
- extern int fcs_save, tcs_save;
- extern int g_xfrxla, xfrxla;
-#endif /* NOCSETS */
-
-/* Restore / reset per-command file-transfer switches */
-
- makestr(&snd_move,g_snd_move);
- makestr(&rcv_move,g_rcv_move);
- makestr(&snd_rename,g_snd_rename);
- makestr(&rcv_rename,g_rcv_rename);
-
- kactive = 0; /* Kermit protocol no longer active */
- oopts = -1; /* O-Packet Options */
- omode = -1; /* O-Packet Transfer Mode */
- oname = -1; /* O-Packet Filename Options */
- opath = -1; /* O-Packet Pathname Options */
-
-#ifdef CK_RESEND
- rs_len = 0L; /* REGET position */
-#endif /* CK_RESEND */
-
-#ifdef COMMENT
-#ifdef CK_SPEED
- if (f_ctlp) {
- for (i = 0; i < 256; i++)
- ctlp[i] = s_ctlp[i];
- f_ctlp = 0;
- }
-#endif /* CK_SPEED */
-#endif /* COMMENT */
-
-#ifdef CK_TMPDIR
- if (f_tmpdir) { /* If we changed to download dir */
- zchdir((char *) savdir); /* Go back where we came from */
- f_tmpdir = 0;
- }
-#endif /* CK_TMPDIR */
-
- calibrate = 0L; /* Calibration run */
- if (xreliable > -1) {
- reliable = xreliable;
- debug(F101,"ftreset reliable","",reliable);
- }
- urclear = 0;
-
- if (autopath) { /* SET RECEIVE PATHNAMES AUTO */
- fnrpath = PATH_AUTO;
- autopath = 0;
- }
- if (filefile) { /* File list */
- zclose(ZMFILE);
- makestr(&filefile,NULL);
- }
- if (c_save > -1) { /* Block Check Type */
- bctr = c_save;
- c_save = -1;
- }
- if (ss_save > -1) { /* Slow Start */
- slostart = ss_save;
- ss_save = -1;
- }
-#ifdef CK_LABELED
- if (g_lf_opts > -1) {
- lf_opts = g_lf_opts; /* Restore labeled transfer options */
- g_lf_opts = -1;
- }
-#endif /* CK_LABELED */
-
-#ifndef NOCSETS
- if (tcs_save > -1) { /* Character sets */
- tcharset = tcs_save;
- tcs_save = -1;
- }
- if (fcs_save > -1) {
- fcharset = fcs_save;
- fcs_save = -1;
- }
- if (g_xfrxla > -1) {
- xfrxla = g_xfrxla;
- g_xfrxla = -1;
- }
- setxlatype(tcharset,fcharset); /* Translation type */
-#endif /* NOCSETS */
-
-#ifdef NETCONN
-#ifndef NOSPL
- if (g_pswd) {
- ckstrncpy(pwbuf,g_pswd,PWBUFL);
- makestr(&g_pswd,NULL);
- }
- if (g_pflg > -1) {
- pwflg = g_pflg;
- g_pflg = -1;
- }
- if (g_pcpt > -1) {
- pwcrypt = g_pcpt;
- g_pcpt = -1;
- }
-#endif /* NOSPL */
-#endif /* NETCONN */
-
- if (g_binary > -1) { /* File type */
- binary = g_binary;
- g_binary = -1;
- }
- if (g_xfermode > -1) { /* Transfer mode */
- xfermode = g_xfermode;
- g_xfermode = -1;
- }
-#ifdef PATTERNS
- if (g_patterns > -1) { /* Filename patterns */
- patterns = g_patterns;
- g_patterns = -1;
- }
-#endif /* PATTERNS */
-
- if (g_usepipes > -1) {
- usepipes = g_usepipes;
- g_usepipes = -1;
- }
- if (g_matchdot > -1) {
- matchdot = g_matchdot;
- g_matchdot = -1;
- }
- if (g_proto > -1) { /* Protocol */
- protocol = g_proto;
- g_proto = -1;
- }
- if (g_urpsiz > -1) {
- urpsiz = g_urpsiz;
- debug(F101,"ftreset restoring urpsiz","",urpsiz);
- g_urpsiz = -1;
- }
- if (g_spsizf > -1) {
- spsizf = g_spsizf;
- debug(F101,"ftreset restoring spsizf","",spsizf);
- g_spsizf = -1;
- }
- if (g_spsiz > -1) {
- spsiz = g_spsiz;
- debug(F101,"ftreset restoring spsiz","",spsiz);
- g_spsiz = -1;
- }
- if (g_spsizr > -1) {
- spsizr = g_spsizr;
- debug(F101,"ftreset restoring spsizr","",spsizr);
- g_spsizr = -1;
- }
- if (g_spmax > -1) {
- spmax = g_spmax;
- g_spmax = -1;
- }
- if (g_wslotr > -1) {
- wslotr = g_wslotr;
- g_wslotr = -1;
- }
- if (g_prefixing > -1) {
- prefixing = g_prefixing;
- g_prefixing = -1;
- }
- if (g_fncact > -1) {
- fncact = g_fncact;
- g_fncact = -1;
- }
- if (g_fncnv > -1) {
- fncnv = g_fncnv;
- g_fncnv = -1;
- }
- if (g_fnspath > -1) {
- fnspath = g_fnspath;
- g_fnspath = -1;
- }
- if (g_fnrpath > -1) {
- fnrpath = g_fnrpath;
- g_fnrpath = -1;
- }
- if (g_skipbup > -1) {
- skipbup = g_skipbup;
- g_skipbup = -1;
- }
- nolinks = 2; /* /FOLLOWLINKS is never global */
- recursive = 0; /* /RECURSIVE can never be global */
- xfiletype = -1;
-
- if (g_displa > -1) { /* File transfer display */
- fdispla = g_displa;
- g_displa = -1;
- }
- if (g_spath > -1) { /* Send pathnames */
- fnspath = g_spath;
- g_spath = -1;
- }
- if (g_rpath > -1) { /* Receive pathnames */
- fnrpath = g_rpath;
- g_rpath = -1;
- }
- if (g_fncnv > -1) { /* Filename conversion */
- fncnv = g_fncnv;
- g_fncnv = -1;
- }
-#ifdef PIPESEND
- makestr(&sndfilter,g_sfilter); /* Send filter */
- makestr(&rcvfilter,g_rfilter); /* Receive filter */
-#endif /* PIPESEND */
-
-#ifndef NOFRILLS
- rmailf = rprintf = 0; /* MAIL and PRINT modifiers for SEND */
- optbuf[0] = NUL; /* MAIL and PRINT options */
-#endif /* NOFRILLS */
-
- moving = 0; /* Reset delete-after-send indicator */
- sndafter[0] = NUL; /* Reset SEND selection switches */
- sndbefore[0] = NUL;
-
- for (i = 0; i < NSNDEXCEPT; i++) {
- if (sndexcept[i])
- free(sndexcept[i]);
- sndexcept[i] = NULL;
- if (rcvexcept[i])
- free(rcvexcept[i]);
- rcvexcept[i] = NULL;
- }
- sndlarger = (CK_OFF_T)-1;
- sndsmaller = (CK_OFF_T)-1;
- debug(F101,"present sndsmaller","",sndsmaller);
-#ifdef GFTIMER
- gtv = -1.0;
- oldgtv = -1.0;
-#else
- gtv = -1L;
- oldgtv = -1L;
-#endif /* GFTIMER */
-#endif /* NOICP */
-}
-#endif /* NOXFER */
-
-char *
-ttgtpn() { /* Get typical port name */
-/*
- Ideally this routine would be implemented in each of the cku?io.* modules,
- but that requires changing the API definition.
-*/
- return(
-#ifdef OS2
-#ifdef OS2ONLY
-"COM1"
-#else /* OS2ONLY */
-"TAPI [ name ] or COM1"
-#endif /* OS2ONLY */
-#else /* OS2 */
-#ifdef VMS
-"TXA0:, TTA0:, or LTA0:"
-#else /* VMS */
-#ifdef SOLARIS
-"/dev/cua/a"
-#else /* SOLARIS */
-#ifdef HPUX10
-"/dev/cua0p0"
-#else /* HPUX10 */
-#ifdef HPUX
-"/dev/cua00"
-#else /* HPUX */
-#ifdef __FreeBSD__
-"/dev/cuaa0"
-#else /* __FreeBSD__ */
-#ifdef __linux__
-"/dev/ttyS0"
-#else /* __linux__ */
-#ifdef BSD44
-"/dev/tty00"
-#else /* BSD44 */
-#ifdef OSK
-"/t1"
-#else /* OSK */
-#ifdef QNX
-"/dev/ser1"
-#else /* QNX */
-#ifdef QNX6
-"/dev/ser1"
-#else /* QNX6 */
-#ifdef UNIXWARE
-"/dev/term/00 or /dev/tty00"
-#else /* UNIXWARE */
-#ifdef CK_SCOV5
-"/dev/tty1A"
-#else /* CK_SCOV5 */
-#ifdef CK_SCO32V4
-"/dev/tty1A"
-#else /* CK_SCO32V4 */
-#ifdef M_XENIX
-"/dev/tty1A"
-#else /* M_XENIX */
-#ifdef AIXRS
-"/dev/tty0"
-#else /* AIXRS */
-#ifdef DGUX
-"/dev/tty00"
-#else /* DGUX */
-#ifdef datageneral
-"@con1"
-#else /* datageneral */
-#ifdef IRIX
-"/dev/ttym0"
-#else /* IRIX */
-#ifdef SUNOS4
-"/dev/ttyh0"
-#else /* SUNOS4 */
-#ifdef SV68R3V6
-"/dev/scc0"
-#else /* SV68R3V6 */
-#ifdef MOTSV88R4
-"/dev/contty00"
-#else /* MOTSV88R4 */
-#ifdef NEXT
-"/dev/cufa"
-#else
-#ifdef OSF
-"/dev/ttyd1"
-#else
-#ifdef SINIX
-"/dev/ttyc1"
-#else
-#ifdef UNIX
-"/dev/cua, /dev/acu, /dev/tty0, etc"
-#else /* UNIX */
-"(sorry no example available)"
-#endif /* UNIX */
-#endif /* SINIX */
-#endif /* OSF */
-#endif /* NEXT */
-#endif /* MOTSV88R4 */
-#endif /* SV68R3V6 */
-#endif /* SUNOS4 */
-#endif /* IRIX */
-#endif /* datageneral */
-#endif /* DGUX */
-#endif /* AIX */
-#endif /* M_XENIX */
-#endif /* CK_SCO32V4 */
-#endif /* CK_SCOV5 */
-#endif /* UNIXWARE */
-#endif /* QNX6 */
-#endif /* QNX */
-#endif /* OSK */
-#endif /* BSD44 */
-#endif /* __linux__ */
-#endif /* __FreeBSD__ */
-#endif /* HPUX */
-#endif /* HPUX10 */
-#endif /* SOLARIS */
-#endif /* VMS */
-#endif /* OS2 */
- );
-}
-
-/* C K _ E R R S T R -- Return message from most recent system error */
-
-#ifdef CKROOT
-extern int ckrooterr;
-#endif /* CKROOT */
-
-char *
-ck_errstr() {
-#ifdef USE_STRERROR
-#ifndef CK_ANSILIBS
- /* Should have been declared in <string.h> */
-_PROTOTYP( char * strerror, (int) );
-#endif /* CK_ANSILIBS */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
-#endif /* CKROOT */
- return(strerror(errno));
-#else /* !USE_STRERROR */
-#ifdef VMS
- extern char * ckvmserrstr(unsigned long);
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
-#endif /* CKROOT */
- return(ckvmserrstr(0L));
-#else /* !VMS */
-#ifdef BSD44
-#ifdef __386BSD__
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#else /* !__386BSD__ */
-#ifndef __bsdi__
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern const char *const sys_errlist[];
-#endif /* NDSYSERRLIST */
-#endif /* __bsdi__ */
-#endif /* __386BSD__ */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
- else
-#endif /* CKROOT */
- if (errno >= sys_nerr)
- return("Error number out of range");
- else
- return((char *) sys_errlist[errno]);
-#else /* !BSD44 */
-#ifdef ATTSV
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
- else
-#endif /* CKROOT */
- if (errno >= sys_nerr)
- return("Error number out of range");
- else
- return((char *) sys_errlist[errno]);
-#else /* !ATTSV */
-#ifdef BSD4
-#ifndef NDSYSERRLIST
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
- else
-#endif /* CKROOT */
- if (errno >= sys_nerr)
- return("Error number out of range");
- else
- return((char *) sys_errlist[errno]);
-#else
-#ifdef OS2
-#ifndef NDSYSERRLIST
- extern char *sys_errlist[];
-#endif /* NDSYSERRLIST */
-#ifdef NT
- extern int_sys_nerr;
-#endif /* NT */
- char *e;
-#ifdef CKROOT
- if (ckrooterr)
- return("Off limits");
-#endif /* CKROOT */
- e = (errno > -1
-#ifdef NT
- && errno <= _sys_nerr
-#endif /* NT */
- ) ?
-#ifdef NT
- (char *) sys_errlist[errno]
-#else /* NT */
- /* I don't know how to get a CLIB error string in OS/2 */
- strerror(errno)
-#endif /* NT */
- : "";
- return(e ? e : "");
-#else /* OS2 */
- return("");
-#endif /* OS2 */
-#endif /* BSD4 */
-#endif /* ATTSV */
-#endif /* BSD44 */
-#endif /* VMS */
-#endif /* USE_STRERROR */
-}
-
-#ifdef PATTERNS
-/*
- Filename pattern recognition lists for automatic text/binary switching.
- These are somewhat passe after the addition of scanfile() (7.0).
- But with the addition of FTP [M]GET, they're back in style (8.0).
-
- Although, with FTP the lists need to be used in the reverse. With
- Kermit the list is used to imply the types of the local system. Whereas
- with FTP, the list must be used to imply the type of the remote system.
- Therefore, all platforms must now support all of the lists.
-*/
-char *txtpatterns[FTPATTERNS+1] = { NULL, NULL };
-char *binpatterns[FTPATTERNS+1] = { NULL, NULL };
-/*
- Default pattern lists for each platform...
-
- NOTE: In most cases we leave ".hlp", ".ini", and ".scr" alone; although they
- are traditionally text types, they are binary in Windows. So they are
- handled by the prevailing SET FILE TYPE, rather than automatically.
- Similarly for ".dat", ".inf", and so on. Also ".ps" since PostScript files
- are not always text. ".log" is omitted since logs can be text or binary,
- except in VMS they are usually text, etc etc.
-
- Later (Sep 2003): Add PostScript to binary patterns.
-*/
-static char *txtp[SYS_MAX][FTPATTERNS] = {
- /* UNKNOWN */ {
- NULL, NULL
- },
- { /* UNIX */
- "*.txt","*.c","*.h","*.r","*.w","*.cpp","*.cc","*.ksc","*.bwr","*.upd",
- "*.html","*.htm","*.mss","*.tex","*.nr","[Mm]akefile", "*.hex", "*.hqx",
- "*.for","*.f77","*.f","*.F","*.s","*.pas","*.java","*.el","*.lisp","*.sh",
- "*.m4","*.perl","*.pl","*.pod","*.pm","*.awk","*.sno","*.spt","*.sed",
- "*.ksc","*.TXT", "*read.me", "*READ.ME", ".*", "*/.*", "*.mem","*.mac",
- NULL
- },
- { /* WIN32 */
- "*.txt","*.ksc","*.htm","*.html","*.bat","*.cmd","*.jav","*.asm", "*.hex",
- "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w",
- "*.java", "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile",
- "*.mem","*.mac","*.cc","*.pl","*.pod","*.pm","*.m4",NULL
- },
- { /* VMS */
- "*.com","*.txt","*.c", "*.for","*.pas","*.rno","*.rnh","*.mar","*.bli",
- "*.hlp","*.mss","*.doc","*.bwr","*.cld","*.hex","*.bas","*.ini","*.log",
- "*.mms","*.opt","*.ksc","*.perl","*.pl","*.pod","*.pm","*.sno","*.spt",
- "*.mem",NULL
- },
- { /* OS2 */
- "*.txt","*.ksc","*.htm","*.html","*.bat","*.cmd","*.jav","*.asm", "*.hex",
- "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w",
- "*.java", "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile",
- NULL
- },
- { /* DOS */
- "*.txt","*.ksc","*.htm","*.bat","*.cmd","*.jav","*.asm", "*.hex",
- "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w",
- "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile", NULL
- },
- { /* TOPS-10 */
- "*.cmd","*.hlp","*.doc","*.ini","*.txt","*.mac","*.for","*.sai","*.bli",
- "*.pas","*.sno","*.spt","*.pcl","*.mss","*.rno","*.b36","*.tex","*.pub",
- "*.req","*.r36","*.mem","*.bwr","*.ccl","*.ctl","*.rnh","*.ksc",NULL
- },
- { /* TOPS-20 */
- "*.cmd","*.hlp","*.doc","*.ini","*.txt","*.mac","*.for","*.sai","*.bli",
- "*.pas","*.sno","*.spt","*.pcl","*.mss","*.rno","*.b36","*.tex","*.pub",
- "*.req","*.r36","*.mem","*.bwr","*.ccl","*.ctl","*.rnh","*.ksc",NULL
- },
- { /* STRATUS VOS */
- "*.txt","*.ksc","*.htm","*.html","*.bat", "*.cmd","*.jav","*.asm","*.hex",
- "*.hqx","*.c", "*.h", "*.w", "*.java","*.bwr","*.upd","*.ttp","*.cm",
- "*.pl1","*.emacs", "read.me", "*.pl", "makefile", NULL
- },
- { /* DG AOS/VS */
- "*.txt", "*.c", "*.h", "*.w", "*.er", "*.bwr", "*.upd", "read.me",
- "*.cli", "*.ksc", NULL
- },
- { /* OSK */
- "*.c","*.cpp","*.h","*.a","*akefile", /* program sources */
- "*.for","*.f77","*.f","*.F","*.s","*.pas","*.java","*.el","*.lisp",
- "*.sh","*.perl","*.awk","*.sno","*.spt","*.sed",
- "*.txt","*.w", /* general text */
- "*.ksc","*.bwr","*.upd",
- "*.html","*.htm","*.mss","*.tex","*.nr","*.hex", "*.hqx",
- "*.TXT", "*read.me", "*READ.ME", ".*", "*/.*",
- NULL
- }
-};
-
-/* Note: .DOC added to (some) binary patterns June 1998... Microsoft wins. */
-
-static char *binp[SYS_MAX][FTPATTERNS] = {
- { /* UNKNOWN */
- NULL, NULL
- },
- { /* UNIX */
- "*.gz","*.Z","*.tgz","*.gif", "*.tar","*.zip","*.o","*.so","*.a","*.out",
- "*.exe", "*.jpg", "*.jpeg", "*.tif","*.tiff", "*.pdf", "*.so.*", "*.class",
- "*.rpm", "*.bmp", "*.bz2", "*.BMP", "*.dll", "*.doc", "*.vxd", "*.dcx",
- "*.xl*", "*.lzh", "*.lhz", "*.au", "*.voc", "*.mpg", "*.mpeg","[wk]ermit",
- "*.ps", NULL
- },
- { /* WIN32 */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.class","*.cla","*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.lzh", "*.vxd", "*.snd", "*.au", "* .voc", "*.mpg", "*.mpeg",
- "*.ps", NULL
- },
- { /* VMS */
- "*.exe","*.obj","*.bak","*.bin","*.adf","*.stb","*.mai","*.sys","*.dmp",
- "*.ps", "*.dat","*.par", NULL
- },
- { /* OS2 */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.class", "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.ps", "*.lzh", NULL
- },
- { /* DOS */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.ps", "*.lzh", NULL
- },
- { /* TOPS10 */
- "*.exe","*.sav","*.bin","*.rim","*.rel","*.unv","*.lib","*.tap","*.dvi",
- "*.ps", NULL
- },
- { /* TOPS20 */
- "*.exe","*.sav","*.bin","*.rim","*.rel","*.unv","*.lib","*.tap","*.dvi",
- "*.ps", NULL
- },
- { /* STRATUS VOS */
- "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram",
- "*.class", "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico",
- "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd",
- "*.pdf", "*.ps", "*.lzh", "*.pm", NULL
- },
- { /* DG */
- "*.ob", "*.pr", "*.dmp", "*.ps", NULL
- },
- { /* OSK */
- "*.gz","*.Z","*.z","*.tgz","*.lhz","*.tar", /* archivers */
- "*.zip","*.ar","*.zoo","*.rpm","*.lzh",
- /* object files, libraries, executables */
- "*.r","*.l","*.exe", "*.dll", "*.so.*", "*.class",
- /* images */
- "*.gif", "*.jpg", "*.jpeg", "*.tif","*.tiff", "*.pdf", "*.ps",
- "*.bmp", "*.bz2", "*.BMP","*.pcx",
- NULL
- }
-};
-
-/*
- Set up default pattern lists so they can be freed and re-malloc'd.
- Each pattern list must terminated by a null element.
-*/
-VOID
-initpat() {
- int i;
- for (i = 0; i < FTPATTERNS; i++) {
- txtpatterns[i] = NULL;
- binpatterns[i] = NULL;
- }
- for (i = 0; i < FTPATTERNS; i++) {
-#ifdef UNIX
- makestr(&(txtpatterns[i]),txtp[SYS_UNIX][i]);
-#else /* UNIX */
-#ifdef OS2
-#ifdef NT
- makestr(&(txtpatterns[i]),txtp[SYS_WIN32][i]);
-#else /* NT */
- makestr(&(txtpatterns[i]),txtp[SYS_OS2][i]);
-#endif /* NT */
-#else /* OS2 */
-#ifdef VMS
- makestr(&(txtpatterns[i]),txtp[SYS_VMS][i]);
-#else /* VMS */
-#ifdef STRATUS
- makestr(&(txtpatterns[i]),txtp[SYS_VOS][i]);
-#else /* STRATUS */
-#ifdef datageneral
- makestr(&(txtpatterns[i]),txtp[SYS_DG][i]);
-#else /* datageneral */
-#ifdef OSK
- makestr(&(txtpatterns[i]),txtp[SYS_OSK][i]);
-#else /* OSK */
- makestr(&(txtpatterns[i]),txtp[SYS_UNK][i]);
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIX */
- if (!txtp[i])
- break;
- }
- for (i = 0; i < FTPATTERNS; i++) {
-#ifdef UNIX
- makestr(&(binpatterns[i]),binp[SYS_UNIX][i]);
-#else /* UNIX */
-#ifdef OS2
-#ifdef NT
- makestr(&(binpatterns[i]),binp[SYS_WIN32][i]);
-#else /* NT */
- makestr(&(binpatterns[i]),binp[SYS_OS2][i]);
-#endif /* NT */
-#else /* OS2 */
-#ifdef VMS
- makestr(&(binpatterns[i]),binp[SYS_VMS][i]);
-#else /* VMS */
-#ifdef STRATUS
- makestr(&(binpatterns[i]),binp[SYS_VOS][i]);
-#else /* STRATUS */
-#ifdef datageneral
- makestr(&(binpatterns[i]),binp[SYS_DG][i]);
-#else /* datageneral */
-#ifdef OSK
- makestr(&(binpatterns[i]),binp[SYS_OSK][i]);
-#else /* OSK */
- makestr(&(binpatterns[i]),binp[SYS_UNK][i]);
-#endif /* OSK */
-#endif /* datageneral */
-#endif /* STRATUS */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIX */
- if (!binp[i])
- break;
- }
-}
-
-/*
- m a t c h n a m e -- Compare filename with text & binary name patterns.
-
- Returns:
- 0 if name matches a text pattern but not a binary pattern.
- 1 if name matches a binary pattern but not a text pattern.
- -1 if name matches no patterns.
- -2 if name matches a binary pattern and a text pattern.
-*/
-int
-matchname(filename, local, os) char * filename; int local; int os; {
- int rc = -1; /* Return code */
- char * name, * p;
-#ifdef OS2ORUNIX
- char tmpbuf[CKMAXPATH+1];
-#endif /* OS2ORUNIX */
-
- name = filename ? filename : ""; /* Copy of original arg */
- if (patterns && *name) { /* If PATTERNS ON... */
- int i;
-
-#ifdef OS2ORUNIX
- if (ckmatch("*.~[1-9]*~",name,1,1)) { /* Name has backup suffix? */
- int k;
- k = ckstrncpy(tmpbuf,name,CKMAXPATH+1); /* Yes, copy and strip */
- for (i = k - 3; i > 4; i--) {
- if (tmpbuf[i] == '~' && tmpbuf[i-1] == '.') {
- tmpbuf[i-1] = NUL;
- break;
- }
- }
- name = tmpbuf; /* And point to stripped copy */
- }
-#endif /* OS2ORUNIX */
- zstrip(name,&p); /* Strip pathname too */
- name = p;
-
- if (local) {
- if (txtpatterns[0]) { /* Search text patterns */
- for (i = 0; i < FTPATTERNS && txtpatterns[i]; i++) {
- if (ckmatch(txtpatterns[i],name,filecase,1)) {
- rc = 0;
- break;
- }
- }
- }
- if (binpatterns[0]) { /* And search binary patterns */
- for (i = 0; i < FTPATTERNS && binpatterns[i]; i++) {
- if (ckmatch(binpatterns[i],name,filecase,1)) {
- rc = (rc > -1) ? -2 : 1;
- break;
- }
- }
- }
- } else {
- if (os >= 0 && os < SYS_MAX) {
- if (txtp[os][0]) {
- for (i = 0; i < FTPATTERNS && txtp[os][i]; i++) {
- if (ckmatch(txtp[os][i],name,filecase,1)) {
- rc = 0;
- break;
- }
- }
- }
- if (binp[os][0]) {
- for (i = 0; i < FTPATTERNS && binp[os][i]; i++) {
- if (ckmatch(binp[os][i],name,filecase,1)) {
- rc = (rc > -1) ? -2 : 1;
- break;
- }
- }
- }
- }
- }
- }
- debug(F111,"matchname",name,rc);
- return(rc);
-}
-#endif /* PATTERNS */
-
-#ifdef UNICODE
-#ifndef NOEVENMAX
-#define EVENMAX
-#endif /* NOEVENMAX */
-#endif /* UNICODE */
-
-/* S C A N F I L E -- Analyze a file's contents */
-
-/*
- Call with:
- name: Pointer to name of existing file.
- flag: Pointer to int in which to return additional numeric data.
-
- Returns:
- -1 on failure (to open file or to read from it).
- Integer, 0..4, on success indicating file type:
- 0 = 7-bit text (flag = -1)
- 1 = UTF-8 text (flag = -1)
- 2 = UCS-2 text (flag = 0: big-endian; flag = 1: little-endian)
- 3 = 8-bit text (flag = 0: no C1 bytes; flag = 1: includes C1 bytes)
- 4 = Text (type unknown)
- 5 = binary (flag = -1)
-
- If UNICODE is defined:
-
- 1. If file begins with a valid BOM, it is believed. Otherwise we
- read the first 4K of the file (since it might be email with verbose
- headers) and analyze it:
-
- 2. If file contains only valid UTF-8 sequences, we call it UTF-8;
- otherwise:
-
- 3. If the file contains lots of alternate 0 bytes, we call it UCS-2, and
- set the polarity according to whether the preponderance of them are in
- even or odd positions; otherwise:
-
- 4. If EVENMAX is defined and the file contains lots of alternate bytes that
- are identical, even if they aren't zero, and the number of such bytes
- is at least four times the length of the maximum run of alternating
- identical bytes of the opposite polarity, we call it UCS-2; otherwise:
-
- 5. If the file contained no bytes with their 8th bits on and no controls
- other than CR, LF, HT, and FF, we call it ASCII; otherwise:
-
- 6. If it contains C0 control characters other than CR, LF, HT, and FF, we
- call it binary; otherwise:
-
- 7. We call it 8-bit text, character set unknown (could be Latin-1 or
- anything else).
-
- Note that malformed UTF-8 is not diagnosed as UTF-8.
-
- If UNICODE is not defined:
-
- 1. If the file contains C0 control characters other than CR, LF, HT, and
- FF, we call it binary; otherwise:
-
- 2. If the file contains any 8-bit bytes, we call it 8-bit text; otherwise:
-
- 3. We call it 7-bit text.
-
- In the non-Unicode case, UCS-2 is diagnosed as binary, but UTF-8 as
- 8-bit text.
-
- There is no significant speed difference between the Unicode and
- non-Unicode cases.
-*/
-int
-scanfile(name,flag,nscanfile) char * name; int * flag, nscanfile; {
- FILE * fp; /* File pointer */
- unsigned char buf[SCANFILEBUF]; /* File data buffer for analysis */
- int x, val = -1, count = 0; /* Workers */
- int rc = -1; /* Return code */
- int pv = -1; /* Pattern-match value */
- int eof = 0; /* Flag for file EOF encountered */
- int bytes = 0; /* Total byte count */
-#ifdef UNICODE
- unsigned int c0, c1; /* First 2 file bytes (for BOM) */
-#endif /* UNICODE */
- extern int pipesend, filepeek;
-
- register int i; /* Loop control */
- int readsize = 0; /* How much to read */
- int eightbit = 0; /* Number of bytes with 8th bit on */
- int c0controls = 0; /* C0 non-text control-char counter */
- int c0noniso = 0; /* C0 non-ISO control-char counter */
- int c1controls = 0; /* C1 control-character counter */
- unsigned int c; /* Current character */
- int runmax = 0; /* Longest run of 0 bytes */
- int runzero = 0; /* Run of 0 bytes */
- int pctzero = 0; /* Percentage of 0 bytes */
- int txtcz = 0;
-#ifdef CK_CTRLZ
- extern int eofmethod;
-#endif /* CK_CTRLZ */
-
-#ifdef UNICODE
- int notutf8 = 0; /* Nonzero if definitely not UTF-8 */
- int utf8state = 0; /* UTF-8 recognizer state */
- int oddzero = 0; /* Number of 0 bytes in odd postions */
- int evenzero = 0; /* and in even positions */
- int lfnul = 0; /* Number of <LF><NUL> sequences */
- int crlf = 0; /* Number of <CRLF> sequences */
-#else
- int notutf8 = 1;
-#endif /* UNICODE */
-
-#ifdef COMMENT
-#ifdef EVENMAX
- int oddrun = 0, oddmax = 0, oddbyte = 0, oddmaxbyte = 0;
- int evenrun = 0, evenmax = 0, evenbyte = 0, evenmaxbyte = 0;
-#endif /* EVENMAX */
-#endif /* COMMENT */
-
-#ifndef NOXFER
- if (pipesend || calibrate || sndarray) /* Only for real files */
- return(-1);
-#endif /* NOXFER */
- debug(F111,"scanfile",name,nscanfile);
-#ifdef PATTERNS
- if (!filepeek) {
- pv = matchname(name,1,-1);
- if (pv < 0)
- rc = -1;
- else
- rc = (pv == 1) ? FT_BIN : FT_TEXT;
- debug(F111,"scanfile !filepeek result",name,rc);
- return(rc);
- }
-#endif /* PATTERNS */
-
-#ifdef VMS
-/* We don't scan in VMS where text files have various record formats in */
-/* which record headers contain seemingly non-text bytes. So the best */
-/* we can do in VMS is tell whether the file is text or binary, period. */
- {
- int b, x;
- b = binary; /* Save current binary setting */
- if (zopeni(ZIFILE,name) > 0) { /* In VMS this sets binary */
- x = binary; /* Get result */
- zclose(ZIFILE); /* Close the file */
- binary = b; /* Restore previous binary setting */
- rc = x ? FT_BIN : FT_TEXT;
- val = 0;
- goto xscanfile;
- }
- }
-#endif /* VMS */
-
- eof = 0; /* End-of-file reached indicator */
-#ifdef OS2
- fp = fopen(name, "rb"); /* Open the file in binary mode */
-#else
- fp = fopen(name, "r");
-#endif /* OS2 */
-
- if (!fp) /* Failed? */
- return(-1);
-
- while (1) { /* One or more gulps from file */
- if (eof) { /* EOF from last time? */
- debug(F111,"scanfile at EOF",name,bytes);
- if (runzero > runmax)
- runmax = runzero;
- break;
- }
- if (nscanfile < 0) { /* Reading whole file */
- readsize = SCANFILEBUF;
- } else { /* Reading first nscanfilee bytes */
- readsize = nscanfile - bytes;
- if (readsize < 1)
- break;
- if (readsize > SCANFILEBUF)
- readsize = SCANFILEBUF;
- }
- debug(F101,"scanfile readsize","",readsize);
- count = fread(buf,1,readsize,fp); /* Read a buffer */
- if (count == EOF || count == 0) {
- debug(F111,"scanfile EOF",name,count);
- break;
- }
- debug(F111,"scanfile buffer ok",name,count);
-
- if (bytes == 0 && count > 8) {
- /* PDF files can look like text in the beginning. */
- if (!ckstrcmp((char *)buf,"%PDF-1.",7,1)) {
- if (isdigit(buf[7])) {
- if (buf[8] == '\015' ||
- count > 9 && buf[8] == SP && buf[9] == '\015') {
-#ifdef DEBUG
- buf[8] = NUL;
- debug(F110,"scanfile PDF",buf,0);
-#endif /* DEBUG */
- binary = 1; /* But they are binary. */
- break;
- }
- }
- } else if (!ckstrcmp((char *)buf,"%!PS-Ado",8,1)) {
- /* Ditto for PostScript */
-#ifdef DEBUG
- int i;
- for (i = 8; i < count; i++) {
- if (buf[i] < '!') {
- buf[i] = NUL;
- break;
- }
- }
- debug(F110,"scanfile PostScript",buf,0);
-#endif /* DEBUG */
- binary = 1;
- break;
-#ifndef NOPCLSCAN
- } else if (!ckstrcmp((char *)buf,") HP-PCL",8,1)) {
- /* HP PCL printer language */
-#ifdef DEBUG
- int i;
- for (i = 8; i < count; i++) {
- if (buf[i] < '!') {
- buf[i] = NUL;
- break;
- }
- }
- debug(F110,"scanfile PCL",buf,0);
-#endif /* DEBUG */
- binary = 1;
- break;
- }
-#endif /* NOPCLSCAN */
-#ifndef NOPJLSCAN
- else if (buf[0] == '\033' && (buf[1] == 'E' || buf[1] == '%')) {
- /* Ditto for PJL Job printer header */
-#ifdef DEBUG
- int i;
- for (i = 2; i < count; i++) {
- if (buf[i] < '!') {
- buf[i] = NUL;
- break;
- }
- }
- debug(F110,"scanfile PJL Job printer header",buf,0);
-#endif /* DEBUG */
- binary = 1;
- break;
-#endif /* NOPJLSCAN */
- }
- }
-
-#ifdef UNICODE
- if (bytes == 0 && count > 1) {
- int incl_cnt = 0;
-
- /* First look for BOM */
-
- c0 = (unsigned)((unsigned)buf[0]&0xFF); /* First file byte */
- c1 = (unsigned)((unsigned)buf[1]&0xFF); /* Second byte */
-
- if (c0 == 0xFE && c1 == 0xFF) { /* UCS-2 BE */
- rc = FT_UCS2;
- val = 0;
- debug(F111,"scanfile UCS2 BOM BE",ckitoa(val),rc);
- incl_cnt++;
- } else if (c0 == 0xFF && c1 == 0xFE) { /* UCS-2 LE */
- rc = FT_UCS2;
- val = 1;
- debug(F111,"scanfile UCS2 BOM LE",ckitoa(val),rc);
- incl_cnt++;
- } else if (count > 2) if (c0 == 0xEF && c1 == 0xBB &&
- (unsigned)((unsigned)buf[2]&0xFF) == 0xBF) {
- rc = FT_UTF8;
- debug(F111,"scanfile UTF8 BOM",ckitoa(val),rc);
- incl_cnt++;
- }
- if (incl_cnt) { /* Have BOM */
- bytes += count;
- goto xscanfile;
- }
- }
-#endif /* UNICODE */
-
- bytes += count; /* Count bytes read */
- eof = feof(fp); /* Flag for at EOF */
-
- for (i = 0; i < count; i++) { /* For each byte... */
- c = (unsigned)buf[i]; /* For ease of reference */
- if (!c) { /* Zero byte? */
-#ifdef EVENMAX
- if (i&1) /* In odd position */
- oddzero++;
- else
- evenzero++; /* In even position */
-#endif /* EVENMAX */
- runzero++;
- } else { /* Not a zero byte */
- if (runzero > runmax)
- runmax = runzero;
- if (runmax > 2) /* That's all we need to be certain */
- break; /* it's a binary file. */
- runzero = 0;
- }
-
-#ifdef COMMENT
-#ifdef EVENMAX
-
-/* This is to catch UCS-2 with a non-ASCII, non-Latin-1 repertoire */
-
- if (i > 1) { /* Look for runs of alternating chars */
- if (i&1) {
- if (c == buf[i-2]) { /* In odd positions */
- oddrun++;
- oddbyte = c;
- } else {
- oddmax = oddrun;
- oddmaxbyte = oddbyte;
- }
- } else { /* and even positions */
- if (c == buf[i-2]) {
- evenrun++;
- evenbyte = c;
- } else {
- evenmax = evenrun;
- evenmaxbyte = evenbyte;
- }
- }
- }
-#endif /* EVENMAX */
-#endif /* COMMENT */
-
- if ((c & 0x80) == 0) { /* We have a 7-bit byte */
-#ifdef UNICODE
- if (i > 0 && c == 10) { /* Linefeed */
- if (buf[i-1] == 0) lfnul++; /* Preceded by NUL */
- else if (buf[i-1] == 13) crlf++; /* or by CR... */
- }
-#endif /* UNICODE */
- if (c < ' ') { /* Check for CO controls */
- if (c != LF && c != CR && c != HT && c != FF) {
- c0controls++;
- if (c != ESC && c != SO && c != SI)
- c0noniso++;
- }
- if ((c == '\032') /* Ctrl-Z */
-#ifdef COMMENT
- && eof && (i >= count - 2)
-#endif /* COMMENT */
- ) {
- c0controls--;
- c0noniso--;
-#ifdef CK_CTRLZ
- if (eofmethod == XYEOF_Z && txtcz == 0) {
- if (c0controls == 0) /* All text prior to Ctrl-Z */
- txtcz = 1;
- }
-#endif /* CK_CTRLZ */
- }
- }
-#ifdef UNICODE
- if (!notutf8 && utf8state) { /* In UTF-8 sequence? */
- utf8state = 0;
- debug(F000,"scanfile","7-bit byte in UTF8 sequence",c);
- notutf8++; /* Then it's not UTF-8 */
- continue;
- }
-#endif /* UNICODE */
- } else { /* We have an 8-bit byte */
- eightbit++; /* Count it */
- if (c >= 0x80 && c < 0xA0) /* Check for C1 controls */
- c1controls++;
-#ifdef UNICODE
- if (!notutf8) { /* If it might still be UTF8... */
- switch (utf8state) { /* Enter the UTF-8 state machine */
- case 0: /* First byte... */
- if ((c & 0xE0) == 0xC0) { /* Tells number of */
- utf8state = 1; /* subsequent bytes */
- } else if ((c & 0xF0) == 0xE0) {
- utf8state = 2;
- } else if ((c & 0xF8) == 0xF0) {
- utf8state = 3;
- } else {
- notutf8++;
- }
- break;
- case 1: /* Subsequent byte */
- case 2:
- case 3:
- if ((c & 0xC0) != 0x80) { /* Must start with 10 */
- debug(F000,"scanfile",
- "bad byte in UTF8 sequence",c);
- notutf8++;
- break;
- }
- utf8state--; /* Good, one less in this sequence */
- break;
- default: /* Shouldn't happen */
- debug(F111,"scanfile","bad UTF8 state",utf8state);
- notutf8++;
- }
- }
-#endif /* UNICODE */
- }
- }
- }
- fclose(fp); /* Close the file */
- debug(F101,"scanfile bytes","",bytes);
-
- if (bytes == 0) /* If nothing was read */
- return(-1); /* we're done. */
-
-#ifdef EVENMAX
- /* In case we had a run that never broke... */
-#ifdef COMMENT
- if (oddmax == 0) {
- oddmax = oddrun;
- oddmaxbyte = oddbyte;
- }
- if (evenmax == 0) {
- evenmax = evenrun;
- evenmaxbyte = evenbyte;
- }
-#endif /* COMMENT */
- if (runmax == 0) {
- runmax = runzero;
- }
-#endif /* EVENMAX */
-
-#ifdef UNICODE
- if (bytes > 100) /* Bytes is not 0 */
- pctzero = (evenzero + oddzero) / (bytes / 100);
- else
- pctzero = ((evenzero + oddzero) * 100) / bytes;
-#endif /* UNICODE */
-
-#ifdef DEBUG
- if (deblog) { /* If debugging, dump statistics */
- debug(F101,"scanfile c0controls ","",c0controls);
- debug(F101,"scanfile c0noniso ","",c0noniso);
- debug(F101,"scanfile c1controls ","",c1controls);
- debug(F101,"scanfile eightbit ","",eightbit);
-#ifdef UNICODE
- debug(F101,"scanfile crlf ","",crlf);
- debug(F101,"scanfile lfnul ","",lfnul);
- debug(F101,"scanfile notutf8 ","",notutf8);
- debug(F101,"scanfile evenzero ","",evenzero);
- debug(F101,"scanfile oddzero ","",oddzero);
- debug(F101,"scanfile even/odd ","",(evenzero / (oddzero + 1)));
- debug(F101,"scanfile odd/even ","",(oddzero / (evenzero + 1)));
- debug(F101,"scanfile pctzero ","",pctzero);
-#endif /* UNICODE */
-#ifdef COMMENT
-#ifdef EVENMAX
- debug(F101,"scanfile oddmax ","",oddmax);
- debug(F101,"scanfile oddmaxbyte ","",oddmaxbyte);
- debug(F101,"scanfile evenmax ","",evenmax);
- debug(F101,"scanfile evenmaxbyte","",evenmaxbyte);
-#endif /* EVENMAX */
-#endif /* COMMENT */
- debug(F101,"scanfile runmax ","",runmax);
- }
-#endif /* DEBUG */
-
-#ifdef UNICODE
- x = eightbit ? bytes / 20 : bytes / 4; /* For UCS-2... */
-
- if (runmax > 2) { /* File has run of more than 2 NULs */
- debug(F100,"scanfile BIN runmax","",0);
- rc = FT_BIN; /* so it can't be any kind of text. */
- goto xscanfile;
-
- } else if (rc == FT_UCS2 || (rc == FT_UTF8 && runmax == 0)) {
- goto xscanfile; /* File starts with a BOM */
-
- } else if (eightbit > 0 && !notutf8) { /* File has 8-bit data */
- if (runmax > 0) { /* and runs of NULs */
- debug(F100,"scanfile BIN (nnUTF8) runmax","",0);
- rc = FT_BIN; /* UTF-8 doesn't have NULs */
- } else { /* No NULs */
- debug(F100,"scanfile UTF8 (nnUTF8 + runmax == 0)","",0);
- rc = FT_UTF8; /* and not not UTF-8, so is UTF-8 */
- }
- goto xscanfile;
- }
-/*
- For UCS-2 detection, see if the text contains lines delimited by
- ASCII controls and containing spaces, ASCII digits, or other ASCII
- characters, thus forcing the presence of a certain percentage of zero bytes.
- For this purpose require 20% zero bytes, with at least six times as many
- in even (odd) positions as in odd (even) positions.
-*/
- if ((evenzero >= x && oddzero == 0) ||
- ((((evenzero / (oddzero + 1)) > 6) && (pctzero > 20)) &&
- (crlf == 0) &&
- (lfnul > 1))
- ) {
- debug(F100,"scanfile UCS2 noBOM BE (even/oddzero)","",0);
- rc = FT_UCS2;
- val = 0;
- } else if ((evenzero == 0 && oddzero >= x) ||
- ((((oddzero / (evenzero + 1)) > 6) && (pctzero > 20)) &&
- (crlf == 0) &&
- (lfnul > 1))
- ) {
- debug(F100,"scanfile UCS2 noBOM LE (even/oddzero)","",0);
- rc = FT_UCS2;
- val = 1;
-
-#ifdef COMMENT
-#ifdef EVENMAX
-/*
- If the tests above fail, we still might have UCS-2 if there are significant
- runs of identical bytes in alternating positions, but only if it also has
- unusual C0 controls (otherwise we'd pick up hex files here). NOTE: We
- don't actually do this -- EVENMAX is not defined (see comments above at
- first occurrence of EVENMAX).
-*/
- } else if (c0noniso && evenmax > bytes / 4) {
- debug(F100,"scanfile UCS2 BE (evenmax)","",0);
- rc = FT_UCS2;
- val = 0;
- } else if (c0noniso && oddmax > bytes / 4) {
- debug(F100,"scanfile UCS2 LE (evenmax)","",0);
- rc = FT_UCS2;
- val = 1;
-#endif /* EVENMAX */
-#endif /* COMMENT */
-
- }
-/*
- It seems to be UCS-2 but let's be more certain since there is no BOM...
- If the number of 7- and 8-bit characters is approximately equal, it might
- be a compressed file. In this case we decide based on the name.
-*/
- if (rc == FT_UCS2) {
- if (eightbit > 0) {
- int j, k;
- j = (c1controls * 100) / (c0controls + 1);
- debug(F101,"scanfile c1/c0 ","",j);
- k = (bytes * 100) / eightbit;
- debug(F101,"scanfile pct 8bit ","",k);
- if (k > 40 && k < 60 && j > 60) {
- if (ckmatch("{*.Z,*.gz,*.zip,*.ZIP}",name,1,1)) {
- debug(F110,"scanfile 8-bit BIN compressed",name,0);
- rc = FT_BIN;
- goto xscanfile;
- }
- }
- }
- /* Small file - not enough evidence unless ... */
-
- if (bytes < 100) {
- if (oddzero != 0 && evenzero != 0) {
- debug(F100,"scanfile small UCS2 doubtful","",0);
- rc = FT_BIN;
- goto xscanfile;
- } else if (oddzero == 0 && evenzero == 0) {
- rc = eightbit ? FT_8BIT : FT_7BIT;
- }
- }
- goto xscanfile; /* Seems to be UCS-2 */
- }
-
-/* If none of the above, it's probably not Unicode. */
-
- if (!eightbit) { /* It's 7-bit */
- if (c0controls) { /* This would be strange */
- if ((c0noniso > 0) && (txtcz == 0)) {
- debug(F100,"scanfile 7-bit BIN (c0coniso)","",0);
- rc = FT_BIN;
- } else {
- debug(F100,"scanfile 7-bit ISO2022 TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
- } else { /* 7-bit text */
- debug(F100,"scanfile 7-bit TEXT (no c0controls)","",0);
- rc = FT_7BIT;
- }
- } else if (!c0noniso || txtcz) { /* 8-bit text */
- debug(F100,"scanfile 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else { /* 8-bit binary */
- debug(F100,"scanfile 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- }
-
-#else /* !UNICODE */
-
- if (c0noniso) {
- debug(F100,"scanfile 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- } else if (eightbit) {
- debug(F100,"scanfile 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else {
- debug(F100,"scanfile 7-bit TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
-
-#endif /* UNICODE */
-
- xscanfile:
- if (flag) *flag = val;
- debug(F101,"scanfile result ","",rc);
- return(rc);
-}
-
-/*
- scanstring - like scan file but for a string.
- This is just a quick butchery of scanfile without thinking too much.
-*/
-int
-scanstring(s) char * s; {
- int x, val = -1, count = 0; /* Workers */
- int rc = -1; /* Return code */
- int pv = -1; /* Pattern-match value */
- int bytes = 0; /* Total byte count */
-#ifdef UNICODE
- unsigned int c0, c1; /* First 2 file bytes (for BOM) */
-#endif /* UNICODE */
- extern int pipesend, filepeek;
-
- register int i; /* Loop control */
- int readsize = 0; /* How much to read */
- int eightbit = 0; /* Number of bytes with 8th bit on */
- int c0controls = 0; /* C0 non-text control-char counter */
- int c0noniso = 0; /* C0 non-ISO control-char counter */
- int c1controls = 0; /* C1 control-character counter */
- unsigned int c; /* Current character */
- int runmax = 0; /* Longest run of 0 bytes */
- int runzero = 0; /* Run of 0 bytes */
- int pctzero = 0; /* Percentage of 0 bytes */
- int txtcz = 0;
-
-#ifdef UNICODE
- int notutf8 = 0; /* Nonzero if definitely not UTF-8 */
- int utf8state = 0; /* UTF-8 recognizer state */
- int oddzero = 0; /* Number of 0 bytes in odd postions */
- int evenzero = 0; /* and in even positions */
- int lfnul = 0; /* Number of <LF><NUL> sequences */
- int crlf = 0; /* Number of <CRLF> sequences */
-#else
- int notutf8 = 1;
-#endif /* UNICODE */
-
- char * buf = s;
- if (!s) s = "";
- count = strlen(s);
-
-#ifdef UNICODE
- if (bytes == 0 && count > 1) {
- int incl_cnt = 0;
-
- /* First look for BOM */
-
- c0 = (unsigned)((unsigned)buf[0]&0xFF); /* First file byte */
- c1 = (unsigned)((unsigned)buf[1]&0xFF); /* Second byte */
-
- if (c0 == 0xFE && c1 == 0xFF) { /* UCS-2 BE */
- rc = FT_UCS2;
- val = 0;
- debug(F111,"scanstring UCS2 BOM BE",ckitoa(val),rc);
- incl_cnt++;
- } else if (c0 == 0xFF && c1 == 0xFE) { /* UCS-2 LE */
- rc = FT_UCS2;
- val = 1;
- debug(F111,"scanstring UCS2 BOM LE",ckitoa(val),rc);
- incl_cnt++;
- } else if (count > 2) if (c0 == 0xEF && c1 == 0xBB &&
- (unsigned)((unsigned)buf[2]&0xFF) == 0xBF) {
- rc = FT_UTF8;
- debug(F111,"scanstring UTF8 BOM",ckitoa(val),rc);
- incl_cnt++;
- }
- if (incl_cnt) { /* Have BOM */
- bytes += count;
- goto xscanstring;
- }
- }
-#endif /* UNICODE */
-
- bytes += count; /* Count bytes read */
-
- for (i = 0; i < count; i++) { /* For each byte... */
- c = (unsigned)buf[i]; /* For ease of reference */
- if (!c) { /* Zero byte? */
- goto xscanstring; /* Null terminated string */
- }
- if ((c & 0x80) == 0) { /* We have a 7-bit byte */
-#ifdef UNICODE
- if (i > 0 && c == 10) { /* Linefeed */
- if (buf[i-1] == 0) lfnul++; /* Preceded by NUL */
- else if (buf[i-1] == 13) crlf++; /* or by CR... */
- }
-#endif /* UNICODE */
- if (c < ' ') { /* Check for CO controls */
- if (c != LF && c != CR && c != HT && c != FF) {
- c0controls++;
- if (c != ESC && c != SO && c != SI)
- c0noniso++;
- }
- if ((c == '\032') /* Ctrl-Z */
- ) {
- c0controls--;
- c0noniso--;
- }
- }
-#ifdef UNICODE
- if (!notutf8 && utf8state) { /* In UTF-8 sequence? */
- utf8state = 0;
- debug(F000,"scanstring","7-bit byte in UTF8 sequence",c);
- notutf8++; /* Then it's not UTF-8 */
- continue;
- }
-#endif /* UNICODE */
- } else { /* We have an 8-bit byte */
- eightbit++; /* Count it */
- if (c >= 0x80 && c < 0xA0) /* Check for C1 controls */
- c1controls++;
-#ifdef UNICODE
- if (!notutf8) { /* If it might still be UTF8... */
- switch (utf8state) { /* Enter the UTF-8 state machine */
- case 0: /* First byte... */
- if ((c & 0xE0) == 0xC0) { /* Tells number of */
- utf8state = 1; /* subsequent bytes */
- } else if ((c & 0xF0) == 0xE0) {
- utf8state = 2;
- } else if ((c & 0xF8) == 0xF0) {
- utf8state = 3;
- } else {
- notutf8++;
- }
- break;
- case 1: /* Subsequent byte */
- case 2:
- case 3:
- if ((c & 0xC0) != 0x80) { /* Must start with 10 */
- debug(F000,"scanstring",
- "bad byte in UTF8 sequence",c);
- notutf8++;
- break;
- }
- utf8state--; /* Good, one less in this sequence */
- break;
- default: /* Shouldn't happen */
- debug(F111,"scanstring","bad UTF8 state",utf8state);
- notutf8++;
- }
- }
-#endif /* UNICODE */
- }
- }
- if (bytes == 0) /* If nothing was read */
- return(-1); /* we're done. */
-
-#ifdef UNICODE
- if (bytes > 100) /* Bytes is not 0 */
- pctzero = (evenzero + oddzero) / (bytes / 100);
- else
- pctzero = ((evenzero + oddzero) * 100) / bytes;
-#endif /* UNICODE */
-
-#ifdef UNICODE
- x = eightbit ? bytes / 20 : bytes / 4; /* For UCS-2... */
-
- if (runmax > 2) { /* File has run of more than 2 NULs */
- debug(F100,"scanstring BIN runmax","",0);
- rc = FT_BIN; /* so it can't be any kind of text. */
- goto xscanstring;
-
- } else if (rc == FT_UCS2 || (rc == FT_UTF8 && runmax == 0)) {
- goto xscanstring; /* File starts with a BOM */
-
- } else if (eightbit > 0 && !notutf8) { /* File has 8-bit data */
- if (runmax > 0) { /* and runs of NULs */
- debug(F100,"scanstring BIN (nnUTF8) runmax","",0);
- rc = FT_BIN; /* UTF-8 doesn't have NULs */
- } else { /* No NULs */
- debug(F100,"scanstring UTF8 (nnUTF8 + runmax == 0)","",0);
- rc = FT_UTF8; /* and not not UTF-8, so is UTF-8 */
- }
- goto xscanstring;
- }
-/*
- It seems to be UCS-2 but let's be more certain since there is no BOM...
- If the number of 7- and 8-bit characters is approximately equal, it might
- be a compressed file. In this case we decide based on the name.
-*/
- if (rc == FT_UCS2) {
- if (bytes < 100) {
- if (oddzero != 0 && evenzero != 0) {
- debug(F100,"scanstring small UCS2 doubtful","",0);
- rc = FT_BIN;
- goto xscanstring;
- } else if (oddzero == 0 && evenzero == 0) {
- rc = eightbit ? FT_8BIT : FT_7BIT;
- }
- }
- goto xscanstring; /* Seems to be UCS-2 */
- }
-
-/* If none of the above, it's probably not Unicode. */
-
- if (!eightbit) { /* It's 7-bit */
- if (c0controls) { /* This would be strange */
- if ((c0noniso > 0) && (txtcz == 0)) {
- debug(F100,"scanstring 7-bit BIN (c0coniso)","",0);
- rc = FT_BIN;
- } else {
- debug(F100,"scanstring 7-bit ISO2022 TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
- } else { /* 7-bit text */
- debug(F100,"scanstring 7-bit TEXT (no c0controls)","",0);
- rc = FT_7BIT;
- }
- } else if (!c0noniso || txtcz) { /* 8-bit text */
- debug(F100,"scanstring 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else { /* 8-bit binary */
- debug(F100,"scanstring 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- }
-
-#else /* !UNICODE */
-
- if (c0noniso) {
- debug(F100,"scanstring 8-bit BIN (c0noniso)","",0);
- rc = FT_BIN;
- } else if (eightbit) {
- debug(F100,"scanstring 8-bit TEXT (no c0noniso)","",0);
- rc = FT_8BIT;
- val = c1controls ? 1 : 0;
- } else {
- debug(F100,"scanstring 7-bit TEXT (no c0noniso)","",0);
- rc = FT_7BIT;
- }
-
-#endif /* UNICODE */
-
- xscanstring:
- debug(F101,"scanstring result ","",rc);
- return(rc);
-}
-
-
-
-/* F I L E S E L E C T -- Select this file for sending */
-
-int
-#ifdef CK_ANSIC
-fileselect(
- char *f, char *sa, char *sb, char *sna, char *snb,
- CK_OFF_T minsiz, CK_OFF_T maxsiz,
- int nbu, int nxlist,
- char ** xlist
-)
-#else
-fileselect(f,sa,sb,sna,snb,minsiz,maxsiz,nbu,nxlist,xlist)
- char *f,*sa,*sb,*sna,*snb; CK_OFF_T minsiz,maxsiz;
- int nbu,nxlist; char ** xlist;
-#endif /* CK_ANSIC */
-/* fileselect */ {
- char *fdate;
- int n;
- CK_OFF_T z;
-
- debug(F111,"fileselect minsiz",ckfstoa(minsiz),minsiz);
- debug(F111,"fileselect maxsiz",ckfstoa(maxsiz),maxsiz);
- debug(F111,"fileselect (CK_OFF_T)-1",ckfstoa((CK_OFF_T)-1),(CK_OFF_T)-1);
-
- if (!sa) sa = "";
- if (!sb) sb = "";
- if (!sna) sna = "";
- if (!snb) snb = "";
-
-#ifdef CKSYMLINK
-#ifndef NOICP
-#ifndef NOXFER
- if (nolinks) {
- CK_OFF_T zz;
- zz = zgetfs(f);
- debug(F111,"fileselect NOLINKS zgetfs",f,zz);
- if (zz < (CK_OFF_T)0)
- return(0);
- debug(F111,"fileselect NOLINKS zgfs_link",f,zgfs_link);
- if (zgfs_link)
- return(0);
- }
-#endif /* NOXFER */
-#endif /* NOICP */
-#endif /* CKSYMLINK */
-
- debug(F110,"fileselect",f,0);
- if (*sa || *sb || *sna || *snb) {
- fdate = zfcdat(f); /* Date/time of this file */
- if (!fdate) fdate = "";
- n = strlen(fdate);
- debug(F111,"fileselect fdate",fdate,n);
- if (n != 17) /* Failed to get it */
- return(1);
- /* /AFTER: */
- if (sa[0] && (strcmp(fdate,(char *)sa) <= 0)) {
- debug(F110,"fileselect sa",sa,0);
- /* tlog(F110,"Skipping (too old)",f,0); */
- return(0);
- }
- /* /BEFORE: */
- if (sb[0] && (strcmp(fdate,(char *)sb) >= 0)) {
- debug(F110,"fileselect sb",sb,0);
- /* tlog(F110,"Skipping (too new)",f,0); */
- return(0);
- }
- /* /NOT-AFTER: */
- if (sna[0] && (strcmp(fdate,(char *)sna) > 0)) {
- debug(F110,"fileselect sna",sna,0);
- /* tlog(F110,"Skipping (too new)",f,0); */
- return(0);
- }
- /* /NOT-BEFORE: */
- if (snb[0] && (strcmp(fdate,(char *)snb) < 0)) {
- debug(F110,"fileselect snb",snb,0);
- /* tlog(F110,"Skipping (too old)",f,0); */
- return(0);
- }
- }
- /* Smaller or larger */
- if (minsiz > (CK_OFF_T)-1 || maxsiz > (CK_OFF_T)-1) {
- z = zchki(f); /* Get size */
- debug(F101,"fileselect filesize","",z);
- if (z < (CK_OFF_T)0)
- return(1);
- if ((minsiz > (CK_OFF_T)-1) && (z >= minsiz)) {
- debug(F111,"fileselect minsiz skipping",f,minsiz);
- /* tlog(F111,"Skipping (too big)",f,z); */
- return(0);
- }
- if ((maxsiz > (CK_OFF_T)-1) && (z <= maxsiz)) {
- debug(F111,"fileselect maxsiz skipping",f,maxsiz);
- /* tlog(F110,"Skipping (too small)",f,0); */
- return(0);
- }
- }
- if (nbu) { /* Skipping backup files? */
- if (ckmatch(
-#ifdef CKREGEX
- "*.~[0-9]*~" /* Not perfect but close enough. */
-#else
- "*.~*~" /* Less close. */
-#endif /* CKREGEX */
- ,f,filecase,1)) {
- debug(F110,"fileselect skipping backup",f,0);
- return(0);
- }
- }
- for (n = 0; xlist && n < nxlist; n++) {
- if (!xlist[n]) {
- debug(F101,"fileselect xlist empty",0,n);
- break;
- }
- if (ckmatch(xlist[n],f,filecase,1)) {
- debug(F111,"fileselect xlist",xlist[n],n);
- debug(F110,"fileselect skipping",f,0);
- return(0);
- }
- }
- if (xfiletype > -1) {
- n = scanfile(f,NULL,nscanfile);
- if (n < 0) {
- n = binary ? 1 : 0;
- } else {
- n = (n == FT_BIN) ? 1 : 0;
- }
- if (n != xfiletype)
- return(0);
- }
- debug(F110,"fileselect selecting",f,0);
- return(1);
-}
-
-
-#ifdef TCPSOCKET
-#ifdef NT
-extern int WSASafeToCancel;
-#endif /* NT */
-#endif /* TCPSOCKET */
-
-VOID
-setflow() {
- extern int flow, autoflow, mdmtyp, cxtype, cxflow[];
-#ifndef NODIAL
- extern int dialcapas, dialfc;
- extern MDMINF * modemp[];
- MDMINF * p = NULL;
- long bits = 0;
-#endif /* NODIAL */
-
- debug(F101,"setflow autoflow","",autoflow);
-
-/* #ifdef COMMENT */
-/* WHY WAS THIS COMMENTED OUT? */
- if (!autoflow) /* Only if FLOW is AUTO */
- return;
-/* #endif */ /* COMMENT */
-
- debug(F101,"setflow local","",local);
- debug(F101,"setflow network","",network);
- debug(F101,"setflow cxtype","",cxtype);
-
-#ifdef TN_COMPORT
- if (network && istncomport()) {
- flow = cxflow[CXT_MODEM];
- debug(F101,"setflow TN_COMPORT flow","",flow);
- return;
- }
-#endif /* TN_COMPORT */
-
- if (network || !local || cxtype == CXT_DIRECT) {
- flow = cxflow[cxtype]; /* Set appropriate flow control */
- debug(F101,"setflow flow","",flow);
- return;
- }
- if (cxtype != CXT_MODEM) /* Connection type should be modem */
- return;
-
-#ifndef NODIAL
- bits = dialcapas; /* Capability bits */
- if (!bits) { /* No bits? */
- p = modemp[mdmtyp]; /* Look in modem info structure */
- if (p)
- bits = p->capas;
- }
- if (dialfc == FLO_AUTO) { /* If DIAL flow is AUTO */
-#ifdef CK_RTSCTS /* If we can do RTS/CTS flow control */
- if (bits & CKD_HW) /* and modem can do it too */
- flow = FLO_RTSC; /* then switch to RTS/CTS */
- else /* otherwise */
- flow = FLO_XONX; /* use Xon/Xoff. */
-#else
-#ifndef NEXT
-#ifndef IRIX
- flow = FLO_XONX; /* Use Xon/Xoff. */
-#endif /* IRIX */
-#endif /* NEXT */
-#endif /* CK_RTSCTS */
- }
-#endif /* NODIAL */
- debug(F101,"setflow modem flow","",flow);
- return;
-}
-
-#ifndef NOLOCAL
-#ifdef CK_TRIGGER
-
-/* A U T O E X I T C H K -- Check for CONNECT-mode trigger string */
-/*
- Returns -1 if trigger not found, or else the trigger index, 0 or greater.
- (Replace with fancier and more efficient matcher later...)
- NOTE: to prevent unnecessary function call overhead, call this way:
-
- x = tt_trigger[0] ? autoexitchk(c) : -1;
-
-*/
-int
-#ifdef CK_ANSIC
-autoexitchk(CHAR c)
-#else
-autoexitchk(c) CHAR c;
-#endif /* CK_ANSIC */
-/* autoexitchk */ {
- extern CHAR * tt_trmatch[];
- extern char * tt_trigger[];
- int i;
- for (i = 0; i < TRIGGERS; i++) {
- if (!tt_trigger[i]) { /* No more triggers in list */
- break;
- } else if (*tt_trigger[i]) {
- if (!tt_trmatch[i]) /* Just starting? */
- tt_trmatch[i] = (CHAR *)tt_trigger[i]; /* Set match pointer */
- if (c == *tt_trmatch[i]) { /* Compare this character */
- tt_trmatch[i]++; /* It matches */
- if (!*tt_trmatch[i]) { /* End of match string? */
- tt_trmatch[i] = (CHAR *) tt_trigger[i]; /* Yes, rewind, */
- debug(F101,"autoexitchk",tt_trigger[i],i); /* log, */
- return(i); /* and return success */
- }
- } else /* No match */
- tt_trmatch[i] = (CHAR *) tt_trigger[i]; /* Rewind match string */
- } /* and go on the next match string */
- }
- return(-1); /* No match found */
-}
-#endif /* CK_TRIGGER */
-
-#ifndef NOSHOW
-/* S H O M D M -- Show modem signals */
-
-VOID
-shomdm() {
-/*
- Note use of "\r\n" to make sure this report prints right, even when
- called during CONNECT mode.
-*/
- int y;
- y = ttgmdm();
- switch (y) {
- case -3: printf(
- "Modem signals unavailable in this version of Kermit\r\n");
- break;
- case -2: printf("No modem control for this device\r\n"); break;
- case -1: printf("Modem signals unavailable\r\n"); break;
- default:
-#ifndef MAC
- printf(
- " Carrier Detect (CD): %s\r\n",(y & BM_DCD) ? "On": "Off");
- printf(
- " Dataset Ready (DSR): %s\r\n",(y & BM_DSR) ? "On": "Off");
-#endif /* MAC */
- printf(
- " Clear To Send (CTS): %s\r\n",(y & BM_CTS) ? "On": "Off");
-#ifndef STRATUS
-#ifndef MAC
- printf(
- " Ring Indicator (RI): %s\r\n",(y & BM_RNG) ? "On": "Off");
-#endif /* MAC */
- printf(
- " Data Terminal Ready (DTR): %s\r\n",
-#ifdef NT
- "(unknown)"
-#else /* NT */
- (y & BM_DTR) ? "On": "Off"
-#endif /* NT */
- );
-#ifndef MAC
- printf(
- " Request To Send (RTS): %s\r\n",
-#ifdef NT
- "(unknown)"
-#else /* NT */
- (y & BM_RTS) ? "On": "Off"
-#endif /* NT */
- );
-#endif /* MAC */
-#endif /* STRATUS */
- }
-#ifdef BETADEBUG
-#ifdef CK_TAPI
- if (tttapi && !tapipass) {
- LPDEVCFG lpDevCfg = NULL;
- LPCOMMCONFIG lpCommConfig = NULL;
- LPMODEMSETTINGS lpModemSettings = NULL;
- DCB * lpDCB = NULL;
-
- if (cktapiGetModemSettings(&lpDevCfg,&lpModemSettings,
- &lpCommConfig,&lpDCB)) {
- printf("\n");
- cktapiDisplayModemSettings(lpDevCfg,lpModemSettings,
- lpCommConfig,lpDCB);
- }
- }
-#endif /* CK_TAPI */
-#endif /* BETADEBUG */
-}
-#endif /* NOSHOW */
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
-/* S D E B U -- Record spar results in debugging log */
-
-VOID
-sdebu(len) int len; {
- debug(F111,"spar: data",(char *) rdatap,len);
- debug(F101," spsiz ","", spsiz);
- debug(F101," timint","",timint);
- debug(F101," npad ","", npad);
- debug(F101," padch ","", padch);
- debug(F101," seol ","", seol);
- debug(F101," ctlq ","", ctlq);
- debug(F101," ebq ","", ebq);
- debug(F101," ebqflg","",ebqflg);
- debug(F101," bctr ","", bctr);
- debug(F101," rptq ","", rptq);
- debug(F101," rptflg","",rptflg);
- debug(F101," lscapu","",lscapu);
- debug(F101," atcapu","",atcapu);
- debug(F101," lpcapu","",lpcapu);
- debug(F101," swcapu","",swcapu);
- debug(F101," wslotn","", wslotn);
- debug(F101," whatru","", whatru);
-}
-/* R D E B U -- Debugging display of rpar() values */
-
-VOID
-rdebu(d,len) CHAR *d; int len; {
- debug(F111,"rpar: data",d,len);
- debug(F101," rpsiz ","", xunchar(d[0]));
- debug(F101," rtimo ","", rtimo);
- debug(F101," mypadn","",mypadn);
- debug(F101," mypadc","",mypadc);
- debug(F101," eol ","", eol);
- debug(F101," ctlq ","", ctlq);
- debug(F101," sq ","", sq);
- debug(F101," ebq ","", ebq);
- debug(F101," ebqflg","",ebqflg);
- debug(F101," bctr ","", bctr);
- debug(F101," rptq ","", d[8]);
- debug(F101," rptflg","",rptflg);
- debug(F101," capas ","", capas);
- debug(F101," bits ","",d[capas]);
- debug(F101," lscapu","",lscapu);
- debug(F101," atcapu","",atcapu);
- debug(F101," lpcapu","",lpcapu);
- debug(F101," swcapu","",swcapu);
- debug(F101," wslotr","", wslotr);
- debug(F101," rpsiz(extended)","",rpsiz);
-}
-
-#ifdef COMMENT
-/* C H K E R R -- Decide whether to exit upon a protocol error */
-
-VOID
-chkerr() {
- if (backgrd && !server) fatal("Protocol error");
-}
-#endif /* COMMENT */
-#endif /* NOXFER */
-
-/* F A T A L -- Fatal error message */
-
-VOID
-fatal(msg) char *msg; {
- extern int initflg;
- static int initing = 0;
- if (!msg) msg = "";
- debug(F111,"fatal",msg,initflg);
-
- if (!initflg) { /* If called from prescan */
- if (initing) /* or called from sysinit() */
- exit(253);
- initing = 1;
- sysinit();
- }
-
- debug(F111,"fatal",msg,xitsta);
- tlog(F110,"Fatal:",msg,0L);
-#ifdef VMS
- if (strncmp(msg,"%CKERMIT",8))
- conol("%CKERMIT-E-FATAL, ");
- conoll(msg);
-#else /* !VMS */
- conoll(msg);
-#endif /* VMS */
-#ifdef OS2
-#ifndef NOXFER
- if (xfrbel) {
- bleep(BP_FAIL);
- sleep(1);
- bleep(BP_FAIL);
- }
-#endif /* NOXFER */
-
-#endif /* OS2 */
- doexit(BAD_EXIT,xitsta | 1); /* Exit indicating failure */
-}
-
-#ifndef NOXFER
-/* B L D L E N -- Make length-encoded copy of string */
-
-char *
-bldlen(str,dest) char *str, *dest; {
- int len;
- len = (int)strlen(str);
- if (len > 94)
- *dest = SP;
- else
- *dest = (char) tochar(len);
- strcpy(dest+1,str); /* Checked below in setgen() */
- return(dest+len+1);
-}
-
-
-/* S E T G E N -- Construct a generic command */
-/*
- Call with Generic command character followed by three string arguments.
- Trailing strings are allowed to be empty (""). Each string except the last
- non-empty string must be less than 95 characters long. The final nonempty
- string is allowed to be longer.
-*/
-CHAR
-#ifdef CK_ANSIC
-setgen(char type, char * arg1, char * arg2, char * arg3)
-#else
-setgen(type,arg1,arg2,arg3) char type, *arg1, *arg2, *arg3;
-#endif /* CK_ANSIC */
-/* setgen */ {
- char *upstr, *cp;
-#ifdef DYNAMIC
- if (!cmdstr)
- if (!(cmdstr = malloc(MAXSP + 1)))
- fatal("setgen: can't allocate memory");
-#endif /* DYNAMIC */
-
- cp = cmdstr;
- *cp++ = type;
- *cp = NUL;
- if (!arg1) arg1 = "";
- if (!arg2) arg2 = "";
- if (!arg3) arg3 = "";
- if (((int)strlen(arg1)+(int)strlen(arg2)+(int)strlen(arg3)+4) < MAXSP) {
- if (*arg1 != NUL) {
- upstr = bldlen(arg1,cp);
- if (*arg2 != NUL) {
- upstr = bldlen(arg2,upstr);
- if (*arg3 != NUL) bldlen(arg3,upstr);
- }
- }
- cmarg = cmdstr;
- debug(F110,"setgen",cmarg,0);
- return('g');
- }
- return('E');
-}
-#endif /* NOXFER */
-
-#ifndef NOMSEND
-static char *mgbufp = NULL;
-
-/* F N P A R S E -- */
-
-/*
- Argument is a character string containing one or more filespecs.
- This function breaks the string apart into an array of pointers, one
- to each filespec, and returns the number of filespecs. Used by server
- when it receives a GET command to allow it to process multiple file
- specifications in one transaction. Sets cmlist to point to a list of
- file pointers, exactly as if they were command line arguments.
-
- This version of fnparse treats spaces as filename separators. If your
- operating system allows spaces in filenames, you'll need a different
- separator.
-
- This version of fnparse mallocs a string buffer to contain the names. It
- cannot assume that the string that is pointed to by the argument is safe.
-*/
-int
-fnparse(string) char *string; {
- char *p, *s, *q;
- int r = 0, x; /* Return code */
-#ifdef RECURSIVE
- debug(F111,"fnparse",string,recursive);
-#endif /* RECURSIVE */
-
- if (mgbufp) free(mgbufp); /* Free this from last time. */
- mgbufp = malloc((int)strlen(string)+2);
- if (!mgbufp) {
- debug(F100,"fnparse malloc error","",0);
- return(0);
- }
-#ifndef NOICP
-#ifndef NOSPL
- ckstrncpy(fspec,string,fspeclen); /* Make copy for \v(filespec) */
-#endif /* NOSPL */
-#endif /* NOICP */
- s = string; /* Input string */
- p = q = mgbufp; /* Point to the copy */
- r = 0; /* Initialize our return code */
- while (*s == SP || *s == HT) /* Skip leading spaces and tabs */
- s++;
- for (x = strlen(s); /* Strip trailing spaces */
- (x > 1) && (s[x-1] == SP || s[x-1] == HT);
- x--)
- s[x-1] = NUL;
- while (1) { /* Loop through rest of string */
- if (*s == CMDQ) { /* Backslash (quote character)? */
- if ((x = xxesc(&s)) > -1) { /* Go interpret it. */
- *q++ = (char) x; /* Numeric backslash code, ok */
- } else { /* Just let it quote next char */
- s++; /* get past the backslash */
- *q++ = *s++; /* deposit next char */
- }
- continue;
- } else if (*s == SP || *s == NUL) { /* Unquoted space or NUL? */
- *q++ = NUL; /* End of output filename. */
- msfiles[r] = p; /* Add this filename to the list */
- debug(F111,"fnparse",msfiles[r],r);
- r++; /* Count it */
- if (*s == NUL) break; /* End of string? */
- while (*s == SP) s++; /* Skip repeated spaces */
- p = q; /* Start of next name */
- continue;
- } else *q++ = *s; /* Otherwise copy the character */
- s++; /* Next input character */
- }
- debug(F101,"fnparse r","",r);
- msfiles[r] = ""; /* Put empty string at end of list */
- cmlist = msfiles;
- return(r);
-}
-#endif /* NOMSEND */
-
-char * /* dbchr() for DEBUG SESSION */
-dbchr(c) int c; {
- static char s[8];
- char *cp = s;
-
- c &= 0xff;
- if (c & 0x80) { /* 8th bit on */
- *cp++ = '~';
- c &= 0x7f;
- }
- if (c < SP) { /* Control character */
- *cp++ = '^';
- *cp++ = (char) ctl(c);
- } else if (c == DEL) {
- *cp++ = '^';
- *cp++ = '?';
- } else { /* Printing character */
- *cp++ = (char) c;
- }
- *cp = '\0'; /* Terminate string */
- cp = s; /* Return pointer to it */
- return(cp);
-}
-
-/* C K H O S T -- Get name of local host (where C-Kermit is running) */
-
-/*
- Call with pointer to buffer to put hostname in, and length of buffer.
- Copies hostname into buffer on success, puts null string in buffer on
- failure.
-*/
-#ifdef BSD44
-#define BSD4
-#undef ATTSV
-#endif /* BSD44 */
-
-#ifdef SVORPOSIX
-#ifndef BSD44
-#ifndef apollo
-#include <sys/utsname.h>
-#endif /* apollo */
-#endif /* BSD44 */
-#else
-#ifdef BELLV10
-#include <utsname.h>
-#endif /* BELLV10 */
-#endif /* SVORPOSIX*/
-
-#ifdef CKSYSLOG
-extern char uidbuf[], * clienthost;
-#endif /* CKSYSLOG */
-
-VOID
-ckhost(vvbuf,vvlen) char * vvbuf; int vvlen; {
-
-#ifndef NOPUSH
- extern int nopush;
-#ifndef NOSERVER
- extern int en_hos;
-#endif /* NOSERVER */
-#endif /* NOPUSH */
-
-#ifdef pdp11
- *vvbuf = NUL;
-#else /* Everything else - rest of this routine */
-
- char *g;
- int havefull = 0;
-#ifdef VMS
- int x;
-#endif /* VMS */
-
-#ifdef SVORPOSIX
-#ifndef BSD44
-#ifndef _386BSD
-#ifndef APOLLOSR10
- struct utsname hname;
-#endif /* APOLLOSR10 */
-#endif /* _386BSD */
-#endif /* BSD44 */
-#endif /* SVORPOSIX */
-#ifdef datageneral
- int ac0 = (char *) vvbuf, ac1 = -1, ac2 = 0;
-#endif /* datageneral */
-
-#ifndef NOPUSH
- if (getenv("CK_NOPUSH")) { /* No shell access allowed */
- nopush = 1; /* on this host... */
-#ifndef NOSERVER
- en_hos = 0;
-#endif /* NOSERVER */
- }
-#endif /* NOPUSH */
-
- *vvbuf = NUL; /* How let's get our host name ... */
-
-#ifndef BELLV10 /* Does not have gethostname() */
-#ifndef OXOS
-#ifdef SVORPOSIX
-#ifdef APOLLOSR10
- ckstrncpy(vvbuf,"Apollo",vvlen);
-#else
-#ifdef BSD44
- if (gethostname(vvbuf,vvlen) < 0)
- *vvbuf = NUL;
-#else
-#ifdef _386BSD
- if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL;
-#else
-#ifdef QNX
-#ifdef TCPSOCKET
- if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL;
-#else
- if (uname(&hname) > -1) ckstrncpy(vvbuf,hname.nodename,vvlen);
-#endif /* TCPSOCKET */
-#else /* SVORPOSIX but not _386BSD or BSD44 */
-#ifdef __ia64__
- if (uname(&hname) > -1) ckstrncpy(vvbuf,hname.nodename,vvlen);
-#else
- if (uname(&hname) > -1) {
- char * p;
- p = hname.nodename;
-#ifdef TCPSOCKET
-#ifndef NOCKGETFQHOST
- if (!ckstrchr(p,'.'))
- p = (char *)ckgetfqhostname(p);
-#endif /* NOCKGETFQHOST */
-#endif /* TCPSOCKET */
- if (!p) p = "";
- if (!*p) p = "(unknown)";
- ckstrncpy(vvbuf,p,vvlen);
- }
-#endif /* __ia64__ */
-#endif /* QNX */
-#endif /* _386BSD */
-#endif /* BSD44 */
-#endif /* APOLLOSR10 */
-#else /* !SVORPOSIX */
-#ifdef BSD4
- if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL;
-#else /* !BSD4 */
-#ifdef VMS
- g = getenv("SYS$NODE");
- if (g) ckstrncpy(vvbuf,g,vvlen);
- x = (int)strlen(vvbuf);
- if (x > 1 && vvbuf[x-1] == ':' && vvbuf[x-2] == ':') vvbuf[x-2] = NUL;
-#else
-#ifdef datageneral
- if (sys($HNAME,&ac0,&ac1,&ac2) == 0) /* successful */
- vvlen = ac2 + 1; /* enh - have to add one */
-#else
-#ifdef OS2 /* OS/2 */
- g = os2_gethostname();
- if (g) ckstrncpy(vvbuf,g,vvlen);
-#else /* OS2 */
-#ifdef OSK
-#ifdef TCPSOCKET
- if (gethostname(vvbuf, vvlen) < 0) *vvbuf = NUL;
-#endif /* TCPSOCKET */
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* datageneral */
-#endif /* VMS */
-#endif /* BSD4 */
-#endif /* SVORPOSIX */
-#else /* OXOS */
- /* If TCP/IP is not installed, gethostname() fails, use uname() */
- if (gethostname(vvbuf,vvlen) < 0) {
- if (uname(&hname) > -1)
- ckstrncpy(vvbuf,hname.nodename,vvlen);
- else
- *vvbuf = NUL;
- }
-#endif /* OXOS */
-#endif /* BELLV10 */
- if (*vvbuf == NUL) { /* If it's still empty */
- g = getenv("HOST"); /* try this */
- if (g) ckstrncpy(vvbuf,g,vvlen);
- }
- vvbuf[vvlen-1] = NUL; /* Make sure result is terminated. */
-#endif /* pdp11 */
-}
-#ifdef BSD44
-#undef BSD4
-#define ATTSV
-#endif /* BSD44 */
-
-/*
- A S K M O R E -- Poor person's "more".
- Returns 0 if no more, 1 if more wanted.
-*/
-int
-askmore() {
- char c;
- int rv, cx;
-#ifdef IKSD
- extern int timelimit;
-#endif /* IKSD */
-#ifdef IKSDCONF
- extern int iksdcf;
-#endif /* IKSDCONF */
-#ifdef CK_APC
- extern int apcstatus, apcactive;
-#endif /* CK_APC */
-
-#ifdef NOICP
- return(1);
-#else
- if (!xaskmore)
- return(1);
-#ifdef IKSDCONF
- if (inserver && !iksdcf)
- return(1);
-#endif /* IKSDCONF */
-#ifdef CK_APC
- if (apcactive == APC_LOCAL ||
- (apcactive == APC_REMOTE && (apcstatus & APC_NOINP)))
- return(1);
-#endif /* CK_APC */
-#ifdef VMS
- if (batch)
- return(1);
-#else
-#ifdef UNIX
- if (backgrd)
- return(1);
-#endif /* UNIX */
-#endif /* VMS */
-
-#ifndef VMS
- concb((char)escape); /* Force CBREAK mode. */
-#endif /* VMS */
-
- rv = -1;
- while (rv < 0) {
-#ifndef OS2
- printf("more? ");
-#ifdef UNIX
-#ifdef NOSETBUF
- fflush(stdout);
-#endif /* NOSETBUF */
-#endif /* UNIX */
-#else
- printf("more? ");
- fflush(stdout);
-#endif /* OS2 */
-
-#ifdef IKSD
- if (inserver) {
- cx = cmdgetc(timelimit);
- if (cx < -1 && timelimit) {
- printf("\n?IKS idle timeout - Goodbye.\n");
- doexit(GOOD_EXIT,0);
- } else if (cx == -1) { /* Connection lost */
- doexit(BAD_EXIT,0);
- }
- c = (char) cx;
- } else {
-#endif /* IKSD */
-#ifdef VMS
- conbin((char)escape); /* Protect against Ctrl-Z */
- cx = coninc(0);
- concb((char)escape);
-#else
- cx = cmdgetc(0);
-#endif /* VMS */
- debug(F101,"askmore cmdgetc","",cx);
- if (cx == EOF) {
- debug(F100,"askmore EOF","",0);
-#ifdef VMS
- c = '\032';
-#else
- c = 'n';
-#endif /* VMS */
- } else {
- c = (char)cx;
- }
- debug(F101,"askmore c","",c);
-
-#ifdef IKSD
- }
-#endif /* IKSD */
- switch (c) {
- /* Yes */
- case 'p': case 'P': case 'g': case 'G': /* Proceed or Go */
- xaskmore = 0;
- /* fall thru on purpose */
-
- case SP: case 'y': case 'Y': case 012: case 015:
-#ifdef OSK
- write(1, "\015 \015", sizeof "\015 \015" - 1);
-#else
- printf("\015 \015");
-#endif /* OSK */
- rv = 1;
- break;
- /* No */
- case 'n': case 'N': case 'q': case 'Q':
-#ifdef OSK
- printf("\n");
-#else
- printf("\015\012");
-#endif /* OSK */
- rv = 0;
- break;
- case '\003':
- case '\004':
- case '\032':
-#ifdef OSK
- printf("^%c...\n", (c + 0100));
-#else
- printf("^%c...\015\012", (c + 0100));
-#endif /* OSK */
- rv = 0;
- break;
- /* Invalid answer */
- default:
- debug(F111,"askmore","invalid answer",c);
- printf("Y or space-bar for yes, N for no, G to show the rest\n");
- continue;
- }
-#ifdef OS2
- printf("\r \r");
- fflush(stdout);
-#endif /* OS2 */
- }
- return(rv);
-#endif /* NOICP */
-}
-
-/* T R A P -- Terminal interrupt handler */
-
-SIGTYP
-#ifdef CK_ANSIC
-trap(int sig)
-#else
-trap(sig) int sig;
-#endif /* CK_ANSIC */
-/* trap */ {
- extern int b_save, f_save;
-#ifndef NOICP
- extern int timelimit;
-#endif /* NOICP */
-#ifdef OS2
- extern unsigned long startflags;
-#ifndef NOSETKEY
- extern int os2gks;
-#endif /* NOSETKEY */
- int i;
-#endif /* OS2 */
-#ifndef NOSPL
- extern int i_active, instatus;
-#endif /* NOSPL */
-#ifdef VMS
- int i; FILE *f;
-#endif /* VMS */
- extern int zchkod, zchkid;
-#ifndef NOSPL
- extern int unkmacro;
-#endif /* NOSPL */
-
- debok = 1;
-#ifdef NTSIG
- connoi();
-#endif /* NTSIG */
-#ifdef __EMX__
- signal(SIGINT, SIG_ACK);
-#endif
-#ifdef GEMDOS
-/* GEM is not reentrant, no i/o from interrupt level */
- cklongjmp(cmjbuf,1); /* Jump back to parser now! */
-#endif /* GEMDOS */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F100,"*********************","",0);
- if (sig == SIGINT)
- debug(F101,"trap caught SIGINT","",sig);
- else
- debug(F101,"trap caught signal","",sig);
- debug(F100,"*********************","",0);
- }
-#endif /* DEBUG */
-
-#ifdef OS2
- if ( sig == SIGBREAK && (startflags & 128) ) {
- debug(F101,"trap ignoring SIGBREAK","",sig);
- return;
- }
-#endif /* OS2 */
-
-#ifndef NOICP
- timelimit = 0; /* In case timed ASK interrupted */
-#ifndef NOSPL
- unkmacro = 0; /* Or ON_UNKNOWN_MACRO interrupted.. */
-#endif /* NOSPL */
-#endif /* NOICP */
- zchkod = 0; /* Or file expansion interrupted... */
- zchkid = 0;
- interrupted = 1;
-
- if (what & W_CONNECT) { /* Are we in CONNECT mode? */
-/*
- The HP workstation Reset key sends some kind of ueber-SIGINT that can not
- be SIG_IGNored, so we wind up here somehow (even though this is *not* the
- current SIGINT handler). Just return.
-*/
- debug(F101,"trap: SIGINT caught during CONNECT","",sig);
- SIGRETURN;
- }
-#ifndef NOSPL
- if (i_active) { /* INPUT command was active? */
- i_active = 0; /* Not any more... */
- instatus = INP_UI; /* INPUT status = User Interrupted */
- }
-#endif /* NOSPL */
-
-#ifndef NOXFER
- ftreset(); /* Restore global protocol settings */
- binary = b_save; /* Then restore these */
- fncnv = f_save;
- bye_active = 0;
- diractive = 0;
- cdactive = 0;
-#endif /* NOXFER */
- zclose(ZIFILE); /* If we were transferring a file, */
- zclose(ZOFILE); /* close it. */
-#ifndef NOICP
- cmdsquo(cmd_quoting); /* If command quoting was turned off */
-#ifdef CKLEARN
- {
- extern FILE * learnfp;
- extern int learning;
- if (learnfp) {
- fclose(learnfp);
- learnfp = NULL;
- learning = 0;
- }
- }
-#endif /* CKLEARN */
-#endif /* NOICP */
-#ifdef CK_APC
- delmac("_apc_commands",1);
- apcactive = APC_INACTIVE;
-#endif /* CK_APC */
-
-#ifdef VMS
-/*
- Fix terminal.
-*/
- if (ft_win) { /* If curses window open */
- debug(F100,"^C trap() curses","",0);
- xxscreen(SCR_CW,0,0L,""); /* Close it */
- conres(); /* Restore terminal */
- i = printf("^C..."); /* Echo ^C to standard output */
- } else {
- conres();
- i = printf("^C...\n"); /* Echo ^C to standard output */
- }
- if (i < 1 && ferror(stdout)) { /* If there was an error */
- debug(F100,"^C trap() error","",0);
- fclose(stdout); /* close standard output */
- f = fopen(dftty, "w"); /* open the controlling terminal */
- if (f) stdout = f; /* and make it standard output */
- printf("^C...\n"); /* and echo the ^C again. */
- }
-#else /* Not VMS */
-#ifdef STRATUS
- conres(); /* Set console back to normal mode */
-#endif /* STRATUS */
-#ifndef NOXFER
- if (ft_win) { /* If curses window open, */
- debug(F100,"^C trap() curses","",0);
- xxscreen(SCR_CW,0,0L,""); /* close it. */
- printf("^C..."); /* Echo ^C to standard output */
- } else {
-#endif /* NOXFER */
- printf("^C...\n");
-#ifndef NOXFER
- }
-#endif /* NOXFER */
-#endif /* VMS */
-#ifdef datageneral
- connoi_mt(); /* Kill asynch task that listens to */
- ttimoff();
- conres(); /* the keyboard */
-#endif /* datageneral */
-
-#ifndef NOCCTRAP
-/* This is stupid -- every version should have ttimoff()... */
-#ifdef UNIX
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef OSK
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef STRATUS
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef OS2
-#ifndef NOSETKEY
- os2gks = 1; /* Turn back on keycode mapping */
-#endif /* NOSETKEY */
-#ifndef NOLOCAL
- for (i = 0; i < VNUM; i++)
- VscrnResetPopup(i);
-#endif /* NOLOCAL */
-#ifdef TCPSOCKET
-#ifdef NT
- /* WSAIsBlocking() returns FALSE in Win95 during a blocking accept call */
- if ( WSASafeToCancel /* && WSAIsBlocking() */ ) {
- WSACancelBlockingCall();
- }
-#endif /* NT */
-#endif /* TCPSOCKET */
-#ifdef CK_NETBIOS
- NCBCancelOutstanding();
-#endif /* CK_NETBIOS */
- ttimoff(); /* Turn off any timer interrupts */
-#else
-#ifdef VMS
- ttimoff(); /* Turn off any timer interrupts */
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* STRATUS */
-#endif /* OSK */
-#endif /* UNIX */
-
-#ifdef NETPTY
- /* Clean up Ctrl-C out of REDIRECT or external protocol */
- {
- extern PID_T pty_fork_pid;
- extern int pty_master_fd, pty_slave_fd;
- int x;
-
- signal(SIGCHLD,SIG_IGN); /* We don't want this any more */
-
- debug(F101,"trap pty_master_fd","",pty_master_fd);
- if (pty_master_fd > 2) {
- x = close(pty_master_fd);
- debug(F101,"trap pty_master_fd close","",x);
- }
- pty_master_fd = -1;
- debug(F101,"trap pty_slave_fd","",pty_slave_fd);
- if (pty_slave_fd > 2) {
- x = close(pty_slave_fd);
- debug(F101,"trap pty_slave_fd close","",x);
- }
- pty_slave_fd = -1;
- debug(F101,"trap pty_fork_pid","",pty_fork_pid);
- if (pty_fork_pid > 0) {
- x = kill(pty_fork_pid,0); /* See if the fork is really there */
- debug(F111,"trap pty_fork_pid kill 0 errno",ckitoa(x),errno);
- if (x == 0) { /* Seems to be active */
- x = kill(pty_fork_pid,SIGHUP); /* Ask it to clean up & exit */
- debug(F101,"trap pty_fork_pid kill SIGHUP","",x);
- msleep(100);
- errno = 0;
- x = kill(pty_fork_pid,0); /* Is it still there? */
- if (x == 0
-#ifdef ESRCH
- /* This module is not always exposed to <errno.h> */
- || errno != ESRCH
-#endif /* ESRCH */
- ) {
- x = kill(pty_fork_pid,SIGKILL);
- debug(F101,"trap pty_fork_pid kill SIGKILL","",x);
- }
- }
- pty_fork_pid = -1;
- }
- }
-#endif /* NETPTY */
-
-#ifdef OSK
- sigmask(-1);
-/*
- We are in an intercept routine but do not perform a F$RTE (done implicitly
- by rts). We have to decrement the sigmask as F$RTE does. Warning: longjump
- only restores the cpu registers, NOT the fpu registers. So don't use fpu at
- all or at least don't use common fpu (double or float) register variables.
-*/
-#endif /* OSK */
-
-#ifdef NTSIG
- PostCtrlCSem();
-#else /* NTSIG */
- debug(F100,"trap about to longjmp","",0);
-#ifdef NT
- cklongjmp(ckjaddr(cmjbuf),1);
-#else /* NT */
- cklongjmp(cmjbuf,1);
-#endif /* NT */
-#endif /* NTSIG */
-#else /* NOCCTRAP */
-/* No Ctrl-C trap, just exit. */
-#ifdef CK_CURSES /* Curses support? */
- xxscreen(SCR_CW,0,0L,""); /* Close curses window */
-#endif /* CK_CURSES */
- doexit(BAD_EXIT,what); /* Exit poorly */
-#endif /* NOCCTRAP */
- SIGRETURN;
-}
-
-
-/* C K _ T I M E -- Returns pointer to current time. */
-
-char *
-ck_time() {
- static char tbuf[10];
- char *p;
- int x;
-
- ztime(&p); /* "Thu Feb 8 12:00:00 1990" */
- if (!p) /* like asctime()! */
- return("");
- if (*p) {
- for (x = 11; x < 19; x++) /* copy hh:mm:ss */
- tbuf[x - 11] = p[x]; /* to tbuf */
- tbuf[8] = NUL; /* terminate */
- }
- return(tbuf); /* and return it */
-}
-
-/* C C _ C L E A N -- Cleanup after terminal interrupt handler */
-
-#ifdef GEMDOS
-int
-cc_clean() {
- zclose(ZIFILE); /* If we were transferring a file, */
- zclose(ZOFILE); /* close it. */
- printf("^C...\n"); /* Not VMS, no problem... */
-}
-#endif /* GEMDOS */
-
-
-/* S T P T R A P -- Handle SIGTSTP (suspend) signals */
-
-SIGTYP
-#ifdef CK_ANSIC
-stptrap(int sig)
-#else
-stptrap(sig) int sig;
-#endif /* CK_ANSIC */
-/* stptrap */ {
-
-#ifndef NOJC
- int x; extern int cmflgs;
- debug(F101,"stptrap() caught signal","",sig);
- if (!xsuspend) {
- printf("\r\nsuspend disabled\r\n");
-#ifndef NOICP
- if (what & W_COMMAND) { /* If we were parsing commands */
- prompt(xxstring); /* reissue the prompt and partial */
- if (!cmflgs) /* command (if any) */
- printf("%s",cmdbuf);
- }
-#endif /* NOICP */
- } else {
- conres(); /* Reset the console */
-#ifndef OS2
- /* Flush pending output first, in case we are continued */
- /* in the background, which could make us block */
- fflush(stdout);
-
- x = psuspend(xsuspend); /* Try to suspend. */
- if (x < 0)
-#endif /* OS2 */
- printf("Job control not supported\r\n");
- conint(trap,stptrap); /* Rearm the trap. */
- debug(F100,"stptrap back from suspend","",0);
- switch (what) {
- case W_CONNECT: /* If suspended during CONNECT? */
- conbin((char)escape); /* put console back in binary mode */
- debug(F100,"stptrap W_CONNECT","",0);
- break;
-#ifndef NOICP
- case W_COMMAND: /* Suspended in command mode */
- debug(F101,"stptrap W_COMMAND pflag","",pflag);
- concb((char)escape); /* Put back CBREAK tty mode */
- if (pflag) { /* If command parsing was */
- prompt(xxstring); /* reissue the prompt and partial */
- if (!cmflgs) /* command (if any) */
- printf("%s",cmdbuf);
- }
- break;
-#endif /* NOICP */
- default: /* All other cases... */
- debug(F100,"stptrap default","",0);
- concb((char)escape); /* Put it back in CBREAK mode */
- break;
- }
- }
-#endif /* NOJC */
- SIGRETURN;
-}
-
-#ifdef TLOG
-#define TBUFL 300
-
-/* T L O G -- Log a record in the transaction file */
-/*
- Call with a format and 3 arguments: two strings and a number:
- f - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
- s1,s2 - String arguments 0 and 1.
- n - Long, argument 2.
-*/
-VOID
-#ifdef CK_ANSIC
-dotlog(int f, char *s1, char *s2, CK_OFF_T n)
-#else
-dotlog(f,s1,s2,n) int f; CK_OFF_T n; char *s1, *s2;
-#endif /* CK_ANSIC */
-/* dotlog */ {
- static char s[TBUFL];
- extern int tlogfmt;
- char *sp = s; int x;
- if (!s1) s1 = "";
- if (!s2) s2 = "";
-
- if (!tralog) return; /* If no transaction log, don't */
- if (tlogfmt != 1) return;
- switch (f) {
- case F000: /* 0 (special) "s1 n s2" */
- if ((int)strlen(s1) + (int)strlen(s2) + 15 > TBUFL)
- sprintf(sp,"?T-Log string too long");
- else
- sprintf(sp,"%s %s %s",s1,ckfstoa(n),s2);
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F001: /* 1, " n" */
- sprintf(sp," %s",ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F010: /* 2, "[s2]" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if (x + 6 > TBUFL)
- sprintf(sp,"?String too long");
- else sprintf(sp,"[%s]",s2);
- if (zsoutl(ZTFILE,"") < 0) tralog = 0;
- break;
- case F011: /* 3, "[s2] n" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if (x + 6 > TBUFL)
- sprintf(sp,"?String too long");
- else sprintf(sp,"[%s] %s",s2,ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F100: /* 4, "s1" */
- if (zsoutl(ZTFILE,s1) < 0) tralog = 0;
- break;
- case F101: /* 5, "s1: n" */
- if ((int)strlen(s1) + 15 > TBUFL)
- sprintf(sp,"?String too long");
- else sprintf(sp,"%s: %s",s1,ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F110: /* 6, "s1 s2" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if ((int)strlen(s1) + x + 4 > TBUFL)
- sprintf(sp,"?String too long");
- else
- sprintf(sp,"%s%s%s",s1,((*s2 == ':') ? "" : " "),s2);
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- case F111: /* 7, "s1 s2: n" */
- x = (int)strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- if ((int)strlen(s1) + x + 15 > TBUFL)
- sprintf(sp,"?String too long");
- else
- sprintf(sp,"%s%s%s: %s",s1,((*s2 == ':') ? "" : " "),s2,ckfstoa(n));
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- break;
- default:
- sprintf(sp,"?Invalid format for tlog() - %d",f);
- if (zsoutl(ZTFILE,s) < 0) tralog = 0;
- }
-}
-
-/*
- D O X L O G
-
- This is the transaction-log writer for BRIEF format.
- The idea is produce one record (line) per file. Each record
- has the following delimited fields:
- Date (yyyymmdd)
- Time (hh:mm:ss)
- Action: SEND or RECV
- File name
- File size
- Transfer mode (text, binary, image, labeled, etc).
- Status: OK or FAILED
- Free-form comments in doublequotes
- The default separator is comma.
- If a field contains the separator, it is enclosed in doublequotes.
-*/
-VOID
-#ifdef CK_ANSIC
-doxlog(int x, char * fn, CK_OFF_T fs, int fm, int status, char * msg)
-#else
-doxlog(x, fn, fs, fm, status, msg)
- int x; char * fn; CK_OFF_T fs; int fm; int status; char * msg;
-#endif /* CK_ANSIC */
-/* doxlog */ {
- extern int tlogsep;
- char sep[2];
- char buf[CKMAXPATH+256], * bufp;
- char tmpbuf[32];
- char * s, * p;
- int len, left, ftp = 0, k;
-
- if (!tralog) return; /* If no transaction log, don't */
-
- if (!fn) fn = ""; /* Protect against null pointers */
- if (!msg) msg = "";
- if (x & W_FTP)
- ftp++;
-
- sep[0] = (char) tlogsep;
- sep[1] = NUL;
- if (!sep[0]) sep[0] = ',';
-
- bufp = buf;
- left = sizeof(buf);
- debug(F101,"XXX doxlog left 1","",left);
-
- p = zzndate(); /* Date */
- ckmakmsg(buf, left, p ? p : "00000000", sep, NULL, NULL);
- bufp += 9;
- left -= 9;
- debug(F111,"XXX doxlog left 2",buf,left);
-
- ztime(&p);
- ckstrncpy(bufp,p+11,left);
- bufp += 8;
- left -= 8;
- debug(F111,"XXX doxlog left 3",buf,left);
-
- if (ftp) {
- if (!(x & (W_SEND|W_RECV)))
- return;
- s = (x & W_SEND) ? "PUT" : "GET";
- k = 3;
- } else {
- s = (x & W_SEND) ? "SEND" : "RECV";
- k = 4;
- }
- ckmakmsg(bufp,left,sep,s,sep,NULL);
- bufp += k + 2;
- left -= (k + 2);
- debug(F111,"XXX doxlog left 4",buf,left);
-
- s = "";
- if (ckstrchr(fn,sep[0])) /* Filename */
- s = "\"";
- ckmakmsg(bufp,left,s,fn,s,sep);
- sprintf(tmpbuf,"%s",ckfstoa(fs)); /* Size */
- ckstrncat(buf,tmpbuf,CKMAXPATH);
- ckstrncat(buf,sep,CKMAXPATH);
- debug(F110,"doxlog 4",buf,0);
-
-#ifdef NOICP
- /* Transfer mode */
- ckstrncpy(tmpbuf, (binary ? "binary" : "text"), TMPBUFSIZ);
-#else
- ckstrncpy(tmpbuf,gfmode(fm,0),TMPBUFSIZ);
-#endif /* NOICP */
- if (ckstrchr(tmpbuf,sep[0])) { /* Might contain spaces */
- ckstrncat(buf,"\"",CKMAXPATH);
- ckstrncat(buf,tmpbuf,CKMAXPATH);
- ckstrncat(buf,"\"",CKMAXPATH);
- } else
- ckstrncat(buf,tmpbuf,CKMAXPATH);
- ckstrncat(buf,sep,CKMAXPATH);
- debug(F110,"doxlog 5",buf,0);
-
- ckstrncat(buf, status ? "FAILED" : "OK",CKMAXPATH);
- len = strlen(buf);
- left = CKMAXPATH+256 - len;
- if (left < 2) fatal("doxlog buffer overlow");
-
- debug(F111,"XXX doxlog left 5",buf,left);
-
- debug(F110,"doxlog buf 1", buf, len);
- s = buf + len;
- if (status == 0 && left > 32) {
- long cps = 0L;
-#ifdef GFTIMER
- debug(F101,"DOXLOG fpxfsecs","",(long)(fpxfsecs * 1000));
- if (fpxfsecs) cps = (long)((CKFLOAT) fs / fpxfsecs);
- sprintf(s,"%s\"%0.3fsec %ldcps\"",sep,fpxfsecs,cps);
-#else
- if (xfsecs) cps = fs / xfsecs;
- sprintf(s,"%s\"%ldsec %ldcps\"",sep,xfsecs,cps);
-#endif /* GFTIMER */
- } else if ((int)strlen(msg) + 4 < left) {
- sprintf(s,"%s\"%s\"",sep,msg);
- }
- debug(F111,"XXX doxlog left 5",buf,left);
-
- debug(F110,"doxlog 5",buf,0);
- x = zsoutl(ZTFILE,buf);
- debug(F101,"doxlog zsoutl","",x);
- if (x < 0) tralog = 0;
-}
-#endif /* TLOG */
-
-#ifndef MAC
-/*
- The rest of this file is for all implementations but the Macintosh.
-*/
-
-#ifdef CK_CURSES
-static int repaint = 0; /* Transfer display needs repainting */
-#endif /* CK_CURSES */
-
-#ifndef NOXFER
-/* C H K I N T -- Check for console interrupts */
-
-/*
- Used during file transfer in local mode only:
- . If user has not touched the keyboard, returns 0 with no side effects.
- . If user typed S or A (etc, see below) prints status message and returns 0.
- . If user typed X or F (etc, see below) returns 0 with cxseen set to 1.
- . If user typed Z or B (etc, see below) returns 0 with czseen set to 1.
- . If user typed E or C (etc, see below) returns -1.
-*/
-int
-chkint() {
- int ch, cn, ofd; long zz;
- if (!xfrint)
- return(0);
- if ((!local) || (quiet)) return(0); /* Only do this if local & not quiet */
-#ifdef datageneral
- if (con_reads_mt) /* if conint_mt task is active */
- if (conint_avl) { /* and there's an interrupt pending */
- cn = 1; /* process it */
- ch = conint_ch;
- conint_avl = 0; /* turn off flag so conint_mt can */
- } else /* proceed */
- return(0);
- else /* if conint_mt not active */
- if ((ch = coninc(2)) < 0) /* try to get char manually */
- return(0); /* I/O error, or no data */
- else /* if successful, set cn so we */
- cn = 1; /* know we got one */
- debug(F101,"chkint got keyboard character",ch,cn);
-#else /* !datageneral */
-#ifdef NTSIG
- {
- extern int TlsIndex;
- struct _threadinfo * threadinfo;
- threadinfo = (struct _threadinfo *) TlsGetValue(TlsIndex);
- if (threadinfo) {
- if (!WaitSem(threadinfo->DieSem,0))
- return -1; /* Cancel Immediately */
- }
- }
-#endif /* NTSIG */
- cn = conchk(); /* Any input waiting? */
- debug(F101,"conchk","",cn);
- if (cn < 1) return(0);
- ch = coninc(5) ;
- debug(F101,"coninc","",ch);
- if (ch < 0) return(0);
-#endif /* datageneral */
-
- ch &= 0177;
- switch (ch) {
- case 'A': case 'a': case 0001: /* Status report */
- case 'S': case 's':
- if (fdispla != XYFD_R && fdispla != XYFD_S && fdispla != XYFD_N)
- return(0); /* Only for serial, simple or none */
- ofd = fdispla; /* [MF] Save file display type */
- if (fdispla == XYFD_N)
- fdispla = XYFD_R; /* [MF] Pretend serial if no display */
- xxscreen(SCR_TN,0,0l,"Status report:");
- xxscreen(SCR_TN,0,0l," file type: ");
- if (binary) {
- switch(binary) {
- case XYFT_L: xxscreen(SCR_TZ,0,0l,"labeled"); break;
- case XYFT_I: xxscreen(SCR_TZ,0,0l,"image"); break;
- case XYFT_U: xxscreen(SCR_TZ,0,0l,"binary undefined"); break;
- default:
- case XYFT_B: xxscreen(SCR_TZ,0,0l,"binary"); break;
- }
- } else {
-#ifdef NOCSETS
- xxscreen(SCR_TZ,0,0l,"text");
-#else
- xxscreen(SCR_TU,0,0l,"text, ");
- if (tcharset == TC_TRANSP || xfrxla == 0) {
- xxscreen(SCR_TZ,0,0l,"transparent");
- } else {
- if (what & W_SEND) {
- xxscreen(SCR_TZ,0,0l,tcsinfo[tcharset].keyword);
- xxscreen(SCR_TU,0,0l," => ");
- xxscreen(SCR_TZ,0,0l,fcsinfo[fcharset].keyword);
- } else {
- xxscreen(SCR_TZ,0,0l,fcsinfo[fcharset].keyword);
- xxscreen(SCR_TU,0,0l," => ");
- xxscreen(SCR_TZ,0,0l,tcsinfo[tcharset].keyword);
- }
- }
-#endif /* NOCSETS */
- }
- xxscreen(SCR_QE,0,filcnt," file number");
- if (fsize) xxscreen(SCR_QE,0,fsize," size");
- xxscreen(SCR_QE,0,ffc," characters so far");
- if (fsize > 0L) {
-#ifdef CK_RESEND
- zz = what & W_SEND ? sendstart : what & W_RECV ? rs_len : 0;
- zz = ( (ffc + zz) * 100L ) / fsize;
-#else
- zz = ( ffc * 100L ) / fsize;
-#endif /* CK_RESEND */
- xxscreen(SCR_QE,0,zz, " percent done");
- }
- if (bctu == 4) { /* Block check */
- xxscreen(SCR_TU,0,0L," block check: ");
- xxscreen(SCR_TZ,0,0L,"blank-free-2");
- } else xxscreen(SCR_QE,0,(long)bctu, " block check");
- xxscreen(SCR_QE,0,(long)rptflg," compression");
- xxscreen(SCR_QE,0,(long)ebqflg," 8th-bit prefixing");
- xxscreen(SCR_QE,0,(long)lscapu," locking shifts");
- if (!network)
- xxscreen(SCR_QE,0, speed, " speed");
- if (what & W_SEND)
-
- xxscreen(SCR_QE,0,spsiz, " packet length");
- else if (what & W_RECV || what & W_REMO)
- xxscreen(SCR_QE,0,urpsiz," packet length");
- xxscreen(SCR_QE,0,wslots, " window slots");
- fdispla = ofd; /* [MF] Restore file display type */
- return(0);
-
- case 'B': case 'b': case 0002: /* Cancel batch */
- case 'Z': case 'z': case 0032:
- czseen = 1;
- interrupted = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- (((what & W_RECV) && (wslots > 1)) ?
- "Canceling batch, wait... " :
- "Canceling batch... ")
- );
- return(0);
-
- case 'F': case 'f': case 0006: /* Cancel file */
- case 'X': case 'x': case 0030:
- cxseen = 1;
- interrupted = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- (((what & W_RECV) && (wslots > 1)) ?
- "Canceling file, wait... " :
- "Canceling file... ")
- );
- return(0);
-
- case 'R': case 'r': case 0022: /* Resend packet */
- case 0015: case 0012:
-#ifdef STREAMING
- if (streaming)
- return(0);
-#endif /* STREAMING */
- xxscreen(SCR_ST,ST_MSG,0l,"Resending packet... ");
- numerrs++;
- resend(winlo);
- return(0);
-
-#ifdef datageneral
- case '\03': /* We're not trapping ^C's with */
- trap(0); /* signals, so we check here */
-#endif /* datageneral */
-
- case 'C': case 'c': /* Ctrl-C */
-#ifndef datageneral
- case '\03':
-#endif /* datageneral */
-
- case 'E': case 'e': /* Send error packet */
- case 0005:
- interrupted = 1;
- return(-1);
-
-#ifdef CK_CURSES
- case 0014: /* Ctrl-L to refresh screen */
- case 'L': case 'l': /* Also accept L (upper, lower) */
- case 0027: /* Ctrl-W synonym for VMS & Ingres */
- repaint = 1;
- return(0);
-#endif /* CK_CURSES */
-
- case 'T':
- case 't': /* Turn on debug-log timestamps */
-#ifdef DEBUG
- {
- extern int debtim;
- if (ch == 'T') {
- debtim = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- "Debug timestamps On... ");
- } else {
- debtim = 1;
- xxscreen(SCR_ST,ST_MSG,0l,
- "Debug timestamps Off... ");
- }
- }
-#endif /* DEBUG */
- return(0);
-
- case 'D':
-#ifdef DEBUG
- if (!deblog) {
- debopn("debug.log",0);
- if (deblog) {
- xxscreen(SCR_ST,ST_MSG,0l,"debug.log open... ");
- } else {
- xxscreen(SCR_ST,ST_MSG,0l,"debug.log open FAILED... ");
- }
- } else {
- xxscreen(SCR_ST,ST_MSG,0l,"Debug log On... ");
- }
- if (deblog)
- debok = 1;
-#endif /* DEBUG */
- return(0);
-
- case 'd': /* Turn off debugging */
-#ifdef DEBUG
- if (deblog)
- xxscreen(SCR_ST,ST_MSG,0l,"Debug log Off... ");
- debok = 0;
-#endif /* DEBUG */
- return(0);
-
- default: /* Anything else, print message */
- intmsg(1L);
- return(0);
- }
-}
-
-/* I N T M S G -- Issue message about terminal interrupts */
-
-VOID
-#ifdef CK_ANSIC
-intmsg(long n)
-#else
-intmsg(n) long n;
-#endif /* CK_ANSIC */
-/* intmsg */ {
-#ifdef CK_NEED_SIG
- char buf[80];
-#endif /* CK_NEED_SIG */
-
- if (!displa || quiet) /* Not if we're being quiet */
- return;
- if (server && (!srvdis || n > -1L)) /* Special for server */
- return;
-#ifdef CK_NEED_SIG
- buf[0] = NUL; /* Keep compilers happy */
-#endif /* CK_NEED_SIG */
-#ifndef OXOS
-#ifdef SVORPOSIX
- conchk(); /* Clear out pending escape-signals */
-#endif /* SVORPOSIX */
-#endif /* ! OXOS */
-#ifdef VMS
- conres(); /* So Ctrl-C will work */
-#endif /* VMS */
- if ((!server && n == 1L) || (server && n < 0L)) {
-
-#ifdef CK_NEED_SIG
- if (xfrint) {
- ckmakmsg(buf,
- 80,
- "Type escape character (",
- dbchr(escape),
- ") followed by:",
- NULL
- );
- xxscreen(SCR_TN,0,0l,buf);
- }
-#endif /* CK_NEED_SIG */
-
- if (xfrint) {
- if (protocol == PROTO_K) {
- xxscreen(SCR_TN,0,0l,"X to cancel file, CR to resend current packet");
- xxscreen(SCR_TN,0,0l,"Z to cancel group, A for status report");
- xxscreen(SCR_TN,0,0l,"E to send Error packet, Ctrl-C to quit immediately: ");
- } else {
- xxscreen(SCR_TN,0,0l,"Ctrl-C to cancel file transfer: ");
- }
- } else {
- xxscreen(SCR_TN,0,0l,"Transfer interruption disabled. ");
- }
- }
- else xxscreen(SCR_TU,0,0l," ");
-}
-
-#ifndef NODISPLAY
-static int newdpy = 0; /* New display flag */
-static char fbuf[80]; /* Filename buffer */
-static char abuf[80]; /* As-name buffer */
-static char a2buf[80]; /* Second As-name buffer */
-static CK_OFF_T oldffc = 0L;
-static CK_OFF_T dots = 0L;
-static int hpos = 0;
-
-static VOID /* Initialize Serial or CRT display */
-dpyinit() {
- int m = 0, n = 0;
- char * s = "";
-
- newdpy = 0; /* Don't do this again */
- oldffc = (CK_OFF_T)0; /* Reset this */
- dots = (CK_OFF_T)0; /* and this.. */
- oldcps = cps = 0L;
-
- conoll(""); /* New line */
- if (what & W_SEND) s = "Sending: "; /* Action */
- else if (what & W_RECV) s = "Receiving: ";
- n = (int)strlen(s) + (int)strlen(fbuf);
- conol(fbuf);
- m = (int)strlen(abuf) + 4;
- if (n + m > cmd_cols) {
- conoll("");
- n = 0;
- } else
- n += m;
- if (*abuf) {
- conol(" => ");
- conol(abuf);
- }
- m = (int)strlen(a2buf) + 4;
- if (n + m > cmd_cols) {
- conoll("");
- n = 0;
- } else
- n += m;
- if (*a2buf) {
- conol(" => ");
- conol(a2buf);
- }
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- conoll("");
- if (fsize > (CK_OFF_T)-1) { /* Size */
- sprintf(fbuf,"Size: %s, Type: ",ckfstoa(fsize)); /* SAFE (80) */
- conol(fbuf); *fbuf = NUL;
- } else conol("Size: unknown, Type: ");
- if (binary) { /* Type */
- switch(binary) {
- case XYFT_L: conol("labeled"); break;
- case XYFT_I: conol("image"); break;
- case XYFT_U: conol("binary undefined"); break;
- default:
- case XYFT_B: conol("binary"); break;
- }
- } else {
-#ifdef NOCSETS
- conol("text");
-#else
- conol("text, ");
- if (tcharset == TC_TRANSP || xfrxla == 0) {
- conol("transparent");
- } else {
- if (what & W_SEND) {
- conol(fcsinfo[fcharset].keyword);
- conol(" => ");
- conol(tcsinfo[tcharset].keyword);
- } else {
- conol(tcsinfo[tcharset].keyword);
- conol(" => ");
- conol(fcsinfo[fcharset].keyword);
- }
- }
-#endif /* NOCSETS */
- }
-#ifdef STREAMING
- if (streaming)
- conol(", STREAMING");
-#endif /* STREAMING */
- conoll("");
-
- if (fdispla == XYFD_S) { /* CRT field headings */
-/*
- Define CK_CPS to show current transfer rate.
- Leave it undefined to show estimated time remaining.
- Estimated-time-remaining code from Andy Fyfe, not tested on
- pathological cases.
-*/
-#define CK_CPS
-
-#ifdef CK_CPS
- conoll(" File Percent Packet");
- conoll(" Bytes Done CPS Length");
-#else
- conoll(" File Percent Secs Packet");
- conoll(" Bytes Done Left Length");
-#endif /* CK_CPS */
- newdpy = 0;
- }
- hpos = 0;
-}
-
-/*
- showpkt(c)
- c = completion code: 0 means transfer in progress, nonzero means it's done.
- Show the file transfer progress counter and perhaps verbose packet type.
-*/
-VOID
-#ifdef CK_ANSIC
-showpkt(char c)
-#else
-showpkt(c) char c;
-#endif /* CK_ANSIC */
-/* showpkt */ {
-
-#ifndef GFTIMER
- long et; /* Elapsed time, entire batch */
-#endif /* GFTIMER */
- CK_OFF_T howfar; /* How far into file */
- long pd; /* Percent done, this file */
- long tp; /* Transfer rate, entire batch */
- long ps; /* Packet size, current packet */
- CK_OFF_T mytfc; /* Local copy of byte counter */
-
-#ifdef GFTIMER
- CKFLOAT tnow;
-#endif /* GFTIMER */
-
- if (newdpy) /* Put up filenames, etc, */
- dpyinit(); /* if they're not there already. */
-
- howfar = ffc; /* How far */
-/*
- Calculate CPS rate even if not displaying on screen for use in file
- transfer statistics.
-*/
-#ifdef GFTIMER
- tnow = gftimer(); /* Time since we started */
- ps = (what & W_RECV) ? rpktl : spktl; /* Packet size */
-#ifdef CK_RESEND
- if (what & W_SEND) /* In case we didn't start at */
- howfar += sendstart; /* the beginning... */
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- pd = -1; /* Percent done. */
- if (c == NUL) { /* Still going, figure % done */
- if (!fsize) return; /* Empty file, don't bother */
- pd = (fsize > 99) ? (howfar / (fsize / (CK_OFF_T)100)) : 0;
- if (pd > 100) pd = 100; /* Expansion */
- }
- if (c != NUL)
- if (!cxseen && !discard && !czseen)
- pd = 100; /* File complete, so 100%. */
-
- mytfc = (pd < 100) ? tfc + ffc : tfc; /* CPS */
- tp = (long)((tnow > 0.0) ? (CKFLOAT) mytfc / tnow : 0);
- if (c && (tp == 0))
- tp = ffc;
-
- cps = tp; /* Set global variable */
- if (cps > peakcps && /* Peak transfer rate */
- ((what & W_SEND && spackets > wslots + 4) ||
- (!(what & W_SEND) && spackets > 10))) {
- peakcps = cps;
- }
-
-#else /* Not GFTIMER */
-
- et = gtimer(); /* Elapsed time */
- ps = (what & W_RECV) ? rpktl : spktl; /* Packet length */
-#ifdef CK_RESEND
- if (what & W_SEND) /* And if we didn't start at */
- howfar += sendstart; /* the beginning... */
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- pd = -1; /* Percent done. */
- if (c == NUL) { /* Still going, figure % done */
- if (fsize == 0L) return; /* Empty file, don't bother */
- pd = (fsize > 99) ? (howfar / (fsize / (CK_OFF_T)100)) : 0;
- if (pd > 100) pd = 100; /* Expansion */
- }
- if (c != NUL)
- if (!cxseen && !discard && !czseen)
- pd = 100; /* File complete, so 100%. */
-
-
-#ifndef CK_CPS
-/*
- fsecs = time (from gtimer) that this file started (set in sfile()).
- Rate so far is ffc / (et - fsecs), estimated time for remaining bytes
- is (fsize - ffc) / (ffc / (et - fsecs)).
-*/
- tp = (howfar > 0) ? (fsize - howfar) * (et - fsecs) / howfar : 0;
-#endif /* CK_CPS */
-
-#ifdef CK_CPS
- mytfc = (pd < 100) ? tfc + ffc : tfc;
- tp = (et > 0) ? mytfc / et : 0; /* Transfer rate */
- if (c && (tp == 0)) /* Watch out for subsecond times */
- tp = ffc;
-
- cps = tp; /* Set global variable */
- if (cps > peakcps && /* Peak transfer rate */
- ((what & W_SEND && spackets > wslots + 4) ||
- (!(what & W_SEND) && spackets > 10))) {
- peakcps = cps;
- }
-#endif /* CK_CPS */
-
-#endif /* GFTIMER */
-
- if (fdispla == XYFD_S) { /* CRT display */
- char buffer[128];
- /* These sprintfs should be safe until we have 32-digit numbers */
-
- if (pd > -1L)
- sprintf(buffer, "%c%9s%5ld%%%8ld%8ld ", CR,ckfstoa(howfar),pd,tp,ps);
- else
- sprintf(buffer, "%c%9s %8ld%8ld ", CR,ckfstoa(howfar),tp,ps);
- conol(buffer);
- hpos = 31;
- } else if (fdispla == XYFD_R) { /* SERIAL */
- long i, k;
- if (howfar - oldffc < 1024) /* Update display every 1K */
- return;
- oldffc = howfar; /* Time for new display */
- k = (howfar / 1024L) - dots; /* How many K so far */
- for (i = 0L; i < k; i++) {
- if (hpos++ > (cmd_cols - 3)) { /* Time to wrap? */
- conoll("");
- hpos = 0;
- }
- conoc('.'); /* Print a dot for this K */
- dots++; /* Count it */
- }
- }
-}
-
-
-/* C K S C R E E N -- Screen display function */
-
-/*
- ckscreen(f,c,n,s)
- f - argument descriptor
- c - a character or small integer
- n - a long integer
- s - a string.
-
- and global fdispla = SET FILE DISPLAY value:
-
- XYFD_N = NONE
- XYFD_R = SERIAL: Dots, etc, works on any terminal, even hardcopy.
- XYFD_S = CRT: Works on any CRT, writes over current line.
- XYFD_C = FULLSCREEN: Requires terminal-dependent screen control.
- XYFD_B = BRIEF: Like SERIAL but only filename & completion status.
- XYFD_G = GUI; Windows GUI, same behavior as FULLSCREEN
-*/
-VOID
-#ifdef CK_ANSIC
-ckscreen(int f, char c,CK_OFF_T n,char *s)
-#else
-ckscreen(f,c,n,s) int f; char c; CK_OFF_T n; char *s;
-#endif /* CK_ANSIC */
-/* screen */ {
- char buf[80];
- int len; /* Length of string */
-#ifdef UNIX
-#ifndef NOJC
- int obg;
-_PROTOTYP( VOID conbgt, (int) );
-#endif /* NOJC */
-#endif /* UNIX */
- int ftp = 0;
-
- ftp = (what & W_FTP) ? 1 : 0; /* FTP or Kermit? */
-
- if (!local && !ftp) /* In remote mode - don't do this */
- return;
-
- if (!s) s = "";
-
- if (!fxd_inited) /* Initialize if necessary */
- fxdinit(fdispla);
-
-#ifdef UNIX
-#ifndef NOJC
- obg = backgrd; /* Previous background status */
- conbgt(1); /* See if running in background */
- if (!backgrd && obg) { /* Just came into foreground? */
- concb((char)escape); /* Put console back in CBREAK mode */
- setint(); /* Restore interrupts */
- }
-#endif /* NOJC */
-#endif /* UNIX */
-
- if ((f != SCR_WM) && (f != SCR_EM)) /* Always update warnings & errors */
- if (!displa ||
- (backgrd && bgset) ||
- fdispla == XYFD_N ||
- (server && !srvdis)
- )
- return;
-
-#ifdef VMS
- if (f == SCR_FN) /* VMS - shorten the name */
- s = zrelname(s,zgtdir());
-#endif /* VMS */
-
- if (dest == DEST_S) /* SET DESTINATION SCREEN */
- return; /* would interfere... */
-
-#ifdef KUI
- if (fdispla == XYFD_G) { /* If gui display selected */
- screeng(f,c,n,s); /* call the gui version */
- return;
- }
-#endif /* KUI */
-#ifdef CK_CURSES
- if (fdispla == XYFD_C) { /* If fullscreen display selected */
- screenc(f,c,n,s); /* call the fullscreen version */
- return;
- }
-#endif /* CK_CURSES */
-
- len = (int)strlen(s); /* Length of string */
-
- switch (f) { /* Handle our function code */
- case SCR_FN: /* Filename */
- if (fdispla == XYFD_B) {
-#ifdef NEWFTP
- if (ftp)
- printf(" %s %s", what & W_SEND ? "PUT" : "GET", s);
- else
-#endif /* NEWFTP */
- printf(" %s %s", what & W_SEND ? "SEND" : "RECV", s);
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- return;
- }
-#ifdef MAC
- conoll(""); conol(s); conoc(SP); hpos = len + 1;
-#else
- ckstrncpy(fbuf,s,80);
- abuf[0] = a2buf[0] = NUL;
- newdpy = 1; /* New file so refresh display */
-#endif /* MAC */
- return;
-
- case SCR_AN: /* As-name */
- if (fdispla == XYFD_B) {
-#ifdef COMMENT
- printf("(as %s) ",s);
-#endif /* COMMENT */
- return;
- }
-#ifdef MAC
- if (hpos + len > 75) { conoll(""); hpos = 0; }
- conol("=> "); conol(s);
- if ((hpos += (len + 3)) > 78) { conoll(""); hpos = 0; }
-#else
- if (abuf[0]) {
- ckstrncpy(a2buf,s,80);
- } else {
- ckstrncpy(abuf,s,80);
- }
-#endif /* MAC */
- return;
-
- case SCR_FS: /* File-size */
- if (fdispla == XYFD_B) {
- printf(" (%s) (%s byte%s)",
-#ifdef NOICP
- (binary ? "binary" : "text")
-#else
- gfmode(binary,0)
-#endif /* NOICP */
- , ckfstoa(n), n == 1 ? "" : "s");
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- return;
- }
-#ifdef MAC
- sprintf(buf,", Size: %s",ckfstoa(n)); conoll(buf); hpos = 0;
-#endif /* MAC */
- return;
-
- case SCR_XD: /* X-packet data */
- if (fdispla == XYFD_B)
- return;
-#ifdef MAC
- conoll(""); conoll(s); hpos = 0;
-#else
- ckstrncpy(fbuf,s,80);
- abuf[0] = a2buf[0] = NUL;
-#endif /* MAC */
- return;
-
- case SCR_ST: /* File status */
- switch (c) {
- case ST_OK: /* Transferred OK */
- showpkt('Z'); /* Update numbers one last time */
- if (fdispla == XYFD_B) {
-#ifdef GFTIMER
- if (fpxfsecs)
- printf(": OK (%0.3f sec, %ld cps)",fpxfsecs,
- (long)((CKFLOAT)ffc / fpxfsecs));
-#else
- if (xfsecs)
- printf(": OK (%d sec, %ld cps)",xfsecs,ffc/xfsecs);
-#endif /* GFTIMER */
- printf("\n");
- return;
- }
- if ((hpos += 5) > 78) conoll(""); /* Wrap screen line. */
- conoll(" [OK]"); hpos = 0; /* Print OK message. */
- if (fdispla == XYFD_S) { /* We didn't show Z packet when */
- conoc('Z'); /* it came, so show it now. */
- hpos = 1;
- }
- return;
-
- case ST_DISC: /* Discarded */
- if (fdispla == XYFD_B) {
- printf(": DISCARDED\n");
- return;
- }
- if ((hpos += 12) > 78) conoll("");
- conoll(" [discarded]"); hpos = 0;
- return;
-
- case ST_INT: /* Interrupted */
- if (fdispla == XYFD_B) {
- printf(": INTERRUPTED\n");
- return;
- }
- if ((hpos += 14) > 78) conoll("");
- conoll(" [interrupted]"); hpos = 0;
- return;
-
- case ST_SIM:
- if (fdispla == XYFD_B) {
- if (n == SKP_XNX)
- printf(": WOULD BE TRANSFERRED (New file)\n");
- else if (n == SKP_XUP)
- printf(": WOULD BE TRANSFERRED (Remote file older)\n");
- else if (n == SKP_SIM)
- printf(": WOULD BE TRANSFERRED\n");
- else if (n > 0 && n < nskreason)
- printf(": SKIPPED (%s)\n",skreason[n]);
- else
- printf(": SKIPPED\n");
- return;
- } else if (fdispla == XYFD_S) {
- if (fdispla == XYFD_S && fbuf[0]) { /* CRT display */
- conoll(""); /* New line */
- if (what & W_SEND) conol("Would Send: "); /* Action */
- else if (what & W_RECV) conol("Would Receive: ");
- conol(fbuf);
- if (*abuf) conol(" => "); conol(abuf); /* Names */
- if (*a2buf) conol(" => "); conol(a2buf); /* Names */
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- }
- conoll(" [simulated]");
- return;
- }
- if ((hpos += 10) > 78) conoll("");
- conol(" [simulated]"); hpos = 0;
- return;
-
- case ST_SKIP: /* Skipped */
- if (fdispla == XYFD_B) {
- if (n == SKP_XNX)
- printf(": WOULD BE TRANSFERRED (New file)\n");
- else if (n == SKP_XUP)
- printf(": WOULD BE TRANSFERRED (Remote file older)\n");
- else if (n == SKP_SIM)
- printf(": WOULD BE TRANSFERRED\n");
- else if (n > 0 && n < nskreason)
- printf(": SKIPPED (%s)\n",skreason[n]);
- else
- printf(": SKIPPED\n");
- return;
- } else if (fdispla == XYFD_S) {
- if (fdispla == XYFD_S && fbuf[0]) { /* CRT display */
- conoll(""); /* New line */
- if (what & W_SEND) conol("Sending: "); /* Action */
- else if (what & W_RECV) conol("Receiving: ");
- conol(fbuf);
- if (*abuf) conol(" => "); conol(abuf); /* Names */
- if (*a2buf) conol(" => "); conol(a2buf); /* Names */
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- }
- conoll(" [skipped]");
- return;
- }
- if ((hpos += 10) > 78) conoll("");
- conol(" "); conol(fbuf);
- conoll(" [skipped]"); hpos = 0;
- return;
-
- case ST_ERR: /* Error */
- if (fdispla == XYFD_B) {
- printf(": ERROR: %s\n",s);
- return;
- }
- conoll("");
- conol("Error: "); conoll(s); hpos = 0;
- return;
-
- case ST_MSG: /* Message */
-#ifdef NEWFTP
- if (fdispla == XYFD_B) {
- if (ftp && ftp_deb)
- printf(": MESSAGE: %s\n",s);
- return;
- }
-#endif /* NEWFTP */
- conoll("");
- conol("Message: ");
- conoll(s);
- hpos = 0;
- return;
-
- case ST_REFU: /* Refused */
- if (fdispla == XYFD_B) {
- printf(": REFUSED\n");
- return;
- } else if (fdispla == XYFD_S) {
- if (fdispla == XYFD_S && fbuf[0]) { /* CRT display */
- conoll(""); /* New line */
- if (what & W_SEND) conol("Sending: "); /* Action */
- else if (what & W_RECV) conol("Receiving: ");
- conol(fbuf);
- if (*abuf) conol(" => "); conol(abuf); /* Names */
- if (*a2buf) conol(" => "); conol(a2buf); /* Names */
- *fbuf = NUL; *abuf = NUL; *a2buf = NUL;
- conoll("");
- }
- conol("Refused: "); conoll(s);
- return;
- }
- conoll("");
- conol("Refused: "); conoll(s); hpos = 0;
- return;
-
- case ST_INC: /* Incomplete */
- if (fdispla == XYFD_B) {
- printf(": INCOMPLETE\n");
- return;
- }
- if ((hpos += 12) > 78) conoll("");
- conoll(" [incomplete]"); hpos = 0;
- return;
-
- default:
- conoll("*** screen() called with bad status ***");
- hpos = 0;
- return;
- }
-
-#ifdef MAC
- case SCR_PN: /* Packet number */
- if (fdispla == XYFD_B) {
- return;
- }
- ckmakmsg(buf,80,s,": ",ckltoa(n),NULL);
- conol(buf); hpos += (int)strlen(buf); return;
-#endif /* MAC */
-
- case SCR_PT: /* Packet type or pseudotype */
- if (fdispla == XYFD_B)
- return;
- if (c == 'Y') return; /* Don't bother with ACKs */
- if (c == 'D') { /* In data transfer phase, */
- showpkt(NUL); /* show progress. */
- return;
- }
-#ifndef AMIGA
- if (hpos++ > 77) { /* If near right margin, */
- conoll(""); /* Start new line */
- hpos = 0; /* and reset counter. */
- }
-#endif /* AMIGA */
- if (c == 'Z' && fdispla == XYFD_S)
- return;
- else
- conoc(c); /* Display the packet type. */
-#ifdef AMIGA
- if (c == 'G') conoll(""); /* New line after G packets */
-#endif /* AMIGA */
- return;
-
- case SCR_TC: /* Transaction complete */
- if (xfrbel) bleep(BP_NOTE);
- if (fdispla == XYFD_B) { /* Brief display... */
- if (filcnt > 1) {
- long fx;
- fx = filcnt - filrej;
- printf(" SUMMARY: %ld file%s", fx, ((fx == 1) ? "" : "s"));
- printf(", %s byte%s", ckfstoa(tfc), ((tfc == 1) ? "" : "s"));
-#ifdef GFTIMER
- printf(", %0.3f sec, %ld cps", fptsecs, tfcps);
-#else
- printf(", %ld sec, %ld cps", tsecs, tfcps);
-#endif /* GFTIMER */
- printf(".\n");
- }
- } else {
- conoll("");
- }
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- return;
-
- case SCR_EM: /* Error message */
- if (fdispla == XYFD_B) {
- printf(" ERROR: %s\n",s);
- return;
- }
- conoll(""); conoc('?'); conoll(s); hpos = 0; return;
-
- case SCR_WM: /* Warning message */
- if (fdispla == XYFD_B) {
- printf(" WARNING: %s\n",s);
- return;
- }
- conoll(""); conoll(s); hpos = 0; return;
-
- case SCR_MS: /* Message from other Kermit */
- if (fdispla == XYFD_B) {
- printf(" MESSAGE: %s\n",s);
- return;
- }
- conoll(""); conoll(s); hpos = 0; return;
-
- case SCR_TU: /* Undelimited text */
- if (fdispla == XYFD_B)
- return;
- if ((hpos += len) > 77) { conoll(""); hpos = len; }
- conol(s); return;
-
- case SCR_TN: /* Text delimited at beginning */
- if (fdispla == XYFD_B)
- return;
- conoll(""); conol(s); hpos = len; return;
-
- case SCR_TZ: /* Text delimited at end */
- if (fdispla == XYFD_B)
- return;
- if ((hpos += len) > 77) { conoll(""); hpos = len; }
- conoll(s); return;
-
- case SCR_QE: /* Quantity equals */
- if (fdispla == XYFD_B)
- return;
- ckmakmsg(buf,80,s,": ",ckltoa(n),NULL);
- conoll(buf); hpos = 0; return;
-
- case SCR_CW: /* Close fullscreen window */
- return; /* No window to close */
-
- case SCR_CD:
- return;
-
- default:
- conoll("*** screen() called with bad object ***");
- hpos = 0;
- return;
- }
-}
-#endif /* NODISPLAY */
-
-/* E R M S G -- Nonfatal error message */
-
-/* Should be used only for printing the message text from an Error packet. */
-
-VOID
-ermsg(msg) char *msg; { /* Print error message */
- debug(F110,"ermsg",msg,0);
- if (local)
- xxscreen(SCR_EM,0,0L,msg);
- tlog(F110,"Protocol Error:",msg,0L);
-}
-#endif /* NOXFER */
-
-VOID
-setseslog(x) int x; {
- seslog = x;
-#ifdef KUI
- KuiSetProperty(KUI_TERM_CAPTURE,x,0);
-#endif /* KUI */
-}
-
-VOID
-doclean(fc) int fc; { /* General cleanup */
-#ifdef OS2ORUNIX
- extern int ttyfd;
-#endif /* OS2ORUNIX */
- extern int keep;
- extern int exithangup;
-#ifndef NOXFER
- extern char filnam[];
-#endif /* NOXFER */
-#ifndef NOICP
- int x;
-
- if (fc > 0)
- dostop(); /* Stop all command files and end macros */
-#endif /* NOICP */
-
-#ifndef NOXFER
- if (pktlog) {
- *pktfil = '\0';
- pktlog = 0;
- zclose(ZPFILE);
- }
-#endif /* NOXFER */
- if (seslog) {
- *sesfil = '\0';
- setseslog(0);
- zclose(ZSFILE);
- }
-#ifdef TLOG
- if (tralog) {
- tlog(F100,"Transaction Log Closed","",0L);
- *trafil = '\0';
- tralog = 0;
- zclose(ZTFILE);
- }
-#endif /* TLOG */
-
- debug(F100,"doclean calling dologend","",0);
- dologend(); /* End current log record if any */
-#ifdef COMMENT
- if (dialog) { /* If connection log open */
- dialog = 0;
- *diafil = '\0'; /* close it. */
- zclose(ZDIFIL);
- }
-#endif /* COMMENT */
-
-#ifndef NOICP
-#ifndef NOSPL
- zclose(ZRFILE); /* READ and WRITE files, if any. */
- zclose(ZWFILE);
-#ifndef NOXFER
- zclose(ZIFILE); /* And other files too */
- x = chkfn(ZOFILE); /* Download in progress? */
- debug(F111,"doclean chkfn ZOFILE",filnam,x);
- debug(F111,"doclean keep","",keep);
- zclose(ZOFILE); /* Close output file */
- if (x > 0 && !keep) { /* If it was being downloaded */
- if (filnam[0])
- x = zdelet(filnam); /* Delete if INCOMPLETE = DISCARD */
- debug(F111,"doclean download filename",filnam,x);
- }
-#endif /* NOXFER */
- zclose(ZSYSFN);
- zclose(ZMFILE);
-
- if (fc < 1) { /* RESETing, not EXITing */
-#ifdef DEBUG
- if (deblog) { /* Close the debug log. */
- *debfil = '\0';
- deblog = 0;
- zclose(ZDFILE);
- }
-#endif /* DEBUG */
- return;
- }
-#endif /* NOSPL */
-#endif /* NOICP */
-
-#ifndef NOLOCAL
- debug(F101,"doclean exithangup","",exithangup);
- if (local && exithangup) { /* Close communication connection */
- extern int haslock;
- int x;
-
- x = ttchk();
- debug(F101,"doclean ttchk()","",x);
-#ifdef OS2ORUNIX
- debug(F101,"doclean ttyfd","",ttyfd);
-#endif /* OS2ORUNIX */
- if (x >= 0
-#ifdef OS2
- || ttyfd != -1
-#else
-#ifdef UNIX
- || haslock /* Make sure we get lockfile! */
- || (!network && ttyfd > -1)
-#endif /* UNIX */
-#endif /* OS2 */
- ) {
- extern int wasclosed, whyclosed;
- debug(F100,"doclean hanging up and closing","",0);
- if (msgflg) {
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- printf("Closing %s...",ttname);
- }
-#ifndef NODIAL
- mdmhup(); /* Hangup the modem??? */
-#endif /* NODIAL */
- ttclos(0); /* Close external line, if any */
- if (msgflg) {
- printf("OK\n");
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- }
- if (wasclosed) {
- whyclosed = WC_CLOS;
-#ifndef NOSPL
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_close",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- wasclosed = 0;
- /* printf("ON_CLOSE DOCLEAN\n"); */
- *(mactab[k].kwd) = NUL; /* See comment below */
- if (dodo(k,ckitoa(whyclosed),0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
-#endif /* NOSPL */
- wasclosed = 0;
- }
- }
- ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty */
- local = dfloc; /* And default remote/local status */
- }
-#ifdef DEBUG
- else if (local) debug(F100,"doclean hangup/close skipped","",0);
-#endif /* DEBUG */
-#endif /* NOLOCAL */
-
-#ifdef NEWFTP
- ftpbye(); /* If FTP connection open, close it */
-#endif /* NEWFTP */
-
-#ifdef IKSD
- if (inserver)
- ttclos(0); /* If IKSD, close socket */
-#endif /* IKSD */
-
-#ifndef NOSPL
-/*
- If a macro named "on_exit" is defined, execute it. Also remove it from the
- macro table, in case its definition includes an EXIT or QUIT command, which
- would cause much recursion and would prevent the program from ever actually
- EXITing.
-*/
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- char * cmd = "on_exit"; /* MSVC 2.x compiler error */
- k = mlook(mactab,cmd,nmac); /* Look up "on_exit" */
- if (k >= 0) { /* If found, */
-#ifdef COMMENT
- /* This makes a mess if ON_EXIT itself executes macros */
- *(mactab[k].kwd) = NUL; /* poke its name from the table, */
-#else
- /* Replace the keyword with something that doesn't wreck the */
- /* order of the keyword table */
- ckstrncpy(mactab[k].kwd,"on_exxx",8);
-#endif /* COMMENT */
- if (dodo(k,"",0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
-#endif /* NOSPL */
-/*
- Put console terminal back to normal. This is done here because the
- ON_EXIT macro calls the parser, which meddles with console terminal modes.
-*/
- conres(); /* Restore console terminal. */
-
-#ifdef COMMENT
-/* Should be no need for this, and maybe it's screwing things up? */
- connoi(); /* Turn off console interrupt traps */
-#endif /* COMMENT */
-
- /* Delete the Startup File if we are supposed to. */
-#ifndef NOICP
- {
- extern int DeleteStartupFile;
- debug(F111,"doclean DeleteStartupFile",cmdfil,DeleteStartupFile);
- if (DeleteStartupFile) {
- int rc = zdelet(cmdfil);
- debug(F111,"doclean zdelet",cmdfil,rc);
- }
- }
-#endif /* NOICP */
- syscleanup(); /* System-dependent cleanup, last */
-}
-
-/* D O E X I T -- Exit from the program. */
-
-/*
- First arg is general, system-independent symbol: GOOD_EXIT or BAD_EXIT.
- If second arg is -1, take 1st arg literally.
- If second arg is not -1, work it into the exit code.
-*/
-VOID
-doexit(exitstat,code) int exitstat, code; {
- extern int x_logged, quitting;
-#ifdef OS2
- extern int display_demo;
- extern int SysInited;
-#endif /* OS2 */
-#ifdef CK_KERBEROS
-#ifdef KRB4
- extern int krb4_autodel;
-#endif /* KRB4 */
-#ifdef KRB5
- extern int krb5_autodel;
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifdef VMS
- char envstr[64];
- static $DESCRIPTOR(symnam,"CKERMIT_STATUS");
- static struct dsc$descriptor_s symval;
-#endif /* VMS */
- int i;
-
-#ifdef DEBUG
-#ifdef USE_LUCACHE
- extern long lucalls, luhits, xxhits, luloop;
- extern int lusize;
-#endif /* USE_LUCACHE */
-#ifndef NOSPL
- extern int cmdstats[];
-#endif /* NOSPL */
-
- quitting++;
-
-#ifdef OS2
- if ( !SysInited ) {
- static int initing = 0;
- if ( initing )
- exit(253);
- initing = 1;
- sysinit();
- }
-#endif /* OS2 */
-
- if (deblog) {
-#ifdef USE_LUCACHE
- debug(F101,"lookup cache size","",lusize);
- debug(F101,"lookup calls ....","",lucalls);
- debug(F101,"lookup cache hits","",luhits);
- debug(F101,"lookup start hits","",xxhits);
- debug(F101,"lookup loop iterations","",luloop);
-#endif /* USE_LUCACHE */
-#ifndef NOSPL
- for (i = 0; i < 256; i++) {
- if (cmdstats[i])
- debug(F111,"CMSTATS",ckitoa(i),cmdstats[i]);
- }
-#endif /* NOSPL */
- debug(F101,"doexit exitstat","",exitstat);
- debug(F101,"doexit code","",code);
- debug(F101,"doexit xitsta","",xitsta);
- }
-#endif /* DEBUG */
-
-#ifdef CK_KERBEROS
- /* If we are automatically destroying Kerberos credentials on Exit */
- /* do it now. */
-#ifdef KRB4
- if (krb4_autodel == KRB_DEL_EX) {
- extern struct krb_op_data krb_op;
- krb_op.version = 4;
- krb_op.cache = NULL;
- ck_krb4_destroy(&krb_op);
- }
-#endif /* KRB4 */
-#ifdef KRB5
- if (krb5_autodel == KRB_DEL_EX) {
- extern struct krb_op_data krb_op;
- extern char * krb5_d_cc;
- krb_op.version = 5;
- krb_op.cache = krb5_d_cc;
- ck_krb5_destroy(&krb_op);
- }
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-#ifndef NOLOCAL
-#ifdef OS2
- if (SysInited)
- {
-#ifdef DCMDBUF
- extern struct cmdptr *cmdstk;
-#else
- extern struct cmdptr cmdstk[];
-#endif /* DCMDBUF */
- extern int tt_status[];
- extern int vmode;
-
- /* If there is a demo screen to be displayed, display it */
- if (display_demo) {
- demoscrn(VCMD);
- display_demo = 0;
- }
-#ifndef KUI
- /* This is going to be hideous. If we have a status line */
- /* in the command window turn it off before we exit. */
-
- if ( tt_status[VCMD] && vmode == VCMD ) {
- domac("_clear_statusline","set command statusline off",
- cmdstk[cmdlvl].ccflgs);
- delmac("_clear_statusline",1);
- RequestScreenMutex(-1);
- VscrnIsDirty(vmode);
- ReleaseScreenMutex();
- while ( IsVscrnDirty(vmode) )
- msleep(200);
- RequestScreenMutex(-1);
- ReleaseScreenMutex();
- }
-#endif /* KUI */
- DialerSend(OPT_KERMIT_EXIT,exitstat);
-#ifndef KUI
- debug(F100,"doexit about to msleep","",0);
-
- if ( isWin95() )
- msleep(250);
-#endif /* KUI */
- }
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && x_logged) {
-#ifndef NOSPL
-/*
- If a macro named "on_logout" is defined, execute it. Also remove it from the
- macro table, in case its definition includes an EXIT or QUIT command, which
- would cause much recursion and would prevent the program from ever actually
- EXITing.
-*/
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- char * cmd = "on_logout"; /* MSVC 2.x compiler error */
- k = mlook(mactab,cmd,nmac); /* Look up "on_logout" */
- if (k >= 0) { /* If found, */
- *(mactab[k].kwd) = NUL; /* poke its name from the table, */
- if (dodo(k,"",0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
-#endif /* NOSPL */
- zvlogout();
- }
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-
- debug(F100,"doexit about to doclean","",0);
- doclean(1); /* Clean up most things */
-
-#ifdef VMS
- if (code == -1)
- code = 0; /* Since we set two different items */
- sprintf(envstr,"%d", exitstat | code); /* SAFE */
- symval.dsc$w_length = (int)strlen(envstr);
- symval.dsc$a_pointer = envstr;
- symval.dsc$b_class = DSC$K_CLASS_S;
- symval.dsc$b_dtype = DSC$K_DTYPE_T;
- i = 2; /* Store in global table */
-#ifdef COMMENT /* Martin Zinser */
- LIB$SET_SYMBOL(&symnam, &symval, &i);
-#else
- lib$set_symbol(&symnam, &symval, &i);
-#endif /* COMMENT */
- if (exitstat == BAD_EXIT)
- exitstat = SS$_ABORT | STS$M_INHIB_MSG;
- if (exitstat == GOOD_EXIT)
- exitstat = SS$_NORMAL | STS$M_INHIB_MSG;
-#else /* Not VMS */
- if (code != -1) /* Take 1st arg literally */
- exitstat |= code;
-#endif /* VMS */
-
-#ifdef IKSD
-#ifdef IKSDB
- debug(F101,"doexit ikdbopen","",ikdbopen);
- if (ikdbopen && dbfp) { /* If IKSD database open */
- int x;
- x = freeslot(mydbslot); /* Free our slot... */
- debug(F101,"doexit freeslot","",x);
- fclose(dbfp); /* and close it. */
- }
-#endif /* IKSDB */
-#endif /* IKSD */
-
-/* We have put this off till the very last moment... */
-
-#ifdef DEBUG
- if (deblog) { /* Close the debug log. */
- debug(F101,"C-Kermit EXIT status","",exitstat);
- *debfil = '\0';
- deblog = 0;
- zclose(ZDFILE);
- }
-#endif /* DEBUG */
-
-#ifdef OS2
- _exit(exitstat); /* Exit from C-Kermit (no matter what) */
-#else /* OS2 */
- exit(exitstat); /* Exit from C-Kermit */
-#endif /* OS2 */
-}
-
-VOID
-bgchk() { /* Check background status */
- if (bgset < 0) { /* They didn't type SET BACKGROUND */
-#ifdef VMS /* Set prompt flag based on */
- pflag = !batch; /* what we detected at startup. */
-#else
- pflag = !backgrd;
-#endif /* VMS */
- } else { /* Otherwise SET BACKGROUND value */
- pflag = (bgset == 0 ? 1 : 0);
- }
-
-#ifndef NOICP
- /* Message flag on only if at top level, pflag is on, and QUIET is OFF */
- if (!xcmdsrc)
- msgflg = (pflag == 0) ? 0 : !quiet;
- else msgflg = 0;
-#else
- msgflg = 0;
-#endif /* NOICP */
-}
-
-/* Set console interrupts */
-
-VOID
-setint() { /* According to SET COMMAND INTERRUP */
- int x = 0;
- if (cmdint) x |= 1;
- if (xsuspend) x |= 2;
- debug(F101,"setint","",x);
-
- switch (x) { /* Set the desired combination */
- case 0: connoi(); break; /* No interrupts */
- case 1: conint(trap,SIG_IGN); break;
- case 2: conint(SIG_IGN,stptrap); break;
- case 3: conint(trap,stptrap); break;
- }
- bgchk(); /* Check background status */
-}
-
-#ifdef DEBUG
-/* D E B U G -- Enter a record in the debugging log */
-
-/*
- Call with a format, two strings, and a number:
- f - Format, a bit string in range 0-7.
- If bit x is on, then argument number x is printed.
- s1 - String, argument number 1. If selected, printed as is.
- s2 - String, argument number 2. If selected, printed in brackets.
- n - Long int, argument 3. If selected, printed preceded by equals sign.
-
- f=0 is special: print s1,s2, and interpret n as a char.
-
- f=F011 (3) is also special; in this case s2 is interpeted as a counted
- string that might contain NULs. n is the length. If n is negative, this
- means the string has been truncated and ".." should be printed after the
- first n bytes. NUL and LF bytes are printed as "<NUL>" and "<LF>".
-
- Globals:
- deblog: nonzero if debug log open.
- debok: nonzero if ok to write entries.
-*/
-/*
- WARNING: Don't change DEBUFL without changing sprintf() formats below,
- accordingly.
-*/
-#define DBUFL 4000
-/*
- WARNING: This routine is not thread-safe, especially when Kermit is
- executing on multiple CPUs -- as different threads write to the same
- static buffer, the debug statements are all interleaved. To be fixed
- later...
-*/
-static char *dbptr = (char *)0;
-
-int
-#ifdef CK_ANSIC
-dodebug(int f, char *s1, char *s2, CK_OFF_T n)
-#else
-dodebug(f,s1,s2,n) int f; char *s1, *s2; CK_OFF_T n;
-#endif /* CK_ANSIC */
-/* dodebug */ {
- char *sp;
- int len1, len2;
- extern int debtim;
-#ifdef OS2
- extern int SysInited;
-#endif /* OS2 */
-
- if (!deblog || !debok)
- return(0);
-
-#ifdef COMMENT
- /* expensive... */
- if (!chkfn(ZDFILE)) /* Debug log not open, don't. */
- return(0);
-#endif /* COMMENT */
- if (!dbptr) { /* Allocate memory buffer */
- dbptr = malloc(DBUFL+4); /* This only happens once */
- if (!dbptr) {
- zclose(ZDFILE);
- return(0);
- }
- }
-/*
- This prevents infinite recursion in case we accidentally put a debug()
- call in this routine, or call another routine that contains debug() calls.
- From this point on, all returns from this return must be via goto xdebug,
- which sets deblog back to 1.
-*/
-#ifdef OS2
- if (SysInited) {
- if (RequestDebugMutex(30000))
- goto xdebug;
- }
-#else /* OS2 */
- deblog = 0; /* Prevent infinite recursion */
-#endif /* OS2 */
-
- if (debtim) { /* Timestamp */
- char *tb, tsbuf[48];
- ztime(&tb);
- ckstrncpy(tsbuf,tb,32);
- if (ztmsec > -1L) {
- sprintf(tsbuf+19,".%03ld ",ztmsec); /* SAFE */
- } else {
- tsbuf[19] = ':';
- tsbuf[20] = SP;
- tsbuf[21] = NUL;
- }
- zsout(ZDFILE,tsbuf+11);
- }
- if (!s1) s1="(NULL)";
- if (!s2) s2="(NULL)";
-
- len1 = strlen(s1);
- len2 = strlen(s2);
-
-#ifdef COMMENT
-/*
- This should work, but it doesn't.
- So instead we'll cope with overflow via sprintf formats.
- N.B.: UNFORTUNATELY, this means we have to put constants in the
- sprintf formats.
-*/
- if (f != F011 && (!f || (f & 6))) { /* String argument(s) included? */
- x = (int) strlen(s1) + (int) strlen(s2) + 18;
- if (x > dbufl) { /* Longer than buffer? */
- if (dbptr) /* Yes, free previous buffer */
- free(dbptr);
- dbptr = (char *) malloc(x + 2); /* Allocate a new one */
- if (!dbptr) {
- zsoutl(ZDFILE,"DEBUG: Memory allocation failure");
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- } else {
- dbufl = x;
- sprintf(dbptr,"DEBUG: Buffer expanded to %d\n", x + 18);
- zsoutl(ZDFILE,dbptr);
- }
- }
- }
-#endif /* COMMENT */
-
-#ifdef COMMENT
-/* The aforementioned sprintf() formats were like this: */
- if (n > 31 && n < 127)
- sprintf(sp,"%.100s%.2000s:%c\n",s1,s2,(CHAR) n);
- else if (n < 32 || n == 127)
- sprintf(sp,"%.100s%.2000s:^%c\n",s1,s2,(CHAR) ((n+64) & 0x7F));
- else if (n > 127 && n < 160)
- sprintf(sp,"%.100s%.2000s:~^%c\n",s1,s2,(CHAR)((n-64) & 0x7F));
- else if (n > 159 && n < 256)
- sprintf(sp,"%.100s%.2000s:~%c\n",s1,s2,(CHAR) (n & 0x7F));
- else sprintf(sp,"%.100s%.2000s:%ld\n",s1,s2,n);
-/*
- But, naturally, it turns out these are not portable either, so now
- we do the stupidest possible thing.
-*/
-#endif /* COMMENT */
-
-#ifdef BIGBUFOK
-/* Need to accept longer strings when debugging authenticated connections */
- if (f == F010) {
- if (len2 + 2 >= DBUFL) s2 = "(string too long)";
- } else if (f != F011 && f != F100) {
- if (len1 > 100) s1 = "(string too long)";
- if (len2 + 101 >= DBUFL) s2 = "(string too long)";
- }
-#else
- if (f != F011) {
- if (len1 > 100) s1 = "(string too long)";
- if (len2 + 101 >= DBUFL) s2 = "(string too long)";
- }
-#endif /* BIGBUFOK */
-
- sp = dbptr;
-
- switch (f) { /* Write log record according to format. */
- case F000: /* 0 = print both strings, and n as a char. */
- if (len2 > 0) {
- if ((n > 31 && n < 127) || (n > 159 && n < 256))
- sprintf(sp,"%s[%s]=%c\n",s1,s2,(CHAR) n);
- else if (n < 32 || n == 127)
- sprintf(sp,"%s[%s]=^%c\n",s1,s2,(CHAR) ((n+64) & 0x7F));
- else if (n > 127 && n < 160)
- sprintf(sp,"%s[%s]=~^%c\n",s1,s2,(CHAR)((n-64) & 0x7F));
- else sprintf(sp,"%s[%s]=0x%lX\n",s1,s2,(long)n);
- } else {
- if ((n > 31 && n < 127) || (n > 159 && n < 256))
- sprintf(sp,"%s=%c\n",s1,(CHAR) n);
- else if (n < 32 || n == 127)
- sprintf(sp,"%s=^%c\n",s1,(CHAR) ((n+64) & 0x7F));
- else if (n > 127 && n < 160)
- sprintf(sp,"%s=~^%c\n",s1,(CHAR)((n-64) & 0x7F));
- else sprintf(sp,"%s=0x%lX\n",s1,(long)n);
- }
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
-
- case F001: /* 1, "=n" */
-#ifdef COMMENT
- /* This was never used */
- sprintf(sp,"=%s\n",ckfstoa(n));
-#else
- /* Like F111, but shows number n in hex */
- ckmakxmsg(sp,DBUFL,
- s1,
- (*s1 ? ":" : ""),
- s2,
- (*s2 ? ":" : ""),
- ckltox(n),
- "\n",
- NULL,NULL,NULL,NULL,NULL,NULL
- );
-#endif /* COMMENT */
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
-
-/*
- This one was never used so (October 2000) we now use it like F011,
- except in this case we treat s2 as NUL terminated.
-*/
- case F010:
- n = -debxlen;
-/*
- This one treats n as the length of the string s2, which may contain NULs.
- It's good for logging NUL-bearing data in the debug log.
-*/
- case F011: {
- int i, j, contd = 0;
- char * p = s2, *pbuf = NULL; /* p = source pointer */
- int m; /* pbuf = destination pointer */
-
- if (f == F011) {
- if (n < 0) { /* n = size of source */
- n = 0 - n; /* Negative means to add "..." */
- contd = 1;
- }
- } else {
- int x, flag = 0;
- x = strlen(s2);
- if (n < 0) {
- flag = 1;
- n = 0 - n;
- }
- if (x < n)
- n = x;
- }
- if (n == 0) /* 0 means do nothing */
- goto xdebug;
- m = DBUFL - 8; /* Get size for interpreted part */
- if (n > m) /* Ensure requested size not too big */
- n = m;
- pbuf = dbptr; /* Construction pointer */
- i = 0;
- pbuf[i++] = '['; /* Interpret the string into it */
- for (j = 0; j < n && i < m-4; p++,j++) { /* char by char... */
- if (*p == LF) {
- if (i >= m-4)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'L';
- pbuf[i++] = 'F';
- pbuf[i++] = '>';
- continue;
- } else if (*p == CR) {
- if (i >= m-4)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'C';
- pbuf[i++] = 'R';
- pbuf[i++] = '>';
- continue;
- } else if (*p == HT) {
- if (i >= m-5)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'T';
- pbuf[i++] = 'A';
- pbuf[i++] = 'B';
- pbuf[i++] = '>';
- continue;
- } else if (*p) {
- pbuf[i++] = *p;
- continue;
- } else {
- if (i >= m-5)
- break;
- pbuf[i++] = '<';
- pbuf[i++] = 'N';
- pbuf[i++] = 'U';
- pbuf[i++] = 'L';
- pbuf[i++] = '>';
- continue;
- }
- }
- if (i < m-2 && (*p || contd)) {
- pbuf[i++] = '.';
- pbuf[i++] = '.';
- }
- pbuf[i++] = ']';
- pbuf[i] = NUL;
- if (zsout(ZDFILE,s1) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
- if (zsoutl(ZDFILE,pbuf) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",s1,pbuf);
- }
-#endif /* CKSYSLOG */
- }
- break;
-
- case F100: /* 4, "s1" */
- if (zsoutl(ZDFILE,s1) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",s1,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- case F101: /* 5, "s1=n" */
- sprintf(sp,"%s=%s\n",s1,ckfstoa(n));
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- case F110: /* 6, "s1[s2]" */
- sprintf(sp,"%s[%s]\n",s1,s2);
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- case F111: /* 7, "s1[s2]=n" */
- sprintf(sp,"%s[%s]=%s\n",s1,s2,ckfstoa(n));
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- default:
- sprintf(sp,"\n?Invalid format for debug() - %d\n",f);
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- }
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_DB && ckxlogging) {
- cksyslog(SYSLG_DB,1,"debug",dbptr,NULL);
- }
-#endif /* CKSYSLOG */
- break;
- }
- xdebug: /* Common exit point */
-#ifdef OS2
- if (SysInited)
- ReleaseDebugMutex();
-#else /* OS2 */
- deblog = 1; /* Restore this */
-#endif /* OS2 */
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-dohexdump(CHAR *msg, CHAR *st, int cnt)
-#else
-dohexdump(msg,st,cnt) CHAR *msg; CHAR *st; int cnt;
-#endif /* CK_ANSIC */
-/* dohexdump */ {
- int i = 0, j = 0, k = 0;
- char tmp[8];
-#ifdef OS2
- extern int SysInited;
-#endif /* OS2 */
-
- if (!deblog) return(0); /* If no debug log, don't. */
- if (!dbptr) { /* Allocate memory buffer */
- dbptr = malloc(DBUFL+1); /* This only happens once */
- if (!dbptr) {
- deblog = 0;
- zclose(ZDFILE);
- return(0);
- }
- }
-
-#ifdef OS2
- if (SysInited) {
- if (RequestDebugMutex(30000))
- goto xdebug;
- }
-#else /* OS2 */
- deblog = 0; /* Prevent infinite recursion */
-#endif /* OS2 */
-
- if (msg != NULL) {
- ckmakxmsg(dbptr,
- DBUFL,
- "HEXDUMP: ",
- (char *)msg,
- " (",
- ckitoa(cnt),
- " bytes)\n",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- }
- } else {
- ckmakmsg(dbptr,
- DBUFL,
- "HEXDUMP: (",
- ckitoa(cnt),
- " bytes)\n",
- NULL
- );
- zsout(ZDFILE,dbptr);
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- }
- }
- for (i = 0; i < cnt; i++) {
- dbptr[0] = '\0';
- for (j = 0 ; (j < 16); j++) {
- if ((i + j) < cnt)
- sprintf(tmp,
- "%s%02x ",
- (j == 8 ? "| " : ""),
- (CHAR) st[i + j]
- );
- else
- sprintf(tmp,
- "%s ",
- (j == 8 ? "| " : "")
- );
- ckstrncat(dbptr,tmp,DBUFL+1);
- }
- ckstrncat(dbptr," ",DBUFL+1);
- for (k = 0; (k < 16) && ((i + k) < cnt); k++) {
- sprintf(tmp,
- "%s%c",
- (k == 8 ? " " : ""),
- isprint(st[i + k]) ? st[i + k] : '.'
- );
- ckstrncat(dbptr,tmp,DBUFL+1);
- }
- ckstrncat(dbptr,"\n",DBUFL+1);
- i += j - 1;
- if (zsout(ZDFILE,dbptr) < 0) {
- deblog = 0;
- zclose(ZDFILE);
- goto xdebug;
- }
- } /* end for */
-
-
- xdebug:
-#ifdef OS2
- if (SysInited)
- ReleaseDebugMutex();
-#else /* OS2 */
- deblog = 1;
-#endif /* OS2 */
- return(0);
-}
-#endif /* DEBUG */
-
-/* Session Log... */
-
-int tsstate = 0;
-
-VOID
-#ifdef OS2
-logchar(unsigned short c)
-#else /* OS2 */
-#ifdef CK_ANSIC
-logchar(char c)
-#else
-logchar(c) char c;
-#endif /* CK_ANSIC */
-#endif /* OS2 */
-/* logchar */ { /* Log character c to session log */
- extern int slognul;
- int oktolog = 0;
-#ifndef NOLOCAL
- if (!seslog)
- return;
-
- if ((sessft != XYFT_T) || (
-#ifdef UNIX
- c != '\r' &&
-#else
-#ifdef datageneral
- c != '\r' &&
-#else
-#ifdef STRATUS
- c != '\r' &&
-#else
-#ifdef AMIGA
- c != '\r' &&
-#else
-#ifdef GEMDOS
- c != '\r' &&
-#endif /* GEMDOS */
-#endif /* AMIGA */
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* UNIX */
-#ifdef OSK
- c != '\n' &&
-#else
-#ifdef MAC
- c != '\n' &&
-#endif /* MAC */
-#endif /* OSK */
- c != XON &&
- c != XOFF))
- oktolog = 1;
- if (c == '\0' && !sessft) /* NUL in text mode */
- if (slognul) oktolog = 1; /* only if padding (2009/10/22) */
- if (!oktolog)
- return;
- if (slogts) { /* Log is timestamped */
- if (tsstate == 0) { /* State = between-lines */
- char * p; /* zstime() pointer */
- char ts[48]; /* timestamp buffer */
- ztime(&p); /* Get asctime() string */
- ckstrncpy(ts,p,32); /* Make safe copy */
- if (ztmsec > -1L) { /* Add msecs if we have them */
- sprintf(&ts[19],".%03ld: ",ztmsec); /* SAFE */
- } else {
- ts[19] = ':';
- ts[20] = SP;
- ts[21] = NUL;
- }
- if (zsout(ZSFILE,&ts[11]) < 0)
- goto xlogchar;
- }
- }
- if (c == '\n') /* At end of line? */
- tsstate = 0; /* yes */
- else
- tsstate = 1; /* no */
- if (zchout(ZSFILE,(CHAR)(c & 0xFF)) < 0) /* Log the character */
- goto xlogchar;
- if (tsstate == 0 && slognul != 0) { /* Null-terminating lines? */
- if (zchout(ZSFILE,(CHAR)0) < 0) /* Add a NUL */
- goto xlogchar;
- }
- return;
-
- xlogchar:
- conoll("");
- conoll("ERROR WRITING SESSION LOG, LOG CLOSED!");
- setseslog(0);
- zclose(ZSFILE);
-#endif /* NOLOCAL */
-}
-
-VOID
-logstr(s, len) char * s; int len; { /* Log string to session log */
-#ifndef NOLOCAL
- int n = 0;
- if (!s)
- return;
- while (seslog && (n < len))
- logchar(s[n++]);
-#endif /* NOLOCAL */
-}
-
-#ifdef CK_CURSES
-int
-ck_repaint() {
- repaint = 1;
- return(0);
-}
-
-#ifdef STRATUS
-/* VOS has curses but no tgetent() */
-int
-tgetent(s1, s2) char * s1, * s2; {
- return(1);
-}
-#endif /* STRATUS */
-
-#ifdef VMS
-#ifdef __DECC
-_PROTOTYP(int tgetent,(char *, char *));
-#endif /* __DECC */
-#endif /* VMS */
-
-/*
- There are three different ways to do fullscreen on VMS.
- 1. Use the real curses library, VAXCCURSE.
- 2. Use do-it-yourself code.
- 3. Use the Screen Manager, SMG$.
-
- Method 1 doesn't work quite right; you can't call endwin(), so once you've
- started curses mode, you can never leave.
-
- Method 2 doesn't optimize the screen, and so much more time is spent in
- screen writes. This actually causes file transfers to fail because the
- tty device input buffer can be overrun while the screen is being updated,
- especially on a slow MicroVAX that has small typeahead buffers.
-
- In the following #ifdef block, #define one of them and #undef the other 2.
-
- So now let's try method 3...
-*/
-#ifdef VMS
-#define CK_SMG /* Screen Manager */
-#undef MYCURSES /* Do-it-yourself */
-#undef VMSCURSE /* VAXCCURSE library */
-#endif /* VMS */
-/*
- But just before New Years, 2000, the SMG library seemed to break on
- both VMS systems we have here (an Alpha with VMS 7.1 and a VAX with 5.5).
- So back to MYCURSES, which works fine.
-*/
-#ifdef VMS
-#undef CK_SMG
-#define MYCURSES
-#endif /* VMS */
-
-#ifdef MYCURSES
-#define stdscr 0
-#ifdef CK_WREFRESH
-#undef CK_WREFRESH
-#endif /* CK_WREFRESH */
-#endif /* MYCURSES */
-
-/* S C R E E N C -- Screen display function, uses curses */
-
-/* Idea for curses display contributed by Chris Pratt of APV Baker, UK */
-
-/* Avoid conficts with curses.h */
-
-#ifdef QNX
-/* Same as ckcasc.h, but in a different radix... */
-#ifdef ESC
-#undef ESC
-#endif /* ESC */
-#endif /* QNX */
-
-#ifndef MYCURSES
-#undef VOID /* This was defined in ckcdeb.h */
-#endif /* MYCURSES */
-
-#undef BS /* These were defined in ckcasc.h */
-#undef CR
-#undef NL
-#undef SO
-#ifdef US
-#undef US
-#endif /* US */
-#undef SP /* Used in ncurses */
-#define CHR_SP 32 /* Use this instead */
-
-#ifdef VMS /* VMS fullscreen display */
-#ifdef MYCURSES /* Do-it-yourself method */
-extern int isvt52; /* From CKVTIO.C */
-#define printw printf
-#else
-#ifdef VMSCURSE /* VMS curses library VAXCCURSE */
-#include <curses.h>
-/* Note: Screen manager doesn't need a header file */
-#endif /* VMSCURSE */
-#endif /* MYCURSES */
-#else /* Not VMS */
-#ifdef MYCURSES /* Do-it-yourself method */
-#define isvt52 0 /* Used by OS/2, VT-100/ANSI always */
-#ifdef CKXPRINTF
-#define printw ckxprintf
-#else /* CKXPRINTF */
-#ifdef KUI
-#define printw Vscrnprintw
-#else /* KUI */
-#define printw printf
-#endif /* KUI */
-#endif /* CKXPRINTF */
-#else /* Use real curses */
-#ifdef CK_NCURSES /* or ncurses... */
-#ifdef CKXPRINTF /* Our printf macro conflicts with */
-#undef printf /* use of "printf" in ncurses.h */
-#endif /* CKXPRINTF */
-#include <ncurses.h>
-#ifdef CKXPRINTF
-#define printf ckxprintf
-#endif /* CKXPRINTF */
-#else /* Not ncurses */
-#ifdef CKXPRINTF /* Our printf macro conflicts with */
-#undef printf /* use of "printf" in curses.h */
-#endif /* CKXPRINTF */
-#ifdef M_XENIX /* SCO XENIX... */
-#ifdef M_TERMCAP
-#undef M_TERMCAP
-#endif /* M_TERMCAP */
-#ifndef M_TERMINFO
-#define M_TERMINFO
-#endif /* M_TERMINFO */
-#endif /* M_XENIX */
-#ifdef RTAIX
-#undef NLS /* Avoid 'redeclaration of free'. */
-#endif /* RTAIX */
-#include <curses.h>
-#ifdef CKXPRINTF
-#define printf ckxprintf
-#endif /* CKXPRINTF */
-#endif /* CK_NCURSES */
-#endif /* MYCURSES */
-#endif /* VMS */
-
-#ifdef BUG999
-_PROTOTYP(int tgetent,(char *, char *));
-_PROTOTYP(char *tgetstr,(char *, char **));
-_PROTOTYP(int tputs,(char *, int, int (*)()));
-_PROTOTYP(char *tgoto,(const char *, int, int));
-#endif /* BUG999 */
-
-#endif /* CK_CURSES */
-
-/* F X D I N I T -- File Xfer Display Initialization */
-
-#ifdef CK_CURSES
-#ifndef MYCURSES
-#ifndef CK_SMG
-static
-#ifdef CK_ANSIC
-/* Can't use VOID because of curses.h */
-void
-ck_termset(int);
-#else
-ck_termset();
-#endif /* CK_ANSIC */
-#endif /* CK_SMG */
-#endif /* MYCURSES */
-#endif /* CK_CURSES */
-
-#ifdef NOTERMCAP
-static int notermcap = 1;
-#else
-static int notermcap = 0;
-#endif /* NOTERMCAP */
-
-#ifndef NODISPLAY
-CKVOID
-fxdinit(xdispla) int xdispla; {
-#ifndef COHERENT
-#ifndef OS2
-#ifndef STRATUS
- char *s;
- int x, dummy;
-
- debug(F101,"fxdinit xdispla","",xdispla);
- debug(F101,"fxdinit fxd_inited","",fxd_inited);
-
-#ifdef IKSD
-#ifndef NOXFER
- /* No curses for IKSD */
- if (inserver) {
- fdispla = XYFD_N;
- return;
- }
- if (fxd_inited) /* Only do this once */
- return;
-#endif /* NOXFER */
-#endif /* IKSD */
-
- if (xdispla == XYFD_R || xdispla == XYFD_S || xdispla == XYFD_B) {
- if (xfrmsg) {
- printf("%s\n",xfrmsg);
- makestr(&xfrmsg,NULL);
- }
- }
-
-#ifdef CK_CURSES
-#ifdef VMS
- /* Force BRIEF in Batch logs */
- if (batch && (xdispla == XYFD_C || xdispla == XYFD_S))
- xdispla = XYFD_B;
-#else
- if (xdispla == XYFD_C || xdispla == 9999) {
-
-#ifdef DYNAMIC
- if (!trmbuf) {
-/*
- Allocate tgetent() buffer. Make it big -- some termcaps can be huge;
- tgetent() merrily writes past the end of the buffer, causing core dumps
- or worse.
-*/
- trmbuf = (char *)malloc(TRMBUFL);
- if (!trmbuf) {
- notermcap = 1;
- debug(F101,"fxdinit malloc trmbuf","FAILED",TRMBUFL);
- fdispla = XYFD_S;
- return;
- }
-#ifdef COMMENT
- debug(F111,"fxdinit malloc trmbuf","OK",TRMBUFL);
- debug(F001,"fxdinit trmbuf","",trmbuf);
- memset(trmbuf,'\0',(size_t)TRMBUFL);
- debug(F100,"fxdinit memset OK","",0);
-#endif /* COMMENT */
- }
-#endif /* DYNAMIC */
-
- debug(F100,"fxdinit before getenv(TERM)","",0);
- s = getenv("TERM");
- debug(F110,"fxdinit after getenv(TERM)",s,0);
- if (!s) s = "";
- if (*s) {
- debug(F110,"fxdinit before tgetent()",s,0);
- x = tgetent(trmbuf,s);
- debug(F111,"fxdinit tgetent",s,x);
- } else {
- x = 0;
- notermcap = 1;
- debug(F110,"fxdinit TERM null - no tgetent",s,0);
- }
- if (x < 1 && !quiet && !backgrd
-#ifdef VMS
- && !batch
-#endif /* VMS */
- ) {
- printf("Warning: terminal type unknown: \"%s\"\n",s);
-#ifdef COMMENT
- /* Confusing - nobody knows what this means */
- printf("SCREEN command will use ANSI sequences.\n");
-#endif /* COMMENT */
- if (local)
- printf("Fullscreen file transfer display disabled.\n");
- fdispla = XYFD_S;
- }
-#ifndef MYCURSES
-#ifndef CK_SMG
- ck_termset(x);
-#endif /* CK_SMG */
-#endif /* MYCURSES */
- fxd_inited = 1;
- }
-#endif /* CK_CURSES */
-#endif /* VMS */
-#endif /* STRATUS */
-#endif /* OS2 */
-#endif /* COHERENT */
-}
-#endif /* NODISPLAY */
-
-#ifdef CK_CURSES
-#ifdef CK_SMG
-/*
- Long section for Screen Manager starts here...
- By William Bader.
-*/
-#include "ckvvms.h"
-#ifdef OLD_VMS
-#include <smgdef.h> /* use this on VAX C 2.4 */
-/* #include <smgmsg.h> */
-#else
-#include <smg$routines.h> /* Martin Zinser */
-#endif /* OLD_VMS */
-
-extern unsigned int vms_status; /* Used for system service return status */
-
-static long smg_pasteboard_id = -1; /* pasteboard identifier */
-static long smg_display_id = -1; /* display identifier */
-static int smg_open = 0; /* flag if smg current open */
-static int smg_inited = 0; /* flag if smg initialized */
-
-#ifdef COMMENT
-#define clrtoeol() SMG$ERASE_LINE(&smg_display_id, 0, 0)
-
-#define clear() SMG$ERASE_DISPLAY(&smg_display_id, 0, 0, 0, 0)
-
-#define touchwin(scr) SMG$REPAINT_SCREEN(&smg_pasteboard_id)
-
-#else /* Not COMMENT */
-
-#define clrtoeol() smg$erase_line(&smg_display_id, 0, 0)
-
-#define clear() smg$erase_display(&smg_display_id, 0, 0, 0, 0)
-
-#define touchwin(scr) smg$repaint_screen(&smg_pasteboard_id)
-#endif /* COMMENT */
-
-#define clearok(curscr,ok) /* Let wrefresh() do the work */
-
-#define wrefresh(cursrc) touchwin(scr)
-
-static void
-move(row, col) int row, col; {
- /* Change from 0-based for curses to 1-based for SMG */
- if (!smg_open)
- return;
- ++row; ++col;
- debug(F111,"VMS smg move",ckitoa(row),col);
-#ifdef COMMENT /* Martin Zinser */
- CHECK_ERR("move: smg$set_cursor_abs",
- SMG$SET_CURSOR_ABS(&smg_display_id, &row, &col));
-#else
- CHECK_ERR("move: smg$set_cursor_abs",
- smg$set_cursor_abs(&smg_display_id, &row, &col));
-#endif /* COMMENT */
- debug(F101,"VMS smg move vms_status","",vms_status);
-}
-
-#ifdef VMS_V40
-#define OLD_VMS
-#endif /* VMS_V40 */
-#ifdef VMS_V42
-#define OLD_VMS
-#endif /* VMS_V42 */
-#ifdef VMS_V44
-#define OLD_VMS
-#endif /* VMS_V44 */
-
-static int
-initscr() {
- int rows = 24, cols = 80;
- int row = 1, col = 1;
-
- debug(F101,"VMS initscr smg_pasteboard_id A","",smg_pasteboard_id);
-
- if (smg_pasteboard_id == -1) { /* Open the screen */
-#ifdef OLD_VMS /* Note: Routine calls lowercased 9/96 */
- CHECK_ERR("initscr: smg$create_pasteboard",
- smg$create_pasteboard(&smg_pasteboard_id, 0, 0, 0, 0));
-#else
- /* For VMS V5, not tested */
- CHECK_ERR("initscr: smg$create_pasteboard",
- smg$create_pasteboard(&smg_pasteboard_id, 0, 0, 0, 0, 0));
-#endif /* OLD_VMS */
- }
- debug(F101,"VMS initscr smg_pasteboard_id B","",smg_pasteboard_id);
- if (smg_pasteboard_id == -1) {
- printf("?Error initializing fullscreen display\n");
- fdispla = XYFD_S;
- dpyinit();
- return(0);
- }
- debug(F101,"VMS initscr smg_display_id","",smg_display_id);
- if (smg_display_id == -1) { /* Create a display window */
-
-#ifdef COMMENT /* Martin Zinser */
- CHECK_ERR("initscr: smg$create_virtual_display",
- SMG$CREATE_VIRTUAL_DISPLAY(&rows, &cols, &smg_display_id,
- 0, 0, 0));
-
- /* Connect the display window to the screen */
- CHECK_ERR("initscr: smg$paste_virtual_display",
- SMG$PASTE_VIRTUAL_DISPLAY(&smg_display_id,&smg_pasteboard_id,
- &row,&col));
-#else
- CHECK_ERR("initscr: smg$create_virtual_display",
- smg$create_virtual_display(&rows, &cols, &smg_display_id,
- 0, 0, 0));
-
- /* Connect the display window to the screen */
- CHECK_ERR("initscr: smg$paste_virtual_display",
- smg$paste_virtual_display(&smg_display_id,&smg_pasteboard_id,
- &row,&col));
-#endif /* COMMENT */
- }
- debug(F101,"VMS initscr smg_open A","",smg_open);
- if (!smg_open) { /* Start a batch update */
- smg_open = 1;
-#ifdef COMMENT
- CHECK_ERR("initscr: smg$begin_pasteboard_update",
- SMG$BEGIN_PASTEBOARD_UPDATE(&smg_pasteboard_id));
-#else
- CHECK_ERR("initscr: smg$begin_pasteboard_update",
- smg$begin_pasteboard_update(&smg_pasteboard_id));
-#endif /* COMMENT */
- debug(F101,"VMS initscr smg$begin_pasteboard_update","",vms_status);
- }
- debug(F101,"VMS initscr smg_open B","",smg_open);
- smg_inited = 1;
- return(1);
-}
-
-static void
-refresh() {
- debug(F101,"refresh smg_pasteboard_id","",smg_pasteboard_id);
-
- if (smg_open == 0 || smg_pasteboard_id == -1)
- return;
-
-#ifdef COMMENT /* Martin Zinser */
- CHECK_ERR("refresh: smg$end_pasteboard_update",
- SMG$END_PASTEBOARD_UPDATE(&smg_pasteboard_id));
- CHECK_ERR("refresh: smg$begin_pasteboard_update",
- SMG$BEGIN_PASTEBOARD_UPDATE(&smg_pasteboard_id));
-#else
- CHECK_ERR("refresh: smg$end_pasteboard_update",
- smg$end_pasteboard_update(&smg_pasteboard_id));
- CHECK_ERR("refresh: smg$begin_pasteboard_update",
- smg$begin_pasteboard_update(&smg_pasteboard_id));
-#endif /* COMMENT */
-}
-
-static void
-endwin() {
- if (!smg_open)
- return;
-
- smg_open = 0;
-
-#ifdef COMMENT
- CHECK_ERR("endwin: smg$end_pasteboard_update",
- SMG$END_PASTEBOARD_UPDATE(&smg_pasteboard_id));
-#else
- CHECK_ERR("endwin: smg$end_pasteboard_update",
- smg$end_pasteboard_update(&smg_pasteboard_id));
-#endif /* COMMENT */
-
- move(22, 0);
-
-#ifdef COMMENT
-/*
- These calls clear the screen.
- (convert routine calls to lowercase - Martin Zinser)
-*/
- CHECK_ERR("endwin: smg$delete_virtual_display",
- SMG$DELETE_VIRTUAL_DISPLAY(&smg_display_id));
- smg_display_id = -1;
-
- CHECK_ERR("endwin: smg$delete_pasteboard",
- SMG$DELETE_PASTEBOARD(&smg_pasteboard_id, 0));
- smg_pasteboard_id = -1;
-#endif /* COMMENT */
-}
-
-#ifdef COMMENT
-/* DECC 6.2 screams bloody murder about printw ("not enough args") */
-/* but adding the following prototype only makes it holler louder. */
-#ifdef __DECC
-/* "varargs" prototype for printw */
-_PROTOTYP(static int printw,(char *, ...));
-#endif /* __DECC */
-#endif /* COMMENT */
-
-#ifdef __DECC
-#include <stdarg.h>
-_PROTOTYP(static void printw,(char *, ...));
-static void
-printw(char *str,...) {
- char buf[255];
- va_list ap;
- $DESCRIPTOR(text_dsc, 0);
- text_dsc.dsc$a_pointer=buf;
- if (!smg_open)
- return;
- va_start(ap,str);
- text_dsc.dsc$w_length = vsprintf(buf, str, ap);
- va_end(ap);
- CHECK_ERR("printw: smg$put_chars",
- smg$put_chars(&smg_display_id, &text_dsc, 0, 0, 0, 0, 0));
-}
-#else
-static void
-printw(str, a1, a2, a3, a4, a5, a6, a7, a8)
- char *str;
- long a1, a2, a3, a4, a5, a6, a7, a8;
-/* printw */ {
- char buf[255];
- $DESCRIPTOR(text_dsc, 0);
- if (!smg_open)
- return;
- text_dsc.dsc$a_pointer=buf;
- text_dsc.dsc$w_length = sprintf(buf, str, a1, a2, a3, a4, a5, a6, a7, a8);
- CHECK_ERR("printw: smg$put_chars",
- smg$put_chars(&smg_display_id, &text_dsc, 0, 0, 0, 0, 0));
-}
-#endif /* __DECC */
-
-#define CK_CURPOS
-int
-ck_curpos(row, col) {
- debug(F111,"VMS smg ck_curpos",ckitoa(row),col);
- if (!smg_inited || !smg_open) {
- initscr();
- }
- debug(F101,"VMS smg curpos smg_open","",smg_open);
- if (!smg_open)
- return(0);
- debug(F111,"VMS smg ck_curpos",ckitoa(row-1),col-1);
- move(row - 1, col - 1); /* SMG is 0-based */
- refresh();
- /* endwin(); */
- return(0);
-}
-
-int
-ck_cls() {
- debug(F101,"VMS smg ck_cls smg_inited","",smg_inited);
- if (!smg_inited || !smg_open) {
- initscr();
- }
- debug(F101,"VMS smg ck_cls smg_open","",smg_open);
- if (!smg_open)
- return(0);
- clear();
- refresh();
- /* endwin(); */
- return(0);
-}
-
-int
-ck_cleol() {
- debug(F101,"VMS smg ck_cleol smg_inited","",smg_inited);
- if (!smg_inited || !smg_open) {
- initscr();
- }
- debug(F101,"VMS smg ck_cleol smg_open","",smg_open);
- if (!smg_open)
- return(0);
- clrtoeol();
- refresh();
- /* endwin(); */
- return(0);
-}
-#endif /* CK_SMG */
-
-#ifdef MYCURSES
-/*
- Do-it-yourself curses implementation for VMS, OS/2 and other ANSI/VT-100's.
- Supports only the VT52 and VT1xx (and later VT2xx/3xx/4xx) terminals.
- By Terry Kennedy, St Peters College.
-
- First, some stuff we can just ignore:
-*/
-
-static int
-touchwin(x) int x; {
- return(0);
-}
-static int
-initscr() {
- return(0);
-}
-static int
-refresh() {
- return(0);
-}
-static int
-endwin() {
- return(0);
-}
-
-/*
- * Now, some stuff we need to do:
- */
-
-_PROTOTYP( int move, (int, int) );
-#ifndef OS2
-int
-move(row, col) int row, col; {
- if (isvt52)
- printf("\033Y%c%c", row + 037, col + 037);
- else
- printf("\033[%d;%dH", row + 1, col + 1);
- return(0);
-}
-
-int
-clear() {
- move(0,0);
- if (isvt52)
- printf("\033J");
- else
- printf("\033[J");
- return(0);
-}
-
-int
-clrtoeol() {
- if (isvt52)
- printf("\033K");
- else
- printf("\033[K");
- return(0);
-}
-
-#define CK_CURPOS
-int
-ck_cls() {
- return(clear());
-}
-
-int
-ck_cleol() {
- return(clrtoeol());
-}
-
-int
-ck_curpos(row, col) int row, col; {
- move(row, col);
- return(0);
-}
-
-#else /* OS2 */
-/* Windows NT and Windows 95 do not provide ANSI emulation */
-/* Therefore we might as well not use it for OS/2 either */
-
-int
-move(row, col) int row, col; {
-#ifndef ONETERMUPD
- SetCurPos(row, col);
-#endif /* ONETERMUPD */
- lgotoxy( VCMD, col+1, row+1);
- VscrnIsDirty(VCMD);
- return(0);
-}
-
-int
-clear() {
- viocell cell;
- move(0,0);
-#ifdef ONETERMUPD
- if (VscrnGetBufferSize(VCMD) > 0) {
- VscrnScroll(VCMD, UPWARD, 0,
- VscrnGetHeight(VCMD)-(1),
- VscrnGetHeight(VCMD)-(0), TRUE, CHR_SP);
- cleartermscreen(VCMD);
- }
-#else
- cell.c = ' ';
- cell.a = colorcmd;
- WrtNCell(cell, cmd_rows * cmd_cols, 0, 0);
-#endif /* ONETERMUPD */
- return(0);
-}
-
-int
-clrtoeol() {
- USHORT row, col;
- viocell cell;
-
- cell.c = ' ';
- cell.a = colorcmd;
-#ifndef ONETERMUPD
- GetCurPos(&row, &col );
- WrtNCell(cell, cmd_cols - col -1, row, col);
-#endif /* ONETERMUPD */
- clrtoeoln(VCMD,CHR_SP);
- return(0);
-}
-
-#define CK_CURPOS
-int
-ck_curpos(row, col) int row, col; {
- move(row, col);
- return(0);
-}
-
-int
-ck_cls() {
- return(clear());
-}
-
-int
-ck_cleol() {
- return(clrtoeol());
-}
-
-#endif /* OS2 */
-#endif /* MYCURSES */
-
-#ifndef NOTERMCAP
-#ifndef CK_CURPOS
-#define CK_CURPOS
-
-/* Termcap/Terminfo section */
-
-static char cur_cls[32] = { NUL, NUL };
-static char cur_cleol[32] = { NUL, NUL };
-static char cur_cm[64] = { NUL, NUL };
-static char tgsbuf[128] = { NUL, NUL };
-
-static
-#ifdef CK_ANSIC
-void
-#endif /* CK_ANSIC */
-ck_termset(x) int x; {
- cur_cls[0] = NUL;
- cur_cleol[0] = NUL;
- cur_cm[0] = NUL;
-#ifdef tgetent
- debug(F100,"tgetent is a macro","",0);
-#endif /* tgetent */
-#ifdef tgetstr
- debug(F100,"tgetstr is a macro","",0);
-#endif /* tgetstr */
-#ifdef tputs
- debug(F100,"tputs is a macro","",0);
-#endif /* tputs */
-#ifdef tgoto
- debug(F100,"tgoto is a macro","",0);
-#endif /* tgoto */
-#ifdef NOTERMCAP
- /* tgetstr() gets a segmentation fault on OSF/1 */
- debug(F100,"ck_termset NOTERMCAP","",0);
-#else
- if (notermcap) {
- debug(F100,"ck_termset notermcap","",0);
- return;
- }
- debug(F101,"ck_termset x","",x);
- if (x > 0) {
- char * bp;
- bp = tgsbuf;
- *bp = NUL;
- debug(F110,"ck_termset calling tgetstr","cl",0);
- if (tgetstr("cl", &bp)) { /* Get clear-screen code */
- debug(F110,"ck_termset tgetstr cl",tgsbuf,"");
- if ((int)strlen(tgsbuf) < 32)
- ckstrncpy(cur_cls,tgsbuf,32);
- } else
- return;
- bp = tgsbuf;
- if (tgetstr("ce", &bp)) { /* Get clear-to-end-of-line code */
- debug(F110,"ck_termset tgetstr ce",tgsbuf,"");
- if ((int)strlen(tgsbuf) < 32)
- ckstrncpy(cur_cleol,tgsbuf,32);
- } else
- return;
- bp = tgsbuf;
- if (tgetstr("cm", &bp)) { /* Get cursor-movement code */
- debug(F110,"ck_termset tgetstr cm",tgsbuf,"");
- if ((int)strlen(tgsbuf) < 64)
- ckstrncpy(cur_cm,tgsbuf,64);
- } else
- return;
- }
-#endif /* NOTERMCAP */
-}
-
-#ifndef TPUTSFNTYPE
-#ifdef TPUTSISVOID
-#define TPUTSFNTYPE void
-#else
-#define TPUTSFNTYPE int
-#endif /* TPUTSISVOID */
-#endif /* TPUTSFNTYPE */
-
-#ifndef TPUTSARGTYPE
-#ifdef HPUX9
-#define TPUTSARGTYPE char
-#else
-#ifdef HPUX10
-#define TPUTSARGTYPE char
-#else
-#define TPUTSARGTYPE int
-#endif /* HPUX10 */
-#endif /* HPUX9 */
-#endif /* TPUTSARGTYPE */
-
-static TPUTSFNTYPE
-#ifdef CK_ANSIC
-ck_outc(TPUTSARGTYPE x)
-#else
-ck_outc(x) TPUTSARGTYPE x;
-#endif /* CK_ANSIC */
-{ /* To satisfy tputs() arg3 prototype */
- int rc;
- char c;
- c = (char) x;
- rc = (inserver) ? ttoc(c) : conoc(c);
-#ifndef TPUTSISVOID
- return(rc);
-#endif /* TPUTSISVOID */
-}
-
-int
-ck_curpos(row, col) int row, col; {
-#ifdef CK_ANSIC
- TPUTSFNTYPE (*fn)(TPUTSARGTYPE);
-#else
- TPUTSFNTYPE (*fn)();
-#endif /* CK_ANSIC */
- if (!fxd_inited)
- fxdinit(9999);
- if (!cur_cm[0]) { /* We don't have escape sequences */
-#ifdef COMMENT
- return(-1); /* Do nothing */
-#else
- /* Both C-Kermit's SCREEN command and ANSI/VT100 are 1-based */
- printf("\033[%d;%dH", row, col); /* Or default to ANSI */
-#endif /* COMMENT */
- } else {
- fn = ck_outc;
- /* termcap/terminfo is 0-based */
- tputs(
-#ifdef TPUTSARG1CONST
- (const char *)
-#endif /* TPUTSARG1CONST */
- tgoto(cur_cm,col-1,row-1),1,fn);
- }
- return(0);
-}
-
-int
-ck_cls() {
-#ifdef CK_ANSIC
- TPUTSFNTYPE (*fn)(TPUTSARGTYPE);
-#else
- TPUTSFNTYPE (*fn)();
-#endif /* CK_ANSIC */
- if (!fxd_inited)
- fxdinit(9999);
- if (!cur_cls[0]) { /* If we don't have escape sequences */
-#ifdef COMMENT
- return(-1); /* Do nothing */
-#else
- printf("\033[;H\033[2J"); /* Or default to ANSI */
-#endif /* COMMENT */
- } else {
- fn = ck_outc;
- debug(F111,"ck_cls 2",cur_cls,fxd_inited);
- tputs(cur_cls,cmd_rows,fn);
- }
- return(0);
-}
-
-int
-ck_cleol() {
-#ifdef CK_ANSIC
- TPUTSFNTYPE (*fn)(TPUTSARGTYPE);
-#else
- TPUTSFNTYPE (*fn)();
-#endif /* CK_ANSIC */
- if (!fxd_inited)
- fxdinit(9999);
- if (!cur_cleol[0]) { /* If we don't have escape sequences */
-#ifdef COMMENT
- return(-1); /* Do nothing */
-#else
- printf("\033[K"); /* Or use ANSI */
-#endif /* COMMENT */
- } else {
- fn = ck_outc;
- tputs(cur_cleol,1,fn);
- }
- return(0);
-}
-#endif /* CK_CURPOS */
-#else
-static void
-ck_termset(x) int x; {
- if (x) return;
-}
-#endif /* NOTERMCAP */
-
-#ifndef CK_CURPOS
-#define CK_CURPOS
-int
-ck_cls() {
- printf("\033[;H\033[2J");
- return(0);
-}
-
-int
-ck_cleol() {
- printf("\033[K");
- return(0);
-}
-
-int
-ck_curpos(row, col) int row, col; {
- printf("\033[%d;%dH", row, col);
- return(0);
-}
-#endif /* CK_CURPOS */
-
-
-#ifndef NOXFER
-static int cinit = 0; /* Flag for curses init'd */
-static int cendw = 0; /* endwin() was called */
-
-static
-#ifdef CK_ANSIC /* Because VOID used by curses.h */
-void
-#else
-#ifdef MYCURSES
-VOID
-#else
-int
-#endif /* MYCURSES */
-#endif /* CK_ANSIC */
-#ifdef CK_ANSIC /* Update % transfered and % bar */
-updpct(long old, long new)
-#else /* CK_ANSIC */
-updpct(old, new) long old, new;
-#endif /* CK_ANSIC */
-/* updpct */ {
-#ifdef COMMENT
- int m, n;
- move(CW_PCD,22);
- printw("%ld", new);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_PCD, (long) new);
-#endif /* K95G */
-#endif /* KUI */
-#ifdef CK_PCT_BAR
- if (thermometer) {
- if (old > new) {
- old = 0;
- move(CW_PCD, 26);
- clrtoeol();
- }
- m = old/2;
- move(CW_PCD, 26 + m);
- n = new / 2 - m;
-#ifndef OS2
- while (n > 0) {
- if ((m + 1) % 5 == 0)
- printw("*");
- else
- printw("=");
- m++;
- n--;
- }
- if (new % 2 != 0) printw("-");
- /* move(CW_PCD, 22+53); */
-#else /* OS2 */
- while (n > 0) {
- printw("%c", '\333');
- m++; n--;
- }
- if (new % 2 != 0)
- printw("%c", '\261');
-#endif /* OS2 */
- }
-#endif /* CK_PCT_BAR */
- /* clrtoeol(); */
-#else /* !COMMENT */
-#ifdef OS2
-#define CHAR1 '\333' /* OS2 - CP437 */
-#define CHAR2 '\261'
-#else
-#define CHAR1 '/' /* Default */
-#define CHAR2 '-'
-#endif /* OS2 */
- debug(F101,"updpct old","",old);
- debug(F101,"updpct new","",new);
- move(CW_PCD,22);
- printw("%-3ld", new); /* (was) printw("%ld", new); */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PCD, (long) new );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef CK_PCT_BAR
- if (thermometer) {
- int m, n;
-
- if (old > new) {
- old = 0 ;
- move(CW_PCD, 26);
- clrtoeol();
- }
- if (new <= 100L) {
- m = old / 2;
- n = new / 2 - m;
- move(CW_PCD, 26+m);
- while (n-- > 0)
- printw("%c", CHAR1);
- if (new % 2 != 0)
- printw("%c", CHAR2);
- }
- }
-#endif /* CK_PCT_BAR */
-#endif /* COMMENT */
-}
-
-static CK_OFF_T old_tr = (CK_OFF_T)-1; /* Time remaining previously */
-
-static CK_OFF_T
-#ifdef CK_ANSIC
-shoetl(CK_OFF_T old_tr, long cps, CK_OFF_T fsiz, CK_OFF_T howfar)
-#else
- shoetl(old_tr, cps, fsiz, howfar) long cps; CK_OFF_T old_tr, fsiz, howfar;
-#endif /* CK_ANSIC */
-/* shoetl */ { /* Estimated time left in transfer */
- CK_OFF_T tr; /* Time remaining, seconds */
-
-#ifdef GFTIMER
- if (fsiz > 0L && cps > 0L)
- tr = (CK_OFF_T)((CKFLOAT)(fsiz - howfar) / (CKFLOAT)cps);
- else
- tr = (CK_OFF_T)-1;
-#else
- tr = (fsiz > 0L && cps > 0L) ?
- ((fsiz - howfar) / cps) :
- (CK_OFF_T)-1;
-#endif /* GFTIMER */
- move(CW_TR,22);
- if (tr > (CK_OFF_T)-1) {
- if (tr != old_tr) {
- printw("%s",hhmmss(tr));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long)CW_TR, (long)hhmmss(tr));
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- }
- } else {
- printw("(unknown)");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TR, (long) "(unknown)" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- }
- return(tr);
-}
-
-static long
-#ifdef CK_ANSIC
-shocps(int pct, CK_OFF_T fsiz, CK_OFF_T howfar)
-#else
-shocps(pct, fsiz, howfar) int pct; CK_OFF_T fsiz, howfar;
-#endif /* CK_ANSIC */
-/* shocps */ {
-#ifdef CPS_WEIGHTED
- static CK_OFF_T oldffc = 0L;
-#endif /* CPS_WEIGHTED */
-#ifdef GFTIMER
- CKFLOAT secs, xx;
-#else
- CK_OFF_T secs, xx;
-#endif /* GFTIMER */
-
-#ifdef GFTIMER
- xx = (gtv >= 0.0) ? gtv : 0.0; /* Floating-point version */
- gtv = gftimer();
- if ((gtv - oldgtv) < (CKFLOAT) 1.0) /* Only do this once per second */
- return(oldcps);
- oldgtv = xx;
-#else
- xx = (gtv >= 0) ? gtv : 0; /* Whole-number version */
- gtv = gtimer();
- if ((gtv - oldgtv) < 1)
- return(oldcps);
- oldgtv = xx;
-#endif /* GFTIMER */
-
-#ifdef CPS_WEIGHTED
- /* debug(F100,"SHOCPS: WEIGHTED","",0); */
- if (gtv != oldgtv) { /* The first packet is ignored */
- if (ffc < oldffc)
- oldffc = ffc;
- oldcps = cps;
- if (oldcps && oldgtv >
-#ifdef GFTIMER
- 1.0
-#else
- 1
-#endif /* GFTIMER */
- ) { /* The first second is ignored */
-/*
- This version of shocps() produces a weighted average that some
- people like, but most people find it disconcerting and bombard us
- with questions and complaints about why the CPS figure fluctuates so
- wildly. So now you only get the weighted average if you build the
- program yourself with CPS_WEIGHTED defined.
-*/
-#ifndef CPS_VINCE
-#ifdef GFTIMER
- cps = (long)((((CKFLOAT)oldcps * 3.0) +
- (CKFLOAT)(ffc - oldffc) / (gtv-oldgtv) ) / 4.0);
-#else
- cps = ( (oldcps * 3) + (ffc - oldffc) / (gtv-oldgtv) ) / 4;
-#endif /* GFTIMER */
-#else
-/* And an alternate weighting scheme from Vincent Fatica... */
- cps = (3 *
- ((1+pct/300)*oldffc/oldgtv+(1-pct/100)*(ffc-oldffc)/(gtv-oldgtv)))
- / 4;
-#endif /* CPS_VINCE */
- } else {
- /* No weighted average since there is nothing to weigh */
-#ifdef GFTIMER
- cps = (long)(gtv != 0.0 ?
- (CKFLOAT)(ffc - oldffc) / (gtv - oldgtv) :
- (ffc - oldffc)) ;
-#else
- cps = gtv ? (ffc - oldffc) / (gtv - oldgtv) : (ffc - oldffc) ;
-#endif /* GFTIMER */
- }
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"SHOCPS: pct ","",pct);
- debug(F101,"SHOCPS: gtv ","",gtv);
- debug(F101,"SHOCPS: oldgtv","",oldgtv);
- debug(F101,"SHOCPS: dgtv ","",(long)(gtv-oldgtv));
- debug(F101,"SHOCPS: ffc ","",ffc);
- debug(F101,"SHOCPS: oldffc","",oldffc);
- debug(F101,"SHOCPS: dffc ","",ffc-oldffc);
- debug(F101,"SHOCPS: cps ","",cps);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- move(CW_CP,22);
- printw("%ld", cps);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, (long) cps );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldffc = ffc;
- }
-#else /* !CPS_WEIGHTED */
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- debug(F100,"SHOCPS: NOT WEIGHTED","",0);
- debug(F101,"SHOCPS: pct ","",pct);
- debug(F101,"SHOCPS: gtv ","",gtv);
- debug(F101,"SHOCPS: oldgtv ","",oldgtv);
- debug(F101,"SHOCPS: dgtv ","",(long)gtv - (long)oldgtv);
- debug(F101,"SHOCPS: ffc ","",ffc);
- debug(F101,"SHOCPS: oldffc ","",oldffc);
- debug(F101,"SHOCPS: dffc ","",ffc-oldffc);
- debug(F101,"SHOCPS: cps ","",cps);
- debug(F101,"SHOCPS: filcnt ","",filcnt);
-#ifdef GFTIMER
- debug(F101,"SHOCPS: fpfsecs","",fpfsecs);
-#endif /* GFTIMER */
- }
- debug(F101,"shocps gtv","",gtv);
-#endif /* DEBUG */
-#ifdef GFTIMER
-#endif /* COMMENT */
- /* debug(F101,"shocps fpfsecs","",fpfsecs); */
- secs = gtv - fpfsecs;
- /* debug(F101,"shocps secs","",(long)secs); */
- if (secs > 0.0) {
- cps = (long)((CKFLOAT) ffc / secs);
- /* debug(F101,"shocps cps","",cps); */
- move(CW_CP,22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, (long) cps );
-#endif /* K95G */
-#endif /* KUI */
- printw("%ld", cps);
- clrtoeol();
- }
-#else /* Not GFTIMER */
- if ((secs = gtv - fsecs) > 0) {
- cps = (secs < 1L) ? ffc : ffc / secs;
- move(CW_CP,22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, (long) cps );
-#endif /* K95G */
-#endif /* KUI */
- printw("%ld", cps);
- clrtoeol();
- }
-#endif /* GFTIMER */
-#endif /* CPS_WEIGHTED */
-
- if (cps > peakcps && /* Peak transfer rate */
- ((what & W_SEND && spackets > wslots + 4) ||
- (!(what & W_SEND) && spackets > 10))) {
- peakcps = cps;
- }
- old_tr = shoetl(old_tr, cps, fsiz, howfar);
- return(cps);
-}
-
-static
-#ifdef CK_ANSIC /* Because VOID used by curses.h */
-void
-#else
-#ifdef MYCURSES
-VOID
-#else
-int
-#endif /* MYCURSES */
-#endif /* CK_ANSIC */
-scrft() { /* Display file type */
- char xferstr[256];
- xferstr[0] = NUL;
- debug(F101,"scrft binary","",binary);
- if (binary) {
- switch(binary) {
- case XYFT_L:
- ckstrncpy(xferstr,"LABELED",256);
- break;
- case XYFT_I:
- ckstrncpy(xferstr,"IMAGE",256);
- break;
- case XYFT_U:
- ckstrncpy(xferstr,"BINARY UNDEFINED",256);
- break;
- case XYFT_M:
- ckstrncpy(xferstr,"MACBINARY",256);
- break;
- case XYFT_X:
- ckstrncpy(xferstr,"TENEX",256);
- break;
- default:
- case XYFT_B:
- ckstrncpy(xferstr,"BINARY",256);
- break;
- }
-#ifdef CK_RESEND
- if (what & W_SEND && sendstart > 0L) {
- if (sendmode == SM_PSEND) {
- ckstrncat(xferstr, " / partial", 256);
- } else if (sendmode == SM_RESEND) {
- ckstrncat(xferstr, " / resend", 256);
- }
- } else if (what & W_RECV && rs_len > 0L) {
- ckstrncat(xferstr, " / resend", 256);
- }
-#endif /* CK_RESEND */
- } else {
-
-#ifndef NOCSETS
- ckstrncpy(xferstr,"TEXT",256);
-#ifdef NEWFTP
-#ifndef NOUNICODE
- if (what & W_FTP) {
- if (ftp_csx < 0)
- ckstrncat(xferstr," (no translation)", 256);
- else
- ckmakxmsg(&xferstr[4],252,
- " (",
- fcsinfo[(what & W_SEND) ? ftp_csl : ftp_csx].keyword,
- " => ",
- fcsinfo[(what & W_SEND) ? ftp_csx : ftp_csl].keyword,
- ")",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL
- );
- } else
-#endif /* NOUNICODE */
-#endif /* NEWFTP */
- if (tcharset == TC_TRANSP) {
- ckstrncat(xferstr, " (no translation)", 256);
- } else {
- if (what & W_SEND) {
- sprintf( &xferstr[strlen(xferstr)], /* safe */
- " (%s => %s)",
- fcsinfo[fcharset].keyword, /* built-in keywords */
- tcsinfo[tcharset].keyword /* lengths are controlled */
- );
- } else {
- sprintf( &xferstr[strlen(xferstr)], /* safe */
- " (%s => %s)",
- tcsinfo[tcharset].keyword, /* built-in keywords */
- fcsinfo[fcharset].keyword); /* lengths controlled */
- }
- }
-#endif /* NOCSETS */
- }
- move(CW_TYP,22);
- printw("%s", xferstr);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TYP, (long) xferstr );
-#endif /* K95G */
-#endif /* KUI */
- return;
-}
-
-#ifdef CK_NEWTERM
-static FILE *ck_stdout = NULL;
-static int ck_fd = -1;
-#endif /* CK_NEWTERM */
-
-static long pct = 0L, oldpct = 0L, oldrtt = -1L;
-static int oldtyp = 0, oldwin = -1, oldtry = -1, oldlen = -1, oldtim = -1;
-
-#ifdef NETCONN
-static char *netname[] = {
- "none", /* 00 */
- "TCP/IP", /* 01 TCP (Sockets) */
- "TCP/IP", /* 02 TCP (Streams) */
- "X.25", /* 03 SunLink X.24 */
- "DECnet", /* 04 DECnet */
- "VAX PSI", /* 05 VAX PSI */
- "Named Pipes", /* 06 LAN Manager Named Pipe */
- "X.25", /* 07 Stratus VOS X.25 */
- "NetBIOS", /* 08 IBM NETBIOS */
- "SuperLAT", /* 07 Meridian SuperLAT */
- "File", /* 10 File */
- "Command", /* 11 Subprocess (pipe) */
- "DLL", /* 12 DLL does i/o */
- "X.25", /* 13 IBM AIXLink X.25 */
- "X.25", /* 14 HP-UX X.25 */
- "PTY", /* 15 Pseudoterminal */
- "SSH", /* 16 SSH */
- "<ERROR>", /* 17 In case new types are added */
- "<ERROR>", /* 18 but nobody remembers to update */
- "<ERROR>", /* 19 this table ... */
- NULL /* 20 */
-};
-static int nnetname = (sizeof(netname) / sizeof(char *));
-
-#endif /* NETCONN */
-
-#ifdef CK_ANSIC
-void
-screenc(int f, char c,CK_OFF_T n,char *s)
-#else
-CKVOID
-screenc(f,c,n,s)
-int f; /* argument descriptor */
-char c; /* a character or small integer */
-CK_OFF_T n; /* a long integer */
-char *s; /* a string */
-#endif /* CK_ANSIC */
-/* screenc() */ {
-#ifdef CK_SSL
- extern int tls_active_flag, ssl_active_flag;
-#endif /* CK_SSL */
-#ifdef RLOGCODE
- extern int ttnproto;
-#endif /* RLOGCODE */
- static int q = 0;
- static long fcnt = 0L; /* Number of files transferred */
- static CK_OFF_T fsiz = (CK_OFF_T)-1; /* Copy of file size */
- static CK_OFF_T fbyt = 0L; /* Total file bytes of all files transferred */
- static CK_OFF_T howfar = 0L; /* How much of current file has been xfer'd */
- static int pctlbl = 0L; /* Percent done vs Bytes so far */
- long cps = 0L;
-
- int net = 0;
- int xnet = 0;
- int ftp = 0;
- int len; /* Length of string */
- int errors = 0; /* Error counter */
- int x; /* Worker */
-
- debug(F101,"screenc cinit","",cinit);
- debug(F101,"screenc cendw","",cendw);
-
- if (!s) s = ""; /* Always do this. */
-
- ftp = (what & W_FTP) ? 1 : 0; /* FTP or Kermit */
- net = network || ftp;
- xnet = ftp ? 1 : nettype; /* NET_TCPB == 1 */
-
- if (cinit == 0 || cendw > 0) { /* Handle borderline cases... */
- if (f == SCR_CW) { /* Close window, but it's not open */
- ft_win = 0;
- return;
- }
- debug(F111,"screenc A",s,f);
- if (f == SCR_EM ||
- (f == SCR_PT && c == 'E')) { /* Fatal error before window open */
- conoll(""); conoc('?'); conoll(s); return; /* Regular display */
- }
- }
- if (cinit == 0) { /* Only call initscr() once */
- char * s;
- /* Check these now -- if they are defined but not numeric */
- /* they can crash curses */
- s = getenv("LINES");
- if (s) if (!rdigits(s)) {
- printf("?LINES variable not numeric: \"%s\".\n",s);
- printf("(Fullscreen display disabled)\n");
- fdispla = XYFD_S;
- return;
- }
- s = getenv("COLUMNS");
- if (s) if (!rdigits(s)) {
- printf("?COLUMNS variable not numeric: \"%s\".\n",s);
- printf("(Fullscreen display disabled)\n");
- fdispla = XYFD_S;
- return;
- }
- cendw = 1; /* New window needs repainting */
-#ifdef COMMENT
- if (!initscr()) { /* Oops, can't initialize window? */
-/*
- In fact, this doesn't happen. "man curses" says initscr() halts the
- entire program if it fails, which is true on the systems where I've
- tested it. It will fail if your terminal type is not known to it.
- That's why SET FILE DISPLAY FULLSCREEN calls tgetent() to make sure the
- terminal type is known before allowing a curses display.
-*/
- fprintf(stderr,"CURSES INITSCR ERROR\r\n");
- fdispla = XYFD_S; /* Fall back to CRT display */
- return;
- } else {
- cinit++; /* Window initialized ok */
- debug(F100,"CURSES INITSCR OK","",0);
- }
-#else /* Save some memory. */
-#ifdef CK_NEWTERM
- /* (From Andy Fyfe <andy@vlsi.cs.caltech.edu>)
- System V curses seems to reserve the right to alter the buffering
- on the output FILE* without restoring it. Fortunately System V
- curses provides newterm(), an alternative to initscr(), that
- allows us to specify explicitly the terminal type and input and
- output FILE pointers. Thus we duplicate stdout, and let curses
- have the copy. The original remains unaltered. Unfortunately,
- newterm() seems to be particular to System V.
- */
- s = getenv("TERM");
- if (ck_fd < 0) {
- ck_fd = dup(fileno(stdout));
- ck_stdout = (ck_fd >= 0) ? (FILE *)fdopen(ck_fd, "w") : NULL;
- }
- debug(F100,"screenc newterm...","",0);
-
-/* NOTE: It might be necessary to do this with stdin too! */
-/* This would have been the case in FreeBSD 4.1 but they fixed the */
-/* problem by restoring the buffering of stdin before the final release. */
-/* (But T.E. Dickey says stdin is not buffered?) */
-
- if (ck_stdout == NULL || newterm(s, ck_stdout, stdin) == 0) {
- fprintf(stderr,
- "Fullscreen display not supported for terminal type: %s\r\n",s);
- fdispla = XYFD_S; /* Use CRT instead */
- return;
- }
- debug(F100,"screenc newterm ok","",0);
-#else
- debug(F100,"screen calling initscr","",0);
- initscr(); /* Initialize curses. */
- debug(F100,"screen initscr ok","",0);
-#endif /* CK_NEWTERM */
- cinit++; /* Remember curses was initialized. */
-#endif /* COMMENT */
- }
- ft_win = 1; /* Window is open */
- if (repaint) {
-#ifdef CK_WREFRESH
-/*
- This totally repaints the screen, just what we want, but we can only
- do this with real curses, and then only if clearok() and wrefresh() are
- provided in the curses library.
-*/
-#ifdef OS2
- RestoreCmdMode();
-#else
-#ifdef QNX
-#ifndef QNX16
- clearok(stdscr, 1); /* QNX doesn't have curscr */
-#endif /* QNX16 */
- wrefresh(stdscr);
-#else
- wrefresh(curscr);
-#endif /* QNX */
-#endif /* OS2 */
-#else /* No CK_WREFRESH */
-/*
- Kermit's do-it-yourself method, works with all types of fullscreen
- support, but does not repaint all the fields. For example, the filename
- is lost, because it arrives at a certain time and never comes again, and
- Kermit presently does not save it anywhere. Making this method work for
- all fields would be a rather major recoding task, duplicating what curses
- already does, and would add a lot of complexity and storage space.
-*/
- cendw = 1;
-#endif /* CK_WREFRESH */
- repaint = 0;
- }
- if (cendw) { /* endwin() was called previously */
-#ifdef VMS
- initscr(); /* (or should have been!) */
- clear();
- touchwin(stdscr);
- refresh();
-#else
-#ifdef QNX
-/*
- In QNX, if we don't call initscr() here we core dump.
- I don't have any QNX curses documentation, but other curses manuals
- say that initscr() should be called only once per application, and
- experience shows that on other systems, calling initscr() here generally
- results in a core dump.
-*/
- debug(F100,"screenc re-calling initscr QNX","",0);
- initscr();
- clear();
- refresh();
-#ifdef COMMENT
-/*
- But even so, second and subsequent curses displays are messed up.
- Calling touchwin, refresh, etc, doesn't make any difference.
-*/
- debug(F100,"screenc calling touchwin QNX","",0);
- touchwin(stdscr);
- debug(F100,"screenc calling refresh QNX","",0);
- refresh();
-#endif /* COMMENT */
-
-#else /* All others... */
- debug(F100,"screenc calling clear","",0);
- clear();
- debug(F100,"screenc clear ok","",0);
-#endif /* QNX */
-#endif /* VMS */
- debug(F100,"screenc setup ok","",0);
- debug(F100,"screenc doing first move","",0);
- move(CW_BAN,0); /* Display the banner */
- debug(F110,"screenc myhost",myhost,0);
-#ifdef TCPSOCKET
- debug(F110,"screenc myipaddr",myipaddr,0);
-#endif /* TCPSOCKET */
-#ifdef HPUX1010
- debug(F100,"screenc calling first printw...","",0);
-/* Right here is where HP-UX 10.10 libxcurse.1 Rev 76.20 hangs... */
-#endif /* HPUX1010 */
- if (myhost[0]) {
-#ifdef TCPSOCKET
- if (!myipaddr[0]
-#ifdef OS2
- /* We need to perform this test because on non-TCP/IP */
- /* systems the call to getlocalipaddr() results in a */
- /* DNS Lookup which takes several minutes to time out */
- && net &&
- (xnet == NET_TCPA || xnet == NET_TCPB
-#ifdef SSHBUILTIN
- || xnet == NET_SSH
-#endif /* SSHBUILTIN */
- )
-#endif /* OS2 */
- )
- getlocalipaddr();
- if (myipaddr[0] && strcmp((char *)myhost,(char *)myipaddr))
- printw("%s, %s [%s]",versio,(char *)myhost,(char *)myipaddr);
- else
-#endif /* TCPSOCKET */
- printw("%s, %s",versio,(char *)myhost);
- } else {
- printw("%s",versio);
- }
-#ifdef HPUX1010
- debug(F100,"screenc first printw returns","",0);
-#endif /* HPUX1010 */
- move(CW_DIR,3);
- printw("Current Directory: %s",zgtdir());
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) zgtdir() );
-#endif /* K95G */
-#endif /* KUI */
- if (net) {
- move(CW_LIN,8);
- printw("Network Host: %s",
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "(unknown)") :
-#endif /* NEWFTP */
- ttname
- );
- } else {
- move(CW_LIN,0);
- printw("Communication Device: %s",ttname);
- }
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_LIN, (long) ttname );
-#endif /* K95G */
-#endif /* KUI */
-
- if (net) {
- move(CW_SPD,8);
- printw("Network Type: ");
- } else {
- move(CW_SPD,1);
- printw("Communication Speed: ");
- }
- move(CW_SPD,22); /* Serial speed or network type */
- if (net) {
-#ifdef NETCONN
- int secure = 0;
- char * xname;
- if (xnet > nnetname)
- xname = "[ERROR]";
- else
- xname = netname[xnet];
-#ifdef NEWFTP
- if (ftp) {
- if (ftpissecure())
- secure = 1;
- } else
-#endif /* NEWFTP */
- if (0
-#ifdef SSHBUILTIN
- || IS_SSH()
-#endif /* SSHBUILTIN */
-#ifdef CK_ENCRYPTION
- || ck_tn_encrypting() && ck_tn_decrypting()
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- || tls_active_flag || ssl_active_flag
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
-#ifdef CK_ENCRYPTION
- || ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_ENCRYPTION */
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
- ) {
- secure = 1;
- }
- if (secure) {
-#ifdef KUI
-#ifndef K95G
- char buf[30];
- sprintf(buf,"%s (SECURE)",xname);
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) buf
- );
-#endif /* K95G */
-#endif /* KUI */
- printw("%s (SECURE)",xname);
- } else {
- printw("%s",xname);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) xname
- );
-#endif /* K95G */
-#endif /* KUI */
- }
-#else
- printw("(network)");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(network)"
- );
-#endif /* K95G */
-#endif /* KUI */
-#endif /* NETCONN */
- } else {
- if (speed < 0L)
- speed = ttgspd();
- if (speed > 0L) {
- if (speed == 8880) {
- printw("75/1200");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "75/1200"
- );
-#endif /* K95G */
-#endif /* KUI */
- } else {
- char speedbuf[64] ;
- sprintf(speedbuf, "%ld", speed);
- printw("%s",speedbuf);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) speedbuf
- );
-#endif /* K95G */
-#endif /* KUI */
- }
- } else {
- printw("unknown");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(unknown)"
- );
-#endif /* K95G */
-#endif /* KUI */
- }
- }
- move(CW_PAR,14);
- printw("Parity: %s",ftp ? "none" : parnam((char)parity));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef CK_TIMERS
- if (/* rttflg && */ protocol == PROTO_K) {
- move(CW_TMO, 9); printw("RTT/Timeout:"); }
-#endif /* CK_TIMERS */
- move(CW_TYP,11); printw("File Type:");
- move(CW_SIZ,11); printw("File Size:");
- move(CW_PCD, 8);
- clrtoeol();
- pctlbl = (what & W_SEND);
- printw("%s:", pctlbl ? "Percent Done" : "Bytes So Far");
-
-#ifdef XYZ_INTERNAL
- move(CW_BAR, 1);
- printw("%10s Protocol:", ftp ? "FTP" : ptab[protocol].p_name);
-#endif /* XYZ_INTERNAL */
-#ifdef CK_PCT_BAR
- if (thermometer) {
- oldpct = pct = 0;
- move(CW_BAR,22);
- printw(" ...10...20...30...40...50...60...70...80...90..100");
- move(CW_BAR,22+56);
- }
-#endif /* CK_PCT_BAR */
- move(CW_TR, 1); printw("Estimated Time Left:");
- move(CW_CP, 2); printw("Transfer Rate, CPS:");
- move(CW_WS, 8); printw("Window Slots:%s",
- ((protocol == PROTO_K) && !ftp) ?
- "" : " N/A"
- );
- move(CW_PT, 9); printw("Packet Type:");
- if (ftp || protocol != PROTO_K) {
- move(CW_PT,22);
- printw("%s", "N/A");
- move(CW_PC, 11); printw("I/O Count:");
- move(CW_PL, 10); printw("I/O Length:");
- } else {
- move(CW_PC, 8); printw("Packet Count:");
- move(CW_PL, 7); printw("Packet Length:");
- }
-#ifndef COMMENT
- move(CW_PR, 9); printw("Error Count:");
-#else
- move(CW_PR, 2); printw("Packet Retry Count:");
-#endif
-#ifdef COMMENT
- move(CW_PB, 2); printw("Packet Block Check:");
-#endif /* COMMENT */
- move(CW_ERR,10); printw("Last Error:");
- move(CW_MSG, 8); printw("Last Message:");
- if (xfrmsg) {
- move(CW_MSG, 22); printw("%s",xfrmsg);
- makestr(&xfrmsg,NULL);
- }
- move(CW_INT, 0);
- if (!xfrint) {
- printw("(Transfer interruption is disabled)");
- } else {
-#ifdef CK_NEED_SIG
- printw(
-"<%s>X to cancel file, <%s>Z to cancel group, <%s><CR> to resend last packet",
- dbchr(escape), dbchr(escape), dbchr(escape)
- );
- move(CW_INT + 1, 0);
- printw(
-"<%s>E to send Error packet, ^C to quit immediately, <%s>L to refresh screen.",
- dbchr(escape), dbchr(escape)
- );
-#else /* !CK_NEED_SIG */
- move(CW_INT, 0);
-#ifdef OS2
- if (protocol == PROTO_K) {
- printw(
-"X to cancel file, Z to cancel group, <Enter> to resend last packet,"
- );
- }
-#else /* !OS2 */
-#ifdef VMS /* In VMS avoid bottom line */
- printw(
-"X: Cancel this file; E: Cancel transfer; ^C: Quit now; ^W: Refresh screen."
- );
-#else
- printw(
-"X to cancel file, Z to cancel group, <CR> to resend last packet,"
- );
-#endif /* VMS */
-#endif /* OS2 */
-
-#ifndef VMS
- move(CW_INT + 1, 0);
- if (protocol == PROTO_K) {
- printw(
-"E to send Error packet, ^C to quit immediately, ^L to refresh screen."
- );
- } else {
- printw("^C to cancel file transfer.");
- }
-#endif /* VMS */
-#endif /* CK_NEED_SIG */
- }
- refresh();
- cendw = 0;
- }
- debug(F101,"SCREENC switch","",f);
- debug(F000,"SCREENC c","",c);
- debug(F101,"SCREENC n","",n);
-
- len = strlen(s); /* Length of argument string */
- switch (f) { /* Handle our function code */
- case SCR_FN: /* Filename */
- oldpct = pct = 0L; /* Reset percents */
-#ifdef GFTIMER
- gtv = (CKFLOAT) -1.0;
- /* oldgtv = (CKFLOAT) -1.0; */
-#else
- gtv = -1L;
- /* oldgtv = -1L; */
-#endif /* GFTIMER */
- oldwin = -1;
- fsiz = (CK_OFF_T)-1; /* Invalidate previous file size */
- move(CW_PCD,22); /* Erase percent done from last time */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PCD, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_FFC, (long) 0 );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- move(CW_SIZ,22); /* Erase file size from last time */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) 0 );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- move(CW_ERR,22); /* And last error message */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) "" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-#ifdef COMMENT
-#ifdef STREAMING
- if (protocol == PROTO_K && streamok) {
- move(CW_BAR, 1);
-#ifdef XYZ_INTERNAL
- printw(" Kermit STREAMING:");
-#else
- printw(" STREAMING:");
-#endif /* XYZ_INTERNAL */
- }
-#endif /* STREAMING */
-#endif /* COMMENT */
-
- if (what & W_SEND) { /* If we're sending... */
-#ifdef NEWFTP
- if (what & W_FTP) { /* FTP */
- move(CW_NAM,10);
- printw(" FTP PUT:");
- } else
-#endif /* NEWFTP */
-#ifdef CK_RESEND
- switch (sendmode) { /* Kermit */
- case SM_RESEND:
- move(CW_NAM,10);
- printw(" RESENDING:");
- break;
- default:
- move(CW_NAM,10);
- printw(" SENDING:");
- break;
- }
-#else
- move(CW_NAM,10);
- printw(" SENDING:");
-#endif /* CK_RESEND */
-
- } else if (what & W_RECV) { /* If we're receiving... */
-#ifdef NEWFTP
- if (what & W_FTP) { /* FTP */
- move(CW_NAM,10);
- printw(" FTP GET:");
- } else {
-#endif /* NEWFTP */
- move(CW_NAM,10);
- printw(" RECEIVING:");
-#ifdef NEWFTP
- }
- } else if (what == (W_FTP|W_FT_DELE)) {
- move(CW_NAM,10);
- printw("FTP DELETE:");
-#endif /* NEWFTP */
- } else { /* If we don't know... */
- move(CW_NAM,10); /* (should never see this) */
- printw(" File Name:");
- }
- move(CW_NAM,22); /* Display the filename */
- if (len > 57) {
- printw("%.55s..",s);
- len = 57;
- } else printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- q = len; /* Remember name length for later */
- clrtoeol();
- scrft(); /* Display file type (can change) */
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_AN: /* File as-name */
- if (q + len + 4 < 58) { /* Will fit */
- move(CW_NAM, 22 + q);
- printw(" => %s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- } else { /* Too long */
- move(CW_NAM, 22); /* Overwrite previous name */
- q = 0;
- if (len + 4 > 57) { /* wg15 */
- printw(" => %.51s..",s); /* wg15 */
- len = 53; /* wg15 */
- } else printw(" => %s",s); /* wg15 */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- }
- q += len + 4; /* Remember horizontal position */
- clrtoeol();
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_FS: /* File size */
- fsiz = n;
- move(CW_SIZ,22);
- if (fsiz > (CK_OFF_T)-1) {
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) n );
-#endif /* K95G */
-#endif /* KUI */
- printw("%s",ckfstoa(n));
- }
- if (fsiz == -2L) {
- printw("POSSIBLY EXCEEDS LOCAL FILE SIZE LIMIT");
- }
- clrtoeol();
-#ifdef COMMENT
- move(CW_PCD, 8);
- if (fsiz > (CK_OFF_T)-1) { /* Put up percent label */
- pctlbl = 1;
- clrtoeol();
- printw("Percent Done:");
- }
-#else
- move(CW_PCD, 8);
- clrtoeol();
- if (fsiz > (CK_OFF_T)-1) { /* Put up percent label */
- pctlbl = 1;
- printw("Percent Done:");
- } else {
- pctlbl = 0;
- printw("Bytes So Far:");
- }
-#endif /* COMMENT */
- clrtoeol();
- scrft(); /* File type */
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_PT: /* Packet type or pseudotype */
- if (spackets < 5) {
- extern int sysindex;
- extern struct sysdata sysidlist[];
- /* Things that won't change after the 4th packet */
- move(CW_PAR,22);
- printw("%s",parnam((char)parity));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-#ifdef COMMENT
- move(CW_PB, 22); /* Block check on this packet */
- if (bctu == 4)
- printw("B");
- else
- printw("%d",bctu);
- clrtoeol();
-#endif /* COMMENT */
- if (
-#ifdef NEWFTP
- (ftp && (spackets == 1 || rpackets == 1)) ||
-#endif /* NEWFTP */
- spackets == 4
- ) {
- move(CW_LIN,8);
- if (
-#ifdef NEWFTP
- ftp ||
-#endif /* NEWFTP */
- ((protocol == PROTO_K) && (sysindex > -1))
- ) {
- if (net) {
- move(CW_LIN,8);
- printw("Network Host: %s (%s)",
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "") :
-#endif /* NEWFTP */
- ttname,
-#ifdef NEWFTP
- ftp ? ftp_srvtyp :
-#endif /* NEWFTP */
- sysidlist[sysindex].sid_name
- );
- } else {
- move(CW_LIN,0);
- printw("Communication Device: %s (remote host is %s)",
- ttname,
- sysidlist[sysindex].sid_name
- );
- }
- clrtoeol();
- }
- }
- }
-#ifdef CK_TIMERS
- if (/* rttflg && */ protocol == PROTO_K) {
- long xx;
- if (
-#ifdef STREAMING
- streaming && oldwin != -2
-#else
- 0
-#endif /* STREAMING */
- ) {
- move(CW_TMO, 22);
- printw("00 / 00");
- clrtoeol();
- } else {
- xx = (rttdelay + 500) / 1000;
- if (xx != oldrtt || rcvtimo != oldtim) {
- move(CW_TMO, 22);
- printw("%02ld / %02d", xx, rcvtimo);
- oldrtt = xx;
- oldtim = rcvtimo;
- clrtoeol();
- }
- }
- }
-#endif /* CK_TIMERS */
-
- x = (what & W_RECV) ? /* Packet length */
- rpktl+(protocol==PROTO_K?1:0) :
- spktl;
- if (x != oldlen) { /* But only if it changed. */
- move(CW_PL, 22);
- printw("%d",x);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PL, (long) x );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldlen = x;
- }
- move(CW_PC, 22); /* Packet count (always). */
-
- printw("%d", (what & W_RECV) ? rpackets : spackets);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PC, (long) spackets );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-
- if (protocol == PROTO_K && !ftp) { /* Window slots */
- char ws[16];
- int flag;
- flag = 0;
-#ifdef STREAMING
- if (streaming) {
- if (oldwin != -2) {
- sprintf(ws,"STREAMING");
- flag = 1;
- oldwin = -2;
- }
- } else
-#endif /* STREAMING */
- if (wcur != oldwin) {
- sprintf(ws, "%d of %d", wcur < 1 ? 1 : wcur, wslotn);
- flag = 1;
- oldwin = wcur;
- }
- if (flag) {
- move(CW_WS, 22);
- printw("%s", ws);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_WS, (long) ws );
-#endif /* K95G */
-#endif /* KUI */
- }
- }
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Retry count, if changed */
- move(CW_PR, 22);
- printw("%d",errors);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PR, (long) errors );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldtry = errors;
- }
- /* Sender's packet type */
- if (!ftp && (c != oldtyp && c != 'Y' && c != 'N')) {
- char type[2];
- sprintf(type, "%c",c);
- move(CW_PT,22);
- printw("%s", type);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PT, (long) type );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldtyp = c;
- }
- switch (c) { /* Now handle specific packet types */
- case 'S': /* Beginning of transfer */
- fcnt = fbyt = 0L; /* Clear counters */
-#ifdef GFTIMER
- gtv = -1.0;
-#else /* GFTIMER */
- gtv = -1L; /* And old/new things... */
-#endif /* GFTIMER */
- oldpct = pct = 0L;
- break;
-
- case 'Z': /* or EOF */
- debug(F101,"screenc SCR_PT Z pktnum","",n);
- debug(F101,"screenc SCR_PT Z oldpct","",oldpct);
- debug(F101,"screenc SCR_PT Z pct","",pct);
- case 'D': /* Data packet */
- if (fsiz > 0L) { /* Show percent done if known */
- oldpct = pct; /* Remember previous percent */
- howfar = ffc;
-#ifdef CK_RESEND
- if (what & W_SEND) /* Account for PSEND or RESEND */
- howfar += sendstart;
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- /* Percent done, to be displayed... */
- if (c == 'Z') {
- if (!discard && !cxseen && !czseen) pct = 100L;
- } else
- pct = (fsiz > 99L) ? (howfar / (fsiz / 100L)) : 0L;
- if (pct > 100L || /* Allow for expansion and */
- (oldpct == 99L && pct < 0L)) /* other boundary conditions */
- pct = 100L;
- if (pct != oldpct) /* Only do this 100 times per file */
- updpct(oldpct, pct);
- } else {
- move(CW_PCD,22);
- printw("%s", ckfstoa(ffc));
- }
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) howfar);
-#endif /* K95G */
-#endif /* KUI */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- break;
-
- case '%': /* Timeouts, retransmissions */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
-
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- move(CW_PR, 22);
- printw("%d",errors);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR, (long) errors
- );
-#endif /* K95G */
-#endif /* KUI */
- }
- oldtry = errors;
- if (s) if (*s) {
- move(CW_ERR,22);
- printw("%s",s);
- clrtoeol();
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_ERR, (long) s);
-#endif /* K95G */
-#endif /* KUI */
- }
- break;
-
- case 'E': /* Error packet */
-#ifdef COMMENT
- move(CW_ERR,22); /* Print its data field */
- if (*s) {
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- }
- clrtoeol();
-#endif /* COMMENT */
- fcnt = fbyt = 0L; /* So no bytes for this file */
- break;
- case 'Q': /* Crunched packet */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- move(CW_ERR,22);
- printw("Damaged Packet");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Damaged Packet"
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- break;
- case 'q': /* Ctrl-C or connection lost */
- move(CW_MSG,22);
- clrtoeol();
- if (!s) s = "";
- printw(*s ? s : "User interruption or connection lost");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) s
- );
-#endif /* K95G */
-#endif /* KUI */
- break;
- case 'T': /* Timeout */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- move(CW_ERR,22);
- printw("Timeout %d sec",rcvtimo);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Timeout"
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- move(CW_PR, 22);
- printw("%d",errors);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR, (long) errors
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- oldtry = errors;
- }
- break;
- default: /* Others, do nothing */
- break;
- }
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_ST: /* File transfer status */
- debug(F101,"screenc SCR_ST c","",c);
- debug(F101,"screenc SCR_ST success","",success);
- debug(F101,"screenc SCR_ST cxseen","",cxseen);
-#ifdef COMMENT
- move(CW_PCD,22); /* Update percent done */
- if (c == ST_OK) { /* OK, print 100 % */
- if (pctlbl)
- updpct(oldpct,100);
- else
- printw("%s", ckfstoa(ffc));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
-#endif /* K95G */
-#endif /* KUI */
- pct = 100;
- oldpct = 0;
- } else if (fsiz > 0L) /* Not OK, update final percent */
-/*
- The else part writes all over the screen -- howfar and/or fsiz have
- been reset as a consequence of the not-OKness of the transfer.
-*/
- if (pctlbl)
- updpct(oldpct, (howfar * 100L) / fsiz);
- clrtoeol();
-#else
- if (c == ST_OK) { /* OK, print 100 % */
- move(CW_PCD,22); /* Update percent done */
- if (pctlbl) {
- if (oldpct == 0) /* Switching from "bytes so far" */
- clrtoeol(); /* to "percent done"... */
- updpct(oldpct,100);
- } else
- printw("%s", ckfstoa(ffc));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = 100;
- oldpct = 0;
-#endif /* COMMENT */
- clrtoeol();
- }
-#endif /* COMMENT */
-
-#ifdef COMMENT
-/* No, leave it there so they can read it */
- move(CW_MSG,22); /* Remove any previous message */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_MSG, (long) "" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
-#endif /* COMMENT */
-
- move(CW_TR, 22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TR, (long) "" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
-
- switch (c) { /* Print new status message */
- case ST_OK: /* Transfer OK */
- fcnt++; /* Count this file */
- if (what == (W_FTP|W_FT_DELE)) {
- move(CW_MSG,22);
- clrtoeol();
- printw("Delete OK");
- } else {
- fbyt += ffc;
- move(CW_MSG,22);
- clrtoeol();
- printw("Transfer OK");
- }
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) "Transfer OK"
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
- return;
-
- case ST_DISC: /* Discarded */
- move(CW_ERR,22);
- printw("File discarded");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "File discarded"
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_INT: /* Interrupted */
- move(CW_ERR,22);
- printw("Transfer interrupted");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Transfer interrupted"
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_SKIP: /* Skipped */
- move(CW_ERR,22);
- if (n > 0 && n < nskreason)
- printw("File skipped (%s)",skreason[n]);
- else
- printw("File skipped");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "File skipped"
- );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_ERR: /* Error message */
- move(CW_ERR,22);
- if (!s) s = (char *)epktmsg;
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_REFU: /* Refused */
- move(CW_ERR,22);
- if (*s) {
- char errbuf[64] ;
- sprintf( errbuf, "Refused, %s", s ) ;
- printw("%s", errbuf);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long) CW_ERR,(long) errbuf);
-#endif /* K95G */
-#endif /* KUI */
- } else {
- printw("Refused");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Refused");
-#endif /* K95G */
-#endif /* KUI */
- }
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_INC:
- move(CW_ERR,22);
- printw("Incomplete");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Incomplete");
-#endif /* K95G */
-#endif /* KUI */
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh();
- return;
-
- case ST_MSG:
- move(CW_MSG,22);
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_MSG,(long)s);
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh();
- return;
-
- default: /* Bad call */
- move(CW_ERR,22);
- printw("*** screen() called with bad status ***");
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR,
- (long) "*** screen() called with bad status ***" );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh(); return;
- }
-
- case SCR_TC: { /* Transaction complete */
- char msgbuf[128];
- move(CW_CP,22); /* Overall transfer rate */
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, tfcps);
-#endif /* K95G */
-#endif /* KUI */
- printw("%s", ckfstoa(tfcps));
- clrtoeol();
- if (success) {
- move(CW_MSG,22); /* Print statistics in message line */
- clrtoeol();
- }
- if (success) {
- sprintf(msgbuf,
- "SUCCESS. Files: %ld, Bytes: %s, %ld CPS",
- filcnt - filrej,
- ckfstoa(fbyt),
- tfcps
- );
- printw("%s", msgbuf);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) msgbuf
- );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
-
- }
- move(CW_TR, 1);
- printw(" Elapsed Time: %s",hhmmss((long)
-#ifdef GFTIMER
- (fptsecs + 0.5)
-#else
- tsecs
-#endif /* GFTIMER */
- ));
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_TR,
- (long) hhmmss((long)
-#ifdef GFTIMER
- (fptsecs + 0.5)
-#else
- tsecs
-#endif /* GFTIMER */
- ));
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- move(23,0); clrtoeol(); /* Clear instructions lines */
- move(22,0); clrtoeol(); /* to make room for prompt. */
- refresh();
-
-#ifdef GFTIMER
- oldgtv = (CKFLOAT) -1.0;
-#else
- oldgtv = -1L;
-#endif /* GFTIMER */
-
-#ifndef VMSCURSE
- debug(F100,"screenc endwin A","",0);
- endwin();
-#ifdef COMMENT
-/*
- Why and when was this call to conres() added? It makes no sense,
- and it breaks echoing on Solaris 8.
-*/
-#ifdef SOLARIS
- conres();
-#endif /* SOLARIS */
-#endif /* COMMENT */
-#endif /* VMSCURSE */
-
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
- cendw = 1;
- if (xfrbel) bleep(BP_NOTE); /* Close window, then beep. */
-#ifdef UNIX
- fflush(stdout);
-#endif /* UNIX */
- ft_win = 0; /* Window closed. */
- return;
- }
- case SCR_EM: /* Error packet (fatal) */
- move (CW_ERR,22);
- printw("FAILURE: %s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- if (xfrbel) bleep(BP_FAIL);
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- clrtoeol(); refresh(); return;
-
- case SCR_QE: /* Quantity equals */
- case SCR_TU: /* Undelimited text */
- case SCR_TN: /* Text delimited at start */
- case SCR_TZ: /* Text delimited at end */
- return; /* (ignored in fullscreen display) */
-
- case SCR_MS: /* Message from Kermit partner */
- move(CW_MSG,22);
- printw("%s",s);
- clrtoeol(); refresh(); return;
-
- case SCR_XD: /* X-packet data */
- pct = oldpct = 0;
- move(CW_NAM,22);
- printw("%s",s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol(); refresh(); return;
-
- case SCR_CW: /* Close Window */
- clrtoeol(); move(23,0); clrtoeol(); move(22,0); clrtoeol();
- refresh();
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
-
-#ifndef VMSCURSE
- debug(F100,"screenc endwin B","",0);
- endwin();
-#endif /* VMSCURSE */
- ft_win = 0; /* Flag that window is closed. */
- cendw = 1; return;
-
- case SCR_CD: /* Display current directory */
- move(CW_DIR,22);
- printw("%s", s);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) s );
-#endif /* K95G */
-#endif /* KUI */
- clrtoeol();
- refresh();
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- default: /* Bad call */
- move (CW_ERR,22);
-#ifdef KUI
-#ifndef K95G
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "*** screen() called with bad function code ***"
- );
-#endif /* K95G */
-#endif /* KUI */
- printw("*** screen() called with bad function code ***");
- clrtoeol(); refresh(); return;
- }
-}
-#endif /* CK_CURSES */
-
-#ifdef KUI
-#ifdef CK_ANSIC
-void
-screeng(int f, char c,long n,char *s)
-#else
-CKVOID
-screeng(f,c,n,s)
-int f; /* argument descriptor */
-char c; /* a character or small integer */
-long n; /* a long integer */
-char *s; /* a string */
-#endif /* CK_ANSIC */
-/* screeng() */ {
-#ifdef CK_SSL
- extern int tls_active_flag, ssl_active_flag;
-#endif /* CK_SSL */
-#ifdef RLOGCODE
- extern int ttnproto;
-#endif /* RLOGCODE */
- static int q = 0;
- static CK_OFF_T fsiz = (CK_OFF_T)-1; /* Copy of file size */
- static long fcnt = 0L; /* Number of files transferred */
- static long fbyt = 0L; /* Total file bytes of all files transferred */
- static CK_OFF_T howfar = (CK_OFF_T)0; /* How much of file xfer'd so far */
- static int pctlbl = 0L; /* Percent done vs Bytes so far */
- long cps = 0L;
-
- int net = 0;
- int xnet = 0;
- int ftp = 0;
- int len; /* Length of string */
- int errors = 0; /* Error counter */
- int x; /* Worker */
-
- debug(F101,"screeng cinit","",cinit);
- debug(F101,"screeng cendw","",cendw);
-
- if (!s) s = ""; /* Always do this. */
-
- ftp = (what & W_FTP) ? 1 : 0; /* FTP or Kermit */
- net = network || ftp;
- xnet = ftp ? 1 : nettype; /* NET_TCPB == 1 */
-
- if (cinit == 0 || cendw > 0) { /* Handle borderline cases... */
- if (f == SCR_CW) { /* Close window, but it's not open */
- ft_win = 0;
- return;
- }
- debug(F111,"screeng A",s,f);
- if (f == SCR_EM ||
- (f == SCR_PT && c == 'E')) { /* Fatal error before window open */
- conoll(""); conoc('?'); conoll(s); return; /* Regular display */
- }
- }
- if (cinit == 0) { /* Only call initscr() once */
- /* Check these now -- if they are defined but not numeric */
- /* they can crash curses */
- cendw = 1; /* New window needs repainting */
- debug(F100,"screeng calling initscr","",0);
- initscr(); /* Initialize curses. */
- debug(F100,"screeng initscr ok","",0);
- cinit++; /* Remember curses was initialized. */
- }
- ft_win = 1; /* Window is open */
- if (repaint) {
-#ifdef CK_WREFRESH
-/*
- This totally repaints the screen, just what we want, but we can only
- do this with real curses, and then only if clearok() and wrefresh() are
- provided in the curses library.
-*/
- RestoreCmdMode();
-#else /* No CK_WREFRESH */
-/*
- Kermit's do-it-yourself method, works with all types of fullscreen
- support, but does not repaint all the fields. For example, the filename
- is lost, because it arrives at a certain time and never comes again, and
- Kermit presently does not save it anywhere. Making this method work for
- all fields would be a rather major recoding task, duplicating what curses
- already does, and would add a lot of complexity and storage space.
-*/
- cendw = 1;
-#endif /* CK_WREFRESH */
- repaint = 0;
- }
- if (cendw) { /* endwin() was called previously */
- debug(F100,"screeng setup ok","",0);
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) zgtdir() );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_LIN,
- (long) (
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "(unknown)") :
-#endif /* NEWFTP */
- ttname) );
-
- if (net) {
-#ifdef NETCONN
- int secure = 0;
- char * xname;
- if (xnet > nnetname)
- xname = "[ERROR]";
- else
- xname = netname[xnet];
-#ifdef NEWFTP
- if (ftp) {
- if (ftpissecure())
- secure = 1;
- } else
-#endif /* NEWFTP */
- if (0
-#ifdef SSHBUILTIN
- || IS_SSH()
-#endif /* SSHBUILTIN */
-#ifdef CK_ENCRYPTION
- || ck_tn_encrypting() && ck_tn_decrypting()
-#endif /* CK_ENCRYPTION */
-#ifdef CK_SSL
- || tls_active_flag || ssl_active_flag
-#endif /* CK_SSL */
-#ifdef RLOGCODE
-#ifdef CK_KERBEROS
-#ifdef CK_ENCRYPTION
- || ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN
-#endif /* CK_ENCRYPTION */
-#endif /* CK_KERBEROS */
-#endif /* RLOGCODE */
- ) {
- secure = 1;
- }
- if (secure) {
- char buf[30];
- sprintf(buf,"%s (SECURE)",xname);
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) buf
- );
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) xname
- );
- }
-#else
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(network)"
- );
-#endif /* NETCONN */
- } else {
- if (speed < 0L)
- speed = ttgspd();
- if (speed > 0L) {
- if (speed == 8880) {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "75/1200"
- );
- } else {
- char speedbuf[64] ;
- sprintf(speedbuf, "%ld", speed);
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) speedbuf
- );
- }
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_SPD,
- (long) "(unknown)"
- );
- }
- }
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
- pctlbl = (what & W_SEND);
- cendw = 0;
- }
- debug(F101,"SCREENC switch","",f);
- debug(F000,"SCREENC c","",c);
- debug(F101,"SCREENC n","",n);
-
- len = strlen(s); /* Length of argument string */
- switch (f) { /* Handle our function code */
- case SCR_FN: /* Filename */
- oldpct = pct = 0L; /* Reset percents */
-#ifdef GFTIMER
- gtv = (CKFLOAT) -1.0;
- /* oldgtv = (CKFLOAT) -1.0; */
-#else
- gtv = -1L;
- /* oldgtv = -1L; */
-#endif /* GFTIMER */
- oldwin = -1;
- fsiz = (CK_OFF_T)-1L; /* Invalidate previous file size */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PCD, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_FFC, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) 0 );
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) "" );
-
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
- q = len; /* Remember name length for later */
- scrft(); /* Display file type (can change) */
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_AN: /* File as-name */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_FS: /* File size */
- fsiz = n;
- if (fsiz > (CK_OFF_T)-1) {
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_SIZ, (long) n );
- }
- if (fsiz > (CK_OFF_T)-1) { /* Put up percent label */
- pctlbl = 1;
- } else {
- pctlbl = 0;
- }
- scrft(); /* File type */
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_PT: /* Packet type or pseudotype */
- if (spackets < 5) {
- extern int sysindex;
- extern struct sysdata sysidlist[];
- /* Things that won't change after the 4th packet */
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_PAR,
- (long) parnam((char)parity)
- );
- if (
-#ifdef NEWFTP
- (ftp && (spackets == 1 || rpackets == 1)) ||
-#endif /* NEWFTP */
- spackets == 4
- ) {
- if (
-#ifdef NEWFTP
- ftp ||
-#endif /* NEWFTP */
- ((protocol == PROTO_K) && (sysindex > -1))
- ) {
- char msgbuf[128];
- if (net) {
- sprintf(msgbuf,"Network Host: %s (%s)",
-#ifdef NEWFTP
- ftp ? (ftp_host ? ftp_host : "") :
-#endif /* NEWFTP */
- ttname,
-#ifdef NEWFTP
- ftp ? ftp_srvtyp :
-#endif /* NEWFTP */
- sysidlist[sysindex].sid_name
- );
- } else {
- sprintf(msgbuf,
- "Communication Device: %s (remote host is %s)",
- ttname,
- sysidlist[sysindex].sid_name
- );
- }
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_LIN,
- (long) msgbuf
- );
- }
- }
- }
-#ifdef CK_TIMERS
- if (/* rttflg && */ protocol == PROTO_K) {
- long xx;
- if (
-#ifdef STREAMING
- streaming && oldwin != -2
-#else
- 0
-#endif /* STREAMING */
- ) {
- char msgbuf[64];
- sprintf(msgbuf,"00 / 00");
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_TMO,
- (long) msgbuf
- );
- } else {
- xx = (rttdelay + 500) / 1000;
- if (xx != oldrtt || rcvtimo != oldtim) {
- char msgbuf[64];
- sprintf(msgbuf,"%02ld / %02d", xx, rcvtimo);
- KuiSetProperty( KUI_FILE_TRANSFER,
- (long) CW_TMO,
- (long) msgbuf
- );
- oldrtt = xx;
- oldtim = rcvtimo;
- clrtoeol();
- }
- }
- }
-#endif /* CK_TIMERS */
-
- x = (what & W_RECV) ? /* Packet length */
- rpktl+(protocol==PROTO_K?1:0) :
- spktl;
- if (x != oldlen) { /* But only if it changed. */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PL, (long) x );
- oldlen = x;
- }
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PC, (long) spackets );
-
- if (protocol == PROTO_K && !ftp) { /* Window slots */
- char ws[16];
- int flag;
- flag = 0;
-#ifdef STREAMING
- if (streaming) {
- if (oldwin != -2) {
- sprintf(ws,"STREAMING");
- flag = 1;
- oldwin = -2;
- }
- } else
-#endif /* STREAMING */
- if (wcur != oldwin) {
- sprintf(ws, "%d of %d", wcur < 1 ? 1 : wcur, wslotn);
- flag = 1;
- oldwin = wcur;
- }
- if (flag) {
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_WS, (long) ws );
- }
- }
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Retry count, if changed */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PR, (long) errors );
- oldtry = errors;
- }
- /* Sender's packet type */
- if (!ftp && (c != oldtyp && c != 'Y' && c != 'N')) {
- char type[2];
- sprintf(type, "%c",c);
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_PT, (long) type );
- oldtyp = c;
- }
- switch (c) { /* Now handle specific packet types */
- case 'S': /* Beginning of transfer */
- fcnt = fbyt = 0L; /* Clear counters */
-#ifdef GFTIMER
- gtv = -1.0;
-#else /* GFTIMER */
- gtv = -1L; /* And old/new things... */
-#endif /* GFTIMER */
- oldpct = pct = 0L;
- break;
-
- case 'Z': /* or EOF */
- debug(F101,"screeng SCR_PT Z pktnum","",n);
- debug(F101,"screeng SCR_PT Z oldpct","",oldpct);
- debug(F101,"screeng SCR_PT Z pct","",pct);
- case 'D': /* Data packet */
- if (fsiz > 0L) { /* Show percent done if known */
- oldpct = pct; /* Remember previous percent */
- howfar = ffc;
-#ifdef CK_RESEND
- if (what & W_SEND) /* Account for PSEND or RESEND */
- howfar += sendstart;
- else if (what & W_RECV)
- howfar += rs_len;
-#endif /* CK_RESEND */
- /* Percent done, to be displayed... */
- if (c == 'Z') {
- if (!discard && !cxseen && !czseen) pct = 100L;
- } else
- pct = (fsiz > 99L) ? (howfar / (fsiz / 100L)) : 0L;
- if (pct > 100L || /* Allow for expansion and */
- (oldpct == 99L && pct < 0L)) /* other boundary conditions */
- pct = 100L;
- if (pct != oldpct) /* Only do this 100 times per file */
- updpct(oldpct, pct);
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
- }
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) howfar);
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- break;
-
- case '%': /* Timeouts, retransmissions */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
-
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR,
- (long) errors
- );
- }
- oldtry = errors;
- if (s) if (*s) {
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_ERR, (long) s);
- }
- break;
-
- case 'E': /* Error packet */
- if (*s) {
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
- }
- fcnt = fbyt = 0L; /* So no bytes for this file */
- break;
- case 'Q': /* Crunched packet */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Damaged Packet"
- );
- break;
- case 'q': /* Ctrl-C or connection lost */
- if (!s) s = "";
- if (!*s) s = "User interruption or connection lost";
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) s
- );
- break;
- case 'T': /* Timeout */
- cps = shocps((int) pct, fsiz, howfar);
- /* old_tr = shoetl(old_tr, cps, fsiz, howfar); */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Timeout"
- );
- errors = retrans + crunched + timeouts;
- if (errors != oldtry) { /* Error count, if changed */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_PR, (long) errors
- );
- oldtry = errors;
- }
- break;
- default: /* Others, do nothing */
- break;
- }
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- case SCR_ST: /* File transfer status */
- debug(F101,"screeng SCR_ST c","",c);
- debug(F101,"screeng SCR_ST success","",success);
- debug(F101,"screeng SCR_ST cxseen","",cxseen);
-#ifdef COMMENT
- if (c == ST_OK) { /* OK, print 100 % */
- if (pctlbl)
- updpct(oldpct,100);
- else
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
- pct = 100;
- oldpct = 0;
- } else if (fsiz > 0L) /* Not OK, update final percent */
-/*
- The else part writes all over the screen -- howfar and/or fsiz have
- been reset as a consequence of the not-OKness of the transfer.
-*/
- if (pctlbl)
- updpct(oldpct, (howfar * 100L) / fsiz);
-#else
- if (c == ST_OK) { /* OK, print 100 % */
- if (pctlbl) {
- updpct(oldpct,100);
- } else
- KuiSetProperty(KUI_FILE_TRANSFER, (long) CW_FFC, (long) ffc);
-#ifdef COMMENT
- pct = 100;
- oldpct = 0;
-#endif /* COMMENT */
- }
-#endif /* COMMENT */
-
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_TR, (long) "" );
-
- switch (c) { /* Print new status message */
- case ST_OK: /* Transfer OK */
- fcnt++; /* Count this file */
- if (what == (W_FTP|W_FT_DELE)) {
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) "Delete OK"
- );
- } else {
- fbyt += ffc;
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) "Transfer OK"
- );
- }
- return;
-
- case ST_DISC: /* Discarded */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "File discarded"
- );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_INT: /* Interrupted */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "Transfer interrupted"
- );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_SKIP: { /* Skipped */
- char errbuf[64] ;
- if (n > 0 && n < nskreason)
- sprintf( errbuf, "File skipped, (%s)", skreason[n] ) ;
- else
- sprintf( errbuf, "File skipped" ) ;
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) errbuf
- );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
- }
- case ST_ERR: /* Error message */
- if (!s) s = (char *)epktmsg;
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_REFU: /* Refused */
- if (*s) {
- char errbuf[64] ;
- sprintf( errbuf, "Refused, %s", s ) ;
- KuiSetProperty(KUI_FILE_TRANSFER,(long) CW_ERR,(long) errbuf);
- } else {
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Refused");
- }
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_INC:
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_ERR,(long)"Incomplete");
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case ST_MSG:
- KuiSetProperty(KUI_FILE_TRANSFER,(long)CW_MSG,(long)s);
- return;
-
- default: /* Bad call */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR,
- (long) "*** screen() called with bad status ***" );
- return;
- }
-
- case SCR_TC: { /* Transaction complete */
- char msgbuf[128];
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_CP, tfcps);
- if (success) {
- sprintf(msgbuf,
- "SUCCESS. Files: %s, Bytes: %ld, %ld CPS",
- filcnt - filrej,
- ckfstoa(fbyt),
- tfcps
- );
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_MSG,
- (long) msgbuf
- );
- }
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_TR,
- (long) hhmmss((long)
-#ifdef GFTIMER
- (fptsecs + 0.5)
-#else
- tsecs
-#endif /* GFTIMER */
- ));
-
-#ifdef GFTIMER
- oldgtv = (CKFLOAT) -1.0;
-#else
- oldgtv = -1L;
-#endif /* GFTIMER */
-
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
- cendw = 1;
- if (xfrbel) bleep(BP_NOTE); /* Close window, then beep. */
- ft_win = 0; /* Window closed. */
- return;
- }
- case SCR_EM: /* Error packet (fatal) */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_ERR, (long) s );
- if (xfrbel) bleep(BP_FAIL);
-#ifdef COMMENT
- pct = oldpct = 0;
-#endif /* COMMENT */
- return;
-
- case SCR_QE: /* Quantity equals */
- case SCR_TU: /* Undelimited text */
- case SCR_TN: /* Text delimited at start */
- case SCR_TZ: /* Text delimited at end */
- return; /* (ignored in fullscreen display) */
-
- case SCR_XD: /* X-packet data */
- pct = oldpct = 0;
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_NAM, (long) s );
- return;
-
- case SCR_CW: /* Close Window */
-#ifdef COMMENT
- pct = 100; oldpct = 0; /* Reset these for next time. */
-#endif /* COMMENT */
- oldtyp = 0; oldrtt = -1L; oldtry = -1; oldlen = -1;
- oldtim = -1;
-
- ft_win = 0; /* Flag that window is closed. */
- cendw = 1; return;
-
- case SCR_CD: /* Display current directory */
- KuiSetProperty( KUI_FILE_TRANSFER, (long) CW_DIR, (long) s );
-#ifdef OS2
- SaveCmdMode(0, 0);
-#endif /* OS2 */
- return;
-
- default: /* Bad call */
- KuiSetProperty(KUI_FILE_TRANSFER,
- (long) CW_ERR,
- (long) "*** screen() called with bad function code ***"
- );
- return;
- }
-}
-#endif /* KUI */
-#endif /* MAC */
-
-#endif /* NOXFER */
-
-#ifndef CK_CURPOS
-/* Dummies for when cursor control is not supported */
-int
-ck_curpos(row, col) {
- return(-1);
-}
-
-int
-ck_cls() {
- return(-1);
-}
-
-int
-ck_cleol() {
- return(-1);
-}
-#endif /* CK_CURPOS */
-
-#ifndef NOIKSD
-#ifdef IKSDB
-
-struct iksdbfld dbfld[] = {
- /* Offset Length Type */
- { DB_FLAGS, dB_FLAGS, DBT_HEX }, /* 0 db_FLAGS Flags */
- { DB_ATYPE, dB_ATYPE, DBT_HEX }, /* 1 db_ATYPE Auth type */
- { DB_AMODE, dB_AMODE, DBT_HEX }, /* 3 db_AMODE Auth mode */
- { DB_STATE, dB_STATE, DBT_HEX }, /* 2 db_STATE State */
- { DB_MYPID, dB_MYPID, DBT_HEX }, /* 5 db_MYPID PID */
- { DB_SADDR, dB_SADDR, DBT_HEX }, /* 4 db_SADDR Server address */
- { DB_CADDR, dB_CADDR, DBT_HEX }, /* 6 db_CADDR Client address */
- { DB_START, dB_START, DBT_DAT }, /* 7 db_START Session start */
- { DB_LASTU, dB_LASTU, DBT_DAT }, /* 8 db_LASTU Last update */
- { DB_ULEN, dB_ULEN, DBT_HEX }, /* 9 db_ULEN Username length */
- { DB_DLEN, dB_DLEN, DBT_HEX }, /* 10 db_DLEN Directory name length */
- { DB_ILEN, dB_ILEN, DBT_HEX }, /* 11 db_ILEN Info length */
- { DB_PAD1, dB_PAD1, DBT_UND }, /* 12 db_PAD1 (Reserved) */
- { DB_USER, dB_USER, DBT_STR }, /* 13 db_USER Username */
- { DB_DIR, dB_DIR, DBT_STR }, /* 14 db_DIR Current Directory */
- { DB_INFO, dB_INFO, DBT_STR } /* 15 db_INFO State-specific info */
-};
-
-static char lcknam[CKMAXPATH+1]; /* Lockfile pathname */
-static char tmplck[CKMAXPATH+1]; /* Temporary lockfile name */
-
-static char * updmode = /* Update mode for fopen() */
-#ifdef OS2
- "r+b"
-#else
-#ifdef VMS
- "r+b"
-#else
- "r+"
-#endif /* VMS */
-#endif /* OS2 */
- ;
-
-/* D B I N I T -- Initialize the IKSD database... */
-
-int
-dbinit() {
- extern int dbinited;
- int x = 0;
- debug(F110,"dbinit dbdir 1",dbdir,0);
- debug(F110,"dbinit dbfile 1",dbfile,0);
- if (dbinited)
- return(0);
-#ifdef OS2
- if (!dbdir) {
-#ifdef NT
- char * p = NULL;
- if (!isWin95()) {
- p = getenv("SystemRoot");
- } else {
- p = getenv("winbootdir");
- if (!p) p = getenv("windir");
- }
- if (!p) p = "C:/";
- dbdir = malloc(strlen(p)+2);
- strcpy(dbdir,p); /* safe */
- p = dbdir;
- while (*p) {
- if (*p == '\\')
- *p = '/';
- p++;
- }
- if (*(p-1) != '/' ) {
- *p++ = '/';
- *p = '\0';
- }
-#else /* NT */
- makestr(&dbdir,"C:/");
-#endif /* NT */
- }
-#else /* OS2 */
- if (!dbdir)
- makestr(&dbdir,IK_DBASEDIR);
-#endif /* OS2 */
-
- if (!dbfile) {
- char * s = "";
- x = strlen(dbdir);
- if (dbdir[x-1] != '/') {
- s = "/";
- x++;
- }
- x += (int)strlen(IK_DBASEFIL);
- dbfile = (char *)malloc(x+1);
- sprintf(dbfile,"%s%s%s",dbdir,s,IK_DBASEFIL);
- }
- debug(F110,"dbinit dbdir 2",dbdir,0);
- debug(F110,"dbinit dbfile 2",dbfile,0);
- mypid = getpid(); /* Get my pid */
- debug(F101,"dbinit mypid","",mypid);
-
- if (!myhexip[0]) { /* Set my hex IP address */
-#ifdef TCPSOCKET
- extern unsigned long myxipaddr;
- if (getlocalipaddr() > -1) {
- myip = myxipaddr;
- sprintf(myhexip,"%08lx",myip); /* (Needs fixing for IPv6) */
- } else
-#endif /* TCPSOCKET */
- ckstrncpy(myhexip,"00000000",9);
- }
- debug(F111,"dbinit myip",myhexip,myip);
- if (!peerhexip[0]) { /* Get peer's hex IP address */
-#ifdef TCPSOCKET
- extern unsigned long peerxipaddr;
- if (ckgetpeer()) {
- peerip = peerxipaddr;
- sprintf(peerhexip,"%08lx",peerip); /* (Needs fixing for IPv6) */
- debug(F111,"dbinit peerip",peerhexip,peerip);
- } else {
- debug(F101,"dbinit ckgetpeer failure","",errno);
- ckstrncpy(peerhexip,"00000000",9);
- }
-#else
- ckstrncpy(peerhexip,"00000000",9);
-#endif /* TCPSOCKET */
- }
- debug(F111,"dbinit peerip",peerhexip,peerip);
- debug(F101,"dbinit dbenabled","",dbenabled);
- if (dbenabled && inserver) {
- mydbslot = getslot();
- debug(F111,"dbinit getslot",ckitoa(ikdbopen),x);
- if (ikdbopen) dbinited = 1;
- }
- return(0);
-}
-
-/* U P D S L O T -- Update slot n */
-
-/*
- Opens the database if necessary, seeks to slot n, writes current record
- and adds current time to last-update field. n is the record sequence number
- (0, 1, 2, ...), not the seek pointer. Returns -1 on failure, 0 on success.
-*/
-int
-updslot(n) int n; { /* Update our slot */
- int rc = 0;
- CK_OFF_T position;
-
- debug(F111,"updslot","ikdbopen",ikdbopen);
- if (!ikdbopen) /* Not if not ok */
- return(0);
- if (!dbfp) { /* Open database if not open */
- dbfp = fopen(dbfile,updmode); /* In update no-truncate mode */
- if (!dbfp) {
- debug(F110,"updslot fopen failed",dbfile,0);
- ikdbopen = 0;
- return(-1);
- }
- }
- /* debug(F111,"updslot dbfile",dbfile,dbfp); */
- position = n * DB_RECL;
- if (CKFSEEK(dbfp,position,0) < 0) { /* Seek to desired slot */
- debug(F111,"updslot fseek failed",dbfile,mydbseek);
- ikdbopen = 0;
- rc = -1;
- } else {
- /* Update the update time */
- strncpy(&dbrec[dbfld[db_LASTU].off],
- ckdate(),
- dbfld[db_LASTU].len
- );
- if (fwrite(dbrec,1,DB_RECL,dbfp) < DB_RECL) { /* Write the record */
- debug(F110,"updslot fwrite failed",dbfile,0);
- ikdbopen = 0;
- rc = -1;
- } else { /* Flush the write */
- fflush(dbfp);
- }
- }
- return(rc);
-}
-
-/* I N I T S L O T -- Initialize slot n with my info */
-
-int
-initslot(n) int n; { /* Initialize slot */
- int k;
-#ifdef TCPSOCKET
- extern unsigned long peerxipaddr;
-#endif /* TCPSOCKET */
-
- debug(F101,"initslot","",n);
-
-#ifdef USE_MEMCPY
- memset(dbrec,32,DB_RECL);
-#else
- for (k = 0; k < DB_RECL; k++)
- dbrec[k] = '\040';
-#endif /* USE_MEMCPY */
-
- myflags = DBF_INUSE; /* Set in-use flag */
- mystate = W_NOTHING;
- myatype = 0L;
- myamode = 0L;
-
- k = dbfld[db_FLAGS].len; /* Length of flags field */
- strncpy(&dbrec[dbfld[db_FLAGS].off],ulongtohex(myflags,k),k);
-
- k = dbfld[db_ATYPE].len;
- strncpy(&dbrec[dbfld[db_ATYPE].off],ulongtohex(myatype,k),k);
-
- k = dbfld[db_AMODE].len;
- strncpy(&dbrec[dbfld[db_AMODE].off],ulongtohex(myamode,k),k);
-
- k = dbfld[db_STATE].len;
- strncpy(&dbrec[dbfld[db_STATE].off],ulongtohex(mystate,k),k);
-
- k = dbfld[db_SADDR].len;
- strncpy(&dbrec[dbfld[db_SADDR].off],ulongtohex(myip,k),k);
-
-#ifdef TCPSOCKET
- ckgetpeer();
- k = dbfld[db_CADDR].len;
- strncpy(&dbrec[dbfld[db_CADDR].off],ulongtohex(peerxipaddr,k),k);
-#else
- k = dbfld[db_CADDR].len;
- strncpy(&dbrec[dbfld[db_CADDR].off],ulongtohex(0L,k),k);
-#endif /* TCPSOCKET */
-
- k = dbfld[db_MYPID].len;
- strncpy(&dbrec[dbfld[db_MYPID].off],ulongtohex(mypid,k),k);
-
- k = dbfld[db_START].len;
- strncpy(&dbrec[dbfld[db_START].off],ckdate(),k);
-
- k = dbfld[db_ULEN].len;
- strncpy(&dbrec[dbfld[db_ULEN].off],"0000",4);
-
- k = dbfld[db_DLEN].len;
- strncpy(&dbrec[dbfld[db_DLEN].off],"0000",4);
-
- k = dbfld[db_ILEN].len;
- strncpy(&dbrec[dbfld[db_ILEN].off],"0000",4);
-
- strncpy(&dbrec[dbfld[db_INFO].off],"INIT",4);
- return(updslot(n));
-}
-
-int
-slotstate(x,s1,s2,s3) int x; char *s1, *s2, *s3; {
- int k, l1, l2, l3, z;
- mystate = x;
- debug(F101,"slotstate ikdbopen","",ikdbopen);
- if (!ikdbopen)
- return(-1);
- if (!s1) s1 = "";
- l1 = strlen(s1);
- if (!s2) s2 = "";
- l2 = strlen(s2);
- if (!s3) s3 = "";
- l3 = strlen(s3);
- strncpy(&dbrec[DB_STATE],ulongtohex(mystate,4),4);
- k = dbfld[db_ILEN].len;
- z = l1 + l2 + l3 + 2;
- if (z > dB_INFO)
- z = dB_INFO;
- strncpy(&dbrec[DB_ILEN],ulongtohex((unsigned long)z,k),k);
- k = dbfld[db_INFO].len;
- z = dbfld[db_INFO].off;
- if (l1 <= k) {
- lset(&dbrec[z],s1,l1+1,32);
- z += l1+1;
- k -= l1+1;
- if (l2 <= k) {
- lset(&dbrec[z],s2,l2+1,32);
- z += l2+1;
- k -= l2+1;
- if (l3 <= k)
- lset(&dbrec[z],s3,k,32);
- }
- }
-#ifdef DEBUG
- if (deblog) {
- char buf[128];
- int i;
- strncpy(buf,&dbrec[DB_INFO],127);
- buf[127] = NUL;
- for (i = 126; i > 0 && buf[i] == 32; i--) buf[i] = 0;
- debug(F111,"slotstate",buf,mystate);
- }
-#endif /* DEBUG */
- z = updslot(mydbslot);
- debug(F101,"slotstate updslot","",z);
- return(z);
-}
-
-int
-slotdir(s1,s2) char * s1, * s2; { /* Update current directory */
- int k, len1, len2;
- if (!ikdbopen)
- return(-1);
- if (!s1) s1 = "";
- if (!s2) s2 = "";
- len1 = strlen(s1);
- len2 = strlen(s2);
- k = dbfld[db_DLEN].len;
- strncpy(&dbrec[DB_DLEN],ulongtohex((unsigned long)(len1+len2),k),k);
- k = dbfld[db_DIR].len;
- if (len1 > 0) {
- lset(&dbrec[dbfld[db_DIR].off],s1,len1,32);
- lset(&dbrec[dbfld[db_DIR].off+len1],s2,k-len1,32);
- } else {
- lset(&dbrec[dbfld[db_DIR].off],s2,k,32);
- }
- return(updslot(mydbslot));
-}
-
-/* F R E E S L O T -- Free slot n */
-
-int
-freeslot(n) int n; {
- int k;
- if (!ikdbopen)
- return(0);
- dbflags = 0L;
- if (n == mydbslot) {
- dbflags = myflags & ~DBF_INUSE;
- dbflags &= ~DBF_LOGGED;
- }
- k = dbfld[db_FLAGS].len;
- strncpy(&dbrec[dbfld[db_FLAGS].off],ulongtohex(dbflags,k),k);
- return(updslot(n));
-}
-
-/* G E T S L O T -- Find a free database slot; returns slot number */
-
-#ifdef UNIX
-#include <fcntl.h> /* For creat() */
-#endif /* UNIX */
-
-int
-getslot() { /* Find a free slot for us */
- FILE * rfp = NULL; /* Returns slot number (0, 1, ...) */
- char idstring[64]; /* PID string buffer (decimal) */
- char pidbuf[64], * s;
- int j, k, n, x, rc = -1;
- int lockfd, tries, haveslot = 0;
- long lockpid;
- CK_OFF_T i;
- /* char ipbuf[17]; */
-
- if (!myhexip[0]) /* Set my hex IP address if not set */
- ckstrncpy((char *)myhexip,"7F000001",33);
- sprintf(idstring,"%08lx:%010ld\n",myip,mypid);
- debug(F110,"getslot idstring", idstring, 0);
-
- /* Make temporary lockfile name IP.PID (hex.hex) */
- /* This should fit in 14 chars -- huge PIDs are usually not possible */
- /* on 14-char filename systems. */
-
- sprintf(tmplck,"%s%08lx.%lx",dbdir,myip,mypid);
- debug(F110,"getslot tempfile",tmplck,0);
-
- /* Make a temporary file */
-
- lockfd = creat(tmplck, 0600); /* BUT THIS ISN'T PORTABLE */
- if (lockfd < 0) {
- debug(F111,"getslock temp lockfile create failure", tmplck, errno);
- return(-1);
- }
- /* Write my (decimal) PID into the temp file */
-
- write(lockfd,idstring,(int)strlen(idstring));
- if (close(lockfd) < 0) { /* Close lockfile */
- debug(F101,"getslot error closing temp lockfile", "", errno);
- return(-1);
- }
- sprintf(lcknam,"%s%s",dbdir,IK_LOCKFILE); /* Build lockfile name */
- debug(F110,"getslot lockfile",lcknam,0);
-
- rfp = fopen(lcknam,"r"); /* See if lockfile exists */
- if (rfp) { /* If so... */
- rset(pidbuf,"",64,0);
- x = fread(pidbuf,1,63,rfp); /* Read ID string from it */
- fclose(rfp); /* and close it quickly */
- debug(F110,"getslot lock exists",pidbuf,0);
- if (x > 0) { /* If we have a PID, check it */
- char * s = pidbuf;
- while (*s) {
- if (islower(*s)) *s = toupper(*s);
- if (*s == ':') {
- *s = NUL;
- debug(F110,"getslot lock IP",pidbuf,0);
- debug(F110,"gteslot my IP",myhexip,0);
- if (!strcmp(pidbuf,myhexip)) { /* Same IP address? */
- lockpid = atol(s+1); /* Yes, now get PID */
- debug(F101,"getslot lockpid","",lockpid);
-
- /* Check if PID lockpid on this computer is alive */
- x = zchkpid(lockpid);
- if (!x) {
- debug(F100,"getslot PID stale,removing lock","",0);
- unlink(lcknam);
- }
- break;
- }
- }
- s++;
- }
- } else {
- debug(F111,"getslot lockfile open failure",lcknam,errno);
- }
- }
- /* Try IK_LCKTRIES (16) times to rename temp file to lockfile */
-
- for (tries = IK_LCKTRIES; tries > 0; tries--) {
- if (zrename(tmplck,lcknam) == 0)
- break;
- debug(F101,"getslot database locked by pid", "", dbpid);
- sleep(IK_LCKSLEEP);
- }
- if (tries < 1) { /* Couldn't */
- debug(F110,"getslot create lock failure",lcknam,0);
- return(-1);
- }
- /* Have lock, open database */
-
- debug(F110,"getslot has lock",lcknam,0); /* Have lock */
-
- if (!dbfile)
- return(-1);
-
- /* If database doesn't exist, create it. */
-
- debug(F110,"getslot dbfile",dbfile,0);
- if (zchki(dbfile) < 0) {
- debug(F110,"getslot creating new database",dbfile,0);
- x = creat(dbfile,0660);
- if (x < 0) {
- debug(F111,"getslot creat() failed", dbfile, errno);
- goto xslot;
- }
- close(x);
- }
- dbfp = fopen(dbfile,updmode); /* Open it in update mode */
- if (!dbfp) {
- debug(F111,"getslot fopen failed",dbfile,errno);
- goto xslot;
- }
- /* Now find a free (or new) slot... */
-
- dblastused = 0L; /* Seek pointer to last record inuse */
- mydbseek = 0L; /* Seek pointer for my record */
-
- /* Quickly read the whole database; n = record counter, i = seek pointer */
-
- for (n = 0, i = 0; !feof(dbfp); i += DB_RECL, n++) {
- x = fread(dbrec,1,DB_RECL,dbfp); /* Read a record */
- if (x < 1) /* EOF not caught by feof() */
- break;
-#ifndef NOFTRUNCATE
- if (x != DB_RECL) { /* Watch out for trailing junk */
- debug(F101,"getslot bad size","",x); /* (Shouldn't happen...) */
-#ifdef COHERENT
- chsize(fileno(dbfp),i);
-#else
- ftruncate(fileno(dbfp),(CK_OFF_T)i);
-#endif /* COHERENT */
- x = 0;
- CKFSEEK(dbfp,i,0);
- break;
- }
-#endif /* NOFTRUNCATE */
- debug(F101,"getslot record","",n);
- k = dbfld[db_FLAGS].off;
- j = dbfld[db_FLAGS].len;
- dbflags = hextoulong(&dbrec[k],j);
- debug(F001,"getslot dbflags","",dbflags);
- k = dbfld[db_MYPID].off;
- j = dbfld[db_MYPID].len;
- dbpid = hextoulong(&dbrec[k],j);
- debug(F001,"getslot dbpid","",dbpid);
- k = dbfld[db_SADDR].off;
- j = dbfld[db_SADDR].len;
- dbip = hextoulong(&dbrec[k],j);
- debug(F001,"getslot dbip","",dbip);
-
- if (dbflags & DBF_INUSE) { /* Remember last slot in use */
- x = 0; /* Make sure it's REALLY in use */
- if (dbpid == mypid && dbip == myip) { /* Check for PID == my PID */
- x = 1;
- debug(F101,"getslot record pid","",dbpid);
- } else { /* Or for stale PID */
- x = zchkpid(dbpid);
- debug(F101,"getslot zchkpid()","",x);
- }
- if (!x) { /* Bogus record */
- x = freeslot(n);
- debug(F101,"getslot stale record pid: freeslot()","",x);
- if (x > -1 && !haveslot)
- dbflags = 0;
- } else { /* It's really in use */
- dblastused = i;
- }
- }
- if (!haveslot) { /* If I don't have a slot yet */
- if (!(dbflags & DBF_INUSE)) { /* Claim this one */
- debug(F101,"getslot free slot", "", n);
- haveslot = 1;
- mydbseek = i;
- mydbslot = n; /* But keep going... */
- }
- }
- }
- /* Come here with i == seek pointer to first record after eof */
-
- if (!haveslot) { /* Found no free slot so add to end */
- debug(F101,"getslot new slot","",n);
- haveslot = 1;
- mydbseek = i;
- mydbslot = n;
- }
- ikdbopen = 1; /* OK to make database entries */
- debug(F101,"getslot records","",n);
- debug(F101,"getslot dblastused","",dblastused);
- debug(F101,"getslot i","",i);
-
- /* Trim stale records from end */
-
-#ifndef NOFTRUNCATE
- if (i > dblastused+DB_RECL) {
- debug(F101,"getslot truncating at","",dblastused+DB_RECL);
-#ifdef COHERENT
- x = chsize(fileno(dbfp),dblastused+DB_RECL);
-#else
- x = ftruncate(fileno(dbfp),(CK_OFF_T)(dblastused+DB_RECL));
-#endif /* COHERENT */
- if (x < 0) /* (Not fatal) */
- debug(F101,"getslot ftruncate failed", "", errno);
- }
-#endif /* NOFTRUNCATE */
-
- /* Initialize my record */
-
- if (initslot(mydbslot) < 0) {
- debug(F101,"getslot initslot() error","",n);
- ikdbopen = 0;
- goto xslot;
- }
- debug(F101,"getslot OK","",mydbslot);
- rc = mydbslot; /* OK return code */
-
- xslot: /* Unlock the database and return */
- if (unlink(lcknam) < 0) {
- debug(F111,"getslot lockfile removal failed",lcknam,errno);
- rc = -1;
- }
- return(rc);
-}
-#endif /* IKSDB */
-#endif /* NOIKSD */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusy.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuusy.c
deleted file mode 100644
index 1802b05..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuusy.c
+++ /dev/null
@@ -1,4744 +0,0 @@
-#include "ckcsym.h"
-#define XFATAL fatal
-
-/* C K U U S Y -- "User Interface" for C-Kermit Kermit, part Y */
-
-/* Command-Line Argument Parser */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#include "ckcdeb.h"
-
-char * bannerfile = NULL;
-char * helpfile = NULL;
-extern int xferlog, filepeek, nolinks;
-extern char * xferfile;
-extern int debtim;
-
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckucmd.h"
-#include "ckcnet.h"
-#include "ckuusr.h"
-#include "ckcxla.h"
-#ifdef CK_SSL
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-#include <signal.h>
-
-#ifdef OS2
-#include <io.h>
-#ifdef KUI
-#include "ikui.h"
-extern struct _kui_init kui_init;
-#endif /* KUI */
-#endif /* OS2 */
-
-extern int inserver, fncnv, f_save, xfermode;
-#ifdef PATTERNS
-extern int patterns;
-#endif /* PATTERNS */
-
-#ifndef NOICP
-extern int cmdint;
-#endif /* NOICP */
-extern int xsuspend;
-
-#ifdef NETCONN
-#ifdef ANYX25
-extern int revcall, closgr, cudata;
-extern char udata[];
-extern int x25fd;
-#endif /* ANYX25 */
-#ifndef VMS
-#ifndef OS2
-#ifndef OSK
-extern
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* VMS */
-
-int telnetfd;
-extern struct keytab netcmd[];
-extern int tn_exit;
-#ifndef NOICP
-#ifndef NODIAL
-extern int nnets, nnetdir; /* Network services directory */
-extern char *netdir[];
-extern char *nh_p[]; /* Network directory entry pointers */
-extern char *nh_p2[]; /* Network directory entry nettype */
-extern char *nh_px[4][MAXDNUMS + 1];
-#endif /* NODIAL */
-extern int nhcount;
-extern char * n_name; /* Network name pointer */
-#endif /* NOICP */
-#endif /* NETCONN */
-
-#ifndef NOSPL
-extern int nmac;
-extern struct mtab *mactab;
-#endif /* NOSPL */
-extern char uidbuf[];
-
-#ifdef CK_LOGIN
-extern int logintimo;
-#endif /* CK_LOGIN */
-
-extern char * myname, * dftty;
-extern int howcalled;
-
-extern char *ckxsys, *ckzsys, **xargv, *xarg0, **cmlist, *clcmds;
-
-extern int action, cflg, xargc, cnflg, local, quiet, escape, network, mdmtyp,
- bgset, backgrd, xargs, binary, parity, turn, turnch, duplex, flow, clfils,
- noinit, stayflg, nettype, cfilef, noherald, cmask, cmdmsk, exitonclose,
- haveline, justone, cxtype, xfinish, ttnproto;
-
-extern long speed;
-extern char ttname[];
-extern char * pipedata, * cmdfil;
-
-#ifndef NOXFER
-extern char *cmarg, *cmarg2;
-
-extern int nfils, stdouf, stdinf, displa, maxrps, rpsiz, ckwarn, urpsiz,
- wslotr, swcapr, ckdelay, recursive, reliable, xreliable, fnspath, fncact,
- clearrq, setreliable;
-
-#ifdef PIPESEND
-extern int usepipes, pipesend;
-#endif /* PIPESEND */
-extern int protocol;
-#endif /* NOXFER */
-
-#ifndef NOPUSH
-extern int nopush;
-#endif /* NOPUSH */
-
-#ifdef OS2
-extern struct keytab os2devtab[];
-extern int nos2dev;
-extern int ttslip;
-extern int tt_scroll, tt_escape;
-#ifdef OS2PM
-extern int os2pm;
-#endif /* OS2PM */
-#endif /* OS2 */
-
-#ifdef CK_NETBIOS
-extern unsigned char NetBiosAdapter;
-#endif /* CK_NETBIOS */
-
-#ifdef XFATAL
-#undef XFATAL
-#endif /* XFATAL */
-
-#ifdef TNCODE
-_PROTOTYP(static int dotnarg, (char x) );
-#endif /* TNCODE */
-#ifdef RLOGCODE
-_PROTOTYP(static int dorlgarg, (char x) );
-#endif /* RLOGCODE */
-#ifdef SSHBUILTIN
-_PROTOTYP(static int dossharg, (char x) );
-#endif /* SSHBUILTIN */
-
-int haveftpuid = 0; /* Have FTP user ID */
-static int have_cx = 0; /* Have connection */
-
-static char * failmsg = NULL; /* Failure message */
-
-#ifdef NEWFTP
-extern char * ftp_host;
-#endif /* NEWFTP */
-
-extern int what;
-
-#ifndef NOICP
-#ifndef NODIAL
-extern int nmdm, telephony;
-extern struct keytab mdmtab[];
-extern int usermdm, dialudt;
-#endif /* NODIAL */
-_PROTOTYP(static int pmsg, (char *) );
-_PROTOTYP(static int fmsg, (char *) );
-static int pmsg(s) char *s; { printf("%s\n", s); return(0); }
-static int fmsg(s) char *s; { fatal(s); return(0); }
-#define XFATAL(s) return(what==W_COMMAND?pmsg(s):fmsg(s))
-#else
-#define XFATAL fatal
-#endif /* NOICP */
-
-#ifndef NOHTTP
-#define HTTP_GET 1
-#define HTTP_PUT 2
-#define HTTP_HED 3
-#endif /* NOHTTP */
-
-#ifdef CK_URL
-/* URLs we recognize */
-
-#define URL_FTP 1
-#define URL_HTTP 2
-#define URL_HTTPS 3
-#define URL_IKSD 4
-#define URL_TELNET 5
-#define URL_LOGIN 6
-
-struct keytab urltab[] = {
-#ifdef NEWFTP
- "ftp", URL_FTP, 0,
-#endif /* NEWFTP */
-#ifndef NOHTTP
- "http", URL_HTTP, 0,
- "https", URL_HTTPS, 0,
-#endif /* NOHTTP */
- "iksd", URL_IKSD, 0,
- "kermit", URL_IKSD, 0,
- "telnet", URL_TELNET, 0,
- "", 0, 0
-};
-int nurltab = sizeof(urltab)/sizeof(struct keytab) - 1;
-
-#ifndef URLBUFLEN
-#define URLBUFLEN 1024
-#endif /* URLBUFLEN */
-static char urlbuf[URLBUFLEN];
-struct urldata g_url = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
-
-/* u r l p a r s e -- Parse a possible URL */
-
-/*
- Returns 0 if the candidate does not seem to be a URL.
- Returns 1 if it might be a URL, with the above pointers set to its pieces:
- service : [ // ] [ user [ : password ] @ ] host [ : service ] [ / path ] -
- [ ? name [ = value ]]
-
- Example: ftp://ds.internic.net:21/rfc/rfc1234.txt
- url.svc = [ftp]
- url.usr = [(NULL)]
- url.psw = [(NULL)]
- url.hos = [ds.internic.net]
- url.por = [21]
- url.pth = [rfc/rfc1234.txt]
-
- It might be a URL if it contains a possible service name followed by a
- a colon (:). Thus "telnet:xyzcorp.com" is a minimal URL, whereas a
- full-blown example would be:
-
- ftp://olga:secret@ftp.xyzcorp.com/public/oofa.txt
-
- The caller must verify the results, i.e. that the service string is a real
- TCP service, etc. This routine just parses the fields.
-
- struct urldata defined in ckcker.h
-*/
-
-int
-urlparse(s,url) char *s; struct urldata * url; {
- char * p = NULL, * urlbuf = NULL;
- int x;
-
- if (!s || !url)
- return(0);
-
- if (!*s)
- return(0);
-
- makestr(&urlbuf,s);
-
- if (url->sav) { /* In case we were called before... */
- free(url->sav);
- url->sav = NULL;
- }
- if (url->svc) {
- free(url->svc);
- url->svc = NULL;
- }
- if (url->hos) {
- free(url->hos);
- url->hos = NULL;
- }
- if (url->por) {
- free(url->por);
- url->por = NULL;
- }
- if (url->usr) {
- free(url->usr);
- url->usr = NULL;
- }
- if (url->psw) {
- free(url->psw);
- url->psw = NULL;
- }
- if (url->pth) {
- free(url->pth);
- url->pth = NULL;
- }
- if (url->nopts) {
- int i;
- for (i = 0; i < url->nopts && i < MAX_URL_OPTS; i++ ) {
- if (url->opt[i].nam) {
- free(url->opt[i].nam);
- url->opt[i].nam = NULL;
- }
- if (url->opt[i].val) {
- free(url->opt[i].val);
- url->opt[i].val = NULL;
- }
- }
- url->nopts = 0;
- }
- p = urlbuf; /* Was a service requested? */
- while (*p && *p != ':') /* Look for colon */
- p++;
- if (*p == ':') { /* Have a colon */
- *p++ = NUL; /* Get service name or number */
- if (*p == ':') /* a second colon */
- *p++ = NUL; /* get rid of that one too */
- while (*p == '/') *p++ = NUL; /* and slashes */
-#ifdef COMMENT
- /* Trailing slash is part of path - leave it - jaltman */
- x = strlen(p); /* Length of remainder */
- if (p[x-1] == '/') /* If there is a trailing slash */
- p[x-1] = NUL; /* remove it. */
-#endif /* COMMENT */
- if (urlbuf[0]) { /* Anything left? */
- char *q = p, *r = p, *w = p;
- makestr(&url->svc,urlbuf);
-
- while (*p != NUL && *p != '@') /* look for @ */
- p++;
- if (*p == '@') { /* Signifies user ID, maybe password */
- *p++ = NUL;
- url->hos = p;
- while (*w != NUL && *w != ':')
- w++;
- if (*w == ':')
- *w++ = NUL;
- url->usr = r; /* Username */
- if (*w)
- url->psw = w; /* Password */
- q = p;
- } else { /* No username or password */
- p = q;
- url->hos = p;
- }
-#ifdef COMMENT
- debug(F111,"urlparse url->usr",url->usr,url->usr);
- debug(F111,"urlparse url->psw",url->usr,url->psw);
- debug(F111,"urlparse url->hos",url->usr,url->hos);
-#endif /* COMMENT */
-
- while (*p != NUL && *p != ':' && *p != '/') /* Port? */
- p++;
- if (*p == ':') { /* TCP port */
- *p++ = NUL;
- r = p;
- url->por = r;
- while (*p != NUL && *p != '/')
- p++;
- /* '/' is part of path, leave it until we can copy */
- if (*p == '/') {
- makestr(&url->pth,p); /* Path */
- *p = NUL;
- }
- } else { /* No port */
- /* '/' is part of path, leave it */
- if (*p == '/') {
- makestr(&url->pth,p); /* Path */
- *p = NUL;
- }
- }
- }
- /* Copy non-NULL result strings */
- if (url->svc) if (*url->svc) {
- p = url->svc;
- url->svc = NULL;
- makestr(&url->svc,p);
- }
- if (url->hos) if (*url->hos) {
- p = url->hos;
- url->hos = NULL;
- makestr(&url->hos,p);
- }
- if (url->por) if (*url->por) {
- p = url->por;
- url->por = NULL;
- makestr(&url->por,p);
- }
-/*
- WARNING (Wed Oct 9 16:09:03 2002): We now allow the username and
- password to be empty strings. These are treated differently from null
- pointers: an empty string means the URL included username and/or password
- fields that were empty, e.g. ftp://:@ftp.xyzcorp.com/somepath/somefile,
- which causes the client to prompt for the username and/or password.
-*/
- if (url->usr) /* if (*url->usr) */ {
- p = url->usr;
- url->usr = NULL;
- makestr(&url->usr,p);
- }
- if (url->psw) /* if (*url->psw) */ {
- p = url->psw;
- url->psw = NULL;
- makestr(&url->psw,p);
- }
- /* Save a copy of the full url if one was found. */
- if (url->svc)
- makestr(&url->sav,s);
- free(urlbuf);
- return(url->svc ? 1 : 0);
- }
- return(0);
-}
-#endif /* CK_URL */
-
-#ifndef NOCMDL
-
-char *hlp1[] = {
-#ifndef NOICP
-" [filename] [-x arg [-x arg]...[-yyy]..] [ = text ] ]\n",
-#else
-"[-x arg [-x arg]...[-yyy]..]\n",
-#endif /* NOICP */
-"\n",
-" -x is an option requiring an argument, -y an option with no argument.\n",
-" If the first command-line argument is the name of a file, interactive-\n",
-" mode commands are executed from the file. The '=' argument tells Kermit\n",
-" not to parse the remainder of the command line, but to make the words\n",
-" following '=' available as \\%1, \\%2, ... \\%9. The command file \
-(if any)\n",
-" is executed before the command-line options.\n",
-"\n",
-#ifndef NOICP
-"If no action command is included, or -S is, then after the command line is\n",
-"executed, Kermit issues its prompt and waits for you to type commands.\n",
-#else
-"Operation by command-line options only.\n",
-#endif /* NOICP */
-""
-};
-
-static
-char *hlp2[] = {
-" [option-list] host[:port] [port]\n",
-" The option-list consists of zero, one, or more of:\n",
-" -8 Negotiate Telnet Binary in both directions\n",
-" -a Require use of Telnet authentication\n",
-" -d Turn on debug mode\n",
-" -E No escape character\n",
-" -K Refuse use of authentication; do not send username\n",
-" -l user Set username and request Telnet authentication\n",
-" -L Negotiate Telnet Binary Output only\n",
-" -x Require Encryption\n",
-" -D Disable forward-X\n",
-" -T cert=file Use certificate in file\n",
-" -T key=file Use private key in file\n",
-" -T crlfile=file Use CRL in file\n",
-" -T crldir=dir Use CRLs in directory\n",
-" -T cipher=string Use only ciphers in string\n",
-" -f Forward credentials to host\n",
-" -k realm Set default Kerberos realm\n",
-""
-};
-
-static
-char *hlp3[] = { /* rlogin */
-" [option-list] host[:port] [port]\n",
-" The option-list consists of zero, one, or more of:\n",
-" -d Turn on debug mode\n",
-" -l user Set username\n",
-""
-};
-
-static
-char *hlp4[] = { /* ssh */
-" [option-list] host[:port] [port]\n",
-" The option-list consists of zero, one, or more of:\n",
-#ifdef OS2
-" -# flags Kermit 95 Startup Flags\n",
-" 1 turn off Win95 special fixes\n",
-" 2 do not load optional network dlls\n",
-" 4 do not load optional tapi dlls\n",
-" 8 do not load optional kerberos dlls\n",
-" 16 do not load optional zmodem dlls\n",
-" 32 use stdin for input instead of the console\n",
-" 64 use stdout for output instead of the console\n",
-" 128 do not terminate process in response to Session Logoff\n",
-#endif /* OS2 */
-" -d Turn on debug mode\n",
-" -Y Disable init file processing\n",
-" -l user Set username\n",
-""
-};
-
-/* Command-line option help lines. Update this when adding new options! */
-
-char * opthlp[128]; /* Option help */
-char * arghlp[128]; /* Argument for option */
-int optact[128]; /* Action-option flag */
-
-VOID
-fatal2(msg1,msg2) char *msg1, *msg2; {
- char buf[256];
- if (!msg1) msg1 = "";
- if (!msg2) msg2 = "";
- ckmakmsg(buf,256,"\"",msg1,"\" - ",msg2);
-#ifndef NOICP
- if (what == W_COMMAND)
- printf("%s\n",buf);
- else
-#endif /* NOICP */
- fatal((char *)buf);
-}
-
-static SIGTYP
-#ifdef CK_ANSI
-cl_int(int dummy)
-#else /* CK_ANSI */
-cl_int(dummy) int dummy;
-#endif /* CK_ANSI */
-{ /* Command-line interrupt handler */
- doexit(BAD_EXIT,1);
- SIGRETURN;
-}
-
-#ifdef NEWFTP
-extern int ftp_action, ftp_cmdlin;
-
-static int
-xx_ftp(host, port) char * host, * port; {
-#ifdef CK_URL
- extern int haveurl;
-#endif /* CK_URL */
- extern char * ftp_logname;
- int use_tls = 0;
- char * p;
-
- if (port) if (!*port) port = NULL;
-
- if (!host)
- return(0);
- if (!*host)
- return(0);
- debug(F111,"ftp xx_ftp host",ftp_host,haveftpuid);
- debug(F111,"ftp xx_ftp uidbuf 1",uidbuf,haveftpuid);
- ftp_cmdlin = 1; /* 1 = FTP started from command line */
- if (nfils > 0)
- ftp_cmdlin++; /* 2 = same plus file transfer */
-
-#ifndef NOURL
- /* debug(F111,"ftp xx_ftp g_url.usr",g_url.usr,g_url.usr); */
- if (haveurl && g_url.usr) { /* Wed Oct 9 15:15:22 2002 */
- if (!*(g_url.usr)) { /* Force username prompt if */
- haveftpuid = 0; /* "ftp://:@host" given. */
- uidbuf[0] = NUL;
- makestr(&ftp_logname,NULL);
- }
- debug(F111,"ftp xx_ftp uidbuf 2",uidbuf,haveftpuid);
- }
-#endif /* NOURL */
- debug(F111,"ftp xx_ftp uidbuf 3",uidbuf,haveftpuid);
- if (haveftpuid) {
- makestr(&ftp_logname,uidbuf);
- debug(F111,"ftp_logname",ftp_logname,haveftpuid);
- }
- if (!port) {
- if ((p = ckstrchr(ftp_host,':')))
- *p++ = NUL;
- port = p;
- }
- if (!port) {
-#ifdef CK_URL
- if (haveurl) {
- if (g_url.por)
- port = g_url.por;
- else if (g_url.svc)
- port = g_url.svc;
- else
- port = "ftp";
- } else
-#endif /* CK_URL */
- port = "ftp";
- }
-
-#ifdef CK_SSL
- if (haveurl && g_url.svc)
- use_tls = !ckstrcmp("ftps",g_url.svc,-1,0);
-#endif /* CK_SSL */
-
- if (ftpopen(ftp_host,port,use_tls) < 1)
- return(-1);
- debug(F111,"ftp xx_ftp action",ckctoa((char)ftp_action),nfils);
- if (nfils > 0) {
- switch (ftp_action) {
- case 'g':
- return(cmdlinget(stayflg));
- case 'p':
- case 's':
- return(cmdlinput(stayflg));
- }
- }
- return(1);
-}
-#endif /* NEWFTP */
-
-
-#ifndef NOHTTP
-static
-char * http_hlp[] = {
- " -h This message.\n",
- " -d Debug to debug.log.\n",
- " -S Stay (issue command prompt when done).\n",
- " -Y Do not execute Kermit initialization file.\n",
- " -q Quiet (suppress most messages).\n",
- " -u name Username.\n",
- " -P password Password.\n",
- " -g pathname Get remote pathname.\n",
- " -p pathname Put remote pathname.\n",
- " -H pathname Head remote pathname.\n",
- " -l pathname Local path for -g, -p, and -H.\n",
-#ifdef CK_SSL
- " -z opt[=value] Security options...\n",
- " cert=file Client certificate file\n",
- " certsok Accept all certificates\n",
- " key=file Client private key file\n",
- " secure Use SSL\n",
- " verify=n 0 = none, 1 = peer , 2 = certificate required\n",
-#endif /* CK_SSL */
- ""
-};
-
-#define HT_CERTFI 0
-#define HT_OKCERT 1
-#define HT_KEY 2
-#define HT_SECURE 3
-#define HT_VERIFY 4
-
-static struct keytab httpztab[] = {
- { "cert", HT_CERTFI, CM_ARG },
- { "certsok", HT_OKCERT, 0 },
- { "key", HT_KEY, CM_ARG },
- { "secure", HT_SECURE, 0 },
- { "verify", HT_VERIFY, CM_ARG },
- { "", 0, 0 }
-};
-static int nhttpztab = sizeof(httpztab) / sizeof(struct keytab) - 1;
-#endif /* NOHTTP */
-
-/* U S A G E */
-
-VOID
-usage() {
-#ifdef MINIX
- conol("Usage: ");
- conol(xarg0);
- conol(" [-x arg [-x arg]...[-yyy]..] ]\n");
-#else
- conol("Usage: ");
- conol(xarg0);
- if (howcalled == I_AM_KERMIT || howcalled == I_AM_IKSD ||
- howcalled == I_AM_SSHSUB)
- conola(hlp1);
- else if (howcalled == I_AM_TELNET)
- conola(hlp2);
- else if (howcalled == I_AM_RLOGIN)
- conola(hlp3);
- else if (howcalled == I_AM_SSH)
- conola(hlp4);
- if (howcalled == I_AM_KERMIT || howcalled == I_AM_IKSD ||
- howcalled == I_AM_SSHSUB) {
- int c;
- conoll("");
- conoll("Complete listing of command-line options:");
- conoll("");
- for (c = 31; c < 128; c++) {
- if (!opthlp[c])
- continue;
- if (arghlp[c]) {
- printf(" -%c <arg>%s\n",
- (char)c,
- (optact[c] ? " (action option)" : "")
- );
- printf(" %s\n",opthlp[c]);
- printf(" Argument: %s\n\n",arghlp[c]);
- } else { /* Option without arg */
- printf(" -%c %s%s\n",
- (char)c, opthlp[c],
- (optact[c]?" (action option)":"")
- );
- printf(" Argument: (none)\n\n");
- }
- }
-#ifdef OS2ORUNIX
- printf("To prevent this message from scrolling, use '%s -h | more'.\n",
- xarg0);
-#endif /* OS2ORUNIX */
- printf("For a list of extended options use '%s --help'.\n",
- xarg0);
- }
-#endif /* MINIX */
-}
-
-
-/* C M D L I N -- Get arguments from command line */
-
-int
-cmdlin() {
- char x; /* Local general-purpose char */
- extern int haveurl;
-
-#ifdef NEWFTP
- char * port = NULL;
-#endif /* NEWFTP */
-
-#ifndef NOXFER
- cmarg = ""; /* Initialize globals */
- cmarg2 = "";
-#endif /* NOXFER */
- action = 0;
- cflg = 0;
-
- signal(SIGINT,cl_int);
-
-/* Here we handle different "Command Line Personalities" */
-
-#ifdef TCPSOCKET
-#ifndef NOHTTP
- if (howcalled == I_AM_HTTP) { /* If I was called as HTTP... */
- char rdns[128];
-#ifdef OS2
- char * agent = "Kermit 95";
-#else
- char * agent = "C-Kermit";
-#endif /* OS2 */
-
- debug(F100,"http personality","",0);
-#ifdef CK_URL
- if (haveurl) {
- int type;
- char * lfile;
-
- type = lookup(urltab,g_url.svc,nurltab,NULL);
- if (!(type == URL_HTTP || type == URL_HTTPS)) {
- printf("?Internal Error: HTTP command line processing\n");
- debug(F100,"Error: HTTP command line processing","",0);
- doexit(BAD_EXIT,1);
- }
- rdns[0] = '\0';
- lfile = "";
- x = (http_open(g_url.hos,g_url.por ? g_url.por : g_url.svc,
- type == URL_HTTPS, rdns,128,NULL) == 0);
- if (x) {
-#ifdef KUI
- char asname[CKMAXPATH+1];
-#endif /* KUI */
- if (!quiet) {
- if (rdns[0])
- printf("Connected to %s [%s]\r\n",g_url.hos,rdns);
- else
- printf("Connected to %s\r\n",g_url.hos);
- }
- if (g_url.pth)
- zstrip(g_url.pth,&lfile);
- else
- g_url.pth = "/";
-
- if (!*lfile)
- lfile = "index.html";
-
-#ifdef KUI
- if (uq_file(NULL, /* K95 GUI: Put up file box. */
- NULL, /* (not tested...) */
- 4,
- NULL,
- lfile,
- asname,
- CKMAXPATH+1
- ) > 0)
- lfile = asname;
-#endif /* KUI */
-
- x = http_get(agent,
- NULL, /* hdrlist */
- g_url.usr,
- g_url.psw,
- 0,
- lfile,
- g_url.pth,
- 0 /* stdio */
- );
- x = (http_close() == 0);
- } else {
- if (!quiet)
- printf("?HTTP Connection failed.\r\n");
- }
- doexit(x ? GOOD_EXIT : BAD_EXIT, -1);
- } else
-#endif /* CK_URL */
- {
- int http_action = 0;
- char * host = NULL, * svc = NULL, * lpath = NULL;
- char * user = NULL, * pswd = NULL, * path = NULL;
- char * xp;
-
- while (--xargc > 0) { /* Go through command line words */
- xargv++;
- debug(F111,"cmdlin http xargv",*xargv,xargc);
- xp = *xargv+1;
- if (**xargv == '-') { /* Got an option */
- int xx;
- x = *(*xargv+1); /* Get the option letter */
- switch (x) {
- case 'd': /* Debug */
-#ifdef DEBUG
- if (deblog) {
- debtim = 1;
- } else {
- deblog = debopn("debug.log",0);
- }
-#endif /* DEBUG */
- break;
- case 'S': /* Stay */
- case 'Y': /* No initialization file */
- break; /* (already done in prescan) */
- case 'q': /* Quiet */
- quiet = 1;
- break;
- case 'u': /* Options that require arguments */
- case 'P':
- case 'g':
- case 'p':
- case 'H':
- case 'l':
- if (*(xp+1)) {
- XFATAL("Invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("Missing argument");
- }
- switch (x) {
- case 'u':
- user = *xargv;
- break;
- case 'P':
- pswd = *xargv;
- break;
- case 'l':
- if (http_action != HTTP_PUT)
- lpath = *xargv;
- break;
- case 'g':
- http_action = HTTP_GET;
- path = *xargv;
- debug(F111,"cmdlin http GET",path,http_action);
- break;
- case 'p':
- http_action = HTTP_PUT;
- path = *xargv;
- break;
- case 'H':
- http_action = HTTP_HED;
- path = *xargv;
- }
- break;
-
-#ifdef CK_SSL
- case 'z': {
- /* *xargv contains a value of the form tag=value */
- /* we need to lookup the tag and save the value */
- int x,y,z;
- char * p, * q;
- makestr(&p,*xargv);
- y = ckindex("=",p,0,0,1);
- if (y > 0)
- p[y-1] = '\0';
- x = lookup(httpztab,p,nhttpztab,&z);
- if (x < 0) {
- printf("?Invalid security option: \"%s\"\n",p);
- } else {
- printf("Security option: \"%s",p);
- if (httpztab[z].flgs & CM_ARG) {
- q = &p[y];
- if (!*q)
- fatal("?Missing required value");
- }
- /* -z options w/args */
- switch (httpztab[z].kwval) {
- case HT_CERTFI:
- makestr(&ssl_rsa_cert_file,q);
- break;
- case HT_OKCERT:
- ssl_certsok_flag = 1;
- break;
- case HT_KEY:
- makestr(&ssl_rsa_key_file,q);
- break;
- case HT_SECURE:
- svc="https";
- break;
- case HT_VERIFY:
- if (!rdigits(q))
- printf("?Bad number: %s\n",q);
- ssl_verify_flag = atoi(q);
- break;
- }
- }
- free(p);
- break;
- }
-#endif /* CK_SSL */
-
- case 'h': /* Help */
- default:
- printf("Usage: %s host [ options... ]\n",xarg0);
- conola(http_hlp);
- doexit(GOOD_EXIT,-1);
- }
- } else { /* No dash - must be hostname */
- host = *xargv;
- if (xargc > 1) {
- svc = *(xargv+1);
- if (svc) if (*svc == '-' || !*svc)
- svc = NULL;
- if (svc) {
- xargv++;
- xargc--;
- }
- }
- }
- }
- if (!svc) svc = "";
- if (!*svc) svc = "http";
- if (!host) XFATAL("No http host given");
-
- /* Check action args before opening the connection */
- if (http_action) {
- if (http_action == HTTP_PUT) {
- if (!lpath)
- XFATAL("No local path for http PUT");
- }
- if (!path)
- XFATAL("No remote path for http action");
- }
- /* Now it's OK to open the connection */
- rdns[0] = NUL;
- x = (http_open(host,
- svc,!ckstrcmp("https",svc,-1,0),rdns,128,NULL
- ) == 0);
- if (!x) {
- if (!quiet)
- printf("?HTTP Connection failed.\r\n");
- doexit(BAD_EXIT,-1);
- }
- if (!quiet) {
- if (rdns[0])
- printf("Connected to %s [%s]\r\n",host,rdns);
- else
- printf("Connected to %s\r\n",host);
- }
- if (http_action) {
- int pcpy = 0;
- if (http_action != HTTP_PUT) { /* Supply default */
- if (!lpath) { /* local path... */
- zstrip(path,&lpath);
- if (!lpath)
- lpath = "";
- if (!*lpath)
- lpath = "index.html";
- }
- }
- if (*path != '/') {
- char * p = (char *) malloc(strlen(path)+2);
- if (!p) fatal("?Memory allocation error\n");
- *p = '/';
- strcpy(&p[1],path); /* safe */
- path = p;
- pcpy = 1;
- }
- switch (http_action) {
- case HTTP_GET:
- x = http_get(agent,NULL,user,pswd,0,lpath,path,0);
- break;
-
- case HTTP_PUT:
- x = http_put(agent,NULL,"text/HTML",
- user,pswd,0,lpath,path,NULL,0);
- break;
-
- case HTTP_HED:
- x = http_head(agent,NULL,user,pswd,0,lpath,path,0);
- break;
- }
- debug(F101,"cmdline http result","",x);
- x = (http_close() == 0);
- if (pcpy) free(path);
- doexit(x ? GOOD_EXIT : BAD_EXIT, -1);
- }
- return(0);
- }
- } else
-#endif /* NOHTTP */
-#ifdef NEWFTP
- if (howcalled == I_AM_FTP) { /* If I was called as FTP... */
- debug(F100,"ftp personality","",0);
-#ifdef CK_URL
- if (haveurl)
- doftparg('U');
- else
-#endif /* CK_URL */
- {
- while (--xargc > 0) { /* Go through command line words */
- xargv++;
- debug(F111,"cmdlin ftp xargv",*xargv,xargc);
- if (**xargv == '-') { /* Got an option */
- int xx;
- x = *(*xargv+1); /* Get the option letter */
- xx = doftparg(x);
- if (xx < 0) {
- if (what == W_COMMAND)
- return(0);
- else
- doexit(BAD_EXIT,1);
- }
- } else { /* No dash - must be hostname */
- makestr(&ftp_host,*xargv);
- if (xargc > 1) {
- port = *(xargv+1);
- if (port) if (*port == '-' || !*port)
- port = NULL;
- if (port) {
- xargv++;
- xargc--;
- }
- }
- debug(F110,"cmdlin ftp host",ftp_host,0);
- debug(F110,"cmdlin ftp port",port,0);
- }
- } /* while */
- } /* if (haveurl) */
-
- if (ftp_host) {
- int xx;
-#ifdef NODIAL
- xx = xx_ftp(ftp_host,port);
- if (xx < 0 && (haveurl || ftp_cmdlin > 1)) doexit(BAD_EXIT,-1);
-#else
-#ifdef NOICP
- xx = xx_ftp(ftp_host,port);
- if (xx < 0 && (haveurl || ftp_cmdlin > 1)) doexit(BAD_EXIT,-1);
-#else
- if (*ftp_host == '=') { /* Skip directory lookup */
- xx = xx_ftp(&ftp_host[1],port);
- if (xx < 0 && (haveurl || ftp_cmdlin > 1))
- doexit(BAD_EXIT,-1);
- } else { /* Want lookup */
- int i;
- nhcount = 0; /* Check network directory */
- debug(F101,"cmdlin nnetdir","",nnetdir);
- if (nnetdir > 0) /* If there is a directory... */
- lunet(ftp_host); /* Look up the name */
- else /* If no directory */
- nhcount = 0; /* we didn't find anything there */
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"cmdlin lunet nhcount","",nhcount);
- if (nhcount > 0) {
- debug(F110,"cmdlin lunet nh_p[0]",nh_p[0],0);
- debug(F110,"cmdlin lunet nh_p2[0]",nh_p2[0],0);
- debug(F110,"cmdlin lunet nh_px[0][0]",
- nh_px[0][0],0);
- }
- }
-#endif /* DEBUG */
- if (nhcount == 0) {
- xx = xx_ftp(ftp_host,port);
- if (xx < 0 && (haveurl || ftp_cmdlin > 1))
- doexit(BAD_EXIT,-1);
- } else {
- for (i = 0; i < nhcount; i++) {
- if (ckstrcmp(nh_p2[i],"tcp/ip",6,0))
- continue;
- makestr(&ftp_host,nh_p[i]);
- debug(F110,"cmdlin calling xx_ftp",ftp_host,0);
- if (!quiet)
- printf("Trying %s...\n",ftp_host);
- if (xx_ftp(ftp_host,port) > -1)
- break;
- }
- }
- }
-#endif /* NODIAL */
-#endif /* NOICP */
- if (!ftpisconnected())
- doexit(BAD_EXIT,-1);
- }
- return(0);
- }
-#endif /* NEWFTP */
-
-#ifdef TNCODE
- if (howcalled == I_AM_TELNET) { /* If I was called as Telnet... */
-
- while (--xargc > 0) { /* Go through command line words */
- xargv++;
- debug(F111,"cmdlin telnet xargv",*xargv,xargc);
- if (**xargv == '=')
- return(0);
- if (!strcmp(*xargv,"--")) /* getopt() conformance */
- return(0);
-#ifdef VMS
- else if (**xargv == '/')
- continue;
-#endif /* VMS */
- else if (**xargv == '-') { /* Got an option (begins with dash) */
- int xx;
- x = *(*xargv+1); /* Get the option letter */
- debug(F111,"cmdlin telnet args 1",*xargv,xargc);
- xx = dotnarg(x);
- debug(F101,"cmdlin telnet doarg","",xx);
- debug(F111,"cmdlin telnet args 2",*xargv,xargc);
- if (xx < 0) {
-#ifndef NOICP
- if (what == W_COMMAND)
- return(0);
- else
-#endif /* NOICP */
- {
-#ifdef OS2
- sleep(1); /* Give it a chance... */
-#endif /* OS2 */
- doexit(BAD_EXIT,1); /* Go handle option */
- }
- }
- } else { /* No dash must be hostname */
- ckstrncpy(ttname,*xargv,TTNAMLEN+1);
- debug(F110,"cmdlin telnet host",ttname,0);
-
-#ifndef NOICP
-#ifndef NODIAL
- nhcount = 0; /* Check network directory */
- debug(F101,"cmdlin telnet nnetdir","",nnetdir);
- if (nnetdir > 0) /* If there is a directory... */
- lunet(*xargv); /* Look up the name */
- else /* If no directory */
- nhcount = 0; /* we didn't find anything there */
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"cmdlin telnet lunet nhcount","",nhcount);
- if (nhcount > 0) {
- debug(F110,"cmdlin telnet lunet nh_p[0]",nh_p[0],0);
- debug(F110,"cmdlin telnet lunet nh_p2[0]",nh_p2[0],0);
- debug(F110,"cmdlin telnet lunet nh_px[0][0]",
- nh_px[0][0],0);
- }
- }
-#endif /* DEBUG */
- if (nhcount > 0 && nh_p2[0]) /* If network type specified */
- if (ckstrcmp(nh_p2[0],"tcp/ip",6,0)) /* it must be TCP/IP */
- nhcount = 0;
- if (nhcount == 1) { /* Still OK, so make substitution */
- ckstrncpy(ttname,nh_p[0],TTNAMLEN+1);
- debug(F110,"cmdlin telnet lunet substitution",ttname,0);
- }
-#endif /* NODIAL */
-#endif /* NOICP */
-
- if (--xargc > 0 && !haveurl) { /* Service from command line? */
- xargv++;
- ckstrncat(ttname,":",TTNAMLEN+1);
- ckstrncat(ttname,*xargv,TTNAMLEN+1);
- debug(F110,"cmdlin telnet host2",ttname,0);
- }
-#ifndef NOICP
-#ifndef NODIAL
- else if (nhcount) { /* No - how about in net directory? */
- if (nh_px[0][0]) {
- ckstrncat(ttname,":",TTNAMLEN+1);
- ckstrncat(ttname,nh_px[0][0],TTNAMLEN+1);
- }
- }
-#endif /* NODIAL */
-#endif /* NOICP */
- local = 1; /* Try to open the connection */
- nettype = NET_TCPB;
- mdmtyp = -nettype;
- if (ttopen(ttname,&local,mdmtyp,0) < 0) {
- XFATAL("can't open host connection");
- }
- network = 1; /* It's open */
-#ifdef CKLOGDIAL
- dolognet();
-#endif /* CKLOGDIAL */
-#ifndef NOXFER
- reliable = 1; /* It's reliable */
- xreliable = 1; /* ... */
- setreliable = 1;
-#endif /* NOXFER */
- cflg = 1; /* Connect */
- stayflg = 1; /* Stay */
- tn_exit = 1; /* Telnet-like exit condition */
- quiet = 1;
- exitonclose = 1; /* Exit when connection closes */
-#ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ttname,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
-#endif /* NOSPL */
- break;
- }
- }
- return(0);
- }
-#endif /* TNCODE */
-#ifdef RLOGCODE
- else if (howcalled == I_AM_RLOGIN) { /* If I was called as Rlogin... */
- while (--xargc > 0) { /* Go through command line words */
- xargv++;
- debug(F111,"cmdlin rlogin xargv",*xargv,xargc);
- if (**xargv == '=')
- return(0);
- if (!strcmp(*xargv,"--")) /* getopt() conformance */
- return(0);
-#ifdef VMS
- else if (**xargv == '/')
- continue;
-#endif /* VMS */
- else if (**xargv == '-') { /* Got an option (begins with dash) */
- int xx;
- x = *(*xargv+1); /* Get the option letter */
- debug(F111,"cmdlin rlogin args 1",*xargv,xargc);
- xx = dorlgarg(x);
- debug(F101,"cmdlin rlogin doarg","",xx);
- debug(F111,"cmdlin rlogin args 2",*xargv,xargc);
- if (xx < 0) {
-#ifndef NOICP
- if (what == W_COMMAND)
- return(0);
- else
-#endif /* NOICP */
- {
-#ifdef OS2
- sleep(1); /* Give it a chance... */
-#endif /* OS2 */
- doexit(BAD_EXIT,1); /* Go handle option */
- }
- }
- } else { /* No dash must be hostname */
- ckstrncpy(ttname,*xargv,TTNAMLEN+1);
- debug(F110,"cmdlin rlogin host",ttname,0);
-
-#ifndef NOICP
-#ifndef NODIAL
- nhcount = 0; /* Check network directory */
- debug(F101,"cmdlin rlogin nnetdir","",nnetdir);
- if (nnetdir > 0) /* If there is a directory... */
- lunet(*xargv); /* Look up the name */
- else /* If no directory */
- nhcount = 0; /* we didn't find anything there */
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"cmdlin rlogin lunet nhcount","",nhcount);
- if (nhcount > 0) {
- debug(F110,"cmdlin rlogin lunet nh_p[0]",nh_p[0],0);
- debug(F110,"cmdlin rlogin lunet nh_p2[0]",nh_p2[0],0);
- debug(F110,"cmdlin rlogin lunet nh_px[0][0]",
- nh_px[0][0],0);
- }
- }
-#endif /* DEBUG */
- if (nhcount > 0 && nh_p2[0]) /* If network type specified */
- if (ckstrcmp(nh_p2[0],"tcp/ip",6,0)) /* it must be TCP/IP */
- nhcount = 0;
- if (nhcount == 1) { /* Still OK, so make substitution */
- ckstrncpy(ttname,nh_p[0],TTNAMLEN+1);
- debug(F110,"cmdlin rlogin lunet substitution",ttname,0);
- }
-#endif /* NODIAL */
-#endif /* NOICP */
-
- if (!haveurl) { /* Service from command line? */
- ckstrncat(ttname,":login",TTNAMLEN+1);
- debug(F110,"cmdlin rlogin host2",ttname,0);
- }
- local = 1; /* Try to open the connection */
- nettype = NET_TCPB;
- mdmtyp = -nettype;
- if (ttopen(ttname,&local,mdmtyp,0) < 0) {
- XFATAL("can't open host connection");
- }
- network = 1; /* It's open */
-#ifdef CKLOGDIAL
- dolognet();
-#endif /* CKLOGDIAL */
-#ifndef NOXFER
- reliable = 1; /* It's reliable */
- xreliable = 1; /* ... */
- setreliable = 1;
-#endif /* NOXFER */
- cflg = 1; /* Connect */
- stayflg = 1; /* Stay */
- tn_exit = 1; /* Telnet-like exit condition */
- quiet = 1;
- exitonclose = 1; /* Exit when connection closes */
-#ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ttname,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
-#endif /* NOSPL */
- break;
- }
- }
- return(0);
- }
-#endif /* RLOGCODE */
-#endif /* TCPSOCKET */
-
-#ifdef SSHBUILTIN
- if (howcalled == I_AM_SSH) { /* If I was called as SSH... */
- extern char * ssh_hst, * ssh_cmd, * ssh_prt;
- debug(F100,"ssh personality","",0);
-#ifdef CK_URL
- if (haveurl) {
- makestr(&ssh_hst,g_url.hos);
- makestr(&ssh_prt,g_url.svc);
- ckstrncpy(ttname,ssh_hst,TTNAMLEN+1);
- ckstrncat(ttname,":",TTNAMLEN+1);
- ckstrncat(ttname,ssh_prt,TTNAMLEN+1);
- }
- else
-#endif /* CK_URL */
- {
- while (--xargc > 0) { /* Go through command line words */
- xargv++;
- debug(F111,"cmdlin ssh xargv",*xargv,xargc);
- if (**xargv == '=')
- return(0);
- if (!strcmp(*xargv,"--")) /* getopt() conformance */
- return(0);
-#ifdef VMS
- else if (**xargv == '/')
- continue;
-#endif /* VMS */
- /* Got an option (begins with dash) */
- else if (**xargv == '-') {
- int xx;
- x = *(*xargv+1); /* Get the option letter */
- debug(F111,"cmdlin args 1",*xargv,xargc);
- xx = dossharg(x);
- debug(F101,"cmdlin doarg","",xx);
- debug(F111,"cmdlin args 2",*xargv,xargc);
- if (xx < 0) {
-#ifndef NOICP
- if (what == W_COMMAND)
- return(0);
- else
-#endif /* NOICP */
- {
-#ifdef OS2
- sleep(1); /* Give it a chance... */
-#endif /* OS2 */
- doexit(BAD_EXIT,1); /* Go handle option */
- }
- }
- } else { /* No dash must be hostname */
- ckstrncpy(ttname,*xargv,TTNAMLEN+1);
- makestr(&ssh_hst,ttname);
- debug(F110,"cmdlin ssh host",ttname,0);
-#ifndef NOICP
-#ifndef NODIAL
- nhcount = 0; /* Check network directory */
- debug(F101,"cmdlin nnetdir","",nnetdir);
- if (nnetdir > 0) /* If there is a directory... */
- lunet(*xargv); /* Look up the name */
- else /* If no directory */
- nhcount = 0; /* we didn't find anything there */
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"cmdlin lunet nhcount","",nhcount);
- if (nhcount > 0) {
- debug(F110,"cmdlin lunet nh_p[0]",nh_p[0],0);
- debug(F110,"cmdlin lunet nh_p2[0]",nh_p2[0],0);
- debug(F110,
- "cmdlin lunet nh_px[0][0]",nh_px[0][0],0);
- }
- }
-#endif /* DEBUG */
- /* If network type specified */
- /* it must be TCP/IP */
- if (nhcount > 0 && nh_p2[0])
- if (ckstrcmp(nh_p2[0],"tcp/ip",6,0))
- nhcount = 0;
- if (nhcount == 1) { /* Still OK, so make substitution */
- ckstrncpy(ttname,nh_p[0],TTNAMLEN+1);
- makestr(&ssh_hst,ttname);
- debug(F110,"cmdlin lunet substitution",ttname,0);
- }
-#endif /* NODIAL */
-#endif /* NOICP */
- /* Service from command line? */
- if (--xargc > 0 && !haveurl) {
- xargv++;
- ckstrncat(ttname,":",TTNAMLEN+1);
- ckstrncat(ttname,*xargv,TTNAMLEN+1);
- makestr(&ssh_prt,*xargv);
- debug(F110,"cmdlin telnet host2",ttname,0);
- }
-#ifdef COMMENT
- /* Do not substitute net dir service for ssh port */
-#ifndef NOICP
-#ifndef NODIAL
- /* No - how about in net directory? */
- else if (nhcount) {
- if (nh_px[0][0]) {
- ckstrncat(ttname,":",TTNAMLEN+1);
- ckstrncat(ttname,nh_px[0][0],TTNAMLEN+1);
- makestr(&ssh_prt,nh_px[0][0]);
- }
- }
-
-#endif /* NODIAL */
-#endif /* NOICP */
-#endif /* COMMENT */
- break;
- }
- }
- }
- local = 1; /* Try to open the connection */
- nettype = NET_SSH;
- mdmtyp = -nettype;
- if (ttopen(ttname,&local,mdmtyp,0) < 0) {
- XFATAL("can't open host connection");
- }
- network = 1; /* It's open */
-#ifdef CKLOGDIAL
- dolognet();
-#endif /* CKLOGDIAL */
-#ifndef NOXFER
- reliable = 1; /* It's reliable */
- xreliable = 1; /* ... */
- setreliable = 1;
-#endif /* NOXFER */
- cflg = 1; /* Connect */
- stayflg = 1; /* Stay */
- tn_exit = 1; /* Telnet-like exit condition */
- quiet = 1;
- exitonclose = 1; /* Exit when connection closes */
-#ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ttname,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
-#endif /* NOSPL */
- return(0);
- }
-#endif /* SSHBUILTIN */
-
- if (howcalled == I_AM_SSHSUB)
- return(0);
-
-/*
- From here down: We were called as "kermit" or "iksd".
-
- If we were started directly from a Kermit script file,
- the filename of the script is in argv[1], so skip past it.
-*/
- if (xargc > 1) {
- int n = 1;
- if (*xargv[1] != '-') {
-
-#ifdef KERBANG
- /* If we were started with a Kerbang script, the script */
- /* arguments were already picked up in prescan / cmdini() */
- /* and there is nothing here for us anyway. */
- if (!strcmp(xargv[1],"+"))
- return(0);
-#endif /* KERBANG */
-
- if (cfilef) { /* Command file found in prescan() */
- xargc -= n; /* Skip past it */
- xargv += n;
- cfilef = 0;
- debug(F101,"cmdlin cfilef set to 0","",cfilef);
- }
- }
- }
-/*
- Regular Unix-style command line parser, mostly conforming with 'A Proposed
- Command Syntax Standard for Unix Systems', Hemenway & Armitage, Unix/World,
- Vol.1, No.3, 1984.
-*/
- while (--xargc > 0) { /* Go through command line words */
- xargv++;
- debug(F111,"cmdlin xargv",*xargv,xargc);
- if (**xargv == '=')
- return(0);
- if (!strcmp(*xargv,"--")) /* getopt() conformance */
- return(0);
-#ifdef VMS
- else if (**xargv == '/')
- continue;
-#endif /* VMS */
- else if (**xargv == '-') { /* Got an option (begins with dash) */
- int xx;
- x = *(*xargv+1); /* Get the option letter */
- debug(F111,"cmdlin args 1",*xargv,xargc);
- xx = doarg(x);
- debug(F101,"cmdlin doarg","",xx);
- debug(F111,"cmdlin args 2",*xargv,xargc);
- if (xx < 0) {
-#ifndef NOICP
- if (what == W_COMMAND)
- return(0);
- else
-#endif /* NOICP */
- {
-#ifdef OS2
- sleep(1); /* Give it a chance... */
-#endif /* OS2 */
- doexit(BAD_EXIT,1); /* Go handle option */
- }
- }
- } else if (!haveurl) { /* No dash where expected */
- char xbuf[32];
- char buf[128];
- int k;
- k = ckstrncpy(xbuf,*xargv,40);
- if (k > 30) {
- xbuf[30] = '.';
- xbuf[29] = '.';
- xbuf[28] = '.';
- }
- xbuf[31] = NUL;
- ckmakmsg(buf,
- 128,
- "invalid command-line option, type \"",
- myname,
- " -h\" for help",
- NULL
- );
- fatal2(xbuf,buf);
- }
- }
-#ifdef DEBUG
- if (deblog) {
-#ifndef NOICP
- debug(F101,"cmdlin what","",what);
-#endif /* NOICP */
- debug(F101,"cmdlin action","",action);
-#ifndef NOXFER
- debug(F101,"cmdlin stdouf","",stdouf);
-#endif /* NOXFER */
- }
-#endif /* DEBUG */
-
-#ifdef NOICP
- if (!action && !cflg && !cnflg) {
- debug(F100,"cmdlin NOICP fatal no action","",0);
- XFATAL("?No actions specified on command line");
- }
-#else
- if (inserver && what == 0) { /* Internet Kermit server checks */
- if (local || (action != 0 && action != 'x')) {
- if (local)
- printf("local\r\n");
- if (action)
- printf("action=%c\r\n",action);
- debug(F100,"cmdlin fatal 1","",0);
- XFATAL("No actions or connections allowed with -A");
- }
- }
-#endif /* NOICP */
-
-#ifndef NOLOCAL
- if (!local) {
- if ((action == 'c') || (cflg != 0)) {
- debug(F100,"cmdlin fatal 2","",0);
- XFATAL("-l or -j or -X required");
- }
- }
-#endif /* NOLOCAL */
-#ifndef NOXFER
- if (*cmarg2 != 0) {
- if ((action != 's') && (action != 'r') && (action != 'v')) {
- debug(F100,"cmdlin fatal 3","",0);
- XFATAL("-a without -s, -r, or -g");
- }
- if (action == 'r' || action == 'v') {
-#ifdef CK_TMPDIR
- if (isdir(cmarg2)) { /* -a is a directory */
- if (!zchdir(cmarg2)) { /* try to change to it */
- debug(F100,"cmdlin fatal 4","",0);
- XFATAL("can't change to '-a' directory");
- } else cmarg2 = "";
- } else
-#endif /* CK_TMPDIR */
- if (zchko(cmarg2) < 0) {
- debug(F100,"cmdlin fatal 5","",0);
- XFATAL("write access to -a file denied");
- }
- }
- }
- if ((action == 'v') && (stdouf) && (!local)) {
- if (is_a_tty(1)) {
- debug(F100,"cmdlin fatal 6","",0);
- XFATAL("unredirected -k can only be used in local mode");
- }
- }
- if ((action == 's') || (action == 'v') ||
- (action == 'r') || (action == 'x')) {
- if (local)
- displa = 1;
- if (stdouf) {
- displa = 0;
- quiet = 1;
- }
- }
- if (quiet) displa = 0; /* No display if quiet requested */
-#endif /* NOXFER */
-#ifdef DEBUG
- if (action)
- debug(F000,"cmdlin returns action","",action);
- else
- debug(F101,"cmdlin returns action","",action);
-#endif /* DEBUG */
-
- return(action); /* Then do any requested protocol */
-}
-
-/* Extended argument parsing: --keyword[:value] (or =value) */
-
-/*
- XA_xxxx symbols are defined in ckuusr.h.
- If you add a new one, also remember to update doshow(),
- SHXOPT section, in ckuus5.c.
-*/
-struct keytab xargtab[] = {
-#ifdef CK_LOGIN
- { "anonymous", XA_ANON, CM_ARG|CM_PRE },
-#endif /* CK_LOGIN */
- { "bannerfile", XA_BAFI, CM_ARG },
- { "cdfile", XA_CDFI, CM_ARG },
- { "cdmessage", XA_CDMS, CM_ARG },
- { "cdmsg", XA_CDMS, CM_ARG|CM_INV },
-#ifdef KUI
- { "changedim", XA_CHGD, CM_PRE },
-#endif /* KUI */
-#ifndef NOCSETS
- { "charset", XA_CSET, CM_ARG|CM_PRE },
-#endif /* NOCSETS */
-#ifdef IKSDB
- { "database", XA_DBAS, CM_ARG|CM_PRE },
- { "dbfile", XA_DBFI, CM_ARG|CM_PRE },
-#endif /* IKSDB */
-#ifdef KUI
- { "facename", XA_FNAM, CM_ARG|CM_PRE|CM_INV },
- { "fontname", XA_FNAM, CM_ARG|CM_PRE },
- { "fontsize", XA_FSIZ, CM_ARG|CM_PRE },
-#endif /* KUI */
-#ifdef COMMENT
-#ifdef NEWFTP
- { "ftp", XA_FTP, CM_ARG },
-#endif /* NEWFTP */
-#endif /* COMMENT */
-#ifndef NOLOCAL
-#ifdef OS2
- { "height", XA_ROWS, CM_ARG|CM_PRE },
-#endif /* OS2 */
-#endif /* NOLOCAL */
- { "help", XA_HELP, 0 },
-#ifndef NOHELP
- { "helpfile", XA_HEFI, CM_ARG },
-#endif /* NOHELP */
-#ifdef CK_LOGIN
- { "initfile", XA_ANFI, CM_ARG|CM_PRE },
-#endif /* CK_LOGIN */
-#ifdef OS2
- { "lockdown", XA_LOCK, CM_PRE },
-#ifdef KUI
- { "maximize", XA_WMAX, CM_PRE },
- { "minimize", XA_WMIN, CM_PRE },
- { "nobars", XA_NOBAR, CM_PRE },
- { "noclose" , XA_NOCLOSE, CM_PRE },
-#endif /* KUI */
- { "noescape", XA_NOESCAPE, CM_PRE },
-#endif /* OS2 */
- { "nointerrupts",XA_NOIN, CM_PRE },
-#ifdef KUI
- { "nomenubar", XA_NOMN, CM_PRE },
-#endif /* KUI */
- { "noperms", XA_NPRM, 0 },
-#ifndef NOPUSH
- { "nopush", XA_NOPUSH, CM_PRE },
-#endif /* NOPUSH */
-#ifdef OS2
- { "noscroll", XA_NOSCROLL, CM_PRE },
-#endif /* OS2 */
-#ifdef KUI
- { "nostatusbar", XA_NOSB, CM_PRE },
- { "notoolbar", XA_NOTB, CM_PRE },
-#endif /* KUI */
-#ifdef COMMENT
- { "password", XA_PASS, CM_ARG|CM_INV },
-#endif /* COMMENT */
-#ifdef CK_LOGIN
-#ifndef NOXFER
-#ifdef CK_PERM
- { "permissions", XA_PERM, CM_ARG|CM_PRE },
- { "perms", XA_PERM, CM_ARG|CM_PRE|CM_INV },
-#endif /* CK_PERM */
-#endif /* NOXFER */
-#ifdef UNIX
- { "privid", XA_PRIV, CM_ARG|CM_PRE },
-#endif /* UNIX */
-#ifndef NOLOCAL
-#ifndef NOCSETS
- { "rcharset", XA_CSET, CM_ARG|CM_PRE|CM_INV },
-#endif /* NOCSETS */
-#endif /* NOLOCAL */
-#ifdef UNIX
- { "root", XA_ROOT, CM_ARG|CM_PRE },
-#else /* UNIX */
-#ifdef CKROOT
- { "root", XA_ROOT, CM_ARG|CM_PRE },
-#endif /* CKROOT */
-#endif /* UNIX */
-#ifdef KUI
- { "scalefont", XA_SCALE, CM_PRE },
-#endif /* KUI */
-#ifdef COMMENT
-#ifdef SSHBUILTIN
- { "ssh", XA_SSH, CM_ARG },
-#endif /* SSHBUILTIN */
-#endif /* COMMENT */
-#ifdef CKSYSLOG
- { "syslog", XA_SYSL, CM_ARG|CM_PRE },
-#endif /* CKSYSLOG */
-#ifndef NOLOCAL
-#ifdef COMMENT
-#ifdef TNCODE
- { "telnet", XA_TEL, CM_ARG },
-#endif /* TNCODE */
-#endif /* COMMENT */
- { "termtype", XA_TERM, CM_ARG|CM_PRE },
-#endif /* NOLOCAL */
- { "timeout", XA_TIMO, CM_ARG|CM_PRE },
-#ifndef NOLOCAL
-#ifdef OS2
- { "title", XA_TITL, CM_ARG },
-#endif /* OS2 */
-#ifdef UNIX
- { "unbuffered", XA_UNBUF, 0 },
-#endif /* UNIX */
-#ifndef NOSPL
- { "user", XA_USER, CM_ARG },
-#endif /* NOSPL */
-#endif /* NOLOCAL */
- { "userfile", XA_USFI, CM_ARG|CM_PRE },
- { "version", XA_VERS, 0 },
-#ifndef NOLOCAL
-#ifdef OS2
- { "width", XA_COLS, CM_ARG|CM_PRE },
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef CKWTMP
- { "wtmpfile", XA_WTFI, CM_ARG|CM_PRE },
- { "wtmplog", XA_WTMP, CM_ARG|CM_PRE },
-#endif /* CKWTMP */
-#endif /* CK_LOGIN */
- { "xferfile", XA_IKFI, CM_ARG|CM_PRE },
- { "xferlog", XA_IKLG, CM_ARG|CM_PRE },
-#ifndef NOLOCAL
-#ifdef KUI
- { "xpos", XA_XPOS, CM_ARG|CM_PRE },
- { "ypos", XA_YPOS, CM_ARG|CM_PRE },
-#endif /* KUI */
-#endif /* NOLOCAL */
- {"", 0, 0 }
-};
-int nxargs = sizeof(xargtab)/sizeof(struct keytab) - 1;
-
-static struct keytab oktab[] = {
- { "0", 0, 0 },
- { "1", 1, 0 },
- { "2", 2, 0 },
- { "3", 3, 0 },
- { "4", 4, 0 },
- { "5", 5, 0 },
- { "6", 6, 0 },
- { "7", 7, 0 },
- { "8", 8, 0 },
- { "9", 9, 0 },
- { "false", 0, 0 },
- { "no", 0, 0 },
- { "off", 0, 0 },
- { "ok", 1, 0 },
- { "on", 1, 0 },
- { "true", 1, 0 },
- { "yes", 1, 0 }
-};
-static int noktab = sizeof(oktab)/sizeof(struct keytab);
-
-#define XARGBUFL 32
-
-char * xopthlp[XA_MAX+1]; /* Extended option help */
-char * xarghlp[XA_MAX+1]; /* Extended argument for option */
-
-static VOID
-inixopthlp() {
- int i, j;
- for (i = 0; i <= XA_MAX; i++) { /* Initialize all to null */
- xopthlp[i] = NULL;
- xarghlp[i] = NULL;
- }
- for (i = 0; i < nxargs; i++) { /* Then for each defined keyword */
- j = xargtab[i].kwval; /* index by associated value */
- if (j < 0 || j > XA_MAX)
- continue;
- switch (j) {
-#ifdef CK_LOGIN
- case XA_ANON: /* "--anonymous" */
- xopthlp[j] = "--anonymous:{on,off} [IKSD only]";
- xarghlp[j] = "Whether to allow anonymous IKSD logins";
- break;
-#ifdef UNIX
- case XA_PRIV:
- xopthlp[j] = "--privid:{on,off} [IKSD only]";
- xarghlp[j] = "Whether to allow privileged IDs to login to IKSD";
- break;
-#endif /* UNIX */
-#endif /* CK_LOGIN */
- case XA_BAFI: /* "--bannerfile" */
- xopthlp[j] = "--bannerfile:<filename>";
- xarghlp[j] = "File to display upon startup or IKSD login";
- break;
- case XA_CDFI: /* "--cdfile" */
- xopthlp[j] = "--cdfile:<filename>";
- xarghlp[j] = "File to display when server changes directory";
- break;
- case XA_CDMS: /* "--cdmessage" */
- xopthlp[j] = "--cdmessage:{on,off}";
- xarghlp[j] = "Whether to display CD message file";
- break;
- case XA_HELP: /* "--help" */
- xopthlp[j] = "--help";
- xarghlp[j] = "Print this help text about extended options";
- break;
- case XA_HEFI: /* "--help" */
- xopthlp[j] = "--helpfile:<filename>";
- xarghlp[j] = "File containing custom info for HELP command";
- break;
- case XA_IKFI: /* "--xferfile" */
- xopthlp[j] = "--xferfile:<filename> [IKSD only]";
- xarghlp[j] = "Name of ftpd-like logfile.";
- break;
- case XA_IKLG: /* "--xferlog" */
- xopthlp[j] = "--xferlog:{on,off} [IKSD only]";
- xarghlp[j] = "Whether to keep an ftpd-like logfile.";
- break;
-#ifdef CK_LOGIN
- case XA_ANFI: /* "--initfile" */
- xopthlp[j] = "--initfile:<filename> [IKSD only]";
- xarghlp[j] = "Initialization file for anonymous users.";
- break;
-#ifdef CK_PERM
- case XA_PERM: /* "--permissions" */
- xopthlp[j] = "--permissions:<octalnum> [IKSD only]";
- xarghlp[j] = "Permissions for files uploaded by anonymous users.";
- break;
-#endif /* CK_PERM */
-#ifdef UNIX
- case XA_ROOT: /* "--root" */
- xopthlp[j] = "--root:<directory> [IKSD only]";
- xarghlp[j] = "File-system root for anonymous users.";
- break;
-#else /* UNIX */
-#ifdef CKROOT
- case XA_ROOT: /* "--root" */
- xopthlp[j] = "--root:<directory> [IKSD only]";
- xarghlp[j] = "File-system root for anonymous users.";
- break;
-#endif /* CKROOT */
-#endif /* UNIX */
-#endif /* CK_LOGIN */
-#ifdef CKSYSLOG
- case XA_SYSL: /* "--syslog" */
- xopthlp[j] = "--syslog:<digit> [IKSD only]";
- xarghlp[j] = "Syslog recording level, 0-6.";
- break;
-#endif /* CKSYSLOG */
- case XA_USFI: /* "--userfile" */
- xopthlp[j] = "--userfile:<filename> [IKSD only]";
- xarghlp[j] = "Forbidden user file.";
- break;
-#ifdef CKWTMP
- case XA_WTFI: /* "--wtmpfile" */
- xopthlp[j] = "--wtmpfile:<filename> [IKSD only]";
- xarghlp[j] = "Name of wtmp logfile.";
- break;
- case XA_WTMP: /* "--wtmplog" */
- xopthlp[j] = "--wtmplog:{on,off} [IKSD only]";
- xarghlp[j] = "Whether to keep a wtmp logfile.";
- break;
-#endif /* CKWTMP */
-#ifdef CK_LOGIN
- case XA_TIMO: /* "--timeout" */
- xopthlp[j] = "--timeout:<seconds> [IKSD only]";
- xarghlp[j] =
- "How long to wait for login before closing the connection.";
- break;
-#endif /* CK_LOGIN */
- case XA_NOIN:
- xopthlp[j] = "--nointerrupts";
- xarghlp[j] = "Disable keyboard interrupts.";
- break;
-#ifdef UNIX
- case XA_UNBUF:
- xopthlp[j] = "--unbuffered";
- xarghlp[j] = "Force unbuffered console i/o.";
- break;
-#endif /* UNIX */
-#ifdef IKSDB
- case XA_DBAS:
- xopthlp[j] = "--database:{on,off}";
- xarghlp[j] = "Enable/Disable IKSD database (IKSD only)";
- break;
- case XA_DBFI:
- xopthlp[j] = "--dbfile:<filename>";
- xarghlp[j] = "Specify IKSD database file (IKSD only)";
- break;
-#endif /* IKSDB */
-#ifdef CK_PERMS
- case XA_NPRM:
- xopthlp[j] = "--noperms";
- xarghlp[j] = "Disable file-transfer Permissions attribute.";
- break;
-#endif /* CK_PERMS */
-#ifdef KUI
- case XA_CHGD:
- xopthlp[j] = "--changedim";
- xarghlp[j] = "Change Dimension on Window Resize";
- case XA_SCALE:
- xopthlp[j] = "--scalefont";
- xarghlp[j] = "Scale Font on Window Resize";
- case XA_WMAX:
- xopthlp[j] = "--maximize";
- xarghlp[j] = "start K95G window maximized.";
- break;
- case XA_WMIN:
- xopthlp[j] = "--minimize";
- xarghlp[j] = "start K95G window minimized.";
- break;
- case XA_XPOS:
- xopthlp[j] = "--xpos:n";
- xarghlp[j] = "X-coordinate of window position (number).";
- break;
- case XA_YPOS:
- xopthlp[j] = "--ypos:n";
- xarghlp[j] = "Y-coordinate of window position (number).";
- break;
- case XA_FNAM:
- xopthlp[j] = "--fontname:s (or --facename:s)";
- xarghlp[j] = "Font/typeface name: string with _ replacing blank.";
- break;
- case XA_FSIZ:
- xopthlp[j] = "--fontsize:n";
- xarghlp[j] = "Font point size (number).";
- break;
- case XA_NOMN:
- xopthlp[j] = "--nomenubar";
- xarghlp[j] = "No Menu Bar";
- break;
- case XA_NOTB:
- xopthlp[j] = "--notoolbar";
- xarghlp[j] = "No Tool Bar";
- break;
- case XA_NOSB:
- xopthlp[j] = "--nostatusbar";
- xarghlp[j] = "No Status Bar";
- break;
- case XA_NOBAR:
- xopthlp[j] = "--nobars";
- xarghlp[j] = "No Menu, Status, or Tool Bars";
- break;
-#endif /* KUI */
-#ifndef NOPUSH
- case XA_NOPUSH:
- xopthlp[j] = "--nopush";
- xarghlp[j] = "Disable external command execution.";
- break;
-#endif /* NOPUSH */
-#ifdef OS2
- case XA_LOCK:
- xopthlp[j] = "--lockdown";
- xarghlp[j] = "Enable all lockdown options.";
- break;
- case XA_NOCLOSE:
- xopthlp[j] = "--noclose";
- xarghlp[j] = "Disable Close Window and Menu Exit.";
- break;
- case XA_NOSCROLL:
- xopthlp[j] = "--noscroll";
- xarghlp[j] = "Disable scrollback operations.";
- break;
- case XA_NOESCAPE:
- xopthlp[j] = "--noescape";
- xarghlp[j] = "Disable escape from connect mode.";
- break;
- case XA_ROWS:
- xopthlp[j] = "--height:n";
- xarghlp[j] = "Screen height (number of rows).";
- break;
- case XA_COLS:
- xopthlp[j] = "--width:n";
- xarghlp[j] = "Screen width (number of columns).";
- break;
- case XA_TITL:
- xopthlp[j] = "--title:string";
- xarghlp[j] = "Window Title.";
- break;
-#endif /* OS2 */
- case XA_CSET:
- xopthlp[j] = "--rcharset:name";
- xarghlp[j] = "Name of remote terminal character set.";
- break;
- case XA_TERM:
- xopthlp[j] = "--termtype:name";
-#ifdef OS2
- xarghlp[j] = "Choose terminal emulation.";
-#else
- xarghlp[j] = "Choose terminal type.";
-#endif /* OS2 */
- break;
- case XA_USER:
- xopthlp[j] = "--user:name";
-#ifndef NETCONN
- xarghlp[j] = "Username (for network login)";
-#else
- xarghlp[j] = "Username.";
-#endif /* NETCONN */
- break;
- }
- }
-}
-
-VOID
-iniopthlp() {
- int i;
- for (i = 0; i < 128; i++) {
- optact[i] = 0;
- switch(i) {
-#ifdef OS2
- case '#': /* K95 Startup Flags */
- opthlp[i] = "Kermit 95 Startup Flags";
- arghlp[i] = "\n"\
- " 1 - turn off Win95 special fixes\n"\
- " 2 - do not load optional network dlls\n"\
- " 4 - do not load optional tapi dlls\n"\
- " 8 - do not load optional kerberos dlls\n"\
- " 16 - do not load optional zmodem dlls\n"\
- " 32 - use stdin for input instead of the console\n"\
- " 64 - use stdout for output instead of the console\n"\
- " 128 - do not terminate process in response to Session Logoff";
- break;
-#endif /* OS2 */
- case '0': /* In the middle */
- opthlp[i] =
- "100% transparent CONNECT mode for \"in-the-middle\" operation";
- arghlp[i] = NULL;
- break;
-
- case '8':
- opthlp[i] = "Connection is 8-bit clean";
- arghlp[i] = NULL;
- break;
-
-#ifdef NEWFTP
- case '9':
- opthlp[i] = "Make a connection to an FTP server";
- arghlp[i] = "IP-address-or-hostname[:optional-TCP-port]";
- break;
-#endif /* NEWFTP */
-
-#ifdef IKSD
- case 'A':
- opthlp[i] = "Kermit is to be started as an Internet service";
-#ifdef NT
- arghlp[i] = " socket handle of incoming connection";
-#else /* NT */
- arghlp[i] = NULL;
-#endif /* NT */
- break;
-#endif /* IKSD */
- case 'B': opthlp[i] =
- "Kermit is running in Batch or Background (no controlling terminal)";
- break;
-#ifndef NOSPL
- case 'C':
- opthlp[i] = "Interactive-mode Commands to be executed";
- arghlp[i] = "Commands separated by commas, list in doublequotes";
- break;
-#endif /* NOSPL */
- case 'D':
- opthlp[i] = "Delay before starting to send";
- arghlp[i] = "Number of seconds";
- break;
- case 'E':
- opthlp[i] = "Exit automatically when connection closes";
- arghlp[i] = NULL;
- break;
-#ifdef TCPSOCKET
- case 'F':
- opthlp[i] = "Use an existing TCP connection";
- arghlp[i] = "Numeric file descriptor of open TCP connection";
- break;
-#endif /* TCPSOCKET */
- case 'G':
- opthlp[i] = "GET from server, send to standard output";
- arghlp[i] = "Remote file specification";
- optact[i] = 1;
- break;
- case 'H':
- opthlp[i] = "Suppress program startup Herald and greeting";
- arghlp[i] = NULL;
- break;
- case 'I':
- opthlp[i] = "Connection is reliable, streaming is allowed";
- arghlp[i] = NULL;
- break;
-#ifdef TCPSOCKET
- case 'J':
- opthlp[i] = "'Be like Telnet'";
- arghlp[i] = "IP hostname/address optionally followed by service";
- break;
-#endif /* TCPSOCKET */
- case 'L':
- opthlp[i] = "Recursive directory descent for files in -s option";
- arghlp[i] = NULL;
- break;
- case 'M':
- opthlp[i] = "My user name (for use with Telnet, Rlogin, etc)";
- arghlp[i] = "Username string";
- break;
-#ifdef NETBIOS
- case 'N':
- opthlp[i] = "NETBIOS adapter number";
- arghlp[i] = "Number";
- break;
-#endif /* NETBIOS */
- case 'O': /* Be a server for One command only */
- opthlp[i] = "Be a server for One command only";
- arghlp[i] = NULL;
- optact[i] = 1;
- break;
- case 'P':
- opthlp[i] = "Don't convert file (Path) names";
- arghlp[i] = NULL;
- break;
- case 'Q':
- opthlp[i] = "Quick (FAST) Kermit protocol settings";
- arghlp[i] = NULL;
- break;
- case 'R': /* Remote-Only */
- opthlp[i] = "Remote-only (makes IF REMOTE true)";
- arghlp[i] = NULL;
- break;
- case 'S': /* "Stay" - enter interactive */
- opthlp[i] = "Stay (enter command parser after action options)";
- arghlp[i] = NULL;
- break;
- case 'T': /* Text file transfer mode */
- opthlp[i] = "Transfer files in Text mode";
- arghlp[i] = NULL;
- break;
-#ifdef ANYX25
- case 'U': /* X.25 call user data */
- opthlp[i] = "X.25 call User data";
- arghlp[i] = "Call-user-data string";
- break;
-#endif /* ANYX25 */
- case 'V': /* No automatic filetype switching */
- opthlp[i] = "Disable automatic per-file text/binary switching";
- arghlp[i] = NULL;
- break;
-#ifdef COMMENT
-#ifdef OS2
- case 'W': /* Win32 Window Handle */
- opthlp[i] = "";
- arghlp[i] = NULL;
- break;
-#endif /* OS2 */
-#endif /* COMMENT */
-#ifdef ANYX25
- case 'X': /* SET HOST to X.25 address */
- opthlp[i] = "Make an X.25 connection";
- arghlp[i] = "X.25 or X.121 address";
- break;
-#endif /* ANYX25 */
- case 'Y': /* No initialization file */
- opthlp[i] = "Skip initialization file";
- arghlp[i] = NULL;
- break;
-#ifdef ANYX25
- case 'Z': /* SET HOST to X.25 file descriptor */
- opthlp[i] = "Make an X.25 connection";
- arghlp[i] = "Numeric file descriptor of open X.25 connection";
- break;
-#endif /* ANYX25 */
- case 'a': /* as-name */
- opthlp[i] = "As-name for file(s) in -s, -r, or -g";
- arghlp[i] = "As-name string (alternative filename)";
- break;
- case 'b': /* Set bits-per-second for serial */
- opthlp[i] = "Speed for serial device";
- arghlp[i] = "Numeric Bits per second";
- break;
- case 'c': /* Connect before */
- optact[i] = 1;
- opthlp[i] = "CONNECT before transferring files";
- arghlp[i] = NULL;
- break;
- case 'd': /* DEBUG */
- opthlp[i] = "Create debug.log file (a second -d adds timestamps)";
- arghlp[i] = NULL;
- break;
- case 'e': /* Extended packet length */
- opthlp[i] = "Maximum length for incoming file-transfer packets";
- arghlp[i] = "Length in bytes";
- break;
- case 'f': /* finish */
- optact[i] = 1;
- opthlp[i] = "Send Finish command to a Kermit server";
- arghlp[i] = NULL;
- break;
- case 'g': /* get */
- optact[i] = 1;
- opthlp[i] = "GET file(s) from a Kermit server";
- arghlp[i] = "Remote file specification";
- break;
- case 'h': /* help */
- optact[i] = 1;
-#ifdef OS2ORUNIX
- opthlp[i] =
- "Print this message (pipe thru 'more' to prevent scrolling)";
-#else
- "Print this message";
-#endif /* OS2ORUNIX */
- arghlp[i] = NULL;
- break;
- case 'i': /* Treat files as binary */
- opthlp[i] ="Transfer files in binary mode";
- arghlp[i] = NULL;
- break;
-#ifdef TCPSOCKET
- case 'j': /* SET HOST (TCP/IP socket) */
- opthlp[i] = "Make a TCP connection";
- arghlp[i] =
- "TCP host name/address and optional service name or number";
- break;
-#endif /* TCPSOCKET */
- case 'k': /* receive to stdout */
- optact[i] = 1;
- opthlp[i] = "RECEIVE file(s) to standard output";
- arghlp[i] = NULL;
- break;
- case 'l': /* SET LINE */
- opthlp[i] = "Make connection on serial communications device";
- arghlp[i] = "Serial device name";
- break;
- case 'm': /* Modem type */
- opthlp[i] = "Modem type for use with -l device";
- arghlp[i] = "Modem name as in SET MODEM TYPE command";
- break;
- case 'n': /* connect after */
- optact[i] = 1;
- opthlp[i] = "CONNECT after transferring files";
- arghlp[i] = NULL;
- break;
-#ifdef ANYX25
- case 'o': /* X.25 closed user group */
- opthlp[i] = "X.25 closed user group";
- arghlp[i] = "User group string";
- break;
-#endif /* ANYX25 */
- case 'p': /* SET PARITY */
- opthlp[i] = "Parity";
- arghlp[i] = "One of the following: even, odd, mark, none, space";
- break;
- case 'q': /* Quiet */
- opthlp[i] = "Quiet (suppress most messages)";
- arghlp[i] = NULL;
- break;
- case 'r': /* receive */
- optact[i] = 1;
- opthlp[i] = "RECEIVE file(s)";
- arghlp[i] = NULL;
- break;
- case 's': /* send */
- optact[i] = 1;
- opthlp[i] = "SEND file(s)";
- arghlp[i] = "One or more file specifications";
- break;
- case 't': /* Line turnaround handshake */
- opthlp[i] = "XON Turnaround character for half-duplex connections";
- arghlp[i] = NULL;
- break;
-#ifdef ANYX25
- case 'u': /* X.25 reverse charge call */
- opthlp[i] = "X.25 reverse charge call";
- arghlp[i] = NULL;
- break;
-#endif /* ANYX25 */
- case 'v': /* Vindow size */
- opthlp[i] = "Window size";
- arghlp[i] = "Number, 1 to 32";
- break;
- case 'w': /* Writeover */
- opthlp[i] = "Incoming files Write over existing files";
- arghlp[i] = NULL;
- break;
- case 'x': /* Server */
- optact[i] = 1;
- opthlp[i] = "Be a Kermit SERVER";
- arghlp[i] = NULL;
- break;
- case 'y': /* Alternate init-file name */
- opthlp[i] = "Alternative initialization file";
- arghlp[i] = "File specification";
- break;
- case 'z': /* Not background */
- opthlp[i] = "Force foreground behavior";
- arghlp[i] = NULL;
- break;
- default:
- opthlp[i] = NULL;
- arghlp[i] = NULL;
- }
- }
- inixopthlp();
-}
-
-int
-doxarg(s,pre) char ** s; int pre; {
-#ifdef IKSD
-#ifdef CK_LOGIN
- extern int ckxsyslog, ckxwtmp, ckxanon;
-#ifdef UNIX
- extern int ckxpriv;
-#endif /* UNIX */
-#ifdef CK_PERMS
- extern int ckxperms;
-#endif /* CK_PERMS */
- extern char * anonfile, * userfile, * anonroot;
-#endif /* CK_LOGIN */
-#ifdef CKWTMP
- extern char * wtmpfile;
-#endif /* CKWTMP */
-#endif /* IKSD */
- extern int srvcdmsg;
- extern char * cdmsgfile[], * cdmsgstr;
- char tmpbuf[CKMAXPATH+1];
-
- int i, x, y, z, havearg = 0;
- char buf[XARGBUFL], c, * p;
-
- if (nxargs < 1)
- return(-1);
-
- c = *(*s + 1); /* Hyphen or Plus sign */
-
- p = *s + 2;
- for (i = 0; *p && i < XARGBUFL; i++) {
- buf[i] = *p++;
- if (buf[i] == '=' || buf[i] == ':') {
- havearg = 1;
- buf[i] = NUL;
- break;
- } else if (buf[i] < ' ') {
- buf[i] = NUL;
- break;
- }
- }
- if (i > XARGBUFL - 1)
- return(-1);
- buf[i] = NUL;
-
- x = lookup(xargtab,buf,nxargs,&z); /* Lookup the option keyword */
-
- if (x < 0) /* On any kind of error */
- return(-1); /* fail. */
-
- /* Handle prescan versus post-initialization file */
-
- if (((xargtab[z].flgs & CM_PRE) || (c == '+')) && !pre)
- return(0);
- else if (pre && !(xargtab[z].flgs & CM_PRE) && (c != '+'))
- return(0);
-
- /* Ensure that argument is given if and only if required */
-
- p = havearg ? *s + i + 3 : NULL;
-
- if ((xargtab[z].flgs & CM_ARG) && !havearg)
- return(-1);
- else if ((!(xargtab[z].flgs & CM_ARG)) && havearg)
- return(-1);
-
- switch (x) { /* OK to process this option... */
-#ifdef CKSYSLOG
- case XA_SYSL: /* IKS: Syslog level */
- y = 0;
- if (isdigit(*p)) {
- while (*p) {
- if (*p < '0' || *p > '9')
- return(-1);
- y = y * 10 + (*p++ - '0');
- }
- } else {
- y = lookup(oktab,p,noktab,&z);
- if (y > 0) y = SYSLG_DF; /* Yes = default logging level */
- }
-#ifndef SYSLOGLEVEL
- /* If specified on cc command line, user can't change it. */
- if (!inserver) /* Don't allow voluminous syslogging */
- if (y > SYSLG_FA) /* by ordinary users. */
- y = SYSLG_FA;
-#endif /* SYSLOGLEVEL */
- if (y < 0) return(-1);
-#ifdef DEBUG
- if (y >= SYSLG_DB)
- if (!deblog)
- deblog = debopn("debug.log",0);
-#endif /* DEBUG */
-#ifdef SYSLOGLEVEL
- /* If specified on cc command line, user can't change it. */
- y = SYSLOGLEVEL;
-#endif /* SYSLOGLEVEL */
- ckxsyslog = y;
- /* printf("ckxsyslog=%d\n",ckxsyslog); */
- break;
-#endif /* CKSYSLOG */
-
-#ifdef CK_LOGIN
-#ifdef CKWTMP
- case XA_WTMP: /* IKS: wtmp log */
- y = lookup(oktab,p,noktab,&z);
- if (y < 0) return(-1);
- ckxwtmp = y;
- /* printf("ckxwtmp=%d\n",ckxwtmp); */
- break;
-
- case XA_WTFI: /* IKS: wtmp logfile */
- if (zfnqfp(p,CKMAXPATH,tmpbuf))
- p = tmpbuf;
- makestr(&wtmpfile,p);
- /* printf("wtmpfile=%s\n",wtmpfile); */
- break;
-#endif /* CKWTMP */
-
- case XA_ANON: /* IKS: Anonymous login allowed */
- y = lookup(oktab,p,noktab,&z);
- if (y < 0) return(-1);
- ckxanon = y;
- /* printf("ckxanon=%d\n",ckxanon); */
- break;
-
-#ifdef UNIX
- case XA_PRIV: /* IKS: Priv'd login allowed */
- y = lookup(oktab,p,noktab,&z);
- if (y < 0) return(-1);
- ckxpriv = y;
- /* printf("ckxpriv=%d\n",ckxpriv); */
- break;
-#endif /* UNIX */
-
-#ifdef CK_PERMS
- case XA_PERM: /* IKS: Anonymous Upload Permissions */
- y = 0;
- while (*p) {
- if (*p < '0' || *p > '7')
- return(-1);
- y = y * 8 + (*p++ - '0');
- }
- ckxperms = y;
- /* printf("ckxperms=%04o\n",ckxperms); */
- break;
-#endif /* CK_PERMS */
-
- case XA_ANFI: /* Anonymous init file */
- if (!isabsolute(p))
- if (zfnqfp(p,CKMAXPATH,tmpbuf))
- p = tmpbuf;
- makestr(&anonfile,p);
- /* printf("anonfile=%s\n",anonfile); */
- break;
-
- case XA_USFI: /* IKS: Forbidden user file */
- if (!isabsolute(p))
- if (zfnqfp(p,CKMAXPATH,tmpbuf))
- p = tmpbuf;
- makestr(&userfile,p);
- /* printf("userfile=%s\n",userfile); */
- break;
-
- case XA_ROOT: /* IKS: Anonymous root */
- if (!isabsolute(p))
- if (zfnqfp(p,CKMAXPATH,tmpbuf))
- p = tmpbuf;
- makestr(&anonroot,p);
- /* printf("anonroot=%s\n",anonroot); */
- break;
-#endif /* CK_LOGIN */
-
- case XA_CDFI: /* CD filename */
-#ifdef COMMENT
- /* Do NOT expand this one! */
- if (zfnqfp(p,CKMAXPATH,tmpbuf))
- p = tmpbuf;
-#endif /* COMMENT */
- makelist(p,cdmsgfile,16);
- makestr(&cdmsgstr,p);
- /* printf("cdmsgstr=%s\n",cdmsgstr); */
- break;
-
- case XA_CDMS: /* CD messages */
- y = lookup(oktab,p,noktab,&z);
- if (y < 0) return(-1);
- srvcdmsg = y;
- /* printf("srvcdmsg=%d\n",srvcdmsg); */
- break;
-
-#ifndef NOXFER
- case XA_IKLG: /* Transfer log on/off */
- y = lookup(oktab,p,noktab,&z);
- if (y < 0) return(-1);
- xferlog = y;
- /* printf("xferlog=%d\n",xferlog); */
- break;
-
- case XA_IKFI: /* Transfer log file */
- if (!isabsolute(p))
- if (zfnqfp(p,CKMAXPATH,tmpbuf))
- p = tmpbuf;
- makestr(&xferfile,p);
- xferlog = 1;
- /* printf("xferfile=%s\n",xferfile); */
- break;
-
- case XA_BAFI: /* IKS: banner (greeting) file */
- if (!isabsolute(p))
- if (zfnqfp(p,CKMAXPATH,tmpbuf))
- p = tmpbuf;
- makestr(&bannerfile,p);
- /* printf("bannerfile=%s\n",bannerfile); */
- break;
-#endif /* NOXFER */
-
-#ifndef NOHELP
- case XA_HELP: /* Help */
- /* printf("help\n"); */
- for (i = 0; i <= XA_MAX; i++)
- if (xopthlp[i])
- printf("%s\n %s\n\n",xopthlp[i],xarghlp[i]);
- if (stayflg || what == W_COMMAND)
- break;
- else
- doexit(GOOD_EXIT,-1);
-#endif /* NOHELP */
-
-#ifndef NOHELP
- case XA_HEFI: /* IKS: custom help file */
- if (!isabsolute(p))
- if (zfnqfp(p,CKMAXPATH,tmpbuf))
- p = tmpbuf;
- makestr(&helpfile,p);
- /* printf("helpfile=%s\n",helpfile); */
- break;
-#endif /* NOHELP */
-
-#ifdef CK_LOGIN
- case XA_TIMO:
- if (!rdigits(p))
- return(-1);
- logintimo = atoi(p);
- /* printf("logintimo=%d\n",p); */
- break;
-#endif /* CK_LOGIN */
-
- case XA_NOIN: /* No interrupts */
-#ifndef NOICP
- cmdint = 0;
-#endif /* NOICP */
- xsuspend = 0;
- break;
-
-#ifdef UNIX
- case XA_UNBUF: /* Unbuffered console i/o*/
- break; /* This one is handled in ckcmai.c */
-#endif /* UNIX */
-
-#ifdef IKSDB
- case XA_DBFI: {
- extern char * dbdir, * dbfile;
- extern int dbenabled;
- struct zfnfp * zz;
- if ((zz = zfnqfp(p,CKMAXPATH,tmpbuf))) {
- char *s, *s2 = NULL;
- makestr(&dbdir,zz->fpath);
- makestr(&dbfile,zz->fpath);
- for (s = dbdir; *s; s++) {
- if (ISDIRSEP(*s))
- s2 = s+1;
- }
- if (s2) *s2 = NUL;
- debug(F110,"XA_DBFI dbdir",dbdir,0);
- debug(F110,"XA_DBFI dbfile",dbfile,0);
- dbenabled = 1;
- }
- break;
- }
- case XA_DBAS: {
- extern int dbenabled;
- y = lookup(oktab,p,noktab,&z);
- if (y < 0) return(-1);
- dbenabled = y;
- break;
- }
-#endif /* IKSDB */
-
- case XA_VERS: {
- extern char * ck_s_ver, * ck_s_xver;
- printf("%s",ck_s_ver);
- if (*ck_s_xver)
- printf(" [%s]\n",ck_s_xver);
- printf("\n");
- if (stayflg || what == W_COMMAND)
- break;
- else
- doexit(GOOD_EXIT,-1);
- }
-#ifndef NOXFER
-#ifdef CK_PERMS
- case XA_NPRM: {
- extern int atlpri, atlpro, atgpri, atgpro;
- atlpri = 0;
- atlpro = 0;
- atgpri = 0;
- atgpro = 0;
- break;
- }
-#endif /* CK_PERMS */
-#endif /* NOXFER */
-
-#ifdef KUI
- case XA_SCALE:
- kui_init.resizeMode = 1;
- break;
- case XA_CHGD:
- kui_init.resizeMode = 2;
- break;
- case XA_WMAX:
- kui_init.nCmdShow = SW_MAXIMIZE;
- break;
- case XA_WMIN:
- kui_init.nCmdShow = SW_MINIMIZE;
- break;
-
- case XA_XPOS:
- if (!rdigits(p))
- return(-1);
- kui_init.pos_init++;
- kui_init.pos_x = atoi(p);
- break;
-
- case XA_YPOS:
- if (!rdigits(p))
- return(-1);
- kui_init.pos_init++;
- kui_init.pos_y = atoi(p);
- break;
-
- case XA_FNAM: {
- extern struct _kui_init kui_init;
- extern struct keytab * term_font;
- extern struct keytab * _term_font;
- extern int tt_font, ntermfont;
- int x, z;
- if (ntermfont == 0)
- BuildFontTable(&term_font, &_term_font, &ntermfont);
- if (!(term_font && _term_font && ntermfont > 0)) {
- printf("?Unable to construct Font Facename Table\n");
- return(0);
- }
- x = lookup(term_font,p,ntermfont,&z);
- if (x < 0) {
- x = lookup(_term_font,p,ntermfont,&z);
- if (x < 0) {
- printf("?Invalid Font Facename: %s\n",p);
- return(0);
- }
- }
- tt_font = x;
- kui_init.face_init++;
- makestr(&kui_init.facename,term_font[z].kwd);
- break;
- }
- case XA_FSIZ: {
- extern struct _kui_init kui_init;
- extern int tt_font_size;
- char * q;
- int halfpoint = 0;
-
- kui_init.font_init++;
- for ( q=p ; *q ; q++ ) {
- if ( *q == '.') {
- *q++ = '\0';
- if (!rdigits(q))
- return(-1);
- if (!*q || atoi(q) == 0)
- break; /* no halfpoint */
- halfpoint = 1;
- if (atoi(q) != 5)
- printf("? Font sizes are treated in half-point increments\n");
- break;
- }
- }
- if (!rdigits(p))
- return(-1);
- tt_font_size = kui_init.font_size = 2 * atoi(p) + halfpoint;
- break;
- }
- case XA_NOMN:
- kui_init.nomenubar = 1;
- break;
- case XA_NOTB:
- kui_init.notoolbar = 1;
- break;
- case XA_NOSB:
- kui_init.nostatusbar = 1;
- break;
- case XA_NOBAR:
- kui_init.nomenubar = 1;
- kui_init.notoolbar = 1;
- kui_init.nostatusbar = 1;
- break;
-#endif /* KUI */
-
-#ifndef NOPUSH
- case XA_NOPUSH:
- nopush = 1;
- break;
-#endif /* NOPUSH */
-#ifdef OS2
- case XA_LOCK:
- tt_scroll = 0;
- tt_escape = 0;
-#ifndef NOPUSH
- nopush = 1;
-#endif
-#ifdef KUI
- kui_init.nomenubar = 1;
- kui_init.notoolbar = 1;
- kui_init.nostatusbar = 1;
-#endif
- break;
-#ifdef KUI
- case XA_NOCLOSE:
- kui_init.noclose = 1;
- break;
-#endif /* KUI */
- case XA_NOSCROLL:
- tt_scroll = 0;
- break;
- case XA_NOESCAPE:
- tt_escape = 0;
- break;
-#endif /* OS2 */
-
-#ifndef NOLOCAL
- case XA_TERM: { /* Terminal type */
- extern struct keytab ttyptab[];
- extern int nttyp;
-#ifdef TNCODE
- extern char * tn_term;
-#endif /* TNCODE */
-#ifdef OS2
- int x, z;
- extern int tt_type, tt_type_mode;
- x = lookup(ttyptab,p,nttyp,&z);
- if (x < 0)
- return(-1);
- tt_type_mode = tt_type = x;
-#endif /* OS2 */
-#ifdef TNCODE
- makestr(&tn_term,p);
-#endif /* TNCODE */
- break;
- }
- case XA_CSET: { /* Remote Character Set */
-#ifndef NOCSETS
-#ifdef CKOUNI
- extern struct keytab txrtab[];
- extern int ntxrtab;
- x = lookup(txrtab,p,ntxrtab,&z);
-#else /* CKOUNI */
- extern struct keytab ttcstab[];
- extern int ntermc;
- x = lookup(ttcstab,p,ntermc,&z);
-#endif /* CKOUNI */
- if (x < 0)
- return(-1);
- setremcharset(z,4 /* TT_GR_ALL (in ckuus7.c) */);
-#else /* NOCSETS */
- return(-1);
-#endif /* NOCSETS */
- break;
- }
- case XA_ROWS: { /* Screen rows (height) */
-#ifdef OS2
- extern int row_init;
-#else /* OS2 */
- extern int tt_rows;
-#endif /* OS2 */
- if (!rdigits(p))
- return(-1);
-#ifdef OS2
- if (!os2_settermheight(atoi(p)))
- return(-1);
- row_init++;
-#else /* Not OS/2 */
- tt_rows = atoi(p);
-#endif /* OS2 */
- break;
- }
- case XA_COLS: { /* Screen columns (width) */
-#ifdef OS2
- extern int col_init;
-#else /* OS2 */
- extern int tt_cols;
-#endif /* OS2 */
- if (!rdigits(p))
- return(-1);
-#ifdef OS2
- if (!os2_settermwidth(atoi(p)))
- return(-1);
- col_init++;
-#else /* Not OS/2 */
- tt_cols = atoi(p);
-#endif /* OS2 */
- break;
- }
-#ifdef OS2
- case XA_TITL: {
- extern char usertitle[];
- ckstrncpy(usertitle,p,64);
- os2settitle("",1);
- break;
- }
-#endif /* OS2 */
-
-#ifdef COMMENT /* TO BE FILLED IN ... */
- case XA_TEL: /* Make a Telnet connection */
- case XA_FTP: /* Make an FTP connection */
- case XA_SSH: /* Make an SSH connection */
-#endif /* COMMENT */
-
-#ifndef NOSPL
- case XA_USER: /* Username for login */
-#ifdef IKSD
- if (!inserver)
-#endif /* IKSD */
- {
- ckstrncpy(uidbuf,*xargv,UIDBUFLEN);
- haveftpuid = 1;
- }
- break;
-#endif /* NOSPL */
-#endif /* NOLOCAL */
-
- default:
- return(-1);
- }
- return(0);
-}
-
-#ifdef IKSD
-#ifdef IKSDCONF
-#define IKS_ANON 0
-#define IKS_BAFI 1
-#define IKS_CDFI 2
-#define IKS_CDMS 3
-#define IKS_HEFI 4
-#define IKS_ANFI 5
-#define IKS_USFI 6
-#define IKS_IKLG 7
-#define IKS_IKFI 8
-#define IKS_DBAS 9
-#define IKS_DBFI 10
-#define IKS_PERM 11
-#define IKS_PRIV 12
-#define IKS_ROOT 13
-#define IKS_TIMO 14
-#define IKS_WTFI 15
-#define IKS_WTMP 16
-#define IKS_SRVR 17
-#define IKS_NOIN 18
-#define IKS_INIT 19
-#define IKS_ANLG 20
-#define IKS_ACCT 21
-#define IKS_NTDOM 22
-#define IKS_SYSL 23
-
-#ifdef CK_LOGIN
-static struct keytab iksantab[] = {
-#ifdef OS2
- { "account", IKS_ACCT, 0 },
-#endif /* OS2 */
- { "initfile", IKS_ANFI, 0 },
- { "login", IKS_ANLG, 0 },
-#ifdef UNIX
- { "root", IKS_ROOT, 0 },
-#else
-#ifdef CKROOT
- { "root", IKS_ROOT, 0 },
-#endif /* CKROOT */
-#endif /* UNIX */
- { "", 0, 0 }
-};
-static int niksantab = sizeof(iksantab) / sizeof(struct keytab) - 1;
-#endif /* CK_LOGIN */
-
-static struct keytab ikstab[] = {
-#ifdef CK_LOGIN
- { "anonymous", IKS_ANON, 0 },
-#endif /* CK_LOGIN */
- { "bannerfile", IKS_BAFI, 0 },
- { "cdfile", IKS_CDFI, 0 },
- { "cdmessage", IKS_CDMS, 0 },
- { "cdmsg", IKS_CDMS, CM_INV },
-#ifdef IKSDB
- { "database", IKS_DBAS, 0 },
- { "dbfile", IKS_DBFI, 0 },
-#endif /* IKSDB */
-#ifdef CK_LOGIN
-#ifdef NT
- { "default-domain", IKS_NTDOM, 0 },
-#endif /* NT */
-#endif /* CK_LOGIN */
-#ifndef NOHELP
- { "helpfile", IKS_HEFI, 0 },
-#endif /* NOHELP */
- { "initfile", IKS_INIT, 0 },
- { "no-initfile", IKS_NOIN, 0 },
-#ifdef CK_LOGIN
-#ifdef CK_PERM
- { "permissions", IKS_PERM, 0 },
- { "perms", IKS_PERM, CM_INV },
-#endif /* CK_PERM */
-#ifdef UNIX
- { "privid", IKS_PRIV, 0 },
-#endif /* UNIX */
- { "server-only", IKS_SRVR, 0 },
-#ifdef CKSYSLOG
- { "syslog", IKS_SYSL, 0 },
-#endif /* CKSYSLOG */
- { "timeout", IKS_TIMO, 0 },
- { "userfile", IKS_USFI, 0 },
-#ifdef CKWTMP
- { "wtmpfile", IKS_WTFI, 0 },
- { "wtmplog", IKS_WTMP, 0 },
-#endif /* CKWTMP */
-#endif /* CK_LOGIN */
- { "xferfile", IKS_IKFI, 0 },
- { "xferlog", IKS_IKLG, 0 }
-};
-static int nikstab = sizeof(ikstab) / sizeof(struct keytab);
-#endif /* IKSDCONF */
-
-#ifndef NOICP
-int
-setiks() { /* SET IKS */
-#ifdef IKSDCONF
-#ifdef CK_LOGIN
- extern int ckxsyslog, ckxwtmp, ckxanon;
-#ifdef UNIX
- extern int ckxpriv;
-#endif /* UNIX */
-#ifdef CK_PERMS
- extern int ckxperms;
-#endif /* CK_PERMS */
- extern char * anonfile, * userfile, * anonroot;
-#ifdef OS2
- extern char * anonacct;
-#endif /* OS2 */
-#ifdef NT
- extern char * iks_domain;
-#endif /* NT */
-#endif /* CK_LOGIN */
-#ifdef CKWTMP
- extern char * wtmpfile;
-#endif /* CKWTMP */
- extern int srvcdmsg, success, iksdcf, rcflag, noinit, arg_x;
- extern char * cdmsgfile[], * cdmsgstr, *kermrc;
- extern xx_strp xxstring;
- int x, y, z;
- char *s;
- char tmpbuf[CKMAXPATH+1];
-
- if ((y = cmkey(ikstab,nikstab,"","",xxstring)) < 0)
- return(y);
-
-#ifdef CK_LOGIN
- if (y == IKS_ANON) {
- if ((y = cmkey(iksantab,niksantab,"","",xxstring)) < 0)
- return(y);
- }
-#endif /* CK_LOGIN */
-
- switch (y) {
-#ifdef CKSYSLOG
- case IKS_SYSL: /* IKS: Syslog level */
- if ((z = cmkey(oktab,noktab,"","",xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
-#ifndef SYSLOGLEVEL
- /* If specified on cc command line, user can't change it. */
- if (!inserver) /* Don't allow voluminous syslogging */
- if (y > SYSLG_FA) /* by ordinary users. */
- y = SYSLG_FA;
-#endif /* SYSLOGLEVEL */
- if (y < 0) return(-1);
-#ifdef DEBUG
- if (y >= SYSLG_DB)
- if (!deblog)
- deblog = debopn("debug.log",0);
-#endif /* DEBUG */
-#ifdef SYSLOGLEVEL
- /* If specified on cc command line, user can't change it. */
- y = SYSLOGLEVEL;
-#endif /* SYSLOGLEVEL */
- ckxsyslog = y;
- /* printf("ckxsyslog=%d\n",ckxsyslog); */
- break;
-#endif /* CKSYSLOG */
-
-#ifdef CK_LOGIN
-#ifdef NT
- case IKS_NTDOM:
- if ((z = cmtxt(
- "DOMAIN to be used for user authentication when none is specified",
- "", &s,xxstring)) < 0)
- return(z);
- if (iksdcf) return(success = 0);
- if (!*s) s= NULL;
- makestr(&iks_domain,s);
- break;
-#endif /* NT */
-#ifdef OS2
- case IKS_ACCT:
- if ((z = cmtxt("Name of local account to use for anonymous logins",
- "GUEST", &s,xxstring)) < 0)
- return(z);
- if (iksdcf) return(success = 0);
- if (*s) {
- makestr(&anonacct,s);
- } else if ( anonacct ) {
- free(anonacct);
- anonacct = NULL;
- }
- break;
-#endif /* OS2 */
- case IKS_ANLG:
- if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- ckxanon = z;
-#ifdef OS2
- if (ckxanon && !anonacct)
- makestr(&anonacct,"GUEST");
-#endif /* OS2 */
- break;
-#endif /* CK_LOGIN */
- case IKS_BAFI:
- if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
- return(z);
- if (x) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
- debug(F110,"bannerfile before zfnqfp()",s,0);
- if (zfnqfp(s,CKMAXPATH,tmpbuf)) {
- debug(F110,"bannerfile after zfnqfp()",tmpbuf,0);
- s = tmpbuf;
- }
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- if (*s)
- makestr(&bannerfile,s);
- break;
- case IKS_CDFI:
- if ((z = cmtxt("list of cd message file names","READ.ME",
- &s,xxstring)) < 0)
- return(z);
- if (iksdcf) return(success = 0);
- if (*s) {
- makelist(s,cdmsgfile,16);
- makestr(&cdmsgstr,s);
- }
- break;
- case IKS_CDMS:
- if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- srvcdmsg = z;
- break;
- case IKS_HEFI:
- if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
- return(z);
- if (x) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
- if (zfnqfp(s,CKMAXPATH,tmpbuf))
- s = tmpbuf;
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- if (*s)
- makestr(&helpfile,s);
- break;
- case IKS_ANFI:
- if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
- return(z);
- if (x) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
- if (zfnqfp(s,CKMAXPATH,tmpbuf))
- s = tmpbuf;
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- if (*s)
- makestr(&anonfile,s);
- break;
- case IKS_USFI:
- if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
- return(z);
- if (x) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
- if (zfnqfp(s,CKMAXPATH,tmpbuf))
- s = tmpbuf;
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- if (*s)
- makestr(&userfile,s);
- break;
- case IKS_IKFI:
- if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
- return(z);
- if (x) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
- if (zfnqfp(s,CKMAXPATH,tmpbuf))
- s = tmpbuf;
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- if (*s) {
- makestr(&xferfile,s);
- xferlog = 1;
- }
- break;
- case IKS_IKLG:
- if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- xferlog = z;
- break;
-
-#ifdef CK_LOGIN
-#ifdef CK_PERM
- case IKS_PERM:
- if ((z = cmtxt("Octal file permssion code","000",
- &s,xxstring)) < 0)
- return(z);
- if (z < 0) return(z);
- if (iksdcf) return(success = 0);
- y = 0;
- while (*s) {
- if (*s < '0' || *s > '7')
- return(-9);
- y = y * 8 + (*s++ - '0');
- }
- ckxperms = y;
- break;
-#endif /* CK_PERM */
-#ifdef UNIX
- case IKS_PRIV: /* IKS: Priv'd login allowed */
- if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- ckxpriv = z;
- break;
-#endif /* UNIX */
-
- case IKS_ROOT: /* IKS: Anonymous root */
- if ((z = cmdir("Name of disk and/or directory","",&s,
- xxstring)) < 0 ) {
- if (z != -3)
- return(z);
- }
- if (*s) {
- if (zfnqfp(s,CKMAXPATH,tmpbuf))
- s = tmpbuf;
- } else
- s = "";
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- if (*s)
- makestr(&anonroot,s);
- /* printf("anonroot=%s\n",anonroot); */
- break;
-
- case IKS_TIMO:
- z = cmnum("login timeout, seconds","0",10,&x,xxstring);
- if (z < 0) return(z);
- if (x < 0 || x > 7200) {
- printf("?Value must be between 0 and 7200\r\n");
- return(-9);
- }
- if ((z = cmcfm()) < 0) return(z);
- if (iksdcf) return(success = 0);
- logintimo = x;
- break;
-
-#ifdef CKWTMP
- case IKS_WTMP: /* IKS: wtmp log */
- if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- ckxwtmp = z;
- break;
-
- case IKS_WTFI: /* IKS: wtmp logfile */
- if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
- return(z);
- if (x) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
- if (zfnqfp(s,CKMAXPATH,tmpbuf))
- s = tmpbuf;
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- if (*s)
- makestr(&wtmpfile,s);
- break;
-#endif /* CKWTMP */
-#endif /* CK_LOGIN */
-#ifdef IKSDB
- case IKS_DBFI: {
- extern char * dbdir, * dbfile;
- extern int dbenabled;
- struct zfnfp * zz;
- if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
- return(z);
- if (x) {
- printf("?Wildcards not allowed\n");
- return(-9);
- }
- zz = zfnqfp(s,CKMAXPATH,tmpbuf);
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- if (zz) {
- makestr(&dbdir,zz->fpath);
- makestr(&dbfile,(char *)tmpbuf);
- dbenabled = 1;
- } else
- return(success = 0);
- break;
- }
- case IKS_DBAS: {
- extern int dbenabled;
- if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- dbenabled = z;
- break;
- }
-#endif /* IKSDB */
-
- case IKS_INIT:
- if ((z = cmtxt("Alternate init file specification","",
- &s,xxstring)) < 0)
- return(z);
- if (z < 0) return(z);
- if (iksdcf) return(success = 0);
- ckstrncpy(kermrc,s,KERMRCL);
- rcflag = 1; /* Flag that this has been done */
- break;
-
- case IKS_NOIN:
- if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- noinit = z;
- break;
-
- case IKS_SRVR:
- if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
- return(z);
- if ((x = cmcfm()) < 0) return(x);
- if (iksdcf) return(success = 0);
- arg_x = z;
- break;
-
- default:
- return(-9);
- }
- return(success = (inserver ? 1 : 0));
-#else /* IKSDCONF */
- if ((x = cmcfm()) < 0)
- return(x);
- return(success = 0);
-#endif /* IKSDCONF */
-}
-#endif /* NOICP */
-#endif /* IKSD */
-
-/* D O A R G -- Do a command-line argument. */
-
-int
-#ifdef CK_ANSIC
-doarg(char x)
-#else
-doarg(x) char x;
-#endif /* CK_ANSIC */
-/* doarg */ {
- int i, n, y, z, xx; long zz; char *xp;
-
-#ifdef NETCONN
-extern char *line, *tmpbuf; /* Character buffers for anything */
-#endif /* NETCONN */
-
-#ifdef IKSD
- /* Internet Kermit Server set some way besides -A... */
- if (inserver)
- dofast();
-#endif /* IKSD */
-
- xp = *xargv+1; /* Pointer for bundled args */
- debug(F111,"doarg entry",xp,xargc);
- while (x) {
- debug(F000,"doarg arg","",x);
- switch (x) { /* Big switch on arg */
-
-#ifndef COMMENT
- case '-': /* Extended commands... */
- if (doxarg(xargv,0) < 0) {
- XFATAL("Extended option error");
- } /* Full thru... */
- case '+': /* Extended command for prescan() */
- return(0);
-#else /* NOICP */
- case '-':
- case '+':
- XFATAL("Extended options not configured");
-#endif /* NOICP */
-
-#ifndef NOSPL
- case 'C': { /* Commands for parser */
- char * s;
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("No commands given for -C");
- }
- s = *xargv; /* Get the argument (must be quoted) */
- if (!*s) /* If empty quotes */
- s = NULL; /* ignore this option */
- if (s) {
- makestr(&clcmds,s); /* Make pokeable copy */
- s = clcmds; /* Change tabs to spaces */
- while (*s) {
- if (*s == '\t') *s = ' ';
- s++;
- }
- }
- break;
- }
-#endif /* NOSPL */
-
-#ifndef NOXFER
- case 'D': /* Delay */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing delay value");
- }
- z = atoi(*xargv); /* Convert to number */
- if (z > -1) /* If in range */
- ckdelay = z; /* set it */
- else {
- XFATAL("bad delay value");
- }
- break;
-#endif /* NOXFER */
-
- case 'E': /* Exit on close */
-#ifdef NETCONN
- tn_exit = 1;
-#endif /* NETCONN */
- exitonclose = 1;
- break;
-
-#ifndef NOICP
- case 'S': /* "Stay" - enter interactive */
- stayflg = 1; /* command parser after executing */
- xfinish = 0; /* command-line actions. */
- break;
-#endif /* NOICP */
-
- case 'T': /* File transfer mode = text */
- binary = XYFT_T;
- xfermode = XMODE_M; /* Transfer mode manual */
- filepeek = 0;
-#ifdef PATTERNS
- patterns = 0;
-#endif /* PATTERNS */
- break;
-
- case '7':
- break;
-
-#ifdef IKSD
- case 'A': { /* Internet server */
- /* Already done in prescan() */
- /* but implies 'x' && 'Q' */
-#ifdef OS2
- char * p;
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
-#ifdef NT
- /* Support for Pragma Systems Telnet/Terminal Servers */
- p = getenv("PRAGMASYS_INETD_SOCK");
- if (!(p && atoi(p) != 0)) {
- xargv++, xargc--;
- if (xargc < 1 || **xargv == '-') {
- XFATAL("missing socket handle");
- }
- }
-#else /* NT */
- xargv++, xargc--;
- if (xargc < 1 || **xargv == '-') {
- XFATAL("missing socket handle");
- }
-#endif /* NT */
-#endif /* OS2 */
-#ifdef NOICP /* If no Interactive Command Parser */
- action = 'x'; /* -A implies -x. */
-#endif /* NOICP */
-#ifndef NOXFER
- dofast();
-#endif /* NOXFER */
- break;
- }
-#endif /* IKSD */
-
-#ifndef NOXFER
- case 'Q': /* Quick (i.e. FAST) */
- dofast();
- break;
-#endif /* NOXFER */
-
- case 'R': /* Remote-Only */
- break; /* This is handled in prescan(). */
-
-#ifndef NOSERVER
- case 'x': /* server */
- case 'O': /* (for One command only) */
- if (action) {
- XFATAL("conflicting actions");
- }
- if (x == 'O') justone = 1;
- xfinish = 1;
- action = 'x';
- break;
-#endif /* NOSERVER */
-
-#ifndef NOXFER
- case 'f': /* finish */
- if (action) {
- XFATAL("conflicting actions");
- }
- action = setgen('F',"","","");
- break;
-#endif /* NOXFER */
-
- case 'r': { /* receive */
- if (action) {
- XFATAL("conflicting actions");
- }
- action = 'v';
- break;
- }
-
-#ifndef NOXFER
- case 'k': /* receive to stdout */
- if (action) {
- XFATAL("conflicting actions");
- }
- stdouf = 1;
- action = 'v';
- break;
-
- case 's': { /* send */
- int fil2snd, rc;
- if (!recursive)
- nolinks = 0; /* Follow links by default */
-
- if (action) {
- XFATAL("conflicting actions");
- }
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -s");
- }
- nfils = 0; /* Initialize file counter */
- fil2snd = 0; /* Assume nothing to send */
- z = 0; /* Flag for stdin */
- cmlist = xargv + 1; /* Remember this pointer */
- while (++xargv, --xargc > 0) { /* Traverse the list */
-#ifdef PIPESEND
- if (usepipes && protocol == PROTO_K && **xargv == '!') {
- cmarg = *xargv;
- cmarg++;
- debug(F110,"doarg pipesend",cmarg,0);
- nfils = -1;
- z = 1;
- pipesend = 1;
- } else
-#endif /* PIPESEND */
- if (**xargv == '-') { /* Check for sending stdin */
- if (strcmp(*xargv,"-") != 0) /* next option? */
- break;
- z++; /* "-" alone means send from stdin. */
-#ifdef RECURSIVE
- } else if (!strcmp(*xargv,".")) {
- fil2snd = 1;
- nfils++;
- recursive = 1;
- nolinks = 2;
-#endif /* RECURSIVE */
- } else /* Check if file exists */
- if ((rc = zchki(*xargv)) > -1 || (rc == -2)) {
- if (rc != -2)
- fil2snd = 1;
- nfils++; /* Bump file counter */
- } else if (iswild(*xargv) && nzxpand(*xargv,0) > 0) {
- /* or contains wildcard characters matching real files */
- fil2snd = 1;
- nfils++;
- } else {
- if (!failmsg)
- failmsg = (char *)malloc(2000);
- if (failmsg) {
- ckmakmsg(failmsg,2000,
-#ifdef VMS
- "%CKERMIT-E-SEARCHFAIL "
-#else
- "kermit -s "
-#endif /* VMS */
- ,
- *xargv,
- ": ",
- ck_errstr()
- );
- }
- }
- }
- xargc++, xargv--; /* Adjust argv/argc */
- if (!fil2snd && z == 0) {
- if (!failmsg) {
-#ifdef VMS
- failmsg = "%CKERMIT-E-SEARCHFAIL, no files for -s";
-#else
- failmsg = "No files for -s";
-#endif /* VMS */
- }
- XFATAL(failmsg);
- }
- if (z > 1) {
- XFATAL("kermit -s: too many -'s");
- }
- if (z == 1 && fil2snd) {
- XFATAL("invalid mixture of filenames and '-' in -s");
- }
- debug(F101,"doarg s nfils","",nfils);
- debug(F101,"doarg s z","",z);
- if (nfils == 0) { /* no file parameters were specified */
- if (is_a_tty(0)) { /* (used to be is_a_tty(1) - why?) */
- XFATAL("sending from terminal not allowed");
- } else stdinf = 1;
- }
- debug(F101,"doarg s stdinf","",stdinf);
- debug(F111,"doarg",*xargv,nfils);
- action = 's';
- break;
- }
-
- case 'g': /* get */
- case 'G': /* get to stdout */
- if (action) {
- XFATAL("conflicting actions");
- }
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -g");
- }
- xargv++, xargc--;
- if ((xargc == 0) || (**xargv == '-')) {
- XFATAL("missing filename for -g");
- }
- if (x == 'G') stdouf = 1;
- cmarg = *xargv;
- action = 'r';
- break;
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
- case 'c': /* connect before */
- cflg = 1;
- break;
-
- case 'n': /* connect after */
- cnflg = 1;
- break;
-#endif /* NOLOCAL */
-
- case 'h': /* help */
- usage();
-#ifndef NOICP
- if (stayflg || what == W_COMMAND)
- break;
- else
-#endif /* NOICP */
- doexit(GOOD_EXIT,-1);
-
-#ifndef NOXFER
- case 'a': /* "as" */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -a");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing name in -a");
- }
- cmarg2 = *xargv;
- debug(F111,"doarg a",cmarg2,xargc);
- break;
-#endif /* NOXFER */
-
-#ifndef NOICP
- case 'Y': /* No initialization file */
- noinit = 1;
- break;
-
- case 'y': /* Alternate init-file name */
- noinit = 0;
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -y");
- }
- xargv++, xargc--;
- if (xargc < 1) {
- XFATAL("missing filename in -y");
- }
- /* strcpy(kermrc,*xargv); ... already done in prescan()... */
- break;
-#endif /* NOICP */
-
-#ifndef NOXFER
- case 'I': /* Assume we have an "Internet" */
- reliable = 1; /* or other reliable connection */
- xreliable = 1;
- setreliable = 1;
-
- /* I'm not so sure about this -- what about VMS? (next comment) */
- clearrq = 1; /* therefore the channel is clear */
-
-#ifndef VMS
-/*
- Since this can trigger full control-character unprefixing, we need to
- ensure that our terminal or pty driver is not doing Xon/Xoff; otherwise
- we can become deadlocked the first time we receive a file that contains
- Xoff.
-*/
- flow = FLO_NONE;
-#endif /* VMS */
- break;
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
- case 'l': /* SET LINE */
-#ifdef NETCONN
-#ifdef ANYX25
- case 'X': /* SET HOST to X.25 address */
-#ifdef SUNX25
- case 'Z': /* SET HOST to X.25 file descriptor */
-#endif /* SUNX25 */
-#endif /* ANYX25 */
-#ifdef TCPSOCKET
- case 'J':
- case 'j': /* SET HOST (TCP/IP socket) */
-#endif /* TCPSOCKET */
-#endif /* NETCONN */
-#ifndef NOXFER
- if (x == 'j' || x == 'J' || x == 'X' || x == 'Z') {
- reliable = 1; /* or other reliable connection */
- xreliable = 1;
- setreliable = 1;
- }
-#endif /* NOXFER */
- network = 0;
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -l or -j");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("communication line device name missing");
- }
-
-#ifdef NETCONN
- if (x == 'J') {
- cflg = 1; /* Connect */
- stayflg = 1; /* Stay */
- tn_exit = 1; /* Telnet-like exit condition */
- exitonclose = 1;
- }
-#endif /* NETCONN */
- ckstrncpy(ttname,*xargv,TTNAMLEN+1);
- local = (strcmp(ttname,CTTNAM) != 0);
- if (local && strcmp(ttname,"0") == 0)
- local = 0;
-/*
- NOTE: We really do not need to call ttopen here, since it should be called
- again later, automatically, when we first try to condition the device via
- ttpkt or ttvt. Calling ttopen here has the bad side effect of making the
- order of the -b and -l options significant when the order of command-line
- options should not matter. However, the network cases immediately below
- complicate matters a bit, so we'll settle this in a future edit.
-*/
- if (x == 'l') {
- if (ttopen(ttname,&local,mdmtyp,0) < 0) {
- XFATAL("can't open device");
- }
-#ifdef CKLOGDIAL
- dologline();
-#endif /* CKLOGDIAL */
- debug(F101,"doarg speed","",speed);
- cxtype = (mdmtyp > 0) ? CXT_MODEM : CXT_DIRECT;
- speed = ttgspd(); /* Get the speed. */
- setflow(); /* Do something about flow control. */
-#ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ttname,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
-#endif /* NOSPL */
-
-#ifdef NETCONN
- } else {
- if (x == 'j' || x == 'J') { /* IP network host name */
- char * s = line;
- char * service = tmpbuf;
- if (xargc > 0) { /* Check if it's followed by */
- /* A service name or number */
- if (*(xargv+1) && *(*(xargv+1)) != '-') {
- xargv++, xargc--;
- ckstrncat(ttname,":",TTNAMLEN+1);
- ckstrncat(ttname,*xargv,TTNAMLEN+1);
- }
- }
- nettype = NET_TCPB;
- mdmtyp = -nettype; /* Perhaps already set in init file */
- telnetfd = 1; /* Or maybe an open file descriptor */
- ckstrncpy(line, ttname, LINBUFSIZ); /* Working copy */
- for (s = line; *s != NUL && *s != ':'; s++);
- if (*s) {
- *s++ = NUL;
- ckstrncpy(service, s, TMPBUFSIZ);
- } else *service = NUL;
- s = line;
-#ifndef NODIAL
-#ifndef NOICP
- /* Look up in network directory */
- x = 0;
- if (*s == '=') { /* If number starts with = sign */
- s++; /* strip it */
- while (*s == SP) /* and also any leading spaces */
- s++;
- ckstrncpy(line,s,LINBUFSIZ); /* Do this again. */
- nhcount = 0;
- } else if (!isdigit(line[0])) {
-/*
- nnetdir will be greater than 0 if the init file has been processed and it
- contained a SET NETWORK DIRECTORY command.
-*/
- xx = 0; /* Initialize this */
- if (nnetdir > 0) /* If there is a directory... */
- xx = lunet(line); /* Look up the name */
- else /* If no directory */
- nhcount = 0; /* we didn't find anything there */
- if (xx < 0) { /* Lookup error: */
- ckmakmsg(tmpbuf,
- TMPBUFSIZ,
- "?Fatal network directory lookup error - ",
- line,
- "\n",
- NULL
- );
- XFATAL(tmpbuf);
- }
- }
-#endif /* NOICP */
-#endif /* NODIAL */
- /* Add service to line specification for ttopen() */
- if (*service) { /* There is a service specified */
- ckstrncat(line, ":",LINBUFSIZ);
- ckstrncat(line, service,LINBUFSIZ);
- ttnproto = NP_DEFAULT;
- } else {
- ckstrncat(line, ":telnet",LINBUFSIZ);
- ttnproto = NP_TELNET;
- }
-
-#ifndef NOICP
-#ifndef NODIAL
- if ((nhcount > 1) && !quiet && !backgrd) {
- printf("%d entr%s found for \"%s\"%s\n",
- nhcount,
- (nhcount == 1) ? "y" : "ies",
- s,
- (nhcount > 0) ? ":" : "."
- );
- for (i = 0; i < nhcount; i++)
- printf("%3d. %s %-12s => %s\n",
- i+1, n_name, nh_p2[i], nh_p[i]
- );
- }
- if (nhcount == 0)
- n = 1;
- else
- n = nhcount;
-#else
- n = 1;
- nhcount = 0;
-#endif /* NODIAL */
- for (i = 0; i < n; i++) {
-#ifndef NODIAL
- if (nhcount >= 1) {
- /* Copy the current entry to line */
- ckstrncpy(line,nh_p[i],LINBUFSIZ);
- /* Check to see if the network entry contains a service */
- for (s = line ; (*s != NUL) && (*s != ':'); s++)
- ;
- /* If directory does not have a service ... */
- /* and the user specified one */
- if (!*s && *service) {
- ckstrncat(line, ":",LINBUFSIZ);
- ckstrncat(line, service,LINBUFSIZ);
- }
- if (lookup(netcmd,nh_p2[i],nnets,&z) > -1) {
- mdmtyp = 0 - netcmd[z].kwval;
- } else {
- printf(
- "Error - network type \"%s\" not supported\n",
- nh_p2[i]
- );
- continue;
- }
- }
-#endif /* NODIAL */
- }
-#endif /* NOICP */
- ckstrncpy(ttname, line,TTNAMLEN+1);
- cxtype = CXT_TCPIP; /* Set connection type */
- setflow(); /* Set appropriate flow control. */
-#ifdef SUNX25
- } else if (x == 'X') { /* X.25 address */
- nettype = NET_SX25;
- mdmtyp = -nettype;
- } else if (x == 'Z') { /* Open X.25 file descriptor */
- nettype = NET_SX25;
- mdmtyp = -nettype;
- x25fd = 1;
-#endif /* SUNX25 */
-#ifdef STRATUSX25
- } else if (x == 'X') { /* X.25 address */
- nettype = NET_VX25;
- mdmtyp = -nettype;
-#endif /* STRATUSX25 */
-#ifdef IBMX25
- } else if (x == 'X') { /* X.25 address */
- nettype = NET_IX25;
- mdmtyp = -nettype;
-#endif /* IBMX25 */
-#ifdef HPX25
- } else if (x == 'X') { /* X.25 address */
- nettype = NET_HX25;
- mdmtyp = -nettype;
-#endif /* HPX25 */
- }
- if (ttopen(ttname,&local,mdmtyp,0) < 0) {
- XFATAL("can't open host connection");
- }
- network = 1;
-#ifdef CKLOGDIAL
- dolognet();
-#endif /* CKLOGDIAL */
- cxtype = CXT_X25; /* Set connection type */
- setflow(); /* Set appropriate flow control. */
-#ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ttname,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
-#endif /* NOSPL */
-#endif /* NETCONN */
- }
- /* add more here -- decnet, etc... */
- haveline = 1;
- break;
-
-#ifdef ANYX25
- case 'U': /* X.25 call user data */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing call user data string");
- }
- ckstrncpy(udata,*xargv,MAXCUDATA);
- if ((int)strlen(udata) <= MAXCUDATA) {
- cudata = 1;
- } else {
- XFATAL("Invalid call user data");
- }
- break;
-
- case 'o': /* X.25 closed user group */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing closed user group index");
- }
- z = atoi(*xargv); /* Convert to number */
- if (z >= 0 && z <= 99) {
- closgr = z;
- } else {
- XFATAL("Invalid closed user group index");
- }
- break;
-
- case 'u': /* X.25 reverse charge call */
- revcall = 1;
- break;
-#endif /* ANYX25 */
-#endif /* NOLOCAL */
-
- case 'b': /* Bits-per-second for serial device */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing bps");
- }
- zz = atol(*xargv); /* Convert to long int */
- i = zz / 10L;
-#ifndef NOLOCAL
- if (ttsspd(i) > -1) /* Check and set it */
-#endif /* NOLOCAL */
- speed = ttgspd(); /* and read it back. */
-#ifndef NOLOCAL
- else {
- XFATAL("unsupported transmission rate");
- }
-#endif /* NOLOCAL */
- break;
-
-#ifndef NODIAL
-#ifndef NOICP
- case 'm': /* Modem type */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -m");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("modem type missing");
- }
- y = lookup(mdmtab,*xargv,nmdm,&z);
- if (y < 0) {
- XFATAL("unknown modem type");
- }
- usermdm = 0;
- usermdm = (y == dialudt) ? x : 0;
- initmdm(y);
- break;
-#endif /* NOICP */
-#endif /* NODIAL */
-
-#ifndef NOXFER
- case 'e': /* Extended packet length */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -e");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing length");
- }
- z = atoi(*xargv); /* Convert to number */
- if (z > 10 && z <= maxrps) {
- rpsiz = urpsiz = z;
- if (z > 94) rpsiz = 94; /* Fallback if other Kermit can't */
- } else {
- XFATAL("Unsupported packet length");
- }
- break;
-
- case 'v': /* Vindow size */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing or bad window size");
- }
- z = atoi(*xargv); /* Convert to number */
- if (z < 32) { /* If in range */
- wslotr = z; /* set it */
- if (z > 1) swcapr = 1; /* Set capas bit if windowing */
- } else {
- XFATAL("Unsupported packet length");
- }
- break;
-#endif /* NOXFER */
-
- case 'i': /* Treat files as binary */
- binary = XYFT_B;
- xfermode = XMODE_M; /* Transfer mode manual */
- filepeek = 0;
-#ifdef PATTERNS
- patterns = 0;
-#endif /* PATTERNS */
- break;
-
-#ifndef NOXFER
- case 'w': /* Writeover */
- ckwarn = 0;
- fncact = XYFX_X;
- break;
-#endif /* NOXFER */
-
- case 'q': /* Quiet */
- quiet = 1;
- break;
-
-#ifdef DEBUG
- case 'd': /* DEBUG */
- break; /* Handled in prescan() */
-#endif /* DEBUG */
-
- case '0': { /* In the middle */
- extern int tt_escape, lscapr;
- tt_escape = 0; /* No escape character */
- flow = 0; /* No Xon/Xoff (what about hwfc?) */
-#ifndef NOXFER
- lscapr = 0; /* No locking shifts */
-#endif /* NOXFER */
-#ifdef CK_APC
- {
- extern int apcstatus; /* No APCs */
- apcstatus = APC_OFF;
- }
-#endif /* CK_APC */
-#ifndef NOLOCAL
-#ifdef CK_AUTODL
- setautodl(0,0); /* No autodownload */
-#endif /* CK_AUTODL */
-#endif /* NOLOCAL */
-#ifndef NOCSETS
- {
- extern int tcsr, tcsl; /* No character-set translation */
- tcsr = 0;
- tcsl = tcsr; /* Make these equal */
- }
-#endif /* NOCSETS */
-#ifdef TNCODE
- TELOPT_DEF_C_U_MODE(TELOPT_KERMIT) = TN_NG_RF;
- TELOPT_DEF_C_ME_MODE(TELOPT_KERMIT) = TN_NG_RF;
- TELOPT_DEF_S_U_MODE(TELOPT_KERMIT) = TN_NG_RF;
- TELOPT_DEF_S_ME_MODE(TELOPT_KERMIT) = TN_NG_RF;
-#endif /* TNCODE */
- }
-/* Fall thru... */
-
- case '8': /* 8-bit clean */
- parity = 0;
- cmdmsk = 0xff;
- cmask = 0xff;
- break;
-
- case 'V': {
- extern int xfermode;
-#ifdef PATTERNS
- extern int patterns;
- patterns = 0; /* No patterns */
-#endif /* PATTERNS */
- xfermode = XMODE_M; /* Manual transfer mode */
- filepeek = 0;
- break;
- }
-
- case 'p': /* SET PARITY */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing parity");
- }
- switch(x = **xargv) {
- case 'e':
- case 'o':
- case 'm':
- case 's': parity = x; break;
- case 'n': parity = 0; break;
- default: { XFATAL("invalid parity"); }
- }
- break;
-
- case 't': /* Line turnaround handshake */
- turn = 1;
- turnch = XON; /* XON is turnaround character */
- duplex = 1; /* Half duplex */
- flow = 0; /* No flow control */
- break;
-
- case 'B':
- bgset = 1; /* Force background (batch) */
- backgrd = 1;
- break;
-
- case 'z': /* Force foreground */
- bgset = 0;
- backgrd = 0;
- break;
-
-#ifndef NOXFER
-#ifdef RECURSIVE
- case 'L':
- recursive = 2;
- nolinks = 2;
- fnspath = PATH_REL;
- break;
-#endif /* RECURSIVE */
-#endif /* NOXFER */
-
-#ifndef NOSPL
- case 'M': /* My User Name */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing username");
- }
- if ((int)strlen(*xargv) > 63) {
- XFATAL("username too long");
- }
-#ifdef IKSD
- if (!inserver)
-#endif /* IKSD */
- {
- ckstrncpy(uidbuf,*xargv,UIDBUFLEN);
- haveftpuid = 1;
- }
- break;
-#endif /* NOSPL */
-
-#ifdef CK_NETBIOS
- case 'N': /* NetBios Adapter Number follows */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -N");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing NetBios Adapter number");
- }
- if ((strlen(*xargv) != 1) ||
- (*xargv)[0] != 'X' &&
- (atoi(*xargv) < 0) &&
- (atoi(*xargv) > 9)) {
- XFATAL("Invalid NetBios Adapter - Adapters 0 to 9 are valid");
- }
- break;
-#endif /* CK_NETBIOS */
-
-#ifdef NETCONN
- case 'F':
- network = 1;
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -F");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("network file descriptor missing");
- }
- ckstrncpy(ttname,*xargv,TTNAMLEN+1);
- nettype = NET_TCPB;
- mdmtyp = -nettype;
- telnetfd = 1;
- local = 1;
- break;
-#endif /* NETCONN */
-
-#ifdef COMMENT
-#ifdef OS2PM
- case 'P': /* OS/2 Presentation Manager */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -P");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("pipe data missing");
- }
- pipedata = *xargv;
- break;
-#endif /* OS2PM */
-#else
- case 'P': /* Filenames literal */
- fncnv = XYFN_L;
- f_save = XYFN_L;
- break;
-#endif /* COMMENT */
-
-#ifndef NOICP
- case 'H':
- noherald = 1;
- break;
-#endif /* NOICP */
-
-#ifdef OS2
- case 'W':
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -W");
- }
- xargv++, xargc--;
- if ((xargc < 1)) { /* could be negative */
- XFATAL("Window handle missing");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("Kermit Instance missing");
- }
- /* Action done in prescan */
- break;
-
- case '#': /* K95 stdio threads */
- xargv++, xargc--; /* Skip past argument */
- break; /* Action done in prescan */
-#endif /* OS2 */
-
-#ifdef NEWFTP
- case '9': /* FTP */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling after -9");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("FTP server address missing");
- }
- makestr(&ftp_host,*xargv);
- break;
-#endif /* NEWFTP */
-
- default:
- fatal2(*xargv,
-#ifdef NT
- "invalid command-line option, type \"k95 -h\" for help"
-#else
-#ifdef OS2
- "invalid command-line option, type \"k2 -h\" for help"
-#else
- "invalid command-line option, type \"kermit -h\" for help"
-#endif /* OS2 */
-#endif /* NT */
- );
- }
- if (!xp) break;
- x = *++xp; /* See if options are bundled */
- }
- return(0);
-}
-
-#ifdef TNCODE
-/* D O T N A R G -- Do a telnet command-line argument. */
-
-static int
-#ifdef CK_ANSIC
-dotnarg(char x)
-#else
-dotnarg(x) char x;
-#endif /* CK_ANSIC */
-/* dotnarg */ {
- char *xp;
-
- xp = *xargv+1; /* Pointer for bundled args */
- debug(F111,"dotnarg entry",xp,xargc);
- while (x) {
- debug(F000,"dotnarg arg","",x);
- switch (x) { /* Big switch on arg */
-
-#ifndef COMMENT
- case '-': /* Extended commands... */
- if (doxarg(xargv,0) < 0) {
- XFATAL("Extended option error");
- } /* Full thru... */
- case '+': /* Extended command for prescan() */
- return(0);
-#else /* COMMENT */
- case '-':
- case '+':
- XFATAL("Extended options not configured");
-#endif /* COMMENT */
-
-/*
- * -# Kermit 95 Startup Flags
- * -8 Negotiate Telnet Binary in both directions
- * -a Require use of Telnet authentication
- * -c Do not read the .telnetrc file
- * -d Turn on debug mode
- * -E No escape character
- * -f Forward credentials to host
- * -K Refuse use of authentication; do not send username
- * -k realm Set default realm
- * -l user Set username and request Telnet authentication
- * -L Negotiate Telnet Binary Output only
- * -q Quiet mode (suppress messages)
- * -S tos Use the IP type-of-service tos
- * -x Require Encryption
- * -D Disable forward-X
- * -T cert=file Use certificate in file
- * -T key=file Use private key in file
- * -T crlfile=file Use CRL in file
- * -T crldir=dir Use CRLs in directory
- * -T cipher=string Use only ciphers in string
- * -X atype Disable use of atype authentication
- * -Y Disable init file processing
- *
- */
- case 'h': /* help */
- usage();
- doexit(GOOD_EXIT,-1);
- break;
-
- case '8': /* Telnet Binary in both directions */
- TELOPT_DEF_C_U_MODE(TELOPT_BINARY) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_BINARY) = TN_NG_MU;
- parity = 0;
- cmdmsk = 0xff;
- cmask = 0xff;
- break;
-
- case 'a': /* Require Telnet Auth */
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
-
- case 'Y':
- xargv++, xargc--; /* Skip past argument */
- break; /* Action done in prescan */
-
-#ifdef OS2
- case '#': /* K95 stdio threads */
- xargv++, xargc--; /* Skip past argument */
- break; /* Action done in prescan */
-#endif /* OS2 */
-
- case 'q': /* Quiet */
- quiet = 1;
- break;
-
- case 'd':
-#ifdef DEBUG
- if (deblog) {
- debtim = 1;
- } else {
- deblog = debopn("debug.log",0);
- }
-#endif /* DEBUG */
- break;
-
- case 'E': { /* No Escape character */
- extern int tt_escape;
- tt_escape = 0;
- }
- break;
-
- case 'K':
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
- uidbuf[0] = NUL;
- break;
-
- case 'l': /* Set username and request telnet authentication */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing username");
- }
- if ((int)strlen(*xargv) > 63) {
- XFATAL("username too long");
- }
- ckstrncpy(uidbuf,*xargv,UIDBUFLEN);
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
-
- case 'L': /* Require BINARY mode outbound only */
- TELOPT_DEF_C_ME_MODE(TELOPT_BINARY) = TN_NG_MU;
- break;
-
- case 'x': /* Require Encryption */
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- break;
-
- case 'D': /* Disable use of Forward X */
- TELOPT_DEF_C_U_MODE(TELOPT_FORWARD_X) = TN_NG_RF;
- break;
-
- case 'f': /* Forward credentials to host */
- {
-#ifdef CK_AUTHENTICATION
- extern int forward_flag;
- forward_flag = 1;
-#endif
- break;
- }
-
- case 'k': {
-#ifdef CK_KERBEROS
- extern char * krb5_d_realm, * krb4_d_realm;
-#endif /* CK_KERBEROS */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing realm");
- }
-#ifdef CK_KERBEROS
- if ((int)strlen(*xargv) > 63) {
- XFATAL("realm too long");
- }
- makestr(&krb5_d_realm,*xargv);
- makestr(&krb4_d_realm,*xargv);
-#endif /* CK_KERBEROS */
- break;
- }
-
- case 'T': {
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing cert=, key=, crlfile=, crldir=, or cipher=");
- }
-#ifdef CK_SSL
- if (!strncmp(*xargv,"cert=",5)) {
- extern char * ssl_rsa_cert_file;
- makestr(&ssl_rsa_cert_file,&(*xargv[5]));
- } else if ( !strncmp(*xargv,"key=",4) ) {
- extern char * ssl_rsa_key_file;
- makestr(&ssl_rsa_key_file,&(*xargv[4]));
- } else if ( !strncmp(*xargv,"crlfile=",8) ) {
- extern char * ssl_crl_file;
- makestr(&ssl_crl_file,&(*xargv[8]));
- } else if ( !strncmp(*xargv,"crldir=",7) ) {
- extern char * ssl_crl_dir;
- makestr(&ssl_crl_dir,&(*xargv[7]));
- } else if ( !strncmp(*xargv,"cipher=",7) ) {
- extern char * ssl_cipher_list;
- makestr(&ssl_cipher_list,&(*xargv[7]));
- } else {
- XFATAL("invalid parameter");
- }
-#endif /* CK_SSL */
- break;
- }
-
- default:
- fatal2(*xargv,
- "invalid command-line option, type \"telnet -h\" for help"
- );
- }
-
- if (!xp) break;
- x = *++xp; /* See if options are bundled */
- }
- return(0);
-}
-#endif /* TNCODE */
-
-#ifdef RLOGCODE
-
-/* D O R L G A R G -- Do a rlogin command-line argument. */
-
-static int
-#ifdef CK_ANSIC
-dorlgarg(char x)
-#else
-dorlgarg(x) char x;
-#endif /* CK_ANSIC */
-/* dorlgarg */ {
- char *xp;
-
- xp = *xargv+1; /* Pointer for bundled args */
- debug(F111,"dorlgarg entry",xp,xargc);
- while (x) {
- debug(F000,"dorlgarg arg","",x);
- switch (x) { /* Big switch on arg */
-
-#ifndef COMMENT
- case '-': /* Extended commands... */
- if (doxarg(xargv,0) < 0) {
- XFATAL("Extended option error");
- } /* Full thru... */
- case '+': /* Extended command for prescan() */
- return(0);
-#else /* COMMENT */
- case '-':
- case '+':
- XFATAL("Extended options not configured");
-#endif /* COMMENT */
-
-/*
- * -d Debug
- * -l user Set username
- *
- */
- case 'h': /* help */
- usage();
- doexit(GOOD_EXIT,-1);
- break;
-
- case 'Y':
- xargv++, xargc--; /* Skip past argument */
- break; /* Action done in prescan */
-#ifdef OS2
- case '#': /* K95 stdio threads */
- xargv++, xargc--; /* Skip past argument */
- break; /* Action done in prescan */
-#endif /* OS2 */
- case 'q': /* Quiet */
- quiet = 1;
- break;
-
- case 'd':
-#ifdef DEBUG
- if (deblog) {
- debtim = 1;
- } else {
- deblog = debopn("debug.log",0);
- }
-#endif /* DEBUG */
- break;
-
- case 'l': /* Set username and request telnet authentication */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing username");
- }
- if ((int)strlen(*xargv) > 63) {
- XFATAL("username too long");
- }
- ckstrncpy(uidbuf,*xargv,UIDBUFLEN);
- break;
-
- default:
- fatal2(*xargv,
- "invalid command-line option, type \"rlogin -h\" for help"
- );
- }
-
- if (!xp) break;
- x = *++xp; /* See if options are bundled */
- }
- return(0);
-}
-#endif /* RLOGCODE */
-
-#ifdef SSHBUILTIN
-
-/* D O S S H A R G -- Do a ssh command-line argument. */
-
-static int
-#ifdef CK_ANSIC
-dossharg(char x)
-#else
-dossharg(x) char x;
-#endif /* CK_ANSIC */
-/* dossharg */ {
- char *xp;
-
- xp = *xargv+1; /* Pointer for bundled args */
- debug(F111,"dossharg entry",xp,xargc);
- while (x) {
- debug(F000,"dossharg arg","",x);
- switch (x) { /* Big switch on arg */
-
-#ifndef COMMENT
- case '-': /* Extended commands... */
- if (doxarg(xargv,0) < 0) {
- XFATAL("Extended option error");
- } /* Full thru... */
- case '+': /* Extended command for prescan() */
- return(0);
-#else /* COMMENTP */
- case '-':
- case '+':
- XFATAL("Extended options not configured");
-#endif /* COMMENT */
-
-/*
- * -d Debug
- * -# args Init
- * -Y no init file
- * -l user Set username
- *
- */
- case 'h': /* help */
- usage();
- doexit(GOOD_EXIT,-1);
- break;
-
- case 'Y':
- xargv++, xargc--; /* Skip past argument */
- break; /* Action done in prescan */
-#ifdef OS2
- case '#': /* K95 stdio threads */
- xargv++, xargc--; /* Skip past argument */
- break; /* Action done in prescan */
-#endif /* OS2 */
- case 'q': /* Quiet */
- quiet = 1;
- break;
-
- case 'd':
-#ifdef DEBUG
- if (deblog) {
- debtim = 1;
- } else {
- deblog = debopn("debug.log",0);
- }
-#endif /* DEBUG */
- break;
-
- case 'l': /* Set username and request telnet authentication */
- if (*(xp+1)) {
- XFATAL("invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- XFATAL("missing username");
- }
- if ((int)strlen(*xargv) > 63) {
- XFATAL("username too long");
- }
- ckstrncpy(uidbuf,*xargv,UIDBUFLEN);
- break;
-
- default:
- fatal2(*xargv,
- "invalid command-line option, type \"ssh -h\" for help"
- );
- }
-
- if (!xp) break;
- x = *++xp; /* See if options are bundled */
- }
- return(0);
-}
-#endif /* SSHBUILTIN */
-
-#else /* No command-line interface... */
-
-int
-cmdlin() {
- extern int xargc;
- if (xargc > 1) {
- XFATAL("Sorry, command-line options disabled.");
- }
-}
-#endif /* NOCMDL */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuver.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckuver.h
deleted file mode 100644
index 7a111fb..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuver.h
+++ /dev/null
@@ -1,1262 +0,0 @@
-/* ckuver.h -- C-Kermit UNIX Version heralds */
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2010,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-#ifndef CKUVER_H
-#define CKUVER_H
-
-/* Arranged more or less alphabetically by compiler symbol */
-/* Must be included AFTER ckcdeb.h. */
-
-#ifdef BEOS
-#ifdef BEOS45
-#define HERALD " BeOS 4.5"
-#else
-#define HERALD " BeOS"
-#endif /* BEOS45 */
-#else
-#ifdef BEBOX
-#ifdef BE_DR_7
-#define HERALD " BeBox DR7"
-#else
-#define HERALD " BeBox"
-#endif /* BE_DR_7 */
-#endif /* BEBOX */
-#endif /* BEOS */
-
-#ifdef BELLV10
-#define HERALD " Bell Labs Research UNIX V10"
-#endif /* BELLV10 */
-
-#ifdef APOLLOSR10
-#define HERALD " Apollo SR10"
-#endif /* APOLLOSR10 */
-
-#ifdef MAC
-#define HERALD " Apple Macintosh"
-#endif /* MAC */
-
-#ifdef A986
-#define HERALD " Altos 986 / Xenix 3.0"
-#endif /* A986 */
-
-#ifdef AS400
-#define HERALD " AS/400"
-#endif /* AS400 */
-
-#ifdef aegis
-#ifdef BSD4
-#define HERALD " Apollo DOMAIN/IX 4.2 BSD"
-#else
-#ifdef ATTSV
-#define HERALD " Apollo DOMAIN/IX System V"
-#else
-#define HERALD " Apollo Aegis"
-#endif /* BSD4 */
-#endif /* ATTSV */
-#endif /* aegis */
-
-#ifndef HERALD
-
-#ifdef AIXRS
-
-#ifdef AIX53
-#define HERALD " IBM AIX 5.3"
-#else
-#ifdef AIX52
-#define HERALD " IBM AIX 5.2"
-#else
-#ifdef AIX51
-#define HERALD " IBM AIX 5.1"
-#else
-#ifdef AIX45
-#define HERALD " IBM AIX 5.0"
-#else
-#ifdef AIX45
-#define HERALD " IBM AIX 4.5"
-#else
-#ifdef AIX44
-#define HERALD " IBM AIX 4.4"
-#else
-#ifdef AIX43
-#define HERALD " IBM AIX 4.3"
-#else
-#ifdef AIX42
-#define HERALD " IBM AIX 4.2"
-#else
-#ifdef SVR4
-#ifdef AIX41
-#define HERALD " IBM AIX 4.1"
-#else
-#define HERALD " IBM RS/6000 AIX 3.2"
-#endif /* AIX41 */
-#else
-#define HERALD " IBM RS/6000 AIX 3.0/3.1"
-#endif /* SVR4 */
-#endif /* AIX42 */
-#endif /* AIX43 */
-#endif /* AIX44 */
-#endif /* AIX45 */
-#endif /* AIX50 */
-#endif /* AIX51 */
-#endif /* AIX52 */
-#endif /* AIX53 */
-#endif /* AIXRS */
-
-#ifdef PS2AIX10
-#define HERALD " IBM PS/2 AIX 1.x"
-#endif /* PS2AIX10 */
-
-#ifdef AIXPS2
-#define HERALD " IBM PS/2 AIX 3.x"
-#endif /* AIXPS2 */
-
-#ifdef AIX370
-#ifndef HERALD
-#define HERALD " IBM System/370 AIX/370"
-#endif
-#endif /* AIX370 */
-
-#ifdef AIXESA
-#ifndef HERALD
-#define HERALD " IBM AIX/ESA version 2.1"
-#endif
-#endif /* AIXESA */
-
-#ifdef ATT6300
-#define HERALD " AT&T 6300"
-#endif /* ATT6300 */
-
-#ifdef ATT7300
-#ifdef UNIX351M
-#define HERALD " AT&T 7300 UNIX PC UNIX 3.51m"
-#else
-#define HERALD " AT&T 7300 UNIX PC"
-#endif /* UNIX351M */
-#endif /* ATT7300 */
-
-#ifdef AUX
-#define HERALD " Apple Macintosh AUX"
-#endif /* AUX */
-
-#ifdef BSD44
-#ifdef MACOSX
-#define HERALD " Mac OS X"
-#else
-#ifdef __OpenBSD__
-#define HERALD " OpenBSD"
-#else
-#ifdef __bsdi__
-#ifdef BSDI4
-#define HERALD " BSDI BSD/OS 4.0"
-#else
-#ifdef BSDI3
-#define HERALD " BSDI BSD/OS 3.0"
-#else
-#ifdef BSDI2
-#define HERALD " BSDI BSD/OS 2.0" /* 1.1++ name... */
-#else
-#define HERALD " BSDI BSD/386" /* Original 1.0 name */
-#endif /* BSDI2 */
-#endif /* BSDI3 */
-#endif /* BSDI4 */
-#else /* __bsdi__ */
-#ifdef __NetBSD__
-#ifndef HERALD
-#ifdef NETBSD16
-#define HERALD " NetBSD 1.6"
-#else
-#ifdef NETBSD15
-#define HERALD " NetBSD 1.5"
-#else
-#define HERALD " NetBSD"
-#endif /* NETBSD15 */
-#endif /* NETBSD16 */
-#endif /* HERALD */
-#else /* __NetBSD__ */
-#ifdef __FreeBSD__
-#ifdef FREEBSD51
-#define HERALD " FreeBSD 5.1"
-#else
-#ifdef FREEBSD50
-#define HERALD " FreeBSD 5.0"
-#else
-#ifdef FREEBSD49
-#define HERALD " FreeBSD 4.9"
-#else
-#ifdef FREEBSD48
-#define HERALD " FreeBSD 4.8"
-#else
-#ifdef FREEBSD47
-#define HERALD " FreeBSD 4.7"
-#else
-#ifdef FREEBSD46
-#define HERALD " FreeBSD 4.6"
-#else
-#ifdef FREEBSD45
-#define HERALD " FreeBSD 4.5"
-#else
-#ifdef FREEBSD44
-#define HERALD " FreeBSD 4.4"
-#else
-#ifdef FREEBSD43
-#define HERALD " FreeBSD 4.3"
-#else
-#ifdef FREEBSD42
-#define HERALD " FreeBSD 4.2"
-#else
-#ifdef FREEBSD41
-#define HERALD " FreeBSD 4.1"
-#else
-#ifdef FREEBSD4
-#define HERALD " FreeBSD 4.0"
-#else
-#ifdef FREEBSD3
-#define HERALD " FreeBSD 3.0"
-#else
-#ifdef FREEBSD2
-#define HERALD " FreeBSD 2.0"
-#else
-#define HERALD " FreeBSD"
-#endif /* FREEBSD2 */
-#endif /* FREEBSD3 */
-#endif /* FREEBSD4 */
-#endif /* FREEBSD41 */
-#endif /* FREEBSD42 */
-#endif /* FREEBSD43 */
-#endif /* FREEBSD44 */
-#endif /* FREEBSD45 */
-#endif /* FREEBSD46 */
-#endif /* FREEBSD47 */
-#endif /* FREEBSD48 */
-#endif /* FREEBSD49 */
-#endif /* FREEBSD50 */
-#endif /* FREEBSD51 */
-#else
-#ifdef __386BSD__
-#define HERALD " 386BSD"
-#else
-#define HERALD " 4.4BSD"
-#endif /* __386BSD__ */
-#endif /* __FreeBSD__ */
-#endif /* __NetBSD__ */
-#endif /* __bsdi__ */
-#endif /* __OpenBSD__ */
-#endif /* MACOSX */
-#endif /* BSD44 */
-
-#ifdef ENCORE
-#ifdef BSD43
-#define HERALD " Encore Multimax UMAX 4.3"
-#else
-#define HERALD " Encore Multimax UMAX 4.2"
-#endif
-#endif /* ENCORE */
-
-#ifdef BSD29
-#define HERALD " 2.9 BSD"
-#endif /* BSD29 */
-
-#ifdef BSD41
-#define HERALD " 4.1 BSD"
-#endif /* BSD41 */
-
-#ifdef C70
-#define HERALD " BBN C/70"
-#endif /* c70 */
-
-#ifdef CIE
-#define HERALD " CIE Systems 680/20 Regulus"
-#endif /* CIE */
-
-#ifdef COHERENT
-#ifdef _I386
-#define HERALD " MWC Coherent 386 4.x"
-#ifndef i386
-#define i386
-#endif /* i386 */
-#else
-#define HERALD " PC/AT MWC Coherent 286 3.x"
-#ifndef i286
-#define i286
-#endif /* i286 */
-#endif /* _I386 */
-#endif /* COHERENT */
-
-#ifdef CONVEX9
-#define HERALD " Convex/OS"
-#endif /* CONVEX9 */
-
-#ifdef CONVEX10
-#define HERALD " Convex/OS 10.1"
-#endif /* CONVEX10 */
-
-#ifdef _CRAY
-#ifdef _CRAYCOM
-#define HERALD " Cray CSOS"
-#else /* _CRAYCOM */
-#define HERALD " Cray UNICOS"
-#endif /* _CRAYCOM */
-#endif /* _CRAY */
-
-#ifdef DGUX
-#ifdef DGUX54420
-#define HERALD " Data General DG/UX R4.20"
-#else
-#ifdef DGUX54411
-#define HERALD " Data General DG/UX R4.11"
-#else
-#ifdef DGUX54410
-#define HERALD " Data General DG/UX R4.10"
-#else
-#ifdef DGUX54310
-#define HERALD " Data General DG/UX 5.4R3.10"
-#else
-#ifdef DGUX543
-#define HERALD " Data General DG/UX 5.4R3.00"
-#else
-#ifdef DGUX540
-#define HERALD " Data General DG/UX 5.4"
-#else
-#ifdef DGUX430
-#define HERALD " Data General DG/UX 4.30"
-#else
-#define HERALD " Data General DG/UX"
-#endif /* DGUX430 */
-#endif /* DGUX540 */
-#endif /* DGUX543 */
-#endif /* DGUX54310 */
-#endif /* DGUX54410 */
-#endif /* DGUX54411 */
-#endif /* DGUX54420 */
-#endif /* DGUX */
-
-#ifdef datageneral
-#ifndef HERALD
-#define HERALD " Data General AOS/VS"
-#endif /* HERALD */
-#endif /* datageneral */
-
-#ifdef SINIX
-#ifdef SNI544
-#define HERALD " Siemens Nixdorf Reliant UNIX V5.44"
-#else
-#ifdef SNI543
-#define HERALD " Siemens Nixdorf Reliant UNIX V5.43"
-#else
-#ifdef SNI541
-#define HERALD " Siemens Nixdorf SINIX V5.41"
-#else
-#define HERALD " Siemens Nixdorf SINIX V5.42"
-#endif /* SNI541 */
-#endif /* SNI543 */
-#endif /* SNI544 */
-#endif /* SINIX */
-
-#ifdef POWERMAX
-#define HERALD " Concurrent PowerMAX OS"
-#endif /* POWERMAX */
-
-#ifdef DELL_SVR4
-#define HERALD " Dell System V R4"
-#endif /* DELL_SVR4 */
-
-#ifdef NCRMPRAS
-#define HERALD " NCR MP-RAS"
-#endif /* NCRMPRAS */
-
-#ifdef UNIXWARE
-#define HERALD " UnixWare"
-#else
-#ifdef OLD_UNIXWARE
-#define HERALD " UnixWare"
-#endif /* OLD_UNIXWARE */
-#endif /* UNIXWARE */
-
-#ifdef ICL_SVR4
-#define HERALD " ICL System V R4 DRS N/X"
-#endif /* ICL_SVR4 */
-
-#ifdef FT18
-#ifdef FT21
-#define HERALD " Fortune For:Pro 2.1"
-#else
-#define HERALD " Fortune For:Pro 1.8"
-#endif /* FT21 */
-#endif /* FT18 */
-
-#ifdef GEMDOS
-#define HERALD " Atari ST GEM 1.0"
-#endif /* GEMDOS */
-
-#ifdef XF68R3V6
-#define HERALD " Motorola UNIX System V/68 R3V6"
-#endif /* XF68R3V6 */
-
-#ifdef XF88R32
-#define HERALD " Motorola UNIX System V/88 R32"
-#endif /* XF88R32 */
-
-#ifdef I386IX
-#ifdef SVR3JC
-#define HERALD " Interactive UNIX System V/386 R3.2"
-#else
-#define HERALD " Interactive Systems Corp 386/ix"
-#endif /* SVR3JC */
-#endif /* I386IX */
-
-#ifdef IRIX65
-#define HERALD " Silicon Graphics IRIX 6.5"
-#else
-#ifdef IRIX64
-#define HERALD " Silicon Graphics IRIX 6.4"
-#else
-#ifdef IRIX63
-#define HERALD " Silicon Graphics IRIX 6.3"
-#else
-#ifdef IRIX62
-#define HERALD " Silicon Graphics IRIX 6.2"
-#else
-#ifdef IRIX60
-#define HERALD " Silicon Graphics IRIX 6.0"
-#else
-#ifdef IRIX53
-#define HERALD " Silicon Graphics IRIX 5.3"
-#else
-#ifdef IRIX52
-#define HERALD " Silicon Graphics IRIX 5.2"
-#else
-#ifdef IRIX51
-#define HERALD " Silicon Graphics IRIX 5.1"
-#else
-#ifdef IRIX40
-#define HERALD " Silicon Graphics IRIX 4.0"
-#endif /* IRIX40 */
-#endif /* IRIX51 */
-#endif /* IRIX52 */
-#endif /* IRIX53 */
-#endif /* IRIX60 */
-#endif /* IRIX62 */
-#endif /* IRIX63 */
-#endif /* IRIX64 */
-#endif /* IRIX65 */
-
-#ifdef ISIII
-#define HERALD " Interactive Systems Corp System III"
-#endif /* ISIII */
-
-#ifdef IX370
-#define HERALD " IBM IX/370"
-#endif /* IX370 */
-
-#ifdef HPUX
-#ifdef HPUX5
-#define HERALD " HP-UX 5.00"
-#else
-#ifdef HPUX6
-#define HERALD " HP-UX 6.00"
-#else
-#ifdef HPUX7
-#define HERALD " HP-UX 7.00"
-#else
-#ifdef HPUX8
-#define HERALD " HP-UX 8.00"
-#else
-#ifdef HPUX9
-#define HERALD " HP-UX 9.00"
-#else
-#ifdef HPUX1100
-#define HERALD " HP-UX 11.00"
-#else
-#ifdef HPUX10
-#ifdef HPUX1030
-#define HERALD " HP-UX 10.30"
-#else
-#ifdef HPUX1020
-#define HERALD " HP-UX 10.20"
-#else
-#ifdef HPUX1010
-#define HERALD " HP-UX 10.10"
-#else
-#ifdef HPUX10xx
-#define HERALD " HP-UX 10.xx"
-#else
-#define HERALD " HP-UX 10.00"
-#endif /* HPUX10XX */
-#endif /* HPUX1010 */
-#endif /* HPUX1020 */
-#endif /* HPUX1030 */
-#else
-#define HERALD " HP-UX"
-#endif /* HPUX10 */
-#endif /* HPUX1100 */
-#endif /* HPUX9 */
-#endif /* HPUX8 */
-#endif /* HPUX7 */
-#endif /* HPUX6 */
-#endif /* HPUX5 */
-#endif /* HPUX */
-
-#ifndef MINIX
-#ifdef MINIX315
-#define MINIX
-#endif /* MINIX315 */
-#endif /* MINIX */
-
-#ifndef MINIX
-#ifdef MINIX3
-#define MINIX
-#endif /* MINIX3 */
-#endif /* MINIX */
-
-#ifdef MINIX
-#ifdef MINIX315
-#define HERALD " Minix 3.1.5"
-#ifndef MINIX3
-#define MINIX3
-#endif /* MINIX3 */
-#endif /* MINIX315 */
-#ifdef MINIX3
-#ifndef MINIX2
-#define MINIX2
-#endif /* MINIX2 */
-#ifndef HERALD
-#define HERALD " Minix 3.0"
-#endif /* HERALD */
-#else
-#ifdef MINIX2
-#define HERALD " Minix 2.0"
-#else
-#define HERALD " Minix 1.0"
-#endif /* MINIX3 */
-#endif /* MINIX2 */
-#endif /* MINIX */
-
-#ifdef MIPS
-#define HERALD " MIPS RISC/OS SVR3"
-#endif /* MIPS */
-
-#ifdef NEXT
-#ifdef OPENSTEP42
-#define HERALD " OPENSTEP 4.2"
-#else
-#ifdef NEXT33
-#define HERALD " NeXTSTEP 3.3"
-#else
-#define HERALD " NeXTSTEP"
-#endif /* NEXT33 */
-#endif /* OPENSTEP42 */
-#endif /* NEXT */
-
-#ifdef OSF
-#ifdef i386
-#define HERALD " DECpc OSF/1"
-#ifdef __GNUC
-#define OSFPC
-#endif /* __GNUC */
-#else /* Not i386 so Alpha */
-
-#ifdef TRU64
-
-#ifdef OSF51B
-#define HERALD " Compaq Tru64 UNIX 5.1B"
-#else
-#ifdef OSF51A
-#define HERALD " Compaq Tru64 UNIX 5.1A"
-#else
-#ifdef OSF50
-#define HERALD " Compaq Tru64 UNIX 5.0A"
-#else
-#ifdef OSF40G
-#define HERALD " Compaq Tru64 UNIX 4.0G"
-#else
-#ifdef OSF40F
-#define HERALD " Compaq Tru64 UNIX 4.0F"
-#else
-#ifdef OSF40E
-#define HERALD " Compaq Tru64 UNIX 4.0E"
-#endif /* OSF40E */
-#endif /* OSF40F */
-#endif /* OSF40G */
-#endif /* OSF50 */
-#endif /* OSF51A */
-#endif /* OSF51B */
-
-#else /* Not TRU64 */
-
-#ifdef OSF40
-#define HERALD " Digital UNIX 4.0"
-#else
-#ifdef OSF32
-#define HERALD " Digital UNIX 3.2"
-#else
-#define HERALD " DEC OSF/1 Alpha"
-#endif /* OSF40 */
-#endif /* OSF32 */
-
-#endif /* TRU64 */
-#endif /* i386 */
-#endif /* OSF */
-
-#ifdef PCIX
-#define HERALD " PC/IX"
-#endif /* PCIX */
-
-#ifdef sxaE50
-#define HERALD " PFU SX/A V10/L50"
-#endif /* sxaE50 */
-
-#ifdef PROVX1
-#define HERALD " DEC Professional 300 (Venix 1.0)"
-#endif /* PROVX1 */
-
-#ifdef PYRAMID
-#ifdef SVR4
-#define HERALD " Pyramid DC/OSx"
-#else
-#define HERALD " Pyramid Dual Port OSx"
-#endif /* SVR4 */
-#endif /* PYRAMID */
-
-#ifdef RTAIX
-#define HERALD " IBM RT PC (AIX 2.2)"
-#endif /* RTAIX */
-
-#ifdef RTU
-#define HERALD " Masscomp/Concurrent RTU"
-#endif /* RTU */
-
-#ifdef sony_news
-#define HERALD " SONY NEWS"
-#endif /* sony_news */
-
-#ifdef SOLARIS24
-#define HERALD " Solaris 2.4"
-#else
-#ifdef SOLARIS23
-#define HERALD " Solaris 2.3"
-#else
-#ifdef SOLARIS
-#define HERALD " Solaris 2.x"
-#endif /* SOLARIS */
-#endif /* SOLARIS23 */
-#endif /* SOLARIS24 */
-
-#ifdef SUNOS4
-#ifdef BSD4
-#ifdef SUNOS41
-#define HERALD " SunOS 4.1"
-#else
-#define HERALD " SunOS 4.0"
-#endif /* SUNOS41 */
-#endif /* BSD4 */
-#endif /* SUNOS4 */
-
-#ifdef SUN4S5
-#ifdef HDBUUCP
-#define HERALD " SunOS 4.1 (SVR3)"
-#else
-#define HERALD " SunOS 4.0 (SVR3)"
-#endif /* HDBUUCP */
-#endif /* SUN4S5 */
-
-#ifdef STRATUS
-#define HERALD " Stratus VOS"
-#endif /* STRATUS */
-
-#ifdef TOWER1
-#define HERALD " NCR Tower 1632 OS 1.02"
-#endif /* TOWER1 */
-
-#ifdef TRS16
-#define HERALD " Tandy 16/6000 Xenix 3.0"
-#ifndef CKCPU
-#define CKCPU "mc68000"
-#endif /* CKCPU */
-#endif /* TRS16 */
-
-#ifdef u3b2
-#ifndef HERALD
-#ifdef SVR3
-#define HERALD " AT&T 3B2 System V R3"
-#else
-#define HERALD " AT&T 3B2 System V"
-#endif /* SVR3 */
-#endif /* HERALD */
-#endif /* u3b2 */
-
-#ifdef ultrix
-#ifdef vax
-#ifdef ULTRIX3
-#define HERALD " VAX/ULTRIX 3.0"
-#else
-#define HERALD " VAX/ULTRIX"
-#endif /* ULTRIX3 */
-#else
-#ifdef mips
-#ifdef ULTRIX43
-#define HERALD " DECstation/ULTRIX 4.3"
-#else
-#ifdef ULTRIX44
-#define HERALD " DECstation/ULTRIX 4.4"
-#else
-#ifdef ULTRIX45
-#define HERALD " DECstation/ULTRIX 4.5"
-#else
-#define HERALD " DECstation/ULTRIX"
-#endif /* ULTRIX45 */
-#endif /* ULTRIX44 */
-#endif /* ULTRIX43 */
-#else
-#define HERALD " ULTRIX"
-#endif /* mips */
-#endif /* vax */
-#endif /* ultrix */
-
-#ifdef OXOS
-#define HERALD " Olivetti X/OS"
-#endif /* OXOS */
-
-#ifdef _386BSD
-#define HERALD " 386BSD"
-#endif /* _386BSD */
-
-#ifdef POSIX
-#ifdef PTX
-#ifdef PTX4
-#define HERALD " DYNIX/ptx V4"
-#else
-#define HERALD " DYNIX/ptx"
-#endif /* PTX4 */
-#else /* PTX */
-#ifndef OSF /* Let OSF -DPOSIX keep previously defined HERALD */
-#ifdef HERALD
-#undef HERALD
-#endif /* HERALD */
-#endif /* OSF */
-#ifdef OU8
-#define HERALD " OpenUNIX 8"
-#else
-#ifdef UW7
-#define HERALD " Unixware 7"
-#else
-#ifdef QNX
-#ifdef QNX16
-#define HERALD " QNX 16-bit"
-#else
-#define HERALD " QNX 32-bit"
-#endif /* QNX16 */
-#else
-#ifdef NEUTRINO
-#define HERALD " QNX Neutrino 2"
-#else /* NEUTRINO */
-#ifdef QNX6
-#define HERALD " QNX6"
-#else /* QNX6 */
-#ifdef __linux__
-#ifdef ZSL5500
-#define HERALD " Sharp Zaurus SL-5500"
-#else
-#ifdef RH90
-#define HERALD " Red Hat Linux 9.0"
-#else
-#ifdef RH80
-#define HERALD " Red Hat Linux 8.0"
-#else
-#ifdef RH73
-#define HERALD " Red Hat Linux 7.3"
-#else
-#ifdef RH72
-#define HERALD " Red Hat Linux 7.2"
-#else
-#ifdef RH71
-#define HERALD " Red Hat Linux 7.1"
-#else
-#define HERALD " Linux"
-#endif /* RH71 */
-#endif /* RH72 */
-#endif /* RH73 */
-#endif /* RH80 */
-#endif /* RH90 */
-#endif /* ZSL5500 */
-#else /* __linux__ */
-#ifdef _386BSD /* 386BSD Jolix */
-#define HERALD " 386BSD"
-#else
-#ifdef LYNXOS /* Lynx OS 2.2 */
-#define HERALD " Lynx OS"
-#else
-#ifdef Plan9
-#define HERALD " Plan 9 from Bell Labs"
-#else
-#ifdef SOLARIS11
-#define HERALD " Solaris 11"
-#else
-#ifdef SOLARIS10
-#define HERALD " Solaris 10"
-#else
-#ifdef SOLARIS9
-#define HERALD " Solaris 9"
-#else
-#ifdef SOLARIS8
-#define HERALD " Solaris 8"
-#else
-#ifdef SOLARIS7
-#define HERALD " Solaris 7"
-#else
-#ifdef SOLARIS26
-#define HERALD " Solaris 2.6"
-#else
-#ifdef SOLARIS25
-#define HERALD " Solaris 2.5"
-#else
-#ifdef SOLARIS24
-#define HERALD " Solaris 2.4"
-#else
-#ifdef SOLARIS
-#define HERALD " Solaris 2.x"
-#endif /* SOLARIS */
-#endif /* SOLARIS24 */
-#endif /* SOLARIS25 */
-#endif /* SOLARIS26 */
-#endif /* SOLARIS7 */
-#endif /* SOLARIS8 */
-#endif /* SOLARIS9 */
-#endif /* SOLARIS10 */
-#endif /* SOLARIS11 */
-#endif /* Plan9 */
-#endif /* LYNXOS */
-#endif /* _386BSD */
-#endif /* __linux__ */
-#endif /* QNX6 */
-#endif /* NEUTRINO */
-#endif /* QNX */
-#endif /* UW7 */
-#endif /* OU8 */
-#endif /* PTX */
-#endif /* POSIX */
-
-#ifdef UTS24
-#define HERALD " Amdahl UTS 2.4"
-#endif /* UTS24 */
-
-#ifdef UTSV
-#define HERALD " Amdahl UTS V"
-#endif /* UTSV */
-
-#ifdef VXVE
-#define HERALD " CDC VX/VE 5.2.1 System V"
-#endif /* VXVE */
-
-#ifdef SCO234
-#ifdef HERALD
-#undef HERALD
-#endif /* HERALD */
-#define HERALD " SCO XENIX 2.3.4"
-#else
-#ifdef CK_SCO32V4
-#ifdef HERALD
-#undef HERALD
-#endif /* HERALD */
-#ifdef ODT30
-#define HERALD " SCO ODT 3.0"
-#else
-#define HERALD " SCO UNIX/386 V4"
-#endif /* ODT30 */
-#else
-#ifdef CK_SCOV5
-#ifdef HERALD
-#undef HERALD
-#endif /* HERALD */
-#ifdef SCO_OSR507
-#define HERALD " SCO OpenServer R5.0.7"
-#else
-#ifdef SCO_OSR506A
-#define HERALD " SCO OpenServer R5.0.6a"
-#else
-#ifdef SCO_OSR506
-#define HERALD " SCO OpenServer R5.0.6"
-#else
-#ifdef SCO_OSR505
-#define HERALD " SCO OpenServer R5.0.5"
-#else
-#ifdef SCO_OSR504
-#define HERALD " SCO OpenServer R5.0.4"
-#else
-#ifdef SCO_OSR502
-#define HERALD " SCO OpenServer R5.0.2"
-#else
-#define HERALD " SCO OpenServer R5.0"
-#endif /* SCO_OSR502 */
-#endif /* SCO_OSR504 */
-#endif /* SCO_OSR505 */
-#endif /* SCO_OSR506 */
-#endif /* SCO_OSR506A */
-#endif /* SCO_OSR507 */
-#else
-#ifdef XENIX
-#ifdef HERALD
-#undef HERALD
-#endif /* HERALD */
-#ifdef M_UNIX
-#define HERALD " SCO UNIX/386"
-#else
-#ifdef M_I386
-#define HERALD " Xenix/386"
-#else
-#ifdef M_I286
-#define HERALD " Xenix/286"
-#else
-#define HERALD " Xenix"
-#endif /* M_I286 */
-#endif /* M_I386 */
-#endif /* M_UNIX */
-#endif /* XENIX */
-#endif /* CK_SCOV5 */
-#endif /* CK_SCOV32V4 */
-#endif /* SCO234 */
-
-#ifdef ZILOG
-#define HERALD " Zilog S8000 Zeus 3.21+"
-#endif /* ZILOG */
-
-#ifdef UTEK
-#define HERALD " UTek"
-#endif /* UTEK */
-
-/* Catch-alls for anything not defined explicitly above */
-
-#ifndef HERALD
-#ifdef SVR4
-#ifdef i386
-#define HERALD " AT&T System V/386 R4"
-#else
-#ifdef AMIX
-#define HERALD " Commodore Amiga System V/m68k R4"
-#else
-#define HERALD " AT&T System V R4"
-#endif /* AMIX */
-#endif /* i386 */
-#else
-#ifdef SVR3
-#define HERALD " AT&T System V R3"
-#else
-#ifdef ATTSV
-#define HERALD " AT&T System III / System V"
-#else
-#ifdef BSD43
-#ifdef pdp11
-#define HERALD " 2.10 BSD PDP-11"
-#else
-#ifdef vax
-#define HERALD " 4.3 BSD VAX"
-#else
-#define HERALD " 4.3 BSD"
-#endif /* vax */
-#endif /* pdp11 */
-#else
-#ifdef BSD4
-#ifdef vax
-#define HERALD " 4.2 BSD VAX"
-#else
-#define HERALD " 4.2 BSD"
-#endif /* vax */
-#else
-#ifdef V7
-#define HERALD " UNIX Version 7"
-#endif /* V7 */
-#endif /* BSD4 */
-#endif /* BSD43 */
-#endif /* ATTSV */
-#endif /* SVR3 */
-#endif /* SVR4 */
-#endif /* HERALD */
-#endif /* HERALD */
-
-#ifdef OS2
-#ifdef HERALD
-#undef HERALD
-#endif /* HERALD */
-#ifdef NT
-#define HERALD " 32-bit Windows"
-#else /* NT */
-#define HERALD " 32-bit OS/2"
-#endif /* NT */
-#endif /* OS/2 */
-
-#ifndef HERALD
-#define HERALD " Unknown Version"
-#endif /* HERALD */
-
-/* Hardware type */
-
-#ifdef vax /* DEC VAX */
-#ifndef CKCPU
-#define CKCPU "vax"
-#endif /* CKCPU */
-#endif /* vax */
-#ifdef pdp11 /* DEC PDP-11 */
-#ifndef CKCPU
-#define CKCPU "pdp11"
-#endif /* CKCPU */
-#endif /* pdp11 */
-
-#ifdef __ALPHA /* DEC Alpha */
-#ifndef CKCPU
-#define CKCPU "Alpha"
-#endif /* CKCPU */
-#endif /* __ALPHA */
-
-#ifdef __alpha /* OSF/1 uses lowercase... */
-#ifndef CKCPU
-#define CKCPU "Alpha"
-#endif /* CKCPU */
-#endif /* __alpha */
-
-#ifdef DGUX /* Override Motorola 88k assumption */
-#ifndef CKCPU /* New AViiONs are Intel based... */
-#ifdef i586
-#define CKCPU "i586"
-#else
-#ifdef i486
-#define CKCPU "i486"
-#else
-#ifdef i386
-#define CKCPU "i386"
-#endif /* i386 */
-#endif /* i486 */
-#endif /* i586 */
-#endif /* CKCPU */
-#endif /* DGUX */
-
-/* HP 9000 */
-
-#ifdef __hp9000s700
-#ifndef CKCPU
-#define CKCPU "hp9000s700"
-#endif /* CKCPU */
-#endif /* __hp9000s700 */
-
-#ifdef __hp9000s800
-#ifndef CKCPU
-#define CKCPU "hp9000s800"
-#endif /* CKCPU */
-#endif /* __hp9000s800 */
-
-#ifdef __hp9000s500
-#ifndef CKCPU
-#define CKCPU "hp9000s500"
-#endif /* CKCPU */
-#endif /* __hp9000s500 */
-
-#ifdef __hp9000s400
-#ifndef CKCPU
-#define CKCPU "hp9000s400"
-#endif /* CKCPU */
-#endif /* __hp9000s400 */
-
-#ifdef __hp9000s300
-#ifndef CKCPU
-#define CKCPU "hp9000s300"
-#endif /* CKCPU */
-#endif /* __hp9000s300 */
-
-#ifdef __hp9000s200
-#ifndef CKCPU
-#define CKCPU "hp9000s200"
-#endif /* CKCPU */
-#endif /* __hp9000s200 */
-
-#ifdef m88000 /* Motorola 88000 */
-#ifndef CKCPU
-#define CKCPU "mc88000"
-#endif /* CKCPU */
-#endif /* m88000 */
-#ifdef __using_M88KBCS /* DG symbol for Motorola 88000 */
-#ifndef CKCPU
-#define CKCPU "mc88000"
-#endif /* CKCPU */
-#endif /* __using_M88KBCS */
-#ifdef m88k /* Motorola symbol for 88000 */
-#ifndef CKCPU
-#define CKCPU "mc88000"
-#endif /* CKCPU */
-#endif /* m88k */
-#ifdef mc68040 /* Motorola 68040 */
-#ifndef CKCPU
-#define CKCPU "mc68040"
-#endif /* CKCPU */
-#endif /* mc68040 */
-#ifdef mc68030 /* Motorola 68030 */
-#ifndef CKCPU
-#define CKCPU "mc68030"
-#endif /* CKCPU */
-#endif /* mc68030 */
-#ifdef mc68020 /* Motorola 68020 */
-#ifndef CKCPU
-#define CKCPU "mc68020"
-#endif /* CKCPU */
-#endif /* mc68020 */
-#ifdef mc68010 /* Motorola 68010 */
-#ifndef CKCPU
-#define CKCPU "mc68010"
-#endif /* CKCPU */
-#endif /* mc68010 */
-#ifdef mc68000 /* Motorola 68000 */
-#ifndef CKCPU
-#define CKCPU "mc68000"
-#endif /* CKCPU */
-#endif /* mc68000 */
-#ifdef mc68k /* Ditto (used by DIAB DS90) */
-#ifndef CKCPU
-#define CKCPU "mc68000"
-#endif /* CKCPU */
-#endif /* mc68k */
-#ifdef m68 /* Ditto */
-#ifndef CKCPU
-#define CKCPU "mc68000"
-#endif /* CKCPU */
-#endif /* m68 */
-#ifdef m68k /* Ditto */
-#ifndef CKCPU
-#define CKCPU "mc68000"
-#endif /* CKCPU */
-#endif /* m68k */
-
-#ifdef ia64 /* IA64 / Itanium */
-#ifndef CKCPU
-#define CKCPU "ia64"
-#endif /* CKCPU */
-#endif /* i686 */
-
-#ifdef i686 /* Intel 80686 */
-#ifndef CKCPU
-#define CKCPU "i686"
-#endif /* CKCPU */
-#endif /* i686 */
-
-#ifdef i586 /* Intel 80586 */
-#ifndef CKCPU
-#define CKCPU "i586"
-#endif /* CKCPU */
-#endif /* i586 */
-
-#ifdef i486 /* Intel 80486 */
-#ifndef CKCPU
-#define CKCPU "i486"
-#endif /* CKCPU */
-#endif /* i80486 */
-#ifdef i386 /* Intel 80386 */
-#ifndef CKCPU
-#define CKCPU "i386"
-#endif /* CKCPU */
-#endif /* i80386 */
-#ifdef i286 /* Intel 80286 */
-#ifndef CKCPU
-#define CKCPU "i286"
-#endif /* CKCPU */
-#endif /* i286 */
-#ifdef i186 /* Intel 80186 */
-#ifndef CKCPU
-#define CKCPU "i186"
-#endif /* CKCPU */
-#endif /* i186 */
-#ifdef M_I586 /* Intel 80586 */
-#ifndef CKCPU
-#define CKCPU "i586"
-#endif /* CKCPU */
-#endif /* M_I586 */
-#ifdef M_I486 /* Intel 80486 */
-#ifndef CKCPU
-#define CKCPU "i486"
-#endif /* CKCPU */
-#endif /* M_I486 */
-#ifdef _M_I386 /* Intel 80386 */
-#ifndef CKCPU
-#define CKCPU "i386"
-#endif /* CKCPU */
-#endif /* _M_I386 */
-#ifdef M_I286 /* Intel 80286 */
-#ifndef CKCPU
-#define CKCPU "i286"
-#endif /* CKCPU */
-#endif /* M_I286 */
-#ifdef M_I86 /* Intel 80x86 */
-#ifndef CKCPU
-#define CKCPU "ix86"
-#endif /* CKCPU */
-#endif /* M_I86 */
-#ifdef sparc /* SUN SPARC */
-#ifndef CKCPU
-#define CKCPU "sparc"
-#endif /* CKCPU */
-#endif /* sparc */
-#ifdef mips /* MIPS RISC processor */
-#ifndef CKCPU
-#define CKCPU "mips"
-#endif /* CKCPU */
-#endif /* mips */
-#ifdef _IBMR2 /* IBM RS/6000 */
-#ifndef CKCPU /* (what do they call the chip?) */
-#define CKCPU "rs6000"
-#endif /* CKCPU */
-#endif /* rs6000 */
-#ifdef u3b5 /* WE32000 MAC-32, AT&T 3Bx */
-#ifndef CKCPU
-#define CKCPU "u3b5"
-#endif /* CKCPU */
-#endif /* u3b5 */
-#ifdef n3b
-#ifndef CKCPU
-#define CKCPU "n3b"
-#endif /* CKCPU */
-#endif /* n3b */
-#ifdef u3b
-#ifndef CKCPU
-#define CKCPU "u3b"
-#endif /* CKCPU */
-#endif /* u3b */
-#ifdef n16 /* Encore Multimax */
-#ifndef CKCPU
-#define CKCPU "n16"
-#endif /* CKCPU */
-#endif /* n16 */
-#ifdef u370 /* IBM 370 */
-#ifndef CKCPU
-#define CKCPU "u370"
-#endif /* CKCPU */
-#endif /* u370 */
-#ifdef MAC /* Macintosh catch-all */
-#ifndef CKCPU
-#define CKCPU "mc68000"
-#endif /* CKCPU */
-#endif /* MAC */
-
-#ifdef STRATUS
-#ifndef CKCPU
-#ifdef __I860__
-#define CKCPU "I860 Family"
-#else
-#ifdef __MC68K__
-#define CKCPU "MC680x0 Family"
-#else
-#define CKCPU "Stratus unknown processor"
-#endif /* __MC68K__ */
-#endif /* __I860__ */
-#endif /* CKCPU */
-#endif /* STRATUS */
-
-#ifdef COMMENT
-#ifndef CKCPU /* All others */
-#define CKCPU "unknown"
-#endif /* CKCPU */
-#endif /* COMMENT */
-
-#endif /* CKUVER_H */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuxla.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckuxla.c
deleted file mode 100644
index d5566fa..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuxla.c
+++ /dev/null
@@ -1,7588 +0,0 @@
-#include "ckcsym.h"
-
-#include "ckcdeb.h" /* Includes... */
-#include "ckcker.h"
-#include "ckucmd.h"
-#include "ckcxla.h"
-
-#ifdef NOXFER
-#define zdstuff(a)
-#endif /* NOXFER */
-
-#ifndef NOCSETS
-char *xlav = "Character Set Translation 9.0.044, 2 Jun 2011";
-
-/* C K U X L A */
-
-/* C-Kermit tables and functions supporting character set translation. */
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2011,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/* Character set translation data and functions */
-
-extern int zincnt; /* File i/o macros and variables */
-extern char *zinptr;
-extern int zoutcnt;
-extern char *zoutptr;
-extern int byteorder;
-extern int xfrxla;
-
-int tslevel = TS_L0; /* Transfer syntax level (0,1,2) */
-int tcharset = TC_TRANSP; /* Transfer syntax character set */
-int tcs_save = -1; /* For save/restore term charset */
-int tcs_transp = 0; /* Term charset is TRANSPARENT flag */
-
-#ifdef CKOUNI
-int tcsr = TX_8859_1; /* Remote terminal character set */
-#else /* CKOUNI */
-int tcsr = FC_USASCII;
-#endif /* CKOUNI */
-int language = L_USASCII; /* Language */
-
-#ifdef UNICODE
-int ucsbom = 1; /* Add BOM to new UCS files? */
-int ucsorder = -1; /* Default byte order for UCS files */
-int fileorder = -1; /* Byte order of current file */
- /* 0 = BE, 1 = LE */
-#endif /* UNICODE */
-/*
- Default local file and terminal character set.
- Normally ASCII, but for some systems we know otherwise.
-*/
-int fcs_save = -1;
-#ifdef datageneral /* Data General AOS/VS */
-int fcharset = FC_DGMCS; /* uses the DG International set */
-int dcset8 = FC_DGMCS;
-int dcset7 = FC_USASCII;
-int tcsl = FC_DGMCS;
-#else
-#ifdef NEXT /* The NeXT workstation */
-int fcharset = FC_NEXT; /* uses its own 8-bit set */
-int dcset8 = FC_NEXT;
-int dcset7 = FC_USASCII;
-int tcsl = FC_NEXT;
-#else
-#ifdef MAC /* The Macintosh */
-int fcharset = FC_APPQD; /* uses an extended version of */
-int dcset8 = FC_APPQD;
-int dcset7 = FC_USASCII;
-int tcsl = FC_APPQD; /* Apple Quickdraw */
-#else
-#ifdef AUX
-int fcharset = FC_APPQD; /* Ditto for Apple A/UX */
-int dcset8 = FC_APPQD;
-int dcset7 = FC_USASCII;
-int tcsl = FC_APPQD;
-#else
-#ifdef AMIGA /* The Commodore Amiga */
-int fcharset = FC_1LATIN; /* uses Latin-1 */
-int dcset8 = FC_1LATIN;
-int dcset7 = FC_USASCII;
-int tcsl = FC_1LATIN;
-#else /* All others */
-#ifdef CKOUNI /* OS/2 Unicode */
-int fcharset = FC_1LATIN;
-int dcset8 = FC_1LATIN;
-int dcset7 = FC_USASCII;
-int tcsl = TX_8859_1;
-int prncs = TX_CP437;
-#else /* All others */
-int fcharset = FC_USASCII; /* use ASCII by default */
-int dcset8 = FC_1LATIN; /* But default 8-bit set is Latin-1 */
-int dcset7 = FC_USASCII;
-int tcsl = FC_USASCII;
-int prncs = FC_CP437;
-#endif /* CKOUNI */
-#endif /* AMIGA */
-#endif /* AUX */
-#endif /* MAC */
-#endif /* NEXT */
-#endif /* datageneral */
-
-int s_cset = XMODE_A; /* SEND charset selection = AUTO */
-int r_cset = XMODE_A; /* RECV charset selection = AUTO */
-int afcset[MAXFCSETS+1]; /* Character-set associations */
-int axcset[MAXTCSETS+1];
-int xlatype = XLA_NONE; /* Translation type */
-
-#ifdef UNICODE
-#ifdef CK_ANSIC
-extern int (*xl_utc[MAXTCSETS+1])(USHORT); /* Unicode to TCS */
-extern int (*xl_ufc[MAXFCSETS+1])(USHORT); /* Unicode to FCS */
-extern USHORT (*xl_tcu[MAXTCSETS+1])(CHAR); /* TCS to Unicode */
-extern USHORT (*xl_fcu[MAXFCSETS+1])(CHAR); /* FCS to Unicode */
-#else
-extern int (*xl_utc[MAXTCSETS+1])();
-extern int (*xl_ufc[MAXFCSETS+1])();
-extern USHORT (*xl_tcu[MAXTCSETS+1])();
-extern USHORT (*xl_fcu[MAXFCSETS+1])();
-#endif /* CK_ANSIC */
-#endif /* UNICODE */
-
-/* Bureaucracy section */
-
-_PROTOTYP( CHAR xnel1, (CHAR c) ); /* NeXT to Latin-1 */
-_PROTOTYP( CHAR xl143, (CHAR c) ); /* Latin-1 to IBM CP437 */
-_PROTOTYP( CHAR xl1as, (CHAR c) ); /* Latin-1 to US ASCII */
-_PROTOTYP( CHAR zl1as, (CHAR c) ); /* Latin-1 to US ASCII */
-
-#ifdef CYRILLIC
-_PROTOTYP( CHAR xassk, (CHAR c) ); /* ASCII to Short KOI */
-_PROTOTYP( CHAR xskcy, (CHAR c) ); /* Short KOI to Latin/Cyrillic */
-#endif /* CYRILLIC */
-
-#ifdef LATIN2
-_PROTOTYP( CHAR xnel2, (CHAR c) ); /* NeXT to Latin-2 */
-_PROTOTYP( CHAR xl243, (CHAR c) ); /* Latin-2 to IBM CP437 */
-_PROTOTYP( CHAR xl2as, (CHAR c) ); /* Latin-2 to US ASCII */
-_PROTOTYP( CHAR zl2as, (CHAR c) ); /* Latin-2 to US ASCII */
-_PROTOTYP( CHAR xl2r8, (CHAR c) ); /* Latin-2 to HP */
-_PROTOTYP( CHAR xl2l9, (CHAR c) ); /* Latin-2 to Latin-9 */
-_PROTOTYP( CHAR xl9l2, (CHAR c) ); /* Latin-9 to Latin-2 */
-_PROTOTYP( CHAR xl2mz, (CHAR c) ); /* Latin-2 to Mazovia */
-_PROTOTYP( CHAR xmzl2, (CHAR c) ); /* Mazovia to Latin-2 */
-_PROTOTYP( CHAR xl1mz, (CHAR c) ); /* Latin-1 to Mazovia */
-_PROTOTYP( CHAR xmzl1, (CHAR c) ); /* Mazovia to Latin-1 */
-_PROTOTYP( CHAR xmzl9, (CHAR c) ); /* Latin-9 to Mazovia */
-_PROTOTYP( CHAR xl9mz, (CHAR c) ); /* Mazovia to Latin-9 */
-#endif /* LATIN2 */
-
-/* Transfer character-set info */
-
-struct csinfo tcsinfo[] = {
-/* Name size code designator alphabet keyword */
- "TRANSPARENT", 256,TC_TRANSP, "", AL_UNK, "transparent", /* 0 */
- "ASCII", 128,TC_USASCII,"", AL_ROMAN,"ascii", /* 1 */
- "ISO 8859-1 Latin-1",256,TC_1LATIN, "I6/100",AL_ROMAN,"latin1-iso", /* 2 */
-#ifdef LATIN2
- "ISO 8859-2 Latin-2",256,TC_2LATIN, "I6/101",AL_ROMAN,"latin2-iso", /* 3 */
-#endif /* LATIN2 */
-#ifdef CYRILLIC
- /* 4 */
- "ISO 8859-5 Latin/Cyrillic",256,TC_CYRILL,"I6/144",AL_CYRIL,"cyrillic-iso",
-#endif /* CYRILLIC */
-#ifdef KANJI
- "Japanese EUC",16384,TC_JEUC, "I14/87/13", AL_JAPAN, "euc-jp", /* 5 */
-#endif /* KANJI */
-#ifdef HEBREW
- /* 6 */
- "ISO 8859-8 Latin/Hebrew",256,TC_HEBREW,"I6/138",AL_HEBREW,"hebrew-iso",
-#endif /* HEBREW */
-#ifdef GREEK
- "ISO 8859-7 Latin/Greek",256,TC_GREEK,"I6/126",AL_GREEK,"greek-iso", /* 7 */
-#endif /* GREEK */
- "ISO 8859-15 Latin-9",256,TC_9LATIN,"I6/203",AL_ROMAN,"latin9-iso", /* 8 */
- "ISO 10646 / Unicode UCS-2",64000,TC_UCS2,"I162",AL_UNIV,"ucs2", /* 9 */
- "ISO 10646 / Unicode UTF-8",64000,TC_UTF8,"I190",AL_UNIV,"utf8", /* 10 */
- "",0,0,"",0,""
-};
-int ntcsets = (sizeof(tcsinfo) / sizeof(struct csinfo)) - 1;
-
-struct keytab tcstab[] = { /* Keyword table for */
- "ascii", TC_USASCII, 0, /* SET TRANSFER CHARACTER-SET */
-#ifdef CYRILLIC
- "cyrillic-iso", TC_CYRILL, 0,
-#endif /* CYRILLIC */
-#ifdef GREEK
- "elot928-greek", TC_GREEK, CM_INV,
-#endif /* GREEK */
-#ifdef KANJI
- "euc-jp", TC_JEUC, 0,
-#endif /* KANJI */
-#ifdef GREEK
- "greek-iso", TC_GREEK, 0,
-#endif /* GREEK */
-#ifdef HEBREW
- "hebrew-iso", TC_HEBREW, 0,
-#endif /* HEBREW */
-
-#ifdef UNICODE
- "iso-10646-ucs-2", TC_UCS2, CM_INV, /* ISO 10646 / Unicode UCS-2 */
-#endif /* UNICODE */
- "iso-8859-1", TC_1LATIN, CM_INV, /* ISO Latin Alphabet 1 */
- "iso-8859-15", TC_9LATIN, CM_INV, /* ISO Latin Alphabet 9 (yes) */
- "iso-8859-2", TC_2LATIN, CM_INV, /* ISO Latin Alphabet 2 */
-#ifdef CYRILLIC
- "iso-8859-5", TC_CYRILL, CM_INV, /* ISO Latin/Cyrillic Alphabet */
-#endif /* CYRILLIC */
-#ifdef GREEK
- "iso-8859-7", TC_GREEK, CM_INV, /* ISO 8859-7 Latin/Greek */
-#endif /* GREEK */
-#ifdef HEBREW
- "iso-8859-8", TC_HEBREW, CM_INV, /* ISO Latin/Hebrew */
-#endif /* HEBREW */
-
-#ifdef KANJI
- "japanese-euc", TC_JEUC, CM_INV,
-#endif /* KANJI */
- "l", TC_1LATIN, CM_ABR|CM_INV,
- "la", TC_1LATIN, CM_ABR|CM_INV,
- "lat", TC_1LATIN, CM_ABR|CM_INV,
- "lati", TC_1LATIN, CM_ABR|CM_INV,
- "latin", TC_1LATIN, CM_ABR|CM_INV,
- "latin1-iso", TC_1LATIN, 0,
-#ifdef LATIN2
- "latin2-iso", TC_2LATIN, 0,
-#endif /* LATIN2 */
- "latin9-iso", TC_9LATIN, 0,
- "transparent", TC_TRANSP, 0,
-#ifdef UNICODE
- "ucs2", TC_UCS2, 0,
-#endif /* UNICODE */
- "us-ascii", TC_USASCII, CM_INV,
- "usascii", TC_USASCII, CM_INV,
-#ifdef UNICODE
- "utf-8", TC_UTF8, CM_INV,
- "utf8", TC_UTF8, 0,
-#endif /* UNICODE */
- "", 0, 0
-};
-int ntcs = (sizeof(tcstab) / sizeof(struct keytab)) - 1;
-
-/* File character set information structure, indexed by character set code, */
-/* as defined in ckuxla.h. This table must be in order of file character */
-/* set number! */
-
-struct csinfo fcsinfo[] = { /* File character set information... */
- /* Descriptive Name Size Designator */
- "US ASCII", 128, FC_USASCII, NULL, AL_ROMAN, "ascii",
- "British/UK ISO-646", 128, FC_UKASCII, NULL, AL_ROMAN, "british",
- "Dutch ISO-646", 128, FC_DUASCII, NULL, AL_ROMAN, "dutch",
- "Finnish ISO-646", 128, FC_FIASCII, NULL, AL_ROMAN, "finnish",
- "French ISO-646", 128, FC_FRASCII, NULL, AL_ROMAN, "french",
- "Canadian-French NRC", 128, FC_FCASCII, NULL, AL_ROMAN, "canadian-french",
- "German ISO-646", 128, FC_GEASCII, NULL, AL_ROMAN, "german",
- "Hungarian ISO-646", 128, FC_HUASCII, NULL, AL_ROMAN, "hungarian",
- "Italian ISO-646", 128, FC_ITASCII, NULL, AL_ROMAN, "italian",
- "Norwegian/Danish ISO-646",128,FC_NOASCII,NULL,AL_ROMAN,"norwegian/danish",
- "Portuguese ISO-646", 128, FC_POASCII, NULL, AL_ROMAN,"portuguese",
- "Spanish ISO-646", 128, FC_SPASCII, NULL, AL_ROMAN, "spanish",
- "Swedish ISO-646", 128, FC_SWASCII, NULL, AL_ROMAN, "swedish",
- "Swiss NRC", 128, FC_CHASCII, NULL, AL_ROMAN, "swiss",
- "ISO 8859-1 Latin-1", 256, FC_1LATIN, NULL, AL_ROMAN,"latin1-iso",
- "ISO 8859-2 Latin-2", 256, FC_2LATIN, NULL, AL_ROMAN,"latin2-iso",
- "DEC Multinational", 256, FC_DECMCS, NULL,AL_ROMAN,"dec-multinational",
- "NeXT Multinational", 256, FC_NEXT, NULL,AL_ROMAN,"next-multinational",
- "PC Code Page 437", 256, FC_CP437, NULL, AL_ROMAN,"cp437",
- "PC Code Page 850", 256, FC_CP850, NULL, AL_ROMAN,"cp850",
- "PC Code Page 852", 256, FC_CP852, NULL, AL_ROMAN,"cp852",
- "Apple Macintosh Latin", 256, FC_APPQD, NULL, AL_ROMAN,"macintosh-latin",
- "Data General International",256,FC_DGMCS,NULL,AL_ROMAN,"dg-international",
- "Hewlett Packard Roman8", 256, FC_HPR8, NULL, AL_ROMAN, "hp-roman8",
- "ISO 8859-5 Latin/Cyrillic", 256, FC_CYRILL, NULL, AL_CYRIL,"cyrillic-iso",
- "CP866 Cyrillic", 256, FC_CP866, NULL, AL_CYRIL,"cp866",
- "Short KOI", 128, FC_KOI7, NULL, AL_CYRIL,"short-koi",
- "Old KOI-8 Cyrillic", 256, FC_KOI8, NULL, AL_CYRIL,"koi8-cyrillic",
- "Japanese JIS7", 16384, FC_JIS7, NULL, AL_JAPAN, "jis7-kanji",
- "Japanese Shift JIS", 16384, FC_SHJIS, NULL, AL_JAPAN, "shift-jis-kanji",
- "Japanese EUC", 16384, FC_JEUC, NULL, AL_JAPAN, "euc-jp",
- "Japanese DEC Kanji", 16384, FC_JDEC, NULL, AL_JAPAN, "dec-kanji",
- "Hebrew-7 DEC", 128, FC_HE7, NULL, AL_HEBREW, "hebrew-7",
- "ISO 8859-8 Latin/Hebrew",256, FC_HEBREW, NULL, AL_HEBREW, "hebrew-iso",
- "CP862 Hebrew", 256, FC_CP862, NULL, AL_HEBREW, "cp862-hebrew",
- "ELOT 927 Greek", 128, FC_ELOT, NULL, AL_GREEK, "elot927-greek",
- "ISO 8859-7 Latin/Greek", 256, FC_GREEK, NULL, AL_GREEK, "greek-iso",
- "CP869 Greek", 256, FC_CP869, NULL, AL_GREEK, "cp869-greek",
- "ISO 8859-15 Latin-9", 256, FC_9LATIN, NULL, AL_ROMAN, "latin9-iso",
- "PC Code Page 858", 256, FC_CP850, NULL, AL_ROMAN, "cp858",
- "PC Code Page 855", 256, FC_CP855, NULL, AL_CYRIL, "cp855-cyrillic",
- "Windows Code Page 1251", 256, FC_CP1251, NULL, AL_CYRIL, "cp1251-cyrillic",
- "Bulgarian PC Code Page", 256, FC_BULGAR, NULL, AL_CYRIL, "bulgaria-pc",
- "Windows Code Page 1250", 256, FC_CP1250, NULL, AL_ROMAN, "cp1250",
- "Polish Mazovia PC Code Page", 256, FC_MAZOVIA, NULL, AL_ROMAN, "mazovia-pc",
- "ISO 10646 / Unicode UCS-2", 64000, FC_UCS2, NULL, AL_UNIV, "ucs2",
- "ISO 10646 / Unicode UTF-8", 64000, FC_UCS2, NULL, AL_UNIV, "utf8",
- "KOI8-R Russian+Boxdrawing",256, FC_KOI8R, NULL, AL_CYRIL,"koi8r",
- "KOI8-U Ukrainian+Boxdrawing",256,FC_KOI8U, NULL, AL_CYRIL,"koi8u",
- "Windows Code Page 1252", 256, FC_CP1252, NULL, AL_ROMAN, "cp1252",
- "",0,0,NULL,0,NULL
-};
-
-/* Local file character sets */
-/* Includes 7-bit National Replacement Character Sets of ISO 646 */
-/* Plus ISO Latin-1, DEC Multinational Character Set (MCS), NeXT char set, */
-/* Various PC and Windows code pages, etc. */
-/* As of C-Kermit 9.0 MIME names are included as invisible synomyms for */
-/* those character sets that have MIME names. */
-
-struct keytab fcstab[] = { /* Keyword table for 'set file character-set' */
-/*
- IMPORTANT: This table is replicated below as ttcstab (terminal character
- set table). The only differences are the addition of TRANSPARENT
- and the removal of the Kanji sets, which are not supported for terminal
- emulation. If you make changes to this table, also change ttcstab.
-*/
-
-/* Keyword Value Flags */
- "apple-quickdraw", FC_APPQD, CM_INV, /* Apple Quickdraw */
- "ascii", FC_USASCII, 0, /* ASCII */
- "british", FC_UKASCII, 0, /* British NRC */
- "bulgaria-pc", FC_BULGAR, 0, /* Bulgarian PC Code Page */
- "canadian-french", FC_FCASCII, 0, /* French Canadian NRC */
-#ifdef LATIN2
- "cp1250", FC_CP1250, 0, /* Windows CP 1250 */
-#endif /* LATIN2 */
-#ifdef CYRILLIC
- "cp1251-cyrillic", FC_CP1251, 0, /* Windows CP 1251 */
-#endif /* CYRILLIC */
- "cp1252", FC_CP1252, 0, /* Windows CP 1252 */
- "cp437", FC_CP437, 0, /* PC CP437 */
- "cp850", FC_CP850, 0, /* PC CP850 */
-#ifdef LATIN2
- "cp852", FC_CP852, 0, /* PC CP852 */
-#endif /* LATIN2 */
-#ifdef CYRILLIC
- "cp855-cyrillic", FC_CP855, 0, /* PC CP855 */
-#endif /* CYRILLIC */
- "cp858", FC_CP858, 0, /* PC CP858 */
-#ifdef HEBREW
- "cp862-hebrew", FC_CP862, 0, /* PC CP862 */
-#endif /* HEBREW */
-#ifdef CYRILLIC
- "cp866-cyrillic", FC_CP866, 0, /* CP866 Cyrillic */
-#endif /* CYRILLIC */
-#ifdef GREEK
- "cp869-greek", FC_CP869, 0, /* CP869 Greek */
-#endif /* GREEK */
-#ifdef CYRILLIC
- "cyrillic-iso", FC_CYRILL, 0, /* ISO Latin/Cyrillic Alphabet */
-#endif /* CYRILLIC */
- "danish", FC_NOASCII, 0, /* Norwegian and Danish NRC */
-#ifdef KANJI
- "dec-kanji", FC_JDEC, 0, /* Japanese DEC Kanji */
-#endif /* KANJI */
- "dec-mcs", FC_DECMCS, CM_INV, /* DEC multinational char set */
- "dec-multinational", FC_DECMCS, 0, /* DEC multinational character set */
- "dg-international", FC_DGMCS, 0, /* Data General multinational */
- "dutch", FC_DUASCII, 0, /* Dutch NRC */
-#ifdef GREEK
- "elot927-greek", FC_ELOT, 0, /* ELOT 927 Greek */
- "elot928-greek", FC_GREEK, 0, /* Same as ISO 8859-7 Latin/Greek */
-#endif /* GREEK */
-#ifdef KANJI
- "euc-jp", FC_JEUC, 0, /* Japanese EUC */
-#endif /* KANJI */
- "finnish", FC_FIASCII, 0, /* Finnish NRC */
- "french", FC_FRASCII, 0, /* French NRC */
- "fr-canadian", FC_FCASCII, CM_INV, /* French Canadian NRC */
- "german", FC_GEASCII, 0, /* German NRC */
-#ifdef GREEK
- "greek-iso", FC_GREEK, 0, /* ISO 8859-7 Latin/Greek */
-#endif /* GREEK */
-#ifdef HEBREW
- "he", FC_HEBREW, CM_ABR|CM_INV,
- "heb", FC_HEBREW, CM_ABR|CM_INV,
- "hebr", FC_HEBREW, CM_ABR|CM_INV,
- "hebre", FC_HEBREW, CM_ABR|CM_INV,
- "hebrew", FC_HEBREW, CM_ABR|CM_INV,
- "hebrew-7", FC_HE7, 0, /* DEC 7-Bit Hebrew */
- "hebrew-iso", FC_HEBREW, 0, /* ISO Latin/Hebrew */
-#endif /* HEBREW */
- "hp-roman8", FC_HPR8, 0, /* Hewlett Packard Roman8 */
- "hungarian", FC_HUASCII, 0, /* Hungarian NRC */
-
- "ibm437", FC_CP437, CM_INV, /* PC CP437 */
- "ibm850", FC_CP850, CM_INV, /* PC CP850 (not in MIME) */
-#ifdef LATIN2
- "ibm852", FC_CP852, CM_INV, /* PC CP852 */
-#endif /* LATIN2 */
-#ifdef CYRILLIC
- "ibm855", FC_CP855, CM_INV, /* PC CP855 */
-#endif /* CYRILLIC */
- "ibm858", FC_CP858, CM_INV, /* PC CP858 (not in MIME) */
-#ifdef HEBREW
- "ibm862", FC_CP862, CM_INV, /* PC CP862 (not in MIME) */
-#endif /* HEBREW */
-#ifdef CYRILLIC
- "ibm866", FC_CP866, CM_INV, /* CP866 Cyrillic */
-#endif /* CYRILLIC */
-#ifdef GREEK
- "ibm869", FC_CP869, CM_INV, /* CP869 Greek */
-#endif /* GREEK */
-
-#ifdef UNICODE
- "iso-10646-ucs-2", FC_UCS2, CM_INV, /* ISO 10646 / Unicode UCS-2 */
-#endif /* UNICODE */
- "iso-8859-1", FC_1LATIN, CM_INV, /* ISO Latin Alphabet 1 */
- "iso-8859-15", FC_9LATIN, CM_INV, /* ISO Latin Alphabet 9 (yes) */
- "iso-8859-2", FC_2LATIN, CM_INV, /* ISO Latin Alphabet 2 */
-#ifdef CYRILLIC
- "iso-8859-5", FC_CYRILL, CM_INV, /* ISO Latin/Cyrillic Alphabet */
-#endif /* CYRILLIC */
-#ifdef GREEK
- "iso-8859-7", FC_GREEK, CM_INV, /* ISO 8859-7 Latin/Greek */
-#endif /* GREEK */
-#ifdef HEBREW
- "iso-8859-8", FC_HEBREW, CM_INV, /* ISO Latin/Hebrew */
-#endif /* HEBREW */
-#ifdef KANJI
- "iso2022jp-kanji", FC_JIS7, CM_INV, /* Synonym for JIS-7 */
-#endif /* KANJI */
-
- "iso646-gb", FC_UKASCII, CM_INV, /* British NRC */
- "iso646-ca", FC_FCASCII, CM_INV, /* French Canadian NRC */
- "iso646-de", FC_GEASCII, CM_INV, /* German NRC */
- "iso646-dk", FC_NOASCII, CM_INV, /* Norwegian and Danish NRC */
- "iso646-es", FC_SPASCII, CM_INV, /* Spanish NRC */
- "iso646-fi", FC_FIASCII, CM_INV, /* Finnish NRC */
- "iso646-fr", FC_FRASCII, CM_INV, /* French NRC */
- "iso646-hu", FC_HUASCII, CM_INV, /* Hungarian NRC */
- "iso646-it", FC_ITASCII, CM_INV, /* Italian NRC */
- "iso646-no", FC_NOASCII, CM_INV, /* Norwegian and Danish NRC */
- "iso646-po", FC_POASCII, CM_INV, /* Portuguese NRC */
- "iso646-se", FC_SWASCII, CM_INV, /* Swedish NRC */
-
- "italian", FC_ITASCII, CM_INV, /* Italian NRC */
-#ifdef KANJI
- "japanese-euc", FC_JEUC, CM_INV, /* Japanese EUC */
- "jis7-kanji", FC_JIS7, 0, /* Japanese JIS7 7bit code */
-#endif /* KANJI */
-#ifdef CYRILLIC
- "k", FC_KOI8, CM_ABR|CM_INV,
- "ko", FC_KOI8, CM_ABR|CM_INV,
- "koi", FC_KOI8, CM_ABR|CM_INV,
- "koi7", FC_KOI7, 0, /* Short KOI Cyrillic */
- "koi8", FC_KOI8, 0, /* Old KOI-8 Cyrillic */
- "koi8-e", FC_KOI8, CM_INV, /* Old KOI-8 Cyrillic */
- "koi8-cyrillic", FC_KOI8, CM_INV,
- "koi8-r", FC_KOI8R, CM_INV, /* KOI8-R RFC1489 */
- "koi8-u", FC_KOI8U, CM_INV, /* KOI8-U RFC2319 */
- "koi8r", FC_KOI8R, 0, /* KOI8-R RFC1489 */
- "koi8u", FC_KOI8U, 0, /* KOI8-U RFC2319 */
-#endif /* CYRILLIC */
- "l", FC_1LATIN, CM_ABR|CM_INV,
- "la", FC_1LATIN, CM_ABR|CM_INV,
- "lat", FC_1LATIN, CM_ABR|CM_INV,
- "lati", FC_1LATIN, CM_ABR|CM_INV,
- "latin", FC_1LATIN, CM_ABR|CM_INV,
- "latin1-iso", FC_1LATIN, 0, /* ISO Latin Alphabet 1 */
-#ifdef LATIN2
- "latin2-iso", FC_2LATIN, 0, /* ISO Latin Alphabet 2 */
-#endif /* LATIN2 */
- "latin9-iso", FC_9LATIN, 0, /* ISO Latin Alphabet 9 */
- "macintosh-latin", FC_APPQD, 0, /* "Extended Mac Latin" */
-#ifdef LATIN2
- "mazovia-pc", FC_MAZOVIA, 0, /* Polish Mazovia PC code page */
-#endif /* LATIN2 */
- "next-multinational", FC_NEXT, 0, /* NeXT workstation */
- "norwegian", FC_NOASCII, 0, /* Norwegian and Danish NRC */
- "portuguese", FC_POASCII, 0, /* Portuguese NRC */
-#ifdef KANJI
- "shift-jis-kanji", FC_SHJIS, 0, /* Japanese Kanji Shift-JIS */
- "shift_jis", FC_SHJIS, CM_INV, /* Japanese Kanji Shift-JIS */
-#endif /* KANJI */
-#ifdef CYRILLIC
- "short-koi", FC_KOI7, 0, /* Short KOI Cyrillic */
-#endif /* CYRILLIC */
- "spanish", FC_SPASCII, 0, /* Spanish NRC */
- "swedish", FC_SWASCII, 0, /* Swedish NRC */
- "swiss", FC_CHASCII, 0, /* Swiss NRC */
-#ifdef UNICODE
- "ucs2", FC_UCS2, 0, /* ISO 10646 / Unicode UCS-2 */
-#endif /* UNICODE */
- "us-ascii", FC_USASCII, CM_INV, /* MIME */
- "usascii", FC_USASCII, CM_INV,
-#ifdef UNICODE
- "utf-8", FC_UTF8, CM_INV, /* ISO 10646 / Unicode UTF-8 */
- "utf8", FC_UTF8, 0, /* ISO 10646 / Unicode UTF-8 */
-#endif /* UNICODE */
-#ifdef LATIN2
- "windows-1250", FC_CP1250, CM_INV, /* Windows CP 1250 */
-#endif /* LATIN2 */
-#ifdef CYRILLIC
- "windows-1251", FC_CP1251, CM_INV, /* Windows CP 1251 */
-#endif /* CYRILLIC */
- "windows-1252", FC_CP1252, CM_INV, /* Windows CP 1252 */
- "", 0, 0
-};
-int nfilc = (sizeof(fcstab) / sizeof(struct keytab)) - 1;
-
-struct keytab ttcstab[] = { /* Keyword table for SET TERMINAL CHARACTER-SET */
-/*
- IMPORTANT: This table is a replica of fcstab, immediately above, with the
- addition of TRANSPARENT and deletion of the Japanese sets. If you make
- changes to this table, make the corresponding changes to fcstab.
-*/
-/* Keyword Value Flags */
- "apple-quickdraw", FC_APPQD, CM_INV, /* Apple Quickdraw */
- "ascii", FC_USASCII, 0, /* ASCII */
- "british", FC_UKASCII, 0, /* British NRC */
- "bulgaria-pc", FC_BULGAR, 0, /* Bulgarian PC Code Page */
- "canadian-french", FC_FCASCII, 0, /* French Canadian NRC */
-#ifdef LATIN2
- "cp1250", FC_CP1250, 0, /* Windows CP 1250 */
-#endif /* LATIN2 */
-#ifdef CYRILLIC
- "cp1251-cyrillic", FC_CP1251, 0, /* Windows CP 1251 */
-#endif /* CYRILLIC */
- "cp1252", FC_CP1252, 0, /* Windows CP 1252 */
- "cp437", FC_CP437, 0, /* PC CP437 */
- "cp850", FC_CP850, 0, /* PC CP850 */
-#ifdef LATIN2
- "cp852", FC_CP852, 0, /* PC CP852 */
-#endif /* LATIN2 */
-#ifdef CYRILLIC
- "cp855-cyrillic", FC_CP855, 0, /* PC CP855 */
-#endif /* CYRILLIC */
- "cp858", FC_CP858, 0, /* PC CP858 */
-#ifdef HEBREW
- "cp862-hebrew", FC_CP862, 0, /* PC CP862 */
-#endif /* HEBREW */
-#ifdef CYRILLIC
- "cp866-cyrillic", FC_CP866, 0, /* CP866 Cyrillic */
-#endif /* CYRILLIC */
-#ifdef GREEK
- "cp869-greek", FC_CP869, 0, /* CP869 Greek */
-#endif /* GREEK */
-#ifdef CYRILLIC
- "cyrillic-iso", FC_CYRILL, 0, /* ISO Latin/Cyrillic Alphabet */
-#endif /* CYRILLIC */
- "danish", FC_NOASCII, 0, /* Norwegian and Danish NRC */
- "dec-mcs", FC_DECMCS, CM_INV, /* DEC multinational char set */
- "dec-multinational", FC_DECMCS, 0, /* DEC multinational character set */
- "dg-international", FC_DGMCS, 0, /* Data General multinational */
- "dutch", FC_DUASCII, 0, /* Dutch NRC */
-#ifdef GREEK
- "elot927-greek", FC_ELOT, 0, /* ELOT 927 Greek */
- "elot928-greek", FC_GREEK, 0, /* Same as ISO 8859-7 Latin/Greek */
-#endif /* GREEK */
- "finnish", FC_FIASCII, 0, /* Finnish NRC */
- "french", FC_FRASCII, 0, /* French NRC */
- "fr-canadian", FC_FCASCII, CM_INV, /* French Canadian NRC */
- "german", FC_GEASCII, 0, /* German NRC */
-#ifdef GREEK
- "greek-iso", FC_GREEK, 0, /* ISO 8859-7 Latin/Greek */
-#endif /* GREEK */
-#ifdef HEBREW
- "he", FC_HEBREW, CM_ABR|CM_INV,
- "heb", FC_HEBREW, CM_ABR|CM_INV,
- "hebr", FC_HEBREW, CM_ABR|CM_INV,
- "hebre", FC_HEBREW, CM_ABR|CM_INV,
- "hebrew", FC_HEBREW, CM_ABR|CM_INV,
- "hebrew-7", FC_HE7, 0, /* DEC 7-Bit Hebrew */
- "hebrew-iso", FC_HEBREW, 0, /* ISO Latin/Hebrew */
-#endif /* HEBREW */
- "hp-roman8", FC_HPR8, 0, /* Hewlett Packard Roman8 */
- "hungarian", FC_HUASCII, 0, /* Hungarian NRC */
-
- "ibm437", FC_CP437, CM_INV, /* PC CP437 */
- "ibm850", FC_CP850, CM_INV, /* PC CP850 (not in MIME) */
-#ifdef LATIN2
- "ibm852", FC_CP852, CM_INV, /* PC CP852 */
-#endif /* LATIN2 */
-#ifdef CYRILLIC
- "ibm855", FC_CP855, CM_INV, /* PC CP855 */
-#endif /* CYRILLIC */
- "ibm858", FC_CP858, CM_INV, /* PC CP858 (not in MIME) */
-#ifdef HEBREW
- "ibm862", FC_CP862, CM_INV, /* PC CP862 (not in MIME) */
-#endif /* HEBREW */
-#ifdef CYRILLIC
- "ibm866", FC_CP866, CM_INV, /* CP866 Cyrillic */
-#endif /* CYRILLIC */
-#ifdef GREEK
- "ibm869", FC_CP869, CM_INV, /* CP869 Greek */
-#endif /* GREEK */
-
-#ifdef UNICODE
- "iso-10646-ucs-2", FC_UCS2, CM_INV, /* ISO 10646 / Unicode UCS-2 */
-#endif /* UNICODE */
- "iso-8859-1", FC_1LATIN, CM_INV, /* ISO Latin Alphabet 1 */
- "iso-8859-15", FC_9LATIN, CM_INV, /* ISO Latin Alphabet 9 (yes) */
- "iso-8859-2", FC_2LATIN, CM_INV, /* ISO Latin Alphabet 2 */
-#ifdef CYRILLIC
- "iso-8859-5", FC_CYRILL, CM_INV, /* ISO Latin/Cyrillic Alphabet */
-#endif /* CYRILLIC */
-#ifdef GREEK
- "iso-8859-7", FC_GREEK, CM_INV, /* ISO 8859-7 Latin/Greek */
-#endif /* GREEK */
-#ifdef HEBREW
- "iso-8859-8", FC_HEBREW, CM_INV, /* ISO Latin/Hebrew */
-#endif /* HEBREW */
-
- "iso646-gb", FC_UKASCII, CM_INV, /* British NRC */
- "iso646-ca", FC_FCASCII, CM_INV, /* French Canadian NRC */
- "iso646-de", FC_GEASCII, CM_INV, /* German NRC */
- "iso646-dk", FC_NOASCII, CM_INV, /* Norwegian and Danish NRC */
- "iso646-es", FC_SPASCII, CM_INV, /* Spanish NRC */
- "iso646-fi", FC_FIASCII, CM_INV, /* Finnish NRC */
- "iso646-fr", FC_FRASCII, CM_INV, /* French NRC */
- "iso646-hu", FC_HUASCII, CM_INV, /* Hungarian NRC */
- "iso646-it", FC_ITASCII, CM_INV, /* Italian NRC */
- "iso646-no", FC_NOASCII, CM_INV, /* Norwegian and Danish NRC */
- "iso646-po", FC_POASCII, CM_INV, /* Portuguese NRC */
- "iso646-se", FC_SWASCII, CM_INV, /* Swedish NRC */
-
- "italian", FC_ITASCII, CM_INV, /* Italian NRC */
-
-#ifdef CYRILLIC
- "k", FC_KOI8, CM_ABR|CM_INV,
- "ko", FC_KOI8, CM_ABR|CM_INV,
- "koi", FC_KOI8, CM_ABR|CM_INV,
- "koi7", FC_KOI7, 0, /* Short KOI Cyrillic */
- "koi8", FC_KOI8, 0, /* Old KOI-8 Cyrillic */
- "koi8-e", FC_KOI8, CM_INV, /* Old KOI-8 Cyrillic */
- "koi8-cyrillic", FC_KOI8, CM_INV,
- "koi8-r", FC_KOI8R, CM_INV, /* KOI8-R RFC1489 */
- "koi8-u", FC_KOI8U, CM_INV, /* KOI8-U RFC2319 */
- "koi8r", FC_KOI8R, 0, /* KOI8-R RFC1489 */
- "koi8u", FC_KOI8U, 0, /* KOI8-U RFC2319 */
-#endif /* CYRILLIC */
- "l", FC_1LATIN, CM_ABR|CM_INV,
- "la", FC_1LATIN, CM_ABR|CM_INV,
- "lat", FC_1LATIN, CM_ABR|CM_INV,
- "lati", FC_1LATIN, CM_ABR|CM_INV,
- "latin", FC_1LATIN, CM_ABR|CM_INV,
- "latin1-iso", FC_1LATIN, 0, /* ISO Latin Alphabet 1 */
-#ifdef LATIN2
- "latin2-iso", FC_2LATIN, 0, /* ISO Latin Alphabet 2 */
-#endif /* LATIN2 */
- "latin9-iso", FC_9LATIN, 0, /* ISO Latin Alphabet 9 */
- "macintosh-latin", FC_APPQD, 0, /* "Extended Mac Latin" */
-#ifdef LATIN2
- "mazovia-pc", FC_MAZOVIA, 0, /* Polish Mazovia PC code page */
-#endif /* LATIN2 */
- "next-multinational", FC_NEXT, 0, /* NeXT workstation */
- "norwegian", FC_NOASCII, 0, /* Norwegian and Danish NRC */
- "portuguese", FC_POASCII, 0, /* Portuguese NRC */
-
-#ifdef CYRILLIC
- "short-koi", FC_KOI7, 0, /* Short KOI Cyrillic */
-#endif /* CYRILLIC */
- "spanish", FC_SPASCII, 0, /* Spanish NRC */
- "swedish", FC_SWASCII, 0, /* Swedish NRC */
- "swiss", FC_CHASCII, 0, /* Swiss NRC */
- "transparent", FC_TRANSP, 0, /* Transparent */
-#ifdef UNICODE
- "ucs2", FC_UCS2, 0, /* ISO 10646 / Unicode UCS-2 */
-#endif /* UNICODE */
- "us-ascii", FC_USASCII, CM_INV, /* MIME */
- "usascii", FC_USASCII, CM_INV,
-#ifdef UNICODE
- "utf-8", FC_UTF8, CM_INV, /* ISO 10646 / Unicode UTF-8 */
- "utf8", FC_UTF8, 0, /* ISO 10646 / Unicode UTF-8 */
-#endif /* UNICODE */
-#ifdef LATIN2
- "windows-1250", FC_CP1250, CM_INV, /* Windows CP 1250 */
-#endif /* LATIN2 */
-#ifdef CYRILLIC
- "windows-1251", FC_CP1251, CM_INV, /* Windows CP 1251 */
-#endif /* CYRILLIC */
- "windows-1252", FC_CP1252, CM_INV, /* Windows CP 1252 */
- "", 0, 0
-};
-int ntermc = (sizeof(ttcstab) / sizeof(struct keytab)) - 1;
-
-/* This table contains the equivalent FCS number for each TCS. */
-/* If the TC_xxx symbol definitions are ever changed, fix this table. */
-/* Ditto if another TCS is added. */
-
-int
-cseqtab[MAXTCSETS+1] = { /* TCS/FCS equivalency table */
- -1, /* 0 = Transparent */
- FC_USASCII, /* 1 = ASCII */
- FC_1LATIN, /* 2 = Latin-1 */
- FC_2LATIN, /* 3 = Latin-2 */
- FC_CYRILL, /* 4 = Latin/Cyrillic */
- FC_JEUC, /* 5 = Japanese EUC */
- FC_HEBREW, /* 6 = Latin/Hebrew */
- FC_GREEK, /* 7 = Latin/Greek */
- FC_9LATIN, /* 8 = Latin-9 */
- FC_UCS2, /* 9 = UCS-2 */
- FC_UTF8 /* 10 = UTF-8 */
-};
-
-/*
- Languages:
-
- This table allows C-Kermit to have a SET LANGUAGE command to apply special
- language-specific rules when translating from a character set that contains
- national characters into plain ASCII, like German umlaut-a becomes ae.
-
- Originally, I thought it would be a good idea to let SET LANGUAGE also select
- an appropriate FILE CHARACTER-SET and TRANSFER CHARACTER-SET automatically,
- and these are included in the langinfo structure. Later I realized that this
- was a bad idea. Any particular language (e.g. Dutch) can be represented by
- many different and incompatible character sets.
-
- (But we could use the new (1998) ASSOCIATE command for this...)
-*/
-
-struct langinfo langs[] = {
-/* Language code File Charset Xfer Charset Name */
- L_USASCII, FC_USASCII, TC_USASCII, "ASCII (American English)",
- L_DANISH, FC_NOASCII, TC_1LATIN, "Danish",
- L_DUTCH, FC_DUASCII, TC_1LATIN, "Dutch",
- L_FINNISH, FC_FIASCII, TC_1LATIN, "Finnish",
- L_FRENCH, FC_FRASCII, TC_1LATIN, "French",
- L_GERMAN, FC_GEASCII, TC_1LATIN, "German",
-#ifdef GREEK
- L_GREEK, FC_GREEK, TC_GREEK, "Greek",
-#endif /* GREEK */
-#ifdef HEBREW
- L_HEBREW, FC_HEBREW, TC_HEBREW, "Hebrew",
-#endif /* HEBREW */
- L_HUNGARIAN, FC_HUASCII, TC_2LATIN, "Hungarian",
- L_ICELANDIC, FC_USASCII, TC_1LATIN, "Icelandic",
- L_ITALIAN, FC_ITASCII, TC_1LATIN, "Italian",
-#ifdef KANJI
- L_JAPANESE, FC_JEUC, TC_JEUC, "Japanese",
-#endif /* KANJI */
- L_NORWEGIAN, FC_NOASCII, TC_1LATIN, "Norwegian",
- L_PORTUGUESE, FC_POASCII, TC_1LATIN, "Portuguese",
-#ifdef CYRILLIC
- L_RUSSIAN, FC_CP866, TC_CYRILL, "Russian",
-#endif /* CYRILLIC */
- L_SPANISH, FC_SPASCII, TC_1LATIN, "Spanish",
- L_SWEDISH, FC_SWASCII, TC_1LATIN, "Swedish",
- L_SWISS, FC_CHASCII, TC_1LATIN, "Swiss"
-};
-int nlangs = (sizeof(langs) / sizeof(struct langinfo));
-
-/*
- Keyword table for the SET LANGUAGE command.
- Only a few of these (German, Scandinavian, etc) actually do anything.
- The language is used to invoke special translation rules when converting
- from an 8-bit character set to ASCII; for example, German u-diaeresis
- becomes "ue", Dutch y-diaeresis becomes "ij". Languages without associated
- rules are invisible (CM_INV).
-*/
-struct keytab lngtab[] = {
- "ascii", L_USASCII, CM_INV,
- "danish", L_DANISH, 0,
- "dutch", L_DUTCH, 0,
- "english", L_USASCII, CM_INV,
- "finnish", L_FINNISH, 0,
- "french", L_FRENCH, 0,
- "german", L_GERMAN, 0,
-#ifdef GREEK
- "greek", L_GREEK, CM_INV,
-#endif /* GREEK */
-#ifdef HEBREW
- "hebrew", L_HEBREW, CM_INV,
-#endif /* HEBREW */
- "hungarian", L_HUNGARIAN, CM_INV,
- "icelandic", L_ICELANDIC, 0,
- "italian", L_ITALIAN, CM_INV,
-#ifdef KANJI
- "japanese", L_JAPANESE, CM_INV,
-#endif /* KANJI */
- "norwegian", L_NORWEGIAN, 0,
- "none", L_USASCII, 0,
- "portuguese", L_PORTUGUESE, CM_INV,
-#ifdef CYRILLIC
- "russian", L_RUSSIAN, 0,
-#endif /* CYRILLIC */
- "spanish", L_SPANISH, CM_INV,
- "swedish", L_SWEDISH, 0,
-#ifdef CYRILLIC
- "ukrainian", L_RUSSIAN, 0,
-#endif /* CYRILLIC */
- "", 0, 0
-};
-int nlng = (sizeof(lngtab) / sizeof(struct keytab)) - 1; /* how many */
-
-
-/* Translation tables ... */
-
-/*
- For each pair of (transfer,file) character sets, we need two translation
- functions, one for sending, one for receiving.
-*/
-
-/*
- Here is the first table, Latin-1 to ASCII, fully annotated...
- This one is absolutely NOT invertible, since we're going from an 8-bit
- set to a 7-bit set. Accented letters are mapped to unaccented
- equivalents, C1 control characters are all translated to "?", etc.
-*/
-CONST CHAR
-yl1as[] = { /* ISO 8859-1 Latin Alphabet 1 to US ASCII */
- /* Source character Description => Translation */
- /* Dec row/col Set */
- 0, /* 000 00/00 C0 NUL Ctrl-@ => (self) */
- 1, /* 001 00/01 C0 SOH Ctrl-A => (self) */
- 2, /* 002 00/02 C0 STX Ctrl-B => (self) */
- 3, /* 003 00/03 C0 ETX Ctrl-C => (self) */
- 4, /* 004 00/04 C0 EOT Ctrl-D => (self) */
- 5, /* 005 00/05 C0 ENQ Ctrl-E => (self) */
- 6, /* 006 00/06 C0 ACK Ctrl-F => (self) */
- 7, /* 007 00/07 C0 BEL Ctrl-G => (self) */
- 8, /* 008 00/08 C0 BS Ctrl-H => (self) */
- 9, /* 009 00/09 C0 HT Ctrl-I => (self) */
- 10, /* 010 00/10 C0 LF Ctrl-J => (self) */
- 11, /* 011 00/11 C0 VT Ctrl-K => (self) */
- 12, /* 012 00/12 C0 FF Ctrl-L => (self) */
- 13, /* 013 00/13 C0 CR Ctrl-M => (self) */
- 14, /* 014 00/14 C0 SO Ctrl-N => (self) */
- 15, /* 015 00/15 C0 SI Ctrl-O => (self) */
- 16, /* 016 01/00 C0 DLE Ctrl-P => (self) */
- 17, /* 017 01/01 C0 DC1 Ctrl-Q => (self) */
- 18, /* 018 01/02 C0 DC2 Ctrl-R => (self) */
- 19, /* 019 01/03 C0 DC3 Ctrl-S => (self) */
- 20, /* 020 01/04 C0 DC4 Ctrl-T => (self) */
- 21, /* 021 01/05 C0 NAK Ctrl-U => (self) */
- 22, /* 022 01/06 C0 SYN Ctrl-V => (self) */
- 23, /* 023 01/07 C0 ETB Ctrl-W => (self) */
- 24, /* 024 01/08 C0 CAN Ctrl-X => (self) */
- 25, /* 025 01/09 C0 EM Ctrl-Y => (self) */
- 26, /* 026 01/10 C0 SUB Ctrl-Z => (self) */
- 27, /* 027 01/11 C0 ESC Ctrl-[ => (self) */
- 28, /* 028 01/12 C0 FS Ctrl-\ => (self) */
- 29, /* 029 01/13 C0 GS Ctrl-] => (self) */
- 30, /* 030 01/14 C0 RS Ctrl-^ => (self) */
- 31, /* 031 01/15 C0 US Ctrl-_ => (self) */
- 32, /* 032 02/00 SP Space => (self) */
- 33, /* 033 02/01 G0 ! Exclamation mark => (self) */
- 34, /* 034 02/02 G0 " Doublequote => (self) */
- 35, /* 035 02/03 G0 # Number sign => (self) */
- 36, /* 036 02/04 G0 $ Dollar sign => (self) */
- 37, /* 037 02/05 G0 % Percent sign => (self) */
- 38, /* 038 02/06 G0 & Ampersand => (self) */
- 39, /* 039 02/07 G0 ' Apostrophe => (self) */
- 40, /* 040 02/08 G0 ( Left parenthesis => (self) */
- 41, /* 041 02/09 G0 ) Right parenthesis => (self) */
- 42, /* 042 02/10 G0 * Asterisk => (self) */
- 43, /* 043 02/11 G0 + Plus sign => (self) */
- 44, /* 044 02/12 G0 , Comma => (self) */
- 45, /* 045 02/13 G0 - Hyphen, minus sign => (self) */
- 46, /* 046 02/14 G0 . Period, full stop => (self) */
- 47, /* 047 02/15 G0 / Slash, solidus => (self) */
- 48, /* 048 03/00 G0 0 Digit 0 => (self) */
- 49, /* 049 03/01 G0 1 Digit 1 => (self) */
- 50, /* 050 03/02 G0 2 Digit 2 => (self) */
- 51, /* 051 03/03 G0 3 Digit 3 => (self) */
- 52, /* 052 03/04 G0 4 Digit 4 => (self) */
- 53, /* 053 03/05 G0 5 Digit 5 => (self) */
- 54, /* 054 03/06 G0 6 Digit 6 => (self) */
- 55, /* 055 03/07 G0 7 Digit 7 => (self) */
- 56, /* 056 03/08 G0 8 Digit 8 => (self) */
- 57, /* 057 03/09 G0 9 Digit 9 => (self) */
- 58, /* 058 03/10 G0 : Colon => (self) */
- 59, /* 059 03/11 G0 ; Semicolon => (self) */
- 60, /* 060 03/12 G0 < Less-than sign => (self) */
- 61, /* 061 03/13 G0 = Equals sign => (self) */
- 62, /* 062 03/14 G0 > Greater-than sign => (self) */
- 63, /* 063 03/15 G0 ? Question mark => (self) */
- 64, /* 064 04/00 G0 @ Commercial at sign => (self) */
- 65, /* 065 04/01 G0 A Letter A => (self) */
- 66, /* 066 04/02 G0 B Letter B => (self) */
- 67, /* 067 04/03 G0 C Letter C => (self) */
- 68, /* 068 04/04 G0 D Letter D => (self) */
- 69, /* 069 04/05 G0 E Letter E => (self) */
- 70, /* 070 04/06 G0 F Letter F => (self) */
- 71, /* 071 04/07 G0 G Letter G => (self) */
- 72, /* 072 04/08 G0 H Letter H => (self) */
- 73, /* 073 04/09 G0 I Letter I => (self) */
- 74, /* 074 04/10 G0 J Letter J => (self) */
- 75, /* 075 04/11 G0 K Letter K => (self) */
- 76, /* 076 04/12 G0 L Letter L => (self) */
- 77, /* 077 04/13 G0 M Letter M => (self) */
- 78, /* 078 04/14 G0 N Letter N => (self) */
- 79, /* 079 04/15 G0 O Letter O => (self) */
- 80, /* 080 05/00 G0 P Letter P => (self) */
- 81, /* 081 05/01 G0 Q Letter Q => (self) */
- 82, /* 082 05/02 G0 R Letter R => (self) */
- 83, /* 083 05/03 G0 S Letter S => (self) */
- 84, /* 084 05/04 G0 T Letter T => (self) */
- 85, /* 085 05/05 G0 U Letter U => (self) */
- 86, /* 086 05/06 G0 V Letter V => (self) */
- 87, /* 087 05/07 G0 W Letter W => (self) */
- 88, /* 088 05/08 G0 X Letter X => (self) */
- 89, /* 089 05/09 G0 Y Letter Y => (self) */
- 90, /* 090 05/10 G0 Z Letter Z => (self) */
- 91, /* 091 05/11 G0 [ Left square bracket => (self) */
- 92, /* 092 05/12 G0 \ Reverse slash => (self) */
- 93, /* 093 05/13 G0 ] Right square bracket => (self) */
- 94, /* 094 05/14 G0 ^ Circumflex accent => (self) */
- 95, /* 095 05/15 G0 _ Underline, low line => (self) */
- 96, /* 096 06/00 G0 ` Grave accent => (self) */
- 97, /* 097 06/01 G0 a Letter a => (self) */
- 98, /* 098 06/02 G0 b Letter b => (self) */
- 99, /* 099 06/03 G0 c Letter c => (self) */
-100, /* 100 06/04 G0 d Letter d => (self) */
-101, /* 101 06/05 G0 e Letter e => (self) */
-102, /* 102 06/06 G0 f Letter f => (self) */
-103, /* 103 06/07 G0 g Letter g => (self) */
-104, /* 104 06/08 G0 h Letter h => (self) */
-105, /* 105 06/09 G0 i Letter i => (self) */
-106, /* 106 06/10 G0 j Letter j => (self) */
-107, /* 107 06/11 G0 k Letter k => (self) */
-108, /* 108 06/12 G0 l Letter l => (self) */
-109, /* 109 06/13 G0 m Letter m => (self) */
-110, /* 110 06/14 G0 n Letter n => (self) */
-111, /* 111 06/15 G0 o Letter o => (self) */
-112, /* 112 07/00 G0 p Letter p => (self) */
-113, /* 113 07/01 G0 q Letter q => (self) */
-114, /* 114 07/02 G0 r Letter r => (self) */
-115, /* 115 07/03 G0 s Letter s => (self) */
-116, /* 116 07/04 G0 t Letter t => (self) */
-117, /* 117 07/05 G0 u Letter u => (self) */
-118, /* 118 07/06 G0 v Letter v => (self) */
-119, /* 119 07/07 G0 w Letter w => (self) */
-120, /* 120 07/08 G0 x Letter x => (self) */
-121, /* 121 07/09 G0 y Letter y => (self) */
-122, /* 122 07/10 G0 z Letter z => (self) */
-123, /* 123 07/11 G0 { Left curly bracket => (self) */
-124, /* 124 07/12 G0 | Vertical bar => (self) */
-125, /* 125 07/13 G0 } Right curly bracket => (self) */
-126, /* 126 07/14 G0 ~ Tilde => (self) */
-127, /* 127 07/15 DEL Delete, Rubout => (self) */
-UNK, /* 128 08/00 C1 => UNK */
-UNK, /* 129 08/01 C1 => UNK */
-UNK, /* 130 08/02 C1 => UNK */
-UNK, /* 131 08/03 C1 => UNK */
-UNK, /* 132 08/04 C1 IND => UNK */
-UNK, /* 133 08/05 C1 NEL => UNK */
-UNK, /* 134 08/06 C1 SSA => UNK */
-UNK, /* 135 08/07 C1 ESA => UNK */
-UNK, /* 136 08/08 C1 HTS => UNK */
-UNK, /* 137 08/09 C1 => UNK */
-UNK, /* 138 08/10 C1 => UNK */
-UNK, /* 139 08/11 C1 => UNK */
-UNK, /* 140 08/12 C1 => UNK */
-UNK, /* 141 08/13 C1 RI => UNK */
-UNK, /* 142 08/14 C1 SS2 => UNK */
-UNK, /* 143 08/15 C1 SS3 => UNK */
-UNK, /* 144 09/00 C1 DCS => UNK */
-UNK, /* 145 09/01 C1 => UNK */
-UNK, /* 146 09/02 C1 => UNK */
-UNK, /* 147 09/03 C1 STS => UNK */
-UNK, /* 148 09/04 C1 => UNK */
-UNK, /* 149 09/05 C1 => UNK */
-UNK, /* 150 09/06 C1 SPA => UNK */
-UNK, /* 151 09/07 C1 EPA => UNK */
-UNK, /* 152 09/08 C1 => UNK */
-UNK, /* 153 09/09 C1 => UNK */
-UNK, /* 154 09/10 C1 => UNK */
-UNK, /* 155 09/11 C1 CSI => UNK */
-UNK, /* 156 09/12 C1 ST => UNK */
-UNK, /* 157 09/13 C1 OSC => UNK */
-UNK, /* 158 09/14 C1 PM => UNK */
-UNK, /* 159 09/15 C1 APC => UNK */
- 32, /* 160 10/00 G1 No-break space => SP */
- 33, /* 161 10/01 G1 Inverted exclamation => ! */
- 99, /* 162 10/02 G1 Cent sign => c */
- 35, /* 163 10/03 G1 Pound sign => # */
- 36, /* 164 10/04 G1 Currency sign => $ */
- 89, /* 165 10/05 G1 Yen sign => Y */
-124, /* 166 10/06 G1 Broken bar => | */
- 80, /* 167 10/07 G1 Paragraph sign => P */
- 34, /* 168 10/08 G1 Diaeresis => " */
- 67, /* 169 10/09 G1 Copyright sign => C */
- 97, /* 170 10/10 G1 Feminine ordinal => a */
- 34, /* 171 10/11 G1 Left angle quotation => " */
-126, /* 172 10/12 G1 Not sign => ~ */
- 45, /* 173 10/13 G1 Soft hyphen => - */
- 82, /* 174 10/14 G1 Registered trade mark => R */
- 95, /* 175 10/15 G1 Macron => _ */
-111, /* 176 11/00 G1 Degree sign, ring above => o */
-UNK, /* 177 11/01 G1 Plus-minus sign => UNK */
- 50, /* 178 11/02 G1 Superscript two => 2 */
- 51, /* 179 11/03 G1 Superscript three => 3 */
- 39, /* 180 11/04 G1 Acute accent => ' */
-117, /* 181 11/05 G1 Micro sign => u */
- 45, /* 182 11/06 G1 Pilcrow sign => - */
- 45, /* 183 11/07 G1 Middle dot => - */
- 44, /* 184 11/08 G1 Cedilla => , */
- 49, /* 185 11/09 G1 Superscript one => 1 */
-111, /* 186 11/10 G1 Masculine ordinal => o */
- 34, /* 187 11/11 G1 Right angle quotation => " */
-UNK, /* 188 11/12 G1 One quarter => UNK */
-UNK, /* 189 11/13 G1 One half => UNK */
-UNK, /* 190 11/14 G1 Three quarters => UNK */
- 63, /* 191 11/15 G1 Inverted question mark => ? */
- 65, /* 192 12/00 G1 A grave => A */
- 65, /* 193 12/01 G1 A acute => A */
- 65, /* 194 12/02 G1 A circumflex => A */
- 65, /* 195 12/03 G1 A tilde => A */
- 65, /* 196 12/04 G1 A diaeresis => A */
- 65, /* 197 12/05 G1 A ring above => A */
- 65, /* 198 12/06 G1 A with E => A */
- 67, /* 199 12/07 G1 C Cedilla => C */
- 69, /* 200 12/08 G1 E grave => E */
- 69, /* 201 12/09 G1 E acute => E */
- 69, /* 202 12/10 G1 E circumflex => E */
- 69, /* 203 12/11 G1 E diaeresis => E */
- 73, /* 204 12/12 G1 I grave => I */
- 73, /* 205 12/13 G1 I acute => I */
- 73, /* 206 12/14 G1 I circumflex => I */
- 73, /* 207 12/15 G1 I diaeresis => I */
- 68, /* 208 13/00 G1 Icelandic Eth => D */
- 78, /* 209 13/01 G1 N tilde => N */
- 79, /* 210 13/02 G1 O grave => O */
- 79, /* 211 13/03 G1 O acute => O */
- 79, /* 212 13/04 G1 O circumflex => O */
- 79, /* 213 13/05 G1 O tilde => O */
- 79, /* 214 13/06 G1 O diaeresis => O */
-120, /* 215 13/07 G1 Multiplication sign => x */
- 79, /* 216 13/08 G1 O oblique stroke => O */
- 85, /* 217 13/09 G1 U grave => U */
- 85, /* 218 13/10 G1 U acute => U */
- 85, /* 219 13/11 G1 U circumflex => U */
- 85, /* 220 13/12 G1 U diaeresis => U */
- 89, /* 221 13/13 G1 Y acute => Y */
- 84, /* 222 13/14 G1 Icelandic Thorn => T */
-115, /* 223 13/15 G1 German sharp s => s */
- 97, /* 224 14/00 G1 a grave => a */
- 97, /* 225 14/01 G1 a acute => a */
- 97, /* 226 14/02 G1 a circumflex => a */
- 97, /* 227 14/03 G1 a tilde => a */
- 97, /* 228 14/04 G1 a diaeresis => a */
- 97, /* 229 14/05 G1 a ring above => a */
- 97, /* 230 14/06 G1 a with e => a */
- 99, /* 231 14/07 G1 c cedilla => c */
-101, /* 232 14/08 G1 e grave => e */
-101, /* 233 14/09 G1 e acute => e */
-101, /* 234 14/10 G1 e circumflex => e */
-101, /* 235 14/11 G1 e diaeresis => e */
-105, /* 236 14/12 G1 i grave => i */
-105, /* 237 14/13 G1 i acute => i */
-105, /* 238 14/14 G1 i circumflex => i */
-105, /* 239 14/15 G1 i diaeresis => i */
-100, /* 240 15/00 G1 Icelandic eth => d */
-110, /* 241 15/01 G1 n tilde => n */
-111, /* 242 15/02 G1 o grave => o */
-111, /* 243 15/03 G1 o acute => o */
-111, /* 244 15/04 G1 o circumflex => o */
-111, /* 245 15/05 G1 o tilde => o */
-111, /* 246 15/06 G1 o diaeresis => o */
- 47, /* 247 15/07 G1 Division sign => / */
-111, /* 248 15/08 G1 o oblique stroke => o */
-117, /* 249 15/09 G1 u grave => u */
-117, /* 250 15/10 G1 u acute => u */
-117, /* 251 15/11 G1 u circumflex => u */
-117, /* 252 15/12 G1 u diaeresis => u */
-121, /* 253 15/13 G1 y acute => y */
-116, /* 254 15/14 G1 Icelandic thorn => t */
-121 /* 255 15/15 G1 y diaeresis => y */
-};
-
-
-/* Translation tables for ISO Latin Alphabet 1 to local file character sets */
-
-/*
- Most of the remaining tables are not annotated like the one above, because
- the size of the resulting source file would be ridiculous. Each row in the
- following tables corresponds to a column of ISO 8859-1.
-*/
-
-CONST CHAR
-yl185[] = { /* ISO 8859-1 Latin Alphabet 1 (Latin-1) to IBM Code Page 850 */
-/*
- This is based on IBM's official invertible translation. Reference: IBM
- Character Data Representation Architecture (CDRA), Level 1, Registry,
- SC09-1291-00 (1990), p.152. (Note: Latin-1 is IBM Code Page 00819.) Note:
- IBM's bizarre rearrangement of C0 controls and DEL has been undone in this
- table.
-*/
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-186, 205, 201, 187, 200, 188, 204, 185, 203, 202, 206, 223, 220, 219, 254, 242,
-179, 196, 218, 191, 192, 217, 195, 180, 194, 193, 197, 176, 177, 178, 213, 159,
-255, 173, 189, 156, 207, 190, 221, 245, 249, 184, 166, 174, 170, 240, 169, 238,
-248, 241, 253, 252, 239, 230, 244, 250, 247, 251, 167, 175, 172, 171, 243, 168,
-183, 181, 182, 199, 142, 143, 146, 128, 212, 144, 210, 211, 222, 214, 215, 216,
-209, 165, 227, 224, 226, 229, 153, 158, 157, 235, 233, 234, 154, 237, 232, 225,
-133, 160, 131, 198, 132, 134, 145, 135, 138, 130, 136, 137, 141, 161, 140, 139,
-208, 164, 149, 162, 147, 228, 148, 246, 155, 151, 163, 150, 129, 236, 231, 152
-};
-
-CONST CHAR
-y85l1[] = { /* IBM Code Page 850 to Latin-1 */
-/*
- This is from IBM CDRA page 153. It is the inverse of yl185[].
- As of edit 183, this table is no longer pure CDRA. The translations
- involving C0 controls and DEL have been removed.
-*/
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232, 239, 238, 236, 196, 197,
-201, 230, 198, 244, 246, 242, 251, 249, 255, 214, 220, 248, 163, 216, 215, 159,
-225, 237, 243, 250, 241, 209, 170, 186, 191, 174, 172, 189, 188, 161, 171, 187,
-155, 156, 157, 144, 151, 193, 194, 192, 169, 135, 128, 131, 133, 162, 165, 147,
-148, 153, 152, 150, 145, 154, 227, 195, 132, 130, 137, 136, 134, 129, 138, 164,
-240, 208, 202, 203, 200, 158, 205, 206, 207, 149, 146, 141, 140, 166, 204, 139,
-211, 223, 212, 210, 245, 213, 181, 254, 222, 218, 219, 217, 253, 221, 175, 180,
-173, 177, 143, 190, 182, 167, 247, 184, 176, 168, 183, 185, 179, 178, 142, 160
-};
-
-#ifdef COMMENT
-CONST CHAR
-yl1r8[] = { /* Latin-1 to Hewlett Packard Roman8 */
-/* This is HP's official translation, straight from iconv */
-/* It is NOT invertible. */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 184, 191, 187, 186, 188, 124, 189, 171, 99, 249, 251, 126, 45, 82, 176,
-179, 254, 50, 51, 168, 243, 244, 242, 44, 49, 250, 253, 247, 248, 245, 185,
-161, 224, 162, 225, 216, 208, 211, 180, 163, 220, 164, 165, 230, 229, 166, 167,
-227, 182, 232, 231, 223, 233, 218, 120, 210, 173, 237, 174, 219, 177, 240, 222,
-200, 196, 192, 226, 204, 212, 215, 181, 201, 197, 193, 205, 217, 213, 209, 221,
-228, 183, 202, 198, 194, 234, 206, 47, 214, 203, 199, 195, 207, 178, 241, 239
-};
-CONST CHAR
-yr8l1[] = { /* Hewlett Packard Roman8 to Latin-1 */
-/* This is HP's official translation, straight from iconv */
-/* It is NOT invertible. */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 192, 194, 200, 202, 203, 206, 207, 180, 96, 94, 168, 126, 217, 219, 163,
-175, 221, 253, 176, 199, 231, 209, 241, 161, 191, 164, 163, 165, 167, 102, 162,
-226, 234, 244, 251, 225, 233, 243, 250, 224, 232, 242, 249, 228, 235, 246, 252,
-197, 238, 216, 198, 229, 237, 248, 230, 196, 236, 214, 220, 201, 239, 223, 212,
-193, 195, 227, 208, 240, 205, 204, 211, 210, 213, 245, 83, 115, 218, 89, 255,
-222, 254, 183, 181, 182, 190, 45, 188, 189, 170, 186, 171, 42, 187, 177, 160
-};
-#else /* !COMMENT */
-/* This is an invertible mapping, approved by HP in January 1994. */
-CONST CHAR
-yl1r8[] = { /* ISO Latin-1 to HP Roman8, Invertible */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 184, 191, 187, 186, 188, 169, 189, 171, 170, 249, 251, 172, 175, 190, 176,
-179, 254, 235, 236, 168, 243, 244, 242, 238, 246, 250, 253, 247, 248, 245, 185,
-161, 224, 162, 225, 216, 208, 211, 180, 163, 220, 164, 165, 230, 229, 166, 167,
-227, 182, 232, 231, 223, 233, 218, 252, 210, 173, 237, 174, 219, 177, 240, 222,
-200, 196, 192, 226, 204, 212, 215, 181, 201, 197, 193, 205, 217, 213, 209, 221,
-228, 183, 202, 198, 194, 234, 206, 255, 214, 203, 199, 195, 207, 178, 241, 239
-};
-
-CONST CHAR
-yr8l1[] = { /* HP Roman8 to ISO Latin-1, Invertible */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 192, 194, 200, 202, 203, 206, 207, 180, 166, 169, 168, 172, 217, 219, 173,
-175, 221, 253, 176, 199, 231, 209, 241, 161, 191, 164, 163, 165, 167, 174, 162,
-226, 234, 244, 251, 225, 233, 243, 250, 224, 232, 242, 249, 228, 235, 246, 252,
-197, 238, 216, 198, 229, 237, 248, 230, 196, 236, 214, 220, 201, 239, 223, 212,
-193, 195, 227, 208, 240, 205, 204, 211, 210, 213, 245, 178, 179, 218, 184, 255,
-222, 254, 183, 181, 182, 190, 185, 188, 189, 170, 186, 171, 215, 187, 177, 247
-};
-#endif /* COMMENT */
-
-CONST CHAR
-yl143[] = { /* Latin-1 to IBM Code Page 437 */
-/*
- Although the IBM CDRA does not include an official translation between CP437
- and ISO Latin Alphabet 1, it does include an official, invertible
- translation between CP437 and CP850 (page 196), and another from CP850 to
- Latin-1 (CP819) (page 153). This translation was obtained with a two-step
- process based on those tables.
- As of edit 183, the translation is modified to leave C0 controls alone.
-*/
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-186, 205, 201, 187, 200, 188, 204, 185, 203, 202, 206, 223, 220, 219, 254, 242,
-179, 196, 218, 191, 192, 217, 195, 180, 194, 193, 197, 176, 177, 178, 213, 159,
-255, 173, 155, 156, 207, 157, 221, 245, 249, 184, 166, 174, 170, 240, 169, 238,
-248, 241, 253, 252, 239, 230, 244, 250, 247, 251, 167, 175, 172, 171, 243, 168,
-183, 181, 182, 199, 142, 143, 146, 128, 212, 144, 210, 211, 222, 214, 215, 216,
-209, 165, 227, 224, 226, 229, 153, 158, 190, 235, 233, 234, 154, 237, 232, 225,
-133, 160, 131, 198, 132, 134, 145, 135, 138, 130, 136, 137, 141, 161, 140, 139,
-208, 164, 149, 162, 147, 228, 148, 246, 189, 151, 163, 150, 129, 236, 231, 152
-};
-
-CONST CHAR
-y43l1[] = { /* IBM Code Page 437 to Latin-1 */
-/*
- This table is the inverse of yl143[].
-*/
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232, 239, 238, 236, 196, 197,
-201, 230, 198, 244, 246, 242, 251, 249, 255, 214, 220, 162, 163, 165, 215, 159,
-225, 237, 243, 250, 241, 209, 170, 186, 191, 174, 172, 189, 188, 161, 171, 187,
-155, 156, 157, 144, 151, 193, 194, 192, 169, 135, 128, 131, 133, 248, 216, 147,
-148, 153, 152, 150, 145, 154, 227, 195, 132, 130, 137, 136, 134, 129, 138, 164,
-240, 208, 202, 203, 200, 158, 205, 206, 207, 149, 146, 141, 140, 166, 204, 139,
-211, 223, 212, 210, 245, 213, 181, 254, 222, 218, 219, 217, 253, 221, 175, 180,
-173, 177, 143, 190, 182, 167, 247, 184, 176, 168, 183, 185, 179, 178, 142, 160
-};
-
-CONST CHAR
-yl1aq[] = { /* Latin-1 to Extended Mac Latin (based on Apple QuickDraw) */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-182, 183, 184, 185, 189, 196, 197, 198, 206, 207, 210, 211, 217, 218, 195, 212,
-209, 215, 213, 226, 227, 228, 240, 245, 246, 247, 249, 250, 251, 253, 254, 255,
-202, 193, 162, 163, 219, 180, 201, 164, 172, 169, 187, 199, 194, 208, 168, 248,
-161, 177, 170, 173, 171, 181, 166, 225, 252, 176, 188, 200, 178, 179, 186, 192,
-203, 231, 229, 204, 128, 129, 174, 130, 233, 131, 230, 232, 237, 234, 235, 236,
-220, 132, 241, 238, 239, 205, 133, 165, 175, 244, 242, 243, 134, 160, 222, 167,
-136, 135, 137, 139, 138, 140, 190, 141, 143, 142, 144, 145, 147, 146, 148, 149,
-221, 150, 152, 151, 153, 155, 154, 214, 191, 157, 156, 158, 159, 224, 223, 216
-};
-
-CONST CHAR
-yl1du[] = { /* Latin-1 to Dutch ISO 646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, UNK, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-UNK, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, 39, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, 35, 124, UNK, UNK, 93, 123, 67, UNK, 34, UNK, 45, 82, UNK,
- 91, UNK, UNK, UNK, 126, 117, UNK, UNK, 44, UNK, UNK, 34, 125, 92, 64, 63,
- 65, 65, 65, 65, 91, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 79, 79, 120, 79, 85, 85, 85, 85, 89, UNK, 115,
- 97, 97, 97, 97, 97, 97, 97, 99, 101, 101, 101, 101, 105, 105, 105, 105,
-UNK, 110, 111, 111, 111, 111, 111, 47, 111, 117, 117, 117, 117, 121, UNK, 91
-};
-
-CONST CHAR
-yl1fi[] = { /* Latin-1 to Finnish ISO NRC (*not* ISO 646) */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, UNK, 95,
-UNK, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, UNK, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, UNK, UNK, UNK, UNK, UNK, 34, 67, UNK, 34, UNK, 45, 82, UNK,
-UNK, UNK, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 63,
- 65, 65, 65, 65, 91, 93, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 79, 92, 120, 79, 85, 85, 85, 94, 89, UNK, 115,
- 97, 97, 97, 97, 123, 125, 97, 99, 101, 96, 101, 101, 105, 105, 105, 105,
-UNK, 110, 111, 111, 111, 111, 124, 47, 111, 117, 117, 117, 126, 121, UNK, 121
-};
-
-CONST CHAR
-yl1fr[] = { /* Latin-1 to French ISO 646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, UNK, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-UNK, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, UNK, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, 35, UNK, UNK, UNK, 93, 34, 67, UNK, 34, UNK, 45, 82, UNK,
- 91, UNK, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 63,
- 65, 65, 65, 65, 65, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 79, 79, 120, 79, 85, 85, 85, 85, 89, UNK, 115,
- 64, 97, 97, 97, 97, 97, 97, 92, 125, 123, 101, 101, 105, 105, 105, 105,
-UNK, 110, 111, 111, 111, 111, 111, 47, 111, 124, 117, 117, 117, 121, UNK, 121
-};
-
-CONST CHAR
-yl1fc[] = { /* Latin-1 to French-Canadian ISO 646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-UNK, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, UNK, 95,
-UNK, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, UNK, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, UNK, UNK, UNK, UNK, UNK, 34, 67, UNK, 34, UNK, 45, 82, UNK,
-UNK, UNK, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 63,
- 65, 65, 65, 65, 65, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 79, 79, 120, 79, 85, 85, 85, 85, 89, UNK, 115,
- 64, 97, 91, 97, 97, 97, 97, 92, 125, 123, 93, 101, 105, 105, 94, 105,
-UNK, 110, 111, 111, 96, 111, 111, 47, 111, 124, 117, 126, 117, 121, UNK, 121
-};
-
-CONST CHAR
-yl1ge[] = { /* Latin-1 to German ISO 646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-UNK, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, UNK, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, UNK, UNK, UNK, UNK, 64, 34, 67, UNK, 34, UNK, 45, 82, UNK,
-UNK, UNK, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 63,
- 65, 65, 65, 65, 91, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 79, 92, 120, 79, 85, 85, 85, 93, 89, UNK, 126,
- 97, 97, 97, 97, 123, 97, 97, 99, 101, 101, 101, 101, 105, 105, 105, 105,
-UNK, 110, 111, 111, 111, 111, 124, 47, 111, 117, 117, 117, 125, 121, UNK, 121
-};
-
-CONST CHAR
-yl1hu[] = { /* Latin-1 to Hungarian ISO-646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, UNK, 36, UNK, UNK, UNK, 34, 67, UNK, 34, UNK, 45, 82, UNK,
-UNK, 64, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 63,
- 65, 65, 65, 65, 65, 65, 65, 67, 69, 91, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 79, 92, 120, 79, 85, 85, 85, 93, 89, UNK, 115,
- 97, 96, 97, 97, 97, 97, 97, 99, 101, 123, 101, 101, 105, 105, 105, 105,
-UNK, 110, 111, 111, 111, 111, 124, 47, 111, 117, 117, 117, 125, 121, UNK, 121
-};
-
-CONST CHAR
-yl1it[] = { /* Latin-1 to Italian ISO 646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, UNK, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-UNK, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, 94, 95,
-UNK, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, UNK, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, 35, UNK, UNK, UNK, 64, 34, 67, UNK, 34, UNK, 45, 82, UNK,
- 91, UNK, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 63,
- 65, 65, 65, 65, 65, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 79, 79, 120, 79, 85, 85, 85, 85, 89, UNK, 115,
-123, 97, 97, 97, 97, 97, 97, 92, 125, 93, 101, 101, 126, 105, 105, 105,
-UNK, 110, 124, 111, 111, 111, 111, 47, 111, 96, 117, 117, 117, 121, UNK, 121
-};
-
-CONST CHAR
-yl1ne[] = { /* Latin-1 to NeXT */
-/* NEED TO MAKE THIS ONE INVERTIBLE, LIKE CP850 */
-/*
- Which means finding all the graphic characters in the NeXT set that have
- no equivalent in Latin-1 and assigning them to the UNK positions (mostly
- Latin-1 C1 controls). Then make the ynel1[] table be the inverse of this
- one. But first we should try to get an official Latin-1/NeXT translation
- table from NeXT, Inc.
-*/
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
- 32, 161, 162, 163, 168, 165, 181, 167, 200, 160, 227, 171, 190, UNK, 176, 197,
-202, 209, 201, 204, 194, 157, 182, 183, 203, 192, 235, 187, 210, 211, 212, 191,
-129, 130, 131, 132, 133, 134, 225, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 158, 233, 151, 152, 153, 154, 155, 156, 251,
-213, 214, 215, 216, 217, 218, 241, 219, 220, 221, 222, 223, 224, 226, 228, 229,
-230, 231, 236, 237, 238, 239, 240, 159, 249, 242, 243, 244, 246, 247, 252, 253
-};
-
-CONST CHAR
-yl1no[] = { /* Latin-1 to Norwegian/Danish ISO 646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, UNK, UNK, UNK, UNK, UNK, 34, 67, UNK, 34, UNK, 45, 82, UNK,
-UNK, UNK, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 63,
- 65, 65, 65, 65, 65, 93, 91, 67, 69, 69, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 79, 79, 120, 92, 85, 85, 85, 85, 89, UNK, 115,
- 97, 97, 97, 97, 97, 125, 123, 99, 101, 101, 101, 101, 105, 105, 105, 105,
-UNK, 110, 111, 111, 111, 111, 111, 47, 124, 117, 117, 117, 117, 121, UNK, 121
-};
-
-CONST CHAR
-yl1po[] = { /* Latin-1 to Portuguese ISO 646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, UNK, UNK, UNK, UNK, UNK, 34, 67, UNK, 34, UNK, 45, 82, UNK,
-UNK, UNK, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 63,
- 65, 65, 65, 91, 65, 65, 65, 92, 69, 69, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 93, 79, 120, 79, 85, 85, 85, 85, 89, UNK, 115,
- 97, 97, 97, 123, 97, 97, 97, 124, 101, 101, 101, 101, 105, 105, 105, 105,
-UNK, 110, 111, 111, 111, 125, 111, 47, 111, 117, 117, 117, 117, 121, UNK, 121
-};
-
-CONST CHAR
-yl1sp[] = { /* Latin-1 to Spanish ISO 646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, UNK, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-UNK, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 96, UNK, UNK, 126, 127,
-126, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 91, UNK, 35, UNK, UNK, UNK, 64, 34, 67, UNK, 34, UNK, 45, 82, UNK,
-123, UNK, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 93,
- 65, 65, 65, 65, 65, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
-UNK, 92, 79, 79, 79, 79, 79, 120, 79, 85, 85, 85, 85, 89, UNK, 115,
-124, 97, 97, 97, 97, 97, 97, 125, 101, 101, 101, 101, 105, 105, 105, 105,
-UNK, 124, 111, 111, 111, 111, 111, 47, 111, 117, 117, 117, 117, 121, UNK, 121
-};
-
-CONST CHAR
-yl1sw[] = { /* Latin-1 to Swedish ISO 646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-UNK, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, UNK, 95,
-UNK, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, UNK, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, UNK, UNK, UNK, UNK, UNK, 34, 67, UNK, 34, UNK, 45, 82, UNK,
-UNK, UNK, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 63,
- 65, 65, 65, 65, 91, 93, 65, 67, 69, 64, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 79, 92, 120, 79, 85, 85, 85, 94, 89, UNK, 115,
- 97, 97, 97, 97, 123, 125, 97, 99, 101, 96, 101, 101, 105, 105, 105, 105,
-UNK, 110, 111, 111, 111, 111, 124, 47, 111, 117, 117, 117, 126, 121, UNK, 121
-};
-
-CONST CHAR
-yl1ch[] = { /* Latin-1 to Swiss ISO 646 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, UNK, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-UNK, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, UNK, UNK, UNK, UNK, UNK,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, UNK, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 33, UNK, UNK, UNK, UNK, UNK, UNK, 34, 67, UNK, 34, UNK, 45, 82, UNK,
-UNK, UNK, UNK, UNK, 39, 117, UNK, UNK, 44, UNK, UNK, 34, UNK, UNK, UNK, 63,
- 65, 65, 65, 65, 65, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
-UNK, 78, 79, 79, 79, 79, 79, 120, 79, 85, 85, 85, 85, 89, UNK, 115,
- 64, 97, 97, 97, 123, 97, 97, 92, 95, 91, 93, 101, 105, 105, 94, 105,
-UNK, 110, 111, 111, 96, 111, 124, 47, 111, 35, 117, 126, 125, 121, UNK, 121
-};
-
-CONST CHAR
-yl1dm[] = { /* Latin-1 to DEC Multinational Character Set */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 32, 161, 162, 163, 168, 165, 124, 167, 34, 169, 170, 171, 126, UNK, 82, UNK,
-176, 177, 178, 179, 39, 181, 182, 183, 44, 185, 186, 187, 188, 189, UNK, 191,
-192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
-UNK, 209, 210, 211, 212, 213, 214, 120, 216, 217, 218, 219, 220, 221, UNK, 223,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
-UNK, 241, 242, 243, 244, 245, 246, 47, 248, 249, 250, 251, 252, UNK, UNK, 253
-};
-
-CONST CHAR
-yl1dg[] = { /* Latin-1 to Data General International Character Set */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 171, 167, 168, 166, 181, 191, 187, 189, 173, 169, 177, 161, 255, 174, 175,
-188, 182, 164, 165, 190, 163, 178, 185, 186, 179, 170, 176, 223, 162, 220, 172,
-193, 192, 194, 196, 195, 197, 198, 199, 201, 200, 202, 203, 205, 204, 206, 207,
-184, 208, 210, 209, 211, 213, 212, 215, 214, 217, 216, 218, 219, 221, 222, 252,
-225, 224, 226, 228, 227, 229, 230, 231, 233, 232, 234, 235, 237, 236, 238, 239,
-183, 240, 242, 241, 243, 245, 244, 247, 246, 249, 248, 250, 251, 180, 254, 253
-};
-
-
-/* Local file character sets to ISO Latin Alphabet 1 */
-
-#ifdef NOTUSED
-CONST CHAR
-yasl1[] = { /* ASCII to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127
-};
-#endif /* NOTUSED */
-
-CONST CHAR
-yaql1[] = { /* Extended Mac Latin (based on Apple Quickdraw) to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-196, 197, 199, 201, 209, 214, 220, 225, 224, 226, 228, 227, 229, 231, 233, 232,
-234, 235, 237, 236, 238, 239, 241, 243, 242, 244, 246, 245, 250, 249, 251, 252,
-221, 176, 162, 163, 167, 215, 182, 223, 174, 169, 178, 180, 168, 179, 198, 216,
-185, 177, 188, 189, 165, 181, 128, 129, 130, 131, 190, 170, 186, 132, 230, 248,
-191, 161, 172, 142, 133, 134, 135, 171, 187, 166, 160, 192, 195, 213, 136, 137,
-173, 144, 138, 139, 143, 146, 247, 145, 255, 140, 141, 164, 208, 240, 222, 254,
-253, 183, 147, 148, 149, 194, 202, 193, 203, 200, 205, 206, 207, 204, 211, 212,
-150, 210, 218, 219, 217, 151, 152, 153, 175, 154, 155, 156, 184, 157, 158, 159
-};
-
-CONST CHAR
-ydul1[] = { /* Dutch ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 163, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-190, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 255, 189, 124, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 168, 164, 188, 39, 127
-};
-
-CONST CHAR
-yfil1[] = { /* Finnish NRC (*not* ISO-646) to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 196, 214, 197, 220, 95,
-233, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 228, 246, 229, 252, 127
-};
-
-CONST CHAR
-yfrl1[] = { /* French ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 163, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-224, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 176, 231, 167, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 233, 249, 232, 168, 127
-};
-
-CONST CHAR
-yfcl1[] = { /* French-Canadian ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-224, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 226, 231, 234, 238, 95,
-244, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 233, 249, 232, 251, 127
-};
-
-CONST CHAR
-ygel1[] = { /* German ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-167, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 196, 214, 220, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 228, 246, 252, 223, 127
-};
-
-CONST CHAR
-yitl1[] = { /* Italian ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 163, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-167, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 176, 231, 233, 94, 95,
-249, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 224, 242, 232, 236, 127
-};
-
-CONST CHAR
-ynel1[] = { /* NeXT to Latin-1 */
-/* NEED TO MAKE THIS ONE INVERTIBLE */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-160, 192, 193, 194, 195, 196, 197, 199, 200, 201, 202, 203, 204, 205, 206, 207,
-208, 209, 210, 211, 212, 213, 214, 217, 218, 219, 220, 221, 222, 181, 215, 247,
-169, 161, 162, 163, UNK, 165, UNK, 167, 164, UNK, UNK, 171, UNK, UNK, UNK, UNK,
-174, UNK, UNK, UNK, 183, 166, 182, UNK, UNK, UNK, UNK, 187, UNK, UNK, 172, 191,
-185, 96, 180, 94, 126, 175, UNK, UNK, 168, 178, 176, 184, 179, UNK, UNK, UNK,
-UNK, 177, 188, 189, 190, 224, 225, 226, 227, 228, 229, 231, 232, 233, 234, 235,
-236, 198, 237, 170, 238, 239, 240, 241, UNK, 216, UNK, 186, 242, 243, 244, 245,
-246, 230, 249, 250, 251, UNK, 252, 253, UNK, 248, UNK, 223, 254, 255, UNK, UNK
-};
-
-CONST CHAR
-ynol1[] = { /* Norwegian/Danish ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 198, 216, 197, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 230, 248, 229, 126, 127
-};
-
-CONST CHAR
-ypol1[] = { /* Portuguese ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 195, 199, 213, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 227, 231, 245, 126, 127
-};
-
-CONST CHAR
-yspl1[] = { /* Spanish ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 163, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-167, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 161, 209, 191, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 176, 241, 231, 126, 127
-};
-
-CONST CHAR
-yswl1[] = { /* Swedish ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-201, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 196, 214, 197, 220, 95,
-233, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 228, 246, 229, 252, 127
-};
-
-CONST CHAR
-ychl1[] = { /* Swiss ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 249, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-224, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 233, 231, 234, 238, 232,
-244, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 228, 246, 252, 251, 127
-};
-
-CONST CHAR
-yhul1[] = { /* Hungarian ISO 646 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 164, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-193, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 201, 214, 220, 94, 95,
-225, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 233, 246, 252, 34, 127
-};
-
-CONST CHAR
-ydml1[] = { /* DEC Multinational Character Set to Latin-1 */
-/* Note: This is a null translation */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
-176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
-192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
-208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
-240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
-};
-
-CONST CHAR
-ydgl1[] = { /* Data General International to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 172, 189, 181, 178, 179, 164, 162, 163, 170, 186, 161, 191, 169, 174, 175,
-187, 171, 182, 185, 253, 165, 177, 240, 208, 183, 184, 167, 176, 168, 180, 166,
-193, 192, 194, 196, 195, 197, 198, 199, 201, 200, 202, 203, 205, 204, 206, 207,
-209, 211, 210, 212, 214, 213, 216, 215, 218, 217, 219, 220, 190, 221, 222, 188,
-225, 224, 226, 228, 227, 229, 230, 231, 233, 232, 234, 235, 237, 236, 238, 239,
-241, 243, 242, 244, 246, 245, 248, 247, 250, 249, 251, 252, 223, 255, 254, 173
-};
-
-
-/* Translation tables for Cyrillic character sets */
-
-#ifdef CYRILLIC
-CONST CHAR
-ylcac[] = { /* Latin/Cyrillic to CP866 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 208, 209, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-196, 179, 192, 217, 191, 218, 195, 193, 180, 194, 197, 176, 177, 178, 211, 216,
-205, 186, 200, 188, 187, 201, 204, 202, 185, 203, 206, 223, 220, 219, 254, UNK,
-255, 240, 132, 131, 242, 83, 73, 244, 74, 139, 141, 151, 138, 45, 246, 135,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
-252, 241, 164, 163, 243, 115, 105, 245, 106, 171, 173, 231, 170, 21, 247, 167
-};
-
-CONST CHAR
-ylc55[] = { /* Latin/Cyrillic to CP855 (inverse of y55lc) */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-174, 175, 176, 177, 178, 179, 180, 185, 186, 187, 188, 191, 192, 193, 194, 195,
-196, 197, 200, 201, 202, 203, 204, 205, 206, 207, 217, 218, 219, 220, 223, 254,
-255, 133, 129, 131, 135, 137, 139, 141, 143, 145, 147, 149, 151, 240, 153, 155,
-161, 163, 236, 173, 167, 169, 234, 244, 184, 190, 199, 209, 211, 213, 215, 221,
-226, 228, 230, 232, 171, 182, 165, 252, 246, 250, 159, 242, 238, 248, 157, 224,
-160, 162, 235, 172, 166, 168, 233, 243, 183, 189, 198, 208, 210, 212, 214, 216,
-225, 227, 229, 231, 170, 181, 164, 251, 245, 249, 158, 241, 237, 247, 156, 222,
-239, 132, 128, 130, 134, 136, 138, 140, 142, 144, 146, 148, 150, 253, 152, 154
-};
-
-CONST CHAR
-ylc1251[] = { /* Latin/Cyrillic to CP1251 (inverse of y1251lc) */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-130, 132, 133, 134, 135, 136, 137, 139, 145, 146, 147, 148, 149, 150, 151, 152,
-153, 155, 164, 165, 166, 169, 171, 172, 174, 176, 177, 180, 181, 182, 183, 187,
-160, 168, 128, 129, 170, 189, 178, 175, 163, 138, 140, 142, 141, 173, 161, 143,
-192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
-208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
-240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
-185, 184, 144, 131, 186, 190, 179, 191, 188, 154, 156, 158, 157, 167, 162, 159
-};
-
-CONST CHAR
-ylcbu[] = { /* Latin/Cyrillic to Bulgarian PC Code Page */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-255, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
-176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
-213, 207, 208, 209, 210, 211, 212, 215, 216, 217, 218, 219, 220, 221, 222, 223,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
-240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 214, 253, 254
-};
-
-CONST CHAR
-ylck8[] = { /* Latin/Cyrillic to Old KOI-8 Cyrillic */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-UNK, 229, UNK, UNK, UNK, 83, 73, 73, 74, UNK, UNK, UNK, 235, UNK, 245, UNK,
-225, 226, 247, 231, 228, 229, 246, 250, 233, 234, 235, 236, 237, 238, 239, 240,
-242, 243, 244, 245, 230, 232, 227, 254, 251, 253, 255, 249, 248, 252, 224, 241,
-193, 194, 215, 199, 196, 197, 214, 218, 201, 202, 203, 204, 205, 206, 207, 208,
-210, 211, 212, 213, 198, 200, 195, 222, 219, 221, 223, 217, 216, 220, 192, 209,
-UNK, 197, UNK, UNK, UNK, 115, 105, 105, 106, UNK, UNK, UNK, 203, UNK, 213, UNK
-};
-
-CONST CHAR
-yaclc[] = { /* CP866 to Latin/Cyrillic */
-/* NEED TO MAKE THIS ONE INVERTIBLE */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
-192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
-208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
-161, 241, 164, 244, 167, 247, 174, 254, UNK, UNK, UNK, UNK, 240, UNK, UNK, UNK
-};
-
-CONST CHAR
-y55lc[] = { /* CP855 to Latin/Cyrillic (inverse of ylc55) */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-242, 162, 243, 163, 241, 161, 244, 164, 245, 165, 246, 166, 247, 167, 248, 168,
-249, 169, 250, 170, 251, 171, 252, 172, 254, 174, 255, 175, 238, 206, 234, 202,
-208, 176, 209, 177, 230, 198, 212, 180, 213, 181, 228, 196, 211, 179, 128, 129,
-130, 131, 132, 133, 134, 229, 197, 216, 184, 135, 136, 137, 138, 217, 185, 139,
-140, 141, 142, 143, 144, 145, 218, 186, 146, 147, 148, 149, 150, 151, 152, 153,
-219, 187, 220, 188, 221, 189, 222, 190, 223, 154, 155, 156, 157, 191, 239, 158,
-207, 224, 192, 225, 193, 226, 194, 227, 195, 214, 182, 210, 178, 236, 204, 240,
-173, 235, 203, 215, 183, 232, 200, 237, 205, 233, 201, 231, 199, 253, 159, 160
-};
-
-CONST CHAR
-y1251lc[] = { /* CP1251 to Latin/Cyrillic (inverse of ylc1251) */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-162, 163, 128, 243, 129, 130, 131, 132, 133, 134, 169, 135, 170, 172, 171, 175,
-242, 136, 137, 138, 139, 140, 141, 142, 143, 144, 249, 145, 250, 252, 251, 255,
-160, 174, 254, 168, 146, 147, 148, 253, 161, 149, 164, 150, 151, 173, 152, 167,
-153, 154, 166, 246, 155, 156, 157, 158, 241, 240, 244, 159, 248, 165, 245, 247,
-176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
-192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
-208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
-};
-
-CONST CHAR
-ybulc[] = { /* Bulgarian PC Code Page to Latin/Cyrillic */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
-176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
-192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
-129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 209,
-210, 211, 212, 213, 214, 208, 253, 215, 216, 217, 218, 219, 220, 221, 222, 223,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
-240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 254, 255, 128
-};
-
-CONST CHAR
-yk8lc[] = { /* Old KOI-8 Cyrillic to Latin/Cyrillic */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-238, 208, 209, 230, 212, 213, 228, 211, 229, 216, 217, 218, 219, 220, 221, 222,
-223, 239, 224, 225, 226, 227, 214, 210, 236, 235, 215, 232, 237, 233, 231, 234,
-206, 176, 177, 198, 180, 181, 196, 179, 197, 184, 185, 186, 187, 188, 189, 190,
-191, 207, 192, 193, 194, 195, 182, 178, 204, 203, 183, 200, 205, 201, 199, 127
-};
-
-CONST CHAR
-ylcsk[] = { /* Latin/Cyrillic to Short KOI */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 127,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 101, UNK, UNK, UNK, 83, 73, 73, 74, UNK, UNK, UNK, 107, 45, 117, UNK,
- 97, 98, 119, 103, 100, 101, 118, 122, 105, 106, 107, 108, 109, 110, 111, 112,
-114, 115, 116, 117, 102, 104, 99, 126, 123, 125, 39, 121, 120, 124, 96, 113,
- 97, 98, 119, 103, 100, 101, 118, 122, 105, 106, 107, 108, 109, 110, 111, 112,
-114, 115, 116, 117, 102, 104, 99, 126, 123, 125, 39, 121, 120, 124, 96, 113,
-UNK, 101, UNK, UNK, UNK, 83, 73, 73, 74, UNK, UNK, UNK, 107, UNK, 117, UNK
-};
-
-CONST CHAR yskcy[] = { /* Short KOI to Latin/Cyrillic */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
-206, 176, 177, 198, 180, 181, 196, 179, 197, 184, 185, 186, 187, 188, 189, 190,
-191, 207, 192, 193, 194, 195, 182, 178, 204, 203, 183, 200, 205, 201, 199, 127
-};
-#endif /* CYRILLIC */
-
-#ifdef LATIN2
-
-/* Latin-2 tables */
-
-CONST CHAR
-yl252[] = { /* Latin-2 to Code Page 852 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-174, 175, 176, 177, 178, 179, 180, 185, 186, 187, 188, 191, 192, 193, 194, 195,
-196, 197, 200, 201, 202, 203, 204, 205, 206, 217, 218, 219, 220, 223, 240, 254,
-255, 164, 244, 157, 207, 149, 151, 245, 249, 230, 184, 155, 141, 170, 166, 189,
-248, 165, 242, 136, 239, 150, 152, 243, 247, 231, 173, 156, 171, 241, 167, 190,
-232, 181, 182, 198, 142, 145, 143, 128, 172, 144, 168, 211, 183, 214, 215, 210,
-209, 227, 213, 224, 226, 138, 153, 158, 252, 222, 233, 235, 154, 237, 221, 225,
-234, 160, 131, 199, 132, 146, 134, 135, 159, 130, 169, 137, 216, 161, 140, 212,
-208, 228, 229, 162, 147, 139, 148, 246, 253, 133, 163, 251, 129, 236, 238, 250
-};
-
-CONST CHAR
-y52l2[] = { /* Code Page 852 to Latin-2 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-199, 252, 233, 226, 228, 249, 230, 231, 179, 235, 213, 245, 238, 172, 196, 198,
-201, 197, 229, 244, 246, 165, 181, 166, 182, 214, 220, 171, 187, 163, 215, 232,
-225, 237, 243, 250, 161, 177, 174, 190, 202, 234, 173, 188, 200, 186, 128, 129,
-130, 131, 132, 133, 134, 193, 194, 204, 170, 135, 136, 137, 138, 175, 191, 139,
-140, 141, 142, 143, 144, 145, 195, 227, 146, 147, 148, 149, 150, 151, 152, 164,
-240, 208, 207, 203, 239, 210, 205, 206, 236, 153, 154, 155, 156, 222, 217, 157,
-211, 223, 212, 209, 241, 242, 169, 185, 192, 218, 224, 219, 253, 221, 254, 180,
-158, 189, 178, 183, 162, 167, 247, 184, 176, 168, 255, 251, 216, 248, 159, 160
-};
-
-CONST CHAR
-yl21250[] = { /* Latin-2 to Code Page 1250 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 139, 144, 145, 146, 147, 148,
-149, 150, 151, 152, 153, 155, 166, 169, 171, 172, 174, 177, 181, 182, 183, 187,
-160, 165, 162, 163, 164, 188, 140, 167, 168, 138, 170, 141, 143, 173, 142, 175,
-176, 185, 178, 179, 180, 190, 156, 161, 184, 154, 186, 157, 159, 189, 158, 191,
-192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
-208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
-240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
-};
-
-CONST CHAR
-y1250l2[] = { /* Code Page 1250 to Latin-2 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 169, 138, 166, 171, 174, 172,
-139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 185, 149, 182, 187, 190, 188,
-160, 183, 162, 163, 164, 161, 150, 167, 168, 151, 170, 152, 153, 173, 154, 175,
-176, 155, 178, 179, 180, 156, 157, 158, 184, 177, 186, 159, 165, 189, 181, 191,
-192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
-208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
-240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
-};
-
-CONST CHAR
-yl2mz[] = { /* Latin-2 to Mazovia (NOT invertible) */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-255, 143, UNK, 156, 155, 76, 152, 21, 34, 83, 83, 84, 160, 45, 90, 161,
-248, 134, 44, 146, 39, 108, 158, UNK, 44, 115, 115, 116, 166, 34, 122, 167,
- 82, 65, 65, 65, 142, 76, 149, 128, 67, 69, 144, 69, 69, 73, 73, 68,
- 68, 165, 78, 163, 79, 153, 153, 250, 82, 85, 85, 154, 154, 89, 84, 225,
-114, 97, 131, 97, 132, 108, 141, 135, 99, 130, 145, 137, 101, 105, 140, 101,
-100, 164, 110, 162, 147, 148, 148, 246, 114, 117, 117, 129, 129, 121, 116, 249
-};
-
-CONST CHAR
-ymzl2[] = { /* Mazovia to Latin-2 (NOT INVERTIBLE) */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 252, 233, 226, 228, 97, 177, 231, 101, 235, 101, 105, 238, 230, 196, 161,
-202, 234, 179, 244, 246, 198, 117, 117, 166, 214, 220, 164, 163, 89, 182, 102,
-172, 175, 243, 211, 242, 210, 188, 191, 63, UNK, UNK, UNK, UNK, 33, 34, 34,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, 247, UNK, 176, 255, 215, UNK, UNK, UNK, UNK, 160
-};
-
-CONST CHAR
-yl2l1[] = { /* Latin-2 to Latin-1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 'A', UNK, 'L', 164, 'L', 'S', 167, 168, 'S', 'S', 'T', 'Z', 173, 'Z', 'Z',
-176, 'a', UNK, 'l', 180, 'l', 's', UNK, 184, 's', 's', 't', 'z', UNK, 'z', 'z',
-'R', 193, 194, 'A', 196, 'L', 'C', 199, 'C', 201, 'E', 203, 'E', 205, 'I', 'D',
-208, 'N', 'N', 211, 212, 'O', 214, 215, 'R', 'U', 218, 'U', 220, 221, 'T', 223,
-'r', 225, 226, 'a', 228, 'l', 'c', 231, 'c', 233, 'e', 235, 'e', 237, 'i', 'd',
-240, 'n', 'n', 243, 244, 'o', 246, 247, 'r', 'u', 250, 'u', 252, 253, 't', '.'
-};
-
-CONST CHAR
-yl1l2[] = { /* Latin-1 to Latin-2 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-160, 'A', UNK, 'L', 164, UNK, UNK, 167, 168, 'C', 'a', '<', '>', 173, 'R', UNK,
-176, UNK, UNK, UNK, 180, UNK, UNK, UNK, 184, UNK, 'o', '>', UNK, UNK, UNK, UNK,
-'A', 193, 194, 'A', 196, 'A', 'A', 199, 'E', 201, 'E', 203, 'I', 205, 'I', 'I',
-208, 'N', 'O', 211, 212, 'O', 214, 215, 'O', 'U', 218, 'U', 220, 221, UNK, 223,
-'a', 225, 226, 'a', 228, 'a', 'a', 231, 'e', 233, 'e', 235, 'i', 237, 'i', 'i',
-240, 'n', 'o', 243, 244, 'o', 246, 247, 'o', 'u', 250, 'u', 252, 253, UNK, 'y'
-};
-
-CONST CHAR
-yl2as[] = { /* Latin-2 to ASCII */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
- 32, 'A', UNK, 'L', UNK, 'L', 'S', UNK, 34, 'S', 'S', 'T', 'Z', '-', 'Z', 'Z',
-UNK, 'a', UNK, 'l', 39, 'l', 's', UNK, 44, 's', 's', 't', 'z', UNK, 'z', 'z',
-'R', 'A', 'A', 'A', 'A', 'L', 'C', 'C', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'D',
-'D', 'N', 'N', 'O', 'O', 'O', 'O', 'x', 'R', 'U', 'U', 'U', 'U', 'Y', 'T', 's',
-'r', 'a', 'a', 'a', 'a', 'l', 'c', 'c', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'd',
-'d', 'n', 'n', 'o', 'o', 'o', 'o', '/', 'r', 'u', 'u', 'u', 'u', 'y', 't', '.'
-};
-#endif /* LATIN2 */
-
-#ifdef HEBREW
-/*
- 8-bit Tables providing invertible translation between Latin/Hebrew and CP862.
-*/
-CONST CHAR
-y62lh[] = { /* PC Code Page 862 to ISO 8859-8 Latin/Hebrew */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
-240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 162, 163, 165, 128, 129,
-130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 172, 189, 188, 140, 171, 187,
-141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
-157, 158, 159, 161, 164, 166, 167, 168, 169, 170, 173, 174, 175, 223, 179, 180,
-182, 184, 185, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
-203, 204, 205, 206, 207, 208, 181, 209, 210, 211, 212, 213, 214, 215, 216, 217,
-218, 177, 219, 220, 221, 222, 186, 251, 176, 183, 252, 253, 254, 178, 255, 160
-};
-
-CONST CHAR
-ylh62[] = { /* ISO 8859-8 Latin/Hebrew to PC Code Page 862 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 173, 176, 177, 178,
-179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
-255, 195, 155, 156, 196, 157, 197, 198, 199, 200, 201, 174, 170, 202, 203, 204,
-248, 241, 253, 206, 207, 230, 208, 249, 209, 210, 246, 175, 172, 171, 211, 212,
-213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,
-229, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 242, 243, 244, 245, 205,
-128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 247, 250, 251, 252, 254
-};
-/*
- 7-bit table providing readable translation from DEC Hebrew-7 to CP862.
-*/
-CONST CHAR
-yh762[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
-UNK, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127
-};
-/*
- 8-bit table providing readable translation from CP862 to Hebrew-7.
-*/
-CONST CHAR
-y62h7[] = { /* PC Code Page 862 to Hebrew-7 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK
-};
-/*
- 7-bit table providing readable translation from Hebrew-7 to ISO Latin/Hebrew.
-*/
-CONST CHAR
-yh7lh[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
-208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
-224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 123, 124, 125, 126, 127
-};
-/*
- 8-bit table providing readable translation from ISO Latin/Hebrew to Hebrew-7.
-*/
-CONST CHAR
-ylhh7[] = { /* Latin/Hebrew to Hebrew-7 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, UNK, UNK, UNK, UNK, UNK
-};
-#endif /* HEBREW */
-
-#ifdef GREEK
-/*
- 8-bit Tables providing invertible translation between Latin/Greek and CP869.
-*/
-CONST CHAR
-ylg69[] = { /* ISO 8859-7 Latin/Greek to PC Code Page 869 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-135, 147, 148, 176, 177, 178, 179, 180, 185, 186, 187, 188, 191, 192, 193, 194,
-195, 196, 197, 200, 201, 202, 203, 204, 205, 206, 217, 218, 219, 220, 223, 254,
-255, 139, 140, 156, 128, 129, 138, 245, 249, 151, 130, 174, 137, 240, 131, 142,
-248, 241, 153, 154, 239, 247, 134, 136, 141, 143, 144, 175, 146, 171, 149, 152,
-161, 164, 165, 166, 167, 168, 169, 170, 172, 173, 181, 182, 183, 184, 189, 190,
-198, 199, 132, 207, 208, 209, 210, 211, 212, 213, 145, 150, 155, 157, 158, 159,
-252, 214, 215, 216, 221, 222, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
-234, 235, 237, 236, 238, 242, 243, 244, 246, 250, 160, 251, 162, 163, 253, 133
-};
-
-CONST CHAR
-y69lg[] = { /* PC Code Page 869 to ISO 8859-7 Latin/Greek */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
-164, 165, 170, 174, 210, 255, 182, 128, 183, 172, 166, 161, 162, 184, 175, 185,
-186, 218, 188, 129, 130, 190, 219, 169, 191, 178, 179, 220, 163, 221, 222, 223,
-250, 192, 252, 253, 193, 194, 195, 196, 197, 198, 199, 189, 200, 201, 171, 187,
-131, 132, 133, 134, 135, 202, 203, 204, 205, 136, 137, 138, 139, 206, 207, 140,
-141, 142, 143, 144, 145, 146, 208, 209, 147, 148, 149, 150, 151, 152, 153, 211,
-212, 213, 214, 215, 216, 217, 225, 226, 227, 154, 155, 156, 157, 228, 229, 158,
-230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 243, 242, 244, 180,
-173, 177, 245, 246, 247, 167, 248, 181, 176, 168, 249, 251, 224, 254, 159, 160
-};
-/*
- 7-bit table providing readable translation from ELOT 927 to CP869.
-*/
-CONST CHAR
-yeg69[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 164, 165, 166, 167, 168, 169, 170, 172, 173, 181, 182, 183, 184, 189, 190,
-198, 199, 207, 208, 209, 210, 211, 212, 213, 32, 32, 23, 124, 125, 126, 127
-};
-/*
- 8-bit table providing readable translation from CP869 to ELOT 927.
-*/
-CONST CHAR
-y69eg[] = { /* PC Code Page 869 to ELOT 927 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127,
-UNK, UNK, UNK, UNK, UNK, UNK, 97, UNK, 46, UNK, 124, 39, 39, 101, 45, 103,
-105, 105, 111, UNK, UNK, 116, 116, UNK, 120, 50, 51, 97, UNK, 101, 103, 105,
-105, 105, 111, 116, 97, 98, 99, 100, 101, 102, 103, UNK, 104, 105, 34, 34,
-UNK, UNK, UNK, UNK, UNK, 106, 107, 108, 109, UNK, UNK, UNK, UNK, 110, 111, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, 112, 113, UNK, UNK, UNK, UNK, UNK, UNK, UNK, 114,
-115, 116, 117, 118, 119, 120, 97, 98, 99, UNK, UNK, UNK, UNK, 100, 101, UNK,
-102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 39,
- 45, UNK, 116, 117, 118, UNK, 119, UNK, UNK, UNK, 120, 116, 116, 120, UNK, 32
-
-};
-/*
- 7-bit table providing readable translation from ELOT 927 to ISO Latin/Greek.
-*/
-CONST CHAR
-yeglg[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
-208, 209, 211, 212, 213, 214, 215, 216, 217, 32, 32, 123, 124, 125, 126, 127
-};
-/*
- 8-bit table providing readable translation from ISO Latin/Greek to ELOT 927.
-*/
-CONST CHAR
-ylgeg[] = { /* Latin/Greek to ELOT 927 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
-UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK, UNK,
- 32, 39, 39, UNK, UNK, UNK, 124, UNK, 34, UNK, UNK, 34, UNK, 45, UNK, 45,
-UNK, UNK, 50, 51, 39, UNK, 97, 46, 101, 103, 105, 34, 111, UNK, 116, 120,
-UNK, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, UNK, 114, 115, 116, 117, 118, 119, 120, 105, 116, 97, 101, 103, 105,
-116, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 105, 116, 111, 116, 120, UNK
-};
-#endif /* GREEK */
-
-/* Translation functions ... */
-
-CHAR /* The identity function... */
-#ifdef CK_ANSIC
-ident(CHAR c) /* (no longer used) */
-#else
-ident(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* ident */
- return(c); /* Instead, enter NULL in the */
-} /* table of functions to avoid */
- /* needless function calls. */
-
-CHAR
-#ifdef CK_ANSIC
-xleft128(CHAR c)
-#else
-xleft128(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xleft128 */
- return((c < 128) ? c : '?');
-}
-
-CHAR
-#ifdef CK_ANSIC
-xleft160(CHAR c)
-#else
-xleft160(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xleft160 */
- return((c < 160) ? c : '?');
-}
-
-
-CHAR
-#ifdef CK_ANSIC
-xl1as(CHAR c)
-#else
-xl1as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1as */ /* Latin-1 to US ASCII... */
- switch(langs[language].id) {
-
- case L_DUTCH:
- if (c == 255) { /* Dutch umlaut-y */
- zmstuff('j'); /* becomes ij */
- return('i');
- } else return(yl1as[c]); /* all others by the book */
-
- case L_GERMAN:
- switch (c) { /* German, special rules. */
- case 196: /* umlaut-A -> Ae */
- zmstuff('e');
- return('A');
- case 214: /* umlaut-O -> Oe */
- zmstuff('e');
- return('O');
- case 220: /* umlaut-U -> Ue */
- zmstuff('e');
- return('U');
- case 228: /* umlaut-a -> ae */
- zmstuff('e');
- return('a');
- case 246: /* umlaut-o -> oe */
- zmstuff('e');
- return('o');
- case 252: /* umlaut-u -> ue */
- zmstuff('e');
- return('u');
- case 223: /* ess-zet -> ss */
- zmstuff('s');
- return('s');
- default: return(yl1as[c]); /* all others by the book */
- }
- case L_DANISH:
- case L_FINNISH:
- case L_NORWEGIAN:
- case L_SWEDISH:
- switch (c) { /* Scandanavian languages. */
- case 196: /* umlaut-A -> Ae */
- case 198: /* AE ligature also -> Ae */
- zmstuff('e');
- return('A');
- case 214: /* umlaut-O -> Oe */
- case 216: /* O-slash -> Oe */
- zmstuff('e');
- return('O');
- case 220: /* umlaut-U -> Ue */
- /* return('Y'); replaced by "Ue" by popular demand. */
- /* Y for Umlaut-U is only used in German names. */
- zmstuff('e');
- return('U');
- case 228: /* umlaut-a -> ae */
- case 230: /* ditto for ae ligature */
- zmstuff('e');
- return('a');
- case 246: /* umlaut-o -> oe */
- case 248: /* o-slash -> oe */
- zmstuff('e');
- return('o');
- case 252: /* umlaut-u -> ue */
- /* return('y'); replaced by "ue" by popular demand. */
- zmstuff('e');
- return('u');
- case 197: /* A-ring -> Aa */
- zmstuff('a');
- return('A');
- case 229: /* a-ring -> aa */
- zmstuff('a');
- return('a');
- default: return(yl1as[c]); /* All others by the book */
- }
- case L_ICELANDIC: /* Icelandic. */
- switch (c) {
- case 198: /* uppercase AE -> AE */
- zmstuff('e');
- return('A');
- case 208: /* uppercase Eth -> D */
- return('D');
- case 214: /* uppercase O-diaeresis -> Oe */
- zmstuff('e');
- return('O');
- case 222: /* uppercase Thorn -> Th */
- zmstuff('h');
- return('T');
- case 230: /* lowercase ae -> ae */
- zmstuff('e');
- return('a');
- case 240: /* lowercase Eth -> d */
- return('d');
- case 246: /* lowercase O-diaeresis -> oe */
- zmstuff('e');
- return('o');
- case 254: /* lowercase Thorn -> th */
- zmstuff('h');
- return('t');
- default: return(yl1as[c]); /* All others by the book */
- }
- default:
- return(yl1as[c]); /* None of the above, by the table. */
- }
-}
-
-CHAR /* CP1252 to ASCII */
-#ifdef CK_ANSIC
-xw1as(CHAR c)
-#else
-xw1as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xw1as */
- switch(c) { /* Microsoft name... */
- case 0x80: return('?'); /* Euro Sign */
- case 0x82: return('\047'); /* Single Low-9 Quotation Mark */
- case 0x83: return('f'); /* Latin Small Letter f with Hook */
- case 0x84: return('"'); /* Double low-9 Quotation Mark */
- case 0x85: return('-'); /* Horizontal Ellipsis */
- case 0x86: return('+'); /* Dagger */
- case 0x87: return('+'); /* Double Dagger */
- case 0x88: return('^'); /* Modifier Letter Circumflex Accent */
- case 0x89: return('?'); /* Per Mille Sign */
- case 0x8A: return('S'); /* Latin Capital Letter S with Caron */
- case 0x8B: return('<'); /* Single Left Angle Quotation Mark */
- case 0x8C: return('O'); /* Latin Capital Ligature OE */
- case 0x8E: return('Z'); /* Latin Capital Letter Z with Caron */
- case 0x91: return('\047'); /* Left Single Quotation Mark */
- case 0x92: return('\047'); /* Right Single Quotation Mark */
- case 0x93: return('"'); /* Left Double Quotation Mark */
- case 0x94: return('"'); /* Right Double Quotation Mark */
- case 0x95: return('.'); /* Bullet */
- case 0x96: return('-'); /* En Dash */
- case 0x97: return('-'); /* Em Dash */
- case 0x98: return('~'); /* Small Tilde */
- case 0x99: return('T'); /* Trade Mark Sign */
- case 0x9A: return('s'); /* Latin Small Letter s with Caron */
- case 0x9B: return('>'); /* Single Right Angle Quotation Mark */
- case 0x9C: return('o'); /* Latin Small Ligature OE */
- case 0x9E: return('z'); /* Latin Small Letter z with Caron */
- case 0x9F: return('Y'); /* Latin Capital Letter Y Diaeresis */
- default:
- if (c > 0x80 && c < 0xa0)
- return('?');
- else
- return(yl1as[c]);
- }
-}
-
-CHAR /* CP1252 to Latin-1 */
-#ifdef CK_ANSIC
-xw1l1(CHAR c)
-#else
-xw1l1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xw1l1 */
- if (c == 0x95) return(0xb7); /* Middle dot */
- return((c < 160) ? xw1as(c) : c);
-}
-
-CHAR /* Latin-1 to German */
-#ifdef CK_ANSIC
-xl1ge(CHAR c)
-#else
-xl1ge(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1ge */
- return(yl1ge[c]);
-}
-
-CHAR /* German to Latin-1 */
-#ifdef CK_ANSIC
-xgel1(CHAR c)
-#else
-xgel1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xgel1 */
- if (c & 0x80)
- return(UNK);
- return(ygel1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xgeas(CHAR c)
-#else
-xgeas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xgeas */ /* German ISO 646 to ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 91: /* umlaut-A -> Ae */
- zmstuff('e');
- return('A');
- case 92: /* umlaut-O -> Oe */
- zmstuff('e');
- return('O');
- case 93: /* umlaut-U -> Ue */
- zmstuff('e');
- return('U');
- case 123: /* umlaut-a -> ae */
- zmstuff('e');
- return('a');
- case 124: /* umlaut-o -> oe */
- zmstuff('e');
- return('o');
- case 125: /* umlaut-u -> ue */
- zmstuff('e');
- return('u');
- case 126: /* ess-zet -> ss */
- zmstuff('s');
- return('s');
- default: return(c); /* all others stay the same */
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1w1(CHAR c)
-#else
-xl1w1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1w1 */ /* Latin-1 to CP1252 (Windows L1) */
- if (c > 127 && c < 160)
- return(UNK);
- else
- return(c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xduas(CHAR c)
-#else
-xduas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xduas */ /* Dutch ISO 646 to US ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 64: return(UNK); /* 3/4 */
- case 91: /* y-diaeresis */
- zmstuff('j');
- return('i');
- case 92: return(UNK); /* 1/2 */
- case 93: return(124); /* vertical bar */
- case 123: return(34); /* diaeresis */
- case 124: return(UNK); /* Florin */
- case 125: return(UNK); /* 1/4 */
- case 126: return(39); /* Apostrophe */
- default: return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xfias(CHAR c)
-#else
-xfias(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xfias */ /* Finnish ISO 646 to US ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 91: /* A-diaeresis */
- zmstuff('e');
- return('A');
- case 92: /* O-diaeresis */
- zmstuff('e');
- return('O');
- case 93: /* A-ring */
- zmstuff('a');
- return('A');
- case 94: /* U-diaeresis */
- /* return('Y'); */
- zmstuff('e');
- return('U');
- case 96: /* e-acute */
- return('e');
- case 123: /* a-diaeresis */
- zmstuff('e');
- return('a');
- case 124: /* o-diaeresis */
- zmstuff('e');
- return('o');
- case 125: /* a-ring */
- zmstuff('a');
- return('a');
- case 126: /* u-diaeresis */
- /* return('y'); */
- zmstuff('e');
- return('U');
- default:
- return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xfras(CHAR c)
-#else
-xfras(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xfras */ /* French ISO 646 to US ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 64: return(97); /* a grave */
- case 91: return(UNK); /* degree sign */
- case 92: return(99); /* c cedilla */
- case 93: return(UNK); /* paragraph sign */
- case 123: return(101); /* e acute */
- case 124: return(117); /* u grave */
- case 125: return(101); /* e grave */
- case 126: return(34); /* diaeresis */
- default: return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xfcas(CHAR c)
-#else
-xfcas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xfcas */ /* French Canadian ISO 646 to ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 64: return('a'); /* a grave */
- case 91: return('a'); /* a circumflex */
- case 92: return('c'); /* c cedilla */
- case 93: return('e'); /* e circumflex */
- case 94: return('i'); /* i circumflex */
- case 96: return('o'); /* o circumflex */
- case 123: return('e'); /* e acute */
- case 124: return('u'); /* u grave */
- case 125: return('e'); /* e grave */
- case 126: return('u'); /* u circumflex */
- default: return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xitas(CHAR c)
-#else
-xitas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xitas */ /* Italian ISO 646 to ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 91: return(UNK); /* degree */
- case 92: return('c'); /* c cedilla */
- case 93: return('e'); /* e acute */
- case 96: return('u'); /* u grave */
- case 123: return('a'); /* a grave */
- case 124: return('o'); /* o grave */
- case 125: return('e'); /* e grave */
- case 126: return('i'); /* i grave */
- default: return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xneas(CHAR c)
-#else
-xneas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xneas */ /* NeXT to ASCII */
- if (langs[language].id == L_FRENCH) { /* If SET LANGUAGE FRENCH */
- if (c == 234) { /* handle OE digraph. */
- zmstuff('E');
- return('O');
- } else if (c == 250) { /* Also lowercase oe. */
- zmstuff('e');
- return('o');
- }
- }
- c = xnel1(c); /* Convert to Latin-1 */
- return(yl1as[c]); /* Convert Latin-1 to ASCII */
-}
-
-CHAR
-#ifdef CK_ANSIC
-xnoas(CHAR c)
-#else
-xnoas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xnoas */ /* Norge/Danish ISO 646 to ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 91:
- zmstuff('E'); /* AE digraph */
- return('A');
- case 92: return('O'); /* O slash */
- case 93: /* A ring */
- zmstuff('a');
- return('A');
- case 123: /* ae digraph */
- zmstuff('e');
- return('a');
- case 124: return('o'); /* o slash */
- case 125: /* a ring */
- zmstuff('a');
- return('a');
- default: return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xpoas(CHAR c)
-#else
-xpoas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xpoas */ /* Portuguese ISO 646 to ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 91: return('A'); /* A tilde */
- case 92: return('C'); /* C cedilla */
- case 93: return('O'); /* O tilde */
- case 123: return('a'); /* a tilde */
- case 124: return('c'); /* c cedilla */
- case 125: return('o'); /* o tilde */
- default: return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xspas(CHAR c)
-#else
-xspas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xspas */ /* Spanish ISO 646 to ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 91: return(33); /* Inverted exclamation */
- case 92: return('N'); /* N tilde */
- case 93: return(63); /* Inverted question mark */
- case 123: return(UNK); /* degree */
- case 124: return('n'); /* n tilde */
- case 125: return('c'); /* c cedilla */
- default: return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xswas(CHAR c)
-#else
-xswas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xswas */ /* Swedish ISO 646 to ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 64: return('E'); /* E acute */
- case 91: /* A diaeresis */
- zmstuff('e');
- return('A');
- case 92: /* O diaeresis */
- zmstuff('e');
- return('O');
- case 93: /* A ring */
- zmstuff('a');
- return('A');
- case 94: /* U diaeresis */
- /* return('Y'); */
- zmstuff('e');
- return('U');
- case 96: return('e'); /* e acute */
- case 123: /* a diaeresis */
- zmstuff('e');
- return('a');
- case 124: /* o diaeresis */
- zmstuff('e');
- return('o');
- case 125: /* a ring */
- zmstuff('a');
- return('a');
- case 126: /* u diaeresis */
- /* return('y'); */
- zmstuff('e');
- return('u');
- default: return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xchas(CHAR c)
-#else
-xchas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xchas */ /* Swiss ISO 646 to ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 35: return('u'); /* u grave */
- case 64: return('a'); /* a grave */
- case 91: return('e'); /* e acute */
- case 92: return('c'); /* c cedilla */
- case 93: return('e'); /* e circumflex */
- case 94: return('i'); /* i circumflex */
- case 95: return('e'); /* e grave */
- case 96: return('o'); /* o circumflex */
- case 123: /* a diaeresis */
- zmstuff('e');
- return('a');
- case 124: /* o diaeresis */
- zmstuff('e');
- return('o');
- case 125: /* u diaeresis */
- zmstuff('e');
- return('u');
- case 126: return('u'); /* u circumflex */
- default: return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xhuas(CHAR c)
-#else
-xhuas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xhuas */ /* Hungarian ISO 646 to ASCII */
- if (c & 0x80)
- return(UNK);
- switch (c) {
- case 64: return('A'); /* A acute */
- case 91: return('E'); /* E acute */
- case 92: return('O'); /* O diaeresis */
- case 93: return('U'); /* U diaeresis */
- case 96: return('a'); /* a acute */
- case 123: return('e'); /* e acute */
- case 124: return('o'); /* o acute */
- case 125: return('u'); /* u acute */
- case 126: return(34); /* double acute accent */
- default: return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xdmas(CHAR c)
-#else
-xdmas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xdmas */ /* DEC MCS to ASCII */
- if (langs[language].id == L_FRENCH) { /* If SET LANGUAGE FRENCH */
- if (c == 215) { /* handle OE digraph. */
- zmstuff('E');
- return('O');
- } else if (c == 247) { /* Also lowercase oe. */
- zmstuff('e');
- return('o');
- }
- }
- return(yl1as[c]); /* Otherwise treat like Latin-1 */
-}
-
-CHAR
-#ifdef CK_ANSIC
-xdgas(CHAR c)
-#else
-xdgas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xdgas */ /* Data General to ASCII */
- switch(c) {
- case 180: return('f'); /* Florin */
- case 183: return('<'); /* Less-equal */
- case 184: return('>'); /* Greater-equal */
- case 186: return(96); /* Grave accent */
- case 191: return('^'); /* Uparrow */
- case 215:
- if (langs[language].id == L_FRENCH) { /* OE digraph */
- zmstuff('E');
- return('O');
- } else return('O');
- case 247:
- if (langs[language].id == L_FRENCH) { /* oe digraph */
- zmstuff('e');
- return('o');
- } else return('o');
- case 175: case 179: case 220: case 222:
- case 223: case 254: case 255:
- return(UNK);
- default: /* The rest, convert to Latin-1 */
- return(yl1as[ydgl1[c]]); /* and from there to ASCII */
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xr8as(CHAR c)
-#else
-xr8as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xr8as */ /* Hewlett Packard Roman8 to ASCII */
- switch(c) {
- case 175: return('L'); /* Lira */
- case 190: return('f'); /* Florin */
- case 235: return('S'); /* S caron */
- case 236: return('s'); /* s caron */
- case 246: return('-'); /* Horizontal bar */
- case 252: return('*'); /* Solid box */
- default: /* The rest, convert to Latin-1 */
- return(yl1as[yr8l1[c]]); /* and from there to ASCII */
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xukl1(CHAR c)
-#else
-xukl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xukl1 */ /* UK ASCII to Latin-1 */
- if (c & 0x80)
- return(UNK);
- if (c == 35)
- return(163);
- else return(c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1uk(CHAR c)
-#else
-xl1uk(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1uk */ /* Latin-1 to UK ASCII */
- if (c == 163)
- return(35);
- else return(yl1as[c]);
-}
-
-CHAR /* Latin-1 to French ISO 646 */
-#ifdef CK_ANSIC
-xl1fr(CHAR c)
-#else
-xl1fr(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1fr */
- return(yl1fr[c]);
-}
-
-
-CHAR /* French ISO 646 to Latin-1 */
-#ifdef CK_ANSIC
-xfrl1(CHAR c)
-#else
-xfrl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xfrl1 */
- if (c & 0x80)
- return(UNK);
- return(yfrl1[c]);
-}
-
-CHAR /* Latin-1 to Dutch ASCII */
-#ifdef CK_ANSIC
-xl1du(CHAR c)
-#else
-xl1du(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1du */
- return(yl1du[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xdul1(CHAR c)
-#else
-xdul1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xdul1 */ /* Dutch ISO 646 to Latin-1 */
- if (c & 0x80)
- return(UNK);
- return(ydul1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xfil1(CHAR c)
-#else
-xfil1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xfil1 */ /* Finnish ISO 646 to Latin-1 */
- if (c & 0x80)
- return(UNK);
- return(yfil1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1fi(CHAR c)
-#else
-xl1fi(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1fi */ /* Latin-1 to Finnish ISO 646 */
- return(yl1fi[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xfcl1(CHAR c)
-#else
-xfcl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xfcl1 */ /* French Canadian ISO646 to Latin-1 */
- if (c & 0x80)
- return(UNK);
- return(yfcl1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1fc(CHAR c)
-#else
-xl1fc(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1fc */ /* Latin-1 to French Canadian ISO646 */
- return(yl1fc[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xitl1(CHAR c)
-#else
-xitl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xitl1 */ /* Italian ISO 646 to Latin-1 */
- if (c & 0x80)
- return(UNK);
- return(yitl1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1it(CHAR c)
-#else
-xl1it(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1it */ /* Latin-1 to Italian ISO 646 */
- return(yl1it[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xnel1(CHAR c)
-#else
-xnel1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xnel1 */ /* NeXT to Latin-1 */
- if (langs[language].id == L_FRENCH) { /* If SET LANGUAGE FRENCH */
- if (c == 234) { /* handle OE digraph. */
- zmstuff('E');
- return('O');
- } else if (c == 250) { /* Also lowercase oe. */
- zmstuff('e');
- return('o');
- }
- }
- return(ynel1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xnel9(CHAR c)
-#else
-xnel9(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xnel9 */ /* NeXT to Latin-9 */
- switch (c) {
- case 234: return(188); /* OE */
- case 250: return(189); /* oe */
- case 188: return(234); /* keep it invertible... */
- case 189: return(250); /* oe */
- default:
- return(ynel1[c]);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1ne(CHAR c)
-#else
-xl1ne(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1ne */ /* Latin-1 to NeXT */
- return(yl1ne[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl9ne(CHAR c)
-#else
-xl9ne(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl9ne */ /* Latin-9 to NeXT */
- switch (c) {
- case 188: return(234); /* OE */
- case 189: return(250); /* oe */
- case 234: return(188); /* OE */
- case 250: return(189); /* oe */
- default:
- return(yl1ne[c]);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xnol1(CHAR c)
-#else
-xnol1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xnol1 */ /* Norway/Denmark ISO 646 to Latin-1 */
- if (c & 0x80)
- return(UNK);
- return(ynol1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1no(CHAR c)
-#else
-xl1no(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1no */ /* Latin-1 to Norway/Denmark ISO 646 */
- return(yl1no[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xpol1(CHAR c)
-#else
-xpol1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xpol1 */ /* Portuguese ISO 646 to Latin-1 */
- if (c & 0x80)
- return(UNK);
- return(ypol1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1po(CHAR c)
-#else
-xl1po(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1po */ /* Latin-1 to Portuguese ISO 646 */
- return(yl1po[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xspl1(CHAR c)
-#else
-xspl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xspl1 */ /* Spanish ISO 646 to Latin-1 */
- if (c & 0x80)
- return(UNK);
- return(yspl1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1sp(CHAR c)
-#else
-xl1sp(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1sp */ /* Latin-1 to Spanish ISO 646 */
- return(yl1sp[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xswl1(CHAR c)
-#else
-xswl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xswl1 */ /* Swedish ISO 646 to Latin-1 */
- if (c & 0x80)
- return(UNK);
- return(yswl1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1sw(CHAR c)
-#else
-xl1sw(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1sw */ /* Latin-1 to Swedish ISO 646 */
- return(yl1sw[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xchl1(CHAR c)
-#else
-xchl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xchl1 */ /* Swiss ISO 646 to Latin-1 */
- if (c & 0x80)
- return(UNK);
- return(ychl1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1ch(CHAR c)
-#else
-xl1ch(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1ch */ /* Latin-1 to Swiss ISO 646 */
- return(yl1ch[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xhul1(CHAR c)
-#else
-xhul1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xhul1 */ /* Hungarian ISO 646 to Latin-1 */
- if (c & 0x80)
- return(UNK);
- return(yhul1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1hu(CHAR c)
-#else
-xl1hu(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1hu */ /* Latin-1 to Hungarian ISO 646 */
- return(yl1hu[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1dm(CHAR c)
-#else
-xl1dm(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1dm */ /* Latin-1 to DEC MCS */
- return(yl1dm[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl9dm(CHAR c)
-#else
-xl9dm(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl9dm */ /* Latin-9 to DEC MCS */
- switch (c) {
- case 188: return(215);
- case 189: return(247);
- case 215: return(188);
- case 247: return(189);
- default:
- return(yl1dm[c]);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl9w1(CHAR c)
-#else
-xl9w1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl9w1 */ /* Latin-9 to CP1252 */
- if (c < 128)
- return(c);
- else if (c < 160)
- return('?');
- switch (c) {
- case 0xa4: return(0x80); /* Euro */
- case 0xa6: return(0x8a); /* S-caron */
- case 0xa8: return(0x9a); /* s-caron */
- case 0xb4: return(0x8e); /* Z-caron */
- case 0xb8: return(0x9e); /* z-caron */
- case 0xbc: return(0x8c); /* OE */
- case 0xbd: return(0x9c); /* oe */
- case 0xbe: return(0x9f); /* Y-diaeresis */
- default:
- return(c);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1dg(CHAR c)
-#else
-xl1dg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1dg */ /* Latin-1 to DG ICS */
- return(yl1dg[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xdml1(CHAR c)
-#else
-xdml1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xdml1 */ /* DEC MCS to Latin-1 */
- if (langs[language].id == L_FRENCH) { /* If SET LANGUAGE FRENCH */
- if (c == 215) { /* handle OE digraph. */
- zmstuff('E');
- return('O');
- } else if (c == 247) { /* Also lowercase oe. */
- zmstuff('e');
- return('o');
- }
- }
- return(ydml1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xdml9(CHAR c)
-#else
-xdml9(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xdml9 */ /* DEC MCS to Latin-9 */
- switch (c) {
- case 215: return(188); /* OE */
- case 247: return(189); /* oe */
- case 188: return(215); /* and swap the other two... */
- case 189: return(247); /* (1/4 and 1/2) */
- default: /* to keep it invertible */
- return(ydml1[c]);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xdgl1(CHAR c)
-#else
-xdgl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xdgl1 */ /* DG International CS to Latin-1 */
- if (langs[language].id == L_FRENCH) { /* If SET LANGUAGE FRENCH */
- if (c == 215) { /* handle OE digraph. */
- zmstuff('E');
- return('O');
- } else if (c == 247) { /* Also lowercase oe. */
- zmstuff('e');
- return('o');
- }
- }
- return(ydgl1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xr8l1(CHAR c)
-#else
-xr8l1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xr8l1 */ /* Hewlett Packard Roman8 to Latin-1 */
- return(yr8l1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1r8(CHAR c)
-#else
-xl1r8(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1r8 */ /* Latin-1 to Hewlett Packard Roman8 */
- return(yl1r8[c]);
-}
-
-/* Translation functions for receiving files and translating them into ASCII */
-
-CHAR
-#ifdef CK_ANSIC
-zl1as(CHAR c)
-#else
-zl1as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* zl1as */
- switch(langs[language].id) {
-
- case L_DUTCH:
- if (c == 255) { /* Dutch umlaut-y */
- zdstuff('j'); /* becomes ij */
- return('i');
- } else return(yl1as[c]); /* all others by the book */
-
- case L_GERMAN:
- switch (c) { /* German, special rules. */
- case 196: /* umlaut-A -> Ae */
- zdstuff('e');
- return('A');
- case 214: /* umlaut-O -> Oe */
- zdstuff('e');
- return('O');
- case 220: /* umlaut-U -> Ue */
- zdstuff('e');
- return('U');
- case 228: /* umlaut-a -> ae */
- zdstuff('e');
- return('a');
- case 246: /* umlaut-o -> oe */
- zdstuff('e');
- return('o');
- case 252: /* umlaut-u -> ue */
- zdstuff('e');
- return('u');
- case 223: /* ess-zet -> ss */
- zdstuff('s');
- return('s');
- default: return(yl1as[c]); /* all others by the book */
- }
- case L_DANISH:
- case L_FINNISH:
- case L_NORWEGIAN:
- case L_SWEDISH:
- switch (c) { /* Scandanavian languages. */
- case 196: /* umlaut-A -> Ae */
- zdstuff('e');
- return('A');
- case 214: /* umlaut-O -> Oe */
- case 216: /* O-slash -> Oe */
- zdstuff('e');
- return('O');
- case 220: /* umlaut-U -> Y */
- /* return('Y'); */
- zdstuff('e');
- return('U');
- case 228: /* umlaut-a -> ae */
- zdstuff('e');
- return('a');
- case 246: /* umlaut-o -> oe */
- case 248: /* o-slash -> oe */
- zdstuff('e');
- return('o');
- case 252: /* umlaut-u -> y */
- /* return('y'); */
- zdstuff('e');
- return('u');
- case 197: /* A-ring -> Aa */
- zdstuff('a');
- return('A');
- case 229: /* a-ring -> aa */
- zdstuff('a');
- return('a');
- default: return(yl1as[c]); /* All others by the book */
- }
- default:
- return(yl1as[c]); /* No language, go by the table. */
- }
-}
-
-CHAR /* IBM CP437 to Latin-1 */
-#ifdef CK_ANSIC
-x43l1(CHAR c)
-#else
-x43l1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x43l1 */
- return(y43l1[c]);
-}
-
-CHAR /* IBM CP850 to Latin-1 */
-#ifdef CK_ANSIC
-x85l1(CHAR c)
-#else
-x85l1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x85l1 */
- return(y85l1[c]);
-}
-
-CHAR /* Latin-1 to IBM CP437 */
-#ifdef CK_ANSIC
-xl143(CHAR c)
-#else
-xl143(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl143 */
- return(yl143[c]);
-}
-
-CHAR /* Latin-1 to CP850 */
-#ifdef CK_ANSIC
-xl185(CHAR c)
-#else
-xl185(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl185 */
- return(yl185[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-x43as(CHAR c)
-#else
-x43as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x43as */ /* CP437 to ASCII */
- c = y43l1[c]; /* Translate to Latin-1 */
- return(xl143(c)); /* and from Latin-1 to ASCII. */
-}
-
-CHAR
-#ifdef CK_ANSIC
-x85as(CHAR c)
-#else
-x85as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x85as */ /* CP850 to ASCII */
- c = y85l1[c]; /* Translate to Latin-1 */
- return(xl1as(c)); /* and from Latin-1 to ASCII. */
-}
-
-CHAR /* Macintosh Latin to Latin-1 */
-#ifdef CK_ANSIC
-xaql1(CHAR c)
-#else
-xaql1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xaql1 */
- if (langs[language].id == L_FRENCH) { /* If SET LANGUAGE FRENCH */
- if (c == 206) { /* handle OE digraph. */
- zmstuff('E');
- return('O');
- } else if (c == 207) { /* Also lowercase oe. */
- zmstuff('e');
- return('o');
- }
- }
- return(yaql1[c]);
-}
-
-CHAR /* Macintosh Latin to ASCII */
-#ifdef CK_ANSIC
-xaqas(CHAR c)
-#else
-xaqas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xaqas */
- if (langs[language].id == L_FRENCH) { /* If SET LANGUAGE FRENCH */
- if (c == 206) { /* handle OE digraph. */
- zmstuff('E');
- return('O');
- } else if (c == 207) { /* Also lowercase oe. */
- zmstuff('e');
- return('o');
- }
- }
- c = yaql1[c]; /* Translate to Latin-1 */
- return(xl1as(c)); /* then to ASCII. */
-}
-
-CHAR /* Latin-1 to Macintosh Latin */
-#ifdef CK_ANSIC
-xl1aq(CHAR c)
-#else
-xl1aq(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1aq */
- return(yl1aq[c]);
-}
-
-#ifdef LATIN2
-
-/* Translation functions for Latin Alphabet 2 */
-
-CHAR /* Latin-2 to Latin-1 */
-#ifdef CK_ANSIC
-xl2l1(CHAR c)
-#else
-xl2l1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll2l1 */
- return(yl2l1[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl2w1(CHAR c)
-#else
-xl2w1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl2w1 */ /* Latin-2 to CP1252 (Windows L1) */
- if (c > 127 && c < 160)
- return(UNK);
- else
- return(yl2l1[c]);
-}
-
-CHAR /* Latin-1 to Latin-2 */
-#ifdef CK_ANSIC
-xl1l2(CHAR c)
-#else
-xl1l2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll1l2 */
- return(yl1l2[c]);
-}
-
-CHAR /* CP1252 to Latin-1 */
-#ifdef CK_ANSIC
-xw1l2(CHAR c)
-#else
-xw1l2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xw1l2 */
- switch (c) {
- case 0x8a: return(0xa9); /* S caron */
- case 0x8e: return(0xae); /* Z caron */
- case 0x9a: return(0xb9); /* s caron */
- case 0x9e: return(0xbe); /* z caron */
- default:
- return((c < 160) ? xw1as(c) : xl1l2(c));
- }
-}
-
-
-CHAR /* Latin-2 to ASCII */
-#ifdef CK_ANSIC
-xl2as(CHAR c)
-#else
-xl2as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll2as */
- return(yl2as[c]);
-}
-
-CHAR /* Latin-2 to CP852 */
-#ifdef CK_ANSIC
-xl252(CHAR c)
-#else
-xl252(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll252 */
- return(yl252[c]);
-}
-
-CHAR /* Latin-2 to Mazovia */
-#ifdef CK_ANSIC
-xl2mz(CHAR c)
-#else
-xl2mz(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll2mz */
- return(yl2mz[c]);
-}
-
-CHAR /* Latin-1 to Mazovia */
-#ifdef CK_ANSIC
-xl1mz(CHAR c)
-#else
-xl1mz(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll1mz */
- return(yl2mz[yl1l2[c]]);
-}
-
-CHAR /* Mazovia to Latin-1 */
-#ifdef CK_ANSIC
-xmzl1(CHAR c)
-#else
-xmzl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xmzl1 */
- return(yl2l1[ymzl2[c]]);
-}
-
-CHAR /* Mazovia to Latin-9 */
-#ifdef CK_ANSIC
-xmzl9(CHAR c)
-#else
-xmzl9(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xmzl9 */
- return(xl2l9(ymzl2[c]));
-}
-
-CHAR /* CP852 to Latin-2 */
-#ifdef CK_ANSIC
-x52l2(CHAR c)
-#else
-x52l2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x52l2 */
- return(y52l2[c]);
-}
-
-CHAR /* Mazovia to Latin-2 */
-#ifdef CK_ANSIC
-xmzl2(CHAR c)
-#else
-xmzl2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xmzl2 */
- return(ymzl2[c]);
-}
-
-CHAR /* Latin-2 to CP1250 */
-#ifdef CK_ANSIC
-xl21250(CHAR c)
-#else
-xl21250(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll21250 */
- return(yl21250[c]);
-}
-
-CHAR /* CP1250 to Latin-2 */
-#ifdef CK_ANSIC
-x1250l2(CHAR c)
-#else
-x1250l2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x1250l2 */
- return(y1250l2[c]);
-}
-
-CHAR /* CP852 to ASCII */
-#ifdef CK_ANSIC
-x52as(CHAR c)
-#else
-x52as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl52as */
- return(yl2as[y52l2[c]]); /* CP852 -> Latin-2 -> ASCII */
-}
-
-CHAR /* CP1250 to ASCII */
-#ifdef CK_ANSIC
-x1250as(CHAR c)
-#else
-x1250as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1250as */
- return(yl2as[y1250l2[c]]); /* CP81250 -> Latin-2 -> ASCII */
-}
-
-
-CHAR /* CP852 to Latin-1 */
-#ifdef CK_ANSIC
-x52l1(CHAR c)
-#else
-x52l1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl52l1 */
- return(yl2l1[y52l2[c]]); /* CP852 -> Latin-2 -> Latin-1 */
-}
-
-CHAR /* CP1250 to Latin-1 */
-#ifdef CK_ANSIC
-x1250l1(CHAR c)
-#else
-x1250l1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1250l1 */
- return(yl2l1[y1250l2[c]]); /* CP1250 -> Latin-2 -> Latin-1 */
-}
-
-CHAR /* CP1250 to Latin-9 */
-#ifdef CK_ANSIC
-x1250l9(CHAR c)
-#else
-x1250l9(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x1250l9 */
- if (c == (CHAR)128) /* Euro */
- return((CHAR)164);
- else
- return(xl2l9(y1250l2[c])); /* CP1250 -> Latin-2 -> Latin-9 */
-}
-
-CHAR /* Latin-1 to CP852 */
-#ifdef CK_ANSIC
-xl152(CHAR c)
-#else
-xl152(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll152 */
- return(yl252[yl1l2[c]]); /* Latin-1 -> Latin-2 -> CP852 */
-}
-
-CHAR /* Latin-1 to CP1250 */
-#ifdef CK_ANSIC
-xl11250(CHAR c)
-#else
-xl11250(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll11250 */
- return(yl21250[yl1l2[c]]); /* Latin-1 -> Latin-2 -> CP1250 */
-}
-
-CHAR /* Latin-9 to CP1250 */
-#ifdef CK_ANSIC
-xl91250(CHAR c)
-#else
-xl91250(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll91250 */
- if (c == (CHAR)164) /* Euro */
- return((CHAR)128);
- else
- return(yl21250[xl9l2(c)]); /* Latin-9 -> Latin-2 -> CP1250 */
-}
-
-CHAR /* Latin-9 to Mazovia */
-#ifdef CK_ANSIC
-xl9mz(CHAR c)
-#else
-xl9mz(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll9mz */
- return(yl2mz[xl9l2(c)]); /* Latin-9 -> Latin-2 -> Mazovia */
-}
-
-CHAR /* Latin-9 to Mazovia */
-#ifdef CK_ANSIC
-xmzas(CHAR c)
-#else
-xmzas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xmzas */
- return(yl2as[xmzl2(c)]); /* Mazovia -> Latin-2 -> ASCII */
-}
-
-CHAR /* Latin-2 to NeXT */
-#ifdef CK_ANSIC
-xl2ne(CHAR c)
-#else
-xl2ne(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll2ne */
- switch(c) {
- case 162: return(198); /* Breve */
- case 163: return(232); /* L with stroke */
- case 178: return(206); /* Ogonek */
- case 179: return(248); /* l with stroke */
- case 183: return(207); /* Caron */
- case 189: return(205); /* Double acute */
- case 208: return(144); /* D stroke = Eth */
- case 240: return(230); /* d stroke = eth */
- case 255: return(199); /* Dot above */
- default: return(yl1ne[yl2l1[c]]);
- }
-}
-
-CHAR /* Latin-2 to CP437 */
-#ifdef CK_ANSIC
-xl243(CHAR c)
-#else
-xl243(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll243 */
- return(yl1l2[y43l1[c]]);
-}
-
-CHAR /* Latin-2 to CP850 */
-#ifdef CK_ANSIC
-xl285(CHAR c)
-#else
-xl285(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll285 */
- return(yl1l2[y85l1[c]]);
-}
-
-CHAR /* Latin-2 to Apple */
-#ifdef CK_ANSIC
-xl2aq(CHAR c)
-#else
-xl2aq(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl2aq */
- return(yl1aq[yl2l1[c]]); /* Could do more... */
-}
-
-CHAR /* Latin-2 to DGI */
-#ifdef CK_ANSIC
-xl2dg(CHAR c)
-#else
-xl2dg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll2dg */
- return(ydgl1[yl1l2[c]]);
-}
-
-CHAR /* Latin-2 to Short KOI */
-#ifdef CK_ANSIC
-xl2sk(CHAR c)
-#else
-xl2sk(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll2sk */
- return(islower(c) ? toupper(c) : c);
-}
-
-CHAR /* NeXT to Latin-2 */
-#ifdef CK_ANSIC
-xnel2(CHAR c)
-#else
-xnel2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xnel2 */
- switch (c) {
- case 144: return(208); /* D stroke = Eth */
- case 198: return(162); /* Breve */
- case 199: return(255); /* Dot above */
- case 205: return(189); /* Double acute */
- case 206: return(178); /* Ogonek */
- case 207: return(183); /* Caron */
- case 230: return(240); /* d stroke = eth */
- case 232: return(163); /* L with stroke */
- case 248: return(179); /* l with stroke */
- default: return(yl1l2[ynel1[c]]); /* Others, go thru Latin-1 */
- }
-}
-
-CHAR /* CP437 to Latin-2 */
-#ifdef CK_ANSIC
-x43l2(CHAR c)
-#else
-x43l2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl43l2 */
- return(yl1l2[y43l1[c]]);
-}
-
-CHAR /* CP850 to Latin-2 */
-#ifdef CK_ANSIC
-x85l2(CHAR c)
-#else
-x85l2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl85l2 */
- return(yl1l2[y85l1[c]]);
-}
-
-CHAR /* Apple to Latin-2 */
-#ifdef CK_ANSIC
-xaql2(CHAR c)
-#else
-xaql2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlaql2 */
- switch (c) {
- case 249: return(162); /* Breve accent */
- case 250: return(255); /* Dot accent */
- case 253: return(189); /* Double acute */
- default: return(yl1l2[yaql1[c]]);
- }
-}
-
-CHAR /* DGI to Latin-2 */
-#ifdef CK_ANSIC
-xdgl2(CHAR c)
-#else
-xdgl2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xldgl2 */
- return(yl1l2[ydgl1[c]]); /* (for now) */
-}
-
-CHAR /* Short KOI to Latin-2 */
-#ifdef CK_ANSIC
-xskl2(CHAR c)
-#else
-xskl2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlskl2 */
- return(islower(c) ? toupper(c) : c);
-}
-
-CHAR /* Latin-2 to German */
-#ifdef CK_ANSIC
-xl2ge(CHAR c)
-#else
-xl2ge(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll2ge */
- switch(c) {
- case 167: return(64); /* Paragraph sign */
- case 196: return(91); /* A-diaeresis */
- case 214: return(92); /* O-diaeresis */
- case 220: return(93); /* U-diaeresis */
- case 223: return(126); /* double-s */
- case 228: return(123); /* a-diaeresis */
- case 246: return(124); /* o-diaeresis */
- case 252: return(125); /* u-diaeresis */
- default: return(yl2as[c]); /* Others */
- }
-}
-
-CHAR /* German to Latin-2 */
-#ifdef CK_ANSIC
-xgel2(CHAR c)
-#else
-xgel2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlgel2 */
- if (c & 0x80)
- return(UNK);
- switch(c) {
- case 64: return(167); /* Paragraph sign */
- case 91: return(196); /* A-diaeresis */
- case 92: return(214); /* O-diaeresis */
- case 93: return(220); /* U-diaeresis */
- case 123: return(228); /* a-diaeresis */
- case 126: return(223); /* double-s */
- case 124: return(246); /* o-diaeresis */
- case 125: return(252); /* u-diaeresis */
- default: return(c); /* Others */
- }
-}
-
-CHAR /* Latin-2 to Hungarian */
-#ifdef CK_ANSIC
-xl2hu(CHAR c)
-#else
-xl2hu(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xll2hu */
- switch(c) {
- case 164: return(36); /* Currency symbol */
- case 189: return(126); /* Double acute accent */
- case 193: return(64); /* A-acute */
- case 201: return(91); /* E-acute */
- case 214: return(92); /* O-diaeresis */
- case 220: return(93); /* U-diaeresis */
- case 225: return(96); /* a-acute */
- case 233: return(123); /* e-acute */
- case 246: return(124); /* o-diaeresis */
- case 252: return(125); /* u-diaeresis */
- default: return(yl2as[c]); /* Others */
- }
-}
-
-CHAR /* Hungarian to Latin-2 */
-#ifdef CK_ANSIC
-xhul2(CHAR c)
-#else
-xhul2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlhul2 */
- if (c & 0x80)
- return(UNK);
- switch(c) {
- case 36: return(164); /* Currency symbol */
- case 64: return(193); /* A-acute */
- case 91: return(201); /* E-acute */
- case 92: return(214); /* O-diaeresis */
- case 93: return(220); /* U-diaeresis */
- case 96: return(225); /* a-acute */
- case 123: return(233); /* e-acute */
- case 124: return(246); /* o-diaeresis */
- case 125: return(252); /* u-diaeresis */
- case 126: return(189); /* Double acute accent */
- default: return(c); /* Others */
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xr8l2(CHAR c)
-#else
-xr8l2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xr8l2 */ /* Hewlett Packard Roman8 to Latin-2 */
- switch (c) {
- case 235: return(169); /* S caron */
- case 236: return(185); /* s caron */
- default: return(yl1l2[yr8l1[c]]);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl2r8(CHAR c)
-#else
-xl2r8(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl2r8 */ /* Latin-2 to Hewlett Packard Roman8 Character Set */
- switch (c) {
- case 169: return(235); /* S caron */
- case 185: return(236); /* s caron */
- default: return(yr8l1[yl1l2[c]]);
- }
-}
-
-#else /* NOLATIN2 */
-
-#define xl1mz NULL
-#define xmzl1 NULL
-#define xl2mz NULL
-#define xmzl2 NULL
-#define xl9mz NULL
-#define xmzl9 NULL
-#define xmzas NULL
-
-#define xl11250 NULL
-#define xl21250 NULL
-#define xl91250 NULL
-
-#define x1250as NULL
-#define x1250l1 NULL
-#define x1250l2 NULL
-#define x1250l9 NULL
-
-#define xl2l1 NULL
-#define xl2w1 NULL
-#define xl1l2 NULL
-#define xw1l2 NULL
-#define xl2as NULL
-#define xl252 NULL
-#define x52l2 NULL
-#define x52as NULL
-#define x52l1 NULL
-#define xl152 NULL
-#define xl2ne NULL
-#define xl243 NULL
-#define xl285 NULL
-#define xl2aq NULL
-#define xl2dg NULL
-#define xl2sk NULL
-#define xnel2 NULL
-#define x43l2 NULL
-#define x85l2 NULL
-#define xaql2 NULL
-#define xdgl2 NULL
-#define xskl2 NULL
-#define xl2ge NULL
-#define xgel2 NULL
-#define xl2hu NULL
-#define xhul2 NULL
-#define xl2r8 NULL
-#define xr8l2 NULL
-#endif /* LATIN2 */
-
-/* This one can also be used for ELOT 927, Hebrew 7, etc */
-
-CHAR
-#ifdef CK_ANSIC
-xassk(CHAR c)
-#else
-xassk(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xassk */ /* ASCII to Short KOI */
- if (c & 0x80)
- return(UNK);
- return((c > 95) ? (c - 32) : c); /* Fold columns 6-7 to 4-5 */
-}
-
-#ifdef CYRILLIC
-/* Translation functions for Cyrillic character sets */
-
-CHAR /* Latin/Cyrillic to CP866 */
-#ifdef CK_ANSIC
-xlcac(CHAR c)
-#else
-xlcac(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlcac */ /* PC Code Page 866 */
- return(ylcac[c]);
-}
-
-CHAR /* Latin/Cyrillic to */
-#ifdef CK_ANSIC
-xlc55(CHAR c)
-#else
-xlc55(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlc55 */ /* PC Code Page 855 */
- return(ylc55[c]);
-}
-
-CHAR /* Latin/Cyrillic to */
-#ifdef CK_ANSIC
-xlc1251(CHAR c)
-#else
-xlc1251(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlc1251 */ /* PC Code Page 1251 */
- return(ylc1251[c]);
-}
-
-CHAR /* Latin/Cyrillic to... */
-#ifdef CK_ANSIC
-xlcbu(CHAR c)
-#else
-xlcbu(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlcbu */ /* Bulgarian PC Code Page */
- return(ylcbu[c]);
-}
-
-CHAR /* Latin/Cyrillic to Old KOI-8 */
-#ifdef CK_ANSIC
-xlck8(CHAR c)
-#else
-xlck8(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlck8 */
- return(ylck8[c]);
-}
-
-CHAR /* Latin/Cyrillic to KOI8-R */
-#ifdef CK_ANSIC
-xlckr(CHAR c)
-#else
-xlckr(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlckr */
- switch(c) {
- case 0xa1: return(0xb3); /* Io */
- case 0xf1: return(0xa3); /* io */
- default:
- if (c > 0x7f && c < 0xc0)
- return(UNK);
- return(ylck8[c]);
- }
-}
-
-CHAR /* Latin/Cyrillic to KOI8-U */
-#ifdef CK_ANSIC
-xlcku(CHAR c)
-#else
-xlcku(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlcku */
- switch(c) {
- case 0xa1: return(0xb3); /* Io */
- case 0xf1: return(0xa3); /* io */
- case 0xf4: return(0xa4); /* Ukrainian ie */
- case 0xf6: return(0xa6); /* Ukrainian i */
- case 0xf7: return(0xa7); /* Ukrainian yi */
- case 0xf3: return(0xad); /* Ukrainian ghe with upturn */
- case 0xa4: return(0xb4); /* Ukrainian Ie */
- case 0xa6: return(0xb6); /* Ukrainian I */
- case 0xa7: return(0xb7); /* Ukrainian Yi */
- case 0xa3: return(0xbd); /* Ukrainian Ghe with upturn */
- default:
- if (c > 0x7f && c < 0xc0)
- return(UNK);
- return(ylck8[c]);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xlcsk(CHAR c)
-#else
-xlcsk(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlcsk */ /* Latin/Cyrillic to Short KOI */
- return(ylcsk[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xlcas(CHAR c)
-#else
-xlcas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlcas */ /* Latin/Cyrillic to ASCII */
- if (langs[language].id == L_RUSSIAN)
- return(ylcsk[c]);
- else
- return((c > 127) ? '?' : c);
-}
-
-CHAR /* CP866 */
-#ifdef CK_ANSIC
-xaclc(CHAR c)
-#else
-xaclc(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xaclc */ /* to Latin/Cyrillic */
- return(yaclc[c]);
-}
-
-CHAR /* CP855 */
-#ifdef CK_ANSIC
-x55lc(CHAR c)
-#else
-x55lc(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x55lc */ /* to Latin/Cyrillic */
- return(y55lc[c]);
-}
-
-CHAR /* Bulgarian PC Code Page ... */
-#ifdef CK_ANSIC
-xbulc(CHAR c)
-#else
-xbulc(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xbulc */ /* to Latin/Cyrillic */
- return(ybulc[c]);
-}
-
-CHAR /* CP1251 */
-#ifdef CK_ANSIC
-x1251lc(CHAR c)
-#else
-x1251lc(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x1251lc */ /* to Latin/Cyrillic */
- return(y1251lc[c]);
-}
-
-CHAR /* Old KOI-8 to Latin/Cyrillic */
-#ifdef CK_ANSIC
-xk8lc(CHAR c)
-#else
-xk8lc(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xk8lc */
- return(yk8lc[c]);
-}
-
-CHAR /* KOI8-R to Latin/Cyrillic */
-#ifdef CK_ANSIC
-xkrlc(CHAR c)
-#else
-xkrlc(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xkrlc */
- if (c == 0xb3) return(0xa1);
- else if (c == 0xa3) return(0xf1);
- else if (c > 0x7f && c < 0xc0)
- return(UNK);
- return(yk8lc[c]);
-}
-
-CHAR /* KOI8-U to Latin/Cyrillic */
-#ifdef CK_ANSIC
-xkulc(CHAR c)
-#else
-xkulc(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xkulc */
- switch (c) {
- case 0xb3: return(0xa1); /* Io */
- case 0xa3: return(0xf1); /* io */
- case 0xa4: return(0xf4); /* Ukrainian ie */
- case 0xa6: return(0xf6); /* Ukrainian i */
- case 0xa7: return(0xf7); /* Ukrainian yi */
- case 0xad: return(0xf3); /* Ukrainian ghe with upturn */
- case 0xb4: return(0xa4); /* Ukrainian Ie */
- case 0xb6: return(0xa6); /* Ukrainian I */
- case 0xb7: return(0xa7); /* Ukrainian Yi */
- case 0xbd: return(0xa3); /* Ukrainian Ghe with upturn */
- /* Note substitution of Gje for Ghe-Upturn, which is not in 8859-5 */
- default:
- if (c > 0x7f && c < 0xc0)
- return(UNK);
- return(yk8lc[c]);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xskcy(CHAR c)
-#else
-xskcy(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xskcy */ /* Short KOI to Latin/Cyrillic */
- return(yskcy[c & 0x7f]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xascy(CHAR c)
-#else
-xascy(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xascy */ /* ASCII to Latin/Cyrillic */
- if (langs[language].id == L_RUSSIAN) { /* If LANGUAGE == RUSSIAN */
- return(yskcy[c & 0x7f]); /* treat ASCII as Short KOI */
- } else return((c > 127) ? '?' : c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xacas(CHAR c)
-#else
-xacas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xacas */ /* CP866 to ASCII */
- if (langs[language].id == L_RUSSIAN) {
- c = yaclc[c]; /* First to Latin/Cyrillic */
- return(ylcsk[c]); /* Then to Short KOI */
- } else return((c > 127) ? '?' : c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-x55as(CHAR c)
-#else
-x55as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x55as */ /* CP855 to ASCII */
- if (langs[language].id == L_RUSSIAN) {
- c = y55lc[c]; /* First to Latin/Cyrillic */
- return(ylcsk[c]); /* Then to Short KOI */
- } else return((c > 127) ? '?' : c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-x1251as(CHAR c)
-#else
-x1251as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x1251as */ /* CP81251 to ASCII */
- if (langs[language].id == L_RUSSIAN) {
- c = y1251lc[c]; /* First to Latin/Cyrillic */
- return(ylcsk[c]); /* Then to Short KOI */
- } else return((c > 127) ? '?' : c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xskas(CHAR c)
-#else
-xskas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xskas */ /* Short KOI to ASCII */
- return((c > 95) ? '?' : c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xk8as(CHAR c)
-#else
-xk8as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xk8as */ /* Old KOI-8 Cyrillic to ASCII */
- if (langs[language].id == L_RUSSIAN) {
- c = yk8lc[c]; /* First to Latin/Cyrillic */
- return(ylcsk[c]); /* Then to Short KOI */
- } else return((c > 127) ? '?' : c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1sk(CHAR c)
-#else
-xl1sk(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1sk */ /* Latin-1 to Short KOI */
- c = zl1as(c); /* Convert to ASCII */
- return(c = xassk(c)); /* Convert ASCII to Short KOI */
-}
-
-CHAR
-#ifdef CK_ANSIC
-xw1lc(CHAR c)
-#else
-xw1lc(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xw1lc */ /* CP1252 to Latin/Cyrillic */
- return((c < 160) ? xw1as(c) : zl1as(c));
-}
-
-CHAR
-#ifdef CK_ANSIC
-xaslc(CHAR c)
-#else
-xaslc(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xaslc */ /* ASCII to Latin/Cyrillic */
- if (langs[language].id == L_RUSSIAN)
- return(yskcy[c & 0x7f]);
- else return(c & 0x7f);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xasac(CHAR c)
-#else
-xasac(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xasac */ /* ASCII to CP866 */
- if (c & 0x80)
- return(UNK);
- if (langs[language].id == L_RUSSIAN) { /* Use Short KOI */
- c = xskcy(c); /* Translate to Latin/Cyrillic */
- return(ylcac[c]); /* Then to CP866 */
- } else return(c & 0x7f);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xas55(CHAR c)
-#else
-xas55(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xas55 */ /* ASCII to CP855 */
- if (c & 0x80)
- return(UNK);
- if (langs[language].id == L_RUSSIAN) { /* Use Short KOI */
- c = xskcy(c); /* Translate to Latin/Cyrillic */
- return(ylc55[c]); /* Then to CP866 */
- } else return(c & 0x7f);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xas1251(CHAR c)
-#else
-xas1251(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xas1251 */ /* ASCII to CP81251 */
- if (c & 0x80)
- return(UNK);
- if (langs[language].id == L_RUSSIAN) { /* Use Short KOI */
- c = xskcy(c); /* Translate to Latin/Cyrillic */
- return(ylc1251[c]); /* Then to CP866 */
- } else return(c & 0x7f);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xask8(CHAR c)
-#else
-xask8(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xask8 */ /* ASCII to KOI-8 */
- if (c & 0x80)
- return(UNK);
- if (langs[language].id == L_RUSSIAN) { /* Use Short KOI */
- c = xskcy(c); /* Translate to Latin/Cyrillic */
- return(ylck8[c]); /* Then to KOI-8 */
- } else return(c & 0x7f);
-}
-#else /* No Cyrillic */
-#define xacas NULL
-#define x55as NULL
-#define x1251as NULL
-#define xaclc NULL
-#define x55lc NULL
-#define x1251lc NULL
-#define xasac NULL
-#define xas55 NULL
-#define xas1251 NULL
-#define xascy NULL
-#define xask8 NULL
-#define xaslc NULL
-#define xassk NULL
-#define xk8as NULL
-#define xk8lc NULL
-#define xkrlc NULL
-#define xkulc NULL
-#define xl1sk NULL
-#define xw1lc NULL
-#define xlcac NULL
-#define xlc55 NULL
-#define xlc1251 NULL
-#define xlcas NULL
-#define xlck8 NULL
-#define xlckr NULL
-#define xlcku NULL
-#define xlch7 NULL
-#define xlcsk NULL
-#define xskas NULL
-#define xskcy NULL
-#define xbulc NULL
-#define xlcbu NULL
-#endif /* CYRILLIC */
-
-/* Translation functions for Hebrew character sets */
-
-#ifdef HEBREW
-
-CHAR
-#ifdef CK_ANSIC
-xash7(CHAR c)
-#else
-xash7(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xash7 */ /* ASCII to Hebrew-7 */
- if (c & 0x80)
- return(UNK);
- if (c == 96) return('?');
- if (c > 96 && c < 123) return(c - 32);
- else return(c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1h7(CHAR c)
-#else
-xl1h7(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1h7 */ /* Latin-1 to Hebrew-7 */
- return(xash7(xl1as(c)));
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1lh(CHAR c)
-#else
-xl1lh(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1lh */ /* Latin-1 to Latin/Hebrew */
- switch(c) {
- case 170: return('a'); /* Feminine ordinal */
- case 186: return('o'); /* Masculine ordinal */
- case 215: return(170); /* Times */
- case 247: return(186); /* Divide */
- default: return( (c > 190) ? xl1as(c) : c );
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xw1lh(CHAR c)
-#else
-xw1lh(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xw1lh */ /* CP1252 to Latin/Hebrew */
- switch(c) {
- case 170: return('a'); /* Feminine ordinal */
- case 186: return('o'); /* Masculine ordinal */
- case 215: return(170); /* Times */
- case 247: return(186); /* Divide */
- default:
- if (c < 160)
- return(xw1as(c));
- else
- return((c > 190) ? xl1as(c) : c);
- }
-}
-
-#ifdef LATIN2
-CHAR
-#ifdef CK_ANSIC
-xl2h7(CHAR c)
-#else
-xl2h7(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl2h7 */ /* Latin-2 to Hebrew-7 */
- return(xash7(xl2as(c)));
-}
-#else
-#define xl2h7 NULL
-#endif /* LATIN2 */
-
-#ifndef NOCYRIL
-CHAR
-#ifdef CK_ANSIC
-xlch7(CHAR c)
-#else
-xlch7(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlch7 */ /* Latin/Cyrillic to Hebrew-7 */
- return(xash7(xlcas(c)));
-}
-#endif /* NOCYRIL */
-
-CHAR
-#ifdef CK_ANSIC
-xlhas(CHAR c)
-#else
-xlhas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlhas */ /* Latin/Hebrew to ASCII */
- return( (c > 127) ? '?' : c );
-}
-
-CHAR
-#ifdef CK_ANSIC
-xlhl1(CHAR c)
-#else
-xlhl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlhl1 */ /* Latin/Hebrew to Latin-1 */
- switch (c) {
- case 170: return(215);
- case 186: return(247);
- default: return( (c > 190) ? '?' : c );
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xlhw1(CHAR c)
-#else
-xlhw1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlhw1 */ /* Latin/Hebrew to CP1252 */
- if (c > 127 && c < 160)
- return('?');
- switch (c) {
- case 170: return(215);
- case 186: return(247);
- default: return( (c > 190) ? '?' : c );
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xlh62(CHAR c)
-#else
-xlh62(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlh62 */ /* Latin/Hebrew to CP862 */
- return(ylh62[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl162(CHAR c)
-#else
-xl162(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl162 */ /* Latin-1 to CP862 */
- return(xlh62(xl1lh(c))); /* Via Latin/Hebrew */
-}
-
-CHAR
-#ifdef CK_ANSIC
-xlhh7(CHAR c)
-#else
-xlhh7(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlhh7 */ /* Latin/Hebrew to Hebrew-7 */
- return(ylhh7[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xh7as(CHAR c)
-#else
-xh7as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xh7as */ /* Hebrew-7 to ASCII */
- if (c & 0x80)
- return(UNK);
- return( (c > 95 && c < 123) ? '?' : c );
-}
-
-CHAR
-#ifdef CK_ANSIC
-x62lh(CHAR c)
-#else
-x62lh(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x62lh */ /* CP862 to Latin/Hebrew */
- return(y62lh[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-x62as(CHAR c)
-#else
-x62as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x62as */ /* CP862 to ASCII */
- return( xlhas(x62lh(c)) );
-}
-
-CHAR
-#ifdef CK_ANSIC
-x62l1(CHAR c)
-#else
-x62l1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x62l1 */ /* CP862 to Latin-1 */
- return( xlhl1(x62lh(c)) );
-}
-
-CHAR
-#ifdef CK_ANSIC
-xh7lh(CHAR c)
-#else
-xh7lh(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xh7lh */ /* Hebrew-7 to Latin/Hebrew */
- if (c & 0x80)
- return(UNK);
- return(yh7lh[c]);
-}
-
-#else /* No Hebrew */
-
-#define xash7 NULL
-#define xl1h7 NULL
-#define xl2h7 NULL
-#define xlch7 NULL
-#define xl1lh NULL
-#define xw1lh NULL
-#define xlhas NULL
-#define xlhl1 NULL
-#define xlhw1 NULL
-#define xl162 NULL
-#define xlhh7 NULL
-#define xlh62 NULL
-#define xh7as NULL
-#define x62as NULL
-#define x62l1 NULL
-#define xh7lh NULL
-#define x62lh NULL
-
-#endif /* HEBREW */
-
-/* Translation functions for Greek character sets */
-
-#ifdef GREEK
-
-CHAR
-#ifdef CK_ANSIC
-xaseg(CHAR c)
-#else
-xaseg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xaseg */ /* ASCII to ELOT 927 */
- if (c & 0x80)
- return(UNK);
- if (c > 96 && c < 123) return(c - 32);
- else return(c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1eg(CHAR c)
-#else
-xl1eg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1ge */ /* Latin-1 to ELOT 927 */
- return(xaseg(xl1as(c)));
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl2lg(CHAR c)
-#else
-xl2lg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl2lg */ /* Latin-1 to Latin/Greek */
- if (c < 160) return(c);
- else if (c == 160 || c == 168 || c == 173 || c == 174)
- return(c);
- else return('?');
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl1lg(CHAR c)
-#else
-xl1lg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl1lg */ /* Latin-1 to Latin/Greek */
- if (c < 160) return(c);
- switch(c) {
- case 160: /* Themselves */
- case 164:
- case 166:
- case 167:
- case 168:
- case 169:
- case 171:
- case 172:
- case 173:
- case 176:
- case 177:
- case 178:
- case 179:
- case 180:
- case 187:
- case 189:
- return(c);
- case 181: /* Lowercase mu */
- return(236);
- default:
- return(UNK);
- }
-}
-
-CHAR
-#ifdef CK_ANSIC
-xw1lg(CHAR c)
-#else
-xw1lg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xw1lg */ /* CP1252 to Latin/Greek */
- return((c < 160) ? xw1as(c) : xl1lg(c));
-}
-
-
-#ifdef LATIN2
-CHAR
-#ifdef CK_ANSIC
-xl2eg(CHAR c)
-#else
-xl2eg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl2eg */ /* Latin-2 to ELOT 927 */
- return(xaseg(xl2as(c)));
-}
-#else
-#define xl2eg NULL
-#endif /* LATIN2 */
-
-#ifndef NOCYRIL
-CHAR
-#ifdef CK_ANSIC
-xlceg(CHAR c)
-#else
-xlceg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlceg */ /* Latin/Cyrillic to ELOT 927 */
- return(xaseg(xlcas(c)));
-}
-#endif /* NOCYRIL */
-
-CHAR
-#ifdef CK_ANSIC
-xlgas(CHAR c)
-#else
-xlgas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlgas */ /* Latin/Greek to ASCII */
- return( (c > 127) ? '?' : c );
-}
-
-CHAR
-#ifdef CK_ANSIC
-xlgl1(CHAR c)
-#else
-xlgl1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlgl1 */ /* Latin/Greek to Latin-1 */
- if (c == 236)
- return(181);
- else
- return(xl1lg(c));
-}
-
-CHAR
-#ifdef CK_ANSIC
-xlgw1(CHAR c)
-#else
-xlgw1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlgw1 */ /* Latin/Greek to Latin-1 */
- if (c > 127 && c < 160)
- return('?');
- return(xlgl1(c));
-}
-
-CHAR
-#ifdef CK_ANSIC
-xlg69(CHAR c)
-#else
-xlg69(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlg69 */ /* Latin/Greek to CP869 */
- return(ylg69[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xl169(CHAR c)
-#else
-xl169(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl169 */ /* Latin-1 to CP869 */
- return(xlg69(xl1lg(c))); /* Via Latin/Greek */
-}
-
-CHAR
-#ifdef CK_ANSIC
-xlgeg(CHAR c)
-#else
-xlgeg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xlgeg */ /* Latin/Greek to ELOT 927 */
- return(ylgeg[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-xegas(CHAR c)
-#else
-xegas(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xegas */ /* ELOT 927 to ASCII */
- if (c & 0x80)
- return(UNK);
- return( (c > 96 && c < 123) ? '?' : c );
-}
-
-CHAR
-#ifdef CK_ANSIC
-x69lg(CHAR c)
-#else
-x69lg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x69lg */ /* CP869 to Latin/Greek */
- return(y69lg[c]);
-}
-
-CHAR
-#ifdef CK_ANSIC
-x69as(CHAR c)
-#else
-x69as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x69as */ /* CP869 to ASCII */
- return( xlgas(x69lg(c)) );
-}
-
-CHAR
-#ifdef CK_ANSIC
-x69l1(CHAR c)
-#else
-x69l1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x69l1 */ /* CP869 to Latin-1 */
- return( xlgl1(x69lg(c)) );
-}
-
-CHAR
-#ifdef CK_ANSIC
-xeglg(CHAR c)
-#else
-xeglg(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xeglg */ /* ELOT 927 to Latin/Greek */
- return(yeglg[c]);
-}
-
-#else /* No Greek */
-
-#define x69as NULL
-#define x69l1 NULL
-#define x69lg NULL
-#define xaseg NULL
-#define xegas NULL
-#define xeglg NULL
-#define xl169 NULL
-#define xl1eg NULL
-#define xl1lg NULL
-#define xw1lg NULL
-#define xl2ge NULL
-#define xl2lg NULL
-#define xlcge NULL
-#define xlg69 NULL
-#define xlgas NULL
-#define xlgeg NULL
-#define xlgge NULL
-#define xlgl1 NULL
-#define xlgw1 NULL
-
-#endif /* GREEK */
-
-
-/* Translation functions for Japanese Kanji character sets */
-
-#ifdef KANJI
-/*
- Translate Kanji Transfer Character Set (EUC) to local file character set,
- contributed by Dr. Hirofumi Fujii, Japan High Energy Research Laboratory
- (KEK), Tokyo, Japan.
-
- a is a byte to be translated, which may be a single-byte character,
- the Katakana prefix, the first byte of a two-byte Kanji character, or the
- second byte of 2-byte Kanji character.
-
- fn is the output function.
-
- Returns 0 on success, -1 on failure.
-*/
-
-_PROTOTYP(static int jpnxas, (int, int[]) );
-_PROTOTYP(static int jpnxkt, (int, int[]) );
-_PROTOTYP(static int jpnxkn, (int[], int[]) );
-
-static int jpncnt; /* Byte count for Japanese */
-static int jpnlst; /* Last status (for JIS7) */
-
-static int
-jpnxas(a, obuf) int a; int obuf[]; { /* Translate ASCII to local file code */
- int r;
-
- r = 0;
- if (fcharset == FC_JIS7) {
- switch (jpnlst) {
- case 1:
- obuf[0] = 0x0f;
- obuf[1] = a;
- r = 2;
- break;
- case 2:
- obuf[0] = 0x1b;
- obuf[1] = 0x28;
- obuf[2] = 0x4a;
- obuf[3] = a;
- r = 4;
- break;
- default:
- obuf[0] = a;
- r = 1;
- break;
- }
- } else {
- obuf[0] = a;
- r = 1;
- }
- return(r);
-}
-
-static int
-jpnxkt(a, obuf) int a; int obuf[]; {
-/* Translate JIS X 201 Katakana to local code */
-
- int r;
-
- r = 0;
- if (fcharset == FC_JIS7) {
- switch (jpnlst) {
- case 2: /* from Kanji */
- obuf[r++] = 0x1b;
- obuf[r++] = 0x28;
- obuf[r++] = 0x4a;
- case 0: /* from Roman */
- obuf[r++] = 0x0e;
- default:
- obuf[r++] = (a & 0x7f);
- break;
- }
- } else {
- if (fcharset == FC_JEUC)
- obuf[r++] = 0x8e;
- obuf[r++] = (a | 0x80);
- }
- return(r);
-}
-
-static int
-jpnxkn(ibuf, obuf) int ibuf[], obuf[]; {
- /* Translate JIS X 0208 Kanji to local code */
- int c1, c2;
- int r;
-
- c1 = ibuf[0] & 0x7f;
- c2 = ibuf[1] & 0x7f;
-
- if (fcharset == FC_SHJIS) {
- if (c1 & 1)
- c2 += 0x1f;
- else
- c2 += 0x7d;
-
- if (c2 >= 0x7f) c2++;
-
- c1 = ((c1 - 0x21) >> 1) + 0x81;
- if (c1 > 0x9f) c1 += 0x40;
-
- obuf[0] = c1;
- obuf[1] = c2;
- r = 2;
- } else if (fcharset == FC_JIS7) {
- r = 0;
- switch (jpnlst) {
- case 1:
- obuf[r++] = 0x0f; /* From Katakana */
- case 0:
- obuf[r++] = 0x1b;
- obuf[r++] = 0x24;
- obuf[r++] = 0x42;
- default:
- obuf[r++] = c1;
- obuf[r++] = c2;
- break;
- }
- } else {
- obuf[0] = (c1 | 0x80);
- obuf[1] = (c2 | 0x80);
- r = 2;
- }
- return(r);
-}
-
-int
-xkanjf() {
-/* Initialize parameters for xkanji */
-/* This function should be called when F/X-packet is received */
- jpncnt = jpnlst = 0;
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-xkanjz(int (*fn)(char))
-#else
-xkanjz(fn) int (*fn)();
-#endif /* CK_ANSIC */
-{ /* xkanjz */
-/*
- Terminate xkanji
- This function must be called when Z-packet is received
- (before closing the file).
-*/
- static int obuf[6];
- int r, i, c;
-
- if (fcharset == FC_JIS7) {
- c = 'A'; /* Dummy Roman character */
- r = jpnxas(c, obuf) - 1; /* -1 removes Dummy character */
- if (r > 0) {
- for (i = 0; i < r; i++)
- if (((*fn)((char) obuf[i])) < 0)
- return(-1);
- }
- }
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-xkanji(int a, int (*fn)(char))
-#else
-xkanji(a, fn) int a; int (*fn)();
-#endif /* CK_ANSIC */
-{ /* xkanji */
- static int xbuf[2];
- static int obuf[8];
-
- int i, r;
- int c7;
- int state=0;
-
- r = 0;
- if (jpncnt == 0) {
- /* 1st byte */
- if ((a & 0x80) == 0) {
- /* 8th bit is 0, i.e., single-byte code */
- r = jpnxas(a, obuf);
- state = 0;
- } else {
- /* 8th bit is 1, check the range */
- c7 = a & 0x7f;
- if (((c7 > 0x20) && (c7 < 0x7f)) || (c7 == 0x0e)) {
- /* double byte code */
- xbuf[jpncnt++] = a;
- } else {
- /* single byte code */
- r = jpnxas(a, obuf);
- state = 0;
- }
- }
- } else {
- /* not the 1st byte */
- xbuf[jpncnt++] = a;
- if (xbuf[0] == 0x8e) {
- r = jpnxkt(xbuf[1], obuf);
- state = 1;
- } else {
- r = jpnxkn(xbuf, obuf);
- state = 2;
- }
- }
- if (r > 0) {
- for (i = 0; i < r; i++ )
- if (((*fn)((char) obuf[i])) < 0)
- return(-1);
- jpnlst = state;
- jpncnt = 0;
- }
- return(0);
-}
-
-/*
- Function for translating from Japanese file character set
- to Japanese EUC transfer character set.
- Returns a pointer to a string containing 0, 1, or 2 bytes.
-*/
-
-/* zkanji */
-static int jpnstz; /* status for JIS-7 */
-static int jpnpnd; /* number of pending bytes */
-static int jpnpnt; /* pending buffer index */
-static int jpnpbf[8]; /* pending buffer */
-
-/* There is some duplication here between the old and new JIS-7 parsers */
-/* to be cleaned up later... */
-
-VOID
-j7init() { /* Initialize JIS-7 parser */
- jpnstz = 0;
- jpnpnd = 0;
- jpnpnt = 0;
-}
-
-int
-getj7() { /* Reads JIS-7 returns next EUC byte */
- int x;
-
- if (jpnpnd > 0) { /* If something is pending */
- x = (unsigned) jpnpbf[jpnpnt++]; /* Get it */
- jpnpnd--;
- if (jpnpnd < 0) jpnpnd = 0;
- return((unsigned)x);
- }
- jpnpnt = 0;
-
- if ((x = zminchar()) < 0) return(x);
- while (jpnpnd == 0) { /* While something is pending... */
- if ((x > 0x20) && (x < 0x7f)) { /* 7-bit graphic character */
- switch (jpnstz) {
- case 1: /* Katakana */
-#ifdef COMMENT
- /* This can't be right... */
- jpnpbf[jpnpnd++] = 0x80; /* Insert flag (NOT SS2???) */
-#else
- jpnpbf[jpnpnd++] = 0x8e; /* Insert SS2 */
-#endif /* COMMENT */
- jpnpbf[jpnpnd++] = (x | 0x80); /* Insert Kana + 8th bit */
- break;
- case 2: /* Kanji */
- jpnpbf[jpnpnd++] = (x | 0x80); /* Get another byte */
- if ((x = zminchar()) < 0) return(x);
- jpnpbf[jpnpnd++] = (x | 0x80);
- break;
- default: /* ASCII / JIS Roman */
- jpnpbf[jpnpnd++] = x;
- break;
- }
- } else if (x == 0x0e) { /* ^N = SO */
- jpnstz = 1; /* Katakana */
- if ((x = zminchar()) < 0) return(x);
- } else if (x == 0x0f) { /* ^O = SI */
- jpnstz = 0; /* ASCII / JIS Roman */
- if ((x = zminchar()) < 0) return(x);
- } else if (x == 0x1b) { /* Escape */
- jpnpbf[jpnpnd++] = x; /* Save in buffer */
- if ((x = zminchar()) < 0) return(x);
- jpnpbf[jpnpnd++] = x; /* Save in buffer */
- if (x == '$') { /* <ESC>$ */
- if ((x = zminchar()) < 0) return(x);
- jpnpbf[jpnpnd++] = x;
- if ((x == '@') || (x == 'B')) { /* Kanji */
- jpnstz = 2;
- jpnpnt = jpnpnd = 0;
- if ((x = zminchar()) < 0) return(x);
- }
- } else if (x == '(') { /* <ESC>( == 94-byte single-byte set */
- if ((x = zminchar()) < 0) return(x);
- jpnpbf[jpnpnd++] = x;
- if ((x == 'B') || (x == 'J')) { /* ASCII or JIS Roman */
- jpnstz = 0; /* Set state */
- jpnpnt = jpnpnd = 0; /* Reset pointers */
- if ((x = zminchar()) < 0) return(x);
- }
- } else if (x == 0x1b) { /* <ESC><ESC> */
- jpnpnt = jpnpnd = 0; /* Reset pointers, stay in state */
- if ((x = zminchar()) < 0) return(x);
- }
- } else { /* Not <ESC> - just save it */
- jpnpbf[jpnpnd++] = x;
- }
- }
- jpnpnt = 0;
- x = (unsigned)jpnpbf[jpnpnt++];
- jpnpnd--;
- return((unsigned)x);
-}
-
-USHORT
-#ifdef CK_ANSIC
-eu_to_sj(USHORT eu) /* EUC-JP to Shift-JIS */
-#else
-eu_to_sj(eu) USHORT eu;
-#endif /* CK_ANSIC */
-{
- int c1, c2;
- union ck_short jcode,scode;
-
- jcode.x_short = eu;
- c1 = (jcode.x_char[byteorder] & 0x7f);
- c2 = (jcode.x_char[1-byteorder] & 0x7f);
-
- if (c1 & 1)
- c2 += 0x1f;
- else
- c2 += 0x7d;
- if (c2 >= 0x7f)
- c2++;
- c1 = ((c1 - 0x21) >> 1) + 0x81;
- if (c1 > 0x9f)
- c1 += 0x40;
-
- scode.x_char[byteorder] = c1;
- scode.x_char[1-byteorder] = c2;
- return(scode.x_short);
-}
-
-
-USHORT
-#ifdef CK_ANSIC
-sj_to_eu(USHORT sj) /* Shift-JIS to EUC-JP */
-#else
-sj_to_eu(sj) USHORT sj;
-#endif /* CK_ANSIC */
-{
- union ck_short jcode, scode;
- int c0, c1;
-
- scode.x_short = sj;
- c0 = scode.x_char[byteorder]; /* Left (hi order) byte */
- c1 = scode.x_char[1-byteorder]; /* Right (lo order) byte */
-
- if (((c0 >= 0x81) && (c0 <= 0x9f)) || /* High order byte has 8th bit set */
- ((c0 >= 0xe0) && (c0 <= 0xfc))) { /* Kanji */
- if (c0 <= 0x9f) /* Two bytes in */
- c0 -= 0x71; /* Do the shifting... */
- else
- c0 -= 0xb1;
- c0 = c0 * 2 + 1;
- if (c1 > 0x7f) c1 -= 1;
- if (c1 >= 0x9e) {
- c1 -= 0x7d;
- c0 += 1;
- } else {
- c1 -= 0x1f;
- }
- jcode.x_char[byteorder] = (c0 | 0x80); /* Two bytes out */
- jcode.x_char[1-byteorder] = (c1 | 0x80);
-
- } else if (c0 == 0) { /* Single byte */
- if (c1 >= 0xa1 && c1 <= 0xdf) { /* Katakana */
- jcode.x_char[byteorder] = 0x8e; /* SS2 */
- jcode.x_char[1-byteorder] = c1; /* Kana code */
- } else { /* ASCII or C0 */
- jcode.x_short = c1;
- }
- } else { /* Something bad */
- debug(F001,"sj_to_eu bad sj","",sj);
- jcode.x_short = 0xffff;
- }
- return(jcode.x_short);
-}
-
-int
-zkanjf() { /* Initialize */
- jpnstz = jpnpnd = jpnpnt = 0;
- return(0);
-}
-
-int
-zkanjz() {
- return(0);
-}
-
-int
-#ifdef CK_ANSIC
-zkanji(int (*fn)(void))
-#else
-zkanji(fn) int (*fn)();
-#endif /* CK_ANSIC */
-{ /* zkanji */
- /* Read Japanese local code and translate to Japanese EUC */
- int a;
- int sc[3];
-
- /* No pending characters */
- if (fcharset == FC_SHJIS) { /* Translating from Shift-JIS */
- if (jpnpnd) {
- jpnpnd--;
- return(jpnpbf[jpnpnt++]);
- }
- a = (*fn)();
- jpnpnd = jpnpnt = 0;
- if (((a >= 0x81) && (a <= 0x9f)) ||
- ((a >= 0xe0) && (a <= 0xfc))) { /* 2-byte Kanji code */
- sc[0] = a;
- if ((sc[1] = (*fn)()) < 0) /* Get second byte */
- return(sc[1]);
- if (sc[0] <= 0x9f)
- sc[0] -= 0x71;
- else
- sc[0] -= 0xb1;
- sc[0] = sc[0] * 2 + 1;
- if (sc[1] > 0x7f)
- sc[1]--;
- if (sc[1] >= 0x9e) {
- sc[1] -= 0x7d;
- sc[0]++;
- } else {
- sc[1] -= 0x1f;
- }
- a = (sc[0] | 0x80);
- jpnpbf[0] = (sc[1] | 0x80);
- jpnpnd = 1;
- jpnpnt = 0;
- } else if ((a >= 0xa1) && (a <= 0xdf)) { /* Katakana */
- jpnpbf[0] = a;
- jpnpnd = 1;
- jpnpnt = 0;
- a = 0x8e;
- }
- return(a);
- } else if (fcharset == FC_JIS7 ) { /* 7-bit JIS X 0208 */
- if (jpnpnd) {
- a = jpnpbf[jpnpnt++];
- jpnpnd--;
- return(a);
- }
- jpnpnt = 0;
- if ((a = (*fn)()) < 0)
- return(a);
- while (jpnpnd == 0) {
- if ((a > 0x20) && (a < 0x7f)) {
- switch (jpnstz) {
- case 1:
- jpnpbf[jpnpnd++] = 0x80; /* Katakana */
- jpnpbf[jpnpnd++] = (a | 0x80);
- break;
- case 2:
- jpnpbf[jpnpnd++] = (a | 0x80); /* Kanji */
- if ((a = (*fn)()) < 0)
- return(a);
- jpnpbf[jpnpnd++] = (a | 0x80);
- break;
- default:
- jpnpbf[jpnpnd++] = a; /* Single byte */
- break;
- }
- } else if (a == 0x0e) {
- jpnstz = 1;
- if ((a = (*fn)()) < 0)
- return(a);
- } else if (a == 0x0f) {
- jpnstz = 0;
- if ((a = (*fn)()) < 0)
- return(a);
- } else if (a == 0x1b) {
- jpnpbf[jpnpnd++] = a; /* Escape */
- if ((a = (*fn)()) < 0)
- return(a);
- jpnpbf[jpnpnd++] = a;
- if (a == '$') {
- if ((a = (*fn)()) < 0)
- return(a);
- jpnpbf[jpnpnd++] = a;
- if ((a == '@') || (a == 'B')) {
- jpnstz = 2;
- jpnpnt = jpnpnd = 0;
- if ((a = (*fn)()) < 0)
- return(a);
- }
- } else if (a == '(') {
- if ((a = (*fn)()) < 0)
- return(a);
- jpnpbf[jpnpnd++] = a;
- if ((a == 'B') || (a == 'J')) {
- jpnstz = 0;
- jpnpnt = jpnpnd = 0;
- if ((a = (*fn)()) < 0)
- return(a);
- }
- } else if (a == 0x1b) {
- jpnpnt = jpnpnd = 0;
- if ((a = (*fn)()) < 0)
- return(a);
- }
- } else {
- jpnpbf[jpnpnd++] = a;
- }
- }
- jpnpnt = 0;
- a = jpnpbf[jpnpnt++];
- jpnpnd--;
- return(a);
- } else {
- a = (*fn)();
- return(a);
- }
-}
-#endif /* KANJI */
-
-/* Euro functions */
-
-#ifdef LATIN2
-CHAR
-#ifdef CK_ANSIC
-xl2l9(CHAR c)
-#else
-xl2l9(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl2l9 */ /* Latin-2 to Latin-9... */
- switch (c) {
- case 169: return((CHAR)166); /* S caron */
- case 185: return((CHAR)168); /* s caron */
- case 174: return((CHAR)180); /* Z caron */
- case 190: return((CHAR)184); /* z caron */
- default:
- return(yl2l1[c]);
- }
-
-}
-
-_PROTOTYP( CHAR xl258, ( CHAR ) );
-CHAR
-#ifdef CK_ANSIC
-xl258(CHAR c)
-#else
-xl258(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl258 */ /* Latin-2 to CP858... */
- return(c);
-}
-#else
-#define xl2l9 NULL
-#define xl258 NULL
-#endif /* LATIN2 */
-
-CHAR
-#ifdef CK_ANSIC
-zl9as(CHAR c)
-#else
-zl9as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* zl9as */ /* Latin-9 to US ASCII... */
- if (c < (CHAR)0x80) return(c); /* Save a function call */
- switch (c) {
- case 0xa4: return(UNK); /* Euro */
- case 0xa6: return('S'); /* S Caron */
- case 0xa8: return('s'); /* s Caron */
- case 0xb4: return('Z'); /* Z Caron */
- case 0xbc: return('O'); /* OE digraph */
- case 0xbd: return('o'); /* oe digraph */
- case 0xbe: return('Y'); /* Y diaeresis */
- default: return(zl1as(c)); /* The rest is like Latin-1 */
- }
-}
-
-_PROTOTYP( CHAR xl9as, ( CHAR ) );
-CHAR
-#ifdef CK_ANSIC
-xl9as(CHAR c)
-#else
-xl9as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl9as */ /* Latin-9 to US ASCII... */
- if (c < (CHAR)0x80) return(c); /* Save a function call */
- switch (c) {
- case 0xa4: return(UNK); /* Euro */
- case 0xa6: return('S'); /* S Caron */
- case 0xa8: return('s'); /* s Caron */
- case 0xb4: return('Z'); /* Z Caron */
- case 0xb8: return('z'); /* z Caron */
- case 0xbc: return('O'); /* OE digraph */
- case 0xbd: return('o'); /* oe digraph */
- case 0xbe: return('Y'); /* Y diaeresis */
- default: return(xl1as(c)); /* The rest is like Latin-1 */
- }
-}
-
-CHAR /* CP1252 to Latin-9 */
-#ifdef CK_ANSIC
-xw1l9(CHAR c)
-#else
-xw1l9(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xw1l9 */
- switch (c) {
- case 0x80: return(0xa4); /* Euro sign */
- case 0x8a: return(0xa6); /* S caron */
- case 0x8c: return(0xbc); /* OE */
- case 0x8e: return(0xb4); /* Z caron */
- case 0x9a: return(0xa8); /* s caron */
- case 0x9c: return(0xbd); /* oe */
- case 0x9e: return(0xb8); /* z caron */
- case 0x9f: return(0xbe); /* Y diaeresis */
- case 0xa4: /* Currency sign */
- case 0xa6: /* Broken vertical bar */
- case 0xa8: /* Diaeresis */
- case 0xb4: /* Acute accent */
- case 0xb8: /* Cedilla */
- case 0xbc: /* 1/4 */
- case 0xbd: /* 1/2 */
- case 0xbe: return('?'); /* 3/4 */
- default: return((c < 160) ? xw1as(c) : c);
- }
-}
-
-#ifdef LATIN2
-CHAR
-#ifdef CK_ANSIC
-xl9l2(CHAR c)
-#else
-xl9l2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl9l2 */ /* Latin-9 to Latin-2... */
- if (c < (CHAR)0x80) return(c); /* Save a function call */
- switch (c) {
- case 0xa4: return(UNK); /* Euro */
- case 0xa6: return((CHAR)0xa9); /* S Caron */
- case 0xa8: return((CHAR)0xb9); /* s Caron */
- case 0xb4: return((CHAR)0xae); /* Z Caron */
- case 0xb8: return((CHAR)0xaf); /* z Caron */
- case 0xbc: return('O'); /* OE digraph */
- case 0xbd: return('o'); /* oe digraph */
- case 0xbe: return('Y'); /* Y diaeresis */
- default: return(xl1l2(c)); /* The rest is like Latin-1 */
- }
-}
-#else
-#define xl9l2 NULL
-#endif /* LATIN2 */
-
-CHAR
-#ifdef CK_ANSIC
-xl958(CHAR c)
-#else
-xl958(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* xl958 */ /* Latin-9 to CP858... */
- if (c == 0xa4) /* Euro Symbol */
- return((CHAR)0xd5);
- else if (c == 0x9e) /* This was currency symbol */
- return((CHAR)0xcf);
- c = yl185[c];
- return(c);
-}
-
-CHAR
-#ifdef CK_ANSIC
-x58as(CHAR c)
-#else
-x58as(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x58as */ /* CP858 to US ASCII... */
- if (c == 0xd5) /* Euro rather than dotless i */
- return(UNK);
- else
- return(x85as(c)); /* The rest is like CP850 */
-}
-
-CHAR
-#ifdef CK_ANSIC
-x58l1(CHAR c)
-#else
-x58l1(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x58l1 */ /* CP858 to Latin-1... */
- if (c == 0xd5) /* Euro rather than dotless i */
- return((CHAR)0xa4); /* Return currency symbol */
- else if (c == 0xcf) /* This keeps it invertible */
- return((CHAR)0x9e);
- else
- return(x85l1(c));
-}
-
-#ifdef LATIN2
-CHAR
-#ifdef CK_ANSIC
-x58l2(CHAR c)
-#else
-x58l2(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x58l2 */ /* CP858 to Latin-2... */
- if (c == 0xd5) /* Euro rather than dotless i */
- return((CHAR)0xa4); /* Return currency symbol */
- else if (c == 0xcf) /* This keeps it invertible */
- return((CHAR)0x9e); /* (if it ever was...) */
- else /* Otherwise like CP850 */
- return(x85l2(c));
-}
-#else
-#define x58l2 NULL
-#endif /* LATIN2 */
-
-CHAR
-#ifdef CK_ANSIC
-x58l9(CHAR c)
-#else
-x58l9(c) CHAR c;
-#endif /* CK_ANSIC */
-{ /* x58l9 */ /* CP-858 to Latin-9... */
- if (c == 0xd5) /* Euro rather than dotless i */
- return((CHAR)0xa4); /* Return currency symbol */
- else if (c == 0xcf) /* This keeps it invertible */
- return((CHAR)0x9e); /* (if it ever was...) */
- else /* Otherwise like CP850 */
- return(x85l1(c)); /* to Latin-1 */
-}
-
-/* End Euro functions */
-
-
-/* TABLES OF TRANSLATION FUNCTIONS */
-
-/*
- First, the table of translation functions for RECEIVING files. That is,
- *from* the TRANSFER character set *to* the FILE character set, an array of
- pointers to functions. The first index is the TRANSFER CHARACTER-SET
- number, the second index is the FILE CHARACTER-SET number.
-
- These arrays must be fully populated, even if (as is the case with Kanji
- character sets), all the entries are NULL. Otherwise, subscript
- calculations will be wrong and we'll use the wrong functions.
-*/
-
-/* Pointers to byte-for-byte translation functions */
-
-_PROTOTYP( CHAR (*rx), (CHAR) );
-_PROTOTYP( CHAR (*sx), (CHAR) );
-
-#ifdef UNICODE
-_PROTOTYP( int (*xut), (USHORT) ); /* Translation function UCS to TCS */
-_PROTOTYP( int (*xuf), (USHORT) ); /* Translation function UCS to FCS */
-_PROTOTYP( USHORT (*xtu), (CHAR) ); /* Translation function TCS to UCS */
-_PROTOTYP( USHORT (*xfu), (CHAR) ); /* Translation function FCS to UCS */
-#endif /* UNICODE */
-
-#ifdef CK_ANSIC
-CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR) =
-#else
-CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])() =
-#endif /* CK_ANSIC */
-{
- NULL, /* 0,0 transparent to us ascii */
- NULL, /* 0,1 transparent to uk ascii */
- NULL, /* 0,2 transparent to dutch nrc */
- NULL, /* 0,3 transparent to finnish nrc */
- NULL, /* 0,4 transparent to french nrc */
- NULL, /* 0,5 transparent to fr-canadian nrc */
- NULL, /* 0,6 transparent to german nrc */
- NULL, /* 0,7 transparent to hungarian nrc */
- NULL, /* 0,8 transparent to italian nrc */
- NULL, /* 0,9 transparent to norge/danish nrc */
- NULL, /* 0,10 transparent to portuguese nrc */
- NULL, /* 0,11 transparent to spanish nrc */
- NULL, /* 0,12 transparent to swedish nrc */
- NULL, /* 0,13 transparent to swiss nrc */
- NULL, /* 0,14 transparent to latin-1 */
- NULL, /* 0,15 transparent to latin-2 */
- NULL, /* 0,16 transparent to DEC MCS */
- NULL, /* 0,17 transparent to NeXT */
- NULL, /* 0,18 transparent to CP437 */
- NULL, /* 0,19 transparent to CP850 */
- NULL, /* 0,20 transparent to CP852 */
- NULL, /* 0,21 transparent to Macintosh Latin */
- NULL, /* 0,22 transparent to DGI */
- NULL, /* 0,23 transparent to HP */
- NULL, /* 0,24 transparent to Latin/Cyrillic */
- NULL, /* 0,25 transparent to CP866 */
- NULL, /* 0,26 transparent to Short KOI-7 */
- NULL, /* 0,27 transparent to Old KOI-8 Cyrillic */
- NULL, /* 0,28 transparent to JIS-7 */
- NULL, /* 0,29 transparent to Shift-JIS */
- NULL, /* 0,30 transparent to J-EUC */
- NULL, /* 0,31 transparent to DEC Kanji */
- NULL, /* 0,32 transparent to Hebrew-7 */
- NULL, /* 0,33 transparent to Latin/Hebrew */
- NULL, /* 0,34 transparent to CP862 Hebrew */
- NULL, /* 0,35 transparent to ELOT 927 Greek */
- NULL, /* 0,36 transparent to Latin/Greek */
- NULL, /* 0,37 transparent to CP869 */
- NULL, /* 0,38 transparent to Latin-9 */
- NULL, /* 0,39 transparent to CP858 */
- NULL, /* 0,40 transparent to CP855 */
- NULL, /* 0,41 transparent to CP1251 */
- NULL, /* 0,42 transparent to Bulgarian */
- NULL, /* 0,43 transparent to CP1250 */
- NULL, /* 0,44 transparent to Mazovia */
- NULL, /* 0,45 transparent to UCS-2 */
- NULL, /* 0,46 transparent to UTF-8 */
- NULL, /* 0,47 transparent to KOI8R */
- NULL, /* 0,48 transparent to KOI8U */
- NULL, /* 0,49 transparent to CP1252 */
- NULL, /* 1,0 ascii to us ascii */
- NULL, /* 1,1 ascii to uk ascii */
- NULL, /* 1,2 ascii to dutch nrc */
- NULL, /* 1,3 ascii to finnish nrc */
- NULL, /* 1,4 ascii to french nrc */
- NULL, /* 1,5 ascii to fr-canadian nrc */
- NULL, /* 1,6 ascii to german nrc */
- NULL, /* 1,7 ascii to hungarian nrc */
- NULL, /* 1,8 ascii to italian nrc */
- NULL, /* 1,9 ascii to norge/danish nrc */
- NULL, /* 1,10 ascii to portuguese nrc */
- NULL, /* 1,11 ascii to spanish nrc */
- NULL, /* 1,12 ascii to swedish nrc */
- NULL, /* 1,13 ascii to swiss nrc */
- NULL, /* 1,14 ascii to latin-1 */
- NULL, /* 1,15 ascii to latin-2 */
- NULL, /* 1,16 ascii to DEC MCS */
- NULL, /* 1,17 ascii to NeXT */
- NULL, /* 1,18 ascii to CP437 */
- NULL, /* 1,19 ascii to CP850 */
- NULL, /* 1,20 ascii to CP852 */
- NULL, /* 1,21 ascii to Macintosh Latin */
- NULL, /* 1,22 ascii to DGI */
- NULL, /* 1,23 ascii to HP */
- xaslc, /* 1,24 ascii to Latin/Cyrillic */
- xasac, /* 1,25 ascii to CP866 */
- xassk, /* 1,26 ascii to Short KOI */
- xask8, /* 1,27 ascii to Old KOI-8 Cyrillic */
- NULL, /* 1,28 ascii to JIS-7 */
- NULL, /* 1,29 ascii to Shift-JIS */
- NULL, /* 1,30 ascii to J-EUC */
- NULL, /* 1,31 ascii to DEC Kanji */
- xash7, /* 1,32 ascii to Hebrew-7 */
- NULL, /* 1,33 ascii to Latin/Hebrew */
- NULL, /* 1,34 ascii to CP862 Hebrew */
- xaseg, /* 1,35 ascii to ELOT 927 Greek */
- NULL, /* 1,36 ascii to Latin/Greek */
- NULL, /* 1,37 ascii to CP869 */
- NULL, /* 1,38 ascii to Latin-9 */
- NULL, /* 1,39 ascii to CP858 */
- xas55, /* 1,40 ascii to CP855 */
- xas1251, /* 1,41 ascii to CP1251 */
- xleft128, /* 1,42 ascii to bulgarian */
- xleft128, /* 1,43 ascii to CP1250 */
- xleft128, /* 1,44 ascii to Mazovia */
- NULL, /* 1,45 ascii to UCS-2 */
- NULL, /* 1,46 ascii to UTF-8 */
- NULL, /* 1,47 ascii to KOI8-R */
- NULL, /* 1,48 ascii to KOI8-U */
- NULL, /* 1,49 ascii to CP1252 */
- zl1as, /* 2,0 latin-1 to us ascii */
- xl1uk, /* 2,1 latin-1 to uk ascii */
- xl1du, /* 2,2 latin-1 to dutch nrc */
- xl1fi, /* 2,3 latin-1 to finnish nrc */
- xl1fr, /* 2,4 latin-1 to french nrc */
- xl1fc, /* 2,5 latin-1 to fr-canadian nrc */
- xl1ge, /* 2,6 latin-1 to german nrc */
- xl1it, /* 2,7 latin-1 to italian nrc */
- xl1hu, /* 2,8 latin-1 to hungarian nrc */
- xl1no, /* 2,9 latin-1 to norge/danish nrc */
- xl1po, /* 2,10 latin-1 to portuguese nrc */
- xl1sp, /* 2,11 latin-1 to spanish nrc */
- xl1sw, /* 2,12 latin-1 to swedish nrc */
- xl1ch, /* 2,13 latin-1 to swiss nrc */
- NULL, /* 2,14 latin-1 to latin-1 */
- xl1l2, /* 2,15 latin-1 to latin-2 */
- xl1dm, /* 2,16 latin-1 to DEC MCS */
- xl1ne, /* 2,17 latin-1 to NeXT */
- xl143, /* 2,18 latin-1 to CP437 */
- xl185, /* 2,19 latin-1 to CP850 */
- xl152, /* 2,20 latin-1 to CP852 */
- xl1aq, /* 2,21 latin-1 to Macintosh Latin */
- xl1dg, /* 2,22 latin-1 to DGI */
- xl1r8, /* 2,23 latin-1 to HP Roman8 */
- zl1as, /* 2,24 latin-1 to Latin/Cyrillic */
- zl1as, /* 2,25 latin-1 to CP866 */
- xl1sk, /* 2,26 latin-1 to Short KOI */
- zl1as, /* 2,27 latin-1 to Old KOI-8 Cyrillic */
- NULL, /* 2,28 latin-1 to JIS-7 */
- NULL, /* 2,29 latin-1 to Shift-JIS */
- NULL, /* 2,30 latin-1 to J-EUC */
- NULL, /* 2,31 latin-1 to DEC Kanji */
- xl1h7, /* 2,32 latin-1 to Hebrew-7 */
- xl1lh, /* 2,33 latin-1 to Latin/Hebrew */
- xl162, /* 2,34 latin-1 to CP862 Hebrew */
- xl1eg, /* 2,35 latin-1 to ELOT 927 Greek */
- xl1lg, /* 2,36 latin-1 to Latin/Greek */
- xl169, /* 2,37 latin-1 to CP869 */
- NULL, /* 2,38 latin-1 to Latin9 */
- xl185, /* 2,39 latin-1 to CP858 */
- zl1as, /* 2,40 latin-1 to CP855 */
- zl1as, /* 2,41 latin-1 to CP1251 */
- zl1as, /* 2,42 latin-1 to Bulgarian */
- xl11250, /* 2,43 latin-1 to CP1250 */
- xl1mz, /* 2,44 latin-1 to Mazovia */
- NULL, /* 2,45 latin-1 to UCS-2 */
- NULL, /* 2,46 latin-1 to UTF-8 */
- zl1as, /* 2,47 latin-1 to KOI8R */
- zl1as, /* 2,48 latin-1 to KOI8U */
- xl1w1, /* 2,49 latin-1 to CP1252 */
- xl2as, /* 3,0 latin-2 to us ascii */
- xl2as, /* 3,1 latin-2 to uk ascii */
- xl2as, /* 3,2 latin-2 to dutch nrc */
- xl2as, /* 3,3 latin-2 to finnish nrc */
- xl2as, /* 3,4 latin-2 to french nrc */
- xl2as, /* 3,5 latin-2 to fr-canadian nrc */
- xl2as, /* 3,6 latin-2 to german nrc */
- xl2as, /* 3,7 latin-2 to italian nrc */
- xl2as, /* 3,8 latin-2 to hungarian nrc */
- xl2as, /* 3,9 latin-2 to norge/danish nrc */
- xl2as, /* 3,10 latin-2 to portuguese nrc */
- xl2as, /* 3,11 latin-2 to spanish nrc */
- xl2as, /* 3,12 latin-2 to swedish nrc */
- xl2as, /* 3,13 latin-2 to swiss nrc */
- xl2l1, /* 3,14 latin-2 to latin-1 */
- NULL, /* 3,15 latin-2 to latin-2 */
- xl2l1, /* 3,16 latin-2 to DEC MCS */
- xl2ne, /* 3,17 latin-2 to NeXT */
- xl243, /* 3,18 latin-2 to CP437 */
- xl285, /* 3,19 latin-2 to CP850 */
- xl252, /* 3,20 latin-2 to CP852 */
- xl2aq, /* 3,21 latin-2 to Macintosh Latin */
- xl2dg, /* 3,22 latin-2 to DGI */
- xl2r8, /* 3,23 latin-2 to HP */
- xl2as, /* 3,24 latin-2 to Latin/Cyrillic */
- xl2as, /* 3,25 latin-2 to CP866 */
- xl2sk, /* 3,26 latin-2 to Short KOI */
- xl2as, /* 3,27 latin-2 to Old KOI-8 Cyrillic */
- NULL, /* 3,28 latin-2 to JIS-7 */
- NULL, /* 3,29 latin-2 to Shift-JIS */
- NULL, /* 3,30 latin-2 to J-EUC */
- NULL, /* 3,31 latin-2 to DEC Kanji */
- xl2h7, /* 3,32 latin-2 to Hebrew-7 */
- xl2as, /* 3,33 latin-2 to Latin/Hebrew */
- xl2as, /* 3,34 latin-2 to CP862 Hebrew */
- xassk, /* 3,35 latin-2 to ELOT 927 Greek */
- xl2as, /* 3,36 latin-2 to Latin/Greek */
- xl2as, /* 3,37 latin-2 to CP869 */
- xl2l9, /* 3,38 latin-2 to Latin-9 */
- xl258, /* 3,39 latin-2 to CP858 */
- xl2as, /* 3,40 latin-2 to CP855 */
- xl2as, /* 3,41 latin-2 to CP1251 */
- xl2as, /* 3,42 latin-2 to Bulgarian */
- xl21250, /* 3,43 latin-2 to CP1250 */
- xl2mz, /* 3,44 latin-2 to Mazovia */
- NULL, /* 3,45 latin-2 to UCS-2 */
- NULL, /* 3,46 latin-2 to UTF-8 */
- xl2as, /* 3,47 latin-2 to KOI8R */
- xl2as, /* 3,48 latin-2 to KOI8U */
- xl2w1, /* 3,49 latin-2 to CP1252 */
- xlcas, /* 4,0 latin/cyrillic to us ascii */
- xlcas, /* 4,1 latin/cyrillic to uk ascii */
- xlcas, /* 4,2 latin/cyrillic to dutch nrc */
- xlcas, /* 4,3 latin/cyrillic to finnish ascii */
- xlcas, /* 4,4 latin/cyrillic to french nrc */
- xlcas, /* 4,5 latin/cyrillic to fr-canadian nrc */
- xlcas, /* 4,6 latin/cyrillic to german nrc */
- xlcas, /* 4,7 latin/cyrillic to italian nrc */
- xlcas, /* 4,8 latin/cyrillic to hungarian nrc */
- xlcas, /* 4,9 latin/cyrillic to norge/danish nrc */
- xlcas, /* 4,10 latin/cyrillic to portuguese nrc */
- xlcas, /* 4,11 latin/cyrillic to spanish nrc */
- xlcas, /* 4,12 latin/cyrillic to swedish nrc */
- xlcas, /* 4,13 latin/cyrillic to swiss nrc */
- xlcas, /* 4,14 latin/cyrillic to latin-1 */
- xlcas, /* 4,15 latin/cyrillic to latin-2 */
- xlcas, /* 4,16 latin/cyrillic to DEC MCS */
- xlcas, /* 4,17 latin/cyrillic to NeXT */
- xlcas, /* 4,18 latin/cyrillic to CP437 */
- xlcas, /* 4,19 latin/cyrillic to CP850 */
- xlcas, /* 4,20 latin/cyrillic to CP852 */
- xlcas, /* 4,21 latin/cyrillic to Macintosh Latin */
- xlcas, /* 4,22 latin/cyrillic to DGI */
- xlcas, /* 4,23 latin/cyrillic to HP */
- NULL, /* 4,24 latin/cyrillic to Latin/Cyrillic */
- xlcac, /* 4,25 latin/cyrillic to CP866 */
- xlcsk, /* 4,26 latin/cyrillic to Short KOI */
- xlck8, /* 4,27 latin/cyrillic to Old KOI-8 Cyrillic */
- NULL, /* 4,28 latin/cyril to JIS-7 */
- NULL, /* 4,29 latin/cyril to Shift-JIS */
- NULL, /* 4,30 latin/cyril to J-EUC */
- NULL, /* 4,31 latin/cyril to DEC Kanji */
- xlch7, /* 4,32 latin/cyril to Hebrew-7 */
- xlcas, /* 4,33 latin/cyril to Latin/Hebrew */
- xlcas, /* 4,34 latin/cyril to CP862 Hebrew */
- xassk, /* 4,35 latin/cyril to ELOT 927 Greek */
- xleft160, /* 4,36 latin/cyril to Latin/Greek */
- xleft128, /* 4,37 latin/cyril to CP869 */
- xlcas, /* 4,38 latin/cyril to latin-9 */
- xlcas, /* 4,39 latin/cyril to CP858 */
- xlc55, /* 4,40 latin/cyril to CP855 */
- xlc1251, /* 4,41 latin/cyril to CP1251 */
- xlcbu, /* 4,42 latin/cyril to Bulgarian */
- xlcas, /* 4,43 latin/cyril to CP1250 */
- xlcas, /* 4,44 latin/cyril to Mazovia */
- NULL, /* 4,45 latin/cyril to UCS-2 */
- NULL, /* 4,46 latin/cyril to UTF-8 */
- xlckr, /* 4,47 latin/cyril to KOI8R */
- xlcku, /* 4,48 latin/cyril to KOI8U */
- xlcas, /* 4,49 latin/cyril to CP1252 */
- NULL, /* 5,00 */
- NULL, /* 5,01 */
- NULL, /* 5,02 */
- NULL, /* 5,03 */
- NULL, /* 5,04 */
- NULL, /* 5,05 */
- NULL, /* 5,06 */
- NULL, /* 5,07 */
- NULL, /* 5,08 */
- NULL, /* 5,09 */
- NULL, /* 5,10 */
- NULL, /* 5,11 */
- NULL, /* 5,12 */
- NULL, /* 5,13 */
- NULL, /* 5,14 */
- NULL, /* 5,15 */
- NULL, /* 5,16 */
- NULL, /* 5,17 */
- NULL, /* 5,18 */
- NULL, /* 5,19 */
- NULL, /* 5,20 */
- NULL, /* 5,21 */
- NULL, /* 5,22 */
- NULL, /* 5,23 */
- NULL, /* 5,24 */
- NULL, /* 5,25 */
- NULL, /* 5,26 */
- NULL, /* 5,27 */
- NULL, /* 5,28 */
- NULL, /* 5,29 */
- NULL, /* 5,30 */
- NULL, /* 5,31 */
- NULL, /* 5,32 */
- NULL, /* 5,33 */
- NULL, /* 5,34 */
- NULL, /* 5,35 */
- NULL, /* 5,36 */
- NULL, /* 5,37 */
- NULL, /* 5,38 */
- NULL, /* 5,39 */
- NULL, /* 5,40 */
- NULL, /* 5,41 */
- NULL, /* 5,42 */
- NULL, /* 5,43 */
- NULL, /* 5,44 */
- NULL, /* 5,45 */
- NULL, /* 5,46 */
- NULL, /* 5,47 */
- NULL, /* 5,48 */
- NULL, /* 5,49 */
- xlhas, /* 6,0 latin/hebrew to us ascii */
- xlhas, /* 6,1 latin/hebrew to uk ascii */
- xlhas, /* 6,2 latin/hebrew to dutch nrc */
- xlhas, /* 6,3 latin/hebrew to finnish ascii */
- xlhas, /* 6,4 latin/hebrew to french nrc */
- xlhas, /* 6,5 latin/hebrew to fr-canadian nrc */
- xlhas, /* 6,6 latin/hebrew to german nrc */
- xlhas, /* 6,7 latin/hebrew to italian nrc */
- xlhas, /* 6,8 latin/hebrew to hungarian nrc */
- xlhas, /* 6,9 latin/hebrew to norge/danish nrc */
- xlhas, /* 6,10 latin/hebrew to portuguese nrc */
- xlhas, /* 6,11 latin/hebrew to spanish nrc */
- xlhas, /* 6,12 latin/hebrew to swedish nrc */
- xlhas, /* 6,13 latin/hebrew to swiss nrc */
- xlhl1, /* 6,14 latin/hebrew to latin-1 */
- xlhas, /* 6,15 latin/hebrew to latin-2 */
- xlhl1, /* 6,16 latin/hebrew to DEC MCS */
- xlhas, /* 6,17 latin/hebrew to NeXT */
- xlhas, /* 6,18 latin/hebrew to CP437 */
- xlhas, /* 6,19 latin/hebrew to CP850 */
- xlhas, /* 6,20 latin/hebrew to CP852 */
- xlhas, /* 6,21 latin/hebrew to Macintosh Latin */
- xlhas, /* 6,22 latin/hebrew to DGI */
- xlhas, /* 6,23 latin/hebrew to HP */
- xlhas, /* 6,24 latin/hebrew to Latin/Cyrillic */
- xlhas, /* 6,25 latin/hebrew to CP866 */
- NULL, /* 6,26 latin/hebrew to Short KOI */
- xlhas, /* 6,27 latin/hebrew to Old KOI-8 Cyrillic */
- NULL, /* 6,28 latin/hebrew to JIS-7 */
- NULL, /* 6,29 latin/hebrew to Shift-JIS */
- NULL, /* 6,30 latin/hebrew to J-EUC */
- NULL, /* 6,31 latin/hebrew to DEC Kanji */
- xlhh7, /* 6,32 latin/hebrew to Hebrew-7 */
- NULL, /* 6,33 latin/hebrew to Latin/Hebrew */
- xlh62, /* 6,34 latin/hebrew to CP862 Hebrew */
- NULL, /* 6,35 latin/hebrew to ELOT 927 Greek */
- xlhas, /* 6,36 latin/hebrew to Latin/Greek */
- xlhas, /* 6,37 latin/hebrew to CP869 */
- xlhas, /* 6,38 latin/hebrew to Latin-9 */
- xlhas, /* 6,39 latin/hebrew to CP858 */
- xlhas, /* 6,40 latin/hebrew to CP855 */
- xlhas, /* 6,41 latin/hebrew to CP1251 */
- xlhas, /* 6,42 latin/hebrew to Bulgarian */
- xlhas, /* 6,43 latin/hebrew to CP1250 */
- xlhas, /* 6,44 latin/hebrew to Mazovia */
- NULL, /* 6,45 latin/hebrew to UCS-2 */
- NULL, /* 6,46 latin/hebrew to UTF-8 */
- NULL, /* 6,47 latin/hebrew to KOI8R */
- NULL, /* 6,48 latin/hebrew to KOI8U */
- xlhw1, /* 6,49 latin/hebrew to CP1252 */
- xlgas, /* 7,0 latin/greek to us ascii */
- xlgas, /* 7,1 latin/greek to uk ascii */
- xlgas, /* 7,2 latin/greek to dutch nrc */
- xlgas, /* 7,3 latin/greek to finnish ascii */
- xlgas, /* 7,4 latin/greek to french nrc */
- xlgas, /* 7,5 latin/greek to fr-canadian nrc */
- xlgas, /* 7,6 latin/greek to german nrc */
- xlgas, /* 7,7 latin/greek to italian nrc */
- xlgas, /* 7,8 latin/greek to hungarian nrc */
- xlgas, /* 7,9 latin/greek to norge/danish nrc */
- xlgas, /* 7,10 latin/greek to portuguese nrc */
- xlgas, /* 7,11 latin/greek to spanish nrc */
- xlgas, /* 7,12 latin/greek to swedish nrc */
- xlgas, /* 7,13 latin/greek to swiss nrc */
- xlgas, /* 7,14 latin/greek to latin-1 */
- xlgas, /* 7,15 latin/greek to latin-2 */
- xlgas, /* 7,16 latin/greek to DEC MCS */
- xlgas, /* 7,17 latin/greek to NeXT */
- xlgas, /* 7,18 latin/greek to CP437 */
- xlgas, /* 7,19 latin/greek to CP850 */
- xlgas, /* 7,20 latin/greek to CP852 */
- xlgas, /* 7,21 latin/greek to Macintosh Latin */
- xlgas, /* 7,22 latin/greek to DGI */
- xlgas, /* 7,23 latin/greek to HP */
- xleft160, /* 7,24 latin/greek to Latin/Cyrillic */
- xleft128, /* 7,25 latin/greek to CP866 */
- xassk, /* 7,26 latin/greek to Short KOI */
- xleft160, /* 7,27 latin/greek to Old KOI-8 Greek */
- NULL, /* 7,28 latin/greek to JIS-7 */
- NULL, /* 7,29 latin/greek to Shift-JIS */
- NULL, /* 7,30 latin/greek to J-EUC */
- NULL, /* 7,31 latin/greek to DEC Kanji */
- NULL, /* 7,32 latin/greek to Hebrew-7 */
- xlgas, /* 7,33 latin/greek to Latin/Hebrew */
- xlgas, /* 7,34 latin/greek to CP862 Hebrew */
- xlgeg, /* 7,35 latin/greek to ELOT 927 Greek */
- NULL, /* 7,36 latin/greek to Latin/Greek */
- xlg69, /* 7,37 latin/greek to CP869 */
- xlgas, /* 7,38 latin/greek to Latin-9 */
- xlgas, /* 7,39 latin/greek to CP858 */
- xleft128, /* 7,40 latin/greek to CP855 */
- xleft128, /* 7,41 latin/greek to CP1251 */
- xleft128, /* 7,42 latin/greek to Bulgarian */
- xleft128, /* 7,43 latin/greek to CP1250 */
- xleft128, /* 7,44 latin/greek to Mazovia */
- NULL, /* 7,45 latin/greek to UCS-2 */
- NULL, /* 7,46 latin/greek to UTF-8 */
- NULL, /* 7,47 latin/greek to KOI8R */
- NULL, /* 7,48 latin/greek to KOI8U */
- xlgw1, /* 7,49 latin/greek to CP1252 */
- zl9as, /* 8,0 latin-9 to us ascii */
- xl1uk, /* 8,1 latin-9 to uk ascii */
- xl1du, /* 8,2 latin-9 to dutch nrc */
- xl1fi, /* 8,3 latin-9 to finnish nrc */
- xl1fr, /* 8,4 latin-9 to french nrc */
- xl1fc, /* 8,5 latin-9 to fr-canadian nrc */
- xl1ge, /* 8,6 latin-9 to german nrc */
- xl1it, /* 8,7 latin-9 to italian nrc */
- xl1hu, /* 8,8 latin-9 to hungarian nrc */
- xl1no, /* 8,9 latin-9 to norge/danish nrc */
- xl1po, /* 8,10 latin-9 to portuguese nrc */
- xl1sp, /* 8,11 latin-9 to spanish nrc */
- xl1sw, /* 8,12 latin-9 to swedish nrc */
- xl1ch, /* 8,13 latin-9 to swiss nrc */
- NULL, /* 8,14 latin-9 to latin-1 */
- xl1l2, /* 8,15 latin-9 to latin-2 */
- xl9dm, /* 8,16 latin-9 to DEC MCS */
- xl9ne, /* 8,17 latin-9 to NeXT */
- xl143, /* 8,18 latin-9 to CP437 */
- xl185, /* 8,19 latin-9 to CP850 */
- xl152, /* 8,20 latin-9 to CP852 */
- xl1aq, /* 8,21 latin-9 to Macintosh Latin */
- xl1dg, /* 8,22 latin-9 to DGI */
- xl1r8, /* 8,23 latin-9 to HP Roman8 */
- zl1as, /* 8,24 latin-9 to Latin/Cyrillic */
- zl1as, /* 8,25 latin-9 to CP866 */
- xl1sk, /* 8,26 latin-9 to Short KOI */
- zl1as, /* 8,27 latin-9 to Old KOI-8 Cyrillic */
- NULL, /* 8,28 latin-9 to JIS-7 */
- NULL, /* 8,29 latin-9 to Shift-JIS */
- NULL, /* 8,30 latin-9 to J-EUC */
- NULL, /* 8,31 latin-9 to DEC Kanji */
- xl1h7, /* 8,32 latin-9 to Hebrew-7 */
- xl1lh, /* 8,33 latin-9 to Latin/Hebrew */
- xl162, /* 8,34 latin-9 to CP862 Hebrew */
- xl1eg, /* 8,35 latin-9 to ELOT 927 Greek */
- xl1lg, /* 8,36 latin-9 to Latin/Greek */
- xl169, /* 8,37 latin-9 to CP869 */
- NULL, /* 8,38 latin-9 to Latin9 */
- xl958, /* 8,39 latin-9 to CP858 */
- zl1as, /* 8,40 latin-9 to CP855 */
- zl1as, /* 8,41 latin-9 to CP1251 */
- xl1as, /* 8,42 latin-9 to Bulgarian */
- xl91250, /* 8,43 latin-9 to CP1250 */
- xl9mz, /* 8,44 latin-9 to Mazovia */
- NULL, /* 8,45 latin-9 to UCS-2 */
- NULL, /* 8,46 latin-9 to UTF-8 */
- zl1as, /* 8,47 latin-9 to KOI8-R */
- zl1as, /* 8,48 latin-9 to KOI8-U */
- xl9w1, /* 8,49 latin-9 to CP1252 */
- NULL, /* 9,00 Unicode... */
- NULL, /* 9,01 */
- NULL, /* 9,02 */
- NULL, /* 9,03 */
- NULL, /* 9,04 */
- NULL, /* 9,05 */
- NULL, /* 9,06 */
- NULL, /* 9,07 */
- NULL, /* 9,08 */
- NULL, /* 9,09 */
- NULL, /* 9,10 */
- NULL, /* 9,11 */
- NULL, /* 9,12 */
- NULL, /* 9,13 */
- NULL, /* 9,14 */
- NULL, /* 9,15 */
- NULL, /* 9,16 */
- NULL, /* 9,17 */
- NULL, /* 9,18 */
- NULL, /* 9,19 */
- NULL, /* 9,20 */
- NULL, /* 9,21 */
- NULL, /* 9,22 */
- NULL, /* 9,23 */
- NULL, /* 9,24 */
- NULL, /* 9,25 */
- NULL, /* 9,26 */
- NULL, /* 9,27 */
- NULL, /* 9,28 */
- NULL, /* 9,29 */
- NULL, /* 9,30 */
- NULL, /* 9,31 */
- NULL, /* 9,32 */
- NULL, /* 9,33 */
- NULL, /* 9,34 */
- NULL, /* 9,35 */
- NULL, /* 9,36 */
- NULL, /* 9,37 */
- NULL, /* 9,38 */
- NULL, /* 9,39 */
- NULL, /* 9,40 */
- NULL, /* 9,41 */
- NULL, /* 9,42 */
- NULL, /* 9,43 */
- NULL, /* 9,44 */
- NULL, /* 9,45 */
- NULL, /* 9,46 */
- NULL, /* 9,47 */
- NULL, /* 9,48 */
- NULL, /* 9,49 */
- NULL, /* 10,00 */
- NULL, /* 10,01 */
- NULL, /* 10,02 */
- NULL, /* 10,03 */
- NULL, /* 10,04 */
- NULL, /* 10,05 */
- NULL, /* 10,06 */
- NULL, /* 10,07 */
- NULL, /* 10,08 */
- NULL, /* 10,09 */
- NULL, /* 10,10 */
- NULL, /* 10,11 */
- NULL, /* 10,12 */
- NULL, /* 10,13 */
- NULL, /* 10,14 */
- NULL, /* 10,15 */
- NULL, /* 10,16 */
- NULL, /* 10,17 */
- NULL, /* 10,18 */
- NULL, /* 10,19 */
- NULL, /* 10,20 */
- NULL, /* 10,21 */
- NULL, /* 10,22 */
- NULL, /* 10,23 */
- NULL, /* 10,24 */
- NULL, /* 10,25 */
- NULL, /* 10,26 */
- NULL, /* 10,27 */
- NULL, /* 10,28 */
- NULL, /* 10,29 */
- NULL, /* 10,30 */
- NULL, /* 10,31 */
- NULL, /* 10,32 */
- NULL, /* 10,33 */
- NULL, /* 10,34 */
- NULL, /* 10,35 */
- NULL, /* 10,36 */
- NULL, /* 10,37 */
- NULL, /* 10,38 */
- NULL, /* 10,39 */
- NULL, /* 10,40 */
- NULL, /* 10,41 */
- NULL, /* 10,42 */
- NULL, /* 10,43 */
- NULL, /* 10,44 */
- NULL, /* 10,45 */
- NULL, /* 10,46 */
- NULL, /* 10,47 */
- NULL, /* 10,48 */
- NULL /* 10,49 */
-};
-int nxlr = (sizeof(xlr) / sizeof(CHAR *));
-
-/*
- Translation function table for sending files.
- Array of pointers to functions for translating from the local file
- character set to the transfer character set. Indexed in the same
- way as the xlr array above, but with the indices reversed.
-*/
-#ifdef CK_ANSIC
-CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(CHAR) =
-#else
-CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])() =
-#endif /* CK_ANSIC */
-{
- NULL, /* 0,0 us ascii to transparent */
- NULL, /* 0,1 uk ascii to transparent */
- NULL, /* 0,2 dutch nrc to transparent */
- NULL, /* 0,3 finnish nrc to transparent */
- NULL, /* 0,4 french nrc to transparent */
- NULL, /* 0,5 fr-canadian nrc to transparent */
- NULL, /* 0,6 german nrc to transparent */
- NULL, /* 0,7 hungarian nrc to transparent */
- NULL, /* 0,8 italian nrc to transparent */
- NULL, /* 0,9 norge/danish nrc to transparent */
- NULL, /* 0,10 portuguese nrc to transparent */
- NULL, /* 0,11 spanish nrc to transparent */
- NULL, /* 0,12 swedish nrc to transparent */
- NULL, /* 0,13 swiss nrc to transparent */
- NULL, /* 0,14 latin-1 to transparent */
- NULL, /* 0,15 latin-2 to transparent */
- NULL, /* 0,16 DEC MCS to transparent */
- NULL, /* 0,17 NeXT to transparent */
- NULL, /* 0,18 CP437 to transparent */
- NULL, /* 0,19 CP850 to transparent */
- NULL, /* 0,20 CP852 to transparent */
- NULL, /* 0,21 Macintosh Latin to transparent */
- NULL, /* 0,22 DGI to transparent */
- NULL, /* 0,23 HP to transparent */
- NULL, /* 0,24 Latin/Cyrillic to transparent */
- NULL, /* 0,25 CP866 to transparent */
- NULL, /* 0,26 Short KOI to transparent */
- NULL, /* 0,27 Old KOI-8 to transparent */
- NULL, /* 0,28 JIS-7 to transparent */
- NULL, /* 0,29 Shift JIS to transparent */
- NULL, /* 0,30 Japanese EUC to transparent */
- NULL, /* 0,31 DEC Kanji to transparent */
- NULL, /* 0,32 Hebrew-7 to transparent */
- NULL, /* 0,33 Latin/Hebrew to transparent */
- NULL, /* 0,34 CP862 Hebrew to transparent */
- NULL, /* 0,35 ELOT 927 Greek to transparent */
- NULL, /* 0,36 Latin/Greek to transparent */
- NULL, /* 0,37 CP869 to transparent */
- NULL, /* 0,38 Latin-9 to transparent */
- NULL, /* 0,39 CP858 to transparent */
- NULL, /* 0,40 CP855 to transparent */
- NULL, /* 0,41 CP1251 to transparent */
- NULL, /* 0,42 Bulgarian to transparent */
- NULL, /* 0,43 CP1250 to transparent */
- NULL, /* 0,44 Mazovia to transparent */
- NULL, /* 0,45 UCS-2 to transparent */
- NULL, /* 0,46 UTF-8 to transparent */
- NULL, /* 0,47 KOI8R to transparent */
- NULL, /* 0,48 KOI8U to transparent */
- NULL, /* 0,49 CP1252 to transparent */
- NULL, /* 1,0 us ascii to ascii */
- NULL, /* 1,1 uk ascii to ascii */
- xduas, /* 1,2 dutch nrc to ascii */
- xfias, /* 1,3 finnish nrc to ascii */
- xfras, /* 1,4 french nrc to ascii */
- xfcas, /* 1,5 french canadian nrc to ascii */
- xgeas, /* 1,6 german nrc to ascii */
- xhuas, /* 1,7 hungarian nrc to ascii */
- xitas, /* 1,8 italian nrc to ascii */
- xnoas, /* 1,9 norwegian/danish nrc to ascii */
- xpoas, /* 1,10 portuguese nrc to ascii */
- xspas, /* 1,11 spanish nrc to ascii */
- xswas, /* 1,12 swedish nrc to ascii */
- xchas, /* 1,13 swiss nrc to ascii */
- xl1as, /* 1,14 latin-1 to ascii */
- xl2as, /* 1,15 latin-2 to ascii */
- xdmas, /* 1,16 dec mcs to ascii */
- xneas, /* 1,17 NeXT to ascii */
- x43as, /* 1,18 CP437 to ascii */
- x85as, /* 1,19 CP850 to ascii */
- x52as, /* 1,20 CP850 to ascii */
- xaqas, /* 1,21 Macintosh Latin to ascii */
- xdgas, /* 1,22 DGI to ascii */
- xr8as, /* 1,23 HP to ASCII */
- xlcas, /* 1,24 Latin/Cyrillic to ASCII */
- xacas, /* 1,25 CP866 to ASCII */
- xskas, /* 1,26 Short KOI to ASCII */
- xk8as, /* 1,27 Old KOI-8 Cyrillic to ASCII */
- NULL, /* 1,28 */
- NULL, /* 1,29 */
- NULL, /* 1,30 */
- NULL, /* 1,31 */
- xh7as, /* 1,32 Hebrew-7 to ASCII */
- xlhas, /* 1,33 Latin/Hebrew to ASCII */
- x62as, /* 1,34 CP862 Hebrew to ASCII */
- xegas, /* 1,35 ELOT 927 Greek to ASCII */
- xlgas, /* 1,36 Latin/Greek to ASCII */
- x69as, /* 1,37 CP869 to ASCII */
- xl9as, /* 1,38 Latin-9 to ASCII */
- x58as, /* 1,39 CP858 to ASCII */
- x55as, /* 1,40 CP855 to ASCII */
- x1251as, /* 1,41 CP1251 to ASCII */
- xleft128, /* 1,42 Bulgarian to ASCII */
- x1250as, /* 1,43 CP1250 to ASCII */
- xmzas, /* 1,44 Mazovia to ASCII */
- NULL, /* 1,45 UCS-2 to ASCII */
- NULL, /* 1,46 UTF-8 to ASCII */
- xk8as, /* 1,47 KOI8R to ASCII */
- xk8as, /* 1,48 KOI8U to ASCII */
- xw1as, /* 1,49 CP1252 to ASCII */
- NULL, /* 2,0 us ascii to latin-1 */
- xukl1, /* 2,1 uk ascii to latin-1 */
- xdul1, /* 2,2 dutch nrc to latin-1 */
- xfil1, /* 2,3 finnish nrc to latin-1 */
- xfrl1, /* 2,4 french nrc to latin-1 */
- xfcl1, /* 2,5 french canadian nrc to latin-1 */
- xgel1, /* 2,6 german nrc to latin-1 */
- xhul1, /* 2,7 hungarian nrc to latin-1 */
- xitl1, /* 2,8 italian nrc to latin-1 */
- xnol1, /* 2,9 norwegian/danish nrc to latin-1 */
- xpol1, /* 2,10 portuguese nrc to latin-1 */
- xspl1, /* 2,11 spanish nrc to latin-1 */
- xswl1, /* 2,12 swedish nrc to latin-1 */
- xchl1, /* 2,13 swiss nrc to latin-1 */
- NULL, /* 2,14 latin-1 to latin-1 */
- xl2l1, /* 2,15 latin-2 to latin-1 */
- xdml1, /* 2,16 dec mcs to latin-1 */
- xnel1, /* 2,17 NeXT to Latin-1 */
- x43l1, /* 2,18 CP437 to Latin-1 */
- x85l1, /* 2,19 CP850 to Latin-1 */
- x52l1, /* 2,20 CP852 to Latin-1 */
- xaql1, /* 2,21 Macintosh Latin to Latin-1 */
- xdgl1, /* 2,22 DGI to Latin-1 */
- xr8l1, /* 2,23 HP to Latin-1 */
- xlcas, /* 2,24 Latin/Cyrillic to Latin-1 */
- xacas, /* 2,25 CP866 to Latin-1 */
- xskas, /* 2,26 Short KOI to Latin-1 */
- xk8as, /* 2,27 Old KOI-8 Cyrillic to Latin-1 */
- NULL, /* 2,28 Kanji ... */
- NULL, /* 2,29 */
- NULL, /* 2,30 */
- NULL, /* 2,31 */
- xh7as, /* 2,32 Hebrew-7 to Latin-1 */
- xlhl1, /* 2,33 Latin/Hebrew to Latin-1 */
- x62l1, /* 2,34 CP862 Hebrew to Latin-1 */
- xegas, /* 2,35 ELOT 927 Greek to Latin-1 */
- xlgl1, /* 2,36 Latin/Greek to Latin-1 */
- NULL, /* 2,37 CP869 to Latin-1 */
- NULL, /* 2,38 Latin-9 to Latin-1 */
- x58l1, /* 2,39 CP858 to Latin-1 */
- x55as, /* 2,40 CP855 to Latin-1 */
- x1251as, /* 2,41 CP1251 to Latin-1 */
- xleft128, /* 2,42 Bulgarian to Latin-1 */
- x1250l1, /* 2,43 CP1250 to Latin-1 */
- xmzl1, /* 2,44 Mazovia to Latin-1 */
- NULL, /* 2,45 UCS-2 to Latin-1 */
- NULL, /* 2,46 UTF-8 to Latin-1 */
- xk8as, /* 2,47 KOI8R to Latin-1 */
- xk8as, /* 2,48 KOI8U to Latin-1 */
- xw1l1, /* 2,49 CP1252 to Latin-1 */
- NULL, /* 3,0 us ascii to latin-2 */
- NULL, /* 3,1 uk ascii to latin-2 */
- xduas, /* 3,2 dutch nrc to latin-2 */
- xfias, /* 3,3 finnish nrc to latin-2 */
- xfras, /* 3,4 french nrc to latin-2 */
- xfcas, /* 3,5 french canadian nrc to latin-2 */
- xgel2, /* 3,6 german nrc to latin-2 */
- xhul2, /* 3,7 hungarian nrc to latin-2 */
- xitas, /* 3,8 italian nrc to latin-2 */
- xnoas, /* 3,9 norwegian/danish nrc to latin-2 */
- xpoas, /* 3,10 portuguese nrc to latin-2 */
- xspas, /* 3,11 spanish nrc to latin-2 */
- xswas, /* 3,12 swedish nrc to latin-2 */
- xchas, /* 3,13 swiss nrc to latin-2 */
- xl1l2, /* 3,14 latin-1 to latin-2 */
- NULL, /* 3,15 latin-2 to latin-2 */
- xl1l2, /* 3,16 dec mcs to latin-2 */
- xnel2, /* 3,17 NeXT to Latin-2 */
- x43l2, /* 3,18 CP437 to Latin-2 */
- x85l2, /* 3,19 CP850 to Latin-2 */
- x52l2, /* 3,20 CP852 to Latin-2 */
- xaql2, /* 3,21 Macintosh Latin to Latin-2 */
- xdgl2, /* 3,22 DGI to Latin-2 */
- xr8l2, /* 3,23 HP to Latin-2 */
- xlcas, /* 3,24 Latin/Cyrillic to Latin-2 */
- xacas, /* 3,25 CP866 to Latin-2 */
- xskas, /* 3,26 Short KOI to Latin-2 */
- xk8as, /* 3,27 Old KOI-8 Cyrillic to Latin-2 */
- NULL, /* 3,28 Kanji ... */
- NULL, /* 3,29 */
- NULL, /* 3,30 */
- NULL, /* 3,31 */
- xh7as, /* 3,32 Hebrew-7 to Latin-2 */
- xlhas, /* 3,33 Latin/Hebrew to Latin-2 */
- x62as, /* 3,34 CP862 Hebrew to Latin-2 */
- xegas, /* 3,35 ELOT 927 Greek to Latin-2 */
- xl2lg, /* 3,36 Latin/Greek to Latin-2 */
- xleft128, /* 3,37 CP869 to Latin-2 */
- xl9l2, /* 3,38 Latin-9 to Latin-2 */
- x58l2, /* 3,39 CP858 to Latin-2 */
- x55as, /* 3,40 CP855 to Latin-2 */
- x1251as, /* 3,41 CP1251 to Latin-2 */
- xleft128, /* 3,42 Bulgarian to Latin-2 */
- x1250l2, /* 3,43 CP1250 to Latin-2 */
- xmzl2, /* 3,44 Mazovia to Latin-2 */
- NULL, /* 3,45 UCS-2 to Latin-2 */
- NULL, /* 3,46 UTF-8 to Latin-2 */
- xk8as, /* 3,47 KOI8R to Latin-2 */
- xk8as, /* 3,48 KOI8U to Latin-2 */
- xw1l2, /* 3,49 CP1252 to latin-2 */
- xaslc, /* 4,0 us ascii to latin/cyrillic */
- xaslc, /* 4,1 uk ascii to latin/cyrillic */
- xduas, /* 4,2 dutch nrc to latin/cyrillic */
- xfias, /* 4,3 finnish nrc to latin/cyrillic */
- xfras, /* 4,4 french nrc to latin/cyrillic */
- xfcas, /* 4,5 french canadian nrc to latin/cyrillic */
- xgeas, /* 4,6 german nrc to latin/cyrillic */
- xhuas, /* 4,7 hungarian nrc to latin/cyrillic */
- xitas, /* 4,8 italian nrc to latin/cyrillic */
- xnoas, /* 4,9 norge/danish nrc to latin/cyrillic */
- xpoas, /* 4,10 portuguese nrc to latin/cyrillic */
- xspas, /* 4,11 spanish nrc to latin/cyrillic */
- xswas, /* 4,12 swedish nrc to latin/cyrillic */
- xchas, /* 4,13 swiss nrc to latin/cyrillic */
- xl1as, /* 4,14 latin-1 to latin/cyrillic */
- xl2as, /* 4,15 latin-2 to latin/cyrillic */
- xdmas, /* 4,16 dec mcs to latin/cyrillic */
- xneas, /* 4,17 NeXT to latin/cyrillic */
- x43as, /* 4,18 CP437 to latin/cyrillic */
- x85as, /* 4,19 CP850 to latin/cyrillic */
- x52as, /* 4,20 CP852 to latin/cyrillic */
- xaqas, /* 4,21 Macintosh Latin to latin/cyrillic */
- xdgas, /* 4,22 DGI to Latin/Cyrillic */
- xr8as, /* 4,23 HP to Latin/Cyrillic */
- NULL, /* 4,24 Latin/Cyrillic to Latin/Cyrillic */
- xaclc, /* 4,25 CP866 to Latin/Cyrillic */
- xskcy, /* 4,26 Short KOI to Latin/Cyrillic */
- xk8lc, /* 4,27 Old KOI-8 Cyrillic to Latin/Cyrillic */
- NULL, /* 4,28 Kanji... */
- NULL, /* 4,29 */
- NULL, /* 4,30 */
- NULL, /* 4,31 */
- xh7as, /* 4,32 Hebrew-7 to Latin/Cyrillic */
- xlhas, /* 4,33 Latin/Hebrew to Latin/Cyrillic */
- x62as, /* 4,34 CP862 Hebrew to Latin/Cyrillic */
- xegas, /* 4,35 ELOT 927 Greek to Latin/Cyrillic */
- xleft160, /* 4,36 Latin/Greek to Latin/Cyrillic */
- xleft128, /* 4,37 CP869 to Latin/Cyrillic */
- xl1as, /* 4,38 latin-9 to latin/cyrillic */
- xleft128, /* 4,39 CP858 to Latin/Cyrillic */
- x55lc, /* 4,40 CP855 to Latin/Cyrillic */
- x1251lc, /* 4,41 CP1251 to Latin/Cyrillic */
- xbulc, /* 4,42 Bulgarian to Latin/Cyrillic */
- x1250as, /* 4,43 CP1250 to Latin/Cyrillic */
- xmzas, /* 4,44 Mazovia to Latin/Cyrillic */
- NULL, /* 4,45 UCS-2 to Latin/Cyrillic */
- NULL, /* 4,46 UTF-8 to Latin/Cyrillic */
- xkrlc, /* 4,47 KOI8R to Latin/Cyrillic */
- xkulc, /* 4,48 KOI8U to Latin/Cyrillic */
- xw1lc, /* 4,49 CP1252 to Latin/Cyrillic */
- NULL, /* 5,00 */
- NULL, /* 5,01 */
- NULL, /* 5,02 */
- NULL, /* 5,03 */
- NULL, /* 5,04 */
- NULL, /* 5,05 */
- NULL, /* 5,06 */
- NULL, /* 4.07 */
- NULL, /* 5,08 */
- NULL, /* 5,09 */
- NULL, /* 5,10 */
- NULL, /* 5,11 */
- NULL, /* 5,12 */
- NULL, /* 5,13 */
- NULL, /* 5,14 */
- NULL, /* 5,15 */
- NULL, /* 5,16 */
- NULL, /* 5,17 */
- NULL, /* 5,18 */
- NULL, /* 5,19 */
- NULL, /* 5,20 */
- NULL, /* 5,21 */
- NULL, /* 5,22 */
- NULL, /* 5,23 */
- NULL, /* 5,24 */
- NULL, /* 5,25 */
- NULL, /* 5,26 */
- NULL, /* 5,27 */
- NULL, /* 5,28 */
- NULL, /* 5,29 */
- NULL, /* 5,30 */
- NULL, /* 5,31 */
- NULL, /* 5,32 */
- NULL, /* 5,33 */
- NULL, /* 5,34 */
- NULL, /* 5,35 */
- NULL, /* 5,36 */
- NULL, /* 5,37 */
- NULL, /* 5,38 */
- NULL, /* 5,39 */
- NULL, /* 5,40 */
- NULL, /* 5,41 */
- NULL, /* 5,42 */
- NULL, /* 5,43 */
- NULL, /* 5,44 */
- NULL, /* 5,45 */
- NULL, /* 5,46 */
- NULL, /* 5,47 */
- NULL, /* 5,48 */
- NULL, /* 5,49 */
- NULL, /* 6,0 us ascii to Latin/Hebrew */
- NULL, /* 6,1 uk ascii to Latin/Hebrew */
- xduas, /* 6,2 dutch nrc to Latin/Hebrew */
- xfias, /* 6,3 finnish nrc to Latin/Hebrew */
- xfras, /* 6,4 french nrc to Latin/Hebrew */
- xfcas, /* 6,5 french canadian nrc to Latin/Hebrew */
- xgeas, /* 6,6 german nrc to Latin/Hebrew */
- xhuas, /* 6,7 hungarian nrc to Latin/Hebrew */
- xitas, /* 6,8 italian nrc to Latin/Hebrew */
- xnoas, /* 6,9 norge/danish nrc to Latin/Hebrew */
- xpoas, /* 6,10 portuguese nrc to Latin/Hebrew */
- xspas, /* 6,11 spanish nrc to Latin/Hebrew */
- xswas, /* 6,12 swedish nrc to Latin/Hebrew */
- xchas, /* 6,13 swiss nrc to Latin/Hebrew */
- xl1lh, /* 6,14 latin-1 to Latin/Hebrew */
- xl2as, /* 6,15 latin-2 to Latin/Hebrew */
- xdmas, /* 6,16 dec mcs to Latin/Hebrew */
- xneas, /* 6,17 NeXT to Latin/Hebrew */
- x43as, /* 6,18 CP437 to Latin/Hebrew */
- x85as, /* 6,19 CP850 to Latin/Hebrew */
- x52as, /* 6,20 CP852 to Latin/Hebrew */
- xaqas, /* 6,21 Macintosh Latin to Latin/Hebrew */
- xdgas, /* 6,22 DGI to Latin/Hebrew */
- xr8as, /* 6,23 HP to Latin/Hebrew */
- xlcas, /* 6,24 Latin/Cyrillic to Latin/Hebrew */
- xacas, /* 6,25 CP866 to Latin/Hebrew */
- xskas, /* 6,26 Short KOI to Latin/Hebrew */
- xk8as, /* 6,27 Old KOI-8 Cyrillic to Latin/Hebrew */
- NULL, /* 6,28 Kanji... */
- NULL, /* 6,29 */
- NULL, /* 6,30 */
- NULL, /* 6,31 */
- xh7lh, /* 6,32 Hebrew-7 to Latin/Hebrew */
- NULL, /* 6,33 Latin/Hebrew to Latin/Hebrew */
- x62lh, /* 6,34 CP862 Hebrew to Latin/Hebrew */
- xegas, /* 6,35 ELOT 927 Greek to Latin/Hebrew */
- xlgas, /* 6,36 Latin/Greek to Latin/Hebrew */
- x69as, /* 6,37 CP869 to Latin/Hebrew */
- xl1as, /* 6,38 latin-9 to Latin/Hebrew */
- x58as, /* 6,39 CP858 to Latin/Hebrew */
- x55as, /* 6,40 CP855 to Latin/Hebrew */
- x1251as, /* 6,41 CP1251 to Latin/Hebrew */
- xleft128, /* 6,42 Bulgarian to Latin/Hebrew */
- x1250as, /* 6,43 CP1250 to Latin/Hebrew */
- xmzas, /* 6,44 Mazovia to Latin/Hebrew */
- NULL, /* 6,45 UCS-2 to Latin/Hebrew */
- NULL, /* 6,46 UTF-8 to Latin/Hebrew */
- NULL, /* 6,47 KOI8R to Latin/Hebrew */
- NULL, /* 6,48 KOI8U to Latin/Hebrew */
- xw1lh, /* 6,49 CP1252 to Latin/Hebrew */
- NULL, /* 7,0 us ascii to Latin/Greek */
- NULL, /* 7,1 uk ascii to Latin/Greek */
- xduas, /* 7,2 dutch nrc to Latin/Greek */
- xfias, /* 7,3 finnish nrc to Latin/Greek */
- xfras, /* 7,4 french nrc to Latin/Greek */
- xfcas, /* 7,5 french canadian nrc to Latin/Greek */
- xgeas, /* 7,6 german nrc to Latin/Greek */
- xhuas, /* 7,7 hungarian nrc to Latin/Greek */
- xitas, /* 7,8 italian nrc to Latin/Greek */
- xnoas, /* 7,9 norge/danish nrc to Latin/Greek */
- xpoas, /* 7,10 portuguese nrc to Latin/Greek */
- xspas, /* 7,11 spanish nrc to Latin/Greek */
- xswas, /* 7,12 swedish nrc to Latin/Greek */
- xchas, /* 7,13 swiss nrc to Latin/Greek */
- xl1lg, /* 7,14 latin-1 to Latin/Greek */
- xl2lg, /* 7,15 latin-2 to Latin/Greek */
- xl1lg, /* 7,16 dec mcs to Latin/Greek */
- xneas, /* 7,17 NeXT to Latin/Greek */
- xleft128, /* 7,18 CP437 to Latin/Greek */
- x85as, /* 7,19 CP850 to Latin/Greek */
- x52as, /* 7,20 CP852 to Latin/Greek */
- xaqas, /* 7,21 Macintosh Latin to Latin/Greek */
- xdgas, /* 7,22 DGI to Latin/Greek */
- xr8as, /* 7,23 HP to Latin/Greek */
- xleft160, /* 7,24 Latin/Cyrillic to Latin/Greek */
- xleft128, /* 7,25 CP866 to Latin/Greek */
- xskas, /* 7,26 Short KOI to Latin/Greek */
- xk8as, /* 7,27 Old KOI-8 Cyrillic to Latin/Greek */
- NULL, /* 7,28 Kanji... */
- NULL, /* 7,29 */
- NULL, /* 7,30 */
- NULL, /* 7,31 */
- xh7as, /* 7,32 Hebrew-7 to Latin/Greek */
- NULL, /* 7,33 Latin/Hebrew to Latin/Greek */
- x62as, /* 7,34 CP862 Hebrew to Latin/Greek */
- xeglg, /* 7,35 ELOT 927 Greek to Latin/Greek */
- NULL, /* 7,36 Latin/Greek to Latin/Greek */
- x69lg, /* 7,37 CP869 to Latin/Greek */
- xl1as, /* 7,38 latin-9 to Latin/Greek */
- xl1as, /* 7,39 latin-9 to Latin/Hebrew*/
- xleft128, /* 7,40 CP855 to Latin/Greek */
- xleft128, /* 7,41 CP1251 to Latin/Greek */
- xleft128, /* 7,42 Bulgarian to Latin/Greek */
- x1250as, /* 7,43 CP1250 to Latin/Greek */
- xmzas, /* 7,44 Mazovia to Latin/Greek */
- NULL, /* 7,45 UCS-2 to Latin/Greek */
- NULL, /* 7,46 UTF-8 to Latin/Greek */
- NULL, /* 7,47 KOI8R to Latin/Greek */
- NULL, /* 7,48 KOI8U to Latin/Greek */
- xw1lg, /* 7,49 CP1252 to Latin/Greek */
- NULL, /* 8,0 us ascii to latin-9 */
- xukl1, /* 8,1 uk ascii to latin-9 */
- xdul1, /* 8,2 dutch nrc to latin-9 */
- xfil1, /* 8,3 finnish nrc to latin-9 */
- xfrl1, /* 8,4 french nrc to latin-9 */
- xfcl1, /* 8,5 french canadian nrc to latin-9 */
- xgel1, /* 8,6 german nrc to latin-9 */
- xhul1, /* 8,7 hungarian nrc to latin-9 */
- xitl1, /* 8,8 italian nrc to latin-9 */
- xnol1, /* 8,9 norwegian/danish nrc to latin-9 */
- xpol1, /* 8,10 portuguese nrc to latin-9 */
- xspl1, /* 8,11 spanish nrc to latin-9 */
- xswl1, /* 8,12 swedish nrc to latin-9 */
- xchl1, /* 8,13 swiss nrc to latin-9 */
- NULL, /* 8,14 latin-1 to latin-9 */
- xl2l9, /* 8,15 latin-2 to latin-9 */
- xdml9, /* 8,16 dec mcs to latin-9 */
- xnel9, /* 8,17 NeXT To Latin-9 */
- x43l1, /* 8,18 CP437 To Latin-9 */
- x85l1, /* 8,19 CP850 To Latin-9 */
- x52l1, /* 8,20 CP852 To Latin-9 */
- xaql1, /* 8,21 Macintosh Latin To Latin-9 */
- xdgl1, /* 8,22 DGI To Latin-9 */
- xr8l1, /* 8,23 HP To Latin-9 */
- xlcas, /* 8,24 Latin/Cyrillic To Latin-9 */
- xacas, /* 8,25 CP866 To Latin-9 */
- xskas, /* 8,26 Short KOI To Latin-9 */
- xk8as, /* 8,27 Old KOI-8 Cyrillic To Latin-9 */
- NULL, /* 8,28 Kanji ... */
- NULL, /* 8,29 */
- NULL, /* 8,30 */
- NULL, /* 8,31 */
- xh7as, /* 8,32 Hebrew-7 To Latin-9 */
- xlhl1, /* 8,33 Latin/Hebrew To Latin-9 */
- x62l1, /* 8,34 CP862 Hebrew To Latin-9 */
- xegas, /* 8,35 ELOT 927 Greek To Latin-9 */
- xlgl1, /* 8,36 Latin/Greek To Latin-9 */
- xl169, /* 8,37 CP869 To Latin-9 */
- NULL, /* 8,38 Latin-9 To Latin-9 */
- x58l9, /* 8,39 cp858 To Latin-9 */
- x55as, /* 8,40 cp855 To Latin-9 */
- x55as, /* 8,41 cp1251 To Latin-9 */
- xleft128, /* 8,42 Bulgarian To Latin-9 */
- x1250l9, /* 8,43 CP1250 To Latin-9 */
- xmzl9, /* 8,44 Mazovia To Latin-9 */
- NULL, /* 8,45 UCS-2 to Latin-9 */
- NULL, /* 8,46 UTF-8 to Latin-9 */
- NULL, /* 8,47 KOI8R to Latin-9 */
- NULL, /* 8,48 KOI8U to Latin-9 */
- xw1l9, /* 8,49 CP1252 to Latin-9 */
- NULL, /* 9,00 Unicode... */
- NULL, /* 9,01 */
- NULL, /* 9,02 */
- NULL, /* 9,03 */
- NULL, /* 9,04 */
- NULL, /* 9,05 */
- NULL, /* 9,06 */
- NULL, /* 9,07 */
- NULL, /* 9,08 */
- NULL, /* 9,09 */
- NULL, /* 9,10 */
- NULL, /* 9,11 */
- NULL, /* 9,12 */
- NULL, /* 9,13 */
- NULL, /* 9,14 */
- NULL, /* 9,15 */
- NULL, /* 9,16 */
- NULL, /* 9,17 */
- NULL, /* 9,18 */
- NULL, /* 9,19 */
- NULL, /* 9,20 */
- NULL, /* 9,21 */
- NULL, /* 9,22 */
- NULL, /* 9,23 */
- NULL, /* 9,24 */
- NULL, /* 9,25 */
- NULL, /* 9,26 */
- NULL, /* 9,27 */
- NULL, /* 9,28 */
- NULL, /* 9,29 */
- NULL, /* 9,30 */
- NULL, /* 9,31 */
- NULL, /* 9,32 */
- NULL, /* 9,33 */
- NULL, /* 9,34 */
- NULL, /* 9,35 */
- NULL, /* 9,36 */
- NULL, /* 9,37 */
- NULL, /* 9,38 */
- NULL, /* 9,39 */
- NULL, /* 9,40 */
- NULL, /* 9,41 */
- NULL, /* 9,42 */
- NULL, /* 9,43 */
- NULL, /* 9,44 */
- NULL, /* 9,45 */
- NULL, /* 9,46 */
- NULL, /* 9,47 */
- NULL, /* 9,48 */
- NULL, /* 9,49 */
- NULL, /* 10,00 */
- NULL, /* 10,01 */
- NULL, /* 10,02 */
- NULL, /* 10,03 */
- NULL, /* 10,04 */
- NULL, /* 10,05 */
- NULL, /* 10,06 */
- NULL, /* 10,07 */
- NULL, /* 10,08 */
- NULL, /* 10,09 */
- NULL, /* 10,10 */
- NULL, /* 10,11 */
- NULL, /* 10,12 */
- NULL, /* 10,13 */
- NULL, /* 10,14 */
- NULL, /* 10,15 */
- NULL, /* 10,16 */
- NULL, /* 10,17 */
- NULL, /* 10,18 */
- NULL, /* 10,19 */
- NULL, /* 10,20 */
- NULL, /* 10,21 */
- NULL, /* 10,22 */
- NULL, /* 10,23 */
- NULL, /* 10,24 */
- NULL, /* 10,25 */
- NULL, /* 10,26 */
- NULL, /* 10,27 */
- NULL, /* 10,28 */
- NULL, /* 10,29 */
- NULL, /* 10,30 */
- NULL, /* 10,31 */
- NULL, /* 10,32 */
- NULL, /* 10,33 */
- NULL, /* 10,34 */
- NULL, /* 10,35 */
- NULL, /* 10,36 */
- NULL, /* 10,37 */
- NULL, /* 10,38 */
- NULL, /* 10,39 */
- NULL, /* 10,40 */
- NULL, /* 10,41 */
- NULL, /* 10,42 */
- NULL, /* 10,43 */
- NULL, /* 10,44 */
- NULL, /* 10,45 */
- NULL, /* 10,46 */
- NULL, /* 10,47 */
- NULL, /* 10,48 */
- NULL /* 10,49 */
-};
-int nxls = (sizeof(xls) / sizeof(CHAR *));
-
-#ifndef NOLOCAL
-/*
- The following routines are useful only for terminal character sets, and so
- ifdef'd out for NOLOCAL compilations.
-*/
-
-/*
- C S _ I S _ N R C
-
- Returns nonzero if argument indicates a 7-bit national character set,
- zero otherwise.
-*/
-int
-cs_is_nrc(x) int x; {
-#ifdef UNICODE
- if (x == TX_J201R || x == TX_DECSPEC || x == TX_DECTECH
- || txrinfo[x] == NULL)
- return(0);
- else
- return(txrinfo[x]->flags & X2U_STD && txrinfo[x]->size == 94);
-#else /* UNICODE */
- if ((cs_size(x) == 94))
- return(1);
- else
- return(0);
-#endif /* UNICODE */
-}
-
-/*
- C S _ I S _ S T D
-
- Returns nonzero if argument indicates an ISO 4873-standard-format
- character set, i.e. one in which the control region is NOT used for
- graphics; zero otherwise.
-*/
-int
-cs_is_std(x) int x; {
-#ifdef UNICODE
- if (!txrinfo[x]) /* Even more safety */
- return(0);
- else if (txrinfo[x]->size == 128) /* Just for safety */
- return(0);
- else
- return(txrinfo[x]->flags & X2U_STD); /* Only this should be needed */
-#else
- switch (x) {
- case FC_CP437: /* Code pages use C1 graphics */
- case FC_CP850:
- case FC_CP852:
- case FC_CP862:
- case FC_CP866:
- case FC_CP869:
- case FC_CP858:
- case FC_APPQD: /* So do Apple and NeXTSTEP */
- case FC_NEXT:
- return(0);
- default: /* Others behave */
- return(1);
- }
-#endif /* CKOUINI */
-}
-
-int
-cs_size(x) int x; {
-#ifdef UNICODE
- if (!txrinfo[x])
- return(128);
- return(txrinfo[x]->size);
-#else
- switch(x) {
- case FC_USASCII:
- case FC_UKASCII:
- case FC_DUASCII:
- case FC_FIASCII:
- case FC_FRASCII:
- case FC_FCASCII:
- case FC_GEASCII:
- case FC_HUASCII:
- case FC_ITASCII:
- case FC_NOASCII:
- case FC_POASCII:
- case FC_SPASCII:
- case FC_SWASCII:
- case FC_CHASCII:
- case FC_KOI7:
- case FC_HE7:
- case FC_ELOT:
- return(94);
-
- case FC_1LATIN:
- case FC_2LATIN:
- case FC_DECMCS:
- case FC_DGMCS:
- case FC_HPR8:
- case FC_CYRILL:
- case FC_KOI8:
- case FC_HEBREW:
- case FC_GREEK:
- case FC_9LATIN:
- return(96);
-
- case FC_NEXT:
- case FC_CP437:
- case FC_CP850:
- case FC_CP852:
- case FC_CP855:
- case FC_CP862:
- case FC_CP866:
- case FC_CP1251:
- case FC_APPQD:
- return(128);
-#ifdef KANJI
- case FC_JIS7:
- return(-94);
- case FC_SHJIS:
- return(-128);
- case FC_JEUC:
- case FC_JDEC:
- return(-96);
-#endif /* KANJI */
- case FC_CP858:
- default:
- return(-1);
- }
-#endif /* UNICODE */
-}
-#endif /* NOLOCAL */
-
-/*
- S E T X L A T Y P E -- Set Translation Type
-
- Sets global xlatype to indicate which kind of translation:
-
- XLA_NONE No translation
- XLA_BYTE Byte-for-Byte translation
- XLA_JAPAN Japanese Kanji translation
- XLA_UNICODE Unicode translations
-
- And sets up the appropriate translation function pointers as follows:
-
- For no translation:
- All function pointers are NULL.
-
- For Byte-for-Byte transation:
- rx = TCS to FCS (these functions are in this module...)
- sx = FCS to TCS
-
- For Unicode translations:
- xfu = FCS to UCS (these functions are in ckcuni.c...)
- xtu = TCS to UCS
- xuf = UCS to FCS
- xut = UCS to TCS
-*/
-VOID
-setxlatype(tcs, fcs) int tcs, fcs; {
-#ifdef UNICODE
- xfu = NULL; /* Unicode <-> TCS/FCS functions */
- xtu = NULL;
- xuf = NULL;
- xut = NULL;
-#endif /* UNICODE */
- rx = sx = NULL;
- debug(F101,"setxlatype fcs","",fcs);
- debug(F101,"setxlatype tcs","",tcs);
-
- if (tcs < 0 || tcs > MAXTCSETS) {
- debug(F101,"setxlatype bad tcs","",tcs);
- return;
- }
- if (fcs < 0 || fcs > MAXFCSETS) {
- debug(F101,"setxlatype bad fcs","",fcs);
- return;
- }
- if (tcs == TC_TRANSP || xfrxla == 0) { /* Transfer charset TRANSPARENT */
- debug(F101,"setxlatype transparent because TCS==Transparent","",tcs);
- xlatype = XLA_NONE; /* Translation type is None */
-#ifdef UNICODE
- /* If any of our charsets is Unicode we use Unicode functions */
- /* even if TCS and FCS are the same because of BOM and byte swapping */
- } else if (tcs == TC_UCS2 || tcs == TC_UTF8 ||
- fcs == FC_UCS2 || fcs == FC_UTF8) {
- debug(F101,"setxlatype Unicode tcs","",tcs);
- debug(F101,"setxlatype Unicode fcs","",fcs);
- /* Unicode <-> TCS/FCS functions */
- xfu = xl_fcu[fcs]; /* FCS -> UCS */
- xtu = xl_tcu[tcs]; /* TCS -> UCS */
- xuf = xl_ufc[fcs]; /* UCS -> FCS */
- xut = xl_utc[tcs]; /* UCS -> TCS */
- xlatype = XLA_UNICODE; /* Translation type is Unicode */
-#ifdef COMMENT
- /* These make trouble in 64-bit land */
- debug(F001,"setxlatype Unicode xfu","",(unsigned)xfu);
- debug(F001,"setxlatype Unicode xuf","",(unsigned)xuf);
-#endif /* COMMENT */
-#endif /* UNICODE */
- } else if (cseqtab[tcs] == fcs) { /* Or if TCS == FCS */
- debug(F101,"setxlatype transparent because TCS==FCS","",tcs);
- xlatype = XLA_NONE; /* translation type is also None */
-#ifdef KANJI
- /* Otherwise if any of them is Japanese, we use Kanji functions */
- } else if (tcs == TC_JEUC || fcsinfo[fcs].alphabet == AL_JAPAN) {
- debug(F101,"setxlatype Japanese tcs","",tcs);
- debug(F101,"setxlatype Japanese fcs","",fcs);
- xlatype = XLA_JAPAN; /* Translation type is Japanese */
-#endif /* KANJI */
- /* Otherwise we use byte functions */
- } else { /* Otherwise... */
- rx = xlr[tcs][fcs]; /* Input translation function */
- sx = xls[tcs][fcs]; /* Output translation function */
- debug(F101,"setxlatype Byte tcs","",tcs);
- debug(F101,"setxlatype Byte fcs","",fcs);
- xlatype = XLA_BYTE; /* Translation type is Byte */
- }
- debug(F101,"setxlatype xlatype","",xlatype);
-}
-
-/* Set up translation between two file character sets with UCS intermediate */
-
-#ifdef UNICODE
-VOID
-initxlate(csin, csout) int csin, csout; {
- xfu = NULL;
- xtu = NULL;
- xuf = NULL;
- xut = NULL;
-
- debug(F101,"initxlate csin","",csin);
- debug(F101,"initxlate csout","",csout);
-
- if (csin < 0 || csin > MAXFCSETS) {
- debug(F101,"initxlate bad csin","",csin);
- return;
- }
- if (csout < 0 || csout > MAXFCSETS) {
- debug(F101,"initxlate bad csout","",csout);
- return;
- }
- if (csin == csout && csin != FC_UCS2) {
- xlatype = XLA_NONE; /* Translation type is None */
- return;
- }
- xlatype = XLA_UNICODE; /* Translation type is Unicode */
- xfu = xl_fcu[csin]; /* FCS -> UCS */
- xuf = xl_ufc[csout]; /* UCS -> FCS */
- xpnbyte(-1,0,0,NULL); /* Reset UCS-2 */
-#ifdef COMMENT
- debug(F001,"initxlate Unicode xfu","",(unsigned)xfu);
- debug(F001,"initxlate Unicode xuf","",(unsigned)xuf);
-#endif /* COMMENT */
- debug(F101,"initxlate xlatype","",xlatype);
-}
-#endif /* UNICODE */
-
-int csetsinited = 0;
-
-VOID
-initcsets() { /* Routine to reset or initialize */
- int i; /* character-set associations. */
-
-#ifdef UNICODE
- if (ucsorder < 0) /* For creating UCS-2 files. */
- ucsorder = byteorder;
- if (ucsorder < 0)
- ucsorder = 0;
- if (fileorder < 0) /* For reading UCS-2 files. */
- fileorder = ucsorder;
-#endif /* UNICODE */
-
- debug(F101,"initcsets nxls","",nxls);
- debug(F101,"initcsets nxlr","",nxlr);
-
- debug(F101,"initcsets TERM LOCAL CSET","",tcsl);
- debug(F101,"initcsets TERM REMOTE CSET","",tcsr);
-
- for (i = 0; i <= MAXFCSETS; i++) /* First clear them all... */
- afcset[i] = -1;
- for (i = 0; i <= MAXTCSETS; i++)
- axcset[i] = -1;
-
- /* Now set specific defaults for incoming files */
-
- xlatype = XLA_NONE;
-
- axcset[TC_TRANSP] = FC_TRANSP;
- axcset[TC_USASCII] = FC_USASCII;
-
-#ifdef OS2
- switch (fcharset) {
- case FC_CP850:
- case FC_CP858:
- case FC_CP437:
- case FC_1LATIN:
- axcset[TC_1LATIN] = fcharset;
- break;
- default:
- axcset[TC_1LATIN] = FC_CP850;
- }
-#else
-#ifdef HPUX
- axcset[TC_1LATIN] = FC_HPR8;
-#else
-#ifdef VMS
- axcset[TC_1LATIN] = FC_DECMCS;
-#else
-#ifdef NEXT
- axcset[TC_1LATIN] = FC_NEXT;
-#else
-#ifdef datageneral
- axcset[TC_1LATIN] = FC_DGMCS;
-#else
- /* Should we use code pages on some PC based UNIXes? */
- axcset[TC_1LATIN] = FC_1LATIN;
-#endif /* datageneral */
-#endif /* NEXT */
-#endif /* VMS */
-#endif /* HPUX */
-#endif /* OS2 */
-
-#ifdef OS2
- axcset[TC_2LATIN] = FC_CP852;
- axcset[TC_CYRILL] = FC_CP866;
- axcset[TC_JEUC] = FC_SHJIS;
- axcset[TC_HEBREW] = FC_CP862;
- axcset[TC_GREEK] = FC_CP869;
- axcset[TC_9LATIN] = FC_CP858;
- axcset[TC_UCS2] = FC_UCS2;
- axcset[TC_UTF8] = FC_UCS2;
-#else
- axcset[TC_2LATIN] = FC_2LATIN;
- axcset[TC_CYRILL] = FC_CYRILL;
- axcset[TC_JEUC] = FC_JEUC;
- axcset[TC_HEBREW] = FC_HEBREW;
- axcset[TC_GREEK] = FC_GREEK;
- axcset[TC_9LATIN] = FC_9LATIN;
- axcset[TC_UCS2] = FC_UTF8;
- axcset[TC_UTF8] = FC_UTF8;
-#endif /* OS2 */
-
- /* And for outbound files */
-
- afcset[FC_USASCII] = TC_USASCII;
- afcset[FC_UKASCII] = TC_1LATIN;
- afcset[FC_DUASCII] = TC_1LATIN;
- afcset[FC_FIASCII] = TC_1LATIN;
- afcset[FC_FRASCII] = TC_1LATIN;
- afcset[FC_FCASCII] = TC_1LATIN;
- afcset[FC_GEASCII] = TC_1LATIN;
- afcset[FC_HUASCII] = TC_2LATIN;
- afcset[FC_ITASCII] = TC_1LATIN;
- afcset[FC_NOASCII] = TC_1LATIN;
- afcset[FC_POASCII] = TC_1LATIN;
- afcset[FC_SPASCII] = TC_1LATIN;
- afcset[FC_SWASCII] = TC_1LATIN;
- afcset[FC_CHASCII] = TC_1LATIN;
- afcset[FC_1LATIN] = TC_1LATIN;
- afcset[FC_2LATIN] = TC_2LATIN;
- afcset[FC_DECMCS] = TC_1LATIN;
- afcset[FC_NEXT] = TC_1LATIN;
- afcset[FC_CP437] = TC_1LATIN;
- afcset[FC_CP850] = TC_1LATIN;
- afcset[FC_CP852] = TC_2LATIN;
- afcset[FC_APPQD] = TC_1LATIN;
- afcset[FC_DGMCS] = TC_1LATIN;
- afcset[FC_HPR8] = TC_1LATIN;
- afcset[FC_CYRILL] = TC_CYRILL;
- afcset[FC_CP866] = TC_CYRILL;
- afcset[FC_KOI7] = TC_CYRILL;
- afcset[FC_KOI8] = TC_CYRILL;
- afcset[FC_JIS7] = TC_JEUC;
- afcset[FC_SHJIS] = TC_JEUC;
- afcset[FC_JEUC] = TC_JEUC;
- afcset[FC_JDEC] = TC_JEUC;
- afcset[FC_HE7] = TC_HEBREW;
- afcset[FC_HEBREW] = TC_HEBREW;
- afcset[FC_CP862] = TC_HEBREW;
- afcset[FC_ELOT] = TC_GREEK;
- afcset[FC_GREEK] = TC_GREEK;
- afcset[FC_CP869] = TC_GREEK;
- afcset[FC_9LATIN] = TC_9LATIN;
- afcset[FC_CP923] = TC_9LATIN;
- afcset[FC_CP858] = TC_9LATIN;
- afcset[FC_CP855] = TC_CYRILL;
- afcset[FC_CP1251] = TC_CYRILL;
- afcset[FC_BULGAR] = TC_CYRILL;
- afcset[FC_CP1250] = TC_2LATIN;
- afcset[FC_MAZOVIA] = TC_2LATIN;
- afcset[FC_UCS2] = TC_UTF8;
- afcset[FC_UTF8] = TC_UTF8;
-
- afcset[FC_KOI8R] = TC_CYRILL;
- afcset[FC_KOI8U] = TC_CYRILL;
- afcset[FC_CP1252] = TC_1LATIN;
-
- csetsinited++;
- return;
-}
-#endif /* NOCSETS */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckuxla.h b/ckermit-9.0.302-build/ckermit-9.0.302/ckuxla.h
deleted file mode 100644
index a3cd1a5..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckuxla.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- File CKUXLA.H
-
- C-Kermit language and character-set support for UNIX, VMS, OS/2,
- AOS/VS, and other systems.
-
- This file should be used as a template for the language support files
- for other C-Kermit implementations -- Macintosh, etc.
-*/
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
-*/
-
-#ifndef CKUXLA_H
-#define CKUXLA_H
-
-/* Codes for file character sets */
-
-/* ISO 646 and other ISO-646-like 7-bit sets */
-
-#define FC_USASCII 0 /* US ASCII */
-#define FC_UKASCII 1 /* United Kingdom ASCII */
-#define FC_DUASCII 2 /* Dutch ISO 646 NRC */
-#define FC_FIASCII 3 /* Finnish ISO 646 NRC */
-#define FC_FRASCII 4 /* French ISO 646 NRC */
-#define FC_FCASCII 5 /* French Canadian ISO 646 NRC */
-#define FC_GEASCII 6 /* German ISO 646 NRC */
-#define FC_HUASCII 7 /* Hungarian ISO 646 NRC */
-#define FC_ITASCII 8 /* Italian *ISO 646 NRC */
-#define FC_NOASCII 9 /* Norwegian and Danish ISO 646 NRC */
-#define FC_POASCII 10 /* Portuguese ISO 646 NRC */
-#define FC_SPASCII 11 /* Spanish ISO 646 NRC */
-#define FC_SWASCII 12 /* Swedish ISO 646 NRC */
-#define FC_CHASCII 13 /* Swiss ISO 646 NRC */
-
-/* 8-bit Roman character sets */
-
-#define FC_1LATIN 14 /* ISO 8859-1 Latin Alphabet 1 */
-#define FC_2LATIN 15 /* ISO 8859-2 Latin Alphabet 2 */
-#define FC_DECMCS 16 /* DEC Multinational Character Set */
-#define FC_NEXT 17 /* NeXT workstation character set */
-#define FC_CP437 18 /* IBM PC Code Page 437 */
-#define FC_CP850 19 /* IBM PC Code Page 850 */
-#define FC_CP852 20 /* IBM PC Code Page 852 */
-#define FC_APPQD 21 /* Apple Quickdraw */
-#define FC_DGMCS 22 /* Data General International Character Set */
-#define FC_HPR8 23 /* HP Roman8 */
-
-/* Cyrillic sets */
-
-#define FC_CYRILL 24 /* ISO 8859-5 Latin/Cyrillic */
-#define FC_CP866 25 /* PC Code Page 866 Cyrillic */
-#define FC_KOI7 26 /* KOI-7 = Short KOI */
-#define FC_KOI8 27 /* KOI-8 */
-
-/* Japanese sets */
-
-#define FC_JIS7 28 /* JIS-7 */
-#define FC_SHJIS 29 /* Shifted JIS = CP932 */
-#define FC_JEUC 30 /* Japanese EUC (JAE) */
-#define FC_JDEC 31 /* Japanese DEC Kanji */
-
-/* Hebrew sets */
-
-#define FC_HE7 32 /* 7-Bit DEC Hebrew */
-#define FC_HEBREW 33 /* 8-Bit ISO 8859-8 Latin/Hebrew */
-#define FC_CP862 34 /* Hebrew PC Code Page */
-
-/* Greek sets */
-
-#define FC_ELOT 35 /* 7-Bit ELOT 927 Greek */
-#define FC_GREEK 36 /* 8-Bit ISO 8859-7 Latin/Greek */
-#define FC_CP869 37 /* Greek PC Code Page */
-
-/* New Roman sets with Euro symbol */
-
-#define FC_9LATIN 38 /* ISO 8859-15 Latin Alphabet 9 */
-#define FC_CP923 38 /* Same as Latin-9 */
-#define FC_CP858 39 /* Western Europe with Euro */
-
-/* Other new additions */
-
-#define FC_CP855 40 /* Cyrillic PC Code Page */
-#define FC_CP1251 41 /* Cyrillic Windows */
-#define FC_BULGAR 42 /* Bulgarian PC code page */
-#define FC_CP1250 43 /* Latin 2 Windows (different from Latin-2)*/
-#define FC_MAZOVIA 44 /* Polish Mazovia PC code page */
-
-/* Unicode */
-
-#define FC_UCS2 45 /* ISO-10646 / Unicode UCS-2 */
-#define FC_UTF8 46 /* ISO-10646 / Unicode UTF-8 */
-
-/* Recent additions */
-
-#define FC_KOI8R 47 /* KOI8-R (RFC1489) - Russian + boxdrawing */
-#define FC_KOI8U 48 /* KOI8-U (RFC2319) - Ukrainian + boxdrawing */
-#define FC_CP1252 49 /* Latin 1 Windows */
-
-#define MAXFCSETS 49 /* Highest file character set number */
-
-#ifdef OS2
-#define FC_DECSPEC 253 /* Not real character-sets */
-#define FC_DECTECH 252
-#endif /* OS2 */
-
-#ifdef UNICODE
-_PROTOTYP( VOID initxlate, (int, int) );
-#endif /* UNICODE */
-
-#endif /* CKUXLA_H */
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ckwart.c b/ckermit-9.0.302-build/ckermit-9.0.302/ckwart.c
deleted file mode 100644
index 2f3bb75..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ckwart.c
+++ /dev/null
@@ -1,746 +0,0 @@
-#include "ckcsym.h"
-char *wartv = "Wart Version 2.14, 10 Nov 1999";
-
-#define CKWART_C
-
-#ifdef MDEBUG
-/* Use the real ones in this module only */
-#ifdef malloc
-#undef malloc
-#endif /* malloc */
-#ifdef calloc
-#undef calloc
-#endif /* calloc */
-#ifdef realloc
-#undef realloc
-#endif /* realloc */
-#ifdef free
-#undef free
-#endif /* free */
-#endif /* MDEBUG */
-
-#ifdef MAC
-#define VOID void
-#endif /* MAC */
-
-/* W A R T */
-
-/*
- A small subset of "lex".
-
- Authors: Jeff Damens, Frank da Cruz
- Columbia University Center for Computing Activites.
- First released November 1984.
- Copyright (C) 1984, 2009,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-
-/*
- * input format is:
- * lines to be copied | %state <state names...>
- * %%
- * <state> | <state,state,...> CHAR { actions }
- * ...
- * %%
- * more lines to be copied
- */
-
-#include "ckcdeb.h" /* Includes */
-
-#ifdef STRATUS
-/* Actually call printf, not our printf-catcher for Kermit */
-#ifdef printf
-#undef printf
-#endif /* printf */
-#ifdef fprintf
-#undef fprintf
-#endif /* fprintf */
-#endif /* STRATUS */
-
-#ifdef MAC
-/* Same deal for Macintosh */
-#ifdef printf
-#undef printf
-#endif /* printf */
-#ifdef fprintf
-#undef fprintf
-#endif /* fprintf */
-#endif /* MAC */
-
-#ifdef UNIX
-/* And UNIX */
-#ifdef printf
-#undef printf
-#endif /* printf */
-#ifdef fprintf
-#undef fprintf
-#endif /* fprintf */
-#endif /* UNIX */
-/*
- The following "char" should be changed to "short", "int", or "long" if your
- wart program will generate more than 127 states. Since wart is used mainly
- with C-Kermit, which has about 80 states, "char" is adequate. This keeps
- the program about 3K-4K smaller, which can be critical on 16-bit
- architectures.
-*/
-#ifdef IRIX60
-/*
- Also use short or int if your compiler complains inordinately about
- "integer conversion resulted in a change of sign"...
-*/
-#define TBL_TYPE "short" /* C data type of state table */
-#else
-#define TBL_TYPE "char" /* C data type of state table */
-#endif /* IRIX60 */
-
-#define C_L 014 /* Formfeed */
-
-#define SEP 1 /* Token types */
-#define LBRACK 2
-#define RBRACK 3
-#define WORD 4
-#define COMMA 5
-
-/* Storage sizes */
-
-#define MAXSTATES 50 /* max number of states */
-#define MAXWORD 50 /* max # of chars/word */
-#define SBYTES ((MAXSTATES+6)/8) /* # of bytes for state bitmask */
-
-/* Name of wart function in generated program */
-
-#ifndef FNAME
-#define FNAME "wart"
-#endif /* FNAME */
-
-/* Structure for state information */
-
-struct transx {
- CHAR states[SBYTES]; /* included states */
- int anyst; /* true if this good from any state */
- CHAR inchr; /* input character */
- int actno; /* associated action */
- struct transx *nxt;
-}; /* next transition */
-typedef struct transx *trans;
-
-/* Function prototypes */
-
-_PROTOTYP( VOID setwstate, (int, trans) );
-_PROTOTYP( int teststate, (int, trans) );
-_PROTOTYP( trans rdinput, (FILE *, FILE *) );
-_PROTOTYP( VOID initial, (FILE *, FILE *) );
-_PROTOTYP( int isin, (char *, int) );
-_PROTOTYP( int isword, (int) );
-_PROTOTYP( VOID rdword, (FILE *, char *) );
-_PROTOTYP( VOID rdstates, (FILE *, FILE *) );
-_PROTOTYP( trans newtrans, (void) );
-_PROTOTYP( trans rdrules, (FILE *, FILE *) );
-_PROTOTYP( VOID statelist, (FILE *, trans) );
-_PROTOTYP( VOID copyact, (FILE *, FILE *, int) );
-_PROTOTYP( int faction, (trans, int, int) );
-_PROTOTYP( VOID emptytbl, (void) );
-_PROTOTYP( VOID addaction, (int, int, int) );
-_PROTOTYP( VOID writetbl, (FILE *) );
-_PROTOTYP( VOID warray, (FILE *, char *, int [], int, char *) );
-_PROTOTYP( VOID prolog, (FILE *) );
-_PROTOTYP( VOID epilogue, (FILE *) );
-_PROTOTYP( VOID copyrest, (FILE *, FILE *) );
-_PROTOTYP( int gettoken, (FILE *) );
-_PROTOTYP( VOID rdcmnt, (FILE *) );
-_PROTOTYP( VOID clrhash, (void) );
-_PROTOTYP( int hash, (char *) );
-_PROTOTYP( VOID enter, (char *, int) );
-_PROTOTYP( int lkup, (char *) );
-_PROTOTYP( static char* copy, (char *s) );
-
-/* Variables and tables */
-
-/* lt 1992-10-08 Begin
- * provide definition for deblog variable
- * ckcdeb.h declares as extern. DECC AXP is strict about ref/def model
- * Variable is unused herein, to the best of my knowledge.
- */
-#ifdef VMS
-int deblog;
-#endif /* VMS */
-/* lt 1992-10-08 End
- */
-
-static int lines, nstates, nacts;
-
-static char tokval[MAXWORD];
-
-static int tbl[MAXSTATES*96];
-
-char *tbl_type = TBL_TYPE;
-
-char *txt1 = "\n#define BEGIN state =\n\nint state = 0;\n\nint\n";
-
-char *fname = FNAME; /* Generated function name goes here */
-
-/* rest of program... */
-
-char *txt2 = "()\n\
-{\n\
- int c,actno;\n\
- extern ";
-
-/* Data type of state table is inserted here (short or int) */
-
-char *txt2a =
-" tbl[];\n\
- while (1) {\n\
- c = input() - 32;\n\
- debug(F000,\"PROTO input\",ckitoa(state),c+32);\n\
- if (c < 0 || c > 95) c = 0;\n";
-
-char *txt2b = " if ((actno = tbl[c + state*96]) != -1)\n\
- switch(actno) {\n";
-
-/* this program's output goes here, followed by final text... */
-
-char *txt3 = "\n }\n }\n}\n\n";
-
-
-/*
- * turn on the bit associated with the given state
- *
- */
-VOID
-setwstate(state,t) int state; trans t; {
- int idx,msk;
- idx = state/8; /* byte associated with state */
- msk = 0x80 >> (state % 8); /* bit mask for state */
- t->states[idx] |= msk;
-}
-
-/*
- * see if the state is involved in the transition
- *
- */
-int
-teststate(state,t) int state; trans t; {
- int idx,msk;
- idx = state/8;
- msk = 0x80 >> (state % 8);
- return(t->states[idx] & msk);
-}
-
-
-/*
- * read input from here...
- *
- */
-
-trans
-rdinput(infp,outfp) FILE *infp,*outfp; {
- trans x;
- lines = 1; /* line counter */
- nstates = 0; /* no states */
- nacts = 0; /* no actions yet */
- fprintf(outfp,"\n%c* WARNING -- This C source program generated by ",'/');
- fprintf(outfp,"Wart preprocessor. */\n");
- fprintf(outfp,"%c* Do not edit this file; edit the Wart-format ",'/');
- fprintf(outfp,"source file instead, */\n");
- fprintf(outfp,"%c* and then run it through Wart to produce a new ",'/');
- fprintf(outfp,"C source file. */\n\n");
- fprintf(outfp,"%c* Wart Version Info: */\n",'/');
- fprintf(outfp,"char *wartv = \"%s\";\n\n",wartv);
-
- initial(infp,outfp); /* read state names, initial defs */
- prolog(outfp); /* write out our initial code */
- x = rdrules(infp,outfp); /* read rules */
- epilogue(outfp); /* write out epilogue code */
- return(x);
-}
-
-
-/*
- * initial - read initial definitions and state names. Returns
- * on EOF or %%.
- *
- */
-VOID
-initial(infp,outfp) FILE *infp, *outfp; {
- int c;
- char wordbuf[MAXWORD];
- while ((c = getc(infp)) != EOF) {
- if (c == '%') {
- rdword(infp,wordbuf);
- if (strcmp(wordbuf,"states") == 0)
- rdstates(infp,outfp);
- else if (strcmp(wordbuf,"%") == 0) return;
- else fprintf(outfp,"%%%s",wordbuf);
- }
- else putc(c,outfp);
- if (c == '\n') lines++;
- }
-}
-
-/*
- * boolean function to tell if the given character can be part of
- * a word.
- *
- */
-int
-isin(s,c) char *s; int c; {
- for (; *s != '\0'; s++)
- if (*s == (char) c) return(1);
- return(0);
-}
-int
-isword(c) int c; {
- static char special[] = ".%_-$@"; /* these are allowable */
- return(isalnum(c) || isin(special,c));
-}
-
-/*
- * read the next word into the given buffer.
- *
- */
-VOID
-rdword(fp,buf) FILE *fp; char *buf; {
- int len = 0,c;
- while (isword(c = getc(fp)) && ++len < MAXWORD) *buf++ = (char) c;
- *buf++ = '\0'; /* tie off word */
- ungetc(c,fp); /* put break char back */
-}
-
-/*
- * read state names, up to a newline.
- *
- */
-VOID
-rdstates(fp,ofp) FILE *fp,*ofp; {
- int c;
- char wordbuf[MAXWORD];
- while ((c = getc(fp)) != EOF && c != '\n') {
- if (isspace(c) || c == C_L) continue; /* skip whitespace */
- ungetc(c,fp); /* put char back */
- rdword(fp,wordbuf); /* read the whole word */
- enter(wordbuf,++nstates); /* put into symbol tbl */
- fprintf(ofp,"#define %s %d\n",wordbuf,nstates);
- }
- lines++;
-}
-
-/*
- * allocate a new, empty transition node
- *
- */
-trans
-newtrans() {
- trans new;
- int i;
- new = (trans) malloc(sizeof (struct transx));
- for (i=0; i<SBYTES; i++) new->states[i] = 0;
- new->anyst = 0;
- new->nxt = NULL;
- return(new);
-}
-
-
-/*
- * read all the rules.
- *
- */
-
-trans
-rdrules(fp,out) FILE *fp,*out; {
- trans head,cur,prev;
- int curtok;
- head = cur = prev = NULL;
- while ((curtok = gettoken(fp)) != SEP)
-
- switch(curtok) {
- case LBRACK:
- if (cur == NULL)
- cur = newtrans();
- else
- fatal("duplicate state list");
- statelist(fp,cur); /* set states */
- continue; /* prepare to read char */
-
- case WORD:
- if ((int)strlen(tokval) != 1)
- fatal("multiple chars in state");
- if (cur == NULL) {
- cur = newtrans();
- cur->anyst = 1;
- }
- cur->actno = ++nacts;
- cur->inchr = (char) (tokval[0] - 32);
- if (head == NULL)
- head = cur;
- else
- prev->nxt = cur;
- prev = cur;
- cur = NULL;
- copyact(fp,out,nacts);
- break;
- default: fatal("bad input format");
- }
- return(head);
-}
-
-/*
- * read a list of (comma-separated) states, set them in the
- * given transition.
- *
- */
-VOID
-statelist(fp,t) FILE *fp; trans t; {
- int curtok,sval;
- curtok = COMMA;
- while (curtok != RBRACK) {
- if (curtok != COMMA) fatal("missing comma");
- if ((curtok = gettoken(fp)) != WORD) fatal("missing state name");
- if ((sval = lkup(tokval)) == -1) {
- fprintf(stderr,"state %s undefined\n",tokval);
- fatal("undefined state");
- }
- setwstate(sval,t);
- curtok = gettoken(fp);
- }
-}
-
-/*
- * copy an action from the input to the output file
- *
- */
-VOID
-copyact(inp,outp,actno) FILE *inp,*outp; int actno; {
- int c,bcnt;
- fprintf(outp,"case %d:\n",actno);
- while (c = getc(inp), (isspace(c) || c == C_L))
- if (c == '\n') lines++;
- if (c == '{') {
- bcnt = 1;
- fputs(" {",outp);
- while (bcnt > 0 && (c = getc(inp)) != EOF) {
- if (c == '{') bcnt++;
- else if (c == '}') bcnt--;
- else if (c == '\n') lines++;
- putc(c,outp);
- }
- if (bcnt > 0) fatal("action doesn't end");
- } else {
- while (c != '\n' && c != EOF) {
- putc(c,outp);
- c = getc(inp);
- }
- lines++;
- }
- fprintf(outp,"\n break;\n");
-}
-
-/*
- * find the action associated with a given character and state.
- * returns -1 if one can't be found.
- *
- */
-int
-faction(hd,state,chr) trans hd; int state,chr; {
- while (hd != NULL) {
- if (hd->anyst || teststate(state,hd))
- if (hd->inchr == ('.' - 32) || hd->inchr == (char) chr)
- return(hd->actno);
- hd = hd->nxt;
- }
- return(-1);
-}
-
-/*
- * empty the table...
- *
- */
-VOID
-emptytbl() {
- int i;
- for (i=0; i<nstates*96; i++) tbl[i] = -1;
-}
-
-/*
- * add the specified action to the output for the given state and chr.
- *
- */
-VOID
-addaction(act,state,chr) int act,state,chr; {
- tbl[state*96 + chr] = act;
-}
-
-VOID
-writetbl(fp) FILE *fp; {
- warray(fp,"tbl",tbl,96*(nstates+1),TBL_TYPE);
-}
-
-
-/*
- * write an array to the output file, given its name and size.
- *
- */
-VOID
-warray(fp,nam,cont,siz,typ) FILE *fp; char *nam; int cont[],siz; char *typ; {
- int i;
- fprintf(fp,"%s %s[] = {\n",typ,nam);
- for (i = 0; i < siz - 1; ) {
- fprintf(fp," %2d,",cont[i]);
- if ((++i % 16) == 0) putc('\n',fp);
- }
- fprintf(fp,"%2d\n};\n",cont[siz-1]);
-}
-
-#ifndef STRATUS
-#ifdef MAINTYPE
-/*
- If you get complaints about "main: return type is not blah",
- define MAINTYPE on the CC command line, e.g. "CFLAGS=-DMAINTYPE=int".
-*/
-MAINTYPE
-#else
-#ifdef CK_SCOV5
-int
-#else
-#ifdef __DECC
-#ifdef __ALPHA
-int
-#else
-VOID
-#endif /* __ALPHA */
-#else
-#ifdef STRATUS
-int
-#ifdef __GNUC__
-int
-#else
-/*
- The default case should be int, not VOID, but it's been this way for
- years (no doubt for a reason) and who knows how many builds would break
- if I changed it.
-*/
-VOID
-#endif /* __GNUC__ */
-#endif /* STRATUS */
-#endif /* __DECC */
-#endif /* CK_SCOV5 */
-#endif /* MAINTYPE */
-#endif /* STRATUS */
-main(argc,argv) int argc; char **argv; {
- trans head;
- int state,c;
- FILE *infile,*outfile;
-
- if (argc > 1) {
- if ((infile = fopen(argv[1],"r")) == NULL) {
- fprintf(stderr,"Can't open %s\n",argv[1]);
- fatal("unreadable input file");
- }
- } else infile = stdin;
-
- if (argc > 2) {
- if ((outfile = fopen(argv[2],"w")) == NULL) {
- fprintf(stderr,"Can't write to %s\n",argv[2]);
- fatal("bad output file");
- }
- } else outfile = stdout;
-
- clrhash(); /* empty hash table */
- head = rdinput(infile,outfile); /* read input file */
- emptytbl(); /* empty our tables */
- for (state = 0; state <= nstates; state++)
- for (c = 1; c < 96; c++) /* find actions, */
- addaction(faction(head,state,c),state,c); /* add to tbl */
- writetbl(outfile);
- copyrest(infile,outfile);
- printf("%d states, %d actions\n",nstates,nacts);
- exit(GOOD_EXIT);
-}
-
-
-/*
- * fatal error handler
- *
- */
-
-VOID
-fatal(msg) char *msg; {
- fprintf(stderr,"error in line %d: %s\n",lines,msg);
- exit(BAD_EXIT);
-}
-
-VOID
-prolog(outfp) FILE *outfp; {
- int c;
- while ((c = *txt1++) != '\0') putc(c,outfp);
- while ((c = *fname++) != '\0') putc(c,outfp);
- while ((c = *txt2++) != '\0') putc(c,outfp);
- while ((c = *tbl_type++) != '\0') putc(c,outfp);
- while ((c = *txt2a++) != '\0') putc(c,outfp);
- while ((c = *txt2b++) != '\0') putc(c,outfp);
-}
-
-VOID
-epilogue(outfp) FILE *outfp; {
- int c;
- while ((c = *txt3++) != '\0') putc(c,outfp);
-}
-
-VOID
-copyrest(in,out) FILE *in,*out; {
- int c;
- while ((c = getc(in)) != EOF) putc(c,out);
-}
-
-/*
- * gettoken - returns token type of next token, sets tokval
- * to the string value of the token if appropriate.
- *
- */
-
-int
-gettoken(fp) FILE *fp; {
- int c;
- while (1) { /* loop if reading comments... */
- do {
- c = getc(fp);
- if (c == '\n') lines++;
- } while ((isspace(c) || c == C_L)); /* skip whitespace */
- switch(c) {
- case EOF:
- return(SEP);
- case '%':
- if ((c = getc(fp)) == '%') return(SEP);
- tokval[0] = '%';
- tokval[1] = (char) c;
- rdword(fp,tokval+2);
- return(WORD);
- case '<':
- return(LBRACK);
- case '>':
- return(RBRACK);
- case ',':
- return(COMMA);
- case '/':
- if ((c = getc(fp)) == '*') {
- rdcmnt(fp); /* skip over the comment */
- continue;
- } else { /* and keep looping */
- ungetc(c,fp); /* put this back into input */
- c = '/'; /* put character back, fall thru */
- }
-
- default:
- if (isword(c)) {
- ungetc(c,fp);
- rdword(fp,tokval);
- return(WORD);
- } else fatal("Invalid character in input");
- }
- }
-}
-
-/*
- * skip over a comment
- *
- */
-
-VOID
-rdcmnt(fp) FILE *fp; {
- int c,star,prcnt;
- prcnt = star = 0; /* no star seen yet */
- while (!((c = getc(fp)) == '/' && star)) {
- if (c == EOF || (prcnt && c == '%')) fatal("Unterminated comment");
- prcnt = (c == '%');
- star = (c == '*');
- if (c == '\n') lines++;
- }
-}
-
-/*
- * symbol table management for wart
- *
- * entry points:
- * clrhash - empty hash table.
- * enter - enter a name into the symbol table
- * lkup - find a name's value in the symbol table.
- *
- */
-
-#define HASHSIZE 101 /* # of entries in hash table */
-
-struct sym {
- char *name; /* symbol name */
- int val; /* value */
- struct sym *hnxt; /* next on collision chain */
-} *htab[HASHSIZE]; /* the hash table */
-
-/*
- * empty the hash table before using it...
- *
- */
-VOID
-clrhash() {
- int i;
- for (i=0; i<HASHSIZE; i++) htab[i] = NULL;
-}
-
-/*
- * compute the value of the hash for a symbol
- *
- */
-int
-hash(name) char *name; {
- int sum;
- for (sum = 0; *name != '\0'; name++) sum += (sum + *name);
- sum %= HASHSIZE; /* take sum mod hashsize */
- if (sum < 0) sum += HASHSIZE; /* disallow negative hash value */
- return(sum);
-}
-
-/*
- * make a private copy of a string...
- *
- */
-static char*
-copy(s) char *s; {
- char *new;
- new = (char *) malloc((int)strlen(s) + 1);
- strcpy(new,s);
- return(new);
-}
-
-/*
- * enter state name into the hash table
- *
- */
-VOID
-enter(name,svalue) char *name; int svalue; {
- int h;
- struct sym *cur;
- if (lkup(name) != -1) {
- fprintf(stderr,"state \"%s\" appears twice...\n", name);
- exit(BAD_EXIT);
- }
- h = hash(name);
- cur = (struct sym *)malloc(sizeof (struct sym));
- cur->name = copy(name);
- cur->val = svalue;
- cur->hnxt = htab[h];
- htab[h] = cur;
-}
-
-/*
- * find name in the symbol table, return its value. Returns -1
- * if not found.
- *
- */
-int
-lkup(name) char *name; {
- struct sym *cur;
- for (cur = htab[hash(name)]; cur != NULL; cur = cur->hnxt)
- if (strcmp(cur->name,name) == 0) return(cur->val);
- return(-1);
-}
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/makefile b/ckermit-9.0.302-build/ckermit-9.0.302/makefile
deleted file mode 100644
index 9efe262..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/makefile
+++ /dev/null
@@ -1,8626 +0,0 @@
-# makefile / Makefile / ckuker.mak / CKUKER.MAK
-#
-# Sun Aug 21 10:33:08 2011
-BUILDID=20110821
-CKVER= "9.0.302"
-#
-# -- Makefile to build C-Kermit for UNIX and UNIX-like platforms --
-#
-# Copyright (C) 1985, 2011,
-# Trustees of Columbia University in the City of New York.
-# All rights reserved. See the C-Kermit COPYING.TXT file or the
-# copyright text in the ckcmai.c module for disclaimer and permissions.
-# In case you can't find the COPYING.TXT file, it contains the
-# Simplified 3-Clause BSD License, which is an Open Source license.
-#
-# Author: Frank da Cruz, Columbia University
-# 612 West 115th Street, New York NY 10025-7799, USA
-# Email: fdc@columbia.edu
-# Web: http://kermit.columbia.edu/
-# FTP: ftp://kermit.columbia.edu/kermit/
-#
-# Note: Author is no longer at Columbia University or at the 115th Street
-# address effective 1 July 2011. The email address should still work,
-# as well as the website and FTP addresses, for the foreseeable future.
-# For new developments, also check:
-#
-# http://www.columbia.edu/~fdc/kermit/
-#
-# Contributions from many others. Special thanks to Jeff Altman for the
-# secure-build targets, Peter Eichhorn, assyst GmbH, for the consolidated
-# HP-UX targets and the "uninstall" target, to Robert Lipe for the updated
-# and consolidated SCO UNIX / ODT / OSR5 targets, to Ric Anderson for the
-# IRIX 6.x targets, to Seth Theriault for major improvements to the
-# Mac OS X targets, and to Alexey Dokuchaev for FreeBSD 9.0.
-#
-# C-Kermit is written and produced by hand without any automated procedures
-# such as autoconf / automake / configure, although some of the targets below
-# (especially the linux target) inspect the environment and make some
-# decisions in the most portable way possible. The automated tools are not
-# used because (a) C-Kermit predates them, and (b) they are not portable to
-# all the platforms where C-Kermit must be (or once was) built, and (c) to
-# keep C-Kermit as independent as possible from external tools over which
-# we have no control.
-#
-# Most entries use the "xermit" target, which uses the select()-based CONNECT
-# module, ckucns.c. The "wermit" target uses the original fork()-based CONNECT
-# module, ckucon.c, which has some drawbacks but was portable to every Unix
-# variant whether it had TCP/IP or not (select() is part of the TCP/IP
-# library, which was not standard on older Unixes). If your target still uses
-# the "wermit" target, please try substituting the "xermit" one and if it
-# works, let us know (mailto:kermit-support@columbia.edu). When changing a
-# target over from wermit to xermit, also remove -DNOLOEARN.
-#
-# CAREFUL: Don't put the lowercase word "if", "define", or "end" as the first
-# word after the "#" comment introducer in the makefile, even if it is
-# separated by whitespace. Some versions of "make" understand these as
-# directives. Uppercase letters remove the danger, e.g. "# If you have..."
-#
-# WARNING: This is a huge makefile. Although this is less likely since the
-# turn of the century, some "make" programs might run out of memory. If this
-# happens to you, edit away the parts that do not apply to your platform and
-# try again.
-#
-# WARNING 2: In many cases this file invokes itself recursively, sometimes
-# several levels deep (as in the Linux targets); i.e. some targets are used
-# as 'subroutines' of other targets, with parameters passed by setting
-# environment variables. For that reason, don't use 'make -e'.
-#
-# Certain UNIX variations have their own separate makefiles:
-# . For 2.10 or 2.11 BSD on the DEC PDP-11, use ckubs2.mak.
-# . For Plan 9, use ckpker.mk.
-#
-# Separate build procedures are provided non-UNIX platforms: VMS, VOS,
-# AOS/VS, etc. See the ckaaaa.txt file or the Kermit website for details.
-#
-#
-# DIRECTIONS FOR UNIX
-#
-# Rename this file to "makefile" or "Makefile" if necessary. Pick out the
-# entry most appropriate for your UNIX version from the list below and then
-# give the appropriate "make" command, for example "make aix", "make macosx",
-# "make linux". If you experience any difficulties with the build procedure,
-# then please also read any comments that accompany the make entry itself
-# (search for the make entry name on the left margin).
-#
-# Other targets:
-# 'make install' is an installation script (read accompanying comments!).
-# 'make uninstall' undoes 'make install' (read accompanying comments!).
-# 'make clean' removes intermediate and object files.
-# 'make show' tells the default include and lib paths for secure builds.
-#
-# IMPORTANT:
-# For more detailed installation instructions, read the files ckuins.txt
-# and ckccfg.txt, also available at the Kermit website in HTML form:
-# http://www.columbia.edu/kermit/ckuins.html
-# http://www.columbia.edu/kermit/ckccfg.html
-#
-# For descriptions of known problems and limitations,
-# read the files ckcbwr.txt and ckubwr.txt (the "beware files") or:
-# http://www.columbia.edu/kermit/ckcbwr.html
-# http://www.columbia.edu/kermit/ckubwr.html
-#
-# Most targets build C-Kermit with its symbol table included. To reduce the
-# size of the executable program, add "LNKFLAGS=-s" to the end of your 'make'
-# command or to the makefile entry, or 'strip' the executable after
-# building. To further reduce the size after building, use 'mcs -d' if your
-# Unix version has such a command. For further details on size reduction, read
-# ckccfg.txt to find out how to remove features that you don't need.
-#
-# TCP/IP networking support: If your C-Kermit version does not include TCP/IP
-# networking, but your UNIX system does, try adding -DTCPSOCKET to the CFLAGS
-# of your makefile entry. If that doesn't work, look at some of the other
-# targets that include this flag for ideas about what libraries might need to
-# be included (typically -lsocket and/or -lBSD and/or -lnsl and/or -linet).
-# NOTE: In some cases (old versions of SCO or HP-UX), you might need not only
-# a C compiler, but also a "TCP/IP developers kit" for the required object
-# libraries and header files.
-#
-# Please report modifications, failures (preferably with fixes) or successes
-# to the author, fdc@columbia.edu.
-#
-# TARGETS FOR DIFFERENT UNIX PLATFORMS AND VERSIONS:
-#
-# + Marks those that have been built successfully for C-Kermit 9.0 or later.
-# - Those that once built OK but no longer do (e.g. too big).
-# ? Those that worked in a previous version but have not been tested recently.
-# --------------------------
-# Some commonly used targets:
-#
-# + "make linux" should work for any version of Linux on any hardware.
-# + "make linux+ssl" ditto, with OpenSSL security added.
-# + "make linux+krb5" ditto, with Kerberos 5 security added.
-# + "make linux+krb5+ssl" Linux with OpenSSL and Kerberos 5.
-# + "make netbsd", NetBSD, any version.
-# + "make netbsd+ssl", NetBSD with OpenSSL 0.9.7 or later.
-# + "make netbsd+krb5", NetBSD with Kerberos 5.
-# + "make netbsd+krb5+ssl", NetBSD with Kerberos 5 and OpenSSL 0.9.7 or later.
-# ? "make freebsd1" for FreeBSD 1.x
-# ? "make freebsd2" for FreeBSD 2.x
-# + "make freebsd3" for FreeBSD 3.x
-# ? "make freebsd4" for FreeBSD 4.0
-# + "make freebsd", FreeBSD 4.1 or later.
-# + "make freebsd+ssl", FreeBSD 5.0 or later with OpenSSL 0.9.7 or later.
-# + "make openbsd", OpenBSD 2.3 or later.
-# + "make openbsd+ssl", OpenBSD 2.3 or later with OpenSSL 0.9.7 or later.
-# + "make mirbsd", MirBSD.
-# + "make mirbsd+ssl", MirBSD with OpenSSL 0.9.7 or later.
-# + "make macosx" should work for any Mac OS X version 10.3.9 or later.
-# + "make macosx+krb5+openssl" Mac OS X 10.3.9 or later + Kerberos V + OpenSSL.
-# + "make aix" should work for any version of AIX 4.2 or later.
-# + "make aixg" should work for any version of AIX 4.2 or later, using gcc.
-# + "make aix+ssl" ditto, with OpenSSL (specifying SSLLIB and SSLINC)
-# + "make aix+ibmssl" ditto, with IBM OpenSSL
-# + "make solaris9", "make solaris10" for Solaris 9 or 10 with Sun cc.
-# + "make solaris9g", "make solaris10g" for Solaris 9 or 10 with gcc.
-# + "make solaris11" for Solaris 11 with Sun CC
-# + "make solaris11g" for Solaris 11 with gcc
-# + "make sco_osr600" for SCO OpenServer 6.0.0.
-#
-# For other current OSs such as Solaris, HP-UX, and SCO there are separate
-# targets for different combinations of OS version and compiler; see the
-# complete list. For older OS's see the complete list. If an old target
-# doesn't work in this release of C-Kermit you can get a previous release from
-# the Kermit FTP site: ftp://kermit.columbia.edu/kermit/
-#
-# SECURE TARGETS (versions that support authentication and encryption)
-# are described after the following list. Search for ******* below.
-#
-# --------------------------
-# Complete list (alphabetical):
-# ? for 386BSD (Jolix) 0.0, 0.1, "make 386bsd" (see comments in entry),
-# or (preferably, if it works) "make bsd44" or "make bsd44c".
-# ? for Acorn RISCiX, "make riscix" or "make riscix-gcc"
-# ? for Alliant FX/8 with Concentrix 4.1 or later, "make bsdlck"
-# ? for Altos 486, 586, 986 with Xenix 3.0, "make altos"
-# ? for Altos ACS68000, 8Mhz 68000, UNIX System 3 Rel 2, 512K, "make altos3"
-# ? for Amdahl UTS 2.4 on IBM 370 series & compatible mainframes, "make uts24"
-# ? for Amdahl UTSV IBM 370 series & compatible mainframes, "make utsv"
-# ? for Amdahl UTSV IBM 370 series mainframes with TCP/IP, "make utsvtcp"
-# ? for Amdahl mainframes with UNIX System V R 5.2.6b 580, "make sys3"
-# ? for Apollo Aegis 9.x, DOMAIN/IX 9.x, "make aegis"
-# (Last tested in C-Kermit 5A(189))
-# ? for Apollo DOMAIN/IX, if the above fails, try "make apollobsd"
-# ? for Apollo with SR10.0 or later, BSD environment, "make sr10-bsd"
-# ? for Apollo with SR10.0 or later, System V environment, "make sr10-s5r3"
-# ? for Apple Macintosh II with A/UX pre-3.0, "make aux", "auxgcc" or "auxufs"
-# ? for Apple Macintosh with A/UX 3.0 and gcc, "make aux3gcc" or aux3gccc
-# ? for Apple PowerMac with MkLinux, "make mklinux" (read Linux entry first)
-# ? for Apple PowerMac with LinuxPPC, "make linuxppc"
-# ? for Apple Macintosh with Minix 1.5.10, "make minix68k" or "make minixc68"
-# ? for Apple Macintosh with Mac OS X 1.0 (Rhapsody), "make macosx10"
-# (no curses), "make macosx10c" (curses), or "make macosx10nc" (ncurses).
-# Or "make macosx10ncx" (ncurses but "make macosx10nc" doesn't work).
-# ? for Apple Macintosh with Mac OS X 10.2, "make macosx102nc" (ncurses).
-# ? for Apple Macintosh with Mac OS X 10.3, "make macosx103"
-# ? for Apple Macintosh with Mac OS X 10.3.9 or later, "make macosx"
-# ? for Arix System 90 with AT&T SVR3, "make sys5r3na"
-# - for AT&T 6300 with IN/ix, "make sys5"
-# - for AT&T 6300 PLUS, "make att6300" or (with no debugging) "make att6300nd"
-# ? for AT&T 6386 WGS UNIX PC, "make sys5r3"
-# ? for AT&T 3B2, 3B20 systems, "make att3b2".
-# for AT&T 3B1, 7300 UNIX PC (see notes with the entries):
-# In C-Kermit 7.0, only the gcc entries work:
-# ? "make sys3upcg", "make sys3upcgc", "make att351gm"
-# The others fail with "too many defines" (usually in ckuusr.h):
-# - "make sys3upc", "make sys3upcold", "make sys3upcc", "make sys3upcx",
-# "make sys3upcm", "make att351m"
-# ? for AT&T System III/System V R2 or earlier, "make sys3" or "make sys3nid"
-# ? for AT&T System III/System V with Honey DanBer UUCP, "make sys3hdb"
-# ? for AT&T System V on DEC VAX, "make sys3" or "make sys5r3"
-# ? for AT&T System V R3, use "make sys5r3" or "make sys5r3c"
-# ? for AT&T System V/386 R3.2 built on Interactive 4.1.1, "make sys5r32is".
-# ? for AT&T System V/386 R320.0 Versyss Systems, use "make sys5r3"
-# or "make sys5r3c".
-# ? for AT&T System V R4, "make sys5r4", "make sys5r4sx", or "make sys5r4nx",
-# or if the ANSI C function prototyping makes trouble, add -DNOANSI,
-# as in "sys5r4sxna" entry
-# ? for AT&T (USL) System V R4.2 use the sys5r4* entries.
-# ? for Atari Falcon with MiNT, "make posix"
-# ? for Atari ST with Minix ST 1.5.10.3, "make minix68k" or "make minixc68"
-# ? for BBN C/70 with IOS 2.0, "make c70"
-# ? for BeBox with Be OS 1.x DR7, "make beboxdr7"
-# Compiles OK but doesn't link with default linker which is limited to 64K.
-# Links OK with "Code Warrior Gold". Many hacks in the source code need
-# to be removed when DR8 and later come out.
-# (Last tested in C-Kermit 6.0)
-# - for BeBox with Be OS 1.x DR8, "make bebox"
-# (Needed functions missing from operating system and/or not working.)
-# - for Bell Labs UNIX Version 6 (6th Edition), there is no makefile entry.
-# ? for Bell Labs UNIX Version 7 (7th Edition), "make v7" (but see notes below)
-# (last built successfully in C-Kermit 5A188)
-# ? for Bell Labs Research UNIX Version 10, "make bellv10"
-# (last built successfully in C-Kermit 6.0)
-# ? for Bell Labs / Lucent Plan 9, use separate makefile ckpker.mk:
-# can be built for Intel, MIPS, 680x0, and PowerPC (last built C-Kermit 7.0)
-# ? for BSDI BSD/386 1.x, "make bsdi"
-# ? for BSDI BSD/OS 2.x, "make bsdi2"
-# ? for BSDI BSD/OS 3.0 or 3.1, "make bsdi3"
-# ? for BSDI BSD/OS 4.x, "make bsdi4"
-# ? for BSDI BSD/OS 4.x, to build a binary that also works on FreeBSD,
-# "make bsdix".
-# ? for Berkeley Unix 2.4, "make v7" (but read v7 material below)
-# ? for Berkeley Unix 2.9 (DEC PDP-11 or Pro-3xx), "make bsd29"
-# - for Berkeley Unix 2.10, use ckubs2.mak (a separate makefile)
-# - for Berkeley Unix 2.11, use ckubs2.mak (a separate makefile)
-# This makefile is too big. Read the instructions in ckubs2.mak.
-# "make -f ckubs2.mak bsd210" or "make -f ckubs2.mak bsd211".
-# (last built successfully in C-Kermit 6.0 - later versions too big)
-# ? for Berkeley Unix 2.11 "make -f ckubs2.mak bsd210noicp" (no command parser)
-# ? for Berkeley Unix 4.1, "make bsd41"
-# ? for Berkeley Unix 4.2 on VAX, "make bsd42" or "make bsd42c"
-# ? for Berkeley Unix 4.2 or 4.3 with HoneyDanBer UUCP, "make bsdhdb"
-# ? for Berkeley Unix 4.3 on VAX, "make bsd43", "make bsd43nc".
-# ? for Berkeley Unix 4.3 on VAX, no networking "make bsd43nonet.
-# ? for Berkeley Unix 4.3 without acucntrl program, "make bsd42" or "bsd42c"
-# NOTE: all the C-Kermit 7.0 full builds for old BSDs fail with
-# "too many defines" in CPP, even on big architectures like VAX. This
-# can be worked around with a clever ruse. See comments at target.
-# ? for Berkeley Unix 4.3, command-line only, "make bsdm".
-# ? for Berkeley Unix 4.3-Tahoe, same as 4.3 BSD
-# ? for Berkeley Unix 4.3-Reno, "make bsd43" or "make bsd44" or "make bsd44c"
-# ? for Berkeley Unix 4.3-Carson City, "make bsd44" or "make bsd44c"
-# ? for Berkeley Unix 4.4-Networking/2 or -Alpha, "make bsd44" or "make bsd44c"
-# ? for Berkeley Unix 4.4, "make bsd44" or "make bsd44c"
-# ? for Berkeley Unix 4.4-Lite, "make bsd44" or "make bsd44c"
-# ? for Bull DPX/2 with BOS/X, "make bulldpx2"
-# ? for Cadmus, "make sys3"
-# for Caldera, see SCO, Linux.
-# ? for Callan Unistar, "make sys3"
-# ? for CDC VX/VE 5.2.1 System V emulation, "make vxve"
-# ? for Charles River Data Systems Universe 680x0 with UNOS 9.2, maybe
-# also other UNOS versions, "make crds"
-# ? for CIE Systems 680/20 with Regulus, "make cie"
-# ? for Commodore Amiga 3000UX Sys V R4, "make sys5r4sx"
-# ? for Commodore Amiga 3000UX Sys V R4 and TCP/IP, "make svr4amiganet"
-# ? for Commodore Amiga with Minix 1.5.10, "make minix68k" of "make minixc68"
-# ? for Concurrent/Masscomp with RTU 4.0 or later, BSD environment, "make
-# rtubsd", "make rtubsd2", "make rtubsd3" (depending on where ndir.h
-# is stored, see entries below).
-# ? for Concurrent/Masscomp with RTU 4.0 or later, System V R2, "make rtus5"
-# ? for Concurrent (Perkin-Elmer) 3200 series, "make sys5".
-# ? for Concurrent (Perkin-Elmer) 3200 series with <dirent.h>, "make ccop1"
-# ? for Concurrent PowerMAX OS SVR4, "make powermax"
-# ? for Consensys UNIX SV/386 R4V3, "make sys5r4sxtcpc" or "make sys5r4sx"
-# ? for Convergent with CTIX Sys V R2, "make sys5"
-# ? for Convergent with CTIX 6.4.1, "make ctix"
-# ? for Convex C1, "make convex"
-# ? for Convex C210 with Convex/OS 8, "make convex8"
-# ? for Convex C2 with Convex/OS 9.1, "make convex9"
-# ? for Convex C2 with Convex/OS 10.1 and gcc 2.x, "make convex10gcc"
-# ? for Cray Research X/MP or YMP or C90 with UNICOS 6.x (System V R3),
-# "make cray"
-# ? for Cray Research X/MP or YMP or C90 with UNICOS 7.x (System V R4),
-# "make cray"
-# ? for Cray Research X/MP or YMP or C90 with UNICOS 8.0 Alpha, "make cray8"
-# ? for Cray Research X/MP or Y-MP or C90 with UNICOS 9.0, "make cray9"
-# ? for Cray Computer Cray-2 or Cray3 with CSOS, "make craycsos"
-# ? for Cyber 910 (Silicon-Graphics Iris) with Irix 3.3, "irix33"
-# ? for Data General AViiON with DG/UX 5.4 before R3.00, "make dgux540"
-# or "make dgux540c" (compile ckwart separately if necessary)
-# ? for DG/UX 5.4 on AViiON Intel models, "make dgux540i" or dgux540ic.
-# ? for DG/UX 5.4R4.11 on AViiON, all models, "make dgux54411"
-# ? for DG/UX 5.4R4.20 on AViiON, all models, "make dgux54420"
-# ? for Data General AViiON with DG/UX 4.3x using Sys V-isms, "make dgux430"
-# ? for Data General AViiON with DG/UX 4.3x using BSD-isms, "make dgux430bsd"
-# ? for Data General AViiON, earlier UNIX versions,
-# "make sys5r3" (maybe compile ckwart separately, or "touch ckcpro.c")
-# ? for Data General MV systems with DG/UX, ???
-# ? for Data General MV systems with MV/UX, use AOS/VS C-Kermit (CKDKER.MAK)
-# ? for Data General MV systems with AOS/VS, use CKDKER.MAK (last = C-K 7.0)
-# ? for DEC PDP-11 with Berkeley UNIX 2.x, see Berkeley UNIX 2.x.
-# ? for DEC PDP-11 with Mini-UNIX (Bell 6th Edition for PDP-11 with no MMU),
-# probably no way to fit C-Kermit without I&D space.
-# ? for DEC PDP-11 with Ultrix-11 3.x, ??? (probably needs overlays)
-# ? for DEC VAX with Ultrix 1.x "make bsd"
-# ? for DEC VAX with Ultrix 2.x "make ultrix2x"
-# ? for DEC VAX or DECstation with Ultrix 3.0, 3.1, "make ultrix3x"
-# ? for DECstation or VAX with Ultrix 4.0 or 4.1, "make ultrix40"
-# ? for DECstation or VAX with Ultrix 4.2, "make ultrix42" or "make ultrix42c"
-# ? for DECstation or VAX with Ultrix 4.x, POSIX world, "make posix"
-# ? for DECstation or VAX with Ultrix 4.3, "make ultrix43".
-# ? for DECstation or VAX with Ultrix 4.4, "make ultrix44".
-# ? for DECstation 5000/50, /150 or /260 (R4x00 MIPS CPU), Ultrix 4.3A or later
-# "make ultrix43-mips3" or "make ultrix43c-mips3"
-# ? for DECstation (MIPS) with Berkeley Sprite, "make bsd44"?
-# ? for DECstation (MIPS) with OSF/1 V1.0 to 1.3, "make dec-osf"
-# ? for DEC Alpha with OSF/1 1.0 to 1.3, "make dec-osf"
-# ? for DEC PC 486 with OSF/1, "make dec-osf"
-# ? for DEC Alpha with OSF/1 2.x, "make dec-osf20"
-# ? for DEC Alpha with OSF/1 3.0, "make dec-osf30"
-# ? for DEC Alpha with Digital UNIX 3.2, "make du32"
-# ? for DEC Alpha with Digital UNIX 4.0-4.0D, "make du40" or "make du40gcc"
-# ? for DEC Alpha with Digital UNIX 4.0E or higher, see Tru64.
-# + for DEC Alpha with any version of DU or OSF/1, "make dec-osf1"
-# - for DEC Pro-350 with Pro/Venix V1.x, "make provx1" (version 5A is too big)
-# ? for DEC Pro-380 with Pro/Venix V2.0 (Sys V), "make sys3" or "make sys3nid"
-# ? for DEC Pro-380 with 2.9, 2.10, or 2.11 BSD, "make bsd29" or "make bsd210"
-# for DEC PDP-11 with 2.xBSD (use separate makefile ckubs2.mak)
-# ? for Dell UNIX Issue 2.x (= USL Sys V/386 R4.x + fixes), "make dellsys5r4"
-# or "make dellsys5r4c" (last tested in C-Kermit 5A).
-# ? for DIAB DS90 with DNIX (any version) create an empty <sys/file.h> if
-# this file does not already exist (or add -DNOFILEH to the make entry).
-# ? for DIAB DS90 with DNIX 5.2 (Sys V.2) or earlier, "make dnix",
-# "make dnixnd", or (to add curses and TCP/IP) "make dnixnetc",
-# ? for DIAB DS90 with DNIX 5.3 (Sys V.3), "make dnix5r3"
-# ? for DIAB DS90 with DNIX 5.3 (Sys V.3) and TCP/IP, "make dnix5r3net"
-# ? for DIAB DS90 with DNIX 5.3 2.2 (Sys V.3), ANSI C, "make dnix5r3ansi"
-# or, to include TCP/IP, "make dnix5r3ansinet",
-# but you have to fix a bug in /usr/include/stdlib.h first:
-# change "extern void free(char *str);" to "extern void free(void *str);"
-# ? for Dolphin Server Technology Triton 88/17 with SV/88 R3.2, "make sv88r32"
-# ? for Encore Multimax 310, 510 with Umax 4.2, "make umax42"
-# ? for Encore Multimax 310, 510 with Umax 4.3, "make umax43"
-# ? for Encore Multimax 310, 510 with Umax V 2.2, use Berkeley cc, "make bsd"
-# ? for Encore 88K with Umax V 5.2, "make encore88k"
-# ? for ESIX System V R4.0.3 or 4.04 with TCP/IP support, "make esixr4"
-# NOTE: You can also build on Unixware 2.x with "make esixr4", and run
-# on ESIX, but there you must first:
-# ln /usr/lib/libsocket.so /usr/lib/libsocket.so.1
-# ln /usr/lib/libnsl.so /usr/lib/libnsl.so.1
-# (This worked for C-Kermit 6.0 but does not work for 7.0)
-# (But you can probably still build a non-networking version this way)
-# ? for Everex STEP 386/25 Rev G with ESIX Sys V R3.2D, "make sys5r3"
-# ? for Fortune 32:16, For:Pro 1.8, "make ft18"
-# ? for Fortune 32:16, For:Pro 2.1, "make ft21"
-# ? for FPS 500 with FPX 4.1, "made bsd"
-# ? for FreeBSD 1.0, "make freebsd1"
-# ? for FreeBSD 2.x, "make freebsd2" (ncurses) or "make freebsd2c" (curses)
-# ? for FreeBSD 3.x, "make freebsd3" (ncurses) or "make freebsd3c" (curses)
-# ? for FreeBSD 4.0, "make freebsd40"
-# ? for FreeBSD 4.1 or later, "make freebsd"
-# + NOTE: Just use "make freebsd" for any reasonably recent FreeBSD version.
-# ? for Harris HCX-2900, "make sys5r3"
-# ? for Harris Night Hawk 88K or 68K with CX/UX pre-6.1, "make sys5r3"
-# ? for Harris Night Hawk 88K or 68K with CX/UX 6.1 or later, "make cx_ux"
-# ? for Heurikon, "make sys3"
-# ? for HP-3000, MPE/ix, "make posix"?
-# ? for HP-9000 Series 300 with 4.4BSD, "make bsd44"
-
-# NOTE: Most of the HP-UX targets were tested successfully in 2010.
-# Verification needed for C-Kermit 9.0 Beta.01...
-
-# ? for HP-9000 Series 500, HP-UX 5.21 and no networking "make hpux0500"
-# ? for HP-9000 Series 500, HP-UX 5.21 with WIN/TCP 1.2 "make hpux0500wintcp"
-# ? for HP-9000 Series, HP-UX 6.5, without long filenames,
-# "make hpux0650", "make hpux0650c" or "make hpux0650tcpc"
-# ? for HP-9000 Series, HP-UX 7.0 or later no long filenames, "make hpux0700sf"
-# or (to include tcp/ip, curses, etc) "make hpux0700sftcpc"
-# ? for HP-9000 Series with HP-UX 7.0, TCP/IP,long filenames,"make hpux0700lfn"
-# ? for HP-9000 300/400 Series (680x0) with HP-UX 8.0, TCP/IP, "make hpux0800"
-# or "make hpux0800c"
-# ? for HP-9000 700/800 Series (PA-RISC), HP-UX 8.0, TCP/IP, "make hpux0800pa"
-# or "make hpux0800pac"
-# ? for HP-9000 Series with HP-UX 8.0, no TCP/IP, long filenames,
-# "make hpux0800notcp"
-# ? for HP-9000 Series, HP-UX 9.0 - 9.10, TCP/IP, curses, restricted compiler
-# (no optimization, no ANSI), all models, "make hpux0900". Read the
-# hpux0900 entry below for more info.
-# ? for HP-9000 700 and 800 Series, HP-UX 9.x, TCP/IP, curses,
-# HP optimizing ANSI C compiler, "make hpux0900o700".
-# ? for HP-9000 with Motorola CPUs, HP-UX 9.x, TCP/IP, curses,
-# HP optimizing ANSI C compiler, "make hpux0900mot".
-# ? for HP-9000 on other CPUs, HP-UX 9.x, TCP/IP, curses,
-# HP optimizing ANSI C compiler, "make hpux0900o".
-# ? for HP-9000 series, HP-UX 9.x, TCP/IP, curses, gcc, all models,
-# "make hpux0900gcc"
-# ? for HP-9000 700/800 Series, HP-UX 10.00,10.01,10.10,10.20,10.30, TCP/IP,
-# curses, restricted compiler (no optimization, no ANSI) "make hpux1000".
-# ? for HP-9000 700/800 Series, HP-UX 10.00,10.01,10.10,10.20,10.30, TCP/IP,
-# curses, HP ANSI/optimizing compiler "make hpux1000o" or "make hpux1000o+"
-# ? for HP-9000 HP-UX 10.00 or later with gcc, "make hpux1000gcc"
-# ? for Trusted HP-UX 10.xx "make hpux1000t", "make hpux1000to",
-# or make hpux1000to+"
-# ? for HP-9000 700/800 Series, HP-UX 11.00,TCP/IP,curses, restricted compiler
-# (no optimization, no ANSI) "make hpux1100".
-# ? for HP-9000 700/800 Series, HP-UX 11.00,TCP/IP,curses, restricted compiler
-# HP ANSI/optimizing compiler "make hpux1100o" or "make hpux1100o+"
-# ? for Trusted HP-UX 11.xx "make hpux1100t", "make hpux1100to",
-# make hpux1100to+"
-# ? for HP-9000 PA-RISC models with NeXTSTEP 3.3, "make nextquadfat".
-# ? for HP-9000 PA-RISC models with OPENSTEP/Mach 4.1, "make nextquadfat".
-# ? for IBM 370 Series with IX/370, "make ix370"
-# ? for IBM 370 Series with AIX/370 1.2, "make aix370"
-# ? for IBM 370 Series with AIX/370 3.0, "make aix370"
-# ? for IBM 370 Series with AIX/ESA 2.1, "make aixesa"
-# - for IBM PC/AT 286 & compatibles with Mark Williams Coherent OS,
-# command-line-only version, "make coherent" (version 5A & later too big)
-# ? for IBM PC 386 & compatibles with Mark Williams Coherent OS,
-# minimum interactive version, "make coherentmi"
-# ? for IBM PC 386 & compatibles with Mark Williams Coherent OS,
-# full interactive version, prior to v4.2, "make coherentmax"
-# ? for IBM PC 386 & compatibles with Mark Williams Coherent OS 4.2,
-# "make coherent42"
-# ? for IBM PC 386 & compatibles with LynxOS 2.0 or 2.1, "make lynx21"
-# ? for IBM PC 386 & compatibles with LynxOS 2.2, "make lynx"
-# - for IBM PC/AT & compatibles with original MINIX, "make minix" (too big)
-# ? for IBM PC family, 386-based, with MINIX/386 1.5, "make minix386"
-# or if you have GNU CC, "make minix386gcc"
-# ? for IBM PC family, 386-based, with MINIX 2.0, "make minix20"
-# ? for IBM PC family, 386-based, with MINIX 3.0, "make minix3"
-# + for IBM PC family, 386-based, with MINIX 3.0, "make minix315"
-# ? for IBM PS/2 with PS/2 AIX 1.0, 1.1, or 1.2, "make ps2aix" or ps2aixnetc.
-# ? for IBM PS/2 with PS/2 AIX 1.3, "make ps2aix3"
-# ? for IBM RISC System/6000 with AIX 3.0, "make aix30"
-# ? for IBM RISC System/6000 with AIX 3.1.x, "make aix31"
-# ? for IBM RISC System/6000 with AIX 3.2.0 thru 3.2.5, "make aix32"
-# ? for IBM RS/6000 or Power Series with AIX 4.1.x, "make aix41"
-# ? for IBM RS/6000 or Power Series with AIX 4.1.x with gcc, "make aix41g"
-# ? for IBM RS/6000 or Power Series with AIX 4.1 with X.25, "make aix41x25"
-# ? for IBM RS/6000 or Power Series with AIX 4.2 or later: "make aix"
-# (the following "make aixnn" targets are no longer necessary except for gcc)
-# ? for IBM RS/6000 or Power Series with AIX 4.2, "make aix42"
-# ? for IBM RS/6000 or Power Series with AIX 4.3, "make aix43" (or aix43gcc)
-# ? for IBM RS/6000 or Power Series with AIX 4.4, "make aix44" (or aix44gcc)
-# ? for IBM RS/6000 or Power Series with AIX 4.5, "make aix45" (or aix45gcc)
-# ? for IBM RS/6000 or Power Series with AIX 5.0, "make aix50" (or aix50gcc)
-# ? for IBM RS/6000 or Power Series with AIX 5.1, "make aix51" (or aix51gcc)
-# ? for IBM RS/6000 or Power Series with AIX 5.2, "make aix52" (or aix52gcc)
-# ? for IBM RS/6000 or Power Series with AIX 5.3, "make aix53" (or aix53gcc)
-# ? for IBM RS/6000 or Power Series with AIX 6.1, "make aix61" (or aix53gcc)
-# ? for IBM RT PC with AIX 2.1, "make sys3"
-# ? for IBM RT PC with AIX 2.2.1, "make rtaix" or "make rtaixc"
-# ? for IBM RT PC with ACIS 4.2, "make bsd"
-# ? for IBM RT PC with ACIS 4.3, "make rtacis" or "make bsd KFLAGS=-DNOANSI"
-# ? for IBM RT PC with 4.3BSD/Reno, "make bsd44" or "make bsd44c"
-# ? for ICL DRS400 or 400E, "make iclsys5r3"
-# ? for ICL DRS3000 (80486) with DRS/NX, "make iclsys5r4_486"
-# ? for ICL DRS6000 (SPARC) with DRS/NX, "make iclsys5r4"
-# ? for ICL DRS6000 (SPARC) with DRS/NX 4.2MP 7MPlus, "make iclsys5r4m+"
-# ? Ditto but with IKSD support included, "make iclsys5r4m+iksd"
-# ? for Integrated Solutions Inc V8S VME 68020, "make isi"
-# ? for Intel 302 with Bell Tech Sys V/386 R3.2, "make sys5r3"
-# ? for Intel Xenix/286, "make sco286"
-# ? for Interactive System III (PC/IX), "make pcix" or "make is3"
-# ? for Interactive System III (PC/IX) with gcc, "make is3gcc"
-# ? for Interactive 386/ix 1.0.6 with TCP/IP networking, "make is5r3net2"
-# ? for Interactive 386/ix 2.0.x, "make is5r3" or (POSIX) "make is5r3p"
-# ? for Interactive 386/ix 2.0.x with TCP/IP networking, "make is5r3net"
-# or "make is5r3net2"
-# ? for Interactive 386/ix 2.2.1, job control, curses, no net, gcc,
-# "make is5r3gcc"
-# ? for Interactive UNIX Sys V R3.2 V2.2 - 4.0 without TCP/IP, "make is5r3jc"
-# ? for Interactive UNIX Sys V R3.2 V2.2 - 4.0 with TCP/IP, "make is5r3netjc"
-# ? for Intergraph Clipper, "make clix" or "make clixnet"
-# ? for Jolix (see 386BSD)
-# + for Linux 1.2 and later, "make linux". Uses ncurses. This version
-# handles serial speeds up to 460800 bps, Linux FSSTD 1.2, TCP/IP, and
-# should work on both libc and glibc systems. For static linking, use
-# "make linux LNKFLAGS=-static". Please read the comments that accompany
-# the linux entry. As of 8.0.212 Dev.10, this also includes Large File
-# Support (LFS).
-# + for Linux builds that fail with "sys/select.h: No such file or directory",
-# "make linuxns"
-# + for Linux 1.2 and later but with curses.h and libcurses (rather than
-# ncurses.h and libncurses), use "make linuxc".
-# + for Linux 1.2 and later with no curses support at all, "make linuxnc".
-# + for Linux with no TCP/IP, "make linuxnotcp"
-# (The following Linux targets are historic and might not work...)
-# ? for Red Hat Linux 7.1 through RH9, fully configured (krb5, SSL, etc):
-# "make redhat71", "make redhat72", "make redhat73", "make redhat80"
-# "make redhat9"
-# NOTE: You must use this target for Red Hat 7.1 since it
-# also includes a workaround for its broken curses library.
-# WARNING: These targets create binaries that include code for
-# strong encryption and are therefore not exportable. DO NOT PUT
-# THESE BINARIES ON US OR CANADIAN WEB OR FTP SITES.
-# ? for Linux on PowerMac (Mklinux DR3), "make mklinux".
-# ? for Linux 1.2 and later, to build with egcs, "make linuxegcs".
-# ? for Linux with lcc compiler, no TCP/IP, "make linuxnotcp-lcc"
-# ? for Linux 1.0 or earlier, "make linux10".
-# (End old linux targets)
-# ? for Mach 2.6 on (anything, e.g. DECstation), "make bsd42" or "make bsd43".
-# ? for MachTen (Tenon) 2.1.1.D on (e.g.) Apple Powerbook, "make machten".
-# ? for Masscomp RTU AT&T System III, "make rtu"
-# for other Masscomp, see Concurrent.
-# ? for Microport SV/AT (System V R2), "make mpsysv" (last edit tested: 144)
-# ? for Microport SVR4 2.2, 3.1, or 4.1 "make sys5r4sx"
-# ? for Microsoft,IBM Xenix (/286, PC/AT, etc), "make xenix" or "make sco286"
-# ? for MIPS System with RISC/os (UMIPS) 4.52 = AT&T SVR3, "make mips"
-# or "make mipstcpc"
-# ? for MkLinux on Power Macintosh, "make mklinux"
-# ? for Modcomp 9730, Real/IX, "make sys5r3" (or modify to use gcc = GLS cc)
-# ? for Modcomp Realstar 1000 with REAL/IX D.1, "make sv88r32"
-# ? for Motorola Four Phase, "make sys3" or "make sys3nid"
-# ? for Motorola Delta System V/68 R3, "make sv68r3"
-# ? for Motorola Delta System V/68 R3V5, "make sv68r3v5"
-# ? for Motorola Delta System V/68 R3V5.1, "make sv68r3v51"
-# ? for Motorola Delta System V/68 R3V6 with NSE TCP/IP, "make sv68r3v6"
-# ? for Motorola Delta System V/88 R32, "make sv88r32"
-# ? for Motorola Delta System V/88 R40, "make sv88r40"
-# ? for Mt Xinu Mach386 on 386/486-based PCs, "make bsd43"
-# ? for NCR Tower 1632, OS 1.02, "make tower1"
-# ? for NCR Tower 1632 or Minitower with System V R2, "make sys3"
-# or "make sys3nv"
-# ? for NCR Tower 32, OS Release 1.xx.xx, "make tower32-1"
-# ? for NCR Tower 32, OS Release 2.xx.xx, "make tower32-2"
-# ? for NCR Tower 32, OS Releases based on Sys V R3, "make tower32"
-# ? for NCR Tower 32, OS Releases based on Sys V R3 with gcc "make tower32g"
-# ? for NCR System 3000, AT&T UNIX System V R4 2.0, "make sys5r4sxna"
-# ? for NCR System 3000, AT&T UNIX System V R4 2.0 with Wollongong TCP/IP,
-# "make sys5r4net2" or "make sys5r4net2c".
-# Some header files might be misplaced; try this:
-# ln /usr/include/netinet/in.h /usr/include/sys/in.h
-# ln /usr/include/arpa/inet.h /usr/include/sys/inet.h
-# ln /usr/include/sys/termiox.h /usr/include/termiox.h
-# ? for NCR System 3000, NCR UNIX 02.02.01, same as above.
-# ? for NCR MP-RAS System V R4 V2.03 or 3.02, "make mpras" or "make mprastcpc"
-# + for NetBSD any version on any architecture, "make netbsd"
-# + for NetBSD with OpenSSL, "make netbsd+ssl"
-# ? for NetBSD with ncurses specified instead of curses, "make netbsdn"
-# ? for NetBSD with all curses support omitted, "make netbsdnc"
-# ? for NeXT with NeXTSTEP 1.0 through 3.2, "make next" (on a NeXT)
-# ? for NeXT with NeXTSTEP 3.3, "make next33"
-# ? for NeXT with OPENSTEP/Mach 4.1, "make nextquadfat".
-# ? for NeXT with OPENSTEP/Mach 4.2, "make openstep42".
-# ? for NeXTSTEP/486, "make next" (on a PC)
-# ? for NeXTSTEP portable binary (runs on Intel or Motorola), "make nextfat"
-# ? for NeXTSTEP portable binary (Intel, Motorola, HP PA-RISC, or SPARC),
-# "make nextquadfat"
-# ? for Nixdorf Targon/31, "make t31tos40x"
-# ? for Norsk Data Uniline 88/17 with SV/88 R3.2, "make sv88r32"
-# for Novell UnixWare - see UnixWare
-# ? for OSF/1 (vanilla, from OS/F), "make posix"
-# ? for OkiStation 7300 Series, "make sys5r4sxtcp"
-# ? for Olivetti LSX-3020 with X/OS R.2.3, "make xos23" or "make xos23c"
-# + for OpenBSD, "make openbsd" (also see secure targets listed below).
-# ? for OPENSTEP/Mach 4.1, "make nextquadfat" (NeXT, Intel, PA-RISC, SPARC)
-# ? for OPENSTEP/Mach 4.2, "make openstep42" (tested on NeXT)
-# ? for Perkin-Elmer (Concurrent) 3200 series, "make sys5".
-# ? for Perkin-Elmer (Concurrent) 3200 series with <dirent.h>, "make ccop1"
-# ? for Perkin-Elmer/Concurrent 3200 with Xelos R02, "make ccop1"
-# ? for PFU Compact A Series SX/A TISP V10/E50 (Japan), "make sxae50"
-# ? for Plexus, "make sys3"
-# ? for Pyramid 9XXX (e.g. 9845) or MIServer T series, OSx 4.4b thru 5.1,
-# "ucb make pyramid" or for HDB UUCP, "ucb make pyramid-hdb" or:
-# ? for Pyramid MIServer S or ES Series, DataCenter/OSx, "make pyrdcosx"
-# ? for Pyramid MIS-S MIPS R3000, DataCenter OSx System V R4, "make pyrdcosx"
-# ? for POSIX on anything, "make posix" (but adjustments might be necessary).
-# NOTE: this target is not very useful - many features are missing.
-# ? for Prime 8000 MIPS, SVR3, "make mips" or "make mipstcpc"
-# - for QNX 2.x (sorry we don't have a version of C-Kermit for QNX 2.x)
-# ? for QNX 4.0 or 4.1, 16-bit, on 286 PC, Watcom C 8.5, "make qnx16_41"
-# ? for QNX 4.21 - 4.22A (286+), and 4.23 (386+), or higher, 16-bit,
-# Watcom C 9.5x or higher, "make qnx16"
-# + for QNX 4.21-4.25, 32-bit, 386 or above, Watcom C 10.6, "make qnx32"
-# NOTE: ("make qnx" == "make qnx32")
-# ? for QNX Neutrino 2+, "make qnx_nto2+" (crosscompiled on QNX4 with Watcom C)
-# ? for QNX 6 = Neutrino 2.xx, "make qnx6"
-# ? for Ridge 32 (ROS3.2), "make ridge32"
-# ? for Samsung MagicStation, "make sys5r4"
-# ? for SCO Xenix 2.2.1 with development system 2.2 on 8086/8 "make sco86"
-# ? for SCO Xenix/286 2.2.1 with development system 2.2 on 80286, "make sco286"
-# NOTE: reportedly this makefile is too long for SCO Xenix/286 make, but it
-# works with "makeL", or if some of the other make entries are edited out.
-# ? for SCO Xenix/386 2.2.2, "make sco386"
-# ? for SCO Xenix/386 2.3.x, "make sco3r2"
-# ? for SCO Xenix/386 SCO 2.3.3 or 2.3.4 with gcc 1.37 or later,
-# "make sco386gcc" or (to add curses) "make sco386gccc".
-# ? for SCO Xenix/386 or UNIX/386 with Excelan TCP/IP, "make sco3r2net"
-# or (to add curses support) "make sco3r2netc" or "sco386netc"
-# + for SCO XENIX 2.3.4, "make sco234" or "make sco234c" to add curses.
-# ? for SCO XENIX 2.3.4 with SCO TCP/IP & curses, "make sco234netc".
-# ? for SCO Xenix 2.3.x with Racal-InterLan TCP/IP, "make sco3r2netri"
-# for other UNIX varieties with Racal Interlan TCP/IP, read sco3r2netri entry
-# ? for SCO Xenix 2.3.x with SCO (Lachman) TCP/IP, "make sco3r2lai"
-# or (to add curses) "make sco3r2laic"
-# for SCO UNIX... ALSO READ COMMENTS in the SCO UNIX entries for more info!
-# ? for SCO UNIX/386 3.2.0 or 3.2.1, "make sco3r2" or "make sco3r2x"
-# ? for SCO UNIX/386 3.2.2, "make sco3r22" or "make sco3r22gcc"
-# or "make sco3r22c"
-# ? for SCO UNIX/386 3.2.2 with SCO TCP/IP, "make sco3r22net"
-# or "make sco3r22netc" (curses)
-# ? for SCO ODT 1.1, "make sco3r22net" or "make sco3r22netc" (curses)
-# ? for SCO UNIX/386 3.2 V4.x, no network support, "make sco32v4"
-# ? or "make sco32v4ns" (this one uses no select() or sockets library)
-# ? for SCO UNIX/386 3.2 V4.x with TCP/IP, "make sco32v4net"
-# (also sco32v4gcc, sco32v4netgcc)
-# ? for SCO UNIX/386 3.2 V5.0 - see SCO OpenServer.
-# ? for SCO UNIX 3.2v4.x with TCP/IP, <dirent.h> for Extended Acer File
-# System (EAFS), curses, ANSI C compilation, "make sco32v4net"
-# ? or (to use select()-based CONNECT module) "make sco32v4netx".
-# ? for SCO UNIX 3.2v4.2, "make sco-odt30" (includes TCP/IP).
-# ? for SCO MPX 3.0 - The SCO UNIX binary runs on the corresponding MPX system.
-#
-# NOTE: Also see below for other entries that are variations on these.
-# Also be sure to read the comments accompanying each SCO entry.
-# Also see Unixware section.
-#
-# ? for SCO ODT 2.0, "make sco32v4net"
-# ? for SCO ODT 3.0, "make sco-odt30"
-# ? for SCO OpenServer 5.0 (OSR5), "make sco32v500"
-# ? for SCO OpenServer 5.0 (OSR5) with networking, "make sco32v500net"
-# ? for SCO OpenServer 5.0 (OSR5), gcc, "make sco32v500gcc"
-# ? for SCO OpenServer 5.0 (OSR5), gcc, with networking, "make sco32v500netgcc"
-# ? for SCO OpenServer 5.0 (OSR5), as above, ELF, "make sco32v500netgccelf"
-# ? for SCO OpenServer 5.0.2, use "make sco32v502xxx" entries as above.
-# ? for SCO OpenServer 5.0.4, use "make sco32v504xxx" entries as above.
-# ? for SCO OpenServer 5.0.5, use "make sco32v505xxx" entries as above.
-# Use the sco32v505udkxxx entries if you have the UDK rather than /bin/cc.
-# ? for SCO OpenServer 5.0.6, use "make sco32v506xxx" entries as above.
-# ? for SCO OpenServer 5.0.6a,use "make sco32v506axxx" entries as above.
-# ? for SCO OpenServer 5.0.7, use "make sco32v507", "make sco32v507net"
-# ? for SCO (Univel) UnixWare 1.x, "make unixware" or "make unixwarenetc".
-# If there are problems with this in C-K 7+ see notes at unixware entry.
-# + for SCO OpenServer 6.0.0, "make sco_osr600"
-# ? for SCO UnixWare 2.0.x, "make uw20"
-# ? for SCO UnixWare 2.1.0, "make uw21"
-# ? for SCO UnixWare 2.1.3, "make uw213"
-# + for SCO UnixWare 7, "make uw7" (includes large file support)
-# ? for SCO UnixWare 7 with IKSD support, "make uw7iksd" or "make uw7iksdudk"
-# ? for SCO UnixWare 7 with OpenSSL, "make uw7ssl"
-# ? for SCO (Caldera) Open UNIX 8, "make ou8"
-# ? for Sharp Zaurus SL5500 PDA, "make zsl5500".
-# ? for Sequent with DYNIX/ptx 1.2.1, "make dynixptx12"
-# ? for Sequent with DYNIX/ptx 1.3 or 1.4 with TCP/IP, "make dynixptx13"
-# ? for Sequent with DYNIX/ptx 2.0 or 2.1 with TCP/IP, "make dynixptx20"
-# or "dynixptx20c"
-# ? for Sequent with DYNIX/ptx 2.1.6 on i486, "dynixptx216c"
-# ? for Sequent with DYNIX/ptx V4.1.3 with TCP/IP, "make dynixptx41c"
-# ? for Sequent with DYNIX/ptx V4.4.2 with TCP/IP, "make dynixptx44"
-# ? for Sequent Balance 8000 or B8 with DYNIX 3.0.xx, "make dynix3"
-# or "make dynix3noacu"
-# ? for Sequent Symmetry S81 with DYNIX 3.0.xx, "make dynix3"
-# ? for Sequent DYNIX 3.1.xx, "make dynix31" or "make dynix31c"
-# ? for Siemens/Nixdorf SINIX-L Intel V5.41, "make sinix541i"
-# + for Siemens/Nixdorf SINIX-N MIPS V5.42, "make sinix542"
-# ? for Siemens/Nixdorf SINIX-P MIPS V5.42 with gcc, "make sinix542g"
-# ? for Siemens/Nixdorf SINIX-Z Intel V5.42, "make sinix542i"
-# ? for Siemens/Nixdorf Reliant UNIX V5.43, "make sni543"
-# ? for Siemens/Nixdorf Reliant UNIX V5.44, "make sni544"
-# ? for Silicon Graphics Iris System V IRIX 3.2 or earlier, "make iris"
-# ? for Silicon Graphics Sys V R3 with IRIX 3.3 or later, "make sys5r3"
-# ? for Silicon Graphics Iris Indigo with IRIX 4.0 or 5.0, "make irix40" or
-# (to include Yellow Pages and Curses) "make irix40ypc"
-# ? for Silicon Graphics Iris Indigo or Elan with IRIX 4.0.x with microcode
-# optimization and -O4, "make irix40u" or "irix40uc" (and read notes
-# accompanying these entries).
-# ? for Silicon Graphics IRIX 5.1, "make irix51" or "irix51x" (no optimize)
-# ? for Silicon Graphics IRIX 5.2, "make irix52"
-# ? for Silicon Graphics IRIX 5.3, "make irix53" or "irix53x" (no optimize)
-# ? for Silicon Graphics IRIX 6.0, "make irix60".
-# ? for Silicon Graphics IRIX 6.2, "make irix62".
-# ? for Silicon Graphics IRIX 6.3, "make irix63".
-# ? for Silicon Graphics IRIX 6.4, "make irix64" or "make irix64gcc".
-# + for Silicon Graphics (SGI) IRIX 6.5, "make irix65"
-# + or "make irix65mips2" to force MIPS2, or "make irix65gcc" for GCC.
-# + for Silicon Graphics (SGI) IRIX 6.5, "make irix65" or "make irix65mips2"
-# ? for SGI IRIX 6.5 with SSL/TLS, SRP, and ZLIB "make irix65+ssl+srp+zlib"
-# ? for Solaris 2.0-2.3 on SPARC or Intel, SunPro CC, "make solaris2x",
-# ? or to add SunLink X.25 8.0x support, "make solaris2x25".
-# ? for Solaris 2.4 built with gcc, "make solaris24g".
-# ? for Solaris 2.0-2.3 on SPARC or Intel, GNU CC, "make solaris2xg".
-# ? for Solaris 2.4 with X.25, "make solaris24x25".
-# ? for Solaris 2.5 on SPARC or Intel, SunPro CC, "make solaris25".
-# ? or to add SunLink X.25 8.0x support, "make solaris25x25".
-# ? for Solaris 2.5 on SPARC or Intel, GNU CC, "make solaris25g".
-# ? for Solaris 2.6 on SPARC or Intel, "make solaris26".
-# ? for Solaris 7 on SPARC or Intel, SunPro CC, "make solaris7".
-# ? for Solaris 7 on SPARC or Intel, GNU CC, "make solaris7g".
-# ? for Solaris 8 on SPARC or Intel, SunPro CC, "make solaris8".
-# ? for Solaris 8 on SPARC or Intel, GNU CC, "make solaris8g".
-# + for Solaris 9 on SPARC (or Intel?), 32-bit, SunPro CC, "make solaris9".
-# + for Solaris 9 on SPARC (or Intel?), 32-bit, GNU CC, "make solaris9g".
-# ? for Solaris 9 on SPARC (or Intel?), 64-bit, GNU CC, "make solaris9g64".
-# + for Solaris 10 on SPARC (or Intel?), 32-bit, SunPro CC, "make solaris10".
-# + for Solaris 10 on SPARC 64-bit, SunPro CC, "make solaris10_64".
-# + for Solaris 10 on SPARC (or Intel?), 32-bit, GNU CC, "make solaris10g".
-# ? for Solaris 10 on SPARC (or Intel?), 64-bit, GNU CC, "make solaris10g64".
-# ? for Solbourne 4/500 with OS/MP 4 "make sunos4"
-# ? for Solbourne 4/500 with OS/MP 4.1 "make sunos41" or "make sunos41c"
-# ? for SONY NEWS with NEWS-OS 4.0.1C, "make sonynews"
-# ? for SONY NEWS with NEWS-OS 4.1.2C, "make sonynews"
-# ? for Sperry/UNISYS 5000/20, UTS V 5.2 3R1, "make sys5"
-# ? for Sperry/UNISYS 5000/30/35/50/55, UTS V 5.2 2.01, "make unisys5r2"
-# ? for Sperry/UNISYS 5000/80 with System V R3, "make sys5r3"
-# ? for Sperry/UNISYS 5000/95 with System V R3, "make sys5r3"
-# For UNISYS SVR3 it might be necessary to "make sys5r3 KFLAGS=-UDYNAMIC"
-# ? for Stardent 1520, "make sys5r3"
-# ? for Stratus FTX 2.x, try "make ftx" or else "make sys5r4" or "sys5r4sx"
-# ? for Stratus FTX 3.x, PA-RISC 1.0 or 2.0, "make ftx" or "make ftxtcp"
-# ? for Sun with Sun UNIX 3.5 and gcc, "make sunos3gcc"
-# ? for Sun with pre-4.0 SunOS versions, "make bsd" (or appropriate variant)
-# ? for Sun with SunOS 4.0, BSD environment, "make sunos4"
-# ? for Sun with SunOS 4.0, BSD, with SunLink X.25, make sunos4x25
-# ? for Sun with SunOS 4.1 or 4.1.1, BSD environment, "make sunos41"
-# or "make sunos41c" (curses) or "make sunos41gcc" (compile with gcc)
-# ? for Sun with SunOS 4.1.x, BSD, with SunLink X.25 7.00 or earlier,
-# "make sunos41x25" or "make sunos41x25c" (curses)
-# ? for Sun with SunOS 4.1, 4.1.1, AT&T Sys V R3 environment, "make sunos41s5"
-# ? for Sun with SunOS 4.1.2, "make sunos41" or any of its variations.
-# NOTE: All SunOS 4.x systems -- Shared libraries are used by default.
-# If this causes problems, add -Bstatic to CFLAGS.
-# NOTE2: When building C-Kermit under SunOS for the BSD universe,
-# but /usr/5bin/cc is ahead of /usr/ucb/cc in your PATH, add
-# "CC=/usr/ucb/cc CC2=/usr/ucb/cc" to the make entry.
-# NOTE3: If an executable built on one type of Sun hardware does not work
-# on another type, rebuild the program from source on the target machine.
-# for Sun with Solaris 1.x use SunOS 4.1 entries.
-# for Sun with Solaris 2.0 and higher use Solaris entries.
-# + for Sun SPARC with Linux, "make linux"
-# ? for Sun SPARC with OPENSTEP/Mach 4.1, "make nextquadfat"
-# ? for Sun SPARC with OPENSTEP/Mach 4.2, "make openstep42"
-# - for Tandy 16/6000 with Xenix 3.0, "make trs16" (C-Kermit 7.0 is too big)
-# ? for Tektronix 6130/4132/43xx (e.g.4301) with UTek OS, "make utek"
-# or (for models without hardware flow control), "make uteknohwfc"
-# ? for Tektronix XD88 series with UTekV OS, "make utekvr3"
-# ? for Tri Star Flash Cache with Esix SVR3.2, "make sys5r3"
-# NOTE: The Tru64 builds have been failing since 2010, but "make dec-osf" is OK
-# ? for Tru64 UNIX 4.0E, "make tru64-40e"
-# ? for Tru64 UNIX 4.0F, "make tru64-40f"
-# ? for Tru64 UNIX 4.0G, "make tru64-40g"
-# ? for Tru64 UNIX 5.0A, "make tru64-50a"
-# ? for Tru64 UNIX 5.1A, "make tru64-51a"
-# ? for Tru64 UNIX 5.1B, "make tru64-51b"
-# ? for Unistar, "make sys5"
-# ? for Unisys S/4040 68040 CTIX SVR3.2 6.4.1, "make ctix" or "make sys5r3"
-# ? for Unisys U5000 UNIX SVR3 6.x, "make sys5r3" or "make sys5r3c"
-# ? for Unisys U6000 UNIX SVR4 1.x, "make sys5r4nx" or "make sys5r4nxnetc"
-# for Unisys ... (also see Sperry)
-# for Univel - see UnixWare
-# for Unixware - see SCO
-# ? for Valid Scaldstar, "make valid"
-# ? for Whitechapel MG01 Genix 1.3, "make white"
-# ? for Zilog ZEUS 3.21, "make zilog"
-#
-# The result should be a runnable program called "wermit" in the current
-# directory. After satisfactory testing, you can rename wermit to "kermit"
-# and put it in some directory that's in everybody's PATH, such as
-# /usr/local or /opt/local.
-#
-# To remove intermediate and object files, "make clean".
-# If your C compiler produces files with an extension other than "o",
-# then "make clean EXT=u", "make clean EXT=s", or whatever.
-#
-# To run lint on the source files, "make lintsun", "make lintbsd",
-# "make lints5", as appropriate.
-#
-# ******************************
-# SECURE TARGETS
-#
-# Beginning with C-Kermit 7.0, secure targets are included, as are the
-# source modules (ckuat*.[ch], ck_*.[ch]) needed to build them. Secure
-# target names are like the regular names, but with security features
-# indicated by plus (+) signs. The features are:
-#
-# krb4 MIT Kerberos IV
-# krb5 MIT Kerberos V
-# openssl OpenSSL (SSL/TLS)
-# zlib ZLIB compression for SSL/TLS
-# srp Stanford Secure Remote Password
-# pam PAM (pluggable authentication module)
-# shadow Shadow Password File
-#
-# You can build these targets if you have the Kermit source files and the
-# required libraries (Kerberos, OpenSSL, SRP, etc) and header files. See:
-# http://www.columbia.edu/kermit/security.html
-# for specific details regarding supported versions.
-#
-# NOTE: OpenSSL 0.9.6 and earlier are not compatible with 0.9.7 and later.
-# C-Kermit code was originally designed for 0.9.6. To build with 0.9.7 you
-# must add -DOPENSSL_097 to avoid missing symbols in the DES library and to
-# use the entry points that were renamed to avoid conflict with Kerberos 4.
-# If you have OpenSSL 0.9.8, add -DOPENSSL_098, which is a synonym for
-# -DOPENSSL_097. If you have 1.0.0 or later, add -DOPENSSL_100, which is
-# another synonym.
-
-# In OpenSSL builds add -ldl if you get unresolved references for
-# dlopen, dlclose, dlsym, and/or dlerror.
-#
-# In order to build a secure version of Kermit, you need to know the location
-# of the header (include) files and libraries for the desired form of
-# security. Unless you specify a location, this makefile looks in /usr/local
-# and if the required files are not found, the build fails.
-#
-# If the secure headers and libraries are not on your computer, you have
-# to download and install them, for example from http://www.openssl.org .
-#
-# The following symbols are used to specify library and header file locations:
-#
-prefix = /usr/local
-srproot = $(prefix)
-sslroot = $(prefix)
-manroot = $(prefix)
-
-K4LIB=-L/usr/kerberos/lib
-K4INC=-I/usr/kerberos/include
-K5LIB=-L/usr/kerberos/lib
-K5INC=-I/usr/kerberos/include
-SRPLIB=-L$(srproot)/lib
-SRPINC=-I$(srproot)/include
-SSLLIB=-L$(sslroot)/ssl/lib
-SSLINC=-I$(sslroot)/ssl/include
-
-# To override these assignments; for example, if your OpenSSL files are
-# not in /usr/local/ssl, invoke the desired target like this:
-#
-# make solaris9+openssl "SSLINC=-I/opt/openssl-0.9.8k/include" \
-# "SSLLIB=-L/opt/openssl-0.9.8k/lib"
-#
-# (don't set the variables and then do "make -e" because that breaks
-# chaining of makefile targets.)
-#
-# Here are some up-to-date secure targets as of Sep 2009:
-#
-# aix+openssl: IBM AIX 4.2 or later with OpenSSL
-# freebsd44+srp+openssl FreeBSD 4.4 with SRP and OpenSSL
-# freebsd50+openssl FreeBSD 5.0 with OpenSSL
-# hpux1100o+openssl: HP-UX 11.xx with OpenSSL
-# hpux1000gcc+openssl: HP-UX 10.xx with OpenSSL (build with gcc)
-# hpux1100gcc+openssl: HP-UX 11.xx with OpenSSL (build with gcc)
-# irix6x+krb5: IRIX 6.x with Kerberos V
-# irix65+krb5: etc etc...
-# solaris9+openssl Solaris 9,10, or 11 with Openssl (Sun cc)
-# solaris9g+openssl Solaris 9,10, or 11 with Openssl (gcc)
-# linux+ssl OpenSSL only
-# linux+krb5+ssl Linux with Kerberos 5 and OpenSSL
-# linux+krb5: Kerberos 5 only
-#
-# The following secure Linux targets have not been updated or tested recently.
-# linux+krb5+krb4:
-# linux+srp:
-# linux+srp+pam:
-# linux+srp+gmp:
-# linux+srp+gmp+no-des:
-# linux+srp+gmp-export:
-# linux+srp+gmp+pam:
-# linux+shadow+pam:
-# linux+openssl:
-# linux+openssl+shadow:
-# linux+openssl+zlib+shadow+pam:
-# linux+srp+openssl:
-# linux+krb5+krb4+srp:
-# linux+krb5+krb4+srp+openssl:
-# linux+krb5+krb4+openssl:
-# linux+krb5+krb4+openssl+shadow:
-# linux+krb5+krb4+openssl+zlib+shadow:
-# linux+krb5+krb4+srp-export:
-# linux+krb5+krb4+srp+pam:
-# linux+krb5+krb4+srp+openssl+pam-debug:
-# linux+krb5+krb4+srp+openssl+pam:
-# linux+krb5+krb4+srp+openssl+zlib+pam:
-# linux+krb5+krb4+openssl+shadow+pam:
-# linux+krb5+openssl+zlib+shadow+pam:
-#
-# The following have not been tested recently either and might
-# need adjustment.
-#
-# macosx+krb5+ssl: Mac OS X 10.3.9 or later + OpenSSL and Kerberos 5
-# macosx103+secure: This one is probably redundant
-# netbsd+openssl: NetBSD with OpenSSL
-# openbsd30+ssl: OpenBSD 3.0 with OpenSSL
-# redhat71,redhat72,redhat73,redhat80,redhat9 (Krb5,OpenSSL,Showdow,PAM,Zlib)
-# sco32v500net+ssl:
-# sco32v505net+ssl:
-# solaris2x+krb4:
-# solaris2xg+krb4:
-# solaris2xg+openssl+pam+shadow:
-# solaris2xg+openssl+zlib+pam+shadow:
-# solaris2xg+krb5+krb4+openssl+shadow:
-# solaris25+krb4:
-# solaris25g+krb4:
-# solaris26g+openssl:
-# solaris8g+openssl+zlib+pam+shadow:
-# solaris8g+krb4:
-# solaris9g+openssl+zlib+pam+shadow:
-# solaris9g+openssl+shadow+pam+zlib
-# sunos41gcc+krb4: SunOS 4.1 built with gcc with Kerberos IV
-# sunos41gcc+openssl: SunOS 4.1 built with gcc with OpenSSL
-# sunos41gcc+krb4+openssl: ...with Kerberos IV and OpenSSL
-# sunos41gcc+krb4+openssl+zlib: ditto, plus ZLIB compression
-# sunos41gcc+krb4+srp+openssl+zlib: ditto, plus SRP
-# sunos41gcc+srp+openssl+zlib:
-# tru64-51b-openssl: Tru64 (Digital) Unix 5.1B with OpenSSL
-# uw7ssl Unixware 7 with SSL
-#
-###########################################################################
-#
-# Compile and Link variables:
-#
-# EXT is the extension (file type) for object files, normally o.
-# See MINIX entry for what to do if another filetype must be used.
-#
-EXT=o
-#LNKFLAGS=
-SHAREDLIB=
-CC= cc
-CC2= cc
-MAKE= make
-SHELL=/bin/sh
-
-###########################################################################
-# (Ancient) UNIX V7-specific variables.
-# These are set up for Perkin-Elmer 3230 V7 Unix:
-#
-PROC=proc
-DIRECT=
-NPROC=nproc
-NPTYPE=int
-BOOTFILE=/edition7
-#
-# ( For old Tandy TRS-80 Model 16A or 6000 V7-based Xenix, use PROC=_proc,
-# DIRECT=-DDIRECT, NPROC=_Nproc, NPTYPE=short, BOOTFILE=/xenix )
-#
-
-###########################################################################
-# SAMPLE INSTALLATION SCRIPT
-#
-# Modify to suit your own computer's file organization and permissions. If
-# you don't have write access to the destination directories, "make install"
-# fails. In most cases, a real installation also requires you to chown /
-# chgrp the Kermit binary for the UUCP lockfile and/or tty devices, and
-# perhaps also to chmod +s the corresponding permission fields.
-#
-# Default binary, man, and doc directories are supplied below. You can
-# override them in your 'make' command. Examples:
-#
-# make install # Accept defaults.
-# make "INFODIR=/usr/share/lib/kermit" install # Override INFODIR default.
-#
-# You can also build and install in one step, e.g.:
-#
-# make linux install
-#
-# If you use the 'install' target to install C-Kermit, it creates an
-# UNINSTALL script that can be used to uninstall it.
-#
-WERMIT = makewhat
-BINARY = wermit
-DESTDIR =
-BINDIR = $(prefix)/bin
-MANDIR = $(manroot)/man/man1
-MANEXT = 1
-SRCDIR =
-INFODIR =
-CERTDIR =
-
-TEXTFILES = COPYING.TXT ckcbwr.txt ckubwr.txt ckuins.txt ckccfg.txt \
- ckcplm.txt ckermit.ini ckermod.ini ckermit70.txt ckermit80.txt
-
-ALL = $(WERMIT)
-
-all: $(ALL)
-
-.c.o:
- $(CC) $(CFLAGS) -DKTARGET=\"$(KTARGET)\" -c $<
-
-#Clean up intermediate and object files
-clean:
- @echo 'Removing object files...'
- -rm -f ckcmai.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \
-ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckcpro.$(EXT) ckcfns.$(EXT) \
-ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) ckucon.$(EXT) ckutio.$(EXT) \
-ckufio.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) ckwart.$(EXT) ckuusx.$(EXT) \
-ckuusy.$(EXT) ckcnet.$(EXT) ckuus6.$(EXT) ckuus7.$(EXT) ckusig.$(EXT) \
-ckucns.$(EXT) ckcmdb.$(EXT) ckuath.$(EXT) ckctel.$(EXT) ckclib.$(EXT) \
-ckcuni.$(EXT) ck_crp.$(EXT) ck_ssl.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) \
-ckcpro.c wart
-
-show:
- @echo prefix=$(prefix)
- @echo srproot=$(srproot)
- @echo sslroot=$(sslroot)
- @echo manroot=$(manroot)
- @echo K4LIB=$(K4LIB)
- @echo K4INC=$(K4INC)
- @echo K5LIB=$(K5LIB)
- @echo K5INC=$(K5INC)
- @echo SRPLIB=$(SRPLIB)
- @echo SRPINC=$(SRPINC)
- @echo SSLLIB=$(SSLLIB)
- @echo SSLINC=$(SSLINC)
- @exit
-
-# Install C-Kermit after building -- IMPORTANT: Read the instructions above
-# (SAMPLE INSTALLATION SCRIPT). For SSL/TLS versions, ca_certs.pem file
-# should be installed in the appropriate place for your OpenSSL library, e.g.:
-#
-# cp ca_certs.pem /usr/local/ssl/
-# cp ca_certs.pem /usr/share/ssl/
-#
-# To make sure 'man' notices the new source file and doesn't keep
-# showing the old formatted version, remove the old formatted version,
-# something like this:
-# rm -f $(MANDIR)/../cat$(MANEXT)/kermit.$(MANEXT)
-# or this (which requires CATDIR to be defined):
-# rm -f $(CATDIR)/kermit.$(MANEXT)
-#
-# As of C-Kermit 8.0.205 this target also builds an UNINSTALL script, and
-# so it might be too long for some old Bourne shells, in which case you can
-# use a different shell:
-#
-# make SHELL=ksh install
-# make SHELL=/bin/posix/sh install
-#
-install:
- @echo Installing C-Kermit version $(CKVER)...;\
- rm -f UNINSTALL;\
- exec 3>./UNINSTALL;\
- echo "# C-Kermit UNINSTALL script" >&3;\
- echo "# `date`\n" >&3;\
- echo "CKVER=$(CKVER)" >&3;\
- echo "PrN Uninstalling C-Kermit version $(CKVER)..." >&3;\
- echo DESTDIR=$(DESTDIR);\
- if test -n "$(DESTDIR)"; then\
- if test -d $(DESTDIR); then\
- echo "$(DESTDIR) exists...\n";\
- else\
- echo "Creating $(DESTDIR)...";\
- DESTDIR=`echo $(DESTDIR) | sed 's!/*$$!!'`;\
- mkdir $$DESTDIR || exit 1;\
- fi;\
- chmod 755 $(DESTDIR) || exit 1;\
- fi;\
- echo BINARY=$(BINARY);\
- if test -f $(BINARY); then\
- ls -l $(BINARY);\
- else\
- echo "?$(BINARY) not found";\
- exit 1;\
- fi;\
- if test -z "$(DESTDIR)$(BINDIR)"; then\
- echo "Binary directory not specified";\
- exit 1;\
- fi;\
- if test -d $(DESTDIR)$(BINDIR); then\
- echo "$(DESTDIR)$(BINDIR) exists...";\
- else\
- echo "Creating $(DESTDIR)$(BINDIR)/...";\
- mkdir $(DESTDIR)$(BINDIR) || exit 1;\
- chmod 755 $(DESTDIR)$(BINDIR);\
- fi;\
- rm -f $(DESTDIR)$(BINDIR)/kermit;\
- cp $(BINARY) $(DESTDIR)$(BINDIR)/kermit || exit 1;\
- chmod 755 $(DESTDIR)$(BINDIR)/kermit || exit 1;\
- rm -f $(DESTDIR)$(BINDIR)/kermit-sshsub;\
- ln -s $(DESTDIR)$(BINDIR)/kermit\
- $(DESTDIR)$(BINDIR)/kermit-sshsub || exit 1;\
- echo 'set flag=f\nPrC Removing binaries' >&3;\
- echo "RmF $(DESTDIR)$(BINDIR)/kermit-sshsub" >&3;\
- echo "RmF $(DESTDIR)$(BINDIR)/kermit" >&3;\
- if test -f ckermit.ini; then\
- echo "#!$(BINDIR)/kermit" >\
- $(DESTDIR)$(BINDIR)/_tmp.ini;\
- cat ckermit.ini >> $(DESTDIR)$(BINDIR)/_tmp.ini;\
- mv $(DESTDIR)$(BINDIR)/_tmp.ini\
- $(DESTDIR)$(BINDIR)/ckermit.ini;\
- chmod 755 $(DESTDIR)$(BINDIR)/ckermit.ini;\
- echo "RmF $(DESTDIR)$(BINDIR)/ckermit.ini" >&3;\
- fi;\
- echo;\
- echo 'EfM' >&3;\
- echo "Kermit binary installed:";\
- ls -l $(DESTDIR)$(BINDIR)/kermit\
- $(DESTDIR)$(BINDIR)/kermit-sshsub\
- $(DESTDIR)$(BINDIR)/ckermit.ini;\
- echo;\
- echo " WARNING: If C-Kermit is to be used for dialing out,";\
- echo " you must change its owner and group and permissions";\
- echo " to match the 'cu' program. See the ckuins.txt file";\
- echo " for details.";\
- echo;\
- echo MANDIR=$(MANDIR);\
- if test -n "$(DESTDIR)$(MANDIR)"; then\
- if test -d $(DESTDIR)$(MANDIR); then\
- echo "$(DESTDIR)$(MANDIR) exists...";\
- else\
- echo "Creating $(MANDIR)...";\
- mkdir $(MANDIR) || exit 1;\
- chmod 755 $(MANDIR) || exit 1;\
- fi;\
- rm -f $(DESTDIR)$(MANDIR)/kermit.$(MANEXT);\
- cp ckuker.nr $(DESTDIR)$(MANDIR)/kermit.$(MANEXT) || exit 1;\
- chmod 644 $(DESTDIR)$(MANDIR)/kermit.$(MANEXT) || exit 1;\
- echo 'set flag=f\nPrC Removing man pages' >&3;\
- echo "RmF $(DESTDIR)$(MANDIR)/kermit.$(MANEXT)" >&3;\
- echo 'EfM' >&3;\
- echo;\
- else\
- echo "Not installing man page!\n";\
- fi;\
- echo CERTDIR=$(CERTDIR);\
- if test -n "$(CERTDIR)"; then\
- if test -f ca_certs.pem; then\
- if test -d $(CERTDIR); then\
- echo "$(CERTDIR) exists...";\
- else\
- echo "Creating $(CERTDIR)...";\
- mkdir $(CERTDIR) || exit 1;\
- chmod 755 $(CERTDIR) || exit 1;\
- fi;\
- echo "Installing certificates file...";\
- cp ca_certs.pem $(CERTDIR) || exit 1;\
- echo 'set flag=f' >&3;\
- echo 'PrC Removing certificates file' >&3;\
- echo "RmF $(CERTDIR)/ca_certs.pem" >&3;\
- echo 'EfM' >&3;\
- echo;\
- fi;\
- else\
- echo "Not installing certificates file!\n";\
- fi;\
- echo SRCDIR=$(DESTDIR)$(SRCDIR);\
- if test -n "$(SRCDIR)"; then\
- echo "Installing source files...";\
- if test -d $(DESTDIR)$(SRCDIR); then\
- echo "$(DESTDIR)$(SRCDIR) exists...";\
- else\
- echo "Creating $(DESTDIR)$(SRCDIR)/...";\
- mkdir $(DESTDIR)$(SRCDIR) || exit 1;\
- chmod 755 $(DESTDIR)$(SRCDIR);\
- fi;\
- echo "Copying source files to $(DESTDIR)$(SRCDIR)...";\
- echo 'set flag=f\nPrC Removing source files' >&3;\
- for TextFile in COPYING.TXT ck[cuw_]*.[cwh] makefile; do\
- cp $$TextFile $(DESTDIR)$(SRCDIR)/ && echo ".\c";\
- echo "RmF $(DESTDIR)$(SRCDIR)/$$TextFile" >&3;\
- done; echo;\
- echo 'EfM' >&3;\
- ( cd $(DESTDIR)$(SRCDIR)/ &&\
- ls -l COPYING.TXT ck[cuw_]*.[cwh] makefile );echo;\
- else\
- echo "Not installing source code!\n";\
- fi;\
- echo INFODIR=$(DESTDIR)$(INFODIR);\
- if test -n "$(INFODIR)"; then\
- echo "Installing info files...";\
- if test -d $(DESTDIR)$(INFODIR); then\
- echo "$(DESTDIR)$(INFODIR) exists...";\
- else\
- echo "Creating $(DESTDIR)$(INFODIR)/...";\
- mkdir $(DESTDIR)$(INFODIR) || exit 1;\
- chmod 755 $(DESTDIR)$(INFODIR);\
- fi;\
- echo "Copying text files to $(DESTDIR)$(INFODIR)...";\
- echo 'set flag=f\nPrC Removing text files' >&3;\
- FileCopyList='';\
- for TextFile in $(TEXTFILES); do\
- test -f $$TextFile || continue;\
- cp $$TextFile $(DESTDIR)$(INFODIR) && echo ".\c" &&\
- FileCopyList="$$FileCopyList $$TextFile";\
- echo "RmF $(DESTDIR)$(INFODIR)/$$TextFile" >&3;\
- done; echo;\
- echo 'EfM' >&3;\
- ( cd $(DESTDIR)$(INFODIR)/ && chmod 644 $$FileCopyList );\
- ( cd $(DESTDIR)$(INFODIR)/ && pwd && ls -l $$FileCopyList );\
- else\
- echo "Not installing text files!\n";\
- fi;\
- echo "set flag=d\nPrN Removing empty dirs..." >&3;\
- echo "RmD $(DESTDIR)$(BINDIR)" >&3;\
- echo "RmD $(DESTDIR)$(SRCDIR)" >&3;\
- echo "RmD $(DESTDIR)$(INFODIR)" >&3;\
- echo "RmD $(CERTDIR)" >&3;\
- echo "RmD $(MANDIR)" >&3;\
- echo "RmD $(DESTDIR)" >&3;\
- echo "EfM" >&3;\
- echo "PrN C-Kermit version $(CKVER) is uninstalled!" >&3;\
- echo C-Kermit version $(CKVER) installed!
-
-# UN-Install C-Kermit after building
-# Please to not remove the extra blanks before and after '{}' within the
-# functions. You would get syntax errors for some older Bourne shells! Best is
-# you don't change or remove anything.
-#
-uninstall:
- @if test ! -f UNINSTALL; then\
- echo "?C-Kermit UNINSTALL data file not found!";\
- exit 1;\
- fi; \
- X=`grep '^CKVER='$(CKVER)'$$' ./UNINSTALL || :`;\
- if test -z "$$X"; then\
- echo "?UNINSTALL file is not for C-Kermit version $(CKVER)";\
- exit 2;\
- fi;\
- PrN () { echo "$$*"; };\
- PrC () { echo "$$* \c"; };\
- RmF () { test -f "$$1" && rm -f "$$1" && echo ".\c" && flag=F ; };\
- RmD () { \
- dir=$$1;\
- while test -d "$$dir"; do\
- rmdir "$$dir" 2>&- || return && echo "$$dir" && flag=D;\
- dir=`echo "$$dir" | sed 's!/[^/]*/*$$!!'`;\
- done; \
- };\
- EfM () { \
- case "$$flag" in\
- f) echo "- Nothing to remove!";;\
- d) echo "Nothing to remove!";;\
- F) echo " done";;\
- D) echo "done";;\
- esac; \
- };\
- while read Act Args; do\
- case $$Act in\
- EfM) EfM;;\
- RmD) RmD $$Args;;\
- RmF) RmF $$Args;;\
- PrN) PrN $$Args;;\
- PrC) PrC $$Args;;\
- set) eval $$Args;;\
- esac;\
- done < ./UNINSTALL
-
-makewhat:
- @echo 'make what? You must tell which platform to make C-Kermit for.'
- @echo Examples: make linux, make aix, make solaris10, make hpux1100.
- @echo Please read the comments at the beginning of the makefile.
-
-###########################################################################
-#
-# Dependencies Section:
-
-wermit: ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \
- ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \
- ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \
- ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \
- ckucon.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \
- ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \
- ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT)
- $(CC2) $(LNKFLAGS) -o wermit \
- ckcmai.$(EXT) ckclib.$(EXT) ckutio.$(EXT) ckufio.$(EXT) \
- ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \
- ckcpro.$(EXT) ckucmd.$(EXT) ckuus2.$(EXT) ckuus3.$(EXT) \
- ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) ckuus7.$(EXT) \
- ckuusx.$(EXT) ckuusy.$(EXT) ckuusr.$(EXT) ckucon.$(EXT) \
- ckudia.$(EXT) ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) \
- ckusig.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) \
- $(LIBS)
-
-# Preferred configuration with select()-based CONNECT
-
-xermit: ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \
- ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \
- ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \
- ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \
- ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \
- ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \
- ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) ckuath.$(EXT) \
- ck_crp.$(EXT) ck_ssl.$(EXT)
- $(CC2) $(LNKFLAGS) -o wermit \
- ckcmai.$(EXT) ckclib.$(EXT) ckutio.$(EXT) ckufio.$(EXT) \
- ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \
- ckcpro.$(EXT) ckucmd.$(EXT) ckuus2.$(EXT) ckuus3.$(EXT) \
- ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) ckuus7.$(EXT) \
- ckuusx.$(EXT) ckuusy.$(EXT) ckuusr.$(EXT) ckucns.$(EXT) \
- ckudia.$(EXT) ckuscr.$(EXT) ckcnet.$(EXT) ckusig.$(EXT) \
- ckctel.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) \
- ckuath.$(EXT) ck_crp.$(EXT) ck_ssl.$(EXT) $(LIBS)
-
-# Malloc Debugging version
-
-mermit: ckcmdb.$(EXT) ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) \
- ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \
- ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \
- ckcpro.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) \
- ckuxla.$(EXT) ckucon.$(EXT) ckutio.$(EXT) ckufio.$(EXT) \
- ckudia.$(EXT) ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) \
- ckusig.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT)
- $(CC2) $(LNKFLAGS) -o mermit ckcmdb.$(EXT) ckclib.$(EXT) ckcmai.$(EXT)\
- ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) \
- ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) ckucmd.$(EXT) \
- ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \
- ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \
- ckuusr.$(EXT) ckucon.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) \
- ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) ckcuni.$(EXT) \
- ckupty.$(EXT) ckcftp.$(EXT) $(LIBS)
-
-# Kerberized Version - Subject to USA export restrictions.
-
-# NOTE: We don't use this any more -- As of 15 Feb 2003, the "xermit"
-# target is used for both secure and regular version.
-
-krbmit: ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \
- ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \
- ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \
- ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \
- ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \
- ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \
- ckuath.$(EXT) ck_crp.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) \
- ckcftp.$(EXT) ck_ssl.$(EXT)
- $(CC2) $(LNKFLAGS) -o krbmit ckcmai.$(EXT) ckclib.$(EXT) \
- ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) \
- ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) ckucmd.$(EXT) \
- ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \
- ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \
- ckuusr.$(EXT) ckucns.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) \
- ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) ckuath.$(EXT) \
- ck_crp.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) \
- ck_ssl.$(EXT) $(LIBS)
-
-krbmit-debug: ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) \
- ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \
- ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \
- ckcpro.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) \
- ckuxla.$(EXT) ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) \
- ckudia.$(EXT) ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) \
- ckusig.$(EXT) ckuath.$(EXT) ck_crp.$(EXT) ckcuni.$(EXT) \
- ckupty.$(EXT) ck_ssl.$(EXT) ckcmdb.$(EXT) ckcftp.$(EXT)
- $(CC2) $(LNKFLAGS) -o krbmit ckcmdb.$(EXT) ckcmai.$(EXT) \
- ckclib.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) \
- ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) \
- ckucmd.$(EXT) ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) \
- ckuus5.$(EXT) ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) \
- ckuusy.$(EXT) ckuusr.$(EXT) ckucns.$(EXT) ckudia.$(EXT) \
- ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \
- ckuath.$(EXT) ck_crp.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) \
- ckcftp.$(EXT) ck_ssl.$(EXT) $(LIBS)
-
-# SRP(TM) Version - Subject to USA export restrictions.
-
-srpmit: ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \
- ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \
- ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \
- ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \
- ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \
- ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \
- ckuath.$(EXT) ck_crp.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) \
- ckcftp.$(EXT) ck_ssl.$(EXT)
- $(CC2) $(LNKFLAGS) -o srpmit ckcmai.$(EXT) ckclib.$(EXT) \
- ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) \
- ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) ckucmd.$(EXT) \
- ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \
- ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \
- ckuusr.$(EXT) ckucns.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) \
- ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) ckuath.$(EXT) \
- ck_crp.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ck_ssl.$(EXT) \
- ckcftp.$(EXT) $(LIBS)
-
-# Kerberized Version - Not subject to USA export restrictions.
-
-krbmit-export: ckcmai.$(EXT) \
- ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \
- ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \
- ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \
- ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \
- ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \
- ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \
- ckuath.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT)
- $(CC2) $(LNKFLAGS) -o krbmit-export ckcmai.$(EXT) ckclib.$(EXT) \
- ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) \
- ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) ckucmd.$(EXT) \
- ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \
- ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \
- ckuusr.$(EXT) ckucns.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) \
- ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) ckuath.$(EXT) \
- ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) $(LIBS)
-
-# SRP(TM) Version - Not subject to USA export restrictions.
-
-srpmit-export: ckcmai.$(EXT) \
- ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \
- ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \
- ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \
- ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \
- ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \
- ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \
- ckuath.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT)
- $(CC2) $(LNKFLAGS) -o srpmit-export ckcmai.$(EXT) ckclib.$(EXT) \
- ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) \
- ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) ckucmd.$(EXT) \
- ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \
- ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \
- ckuusr.$(EXT) ckucns.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) \
- ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) ckuath.$(EXT) \
- ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) $(LIBS)
-
-###########################################################################
-# man page...
-#
-ckuker.nr:
- @echo This target is obsolete.
- @echo The ckuker.nr file no longer needs any preprocessing.
-
-###########################################################################
-# Dependencies for each module...
-#
-ckcmai.$(EXT): ckcmai.c ckcker.h ckcdeb.h ckcsym.h ckcasc.h ckcnet.h ckcsig.h \
- ckuusr.h ckctel.h ckclib.h
-
-ckclib.$(EXT): ckclib.c ckclib.h ckcdeb.h ckcasc.h ckcsym.h
-
-ckcpro.$(EXT): ckcpro.c ckcker.h ckcdeb.h ckcsym.h ckcasc.h ckclib.h
-
-ckcpro.c: ckcpro.w wart ckcdeb.h ckcsym.h ckcasc.h ckcker.h ckcnet.h ckctel.h \
- ckclib.h
- ./wart ckcpro.w ckcpro.c
-
-ckcfns.$(EXT): ckcfns.c ckcker.h ckcdeb.h ckcsym.h ckcasc.h ckcxla.h ckcuni.h \
- ckuxla.h ckclib.h ckcnet.h
-
-ckcfn2.$(EXT): ckcfn2.c ckcker.h ckcdeb.h ckcsym.h ckcasc.h ckcxla.h \
- ckuxla.h ckctel.h ckclib.h ckcnet.h ckcuni.h
-
-ckcfn3.$(EXT): ckcfn3.c ckcker.h ckcdeb.h ckcsym.h ckcasc.h ckcxla.h \
- ckuxla.h ckclib.h ckcuni.h
-
-ckuxla.$(EXT): ckuxla.c ckcker.h ckcsym.h ckcdeb.h ckcxla.h ckuxla.h ckclib.h \
- ckcuni.h
-
-ckcuni.$(EXT): ckcuni.c ckcdeb.h ckcker.h ckucmd.h ckcuni.h ckcxla.h ckuxla.h
-
-ckuusr.$(EXT): ckuusr.c ckucmd.h ckcker.h ckuusr.h ckcsym.h ckcdeb.h ckcxla.h \
- ckuxla.h ckcasc.h ckcnet.h ckctel.h ckclib.h ckcuni.h
-
-ckuus2.$(EXT): ckuus2.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcxla.h ckuxla.h \
- ckcasc.h ckcnet.h ckcsym.h ckctel.h ckclib.h ckcuni.h
-
-ckuus3.$(EXT): ckuus3.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcxla.h ckuxla.h \
- ckcasc.h ckcnet.h ckcsym.h ckctel.h ckclib.h ckcuni.h
-
-ckuus4.$(EXT): ckuus4.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcxla.h ckuxla.h \
- ckcasc.h ckcnet.h ckuver.h ckcsym.h ckctel.h ckclib.h ckcuni.h
-
-ckuus5.$(EXT): ckuus5.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcasc.h ckcnet.h \
- ckcsym.h ckctel.h ckclib.h ckcxla.h ckuxla.h ckcuni.h
-
-ckuus6.$(EXT): ckuus6.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcasc.h ckcnet.h \
- ckcsym.h ckctel.h ckclib.h
-
-ckuus7.$(EXT): ckuus7.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcxla.h ckuxla.h \
- ckcasc.h ckcnet.h ckcsym.h ckctel.h ckclib.h ckcuni.h
-
-ckuusx.$(EXT): ckuusx.c ckcker.h ckuusr.h ckcdeb.h ckcasc.h ckcsym.h \
- ckcsig.h ckcnet.h ckctel.h ckclib.h ckcxla.h ckuxla.h ckcuni.h
-
-ckuusy.$(EXT): ckuusy.c ckcker.h ckcdeb.h ckcasc.h ckcnet.h ckcsym.h ckctel.h \
- ckclib.h
-
-ckucmd.$(EXT): ckucmd.c ckcasc.h ckucmd.h ckcdeb.h ckcsym.h ckctel.h ckclib.h
-
-ckufio.$(EXT): ckufio.c ckcdeb.h ckuver.h ckcsym.h ckclib.h \
- ckcxla.h ckuxla.h ckcuni.h
-
-ckutio.$(EXT): ckutio.c ckcdeb.h ckcnet.h ckuver.h ckcsym.h ckctel.h ckclib.h
-
-ckucon.$(EXT): ckucon.c ckcker.h ckcdeb.h ckcasc.h ckcnet.h ckcsym.h ckctel.h \
- ckclib.h
-
-ckucns.$(EXT): ckucns.c ckcker.h ckcdeb.h ckcasc.h ckcnet.h ckcsym.h ckctel.h \
- ckclib.h ckcxla.h ckuxla.h ckcuni.h
-
-ckcnet.$(EXT): ckcnet.c ckcdeb.h ckcker.h ckcnet.h ckcsym.h ckcsig.h ckctel.h \
- ckclib.h
-
-ckctel.$(EXT): ckcsym.h ckcdeb.h ckcker.h ckcnet.h ckctel.h ckclib.h
-
-# ck_off_t: ck_off_t.$(EXT)
-# $(CC) -o ck_off_t ck_off_t.$(EXT)
-
-wart: ckwart.$(EXT)
- $(CC) $(LNKFLAGS) -o wart ckwart.$(EXT) $(LIBS)
-
-ckcmdb.$(EXT): ckcmdb.c ckcdeb.h ckcsym.h ckclib.h
-
-ckwart.$(EXT): ckwart.c
-
-ckudia.$(EXT): ckudia.c ckcker.h ckcdeb.h ckucmd.h ckcasc.h ckcsym.h ckcsig.h \
- ckcnet.h ckctel.h ckclib.h
-
-ckuscr.$(EXT): ckuscr.c ckcker.h ckcdeb.h ckcasc.h ckcsym.h ckcsig.h \
- ckcnet.h ckctel.h ckclib.h
-
-ckusig.$(EXT): ckusig.c ckcasc.h ckcdeb.h ckcker.h ckcnet.h ckuusr.h \
- ckcsig.h ckctel.h ckclib.h
-
-ckcftp.$(EXT): ckcftp.c ckcdeb.h ckcasc.h ckcker.h ckucmd.h ckuusr.h \
- ckcnet.h ckctel.h ckcxla.h ckuxla.h ckcuni.h
-
-ckupty.$(EXT): ckupty.c ckupty.h ckcdeb.h
-
-ckuath.$(EXT): ckuath.c ckcdeb.h ckucmd.h ckuath.h ckuat2.h ckctel.h \
- ckclib.h ckcnet.h
-
-ck_crp.$(EXT): ck_crp.c ckcdeb.h ckcnet.h ckuath.h ckclib.h
-
-ck_ssl.$(EXT): ck_ssl.c ckcdeb.h ckucmd.h ckuath.h ckuat2.h ckctel.h \
- ckclib.h ck_ssl.h
-
-###########################################################################
-#
-# Entries to make C-Kermit for specific systems.
-#
-# Put the ones that need short makefiles first.
-
-#Apollo Aegis 9.x. Includes TCP/IP support.
-#You can also add processor-dependent optimization switches like -M570.
-aegis:
- @echo Making C-Kermit $(CKVER) for Apollo Aegis 9.x...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DNOCSETS -DCK_CURSES -O $(KFLAGS)" \
- "LIBS = -lcurses -ltermcap"
-
-#Apple Mac II, A/UX pre-3.0
-#Warning, if "send *" doesn't work, try the auxufs makefile entry below.
-aux:
- @echo Making C-Kermit $(CKVER) for Macintosh A/UX...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DAUX -DTCPSOCKET $(KFLAGS) -i -O" "LNKFLAGS = -i"
-
-#Apple Mac II, A/UX pre-3.0, compiled with gcc
-auxgcc:
- @echo Making C-Kermit $(CKVER) for Macintosh A/UX...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DAUX -DTCPSOCKET -traditional $(KFLAGS) -i -O" \
- "LNKFLAGS = " "CC = gcc" "CC2 = gcc"
-
-#Apple Mac II, A/UX, pre-3.0, but with ufs file volumes, uses <dirent.h>.
-auxufs:
- @echo Making C-Kermit $(CKVER) for Macintosh A/UX...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DAUX -DTCPSOCKET -DDIRENT $(KFLAGS) -i -O" "LNKFLAGS = -i"
-
-#Apple Mac II, A/UX 3.0, compiled with gcc
-aux3gcc:
- @echo Making C-Kermit $(CKVER) for Macintosh A/UX 3.0...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DAUX -DHDBUUCP -DLFDEVNO -DTCPSOCKET -DDIRENT $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS = $(LIBS)" \
- "CC=gcc -pipe -traditional" "CC2=gcc -pipe -traditional"
-
-#Apple Mac II, A/UX 3.0, compiled with gcc, uses curses
-aux3cgcc:
- @echo Making C-Kermit $(CKVER) for Macintosh A/UX 3.0...
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) aux3gcc \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -DCK_CURSES" "LIBS = -lcurses $(LIBS)"
-
-# Tenon MachTen, tested on Apple Powerbook with MachTen 2.1.1.D.
-# NOTE: This doesn't do anything about UUCP. It only works if /usr/spool/uucp
-# has permission of 777, and dialout device is world read/writeable.
-machten:
- @echo Making C-Kermit $(CKVER) for MachTen...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD43 -DTCPSOCKET -DSIG_V -DNDGPWNAM -DCK_CURSES -O \
- $(KFLAGS)" "LIBS=-lcurses -ltermcap"
-
-#Bell Labs Research UNIX V10
-#Can't add TCP/IP because there is no sockets library. It would have to
-#be done using streams, but there is no code in C-Kermit for that.
-#Remove -DNOJC if desired (if your system has csh, ksh, or bash).
-bellv10:
- @echo Making C-Kermit $(CKVER) for Bell Labs Research UNIX V10...
- $(MAKE) wermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBELLV10 -DBSD4 -DNDIR -DNOJC -DNOSYSIOCTLH -DNOSETREU \
- -DNOCSETS -MINIDIAL $(KFLAGS)"
-
-# WARNING: The early BSD entries do not build in version 7.0 with the stock
-# BSD compiler: "Too many defines". Unless you can rebuild cpp to have more
-# space for defines, these builds must be accomplished by:
-# copying the /usr/include tree to someplace else, preprocessing there with cc
-# -E -I./include or whatever (plus all the same -D's, adding any necessary
-# -U/-D to override the architecture)), renaming the the resulting files back
-# to their original names, bringing them back to the original BSD system, and
-# running the make target there. This technique was used for 4.2 and 4.3 BSD
-# on a VAX in C-Kermit 7.0 (later, cpp on that machine was rebuilt to allow
-# more symbols, so the C-Kermit 8.0 build proceeds normally).
-
-#Berkeley Unix 4.1
-bsd41:
- @echo Making C-Kermit $(CKVER) for 4.1BSD...
- $(MAKE) wermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD41" "LIBS = -ljobs"
-
-#Berkeley 4.2, 4.3, also Ultrix-32 1.x, 2.x, 3.x, many others
-# Add -O, -s, etc, if they work.
-# If you have a version of BSD but signal() is void rather than int,
-# "make bsd KFLAGS=-DSIG_V".
-bsd42:
- @echo Making C-Kermit $(CKVER) for 4.2BSD...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DNOREALPATH -DNOTIMEH -DNOIKSD \
- -DCK_CURSES -DSYSTIMEBH -DNOPUTENV -DNOANSI -DBIGBUFOK -DBSD42HACK \
- $(KFLAGS)" "LIBS=-lcurses -ltermcap $(LIBS)"
-
-bsd:
- $(MAKE) CC=$(CC) CC2=$(CC2) bsd42 KTARGET=$${KTARGET-$(@)}
-
-#Berkeley Unix 4.2 or 4.3 with HoneyDanBer UUCP
-bsdhdb:
- @echo Making C-Kermit $(CKVER) for 4.2BSD with HDB UUCP...
- $(MAKE) CC=$(CC) CC2=$(CC2) bsd KTARGET=$${KTARGET-$(@)} \
- "KFLAGS= -DHDBUUCP $(KFLAGS)"
-
-#Berkeley Unix 4.3 with acucntrl program, curses, TCP/IP included.
-bsd43:
- @echo Making C-Kermit $(CKVER) for 4.3BSD...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DBSD43 -DTCPSOCKET -DNOREALPATH -DNOTIMEH -DNOIKSD \
- -DCK_CURSES -DACUCNTRL -DSYSTIMEBH -DNOPUTENV -DNOANSI -DBIGBUFOK \
- -DBSD42HACK $(KFLAGS)" "LIBS=-lcurses -ltermcap $(LIBS)"
-
-#4.3BSD, curses excluded
-bsd43nc:
- @echo Making C-Kermit $(CKVER) for 4.3BSD...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DBSD43 -DTCPSOCKET -DNOREALPATH -DNOTIMEH \
- -DACUCNTRL -DSYSTIMEBH -DNOIKSD -DNOPUTENV -DNOANSI -DBIGBUFOK \
- -DBSD42HACK $(KFLAGS)" "LIBS=$(LIBS)"
-
-#4.3BSD, TCP/IP excluded.
-bsd43nonet:
- @echo Making C-Kermit $(CKVER) for 4.3BSD + curses...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DBSD43 -DTCPSOCKET -DNOREALPATH -DNOTIMEH -DNOIKSD \
- -DCK_CURSES -DACUCNTRL -DSYSTIMEBH -DNOPUTENV -DNOANSI -DBIGBUFOK \
- -DBSD42HACK -DNONET $(KFLAGS)" "LIBS=-lcurses -ltermcap $(LIBS)"
-
-#Berkeley Unix 4.2 or 4.3 with lock directory /usr/spool/uucp/LCK/LCK..ttyxx,
-#but without acucntrl program
-bsdlck:
- @echo Making C-Kermit $(CKVER) for 4.2BSD, /usr/spool/uucp/LCK/...
- $(MAKE) CC=$(CC) CC2=$(CC2) bsd KTARGET=$${KTARGET-$(@)} \
- "KFLAGS= -DLCKDIR $(KFLAGS)"
-
-#Berkeley UNIX 4.4-Lite, 4.4-Encumbered, Net/2, etc (Post-Reno),
-#with TCP/IP networking. This was the basis for FreeBSD, NetBSD, OpenBSD,
-#BSDI, BSD/OS, and Mac OS X (each of which has its own set of targets that
-#are newer than this one).
-#
-#NOTE: This is not a pure POSIX configuration. Using -DPOSIX instead of
-# -DBSD44 prevents any kind of directory-reading (for wildcard expansion),
-#and disallows use of ENOTCONN symbol for detecting broken network
-#connections, and disallows RTS/CTS flow control, and would also require
-#definition of the appropriate UUCP lockfile convention.
-#Do not add -DCK_POSIX_SIG without reading <signal.h> first! For example,
-#sigsetjmp(), etc, tend to be defined but not implemented.
-#
-#NOTE: originally crypt was in libc - later it was unbundled.
-#Remove the LIBS clause to build on an early 4.4BSD platform.
-#
-bsd44:
- @echo Making C-Kermit $(CKVER) for 4.4BSD...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DTCPSOCKET $(KFLAGS) -O" "LIBS=-lcrypt"
-
-#Berkeley UNIX 4.4, as above, but with curses for fullscreen display
-#Please read notes for bsd44 entry just above.
-# NOTE: This one dumped core on the real 4.4BSD development system at
-# UC Berkeley (an HP-9000/300), so the no-curses version was used
-# for that one, which was unplugged years ago.
-bsd44c:
- @echo Making C-Kermit $(CKVER) for 4.4BSD with curses...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET $(KFLAGS) -O" \
- "LIBS= -lcurses -ltermcap -lcrypt $(LIBS)"
-
-#For FreeBSD 1.x.
-freebsd1:
- @echo 'Making C-Kermit $(CKVER) for FreeBSD...'
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DNOCOTFMC -funsigned-char \
- -DFNFLOAT -DNOHTERMCAP -DNOREALPATH -DNOSYSCONF $(KFLAGS) -O -pipe" \
- "LIBS= -lcurses -ltermcap -lm $(LIBS)"
-
-#FreeBSD 2.x with ncurses
-freebsd2:
- @echo 'Making C-Kermit $(CKVER) for FreeBSD 2.x with ncurses...'
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_NCURSES -DTCPSOCKET -DNOCOTFMC -DUSE_STRERROR \
- -DTPUTSARGTYPE=int -DTPUTSARG1CONST -DFREEBSD2 -funsigned-char \
- -DFNFLOAT $(KFLAGS) -O -pipe" \
- "LIBS= -lncurses -ltermlib -lcrypt -lm $(LIBS)"
-
-#For FreeBSD 2.x -- Uses curses rather than ncurses
-freebsd2c:
- @echo 'Making C-Kermit $(CKVER) for FreeBSD 2.x with curses...'
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DNOCOTFMC -DUSE_STRERROR \
- -DTPUTSARGTYPE=int -DTPUTSARG1CONST -DFREEBSD2 -DFNFLOAT \
- -funsigned-char $(KFLAGS) -O -pipe" \
- "LIBS= -lcurses -ltermlib -lcrypt -lm $(LIBS)"
-
-#FreeBSD 3.x with ncurses and uu_lock()
-#(Note: uu_lock() goes back to 2.2.2, but not necessarily 2.0)
-#OK 2011/08/20 FreeBSD 3.3
-freebsd3:
- @echo 'Making C-Kermit $(CKVER) for FreeBSD 3.x with ncurses...'
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_NCURSES -DTCPSOCKET -DNOCOTFMC -funsigned-char \
- -DTPUTSARGTYPE=int -DUSE_STRERROR -DFREEBSD3 -DUSE_UU_LOCK -DFNFLOAT \
- $(KFLAGS) -O -pipe" \
- "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)"
-
-#As above but with curses rather than ncurses.
-freebsd3c:
- @echo 'Making C-Kermit $(CKVER) for FreeBSD 3.x with curses...'
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DNOCOTFMC -DUSE_UU_LOCK \
- -DTPUTSARGTYPE=int -DUSE_STRERROR -DFREEBSD3 $(KFLAGS) -DFNFLOAT \
- -funsigned-char -pipe -O" \
- "LIBS= -lcurses -lcrypt -lutil -lm $(LIBS)"
-
-#FreeBSD 4.0 with ncurses and uu_lock(). Note - there is no curses in 4.0.
-#ncurses 5.0 is broken requiring us to work around with setbuf().
-freebsd40:
- @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.x with ncurses...'
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_NCURSES -DTCPSOCKET -DNOCOTFMC -DFNFLOAT \
- -funsigned-char -DTPUTSARGTYPE=int -DUSE_STRERROR -DFREEBSD4 \
- -DNONOSETBUF -DUSE_UU_LOCK $(KFLAGS) -O -pipe" \
- "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)"
-
-#FreeBSD 4.1 and above
-#Like FreeBSD 4.0 but without the NONOSETBUF hack and with CK_NEWTERM.
-#NOTE: This target definitely does not work for FreeBSD 3.3 in 9.0.302.
-#and it has not been tested on 4 or 5.
-#OK 2011/06/xx FreeBSD 3.3, 4,4, 4.7, and 8.2
-#OK 2011/08/21 FreeBSD 3.3, 4.4, 6.4, 9.0
-freebsd freebsd41 freebsd72 freebsd5 freebsd6 freebsd7 freebsd8 freebsd9:
- @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.1 or later...'
- @if test `uname -r | cut -d . -f 1` -ge 8; then \
- HAVE_FBSD8='-DFREEBSD8'; \
- else HAVE_FBSD8=''; fi; \
- if test `uname -r | cut -d . -f 1` -ge 9; then \
- HAVE_FBSD9='-DFREEBSD9'; \
- else HAVE_FBSD9=''; fi; \
- if test -f /usr/include/utmpx.h ; \
- then HAVE_UTMPX='-DHAVEUTMPX' ; \
- else HAVE_UTMPX='' ; fi; \
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \
- -DFREEBSD4 $$HAVE_FBSD8 $$HAVE_FBSD9 -DUSE_UU_LOCK -DFNFLOAT \
- $$HAVE_UTMPX -DHERALD=\"\\\" `uname -rs`\\\"\" \
- -funsigned-char -DTPUTSARGTYPE=int -DUSE_STRERROR $(KFLAGS) \
- -O2 -pipe"\
- "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)"
-
-#FreeBSD 5.0 or later with OpenSSL.
-#OK 2011/06/15 FreeBSD 4.7 and 8.2
-#OK 2011/08/20 FreeBSD 9.0-CURRENT
-freebsd+ssl freebsd+openssl freebsd50+openssl:
- @echo 'Making C-Kermit $(CKVER) for FreeBSD with Kerberos 5...'
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac; \
- HAVE_DES=''; \
- DES_LIB=''; \
- if ls /usr/lib/libdes* > /dev/null 2> /dev/null || \
- ls $(SSLLIB)/libdes* > /dev/null 2> /dev/null; then \
- DES_LIB='-ldes'; \
- HAVE_DES='-DCK_DES -DLIBDES'; \
- echo "HAVE DES"; \
- else echo "NO DES"; \
- fi; \
- $(MAKE) freebsd KTARGET=$${KTARGET:-$(@)} "CC = $(CC)" "CC2 = $(CC2)" \
- KFLAGS="-DCK_AUTHENTICATION -DCK_SSL $(SSLINC) -DZLIB $$OPENSSLOPTION \
- $$HAVE_DES $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS= -lncurses -lcrypt -lssl -lcrypto -lutil -lm \
- $(SSLLIB) $$DES_LIB $(LIBS)"; \
- if [ ! -f ./wermit ] || [ ./ckcmai.o -nt ./wermit ] ; then \
- echo ""; \
- echo "If build failed try:"; \
- echo ""; \
- echo " make clean ; make $${KTARGET:-$(@)} KFLAGS=-UCK_DES"; \
- echo ""; \
- fi
-
-#NetBSD 1.4.1 or later with vanity banner automated with uname
-#and automatic inclusion of large file support if it is available.
-#This target tested successfully on NetBSD 1.4.1, 1.5.2, and 2.0.3 (Jan 2006).
-#Fails on NetBSD 2.0 on Sun/3 mc68030 with gcc 3.3.3 unless optimization is
-#disabled on ckcfn2.c ("KFLAGS=-O0") (Letter O Digit Zero).
-#(This could be automated by testing `uname -m` for "sun3".)
-#OK: 2011/06/15 on NetBSD 1.5.2 and 5.1.
-#OK: 2011/08/21 on 5.1.
-netbsd netbsd2 netbsd15 netbsd16 old-netbsd:
- @echo Making C-Kermit $(CKVER) for NetBSD with curses...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS=`grep fseeko /usr/include/stdio.h > /dev/null && \
- echo '-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'` \
- -DBSD44 -DCK_CURSES -DTCPSOCKET -DUSE_STRERROR -DHAVE_OPENPTY \
- -funsigned-char -DHERALD=\"\\\" NetBSD `uname -r`\\\"\" \
- -DCK_DTRCD -DCK_DTRCTS -DTPUTSARGTYPE=int -DFNFLOAT $(KFLAGS) -O" \
- "LIBS= -lcurses -lcrypt -lm -lutil $(LIBS)"
-
-#NetBSD 1.4.1 or later with OpenSSL
-#OK: 2011/06/15 on NetBSD 5.1 (but not 1.5.2 with OpenSSL 0.9.5a)
-#OK: 2011/08/21 on 5.1.
-netbsd+ssl netbsd+openssl:
- @echo 'Making C-Kermit $(CKVER) for NetBSD+OpenSSL SSLLIB=$(SSLLIB)'
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac; \
- HAVE_DES=''; \
- DES_LIB=''; \
- if ls /usr/lib/libdes* > /dev/null 2> /dev/null || \
- ls $(SSLLIB)/libdes* > /dev/null 2> /dev/null; then \
- DES_LIB='-ldes'; \
- HAVE_DES='-DCK_DES -DLIBDES'; \
- echo "HAVE DES"; \
- else echo "NO DES"; \
- fi; \
- $(MAKE) netbsd KTARGET=$${KTARGET:-$(@)} "CC = $(CC)" "CC2 = $(CC2)" \
- "KFLAGS= -DCK_AUTHENTICATION -DCK_ENCRYPTION -DCK_CAST $$HAVE_DES \
- -DCK_SSL -DCK_PAM -DZLIB -DNO_DCL_INET_ATON $$OPENSSLOPTION \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS= -L/usr/pkg/lib -R/usr/pkg/lib -lssl $$DES_LIB -lcurses \
- -lcrypto -lcrypt -lz -lm -lpam -lutil $(LIBS)"
-
-#NetBSD with MIT Kerberos 5:
-# OK 2011/06/15 (once K5INC and K5LIB were set right).
-# NOT OK for Heimdal - Heimdal Kerberos support in C-Kermit needs work.
-# OK: 2011/08/21 on 5.1.
-netbsd+krb5:
- @echo 'Making C-Kermit $(CKVER) for NetBSD with Kerberos 5...'
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac; \
- HAVE_DES=''; \
- DES_LIB=''; \
- if ls /usr/lib/libdes* > /dev/null 2> /dev/null || \
- ls $(SSLLIB)/libdes* > /dev/null 2> /dev/null; then \
- DES_LIB='-ldes'; \
- HAVE_DES='-DCK_DES -DLIBDES'; \
- echo "HAVE DES"; \
- else echo "NO DES"; \
- fi; \
- $(MAKE) netbsd KTARGET=$${KTARGET:-$(@)} "CC = $(CC)" "CC2 = $(CC2)" \
- "KFLAGS= -DCK_AUTHENTICATION -DCK_ENCRYPTION -DCK_KERBEROS -DKRB5 \
- -DCK_CAST $$HAVE_DES -DNOFTP_GSSAPI $(K5INC) $(K5INC)/krb5 \
- $(KFLAGS)" \
- "LIBS= $(K5LIB) -L/usr/pkg/lib -R/usr/pkg/lib -lcurses $$DES_LIB \
- -lcrypto -lgssapi -lkrb5 -lm -lutil $(LIBS)"
-
-# NetBSD - With Kerberos 5 and SSL and Zlib.
-# OK: 2011/08/21 on 5.1 with MIT Kerberos.
-netbsd+krb5+ssl netbsd+krb5+openssl+zlib:
- @echo 'Making C-Kermit $(CKVER) for NetBSD+OpenSSL+Kerberos5...'
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac; \
- HAVE_DES=''; \
- DES_LIB=''; \
- if ls /usr/lib/libdes* > /dev/null 2> /dev/null || \
- ls $(SSLLIB)/libdes* > /dev/null 2> /dev/null; then \
- DES_LIB='-ldes'; \
- HAVE_DES='-DCK_DES -DLIBDES'; \
- echo "HAVE DES"; \
- else echo "NO DES"; \
- fi; \
- $(MAKE) netbsd KTARGET=$${KTARGET:-$(@)} "CC = $(CC)" "CC2 = $(CC2)" \
- "KFLAGS= -DCK_AUTHENTICATION -DCK_ENCRYPTION -DCK_CAST $$HAVE_DES \
- -DCK_KERBEROS -DKRB5 -DNOFTP_GSSAPI $(K5INC) $(K5INC)/krb5 \
- -DCK_SSL -DCK_PAM -DZLIB -DNO_DCL_INET_ATON $$OPENSSLOPTION \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS= $(K5LIB) -L/usr/pkg/lib -R/usr/pkg/lib -lssl $$DES_LIB \
- -lcrypto -lcrypt -lgssapi -lkrb5 -lz -lm -lpam -lutil -lcurses $(LIBS)"
-
-#Special Security Enhanced NetBSD target with SRP, SSL, and zlib support.
-#To build this, you need to BUILD the pkgsrc srp_client package. After
-#you build it, you must go into work/srp-x.y.z/libkrypto and "bmake install"
-#then go to work/srp-x.y.z/libsrp and "bmake install". As of 2005Q3, the
-#pkgsrc install only installed the statically linked client applications. You
-#need to manually install the libraries to build your own applications.
-#NOT TESTED RECENTLY - probably needs work.
-netbsd+ssl+srp+zlib:
- @echo Making C-Kermit $(CKVER) for NetBSD with curses...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DUSE_STRERROR -DNETBSD15 \
- -DCK_DTRCD -DCK_DTRCTS -DTPUTSARGTYPE=int -DHAVE_OPENPTY \
- -I/usr/include/openssl -I/usr/pkg/include \
- -DCK_AUTHENTICATION -DCK_SRP -DPRE_SRP_1_4_5 -DCK_ENCRYPTION \
- -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DZLIB -DFNFLOAT $(KFLAGS) -O" \
- "LIBS= -L/usr/pkg/lib -R/usr/pkg/lib -lcurses -lsrp -lgmp -ldes \
- -lssl -lkrypto -lcrypto -lcrypt -lz -lm -lutil $(LIBS)"
-
-#NetBSD with curses left out (e.g. for use as IKSD).
-netbsdnc:
- @echo Making C-Kermit $(CKVER) for NetBSD with no curses...
- $(MAKE) CC=$(CC) CC2=$(CC2) netbsd KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DNOCURSES"
-
-#NetBSD with ncurses requested explicitly rather than curses-which-is-ncurses
-netbsdn:
- @echo Making C-Kermit $(CKVER) for NetBSD with curses...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS=`grep fseeko /usr/include/stdio.h > /dev/null && \
- echo '-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'` \
- -DBSD44 -DCK_CURSES -DTCPSOCKET -DUSE_STRERROR -DHAVE_OPENPTY \
- -DHERALD=\"\\\" NetBSD `uname -r`\\\"\" \
- -DCK_DTRCD -DCK_DTRCTS -DTPUTSARGTYPE=int -DFNFLOAT $(KFLAGS) -O" \
- "LIBS= -L/usr/pkg/lib -lncurses -lcrypt -lm -lutil $(LIBS)"
-
-#OpenBSD before 2.3.
-#Uses ncurses as its curses so use -ltermlib, not -ltermcap
-#But it doesn't use uu_lock() which was introduced in OpenBSD 2.3.
-#For that use the next entry.
-#Add -DMAINTYPE=int if you get complaints about main: return type is not int.
-openbsdold:
- @echo Making C-Kermit $(CKVER) for OpenBSD...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_CURSES -DCK_NEWTERM -DTCPSOCKET -DOPENBSD \
- -DFNFLOAT -DNDSYSERRLIST $(KFLAGS) -O" "LIBS= -lcurses -ltermlib -lm"
-
-#OpenBSD 2.3 or later
-#Add -DMAINTYPE=int if you get complaints about main: return type is not int.
-#For C-Kermit 8.0 (Christian Weisgerber):
-# -ltermlib removed (presumably because -lcurses==ncurses already includes it)
-# -DUSE_UU_LOCK and -lutil added for uu_lock()
-# -DNDSYSERRLIST changed to -DUSE_STRERROR
-#If this gives you trouble use the previous entry.
-#NOTE: The openbsd and openbsd+ssl should be reworked to be like the
-#corresponding FreeBSD and NetBSD targets. The mirbsd targets should
-openbsd:
- @echo Making C-Kermit $(CKVER) for OpenBSD 2.3 or later...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_CURSES -DCK_NEWTERM -DTCPSOCKET -DOPENBSD \
- -DHERALD=\"\\\" OpenBSD `uname -r`\\\"\" \
- -DUSE_UU_LOCK -DFNFLOAT -DUSE_STRERROR $(KFLAGS) -O" \
- "LIBS= -lcurses -lutil -lm"
-
-#Better to chain to the openbsd target but...
-mirbsd:
- @echo Making C-Kermit $(CKVER) for OpenBSD 2.3 or later...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_CURSES -DCK_NEWTERM -DTCPSOCKET -DOPENBSD \
- -DHERALD=\"\\\" MirBSD `uname -r`\\\"\" \
- -DUSE_UU_LOCK -DFNFLOAT -DUSE_STRERROR $(KFLAGS) -O" \
- "LIBS= -lcurses -lutil -lm"
-
-#OpenBSD 3.0 or later includes OpenSSL
-#Add -DMAINTYPE=int if you get complaints about main: return type is not int.
-#For C-Kermit 8.0 (Christian Weisgerber):
-# -ltermlib removed (presumably because -lcurses==ncurses already includes it)
-# -DUSE_UU_LOCK and -lutil added for uu_lock()
-# -DNDSYSERRLIST changed to -DUSE_STRERROR
-#If this gives you trouble use the previous entry.
-openbsd+ssl:
- @echo Making C-Kermit $(CKVER) for OpenBSD 3.0 or later...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_CURSES -DCK_NEWTERM -DTCPSOCKET -DOPENBSD \
- -DHERALD=\"\\\" OpenBSD `uname -r`\\\"\" \
- -DUSE_UU_LOCK -DFNFLOAT -DUSE_STRERROR -DCK_AUTHENTICATION \
- -DCK_SSL $(KFLAGS) -O" \
- "LIBS= -lcurses -lutil -lm -lssl -lcrypto"
-
-mirbsd+ssl:
- @echo Making C-Kermit $(CKVER) for OpenBSD 3.0 or later...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DCK_CURSES -DCK_NEWTERM -DTCPSOCKET -DOPENBSD \
- -DHERALD=\"\\\" MirBSD `uname -r`\\\"\" \
- -DUSE_UU_LOCK -DFNFLOAT -DUSE_STRERROR -DCK_AUTHENTICATION \
- -DCK_SSL -DNO_DCL_INET_ATON $(KFLAGS) -O" \
- "LIBS= -lcurses -lutil -lm -lssl -lcrypto"
-
-# make 386bsd 0.0new, posix
-# for 386bsd 0.1.24, change /usr/include/termios.h to #define NCCS if
-# _POSIX_SOURCE is #defined. (source: lewine, posix prgmrs guide, o`reilly)
-#NOTE: Lock directory is /var/spool/lock. Formerly, it was /var/spool/uucp,
-#but reportedly <wjones@halcyon.com> that was due to a typo in 'man tip'.
-386bsd:
- @echo 'Making C-Kermit $(CKVER) for jolix 386BSD 0.0new and 0.1.24...'
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPOSIX -DSETREUID -DPIDSTRING -DUSLEEP \
- -D_386BSD -DCK_CURSES -DTCPSOCKET \
- -DLOCK_DIR=\\\"/var/spool/lock\\\" \
- $(KFLAGS) -O" "LNKFLAGS = -s" "LIBS = -lcurses -ltermcap"
-
-# Mac OS X 10 early versions.
-# For 10.3.9 and later, use the macosx target below.
-
-#Mac OS X 1.0 (Rhapsody, Darwin) -- TCP/IP but no curses.
-oldmacosx10:
- @echo Making C-Kermit $(CKVER) for `uname -s`...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DMACOSX10 -DTCPSOCKET -DUSE_STRERROR -O $(KFLAGS)"
-
-#Mac OS X 1.0 (Rhapsody, Darwin) -- TCP/IP and curses.
-#Note: curses must be obtained separately. See next entry for ncurses.
-#Add "LIBS = -lcurses -ltermcap" if necessary (but reportedly it is not).
-oldmacosx10c:
- @echo Making C-Kermit $(CKVER) for `uname -s` + curses...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DMACOSX10 -DCK_CURSES -DTPUTSFNTYPE=void -DTPUTSISVOID \
- -DTCPSOCKET -DUSE_STRERROR -O $(KFLAGS)"
-
-#Mac OS X 1.0 (Rhapsody, Darwin) -- TCP/IP and ncurses.
-#Note: ncurses must be obtained separately.
-#In the event of trouble with this one try the next one.
-oldmacosx10nc:
- @echo Making C-Kermit $(CKVER) for `uname -s` + ncurses...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DMACOSX10 -DCK_NCURSES -DTCPSOCKET -DUSE_STRERROR -O \
- $(KFLAGS)" "LIBS= -lncurses $(LIBS)"
-
-#Mac OS X 10.2 (Jaguar) ncurses.
-oldmacosx102nc:
- @echo Making C-Kermit $(CKVER) for `uname -s` + ncurses...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DMACOSX10 -DCK_NCURSES -DTCPSOCKET -DUSE_STRERROR -O \
- $(KFLAGS) " "LIBS= -lncurses $(LIBS)"
-
-#The problem here is that if curses.h also exists, it conflicts with
-#ncurses.h and and we have fatal errors. If this happens to you, then
-#try this target.
-oldmacosx10ncx:
- @echo Making C-Kermit $(CKVER) for `uname -s` + ncurses...
- @rm -f ./curses.h; touch ./curses.h
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DMACOSX10 -DCK_NCURSES -DTCPSOCKET -DUSE_STRERROR \
- -I. -O $(KFLAGS) " \
- "LIBS= -lncurses $(LIBS)"
- @rm -f ./curses.h
-
-#Mac OS X 10.3 (Panther) - Assumes ncurses is installed.
-oldmacosx103:
- @echo Making C-Kermit $(CKVER) for `uname -s` + ncurses...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DMACOSX10 -DMACOSX103 -DCK_NCURSES -DTCPSOCKET -DCKHTTP \
- -DUSE_STRERROR -DUSE_NAMESER_COMPAT -O \
- $(KFLAGS) " "LIBS= -lncurses -lresolv $(LIBS)"
-
-#Mac OS X 10.3 (Panther) with Kerberos 5 and SSL, assumes ncurses is installed.
-oldmacosx103+secure:
- @echo Making Secure C-Kermit $(CKVER) for `uname -s` + ncurses...
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DMACOSX10 -DMACOSX103 -DCK_NCURSES -DTCPSOCKET \
- -DUSE_STRERROR -DUSE_NAMESER_COMPAT -O -DCK_PAM \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DZLIB \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL \
- $(KFLAGS) " "LIBS= -lssl -lcrypto -lkrb5 -lcom_err \
- -lk5crypto -lgssapi_krb5 -lpam -lncurses -lresolv $(LIBS)"
-
-# THIS IS THE MAIN MAC OS X TARGET (the next one is for Kerberos/SSL builds).
-# Use this target for 10.3.9 (or maybe earlier) through 10.6 (maybe later)
-# on both Power and Intel architectures. This one uses utmp.h on 10.4 and
-# earlier and utmpx.h on 10.5 onwards.
-# Note: Mac OS X 10.5 and earlier are 32-bit; 10.6 and later 64-bit.
-# Note 2: As of C-Kermit 9.0 -NOUUCP is included by default because
-# Mac OS X doesn't support UUCP. To undo this, use KFLAGS=-UNOUUCP.
-#OK: 2011/06/14 (for 10.4.11, 10.5.8, 10.6.7)
-macosx macosx10 macosx10.3.9 macosx10.4 macosx10.5 macosx10.6:
- @MACOSNAME=`/usr/bin/sw_vers -productName`; \
- MACOSV=`/usr/bin/sw_vers -productVersion`; \
- echo Making C-Kermit $(CKVER) for $$MACOSNAME $$MACOSV... ; \
- MACCPU=$$HOSTTYPE; \
- if test `uname -r | cut -d . -f 1` -gt 8; \
- then if test -f /usr/include/utmpx.h ; \
- then HAVE_UTMPX='-DHAVEUTMPX -D_UTMPX_COMPAT' ; \
- else HAVE_UTMPX='' ; fi ; fi; \
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DMACOSX10 -DMACOSX103 -DCK_NCURSES -DTCPSOCKET -DCKHTTP \
- -DUSE_STRERROR -DUSE_NAMESER_COMPAT -DNOCHECKOVERFLOW -DFNFLOAT \
- -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $$HAVE_UTMPX \
- -funsigned-char -DNODCLINITGROUPS \
- -DNOUUCP -O -DHERALD=\"\\\" $${MACOSNAME} $${MACOSV}\\\"\" \
- -DCKCPU=\"\\\"$${MACCPU}\\\"\" \
- $(KFLAGS)" "LIBS= -lncurses -lresolv $(LIBS)"
-
-# Mac OS X 10.3.9 or later with Kerberos 5 and OpenSSL...
-# NOTE: Apple has removed all support for DES in OpenSSL and Kerberos
-# in Mac OS X 10.6 and later. The DES flags are included or left out
-# automatically based on the Mac OS X version number.
-# See note about UUCP in previous target.
-#OK: 2009/11/16 (for 10.3.9, 10.4.11, 10.5.8, 10.6.1)
-#OK: 2011/06/14 (for 10.4.11, 10.5.8, 10.6.7)
-macosx+krb5+ssl macosx10.5+krb5+ssl macosx10.6+krb5+ssl \
-macosx+krb5+openssl macosx10.5+krb5+openssl macosx10.6+krb5+openssl:
- @MACOSNAME=`/usr/bin/sw_vers -productName`; \
- MACOSV=`/usr/bin/sw_vers -productVersion`; \
- echo Making C-Kermit $(CKVER) for $$MACOSNAME $$MACOSV... ; \
- MACCPU=$$HOSTTYPE; \
- if test `uname -r | cut -d . -f 1` -gt 8; \
- then if test -f /usr/include/utmpx.h ; \
- then HAVE_UTMPX='-DHAVEUTMPX -D_UTMPX_COMPAT' ; \
- else HAVE_UTMPX='' ; fi ; fi; \
- if test `uname -r | cut -d . -f 1` -eq 7; \
- then IS_MACOSX103='-DMACOSX103' ; \
- else IS_MACOSX103='' ; fi; \
- case $$MACOSV in \
- 10.[012345].*) HAVE_DES='-DCK_DES -DLIBDES' ;; \
- *.*) HAVE_DES='' ;; \
- esac ; \
- if test -x /usr/bin/krb5-config ; \
- then HAVE_KRB5CONFIG=`/usr/bin/krb5-config --libs krb5 gssapi` ; \
- else HAVE_KRB5CONFIG='-lgssapi_krb5 -lkrb5 -lk5crypto \
- -lcom_err -lresolv' ; fi; \
- $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DMACOSX10 $$IS_MACOSX103 -DCK_NCURSES -DTCPSOCKET \
- -DUSE_STRERROR -DUSE_NAMESER_COMPAT -DNOCHECKOVERFLOW -DFNFLOAT \
- -DCKHTTP -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $$HAVE_UTMPX \
- -DNODCLINITGROUPS -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DZLIB \
- -DCK_ENCRYPTION -DCK_CAST -DCK_SSL -DOPENSSL_098 $$HAVE_DES \
- -DNOUUCP -DHERALD=\"\\\" $${MACOSNAME} $${MACOSV}\\\"\" \
- -DCKCPU=\"\\\"$${MACCPU}\\\"\" \
- -funsigned-char -O $(KFLAGS)" \
- "LIBS= $$HAVE_KRB5CONFIG -lssl -lcrypto -lpam -lncurses $(LIBS)"
-
-# End of Mac OS X Section
-
-#Acorn RISCiX, based on ...
-#Berkeley Unix 4.2 or 4.3 with lock directory /usr/spool/uucp/LCK/LCK..ttyxx,
-#but without acucntrl program
-riscix:
- @echo Making C-Kermit $(CKVER) for RISCiX, /usr/spool/uucp/LCK..ttyxx
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD42 -DBSD4 -DRISCIX -DNOCSETS \
- -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DDIRENT -DCK_CURSES \
- -DMAXSP=9024 -DMAXRD=9024 -DSBSIZ=9050 -DRBSIZ=9050 \
- -DDFTTY=\\\"/dev/serial\\\" -DNOCSETS -DNOCYRIL \
- -DNOANSI -w -O2 -fomit-frame-pointer" \
- "LIBS= -lcurses -ltermcap " \
- "CC= /usr/ucb/cc" \
- "CC2= /usr/ucb/cc"
-
-#Acorn RISCiX, as above, but using gcc
-riscix-gcc:
- @echo Making C-Kermit $(CKVER) for RISCiX, /usr/spool/uucp/LCK..ttyxx
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD42 -DBSD4 -DRISCIX -DNOCSETS \
- -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DDIRENT -DCK_CURSES \
- -DMAXSP=9024 -DMAXRD=9024 -DSBSIZ=9050 -DRBSIZ=9050 \
- -DDFTTY=\\\"/dev/serial\\\" -DNOCSETS -DNOCYRIL \
- -DNOANSI -w -O2 -fomit-frame-pointer" \
- "LIBS= -lcurses -ltermcap " \
- "CC= gcc -mbsd" \
- "CC2= gcc -mbsd"
-
-#Convergent CTIX 6.4.1
-ctix:
- @echo 'Making C-Kermit $(CKVER) for Convergent CTIX 6.4.1'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DSVR3 -DDIRENT -DTCPSOCKET -DHDBUUCP -DCK_CURSES \
- -DNONAWS -DNOLEARN -DNOLONGLONG $(KFLAGS) -XO" \
- "LNKFLAGS=-s" "LIBS=-lsocket -lcurses -lc_s"
- mcs -d wermit
-
-# The following makefile entry should work for any Harris Night Hawk system
-# (either 88k or 68k based) running release 6.1 or later of the CX/UX
-# operating system. This is a POSIX and ANSI-C compliant system which also
-# supports BSD networking. (Earlier CX/UX releases will probably work with
-# sys5r3, but this has not been verified).
-#
-cx_ux:
- @echo Making C-Kermit $(CKVER) for Harris Night Hawk CX/UX 6.1 or later
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS=-DPOSIX -DTCPSOCKET -DHDBUUCP -DPID_T=pid_t -DWAIT_T=int \
- -Dd_ino=d_fileno -DUID_T=uid_t -DGID_T=gid_t -DNOLONGLONG \
- $(KFLAGS) -Xa -O3 -g" "LNKFLAGS=-O3"
-
-#Intergraph Clipper, CLIX, job control, HDB UUCP.
-clix:
- @echo 'Making C-Kermit $(CKVER) for Intergraph CLIX...'
- $(MAKE) wermit "CC=acc" "CC2=acc" KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -w -DSVR3 -DCLIX -DDIRENT -DHDBUUCP -DNOSYSLOG -DUSE_MEMCPY \
- -DNOGETUSERSHELL -DNOREALPATH -DNOLEARN $(KFLAGS) -O" \
- "LNKFLAGS=" "LIBS= -lbsd"
-
-#As above + TCP/IP...
-clixnet:
- @echo 'Making networked C-Kermit $(CKVER) for Intergraph CLIX...'
- $(MAKE) wermit "CC=acc" "CC2=acc" KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -w -DSVR3 -DCLIX -DDIRENT -DHDBUUCP -DNOSYSLOG -DUSE_MEMCPY \
- -DTCPSOCKET -DNOGETUSERSHELL -DNOLEARN -DNOREALPATH $(KFLAGS) -O" \
- "LNKFLAGS=" "LIBS= -lbsd"
-
-#Mark Williams Coherent 286 or 386 on IBM PC family.
-#There is a 64K limit on program size, so this is a command-line only version.
-coherent:
- $(MAKE) "CFLAGS = -O -DCOHERENT -DNOANSI -DNOICP -DNOSETKEY -DNOLEARN \
- -DNOCSETS -DNOHELP -DNODIAL -DNOSCRIPT -DNODEBUG -DNOTLOG -DNOXMIT \
- -DNOMSEND -DNOFRILLS -DNOSYSIOCTLH -DSELECT_H $(KFLAGS) -VSUVAR" \
- -DNOFLOAT KTARGET=$${KTARGET:-$(@)} wermit
-
-#Mark Williams Coherent 386 on IBM PC family.
-#This will make a "minimum interactive" version - no scripts,
-#no character sets, no help, no dial, no debug/transaction logging, no
-#transmit, msend, mail, type, etc.
-coherentmi:
- $(MAKE) "CFLAGS = -O -DCOHERENT -DNOANSI -DNOSETKEY -DNOLEARN \
- -DNOSHOW -DNOCSETS -DNOHELP -DNODIAL -DNOSCRIPT -DNODEBUG -DNOTLOG \
- -DNOXMIT -DNOMSEND -DNOFRILLS -DNOSYSIOCTLH -DNOSERVER -DNOUUCP \
- -DNOSPL -DNOPUSH -DNOMDMHUP -DNOJC -DNOFDZERO -DNOESCSEQ -DNOFLOAT \
- -DNOCMDL $(KFLAGS) -VSUVAR -DSELECT_H" KTARGET=$${KTARGET:-$(@)} \
- wermit
-
-#Mark Williams Coherent 386 on IBM PC/AT family.
-coherentmax:
- $(MAKE) "CFLAGS = -O -DCOHERENT -DNOANSI -DSELECT_H -DNOLEARN \
- -DNOFLOAT -DNOSYSIOCTLH $(KFLAGS) -VSUVAR" "LNKFLAGS = -O -s" \
- KTARGET=$${KTARGET:-$(@)} wermit
-
-#Mark Williams Coherent 386 4.2. Includes curses but not TCP/IP.
-#Requires updates to the 4.2.10 compiler; the regular compiler fails to
-#to handle "complex expressions". NOFLOAT is so it can work on old PCs
-#without floating-point hardware.
-coherent42:
- $(MAKE) "CFLAGS = -T500000 -DNOFLOAT -DCOHERENT -DNOANSI -DSELECT \
- -DNOSYSLOG -DDIRENT -DCK_CURSES -DCK_NEWTERM -DCK_WREFRESH -VSUVAR \
- -DDCLGETCWD -DNOSYSIOCTLH -DNOINITGROUPS -DNOSYMLINK -DSELECT_H \
- -DDCLGETCWD -O $(KFLAGS)" \
- "LNKFLAGS = -O -s" KTARGET=$${KTARGET:-$(@)} \
- "LIBS = -lsocket -lcurses" wermit
-
-#DEC Ultrix 2.x
-# Add -O, -DDYNAMIC, -s, etc, if they work.
-ultrix2x:
- @echo Making C-Kermit $(CKVER) for Ultrix 2.x ...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DDU2 -DNOGETUSERSHELL $(KFLAGS)"
-
-du2:
- $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET-$(@)} ultrix2x
-
-#DEC Ultrix 3.0 and 3.1
-ultrix30:
- @echo Making C-Kermit $(CKVER) for Ultrix 3.0...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DDIRENT -DSIG_V -DNOGETUSERSHELL \
- -DULTRIX3 -DCK_CURSES $(KFLAGS) -O" "LIBS= -lcurses -ltermcap"
-
-du3:
- $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET-$(@)} ultrix30
-
-ultrix3x:
- $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET-$(@)} ultrix30
-
-#DEC Ultrix 4.0 or 4.1 on DECstation, VAXstation, VAX, etc.
-ultrix40:
- @echo Making C-Kermit $(CKVER) for Ultrix 4.0 or 4.1...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DDU4 -DNOGETUSERSHELL \
- $(KFLAGS) -Olimit 1450" "LNKFLAGS = -s"
-
-#DEC Ultrix 4.2-4.5 on DECstation, DECsystem, VAXstation, VAX, etc.
-#Like ultrix40, except now C compiler supports -O2 optimization.
-ultrix42:
- @echo Making C-Kermit $(CKVER) for Ultrix 4.2 or later...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DNOGETUSERSHELL $(KFLAGS) \
- -O2 -Olimit 1750" "LNKFLAGS = -s"
-
-du42:
- $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET-$(@)} ultrix42
-
-#DEC Ultrix 4.2-4.5 on DECstation, DECsystem, VAXstation, VAX, etc.
-#Like du42, but with curses support added and a couple features.
-ultrix42c:
- @echo Making C-Kermit $(CKVER) for Ultrix 4.2 or later...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DNOGETUSERSHELL \
- -DCK_CURSES -DNOIKSD $(KFLAGS)-G6 -O2 -Olimit 3000 " \
- "LNKFLAGS = -s" "LIBS= -lcurses -ltermcap"
-
-ultrix43:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \
- "KFLAGS=-DULTRIX43 $(KFLAGS)" KTARGET=$${KTARGET-$(@)} ultrix42c
-
-ultrix43notcp:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \
- "KFLAGS=-DULTRIX43 -DNONET $(KFLAGS)" \
- KTARGET=$${KTARGET-$(@)} ultrix42c
-
-# NOTE: need -DNODEBUG on MIPS to avoid relocation errors at link time.
-# Actually now (8.0) that we have discovered the -G option maybe debugging
-# can be put back.
-ultrix44:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \
- "KFLAGS=-DULTRIX44 -G7 -DNODEBUG -DNETPTY -DNO_DEVTTY $(KFLAGS)" \
- KTARGET=$${KTARGET-$(@)} ultrix42c
-
-ultrix45:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \
- "KFLAGS=-DULTRIX45 $(KFLAGS)-DNETPTY -DNO_DEVTTY $(KFLAGS)" \
- KTARGET=$${KTARGET-$(@)} ultrix42c
-
-du42c:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \
- KTARGET=$${KTARGET-$(@)} ultrix42c
-
-#DEC Ultrix 4.3A or later on DECsystem and DECstation 5000/50, /150 or /260
-#with MIPS R4x00 processor. The "-mips3" switch generates R4000-specific
-#code, which is faster and more compact, but *won't* run on earlier
-#DECsystems and DECstations.
-ultrix43-mips3:
- @echo Making C-Kermit $(CKVER) for Ultrix 4.3A or later, R4000 cpu...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DNOGETUSERSHELL \
- $(KFLAGS) -O2 -Olimit 1750 -mips3" "LNKFLAGS = -s -mips3"
-
-du43-mips3:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) ultrix43-mips3
-
-#DEC Ultrix 4.3A or later on MIPS R4x000 based systems.
-#Like ultrix43-mips3 but with curses support added
-ultrix43c-mips3:
- @echo Making C-Kermit $(CKVER) for Ultrix 4.3A or later, R4000 cpu...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DNOGETUSERSHELL -DCK_CURSES \
- $(KFLAGS) -O2 -Olimit 3000 -mips3" "LNKFLAGS = -s -mips3" \
- "LIBS= -lcurses -ltermcap"
-
-du43c-mips3:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \
- KTARGET=$${KTARGET-$(@)} ultrix43c-mips3
-
-#DEC Ultrix 4.4 on DECstation 5000/50 or /150 with R4000 MIPS processor,
-#or 5000/260 with R4400. The "-mips3" switch generates R4000-specific code,
-#which is faster and more compact but *won't* run on earlier DECstations.
-ultrix44-mips3:
- @echo Making C-Kermit $(CKVER) for Ultrix 4.4, R4000 cpu ...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DNOGETUSERSHELL \
- $(KFLAGS) -O2 -Olimit 1450 -mips3" "LNKFLAGS = -s -mips3"
-
-du44-mips3:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \
- KTARGET=$${KTARGET-$(@)} ultrix44c-mips3
-
-#DEC Ultrix 4.2 on DECstation, VAXstation, VAX, etc, System V R4 environment
-ultrix42s5r4:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4 on Ultrix...'
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS = -O2 -Olimit 1500 -DSVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \
- -DTCPSOCKET $(KFLAGS)" "LNKFLAGS = -s"
-
-#OSF/1
-osf osf1:
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD4 -DOSF -D_BSD -DTCPSOCKET -DCK_ANSIC -DSIG_V \
- -DCK_CURSES -DCK_RTSCTS -DFNFLOAT $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS = $(LIBS) -lbsd -lcurses -ltermcap -lm"
-
-#DEC OSF/1 V1.0-1.3 on DECstation, VAX, Alpha, or PC.
-dec-osf dec-osf1:
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD4 -DOSF -DOSF13 -D_BSD -DTCPSOCKET -DCK_ANSIC -DSIG_V \
- -DNOREALPATH -DNOIKSD -DCK_CURSES -DCK_RTSCTS -DFNFLOAT -DNODEBUG \
- -DNOUNICODE $(KFLAGS)" \
- "LNKFLAGS = -non_shared" "LIBS = -lbsd -lcurses -ltermcap -lm"
-
-# This one causes "relocation out-of-range" errors in the linker.
-old-dec-osf:
- @echo Making C-Kermit $(CKVER) for DEC OSF/1 V1.x...
- @echo If you are building for DEC OSF/1 2.0, please use dec-osf20.
- @echo Remove or adjust -O2 and/or -Olimit if they cause trouble.
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -O2 -Olimit 2400 $(KFLAGS)"
-
-#DEC OSF/1 2.0 on Alpha and probably nowhere else.
-#The only difference from OSF/1 is that optimization is omitted.
-#The optimized version gets strange runtime errors, like the PAUSE command
-#not working. Add "-unsigned" to make all chars unsigned.
-dec-osf20:
- @echo Making C-Kermit $(CKVER) for DEC OSF/1 V2.0...
- @echo Optimization omitted because it causes runtime errors.
- @echo See comments in makefile.
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DOSF20 $(KFLAGS)"
-
-dec-osf30:
- @echo Making C-Kermit $(CKVER) for DEC OSF/1 V3.0...
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DOSF30 -O2 -Olimit 2400 $(KFLAGS)"
-
-#Digital UNIX 3.2
-# Must compile ckuus[6x].c separately without optimization otherwise
-# the optimizer dumps core - keep CFLAGS here in sync with those from osf.
-du32:
- @echo Making C-Kermit $(CKVER) for Digital UNIX 3.2...
- $(MAKE) CC=$(CC) CC2=$(CC2) ckuus6.$(EXT) \
- "CFLAGS= -DBSD4 -DOSF -D_BSD -DTCPSOCKET -DCK_ANSIC -DSIG_V \
- -DCK_CURSES -DCK_RTSCTS -DFNFLOAT -DOSF32 -DHDBUUCP $(KFLAGS)"
- $(MAKE) CC=$(CC) CC2=$(CC2) ckuusx.$(EXT) \
- "CFLAGS= -DBSD4 -DOSF -D_BSD -DTCPSOCKET -DCK_ANSIC -DSIG_V \
- -DCK_CURSES -DCK_RTSCTS -DFNFLOAT -DOSF32 -DHDBUUCP $(KFLAGS)"
- $(MAKE) CC=$(CC) CC2=$(CC2) osf \
- "KFLAGS= -DOSF32 -DHDBUUCP -O2 -Olimit 3200 $(KFLAGS)"
-
-dec-osf32:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) du32 \
- KTARGET=$${KTARGET:-$(@)}
-
-#Digital UNIX 4.0 through 4.0D (use tru64 targets for 4.0E and above)...
-du40:
- @echo Making C-Kermit $(CKVER) for Digital UNIX 4.0...
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DOSF40 -DHDBUUCP -DFNFLOAT \
- -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" "LIBS=-lm"
-
-du40gcc:
- @echo Making C-Kermit $(CKVER) for Digital UNIX 4.0 with gcc ...
- $(MAKE) osf CC=gcc CC2=gcc KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DOSF40 -DHDBUUCP $(KFLAGS)"
-
-#Tru64 Unix 4.0E
-tru64-40e:
- @echo Making C-Kermit $(CKVER) for Tru64 UNIX 4.0E...
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DOSF40 -DOSF40E -DTRU64 -DHDBUUCP -DFNFLOAT -DNOCOTFMC \
- -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" "LIBS=-lm"
-
-tru64-40f:
- @echo Making C-Kermit $(CKVER) for Tru64 UNIX 4.0F...
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DOSF40 -DOSF40F -DTRU64 -DHDBUUCP -DFNFLOAT -DNOCOTFMC \
- -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" "LIBS=-lm"
-
-tru64-40g:
- @echo Making C-Kermit $(CKVER) for Tru64 UNIX 4.0G...
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DOSF40 -DOSF40G -DTRU64 -DHDBUUCP -DFNFLOAT -DNOCOTFMC \
- -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" "LIBS=-lm"
-
-tru64-50a:
- @echo Making C-Kermit $(CKVER) for Tru64 UNIX 5.0A...
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DTRU64 -DOSF50 -DHDBUUCP \
- -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)"
-
-tru64-51a:
- @echo Making C-Kermit $(CKVER) for Tru64 UNIX 5.1A...
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DTRU64 -DOSF50 -DOSF51A -DHDBUUCP \
- -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)"
-
-tru64-51b:
- @echo Making C-Kermit $(CKVER) for Tru64 UNIX 5.1B...
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DTRU64 -DOSF50 -DOSF51A -DOSF51B -DHDBUUCP \
- -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)"
-
-# Added 5.1b version with OpenSSL - CDW 6-13-2005...
-tru64-51b+openssl:
- @echo Making C-Kermit $(CKVER) for Tru64 UNIX 5.1b
- @echo including OpenSSL...
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DTRU64 -DOSF50 -DOSF51A -DOSF51B -DHDBUUCP \
- -unsigned -std1 -O3 -Olimit 2400 \
- -DCK_AUTHENTICATION -DCK_SSL $(SSLINC) $(KFLAGS)" \
- "LIBS= $(SSLLIB) -rpath $(sslroot)/ssl/lib -lssl -lcrypto"
-
-du50:
- $(MAKE) CC=$(CC) CC2=$(CC2) tru64-50a KTARGET=$${KTARGET:-$(@)}
-
-du40-ridiculous-checking:
- @echo Making C-Kermit $(CKVER) for Digital UNIX 4.0.
- @echo Checking everything - assumes DECC...
- $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= -DOSF40 -DHDBUUCP -w0 -warnprotos -check -portable \
- -unsigned -std1 -O3 -Olimit 1760 $(KFLAGS)"
-
-#Sequent DYNIX/ptx 1.2.1
-dynixptx12:
- @echo Making C-Kermit $(CKVER) for Sequent DYNIX/ptx 1.2.1...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DPTX -DNOGETUSERSHELL -DNOLEARN \
- -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t $(KFLAGS) -i -O" \
- "LNKFLAGS = -i"
-
-#Sequent DYNIX/ptx 1.3 or 1.4
-dynixptx13:
- @echo Making C-Kermit $(CKVER) for Sequent DYNIX/ptx 1.3 TCP/IP...
- $(MAKE) xermit "CFLAGS= -O KTARGET=$${KTARGET:-$(@)} \
- -DSVR3 -DDIRENT -DHDBUUCP -DPTX -DCK_POLL -DNOGETUSERSHELL \
- -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DTCPSOCKET $(KFLAGS) -i" \
- "LNKFLAGS = -i" "LIBS = -lsocket -linet -lnsl"
-
-#Sequent DYNIX/ptx 2.0, ANSI C compilation
-#Should work on any hardware platform when DYNIX/ptx runs, including
-#386, 486, Pentium.
-dynixptx20:
- @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 2.0...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPOSIX -DHDBUUCP -DTCPSOCKET \
- -DWAIT_T=int -DPTX -DNOGETUSERSHELL $(KFLAGS) -O" \
- "LIBS = -lsocket -linet -lnsl"
-
-#Sequent DYNIX/ptx 2.0, ANSI C compilation, with curses
-dynixptx20c:
- @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 2.0...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPOSIX -DHDBUUCP -DTCPSOCKET -DWAIT_T=int -DPTX -DCK_CURSES \
- -DCK_NEWTERM -DNOGETUSERSHELL $(KFLAGS) -O" \
- "LIBS = -lsocket -linet -lnsl -lcurses -ltermcap"
-
-#Sequent DYNIX/ptx 2.1.6, 80486, ANSI C compilation, with curses:
-# -Xa -- use ANSI compiler.
-# -Wc,-pw -- suppress portability warnings.
-# -Wc,-i386 -- 80386 cpu.
-# -Wc,-i486 -- 80486 cpu.
-# -Wc,-P5 -- Pentium (default).
-# -Wc,-O3 -- highest optimization.
-# -Wa,-N17061 -- increase symbol table from default of 15013 for ckcuni.c.
-# Early versions of DYNIX/ptx 2.1.x may need -DCK_POLL instead of -DSELECT.
-# Add "$&" after the colon in the "xermit" target for parallel makes.
-dynixptx216c:
- @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 2.1.6'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPOSIX -DHDBUUCP -DDYNAMIC -DTCPSOCKET \
- -DSELECT -DCK_REDIR -DCK_NAWS -DCK_WREFRESH -DSW_ACC_ID \
- -DTCP_NODELAY=1 -DTRMBUFL=2048 -DBIGBUFOK -DHADDRLIST \
- -DPTX -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL -DNOREALPATH \
- $(KFLAGS) -Xa -Wc,-pw -Wc,-i486 -Wc,-O3 -Wa,-N17061" \
- "LIBS = -lXbsd -lseq -lsocket -linet -lnsl -lmalloc -lm -lcurses" \
- "LNKFLAGS = -s"
-
-#Sequent DYNIX/ptx 2.1.6, gcc 2.7.2.2, with curses:
-dynixptx216cgcc:
- @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 2.1.6 gcc'
- $(MAKE) xermit "CC = gcc" "CC2 = gcc" KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPOSIX -DHDBUUCP -DDYNAMIC -DTCPSOCKET \
- -DSELECT -DCK_REDIR -DCK_NAWS -DCK_WREFRESH -DSW_ACC_ID \
- -DTCP_NODELAY=1 -DTRMBUFL=2048 -DBIGBUFOK -DHADDRLIST \
- -DPTX -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL -DNOREALPATH \
- $(KFLAGS) -O3 -pipe -funsigned-char" \
- "LIBS = -lXbsd -lseq -lsocket -linet -lnsl -lmalloc -lm -lcurses" \
- "LNKFLAGS = -s"
-
-#Sequent DYNIX/ptx 4.0, ANSI C compilation, with curses
-dynixptx41c:
- @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 4.0...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPOSIX -DHDBUUCP -DTCPSOCKET \
- -DWAIT_T=int -DPTX -DPTX4 -DCK_CURSES -DCK_NEWTERM \
- -DNOGETUSERSHELL $(KFLAGS) -O" \
- "LIBS = -lsocket -lnsl -lcurses -ltermcap"
-
-#Sequent DYNIX/ptx 4.4, ANSI C compilation, with curses
-dynixptx44:
- @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 4.4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPTX -DPTX4 -DPOSIX -DHDBUUCP -DTCPSOCKET -DWAIT_T=int \
- -DCK_CURSES -DCK_NEWTERM -DBIGBUFOK -DSELECT -DNOGETUSERSHELL \
- $(KFLAGS) -O" "LIBS = -lsocket -lnsl -lcurses -ltermcap"
-
-#Sequent DYNIX 3.0.x
-dynix3:
- @echo Making C-Kermit $(CKVER) for Sequent DYNIX 3.0.x...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD43 -DACUCNTRL -DTCPSOCKET -O \
- -DPWUID_T=int -DGID_T=int $(KFLAGS)"
-
-#Sequent DYNIX 3.0.x, no ACUCNTRL
-dynix3noacu:
- @echo Making C-Kermit $(CKVER) for Sequent DYNIX 3.0.x...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD43 -DLCKDIR -DTCPSOCKET -O \
- -DUID_T=int -DGID_T=int $(KFLAGS)"
-
-#Sequent DYNIX 3.1.x
-dynix31:
- @echo Making C-Kermit $(CKVER) for Sequent DYNIX 3.1.x...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DDCLPOPEN -DLCKDIR -DBSD4 -DTCPSOCKET $(KFLAGS)"
-
-#Sequent DYNIX 3.1.2, as above but with curses, to be compiled by gcc 2.3.3.
-dynix31c:
- @echo 'Making C-Kermit $(CKVER) for Sequent DYNIX 3.1.2, curses...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O2 -DDCLPOPEN -DACUCNTRL \
- -DBSD43 -DTCPSOCKET -DCK_CURSES -DUID_T=int \
- $(KFLAGS)" "LIBS= -lcurses -ltermcap"
-
-#Convex C1 with Berkeley Unix
-convex:
- @echo Making C-Kermit $(CKVER) for Convex C1 / BSD...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD4 -DNOLEARN $(KFLAGS) -Dmsleep=mnap"
-
-#Convex C210 with Convex/OS 8
-convex8:
- @echo Making C-Kermit $(CKVER) for Convex C210 with OS 8
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DNODEBUG -DDIRENT -DNOFILEH \
- $(KFLAGS) -DSIG_V -Dmsleep=mnap"
-
-#Convex C2 with Convex OS 9.1 (should also work with 8.1 or later)
-#with ANSI C compiler, uses BSD 4.3 uucp lockfile convention.
-convex9:
- @echo Making C-Kermit $(CKVER) for Convex C210 with OS 9.1
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPOSIX -DCONVEX9 -DNOIEXTEN -DDIRENT -DNOFILEH -DTCPSOCKET \
- -D__STDC__ -DLCKDIR -Dmsleep=mnap -O -ext -tm c1 $(KFLAGS)" \
- "LNKFLAGS = -ext"
-
-#Convex C2 with Convex OS 10.1 or later
-#with gcc 2.x C compiler
-convex10gcc:
- @echo Making C-Kermit $(CKVER) for Convex C2 with OS 10.1 using gcc
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPOSIX -DCONVEX9 -DNOIEXTEN -DDIRENT -DNOFILEH -DTCPSOCKET \
- -D__STDC__ -Dmsleep=mnap -O2 $(KFLAGS)" CC=gcc CC2=gcc
-
-#Cray X-MP or Y-MP UNICOS 6.x or 7.x.
-#NOTE: NPROC tells how many parallel makes to run. If your Cray has multiple
-#processors, you can set NPROC up to the number of CPUs, e.g. NPROC=16.
-cray:
- @echo 'Making C-Kermit $(CKVER) for Cray X/Y-MP UNICOS 6.x or 7.0...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} NPROC=1 \
- "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS) -O1"
-
-#Cray X-MP or Y-MP UNICOS 8.0 Alpha.
-cray8:
- @echo 'Making C-Kermit $(CKVER) for Cray X/Y-MP UNICOS 8.0 Alpha...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} NPROC=1 \
- "CFLAGS= -DSVR4 -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS) -O1"
-
-#Cray X-MP or Y-MP UNICOS 9.0.
-#This one was executed successfully for C-Kermit 8.0.209.
-#Earlier versions of Unicos will probably need the same flags.
-cray9:
- @echo 'Making C-Kermit $(CKVER) for Cray X/Y-MP UNICOS 9.0...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} NPROC=1 \
- "CFLAGS= -DSVR4 -DDIRENT -DHDBUUCP -DNOLFDEVNO \
- -DTCPSOCKET $(KFLAGS) -O1"
-
-#Cray-2 or Cray 3-CSOS
-#NOTE: NPROC tells how many parallel makes to run. If your Cray has multiple
-#processors, you can set NPROC up to the number of CPUs, e.g. NPROC=16.
-craycsos:
- @echo 'Making C-Kermit $(CKVER) for Cray-2/3 CSOS
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} NPROC=1 \
- "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DTCPSOCKET \
- $(KFLAGS) -DCK_ANSIC -DCK_CURSES" "LIBS=-lnet"
-
-#NeXTSTEP 1.0 through 3.2.
-#Includes fullscreen file transfer display (curses) and TCP/IP support.
-#Uses shared library to make executable program about 80K smaller.
-#Remove "LIBS = -lsys_s" if this causes trouble.
-next:
- @echo Making C-Kermit $(CKVER) for NeXTSTEP...
- @echo 'If you get errors in ckutio.c about w_S, w_T, etc,'
- @echo 'add KFGLAGS=-DNOREDIRECT to your make command.'
- $(MAKE) xermit CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DNEXT -DTCPSOCKET -DLCKDIR -DNOPUTENV -DFNFLOAT \
- -pipe -DCK_CURSES $(KFLAGS) -O -w" "LIBS = -lsys_s -lcurses -ltermcap"
-
-nextc:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) next \
- KTARGET=$${KTARGET:-$(@)}
-
-nextg:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) next \
- KFLAGS=-Wall KTARGET=$${KTARGET:-$(@)}
-
-nextgc:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) next \
- KFLAGS=-Wall KTARGET=$${KTARGET:-$(@)}
-
-#NeXTSTEP 3.3.
-#Includes fullscreen file transfer display and TCP/IP.
-# You might have to add 1 line to 1 NeXT header file <ip.h>
-# to declare n_long as u_long by adding #include <bsd/netinet/in_systm.h>
-
-next33:
- @echo Making C-Kermit $(CKVER) for NeXTSTEP 3.3...
- $(MAKE) xermit CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DNEXT33 -DTCPSOCKET -DLCKDIR -DNOPUTENV -DFNFLOAT \
- -pipe -DCK_CURSES $(KFLAGS) -O -w" "LIBS = -lsys_s -lcurses -ltermcap"
-
-#OPENSTEP 4.2 for Sparc, m680x0, HP PA-RISC, and Intel.
-#Includes fullscreen file transfer display and TCP/IP.
-#ckcpro.c compiled without optimization because it crashes the compiler.
-openstep42:
- @echo Making C-Kermit $(CKVER) for OPENSTEP 4.2...
- $(MAKE) ckcpro.$(EXT) \
- "CFLAGS= -DOPENSTEP42 -DNEXT33 -DTCPSOCKET -DLCKDIR -DNOPUTENV \
- -DFNFLOAT -pipe -DCK_CURSES $(KFLAGS) -w"
- $(MAKE) xermit CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DOPENSTEP42 -DNEXT33 -DTCPSOCKET -DLCKDIR -DNOPUTENV \
- -DFNFLOAT -pipe -DCK_CURSES $(KFLAGS) -O -w" \
- "LIBS = -lsys_s -lcurses -ltermcap"
-
-#NeXT with malloc debugger
-nextmd:
- @echo Making C-Kermit $(CKVER) for NeXT with malloc debugging...
- $(MAKE) mermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DNEXT -DTCPSOCKET -DLCKDIR -DNOPUTENV -DFNFLOAT \
- -DCK_CURSES $(KFLAGS) -O -w -Dmalloc=dmalloc -Dfree=dfree -DMDEBUG" \
- "LIBS = -lsys_s -lcurses -ltermcap"
-
-#Build for NeXTSTEP with "fat" binaries (MABs) that run on both Motorola
-#and Intel platforms.
-nextfat:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \
- next KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-Wall -arch m68k -arch i386" "LNKFLAGS = -arch m68k -arch i386"
-
-#NeXTSTEP on Intel Platforms.
-next486:
- @echo Making C-Kermit $(CKVER) for NeXTSTEP on Intel Platforms...
- @echo 'If you get errors in ckutio.c about w_S, w_T, etc,'
- @echo 'add KFGLAGS=D-DNOREDIRECT to your make command.'
- $(MAKE) xermit CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DNEXT -DTCPSOCKET -DLCKDIR -DNOPUTENV -DFNFLOAT \
- -DNODEBUG -O3 -fno-omit-frame-pointer -fschedule-insns2 -pipe \
- -DCK_CURSES $(KFLAGS) -w" "LIBS = -lsys_s -lcurses -ltermcap"
-
-#Single binary that runs on NeXT 68030 and 68040, Intel, HP, and Sparc,
-#as well as on OpenStep/Mach.
-nextquadfat:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) next \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-Wall -arch m68k -arch i386 -arch hppa -arch sparc" \
- "LNKFLAGS = -arch m68k -arch i386 -arch hppa -arch sparc"
-
-#BeBox
-beboxdr7:
- @echo 'Making C-Kermit $(CKVER) for the BeBox...'
- @echo 'Link step will fail with default Metroworks linker 64K limit.'
- @echo 'Code Warrior Gold required to link big programs.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CC=/boot/develop/tools/mwcc" "CC2=/boot/develop/tools/mwld" \
- "CFLAGS= -DBEBOX -DBE_DR_7 -DPOSIX -DNOUUCP -DNOLEARN $(KFLAGS) -O"
-
-#BeBox BeOS DR7 only
-bebox:
- @echo 'Making C-Kermit $(CKVER) for BeBox...'
- @echo 'Link step will fail with default Metroworks linker 64K limit.'
- @echo 'Code Warrior Pro 3.0 for BeBox required to link big programs.'
- $(MAKE) wermit "CC=mwcc" "CC2=mwld" KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBEBOX -DPOSIX -DNOLEARN -DNOUUCP $(KFLAGS) -O"
-
-#BeOS 4.5
-#We have to use the wermit target because 'fd_set' is unknown.
-beos45:
- $(MAKE) wermit "CC=$(CC)" "CC2=$(CC2)" KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBEOS -DBEOS45 -DPOSIX -DNOIKSD -DNOREALPATH -DSYSTIMEH \
- -DNOCOTFMC -DNOUUCP -DNOLEARN $(KFLAGS) -O" \
- "LIBS = $(LIBS)"
-
-#BeOS 4.5
-beos45net:
- $(MAKE) CC=$(CC) CC2=$(CC2) beos45 \
- "KFLAGS=-DTCPSOCKET -DNO_DNS_SRV $(KFLAGS)" "LIBS=-lnet -lnetapi"
-
-#Plan 9 from Bell Labs
-plan9:
- @echo 'C-Kermit for Plan 9 from Bell Labs - calling ckpker.mk...'
- make -f ckpker.mk
-
-#POSIX
-posix:
- @echo 'Making C-Kermit $(CKVER) for pure POSIX...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPOSIX -DNOUUCP -DNOLEARN $(KFLAGS) -O"
-
-# PowerMAX OS (SVR4) from Concurrent (tested on PowerMAX 5.1)
-powermax:
- @echo 'Making C-Kermit $(CKVER) for Concurrent PowerMAX OS...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DPOWERMAX \
- -DNETPTY -DHAVE_STREAMS -DHAVE_GRANTPT -DHAVE_PTSNAME -DPUSH_PTEM \
- -DPUSH_LDTERM -DPUSH_TTCOMPAT \
- -DSTERMIOX -DTCPSOCKET -DCK_CURSES $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lresolv -lcurses -lgen -lc -lucbc"
-
-#Berkeley Software Design Inc. BSDI
-# Substitute "LIBS= -lnewcurses -ltermcap" if desired.
-bsdi:
- @echo 'Making C-Kermit $(CKVER) for BSDI ...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD44 -DSETREUID -DSW_ACC_ID -DBIGBUFOK -DFIXCRTSCTS \
- -DTCPSOCKET -DCK_CURSES -DFNFLOAT $(KFLAGS) -O" \
- "LIBS= -lcurses -ltermcap -lm"
-
-#Berkeley Software Design Inc. BSDI - has higher serial speeds than 1.x.
-bsdi2:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) bsdi \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DBSDI2 $(KFLAGS)"
-
-bsdi3:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) bsdi \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DBSDI2 -DBSDI3 $(KFLAGS)"
-
-bsdi4:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) bsdi \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DBSDI2 -DBSDI3 -DBSDI4 -DTPUTSFNTYPE=void -DTPUTSISVOID \
- -DCKHTTP -m486 $(KFLAGS)"
-
-# (old name for the above)
-bsdiposix:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) bsdi
-
-
-#Build a BSDI 4.x binary that also runs under FreeBSD (Terry Kennedy).
-#But watch out for details like serial-port locking.
-bsdix:
- $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) bsdi \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DBSDI2 -DBSDI3 -DBSDI4 -DTPUTSFNTYPE=void -DTPUTSISVOID \
- -m486 $(KFLAGS)" "LNKFLAGS=-static -Wl,-m,i386bsdi -Wl,-e,_start"
-
-#Pyramid 9XXX (e.g. 9845) or MIServer T series, OSx 4.4b thru 5.1
-pyramid:
- @echo Making C-Kermit $(CKVER) for Pyramid Dual Port OSx
- ucb $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD43 -DTCPSOCKET -DPYRAMID -O $(KFLAGS)" "LNKFLAGS = -s"
-
-#Pyramid Dual Port OSx using HoneyDanBer UUCP, curses and TCP
-pyramid-hdb:
- @echo Making C-Kermit $(CKVER) for Pyramid Dual Port OSx
- ucb $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DBSD43 -DTCPSOCKET -DHBDUUCP -DCK_CURSES -O $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS = -lcurses -ltermcap"
-
-#Pyramid DC/OSx (UNIX System V R4).
-#Has <sys/termiox.h>, regular Berkeley sockets library, i.e. in.h and inet.h
-#are not misplaced in sys (rather than netinet and arpa, respectively).
-#Uses ANSI C.
-#NOTE: Remove -O and Olimit:2500 from CFLAGS if TELNET connections do not work.
-pyrdcosx:
- @echo 'Making C-Kermit $(CKVER) for Pyramid DC/OSx...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -Xa -O -DSVR4 -DDIRENT -DHDBUUCP -DSELECT -DNOGETUSERSHELL \
- -DCK_CURSES -DSTERMIOX -DTCPSOCKET -DPYRAMID -K Olimit:3100 \
- -DNO_DNS_SRV $(KFLAGS)" "LIBS= -lcurses -lsocket -lnsl" "LNKFLAGS = -s"
-
-#IBM's AIX 3.0 on IBM 370 mainframe, tested on AIX F44 thru F50.
-aix370:
- @echo Making C-Kermit $(CKVER) for IBM System/370 AIX 3.0...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIX370 -DTCPSOCKET -DLCKDIR -DDIRENT $(KFLAGS)" \
- "LIBS = -lbsd"
-
-#IBM's AIX/ESA 2.1 (OSF/1) on IBM mainframe
-aixesa:
- @echo Making C-Kermit $(CKVER) for IBM AIX/ESA...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXESA -DTCPSOCKET $(KFLAGS) -O"
-
-#IBM PS/2 with AIX 1.0 thru 1.3.
-# Reports indicate that -O switch must be omitted.
-# It is also possible that "make bsd" will work (reports welcome).
-# One report said "make LIBS=-lbsd bsd" did the trick.
-# NOTLOG is to get around a 'tlog' symbol defined in one of the headers.
-ps2aix:
- @echo 'Making C-Kermit $(CKVER) for IBM AIX 1.x PS/2...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DNOREALPATH -DPS2AIX10 -DSIG_V \
- -DNOUNICODE -DNOTLOG -DNOLEARN $(KFLAGS) -i" \
- "LNKFLAGS = -i"
-
-ps2aixnetc:
- @echo 'Making C-Kermit $(CKVER) for IBM AIX 1.x PS/2...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DNOREALPATH -DPS2AIX10 -DTCPSOCKET -DCK_CURSES \
- -DSIG_V -DNOUNICODE -DNOTLOG -DNOLEARN $(KFLAGS) -i" \
- "LIBS = -lcurses" "LNKFLAGS = -i"
-
-ps2aix3:
- $(MAKE) ps2aix KTARGET=$${KTARGET:-$(@)}
-
-#IBM RT PC with AIX 2.2.1, valid as of C-Kermit 8.0.
-#NOTLOG because of a conflict in <sys/termio.h>.
-#This one has unique and strange lockfiles.
-# -O removed on purpose (8.0).
-# In case of "compiler error: symbol table full", increase the -Nn number.
-# In case of "compiler error: Constant pool too big", boost the -Np number.
-# Add -DNOPUTENV if putenv() causes trouble.
-# Put -DNOIKSD back if IKSD-related problems occur.
-rtaix:
- @echo 'Making C-Kermit $(CKVER) for IBM RT PC, AIX 2.2.1...'
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS = -DATTSV -DRTAIX -DHDBUUCP -DDIRENT -DNOTLOG -DTCPSOCKET \
- -DNOGETUSERSHELL -DCLSOPN -DNOREALPATH -DNOUNICODE -DBSD_INCLUDES \
- -DUSE_LSTAT -DFNFLOAT -Nn2500 -Np1000 -Wq,-SJ2 -a -w $(KFLAGS)" \
- "LIBS = -lm $(LIBS)" "LNKFLAGS = -s"
-
-#### IBM RT PC - these targets were last verified in C-Kermit 8.0.211.
-
-#IBM RT PC with AIX 2.2.1 + curses
-rtaixc:
- $(MAKE) rtaix CC=$(CC) CC2=$(CC2) "KFLAGS=-DCK_CURSES" "LIBS=-lcurses"
-
-#IBM RT PC with AIX (ACIS) 2.2.1 (BSD 4.3)
-# Add -O, -DDYNAMIC, -s, etc, if they work.
-rtacis:
- @echo Making C-Kermit $(CKVER) for RT PC with ACIS 2.2.1 = BSD 4.3...
- $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DNOREALPATH -DNOIKSD -DNOPUTENV \
- $(KFLAGS) -U__STDC__" "LNKFLAGS = -s"
-
-#### IBM AIX. The first two targets should work for any version of AIX
-#### from 4.2 onwards. The ones after that are for older versions or
-#### specific configurations, and/or with gcc.
-
-# This one should work for any AIX 4.2 or later: "make aix".
-# Other tags are for compatibility with old makefile targets.
-#OK: 2011/06/11
-aix aix42 aix43 aix44 aix45 aix50 aix51 aix52 aix53 aix54 aix61:
- @echo Making C-Kermit $(CKVER) for IBM AIX...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DAIX41 -DAIX42 -DSVR4 -DSTERMIOX -DTCPSOCKET \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DFNFLOAT \
- -DSELECT -DSELECT_H -DNOGETUSERSHELL -qmaxmem=16000 -O \
- -DCKCPU=\\\"`uname -p`\\\" \
- -DHERALD=\"\\\" IBM AIX `uname -v`.`uname -r`\\\"\" \
- -D_LARGE_FILES $(KFLAGS)" "LNKFLAGS = -s" "LIBS=-lcurses -lm"
-
-# Same but using gcc instead of cc
-# This works but we get "gcc: unrecognized option '-qmaxmem-..'" each module.
-aixg:
- @echo "Using gcc..."
- $(MAKE) aix KTARGET=$${KTARGET:-$(@)} \
- CC=gcc CC2=gcc "KFLAGS=-pipe -funsigned-char"
-
-# AIX 4.2 or later with OpenSSL 0.9.7 or later: "make aix+ssl"
-# For earlier OpenSSL remove -DOPENSSL_097 or add "KFLAGS=-UOPENSSL_097".
-# Synonym target names added to cover old redundant targets that were removed.
-# If SSL is not installed in the /usr/local tree (see SSLINC and SSLLIB
-# definitions near the top), you can specify the locations in your make
-# command as in this example:
-#
-# SSLINC=-I/opt/ssl/include SSLLIB=-L/opt/ssl/lib make -e aix+ssl
-#
-# To build with gcc use "make aix CC=gcc CC2=gcc", or "make aixg"
-#
-#OK: 2011/06/15
-aix+ssl aix51+openssl aix52+openssl aix53+openssl:
- @echo "Making C-Kermit $(CKVER) for IBM AIX with OpenSSL..."
- @echo "SSLINC=$(SSLINC) SSLLIB=$(SSLLIB)"
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- CC=$(CC) CC2=$(CC2) \
- "CFLAGS=-DAIXRS -DAIX41 -DAIX42 -DSVR4 -DSTERMIOX -DTCPSOCKET \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DFNFLOAT \
- -D_LARGE_FILES -DSELECT -DSELECT_H -DNOGETUSERSHELL \
- -DCKCPU=\\\"`uname -p`\\\" \
- -DHERALD=\"\\\" IBM AIX `uname -v`.`uname -r`\\\"\" \
- -DCK_AUTHENTICATION -DCK_SSL -DOPENSSL_097 $(SSLINC) $(KFLAGS)" \
- "LNKFLAGS=-s" "LIBS=$(SSLLIB) -lssl -lcrypto -lcurses -lm -lcrypt"
-
-# AIX 5.3 or 6.1 or later with IBM OpenSSL, which is always in the directories
-# shown below so you don't have to set SSLINC and SSLLIB. If for some reason
-# the SSL include files and libraries are not in the places assumed, then use
-# "make aix+ssl" (just above) and set SSLINC and SSLLIB to indicate where the
-# SSL files are. To build with gcc use "make aix+ibmssl CC=gcc CC2=gcc".
-aix+ibmssl:
- @echo "Making C-Kermit $(CKVER) for IBM AIX 6.1 with OpenSSL..."
- @echo "If this fails use 'make aix+ss' and specify SSLINC and SSLLIB"
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- CC=$(CC) CC2=$(CC2) \
- "CFLAGS=-DAIXRS -DAIX41 -DAIX42 -DSVR4 -DSTERMIOX -DTCPSOCKET \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DFNFLOAT \
- -D_LARGE_FILES -DSELECT -DSELECT_H -DNOGETUSERSHELL \
- -DCKCPU=\\\"`uname -p`\\\" \
- -DHERALD=\"\\\" IBM AIX `uname -v`.`uname -r`\\\"\" \
- -DCK_AUTHENTICATION -DCK_SSL -DOPENSSL_098 \
- -I/usr/include/openssl $(KFLAGS)" \
- "LNKFLAGS=-s" \
- "LIBS=-L/usr/lib/openssl -lssl -lcrypto -lcurses -lm -lcrypt"
-
-# Old AIX versions...
-
-#IBM AIX 3.0, 3.1, or 3.2 for RISC System/6000.
-rs6000:
- @echo Making C-Kermit $(CKVER) for IBM AIX 3.0 or 3.1, RS/6000...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DTCPSOCKET -DSVR3 -DDIRENT -DCK_ANSIC \
- -DCK_POLL -DCLSOPN -DSELECT_H -DNOTTYLOCK -O $(KFLAGS)" \
- "LNKFLAGS = -s"
-
-#IBM AIX 3.0, 3.1, or 3.2 for RISC System/6000, with curses.
-rs6000c:
- @echo Making C-Kermit $(CKVER) for IBM AIX 3.0 or 3.1, RS/6000...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DTCPSOCKET -DSVR3 -DDIRENT -DCK_ANSIC \
- -DCK_POLL -DCLSOPN -DCK_CURSES -DSELECT_H -DNOTTYLOCK -DNOREALPATH \
- -O $(KFLAGS)" "LIBS= -lcurses -ltermcap" "LNKFLAGS = -s"
-
-aix30:
- $(MAKE) rs6000 CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)}
-
-aix31:
- $(MAKE) rs6000 CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)}
-
-#IBM AIX 3.2 for RISC System/6000.
-#In case of "subprogram too complex" warnings, add "-qmaxmem=16000" to CFLAGS.
-rs6aix32:
- @echo Making C-Kermit $(CKVER) for IBM AIX 3.2, RS/6000...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DTCPSOCKET -DSVR4 -DDIRENT -DCK_ANSIC -DNOREALPATH \
- -DSELECT_H -DCLSOPN -DNOTTYLOCK -O $(KFLAGS)" "LNKFLAGS = -s"
-
-#IBM AIX 3.2 for RISC System/6000.
-rs6aix32c:
- @echo Making C-Kermit $(CKVER) for IBM AIX 3.2, RS/6000, TCP+curses...
- @echo In case of Subprogram Too Complex warnings,
- @echo add -qmaxmem=16000 to CFLAGS.
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DTCPSOCKET -DSVR4 -DDIRENT -DCK_ANSIC -DNOREALPATH \
- -DCLSOPN -DCK_CURSES -DSELECT_H -DNOTTYLOCK -O $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS=-lcurses"
-
-aix32:
- $(MAKE) rs6aix32c KTARGET=$${KTARGET:-$(@)}
-
-#IBM AIX 4.1, 4.1.x on RISC System/6000 or Power Series.
-#Generates common binary for all platforms if using xlc (IBM C compiler).
-#When using gcc, add -mcpu=common to generate common binary.
-#Note that this one needs CK_NEWTERM.
-# Add -bbigtoc in case ld fails with TOC overflow.
-aix41:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.1.1 RS/6000 or PowerPC...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DAIX41 -DSVR4 -DSTERMIOX -DTCPSOCKET -DDIRENT \
- -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DNOGETUSERSHELL -qmaxmem=16000 -O $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS=-lcurses"
-
-#Ditto but with gcc.
-#Remove "CC=gcc CC2=gcc" if you have gcc installed as cc.
-aix41g:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.1.1 RS/6000 or PowerPC...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC=gcc" "CC2=gcc" \
- "CFLAGS= -DAIXRS -DAIX41 -DSVR4 -DSTERMIOX -DTCPSOCKET -DDIRENT \
- -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DNOGETUSERSHELL -O $(KFLAGS)" \
- "LNKFLAGS = -s -Xlinker -bbigtoc" "LIBS=-lcurses"
-
-# Add -bbigtoc in case ld fails with TOC overflow.
-aix41+krb5+krb4:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.1.1 RS/6000 or PowerPC...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DAIX41 -DSVR4 -DSTERMIOX -DTCPSOCKET -DDIRENT \
- -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_DES $(K5INC) $(K5INC)/krb5 \
- -DNOGETUSERSHELL -qmaxmem=16000 -O $(KFLAGS)" \
- "LNKFLAGS = -s" \
- "LIBS = $(K5LIB) -lcurses -lkrb4 -ldes425 -lkrb5 \
- -lcom_err -lk5crypto -lgssapi_krb5"
-
-#Old name for "aix41".
-rs6aix41c:
- $(MAKE) aix41 KTARGET=$${KTARGET:-$(@)}
-
-#IBM AIX 4.1, 4.1.x, or 4.2 on RISC System/6000 or Power Series,
-# with X.25 support
-#Generates common binary for all platforms if using xlc (IBM C compiler).
-#When using gcc, add -mcpu=common to generate common binary.
-# Add -bbigtoc in case ld fails with TOC overflow.
-aix41x25:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.1.1 RS/6000 or PowerPC...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DAIX41 -DSVR4 -DSTERMIOX -DTCPSOCKET -DDIRENT \
- -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DIBMX25 -DDEBUG -DNOGETUSERSHELL -qmaxmem=16000 -g $(KFLAGS)" \
- "LNKFLAGS = -g -bI:/lib/pse.exp" "LIBS=-lcurses -lodm -lcfg"
- -@echo "^[]0;kermit done\a\c"
-
-#As above but without -g in LNKFLAGS.
-# Add -bbigtoc in case ld fails with TOC overflow.
-aix41x25o:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.1.1 RS/6000 or PowerPC...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DAIX41 -DSVR4 -DSTERMIOX -DTCPSOCKET -DDIRENT \
- -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DIBMX25 -DNODEBUG -DNOGETUSERSHELL -qmaxmem=16000 $(KFLAGS)" \
- "LNKFLAGS = -bI:/lib/pse.exp" "LIBS=-lcurses -lodm -lcfg"
- -@echo "^[]0;kermit done\a\c"
-
-#AIX 4.2 -- Use this target if the regular "make aix" doesn't work.
-# Must have CK_NEWTERM or echoing is lost after curses.
-# Add -bbigtoc in case ld fails with TOC overflow. As of C-Kermit 8.0.212,
-# all AIX builds 4.2 and later include large file support.
-oldaix42:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.2 or higher...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DAIX41 -DAIX42 -DSVR4 -DSTERMIOX -DTCPSOCKET \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DFNFLOAT \
- -DSELECT -DSELECT_H -DNOGETUSERSHELL -qmaxmem=16000 -O \
- -DCKCPU=\\\"`uname -p`\\\" \
- -DHERALD=\\\"\ IBM\ AIX\ `uname -v`.`uname -r`\\\" \
- -D_LARGE_FILES $(KFLAGS)" "LNKFLAGS = -s" "LIBS=-lcurses -lm"
-
-#AIX 4.3 - Use this target if the regular "make aix" doesn't work.
-# Must NOT have CK_NEWTERM or else C-Kermit hangs after curses.
-# -bbigtoc needed on some systems but not others to avoid TOC overflow.
-# "man ld" says -bbigtoc makes program run slower.
-oldaix43:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 or higher...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DAIX41 -DAIX43 -DSVR4 -DSTERMIOX -DTCPSOCKET \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \
- -DFNFLOAT -DNOGETUSERSHELL -qmaxmem=16000 -bbigtoc -O $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS=-lcurses -lm"
-
-#AIX 4.3 with IBM X.25.
-aix43x25:
- @echo "Making C-Kermit $(CKVER) for IBM AIX 4.3 with X.25..."
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DAIXRS -DAIX41 -DAIX43 -DSVR4 -DSTERMIOX -DTCPSOCKET \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \
- -DFNFLOAT -DNOGETUSERSHELL -DIBMX25 \
- -qmaxmem=16000 -bbigtoc -O $(KFLAGS)" \
- "LNKFLAGS = -bI:/lib/pse.exp" "LIBS=-lcurses -lodm -lcfg -lm"
-
-#AIX 4.3 -- Must NOT have CK_NEWTERM or else C-Kermit hangs after curses.
-# -mminimal-toc needed on some systems but not others to avoid TOC overflow.
-# "man ld" says -bbigtoc makes program run slower.
-aix43g:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 gcc...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \
- -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL $(KFLAGS)" \
- "LIBS=-lcurses -lm"
-
-aix43gcc:
- $(MAKE) aix43g
-
-# None of the following aix43gcc attempts work on a gcc-only AIX 4.3.3 box.
-# It just plain can't find the math routines (fmod, pow, exp, sqrt, log10,...)
-# Which is odd because nm /usr/lib/libC.a finds them...
-
-#in case aix43gcc can't find its math library...
-aix43gccx:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 gcc...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \
- -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL $(KFLAGS)" \
- "LIBS= -L/usr/local/lib/gcc-lib/powerpc-ibm-aix4.3.1.0/2.95.2 \
- -lcurses -bloadmap -bnoquiet"
-
-#in case aix43gccx can't find its math library...
-aix43gccy:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 gcc...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \
- -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL $(KFLAGS)" \
- "LIBS= -lcurses -bloadmap -bnoquiet"
-
-#in case aix43gccx can't find its math library...
-aix43gccz:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 gcc...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \
- -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL $(KFLAGS)" \
- "LIBS= -L. -lcurses -bloadmap -bnoquiet"
-
-#AIX 4.3 with MIT Kerberos 5 and Kerberos 4 compatibility mode
-# Must NOT have CK_NEWTERM or else C-Kermit hangs after curses.
-# -mminimal-toc needed on some systems but not others to avoid TOC overflow.
-# "man ld" says -bbigtoc makes program run slower.
-aix43gcc+krb5+krb4:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 or higher w/Kerberos...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \
- -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_DES -funsigned-char $(K5INC) $(K5INC)/krb5 \
- $(KFLAGS)" \
- "LIBS=$(K5LIB) -lcurses -lm -lkrb4 -ldes425 -lkrb5 \
- -lcom_err -lk5crypto -lcrypt -lgssapi_krb5"
-
-#AIX 4.3 with MIT Kerberos 5, Kerberos 4 compatibility mode and OpenSSL
-# Must NOT have CK_NEWTERM or else C-Kermit hangs after curses.
-# -mminimal-toc needed on some systems but not others to avoid TOC overflow.
-# "man ld" says -bbigtoc makes program run slower.
-aix43gcc+krb5+krb4+openssl:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 or higher w/Kerberos...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \
- -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_DES -DCK_CAST -DLIBDES -DCK_SSL \
- -funsigned-char $(K5INC) $(K5INC)/krb5 $(SSLINC) $(KFLAGS)" \
- "LIBS=$(K5LIB) $(SSLLIB) -lssl -lcrypto \
- -lcurses -lm -lkrb4 -ldes425 -lkrb5 -lcom_err -lk5crypto -lcrypt \
- -lgssapi_krb5"
-
-aix43gcc+openssl:
- @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 or higher w/OpenSSL...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \
- -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \
- -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL \
- -DCK_AUTHENTICATION -DCK_SSL -funsigned-char $(SSLINC) $(KFLAGS)" \
- "LIBS=$(SSLLIB) -lssl -lcrypto -lcurses -lm -lcrypt"
-
-aix44gcc:
- $(MAKE) aix43g "KFLAGS=-DAIX44 $(KFLAGS)" \
- KTARGET=$${KTARGET:-$(@)}
-
-aix45gcc:
- $(MAKE) aix43g "KFLAGS=-DAIX45 $(KFLAGS)" \
- KTARGET=$${KTARGET:-$(@)}
-
-aix50gcc:
- $(MAKE) aix43g "KFLAGS=-DAIX50 $(KFLAGS)" \
- KTARGET=$${KTARGET:-$(@)}
-
-aix51gcc:
- $(MAKE) aix43g "KFLAGS=-DAIX51 $(KFLAGS)" \
- KTARGET=$${KTARGET:-$(@)}
-
-aix52gcc:
- $(MAKE) aix43g "KFLAGS=-DAIX52 $(KFLAGS)" \
- KTARGET=$${KTARGET:-$(@)}
-
-aix53gcc:
- $(MAKE) aix43g "KFLAGS=-DAIX53 $(KFLAGS)" \
- KTARGET=$${KTARGET:-$(@)}
-
-#Bull DPX/2 with BOS/X, like AIX/RS6000
-bulldpx2:
- @echo Making C-Kermit $(CKVER) for Bull DPX/2 with BOS/X...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DSVR3 -DDIRENT -DCK_ANSIC -DCKTYP_H=<sys/types.h> \
- -DCK_POLL -DNOGETUSERSHELL -DCLSOPN -DNOLEARN -O $(KFLAGS)" \
- "LNKFLAGS = -s"
-
-#Sun UNIX 3.5 with gcc 2.3.3.
-sunos3gcc:
- @echo Making C-Kermit $(CKVER) for Sun UNIX 3.5 and gcc...
- $(MAKE) xermit CC=gcc CC2=gcc KTARGET=$${KTARGET:-$(@)} \
- CFLAGS="-g -O -DBSD4 -DTCPSOCKET $(KFLAGS)"
-
-#SunOS version 4.0, BSD environment, has saved original euid feature.
-# Add "CC=/usr/ucb/cc CC2=/usr/ucb/cc" if necessary.
-# Note: Including Unicode crashes the assembler in ckcuni.c.
-sunos4:
- @echo Making C-Kermit $(CKVER) for SunOS 4.0, BSD environment...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DSUNOS4 -DFNFLOAT -DNOUNICODE $(KFLAGS)" \
- "LIBS=-lm"
-
-#As above, but with SunLink X.25 support
-sunos4x25:
- @echo SunLink X.25 support
- $(MAKE) "MAKE=$(MAKE)" sunos4 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -DFNFLOAT -DSUNX25" \
- "LIBS=-lm"
-
-#SUN OS version 4.1 - 4.1.3, BSD environment, has saved original euid feature.
-#Uses Honey DanBer UUCP. Requires presence of /usr/spool/locks directory.
-# /var/spool/ should be a symbolic link to /usr/spool/.
-# ... or 'make xermit "CC= /usr/ucb/cc " \'
-# Note: "xermit" means use the select() version of the CONNECT module.
-# Note for C-Kermit 9.0: Reportedly 'you need to modify the sys/ioctl.h
-# include file, i.e. comment out the "struct winsize" and "struct
-# ttysize". Otherwise there will be a conflict with sys/ttycom.h (included by
-# termios.h) which also declares these structs. But you need both includes.'
-sunos41:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 / BSD...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNOUNICODE $(KFLAGS)" \
- "LIBS= $(LIBS) -lresolv -lm"
-
-#As above, but compiled with gcc. Gives 24-32K size reduction
-#with gcc 2.1 or 2.2.2. CAUTION: make sure "fixincludes" has been run on
-#the include files, so gcc's are in sync with the regular Sun ones.
-#This includes the curses library for fullscreen file transfer display.
-#NDGPWNAM needed for GCC 2.5.6, not needed for 2.4.0, but it's uncertain
-#whether it will do any harm for 2.4.0 compilation -- if so, remove it.
-sunos41gcc:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 with gcc and curses...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \
- -funsigned-char $(KFLAGS)" "LIBS= -lcurses -ltermcap -lresolv -lm"
-
-# As above, but without -funsigned-char so I can see the warnings that
-# everybody else will get when they use ANSI compilers that don't have this
-# option (gsc = gcc signed char).
-sunos41gsc:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 with gcc and curses...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \
- $(KFLAGS)" "LIBS= -lcurses -ltermcap -lresolv -lm"
-
-#As above but with ckucon.c rather than ckucns.c (for testing only)
-sunos41gccfork:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 with gcc and curses...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \
- -DNOLEARN -funsigned-char $(KFLAGS)" \
- "LIBS= -lcurses -ltermcap -lresolv -lm"
-
-#as above but configured for Kerberos IV
-sunos41gcc+krb4:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1, gcc, curses, krb4...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \
- -DTCPSOCKET -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 \
- -DCK_ENCRYPTION -DCK_DES -DCK_CAST -DBIGBUFOK -funsigned-char \
- $(K4INC) $(KFLAGS)" \
- "LIBS= $(K4LIB) -lcurses -ltermcap -lresolv -lm -lkrb -ldes"
-
-#as above but configured for SSL/TLS
-sunos41gcc+openssl:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1, gcc, curses, ssl...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \
- -DCK_AUTHENTICATION -funsigned-char \
- -DCK_SSL -DTCPSOCKET -DBIGBUFOK $(SSLINC) $(KFLAGS)" \
- "LIBS= $(SSLLIB) -lcurses -ltermcap -lresolv -lm -lssl -lcrypto"
-
-#as above but configured for Kerberos IV and SSL/TLS
-sunos41gcc+krb4+openssl:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1, gcc, curses, krb4...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 -DCK_ENCRYPTION -DCK_DES \
- -DCK_CAST -DCK_SSL -DLIBDES -DTCPSOCKET -DBIGBUFOK -funsigned-char \
- $(K4INC) $(SSLINC) $(KFLAGS)" \
- "LIBS= $(K4LIB) $(SSLLIB) \
- -lcurses -ltermcap -lresolv -lm -lkrb -lssl -lcrypto"
-
-#as above but configured for Kerberos IV and ZLIB enabled SSL/TLS
-sunos41gcc+krb4+openssl+zlib:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1, gcc, curses, krb4...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 -DCK_ENCRYPTION -DCK_DES \
- -DCK_CAST -DCK_SSL -DLIBDES -DTCPSOCKET -DBIGBUFOK -funsigned-char \
- -DZLIB $(K4INC) $(SSLINC) \
- $(KFLAGS)" \
- "LIBS= $(K4LIB) $(SSLLIB) \
- -lcurses -ltermcap -lresolv -lm -lkrb -lssl -lcrypto -lz"
-
-#as above but configured for Kerberos IV and SRP and ZLIB enabled SSL/TLS
-sunos41gcc+krb4+srp+openssl+zlib:
- @echo "C-Kermit $(CKVER) SunOS 4.1: gcc,curses,krb4,srp,ssl,zlib..."
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 -DCK_ENCRYPTION -DCK_DES \
- -DCK_CAST -DCK_SSL -DLIBDES -DTCPSOCKET -DBIGBUFOK -funsigned-char \
- -DZLIB -DCK_SRP $(K4INC) $(SRPINC) $(SSLINC) $(KFLAGS)" \
- "LIBS= $(K4LIB) $(SRPLIB) $(SSLLIB) \
- -lcurses -ltermcap -lresolv -lm -lkrb -lkrypto \
- -lsrp -lssl -lcrypto -lz"
-
-#as above but configured for Kerberos IV and SRP and ZLIB enabled SSL/TLS
-sunos41gcc+srp+openssl+zlib:
- @echo "C-Kermit $(CKVER) SunOS 4.1: gcc,curses,srp,ssl,zlib..."
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \
- -DCK_AUTHENTICATION -DCK_ENCRYPTION -DCK_DES \
- -DCK_CAST -DCK_SSL -DLIBDES -DTCPSOCKET -DBIGBUFOK -funsigned-char \
- -DZLIB -DCK_SRP $(SRPINC) $(SSLINC) \
- $(KFLAGS)" \
- "LIBS= $(SRPLIB) $(SSLLIB) \
- -lcurses -ltermcap -lresolv -lm -lkrypto -lsrp -lssl -lcrypto -lz "
-
-#SUNOS 4.1 as sunos41 above, but also with curses support
-sunos41c:
- @echo Curses support
- $(MAKE) "MAKE=$(MAKE)" sunos41 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -DCK_CURSES -DFNFLOAT " \
- "LIBS= -lcurses -ltermcap"
-
-#As SunOS 4.1.x, gcc, configured as Internet Kermit Server.
-# . NOLOCAL removes capability to make connections
-# . TNCODE allows server-side Telnet negotiation.
-# . used to include -lpwent, why?
-# . used to include -L/usr/local/lib -lm, why?
-sunos41giks:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 with gcc for IKS...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \
- "CFLAGS= -O -DSUNOS41 -DNDGPWNAM -DFNFLOAT \
- -DNOLOCAL -DTCPSOCKET -DTNCODE -DNOPUSH $(KFLAGS)" \
- "LIBS= -lm -lresolv"
-
-#SUNOS 4.1 with SunLink X.25 support
-sunos41x25:
- @echo SunLink X.25 support
- $(MAKE) "MAKE=$(MAKE)" wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNOUNICODE -DFNFLOAT -DSUNX25 \
- -DNOLEARN $(KFLAGS)" "LIBS= $(LIBS) -lresolv -lm"
-
-#SUNOS 4.1 with SunLink X.25 support and curses
-sunos41x25c:
- @echo SunLink X.25 support + curses
- $(MAKE) "MAKE=$(MAKE)" wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNOUNICODE -DFNFLOAT -DSUNX25 \
- -DCK_CURSES -DNOLEARN $(KFLAGS)" \
- "LIBS= $(LIBS) -lcurses -ltermcap -lresolv -lm"
-
-#SUN with Solaris 2.0 = SunOS 5.0.
-#Mostly the same as System V R4. Don't use this with later Solaris versions.
-solaris20:
- @echo 'Making C-Kermit $(CKVER) for Sun with Solaris 2.0 and curses...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DSOLARIS -DDIRENT -DHDBUUCP -DSTERMIOX \
- -DTCPSOCKET -DCK_CURSES -DFNFLOAT -DCK_POLL $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermlib -lm" "LNKFLAGS = -s"
-
-#SUN with Solaris 2.0.
-#As above, but built with the gcc compiler from the Cygnus CD-ROM.
-solaris20g:
- @echo 'Making C-Kermit $(CKVER) for Sun Solaris 2.0, gcc, and curses..'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DSOLARIS -DDIRENT -DHDBUUCP -DSTERMIOX \
- -DTCPSOCKET -DCK_CURSES -DCK_POLL -DFNFLOAT $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermlib -lm" "LNKFLAGS = -s" \
- CC=/opt/cygnus-sol2-1.1/bin/gcc CC2=/opt/cygnus-sol2-1.1/bin/gcc
-
-#SunOS 5.1 = Solaris 2.1.
-#NOTE: A C compiler is no longer bundled with SunOS 5.1, so to compile C
-#programs, you might have to change your PATH to include the directory
-#/usr/ccs/bin AFTER the directory containing the compiler. SunPRO C is
-#installed by default in /opt/SUNWspro/bin. So a sample PATH might be:
-#
-# /usr/local/bin:/usr/bin:/opt/SUNWspro/bin:/usr/ccs/bin:\
-# /usr/ucb:/usr/sbin:/sbin:.
-#
-# or:
-#
-# /usr/openwin/bin:/export/home/SUNWspro/bin:/usr/ccs/bin:/usr/sbin:/usr/bin.
-#
-#NOTE 2: Compilation with the Apogee C compiler (apcc) might not work,
-#because it refuses to allow "-Usun". Reportedly, newer releases of apcc
-#(such as 1.2.17) work OK, use: "make -e sunos51 CC=apcc CC2=apcc".
-solaris21:
- @echo 'Making C-Kermit $(CKVER) for SunOS 5.x....'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -Usun -DSVR4 -DSOLARIS -DDIRENT -DHDBUUCP -DFNFLOAT \
- -DSELECT -DNODEBUG -DSTERMIOX $(KFLAGS)" "LIBS = -lm" "LNKFLAGS = -s"
-
-#Solaris 2.0 - 2.4, SunPro compiler, includes curses and TCP/IP.
-#When using SUNWspro CC 2.0.1 under Solaris 2.3, be sure all cc patches
-#are applied, otherwise corrupt or truncated object files can result.
-#To build, set your PATH as follows:
-# /usr/local/bin:/usr/bin:/opt/SUNWspro/bin:/usr/ccs/bin:\
-# /usr/ucb:/usr/sbin:/sbin:.
-# or (depending on where the compiler has been installed):
-# /usr/openwin/bin:/export/home/SUNWspro/bin:/usr/ccs/bin:/usr/sbin:/usr/bin.
-#For additional optimization try using "-fast -xO4 -xdepend".
-solaris2x:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with SunPro cc...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -Usun -i -DSVR4 -DDIRENT -DSOLARIS -DHDBUUCP -DFNFLOAT \
- -DSELECT -DCK_CURSES -DCK_NEWTERM -DSTERMIOX -DTCPSOCKET $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS= -ltermlib -lsocket -lnsl -lm -lresolv"
-
-#as above but configured for Kerberos IV
-solaris2x+krb4:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x, SunPro cc, krb4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -Usun -i -DSVR4 -DDIRENT -DSOLARIS -DHDBUUCP -DFNFLOAT \
- -DSELECT -DCK_CURSES -DCK_NEWTERM -DSTERMIOX -DTCPSOCKET \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 \
- -DCK_ENCRYPTION -DCK_DES -DCK_CAST $(K4INC) $(KFLAGS)" \
- "LNKFLAGS = -s" \
- "LIBS= $(K4LIB) -ltermlib -lsocket -lnsl -lm -lresolv -lkrb -ldes"
-
-#C-Kermit for Solaris 2.0-2.4 compiled with gcc, includes curses and TCP/IP.
-#Change -O2 to -O if -O2 gives trouble.
-#Remove -Usun if it causes trouble.
-#Your PATH should start with something like:
-# /usr/local/gnu/bin:/usr/ccs/bin:
-#Produces a huge executable -- strip with /usr/ccs/bin/strip (not Gnu strip).
-#Also don't add "LNKFLAGS = -s" -- strip manually instead.
-#Also note: this can NOT be linked statically - Sun makes it impossible.
-#And for Solaris 2.4, you might have to replace:
-# /usr/local/lib/gcc-lib/i486-sun-solaris2/2.4.5/include/sys/stat.h
-#with /usr/include/sys/stat.h.
-solaris2xg:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with GNU cc...'
- @echo 'Please read the comments that accompany the solaris2xg target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS)" \
- "LIBS= -ltermlib -lsocket -lnsl -lm -lresolv $(LIBS)"
-
-#ditto but no curses.
-solaris2xgnc:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with GNU cc...'
- @echo 'Please read the comments that accompany the solaris2xg target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \
- -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lm -lresolv $(LIBS)"
-
-#and with Kerberos IV
-solaris2xg+krb4:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with GNU cc, krb4...'
- @echo 'Please read the comments that accompany the solaris2xg target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 -DCK_ENCRYPTION \
- -DCK_DES -DCK_CAST -DBIGBUFOK $(K4INC) $(KFLAGS)" \
- "LIBS= $(K4LIB) -ltermlib -lsocket -lnsl -lm -lresolv -lkrb -ldes \
- $(LIBS)"
-
-#and with OpenSSL,ZLIB,PAM,SHADOW
-solaris2xg+openssl+zlib+pam+shadow:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with gcc, OpenSSL...'
- @echo 'Please read the comments that accompany the solaris2xg target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \
- -DCK_AUTHENTICATION -DCK_SSL -DCK_PAM -DCK_SHADOW -DZLIB \
- -DBIGBUFOK $(SSLINC) $(KFLAGS)" \
- "LIBS= $(SSLLIB) -ltermlib \
- -lsocket -lnsl -lm -lresolv -lssl -lcrypto -lpam -lz"
-
-#Ditto but with GCC 3.1 in which you have to specify 32-bit with -m32.
-#In Solaris 9 (and maybe 8) you'll also need specifiy the Library path.
-#Reportedly this can be done here, but only with:
-# crle -l /usr/lib:/usr/local/ssl/lib
-#prior to building. Note: 64-bit not tested with SSL.
-#For no-crypto 64-bit builds see the solaris9g64 target.
-solaris2xg32+openssl+zlib+pam+shadow:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with gcc, OpenSSL...'
- @echo 'Please read the comments that accompany the solaris2xg target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC="gcc -m32" CC2="gcc -m32" \
- "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \
- -DCK_AUTHENTICATION -DCK_SSL -DCK_PAM -DCK_SHADOW -DZLIB \
- -DBIGBUFOK $(SSLINC) $(KFLAGS)" \
- "LIBS= $(SSLLIB) -ltermlib \
- -lsocket -lnsl -lm -lresolv -lssl -lcrypto -lpam -lz"
-
-#and with Krb5,Krb4,OpenSSL,SHADOW
-solaris2xg+krb5+krb4+openssl+shadow:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with gcc,k5,k4,ssl...'
- @echo 'Please read the comments that accompany the solaris2xg target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS = -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_SSL -DCK_DES -DCK_CAST -DBIGBUFOK \
- $(K5INC) $(K5INC)/krb5 $(SSLINC) $(KFLAGS)" \
- "LIBS= $(K5LIB) $(SSLLIB) -ltermlib -lsocket -lnsl -lm -lresolv \
- -lkrb4 -lssl -lcrypto -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto \
- -ldes $(LIBS)"
-
-#and with OpenSSL
-solaris2xg+openssl+pam+shadow:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with gcc, OpenSSL...'
- @echo 'Please read the comments that accompany the solaris2xg target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \
- -DCK_AUTHENTICATION -DCK_SSL -DCK_PAM -DCK_SHADOW \
- -DBIGBUFOK $(SSLINC) $(KFLAGS)" \
- "LIBS= $(SSLLIB) -ltermlib \
- -lsocket -lnsl -lm -lresolv -lssl -lcrypto -lpam"
-
-solaris2xg+openssl+zlib+srp+pam+shadow:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with gcc, OpenSSL...'
- @echo 'Please read the comments that accompany the solaris2xg target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET -DBIGBUFOK \
- -DCK_AUTHENTICATION -DCK_ENCRYPTION -DCK_DES -DLIBDES -DCK_CAST \
- -DCK_SSL -DCK_PAM -DCK_SHADOW -DZLIB -DCK_SRP $(SSLINC) $(KFLAGS)" \
- "LIBS= $(SSLLIB) -ltermlib -lsocket -lnsl -lm -lresolv -lsrp -lssl \
- -ldes -lkrypto -lcrypto -lpam -lz"
-
-solaris22g:
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=-DPOSIX_CRTSCTS $(KFLAGS)" solaris2xg \
- KTARGET=$${KTARGET:-$(@)}
-
-solaris23g:
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=-DPOSIX_CRTSCTS $(KFLAGS)" solaris2xg \
- KTARGET=$${KTARGET:-$(@)}
-
-#Solaris 2.4 built with gcc
-solaris24g:
- $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET:-$(@)} \
- solaris2xg "KFLAGS=-DSOLARIS24 -DPOSIX_CRTSCTS $(KFLAGS)"
-
-#Solaris 2.0-2.3, SunPro compiler, with SunLink X.25 support.
-#This will only run if user has /opt/SUNWconn/lib/libsockx25.so.1
-#exists and can be dynamically linked.
-#NOTE: Do not change target to xermit -- it doesn't support X.25.
-solaris2x25:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x+X.25 with SunPro cc...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -i -Usun -DSVR4 -DSOLARIS -DDIRENT \
- -DSUNX25 -DTCPSOCKET -DHDBUUCP -DFNFLOAT -DNOLEARN \
- -DSELECT -DCK_CURSES -DCK_NEWTERM -DSTERMIOX $(KFLAGS)" \
- "LNKFLAGS = -s" \
- "LIBS= -ltermlib -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib \
- -lsockx25 -lsocket -lnsl -lm -lresolv"
-
-#Solaris 2.0-2.4, gcc, SunLink X.25 added.
-#NOTE: Can't use xermit target with X.25.
-solaris2xgx25:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x + X.25 with GNU cc...'
- @echo 'Please read the comments that accompany the solaris2xg entry.'
- $(MAKE) wermit CC=gcc CC2=gcc KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DSUNX25 \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET -DFNFLOAT \
- -DNOLEARN $(KFLAGS)" \
- "LIBS= -ltermlib -lm -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib \
- -lsockx25 -lsocket -lnsl"
-
-#Solaris 2.4, SunPro compiler, with SunLink X.25 support.
-#This will only run if user has /opt/SUNWconn/lib/libsockx25.so.1
-#exists and can be dynamically linked.
-solaris24x25:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.4+X.25 with SunPro cc...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -i -Usun -DSVR4 -DSOLARIS -DSOLARIS24 -DDIRENT -DNOLEARN \
- -DSUNX25 -DTCPSOCKET -DHDBUUCP -DFNFLOAT -DPOSIX_CRTSCTS \
- -DSELECT -DCK_CURSES -DCK_NEWTERM -DSTERMIOX $(KFLAGS)" \
- "LNKFLAGS = -s" \
- "LIBS= -ltermlib -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib \
- -lsockx25 -lsocket -lnsl -lm -lresolv"
-
-#Solaris 2.5, SunPro compiler, with SunLink X.25 support.
-solaris25x25:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.5+X.25 with SunPro cc...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -i -Usun -DSVR4 -DSOLARIS25 -DDIRENT -DSUNX25 \
- -DTCPSOCKET -DHDBUUCP -DSELECT -DCK_CURSES \
- -DCK_NEWTERM -DSTERMIOX -DFNFLOAT -DPOSIX_CRTSCTS -DNOLEARN \
- -I/opt/SUNWconn/include $(KFLAGS)" \
- "LIBS= -ltermlib -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib \
- -lsockx25 -lsocket -lnsl -lm -lresolv"
-
-solaris23:
- $(MAKE) "MAKE=$(MAKE)" solaris2x KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS)"
-
-solaris24:
- $(MAKE) "MAKE=$(MAKE)" solaris2x KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS24 -DPOSIX_CRTSCTS $(KFLAGS)"
-
-# template for Solaris 2.5 and above.
-solaris25x:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with SunPro cc...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DFNFLOAT -O -Usun -i $(KFLAGS)" \
- "LNKFLAGS = -s" \
- "LIBS= -ltermlib -lsocket -lnsl -lm -lresolv $(LIBS)"
-
-#Solaris 2.5, SunPro compiler, curses, TCP/IP
-solaris25:
- $(MAKE) "MAKE=$(MAKE)" solaris25x KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS25 $(KFLAGS)"
-
-#Solaris 2.5, SunPro compiler, curses, TCP/IP, Kerberos IV
-solaris25+krb4:
- $(MAKE) "MAKE=$(MAKE)" solaris25x+krb4 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS25 $(KFLAGS)"
-
-#Solaris 2.5 built with gcc
-solaris25g:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-funsigned-char -DSOLARIS25 $(KFLAGS)"
-
-#Solaris 2.5 built with gcc and Kerberos IV
-solaris25g+krb4:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg+krb4 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-funsigned-char -DSOLARIS25 $(KFLAGS)"
-
-#Solaris 2.5 built with gcc and Kerberos V/IV, SSL, ...
-solaris25g+krb5+krb4+openssl+shadow:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg+krb5+krb4+openssl+shadow \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-funsigned-char -DSOLARIS25 $(KFLAGS)"
-
-#Solaris 2.5, gcc, SunLink X.25 added.
-solaris25gx25:
- $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET:-$(@)} solaris2xgx25 \
- "KFLAGS=-DSOLARIS25 $(KFLAGS)"
-
-#Solaris 2.6, gcc, SunLink X.25 added.
-solaris26gx25:
- $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET:-$(@)} solaris2xgx25 \
- "KFLAGS=-DSOLARIS26 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \
- "LIBS= -lpam"
-
-#Solaris 2.6, SunPro compiler, curses, TCP/IP
-solaris26:
- $(MAKE) "MAKE=$(MAKE)" solaris25x KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS26 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \
- "LIBS= -lpam"
-
-#Solaris 2.6 with gcc
-solaris26g:
- $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET:-$(@)} solaris2xg \
- "KFLAGS= -DSOLARIS26 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \
- "LIBS = -lpam"
-
-#Solaris 2.6 with gcc and SSL
-solaris26g+openssl:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg+openssl+pam+shadow \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS= -DSOLARIS26 $(KFLAGS)"
-
-#Solaris 2.6 with gcc, no curses (e.g. because libtermlib is missing).
-solaris26gnc:
- $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET:-$(@)} solaris2xgnc \
- "KFLAGS= -DSOLARIS26 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \
- "LIBS= -lpam"
-
-#Solaris 2.6, SunPro compiler, with SunLink X.25 support.
-solaris26x25:
- @echo 'Making C-Kermit $(CKVER) for Solaris 2.6+X.25 with SunPro cc...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -i -Usun -DSVR4 -DSOLARIS26 -DDIRENT -DSUNX25 \
- -DTCPSOCKET -DHDBUUCP -DSELECT -DCK_CURSES -DCK_PAM -DCK_SHADOW \
- -DCK_NEWTERM -DSTERMIOX -DFNFLOAT -DPOSIX_CRTSCTS -DNOLEARN \
- -I/opt/SUNWconn/include $(KFLAGS)" \
- "LIBS= -ltermlib -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib \
- -lsockx25 -lsocket -lnsl -lm -lresolv -lpam"
-
-#Solaris 7 (2.7) with Sun CC
-solaris7:
- $(MAKE) "MAKE=$(MAKE)" solaris25x KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS7 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \
- "LIBS= -lpam"
-
-#Solaris 7 with gcc (32-bit)
-solaris7g:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS7 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \
- "LIBS= -lpam"
-
-#Solaris 7 with gcc + Kerberos IV (32-bit)
-solaris7g+krb4:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg+krb4 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS7 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \
- "LIBS= -lpam"
-
-solaris7g+openssl+zlib+pam+shadow:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg+openssl+zlib+pam+shadow \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS7 -DCK_PAM -DCK_SHADOW $(KFLAGS)"
-
-#Solaris 7 with gcc + OpenSSL (32-bit)
-solaris7g+openssl+zlib+srp+pam+shadow:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg+openssl+zlib+srp+pam+shadow \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS7 -DCK_PAM -DCK_SHADOW $(KFLAGS)"
-
-#Solaris 8
-solaris8:
- $(MAKE) "MAKE=$(MAKE)" solaris25x KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS8 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \
- "LIBS= -lpam"
-
-#Solaris 8 with gcc (32-bit)
-solaris8g:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS8 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \
- "LIBS= -lpam"
-
-# In OpenSSL builds add -ldl if you get unresolved references for
-# dlclose, dlsym, dlopen, dlerror.
-
-#Solaris 8 with gcc + OpenSSL (32-bit)
-solaris8g+openssl+zlib+pam+shadow:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg+openssl+zlib+pam+shadow \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DSOLARIS8 $(KFLAGS)"
-
-#Solaris 8 with gcc + Kerberos IV (32-bit)
-solaris8g+krb4:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg+krb4 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS8 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \
- "LIBS= -lpam"
-
-solaris9nolfs:
- $(MAKE) "MAKE=$(MAKE)" solaris25x KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS9 -DCK_PAM -DCK_SHADOW -DUSE_STRERROR $(KFLAGS)" \
- "LIBS= -lpam"
-
-#Solaris 9 with malloc debugging
-solaris9md:
- $(MAKE) mermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DFNFLOAT -O -Usun -i -D_FILE_OFFSET_BITS=64 \
- -DSOLARIS9 -Dmalloc=dmalloc -Dfree=dfree -DMDEBUG \
- -DCK_PAM -DCK_SHADOW -DUSE_STRERROR $(KFLAGS)" \
- "LIBS= -lpam -ltermlib -lsocket -lnsl -lm -lresolv"
-
-#Solaris 9 with gcc + OpenSSL + Shadow (32-bit)
-#Add -DOPENSSL_097 for OpenSSL 0.9.7 or later.
-solaris9g+openssl+shadow+pam+zlib:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg+openssl+zlib+pam+shadow \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS9 -DHDBUUCP -DDIRENT -D_FILE_OFFSET_BITS=64 \
- -DNO_DCL_INET_ATON -DZLIB -DCK_PAM -DCK_SHADOW -DLIBDES $(KFLAGS)" \
- "LIBS= -lpam -ldes425 -lz $(LIBS)"
-
-#Solaris 9 with gcc + OpenSSL + Kerberos 5 + Krb4 + Shadow (32-bit)
-#Add -DOPENSSL_097 for OpenSSL 0.9.7 or later.
-solaris9g+krb5+krb4+openssl+shadow+pam+zlib:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg+krb5+krb4+openssl+shadow \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS9 -DHDBUUCP -DDIRENT -D_FILE_OFFSET_BITS=64 \
- -DNO_DCL_INET_ATON -DZLIB -DCK_PAM -DCK_SHADOW -DLIBDES $(KFLAGS)" \
- "LIBS= -lpam -ldes -lz $(LIBS)"
-
-#Solaris 9 with gcc + Kerberos 4 and 5:
-solaris9g+krb5+krb4:
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS = -O -Usun -DSVR4 -DSOLARIS9 -DSTERMIOX -DSELECT -DFNFLOAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -D_FILE_OFFSET_BITS=64 \
- -DCK_ENCRYPTION -DCK_DES -DCK_CAST -DBIGBUFOK \
- $(K5INC) $(K5INC)/krb5 $(KFLAGS)" \
- "LIBS= $(K5LIB) -ltermlib -lsocket -lnsl -lm -lresolv \
- -lkrb4 -lcrypto -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto \
- -ldes $(LIBS)"
-
-#Solaris 9, 10, or 11 with gcc...
-#Uses streams PTYs rather than BSD ptys as in C-Kermit 8.0 and earlier.
-#This target is chained to be the secure solaris9g+xxx targets below.
-solaris9g solaris10g solaris11g:
- @echo 'Making C-Kermit $(CKVER) for Solaris 9 or later with gcc'
- @case `uname -r` in \
- 5.9) SOLARISVERSION="-DSOLARIS9" ;; \
- 5.10) SOLARISVERSION="-DSOLARIS10" ;; \
- 5.11) SOLARISVERSION="-DSOLARIS11" ;; \
- *) SOLARISVERSION="-DSOLARIS" ;; \
- esac ; \
- $(MAKE) "MAKE=$(MAKE)" CC="gcc -m32" CC2="gcc -m32" xermit \
- KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -g -O -Usun -DSVR4 $$SOLARISVERSION -DUSE_STRERROR \
- -DSTERMIOX -DSELECT -DFNFLOAT -DCK_PAM -DCK_SHADOW -funsigned-char \
- -DHAVE_STREAMS -DHAVE_GRANTPT -DHAVE_PTSNAME -DPUSH_PTEM \
- -DPUSH_LDTERM -DPUSH_TTCOMPAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \
- -D_FILE_OFFSET_BITS=64 $(KFLAGS)" \
- "LIBS= -ltermlib -lsocket -lnsl -lm -lresolv -lpam $(LIBS)"
-
-#Solaris 9, 10, or 11 with gcc + Kerberos 5 + OpenSSL.
-#OK C-Kermit 9.0.301.
-solaris9g+krb5+ssl solaris10g+krb5+ssl solaris11g+krb5+ssl:
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac ; \
- HAVE_DES=''; \
- DES_LIB=''; \
- if ls $(SSLLIB)/libdes* > /dev/null 2> /dev/null; then \
- DES_LIB='-ldes425'; \
- HAVE_DES='-DCK_DES -DLIBDES'; \
- echo "HAVE DES"; \
- else echo "NO DES"; \
- fi; \
- GSSAPILIB=''; \
- K5DIR=`echo $(K5LIB) | sed 's|-L||'`; \
- echo K5DIR=$$K5DIR; \
- if ls $$K5DIR/libgssapi_krb5* > /dev/null 2> /dev/null; then \
- GSSAPILIB='-lgssapi_krb5'; \
- else GSSAPILIB='-lgssapi'; \
- fi; \
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS = -O -Usun -DSVR4 -DSOLARIS9 -DSTERMIOX -DSELECT -DFNFLOAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET -DBIGBUFOK \
- -DCK_AUTHENTICATION -DCK_SSL -DZLIB -DCK_KERBEROS -DKRB5 \
- -DCK_ENCRYPTION -DCK_CAST $$OPENSSLOPTION \
- $$HAVE_DES $(SSLINC) $(K5INC) $(K5INC)/krb5 $(KFLAGS)" \
- "LIBS= $(SSLLIB) $(K5LIB) -lz -lssl -ltermlib -lsocket -lnsl -lm \
- -lresolv -lcrypto \
- $$GSSAPILIB -lkrb5 -lcom_err -lk5crypto $$DES_LIB $(LIBS)"
-
-#Solaris 9, 10, or 11 with gcc, 64 bit build.
-#Peeking inside FILE struct not allowed in 64-bit world.
-#DON'T USE THIS ONE ON PC ARCHITECTURE - It compiles and links but won't run.
-#OK: 2009/09/25 (but not tested on Solaris 11)
-solaris9g64 solaris10g64 solaris11g64:
- @echo 'Making C-Kermit $(CKVER) for Solaris 9++ with gcc 64-bit'
- @case `uname -r` in \
- 5.9) SOLARISVERSION="-DSOLARIS9" ;; \
- 5.10) SOLARISVERSION="-DSOLARIS10" ;; \
- 5.11) SOLARISVERSION="-DSOLARIS11" ;; \
- *) SOLARISVERSION="-DSOLARIS" ;; \
- esac ; \
- $(MAKE) "MAKE=$(MAKE)" CC="gcc -m64" CC2="gcc -m64" xermit \
- KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -g -O -Usun -funsigned-char \
- -DSVR4 $$SOLARISVERSION -DNOARROWKEYS \
- -DSTERMIOX -DSELECT -DFNFLOAT -DUSE_STRERROR -DCK_PAM -DCK_SHADOW \
- -DHAVE_STREAMS -DHAVE_GRANTPT -DHAVE_PTSNAME -DPUSH_PTEM \
- -DPUSH_LDTERM -DPUSH_TTCOMPAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS)" \
- "LIBS= -ltermlib -lsocket -lnsl -lm -lresolv -lpam $(LIBS)"
-
-#Solaris 9, 10, or 11 with SunPro CC
-#Uses streams PTYs rather than BSD ptys as in C-Kermit 8.0 and earlier.
-#This target is chained to by the secure targets below.
-#OK C-Kermit 9.0
-solaris9 solaris10 solaris11:
- @echo 'Making C-Kermit $(CKVER) for Solaris 9 or later with Sun CC'
- @case `uname -r` in \
- 5.9) SOLARISVERSION="-DSOLARIS9" ;; \
- 5.10) SOLARISVERSION="-DSOLARIS10" ;; \
- 5.11) SOLARISVERSION="-DSOLARIS11" ;; \
- *) SOLARISVERSION="-DSOLARIS" ;; \
- esac ; \
- $(MAKE) "MAKE=$(MAKE)" xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -Usun -DSVR4 $$SOLARISVERSION -DUSE_STRERROR \
- -DSTERMIOX -DSELECT -DFNFLOAT -DCK_PAM -DCK_SHADOW \
- -DHAVE_STREAMS -DHAVE_GRANTPT -DHAVE_PTSNAME -DPUSH_PTEM \
- -DPUSH_LDTERM -DPUSH_TTCOMPAT \
- -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \
- -D_FILE_OFFSET_BITS=64 $(KFLAGS)" \
- "LIBS= $(LIBS) -ltermlib -lsocket -lnsl -lm -lresolv -lpam"
-
-# Solaris 9, 10, or 11 with OpenSSL built with Sun CC.
-# Here's an example of how to invoke this target in case your OpenSSL
-# headers and libraries are not in /usr/local:
-#
-# make solaris9+openssl "SSLINC=" "SSLLIB=" \
-# "KFLAGS= -I/opt/openssl-0.9.8k/include -L/opt/openssl-0.9.8k/lib"
-#
-# Don't use 'make -e' because that inhibits passing of KFLAGS to
-# the base (solaris9) target.
-#
-#OK C-Kermit 9.0
-solaris9+ssl solaris10+ssl solaris11+ssl \
-solaris9+openssl solaris10+openssl solaris11+openssl:
- @echo 'Making C-Kermit $(CKVER) for Solaris 9/10/11 with OpenSSL: cc'
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac ; \
- HAVE_DES=''; \
- DES_LIB=''; \
- if ls $(SSLLIB)/libdes* > /dev/null 2> /dev/null; then \
- DES_LIB='-ldes425'; \
- HAVE_DES='-DCK_DES -DLIBDES'; \
- echo "HAVE DES"; \
- else echo "NO DES"; \
- fi; \
- $(MAKE) "MAKE=$(MAKE)" solaris9 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DCK_AUTHENTICATION -DCK_SSL -DZLIB $$HAVE_DES \
- -DNO_DCL_INET_ATON $$OPENSSLOPTION $(SSLINC) $(KFLAGS)" \
- "LIBS= $(SSLLIB) -lz -lssl $$DES_LIB -lcrypto $(LIBS)"
-
-# Solaris 9 or later with OpenSSL, built with gcc.
-# Remove -DNO_DCL_INET_ATON if inet_aton comes up missing. This target nicely
-# chains to the solaris{9,10,11}g target but for some reason it doesn't work if
-# you add the -DFORWARD_X option, thus the solaris9g+openssl+forward_x target.
-#
-#OK: 2011/06/14
-solaris9g+ssl solaris10g+ssl solaris11g+ssl \
-solaris9g+openssl solaris10g+openssl solaris11g+openssl:
- @echo 'Making C-Kermit $(CKVER) for Solaris 9/10/11 with OpenSSL: gcc'
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac ; \
- HAVE_DES=''; \
- DES_LIB=''; \
- if ls $(SSLLIB)/libdes* > /dev/null 2> /dev/null; then \
- DES_LIB='-ldes425'; \
- HAVE_DES='-DCK_DES -DLIBDES'; \
- echo "HAVE DES"; \
- else echo "NO DES"; \
- fi; \
- $(MAKE) "MAKE=$(MAKE)" solaris9g KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DCK_AUTHENTICATION -DCK_SSL -DZLIB $$HAVE_DES \
- -DNO_DCL_INET_ATON $$OPENSSLOPTION $(SSLINC) $(KFLAGS)" \
- "LIBS= $(SSLLIB) -lz -lssl $$DES_LIB -lcrypto $(LIBS)"
-
-# Solaris 9 or later with gcc + OpenSSL + Shadow (32-bit).
-# Remove -DNO_DCL_INET_ATON if inet_aton comes up missing.
-# Includes long file support - not sure if this was available before Solaris 9.
-# Detects Solaris version automatically.
-#
-solaris9g+openssl+forward_x:
- @echo 'Making C-Kermit $(CKVER) for Solaris 9 or later with OpenSSL...'
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac ; case `uname -r` in \
- 5.9) SOLARISVERSION="-DSOLARIS9" ;; \
- 5.10) SOLARISVERSION="-DSOLARIS10" ;; \
- 5.11) SOLARISVERSION="-DSOLARIS11" ;; \
- *) SOLARISVERSION="-DSOLARIS" ;; \
- esac ; \
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "CFLAGS = -g -O -Usun -DSVR4 $$SOLARISVERSION \
- -DHAVE_STREAMS -DHAVE_GRANTPT -DHAVE_PTSNAME -DPUSH_PTEM \
- -DPUSH_LDTERM -DPUSH_TTCOMPAT \
- -DSTERMIOX -DSELECT -DFNFLOAT -DBIGBUFOK -D_FILE_OFFSET_BITS=64 \
- -DCK_AUTHENTICATION -DCK_SSL -DCK_PAM -DCK_SHADOW -DZLIB -DLIBDES \
- -DFORWARD_X $$OPENSSLOPTION $(SSLINC) $(KFLAGS)" \
- "LIBS= $(SSLLIB) -lpam -ldes425 -lz -ltermlib \
- -lsocket -lnsl -lm -lresolv -lssl -lcrypto -lpam -lz $(LIBS)"
-
-# These two should be folded in with the ones just above.
-
-#Solaris 9 with gcc 3.1 + OpenSSL (32-bit)
-solaris9g+openssl+zlib+pam+shadow:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg32+openssl+zlib+pam+shadow \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS9 -DUSE_STRERROR $(KFLAGS)"
-
-#Solaris 10 with gcc 3.1 + OpenSSL (32-bit)
-solaris10g+openssl+zlib+pam+shadow:
- $(MAKE) "MAKE=$(MAKE)" solaris2xg32+openssl+zlib+pam+shadow \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSOLARIS10 -DUSE_STRERROR $(KFLAGS)"
-
-#The following (old, old) sunosxxx entries are for debugging and testing only.
-
-sunos41x:
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DSUNOS41 -DDIRENT -DNOTLOG -DNOMSEND \
- -DNOUUCP -DNOSIGWINCH -DNOREDIRECT -DNOPUSH -DNOCCTRAP \
- -DNOICP -DNOLOCAL $(KFLAGS)"
-
-#SunOS 4.1.x, debugging with Pure Software, Inc., Purify 2 (commercial runtime
-#error-detection software for catching wild array references, etc).
-#Before running the resulting wermit, you'll also need to define and export
-#the following environment variables (as in this example):
-#PURIFYHOME=/usr/local/purify ; export PURIFYHOME
-#PURIFYCACHEDIR=/tmp ; export PURIFYCACHEDIR
-sunos41cp:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 / BSD / Curses / Purify...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CC2= purify -cache_dir=/usr/tmp cc" \
- "CFLAGS= -g -DSUNOS41 -DHDBUUCP -DDIRENT -DTCPSOCKET \
- -DSAVEDUID -DCK_CURSES $(KFLAGS)" \
- "LIBS= -lcurses -ltermcap"
-
-#SunOS 4.1 with malloc debugger
-sunos41md:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 malloc debug...
- $(MAKE) mermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DDIRENT -DTCPSOCKET \
- -DSAVEDUID $(KFLAGS) -Dmalloc=dmalloc -Dfree=dfree -DMDEBUG"
-
-sunos41gmd:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 with gcc and curses...
- $(MAKE) mermit KTARGET=$${KTARGET:-$(@)} "CC= gcc " "CC2= gcc" \
- "CFLAGS= -g -DSUNOS41 -DHDBUUCP -DDIRENT -DTCPSOCKET \
- -DNDGPWNAM -DSAVEDUID -DCK_CURSES -DRLOGCODE \
- $(KFLAGS) -Dmalloc=dmalloc -Dfree=dfree -DMDEBUG" \
- "LIBS= -lcurses -ltermcap"
-
-#SunOS version 4.1, gcc, profiling with gprof, no debugging.
-#To get profile, "make sunos41p" (on Sun), then "./wermit". After running
-#wermit, "gprof ./wermit | lpr" (or whatever) to get execution profile.
-sunos41p:
- @echo Making C-Kermit $(CKVER) for SunOS 4.x with profiling...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc " "CC2= gcc" \
- "CFLAGS= -DSUNOS41 -DNODEBUG -DSAVEDUID -DDIRENT -DTCPSOCKET \
- -DNDGPWNAM $(KFLAGS) -pg" "LNKFLAGS = -pg"
-
-#SunOS version 4.1 or later, BSD environment, minimum features.
-sunos41min:
- @echo Minimum interactive
- $(MAKE) "MAKE=$(MAKE)" sunos41 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DNOSPL -DNOXMIT -DNOMSEND -DNOFRILLS -DNORETRY \
- -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG -DNOSCRIPT -DNOCSETS \
- -DNOSHOW -DNOSETKEY -DNOUUCP -DNORECALL -DNOREDIRECT \
- -DNOPUSH -DNOMDMHUP -DNOJC -DNOFDZERO -DNOESCSEQ \
- -DNONET -DCK_SMALL -DNOCKSPEED -DNOCKTIMERS -DNOLOGIN \
- -DNOCKXYZ -DNOKERBEROS -DNOMKDIR -DNOPATTERNS -DNOPERMS -DNOPIPESEND \
- -DNORECURSIVE -DNORENAME -DNORESEND -DNOSETKEY \
- -DNOTRIGGER -DNOTUNING $(KFLAGS)" "LNKFLAGS = -s"
-
-#SunOS version 4.1, BSD environment, min size, command-line only...
-sunos41m:
- @echo Minimum size
- $(MAKE) "MAKE=$(MAKE)" sunos41min KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DNOICP $(KFLAGS)"
-
-#SunOS version 4.1, BSD environment, min size, cmd-line only, remote only...
-#
-sunos41mr:
- @echo Minimum size
- $(MAKE) "MAKE=$(MAKE)" sunos41min KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DNOICP -DNOLOCAL $(KFLAGS)"
-
-#SunOS version 4.1, BSD environment, min size, interactive...
-sunos41mi:
- @echo Minimum size
- $(MAKE) "MAKE=$(MAKE)" sunos41min KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DNOCMDL $(KFLAGS)"
-
-#SunOS version 4.1, BSD environment, min size, interactive, remote only...
-sunos41mir:
- @echo Minimum size
- $(MAKE) "MAKE=$(MAKE)" sunos41min KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DNOCMDL -DNOLOCAL $(KFLAGS)"
-
-#SunOS 4.1, System V R3 environment (-i option omitted).
-sunos41s5:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 System V R3...
- @echo For testing purposes only - NOT for production use.
- @echo For a useable version, make sunos41 instead.
- $(MAKE) wermit "CC= /usr/5bin/cc " "CC2=/usr/5bin/cc " \
- KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSUN4S5 -DDIRENT -DHDBUUCP -DNOLEARN -DCK_POLL $(KFLAGS) -O"
-
-#As above, but with curses support
-sunos41s5c:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 System V R3...
- @echo Curses included.
- @echo For testing purposes only - NOT for production use.
- @echo For a useable version, make sunos41 instead.
- $(MAKE) wermit "CC= /usr/5bin/cc " "CC2=/usr/5bin/cc " \
- KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSUN4S5 -DDIRENT -DHDBUUCP -DNOLEARN \
- -DCK_POLL -DCK_CURSES -DCK_NEWTERM $(KFLAGS) -O" "LIBS= -lcurses"
-
-#As above, but with curses support AND net support
-sunos41s5tcpc:
- @echo Making C-Kermit $(CKVER) for SunOS 4.1 System V R3...
- @echo TCP/IP and curses included. No debug log.
- @echo For testing purposes only - NOT for production use.
- @echo For a useable version, make sunos41 instead.
- $(MAKE) xermit "CC= /usr/5bin/cc " "CC2=/usr/5bin/cc " \
- KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSUN4S5 -DDIRENT -DHDBUUCP -DCK_POLL \
- -DNODEBUG -DCK_CURSES -DCK_NEWTERM -DTCPSOCKET $(KFLAGS) -O" \
- "LIBS= -lcurses -lresolv"
-
-# (End of SunOS test entries...)
-
-#Apollo with Domain SR10.0 or later, BSD environment
-#Reportedly, it might also help to add '-A,systype=bsd4.3' to CFLAGS.
-#Reportedly, there is also a problem with getc & putc macros that can
-#be handled by using '#ifdef apollo' somewhere to redefine them???
-#On the other hand, other reports indicate that it works fine as-is.
-#NOTE: This entry was previously like this:
-# $(MAKE) wermit "CFLAGS= -DNOFILEH -DBSD4 $(KFLAGS) -Uaegis \
-# -DTCPSOCKET -U__STDC__"
-#Reports (Dec 91) indicate SR10 has an ANSI-compliant C compiler,
-#in addition to an older one that claimed to be ANSI-compliant but wasn't.
-#The following make entry (plus checks that are made in ckcdeb.h) detect
-#which compiler is used and define the CK_ANSIC or NOANSI flags accordingly.
-sr10-bsd:
- @echo Making C-Kermit $(CKVER) for Apollo SR10.0 / BSD ...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DAPOLLOSR10 -DBSD43 -DTCPSOCKET -DCK_CURSES -DNOLEARN \
- -Uaegis $(KFLAGS)" "LIBS= -lcurses -ltermcap"
-
-#Apollo with Domain SR10.0 or later, System V R3 environment.
-#Don't use the optimizer (-O), it causes problems at runtime.
-sr10-s5r3:
- @echo Making C-Kermit $(CKVER) for Apollo SR10.0 / Sys V R3 ...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DNOFILEH -DSVR3 -DAPOLLOSR10 -DNOLEARN $(KFLAGS) \
- -Uaegis -U__STDC__"
-
-#Apollo Domain/IX (untested, try this if sr10-bsd doesn't work)
-# -DTCPSOCKET can probably be added here.
-apollobsd:
- @echo Making C-Kermit $(CKVER) for Apollo Domain/IX...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CC= /bin/cc " "CC2= /bin/cc " \
- "CFLAGS= -DNOFILEH -DBSD4 -DAPOLLOBSD -DNOLEARN $(KFLAGS) -Uaegis"
-
-#Version 7 Unix (see comments near top of makefile)
-v7:
- @echo Making C-Kermit $(CKVER) for UNIX Version 7.
- @echo Read the makefile if you have trouble with this...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS=-DV7 -DPROCNAME=\\\"$(PROC)\\\" \
- -DBOOTNAME=\\\"$(BOOTFILE)\\\" -DNPROCNAME=\\\"$(NPROC)\\\" \
- -DNPTYPE=$(NPTYPE) $(DIRECT) -DO_RDWR=2 -DO_NDELAY=0 -DO_SCCS_ID \
- -DNOLEARN $(KFLAGS)"
-
-#AT&T UNIX System V R3, signal() is void rather than int.
-#Uses dirent.h and Honey DanBer UUCP.
-#Add the -i link option if necessary.
-#If you get errors like "ws_row undefined" in ckutio.c, add -DNONAWS.
-sys5r3:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R3...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DNOLEARN $(KFLAGS) -O" \
- "LNKFLAGS="
-
-#As above, plus curses.
-sys5r3c:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R3 + curses...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DCK_CURSES -DNONAWS -DNOLEARN \
- $(KFLAGS) -O" "LNKFLAGS=" "LIBS = -ltermlib"
-
-#System V R3.2 for PCs built on Interactive UNIX SV/386 R4.x
-#but with all calls to dup2() disabled because generic SVR3 does not have dup2.
-# (The -linet library might not need to be in this one.)
-sys5r32is:
- @echo 'Making C-Kermit $(CKVER) for System V/386 R32
- $(MAKE) wermit CC="$(CC)" CC2="$(CC2)" \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -O -DNOCSETS -DNOREALPATH \
- -DUID_T=ushort -DGID_T=ushort -DI386IX -DSVR3JC -DCK_CURSES -DNONAWS \
- -DPOSIX_JC -DCK_REDIR -DCK_POLL -DDCLGETCWD -DNOFDZERO -DNOREDIRECT \
- -DNOZEXEC -DNOLEARN $(KFLAGS)" "LIBS=-lcurses -lc_s -linet"
-
-#System V R3.2 for PCs built on Interactive UNIX SV/386 R4.x
-#but with all calls to dup2() disabled because generic SVR3 does not have dup2.
-#With TCP/IP added.
-sys5r32isnet:
- @echo 'Making C-Kermit $(CKVER) for System V/386 R32 + TCP/IP
- $(MAKE) wermit CC="$(CC)" CC2="$(CC2)" \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -O -DNOCSETS -DNOREALPATH \
- -DUID_T=ushort -DGID_T=ushort -DI386IX -DSVR3JC -DCK_CURSES -DNONAWS \
- -DPOSIX_JC -DCK_REDIR -DCK_POLL -DDCLGETCWD -DNOFDZERO -DNOREDIRECT \
- -DNOLEARN -DNOZEXEC -DTCPSOCKET $(KFLAGS)" "LIBS=-lcurses -lc_s -linet"
-
-iclsys5r3:
- make sys5r3 KTARGET=$${KTARGET:-$(@)} KFLAGS=-DICLSVR3
-
-#AT&T UNIX System V R3. As above, but no ANSI prototyping.
-sys5r3na:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R3...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DNOANSI -DNOLEARN $(KFLAGS) -O" \
- "LNKFLAGS="
-
-#AT&T UNIX System V R3, for 3B computers with Wollongong TCP/IP.
-sys5r3net3b:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX SVR3/3B/Wollongong...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DWOLLONGONG -DNOLEARN $(KFLAGS) \
- -O" "LIBS= -lnet -lnsl_s" "LNKFLAGS ="
-
-#AT&T UNIX System V R3, signal() is void rather than int.
-#Uses dirent.h and Honey DanBer uucp, has <termiox.h>.
-#Has <termiox.h> for RTS/CTS flow control.
-sys5r3tx:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R3...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DTERMIOX -DNOLEARN \
- $(KFLAGS) -i -O" "LNKFLAGS ="
-
-#AT&T UNIX System V R3, signal() is void rather than int.
-#Uses dirent.h and Honey DanBer uucp, has <termiox.h>.
-#Has <sys/termiox.h> for RTS/CTS flow control.
-sys5r3sx:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R3...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DSTERMIOX -DNOLEARN \
- $(KFLAGS) -i -O" "LNKFLAGS ="
-
-#AT&T UNIX System V R4.
-#Has <termiox.h>.
-sys5r4:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DTERMIOX -DNOLEARN $(KFLAGS)" \
- "LNKFLAGS = -s"
-
-#AT&T UNIX System V R4 with Wollongong TCP/IP.
-#Has <termiox.h>.
-sys5r4net:
- @echo 'Making C-Kermit $(CKVER) for System V R4 + Wollongong TCP/IP...'
- @echo ' If sockets-library routines are missing at link time, then'
- @echo ' try the sys5r4net2 entry.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DNOLEARN \
- -DTERMIOX -DWOLLONGONG $(KFLAGS)" "LNKFLAGS = -s"
-
-#As above, but needs libs included.
-sys5r4net2:
- @echo ' PLEASE READ ckuins.txt IF YOU GET MISSING HEADER FILES.'
- @echo ' (Search for WOLLONGONG...)'
- $(MAKE) sys5r4net KTARGET=$${KTARGET:-$(@)} "LIBS= -lsocket -lnsl"
-
-#As above plus curses.
-sys5r4net2c:
- echo 'Making C-Kermit $(CKVER) for System V R4 + Wollongong TCP/IP...'
- @echo ' PLEASE READ ckuins.txt IF YOU GET MISSING HEADER FILES.'
- @echo ' (Search for WOLLONGONG...)'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DNOLEARN \
- -DTERMIOX -DWOLLONGONG -DCK_CURSES $(KFLAGS)" "LNKFLAGS = -s" \
- "LIBS= -lsocket -lnsl -lcurses"
-
-#DELL UNIX System V R4.
-#Has <sys/termiox.h>, regular Berkeley sockets library, i.e. in.h and inet.h
-#are not misplaced in sys (rather than netinet and arpa, respectively).
-#Uses ANSI C constructs, advisory file locking on devices, etc.
-#Warning: -DSTERMIOX enables hardware flow control (RTS/CTS), but reportedly
-#this does not work with the normal drivers. However, it might still work
-#on non-Dell systems, or even Dell systems with different drivers installed.
-dellsys5r4:
- @echo 'Making C-Kermit $(CKVER) for DELL UNIX System V R4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDELL_SVR4 -DDIRENT -DHDBUUCP \
- -DTCPSOCKET -DSTERMIOX -DCK_POLL $(KFLAGS)" \
- "LIBS= -lsocket -lnsl" "LNKFLAGS = -s"
-
-#As above, curses support added...
-dellsys5r4c:
- @echo 'Making C-Kermit $(CKVER) for DELL UNIX System V R4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDELL_SVR4 -DDIRENT -DHDBUUCP \
- -DTCPSOCKET -DSTERMIOX -DCK_CURSES -DCK_POLL \
- $(KFLAGS)" "LIBS= -lsocket -lnsl -lcurses -ltermcap" "LNKFLAGS = -s"
-
-#Minimum interactive: As above, but with every conceivable option removed.
-dellsys5r4mi:
- @echo 'Making C-Kermit $(CKVER) for DELL UNIX System V R4...'
- @echo 'Minimum-size interactive'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDELL_SVR4 -DDIRENT \
- -UTCPSOCKET -DNOCMDL -DNOSPL -DNOXMIT -DCK_POLL \
- -DNOMSEND -DNOFRILLS -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG \
- -DNOSCRIPT -DNOCSETS -DNOSHOW -DNOSETKEY -DNOSERVER -DNOUUCP \
- -DNOPUSH -DNOMDMHUP -DNOJC -DNOFDZERO -DNOESCSEQ \
- $(KFLAGS)" "LNKFLAGS = -s"
-
-#Command-line only version.
-dellsys5r4m:
- @echo 'Making C-Kermit $(CKVER) for DELL UNIX System V R4...'
- @echo 'Command-line only'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDELL_SVR4 -DDIRENT \
- -UTCPSOCKET -DNOICP -DNOFRILLS -DNODIAL -DNODEBUG -DNOTLOG -DNOCSETS \
- -DNOSETKEY -DNOESCSEQ -DNOJC -DNOFDZERO -DCK_POLL \
- $(KFLAGS)" "LNKFLAGS = -s"
-
-#AT&T UNIX System V R4.
-#Has <sys/termiox.h>.
-sys5r4sx:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DSTERMIOX -DNOLEARN \
- $(KFLAGS)" "LNKFLAGS = -s" "LIBS=$(LIBS)"
-
-#AT&T UNIX System V R4.
-#Has <sys/termiox.h>, regular Berkeley sockets library, i.e. in.h and inet.h
-#are not misplaced in sys (rather than netinet and arpa, respectively).
-#Uses ANSI C constructs, <sys/termiox.h>, etc etc.
-sys5r4sxtcp:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP \
- -DSTERMIOX -DTCPSOCKET $(KFLAGS)" \
- "LIBS= -lsocket -lnsl $(LIBS)" "LNKFLAGS= -s"
-
-#AT&T UNIX System V R4.
-#As above + curses.
-sys5r4sxtcpc:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP \
- -DSTERMIOX -DCK_CURSES -DTCPSOCKET $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermcap $(LIBS)" "LNKFLAGS = -s"
-
-#AT&T UNIX System V R4. CONSENSYS SVR4.2-1.
-#Has <sys/termiox.h>, regular Berkeley sockets library, i.e. in.h and inet.h
-#are not misplaced in sys (rather than netinet and arpa, respectively).
-#Uses ANSI C constructs, <sys/termiox.h>, etc.
-# Fullscreen -DCK_CURSES added (with curses & termcap libs)
-# Submission by Robert Weiner/Programming Plus, rweiner@watsun.cc.columbia.edu
-sys5r4sxtcpf:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP \
- -DSTERMIOX -DTCPSOCKET -DCK_CURSES $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -L/usr/ccs/lib -lcurses -ltermcap" \
- "LIBS=$(LIBS)" "LNKFLAGS = -s"
-
-#Smallest possible version for System V R4
-s5r4m:
- @echo Minimum size
- $(MAKE) "MAKE=$(MAKE)" sys5r4sx KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG \
- -DNOSCRIPT -DNOCSETS -DNOICP -DNOMSEND -UTCPSOCKET" "LNKFLAGS = -s"
-
-#Smallest possible interactive version of above
-s5r4mi:
- @echo Minimum interactive
- $(MAKE) "MAKE=$(MAKE)" sys5r4sx \
- "KFLAGS=-DNOSPL -DNOXMIT -DNOMSEND -DNOFRILLS -DNOSHOW \
- -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG -DNOSCRIPT -DNOCSETS -DNOSETKEY \
- -UTCPSOCKET $(KFLAGS)" "LNKFLAGS = -s"
-
-#AT&T UNIX System V R4, has <sys/termiox.h>
-#ANSI C function prototyping disabled.
-sys5r4sxna:
- @echo No ANSI C prototyping...
- $(MAKE) "MAKE=$(MAKE)" sys5r4sx KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -DNOANSI"
-
-#Stratus FTX.
-ftx:
- @echo 'Making C-Kermit $(CKVER) for Stratus FTX 3.x...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DFTX -DDIRENT -DHDBUUCP -DSTERMIOX \
- -DNOGETUSERSHELL -DNOLEARN +DA1.1 $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS=$(LIBS)"
-
-#Stratus FTX + TCP/IP.
-ftxtcp:
- @echo 'Making C-Kermit $(CKVER) for Stratus FTX 3.x...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DFTX -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \
- -DSTERMIOX -DTCPSOCKET -DNO_DNS_SRV +DA1.1 $(KFLAGS)" \
- "LIBS= -lsocket -lnsl $(LIBS)" "LNKFLAGS= -s"
-
-#NCR MP-RAS 2.03 or 3.02
-mpras:
- @echo 'Making C-Kermit $(CKVER) for NCR MP-RAS...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DNCRMPRAS -DDIRENT -DHDBUUCP -DSTERMIOX \
- -DNOGETUSERSHELL -DUSE_FILE__CNT -DNOLEARN -DNO_DNS_SRV $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS=$(LIBS)"
-
-#NCR MP-RAS 2.03 or 3.02 with TCP/IP and curses
-mprastcpc:
- @echo 'Making C-Kermit $(CKVER) for NCR MP-RAS + TCP/IP + curses...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CFLAGS=-DTCPSOCKET \
- -DCK_CURSES -DSVR4 -DNCRMPRAS -DDIRENT -DHDBUUCP -DSTERMIOX -DNOLEARN \
- -DNOGETUSERSHELL -DNO_DNS_SRV DUSE_FILE__CNT -O $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS= -lsocket -lnsl -lcurses -ltermcap $(LIBS)"
-
-#SINIX-L V5.41 - includes curses, tcp/ip - Use this one for i386.
-#This version of SINIX doesn't like fdopen() or popen().
-sinix541:
- @echo 'Making C-Kermit $(CKVER) for Siemens/Nixdorf SINIX V5.41/i386'
- $(MAKE) ckcpro.$(EXT) "CFLAGS = -DSINIX -DSVR4 -DDIRENT -DHDBUUCP \
- -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC -DNO_DNS_SRV \
- -DSNI541 -DNOGETUSERSHELL -DNONETCMD -DNOPOPEN -kansi -W0 $(KFLAGS)"
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSINIX -DSVR4 -DDIRENT -DHDBUUCP -DNO_DNS_SRV -DNOPOPEN \
- -DFNFLOAT -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC \
- -DSNI541 -DNOGETUSERSHELL -DNONETCMD -kansi -W0 -O $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermcap -lm" "LNKFLAGS = -s"
-
-sinix541i:
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" sinix541
-
-#SINIX V5.42 - includes curses, tcp/ip, everything - Use this one for MIPS.
-# As of C-Kermit 7.1, optimization removed -- takes (literally) forever.
-sinix542:
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSINIX -DSVR4 -DDIRENT -DHDBUUCP -DNO_DNS_SRV \
- -DFNFLOAT -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC \
- -DSNI542 -DNOGETUSERSHELL -kansi -W0 $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermcap -lm" "LNKFLAGS = -s"
-
-#SINIX V5.42 gcc - includes curses, tcp/ip, everything.
-#This one was used to build the Pyramid-architecture RM600 version
-#on SINIX-P 5.42 A10 with gcc but should work for SINIX 5.42 on any other
-#architecture with gcc.
-sinix542g:
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC=gcc" "CC2=gcc" \
- "CFLAGS = -DSINIX -DSVR4 -DDIRENT -DHDBUUCP -DNO_DNS_SRV \
- -DFNFLOAT -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC \
- -DSNI542 -DNOGETUSERSHELL $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermcap -lm" \
- "LNKFLAGS = -s"
-
-#SINIX V5.42 - includes curses, tcp/ip, everything - Use this one for Intel.
-# (Note: SNI discontinued Intel support after 5.42.)
-sinix542i:
- @echo 'Making C-Kermit $(CKVER) for Siemens/Nixdorf SINIX-Z V5.42...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSINIX -DSVR4 -DDIRENT -DHDBUUCP -DFNFLOAT -DSTERMIOX \
- -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC -DNO_DNS_SRV -kansi \
- -DSNI542 $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermcap -lm" \
- "LNKFLAGS = -s"
-
-#Siemens Nixdorf Reliant UNIX V5.43 - includes curses, tcp/ip, everything:
-# . gettimeofday() suddenly has only one arg instead of two (GTODONEARG).
-# . The syntax of the Olimit specifier changed.
-# . The name was changed from SINIX to Reliant UNIX in version 5.43C.
-sni543:
- @echo 'Making C-Kermit $(CKVER) for Siemens/Nixdorf Reliant UNIX V5.43'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSINIX -DSNI543 -DSVR4 -DDIRENT -DHDBUUCP \
- -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC -DGTODONEARG \
- -DNO_DNS_SRV -kansi -W0 -O -F Olimit,3100 $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermcap" "LNKFLAGS = -s"
-
-#Siemens Nixdorf Reliant UNIX V5.44 - Like 5.43 but with different banner.
-sni544:
- @echo 'Making C-Kermit $(CKVER) for Siemens/Nixdorf Reliant UNIX V5.44'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSINIX -DSNI544 -DSVR4 -DDIRENT -DHDBUUCP \
- -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC -DGTODONEARG \
- -DNO_DNS_SRV -kansi -W0 -O -K Olimit,3100 $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermcap" "LNKFLAGS = -s"
-
-#Commodore Amiga with AT&T UNIX System V R4 and TCP/IP support.
-#Has <sys/termiox.h>.
-svr4amiganet:
- @echo 'Making C-Kermit $(CKVER) for Amiga SVR4 + TCP/IP...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC=gcc" "CC2=gcc" \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DSTERMIOX \
- -DTCPSOCKET -DCK_CURSES $(KFLAGS)" "LNKFLAGS = -s" \
- "LIBS = -lsocket -lnsl -ltermlib"
-
-#SCO (Novell (Univel)) UnixWare 1.x or 2.0, no TCP/IP.
-#This assumes the Novell SDK 1.0, which has <sys/termiox.h>.
-#UnixWare users with the "Prime Time Freeware" CD-ROM SDK will probably have
-#to use the sys5r4 entry (no termiox.h file, so no hardware flow control).
-#Change -DSELECT to -DCK_POLL if -DSELECT causes problems.
-# NOTE: Unixware 1.x builds have not been tried in C-Kermit 7.0.
-unixware:
- $(MAKE) "MAKE=$(MAKE)" sys5r4sx KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DOLD_UNIXWARE -DCK_NEWTERM -DSELECT -DNOGETUSERSHELL \
- -DNOSYSLOG $(KFLAGS)" "LIBS=-lcrypt"
-
-#UnixWare 1.x or 2.0 with TCP/IP and curses.
-#fork()-based CONNECT - no high serial speeds.
-unixwarenetc:
- $(MAKE) "MAKE=$(MAKE)" sys5r4sxtcpc KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DOLD_UNIXWARE -DCK_NEWTERM -DSELECT -DNOGETUSERSHELL \
- -DNOSYSLOG $(KFLAGS)" "LIBS=-lcrypt -lresolv"
-
-uw10:
- $(MAKE) unixwarenetc KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS)"
-
-#This is for Unixware 2.0.x only - use unixware21 for UW 2.1.x.
-#Has special library search and enables special kludge around library
-#foulup regarding vfork() (which Kermit doesn't use). Forces POSIX-style
-#hangup.
-unixware20:
- @echo 'Making C-Kermit $(CKVER) for UnixWare 2.0.x...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DOLD_UNIXWARE -DUNIXWARE2 -DSELECT -DSVR4 -DDIRENT \
- -DHDBUUCP -DBIGBUFOK -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES \
- -DTCPSOCKET -DUW200 -DFNFLOAT -DCK_NEWTERM -DNOSYSLOG $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermcap -lcrypt -lgen -lm -lresolv" \
- "LNKFLAGS = -s"
-
-uw20:
- $(MAKE) unixware20 KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS)"
-
-#Adds big buffers ("large memory model") - otherwise the same as UnixWare 1.x.
-unixware21:
- @echo 'Making C-Kermit $(CKVER) for UnixWare 2.1.x...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \
- -DNOSYSLOG -DSTERMIOX -DCK_CURSES -DTCPSOCKET \
- -DCK_NEWTERM -DFNFLOAT -DUNIXWARE2 $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv \
- $(LIBS)" "LNKFLAGS = -s"
-
-#Unixware 2.1.0
-uw21:
- $(MAKE) unixware21 KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS)"
-
-#Unixware 2.1.3
-uw213:
- $(MAKE) unixware21 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DUSE_FILE__CNT $(KFLAGS)"
-
-#Unixware 2.1 with IKSD support
-uw21iksd:
- $(MAKE) unixware21 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DCK_SHADOW $(KFLAGS)" "LIBS= -lgen"
-
-#UnixWare 7 with tc[gs]etspeed() high serial speeds & select()-based CONNECT
-#and as of C-Kermit 8.0.212, large file support (LFS).
-#NOTE: This is the one we use.
-unixware7t:
- @echo 'Making C-Kermit $(CKVER) for UnixWare 7 with POSIX i/o...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \
- -DFNFLOAT -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DPOSIX \
- -DUW7 -DUSETCSETSPEED -DCK_NEWTERM -DNOLSTAT -DDCLTIMEVAL \
- -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DNEEDMDMDEFS $(KFLAGS)" \
- "LIBS=-lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv $(LIBS)" \
- "LNKFLAGS = -s"
-
-#UnixWare 7 - select()-based CONNECT - no POSIX i/o - no high serial speeds.
-#In other words, just like the UnixWare 1 and 2 builds.
-unixware7x:
- @echo 'Making C-Kermit $(CKVER) for UnixWare 7...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \
- -DUW7 -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DNOLSTAT \
- -DFNFLOAT -DCK_NEWTERM $(KFLAGS)" \
- "LIBS=-lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv $(LIBS)" \
- "LNKFLAGS = -s"
-
-#UnixWare 7 with POSIX cfset[oi]speed() to allow high serial speeds.
-#(but the high speeds don't work)
-unixware7p:
- @echo 'Making C-Kermit $(CKVER) for UnixWare 7 with POSIX i/o...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \
- -DUW7 -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DPOSIX \
- -DFNFLOAT -DCK_NEWTERM -DNOLSTAT $(KFLAGS)" \
- "LIBS=-lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv $(LIBS)" \
- "LNKFLAGS = -s"
-
-# UnixWare 7 built with gcc - This does not work at all...
-# Reportedly gcc 2.8.1 is broken on Unixware 7. Try egcs?
-unixware7g:
- @echo 'Making C-Kermit $(CKVER) for UnixWare 7 with gcc...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CC = gcc" "CC2 = gcc" "LNKFLAGS = -s -shlib"
- "CFLAGS = -O -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \
- -DUW7 -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DNOLSTAT \
- -DFNFLOAT -DCK_NEWTERM $(KFLAGS)" \
- "LIBS=-lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv $(LIBS)" \
- "LNKFLAGS = -s"
-
-unixware7:
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" unixware7t \
- KTARGET=$${KTARGET:-$(@)}
-
-uw7:
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" unixware7t \
- KTARGET=$${KTARGET:-$(@)}
-
-#SCO OpenUNIX 8.0
-ou8:
- @echo 'Making C-Kermit $(CKVER) for Open UNIX 8...'
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=-DOU8 $(KFLAGS)" unixware7t \
- KTARGET=$${KTARGET:-$(@)}
-
-#UnixWare 7 with OpenSSL
-uw7ssl uw7+ssl:
- @echo 'Making C-Kermit $(CKVER) for UnixWare 7 and OpenSSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DCK_AUTHENTICATION -DCK_SSL -DCK_SHADOW \
- -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \
- -DFNFLOAT -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DPOSIX \
- -DUW7 -DUSETCSETSPEED -DCK_NEWTERM -DNOLSTAT -DDCLTIMEVAL \
- $(SSLINC) $(KFLAGS)" \
- "LIBS=-lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv \
- -lgen -lcudk70 $(SSLLIB) -lssl -lcrypto $(LIBS)" \
- "LNKFLAGS = -s"
-
-#As above but includes Shadow password support needed for IKSD.
-uw7iksd:
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=-DCK_SHADOW $(KFLAGS)" \
- KTARGET=$${KTARGET:-$(@)} "LIBS= -lgen" unixware7t
-
-#As above but links with static API for realpath() so a binary built
-#with this target on UW7.1 will also work on 7.0. Requires SCO UDK
-#rather than the stock compiler.
-uw7iksdudk:
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=-DCK_SHADOW $(KFLAGS)" \
- KTARGET=$${KTARGET:-$(@)} "LIBS= -lgen -lcudk70" unixware7t
-
-#ESIX SVR4.0.3 or 4.04 with TCP/IP support.
-#Has <sys/termiox.h>, ANSI C function prototyping disabled.
-#Add -m486 to CFLAGS if desired.
-esixr4:
- @echo 'Making C-Kermit $(CKVER) for ESIX SVR4 + TCP/IP...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DNOANSI \
- -DSTERMIOX -DTCPSOCKET $(KFLAGS)" "LNKFLAGS = -s" \
- "LIBS = -lsocket -lnsl"
-
-#AT&T UNIX System V R4.
-#Has <sys/termiox.h>, Wollongong WIN/TCP TCP/IP.
-sys5r4sxnet:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP \
- -DSTERMIOX -DWOLLONGONG $(KFLAGS)" "LNKFLAGS = -s"
-
-#AT&T UNIX System V R4, no <termio.x> or <sys/termio.x>.
-sys5r4nx:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DNOLEARN $(KFLAGS)" \
- "LNKFLAGS = -s"
-
-#AT&T UNIX System V R4, no <termio.x> or <sys/termio.x>, curses, TCP/IP.
-sys5r4nxnetc:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP \
- -DCK_CURSES -DTCPSOCKET $(KFLAGS)" \
- "LIBS = -lcurses -lsocket -lnsl -ltcpip" \
- "LNKFLAGS = -s"
-
-#AT&T UNIX System V R4, no <termio.x> or <sys/termio.x>, Wollongong TCP/IP.
-sys5r4nxtwg:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DWOLLONGONG $(KFLAGS)"
- "LNKFLAGS = -s"
-
-#ICL UNIX System V R4.(DRS N/X) version :-
-#UNIX System V Release 4.0 ICL DRS 6000 (SPARC)
-#DRS/NX 6000 SVR4 Version 5 Level 1 Increment 4
-#Has <sys/termiox.h>, regular Berkeley sockets library, i.e. in.h and inet.h
-#are not misplaced in sys (rather than netinet and arpa, respectively).
-#Uses ANSI C constructs, advisory file locking on devices, etc.
-#Remove -lnsl if it causes trouble.
-iclsys5r4:
- @echo 'Making C-Kermit $(CKVER) for ICL UNIX System V R4 (DRS N/X)'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DICL_SVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \
- -DSTERMIOX -DTCPSOCKET $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lresolv " "LNKFLAGS = -s"
-
-#As above but for DRS/NX 4.2MP 7MPlus.
-iclsys5r4m+:
- @echo 'Making C-Kermit $(CKVER) for ICL UNIX System V R4 DRS/NX 4.2MP+'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DICL_SVR4 -DDIRENT -DHDBUUCP -DNOIKSD \
- -DSTERMIOX -DTCPSOCKET $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lm -lc -g -lgen " "LNKFLAGS = -s"
-
-#As above but for DRS/NX 4.2MP 7MPlus with IKSD support.
-iclsys5r4m+iksd:
- @echo 'Making C-Kermit $(CKVER) for ICL UNIX System V R4 DRS/NX 4.2MP+'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DICL_SVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \
- -DSTERMIOX -DTCPSOCKET $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lm -lc -g -lgen -lresolv " "LNKFLAGS = -s"
-
-iclsys5r4_486:
- $(MAKE) "MAKE=$(MAKE)" iclsys5r4 KTARGET=$${KTARGET:-$(@)}
-
-#Data General DG/UX 4.30 (System V R3) for DG AViiON, with TCP/IP support.
-dgux430:
- @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 4.30...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DDGUX430 -DSVR3 -DDIRENT -DTCPSOCKET \
- -DNOINADDRX -DNOGETUSERSHELL $(KFLAGS)"
-
-#Data General DG/UX 4.30 for DG AViiON, with TCP/IP support with BSDisms.
-dgux430bsd:
- @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 4.30...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DDGUX430 -D_BSD_SOURCE -DBSD4 \
- -DNOINADDRX -DTCPSOCKET -DNOGETUSERSHELL $(KFLAGS)"
-
-#Data General DG/UX 5.4 (System V R4) for DG AViiON, with TCP/IP support.
-#Add -lsocket -lnsl if inet_addr comes up missing...
-#Hmmm - I really think CK_POLL can be removed from this one in which case
-#there is no difference between dgux540 and dgux540i.
-dgux540:
- @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 5.40...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DDGUX540 -DDIRENT -DHDBUUCP -DNOINADDRX \
- -DSTERMIOX -DTCPSOCKET -DCK_POLL -DNOGETUSERSHELL $(KFLAGS)"
-
-#Data General DG/UX 5.40 (System V R4) for Intel AViiON, with TCP/IP support.
-dgux540i:
- @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 5.40...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DDGUX540 -DDIRENT -DHDBUUCP -DNOINADDRX \
- -DSTERMIOX -DTCPSOCKET -DNOGETUSERSHELL $(KFLAGS)" \
- "LIBS = -lsocket -lnsl"
-
-dgux54:
- make dgux540 KTARGET=$${KTARGET:-$(@)}
-
-#Data General DG/UX 5.4 (= System V R4) for DG AViiON, with TCP/IP support.
-# And curses.
-dgux540c:
- @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 5.4...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DDGUX540 -DDIRENT -DHDBUUCP -DNOINADDRX \
- -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \
- $(KFLAGS)" "LIBS= -lcurses8 -ltermcap" "LNKFLAGS = -s"
-
-#As above but for Intel - only difference is name library names.
-dgux540ic:
- @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 5.40...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DDGUX540 -DDIRENT -DHDBUUCP -DNOINADDRX \
- -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \
- $(KFLAGS)" "LIBS = -lsocket -lnsl -lcurses -ltermcap"
-
-dgux54c:
- make dgux540c KTARGET=$${KTARGET:-$(@)}
-
-#DG/UX 5.4R3.10
-dgux54310:
- @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 5.4R3...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DDGUX540 -DDGUX54310 -DDIRENT -DHDBUUCP -DSELECT \
- -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \
- -DNOINADDRX $(KFLAGS)" "LIBS= -lcurses8 -ltermcap" "LNKFLAGS = -s"
-
-#DG/UX 5.4R4.10 - Includes everything.
-dgux54410:
- @echo 'Making C-Kermit $(CKVER) for DG/UX 5.4R4.10...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DDGUX540 -DDGUX54410 -DDIRENT -DHDBUUCP -DSELECT \
- -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \
- -DNOINADDRX $(KFLAGS)" "LIBS = -lsocket -lnsl -lcurses -ltermcap"
-
-#DG/UX 5.4R4.11 - Includes everything.
-dgux54411:
- @echo 'Making C-Kermit $(CKVER) for DG/UX 5.4R4.11...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DDGUX540 -DDGUX54411 -DDIRENT -DHDBUUCP -DSELECT \
- -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \
- -DNOINADDRX $(KFLAGS)" "LIBS = -lsocket -lnsl -lcurses -ltermcap"
-
-#DG/UX 5.4R4.20 - Includes everything.
-dgux54420:
- @echo 'Making C-Kermit $(CKVER) for DG/UX 5.4R4.20...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DDGUX540 -DDGUX54420 -DDIRENT -DHDBUUCP -DSELECT \
- -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \
- -DNOINADDRX $(KFLAGS)" \
- "LIBS = -lsocket -lresolv -lnsl -lcurses -ltermcap"
-
-#Silicon Graphics System V R3 with BSD file system (IRIS)
-iris:
- @echo Making C-Kermit $(CKVER) for Silicon Graphics IRIX pre-3.3...
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR3 -DLONGFN -DNOLEARN $(KFLAGS) -I/usr/include/bsd" \
- "LIBS = -lbsd"
-
-#Silicon Graphics IRIS System V R3
-irix33:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 3.3...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DNOLEARN $(KFLAGS) -O" \
- "LNKFLAGS = -s"
-
-#Silicon Graphics Iris Indigo with IRIX 4.0.0 or 5.0...
-#Strict ANSI C compilation, TCP/IP support included
-irix40:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 4.0...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DIRIX40 -DSVR3 -DDIRENT -DHDBUUCP -DPWID_T=uid_t \
- -DCK_ANSIC -DTCPSOCKET $(KFLAGS) -O -Olimit 1600 -I/usr/include/bsd" \
- "LNKFLAGS = -s"
-
-#As above, but with fullscreen display (curses) and Sun Yellow Pages support.
-#NOTE: IRIX versions prior to 5 run COFF binaries.
-irix40ypc:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 4.0.'
- @echo 'Includes fullscreen file display and Sun Yellow Pages...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DIRIX40 -DSVR3 -DDIRENT -DHDBUUCP -DCK_CURSES \
- -DPWID_T=uid_t -DCK_ANSIC -DTCPSOCKET $(KFLAGS) \
- -O -Olimit 1600 -I/usr/include/bsd" \
- "LIBS = -lcurses -lsun" "LNKFLAGS = -s"
-
-# Silicon Graphics Iris Series 4D/*, IRIX 4.0.x, -O4 ucode optimized.
-# Huge temporary file space needed for ucode optimizer. If you get an error
-# like "ugen: internal error writing to /tmp/ctmca08777: Error 0", define the
-# the TMPDIR environment variable to point to a file system that has more
-# space available, e.g. "setenv TMPDIR /usr/tmp".
-irix40u:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 4.0...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DIRIX40 -DSVR3 -DDIRENT -DHDBUUCP -DPWID_T=uid_t \
- -DCK_ANSIC -DTCPSOCKET $(KFLAGS) -O4 -Olimit 1600" \
- "LNKFLAGS=-O4 -Olimit 1600 -s" "EXT=u"
-
-# As above, with Curses Support added
-irix40uc:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 4.0...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DIRIX40 -DSVR3 -DDIRENT -DHDBUUCP -DPWID_T=uid_t \
- -DCK_ANSIC -DCK_CURSES -DTCPSOCKET $(KFLAGS) -O4 -Olimit 1600" \
- "LNKFLAGS=-O4 -Olimit 1600 -s" "EXT=u" "LIBS= -lcurses -ltermcap"
-
-#Silicon Graphics IRIX 5.x.
-#Yellow Pages and Curses support included.
-#IRIX version 5.x can run COFF or ELF binaries.
-irix51:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 5.x'
- @echo 'Includes fullscreen file display and Yellow Pages...'
- @echo 'Add -mips<n> to CFLAGS specify a particular hardware target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DIRIX51 -DSVR4 -DDIRENT -DHDBUUCP -DCK_CURSES -DCK_NEWTERM \
- -DPWID_T=uid_t -DCK_ANSIC -DTCPSOCKET -DSELECT -DNOGETUSERSHELL \
- -DSYSTIMEH -DDCLPOPEN -DDCLFDOPEN $(KFLAGS) -ansi -O -Olimit 3000" \
- "LIBS = -lcurses" "LNKFLAGS = -s"
-
-#Use this one if irix51 blows up due to lack of swap space or whatever.
-irix51x:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 5.x'
- @echo 'Includes fullscreen file display and Yellow Pages...'
- @echo 'Add -mips<n> to CFLAGS specify a particular hardware target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DIRIX51 -DSVR4 -DDIRENT -DHDBUUCP -DCK_CURSES -DCK_NEWTERM \
- -DPWID_T=uid_t -DCK_ANSIC -DTCPSOCKET -DSELECT -DNOGETUSERSHELL \
- -DSYSTIMEH -DDCLPOPEN -DDCLFDOPEN $(KFLAGS)" \
- "LIBS = -lcurses" "LNKFLAGS = -s"
-
-irix51ypc:
- $(MAKE) "MAKE=$(MAKE)" irix51 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS= $(KFLAGS)"
-
-#IRIX 5.2 adds RTS/CTS
-irix52:
- $(MAKE) "MAKE=$(MAKE)" irix51 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DIRIX52 -DCK_RTSCTS $(KFLAGS)"
-
-irix53:
- $(MAKE) "MAKE=$(MAKE)" irix51 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DIRIX52 -DIRIX53 -DCK_RTSCTS $(KFLAGS)"
-
-irix53x:
- $(MAKE) "MAKE=$(MAKE)" irix51x KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DIRIX52 -DIRIX53 -DCK_RTSCTS $(KFLAGS)"
-
-#Silicon Graphics IRIX 6.[024] common stuff.
-#Yellow Pages and Curses support included.
-#IRIX version 6.0 and later runs only ELF binaries.
-#Depends on code changes in ckcdeb.h that make -DIRIX6x define all
-#lower IRIX6x values and IRIX51.
-irix6x:
- @echo 'Includes fullscreen file display and Yellow Pages...'
- @echo 'Add -mips<n> to specify a particular hardware target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \
- -DCK_CURSES -DCK_NEWTERM -DPWID_T=uid_t -DCK_ANSIC -DTCPSOCKET \
- -DSELECT -DCK_RTSCTS -O $(KFLAGS)" \
- "LIBS = -lcurses" "LNKFLAGS = -s $(LNKFLAGS)"
-
-#Silicon Graphics IRIX 6.0.
-irix60:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 6.0'
- @$(MAKE) "MAKE=$(MAKE)" \
- "KFLAGS=-DIRIX60 -Olimit 2138 $(KFLAGS)" \
- irix6x KTARGET=$${KTARGET:-$(@)}
-
-#Silicon Graphics IRIX 6.2.
-#Serial speeds > 38400 are available in IRIX 6.2 on O-class machines only.
-#Note: Olimit must be a number > 0.
-irix62:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 6.2'
- @$(MAKE) "MAKE=$(MAKE)" \
- LNKFLAGS="-Wl,-woff,84" \
- "KFLAGS=-DIRIX62 -Olimit 4700 $(KFLAGS)" \
- irix6x KTARGET=$${KTARGET:-$(@)}
-
-#Silicon Graphics IRIX 6.3.
-irix63:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 6.3'
- @$(MAKE) "MAKE=$(MAKE)" irix62 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DIRIX63"
-
-#Silicon Graphics IRIX 6.4.
-# -woff,84 to linker stops complaints about no symbols loaded from
-# curses, and -woff 1110 stops complaints about unreachable "break;"
-# statements in ckcpro.c among others.
-# tested on SGI Octane, running IRIX 6.4 up to 115200 bps.
-# -Olimit 0 means infinite.
-irix64:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 6.4'
- @$(MAKE) "MAKE=$(MAKE)" \
- LNKFLAGS="-Wl,-woff,84" \
- "KFLAGS=-DIRIX64 -DCK_RTSCTS -Olimit 3000 -woff 1110 $(KFLAGS)" \
- irix6x KTARGET=$${KTARGET:-$(@)}
-
-irix64gcc:
- @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 6.4 gcc'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS= -DSVR4 -DIRIX64 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \
- -DSELECT -DPWID_T=uid_t -DTCPSOCKET -DNOCOTFMC \
- -DCK_ANSIC -DCK_RTSCTS -DCK_NEWTERM -DCK_CURSES \
- $(KFLAGS) -O" "LIBS= -lcurses -ltermcap -lcrypt"
-
-#Note the new Optimization option syntax for MIPSpro CC 7.2.1.2m.
-#See note on irix65gcc target about Large File Support (LFS).
-irix65:
- @echo 'Making C-Kermit $(CKVER) for SGI IRIX 6.5'
- @$(MAKE) "MAKE=$(MAKE)" LNKFLAGS="-Wl,-woff,84" \
- "KFLAGS=-DIRIX65 -D_LARGEFILE_SOURCE -DCK_RTSCTS -OPT:Olimit=0 \
- -woff 1110,1552,1174 $(KFLAGS)" \
- irix6x KTARGET=$${KTARGET:-$(@)}
-
-#Build for those that have GCC instead of MIPSpro.
-#
-# Large File Support note: use the define _LARGEFILE_SOURCE to enable support
-# for files larger than 2GB. This may work on releases of Irix prior to
-# 6.5.xx. To verify, check the man page for fstat and verify that off_t is a
-# 64 bit value for an -n32 build. Also check the manpage for fseek and ftell
-# to verify that the fseek64 and ftell64 functions are provided. If so, then
-# LFS support should work and you can try adding -D_LARGEFILE_SOURCE to CFLAGS
-# for your selected Irix target.
-#
-irix65gcc:
- @echo 'Making C-Kermit $(CKVER) for SGI IRIX 6.5 with gcc'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CC = gcc" "CC2 = gcc" \
- "CFLAGS= -DSVR4 -DIRIX65 -D_LARGEFILE_SOURCE -DDIRENT -DHDBUUCP \
- -DNOGETUSERSHELL -DSELECT -DPWID_T=uid_t -DTCPSOCKET -DNOCOTFMC \
- -DCK_ANSIC -DCK_RTSCTS -DCK_NEWTERM -DCK_CURSES \
- $(KFLAGS) -O" "LIBS= -lcurses"
-
-# The 64-bit IRIX target works but presumably is no longer needed given the
-# large file support in the more portable and compact 32-bit version.
-irix65_64:
- @echo 'Making C-Kermit $(CKVER) 64-bit for SGI IRIX 6.5'
- @$(MAKE) "MAKE=$(MAKE)" LNKFLAGS="-Wl,-woff,84" \
- "KFLAGS=-DIRIX65 -64 -DCK_RTSCTS -OPT:Olimit=0 -woff 1110,1552,1174 \
- -DCK_64BIT $(KFLAGS)" \
- irix6x KTARGET=$${KTARGET:-$(@)}
-
-#Dumb down to MIPS-2 if building on R5000 or higher...
-irix65mips2:
- @echo 'Making C-Kermit $(CKVER) for SGI IRIX 6.5 MIPS-2'
- @$(MAKE) "MAKE=$(MAKE)" LNKFLAGS="-o32 -mips2 -Wl,-woff,84" \
- "KFLAGS=-DIRIX65 -DCK_RTSCTS -OPT:Olimit=0 -o32 -mips2 \
- -woff 1110,1552,1174 $(KFLAGS)" \
- irix6x KTARGET=$${KTARGET:-$(@)}
-
-#Special target that adds srp, ssl, and zlib support. This requires
-#that you have pkgsrc installed instead of Irix Freeware. See
-#NetBSD.org for pkgsrc for Irix. You will need to BUILD the srp_client
-#package yourself. Install it manually using the directions found
-#in the netbsds+ssl+srp+zlib target comments.
-irix65+ssl+srp+zlib:
- @echo 'Making C-Kermit $(CKVER) for IRIX 6.5 with gcc and SSL SRP ZLIB'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CC = gcc" "CC2 = gcc" \
- "CFLAGS= -DIRIX65 -DSVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL -DSELECT \
- -DTCPSOCKET -DNOCOTFMC -DCK_NEWTERM -DPWID_T=uid_t -DCK_ANSIC \
- -I/usr/pkg/include -DCK_AUTHENTICATION -DCK_SRP -DPRE_SRP_1_4_5 \
- -DCK_RTSCTS -DCK_NCURSES -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DCK_SSL \
- -DLIBDES -DZLIB -DFNFLOAT -I/usr/pkg/include/openssl $(KFLAGS) -O" \
- "LIBS= -L/usr/pkg/lib -rpath /usr/pkg/lib -lncurses -lsrp -lgmp -ldes \
- -lssl -lkrypto -lcrypto -lcrypt -lz -lm"
-
-irix6x+krb5:
- @echo 'Includes fullscreen file display and Yellow Pages...'
- @echo 'Add -mips<n> to specify a particular hardware target.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \
- -DCK_CURSES -DCK_NEWTERM -DPWID_T=uid_t -DCK_ANSIC -DTCPSOCKET\
- -DSELECT -DCK_RTSCTS -O \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DCK_ENCRYPTION -DCK_DES \
- $(K5INC) $(K5INC)/krb5 $(KFLAGS)" \
- "LIBS = -lcurses $(K5LIB) -ldes425 -lkrb5 \
- -lcom_err -lcrypto -lcrypt -lgssapi_krb5" \
- "LNKFLAGS = -s $(LNKFLAGS)"
-
-irix65+krb5:
- @echo 'Making C-Kermit $(CKVER) for SGI IRIX 6.5'
- @$(MAKE) "MAKE=$(MAKE)" \
- LNKFLAGS="-Wl,-woff,84" \
- "KFLAGS=-DIRIX65 -DCK_RTSCTS -OPT:Olimit=0 -woff 1110,1552,1174 \
- $(KFLAGS)" \
- irix6x+krb5 KTARGET=$${KTARGET:-$(@)}
-
-#In case they type "make sys5"...
-sys5:
- $(MAKE) "MAKE=$(MAKE)" sys3 KTARGET=$${KTARGET:-$(@)}
-
-#Generic ATT System III or System V (with I&D space)
-sys3:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System III'
- @echo 'or System V R2 or earlier...'
- @echo 'add -DNOMKDIR if mkdir is an undefined symbol.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DNOUNICODE -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL \
- -DNOINITGROUPS -DNOFTRUNCATE -DNOREALPATH -DNOLEARN $(KFLAGS) -i -O" \
- "LNKFLAGS = -i"
-
-#Generic ATT System III or System V (no I&D space)
-sys3nid:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System III'
- @echo 'or System V R2 or earlier, no I&D space...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DNOREALPATH -DNOUNICODE -DNOSYSLOG -DNOSYMLINK \
- -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE -DNOLEARN $(KFLAGS) -O" \
- "LNKFLAGS ="
-
-#Generic ATT System III or System V R2 or earlier, "no void":
-#special entry to remove "Illegal pointer combination" warnings.
-sys3nv:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System III'
- @echo 'or System V R2 or earlier...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DATTSV -DNOREALPATH -DNOUNICODE -DNOSYSLOG -DNOGETUSERSHELL \
- -DNOSYMLINK -DNOFTRUNCATE -DNOINITGROUPS -DNOLEARN \
- -Dvoid=int $(KFLAGS) -i -O" \
- "LNKFLAGS = -i"
-
-# AT&T 7300 UNIX PC. As of C-Kermit 6.1, many of these entries don't work
-# any more due to "Out of memory" or "Too many defines" errors during
-# compilation, at least not on systems without lots of memory. The sys3upcgc
-# entry works (using gcc) with optimization removed, and might also work
-# with optimization enabled on machines with larger memories.
-
-#AT&T 7300/UNIX PC (3B1) systems, sys3 but special handling for internal modem.
-#Link with the shared library -- the conflict with openi in shared library
-#is solved with -Dopeni=xopeni. Note that the xermit target can't be used
-#for the Unix PC; there is no select().
-sys3upc:
- @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC, shared lib...'
- @echo 'If shared lib causes trouble, use make sys3upcold.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DATT7300 -DNOMKDIR -DUSE_MEMCPY -DNOREALPATH -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOREDIRECT -DNOGFTIMER -DNOUNICODE $(KFLAGS) -Dopeni=xopeni" \
- "CC2 = ld /lib/crt0s.o /lib/shlib.ifile" "LNKFLAGS = -s"
-
-#AT&T 7300/Unix PC systems, minimum kermit for those with smaller amounts
-#of memory.
-sys3upcm:
- @echo Minimum interactive
- $(MAKE) "MAKE=$(MAKE)" sys3upc KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DNOSPL -DNOFRILLS -DNOHELP -DNODEBUG -DNOTLOG -DNOCSETS \
- -DNOSYSLOG -DNOSETKEY -DNOREALPATH"
-
-#AT&T 7300/UNIX PC (3B1) systems, with curses support.
-#Curses and the shared library don't get along, so we don't use the
-#shared library. We need to include CK_NEWTERM to avoid a conflict
-#with curses and buffering on stdout. Merged with submission by
-#Robert Weiner/Programming Plus, rweiner@watsun.cc.columbia.edu.
-#We don't need -Dopeni=xopeni since we're not using the shared library,
-#but we keep it to be consistent with the other entries.
-sys3upcc:
- @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC, curses...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DATT7300 -DNOREALPATH \
- -DCK_CURSES -DCK_NEWTERM -DNOMKDIR -DNOREDIRECT -DNOGFTIMER -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DUSE_MEMCPY -DNOUNICODE $(KFLAGS) -Dopeni=xopeni" \
- "LIBS = -lcurses" "LNKFLAGS = -s"
-
-#Like sys3upcc but for AT&T UNIX 3.51m (released as a patch on Fix Disk 2),
-#adds hardware flow control.
-att351m:
- $(MAKE) "MAKE=$(MAKE)" sys3upcc KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DCK_RTSCTS -DUNIX351M"
-
-#As above but with gcc.
-att351gm:
- $(MAKE) "MAKE=$(MAKE)" sys3upcgc KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DCK_RTSCTS -DUNIX351M"
-
-#AT&T 7300 UNIX PC (3B1), as above, but no newterm().
-sys3upcx:
- @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC, curses...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DATT7300 -DNOREALPATH -DNOUNICODE -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DCK_CURSES -DNOMKDIR -DNOREDIRECT -DNOGFTIMER -DUSE_MEMCPY $(KFLAGS) \
- -Dopeni=xopeni" "LIBS = -lcurses -ltermcap" "LNKFLAGS = -s"
-
-#AT&T 7300/UNIX PC (3B1) systems, with curses and shared library support.
-sys3upcshcc:
- @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC, shared lib...'
- @echo 'With curses. Requires shcc.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DATT7300 -DNOMKDIR -DNOREALPATH -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DCK_NEWTERM -DCK_CURSES -DNOREDIRECT -DNOGFTIMER \
- -DUSE_MEMCPY -DNOUNICODE $(KFLAGS) -Dopeni=xopeni" \
- "LNKFLAGS = -i -s" "CC = shcc" "CC2 = shcc" "LIBS = -lcurses"
-
-#AT&T 7300/UNIX PC (3B1) systems, as above, no curses, but use gcc.
-sys3upcg:
- @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATT7300 -DNOREDIRECT -DUSE_MEMCPY -DNOUNICODE -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOGFTIMER -DNOMKDIR -DNOREALPATH $(KFLAGS) -Dopeni=xopeni" \
- "CC = gcc" "CC2 = gcc" "LNKFLAGS = -s -shlib"
-
-#AT&T 7300/UNIX PC (3B1) systems, curses and gcc.
-#Optimization omitted -- add it back in if your machine has lots of memory.
-sys3upcgc:
- @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC, curses...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATT7300 -DNOREDIRECT -DUSE_MEMCPY -DNOGFTIMER -DNOUNICODE \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DCK_CURSES -DCK_NEWTERM -DNOMKDIR -DNOREALPATH -DNOLEARN $(KFLAGS)" \
- "CC = gcc" "CC2 = gcc" "LIBS = -lcurses" "LNKFLAGS = -s"
-
-#AT&T 7300/UNIX PC (3B1) systems, special handling for internal modem.
-#No FULLSCREEN file transfer display (curses).
-sys3upcold:
- @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATT7300 -DNOMKDIR -DUSE_MEMCPY -DNOUNICODE -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOGFTIMER -DNOREDIRECT -DNOREALPATH $(KFLAGS) -O" "LNKFLAGS = -i"
-
-#As above, but with gcc. mininum features - fits on a 400K UNIX PC floppy
-#after compression with room to spare; add -DNOSHOW or other -DNOxxxx items
-#to reduce size even further.
-sys3upcgm:
- @echo Minimum interactive
- $(MAKE) "MAKE=$(MAKE)" sys3upcg KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DNOSPL -DNOFRILLS -DNOHELP -DNODEBUG -DNOTLOG -DNOCSETS \
- -DNOSETKEY $(KFLAGS)"
-
-#This target is designed to create a version with the most features possible
-#that, after compression, still fits on a 400K UNIX PC floppy.
-sys3upcgfd:
- @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC floppy...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATT7300 -DNOREDIRECT -DUSE_MEMCPY -DNOSPL -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOGFTIMER -DNOREALPATH -Dopeni=xopeni \
- -DNOHELP -DNODEBUG -DNOTLOG -DNOCSETS -DNOSETKEY -DNOMKDIR $(KFLAGS)" \
- "CC = gcc" "CC2 = gcc" "LNKFLAGS = -s"
-
-#AT&T 6300 PLUS (warning, -O might make it run out of space).
-#NOTE: Remove -DHDBUUCP if not using Honey DanBer UUCP.
-att6300:
- @echo 'Making C-Kermit $(CKVER) for AT&T 6300 PLUS...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATT6300 -DHDBUUCP -DNOFILEH -DNOREALPATH -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOUNICODE $(KFLAGS) -O -Ml -i" "LNKFLAGS = -i -Ml"
-
-#As above, but with curses support. Debugging disabled to prevent thrashing.
-att6300c:
- @echo 'Making C-Kermit $(CKVER) for AT&T 6300 PLUS...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATT6300 -DHDBUUCP -DNOFILEH -DNOCSETS -DNOREALPATH \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DCK_CURSES -DNODEBUG -DNOUNICODE -DNOLEARN $(KFLAGS) -O -Ml -i" \
- "LNKFLAGS = -i -Ml" "LIBS = -lcurses"
-
-#AT&T 6300 PLUS with no curses, no debugging (about 34K smaller)
-# -Optimization saves about 20K too.
-att6300nd:
- @echo 'Making C-Kermit $(CKVER) for AT&T 6300 PLUS, no debugging...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATT6300 -DHDBUUCP -DNODEBUG -DNOFILEH -DNOREALPATH \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOUNICODE -DNOLEARN $(KFLAGS) -O -i -Ml" "LNKFLAGS = -i -Ml"
-
-#AT&T 3B2 and maybe 3B20-series computers running AT&T UNIX System V R3.
-#This one was actually used to build C-Kermit 7.0 successfully on a 3B2/300.
-att3b2:
- @echo 'Making C-Kermit $(CKVER) for AT&T 3B2'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DNOREDIRECT -DUSE_MEMCPY \
- -DNOTIMEVAL -DNOTIMEZONE -DMINIDIAL -DNOCHANNELIO -DNOBIGBUF \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOGFTIMER -DNOREALPATH -Dopeni=xopeni -DNOFRILLS -DNOLEARN \
- -DNOHELP -DNODEBUG -DNOTLOG -DNOCSETS -DNOSETKEY -DNOMKDIR $(KFLAGS)" \
- "CC = gcc" "CC2 = gcc" "LNKFLAGS = -s"
-
-# The next two are likely not to work as-is.
-
-#AT&T 3B2, 3B20-series computers running AT&T UNIX System V.
-#This is just generic System V with Honey DanBer UUCP, so refer to sys3hdb.
-#Remove -DNONAWS if you can get away with it.
-att3bx:
- $(MAKE) "MAKE=$(MAKE)" sys3hdb KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -DNONAWS -DNOTIMEVAL"
-
-# 3Bx with charsets (except Unicode) but no curses.
-att3bx1:
- @echo 'Making C-Kermit $(CKVER) for AT&T 3B2 or 3B20'
- @echo 'with Honey DanBer UUCP no curses...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DHDBUUCP $(KFLAGS) -DNOREDIRECT \
- -DNOTIMEVAL -DNOTIMEZONE -DMINIDIAL -DNOCHANNELIO -DNOBIGBUF \
- -DNOHELP -DNODEBUG -DNOGFTIMER -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOREALPATH -DNOUNICODE -i" \
- "CC = gcc" "CC2 = gcc" "LNKFLAGS = -i -s"
-
-#AT&T 3B2, 3B20-series computers running AT&T UNIX System V,
-#with fullscreen file transfer display.
-att3bxc:
- @echo 'Making C-Kermit $(CKVER) for AT&T 3B2 or 3B20'
- @echo 'with Honey DanBer UUCP and curses...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DHDBUUCP -DNONAWS -DNOTIMEVAL $(KFLAGS) \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOREALPATH -DCK_CURSES -DCK_NEWTERM -DNOUNICODE -DNOLEARN -i -O" \
- "LNKFLAGS = -i" "LIBS=-lcurses"
-
-#3bx with curses but no charsets
-att3bxc3:
- @echo 'Making C-Kermit $(CKVER) for AT&T 3B2 or 3B20'
- @echo 'with Honey DanBer UUCP with curses... no CSETS'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DHDBUUCP $(KFLAGS) -DNOREDIRECT \
- -DNOTIMEVAL -DNOTIMEZONE -DMINIDIAL -DNOCHANNELIO -DNOBIGBUF \
- -DNOHELP -DNODEBUG -DNOGFTIMER -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOREALPATH -DNOCSETS -DCK_CURSES -DCK_NEWTERM -i" \
- "CC = gcc" "CC2 = gcc" "LNKFLAGS = -i -s" "LIBS = -lcurses"
-
-#Any System V R2 or earlier with Honey DanBer UUCP (same as above)
-sys3hdb:
- @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System III'
- @echo 'or System V R2 or earlier with Honey DanBer UUCP...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DHDBUUCP -DNOREALPATH -DNOUNICODE -DNOLEARN \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- $(KFLAGS) -i -O" "LNKFLAGS = -i"
-
-#Sperry/UNISYS 5000 UTS V 5.2 (System V R2), Honey DanBer UUCP
-unisys5r2:
- @echo 'Making C-Kermit $(CKVER) for Sperry/UNISYS 5000 UTS V 5.2...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DUNISYS52 -DHDBUUCP -DNOREALPATH -DNOUNICODE \
- -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \
- -DNOLEARN $(KFLAGS) -i -O" "LNKFLAGS = -i"
-
-#In case they say "make sys5hdb" instead of "make sys3hdb"...
-sys5hdb:
- $(MAKE) "MAKE=$(MAKE)" sys3hdb
-
-#Create the common header line for all hpux[5-11]* entries and above. This
-#extra entry is here because our header message length may differ for each
-#C-Kermit version. Don't use 'fold -s' for HP-UX 5.x - 7.x! This option is
-#available only for HP-UX 8.0 and above!
-hpux-header:
- @HPUX=`uname -r | sed -e 's/^[^1-9]*//' -e 's/\.00$$/.0/'` ; \
- [ "$(MESSAGE0)" ] && MESSAGE1="$(MESSAGE0)" ; \
- Message0='Making C-Kermit $(CKVER) for HP9000 HP-UX' ; \
- Message1=$${MESSAGE1:='without any extra compiler optimization'} ; \
- MessageH="$$Message0 $$HPUX" ; \
- case $$HPUX in \
- [567].*) echo "$$MessageH\n$$Message1" ;; \
- *.*) echo "$$MessageH $${Message1}$(MESSAGE1A)" | fold -s ;; \
- esac | sed -e 's/^ //' -e 's/ *$$//'
-
-# Peter E's updated HP-UX 5.xx entries Oct 2001.
-
-#HP-9000 500 HP-UX 5.xx, no TCP/IP.
-# Last known successful build: C-Kermit 8.0.206 2002/20/27.
-hpux0500:
- @MESSAGE0="no TCP/IP and no compiler optimization";\
- MESSAGE0=$${MESSAGE1:-$$MESSAGE0} \
- $(MAKE) hpux-header
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DHPUX -DHPUX5 -DHPUXPRE65 -DNOREDIRECT -DDCLGETCWD \
- -DNOGETUSERSHELL -DNOGFTIMER -DNOSYSLOG -DNOTOMACROS -DNOLSTAT \
- -DNOSYMLINK -DNOINITGROUPS -DNOUNICODE -DNOLEARN -DNOLONGLONG \
- -DVOID=int -DCKVOID=int $(KFLAGS)" "LIBS = $(LIBS)" "LNKFLAGS = "
-
-#HP-9000 500 HP-UX 5.21 with Wollongong WIN/TCP 1.2 TCP/IP.
-#Requires /usr/wins/usr/include and /usr/lib/libnet.a from Wollongong.
-#Optimization skipped - takes forever. Really.
-# WARNING: this doesn't work if a file called "hpux0500" is on the disk.
-# Last known successful build: C-Kermit 8.0.206 2002/20/27.
-hpux0500wintcp:
- @MESSAGE1="with WIN/TCP but without any extra compiler optimization" \
- $(MAKE) hpux0500 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = -DTCPSOCKET -DHPUX5WINTCP -DINADDRX -DNO_DNS_SRV \
- -DNOMHHOST -DVOID=int -DCKVOID=int -DNOHADDRLIST -DNOLONGLONG \
- -I/usr/wins/usr/include $(KFLAGS)" "LIBS = /usr/lib/libnet.a"
-
-#HP-UX 6.5, short filenames, no network and no curses support.
-#ckcpro, ckuusr, ckuus3 and others are broken out because they make the
-#optimizer run away. Note that the XERMIT target does not work with HP-UX 6.5!
-#
-#If you get compiler warnings like:
-#'Switch table overflow. Try the -Wc,-Nw option.' (for ckcuni.c, or
-#other files) increase the '...' value in '-Wc,-Nw...'! The default maximum
-#switch table stack (-Nw) is 250 table entries. ckcuni.c from Oct 16 2009
-#needs 257 table entries (C-Kermit Version "9.0.299").
-#OK: 2010/03/26
-hpux0650:
- @$(MAKE) hpux-header
- @MESSAGE2=$${MESSAGE2:-'and NO network'}; \
- echo "supporting: NO long filenames $$MESSAGE2."
-
- $(MAKE) KTARGET=$${KTARGET:-$(@)} \
- ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \
- ckuusr.$(EXT) ckuxla.$(EXT) ckcftp.$(EXT) ckcpro.$(EXT) \
- "CFLAGS = -DHPUX -DHPUX6 -DSIG_V -DNOSYSLOG -DNOSELECT -DFNFLOAT \
- -DDCLGETCWD -DNOGETUSERSHELL -DNO_DNS_SRV -DNOLEARN -DNOLONGLONG \
- $(KFLAGS)"
-
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DHPUX -DHPUX6 -DSIG_V -DNOSYSLOG -DNOSELECT -DFNFLOAT \
- -DDCLGETCWD -DNOGETUSERSHELL -DNO_DNS_SRV -DNOLEARN -DNOLONGLONG \
- $(KFLAGS) -Wc,-Nw260 $(OFLAGS)" "LNKFLAGS = -s" "LIBS = -lm $(LIBS)"
-
-#Exactly as above, plus curses:
-#OK: 2009/10/06
-hpux0650c:
- @MESSAGE2="and NO network but with curses" \
- $(MAKE) hpux0650 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = -DCK_CURSES $(KFLAGS)" \
- "LIBS = -lcurses"
-
-#Exactly as above, plus curses + network:
-#OK: 2009/10/02
-hpux0650tcpc:
- @MESSAGE2="but with curses and with TCP/IP" \
- $(MAKE) hpux0650 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DCK_CURSES -DTCPSOCKET -DNOHADDRLIST \
- -DINTSELECT -DNOCKGETFQHOST $(KFLAGS)" \
- "LIBS=-lcurses"
-
-#Exactly as hpux0650 but with compiler optimization:
-#OK: 2009/10/06
-hpux0650o:
- @MESSAGE1="with compiler optimization" \
- $(MAKE) hpux0650 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -O"
-
-#Exactly as hpux0650c but with compiler optimization:
-#OK: 2009/10/06
-hpux0650oc:
- @MESSAGE1="with compiler optimization" \
- $(MAKE) hpux0650c KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -O"
-
-#Exactly as hpux0650tcpc but with compiler optimization:
-#OK: 2009/10/06
-hpux0650otcpc:
- @MESSAGE1="with compiler optimization" \
- $(MAKE) hpux0650tcpc KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -O"
-
-#Take this as startup entry for all 'non-optimized' files under HP-UX 7.x!
-#Make sure we don't call it with the '-O' option because this will blow up
-#the compiler!
-#OK: 2009/09/30
-hpux0700noopt:
- @case "$(CFLAGS)" in \
- *-O*) echo "Don't use CFLAGS= -O here!" ;; \
- *) $(MAKE) KTARGET=$${KTARGET:-$(@)} \
- ckuusr.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \
- ckuus6.$(EXT) ckuus7.$(EXT) ckuxla.$(EXT) \
- ckcuni.$(EXT) ckcftp.$(EXT) ckcpro.$(EXT) \
- ;; \
- esac
-
-#HP-UX 7.0, no long filenames, no network support, no curses.
-#If you get compiler warnings like:
-#'Switch table overflow. Try the -Wc,-Nw option.' (for ckcuni.c, or
-#other files) increase the '...' value in '-Wc,-Nw...'! The default maximum
-#switch table stack (-Nw) is 250 table entries. ckcuni.c from Oct 16 2009
-#needs 257 table entries (C-Kermit Version "9.0.299").
-#OK: 2010/10/26
-hpux0700sf:
- @$(MAKE) hpux-header
- @echo 'supporting: NO long filenames, NO network, NO curses.'
- $(MAKE) hpux0700noopt KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DHPUX -DHPUX7 -DSIG_V -DNOGETUSERSHELL -DFNFLOAT \
- -DNO_DNS_SRV $(KFLAGS) -Wc,-Nw260"
-
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DHPUX -DHPUX7 -DSIG_V -DNOGETUSERSHELL -DFNFLOAT \
- -DNO_DNS_SRV $(KFLAGS) -Wc,-Nw260 $(OFLAGS)" \
- "LNKFLAGS = -s" "LIBS = -lm $(LIBS)"
-
-#Exactly as hpux0700sf but with compiler optimization:
-#OK: 2009/09/30
-hpux0700osf:
- @MESSAGE1="with compiler optimization" \
- $(MAKE) hpux0700sf KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -O"
-
-#HP-UX 7.0, short filenames, but with tcp/ip and curses.
-#To use this, you must have bought the ARPA Services Product from HP, and you
-#must have /usr/lib/libBSD.a.
-#
-#If you get compiler warnings like:
-#'Symbol table overflow. Try the -Wc,-Ns option.' (as for ckuus4.c or
-#other files) increase the '...' value in '-Wc,-Ns...'! The default maximum
-#symbol table size (-Ns) is 2000 table entries. ckuus4.c from Mar 12 2010
-#needs 2031 table entries (C-Kermit Version "9.0.299").
-#OK: 2010/03/24
-hpux0700sftcpc:
- @$(MAKE) hpux-header
- @echo 'supporting: NO long filenames, \c'
- @echo 'but with networking, curses, HDB uucp...'
- $(MAKE) hpux0700noopt KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DHPUXDEBUG -DHPUX -DHPUX7 -DTCPSOCKET -DSIG_V \
- -DCK_REDIR -DCK_RTSCTS -DCK_CURSES -DNOGETUSERSHELL -DFNFLOAT \
- -DNO_DNS_SRV -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" \
- -DNOLONGLONG $(KFLAGS) -Wc,-Nw260,-Ns2040"
-
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DHPUXDEBUG -DHPUX -DHPUX7 -DTCPSOCKET -DSIG_V \
- -DCK_REDIR -DCK_RTSCTS -DCK_CURSES -DNOGETUSERSHELL -DFNFLOAT \
- -DNO_DNS_SRV -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" \
- -DNOLONGLONG $(KFLAGS) -Wc,-Nw260,-Ns2040 $(OFLAGS)" \
- "LNKFLAGS = -s" "LIBS = -lm -lBSD -lcurses"
-
-#Exactly as above but with compiler optimization:
-#OK: 2009/09/30
-hpux0700osftcpc:
- @MESSAGE1="with compiler optimization" \
- $(MAKE) hpux0700sftcpc KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -O"
-
-#HP 9000 series 300/800 HP-UX 7.0, long filenames, network support, HDB uucp,
-#but NO curses. See comments in hpux0700sftcpc about TCP/IP support.
-#
-#If you get compiler warnings like:
-#'Symbol table overflow. Try the -Wc,-Ns option.' (as for ckuus4.c or
-#other files) increase the '...' value in '-Wc,-Ns...'! The default maximum
-#symbol table size (-Ns) is 2000 table entries. ckuus4.c from Mar 12 2010
-#needs 2031 table entries (C-Kermit Version "9.0.299").
-#OK: 2010/03/24
-hpux0700lfn:
- @$(MAKE) hpux-header
- @echo 'supporting: long filenames, networking, HDB uucp$(MESSAGE2)...'
- $(MAKE) hpux0700noopt KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DHPUXDEBUG -DHPUX -DHPUX7 -DTCPSOCKET -DSIG_V -DFNFLOAT \
- -DNOGETUSERSHELL -DNOSETBUF -DCK_REDIR -DCK_RTSCTS -DLONGFN \
- -DNO_DNS_SRV -DDIRENT -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" \
- -DNOLONGLONG $(KFLAGS) -Wc,-Nw260,-Ns2040"
-
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DHPUXDEBUG -DHPUX -DHPUX7 -DTCPSOCKET -DSIG_V -DFNFLOAT \
- -DNOGETUSERSHELL -DNOSETBUF -DCK_REDIR -DCK_RTSCTS -DLONGFN \
- -DNO_DNS_SRV -DDIRENT -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" \
- -DNOLONGLONG $(KFLAGS) -Wc,-Nw260,-Ns2040 $(OFLAGS)" \
- "LNKFLAGS = -s" "LIBS = -lm -lBSD $(LIBS)"
-
-#Exactly as above + curses.
-#OK: 2009/09/30
-hpux0700lfnc:
- @MESSAGE2=', curses' \
- $(MAKE) hpux0700lfn KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = -DCK_CURSES $(KFLAGS)" \
- "LIBS = -lcurses"
-
-#Exactly as above hpux0700lfn but with compiler optimization:
-#OK: 2009/09/30
-hpux0700olfn:
- @MESSAGE1="with compiler optimization" \
- $(MAKE) hpux0700lfn KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -O"
-
-#Exactly as above hpux0700lfnc but with compiler optimization:
-#OK: 2009/09/30
-hpux0700olfnc:
- @MESSAGE1="with compiler optimization" \
- $(MAKE) hpux0700lfnc KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -O"
-
-#HP 9000 Series 300 or 400, HP-UX 8.0, long filenames and TCP/IP support.
-#This one should also work on 700/800, but without PA-specific optimization.
-#In case -DCK_RTSCTS and -DCK_REDIR make trouble, remove them.
-#NOTE: ckcpro.c, ckuusr.c and ckuus3.c blow up the optimizer, so don't optimize
-#them.
-#For HP-UX 8.0 on Motorola CPUs, you might have to reinstall your kernel with
-#maxdsiz >= 0x03000000. But if physical memory is small, that still will not
-#help much.
-#OK: 2009/10/01
-hpux0800:
- @$(MAKE) hpux-header
- @MESSAGE3=$${MESSAGE3:='TCP/IP'}; \
- echo "supporting: long filenames, $$MESSAGE3, HDB UUCP$(MESSAGE2)..."
- $(MAKE) -B "CC=$(CC)" "CC2=$(CC2)" KTARGET=$${KTARGET:-$(@)} \
- ckcpro.$(EXT) ckuusr.$(EXT) ckuus3.$(EXT) \
- "CFLAGS = -DCK_REDIR -DHPUXDEBUG -DHPUX -DHPUX8 -DRENAME -DSIG_V \
- -DNOSETBUF -DDIRENT -DCK_RTSCTS -DSTERMIOX -DLONGFN -DTCPSOCKET \
- -DHDBUUCP -DNO_DNS_SRV -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DFNFLOAT \
- -DNOLONGLONG $(KFLAGS)"
-
- $(MAKE) -B "CC=$(CC)" "CC2=$(CC2)" xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DCK_REDIR -DHPUXDEBUG -DHPUX -DHPUX8 -DRENAME -DSIG_V \
- -DNOSETBUF -DDIRENT -DCK_RTSCTS -DSTERMIOX -DLONGFN -DTCPSOCKET \
- -DHDBUUCP -DNO_DNS_SRV -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DFNFLOAT \
- -DNOLONGLONG -DNODCLENDUSERSHELL $(KFLAGS) $(OFLAGS)" \
- "LNKFLAGS = -s" "LIBS = -lm -lBSD $(LIBS)"
-
-#Exactly as above hpux0800 + curses.
-#OK: 2009/10/01
-hpux0800c:
- @MESSAGE2=', curses' \
- $(MAKE) hpux0800 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS) -DCK_CURSES" "LIBS = -lcurses"
-
-#HP 9000 HP-UX 8.0, no TCP/IP because /usr/lib/libBSD.a can't be found,
-#or TCP/IP header files missing.
-#OK: 2009/10/01
-hpux0800notcp:
- @MESSAGE3='NO network, NO curses' \
- $(MAKE) "MAKE=$(MAKE)" hpux0800 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS) -UTCPSOCKET"
-
-#Now the same as above hpux0800 but with compiler optimization
-#OK: 2009/10/01
-hpux0800o:
- @MESSAGE1="with compiler optimization" \
- $(MAKE) hpux0800 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -O"
-
-#Exactly as above hpux0800 + curses and with compiler optimization.
-#OK: 2009/10/01
-hpux0800oc:
- @MESSAGE1="with compiler optimization" \
- $(MAKE) hpux0800c KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -O" "LIBS = -lcurses"
-
-#Exactly as above hpux0800notcp but with compiler optimization
-#OK: 2009/10/01
-hpux0800onotcp:
- @MESSAGE1="with compiler optimization" \
- $(MAKE) "MAKE=$(MAKE)" hpux0800notcp KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -O"
-
-#HP 9000 Series 700 or 800, HP-UX 8.0, long filenames and TCP/IP support.
-# Like the previous entries, but with PA-RISC-specific optimization.
-#OK: 2009/10/01
-hpux0800pa:
- @MESSAGE1="with PA-RISC-specific optimization" \
- $(MAKE) hpux0800 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS) +Obb1100"
-
-#As above, but with curses.
-#OK: 2009/10/01
-hpux0800pac:
- @MESSAGE1="with PA-RISC-specific optimization" \
- $(MAKE) hpux0800c KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS) +Obb1100"
-
-#As above, but compiled with GCC 2.3.3.
-#OK: 2009/10/01
-hpux0800pagcc:
- @MESSAGE1='using the gcc compiler' \
- $(MAKE) hpux0800 KTARGET=$${KTARGET:-$(@)} \
- "CC=gcc" "CC2=gcc" "KFLAGS = -funsigned-char $(KFLAGS)"
-
-#HP-UX 9.0, 9.01, 9.03, 9.04, 9.05, 9.07, 9.10 ..., + TCP/IP + curses, fully
-#configured. Use this entry with the restricted compiler: no optimization, no
-#ANSI support. If you get unresolved sockets library references at link time,
-#then try adding -lBSD to LIBS, or else remove -DTCPSOCKET to build a version
-#without TCP/IP support.
-#
-#Please note that we have to add the compiler option +DA1.0/+DA1.1 to avoid
-#core-dumps for large arguments in IF MATCH. The man page says these options
-#are default but C-Kermit dumps core without them! Therefore keep them
-#untouched. If you want to overwrite or disable the +DA1.0/+DA1.1 option use
-#'make hpux0900 OFLAGS=...'. An other possibility would be to create a new
-#kernel with maxssiz >= 0x01185000 (default maxssiz=0x00800000).
-#OK: 2009/09/24
-hpux0900:
- @MESSAGE1A='. Read hpux0900 entry comments if you have trouble.' \
- $(MAKE) hpux-header
- @case `uname -m` in \
- */[34]*) KFLAGS='-DNOLONGLONG $(KFLAGS)' ;; \
- */7*) AFLAGS='+DA1.1' ;; \
- */8*) AFLAGS='+DA1.0' ;; \
- esac ; \
- OFLAGS=$${OFLAGS:-$$AFLAGS} ; \
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DHPUXDEBUG -DHPUX9 -DSTERMIOX -DDIRENT -DUTIMEH \
- -DNOSETBUF -DCK_CURSES -DTCPSOCKET -DRENAME -DCK_REDIR -DLONGFN \
- -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DFNFLOAT \
- -DNODCLENDUSERSHELL $$KFLAGS $$OFLAGS" \
- "LNKFLAGS = -s" "LIBS = -lm -lcurses" "CC=$(CC)" "CC2=$(CC2)"
-
-#Like hpux0900, but for the "value-added" compiler on all HP 9000 models.
-#Adds optimization and ANSI compilation:
-# +O2 makes smaller executable (= -O = Level-1 and global optimization)
-# +O3 adds interprocedural global optimization, makes bigger executable.
-# Please note: To support long-long we would need compiler switch '-Ae' but
-# this one works only on Risc systems. But the equivalant compiler flags
-# '-Aa -D_HPUX_SOURCE +e' works for Motorola and Risc.
-# If optimization fails on some modules, you can add:
-# +Obb<n>, +Olimit <n>, or +Onolimit, depending on your cc version,
-# where <n> is a number, e.g. +Obb1200. In other words, if you get optimizer
-# warnings, add (for example) +Obb1200; if you still get optimizer warnings,
-# increase the number. Repeat until warnings go away. If your compiler
-# permits it, use +Onolimit. If optimizer blows up on ckcpro.c, see next entry.
-# Reportedly, on some configurations, such as HP9000/425e or /340, perhaps
-# depending on the amount of main memory, this entry might fail no matter what
-# you do ("Out of Memory", "cc: Fatal error in /lib/c.c1", etc). In that case
-# use "make hpux0900" (no "o").
-#OK: 2009/09/24
-hpux0900o:
- @MESSAGE1=$${MESSAGE1:-"with compiler optimization"} \
- $(MAKE) hpux0900 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS) -Aa -DCK_ANSIC -D_HPUX_SOURCE +O2 +e"
-
-# For HP-UX 9.0 on Motorola CPUs, optimization of ckcpro.c tends to blow up
-# the compiler. You might have to reinstall your kernel with maxdsiz >=
-# 0x03000000. But if physical memory is small, that still will not help much.
-# In that case, use this entry to skip optimization of ckcpro.c. But for
-# C-Kermit 8.0.208 you need a kernel with maxdsiz >= 0x02000000 to compile an
-# optimized ckcftp.c.
-# Please note: To support long-long we would need compiler switch '-Ae' but
-# this one works only on Risc systems. But the equivalant compiler flags
-# '-Aa -D_HPUX_SOURCE +e' works for Motorola and Risc.
-hpux0900m68ko:
- @MESSAGE1='without compiler optimization for ckcpro.$(EXT) ...' \
- $(MAKE) hpux-header
- $(MAKE) ckuusr.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) \
- ckcftp.$(EXT) ckcpro.$(EXT) \
- "CFLAGS = -DHPUXDEBUG -DHPUX9 -DSTERMIOX -DDIRENT \
- -DNOSETBUF -DCK_CURSES -DTCPSOCKET -DRENAME -DCK_REDIR -DLONGFN \
- -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DFNFLOAT $(KFLAGS)"
- @echo
- @MESSAGE1="with compiler optimization for the rest" \
- $(MAKE) hpux0900 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS) -Aa -DCK_ANSIC -D_HPUX_SOURCE +O2 +e"
-
-# Old name for hpux0900m68ko.
-hpux0900mot:
- $(MAKE) hpux0900m68ko KTARGET=$${KTARGET:-$(@)} "KFLAGS = $(KFLAGS)"
-
-#Like hpux0900o but with additional model-700/800-specific optimizations.
-# +ESlit = consolidate strings in read-only memory.
-# +ESfsc = inline millicode calls when comparing pointers.
-hpux0900o700:
- @echo 'If you get optimizer warnings \c'
- @echo 'try "make hpux0900o700 KFLAGS=+Obb1200"'
- @MESSAGE1="with PA-RISC-specific optimizations" \
- $(MAKE) hpux0900o KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS) +ESlit +ESsfc"
-
-#HP-UX 9.0, 9.01, 9.03, 9.04, 9.05, 9.07, 9.10 ..., + TCP/IP + curses, fully
-#configured, built with gcc, all models except 800 series.
-#You might need to add the include path for gcc headers, for example:
-# 'KFLAGS=-I/usr/gnu/lib/gcc-lib/hppa1.1-hp-hpux/2.4.5/include/'
-hpux0900gcc:
- @MESSAGE1='using the gcc compiler' \
- $(MAKE) hpux0900 KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "KFLAGS = -DCK_ANSIC $(KFLAGS)" \
- "OFLAGS = -funsigned-char -O2 $(OFLAGS)"
-
-#HP-9000 HP-UX 10.0 + TCP/IP + curses, fully configured.
-#Use with restricted (bundled) compiler: no optimization, no ANSI support.
-#libcurses needed for fullscreen file xfer display in HP-UX 10.00 and 10.01.
-#libHcurses (NOT libcurses!) for fullscreen display, to work around fatal bugs
-#in HP-UX 10.10 and 10.20 curses. Maybe we could use lcurses for 10.30, since
-#the 10.10 curses problem is supposedly fixed in 10.30.
-# +DA1.0 = Generate PA-RISC 1.0 code that runs on both 700 and 800 models.
-# +DA1.1 = Generate PA-RISC 1.1 code that runs on both 700 and 800 models.
-# Note that HP-UX 10.20 and upwards do not support PA-RISC 1.0 systems.
-# And that as of Dec 2001, 11.00 and 11.11 are PA-only and 11.20 is IA64-only.
-# Later 11.2x releases are expected to be for both. Architecture can be
-# determined with the model command, at least in 10.20 and later...
-#For future releases, we need to include +DA1.1 for PA builds, so that a
-#binary built on PA 2.0 will still work on PA 1.1 machines, whereas +DA1.1
-#must NOT be included for IA64 builds.
-#4 Jan 2006 - Added Large File Support (LFS). Large files (>2GB) are
-#possible in HP-UX 10.20 and later. The only change is to add:
-# -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-#to KFLAGS. These should be harmless in 10.00 and 10.10, if any of examples
-#of those still exist, but I have no way to test this hypothesis.
-#OK: 2009/11/16
-hpux1000:
- @$(MAKE) hpux-header
- @LIBS='-lHcurses' ; \
- AFLAGS='+DA1.1' ; \
- case `uname -r` in \
- [AB].10.0*) KFLAGS='-DHPUX1000 $(KFLAGS)' ; \
- AFLAGS='+DA1.0' ; LIBS='-lcurses' ;; \
- [AB].10.1*) KFLAGS='-DHPUX1010 -D__HP_CURSES $(KFLAGS)' ; \
- ;; \
- [AB].10.2*) KFLAGS='-DHPUX1020 -D__HP_CURSES $(KFLAGS)' ; \
- ;; \
- [AB].10.3*) KFLAGS='-DHPUX1030 -D__HP_CURSES $(KFLAGS)' ; \
- ;; \
- [AB].10.?*) KFLAGS='-DHPUX10XX -D__HP_CURSES $(KFLAGS)' ; \
- ;; \
- [AB].11.0*) KFLAGS='-DHPUX1100 -D__HP_CURSES $(KFLAGS)' ; \
- ;; \
- [AB].11.1*) KFLAGS='-DHPUX1100 -D__HP_CURSES $(KFLAGS)' ; \
- ;; \
- [AB].11.?*) KFLAGS='-DHPUX1100 -D__HP_CURSES $(KFLAGS)' ; \
- AFLAGS='' ; LIBS='-lcurses' ;; \
- esac ; \
- OFLAGS=$${OFLAGS:-$$AFLAGS} ; \
- $(MAKE) "SHELL=/usr/bin/sh" xermit KTARGET=$${KTARGET:-$(@)} \
- "CC=$(CC)" "CC2=$(CC2)" \
- "CFLAGS = -DHPUX10 -DDIRENT -DSTERMIOX -DCK_DSYSINI -DHDBUUCP \
- -DCK_CURSES -DCK_WREFRESH -DTCPSOCKET -DCK_REDIR -DRENAME -DFNFLOAT \
- -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
- $$KFLAGS $$OFLAGS" \
- "LNKFLAGS=-s $(LNKFLAGS)" "LIBS = -lm $$LIBS $(KLIBS)"
-
-# This is a kludge, copying hpux0900gcc and adapting hpux1000
-# (add CC and CC2, drop the A1.[0||1])
-# Builds w/ no compiler warnings but minimally tested.
-#
-#OK: 2009/09/21
-hpux1000gcc:
- @MESSAGE1="using the gcc compiler $(MESSAGE1)" \
- $(MAKE) hpux1000 KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \
- "KFLAGS = $(KFLAGS)" "OFLAGS = -DCK_ANSIC -funsigned-char -O2"
-
-# Trusted HP-UX 10
-# echo KFLAGS=$(KFLAGS) YTARGET YTARGET=$(YTARGET) $(XTARGET) ;
-hpux1000t:
- @case "$(KTARGET)" in \
- *+openssl | *+ssl) \
- KENTRY=hpux1000o+openssl ;; \
- *gcc) \
- KENTRY=hpux1000gcc ;; \
- *o+) KENTRY=hpux1000o+ ;; \
- *o) KENTRY=hpux1000o ;; \
- *) KENTRY=hpux1000 ;; \
- esac ; \
- MESSAGE1="and support for 'Trusted HP-UX'" \
- $(MAKE) $$KENTRY KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS = $(KFLAGS) -DHPUX10_TRUSTED" "KLIBS=-lsec"
-
-hpux1000to:
- $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)}
-
-hpux1000to+:
- $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)}
-
-hpux1000tgcc:
- $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)}
-
-hpux1000to+ssl hpux1000to+openssl:
- $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)}
-
-hpux1000tgcc+ssl hpux1000tgcc+openssl:
- $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)}
-
-#HP-9000 HP-UX 10.00 and higher with ANSI prototyping and optimization.
-#PA-RISC only, no Motorola or other hardware is support in HP-UX 10.00++.
-#The unbundled optional compiler is required.
-#Your path should start with /opt/ansic/bin.
-# -Wl,-Fw = Remove stack unwind table (info used by debuggers).
-# +O2 makes a smaller executable (= -O = Level-1 and global optimization).
-# +O3 adds interprocedural global optimization, makes a bigger executable.
-# +Onolimit allows all modules to be optimized, no matter how complex. But:
-# (a) +Onolimit does not seem to always be there in HP-UX 10.00, and:
-# (b) some modules might take hours on low-memory and/or slow systems.
-# The following are PA-RISC-specific optimizations:
-# +ESlit = Consolidate strings in read-only memory.
-# +ESfsc = Inline millicode calls when comparing pointers.
-# You might need to configure your kernel for a maxdsiz of 0x0B000000 (176MB)
-# or greater to prevent the optimizer from running out of space.
-# December 2001: +ESlit +ESsfc removed because not supported on IA64.
-# Somebody who cares can use 'model' to see whether it's PA-RISC or IA64
-# and include the architecture-specific optimization flags. Also note:
-# +DA1.1 is PA-only. If this is included in in HP-UX 11.00 or later,
-# then +DS2.0 should be included too (but don't use +DS2.0 without +DA1.1,
-# or else the binary won't run on older PA hardware).
-#OK: 2009/09/21
-hpux1000o:
- @case `uname -m` in \
- ia64) ;; \
- *) MFLAGS='+ESlit +ESsfc' ;; \
- esac ; \
- MESSAGE1="with PA-RISC-specific optimizations $(MESSAGE1)" \
- $(MAKE) "SHELL=/usr/bin/sh" "PATH=/opt/ansic/bin:$$PATH" hpux1000 \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = $(KFLAGS) \
- -Ae -D_HPUX_SOURCE -DCK_ANSIC -DUTIMEH \
- +O2 -Wl,-Fw $$MFLAGS"
-
-#Like hpux1000o but with "+Onolimit".
-#On 700 series set kernel parameter maxdsiz >= 0x0D000000 (=208MB).
-#Takes a long time.
-hpux1000o+:
- @MESSAGE1="and +Onolimit $(MESSAGE1)" KTARGET=$${KTARGET:-$(@)} \
- $(MAKE) hpux1000o \
- "KFLAGS = $(KFLAGS) +Onolimit"
-
-#HP-UX 10.xx + 11.xx with optimizing ANSI compiler and OpenSSL.
-#Define SSLLIB and SSLINC appropriately for your OpenSSL installation.
-#To overwrite the default SSLLIB and SSLINC settings you can also use the
-#command-line variable KSSLLIB and KSSLINC like:
-#make hpux1000o+openssl KSSLLIB=-L/opt/openssl/lib KSSLINC=-I/...
-#Ditto for the Zlib location.
-#This entry works for C-Kermit 8.0.206 on HP-UX 10.20 + 11.11
-#with OpenSSL 0.9.6 + 0.9.7
-#NOTE: an ANSI C compiler is required for the SSL interface. If you don't
-#have the HP Optimizing ANSI compiler, see the hpux1000gcc+openssl target
-#below.
-hpux1000o+ssl hpux1000o+openssl:
- @case "$(KTARGET)" in \
- *gcc+*) \
- KENTRY=hpux1000gcc ;; \
- *) KENTRY=hpux1000o ;; \
- esac ; \
- case "$(KTARGET)" in \
- *-zlib*) \
- DZLIB= LZLIB= ;; \
- *) DZLIB=-DZLIB LZLIB='-L/opt/zlib/lib -lz' ;; \
- esac ; \
- SSLINC=$${KSSLINC:-$(SSLINC)}; \
- SSLLIB=$${KSSLLIB:-$(SSLLIB)}; \
- MESSAGE1="and with OpenSSL $(MESSAGE1)" \
- $(MAKE) $$KENTRY KTARGET=$${KTARGET:-$(@)} \
- KFLAGS="-DCK_AUTHENTICATION -DCK_SSL -DOPENSSL_097 $$DZLIB \
- $$SSLINC $(KFLAGS)" \
- KLIBS="$(KLIBS) \
- $$SSLLIB -lssl -lcrypto \
- $$LZLIB \
- "
-
-# Ditto but without Zlib:
-hpux1000o+ssl-zlib hpux1000o+openssl-zlib:
- @MESSAGE1="but without Zlib $(MESSAGE1)" \
- $(MAKE) hpux1000o+ssl KTARGET=$${KTARGET:-$(@)}
-
-#HP-UX 10.00 or higher with OpenSSL 0.9.7. Compiled with gcc.
-#From Chris Chaney, NEC America Inc. His instructions:
-# (1) Install gcc version 3.2.3 & binutils version 2.13.2
-# (used binary depot from http://hpux.cs.utah.edu/)
-# (2) Install gcc make version 3.80 from http://hpux.cs.utah.edu/
-#
-# or: gcc 2.9.2000-12-1 from "Linux to hp-ux 11.0/11i porting kit version 1.0
-# (2CD)" free from: http://www.software.hp.com
-#
-# (3) Install openSSL version 0.9.7b from http://www.software.hp.com
-# (4) Install flex version 2.5.4 from http://hpux.cs.utah.edu/
-# (5) Install gmp version 3.1.1 from http://hpux.cs.utah.edu/
-#
-#Note from Peter Eichhorn, assyst Munich. It works also without gcc make!
-hpux1000gcc+ssl hpux1000gcc+openssl:
- $(MAKE) hpux1000o+openssl KTARGET=$${KTARGET:-$(@)}
-
-# Ditto but without Zlib:
-hpux1000gcc+ssl-zlib hpux1000gcc+openssl-zlib:
- $(MAKE) hpux1000o+openssl-zlib KTARGET=$${KTARGET:-$(@)}
-
-# Same for HP-UX 11
-hpux1100o+ssl hpux1100o+openssl:
- $(MAKE) hpux1000o+openssl KTARGET=$${KTARGET:-$(@)}
-
-#OK: 2009/09/26
-hpux1100gcc+ssl hpux1100gcc+openssl:
- $(MAKE) hpux1000gcc+openssl KTARGET=$${KTARGET:-$(@)}
-
-hpux1100o+ssl-zlib hpux1100o+openssl-zlib:
- $(MAKE) hpux1000o+openssl-zlib KTARGET=$${KTARGET:-$(@)}
-
-hpux1100gcc+ssl-zlib hpux1100gcc+openssl-zlib:
- $(MAKE) hpux1000gcc+openssl-zlib KTARGET=$${KTARGET:-$(@)}
-
-# HP-UX 11
-# Note: these are 32-bit builds even on IA64.
-# Adding +DD64 to CFLAGS produces 64-bit object files,
-# but the linker fails to find the needed 64-bit libs.
-#OK: 2009/09/26
-hpux1100:
- $(MAKE) hpux1000 KTARGET=$${KTARGET:-$(@)}
-
-#OK: 2009/09/26
-hpux1100o:
- $(MAKE) hpux1000o KTARGET=$${KTARGET:-$(@)}
-
-hpux1100o+:
- $(MAKE) hpux1000o+ KTARGET=$${KTARGET:-$(@)}
-
-#OK: 2009/09/26
-hpux1100gcc:
- $(MAKE) hpux1000gcc KTARGET=$${KTARGET:-$(@)}
-
-# Trusted HP-UX 11
-hpux1100t:
- $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)}
-
-hpux1100to:
- $(MAKE) hpux1000to KTARGET=$${KTARGET:-$(@)}
-
-hpux1100to+:
- $(MAKE) hpux1000to+ KTARGET=$${KTARGET:-$(@)}
-
-hpux1100tgcc:
- $(MAKE) hpux1000tgcc KTARGET=$${KTARGET:-$(@)}
-
-hpux1100to+ssl hpux1100to+openssl:
- $(MAKE) hpux1000to+openssl KTARGET=$${KTARGET:-$(@)}
-
-hpux1100tgcc+ssl hpux1100tgcc+openssl:
- $(MAKE) hpux1000tgcc+openssl KTARGET=$${KTARGET:-$(@)}
-
-#Regulus on CIE Systems 680/20
-cie:
- @echo 'Making C-Kermit $(CKVER) for CIE Systems 680/20 Regulus...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DATTSV -DNOFILEH -DCIE -DNOLEARN $(KFLAGS) -O" "LNKFLAGS ="
-
-# Linux 1.2 or later with gcc, dynamic libraries, ncurses, TCP/IP.
-#
-# If your Linux system has curses rather than ncurses, use the linuxc
-# entry, or if that doesn't work, linuxnc.
-#
-# The Kermit "large memory model" is used by default to configure big packet
-# and script buffers, etc. For small-memory or limited-resource systems,
-# "make linux KFLAGS=-DNOBIGBUF".
-#
-# -DLINUXFSSTND (Linux File System Standard 1.2) gives UUCP lockfile /var/lock
-# with string pid. Remove this to get /usr/spool/uucp with int pid, used in
-# very early Linux versions. FSSTND 1.2 also says that the PID string in the
-# UUCP lock file has leading spaces. This is a change from FSSTND 1.0, which
-# used leading zeros. Add -DFSSTND10 to support FSSTND 1.0 instead of 1.2.
-# I hope subsequent editions of the file-system standard did not change these
-# again.
-#
-# Add -DOLINUXHISPEED (Old Linux High Speed support) to turn on an ugly kludge
-# in Linux 1.0 and earlier to support speeds of 57600 and 115200. Extremely
-# old Linux systems (pre-0.99pl15) will not support this. If OLINUXHISPEED is
-# not defined, then only the standard POSIX termios methods of setting the port
-# speed will be used, and in this case speeds can be as high as 460800 in most
-# modern Linux versions.
-#
-# -DCK_POSIX_SIG (POSIX signal handling) is good for Linux releases back to at
-# least 0.99.14; if it causes trouble for you, remove it from the CFLAGS.
-#
-# -pipe removes the need for temp files - remove it if it causes trouble.
-#
-# -funsigned-char makes all characters unsigned, as they should have been
-# in the first place.
-#
-# Add -DCK_DSYSINI if you want a shared system-wide init file.
-#
-# See http://www.columbia.edu/kermit/ckubwr.html about -DNOCOTFMC.
-# Better still, should read the entire Linux section of that document.
-#
-# The "linuxa" entry can be referenced directly on LIBC systems, but not
-# GLIBC, where -lcrypt is required. The "make linux" entry should normally
-# be used for all builds on all Linux distributions unless you have special
-# requirements, in which case keep reading. CK_NEWTERM added after 7.0b04
-# due to new complaints about ncurses changing buffering of tty.
-
-linuxa:
- @echo 'Making C-Kermit $(CKVER) for Linux 1.2 or later...'
- @echo 'IMPORTANT: Read the comments in the linux section of the'
- @echo 'makefile if you have trouble.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -DLINUX -pipe -funsigned-char -DFNFLOAT -DCK_POSIX_SIG \
- -DCK_NEWTERM -DTCPSOCKET -DLINUXFSSTND -DNOCOTFMC -DPOSIX \
- -DUSE_STRERROR $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(LIBS) -lm"
-
-# As above but with profiling
-linuxp:
- $(MAKE) linuxa KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS) -pg" \
- "LIBS=-pg -lcrypt -lresolv"
-
-#Linux. This entry should work for any Linux distribution on any platform,
-#32-bit or 64-bit, except for extremely ancient ones. Automatically detects:
-# . curses, ncurses, or no curses
-# . Old versus new pty handling (new == glibc 2.1++)
-# . Presence or absence of libcrypt.a and <crypt.h>
-# . Presence or absence of libresolv.a
-# . Transitional Long File API for 32-bit platforms (SUS V2 UNIX 98 LFS).
-#Note: The HAVE_PTMX test was previously "if test -c /dev/ptmx" but this was
-#not sufficient for Debian 2.1, because although it had /dev/ptmx, it did not
-#have grantpt(), unlockpt(), or ptsname(), so has been changed to look for a
-#grantpt() prototype in the header files. Modified in 8.0.206 to allow for
-#libraries that contain .so's but no .a's, e.g. Mandrake 9.0.
-#HAVE_BAUDBOY added in 8.0.210 for Red Hat -- it's like AIX ttylock().
-#Modified 17 Aug 2005 to use openpty() if available because the other stuff
-#dumps core in 64-bit ia64 and x86_64 builds.
-#Long file support for 32-bit builds added in 8.0.212 - if features.h contains
-#__USE_LARGEFILE64 then we set the flags that must be set before reading any
-#header files; on 32-bit platforms such as i386, this produces a 32-bit build
-#capable of accessing, sending, receiving, and managing long (> 2GB) files.
-#On 64-bit platforms, it does no harm.
-#As of 3 March 2009 we detect automatically if we have curses, ncurses,
-#or no curses at all.
-#Added HAVE_LOCKDEV as openSuSE >= 11.3 uses ttylock directly instead of
-#baudboy 2010/08/23
-#OK: 2011/06/18
-linux:
- @if test \
- `grep grantpt /usr/include/*.h /usr/include/sys/*.h | wc -l` -gt 0; \
- then if test -c /dev/ptmx; then HAVE_PTMX='-DHAVE_PTMX'; \
- else HAVE_PTMX=''; fi; fi ; \
- if test `grep openpty /usr/include/pty.h | wc -l` -gt 0; \
- then HAVE_OPENPTY='-DHAVE_OPENPTY'; \
- else HAVE_OPENPTY=''; fi ; \
- HAVE_LIBCURSES=''; \
- if test -f /usr/lib64/libncurses.so || \
- test -f /usr/lib/libncurses.a || \
- test -f /usr/lib/libncurses.so; then \
- HAVE_LIBCURSES='-lncurses'; \
- else if test -f /usr/lib64/libcurses.so || \
- test -f /usr/lib/libcurses.a || \
- test -f /usr/lib/libcurses.so; then \
- HAVE_LIBCURSES='-lcurses'; fi; fi; \
- HAVE_CURSES=''; \
- if test -n '$$HAVE_LIBCURSES'; then \
- if test -f /usr/include/ncurses.h; then \
- HAVE_CURSES='-DCK_NCURSES -I/usr/include/ncurses'; \
- else if test -f /usr/include/curses.h; then \
- HAVE_CURSES='-DCK_CURSES'; \
- fi; fi; fi; \
- if test -f /usr/include/baudboy.h || test -f /usr/include/ttylock.h; \
- then HAVE_LOCKDEV='-DHAVE_LOCKDEV' ; \
- else HAVE_LOCKDEV='' ; fi ; \
- if test -f /usr/include/baudboy.h ; \
- then HAVE_BAUDBOY='-DHAVE_BAUDBOY' ; \
- else HAVE_BAUDBOY='' ; fi ; \
- $(MAKE) KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$$HAVE_CURSES $$HAVE_PTMX $$HAVE_LOCKDEV \
- $$HAVE_BAUDBOY $$HAVE_OPENPTY \
- `grep __USE_LARGEFILE64 /usr/include/features.h > /dev/null && \
- echo '-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'` \
- `if test -f /usr/include/crypt.h; then echo -DHAVE_CRYPT_H; fi` \
- $(KFLAGS)" \
- "LIBS=$(LIBS) $$HAVE_LIBCURSES \
- `if test -n '$$HAVE_OPENPTY'; then echo -lutil; fi` \
- `if test -f /usr/lib64/libresolv.a || test -f /usr/lib64/libresolv.so \
- || test -f /usr/lib/libresolv.a || test -f /usr/lib/libresolv.so \
- || test -f /usr/lib/i386-linux-gnu/libresolv.a \
- || test -f /usr/lib/i386-linux-gnu/libresolv.so \
- || ls /lib/x86_64-linux-gnu/libresolv.* > /dev/null 2> /dev/null; \
- then echo -lresolv; fi` \
- `if test -f /usr/lib64/libcrypt.a || test -f /usr/lib64/libcrypt.so \
- || test -f /usr/lib/libcrypt.a || test -f /usr/lib/libcrypt.so \
- || ls /lib/x86_64-linux-gnu/libcrypt.* > /dev/null 2> /dev/null; \
- then echo -lcrypt; fi` \
- `if test -f /usr/lib64/liblockdev.a || \
- test -f /usr/lib64/liblockdev.so || \
- test -f /usr/lib/liblockdev.a || \
- test -f /usr/lib/liblockdev.so; \
- then echo -llockdev; fi`" \
- linuxa
-
-# Linux + Shadow passwords + PAM
-# OK 2011/06/18
-linux+shadow+pam:
- @echo 'Making C-Kermit $(CKVER) for Linux+Shadow+PAM...'
- $(MAKE) linux KTARGET=$${KTARGET:-$(@)} \
- KFLAGS="-DCK_SHADOW -DCK_PAM $(KFLAGS)" \
- "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = -lpam"
-
-# Linux systems that have no <sys/select.h>.
-# (not tested in recent years, perhaps no longer needed)
-linuxns:
- $(MAKE) linux KTARGET=$${KTARGET:-$(@)} KFLAGS=-DNO_SYS_SELECT_H
-
-# Linux-script-only:
-# A minimum-size version for Linux that does only scripting and
-# serial communication -- no networks, no file transfer, no security.
-# OK 2011/06/18
-linuxso:
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -DLINUX -pipe -funsigned-char -DPOSIX -DCK_POSIX_SIG \
- -DLINUXFSSTND -DNOCOTFMC -DNOXFER -DNODEBUG -DNOCSETS -DNOHELP \
- -DNONET -DMINIDIAL -DNOSCRIPT -DNOIKSD -DNOPUSH $(KFLAGS)" \
- "LNKFLAGS = $(LNKFLAGS)" "LIBS = "
-
-# Secure targets for Linux. These work on RHAS4, RHEL4, and RHEL5,
-# unlike some of the older targets that follow. They hook into the main Linux
-# target so we pick up all the other new stuff - large files, baudboy.h, the
-# appropriate pty interface, etc.
-
-# Linux with Kerberos 5.
-# Use "make linux+krb5 KFLAGS=-DNO_KRB5_INIT_ETS" if necessary.
-#OK 2011/06/16 on Fedora 14 with:
-# make linux+krb5 "LIBS=$LIBS /lib/libk5crypto.so.3 /lib/libcom_err.so.2"
-# On RHEL5: make linux+krb5 -UCK_DES
-linux+krb5:
- @echo 'Making C-Kermit $(CKVER) for Linux with Kerberos 5...'
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac; \
- HAVE_DES=''; \
- DES_LIB=''; \
- if ls /usr/lib/libdes* > /dev/null 2> /dev/null || \
- ls $(SSLLIB)/libdes* > /dev/null 2> /dev/null; then \
- DES_LIB='-ldes425'; \
- HAVE_DES='-DCK_DES -DLIBDES'; \
- echo "HAVE DES"; \
- else echo "NO DES"; \
- fi; \
- K5CRYPTO=''; \
- if ls /lib/libk5crypto* > /dev/null 2> /dev/null; then \
- K5CRYPTO='-lk5crypto'; \
- else if ls /usr/lib/libk5crypto* > /dev/null 2> /dev/null; then \
- K5CRYPTO='-lk5crypto'; \
- else if ls /usr/lib64/libk5crypto* > /dev/null 2> /dev/null; then \
- K5CRYPTO='-lk5crypto'; \
- fi; fi; fi; \
- COM_ERR=''; \
- if ls /lib/libcom_err* > /dev/null 2> /dev/null; then \
- COM_ERR='-lcom_err'; \
- fi; \
- GSSAPILIB='-lgssapi'; \
- if ls /lib/libgssapi_krb5* > /dev/null 2> /dev/null; then \
- GSSAPILIB='-lgssapi_krb5'; \
- else if ls /usr/lib/libgssapi_krb5* > /dev/null 2> /dev/null; then \
- GSSAPILIB='-lgssapi_krb5'; \
- else K5DIR=`echo $(K5LIB) | sed 's|-L||'`; \
- if ls $$K5DIR/libgssapi_krb5* > /dev/null 2> /dev/null; then \
- GSSAPILIB='-lgssapi_krb5'; \
- fi; fi; fi; \
- $(MAKE) linux KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "KFLAGS= -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 $$OPENSSLOPTION \
- -DCK_ENCRYPTION $$HAVE_DES $(K5INC) $(K5INC)/krb5 \
- -I/usr/include/et $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) $$DES_LIB -lcrypto $$GSSAPILIB -lkrb5 \
- $$K5CRYPTO $$COM_ERR $(LIBS)" ; \
- if [ ! -f ./wermit ] || [ ./ckcmai.o -nt ./wermit ] ; then \
- echo ""; \
- echo "If build failed try:"; \
- echo ""; \
- echo " make clean ; make $${KTARGET:-$(@)} KFLAGS=-UCK_DES"; \
- echo ""; \
- fi
-
-# Linux with Kerberos 5 and Kerberos 4.
-# Use "make linux+krb5 KFLAGS=-DNO_KRB5_INIT_ETS" if necessary.
-# Add "KFLAGS=-UCK_DES" if failure messages look DES-related.
-# UNTESTED (because I can't find a box with Krb4 and Krb5 installed)
-linux+krb5+krb4:
- @echo 'Making C-Kermit for Linux with Kerberos 4 and Kerberos 5'
- $(MAKE) linux+krb5 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DKRB4 -DKRB524 $(KFLAGS)" "LIBS=$(LIBS) -lkrb4"
-
-# Linux with OpenSSL
-# In Linux, SSL libs are often in /lib or /usr/lib and so found by default.
-# This targets takes into account the DES library might or might not
-# exist. If it does exist, however, the target will require some editing
-# if its basename is not libdes425. - fdc Tue Sep 21 14:28:00 2010
-# IMPORTANT: Some Linux platforms have DES libraries but they are missing
-# functions used by Kermit. In that case you will get fatal errors at
-# link time involving routines such as des_ecb3_encrypt, des_random_seed,
-# and des_set_odd_parity. In that case, "make linux KFLAGS=-UCK_DES"
-# There's a new warning at the end that should come out if this happens,
-# and that should not come out if it didn't.
-#
-linux+ssl linux+openssl linux+openssl+zlib+shadow+pam linux+openssl+shadow:
- @echo 'Making C-Kermit $(CKVER) for Linux+OpenSSL SSLLIB=$(SSLLIB)'
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac; \
- HAVE_DES=''; \
- DES_LIB=''; \
- if ls /usr/lib/libdes* > /dev/null 2> /dev/null || \
- ls $(SSLLIB)/libdes* > /dev/null 2> /dev/null; then \
- DES_LIB='-ldes425'; \
- HAVE_DES='-DCK_DES -DLIBDES'; \
- echo "HAVE DES"; \
- else echo "NO DES"; \
- fi; \
- $(MAKE) linux KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "KFLAGS= -DCK_AUTHENTICATION -DCK_ENCRYPTION -DCK_CAST $$HAVE_DES \
- -DCK_SSL -DCK_PAM -DZLIB -DCK_SHADOW $$OPENSSLOPTION $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SSLLIB) -lssl $$DES_LIB -lcrypto -lpam -ldl -lz $(LIBS)" ; \
- if [ ! -f ./wermit ] || [ ./ckcmai.o -nt ./wermit ] ; then \
- echo ""; \
- echo "If build failed try:"; \
- echo ""; \
- echo " make clean ; make $${KTARGET:-$(@)} KFLAGS=-UCK_DES"; \
- echo ""; \
- fi
-
-# Linux with Kerberos 5 and OpenSSL
-# OK 2011/05/16
-# Add -UCK_DES if functions like des_ecb3_encrypt, es_random_seed,
-# come up missing at link time.
-linux+krb5+ssl linux+krb5+openssl:
- @echo 'Making C-Kermit $(CKVER) for Linux with Krb5 and OpenSSL...'
- @case `openssl version` in \
- *0.9.7*) OPENSSLOPTION="-DOPENSSL_097" ;; \
- *0.9.8*) OPENSSLOPTION="-DOPENSSL_098" ;; \
- *1.[0-9].[0-9]*) OPENSSLOPTION="-DOPENSSL_100" ;; \
- *) OPENSSLOPTION="" ;; \
- esac; \
- HAVE_DES=''; \
- DES_LIB=''; \
- if ls /usr/lib/libdes* > /dev/null 2> /dev/null || \
- ls $(SSLLIB)/libdes* > /dev/null 2> /dev/null; then \
- DES_LIB='-ldes425'; \
- HAVE_DES='-DCK_DES -DLIBDES'; \
- echo "HAVE DES"; \
- else echo "NO DES"; \
- fi; \
- K5CRYPTO=''; \
- if ls /lib/libk5crypto* > /dev/null 2> /dev/null; then \
- K5CRYPTO='-lk5crypto'; \
- else if ls /usr/lib/libk5crypto* > /dev/null 2> /dev/null; then \
- K5CRYPTO='-lk5crypto'; \
- else if ls /usr/lib64/libk5crypto* > /dev/null 2> /dev/null; then \
- K5CRYPTO='-lk5crypto'; \
- fi; fi; fi; \
- COM_ERR=''; \
- if ls /lib/libcom_err* > /dev/null 2> /dev/null; then \
- COM_ERR='-lcom_err'; \
- fi; \
- GSSAPILIB='-lgssapi'; \
- if ls /lib/libgssapi_krb5* > /dev/null 2> /dev/null; then \
- GSSAPILIB='-lgssapi_krb5'; \
- else if ls /usr/lib/libgssapi_krb5* > /dev/null 2> /dev/null; then \
- GSSAPILIB='-lgssapi_krb5'; \
- else K5DIR=`echo $(K5LIB) | sed 's|-L||'`; \
- if ls $$K5DIR/libgssapi_krb5* > /dev/null 2> /dev/null; then \
- GSSAPILIB='-lgssapi_krb5'; \
- fi; fi; fi; \
- $(MAKE) linux KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "KFLAGS= -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 \
- -DCK_SSL -DCK_PAM -DZLIB -DCK_SHADOW $$OPENSSLOPTION $(SSLINC) \
- -DCK_ENCRYPTION $$HAVE_DES $(K5INC) $(K5INC)/krb5 \
- -I/usr/include/et $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) $(SSLLIB) -lssl $$DES_LIB -lpam -lz \
- -lcrypto $$GSSAPILIB -lkrb5 $$K5CRYPTO $$COM_ERR $(LIBS)" ; \
- if [ ! -f ./wermit ] || [ ./ckcmai.o -nt ./wermit ] ; then \
- echo ""; \
- echo "If build failed try:"; \
- echo ""; \
- echo " make clean ; make $${KTARGET:-$(@)} KFLAGS=-UCK_DES"; \
- echo ""; \
- fi
-
-# ::BEGIN_OLD_LINUX_TARGETS::
-
-# The remaining Linux entries are for special or customized builds. They have
-# not been generalized ("subroutinized") like the ones above. Ideally, we
-# should allow for every combination of libc vs glibc, gcc vs egcs, curses vs
-# ncurses, Kerberos IV vs Kerberos V vs SRP (in any combination), and so on.
-# The best way to do this is to set KFLAGS and LIBS values and then chain to
-# the main "linux" target, as in the examples just above. To skip past all of
-# these old targets (and there are many) search for ::END_OLD_LINUX_TARGETS::
-# (after this line).
-
-#Sharp Zaurus SL-5500 - Linux based
-zsl5500:
- @echo 'Making C-Kermit $(CKVER) for Sharp Zaurus SL-5500...'
- @touch ckcpro.c
- @touch wart
- $(MAKE) linuxnc KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DZSL5500" \
- "CC = gcc" "CC2 = gcc"
-
-#Mklinux DR3 has horrible bug in <utmpbits.h> - see ckufio.c.
-mklinux:
- $(MAKE) KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DUTMPBUG" \
- "LIBS=-lcrypt -lresolv" linuxa
-
-#LinuxPPC 1999
-linuxppc:
- @echo 'Making C-Kermit $(CKVER) for LinuxPPC 1999...'
- @if test -f /usr/lib/libcrypt.a; then \
- if test -f /usr/lib/libresolv.a; then \
- $(MAKE) KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(NCURSES_CPP) -DHAVE_CRYPT_H \
- -DLOCK_DIR=\\\\\\"\"/var/lock/modem\\\\\\"\" $(KFLAGS)" \
- "LIBS=-lncurses -lresolv -lcrypt" linuxa ; \
- else \
- $(MAKE) KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(NCURSES_CPP) -DHAVE_CRYPT_H \
- -DLOCK_DIR=\\\\\\"\"/var/lock/modem\\\\\\"\" $(KFLAGS)" \
- "LIBS=-lncurses -lcrypt" linuxa ; \
- fi \
- else \
- if test -f /usr/lib/libresolv.a; then \
- $(MAKE) KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(NCURSES_CPP) \
- -DLOCK_DIR=\\\\\\"\"/var/lock/modem\\\\\\"\" $(KFLAGS)" \
- "LIBS=-lncurses -lresolv" linuxa ; \
- else \
- $(MAKE) KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(NCURSES_CPP) \
- -DLOCK_DIR=\\\\\\"\"/var/lock/modem\\\\\\"\" $(KFLAGS)" \
- "LIBS=-lncurses" linuxa ; \
- fi \
- fi
-
-
-# Like "make linux" but built with egcs rather than gcc.
-# If you get "Internal compiler error xxx, output pipe has been closed",
-# try removing -pipe.
-linuxegcs:
- @echo 'Making C-Kermit $(CKVER) for Linux 1.2 or later with egcs...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = egcs" "CC2 = egcs" \
- "CFLAGS = -O -DLINUX -pipe -funsigned-char \
- -DPOSIX -DCK_POSIX_SIG -DCK_NCURSES -DNOCOTFMC \
- -DTCPSOCKET -DLINUXFSSTND $(KFLAGS)" \
- "LNKFLAGS = $(LNKFLAGS)" "LIBS = -lncurses -lcrypt -lresolv"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.1 (no K4 compatibility).
-linux+krb5-old:
- @echo 'Making C-Kermit $(CKVER) for Linux on Intel with Kerberos...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 \
- -DCK_ENCRYPTION -DCK_DES -DCK_CURSES -DCK_POSIX_SIG \
- -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H $(K5INC) $(K5INC)/krb5 \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) -lncurses -ltermcap -ldes425 -lkrb5 \
- -lcom_err -lk5crypto -lgssapi_krb5 -lcrypt -lresolv"
-
-# Linux on Intel PC with SRP 1.7.4 using GNU MP, Krypto, and Eric Young's
-# DES library. Remove the -DCK_DES, -DLIBDES and -ldes if you do not have
-# Eric Young's# libdes.a installed.
-#
-linux+srp+gmp:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...'
- $(MAKE) srpmit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(SRPINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) \
- -lncurses -ltermcap -lsrp -lgmp -ldes -lkrypto -lcrypt -lresolv"
-
-linux+srp+gmp+no-des:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP ...'
- $(MAKE) srpmit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP \
- -DCK_ENCRYPTION -DCK_CAST \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(SRPINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) \
- -lncurses -ltermcap -lsrp -lgmp -lkrypto -lcrypt -lresolv"
-
-linux+srp+gmp-export:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...'
- $(MAKE) srpmit-export KTARGET=$${KTARGET:-$(@)} \
- "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP -DFNFLOAT \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(SRPINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) \
- -lncurses -ltermcap -lsrp -lgmp -lkrypto -lcrypt -lm -lresolv"
-
-linux+srp+gmp+pam:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...'
- $(MAKE) srpmit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- -DCK_PAM -DFNFLOAT $(SRPINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) -lncurses -ltermcap -lsrp -lgmp -ldes -lkrypto \
- -lcrypt -lpam -ldl -lm -lresolv"
-
-#Linux on Intel PC with SRP 1.7.4 built with OpenSSL for Big Number Math
-#and Cryptographic functionality.
-#
-linux+srp:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...'
- $(MAKE) srpmit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(SRPINC) $(SSLINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) $(SSLLIB) \
- -lncurses -ltermcap -lsrp -lkrypto -lcrypto -lcrypt -lresolv"
-
-linux+srp+pam:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...'
- $(MAKE) srpmit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- -DCK_PAM -DFNFLOAT $(SRPINC) $(SSLINC) $(KFLAGS)" \
- "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) $(SSLLIB) -lncurses -ltermcap -lsrp -lkrypto \
- -lcrypto -lcrypt -lpam -ldl -lm -lresolv"
-
-#Linux on Intel PC with SRP and SSL/TLS.
-#
-# libsrp.a should be build with OpenSSL
-# Requires the Kerberos 1.2.2 or higher to be compiled with KRB4 compatibility.
-#Remove -ltermcap if it causes trouble e.g. in Debian 2.2.
-#If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS.
-linux+srp+openssl:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(SRPINC) $(SSLINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) $(SSLLIB) \
- -lncurses -ltermcap -lsrp -lssl -lkrypto -lcrypto \
- -lcrypt -lresolv"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2 and SRP.
-#
-# libsrp.a should be build with GNU MP (libgmp.a)
-# instead of AT&T CryptoLib (libcrypt.a) due to naming conflicts with
-# standard distribution Linux libraries.
-# Requires the Kerberos 1.2.2 or higher to be compiled with KRB4 compatibility.
-linux+krb5+krb4+srp:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB54+SRP...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(K5INC) $(K5INC)/krb5 $(SRPINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) $(SRPLIB) \
- -lncurses -ltermcap -lsrp -lgmp -lgssapi_krb5 -lkrypto \
- -ldes -lkrb4 -ldes425 -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, SRP and SSL/TLS.
-#
-# libsrp.a should be build with OpenSSL
-# Requires the Kerberos 1.2.2 or higher to be compiled with KRB4 compatibility.
-# Requires OpenSSL 0.9.6a or higher
-#If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS.
-linux+krb5+krb4+srp+openssl:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(K5INC) $(K5INC)/krb5 $(SRPINC) $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) $(SRPLIB) $(SSLLIB) \
- -lncurses -ltermcap -lsrp \
- -lkrb4 -lssl -lkrypto -lcrypto \
- -lkrb5 -lcom_err -lk5crypto -lgssapi_krb5 -lcrypt -lresolv"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, SSL/TLS.
-#
-# libsrp.a should be build with OpenSSL
-# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility.
-#If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS.
-linux+krb5+krb4+openssl:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(K5INC) $(K5INC)/krb5 $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) $(SSLLIB) \
- -lncurses -ltermcap \
- -lkrb4 -lssl -lcrypto -lkrb5 -lcom_err \
- -lk5crypto -lgssapi_krb5 -lcrypt -lresolv"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.1, SSL/TLS.
-#
-# libsrp.a should be build with OpenSSL
-# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility.
-# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS.
-linux+krb5+krb4+openssl+shadow:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_SHADOW \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(K5INC) $(K5INC)/krb5 $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) $(SSLLIB) \
- -lncurses -ltermcap \
- -lkrb4 -lssl -lcrypto -lkrb5 -lcom_err \
- -lk5crypto -lgssapi_krb5 -lcrypt -lresolv"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2, SSL/TLS.
-#
-# libsrp.a should be build with OpenSSL
-# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility.
-# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS.
-linux+krb5+krb4+openssl+zlib+shadow:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 -DZLIB \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_SHADOW \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(K5INC) $(K5INC)/krb5 $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) $(SSLLIB) \
- -lncurses -ltermcap \
- -lkrb4 -lssl -lcrypto -lkrb5 -lcom_err \
- -lk5crypto -lgssapi_krb5 -lcrypt -lresolv -lz"
-
-linux+krb5+krb4+srp-export:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...'
- $(MAKE) xermit-export KTARGET=$${KTARGET:-$(@)} \
- "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(K5INC) $(K5INC)/krb5 $(SRPINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) $(K5LIB) \
- -lncurses -ltermcap -lsrp -lgmp -lkrb4 -ldes425 -lkrb5 -lgssapi_krb5 \
- -lcom_err -lk5crypto -lkrypto -lcrypt -lresolv"
-
-linux+krb5+krb4+srp+pam:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- -DCK_PAM $(K5INC) $(K5INC)/krb5 $(SRPINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) $(K5LIB) \
- -lncurses -ltermcap -lsrp -lgmp -ldes -lkrb4 -ldes425 -lkrb5 \
- -lcom_err -lk5crypto -lgssapi_krb5 -lkrypto -lcrypt -lpam -ldl \
- -lresolv"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, SRP and SSL/TLS.
-# and PAM.
-#
-# libsrp.a should be build with OpenSSL
-# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility.
-# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS.
-linux+krb5+krb4+srp+openssl+pam-debug:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...'
- $(MAKE) xermit-debug KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- -w -Dmalloc=dmalloc -Dfree=dfree -DMDEBUG $(K5INC) $(K5INC)/krb5 \
- $(SRPINC) $(SSLINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) $(K5LIB) $(SSLLIB) \
- -lncurses -ltermcap -lsrp -lkrb4 -lssl -lkrypto -lcrypto \
- -lkrb5 -lcom_err -lk5crypto -lgssapi_krb5 -lcrypt -lresolv -lpam -ldl"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.1, SRP and SSL/TLS.
-# and PAM.
-#
-# libsrp.a should be build with OpenSSL
-# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility.
-# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS.
-linux+krb5+krb4+srp+openssl+pam:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(K5INC) $(K5INC)/krb5 $(SRPINC) $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) $(K5LIB) $(SSLLIB) \
- -lm -lncurses -ltermcap -lsrp \
- -lkrb4 -lssl -lkrypto -lcrypto -lgssapi_krb5 \
- -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, SRP, OpenSSL
-# with ZLIB and PAM
-#
-# libsrp.a should be build with OpenSSL
-# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility.
-# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS.
-linux+krb5+krb4+srp+openssl+zlib+pam:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM -DZLIB \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(K5INC) $(K5INC)/krb5 $(SRPINC) $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) $(K5LIB) $(SSLLIB) \
- -lm -lncurses -ltermcap -lsrp \
- -lkrb4 -lssl -lkrypto -lcrypto -lgssapi_krb5 \
- -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl -lz"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, SRP, OpenSSL
-# with ZLIB, Shadow Passwords, and PAM
-#
-# libsrp.a should be build with OpenSSL
-# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility.
-# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS.
-linux+krb5+krb4+srp+openssl+zlib+shadow+pam:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM -DZLIB \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- -DCK_SHADOW $(K5INC) $(K5INC)/krb5 $(SRPINC) $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(SRPLIB) $(K5LIB) $(SSLLIB) \
- -lm -lncurses -ltermcap -lsrp -lkrypto \
- -lkrb4 -lssl -lcrypto -lgssapi_krb5 \
- -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl -lz"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, OpenSSL
-# with Shadow Passwords, PAM
-#
-# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility.
-linux+krb5+krb4+openssl+shadow+pam:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SSL,...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- -DCK_SHADOW $(K5INC) $(K5INC)/krb5 $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) $(SSLLIB) \
- -lm -lncurses -ltermcap \
- -lkrb4 -lssl -lcrypto -lgssapi_krb5 \
- -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, OpenSSL
-# with ZLIB, Shadow Passwords, PAM
-#
-# libsrp.a should be build with OpenSSL
-# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility.
-# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS.
-linux+krb5+krb4+openssl+zlib+shadow+pam:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM -DZLIB \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- -DCK_SHADOW $(K5INC) $(K5INC)/krb5 $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) $(SSLLIB) \
- -lm -lncurses -ltermcap \
- -lkrb4 -lssl -lcrypto -lgssapi_krb5 \
- -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl -lz"
-
-#Red Hat 9 - full install includes Kerberos 5 (4 compat), PAM, SSL.
-#Also works around bug in curses in which terminal goes dead after
-#returning from file-transfer display. Assumes OpenSSL 0.9.7 or later.
-redhat9:
- @echo "Building SECURE Kermit for Red Hat 9.0..."
- $(MAKE) linux+krb5+krb4+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH90 -DOPENSSL_097 $(KFLAGS)"
-
-#Ditto plus SRP (which is not normally included with RH Linux).
-redhat9+srp:
- @echo "Building SECURE Kermit for Red Hat 9.0..."
- $(MAKE) linux+krb5+krb4+srp+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH90 -DOPENSSL_097 $(KFLAGS)"
-
-#For Red Hat AS 2.1 with OpenSSL
-redhat21+ssl:
- @echo "Building SECURE Kermit for Red Hat 2.1..."
- $(MAKE) linux+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = $(KFLAGS)"
-
-#Red Hat Linux 8.0 - full install includes Kerberos 5 (4 compat), PAM, SSL.
-#Also works around bug in curses in which terminal goes dead after
-#returning from file-transfer display.
-redhat80:
- @echo "Building SECURE Kermit for Red Hat 8.0..."
- $(MAKE) linux+krb5+krb4+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH80 $(KFLAGS)"
-
-redhat80+srp:
- @echo "Building SECURE Kermit for Red Hat 8.0..."
- $(MAKE) linux+krb5+krb4+srp+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH80 $(KFLAGS)"
-
-#Red Hat Linux 7.3 - full install includes Kerberos 5 (4 compat), PAM, SSL.
-#Also works around bug in curses in which terminal goes dead after
-#returning from file-transfer display.
-redhat73:
- @echo "Building SECURE Kermit for Red Hat 7.3..."
- $(MAKE) linux+krb5+krb4+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH73 $(KFLAGS)"
-
-redhat73+srp:
- @echo "Building SECURE Kermit for Red Hat 7.3..."
- $(MAKE) linux+krb5+krb4+srp+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH73 $(KFLAGS)"
-
-#Red Hat Linux 7.2 - full install includes Kerberos 5 (4 compat), PAM, SSL.
-#Also works around bug in curses in which terminal goes dead after
-#returning from file-transfer display.
-redhat72:
- @echo "Building SECURE Kermit for Red Hat 7.2..."
- $(MAKE) linux+krb5+krb4+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH72 $(KFLAGS)"
-
-redhat72+srp:
- @echo "Building SECURE Kermit for Red Hat 7.2..."
- $(MAKE) linux+krb5+krb4+srp+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH72 $(KFLAGS)"
-
-#Red Hat Linux 7.1 - full install includes Kerberos 5 (4 compat), PAM, SSL.
-#Also works around bug in curses in which terminal goes dead after
-#returning from file-transfer display.
-redhat71:
- @echo "Building SECURE Kermit for Red Hat 7.1..."
- $(MAKE) linux+krb5+krb4+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH71 $(KFLAGS)"
-
-redhat71+srp:
- @echo "Building SECURE Kermit for Red Hat 7.1..."
- $(MAKE) linux+krb5+krb4+srp+openssl+zlib+shadow+pam \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH71 $(KFLAGS)"
-
-#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, OpenSSL
-# with ZLIB and PAM and Shadow passwords
-linux+krb5+openssl+zlib+shadow+pam:
- @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB5,SSL...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \
- -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DCK_SHADOW -DHAVE_PTMX \
- -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM -DZLIB \
- -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \
- $(K5INC) $(K5INC)/krb5 $(SSLINC) \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
- "LIBS = $(K5LIB) $(SSLLIB) \
- -lm -lncurses -ltermcap -lssl -lcrypto -lgssapi_krb5 \
- -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl -lz"
-
-linuxnotcp:
- $(MAKE) linux KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DNONET $(KFLAGS)"
-
-# "make linuxnotcp" with lcc (see http://www.cs.princeton.edu/software/lcc)
-# lcc does not understand various gcc extensions:
-# "__inline__" -- can be eliminated by adding "-D__inline__="
-# "__asm__ and "long long" -- in header files, should be surrounded by
-# "#ifndef(__STRICT_ANSI__)"/"#endif"
-# however, TCP requires some __asm__ functions, so cannot be compiled
-linuxnotcp-lcc:
- @echo 'Making C-Kermit $(CKVER) for Linux with lcc ...'
- @echo 'Read comments in makefile for additional information.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = lcc" "CC2 = lcc" \
- "CFLAGS = -DLINUX -DPOSIX -DCK_CURSES -DCK_POSIX_SIG \
- -UTCPSOCKET -DLINUXFSSTND -DNOLEARN $(KFLAGS)" \
- "LNKFLAGS = $(LNKFLAGS)" "LIBS = -lcurses -ltermcap"
-
-# Linux 0.99.14 thru 1.0 with gcc, dynamic libraries, curses, TCP/IP.
-# For Linux 1.2 or later, use "make linux" (above).
-#
-# -DLINUXFSSTND (Linux File System Standard) gives UUCP lockfile /var/lock with
-# string pid. Remove this and get /usr/spool/uucp with int pid, which was used
-# in early Linux versions.
-#
-# If you get compiler errors regarding <linux/serial.h>, add -DNOHISPEED.
-#
-# -DCK_POSIX_SIG (POSIX signal handling) is good for Linux releases back to at
-# least 0.99.14; if it causes trouble for you, just remove it.
-#
-# -DCK_CURSES: Here we link with the regular curses library. But you should
-# be using ncurses. Internally, the ckuusx.c module includes <curses.h>, but
-# this really should be <ncurses.h>. Thus if you have the new curses
-# material, you should either install it with the standard names, or else
-# create symbolic links from the standard names to the new ones. If you get
-# compile-time errors complaining about data definitions in termcap.h, it
-# means you have new kernel material mixed with older libc header files. To
-# fix, add "#include <termios.h>" to the <termcap.h> file. Or if all this is
-# too confusing, create a new makefile entry based on this one, but with
-# -DCK_CURSES removed from CFLAGS and the entire LIBS= clause removed.
-#
-# But wait, there's more. On most Linux systems, -ltermcap must be included
-# in LIBS. But on others, the linker complains that libtermcap can't be
-# found. In that case, try removing -ltermcap from LIBS=.
-#
-# But wait, there's more. The format of the PID string in the UUCP lockfile
-# changed between Linux FSSTND 1.0 and 1.2. In the earlier standard, it had
-# leading zeros; in the second, it has leading spaces. By default this entry
-# uses the newer standard. To force the older one, add -DFSSTND10.
-#
-# "The nice thing about the Linux standard is there are so many to choose from"
-#
-# NOTE: Remove -DBIGBUFOK for small-memory or limited-resource systems.
-linux10:
- @echo 'Making C-Kermit $(CKVER) for Linux 1.0 or earlier...'
- @echo 'IMPORTANT: Read the comments in the linux section of the'
- @echo 'makefile if you get compilation or link errors.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -DPOSIX -DCK_CURSES -DCK_POSIX_SIG -DLINUX \
- -DTCPSOCKET -DLINUXFSSTND -DOLINUXHISPEED -DNOLEARN $(KFLAGS)" \
- "LNKFLAGS = $(LNKFLAGS)" "LIBS = -lcurses -ltermcap"
-
-#This version was used for Linux prior to C-Kermit 6.0.192.
-#Now the "Linux File System Standard" is considered standard, ditto TCP/IP.
-linuxold:
- @echo 'Making C-Kermit $(CKVER) for Linux...'
- @echo 'For FSSTND-recommended UUCP lockfiles, use:'
- @echo ' make linux "KFLAGS=-DLINUXFSSTND".'
- @echo 'Read comments in makefile for additional options.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS = -O -DLINUX -DPOSIX -DCK_CURSES -DCK_POSIX_SIG -DNOLEARN \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" "LIBS = -lcurses -ltermcap"
-
-# ::END_OLD_LINUX_TARGETS::
-
-# LynxOS 2.2 with GCC compiler, TCP/IP and fullscreen display.
-# Probably also works with Lynx 2.1, and maybe even Lynx 2.0.
-# -X means use termios serial drivers rather than BSD4.3-style sgtty drivers.
-# If you have trouble with this, try "make bsd KFLAGS=-DNOFDZERO".
-lynx:
- @echo 'Making C-Kermit $(CKVER) for LynxOS 2.2 with TCP/IP'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS= -O -DPOSIX -DDIRENT -DSETREUID -DCK_CURSES -DTCPSOCKET \
- -DCK_ANSIC -DLYNXOS -DNOLEARN" "LNKFLAGS = -X" "LIBS = -lcurses -lbsd"
-
-lynx22:
- $(MAKE) lynx KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS)"
-
-# LynxOS 2.1 with GCC compiler 1.40 and TCP/IP.
-lynx21:
- @echo 'Making C-Kermit $(CKVER) for LynxOS 2.1 with TCP/IP'
- $(MAKE) kermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS= -O -DSETREUID -DTCPSOCKET -DCK_ANSIC -DBSD4 -DLYNXOS" \
- "LIBS = -lbsd"
-
-#SCO Xenix 2.2.1 for IBM PC, XT, PS2/30, or other 8088 or 8086 machine
-#Should this not work, try some of the tricks from sco286.
-#NOTE: -DRENAME is omitted for early SCO Xenix releases because it didn't
-#exist, or its semantics were different from the later POSIX-compliant
-#version of rename().
-sco86:
- @echo 'Making C-Kermit $(CKVER) for SCO Xenix/86...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DXENIX -DNOFILEH -DNOIKSD -DNOUNICODE -DNOLEARN \
- $(KFLAGS) -Dunix -F 3000 -i -M0me" \
- "LNKFLAGS = -F 3000 -i -s -M0me" "LIBS = -lx"
-
-#SCO Xenix/286 2.2.1, e.g. for IBM PC/AT, PS/2 Model 50, etc.
-#Reportedly, this "make" can fail simply because of the size of this
-#makefile. If that happens, use "makeL", or edit out some of the
-#other entries. No debugging or character-set translation.
-sco286:
- @echo 'Making C-Kermit $(CKVER) for SCO Xenix/286...'
- @echo 'If make fails, try using makeL.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -xenix -s -O -LARGE -DXENIX -DNOFILEH -Dunix -DRDCHK -DNAP \
- -DNOIKSD -DNODEBUG -DNOTLOG -DNOCSETS -DNOLEARN \
- $(KFLAGS) -F 3000 -i -M2let16" \
- "LIBS = -lx" "LNKFLAGS = -xenix -s -O -LARGE -F 3000 -i -M2let16"
-
-#SCO Xenix/286 2.2.1, e.g. for IBM PC/AT, PS/2 Model 50, etc.
-#As above, but with HDBUUCP (This one might need fixing -- see sco286).
-sco286hdb:
- @echo 'Making C-Kermit $(CKVER) for SCO Xenix/286 with HDB UUCP...'
- @echo 'If make fails, try using makeL.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -s -O -LARGE -DXENIX -DNOFILEH -Dunix -DRDCHK -DNAP \
- -DHDBUUCP -DNOIKSD -DNOUNICODE -DNOLEARN \
- $(KFLAGS) -F 3000 -i -M2let32" \
- "LIBS = -lx" "LNKFLAGS = -s -O -LARGE -F 3000 -i -M2let32"
-
-#SCO Xenix/386 2.2.2 and 2.2.3
-sco386:
- @echo 'Making C-Kermit $(CKVER) for SCO Xenix/386 2.2.2...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DXENIX -DNOFILEH -DNOIKSD -DNOREDIRECT -DNOLEARN \
- -Dunix -DRDCHK -DNAP -DNOUNICODE $(KFLAGS) -Otcl -M3e" \
- "LNKFLAGS = -s" "LIBS = -lx"
-
-#SCO XENIX/386 2.2.3 with Excelan TCP/IP + curses.
-# NOTE: This one might need some work in C-Kermit 6.0.
-# You might need to include /usr/include/sys/types.h
-# containing "typedef char *caddr_t;". Then at least it compiles.
-sco386netc:
- @echo 'Making C-Kermit $(CKVER) for SCO Xenix/386 2.2.3 + Excelan TCP'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -I/usr/include/exos -DXENIX -DCK_CURSES -DNOUNICODE \
- -Dunix -DRDCHK -DNAP -DTCPSOCKET -DEXCELAN -DNOJC -DNOMKDIR -DNOFILEH \
- -DNOLEARN -DNOREDIRECT -DNOIKSD -DNO_DNS_SRV $(KFLAGS) -Otcl -M3e" \
- "LNKFLAGS = -s" "LIBS = -lc -lx -lsocket -lcurses -ltermcap"
-
-#SCO XENIX/386 2.3.3 with gcc 1.37 or later...
-sco386gcc:
- @echo 'Making C-Kermit $(CKVER) for SCO Xenix/386 2.3.3, gcc...'
- @echo 'Add -D_NO_PROTOTYPE if you have trouble with Xenix header files'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS= -O -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP \
- -DNOJC -DNODEBUG -DNOUNICODE -DNOLEARN $(KFLAGS) \
- -traditional -fpcc-struct-return -fstrength-reduce \
- -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM \
- -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 \
- -DM_SYSIII -DM_SYSV -DM_WORDSWAP -DM_XENIX -DNOIKSD -DNOREDIRECT \
- -DPWID_T=int " "LNKFLAGS = -s" "LIBS = -lx"
-
-#As above, but with curses...
-sco386gccc:
- @echo 'Making C-Kermit $(CKVER) for SCO Xenix/386 2.3.3, gcc...'
- @echo 'Add -D_NO_PROTOTYPE if you have trouble with Xenix header files'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
- "CFLAGS= -O -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP \
- -DNOJC -DNODEBUG -DCK_CURSES -DNOUNICODE -DNOLEARN $(KFLAGS) \
- -traditional -fpcc-struct-return -fstrength-reduce \
- -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM -DNOREDIRECT \
- -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 \
- -DM_SYSIII -DM_SYSV -DM_WORDSWAP -DM_XENIX -DNOIKSD \
- -DPWID_T=int " "LNKFLAGS = -s" "LIBS = -lx -lcurses -ltermlib"
-
-#SCO UNIX (and ODT) entries...
-#
-#NOTE: All SCO UNIX entry LIBS should have "-lc_s -lc -lx" IN THAT ORDER (if
-#shared C library is desired), or else "-lc -lx" IN THAT ORDER. Use shared C
-#libraries to save memory, but then don't expect to run the resulting binary
-#on a different machine. When using -lc_s, you must also use -lc, because the
-#shared C library does not contain all of libc.a. And in all cases, -lc must
-#ALWAYS precede -lx.
-#
-#ANOTHER NOTE: -DRENAME is included in all SCO UNIX entries. Remove it if it
-#causes trouble. No harm is done by removing it (see ckuins.txt).
-#
-#AND ANOTHER: In theory, it should be possible to run SCO UNIX binaries on
-#SCO Xenix 2.3 and later. In practice, this might not work because of the
-#libraries, etc. Also, don't add the -link -z switch (which is supposed to
-#root out references to null pointers) because it makes UNIX binaries core
-#dump when they are run under Xenix.
-
-#NOTE: -Otcl removed and replaced by -O, since -Otcl produced incorrect code.
-#SCO UNIX/386 3.2.0, 3.2.1, and SCO Xenix 2.3.x
-sco3r2:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2.0 or 3.2.1 ...'
- @echo 'Warning: If make blows up, edit the makefile to join'
- @echo 'the following three continued lines into one line.'
- @echo 'Also, remove -DRENAME if _rename unresolved at link time.'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP -DNOLEARN \
- -DRENAME -DNOIKSD -DNOJC $(KFLAGS) -O" \
- "LNKFLAGS = -s" "LIBS = -lc -lx"
-
-#SCO UNIX/386 3.2.0 and SCO Xenix 2.3.x with Excelan TCP/IP support.
-#In case of compilation or runtime problems, try adding
-#"-DUID_T=int -DGID_T=int" to the CFLAGS. If that doesn't work, try
-#"-DUID_T=uid_t -DGID_T=gid_t".
-sco3r2net:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 / Excelan...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -I/usr/include/exos -DXENIX -DSVR3 -DNOFILEH -DNOLEARN \
- -DHDBUUCP -DRDCHK -DNAP -DRENAME -DTCPSOCKET -DEXCELAN -DNOJC \
- -DNOIKSD -DNOREDIRECT $(KFLAGS) -O" \
- "LNKFLAGS = -s" "LIBS = -lc -lx -lsocket"
-
-#SCO UNIX/386 3.2.0 and SCO Xenix 2.3.x with Excelan TCP/IP support.
-#As above, with curses added.
-sco3r2netc:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 / Excelan / curses...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -I/usr/include/exos -DXENIX -DSVR3 -DNOFILEH -DNOLEARN \
- -DHDBUUCP -DRDCHK -DNAP -DTCPSOCKET -DEXCELAN -DNOJC $(KFLAGS) \
- -DRENAME -DCK_CURSES -DNOREDIRECT -DNOIKSD -O" "LNKFLAGS = -s" \
- "LIBS = -lc -lx -lsocket -lcurses -ltermcap"
-
-#SCO UNIX 3.2.x or SCO Xenix 2.3.x with Racal InterLan TCP/IP support
-# Extra compile flags for other version of Racal InterLan TCP/IP:
-# Xenix286/NP621-286, use -Ml -DPARAMH -DINTERLAN -Di286 -DSYSV
-# Xenix386/NP621-386, use -DPARAMH -DINTERLAN -Di386 -DSYSV
-# ISC386ix/NP622I, use -DSYSV -Di386
-# SCO Unix3.2/NP622S, use -DSYSV -Di386 -DSCO_UNIX
-# AT&T SVR3.2/NP622A, use -DSYSV -Di386 -DATT
-sco3r2netri:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 / Racal InterLan...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -I/usr/include/interlan -DXENIX -DNOFILEH -DHDBUUCP \
- -DSVR3 -DRDCHK -DNAP -DTCPSOCKET -DPARAMH -DINTERLAN -Di386 -DSYSV \
- -DRENAME -DNOREDIRECT -DNOIKSD -DNOJC -DNOLEARN $(KFLAGS) -Otcl -M3e" \
- "LNKFLAGS = -s" "LIBS = -lc -lx -ltcp"
-
-# SCO XENIX/386 2.3.3 SysV with SCO TCP/IP
-# System V STREAMS TCP developed by Lachman Associates Inc and
-# Convergent Technologies.
-# -DRENAME removed since some reports indicate it is not supported
-# (whereas others say it is.)
-sco3r2lai:
- @echo 'Making C-Kermit $(CKVER) for SCO XENIX/386 2.3.3 + TCP/IP...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DLAI_TCP -Di386 -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK \
- -DNAP -DTCPSOCKET -DPWID_T=int -DNOREDIRECT -DNOIKSD -DNOLEARN \
- $(KFLAGS) -Otcl -i -M3e" \
- "LNKFLAGS = -i -s" "LIBS = -lc -lx -lsocket"
-
-sco3r2laic:
- @echo 'Making C-Kermit $(CKVER) for SCO XENIX/386 2.3.3 + TCP/IP...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DLAI_TCP -Di386 -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK \
- -DNAP -DTCPSOCKET -DCK_ANSIC -DCK_CURSES -DM_TERMINFO -DNOLEARN \
- -DPWID_T=int -DNOREDIRECT -DNOIKSD $(KFLAGS) -Otcl -i -M3e" \
- "LNKFLAGS = -i -s" "LIBS = -ltinfo -lc -lx -lsocket"
-
-#SCO UNIX/386 3.2v2 (POSIX job control), shared libraries.
-sco3r22:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v2 ...'
- make wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNOLEARN \
- -DNAP -DRENAME -DPID_T=pid_t -DPWID_T=int -DDIRENT -DNOIKSD \
- -DNOREDIRECT $(KFLAGS) -O" \
- "LNKFLAGS = -s" "LIBS = -lc_s -lc -lx"
-
-#SCO UNIX/386 3.2v2, POSIX job control, fullscreen file transfer display,
-#dynamic memory allocation, shared C library
-sco3r22c:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v2 ...'
- @echo 'Warning: If make blows up, edit the makefile to join'
- @echo 'the following four continued lines into one line.'
- make wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP -DNOLEARN \
- -DCK_CURSES -DDIRENT -DRENAME -DNOREDIRECT -DNOIKSD \
- -DPID_T=pid_t -DPWID_T=int $(KFLAGS) -O" \
- "LNKFLAGS = -s" "LIBS = -lcurses -lc_s -lc -lx"
-
-#SCO UNIX/386 3.2v2 with gcc 1.40 or later (POSIX job control)
-sco3r22gcc:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v2, gcc'
- @echo 'Warning: If make blows up, edit the makefile to join'
- @echo 'the following seven continued lines into one line.'
- make wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" \
- "CFLAGS= -O -DPOSIX -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP \
- -DNOLEARN -DRENAME -traditional -fpcc-struct-return -fstrength-reduce \
- -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM \
- -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 \
- -DM_SYSIII -DM_SYSV -DM_UNIX -DM_WORDSWAP -DM_XENIX -Dunix \
- -DPID_T=pid_t -DPWID_T=int -DNOREDIRECT -DNOIKSD $(KFLAGS) " \
- "LNKFLAGS = -s" "LIBS = -lc_s -lc -lx"
-
-#SCO UNIX/386 3.2v2 (ODT 1.1) (POSIX job control) with SCO TCP/IP, shared libs
-#Requires SCO TCP/IP or ODT development system for telnet.h, etc.
-sco3r22net:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2.2 + TCP/IP...'
- @echo 'Warning: If make blows up, edit the makefile to join'
- @echo 'the following three continued lines into one line.'
- make xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP -DTCPSOCKET \
- -DRENAME -DPID_T=pid_t -DPWID_T=int -DDIRENT -DNOREDIRECT -DNOIKSD \
- $(KFLAGS) -O" "LNKFLAGS = -s" "LIBS = -lsocket -lc_s -lc -lx"
-
-#As above, but with curses for fullscreen file transfer display.
-#Requires SCO TCP/IP or ODT development system for telnet.h, etc.
-sco3r22netc:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v2 + TCP/IP...'
- @echo 'Warning: If make blows up, edit the makefile to join'
- @echo 'the following three continued lines into one line.'
- make xermit KTARGET=$${KTARGET:-$(@)} "CFLAGS= \
- -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP -DTCPSOCKET -DRENAME \
- -DCK_CURSES -DDIRENT -DNOIKSD -DNOREDIRECT \
- -DPID_T=pid_t -DPWID_T=int -O $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS = -lcurses -lsocket -lc_s -lc -lx"
-
-#SCO XENIX 2.3.4, no curses, no TCP/IP, no IKSD.
-#This one built and tested in C-Kermit 7.0.
-#lcfp is C library floating-point support.
-#Use -M3 to generate 32-bit i386 code instead of 16-bit segmented i286 code.
-#Use -Me to enable MS nonstandard keywords in system headers.
-#Use -W2 or W3 to increase the warning level.
-#OK: 2011/06/15
-sco234:
- @echo 'Making C-Kermit $(CKVER) for SCO XENIX 2.3.4...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DSCO32 -DXENIX -DNOFILEH -DHDBUUCP -DRDCHK -DNOLEARN \
- -DNAP -DNOJC -DNOCOTFMC -DNOIKSD -DNOREDIRECT -DNOTNCODE -DNOGFTIMER \
- -DNOTIMEVAL -DNOTIMEZONE -DNOSYMLINK -DSCO234 -DDCLGETCWD $(KFLAGS) \
- -Otcl" "LNKFLAGS = -s" "LIBS = -lcfp -lc -lx"
-
-#SCO XENIX 2.3.4, no TCP/IP, no IKSD, but with curses.
-# Built and tested in C-Kermit 7.0.
-# Note: XENIX 2.3.4 does not have newterm() so no point in adding -DCK_NEWTERM.
-sco234c:
- @echo 'Making C-Kermit $(CKVER) for SCO XENIX 2.3.4 + curses...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DSCO32 -DXENIX -DNOFILEH -DHDBUUCP -DRDCHK -DNOLEARN \
- -DNAP -DNOJC -DNOCOTFMC -DNOIKSD -DNOREDIRECT -DNOTNCODE -DNOGFTIMER \
- -DNOTIMEVAL -DNOTIMEZONE -DNOSYMLINK -DCK_CURSES -DSCO234 \
- -DDCLGETCWD $(KFLAGS) -Otcl" \
- "LNKFLAGS = -s" "LIBS = -lcfp -lc -ltinfo -lx"
-
-#SCO XENIX 2.3.4 with SCO TCP/IP and curses, no IKSD.
-# Built and tested in C-Kermit 7.0. TCP/IP works and curses works.
-# Previous versions of this target included -lmalloc, but this caused "error:
-# " _calloc : symbol defined more than once" at link time so I removed it.
-# Results are likely to vary depending on exactly which version of the SDK
-# and TCP/IP SDK you have.
-sco234netc:
- @echo 'Making C-Kermit $(CKVER) for SCO XENIX 2.3.4 + TCP + curses...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DSCO32 -DXENIX -DNOFILEH -DHDBUUCP -DRDCHK -DNOLEARN \
- -DNAP -DNOJC -DNOCOTFMC -DNOIKSD -DNOREDIRECT -DNOTNCODE -DNOGFTIMER \
- -DNOTIMEVAL -DNOTIMEZONE -DNOSYMLINK -DCK_CURSES -DSCO234 \
- -DDCLGETCWD -DTCPSOCKET -DNO_DNS_SRV $(KFLAGS) -Otcl" \
- "LNKFLAGS = -s" "LIBS = -ltinfo -lsocket -lcfp -lc -lx"
-
-# SCO 3.2v4.x targets...
-
-# NOTE: Add -DDCLPOPEN and/or -DDCLFDOPEN to anySCO 3.2v4.x non-gcc entries
-# that complain about fdopen() or popen() at compile time. They compile OK
-# without these flags as of July 1999. However, the gcc entries seem to
-# need them, at least for gcc 2.7.2.2.
-
-# NOTE 2: To enable IKSD support, add:
-# -DCK_LOGIN -DNOGETUSERSHELL -DNOINITGROUPS
-# to CFLAGS (not tested).
-
-#SCO UNIX/386 3.2v4 (POSIX job control), curses, ANSI C compilation,
-#<dirent.h> (EAFS) file system. Remove -lmalloc if it causes trouble. It was
-#put there to avoid core dumps caused by regular libc.a malloc. Add -J to make
-#all chars unsigned. This version uses select() for CONNECT and also has
-#high-precision timers and so might not work on non-TCP systems, in which case
-#sco32v4ns should be used instead.
-# If you get _ftime redefinition_ complaint, try adding -DODT30 to CFLAGS.
-sco32v4:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v4...'
- make xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DCK_SCO32V4 -DNOFILEH -DHDBUUCP -DCK_CURSES -DM_TERMINFO \
- -DNOANSI -DSELECT -DNOIKSD -DDCLGETCWD -NOLSTAT \
- -DNOLINKBITS -DDCLGETCWD $(KFLAGS) -O" \
- "LNKFLAGS = -s" "LIBS = -lcurses -lmalloc -lsocket -lc_s -lc -lx"
-
-# As above, but with no dependence on sockets library or select().
-sco32v4ns:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v4...'
- @echo 'No select() and no sockets library.'
- make wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DCK_SCO32V4 -DNOFILEH -DHDBUUCP -DCK_CURSES -DM_TERMINFO \
- -DNOANSI -DNOIKSD -DNOGFTIMER -DCK_POLL -DNAP -DDCLGETCWD -DNOLSTAT \
- -DNOLINKBITS -DDCLGETCWD -DNOLEARN -O $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS = -lcurses -lmalloc -lc_s -lc -lx"
-
-#SCO UNIX/386 3.2v4 (POSIX job control), TCP/IP, curses, ANSI C compilation,
-#<dirent.h> (EAFS) file system. With DIRENT, -lc must come before -lx.
-#Reportedly it's OK to add -DCK_REDIR and -DCK_WREFRESH, and to remove -lc_s.
-#Requires SCO TCP/IP development system or ODT for telnet.h, etc.
-#See sco32v4 above for additional comments.
-#NOTE: No more room for -Dxxx -- 25 seems to be the limit. Move some to
-#ckcdeb.h or somewhere...
-sco32v4net:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v4...'
- @echo 'If you get _ftime redefinition_ complaint,'
- @echo 'use make sco-odt30.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DNOFILEH -DHDBUUCP -DTCPSOCKET -DCK_ANSIC -DCK_CURSES \
- -DNAP -DCK_WREFRESH -DNOLINKBITS -D_IBCS2 -DSELECT -DNOLSTAT \
- -DDCLGETCWD -DCK_SCO32V4 -DNOIKSD -O \
- $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS) -s" \
- "LIBS = $(LIBS) -lcurses -lsocket -lmalloc -lsocket -lc_s -lc -lx"
-
-#SCO UNIX/386 3.2v4 with gcc 1.40 or later, POSIX job control.
-#Also see comments in sco32r4 entry.
-sco32v4gcc:
- make xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" \
- "CFLAGS= -O -DNOFILEH -DHDBUUCP -DNOANSI -DCK_CURSES -DM_TERMINFO \
- -traditional -fpcc-struct-return -fstrength-reduce -funsigned-char \
- -D_KR -D_NO_PROTOTYPE -D_SVID -DNOIKSD -DCK_SCO32V4 -DNOLINKBITS \
- -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM -DSELECT -DNOLSTAT \
- -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 -DDCLGETCWD \
- -DM_SYSIII -DM_SYSV -DM_UNIX -DM_WORDSWAP -DM_XENIX -Dunix \
- -DDCLPOPEN -DDCLFDOPEN $(KFLAGS) " \
- "LNKFLAGS = -s" "LIBS = -lcurses -lsocket -lc_s -lc -lx"
-
-#SCO UNIX/386 3.2v4 (POSIX job control), TCP/IP, curses, ANSI C compilation,
-#Requires SCO TCP/IP or ODT development system for telnet.h, etc.
-#<dirent.h> (EAFS) file system. With DIRENT, -lc must come before -lx.
-#gcc 1.40 or later. Also see comments in sco32r4 entry.
-sco32v4netgcc:
- make xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2=gcc" \
- "CFLAGS= -O2 -DNOFILEH -DHDBUUCP -DSELECT -DNOLSTAT \
- -DNOANSI -DTCPSOCKET -DCK_CURSES -DM_TERMINFO \
- -D_KR -D_NO_PROTOTYPE -D_SVID -DNOIKSD -DCK_SCO32V4 -DNOLINKBITS \
- -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM -DDCLGETCWD \
- -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 \
- -DM_SYSIII -DM_SYSV -DM_UNIX -DM_WORDSWAP -DM_XENIX -Dunix \
- -DDCLPOPEN -DDCLFDOPEN $(KFLAGS)" \
- "LNKFLAGS = -s" "LIBS = -lcurses -lsocket -lc_s -lc -lx"
-
-#As above but with bgcc BOUNDS CHECKING (for developers only). -lcheck has
-#bounds-checking replacements for malloc, memcpy, bcopy, etc, so must come
-#before -lsocket and -lc.
-sco32v4netbgcc:
- make xermit KTARGET=$${KTARGET:-$(@)} \
- "CC = bgcc -pipe -m386" "CC2=bgcc -pipe -m386" \
- "CFLAGS= -O1 -g -DNOFILEH -DHDBUUCP -DSELECT \
- -DNOANSI -DTCPSOCKET -DCK_CURSES -DM_TERMINFO \
- -D_KR -D_NO_PROTOTYPE -D_SVID -DNOIKSD -DCK_SCO32V4 -DNOLSTAT \
- -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM -DNOLINKBITS \
- -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 -DDCLGETCWD \
- -DM_SYSIII -DM_SYSV -DM_UNIX -DM_WORDSWAP -DM_XENIX -Dunix \
- -DDCLPOPEN -DDCLFDOPEN $(KFLAGS) " \
- "LNKFLAGS = -g" "LIBS = -lcurses -lcheck -lsocket -lx"
-
-sco32v4netnd:
- @echo sco32v4net with no debug
- $(MAKE) "MAKE=$(MAKE)" sco32v4net KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -DNODEBUG -DNOTLOG" "LIBS=$(LIBS)"
-
-sco3r2netnd:
- @echo sco32v4netnd built for SCO XENIX 2.3 under SCO UNIX...
- @echo requires copying /lib/386/Slibc.a to /lib/386/Slibc_s.a and
- @echo getting /lib/386/Slibsocket.a from a XENIX devkit.
- @echo WARNING: poll/CK_POLL supported only on XENIX 2.3.4
- echo For earlier XENIX systems, replace CK_POLL with RDCHK.
- $(MAKE) "MAKE=$(MAKE)" sco32v4netnd KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -x2.3 -DNORENAME -DNOSYMLINK" \
- "LNKFLAGS = $(LNKFLAGS) -x2.3" \
- "LIBS=-ldir -lcfp $(LIBS)"
-
-#SCO UNIX/386 3.2v4 (POSIX job control), TCP/IP, curses, ANSI C compilation,
-#<dirent.h> (EAFS) file system. With DIRENT, -lc must come before -lx.
-#Reportedly it's OK to add -DCK_REDIR and -DCK_WREFRESH, and to remove -lc_s.
-#Requires SCO TCP/IP development system or ODT for telnet.h, etc.
-#See sco32v4 above for additional comments.
-# Note: "xermit" means use the select() version of the CONNECT module.
-sco32v4netx:
- @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v4...'
- @echo 'If you get _ftime redefinition_ complaint,'
- @echo 'use make sco-odt30.'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DNOFILEH -DHDBUUCP -DTCPSOCKET -DCK_ANSIC -DCK_CURSES -DNAP \
- -DCK_WREFRESH -DNOLINKBITS -D_IBCS2 -DSELECT -DDCLGETCWD \
- -DCK_SCO32V4 -DNOIKSD -DNOLSTAT -O $(KFLAGS)" \
- "LNKFLAGS = $(LNKFLAGS) -s" \
- "LIBS = $(LIBS) -lcurses -lsocket -lmalloc -lsocket -lc_s -lc -lx"
-
-sco32v4netndx:
- @echo sco32v4netx with no debug
- $(MAKE) "MAKE=$(MAKE)" sco32v4netx KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -DNODEBUG -DNOTLOG" "LIBS=$(LIBS)"
-
-sco3r2netndx:
- @echo sco32v4netndx built for SCO XENIX 2.3 under SCO UNIX...
- @echo requires copying /lib/386/Slibc.a to /lib/386/Slibc_s.a and
- @echo getting /lib/386/Slibsocket.a from a XENIX devkit.
- @echo WARNING: poll/CK_POLL supported only on XENIX 2.3.4
- echo For earlier XENIX systems, replace CK_POLL with RDCHK.
- $(MAKE) "MAKE=$(MAKE)" sco32v4netndx KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -x2.3 -DNORENAME -DNOSYMLINK" \
- "LNKFLAGS = $(LNKFLAGS) -x2.3" \
- "LIBS=-ldir -lcfp $(LIBS)"
-
-sco-odt30:
- @echo SCO ODT 3.0
- $(MAKE) "MAKE=$(MAKE)" sco32v4net KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=$(KFLAGS) -DODT30"
-
-#SCO OpenServer 5.0 (SCO UNIX 3.2v5.0) with SCO development tools, no TCP/IP.
-#SCO OSR5 is much more like standard System V than previous SCO releases.
-#The SCO development tools include TCP/IP, so this target is only for creating
-#artificially limited versions of kermit required by site policy rather than
-#the operating system. NOSYSLOG is included because syslog() requires the
-#sockets library.
-sco32v500:
- @echo Making C-Kermit $(CKVER) for SCO OpenServer Release 5...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \
- -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DNOSYSLOG \
- $(KFLAGS)" \
- "LIBS=-lcurses $(LIBS)" "LNKFLAGS=$(LNKFLAGS)"
-
-sco32v5:
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" sco32v500
-
-
-#SCO OpenServer 5.0 with networking, SCO development tools.
-#Networking libraries are now provided with the OS.
-sco32v500net:
- @echo Making C-Kermit $(CKVER) for SCO OpenServer Release 5...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \
- -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DTCPSOCKET \
- -DNO_DNS_SRV $(KFLAGS)" \
- "LIBS=-lcurses -lsocket $(LIBS)" "LNKFLAGS=$(LNKFLAGS)"
-
-sco32v5net:
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" sco32v500net
-
-#SCO OpenServer 5.0 with networking and OpenSSL, SCO development tools.
-#Networking libraries are now provided with the OS.
-sco32v500net+ssl:
- @echo Making C-Kermit $(CKVER) for SCO OSR5 with OpenSSL...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \
- -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DTCPSOCKET \
- -DNO_DNS_SRV -DCK_AUTHENTICATION -DCK_SSL -DCK_TRIGGER \
- $(SSLINC) $(SSLLIB) $(KFLAGS)" \
- "LIBS=$(SSLLIB) -lcurses -lsocket -lssl -lcrypto $(LIBS)" \
- "LNKFLAGS=$(LNKFLAGS)"
-
-#SCO OpenServer 5.0 with gcc, no networking.
-#Note: NOSYSLOG required for non-net entries because it requires <socket.h>
-sco32v500gcc:
- @echo Using gcc...
- $(MAKE) "MAKE=$(MAKE)" sco32v500CC=gcc CC2=gcc \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS= $(KFLAGS)"
-
-#SCO OpenServer 5.0 with networking, gcc.
-sco32v500netgcc:
- @echo TCP/IP networking added - using gcc...
- $(MAKE) "MAKE=$(MAKE)" sco32v500net CC=gcc CC2=gcc \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS)"
-
-#SCO OpenServer 5.0 with networking, gcc, elf.
-sco32v500netgccelf:
- @echo TCP/IP networking added - using gcc, dynamic elf library
- $(MAKE) "MAKE=$(MAKE)" sco32v500net "CC=gcc" "CC2=gcc" \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS=-O3 -belf" "LNKFLAGS=-belf"
-
-sco32v502:
- $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR502 $(KFLAGS)"
-
-#SCO OpenServer 5.0.2 with networking, SCO development tools.
-sco32v502net:
- @echo TCP/IP networking added...
- $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-b elf -DSCO_OSR502 $(KFLAGS)"
-
-#SCO OpenServer 5.0.4 (SCO UNIX 3.2v5.0.4) with SCO development tools.
-#Like 5.0, but adds high serial speeds. First POSIX-based SCO version.
-#Note: the -O flag is deliberately omitted for /bin/cc (= /usr/ccs/bin/cc).
-sco32v504:
- @echo Making C-Kermit $(CKVER) for SCO OpenServer Release 5.0.4...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \
- -DSCO_OSR504 -b elf -DPOSIX \
- -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DNOSYSLOG $(KFLAGS)" \
- "LIBS=-lcurses $(LIBS)" "LNKFLAGS=$(LNKFLAGS)"
-
-#SCO OpenServer 5.0.4 with gcc, no networking.
-sco32v504gcc:
- @echo Using gcc...
- $(MAKE) "MAKE=$(MAKE)" sco32v504 "CC=gcc" "CC2=gcc" \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS= $(KFLAGS)"
-
-#SCO OpenServer 5.0.4 with networking.
-#SCO development tools (/bin/cc = /usr/ccs/bin/cc).
-#Optimization deliberately suppressed.
-sco32v504net:
- @echo Making C-Kermit $(CKVER) for SCO OpenServer Release 5.0.4...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \
- -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DTCPSOCKET \
- -b elf -DSCO_OSR504 -DPOSIX -DNO_DNS_SRV $(KFLAGS)" \
- "LIBS=-lcurses -lsocket $(LIBS)" "LNKFLAGS=$(LNKFLAGS)"
-
-#SCO OpenServer 5.0.4 with networking, gcc.
-sco32v504netgcc:
- @echo TCP/IP networking added - using gcc...
- @echo If gcc crashes on ckwart.c then build it by hand:
- @echo " gcc -o wart -DCK_SCOV5 ckwart.c"
- $(MAKE) "MAKE=$(MAKE)" sco32v500net "CC=gcc" "CC2=gcc" \
- KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DSCO_OSR504 -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 5.0.4 with networking, gcc, elf.
-sco32v504netgccelf:
- @echo TCP/IP networking added - using gcc, dynamic elf library
- $(MAKE) "MAKE=$(MAKE)" sco32v500net "CC=gcc" "CC2=gcc"
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR504 -DPOSIX -O3 -belf $(KFLAGS)" \
- LNKFLAGS="-belf"
-
-#SCO OpenServer 5.0.5 (SCO UNIX 3.2v5.0.5) with SCO /bin/cc.
-#Like 5.0, but adds high serial speeds. First POSIX-based SCO version.
-#You might have to add "LIBS=-ltinfo" (some do, some don't).
-sco32v505:
- $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DNOSHADOW -b elf -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 5.0.5 (SCO UNIX 3.2v5.0.5) with SCO UDK.
-#This one can't see the high serial speeds and anything to do with modem
-#signals doesn't work because UKD cc has its own alternative universe of
-#header files.
-sco32v505udk:
- $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DDCLTIMEVAL -DNOSHADOW -b elf -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 5.0.5 with networking, SCO /bin/cc.
-#See comments with sco32v505 targets.
-sco32v505net:
- @echo TCP/IP networking added...
- $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DNOSHADOW -b elf -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 5.0.5 with networking and OpenSSL, SCO /bin/cc.
-#See comments with sco32v505 targets.
-sco32v505net+ssl:
- @echo TCP/IP networking and OpenSSL added...
- $(MAKE) "MAKE=$(MAKE)" sco32v500net+ssl KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DNOSHADOW -b elf -DPOSIX $(KFLAGS) " \
- "LIBS=$(SSLLIB) -lcurses -lsocket -lssl -lcrypto $(LIBS)" \
- "LNKFLAGS=$(LNKFLAGS)"
-
-#SCO OpenServer 5.0.5 with networking, SCO UDK.
-#See comments with above sco32v505 targets.
-sco32v505udknet:
- @echo TCP/IP networking added...
- $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DDCLTIMEVAL -DNOSHADOW -b elf -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 5.0.5 with gcc, no networking.
-sco32v505gcc:
- @echo Using gcc...
- $(MAKE) "MAKE=$(MAKE)" sco32v500 "CC=gcc" "CC2=gcc" \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DPOSIX -funsigned-char $(KFLAGS)"
-
-#SCO OpenServer 5.0.5 with gcc, no networking, no shadow passwords.
-sco32v505xgcc:
- @echo Using gcc...
- $(MAKE) "MAKE=$(MAKE)" sco32v500 "CC=gcc" "CC2=gcc" \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DNOSHADOW -DPOSIX -funsigned-char $(KFLAGS)"
-
-#SCO OpenServer 5.0.5 with networking, gcc.
-sco32v505netgcc:
- @echo TCP/IP networking added - using gcc...
- @echo If gcc crashes on ckwart.c then build it by hand:
- @echo " gcc -o wart -DCK_SCOV5 ckwart.c"
- $(MAKE) "MAKE=$(MAKE)" sco32v500net "CC=gcc" "CC2=gcc" \
- KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DNOSHADOW -DPOSIX -funsigned-char $(KFLAGS)"
-
-#egcs is just like gcc but generates ELF by default.
-#Or you can include -melf (not -belf) to force it.
-sco32v505netegcs:
- $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" sco32v505netgcc \
- KTARGET=$${KTARGET:-$(@)}
-
-#SCO OpenServer 5.0.5 with networking, gcc, elf.
-sco32v505netgccelf:
- @echo TCP/IP networking added - using gcc, dynamic elf library
- $(MAKE) "MAKE=$(MAKE)" sco32v500net "CC=gcc" "CC2=gcc" \
- "KFLAGS=-DSCO_OSR505 -DPOSIX -funsigned-char -O3 -belf $(KFLAGS)" \
- KTARGET=$${KTARGET:-$(@)} LNKFLAGS="-belf"
-
-#SCO OpenServer 5.0.6 with SCO /bin/cc.
-# Add -DDCLTIMEVAL when building with UDK.
-#Like 5.0.5. IMPORTANT: Use sco32v506a target for 5.0.6a.
-sco32v506:
- $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -b elf -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 5.0.6 with networking, SCO /bin/cc.
-# Add -DDCLTIMEVAL when building with UDK.
-# IMPORTANT: Use sco32v506a target for 5.0.6a.
-sco32v506net:
- @echo TCP/IP networking added...
- $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -b elf -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 5.0.6a, no networking, SCO development tools.
-#This one has patched sio drivers that, for the first time,
-#actually handle modem signals correctly.
-# Add -DDCLTIMEVAL when building with UDK.
-sco32v506a:
- $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -DSCO_OSR506A -DNEEDMDMDEFS \
- -b elf -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 5.0.6a with networking, SCO development tools.
-# Add -DDCLTIMEVAL when building with UDK.
-sco32v506anet:
- @echo TCP/IP networking added...
- $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -DSCO_OSR506A -DNEEDMDMDEFS \
- -b elf -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 5.0.7, no networking, SCO development tools.
-#Adds flags to make PTY and SSH commands work. These have been tested
-#only in 5.0.7 but probably they can also be added to earlier OSR5 targets.
-sco32v507:
- $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -DSCO_OSR507 -DNEEDMDMDEFS \
- -DHAVE_PTSNAME -DHAVE_PTMX -DHAVE_GRANTPT \
- -b elf -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 5.0.7 as above but with networking.
-sco32v507net:
- @echo TCP/IP networking added...
- $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \
- "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -DSCO_OSR507 -DNEEDMDMDEFS \
- -DHAVE_PTSNAME -DHAVE_PTMX -DHAVE_GRANTPT \
- -b elf -DPOSIX $(KFLAGS)"
-
-#SCO OpenServer 6 (new target 30 Jan 2006)
-sco_osr600 sco600:
- @echo Making C-Kermit $(CKVER) for SCO OpenServer 6.0.0...
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -O -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \
- -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \
- -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DTCPSOCKET \
- -DNO_DNS_SRV -DSCO_OSR505 -DSCO_OSR506 -DSCO_OSR507 -DNEEDMDMDEFS \
- -DHAVE_PTSNAME -DHAVE_PTMX -DHAVE_GRANTPT -DDCLTIMEVAL \
- -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
- -DSOCKOPT_T=socklen_t -DGSOCKNAME_T=size_t -DGPEERNAME_T=size_t \
- -DHERALD=\"\\\" SCO OpenServer `uname -v`\\\"\" \
- -b elf -DPOSIX $(KFLAGS)" \
- "LIBS=-lcurses -lsocket $(LIBS)" "LNKFLAGS=$(LNKFLAGS)"
-
-#Tandy 16/6000 with Xenix 3.0 (16 bits)
-#C-Kermit 7.0 (and later) do not build here; "too many defines".
-#Add more -DNOxxx options to remove features if program won't load.
-#Successful operation is a function of program size, physical memory,
-#available swap space, etc. The following stripped-down configuration
-#seems to work on most Tandy 6000s. NOTE: "-+" means allow long variable
-#names, needed for C-Kermit 6.0 because some identifiers are not unique
-#within the first six characters.
-trs16:
- @echo 'Making C-Kermit $(CKVER) for Tandy 16/6000, Xenix 3.0...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -+ -DATTSV -DTRS16 -DNOMKDIR -DDCLPOPEN -DCK_CURSES \
- -DNODEBUG -DNOTLOG -DNOHELP -DNOSCRIPT -DNOCSETS -DNOIKSD \
- -DNOREDIRECT -DNOSYSLOG -DNOPUTENV -DNOREALPATH -DNOLEARN \
- $(KFLAGS) -O" "LIBS= -lcurses -ltermcap" "LNKFLAGS = -+ -n -s"
-
-# QNX 4.21 and above, 32-bit version, Watcom C32 10.6, fully configured,
-# except no job control because QNX 4.x does not support it. New NCURSES
-# library used instead of CURSES.
-#
-# -Oatx optimizes to favor speed over size: loop optimization, inline fn's.
-# -Os favors size over speed. Saves 30-40K out of about 1.75M.
-# -3r = generate 386 code with register-based arg passing.
-# -3s = generate 386 code with stack-based arg passing.
-# -ms = separate code & data 4GB segments (32-bit builds only).
-# -mf = flat memory model code+data in one 4GB segment (ditto).
-# -zc = place literal strings in code segment.
-# -N4M = Big stack (increase the digit upon SIGSEGVs at runtime).
-# chars are unsigned by default (-j makes them signed by default).
-# -NOUUCP is included because QNX doesn't use it.
-# Add these to the end if you like but they dump core on my QNX 4.25 system:
-#
-# @wermit -h >use.qnx
-# @usemsg wermit use.qnx
-# @rm use.qnx
-#
-# If you get warnings about HEADER or C_IN add -DNO_DNS_SRV.
-# OK 2011/06/14
-qnx32:
- @echo 'Making C-Kermit $(CKVER) for QNX 4.2x, 32-bit...'
- $(MAKE) xermit \
- "LNKFLAGS = -N4M -3r" \
- "CFLAGS = -ms -3r -DQNX -DTCPSOCKET -DCK_CURSES -DNOGETUSERSHELL \
- -DCK_WREFRESH -DCK_REDIR -DSELECT -DSELECT_H -DCK_RTSCTS -DNOJC \
- -DNOINITGROUPS -DNOUUCP -DCK_ANSIC -DPID_T=pid_t -Oatx -zc $(KFLAGS)" \
- "LIBS= -lsocket -lncurses -ltermcap"
-
-# As above but no networking since some QNX systems do not have TCP/IP
-# installed, or the TCP/IP developers kit, which includes all the needed
-# header files. This entry has not been tested on a QNX system that, in
-# fact, does not have TCP/IP installed; some adjustments might be necessary,
-# in particular regarding the use of select(): is -lsocket needed, can we
-# get the needed definitions from non-TCP/IP header files (FD_SET, etc)?
-qnx32nonet:
- @echo 'Making C-Kermit $(CKVER) for QNX 4.2x, 32-bit, no net...'
- $(MAKE) xermit \
- "LNKFLAGS = -N4M -3r" \
- "CFLAGS = -3r -ms -DQNX -DNONET -DNOIKSD -DCK_CURSES \
- -DCK_WREFRESH -DCK_REDIR -DSELECT -DSELECT_H -DCK_RTSCTS -DNOJC \
- -DNOUUCP -DCK_ANSIC -DPID_T=pid_t -Oatx -zc $(KFLAGS)" \
- "LIBS= -lsocket -lncurses -ltermcap"
- @wermit -h >use.qnx
- @usemsg wermit use.qnx
- @rm use.qnx
-
-# Synonym for qnx32.
-qnx:
- $(MAKE) qnx32 "KFLAGS=$(KFLAGS)"
-
-# QNX 4.21 and above, 16-bit version, Watcom C 8.5 - and higher on i286 PCs
-# and above.
-#
-# IMPORTANT: Do not use Watcom C 10.6!!!
-# If you have it installed, add "-v9.52 to CFLAGS"
-#
-# NOTE: QNX 4.23 onward does not work on 286's anyway.
-# Stacksize 26000, objects larger than 100 bytes in their own segments,
-# string constants to the codesegment, etc. Fully configured except job ctrl.
-# This entry works for building a 16-bit executable on a 32-bit system, but
-# has not been tested on a 16-bit system. Uses large memory model, links
-# explicitly with large-model sockets library. Correct-model curses library
-# is chosen automatically. See comment in qnx32 entry about -DNOUUCP.
-#
-# WARNING:
-#
-# Watcom C prior to 10.6 never had released curses library. To link against it,
-# you must obtain ported free curses source from ftp://ftp.qnx.com/usr/free,
-# then compile and build library (cursesl.lib) and place it in /usr/lib. You
-# must also copy curses.h to /usr/include. Be aware that if you have Watcom
-# 10.6 installed, you should already have curses.h, which is the new ncurses
-# library. You must back it up and use free curses.h instead, since ncurses is
-# only for 32-bit applications and some definitions in these files are
-# different (e.g., clearok()). For safety, curses is not defined in build.
-#
-# In 7.0 -DNOHELP added to keep ckuus2.c from blowing up; NOCSETS and NOSPL
-# added because ckuus4 was blowing up, and NOFLOAT just because it seemed
-# dangerous (remove -DNOFLOAT if you want to try it), The result works OK
-# except for some mysterious beeps upon termination of the top-level keyword.
-#
-# Things to try next time we get in trouble:
-# . Change -zt100 to something smaller like -zt25
-# . Change -Oatx to -Omilerat (enable stack checking)
-# . Maybe get rid of -v9.52 -- it's only there because we were warned.
-#
-qnx16:
- @echo 'Making C-Kermit $(CKVER) for QNX 4.21, 16-bit...'
- $(MAKE) xermit \
- "LNKFLAGS = -2 -ml -N 26000" \
- "CFLAGS = -2 -Oatx -zc -zt100 -ml -DQNX -DQNX16 -DNOUUCP -DNOHELP \
- -DCK_REDIR -DSELECT -DSELECT_H -DNOJC -DNOGETUSERSHELL -DNOCSETS \
- -v9.52 -DTCPSOCKET -DCK_RTSCTS -DCK_ANSIC -DNOINITGROUPS -DNOKVERBS \
- -DNORANDOM -DNOCSETS -DNOSPL -DNOFLOAT -DPID_T=pid_t $(KFLAGS)"
-
-# QNX 4.1, 16-bit version, with Watcom C 8.5 on i286 PCs and above.
-# stacksize 26000, objects larger than 100 bytes in their own segments,
-# string constants to the codesegment, etc. Add -DNOUUCP if desired.
-qnx16_41:
- @echo 'Making C-Kermit $(CKVER) for QNX 4.1, 16-bit...'
- $(MAKE) xermit \
- "LNKFLAGS = -mh -N 26000" "CFLAGS = -Wc,-fpc -Wc,-j -DNOGETUSERSHELL \
- -Wc,-Ols -Wc,-zdf -Wc,-zc -Wc,-zt100 -mh -DPOSIX -DQNX -DDIRENT \
- -DNOCYRIL -DNODEBUG -DNOMSEND -DMINIDIAL -DNOXMIT -DNOSCRIPT -DNOSPL \
- -DNOSETKEY -DNOINITGROUPS -DQNX16 -DPID_T=pid_t $(KFLAGS)"
-
-# QNX Neutrino 2 (pwaechtler@qnx.de) crosscompiled on QNX 4.25.
-# Gets lots of compiler warnings.
-qnx_nto2+:
- @echo 'Making C-Kermit $(CKVER) for QNX Neutrino 2+ '
- cc -o wart ckwart.c
- $(MAKE) xermit \
- "CC = qcc -Vgcc_ntox86" \
- "CC2 = qcc -Vgcc_ntox86" \
- "LNKFLAGS = " \
- "CFLAGS = -DNEUTRINO -DTCPSOCKET -DCK_CURSES -DNOGETUSERSHELL \
- -DNOUUCP -DCK_WREFRESH -DCK_REDIR -DSELECT -DSELECT_H -DCK_RTSCTS \
- -DNOJC -DNOINITGROUPS -DCK_ANSIC -DPID_T=pid_t -DUNIX -DDIRENT \
- -DMYREAD -DBSD44ORPOSIX -DSVORPOSIX -DNDGPWNAM $(KFLAGS)" \
- "LIBS= -lsocket -lncurses "
-
-# QNX 6 (= Neutrino 2.xx) native build (kirussel@cisco.com).
-qnx6:
- @echo 'Making C-Kermit $(CKVER) for QNX6'
- $(MAKE) xermit KTARGET=QNX6 \
- "CFLAGS = -DPOSIX -DCK_POSIX_SIG -DNETPTY -DNOARROWKEYS \
- -DUSE_TIOCSDTR -DBIGBUFOK -DCKMAXOPEN=100 -DRLOGCODE -DNOREALPATH \
- -DMAXNAMLEN=48 -DQNX6 -DUSE_TERMIO -DINIT_SPTY \
- -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DDYNAMIC \
- -DTCPSOCKET -DNOGETUSERSHELL -DCK_REDIR -DSELECT -DSELECT_H \
- -DCK_RTSCTS -DNOJC -DSVORPOSIX -DBSD44ORPOSIX -DNOUUCP -DCK_ANSIC \
- $(KFLAGS) -O" \
- "LIBS= -lsocket -lncurses"
-
-#MINIX/2.0 32 Bit version for intel 386+ running the POSIX-compliant MINIX
-# version 2.0 (The definition of fatal avoids a conflict with a symbol by
-# the same name in the curses library.) It is impossible to compile with
-# network support since Minix does not support Berkeley sockets.
-# Note: use chmem liberally on the compiler passes, make, and the final
-# kermit executable. (3 megabytes of memory for each is sufficient.)
-# From Terry McConnell, Syracuse U, and Will Rose. Will says:
-# The stacks for make and some compiler passes needed to be increased
-# with chmem as follows:
-# make 1MB
-# /usr/lib/em_cemcom.ansi 3MB
-# /usr/lib/em_opt 1MB
-# /usr/lib/i386/cg 1MB
-# /usr/lib/i386/as 1MB
-# The compiler temporary directory was set to /usr/tmp via the TMPDIR
-# environment variable; more than 1MB of temporary space was needed.
-# Kermit itself needs at least 1MB of stack.
-minix20:
- @echo 'Making C-Kermit $(CKVER) for MINIX 2.0/386...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} EXT=o \
- "CFLAGS= -wo -DV7 -DMINIX2 -DMINIX -DSIG_V -D_POSIX_SOURCE \
- -DCKCPU=\\\"i-386\\\" -DNOIKSD -Dfatal=myfatal -DCK_CURSES -DNOLEARN \
- -DNOSYSLOG -DUSE_MEMCPY -DNOREALPATH $(KFLAGS)" "LIBS= -lcurses"
-
-#MINIX/386 (PC Minix modified by Bruce Evans in Australia for 386 addressing)
-# For MINIX 1.5+ (but < 2.0)
-minix386:
- @echo 'Making C-Kermit $(CKVER) for MINIX/386...'
- @echo 'TOTALLY UNTESTED!'
- $(MAKE) wermit EXT=s KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DV7 -DMINIX -D_POSIX_SOURCE -DNOLEARN $(KFLAGS)"
-
-#MINIX/386 Minix modified by Bruce Evans in Australia to use 386 addressing
-minix386gcc:
- @echo 'Making C-Kermit $(CKVER) for MINIX/386 with gcc...'
- @echo 'TOTALLY UNTESTED!'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC=gcc -g -O" "CC2=gcc -g" \
- "CFLAGS= -DV7 -DMINIX -D_POSIX_SOURCE -DNOLEARN $(KFLAGS)"
-
-#MINIX - 68k version with ACK compiler.
-# If you have trouble compiling or running wart, "touch wart".
-# If it still doesn't work, "touch ckcpro.c".
-# The version configured below has many features removed, including
-# the TRANSMIT, MSEND, HELP, and SCRIPT commands, international
-# character set support, and the entire script programming language.
-# But it does have an interactive command parser.
-# Make sure make(1) has (at least) 100000 chmemory!
-# If you are using the Amsterdam C compiler, you might have to add "-D__ACK__".
-minix68k:
- @echo 'Making C-Kermit $(CKVER) for MINIX 68k with ACK...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DV7 -DMINIX -D_MINIX -D_POSIX_SOURCE -DNOLEARN \
- -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG \
- -DNOSCRIPT -DNOCSETS -DNOSPL $(KFLAGS) \
- -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DSIG_V"
-
-#MINIX - 68k version with c68 compiler.
-# If you have trouble compiling or running wart, "touch wart" or
-# "touch ckcpro.c". Compiling ckudia.c (no -DNODIAL!) might fail. :-(
-# Give c68 250000 bytes of stack+heap; make sure make(1) has at least
-# 100000 chmemory. On a 1MB Atari ST this means that the recursive
-# call of make fails due to memory shortage. Try "make -n minixc68 >makeit",
-# followed by ". makeit". Otherwise, as above.
-minixc68:
- @echo 'Making C-Kermit $(CKVER) for MINIX 68k with c68...'
- $(MAKE) wermit "CC= cc -c68" KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DV7 -DMINIX -D_MINIX -D_POSIX_SOURCE -DNOLEARN \
- -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG \
- -DNOSCRIPT -DNOCSETS -DNOSPL $(KFLAGS) \
- -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DSIG_V"
-
-#MINIX - 68k version with c68 compiler.
-#A variation on the above that was recently (Sep 95) reported to work.
-minixc68a:
- @echo 'Making C-Kermit $(CKVER) for MINIX 68k with c68...'
- $(MAKE) wermit "CC= cc -c68" KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DV7 -DMINIX -D_MINIX -D_POSIX_SOURCE \
- -DCK_ANSIC -DNODEBUG -DNOTLOG -DMINIDIAL -DEXTEN -DMYCURSES \
- -DNOSCRIPT -DNOCSETS -DNOSPL -DNOJC -DDIRENT -DNOLEARN \
- -DNOSETKEY -DNOESCSEQ $(KFLAGS) \
- -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DSIG_V"
-
-#MIPS Computer Systems with UMIPS RISC/OS 4.52 = AT&T UNIX System V R3.0.
-#Remove -DNOJC if job control can be safely used.
-mips:
- @echo 'Making C-Kermit $(CKVER) for MIPS RISC/OS...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DMIPS -DDIRENT -DCK_POLL -DNOJC -DNOLEARN -DPID_T=int \
- -DGID_T=gid_t -DUID_T=uid_t -i -O1500 $(KFLAGS)"
-
-#As above, but with TCP/IP and fullscreen support.
-mipstcpc:
- @echo 'Making C-Kermit $(CKVER) for MIPS RISC/OS...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DMIPS -DDIRENT -DCK_POLL -DNOJC \
- -DTCPSOCKET -DCK_CURSES -I/usr/include/bsd \
- -DPID_T=int -DGID_T=gid_t -DUID_T=uid_t -i -O1500 $(KFLAGS)" \
- "LIBS = -lcurses -lbsd"
-
-#Motorola Delta System V/68 R3, signal() is void rather than int.
-#Uses dirent.h and Honey DanBer uucp. Supports TCP/IP.
-#After building, use "mcs -d" to reduce size of the executable program.
-sv68r3:
- @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/68 R3...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSVR3 -DSV68 -DDIRENT -DHDBUUCP -DNO_DNS_SRV -DTCPSOCKET \
- -DNOUNICODE -DNOLEARN -DUSE_MEMCPY $(KFLAGS) -O" "LNKFLAGS ="
-
-#Motorola Delta System V/68 R3V5, signal() is void rather than int.
-#Uses dirent.h and Honey DanBer UUCP. Supports TCP/IP.
-#After building, use "mcs -d" to reduce size of the executable program.
-sv68r3v5:
- @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/68 R3V5'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSVR3 -DSV68 -DDIRENT -DHDBUUCP -DNO_DNS_SRV -DUSE_MEMCPY \
- -DTCPSOCKET -DINADDRX -DNOUNICODE -DFNFLOAT -DNOLEARN $(KFLAGS) -O" \
- "LNKFLAGS =" "LIBS = -linet -lm"
-
-#Motorola MVME147 System V/68 R3 V5.1. Requires gcc 2.1 to compile.
-#After building, use "mcs -d" to reduce size of the executable program.
-sv68r3v51:
- @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/68 R3V5.1'
- $(MAKE) wermit "CC=gcc-delta" "CC2=gcc-delta" \
- KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DNODEBUG -DNO_DNS_SRV -DNOLEARN \
- -DNOUNICODE -DFNFLOAT -DSV68 -DUSE_MEMCPY $(KFLAGS) \
- -O2 -v -ftraditional" \
- "LNKFLAGS = -s -v" "LIBS = -lm881 -lm"
-
-#Motorola MVME147 System V/68 R3V6. derived from Motorola Delta System R3V5.
-#Checked on larger Motorola System V/68 R3V6 (with NSE Network Services Ext.)
-#After building, use "strip" to reduce size of the executable program.
-# "LIBS = -lnsl" removed in C-Kermit 6.1 - put back if needed.
-# "LIBS = lm" added in 7.1/8.0 for floating-point math.
-# ckuusr.c clobbers the optimizer.
-sv68r3v6:
- @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/68 R3V6'
- $(MAKE) ckuusr.$(EXT) KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSV68R3V6 -DDIRENT -DHDBUUCP -DNOLOGIN -DNOINITGROUPS \
- -DNOSYMLINK -DNOREDIRECT -DNOGFTIMER -DTCPSOCKET -DDCLGETCWD -DSV68 \
- -DNO_DNS_SRV -DNOUNICODE -DFNFLOAT -DSELECT -DUSE_MEMCPY $(KFLAGS)"
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSV68R3V6 -DDIRENT -DHDBUUCP -DNOLOGIN -DNOINITGROUPS \
- -DNOSYMLINK -DNOREDIRECT -DNOGFTIMER -DTCPSOCKET -DDCLGETCWD -DSV68 \
- -DNO_DNS_SRV -DNOUNICODE -DFNFLOAT -DSELECT -DUSE_MEMCPY $(KFLAGS)" \
- "LNKFLAGS =" "LIBS = -lm"
-
-#Motorola Delta System V/88 R32, signal() is void rather than int.
-#Uses dirent.h and Honey DanBer uucp. Needs <sys/utime.h> for setting
-#file dates. Supports TCP/IP.
-#After building, use "mcs -d" to reduce size of the executable program.
-sv88r32:
- @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/88 R32...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -DSV88R32 -DDIRENT -DHDBUUCP -DTCPSOCKET \
- -DSYSUTIMEH -DCK_CURSES -DNOGETUSERSHELL -DGTODONEARG $(KFLAGS) -O" \
- "LIBS= -lcurses -lresolv" "LNKFLAGS = -s"
-
-#Motorola Delta System V/88 R40. Has <sys/termiox.h>, regular Berkeley
-#sockets library, i.e. in.h and inet.h are not misplaced in sys (rather than
-#netinet and arpa, respectively). Uses ANSI C constructs, advisory file
-#locking on devices, etc. curses support added. Reportedly, the
-#/usr/include/sys/vnode.h file has a bug which must be fixed before this
-#makefile entry can work correctly. The "if DEBUG" directive at about line
-#320 must be changed to "ifdef DEBUG" (Reportedly, this was fixed in
-#in System V/88 R4.3).
-#After building, use "mcs -d" to reduce size of the executable program.
-sv88r40:
- @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/88 R40...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DMOTSV88R4 -DDIRENT -DHDBUUCP -DSTERMIOX \
- -DTCPSOCKET -DCK_CURSES -DNOGETUSERSHELL -DGTODONEARG -DFNFLOAT \
- $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -lresolv -lm" "LNKFLAGS = -s"
-
-#As above but without the floating-point math library.
-sv88r40nm:
- @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/88 R40...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS = -O -DSVR4 -DMOTSV88R4 -DDIRENT -DHDBUUCP -DSTERMIOX \
- -DTCPSOCKET -DCK_CURSES -DNOGETUSERSHELL -DGTODONEARG $(KFLAGS)" \
- "LIBS= -lsocket -lnsl -lcurses -lresolv" "LNKFLAGS = -s"
-
-#As above but with floating-point math library support \ffp...() functions
-#and S-Expressions.
-
-#Olivetti X/OS R2.3, 3.x.
-#NOTES:
-# . If you build the executable on 2.x X/OS, it will also run on 3.x.
-# . If you build it on 3.x X/OS, it will NOT run on 2.x.
-# . Kermit can run with no privileges unless the uucp lines are protected,
-# in which case kermit must be owned by uucp with suid bit set:
-# chown uucp kermit ; chmod 4111 kermit.
-xos23:
- @echo 'Making C-Kermit $(CKVER) for Olivetti X/OS...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- 'CFLAGS=-OLM -DOXOS -DTCPSOCKET -DHDBUUCP $(KFLAGS)' \
- "LIBS=" "LNKFLAGS="
-
-#As above, but with curses.
-xos23c:
- @echo 'Making C-Kermit $(CKVER) for Olivetti X/OS with curses...'
- $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \
- 'CFLAGS=-OLM -DOXOS -DTCPSOCKET -DHDBUUCP -DCK_CURSES $(KFLAGS)' \
- "LIBS=-lcurses" "LNKFLAGS="
-
-ckuuid:
- @echo 'building C-Kermit $(CKVER) set-UID/set-GID test programs'
- $(CC) -DANYBSD -DSAVEDUID -o ckuuid1 ckuuid.c
- $(CC) -DANYBSD -o ckuuid2 ckuuid.c
- $(CC) -DANYBSD -DNOSETREU -o ckuuid3 ckuuid.c
- $(CC) -DANYBSD -DSETEUID -DNOSETREU -o ckuuid4 ckuuid.c
- $(CC) -o ckuuid5 ckuuid.c
- @echo 'Read the top of ckuuid.c for directions...for testing'
- @echo 'you must make these programs setuid and setgid'
-
-############################################################################
-# A N T I Q U I T I E S
-#
-# The following are antique targets from C-Kermit 5A or earlier. They have
-# not been updated or tested in years. Most of them will need recent features
-# disabled, usually with some combination of -DNOUNICODE, -DNOIKSD, -DNOANSI,
-# -DNOCKGHNLHOST, -DNO_DNS_SRV, -DNOREDIRECT, -DNOREALPATH, -DNOCURSES, etc.
-# They are also missing the KTARGET=$${KTARGET:-$(@)} business.
-# For details see ckuins.txt and ckccfg.txt.
-#
-############################################################################
-
-#Berkeley Unix 2.8, 2.9 for PDP-11s with I&D space, maybe also Ultrix-11???
-#C-Kermit(5A) is simply too large (even turning off almost every feature
-#available) to run without both I&D space plus overlays. The old comment
-#suggested running 'pcc' but that won't help. Changing 'cc' to 'ckustr.sed'
-#will cause a string extraction to be done, saving D space by moving strings
-#to a file.
-bsd29:
- @echo Making C-Kermit $(CKVER) for 2.8 or 2.9BSD.
- @echo Read the makefile if you have trouble with this...
- $(MAKE) ovwermit \
- "CFLAGS= -DBSD29 -DNODEBUG -DNOTLOG -DNOCSETS -DNOHELP \
- -DNOSCRIPT -DNOSPL -DNOXMIT -DNODIAL $(KFLAGS)" \
- "LNKFLAGS= -i -lndir" "CC= cc " "CC2= cc"
-
-bsd210:
- @echo Please use ckubs2.mak to build C-Kermit $(CKVER) for 2.10BSD.
-
-bsd211:
- @echo Please use ckubs2.mak to build C-Kermit $(CKVER) for 2.11BSD.
-
-#Charles River Data Systems Universe with UNOS Version 9.2
-crds:
- @echo 'Making C-Kermit $(CKVER) for Charles River Data Systems...'
- make xermit \
- "CFLAGS = -DATTSV -DNOANSI -DDIRENT -DLONGFN -DTCPSOCKET \
- -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DNOSETREU \
- -Dsuspend=ksuspend $(KFLAGS) -O" "LNKFLAGS ="
-
-#Microport SV/AT for IBM PC/AT 286 and clones, System V R2.
-#The -O flag may fail on some modules (like ckuus2.c), in which case you
-#should compile them by hand, omitting the -O. If you get "hash table
-#overflow", try adding -DNODEBUG.
-#Also, reportedly this compiles better with gcc than with cc.
-mpsysv:
- @echo 'Making C-Kermit $(CKVER) for Microport SV/AT 286...'
- $(MAKE) wermit \
- "CFLAGS= -DATTSV -DNOLEARN $(KFLAGS) -O -Ml" "LNKFLAGS = -Ml"
-
-#Microsoft "Xenix/286" e.g. for IBM PC/AT
-xenix:
- @echo 'Making C-Kermit $(CKVER) for Xenix/286'
- $(MAKE) wermit \
- "CFLAGS= -DXENIX -DNOFILEH -DNOLEARN $(KFLAGS) -Dunix -F 3000 -i" \
- "LNKFLAGS = -F 3000 -i"
-
-#PC/IX, Interactive Corp System III for IBM PC/XT
-pcix:
- @echo 'Making C-Kermit $(CKVER) for PC/IX...'
- $(MAKE) wermit \
- "CFLAGS= -DPCIX -DISIII -DNOLEARN $(KFLAGS) \
- -Dsdata=sdatax -O -i" "LNKFLAGS = -i"
-
-#Integrated Solutions Inc V8S VME 68020
-isi:
- @echo Making C-Kermit $(CKVER) for 4.2BSD on ISI...
- $(MAKE) wermit "CC = cc" \
- "CFLAGS= -DBSD4 -DTCPSOCKET -DINADDRX -DDCLPOPEN -DDEBUG -DNOSETREU \
- -DCK_CURSES -DNOLEARN $(KFLAGS)" "LIBS = -lcurses -ltermcap"
-
-#Interactive Corp version of AT&T System III
-#is3: (very old, probably not sufficient for 5A or later)
-# @echo 'Making C-Kermit $(CKVER) for Interactive System III...'
-# make wermit "CFLAGS = -DISIII -Ddata=datax -O -i" "LNKFLAGS = -i"
-#The following should work, use it if you don't have gcc.
-#Use is3gcc if you have gcc.
-is3:
- @echo 'Making C-Kermit $(CKVER) for Interactive System III...'
- $(MAKE) wermit \
- "CFLAGS= -DISIII $(KFLAGS) -Ddata=datax -DNAP -DHDBUUCP
- -DLOCK_DIR=\"/usr/spool/uucp\" -DSIGTYP=void -O -i" "LNKFLAGS = -i"
-
-#Interactive UNIX System V R3, no network support. Uses <dirent.h> and Honey
-#DanBer UUCP. If this entry does not compile correctly, try any or all of the
-#following. These suggestions also apply more or less to the other is5r3xxx
-#entries that follow this one.
-# . Remove the UID_T and GID_T definitions, or change them as required.
-# . Change -DDIRENT to -DSDIRENT.
-# . Add -DSIGTYP=void.
-# . Remove -g from LNKFLAGS.
-# . Add -DNOANSI to remove compiler complaints about ANSI C constructions
-# . Add other -DNOxxx's to save space (e.g. -DNOCSETS)
-# See the next few makefile entries for related examples.
-# Also see sys5r32is for making a portable i386 SVR3 binary.
-is5r3:
- @echo 'Making C-Kermit $(CKVER) for Interactive 386/ix or later...'
- @echo 'If this does not work please read the makefile entry.'
- $(MAKE) wermit \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -g -DNOCSETS -DNOREALPATH \
- -DUID_T=ushort -DGID_T=ushort -DI386IX $(KFLAGS)" \
- "LNKFLAGS = -g"
-
-#Interactive Corp System System V R3 with gcc
-is3gcc:
- @echo 'Making C-Kermit $(CKVER) for Interactive System V R3 / gcc...'
- $(MAKE) wermit CC=gcc CC2=gcc \
- 'CFLAGS = -D_SYSV3 -DISIII -Ddata=datax -DNAP -DHDBUUCP -DNOREALPATH \
- -DLOCK_DIR=\"/usr/spool/uucp\" -DSIGTYP=void -O' "LNKFLAGS ="
-
-#Interactive UNIX System V R3, POSIX variant. Untested.
-#Uses dirent.h and Honey DanBer uucp. Read comments in is5r3 entry.
-is5r3p:
- @echo 'Making C-Kermit $(CKVER) for Interactive 386/ix or later...'
- $(MAKE) wermit \
- "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -g -DNOCSETS -DNOREALPATH \
- -DI386IX -DPOSIX $(KFLAGS)" "LNKFLAGS=" "LIBS=-lcposix"
-
-#Interactive UNIX SVR3 2.2.1, job control, curses, no net, gcc.
-is5r3gcc:
- $(MAKE) wermit CC=gcc CC2=gcc \
- "CFLAGS=-g -posix -DSVR3 -DDIRENT -DNOREALPATH \
- -DHDBUUCP -O -DNOCSETS -DI386IX -DSVR3JC -DCK_CURSES \
- $(KFLAGS)" LNKFLAGS="-posix" LIBS="-lcurses -lc_s"
-
-#Interactive UNIX System V R3 with TCP/IP network support.
-#Needs -linet for net functions. signal() is void rather than int.
-#Uses dirent.h and Honey DanBer uucp. Read comments in is5r3 entry.
-#Also see is5r3net2 if you have trouble with this entry.
-is5r3net:
- @echo 'Making C-Kermit $(CKVER) for Interactive 386/ix...'
- @echo 'If this does not work please read the makefile entry.'
- $(MAKE) wermit CC="$(CC)" CC2="$(CC2)" \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DTCPSOCKET -DNOREALPATH \
- -DI386IX $(KFLAGS) -O" "LIBS = -linet"
-
-is5r3netgcc:
- $(MAKE) is5r3net CC=gcc CC2=gcc
-
-#Interactive UNIX System V R3, no job control, signal() void rather than int.
-#Uses dirent.h and Honey DanBer uucp. Needs -linet for net functions.
-#Read comments in is5r3 entry. Use this entry if is5r3net fails.
-#Saves some space by stripping (-s) and using shared library (-lc_s).
-is5r3net2:
- @echo 'Making C-Kermit $(CKVER) for Interactive 386/ix...'
- $(MAKE) wermit \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DTCPSOCKET -DNOJC -DNOREALPATH \
- -DSIGTYP=void -DNOANSI -DI386IX $(KFLAGS) -O" \
- "LNKFLAGS= -s" "LIBS = -linet -lc_s"
-
-#Interactive UNIX System V R3 (version 2.2 or later) with job control & curses.
-#Uses dirent.h and Honey DanBer UUCP.
-is5r3jc:
- @echo 'Making C-Kermit $(CKVER) for Interactive Unix 2.2 or later...'
- $(MAKE) wermit CC="$(CC)" CC2="$(CC2)" \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -O -DNOCSETS -DNOREALPATH \
- -DUID_T=ushort -DGID_T=ushort -DI386IX -DSVR3JC -DCK_CURSES \
- -DPOSIX_JC -DCK_REDIR -DCK_POLL -DDCLGETCWD \
- $(KFLAGS)" "LIBS=-lcurses -lc_s -linet"
-
-is5r3jcgcc:
- $(MAKE) is5r3jc CC="gcc -DCK_ANSILIBS -DDCGPWNAM -O4" CC2=gcc \
- KFLAGS="$(KFLAGS)" LNKFLAGS="$(LNKFLAGS)"
-
-#Sunsoft/Interactive UNIX System V R3 (version 2.2 or later)
-#with job control, curses, and TCP/IP networking.
-#Uses dirent.h and Honey DanBer UUCP.
-is5r3netjc:
- @echo 'Making C-Kermit $(CKVER) for Interactive Unix 2.2 or later...'
- $(MAKE) wermit CC="$(CC)" CC2="$(CC2)" \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -O -DNOCSETS -DNOREALPATH \
- -DUID_T=ushort -DGID_T=ushort -DI386IX -DSVR3JC -DCK_CURSES \
- -DPOSIX_JC -DCK_REDIR -DTCPSOCKET -DSELECT \
- $(KFLAGS)" "LIBS=-linet -lcurses -lc_s"
-
-is5r3netjcgcc:
- $(MAKE) is5r3netjc CC="gcc -DCK_ANSILIBS -DDCGPWNAM -O4" CC2=gcc \
- KFLAGS="$(KFLAGS)" LNKFLAGS="$(LNKFLAGS)"
-
-#Masscomp System III
-rtu:
- @echo 'Making C-Kermit $(CKVER) for Masscomp RTU System III...'
- $(MAKE) wermit \
- "CFLAGS= -UFIONREAD -DATTSV $(KFLAGS) -O" "LNKFLAGS =" "LIBS= -ljobs"
-
-#Masscomp/Concurrent RTU 4.0 or later, Berkeley environment.
-#Includes <ndir.h> = /usr/include/ndir.h
-#Note "LIBS = -lndir" might not be necessary because of "ucb make".
-rtubsd:
- @echo 'Making C-Kermit $(CKVER) for Masscomp RTU 4.1A...'
- ucb make wermit \
- "CFLAGS= -DBSD4 -DRTU -DNDIR -DHDBUUCP -DTCPSOCKET $(KFLAGS)" \
- "LIBS = -lndir"
-
-#Masscomp/Concurrent RTU 4.0 or later, same as above,
-#Includes "usr/lib/ndir.h"
-#Note "LIBS = -lndir" might not be necessary because of "ucb make".
-rtubsd2:
- @echo 'Making C-Kermit $(CKVER) for Masscomp RTU 4.1A...'
- ucb make wermit \
- "CFLAGS= -DBSD4 -DRTU -DXNDIR -DHDBUUCP $(KFLAGS)" \
- "LIBS = -lndir"
-
-#Masscomp/Concurrent RTU 4.0 or later, same as above,
-#Includes <sys/ndir.h>
-#Note "LIBS = -lndir" might not be necessary because of "ucb make".
-rtubsd3:
- @echo 'Making C-Kermit $(CKVER) for Masscomp RTU 4.x BSD...'
- ucb make wermit "CFLAGS= -DBSD4 -DRTU -DHDBUUCP $(KFLAGS)" \
- "LIBS = -lndir"
-
-#Masscomp/Concurrent RTU 4.0 or later, System V R2, using <dirent.h>.
-#In case of problems, add back the -DRTU switch.
-#In case -DTCPSOCKET gives trouble, remove it.
-rtus5:
- @echo 'Making C-Kermit $(CKVER) for Masscomp RTU 4.x...'
- $(MAKE) wermit \
- "CFLAGS= -DATTSV -DHDBUUCP -DDIRENT -DTCPSOCKET $(KFLAGS)"
-
-#Masscomp/Concurrent RTU 4.x, System V R3, using <dirent.h>.
-#Use this one if rtus5 gives warnings about pointer type mismatches.
-#In case of problems, add back the -DRTU switch.
-rtus5r3:
- @echo 'Making C-Kermit $(CKVER) for Masscomp RTU Sys V R3...'
- $(MAKE) wermit "CFLAGS= -DSVR3 -DHDBUUCP -DDIRENT $(KFLAGS)"
-
-#DEC Pro-3xx with Pro/Venix V1.0 or V1.1
-# Requires code-mapping on non-I&D-space 11/23 processor, plus some
-# fiddling to get interrupt targets into resident code section.
-# This almost certainly doesn't work any more.
-provx1:
- @echo 'Making C-Kermit $(CKVER) for DEC Pro-3xx, Pro/Venix 1.x...'
- $(MAKE) wart "CFLAGS= -DPROVX1 $(KFLAGS)" "LNKFLAGS= "
- $(MAKE) wermit "CFLAGS = -DPROVX1 -DNOFILEH -md780" \
- "LNKFLAGS= -u _sleep -lc -md780"
-
-#Nixdorf Targon/31.
-#AT&T UNIX System V R3, signal() is void rather than int.
-#Uses dirent.h without Honey DanBer uucp.
-t31tos40x:
- @echo 'Making C-Kermit $(CKVER) for Targon/31 with TOS 4.0.xx...'
- $(MAKE) wermit \
- "CFLAGS= -DSVR3 -DDIRENT $(KFLAGS) -O" \
- "LNKFLAGS="
-
-#NCR Tower 1632, OS 1.02
-tower1:
- @echo 'Making C-Kermit $(CKVER) for NCR Tower 1632, OS 1.02...'
- $(MAKE) wermit "CFLAGS= -DTOWER1 $(KFLAGS)"
-
-#NCR Tower 32, OS Release 1.xx.xx
-tower32-1:
- @echo 'Making C-Kermit $(CKVER) for NCR Tower 32 Rel 1 System V R2...'
- @echo 'Add KFLAGS=-DISDIRBUG if you get errors about S_ISREG/S_ISDIR.'
- $(MAKE) wermit \
- "CFLAGS = -DATTSV $(KFLAGS) -O" "LNKFLAGS = -n"
-
-#NCR Tower 32, OS Release 2.xx.xx
-tower32-2:
- @echo 'Making C-Kermit $(CKVER) for NCR Tower 32 Rel 2 System V R2...'
- $(MAKE) wermit \
- "CFLAGS = -DATTSV -DHDBUUCP $(KFLAGS) -O2" \
- "LNKFLAGS = -n"
-
-#NCR Tower 32, OS Releases based on System V R3
-#Don't add -DNAP (doesn't work right) or -DRDCHK (not available in libc).
-tower32:
- @echo 'Making C-Kermit $(CKVER) for NCR Tower 32 System V R3...'
- $(MAKE) wermit \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DNOSYSIOCTLH $(KFLAGS) \
- -DUID_T=ushort -DGID_T=ushort -O1"
-
-#NCR Tower 32, OS Releases based on System V R3
-tower32g:
- @echo 'Making C-Kermit $(CKVER) for NCR Tower 32 System V R3, gcc...'
- $(MAKE) wermit "CC = gcc" \
- "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DNOSYSIOCTLH $(KFLAGS) \
- DUID_T=ushort -DGID_T=ushort -O -fstrength-reduce -fomit-frame-pointer"
-
-#Fortune 32:16, For:Pro 1.8 (mostly like 4.1bsd)
-ft18:
- @echo 'Making C-Kermit $(CKVER) for Fortune 32:16 For:Pro 1.8...'
- $(MAKE) wermit \
- "CFLAGS= -DNODEBUG -DBSD4 -DFT18 -DNOFILEH $(KFLAGS) \
- -DPID_T=short"
-
-#Fortune 32:16, For:Pro 2.1 (mostly like 4.1bsd).
-#The modules that break the optimizer are compiled separately.
-ft21:
- @echo 'Making C-Kermit $(CKVER) for Fortune 32:16 For:Pro 2.1...'
- $(MAKE) ckuusx.$(EXT) "CFLAGS= -DNODEBUG -DBSD4 -DFT21 -DNOFILEH \
- -SYM 800 -DCK_CURSES $(KFLAGS) -DPID_T=short" \
- "LNKFLAGS= -n -s" "LIBS= -lcurses -ltermcap -lv -lnet"
- $(MAKE) ckuxla.$(EXT) "CFLAGS= -DNODEBUG -DBSD4 -DFT21 -DNOFILEH \
- -SYM 800 -DCK_CURSES $(KFLAGS) -DPID_T=short" \
- "LNKFLAGS= -n -s" "LIBS= -lcurses -ltermcap -lv -lnet"
- $(MAKE) ckudia.$(EXT) "CFLAGS= -DNODEBUG -DBSD4 -DFT21 -DNOFILEH \
- -SYM 800 -DCK_CURSES $(KFLAGS) -DPID_T=short" \
- "LNKFLAGS= -n -s" "LIBS= -lcurses -ltermcap -lv -lnet"
- $(MAKE) wermit \
- "CFLAGS= -O -DNODEBUG -DBSD4 -DFT21 -DNOFILEH -SYM 800 \
- -DCK_CURSES $(KFLAGS) -DPID_T=short" \
- "LNKFLAGS= -n -s" "LIBS= -lcurses -ltermcap -lv -lnet"
-
-#Valid Scaldstar
-#Berkeleyish, but need to change some variable names.
-valid:
- @echo 'Making C-Kermit $(CKVER) for Valid Scaldstar...'
- $(MAKE) wermit \
- "CFLAGS= -DBSD4 -DNODEBUG -DNOTLOG -Dcc=ccx -DFREAD=1 $(KFLAGS)"
-
-#IBM IX/370 on IBM 370 Series mainframes
-#Mostly like sys3, but should buffer packets.
-ix370:
- @echo 'Making C-Kermit $(CKVER) for IBM IX/370...'
- $(MAKE) wermit "CFLAGS = -DIX370 -DATTSV $(KFLAGS) -i -O" \
- "LNKFLAGS = -i"
-
-#Amdahl UTS 2.4 on IBM 370 series compatible mainframes.
-#Mostly like V7, but can't do initrawq() buffer peeking.
-uts24:
- @echo 'Making C-Kermit $(CKVER) for Amdahl UTS 2.4...'
- $(MAKE) wermit "CFLAGS=-DV7 -DPROCNAME=\\\"$(PROC)\\\" \
- -DUTS24 -DBOOTNAME=\\\"$(BOOTFILE)\\\" -DNPROCNAME=\\\"$(NPROC)\\\" \
- -DNPTYPE=$(NPTYPE) $(DIRECT) $(KFLAGS)"
-
-#Amdahl UTSV UNIX System V = System V R2 or earlier.
-utsv:
- @echo 'Making C-Kermit $(CKVER) for Amdahl UTSV...'
- $(MAKE) wermit \
- "CFLAGS = -DUTSV $(KFLAGS) -i -O" "LNKFLAGS = -i"
-
-#Amdahl UTSV UNIX System V = System V R2 or earlier, with TCP sockets library.
-utsvtcp:
- @echo 'Making C-Kermit $(CKVER) for Amdahl UTSV w/tcp...'
- $(MAKE) wermit "CFLAGS = \
- -DTCPSOCKET -DUTSV $(KFLAGS) -i -O" "LNKFLAGS = -i" \
- "LIBS = -lsocket"
-
-#BBN C/70 with IOS 2.0
-#Mostly Berkeley-like, but with some ATTisms
-c70:
- @echo 'Making C-Kermit $(CKVER) for BBN C/70 IOS 2.0...'
- $(MAKE) wermit "CFLAGS= -DBSD4 -DC70 $(KFLAGS)"
-
-#Zilog ZEUS 3.21
-zilog:
- @echo 'Making C-Kermit $(CKVER) for Zilog Zeus 3.21...'
- $(MAKE) wermit \
- "CFLAGS = -DATTSV -DZILOG -DNODEBUG $(KFLAGS) -i -O" \
- "LNKFLAGS = -i -lpw"
-
-#Whitechapel MG-1 Genix 1.3
-white:
- @echo 'Making C-Kermit $(CKVER) for Whitechapel MG-1 Genix 1.3...'
- @touch ckcpro.c
- $(MAKE) wermit "CFLAGS= -DBSD4 -Dzkself()=0 $(KFLAGS)"
-
-#Pixel 1000
-pixel:
- @echo 'Making C-Kermit $(CKVER) for Pixel 1000...'
- $(MAKE) wermit "CFLAGS= -DBSD4 -Dzkself()=0 $(KFLAGS)"
-
-ptx:
- $(MAKE) "MAKE=$(MAKE)" dynixptx12
-
-#CDC VX/VE 5.2.1
-vxve:
- @echo 'Making C-Kermit $(CKVER) for CDC VX/VE 5.2.1...'
- $(MAKE) wermit \
- "CFLAGS = -DATTSV -DVXVE -DNODEBUG -DNOTLOG $(KFLAGS) -i -O" \
- "LNKFLAGS = -i"
-
-#DIAB DS90 or LUXOR ABC-9000 with pre-5.2 DNIX. Sys V with nap() and rdchk().
-# nd = no opendir(), readdir(), closedir(), etc.
-# Some of the modules fail to compile with -O.
-dnixnd:
- @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with very old DNIX 5.2.'
- $(MAKE) wermit \
- "CFLAGS = -DATTSV -DNAP -DRDCHK -DDCLPOPEN \
- -U__STDC__ $(KFLAGS)"
-
-#DIAB DS90 with DNIX 5.2. Sys V with nap() and rdchk().
-# This one has opendir(), readdir(), closedir(), etc.
-# Some of the modules fail to compile with -O.
-dnix:
- @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with old DNIX 5.2...'
- $(MAKE) wermit \
- "CFLAGS = -DATTSV -DNAP -DRDCHK -DDIRENT \
- -U__STDC__ $(KFLAGS)"
-
-#DIAB DS90 with DNIX 5.2. Sys V with nap() and rdchk().
-# As above, but with curses and TCP/IP.
-# You might get complaints about redefinition of O_RDONLY, etc, because
-# of bugs in the DNIX header files, which can be fixed by adding #ifndef...
-# around the offending definitions in the header files.
-dnixnetc:
- @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with old DNIX 5.2...'
- $(MAKE) wermit \
- "CFLAGS = -DATTSV -DNAP -DRDCHK -DDIRENT \
- -DTCPSOCKET -DCK_CURSES -I/usr/include/bsd -U__STDC__ $(KFLAGS)" \
- "LIBS = -ln -lcurses"
-
-#DIAB DS90 with DNIX 5.3 or later, with HDB UUCP, nap() and rdchk().
-dnix5r3:
- @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with DNIX 5.3...'
- @echo 'with Honey DanBer UUCP'
- $(MAKE) wermit \
- "CFLAGS = -DSVR3 -DHDBUUCP -DNAP -DRDCHK -DDIRENT \
- -DCK_CURSES -DRENAME $(KFLAGS) -O" "LIBS= -lcurses"
-
-#DIAB DS90 with DNIX 5.3 or later, with HDB UUCP, nap() and rdchk() + TCP/IP
-dnix5r3net:
- @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with DNIX 5.3...'
- @echo 'with Honey DanBer UUCP and TCP/IP'
- $(MAKE) wermit \
- "CFLAGS = -DSVR3 -DHDBUUCP -DNAP -DRDCHK -DDIRENT \
- -DTCPSOCKET -DCK_CURSES -DRENAME $(KFLAGS) -O \
- -I/usr/include/bsd" "LIBS = -ln -lcurses"
-
-#DIAB DS90 with DNIX 5.3 2.2 or later, with HDB UUCP, nap() and rdchk(),
-#ANSI C compilation and libraries.
-#Note that for DNIX 5.3 2.2 you have to correct a bug in /usr/include/stdlib.h:
-#change "extern void free(char *str);"
-#to "extern void free(void *str);"
-#NOTE: This bug is reportedly fixed in DNIX 5.3 2.2.1.
-#Should you get fatal errors caused by harmless pointer-type mismatches,
-#like between signed and unsigned char, just remove -X7.
-dnix5r3ansi:
- @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with DNIX 5.3...'
- @echo 'with ANSI C Honey DanBer UUCP'
- $(MAKE) wermit \
- "CFLAGS = -DSVR3 -DDIAB -DHDBUUCP -DNAP -DRDCHK -DDIRENT \
- -DCK_ANSILIBS -DCK_CURSES -DRENAME -O -X7 -X9 $(KFLAGS)" \
- "LIBS= -lcurses"
-
-#DIAB DS90 with DNIX 5.3 2.2 or later, with HDB UUCP, nap() and rdchk(),
-# + TCP/IP, ANSI C compilation and libraries.
-#Should you get fatal errors caused by harmless pointer-type mismatches,
-#like between signed and unsigned char, just remove -X7.
-dnix5r3ansinet:
- @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with DNIX 5.3...'
- @echo 'with ANSI C Honey DanBer UUCP'
- $(MAKE) wermit \
- "CFLAGS = -DSVR3 -DDIAB -DHDBUUCP -DNAP -DRDCHK -DDIRENT \
- -DTCPSOCKET -DCK_ANSILIBS -DCK_CURSES -DRENAME -O -X7 -X9 $(KFLAGS) \
- -I/usr/include/bsd" "LIBS= -ln -lcurses"
-
-#Ridge 32 with ROS 3.2
-ridge32:
- @echo 'Making C-Kermit $(CKVER) Ridge 32 ROS 3.2'
- $(MAKE) wermit \
- "CFLAGS = -DATTSV -DNOFILEH -DNODEBUG -DNOTLOG $(KFLAGS) -i -O" \
- "LNKFLAGS = -i"
-
-#Altos 486, 586, or 986 with Xenix 3.0
-altos:
- @echo 'Making C-Kermit $(CKVER) for Altos x86 with Xenix 3.0...'
- $(MAKE) wermit \
- "CFLAGS= -DATTSV -DA986 -DNODEBUG -DNOTLOG $(KFLAGS) -i -O" \
- "LNKFLAGS= -i"
-
-#Altos 986 with Xenix 3.0, as above, but command-line only, minimal size.
-#For systems with small memories. It might also be necessary to chop certain
-#modules up into smaller pieces, e.g. ckuus3-6, because of symbol table
-#overflow. If this makefile is too big or complex for the Altos, compile
-#and link by hand or write shell scripts.
-altosc:
- @echo 'Making C-Kermit $(CKVER) for Altos x86 Xenix 3.0, remote...'
- $(MAKE) wermit \
- "CFLAGS= -DATTSV -DA986 -DNODEBUG -DNOTLOG -DNOSCRIPT -DNODIAL \
- -DNOCSETS -DNOANSI -DNOMSEND -DNOSPL -DNOICP $(KFLAGS) -Mm -O" \
- "LNKFLAGS= -Mm -s"
-
-#Altos 986 with Xenix 3.0, as above, but interactive only, minimal size.
-altosi:
- @echo 'Making C-Kermit $(CKVER) for Altos x86 Xenix 3.0, local...'
- $(MAKE) wermit \
- "CFLAGS= -DATTSV -DA986 -DNODEBUG -DNOTLOG -DNOSCRIPT -DNODIAL \
- -DNOCSETS -DNOANSI -DNOMSEND -DNOSPL -DNOCMDL -DNOFRILLS -DNOHELP \
- -DNOSETKEY $(KFLAGS) -Mm -O" "LNKFLAGS= -Mm -s"
-
-# Altos ACS68000 68000 System, UNIX System 3 Release 2, 512k memory.
-# also needs getcwd() external function; see ckuins.txt file.
-# also, sys/types.h needed modifying:
-# #ifdef __SYS_TYPES_H__, #define ..., #endif
-# also, ckuus2.c MUST be compiled NOOPT else symbol table is destroyed!
-# Submission by Robert Weiner/Programming Plus, rweiner@progplus.com.
-#
-altos3:
- @echo 'Making C-Kermit $(CKVER) for Altos ACS68k UNIX System III'
- $(MAKE) ckuus2.$(EXT) "CFLAGS = -DATTSV -DNOCSETS -DNOSETKEY -DNOJC \
- -DNODIAL -DDCLPOPEN -DNOSCRIPT -DNOHELP $(KFLAGS) -i"
- $(MAKE) wermit \
- "CFLAGS = -DATTSV -DNOCSETS -DNOSETKEY -DNOJC \
- -DNODIAL -DDCLPOPEN -DNOSCRIPT -DNOHELP $(KFLAGS) -i -O" \
- "LNKFLAGS = -i" "LIBS = getcwd.$(EXT)"
-
-#MINIX - Original PC version with 64K+64K limit.
-# Reportedly, the linker (asld) can run out of space while linking. The only
-# way around this is to make a copy of libc.a from which all modules that are
-# not used by Kermit are removed. If you have trouble compiling or running
-# wart, "touch wart". If that doesn't help, "touch ckcpro.c".
-# The version configured below has no interactive command parser.
-# If you can build this version successfully, maybe there will be room for
-# a minimal interactive command parser too; try replacing -DNOICP with
-# -DNOSPL, plus every other -DNOxxx flag there is, except for -DNOICP
-# (see ckccfg.txt).
-minix:
- @echo 'Making C-Kermit $(CKVER) for MINIX, no command parser...'
- @echo 'TOTALLY UNTESTED!'
- $(MAKE) wermit EXT=s \
- "CFLAGS= -DV7 -DMINIX -i -D_MINIX -D_POSIX_SOURCE \
- -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DSIG_V \
- -DNOXMIT -DNOMSEND -DNOFRILLS -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG \
- -DNOSCRIPT -DNOCSETS -DNOICP -DNOSETKEY $(KFLAGS)" \
- "LNKFLAGS= -i -T"
-
-#MINIX - PC version with 64K+64K limit, new (as yet unreleased) ACK 2.0 beta C
-#compiler, which outputs .o object files, rather than .s. But 'make' still
-#expects .s files, so must be patched to use .o. Tested on Minix 1.5.10.
-minix15:
- @echo 'Making C-Kermit $(CKVER) for MINIX (new ACK 2.0 compiler),'
- @echo 'no command parser... TOTALLY UNTESTED!'
- $(MAKE) wermit \
- "CFLAGS= -DV7 -DMINIX -i -D_MINIX -D_POSIX_SOURCE \
- -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DSIG_V -DNODIAL \
- -DNOHELP -DNODEBUG -DNOTLOG -DNOSCRIPT -DNOCSETS -DNOICP $(KFLAGS)" \
- "LNKFLAGS= -i -T"
-
-#MINIX3 - MINIX 3.0 (no VM) - May-Aug 2005 (not sure if this ever worked...)
-minix3:
- @echo 'Making C-Kermit $(CKVER) for MINIX3...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DPOSIX -DNOUUCP -DNOLEARN $(KFLAGS) -DMINIX2 \
- -DMINIX3 -DNO_PARAM_H -DNOSYSLOG -DNOGETUSERSHELL \
- -DNOINITGROUPS -DNOFTRUNCATE -DNOARROWKEYS -DDNOREALPATH \
- -DTCPSOCKET -DNOTIMEZONE -DNOFTP -DNO_DNS_SRV -O"
-
-#MINIX315 - MINIX 3 1.5 - January 2010
-minix315:
- @echo 'Making C-Kermit $(CKVER) for Minix 3 1.5...'
- $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \
- "CFLAGS= -DMINIX315 -DPOSIX -DNOUUCP -DNOJC -DNOLEARN $(KFLAGS) \
- -DHAVE_OPENPTY -DNO_PARAM_H -DNOSYSLOG -DNOGETUSERSHELL \
- -DSYSTIMEH -DNOINITGROUPS -DNOFTRUNCATE -DNOARROWKEYS -DNOREALPATH \
- -DTCPSOCKET -DNOTIMEZONE -DNO_DNS_SRV -DNOFTP -O"
-
-#PFU Compact A Series UNIX System V R3, SX/A TISP V10/L50 (Japan)
-#Maybe the -i link option should be removed?
-sxae50:
- @echo 'Making C-Kermit $(CKVER) for PFU SX/A V10/L50...'
- $(MAKE) xermit \
- "CFLAGS= -DSVR3 -DDIRENT -DsxaE50 -DTCPSOCKET $(KFLAGS) -i -O" \
- "LNKFLAGS= "
-
-#Tektronix 6130, 4319, 4301, etc, with UTek OS, /usr/spool/uucp/LCK./...
-#The models that support hardware flow control.
-utek:
- @echo 'Making C-Kermit $(CKVER) for 4.2BSD/UTek, hardware flow control'
- $(MAKE) wermit \
- "CFLAGS= -O -DLCKDIR -DBSD4 -DTCPSOCKET \
- -DUTEK -DDCLPOPEN -DLOCK_DIR=\\\"/usr/spool/uucp/LCK.\\\" \
- -DTRMBUFL=2048 -DCK_DTRCTS $(KFLAGS)"
-
-#Tektronix 4315, 4316, 4317 with UTek OS, /usr/spool/uucp/LCK./...
-#The models that do not fully support hardware flow control.
-uteknohwfc:
- @echo 'Making C-Kermit $(CKVER) for 4.2BSD/UTek, no h/w flow control'
- $(MAKE) wermit \
- "CFLAGS= -O -DLCKDIR -DBSD4 -DTCPSOCKET \
- -DUTEK -DDCLPOPEN -DLOCK_DIR=\\\"/usr/spool/uucp/LCK.\\\" \
- -DTRMBUFL=2048 $(KFLAGS)"
-
-#Tektronix XD88 with UTekV OS
-utekvr3:
- @echo 'Making C-Kermit $(CKVER) for Tektronix XD88 UTekV R3...'
- $(MAKE) wermit \
- "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP \
- -DTCPSOCKET -DSYSUTIMEH -DCK_CURSES $(KFLAGS) -O" \
- "LIBS= -lcurses" "LNKFLAGS= -s"
-
-#Perkin-Elmer 3200 Xelos R02 or earlier
-ccop1:
- @echo 'Making C-Kermit $(CKVER) for Xelos & Public Domain Dirent calls'
- @echo 'or System V R2 or earlier...'
- $(MAKE) wermit \
- "CFLAGS = -DATTSV -Dvoid=int -DDIRENT -DCK_CURSES \
- $(KFLAGS) -O" "LNKFLAGS =" "LIBS= -lcurses -ltermlib"
-
-#Encore, UMAX 4.3 (BSD) but without acucntrl program.
-encore:
- $(MAKE) "MAKE=$(MAKE)" umax43 "KFLAGS=$(KFLAGS)"
-
-#Encore, as above, but with curses file transfer display included.
-encorec:
- $(MAKE) "MAKE=$(MAKE)" umax43 "KFLAGS=-DCK_CURSES $(KFLAGS)" \
- "LIBS= -lcurses -ltermcap"
-
-#Encore, UMAX 4.3 (BSD) but without acucntrl program.
-umax43:
- @echo Making C-Kermit $(CKVER) for Encore UMAX 4.3...
- $(MAKE) "MAKE=$(MAKE)" PARALLEL=4 xermit \
- "CFLAGS= -DBSD43 -DENCORE -DTCPSOCKET $(KFLAGS) -O"
-
-#Encore, UMAX 4.2 (BSD)
-umax42:
- @echo Making C-Kermit $(CKVER) for Encore UMAX 4.2...
- $(MAKE) "MAKE=$(MAKE)" PARALLEL=4 xermit \
- "CFLAGS= -DBSD4 -DENCORE -DTCPSOCKET $(KFLAGS) -O"
-
-#Encore 88K UMAX 5.3 with TCP/IP support
-encore88k:
- @echo 'Making C-Kermit $(CKVER) for Encore 88K UMAX V, TCP/IP...'
- $(MAKE) xermit \
- "CFLAGS = -q ext=pcc -DSVR3 -DTCPSOCKET -DDIRENT \
- -DNOGETID_PROTOS -DHDBUUCP $(KFLAGS) -O" "LNKFLAGS ="
-
-#Encore 88K UMAX 5.3 with TCP/IP support
-encore88kgcc:
- @echo 'Making C-Kermit $(CKVER) for Encore 88K UMAX V, TCP/IP, gcc...'
- $(MAKE) xermit CC=gcc CC2=gcc \
- "CFLAGS = -DSVR3 -DTCPSOCKET -DDIRENT \
- -DNOGETID_PROTOS -DHDBUUCP $(KFLAGS) -O" "LNKFLAGS ="
-
-#SONY NEWS, NEWS-OS 4.01C
-sonynews:
- @echo Making C-Kermit $(CKVER) for SONY NEWS-OS 4.01C...
- $(MAKE) xermit "CFLAGS= -DBSD43 -DACUCNTRL -DTCPSOCKET -O"
-
-#Run Lint on this mess for selected versions.
-#These are pretty much obsolete since ANSI C / gcc.
-lintsun:
- @echo 'Running Lint on C-Kermit $(CKVER) sources for SunOS version...'
- lint -x -DSUNOS4 -DDIRENT -DTCPSOCKET -DSAVEDUID \
- ck[cu]*.c > ckuker.lint.sun
-
-lintbsd:
- @echo 'Running Lint on C-Kermit $(CKVER) sources for BSD 4.2 version..'
- lint -x -DBSD4 -DTCPSOCKET ck[cu]*.c > ckuker.lint.bsd42
-
-lints5:
- @echo 'Running Lint on C-Kermit $(CKVER) sources for Sys V version...'
- lint -x -DATTSV ck[cu]*.c > ckuker.lint.s5
-
-#Who remembers TECO?
-love:
- @echo 'Not war?'
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ockermit.ini b/ckermit-9.0.302-build/ckermit-9.0.302/ockermit.ini
deleted file mode 100644
index f007561..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ockermit.ini
+++ /dev/null
@@ -1,618 +0,0 @@
-COMMENT - Standard C-Kermit initialization file
-;
-; For C-Kermit Version: 8.0
-;
-; Filename:
-; .kermrc (UNIX, OS-9, Aegis)
-; CKERMIT.INI (OS/2, VMS, OpenVMS, AOS/VS, Atari ST, Commodore Amiga)
-; ckermit.ini (Stratus VOS)
-; K95.INI (Kermit 95 -- but this big version is not used there)
-; K2.INI (Kermit/2 -- but ditto)
-;
-; Authors:
-; Frank da Cruz, Christine M. Gianone, Jeffrey Altman
-; Columbia University, New York, NY 10025-7799, USA
-;
-; This is the standard and recommended C-Kermit 8.0 initialization file. To
-; override settings or definitions made in this file, to add new settings or
-; definitions, or to make any other desired customizations, create a separate,
-; personal customization file called:
-;
-; .mykermrc (UNIX, OS-9, Aegis, BeBox, Plan 9)
-; CKERMOD.INI (OS/2, VMS, OpenVMS, AOS/VS, Atari ST, Commodore Amiga)
-; ckermod.ini (VOS)
-;
-; You can also define the customization filename in an environment
-; variable (logical name in VMS), CKERMOD, which takes precedence over
-; the names shown above.
-;
-; WHAT THIS FILE DOES:
-;
-; . Defines your default dialing directory name:
-; .kdd for UNIX, OS-9 and Aegis; CKERMIT.KDD for other operating systems.
-; You can override this with the environment variable K_DIAL_DIRECTORY
-; . Defines your default network directory name:
-; .knd for UNIX, OS-9 and Aegis; CKERMIT.KND for other operating systems.
-; You can override this with the environment variable K_NET_DIRECTORY
-; . Defines your default services directory name:
-; .ksd for UNIX, OS-9 and Aegis; CKERMIT.KSD for other operating systems.
-; You can override this with environment variable K_SERVICE_DIRECTORY.
-; . Defines your customization file name (name given above)
-; . Performs system-dependent setups for UNIX, VMS, OS/2, etc.
-; . Defines VTPRINT macros for use with K95, MS-DOS Kermit, etc.
-; . If you have a services directory, all the macros needed to use it are
-; defined. If you don't have a services directory, the macros are not
-; defined and Kermit starts faster.
-; . Executes your personal customization file, if you have one.
-; NOTE: Your customization file is NOT executed by Kermit itself; it is
-; executed by this file.
-;
-; In UNIX, with C-Kermit 7.0 and later, you can store this file with a name
-; other than .kermrc, and it will not be executed automatically, but, if you
-; give this file execute permission, you can execute directly because of the
-; "kerbang line" at the top, whenever you want all of the above actions to
-; occur. The kerbang line must reflect the actual full path of the Kermit
-; 7.0-or-later executable.
-;
-; C-Kermit 6.0 is documented in the book "Using C-Kermit", 2nd Edition,
-; by Frank da Cruz and Christine M. Gianone, 1997, Digital Press /
-; Butterworth-Heinemann, ISBN 1-55558-164-1. New features of subsequent
-; versions are documented at the Kermit website:
-; http://www.columbia.edu/kermit/
-;
-; Everything after this point depends on the script programming language.
-; The CHECK command terminates this command file immediately if the script
-; programming language (IF command) is not configured.
-;
-set take error on ; This makes CHECK quit if no script language.
-check if ; Do we have an IF command? If not, quit now.
-set take error off ; Back to normal.
-
-local _sd _servicedir _xp ; Declare local variables.
-
-COMMENT - C-Kermit version 6.0 or later required.
-;
-
-asg _xp \v(xprogram)
-if not def _xp asg _xp \v(program)
-if not equal "\m(_xp)" "C-Kermit" -
- stop 1 \v(cmdfile): This initialization file is only for C-Kermit.
-echo Executing \v(cmdfile) for \v(system)...
-if < \v(version) 60000 -
- stop 1 \v(cmdfile): C-Kermit 6.0 or later required.
-
-forward \v(system) ; First do system-dependent items...
-
-:unknown ; Should not happen
-Stop 1 Error: System type unknown!
-
-:Aegis ; Apollo Aegis and
-:UNIX ; UNIX, all versions
-asg _myinit -
- \v(home).mykermrc ; Customization filename
-if remote forward COMMON ; Skip local-mode items if "-R"
-asg _dialdir -
- \v(home).kdd ; C-Kermit dialing directory
-asg _netdir -
- \v(home).knd ; C-Kermit network directory
-asg _servicedir -
- \v(home).ksd ; C-Kermit services directory
-forward COMMON ; End of UNIX section
-
-:OS9/68K ; OS-9
-asg _myinit -
- \v(home).mykermrc ; Customization filename
-if remote forward COMMON
-asg _dialdir -
- \v(home).kdd ; C-Kermit dialing directory
-asg _netdir -
- \v(home).knd ; C-Kermit network directory
-asg _servicedir -
- \v(home).ksd ; C-Kermit services directory
-else set file display crt
-forward COMMON ; End of OS-9 section
-
-:VMS ; VMS and OpenVMS
-forward COMMON
-
-:OS/2 ; Kermit 95
-:WIN32
-echo This initialization file is not for use with K95.
-forward COMMON ; End of OS/2 section
-
-:AOS/VS ; Data General AOS/VS
-set window 1 ; Sliding windows don't work
-set file char dg-international ; File character-set
-set xfer char latin1 ; Transfer character-set
-set file display crt ; File transfer fisplay
-def cli push ; Escape to CLI
-def reset - ; Macro to reset DG DASHER terminal
- run write [!ascii 236 306 301]
-forward COMMON ; End of AOS/VS section
-
-:Amiga ; Commodore Amiga
-def cls echo \27[H\27[2J ; CLS command to clear the screen
-set file char latin1 ; Use Latin Alphabet 1 for file transfer
-set xfer char latin1 ; ...
-forward COMMON ; End of Amiga section
-
-:Atari_ST ; Atari ST
-def cls echo \27H\27J ; Clear screen a`la VT52
-set server display on ; Show file xfer display in server mode too
-set server timeout 15 ; Nonzero required for ^C interruption!
-forward COMMON ; End of Atari ST section
-
-:Macintosh ; Apple Macintosh
-set server display on ; Show file xfer display in server mode too.
-forward COMMON
-
-:Stratus_VOS ; Stratus VOS
-asg _myinit \v(home)ckermod.ini
-if remote forward COMMON
-asg _dialdir \v(home)ckermit.kdd
-asg _netdir \v(home)ckermit.knd
-asg _servicedir \v(home)ckermit.ksd
-forward COMMON ; End of Stratus VOS section
-
-:COMMON ; For all systems
-
-; Define macros that are useful when running C-Kermit in remote mode.
-; These macros serve no purpose on local-mode-only versions such as
-; OS/2, Macintosh, Amiga, and Atari ST Kermit, so we skip defining them
-; for those systems.
-;
-if not = 0 \findex(\v(system),WIN32:OS/2:Macintosh:Amiga:Atari_ST) -
- forward files
-
-; VTPRINT macro. Print a file on your PC's local printer.
-
-def VTPRINT echo \27[5i, type \%1, echo \27[4i
-; or if your printer needs a formfeed to force the page out:
-; def VTPRINT def echo \27[5i, type \%1, echo \12\27[4i
-
-; Macros for host-initiated file transfer using APC:
-; NOT NEEDED ANY MORE because of autodownload/autoupload.
-; Remove the following FORWARD command to reinstate these definitions:
-
-:FILES
-
-; Get customization and directory file names. Environment variables take
-; precedence, so you do not have to edit this file to change these filenames.
-;
-if def \$(CKERMOD) assign _myinit \$(CKERMOD)
-if not def _myinit assign _myinit \v(home)CKERMOD.INI
-
-if remote forward CUSTOM ; Skip all this if -R given on command line
-
-if def \$(K_NET_DIRECTORY) assign _netdir \$(K_NET_DIRECTORY)
-if not def _netdir assign _netdir \v(home)CKERMIT.KND
-
-if def \$(K_DIAL_DIRECTORY) assign _dialdir \$(K_DIAL_DIRECTORY)
-if not def _dialdir assign _dialdir \v(home)CKERMIT.KDD
-
-CHECK DIAL ; Is there a DIAL command?
-xif fail { ; No.
- echo DIAL disabled
- forward CUSTOM
-}
-
-CHECK NETWORK
-xif success {
- xif exist \m(_netdir) {
- set net directory \m(_netdir)
- echo { Network directory is \m(_netdir) }
- }
-}
-
-if eq "\v(name)" "telnet" forward CUSTOM
-
-xif exist \m(_dialdir) {
- set dial directory \m(_dialdir)
- echo { Dial directory is \m(_dialdir) }
-}
-
-COMMENT - Services directory
-
-if def \$(K_SERVICE_DIRECTORY) assign _servicedir \$(K_SERVICE_DIRECTORY)
-if not def _servicedir assign _servicedir \v(home)CKERMIT.KSD
-
-; If no services directory is found skip all the big macro definitions and
-; go straight to the bottom, where we execute the customization file.
-
-if not exist \m(_servicedir) forward custom
-
-echo { Services directory is \m(_servicedir)}
-
-def MAX_SVCS 200 ; Adjust this if you have more entries
-define _sd 0 ; Assume no services directory
-open read \m(_servicedir) ; Try to open services directory file
-xif success {
- declare \&d[\m(MAX_SVCS)] ; It's open, declare directory array
- for \%i 1 \m(MAX_SVCS) 1 { ; Read the lines into the array
- read \&d[\%i]
- if fail break
- }
- close read
- xif > \%i \m(MAX_SVCS) {
- echo Too many entries in services directory
- echo { Maximum is \m(MAX_SVCS).}
- echo { Change definition of MAX_SVCS in \v(cmdfile) to allow more. }
- echo { Services directory disabled.}
- } else {
- asg \&d[0] \feval(\%i - 1)
- define _sd 1
- }
-}
-
-xif not \m(_sd) {
- def access echo { Services directory not available.}
- asg list \m(access)
-} else {
- def FIND {
- set case off
- for \%i 1 \&d[0] 1 {
- if eq {\%1} {\fsubstr(\&d[\%i],1,\flen(\%1))} break
- }
- if not > \%i \&d[0] return \&d[\%i]
- }
- def LIST {
- xif > \v(argc) 1 {
- do find \%1
- if def \v(return) echo \v(return)
- else echo \%1: Not found
- } else {
- echo \&d[0] items in services directory:
- for \%i 1 \&d[0] 1 { echo \fcont(\&d[\%i]) }
- }
- }
- def SPLIT { asg _word1 \%1, asg _word2 \%2 }
- def DOACCESS { ; (Used internally by ACCESS macro)
- do \%5 \%6 \%7 \%8 \%9 ; Do the connection macro
- if fail end 1
- split \%3 ; Get words from \%3
- asg \%3 \m(_word1)
- asg \%2 \m(_word2)
- do \%3 \%4 {\%1} \%2 ; Login macro, userid, password, prompt
- }
- def ACCESS {
- if not defined \%1 end 1 access what? ; Check service
- do find \%1 ; Look it up
- if success doaccess {\%2} \v(return) ; OK, try it
- else end 1 "\%1" not in services directory ; Not found
- if fail end 1 ; DOACCESS failed?
- xif eq \v(cmdlevel) 1 {
- echo
- echo ACCESS: Login succeeded - CONNECTing...
- show escape
- output \13
- connect /quietly
- }
- }
-}
-
-:CONNECTION ; Macros for making connections
-
-COMMENT - SERIAL macro. Arguments:
-; \%1 = device name
-; \%2 = speed
-;
-def SERIAL {
- if < \v(argc) 3 ; All arguments given?
- end 1 Usage: SERIAL device speed ; No.
- set line \%1 ; OK, try to SET LINE.
- if failure - ; If this failed,
- end 1 Can't open device: \%1 ; print message and quit.
- set speed \%2 ; Try to set the speed.
- if fail end 1 Unsupported speed: \%2 ; Failed.
- echo Connection successful. ; Succeeded.
-}
-
-COMMENT - NET macro. Arguments:
-; \%1 = network type
-; \%2 = host name or address
-;
-def NET {
- if < \v(argc) 3 end 1 Usage: NET network host
- set network type \%1
- if fail end 1 unsupported network: \%1
- set login user ; Don't send user ID.
- set host \%2
- if fail end 1 Can't reach host: \%2
- echo Connection successful.
-}
-
-COMMENT - CALL macro. Arguments:
-;
-; \%1 = modem type
-; \%2 = device name
-; \%3 = speed
-; \%4 = phone number
-;
-def CALL {
- if < \v(argc) 5 - ; All arguments present?
- end 1 Usage: CALL modem device speed number
- xif not equal {\v(modem)} {\%1} { ; Set modem type
- set modem \%1
- if fail end 1 unknown modem type: \%1
- }
- xif not equal {\v(line)} {\%2} { ; Communication device
- set line \%2
- if fail end 1 can't open device: \%2
- }
- xif not equal {\v(speed)} {\%3} { ; Communication speed
- set speed \%3
- if fail end 1 unsupported speed: \%3
- }
- dial \%4 ; Dial the number
- if fail end 1 Can't place call: \%4
- end 0 Connection successful.
-}
-
-COMMENT - TCPCALL macro. Arguments:
-;
-; \%1 = server name:port
-; \%2 = modem type
-; \%3 = phone number
-;
-def TCPCALL {
- if < \v(argc) 4 - ; All arguments present?
- end 1 Usage: TCPCALL server[:port] modem number
- set net type tcp/ip ; Which network to use
- if fail end 1 unsupported network: tcp/ip
- set host \%1 ; Access server and port
- if fail end 1 can't access server \%1
- set modem \%2 ; Set modem type
- if fail end 1 unknown modem type: \%2
- dial \%3 ; Dial the number
- if fail end 1 Can't place call: \%3
- end 0 Connection successful.
-}
-
-COMMENT - SPRINT macro. Arguments:
-; \%1 = Service name or address
-;
-def SPRINT {
- if < \v(argc) 2 end 1 Usage: \%0 service
- set input timeout proceed
- output @D\13
- input 10 TERMINAL=
- if fail end 1 No terminal prompt
- out D1\13
- inp 10 @
- if fail end 1 No atsign prompt
- output c \%1\13
- input 10 CONNECTED
- if fail end 1 Can't access \%1 from SprintNet
-}
-
-COMMENT - ULOGIN macro. For logging into systems where user ID is required
-; but there is no password. Arguments:
-; \%1 = UNIX user ID
-;
-define ULOGIN {
- if < \v(argc) 2 end 1 Usage: \%0 userid
- set input timeout proceed ; Handle timeouts ourselves
- set case on ; Case is important in UNIX
- minput 5 login: Username: {User ID:} {User Name:}
- out \%1\13 ; Send username, carriage return
- end 0
-}
-
-COMMENT - VMSLOGIN macro. Arguments:
-; \%1 = VMS user ID
-; \%2 = Password. If password not supplied, it is prompted for.
-; \%3 = System prompt. If omitted a default is supplied.
-;
-define VMSLOGIN {
- if < \v(argc) 2 end 1 Usage: \%0 userid [ password [ prompt ] ]
- while not defined \%2 {
- askq \%2 { \%1's password: }
- }
- set parity none ; Set communication parameters
- set duplex full
- set handshake none
- set input timeout proceed ; Handle timeouts ourselves
- in 5 Username: ; Is prompt already there?
- xif fail { ; No.
- for \%i 1 3 1 { ; Try 3 times to get it.
- out \13 ; Send carriage return
- in 5 Username: ; Look for prompt
- if success break ; Success, go log in
- }
- if > \%i 3 end 1 No Username prompt
- }
- out \%1\13 ; Send username, carriage return
- inp 5 Password: ; Wait 5 sec for this prompt
- if fail end 1 No password prompt
- pause ; Wait a sec
- out \%2\13 ; Send password
- xif not emulation { ; No emulator built in?
- set input echo off ; Protect terminal from this
- minput 10 {\27Z} {\27[c} {\27[0c} ; Get terminal ID query
- xif success { ; Got one
- output \27[\?1c ; Send VT100 terminal ID
- in 2 \27[6n ; Screen dimension query?
- if succ out \27[\v(rows);\v(cols)R ; Send dimensions
- }
- set input echo on ; Echo input again
- }
- if not def \%3 - ; If we were not given a prompt
- asg \%3 {\v(prompt)} ; use the SET LOGIN PROMPT value
- if not def \%3 - ; If we still don't have a prompt
- asg \%3 {\13$\32} ; use this one as the default
- reinp 0 \%3 ; Did we INPUT the prompt already?
- if fail inp 60 \%3 ; No, look now.
- if fail end 1
-}
-
-COMMENT - UNIXLOGIN macro. Arguments:
-; \%1 = UNIX user ID
-; \%2 = Password. If password not supplied, it is prompted for.
-; \%3 = System prompt. If omitted a default is supplied.
-;
-define UNIXLOGIN {
- local \%m \%i
- if < \v(argc) 2 -
- end 1 Usage: \%0 userid [ password [ prompt ] ]
- while not defined \%2 {
- askq \%2 { \%1's password: }
- }
- set input echo on
- set parity none ; Set communication parameters.
- set duplex full
- set handshake none
- set input timeout proceed ; Handle timeouts ourselves
- set case on ; Case is important in UNIX
- def \%m 10 ; Waiting time for INPUT
- for \%i 1 5 1 {
- minput \%m login: {ssword:} {Password for \%1:}
- if success break
- output \B\13
- \%m ::= 6-\%1
- }
- if > \%i 5 end 1 {No response from host}
- xif = \v(minput) 1 { ; Have username prompt
- output \%1\13 ; Send username
- minput 5 {ssword:} {ssword for \%1:} ; Wait for password prompt
- if fail end 1 {No password prompt}
- }
- pause ; Wait a sec
- out \%2\13 ; Send password
- if not def \%3 - ; If we were not given a prompt
- asg \%3 {\v(prompt)} ; use the SET LOGIN PROMPT value
- if not def \%3 - ; If we still don't have a prompt
- asg \%3 {\10$ } ; use this one as the default
- reinp 0 \%3 ; Did we INPUT the prompt already?
- if fail inp 60 \%3 ; No, look now.
- if fail end 1
-}
-
-COMMENT - VMLINELOGIN macro. Arguments:
-; \%1 = User ID
-; \%2 = Password
-;
-define VMLINELOGIN {
- if < \v(argc) 2 -
- end 1 Usage: \%0 userid [ password ]
- while not defined \%2 {
- askq \%2 { \%1's password: }
- }
- set parity mark ; Set communication parameters
- set flow none
- set handshake xon
- set duplex half
- set input timeout quit ; Don't bother with IF FAILURE
- input 10 BREAK KEY ; Look for BREAK KEY prompt
- pause 1 ; Wait a second
- output \B ; Send BREAK
- input 10 .\17, output logon \%1\13 ; Now log in
- input 10 .\17, output \%2\13 ; Send password
- input 10 .\17, output \13 ; Send carriage return
- input 10 .\17, output \13 ; Send another one
- end 0
-}
-
-COMMENT - VMFULLOGIN macro. Arguments:
-; \%1 = User ID
-; \%2 = Password
-;
-define VMFULLOGIN {
- if < \v(argc) 2 -
- end 1 Usage: \%0 userid [ password ]
- while not defined \%2 {
- askq \%2 { \%1's password: }
- }
- set input timeout quit ; Quit if INPUT fails
- set parity even ; Set communication parameters
- set duplex full
- set handshake none
- set flow xon/xoff
- out \13 ; Send carriage return
- inp 5 TERMINAL TYPE: ; Get terminal-type prompt
- out vt-100\13 ; Just send "vt-100"
- inp 20 RUNNING ; Get RUNNING message
- pau 1 ; Wait one second
- out \%1\9\%2\13 ; Send user ID, tab, password
- out \13\13 ; Two more carriage returns
- end 0
-}
-
-COMMENT - CISLOGIN macro. Arguments:
-; \%1 = CompuServe User ID
-; \%2 = Password
-; \%3 = Prompt
-;
-define CISLOGIN {
- if < \v(argc) 2 -
- end 1 Usage: \%0 userid [ password [ prompt ] ]
- while not defined \%2 {
- askq \%2 { \%1's password: }
- }
- set terminal bytesize 7 ; No 8-bit characters
- set input timeout quit ; Skip the IF FAILURE's
- output \13 ; Send initial carriage return
- input 5 Host Name: ; Look for Host Name prompt
- output cis\13 ; Send "cis" and carriage return
- input 5 User ID: ; Look for User ID prompt
- output \%1\13 ; Send ID and carriage return
- input Password: ; Look for Password prompt
- output \%2\13 ; Send password and CR
- if not def \%3 asg \%3 \v(prompt)
- if not def \%3 asg \%3 {CompuServe Information Service}
- input 30 \%3
- end 0
-}
-
-COMMENT - DOWLOGIN macro. Arguments:
-; \%1 = Dow Jones Password
-;
-define DOWLOGIN {
- while not defined \%1 { ; Get password
- askq \%1 { Dow Jones password: }
- }
- set input timeout proceed
- input 20 SERVICE PLEASE\?\?\?\? ; Look for Dow prompt
- if fail end 1 No service prompt
- out djnr\13 ; Select DJNR
- input 10 @@@@@@@@ ; Get password prompt
- if fail end 1 No password prompt
- pause 1 ; Wait a second, then...
- output \%1\13 ; send password and CR
- input 30 ENTER QUERY ; Get DJNR query prompt
- if fail end 1 No main query prompt
- pause 1
-}
-
-COMMENT - DJNRSPRINT macro: Log in to Dow Jones via SprintNet.
-;
-def djnrsprint sprint dow, if success dowlogin
-
-COMMENT - NOLOGIN macro. Does nothing. Use when login not required.
-;
-def nologin comment
-
-:CUSTOM ; Customization file
-
-; In VMS and OpenVMS, allow for system-wide site customizations
-
-xif equal "\v(system)" "VMS" {
- xif exist CKERMIT_INI:CKERMIT.SYS {
- echo Executing CKERMIT_INI:CKERMIT.SYS
- take CKERMIT_INI:CKERMIT.SYS
- }
-}
-
-; Execute user's personal customization file
-
-xif exist \m(_myinit) { ; If it exists,
- echo Executing \m(_myinit)... ; print message,
- take \m(_myinit) ; and TAKE the file.
-}
-
-; Finish up with traditional greeting.
-
-if < \v(ntime) 43200 echo Good Morning!
- else if < \v(ntime) 61200 echo Good Afternoon!
- else echo Good Evening.
-
-End ; of C-Kermit 8.0 initialization file.
diff --git a/ckermit-9.0.302-build/ckermit-9.0.302/ockermod.ini b/ckermit-9.0.302-build/ckermit-9.0.302/ockermod.ini
deleted file mode 100644
index 5848c3f..0000000
--- a/ckermit-9.0.302-build/ckermit-9.0.302/ockermod.ini
+++ /dev/null
@@ -1,144 +0,0 @@
-; File CKERMOD.INI, Sample C-Kermit 7.0 customization file.
-;
-; This file, which is ONLY A SAMPLE, should be called:
-;
-; .mykermrc (UNIX, OS-9, Aegis, BeBox, Plan 9)
-; CKERMOD.INI (VMS, OpenVMS, AOS/VS, OS/2, Amiga, Atari ST)
-; ckermod.ini (Stratus VOS)
-;
-; This file is executed automatically by the standard C-Kermit initialization
-; file, CKERMIT.INI (or .kermrc). This file is not executed by C-Kermit itself
-; unless the initialization file is not found.
-;
-; MODify this file to suit your needs and preferences, and install it in your
-; home directory. Or replace it entirely with a new file.
-;
-; The design of this sample customization file lets you fill in a section for
-; each different operating system where you run C-Kermit.
-;
-; In UNIX, if you give this file execute permission and make sure the top
-; line indicates the full path of the C-Kermit 7.0-or-later executable, you
-; can execute this file directly, as if it was a shell script, except it is
-; interpreted by Kermit rather than the shell. This lets you have as many
-; different startup files as you like, each suited to a particular purpose.
-;
-; Authors: Christine Gianone, Frank da Cruz, Jeffrey Altman,
-; The Kermit Project, Columbia University.
-; Creation: 23 November 1992 for C-Kermit 5A(188).
-; Modified: 30 June 1993 for edit 189.
-; 04 October 1994 for edit 190.
-; 17 April 1995 for edit 191.
-; 6 September 1996 for version 6.0, edit 192.
-; 1 January 2000 for version 7.0, edit 196.
-; 14 October 2001 for version 8.0, edit 200.
-
-ECHO
-ECHO Executing SAMPLE C-Kermit customization file \v(cmdfile) for \v(system)...
-ECHO { Please edit this file to reflect your needs and preferences.}
-ECHO
-;
-; ... and then remove the ECHO commands above.
-
-COMMENT - Settings that apply to all the systems I use:
-;
-set delay 1 ; I escape back quickly
-set dial display on ; I like to watch C-Kermit dial
-
-; Dialing locale and method
-;
-; SET DIAL COUNTRY-CODE 1 ; Uncomment and replace with yours
-; SET DIAL AREA-CODE 000 ; Uncomment and replace with yours
-; SET DIAL LD-PREFIX 1 ; Uncomment and replace with yours
-; SET DIAL INTL-PREFIX 011 ; Uncomment and replace with yours
-; SET DIAL METHOD TONE ; Uncomment and replace with PULSE if necessary
-; SET DIAL DIRECTORY ... ... ; List dialing directory files here
-
-if < \v(version) 600192 -
- stop 1 \v(cmdfile): C-Kermit 6.0.192 or later required.
-
-set take error on ; Make errors fatal temporarily
-check if ; Do we have an IF command?
-set take error off ; Yes we do, back to normal
-
-; The ON_EXIT macro is executed automatically when C-Kermit exits.
-; Define as desired.
-;
-define ON_EXIT echo Returning you to \v(system) now.
-
-; System-independent quick dialing macro. Depends on having the
-; macros MYMODEM, MYPORT, and (optionally) MYSPEED defined in the
-; system-dependent sections below.
-;
-define MYDIAL {
- if not defined MYMODEM end 1 {\%0: Modem type not defined.}
- set modem type \m(MYMODEM)
- if fail end 1 {\%0: \m(MYMODEM): Unsupported modem type.}
- if not defined MYPORT end 1 {\%0: Communication port not defined.}
- set port \m(MYPORT)
- if fail end 1 {\%0: SET PORT \m(MYPORT) failed.}
- if defined MYFLOW set flow \m(MYFLOW)
- if fail end 1 {\%0: SET FLOW \m(MYFLOW) failed.}
- if defined MYSPEED set speed \m(MYSPEED)
- if fail end 1 {\%0: SET SPEED \m(MYSPEED) failed.}
- dial \%1\%2\%3\%4\%5\%6\%7\%8\%9
- end \v(status)
-}
-
-forward \v(system) ; Go execute system-dependent commands
-
-:UNIX ; UNIX, all versions...
-define MYPORT /dev/cua ; My dialing environment
-define MYMODEM usr ; Replace these by what you actually have
-define MYSPEED 57600
-;
-; If you want all your downloads to go to the same directory, no matter
-; what your current directory is, uncomment and edit the following command:
-;
-; set file download-directory ~/download ; Download directory for UNIX
-
-; Put other UNIX-specific commands here...
-end ; End of UNIX section
-
-:VMS ; VMS and OpenVMS
-define MYPORT TXA0: ; My dialing environment
-define MYMODEM usr ; Replace these by what you actually have
-define MYSPEED 57600
-; set file download-directory [\$(USER).DOWNLOAD] ; Download directory for VMS
-; Put other VMS-specific commands here...
-end ; End of VMS section
-
-:WIN32 ; Windows and OS/2 customizations...
-:OS/2
-define MYPORT COM1 ; My dialing environment
-define MYMODEM usr ; Replace these by what you actually have
-define MYSPEED 57600
-set command byte 8 ; Use 8 bits between Kermit and console
-set xfer char latin1 ; Use Latin-1 for text file transfer
-set term char latin1 ; And use Latin-1 during CONNECT mode
-; set file download-directory C:\DOWNLOADS
-end
-
-:OS9/68K ; OS-9/68000
-define MYPORT /t3 ; My dialing environment
-define MYMODEM usr ; Replace these by what you actually have
-define MYSPEED 9600
-; set file download-directory ~/downloads
-end ; End of OS-9 section
-
-:AOS/VS ; Data General AOS/VS
-define MYPORT @con3 ; My dialing environment
-define MYMODEM usr ; Replace these by what you actually have
-define MYSPEED 9600
-; set file download-directory \v(home)DOWNLOADS
-end
-
-; And so on, you get the idea...
-; Fill in the sections that apply to you.
-
-:Stratus_VOS ; Stratus VOS
-:Amiga ; Commodore Amiga
-:Atari_ST ; Atari ST
-:Macintosh ; Apple Macintosh
-:unknown ; Others
-
-; (End of CKERMOD.INI)
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-18 13:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-18 13:57 [rpms/ckermit] epel8: Remove the 'rpmbuild -bp' directory from git, come on David Cantrell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox